From: Tom Gundersen Date: Mon, 7 Jan 2013 14:14:01 +0000 (+0100) Subject: Merge nss-myhostname X-Git-Tag: v197~24 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=commitdiff_plain;h=f274ece0f76b5709408821e317e87aef76123db6;hp=8e6640f0fe9eebde5a6cc9f1c0a20a289b8ad9c8 Merge nss-myhostname --- diff --git a/.dir-locals.el b/.dir-locals.el new file mode 100644 index 000000000..9d9f8cd17 --- /dev/null +++ b/.dir-locals.el @@ -0,0 +1,7 @@ +; Sets emacs variables based on mode. +; A list of (major-mode . ((var1 . value1) (var2 . value2))) +; Mode can be nil, which gives default values. + +((nil . ((indent-tabs-mode . nil) + (tab-width . 8))) +) diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..a55190489 --- /dev/null +++ b/.gitignore @@ -0,0 +1,138 @@ +/Makefile +/TAGS +/accelerometer +/ata_id +/build-aux +/cdrom_id +/collect +/gtk-doc.make +/hostnamectl +/install-tree +/journalctl +/keymap +/libtool +/localectl +/loginctl +/mtd_probe +/org.freedesktop.hostname1.xml +/org.freedesktop.locale1.xml +/org.freedesktop.systemd1.*.xml +/org.freedesktop.timedate1.xml +/scsi_id +/systemadm +/systemctl +/systemd +/systemd-ac-power +/systemd-ask-password +/systemd-binfmt +/systemd-cat +/systemd-cgls +/systemd-cgroups-agent +/systemd-cgtop +/systemd-coredump +/systemd-coredumpctl +/systemd-cryptsetup +/systemd-cryptsetup-generator +/systemd-delta +/systemd-detect-virt +/systemd-fsck +/systemd-fstab-generator +/systemd-getty-generator +/systemd-gnome-ask-password-agent +/systemd-hostnamed +/systemd-inhibit +/systemd-initctl +/systemd-journal-gatewayd +/systemd-journald +/systemd-kmsg-syslogd +/systemd-localed +/systemd-logind +/systemd-machine-id-setup +/systemd-modules-load +/systemd-multi-seat-x +/systemd-notify +/systemd-nspawn +/systemd-quotacheck +/systemd-random-seed +/systemd-rc-local-generator +/systemd-readahead +/systemd-remount-api-vfs +/systemd-remount-fs +/systemd-reply-password +/systemd-shutdown +/systemd-shutdownd +/systemd-sleep +/systemd-stdio-bridge +/systemd-sysctl +/systemd-system-update-generator +/systemd-timedated +/systemd-timestamp +/systemd-tmpfiles +/systemd-tty-ask-password-agent +/systemd-uaccess +/systemd-udevd +/systemd-update-utmp +/systemd-user-sessions +/systemd-vconsole-setup +/tags +/test-calendarspec +/test-catalog +/test-cgroup +/test-daemon +/test-date +/test-engine +/test-env-replace +/test-hostname +/test-id128 +/test-inhibit +/test-install +/test-job-type +/test-journal +/test-journal-enum +/test-journal-match +/test-journal-send +/test-journal-stream +/test-journal-syslog +/test-journal-verify +/test-libudev +/test-log +/test-login +/test-loopback +/test-mmap-cache +/test-ns +/test-replace-var +/test-sched-prio +/test-sleep +/test-strip-tab-ansi +/test-strv +/test-udev +/test-unit-file +/test-unit-name +/test-watchdog +/timedatectl +/udevadm +/v4l_id +/*.tar.bz2 +/*.tar.gz +/*.tar.xz +*.trs +*.log +*.a +*.cache +*.html +*.la +*.lo +*.o +*.stamp +*~ +.deps/ +.dirstamp +.libs/ +Makefile.in +aclocal.m4 +config.h +config.h.in +config.log +config.status +configure +stamp-* diff --git a/.mailmap b/.mailmap new file mode 100644 index 000000000..da8ca8443 --- /dev/null +++ b/.mailmap @@ -0,0 +1,45 @@ +Kay Sievers +Kay Sievers +Kay Sievers +Kay Sievers +Kay Sievers +Greg KH +Greg KH +Greg KH +Greg KH +Harald Hoyer +David Zeuthen +David Zeuthen +David Zeuthen +Hannes Reinecke +Scott James Remnant +Scott James Remnant +Alan Jenkins +Alan Jenkins +Marco d'Itri +Robert Gerus Robert "arachnist" Gerus +Zbigniew Jędrzejewski-Szmek Zbyszek Szmek +Fabiano Fidêncio Fabiano Fidencio +Martin Pitt +Martin Pitt +Daniel J Walsh +Dave Reisner +Diego Elio Pettenò +Daniel Elstner +Frederic Crozat +Ian Campbell +Jerone Young +Luis Felipe Strano Moraes +Mario Limonciello +Matthias Clasen +Michal Soltys +Piter PUNK +Richard Hughes +Robby Workman +Shawn Landden +Simon Peeters +Tobias Klauser +Miklos Vajna +William Jon McCann +Yin Kangkai +Zbigniew Jędrzejewski-Szmek diff --git a/.vimrc b/.vimrc new file mode 100644 index 000000000..366fbdca4 --- /dev/null +++ b/.vimrc @@ -0,0 +1,4 @@ +" 'set exrc' in ~/.vimrc will read .vimrc from the current directory +set tabstop=8 +set shiftwidth=8 +set expandtab diff --git a/CODING_STYLE b/CODING_STYLE new file mode 100644 index 000000000..04b4ed20e --- /dev/null +++ b/CODING_STYLE @@ -0,0 +1,27 @@ + +- 8ch indent, no tabs + +- structs in MixedCase, variables, functions in lower_case + +- the destructors always unregister the object from the next bigger + object, not the other way around + +- to minimize strict aliasing violations we prefer unions over casting + +- for robustness reasons destructors should be able to destruct + half-initialized objects, too + +- error codes are returned as negative Exxx. i.e. return -EINVAL. There + are some exceptions: for constructors its is OK to return NULL on + OOM. For lookup functions NULL is fine too for "not found" + +- Do not issue NSS requests (that includes user name and host name + lookups) from the main daemon as this might trigger deadlocks when + we those lookups involve synchronously talking to services that we + would need to start up + +- Do not access any directories outside of /etc, /dev, /lib from the + init daemon to avoid deadlocks with the automounter + +- Don't synchronously talk to any other service, due to risk of + deadlocks diff --git a/DISTRO_PORTING b/DISTRO_PORTING new file mode 100644 index 000000000..99c652c77 --- /dev/null +++ b/DISTRO_PORTING @@ -0,0 +1,34 @@ +Porting systemd To New Distributions + +HOWTO: + You need to make the follow changes to adapt systemd to your + distribution: + + 1) Find the right configure parameters for: + + --with-rootprefix= + --with-sysvinit-path= + --with-sysvrcd-path= + --with-rc-local-script-path-start= + --with-rc-local-script-path-stop= + --with-kbd-loadkeys= + --with-kbd-setfont= + --with-tty-gid= + + 2) Try it out. Play around with 'systemd --test --system' for + a test run of systemd without booting. This will read the unit + files and print the initial transaction it would execute + during boot-up. This will also inform you about ordering loops + and suchlike. + +CONTRIBUTING UPSTREAM: + + We are generally do no longer accept distribution specific + patches to systemd upstream. If you have to make changes to + systemd's source code to make it work on your distribution: + unless your code is generic enough to be generally useful we + are unlikely to merge it. Please always consider adopting the + upstream defaults. If that's not possible please maintain the + relevant patches downstream. + + Thank you for understanding. diff --git a/LICENSE.GPL2 b/LICENSE.GPL2 new file mode 100644 index 000000000..d511905c1 --- /dev/null +++ b/LICENSE.GPL2 @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/LICENSE.LGPL2.1 b/LICENSE.LGPL2.1 new file mode 100644 index 000000000..4362b4915 --- /dev/null +++ b/LICENSE.LGPL2.1 @@ -0,0 +1,502 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/LICENSE.MIT b/LICENSE.MIT new file mode 100644 index 000000000..fd44f736e --- /dev/null +++ b/LICENSE.MIT @@ -0,0 +1,19 @@ +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation files +(the "Software"), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of the Software, +and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 000000000..9920bc13f --- /dev/null +++ b/Makefile.am @@ -0,0 +1,4101 @@ +# -*- Mode: makefile; indent-tabs-mode: t -*- */ +# +# This file is part of systemd. +# +# Copyright 2010-2012 Lennart Poettering +# Copyright 2010-2012 Kay Sievers +# +# 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 . + +ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS} +AM_MAKEFLAGS = --no-print-directory +AUTOMAKE_OPTIONS = color-tests parallel-tests + +SUBDIRS = . po + +# remove targets if the command fails +.DELETE_ON_ERROR: + +LIBUDEV_CURRENT=3 +LIBUDEV_REVISION=0 +LIBUDEV_AGE=2 + +LIBGUDEV_CURRENT=1 +LIBGUDEV_REVISION=2 +LIBGUDEV_AGE=1 + +LIBSYSTEMD_LOGIN_CURRENT=3 +LIBSYSTEMD_LOGIN_REVISION=10 +LIBSYSTEMD_LOGIN_AGE=3 + +LIBSYSTEMD_DAEMON_CURRENT=0 +LIBSYSTEMD_DAEMON_REVISION=6 +LIBSYSTEMD_DAEMON_AGE=0 + +LIBSYSTEMD_ID128_CURRENT=0 +LIBSYSTEMD_ID128_REVISION=16 +LIBSYSTEMD_ID128_AGE=0 + +LIBSYSTEMD_JOURNAL_CURRENT=7 +LIBSYSTEMD_JOURNAL_REVISION=0 +LIBSYSTEMD_JOURNAL_AGE=7 + +# Dirs of external packages +dbuspolicydir=@dbuspolicydir@ +dbussessionservicedir=@dbussessionservicedir@ +dbussystemservicedir=@dbussystemservicedir@ +dbusinterfacedir=@dbusinterfacedir@ +pamlibdir=@pamlibdir@ +pkgconfigdatadir=$(datadir)/pkgconfig +pkgconfiglibdir=$(libdir)/pkgconfig +polkitpolicydir=$(datadir)/polkit-1/actions +bashcompletiondir=$(sysconfdir)/bash_completion.d +rpmmacrosdir=$(sysconfdir)/rpm +sysvinitdir=$(SYSTEM_SYSVINIT_PATH) +sysvrcddir=$(SYSTEM_SYSVRCND_PATH) +varlogdir=$(localstatedir)/log +systemdstatedir=$(localstatedir)/lib/systemd +catalogstatedir=$(systemdstatedir)/catalog +hwdb_bin=/etc/udev/hwdb.bin + +# Our own, non-special dirs +pkgsysconfdir=$(sysconfdir)/systemd +userunitdir=$(prefix)/lib/systemd/user +userpresetdir=$(prefix)/lib/systemd/user-preset +tmpfilesdir=$(prefix)/lib/tmpfiles.d +sysctldir=$(prefix)/lib/sysctl.d +usergeneratordir=$(prefix)/lib/systemd/user-generators +pkgincludedir=$(includedir)/systemd +systemgeneratordir=$(rootlibexecdir)/system-generators +systemshutdowndir=$(rootlibexecdir)/system-shutdown +systemsleepdir=$(rootlibexecdir)/system-sleep +systemunitdir=$(rootprefix)/lib/systemd/system +systempresetdir=$(rootprefix)/lib/systemd/system-preset +udevlibexecdir=$(rootprefix)/lib/udev +udevhomedir=$(udevlibexecdir) +udevrulesdir=$(udevlibexecdir)/rules.d +udevhwdbdir=$(udevlibexecdir)/hwdb.d +catalogdir=$(prefix)/lib/systemd/catalog + +# And these are the special ones for / +rootprefix=@rootprefix@ +rootbindir=$(rootprefix)/bin +rootlibexecdir=$(rootprefix)/lib/systemd + +CLEANFILES = $(BUILT_SOURCES) +EXTRA_DIST = +BUILT_SOURCES = +INSTALL_EXEC_HOOKS = +UNINSTALL_EXEC_HOOKS = +INSTALL_DATA_HOOKS = +UNINSTALL_DATA_HOOKS = +DISTCLEAN_LOCAL_HOOKS = +pkginclude_HEADERS = +noinst_LTLIBRARIES = +lib_LTLIBRARIES = +include_HEADERS = +pkgconfiglib_DATA = +polkitpolicy_in_files = +polkitpolicy_files = +dist_udevrules_DATA = +nodist_udevrules_DATA = +dist_man_MANS = +dist_pkgsysconf_DATA = +dist_pkgdata_DATA = +dist_dbuspolicy_DATA = +dbusinterface_DATA = +dist_dbussystemservice_DATA = +check_PROGRAMS = +check_DATA = +noinst_PROGRAMS = +TESTS = +udevlibexec_PROGRAMS = + +AM_CPPFLAGS = \ + -include $(top_builddir)/config.h \ + -DSYSTEM_CONFIG_FILE=\"$(pkgsysconfdir)/system.conf\" \ + -DSYSTEM_CONFIG_UNIT_PATH=\"$(pkgsysconfdir)/system\" \ + -DSYSTEM_DATA_UNIT_PATH=\"$(systemunitdir)\" \ + -DSYSTEM_SYSVINIT_PATH=\"$(SYSTEM_SYSVINIT_PATH)\" \ + -DSYSTEM_SYSVRCND_PATH=\"$(SYSTEM_SYSVRCND_PATH)\" \ + -DUSER_CONFIG_FILE=\"$(pkgsysconfdir)/user.conf\" \ + -DUSER_CONFIG_UNIT_PATH=\"$(pkgsysconfdir)/user\" \ + -DUSER_DATA_UNIT_PATH=\"$(userunitdir)\" \ + -DCATALOG_PATH=\"$(catalogstatedir)\" \ + -DHWDB_BIN=\"$(hwdb_bin)\" \ + -DSYSTEMD_CGROUP_AGENT_PATH=\"$(rootlibexecdir)/systemd-cgroups-agent\" \ + -DSYSTEMD_BINARY_PATH=\"$(rootlibexecdir)/systemd\" \ + -DSYSTEMD_SHUTDOWN_BINARY_PATH=\"$(rootlibexecdir)/systemd-shutdown\" \ + -DSYSTEMD_SLEEP_BINARY_PATH=\"$(rootlibexecdir)/systemd-sleep\" \ + -DSYSTEMCTL_BINARY_PATH=\"$(rootbindir)/systemctl\" \ + -DSYSTEMD_TTY_ASK_PASSWORD_AGENT_BINARY_PATH=\"$(rootbindir)/systemd-tty-ask-password-agent\" \ + -DSYSTEMD_STDIO_BRIDGE_BINARY_PATH=\"$(bindir)/systemd-stdio-bridge\" \ + -DROOTPREFIX=\"$(rootprefix)\" \ + -DRANDOM_SEED=\"$(localstatedir)/lib/random-seed\" \ + -DSYSTEMD_CRYPTSETUP_PATH=\"$(rootlibexecdir)/systemd-cryptsetup\" \ + -DSYSTEM_GENERATOR_PATH=\"$(systemgeneratordir)\" \ + -DUSER_GENERATOR_PATH=\"$(usergeneratordir)\" \ + -DSYSTEM_SHUTDOWN_PATH=\"$(systemshutdowndir)\" \ + -DSYSTEM_SLEEP_PATH=\"$(systemsleepdir)\" \ + -DSYSTEMD_KBD_MODEL_MAP=\"$(pkgdatadir)/kbd-model-map\" \ + -DX_SERVER=\"$(bindir)/X\" \ + -DUDEVLIBEXECDIR=\"$(udevlibexecdir)\" \ + -DPOLKIT_AGENT_BINARY_PATH=\"$(bindir)/pkttyagent\" \ + -I $(top_srcdir)/src \ + -I $(top_srcdir)/src/shared \ + -I $(top_srcdir)/src/login \ + -I $(top_srcdir)/src/journal \ + -I $(top_srcdir)/src/systemd \ + -I $(top_builddir)/src/core \ + -I $(top_srcdir)/src/core \ + -I $(top_srcdir)/src/libudev \ + -I $(top_srcdir)/src/udev \ + $(OUR_CPPFLAGS) + +AM_CFLAGS = $(OUR_CFLAGS) +AM_LDFLAGS = $(OUR_LDFLAGS) + +# ------------------------------------------------------------------------------ + +define move-to-rootlibdir + if test "$(libdir)" != "$(rootlibdir)"; then \ + $(MKDIR_P) $(DESTDIR)$(rootlibdir) && \ + so_img_name=$$(readlink $(DESTDIR)$(libdir)/$$libname) && \ + so_img_rel_target_prefix=$$(echo $(libdir) | sed 's,\(^/\|\)[^/][^/]*,..,g') && \ + ln -sf $$so_img_rel_target_prefix$(rootlibdir)/$$so_img_name $(DESTDIR)$(libdir)/$$libname && \ + mv $(DESTDIR)$(libdir)/$$libname.* $(DESTDIR)$(rootlibdir); \ + fi +endef + +# ------------------------------------------------------------------------------ +rootbin_PROGRAMS = \ + systemctl \ + systemd-notify \ + systemd-ask-password \ + systemd-tty-ask-password-agent \ + systemd-tmpfiles \ + systemd-machine-id-setup + +bin_PROGRAMS = \ + systemd-cgls \ + systemd-cgtop \ + systemd-stdio-bridge \ + systemd-nspawn \ + systemd-detect-virt \ + systemd-delta + +rootlibexec_PROGRAMS = \ + systemd \ + systemd-cgroups-agent \ + systemd-initctl \ + systemd-update-utmp \ + systemd-shutdownd \ + systemd-shutdown \ + systemd-remount-fs \ + systemd-reply-password \ + systemd-fsck \ + systemd-timestamp \ + systemd-ac-power \ + systemd-sysctl \ + systemd-sleep + +if HAVE_KMOD +rootlibexec_PROGRAMS += \ + systemd-modules-load +endif + +systemgenerator_PROGRAMS = \ + systemd-getty-generator \ + systemd-fstab-generator \ + systemd-system-update-generator + +dist_bin_SCRIPTS = \ + src/analyze/systemd-analyze + +EXTRA_DIST += \ + src/analyze/systemd-analyze.in + +CLEANFILES += \ + src/analyze/systemd-analyze + +dist_bashcompletion_DATA = \ + shell-completion/systemd-bash-completion.sh + +dist_tmpfiles_DATA = \ + tmpfiles.d/systemd.conf \ + tmpfiles.d/tmp.conf \ + tmpfiles.d/x11.conf + +if HAVE_SYSV_COMPAT +dist_tmpfiles_DATA += \ + tmpfiles.d/legacy.conf +endif + +dist_systemunit_DATA = \ + units/graphical.target \ + units/multi-user.target \ + units/emergency.service \ + units/emergency.target \ + units/sysinit.target \ + units/basic.target \ + units/getty.target \ + units/halt.target \ + units/kexec.target \ + units/local-fs.target \ + units/local-fs-pre.target \ + units/remote-fs.target \ + units/remote-fs-pre.target \ + units/network.target \ + units/nss-lookup.target \ + units/nss-user-lookup.target \ + units/mail-transfer-agent.target \ + units/hibernate.target \ + units/hybrid-sleep.target \ + units/poweroff.target \ + units/reboot.target \ + units/rescue.target \ + units/rpcbind.target \ + units/time-sync.target \ + units/shutdown.target \ + units/final.target \ + units/umount.target \ + units/sigpwr.target \ + units/sleep.target \ + units/sockets.target \ + units/suspend.target \ + units/swap.target \ + units/systemd-initctl.socket \ + units/systemd-shutdownd.socket \ + units/syslog.socket \ + units/dev-hugepages.mount \ + units/dev-mqueue.mount \ + units/sys-kernel-config.mount \ + units/sys-kernel-debug.mount \ + units/sys-fs-fuse-connections.mount \ + units/tmp.mount \ + units/printer.target \ + units/sound.target \ + units/bluetooth.target \ + units/smartcard.target \ + units/systemd-tmpfiles-clean.timer \ + units/quotaon.service \ + units/systemd-ask-password-wall.path \ + units/systemd-ask-password-console.path \ + units/syslog.target \ + units/systemd-udevd-control.socket \ + units/systemd-udevd-kernel.socket \ + units/system-update.target + +nodist_systemunit_DATA = \ + units/getty@.service \ + units/serial-getty@.service \ + units/console-shell.service \ + units/console-getty.service \ + units/systemd-initctl.service \ + units/systemd-shutdownd.service \ + units/systemd-remount-fs.service \ + units/systemd-update-utmp-runlevel.service \ + units/systemd-update-utmp-shutdown.service \ + units/systemd-tmpfiles-setup.service \ + units/systemd-tmpfiles-clean.service \ + units/systemd-ask-password-wall.service \ + units/systemd-ask-password-console.service \ + units/systemd-sysctl.service \ + units/emergency.service \ + units/rescue.service \ + units/user@.service \ + units/systemd-hibernate.service \ + units/systemd-hybrid-sleep.service \ + units/systemd-suspend.service \ + units/systemd-halt.service \ + units/systemd-poweroff.service \ + units/systemd-reboot.service \ + units/systemd-kexec.service \ + units/systemd-fsck@.service \ + units/systemd-fsck-root.service \ + units/systemd-udevd.service \ + units/systemd-udev-trigger.service \ + units/systemd-udev-settle.service \ + units/debug-shell.service + +if HAVE_KMOD +nodist_systemunit_DATA += \ + units/systemd-modules-load.service +endif + +dist_userunit_DATA = \ + units/user/default.target \ + units/user/exit.target + +nodist_userunit_DATA = \ + units/user/systemd-exit.service + +EXTRA_DIST += \ + units/getty@.service.m4 \ + units/serial-getty@.service.m4 \ + units/console-shell.service.m4.in \ + units/console-getty.service.m4.in \ + units/rescue.service.m4.in \ + units/systemd-initctl.service.in \ + units/systemd-shutdownd.service.in \ + units/systemd-remount-fs.service.in \ + units/systemd-update-utmp-runlevel.service.in \ + units/systemd-update-utmp-shutdown.service.in \ + units/systemd-tmpfiles-setup.service.in \ + units/systemd-tmpfiles-clean.service.in \ + units/systemd-ask-password-wall.service.in \ + units/systemd-ask-password-console.service.in \ + units/systemd-sysctl.service.in \ + units/emergency.service.in \ + units/systemd-halt.service.in \ + units/systemd-poweroff.service.in \ + units/systemd-reboot.service.in \ + units/systemd-kexec.service.in \ + units/user/systemd-exit.service.in \ + units/systemd-fsck@.service.in \ + units/systemd-fsck-root.service.in \ + units/user@.service.in \ + units/systemd-udevd.service \ + units/systemd-udev-trigger.service \ + units/systemd-udev-settle.service \ + units/debug-shell.service.in \ + units/systemd-hibernate.service.in \ + units/systemd-hybrid-sleep.service.in \ + units/systemd-suspend.service.in \ + units/quotaon.service.in \ + introspect.awk \ + man/custom-html.xsl + +if HAVE_KMOD +EXTRA_DIST += \ + units/systemd-modules-load.service.in +endif + +if HAVE_SYSV_COMPAT +nodist_systemunit_DATA += \ + units/rc-local.service \ + units/halt-local.service + +EXTRA_DIST += \ + units/rc-local.service.in \ + units/halt-local.service.in + +systemgenerator_PROGRAMS += \ + systemd-rc-local-generator +endif + +dist_doc_DATA = \ + README \ + NEWS \ + LICENSE.LGPL2.1 \ + LICENSE.GPL2 \ + LICENSE.MIT \ + DISTRO_PORTING + +@INTLTOOL_POLICY_RULE@ + +# ------------------------------------------------------------------------------ +MANPAGES = \ + man/systemd.1 \ + man/systemctl.1 \ + man/systemd-cgls.1 \ + man/systemd-delta.1 \ + man/systemd-cgtop.1 \ + man/systemd-nspawn.1 \ + man/systemd-tmpfiles.8 \ + man/systemd-notify.1 \ + man/systemd.unit.5 \ + man/systemd.service.5 \ + man/systemd.socket.5 \ + man/systemd.mount.5 \ + man/systemd.automount.5 \ + man/systemd.swap.5 \ + man/systemd.timer.5 \ + man/systemd.path.5 \ + man/systemd.target.5 \ + man/systemd.device.5 \ + man/systemd.snapshot.5 \ + man/systemd.exec.5 \ + man/systemd.kill.5 \ + man/systemd.special.7 \ + man/systemd.journal-fields.7 \ + man/systemd.time.7 \ + man/kernel-command-line.7 \ + man/daemon.7 \ + man/bootup.7 \ + man/runlevel.8 \ + man/telinit.8 \ + man/halt.8 \ + man/shutdown.8 \ + man/pam_systemd.8 \ + man/systemd.conf.5 \ + man/tmpfiles.d.5 \ + man/hostname.5 \ + man/localtime.5 \ + man/machine-id.5 \ + man/locale.conf.5 \ + man/os-release.5 \ + man/machine-info.5 \ + man/sysctl.d.5 \ + man/systemd-sysctl.service.8 \ + man/systemd-ask-password.1 \ + man/systemd-cat.1 \ + man/systemd-machine-id-setup.1 \ + man/systemd-detect-virt.1 \ + man/journald.conf.5 \ + man/systemd-journald.service.8 \ + man/journalctl.1 \ + man/systemd-coredumpctl.1 \ + man/systemd-inhibit.1 \ + man/systemd-remount-fs.service.8 \ + man/systemd-update-utmp-runlevel.service.8 \ + man/systemd-initctl.service.8 \ + man/systemd-shutdownd.service.8 \ + man/systemd-suspend.service.8 \ + man/systemd-halt.service.8 \ + man/systemd-fsck@.service.8 \ + man/systemd-ask-password-console.service.8 \ + man/systemd-analyze.1 \ + man/systemd-tty-ask-password-agent.1 \ + man/systemd-getty-generator.8 \ + man/systemd-system-update-generator.8 \ + man/systemd-fstab-generator.8 \ + man/systemd.preset.5 \ + man/sd-id128.3 \ + man/sd_id128_to_string.3 \ + man/sd_id128_randomize.3 \ + man/sd_id128_get_machine.3 \ + man/sd-journal.3 \ + man/sd_journal_print.3 \ + man/sd_journal_stream_fd.3 \ + man/sd_journal_open.3 \ + man/sd_journal_next.3 \ + man/sd_journal_get_data.3 \ + man/sd_journal_get_realtime_usec.3 \ + man/sd_journal_get_cutoff_realtime_usec.3 \ + man/sd_journal_get_cursor.3 \ + man/sd_journal_get_fd.3 \ + man/sd_journal_get_usage.3 \ + man/sd_journal_add_match.3 \ + man/sd_journal_seek_head.3 \ + man/sd_journal_query_unique.3 \ + man/sd_journal_get_catalog.3 + +MANPAGES_ALIAS = \ + man/reboot.8 \ + man/poweroff.8 \ + man/init.1 \ + man/systemd-sysctl.8 \ + man/systemd-journald.socket.8 \ + man/systemd-journald.8 \ + man/systemd-remount-fs.8 \ + man/systemd-update-utmp-shutdown.service.8 \ + man/systemd-update-utmp.8 \ + man/systemd-initctl.socket.8 \ + man/systemd-initctl.8 \ + man/systemd-shutdownd.socket.8 \ + man/systemd-shutdownd.8 \ + man/systemd-hibernate.service.8 \ + man/systemd-hybrid-sleep.service.8 \ + man/systemd-sleep.8 \ + man/systemd-shutdown.8 \ + man/systemd-poweroff.service.8 \ + man/systemd-reboot.service.8 \ + man/systemd-kexec.service.8 \ + man/systemd-fsck.8 \ + man/systemd-fsck-root.service.8 \ + man/systemd-ask-password-console.path.8 \ + man/systemd-ask-password-wall.service.8 \ + man/systemd-ask-password-wall.path.8 \ + man/systemd-tmpfiles-setup.service.8 \ + man/systemd-tmpfiles-clean.service.8 \ + man/systemd-tmpfiles-clean.timer.8 \ + man/sd_id128_t.3 \ + man/SD_ID128_MAKE.3 \ + man/SD_ID128_CONST_STR.3 \ + man/SD_ID128_FORMAT_STR.3 \ + man/SD_ID128_FORMAT_VAL.3 \ + man/sd_id128_equal.3 \ + man/sd_id128_from_string.3 \ + man/sd_id128_get_boot.3 \ + man/sd_journal_printv.3 \ + man/sd_journal_send.3 \ + man/sd_journal_sendv.3 \ + man/sd_journal_perror.3 \ + man/SD_JOURNAL_SUPPRESS_LOCATION.3 \ + man/sd_journal_open_directory.3 \ + man/sd_journal_close.3 \ + man/sd_journal.3 \ + man/SD_JOURNAL_RUNTIME_ONLY.3 \ + man/SD_JOURNAL_SYSTEM_ONLY.3 \ + man/SD_JOURNAL_LOCAL_ONLY.3 \ + man/sd_journal_previous.3 \ + man/sd_journal_next_skip.3 \ + man/sd_journal_previous_skip.3 \ + man/SD_JOURNAL_FOREACH.3 \ + man/SD_JOURNAL_FOREACH_BACKWARDS.3 \ + man/sd_journal_enumerate_data.3 \ + man/sd_journal_restart_data.3 \ + man/SD_JOURNAL_FOREACH_DATA.3 \ + man/sd_journal_get_monotonic_usec.3 \ + man/sd_journal_get_cutoff_monotonic_usec.3 \ + man/sd_journal_reliable_fd.3 \ + man/sd_journal_process.3 \ + man/sd_journal_wait.3 \ + man/SD_JOURNAL_NOP.3 \ + man/SD_JOURNAL_APPEND.3 \ + man/SD_JOURNAL_INVALIDATE.3 \ + man/sd_journal_add_disjunction.3 \ + man/sd_journal_flush_matches.3 \ + man/sd_journal_seek_tail.3 \ + man/sd_journal_seek_monotonic_usec.3 \ + man/sd_journal_seek_realtime_usec.3 \ + man/sd_journal_seek_cursor.3 \ + man/sd_journal_test_cursor.3 \ + man/sd_journal_enumerate_unique.3 \ + man/sd_journal_restart_unique.3 \ + man/SD_JOURNAL_FOREACH_UNIQUE.3 \ + man/sd_journal_get_catalog_for_message_id.3 + +if HAVE_KMOD +MANPAGES += \ + man/modules-load.d.5 \ + man/systemd-modules-load.service.8 +MANPAGES_ALIAS += \ + man/systemd-modules-load.8 +man/systemd-modules-load.8: man/systemd-modules-load.service.8 +endif + +if HAVE_MICROHTTPD +MANPAGES += \ + man/systemd-journal-gatewayd.service.8 +MANPAGES_ALIAS += \ + man/systemd-journal-gatewayd.socket.8 \ + man/systemd-journal-gatewayd.8 +man/systemd-journal-gatewayd.socket.8: man/systemd-journal-gatewayd.service.8 +man/systemd-journal-gatewayd.8: man/systemd-journal-gatewayd.service.8 +endif + +man/reboot.8: man/halt.8 +man/poweroff.8: man/halt.8 +man/init.1: man/systemd.1 +man/systemd-sysctl.8: man/systemd-sysctl.service.8 +man/systemd-journald.socket.8: man/systemd-journald.service.8 +man/systemd-journald.8: man/systemd-journald.service.8 +man/systemd-remount-fs.8: man/systemd-remount-fs.service.8 +man/systemd-update-utmp-shutdown.service.8: man/systemd-update-utmp-runlevel.service.8 +man/systemd-update-utmp.8: man/systemd-update-utmp-runlevel.service.8 +man/systemd-initctl.socket.8: man/systemd-initctl.service.8 +man/systemd-initctl.8: man/systemd-initctl.service.8 +man/systemd-shutdownd.socket.8: man/systemd-shutdownd.service.8 +man/systemd-shutdownd.8: man/systemd-shutdownd.service.8 +man/systemd-hibernate.service.8: man/systemd-suspend.service.8 +man/systemd-hybrid-sleep.service.8: man/systemd-suspend.service.8 +man/systemd-sleep.8: man/systemd-suspend.service.8 +man/systemd-shutdown.8: man/systemd-halt.service.8 +man/systemd-poweroff.service.8: man/systemd-halt.service.8 +man/systemd-reboot.service.8: man/systemd-halt.service.8 +man/systemd-kexec.service.8: man/systemd-halt.service.8 +man/systemd-fsck.8: man/systemd-fsck@.service.8 +man/systemd-fsck-root.service.8: man/systemd-fsck@.service.8 +man/systemd-ask-password-console.path.8: man/systemd-ask-password-console.service.8 +man/systemd-ask-password-wall.service.8: man/systemd-ask-password-console.service.8 +man/systemd-ask-password-wall.path.8: man/systemd-ask-password-console.service.8 +man/systemd-tmpfiles-setup.service.8: man/systemd-tmpfiles.8 +man/systemd-tmpfiles-clean.service.8: man/systemd-tmpfiles.8 +man/systemd-tmpfiles-clean.timer.8: man/systemd-tmpfiles.8 +man/sd_id128_t.3: man/sd-id128.3 +man/SD_ID128_MAKE.3: man/sd-id128.3 +man/SD_ID128_CONST_STR.3: man/sd-id128.3 +man/SD_ID128_FORMAT_STR.3: man/sd-id128.3 +man/SD_ID128_FORMAT_VAL.3: man/sd-id128.3 +man/sd_id128_equal.3: man/sd-id128.3 +man/sd_id128_from_string.3: man/sd_id128_to_string.3 +man/sd_id128_get_boot.3: man/sd_id128_get_machine.3 +man/sd_journal_printv.3: man/sd_journal_print.3 +man/sd_journal_send.3: man/sd_journal_print.3 +man/sd_journal_sendv.3: man/sd_journal_print.3 +man/sd_journal_perror.3: man/sd_journal_print.3 +man/SD_JOURNAL_SUPPRESS_LOCATION.3: man/sd_journal_print.3 +man/sd_journal_open_directory.3: man/sd_journal_open.3 +man/sd_journal_close.3: man/sd_journal_open.3 +man/sd_journal.3: man/sd_journal_open.3 +man/SD_JOURNAL_RUNTIME_ONLY.3: man/sd_journal_open.3 +man/SD_JOURNAL_SYSTEM_ONLY.3: man/sd_journal_open.3 +man/SD_JOURNAL_LOCAL_ONLY.3: man/sd_journal_open.3 +man/sd_journal_previous.3: man/sd_journal_next.3 +man/sd_journal_next_skip.3: man/sd_journal_next.3 +man/sd_journal_previous_skip.3: man/sd_journal_next.3 +man/SD_JOURNAL_FOREACH.3: man/sd_journal_next.3 +man/SD_JOURNAL_FOREACH_BACKWARDS.3: man/sd_journal_next.3 +man/sd_journal_enumerate_data.3: man/sd_journal_get_data.3 +man/sd_journal_restart_data.3: man/sd_journal_get_data.3 +man/SD_JOURNAL_FOREACH_DATA.3: man/sd_journal_get_data.3 +man/sd_journal_get_monotonic_usec.3: man/sd_journal_get_realtime_usec.3 +man/sd_journal_get_cutoff_monotonic_usec.3: man/sd_journal_get_cutoff_realtime_usec.3 +man/sd_journal_reliable_fd.3: man/sd_journal_get_fd.3 +man/sd_journal_process.3: man/sd_journal_get_fd.3 +man/sd_journal_wait.3: man/sd_journal_get_fd.3 +man/SD_JOURNAL_NOP.3: man/sd_journal_get_fd.3 +man/SD_JOURNAL_APPEND.3: man/sd_journal_get_fd.3 +man/SD_JOURNAL_INVALIDATE.3: man/sd_journal_get_fd.3 +man/sd_journal_add_disjunction.3: man/sd_journal_add_match.3 +man/sd_journal_flush_matches.3: man/sd_journal_add_match.3 +man/sd_journal_seek_tail.3: man/sd_journal_seek_head.3 +man/sd_journal_seek_monotonic_usec.3: man/sd_journal_seek_head.3 +man/sd_journal_seek_realtime_usec.3: man/sd_journal_seek_head.3 +man/sd_journal_seek_cursor.3: man/sd_journal_seek_head.3 +man/sd_journal_test_cursor.3: man/sd_journal_get_cursor.3 +man/sd_journal_enumerate_unique.3: man/sd_journal_query_unique.3 +man/sd_journal_restart_unique.3: man/sd_journal_query_unique.3 +man/SD_JOURNAL_FOREACH_UNIQUE.3: man/sd_journal_query_unique.3 +man/sd_journal_get_catalog_for_message_id.3: man/sd_journal_get_catalog.3 + +XML_FILES = \ + ${patsubst %.1,%.xml,${patsubst %.3,%.xml,${patsubst %.5,%.xml,${patsubst %.7,%.xml,${patsubst %.8,%.xml,$(MANPAGES)}}}}} + +if ENABLE_MANPAGES +man_MANS = \ + $(MANPAGES) \ + $(MANPAGES_ALIAS) + +noinst_DATA = \ + ${XML_FILES:.xml=.html} + +CLEANFILES += \ + $(MANPAGES) \ + $(MANPAGES_ALIAS) \ + ${XML_FILES:.xml=.html} + +if HAVE_PYTHON +noinst_DATA += \ + man/index.html + +CLEANFILES += \ + man/index.html + +man/index.html: make-man-index.py $(XML_FILES) + $(AM_V_at)$(MKDIR_P) $(dir $@) + $(AM_V_GEN)$(PYTHON) $^ > $@ + +MANPAGES += \ + man/systemd.directives.5 + +EXTRA_DIST += \ + man/index.html + +XML_DIRECTIVE_FILES = \ + man/systemd.unit.xml \ + man/systemd.service.xml \ + man/systemd.socket.xml \ + man/systemd.mount.xml \ + man/systemd.automount.xml \ + man/systemd.swap.xml \ + man/systemd.target.xml \ + man/systemd.path.xml \ + man/systemd.timer.xml \ + man/systemd.snapshot.xml \ + man/systemd.exec.xml \ + man/systemd.kill.xml \ + man/systemd.device.xml \ + man/systemd.conf.xml \ + man/systemd.journal-fields.xml \ + man/systemd.time.xml + +man/systemd.directives.xml: make-directive-index.py $(XML_DIRECTIVE_FILES) + $(AM_V_at)$(MKDIR_P) $(dir $@) + $(AM_V_GEN)$(PYTHON) $^ > $@ + +EXTRA_DIST += \ + man/systemd.directives.xml + +endif + +endif + +EXTRA_DIST += \ + $(XML_FILES) \ + ${XML_FILES:.xml=.html} \ + $(MANPAGES) \ + $(MANPAGES_ALIAS) \ + make-man-index.py \ + make-directive-index.py + +# ------------------------------------------------------------------------------ +noinst_LTLIBRARIES += \ + libsystemd-shared.la + +libsystemd_shared_la_SOURCES = \ + src/shared/linux/auto_dev-ioctl.h \ + src/shared/linux/fanotify.h \ + src/shared/linux/seccomp.h \ + src/shared/linux/seccomp-bpf.h \ + src/shared/missing.h \ + src/shared/list.h \ + src/shared/macro.h \ + src/shared/def.h \ + src/shared/sparse-endian.h \ + src/shared/util.c \ + src/shared/util.h \ + src/shared/virt.c \ + src/shared/virt.h \ + src/shared/path-util.c \ + src/shared/path-util.h \ + src/shared/time-util.c \ + src/shared/time-util.h \ + src/shared/hashmap.c \ + src/shared/hashmap.h \ + src/shared/set.c \ + src/shared/set.h \ + src/shared/fdset.c \ + src/shared/fdset.h \ + src/shared/strv.c \ + src/shared/strv.h \ + src/shared/strbuf.c \ + src/shared/strbuf.h \ + src/shared/conf-parser.c \ + src/shared/conf-parser.h \ + src/shared/log.c \ + src/shared/log.h \ + src/shared/ratelimit.h \ + src/shared/ratelimit.c \ + src/shared/exit-status.c \ + src/shared/exit-status.h \ + src/shared/utf8.c \ + src/shared/utf8.h \ + src/shared/pager.c \ + src/shared/pager.h \ + src/shared/ioprio.h \ + src/shared/socket-util.c \ + src/shared/socket-util.h \ + src/shared/conf-files.c \ + src/shared/conf-files.h \ + src/shared/cgroup-util.c \ + src/shared/cgroup-util.h \ + src/shared/cgroup-show.c \ + src/shared/cgroup-show.h \ + src/shared/unit-name.c \ + src/shared/unit-name.h \ + src/shared/utmp-wtmp.c \ + src/shared/utmp-wtmp.h \ + src/shared/watchdog.c \ + src/shared/watchdog.h \ + src/shared/spawn-ask-password-agent.c \ + src/shared/spawn-ask-password-agent.h \ + src/shared/specifier.c \ + src/shared/specifier.h \ + src/shared/replace-var.c \ + src/shared/replace-var.h \ + src/shared/spawn-polkit-agent.c \ + src/shared/spawn-polkit-agent.h \ + src/shared/hwclock.c \ + src/shared/hwclock.h \ + src/shared/time-dst.c \ + src/shared/time-dst.h \ + src/shared/calendarspec.c \ + src/shared/calendarspec.h + +libsystemd_shared_la_LIBADD = libsystemd-daemon.la + +#------------------------------------------------------------------------------- +noinst_LTLIBRARIES += \ + libsystemd-dbus.la + +libsystemd_dbus_la_SOURCES = \ + src/shared/dbus-common.c \ + src/shared/dbus-common.h \ + src/shared/dbus-loop.c \ + src/shared/dbus-loop.h \ + src/shared/polkit.c \ + src/shared/polkit.h + +libsystemd_dbus_la_CFLAGS = \ + $(AM_CFLAGS) \ + $(DBUS_CFLAGS) + +libsystemd_dbus_la_LIBADD = \ + $(DBUS_LIBS) + +# ------------------------------------------------------------------------------ +noinst_LTLIBRARIES += \ + libsystemd-units.la + +libsystemd_units_la_SOURCES = \ + src/shared/install.c \ + src/shared/install.h \ + src/shared/path-lookup.c \ + src/shared/path-lookup.h + +libsystemd_units_la_CFLAGS = \ + $(AM_CFLAGS) \ + $(DBUS_CFLAGS) + +# ------------------------------------------------------------------------------ +noinst_LTLIBRARIES += \ + libsystemd-label.la + +libsystemd_label_la_SOURCES = \ + src/shared/cgroup-label.c \ + src/shared/socket-label.c \ + src/shared/label.c \ + src/shared/label.h \ + src/shared/selinux-util.c \ + src/shared/selinux-util.h \ + src/shared/mkdir.c \ + src/shared/mkdir.h \ + src/shared/ask-password-api.c \ + src/shared/ask-password-api.h \ + src/shared/dev-setup.c \ + src/shared/dev-setup.h + +libsystemd_label_la_CFLAGS = \ + $(AM_CFLAGS) \ + $(SELINUX_CFLAGS) + +libsystemd_label_la_LIBADD = \ + $(SELINUX_LIBS) + +# ------------------------------------------------------------------------------ +noinst_LTLIBRARIES += \ + libsystemd-logs.la + +libsystemd_logs_la_SOURCES = \ + src/shared/logs-show.c \ + src/shared/logs-show.h + +libsystemd_logs_la_CFLAGS = \ + $(AM_CFLAGS) + +libsystemd_logs_la_LIBADD = \ + libsystemd-journal-internal.la \ + libsystemd-id128-internal.la \ + libsystemd-shared.la + +# ------------------------------------------------------------------------------ +noinst_LTLIBRARIES += \ + libsystemd-capability.la + +libsystemd_capability_la_SOURCES = \ + src/shared/capability.c \ + src/shared/capability.h + +libsystemd_capability_la_CFLAGS = \ + $(AM_CFLAGS) \ + $(CAP_CFLAGS) + +libsystemd_capability_la_LIBADD = \ + $(CAP_LIBS) + +# ------------------------------------------------------------------------------ +noinst_LTLIBRARIES += \ + libsystemd-audit.la + +libsystemd_audit_la_SOURCES = \ + src/shared/audit.c \ + src/shared/audit.h + +libsystemd_audit_la_LIBADD = \ + libsystemd-capability.la + +# ------------------------------------------------------------------------------ +if HAVE_ACL +noinst_LTLIBRARIES += \ + libsystemd-acl.la + +libsystemd_acl_la_SOURCES = \ + src/shared/acl-util.c \ + src/shared/acl-util.h + +libsystemd_acl_la_CFLAGS = \ + $(AM_CFLAGS) \ + $(ACL_CFLAGS) + +libsystemd_acl_la_LIBADD = \ + $(ACL_LIBS) +endif + +# ------------------------------------------------------------------------------ +noinst_LTLIBRARIES += \ + libsystemd-core.la + +libsystemd_core_la_SOURCES = \ + src/core/unit.c \ + src/core/unit.h \ + src/core/unit-printf.c \ + src/core/unit-printf.h \ + src/core/job.c \ + src/core/job.h \ + src/core/manager.c \ + src/core/manager.h \ + src/core/transaction.c \ + src/core/transaction.h \ + src/core/load-fragment.c \ + src/core/load-fragment.h \ + src/core/service.c \ + src/core/service.h \ + src/core/automount.c \ + src/core/automount.h \ + src/core/mount.c \ + src/core/mount.h \ + src/core/swap.c \ + src/core/swap.h \ + src/core/device.c \ + src/core/device.h \ + src/core/target.c \ + src/core/target.h \ + src/core/snapshot.c \ + src/core/snapshot.h \ + src/core/socket.c \ + src/core/socket.h \ + src/core/timer.c \ + src/core/timer.h \ + src/core/path.c \ + src/core/path.h \ + src/core/load-dropin.c \ + src/core/load-dropin.h \ + src/core/execute.c \ + src/core/execute.h \ + src/core/kill.c \ + src/core/kill.h \ + src/core/dbus.c \ + src/core/dbus.h \ + src/core/dbus-manager.c \ + src/core/dbus-manager.h \ + src/core/dbus-unit.c \ + src/core/dbus-unit.h \ + src/core/dbus-job.c \ + src/core/dbus-job.h \ + src/core/dbus-service.c \ + src/core/dbus-service.h \ + src/core/dbus-socket.c \ + src/core/dbus-socket.h \ + src/core/dbus-timer.c \ + src/core/dbus-timer.h \ + src/core/dbus-target.c \ + src/core/dbus-target.h \ + src/core/dbus-mount.c \ + src/core/dbus-mount.h \ + src/core/dbus-automount.c \ + src/core/dbus-automount.h \ + src/core/dbus-swap.c \ + src/core/dbus-swap.h \ + src/core/dbus-snapshot.c \ + src/core/dbus-snapshot.h \ + src/core/dbus-device.c \ + src/core/dbus-device.h \ + src/core/dbus-execute.c \ + src/core/dbus-execute.h \ + src/core/dbus-kill.c \ + src/core/dbus-kill.h \ + src/core/dbus-path.c \ + src/core/dbus-path.h \ + src/core/cgroup.c \ + src/core/cgroup.h \ + src/core/selinux-access.c \ + src/core/selinux-access.h \ + src/core/selinux-setup.c \ + src/core/selinux-setup.h \ + src/core/ima-setup.c \ + src/core/ima-setup.h \ + src/core/locale-setup.h \ + src/core/locale-setup.c \ + src/core/hostname-setup.c \ + src/core/hostname-setup.h \ + src/core/machine-id-setup.c \ + src/core/machine-id-setup.h \ + src/core/mount-setup.c \ + src/core/mount-setup.h \ + src/core/loopback-setup.h \ + src/core/loopback-setup.c \ + src/core/condition.c \ + src/core/condition.h \ + src/core/namespace.c \ + src/core/namespace.h \ + src/core/tcpwrap.c \ + src/core/tcpwrap.h \ + src/core/cgroup-attr.c \ + src/core/cgroup-attr.h \ + src/core/securebits.h \ + src/core/initreq.h \ + src/core/special.h \ + src/core/bus-errors.h \ + src/core/build.h \ + src/core/sysfs-show.h \ + src/core/switch-root.h \ + src/core/switch-root.c \ + src/core/killall.h \ + src/core/killall.c \ + src/core/syscall-list.c \ + src/core/syscall-list.h \ + src/core/audit-fd.c \ + src/core/audit-fd.h + +if HAVE_KMOD +libsystemd_core_la_SOURCES += \ + src/core/kmod-setup.c \ + src/core/kmod-setup.h +endif + +nodist_libsystemd_core_la_SOURCES = \ + src/core/load-fragment-gperf.c \ + src/core/load-fragment-gperf-nulstr.c \ + src/core/syscall-from-name.h \ + src/core/syscall-to-name.h + +libsystemd_core_la_CFLAGS = \ + $(AM_CFLAGS) \ + $(DBUS_CFLAGS) \ + $(LIBWRAP_CFLAGS) \ + $(PAM_CFLAGS) \ + $(AUDIT_CFLAGS) \ + $(KMOD_CFLAGS) + +libsystemd_core_la_LIBADD = \ + libsystemd-capability.la \ + libsystemd-units.la \ + libsystemd-label.la \ + libsystemd-shared.la \ + libsystemd-dbus.la \ + libsystemd-audit.la \ + libsystemd-id128-internal.la \ + libsystemd-daemon.la \ + libudev.la \ + $(LIBWRAP_LIBS) \ + $(PAM_LIBS) \ + $(AUDIT_LIBS) \ + $(CAP_LIBS) \ + $(KMOD_LIBS) + +src/core/load-fragment-gperf-nulstr.c: src/core/load-fragment-gperf.gperf + $(AM_V_at)$(MKDIR_P) $(dir $@) + $(AM_V_GEN)$(AWK) 'BEGIN{ keywords=0 ; FS="," ; print "extern const char load_fragment_gperf_nulstr[];" ; print "const char load_fragment_gperf_nulstr[] ="} ; keyword==1 { print "\"" $$1 "\\0\"" } ; /%%/ { keyword=1} ; END { print ";" }' < $< > $@ + +EXTRA_DIST += \ + src/core/load-fragment-gperf.gperf.m4 + +CLEANFILES += \ + src/core/load-fragment-gperf.gperf \ + src/core/load-fragment-gperf.c \ + src/core/load-fragment-gperf-nulstr.c \ + src/core/syscall-list.txt \ + src/core/syscall-from-name.gperf + +BUILT_SOURCES += \ + src/core/syscall-from-name.h \ + src/core/syscall-to-name.h + +src/core/syscall-list.txt: Makefile + $(AM_V_at)$(MKDIR_P) $(dir $@) + $(AM_V_GEN)$(CPP) $(CFLAGS) $(AM_CPPFLAGS) $(CPPFLAGS) -dM -include sys/syscall.h - < /dev/null | $(AWK) '/^#define[ \t]+__NR_[^ ]+[ \t]+\(?.*[0-9]+.*\)?/ { sub(/__NR_/, "", $$2); print $$2; }' > $@ + +src/core/syscall-from-name.gperf: src/core/syscall-list.txt Makefile + $(AM_V_at)$(MKDIR_P) $(dir $@) + $(AM_V_GEN)$(AWK) 'BEGIN{ print "struct syscall_name { const char* name; int id; };"; print "%null-strings"; print "%%";} { printf "%s, __NR_%s\n", $$1, $$1 }' < $< > $@ + +src/core/syscall-from-name.h: src/core/syscall-from-name.gperf Makefile + $(AM_V_at)$(MKDIR_P) $(dir $@) + $(AM_V_GEN)$(GPERF) -L ANSI-C -t --ignore-case -N lookup_syscall -H hash_syscall_name -p -C < $< > $@ + +src/core/syscall-to-name.h: src/core/syscall-list.txt Makefile + $(AM_V_at)$(MKDIR_P) $(dir $@) + $(AM_V_GEN)$(AWK) 'BEGIN{ print "const char* const syscall_names[] = { "} { printf "[__NR_%s] = \"%s\",\n", $$1, $$1 } END{print "};"}' < $< > $@ + +# ------------------------------------------------------------------------------ +systemd_SOURCES = \ + src/core/main.c + +systemd_CFLAGS = \ + $(AM_CFLAGS) \ + $(DBUS_CFLAGS) + +systemd_LDADD = \ + libsystemd-core.la \ + libsystemd-daemon.la \ + libsystemd-id128-internal.la \ + libsystemd-dbus.la + +dist_pkgsysconf_DATA += \ + src/core/system.conf \ + src/core/user.conf + +dist_dbuspolicy_DATA += \ + src/core/org.freedesktop.systemd1.conf + +dist_dbussystemservice_DATA += \ + src/core/org.freedesktop.systemd1.service + +dbusinterface_DATA += \ + org.freedesktop.systemd1.Manager.xml \ + org.freedesktop.systemd1.Job.xml \ + org.freedesktop.systemd1.Unit.xml \ + org.freedesktop.systemd1.Service.xml \ + org.freedesktop.systemd1.Socket.xml \ + org.freedesktop.systemd1.Timer.xml \ + org.freedesktop.systemd1.Target.xml \ + org.freedesktop.systemd1.Device.xml \ + org.freedesktop.systemd1.Mount.xml \ + org.freedesktop.systemd1.Automount.xml \ + org.freedesktop.systemd1.Snapshot.xml \ + org.freedesktop.systemd1.Swap.xml \ + org.freedesktop.systemd1.Path.xml + +polkitpolicy_in_in_files = \ + src/core/org.freedesktop.systemd1.policy.in.in + +org.freedesktop.systemd1.%.xml: systemd + $(AM_V_GEN)$(LIBTOOL) --mode=execute $(OBJCOPY) -O binary -j introspect.$* $< $@.tmp && \ + $(STRINGS) $@.tmp | $(AWK) -f $(srcdir)/introspect.awk | \ + $(DBUS_PREPROCESS) -o $@ - && rm $@.tmp + +pkgconfigdata_DATA = \ + src/core/systemd.pc + +nodist_rpmmacros_DATA = \ + src/core/macros.systemd + +EXTRA_DIST += \ + src/core/systemd.pc.in \ + src/core/macros.systemd.in + +CLEANFILES += \ + src/core/macros.systemd + +# ------------------------------------------------------------------------------ +noinst_PROGRAMS += \ + test-engine \ + test-job-type \ + test-ns \ + test-loopback \ + test-hostname \ + test-daemon \ + test-cgroup \ + test-env-replace \ + test-strv \ + test-install \ + test-watchdog \ + test-unit-name \ + test-log \ + test-unit-file \ + test-date \ + test-sleep \ + test-replace-var \ + test-sched-prio \ + test-calendarspec \ + test-strip-tab-ansi + +TESTS += \ + test-job-type \ + test-env-replace \ + test-strv \ + test-unit-name \ + test-unit-file \ + test-date \ + test-sleep \ + test-replace-var \ + test-sched-prio \ + test-calendarspec \ + test-strip-tab-ansi + +EXTRA_DIST += \ + test/sched_idle_bad.service \ + test/sched_idle_ok.service \ + test/sched_rr_bad.service \ + test/sched_rr_ok.service \ + test/sched_rr_change.service + +test_engine_SOURCES = \ + src/test/test-engine.c + +test_engine_CFLAGS = \ + $(AM_CFLAGS) \ + $(DBUS_CFLAGS) + +test_engine_LDADD = \ + libsystemd-core.la \ + libsystemd-daemon.la \ + libsystemd-dbus.la + +test_job_type_SOURCES = \ + src/test/test-job-type.c + +test_job_type_CFLAGS = \ + $(AM_CFLAGS) \ + $(DBUS_CFLAGS) + +test_job_type_LDADD = \ + libsystemd-core.la \ + libsystemd-daemon.la + +test_ns_SOURCES = \ + src/test/test-ns.c + +test_ns_LDADD = \ + libsystemd-core.la + +test_loopback_SOURCES = \ + src/test/test-loopback.c + +test_loopback_LDADD = \ + libsystemd-shared.la \ + libsystemd-core.la + +test_hostname_SOURCES = \ + src/test/test-hostname.c + +test_hostname_LDADD = \ + libsystemd-core.la + +test_unit_name_SOURCES = \ + src/test/test-unit-name.c + +test_unit_name_LDADD = \ + libsystemd-core.la + +test_unit_file_SOURCES = \ + src/test/test-unit-file.c + +test_unit_file_CFLAGS = \ + $(AM_CFLAGS) \ + $(DBUS_CFLAGS) + +test_unit_file_LDADD = \ + libsystemd-core.la + +test_log_SOURCES = \ + src/test/test-log.c + +test_log_LDADD = \ + libsystemd-core.la + +test_date_SOURCES = \ + src/test/test-date.c + +test_date_LDADD = \ + libsystemd-core.la + +test_sleep_SOURCES = \ + src/test/test-sleep.c + +test_sleep_LDADD = \ + libsystemd-core.la + +test_replace_var_SOURCES = \ + src/test/test-replace-var.c + +test_replace_var_LDADD = \ + libsystemd-shared.la + +test_calendarspec_SOURCES = \ + src/test/test-calendarspec.c + +test_calendarspec_LDADD = \ + libsystemd-shared.la + +test_strip_tab_ansi_SOURCES = \ + src/test/test-strip-tab-ansi.c + +test_strip_tab_ansi_LDADD = \ + libsystemd-shared.la + +test_daemon_SOURCES = \ + src/test/test-daemon.c + +test_daemon_LDADD = \ + libsystemd-shared.la \ + libsystemd-daemon.la + +test_cgroup_SOURCES = \ + src/test/test-cgroup.c + +test_cgroup_LDADD = \ + libsystemd-label.la \ + libsystemd-shared.la + +test_env_replace_SOURCES = \ + src/test/test-env-replace.c + +test_env_replace_LDADD = \ + libsystemd-shared.la + +test_strv_SOURCES = \ + src/test/test-strv.c + +test_strv_LDADD = \ + libsystemd-shared.la + +test_install_SOURCES = \ + src/test/test-install.c + +test_install_CFLAGS = \ + $(AM_CFLAGS) \ + $(DBUS_CFLAGS) + +test_install_LDADD = \ + libsystemd-units.la \ + libsystemd-label.la \ + libsystemd-shared.la + +test_watchdog_SOURCES = \ + src/test/test-watchdog.c + +test_watchdog_LDADD = \ + libsystemd-shared.la + +test_sched_prio_SOURCES = \ + src/test/test-sched-prio.c + +test_sched_prio_CFLAGS = \ + $(AM_CFLAGS) \ + $(DBUS_CFLAGS) \ + -D"STR(s)=\#s" -D"TEST_DIR=STR($(abs_top_srcdir)/test/)" + +test_sched_prio_LDADD = \ + libsystemd-core.la \ + libsystemd-daemon.la + +# ------------------------------------------------------------------------------ +systemd_initctl_SOURCES = \ + src/initctl/initctl.c + +systemd_initctl_CFLAGS = \ + $(AM_CFLAGS) \ + $(DBUS_CFLAGS) + +systemd_initctl_LDADD = \ + libsystemd-shared.la \ + libsystemd-daemon.la \ + libsystemd-dbus.la + +# ------------------------------------------------------------------------------ +systemd_update_utmp_SOURCES = \ + src/update-utmp/update-utmp.c + +systemd_update_utmp_CFLAGS = \ + $(AM_CFLAGS) \ + $(DBUS_CFLAGS) \ + $(AUDIT_CFLAGS) + +systemd_update_utmp_LDADD = \ + libsystemd-shared.la \ + libsystemd-dbus.la \ + $(AUDIT_LIBS) + +# ------------------------------------------------------------------------------ +systemd_shutdownd_SOURCES = \ + src/shutdownd/shutdownd.c + +systemd_shutdownd_LDADD = \ + libsystemd-label.la \ + libsystemd-shared.la \ + libsystemd-daemon.la + +pkginclude_HEADERS += \ + src/systemd/sd-shutdown.h + +# ------------------------------------------------------------------------------ +systemd_shutdown_SOURCES = \ + src/core/umount.c \ + src/core/umount.h \ + src/core/shutdown.c \ + src/core/mount-setup.c \ + src/core/mount-setup.h \ + src/core/killall.h \ + src/core/killall.c + +systemd_shutdown_LDADD = \ + libsystemd-label.la \ + libsystemd-shared.la \ + libudev.la + +if HAVE_KMOD +# ------------------------------------------------------------------------------ +systemd_modules_load_SOURCES = \ + src/modules-load/modules-load.c + +systemd_modules_load_CFLAGS = \ + $(AM_CFLAGS) \ + $(KMOD_CFLAGS) + +systemd_modules_load_LDADD = \ + libsystemd-shared.la \ + $(KMOD_LIBS) +endif + +# ------------------------------------------------------------------------------ +systemd_tmpfiles_SOURCES = \ + src/tmpfiles/tmpfiles.c + +systemd_tmpfiles_LDADD = \ + libsystemd-label.la \ + libsystemd-shared.la \ + libsystemd-capability.la + +# ------------------------------------------------------------------------------ +systemd_machine_id_setup_SOURCES = \ + src/machine-id-setup/machine-id-setup-main.c \ + src/core/machine-id-setup.c \ + src/core/machine-id-setup.h + +systemd_machine_id_setup_LDADD = \ + libsystemd-label.la \ + libsystemd-shared.la \ + libsystemd-id128-internal.la + +# ------------------------------------------------------------------------------ +systemd_sysctl_SOURCES = \ + src/sysctl/sysctl.c + +systemd_sysctl_LDADD = \ + libsystemd-shared.la + +# ------------------------------------------------------------------------------ +systemd_sleep_SOURCES = \ + src/sleep/sleep.c + +systemd_sleep_LDADD = \ + libsystemd-shared.la + +# ------------------------------------------------------------------------------ +systemd_fsck_SOURCES = \ + src/fsck/fsck.c + +systemd_fsck_CFLAGS = \ + $(AM_CFLAGS) \ + $(DBUS_CFLAGS) + +systemd_fsck_LDADD = \ + libsystemd-shared.la \ + libsystemd-dbus.la \ + libudev.la + +# ------------------------------------------------------------------------------ +systemd_timestamp_SOURCES = \ + src/timestamp/timestamp.c + +systemd_timestamp_LDADD = \ + libsystemd-shared.la + +# ------------------------------------------------------------------------------ +systemd_ac_power_SOURCES = \ + src/ac-power/ac-power.c + +systemd_ac_power_LDADD = \ + libsystemd-shared.la \ + libudev.la + +# ------------------------------------------------------------------------------ +systemd_detect_virt_SOURCES = \ + src/detect-virt/detect-virt.c + +systemd_detect_virt_LDADD = \ + libsystemd-shared.la + +systemd-detect-virt-install-hook: + -$(SETCAP) cap_dac_override,cap_sys_ptrace=ep $(DESTDIR)$(bindir)/systemd-detect-virt + +INSTALL_EXEC_HOOKS += \ + systemd-detect-virt-install-hook + +# ------------------------------------------------------------------------------ +systemd_delta_SOURCES = \ + src/delta/delta.c + +systemd_delta_LDADD = \ + libsystemd-shared.la + +# ------------------------------------------------------------------------------ +systemd_getty_generator_SOURCES = \ + src/getty-generator/getty-generator.c + +systemd_getty_generator_LDADD = \ + libsystemd-label.la \ + libsystemd-shared.la + +# ------------------------------------------------------------------------------ +systemd_fstab_generator_SOURCES = \ + src/fstab-generator/fstab-generator.c \ + src/core/mount-setup.c + +systemd_fstab_generator_LDADD = \ + libsystemd-label.la \ + libsystemd-shared.la + +# ------------------------------------------------------------------------------ +systemd_system_update_generator_SOURCES = \ + src/system-update-generator/system-update-generator.c + +systemd_system_update_generator_LDADD = \ + libsystemd-label.la \ + libsystemd-shared.la + +# ------------------------------------------------------------------------------ +systemd_rc_local_generator_SOURCES = \ + src/rc-local-generator/rc-local-generator.c + +systemd_rc_local_generator_LDADD = \ + libsystemd-label.la \ + libsystemd-shared.la + +# ------------------------------------------------------------------------------ +systemd_remount_fs_SOURCES = \ + src/remount-fs/remount-fs.c \ + src/core/mount-setup.c \ + src/core/mount-setup.h + +systemd_remount_fs_LDADD = \ + libsystemd-label.la \ + libsystemd-shared.la + +# ------------------------------------------------------------------------------ +systemd_cgroups_agent_SOURCES = \ + src/cgroups-agent/cgroups-agent.c + +systemd_cgroups_agent_CFLAGS = \ + $(AM_CFLAGS) \ + $(DBUS_CFLAGS) + +systemd_cgroups_agent_LDADD = \ + libsystemd-shared.la \ + libsystemd-dbus.la + +# ------------------------------------------------------------------------------ +systemctl_SOURCES = \ + src/systemctl/systemctl.c + +systemctl_CFLAGS = \ + $(AM_CFLAGS) \ + $(DBUS_CFLAGS) + +systemctl_LDADD = \ + libsystemd-units.la \ + libsystemd-label.la \ + libsystemd-shared.la \ + libsystemd-daemon.la \ + libsystemd-dbus.la \ + libsystemd-logs.la + +# ------------------------------------------------------------------------------ +systemd_notify_SOURCES = \ + src/notify/notify.c \ + src/readahead/sd-readahead.c + +systemd_notify_LDADD = \ + libsystemd-shared.la \ + libsystemd-daemon.la + +# ------------------------------------------------------------------------------ +systemd_ask_password_SOURCES = \ + src/ask-password/ask-password.c + +systemd_ask_password_LDADD = \ + libsystemd-label.la \ + libsystemd-shared.la + +# ------------------------------------------------------------------------------ +systemd_reply_password_SOURCES = \ + src/reply-password/reply-password.c + +systemd_reply_password_LDADD = \ + libsystemd-shared.la + +# ------------------------------------------------------------------------------ +systemd_cgls_SOURCES = \ + src/cgls/cgls.c + +systemd_cgls_LDADD = \ + libsystemd-shared.la + +# ------------------------------------------------------------------------------ +systemd_cgtop_SOURCES = \ + src/cgtop/cgtop.c + +systemd_cgtop_LDADD = \ + libsystemd-shared.la + +# ------------------------------------------------------------------------------ +systemd_nspawn_SOURCES = \ + src/nspawn/nspawn.c \ + src/core/mount-setup.c \ + src/core/mount-setup.h \ + src/core/loopback-setup.c \ + src/core/loopback-setup.h + +systemd_nspawn_LDADD = \ + libsystemd-label.la \ + libsystemd-capability.la \ + libsystemd-shared.la \ + libsystemd-daemon.la \ + libsystemd-id128-internal.la + +# ------------------------------------------------------------------------------ +systemd_stdio_bridge_SOURCES = \ + src/stdio-bridge/stdio-bridge.c + +systemd_stdio_bridge_LDADD = \ + libsystemd-shared.la + +# ------------------------------------------------------------------------------ +systemd_tty_ask_password_agent_SOURCES = \ + src/tty-ask-password-agent/tty-ask-password-agent.c + +systemd_tty_ask_password_agent_LDADD = \ + libsystemd-label.la \ + libsystemd-shared.la + +# ------------------------------------------------------------------------------ +libsystemd_daemon_la_SOURCES = \ + src/libsystemd-daemon/sd-daemon.c + +libsystemd_daemon_la_CFLAGS = \ + $(AM_CFLAGS) \ + -fvisibility=hidden \ + -DSD_EXPORT_SYMBOLS + +libsystemd_daemon_la_LDFLAGS = \ + $(AM_LDFLAGS) \ + -shared \ + -version-info $(LIBSYSTEMD_DAEMON_CURRENT):$(LIBSYSTEMD_DAEMON_REVISION):$(LIBSYSTEMD_DAEMON_AGE) \ + -Wl,--version-script=$(top_srcdir)/src/libsystemd-daemon/libsystemd-daemon.sym + +pkginclude_HEADERS += \ + src/systemd/sd-daemon.h + +# move lib from $(libdir) to $(rootlibdir) and update devel link, if needed +libsystemd-daemon-install-hook: + libname=libsystemd-daemon.so && $(move-to-rootlibdir) + +libsystemd-daemon-uninstall-hook: + rm -f $(DESTDIR)$(rootlibdir)/libsystemd-daemon.so* + +INSTALL_EXEC_HOOKS += libsystemd-daemon-install-hook +UNINSTALL_EXEC_HOOKS += libsystemd-daemon-uninstall-hook + +lib_LTLIBRARIES += \ + libsystemd-daemon.la + +pkgconfiglib_DATA += \ + src/libsystemd-daemon/libsystemd-daemon.pc + +MANPAGES += \ + man/sd-daemon.3 \ + man/sd_notify.3 \ + man/sd_listen_fds.3 \ + man/sd_is_fifo.3 \ + man/sd_booted.3 + +MANPAGES_ALIAS += \ + man/sd_is_socket.3 \ + man/sd_is_socket_unix.3 \ + man/sd_is_socket_inet.3 \ + man/sd_is_mq.3 \ + man/sd_notifyf.3 \ + man/SD_LISTEN_FDS_START.3 \ + man/SD_EMERG.3 \ + man/SD_ALERT.3 \ + man/SD_CRIT.3 \ + man/SD_ERR.3 \ + man/SD_WARNING.3 \ + man/SD_NOTICE.3 \ + man/SD_INFO.3 \ + man/SD_DEBUG.3 + +man/sd_is_socket.3: man/sd_is_fifo.3 +man/sd_is_socket_unix.3: man/sd_is_fifo.3 +man/sd_is_socket_inet.3: man/sd_is_fifo.3 +man/sd_is_mq.3: man/sd_is_fifo.3 +man/sd_notifyf.3: man/sd_notify.3 +man/SD_LISTEN_FDS_START.3: man/sd_listen_fds.3 +man/SD_EMERG.3: man/sd-daemon.3 +man/SD_ALERT.3: man/sd-daemon.3 +man/SD_CRIT.3: man/sd-daemon.3 +man/SD_ERR.3: man/sd-daemon.3 +man/SD_WARNING.3: man/sd-daemon.3 +man/SD_NOTICE.3: man/sd-daemon.3 +man/SD_INFO.3: man/sd-daemon.3 +man/SD_DEBUG.3: man/sd-daemon.3 + +EXTRA_DIST += \ + src/libsystemd-daemon/libsystemd-daemon.pc.in \ + src/libsystemd-daemon/libsystemd-daemon.sym + +# ------------------------------------------------------------------------------ +if ENABLE_GTK_DOC +SUBDIRS += \ + docs/libudev +endif + +include_HEADERS += \ + src/libudev/libudev.h + +lib_LTLIBRARIES += \ + libudev.la + +libudev_la_SOURCES =\ + src/libudev/libudev-private.h \ + src/libudev/libudev.c \ + src/libudev/libudev-list.c \ + src/libudev/libudev-util.c \ + src/libudev/libudev-device.c \ + src/libudev/libudev-enumerate.c \ + src/libudev/libudev-monitor.c \ + src/libudev/libudev-queue.c \ + src/libudev/libudev-hwdb-def.h \ + src/libudev/libudev-hwdb.c + +libudev_la_CFLAGS = \ + $(AM_CFLAGS) \ + -fvisibility=hidden + +libudev_la_LDFLAGS = \ + $(AM_LDFLAGS) \ + -version-info $(LIBUDEV_CURRENT):$(LIBUDEV_REVISION):$(LIBUDEV_AGE) \ + -Wl,--version-script=$(top_srcdir)/src/libudev/libudev.sym + +libudev_la_LIBADD = \ + libsystemd-shared.la + +pkgconfiglib_DATA += \ + src/libudev/libudev.pc + +EXTRA_DIST += \ + src/libudev/libudev.pc.in \ + src/libudev/libudev.sym + +CLEANFILES += \ + src/libudev/libudev.pc + +# move lib from $(libdir) to $(rootlibdir) and update devel link, if needed +libudev-install-hook: + libname=libudev.so && $(move-to-rootlibdir) + +libudev-uninstall-hook: + rm -f $(DESTDIR)$(rootlibdir)/libudev.so* + +INSTALL_EXEC_HOOKS += libudev-install-hook +UNINSTALL_EXEC_HOOKS += libudev-uninstall-hook + +# ------------------------------------------------------------------------------ +noinst_LTLIBRARIES += \ + libudev-private.la + +libudev_private_la_SOURCES =\ + $(libudev_la_SOURCES) \ + src/libudev/libudev-device-private.c \ + src/libudev/libudev-queue-private.c + +libudev_private_la_CFLAGS = \ + $(AM_CFLAGS) \ + -fvisibility=default + +libudev_private_la_LIBADD = \ + libsystemd-shared.la + +# ------------------------------------------------------------------------------ +MANPAGES += \ + man/udev.7 \ + man/udevadm.8 \ + man/systemd-udevd.service.8 + +MANPAGES_ALIAS += \ + man/systemd-udevd.8 \ + man/systemd-udevd-control.socket.8 \ + man/systemd-udevd-kernel.socket.8 + +man/systemd-udevd.8: man/systemd-udevd.service.8 +man/systemd-udevd-control.socket.8: man/systemd-udevd.service.8 +man/systemd-udevd-kernel.socket.8: man/systemd-udevd.service.8 + +udev-confdirs: + -$(MKDIR_P) $(DESTDIR)$(sysconfdir)/udev/rules.d + -$(MKDIR_P) $(DESTDIR)$(sysconfdir)/udev/hwdb.d + +INSTALL_DATA_HOOKS += udev-confdirs + +dist_udevrules_DATA += \ + rules/99-systemd.rules \ + rules/42-usb-hid-pm.rules \ + rules/50-udev-default.rules \ + rules/60-persistent-storage-tape.rules \ + rules/60-persistent-serial.rules \ + rules/60-persistent-input.rules \ + rules/60-persistent-alsa.rules \ + rules/60-persistent-storage.rules \ + rules/64-btrfs.rules \ + rules/75-net-description.rules \ + rules/75-tty-description.rules \ + rules/78-sound-card.rules \ + rules/80-net-name-slot.rules \ + rules/95-udev-late.rules + +if HAVE_KMOD +dist_udevrules_DATA += \ + rules/80-drivers.rules +endif + +dist_udevhwdb_DATA = \ + hwdb/20-pci-vendor-product.hwdb \ + hwdb/20-pci-classes.hwdb \ + hwdb/20-usb-vendor-product.hwdb \ + hwdb/20-usb-classes.hwdb \ + hwdb/20-bluetooth-vendor-product.hwdb \ + hwdb/20-acpi-vendor.hwdb \ + hwdb/20-OUI.hwdb + +udevconfdir = $(sysconfdir)/udev +dist_udevconf_DATA = \ + src/udev/udev.conf + +sharepkgconfigdir = $(datadir)/pkgconfig +sharepkgconfig_DATA = \ + src/udev/udev.pc + +EXTRA_DIST += \ + rules/99-systemd.rules.in \ + src/udev/udev.pc.in + +CLEANFILES += \ + rules/99-systemd.rules \ + src/udev/udev.pc + +EXTRA_DIST += \ + units/systemd-udevd.service.in \ + units/systemd-udev-trigger.service.in \ + units/systemd-udev-settle.service.in + +CLEANFILES += \ + units/systemd-udevd.service \ + units/systemd-udev-trigger.service \ + units/systemd-udev-settle.service + +systemd-install-hook: + $(MKDIR_P) $(DESTDIR)$(systemunitdir)/sockets.target.wants + ln -sf ../systemd-udevd-control.socket $(DESTDIR)$(systemunitdir)/sockets.target.wants/systemd-udevd-control.socket + ln -sf ../systemd-udevd-kernel.socket $(DESTDIR)$(systemunitdir)/sockets.target.wants/systemd-udevd-kernel.socket + $(MKDIR_P) $(DESTDIR)$(systemunitdir)/sysinit.target.wants + ln -sf ../systemd-udevd.service $(DESTDIR)$(systemunitdir)/sysinit.target.wants/systemd-udevd.service + ln -sf ../systemd-udev-trigger.service $(DESTDIR)$(systemunitdir)/sysinit.target.wants/systemd-udev-trigger.service + +INSTALL_DATA_HOOKS += systemd-install-hook + +bin_PROGRAMS += \ + udevadm + +rootlibexec_PROGRAMS += \ + systemd-udevd + +noinst_LTLIBRARIES += \ + libudev-core.la + +libudev_core_la_SOURCES = \ + src/udev/udev.h \ + src/udev/udev-event.c \ + src/udev/udev-watch.c \ + src/udev/udev-node.c \ + src/udev/udev-rules.c \ + src/udev/udev-ctrl.c \ + src/udev/udev-builtin.c \ + src/udev/udev-builtin-btrfs.c \ + src/udev/udev-builtin-firmware.c \ + src/udev/udev-builtin-hwdb.c \ + src/udev/udev-builtin-input_id.c \ + src/udev/udev-builtin-net_id.c \ + src/udev/udev-builtin-path_id.c \ + src/udev/udev-builtin-usb_id.c \ + src/libsystemd-daemon/sd-daemon.c + +libudev_core_la_CFLAGS = \ + $(AM_CFLAGS) \ + $(BLKID_CFLAGS) \ + $(KMOD_CFLAGS) + +libudev_core_la_LIBADD = \ + libudev-private.la \ + libsystemd-label.la \ + libsystemd-shared.la \ + $(BLKID_LIBS) \ + $(KMOD_LIBS) + +libudev_core_la_CPPFLAGS = \ + $(AM_CPPFLAGS) \ + -DFIRMWARE_PATH="$(FIRMWARE_PATH)" + +if HAVE_KMOD +libudev_core_la_SOURCES += \ + src/udev/udev-builtin-kmod.c +endif + +if HAVE_BLKID +libudev_core_la_SOURCES += \ + src/udev/udev-builtin-blkid.c +endif + +if HAVE_ACL +libudev_core_la_SOURCES += \ + src/udev/udev-builtin-uaccess.c \ + src/login/logind-acl.c \ + src/login/sd-login.c + +libudev_core_la_LIBADD += \ + libsystemd-acl.la +endif + +systemd_udevd_SOURCES = \ + src/udev/udevd.c + +systemd_udevd_LDADD = \ + libudev-core.la + +udevadm_SOURCES = \ + src/udev/udevadm.c \ + src/udev/udevadm-info.c \ + src/udev/udevadm-control.c \ + src/udev/udevadm-monitor.c \ + src/udev/udevadm-hwdb.c \ + src/udev/udevadm-settle.c \ + src/udev/udevadm-trigger.c \ + src/udev/udevadm-test.c \ + src/udev/udevadm-test-builtin.c + +udevadm_LDADD = \ + libudev-core.la \ + libsystemd-shared.la + +# Update hwdb on installation. Do not bother if installing +# in DESTDIR, since this is likely for packaging purposes. +hwdb-update-hook: + -test -n "$(DESTDIR)" || $(bindir)/udevadm hwdb --update + +INSTALL_DATA_HOOKS += \ + hwdb-update-hook + +hwdb-remove-hook: + -test -n "$(DESTDIR)" || rm -f $(HWDB_BIN) + +# ------------------------------------------------------------------------------ +TESTS += \ + test/udev-test.pl \ + test/rules-test.sh + +noinst_PROGRAMS += \ + test-libudev \ + test-udev + +test_libudev_SOURCES = \ + src/test/test-libudev.c + +test_libudev_LDADD = \ + libsystemd-label.la \ + libsystemd-shared.la \ + libudev.la + +test_udev_SOURCES = \ + src/test/test-udev.c + +test_udev_LDADD = \ + libudev-core.la \ + libsystemd-shared.la \ + $(BLKID_LIBS) \ + $(KMOD_LIBS) \ + $(SELINUX_LIBS) + +if HAVE_ACL +test_udev_LDADD += \ + libsystemd-acl.la +endif + +check_DATA += \ + test/sys + +# packed sysfs test tree +test/sys: + $(AM_V_at)$(MKDIR_P) $(dir $@) + $(AM_V_GEN)tar -C test/ -xJf $(top_srcdir)/test/sys.tar.xz + +test-sys-distclean: + -rm -rf test/sys +DISTCLEAN_LOCAL_HOOKS += test-sys-distclean + +EXTRA_DIST += \ + test/sys.tar.xz \ + test/udev-test.pl \ + test/rules-test.sh \ + test/rule-syntax-check.py + +# ------------------------------------------------------------------------------ +ata_id_SOURCES = \ + src/udev/ata_id/ata_id.c + +ata_id_LDADD = \ + libudev-private.la \ + libsystemd-shared.la + +udevlibexec_PROGRAMS += \ + ata_id + +# ------------------------------------------------------------------------------ +cdrom_id_SOURCES = \ + src/udev/cdrom_id/cdrom_id.c + +cdrom_id_LDADD = \ + libudev.la \ + libsystemd-shared.la + +udevlibexec_PROGRAMS += \ + cdrom_id + +dist_udevrules_DATA += \ + rules/60-cdrom_id.rules + +# ------------------------------------------------------------------------------ +collect_SOURCES = \ + src/udev/collect/collect.c + +collect_LDADD = \ + libudev-private.la + +udevlibexec_PROGRAMS += \ + collect + +# ------------------------------------------------------------------------------ +scsi_id_SOURCES =\ + src/udev/scsi_id/scsi_id.c \ + src/udev/scsi_id/scsi_serial.c \ + src/udev/scsi_id/scsi.h \ + src/udev/scsi_id/scsi_id.h + +scsi_id_LDADD = \ + libudev-private.la \ + libsystemd-shared.la + +udevlibexec_PROGRAMS += \ + scsi_id + +EXTRA_DIST += \ + src/udev/scsi_id/README + +# ------------------------------------------------------------------------------ +v4l_id_SOURCES = \ + src/udev/v4l_id/v4l_id.c + +v4l_id_LDADD = \ + libudev.la + +udevlibexec_PROGRAMS += \ + v4l_id + +dist_udevrules_DATA += \ + rules/60-persistent-v4l.rules + +# ------------------------------------------------------------------------------ +accelerometer_SOURCES = \ + src/udev/accelerometer/accelerometer.c + +accelerometer_LDADD = \ + libudev.la -lm \ + libsystemd-shared.la + +udevlibexec_PROGRAMS += \ + accelerometer + +dist_udevrules_DATA += \ + rules/61-accelerometer.rules + +# ------------------------------------------------------------------------------ +if ENABLE_GUDEV +if ENABLE_GTK_DOC +SUBDIRS += \ + docs/gudev +endif + +libgudev_includedir = \ + $(includedir)/gudev-1.0/gudev + +libgudev_include_HEADERS = \ + src/gudev/gudev.h \ + src/gudev/gudevenums.h \ + src/gudev/gudevenumtypes.h \ + src/gudev/gudevtypes.h \ + src/gudev/gudevclient.h \ + src/gudev/gudevdevice.h \ + src/gudev/gudevenumerator.h + +lib_LTLIBRARIES += libgudev-1.0.la + +pkgconfiglib_DATA += \ + src/gudev/gudev-1.0.pc + +CLEANFILES += \ + src/gudev/gudev-1.0.pc + +libgudev_1_0_la_SOURCES = \ + src/gudev/gudevenums.h \ + src/gudev/gudevenumtypes.h \ + src/gudev/gudevenumtypes.h\ + src/gudev/gudevtypes.h \ + src/gudev/gudevclient.h \ + src/gudev/gudevclient.c \ + src/gudev/gudevdevice.h \ + src/gudev/gudevdevice.c \ + src/gudev/gudevenumerator.h \ + src/gudev/gudevenumerator.c \ + src/gudev/gudevprivate.h + +nodist_libgudev_1_0_la_SOURCES = \ + src/gudev/gudevmarshal.h \ + src/gudev/gudevmarshal.c \ + src/gudev/gudevenumtypes.h \ + src/gudev/gudevenumtypes.c + +BUILT_SOURCES += \ + $(nodist_libgudev_1_0_la_SOURCES) + +libgudev_1_0_la_CPPFLAGS = \ + $(AM_CPPFLAGS) \ + -I$(top_builddir)/src\ + -I$(top_srcdir)/src\ + -I$(top_builddir)/src/gudev \ + -I$(top_srcdir)/src/gudev \ + -D_POSIX_PTHREAD_SEMANTICS -D_REENTRANT \ + -D_GUDEV_COMPILATION \ + -DG_LOG_DOMAIN=\"GUdev\" + +libgudev_1_0_la_CFLAGS = \ + $(AM_CFLAGS) \ + -fvisibility=default \ + $(GLIB_CFLAGS) + +libgudev_1_0_la_LIBADD = \ + libudev.la \ + $(GLIB_LIBS) + +libgudev_1_0_la_LDFLAGS = \ + $(AM_LDFLAGS) \ + -version-info $(LIBGUDEV_CURRENT):$(LIBGUDEV_REVISION):$(LIBGUDEV_AGE) \ + -export-dynamic -no-undefined \ + -export-symbols-regex '^g_udev_.*' + +src/gudev/gudevmarshal.h: src/gudev/gudevmarshal.list + $(AM_V_at)$(MKDIR_P) $(dir $@) + $(AM_V_GEN)glib-genmarshal $< --prefix=g_udev_marshal --header > $@ + +src/gudev/gudevmarshal.c: src/gudev/gudevmarshal.list + $(AM_V_at)$(MKDIR_P) $(dir $@) + $(AM_V_GEN)echo '#include "gudevmarshal.h"' > $@ && \ + glib-genmarshal $< --prefix=g_udev_marshal --body >> $@ + +src/gudev/gudevenumtypes.%: src/gudev/gudevenumtypes.%.template src/gudev/gudevenums.h + $(AM_V_at)$(MKDIR_P) $(dir $@) + $(AM_V_GEN)glib-mkenums --template $^ > $@ + +if HAVE_INTROSPECTION +-include $(INTROSPECTION_MAKEFILE) + +src/gudev/GUdev-1.0.gir: libgudev-1.0.la + +src_gudev_GUdev_1_0_gir_INCLUDES = GObject-2.0 + +src_gudev_GUdev_1_0_gir_CFLAGS = \ + $(INCLUDES) \ + -D_GUDEV_COMPILATION \ + -D_GUDEV_WORK_AROUND_DEV_T_BUG \ + -I$(top_srcdir)/src \ + -I$(top_builddir)/src \ + -I$(top_srcdir)/src/gdev \ + -I$(top_builddir)/src/gdev + +src_gudev_GUdev_1_0_gir_LIBS = libgudev-1.0.la + +src_gudev_GUdev_1_0_gir_SCANNERFLAGS = \ + --pkg-export=gudev-1.0 \ + --warn-all + +src_gudev_GUdev_1_0_gir_FILES = \ + src/gudev/gudev.h \ + src/gudev/gudevtypes.h \ + src/gudev/gudevenums.h \ + src/gudev/gudevenumtypes.h \ + src/gudev/gudevclient.h \ + src/gudev/gudevdevice.h \ + src/gudev/gudevenumerator.h \ + src/gudev/gudevclient.c \ + src/gudev/gudevdevice.c \ + src/gudev/gudevenumerator.c + +INTROSPECTION_GIRS = src/gudev/GUdev-1.0.gir +INTROSPECTION_SCANNER_ARGS = --c-include=gudev/gudev.h + +girdir = $(datadir)/gir-1.0 +gir_DATA = \ + src/gudev/GUdev-1.0.gir + +typelibsdir = $(libdir)/girepository-1.0 +typelibs_DATA = \ + src/gudev/GUdev-1.0.typelib + +CLEANFILES += $(gir_DATA) $(typelibs_DATA) +endif # HAVE_INTROSPECTION + +# move lib from $(libdir) to $(rootlibdir) and update devel link, if needed +libgudev-install-hook: + libname=libgudev-1.0.so && $(move-to-rootlibdir) + +libgudev-uninstall-hook: + rm -f $(DESTDIR)$(rootlibdir)/libgudev-1.0.so* + +INSTALL_EXEC_HOOKS += libgudev-install-hook +UNINSTALL_EXEC_HOOKS += libgudev-uninstall-hook +endif + +EXTRA_DIST += \ + src/gudev/gudev-1.0.pc.in \ + src/gudev/gudevmarshal.list \ + src/gudev/gudevenumtypes.h.template \ + src/gudev/gudevenumtypes.c.template \ + src/gudev/gjs-example.js \ + src/gudev/seed-example-enum.js \ + src/gudev/seed-example.js + + +# ------------------------------------------------------------------------------ +if ENABLE_KEYMAP +keymap_SOURCES = \ + src/udev/keymap/keymap.c + +keymap_CPPFLAGS = \ + $(AM_CPPFLAGS) -I src/udev/keymap + +keymap_LDADD = \ + libsystemd-shared.la + +nodist_keymap_SOURCES = \ + src/udev/keymap/keys-from-name.h \ + src/udev/keymap/keys-to-name.h + +BUILT_SOURCES += \ + $(nodist_keymap_SOURCES) + +udevlibexec_PROGRAMS += \ + keymap + +dist_doc_DATA += \ + src/udev/keymap/README.keymap.txt + +dist_udevrules_DATA += \ + src/udev/keymap/95-keymap.rules \ + src/udev/keymap/95-keyboard-force-release.rules + +dist_udevhome_SCRIPTS = \ + src/udev/keymap/findkeyboards \ + src/udev/keymap/keyboard-force-release.sh + +TESTS += \ + src/udev/keymap/check-keymaps.sh + +CLEANFILES += \ + src/udev/keymap/keys.txt \ + src/udev/keymap/keys-from-name.gperf \ + src/udev/keymap/keyboard-force-release.sh + +udevkeymapdir = $(udevlibexecdir)/keymaps +dist_udevkeymap_DATA = \ + keymaps/acer \ + keymaps/acer-aspire_5720 \ + keymaps/acer-aspire_8930 \ + keymaps/acer-aspire_5920g \ + keymaps/acer-aspire_6920 \ + keymaps/acer-travelmate_c300 \ + keymaps/asus \ + keymaps/compaq-e_evo \ + keymaps/dell \ + keymaps/dell-latitude-xt2 \ + keymaps/everex-xt5000 \ + keymaps/fujitsu-amilo_li_2732 \ + keymaps/fujitsu-amilo_pa_2548 \ + keymaps/fujitsu-amilo_pro_edition_v3505 \ + keymaps/fujitsu-amilo_pro_v3205 \ + keymaps/fujitsu-amilo_si_1520 \ + keymaps/fujitsu-esprimo_mobile_v5 \ + keymaps/fujitsu-esprimo_mobile_v6 \ + keymaps/genius-slimstar-320 \ + keymaps/hewlett-packard \ + keymaps/hewlett-packard-2510p_2530p \ + keymaps/hewlett-packard-compaq_elitebook \ + keymaps/hewlett-packard-pavilion \ + keymaps/hewlett-packard-presario-2100 \ + keymaps/hewlett-packard-tablet \ + keymaps/hewlett-packard-tx2 \ + keymaps/hewlett-packard_elitebook-8440p \ + keymaps/ibm-thinkpad-usb-keyboard-trackpoint \ + keymaps/inventec-symphony_6.0_7.0 \ + keymaps/lenovo-3000 \ + keymaps/lenovo-ideapad \ + keymaps/lenovo-thinkpad-usb-keyboard-trackpoint \ + keymaps/lenovo-thinkpad_x6_tablet \ + keymaps/lenovo-thinkpad_x200_tablet \ + keymaps/lg-x110 \ + keymaps/logitech-wave \ + keymaps/logitech-wave-cordless \ + keymaps/logitech-wave-pro-cordless \ + keymaps/maxdata-pro_7000 \ + keymaps/medion-fid2060 \ + keymaps/medionnb-a555 \ + keymaps/micro-star \ + keymaps/module-asus-w3j \ + keymaps/module-ibm \ + keymaps/module-lenovo \ + keymaps/module-sony \ + keymaps/module-sony-old \ + keymaps/module-sony-vgn \ + keymaps/module-sony-vpc \ + keymaps/olpc-xo \ + keymaps/onkyo \ + keymaps/oqo-model2 \ + keymaps/samsung-other \ + keymaps/samsung-series-9 \ + keymaps/samsung-sq1us \ + keymaps/samsung-sx20s \ + keymaps/toshiba-satellite_a100 \ + keymaps/toshiba-satellite_a110 \ + keymaps/toshiba-satellite_m30x \ + keymaps/zepto-znote + +udevkeymapforcereldir = $(udevlibexecdir)/keymaps/force-release +dist_udevkeymapforcerel_DATA = \ + keymaps-force-release/dell-touchpad \ + keymaps-force-release/dell-xps \ + keymaps-force-release/hp-other \ + keymaps-force-release/samsung-other \ + keymaps-force-release/samsung-series-9 \ + keymaps-force-release/common-volume-keys + +src/udev/keymap/keys.txt: Makefile + $(AM_V_at)$(MKDIR_P) $(dir $@) + $(AM_V_GEN)$(CPP) $(CFLAGS) $(AM_CPPFLAGS) $(CPPFLAGS) -dM -include linux/input.h - < /dev/null | $(AWK) '/^#define[ \t]+KEY_[^ ]+[ \t]+[0-9]/ { if ($$2 != "KEY_MAX") { print $$2 } }' | sed 's/^KEY_COFFEE$$/KEY_SCREENLOCK/' > $@ + +src/udev/keymap/keys-from-name.gperf: src/udev/keymap/keys.txt Makefile + $(AM_V_GEN)$(AWK) 'BEGIN{ print "struct key { const char* name; unsigned short id; };"; print "%null-strings"; print "%%";} { print $$1 ", " $$1 }' < $< > $@ + +src/udev/keymap/keys-from-name.h: src/udev/keymap/keys-from-name.gperf Makefile + $(AM_V_GEN)$(GPERF) -L ANSI-C -t --ignore-case -N lookup_key -H hash_key_name -p -C < $< > $@ + +src/udev/keymap/keys-to-name.h: src/udev/keymap/keys.txt Makefile + $(AM_V_GEN)$(AWK) 'BEGIN{ print "const char* const key_names[KEY_CNT] = { "} { print "[" $$1 "] = \"" $$1 "\"," } END{print "};"}' < $< > $@ +endif + +EXTRA_DIST += \ + src/udev/keymap/check-keymaps.sh \ + src/udev/keymap/keyboard-force-release.sh.in + +# ------------------------------------------------------------------------------ +mtd_probe_SOURCES = \ + src/udev/mtd_probe/mtd_probe.c \ + src/udev/mtd_probe/mtd_probe.h \ + src/udev/mtd_probe/probe_smartmedia.c + +mtd_probe_CPPFLAGS = \ + $(AM_CPPFLAGS) + +dist_udevrules_DATA += \ + rules/75-probe_mtd.rules + +udevlibexec_PROGRAMS += \ + mtd_probe + +# ------------------------------------------------------------------------------ +libsystemd_id128_la_SOURCES = \ + src/libsystemd-id128/sd-id128.c + +libsystemd_id128_la_CFLAGS = \ + $(AM_CFLAGS) \ + -fvisibility=hidden + +libsystemd_id128_la_LDFLAGS = \ + $(AM_LDFLAGS) \ + -shared \ + -version-info $(LIBSYSTEMD_ID128_CURRENT):$(LIBSYSTEMD_ID128_REVISION):$(LIBSYSTEMD_ID128_AGE) \ + -Wl,--version-script=$(top_srcdir)/src/libsystemd-id128/libsystemd-id128.sym + +libsystemd_id128_la_LIBADD = \ + libsystemd-shared.la + +libsystemd_id128_internal_la_SOURCES = \ + $(libsystemd_id128_la_SOURCES) + +test_id128_SOURCES = \ + src/test/test-id128.c + +test_id128_LDADD = \ + libsystemd-shared.la \ + libsystemd-id128-internal.la + +noinst_PROGRAMS += \ + test-id128 + +TESTS += \ + test-id128 + +pkginclude_HEADERS += \ + src/systemd/sd-id128.h + +lib_LTLIBRARIES += \ + libsystemd-id128.la + +noinst_LTLIBRARIES += \ + libsystemd-id128-internal.la + +pkgconfiglib_DATA += \ + src/libsystemd-id128/libsystemd-id128.pc + +# move lib from $(libdir) to $(rootlibdir) and update devel link, if needed +libsystemd-id128-install-hook: + libname=libsystemd-id128.so && $(move-to-rootlibdir) + +libsystemd-id128-uninstall-hook: + rm -f $(DESTDIR)$(rootlibdir)/libsystemd-id128.so* + +INSTALL_EXEC_HOOKS += libsystemd-id128-install-hook +UNINSTALL_EXEC_HOOKS += libsystemd-id128-uninstall-hook + +EXTRA_DIST += \ + src/libsystemd-id128/libsystemd-id128.pc.in \ + src/libsystemd-id128/libsystemd-id128.sym + +# ------------------------------------------------------------------------------ +systemd_journald_SOURCES = \ + src/journal/journald.c \ + src/journal/journald-server.h + +systemd_journald_LDADD = \ + libsystemd-journal-internal.la \ + libsystemd-shared.la \ + libsystemd-id128-internal.la + +systemd_cat_SOURCES = \ + src/journal/cat.c + +systemd_cat_LDADD = \ + libsystemd-shared.la \ + libsystemd-journal-internal.la + +journalctl_SOURCES = \ + src/journal/journalctl.c + +journalctl_CFLAGS = \ + $(AM_CFLAGS) + +journalctl_LDADD = \ + libsystemd-shared.la \ + libsystemd-journal-internal.la \ + libsystemd-id128-internal.la \ + libsystemd-logs.la + +if HAVE_QRENCODE +journalctl_SOURCES += \ + src/journal/journal-qrcode.c \ + src/journal/journal-qrcode.h + +journalctl_CFLAGS += \ + $(QRENCODE_CFLAGS) + +journalctl_LDADD += \ + $(QRENCODE_LIBS) +endif + +systemd_coredumpctl_SOURCES = \ + src/journal/coredumpctl.c + +systemd_coredumpctl_LDADD = \ + libsystemd-shared.la \ + libsystemd-journal.la + +test_journal_SOURCES = \ + src/journal/test-journal.c + +test_journal_LDADD = \ + libsystemd-shared.la \ + libsystemd-journal-internal.la \ + libsystemd-id128-internal.la + +test_journal_send_SOURCES = \ + src/journal/test-journal-send.c + +test_journal_send_LDADD = \ + libsystemd-shared.la \ + libsystemd-journal-internal.la \ + libsystemd-id128-internal.la + +test_journal_syslog_SOURCES = \ + src/journal/test-journal-syslog.c + +test_journal_syslog_LDADD = \ + libsystemd-journal-internal.la \ + libsystemd-shared.la \ + libsystemd-id128-internal.la + +test_journal_match_SOURCES = \ + src/journal/test-journal-match.c + +test_journal_match_LDADD = \ + libsystemd-shared.la \ + libsystemd-journal-internal.la \ + libsystemd-id128-internal.la + +test_journal_enum_SOURCES = \ + src/journal/test-journal-enum.c + +test_journal_enum_LDADD = \ + libsystemd-shared.la \ + libsystemd-journal-internal.la \ + libsystemd-id128-internal.la + +test_journal_stream_SOURCES = \ + src/journal/test-journal-stream.c + +test_journal_stream_LDADD = \ + libsystemd-shared.la \ + libsystemd-journal-internal.la \ + libsystemd-id128-internal.la + +test_journal_verify_SOURCES = \ + src/journal/test-journal-verify.c + +test_journal_verify_LDADD = \ + libsystemd-shared.la \ + libsystemd-journal-internal.la \ + libsystemd-id128-internal.la + +test_mmap_cache_SOURCES = \ + src/journal/test-mmap-cache.c + +test_mmap_cache_LDADD = \ + libsystemd-shared.la \ + libsystemd-journal-internal.la + +test_catalog_SOURCES = \ + src/journal/test-catalog.c + +test_catalog_LDADD = \ + libsystemd-shared.la \ + libsystemd-label.la \ + libsystemd-journal-internal.la \ + libsystemd-id128-internal.la + +libsystemd_journal_la_SOURCES = \ + src/journal/sd-journal.c \ + src/systemd/sd-journal.h \ + src/journal/journal-file.c \ + src/journal/journal-file.h \ + src/journal/journal-vacuum.c \ + src/journal/journal-vacuum.h \ + src/journal/journal-verify.c \ + src/journal/journal-verify.h \ + src/journal/lookup3.c \ + src/journal/lookup3.h \ + src/journal/journal-send.c \ + src/journal/journal-def.h \ + src/journal/compress.h \ + src/journal/catalog.c \ + src/journal/catalog.h \ + src/journal/mmap-cache.c \ + src/journal/mmap-cache.h + +libsystemd_journal_la_CFLAGS = \ + $(AM_CFLAGS) \ + -fvisibility=hidden + +libsystemd_journal_la_LDFLAGS = \ + $(AM_LDFLAGS) \ + -shared \ + -version-info $(LIBSYSTEMD_JOURNAL_CURRENT):$(LIBSYSTEMD_JOURNAL_REVISION):$(LIBSYSTEMD_JOURNAL_AGE) \ + -Wl,--version-script=$(top_srcdir)/src/journal/libsystemd-journal.sym + +libsystemd_journal_la_LIBADD = \ + libsystemd-shared.la \ + libsystemd-label.la \ + libsystemd-id128-internal.la + +libsystemd_journal_internal_la_SOURCES = \ + $(libsystemd_journal_la_SOURCES) \ + src/journal/journald-kmsg.c \ + src/journal/journald-kmsg.h \ + src/journal/journald-syslog.c \ + src/journal/journald-syslog.h \ + src/journal/journald-stream.c \ + src/journal/journald-stream.h \ + src/journal/journald-server.c \ + src/journal/journald-server.h \ + src/journal/journald-console.c \ + src/journal/journald-console.h \ + src/journal/journald-native.c \ + src/journal/journald-native.h \ + src/journal/journald-rate-limit.c \ + src/journal/journald-rate-limit.h \ + src/journal/journal-internal.h + +libsystemd_journal_internal_la_CFLAGS = \ + $(AM_CFLAGS) + +libsystemd_journal_internal_la_LIBADD = \ + libsystemd-label.la \ + libsystemd-audit.la \ + libsystemd-daemon.la \ + libudev.la \ + libsystemd-shared.la \ + libsystemd-label.la + +nodist_libsystemd_journal_internal_la_SOURCES = \ + src/journal/journald-gperf.c + +if ENABLE_LOGIND +libsystemd_journal_internal_la_LIBADD += \ + libsystemd-login-internal.la +endif + +if HAVE_ACL +libsystemd_journal_internal_la_LIBADD += \ + libsystemd-acl.la +endif + +if HAVE_XZ +libsystemd_journal_la_SOURCES += \ + src/journal/compress.c + +libsystemd_journal_la_CFLAGS += \ + $(XZ_CFLAGS) + +libsystemd_journal_la_LIBADD += \ + $(XZ_LIBS) + +libsystemd_journal_internal_la_CFLAGS += \ + $(XZ_CFLAGS) + +libsystemd_journal_internal_la_LIBADD += \ + $(XZ_LIBS) + +endif + +if HAVE_GCRYPT +libsystemd_journal_la_SOURCES += \ + src/journal/journal-authenticate.c \ + src/journal/journal-authenticate.h \ + src/journal/fsprg.c \ + src/journal/fsprg.h + +libsystemd_journal_la_CFLAGS += \ + $(GCRYPT_CFLAGS) \ + -Wno-pointer-arith + +libsystemd_journal_la_LIBADD += \ + $(GCRYPT_LIBS) + +libsystemd_journal_internal_la_CFLAGS += \ + $(GCRYPT_CFLAGS) \ + -Wno-pointer-arith + +libsystemd_journal_internal_la_LIBADD += \ + $(GCRYPT_LIBS) +endif + +# move lib from $(libdir) to $(rootlibdir) and update devel link, if needed +libsystemd-journal-install-hook: + libname=libsystemd-journal.so && $(move-to-rootlibdir) + +libsystemd-journal-uninstall-hook: + rm -f $(DESTDIR)$(rootlibdir)/libsystemd-journal.so* + +INSTALL_EXEC_HOOKS += libsystemd-journal-install-hook +UNINSTALL_EXEC_HOOKS += libsystemd-journal-uninstall-hook + +# Update catalog on installation. Do not bother if installing +# in DESTDIR, since this is likely for packaging purposes. +catalog-update-hook: + -test -n "$(DESTDIR)" || $(rootbindir)/journalctl --update-catalog + +INSTALL_DATA_HOOKS += \ + catalog-update-hook + +catalog-remove-hook: + -test -n "$(DESTDIR)" || rm -f $(catalogstatedir)/database + +UNINSTALL_DATA_HOOKS += \ + catalog-remove-hook + +noinst_PROGRAMS += \ + test-journal \ + test-journal-send \ + test-journal-syslog \ + test-journal-match \ + test-journal-enum \ + test-journal-stream \ + test-journal-verify \ + test-mmap-cache \ + test-catalog + +TESTS += \ + test-journal \ + test-journal-send \ + test-journal-syslog \ + test-journal-match \ + test-journal-stream \ + test-journal-verify \ + test-mmap-cache + +pkginclude_HEADERS += \ + src/systemd/sd-journal.h \ + src/systemd/sd-messages.h + +lib_LTLIBRARIES += \ + libsystemd-journal.la + +noinst_LTLIBRARIES += \ + libsystemd-journal-internal.la + +rootlibexec_PROGRAMS += \ + systemd-journald + +rootbin_PROGRAMS += \ + journalctl + +bin_PROGRAMS += \ + systemd-coredumpctl \ + systemd-cat + +dist_systemunit_DATA += \ + units/systemd-journald.socket + +nodist_systemunit_DATA += \ + units/systemd-journald.service \ + units/systemd-journal-flush.service + +dist_pkgsysconf_DATA += \ + src/journal/journald.conf + +pkgconfiglib_DATA += \ + src/journal/libsystemd-journal.pc + +dist_catalog_DATA = \ + catalog/systemd.catalog + +journal-install-data-hook: + $(MKDIR_P) -m 0755 \ + $(DESTDIR)$(systemunitdir)/sockets.target.wants \ + $(DESTDIR)$(systemunitdir)/sysinit.target.wants + ( cd $(DESTDIR)$(systemunitdir)/sockets.target.wants && \ + rm -f systemd-journald.socket && \ + $(LN_S) ../systemd-journald.socket ) + ( cd $(DESTDIR)$(systemunitdir)/sysinit.target.wants && \ + rm -f systemd-journald.service systemd-journal-flush.service && \ + $(LN_S) ../systemd-journald.service && \ + $(LN_S) ../systemd-journal-flush.service ) + +INSTALL_DATA_HOOKS += \ + journal-install-data-hook + +EXTRA_DIST += \ + src/journal/libsystemd-journal.pc.in \ + src/journal/libsystemd-journal.sym \ + units/systemd-journald.service.in \ + units/systemd-journal-flush.service.in \ + src/journal/journald-gperf.gperf + +CLEANFILES += \ + src/journal/journald-gperf.c + +if HAVE_MICROHTTPD + +gatewayddocumentrootdir=$(pkgdatadir)/gatewayd + +rootlibexec_PROGRAMS += \ + systemd-journal-gatewayd + +systemd_journal_gatewayd_SOURCES = \ + src/journal/journal-gatewayd.c + +systemd_journal_gatewayd_LDADD = \ + libsystemd-shared.la \ + libsystemd-logs.la \ + libsystemd-journal-internal.la \ + libsystemd-id128-internal.la \ + libsystemd-daemon.la \ + $(MICROHTTPD_LIBS) + +systemd_journal_gatewayd_CFLAGS = \ + -DDOCUMENT_ROOT=\"$(gatewayddocumentrootdir)\" \ + $(AM_CFLAGS) \ + $(MICROHTTPD_CFLAGS) + +dist_systemunit_DATA += \ + units/systemd-journal-gatewayd.socket + +nodist_systemunit_DATA += \ + units/systemd-journal-gatewayd.service + +dist_gatewayddocumentroot_DATA = \ + src/journal/browse.html + +endif + +EXTRA_DIST += \ + units/systemd-journal-gatewayd.service.in + +# ------------------------------------------------------------------------------ +if ENABLE_COREDUMP +systemd_coredump_SOURCES = \ + src/journal/coredump.c + +systemd_coredump_LDADD = \ + libsystemd-journal-internal.la \ + libsystemd-label.la \ + libsystemd-shared.la + +if ENABLE_LOGIND +systemd_coredump_LDADD += \ + libsystemd-login-internal.la +endif + +rootlibexec_PROGRAMS += \ + systemd-coredump + +sysctl_DATA = \ + sysctl.d/coredump.conf + +CLEANFILES += \ + sysctl.d/coredump.conf +endif + +EXTRA_DIST += \ + sysctl.d/coredump.conf.in + +# ------------------------------------------------------------------------------ +if ENABLE_BINFMT +systemd_binfmt_SOURCES = \ + src/binfmt/binfmt.c + +systemd_binfmt_LDADD = \ + libsystemd-shared.la + +rootlibexec_PROGRAMS += \ + systemd-binfmt + +dist_systemunit_DATA += \ + units/proc-sys-fs-binfmt_misc.automount \ + units/proc-sys-fs-binfmt_misc.mount + +nodist_systemunit_DATA += \ + units/systemd-binfmt.service + +binfmt-install-data-hook: + $(MKDIR_P) -m 0755 \ + $(DESTDIR)$(prefix)/lib/binfmt.d \ + $(DESTDIR)$(sysconfdir)/binfmt.d \ + $(DESTDIR)$(systemunitdir)/sysinit.target.wants + ( cd $(DESTDIR)$(systemunitdir)/sysinit.target.wants && \ + rm -f systemd-binfmt.service \ + proc-sys-fs-binfmt_misc.automount && \ + $(LN_S) ../systemd-binfmt.service systemd-binfmt.service && \ + $(LN_S) ../proc-sys-fs-binfmt_misc.automount proc-sys-fs-binfmt_misc.automount ) + +INSTALL_DATA_HOOKS += \ + binfmt-install-data-hook + +MANPAGES += \ + man/binfmt.d.5 \ + man/systemd-binfmt.service.8 + +MANPAGES_ALIAS += \ + man/systemd-binfmt.8 + +man/systemd-binfmt.8: man/systemd-binfmt.service.8 +endif + +EXTRA_DIST += \ + units/systemd-binfmt.service.in + +# ------------------------------------------------------------------------------ +if ENABLE_VCONSOLE +systemd_vconsole_setup_SOURCES = \ + src/vconsole/vconsole-setup.c + +systemd_vconsole_setup_LDADD = \ + libsystemd-shared.la + +rootlibexec_PROGRAMS += \ + systemd-vconsole-setup + +nodist_systemunit_DATA += \ + units/systemd-vconsole-setup.service + +vconsole-install-data-hook: + $(MKDIR_P) -m 0755 \ + $(DESTDIR)$(systemunitdir)/sysinit.target.wants + ( cd $(DESTDIR)$(systemunitdir)/sysinit.target.wants && \ + rm -f systemd-vconsole-setup.service && \ + $(LN_S) ../systemd-vconsole-setup.service systemd-vconsole-setup.service ) + +INSTALL_DATA_HOOKS += \ + vconsole-install-data-hook + +MANPAGES += \ + man/vconsole.conf.5 \ + man/systemd-vconsole-setup.service.8 + +MANPAGES_ALIAS += \ + man/systemd-vconsole-setup.8 + +man/systemd-vconsole-setup.8: man/systemd-vconsole-setup.service.8 +endif + +EXTRA_DIST += \ + units/systemd-vconsole-setup.service.in + +# ------------------------------------------------------------------------------ +if ENABLE_READAHEAD +systemd_readahead_SOURCES = \ + src/readahead/readahead.c \ + src/readahead/readahead-collect.c \ + src/readahead/readahead-replay.c \ + src/readahead/readahead-analyze.c \ + src/readahead/readahead-common.c \ + src/readahead/readahead-common.h + +systemd_readahead_LDADD = \ + libsystemd-shared.la \ + libsystemd-daemon.la \ + libudev.la + +dist_doc_DATA += \ + src/readahead/sd-readahead.c \ + src/systemd/sd-readahead.h + +rootlibexec_PROGRAMS += \ + systemd-readahead + +dist_systemunit_DATA += \ + units/systemd-readahead-drop.service \ + units/systemd-readahead-done.timer + +nodist_systemunit_DATA += \ + units/systemd-readahead-collect.service \ + units/systemd-readahead-replay.service \ + units/systemd-readahead-done.service + +MANPAGES += \ + man/sd_readahead.3 \ + man/sd-readahead.3 \ + man/systemd-readahead-replay.service.8 + +MANPAGES_ALIAS += \ + man/systemd-readahead-collect.service.8 \ + man/systemd-readahead-done.service.8 \ + man/systemd-readahead-done.timer.8 \ + man/systemd-readahead.8 + +man/systemd-readahead-collect.service.8: man/systemd-readahead-replay.service.8 +man/systemd-readahead-done.service.8: man/systemd-readahead-replay.service.8 +man/systemd-readahead-done.timer.8: man/systemd-readahead-replay.service.8 +man/systemd-readahead.8: man/systemd-readahead-replay.service.8 + +endif + +EXTRA_DIST += \ + units/systemd-readahead-collect.service.in \ + units/systemd-readahead-replay.service.in \ + units/systemd-readahead-done.service.in + +# ------------------------------------------------------------------------------ +if ENABLE_QUOTACHECK +rootlibexec_PROGRAMS += \ + systemd-quotacheck + +nodist_systemunit_DATA += \ + units/systemd-quotacheck.service + +systemd_quotacheck_SOURCES = \ + src/quotacheck/quotacheck.c + +systemd_quotacheck_LDADD = \ + libsystemd-shared.la + +MANPAGES += \ + man/systemd-quotacheck.service.8 + +MANPAGES_ALIAS += \ + man/systemd-quotacheck.8 + +man/systemd-quotacheck.8: man/systemd-quotacheck.service.8 + +endif + +EXTRA_DIST += \ + units/systemd-quotacheck.service.in + +nodist_systemunit_DATA += \ + units/quotaon.service + +# ------------------------------------------------------------------------------ +if ENABLE_RANDOMSEED +rootlibexec_PROGRAMS += \ + systemd-random-seed + +nodist_systemunit_DATA += \ + units/systemd-random-seed-save.service \ + units/systemd-random-seed-load.service + +systemd_random_seed_SOURCES = \ + src/random-seed/random-seed.c + +systemd_random_seed_LDADD = \ + libsystemd-label.la \ + libsystemd-shared.la + +randomseed-install-data-hook: + $(MKDIR_P) -m 0755 \ + $(DESTDIR)$(systemunitdir)/shutdown.target.wants \ + $(DESTDIR)$(systemunitdir)/sysinit.target.wants + ( cd $(DESTDIR)$(systemunitdir)/shutdown.target.wants && \ + rm -f systemd-random-seed-save.service && \ + $(LN_S) ../systemd-random-seed-save.service systemd-random-seed-save.service ) + ( cd $(DESTDIR)$(systemunitdir)/sysinit.target.wants && \ + rm -f systemd-random-seed-load.service && \ + $(LN_S) ../systemd-random-seed-load.service systemd-random-seed-load.service ) + +INSTALL_DATA_HOOKS += \ + randomseed-install-data-hook + +MANPAGES += \ + man/systemd-random-seed-load.service.8 + +MANPAGES_ALIAS += \ + man/systemd-random-seed-save.service.8 \ + man/systemd-random-seed.8 + +man/systemd-random-seed-save.service.8: man/systemd-random-seed-load.service.8 +man/systemd-random-seed.8: man/systemd-random-seed-load.service.8 + +endif + +EXTRA_DIST += \ + units/systemd-random-seed-save.service.in \ + units/systemd-random-seed-load.service.in + +# ------------------------------------------------------------------------------ +if HAVE_LIBCRYPTSETUP +rootlibexec_PROGRAMS += \ + systemd-cryptsetup + +systemgenerator_PROGRAMS += \ + systemd-cryptsetup-generator + +dist_systemunit_DATA += \ + units/cryptsetup.target + +systemd_cryptsetup_SOURCES = \ + src/cryptsetup/cryptsetup.c + +systemd_cryptsetup_CFLAGS = \ + $(AM_CFLAGS) \ + $(LIBCRYPTSETUP_CFLAGS) + +systemd_cryptsetup_LDADD = \ + libsystemd-label.la \ + libsystemd-shared.la \ + libudev.la \ + $(LIBCRYPTSETUP_LIBS) + +systemd_cryptsetup_generator_SOURCES = \ + src/cryptsetup/cryptsetup-generator.c + +systemd_cryptsetup_generator_LDADD = \ + libsystemd-label.la \ + libsystemd-shared.la + +cryptsetup-install-data-hook: + $(MKDIR_P) -m 0755 \ + $(DESTDIR)$(systemunitdir)/sysinit.target.wants + ( cd $(DESTDIR)$(systemunitdir)/sysinit.target.wants && \ + rm -f cryptsetup.target && \ + $(LN_S) ../cryptsetup.target cryptsetup.target ) + +INSTALL_DATA_HOOKS += \ + cryptsetup-install-data-hook + +MANPAGES += \ + man/systemd-cryptsetup@.service.8 \ + man/systemd-cryptsetup-generator.8 \ + man/crypttab.5 + +MANPAGES_ALIAS += \ + man/systemd-cryptsetup.8 + +man/systemd-cryptsetup.8: man/systemd-cryptsetup@.service.8 + +endif + +# ------------------------------------------------------------------------------ +if ENABLE_HOSTNAMED +systemd_hostnamed_SOURCES = \ + src/hostname/hostnamed.c + +systemd_hostnamed_CFLAGS = \ + $(AM_CFLAGS) \ + $(DBUS_CFLAGS) + +systemd_hostnamed_LDADD = \ + libsystemd-shared.la \ + libsystemd-daemon.la \ + libsystemd-dbus.la + +rootlibexec_PROGRAMS += \ + systemd-hostnamed + +nodist_systemunit_DATA += \ + units/systemd-hostnamed.service + +dist_dbuspolicy_DATA += \ + src/hostname/org.freedesktop.hostname1.conf + +dist_dbussystemservice_DATA += \ + src/hostname/org.freedesktop.hostname1.service + +polkitpolicy_files += \ + src/hostname/org.freedesktop.hostname1.policy + +dbusinterface_DATA += \ + org.freedesktop.hostname1.xml + +org.freedesktop.hostname1.xml: systemd-hostnamed + $(AM_V_GEN)$(LIBTOOL) --mode=execute $(OBJCOPY) -O binary -j introspect.hostname1 $< $@.tmp && \ + $(STRINGS) $@.tmp | $(AWK) -f $(srcdir)/introspect.awk | \ + $(DBUS_PREPROCESS) -o $@ - && rm $@.tmp + +hostnamed-install-data-hook: + ( cd $(DESTDIR)$(systemunitdir) && \ + rm -f dbus-org.freedesktop.hostname1.service && \ + $(LN_S) systemd-hostnamed.service dbus-org.freedesktop.hostname1.service ) + +INSTALL_DATA_HOOKS += \ + hostnamed-install-data-hook + +MANPAGES += \ + man/systemd-hostnamed.service.8 + +MANPAGES_ALIAS += \ + man/systemd-hostnamed.8 + +man/systemd-hostnamed.8: man/systemd-hostnamed.service.8 + +hostnamectl_SOURCES = \ + src/hostname/hostnamectl.c + +hostnamectl_CFLAGS = \ + $(AM_CFLAGS) \ + $(DBUS_CFLAGS) + +hostnamectl_LDADD = \ + libsystemd-shared.la \ + libsystemd-dbus.la \ + libsystemd-id128-internal.la + +bin_PROGRAMS += \ + hostnamectl + +MANPAGES += \ + man/hostnamectl.1 + +endif + +polkitpolicy_in_files += \ + src/hostname/org.freedesktop.hostname1.policy.in + +EXTRA_DIST += \ + units/systemd-hostnamed.service.in + +# ------------------------------------------------------------------------------ +if ENABLE_LOCALED +systemd_localed_SOURCES = \ + src/locale/localed.c + +systemd_localed_CFLAGS = \ + $(AM_CFLAGS) \ + $(DBUS_CFLAGS) + +systemd_localed_LDADD = \ + libsystemd-label.la \ + libsystemd-shared.la \ + libsystemd-daemon.la \ + libsystemd-dbus.la + +nodist_systemunit_DATA += \ + units/systemd-localed.service + +rootlibexec_PROGRAMS += \ + systemd-localed + +dist_dbuspolicy_DATA += \ + src/locale/org.freedesktop.locale1.conf + +dist_dbussystemservice_DATA += \ + src/locale/org.freedesktop.locale1.service + +polkitpolicy_files += \ + src/locale/org.freedesktop.locale1.policy + +dbusinterface_DATA += \ + org.freedesktop.locale1.xml + +org.freedesktop.locale1.xml: systemd-localed + $(AM_V_GEN)$(LIBTOOL) --mode=execute $(OBJCOPY) -O binary -j introspect.locale1 $< $@.tmp && \ + $(STRINGS) $@.tmp | $(AWK) -f $(srcdir)/introspect.awk | \ + $(DBUS_PREPROCESS) -o $@ - && rm $@.tmp + +localed-install-data-hook: + ( cd $(DESTDIR)$(systemunitdir) && \ + rm -f dbus-org.freedesktop.locale1.service && \ + $(LN_S) systemd-localed.service dbus-org.freedesktop.locale1.service ) + +INSTALL_DATA_HOOKS += \ + localed-install-data-hook + +MANPAGES += \ + man/systemd-localed.service.8 + +MANPAGES_ALIAS += \ + man/systemd-localed.8 + +man/systemd-localed.8: man/systemd-localed.service.8 + +dist_pkgdata_DATA += \ + src/locale/kbd-model-map + +dist_noinst_SCRIPT = \ + src/locale/generate-kbd-model-map + +update-kbd-model-map: src/locale/generate-kbd-model-map + $PYTHON $< > src/locale/kbd-model-map + +localectl_SOURCES = \ + src/locale/localectl.c + +localectl_CFLAGS = \ + $(AM_CFLAGS) \ + $(DBUS_CFLAGS) + +localectl_LDADD = \ + libsystemd-shared.la \ + libsystemd-dbus.la \ + libsystemd-id128-internal.la + +bin_PROGRAMS += \ + localectl + +MANPAGES += \ + man/localectl.1 + +endif + +polkitpolicy_in_files += \ + src/locale/org.freedesktop.locale1.policy.in + +EXTRA_DIST += \ + units/systemd-localed.service.in + +# ------------------------------------------------------------------------------ +if ENABLE_TIMEDATED +systemd_timedated_SOURCES = \ + src/timedate/timedated.c + +systemd_timedated_CFLAGS = \ + $(AM_CFLAGS) \ + $(DBUS_CFLAGS) + +systemd_timedated_LDADD = \ + libsystemd-shared.la \ + libsystemd-daemon.la \ + libsystemd-dbus.la + +rootlibexec_PROGRAMS += \ + systemd-timedated + +dist_dbussystemservice_DATA += \ + src/timedate/org.freedesktop.timedate1.service + +dist_dbuspolicy_DATA += \ + src/timedate/org.freedesktop.timedate1.conf + +nodist_systemunit_DATA += \ + units/systemd-timedated.service + +polkitpolicy_files += \ + src/timedate/org.freedesktop.timedate1.policy + +org.freedesktop.timedate1.xml: systemd-timedated + $(AM_V_GEN)$(LIBTOOL) --mode=execute $(OBJCOPY) -O binary -j introspect.timedate1 $< $@.tmp && \ + $(STRINGS) $@.tmp | $(AWK) -f $(srcdir)/introspect.awk | \ + $(DBUS_PREPROCESS) -o $@ - && rm $@.tmp + +dbusinterface_DATA += \ + org.freedesktop.timedate1.xml + +timedated-install-data-hook: + $(MKDIR_P) -m 0755 \ + $(DESTDIR)$(prefix)/lib/systemd/ntp-units.d \ + $(DESTDIR)$(sysconfdir)/systemd/ntp-units.d + ( cd $(DESTDIR)$(systemunitdir) && \ + rm -f dbus-org.freedesktop.timedate1.service && \ + $(LN_S) systemd-timedated.service dbus-org.freedesktop.timedate1.service ) + +INSTALL_DATA_HOOKS += \ + timedated-install-data-hook + +MANPAGES += \ + man/systemd-timedated.service.8 + +MANPAGES_ALIAS += \ + man/systemd-timedated.8 + +man/systemd-timedated.8: man/systemd-timedated.service.8 + +timedatectl_SOURCES = \ + src/timedate/timedatectl.c + +timedatectl_CFLAGS = \ + $(AM_CFLAGS) \ + $(DBUS_CFLAGS) + +timedatectl_LDADD = \ + libsystemd-shared.la \ + libsystemd-dbus.la + +bin_PROGRAMS += \ + timedatectl + +MANPAGES += \ + man/timedatectl.1 + +endif + +polkitpolicy_in_files += \ + src/timedate/org.freedesktop.timedate1.policy.in + +EXTRA_DIST += \ + units/systemd-timedated.service.in + +# ------------------------------------------------------------------------------ +if ENABLE_LOGIND +systemd_logind_SOURCES = \ + src/login/logind.c \ + src/login/logind.h \ + src/login/logind-dbus.c \ + src/login/logind-device.c \ + src/login/logind-device.h \ + src/login/logind-button.c \ + src/login/logind-button.h \ + src/login/logind-action.c \ + src/login/logind-action.h \ + src/login/logind-seat.c \ + src/login/logind-seat.h \ + src/login/logind-session.c \ + src/login/logind-session.h \ + src/login/logind-user.c \ + src/login/logind-user.h \ + src/login/logind-inhibit.c \ + src/login/logind-inhibit.h \ + src/login/logind-session-dbus.c \ + src/login/logind-seat-dbus.c \ + src/login/logind-user-dbus.c \ + src/login/logind-acl.h + +nodist_systemd_logind_SOURCES = \ + src/login/logind-gperf.c + +systemd_logind_CFLAGS = \ + $(AM_CFLAGS) \ + $(DBUS_CFLAGS) + +systemd_logind_LDADD = \ + libsystemd-label.la \ + libsystemd-shared.la \ + libsystemd-audit.la \ + libsystemd-daemon.la \ + libsystemd-dbus.la \ + libudev.la + +if HAVE_ACL +systemd_logind_SOURCES += \ + src/login/logind-acl.c + +systemd_logind_LDADD += \ + libsystemd-acl.la +endif + +systemd_user_sessions_SOURCES = \ + src/login/user-sessions.c + +systemd_user_sessions_LDADD = \ + libsystemd-shared.la + +rootlibexec_PROGRAMS += \ + systemd-logind \ + systemd-user-sessions + +loginctl_SOURCES = \ + src/login/loginctl.c \ + src/login/sysfs-show.c + +loginctl_CFLAGS = \ + $(AM_CFLAGS) \ + $(DBUS_CFLAGS) + +loginctl_LDADD = \ + libsystemd-shared.la \ + libsystemd-dbus.la \ + libudev.la + +rootbin_PROGRAMS += \ + loginctl + +systemd_inhibit_SOURCES = \ + src/login/inhibit.c + +systemd_inhibit_CFLAGS = \ + $(AM_CFLAGS) \ + $(DBUS_CFLAGS) + +systemd_inhibit_LDADD = \ + libsystemd-shared.la \ + libsystemd-dbus.la + +rootbin_PROGRAMS += \ + systemd-inhibit + +test_login_SOURCES = \ + src/login/test-login.c + +test_login_LDADD = \ + libsystemd-login-internal.la \ + libsystemd-shared.la + +test_inhibit_SOURCES = \ + src/login/test-inhibit.c + +test_inhibit_LDADD = \ + libsystemd-shared.la \ + libsystemd-dbus.la + +test_inhibit_CFLAGS = \ + $(AM_CFLAGS) \ + $(DBUS_CFLAGS) + +noinst_PROGRAMS += \ + test-login \ + test-inhibit + +libsystemd_login_la_SOURCES = \ + src/login/sd-login.c + +libsystemd_login_la_CFLAGS = \ + $(AM_CFLAGS) \ + -fvisibility=hidden + +libsystemd_login_la_LDFLAGS = \ + $(AM_LDFLAGS) \ + -shared \ + -version-info $(LIBSYSTEMD_LOGIN_CURRENT):$(LIBSYSTEMD_LOGIN_REVISION):$(LIBSYSTEMD_LOGIN_AGE) \ + -Wl,--version-script=$(top_srcdir)/src/login/libsystemd-login.sym + +libsystemd_login_la_LIBADD = \ + libsystemd-shared.la + +libsystemd_login_internal_la_SOURCES = \ + $(libsystemd_login_la_SOURCES) + +if HAVE_PAM +pam_systemd_la_SOURCES = \ + src/login/pam-module.c + +pam_systemd_la_CFLAGS = \ + $(AM_CFLAGS) \ + $(PAM_CFLAGS) \ + $(DBUS_CFLAGS) \ + -fvisibility=hidden + +pam_systemd_la_LDFLAGS = \ + $(AM_LDFLAGS) \ + -module \ + -export-dynamic \ + -avoid-version \ + -shared \ + -export-symbols-regex '^pam_sm_.*' + +pam_systemd_la_LIBADD = \ + libsystemd-daemon.la \ + libsystemd-audit.la \ + libsystemd-dbus.la \ + libsystemd-shared.la \ + $(PAM_LIBS) + +pamlib_LTLIBRARIES = \ + pam_systemd.la +endif + +# move lib from $(libdir) to $(rootlibdir) and update devel link, if needed +libsystemd-login-install-hook: + libname=libsystemd-login.so && $(move-to-rootlibdir) + +libsystemd-login-uninstall-hook: + rm -f $(DESTDIR)$(rootlibdir)/libsystemd-login.so* + +INSTALL_EXEC_HOOKS += libsystemd-login-install-hook +UNINSTALL_EXEC_HOOKS += libsystemd-login-uninstall-hook + +nodist_systemunit_DATA += \ + units/systemd-logind.service \ + units/systemd-user-sessions.service + +dist_dbussystemservice_DATA += \ + src/login/org.freedesktop.login1.service + +dist_dbuspolicy_DATA += \ + src/login/org.freedesktop.login1.conf + +dist_pkgsysconf_DATA += \ + src/login/logind.conf + +pkginclude_HEADERS += \ + src/systemd/sd-login.h + +lib_LTLIBRARIES += \ + libsystemd-login.la + +noinst_LTLIBRARIES += \ + libsystemd-login-internal.la + +pkgconfiglib_DATA += \ + src/login/libsystemd-login.pc + +polkitpolicy_files += \ + src/login/org.freedesktop.login1.policy + +logind-install-data-hook: + $(MKDIR_P) -m 0755 \ + $(DESTDIR)$(systemunitdir)/multi-user.target.wants \ + $(DESTDIR)$(systemdstatedir) + ( cd $(DESTDIR)$(systemunitdir) && \ + rm -f dbus-org.freedesktop.login1.service && \ + $(LN_S) systemd-logind.service dbus-org.freedesktop.login1.service) + ( cd $(DESTDIR)$(systemunitdir)/multi-user.target.wants && \ + rm -f systemd-logind.service systemd-user-sessions.service && \ + $(LN_S) ../systemd-logind.service systemd-logind.service && \ + $(LN_S) ../systemd-user-sessions.service systemd-user-sessions.service ) + +INSTALL_DATA_HOOKS += \ + logind-install-data-hook + +systemd_multi_seat_x_SOURCES = \ + src/login/multi-seat-x.c + +systemd_multi_seat_x_LDADD = \ + libsystemd-label.la \ + libsystemd-shared.la + +rootlibexec_PROGRAMS += \ + systemd-multi-seat-x + +dist_udevrules_DATA += \ + src/login/70-uaccess.rules \ + src/login/70-power-switch.rules + +nodist_udevrules_DATA += \ + src/login/71-seat.rules \ + src/login/73-seat-late.rules + +MANPAGES += \ + man/systemd-logind.service.8 \ + man/logind.conf.5 \ + man/sd-login.3 \ + man/loginctl.1 \ + man/sd_login_monitor_new.3 \ + man/sd_pid_get_session.3 \ + man/sd_uid_get_state.3 \ + man/sd_session_is_active.3 \ + man/sd_seat_get_active.3 \ + man/sd_get_seats.3 \ + man/systemd-user-sessions.service.8 + +MANPAGES_ALIAS += \ + man/sd_login_monitor_unref.3 \ + man/sd_login_monitor_flush.3 \ + man/sd_login_monitor_get_fd.3 \ + man/sd_login_monitor.3 \ + man/sd_session_get_uid.3 \ + man/sd_session_get_seat.3 \ + man/sd_session_get_service.3 \ + man/sd_session_get_state.3 \ + man/sd_session_get_type.3 \ + man/sd_session_get_class.3 \ + man/sd_session_get_display.3 \ + man/sd_pid_get_owner_uid.3 \ + man/sd_pid_get_unit.3 \ + man/sd_uid_is_on_seat.3 \ + man/sd_uid_get_sessions.3 \ + man/sd_uid_get_seats.3 \ + man/sd_seat_get_sessions.3 \ + man/sd_seat_can_multi_session.3 \ + man/sd_get_sessions.3 \ + man/sd_get_uids.3 \ + man/systemd-logind.8 \ + man/systemd-user-sessions.8 + +man/systemd-logind.8: man/systemd-logind.service.8 +man/sd_login_monitor_unref.3: man/sd_login_monitor_new.3 +man/sd_login_monitor_flush.3: man/sd_login_monitor_new.3 +man/sd_login_monitor_get_fd.3: man/sd_login_monitor_new.3 +man/sd_login_monitor.3: man/sd_login_monitor_new.3 +man/sd_session_get_uid.3: man/sd_session_is_active.3 +man/sd_session_get_seat.3: man/sd_session_is_active.3 +man/sd_session_get_service.3: man/sd_session_is_active.3 +man/sd_session_get_state.3: man/sd_session_is_active.3 +man/sd_session_get_type.3: man/sd_session_is_active.3 +man/sd_session_get_class.3: man/sd_session_is_active.3 +man/sd_session_get_display.3: man/sd_session_is_active.3 +man/sd_pid_get_owner_uid.3: man/sd_pid_get_session.3 +man/sd_pid_get_unit.3: man/sd_pid_get_session.3 +man/sd_uid_is_on_seat.3: man/sd_uid_get_state.3 +man/sd_uid_get_sessions.3: man/sd_uid_get_state.3 +man/sd_uid_get_seats.3: man/sd_uid_get_state.3 +man/sd_seat_get_sessions.3: man/sd_seat_get_active.3 +man/sd_seat_can_multi_session.3: man/sd_seat_get_active.3 +man/sd_get_sessions.3: man/sd_get_seats.3 +man/sd_get_uids.3: man/sd_get_seats.3 +man/systemd-user-sessions.8: man/systemd-user-sessions.service.8 + +CLEANFILES += \ + src/login/logind-gperf.c \ + src/login/71-seat.rules \ + src/login/73-seat-late.rules +endif + +polkitpolicy_in_files += \ + src/login/org.freedesktop.login1.policy.in + +EXTRA_DIST += \ + src/login/logind-gperf.gperf \ + src/login/libsystemd-login.pc.in \ + src/login/libsystemd-login.sym \ + src/login/71-seat.rules.in \ + src/login/73-seat-late.rules.in \ + units/systemd-logind.service.in \ + units/systemd-user-sessions.service.in + +# ------------------------------------------------------------------------------ + +if HAVE_PYTHON_DEVEL + +pkgpyexec_LTLIBRARIES = \ + _journal.la + +_journal_la_SOURCES = \ + src/python-systemd/_journal.c + +_journal_la_CFLAGS = \ + $(AM_CFLAGS) \ + -fvisibility=default \ + $(PYTHON_CFLAGS) + +_journal_la_LDFLAGS = \ + $(AM_LDFLAGS) \ + -shared \ + -module \ + -avoid-version + +_journal_la_LIBADD = \ + $(PYTHON_LIBS) \ + libsystemd-journal.la + +dist_pkgpyexec_PYTHON = \ + src/python-systemd/journal.py \ + src/python-systemd/__init__.py + +endif + +# ------------------------------------------------------------------------------ + +SED_PROCESS = \ + $(AM_V_GEN)$(MKDIR_P) $(dir $@) && \ + $(SED) -e 's,@rootlibexecdir\@,$(rootlibexecdir),g' \ + -e 's,@rootbindir\@,$(rootbindir),g' \ + -e 's,@bindir\@,$(bindir),g' \ + -e 's,@SYSTEMCTL\@,$(rootbindir)/systemctl,g' \ + -e 's,@SYSTEMD_NOTIFY\@,$(rootbindir)/systemd-notify,g' \ + -e 's,@pkgsysconfdir\@,$(pkgsysconfdir),g' \ + -e 's,@pkgdatadir\@,$(pkgdatadir),g' \ + -e 's,@systemunitdir\@,$(systemunitdir),g' \ + -e 's,@userunitdir\@,$(userunitdir),g' \ + -e 's,@systempresetdir\@,$(systempresetdir),g' \ + -e 's,@userpresetdir\@,$(userpresetdir),g' \ + -e 's,@udevhwdbdir\@,$(udevhwdbdir),g' \ + -e 's,@udevrulesdir\@,$(udevrulesdir),g' \ + -e 's,@catalogdir\@,$(catalogdir),g' \ + -e 's,@tmpfilesdir\@,$(tmpfilesdir),g' \ + -e 's,@sysctldir\@,$(sysctldir),g' \ + -e 's,@PACKAGE_VERSION\@,$(PACKAGE_VERSION),g' \ + -e 's,@PACKAGE_NAME\@,$(PACKAGE_NAME),g' \ + -e 's,@PACKAGE_URL\@,$(PACKAGE_URL),g' \ + -e 's,@RANDOM_SEED\@,$(localstatedir)/lib/random-seed,g' \ + -e 's,@prefix\@,$(prefix),g' \ + -e 's,@exec_prefix\@,$(exec_prefix),g' \ + -e 's,@libdir\@,$(libdir),g' \ + -e 's,@includedir\@,$(includedir),g' \ + -e 's,@VERSION\@,$(VERSION),g' \ + -e 's,@rootprefix\@,$(rootprefix),g' \ + -e 's,@udevlibexecdir\@,$(udevlibexecdir),g' \ + -e 's,@sushell\@,$(sushell),g' \ + -e 's,@KILL\@,$(KILL),g' \ + -e 's,@QUOTAON\@,$(QUOTAON),g' \ + -e 's,@QUOTACHECK\@,$(QUOTACHECK),g' \ + -e 's,@SYSTEM_SYSVINIT_PATH\@,$(sysvinitdir),g' \ + -e 's,@VARLOGDIR\@,$(varlogdir),g' \ + -e 's,@RC_LOCAL_SCRIPT_PATH_START\@,$(RC_LOCAL_SCRIPT_PATH_START),g' \ + -e 's,@RC_LOCAL_SCRIPT_PATH_STOP\@,$(RC_LOCAL_SCRIPT_PATH_STOP),g' \ + -e 's,@PYTHON\@,$(PYTHON),g' \ + -e 's,@PYTHON_BINARY\@,$(PYTHON_BINARY),g' \ + < $< > $@ + +units/%: units/%.in Makefile + $(SED_PROCESS) + +man/%: man/%.in Makefile + $(SED_PROCESS) + +sysctl.d/%: sysctl.d/%.in Makefile + $(SED_PROCESS) + +%.pc: %.pc.in Makefile + $(SED_PROCESS) + +src/core/macros.%: src/core/macros.%.in Makefile + $(SED_PROCESS) + +src/%.policy.in: src/%.policy.in.in Makefile + $(SED_PROCESS) + +%.rules: %.rules.in Makefile + $(SED_PROCESS) + +%.sh: %.sh.in Makefile + $(SED_PROCESS) + $(AM_V_GEN)chmod +x $@ + +src/analyze/systemd-analyze: %: %.in Makefile + $(SED_PROCESS) + $(AM_V_GEN)chmod +x $@ + +src/%.c: src/%.gperf + $(AM_V_at)$(MKDIR_P) $(dir $@) + $(AM_V_GEN)$(GPERF) < $< > $@ + +src/%: src/%.m4 + $(AM_V_at)$(MKDIR_P) $(dir $@) + $(AM_V_GEN)$(M4) -P $(M4_DEFINES) < $< > $@ + +M4_PROCESS_SYSTEM = \ + $(AM_V_GEN)$(MKDIR_P) $(dir $@) && \ + $(M4) -P $(M4_DEFINES) -DFOR_SYSTEM=1 < $< > $@ + +M4_PROCESS_USER = \ + $(AM_V_GEN)$(MKDIR_P) $(dir $@) && \ + $(M4) -P $(M4_DEFINES) -DFOR_USER=1 < $< > $@ + +units/%: units/%.m4 Makefile + $(M4_PROCESS_SYSTEM) + +units/user/%: units/%.m4 Makefile + $(M4_PROCESS_USER) + +nodist_polkitpolicy_DATA = \ + $(polkitpolicy_files) \ + $(polkitpolicy_in_in_files:.policy.in.in=.policy) + +EXTRA_DIST += \ + $(polkitpolicy_in_files) \ + $(polkitpolicy_in_in_files) + +CLEANFILES += \ + $(nodist_systemunit_DATA) \ + $(nodist_userunit_DATA) \ + $(nodist_man_MANS) \ + $(pkgconfigdata_DATA) \ + $(pkgconfiglib_DATA) \ + $(nodist_polkitpolicy_DATA) + +if ENABLE_MANPAGES +XSLTPROC_FLAGS = \ + --nonet \ + --stringparam man.output.quietly 1 \ + --stringparam funcsynopsis.style ansi \ + --stringparam man.th.extra1.suppress 1 \ + --stringparam man.authors.section.enabled 0 \ + --stringparam man.copyright.section.enabled 0 + +XSLTPROC_PROCESS_MAN = \ + $(AM_V_GEN)$(MKDIR_P) $(dir $@) && \ + $(XSLTPROC) -o $@ $(XSLTPROC_FLAGS) http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl $< + +XSLTPROC_PROCESS_HTML = \ + $(AM_V_GEN)$(MKDIR_P) $(dir $@) && \ + $(XSLTPROC) -o $@ $(XSLTPROC_FLAGS) $(srcdir)/man/custom-html.xsl $< + +man/%.1: man/%.xml + $(XSLTPROC_PROCESS_MAN) + +man/%.3: man/%.xml + $(XSLTPROC_PROCESS_MAN) + +man/%.5: man/%.xml + $(XSLTPROC_PROCESS_MAN) + +man/%.7: man/%.xml + $(XSLTPROC_PROCESS_MAN) + +man/%.8: man/%.xml + $(XSLTPROC_PROCESS_MAN) + +man/%.html: man/%.xml man/custom-html.xsl + $(XSLTPROC_PROCESS_HTML) + +CLEANFILES += \ + $(dist_man_MANS) \ + ${XML_FILES:.xml=.html} +endif + +DBUS_PREPROCESS = $(CPP) -P $(CFLAGS) $(DBUS_CFLAGS) -imacros dbus/dbus-protocol.h + +CLEANFILES += \ + $(dbusinterface_DATA) + +if HAVE_SYSV_COMPAT +sysvinit_DATA = \ + docs/sysvinit/README + +varlog_DATA = \ + docs/var-log/README + +docs/sysvinit/README: docs/sysvinit/README.in + $(SED_PROCESS) + +docs/var-log/README: docs/var-log/README.in + $(SED_PROCESS) + +EXTRA_DIST += \ + docs/sysvinit/README.in \ + docs/var-log/README.in + +CLEANFILES += \ + docs/sysvinit/README \ + docs/var-log/README + +endif + +EXTRA_DIST += \ + shell-completion/systemd-zsh-completion.zsh + +systemd-install-data-hook: + $(MKDIR_P) -m 0755 \ + $(DESTDIR)$(tmpfilesdir) \ + $(DESTDIR)$(sysconfdir)/tmpfiles.d \ + $(DESTDIR)$(prefix)/lib/modules-load.d \ + $(DESTDIR)$(sysconfdir)/modules-load.d \ + $(DESTDIR)$(prefix)/lib/sysctl.d \ + $(DESTDIR)$(sysconfdir)/sysctl.d \ + $(DESTDIR)$(systemshutdowndir) \ + $(DESTDIR)$(systemsleepdir) \ + $(DESTDIR)$(systemgeneratordir) \ + $(DESTDIR)$(usergeneratordir) + $(MKDIR_P) -m 0755 \ + $(DESTDIR)$(systemunitdir) \ + $(DESTDIR)$(userunitdir) \ + $(DESTDIR)$(systemunitdir)/sysinit.target.wants \ + $(DESTDIR)$(systemunitdir)/sockets.target.wants \ + $(DESTDIR)$(systemunitdir)/basic.target.wants \ + $(DESTDIR)$(systemunitdir)/shutdown.target.wants \ + $(DESTDIR)$(systemunitdir)/local-fs.target.wants \ + $(DESTDIR)$(systemunitdir)/runlevel1.target.wants \ + $(DESTDIR)$(systemunitdir)/runlevel2.target.wants \ + $(DESTDIR)$(systemunitdir)/runlevel3.target.wants \ + $(DESTDIR)$(systemunitdir)/runlevel4.target.wants \ + $(DESTDIR)$(systemunitdir)/runlevel5.target.wants \ + $(DESTDIR)$(systemunitdir)/multi-user.target.wants \ + $(DESTDIR)$(systemunitdir)/graphical.target.wants \ + $(DESTDIR)$(pkgsysconfdir)/system \ + $(DESTDIR)$(pkgsysconfdir)/system/sysinit.target.wants \ + $(DESTDIR)$(pkgsysconfdir)/system/local-fs.target.wants \ + $(DESTDIR)$(pkgsysconfdir)/system/multi-user.target.wants \ + $(DESTDIR)$(pkgsysconfdir)/system/getty.target.wants \ + $(DESTDIR)$(pkgsysconfdir)/user \ + $(DESTDIR)$(dbussessionservicedir) \ + $(DESTDIR)$(sysconfdir)/xdg/systemd + ( cd $(DESTDIR)$(sysconfdir)/xdg/systemd/ && \ + rm -f user && \ + $(LN_S) $(pkgsysconfdir)/user user ) + ( cd $(DESTDIR)$(systemunitdir)/sockets.target.wants && \ + rm -f systemd-initctl.socket systemd-shutdownd.socket && \ + $(LN_S) ../systemd-initctl.socket systemd-initctl.socket && \ + $(LN_S) ../systemd-shutdownd.socket systemd-shutdownd.socket ) + ( cd $(DESTDIR)$(systemunitdir)/runlevel1.target.wants && \ + rm -f systemd-update-utmp-runlevel.service && \ + $(LN_S) ../systemd-update-utmp-runlevel.service systemd-update-utmp-runlevel.service ) + ( cd $(DESTDIR)$(systemunitdir)/runlevel2.target.wants && \ + rm -f systemd-update-utmp-runlevel.service && \ + $(LN_S) ../systemd-update-utmp-runlevel.service systemd-update-utmp-runlevel.service ) + ( cd $(DESTDIR)$(systemunitdir)/runlevel3.target.wants && \ + rm -f systemd-update-utmp-runlevel.service && \ + $(LN_S) ../systemd-update-utmp-runlevel.service systemd-update-utmp-runlevel.service ) + ( cd $(DESTDIR)$(systemunitdir)/runlevel4.target.wants && \ + rm -f systemd-update-utmp-runlevel.service && \ + $(LN_S) ../systemd-update-utmp-runlevel.service systemd-update-utmp-runlevel.service ) + ( cd $(DESTDIR)$(systemunitdir)/runlevel5.target.wants && \ + rm -f systemd-update-utmp-runlevel.service && \ + $(LN_S) ../systemd-update-utmp-runlevel.service systemd-update-utmp-runlevel.service ) + ( cd $(DESTDIR)$(systemunitdir)/shutdown.target.wants && \ + rm -f systemd-update-utmp-shutdown.service && \ + $(LN_S) ../systemd-update-utmp-shutdown.service systemd-update-utmp-shutdown.service ) + ( cd $(DESTDIR)$(systemunitdir)/local-fs.target.wants && \ + rm -f systemd-remount-fs.service \ + systemd-fsck-root.service \ + tmp.mount && \ + $(LN_S) ../systemd-remount-fs.service systemd-remount-fs.service && \ + $(LN_S) ../systemd-fsck-root.service systemd-fsck-root.service && \ + $(LN_S) ../tmp.mount tmp.mount ) + ( cd $(DESTDIR)$(userunitdir) && \ + rm -f shutdown.target sockets.target bluetooth.target printer.target sound.target && \ + $(LN_S) $(systemunitdir)/shutdown.target shutdown.target && \ + $(LN_S) $(systemunitdir)/sockets.target sockets.target && \ + $(LN_S) $(systemunitdir)/bluetooth.target bluetooth.target && \ + $(LN_S) $(systemunitdir)/printer.target printer.target && \ + $(LN_S) $(systemunitdir)/sound.target sound.target ) + ( cd $(DESTDIR)$(systemunitdir) && \ + rm -f runlevel0.target runlevel1.target runlevel2.target runlevel3.target runlevel4.target runlevel5.target runlevel6.target && \ + $(LN_S) poweroff.target runlevel0.target && \ + $(LN_S) rescue.target runlevel1.target && \ + $(LN_S) multi-user.target runlevel2.target && \ + $(LN_S) multi-user.target runlevel3.target && \ + $(LN_S) multi-user.target runlevel4.target && \ + $(LN_S) graphical.target runlevel5.target && \ + $(LN_S) reboot.target runlevel6.target ) + ( cd $(DESTDIR)$(systemunitdir) && \ + rm -f default.target ctrl-alt-del.target autovt@.service && \ + $(LN_S) graphical.target default.target && \ + $(LN_S) reboot.target ctrl-alt-del.target && \ + $(LN_S) getty@.service autovt@.service ) + ( cd $(DESTDIR)$(systemunitdir)/multi-user.target.wants && \ + rm -f getty.target systemd-ask-password-wall.path && \ + $(LN_S) ../getty.target getty.target && \ + $(LN_S) ../systemd-ask-password-wall.path systemd-ask-password-wall.path) + ( cd $(DESTDIR)$(pkgsysconfdir)/system/getty.target.wants && \ + rm -f getty@tty1.service && \ + $(LN_S) $(systemunitdir)/getty@.service getty@tty1.service ) + ( cd $(DESTDIR)$(pkgsysconfdir)/system/multi-user.target.wants && \ + rm -f remote-fs.target && \ + $(LN_S) $(systemunitdir)/remote-fs.target remote-fs.target ) + ( cd $(DESTDIR)$(systemunitdir)/sysinit.target.wants && \ + rm -f dev-hugepages.mount \ + dev-mqueue.mount \ + sys-kernel-config.mount \ + sys-kernel-debug.mount \ + sys-fs-fuse-connections.mount \ + systemd-tmpfiles-setup.service \ + systemd-sysctl.service \ + systemd-ask-password-console.path && \ + $(LN_S) ../dev-hugepages.mount dev-hugepages.mount && \ + $(LN_S) ../dev-mqueue.mount dev-mqueue.mount && \ + $(LN_S) ../sys-kernel-config.mount sys-kernel-config.mount && \ + $(LN_S) ../sys-kernel-debug.mount sys-kernel-debug.mount && \ + $(LN_S) ../sys-fs-fuse-connections.mount sys-fs-fuse-connections.mount && \ + $(LN_S) ../systemd-tmpfiles-setup.service systemd-tmpfiles-setup.service && \ + $(LN_S) ../systemd-sysctl.service systemd-sysctl.service && \ + $(LN_S) ../systemd-ask-password-console.path systemd-ask-password-console.path ) + ( cd $(DESTDIR)$(systemunitdir)/basic.target.wants && \ + rm -f systemd-tmpfiles-clean.timer && \ + $(LN_S) ../systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.timer ) + ( cd $(DESTDIR)$(dbussessionservicedir) && \ + rm -f org.freedesktop.systemd1.service && \ + $(LN_S) ../system-services/org.freedesktop.systemd1.service org.freedesktop.systemd1.service ) + +if HAVE_KMOD + ( cd $(DESTDIR)$(systemunitdir)/sysinit.target.wants && \ + rm -f systemd-modules-load.service && \ + $(LN_S) ../systemd-modules-load.service systemd-modules-load.service ) +endif + +install-exec-hook: $(INSTALL_EXEC_HOOKS) + +uninstall-hook: $(UNINSTALL_DATA_HOOKS) $(UNINSTALL_EXEC_HOOKS) + +install-data-hook: systemd-install-data-hook $(INSTALL_DATA_HOOKS) + +distclean-local: $(DISTCLEAN_LOCAL_HOOKS) + +clean-local: + rm -rf $(abs_srcdir)/install-tree + rm -f $(abs_srcdir)/hwdb/usb.ids $(abs_srcdir)/hwdb/pci.ids $(abs_srcdir)/hwdb/oui.txt \ + $(abs_srcdir)/hwdb/iab.txt + +DISTCHECK_CONFIGURE_FLAGS = \ + --with-dbuspolicydir=$$dc_install_base/$(dbuspolicydir) \ + --with-dbussessionservicedir=$$dc_install_base/$(dbussessionservicedir) \ + --with-dbussystemservicedir=$$dc_install_base/$(dbussystemservicedir) \ + --with-dbusinterfacedir=$$dc_install_base/$(dbusinterfacedir) \ + --with-pamlibdir=$$dc_install_base/$(pamlibdir) \ + --with-rootprefix=$$dc_install_base \ + --disable-split-usr + + +if HAVE_SYSV_COMPAT +DISTCHECK_CONFIGURE_FLAGS += \ + --with-sysvinit-path=$$dc_install_base/$(sysvinitdir) \ + --with-sysvrcnd-path=$$dc_install_base/$(sysvrcddir) +endif + +if ENABLE_GTK_DOC +DISTCHECK_CONFIGURE_FLAGS += \ + --enable-gtk-doc +endif + +hwdb-update: + ( cd $(top_srcdir)/hwdb && \ + wget -N http://www.linux-usb.org/usb.ids \ + http://pci-ids.ucw.cz/v2.2/pci.ids \ + http://standards.ieee.org/develop/regauth/oui/oui.txt \ + http://standards.ieee.org/develop/regauth/iab/iab.txt && \ + ./ids-update.pl ) + +upload: all distcheck + cp -v systemd-$(VERSION).tar.xz /home/lennart/git.fedora/systemd/ + scp systemd-$(VERSION).tar.xz fdo:/srv/www.freedesktop.org/www/software/systemd/ + scp man/*.html tango:public/systemd-man/ + +doc-sync: all + gtkdoc-rebase --html-dir=docs/libudev/html --online + rsync -av --delete docs/libudev/html/ --omit-dir-times www.freedesktop.org:/srv/www.freedesktop.org/www/software/systemd/libudev/ + gtkdoc-rebase --html-dir=docs/gudev/html --online + rsync -av --delete docs/gudev/html/ --omit-dir-times www.freedesktop.org:/srv/www.freedesktop.org/www/software/systemd/gudev/ + rsync -av --delete-excluded --include="*.html" --exclude="*" --omit-dir-times man/ www.freedesktop.org:/srv/www.freedesktop.org/www/software/systemd/man/ + +git-tag: + git tag "v$(VERSION)" -m "systemd $(VERSION)" + +install-tree: all + rm -rf $(abs_srcdir)/install-tree + make install DESTDIR=$(abs_srcdir)/install-tree + tree $(abs_srcdir)/install-tree diff --git a/NEWS b/NEWS new file mode 100644 index 000000000..ca6245bba --- /dev/null +++ b/NEWS @@ -0,0 +1,1264 @@ +systemd System and Service Manager + +CHANGES WITH 196: + + * udev gained support for loading additional device properties + from an indexed database that is keyed by vendor/product IDs + and similar device identifiers. For the beginning this + "hwdb" is populated with data from the well-known PCI and + USB database, but also includes PNP, ACPI and OID data. In + the longer run this indexed database shall grow into + becoming the one central database for non-essential + userspace device metadata. Previously, data from the PCI/USB + database was only attached to select devices, since the + lookup was a relatively expensive operation due to O(n) time + complexity (with n being the number of entries in the + database). Since this is now O(1), we decided to add in this + data for all devices where this is available, by + default. Note that the indexed database needs to be rebuilt + when new data files are installed. To achieve this you need + to update your packaging scripts to invoke "udevadm hwdb + --update" after installation of hwdb data files. For + RPM-based distributions we introduced the new + %udev_hwdb_update macro for this purpose. + + * The Journal gained support for the "Message Catalog", an + indexed database to link up additional information with + journal entries. For further details please check: + + http://www.freedesktop.org/wiki/Software/systemd/catalog + + The indexed message catalog database also needs to be + rebuilt after installation of message catalog files. Use + "journalctl --update-catalog" for this. For RPM-based + distributions we introduced the %journal_catalog_update + macro for this purpose. + + * The Python Journal bindings gained support for the standard + Python logging framework. + + * The Journal API gained new functions for checking whether + the underlying file system of a journal file is capable of + properly reporting file change notifications, or whether + applications that want to reflect journal changes "live" + need to recheck journal files continously in appropriate + time intervals. + + * It is now possible to set the "age" field for tmpfiles + entries to 0, indicating that files matching this entry + shall always be removed when the directories are cleaned up. + + * coredumpctl gained a new "gdb" verb which invokes gdb + right-away on the selected coredump. + + * There's now support for "hybrid sleep" on kernels that + support this, in addition to "suspend" and "hibernate". Use + "systemctl hybrid-sleep" to make use of this. + + * logind's HandleSuspendKey= setting (and related settings) + now gained support for a new "lock" setting to simply + request the screen lock on all local sessions, instead of + actually executing a suspend or hibernation. + + * systemd will now mount the EFI variables file system by + default. + + * Socket units now gained support for configuration of the + SMACK security label. + + * timedatectl will now output the time of the last and next + daylight saving change. + + * We dropped support for various legacy and distro-specific + concepts, such as insserv, early-boot SysV services + (i.e. those for non-standard runlevels such as 'b' or 'S') + or ArchLinux /etc/rc.conf support. We recommend the + distributions who still need support this to either continue + to maintain the necessary patches downstream, or find a + different solution. (Talk to us if you have questions!) + + * Various systemd components will now bypass PolicyKit checks + for root and otherwise handle properly if PolicyKit is not + found to be around. This should fix most issues for + PolicyKit-less systems. Quite frankly this should have been + this way since day one. It is absolutely our intention to + make systemd work fine on PolicyKit-less systems, and we + consider it a bug if something doesn't work as it should if + PolicyKit is not around. + + * For embedded systems it is now possible to build udev and + systemd without blkid and/or kmod support. + + * "systemctl switch-root" is now capable of switching root + more than once. I.e. in addition to transitions from the + initrd to the host OS it is now possible to transition to + further OS images from the host. This is useful to implement + offline updating tools. + + * Various other additions have been made to the RPM macros + shipped with systemd. Use %udev_rules_update() after + installing new udev rules files. %_udevhwdbdir, + %_udevrulesdir, %_journalcatalogdir, %_tmpfilesdir, + %_sysctldir are now available which resolve to the right + directories for packages to place various data files in. + + * journalctl gained the new --full switch (in addition to + --all, to disable ellipsation for long messages. + + Contributions from: Anders Olofsson, Auke Kok, Ben Boeckel, + Colin Walters, Cosimo Cecchi, Daniel Wallace, Dave Reisner, + Eelco Dolstra, Holger Hans Peter Freyther, Kay Sievers, + Chun-Yi Lee, Lekensteyn, Lennart Poettering, Mantas Mikulėnas, + Marti Raudsepp, Martin Pitt, Mauro Dreissig, Michael Biebl, + Michal Schmidt, Michal Sekletar, Miklos Vajna, Nis Martensen, + Oleksii Shevchuk, Olivier Brunel, Ramkumar Ramachandra, Thomas + Bächler, Thomas Hindoe Paaboel Andersen, Tom Gundersen, Tony + Camuso, Umut Tezduyar, Zbigniew Jędrzejewski-Szmek + +CHANGES WITH 195: + + * journalctl gained new --since= and --until= switches to + filter by time. It also now supports nice filtering for + units via --unit=/-u. + + * Type=oneshot services may use ExecReload= and do the + right thing. + + * The journal daemon now supports time-based rotation and + vacuuming, in addition to the usual disk-space based + rotation. + + * The journal will now index the available field values for + each field name. This enables clients to show pretty drop + downs of available match values when filtering. The bash + completion of journalctl has been updated + accordingly. journalctl gained a new switch -F to list all + values a certain field takes in the journal database. + + * More service events are now written as structured messages + to the journal, and made recognizable via message IDs. + + * The timedated, localed and hostnamed mini-services which + previously only provided support for changing time, locale + and hostname settings from graphical DEs such as GNOME now + also have a minimal (but very useful) text-based client + utility each. This is probably the nicest way to changing + these settings from the command line now, especially since + it lists available options and is fully integrated with bash + completion. + + * There's now a new tool "systemd-coredumpctl" to list and + extract coredumps from the journal. + + * We now install a README each in /var/log/ and + /etc/rc.d/init.d explaining where the system logs and init + scripts went. This hopefully should help folks who go to + that dirs and look into the otherwise now empty void and + scratch their heads. + + * When user-services are invoked (by systemd --user) the + $MANAGERPID env var is set to the PID of systemd. + + * SIGRTMIN+24 when sent to a --user instance will now result + in immediate termination of systemd. + + * gatewayd received numerous feature additions such as a + "follow" mode, for live syncing and filtering. + + * browse.html now allows filtering and showing detailed + information on specific entries. Keyboard navigation and + mouse screen support has been added. + + * gatewayd/journalctl now supports HTML5/JSON + Server-Sent-Events as output. + + * The SysV init script compatibility logic will now + heuristically determine whether a script supports the + "reload" verb, and only then make this available as + "systemctl reload". + + * "systemctl status --follow" has been removed, use "journalctl + -u" instead. + + * journald.conf's RuntimeMinSize=, PersistentMinSize= settings + have been removed since they are hardly useful to be + configured. + + * And I'd like to take the opportunity to specifically mention + Zbigniew for his great contributions. Zbigniew, you rock! + + Contributions from: Andrew Eikum, Christian Hesse, Colin + Guthrie, Daniel J Walsh, Dave Reisner, Eelco Dolstra, Ferenc + Wágner, Kay Sievers, Lennart Poettering, Lukas Nykryn, Mantas + Mikulėnas, Martin Mikkelsen, Martin Pitt, Michael Olbrich, + Michael Stapelberg, Michal Schmidt, Sebastian Ott, Thomas + Bächler, Umut Tezduyar, Will Woods, Wulf C. Krueger, Zbigniew + Jędrzejewski-Szmek, Сковорода Никита Андреевич + +CHANGES WITH 194: + + * If /etc/vconsole.conf is non-existent or empty we will no + longer load any console font or key map at boot by + default. Instead the kernel defaults will be left + intact. This is definitely the right thing to do, as no + configuration should mean no configuration, and hard-coding + font names that are different on all archs is probably a bad + idea. Also, the kernel default key map and font should be + good enough for most cases anyway, and mostly identical to + the userspace fonts/key maps we previously overloaded them + with. If distributions want to continue to default to a + non-kernel font or key map they should ship a default + /etc/vconsole.conf with the appropriate contents. + + Contributions from: Colin Walters, Daniel J Walsh, Dave + Reisner, Kay Sievers, Lennart Poettering, Lukas Nykryn, Tollef + Fog Heen, Tom Gundersen, Zbigniew Jędrzejewski-Szmek + +CHANGES WITH 193: + + * journalctl gained a new --cursor= switch to show entries + starting from the specified location in the journal. + + * We now enforce a size limit on journal entry fields exported + with "-o json" in journalctl. Fields larger than 4K will be + assigned null. This can be turned off with --all. + + * An (optional) journal gateway daemon is now available as + "systemd-journal-gatewayd.service". This service provides + access to the journal via HTTP and JSON. This functionality + will be used to implement live log synchronization in both + pull and push modes, but has various other users too, such + as easy log access for debugging of embedded devices. Right + now it is already useful to retrieve the journal via HTTP: + + # systemctl start systemd-journal-gatewayd.service + # wget http://localhost:19531/entries + + This will download the journal contents in a + /var/log/messages compatible format. The same as JSON: + + # curl -H"Accept: application/json" http://localhost:19531/entries + + This service is also accessible via a web browser where a + single static HTML5 app is served that uses the JSON logic + to enable the user to do some basic browsing of the + journal. This will be extended later on. Here's an example + screenshot of this app in its current state: + + http://0pointer.de/public/journal-gatewayd + + Contributions from: Kay Sievers, Lennart Poettering, Robert + Milasan, Tom Gundersen + +CHANGES WITH 192: + + * The bash completion logic is now available for journalctl + too. + + * We don't mount the "cpuset" controller anymore together with + "cpu" and "cpuacct", as "cpuset" groups generally cannot be + started if no parameters are assigned to it. "cpuset" hence + broke code that assumed it it could create "cpu" groups and + just start them. + + * journalctl -f will now subscribe to terminal size changes, + and line break accordingly. + + Contributions from: Dave Reisner, Kay Sievers, Lennart + Poettering, Lukas Nykrynm, Mirco Tischler, Václav Pavlín + +CHANGES WITH 191: + + * nspawn will now create a symlink /etc/localtime in the + container environment, copying the host's timezone + setting. Previously this has been done via a bind mount, but + since symlinks cannot be bind mounted this has now been + changed to create/update the appropriate symlink. + + * journalctl -n's line number argument is now optional, and + will default to 10 if omitted. + + * journald will now log the maximum size the journal files may + take up on disk. This is particularly useful if the default + built-in logic of determining this parameter from the file + system size is used. Use "systemctl status + systemd-journald.service" to see this information. + + * The multi-seat X wrapper tool has been stripped down. As X + is now capable of enumerating graphics devices via udev in a + seat-aware way the wrapper is not strictly necessary + anymore. A stripped down temporary stop-gap is still shipped + until the upstream display managers have been updated to + fully support the new X logic. Expect this wrapper to be + removed entirely in one of the next releases. + + * HandleSleepKey= in logind.conf has been split up into + HandleSuspendKey= and HandleHibernateKey=. The old setting + is not available anymore. X11 and the kernel are + distuingishing between these keys and we should too. This + also means the inhibition lock for these keys has been split + into two. + + Contributions from: Dave Airlie, Eelco Dolstra, Lennart + Poettering, Lukas Nykryn, Václav Pavlín + +CHANGES WITH 190: + + * Whenever a unit changes state we'll now log this to the + journal and show along the unit's own log output in + "systemctl status". + + * ConditionPathIsMountPoint= can now properly detect bind + mount points too. (Previously, a bind mount of one file + system to another place in the same file system could not be + detected as mount, since they shared struct stat's st_dev + field.) + + * We will now mount the cgroup controllers cpu, cpuacct, + cpuset and the controllers net_cls, net_prio together by + default. + + * nspawn containers will now have a virtualized boot + ID. (i.e. /proc/sys/kernel/random/boot_id is now mounted + over with a randomized ID at container initialization). This + has the effect of making "journalctl -b" do the right thing + in a container. + + * The JSON output journal serialization has been updated not + to generate "endless" list objects anymore, but rather one + JSON object per line. This is more in line how most JSON + parsers expect JSON objects. The new output mode + "json-pretty" has been added to provide similar output, but + neatly aligned for readability by humans. + + * We dropped all explicit sync() invocations in the shutdown + code. The kernel does this implicitly anyway in the kernel + reboot() syscall. halt(8)'s -n option is now a compatibility + no-op. + + * We now support virtualized reboot() in containers, as + supported by newer kernels. We will fall back to exit() if + CAP_SYS_REBOOT is not available to the container. Also, + nspawn makes use of this now and will actually reboot the + container if the containerized OS asks for that. + + * journalctl will only show local log output by default + now. Use --merge (-m) to show remote log output, too. + + * libsystemd-journal gained the new sd_journal_get_usage() + call to determine the current disk usage of all journal + files. This is exposed in the new "journalctl --disk-usage" + command. + + * journald gained a new configuration setting SplitMode= in + journald.conf which may be used to control how user journals + are split off. See journald.conf(5) for details. + + * A new condition type ConditionFileNotEmpty= has been added. + + * tmpfiles' "w" lines now support file globbing, to write + multiple files at once. + + * We added Python bindings for the journal submission + APIs. More Python APIs for a number of selected APIs will + likely follow. Note that we intend to add native bindings + only for the Python language, as we consider it common + enough to deserve bindings shipped within systemd. There are + various projects outside of systemd that provide bindings + for languages such as PHP or Lua. + + * Many conditions will now resolve specifiers such as %i. In + addition, PathChanged= and related directives of .path units + now support specifiers as well. + + * There's now a new RPM macro definition for the system preset + dir: %_presetdir. + + * journald will now warn if it can't foward a message to the + syslog daemon because it's socket is full. + + * timedated will no longer write or process /etc/timezone, + except on Debian. As we do not support late mounted /usr + anymore /etc/localtime always being a symlink is now safe, + and hence the information in /etc/timezone is not necessary + anymore. + + * logind will now always reserve one VT for a text getty (VT6 + by default). Previously if more than 6 X sessions where + started they took up all the VTs with auto-spawned gettys, + so that no text gettys were available anymore. + + * udev will now automatically inform the btrfs kernel logic + about btrfs RAID components showing up. This should make + simple hotplug based btrfs RAID assembly work. + + * PID 1 will now increase its RLIMIT_NOFILE to 64K by default + (but not for its children which will stay at the kernel + default). This should allow setups with a lot more listening + sockets. + + * systemd will now always pass the configured timezone to the + kernel at boot. timedated will do the same when the timezone + is changed. + + * logind's inhibition logic has been updated. By default, + logind will now handle the lid switch, the power and sleep + keys all the time, even in graphical sessions. If DEs want + to handle these events on their own they should take the new + handle-power-key, handle-sleep-key and handle-lid-switch + inhibitors during their runtime. A simple way to achiveve + that is to invoke the DE wrapped in an invocation of: + + systemd-inhibit --what=handle-power-key:handle-sleep-key:handle-lid-switch ... + + * Access to unit operations is now checked via SELinux taking + the unit file label and client process label into account. + + * systemd will now notify the administrator in the journal + when he over-mounts a non-empty directory. + + * There are new specifiers that are resolved in unit files, + for the host name (%H), the machine ID (%m) and the boot ID + (%b). + + Contributions from: Allin Cottrell, Auke Kok, Brandon Philips, + Colin Guthrie, Colin Walters, Daniel J Walsh, Dave Reisner, + Eelco Dolstra, Jan Engelhardt, Kay Sievers, Lennart + Poettering, Lucas De Marchi, Lukas Nykryn, Mantas Mikulėnas, + Martin Pitt, Matthias Clasen, Michael Olbrich, Pierre Schmitz, + Shawn Landden, Thomas Hindoe Paaboel Andersen, Tom Gundersen, + Václav Pavlín, Yin Kangkai, Zbigniew Jędrzejewski-Szmek + +CHANGES WITH 189: + + * Support for reading structured kernel messages from + /dev/kmsg has now been added and is enabled by default. + + * Support for reading kernel messages from /proc/kmsg has now + been removed. If you want kernel messages in the journal + make sure to run a recent kernel (>= 3.5) that supports + reading structured messages from /dev/kmsg (see + above). /proc/kmsg is now exclusive property of classic + syslog daemons again. + + * The libudev API gained the new + udev_device_new_from_device_id() call. + + * The logic for file system namespace (ReadOnlyDirectory=, + ReadWriteDirectoy=, PrivateTmp=) has been reworked not to + require pivot_root() anymore. This means fewer temporary + directories are created below /tmp for this feature. + + * nspawn containers will now see and receive all submounts + made on the host OS below the root file system of the + container. + + * Forward Secure Sealing is now supported for Journal files, + which provide cryptographical sealing of journal files so + that attackers cannot alter log history anymore without this + being detectable. Lennart will soon post a blog story about + this explaining it in more detail. + + * There are two new service settings RestartPreventExitStatus= + and SuccessExitStatus= which allow configuration of exit + status (exit code or signal) which will be excepted from the + restart logic, resp. consider successful. + + * journalctl gained the new --verify switch that can be used + to check the integrity of the structure of journal files and + (if Forward Secure Sealing is enabled) the contents of + journal files. + + * nspawn containers will now be run with /dev/stdin, /dev/fd/ + and similar symlinks pre-created. This makes running shells + as container init process a lot more fun. + + * The fstab support can now handle PARTUUID= and PARTLABEL= + entries. + + * A new ConditionHost= condition has been added to match + against the hostname (with globs) and machine ID. This is + useful for clusters where a single OS image is used to + provision a large number of hosts which shall run slightly + different sets of services. + + * Services which hit the restart limit will now be placed in a + failure state. + + Contributions from: Bertram Poettering, Dave Reisner, Huang + Hang, Kay Sievers, Lennart Poettering, Lukas Nykryn, Martin + Pitt, Simon Peeters, Zbigniew Jędrzejewski-Szmek + +CHANGES WITH 188: + + * When running in --user mode systemd will now become a + subreaper (PR_SET_CHILD_SUBREAPER). This should make the ps + tree a lot more organized. + + * A new PartOf= unit dependency type has been introduced that + may be used to group services in a natural way. + + * "systemctl enable" may now be used to enable instances of + services. + + * journalctl now prints error log levels in red, and + warning/notice log levels in bright white. It also supports + filtering by log level now. + + * cgtop gained a new -n switch (similar to top), to configure + the maximum number of iterations to run for. It also gained + -b, to run in batch mode (accepting no input). + + * The suffix ".service" may now be ommited on most systemctl + command lines involving service unit names. + + * There's a new bus call in logind to lock all sessions, as + well as a loginctl verb for it "lock-sessions". + + * libsystemd-logind.so gained a new call sd_journal_perror() + that works similar to libc perror() but logs to the journal + and encodes structured information about the error number. + + * /etc/crypttab entries now understand the new keyfile-size= + option. + + * shutdown(8) now can send a (configurable) wall message when + a shutdown is cancelled. + + * The mount propagation mode for the root file system will now + default to "shared", which is useful to make containers work + nicely out-of-the-box so that they receive new mounts from + the host. This can be undone locally by running "mount + --make-rprivate /" if needed. + + * The prefdm.service file has been removed. Distributions + should maintain this unit downstream if they intend to keep + it around. However, we recommend writing normal unit files + for display managers instead. + + * Since systemd is a crucial part of the OS we will now + default to a number of compiler switches that improve + security (hardening) such as read-only relocations, stack + protection, and suchlike. + + * The TimeoutSec= setting for services is now split into + TimeoutStartSec= and TimeoutStopSec= to allow configuration + of individual time outs for the start and the stop phase of + the service. + + Contributions from: Artur Zaprzala, Arvydas Sidorenko, Auke + Kok, Bryan Kadzban, Dave Reisner, David Strauss, Harald Hoyer, + Jim Meyering, Kay Sievers, Lennart Poettering, Mantas + Mikulėnas, Martin Pitt, Michal Schmidt, Michal Sekletar, Peter + Alfredsen, Shawn Landden, Simon Peeters, Terence Honles, Tom + Gundersen, Zbigniew Jędrzejewski-Szmek + +CHANGES WITH 187: + + * The journal and id128 C APIs are now fully documented as man + pages. + + * Extra safety checks have been added when transitioning from + the initial RAM disk to the main system to avoid accidental + data loss. + + * /etc/crypttab entries now understand the new keyfile-offset= + option. + + * systemctl -t can now be used to filter by unit load state. + + * The journal C API gained the new sd_journal_wait() call to + make writing synchronous journal clients easier. + + * journalctl gained the new -D switch to show journals from a + specific directory. + + * journalctl now displays a special marker between log + messages of two different boots. + + * The journal is now explicitly flushed to /var via a service + systemd-journal-flush.service, rather than implicitly simply + by seeing /var/log/journal to be writable. + + * journalctl (and the journal C APIs) can now match for much + more complex expressions, with alternatives and + disjunctions. + + * When transitioning from the initial RAM disk to the main + system we will now kill all processes in a killing spree to + ensure no processes stay around by accident. + + * Three new specifiers may be used in unit files: %u, %h, %s + resolve to the user name, user home directory resp. user + shell. This is useful for running systemd user instances. + + * We now automatically rotate journal files if their data + object hash table gets a fill level > 75%. We also size the + hash table based on the configured maximum file size. This + together should lower hash collisions drastically and thus + speed things up a bit. + + * journalctl gained the new "--header" switch to introspect + header data of journal files. + + * A new setting SystemCallFilters= has been added to services + which may be used to apply blacklists or whitelists to + system calls. This is based on SECCOMP Mode 2 of Linux 3.5. + + * nspawn gained a new --link-journal= switch (and quicker: -j) + to link the container journal with the host. This makes it + very easy to centralize log viewing on the host for all + guests while still keeping the journal files separated. + + * Many bugfixes and optimizations + + Contributions from: Auke Kok, Eelco Dolstra, Harald Hoyer, Kay + Sievers, Lennart Poettering, Malte Starostik, Paul Menzel, Rex + Tsai, Shawn Landden, Tom Gundersen, Ville Skyttä, Zbigniew + Jędrzejewski-Szmek + +CHANGES WITH 186: + + * Several tools now understand kernel command line arguments, + which are only read when run in an initial RAM disk. They + usually follow closely their normal counterparts, but are + prefixed with rd. + + * There's a new tool to analyze the readahead files that are + automatically generated at boot. Use: + + /usr/lib/systemd/systemd-readahead analyze /.readahead + + * We now provide an early debug shell on tty9 if this enabled. Use: + + systemctl enable debug-shell.service + + * All plymouth related units have been moved into the Plymouth + package. Please make sure to upgrade your Plymouth version + as well. + + * systemd-tmpfiles now supports getting passed the basename of + a configuration file only, in which case it will look for it + in all appropriate directories automatically. + + * udevadm info now takes a /dev or /sys path as argument, and + does the right thing. Example: + + udevadm info /dev/sda + udevadm info /sys/class/block/sda + + * systemctl now prints a warning if a unit is stopped but a + unit that might trigger it continues to run. Example: a + service is stopped but the socket that activates it is left + running. + + * "systemctl status" will now mention if the log output was + shortened due to rotation since a service has been started. + + * The journal API now exposes functions to determine the + "cutoff" times due to rotation. + + * journald now understands SIGUSR1 and SIGUSR2 for triggering + immediately flushing of runtime logs to /var if possible, + resp. for triggering immediate rotation of the journal + files. + + * It is now considered an error if a service is attempted to + be stopped that is not loaded. + + * XDG_RUNTIME_DIR now uses numeric UIDs instead of usernames. + + * systemd-analyze now supports Python 3 + + * tmpfiles now supports cleaning up directories via aging + where the first level dirs are always kept around but + directories beneath it automatically aged. This is enabled + by prefixing the age field with '~'. + + * Seat objects now expose CanGraphical, CanTTY properties + which is required to deal with very fast bootups where the + display manager might be running before the graphics drivers + completed initialization. + + * Seat objects now expose a State property. + + * We now include RPM macros for service enabling/disabling + based on the preset logic. We recommend RPM based + distributions to make use of these macros if possible. This + makes it simpler to reuse RPM spec files across + distributions. + + * We now make sure that the collected systemd unit name is + always valid when services log to the journal via + STDOUT/STDERR. + + * There's a new man page kernel-command-line(7) detailing all + command line options we understand. + + * The fstab generator may now be disabled at boot by passing + fstab=0 on the kernel command line. + + * A new kernel command line option modules-load= is now understood + to load a specific kernel module statically, early at boot. + + * Unit names specified on the systemctl command line are now + automatically escaped as needed. Also, if file system or + device paths are specified they are automatically turned + into the appropriate mount or device unit names. Example: + + systemctl status /home + systemctl status /dev/sda + + * The SysVConsole= configuration option has been removed from + system.conf parsing. + + * The SysV search path is no longer exported on the D-Bus + Manager object. + + * The Names= option is been removed from unit file parsing. + + * There's a new man page bootup(7) detailing the boot process. + + * Every unit and every generator we ship with systemd now + comes with full documentation. The self-explanatory boot is + complete. + + * A couple of services gained "systemd-" prefixes in their + name if they wrap systemd code, rather than only external + code. Among them fsck@.service which is now + systemd-fsck@.service. + + * The HaveWatchdog property has been removed from the D-Bus + Manager object. + + * systemd.confirm_spawn= on the kernel command line should now + work sensibly. + + * There's a new man page crypttab(5) which details all options + we actually understand. + + * systemd-nspawn gained a new --capability= switch to pass + additional capabilities to the container. + + * timedated will now read known NTP implementation unit names + from /usr/lib/systemd/ntp-units.d/*.list, + systemd-timedated-ntp.target has been removed. + + * journalctl gained a new switch "-b" that lists log data of + the current boot only. + + * The notify socket is in the abstract namespace again, in + order to support daemons which chroot() at start-up. + + * There is a new Storage= configuration option for journald + which allows configuration of where log data should go. This + also provides a way to disable journal logging entirely, so + that data collected is only forwarded to the console, the + kernel log buffer or another syslog implementation. + + * Many bugfixes and optimizations + + Contributions from: Auke Kok, Colin Guthrie, Dave Reisner, + David Strauss, Eelco Dolstra, Kay Sievers, Lennart Poettering, + Lukas Nykryn, Michal Schmidt, Michal Sekletar, Paul Menzel, + Shawn Landden, Tom Gundersen + +CHANGES WITH 185: + + * "systemctl help " now shows the man page if one is + available. + + * Several new man pages have been added. + + * MaxLevelStore=, MaxLevelSyslog=, MaxLevelKMsg=, + MaxLevelConsole= can now be specified in + journald.conf. These options allow reducing the amount of + data stored on disk or forwarded by the log level. + + * TimerSlackNSec= can now be specified in system.conf for + PID1. This allows system-wide power savings. + + Contributions from: Dave Reisner, Kay Sievers, Lauri Kasanen, + Lennart Poettering, Malte Starostik, Marc-Antoine Perennou, + Matthias Clasen + +CHANGES WITH 184: + + * logind is now capable of (optionally) handling power and + sleep keys as well as the lid switch. + + * journalctl now understands the syntax "journalctl + /usr/bin/avahi-daemon" to get all log output of a specific + daemon. + + * CapabilityBoundingSet= in system.conf now also influences + the capability bound set of usermode helpers of the kernel. + + Contributions from: Daniel Drake, Daniel J. Walsh, Gert + Michael Kulyk, Harald Hoyer, Jean Delvare, Kay Sievers, + Lennart Poettering, Matthew Garrett, Matthias Clasen, Paul + Menzel, Shawn Landden, Tero Roponen, Tom Gundersen + +CHANGES WITH 183: + + * Note that we skipped 139 releases here in order to set the + new version to something that is greater than both udev's + and systemd's most recent version number. + + * udev: all udev sources are merged into the systemd source tree now. + All future udev development will happen in the systemd tree. It + is still fully supported to use the udev daemon and tools without + systemd running, like in initramfs or other init systems. Building + udev though, will require the *build* of the systemd tree, but + udev can be properly *run* without systemd. + + * udev: /lib/udev/devices/ are not read anymore; systemd-tmpfiles + should be used to create dead device nodes as workarounds for broken + subsystems. + + * udev: RUN+="socket:..." and udev_monitor_new_from_socket() is + no longer supported. udev_monitor_new_from_netlink() needs to be + used to subscribe to events. + + * udev: when udevd is started by systemd, processes which are left + behind by forking them off of udev rules, are unconditionally cleaned + up and killed now after the event handling has finished. Services or + daemons must be started as systemd services. Services can be + pulled-in by udev to get started, but they can no longer be directly + forked by udev rules. + + * udev: the daemon binary is called systemd-udevd now and installed + in /usr/lib/systemd/. Standalone builds or non-systemd systems need + to adapt to that, create symlink, or rename the binary after building + it. + + * libudev no longer provides these symbols: + udev_monitor_from_socket() + udev_queue_get_failed_list_entry() + udev_get_{dev,sys,run}_path() + The versions number was bumped and symbol versioning introduced. + + * systemd-loginctl and systemd-journalctl have been renamed + to loginctl and journalctl to match systemctl. + + * The config files: /etc/systemd/systemd-logind.conf and + /etc/systemd/systemd-journald.conf have been renamed to + logind.conf and journald.conf. Package updates should rename + the files to the new names on upgrade. + + * For almost all files the license is now LGPL2.1+, changed + from the previous GPL2.0+. Exceptions are some minor stuff + of udev (which will be changed to LGPL2.1 eventually, too), + and the MIT licensed sd-daemon.[ch] library that is suitable + to be used as drop-in files. + + * systemd and logind now handle system sleep states, in + particular suspending and hibernating. + + * logind now implements a sleep/shutdown/idle inhibiting logic + suitable for a variety of uses. Soonishly Lennart will blog + about this in more detail. + + * var-run.mount and var-lock.mount are no longer provided + (which prevously bind mounted these directories to their new + places). Distributions which have not converted these + directories to symlinks should consider stealing these files + from git history and add them downstream. + + * We introduced the Documentation= field for units and added + this to all our shipped units. This is useful to make it + easier to explore the boot and the purpose of the various + units. + + * All smaller setup units (such as + systemd-vconsole-setup.service) now detect properly if they + are run in a container and are skipped when + appropriate. This guarantees an entirely noise-free boot in + Linux container environments such as systemd-nspawn. + + * A framework for implementing offline system updates is now + integrated, for details see: + http://freedesktop.org/wiki/Software/systemd/SystemUpdates + + * A new service type Type=idle is available now which helps us + avoiding ugly interleaving of getty output and boot status + messages. + + * There's now a system-wide CapabilityBoundingSet= option to + globally reduce the set of capabilities for the + system. This is useful to drop CAP_SYS_MKNOD, CAP_SYS_RAWIO, + CAP_NET_RAW, CAP_SYS_MODULE, CAP_SYS_TIME, CAP_SYS_PTRACE or + even CAP_NET_ADMIN system-wide for secure systems. + + * There are now system-wide DefaultLimitXXX= options to + globally change the defaults of the various resource limits + for all units started by PID 1. + + * Harald Hoyer's systemd test suite has been integrated into + systemd which allows easy testing of systemd builds in qemu + and nspawn. (This is really awesome! Ask us for details!) + + * The fstab parser is now implemented as generator, not inside + of PID 1 anymore. + + * systemctl will now warn you if .mount units generated from + /etc/fstab are out of date due to changes in fstab that + haven't been read by systemd yet. + + * systemd is now suitable for usage in initrds. Dracut has + already been updated to make use of this. With this in place + initrds get a slight bit faster but primarily are much + easier to introspect and debug since "systemctl status" in + the host system can be used to introspect initrd services, + and the journal from the initrd is kept around too. + + * systemd-delta has been added, a tool to explore differences + between user/admin configuration and vendor defaults. + + * PrivateTmp= now affects both /tmp and /var/tmp. + + * Boot time status messages are now much prettier and feature + proper english language. Booting up systemd has never been + so sexy. + + * Read-ahead pack files now include the inode number of all + files to pre-cache. When the inode changes the pre-caching + is not attempted. This should be nicer to deal with updated + packages which might result in changes of read-ahead + patterns. + + * We now temporaritly lower the kernel's read_ahead_kb variable + when collecting read-ahead data to ensure the kernel's + built-in read-ahead does not add noise to our measurements + of necessary blocks to pre-cache. + + * There's now RequiresMountsFor= to add automatic dependencies + for all mounts necessary for a specific file system path. + + * MountAuto= and SwapAuto= have been removed from + system.conf. Mounting file systems at boot has to take place + in systemd now. + + * nspawn now learned a new switch --uuid= to set the machine + ID on the command line. + + * nspawn now learned the -b switch to automatically search + for an init system. + + * vt102 is now the default TERM for serial TTYs, upgraded from + vt100. + + * systemd-logind now works on VT-less systems. + + * The build tree has been reorganized. The individual + components now have directories of their own. + + * A new condition type ConditionPathIsReadWrite= is now available. + + * nspawn learned the new -C switch to create cgroups for the + container in other hierarchies. + + * We now have support for hardware watchdogs, configurable in + system.conf. + + * The scheduled shutdown logic now has a public API. + + * We now mount /tmp as tmpfs by default, but this can be + masked and /etc/fstab can override it. + + * Since udisks doesn't make use of /media anymore we are not + mounting a tmpfs on it anymore. + + * journalctl gained a new --local switch to only interleave + locally generated journal files. + + * We can now load the IMA policy at boot automatically. + + * The GTK tools have been split off into a systemd-ui. + + Contributions from: Andreas Schwab, Auke Kok, Ayan George, + Colin Guthrie, Daniel Mack, Dave Reisner, David Ward, Elan + Ruusamäe, Frederic Crozat, Gergely Nagy, Guillermo Vidal, + Hannes Reinecke, Harald Hoyer, Javier Jardón, Kay Sievers, + Lennart Poettering, Lucas De Marchi, Léo Gillot-Lamure, + Marc-Antoine Perennou, Martin Pitt, Matthew Monaco, Maxim + A. Mikityanskiy, Michael Biebl, Michael Olbrich, Michal + Schmidt, Nis Martensen, Patrick McCarty, Roberto Sassu, Shawn + Landden, Sjoerd Simons, Sven Anders, Tollef Fog Heen, Tom + Gundersen + +CHANGES WITH 44: + + * This is mostly a bugfix release + + * Support optional initialization of the machine ID from the + KVM or container configured UUID. + + * Support immediate reboots with "systemctl reboot -ff" + + * Show /etc/os-release data in systemd-analyze output + + * Many bugfixes for the journal, including endianess fixes and + ensuring that disk space enforcement works + + * sd-login.h is C++ comptaible again + + * Extend the /etc/os-release format on request of the Debian + folks + + * We now refuse non-UTF8 strings used in various configuration + and unit files. This is done to ensure we don't pass invalid + data over D-Bus or expose it elsewhere. + + * Register Mimo USB Screens as suitable for automatic seat + configuration + + * Read SELinux client context from journal clients in a race + free fashion + + * Reorder configuration file lookup order. /etc now always + overrides /run in order to allow the administrator to always + and unconditionally override vendor supplied or + automatically generated data. + + * The various user visible bits of the journal now have man + pages. We still lack man pages for the journal API calls + however. + + * We now ship all man pages in HTML format again in the + tarball. + + Contributions from: Dave Reisner, Dirk Eibach, Frederic + Crozat, Harald Hoyer, Kay Sievers, Lennart Poettering, Marti + Raudsepp, Michal Schmidt, Shawn Landden, Tero Roponen, Thierry + Reding + +CHANGES WITH 43: + + * This is mostly a bugfix release + + * systems lacking /etc/os-release are no longer supported. + + * Various functionality updates to libsystemd-login.so + + * Track class of PAM logins to distuingish greeters from + normal user logins. + + Contributions from: Kay Sievers, Lennart Poettering, Michael + Biebl + +CHANGES WITH 42: + + * This is an important bugfix release for v41. + + * Building man pages is now optional which should be useful + for those building systemd from git but unwilling to install + xsltproc. + + * Watchdog support for supervising services is now usable. In + a future release support for hardware watchdogs + (i.e. /dev/watchdog) will be added building on this. + + * Service start rate limiting is now configurable and can be + turned off per service. When a start rate limit is hit a + reboot can automatically be triggered. + + * New CanReboot(), CanPowerOff() bus calls in systemd-logind. + + Contributions from: Benjamin Franzke, Bill Nottingham, + Frederic Crozat, Lennart Poettering, Michael Olbrich, Michal + Schmidt, Michał Górny, Piotr Drąg + +CHANGES WITH 41: + + * The systemd binary is installed /usr/lib/systemd/systemd now; + An existing /sbin/init symlink needs to be adapted with the + package update. + + * The code that loads kernel modules has been ported to invoke + libkmod directly, instead of modprobe. This means we do not + support systems with module-init-tools anymore. + + * Watchdog support is now already useful, but still not + complete. + + * A new kernel command line option systemd.setenv= is + understood to set system wide environment variables + dynamically at boot. + + * We now limit the set of capabilities of systemd-journald. + + * We now set SIGPIPE to ignore by default, since it only is + useful in shell pipelines, and has little use in general + code. This can be disabled with IgnoreSIPIPE=no in unit + files. + + Contributions from: Benjamin Franzke, Kay Sievers, Lennart + Poettering, Michael Olbrich, Michal Schmidt, Tom Gundersen, + William Douglas + +CHANGES WITH 40: + + * This is mostly a bugfix release + + * We now expose the reason why a service failed in the + "Result" D-Bus property. + + * Rudimentary service watchdog support (will be completed over + the next few releases.) + + * When systemd forks off in order execute some service we will + now immediately changes its argv[0] to reflect which process + it will execute. This is useful to minimize the time window + with a generic argv[0], which makes bootcharts more useful + + Contributions from: Alvaro Soliverez, Chris Paulson-Ellis, Kay + Sievers, Lennart Poettering, Michael Olbrich, Michal Schmidt, + Mike Kazantsev, Ray Strode + +CHANGES WITH 39: + + * This is mostly a test release, but incorporates many + bugfixes. + + * New systemd-cgtop tool to show control groups by their + resource usage. + + * Linking against libacl for ACLs is optional again. If + disabled, support tracking device access for active logins + goes becomes unavailable, and so does access to the user + journals by the respective users. + + * If a group "adm" exists, journal files are automatically + owned by them, thus allow members of this group full access + to the system journal as well as all user journals. + + * The journal now stores the SELinux context of the logging + client for all entries. + + * Add C++ inclusion guards to all public headers + + * New output mode "cat" in the journal to print only text + messages, without any meta data like date or time. + + * Include tiny X server wrapper as a temporary stop-gap to + teach XOrg udev display enumeration. This is used by display + managers such as gdm, and will go away as soon as XOrg + learned native udev hotplugging for display devices. + + * Add new systemd-cat tool for executing arbitrary programs + with STDERR/STDOUT connected to the journal. Can also act as + BSD logger replacement, and does so by default. + + * Optionally store all locally generated coredumps in the + journal along with meta data. + + * systemd-tmpfiles learnt four new commands: n, L, c, b, for + writing short strings to files (for usage for /sys), and for + creating symlinks, character and block device nodes. + + * New unit file option ControlGroupPersistent= to make cgroups + persistent, following the mechanisms outlined in + http://www.freedesktop.org/wiki/Software/systemd/PaxControlGroups + + * Support multiple local RTCs in a sane way + + * No longer monopolize IO when replaying readahead data on + rotating disks, since we might starve non-file-system IO to + death, since fanotify() will not see accesses done by blkid, + or fsck. + + * Don't show kernel threads in systemd-cgls anymore, unless + requested with new -k switch. + + Contributions from: Dan Horák, Kay Sievers, Lennart + Poettering, Michal Schmidt + +CHANGES WITH 38: + + * This is mostly a test release, but incorporates many + bugfixes. + + * The git repository moved to: + git://anongit.freedesktop.org/systemd/systemd + ssh://git.freedesktop.org/git/systemd/systemd + + * First release with the journal + http://0pointer.de/blog/projects/the-journal.html + + * The journal replaces both systemd-kmsg-syslogd and + systemd-stdout-bridge. + + * New sd_pid_get_unit() API call in libsystemd-logind + + * Many systemadm clean-ups + + * Introduce remote-fs-pre.target which is ordered before all + remote mounts and may be used to start services before all + remote mounts. + + * Added Mageia support + + * Add bash completion for systemd-loginctl + + * Actively monitor PID file creation for daemons which exit in + the parent process before having finished writing the PID + file in the daemon process. Daemons which do this need to be + fixed (i.e. PID file creation must have finished before the + parent exits), but we now react a bit more gracefully to them. + + * Add colourful boot output, mimicking the well-known output + of existing distributions. + + * New option PassCredentials= for socket units, for + compatibility with a recent kernel ABI breakage. + + * /etc/rc.local is now hooked in via a generator binary, and + thus will no longer act as synchronization point during + boot. + + * systemctl list-unit-files now supports --root=. + + * systemd-tmpfiles now understands two new commands: z, Z for + relabelling files according to the SELinux database. This is + useful to apply SELinux labels to specific files in /sys, + among other things. + + * Output of SysV services is now forwarded to both the console + and the journal by default, not only just the console. + + * New man pages for all APIs from libsystemd-login. + + * The build tree got reorganized and a the build system is a + lot more modular allowing embedded setups to specifically + select the components of systemd they are interested in. + + * Support for Linux systems lacking the kernel VT subsystem is + restored. + + * configure's --with-rootdir= got renamed to + --with-rootprefix= to follow the naming used by udev and + kmod + + * Unless specified otherwise we'll now install to /usr instead + of /usr/local by default. + + * Processes with '@' in argv[0][0] are now excluded from the + final shut-down killing spree, following the logic explained + in: + http://www.freedesktop.org/wiki/Software/systemd/RootStorageDaemons + + * All processes remaining in a service cgroup when we enter + the START or START_PRE states are now killed with + SIGKILL. That means it is no longer possible to spawn + background processes from ExecStart= lines (which was never + supported anyway, and bad style). + + * New PropagateReloadTo=/PropagateReloadFrom= options to bind + reloading of units together. + + Contributions from: Bill Nottingham, Daniel J. Walsh, Dave + Reisner, Dexter Morgan, Gregs Gregs, Jonathan Nieder, Kay + Sievers, Lennart Poettering, Michael Biebl, Michal Schmidt, + Michał Górny, Ran Benita, Thomas Jarosch, Tim Waugh, Tollef + Fog Heen, Tom Gundersen, Zbigniew Jędrzejewski-Szmek diff --git a/README b/README new file mode 100644 index 000000000..581e84598 --- /dev/null +++ b/README @@ -0,0 +1,122 @@ +systemd System and Service Manager + +DETAILS: + http://0pointer.de/blog/projects/systemd.html + +WEB SITE: + http://www.freedesktop.org/wiki/Software/systemd + +GIT: + git://anongit.freedesktop.org/systemd/systemd + ssh://git.freedesktop.org/git/systemd/systemd + +GITWEB: + http://cgit.freedesktop.org/systemd/systemd + +MAILING LIST: + http://lists.freedesktop.org/mailman/listinfo/systemd-devel + http://lists.freedesktop.org/mailman/listinfo/systemd-commits + +IRC: + #systemd on irc.freenode.org + +BUG REPORTS: + https://bugs.freedesktop.org/enter_bug.cgi?product=systemd + +AUTHOR: + Lennart Poettering + Kay Sievers + ...and many others + +LICENSE: + LGPLv2.1+ for all code + - except sd-daemon.[ch] and sd-readahead.[ch] which are MIT + - except src/udev/ which is GPLv2.0+ + +REQUIREMENTS: + Linux kernel >= 2.6.39 + with devtmpfs + with cgroups (but it's OK to disable all controllers) + optional but strongly recommended: autofs4, ipv6 + dbus >= 1.4.0 + libcap + libblkid >= 2.20 (from util-linux) (optional) + libkmod >= 5 (optional) + PAM >= 1.1.2 (optional) + libcryptsetup (optional) + libaudit (optional) + libacl (optional) + libattr (optional) + libselinux (optional) + liblzma (optional) + tcpwrappers (optional) + libgcrypt (optional) + libqrencode (optional) + libmicrohttpd (optional) + libpython (optional) + make, gcc, and similar tools + + During runtime you need the following additional dependencies: + + util-linux >= v2.19 (requires fsck -l, agetty -s) + sulogin (from util-linux >= 2.22 or sysvinit-tools, optional but recommended) + dracut (optional) + + When building from git you need the following additional dependencies: + + docbook-xsl + xsltproc + automake + autoconf + libtool + intltool + gperf + gtkdocize (optional) + python (optional) + + When systemd-hostnamed is used it is strongly recommended to + install nss-myhostname to ensure that in a world of + dynamically changing hostnames the hostname stays resolvable + under all circumstances. In fact, systemd-hostnamed will warn + if nss-myhostname is not installed. Packagers are encouraged to + add a dependency on nss-myhostname to the package that + includes systemd-hostnamed. + + Note that D-Bus can link against libsystemd-login.so, which + results in a cyclic build dependency. To accommodate for this + please build D-Bus without systemd first, then build systemd, + then rebuild D-Bus with systemd support. + +WARNINGS: + systemd will warn you during boot if /etc/mtab is not a + symlink to /proc/mounts. Please ensure that /etc/mtab is a + proper symlink. + + systemd will warn you during boot if /usr is on a different + file system than /. While in systemd itself very little will + break if /usr is on a separate partition many of its + dependencies very likely will break sooner or later in one + form or another. For example udev rules tend to refer to + binaries in /usr, binaries that link to libraries in /usr or + binaries that refer to data files in /usr. Since these + breakages are not always directly visible systemd will warn + about this, since this kind of file system setup is not really + supported anymore by the basic set of Linux OS components. + + For more information on this issue consult + http://freedesktop.org/wiki/Software/systemd/separate-usr-is-broken + + To run systemd under valgrind, compile with VALGRIND defined + (e.g. ./configure CPPFLAGS='... -DVALGRIND=1'). Otherwise, + false positives will be triggered by code which violates + some rules but is actually safe. + +ENGINEERING AND CONSULTING SERVICES: + ProFUSION offers professional + engineering and consulting services for systemd for embedded + and other use. Please contact Gustavo Barbieri + for more information. + + Disclaimer: This notice is not a recommendation or official + endorsement. However, ProFUSION's upstream work has been very + beneficial for the systemd project. diff --git a/TODO b/TODO new file mode 100644 index 000000000..c2eb557f5 --- /dev/null +++ b/TODO @@ -0,0 +1,613 @@ +Bugfixes: +* check systemd-tmpfiles for selinux context hookup for mknod(), symlink() and similar + +* swap units that are activated by one name but shown in the kernel under another are semi-broken + +* make anaconda write timeout=0 for encrypted devices + +* Dangling symlinks of .automount unit files in .wants/ directories, set up + automount points even when the original .automount file did not exist + anymore. Only the .mount unit was still around. + +* make polkit checks async + +* properly handle .mount unit state tracking when two mount points are stacked one on top of another on the exact same mount point. + +F18: + +* Retest multi-seat + +Features: +* udev: remove all (misguided from day 1) userspace firmware_class handling + +* logind: optionally, ignore idle-hint logic for autosuspend, block suspend as long as a session is around + +* service: when killing a service with SIGKILL always kill all processes, even if for SIGTERM we only killed the main process + +* exec: when deinitializating a tty device fix the perms and group, too, not only when initializing. Set access mode/gid to 0620/tty. + +* DeviceAllow/DeviceDeny: disallow everything by default, but whitelist /dev/zero, /dev/null and friends + +* service: watchdog logic: for testing purposes allow ping, but do not require pong + +* journald: when dropping msgs due to ratelimit make sure to write + "dropped %u messages" not only when we are about to print the next + message that works, but alraedy after a short tiemout + +* journald: also get thread ID from client, plus thread name + +* check if we can make journalctl by default use --follow mode inside of less if called without args? + +* Add a verbose mode to "systemctl start" and friends that explains what is being done or not done + +* journal is not closed properly at shutdown when run in a container? + +* journal: when waiting for journal additions in the client always sleep at least 1s or so, in order to minimize wakeups + +* When shutdown.target is queued begin with an asynchronous sync()? + +* add API to close/reopen/get fd for journal client fd in libsystemd-journal. + +* maybe add API to send pairs of iovecs via sd_journal_send + +* fallback to /dev/log based logging in libsystemd-journal, if we can't log natively? + +* declare the local journal protocol stable in the wiki interface chart + +* journal: reuse XZ context + +* sd-journal: speed up sd_journal_get_data() with transparent hash table in bg + +* introduce ntp.service (or suchlike) as symlink that is used to arbitrate between various NTP implementations + +* timer units should get the ability to trigger when: + - CLOCK_REALTIME makes jumps (TFD_TIMER_CANCEL_ON_SET) + - DST changes + +* update the kernel's TZ (sys_tz) when DST changes + +* sync down the system time to the RTC when: + - CLOCK_REALTIME makes jumps (the user explicitely requested a time set) + - DST/timezone changes && ntp is active && RTC-in-localtime (never do it without ntp) + This takes care of syncing ntpdate updates to the RTC, and DST updates for localtime + mode, it will never touch the RTC if the no reliable time source is active or the + user did not request anything like it. + +* When we begin with system shutdown all kind of suspend/hibernation should be prohibited until shutdown/reboot + +* When we update the kernel all kind of hibernation should be prohibited until shutdown/reboot + +* hwdb: + - implement conditional properties (dmi matches) + - hwdb --filter=ID_DRIVE_* + - find out what to do for blockdevs and skipping scsi modaliases + - move writing code to src/libudev/libudev-hwdb-private.c + +* if booted in "quiet" mode, and an error happens, turn on status output again, so that the emergency mode isn't totally surprising + +* localectl: add listing support for X11 keymaps, by parsing /usr/share/X11/xkb/rules/xorg.lst + +* libunwind support for coredump pattern hook, and includes this in + the message for coredumps. After all, libunwind is now capable to + unwind coredumps since a few weeks ago. This probably requires that + we have nice support for multi-line messages on display in logs-show.c. + +* figure out relation of --all and --full in the various tools + +* journal: when writing journal auto-rotate if time jumps backwards + +* introduce new "journal" group in place of adm? introduce groups for the various mini daemons? + +* journal: add a setgid "adm" utility to invoke from libsystemd-journal, which passes fds via STDOUT and does PK access + +* journactl: support negative filtering, i.e. FOOBAR!="waldo", + and !FOOBAR for events without FOOBAR. + +* print nice message from systemctl --failed if there are no entries shown, and hook that into ExecStartPre of rescue.service/emergency.service + +* add libsystemd-password or so to query passwords during boot using the password agent logic + +* journal: when rotating, copy over old acls/access mode + +* journal: document why we do not give ownership to journal files to the user that created them but use FS ACLs for that + +* journal: send out marker messages every now and then, and immediately sync with fdatasync() afterwards, in order to have hourly guaranteed syncs. + +* journal: when we haven't written anything in a while, sync to disk and mark file as offline, in order to be more often than not in a clean state + +* journal-send.c, log.c: when the log socket is clogged, and we drop, count this and write a message about this when it gets unclogged again. + +* If we show an error about a unit (such as not showing up) and it has no Description string, then show a description string generated form the reverse of unit_name_mangle(). + +* fedup: add --unit to systemctl switch-root somehow +* fedup: don't delete initrd on switch-root +* fedup: generator + +* journal: find a way to allow dropping history early, based on priority, other rules + +* journal: When used on NFS, check payload hashes + +* journal: When used on NFS make sure wake up sd_journal_wait() every 2s, to handle missing inotify + +* document that people can use file system ACLs to manage access to journal files, with example + +* timedated: export boolean that clarifies whether NTP is even available + +* timedated: refuse time changes when NTP is on + +* clean up date formatting and parsing so that all absolute/relative timestamps we format can also be parsed + +* document unit_name_mangle() + +* add new command to systemctl: "systemctl system-reexec" which reexecs as many daemons as virtually possible + +* introduce generic AUGMENT_PID=, AUGMENT_DEVICE= fields + +* deal with sendmail/postfix exclusivity + +* systemctl enable: improve the success messages (i.e. more human readable, less shell-like) + +* systemctl enable: fail if target to alias into doesn't exist? maybe show how many units are enabled afterwards? + +* on shutdown: move utmp, wall, audit logic all into PID 1 itself, get rid of systemd-update-utmp-runlevel + +* add "provisioning" instructions to setup an empty /etc + /var + - used to setup a new container from a shared /usr + - superset of tmpfiles model + - instructions shipped by packages and stored in /usr/lib/ + - compose /etc/passwd and /etc/group, copy files + - able to create uid + gid used by packages, for file ownership + +* make repeated alt-ctrl-del presses printing a dump, or even force a reboot without + waiting for the timeout + +* high level net_prio setting in execution context + +* Introduce journalctl -b to show journal messages of a previous boot + +* hostnamed: before returning information from /etc/machine-info.conf check the modification data and reread. Similar for localed, ... + +* currently x-systemd.timeout is lost in the initrd, since crypttab is copied into dracut, but fstab isn't + +* WorkingDirectory: support env var replacements like in ExecStart= so that people can use $HOME + +* refuse boot if /etc/machine-id is not useful (or set taint?) + +* nspawn: consider changing users for -u with su, so that NSS resolving works correctly + +* nspawn: implement personality changes a la linux32(8) + +* cryptsetup-generator: warn if the password files are world-readable + +* cryptsetup-generator: add RequiresMountsFor= to cryptseup service files referencing a file, similar for devices + +* cryptsetup-generator: allow specification of passwords in crypttab itself + +* document that deps in [Unit] sections ignore Alias= fileds in + [Install] units of other units, unless those units are disabled + +* systemctl: when powering down/suspending check for inhibitors, and warn. + +* instantiated [Install] for target units + https://bugs.freedesktop.org/show_bug.cgi?id=54377 + +* move debug shell to tty6 and make sure this doesn't break the gettys on tty6 + +* move cryptsetup key caching into kernel keyctl? + https://bugs.freedesktop.org/show_bug.cgi?id=54982 + +* hw watchdog: optionally try to use the preset watchdog timeout instead of always overriding it + https://bugs.freedesktop.org/show_bug.cgi?id=54712 + +* after deserializing sockets in socket.c we should reapply sockopts and things + +* make timer units go away after they elapsed + +* http://lists.freedesktop.org/archives/systemd-devel/2012-September/006502.html + (network and remote-fs on shutdown) + +* come up with a nice way to write queue/read_ahead_kb for a block device without interfering with readahead + +* journald: add kernel cmdline option to disable ratelimiting for debug purposes + +* move PID 1 segfaults to /var/lib/systemd/coredump? + +* Document word splitting syntax for ExecStart= and friends + +* create /sbin/init symlinks from the build system + +* Query Paul Moore about relabelling socket fds while they are open + +* move keymaps to /usr/lib/... rather than /usr/lib/udev/... + +* journald: check whether it is OK if the client can still modify delivered journal entries + +* journal live copy, based on libneon (client) and libmicrohttpd + +* system-wide seccomp filter + +* system.conf should have controls for cgroups + +* bind mount read-only the cgroup tree higher than nspawn + +* allow writing multiple conditions in unit files on one line + +* explore multiple service instances per listening socket idea + +* testing tool for socket activation: some binary that listens on a socket and passes it on using the usual socket activation protocol to some server. + +* shutdown: don't read-only mount anything when running in container + +* nspawn: --read-only is not applied recursively to submounts + +* MountFlags=shared acts as MountFlags=slave right now. + +* ReadOnlyDirectories= is not applied recursively to submounts + +* drop PID 1 reloading, only do reexecing (difficult: Reload() + currently is properly synchronous, Reexec() is weird, because we + can't delay the response properly until we are back, so instead of + being properly synchronous we just keep open the fd and close it + when done. That means clients don't get a successful method reply, + but much rather a disconnect on success. + +* document that service reload may be implemented as service reexec + +* remember which condition failed for services, not just the fact that something failed + +* use opterr = 0 for all getopt tools + +* properly handle loop back mounts via fstab, especially regards to fsck/passno + +* allow services with no ExecStart= but with an ExecStop= + +* add proper journal support to "systemctl --user status ..." + +* add _SYSTEMD_USER_UNIT= field to journal entries + +* dracut-shutdown needs to be ordered before unmounting /boot + +* initialize the hostname from the fs label of /, if /etc/hostname does not exist? + +* rename "userspace" to "core-os" + +* systemctl: "Journal has been rotated since unit was started." message is misleading + +* syscall filter: add knowledge about compat syscalls + +* syscall filter: don't enforce no new privs? + +* syscall filter: option to return EPERM rather than SIGSYS? + +* syscall filter: port to libseccomp + +* logind: wakelock/opportunistic suspend support + +* systemd-analyze post-boot is broken for initrd + +* systemd-analyze: data collection tools should be lightweight (few dependencies); data analysis tools can be heavyweight + +* man: clarify that time-sync.target is not only sysv compat but also useful otherwise. Same for similar targets + +* .device aliases need to be implemented with the "following" logic, probably. + +* refuse taking lower-case variable names in sd_journal_send() and friends. + +* load-fragment: when loading a unit file via a chain of symlinks + verify that it isn't masked via any of the names traversed. + +* journald: we currently rotate only after MaxUse+MaxFilesize has been reached. + +* Document: + - PID 1 D-Bus API + +* introduce Type=pid-file + +* maybe allow services with ExecStop= set, but no ExecStart=? + +* efi: implement /forcefsck as uefi variables thus not requiring file system altering to trigger a file system check + +* efi: honor language efi variables for default language selection + +* efi: honor timezone efi variables for default timezone selection + +* efi: automatically mount EFI partition to /boot if no such entry exists in /etc/fstab and /boot is empty + gummiboot exports the EFI system partion (ESP) device: + /sys/firmware/efi/vars/LoaderDeviceIdentifier-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f/data + Acpi(PNP0A03,0)/Pci(1F|2)/?/HD(Part1,Sig1FCBC57F-4BFC-4C2B-91A3-9C84FBCD9AF1) + '/' is the separator for the device path list + HD(Part1,Sig1FCBC57F-4BFC-4C2B-91A3-9C84FBCD9AF1) contains the GPT UUID of the ESP + +* read the bootloader performance data (raw TSC) in systemd-analyze + /sys/firmware/efi/vars/LoaderTicksExec-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f/data + 19066159288 + /sys/firmware/efi/vars/LoaderTicksInit-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f/data + 17442940316 + /sys/firmware/efi/vars/LoaderTicksStartMenu-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f/data + (only set if the menu was active) + +* change Requires=basic.target to RequisiteOverride=basic.target + +* support rd.luks.allow-discards= kernel cmdline params in cryptsetup generator + +* nspawn: make use of device cgroup controller by default + +* drop accountsservice's StandardOutput=syslog and Type=dbus fields + +* when breaking cycles drop sysv services first, then services from /run, then from /etc, then from /usr + +* readahead: when bumping /sys readahead variable save mtime and compare later to detect changes + +* (attempt to) make Debianites happy: + - implement .d/ auto includes for unit files + - add syntax to reset ExecStart= lists (and similar) + +* move passno parsing to fstab generator + +* improve !/proc/*/loginuid situation: make /proc/*/loginuid less dependent on CONFIG_AUDIT, + or use the users cgroup information when /proc/*/loginuid is not available. + +* pam_systemd: try to get old session id from cgroup, if audit sessionid cannot be determined + +* pam: when leaving a session explicitly exclude the ReleaseSession() caller process from the killing spree + +* maybe introduce ~/.config/locale.conf and apply it within PAM + +* readahead: make use of EXT4_IOC_MOVE_EXT, as used by http://e4rat.sourceforge.net/ + +* automount: implement expire + +* services which create their own subcgroups break cgroup-empty notification (needs to be fixed in the kernel) + +* don't delete /tmp/systemd-namespace-* before a process is gone down + +* vconsole: implement setterm -store -foreground xxx --background zzz + +* ExecOnFailure=/usr/bin/foo + +* fedora: make sshd and pam_loginuid work in nspawn containers + +* fix utmp for console logins in containers + +* Add pretty name for seats in logind + +* ConditionSecurity= should learn about IMA and SMACK + +* Auke: merge Auke's bootchart + +* udev: move to LGPL + +* udev systemd unify: + - strpcpy(), strpcpyl(), strscpy(), strscpyl() + - utf8 validator code + +* udev: scsi_id -> sg3_utils -> kill scsi_id + +* udev: add trigger --subsystem-match=usb/usb_device device + +* allow configuration of console width/height in vconsole.conf + +* cleanup syslog 'priority' vs. 'level' wording + +* dbus upstream still refers to dbus.target and shouldn't + +* when a service has the same env var set twice we actually store it twice and return that in systemctl show -p... We should only show the last setting + +* support container_ttys= + +* introduce mix of BindTo and Requisite + +* journalctl: show multiline log messages sanely, expand tabs, and show all valid utf8 messages + +* add DeleteSocketsOnStop=yes|no option to socket units + +* journal: store euid in journal if it differs from uid + +* There's currently no way to cancel fsck (used to be possible via C-c or c on the console) + +* journal: sanely deal with entries which are larger than the individual file size, but where the components would fit + +* add command to systemctl to plot dependency graph as tree (see rhbz 795365) + +* add option to sockets to avoid activation. Instead just drop packets/connections, see http://cyberelk.net/tim/2012/02/15/portreserve-systemd-solution/ + +* default unix qlen is too small (10). bump sysctl? add sockopt? + +* figure out whether we should leave dbus around during shutdown + +* dbus: in fedora, make the machine a symlink to /etc/machine-id + +* dbus: move dbus to early boot + +* logind: add equivalent to sd_pid_get_owner_uid() to the D-Bus API + +* journal: deal nicely with byte-by-byte copied files, especially regards header + +* journal: local deserializer of export mode, http server + +* document the exit codes when services fail before they are exec()ed + +* save coredump in Windows/Mozilla minidump format + +* support crash reporting operation modes (https://live.gnome.org/GnomeOS/Design/Whiteboards/ProblemReporting) + +* clean up session cgroups that remain after logout (think sshd), but eventually run empty + +* support "systemctl stop foobar@.service" to stop all units matching a certain template + +* logind: allow showing logout dialog from system + +* document that %% can be used to write % in a string that is specifier extended + +* when an instanced service exits, remove its parent cgroup too if possible. + +* default to actual 32bit PIDs, via /proc/sys/kernel/pid_max + +* be able to specify a forced restart of service A where service B depends on, in case B + needs to be auto-respawned? + +* Something is wrong with symlink handling of "autovt@.service" in "systemctl list-unit-files" + +* when a bus name of a service disappears from the bus make sure to queue further activation requests + +* something like ConditionExec= or ExecStartPre= without failure state + +* tmpfiles: apply "x" on "D" too (see patch from William Douglas) + +* don't set $HOME in services unless requested + +* hide PAM/TCPWrap options in fragment parser when compile time disabled + +* when we automatically restart a service, ensure we restart its rdeps, too. + +* allow Type=simple with PIDFile= + https://bugzilla.redhat.com/show_bug.cgi?id=723942 + +* move PAM code into its own binary + +* logind: spawn user@..service on login + +* logind: non-local X11 server handling + +* implement Register= switch in .socket units to enable registration + in Avahi, RPC and other socket registration services. + +* make sure systemd-ask-password-wall does not shutdown systemd-ask-password-console too early + +* readahead: use BTRFS_IOC_DEFRAG_RANGE instead of BTRFS_IOC_DEFRAG ioctl, with START_IO + +* support sd_notify() style notification when reload begins (RELOADING=1), reload is finished (READY=1), and add ReloadSignal= then to use in combination + +* support sd_notify() style notification when shutting down, to make auto-exit bus services work (STOPPING=1) + +* verify that the AF_UNIX sockets of a service in the fs still exist + when we start a service in order to avoid confusion when a user + assumes starting a service is enough to make it accessible + +* Make it possible to set the keymap independently from the font on + the kernel cmdline. Right now setting one resets also the other. + +* move nss-myhostname into systemd + +* and a dbus call to generate target from current state + +* drop /.readahead on bigger upgrades with yum + +* add support for /bin/mount -s + +* GC unreferenced jobs (such as .device jobs) + +* write blog stories about: + - hwdb: what belongs into it, lsusb + - enabling dbus services + - status update + - how to make changes to sysctl and sysfs attributes + - remote access + - how to pass throw-away units to systemd, or dynamically change properties of existing units + - how to integrate cgconfig and suchlike with systemd + - testing with Harald's awesome test kit + - auto-restart + - how to develop against journal browsing APIs + - the journal HTTP iface + - non-cgroup resource management + - refreshed, longer missions statement + - using detect-virt + +* allow port=0 in .socket units + +* move readahead files into /var (look for them with .path units?) + +* teach dbus to activate all services it finds in /etc/systemd/services/org-*.service + +* support systemd.mask= on the kernel command line. + +* when key file cannot be found, read it from kbd in cryptsetup + +* reuse mkdtemp namespace dirs in /tmp? + +* recreate systemd's D-Bus private socket file on SIGUSR2 + +* Support --test based on current system state + +* investigate whether the gnome pty helper should be moved into systemd, to provide cgroup support. + +* maybe introduce ExecRestartPre= + +* configurable jitter for timer events + +* timer events with system resume + +* dot output for --test showing the 'initial transaction' + +* writable cgroups dbus properties for live changes + +* port over to LISTEN_FDS/LISTEN_PID: + - rpcbind (/var/run/rpcbind.sock!) HAVEPATCH + - cups HAVEPATCH + - postfix, saslauthd + - apache/samba + - libvirtd (/var/run/libvirt/libvirt-sock-ro) + - bluetoothd (/var/run/sdp! @/org/bluez/audio!) + - distccd + +* fingerprint.target, wireless.target, gps.target, netdevice.target + +* io priority during initialization + +* systemctl list-jobs - show dependencies + +* add systemctl switch to dump transaction without executing it + +* drop cap bounding set in readahead and other services + +External: + +* dbus: + - dbus --user + - natively watch for dbus-*.service symlinks (PENDING) + - allow specification of socket mode/umask when allocating DBusServer + - allow disabling of fd passing when connecting a AF_UNIX connection + - allow disabling of UID passing for AUTH EXTERNAL + - always pass cred data along each message + +* fix alsa mixer restore to not print error when no config is stored + +* gnome-shell python script/glxinfo/is-accelerated must die + +* make cryptsetup lower --iter-time + +* patch kernel for xattr support in /dev, /proc/, /sys and /sys/fs/cgroup? + +* NTP: the kernel's 11-minutes-mode syncs the system time to the RTC, but only + in an ~30 minutes window. It does not adjust larger differences. Find a way + to tell the kernel, to always do a full time sync when the RTC is in UTC and + we are in 11-minutes-mode. When we trust the system time to NTP we also want + the RTC to sync up. + +* kernel: add device_type = "fb", "fbcon" to class "graphics" + +Regularly: + +* look for close() vs. close_nointr() vs. close_nointr_nofail() + +* check for strerror(r) instead of strerror(-r) + +* Use PR_SET_PROCTITLE_AREA if it becomes available in the kernel + +* %m in printf() instead of strerror(errno); + +* pahole + +* set_put(), hashmap_put() return values check. i.e. == 0 doesn't free()! + +* use secure_getenv() instead of getenv() where appropriate + +* link up selected blog stories from man pages and unit files Documentation= fields + +Scheduled for removal or fixing: + +* xxxOverridable dependencies (probably: fix) + +* support for early-boot SysV services (definitely: remove) + +* insserv support (definitely: remove) diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 000000000..33d8fcda2 --- /dev/null +++ b/autogen.sh @@ -0,0 +1,67 @@ +#!/bin/sh + +# This file is part of systemd. +# +# 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 . + +set -e + +if [ -f .git/hooks/pre-commit.sample ] && [ ! -f .git/hooks/pre-commit ]; then + # This part is allowed to fail + cp -p .git/hooks/pre-commit.sample .git/hooks/pre-commit && \ + chmod +x .git/hooks/pre-commit && \ + echo "Activated pre-commit hook." || : +fi + +if which gtkdocize >/dev/null 2>/dev/null; then + gtkdocize --docdir docs/ + gtkdocargs=--enable-gtk-doc +else + echo "You don't have gtk-doc installed, and thus won't be able to generate the documentation." + rm -f docs/gtk-doc.make + echo 'EXTRA_DIST =' > docs/gtk-doc.make +fi + +intltoolize --force --automake +autoreconf --force --install --symlink + +libdir() { + echo $(cd "$1/$(gcc -print-multi-os-directory)"; pwd) +} + +args="\ +--sysconfdir=/etc \ +--localstatedir=/var \ +--libdir=$(libdir /usr/lib) \ +$gtkdocargs" + +if [ ! -L /bin ]; then +args="$args \ +--with-rootprefix= \ +--with-rootlibdir=$(libdir /lib) \ +" +fi + +if [ "x$1" = "xc" ]; then + ./configure CFLAGS='-g -O0 -Wp,-U_FORTIFY_SOURCE' $args + make clean +else + echo + echo "----------------------------------------------------------------" + echo "Initialized build system. For a common configuration please run:" + echo "----------------------------------------------------------------" + echo + echo "./configure CFLAGS='-g -O0 -Wp,-U_FORTIFY_SOURCE' $args" + echo +fi diff --git a/catalog/Makefile b/catalog/Makefile new file mode 120000 index 000000000..bd1047548 --- /dev/null +++ b/catalog/Makefile @@ -0,0 +1 @@ +../src/Makefile \ No newline at end of file diff --git a/catalog/systemd.catalog b/catalog/systemd.catalog new file mode 100644 index 000000000..5dcbd4620 --- /dev/null +++ b/catalog/systemd.catalog @@ -0,0 +1,291 @@ +# This file is part of systemd. +# +# Copyright 2012 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 . + +# Message catalog for systemd's own messages + +# The catalog format is documented on +# http://www.freedesktop.org/wiki/Software/systemd/catalog + +# For an explanation why we do all this, see https://xkcd.com/1024/ + +-- f77379a8490b408bbe5f6940505a777b +Subject: The Journal has been started +Defined-By: systemd +Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel +Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@ + +The system journal process has been starting up, opened the journal +files for writing and is now ready to process requests. + +-- d93fb3c9c24d451a97cea615ce59c00b +Subject: The Journal has been stopped +Defined-By: systemd +Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel +Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@ + +The system journal process has shut down and closed all currently +active journal files. + +-- a596d6fe7bfa4994828e72309e95d61e +Subject: Messages from a service have been suppressed +Defined-By: systemd +Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel +Documentation: man:journald.conf(5) +Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@ + +A service has logged too many messages within a time period. Messages +from the service have been dropped. + +Note that only messages from the service in question have been +dropped, other services' messages are unaffected. + +The limits when messages are dropped may be configured with +RateLimitInterval= and RateLimitBurst= in +/etc/systemd/journald.conf. See journald.conf(5) for details. + +-- e9bf28e6e834481bb6f48f548ad13606 +Subject: Journal messages have been missed +Defined-By: systemd +Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel +Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@ + +Kernel messages have been lost as the journal system has been unable +to process them quickly enough. + +-- fc2e22bc6ee647b6b90729ab34a250b1 +Subject: Process @COREDUMP_PID@ (@COREDUMP_COMM@) dumped core +Defined-By: systemd +Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel +Documentation: man:core(5) +Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@ + +Process @COREDUMP_PID@ (@COREDUMP_COMM@) crashed and dumped core. + +This usually indicates a programming error in the crashing program and +should be reported to its vendor as a bug. + +-- fc2e22bc6ee647b6b90729ab34a250b1 de +Subject: Speicherabbild für Prozess @COREDUMP_PID@ (@COREDUMP_COMM) generiert +Defined-By: systemd +Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel +Documentation: man:core(5) +Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@ + +Prozess @COREDUMP_PID@ (@COREDUMP_COMM@) ist abgebrochen worden und +ein Speicherabbild wurde generiert. + +Üblicherweise ist dies ein Hinweis auf einen Programmfehler und sollte +als Fehler dem jeweiligen Hersteller gemeldet werden. + +-- 8d45620c1a4348dbb17410da57c60c66 +Subject: A new session @SESSION_ID@ has been created for user @USER_ID@ +Defined-By: systemd +Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel +Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat +Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@ + +A new session with the ID @SESSION_ID@ has been created for the user @USER_ID@. + +The leading process of the session is @LEADER@. + +-- 3354939424b4456d9802ca8333ed424a +Subject: A session @SESSION_ID@ has been terminated +Defined-By: systemd +Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel +Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat +Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@ + +A session with the ID @SESSION_ID@ has been terminated. + +-- fcbefc5da23d428093f97c82a9290f7b +Subject: A new seat @SEAT_ID@ is now available +Defined-By: systemd +Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel +Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat +Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@ + +A new seat @SEAT_ID@ has been configured and is now available. + +-- e7852bfe46784ed0accde04bc864c2d5 +Subject: A seat @SEAT_ID@ has now been removed +Defined-By: systemd +Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel +Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat +Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@ + +A seat @SEAT_ID@ has been removed and is no longer available. + +-- c7a787079b354eaaa9e77b371893cd27 +Subject: Time change +Defined-By: systemd +Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel +Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@ + +The system clock has been changed to @REALTIME@ microseconds after January 1st, 1970. + +-- c7a787079b354eaaa9e77b371893cd27 de +Subject: Zeitänderung +Defined-By: systemd +Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel +Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@ + +Die System-Zeit wurde geändert auf @REALTIME@ Mikrosekunden nach dem 1. Januar 1970. + +-- 45f82f4aef7a4bbf942ce861d1f20990 +Subject: Time zone change to @TIMEZONE@ +Defined-By: systemd +Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel +Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@ + +The system time zone has been changed to @TIMEZONE@. + +-- b07a249cd024414a82dd00cd181378ff +Subject: System start-up is now complete +Defined-By: systemd +Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel +Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@ + +All system services necessary queued for starting at boot have been +successfully started. Note that this does not mean that the machine is +now idle as services might still be busy with completing start-up. + +Kernel start-up required @KERNEL_USEC@ microseconds. + +Initial RAM disk start-up required @INITRD_USEC@ microseconds. + +Userspace start-up required @USERSPACE_USEC@ microseconds. + +-- 6bbd95ee977941e497c48be27c254128 +Subject: System sleep state @SLEEP@ entered +Defined-By: systemd +Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel +Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@ + +The system has now entered the @SLEEP@ sleep state. + +-- 8811e6df2a8e40f58a94cea26f8ebf14 +Subject: System sleep state @SLEEP@ left +Defined-By: systemd +Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel +Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@ + +The system has now left the @SLEEP@ sleep state. + +-- 98268866d1d54a499c4e98921d93bc40 +Subject: System shutdown initiated +Defined-By: systemd +Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel +Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@ + +Systemd shutdown has been initiated. The shutdown has now begun and +all system services are terminated and all file systems unmounted. + +-- 7d4958e842da4a758f6c1cdc7b36dcc5 +Subject: Unit @UNIT@ has begun with start-up +Defined-By: systemd +Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel +Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@ + +Unit @UNIT@ has begun starting up. + +-- 39f53479d3a045ac8e11786248231fbf +Subject: Unit @UNIT@ has finished start-up +Defined-By: systemd +Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel +Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@ + +Unit @UNIT@ has finished starting up. + +The start-up result is @RESULT@. + +-- de5b426a63be47a7b6ac3eaac82e2f6f +Subject: Unit @UNIT@ has begun shutting down +Defined-By: systemd +Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel +Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@ + +Unit @UNIT@ has begun shutting down. + +-- 9d1aaa27d60140bd96365438aad20286 +Subject: Unit @UNIT@ has finished shutting down +Defined-By: systemd +Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel +Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@ + +Unit @UNIT@ has finished shutting down. + +-- be02cf6855d2428ba40df7e9d022f03d +Subject: Unit @UNIT@ has failed +Defined-By: systemd +Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel +Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@ + +Unit @UNIT@ has failed. + +The result is @RESULT@. + +-- d34d037fff1847e6ae669a370e694725 +Subject: Unit @UNIT@ has begun with reloading its configuration +Defined-By: systemd +Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel +Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@ + +Unit @UNIT@ has begun with reloading its configuration + +-- 7b05ebc668384222baa8881179cfda54 +Subject: Unit @UNIT@ has finished reloading its configuration +Defined-By: systemd +Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel +Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@ + +Unit @UNIT@ has finished reloading its configuration + +The result is @RESULT@. + +-- 641257651c1b4ec9a8624d7a40a9e1e7 +Subject: Process @EXECUTABLE@ could not be executed +Defined-By: systemd +Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel +Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@ + +The process @EXECUTABLE@ could not be executed and failed. + +The error number returned while executing this process is @ERRNO@. + +-- 0027229ca0644181a76c4e92458afa2e +Subject: One or more messages could not be forwarded to syslog +Defined-By: systemd +Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel +Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@ + +One or more messages could not be forwarded to the syslog service +running side-by-side with journald. This usually indicates that the +syslog implementation has not been able to keep up with the speed of +messages queued. + +-- 1dee0369c7fc4736b7099b38ecb46ee7 +Subject: Mount point is not empty +Defined-By: systemd +Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel +Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@ + +The directory @WHERE@ is specified as the mount point (second field in +/etc/fstab or Where= field in systemd unit file) and is not empty. +This does not interfere with mounting, but the pre-exisiting files in +this directory become inaccessible. To see those over-mounted files, +please manually mount the underlying file system to a secondary +location. diff --git a/configure.ac b/configure.ac new file mode 100644 index 000000000..a8d48871d --- /dev/null +++ b/configure.ac @@ -0,0 +1,874 @@ +# +# This file is part of systemd. +# +# Copyright 2010-2012 Lennart Poettering +# Copyright 2010-2012 Kay Sievers +# +# 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 . + +AC_PREREQ([2.64]) + +AC_INIT([systemd], + [196], + [http://bugs.freedesktop.org/enter_bug.cgi?product=systemd], + [systemd], + [http://www.freedesktop.org/wiki/Software/systemd]) + +AC_CONFIG_SRCDIR([src/core/main.c]) +AC_CONFIG_MACRO_DIR([m4]) +AC_CONFIG_HEADERS([config.h]) +AC_CONFIG_AUX_DIR([build-aux]) + +AC_USE_SYSTEM_EXTENSIONS +AC_SYS_LARGEFILE +AC_PREFIX_DEFAULT([/usr]) +AM_INIT_AUTOMAKE([foreign 1.11 -Wall -Wno-portability silent-rules tar-pax no-dist-gzip dist-xz subdir-objects check-news]) +AM_SILENT_RULES([yes]) +AC_CANONICAL_HOST +AC_DEFINE_UNQUOTED([CANONICAL_HOST], "$host", [Canonical host string.]) +AS_IF([test "x$host_cpu" = "xmips" || test "x$host_cpu" = "xmipsel" || + test "x$host_cpu" = "xmips64" || test "x$host_cpu" = "xmips64el"], + [AC_DEFINE(ARCH_MIPS, [], [Whether on mips arch])]) + +LT_PREREQ(2.2) +LT_INIT + +# i18n stuff for the PolicyKit policy files +IT_PROG_INTLTOOL([0.40.0]) + +GETTEXT_PACKAGE=systemd +AC_SUBST(GETTEXT_PACKAGE) + +AC_PROG_MKDIR_P +AC_PROG_LN_S +AC_PROG_SED +AC_PROG_GREP +AC_PROG_AWK + +AC_PROG_CC +AC_PROG_CC_C99 +AM_PROG_CC_C_O +AC_PROG_GCC_TRADITIONAL + +AC_PATH_PROG([M4], [m4]) +AC_PATH_PROG([XSLTPROC], [xsltproc]) + +AC_PATH_PROG([QUOTAON], [quotaon], [/usr/sbin/quotaon]) +AC_PATH_PROG([QUOTACHECK], [quotacheck], [/usr/sbin/quotacheck]) + +AC_PATH_PROG([SETCAP], [setcap], [/usr/sbin/setcap]) + +AC_PATH_PROG([KILL], [kill], [/usr/bin/kill]) + +# gtkdocize greps for '^GTK_DOC_CHECK', so it needs to be on its own line +m4_ifdef([GTK_DOC_CHECK], [ +GTK_DOC_CHECK([1.18],[--flavour no-tmpl]) +], [AM_CONDITIONAL([ENABLE_GTK_DOC], [false])]) + +AS_IF([test "x$enable_gtk_doc" = "xyes" -a "x$XSLTPROC" = x], [ + AC_MSG_ERROR([*** GTK doc requested but xsltproc not found]) +]) + +m4_ifdef([GOBJECT_INTROSPECTION_CHECK], [ +GOBJECT_INTROSPECTION_CHECK([1.31.1]) +], [ + AM_CONDITIONAL([HAVE_INTROSPECTION], [false]) + enable_introspection=no]) + +AC_PATH_TOOL(OBJCOPY, objcopy) +AC_PATH_TOOL(STRINGS, strings) +AC_PATH_TOOL(GPERF, gperf) +if test -z "$GPERF" ; then + AC_MSG_ERROR([*** gperf not found]) +fi + +# we use python to build the man page index, and for systemd-python +have_python=no +have_python_devel=no + +AC_ARG_WITH([python], + [AS_HELP_STRING([--without-python], [Disable building the man page index and systemd-python (default: test)])]) + +AS_IF([test "x$with_python" != "xno"], [ + AM_PATH_PYTHON(,, [:]) + AS_IF([test "$PYTHON" != :], [have_python=yes]) +]) +AM_CONDITIONAL([HAVE_PYTHON], [test "x$have_python" = "xyes"]) +AS_IF([test "x$PYTHON_BINARY" = "x"], + [AS_IF([test "x$have_python" = "xyes"], + [PYTHON_BINARY="`which "$PYTHON"`"], + [PYTHON_BINARY=/usr/bin/python])]) +AC_ARG_VAR(PYTHON_BINARY, [Python binary used to launch installed scripts]) + +AS_IF([test "x$with_python" != "xno"], [ + AC_PATH_PROG(PYTHON_CONFIG, python${PYTHON_VERSION}-config) + AS_IF([test -n "$PYTHON_CONFIG"], [ + have_python_devel=yes + PYTHON_CFLAGS="`$PYTHON_CONFIG --cflags`" + PYTHON_LIBS="`$PYTHON_CONFIG --ldflags`" + AC_SUBST(PYTHON_CFLAGS) + AC_SUBST(PYTHON_LIBS) + ]) +]) +AM_CONDITIONAL([HAVE_PYTHON_DEVEL], [test "$have_python_devel" = "yes"]) + +CC_CHECK_FLAGS_APPEND([with_cflags], [CFLAGS], [\ + -pipe \ + -Wall \ + -Wextra \ + -Wno-inline \ + -Wundef \ + -Wformat=2 \ + -Wlogical-op \ + -Wsign-compare \ + -Wformat-security \ + -Wmissing-include-dirs \ + -Wformat-nonliteral \ + -Wold-style-definition \ + -Wpointer-arith \ + -Winit-self \ + -Wdeclaration-after-statement \ + -Wfloat-equal \ + -Wmissing-prototypes \ + -Wstrict-prototypes \ + -Wredundant-decls \ + -Wmissing-declarations \ + -Wmissing-noreturn \ + -Wshadow \ + -Wendif-labels \ + -Wcast-align \ + -Wstrict-aliasing=2 \ + -Wwrite-strings \ + -Wno-long-long \ + -Wno-overlength-strings \ + -Wno-unused-parameter \ + -Wno-missing-field-initializers \ + -Wno-unused-result \ + -Werror=overflow \ + -ffast-math \ + -fno-common \ + -fdiagnostics-show-option \ + -fno-strict-aliasing \ + -fvisibility=hidden \ + -ffunction-sections \ + -fdata-sections \ + -fstack-protector \ + --param=ssp-buffer-size=4]) +AC_SUBST([OUR_CFLAGS], $with_cflags) + +CC_CHECK_FLAGS_APPEND([with_cppflags], [CPPFLAGS], [\ + -Wp,-D_FORTIFY_SOURCE=2]) +AC_SUBST([OUR_CPPFLAGS], $with_cppflags) + +CC_CHECK_FLAGS_APPEND([with_ldflags], [LDFLAGS], [\ + -Wl,--as-needed \ + -Wl,--gc-sections \ + -Wl,-z,relro \ + -Wl,-z,now]) +AC_SUBST([OUR_LDFLAGS], $with_ldflags) + +AC_SEARCH_LIBS([mq_open], [rt], [], [AC_MSG_ERROR([*** POSIX RT library not found])]) +AC_SEARCH_LIBS([dlsym], [dl], [], [AC_MSG_ERROR([*** Dynamic linking loader library not found])]) + +save_LIBS="$LIBS" +LIBS= +AC_SEARCH_LIBS([cap_init], [cap], [], [AC_MSG_ERROR([*** POSIX caps library not found])]) +AC_CHECK_HEADERS([sys/capability.h], [], [AC_MSG_ERROR([*** POSIX caps headers not found])]) +CAP_LIBS="$LIBS" +LIBS="$save_LIBS" +AC_SUBST(CAP_LIBS) + +AC_CHECK_FUNCS([fanotify_init fanotify_mark]) +AC_CHECK_FUNCS([__secure_getenv secure_getenv]) +AC_CHECK_DECLS([gettid, pivot_root, name_to_handle_at], [], [], [[#include +#include +#include +#include ]]) + +# This makes sure pkg.m4 is available. +m4_pattern_forbid([^_?PKG_[A-Z_]+$],[*** pkg.m4 missing, please install pkg-config]) + +PKG_CHECK_MODULES(DBUS, [dbus-1 >= 1.3.2]) + +# ------------------------------------------------------------------------------ +have_kmod=no +AC_ARG_ENABLE(kmod, AS_HELP_STRING([--disable-kmod], [disable loadable modules support])) +if test "x$enable_kmod" != "xno"; then + PKG_CHECK_MODULES(KMOD, [ libkmod >= 5 ], + [AC_DEFINE(HAVE_KMOD, 1, [Define if kmod is available]) have_kmod=yes], have_kmod=no) + if test "x$have_kmod" = xno -a "x$enable_kmod" = xyes; then + AC_MSG_ERROR([*** kmod support requested but libraries not found]) + fi +fi +AM_CONDITIONAL(HAVE_KMOD, [test "$have_kmod" = "yes"]) + +# ------------------------------------------------------------------------------ +have_blkid=no +AC_ARG_ENABLE(blkid, AS_HELP_STRING([--disable-blkid], [disable blkid support])) +if test "x$enable_blkid" != "xno"; then + PKG_CHECK_MODULES(BLKID, [ blkid >= 2.20 ], + [AC_DEFINE(HAVE_BLKID, 1, [Define if blkid is available]) have_blkid=yes], have_blkid=no) + if test "x$have_blkid" = xno -a "x$enable_blkid" = xyes; then + AC_MSG_ERROR([*** blkid support requested but libraries not found]) + fi +fi +AM_CONDITIONAL(HAVE_BLKID, [test "$have_blkid" = "yes"]) + +# ------------------------------------------------------------------------------ +have_ima=yes +AC_ARG_ENABLE([ima], AS_HELP_STRING([--disable-ima],[Disable optional IMA support]), + [case "${enableval}" in + yes) have_ima=yes ;; + no) have_ima=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --disable-ima) ;; + esac], + [have_ima=yes]) + +if test "x${have_ima}" != xno ; then + AC_DEFINE(HAVE_IMA, 1, [Define if IMA is available]) +fi + +# ------------------------------------------------------------------------------ +have_chkconfig=yes +AC_ARG_ENABLE([chkconfig], AS_HELP_STRING([--disable-chkconfig],[Disable optional chkconfig support]), + [case "${enableval}" in + yes) have_chkconfig=yes ;; + no) have_chkconfig=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --disable-chkconfig) ;; + esac], + [AC_PATH_PROG(CHKCONFIG, chkconfig) + if test -z "$CHKCONFIG"; then + have_chkconfig=no + else + have_chkconfig=yes + fi]) + +if test "x${have_chkconfig}" != xno ; then + AC_DEFINE(HAVE_CHKCONFIG, 1, [Define if CHKCONFIG is available]) +fi + +# ------------------------------------------------------------------------------ +have_selinux=no +AC_ARG_ENABLE(selinux, AS_HELP_STRING([--disable-selinux], [Disable optional SELINUX support])) +if test "x$enable_selinux" != "xno"; then + PKG_CHECK_MODULES([SELINUX], [libselinux >= 2.1.9], + [AC_DEFINE(HAVE_SELINUX, 1, [Define if SELinux is available]) have_selinux=yes], have_selinux=no) + if test "x$have_selinux" = xno -a "x$enable_selinux" = xyes; then + AC_MSG_ERROR([*** SELinux support requested but libraries not found]) + fi +fi +AM_CONDITIONAL(HAVE_SELINUX, [test "$have_selinux" = "yes"]) +if test "x${have_selinux}" != xno ; then + sushell=/sbin/sushell +else + sushell=/bin/bash +fi +AC_SUBST(sushell) + +# ------------------------------------------------------------------------------ +have_xz=no +AC_ARG_ENABLE(xz, AS_HELP_STRING([--disable-xz], [Disable optional XZ support])) +if test "x$enable_xz" != "xno"; then + PKG_CHECK_MODULES(XZ, [ liblzma ], + [AC_DEFINE(HAVE_XZ, 1, [Define if XZ is available]) have_xz=yes], have_xz=no) + if test "x$have_xz" = xno -a "x$enable_xz" = xyes; then + AC_MSG_ERROR([*** Xz support requested but libraries not found]) + fi +fi +AM_CONDITIONAL(HAVE_XZ, [test "$have_xz" = "yes"]) + +# ------------------------------------------------------------------------------ +AC_ARG_ENABLE([tcpwrap], + AS_HELP_STRING([--disable-tcpwrap],[Disable optional TCP wrappers support]), + [case "${enableval}" in + yes) have_tcpwrap=yes ;; + no) have_tcpwrap=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --disable-tcpwrap) ;; + esac], + [have_tcpwrap=auto]) + +if test "x${have_tcpwrap}" != xno ; then + ACX_LIBWRAP + if test "x${LIBWRAP_LIBS}" = x ; then + if test "x$have_tcpwrap" = xyes ; then + AC_MSG_ERROR([*** TCP wrappers support not found.]) + fi + have_tcpwrap=no + else + have_tcpwrap=yes + fi +else + LIBWRAP_LIBS= +fi +AC_SUBST(LIBWRAP_LIBS) + +# ------------------------------------------------------------------------------ +AC_ARG_ENABLE([pam], + AS_HELP_STRING([--disable-pam],[Disable optional PAM support]), + [case "${enableval}" in + yes) have_pam=yes ;; + no) have_pam=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --disable-pam) ;; + esac], + [have_pam=auto]) + +if test "x${have_pam}" != xno ; then + AC_CHECK_HEADERS( + [security/pam_modules.h security/pam_modutil.h security/pam_ext.h], + [have_pam=yes], + [if test "x$have_pam" = xyes ; then + AC_MSG_ERROR([*** PAM headers not found.]) + fi]) + + AC_CHECK_LIB( + [pam], + [pam_syslog], + [have_pam=yes], + [if test "x$have_pam" = xyes ; then + AC_MSG_ERROR([*** libpam not found.]) + fi]) + + if test "x$have_pam" = xyes ; then + PAM_LIBS="-lpam -lpam_misc" + AC_DEFINE(HAVE_PAM, 1, [PAM available]) + else + have_pam=no + fi +else + PAM_LIBS= +fi +AC_SUBST(PAM_LIBS) +AM_CONDITIONAL([HAVE_PAM], [test "x$have_pam" != xno]) + +# ------------------------------------------------------------------------------ +AC_ARG_ENABLE([acl], + AS_HELP_STRING([--disable-acl],[Disable optional ACL support]), + [case "${enableval}" in + yes) have_acl=yes ;; + no) have_acl=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --disable-acl) ;; + esac], + [have_acl=auto]) + +if test "x${have_acl}" != xno ; then + AC_CHECK_HEADERS( + [sys/acl.h acl/libacl.h], + [have_acl=yes], + [if test "x$have_acl" = xyes ; then + AC_MSG_ERROR([*** ACL headers not found.]) + fi]) + + AC_CHECK_LIB( + [acl], + [acl_get_file], + [have_acl=yes], + [if test "x$have_acl" = xyes ; then + AC_MSG_ERROR([*** libacl not found.]) + fi]) + + if test "x$have_acl" = xyes ; then + ACL_LIBS="-lacl" + AC_DEFINE(HAVE_ACL, 1, [ACL available]) + else + have_acl=no + fi +else + ACL_LIBS= +fi +AC_SUBST(ACL_LIBS) +AM_CONDITIONAL([HAVE_ACL], [test "x$have_acl" != xno]) + +# ------------------------------------------------------------------------------ +AC_ARG_ENABLE([xattr], + AS_HELP_STRING([--disable-xattr],[Disable optional XATTR support]), + [case "${enableval}" in + yes) have_xattr=yes ;; + no) have_xattr=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --disable-xattr) ;; + esac], + [have_xattr=auto]) + +if test "x${have_xattr}" != xno ; then + AC_CHECK_HEADERS( + [attr/xattr.h], + [have_xattr=yes], + [if test "x$have_xattr" = xyes ; then + AC_MSG_ERROR([*** XATTR headers not found.]) + fi]) + + AC_CHECK_LIB( + [attr], + [fsetxattr], + [have_xattr=yes], + [if test "x$have_xattr" = xyes ; then + AC_MSG_ERROR([*** libattr not found.]) + fi]) + + if test "x$have_xattr" = xyes ; then + XATTR_LIBS="-lattr" + AC_DEFINE(HAVE_XATTR, 1, [XATTR available]) + else + have_xattr=no + fi +else + XATTR_LIBS= +fi +AC_SUBST(XATTR_LIBS) +AM_CONDITIONAL([HAVE_XATTR], [test "x$have_xattr" != xno]) + +# ------------------------------------------------------------------------------ +AC_ARG_ENABLE([gcrypt], + AS_HELP_STRING([--disable-gcrypt],[Disable optional GCRYPT support]), + [case "${enableval}" in + yes) have_gcrypt=yes ;; + no) have_gcrypt=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --disable-gcrypt) ;; + esac], + [have_gcrypt=auto]) + +if test "x${have_gcrypt}" != xno ; then + AM_PATH_LIBGCRYPT( + [1.4.5], + [have_gcrypt=yes], + [if test "x$have_gcrypt" = xyes ; then + AC_MSG_ERROR([*** GCRYPT headers not found.]) + fi]) + + if test "x$have_gcrypt" = xyes ; then + GCRYPT_LIBS="$LIBGCRYPT_LIBS" + GCRYPT_CFLAGS="$LIBGCRYPT_CFLAGS" + AC_DEFINE(HAVE_GCRYPT, 1, [GCRYPT available]) + else + have_gcrypt=no + fi +else + GCRYPT_LIBS= + GCRYPT_CFLAGS= +fi +AC_SUBST(GCRYPT_LIBS) +AC_SUBST(GCRYPT_CFLAGS) +AM_CONDITIONAL([HAVE_GCRYPT], [test "x$have_gcrypt" != xno]) + +# ------------------------------------------------------------------------------ +AC_ARG_ENABLE([audit], + AS_HELP_STRING([--disable-audit],[Disable optional AUDIT support]), + [case "${enableval}" in + yes) have_audit=yes ;; + no) have_audit=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --disable-audit) ;; + esac], + [have_audit=auto]) + +if test "x${have_audit}" != xno ; then + AC_CHECK_HEADERS( + [libaudit.h], + [have_audit=yes], + [if test "x$have_audit" = xyes ; then + AC_MSG_ERROR([*** AUDIT headers not found.]) + fi]) + + AC_CHECK_LIB( + [audit], + [audit_open], + [have_audit=yes], + [if test "x$have_audit" = xyes ; then + AC_MSG_ERROR([*** libaudit not found.]) + fi]) + + if test "x$have_audit" = xyes ; then + AUDIT_LIBS="-laudit" + AC_DEFINE(HAVE_AUDIT, 1, [AUDIT available]) + else + have_audit=no + fi +else + AUDIT_LIBS= +fi +AC_SUBST(AUDIT_LIBS) + +# ------------------------------------------------------------------------------ +have_libcryptsetup=no +AC_ARG_ENABLE(libcryptsetup, AS_HELP_STRING([--disable-libcryptsetup], [disable libcryptsetup tools])) +if test "x$enable_libcryptsetup" != "xno"; then + PKG_CHECK_MODULES(LIBCRYPTSETUP, [ libcryptsetup >= 1.4.2 ], + [AC_DEFINE(HAVE_LIBCRYPTSETUP, 1, [Define if libcryptsetup is available]) have_libcryptsetup=yes], have_libcryptsetup=no) + if test "x$have_libcryptsetup" = xno -a "x$enable_libcryptsetup" = xyes; then + AC_MSG_ERROR([*** libcryptsetup support requested but libraries not found]) + fi +fi +AM_CONDITIONAL(HAVE_LIBCRYPTSETUP, [test "$have_libcryptsetup" = "yes"]) + +# ------------------------------------------------------------------------------ +have_qrencode=no +AC_ARG_ENABLE(qrencode, AS_HELP_STRING([--disable-qrencode], [disable qrencode support])) +if test "x$enable_qrencode" != "xno"; then + PKG_CHECK_MODULES(QRENCODE, [ libqrencode ], + [AC_DEFINE(HAVE_QRENCODE, 1, [Define if qrencode is available]) have_qrencode=yes], have_qrencode=no) + if test "x$have_qrencode" = xno -a "x$enable_qrencode" = xyes; then + AC_MSG_ERROR([*** qrencode support requested but libraries not found]) + fi +fi +AM_CONDITIONAL(HAVE_QRENCODE, [test "$have_qrencode" = "yes"]) + +# ------------------------------------------------------------------------------ +have_microhttpd=no +AC_ARG_ENABLE(microhttpd, AS_HELP_STRING([--disable-microhttpd], [disable microhttpd support])) +if test "x$enable_microhttpd" != "xno"; then + PKG_CHECK_MODULES(MICROHTTPD, [libmicrohttpd >= 0.9.5], + [AC_DEFINE(HAVE_MICROHTTPD, 1, [Define if microhttpd is available]) have_microhttpd=yes], have_microhttpd=no) + if test "x$have_microhttpd" = xno -a "x$enable_microhttpd" = xyes; then + AC_MSG_ERROR([*** microhttpd support requested but libraries not found]) + fi +fi +AM_CONDITIONAL(HAVE_MICROHTTPD, [test "$have_microhttpd" = "yes"]) + +# ------------------------------------------------------------------------------ +have_binfmt=no +AC_ARG_ENABLE(binfmt, AS_HELP_STRING([--disable-binfmt], [disable binfmt tool])) +if test "x$enable_binfmt" != "xno"; then + have_binfmt=yes +fi +AM_CONDITIONAL(ENABLE_BINFMT, [test "$have_binfmt" = "yes"]) + +# ------------------------------------------------------------------------------ +have_vconsole=no +AC_ARG_ENABLE(vconsole, AS_HELP_STRING([--disable-vconsole], [disable vconsole tool])) +if test "x$enable_vconsole" != "xno"; then + have_vconsole=yes +fi +AM_CONDITIONAL(ENABLE_VCONSOLE, [test "$have_vconsole" = "yes"]) + +# ------------------------------------------------------------------------------ +have_readahead=no +AC_ARG_ENABLE(readahead, AS_HELP_STRING([--disable-readahead], [disable readahead tools])) +if test "x$enable_readahead" != "xno"; then + have_readahead=yes +fi +AM_CONDITIONAL(ENABLE_READAHEAD, [test "$have_readahead" = "yes"]) + +# ------------------------------------------------------------------------------ +have_quotacheck=no +AC_ARG_ENABLE(quotacheck, AS_HELP_STRING([--disable-quotacheck], [disable quotacheck tools])) +if test "x$enable_quotacheck" != "xno"; then + have_quotacheck=yes +fi +AM_CONDITIONAL(ENABLE_QUOTACHECK, [test "$have_quotacheck" = "yes"]) + +# ------------------------------------------------------------------------------ +have_randomseed=no +AC_ARG_ENABLE(randomseed, AS_HELP_STRING([--disable-randomseed], [disable randomseed tools])) +if test "x$enable_randomseed" != "xno"; then + have_randomseed=yes +fi +AM_CONDITIONAL(ENABLE_RANDOMSEED, [test "$have_randomseed" = "yes"]) + +# ------------------------------------------------------------------------------ +have_logind=no +AC_ARG_ENABLE(logind, AS_HELP_STRING([--disable-logind], [disable login daemon])) +if test "x$enable_logind" != "xno"; then + have_logind=yes +fi +AM_CONDITIONAL(ENABLE_LOGIND, [test "$have_logind" = "yes"]) +AS_IF([test "$have_logind" = "yes"], [ AC_DEFINE(HAVE_LOGIND, [1], [Logind support available]) ]) + +# ------------------------------------------------------------------------------ +have_hostnamed=no +AC_ARG_ENABLE(hostnamed, AS_HELP_STRING([--disable-hostnamed], [disable hostname daemon])) +if test "x$enable_hostnamed" != "xno"; then + have_hostnamed=yes +fi +AM_CONDITIONAL(ENABLE_HOSTNAMED, [test "$have_hostnamed" = "yes"]) + +# ------------------------------------------------------------------------------ +have_timedated=no +AC_ARG_ENABLE(timedated, AS_HELP_STRING([--disable-timedated], [disable timedate daemon])) +if test "x$enable_timedated" != "xno"; then + have_timedated=yes +fi +AM_CONDITIONAL(ENABLE_TIMEDATED, [test "$have_timedated" = "yes"]) + +# ------------------------------------------------------------------------------ +have_localed=no +AC_ARG_ENABLE(localed, AS_HELP_STRING([--disable-localed], [disable locale daemon])) +if test "x$enable_localed" != "xno"; then + have_localed=yes +fi +AM_CONDITIONAL(ENABLE_LOCALED, [test "$have_localed" = "yes"]) + +# ------------------------------------------------------------------------------ +have_coredump=no +AC_ARG_ENABLE(coredump, AS_HELP_STRING([--disable-coredump], [disable coredump hook])) +if test "x$enable_coredump" != "xno"; then + have_coredump=yes +fi +AM_CONDITIONAL(ENABLE_COREDUMP, [test "$have_coredump" = "yes"]) + +# ------------------------------------------------------------------------------ +AC_ARG_WITH(rc-local-script-path-start, + AS_HELP_STRING([--with-rc-local-script-path-start=PATH], + [Path to /etc/rc.local]), + [RC_LOCAL_SCRIPT_PATH_START="$withval"], + [RC_LOCAL_SCRIPT_PATH_START="/etc/rc.local"]) + +AC_ARG_WITH(rc-local-script-path-stop, + AS_HELP_STRING([--with-rc-local-script-path-stop=PATH], + [Path to /usr/sbin/halt.local]), + [RC_LOCAL_SCRIPT_PATH_STOP="$withval"], + [RC_LOCAL_SCRIPT_PATH_STOP="/usr/sbin/halt.local"]) + +AC_DEFINE_UNQUOTED(RC_LOCAL_SCRIPT_PATH_START, ["$RC_LOCAL_SCRIPT_PATH_START"], [Path of /etc/rc.local script]) +AC_DEFINE_UNQUOTED(RC_LOCAL_SCRIPT_PATH_STOP, ["$RC_LOCAL_SCRIPT_PATH_STOP"], [Path of /usr/sbin/halt.local script]) + +AC_SUBST(RC_LOCAL_SCRIPT_PATH_START) +AC_SUBST(RC_LOCAL_SCRIPT_PATH_STOP) + +# ------------------------------------------------------------------------------ +AC_ARG_WITH(kbd-loadkeys, + AS_HELP_STRING([--with-kbd-loadkeys=PATH], + [Path to loadkeys]), + [KBD_LOADKEYS="$withval"], + [KBD_LOADKEYS="/usr/bin/loadkeys"]) + +AC_ARG_WITH(kbd-setfont, + AS_HELP_STRING([--with-kbd-setfont=PATH], + [Path to setfont]), + [KBD_SETFONT="$withval"], + [KBD_SETFONT="/usr/bin/setfont"]) + +AC_DEFINE_UNQUOTED(KBD_LOADKEYS, ["$KBD_LOADKEYS"], [Path of loadkeys]) +AC_DEFINE_UNQUOTED(KBD_SETFONT, ["$KBD_SETFONT"], [Path of setfont]) + +AC_SUBST(KBD_LOADKEYS) +AC_SUBST(KBD_SETFONT) + +# ------------------------------------------------------------------------------ +AC_ARG_WITH(firmware-path, + AS_HELP_STRING([--with-firmware-path=DIR[[[:DIR[...]]]]], + [Firmware search path (default=ROOTPREFIX/lib/firmware/updates:ROOTPREFIX/lib/firmware)]), + [], [with_firmware_path="$rootprefix/lib/firmware/updates:$rootprefix/lib/firmware"]) +OLD_IFS=$IFS +IFS=: +for i in $with_firmware_path; do + if test "x${FIRMWARE_PATH}" = "x"; then + FIRMWARE_PATH="\\\"${i}/\\\"" + else + FIRMWARE_PATH="${FIRMWARE_PATH}, \\\"${i}/\\\"" + fi +done +IFS=$OLD_IFS +AC_SUBST([FIRMWARE_PATH], [$FIRMWARE_PATH]) + +# ------------------------------------------------------------------------------ +AC_ARG_ENABLE([gudev], + AS_HELP_STRING([--disable-gudev], [disable Gobject libudev support @<:@default=enabled@:>@]), + [], [enable_gudev=yes]) +AS_IF([test "x$enable_gudev" = "xyes"], [ PKG_CHECK_MODULES([GLIB], [glib-2.0 >= 2.22.0 gobject-2.0 >= 2.22.0]) ]) +AM_CONDITIONAL([ENABLE_GUDEV], [test "x$enable_gudev" = "xyes"]) + +# ------------------------------------------------------------------------------ +AC_ARG_ENABLE([keymap], + AS_HELP_STRING([--disable-keymap], [disable keymap fixup support @<:@default=enabled@:>@]), + [], [enable_keymap=yes]) +AS_IF([test "x$enable_keymap" = "xyes"], [ + AC_PATH_PROG([GPERF], [gperf]) + if test -z "$GPERF"; then + AC_MSG_ERROR([gperf is needed]) + fi + + AC_CHECK_HEADER([linux/input.h], [:], AC_MSG_ERROR([kernel headers not found])) + AC_SUBST([INCLUDE_PREFIX], [$(echo '#include ' | eval $ac_cpp -E - | sed -n '/linux\/input.h/ {s:.*"\(.*\)/linux/input.h".*:\1:; p; q}')]) +]) +AM_CONDITIONAL([ENABLE_KEYMAP], [test "x$enable_keymap" = "xyes"]) + +# ------------------------------------------------------------------------------ +have_manpages=no +AC_ARG_ENABLE(manpages, AS_HELP_STRING([--disable-manpages], [disable manpages])) +AS_IF([test "x$enable_manpages" != xno], [ + AS_IF([test "x$enable_manpages" = xyes -a "x$XSLTPROC" = x], [ + AC_MSG_ERROR([*** Manpages requested but xsltproc not found]) + ]) + AS_IF([test "x$XSLTPROC" != x], [have_manpages=yes]) +]) +AM_CONDITIONAL(ENABLE_MANPAGES, [test "x$have_manpages" = "xyes"]) + +# ------------------------------------------------------------------------------ + +# Location of the init scripts as mandated by LSB +SYSTEM_SYSVINIT_PATH=/etc/init.d +SYSTEM_SYSVRCND_PATH=/etc/rc.d +M4_DEFINES= + +AC_ARG_WITH([sysvinit-path], + [AS_HELP_STRING([--with-sysvinit-path=PATH], + [Specify the path to where the SysV init scripts are located])], + [SYSTEM_SYSVINIT_PATH="$withval"], + []) + +AC_ARG_WITH([sysvrcd-path], + [AS_HELP_STRING([--with-sysvrcd-path=PATH], + [Specify the path to the base directory for the SysV rcN.d directories])], + [SYSTEM_SYSVRCND_PATH="$withval"], + []) + +if test "x${SYSTEM_SYSVINIT_PATH}" != "x" -a "x${SYSTEM_SYSVRCND_PATH}" != "x"; then + AC_DEFINE(HAVE_SYSV_COMPAT, [], [SysV init scripts and rcN.d links are supported.]) + SYSTEM_SYSV_COMPAT="yes" + M4_DEFINES="$M4_DEFINES -DHAVE_SYSV_COMPAT" +elif test "x${SYSTEM_SYSVINIT_PATH}" != "x" -o "x${SYSTEM_SYSVRCND_PATH}" != "x"; then + AC_MSG_ERROR([*** You need both --with-sysvinit-path=PATH and --with-sysvrcd-path=PATH to enable SysV compatibility support, or both empty to disable it.]) +else + SYSTEM_SYSV_COMPAT="no" +fi + +AC_SUBST(SYSTEM_SYSVINIT_PATH) +AC_SUBST(SYSTEM_SYSVRCND_PATH) +AC_SUBST(M4_DEFINES) + +AM_CONDITIONAL(HAVE_SYSV_COMPAT, test "$SYSTEM_SYSV_COMPAT" = "yes") + +AC_ARG_WITH([tty-gid], + [AS_HELP_STRING([--with-tty-gid=GID], + [Specify the numeric GID of the 'tty' group])], + [AC_DEFINE_UNQUOTED(TTY_GID, [$withval], [GID of the 'tty' group])], + []) + +AC_ARG_WITH([dbuspolicydir], + AS_HELP_STRING([--with-dbuspolicydir=DIR], [D-Bus policy directory]), + [], + [with_dbuspolicydir=`pkg-config --variable=sysconfdir dbus-1`/dbus-1/system.d]) + +AC_ARG_WITH([dbussessionservicedir], + AS_HELP_STRING([--with-dbussessionservicedir=DIR], [D-Bus session service directory]), + [], + [with_dbussessionservicedir=`pkg-config --variable=session_bus_services_dir dbus-1`]) + +AC_ARG_WITH([dbussystemservicedir], + AS_HELP_STRING([--with-dbussystemservicedir=DIR], [D-Bus system service directory]), + [], + [with_dbussystemservicedir=`pkg-config --variable=session_bus_services_dir dbus-1`/../system-services]) + +AC_ARG_WITH([dbusinterfacedir], + AS_HELP_STRING([--with-dbusinterfacedir=DIR], [D-Bus interface directory]), + [], + [with_dbusinterfacedir=`pkg-config --variable=session_bus_services_dir dbus-1`/../interfaces]) + +AC_ARG_WITH([rootprefix], + AS_HELP_STRING([--with-rootprefix=DIR], [rootfs directory prefix for config files and kernel modules]), + [], [with_rootprefix=${ac_default_prefix}]) + +AC_ARG_WITH([rootlibdir], + AS_HELP_STRING([--with-rootlibdir=DIR], [Root directory for libraries necessary for boot]), + [], + [with_rootlibdir=${libdir}]) + +AC_ARG_WITH([pamlibdir], + AS_HELP_STRING([--with-pamlibdir=DIR], [Directory for PAM modules]), + [], + [with_pamlibdir=${with_rootlibdir}/security]) + +AC_ARG_ENABLE([split-usr], + AS_HELP_STRING([--enable-split-usr], [Assume that /bin, /sbin aren\'t symlinks into /usr]), + [], + [AS_IF([test "x${ac_default_prefix}" != "x${with_rootprefix}"], [ + enable_split_usr=yes + ], [ + enable_split_usr=no + ])]) + +AS_IF([test "x${enable_split_usr}" = "xyes"], [ + AC_DEFINE(HAVE_SPLIT_USR, 1, [Define if /bin, /sbin aren't symlinks into /usr]) +]) + +AC_SUBST([dbuspolicydir], [$with_dbuspolicydir]) +AC_SUBST([dbussessionservicedir], [$with_dbussessionservicedir]) +AC_SUBST([dbussystemservicedir], [$with_dbussystemservicedir]) +AC_SUBST([dbusinterfacedir], [$with_dbusinterfacedir]) +AC_SUBST([pamlibdir], [$with_pamlibdir]) +AC_SUBST([rootprefix], [$with_rootprefix]) +AC_SUBST([rootlibdir], [$with_rootlibdir]) + +AC_CONFIG_FILES([ + Makefile po/Makefile.in + docs/libudev/Makefile + docs/libudev/version.xml + docs/gudev/Makefile + docs/gudev/version.xml +]) + +AC_OUTPUT +AC_MSG_RESULT([ + $PACKAGE_NAME $VERSION + + libcryptsetup: ${have_libcryptsetup} + tcpwrap: ${have_tcpwrap} + PAM: ${have_pam} + AUDIT: ${have_audit} + IMA: ${have_ima} + SELinux: ${have_selinux} + XZ: ${have_xz} + ACL: ${have_acl} + XATTR: ${have_xattr} + GCRYPT: ${have_gcrypt} + QRENCODE: ${have_qrencode} + MICROHTTPD: ${have_microhttpd} + CHKCONFIG: ${have_chkconfig} + binfmt: ${have_binfmt} + vconsole: ${have_vconsole} + readahead: ${have_readahead} + quotacheck: ${have_quotacheck} + randomseed: ${have_randomseed} + logind: ${have_logind} + hostnamed: ${have_hostnamed} + timedated: ${have_timedated} + localed: ${have_localed} + coredump: ${have_coredump} + kmod: ${have_kmod} + blkid: ${have_blkid} + gudev: ${enable_gudev} + gintrospection: ${enable_introspection} + keymap: ${enable_keymap} + Python: ${have_python} + Python Headers: ${have_python_devel} + man pages: ${have_manpages} + gtk-doc: ${enable_gtk_doc} + Split /usr: ${enable_split_usr} + SysV compatibility: ${SYSTEM_SYSV_COMPAT} + + prefix: ${prefix} + rootprefix: ${with_rootprefix} + sysconf dir: ${sysconfdir} + datarootdir: ${datarootdir} + includedir: ${includedir} + include_prefix: ${INCLUDE_PREFIX} + lib dir: ${libdir} + rootlib dir: ${with_rootlibdir} + SysV init scripts: ${SYSTEM_SYSVINIT_PATH} + SysV rc?.d directories: ${SYSTEM_SYSVRCND_PATH} + Build Python: ${PYTHON} + Installation Python: ${PYTHON_BINARY} + firmware path: ${FIRMWARE_PATH} + PAM modules dir: ${with_pamlibdir} + D-Bus policy dir: ${with_dbuspolicydir} + D-Bus session dir: ${with_dbussessionservicedir} + D-Bus system dir: ${with_dbussystemservicedir} + D-Bus interfaces dir: ${with_dbusinterfacedir} + Extra start script: ${RC_LOCAL_SCRIPT_PATH_START} + Extra stop script: ${RC_LOCAL_SCRIPT_PATH_STOP} + + CFLAGS: ${OUR_CFLAGS} ${CFLAGS} + CPPLAGS: ${OUR_CPPFLAGS} ${CPPFLAGS} + LDFLAGS: ${OUR_LDFLAGS} ${LDFLAGS} + PYTHON_CFLAGS: ${PYTHON_CFLAGS} + PYTHON_LIBS: ${PYTHON_LIBS} +]) diff --git a/docs/.gitignore b/docs/.gitignore new file mode 100644 index 000000000..e9fed442c --- /dev/null +++ b/docs/.gitignore @@ -0,0 +1 @@ +/gtk-doc.make diff --git a/docs/Makefile b/docs/Makefile new file mode 120000 index 000000000..bd1047548 --- /dev/null +++ b/docs/Makefile @@ -0,0 +1 @@ +../src/Makefile \ No newline at end of file diff --git a/docs/gudev/.gitignore b/docs/gudev/.gitignore new file mode 100644 index 000000000..e6f2371ab --- /dev/null +++ b/docs/gudev/.gitignore @@ -0,0 +1,19 @@ +/*.bak +/gtk-doc.make +/version.xml +/Makefile +/gudev-overrides.txt +/gudev-decl-list.txt +/gudev-decl.txt +/gudev-undeclared.txt +/gudev-undocumented.txt +/gudev-unused.txt +/gudev.args +/gudev.hierarchy +/gudev.interfaces +/gudev.prerequisites +/gudev.signals +/html/ +/xml/ +/*.stamp +/tmpl/ diff --git a/docs/gudev/Makefile.am b/docs/gudev/Makefile.am new file mode 100644 index 000000000..26c8652b0 --- /dev/null +++ b/docs/gudev/Makefile.am @@ -0,0 +1,113 @@ +## Process this file with automake to produce Makefile.in + +# We require automake 1.10 at least. +AUTOMAKE_OPTIONS = 1.10 color-tests + +# This is a blank Makefile.am for using gtk-doc. +# Copy this to your project's API docs directory and modify the variables to +# suit your project. See the GTK+ Makefiles in gtk+/docs/reference for examples +# of using the various options. + +# The name of the module, e.g. 'glib'. +DOC_MODULE=gudev + +# Uncomment for versioned docs and specify the version of the module, e.g. '2'. +#DOC_MODULE_VERSION=2 + +# The top-level SGML file. You can change this if you want to. +DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.xml + +# The directory containing the source code. Relative to $(srcdir). +# gtk-doc will search all .c & .h files beneath here for inline comments +# documenting the functions and macros. +# e.g. DOC_SOURCE_DIR=../../../gtk +DOC_SOURCE_DIR=$(top_srcdir)/src/gudev $(top_builddir)/src/gudev + +# Extra options to pass to gtkdoc-scangobj. Not normally needed. +SCANGOBJ_OPTIONS= + +# Extra options to supply to gtkdoc-scan. +# e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED" +SCAN_OPTIONS= + +# Extra options to supply to gtkdoc-mkdb. +# e.g. MKDB_OPTIONS=--sgml-mode --output-format=xml +MKDB_OPTIONS=--xml-mode --output-format=xml --name-space=g_udev + +# Extra options to supply to gtkdoc-mktmpl +# e.g. MKTMPL_OPTIONS=--only-section-tmpl +MKTMPL_OPTIONS= + +# Extra options to supply to gtkdoc-mkhtml +MKHTML_OPTIONS=--path=$(abs_srcdir) --path=$(abs_builddir) + +# Extra options to supply to gtkdoc-fixref. Not normally needed. +# e.g. FIXXREF_OPTIONS=--extra-dir=../gdk-pixbuf/html --extra-dir=../gdk/html +FIXXREF_OPTIONS=>/dev/null 2>&1 + +# Used for dependencies. The docs will be rebuilt if any of these change. +# e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h +# e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c +HFILE_GLOB=$(top_srcdir)/src/gudev/*.h +CFILE_GLOB=$(top_srcdir)/src/gudev/*.c + +# Extra header to include when scanning, which are not under DOC_SOURCE_DIR +# e.g. EXTRA_HFILES=$(top_srcdir}/contrib/extra.h +EXTRA_HFILES= + +# Header files to ignore when scanning. Use base file name, no paths +# e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h +IGNORE_HFILES=gudevenumtypes.h gudevmarshal.h + +# Images to copy into HTML directory. +# e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png +HTML_IMAGES= + +# Extra SGML files that are included by $(DOC_MAIN_SGML_FILE). +# e.g. content_files=running.sgml building.sgml changes-2.0.sgml +content_files = version.xml + +# SGML files where gtk-doc abbrevations (#GtkWidget) are expanded +# These files must be listed here *and* in content_files +# e.g. expand_content_files=running.sgml +expand_content_files= + +# Hack, hack. You silly gtk-doc, you must not add CFLAGS multiple +# times when calling gcc; it surely can not work with options that must +# be listed only once. +# Kill CFLAGS here because gtk-doc thinks adding CFLAGS to CC _and_ also +# adding CFLAGS itself again would work. +override CFLAGS= +override LDFLAGS= + +# CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library. +# Only needed if you are using gtkdoc-scangobj to dynamically query widget +# signals and properties. +# e.g. GTKDOC_CFLAGS=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS) +# e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib) +GTKDOC_CFLAGS = \ + $(GLIB_CFLAGS) \ + -I$(top_srcdir)/src/gudev \ + -I$(top_builddir)/src/gudev + +GTKDOC_LIBS = \ + $(GLIB_LIBS) \ + $(top_builddir)/libgudev-1.0.la + +# This includes the standard gtk-doc make rules, copied by gtkdocize. +include $(top_srcdir)/docs/gtk-doc.make + +# Other files to distribute +# e.g. EXTRA_DIST += version.xml.in +EXTRA_DIST += version.xml.in + +# Files not to distribute +# for --rebuild-types in $(SCAN_OPTIONS), e.g. $(DOC_MODULE).types +# for --rebuild-sections in $(SCAN_OPTIONS) e.g. $(DOC_MODULE)-sections.txt +#DISTCLEANFILES += + +# Comment this out if you want your docs-status tested during 'make check' +if ENABLE_GTK_DOC +TESTS_ENVIRONMENT = cd $(top_srcdir) +TESTS = $(GTKDOC_CHECK) +endif diff --git a/docs/gudev/gudev-docs.xml b/docs/gudev/gudev-docs.xml new file mode 100644 index 000000000..3e7e50acd --- /dev/null +++ b/docs/gudev/gudev-docs.xml @@ -0,0 +1,52 @@ + + +]> + + + GUdev Reference Manual + + For version &version; — the latest version of this + documentation can be found at + + http://www.freedesktop.org/software/systemd/gudev/ + . + + + 2009-2012 + David Zeuthen <davidz@redhat.com> + Bastien Nocera <hadess@hadess.net> + + + + + API Reference + + + + + + + Object Hierarchy + + + + + API Index + + + + + Index of new symbols in 165 + + + + + Index of deprecated API + + + + + diff --git a/docs/gudev/gudev-sections.txt b/docs/gudev/gudev-sections.txt new file mode 100644 index 000000000..b25c13bcb --- /dev/null +++ b/docs/gudev/gudev-sections.txt @@ -0,0 +1,100 @@ +
+gudevclient +GUdevClient +GUdevClient +GUdevClientClass +GUdevDeviceType +GUdevDeviceNumber +g_udev_client_new +g_udev_client_query_by_subsystem +g_udev_client_query_by_device_number +g_udev_client_query_by_device_file +g_udev_client_query_by_sysfs_path +g_udev_client_query_by_subsystem_and_name + +G_UDEV_CLIENT +G_UDEV_IS_CLIENT +G_UDEV_TYPE_CLIENT +g_udev_client_get_type +G_UDEV_CLIENT_CLASS +G_UDEV_IS_CLIENT_CLASS +G_UDEV_CLIENT_GET_CLASS + +GUdevClientPrivate +
+ +
+gudevdevice +GUdevDevice +GUdevDevice +GUdevDeviceClass +g_udev_device_get_subsystem +g_udev_device_get_devtype +g_udev_device_get_name +g_udev_device_get_number +g_udev_device_get_sysfs_path +g_udev_device_get_driver +g_udev_device_get_action +g_udev_device_get_seqnum +g_udev_device_get_device_type +g_udev_device_get_device_number +g_udev_device_get_device_file +g_udev_device_get_device_file_symlinks +g_udev_device_get_parent +g_udev_device_get_parent_with_subsystem +g_udev_device_get_tags +g_udev_device_get_is_initialized +g_udev_device_get_usec_since_initialized +g_udev_device_get_property_keys +g_udev_device_has_property +g_udev_device_get_property +g_udev_device_get_property_as_int +g_udev_device_get_property_as_uint64 +g_udev_device_get_property_as_double +g_udev_device_get_property_as_boolean +g_udev_device_get_property_as_strv +g_udev_device_get_sysfs_attr +g_udev_device_get_sysfs_attr_as_int +g_udev_device_get_sysfs_attr_as_uint64 +g_udev_device_get_sysfs_attr_as_double +g_udev_device_get_sysfs_attr_as_boolean +g_udev_device_get_sysfs_attr_as_strv + +G_UDEV_DEVICE +G_UDEV_IS_DEVICE +G_UDEV_TYPE_DEVICE +g_udev_device_get_type +G_UDEV_DEVICE_CLASS +G_UDEV_IS_DEVICE_CLASS +G_UDEV_DEVICE_GET_CLASS + +GUdevDevicePrivate +
+ +
+gudevenumerator +GUdevEnumerator +GUdevEnumerator +GUdevEnumeratorClass +g_udev_enumerator_new +g_udev_enumerator_add_match_subsystem +g_udev_enumerator_add_nomatch_subsystem +g_udev_enumerator_add_match_sysfs_attr +g_udev_enumerator_add_nomatch_sysfs_attr +g_udev_enumerator_add_match_property +g_udev_enumerator_add_match_name +g_udev_enumerator_add_match_tag +g_udev_enumerator_add_match_is_initialized +g_udev_enumerator_add_sysfs_path +g_udev_enumerator_execute + +G_UDEV_ENUMERATOR +G_UDEV_IS_ENUMERATOR +G_UDEV_TYPE_ENUMERATOR +g_udev_enumerator_get_type +G_UDEV_ENUMERATOR_CLASS +G_UDEV_IS_ENUMERATOR_CLASS +G_UDEV_ENUMERATOR_GET_CLASS + +GUdevEnumeratorPrivate +
diff --git a/docs/gudev/gudev.types b/docs/gudev/gudev.types new file mode 100644 index 000000000..a89857a04 --- /dev/null +++ b/docs/gudev/gudev.types @@ -0,0 +1,4 @@ +g_udev_device_type_get_type +g_udev_device_get_type +g_udev_client_get_type +g_udev_enumerator_get_type diff --git a/docs/gudev/version.xml.in b/docs/gudev/version.xml.in new file mode 100644 index 000000000..d78bda934 --- /dev/null +++ b/docs/gudev/version.xml.in @@ -0,0 +1 @@ +@VERSION@ diff --git a/docs/libudev/.gitignore b/docs/libudev/.gitignore new file mode 100644 index 000000000..f8dd67c50 --- /dev/null +++ b/docs/libudev/.gitignore @@ -0,0 +1,19 @@ +/gtk-doc.make +/version.xml +/Makefile +/libudev-overrides.txt +/libudev-decl-list.txt +/libudev-decl.txt +/libudev-undeclared.txt +/libudev-undocumented.txt +/libudev-unused.txt +/libudev.args +/libudev.hierarchy +/libudev.interfaces +/libudev.prerequisites +/libudev.signals +/html/ +/xml/ +/*.stamp +/*.bak +/tmpl/ diff --git a/docs/libudev/Makefile.am b/docs/libudev/Makefile.am new file mode 100644 index 000000000..87196e858 --- /dev/null +++ b/docs/libudev/Makefile.am @@ -0,0 +1,107 @@ +## Process this file with automake to produce Makefile.in + +# We require automake 1.10 at least. +AUTOMAKE_OPTIONS = 1.10 color-tests + +# This is a blank Makefile.am for using gtk-doc. +# Copy this to your project's API docs directory and modify the variables to +# suit your project. See the GTK+ Makefiles in gtk+/docs/reference for examples +# of using the various options. + +# The name of the module, e.g. 'glib'. +DOC_MODULE=libudev + +# Uncomment for versioned docs and specify the version of the module, e.g. '2'. +#DOC_MODULE_VERSION=2 + +# The top-level SGML file. You can change this if you want to. +DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.xml + +# The directory containing the source code. Relative to $(srcdir). +# gtk-doc will search all .c & .h files beneath here for inline comments +# documenting the functions and macros. +# e.g. DOC_SOURCE_DIR=../../../gtk +DOC_SOURCE_DIR=$(top_srcdir)/src/libudev + +# Extra options to pass to gtkdoc-scangobj. Not normally needed. +SCANGOBJ_OPTIONS= + +# Extra options to supply to gtkdoc-scan. +# e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED" +SCAN_OPTIONS= + +# Extra options to supply to gtkdoc-mkdb. +# e.g. MKDB_OPTIONS=--sgml-mode --output-format=xml +MKDB_OPTIONS=--xml-mode --output-format=xml --name-space=udev + +# Extra options to supply to gtkdoc-mktmpl +# e.g. MKTMPL_OPTIONS=--only-section-tmpl +MKTMPL_OPTIONS= + +# Extra options to supply to gtkdoc-mkhtml +MKHTML_OPTIONS=--path=$(abs_srcdir) --path=$(abs_builddir) + +# Extra options to supply to gtkdoc-fixref. Not normally needed. +# e.g. FIXXREF_OPTIONS=--extra-dir=../gdk-pixbuf/html --extra-dir=../gdk/html +FIXXREF_OPTIONS=>/dev/null 2>&1 + +# Used for dependencies. The docs will be rebuilt if any of these change. +# e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h +# e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c +HFILE_GLOB=$(top_srcdir)/src/libudev/libudev*.h +CFILE_GLOB=$(top_srcdir)/src/libudev/libudev*.c + +# Extra header to include when scanning, which are not under DOC_SOURCE_DIR +# e.g. EXTRA_HFILES=$(top_srcdir}/contrib/extra.h +EXTRA_HFILES= + +# Header files to ignore when scanning. Use base file name, no paths +# e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h +IGNORE_HFILES = libudev-private.h libudev-hwdb-def.h + +# Images to copy into HTML directory. +# e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png +HTML_IMAGES= + +# Extra SGML files that are included by $(DOC_MAIN_SGML_FILE). +# e.g. content_files=running.sgml building.sgml changes-2.0.sgml +content_files = version.xml + +# SGML files where gtk-doc abbrevations (#GtkWidget) are expanded +# These files must be listed here *and* in content_files +# e.g. expand_content_files=running.sgml +expand_content_files= + +# Hack, hack. You silly gtk-doc, you must not add CFLAGS multiple +# times when calling gcc; it surely can not work with options that must +# be listed only once. +# Kill CFLAGS here because gtk-doc thinks adding CFLAGS to CC _and_ also +# adding CFLAGS itself again would work. +override CFLAGS= +override LDFLAGS= + +# CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library. +# Only needed if you are using gtkdoc-scangobj to dynamically query widget +# signals and properties. +# e.g. GTKDOC_CFLAGS=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS) +# e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib) +GTKDOC_CFLAGS= +GTKDOC_LIBS= + +# This includes the standard gtk-doc make rules, copied by gtkdocize. +include $(top_srcdir)/docs/gtk-doc.make + +# Other files to distribute +# e.g. EXTRA_DIST += version.xml.in +EXTRA_DIST += version.xml.in + +# Files not to distribute +# for --rebuild-types in $(SCAN_OPTIONS), e.g. $(DOC_MODULE).types +# for --rebuild-sections in $(SCAN_OPTIONS) e.g. $(DOC_MODULE)-sections.txt +#DISTCLEANFILES += + +# Comment this out if you want your docs-status tested during 'make check' +if ENABLE_GTK_DOC +TESTS_ENVIRONMENT = cd $(top_srcdir) +TESTS = $(GTKDOC_CHECK) +endif diff --git a/docs/libudev/libudev-docs.xml b/docs/libudev/libudev-docs.xml new file mode 100644 index 000000000..454cd3164 --- /dev/null +++ b/docs/libudev/libudev-docs.xml @@ -0,0 +1,40 @@ + + +]> + + + libudev Reference Manual + + For version &version; — the latest version of this + documentation can be found at + + http://www.freedesktop.org/software/systemd/libudev/ + . + + + 2009-2012 + Kay Sievers <kay@vrfy.org> + + + + + API Reference + + + + + + + + + + + + + Index + + + diff --git a/docs/libudev/libudev-sections.txt b/docs/libudev/libudev-sections.txt new file mode 100644 index 000000000..067a3f5b9 --- /dev/null +++ b/docs/libudev/libudev-sections.txt @@ -0,0 +1,134 @@ +
+libudev +udev +udev +udev_ref +udev_unref +udev_new +udev_set_log_fn +udev_get_log_priority +udev_set_log_priority +udev_get_userdata +udev_set_userdata +
+ +
+libudev-list +udev_list +udev_list_entry +udev_list_entry_get_next +udev_list_entry_get_by_name +udev_list_entry_get_name +udev_list_entry_get_value +udev_list_entry_foreach +
+ +
+libudev-device +udev_device +udev_device +udev_device_ref +udev_device_unref +udev_device_get_udev +udev_device_new_from_syspath +udev_device_new_from_devnum +udev_device_new_from_subsystem_sysname +udev_device_new_from_device_id +udev_device_new_from_environment +udev_device_get_parent +udev_device_get_parent_with_subsystem_devtype +udev_device_get_devpath +udev_device_get_subsystem +udev_device_get_devtype +udev_device_get_syspath +udev_device_get_sysname +udev_device_get_sysnum +udev_device_get_devnode +udev_device_get_is_initialized +udev_device_get_devlinks_list_entry +udev_device_get_properties_list_entry +udev_device_get_tags_list_entry +udev_device_get_property_value +udev_device_get_driver +udev_device_get_devnum +udev_device_get_action +udev_device_get_sysattr_value +udev_device_get_sysattr_list_entry +udev_device_get_seqnum +udev_device_get_usec_since_initialized +udev_device_has_tag +
+ +
+libudev-monitor +udev_monitor +udev_monitor +udev_monitor_ref +udev_monitor_unref +udev_monitor_get_udev +udev_monitor_new_from_netlink +udev_monitor_enable_receiving +udev_monitor_set_receive_buffer_size +udev_monitor_get_fd +udev_monitor_receive_device +udev_monitor_filter_add_match_subsystem_devtype +udev_monitor_filter_add_match_tag +udev_monitor_filter_update +udev_monitor_filter_remove +
+ +
+libudev-enumerate +udev_enumerate +udev_enumerate +udev_enumerate_ref +udev_enumerate_unref +udev_enumerate_get_udev +udev_enumerate_new +udev_enumerate_add_match_subsystem +udev_enumerate_add_nomatch_subsystem +udev_enumerate_add_match_sysattr +udev_enumerate_add_nomatch_sysattr +udev_enumerate_add_match_property +udev_enumerate_add_match_tag +udev_enumerate_add_match_parent +udev_enumerate_add_match_is_initialized +udev_enumerate_add_match_sysname +udev_enumerate_add_syspath +udev_enumerate_scan_devices +udev_enumerate_scan_subsystems +udev_enumerate_get_list_entry +
+ +
+libudev-queue +udev_queue +udev_queue +udev_queue_ref +udev_queue_unref +udev_queue_get_udev +udev_queue_new +udev_queue_get_udev_is_active +udev_queue_get_queue_is_empty +udev_queue_get_seqnum_is_finished +udev_queue_get_seqnum_sequence_is_finished +udev_queue_get_queued_list_entry +udev_queue_get_kernel_seqnum +udev_queue_get_udev_seqnum +
+ +
+libudev-hwdb +udev_hwdb +udev_hwdb +udev_hwdb_ref +udev_hwdb_unref +udev_hwdb_new +udev_hwdb_get_properties_list_entry +
+ +
+libudev-util +udev_util +udev_util_encode_string +
diff --git a/docs/libudev/libudev.types b/docs/libudev/libudev.types new file mode 100644 index 000000000..e69de29bb diff --git a/docs/libudev/version.xml.in b/docs/libudev/version.xml.in new file mode 100644 index 000000000..d78bda934 --- /dev/null +++ b/docs/libudev/version.xml.in @@ -0,0 +1 @@ +@VERSION@ diff --git a/docs/sysvinit/.gitignore b/docs/sysvinit/.gitignore new file mode 100644 index 000000000..c3fea7424 --- /dev/null +++ b/docs/sysvinit/.gitignore @@ -0,0 +1 @@ +/README diff --git a/docs/sysvinit/Makefile b/docs/sysvinit/Makefile new file mode 120000 index 000000000..50be21181 --- /dev/null +++ b/docs/sysvinit/Makefile @@ -0,0 +1 @@ +../../src/Makefile \ No newline at end of file diff --git a/docs/sysvinit/README.in b/docs/sysvinit/README.in new file mode 100644 index 000000000..996402d06 --- /dev/null +++ b/docs/sysvinit/README.in @@ -0,0 +1,27 @@ +You are looking for the traditional init scripts in @SYSTEM_SYSVINIT_PATH@, +and they are gone? + +Here's an explanation on what's going on: + +You are running a systemd-based OS where traditional init scripts have +been replaced by native systemd services files. Service files provide +very similar functionality to init scripts. To make use of service +files simply invoke "systemctl", which will output a list of all +currently running services (and other units). Use "systemctl +list-unit-files" to get a listing of all known unit files, including +stopped, disabled and masked ones. Use "systemctl start +foobar.service" and "systemctl stop foobar.service" to start or stop a +service, respectively. For further details, please refer to +systemctl(1). + +Note that traditional init scripts continue to function on a systemd +system. An init script @SYSTEM_SYSVINIT_PATH@/foobar is implicitly mapped +into a service unit foobar.service during system initialization. + +Thank you! + +Further reading: + man:systemctl(1) + man:systemd(1) + http://0pointer.de/blog/projects/systemd-for-admins-3.html + http://www.freedesktop.org/wiki/Software/systemd/Incompatibilities diff --git a/docs/var-log/.gitignore b/docs/var-log/.gitignore new file mode 100644 index 000000000..c3fea7424 --- /dev/null +++ b/docs/var-log/.gitignore @@ -0,0 +1 @@ +/README diff --git a/docs/var-log/Makefile b/docs/var-log/Makefile new file mode 120000 index 000000000..50be21181 --- /dev/null +++ b/docs/var-log/Makefile @@ -0,0 +1 @@ +../../src/Makefile \ No newline at end of file diff --git a/docs/var-log/README.in b/docs/var-log/README.in new file mode 100644 index 000000000..2e64fb196 --- /dev/null +++ b/docs/var-log/README.in @@ -0,0 +1,26 @@ +You are looking for the traditional text log files in @VARLOGDIR@, and +they are gone? + +Here's an explanation on what's going on: + +You are running a systemd-based OS where traditional syslog has been +replaced with the Journal. The journal stores the same (and more) +information as classic syslog. To make use of the journal and access +the collected log data simply invoke "journalctl", which will output +the logs in the identical text-based format the syslog files in +@VARLOGDIR@ used to be. For further details, please refer to +journalctl(1). + +Alternatively, consider installing one of the traditional syslog +implementations available for your distribution, which will generate +the classic log files for you. Syslog implementations such as +syslog-ng or rsyslog may be installed side-by-side with the journal +and will continue to function the way they always did. + +Thank you! + +Further reading: + man:journalctl(1) + man:systemd-journald.service(8) + man:journald.conf(5) + http://0pointer.de/blog/projects/the-journal.html diff --git a/hwdb/.gitignore b/hwdb/.gitignore new file mode 100644 index 000000000..a29233b5e --- /dev/null +++ b/hwdb/.gitignore @@ -0,0 +1,4 @@ +/pci.ids +/usb.ids +/oui.txt +/iab.txt diff --git a/hwdb/20-OUI.hwdb b/hwdb/20-OUI.hwdb new file mode 100644 index 000000000..be9819836 --- /dev/null +++ b/hwdb/20-OUI.hwdb @@ -0,0 +1,64139 @@ +# This file is part of systemd. +# +# Data imported from: +# http://standards.ieee.org/develop/regauth/oui/oui.txt +# http://standards.ieee.org/develop/regauth/iab/iab.txt + +OUI:0050C2000* + ID_OUI_FROM_DATABASE=T.L.S. Corp. + +OUI:0050C2001* + ID_OUI_FROM_DATABASE=JMBS Developpements + +OUI:0050C2002* + ID_OUI_FROM_DATABASE=Integrated Automation Solutions + +OUI:0050C2003* + ID_OUI_FROM_DATABASE=Microsoft + +OUI:0050C2004* + ID_OUI_FROM_DATABASE=SCI Technology Inc. + +OUI:0050C2005* + ID_OUI_FROM_DATABASE=GD California, Inc. + +OUI:0050C2006* + ID_OUI_FROM_DATABASE=Project Management Enterprises, Inc. + +OUI:0050C2007* + ID_OUI_FROM_DATABASE=Clive Green & Co. Ltd. + +OUI:0050C2008* + ID_OUI_FROM_DATABASE=Portable Add-Ons + +OUI:0050C2009* + ID_OUI_FROM_DATABASE=Datakinetics Ltd. + +OUI:0050C200A* + ID_OUI_FROM_DATABASE=Tharsys + +OUI:0050C200B* + ID_OUI_FROM_DATABASE=IO Limited + +OUI:0050C200C* + ID_OUI_FROM_DATABASE=Vbrick Systems Inc. + +OUI:0050C200D* + ID_OUI_FROM_DATABASE=Opus Telecom Inc. + +OUI:0050C200E* + ID_OUI_FROM_DATABASE=TTTech + +OUI:0050C200F* + ID_OUI_FROM_DATABASE=XLN-t + +OUI:0050C2010* + ID_OUI_FROM_DATABASE=Moisture Systems + +OUI:0050C2011* + ID_OUI_FROM_DATABASE=BIHL & Wiedemann GmbH + +OUI:0050C2012* + ID_OUI_FROM_DATABASE=Floware System Solutions Ltd. + +OUI:0050C2013* + ID_OUI_FROM_DATABASE=Sensys Technologies Inc. + +OUI:0050C2014* + ID_OUI_FROM_DATABASE=Canal + + +OUI:0050C2015* + ID_OUI_FROM_DATABASE=Leroy Automatique Industrielle + +OUI:0050C2016* + ID_OUI_FROM_DATABASE=DSP Design Ltd. + +OUI:0050C2017* + ID_OUI_FROM_DATABASE=Hunter Technology Inc. + +OUI:0050C2018* + ID_OUI_FROM_DATABASE=CAD-UL GmbH + +OUI:0050C2019* + ID_OUI_FROM_DATABASE=Emtac Technology Corp. + +OUI:0050C201A* + ID_OUI_FROM_DATABASE=Skylake Talix + +OUI:0050C201B* + ID_OUI_FROM_DATABASE=Cross Products Ltd. + +OUI:0050C201C* + ID_OUI_FROM_DATABASE=Tadiran Scopus + +OUI:0050C201D* + ID_OUI_FROM_DATABASE=Princeton Gamma Tech + +OUI:0050C201E* + ID_OUI_FROM_DATABASE=CallTech International Limited + +OUI:0050C201F* + ID_OUI_FROM_DATABASE=KBS Industrieelektronik GmbH + +OUI:0050C2020* + ID_OUI_FROM_DATABASE=Icon Research Ltd. + +OUI:0050C2021* + ID_OUI_FROM_DATABASE=DRS Technologies Canada Co. + +OUI:0050C2022* + ID_OUI_FROM_DATABASE=Ashling Microsystems Ltd. + +OUI:0050C2023* + ID_OUI_FROM_DATABASE=Zabacom, Inc. + +OUI:0050C2024* + ID_OUI_FROM_DATABASE=IPITEK + +OUI:0050C2025* + ID_OUI_FROM_DATABASE=Teracom Telematica Ltda. + +OUI:0050C2026* + ID_OUI_FROM_DATABASE=Abatis Systems Corp. + +OUI:0050C2027* + ID_OUI_FROM_DATABASE=Industrial Control Links + +OUI:0050C2028* + ID_OUI_FROM_DATABASE=The Frensch Corporation (Pty) Ltd. + +OUI:0050C2029* + ID_OUI_FROM_DATABASE=Grossenbacher Systeme AG + +OUI:0050C202A* + ID_OUI_FROM_DATABASE=VersaLogic Corp. + +OUI:0050C202B* + ID_OUI_FROM_DATABASE=Nova Engineering Inc. + +OUI:0050C202C* + ID_OUI_FROM_DATABASE=Narrowband Telecommunications + +OUI:0050C202D* + ID_OUI_FROM_DATABASE=Innocor LTD + +OUI:0050C202E* + ID_OUI_FROM_DATABASE=Turtle Mountain Corp + +OUI:0050C202F* + ID_OUI_FROM_DATABASE=Sinetica Corp + +OUI:0050C2030* + ID_OUI_FROM_DATABASE=Lockheed Martin Tactical Defense Systems Eagan + +OUI:0050C2031* + ID_OUI_FROM_DATABASE=Eloquence Ltd + +OUI:0050C2032* + ID_OUI_FROM_DATABASE=MotionIO + +OUI:0050C2033* + ID_OUI_FROM_DATABASE=Doble Engineering Company + +OUI:0050C2034* + ID_OUI_FROM_DATABASE=Ing. Buero W. Kanis GmbH + +OUI:0050C2035* + ID_OUI_FROM_DATABASE=Alliant Techsystems, Inc. + +OUI:0050C2036* + ID_OUI_FROM_DATABASE=Arcturus Networks Inc. + +OUI:0050C2037* + ID_OUI_FROM_DATABASE=E.I.S.M. + +OUI:0050C2038* + ID_OUI_FROM_DATABASE=Ardmona Foods Limites + +OUI:0050C2039* + ID_OUI_FROM_DATABASE=Apex Signal Corp + +OUI:0050C203A* + ID_OUI_FROM_DATABASE=PLLB Elettronica SPA + +OUI:0050C203B* + ID_OUI_FROM_DATABASE=VNR Electronique SA + +OUI:0050C203C* + ID_OUI_FROM_DATABASE=BrainBoxes Ltd + +OUI:0050C203D* + ID_OUI_FROM_DATABASE=ISDN Gateway Technology AG + +OUI:0050C203E* + ID_OUI_FROM_DATABASE=MSU UK Ltd + +OUI:0050C203F* + ID_OUI_FROM_DATABASE=Celotek Corp + +OUI:0050C2040* + ID_OUI_FROM_DATABASE=MiSPO Co., Ltd. + +OUI:0050C2041* + ID_OUI_FROM_DATABASE=Damler Chrysler Rail System (Signal) AB + +OUI:0050C2042* + ID_OUI_FROM_DATABASE=B.E.A.R. Solutions (Australasia) Pty, Ltd + +OUI:0050C2043* + ID_OUI_FROM_DATABASE=Curtis, Inc. + +OUI:0050C2045* + ID_OUI_FROM_DATABASE=Chase Manhattan Bank + +OUI:0050C2047* + ID_OUI_FROM_DATABASE=B. R. Electronics + +OUI:0050C2048* + ID_OUI_FROM_DATABASE=Cybectec Inc. + +OUI:0050C2049* + ID_OUI_FROM_DATABASE=Computer Concepts Corp + +OUI:0050C204A* + ID_OUI_FROM_DATABASE=Telecom Analysis Systems, LP + +OUI:0050C204B* + ID_OUI_FROM_DATABASE=Tecstar Demo Systems Division + +OUI:0050C204C* + ID_OUI_FROM_DATABASE=New Standard Engineering NV + +OUI:0050C204E* + ID_OUI_FROM_DATABASE=Industrial Electronic Engineers, Inc. + +OUI:0050C204F* + ID_OUI_FROM_DATABASE=Luma Corporation + +OUI:0050C2050* + ID_OUI_FROM_DATABASE=Dataprobe, Inc. + +OUI:0050C2051* + ID_OUI_FROM_DATABASE=JSR Ultrasonics + +OUI:0050C2052* + ID_OUI_FROM_DATABASE=Mayo Foundation + +OUI:0050C2054* + ID_OUI_FROM_DATABASE=Optionexist Limited + +OUI:0050C2055* + ID_OUI_FROM_DATABASE=San Castle Technologies, Inc. + +OUI:0050C2056* + ID_OUI_FROM_DATABASE=Base 2 + +OUI:0050C2057* + ID_OUI_FROM_DATABASE=Lite F GmBH + +OUI:0050C2058* + ID_OUI_FROM_DATABASE=Vision Research, Inc. + +OUI:0050C2059* + ID_OUI_FROM_DATABASE=Austco Communication Systems Pty, Ltd + +OUI:0050C205A* + ID_OUI_FROM_DATABASE=Sonifex Ltd + +OUI:0050C205B* + ID_OUI_FROM_DATABASE=Radiometer Medical A/S + +OUI:0050C205C* + ID_OUI_FROM_DATABASE=Nortel Networks PLC (UK) + +OUI:0050C205D* + ID_OUI_FROM_DATABASE=Ignitus Communications, LLC + +OUI:0050C205E* + ID_OUI_FROM_DATABASE=DIVA Systems + +OUI:0050C205F* + ID_OUI_FROM_DATABASE=Malden Electronics Ltd + +OUI:0050C2061* + ID_OUI_FROM_DATABASE=Simple Network Magic Corporation + +OUI:0050C2063* + ID_OUI_FROM_DATABASE=Ticketmaster Corp + +OUI:0050C2065* + ID_OUI_FROM_DATABASE=Clever Devices, Ltd. + +OUI:0050C2067* + ID_OUI_FROM_DATABASE=Riverlink Computers, Ltd. + +OUI:0050C2068* + ID_OUI_FROM_DATABASE=Seabridge + +OUI:0050C2069* + ID_OUI_FROM_DATABASE=EC Elettronica S.R.L. + +OUI:0050C206A* + ID_OUI_FROM_DATABASE=Unimark + +OUI:0050C206B* + ID_OUI_FROM_DATABASE=NCast Corporation + +OUI:0050C206C* + ID_OUI_FROM_DATABASE=WaveCom Electronics, Inc. + +OUI:0050C206D* + ID_OUI_FROM_DATABASE=Advanced Signal Corp. + +OUI:0050C206E* + ID_OUI_FROM_DATABASE=Avtron Manufacturing Inc. + +OUI:0050C206F* + ID_OUI_FROM_DATABASE=Digital Services Group + +OUI:0050C2070* + ID_OUI_FROM_DATABASE=Katchall Technologies Group + +OUI:0050C2071* + ID_OUI_FROM_DATABASE=NetVision Telecom + +OUI:0050C2072* + ID_OUI_FROM_DATABASE=Neuberger Gebaeudeautomation GmbH & Co. + +OUI:0050C2073* + ID_OUI_FROM_DATABASE=Alstom Signalling Ltd. + +OUI:0050C2074* + ID_OUI_FROM_DATABASE=Edge Tech Co., Ltd. + +OUI:0050C2075* + ID_OUI_FROM_DATABASE=ENTTEC Pty Ltd. + +OUI:0050C2076* + ID_OUI_FROM_DATABASE=Litton Guidance & Control Systems + +OUI:0050C2077* + ID_OUI_FROM_DATABASE=Saco Smartvision Inc. + +OUI:0050C2078* + ID_OUI_FROM_DATABASE=Reselec AG + +OUI:0050C2079* + ID_OUI_FROM_DATABASE=Flextel S.p.A + +OUI:0050C207A* + ID_OUI_FROM_DATABASE=RadioTel + +OUI:0050C207B* + ID_OUI_FROM_DATABASE=Trikon Technologies Ltd. + +OUI:0050C207C* + ID_OUI_FROM_DATABASE=PLLB elettronica spa + +OUI:0050C207D* + ID_OUI_FROM_DATABASE=Caspian Networks + +OUI:0050C207E* + ID_OUI_FROM_DATABASE=JL-teknik + +OUI:0050C207F* + ID_OUI_FROM_DATABASE=Dunti Corporation + +OUI:0050C2080* + ID_OUI_FROM_DATABASE=AIM + +OUI:0050C2081* + ID_OUI_FROM_DATABASE=Matuschek Messtechnik GmbH + +OUI:0050C2082* + ID_OUI_FROM_DATABASE=GFI Chrono Time + +OUI:0050C2083* + ID_OUI_FROM_DATABASE=ARD SA + +OUI:0050C2084* + ID_OUI_FROM_DATABASE=DIALOG4 System Engineering GmbH + +OUI:0050C2085* + ID_OUI_FROM_DATABASE=Crossport Systems + +OUI:0050C2086* + ID_OUI_FROM_DATABASE=Validyne Engineering Corp. + +OUI:0050C2087* + ID_OUI_FROM_DATABASE=Monitor Business Machines Ltd. + +OUI:0050C2088* + ID_OUI_FROM_DATABASE=TELINC Corporation + +OUI:0050C2089* + ID_OUI_FROM_DATABASE=Fenwal Italia S.P.A. + +OUI:0050C208A* + ID_OUI_FROM_DATABASE=Rising Edge Technologies + +OUI:0050C208B* + ID_OUI_FROM_DATABASE=HYPERCHIP Inc. + +OUI:0050C208C* + ID_OUI_FROM_DATABASE=IP Unity + +OUI:0050C208D* + ID_OUI_FROM_DATABASE=Kylink Communications Corp. + +OUI:0050C208E* + ID_OUI_FROM_DATABASE=BSQUARE + +OUI:0050C208F* + ID_OUI_FROM_DATABASE=General Industries Argentina + +OUI:0050C2090* + ID_OUI_FROM_DATABASE=Invensys Controls Network Systems + +OUI:0050C2091* + ID_OUI_FROM_DATABASE=StorLogic, Inc. + +OUI:0050C2092* + ID_OUI_FROM_DATABASE=DigitAll World Co., Ltd + +OUI:0050C2093* + ID_OUI_FROM_DATABASE=KOREALINK + +OUI:0050C2094* + ID_OUI_FROM_DATABASE=Analytical Spectral Devices, Inc. + +OUI:0050C2095* + ID_OUI_FROM_DATABASE=SEATECH + +OUI:0050C2096* + ID_OUI_FROM_DATABASE=Utronix Elektronikutreckling AB + +OUI:0050C2097* + ID_OUI_FROM_DATABASE=IMV Invertomatic + +OUI:0050C2098* + ID_OUI_FROM_DATABASE=EPEL Industrial, S.A. + +OUI:0050C2099* + ID_OUI_FROM_DATABASE=Case Information & Communications + +OUI:0050C209A* + ID_OUI_FROM_DATABASE=NBO Development Center Sekusui Chemical Co. Ltd. + +OUI:0050C209B* + ID_OUI_FROM_DATABASE=Seffle Instrument AB + +OUI:0050C209C* + ID_OUI_FROM_DATABASE=RF Applications, Inc. + +OUI:0050C209D* + ID_OUI_FROM_DATABASE=ZELPOS + +OUI:0050C209E* + ID_OUI_FROM_DATABASE=Infinitec Networks, Inc. + +OUI:0050C209F* + ID_OUI_FROM_DATABASE=MetaWave Vedeo Systems + +OUI:0050C20A0* + ID_OUI_FROM_DATABASE=CYNAPS + +OUI:0050C20A1* + ID_OUI_FROM_DATABASE=Visable Genetics, Inc. + +OUI:0050C20A2* + ID_OUI_FROM_DATABASE=Jäger Computergesteuerte Messtechnik GmbH + +OUI:0050C20A3* + ID_OUI_FROM_DATABASE=BaSyTec GmbH + +OUI:0050C20A4* + ID_OUI_FROM_DATABASE=Bounty Systems Pty Ltd. + +OUI:0050C20A5* + ID_OUI_FROM_DATABASE=Mobiltex Data Ltd. + +OUI:0050C20A6* + ID_OUI_FROM_DATABASE=Arula Systems, Inc. + +OUI:0050C20A7* + ID_OUI_FROM_DATABASE=WaterCove Networks + +OUI:0050C20A8* + ID_OUI_FROM_DATABASE=Kaveri Networks + +OUI:0050C20A9* + ID_OUI_FROM_DATABASE=Radiant Networks Plc + +OUI:0050C20AA* + ID_OUI_FROM_DATABASE=Log-In, Inc. + +OUI:0050C20AB* + ID_OUI_FROM_DATABASE=Fastware.Net, LLC + +OUI:0050C20AC* + ID_OUI_FROM_DATABASE=Honeywell GNO + +OUI:0050C20AD* + ID_OUI_FROM_DATABASE=BMC Messsysteme GmbH + +OUI:0050C20AE* + ID_OUI_FROM_DATABASE=Zarak Systems Corp. + +OUI:0050C20AF* + ID_OUI_FROM_DATABASE=Latus Lightworks, Inc. + +OUI:0050C20B0* + ID_OUI_FROM_DATABASE=LMI Technologies, Inc. + +OUI:0050C20B1* + ID_OUI_FROM_DATABASE=Beeline Networks, Inc. + +OUI:0050C20B2* + ID_OUI_FROM_DATABASE=R F Micro Devices + +OUI:0050C20B3* + ID_OUI_FROM_DATABASE=SMX Corporation + +OUI:0050C20B4* + ID_OUI_FROM_DATABASE=Wavefly Corporation + +OUI:0050C20B5* + ID_OUI_FROM_DATABASE=Extreme Copper, Inc. + +OUI:0050C20B6* + ID_OUI_FROM_DATABASE=ApSecure Technologies (Canada), Inc. + +OUI:0050C20B7* + ID_OUI_FROM_DATABASE=RYMIC + +OUI:0050C20B8* + ID_OUI_FROM_DATABASE=LAN Controls, Inc. + +OUI:0050C20B9* + ID_OUI_FROM_DATABASE=Helmut Mauell GmbH + +OUI:0050C20BA* + ID_OUI_FROM_DATABASE=Pro-Active + +OUI:0050C20BB* + ID_OUI_FROM_DATABASE=MAZet GmbH + +OUI:0050C20BC* + ID_OUI_FROM_DATABASE=Infolink Software AG + +OUI:0050C20BD* + ID_OUI_FROM_DATABASE=Tattile + +OUI:0050C20BE* + ID_OUI_FROM_DATABASE=Stella Electronics & Tagging + +OUI:0050C20C0* + ID_OUI_FROM_DATABASE=Imigix Ltd. + +OUI:0050C20C1* + ID_OUI_FROM_DATABASE=Casabyte + +OUI:0050C20C2* + ID_OUI_FROM_DATABASE=Alchemy Semiconductor, Inc. + +OUI:0050C20C3* + ID_OUI_FROM_DATABASE=Tonbu, Inc. + +OUI:0050C20C4* + ID_OUI_FROM_DATABASE=InterEpoch Technology, Inc. + +OUI:0050C20C5* + ID_OUI_FROM_DATABASE=SAIA Burgess Controls AG + +OUI:0050C20C6* + ID_OUI_FROM_DATABASE=Advanced Medical Information Technologies, Inc. + +OUI:0050C20C7* + ID_OUI_FROM_DATABASE=TransComm Technology System, Inc. + +OUI:0050C20C8* + ID_OUI_FROM_DATABASE=The Trane Company + +OUI:0050C20C9* + ID_OUI_FROM_DATABASE=DSS Networks, Inc. + +OUI:0050C20CA* + ID_OUI_FROM_DATABASE=J D Richards + +OUI:0050C20CB* + ID_OUI_FROM_DATABASE=STUDIEL + +OUI:0050C20CC* + ID_OUI_FROM_DATABASE=AlphaMedia Co., Ltd + +OUI:0050C20CD* + ID_OUI_FROM_DATABASE=LINET OY + +OUI:0050C20CE* + ID_OUI_FROM_DATABASE=RFL Electronics, Inc. + +OUI:0050C20CF* + ID_OUI_FROM_DATABASE=PCSC + +OUI:0050C20D0* + ID_OUI_FROM_DATABASE=Telegrang AB + +OUI:0050C20D1* + ID_OUI_FROM_DATABASE=Renaissance Networking, Inc. + +OUI:0050C20D2* + ID_OUI_FROM_DATABASE=Real World Computing Partnership + +OUI:0050C20D3* + ID_OUI_FROM_DATABASE=Lake Technology, Ltd. + +OUI:0050C20D4* + ID_OUI_FROM_DATABASE=Palm, Inc. + +OUI:0050C20D5* + ID_OUI_FROM_DATABASE=Zelax + +OUI:0050C20D6* + ID_OUI_FROM_DATABASE=Inco Startec GmbH + +OUI:0050C20D7* + ID_OUI_FROM_DATABASE=Summit Avionics, Inc. + +OUI:0050C20D8* + ID_OUI_FROM_DATABASE=Charlotte's Web Networks + +OUI:0050C20D9* + ID_OUI_FROM_DATABASE=Loewe Opta GmbH + +OUI:0050C20DA* + ID_OUI_FROM_DATABASE=Motion Analysis Corp. + +OUI:0050C20DB* + ID_OUI_FROM_DATABASE=Cyberex + +OUI:0050C20DC* + ID_OUI_FROM_DATABASE=Elbit Systems Ltd. + +OUI:0050C20DD* + ID_OUI_FROM_DATABASE=Interisa Electronica, S.A. + +OUI:0050C20DE* + ID_OUI_FROM_DATABASE=Frederick Engineering + +OUI:0050C20DF* + ID_OUI_FROM_DATABASE=Innovation Institute, Inc. + +OUI:0050C20E0* + ID_OUI_FROM_DATABASE=EMAC, Inc. + +OUI:0050C20E1* + ID_OUI_FROM_DATABASE=Inspiration Technology P/L + +OUI:0050C20E2* + ID_OUI_FROM_DATABASE=Visual Circuits Corp. + +OUI:0050C20E3* + ID_OUI_FROM_DATABASE=Lanex S.A. + +OUI:0050C20E4* + ID_OUI_FROM_DATABASE=Collabo Tec. Co., Ltd. + +OUI:0050C20E5* + ID_OUI_FROM_DATABASE=Clearwater Networks + +OUI:0050C20E6* + ID_OUI_FROM_DATABASE=RouteFree, Inc. + +OUI:0050C20E7* + ID_OUI_FROM_DATABASE=Century Geophysical Corp. + +OUI:0050C20E8* + ID_OUI_FROM_DATABASE=Audio Design Associates, Inc. + +OUI:0050C20E9* + ID_OUI_FROM_DATABASE=Smartmedia LLC + +OUI:0050C20EA* + ID_OUI_FROM_DATABASE=iReady Corporation + +OUI:0050C20EB* + ID_OUI_FROM_DATABASE=iREZ Technologies LLC + +OUI:0050C20EC* + ID_OUI_FROM_DATABASE=Keith & Koep GmbH + +OUI:0050C20ED* + ID_OUI_FROM_DATABASE=Valley Products Corporation + +OUI:0050C20EE* + ID_OUI_FROM_DATABASE=Industrial Indexing Systems, Inc. + +OUI:0050C20EF* + ID_OUI_FROM_DATABASE=Movaz Networks, Inc. + +OUI:0050C20F0* + ID_OUI_FROM_DATABASE=VHB Technologies, Inc. + +OUI:0050C20F1* + ID_OUI_FROM_DATABASE=Polyvision Corporation + +OUI:0050C20F2* + ID_OUI_FROM_DATABASE=KMS Systems, Inc. + +OUI:0050C20F3* + ID_OUI_FROM_DATABASE=Young Computer Co., Ltd. + +OUI:0050C20F4* + ID_OUI_FROM_DATABASE=Sysnet Co., Ltd. + +OUI:0050C20F5* + ID_OUI_FROM_DATABASE=Spectra Technologies Holding Co., Ltd. + +OUI:0050C20F6* + ID_OUI_FROM_DATABASE=Carl Baasel Lasertechnik GmbH + +OUI:0050C20F7* + ID_OUI_FROM_DATABASE=Foss NIRSystems, Inc. + +OUI:0050C20F8* + ID_OUI_FROM_DATABASE=Tecnint HTE S.r.L. + +OUI:0050C20F9* + ID_OUI_FROM_DATABASE=Raven Industries + +OUI:0050C20FA* + ID_OUI_FROM_DATABASE=GE Lubrizol, LLC + +OUI:0050C20FB* + ID_OUI_FROM_DATABASE=PIUSYS Co., Ltd. + +OUI:0050C20FC* + ID_OUI_FROM_DATABASE=Kimmon Manufacturing Co., Ltd. + +OUI:0050C20FD* + ID_OUI_FROM_DATABASE=Inducomp Corporation + +OUI:0050C20FE* + ID_OUI_FROM_DATABASE=Energy ICT + +OUI:0050C20FF* + ID_OUI_FROM_DATABASE=IPAXS Corporation + +OUI:0050C2100* + ID_OUI_FROM_DATABASE=Corelatus A.B. + +OUI:0050C2101* + ID_OUI_FROM_DATABASE=LAUD Electronic Design AS + +OUI:0050C2102* + ID_OUI_FROM_DATABASE=Million Tech Development Ltd. + +OUI:0050C2103* + ID_OUI_FROM_DATABASE=Green Hills Software, Inc. + +OUI:0050C2104* + ID_OUI_FROM_DATABASE=Adescom Inc. + +OUI:0050C2105* + ID_OUI_FROM_DATABASE=Lumentis AB + +OUI:0050C2106* + ID_OUI_FROM_DATABASE=MATSUOKA + +OUI:0050C2107* + ID_OUI_FROM_DATABASE=NewHer Systems + +OUI:0050C2108* + ID_OUI_FROM_DATABASE=Balogh S.A. + +OUI:0050C2109* + ID_OUI_FROM_DATABASE=ITK Dr. Kassen GmbH + +OUI:0050C210A* + ID_OUI_FROM_DATABASE=Quinx AG + +OUI:0050C210B* + ID_OUI_FROM_DATABASE=MarekMicro GmbH + +OUI:0050C210C* + ID_OUI_FROM_DATABASE=Photonic Bridges, Inc. + +OUI:0050C210D* + ID_OUI_FROM_DATABASE=Implementa GmbH + +OUI:0050C210E* + ID_OUI_FROM_DATABASE=Unipower AB + +OUI:0050C210F* + ID_OUI_FROM_DATABASE=Perceptics Corp. + +OUI:0050C2110* + ID_OUI_FROM_DATABASE=QuesCom + +OUI:0050C2111* + ID_OUI_FROM_DATABASE=Endusis Limited + +OUI:0050C2112* + ID_OUI_FROM_DATABASE=Compuworx + +OUI:0050C2113* + ID_OUI_FROM_DATABASE=Ace Electronics, Inc. + +OUI:0050C2114* + ID_OUI_FROM_DATABASE=Quest Innovations + +OUI:0050C2115* + ID_OUI_FROM_DATABASE=Vidco, Inc. + +OUI:0050C2116* + ID_OUI_FROM_DATABASE=DSP Design, Ltd. + +OUI:0050C2117* + ID_OUI_FROM_DATABASE=Wintegra Ltd. + +OUI:0050C2118* + ID_OUI_FROM_DATABASE=Microbit 2.0 AB + +OUI:0050C2119* + ID_OUI_FROM_DATABASE=Global Opto Communication Tech. Corp + +OUI:0050C211A* + ID_OUI_FROM_DATABASE=Teamaxess Ticketing GmbH + +OUI:0050C211B* + ID_OUI_FROM_DATABASE=Digital Vision AB + +OUI:0050C211C* + ID_OUI_FROM_DATABASE=Stonefly Networks + +OUI:0050C211D* + ID_OUI_FROM_DATABASE=Destiny Networks, Inc. + +OUI:0050C211E* + ID_OUI_FROM_DATABASE=Volvo Car Corporation + +OUI:0050C211F* + ID_OUI_FROM_DATABASE=CSS Industrie Computer GmbH + +OUI:0050C2120* + ID_OUI_FROM_DATABASE=XStore, Inc. + +OUI:0050C2121* + ID_OUI_FROM_DATABASE=COE Limited + +OUI:0050C2122* + ID_OUI_FROM_DATABASE=Diva Systems + +OUI:0050C2123* + ID_OUI_FROM_DATABASE=Seranoa Networks, Inc. + +OUI:0050C2124* + ID_OUI_FROM_DATABASE=Tokai Soft Corporation + +OUI:0050C2125* + ID_OUI_FROM_DATABASE=Tecwings GmBh + +OUI:0050C2126* + ID_OUI_FROM_DATABASE=Marvell Hispana S.L. + +OUI:0050C2127* + ID_OUI_FROM_DATABASE=TPA Traffic & Parking Automation BV + +OUI:0050C2128* + ID_OUI_FROM_DATABASE=Pycon, Inc. + +OUI:0050C2129* + ID_OUI_FROM_DATABASE=TTPCom Ltd. + +OUI:0050C212A* + ID_OUI_FROM_DATABASE=Symbolic Sound Corp. + +OUI:0050C212B* + ID_OUI_FROM_DATABASE=Dong A Eltek Co., Ltd. + +OUI:0050C212C* + ID_OUI_FROM_DATABASE=Delta Tau Data Systems, Inc. + +OUI:0050C212D* + ID_OUI_FROM_DATABASE=Megisto Systems, Inc. + +OUI:0050C212E* + ID_OUI_FROM_DATABASE=RUNCOM + +OUI:0050C212F* + ID_OUI_FROM_DATABASE=HAAG-STREIT AG + +OUI:0050C2130* + ID_OUI_FROM_DATABASE=U.S. Traffic Corporation + +OUI:0050C2131* + ID_OUI_FROM_DATABASE=InBus Engineering, Inc. + +OUI:0050C2132* + ID_OUI_FROM_DATABASE=Procon Electronics + +OUI:0050C2133* + ID_OUI_FROM_DATABASE=ChipWrights, Inc. + +OUI:0050C2134* + ID_OUI_FROM_DATABASE=DRS Photronics + +OUI:0050C2135* + ID_OUI_FROM_DATABASE=ELAD SRL + +OUI:0050C2136* + ID_OUI_FROM_DATABASE=Tensilica, Inc. + +OUI:0050C2137* + ID_OUI_FROM_DATABASE=Uniwell Systems (UK) Ltd. + +OUI:0050C2138* + ID_OUI_FROM_DATABASE=Delphin Technology AG + +OUI:0050C2139* + ID_OUI_FROM_DATABASE=SR Research Ltd. + +OUI:0050C213A* + ID_OUI_FROM_DATABASE=Tex Computer SRL + +OUI:0050C213B* + ID_OUI_FROM_DATABASE=Vaisala Oyj + +OUI:0050C213C* + ID_OUI_FROM_DATABASE=NBG Industrial Automation B.V. + +OUI:0050C213D* + ID_OUI_FROM_DATABASE=Formula One Management Ltd. + +OUI:0050C213E* + ID_OUI_FROM_DATABASE=AVerMedia Systems, Inc. + +OUI:0050C213F* + ID_OUI_FROM_DATABASE=Sentito Networks + +OUI:0050C2140* + ID_OUI_FROM_DATABASE=ITS, Inc. + +OUI:0050C2141* + ID_OUI_FROM_DATABASE=Time Terminal Adductor Group AB + +OUI:0050C2142* + ID_OUI_FROM_DATABASE=Instrumeter A/S + +OUI:0050C2143* + ID_OUI_FROM_DATABASE=AARTESYS AG + +OUI:0050C2144* + ID_OUI_FROM_DATABASE=Phytec Messtechnik GmbH + +OUI:0050C2145* + ID_OUI_FROM_DATABASE=ELC Lighting + +OUI:0050C2146* + ID_OUI_FROM_DATABASE=APCON, Inc. + +OUI:0050C2147* + ID_OUI_FROM_DATABASE=UniSUR + +OUI:0050C2148* + ID_OUI_FROM_DATABASE=Alltec GmbH + +OUI:0050C2149* + ID_OUI_FROM_DATABASE=Haag-Streit AG + +OUI:0050C214A* + ID_OUI_FROM_DATABASE=DYCEC, S.A. + +OUI:0050C214B* + ID_OUI_FROM_DATABASE=HECUBA Elektronik + +OUI:0050C214C* + ID_OUI_FROM_DATABASE=Optibase Ltd. + +OUI:0050C214D* + ID_OUI_FROM_DATABASE=wellink, Ltd. + +OUI:0050C214E* + ID_OUI_FROM_DATABASE=Corinex Global + +OUI:0050C214F* + ID_OUI_FROM_DATABASE=Telephonics Corp. + +OUI:0050C2150* + ID_OUI_FROM_DATABASE=Torse + +OUI:0050C2151* + ID_OUI_FROM_DATABASE=Redux Communications Ltd. + +OUI:0050C2152* + ID_OUI_FROM_DATABASE=AirVast Technology Inc. + +OUI:0050C2153* + ID_OUI_FROM_DATABASE=Advanced Devices SpA + +OUI:0050C2154* + ID_OUI_FROM_DATABASE=Jostra AB + +OUI:0050C2155* + ID_OUI_FROM_DATABASE=Enea Real Time AB + +OUI:0050C2156* + ID_OUI_FROM_DATABASE=CommServ Solutions Inc. + +OUI:0050C2157* + ID_OUI_FROM_DATABASE=nCore, Inc. + +OUI:0050C2158* + ID_OUI_FROM_DATABASE=Communication Solutions, Inc. + +OUI:0050C2159* + ID_OUI_FROM_DATABASE=Standard Comm. Corp. + +OUI:0050C215A* + ID_OUI_FROM_DATABASE=Plextek Limited + +OUI:0050C215B* + ID_OUI_FROM_DATABASE=Dune Networks + +OUI:0050C215C* + ID_OUI_FROM_DATABASE=Aoptix Technologies + +OUI:0050C215D* + ID_OUI_FROM_DATABASE=Cepheid + +OUI:0050C215E* + ID_OUI_FROM_DATABASE=Celite Systems, Inc. + +OUI:0050C215F* + ID_OUI_FROM_DATABASE=Pulsar GmbH + +OUI:0050C2160* + ID_OUI_FROM_DATABASE=TTI - Telecom International Ltd. + +OUI:0050C2161* + ID_OUI_FROM_DATABASE=J&B Engineering Group S.L. + +OUI:0050C2162* + ID_OUI_FROM_DATABASE=Teseda Corporation + +OUI:0050C2163* + ID_OUI_FROM_DATABASE=Computerwise, Inc. + +OUI:0050C2164* + ID_OUI_FROM_DATABASE=Acunia N.V. + +OUI:0050C2165* + ID_OUI_FROM_DATABASE=IPCAST + +OUI:0050C2166* + ID_OUI_FROM_DATABASE=Infineer Ltd. + +OUI:0050C2167* + ID_OUI_FROM_DATABASE=Precision Filters, Inc. + +OUI:0050C2168* + ID_OUI_FROM_DATABASE=ExtremeSpeed Inc. + +OUI:0050C2169* + ID_OUI_FROM_DATABASE=Nordson Corp. + +OUI:0050C216A* + ID_OUI_FROM_DATABASE=Time Domain + +OUI:0050C216B* + ID_OUI_FROM_DATABASE=Masterclock, Inc. + +OUI:0050C216C* + ID_OUI_FROM_DATABASE=Brijing Embedor Embedded Internet Tech. Co. Ltd. + +OUI:0050C216D* + ID_OUI_FROM_DATABASE=Postec Data Systems Ltd. + +OUI:0050C216E* + ID_OUI_FROM_DATABASE=PMC + +OUI:0050C216F* + ID_OUI_FROM_DATABASE=Dickson Technologies + +OUI:0050C2170* + ID_OUI_FROM_DATABASE=Taishodo Seiko Co., Ltd. + +OUI:0050C2171* + ID_OUI_FROM_DATABASE=Quantronix, Inc. + +OUI:0050C2172* + ID_OUI_FROM_DATABASE=SAET I.S. S.r.l. + +OUI:0050C2173* + ID_OUI_FROM_DATABASE=DeMeTec GmbH + +OUI:0050C2174* + ID_OUI_FROM_DATABASE=N&P Technologies + +OUI:0050C2175* + ID_OUI_FROM_DATABASE=Sei S.p.A. + +OUI:0050C2176* + ID_OUI_FROM_DATABASE=Wavium AB + +OUI:0050C2177* + ID_OUI_FROM_DATABASE=Unicoi Systems + +OUI:0050C2178* + ID_OUI_FROM_DATABASE=Partner Voxstream A/S + +OUI:0050C2179* + ID_OUI_FROM_DATABASE=Verifiber LLC + +OUI:0050C217A* + ID_OUI_FROM_DATABASE=WOLF Industrial Systems Inc. + +OUI:0050C217B* + ID_OUI_FROM_DATABASE=Broadstorm Telecom + +OUI:0050C217C* + ID_OUI_FROM_DATABASE=Jeffress Engineering Pty Ltd + +OUI:0050C217D* + ID_OUI_FROM_DATABASE=Cognex Corporation + +OUI:0050C217E* + ID_OUI_FROM_DATABASE=Binary Wave Technologies Inc. + +OUI:0050C217F* + ID_OUI_FROM_DATABASE=PDQ Manufacturing + +OUI:0050C2180* + ID_OUI_FROM_DATABASE=Zultys Technologies + +OUI:0050C2181* + ID_OUI_FROM_DATABASE=Task 84 Spa + +OUI:0050C2182* + ID_OUI_FROM_DATABASE=wolf-inf-tec + +OUI:0050C2183* + ID_OUI_FROM_DATABASE=Mixbaal S.A. de C.V. + +OUI:0050C2184* + ID_OUI_FROM_DATABASE=H M Computing Limited + +OUI:0050C2185* + ID_OUI_FROM_DATABASE=Optical Wireless Link Inc. + +OUI:0050C2186* + ID_OUI_FROM_DATABASE=Pantec Engineering AG + +OUI:0050C2187* + ID_OUI_FROM_DATABASE=Cyan Technology Ltd + +OUI:0050C2188* + ID_OUI_FROM_DATABASE=dresden-elektronik + +OUI:0050C2189* + ID_OUI_FROM_DATABASE=CC Systems AB + +OUI:0050C218A* + ID_OUI_FROM_DATABASE=Basler Electric Company + +OUI:0050C218B* + ID_OUI_FROM_DATABASE=Teradyne Inc. + +OUI:0050C218C* + ID_OUI_FROM_DATABASE=Technodrive srl + +OUI:0050C218D* + ID_OUI_FROM_DATABASE=CCII Systems (Pty) Ltd + +OUI:0050C218E* + ID_OUI_FROM_DATABASE=SPARR ELECTRONICS LTD + +OUI:0050C218F* + ID_OUI_FROM_DATABASE=MATSUI MFG CO.,LTD + +OUI:0050C2190* + ID_OUI_FROM_DATABASE=Goerlitz AG + +OUI:0050C2191* + ID_OUI_FROM_DATABASE=Partner Voxstream A/S + +OUI:0050C2192* + ID_OUI_FROM_DATABASE=Advanced Concepts, Inc. + +OUI:0050C2193* + ID_OUI_FROM_DATABASE=LaserBit Communications Corp. + +OUI:0050C2194* + ID_OUI_FROM_DATABASE=COMINFO + +OUI:0050C2195* + ID_OUI_FROM_DATABASE=Momentum Data Systems + +OUI:0050C2196* + ID_OUI_FROM_DATABASE=Netsynt Spa + +OUI:0050C2197* + ID_OUI_FROM_DATABASE=EPM Tecnologia e Equipamentos + +OUI:0050C2198* + ID_OUI_FROM_DATABASE=PotsTek, Inc + +OUI:0050C2199* + ID_OUI_FROM_DATABASE=Survalent Technology Corporation + +OUI:0050C219A* + ID_OUI_FROM_DATABASE=AZIO TECHNOLOGY CO. + +OUI:0050C219B* + ID_OUI_FROM_DATABASE=Wilcoxon Research, Inc. + +OUI:0050C219C* + ID_OUI_FROM_DATABASE=Artec Design + +OUI:0050C219D* + ID_OUI_FROM_DATABASE=ELECTREX S.R.L + +OUI:0050C219E* + ID_OUI_FROM_DATABASE=Paltronics, Inc. + +OUI:0050C219F* + ID_OUI_FROM_DATABASE=Fleetwood Electronics Ltd + +OUI:0050C21A0* + ID_OUI_FROM_DATABASE=SCA Data Systems + +OUI:0050C21A1* + ID_OUI_FROM_DATABASE=Portalplayer, Inc + +OUI:0050C21A2* + ID_OUI_FROM_DATABASE=ABB Switzerland Inc + +OUI:0050C21A3* + ID_OUI_FROM_DATABASE=Tidel Engineering, L.P. + +OUI:0050C21A4* + ID_OUI_FROM_DATABASE=Protech Optronics Co. Ltd. + +OUI:0050C21A5* + ID_OUI_FROM_DATABASE=NORCO + +OUI:0050C21A6* + ID_OUI_FROM_DATABASE=RF Code + +OUI:0050C21A7* + ID_OUI_FROM_DATABASE=Alpha Beta Technologies, Inc. + +OUI:0050C21A8* + ID_OUI_FROM_DATABASE=ANOVA BROADBAND + +OUI:0050C21A9* + ID_OUI_FROM_DATABASE=Axotec Technologies GmbH + +OUI:0050C21AA* + ID_OUI_FROM_DATABASE=BitBox Ltd + +OUI:0050C21AB* + ID_OUI_FROM_DATABASE=Streaming Networks + +OUI:0050C21AC* + ID_OUI_FROM_DATABASE=Beckmann+Egle GmbH + +OUI:0050C21AD* + ID_OUI_FROM_DATABASE=Remia s.r.o. + +OUI:0050C21AE* + ID_OUI_FROM_DATABASE=Home Director, Inc + +OUI:0050C21AF* + ID_OUI_FROM_DATABASE=PESA Switching Systems, Inc. + +OUI:0050C21B0* + ID_OUI_FROM_DATABASE=BLANKOM Antennentechnik GmbH + +OUI:0050C21B1* + ID_OUI_FROM_DATABASE=Axes Technologies + +OUI:0050C21B2* + ID_OUI_FROM_DATABASE=SIGOS Systemintegration GmbH + +OUI:0050C21B3* + ID_OUI_FROM_DATABASE=DSP DESIGN + +OUI:0050C21B4* + ID_OUI_FROM_DATABASE=DSP Group Inc. + +OUI:0050C21B5* + ID_OUI_FROM_DATABASE=Thrane & Thrane A/S + +OUI:0050C21B6* + ID_OUI_FROM_DATABASE=DTS, Inc. + +OUI:0050C21B7* + ID_OUI_FROM_DATABASE=MosChip USA + +OUI:0050C21B8* + ID_OUI_FROM_DATABASE=Electronic Systems Development + +OUI:0050C21B9* + ID_OUI_FROM_DATABASE=EmCom Technology Inc. + +OUI:0050C21BA* + ID_OUI_FROM_DATABASE=INTERZEAG AG + +OUI:0050C21BB* + ID_OUI_FROM_DATABASE=Email Metering + +OUI:0050C21BC* + ID_OUI_FROM_DATABASE=DINEC International + +OUI:0050C21BD* + ID_OUI_FROM_DATABASE=AIOI Systems Co., Ltd. + +OUI:0050C21BE* + ID_OUI_FROM_DATABASE=Sedia Electronics + +OUI:0050C21BF* + ID_OUI_FROM_DATABASE=International Test & Engineering Services Co.,Ltd. + +OUI:0050C21C0* + ID_OUI_FROM_DATABASE=WillMonius Inc. + +OUI:0050C21C1* + ID_OUI_FROM_DATABASE=InfinitiNetworks Inc. + +OUI:0050C21C2* + ID_OUI_FROM_DATABASE=Weltronics Corp. + +OUI:0050C21C3* + ID_OUI_FROM_DATABASE=TT electronic manufacturing services ltd + +OUI:0050C21C4* + ID_OUI_FROM_DATABASE=Palm Solutions Group + +OUI:0050C21C5* + ID_OUI_FROM_DATABASE=Flander Oy + +OUI:0050C21C6* + ID_OUI_FROM_DATABASE=Remco Italia Spa + +OUI:0050C21C7* + ID_OUI_FROM_DATABASE=TWIN DEVELOPMENT S.A. + +OUI:0050C21C8* + ID_OUI_FROM_DATABASE=Euphony technology CO., LTD. + +OUI:0050C21C9* + ID_OUI_FROM_DATABASE=modas GmbH + +OUI:0050C21CA* + ID_OUI_FROM_DATABASE=EVER Sp. z o.o. + +OUI:0050C21CB* + ID_OUI_FROM_DATABASE=quantumBEAM Limited + +OUI:0050C21CC* + ID_OUI_FROM_DATABASE=WaveIP ltd. + +OUI:0050C21CD* + ID_OUI_FROM_DATABASE=INCAA Informatica Italia srl + +OUI:0050C21CE* + ID_OUI_FROM_DATABASE=Datatek Applications, Inc. + +OUI:0050C21CF* + ID_OUI_FROM_DATABASE=LIFETIME MEMORY PRODUCTS, INC. + +OUI:0050C21D0* + ID_OUI_FROM_DATABASE=Yazaki North America, Inc. + +OUI:0050C21D1* + ID_OUI_FROM_DATABASE=Benchmark Electronics + +OUI:0050C21D2* + ID_OUI_FROM_DATABASE=Shenyang Internet Technology Inc + +OUI:0050C21D3* + ID_OUI_FROM_DATABASE=Synopsys + +OUI:0050C21D4* + ID_OUI_FROM_DATABASE=Phase IV Engineering Inc. + +OUI:0050C21D5* + ID_OUI_FROM_DATABASE=Redpoint Controls + +OUI:0050C21D6* + ID_OUI_FROM_DATABASE=shanghai trend intelligent systems CO.,LTD + +OUI:0050C21D7* + ID_OUI_FROM_DATABASE=Pleora Technologies Inc. + +OUI:0050C21D8* + ID_OUI_FROM_DATABASE=Guardian Controls International + +OUI:0050C21D9* + ID_OUI_FROM_DATABASE=EDC + +OUI:0050C21DA* + ID_OUI_FROM_DATABASE=GFI Chrono Time + +OUI:0050C21DB* + ID_OUI_FROM_DATABASE=Applied Systems Engineering, Inc. + +OUI:0050C21DC* + ID_OUI_FROM_DATABASE=Imarda New Zealand Limited + +OUI:0050C21DD* + ID_OUI_FROM_DATABASE=Peiker acustic GmbH & Co. KG + +OUI:0050C21DE* + ID_OUI_FROM_DATABASE=ReliOn Inc. + +OUI:0050C21DF* + ID_OUI_FROM_DATABASE=Lulea University of Technology + +OUI:0050C21E0* + ID_OUI_FROM_DATABASE=Cognex Corporation + +OUI:0050C21E1* + ID_OUI_FROM_DATABASE=Automaatiotekniikka Seppo Saari Oy + +OUI:0050C21E2* + ID_OUI_FROM_DATABASE=DIGITRONIC Automationsanlagen GmbH + +OUI:0050C21E3* + ID_OUI_FROM_DATABASE=Bluesocket, Inc. + +OUI:0050C21E4* + ID_OUI_FROM_DATABASE=Soronti, Inc. + +OUI:0050C21E5* + ID_OUI_FROM_DATABASE=DORLET S.A. + +OUI:0050C21E6* + ID_OUI_FROM_DATABASE=United Tri-Tech Corporation + +OUI:0050C21E7* + ID_OUI_FROM_DATABASE=Smith Meter, Inc. + +OUI:0050C21E8* + ID_OUI_FROM_DATABASE=Metrotech + +OUI:0050C21E9* + ID_OUI_FROM_DATABASE=Ranch Networks + +OUI:0050C21EA* + ID_OUI_FROM_DATABASE=DAVE S.r.L. + +OUI:0050C21EB* + ID_OUI_FROM_DATABASE=Data Respons A/S + +OUI:0050C21EC* + ID_OUI_FROM_DATABASE=COSMO co.,ltd. + +OUI:0050C21ED* + ID_OUI_FROM_DATABASE=EMKA-electronic AG + +OUI:0050C21EE* + ID_OUI_FROM_DATABASE=Perto Periféricos de Automação S.A. + +OUI:0050C21EF* + ID_OUI_FROM_DATABASE=M2 Technology Pty Ltd + +OUI:0050C21F0* + ID_OUI_FROM_DATABASE=EXI Wireless Systems Inc. + +OUI:0050C21F1* + ID_OUI_FROM_DATABASE=SKY Computers, Inc. + +OUI:0050C21F2* + ID_OUI_FROM_DATABASE=Tattile srl + +OUI:0050C21F3* + ID_OUI_FROM_DATABASE=Radionor Communications AS + +OUI:0050C21F4* + ID_OUI_FROM_DATABASE=Covia, Inc + +OUI:0050C21F5* + ID_OUI_FROM_DATABASE=Abest Communication Corp. + +OUI:0050C21F6* + ID_OUI_FROM_DATABASE=BAE SYSTEMS Controls + +OUI:0050C21F7* + ID_OUI_FROM_DATABASE=ARC'Créations + +OUI:0050C21F8* + ID_OUI_FROM_DATABASE=ULTRACKER TECHNOLOGY + +OUI:0050C21F9* + ID_OUI_FROM_DATABASE=Fr. Sauter AG + +OUI:0050C21FA* + ID_OUI_FROM_DATABASE=SP Controls, Inc + +OUI:0050C21FB* + ID_OUI_FROM_DATABASE=Willowglen Systems Inc. + +OUI:0050C21FC* + ID_OUI_FROM_DATABASE=EDD Srl + +OUI:0050C21FD* + ID_OUI_FROM_DATABASE=SouthWing S.L. + +OUI:0050C21FE* + ID_OUI_FROM_DATABASE=Safetran Traffic Systems Inc. + +OUI:0050C21FF* + ID_OUI_FROM_DATABASE=Product Design Dept., Sohwa Corporation + +OUI:0050C2200* + ID_OUI_FROM_DATABASE=Whittier Mailing Products, Inc. + +OUI:0050C2201* + ID_OUI_FROM_DATABASE=OlympusNDT + +OUI:0050C2202* + ID_OUI_FROM_DATABASE=Audio Riders Oy + +OUI:0050C2204* + ID_OUI_FROM_DATABASE=Algodue Elettronica srl + +OUI:0050C2205* + ID_OUI_FROM_DATABASE=SystIng + +OUI:0050C2206* + ID_OUI_FROM_DATABASE=Windmill Innovations + +OUI:0050C2207* + ID_OUI_FROM_DATABASE=Solectron Ind.Com.Servs.Exportadora do Brasil Ltda. + +OUI:0050C2208* + ID_OUI_FROM_DATABASE=nNovia, Inc. + +OUI:0050C2209* + ID_OUI_FROM_DATABASE=LK Ltd + +OUI:0050C220A* + ID_OUI_FROM_DATABASE=Ferrari electronic AG + +OUI:0050C220B* + ID_OUI_FROM_DATABASE=Rafael + +OUI:0050C220C* + ID_OUI_FROM_DATABASE=Communication and Telemechanical Systems Company Limited + +OUI:0050C220D* + ID_OUI_FROM_DATABASE=Varisys Ltd + +OUI:0050C220E* + ID_OUI_FROM_DATABASE=PYRAMID Computer Systeme GmbH + +OUI:0050C220F* + ID_OUI_FROM_DATABASE=OMICRON electronics GmbH + +OUI:0050C2210* + ID_OUI_FROM_DATABASE=Innovics Wireless Inc + +OUI:0050C2211* + ID_OUI_FROM_DATABASE=Hochschule für Technik, Wirtschaft und Kultur Leipzig (FH) + +OUI:0050C2212* + ID_OUI_FROM_DATABASE=4Links Limited + +OUI:0050C2213* + ID_OUI_FROM_DATABASE=SysAware S.A.R.L. + +OUI:0050C2214* + ID_OUI_FROM_DATABASE=Oshimi System Design Inc. + +OUI:0050C2215* + ID_OUI_FROM_DATABASE=VoiceCom AG + +OUI:0050C2216* + ID_OUI_FROM_DATABASE=Level Control Systems + +OUI:0050C2217* + ID_OUI_FROM_DATABASE=Linn Products Ltd + +OUI:0050C2218* + ID_OUI_FROM_DATABASE=Nansen S. A. - Instrumentos de Precisão + +OUI:0050C2219* + ID_OUI_FROM_DATABASE=Aeroflex GmbH + +OUI:0050C221A* + ID_OUI_FROM_DATABASE=MST SYSTEMS LIMITED + +OUI:0050C221B* + ID_OUI_FROM_DATABASE=General Dynamics Decision Systems + +OUI:0050C221C* + ID_OUI_FROM_DATABASE=Fracarro Radioindustrie SPA + +OUI:0050C221D* + ID_OUI_FROM_DATABASE=ESG Elektroniksystem u. Logistik GmbH + +OUI:0050C221E* + ID_OUI_FROM_DATABASE=Applied Technologies Associates + +OUI:0050C221F* + ID_OUI_FROM_DATABASE=Monitor Business Machines Ltd + +OUI:0050C2220* + ID_OUI_FROM_DATABASE=Serveron Corporation + +OUI:0050C2221* + ID_OUI_FROM_DATABASE=Getinge IT Solutions ApS + +OUI:0050C2222* + ID_OUI_FROM_DATABASE=imo-elektronik GmbH + +OUI:0050C2223* + ID_OUI_FROM_DATABASE=visicontrol GmbH + +OUI:0050C2224* + ID_OUI_FROM_DATABASE=PANNOCOM Ltd. + +OUI:0050C2225* + ID_OUI_FROM_DATABASE=Pigeon Point Systems + +OUI:0050C2226* + ID_OUI_FROM_DATABASE=Ross Video Limited + +OUI:0050C2227* + ID_OUI_FROM_DATABASE=Intelligent Photonics Control + +OUI:0050C2228* + ID_OUI_FROM_DATABASE=Intelligent Media Technologies, Inc. + +OUI:0050C2229* + ID_OUI_FROM_DATABASE=eko systems inc. + +OUI:0050C222A* + ID_OUI_FROM_DATABASE=Crescendo Networks + +OUI:0050C222B* + ID_OUI_FROM_DATABASE=Riegl Laser Measurement Systems GmbH + +OUI:0050C222C* + ID_OUI_FROM_DATABASE=Intrinsity + +OUI:0050C222D* + ID_OUI_FROM_DATABASE=asetek Inc. + +OUI:0050C222E* + ID_OUI_FROM_DATABASE=LORD INGEN IERIE + +OUI:0050C222F* + ID_OUI_FROM_DATABASE=HTEC Limited + +OUI:0050C2230* + ID_OUI_FROM_DATABASE=AutoTOOLS group Co. Ltd. + +OUI:0050C2231* + ID_OUI_FROM_DATABASE=Legra Systems, Inc. + +OUI:0050C2232* + ID_OUI_FROM_DATABASE=SIMET + +OUI:0050C2233* + ID_OUI_FROM_DATABASE=EdenTree Technologies, Inc. + +OUI:0050C2234* + ID_OUI_FROM_DATABASE=Silverback Systems + +OUI:0050C2235* + ID_OUI_FROM_DATABASE=POLIMAR ELEKTRONIK LTD. + +OUI:0050C2236* + ID_OUI_FROM_DATABASE=JLCooper Electronics + +OUI:0050C2237* + ID_OUI_FROM_DATABASE=Tandata Systems Ltd + +OUI:0050C2238* + ID_OUI_FROM_DATABASE=Schwer+Kopka GmbH + +OUI:0050C2239* + ID_OUI_FROM_DATABASE=Stins Coman + +OUI:0050C223A* + ID_OUI_FROM_DATABASE=Chantry Networks + +OUI:0050C223B* + ID_OUI_FROM_DATABASE=Envara + +OUI:0050C223C* + ID_OUI_FROM_DATABASE=Wheatstone Corporation + +OUI:0050C223D* + ID_OUI_FROM_DATABASE=Gauging Systems Inc + +OUI:0050C223E* + ID_OUI_FROM_DATABASE=Kallastra Inc. + +OUI:0050C223F* + ID_OUI_FROM_DATABASE=Halliburton - NUMAR + +OUI:0050C2240* + ID_OUI_FROM_DATABASE=Geoquip Ltd + +OUI:0050C2241* + ID_OUI_FROM_DATABASE=Contronics Automacao Ltda + +OUI:0050C2242* + ID_OUI_FROM_DATABASE=MDS SCIEX + +OUI:0050C2243* + ID_OUI_FROM_DATABASE=RGB Spectrum + +OUI:0050C2244* + ID_OUI_FROM_DATABASE=intec GmbH + +OUI:0050C2245* + ID_OUI_FROM_DATABASE=Hauppauge Computer Works, Inc. + +OUI:0050C2246* + ID_OUI_FROM_DATABASE=Hardmeier + +OUI:0050C2247* + ID_OUI_FROM_DATABASE=Gradual Tecnologia Ltda. + +OUI:0050C2248* + ID_OUI_FROM_DATABASE=Dixtal Biomedica Ind. Com. Ltda. + +OUI:0050C2249* + ID_OUI_FROM_DATABASE=Dipl.-Ing. W. Bender GmbH & Co. KG + +OUI:0050C224A* + ID_OUI_FROM_DATABASE=CDS Rail + +OUI:0050C224B* + ID_OUI_FROM_DATABASE=Azimuth Systems, Inc. + +OUI:0050C224C* + ID_OUI_FROM_DATABASE=Supertel + +OUI:0050C224D* + ID_OUI_FROM_DATABASE=METTLER-TOLEDO HI-SPEED + +OUI:0050C224E* + ID_OUI_FROM_DATABASE=Scharff Weisberg Systems Integration Inc + +OUI:0050C224F* + ID_OUI_FROM_DATABASE=Macronet s.r.l. + +OUI:0050C2250* + ID_OUI_FROM_DATABASE=ACD Elektronik GmbH + +OUI:0050C2251* + ID_OUI_FROM_DATABASE=DGT Sp. z o.o. + +OUI:0050C2252* + ID_OUI_FROM_DATABASE=ads-tec GmbH + +OUI:0050C2253* + ID_OUI_FROM_DATABASE=DSM-Messtechnik GmbH + +OUI:0050C2254* + ID_OUI_FROM_DATABASE=Thales Communications Ltd + +OUI:0050C2255* + ID_OUI_FROM_DATABASE=STMicroelectronics (R&D) Ltd + +OUI:0050C2256* + ID_OUI_FROM_DATABASE=Information Technology Corp. + +OUI:0050C2257* + ID_OUI_FROM_DATABASE=Digicast Networks + +OUI:0050C2258* + ID_OUI_FROM_DATABASE=Spacesaver Corporation + +OUI:0050C2259* + ID_OUI_FROM_DATABASE=Omicron Ceti AB + +OUI:0050C225A* + ID_OUI_FROM_DATABASE=Zendex Corporation + +OUI:0050C225B* + ID_OUI_FROM_DATABASE=Winford Engineering + +OUI:0050C225C* + ID_OUI_FROM_DATABASE=Softhill Technologies Ltd. + +OUI:0050C225D* + ID_OUI_FROM_DATABASE=RDTECH + +OUI:0050C225E* + ID_OUI_FROM_DATABASE=MITE Hradec Kralove, s.r.o. + +OUI:0050C225F* + ID_OUI_FROM_DATABASE=Handtmann Maschinenfabrik GmbH&Co.KG + +OUI:0050C2260* + ID_OUI_FROM_DATABASE=BIOTAGE + +OUI:0050C2261* + ID_OUI_FROM_DATABASE=Tattile Srl + +OUI:0050C2262* + ID_OUI_FROM_DATABASE=Shanghai Gaozhi Science&Technology Development Ltd. + +OUI:0050C2263* + ID_OUI_FROM_DATABASE=Vansco Electronics Oy + +OUI:0050C2264* + ID_OUI_FROM_DATABASE=Confidence Direct Ltd + +OUI:0050C2265* + ID_OUI_FROM_DATABASE=BELIK S.P.R.L. + +OUI:0050C2266* + ID_OUI_FROM_DATABASE=ATOM GIKEN Co.,Ltd. + +OUI:0050C2267* + ID_OUI_FROM_DATABASE=Allen Martin Conservation Ltd + +OUI:0050C2268* + ID_OUI_FROM_DATABASE=Parabit Systems + +OUI:0050C2269* + ID_OUI_FROM_DATABASE=Technisyst Pty Ltd + +OUI:0050C226A* + ID_OUI_FROM_DATABASE=FG SYNERYS + +OUI:0050C226B* + ID_OUI_FROM_DATABASE=Continental Gateway Limited + +OUI:0050C226C* + ID_OUI_FROM_DATABASE=Crystal Vision Ltd + +OUI:0050C226D* + ID_OUI_FROM_DATABASE=DSP DESIGN + +OUI:0050C226E* + ID_OUI_FROM_DATABASE=ZP Engineering srl + +OUI:0050C226F* + ID_OUI_FROM_DATABASE=Digital Recorders Inc + +OUI:0050C2270* + ID_OUI_FROM_DATABASE=S4 Technology Pty Ltd + +OUI:0050C2271* + ID_OUI_FROM_DATABASE=VLSIP TECHNOLOGIES INC. + +OUI:0050C2272* + ID_OUI_FROM_DATABASE=Verex Technology + +OUI:0050C2273* + ID_OUI_FROM_DATABASE=Servicios Condumex, S. A. de C. V. + +OUI:0050C2274* + ID_OUI_FROM_DATABASE=Fundación ROBOTIKER + +OUI:0050C2275* + ID_OUI_FROM_DATABASE=Extreme Engineering Solutions + +OUI:0050C2276* + ID_OUI_FROM_DATABASE=Tieline Research Pty Ltd + +OUI:0050C2277* + ID_OUI_FROM_DATABASE=T/R Systems, Inc. + +OUI:0050C2278* + ID_OUI_FROM_DATABASE=Replicom Ltd. + +OUI:0050C2279* + ID_OUI_FROM_DATABASE=PATLITE Corporation + +OUI:0050C227A* + ID_OUI_FROM_DATABASE=Maestro Pty Ltd + +OUI:0050C227B* + ID_OUI_FROM_DATABASE=LinkSecurity A/S + +OUI:0050C227C* + ID_OUI_FROM_DATABASE=Danlaw Inc + +OUI:0050C227D* + ID_OUI_FROM_DATABASE=ALLIED TELESIS K.K. + +OUI:0050C227E* + ID_OUI_FROM_DATABASE=AnaLogic Computers Ltd. + +OUI:0050C227F* + ID_OUI_FROM_DATABASE=Air Broadband Communications, Inc. + +OUI:0050C2280* + ID_OUI_FROM_DATABASE=AGECODAGIS SARL + +OUI:0050C2281* + ID_OUI_FROM_DATABASE=CabTronix GmbH + +OUI:0050C2282* + ID_OUI_FROM_DATABASE=Telvent + +OUI:0050C2283* + ID_OUI_FROM_DATABASE=ANSITEX CORP. + +OUI:0050C2284* + ID_OUI_FROM_DATABASE=Micronet Ltd. + +OUI:0050C2285* + ID_OUI_FROM_DATABASE=Littwin GmbH & Co KG + +OUI:0050C2286* + ID_OUI_FROM_DATABASE=ATEME + +OUI:0050C2287* + ID_OUI_FROM_DATABASE=TECNEW Electronics Engineering Cr., Ltd. + +OUI:0050C2288* + ID_OUI_FROM_DATABASE=RPM Systems Corporation + +OUI:0050C2289* + ID_OUI_FROM_DATABASE=Rototype S.p.A. + +OUI:0050C228A* + ID_OUI_FROM_DATABASE=Real Time Systems + +OUI:0050C228B* + ID_OUI_FROM_DATABASE=Orion Technologies, Incorporated + +OUI:0050C228C* + ID_OUI_FROM_DATABASE=Futaba Corporation + +OUI:0050C228D* + ID_OUI_FROM_DATABASE=AXODE SA + +OUI:0050C228E* + ID_OUI_FROM_DATABASE=TATTILE SRL + +OUI:0050C228F* + ID_OUI_FROM_DATABASE=Spellman High Voltage Electronics Corp + +OUI:0050C2290* + ID_OUI_FROM_DATABASE=EBNEURO SPA + +OUI:0050C2291* + ID_OUI_FROM_DATABASE=CHAUVIN ARNOUX + +OUI:0050C2292* + ID_OUI_FROM_DATABASE=AMIRIX Systems + +OUI:0050C2293* + ID_OUI_FROM_DATABASE=IP Unity + +OUI:0050C2294* + ID_OUI_FROM_DATABASE=EPSa GmbH + +OUI:0050C2295* + ID_OUI_FROM_DATABASE=LOGOSOL, INC. + +OUI:0050C2296* + ID_OUI_FROM_DATABASE=OpVista + +OUI:0050C2297* + ID_OUI_FROM_DATABASE=KINETICS + +OUI:0050C2298* + ID_OUI_FROM_DATABASE=Harvad University + +OUI:0050C2299* + ID_OUI_FROM_DATABASE=CAD-UL GmbH + +OUI:0050C229A* + ID_OUI_FROM_DATABASE=Packet Techniques Inc. + +OUI:0050C229B* + ID_OUI_FROM_DATABASE=ACD Elektronik GmbH + +OUI:0050C229C* + ID_OUI_FROM_DATABASE=2N TELEKOMUNIKACE a.s. + +OUI:0050C229D* + ID_OUI_FROM_DATABASE=Globe Wireless + +OUI:0050C229E* + ID_OUI_FROM_DATABASE=SELEX Communications Ltd + +OUI:0050C229F* + ID_OUI_FROM_DATABASE=Baudisch Electronic GmbH + +OUI:0050C22A0* + ID_OUI_FROM_DATABASE=Sterling Industry Consult GmbH + +OUI:0050C22A1* + ID_OUI_FROM_DATABASE=Infinetix Corp + +OUI:0050C22A2* + ID_OUI_FROM_DATABASE=Epelsa, SL + +OUI:0050C22A3* + ID_OUI_FROM_DATABASE=West-Com Nurse Call Systems, Inc. + +OUI:0050C22A4* + ID_OUI_FROM_DATABASE=Xipher Embedded Networking + +OUI:0050C22A5* + ID_OUI_FROM_DATABASE=Septier Communication Ltd + +OUI:0050C22A6* + ID_OUI_FROM_DATABASE=Brannstroms Elektronik AB + +OUI:0050C22A7* + ID_OUI_FROM_DATABASE=Micro System Architecturing srl + +OUI:0050C22A8* + ID_OUI_FROM_DATABASE=DVTel Israel Ltd. + +OUI:0050C22A9* + ID_OUI_FROM_DATABASE=Dr. Staiger, Mohilo + Co GmbH + +OUI:0050C22AA* + ID_OUI_FROM_DATABASE=DEUTA Werke GmbH + +OUI:0050C22AB* + ID_OUI_FROM_DATABASE=AUM Infotech Private Limited + +OUI:0050C22AC* + ID_OUI_FROM_DATABASE=BBI Engineering, Inc. + +OUI:0050C22AD* + ID_OUI_FROM_DATABASE=ABB T&D Spa + +OUI:0050C22AE* + ID_OUI_FROM_DATABASE=Quest Retail Technology Pty Ltd + +OUI:0050C22AF* + ID_OUI_FROM_DATABASE=CSA Computer & Antriebstechnik GmbH + +OUI:0050C22B0* + ID_OUI_FROM_DATABASE=Telda Electronics + +OUI:0050C22B2* + ID_OUI_FROM_DATABASE=Smiths Detection + +OUI:0050C22B3* + ID_OUI_FROM_DATABASE=Embedded Systems Design + +OUI:0050C22B4* + ID_OUI_FROM_DATABASE=Polatis Ltd + +OUI:0050C22B5* + ID_OUI_FROM_DATABASE=Hobbes Computer Network Accessories + +OUI:0050C22B6* + ID_OUI_FROM_DATABASE=Softier Inc. + +OUI:0050C22B7* + ID_OUI_FROM_DATABASE=Rafi GmbH & Co. KG + +OUI:0050C22B8* + ID_OUI_FROM_DATABASE=Admiral Secure Products, Ltd. + +OUI:0050C22B9* + ID_OUI_FROM_DATABASE=Richmond Sound Design Ltd. + +OUI:0050C22BA* + ID_OUI_FROM_DATABASE=NORCO INDUSTRIAL TECHNOLOGY INC + +OUI:0050C22BB* + ID_OUI_FROM_DATABASE=TA Instruments Ltd + +OUI:0050C22BC* + ID_OUI_FROM_DATABASE=Uster Technologies AG + +OUI:0050C22BD* + ID_OUI_FROM_DATABASE=StorLink Semi + +OUI:0050C22BE* + ID_OUI_FROM_DATABASE=Lipowsky Industrie-Elektronik GmbH + +OUI:0050C22BF* + ID_OUI_FROM_DATABASE=PERAX + +OUI:0050C22C0* + ID_OUI_FROM_DATABASE=Magellan Technology Pty Ltd + +OUI:0050C22C1* + ID_OUI_FROM_DATABASE=Stage Tec Entwicklungsgesellschaft für professionelle Audio + +OUI:0050C22C2* + ID_OUI_FROM_DATABASE=smarteye corporation + +OUI:0050C22C3* + ID_OUI_FROM_DATABASE=Digital SP Ltd + +OUI:0050C22C4* + ID_OUI_FROM_DATABASE=Invensys Energy Systens (NZ) Limited + +OUI:0050C22C5* + ID_OUI_FROM_DATABASE=Elman srl + +OUI:0050C22C6* + ID_OUI_FROM_DATABASE=Initial Electronic Security Systems + +OUI:0050C22C7* + ID_OUI_FROM_DATABASE=Siliquent Technologies Ltd + +OUI:0050C22C8* + ID_OUI_FROM_DATABASE=SELCO + +OUI:0050C22C9* + ID_OUI_FROM_DATABASE=Roseman Engineering Ltd. + +OUI:0050C22CA* + ID_OUI_FROM_DATABASE=PUTERCOM CO., LTD + +OUI:0050C22CB* + ID_OUI_FROM_DATABASE=FACTS Engineering LLC + +OUI:0050C22CC* + ID_OUI_FROM_DATABASE=EMBEDDED TOOLSMITHS + +OUI:0050C22CD* + ID_OUI_FROM_DATABASE=DataWind Research + +OUI:0050C22CE* + ID_OUI_FROM_DATABASE=Ross Video Limited + +OUI:0050C22CF* + ID_OUI_FROM_DATABASE=Diseño de Sistemas en Silicio S.A. + +OUI:0050C22D0* + ID_OUI_FROM_DATABASE=Worth Data, Inc. + +OUI:0050C22D1* + ID_OUI_FROM_DATABASE=Miritek, Inc. + +OUI:0050C22D2* + ID_OUI_FROM_DATABASE=AIRNET COMMUNICATIONS CORP + +OUI:0050C22D3* + ID_OUI_FROM_DATABASE=Gerber Scientific Products, Inc. + +OUI:0050C22D4* + ID_OUI_FROM_DATABASE=Integrated System Solution Corp. + +OUI:0050C22D5* + ID_OUI_FROM_DATABASE=PIXY AG + +OUI:0050C22D6* + ID_OUI_FROM_DATABASE=WIS Technologies + +OUI:0050C22D7* + ID_OUI_FROM_DATABASE=Neo Electronics Ltd + +OUI:0050C22D8* + ID_OUI_FROM_DATABASE=SYN-TECH SYSTEMS INC + +OUI:0050C22DA* + ID_OUI_FROM_DATABASE=PYRAMID Computer GmbH + +OUI:0050C22DB* + ID_OUI_FROM_DATABASE=AutoTOOLS group Co. Ltd. + +OUI:0050C22DC* + ID_OUI_FROM_DATABASE=Wiener, Plein & Baus GmbH + +OUI:0050C22DD* + ID_OUI_FROM_DATABASE=Westek Technology Ltd + +OUI:0050C22DE* + ID_OUI_FROM_DATABASE=Research Applications + +OUI:0050C22DF* + ID_OUI_FROM_DATABASE=MICREL-NKE + +OUI:0050C22E0* + ID_OUI_FROM_DATABASE=Baxter Healthcare + +OUI:0050C22E1* + ID_OUI_FROM_DATABASE=Access IS + +OUI:0050C22E2* + ID_OUI_FROM_DATABASE=Ballard Technology, Inc. + +OUI:0050C22E3* + ID_OUI_FROM_DATABASE=MG Industrieelektronik GmbH + +OUI:0050C22E4* + ID_OUI_FROM_DATABASE=iamba LTD. + +OUI:0050C22E5* + ID_OUI_FROM_DATABASE=Transtech DSP + +OUI:0050C22E6* + ID_OUI_FROM_DATABASE=DALSA + +OUI:0050C22E7* + ID_OUI_FROM_DATABASE=SafeView, Inc. + +OUI:0050C22E8* + ID_OUI_FROM_DATABASE=S.M.V. Systemelektronik GmbH + +OUI:0050C22E9* + ID_OUI_FROM_DATABASE=SRI International + +OUI:0050C22EA* + ID_OUI_FROM_DATABASE=QUBIsoft S.r.l. + +OUI:0050C22EB* + ID_OUI_FROM_DATABASE=Lingg & Janke OHG + +OUI:0050C22EC* + ID_OUI_FROM_DATABASE=CHENGDU BOOK DIGITAL CO., LTD + +OUI:0050C22ED* + ID_OUI_FROM_DATABASE=4RF Communications Ltd + +OUI:0050C22EE* + ID_OUI_FROM_DATABASE=SHF Communication Technologies AG + +OUI:0050C22EF* + ID_OUI_FROM_DATABASE=Profline B.V. + +OUI:0050C22F0* + ID_OUI_FROM_DATABASE=LECO Corporation + +OUI:0050C22F1* + ID_OUI_FROM_DATABASE=Geometrics, Inc. + +OUI:0050C22F2* + ID_OUI_FROM_DATABASE=Eurotek Srl + +OUI:0050C22F3* + ID_OUI_FROM_DATABASE=Crossbow Technology, Inc. + +OUI:0050C22F4* + ID_OUI_FROM_DATABASE=Efficient Channel Coding + +OUI:0050C22F5* + ID_OUI_FROM_DATABASE=ADChips + +OUI:0050C22F6* + ID_OUI_FROM_DATABASE=Clifford Chance LLP + +OUI:0050C22F7* + ID_OUI_FROM_DATABASE=GILLAM-FEI S.A. + +OUI:0050C22F8* + ID_OUI_FROM_DATABASE=SavvyCorp.com Ltd + +OUI:0050C22F9* + ID_OUI_FROM_DATABASE=Digilent Inc. + +OUI:0050C22FA* + ID_OUI_FROM_DATABASE=Tornado Modular Systems, Ltd + +OUI:0050C22FB* + ID_OUI_FROM_DATABASE=Arthur Industries Inc., dba On Hold Media Group + +OUI:0050C22FC* + ID_OUI_FROM_DATABASE=Blackline Systems Corporation + +OUI:0050C22FD* + ID_OUI_FROM_DATABASE=American Microsystems LTD + +OUI:0050C22FE* + ID_OUI_FROM_DATABASE=Saab AB + +OUI:0050C22FF* + ID_OUI_FROM_DATABASE=Patria Advanced Solutions + +OUI:0050C2300* + ID_OUI_FROM_DATABASE=Soredex Instrumentarium Oyj + +OUI:0050C2301* + ID_OUI_FROM_DATABASE=Delphi Display Systems, Inc. + +OUI:0050C2302* + ID_OUI_FROM_DATABASE=EuroDesign embedded technologies GmbH + +OUI:0050C2303* + ID_OUI_FROM_DATABASE=CI Systems Ltd. + +OUI:0050C2304* + ID_OUI_FROM_DATABASE=COMERSON S.r.l. + +OUI:0050C2305* + ID_OUI_FROM_DATABASE=Symbium Corporation + +OUI:0050C2306* + ID_OUI_FROM_DATABASE=Noran Tel Communications Ltd. + +OUI:0050C2307* + ID_OUI_FROM_DATABASE=UNIONDIGITAL.,CO.LTD + +OUI:0050C2308* + ID_OUI_FROM_DATABASE=FiveCo + +OUI:0050C2309* + ID_OUI_FROM_DATABASE=Rackmaster Systems, Inc. + +OUI:0050C230A* + ID_OUI_FROM_DATABASE=Innings Telecom Inc. + +OUI:0050C230B* + ID_OUI_FROM_DATABASE=VX Technologies Inc. + +OUI:0050C230C* + ID_OUI_FROM_DATABASE=TEAMLOG + +OUI:0050C230D* + ID_OUI_FROM_DATABASE=SETARAM + +OUI:0050C230E* + ID_OUI_FROM_DATABASE=Obvius + +OUI:0050C230F* + ID_OUI_FROM_DATABASE=Digicontrole Lda + +OUI:0050C2310* + ID_OUI_FROM_DATABASE=CYBERTRON CO., LTD. + +OUI:0050C2311* + ID_OUI_FROM_DATABASE=Comodo + +OUI:0050C2312* + ID_OUI_FROM_DATABASE=Dese Technologies SL + +OUI:0050C2313* + ID_OUI_FROM_DATABASE=SAIA Burgess Controls AG + +OUI:0050C2314* + ID_OUI_FROM_DATABASE=MicroBee Systems, Inc + +OUI:0050C2315* + ID_OUI_FROM_DATABASE=ifak system GmbH + +OUI:0050C2316* + ID_OUI_FROM_DATABASE=Dataline AB + +OUI:0050C2317* + ID_OUI_FROM_DATABASE=Cosine Systems, Inc. + +OUI:0050C2318* + ID_OUI_FROM_DATABASE=Milmega Ltd + +OUI:0050C2319* + ID_OUI_FROM_DATABASE=Invatron Systems Corp. + +OUI:0050C231A* + ID_OUI_FROM_DATABASE=IN-SNEC ZODIAC + +OUI:0050C231B* + ID_OUI_FROM_DATABASE=Datacon + +OUI:0050C231C* + ID_OUI_FROM_DATABASE=Casa Systems Inc. + +OUI:0050C231D* + ID_OUI_FROM_DATABASE=Imarda New Zealand Limited + +OUI:0050C231E* + ID_OUI_FROM_DATABASE=C3-ilex, LLC + +OUI:0050C231F* + ID_OUI_FROM_DATABASE=Geotech Instruments, LLC + +OUI:0050C2320* + ID_OUI_FROM_DATABASE=DTASENSOR S.p.A. + +OUI:0050C2321* + ID_OUI_FROM_DATABASE=UXP + +OUI:0050C2322* + ID_OUI_FROM_DATABASE=BQT Solutions (Australia) Limited + +OUI:0050C2323* + ID_OUI_FROM_DATABASE=Red Rock Networks + +OUI:0050C2324* + ID_OUI_FROM_DATABASE=ODIXION + +OUI:0050C2325* + ID_OUI_FROM_DATABASE=Federal Aviation Administration + +OUI:0050C2326* + ID_OUI_FROM_DATABASE=Navionics S.p.A. + +OUI:0050C2327* + ID_OUI_FROM_DATABASE=Dornier GmbH + +OUI:0050C2328* + ID_OUI_FROM_DATABASE=I.C.S. Electronics Limited + +OUI:0050C2329* + ID_OUI_FROM_DATABASE=Imax + +OUI:0050C232A* + ID_OUI_FROM_DATABASE=PHYTEC Messtechnik GmbH + +OUI:0050C232B* + ID_OUI_FROM_DATABASE=Digital Multimedia Technologies Spa + +OUI:0050C232C* + ID_OUI_FROM_DATABASE=Integrated Silicon Solution (Taiwan), Inc. + +OUI:0050C232D* + ID_OUI_FROM_DATABASE=Consens Zeiterfassung GMBH + +OUI:0050C232E* + ID_OUI_FROM_DATABASE=MANUSA-GEST, S.L. + +OUI:0050C232F* + ID_OUI_FROM_DATABASE=PULTRONICS + +OUI:0050C2330* + ID_OUI_FROM_DATABASE=Sicon S.r.l. + +OUI:0050C2331* + ID_OUI_FROM_DATABASE=Broadcast Sports Inc + +OUI:0050C2332* + ID_OUI_FROM_DATABASE=PUNJAB COMMUNICATIONS LTD + +OUI:0050C2333* + ID_OUI_FROM_DATABASE=Radix Corporation + +OUI:0050C2334* + ID_OUI_FROM_DATABASE=Picture Elements, Inc. + +OUI:0050C2335* + ID_OUI_FROM_DATABASE=Nimcat Networks + +OUI:0050C2336* + ID_OUI_FROM_DATABASE=Golden River Traffic + +OUI:0050C2337* + ID_OUI_FROM_DATABASE=ETI + +OUI:0050C2338* + ID_OUI_FROM_DATABASE=Ernitec A/S + +OUI:0050C2339* + ID_OUI_FROM_DATABASE=CEGELEC SUD EST + +OUI:0050C233A* + ID_OUI_FROM_DATABASE=United Telecoms Ltd + +OUI:0050C233B* + ID_OUI_FROM_DATABASE=MultimediaLED + +OUI:0050C233C* + ID_OUI_FROM_DATABASE=SkipJam + +OUI:0050C233D* + ID_OUI_FROM_DATABASE=General Dynamics Decision Systems + +OUI:0050C233E* + ID_OUI_FROM_DATABASE=CA Technology, Inc + +OUI:0050C233F* + ID_OUI_FROM_DATABASE=EXYS bvba + +OUI:0050C2340* + ID_OUI_FROM_DATABASE=Virtu + +OUI:0050C2341* + ID_OUI_FROM_DATABASE=Novx Systems Canada Inc. + +OUI:0050C2342* + ID_OUI_FROM_DATABASE=St. Michael Strategies + +OUI:0050C2343* + ID_OUI_FROM_DATABASE=ABB Xiamen Switchgear Co. Ltd. + +OUI:0050C2344* + ID_OUI_FROM_DATABASE=ads-tec GmbH + +OUI:0050C2345* + ID_OUI_FROM_DATABASE=ACT + +OUI:0050C2346* + ID_OUI_FROM_DATABASE=biokeysystem + +OUI:0050C2347* + ID_OUI_FROM_DATABASE=Row Seven Ltd + +OUI:0050C2348* + ID_OUI_FROM_DATABASE=KoolSpan, Inc. + +OUI:0050C2349* + ID_OUI_FROM_DATABASE=SSI Schaefer Peem + +OUI:0050C234A* + ID_OUI_FROM_DATABASE=NIE Corporation + +OUI:0050C234B* + ID_OUI_FROM_DATABASE=Ecutel Systems, Inc. + +OUI:0050C234C* + ID_OUI_FROM_DATABASE=Chuo Electric Works Co., LTD. + +OUI:0050C234D* + ID_OUI_FROM_DATABASE=BMK professional electronics GmbH + +OUI:0050C234E* + ID_OUI_FROM_DATABASE=ABB Power Technologies S.p.A. Unità  Operativa SACE (PTMV) + +OUI:0050C234F* + ID_OUI_FROM_DATABASE=North Pole Engineering, Inc. + +OUI:0050C2350* + ID_OUI_FROM_DATABASE=Kinesys Projects Limited + +OUI:0050C2351* + ID_OUI_FROM_DATABASE=Finesystem Co., Ltd + +OUI:0050C2352* + ID_OUI_FROM_DATABASE=edixia + +OUI:0050C2353* + ID_OUI_FROM_DATABASE=Crossing Informationssysteme GmbH + +OUI:0050C2354* + ID_OUI_FROM_DATABASE=Advanced IP Communications + +OUI:0050C2355* + ID_OUI_FROM_DATABASE=IHM + +OUI:0050C2356* + ID_OUI_FROM_DATABASE=Baytech Cinema + +OUI:0050C2357* + ID_OUI_FROM_DATABASE=Athena Semiconductor + +OUI:0050C2358* + ID_OUI_FROM_DATABASE=ALCEA + +OUI:0050C2359* + ID_OUI_FROM_DATABASE=Kramer Electronics Ltd. + +OUI:0050C235A* + ID_OUI_FROM_DATABASE=Advanced Si-Net Co., LTD. + +OUI:0050C235B* + ID_OUI_FROM_DATABASE=VLSIP TECHNOLOGIES, INC + +OUI:0050C235C* + ID_OUI_FROM_DATABASE=Ratotec GmbH + +OUI:0050C235D* + ID_OUI_FROM_DATABASE=NetTest A/S + +OUI:0050C235E* + ID_OUI_FROM_DATABASE=Jobin Yvon,Inc + +OUI:0050C235F* + ID_OUI_FROM_DATABASE=F.Imm. S.r.L. + +OUI:0050C2360* + ID_OUI_FROM_DATABASE=Digital Receiver Technology, Inc. + +OUI:0050C2361* + ID_OUI_FROM_DATABASE=Contec + +OUI:0050C2362* + ID_OUI_FROM_DATABASE=AZD Praha s.r.o. + +OUI:0050C2363* + ID_OUI_FROM_DATABASE=Septentrio nv/sa + +OUI:0050C2364* + ID_OUI_FROM_DATABASE=TATTILE SRL + +OUI:0050C2365* + ID_OUI_FROM_DATABASE=Vishay Nobel AB + +OUI:0050C2366* + ID_OUI_FROM_DATABASE=Vanguard Technology Corp. + +OUI:0050C2367* + ID_OUI_FROM_DATABASE=CANMAX Technology Ltd. + +OUI:0050C2368* + ID_OUI_FROM_DATABASE=ASPEL S.A. + +OUI:0050C2369* + ID_OUI_FROM_DATABASE=Always On Wireless + +OUI:0050C236A* + ID_OUI_FROM_DATABASE=Optronic Partner pr AB + +OUI:0050C236B* + ID_OUI_FROM_DATABASE=Minerva Technology Inc + +OUI:0050C236C* + ID_OUI_FROM_DATABASE=RISCO Group + +OUI:0050C236D* + ID_OUI_FROM_DATABASE=Oplink Communications + +OUI:0050C236E* + ID_OUI_FROM_DATABASE=Minicom Advanced Systems Ltd + +OUI:0050C236F* + ID_OUI_FROM_DATABASE=SOFTHARD Technology Ltd + +OUI:0050C2370* + ID_OUI_FROM_DATABASE=Europe Technologies + +OUI:0050C2371* + ID_OUI_FROM_DATABASE=DIGITAL ART SYSTEM + +OUI:0050C2372* + ID_OUI_FROM_DATABASE=ELV Elektronik AG + +OUI:0050C2373* + ID_OUI_FROM_DATABASE=Companion Worlds, inc. + +OUI:0050C2374* + ID_OUI_FROM_DATABASE=Owasys Advanced Wireless Devices + +OUI:0050C2375* + ID_OUI_FROM_DATABASE=TIR Systems Ltd. + +OUI:0050C2376* + ID_OUI_FROM_DATABASE=CLEODE + +OUI:0050C2377* + ID_OUI_FROM_DATABASE=Xycom VME + +OUI:0050C2378* + ID_OUI_FROM_DATABASE=Daintree Networks Inc + +OUI:0050C2379* + ID_OUI_FROM_DATABASE=Control LAN S.A. + +OUI:0050C237A* + ID_OUI_FROM_DATABASE=IDA Corporation + +OUI:0050C237B* + ID_OUI_FROM_DATABASE=freescale semiconductor + +OUI:0050C237C* + ID_OUI_FROM_DATABASE=MODIA SYSTEMS Co., Ltd + +OUI:0050C237D* + ID_OUI_FROM_DATABASE=VeroTrak Inc. + +OUI:0050C237E* + ID_OUI_FROM_DATABASE=Ni.Co. S.r.l. + +OUI:0050C237F* + ID_OUI_FROM_DATABASE=Foresearch + +OUI:0050C2380* + ID_OUI_FROM_DATABASE=EKE-Electronics Ltd. + +OUI:0050C2381* + ID_OUI_FROM_DATABASE=Realtime Engineering AG + +OUI:0050C2382* + ID_OUI_FROM_DATABASE=Colorado vNet + +OUI:0050C2383* + ID_OUI_FROM_DATABASE=ICS Electronics + +OUI:0050C2384* + ID_OUI_FROM_DATABASE=Wireless Reading Systems Holding ASA + +OUI:0050C2385* + ID_OUI_FROM_DATABASE=SUNGJIN NEOTECH Co.Ltd. + +OUI:0050C2386* + ID_OUI_FROM_DATABASE=Precision System Science Co.,Ltd + +OUI:0050C2387* + ID_OUI_FROM_DATABASE=Inoteska s.r.o. + +OUI:0050C2388* + ID_OUI_FROM_DATABASE=IEE Inc + +OUI:0050C2389* + ID_OUI_FROM_DATABASE=Exavio Inc. + +OUI:0050C238A* + ID_OUI_FROM_DATABASE=Embedtronics Enterprise + +OUI:0050C238B* + ID_OUI_FROM_DATABASE=InterBridge,Inc. + +OUI:0050C238C* + ID_OUI_FROM_DATABASE=EPSILON SRL + +OUI:0050C238D* + ID_OUI_FROM_DATABASE=A&G Soluzioni Digitali + +OUI:0050C238E* + ID_OUI_FROM_DATABASE=Nordic Alarm AB + +OUI:0050C238F* + ID_OUI_FROM_DATABASE=TTC Telecom + +OUI:0050C2390* + ID_OUI_FROM_DATABASE=TC Communications + +OUI:0050C2391* + ID_OUI_FROM_DATABASE=Esensors, Inc. + +OUI:0050C2392* + ID_OUI_FROM_DATABASE=PHYTEC Messtechnik GmbH + +OUI:0050C2393* + ID_OUI_FROM_DATABASE=SYS TEC electronic GmbH + +OUI:0050C2394* + ID_OUI_FROM_DATABASE=Embedit A/S + +OUI:0050C2395* + ID_OUI_FROM_DATABASE=vidisys gmbh + +OUI:0050C2396* + ID_OUI_FROM_DATABASE=RapidWave Inc. + +OUI:0050C2397* + ID_OUI_FROM_DATABASE=MANGO DSP Ltd. + +OUI:0050C2398* + ID_OUI_FROM_DATABASE=InHand Electronics, Inc. + +OUI:0050C2399* + ID_OUI_FROM_DATABASE=Advanced Micro Controls Inc. + +OUI:0050C239A* + ID_OUI_FROM_DATABASE=Optical Air Data Systems + +OUI:0050C239B* + ID_OUI_FROM_DATABASE=YUYAMA MFG. CO., LTD. + +OUI:0050C239C* + ID_OUI_FROM_DATABASE=TIYODA MFG CO.,LTD. + +OUI:0050C239D* + ID_OUI_FROM_DATABASE=DigitalDeck, Inc. + +OUI:0050C239E* + ID_OUI_FROM_DATABASE=A.R.G ElectroDesign Ltd + +OUI:0050C239F* + ID_OUI_FROM_DATABASE=Isensix + +OUI:0050C23A0* + ID_OUI_FROM_DATABASE=StreetFire Sound Labs, LLC + +OUI:0050C23A1* + ID_OUI_FROM_DATABASE=Samsoft + +OUI:0050C23A2* + ID_OUI_FROM_DATABASE=Vegas Amusement + +OUI:0050C23A3* + ID_OUI_FROM_DATABASE=Star Link Communication Pvt. Ltd. + +OUI:0050C23A4* + ID_OUI_FROM_DATABASE=Silvertree Engineering Ltd + +OUI:0050C23A5* + ID_OUI_FROM_DATABASE=LabJack Corporation + +OUI:0050C23A6* + ID_OUI_FROM_DATABASE=IntelliDesign Pty Ltd + +OUI:0050C23A7* + ID_OUI_FROM_DATABASE=Elektrotechnik & Elektronik Oltmann GmbH + +OUI:0050C23A8* + ID_OUI_FROM_DATABASE=Engim, Inc. + +OUI:0050C23A9* + ID_OUI_FROM_DATABASE=Westronic Systems Inc. + +OUI:0050C23AA* + ID_OUI_FROM_DATABASE=Networked Robotics Corporation + +OUI:0050C23AB* + ID_OUI_FROM_DATABASE=taskit Rechnertechnik GmbH + +OUI:0050C23AC* + ID_OUI_FROM_DATABASE=InAccess Networks + +OUI:0050C23AD* + ID_OUI_FROM_DATABASE=Spirent Communications (Scotland) Limited + +OUI:0050C23AE* + ID_OUI_FROM_DATABASE=Hankuk Tapi Computer Co., Ltd + +OUI:0050C23AF* + ID_OUI_FROM_DATABASE=Norbit AS + +OUI:0050C23B0* + ID_OUI_FROM_DATABASE=Microtarget Tecnologia Digital Ltda. + +OUI:0050C23B1* + ID_OUI_FROM_DATABASE=RDC Specstroy-Svyaz Ltd + +OUI:0050C23B2* + ID_OUI_FROM_DATABASE=Tennessee Valley Authority + +OUI:0050C23B3* + ID_OUI_FROM_DATABASE=Media Lab., Inc. + +OUI:0050C23B4* + ID_OUI_FROM_DATABASE=Contrôle Analytique inc. + +OUI:0050C23B5* + ID_OUI_FROM_DATABASE=NEC TOKIN Corporation + +OUI:0050C23B6* + ID_OUI_FROM_DATABASE=Arecont Vision, LLC + +OUI:0050C23B7* + ID_OUI_FROM_DATABASE=Mindspeed Technologies + +OUI:0050C23B8* + ID_OUI_FROM_DATABASE=Keith & Koep GmbH + +OUI:0050C23B9* + ID_OUI_FROM_DATABASE=Gilbarco Autotank AB + +OUI:0050C23BA* + ID_OUI_FROM_DATABASE=PHYTEC Messtechnik GmbH + +OUI:0050C23BB* + ID_OUI_FROM_DATABASE=IMAGO Technologies GmbH + +OUI:0050C23BC* + ID_OUI_FROM_DATABASE=Tyzx, Inc. + +OUI:0050C23BD* + ID_OUI_FROM_DATABASE=Bigbang L.T.D. + +OUI:0050C23BE* + ID_OUI_FROM_DATABASE=Pauly Steuer- und Regelanlagen GmbH & Co. KG + +OUI:0050C23BF* + ID_OUI_FROM_DATABASE=Audio Processing Technology Ltd + +OUI:0050C23C0* + ID_OUI_FROM_DATABASE=EDA Industries Srl + +OUI:0050C23C1* + ID_OUI_FROM_DATABASE=MicroTek Electronics, Inc. + +OUI:0050C23C2* + ID_OUI_FROM_DATABASE=Casabyte Inc. + +OUI:0050C23C3* + ID_OUI_FROM_DATABASE=4g Technologies, L.P. + +OUI:0050C23C4* + ID_OUI_FROM_DATABASE=Sypris Electronics + +OUI:0050C23C5* + ID_OUI_FROM_DATABASE=Silicon Optix Canada Inc. + +OUI:0050C23C6* + ID_OUI_FROM_DATABASE=Net Optics + +OUI:0050C23C7* + ID_OUI_FROM_DATABASE=Salent Technologies Ltd + +OUI:0050C23C8* + ID_OUI_FROM_DATABASE=Wheels of Zeus Inc. + +OUI:0050C23C9* + ID_OUI_FROM_DATABASE=Dilax Intelcom AG + +OUI:0050C23CA* + ID_OUI_FROM_DATABASE=ABB Inc. + +OUI:0050C23CB* + ID_OUI_FROM_DATABASE=Analytica GmbH + +OUI:0050C23CC* + ID_OUI_FROM_DATABASE=LINKWELL TELESYSTEMS PRIVATE LIMITED + +OUI:0050C23CD* + ID_OUI_FROM_DATABASE=Micro-Measurements + +OUI:0050C23CE* + ID_OUI_FROM_DATABASE=Ward Leonard Electric Company + +OUI:0050C23CF* + ID_OUI_FROM_DATABASE=Technovare Systems, Inc. + +OUI:0050C23D0* + ID_OUI_FROM_DATABASE=Micro-Robotics Limited + +OUI:0050C23D1* + ID_OUI_FROM_DATABASE=Braintronics BV + +OUI:0050C23D2* + ID_OUI_FROM_DATABASE=Adilec Enginyeria SL + +OUI:0050C23D3* + ID_OUI_FROM_DATABASE=American LED-gible Inc. + +OUI:0050C23D4* + ID_OUI_FROM_DATABASE=Wisnu and Supak Co.Ltd. + +OUI:0050C23D5* + ID_OUI_FROM_DATABASE=Fluke Biomedical, Radiation Management Services + +OUI:0050C23D6* + ID_OUI_FROM_DATABASE=Comlab Inc. + +OUI:0050C23D7* + ID_OUI_FROM_DATABASE=TTC TELEKOMUNIKACE Ltd + +OUI:0050C23D8* + ID_OUI_FROM_DATABASE=Key Systems , Inc. + +OUI:0050C23D9* + ID_OUI_FROM_DATABASE=Bavaria Digital Technik GmbH + +OUI:0050C23DA* + ID_OUI_FROM_DATABASE=M5 Data Limited + +OUI:0050C23DB* + ID_OUI_FROM_DATABASE=Osmetech Inc. + +OUI:0050C23DC* + ID_OUI_FROM_DATABASE=3D perception + +OUI:0050C23DD* + ID_OUI_FROM_DATABASE=ELMIC GmbH + +OUI:0050C23DE* + ID_OUI_FROM_DATABASE=ABB Power Technologies + +OUI:0050C23DF* + ID_OUI_FROM_DATABASE=BiODE Inc. + +OUI:0050C23E0* + ID_OUI_FROM_DATABASE=Oy Stinghorn Ltd + +OUI:0050C23E1* + ID_OUI_FROM_DATABASE=NeuLion Incorporated + +OUI:0050C23E2* + ID_OUI_FROM_DATABASE=SysNova + +OUI:0050C23E3* + ID_OUI_FROM_DATABASE=CSIRO - Division of Exploration and Mining + +OUI:0050C23E4* + ID_OUI_FROM_DATABASE=CUE, a.s. + +OUI:0050C23E5* + ID_OUI_FROM_DATABASE=Vacon Plc + +OUI:0050C23E6* + ID_OUI_FROM_DATABASE=CRDE + +OUI:0050C23E7* + ID_OUI_FROM_DATABASE=Revolution Education Ltd + +OUI:0050C23E8* + ID_OUI_FROM_DATABASE=Conformative Systems, Inc. + +OUI:0050C23E9* + ID_OUI_FROM_DATABASE=MedAvant Healthcare + +OUI:0050C23EA* + ID_OUI_FROM_DATABASE=Alro Information Systems SA + +OUI:0050C23EB* + ID_OUI_FROM_DATABASE=ISS International + +OUI:0050C23EC* + ID_OUI_FROM_DATABASE=Teneros + +OUI:0050C23ED* + ID_OUI_FROM_DATABASE=The Board Room Inc. + +OUI:0050C23EE* + ID_OUI_FROM_DATABASE=Commoca, Inc + +OUI:0050C23EF* + ID_OUI_FROM_DATABASE=PAT Industries, DBA Pacific Advanced Technology + +OUI:0050C23F0* + ID_OUI_FROM_DATABASE=megatec electronic GmbH + +OUI:0050C23F1* + ID_OUI_FROM_DATABASE=Salland Electronics Holding BV + +OUI:0050C23F2* + ID_OUI_FROM_DATABASE=STL GmbH + +OUI:0050C23F3* + ID_OUI_FROM_DATABASE=Hytec Gerätebau GmbH + +OUI:0050C23F4* + ID_OUI_FROM_DATABASE=MC TECHNOLOGY GmbH + +OUI:0050C23F5* + ID_OUI_FROM_DATABASE=Phaedrus Limited + +OUI:0050C23F6* + ID_OUI_FROM_DATABASE=dAFTdATA Limited + +OUI:0050C23F7* + ID_OUI_FROM_DATABASE=Advantage R&D + +OUI:0050C23F8* + ID_OUI_FROM_DATABASE=Superna Ltd + +OUI:0050C23F9* + ID_OUI_FROM_DATABASE=Sintium Ltd + +OUI:0050C23FA* + ID_OUI_FROM_DATABASE=Tumsan + +OUI:0050C23FB* + ID_OUI_FROM_DATABASE=Pigeon Point Systems + +OUI:0050C23FC* + ID_OUI_FROM_DATABASE=Weinberger Deutschland GmbH + +OUI:0050C23FD* + ID_OUI_FROM_DATABASE=HARTMANN software GbR + +OUI:0050C23FE* + ID_OUI_FROM_DATABASE=HaiVision Systems Incorporated + +OUI:0050C23FF* + ID_OUI_FROM_DATABASE=Cast Iron Systems + +OUI:0050C2400* + ID_OUI_FROM_DATABASE=SmartMotor AS + +OUI:0050C2401* + ID_OUI_FROM_DATABASE=Promess Incorporated + +OUI:0050C2402* + ID_OUI_FROM_DATABASE=Numeron Sp. z o.o. + +OUI:0050C2403* + ID_OUI_FROM_DATABASE=Rohde & Schwarz Topex SA + +OUI:0050C2404* + ID_OUI_FROM_DATABASE=NanShanBridge Co.Ltd + +OUI:0050C2405* + ID_OUI_FROM_DATABASE=Guralp Systems Limited + +OUI:0050C2406* + ID_OUI_FROM_DATABASE=CoreStreet, Ltd + +OUI:0050C2407* + ID_OUI_FROM_DATABASE=AIE Etudes + +OUI:0050C2408* + ID_OUI_FROM_DATABASE=TERN, Inc. + +OUI:0050C2409* + ID_OUI_FROM_DATABASE=KTEC LTD + +OUI:0050C240A* + ID_OUI_FROM_DATABASE=Contec Steuerungstechnik & Automation GmbH + +OUI:0050C240B* + ID_OUI_FROM_DATABASE=Center VOSPI JSC + +OUI:0050C240C* + ID_OUI_FROM_DATABASE=Applied Materials UK Ltd + +OUI:0050C240D* + ID_OUI_FROM_DATABASE=Afonics Fibreoptics Ltd + +OUI:0050C240E* + ID_OUI_FROM_DATABASE=ads-tec GmbH + +OUI:0050C240F* + ID_OUI_FROM_DATABASE=BIR,INC. + +OUI:0050C2410* + ID_OUI_FROM_DATABASE=Grossenbacher Systeme AG + +OUI:0050C2411* + ID_OUI_FROM_DATABASE=Multimessage Systems Ltd. + +OUI:0050C2412* + ID_OUI_FROM_DATABASE=TSB Solutions Inc. + +OUI:0050C2413* + ID_OUI_FROM_DATABASE=Goodrich + +OUI:0050C2414* + ID_OUI_FROM_DATABASE=Talleres de Escoriaza SA + +OUI:0050C2415* + ID_OUI_FROM_DATABASE=SensoTech GmbH + +OUI:0050C2416* + ID_OUI_FROM_DATABASE=SELCO s.r.l. + +OUI:0050C2417* + ID_OUI_FROM_DATABASE=QT systems ab + +OUI:0050C2418* + ID_OUI_FROM_DATABASE=Planea Oy + +OUI:0050C2419* + ID_OUI_FROM_DATABASE=Mecsel Oy + +OUI:0050C241A* + ID_OUI_FROM_DATABASE=Bluewater Systems Ltd + +OUI:0050C241B* + ID_OUI_FROM_DATABASE=LogiM GmbH Software und Entwicklung + +OUI:0050C241C* + ID_OUI_FROM_DATABASE=Infrasafe, Inc. + +OUI:0050C241D* + ID_OUI_FROM_DATABASE=Altronic, Inc. + +OUI:0050C241E* + ID_OUI_FROM_DATABASE=Videotek Sistemas Eletronicos Ltda. + +OUI:0050C241F* + ID_OUI_FROM_DATABASE=Avionica, Inc + +OUI:0050C2420* + ID_OUI_FROM_DATABASE=Boundless Technologies + +OUI:0050C2421* + ID_OUI_FROM_DATABASE=EFSYS + +OUI:0050C2422* + ID_OUI_FROM_DATABASE=Gekeler Martina + +OUI:0050C2423* + ID_OUI_FROM_DATABASE=Power-One Inc. + +OUI:0050C2424* + ID_OUI_FROM_DATABASE=Metrolab Instruments SA + +OUI:0050C2425* + ID_OUI_FROM_DATABASE=Pinnacle Technology + +OUI:0050C2426* + ID_OUI_FROM_DATABASE=STOM System + +OUI:0050C2427* + ID_OUI_FROM_DATABASE=Scheidt & Bachmann GmbH + +OUI:0050C2428* + ID_OUI_FROM_DATABASE=Roxar A/S + +OUI:0050C2429* + ID_OUI_FROM_DATABASE=Matthews Australasia + +OUI:0050C242A* + ID_OUI_FROM_DATABASE=DSP DESIGN + +OUI:0050C242B* + ID_OUI_FROM_DATABASE=VLSIP TECHNOLOGIES, INC. + +OUI:0050C242C* + ID_OUI_FROM_DATABASE=Trapeze ITS U.S.A., LLC + +OUI:0050C242D* + ID_OUI_FROM_DATABASE=Argo-Tech + +OUI:0050C242E* + ID_OUI_FROM_DATABASE=Oelmann Elektronik GmbH + +OUI:0050C242F* + ID_OUI_FROM_DATABASE=Win4NET + +OUI:0050C2430* + ID_OUI_FROM_DATABASE=Arcom Digital + +OUI:0050C2431* + ID_OUI_FROM_DATABASE=Octatron, Inc. + +OUI:0050C2432* + ID_OUI_FROM_DATABASE=Topway Industries Ltd. + +OUI:0050C2433* + ID_OUI_FROM_DATABASE=Idetech Europe S.A. + +OUI:0050C2434* + ID_OUI_FROM_DATABASE=ImperativeNetworks + +OUI:0050C2435* + ID_OUI_FROM_DATABASE=ADATEL TELECOMUNICACIONES S.A. + +OUI:0050C2436* + ID_OUI_FROM_DATABASE=Satellite Services BV + +OUI:0050C2437* + ID_OUI_FROM_DATABASE=PowerWAN, Inc + +OUI:0050C2438* + ID_OUI_FROM_DATABASE=Telecom Protection Technologies Limited + +OUI:0050C2439* + ID_OUI_FROM_DATABASE=Peleton Photonic Systems + +OUI:0050C243A* + ID_OUI_FROM_DATABASE=ProDesign GmbH + +OUI:0050C243B* + ID_OUI_FROM_DATABASE=A3IP + +OUI:0050C243C* + ID_OUI_FROM_DATABASE=LaBarge + +OUI:0050C243D* + ID_OUI_FROM_DATABASE=Ann Arbor Sensor Systems LLC + +OUI:0050C243E* + ID_OUI_FROM_DATABASE=Coppercom + +OUI:0050C243F* + ID_OUI_FROM_DATABASE=ARVOO Imaging Products BV + +OUI:0050C2440* + ID_OUI_FROM_DATABASE=Advanced Modular Computers Ltd. + +OUI:0050C2441* + ID_OUI_FROM_DATABASE=Sammi Information Systems Co.,Ltd + +OUI:0050C2442* + ID_OUI_FROM_DATABASE=Pico Computing, Inc. + +OUI:0050C2443* + ID_OUI_FROM_DATABASE=Pickering Laboratories + +OUI:0050C2444* + ID_OUI_FROM_DATABASE=Offshore Systems Ltd + +OUI:0050C2445* + ID_OUI_FROM_DATABASE=MICRONIC s.r.o. + +OUI:0050C2446* + ID_OUI_FROM_DATABASE=Micro Technic A-S + +OUI:0050C2447* + ID_OUI_FROM_DATABASE=Grupo Epelsa S.L. + +OUI:0050C2448* + ID_OUI_FROM_DATABASE=Comtech Systems Inc. + +OUI:0050C2449* + ID_OUI_FROM_DATABASE=BLEILE DATENTECHNIK GmbH + +OUI:0050C244A* + ID_OUI_FROM_DATABASE=ELETTRONICA SANTERNO SPA + +OUI:0050C244B* + ID_OUI_FROM_DATABASE=Solace Systems, Inc. + +OUI:0050C244C* + ID_OUI_FROM_DATABASE=Computime Systems UK Ltd. + +OUI:0050C244D* + ID_OUI_FROM_DATABASE=Electro-Matic Products, Inc. + +OUI:0050C244E* + ID_OUI_FROM_DATABASE=QQ Technology,Inc + +OUI:0050C244F* + ID_OUI_FROM_DATABASE=kippdata GmbH + +OUI:0050C2450* + ID_OUI_FROM_DATABASE=Enconair Ecological Chambers Inc. + +OUI:0050C2451* + ID_OUI_FROM_DATABASE=HAMEG GmbH + +OUI:0050C2452* + ID_OUI_FROM_DATABASE=SCAME SISTEMI s.r.l. + +OUI:0050C2453* + ID_OUI_FROM_DATABASE=Erhardt + Leimer GmbH + +OUI:0050C2454* + ID_OUI_FROM_DATABASE=Brivo Systems, LLC + +OUI:0050C2455* + ID_OUI_FROM_DATABASE=AirCell, Inc. + +OUI:0050C2456* + ID_OUI_FROM_DATABASE=DRDC Valcartier + +OUI:0050C2457* + ID_OUI_FROM_DATABASE=Danbridge + +OUI:0050C2458* + ID_OUI_FROM_DATABASE=HRZ data GmbH + +OUI:0050C2459* + ID_OUI_FROM_DATABASE=PHYTEC Messtechnik GmbH + +OUI:0050C245A* + ID_OUI_FROM_DATABASE=Funkwerk plettac electronic GmbH + +OUI:0050C245B* + ID_OUI_FROM_DATABASE=Matra Electronique + +OUI:0050C245C* + ID_OUI_FROM_DATABASE=Deister Electronic GmbH + +OUI:0050C245D* + ID_OUI_FROM_DATABASE=Digital Engineering, Inc. + +OUI:0050C245E* + ID_OUI_FROM_DATABASE=Halliburton - Sperry Drilling Service + +OUI:0050C245F* + ID_OUI_FROM_DATABASE=T2C Marketing AB + +OUI:0050C2460* + ID_OUI_FROM_DATABASE=Vitelnet + +OUI:0050C2461* + ID_OUI_FROM_DATABASE=TATTILE SRL + +OUI:0050C2462* + ID_OUI_FROM_DATABASE=CT Company + +OUI:0050C2463* + ID_OUI_FROM_DATABASE=Codem Systems, Inc. + +OUI:0050C2464* + ID_OUI_FROM_DATABASE=XYTAC system technologies + +OUI:0050C2465* + ID_OUI_FROM_DATABASE=PDTS GmbH + +OUI:0050C2466* + ID_OUI_FROM_DATABASE=LoNAP Limited + +OUI:0050C2467* + ID_OUI_FROM_DATABASE=United Western Technologies + +OUI:0050C2468* + ID_OUI_FROM_DATABASE=Network I/O + +OUI:0050C2469* + ID_OUI_FROM_DATABASE=BiPOM Electronics, Inc. + +OUI:0050C246A* + ID_OUI_FROM_DATABASE=ISE GmbH + +OUI:0050C246B* + ID_OUI_FROM_DATABASE=EASYTECH GmbH + +OUI:0050C246C* + ID_OUI_FROM_DATABASE=CAMCO GmbH + +OUI:0050C246D* + ID_OUI_FROM_DATABASE=Paul Scherrer Institut (PSI) + +OUI:0050C246E* + ID_OUI_FROM_DATABASE=Avenir Technologies Inc. + +OUI:0050C246F* + ID_OUI_FROM_DATABASE=Neuroware + +OUI:0050C2470* + ID_OUI_FROM_DATABASE=Cybectec inc. + +OUI:0050C2471* + ID_OUI_FROM_DATABASE=Pixtree Technologies, inc. + +OUI:0050C2472* + ID_OUI_FROM_DATABASE=KOP Ltd + +OUI:0050C2473* + ID_OUI_FROM_DATABASE=Sensus Metering Systems Israel + +OUI:0050C2474* + ID_OUI_FROM_DATABASE=Venue 1, Inc. + +OUI:0050C2475* + ID_OUI_FROM_DATABASE=ISEPOS GmbH + +OUI:0050C2476* + ID_OUI_FROM_DATABASE=Ascon S.p.a. + +OUI:0050C2477* + ID_OUI_FROM_DATABASE=SEV Tidsystem AB + +OUI:0050C2478* + ID_OUI_FROM_DATABASE=Metafix Inc. + +OUI:0050C2479* + ID_OUI_FROM_DATABASE=Unlimited Bandwidth LLC + +OUI:0050C247A* + ID_OUI_FROM_DATABASE=Efficient Channel Coding + +OUI:0050C247B* + ID_OUI_FROM_DATABASE=Pitney Bowes, Inc + +OUI:0050C247C* + ID_OUI_FROM_DATABASE=AUCONET GmbH + +OUI:0050C247D* + ID_OUI_FROM_DATABASE=WIT Inc + +OUI:0050C247E* + ID_OUI_FROM_DATABASE=Energie Umwelt Systemtechnik GmbH + +OUI:0050C247F* + ID_OUI_FROM_DATABASE=BRIT Inc. + +OUI:0050C2480* + ID_OUI_FROM_DATABASE=SELKOM GmbH + +OUI:0050C2481* + ID_OUI_FROM_DATABASE=Computer Sciences Corp + +OUI:0050C2482* + ID_OUI_FROM_DATABASE=PRIAMUS SYSTEM TECHNOLOGIES AG + +OUI:0050C2483* + ID_OUI_FROM_DATABASE=SES + +OUI:0050C2484* + ID_OUI_FROM_DATABASE=Kooltech LLC + +OUI:0050C2485* + ID_OUI_FROM_DATABASE=PHYTEC Messtechnik GmbH + +OUI:0050C2486* + ID_OUI_FROM_DATABASE=Safegate International AB + +OUI:0050C2487* + ID_OUI_FROM_DATABASE=Eridon Corporation + +OUI:0050C2488* + ID_OUI_FROM_DATABASE=DA SISTEMI SPA + +OUI:0050C2489* + ID_OUI_FROM_DATABASE=EREE Electronique + +OUI:0050C248A* + ID_OUI_FROM_DATABASE=Mobile Matrix, Inc. + +OUI:0050C248B* + ID_OUI_FROM_DATABASE=ADS-TEC GmbH + +OUI:0050C248C* + ID_OUI_FROM_DATABASE=UNITON AG + +OUI:0050C248D* + ID_OUI_FROM_DATABASE=Metron Sp. z o.o. + +OUI:0050C248E* + ID_OUI_FROM_DATABASE=Teledyne Tekmar + +OUI:0050C248F* + ID_OUI_FROM_DATABASE=DENGYOSHA co.,LTD. + +OUI:0050C2490* + ID_OUI_FROM_DATABASE=Cloanto Corporation + +OUI:0050C2491* + ID_OUI_FROM_DATABASE=Fr. Sauter AG + +OUI:0050C2492* + ID_OUI_FROM_DATABASE=TRAFSYS AS + +OUI:0050C2493* + ID_OUI_FROM_DATABASE=Artis GmbH + +OUI:0050C2494* + ID_OUI_FROM_DATABASE=Ultimate Technology, Inc. + +OUI:0050C2495* + ID_OUI_FROM_DATABASE=VAZA Elektronik AB + +OUI:0050C2496* + ID_OUI_FROM_DATABASE=Acutelogic Corporation + +OUI:0050C2497* + ID_OUI_FROM_DATABASE=Advanced Driver Information Technology GmbH + +OUI:0050C2498* + ID_OUI_FROM_DATABASE=Quartet Technology, Inc. + +OUI:0050C2499* + ID_OUI_FROM_DATABASE=Trellia Networks + +OUI:0050C249A* + ID_OUI_FROM_DATABASE=TelASIC Communications, Inc. + +OUI:0050C249B* + ID_OUI_FROM_DATABASE=vg controls, inc + +OUI:0050C249C* + ID_OUI_FROM_DATABASE=Envisacor Technologies Inc. + +OUI:0050C249D* + ID_OUI_FROM_DATABASE=Critical Link + +OUI:0050C249E* + ID_OUI_FROM_DATABASE=Armorlink CO .Ltd + +OUI:0050C249F* + ID_OUI_FROM_DATABASE=GCS, Inc + +OUI:0050C24A0* + ID_OUI_FROM_DATABASE=Advanced technologies & Engineering (pty) Ltd + +OUI:0050C24A1* + ID_OUI_FROM_DATABASE=Pigeon Point Systems + +OUI:0050C24A2* + ID_OUI_FROM_DATABASE=SPECS GmbH + +OUI:0050C24A3* + ID_OUI_FROM_DATABASE=Protium Technologies, Inc. + +OUI:0050C24A4* + ID_OUI_FROM_DATABASE=IEEE P1609 WG + +OUI:0050C24A5* + ID_OUI_FROM_DATABASE=Teledyne Monitor Labs + +OUI:0050C24A6* + ID_OUI_FROM_DATABASE=BUYANG ELECTRONICS INDUSTRIAL CO., LTD. + +OUI:0050C24A7* + ID_OUI_FROM_DATABASE=iseg Spezialelektronik GmbH + +OUI:0050C24A8* + ID_OUI_FROM_DATABASE=CYJAYA Korea + +OUI:0050C24A9* + ID_OUI_FROM_DATABASE=Faber Electronics BV + +OUI:0050C24AA* + ID_OUI_FROM_DATABASE=HEINEN ELEKTRONIK GmbH + +OUI:0050C24AB* + ID_OUI_FROM_DATABASE=JVF Communications Ltd + +OUI:0050C24AC* + ID_OUI_FROM_DATABASE=Doramu Co.,Ltd. + +OUI:0050C24AD* + ID_OUI_FROM_DATABASE=OpenPeak, Inc. + +OUI:0050C24AE* + ID_OUI_FROM_DATABASE=ads-tec GmbH + +OUI:0050C24AF* + ID_OUI_FROM_DATABASE=Orbis Oy + +OUI:0050C24B0* + ID_OUI_FROM_DATABASE=Esmart Distribution Pte Ltd + +OUI:0050C24B1* + ID_OUI_FROM_DATABASE=Nsfocus Information Technology Co.,Ltd + +OUI:0050C24B2* + ID_OUI_FROM_DATABASE=TESLA, a.s. + +OUI:0050C24B3* + ID_OUI_FROM_DATABASE=ANSA Corporation + +OUI:0050C24B4* + ID_OUI_FROM_DATABASE=Matrix Audio Designs + +OUI:0050C24B5* + ID_OUI_FROM_DATABASE=Valley Tecnologia + +OUI:0050C24B6* + ID_OUI_FROM_DATABASE=General Resources Co., LTD. + +OUI:0050C24B7* + ID_OUI_FROM_DATABASE=GFI Chrono Time + +OUI:0050C24B8* + ID_OUI_FROM_DATABASE=Shenzhen Hongdian Technologies.,Ltd + +OUI:0050C24B9* + ID_OUI_FROM_DATABASE=Rose Technologies + +OUI:0050C24BA* + ID_OUI_FROM_DATABASE=Mistletoe Technologies + +OUI:0050C24BB* + ID_OUI_FROM_DATABASE=Protonic Holland + +OUI:0050C24BC* + ID_OUI_FROM_DATABASE=Saia Burgess Controls AG + +OUI:0050C24BD* + ID_OUI_FROM_DATABASE=Argon ST + +OUI:0050C24BE* + ID_OUI_FROM_DATABASE=Digital Dynamics, Inc. + +OUI:0050C24BF* + ID_OUI_FROM_DATABASE=Westinghouse Rail Systems Ltd + +OUI:0050C24C0* + ID_OUI_FROM_DATABASE=Bio-logic Systems Corp + +OUI:0050C24C1* + ID_OUI_FROM_DATABASE=Movaz Networks, Inc. + +OUI:0050C24C2* + ID_OUI_FROM_DATABASE=Elbit Systems + +OUI:0050C24C3* + ID_OUI_FROM_DATABASE=Quantum3D, Inc. + +OUI:0050C24C4* + ID_OUI_FROM_DATABASE=Black Diamond Video, Inc. + +OUI:0050C24C5* + ID_OUI_FROM_DATABASE=eXray Broadband Inc. + +OUI:0050C24C6* + ID_OUI_FROM_DATABASE=Rubin Ltd. + +OUI:0050C24C7* + ID_OUI_FROM_DATABASE=Transbit Sp.z o.o. + +OUI:0050C24C8* + ID_OUI_FROM_DATABASE=Neets + +OUI:0050C24C9* + ID_OUI_FROM_DATABASE=Scirocco AB + +OUI:0050C24CA* + ID_OUI_FROM_DATABASE=Yarg Biometrics Limited + +OUI:0050C24CB* + ID_OUI_FROM_DATABASE=Verint Systems Ltd + +OUI:0050C24CC* + ID_OUI_FROM_DATABASE=ImpediMed Limited + +OUI:0050C24CD* + ID_OUI_FROM_DATABASE=Adasoft AG + +OUI:0050C24CE* + ID_OUI_FROM_DATABASE=Open Date Equipment Limited + +OUI:0050C24CF* + ID_OUI_FROM_DATABASE=Ziehl-Abegg AG + +OUI:0050C24D0* + ID_OUI_FROM_DATABASE=Radford Control Systems + +OUI:0050C24D1* + ID_OUI_FROM_DATABASE=SLICAN sp. z o.o. + +OUI:0050C24D2* + ID_OUI_FROM_DATABASE=Twoway CATV SERVICE INC. + +OUI:0050C24D3* + ID_OUI_FROM_DATABASE=SOFTIN sp. z o.o. + +OUI:0050C24D4* + ID_OUI_FROM_DATABASE=Herholdt Controls srl + +OUI:0050C24D5* + ID_OUI_FROM_DATABASE=SEBA Design Pty Ltd + +OUI:0050C24D6* + ID_OUI_FROM_DATABASE=Ingenieurbüro Schober + +OUI:0050C24D7* + ID_OUI_FROM_DATABASE=Delta Tau Data Systems, Inc. + +OUI:0050C24D8* + ID_OUI_FROM_DATABASE=Avantry Ltd. + +OUI:0050C24D9* + ID_OUI_FROM_DATABASE=GE Security Kampro + +OUI:0050C24DA* + ID_OUI_FROM_DATABASE=MEDIORNET GmbH + +OUI:0050C24DB* + ID_OUI_FROM_DATABASE=Alfing Montagetechnik GmbH + +OUI:0050C24DC* + ID_OUI_FROM_DATABASE=Ace Electronics Inc. + +OUI:0050C24DD* + ID_OUI_FROM_DATABASE=Truteq Wireless (PTY) Ltd. + +OUI:0050C24DE* + ID_OUI_FROM_DATABASE=General Dynamics C4 Systems + +OUI:0050C24DF* + ID_OUI_FROM_DATABASE=Thermo Electron + +OUI:0050C24E0* + ID_OUI_FROM_DATABASE=Telematrix + +OUI:0050C24E1* + ID_OUI_FROM_DATABASE=SS Telecoms CC + +OUI:0050C24E2* + ID_OUI_FROM_DATABASE=Applied Research Laboratories: UT + +OUI:0050C24E3* + ID_OUI_FROM_DATABASE=Romteck Pty Ltd + +OUI:0050C24E4* + ID_OUI_FROM_DATABASE=Embigence GmbH + +OUI:0050C24E5* + ID_OUI_FROM_DATABASE=Sedo Systems Ltd + +OUI:0050C24E6* + ID_OUI_FROM_DATABASE=Photonic Bridges Inc. + +OUI:0050C24E7* + ID_OUI_FROM_DATABASE=Computerized Elevator Contol + +OUI:0050C24E8* + ID_OUI_FROM_DATABASE=SATEL sp. z o.o. + +OUI:0050C24E9* + ID_OUI_FROM_DATABASE=Seachange international + +OUI:0050C24EA* + ID_OUI_FROM_DATABASE=PMC + +OUI:0050C24EB* + ID_OUI_FROM_DATABASE=Mandozzi Elettronica SA + +OUI:0050C24EC* + ID_OUI_FROM_DATABASE=Thales Defence and Security Systems GmbH + +OUI:0050C24ED* + ID_OUI_FROM_DATABASE=Lab X Technologies, LLC + +OUI:0050C24EE* + ID_OUI_FROM_DATABASE=Beijing Corelogic Communication Co., Ltd. + +OUI:0050C24EF* + ID_OUI_FROM_DATABASE=Creative Retail Entertainment + +OUI:0050C24F0* + ID_OUI_FROM_DATABASE=MedAvant Healthcare + +OUI:0050C24F1* + ID_OUI_FROM_DATABASE=Packet Island Inc. + +OUI:0050C24F2* + ID_OUI_FROM_DATABASE=Tantronic AG + +OUI:0050C24F3* + ID_OUI_FROM_DATABASE=Autronica Fire & Security + +OUI:0050C24F4* + ID_OUI_FROM_DATABASE=O2RUN + +OUI:0050C24F5* + ID_OUI_FROM_DATABASE=Monroe Electronics, Inc. + +OUI:0050C24F6* + ID_OUI_FROM_DATABASE=REAL D + +OUI:0050C24F7* + ID_OUI_FROM_DATABASE=WaveIP Ltd. + +OUI:0050C24F8* + ID_OUI_FROM_DATABASE=Prodco International Inc. + +OUI:0050C24F9* + ID_OUI_FROM_DATABASE=RTDS Technologies Inc. + +OUI:0050C24FA* + ID_OUI_FROM_DATABASE=Cambridge Technology, Inc. + +OUI:0050C24FB* + ID_OUI_FROM_DATABASE=BES Technology Group + +OUI:0050C24FC* + ID_OUI_FROM_DATABASE=Hwayoung RF Solution Inc + +OUI:0050C24FD* + ID_OUI_FROM_DATABASE=Network Automation mxc AB + +OUI:0050C24FE* + ID_OUI_FROM_DATABASE=GEM ELETTRONICA Srl + +OUI:0050C24FF* + ID_OUI_FROM_DATABASE=Dakty GmbH + +OUI:0050C2500* + ID_OUI_FROM_DATABASE=Orenco Systems, Inc. + +OUI:0050C2501* + ID_OUI_FROM_DATABASE=IBEX + +OUI:0050C2502* + ID_OUI_FROM_DATABASE=Criterion Systems Limited + +OUI:0050C2503* + ID_OUI_FROM_DATABASE=RESPIRONICS INC. + +OUI:0050C2504* + ID_OUI_FROM_DATABASE=Aphex Systems Ltd. + +OUI:0050C2505* + ID_OUI_FROM_DATABASE=Computerwise, Inc. + +OUI:0050C2506* + ID_OUI_FROM_DATABASE=7+ Kft + +OUI:0050C2507* + ID_OUI_FROM_DATABASE=Micro Connect Pty Ltd + +OUI:0050C2508* + ID_OUI_FROM_DATABASE=PUTERCOM ENTERPRISE CO., LTD. + +OUI:0050C2509* + ID_OUI_FROM_DATABASE=Hillcrest Laboratories, Inc. + +OUI:0050C250A* + ID_OUI_FROM_DATABASE=Monitor Business Machines Ltd + +OUI:0050C250B* + ID_OUI_FROM_DATABASE=Logic Beach Inc + +OUI:0050C250C* + ID_OUI_FROM_DATABASE=AIRWISE TECHNOLOGY CO., LTD. + +OUI:0050C250D* + ID_OUI_FROM_DATABASE=Clearsonics Pty. Ltd. + +OUI:0050C250E* + ID_OUI_FROM_DATABASE=Fibresavers Corporation + +OUI:0050C250F* + ID_OUI_FROM_DATABASE=Polystar Instruments AB + +OUI:0050C2510* + ID_OUI_FROM_DATABASE=Summit Developmen + +OUI:0050C2511* + ID_OUI_FROM_DATABASE=Tecna Srl + +OUI:0050C2512* + ID_OUI_FROM_DATABASE=Linear Acoustic, Inc + +OUI:0050C2513* + ID_OUI_FROM_DATABASE=Genie Network Resource Management Inc. + +OUI:0050C2514* + ID_OUI_FROM_DATABASE=Tadian Electronics Systems LTD + +OUI:0050C2515* + ID_OUI_FROM_DATABASE=Monaghan Engineering, Inc. + +OUI:0050C2516* + ID_OUI_FROM_DATABASE=SOWA ELECTRIC CO., LTD. + +OUI:0050C2517* + ID_OUI_FROM_DATABASE=Solid State Logic + +OUI:0050C2518* + ID_OUI_FROM_DATABASE=Christ Elektronik GmbH + +OUI:0050C2519* + ID_OUI_FROM_DATABASE=DBM, LLC + +OUI:0050C251A* + ID_OUI_FROM_DATABASE=SpeasTech, Inc. + +OUI:0050C251B* + ID_OUI_FROM_DATABASE=Beta Lasermike Ltd + +OUI:0050C251C* + ID_OUI_FROM_DATABASE=TOA Systems + +OUI:0050C251D* + ID_OUI_FROM_DATABASE=VELUX + +OUI:0050C251E* + ID_OUI_FROM_DATABASE=Alcon Technologies + +OUI:0050C251F* + ID_OUI_FROM_DATABASE=Traquair Data Systems, Inc. + +OUI:0050C2520* + ID_OUI_FROM_DATABASE=McCain Traffic Supply + +OUI:0050C2521* + ID_OUI_FROM_DATABASE=ARIS TECHNOLOGIES + +OUI:0050C2522* + ID_OUI_FROM_DATABASE=Mark IV IDS Corp. + +OUI:0050C2523* + ID_OUI_FROM_DATABASE=AMRDEC Prototype Integration Facility + +OUI:0050C2524* + ID_OUI_FROM_DATABASE=Motec Pty Ltd + +OUI:0050C2525* + ID_OUI_FROM_DATABASE=VASTech + +OUI:0050C2526* + ID_OUI_FROM_DATABASE=AC SYSTEMS, s.r.o. + +OUI:0050C2527* + ID_OUI_FROM_DATABASE=IRTrans + +OUI:0050C2528* + ID_OUI_FROM_DATABASE=tattile srl + +OUI:0050C2529* + ID_OUI_FROM_DATABASE=Phytec Messtechnik GmbH + +OUI:0050C252A* + ID_OUI_FROM_DATABASE=OMNITRONICS PTY LTD + +OUI:0050C252B* + ID_OUI_FROM_DATABASE=Sicon s.r.l. + +OUI:0050C252C* + ID_OUI_FROM_DATABASE=VITEC MULTIMEDIA + +OUI:0050C252D* + ID_OUI_FROM_DATABASE=Smartcom-Bulgaria AD + +OUI:0050C252E* + ID_OUI_FROM_DATABASE=DSP DESIGN + +OUI:0050C252F* + ID_OUI_FROM_DATABASE=Gesellschaft für Rationalisierung und Rechentechnik mbH + +OUI:0050C2530* + ID_OUI_FROM_DATABASE=Innovation, Institute, Inc + +OUI:0050C2531* + ID_OUI_FROM_DATABASE=Orion Technologies, Inc. + +OUI:0050C2532* + ID_OUI_FROM_DATABASE=NVE Corporation + +OUI:0050C2533* + ID_OUI_FROM_DATABASE=NanShanBridge Co.Ltd + +OUI:0050C2534* + ID_OUI_FROM_DATABASE=Hyundai J. Comm + +OUI:0050C2535* + ID_OUI_FROM_DATABASE=MMS Servis s.r.o. + +OUI:0050C2536* + ID_OUI_FROM_DATABASE=C2 DIAGNOSTICS + +OUI:0050C2537* + ID_OUI_FROM_DATABASE=DST CONTROL AB + +OUI:0050C2538* + ID_OUI_FROM_DATABASE=EtherTek Circuits + +OUI:0050C2539* + ID_OUI_FROM_DATABASE=Detection Technology Inc. + +OUI:0050C253A* + ID_OUI_FROM_DATABASE=Image Control Design Limited + +OUI:0050C253B* + ID_OUI_FROM_DATABASE=Teleks Co. Ltd. + +OUI:0050C253C* + ID_OUI_FROM_DATABASE=Marposs SPA + +OUI:0050C253D* + ID_OUI_FROM_DATABASE=Digital communications Technologies + +OUI:0050C253E* + ID_OUI_FROM_DATABASE=Honeywell GNO + +OUI:0050C253F* + ID_OUI_FROM_DATABASE=Ellips B.V. + +OUI:0050C2540* + ID_OUI_FROM_DATABASE=Mesure Controle Commande + +OUI:0050C2541* + ID_OUI_FROM_DATABASE=WAVES SYSTEM + +OUI:0050C2542* + ID_OUI_FROM_DATABASE=AVerMedia Technologies, Inc. + +OUI:0050C2543* + ID_OUI_FROM_DATABASE=DIGI SESN AG + +OUI:0050C2544* + ID_OUI_FROM_DATABASE=Zetera + +OUI:0050C2545* + ID_OUI_FROM_DATABASE=SecuInfo Co., Ltd. + +OUI:0050C2546* + ID_OUI_FROM_DATABASE=Universidad de Chile Facultad de Medicina + +OUI:0050C2547* + ID_OUI_FROM_DATABASE=BLANKOM Antennentechnik GmbH + +OUI:0050C2548* + ID_OUI_FROM_DATABASE=I.T.W. Betaprint + +OUI:0050C2549* + ID_OUI_FROM_DATABASE=Netsynt S.p.A. + +OUI:0050C254A* + ID_OUI_FROM_DATABASE=IPTC Tech. Comm. AB + +OUI:0050C254B* + ID_OUI_FROM_DATABASE=Innopsys + +OUI:0050C254C* + ID_OUI_FROM_DATABASE=Sintecnos srl + +OUI:0050C254D* + ID_OUI_FROM_DATABASE=Silent System + +OUI:0050C254E* + ID_OUI_FROM_DATABASE=Convergent Design + +OUI:0050C254F* + ID_OUI_FROM_DATABASE=Valtronic SA + +OUI:0050C2550* + ID_OUI_FROM_DATABASE=LJU Automatisierungstechnik GmbH + +OUI:0050C2551* + ID_OUI_FROM_DATABASE=Innovative Neurotroncs + +OUI:0050C2552* + ID_OUI_FROM_DATABASE=Elfiq Inc. + +OUI:0050C2553* + ID_OUI_FROM_DATABASE=ATH system + +OUI:0050C2554* + ID_OUI_FROM_DATABASE=Weinzierl Engineering GmbH + +OUI:0050C2555* + ID_OUI_FROM_DATABASE=Control Alternative Solutions, Inc. + +OUI:0050C2556* + ID_OUI_FROM_DATABASE=Freiburger BlickZentrum + +OUI:0050C2557* + ID_OUI_FROM_DATABASE=TOYO RADIO SYSTEMS CO., LTD. + +OUI:0050C2558* + ID_OUI_FROM_DATABASE=Bedo Elektronik GmbH + +OUI:0050C2559* + ID_OUI_FROM_DATABASE=Fail Safe Solutions LLC + +OUI:0050C255A* + ID_OUI_FROM_DATABASE=Valde Systems, Inc. + +OUI:0050C255B* + ID_OUI_FROM_DATABASE=MATRIX TELECOM PVT. LTD. + +OUI:0050C255C* + ID_OUI_FROM_DATABASE=ads-tec GmbH + +OUI:0050C255D* + ID_OUI_FROM_DATABASE=ACD Elektronik GmbH + +OUI:0050C255E* + ID_OUI_FROM_DATABASE=HANZAS ELEKTRONIKA, SIA + +OUI:0050C255F* + ID_OUI_FROM_DATABASE=Broad Reach Engineering + +OUI:0050C2560* + ID_OUI_FROM_DATABASE=Procon Electronics + +OUI:0050C2561* + ID_OUI_FROM_DATABASE=Seitec Elektronik GmbH + +OUI:0050C2562* + ID_OUI_FROM_DATABASE=C21 Technology Limited + +OUI:0050C2563* + ID_OUI_FROM_DATABASE=ORTRAT, S.L. + +OUI:0050C2564* + ID_OUI_FROM_DATABASE=Last Mile Gear + +OUI:0050C2565* + ID_OUI_FROM_DATABASE=WORKPOWER TECNOLOGIA ELETRONICA LTDA-EPP + +OUI:0050C2566* + ID_OUI_FROM_DATABASE=ubinetsys.co..ltd + +OUI:0050C2567* + ID_OUI_FROM_DATABASE=Tess GmbH + +OUI:0050C2568* + ID_OUI_FROM_DATABASE=GeoFocus, LLC + +OUI:0050C2569* + ID_OUI_FROM_DATABASE=Twinwin Technplogy Co.,Ltd. + +OUI:0050C256A* + ID_OUI_FROM_DATABASE=GRUPO EPELSA S. L. + +OUI:0050C256B* + ID_OUI_FROM_DATABASE=Dataton Utvecklings AB + +OUI:0050C256C* + ID_OUI_FROM_DATABASE=Targeted Technologies, LLC + +OUI:0050C256D* + ID_OUI_FROM_DATABASE=Computrol Fuel Systems Inc. + +OUI:0050C256E* + ID_OUI_FROM_DATABASE=LAB-EL ELEKTRONIKA LABORATORYJNA S.J. + +OUI:0050C256F* + ID_OUI_FROM_DATABASE=GMA, LLC + +OUI:0050C2570* + ID_OUI_FROM_DATABASE=Ellex Medical Pty Ltd + +OUI:0050C2571* + ID_OUI_FROM_DATABASE=Oberon Service srl + +OUI:0050C2572* + ID_OUI_FROM_DATABASE=Chell Instruments Ltd + +OUI:0050C2573* + ID_OUI_FROM_DATABASE=DATAMICRO Co., Ltd. + +OUI:0050C2574* + ID_OUI_FROM_DATABASE=Ingeniería Almudí S.L. + +OUI:0050C2575* + ID_OUI_FROM_DATABASE=SOLYSTIC + +OUI:0050C2576* + ID_OUI_FROM_DATABASE=Visi-tech Systems Ltd + +OUI:0050C2577* + ID_OUI_FROM_DATABASE=Advanced Software Technologies + +OUI:0050C2578* + ID_OUI_FROM_DATABASE=Delphi Display Systems, Inc. + +OUI:0050C2579* + ID_OUI_FROM_DATABASE=Gastager Systemtechnik GmbH + +OUI:0050C257A* + ID_OUI_FROM_DATABASE=Pigeon Point Systems + +OUI:0050C257B* + ID_OUI_FROM_DATABASE=ptswitch + +OUI:0050C257C* + ID_OUI_FROM_DATABASE=CYBERSYS + +OUI:0050C257D* + ID_OUI_FROM_DATABASE=Sierra Video Systems + +OUI:0050C257E* + ID_OUI_FROM_DATABASE=Digital Way + +OUI:0050C257F* + ID_OUI_FROM_DATABASE=Orderite, Inc. + +OUI:0050C2580* + ID_OUI_FROM_DATABASE=Buyang Electronics Industrial co.,Ltd. + +OUI:0050C2581* + ID_OUI_FROM_DATABASE=Devitech ApS + +OUI:0050C2582* + ID_OUI_FROM_DATABASE=AllSun A/S + +OUI:0050C2583* + ID_OUI_FROM_DATABASE=Jünger Audio-Studiotechnik GmbH + +OUI:0050C2584* + ID_OUI_FROM_DATABASE=Toyota Motorsport GmbH + +OUI:0050C2585* + ID_OUI_FROM_DATABASE=Wireless Cables Inc + +OUI:0050C2586* + ID_OUI_FROM_DATABASE=Genetix Ltd + +OUI:0050C2587* + ID_OUI_FROM_DATABASE=Dynalco + +OUI:0050C2588* + ID_OUI_FROM_DATABASE=Federal Electronics + +OUI:0050C2589* + ID_OUI_FROM_DATABASE=HORIBA MEDICAL + +OUI:0050C258A* + ID_OUI_FROM_DATABASE=Dixell S.p.a. + +OUI:0050C258B* + ID_OUI_FROM_DATABASE=Innovative Dynamics GmbH + +OUI:0050C258C* + ID_OUI_FROM_DATABASE=Lattice Semiconductor Corp. (LPA) + +OUI:0050C258D* + ID_OUI_FROM_DATABASE=ZAO + +OUI:0050C258E* + ID_OUI_FROM_DATABASE=Penny & Giles Aerospace Ltd + +OUI:0050C258F* + ID_OUI_FROM_DATABASE=XoIP Systems Pty Ltd + +OUI:0050C2590* + ID_OUI_FROM_DATABASE=EM Motorsport Ltd + +OUI:0050C2591* + ID_OUI_FROM_DATABASE=Grosvenor Technology Ltd + +OUI:0050C2592* + ID_OUI_FROM_DATABASE=PaloDEx Group Oy + +OUI:0050C2593* + ID_OUI_FROM_DATABASE=Broadlight + +OUI:0050C2594* + ID_OUI_FROM_DATABASE=Pixel Velocity, Inc. + +OUI:0050C2595* + ID_OUI_FROM_DATABASE=Callpod, Inc. + +OUI:0050C2596* + ID_OUI_FROM_DATABASE=SPANSION + +OUI:0050C2597* + ID_OUI_FROM_DATABASE=Nautel Limited + +OUI:0050C2598* + ID_OUI_FROM_DATABASE=Bundesamt für Strahlenschutz + +OUI:0050C2599* + ID_OUI_FROM_DATABASE=Fen Technology Limited + +OUI:0050C259A* + ID_OUI_FROM_DATABASE=MultiTrode Pty Ltd + +OUI:0050C259B* + ID_OUI_FROM_DATABASE=SAPEC + +OUI:0050C259C* + ID_OUI_FROM_DATABASE=DELSAT GROUP S.A. + +OUI:0050C259D* + ID_OUI_FROM_DATABASE=DSS Networks, Inc. + +OUI:0050C259E* + ID_OUI_FROM_DATABASE=Legerity + +OUI:0050C259F* + ID_OUI_FROM_DATABASE=ads-tec GmbH + +OUI:0050C25A0* + ID_OUI_FROM_DATABASE=Rudolph Technologies, Inc. + +OUI:0050C25A1* + ID_OUI_FROM_DATABASE=Vestfold Butikkdata AS + +OUI:0050C25A2* + ID_OUI_FROM_DATABASE=iNET Systems Inc. + +OUI:0050C25A3* + ID_OUI_FROM_DATABASE=LUMEL S.A. + +OUI:0050C25A4* + ID_OUI_FROM_DATABASE=Federal State Unitary Enterprise Experimental Factory for Sc + +OUI:0050C25A5* + ID_OUI_FROM_DATABASE=Equipos de Telecomunicación Optoelectronicos, S.A. + +OUI:0050C25A6* + ID_OUI_FROM_DATABASE=Plastic Logic + +OUI:0050C25A7* + ID_OUI_FROM_DATABASE=Phytec Messtechnik GmbH + +OUI:0050C25A8* + ID_OUI_FROM_DATABASE=ETAP NV + +OUI:0050C25A9* + ID_OUI_FROM_DATABASE=AYC Telecom Ltd + +OUI:0050C25AA* + ID_OUI_FROM_DATABASE=Transenna AB + +OUI:0050C25AB* + ID_OUI_FROM_DATABASE=Eaton Corporation Electrical Group Data Center Solutions - Pulizzi + +OUI:0050C25AC* + ID_OUI_FROM_DATABASE=Kinemetrics, Inc. + +OUI:0050C25AD* + ID_OUI_FROM_DATABASE=Emcom Systems + +OUI:0050C25AE* + ID_OUI_FROM_DATABASE=CPS EUROPE B.V. + +OUI:0050C25AF* + ID_OUI_FROM_DATABASE=DORLET S.A. + +OUI:0050C25B0* + ID_OUI_FROM_DATABASE=INCOTEC GmbH + +OUI:0050C25B1* + ID_OUI_FROM_DATABASE=Rosta Ltd + +OUI:0050C25B2* + ID_OUI_FROM_DATABASE=Syntronic AB + +OUI:0050C25B3* + ID_OUI_FROM_DATABASE=HITECOM System + +OUI:0050C25B4* + ID_OUI_FROM_DATABASE=Terrascience Systems Ltd. + +OUI:0050C25B5* + ID_OUI_FROM_DATABASE=RAFAEL + +OUI:0050C25B6* + ID_OUI_FROM_DATABASE=Kontron (Beijing) Technology Co.,Ltd. + +OUI:0050C25B7* + ID_OUI_FROM_DATABASE=AVerMedia Technologies, Inc. + +OUI:0050C25B8* + ID_OUI_FROM_DATABASE=WestfaliaSurge GmbH + +OUI:0050C25B9* + ID_OUI_FROM_DATABASE=Taiwan Video & Monitor + +OUI:0050C25BA* + ID_OUI_FROM_DATABASE=SAIA Burgess Controls AG + +OUI:0050C25BB* + ID_OUI_FROM_DATABASE=UNIC TECHNOLOGIES INC + +OUI:0050C25BC* + ID_OUI_FROM_DATABASE=Guangzhou Hui Si Information Technologies Inc. + +OUI:0050C25BD* + ID_OUI_FROM_DATABASE=Nomus Comm-Systems + +OUI:0050C25BE* + ID_OUI_FROM_DATABASE=Card Access Services Pty Ltd + +OUI:0050C25BF* + ID_OUI_FROM_DATABASE=Techimp Systems S.r.l. + +OUI:0050C25C0* + ID_OUI_FROM_DATABASE=Pyott-Boone Electronics + +OUI:0050C25C1* + ID_OUI_FROM_DATABASE=R. L. Drake Company + +OUI:0050C25C2* + ID_OUI_FROM_DATABASE=Intuitive Surgical + +OUI:0050C25C3* + ID_OUI_FROM_DATABASE=KS System GmbH + +OUI:0050C25C4* + ID_OUI_FROM_DATABASE=ProMik GmbH + +OUI:0050C25C5* + ID_OUI_FROM_DATABASE=Radiant Imaging, Inc. + +OUI:0050C25C6* + ID_OUI_FROM_DATABASE=Technische Alternative GmbH + +OUI:0050C25C7* + ID_OUI_FROM_DATABASE=InSync Technology Ltd + +OUI:0050C25C8* + ID_OUI_FROM_DATABASE=Georgia Tech Research Institute + +OUI:0050C25C9* + ID_OUI_FROM_DATABASE=Shenzhen Quanlong Technique Co.Ltd + +OUI:0050C25CA* + ID_OUI_FROM_DATABASE=Buyang Electronics Industrial Co., Ltd. + +OUI:0050C25CB* + ID_OUI_FROM_DATABASE=Kobold Sistemi s.r.l. + +OUI:0050C25CC* + ID_OUI_FROM_DATABASE=ENSEO + +OUI:0050C25CD* + ID_OUI_FROM_DATABASE=RADA Electronics Industries Ltd. + +OUI:0050C25CE* + ID_OUI_FROM_DATABASE=Roke Manor Research Ltd + +OUI:0050C25CF* + ID_OUI_FROM_DATABASE=Innomed Medical Inc + +OUI:0050C25D0* + ID_OUI_FROM_DATABASE=Automata Spa + +OUI:0050C25D1* + ID_OUI_FROM_DATABASE=Meucci Solutions + +OUI:0050C25D2* + ID_OUI_FROM_DATABASE=DA-Design Oy + +OUI:0050C25D3* + ID_OUI_FROM_DATABASE=Wexiodisk AB + +OUI:0050C25D4* + ID_OUI_FROM_DATABASE=Buyang Electronics Industrial Co., Ltd. + +OUI:0050C25D5* + ID_OUI_FROM_DATABASE=Cannon Technologies + +OUI:0050C25D6* + ID_OUI_FROM_DATABASE=BioAccess Tecnologia em Biometria Ltda. + +OUI:0050C25D7* + ID_OUI_FROM_DATABASE=Synrad, Inc. + +OUI:0050C25D8* + ID_OUI_FROM_DATABASE=TECHNIFOR SAS + +OUI:0050C25D9* + ID_OUI_FROM_DATABASE=Crimson Microsystems, Inc. + +OUI:0050C25DA* + ID_OUI_FROM_DATABASE=TONNA ELECTRONIQUE + +OUI:0050C25DB* + ID_OUI_FROM_DATABASE=CEGELEC SUD EST + +OUI:0050C25DC* + ID_OUI_FROM_DATABASE=RM Michaelides Software & Elektronik GmbH + +OUI:0050C25DD* + ID_OUI_FROM_DATABASE=SomerData ltd + +OUI:0050C25DE* + ID_OUI_FROM_DATABASE=Magal Senstar Inc. + +OUI:0050C25DF* + ID_OUI_FROM_DATABASE=Gnutek Ltd. + +OUI:0050C25E0* + ID_OUI_FROM_DATABASE=Phytec Messtechnik GmbH + +OUI:0050C25E1* + ID_OUI_FROM_DATABASE=Ittiam Systems (P) Ltd + +OUI:0050C25E2* + ID_OUI_FROM_DATABASE=PYRAMID Computer GmbH + +OUI:0050C25E3* + ID_OUI_FROM_DATABASE=Computechnic AG + +OUI:0050C25E4* + ID_OUI_FROM_DATABASE=Buyang Electronics Industrial Co., Ltd. + +OUI:0050C25E5* + ID_OUI_FROM_DATABASE=Stresstech OY + +OUI:0050C25E6* + ID_OUI_FROM_DATABASE=Musatel + +OUI:0050C25E7* + ID_OUI_FROM_DATABASE=EADS TEST & SERVICES + +OUI:0050C25E8* + ID_OUI_FROM_DATABASE=Info-Chip Communications Ltd. + +OUI:0050C25E9* + ID_OUI_FROM_DATABASE=Micro Technology Services Inc. + +OUI:0050C25EA* + ID_OUI_FROM_DATABASE=Micro Elektronische Producten + +OUI:0050C25EB* + ID_OUI_FROM_DATABASE=Garper Telecomunicaciones, S.L. + +OUI:0050C25EC* + ID_OUI_FROM_DATABASE=ASiS Technologies Pte Ltd + +OUI:0050C25ED* + ID_OUI_FROM_DATABASE=AQUAROTTER A FRANKE COMPANY + +OUI:0050C25EE* + ID_OUI_FROM_DATABASE=Condre Corporation + +OUI:0050C25EF* + ID_OUI_FROM_DATABASE=pikkerton GmbH + +OUI:0050C25F0* + ID_OUI_FROM_DATABASE=DIAS Infrared GmbH + +OUI:0050C25F1* + ID_OUI_FROM_DATABASE=Technomarine JSC + +OUI:0050C25F2* + ID_OUI_FROM_DATABASE=ESEM Grünau GmbH & Co. KG + +OUI:0050C25F3* + ID_OUI_FROM_DATABASE=POSNET Polska S.A. + +OUI:0050C25F4* + ID_OUI_FROM_DATABASE=TeamProjects BV + +OUI:0050C25F5* + ID_OUI_FROM_DATABASE=Genesis inc + +OUI:0050C25F6* + ID_OUI_FROM_DATABASE=CAMBRIDGE CONSULTANTS LTD + +OUI:0050C25F7* + ID_OUI_FROM_DATABASE=Metrologic Group + +OUI:0050C25F8* + ID_OUI_FROM_DATABASE=Grupo Epelsa s. l. + +OUI:0050C25F9* + ID_OUI_FROM_DATABASE=ROTHARY Solutions AG + +OUI:0050C25FA* + ID_OUI_FROM_DATABASE=LEA d.o.o. + +OUI:0050C25FB* + ID_OUI_FROM_DATABASE=All-Systems Electronics Pty Ltd + +OUI:0050C25FC* + ID_OUI_FROM_DATABASE=FilmLight Limited + +OUI:0050C25FD* + ID_OUI_FROM_DATABASE=MEG Electronic Inc. + +OUI:0050C25FE* + ID_OUI_FROM_DATABASE=Novacomm + +OUI:0050C25FF* + ID_OUI_FROM_DATABASE=Gazelle Monitoring Systems + +OUI:0050C2600* + ID_OUI_FROM_DATABASE=Protec Fire Detection plc + +OUI:0050C2601* + ID_OUI_FROM_DATABASE=MedAvant Healthcare + +OUI:0050C2602* + ID_OUI_FROM_DATABASE=CHAUVIN ARNOUX + +OUI:0050C2603* + ID_OUI_FROM_DATABASE=Cerus Corp + +OUI:0050C2604* + ID_OUI_FROM_DATABASE=HCJB Global + +OUI:0050C2605* + ID_OUI_FROM_DATABASE=Swistec GmbH + +OUI:0050C2606* + ID_OUI_FROM_DATABASE=Shenzhen Huazhong Technology Inc + +OUI:0050C2607* + ID_OUI_FROM_DATABASE=Telecom FM + +OUI:0050C2608* + ID_OUI_FROM_DATABASE=Silex Industrial Automation Ltd. + +OUI:0050C2609* + ID_OUI_FROM_DATABASE=Toptech Systems, Inc. + +OUI:0050C260A* + ID_OUI_FROM_DATABASE=Gradual Tecnologia Ltda + +OUI:0050C260B* + ID_OUI_FROM_DATABASE=Shanghai QianJin Electronic Equipment Co. Ltd. + +OUI:0050C260C* + ID_OUI_FROM_DATABASE=IDENTIC AB + +OUI:0050C260D* + ID_OUI_FROM_DATABASE=Sicon s.r.l. + +OUI:0050C260E* + ID_OUI_FROM_DATABASE=Automation and Control Technology, Inc. + +OUI:0050C260F* + ID_OUI_FROM_DATABASE=Kommunikations- & Sicherheitssysteme Gesellschaft m.b.H + +OUI:0050C2610* + ID_OUI_FROM_DATABASE=FDT Manufacturing, LLC + +OUI:0050C2611* + ID_OUI_FROM_DATABASE=Brookhaven National Laboratory + +OUI:0050C2612* + ID_OUI_FROM_DATABASE=IHP-GmbH + +OUI:0050C2613* + ID_OUI_FROM_DATABASE=TATTILE SRL + +OUI:0050C2614* + ID_OUI_FROM_DATABASE=SICOM AS + +OUI:0050C2615* + ID_OUI_FROM_DATABASE=Axis Electronics + +OUI:0050C2616* + ID_OUI_FROM_DATABASE=Honeywell + +OUI:0050C2617* + ID_OUI_FROM_DATABASE=NARINET, INC. + +OUI:0050C2618* + ID_OUI_FROM_DATABASE=Intergrated Security Mfg. Ltd + +OUI:0050C2619* + ID_OUI_FROM_DATABASE=Linkbit, Inc. + +OUI:0050C261A* + ID_OUI_FROM_DATABASE=Communication Components Inc. + +OUI:0050C261B* + ID_OUI_FROM_DATABASE=NCI Technologies Inc. + +OUI:0050C261C* + ID_OUI_FROM_DATABASE=TestPro Systems, Inc. + +OUI:0050C261D* + ID_OUI_FROM_DATABASE=Sutus Inc + +OUI:0050C261E* + ID_OUI_FROM_DATABASE=LESTER ELECTRONICS LTD + +OUI:0050C261F* + ID_OUI_FROM_DATABASE=Imagine Communications + +OUI:0050C2620* + ID_OUI_FROM_DATABASE=Harman/Becker Automotive Systems GmbH + +OUI:0050C2621* + ID_OUI_FROM_DATABASE=Version-T + +OUI:0050C2622* + ID_OUI_FROM_DATABASE=2N TELEKOMUNIKACE a.s. + +OUI:0050C2623* + ID_OUI_FROM_DATABASE=SAFELINE SL + +OUI:0050C2624* + ID_OUI_FROM_DATABASE=Comtest Networks + +OUI:0050C2625* + ID_OUI_FROM_DATABASE=EBNeuro SpA + +OUI:0050C2626* + ID_OUI_FROM_DATABASE=Winsys Informatica ltda + +OUI:0050C2627* + ID_OUI_FROM_DATABASE=JungleSystem Co., Ltd. + +OUI:0050C2628* + ID_OUI_FROM_DATABASE=DARE Development + +OUI:0050C2629* + ID_OUI_FROM_DATABASE=MacDonald Humfrey (Products) Ltd + +OUI:0050C262A* + ID_OUI_FROM_DATABASE=Prisma Engineering srl + +OUI:0050C262B* + ID_OUI_FROM_DATABASE=First Control Systems AB + +OUI:0050C262C* + ID_OUI_FROM_DATABASE=AirMatrix, Inc. + +OUI:0050C262D* + ID_OUI_FROM_DATABASE=Procon Electronics + +OUI:0050C262E* + ID_OUI_FROM_DATABASE=TDM Ingénierie + +OUI:0050C262F* + ID_OUI_FROM_DATABASE=QES + +OUI:0050C2630* + ID_OUI_FROM_DATABASE=Aurora Flight Sciences + +OUI:0050C2631* + ID_OUI_FROM_DATABASE=Fraunhofer IIS + +OUI:0050C2632* + ID_OUI_FROM_DATABASE=RoseTechnology A/S + +OUI:0050C2633* + ID_OUI_FROM_DATABASE=Rice University + +OUI:0050C2634* + ID_OUI_FROM_DATABASE=Sohon Inc + +OUI:0050C2635* + ID_OUI_FROM_DATABASE=Shockfish SA + +OUI:0050C2636* + ID_OUI_FROM_DATABASE=dSPACE GmbH + +OUI:0050C2637* + ID_OUI_FROM_DATABASE=Omnitrol Networks, Inc. + +OUI:0050C2638* + ID_OUI_FROM_DATABASE=HUNGAROCOM Telecommunication Ltd. + +OUI:0050C2639* + ID_OUI_FROM_DATABASE=Qstreams Networks Inc. + +OUI:0050C263A* + ID_OUI_FROM_DATABASE=3DSP Corporation + +OUI:0050C263B* + ID_OUI_FROM_DATABASE=Powis Corporation + +OUI:0050C263C* + ID_OUI_FROM_DATABASE=dPict Imaging, Inc. + +OUI:0050C263D* + ID_OUI_FROM_DATABASE=IDERs Inc + +OUI:0050C263E* + ID_OUI_FROM_DATABASE=T2 Communication Ltd + +OUI:0050C263F* + ID_OUI_FROM_DATABASE=Speech Technology Center, Ltd. + +OUI:0050C2640* + ID_OUI_FROM_DATABASE=IAC + +OUI:0050C2641* + ID_OUI_FROM_DATABASE=NEO Information Systems Co., Ltd. + +OUI:0050C2642* + ID_OUI_FROM_DATABASE=Stanton Technologies Sdn Bhd + +OUI:0050C2643* + ID_OUI_FROM_DATABASE=Enatel Limited + +OUI:0050C2644* + ID_OUI_FROM_DATABASE=Phytec Messtechnik GmbH + +OUI:0050C2645* + ID_OUI_FROM_DATABASE=The Software Group Limited + +OUI:0050C2646* + ID_OUI_FROM_DATABASE=TRUTOUCH TECHNOLOGIES INC + +OUI:0050C2647* + ID_OUI_FROM_DATABASE=R&D Technology Solutionz Limited + +OUI:0050C2648* + ID_OUI_FROM_DATABASE=Fidelity Comtech, Inc. + +OUI:0050C2649* + ID_OUI_FROM_DATABASE=Pan-STARRS + +OUI:0050C264A* + ID_OUI_FROM_DATABASE=CPqD + +OUI:0050C264B* + ID_OUI_FROM_DATABASE=MangoDSP + +OUI:0050C264C* + ID_OUI_FROM_DATABASE=CIS Corporation + +OUI:0050C264D* + ID_OUI_FROM_DATABASE=Tera Information System Labs + +OUI:0050C264E* + ID_OUI_FROM_DATABASE=Northern Power + +OUI:0050C264F* + ID_OUI_FROM_DATABASE=MA Lighting Technology GmbH + +OUI:0050C2650* + ID_OUI_FROM_DATABASE=Liquid Breaker, LLC + +OUI:0050C2651* + ID_OUI_FROM_DATABASE=STAER SPA + +OUI:0050C2652* + ID_OUI_FROM_DATABASE=Wideco Sweden AB + +OUI:0050C2653* + ID_OUI_FROM_DATABASE=Doble Engineering + +OUI:0050C2654* + ID_OUI_FROM_DATABASE=PaloDEx Group Oy + +OUI:0050C2655* + ID_OUI_FROM_DATABASE=Physik Instrumente (PI) GmbH&Co.KG + +OUI:0050C2656* + ID_OUI_FROM_DATABASE=LDA Audio Video Profesional + +OUI:0050C2657* + ID_OUI_FROM_DATABASE=MONYTEL S.A. + +OUI:0050C2658* + ID_OUI_FROM_DATABASE=OpenPKG GmbH + +OUI:0050C2659* + ID_OUI_FROM_DATABASE=Dorsett's, Incorporated + +OUI:0050C265A* + ID_OUI_FROM_DATABASE=Hisstema AB + +OUI:0050C265B* + ID_OUI_FROM_DATABASE=Silverbrook Research + +OUI:0050C265C* + ID_OUI_FROM_DATABASE=VTZ d.o.o. + +OUI:0050C265D* + ID_OUI_FROM_DATABASE=Redfone Communications LLC + +OUI:0050C265E* + ID_OUI_FROM_DATABASE=Cantion A/S + +OUI:0050C265F* + ID_OUI_FROM_DATABASE=Invocon, Inc. + +OUI:0050C2660* + ID_OUI_FROM_DATABASE=IZISOFT + +OUI:0050C2661* + ID_OUI_FROM_DATABASE=P.C.E. + +OUI:0050C2662* + ID_OUI_FROM_DATABASE=Asia Pacific Card & System Sdn Bhd + +OUI:0050C2663* + ID_OUI_FROM_DATABASE=COE Limited + +OUI:0050C2664* + ID_OUI_FROM_DATABASE=Westel Wireless Systems + +OUI:0050C2665* + ID_OUI_FROM_DATABASE=NetworkSound, Inc + +OUI:0050C2666* + ID_OUI_FROM_DATABASE=Xworks NZ Limited + +OUI:0050C2668* + ID_OUI_FROM_DATABASE=Keith & Koep GmbH + +OUI:0050C2669* + ID_OUI_FROM_DATABASE=DSP DESIGN + +OUI:0050C266A* + ID_OUI_FROM_DATABASE=ABB Xiamen Transmission and Distribution Automation Equipmen + +OUI:0050C266B* + ID_OUI_FROM_DATABASE=flsystem + +OUI:0050C266C* + ID_OUI_FROM_DATABASE=DESY + +OUI:0050C266D* + ID_OUI_FROM_DATABASE=DIGITEK S.p.A. + +OUI:0050C266E* + ID_OUI_FROM_DATABASE=Linear Systems Ltd. + +OUI:0050C266F* + ID_OUI_FROM_DATABASE=Nilan A/S + +OUI:0050C2670* + ID_OUI_FROM_DATABASE=Naim Audio + +OUI:0050C2671* + ID_OUI_FROM_DATABASE=Skyline Products, Inc + +OUI:0050C2672* + ID_OUI_FROM_DATABASE=DDS Elettronica srl + +OUI:0050C2673* + ID_OUI_FROM_DATABASE=Ferrari electronic AG + +OUI:0050C2674* + ID_OUI_FROM_DATABASE=Protech Optronics Co., Ltd. + +OUI:0050C2675* + ID_OUI_FROM_DATABASE=Kenton Research Ltd + +OUI:0050C2676* + ID_OUI_FROM_DATABASE=EDS + +OUI:0050C2677* + ID_OUI_FROM_DATABASE=ProconX Pty Ltd + +OUI:0050C2678* + ID_OUI_FROM_DATABASE=IHM + +OUI:0050C2679* + ID_OUI_FROM_DATABASE=Industrial Vacuum Systems + +OUI:0050C267A* + ID_OUI_FROM_DATABASE=CC Systems AB + +OUI:0050C267B* + ID_OUI_FROM_DATABASE=Sparton Electronics + +OUI:0050C267C* + ID_OUI_FROM_DATABASE=AirCell, Inc. + +OUI:0050C267D* + ID_OUI_FROM_DATABASE=ESA Messtechnik GmbH + +OUI:0050C267E* + ID_OUI_FROM_DATABASE=SAIA Burgess Controls AG + +OUI:0050C267F* + ID_OUI_FROM_DATABASE=Phytec Messtechnik GmbH + +OUI:0050C2680* + ID_OUI_FROM_DATABASE=Honey Network Research Limited + +OUI:0050C2681* + ID_OUI_FROM_DATABASE=Owasys Advanced Wireless Devices + +OUI:0050C2682* + ID_OUI_FROM_DATABASE=Commet AB + +OUI:0050C2683* + ID_OUI_FROM_DATABASE=MEGGITT Safety System + +OUI:0050C2684* + ID_OUI_FROM_DATABASE=REASON Tecnologia S.A. + +OUI:0050C2685* + ID_OUI_FROM_DATABASE=Datamars SA + +OUI:0050C2686* + ID_OUI_FROM_DATABASE=ANNAX Anzeigesysteme GmbH + +OUI:0050C2687* + ID_OUI_FROM_DATABASE=Access Specialties, Inc + +OUI:0050C2688* + ID_OUI_FROM_DATABASE=Elk Products + +OUI:0050C2689* + ID_OUI_FROM_DATABASE=RF Code, Inc. + +OUI:0050C268A* + ID_OUI_FROM_DATABASE=Zhuhai Jiahe Electronics Co.,LTD + +OUI:0050C268B* + ID_OUI_FROM_DATABASE=SIMTEK INC. + +OUI:0050C268C* + ID_OUI_FROM_DATABASE=Isochron Inc + +OUI:0050C268D* + ID_OUI_FROM_DATABASE=CXR Larus Corporation + +OUI:0050C268E* + ID_OUI_FROM_DATABASE=SELCO + +OUI:0050C268F* + ID_OUI_FROM_DATABASE=BERTRONIC SRL + +OUI:0050C2690* + ID_OUI_FROM_DATABASE=GHL Systems Berhad + +OUI:0050C2691* + ID_OUI_FROM_DATABASE=Interopix, Inc. + +OUI:0050C2692* + ID_OUI_FROM_DATABASE=Mate Media Access Technologies + +OUI:0050C2693* + ID_OUI_FROM_DATABASE=Tech Comm, Inc. + +OUI:0050C2694* + ID_OUI_FROM_DATABASE=Initel srl + +OUI:0050C2695* + ID_OUI_FROM_DATABASE=Purelink Technology, inc. + +OUI:0050C2696* + ID_OUI_FROM_DATABASE=Casabyte Inc. + +OUI:0050C2697* + ID_OUI_FROM_DATABASE=Monarch Instrument + +OUI:0050C2698* + ID_OUI_FROM_DATABASE=Navtech Radar Ltd + +OUI:0050C2699* + ID_OUI_FROM_DATABASE=Bulletendpoints Enterprises Inc + +OUI:0050C269A* + ID_OUI_FROM_DATABASE=StoreTech Limited + +OUI:0050C269B* + ID_OUI_FROM_DATABASE=Tsien (UK) Ltd + +OUI:0050C269C* + ID_OUI_FROM_DATABASE=Bug Labs, Inc. + +OUI:0050C269D* + ID_OUI_FROM_DATABASE=Dvation.co.,Ltd + +OUI:0050C269E* + ID_OUI_FROM_DATABASE=Ideus AB + +OUI:0050C269F* + ID_OUI_FROM_DATABASE=Total RF, LLC + +OUI:0050C26A0* + ID_OUI_FROM_DATABASE=GFP Lab S.r.l. + +OUI:0050C26A1* + ID_OUI_FROM_DATABASE=PRICOL LIMITED + +OUI:0050C26A2* + ID_OUI_FROM_DATABASE=Cadi Scientific Pte Ltd + +OUI:0050C26A3* + ID_OUI_FROM_DATABASE=CreaTech Electronics Co. + +OUI:0050C26A4* + ID_OUI_FROM_DATABASE=TELETASK + +OUI:0050C26A5* + ID_OUI_FROM_DATABASE=FHF Funke+Huster Fernsig GmbH + +OUI:0050C26A6* + ID_OUI_FROM_DATABASE=Victory Concept Industries Ltd. + +OUI:0050C26A7* + ID_OUI_FROM_DATABASE=Hoer GmbH & Co. Industrie-Electronic KG + +OUI:0050C26A8* + ID_OUI_FROM_DATABASE=Intelligent Devices, Inc. + +OUI:0050C26A9* + ID_OUI_FROM_DATABASE=Armida Technologies Corporation + +OUI:0050C26AA* + ID_OUI_FROM_DATABASE=Ifox - Industria e Comercio Ltda + +OUI:0050C26AB* + ID_OUI_FROM_DATABASE=Softwareentwicklung + +OUI:0050C26AC* + ID_OUI_FROM_DATABASE=Thales UK + +OUI:0050C26AD* + ID_OUI_FROM_DATABASE=Heim- & Bürokommunikation + +OUI:0050C26AE* + ID_OUI_FROM_DATABASE=Qualisys AB + +OUI:0050C26AF* + ID_OUI_FROM_DATABASE=Nanoradio AB + +OUI:0050C26B0* + ID_OUI_FROM_DATABASE=Smart Key International Limited + +OUI:0050C26B1* + ID_OUI_FROM_DATABASE=Burk Technology + +OUI:0050C26B2* + ID_OUI_FROM_DATABASE=Edgeware AB + +OUI:0050C26B3* + ID_OUI_FROM_DATABASE=4RF Communications Ltd + +OUI:0050C26B4* + ID_OUI_FROM_DATABASE=SOMESCA + +OUI:0050C26B5* + ID_OUI_FROM_DATABASE=TRIUMF + +OUI:0050C26B6* + ID_OUI_FROM_DATABASE=CommoDaS GmbH + +OUI:0050C26B7* + ID_OUI_FROM_DATABASE=System LSI CO.Ltd. + +OUI:0050C26B8* + ID_OUI_FROM_DATABASE=Epec Oy + +OUI:0050C26B9* + ID_OUI_FROM_DATABASE=unipo GmbH + +OUI:0050C26BA* + ID_OUI_FROM_DATABASE=Fertron Controle e Automacao Industrial Ltda. + +OUI:0050C26BB* + ID_OUI_FROM_DATABASE=Ele.Mag S.r.l. + +OUI:0050C26BC* + ID_OUI_FROM_DATABASE=Paraytec Ltd + +OUI:0050C26BD* + ID_OUI_FROM_DATABASE=Mitron Oy + +OUI:0050C26BE* + ID_OUI_FROM_DATABASE=ESTEC Co.,Ltd. + +OUI:0050C26BF* + ID_OUI_FROM_DATABASE=Optoplan as + +OUI:0050C26C0* + ID_OUI_FROM_DATABASE=GLOSTER SANTE EUROPE + +OUI:0050C26C1* + ID_OUI_FROM_DATABASE=RADIUS Sweden AB + +OUI:0050C26C2* + ID_OUI_FROM_DATABASE=HoseoTelnet Inc... + +OUI:0050C26C3* + ID_OUI_FROM_DATABASE=iTRACS Corporation + +OUI:0050C26C4* + ID_OUI_FROM_DATABASE=REXXON GmbH + +OUI:0050C26C5* + ID_OUI_FROM_DATABASE=Oerlikon Contraves AG + +OUI:0050C26C6* + ID_OUI_FROM_DATABASE=MedAvant Healthcare Solutions + +OUI:0050C26C7* + ID_OUI_FROM_DATABASE=QuickCircuit Ltd. + +OUI:0050C26C8* + ID_OUI_FROM_DATABASE=B&S MEDIA Co., LTD. + +OUI:0050C26C9* + ID_OUI_FROM_DATABASE=NETAMI + +OUI:0050C26CA* + ID_OUI_FROM_DATABASE=Dynamic Hearing Pty Ltd + +OUI:0050C26CB* + ID_OUI_FROM_DATABASE=Stream Processors + +OUI:0050C26CC* + ID_OUI_FROM_DATABASE=Widmer Time Recorder Co., Inc. + +OUI:0050C26CD* + ID_OUI_FROM_DATABASE=RGM SPA + +OUI:0050C26CE* + ID_OUI_FROM_DATABASE=EMITALL Surveillance S.A, + +OUI:0050C26CF* + ID_OUI_FROM_DATABASE=Microway + +OUI:0050C26D0* + ID_OUI_FROM_DATABASE=EDS Systemtechnik + +OUI:0050C26D1* + ID_OUI_FROM_DATABASE=Schnick-Schnack-Systems GmbH + +OUI:0050C26D2* + ID_OUI_FROM_DATABASE=Lumistar Incorporated + +OUI:0050C26D3* + ID_OUI_FROM_DATABASE=DigiSensory technologies Pty Ltd + +OUI:0050C26D4* + ID_OUI_FROM_DATABASE=Etani Electronics Co.,Ltd. + +OUI:0050C26D5* + ID_OUI_FROM_DATABASE=Becker Electronics GmbH + +OUI:0050C26D6* + ID_OUI_FROM_DATABASE=ADL Electronics Ltd. + +OUI:0050C26D7* + ID_OUI_FROM_DATABASE=Mavenir System, Inc. + +OUI:0050C26D8* + ID_OUI_FROM_DATABASE=BL Healthcare, Inc. + +OUI:0050C26D9* + ID_OUI_FROM_DATABASE=Ajeco Oy + +OUI:0050C26DA* + ID_OUI_FROM_DATABASE=Techno Fittings S.r.l. + +OUI:0050C26DB* + ID_OUI_FROM_DATABASE=Gebhardt Ventilatoren GmbH + +OUI:0050C26DC* + ID_OUI_FROM_DATABASE=L-3 Communications Mobile-Vision, Inc. + +OUI:0050C26DD* + ID_OUI_FROM_DATABASE=Zmicro Systems Inc + +OUI:0050C26DE* + ID_OUI_FROM_DATABASE=Laser Tools & Technics Corp. + +OUI:0050C26DF* + ID_OUI_FROM_DATABASE=QR Sciences Ltd + +OUI:0050C26E0* + ID_OUI_FROM_DATABASE=FIRSTTRUST Co.,Ltd. + +OUI:0050C26E1* + ID_OUI_FROM_DATABASE=NewOnSys Ltd. + +OUI:0050C26E2* + ID_OUI_FROM_DATABASE=PHYTEC Messtechnik GmbH + +OUI:0050C26E3* + ID_OUI_FROM_DATABASE=Miros AS + +OUI:0050C26E4* + ID_OUI_FROM_DATABASE=MangoDSP + +OUI:0050C26E5* + ID_OUI_FROM_DATABASE=Boeckeler Instruments, Inc. + +OUI:0050C26E6* + ID_OUI_FROM_DATABASE=Lanetco + +OUI:0050C26E7* + ID_OUI_FROM_DATABASE=Axis Network Technology + +OUI:0050C26E8* + ID_OUI_FROM_DATABASE=Anymax + +OUI:0050C26E9* + ID_OUI_FROM_DATABASE=Bando electronic communication Co.Lltd + +OUI:0050C26EA* + ID_OUI_FROM_DATABASE=FIRSTEC SA + +OUI:0050C26EB* + ID_OUI_FROM_DATABASE=Harrison Audio, LLC + +OUI:0050C26EC* + ID_OUI_FROM_DATABASE=Netistix Technologies Corporation + +OUI:0050C26ED* + ID_OUI_FROM_DATABASE=Sechan Electronics, Inc. + +OUI:0050C26EE* + ID_OUI_FROM_DATABASE=Interactive Electronic Systems + +OUI:0050C26EF* + ID_OUI_FROM_DATABASE=Pneumopartners LaenneXT SA + +OUI:0050C26F0* + ID_OUI_FROM_DATABASE=Stanley Security Solutions, Inc. + +OUI:0050C26F1* + ID_OUI_FROM_DATABASE=ITS Telecom + +OUI:0050C26F2* + ID_OUI_FROM_DATABASE=Laser Electronics Ltd + +OUI:0050C26F3* + ID_OUI_FROM_DATABASE=E3Switch LLC + +OUI:0050C26F4* + ID_OUI_FROM_DATABASE=Cryogenic Control Systems, Inc. + +OUI:0050C26F5* + ID_OUI_FROM_DATABASE=Kitron Microelectronics AB + +OUI:0050C26F6* + ID_OUI_FROM_DATABASE=AV SatCom AS + +OUI:0050C26F7* + ID_OUI_FROM_DATABASE=infoplan Gesellschaftfür Informationssysteme mbH + +OUI:0050C26F8* + ID_OUI_FROM_DATABASE=RV Technology Limited + +OUI:0050C26F9* + ID_OUI_FROM_DATABASE=Revox GmbH + +OUI:0050C26FA* + ID_OUI_FROM_DATABASE=DCN + +OUI:0050C26FB* + ID_OUI_FROM_DATABASE=WaveIP + +OUI:0050C26FC* + ID_OUI_FROM_DATABASE=Acte Sp. z o.o. + +OUI:0050C26FD* + ID_OUI_FROM_DATABASE=SAIA Burgess Controls AG + +OUI:0050C26FE* + ID_OUI_FROM_DATABASE=Blue Origin + +OUI:0050C26FF* + ID_OUI_FROM_DATABASE=St. Michael Strategies Inc. + +OUI:0050C2700* + ID_OUI_FROM_DATABASE=GEM-MED SL + +OUI:0050C2701* + ID_OUI_FROM_DATABASE=Keith & Koep GmbH + +OUI:0050C2702* + ID_OUI_FROM_DATABASE=SPM Instrument AB + +OUI:0050C2703* + ID_OUI_FROM_DATABASE=SAE IT-systems GmbH & Co. KG + +OUI:0050C2704* + ID_OUI_FROM_DATABASE=The Dini Group, La Jolla inc. + +OUI:0050C2705* + ID_OUI_FROM_DATABASE=Hauch & Bach ApS + +OUI:0050C2706* + ID_OUI_FROM_DATABASE=DioDigiWorks. CO., LTD. + +OUI:0050C2707* + ID_OUI_FROM_DATABASE=DTech Labs Inc + +OUI:0050C2708* + ID_OUI_FROM_DATABASE=Smartek d.o.o. + +OUI:0050C2709* + ID_OUI_FROM_DATABASE=RO.VE.R. Laboratories S.p.A + +OUI:0050C270A* + ID_OUI_FROM_DATABASE=Efficient Channel Coding + +OUI:0050C270B* + ID_OUI_FROM_DATABASE=B.E.A.R. Solutions (Australasia) Pty Ltd + +OUI:0050C270C* + ID_OUI_FROM_DATABASE=Exertus + +OUI:0050C270D* + ID_OUI_FROM_DATABASE=ela-soft GmbH & Co. KG + +OUI:0050C270E* + ID_OUI_FROM_DATABASE=AUDICO SYSTEMS OY + +OUI:0050C270F* + ID_OUI_FROM_DATABASE=Zumbach Electronic AG + +OUI:0050C2710* + ID_OUI_FROM_DATABASE=Wharton Electronics Ltd + +OUI:0050C2711* + ID_OUI_FROM_DATABASE=LINKIT S.R.L. + +OUI:0050C2712* + ID_OUI_FROM_DATABASE=Pasan SA + +OUI:0050C2713* + ID_OUI_FROM_DATABASE=3DX-Ray Limited + +OUI:0050C2714* + ID_OUI_FROM_DATABASE=T.E.AM., S. A. + +OUI:0050C2715* + ID_OUI_FROM_DATABASE=RIEXINGER Elektronik + +OUI:0050C2716* + ID_OUI_FROM_DATABASE=MITROL S.R.L. + +OUI:0050C2717* + ID_OUI_FROM_DATABASE=MB Connect Line GmbH + +OUI:0050C2718* + ID_OUI_FROM_DATABASE=illunis LLC + +OUI:0050C2719* + ID_OUI_FROM_DATABASE=ennovatis GmbH + +OUI:0050C271A* + ID_OUI_FROM_DATABASE=Logus Broadband Wireless Solutions Inc. + +OUI:0050C271B* + ID_OUI_FROM_DATABASE=ADVA Optical Networking + +OUI:0050C271C* + ID_OUI_FROM_DATABASE=Elmec Inc. + +OUI:0050C271D* + ID_OUI_FROM_DATABASE=MG s.r.l. + +OUI:0050C271E* + ID_OUI_FROM_DATABASE=ASKI Industrie Elektronik Ges.m.b.H. + +OUI:0050C271F* + ID_OUI_FROM_DATABASE=ASC telecom AG + +OUI:0050C2720* + ID_OUI_FROM_DATABASE=Colorado Engineering Inc. + +OUI:0050C2721* + ID_OUI_FROM_DATABASE=Spectrum Communications FZE + +OUI:0050C2722* + ID_OUI_FROM_DATABASE=Centric TSolve BV + +OUI:0050C2723* + ID_OUI_FROM_DATABASE=Power Electronics + +OUI:0050C2724* + ID_OUI_FROM_DATABASE=HSC-Regelungstechnik GmbH + +OUI:0050C2725* + ID_OUI_FROM_DATABASE=DSP DESIGN + +OUI:0050C2726* + ID_OUI_FROM_DATABASE=eta systemi CKB + +OUI:0050C2727* + ID_OUI_FROM_DATABASE=Pelweckyj Videotechnik GmbH + +OUI:0050C2728* + ID_OUI_FROM_DATABASE=InterDigital Canada Ltd + +OUI:0050C2729* + ID_OUI_FROM_DATABASE=SP Controls, Inc + +OUI:0050C272A* + ID_OUI_FROM_DATABASE=Phytec Messtechnik GmbH + +OUI:0050C272B* + ID_OUI_FROM_DATABASE=Sequestered Solutions + +OUI:0050C272C* + ID_OUI_FROM_DATABASE=Richard Griessbach Feinmechanik GmbH + +OUI:0050C272D* + ID_OUI_FROM_DATABASE=Physical Acoustics Corporation + +OUI:0050C272E* + ID_OUI_FROM_DATABASE=SNCF EIM PAYS DE LOIRE + +OUI:0050C272F* + ID_OUI_FROM_DATABASE=Priority Electronics Ltd + +OUI:0050C2730* + ID_OUI_FROM_DATABASE=haber & koenig electronics gmbh + +OUI:0050C2731* + ID_OUI_FROM_DATABASE=Spirent Communications + +OUI:0050C2732* + ID_OUI_FROM_DATABASE=Schlumberger K.K. + +OUI:0050C2733* + ID_OUI_FROM_DATABASE=Cimetrics Research Pty Ltd + +OUI:0050C2734* + ID_OUI_FROM_DATABASE=CardioMEMS Inc. + +OUI:0050C2735* + ID_OUI_FROM_DATABASE=Duma Video, Inc. + +OUI:0050C2736* + ID_OUI_FROM_DATABASE=Nika Ltd + +OUI:0050C2737* + ID_OUI_FROM_DATABASE=Teradici Corporation + +OUI:0050C2738* + ID_OUI_FROM_DATABASE=Miracom Technology Co., Ltd. + +OUI:0050C2739* + ID_OUI_FROM_DATABASE=Tattile srl + +OUI:0050C273A* + ID_OUI_FROM_DATABASE=Naturela Ltd. + +OUI:0050C273B* + ID_OUI_FROM_DATABASE=On Air Networks + +OUI:0050C273C* + ID_OUI_FROM_DATABASE=Simicon + +OUI:0050C273D* + ID_OUI_FROM_DATABASE=cryptiris + +OUI:0050C273E* + ID_OUI_FROM_DATABASE=Quantec Networks GmbH + +OUI:0050C273F* + ID_OUI_FROM_DATABASE=MEDAV GmbH + +OUI:0050C2740* + ID_OUI_FROM_DATABASE=McQuay China + +OUI:0050C2741* + ID_OUI_FROM_DATABASE=Dain + +OUI:0050C2742* + ID_OUI_FROM_DATABASE=Fantuzzi Reggiane + +OUI:0050C2743* + ID_OUI_FROM_DATABASE=Elektro-Top 3000 Ltd. + +OUI:0050C2744* + ID_OUI_FROM_DATABASE=Avonaco Systems, Inc. + +OUI:0050C2745* + ID_OUI_FROM_DATABASE=ACISA + +OUI:0050C2746* + ID_OUI_FROM_DATABASE=Realtronix Company + +OUI:0050C2747* + ID_OUI_FROM_DATABASE=CDSA Dam Neck + +OUI:0050C2748* + ID_OUI_FROM_DATABASE=Letechnic Ltd + +OUI:0050C2749* + ID_OUI_FROM_DATABASE=Affolter Technologies SA + +OUI:0050C274A* + ID_OUI_FROM_DATABASE=MONITOR ELECTRONICS LTD + +OUI:0050C274B* + ID_OUI_FROM_DATABASE=STAR-Dundee Ltd + +OUI:0050C274C* + ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG + +OUI:0050C274D* + ID_OUI_FROM_DATABASE=Beceem Communications, Inc. + +OUI:0050C274E* + ID_OUI_FROM_DATABASE=TRONICO + +OUI:0050C274F* + ID_OUI_FROM_DATABASE=German Technologies + +OUI:0050C2750* + ID_OUI_FROM_DATABASE=Brightlights Intellectual Property Ltd + +OUI:0050C2751* + ID_OUI_FROM_DATABASE=e&s Engineering & Software GmbH + +OUI:0050C2752* + ID_OUI_FROM_DATABASE=LOBER, S.A. + +OUI:0050C2753* + ID_OUI_FROM_DATABASE=ABB + +OUI:0050C2754* + ID_OUI_FROM_DATABASE=Abeo Corporation + +OUI:0050C2755* + ID_OUI_FROM_DATABASE=Teletek Electronics + +OUI:0050C2756* + ID_OUI_FROM_DATABASE=Chesapeake Sciences Corp + +OUI:0050C2757* + ID_OUI_FROM_DATABASE=E S P Technologies Ltd + +OUI:0050C2758* + ID_OUI_FROM_DATABASE=AixSolve GmbH + +OUI:0050C2759* + ID_OUI_FROM_DATABASE=Sequentric Energy Systems, LLC + +OUI:0050C275A* + ID_OUI_FROM_DATABASE=Gaisler Research AB + +OUI:0050C275B* + ID_OUI_FROM_DATABASE=DMT System S.p.A. + +OUI:0050C275C* + ID_OUI_FROM_DATABASE=STÖRK-TRONIC Störk GmbH&Co. KG + +OUI:0050C275D* + ID_OUI_FROM_DATABASE=Fluid Analytics, Inc. + +OUI:0050C275E* + ID_OUI_FROM_DATABASE=Sky-Skan, Incorporated + +OUI:0050C275F* + ID_OUI_FROM_DATABASE=B. Rexroth the identity company GmbH + +OUI:0050C2760* + ID_OUI_FROM_DATABASE=AR'S CO., LTD. + +OUI:0050C2761* + ID_OUI_FROM_DATABASE=Elbit Systems of America - Fort Worth Operations + +OUI:0050C2762* + ID_OUI_FROM_DATABASE=Assembly Contracts Limited + +OUI:0050C2763* + ID_OUI_FROM_DATABASE=XtendWave + +OUI:0050C2764* + ID_OUI_FROM_DATABASE=Argus-Spectrum + +OUI:0050C2765* + ID_OUI_FROM_DATABASE=Phytec Messtechnik GmbH + +OUI:0050C2766* + ID_OUI_FROM_DATABASE=EMTEC Elektronische Messtechnik GmbH + +OUI:0050C2767* + ID_OUI_FROM_DATABASE=EID + +OUI:0050C2768* + ID_OUI_FROM_DATABASE=Control Service do Brasil Ltda + +OUI:0050C2769* + ID_OUI_FROM_DATABASE=BES GmbH + +OUI:0050C276A* + ID_OUI_FROM_DATABASE=Digidrive Audio Limited + +OUI:0050C276B* + ID_OUI_FROM_DATABASE=Putercom Enterprise Co., LTD. + +OUI:0050C276C* + ID_OUI_FROM_DATABASE=EFG CZ spol. s r.o. + +OUI:0050C276D* + ID_OUI_FROM_DATABASE=Mobilisme + +OUI:0050C276E* + ID_OUI_FROM_DATABASE=Crinia Corporation + +OUI:0050C276F* + ID_OUI_FROM_DATABASE=Control and Robotics Solutions + +OUI:0050C2770* + ID_OUI_FROM_DATABASE=Cadex Electronics Inc. + +OUI:0050C2771* + ID_OUI_FROM_DATABASE=ZigBee Alliance + +OUI:0050C2772* + ID_OUI_FROM_DATABASE=IES Elektronikentwicklung + +OUI:0050C2773* + ID_OUI_FROM_DATABASE=Pointe Conception Medical Inc. + +OUI:0050C2774* + ID_OUI_FROM_DATABASE=GeoSIG Ltd. + +OUI:0050C2775* + ID_OUI_FROM_DATABASE=Laserdyne Technologies + +OUI:0050C2776* + ID_OUI_FROM_DATABASE=Integrated Security Corporation + +OUI:0050C2777* + ID_OUI_FROM_DATABASE=Euro Display Srl + +OUI:0050C2778* + ID_OUI_FROM_DATABASE=SunGard Vivista + +OUI:0050C2779* + ID_OUI_FROM_DATABASE=Coral Telecom Ltd + +OUI:0050C277A* + ID_OUI_FROM_DATABASE=Smith Meter, Inc + +OUI:0050C277B* + ID_OUI_FROM_DATABASE=Itibia Technologies, Inc. + +OUI:0050C277C* + ID_OUI_FROM_DATABASE=ATEC SRL + +OUI:0050C277D* + ID_OUI_FROM_DATABASE=Lincoln Industrial + +OUI:0050C277E* + ID_OUI_FROM_DATABASE=Cominfo, a.s. + +OUI:0050C277F* + ID_OUI_FROM_DATABASE=ACD Elektronik GmbH + +OUI:0050C2780* + ID_OUI_FROM_DATABASE=IQ Solutions GmbH & Co. KG + +OUI:0050C2781* + ID_OUI_FROM_DATABASE=Starling Advanced Communications + +OUI:0050C2782* + ID_OUI_FROM_DATABASE=Phytec Mestechnik GmbH + +OUI:0050C2783* + ID_OUI_FROM_DATABASE=NORMA systems GmbH + +OUI:0050C2784* + ID_OUI_FROM_DATABASE=Lewis Controls Inc. + +OUI:0050C2785* + ID_OUI_FROM_DATABASE=Icon Time Systems + +OUI:0050C2786* + ID_OUI_FROM_DATABASE=Keith & Koep GmbH + +OUI:0050C2787* + ID_OUI_FROM_DATABASE=Austco Communication Systems Pty Ltd + +OUI:0050C2788* + ID_OUI_FROM_DATABASE=HOSA TECHNOLOGY, INC. + +OUI:0050C2789* + ID_OUI_FROM_DATABASE=Rosslare Enterprises Limited + +OUI:0050C278A* + ID_OUI_FROM_DATABASE=LEVEL TELECOM + +OUI:0050C278B* + ID_OUI_FROM_DATABASE=OMICRON electronics GmbH + +OUI:0050C278C* + ID_OUI_FROM_DATABASE=Giga-tronics, Inc. + +OUI:0050C278D* + ID_OUI_FROM_DATABASE=Telairity + +OUI:0050C278E* + ID_OUI_FROM_DATABASE=GLOBALCOM ENGINEERING SRL + +OUI:0050C278F* + ID_OUI_FROM_DATABASE=ELMAR electronic + +OUI:0050C2790* + ID_OUI_FROM_DATABASE=GE Security-Kampro + +OUI:0050C2791* + ID_OUI_FROM_DATABASE=M Squared Lasers Limited + +OUI:0050C2792* + ID_OUI_FROM_DATABASE=SMARTRO Co.,Ltd. + +OUI:0050C2793* + ID_OUI_FROM_DATABASE=Enertex Bayern GmbH + +OUI:0050C2794* + ID_OUI_FROM_DATABASE=COMSONICS, INC. + +OUI:0050C2795* + ID_OUI_FROM_DATABASE=Ameli Spa + +OUI:0050C2796* + ID_OUI_FROM_DATABASE=DORLET S.A. + +OUI:0050C2797* + ID_OUI_FROM_DATABASE=Tiefenbach Control Systems GmbH + +OUI:0050C2798* + ID_OUI_FROM_DATABASE=Indefia + +OUI:0050C2799* + ID_OUI_FROM_DATABASE=AAVD + +OUI:0050C279A* + ID_OUI_FROM_DATABASE=JMC America, LLC + +OUI:0050C279B* + ID_OUI_FROM_DATABASE=Schniewindt GmbH & Co. KG + +OUI:0050C279C* + ID_OUI_FROM_DATABASE=Vital Systems Inc + +OUI:0050C279D* + ID_OUI_FROM_DATABASE=MiraTrek + +OUI:0050C279E* + ID_OUI_FROM_DATABASE=Benshaw Canada Controls, Inc. + +OUI:0050C279F* + ID_OUI_FROM_DATABASE=ZAO NPC + +OUI:0050C27A0* + ID_OUI_FROM_DATABASE=MedAvant Healthcare + +OUI:0050C27A1* + ID_OUI_FROM_DATABASE=Field Design Service + +OUI:0050C27A2* + ID_OUI_FROM_DATABASE=RaySat Israel LTD + +OUI:0050C27A3* + ID_OUI_FROM_DATABASE=ABB Transmission and Distribution Automation Equipment (Xiam + +OUI:0050C27A4* + ID_OUI_FROM_DATABASE=Calibre UK LTD + +OUI:0050C27A5* + ID_OUI_FROM_DATABASE=Quantum Medical Imaging + +OUI:0050C27A6* + ID_OUI_FROM_DATABASE=ASIANA IDT + +OUI:0050C27A7* + ID_OUI_FROM_DATABASE=Guidance Navigation Limited + +OUI:0050C27A8* + ID_OUI_FROM_DATABASE=Integrated Design Tools, Inc. + +OUI:0050C27A9* + ID_OUI_FROM_DATABASE=Delta Tau Data Systems, Inc + +OUI:0050C27AA* + ID_OUI_FROM_DATABASE=EPEL INDUSTRIAL + +OUI:0050C27AB* + ID_OUI_FROM_DATABASE=General Microsystems Sdn Bhd + +OUI:0050C27AC* + ID_OUI_FROM_DATABASE=IUSA SA DE CV + +OUI:0050C27AD* + ID_OUI_FROM_DATABASE=Turun Turvatekniikka Oy + +OUI:0050C27AE* + ID_OUI_FROM_DATABASE=Global Tel-Link + +OUI:0050C27AF* + ID_OUI_FROM_DATABASE=C2 Microsystems + +OUI:0050C27B0* + ID_OUI_FROM_DATABASE=IMP Telekom + +OUI:0050C27B1* + ID_OUI_FROM_DATABASE=ATEME + +OUI:0050C27B2* + ID_OUI_FROM_DATABASE=A.D.I Video technologies + +OUI:0050C27B3* + ID_OUI_FROM_DATABASE=Elmec, Inc. + +OUI:0050C27B4* + ID_OUI_FROM_DATABASE=T 1 Engineering + +OUI:0050C27B5* + ID_OUI_FROM_DATABASE=DIT-MCO International + +OUI:0050C27B6* + ID_OUI_FROM_DATABASE=Alstom (Schweiz) AG + +OUI:0050C27B7* + ID_OUI_FROM_DATABASE=TATTILE SRL + +OUI:0050C27B8* + ID_OUI_FROM_DATABASE=Design 2000 Pty Ltd + +OUI:0050C27B9* + ID_OUI_FROM_DATABASE=Technovare Systems, Inc. + +OUI:0050C27BA* + ID_OUI_FROM_DATABASE=Infodev Electronic Designers Intl. + +OUI:0050C27BB* + ID_OUI_FROM_DATABASE=InRay Solutions Ltd. + +OUI:0050C27BC* + ID_OUI_FROM_DATABASE=EIDOS SPA + +OUI:0050C27BD* + ID_OUI_FROM_DATABASE=PROMATE ELECTRONIC CO.LTD + +OUI:0050C27BE* + ID_OUI_FROM_DATABASE=Powerlinx, Inc. + +OUI:0050C27BF* + ID_OUI_FROM_DATABASE=Zoe Medical + +OUI:0050C27C0* + ID_OUI_FROM_DATABASE=European Industrial Electronics B.V. + +OUI:0050C27C1* + ID_OUI_FROM_DATABASE=Primary Integration Encorp LLC + +OUI:0050C27C2* + ID_OUI_FROM_DATABASE=DSR Information Technologies Ltd. + +OUI:0050C27C3* + ID_OUI_FROM_DATABASE=AST INCORPORATED + +OUI:0050C27C4* + ID_OUI_FROM_DATABASE=MoBaCon + +OUI:0050C27C5* + ID_OUI_FROM_DATABASE=Venture Research Inc. + +OUI:0050C27C6* + ID_OUI_FROM_DATABASE=Lyngdorf Audio Aps + +OUI:0050C27C7* + ID_OUI_FROM_DATABASE=Pyrosequencing AB + +OUI:0050C27C8* + ID_OUI_FROM_DATABASE=Fr. Sauter AG + +OUI:0050C27C9* + ID_OUI_FROM_DATABASE=Bluebell Opticom Limited + +OUI:0050C27CA* + ID_OUI_FROM_DATABASE=CEDAR Audio Limited + +OUI:0050C27CB* + ID_OUI_FROM_DATABASE=ViewPlus Technologies, Inc. + +OUI:0050C27CC* + ID_OUI_FROM_DATABASE=SWECO JAPS AB + +OUI:0050C27CD* + ID_OUI_FROM_DATABASE=Precision MicroControl Corporation + +OUI:0050C27CE* + ID_OUI_FROM_DATABASE=AirCell Inc. + +OUI:0050C27CF* + ID_OUI_FROM_DATABASE=Emitech Corporation + +OUI:0050C27D0* + ID_OUI_FROM_DATABASE=Radar Tronic ltd. + +OUI:0050C27D1* + ID_OUI_FROM_DATABASE=Phytec Messtechnik GmbH + +OUI:0050C27D2* + ID_OUI_FROM_DATABASE=Bittitalo Oy + +OUI:0050C27D3* + ID_OUI_FROM_DATABASE=Highrail Systems Limited + +OUI:0050C27D4* + ID_OUI_FROM_DATABASE=WR Systems, Ltd. + +OUI:0050C27D5* + ID_OUI_FROM_DATABASE=Deuta-Werke GmbH + +OUI:0050C27D6* + ID_OUI_FROM_DATABASE=International Mining Technologies + +OUI:0050C27D7* + ID_OUI_FROM_DATABASE=Newtec A/S + +OUI:0050C27D8* + ID_OUI_FROM_DATABASE=InnoScan K/S + +OUI:0050C27D9* + ID_OUI_FROM_DATABASE=Volumatic Limited + +OUI:0050C27DA* + ID_OUI_FROM_DATABASE=HTEC Limited + +OUI:0050C27DB* + ID_OUI_FROM_DATABASE=Mueller Elektronik + +OUI:0050C27DC* + ID_OUI_FROM_DATABASE=aiXtrusion GmbH + +OUI:0050C27DD* + ID_OUI_FROM_DATABASE=LS Elektronik AB + +OUI:0050C27DE* + ID_OUI_FROM_DATABASE=Cascade Technologies Ltd + +OUI:0050C27E0* + ID_OUI_FROM_DATABASE=C&D Technologies, Inc + +OUI:0050C27E1* + ID_OUI_FROM_DATABASE=Zeltiq Aesthetics, Inc. + +OUI:0050C27E2* + ID_OUI_FROM_DATABASE=DIGITROL LTD + +OUI:0050C27E3* + ID_OUI_FROM_DATABASE=Progentech Limited + +OUI:0050C27E4* + ID_OUI_FROM_DATABASE=Meta Vision Systems Ltd. + +OUI:0050C27E5* + ID_OUI_FROM_DATABASE=Nystrom Engineering + +OUI:0050C27E6* + ID_OUI_FROM_DATABASE=Empirix Italy S.p.A. + +OUI:0050C27E7* + ID_OUI_FROM_DATABASE=V2Green, Inc. + +OUI:0050C27E8* + ID_OUI_FROM_DATABASE=Mistral Solutions Pvt. Ltd + +OUI:0050C27E9* + ID_OUI_FROM_DATABASE=Sicon s.r.l. + +OUI:0050C27EA* + ID_OUI_FROM_DATABASE=Monitor Business Machines Ltd. + +OUI:0050C27EB* + ID_OUI_FROM_DATABASE=Sesol Industrial Computer + +OUI:0050C27EC* + ID_OUI_FROM_DATABASE=Lyngsoe Systems + +OUI:0050C27ED* + ID_OUI_FROM_DATABASE=Genesis Automation Inc. + +OUI:0050C27EE* + ID_OUI_FROM_DATABASE=NH Research + +OUI:0050C27EF* + ID_OUI_FROM_DATABASE=GFI Chrono Time + +OUI:0050C27F0* + ID_OUI_FROM_DATABASE=Network Harbor, Inc. + +OUI:0050C27F1* + ID_OUI_FROM_DATABASE=STUHL Regelsysteme GmbH + +OUI:0050C27F2* + ID_OUI_FROM_DATABASE=Logotherm Regelsysteme GmbH + +OUI:0050C27F3* + ID_OUI_FROM_DATABASE=SOREC + +OUI:0050C27F4* + ID_OUI_FROM_DATABASE=Wireless Cables Inc + +OUI:0050C27F5* + ID_OUI_FROM_DATABASE=ACE Carwash Systems + +OUI:0050C27F6* + ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG + +OUI:0050C27F7* + ID_OUI_FROM_DATABASE=MangoDSP + +OUI:0050C27F8* + ID_OUI_FROM_DATABASE=Wise Industria de Telecomunicações Ldta. + +OUI:0050C27F9* + ID_OUI_FROM_DATABASE=Karl DUNGS GmbH & Co. KG + +OUI:0050C27FA* + ID_OUI_FROM_DATABASE=AutomationX GmbH + +OUI:0050C27FB* + ID_OUI_FROM_DATABASE=Qtron Pty Ltd + +OUI:0050C27FC* + ID_OUI_FROM_DATABASE=TIS Dialog LLC + +OUI:0050C27FD* + ID_OUI_FROM_DATABASE=Adeneo + +OUI:0050C27FE* + ID_OUI_FROM_DATABASE=Wireless Cables Inc. + +OUI:0050C27FF* + ID_OUI_FROM_DATABASE=Shenzhen MaiWei Cable TV Equipment CO.,LTD. + +OUI:0050C2800* + ID_OUI_FROM_DATABASE=Delphi Display Systems, Inc. + +OUI:0050C2801* + ID_OUI_FROM_DATABASE=JANUS srl + +OUI:0050C2803* + ID_OUI_FROM_DATABASE=dB Broadcast Limited + +OUI:0050C2804* + ID_OUI_FROM_DATABASE=SoftSwitching Technologies + +OUI:0050C2805* + ID_OUI_FROM_DATABASE=MultimediaLED + +OUI:0050C2806* + ID_OUI_FROM_DATABASE=CET + +OUI:0050C2807* + ID_OUI_FROM_DATABASE=TECHNOMARK + +OUI:0050C2808* + ID_OUI_FROM_DATABASE=ITB CompuPhase + +OUI:0050C2809* + ID_OUI_FROM_DATABASE=Varma Electronics Oy + +OUI:0050C280A* + ID_OUI_FROM_DATABASE=Phytec Messtechnik GmbH + +OUI:0050C280B* + ID_OUI_FROM_DATABASE=Open Video, Inc. + +OUI:0050C280C* + ID_OUI_FROM_DATABASE=Luxpert Technologies Co., Ltd. + +OUI:0050C280D* + ID_OUI_FROM_DATABASE=Acube Systems s.r.l. + +OUI:0050C280E* + ID_OUI_FROM_DATABASE=Bruno International Ltd. + +OUI:0050C280F* + ID_OUI_FROM_DATABASE=Selekron Microcontrol s.l. + +OUI:0050C2810* + ID_OUI_FROM_DATABASE=Alphion Corporation + +OUI:0050C2811* + ID_OUI_FROM_DATABASE=Open System Solutions Limited + +OUI:0050C2812* + ID_OUI_FROM_DATABASE=Femto SA + +OUI:0050C2813* + ID_OUI_FROM_DATABASE=Intelleflex Corporation + +OUI:0050C2814* + ID_OUI_FROM_DATABASE=Telvent + +OUI:0050C2815* + ID_OUI_FROM_DATABASE=microC Design SRL + +OUI:0050C2816* + ID_OUI_FROM_DATABASE=Intelight Inc. + +OUI:0050C2817* + ID_OUI_FROM_DATABASE=Odin TeleSystems Inc + +OUI:0050C2818* + ID_OUI_FROM_DATABASE=Wireless Value BV + +OUI:0050C2819* + ID_OUI_FROM_DATABASE=Cabinplant A/S + +OUI:0050C281A* + ID_OUI_FROM_DATABASE=InfoGLOBAL + +OUI:0050C281B* + ID_OUI_FROM_DATABASE=Brain Tech Co., Ltd + +OUI:0050C281C* + ID_OUI_FROM_DATABASE=Telcom + +OUI:0050C281D* + ID_OUI_FROM_DATABASE=IT SALUX CO., LTD. + +OUI:0050C281E* + ID_OUI_FROM_DATABASE=Channelot Ltd. + +OUI:0050C281F* + ID_OUI_FROM_DATABASE=2N TELEKOMUNIKACE a.s. + +OUI:0050C2820* + ID_OUI_FROM_DATABASE=TESCAN, s.r.o. + +OUI:0050C2821* + ID_OUI_FROM_DATABASE=MISCO Refractometer + +OUI:0050C2822* + ID_OUI_FROM_DATABASE=Winner Technology Co, Ltd. + +OUI:0050C2823* + ID_OUI_FROM_DATABASE=Robot Visual Systems GmbH + +OUI:0050C2824* + ID_OUI_FROM_DATABASE=SMT d.o.o. + +OUI:0050C2825* + ID_OUI_FROM_DATABASE=Funkwerk Information Technologies Karlsfeld GmbH + +OUI:0050C2826* + ID_OUI_FROM_DATABASE=HEWI Heinrich Wilke GmbH + +OUI:0050C2827* + ID_OUI_FROM_DATABASE=Enero Solutions inc. + +OUI:0050C2828* + ID_OUI_FROM_DATABASE=SLICAN sp. z o.o. + +OUI:0050C2829* + ID_OUI_FROM_DATABASE=Intellectronika + +OUI:0050C282A* + ID_OUI_FROM_DATABASE=VDC Display Systems + +OUI:0050C282B* + ID_OUI_FROM_DATABASE=Keith & Koep GmbH + +OUI:0050C282C* + ID_OUI_FROM_DATABASE=Vitel Net + +OUI:0050C282D* + ID_OUI_FROM_DATABASE=Elmec, Inc. + +OUI:0050C282E* + ID_OUI_FROM_DATABASE=LogiCom GmbH + +OUI:0050C282F* + ID_OUI_FROM_DATABASE=Momentum Data Systems + +OUI:0050C2830* + ID_OUI_FROM_DATABASE=CompuShop Services LLC + +OUI:0050C2831* + ID_OUI_FROM_DATABASE=St Jude Medical, Inc. + +OUI:0050C2832* + ID_OUI_FROM_DATABASE=S1nn GmbH & Co. KG + +OUI:0050C2833* + ID_OUI_FROM_DATABASE=LaserLinc, Inc. + +OUI:0050C2834* + ID_OUI_FROM_DATABASE=ANTEK GmbH + +OUI:0050C2835* + ID_OUI_FROM_DATABASE=Communications Laboratories Inc + +OUI:0050C2836* + ID_OUI_FROM_DATABASE=DSP DESIGN + +OUI:0050C2837* + ID_OUI_FROM_DATABASE=ID-KARTA s.r.o. + +OUI:0050C2838* + ID_OUI_FROM_DATABASE=T PROJE MUHENDISLIK DIS. TIC. LTD. STI. + +OUI:0050C2839* + ID_OUI_FROM_DATABASE=IMS Röntgensysteme GmbH + +OUI:0050C283A* + ID_OUI_FROM_DATABASE=Syr-Tec Engineering & Marketing + +OUI:0050C283B* + ID_OUI_FROM_DATABASE=O. Bay AG + +OUI:0050C283C* + ID_OUI_FROM_DATABASE=hema electronic GmbH + +OUI:0050C283D* + ID_OUI_FROM_DATABASE=beroNet GmbH + +OUI:0050C283E* + ID_OUI_FROM_DATABASE=KPE spol. s r.o. + +OUI:0050C283F* + ID_OUI_FROM_DATABASE=Phytec Messtechnik GmbH + +OUI:0050C2840* + ID_OUI_FROM_DATABASE=Residential Control Systems + +OUI:0050C2841* + ID_OUI_FROM_DATABASE=Connection Electronics Ltd. + +OUI:0050C2842* + ID_OUI_FROM_DATABASE=Quantum Controls BV + +OUI:0050C2843* + ID_OUI_FROM_DATABASE=Xtensor Systems Inc. + +OUI:0050C2844* + ID_OUI_FROM_DATABASE=Prodigy Electronics Limited + +OUI:0050C2845* + ID_OUI_FROM_DATABASE=VisualSonics Inc. + +OUI:0050C2846* + ID_OUI_FROM_DATABASE=ESP-Planning Co. + +OUI:0050C2847* + ID_OUI_FROM_DATABASE=Lars Morich Kommunikationstechnik GmbH + +OUI:0050C2848* + ID_OUI_FROM_DATABASE=DASA ROBOT Co., Ltd. + +OUI:0050C2849* + ID_OUI_FROM_DATABASE=Design Analysis Associates, Inc. + +OUI:0050C284A* + ID_OUI_FROM_DATABASE=Keystone Electronic Solutions + +OUI:0050C284B* + ID_OUI_FROM_DATABASE=TASK SISTEMAS DE COMPUTACAO LTDA + +OUI:0050C284C* + ID_OUI_FROM_DATABASE=Performance Motion Devices + +OUI:0050C284D* + ID_OUI_FROM_DATABASE=BMTI + +OUI:0050C284E* + ID_OUI_FROM_DATABASE=DRACO SYSTEMS + +OUI:0050C284F* + ID_OUI_FROM_DATABASE=Gamber-Johnson LLC + +OUI:0050C2850* + ID_OUI_FROM_DATABASE=K.K. Rocky + +OUI:0050C2851* + ID_OUI_FROM_DATABASE=SPJ Embedded Technologies Pvt. Ltd. + +OUI:0050C2852* + ID_OUI_FROM_DATABASE=eInfochips Ltd. + +OUI:0050C2853* + ID_OUI_FROM_DATABASE=Ettus Research LLC + +OUI:0050C2854* + ID_OUI_FROM_DATABASE=Ratioplast-Optoelectronics GmbH + +OUI:0050C2855* + ID_OUI_FROM_DATABASE=Rohde & Schwarz Topex SA + +OUI:0050C2856* + ID_OUI_FROM_DATABASE=CT Company + +OUI:0050C2857* + ID_OUI_FROM_DATABASE=EPEL INDUSTRIAL + +OUI:0050C2858* + ID_OUI_FROM_DATABASE=Wireless Acquisition LLC + +OUI:0050C2859* + ID_OUI_FROM_DATABASE=Nuvation + +OUI:0050C285A* + ID_OUI_FROM_DATABASE=ART s.r.l. + +OUI:0050C285B* + ID_OUI_FROM_DATABASE=Boreste + +OUI:0050C285C* + ID_OUI_FROM_DATABASE=B S E + +OUI:0050C285D* + ID_OUI_FROM_DATABASE=Ing. Knauseder Mechatronik GmbH + +OUI:0050C285E* + ID_OUI_FROM_DATABASE=Radiometer Medical ApS + +OUI:0050C285F* + ID_OUI_FROM_DATABASE=General Dynamics C4 Systems + +OUI:0050C2860* + ID_OUI_FROM_DATABASE=Eutron S.p.A. + +OUI:0050C2861* + ID_OUI_FROM_DATABASE=Grantronics Pty Ltd + +OUI:0050C2862* + ID_OUI_FROM_DATABASE=Elsys AG + +OUI:0050C2863* + ID_OUI_FROM_DATABASE=Advanced Technology Solutions + +OUI:0050C2864* + ID_OUI_FROM_DATABASE=ATG Automatisierungstechnik GERA GmbH + +OUI:0050C2865* + ID_OUI_FROM_DATABASE=Persy Control Services B.v. + +OUI:0050C2866* + ID_OUI_FROM_DATABASE=Saia Burgess Controls AG + +OUI:0050C2867* + ID_OUI_FROM_DATABASE=Syntronics + +OUI:0050C2868* + ID_OUI_FROM_DATABASE=Aethon, Inc. + +OUI:0050C2869* + ID_OUI_FROM_DATABASE=Funkwerk plettac electronic GmbH + +OUI:0050C286A* + ID_OUI_FROM_DATABASE=USM Systems, Ltd + +OUI:0050C286B* + ID_OUI_FROM_DATABASE=OMB Sistemas Electronicos S.A. + +OUI:0050C286C* + ID_OUI_FROM_DATABASE=Condigi Televagt A/S + +OUI:0050C286D* + ID_OUI_FROM_DATABASE=Tieline Research Pty Ltd + +OUI:0050C286E* + ID_OUI_FROM_DATABASE=HANYANG ELECTRIC CP., LTD + +OUI:0050C286F* + ID_OUI_FROM_DATABASE=b-plus GmbH + +OUI:0050C2870* + ID_OUI_FROM_DATABASE=LOGEL S.R.L. + +OUI:0050C2871* + ID_OUI_FROM_DATABASE=R-S-I Elektrotechnik GmbH & Co. KG + +OUI:0050C2872* + ID_OUI_FROM_DATABASE=Oliotalo - Objecthouse Oy + +OUI:0050C2873* + ID_OUI_FROM_DATABASE=XRONET Corporation + +OUI:0050C2874* + ID_OUI_FROM_DATABASE=Arcos Technologies Ltd. + +OUI:0050C2875* + ID_OUI_FROM_DATABASE=Phytec Messtechnik GmbH + +OUI:0050C2876* + ID_OUI_FROM_DATABASE=Privatquelle Gruber GmbH & CO KG + +OUI:0050C2877* + ID_OUI_FROM_DATABASE=Motion Analysis Corp + +OUI:0050C2878* + ID_OUI_FROM_DATABASE=Acoustic Research Laboratories Pty Ltd + +OUI:0050C2879* + ID_OUI_FROM_DATABASE=MILESYS + +OUI:0050C287A* + ID_OUI_FROM_DATABASE=Spectrum Management, LC + +OUI:0050C287B* + ID_OUI_FROM_DATABASE=UAVNavigation S.L. + +OUI:0050C287C* + ID_OUI_FROM_DATABASE=Arcontia AB + +OUI:0050C287D* + ID_OUI_FROM_DATABASE=AT&T Government Solutions + +OUI:0050C287E* + ID_OUI_FROM_DATABASE=SCM PRODUCTS, INC. + +OUI:0050C287F* + ID_OUI_FROM_DATABASE=Optoelettronica Italia S.r.l. + +OUI:0050C2880* + ID_OUI_FROM_DATABASE=Creation Technologies + +OUI:0050C2881* + ID_OUI_FROM_DATABASE=InnoTrans Communications, Inc. + +OUI:0050C2882* + ID_OUI_FROM_DATABASE=WARECUBE,INC. + +OUI:0050C2883* + ID_OUI_FROM_DATABASE=Neocontrol Soluções em Automação + +OUI:0050C2884* + ID_OUI_FROM_DATABASE=IP Thinking A/S + +OUI:0050C2885* + ID_OUI_FROM_DATABASE=OOO "NTK "IMOS" + +OUI:0050C2886* + ID_OUI_FROM_DATABASE=Transas Scandinavia AB + +OUI:0050C2887* + ID_OUI_FROM_DATABASE=Inventis Technology Pty Limited + +OUI:0050C2888* + ID_OUI_FROM_DATABASE=IADEA CORPORATION + +OUI:0050C2889* + ID_OUI_FROM_DATABASE=ACS MOTION CONTROL + +OUI:0050C288A* + ID_OUI_FROM_DATABASE=Continental Electronics Corp. + +OUI:0050C288B* + ID_OUI_FROM_DATABASE=Hollis Electronics Company LLC + +OUI:0050C288C* + ID_OUI_FROM_DATABASE=Z-App Systems + +OUI:0050C288D* + ID_OUI_FROM_DATABASE=L3 Communications Nova Engineering + +OUI:0050C288E* + ID_OUI_FROM_DATABASE=Cardinal Scale Mfg Co + +OUI:0050C288F* + ID_OUI_FROM_DATABASE=Keynote SIGOS GmbH + +OUI:0050C2890* + ID_OUI_FROM_DATABASE=BAE Systems Hägglunds AB + +OUI:0050C2891* + ID_OUI_FROM_DATABASE=Admiral Secure Products, Ltd. + +OUI:0050C2892* + ID_OUI_FROM_DATABASE=Trakce a.s. + +OUI:0050C2893* + ID_OUI_FROM_DATABASE=EIZO Technologies GmbH + +OUI:0050C2894* + ID_OUI_FROM_DATABASE=Shockfish SA + +OUI:0050C2895* + ID_OUI_FROM_DATABASE=Marine Communications Limited + +OUI:0050C2896* + ID_OUI_FROM_DATABASE=Blankom + +OUI:0050C2897* + ID_OUI_FROM_DATABASE=ODF Optronics, Inc. + +OUI:0050C2898* + ID_OUI_FROM_DATABASE=Veeco Process Equipment, Inc. + +OUI:0050C2899* + ID_OUI_FROM_DATABASE=Inico Technologies Ltd. + +OUI:0050C289A* + ID_OUI_FROM_DATABASE=Neptune Technology Group, Inc. + +OUI:0050C289B* + ID_OUI_FROM_DATABASE=Sensata Technologies, Inc. + +OUI:0050C289C* + ID_OUI_FROM_DATABASE=Mediana + +OUI:0050C289D* + ID_OUI_FROM_DATABASE=Systemtechnik GmbH + +OUI:0050C289E* + ID_OUI_FROM_DATABASE=Broadcast Electronics + +OUI:0050C289F* + ID_OUI_FROM_DATABASE=Datalink Technologies Gateways Inc. + +OUI:0050C28A0* + ID_OUI_FROM_DATABASE=Specialized Communications Corp. + +OUI:0050C28A1* + ID_OUI_FROM_DATABASE=Intune Networks Limited + +OUI:0050C28A2* + ID_OUI_FROM_DATABASE=UAVISION Engenharia de Sistemas + +OUI:0050C28A3* + ID_OUI_FROM_DATABASE=RTW GmbH & Co.KG + +OUI:0050C28A4* + ID_OUI_FROM_DATABASE=BALOGH T.A.G Corporation + +OUI:0050C28A5* + ID_OUI_FROM_DATABASE=Mocon, Inc. + +OUI:0050C28A6* + ID_OUI_FROM_DATABASE=SELCO + +OUI:0050C28A7* + ID_OUI_FROM_DATABASE=EBPW LTD + +OUI:0050C28A8* + ID_OUI_FROM_DATABASE=ALTEK ELECTRONICS + +OUI:0050C28A9* + ID_OUI_FROM_DATABASE=Intelligent Security Systems + +OUI:0050C28AA* + ID_OUI_FROM_DATABASE=ATS Elektronik GmbH + +OUI:0050C28AB* + ID_OUI_FROM_DATABASE=Nanomotion Ltd. + +OUI:0050C28AC* + ID_OUI_FROM_DATABASE=Telsa s.r.l + +OUI:0050C28AD* + ID_OUI_FROM_DATABASE=Thales Communications, Inc + +OUI:0050C28AE* + ID_OUI_FROM_DATABASE=DESARROLLO DE SISTEMAS INTEGRADOS DE CONTROL S.A. + +OUI:0050C28AF* + ID_OUI_FROM_DATABASE=Xelerated + +OUI:0050C28B0* + ID_OUI_FROM_DATABASE=BK Innovation, Inc. + +OUI:0050C28B1* + ID_OUI_FROM_DATABASE=RingCube Technologies, Inc. + +OUI:0050C28B2* + ID_OUI_FROM_DATABASE=SERVAIND SA. + +OUI:0050C28B3* + ID_OUI_FROM_DATABASE=VTQ Videtronik GmbH + +OUI:0050C28B4* + ID_OUI_FROM_DATABASE=Sandar Telecast AS + +OUI:0050C28B5* + ID_OUI_FROM_DATABASE=Keith & Koep GmbH + +OUI:0050C28B6* + ID_OUI_FROM_DATABASE=Shadrinskiy Telefonny Zavod + +OUI:0050C28B7* + ID_OUI_FROM_DATABASE=Calnex Solutions Limited + +OUI:0050C28B8* + ID_OUI_FROM_DATABASE=DSS Networks, Inc. + +OUI:0050C28B9* + ID_OUI_FROM_DATABASE=ACD Elektronik Gmbh + +OUI:0050C28BA* + ID_OUI_FROM_DATABASE=Fr. Sauter AG + +OUI:0050C28BB* + ID_OUI_FROM_DATABASE=smtag international ag + +OUI:0050C28BC* + ID_OUI_FROM_DATABASE=Honeywell Sensotec + +OUI:0050C28BD* + ID_OUI_FROM_DATABASE=Matrix Switch Corporation + +OUI:0050C28BE* + ID_OUI_FROM_DATABASE=The Pennsylvania State University + +OUI:0050C28BF* + ID_OUI_FROM_DATABASE=ARISTO Graphic Systeme GmbH & Co. KG + +OUI:0050C28C0* + ID_OUI_FROM_DATABASE=S.C.E. s.r.l. + +OUI:0050C28C1* + ID_OUI_FROM_DATABASE=Heraeus Noblelight GmbH + +OUI:0050C28C2* + ID_OUI_FROM_DATABASE=Access Control Systems JSC + +OUI:0050C28C3* + ID_OUI_FROM_DATABASE=Byte Paradigm + +OUI:0050C28C4* + ID_OUI_FROM_DATABASE=Soldig Industria e Comercio de Equipamentos Eletronicos LTDA + +OUI:0050C28C5* + ID_OUI_FROM_DATABASE=Vortex Engineering pvt ltd + +OUI:0050C28C6* + ID_OUI_FROM_DATABASE=Gradual Tecnologia Ltda. + +OUI:0050C28C7* + ID_OUI_FROM_DATABASE=Tattile srl + +OUI:0050C28C8* + ID_OUI_FROM_DATABASE=Pumatronix Equipamentos Eletrônicos Ltda + +OUI:0050C28C9* + ID_OUI_FROM_DATABASE=A+S Aktuatorik und Sensorik GmbH + +OUI:0050C28CA* + ID_OUI_FROM_DATABASE=Altair semiconductor Ltd + +OUI:0050C28CB* + ID_OUI_FROM_DATABASE=Beonic Corporation + +OUI:0050C28CC* + ID_OUI_FROM_DATABASE=LyconSys GmbH & Co.KG + +OUI:0050C28CD* + ID_OUI_FROM_DATABASE=Cambridge Sound Management, LLC + +OUI:0050C28CE* + ID_OUI_FROM_DATABASE=Phytec Messtechnik GmbH + +OUI:0050C28CF* + ID_OUI_FROM_DATABASE=GigaLinx Ltd. + +OUI:0050C28D0* + ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG + +OUI:0050C28D1* + ID_OUI_FROM_DATABASE=my-sen GmbH + +OUI:0050C28D2* + ID_OUI_FROM_DATABASE=TTi Ltd + +OUI:0050C28D3* + ID_OUI_FROM_DATABASE=IFAM GmbH + +OUI:0050C28D4* + ID_OUI_FROM_DATABASE=Internet Protocolo Lógica SL + +OUI:0050C28D5* + ID_OUI_FROM_DATABASE=Peek Traffic Corp + +OUI:0050C28D6* + ID_OUI_FROM_DATABASE=UltraVision Security Systems, Inc. + +OUI:0050C28D7* + ID_OUI_FROM_DATABASE=Polygon Informatics Ltd. + +OUI:0050C28D8* + ID_OUI_FROM_DATABASE=Array Technologies Inc + +OUI:0050C28D9* + ID_OUI_FROM_DATABASE=Industrial Control and Communication Limited + +OUI:0050C28DA* + ID_OUI_FROM_DATABASE=DOCUTEMP, INC + +OUI:0050C28DB* + ID_OUI_FROM_DATABASE=DCOM Network Technology (Pty) Ltd + +OUI:0050C28DC* + ID_OUI_FROM_DATABASE=Frame Systems Limited + +OUI:0050C28DD* + ID_OUI_FROM_DATABASE=GIMCON + +OUI:0050C28DE* + ID_OUI_FROM_DATABASE=Coherix, Inc + +OUI:0050C28DF* + ID_OUI_FROM_DATABASE=Dipl.-Ing. W. Nophut GmbH + +OUI:0050C28E0* + ID_OUI_FROM_DATABASE=Shenzhen Pennda Technologies Co., Ltd. + +OUI:0050C28E1* + ID_OUI_FROM_DATABASE=Deutscher Weterdienst + +OUI:0050C28E2* + ID_OUI_FROM_DATABASE=Wireless Cables Inc + +OUI:0050C28E3* + ID_OUI_FROM_DATABASE=bioMérieux Italia S.p.A. + +OUI:0050C28E4* + ID_OUI_FROM_DATABASE=MaCaPS International Limited + +OUI:0050C28E5* + ID_OUI_FROM_DATABASE=Berthel GmbH + +OUI:0050C28E6* + ID_OUI_FROM_DATABASE=Sandel Avionics, Inc. + +OUI:0050C28E7* + ID_OUI_FROM_DATABASE=MKT Systemtechnik + +OUI:0050C28E8* + ID_OUI_FROM_DATABASE=Friedrich Kuhnt GmbH + +OUI:0050C28E9* + ID_OUI_FROM_DATABASE=UNIDATA + +OUI:0050C28EA* + ID_OUI_FROM_DATABASE=ATEME + +OUI:0050C28EB* + ID_OUI_FROM_DATABASE=C-COM Satellite Systems Inc. + +OUI:0050C28EC* + ID_OUI_FROM_DATABASE=Balfour Beatty Rail GmbH + +OUI:0050C28ED* + ID_OUI_FROM_DATABASE=AT-Automation Technology GmbH + +OUI:0050C28EE* + ID_OUI_FROM_DATABASE=PCSC + +OUI:0050C28EF* + ID_OUI_FROM_DATABASE=Technologies Sensio Inc + +OUI:0050C28F0* + ID_OUI_FROM_DATABASE=Xentras Communications + +OUI:0050C28F1* + ID_OUI_FROM_DATABASE=Detection Technologies Ltd. + +OUI:0050C28F2* + ID_OUI_FROM_DATABASE=Schneider Electric GmbH + +OUI:0050C28F3* + ID_OUI_FROM_DATABASE=Curtis Door Systems Inc + +OUI:0050C28F4* + ID_OUI_FROM_DATABASE=Critical Link + +OUI:0050C28F5* + ID_OUI_FROM_DATABASE=tec5 AG + +OUI:0050C28F6* + ID_OUI_FROM_DATABASE=K-MAC Corp. + +OUI:0050C28F7* + ID_OUI_FROM_DATABASE=TGE Co., Ltd. + +OUI:0050C28F8* + ID_OUI_FROM_DATABASE=RMSD LTD + +OUI:0050C28F9* + ID_OUI_FROM_DATABASE=Honeywell International + +OUI:0050C28FA* + ID_OUI_FROM_DATABASE=TELIUM s.c. + +OUI:0050C28FB* + ID_OUI_FROM_DATABASE=Alfred Kuhse GmbH + +OUI:0050C28FC* + ID_OUI_FROM_DATABASE=Symetrics Industries + +OUI:0050C28FD* + ID_OUI_FROM_DATABASE=Sindoma Müh Mim Ýnþ Elk San Tic Ltd. + +OUI:0050C28FE* + ID_OUI_FROM_DATABASE=Cross Country Systems AB + +OUI:0050C28FF* + ID_OUI_FROM_DATABASE=Luceat Spa + +OUI:0050C2900* + ID_OUI_FROM_DATABASE=Magor Communications Corp + +OUI:0050C2901* + ID_OUI_FROM_DATABASE=Research Applications Incorp + +OUI:0050C2902* + ID_OUI_FROM_DATABASE=China Railway Signal & Communication Corp. + +OUI:0050C2903* + ID_OUI_FROM_DATABASE=EcoAxis Systems Pvt. Ltd. + +OUI:0050C2904* + ID_OUI_FROM_DATABASE=R2Sonic, LLC + +OUI:0050C2905* + ID_OUI_FROM_DATABASE=Link Communications, Inc + +OUI:0050C2906* + ID_OUI_FROM_DATABASE=Gidel + +OUI:0050C2907* + ID_OUI_FROM_DATABASE=Cristal Controles Ltee + +OUI:0050C2908* + ID_OUI_FROM_DATABASE=Codex Digital Ltd + +OUI:0050C2909* + ID_OUI_FROM_DATABASE=Elisra Electronic Systems + +OUI:0050C290A* + ID_OUI_FROM_DATABASE=Board Level Limited + +OUI:0050C290B* + ID_OUI_FROM_DATABASE=E.ON ES Sverige AB + +OUI:0050C290C* + ID_OUI_FROM_DATABASE=LSS GmbH + +OUI:0050C290D* + ID_OUI_FROM_DATABASE=EVK DI Kerschhaggl GmbH + +OUI:0050C290E* + ID_OUI_FROM_DATABASE=Phytec Messtechnik GmbH + +OUI:0050C290F* + ID_OUI_FROM_DATABASE=INTEGRA Biosciences AG + +OUI:0050C2910* + ID_OUI_FROM_DATABASE=Autotank AB + +OUI:0050C2911* + ID_OUI_FROM_DATABASE=Vapor Rail + +OUI:0050C2912* + ID_OUI_FROM_DATABASE=ASSET InterTech, Inc. + +OUI:0050C2913* + ID_OUI_FROM_DATABASE=Selex Sensors & Airborne Systems + +OUI:0050C2914* + ID_OUI_FROM_DATABASE=IO-Connect + +OUI:0050C2915* + ID_OUI_FROM_DATABASE=Verint Systems Ltd. + +OUI:0050C2916* + ID_OUI_FROM_DATABASE=CHK GridSense P/L + +OUI:0050C2917* + ID_OUI_FROM_DATABASE=CIRTEM + +OUI:0050C2918* + ID_OUI_FROM_DATABASE=Design Lightning Corp + +OUI:0050C2919* + ID_OUI_FROM_DATABASE=AHV Systems, Inc. + +OUI:0050C291A* + ID_OUI_FROM_DATABASE=Xtone Networks + +OUI:0050C291B* + ID_OUI_FROM_DATABASE=Embedded Data Systems, LLC + +OUI:0050C291C* + ID_OUI_FROM_DATABASE=MangoDSP + +OUI:0050C291D* + ID_OUI_FROM_DATABASE=Rosendahl Studiotechnik GmbH + +OUI:0050C291E* + ID_OUI_FROM_DATABASE=Automation Tec + +OUI:0050C291F* + ID_OUI_FROM_DATABASE=2NCOMM DESIGN SRL + +OUI:0050C2920* + ID_OUI_FROM_DATABASE=Rogue Engineering Inc. + +OUI:0050C2921* + ID_OUI_FROM_DATABASE=iQue RFID Technologies BV + +OUI:0050C2922* + ID_OUI_FROM_DATABASE=Metrum Sweden AB + +OUI:0050C2923* + ID_OUI_FROM_DATABASE=Amicus Wireless + +OUI:0050C2924* + ID_OUI_FROM_DATABASE=Link Electric & Safety Control Co. + +OUI:0050C2925* + ID_OUI_FROM_DATABASE=PHB Eletronica Ltda. + +OUI:0050C2926* + ID_OUI_FROM_DATABASE=DITEST FAHRZEUGDIAGNOSE GMBH + +OUI:0050C2927* + ID_OUI_FROM_DATABASE=ATIS group s.r.o. + +OUI:0050C2928* + ID_OUI_FROM_DATABASE=Cinetix GmbH + +OUI:0050C2929* + ID_OUI_FROM_DATABASE=Flight Deck Resources + +OUI:0050C292A* + ID_OUI_FROM_DATABASE=Rohde & Schwarz Topex SA + +OUI:0050C292B* + ID_OUI_FROM_DATABASE=DSP DESIGN + +OUI:0050C292C* + ID_OUI_FROM_DATABASE=Exatrol Corporation + +OUI:0050C292D* + ID_OUI_FROM_DATABASE=APProSoftware.com + +OUI:0050C292E* + ID_OUI_FROM_DATABASE=Goanna Technologies Pty Ltd + +OUI:0050C292F* + ID_OUI_FROM_DATABASE=Phytec Messtechnik GmbH + +OUI:0050C2930* + ID_OUI_FROM_DATABASE=NETA Elektronik AS + +OUI:0050C2931* + ID_OUI_FROM_DATABASE=Korea Telecom Internet Solutions (KTIS) + +OUI:0050C2932* + ID_OUI_FROM_DATABASE=SMAVIS Inc. + +OUI:0050C2933* + ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG + +OUI:0050C2934* + ID_OUI_FROM_DATABASE=Xilar Corp. + +OUI:0050C2935* + ID_OUI_FROM_DATABASE=Image Video + +OUI:0050C2936* + ID_OUI_FROM_DATABASE=Margaritis Engineering + +OUI:0050C2937* + ID_OUI_FROM_DATABASE=BigBear + +OUI:0050C2938* + ID_OUI_FROM_DATABASE=Postec Data Systems Ltd + +OUI:0050C2939* + ID_OUI_FROM_DATABASE=Mosaic Dynamic Solutions + +OUI:0050C293A* + ID_OUI_FROM_DATABASE=ALPHATRONICS nv + +OUI:0050C293B* + ID_OUI_FROM_DATABASE=Reliatronics Inc. + +OUI:0050C293C* + ID_OUI_FROM_DATABASE=FractureCode Corporation + +OUI:0050C293D* + ID_OUI_FROM_DATABASE=Lighting Science Group Corporation + +OUI:0050C293E* + ID_OUI_FROM_DATABASE=RCS Communication Test Systems Ltd. + +OUI:0050C293F* + ID_OUI_FROM_DATABASE=TSB Solutions Inc. + +OUI:0050C2940* + ID_OUI_FROM_DATABASE=Phitek Systems Ltd. + +OUI:0050C2941* + ID_OUI_FROM_DATABASE=Rolbit + +OUI:0050C2942* + ID_OUI_FROM_DATABASE=Keith & Koep GmbH + +OUI:0050C2943* + ID_OUI_FROM_DATABASE=QuanZhou TDX Electronics Co., Ltd. + +OUI:0050C2944* + ID_OUI_FROM_DATABASE=Wireonair A/S + +OUI:0050C2945* + ID_OUI_FROM_DATABASE=Ex-i Flow Measurement Ltd. + +OUI:0050C2946* + ID_OUI_FROM_DATABASE=MEGWARE Computer GmbH + +OUI:0050C2947* + ID_OUI_FROM_DATABASE=IMEXHIGHWAY cvba + +OUI:0050C2948* + ID_OUI_FROM_DATABASE=ELECTRONIA + +OUI:0050C2949* + ID_OUI_FROM_DATABASE=taskit GmbH + +OUI:0050C294A* + ID_OUI_FROM_DATABASE=TRUMEDIA TECHNOLOGIES + +OUI:0050C294B* + ID_OUI_FROM_DATABASE=Piller engineering Ltd. + +OUI:0050C294C* + ID_OUI_FROM_DATABASE=TEMIX + +OUI:0050C294D* + ID_OUI_FROM_DATABASE=C&H technology ltd. + +OUI:0050C294E* + ID_OUI_FROM_DATABASE=Zynix Original Sdn. Bhd. + +OUI:0050C294F* + ID_OUI_FROM_DATABASE=IT-Designers GmbH + +OUI:0050C2950* + ID_OUI_FROM_DATABASE=Tele and Radio Research Institute + +OUI:0050C2951* + ID_OUI_FROM_DATABASE=EL.C.A. soc. coop. + +OUI:0050C2952* + ID_OUI_FROM_DATABASE=Tech Fass s.r.o. + +OUI:0050C2953* + ID_OUI_FROM_DATABASE=EPEL Industrial + +OUI:0050C2954* + ID_OUI_FROM_DATABASE=Phytec Messtechnik GmbH + +OUI:0050C2955* + ID_OUI_FROM_DATABASE=Roessmann Engineering + +OUI:0050C2956* + ID_OUI_FROM_DATABASE=Sicon s.r.l. + +OUI:0050C2957* + ID_OUI_FROM_DATABASE=STRATEC Control Systems + +OUI:0050C2958* + ID_OUI_FROM_DATABASE=Sensoptics Ltd + +OUI:0050C2959* + ID_OUI_FROM_DATABASE=DECTRIS Ltd. + +OUI:0050C295A* + ID_OUI_FROM_DATABASE=TechnoAP + +OUI:0050C295B* + ID_OUI_FROM_DATABASE=AS Solar GmbH + +OUI:0050C295C* + ID_OUI_FROM_DATABASE=Resurgent Health & Medical + +OUI:0050C295D* + ID_OUI_FROM_DATABASE=full electronic system + +OUI:0050C295E* + ID_OUI_FROM_DATABASE=BEEcube Inc. + +OUI:0050C295F* + ID_OUI_FROM_DATABASE=METRONIC APARATURA KONTROLNO - POMIAROWA + +OUI:0050C2960* + ID_OUI_FROM_DATABASE=kuroneko dennnou kenkyuushitsu + +OUI:0050C2961* + ID_OUI_FROM_DATABASE=Picsolve International Limited + +OUI:0050C2962* + ID_OUI_FROM_DATABASE=Shockfish SA + +OUI:0050C2963* + ID_OUI_FROM_DATABASE=Lécureux SA + +OUI:0050C2964* + ID_OUI_FROM_DATABASE=IQ Automation GmbH + +OUI:0050C2965* + ID_OUI_FROM_DATABASE=Emitech Corporation + +OUI:0050C2966* + ID_OUI_FROM_DATABASE=PCM Industries + +OUI:0050C2967* + ID_OUI_FROM_DATABASE=Watthour Engineering Co., Inc. + +OUI:0050C2968* + ID_OUI_FROM_DATABASE=BuLogics, Inc. + +OUI:0050C2969* + ID_OUI_FROM_DATABASE=Gehrke Kommunikationssysteme GmbH + +OUI:0050C296A* + ID_OUI_FROM_DATABASE=Elektrobit Wireless Communications Ltd + +OUI:0050C296B* + ID_OUI_FROM_DATABASE=Electronic Media Services Ltd + +OUI:0050C296C* + ID_OUI_FROM_DATABASE=Aqua Cooler Pty Ltd + +OUI:0050C296D* + ID_OUI_FROM_DATABASE=Keene Electronics Ltd. + +OUI:0050C296E* + ID_OUI_FROM_DATABASE=Peek Traffic Corporation + +OUI:0050C296F* + ID_OUI_FROM_DATABASE=Varec Inc. + +OUI:0050C2970* + ID_OUI_FROM_DATABASE=Tsuji Electronics Co.,Ltd + +OUI:0050C2971* + ID_OUI_FROM_DATABASE=Ipitek + +OUI:0050C2972* + ID_OUI_FROM_DATABASE=Switch Science (Panini Keikaku) + +OUI:0050C2973* + ID_OUI_FROM_DATABASE=Systèmes Pran + +OUI:0050C2974* + ID_OUI_FROM_DATABASE=EMAC, INC. + +OUI:0050C2975* + ID_OUI_FROM_DATABASE=Pyramid Technical Consultants + +OUI:0050C2976* + ID_OUI_FROM_DATABASE=SANDS INSTRUMENTATION INDIA PVT LTD + +OUI:0050C2977* + ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG + +OUI:0050C2978* + ID_OUI_FROM_DATABASE=LOGITAL DIGITAL MEDIA srl + +OUI:0050C2979* + ID_OUI_FROM_DATABASE=Far South Networks (Pty) Ltd + +OUI:0050C297A* + ID_OUI_FROM_DATABASE=KST Technology Co., Ltd + +OUI:0050C297B* + ID_OUI_FROM_DATABASE=SMARTQUANTUM SA + +OUI:0050C297C* + ID_OUI_FROM_DATABASE=Creacon Technologies B.V. + +OUI:0050C297D* + ID_OUI_FROM_DATABASE=Soehnle Professional GmbH & Co.KG + +OUI:0050C297E* + ID_OUI_FROM_DATABASE=Long Distance Technologies + +OUI:0050C297F* + ID_OUI_FROM_DATABASE=C&I Co.Ltd + +OUI:0050C2980* + ID_OUI_FROM_DATABASE=Digital Payment Technologies + +OUI:0050C2981* + ID_OUI_FROM_DATABASE=Novotronik GmbH + +OUI:0050C2982* + ID_OUI_FROM_DATABASE=Triple Ring Technologies, Inc. + +OUI:0050C2983* + ID_OUI_FROM_DATABASE=Bogart Engineering + +OUI:0050C2984* + ID_OUI_FROM_DATABASE=Atel Corporation + +OUI:0050C2985* + ID_OUI_FROM_DATABASE=Earnestcom Sdn Bhd + +OUI:0050C2986* + ID_OUI_FROM_DATABASE=DSCI + +OUI:0050C2987* + ID_OUI_FROM_DATABASE=Joinsoon Electronics MFG. Co., Ltd + +OUI:0050C2988* + ID_OUI_FROM_DATABASE=Pantel International + +OUI:0050C2989* + ID_OUI_FROM_DATABASE=Psigenics Corporation + +OUI:0050C298A* + ID_OUI_FROM_DATABASE=MEV Limited + +OUI:0050C298B* + ID_OUI_FROM_DATABASE=TI2000 TECNOLOGIA INFORMATICA 2000 + +OUI:0050C298C* + ID_OUI_FROM_DATABASE=MGM-Devices Oy + +OUI:0050C298D* + ID_OUI_FROM_DATABASE=Mecos Traxler AG + +OUI:0050C298E* + ID_OUI_FROM_DATABASE=Link Technologies, Inc + +OUI:0050C298F* + ID_OUI_FROM_DATABASE=BELIK S.P.R.L. + +OUI:0050C2990* + ID_OUI_FROM_DATABASE=Keith & Koep GmbH + +OUI:0050C2991* + ID_OUI_FROM_DATABASE=UGL Limited + +OUI:0050C2992* + ID_OUI_FROM_DATABASE=IDT Sound Processing Corporation + +OUI:0050C2993* + ID_OUI_FROM_DATABASE=UNETCONVERGENCE CO., LTD + +OUI:0050C2994* + ID_OUI_FROM_DATABASE=Xafax Nederland bv + +OUI:0050C2995* + ID_OUI_FROM_DATABASE=Inter Control Hermann Köhler Elektrik GmbH&Co.KG + +OUI:0050C2996* + ID_OUI_FROM_DATABASE=Commercial Timesharing Inc. + +OUI:0050C2997* + ID_OUI_FROM_DATABASE=Depro Électronique + +OUI:0050C2998* + ID_OUI_FROM_DATABASE=Phytec Messtechnik GmbH + +OUI:0050C2999* + ID_OUI_FROM_DATABASE=Cambustion Ltd + +OUI:0050C299A* + ID_OUI_FROM_DATABASE=Miromico AG + +OUI:0050C299B* + ID_OUI_FROM_DATABASE=Bettini srl + +OUI:0050C299C* + ID_OUI_FROM_DATABASE=CaTs3 Limited + +OUI:0050C299D* + ID_OUI_FROM_DATABASE=Powersense A/S + +OUI:0050C299E* + ID_OUI_FROM_DATABASE=Engage Technologies + +OUI:0050C299F* + ID_OUI_FROM_DATABASE=Sietron Elektronik + +OUI:0050C29A0* + ID_OUI_FROM_DATABASE=Trs Systems, Inc. + +OUI:0050C29A1* + ID_OUI_FROM_DATABASE=ComAp s.r.o + +OUI:0050C29A2* + ID_OUI_FROM_DATABASE=SAMsystems GmbH + +OUI:0050C29A3* + ID_OUI_FROM_DATABASE=Computerwise, Inc. + +OUI:0050C29A4* + ID_OUI_FROM_DATABASE=Entwicklung Hard- & Software + +OUI:0050C29A5* + ID_OUI_FROM_DATABASE=Conolog Corporation + +OUI:0050C29A6* + ID_OUI_FROM_DATABASE=Metodo2 + +OUI:0050C29A7* + ID_OUI_FROM_DATABASE=Thales Communications France + +OUI:0050C29A8* + ID_OUI_FROM_DATABASE=DOMIS SA + +OUI:0050C29A9* + ID_OUI_FROM_DATABASE=General Dynamics C4 Systems + +OUI:0050C29AA* + ID_OUI_FROM_DATABASE=TEKO TELECOM SpA + +OUI:0050C29AB* + ID_OUI_FROM_DATABASE=Electrodata Inc. + +OUI:0050C29AC* + ID_OUI_FROM_DATABASE=Questek Australia Pty Ltd + +OUI:0050C29AD* + ID_OUI_FROM_DATABASE=Chronos Technology Ltd. + +OUI:0050C29AE* + ID_OUI_FROM_DATABASE=Esensors, Inc. + +OUI:0050C29AF* + ID_OUI_FROM_DATABASE=KRESS-NET Krzysztof Rutecki + +OUI:0050C29B0* + ID_OUI_FROM_DATABASE=Ebru GmbH + +OUI:0050C29B1* + ID_OUI_FROM_DATABASE=Bon Hora GmbH + +OUI:0050C29B2* + ID_OUI_FROM_DATABASE=TempSys + +OUI:0050C29B3* + ID_OUI_FROM_DATABASE=Kahler Automation + +OUI:0050C29B4* + ID_OUI_FROM_DATABASE=EUKREA ELECTROMATIQUE SARL + +OUI:0050C29B5* + ID_OUI_FROM_DATABASE=Telegamma srl + +OUI:0050C29B6* + ID_OUI_FROM_DATABASE=ACTECH + +OUI:0050C29B7* + ID_OUI_FROM_DATABASE=St. Michael Strategies + +OUI:0050C29B8* + ID_OUI_FROM_DATABASE=Sound Player Systems e.K. + +OUI:0050C29B9* + ID_OUI_FROM_DATABASE=ISA - Intelligent Sensing Anywhere, S.A. + +OUI:0050C29BA* + ID_OUI_FROM_DATABASE=Connor-Winfield + +OUI:0050C29BB* + ID_OUI_FROM_DATABASE=OMICRON electronics GmbH + +OUI:0050C29BC* + ID_OUI_FROM_DATABASE=Vester Elektronik GmbH + +OUI:0050C29BD* + ID_OUI_FROM_DATABASE=Sensitron Semiconductor + +OUI:0050C29BE* + ID_OUI_FROM_DATABASE=Xad Communications Ltd + +OUI:0050C29BF* + ID_OUI_FROM_DATABASE=2N TELEKOMUNIKACE a.s. + +OUI:0050C29C0* + ID_OUI_FROM_DATABASE=Stuyts Engineering Haarlem BV + +OUI:0050C29C1* + ID_OUI_FROM_DATABASE=Tattile srl + +OUI:0050C29C2* + ID_OUI_FROM_DATABASE=Team Enginers + +OUI:0050C29C3* + ID_OUI_FROM_DATABASE=GE Security-Kampro + +OUI:0050C29C4* + ID_OUI_FROM_DATABASE=Vitel Net + +OUI:0050C29C5* + ID_OUI_FROM_DATABASE=Scansonic MI GmbH + +OUI:0050C29C6* + ID_OUI_FROM_DATABASE=Protronic GmbH + +OUI:0050C29C7* + ID_OUI_FROM_DATABASE=Kumera Drives Oy + +OUI:0050C29C8* + ID_OUI_FROM_DATABASE=ethermetrics + +OUI:0050C29C9* + ID_OUI_FROM_DATABASE=LUMINEX Lighting Control Equipment + +OUI:0050C29CA* + ID_OUI_FROM_DATABASE=ESAB-ATAS GmbH + +OUI:0050C29CB* + ID_OUI_FROM_DATABASE=NIS-time GmbH + +OUI:0050C29CC* + ID_OUI_FROM_DATABASE=Hirotech, Inc + +OUI:0050C29CD* + ID_OUI_FROM_DATABASE=Uwe Schneider GmbH + +OUI:0050C29CE* + ID_OUI_FROM_DATABASE=Ronan Engineering + +OUI:0050C29CF* + ID_OUI_FROM_DATABASE=Intuitive Surgical, Inc + +OUI:0050C29D0* + ID_OUI_FROM_DATABASE=J. DITTRICH ELEKTRONIC GmbH & Co. KG + +OUI:0050C29D1* + ID_OUI_FROM_DATABASE=Bladelius Design Group AB + +OUI:0050C29D2* + ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG + +OUI:0050C29D3* + ID_OUI_FROM_DATABASE=Telemetrie Elektronik GmbH + +OUI:0050C29D4* + ID_OUI_FROM_DATABASE=FIRST + +OUI:0050C29D5* + ID_OUI_FROM_DATABASE=Netpower Labs AB + +OUI:0050C29D6* + ID_OUI_FROM_DATABASE=Innovation, Institute, Inc + +OUI:0050C29D7* + ID_OUI_FROM_DATABASE=Melex Inc. + +OUI:0050C29D8* + ID_OUI_FROM_DATABASE=SAMSUNG HEAVY INDUSTRIES CO.,LTD. + +OUI:0050C29D9* + ID_OUI_FROM_DATABASE=CNS Systems, Inc. + +OUI:0050C29DA* + ID_OUI_FROM_DATABASE=NEUTRONIK e.K. + +OUI:0050C29DB* + ID_OUI_FROM_DATABASE=Walter Grotkasten + +OUI:0050C29DC* + ID_OUI_FROM_DATABASE=FTM Marketing Limited + +OUI:0050C29DD* + ID_OUI_FROM_DATABASE=Institut Dr. Foerster + +OUI:0050C29DE* + ID_OUI_FROM_DATABASE=CHAUVIN ARNOUX + +OUI:0050C29DF* + ID_OUI_FROM_DATABASE=CODEC Co., Ltd. + +OUI:0050C29E0* + ID_OUI_FROM_DATABASE=DST Swiss AG + +OUI:0050C29E1* + ID_OUI_FROM_DATABASE=Enreduce Energy Control AB + +OUI:0050C29E2* + ID_OUI_FROM_DATABASE=E-ViEWS SAFETY SYSTEMS, INC + +OUI:0050C29E3* + ID_OUI_FROM_DATABASE=beON Automatenmanagement GmbH + +OUI:0050C29E4* + ID_OUI_FROM_DATABASE=Pyxis Controls WLL + +OUI:0050C29E5* + ID_OUI_FROM_DATABASE=Halliburton Far East Pte Ltd + +OUI:0050C29E6* + ID_OUI_FROM_DATABASE=Kumho Electric, Inc. + +OUI:0050C29E7* + ID_OUI_FROM_DATABASE=DORLET S.A. + +OUI:0050C29E8* + ID_OUI_FROM_DATABASE=Hammock Corporation + +OUI:0050C29E9* + ID_OUI_FROM_DATABASE=Ciemme Sistemi Spa + +OUI:0050C29EA* + ID_OUI_FROM_DATABASE=SISMODULAR - Engenharia, Lda + +OUI:0050C29EB* + ID_OUI_FROM_DATABASE=AFORE Solutions Inc. + +OUI:0050C29EC* + ID_OUI_FROM_DATABASE=Rohde & Schwarz Topex SA + +OUI:0050C29ED* + ID_OUI_FROM_DATABASE=Picell B.V. + +OUI:0050C29EE* + ID_OUI_FROM_DATABASE=Michael Stevens & Partners Ltd + +OUI:0050C29EF* + ID_OUI_FROM_DATABASE=WoKa-Elektronik GmbH + +OUI:0050C29F0* + ID_OUI_FROM_DATABASE=Veracity UK Ltd + +OUI:0050C29F1* + ID_OUI_FROM_DATABASE=IDEAS s.r.l. + +OUI:0050C29F2* + ID_OUI_FROM_DATABASE=Keith & Koep GmbH + +OUI:0050C29F3* + ID_OUI_FROM_DATABASE=Vision Technologies, Inc. + +OUI:0050C29F4* + ID_OUI_FROM_DATABASE=FSR Inc. + +OUI:0050C29F5* + ID_OUI_FROM_DATABASE=Commex Technologies + +OUI:0050C29F6* + ID_OUI_FROM_DATABASE=Ion Sense Inc. + +OUI:0050C29F7* + ID_OUI_FROM_DATABASE=Dave Jones Design + +OUI:0050C29F8* + ID_OUI_FROM_DATABASE=Austco Communication Systems Pty Ltd + +OUI:0050C29F9* + ID_OUI_FROM_DATABASE=ABB Transmission and Distribution Auto Eqip(Xiamen.China) + +OUI:0050C29FA* + ID_OUI_FROM_DATABASE=Teranex A Division of Silicon Optix + +OUI:0050C29FB* + ID_OUI_FROM_DATABASE=Villbau Kft. + +OUI:0050C29FC* + ID_OUI_FROM_DATABASE=ECTEC INC. + +OUI:0050C29FD* + ID_OUI_FROM_DATABASE=Bitt technology-A Ltd. + +OUI:0050C29FE* + ID_OUI_FROM_DATABASE=SPECTRA EMBEDDED SYSTEMS + +OUI:0050C29FF* + ID_OUI_FROM_DATABASE=Humphrey Products + +OUI:0050C2A00* + ID_OUI_FROM_DATABASE=Technovare Systems + +OUI:0050C2A01* + ID_OUI_FROM_DATABASE=Patronics International LTD + +OUI:0050C2A02* + ID_OUI_FROM_DATABASE=Reference, LLC. + +OUI:0050C2A03* + ID_OUI_FROM_DATABASE=EEG Enterprises Inc + +OUI:0050C2A04* + ID_OUI_FROM_DATABASE=TP Radio + +OUI:0050C2A05* + ID_OUI_FROM_DATABASE=Adgil Design Inc. + +OUI:0050C2A06* + ID_OUI_FROM_DATABASE=Cloos Schweisstechnik GmbH + +OUI:0050C2A07* + ID_OUI_FROM_DATABASE=Dynon Instruments + +OUI:0050C2A08* + ID_OUI_FROM_DATABASE=LabJack Corporation + +OUI:0050C2A09* + ID_OUI_FROM_DATABASE=Innovative American Technology + +OUI:0050C2A0A* + ID_OUI_FROM_DATABASE=ACD Elektronik Gmbh + +OUI:0050C2A0B* + ID_OUI_FROM_DATABASE=I.D.S. Ingegneria Dei Sistemi S.p.A. + +OUI:0050C2A0C* + ID_OUI_FROM_DATABASE=Phytec Messtechnik GmbH + +OUI:0050C2A0D* + ID_OUI_FROM_DATABASE=CHARLYROBOT + +OUI:0050C2A0E* + ID_OUI_FROM_DATABASE=Engicam srl + +OUI:0050C2A0F* + ID_OUI_FROM_DATABASE=Visualware Inc + +OUI:0050C2A10* + ID_OUI_FROM_DATABASE=Essential Design & Integration P/L + +OUI:0050C2A11* + ID_OUI_FROM_DATABASE=OJSC Rawenstvo + +OUI:0050C2A12* + ID_OUI_FROM_DATABASE=HCE Engineering S.r.l. + +OUI:0050C2A13* + ID_OUI_FROM_DATABASE=Talyst, Inc. + +OUI:0050C2A14* + ID_OUI_FROM_DATABASE=Elbit Systems of America - Tallahassee Operations + +OUI:0050C2A15* + ID_OUI_FROM_DATABASE=Industrial Computing Ltd + +OUI:0050C2A16* + ID_OUI_FROM_DATABASE=Baudisch Electronic GmbH + +OUI:0050C2A17* + ID_OUI_FROM_DATABASE=Winners Satellite Electronics Corp. + +OUI:0050C2A18* + ID_OUI_FROM_DATABASE=Eoslink + +OUI:0050C2A19* + ID_OUI_FROM_DATABASE=Icon Time Systems + +OUI:0050C2A1A* + ID_OUI_FROM_DATABASE=DDL + +OUI:0050C2A1B* + ID_OUI_FROM_DATABASE=Realtime Systems Ltd. + +OUI:0050C2A1C* + ID_OUI_FROM_DATABASE=Microtechnica + +OUI:0050C2A1D* + ID_OUI_FROM_DATABASE=SAMH Engineering Services + +OUI:0050C2A1E* + ID_OUI_FROM_DATABASE=MAMAC Systems, Inc. + +OUI:0050C2A1F* + ID_OUI_FROM_DATABASE=Flight Data Systems Pty Ltd + +OUI:0050C2A20* + ID_OUI_FROM_DATABASE=Quorum Technologies Ltd + +OUI:0050C2A21* + ID_OUI_FROM_DATABASE=ISAC SRL + +OUI:0050C2A22* + ID_OUI_FROM_DATABASE=Nippon Manufacturing Service Corporation (abbreviated as 'nms') + +OUI:0050C2A23* + ID_OUI_FROM_DATABASE=Agility Mfg, Inc. + +OUI:0050C2A24* + ID_OUI_FROM_DATABASE=GRUPO EPELSA s.l. + +OUI:0050C2A25* + ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG + +OUI:0050C2A26* + ID_OUI_FROM_DATABASE=Preferred Oil, LLC + +OUI:0050C2A27* + ID_OUI_FROM_DATABASE=meconet e. K. + +OUI:0050C2A28* + ID_OUI_FROM_DATABASE=KENDA ELECTRONIC SYSTEMS LIMITED + +OUI:0050C2A29* + ID_OUI_FROM_DATABASE=Luminex Corporation + +OUI:0050C2A2A* + ID_OUI_FROM_DATABASE=Custom Control Concepts + +OUI:0050C2A2B* + ID_OUI_FROM_DATABASE=APRILIA RACING S.R.L. + +OUI:0050C2A2C* + ID_OUI_FROM_DATABASE=KWS-Electronic GmbH + +OUI:0050C2A2D* + ID_OUI_FROM_DATABASE=Inventure Inc. + +OUI:0050C2A2E* + ID_OUI_FROM_DATABASE=Yuyama Mfg. Co., Ltd. + +OUI:0050C2A2F* + ID_OUI_FROM_DATABASE=DragonFly Scientific LLC + +OUI:0050C2A30* + ID_OUI_FROM_DATABASE=D-TA Systems + +OUI:0050C2A31* + ID_OUI_FROM_DATABASE=Coolit Systems, Inc. + +OUI:0050C2A32* + ID_OUI_FROM_DATABASE=Harris Designs of NRV, Inc. + +OUI:0050C2A33* + ID_OUI_FROM_DATABASE=Fuji Firmware + +OUI:0050C2A34* + ID_OUI_FROM_DATABASE=Casabyte Inc. + +OUI:0050C2A35* + ID_OUI_FROM_DATABASE=Appareo Systems, LLC + +OUI:0050C2A36* + ID_OUI_FROM_DATABASE=Shenzhen Shangji electronic Co.Ltd + +OUI:0050C2A37* + ID_OUI_FROM_DATABASE=Software Systems Plus + +OUI:0050C2A38* + ID_OUI_FROM_DATABASE=Tred Displays + +OUI:0050C2A39* + ID_OUI_FROM_DATABASE=Industrial Data Products Ltd + +OUI:0050C2A3A* + ID_OUI_FROM_DATABASE=Telecor Inc. + +OUI:0050C2A3B* + ID_OUI_FROM_DATABASE=IPcontrols GmbH + +OUI:0050C2A3C* + ID_OUI_FROM_DATABASE=Brähler ICS Konferenztechnik AG + +OUI:0050C2A3D* + ID_OUI_FROM_DATABASE=OWANDY + +OUI:0050C2A3E* + ID_OUI_FROM_DATABASE=DUEVI SNC DI MORA E SANTESE + +OUI:0050C2A3F* + ID_OUI_FROM_DATABASE=LHA Systems CC + +OUI:0050C2A40* + ID_OUI_FROM_DATABASE=Mosberger Consulting LLC + +OUI:0050C2A41* + ID_OUI_FROM_DATABASE=Meiryo Denshi Corp. + +OUI:0050C2A42* + ID_OUI_FROM_DATABASE=RealVision Inc. + +OUI:0050C2A43* + ID_OUI_FROM_DATABASE=NKS Co.Ltd. + +OUI:0050C2A44* + ID_OUI_FROM_DATABASE=TORC Technologies + +OUI:0050C2A45* + ID_OUI_FROM_DATABASE=Sofradir-EC + +OUI:0050C2A46* + ID_OUI_FROM_DATABASE=Softronics Ltd. + +OUI:0050C2A47* + ID_OUI_FROM_DATABASE=PRIMETECH ENGINEERING CORP. + +OUI:0050C2A48* + ID_OUI_FROM_DATABASE=Thales Optronics Limited + +OUI:0050C2A49* + ID_OUI_FROM_DATABASE=Wayne Dalton Corp. + +OUI:0050C2A4A* + ID_OUI_FROM_DATABASE=DITRON S.r.l. + +OUI:0050C2A4B* + ID_OUI_FROM_DATABASE=L-3 Communications Mobile-Vision, Inc. + +OUI:0050C2A4C* + ID_OUI_FROM_DATABASE=VasoNova, Inc. + +OUI:0050C2A4D* + ID_OUI_FROM_DATABASE=LevelStar LLC. + +OUI:0050C2A4E* + ID_OUI_FROM_DATABASE=Conduant Corporation + +OUI:0050C2A4F* + ID_OUI_FROM_DATABASE=Deuta GmbH + +OUI:0050C2A50* + ID_OUI_FROM_DATABASE=i-RED Infrarot Systeme GmbH + +OUI:0050C2A51* + ID_OUI_FROM_DATABASE=Y-products co.ltd. + +OUI:0050C2A52* + ID_OUI_FROM_DATABASE=The VON Corporation + +OUI:0050C2A53* + ID_OUI_FROM_DATABASE=Quality & Design + +OUI:0050C2A54* + ID_OUI_FROM_DATABASE=Diamond Point International (Europe) Ltd + +OUI:0050C2A55* + ID_OUI_FROM_DATABASE=Arrowvale Electronics + +OUI:0050C2A56* + ID_OUI_FROM_DATABASE=ReaMetrix, Inc. + +OUI:0050C2A57* + ID_OUI_FROM_DATABASE=Juice Technologies, LLC + +OUI:0050C2A58* + ID_OUI_FROM_DATABASE=EPL + +OUI:0050C2A59* + ID_OUI_FROM_DATABASE=GSP Sprachtechnologie GmbH + +OUI:0050C2A5A* + ID_OUI_FROM_DATABASE=ITAS A/S + +OUI:0050C2A5B* + ID_OUI_FROM_DATABASE=Phytec Messtechnik GmbH + +OUI:0050C2A5C* + ID_OUI_FROM_DATABASE=JSC "Component-ASU" + +OUI:0050C2A5D* + ID_OUI_FROM_DATABASE=MECC CO., LTD. + +OUI:0050C2A5E* + ID_OUI_FROM_DATABASE=Ansen Investment Holdings Ltd. + +OUI:0050C2A5F* + ID_OUI_FROM_DATABASE=Alga Microwave Inc + +OUI:0050C2A60* + ID_OUI_FROM_DATABASE=Arrow Central Europe GmbH - Division Spoerle + +OUI:0050C2A61* + ID_OUI_FROM_DATABASE=Fr. Sauter AG + +OUI:0050C2A62* + ID_OUI_FROM_DATABASE=Grossenbacher Systeme AG + +OUI:0050C2A63* + ID_OUI_FROM_DATABASE=EMS Industries + +OUI:0050C2A64* + ID_OUI_FROM_DATABASE=tetronik GmbH AEN + +OUI:0050C2A65* + ID_OUI_FROM_DATABASE=Mark-O-Print GmbH + +OUI:0050C2A66* + ID_OUI_FROM_DATABASE=DVTech + +OUI:0050C2A67* + ID_OUI_FROM_DATABASE=GSS Avionics Limited + +OUI:0050C2A68* + ID_OUI_FROM_DATABASE=X-Pert Paint Mixing Systems + +OUI:0050C2A69* + ID_OUI_FROM_DATABASE=Advanced Integrated Systems + +OUI:0050C2A6A* + ID_OUI_FROM_DATABASE=Infocrossing + +OUI:0050C2A6B* + ID_OUI_FROM_DATABASE=Explorer Inc. + +OUI:0050C2A6C* + ID_OUI_FROM_DATABASE=Figment Design Laboratories + +OUI:0050C2A6D* + ID_OUI_FROM_DATABASE=DTV Innovations + +OUI:0050C2A6E* + ID_OUI_FROM_DATABASE=Screen Technics Pty Limited + +OUI:0050C2A6F* + ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG + +OUI:0050C2A70* + ID_OUI_FROM_DATABASE=Reliable System Services Corp + +OUI:0050C2A71* + ID_OUI_FROM_DATABASE=Purite Ltd + +OUI:0050C2A72* + ID_OUI_FROM_DATABASE=Gamber-Johnson LLC. + +OUI:0050C2A73* + ID_OUI_FROM_DATABASE=KYOEI ENGINEERING Co.,Ltd. + +OUI:0050C2A74* + ID_OUI_FROM_DATABASE=DSP DESIGN LTD + +OUI:0050C2A75* + ID_OUI_FROM_DATABASE=JTL Systems Ltd. + +OUI:0050C2A76* + ID_OUI_FROM_DATABASE=Roesch & Walter Industrie-Elektronik GmbH + +OUI:0050C2A77* + ID_OUI_FROM_DATABASE=Keith & Koep GmbH + +OUI:0050C2A78* + ID_OUI_FROM_DATABASE=Apantac LLC + +OUI:0050C2A79* + ID_OUI_FROM_DATABASE=Saintronic + +OUI:0050C2A7A* + ID_OUI_FROM_DATABASE=DetNet South Africa PTY (LTD) + +OUI:0050C2A7B* + ID_OUI_FROM_DATABASE=Orange Tree Technologies + +OUI:0050C2A7C* + ID_OUI_FROM_DATABASE=Pneu-Logic Corporation + +OUI:0050C2A7D* + ID_OUI_FROM_DATABASE=Vitel Net + +OUI:0050C2A7E* + ID_OUI_FROM_DATABASE=Independent Project Engineering Ltd + +OUI:0050C2A7F* + ID_OUI_FROM_DATABASE=Phytec Messtechnik GmbH + +OUI:0050C2A80* + ID_OUI_FROM_DATABASE=ARD SA + +OUI:0050C2A81* + ID_OUI_FROM_DATABASE=BPC circuits Ltd + +OUI:0050C2A82* + ID_OUI_FROM_DATABASE=CT Company + +OUI:0050C2A83* + ID_OUI_FROM_DATABASE=Techno Sobi Co. Ltd. + +OUI:0050C2A84* + ID_OUI_FROM_DATABASE=Lino Manfrotto +Co spa + +OUI:0050C2A85* + ID_OUI_FROM_DATABASE=JOYSYSTEM + +OUI:0050C2A86* + ID_OUI_FROM_DATABASE=LIMAB AB + +OUI:0050C2A87* + ID_OUI_FROM_DATABASE=Littlemore Scientific + +OUI:0050C2A88* + ID_OUI_FROM_DATABASE=S-SYS + +OUI:0050C2A89* + ID_OUI_FROM_DATABASE=CA Traffic Ltd + +OUI:0050C2A8A* + ID_OUI_FROM_DATABASE=Audio Engineering Ltd. + +OUI:0050C2A8B* + ID_OUI_FROM_DATABASE=Navicron Oy + +OUI:0050C2A8C* + ID_OUI_FROM_DATABASE=Redwire, LLC + +OUI:0050C2A8D* + ID_OUI_FROM_DATABASE=Frontier Electronic Systems Corp. + +OUI:0050C2A8E* + ID_OUI_FROM_DATABASE=BFI Industrie-Elektronik GmbH & Co.KG + +OUI:0050C2A8F* + ID_OUI_FROM_DATABASE=Quantum3D, Inc. + +OUI:0050C2A90* + ID_OUI_FROM_DATABASE=S.two Corporation + +OUI:0050C2A91* + ID_OUI_FROM_DATABASE=Ceron Tech Co.,LTD + +OUI:0050C2A92* + ID_OUI_FROM_DATABASE=Sicon s.r.l. + +OUI:0050C2A93* + ID_OUI_FROM_DATABASE=SPX Dehydration & Filtration + +OUI:0050C2A94* + ID_OUI_FROM_DATABASE=Par-Tech, Inc. + +OUI:0050C2A95* + ID_OUI_FROM_DATABASE=INNOVACIONES Microelectrónicas SL (AnaFocus) + +OUI:0050C2A96* + ID_OUI_FROM_DATABASE=FEP SRL + +OUI:0050C2A97* + ID_OUI_FROM_DATABASE=MICROSYSTEMES + +OUI:0050C2A98* + ID_OUI_FROM_DATABASE=Sentry 360 Security + +OUI:0050C2A99* + ID_OUI_FROM_DATABASE=Haivision Systems Inc + +OUI:0050C2A9A* + ID_OUI_FROM_DATABASE=Absolutron. LLC + +OUI:0050C2A9B* + ID_OUI_FROM_DATABASE=PDQ Manufacturing Inc. + +OUI:0050C2A9C* + ID_OUI_FROM_DATABASE=Eberspächer Electronics GmbH & Co. KG + +OUI:0050C2A9D* + ID_OUI_FROM_DATABASE=Joehl & Koeferli AG + +OUI:0050C2A9E* + ID_OUI_FROM_DATABASE=Procon Engineering Limited + +OUI:0050C2A9F* + ID_OUI_FROM_DATABASE=YellowSoft Co., Ltd. + +OUI:0050C2AA0* + ID_OUI_FROM_DATABASE=Smith Meter, Inc. + +OUI:0050C2AA1* + ID_OUI_FROM_DATABASE=ELREM ELECTRONIC AG + +OUI:0050C2AA2* + ID_OUI_FROM_DATABASE=ELPA sas + +OUI:0050C2AA3* + ID_OUI_FROM_DATABASE=Peek Traffic/US Traffic + +OUI:0050C2AA4* + ID_OUI_FROM_DATABASE=PSi Printer Systems international GmbH + +OUI:0050C2AA5* + ID_OUI_FROM_DATABASE=Tampere University of Technology + +OUI:0050C2AA6* + ID_OUI_FROM_DATABASE=Bassett Electronic Systems ltd + +OUI:0050C2AA7* + ID_OUI_FROM_DATABASE=Endeas Oy + +OUI:0050C2AA8* + ID_OUI_FROM_DATABASE=Nexans Cabling Solutions + +OUI:0050C2AA9* + ID_OUI_FROM_DATABASE=SAN GIORGIO S.E.I.N. srl + +OUI:0050C2AAA* + ID_OUI_FROM_DATABASE=Flexible Picture Systems + +OUI:0050C2AAB* + ID_OUI_FROM_DATABASE=BRS Sistemas Eletrônicos + +OUI:0050C2AAC* + ID_OUI_FROM_DATABASE=VisiCon GmbH + +OUI:0050C2AAD* + ID_OUI_FROM_DATABASE=Update Systems Inc. + +OUI:0050C2AAE* + ID_OUI_FROM_DATABASE=OUTLINE srl + +OUI:0050C2AAF* + ID_OUI_FROM_DATABASE=Santa Barbara Instrument Group + +OUI:0050C2AB0* + ID_OUI_FROM_DATABASE=FRAKO Kondensatoren- und Anlagenbau GmbH + +OUI:0050C2AB1* + ID_OUI_FROM_DATABASE=Bitmanufaktur GmbH + +OUI:0050C2AB2* + ID_OUI_FROM_DATABASE=ProCom Systems, Inc. + +OUI:0050C2AB3* + ID_OUI_FROM_DATABASE=Compañía de Instrumentacion y control, S.L. + +OUI:0050C2AB4* + ID_OUI_FROM_DATABASE=n3k Informatik GmbH + +OUI:0050C2AB5* + ID_OUI_FROM_DATABASE=METTLER-TOLEDO HI-SPEED + +OUI:0050C2AB6* + ID_OUI_FROM_DATABASE=Gygax Embedded Engineering GEE.ch + +OUI:0050C2AB7* + ID_OUI_FROM_DATABASE=Twinfalls Technologies + +OUI:0050C2AB8* + ID_OUI_FROM_DATABASE=AHM Limited (CLiKAPAD) + +OUI:0050C2AB9* + ID_OUI_FROM_DATABASE=Showtacle + +OUI:0050C2ABA* + ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG + +OUI:0050C2ABB* + ID_OUI_FROM_DATABASE=Volantic AB + +OUI:0050C2ABC* + ID_OUI_FROM_DATABASE=Barrick + +OUI:0050C2ABD* + ID_OUI_FROM_DATABASE=Monitor Business Machines Ltd. + +OUI:0050C2ABE* + ID_OUI_FROM_DATABASE=AP Labs + +OUI:0050C2ABF* + ID_OUI_FROM_DATABASE=MCC Computer Company + +OUI:0050C2AC0* + ID_OUI_FROM_DATABASE=DS PRO Audio Ltda + +OUI:0050C2AC1* + ID_OUI_FROM_DATABASE=DAISHIN-DENSHI Co., Ltd + +OUI:0050C2AC2* + ID_OUI_FROM_DATABASE=OpenXS B.V. + +OUI:0050C2AC3* + ID_OUI_FROM_DATABASE=Diversified Control, Inc. + +OUI:0050C2AC4* + ID_OUI_FROM_DATABASE=Orion Technologies, Inc. + +OUI:0050C2AC5* + ID_OUI_FROM_DATABASE=E-Motion System, Inc. + +OUI:0050C2AC6* + ID_OUI_FROM_DATABASE=Marathon Products, Inc. + +OUI:0050C2AC7* + ID_OUI_FROM_DATABASE=WaveIP + +OUI:0050C2AC8* + ID_OUI_FROM_DATABASE=Palladio Systeme GmbH + +OUI:0050C2AC9* + ID_OUI_FROM_DATABASE=Steinbeis-Transferzentrum Embedded Design und Networking + +OUI:0050C2ACA* + ID_OUI_FROM_DATABASE=Soft & Control Technology s.r.o. + +OUI:0050C2ACB* + ID_OUI_FROM_DATABASE=U-CARE INC. + +OUI:0050C2ACC* + ID_OUI_FROM_DATABASE=StockerYale + +OUI:0050C2ACD* + ID_OUI_FROM_DATABASE=MeshWorks Wireless Oy + +OUI:0050C2ACE* + ID_OUI_FROM_DATABASE=ChronoLogic Pty. Ltd. + +OUI:0050C2ACF* + ID_OUI_FROM_DATABASE=SP Controls, Inc + +OUI:0050C2AD0* + ID_OUI_FROM_DATABASE=Geonautics Australia Pty Ltd + +OUI:0050C2AD1* + ID_OUI_FROM_DATABASE=Phytec Messtechnik GmbH + +OUI:0050C2AD2* + ID_OUI_FROM_DATABASE=Rafael + +OUI:0050C2AD3* + ID_OUI_FROM_DATABASE=Peek Traffic Corporation + +OUI:0050C2AD4* + ID_OUI_FROM_DATABASE=Global Rainmakers Inc. + +OUI:0050C2AD5* + ID_OUI_FROM_DATABASE=Mighty Lube Systematic Lubrication, Inc. + +OUI:0050C2AD6* + ID_OUI_FROM_DATABASE=Unisensor A/S + +OUI:0050C2AD7* + ID_OUI_FROM_DATABASE=Air Monitors Ltd + +OUI:0050C2AD8* + ID_OUI_FROM_DATABASE=Incyma + +OUI:0050C2AD9* + ID_OUI_FROM_DATABASE=elettrondata srl + +OUI:0050C2ADA* + ID_OUI_FROM_DATABASE=Essepie Srl + +OUI:0050C2ADB* + ID_OUI_FROM_DATABASE=GO engineering GmbH + +OUI:0050C2ADC* + ID_OUI_FROM_DATABASE=Synthesechemie Dr. Penth GmbH + +OUI:0050C2ADD* + ID_OUI_FROM_DATABASE=General Dynamics C4 Sysems + +OUI:0050C2ADE* + ID_OUI_FROM_DATABASE=Neoptix Inc. + +OUI:0050C2ADF* + ID_OUI_FROM_DATABASE=Altinex, Inc + +OUI:0050C2AE0* + ID_OUI_FROM_DATABASE=AT4 wireless.S.A + +OUI:0050C2AE1* + ID_OUI_FROM_DATABASE=EVERCARE + +OUI:0050C2AE2* + ID_OUI_FROM_DATABASE=Power Medical Interventions + +OUI:0050C2AE3* + ID_OUI_FROM_DATABASE=PSD + +OUI:0050C2AE4* + ID_OUI_FROM_DATABASE=Advanced Electronic Designs, Inc. + +OUI:0050C2AE5* + ID_OUI_FROM_DATABASE=ABS Gesellschaft f. Automatisierung, Bildverarbeitung und Software mbH + +OUI:0050C2AE6* + ID_OUI_FROM_DATABASE=VECOM USA + +OUI:0050C2AE7* + ID_OUI_FROM_DATABASE=Redwood Systems + +OUI:0050C2AE8* + ID_OUI_FROM_DATABASE=Bit-Lab PTY LTD + +OUI:0050C2AE9* + ID_OUI_FROM_DATABASE=ClearCorp Enterprises, Inc + +OUI:0050C2AEA* + ID_OUI_FROM_DATABASE=EMBEDIA + +OUI:0050C2AEB* + ID_OUI_FROM_DATABASE=UMLogics Corporation + +OUI:0050C2AEC* + ID_OUI_FROM_DATABASE=Fritz Pauker Ingenieure GmbH + +OUI:0050C2AED* + ID_OUI_FROM_DATABASE=3Roam + +OUI:0050C2AEE* + ID_OUI_FROM_DATABASE=IPtec, Inc. + +OUI:0050C2AEF* + ID_OUI_FROM_DATABASE=National CineMedia + +OUI:0050C2AF0* + ID_OUI_FROM_DATABASE=Fr. Sauter AG + +OUI:0050C2AF1* + ID_OUI_FROM_DATABASE=Green Goose + +OUI:0050C2AF2* + ID_OUI_FROM_DATABASE=ACD Elektronik Gmbh + +OUI:0050C2AF3* + ID_OUI_FROM_DATABASE=Palomar Products, Inc. + +OUI:0050C2AF4* + ID_OUI_FROM_DATABASE=Dixell S.p.A. + +OUI:0050C2AF5* + ID_OUI_FROM_DATABASE=Kramara s.r.o. + +OUI:0050C2AF6* + ID_OUI_FROM_DATABASE=Energid + +OUI:0050C2AF7* + ID_OUI_FROM_DATABASE=Midwest Microwave Solutions Inc. + +OUI:0050C2AF8* + ID_OUI_FROM_DATABASE=Global Satellite Engineering + +OUI:0050C2AF9* + ID_OUI_FROM_DATABASE=Ingenieurbuero Bickele und Buehler GmbH + +OUI:0050C2AFA* + ID_OUI_FROM_DATABASE=Absolute Fire Solutions Inc. + +OUI:0050C2AFC* + ID_OUI_FROM_DATABASE=Odus Technologies SA + +OUI:0050C2AFD* + ID_OUI_FROM_DATABASE=HomeScenario, Inc. + +OUI:0050C2AFE* + ID_OUI_FROM_DATABASE=Trolex Limited + +OUI:0050C2AFF* + ID_OUI_FROM_DATABASE=XoByte LLC + +OUI:0050C2B00* + ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG + +OUI:0050C2B01* + ID_OUI_FROM_DATABASE=HSR Harald L. Reuter + +OUI:0050C2B02* + ID_OUI_FROM_DATABASE=MASTER CO LTD + +OUI:0050C2B03* + ID_OUI_FROM_DATABASE=Spider Tecnologia Ind. e Com. Ltda. + +OUI:0050C2B04* + ID_OUI_FROM_DATABASE=Ubiquiti Networks + +OUI:0050C2B05* + ID_OUI_FROM_DATABASE=POLA s.r.l. + +OUI:0050C2B06* + ID_OUI_FROM_DATABASE=CompuDesigns, Inc. + +OUI:0050C2B07* + ID_OUI_FROM_DATABASE=FARECO + +OUI:0050C2B08* + ID_OUI_FROM_DATABASE=Goerlitz AG + +OUI:0050C2B09* + ID_OUI_FROM_DATABASE=Harper Chalice Group Limited + +OUI:0050C2B0A* + ID_OUI_FROM_DATABASE=Indutherm Giesstechnologie GmbH + +OUI:0050C2B0B* + ID_OUI_FROM_DATABASE=Honeywell + +OUI:0050C2B0C* + ID_OUI_FROM_DATABASE=SMARTB TECHNOLOGIES + +OUI:0050C2B0D* + ID_OUI_FROM_DATABASE=Japan Electronics System, Inc + +OUI:0050C2B0E* + ID_OUI_FROM_DATABASE=KYAB Lulea AB + +OUI:0050C2B0F* + ID_OUI_FROM_DATABASE=NARA Controls Inc. + +OUI:0050C2B10* + ID_OUI_FROM_DATABASE=Marine Entertainment Systems Ltd + +OUI:0050C2B11* + ID_OUI_FROM_DATABASE=EXEL s.r.l + +OUI:0050C2B12* + ID_OUI_FROM_DATABASE=CM Elektronik GmbH + +OUI:0050C2B13* + ID_OUI_FROM_DATABASE=Measy Electronics Co., Ltd. + +OUI:0050C2B14* + ID_OUI_FROM_DATABASE=Keith & Koep GmbH + +OUI:0050C2B15* + ID_OUI_FROM_DATABASE=PhotoTelesis LP + +OUI:0050C2B16* + ID_OUI_FROM_DATABASE=Neothings, Inc. + +OUI:0050C2B17* + ID_OUI_FROM_DATABASE=Elcoteq Design Center Oy + +OUI:0050C2B18* + ID_OUI_FROM_DATABASE=Rosslare Enterprises Limited + +OUI:0050C2B19* + ID_OUI_FROM_DATABASE=Polytron Corporation + +OUI:0050C2B1A* + ID_OUI_FROM_DATABASE=ELCUS + +OUI:0050C2B1B* + ID_OUI_FROM_DATABASE=Integrated Control Corp. + +OUI:0050C2B1C* + ID_OUI_FROM_DATABASE=Phytec Messtechnik GmbH + +OUI:0050C2B1D* + ID_OUI_FROM_DATABASE=Telegenix + +OUI:0050C2B1E* + ID_OUI_FROM_DATABASE=Abbott Medical Optics + +OUI:0050C2B1F* + ID_OUI_FROM_DATABASE=SCA Schucker GmbH & Co. + +OUI:0050C2B20* + ID_OUI_FROM_DATABASE=FIVE9 NETWORK SYSTEMS LLC + +OUI:0050C2B21* + ID_OUI_FROM_DATABASE=Phytron-Elektronik GmbH + +OUI:0050C2B22* + ID_OUI_FROM_DATABASE=FarSite Communications Limited + +OUI:0050C2B23* + ID_OUI_FROM_DATABASE=7 Marsyas Development a.s. + +OUI:0050C2B24* + ID_OUI_FROM_DATABASE=Teledyne Defence Limited + +OUI:0050C2B25* + ID_OUI_FROM_DATABASE=Triax A/S + +OUI:0050C2B26* + ID_OUI_FROM_DATABASE=Elko Systems + +OUI:0050C2B27* + ID_OUI_FROM_DATABASE=ATEME + +OUI:0050C2B28* + ID_OUI_FROM_DATABASE=Micromax Pty. Ltd. + +OUI:0050C2B29* + ID_OUI_FROM_DATABASE=Integra LifeSciences (Ireland) Ltd + +OUI:0050C2B2A* + ID_OUI_FROM_DATABASE=Trench Austria GmbH + +OUI:0050C2B2B* + ID_OUI_FROM_DATABASE=CosmoData Informatica Ltda. + +OUI:0050C2B2C* + ID_OUI_FROM_DATABASE=Concepteers, LLC + +OUI:0050C2B2D* + ID_OUI_FROM_DATABASE=Datasat Digital Entertainment + +OUI:0050C2B2E* + ID_OUI_FROM_DATABASE=ACT + +OUI:0050C2B2F* + ID_OUI_FROM_DATABASE=IntelliVision Technologies, Corp + +OUI:0050C2B30* + ID_OUI_FROM_DATABASE=Applied Micro Electronics "AME" BV + +OUI:0050C2B31* + ID_OUI_FROM_DATABASE=Shop Safe AG + +OUI:0050C2B32* + ID_OUI_FROM_DATABASE=Byres Security Inc + +OUI:0050C2B33* + ID_OUI_FROM_DATABASE=Numcore Ltd + +OUI:0050C2B34* + ID_OUI_FROM_DATABASE=Meisol co.,ltd + +OUI:0050C2B35* + ID_OUI_FROM_DATABASE=haneron + +OUI:0050C2B36* + ID_OUI_FROM_DATABASE=CRDE + +OUI:0050C2B37* + ID_OUI_FROM_DATABASE=IAdea Corporation + +OUI:0050C2B38* + ID_OUI_FROM_DATABASE=Grenmore Ltd + +OUI:0050C2B39* + ID_OUI_FROM_DATABASE=siXis, Inc. + +OUI:0050C2B3A* + ID_OUI_FROM_DATABASE=Nikon Systems Inc. + +OUI:0050C2B3B* + ID_OUI_FROM_DATABASE=Sportvision Inc. + +OUI:0050C2B3C* + ID_OUI_FROM_DATABASE=JanasCard + +OUI:0050C2B3D* + ID_OUI_FROM_DATABASE=AMS + +OUI:0050C2B3E* + ID_OUI_FROM_DATABASE=Sage Consultants + +OUI:0050C2B3F* + ID_OUI_FROM_DATABASE=M-Tronic Design and Technology GmbH + +OUI:0050C2B40* + ID_OUI_FROM_DATABASE=Tecnint HTE SRL + +OUI:0050C2B41* + ID_OUI_FROM_DATABASE=Tata Power Company, Strategic Electronics Division + +OUI:0050C2B42* + ID_OUI_FROM_DATABASE=ETM Electromatic Incorporated + +OUI:0050C2B43* + ID_OUI_FROM_DATABASE=J-Systems Inc. + +OUI:0050C2B44* + ID_OUI_FROM_DATABASE=Ampcontrol Pty Ltd + +OUI:0050C2B45* + ID_OUI_FROM_DATABASE=Efftronics Systems (P) Ltd + +OUI:0050C2B46* + ID_OUI_FROM_DATABASE=Mobileye + +OUI:0050C2B47* + ID_OUI_FROM_DATABASE=MCS MICRONIC Computer Systeme GmbH + +OUI:0050C2B48* + ID_OUI_FROM_DATABASE=MTD GmbH + +OUI:0050C2B49* + ID_OUI_FROM_DATABASE=Aplex Technology Inc. + +OUI:0050C2B4A* + ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG + +OUI:0050C2B4B* + ID_OUI_FROM_DATABASE=Chitose Co.,Ltd + +OUI:0050C2B4C* + ID_OUI_FROM_DATABASE=ElectroCom + +OUI:0050C2B4D* + ID_OUI_FROM_DATABASE=Troll Systems Corporation + +OUI:0050C2B4E* + ID_OUI_FROM_DATABASE=AixControl GmbH + +OUI:0050C2B4F* + ID_OUI_FROM_DATABASE=Sencon UK Ltd. + +OUI:0050C2B50* + ID_OUI_FROM_DATABASE=SELCO + +OUI:0050C2B51* + ID_OUI_FROM_DATABASE=Aeroflex GmbH + +OUI:0050C2B52* + ID_OUI_FROM_DATABASE=SMH Technologies + +OUI:0050C2B53* + ID_OUI_FROM_DATABASE=Prodco + +OUI:0050C2B54* + ID_OUI_FROM_DATABASE=APG Cash Drawer, LLC + +OUI:0050C2B55* + ID_OUI_FROM_DATABASE=SANYO ELECTRONIC INDUSTRIES CO.,LTD + +OUI:0050C2B56* + ID_OUI_FROM_DATABASE=SINOVIA SA + +OUI:0050C2B57* + ID_OUI_FROM_DATABASE=Phytec Messtechnik GmbH + +OUI:0050C2B58* + ID_OUI_FROM_DATABASE=Real D + +OUI:0050C2B59* + ID_OUI_FROM_DATABASE=SLICAN sp. z o.o. + +OUI:0050C2B5A* + ID_OUI_FROM_DATABASE=GREEN Center s.r.o. + +OUI:0050C2B5B* + ID_OUI_FROM_DATABASE=Timberline Mfg Company + +OUI:0050C2B5C* + ID_OUI_FROM_DATABASE=ADI Video Technologies + +OUI:0050C2B5D* + ID_OUI_FROM_DATABASE=Plitron Manufacturing Inc. + +OUI:0050C2B5E* + ID_OUI_FROM_DATABASE=Palgiken Co.,Ltd. + +OUI:0050C2B5F* + ID_OUI_FROM_DATABASE=North Bridge Technologies + +OUI:0050C2B60* + ID_OUI_FROM_DATABASE=OOO NPF ATIS + +OUI:0050C2B61* + ID_OUI_FROM_DATABASE=Nayos LTD + +OUI:0050C2B62* + ID_OUI_FROM_DATABASE=Measurement Technology NW + +OUI:0050C2B63* + ID_OUI_FROM_DATABASE=RO.VE.R. Laboratories S.p.A + +OUI:0050C2B64* + ID_OUI_FROM_DATABASE=FEW Bauer GmbH + +OUI:0050C2B65* + ID_OUI_FROM_DATABASE=Peek Traffic Corporation + +OUI:0050C2B66* + ID_OUI_FROM_DATABASE=Deuta-Werke GmbH + +OUI:0050C2B67* + ID_OUI_FROM_DATABASE=RC Systems Co. Inc. + +OUI:0050C2B68* + ID_OUI_FROM_DATABASE=Electronic Systems Protection, Inc. + +OUI:0050C2B69* + ID_OUI_FROM_DATABASE=Thetis S.p.A. + +OUI:0050C2B6A* + ID_OUI_FROM_DATABASE=Phytec Messtechnik GmbH + +OUI:0050C2B6B* + ID_OUI_FROM_DATABASE=Phytec Messtechnik GmbH + +OUI:0050C2B6C* + ID_OUI_FROM_DATABASE=Drinelec + +OUI:0050C2B6D* + ID_OUI_FROM_DATABASE=Sound Metrics Corp + +OUI:0050C2B6F* + ID_OUI_FROM_DATABASE=CT Company + +OUI:0050C2B70* + ID_OUI_FROM_DATABASE=Nisshin Electronics co.,ltd. + +OUI:0050C2B71* + ID_OUI_FROM_DATABASE=Digitale Analoge COMponenten West Electronic Vertriebs GmbH + +OUI:0050C2B72* + ID_OUI_FROM_DATABASE=Advanced Desktop Systems Ltd + +OUI:0050C2B73* + ID_OUI_FROM_DATABASE=ARKRAY, Inc. + +OUI:0050C2B74* + ID_OUI_FROM_DATABASE=AXED Jakubowski Wojciechowski sp.j. + +OUI:0050C2B75* + ID_OUI_FROM_DATABASE=Blankom + +OUI:0050C2B76* + ID_OUI_FROM_DATABASE=ITF Fröschl GmbH + +OUI:0050C2B77* + ID_OUI_FROM_DATABASE=KRISTECH + +OUI:0050C2B78* + ID_OUI_FROM_DATABASE=Folink + +OUI:0050C2B79* + ID_OUI_FROM_DATABASE=MITSUYA LABORATORIES INC. + +OUI:0050C2B7A* + ID_OUI_FROM_DATABASE=Schnoor Industrieelektronik GmbH & Co. KG + +OUI:0050C2B7B* + ID_OUI_FROM_DATABASE=QUARTECH CORPORATION + +OUI:0050C2B7C* + ID_OUI_FROM_DATABASE=Bettini srl + +OUI:0050C2B7D* + ID_OUI_FROM_DATABASE=ELETECH Srl + +OUI:0050C2B7E* + ID_OUI_FROM_DATABASE=NARETRENDS + +OUI:0050C2B7F* + ID_OUI_FROM_DATABASE=Enatel + +OUI:0050C2B80* + ID_OUI_FROM_DATABASE=iScreen LLC + +OUI:0050C2B81* + ID_OUI_FROM_DATABASE=GHL GmbH & Co.KG + +OUI:0050C2B82* + ID_OUI_FROM_DATABASE=TANABIKI Inc. + +OUI:0050C2B83* + ID_OUI_FROM_DATABASE=Advanced Storage Concepts, Inc. + +OUI:0050C2B84* + ID_OUI_FROM_DATABASE=Innovate Software Solutions Pvt Ltd + +OUI:0050C2B85* + ID_OUI_FROM_DATABASE=SilverNet + +OUI:0050C2B86* + ID_OUI_FROM_DATABASE=ASTO + +OUI:0050C2B87* + ID_OUI_FROM_DATABASE=EMAC, Inc. + +OUI:0050C2B88* + ID_OUI_FROM_DATABASE=GIgatronik Köln GmbH + +OUI:0050C2B89* + ID_OUI_FROM_DATABASE=ENTEC Electric & Electronic Co., LTD. + +OUI:0050C2B8A* + ID_OUI_FROM_DATABASE=MicroPoise + +OUI:0050C2B8B* + ID_OUI_FROM_DATABASE=CSTI BV + +OUI:0050C2B8C* + ID_OUI_FROM_DATABASE=Keith & Koep GmbH + +OUI:0050C2B8D* + ID_OUI_FROM_DATABASE=CEMSI + +OUI:0050C2B8E* + ID_OUI_FROM_DATABASE=WAC (Israel) Ltd. + +OUI:0050C2B8F* + ID_OUI_FROM_DATABASE=Gentec + +OUI:0050C2B90* + ID_OUI_FROM_DATABASE=NAONWORKS Co., Ltd + +OUI:0050C2B91* + ID_OUI_FROM_DATABASE=Finnet-Service Ltd. + +OUI:0050C2B92* + ID_OUI_FROM_DATABASE=ABB Transmission and Distribution Auto Eqip(Xiamen.China) + +OUI:0050C2B93* + ID_OUI_FROM_DATABASE=EMC PARTNER AG + +OUI:0050C2B94* + ID_OUI_FROM_DATABASE=Tritech International Ltd + +OUI:0050C2B95* + ID_OUI_FROM_DATABASE=Rx Monitoring Services + +OUI:0050C2B96* + ID_OUI_FROM_DATABASE=Onix Electronic Systems Inc + +OUI:0050C2B97* + ID_OUI_FROM_DATABASE=ikerlan + +OUI:0050C2B98* + ID_OUI_FROM_DATABASE=Southwest Research Institute + +OUI:0050C2B99* + ID_OUI_FROM_DATABASE=Greenlight Innovation Corp. + +OUI:0050C2B9A* + ID_OUI_FROM_DATABASE=Talo, NV Inc + +OUI:0050C2B9B* + ID_OUI_FROM_DATABASE=Telventy Energia S.A. + +OUI:0050C2B9C* + ID_OUI_FROM_DATABASE=Dave srl + +OUI:0050C2B9D* + ID_OUI_FROM_DATABASE=W. Vershoven GmbH + +OUI:0050C2B9E* + ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG + +OUI:0050C2B9F* + ID_OUI_FROM_DATABASE=AUDIOSCOPE 2K SRL + +OUI:0050C2BA0* + ID_OUI_FROM_DATABASE=txtr GmbH + +OUI:0050C2BA1* + ID_OUI_FROM_DATABASE=Transtechnik GmbH & Co.KG + +OUI:0050C2BA2* + ID_OUI_FROM_DATABASE=Logical Tools s.r.l. + +OUI:0050C2BA3* + ID_OUI_FROM_DATABASE=DSP DESIGN LTD + +OUI:0050C2BA4* + ID_OUI_FROM_DATABASE=CUSTOS MOBILE S.L. + +OUI:0050C2BA5* + ID_OUI_FROM_DATABASE=InterCel Pty Ltd + +OUI:0050C2BA6* + ID_OUI_FROM_DATABASE=Jomitek + +OUI:0050C2BA7* + ID_OUI_FROM_DATABASE=RaumComputer Entwicklungs- und Vertriebs GmbH + +OUI:0050C2BA8* + ID_OUI_FROM_DATABASE=Peek Traffic Corporation + +OUI:0050C2BA9* + ID_OUI_FROM_DATABASE=SISS Technology Inc. + +OUI:0050C2BAA* + ID_OUI_FROM_DATABASE=NetworkFX Communications, LLC + +OUI:0050C2BAB* + ID_OUI_FROM_DATABASE=iDeal Teknoloji Bilisim Cozumleri A.S. + +OUI:0050C2BAC* + ID_OUI_FROM_DATABASE=VITECO VNPT JSC + +OUI:0050C2BAD* + ID_OUI_FROM_DATABASE=Prediktor AS + +OUI:0050C2BAE* + ID_OUI_FROM_DATABASE=Fiber Connections Inc. + +OUI:0050C2BAF* + ID_OUI_FROM_DATABASE=MangoDSP + +OUI:0050C2BB0* + ID_OUI_FROM_DATABASE=Gainbrain + +OUI:0050C2BB1* + ID_OUI_FROM_DATABASE=Pro4tech + +OUI:0050C2BB2* + ID_OUI_FROM_DATABASE=St Michael Strategies Inc + +OUI:0050C2BB3* + ID_OUI_FROM_DATABASE=ClimateWell AB (publ) + +OUI:0050C2BB4* + ID_OUI_FROM_DATABASE=JSC Electrical Equipment Factory + +OUI:0050C2BB5* + ID_OUI_FROM_DATABASE=MROAD INFORMATION SYSTEM + +OUI:0050C2BB6* + ID_OUI_FROM_DATABASE=Quarch Technology Ltd + +OUI:0050C2BB7* + ID_OUI_FROM_DATABASE=General Dynamics C4 Systems + +OUI:0050C2BB8* + ID_OUI_FROM_DATABASE=MoeTronix + +OUI:0050C2BB9* + ID_OUI_FROM_DATABASE=Toptech Systems, Inc. + +OUI:0050C2BBA* + ID_OUI_FROM_DATABASE=Systemteq Limited + +OUI:0050C2BBB* + ID_OUI_FROM_DATABASE=GHL Systems Berhad + +OUI:0050C2BBC* + ID_OUI_FROM_DATABASE=ImpactSystems + +OUI:0050C2BBD* + ID_OUI_FROM_DATABASE=ITS Telecom + +OUI:0050C2BBE* + ID_OUI_FROM_DATABASE=Onlinepizza Norden AB + +OUI:0050C2BBF* + ID_OUI_FROM_DATABASE=Phytec Messtechnik GmbH + +OUI:0050C2BC0* + ID_OUI_FROM_DATABASE=Galaxia Electronics + +OUI:0050C2BC1* + ID_OUI_FROM_DATABASE=Sentec Ltd + +OUI:0050C2BC2* + ID_OUI_FROM_DATABASE=XSLENT Energy Technologies LLC + +OUI:0050C2BC3* + ID_OUI_FROM_DATABASE=Phytec Messtechnik GmbH + +OUI:0050C2BC4* + ID_OUI_FROM_DATABASE=Wheatstone Corporation + +OUI:0050C2BC5* + ID_OUI_FROM_DATABASE=Toptechnology SRL + +OUI:0050C2BC6* + ID_OUI_FROM_DATABASE=MireroTack + +OUI:0050C2BC7* + ID_OUI_FROM_DATABASE=PTS GmbH + +OUI:0050C2BC8* + ID_OUI_FROM_DATABASE=AGWTech Ltd + +OUI:0050C2BC9* + ID_OUI_FROM_DATABASE=Nextmove Technologies + +OUI:0050C2BCA* + ID_OUI_FROM_DATABASE=Aitecsystem Co.,Ltd. + +OUI:0050C2BCB* + ID_OUI_FROM_DATABASE=ARTEIXO TELECOM + +OUI:0050C2BCC* + ID_OUI_FROM_DATABASE=VVDN TECHNOLOGIES PVT. LTD. + +OUI:0050C2BCD* + ID_OUI_FROM_DATABASE=Highlight Parking Systems Ltd + +OUI:0050C2BCE* + ID_OUI_FROM_DATABASE=TV Portal Co., Ltd. + +OUI:0050C2BCF* + ID_OUI_FROM_DATABASE=Epiko, elektronski sistemi d.o.o. + +OUI:0050C2BD0* + ID_OUI_FROM_DATABASE=EDC wifi + +OUI:0050C2BD1* + ID_OUI_FROM_DATABASE=Ariem Technologies Pvt Ltd + +OUI:0050C2BD2* + ID_OUI_FROM_DATABASE=Percello Ltd. + +OUI:0050C2BD3* + ID_OUI_FROM_DATABASE=Postjet Systems Ltd + +OUI:0050C2BD4* + ID_OUI_FROM_DATABASE=Global Security Devices + +OUI:0050C2BD5* + ID_OUI_FROM_DATABASE=RF-Embedded GmbH + +OUI:0050C2BD6* + ID_OUI_FROM_DATABASE=BG Systems, Inc. + +OUI:0050C2BD7* + ID_OUI_FROM_DATABASE=SLAT + +OUI:0050C2BD8* + ID_OUI_FROM_DATABASE=b.a.b-technologie gmbh + +OUI:0050C2BD9* + ID_OUI_FROM_DATABASE=AMS Controls, Inc. + +OUI:0050C2BDA* + ID_OUI_FROM_DATABASE=Digital Lumens + +OUI:0050C2BDB* + ID_OUI_FROM_DATABASE=GasTOPS Ltd. + +OUI:0050C2BDC* + ID_OUI_FROM_DATABASE=SS Systems LLC + +OUI:0050C2BDE* + ID_OUI_FROM_DATABASE=Evo-Teh d.o.o. + +OUI:0050C2BDF* + ID_OUI_FROM_DATABASE=Euro-Konsult Sp. z o.o. + +OUI:0050C2BE0* + ID_OUI_FROM_DATABASE=Phaedrus Limited + +OUI:0050C2BE1* + ID_OUI_FROM_DATABASE=TATTILE SRL + +OUI:0050C2BE2* + ID_OUI_FROM_DATABASE=Convergent Bioscience Ltd. + +OUI:0050C2BE3* + ID_OUI_FROM_DATABASE=Jiskoot Ltd + +OUI:0050C2BE4* + ID_OUI_FROM_DATABASE=GRUPO EPELSA S.L. + +OUI:0050C2BE5* + ID_OUI_FROM_DATABASE=RF Code, Inc + +OUI:0050C2BE6* + ID_OUI_FROM_DATABASE=Docobo Ltd + +OUI:0050C2BE7* + ID_OUI_FROM_DATABASE=Genetec Inc. + +OUI:0050C2BE8* + ID_OUI_FROM_DATABASE=VEHICLE TESTING EQUIPMENT, S.L. + +OUI:0050C2BE9* + ID_OUI_FROM_DATABASE=ZUCCHETTI SPA + +OUI:0050C2BEA* + ID_OUI_FROM_DATABASE=Daeyoung inc. + +OUI:0050C2BEB* + ID_OUI_FROM_DATABASE=Peek Traffic Corporation + +OUI:0050C2BEC* + ID_OUI_FROM_DATABASE=DRS Laruel Technologies + +OUI:0050C2BED* + ID_OUI_FROM_DATABASE=Touch Revolution Inc. + +OUI:0050C2BEF* + ID_OUI_FROM_DATABASE=SOCIEDAD IBERICA DE CONSTRUCCIONES ELECTRICAS, S.A. (SICE) + +OUI:0050C2BF0* + ID_OUI_FROM_DATABASE=AIM + +OUI:0050C2BF1* + ID_OUI_FROM_DATABASE=Amatic Industries GmbH + +OUI:0050C2BF2* + ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG + +OUI:0050C2BF3* + ID_OUI_FROM_DATABASE=Wanco Inc. + +OUI:0050C2BF4* + ID_OUI_FROM_DATABASE=Monarch Innovative Technologies Pvt Ltd + +OUI:0050C2BF5* + ID_OUI_FROM_DATABASE=AILES ELECTRONICS CO., LTD. + +OUI:0050C2BF6* + ID_OUI_FROM_DATABASE=NOLAM EMBEDDED SYSTEMS + +OUI:0050C2BF7* + ID_OUI_FROM_DATABASE=Phytec Messtechnik GmbH + +OUI:0050C2BF8* + ID_OUI_FROM_DATABASE=Crtiical Link + +OUI:0050C2BF9* + ID_OUI_FROM_DATABASE=Vitel Net + +OUI:0050C2BFA* + ID_OUI_FROM_DATABASE=Rohde & Schwarz Topex SA + +OUI:0050C2BFB* + ID_OUI_FROM_DATABASE=ecs srl + +OUI:0050C2BFC* + ID_OUI_FROM_DATABASE=Altronix Corporation + +OUI:0050C2BFD* + ID_OUI_FROM_DATABASE=Ernemann Cine Tec GmbH + +OUI:0050C2BFE* + ID_OUI_FROM_DATABASE=Ingeteam Paneles S.A.U. + +OUI:0050C2BFF* + ID_OUI_FROM_DATABASE=I.S.A. S.r.l. + +OUI:0050C2C00* + ID_OUI_FROM_DATABASE=ACD Elektronik GmbH + +OUI:0050C2C01* + ID_OUI_FROM_DATABASE=QUERCUS TECHNOLOGIES, S.L. + +OUI:0050C2C02* + ID_OUI_FROM_DATABASE=Hanning Elektro-Werke GmbH & Co. KG + +OUI:0050C2C03* + ID_OUI_FROM_DATABASE=Volumatic Limited. + +OUI:0050C2C04* + ID_OUI_FROM_DATABASE=SoGEME + +OUI:0050C2C05* + ID_OUI_FROM_DATABASE=Doppler Systems LLC + +OUI:0050C2C06* + ID_OUI_FROM_DATABASE=ANALOG WAY + +OUI:0050C2C07* + ID_OUI_FROM_DATABASE=CIO Informatique Industrielle + +OUI:0050C2C08* + ID_OUI_FROM_DATABASE=juiceboss + +OUI:0050C2C09* + ID_OUI_FROM_DATABASE=Globe Wireless + +OUI:0050C2C0A* + ID_OUI_FROM_DATABASE=ABB Transmission and Distribution Auto Eqip(Xiamen.China) + +OUI:0050C2C0B* + ID_OUI_FROM_DATABASE=ProSourcing GmbH + +OUI:0050C2C0C* + ID_OUI_FROM_DATABASE=Altierre + +OUI:0050C2C0D* + ID_OUI_FROM_DATABASE=Fr. SauterAG + +OUI:0050C2C0E* + ID_OUI_FROM_DATABASE=AVItronic GmbH + +OUI:0050C2C0F* + ID_OUI_FROM_DATABASE=DYCEC, S.A. + +OUI:0050C2C10* + ID_OUI_FROM_DATABASE=Keith & Koep GmbH + +OUI:0050C2C11* + ID_OUI_FROM_DATABASE=ART Antriebs- und Regeltechnik GmbH + +OUI:0050C2C12* + ID_OUI_FROM_DATABASE=OKI DENKI BOHSAI CO.,LTD. + +OUI:0050C2C13* + ID_OUI_FROM_DATABASE=Dantec Dynamics A/S + +OUI:0050C2C14* + ID_OUI_FROM_DATABASE=Spectronix Corporation + +OUI:0050C2C15* + ID_OUI_FROM_DATABASE=INO - Institut National d'Optique + +OUI:0050C2C16* + ID_OUI_FROM_DATABASE=OMICRON electronics GmbH + +OUI:0050C2C17* + ID_OUI_FROM_DATABASE=Axis-Shield PoC AS + +OUI:0050C2C18* + ID_OUI_FROM_DATABASE=Linuxstamp Designs, LLC + +OUI:0050C2C19* + ID_OUI_FROM_DATABASE=Ibercomp SA + +OUI:0050C2C1A* + ID_OUI_FROM_DATABASE=SAM Co., Ltd. + +OUI:0050C2C1B* + ID_OUI_FROM_DATABASE=Graesslin GmbH + +OUI:0050C2C1C* + ID_OUI_FROM_DATABASE=Becton Dickinson + +OUI:0050C2C1D* + ID_OUI_FROM_DATABASE=Powerbase Energy Systems Inc. + +OUI:0050C2C1E* + ID_OUI_FROM_DATABASE=Peperoni-Light + +OUI:0050C2C1F* + ID_OUI_FROM_DATABASE=Specialist Electronics Services Ltd + +OUI:0050C2C20* + ID_OUI_FROM_DATABASE=SRC Computers, LLC + +OUI:0050C2C22* + ID_OUI_FROM_DATABASE=Audient Ltd + +OUI:0050C2C23* + ID_OUI_FROM_DATABASE=Vidicon LLC + +OUI:0050C2C24* + ID_OUI_FROM_DATABASE=Qualnetics Corporation + +OUI:0050C2C26* + ID_OUI_FROM_DATABASE=Austco Communication Systems Pty Ltd + +OUI:0050C2C27* + ID_OUI_FROM_DATABASE=Qtechnology A/S + +OUI:0050C2C28* + ID_OUI_FROM_DATABASE=ELREHA GmbH + +OUI:0050C2C29* + ID_OUI_FROM_DATABASE=Newtel Engineering S.r.l. + +OUI:0050C2C2A* + ID_OUI_FROM_DATABASE=RealTime Systems Ltd + +OUI:0050C2C2B* + ID_OUI_FROM_DATABASE=Z-App Systems, Inc. + +OUI:0050C2C2C* + ID_OUI_FROM_DATABASE=bach-messtechnik gmbh + +OUI:0050C2C2D* + ID_OUI_FROM_DATABASE=Digitale Analoge COMponenten West Electronic Vertriebs GmbH + +OUI:0050C2C2E* + ID_OUI_FROM_DATABASE=DISMUNTEL SAL + +OUI:0050C2C2F* + ID_OUI_FROM_DATABASE=REFLEX CES + +OUI:0050C2C30* + ID_OUI_FROM_DATABASE=Wagner Group GmbH + +OUI:0050C2C31* + ID_OUI_FROM_DATABASE=4D Technology Corporation + +OUI:0050C2C32* + ID_OUI_FROM_DATABASE=Procon Electronics Pty Ltd + +OUI:0050C2C34* + ID_OUI_FROM_DATABASE=Kyuhen + +OUI:0050C2C35* + ID_OUI_FROM_DATABASE=Insitu, Inc. + +OUI:0050C2C36* + ID_OUI_FROM_DATABASE=SET GmbH + +OUI:0050C2C37* + ID_OUI_FROM_DATABASE=BEAR Solutions (Australasia) Pty Ltd + +OUI:0050C2C38* + ID_OUI_FROM_DATABASE=Computer Automation Technology Inc + +OUI:0050C2C39* + ID_OUI_FROM_DATABASE=SECAD SA + +OUI:0050C2C3A* + ID_OUI_FROM_DATABASE=Sicon s.r.l. + +OUI:0050C2C3B* + ID_OUI_FROM_DATABASE=ELEKTRO-AUTOMATIK GmbH & Co. KG + +OUI:0050C2C3C* + ID_OUI_FROM_DATABASE=ELSIST S.r.l. + +OUI:0050C2C3D* + ID_OUI_FROM_DATABASE=PLA ELECTRO APPLIANCES PVT. LTD. + +OUI:0050C2C3E* + ID_OUI_FROM_DATABASE=Sysacom + +OUI:0050C2C3F* + ID_OUI_FROM_DATABASE=ANXeBusiness Corporation + +OUI:0050C2C40* + ID_OUI_FROM_DATABASE=BAE Systems Bofors AB + +OUI:0050C2C41* + ID_OUI_FROM_DATABASE=COMPRION GmbH + +OUI:0050C2C42* + ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG + +OUI:0050C2C43* + ID_OUI_FROM_DATABASE=Cammegh Limited + +OUI:0050C2C44* + ID_OUI_FROM_DATABASE=Beijing Zhongherongzhi Elec.&Tech.Co.,Ltd. + +OUI:0050C2C45* + ID_OUI_FROM_DATABASE=Galvamat & Unican Technologies SA + +OUI:0050C2C46* + ID_OUI_FROM_DATABASE=QNE GmbH & Co. KG + +OUI:0050C2C47* + ID_OUI_FROM_DATABASE=Weltek Technologies Co. Ltd. + +OUI:0050C2C48* + ID_OUI_FROM_DATABASE=Cytek Media Systems, INC. + +OUI:0050C2C49* + ID_OUI_FROM_DATABASE=Elektronic Thoma GmbH + +OUI:0050C2C4A* + ID_OUI_FROM_DATABASE=Herrick Technology Laboratories, Inc. + +OUI:0050C2C4B* + ID_OUI_FROM_DATABASE=R.V.R. elettronica s.p.a. + +OUI:0050C2C4C* + ID_OUI_FROM_DATABASE=Lancier Monitoring GmbH + +OUI:0050C2C4D* + ID_OUI_FROM_DATABASE=Industrial Automation Systems + +OUI:0050C2C4E* + ID_OUI_FROM_DATABASE=Elaso AG + +OUI:0050C2C4F* + ID_OUI_FROM_DATABASE=Powersense A/S + +OUI:0050C2C50* + ID_OUI_FROM_DATABASE=Beceem Communications, Inc. + +OUI:0050C2C51* + ID_OUI_FROM_DATABASE=InForce Computing, Inc. + +OUI:0050C2C52* + ID_OUI_FROM_DATABASE=Smartfield, Inc. + +OUI:0050C2C53* + ID_OUI_FROM_DATABASE=Eilersen Electric A/S + +OUI:0050C2C54* + ID_OUI_FROM_DATABASE=HPC Platform + +OUI:0050C2C55* + ID_OUI_FROM_DATABASE=Watterott electronic + +OUI:0050C2C56* + ID_OUI_FROM_DATABASE=Spirent Communications + +OUI:0050C2C57* + ID_OUI_FROM_DATABASE=High Speed Design, Inc. + +OUI:0050C2C58* + ID_OUI_FROM_DATABASE=Foerster-Technik GmbH + +OUI:0050C2C59* + ID_OUI_FROM_DATABASE=SKD System AB + +OUI:0050C2C5A* + ID_OUI_FROM_DATABASE=Commotive A/S + +OUI:0050C2C5B* + ID_OUI_FROM_DATABASE=MICRO TECHNICA + +OUI:0050C2C5C* + ID_OUI_FROM_DATABASE=WAVECOM ELEKTRONIK AG + +OUI:0050C2C5D* + ID_OUI_FROM_DATABASE=SweMet AB + +OUI:0050C2C5E* + ID_OUI_FROM_DATABASE=CellPlus technologies, Inc. + +OUI:0050C2C5F* + ID_OUI_FROM_DATABASE=Icon Time Systems + +OUI:0050C2C60* + ID_OUI_FROM_DATABASE=Integration Technologies Limited + +OUI:0050C2C61* + ID_OUI_FROM_DATABASE=HaiVision Systems Incorporated + +OUI:0050C2C62* + ID_OUI_FROM_DATABASE=Zeus Systems Private Limited + +OUI:0050C2C63* + ID_OUI_FROM_DATABASE=Potter Electric Signal Company + +OUI:0050C2C64* + ID_OUI_FROM_DATABASE=Pal Software Service Co.,Ltd. + +OUI:0050C2C65* + ID_OUI_FROM_DATABASE=Micro I/O Servicos de Electronica, Lda + +OUI:0050C2C66* + ID_OUI_FROM_DATABASE=KS Beschallungstechnik GmbH + +OUI:0050C2C67* + ID_OUI_FROM_DATABASE=Practical Control Ltd + +OUI:0050C2C68* + ID_OUI_FROM_DATABASE=Broadsoft PacketSmart, Inc. + +OUI:0050C2C69* + ID_OUI_FROM_DATABASE=REBO CO.,LTD. + +OUI:0050C2C6A* + ID_OUI_FROM_DATABASE=ELECTRONICA KELD + +OUI:0050C2C6B* + ID_OUI_FROM_DATABASE=SiGarden Sp z o.o. + +OUI:0050C2C6C* + ID_OUI_FROM_DATABASE=DORLET S.A. + +OUI:0050C2C6D* + ID_OUI_FROM_DATABASE=Deansoft CO., Ltd. + +OUI:0050C2C6E* + ID_OUI_FROM_DATABASE=TBS Holding AG + +OUI:0050C2C6F* + ID_OUI_FROM_DATABASE=MSB Elektronik und Geraetebau GmbH + +OUI:0050C2C70* + ID_OUI_FROM_DATABASE=Wilke Technology GmbH + +OUI:0050C2C71* + ID_OUI_FROM_DATABASE=Sequoia Technology Group Ltd + +OUI:0050C2C72* + ID_OUI_FROM_DATABASE=Quail + +OUI:0050C2C73* + ID_OUI_FROM_DATABASE=Industry Controls, Inc. + +OUI:0050C2C74* + ID_OUI_FROM_DATABASE=Wapice Ltd. + +OUI:0050C2C75* + ID_OUI_FROM_DATABASE=Rovsing A/S + +OUI:0050C2C76* + ID_OUI_FROM_DATABASE=GridManager A/S + +OUI:0050C2C77* + ID_OUI_FROM_DATABASE=AIM Co.,Ltd + +OUI:0050C2C78* + ID_OUI_FROM_DATABASE=9Solutions Oy + +OUI:0050C2C79* + ID_OUI_FROM_DATABASE=CODESYSTEM Co.,Ltd + +OUI:0050C2C7A* + ID_OUI_FROM_DATABASE=Protonic Holland + +OUI:0050C2C7B* + ID_OUI_FROM_DATABASE=Honeywell + +OUI:0050C2C7C* + ID_OUI_FROM_DATABASE=Scienlab Electronic Systems GmbH + +OUI:0050C2C7D* + ID_OUI_FROM_DATABASE=TAE Antriebstechnik GmbH + +OUI:0050C2C7E* + ID_OUI_FROM_DATABASE=Buerkert Werke GmbH + +OUI:0050C2C7F* + ID_OUI_FROM_DATABASE=Kinects Solutions Inc + +OUI:0050C2C80* + ID_OUI_FROM_DATABASE=Reko-vek + +OUI:0050C2C81* + ID_OUI_FROM_DATABASE=Odyssee Systemes SAS + +OUI:0050C2C82* + ID_OUI_FROM_DATABASE=Kyosha Industries + +OUI:0050C2C83* + ID_OUI_FROM_DATABASE=Gronic Systems GmbH + +OUI:0050C2C84* + ID_OUI_FROM_DATABASE=DOMIS + +OUI:0050C2C85* + ID_OUI_FROM_DATABASE=Peek Traffic Corporation + +OUI:0050C2C86* + ID_OUI_FROM_DATABASE=Bruckner & Jarosch Ingenieurgesellschaft mbH + +OUI:0050C2C87* + ID_OUI_FROM_DATABASE=LECO Corporation + +OUI:0050C2C88* + ID_OUI_FROM_DATABASE=CSI Controles e Sistemas Industriais Ltda. + +OUI:0050C2C89* + ID_OUI_FROM_DATABASE=Creative Micro Design + +OUI:0050C2C8A* + ID_OUI_FROM_DATABASE=Automated Media Services, Inc. + +OUI:0050C2C8B* + ID_OUI_FROM_DATABASE=OCAS AS + +OUI:0050C2C8C* + ID_OUI_FROM_DATABASE=Lanmark Controls Inc. + +OUI:0050C2C8D* + ID_OUI_FROM_DATABASE=Emergency Message Controls LLC + +OUI:0050C2C8E* + ID_OUI_FROM_DATABASE=SDD ITG + +OUI:0050C2C8F* + ID_OUI_FROM_DATABASE=Keith & Koep GmbH + +OUI:0050C2C90* + ID_OUI_FROM_DATABASE=REALD + +OUI:0050C2C91* + ID_OUI_FROM_DATABASE=Media Technologies Ltd. + +OUI:0050C2C92* + ID_OUI_FROM_DATABASE=EMAC, Inc. + +OUI:0050C2C93* + ID_OUI_FROM_DATABASE=SENSAIR Pty Ltd + +OUI:0050C2C94* + ID_OUI_FROM_DATABASE=ISIS ENGINEERING, S.A. + +OUI:0050C2C95* + ID_OUI_FROM_DATABASE=IPSES S.r.l. + +OUI:0050C2C96* + ID_OUI_FROM_DATABASE=CyberCraft + +OUI:0050C2C97* + ID_OUI_FROM_DATABASE=MSTRONIC CO., LTD. + +OUI:0050C2C98* + ID_OUI_FROM_DATABASE=Criticare Systems, Inc + +OUI:0050C2C99* + ID_OUI_FROM_DATABASE=HJPC Corporation dba Pactron + +OUI:0050C2C9A* + ID_OUI_FROM_DATABASE=PACOMP Sp. z o.o. + +OUI:0050C2C9B* + ID_OUI_FROM_DATABASE=Sm electronic co. + +OUI:0050C2C9C* + ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG + +OUI:0050C2C9D* + ID_OUI_FROM_DATABASE=Radius Sweden AB + +OUI:0050C2C9E* + ID_OUI_FROM_DATABASE=Rohde & Schwarz Topex SA + +OUI:0050C2C9F* + ID_OUI_FROM_DATABASE=Etherhome + +OUI:0050C2CA0* + ID_OUI_FROM_DATABASE=Kiefer technic GmbH + +OUI:0050C2CA1* + ID_OUI_FROM_DATABASE=Wayne Kerr Electronics + +OUI:0050C2CA2* + ID_OUI_FROM_DATABASE=The Logical Company + +OUI:0050C2CA3* + ID_OUI_FROM_DATABASE=CT Company + +OUI:0050C2CA4* + ID_OUI_FROM_DATABASE=Vox Technologies + +OUI:0050C2CA5* + ID_OUI_FROM_DATABASE=YOKOWO CO.,LTD + +OUI:0050C2CA6* + ID_OUI_FROM_DATABASE=Vidisys GmbH + +OUI:0050C2CA7* + ID_OUI_FROM_DATABASE=Thermo Fisher Scientific + +OUI:0050C2CA8* + ID_OUI_FROM_DATABASE=Systems With Intelligence Inc. + +OUI:0050C2CA9* + ID_OUI_FROM_DATABASE=Intelligent Devices + +OUI:0050C2CAA* + ID_OUI_FROM_DATABASE=DSP DESIGN LTD + +OUI:0050C2CAB* + ID_OUI_FROM_DATABASE=SAE IT-systems GmbH & Co. KG + +OUI:0050C2CAC* + ID_OUI_FROM_DATABASE=PURVIS Systems Incorporated + +OUI:0050C2CAD* + ID_OUI_FROM_DATABASE=Pacific Coast Engineering + +OUI:0050C2CAE* + ID_OUI_FROM_DATABASE=Campbell Scientific Canada Corp. + +OUI:0050C2CAF* + ID_OUI_FROM_DATABASE=Fr. Sauter AG + +OUI:0050C2CB0* + ID_OUI_FROM_DATABASE=Konsmetal S.A. + +OUI:0050C2CB1* + ID_OUI_FROM_DATABASE=ZK Celltest Inc + +OUI:0050C2CB2* + ID_OUI_FROM_DATABASE=Moravian Instruments + +OUI:0050C2CB3* + ID_OUI_FROM_DATABASE=Deuta-Werke GmbH + +OUI:0050C2CB4* + ID_OUI_FROM_DATABASE=GEA Farm Technologies GmbH + +OUI:0050C2CB6* + ID_OUI_FROM_DATABASE=Krontek Pty Ltd + +OUI:0050C2CB7* + ID_OUI_FROM_DATABASE=inotech GmbH + +OUI:0050C2CB8* + ID_OUI_FROM_DATABASE=Raith GmbH + +OUI:0050C2CB9* + ID_OUI_FROM_DATABASE=Micro Technic A/S + +OUI:0050C2CBA* + ID_OUI_FROM_DATABASE=DELTA TAU DATA SYSTEMS + +OUI:0050C2CBB* + ID_OUI_FROM_DATABASE=Coptonix GmbH + +OUI:0050C2CBC* + ID_OUI_FROM_DATABASE=CP ELETRONICA SA + +OUI:0050C2CBD* + ID_OUI_FROM_DATABASE=Hi Tech Electronics Ltd + +OUI:0050C2CBE* + ID_OUI_FROM_DATABASE=CODE BLUE CORPORATION + +OUI:0050C2CBF* + ID_OUI_FROM_DATABASE=Megacon AB + +OUI:0050C2CC0* + ID_OUI_FROM_DATABASE=World Time Solutions Limited + +OUI:0050C2CC1* + ID_OUI_FROM_DATABASE=Level 3 Communications + +OUI:0050C2CC2* + ID_OUI_FROM_DATABASE=ConectaIP Tecnologia S.L. + +OUI:0050C2CC3* + ID_OUI_FROM_DATABASE=viscount systems inc. + +OUI:0050C2CC4* + ID_OUI_FROM_DATABASE=General Dynamics C4S + +OUI:0050C2CC5* + ID_OUI_FROM_DATABASE=Tecnovum AG + +OUI:0050C2CC6* + ID_OUI_FROM_DATABASE=KDT + +OUI:0050C2CC7* + ID_OUI_FROM_DATABASE=TOPROOT Technology Corp. Ltd., + +OUI:0050C2CC9* + ID_OUI_FROM_DATABASE=Promess GmbH + +OUI:0050C2CCA* + ID_OUI_FROM_DATABASE=SANMINA-SCI SHENZHEN + +OUI:0050C2CCB* + ID_OUI_FROM_DATABASE=CaptiveAire Systems Inc. + +OUI:0050C2CCC* + ID_OUI_FROM_DATABASE=Smartech-technology + +OUI:0050C2CCD* + ID_OUI_FROM_DATABASE=FUJI DATA SYSTEM Co.,Ltd. + +OUI:0050C2CCE* + ID_OUI_FROM_DATABASE=Mac-Gray Corporation + +OUI:0050C2CCF* + ID_OUI_FROM_DATABASE=TASK SISTEMAS DE COMPUTACAO LTDA + +OUI:0050C2CD0* + ID_OUI_FROM_DATABASE=MME Mueller Mikroelektronik + +OUI:0050C2CD1* + ID_OUI_FROM_DATABASE=ACD Elektronik GmbH + +OUI:0050C2CD2* + ID_OUI_FROM_DATABASE=SIM2 Multimedia S.p.A. + +OUI:0050C2CD3* + ID_OUI_FROM_DATABASE=Covidence A/S + +OUI:0050C2CD4* + ID_OUI_FROM_DATABASE=SCHRAML GmbH + +OUI:0050C2CD5* + ID_OUI_FROM_DATABASE=Arcos Technologies Ltd. + +OUI:0050C2CD6* + ID_OUI_FROM_DATABASE=Arktan Systems + +OUI:0050C2CD7* + ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG + +OUI:0050C2CD8* + ID_OUI_FROM_DATABASE=IT-IS International Ltd. + +OUI:0050C2CD9* + ID_OUI_FROM_DATABASE=NDC Infrared Engineering, Inc. + +OUI:0050C2CDA* + ID_OUI_FROM_DATABASE=taskit GmbH + +OUI:0050C2CDB* + ID_OUI_FROM_DATABASE=RUTTER INC + +OUI:0050C2CDC* + ID_OUI_FROM_DATABASE=ABB Transmission and Distribution Auto Eqip(Xiamen.China) + +OUI:0050C2CDD* + ID_OUI_FROM_DATABASE=K.C.C. SHOKAI LIMITED + +OUI:0050C2CDE* + ID_OUI_FROM_DATABASE=Axotec Technologies GmbH + +OUI:0050C2CDF* + ID_OUI_FROM_DATABASE=CoreEL TEchnologies (I) Pvt Ltd + +OUI:0050C2CE0* + ID_OUI_FROM_DATABASE=Industrial Control Links, Inc. + +OUI:0050C2CE1* + ID_OUI_FROM_DATABASE=Satellink Inc. + +OUI:0050C2CE2* + ID_OUI_FROM_DATABASE=Sicon srl + +OUI:0050C2CE3* + ID_OUI_FROM_DATABASE=Industrial Automatics Design Bureau + +OUI:0050C2CE4* + ID_OUI_FROM_DATABASE=TEKTRONIK + +OUI:0050C2CE5* + ID_OUI_FROM_DATABASE=Maretron, LLP + +OUI:0050C2CE6* + ID_OUI_FROM_DATABASE=APLICA TECHNOLOGIES + +OUI:0050C2CE7* + ID_OUI_FROM_DATABASE=Echola Systems + +OUI:0050C2CE8* + ID_OUI_FROM_DATABASE=Thomas & Betts + +OUI:0050C2CEA* + ID_OUI_FROM_DATABASE=Keith & Koep GmbH + +OUI:0050C2CEB* + ID_OUI_FROM_DATABASE=Toyon Research Corporation + +OUI:0050C2CEC* + ID_OUI_FROM_DATABASE=Erhardt+Leimer GmbH + +OUI:0050C2CED* + ID_OUI_FROM_DATABASE=AeroMechanical Services Ltd, FLYHT + +OUI:0050C2CEE* + ID_OUI_FROM_DATABASE=EMBED-IT OG + +OUI:0050C2CEF* + ID_OUI_FROM_DATABASE=Lupatecnologia e Sistemas Ltda + +OUI:0050C2CF0* + ID_OUI_FROM_DATABASE=Inviso B.V. + +OUI:0050C2CF1* + ID_OUI_FROM_DATABASE=TelGaAs, Inc. + +OUI:0050C2CF2* + ID_OUI_FROM_DATABASE=Weiss Robotics GmbH & Co. KG + +OUI:0050C2CF3* + ID_OUI_FROM_DATABASE=Daiken Automacao Ltda + +OUI:0050C2CF4* + ID_OUI_FROM_DATABASE=Baudisch Electronic GmbH + +OUI:0050C2CF5* + ID_OUI_FROM_DATABASE=Aircell + +OUI:0050C2CF6* + ID_OUI_FROM_DATABASE=Epec Oy + +OUI:0050C2CF7* + ID_OUI_FROM_DATABASE=Armour Home Electronics LTD + +OUI:0050C2CF8* + ID_OUI_FROM_DATABASE=beks Kommunikacios Technika kft + +OUI:0050C2CF9* + ID_OUI_FROM_DATABASE=Elbit Systems of America + +OUI:0050C2CFA* + ID_OUI_FROM_DATABASE=GRUPO EPELSA S. L. + +OUI:0050C2CFB* + ID_OUI_FROM_DATABASE=New Embedded Technology + +OUI:0050C2CFC* + ID_OUI_FROM_DATABASE=Tritium Pty Ltd + +OUI:0050C2CFD* + ID_OUI_FROM_DATABASE=AIRFOLC,INC. + +OUI:0050C2CFE* + ID_OUI_FROM_DATABASE=Techleader + +OUI:0050C2CFF* + ID_OUI_FROM_DATABASE=INFRASAFE INCORPORATED + +OUI:0050C2D00* + ID_OUI_FROM_DATABASE=Bodensee Gravitymeter Geosystem GmbH + +OUI:0050C2D01* + ID_OUI_FROM_DATABASE=Aanderaa Data Instruments + +OUI:0050C2D02* + ID_OUI_FROM_DATABASE=SURVALENT TECHNOLOGY CORP + +OUI:0050C2D03* + ID_OUI_FROM_DATABASE=Peekel Instruments B.V. + +OUI:0050C2D04* + ID_OUI_FROM_DATABASE=Tehama Wireless + +OUI:0050C2D06* + ID_OUI_FROM_DATABASE=nCk Research LLC + +OUI:0050C2D07* + ID_OUI_FROM_DATABASE=IAF GmbH + +OUI:0050C2D08* + ID_OUI_FROM_DATABASE=Reimesch Kommunikationssysteme GmbH + +OUI:0050C2D09* + ID_OUI_FROM_DATABASE=Guardtec, Inc. + +OUI:0050C2D0A* + ID_OUI_FROM_DATABASE=Airpoint Co., Ltd. + +OUI:0050C2D0B* + ID_OUI_FROM_DATABASE=CODACO ELECTRONIC s.r.o. + +OUI:0050C2D0C* + ID_OUI_FROM_DATABASE=JVL Industri Elektronik + +OUI:0050C2D0D* + ID_OUI_FROM_DATABASE=DECA Card Engineering GmbH + +OUI:0050C2D0E* + ID_OUI_FROM_DATABASE=Weinert Engineering GmbH + +OUI:0050C2D0F* + ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG + +OUI:0050C2D10* + ID_OUI_FROM_DATABASE=Rosslare Enterprises Ltd. + +OUI:0050C2D11* + ID_OUI_FROM_DATABASE=Aplex Technology Inc. + +OUI:0050C2D12* + ID_OUI_FROM_DATABASE=Tokyo Weld Co.,Ltd. + +OUI:0050C2D13* + ID_OUI_FROM_DATABASE=GUNMA ELECTRONICS CO LTD + +OUI:0050C2D14* + ID_OUI_FROM_DATABASE=SAET I.S. + +OUI:0050C2D15* + ID_OUI_FROM_DATABASE=MSR-Office GmbH + +OUI:0050C2D16* + ID_OUI_FROM_DATABASE=Imricor Medical Systems, Inc. + +OUI:0050C2D17* + ID_OUI_FROM_DATABASE=CUE, a.s. + +OUI:0050C2D18* + ID_OUI_FROM_DATABASE=Glyn GmbH & Co.KG + +OUI:0050C2D19* + ID_OUI_FROM_DATABASE=Applied Medical Technologies, Inc DBA AirClean Systems + +OUI:0050C2D1A* + ID_OUI_FROM_DATABASE=GILLAM-FEI S.A. + +OUI:0050C2D1B* + ID_OUI_FROM_DATABASE=TECHKON GmbH + +OUI:0050C2D1C* + ID_OUI_FROM_DATABASE=Recon Dynamics, LLC + +OUI:0050C2D1D* + ID_OUI_FROM_DATABASE=Moco Media Pty Ltd + +OUI:0050C2D1E* + ID_OUI_FROM_DATABASE=Tobila Systems, Inc. + +OUI:0050C2D1F* + ID_OUI_FROM_DATABASE=Olympus NDT Canada Inc. + +OUI:0050C2D20* + ID_OUI_FROM_DATABASE=7+ Kft + +OUI:0050C2D21* + ID_OUI_FROM_DATABASE=Innovative Circuit Technology + +OUI:0050C2D22* + ID_OUI_FROM_DATABASE=eMDee Technology, Inc. + +OUI:0050C2D23* + ID_OUI_FROM_DATABASE=Bluestone Technology GmbH + +OUI:0050C2D24* + ID_OUI_FROM_DATABASE=Expro North Sea + +OUI:0050C2D25* + ID_OUI_FROM_DATABASE=VAF Instruments BV + +OUI:0050C2D26* + ID_OUI_FROM_DATABASE=RCH + +OUI:0050C2D27* + ID_OUI_FROM_DATABASE=Fr.Sauter AG + +OUI:0050C2D28* + ID_OUI_FROM_DATABASE=Digitale Analoge COMponenten West Electronic Vertriebs GmbH + +OUI:0050C2D29* + ID_OUI_FROM_DATABASE=Axible Technologies + +OUI:0050C2D2A* + ID_OUI_FROM_DATABASE=Millennium Electronics Pty.Ltd. + +OUI:0050C2D2B* + ID_OUI_FROM_DATABASE=Video Tech Laboratories, Inc. + +OUI:0050C2D2C* + ID_OUI_FROM_DATABASE=Schneider Electric Motion USA + +OUI:0050C2D2D* + ID_OUI_FROM_DATABASE=CADI SCIENTIFIC PTE LTD + +OUI:0050C2D2E* + ID_OUI_FROM_DATABASE=RS Gesellschaft fur Informationstechnik mbH & Co KG + +OUI:0050C2D2F* + ID_OUI_FROM_DATABASE=Key Systems, Inc. + +OUI:0050C2D30* + ID_OUI_FROM_DATABASE=ACTIV Financial Systems, Inc. + +OUI:0050C2D31* + ID_OUI_FROM_DATABASE=UNGAVA Technologies Inc. + +OUI:0050C2D32* + ID_OUI_FROM_DATABASE=RealTime Systems Ltd + +OUI:0050C2D33* + ID_OUI_FROM_DATABASE=Maddalena S.p.A + +OUI:0050C2D34* + ID_OUI_FROM_DATABASE=GAON TECH corp. + +OUI:0050C2D35* + ID_OUI_FROM_DATABASE=UG Systems GmbH & Co. KG + +OUI:0050C2D36* + ID_OUI_FROM_DATABASE=Enatel Limited + +OUI:0050C2D37* + ID_OUI_FROM_DATABASE=LJT & Associates, Inc. + +OUI:0050C2D38* + ID_OUI_FROM_DATABASE=Kyowa Electronics Co.,Ltd. + +OUI:0050C2D39* + ID_OUI_FROM_DATABASE=Apex NV + +OUI:0050C2D3A* + ID_OUI_FROM_DATABASE=WellSense Technologies + +OUI:0050C2D3B* + ID_OUI_FROM_DATABASE=Gitsn Inc. + +OUI:0050C2D3C* + ID_OUI_FROM_DATABASE=ASSYSTEM France + +OUI:0050C2D3D* + ID_OUI_FROM_DATABASE=Tellabs Operations Inc. + +OUI:0050C2D3E* + ID_OUI_FROM_DATABASE=Synatec Electronic GmbH + +OUI:0050C2D3F* + ID_OUI_FROM_DATABASE=CSS, LLC + +OUI:0050C2D40* + ID_OUI_FROM_DATABASE=demmel products + +OUI:0050C2D41* + ID_OUI_FROM_DATABASE=AREA ENERGY, INC. + +OUI:0050C2D42* + ID_OUI_FROM_DATABASE=Hagenuk KMT GmbH + +OUI:0050C2D43* + ID_OUI_FROM_DATABASE=DSP4YOU Ltd + +OUI:0050C2D44* + ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG + +OUI:0050C2D45* + ID_OUI_FROM_DATABASE=Technagon GmbH + +OUI:0050C2D46* + ID_OUI_FROM_DATABASE=Thales Nederland BV + +OUI:0050C2D47* + ID_OUI_FROM_DATABASE=Rohde & Schwarz Topex SA + +OUI:0050C2D48* + ID_OUI_FROM_DATABASE=Watermark Estate Management Services, LLC + +OUI:0050C2D49* + ID_OUI_FROM_DATABASE=Smith Meter, Inc + +OUI:0050C2D4A* + ID_OUI_FROM_DATABASE=ATH system + +OUI:0050C2D4B* + ID_OUI_FROM_DATABASE=Indra Australia + +OUI:0050C2D4C* + ID_OUI_FROM_DATABASE=DALOG Diagnosesysteme GmbH + +OUI:0050C2D4D* + ID_OUI_FROM_DATABASE=Yardney Technical Products Inc. + +OUI:0050C2D4E* + ID_OUI_FROM_DATABASE=Keith & Koep GmbH + +OUI:0050C2D4F* + ID_OUI_FROM_DATABASE=SECOM GmbH + +OUI:0050C2D50* + ID_OUI_FROM_DATABASE=Solbrig Electronics, Inc. + +OUI:0050C2D51* + ID_OUI_FROM_DATABASE=BETTINI SRL + +OUI:0050C2D52* + ID_OUI_FROM_DATABASE=F+D Feinwerk- und Drucktechnik GmbH + +OUI:0050C2D53* + ID_OUI_FROM_DATABASE=Telemerkki Oy + +OUI:0050C2D54* + ID_OUI_FROM_DATABASE=ABtrack s.r.l. + +OUI:0050C2D55* + ID_OUI_FROM_DATABASE=Sterna Security + +OUI:0050C2D56* + ID_OUI_FROM_DATABASE=SELEX Communications Limited + +OUI:0050C2D57* + ID_OUI_FROM_DATABASE=Hijikata Denki Corp. + +OUI:0050C2D58* + ID_OUI_FROM_DATABASE=NIK-ELEKTRONIKA Ltd + +OUI:0050C2D59* + ID_OUI_FROM_DATABASE=Buanco System A/S + +OUI:0050C2D5A* + ID_OUI_FROM_DATABASE=Embedded Monitoring Systems Ltd. + +OUI:0050C2D5B* + ID_OUI_FROM_DATABASE=Infinition Inc. + +OUI:0050C2D5C* + ID_OUI_FROM_DATABASE=Ibetor S.L. + +OUI:0050C2D5D* + ID_OUI_FROM_DATABASE=GLOBALCOM ENGINEERING SRL + +OUI:0050C2D5E* + ID_OUI_FROM_DATABASE=infinitec co., ltd. + +OUI:0050C2D5F* + ID_OUI_FROM_DATABASE=Embedded Solution Co., Ltd. + +OUI:0050C2D60* + ID_OUI_FROM_DATABASE=Nihon Kessho Koogaku Co., Ltd. + +OUI:0050C2D61* + ID_OUI_FROM_DATABASE=system2 GmbH + +OUI:0050C2D62* + ID_OUI_FROM_DATABASE=EMAC, Inc. + +OUI:0050C2D63* + ID_OUI_FROM_DATABASE=DATAREGIS S.A. + +OUI:0050C2D64* + ID_OUI_FROM_DATABASE=TV1 GmbH + +OUI:0050C2D65* + ID_OUI_FROM_DATABASE=TX Technology Corp + +OUI:0050C2D66* + ID_OUI_FROM_DATABASE=Uvax Concepts + +OUI:0050C2D67* + ID_OUI_FROM_DATABASE=KLING & FREITAG GmbH + +OUI:0050C2D68* + ID_OUI_FROM_DATABASE=HiSpeed Data, Inc. + +OUI:0050C2D69* + ID_OUI_FROM_DATABASE=GHL Systems Bhd + +OUI:0050C2D6A* + ID_OUI_FROM_DATABASE=A&T Corporation, Electrics Group , LAS R&D Unit, + +OUI:0050C2D6B* + ID_OUI_FROM_DATABASE=Nemec Automation + +OUI:0050C2D6C* + ID_OUI_FROM_DATABASE=ALPHA Corporation + +OUI:0050C2D6D* + ID_OUI_FROM_DATABASE=Pro-Digital + +OUI:0050C2D6E* + ID_OUI_FROM_DATABASE=BC Illumination, Inc. + +OUI:0050C2D6F* + ID_OUI_FROM_DATABASE=Imtron Messtechnik GmbH + +OUI:0050C2D70* + ID_OUI_FROM_DATABASE=C. Rob. Hammerstein GmbH & Co. KG + +OUI:0050C2D71* + ID_OUI_FROM_DATABASE=EMAC, Inc. + +OUI:0050C2D72* + ID_OUI_FROM_DATABASE=Scale-Tron, Inc. + +OUI:0050C2D73* + ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG + +OUI:0050C2D74* + ID_OUI_FROM_DATABASE=Computech International + +OUI:0050C2D75* + ID_OUI_FROM_DATABASE=Collectric AB + +OUI:0050C2D76* + ID_OUI_FROM_DATABASE=Telvent + +OUI:0050C2D77* + ID_OUI_FROM_DATABASE=Fr.SauterAG + +OUI:0050C2D78* + ID_OUI_FROM_DATABASE=P4Q Electronics + +OUI:0050C2D79* + ID_OUI_FROM_DATABASE=DSI RF Systems, Inc. + +OUI:0050C2D7A* + ID_OUI_FROM_DATABASE=Transbit Sp. z o.o. + +OUI:0050C2D7B* + ID_OUI_FROM_DATABASE=OWITA GmbH + +OUI:0050C2D7C* + ID_OUI_FROM_DATABASE=Microcubs Systems Pvt Ltd + +OUI:0050C2D7D* + ID_OUI_FROM_DATABASE=Voltech Instruments + +OUI:0050C2D7E* + ID_OUI_FROM_DATABASE=LYNX Technik AG + +OUI:0050C2D7F* + ID_OUI_FROM_DATABASE=HMI Technologies + +OUI:0050C2D80* + ID_OUI_FROM_DATABASE=Keith & Koep GmbH + +OUI:0050C2D81* + ID_OUI_FROM_DATABASE=TATTILE SRL + +OUI:0050C2D82* + ID_OUI_FROM_DATABASE=Audio Authority Corp + +OUI:0050C2D83* + ID_OUI_FROM_DATABASE=Blankom + +OUI:0050C2D84* + ID_OUI_FROM_DATABASE=ABB Transmission and Distribution Auto Eqip(Xiamen.China) + +OUI:0050C2D85* + ID_OUI_FROM_DATABASE=VITEC + +OUI:0050C2D86* + ID_OUI_FROM_DATABASE=ECOMM ERA + +OUI:0050C2D87* + ID_OUI_FROM_DATABASE=Electrolight Shivuk (1994) Ltd. + +OUI:0050C2D88* + ID_OUI_FROM_DATABASE=T+A elektroakustik GmbH & Co KG + +OUI:0050C2D89* + ID_OUI_FROM_DATABASE=Visual Telecommunication Network, Inc + +OUI:0050C2D8A* + ID_OUI_FROM_DATABASE=OptoLink Industria e Comercio Ltda + +OUI:0050C2D8B* + ID_OUI_FROM_DATABASE=Sicon srl + +OUI:0050C2D8C* + ID_OUI_FROM_DATABASE=iRphotonics + +OUI:0050C2D8D* + ID_OUI_FROM_DATABASE=CS-Instruments + +OUI:0050C2D8E* + ID_OUI_FROM_DATABASE=LSD Science&Technology Co.,Ltd. + +OUI:0050C2D8F* + ID_OUI_FROM_DATABASE=Syes srl + +OUI:0050C2D90* + ID_OUI_FROM_DATABASE=Dumps Electronic + +OUI:0050C2D91* + ID_OUI_FROM_DATABASE=CHAUVIN ARNOUX + +OUI:0050C2D92* + ID_OUI_FROM_DATABASE=Manz + +OUI:0050C2D93* + ID_OUI_FROM_DATABASE=Axlon AB + +OUI:0050C2D94* + ID_OUI_FROM_DATABASE=Software Effect Enterprises, Inc + +OUI:0050C2D95* + ID_OUI_FROM_DATABASE=Honeywell + +OUI:0050C2D96* + ID_OUI_FROM_DATABASE=CONTEC GmbH + +OUI:0050C2D97* + ID_OUI_FROM_DATABASE=ERS electronic GmbH + +OUI:0050C2D98* + ID_OUI_FROM_DATABASE=Rong Shun Xuan Corp. + +OUI:0050C2D99* + ID_OUI_FROM_DATABASE=T-Industry, s.r.o. + +OUI:0050C2D9A* + ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG + +OUI:0050C2D9B* + ID_OUI_FROM_DATABASE=Intuitive Surgical, Inc + +OUI:0050C2D9C* + ID_OUI_FROM_DATABASE=Gamber Johnson LLC + +OUI:0050C2D9D* + ID_OUI_FROM_DATABASE=Mistral Solutions Pvt. Ltd + +OUI:0050C2D9F* + ID_OUI_FROM_DATABASE=BitWise Controls + +OUI:0050C2DA0* + ID_OUI_FROM_DATABASE=Precision Remotes + +OUI:0050C2DA1* + ID_OUI_FROM_DATABASE=MangoDSP + +OUI:0050C2DA2* + ID_OUI_FROM_DATABASE=metraTec GmbH + +OUI:0050C2DA3* + ID_OUI_FROM_DATABASE=GENERAL DYNAMICS C4 SYSTEMS + +OUI:0050C2DA4* + ID_OUI_FROM_DATABASE=Deuta-Werke GmbH + +OUI:0050C2DA5* + ID_OUI_FROM_DATABASE=megatec electronic GmbH + +OUI:0050C2DA6* + ID_OUI_FROM_DATABASE=Manitowoc Ice + +OUI:0050C2DA7* + ID_OUI_FROM_DATABASE=Capton + +OUI:0050C2DA8* + ID_OUI_FROM_DATABASE=Sine Systems, Inc. + +OUI:0050C2DA9* + ID_OUI_FROM_DATABASE=Tieline Research Pty Ltd + +OUI:0050C2DAA* + ID_OUI_FROM_DATABASE=M & PAUL, INC + +OUI:0050C2DAB* + ID_OUI_FROM_DATABASE=Aplex Technology Inc. + +OUI:0050C2DAC* + ID_OUI_FROM_DATABASE=RFL Electronics + +OUI:0050C2DAD* + ID_OUI_FROM_DATABASE=Keith & Koep GmbH + +OUI:0050C2DAE* + ID_OUI_FROM_DATABASE=Spang Power Electronics + +OUI:0050C2DAF* + ID_OUI_FROM_DATABASE=eumig industrie-tv GmbH + +OUI:0050C2DB0* + ID_OUI_FROM_DATABASE=IMAGO Technologies GmbH + +OUI:0050C2DB1* + ID_OUI_FROM_DATABASE=RF Code, Inc + +OUI:0050C2DB2* + ID_OUI_FROM_DATABASE=SoftwareCannery + +OUI:0050C2DB3* + ID_OUI_FROM_DATABASE=LAUDA DR. R. WOBSER GMBH & CO. KG + +OUI:0050C2DB4* + ID_OUI_FROM_DATABASE=ZAO NPC "Kompjuternie Technologii" + +OUI:0050C2DB5* + ID_OUI_FROM_DATABASE=DSP DESIGN LTD + +OUI:0050C2DB6* + ID_OUI_FROM_DATABASE=PROSOFT-SYSTEMS LTD + +OUI:0050C2DB7* + ID_OUI_FROM_DATABASE=SOREL GmbH Mikroelektronik + +OUI:0050C2DB8* + ID_OUI_FROM_DATABASE=Comsat VertriebsgmbH + +OUI:0050C2DB9* + ID_OUI_FROM_DATABASE=Peek Traffic Corporation + +OUI:0050C2DBA* + ID_OUI_FROM_DATABASE=M.P. Electronics + +OUI:0050C2DBB* + ID_OUI_FROM_DATABASE=Esensors, Inc. + +OUI:0050C2DBC* + ID_OUI_FROM_DATABASE=Nantes Systems Private Limited + +OUI:0050C2DBD* + ID_OUI_FROM_DATABASE=Margento R&D + +OUI:0050C2DBE* + ID_OUI_FROM_DATABASE=WITHSYSTEM Co.,Ltd + +OUI:0050C2DBF* + ID_OUI_FROM_DATABASE=One-Nemoto Engineering Corporation + +OUI:0050C2DC0* + ID_OUI_FROM_DATABASE=Security Services Group (SSG) + +OUI:0050C2DC1* + ID_OUI_FROM_DATABASE=Acrux Technology Limited + +OUI:0050C2DC2* + ID_OUI_FROM_DATABASE=TESSERA TECHNOLOGY INC. + +OUI:0050C2DC3* + ID_OUI_FROM_DATABASE=ZED Ziegler Electronic Devices GmbH + +OUI:0050C2DC4* + ID_OUI_FROM_DATABASE=Keith & Koep GmbH + +OUI:0050C2DC5* + ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG + +OUI:0050C2DC6* + ID_OUI_FROM_DATABASE=Fluid Components International + +OUI:0050C2DC7* + ID_OUI_FROM_DATABASE=AGT Holdings Limited + +OUI:0050C2DC8* + ID_OUI_FROM_DATABASE=T2M2 GmbH + +OUI:0050C2DC9* + ID_OUI_FROM_DATABASE=KinotonGmbH + +OUI:0050C2DCA* + ID_OUI_FROM_DATABASE=Tele Data Control + +OUI:0050C2DCB* + ID_OUI_FROM_DATABASE=CT Company + +OUI:0050C2DCC* + ID_OUI_FROM_DATABASE=Instrumentel Limited + +OUI:0050C2DCD* + ID_OUI_FROM_DATABASE=dilitronics GmbH + +OUI:0050C2DCE* + ID_OUI_FROM_DATABASE=Mecsel Oy + +OUI:0050C2DCF* + ID_OUI_FROM_DATABASE=MCS Engenharia ltda + +OUI:0050C2DD0* + ID_OUI_FROM_DATABASE=IDC Solutions Pty Ltd + +OUI:0050C2DD1* + ID_OUI_FROM_DATABASE=Dr. Ing. K. Brankamp System Prozessautomation GmbH + +OUI:0050C2DD2* + ID_OUI_FROM_DATABASE=Electronic Applications, Inc. + +OUI:0050C2DD3* + ID_OUI_FROM_DATABASE=Rohde & Schwarz Topex SA + +OUI:0050C2DD4* + ID_OUI_FROM_DATABASE=SYSTECH + +OUI:0050C2DD5* + ID_OUI_FROM_DATABASE=Friend Spring Industrial Co., Ltd. + +OUI:0050C2DD6* + ID_OUI_FROM_DATABASE=Transas Marine International AB + +OUI:0050C2DD7* + ID_OUI_FROM_DATABASE=Tornado Modular Systems + +OUI:0050C2DD8* + ID_OUI_FROM_DATABASE=Selex Systems Integration Inc + +OUI:0050C2DD9* + ID_OUI_FROM_DATABASE=Metraware + +OUI:0050C2DDA* + ID_OUI_FROM_DATABASE=rbz robot design s.l. + +OUI:0050C2DDB* + ID_OUI_FROM_DATABASE=EDIXIA + +OUI:0050C2DDC* + ID_OUI_FROM_DATABASE=Vision & Control GmbH + +OUI:0050C2DDD* + ID_OUI_FROM_DATABASE=A&A GENERAL SRL + +OUI:0050C2DDE* + ID_OUI_FROM_DATABASE=DRS RSTA + +OUI:0050C2DDF* + ID_OUI_FROM_DATABASE=Device GmbH + +OUI:0050C2DE0* + ID_OUI_FROM_DATABASE=INTERNET PROTOCOLO LOGICA SL + +OUI:0050C2DE1* + ID_OUI_FROM_DATABASE=ABB Transmission and Distribution Auto Eqip(Xiamen.China) + +OUI:0050C2DE2* + ID_OUI_FROM_DATABASE=SEQUTEC INC + +OUI:0050C2DE3* + ID_OUI_FROM_DATABASE=Breakaway Systems LLC + +OUI:0050C2DE4* + ID_OUI_FROM_DATABASE=EGS Technologies Ltd + +OUI:0050C2DE5* + ID_OUI_FROM_DATABASE=Neets + +OUI:0050C2DE6* + ID_OUI_FROM_DATABASE=Fr. Sauter AG + +OUI:0050C2DE7* + ID_OUI_FROM_DATABASE=Elan Systems + +OUI:0050C2DE8* + ID_OUI_FROM_DATABASE=Visual Productions + +OUI:0050C2DE9* + ID_OUI_FROM_DATABASE=Digatale Analoge COMponenten West Electronic Vertrieb GmbH + +OUI:0050C2DEA* + ID_OUI_FROM_DATABASE=Cerner Corporation + +OUI:0050C2DEB* + ID_OUI_FROM_DATABASE=Ruwisch & Kollegen GmbH + +OUI:0050C2DEC* + ID_OUI_FROM_DATABASE=VendNovation LLC + +OUI:0050C2DED* + ID_OUI_FROM_DATABASE=Lee Laser + +OUI:0050C2DEF* + ID_OUI_FROM_DATABASE=Powersense A/S + +OUI:0050C2DF0* + ID_OUI_FROM_DATABASE=Koncar Electrical Engineering Institute + +OUI:0050C2DF1* + ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG + +OUI:0050C2DF2* + ID_OUI_FROM_DATABASE=Instrument Concepts + +OUI:0050C2DF3* + ID_OUI_FROM_DATABASE=INSEVIS GmbH + +OUI:0050C2DF4* + ID_OUI_FROM_DATABASE=Potter Electric Signal + +OUI:0050C2DF5* + ID_OUI_FROM_DATABASE=EtherLight + +OUI:0050C2DF6* + ID_OUI_FROM_DATABASE=HINO ENGINEERING, INC + +OUI:0050C2DF7* + ID_OUI_FROM_DATABASE=Combilent + +OUI:0050C2DF8* + ID_OUI_FROM_DATABASE=Tommotek (WA) Pty Ltd. + +OUI:0050C2DF9* + ID_OUI_FROM_DATABASE=Jenny Science AG + +OUI:0050C2DFA* + ID_OUI_FROM_DATABASE=MAC Valves, Inc. + +OUI:0050C2DFB* + ID_OUI_FROM_DATABASE=BETTINI SRL + +OUI:0050C2DFC* + ID_OUI_FROM_DATABASE=I-Evo Ltd + +OUI:0050C2DFD* + ID_OUI_FROM_DATABASE=Wotbox ltd + +OUI:0050C2DFE* + ID_OUI_FROM_DATABASE=Xitek Design Limited + +OUI:0050C2DFF* + ID_OUI_FROM_DATABASE=TANTAL ELECTRONICA, SL + +OUI:0050C2E00* + ID_OUI_FROM_DATABASE=Aplex Technology Inc. + +OUI:0050C2E01* + ID_OUI_FROM_DATABASE=Tyco Traffic & Transportation + +OUI:0050C2E02* + ID_OUI_FROM_DATABASE=Cleverscope + +OUI:0050C2E03* + ID_OUI_FROM_DATABASE=ICU Scandinavia Schweiz GmbH + +OUI:0050C2E04* + ID_OUI_FROM_DATABASE=Sec.Eng Systems Pty Ltd + +OUI:0050C2E05* + ID_OUI_FROM_DATABASE=NOCOSIUM + +OUI:0050C2E06* + ID_OUI_FROM_DATABASE=Ebner Electronic GmbH + +OUI:0050C2E07* + ID_OUI_FROM_DATABASE=Protagon Process Technologies GmbH + +OUI:0050C2E08* + ID_OUI_FROM_DATABASE=KST Technology + +OUI:0050C2E09* + ID_OUI_FROM_DATABASE=ATEME + +OUI:0050C2E0A* + ID_OUI_FROM_DATABASE=Sicon srl + +OUI:0050C2E0B* + ID_OUI_FROM_DATABASE=Seartech + +OUI:0050C2E0C* + ID_OUI_FROM_DATABASE=YOUHO ELECTRIC IND.,LTD. + +OUI:0050C2E0D* + ID_OUI_FROM_DATABASE=Unixmedia Srl + +OUI:0050C2E0E* + ID_OUI_FROM_DATABASE=PMAC JAPAN + +OUI:0050C2E0F* + ID_OUI_FROM_DATABASE=Trentino Systems + +OUI:0050C2E10* + ID_OUI_FROM_DATABASE=Radinetworks Co., Ltd + +OUI:0050C2E11* + ID_OUI_FROM_DATABASE=RF Neulink + +OUI:0050C2E12* + ID_OUI_FROM_DATABASE=Innolex + +OUI:0050C2E13* + ID_OUI_FROM_DATABASE=Automation Assist Japan Company + +OUI:0050C2E14* + ID_OUI_FROM_DATABASE=Calixto Systems Pvt Ltd + +OUI:0050C2E15* + ID_OUI_FROM_DATABASE=IHI Scube Co.,Ltd + +OUI:0050C2E16* + ID_OUI_FROM_DATABASE=Jetstream Ltd. + +OUI:0050C2E17* + ID_OUI_FROM_DATABASE=Gall Tankdatensysteme GmbH + +OUI:0050C2E18* + ID_OUI_FROM_DATABASE=ABB Transmission and Distribution Automation Equipment (Xiamen) Co., Ltd. + +OUI:0050C2E19* + ID_OUI_FROM_DATABASE=Zoe Medical + +OUI:0050C2E1A* + ID_OUI_FROM_DATABASE=Rosslare Enterprises Limited + +OUI:0050C2E1B* + ID_OUI_FROM_DATABASE=Embedded Labs + +OUI:0050C2E1C* + ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG + +OUI:0050C2E1D* + ID_OUI_FROM_DATABASE=Holdline Tecnologia e Sistemas Ltda + +OUI:0050C2E1E* + ID_OUI_FROM_DATABASE=Lo-Q plc + +OUI:0050C2E1F* + ID_OUI_FROM_DATABASE=ELVEES + +OUI:0050C2E20* + ID_OUI_FROM_DATABASE=Divelbiss Corporation + +OUI:0050C2E21* + ID_OUI_FROM_DATABASE=Norwia AS + +OUI:0050C2E22* + ID_OUI_FROM_DATABASE=Michael Riedel Transformatorenbau GmbH + +OUI:0050C2E23* + ID_OUI_FROM_DATABASE=VITEC + +OUI:0050C2E24* + ID_OUI_FROM_DATABASE=DiTEST Fahrzeugdiagnose GmbH + +OUI:0050C2E25* + ID_OUI_FROM_DATABASE=ACD Elektronik GmbH + +OUI:0050C2E26* + ID_OUI_FROM_DATABASE=Cinetix s.r.l. + +OUI:0050C2E27* + ID_OUI_FROM_DATABASE=CONTROL SYSTEMS Srl + +OUI:0050C2E28* + ID_OUI_FROM_DATABASE=Teplovodokhran + +OUI:0050C2E29* + ID_OUI_FROM_DATABASE=Fr. Sauter AG + +OUI:0050C2E2A* + ID_OUI_FROM_DATABASE=Rohde&Schwarz Topex SA + +OUI:0050C2E2B* + ID_OUI_FROM_DATABASE=Plant Integrity Limited + +OUI:0050C2E2C* + ID_OUI_FROM_DATABASE=EN ElectronicNetwork Hamburg GmbH + +OUI:0050C2E2D* + ID_OUI_FROM_DATABASE=Funkwerk IT Karlsfeld GmbH + +OUI:0050C2E2E* + ID_OUI_FROM_DATABASE=DS! Ingenieurbuero + +OUI:0050C2E2F* + ID_OUI_FROM_DATABASE=Beam Ltd + +OUI:0050C2E30* + ID_OUI_FROM_DATABASE=Goennheimer Elektronic GmbH + +OUI:0050C2E31* + ID_OUI_FROM_DATABASE=ENSIS Co., Ltd. + +OUI:0050C2E32* + ID_OUI_FROM_DATABASE=Oshoksh Corporation + +OUI:0050C2E33* + ID_OUI_FROM_DATABASE=Morita Technical Center Company + +OUI:0050C2E34* + ID_OUI_FROM_DATABASE=HGL Dynamics + +OUI:0050C2E35* + ID_OUI_FROM_DATABASE=Omnica Corporation + +OUI:0050C2E36* + ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG + +OUI:0050C2E37* + ID_OUI_FROM_DATABASE=FUJI DATA SYSTEM Co., Ltd + +OUI:0050C2E38* + ID_OUI_FROM_DATABASE=Aesir Copenhagen + +OUI:0050C2E39* + ID_OUI_FROM_DATABASE=Telemetrics Inc. + +OUI:0050C2E3B* + ID_OUI_FROM_DATABASE=Nanosolution Inc. + +OUI:0050C2E3C* + ID_OUI_FROM_DATABASE=GRUPO EPELSA S.L. + +OUI:0050C2E3D* + ID_OUI_FROM_DATABASE=Baudisch Electronic GmbH + +OUI:0050C2E3E* + ID_OUI_FROM_DATABASE=Monnit Corp. + +OUI:0050C2E3F* + ID_OUI_FROM_DATABASE=VISITO S.R.L. IT10346660011 + +OUI:0050C2E40* + ID_OUI_FROM_DATABASE=Ecrin Systems + +OUI:0050C2E41* + ID_OUI_FROM_DATABASE=Higeco S.r.l. + +OUI:0050C2E42* + ID_OUI_FROM_DATABASE=Wings for Media SL + +OUI:0050C2E43* + ID_OUI_FROM_DATABASE=Technica Engineering GmbH + +OUI:0050C2E44* + ID_OUI_FROM_DATABASE=DEUTA-WERKE GmbH + +OUI:0050C2E45* + ID_OUI_FROM_DATABASE=Stichting Sunrise + +OUI:0050C2E46* + ID_OUI_FROM_DATABASE=Industrea Mining Technology + +OUI:0050C2E47* + ID_OUI_FROM_DATABASE=ENIKA.CZ + +OUI:0050C2E48* + ID_OUI_FROM_DATABASE=ITW Reyflex North America + +OUI:0050C2E49* + ID_OUI_FROM_DATABASE=CTF TECHNOLOGIES DO BRASIL LTDA + +OUI:0050C2E4A* + ID_OUI_FROM_DATABASE=GHL Systems Bhd + +OUI:0050C2E4B* + ID_OUI_FROM_DATABASE=Rohde&Schwarz Topex SA + +OUI:0050C2E4C* + ID_OUI_FROM_DATABASE=Applied Micro Electronics "AME" BV + +OUI:0050C2E4D* + ID_OUI_FROM_DATABASE=PCSC + +OUI:0050C2E4E* + ID_OUI_FROM_DATABASE=Institute For Information Industry + +OUI:0050C2E4F* + ID_OUI_FROM_DATABASE=Wine Technology Marlborough + +OUI:0050C2E50* + ID_OUI_FROM_DATABASE=Tattile srl + +OUI:0050C2E51* + ID_OUI_FROM_DATABASE=Motec Pty Ltd + +OUI:0050C2E52* + ID_OUI_FROM_DATABASE=Famas System S.p.A. + +OUI:0050C2E53* + ID_OUI_FROM_DATABASE=NEXT video systems Hard- and Software Development GmbH + +OUI:0050C2E54* + ID_OUI_FROM_DATABASE=Arcos Technologies LTD + +OUI:0050C2E55* + ID_OUI_FROM_DATABASE=TTi Ltd + +OUI:0050C2E56* + ID_OUI_FROM_DATABASE=RFENGINE CO., LTD. + +OUI:0050C2E57* + ID_OUI_FROM_DATABASE=EOLANE MONTCEAU + +OUI:0050C2E58* + ID_OUI_FROM_DATABASE=Agri-hitech LLC + +OUI:0050C2E59* + ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG + +OUI:0050C2E5A* + ID_OUI_FROM_DATABASE=FUTEC INC. + +OUI:0050C2E5B* + ID_OUI_FROM_DATABASE=CAIPO Automazione Industriale s.r.l. + +OUI:0050C2E5C* + ID_OUI_FROM_DATABASE=MCOPIA Co., Ltd + +OUI:0050C2E5D* + ID_OUI_FROM_DATABASE=T8 Ltd + +OUI:0050C2E5E* + ID_OUI_FROM_DATABASE=OREP + +OUI:0050C2E5F* + ID_OUI_FROM_DATABASE=Pantec Engineering AG + +OUI:0050C2E60* + ID_OUI_FROM_DATABASE=TAIYO SEIKI CO.,LTD. + +OUI:0050C2E61* + ID_OUI_FROM_DATABASE=Detech Electronics ApS + +OUI:0050C2E62* + ID_OUI_FROM_DATABASE=SAE IT-systems GmbH & Co. KG + +OUI:0050C2E63* + ID_OUI_FROM_DATABASE=Prima sistemi + +OUI:0050C2E64* + ID_OUI_FROM_DATABASE=Edgeware AB + +OUI:0050C2E65* + ID_OUI_FROM_DATABASE=IB Elektronik GmbH + +OUI:0050C2E66* + ID_OUI_FROM_DATABASE=EMAC, Inc. + +OUI:0050C2E67* + ID_OUI_FROM_DATABASE=Critical Link, LLC + +OUI:0050C2E68* + ID_OUI_FROM_DATABASE=Kyoritsu Electric Corporation + +OUI:0050C2E69* + ID_OUI_FROM_DATABASE=Netmaker + +OUI:0050C2E6A* + ID_OUI_FROM_DATABASE=Aplex Technology Inc. + +OUI:0050C2E6B* + ID_OUI_FROM_DATABASE=Sika Technology AG + +OUI:0050C2E6C* + ID_OUI_FROM_DATABASE=SAMSUNG LED Co.,Ltd. + +OUI:0050C2E6D* + ID_OUI_FROM_DATABASE=Allerta Inc + +OUI:0050C2E6E* + ID_OUI_FROM_DATABASE=Power-One Italia S.p.A + +OUI:0050C2E6F* + ID_OUI_FROM_DATABASE=Leyden Engineering + +OUI:0050C2E70* + ID_OUI_FROM_DATABASE=DORLET S.A. + +OUI:0050C2E71* + ID_OUI_FROM_DATABASE=traffic network solutions s.l + +OUI:0050C2E73* + ID_OUI_FROM_DATABASE=ACS Motion Control Ltd. + +OUI:0050C2E74* + ID_OUI_FROM_DATABASE=Will corp. + +OUI:0050C2E75* + ID_OUI_FROM_DATABASE=FSM Elektronik GmbH + +OUI:0050C2E76* + ID_OUI_FROM_DATABASE=Embedded Solution Bank Co., Ltd. + +OUI:0050C2E77* + ID_OUI_FROM_DATABASE=Fr. Sauter AG + +OUI:0050C2E78* + ID_OUI_FROM_DATABASE=TASK SISTEMAS DE COMPUTACAO LTDA + +OUI:0050C2E79* + ID_OUI_FROM_DATABASE=MCS MICRONIC Computer Systeme GmbH + +OUI:0050C2E7A* + ID_OUI_FROM_DATABASE=Lightel + +OUI:0050C2E7B* + ID_OUI_FROM_DATABASE=ATOM GIKEN Co.,Ltd. + +OUI:0050C2E7C* + ID_OUI_FROM_DATABASE=sp controls, inc + +OUI:0050C2E7D* + ID_OUI_FROM_DATABASE=AEL Microsystems Limited + +OUI:0050C2E7E* + ID_OUI_FROM_DATABASE=Swareflex GmbH + +OUI:0050C2E7F* + ID_OUI_FROM_DATABASE=LS Control A/S + +OUI:0050C2E80* + ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG + +OUI:0050C2E81* + ID_OUI_FROM_DATABASE=Adaptive Technologies, Inc. + +OUI:0050C2E82* + ID_OUI_FROM_DATABASE=Xplore Technologies Corp + +OUI:0050C2E83* + ID_OUI_FROM_DATABASE=Witree Co.,Ltd + +OUI:0050C2E84* + ID_OUI_FROM_DATABASE=ABB Transmission and Distribution Automation Equipment (Xiamen) Co., Ltd. + +OUI:0050C2E85* + ID_OUI_FROM_DATABASE=Cosmo Life Co.,Ltd + +OUI:0050C2E86* + ID_OUI_FROM_DATABASE=Multisuns Corporation + +OUI:0050C2E87* + ID_OUI_FROM_DATABASE=Lamson Safes & Security + +OUI:0050C2E88* + ID_OUI_FROM_DATABASE=Pivitec, LLC + +OUI:0050C2E89* + ID_OUI_FROM_DATABASE=PROTEQSEN + +OUI:0050C2E8A* + ID_OUI_FROM_DATABASE=Macronet s.r.l. + +OUI:0050C2E8B* + ID_OUI_FROM_DATABASE=RPA Electronic Solutions, Inc. + +OUI:0050C2E8C* + ID_OUI_FROM_DATABASE=Epec Oy + +OUI:0050C2E8D* + ID_OUI_FROM_DATABASE=SystemAdvanced Co,Ltd + +OUI:0050C2E8E* + ID_OUI_FROM_DATABASE=GENERAL DYNAMICS C4 SYSTEMS + +OUI:0050C2E8F* + ID_OUI_FROM_DATABASE=STT Condigi A/S + +OUI:0050C2E90* + ID_OUI_FROM_DATABASE=GS Elektromedizinische Geraete G. Stemple GmbH + +OUI:0050C2E91* + ID_OUI_FROM_DATABASE=DSP DESIGN LTD + +OUI:0050C2E92* + ID_OUI_FROM_DATABASE=CT Company + +OUI:0050C2E93* + ID_OUI_FROM_DATABASE=Perceptive Pixel Inc. + +OUI:0050C2E94* + ID_OUI_FROM_DATABASE=ANA-U GmbH + +OUI:0050C2E95* + ID_OUI_FROM_DATABASE=Dlite Comercio, Importadora e Serviços de Automação Ltda + +OUI:0050C2E96* + ID_OUI_FROM_DATABASE=PROYECSON S.A. + +OUI:0050C2E97* + ID_OUI_FROM_DATABASE=Arista Systems Corporation + +OUI:0050C2E98* + ID_OUI_FROM_DATABASE=i3 International Inc. + +OUI:0050C2E99* + ID_OUI_FROM_DATABASE=UV Networks, Inc. + +OUI:0050C2E9A* + ID_OUI_FROM_DATABASE=Solace Systems + +OUI:0050C2E9B* + ID_OUI_FROM_DATABASE=Hentschel System GmbH + +OUI:0050C2E9C* + ID_OUI_FROM_DATABASE=SPARQ systems + +OUI:0050C2E9D* + ID_OUI_FROM_DATABASE=nicai-systems + +OUI:0050C2E9E* + ID_OUI_FROM_DATABASE=American Microsystems, Ltd. + +OUI:0050C2E9F* + ID_OUI_FROM_DATABASE=DataSoft Corporation + +OUI:0050C2EA0* + ID_OUI_FROM_DATABASE=Robert Bosch Healthcare, Inc. + +OUI:0050C2EA1* + ID_OUI_FROM_DATABASE=TEX COMPUTER SRL + +OUI:0050C2EA2* + ID_OUI_FROM_DATABASE=ThinkRF Corp + +OUI:0050C2EA3* + ID_OUI_FROM_DATABASE=Subsea Systems, Inc. + +OUI:0050C2EA4* + ID_OUI_FROM_DATABASE=head + +OUI:0050C2EA5* + ID_OUI_FROM_DATABASE=Aerodata AG + +OUI:0050C2EA6* + ID_OUI_FROM_DATABASE=Powersense A/S + +OUI:0050C2EA7* + ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG + +OUI:0050C2EA8* + ID_OUI_FROM_DATABASE=MB Connect Line GmbH + +OUI:0050C2EA9* + ID_OUI_FROM_DATABASE=METTLER-TOLEDO HI-SPEED + +OUI:0050C2EAA* + ID_OUI_FROM_DATABASE=BAE Systems + +OUI:0050C2EAB* + ID_OUI_FROM_DATABASE=Warp9 Tech Design, Inc. + +OUI:0050C2EAC* + ID_OUI_FROM_DATABASE=Alias ip + +OUI:0050C2EAD* + ID_OUI_FROM_DATABASE=Rohde&Schwarz Topex SA + +OUI:0050C2EAE* + ID_OUI_FROM_DATABASE=Alyrica Networks + +OUI:0050C2EAF* + ID_OUI_FROM_DATABASE=Aircell + +OUI:0050C2EB0* + ID_OUI_FROM_DATABASE=Pulse Communication Systems Pvt. Ltd. + +OUI:0050C2EB1* + ID_OUI_FROM_DATABASE=PDU EXPERT UK LTD + +OUI:0050C2EB2* + ID_OUI_FROM_DATABASE=Otaki Electric Corporation + +OUI:0050C2EB3* + ID_OUI_FROM_DATABASE=AR RF/Microwave Instrumentation + +OUI:0050C2EB4* + ID_OUI_FROM_DATABASE=Wishtek Technology, Inc. + +OUI:0050C2EB5* + ID_OUI_FROM_DATABASE=Covidence A/S + +OUI:0050C2EB6* + ID_OUI_FROM_DATABASE=Monsoon Solutions, Inc. + +OUI:0050C2EB7* + ID_OUI_FROM_DATABASE=Saab AB + +OUI:0050C2EB8* + ID_OUI_FROM_DATABASE=dspnor + +OUI:0050C2EB9* + ID_OUI_FROM_DATABASE=ALPHA-MOS + +OUI:0050C2EBA* + ID_OUI_FROM_DATABASE=West-Com Nurse Call Systems, Inc. + +OUI:0050C2EBB* + ID_OUI_FROM_DATABASE=TimeTerminal Adductor Group AB + +OUI:0050C2EBC* + ID_OUI_FROM_DATABASE=Diehl AKO Stiftung & Co. KG + +OUI:0050C2EBD* + ID_OUI_FROM_DATABASE=Droplet Measurement Technologies + +OUI:0050C2EBE* + ID_OUI_FROM_DATABASE=Global Tecnologia LTDA. + +OUI:0050C2EBF* + ID_OUI_FROM_DATABASE=CIVOLUTION + +OUI:0050C2EC0* + ID_OUI_FROM_DATABASE=UgMO Technologies + +OUI:0050C2EC1* + ID_OUI_FROM_DATABASE=ANT Group s.r.l + +OUI:0050C2EC2* + ID_OUI_FROM_DATABASE=Ixonos Finland Ltd + +OUI:0050C2EC3* + ID_OUI_FROM_DATABASE=Aplex Technology Inc. + +OUI:0050C2EC4* + ID_OUI_FROM_DATABASE=Logical Electromechanical Sys Inc. + +OUI:0050C2EC5* + ID_OUI_FROM_DATABASE=RSUPPORT Co., Ltd. + +OUI:0050C2EC6* + ID_OUI_FROM_DATABASE=INFRONICS SYSTEMS LIMITED + +OUI:0050C2EC7* + ID_OUI_FROM_DATABASE=LIQUID ROBOTICS, INC + +OUI:0050C2EC8* + ID_OUI_FROM_DATABASE=IBERNEX INGENIERIA, S.L. + +OUI:0050C2EC9* + ID_OUI_FROM_DATABASE=Amsterdam Scientific Instruments BV + +OUI:0050C2ECA* + ID_OUI_FROM_DATABASE=BitWise Controls + +OUI:0050C2ECB* + ID_OUI_FROM_DATABASE=FAL Corp + +OUI:0050C2ECC* + ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG + +OUI:0050C2ECD* + ID_OUI_FROM_DATABASE=Peek Traffic Corporation + +OUI:0050C2ECE* + ID_OUI_FROM_DATABASE=easii ic adiis + +OUI:0050C2ECF* + ID_OUI_FROM_DATABASE=TAIWAN HIPLUS CORPORATION + +OUI:0050C2ED0* + ID_OUI_FROM_DATABASE=Nippon Systemware Co.,Ltd. + +OUI:0050C2ED1* + ID_OUI_FROM_DATABASE=Arcontia Technology AB + +OUI:0050C2ED2* + ID_OUI_FROM_DATABASE=Klangspektrum GmbH + +OUI:0050C2ED3* + ID_OUI_FROM_DATABASE=ECO MONITORING UTILITY SYSTEMS LTD + +OUI:0050C2ED4* + ID_OUI_FROM_DATABASE=TAMAGAWA ELECTRONICS CO.,LTD. + +OUI:0050C2ED5* + ID_OUI_FROM_DATABASE=RFL Electronics Inc. + +OUI:0050C2ED6* + ID_OUI_FROM_DATABASE=Cat AB + +OUI:0050C2ED7* + ID_OUI_FROM_DATABASE=FBT Elettronica spa + +OUI:0050C2ED8* + ID_OUI_FROM_DATABASE=AVocation Systems, Inc. + +OUI:0050C2ED9* + ID_OUI_FROM_DATABASE=Plasmatronics pty ltd + +OUI:0050C2EDA* + ID_OUI_FROM_DATABASE=Joint Stock Company "Svyaz Inginiring M" + +OUI:0050C2EDB* + ID_OUI_FROM_DATABASE=BELIK S.P.R.L. + +OUI:0050C2EDC* + ID_OUI_FROM_DATABASE=Eyelock Corporation + +OUI:0050C2EDD* + ID_OUI_FROM_DATABASE=EBNEURO SPA + +OUI:0050C2EDE* + ID_OUI_FROM_DATABASE=Smart Grid Networks + +OUI:0050C2EDF* + ID_OUI_FROM_DATABASE=Monitor Business Machines + +OUI:0050C2EE0* + ID_OUI_FROM_DATABASE=osf Hansjuergen Meier GmbH & Co. KG + +OUI:0050C2EE1* + ID_OUI_FROM_DATABASE=Procon Electronics Pty Ltd + +OUI:0050C2EE2* + ID_OUI_FROM_DATABASE=System Industrie Electronic GmbH + +OUI:0050C2EE3* + ID_OUI_FROM_DATABASE=Tecnint HTE Srl + +OUI:0050C2EE4* + ID_OUI_FROM_DATABASE=Rohde&Schwarz Topex SA + +OUI:0050C2EE5* + ID_OUI_FROM_DATABASE=Cytec Zylindertechnik GmbH + +OUI:0050C2EE6* + ID_OUI_FROM_DATABASE=B:TECH, a. s. + +OUI:0050C2EE7* + ID_OUI_FROM_DATABASE=Syes srl + +OUI:0050C2EE8* + ID_OUI_FROM_DATABASE=Kamacho Scale Co., Ltd. + +OUI:0050C2EE9* + ID_OUI_FROM_DATABASE=QUANTA S.r.l. + +OUI:0050C2EEA* + ID_OUI_FROM_DATABASE=Positioneering Limited + +OUI:0050C2EEB* + ID_OUI_FROM_DATABASE=fibrisTerre GmbH + +OUI:0050C2EEC* + ID_OUI_FROM_DATABASE=Yuyama Mfg. Co., Ltd. + +OUI:0050C2EED* + ID_OUI_FROM_DATABASE=Future Design Controls, Inc + +OUI:0050C2EEE* + ID_OUI_FROM_DATABASE=ABB Transmission and Distribution Automation Equipment (Xiamen) Co., Ltd + +OUI:0050C2EEF* + ID_OUI_FROM_DATABASE=IDTRONIC GmbH + +OUI:0050C2EF0* + ID_OUI_FROM_DATABASE=Homaetrix Ltd + +OUI:0050C2EF1* + ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG + +OUI:0050C2EF2* + ID_OUI_FROM_DATABASE=Specialty Microwave Corp + +OUI:0050C2EF3* + ID_OUI_FROM_DATABASE=Smart Power Electronics GmbH & Co. KG + +OUI:0050C2EF4* + ID_OUI_FROM_DATABASE=RO.VE.R. Laboratories S.p.A + +OUI:0050C2EF5* + ID_OUI_FROM_DATABASE=Human Network Labs, Inc. + +OUI:0050C2EF6* + ID_OUI_FROM_DATABASE=Netline Communication Technologies + +OUI:0050C2EF7* + ID_OUI_FROM_DATABASE=Amstelland Electronic BV + +OUI:0050C2EF8* + ID_OUI_FROM_DATABASE=HCL Technologies + +OUI:0050C2EF9* + ID_OUI_FROM_DATABASE=HORIBA ABX + +OUI:0050C2EFA* + ID_OUI_FROM_DATABASE=Predictive Sensor Technology + +OUI:0050C2EFB* + ID_OUI_FROM_DATABASE=Norbit ODM AS + +OUI:0050C2EFD* + ID_OUI_FROM_DATABASE=Sanmina-SCI + +OUI:0050C2EFE* + ID_OUI_FROM_DATABASE=PLR Information Systems Ltd. + +OUI:0050C2EFF* + ID_OUI_FROM_DATABASE=Zephyrus Electronics LTD. + +OUI:0050C2F00* + ID_OUI_FROM_DATABASE=Syscom Instruments + +OUI:0050C2F01* + ID_OUI_FROM_DATABASE=Mango DSP, Inc + +OUI:0050C2F02* + ID_OUI_FROM_DATABASE=BMR + +OUI:0050C2F03* + ID_OUI_FROM_DATABASE=Wren Sound Systems + +OUI:0050C2F04* + ID_OUI_FROM_DATABASE=KINKI ROENTGEN INDUSTRIAL CO.,LTD + +OUI:0050C2F05* + ID_OUI_FROM_DATABASE=ESI Ventures + +OUI:0050C2F06* + ID_OUI_FROM_DATABASE=Micro-Key BV + +OUI:0050C2F07* + ID_OUI_FROM_DATABASE=Icon Research Ltd + +OUI:0050C2F08* + ID_OUI_FROM_DATABASE=Aplex Technology Inc. + +OUI:0050C2F09* + ID_OUI_FROM_DATABASE=Wheatstone Corporation + +OUI:0050C2F0A* + ID_OUI_FROM_DATABASE=HASCOM International Pty Ltd + +OUI:0050C2F0B* + ID_OUI_FROM_DATABASE=Treehaven Technologies, Inc. + +OUI:0050C2F0C* + ID_OUI_FROM_DATABASE=SKYCHANNEL LTD + +OUI:0050C2F0D* + ID_OUI_FROM_DATABASE=Bluetest AB + +OUI:0050C2F0E* + ID_OUI_FROM_DATABASE=Micro Technic A/S + +OUI:0050C2F0F* + ID_OUI_FROM_DATABASE=AeroVision Avionics, Inc. + +OUI:0050C2F10* + ID_OUI_FROM_DATABASE=Wincor Nixdorf Sp. z o.o. + +OUI:0050C2F11* + ID_OUI_FROM_DATABASE=Organis GmbH + +OUI:0050C2F12* + ID_OUI_FROM_DATABASE=General Industrial Controls Pvt Ltd + +OUI:0050C2F13* + ID_OUI_FROM_DATABASE=Packet Plus, Inc. + +OUI:0050C2F14* + ID_OUI_FROM_DATABASE=VISION SYSTEMS AERONAUTIC + +OUI:0050C2F15* + ID_OUI_FROM_DATABASE=Sascal Displays Ltd + +OUI:0050C2F16* + ID_OUI_FROM_DATABASE=Peter Huber Kältemaschinenbau GmbH + +OUI:0050C2F17* + ID_OUI_FROM_DATABASE=ABB Transmission and Distribution Automation Equipment (Xiamen) Co., Ltd + +OUI:0050C2F18* + ID_OUI_FROM_DATABASE=Vitec Multimedia + +OUI:0050C2F19* + ID_OUI_FROM_DATABASE=Netlink Bilisim Sistemleri San. ve Tic. Ltd. Sti. + +OUI:0050C2F1A* + ID_OUI_FROM_DATABASE=Aqua Management + +OUI:0050C2F1B* + ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG + +OUI:0050C2F1C* + ID_OUI_FROM_DATABASE=GENERAL DYNAMICS C4 SYSTEMS + +OUI:0050C2F1D* + ID_OUI_FROM_DATABASE=Grossenbacher Systeme AG + +OUI:0050C2F1E* + ID_OUI_FROM_DATABASE=Dell'Orto S.P.A. + +OUI:0050C2F1F* + ID_OUI_FROM_DATABASE=Verified Energy, LLC. + +OUI:0050C2F20* + ID_OUI_FROM_DATABASE=Unfors Instruments AB + +OUI:0050C2F21* + ID_OUI_FROM_DATABASE=SEITEC Co. Ltd + +OUI:0050C2F22* + ID_OUI_FROM_DATABASE=Harland Simon plc + +OUI:0050C2F23* + ID_OUI_FROM_DATABASE=Electro Motive Diesel + +OUI:0050C2F24* + ID_OUI_FROM_DATABASE=CT Company + +OUI:0050C2F25* + ID_OUI_FROM_DATABASE=Samway Electronic SRL + +OUI:0050C2F26* + ID_OUI_FROM_DATABASE=WaveIP + +OUI:0050C2F27* + ID_OUI_FROM_DATABASE=ELAN SYSTEMS + +OUI:0050C2F28* + ID_OUI_FROM_DATABASE=Vertex Antennentechnik GmbH + +OUI:0050C2F29* + ID_OUI_FROM_DATABASE=RADYNE CORPORATION + +OUI:0050C2F2A* + ID_OUI_FROM_DATABASE=ACD Elektronik GmbH + +OUI:0050C2F2B* + ID_OUI_FROM_DATABASE=Bio Guard component & technologies + +OUI:0050C2F2C* + ID_OUI_FROM_DATABASE=Terratel Technology s.r.o. + +OUI:0050C2F2D* + ID_OUI_FROM_DATABASE=Robert Bosch Healthcare Systems, Inc. + +OUI:0050C2F2E* + ID_OUI_FROM_DATABASE=H&L Instruments, LLC + +OUI:0050C2F2F* + ID_OUI_FROM_DATABASE=Arcos Technologies LTD + +OUI:0050C2F30* + ID_OUI_FROM_DATABASE=Miris AB + +OUI:0050C2F31* + ID_OUI_FROM_DATABASE=Ruetz Technologies GmbH + +OUI:0050C2F32* + ID_OUI_FROM_DATABASE=Net4Things + +OUI:0050C2F33* + ID_OUI_FROM_DATABASE=Applied Micro Electronics "AME" BV + +OUI:0050C2F34* + ID_OUI_FROM_DATABASE=Sequip S+E GmbH + +OUI:0050C2F35* + ID_OUI_FROM_DATABASE=GRUPO EPELSA S.L. + +OUI:0050C2F36* + ID_OUI_FROM_DATABASE=Visitech AS + +OUI:0050C2F37* + ID_OUI_FROM_DATABASE=Rosslare Enterprises Limited + +OUI:0050C2F38* + ID_OUI_FROM_DATABASE=AeroControl, Inc. + +OUI:0050C2F39* + ID_OUI_FROM_DATABASE=Inforce Computing, Inc. + +OUI:0050C2F3A* + ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG + +OUI:0050C2F3B* + ID_OUI_FROM_DATABASE=TAMS firmware co. + +OUI:0050C2F3C* + ID_OUI_FROM_DATABASE=Vemco Sp. z o. o. + +OUI:0050C2F3D* + ID_OUI_FROM_DATABASE=Project service S.a.s + +OUI:0050C2F3E* + ID_OUI_FROM_DATABASE=Vtron Pty Ltd + +OUI:0050C2F3F* + ID_OUI_FROM_DATABASE=DENSEI COMMUNICATION Inc. + +OUI:0050C2F40* + ID_OUI_FROM_DATABASE=iBWorld co.,ltd. + +OUI:0050C2F41* + ID_OUI_FROM_DATABASE=FairyDevices Inc. + +OUI:0050C2F42* + ID_OUI_FROM_DATABASE=DSPCon + +OUI:0050C2F43* + ID_OUI_FROM_DATABASE=Special Systems Engineering Center LLC + +OUI:0050C2F44* + ID_OUI_FROM_DATABASE=Steinbichler Optotechnik GmbH + +OUI:0050C2F45* + ID_OUI_FROM_DATABASE=HUSTY M.Styczen J.Hupert Sp.J. + +OUI:0050C2F46* + ID_OUI_FROM_DATABASE=Reason Tecnologia S.A. + +OUI:0050C2F47* + ID_OUI_FROM_DATABASE=cadac,inc. + +OUI:0050C2F48* + ID_OUI_FROM_DATABASE=Midas Technology DBA Phoenix Audio Technologies + +OUI:0050C2F49* + ID_OUI_FROM_DATABASE=Green Instruments A/S + +OUI:0050C2F4A* + ID_OUI_FROM_DATABASE=Z-App Systems, Inc. + +OUI:0050C2F4B* + ID_OUI_FROM_DATABASE=Supranet + +OUI:0050C2F4C* + ID_OUI_FROM_DATABASE=Enistic Limited + +OUI:0050C2F4D* + ID_OUI_FROM_DATABASE=KNOWHOW INFOCOM INC. + +OUI:0050C2F4E* + ID_OUI_FROM_DATABASE=Heinzinger electronic GmbH + +OUI:0050C2F4F* + ID_OUI_FROM_DATABASE=BAP Precision Ltd. + +OUI:0050C2F50* + ID_OUI_FROM_DATABASE=Moritex Corporation + +OUI:0050C2F51* + ID_OUI_FROM_DATABASE=NDC Infrared Engineering, Inc. + +OUI:0050C2F52* + ID_OUI_FROM_DATABASE=Rohde&Schwarz Topex SA + +OUI:0050C2F53* + ID_OUI_FROM_DATABASE=BAYCOM OPTO-ELECTRONICS TECHNOLOGY CO.,LTD. + +OUI:0050C2F54* + ID_OUI_FROM_DATABASE=Hella Gutmann Solutions GmbH + +OUI:0050C2F55* + ID_OUI_FROM_DATABASE=Honeywell International Inc. + +OUI:0050C2F56* + ID_OUI_FROM_DATABASE=Monsoon Solutions, Inc. + +OUI:0050C2F57* + ID_OUI_FROM_DATABASE=Reach Technologies Inc. + +OUI:0050C2F58* + ID_OUI_FROM_DATABASE=IEEE-SA + +OUI:0050C2F59* + ID_OUI_FROM_DATABASE=G3 Technologies + +OUI:0050C2F5A* + ID_OUI_FROM_DATABASE=Sentry 360 Security + +OUI:0050C2F5B* + ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG + +OUI:0050C2F5C* + ID_OUI_FROM_DATABASE=DSP DESIGN LTD + +OUI:0050C2F5D* + ID_OUI_FROM_DATABASE=SMARTB TECHNOLOGIES + +OUI:0050C2F5E* + ID_OUI_FROM_DATABASE=Y-cam Solutions Ltd + +OUI:0050C2F5F* + ID_OUI_FROM_DATABASE=BORYEU TECHNOLOGY CO.,LTD + +OUI:0050C2F60* + ID_OUI_FROM_DATABASE=Deckma GmbH + +OUI:0050C2F61* + ID_OUI_FROM_DATABASE=Brauch Elektronik GmbH&Co.KG + +OUI:0050C2F62* + ID_OUI_FROM_DATABASE=EMAC, Inc. + +OUI:0050C2F63* + ID_OUI_FROM_DATABASE=Triax A/S + +OUI:0050C2F64* + ID_OUI_FROM_DATABASE=Chrisso Technologies LLC + +OUI:0050C2F65* + ID_OUI_FROM_DATABASE=Telebyte Inc. + +OUI:0050C2F66* + ID_OUI_FROM_DATABASE=GWT LLC + +OUI:0050C2F67* + ID_OUI_FROM_DATABASE=Celestial Audio + +OUI:0050C2F68* + ID_OUI_FROM_DATABASE=NEWTEC A/S + +OUI:0050C2F69* + ID_OUI_FROM_DATABASE=Safe Place Solutions Ltd + +OUI:0050C2F6A* + ID_OUI_FROM_DATABASE=OFI Inc. (dba 2D2C) + +OUI:0050C2F6B* + ID_OUI_FROM_DATABASE=Algodue Elettronica Srl + +OUI:0050C2F6C* + ID_OUI_FROM_DATABASE=Pro Design Electronic GmbH + +OUI:0050C2F6D* + ID_OUI_FROM_DATABASE=Pro Design Electronic GmbH + +OUI:0050C2F6E* + ID_OUI_FROM_DATABASE=Smith Meter, Inc. + +OUI:0050C2F6F* + ID_OUI_FROM_DATABASE=Aplex Technology Inc. + +OUI:0050C2F70* + ID_OUI_FROM_DATABASE=Noralta Technologies Inc + +OUI:0050C2F71* + ID_OUI_FROM_DATABASE=RF CODE, INC + +OUI:0050C2F72* + ID_OUI_FROM_DATABASE=MaxDeTec AG + +OUI:0050C2F73* + ID_OUI_FROM_DATABASE=DELTACAST.TV + +OUI:0050C2F74* + ID_OUI_FROM_DATABASE=Thor Technologies Pty Ltd + +OUI:0050C2F75* + ID_OUI_FROM_DATABASE=PumpWell Solutions Ltd. + +OUI:0050C2F76* + ID_OUI_FROM_DATABASE=Rong Jie(FuZhou)Electronics Co.,Ltd + +OUI:0050C2F77* + ID_OUI_FROM_DATABASE=SYSTEMTECHNIK GmbH + +OUI:0050C2F78* + ID_OUI_FROM_DATABASE=Gets MSS S.A. + +OUI:0050C2F79* + ID_OUI_FROM_DATABASE=Tattile SRL + +OUI:0050C2F7A* + ID_OUI_FROM_DATABASE=C3 LLC + +OUI:0050C2F7B* + ID_OUI_FROM_DATABASE=MCM Electronics + +OUI:0050C2F7C* + ID_OUI_FROM_DATABASE=Atonometrics, Inc. + +OUI:0050C2F7D* + ID_OUI_FROM_DATABASE=D-Hike Electroncs Technology Co.,Ltd + +OUI:0050C2F7E* + ID_OUI_FROM_DATABASE=TruTeq Wireless (Pty) Ltd + +OUI:0050C2F7F* + ID_OUI_FROM_DATABASE=Dynamic Design + +OUI:0050C2F80* + ID_OUI_FROM_DATABASE=SYS TEC electronic GmbH + +OUI:0050C2F81* + ID_OUI_FROM_DATABASE=PLDA + +OUI:0050C2F82* + ID_OUI_FROM_DATABASE=Sincair Systems International + +OUI:0050C2F83* + ID_OUI_FROM_DATABASE=GSP Sprachtechnologie GmbH + +OUI:0050C2F84* + ID_OUI_FROM_DATABASE=Dynon Instruments + +OUI:0050C2F85* + ID_OUI_FROM_DATABASE=Enetics, Inc. + +OUI:0050C2F86* + ID_OUI_FROM_DATABASE=Audio Power Labs + +OUI:0050C2F87* + ID_OUI_FROM_DATABASE=Vaisala Oyj + +OUI:0050C2F88* + ID_OUI_FROM_DATABASE=RTC Manufacturing Inc. + +OUI:0050C2F89* + ID_OUI_FROM_DATABASE=CSA Engineering AG + +OUI:0050C2F8A* + ID_OUI_FROM_DATABASE=EMAC, Inc. + +OUI:0050C2F8B* + ID_OUI_FROM_DATABASE=Comlet Verteilte Systeme GmbH + +OUI:0050C2F8C* + ID_OUI_FROM_DATABASE=UBSTechnology Co., Ltd + +OUI:0050C2F8D* + ID_OUI_FROM_DATABASE=GUANGDONG EAST POWER CO.,LTD. + +OUI:0050C2F8E* + ID_OUI_FROM_DATABASE=GPO + +OUI:0050C2F8F* + ID_OUI_FROM_DATABASE=Computerwise, Inc. + +OUI:0050C2F90* + ID_OUI_FROM_DATABASE=SecureTech Systems, Inc. + +OUI:0050C2F91* + ID_OUI_FROM_DATABASE=RE2 Inc + +OUI:0050C2F92* + ID_OUI_FROM_DATABASE=CONET Solutions GmbH + +OUI:0050C2F93* + ID_OUI_FROM_DATABASE=Baudisch Electronic GmbH + +OUI:0050C2F94* + ID_OUI_FROM_DATABASE=Digital Barriers + +OUI:0050C2F95* + ID_OUI_FROM_DATABASE=TTi LTD (Thurlby Thandar Instruments LTD) + +OUI:0050C2F96* + ID_OUI_FROM_DATABASE=JLCooper Electronics + +OUI:0050C2F97* + ID_OUI_FROM_DATABASE=Sicon srl + +OUI:0050C2F98* + ID_OUI_FROM_DATABASE=Infotech North America + +OUI:0050C2F99* + ID_OUI_FROM_DATABASE=Dr. Neumann elektronik GmbH + +OUI:0050C2F9A* + ID_OUI_FROM_DATABASE=Telvent + +OUI:0050C2F9B* + ID_OUI_FROM_DATABASE=NEWELL TECHNOLOGIES LIMITED + +OUI:0050C2F9C* + ID_OUI_FROM_DATABASE=R&D KOMETEH + +OUI:0050C2F9D* + ID_OUI_FROM_DATABASE=JSC "Kaluga Teletypes Manufacturing Plant" + +OUI:0050C2F9E* + ID_OUI_FROM_DATABASE=Matsusada Precision Inc. + +OUI:0050C2F9F* + ID_OUI_FROM_DATABASE=Nanjing SAC Power Grid Automation Co., Ltd. + +OUI:0050C2FA0* + ID_OUI_FROM_DATABASE=Amplus Communication Pte Ltd + +OUI:0050C2FA1* + ID_OUI_FROM_DATABASE=N-Hands GmbH und Co KG + +OUI:0050C2FA2* + ID_OUI_FROM_DATABASE=Power-One + +OUI:0050C2FA3* + ID_OUI_FROM_DATABASE=Xemex NV + +OUI:0050C2FA5* + ID_OUI_FROM_DATABASE=Intuitive Surgical, Inc. + +OUI:0050C2FA6* + ID_OUI_FROM_DATABASE=Hilkom digital GmbH + +OUI:0050C2FA7* + ID_OUI_FROM_DATABASE=Exelis Inc. + +OUI:0050C2FA8* + ID_OUI_FROM_DATABASE=Yash SiQure Technologies India Pvt. Ltd. + +OUI:0050C2FA9* + ID_OUI_FROM_DATABASE=Hijet Print d.o.o. + +OUI:0050C2FAA* + ID_OUI_FROM_DATABASE=YJSYSTEM + +OUI:0050C2FAB* + ID_OUI_FROM_DATABASE=Aplex Technology Inc. + +OUI:0050C2FAC* + ID_OUI_FROM_DATABASE=ADETEL GROUP + +OUI:0050C2FAD* + ID_OUI_FROM_DATABASE=Finishing Brands + +OUI:0050C2FAE* + ID_OUI_FROM_DATABASE=ATI Automacao Telecomunicacoes e Informatica Ltda + +OUI:0050C2FAF* + ID_OUI_FROM_DATABASE=Vremya-CH JSC + +OUI:0050C2FB0* + ID_OUI_FROM_DATABASE=Tateishi Kobisha Co.LTD + +OUI:0050C2FB1* + ID_OUI_FROM_DATABASE=MATELEX + +OUI:0050C2FB2* + ID_OUI_FROM_DATABASE=Preston Industries dba PolyScience + +OUI:0050C2FB3* + ID_OUI_FROM_DATABASE=CT Company + +OUI:0050C2FB4* + ID_OUI_FROM_DATABASE=MC-monitoring SA + +OUI:0050C2FB5* + ID_OUI_FROM_DATABASE=Assembly Contracts Limited + +OUI:0050C2FB6* + ID_OUI_FROM_DATABASE=ARGUS-SPECTRUM + +OUI:0050C2FB7* + ID_OUI_FROM_DATABASE=Pounce Consulting + +OUI:0050C2FB8* + ID_OUI_FROM_DATABASE=TECHNO CO.,LTD. + +OUI:0050C2FB9* + ID_OUI_FROM_DATABASE=Coral Telecom Ltd + +OUI:0050C2FBA* + ID_OUI_FROM_DATABASE=Elbit Systems of America + +OUI:0050C2FBB* + ID_OUI_FROM_DATABASE=ACIDA GmbH + +OUI:0050C2FBC* + ID_OUI_FROM_DATABASE=Leroy Somer + +OUI:0050C2FBD* + ID_OUI_FROM_DATABASE=FHF Funke + Huster Fernsig GmbH + +OUI:0050C2FBE* + ID_OUI_FROM_DATABASE=senTec Elektronik GmbH + +OUI:0050C2FBF* + ID_OUI_FROM_DATABASE=MYLOGIC + +OUI:0050C2FC0* + ID_OUI_FROM_DATABASE=Rohde&Schwarz Topex SA + +OUI:0050C2FC1* + ID_OUI_FROM_DATABASE=Motec Pty Ltd + +OUI:0050C2FC2* + ID_OUI_FROM_DATABASE=ELTA + +OUI:0050C2FC3* + ID_OUI_FROM_DATABASE=HSDC Sp. z o.o. + +OUI:0050C2FC4* + ID_OUI_FROM_DATABASE=Kyowadensi + +OUI:0050C2FC5* + ID_OUI_FROM_DATABASE=Sakura Seiki Co.,Ltd. + +OUI:0050C2FC6* + ID_OUI_FROM_DATABASE=Critical Link + +OUI:0050C2FC7* + ID_OUI_FROM_DATABASE=SERCOM Regeltechniek + +OUI:0050C2FC8* + ID_OUI_FROM_DATABASE=Far South Networks + +OUI:0050C2FC9* + ID_OUI_FROM_DATABASE=Mehta Tech, Inc. + +OUI:0050C2FCA* + ID_OUI_FROM_DATABASE=Telemisis Ltd + +OUI:0050C2FCB* + ID_OUI_FROM_DATABASE=Propagation Systems Limited + +OUI:0050C2FCC* + ID_OUI_FROM_DATABASE=Soudronic AG + +OUI:0050C2FCD* + ID_OUI_FROM_DATABASE=Jinyoung Contech + +OUI:0050C2FCE* + ID_OUI_FROM_DATABASE=KOYO ELECTRIC + +OUI:0050C2FCF* + ID_OUI_FROM_DATABASE=DINTEK Shanghai Electronic Ltd + +OUI:0050C2FD0* + ID_OUI_FROM_DATABASE=Simple Solutions + +OUI:0050C2FD1* + ID_OUI_FROM_DATABASE=Enyx SA + +OUI:0050C2FD2* + ID_OUI_FROM_DATABASE=Autonomic Controls. Inc + +OUI:0050C2FD3* + ID_OUI_FROM_DATABASE=Aster Electric Co.,Ltd. + +OUI:0050C2FD4* + ID_OUI_FROM_DATABASE=Insitu, Inc. + +OUI:0050C2FD5* + ID_OUI_FROM_DATABASE=American Microsystems, Ltd. + +OUI:0050C2FD6* + ID_OUI_FROM_DATABASE=City Computing Ltd + +OUI:0050C2FD7* + ID_OUI_FROM_DATABASE=Deuta-Werke GmbH + +OUI:0050C2FD8* + ID_OUI_FROM_DATABASE=Ease Inc. + +OUI:0050C2FD9* + ID_OUI_FROM_DATABASE=Figment Design Laboratories + +OUI:0050C2FDA* + ID_OUI_FROM_DATABASE=ELAN SYSTEMS + +OUI:0050C2FDB* + ID_OUI_FROM_DATABASE=The Security Center Inc + +OUI:0050C2FDC* + ID_OUI_FROM_DATABASE=QUERCUS TECHNOLOGIES, S.L. + +OUI:0050C2FDD* + ID_OUI_FROM_DATABASE=Toptech Systems, Inc. + +OUI:0050C2FDE* + ID_OUI_FROM_DATABASE=Peek Traffic + +OUI:0050C2FDF* + ID_OUI_FROM_DATABASE=ACD Elektronik GmbH + +OUI:0050C2FE0* + ID_OUI_FROM_DATABASE=Azurtest + +OUI:0050C2FE1* + ID_OUI_FROM_DATABASE=dotOcean + +OUI:0050C2FE2* + ID_OUI_FROM_DATABASE=Pulsotronic Anlagentechnik GmbH + +OUI:0050C2FE4* + ID_OUI_FROM_DATABASE=RTT Mobile Interpretation + +OUI:0050C2FE5* + ID_OUI_FROM_DATABASE=Scandinova Systems AB + +OUI:0050C2FE6* + ID_OUI_FROM_DATABASE=Exibea AB + +OUI:0050C2FE7* + ID_OUI_FROM_DATABASE=Erhardt+Leimer GmbH + +OUI:0050C2FE8* + ID_OUI_FROM_DATABASE=Mango DSP, Inc. + +OUI:0050C2FE9* + ID_OUI_FROM_DATABASE=MB Connect Line GmbH + +OUI:0050C2FEA* + ID_OUI_FROM_DATABASE=Brunel GmbH Section Communications + +OUI:0050C2FEB* + ID_OUI_FROM_DATABASE=Axible Technologies + +OUI:0050C2FEC* + ID_OUI_FROM_DATABASE=First System Technology Co., Ltd. + +OUI:0050C2FED* + ID_OUI_FROM_DATABASE=LOGISOL Kft. + +OUI:0050C2FEE* + ID_OUI_FROM_DATABASE=Sparks Instruments SA + +OUI:0050C2FEF* + ID_OUI_FROM_DATABASE=Task Sistemas de Computacao + +OUI:0050C2FF0* + ID_OUI_FROM_DATABASE=GENERAL DYNAMICS C4 SYSTEMS + +OUI:0050C2FF1* + ID_OUI_FROM_DATABASE=DiTEST FAHRZEUGDIAGNOSE GMBH + +OUI:0050C2FF2* + ID_OUI_FROM_DATABASE=GLOBALCOM ENGINEERING SRL + +OUI:0050C2FF3* + ID_OUI_FROM_DATABASE=CONTROL SYSTEMS Srl + +OUI:0050C2FF4* + ID_OUI_FROM_DATABASE=Burk Technology + +OUI:0050C2FF5* + ID_OUI_FROM_DATABASE=Flexkom Internet Pazarlama Bilipim ve Eoitim Hiz.Inp.Mim.Muh.Oto.Enerji San. Tic. A.p. + +OUI:0050C2FF6* + ID_OUI_FROM_DATABASE=Booyco Electronics + +OUI:0050C2FF7* + ID_OUI_FROM_DATABASE=Human Intech + +OUI:0050C2FF8* + ID_OUI_FROM_DATABASE=KST technology + +OUI:0050C2FF9* + ID_OUI_FROM_DATABASE=Penttech AB + +OUI:0050C2FFA* + ID_OUI_FROM_DATABASE=Nupoint Systems Inc. + +OUI:0050C2FFB* + ID_OUI_FROM_DATABASE=SEFRAM + +OUI:0050C2FFC* + ID_OUI_FROM_DATABASE=Spirent Communications + +OUI:0050C2FFD* + ID_OUI_FROM_DATABASE=Touchless Biometric Systems AG + +OUI:0050C2FFE* + ID_OUI_FROM_DATABASE=Sensata Technologies + +OUI:0050C2FFF* + ID_OUI_FROM_DATABASE=MSR-Solutions GmbH + +OUI:40D855000* + ID_OUI_FROM_DATABASE=XRONOS.INC + +OUI:40D855001* + ID_OUI_FROM_DATABASE=Vemotion + +OUI:40D855002* + ID_OUI_FROM_DATABASE=Hangzhou Chenxiao Technologies Co. Ltd. + +OUI:40D855003* + ID_OUI_FROM_DATABASE=AlphaNavigation coltd + +OUI:40D855004* + ID_OUI_FROM_DATABASE=CR Magnetics, Inc. + +OUI:40D855005* + ID_OUI_FROM_DATABASE=Monarch Instrument + +OUI:40D855006* + ID_OUI_FROM_DATABASE=Bactest Limited + +OUI:40D855007* + ID_OUI_FROM_DATABASE=Digital Audio SA + +OUI:40D855008* + ID_OUI_FROM_DATABASE=Kaori Industria Eletronica Ltda + +OUI:40D855009* + ID_OUI_FROM_DATABASE=ClearSite Communications Inc. + +OUI:40D85500A* + ID_OUI_FROM_DATABASE=Sarana Sistem Mikro + +OUI:40D85500B* + ID_OUI_FROM_DATABASE=Aircell + +OUI:40D85500C* + ID_OUI_FROM_DATABASE=Aplex Technology Inc. + +OUI:40D85500D* + ID_OUI_FROM_DATABASE=HuNS + +OUI:40D85500E* + ID_OUI_FROM_DATABASE=Brightwell Dispensers + +OUI:40D85500F* + ID_OUI_FROM_DATABASE=DIGITAL DYNAMICS, INC. + +OUI:40D855010* + ID_OUI_FROM_DATABASE=APG CASH DRAWER + +OUI:40D855011* + ID_OUI_FROM_DATABASE=Flexim Security Oy + +OUI:40D855012* + ID_OUI_FROM_DATABASE=Sencon Inc. + +OUI:40D855013* + ID_OUI_FROM_DATABASE=Grande Vitesse Systems + +OUI:40D855014* + ID_OUI_FROM_DATABASE=Toni Studio + +OUI:40D855015* + ID_OUI_FROM_DATABASE=BITMILL srl + +OUI:40D855016* + ID_OUI_FROM_DATABASE=Par-Tech, Inc. + +OUI:40D855017* + ID_OUI_FROM_DATABASE=Franke Aquarotter GmbH + +OUI:40D855018* + ID_OUI_FROM_DATABASE=STANEO SAS + +OUI:40D855019* + ID_OUI_FROM_DATABASE=Nautel Limited + +OUI:40D85501A* + ID_OUI_FROM_DATABASE=MEGGITT DEFENSE SYSTEMS INC. + +OUI:40D85501B* + ID_OUI_FROM_DATABASE=Audio Enhancement + +OUI:40D85501C* + ID_OUI_FROM_DATABASE=BERG + +OUI:40D85501D* + ID_OUI_FROM_DATABASE=Scharco Elektronik GmbH + +OUI:40D85501E* + ID_OUI_FROM_DATABASE=A2S + +OUI:40D85501F* + ID_OUI_FROM_DATABASE=Sitep Italia Spa + +OUI:40D855020* + ID_OUI_FROM_DATABASE=ENTEC Electric & Electronic CO., LTD. + +OUI:40D855021* + ID_OUI_FROM_DATABASE=SMT D.O.O. + +OUI:40D855022* + ID_OUI_FROM_DATABASE=Digimerge Technology Inc + +OUI:40D855023* + ID_OUI_FROM_DATABASE=Shanghai o-solution electronics & Technology Co., Ltd. + +OUI:40D855024* + ID_OUI_FROM_DATABASE=Electrical Geodesics Incorporated + +OUI:40D855025* + ID_OUI_FROM_DATABASE=Rosemount Analytical + +OUI:40D855026* + ID_OUI_FROM_DATABASE=Symetrics Industries + +OUI:40D855027* + ID_OUI_FROM_DATABASE=GRUPO EPELSA S.L. + +OUI:40D855028* + ID_OUI_FROM_DATABASE=Integrated Control Corp. + +OUI:40D855029* + ID_OUI_FROM_DATABASE=Depro Electronique + +OUI:40D85502A* + ID_OUI_FROM_DATABASE=Tinkerforge GmbH + +OUI:40D85502B* + ID_OUI_FROM_DATABASE=Nomatronics + +OUI:40D85502C* + ID_OUI_FROM_DATABASE=InventLab s.c. + +OUI:40D85502D* + ID_OUI_FROM_DATABASE=Elgama Sistemos + +OUI:40D85502E* + ID_OUI_FROM_DATABASE=Circuitec Ind. Equip. Eletr. Ltda + +OUI:40D85502F* + ID_OUI_FROM_DATABASE=Adva Technologies + +OUI:40D855030* + ID_OUI_FROM_DATABASE=Tecnologias Plexus + +OUI:40D855031* + ID_OUI_FROM_DATABASE=Dommel GmbH + +OUI:40D855032* + ID_OUI_FROM_DATABASE=BETTINI SRL + +OUI:40D855033* + ID_OUI_FROM_DATABASE=Ermes Elettronica s.r.l. + +OUI:40D855034* + ID_OUI_FROM_DATABASE=Dacom West GmbH + +OUI:40D855035* + ID_OUI_FROM_DATABASE=Mesotech International, Inc. + +OUI:40D855036* + ID_OUI_FROM_DATABASE=Schweers informationstechnologie GmbH + +OUI:40D855037* + ID_OUI_FROM_DATABASE=Software Workshop + +OUI:40D855038* + ID_OUI_FROM_DATABASE=Special Measurements Labs LLC + +OUI:40D855039* + ID_OUI_FROM_DATABASE=CI Systems Ltd + +OUI:40D85503A* + ID_OUI_FROM_DATABASE=Socus networks + +OUI:40D85503B* + ID_OUI_FROM_DATABASE=Telcomkorea + +OUI:40D85503C* + ID_OUI_FROM_DATABASE=Computer System Co.,Ltd + +OUI:40D85503D* + ID_OUI_FROM_DATABASE=Tekelek Europe Ltd + +OUI:40D85503E* + ID_OUI_FROM_DATABASE=Vishay Celtron Technologies, Inc. + +OUI:40D85503F* + ID_OUI_FROM_DATABASE=UniSVR Global Information Technology Corp. + +OUI:40D855040* + ID_OUI_FROM_DATABASE=GHL Systems Berhad + +OUI:40D855041* + ID_OUI_FROM_DATABASE=T.Q.M. Itaca Technology s.r.l. + +OUI:40D855042* + ID_OUI_FROM_DATABASE=Mango Communicaitons Inc. + +OUI:40D855043* + ID_OUI_FROM_DATABASE=SchulerControl GmbH + +OUI:40D855044* + ID_OUI_FROM_DATABASE=An Chen Computer Co. Ltd. + +OUI:40D855045* + ID_OUI_FROM_DATABASE=Genadsystem + +OUI:40D855046* + ID_OUI_FROM_DATABASE=Circuitlink Pty Ltd + +OUI:40D855047* + ID_OUI_FROM_DATABASE=Dos&Donts SRL + +OUI:40D855048* + ID_OUI_FROM_DATABASE=GENERAL DYNAMICS C4 SYSTEMS + +OUI:40D855049* + ID_OUI_FROM_DATABASE=Thermo Fisher Scientific + +OUI:40D85504A* + ID_OUI_FROM_DATABASE=Gateway Technologies SA de CV + +OUI:40D85504B* + ID_OUI_FROM_DATABASE=Vital Tech Industria e Comercio Ltda + +OUI:40D85504C* + ID_OUI_FROM_DATABASE=Serveron Corporation + +OUI:40D85504D* + ID_OUI_FROM_DATABASE=MACHINEPERFORMANCE ApS + +OUI:40D85504E* + ID_OUI_FROM_DATABASE=Honeywell Aerospace/Intelligent Automation Corp. + +OUI:40D85504F* + ID_OUI_FROM_DATABASE=Haein S&S Co., Ltd + +OUI:40D855050* + ID_OUI_FROM_DATABASE=ATG UV Technology + +OUI:40D855051* + ID_OUI_FROM_DATABASE=CS Instruments Asia + +OUI:40D855052* + ID_OUI_FROM_DATABASE=DAN ELECTRONICS SYSTEM (P) LIMITED + +OUI:40D855053* + ID_OUI_FROM_DATABASE=Amantys Ltd + +OUI:40D855054* + ID_OUI_FROM_DATABASE=VITEC + +OUI:40D855055* + ID_OUI_FROM_DATABASE=Helmholtz Zentrum Dresden Rossendorf e.V. + +OUI:40D855056* + ID_OUI_FROM_DATABASE=GROUP 57 + +OUI:40D855057* + ID_OUI_FROM_DATABASE=Tammermatic Group Oy + +OUI:40D855058* + ID_OUI_FROM_DATABASE=Energy Team S.p.A. + +OUI:40D855059* + ID_OUI_FROM_DATABASE=COLONIAL ASSEMBLY and DESIGN + +OUI:40D85505A* + ID_OUI_FROM_DATABASE=Ultra Electronics Flightline Systems + +OUI:40D85505B* + ID_OUI_FROM_DATABASE=Data Flow Systems, Inc. + +OUI:40D85505C* + ID_OUI_FROM_DATABASE=Rosslare Enterprises Limited + +OUI:40D85505D* + ID_OUI_FROM_DATABASE=Leica Biosystems + +OUI:40D85505E* + ID_OUI_FROM_DATABASE=inoage GmbH + +OUI:40D85505F* + ID_OUI_FROM_DATABASE=EPSa GmbH + +OUI:40D855060* + ID_OUI_FROM_DATABASE=Aplex Technology Inc. + +OUI:40D855061* + ID_OUI_FROM_DATABASE=Cominfo, Inc. + +OUI:40D855062* + ID_OUI_FROM_DATABASE=Tech Source Inc + +OUI:40D855063* + ID_OUI_FROM_DATABASE=Protonic Holland + +OUI:40D855064* + ID_OUI_FROM_DATABASE=HIPODROMO DE AGUA CALIENTE, S.A. DE C.V. + +OUI:40D855065* + ID_OUI_FROM_DATABASE=Parallel Wireless + +OUI:40D855066* + ID_OUI_FROM_DATABASE=TeraTron GmbH + +OUI:40D855067* + ID_OUI_FROM_DATABASE=Tronic Control ltd. + +OUI:40D855068* + ID_OUI_FROM_DATABASE=Oki Seatec Co., Ltd. + +OUI:40D855069* + ID_OUI_FROM_DATABASE=Smartcom-Bulgaria AD + +OUI:40D85506A* + ID_OUI_FROM_DATABASE=elgris + +OUI:40D85506B* + ID_OUI_FROM_DATABASE=BRS Sistemas Eletronicos + +OUI:40D85506C* + ID_OUI_FROM_DATABASE=Rohde&Schwarz Topex SA + +OUI:40D85506D* + ID_OUI_FROM_DATABASE=BroadSoft, INC + +OUI:40D85506E* + ID_OUI_FROM_DATABASE=C-COM Satellite Systems Inc. + +OUI:40D85506F* + ID_OUI_FROM_DATABASE=DORLET SA + +OUI:40D855070* + ID_OUI_FROM_DATABASE=JSC Electrical Equipment Factory + +OUI:40D855071* + ID_OUI_FROM_DATABASE=TATTILE SRL + +OUI:40D855072* + ID_OUI_FROM_DATABASE=CT Company + +OUI:40D855073* + ID_OUI_FROM_DATABASE=Diamond Technologies, Inc + +OUI:40D855074* + ID_OUI_FROM_DATABASE=Sphere Medical Ltd + +OUI:40D855075* + ID_OUI_FROM_DATABASE=Teraflops + +OUI:000000* + ID_OUI_FROM_DATABASE=XEROX CORPORATION + +OUI:000001* + ID_OUI_FROM_DATABASE=XEROX CORPORATION + +OUI:000002* + ID_OUI_FROM_DATABASE=XEROX CORPORATION + +OUI:000003* + ID_OUI_FROM_DATABASE=XEROX CORPORATION + +OUI:000004* + ID_OUI_FROM_DATABASE=XEROX CORPORATION + +OUI:000005* + ID_OUI_FROM_DATABASE=XEROX CORPORATION + +OUI:000006* + ID_OUI_FROM_DATABASE=XEROX CORPORATION + +OUI:000007* + ID_OUI_FROM_DATABASE=XEROX CORPORATION + +OUI:000008* + ID_OUI_FROM_DATABASE=XEROX CORPORATION + +OUI:000009* + ID_OUI_FROM_DATABASE=XEROX CORPORATION + +OUI:00000A* + ID_OUI_FROM_DATABASE=OMRON TATEISI ELECTRONICS CO. + +OUI:00000B* + ID_OUI_FROM_DATABASE=MATRIX CORPORATION + +OUI:00000C* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00000D* + ID_OUI_FROM_DATABASE=FIBRONICS LTD. + +OUI:00000E* + ID_OUI_FROM_DATABASE=FUJITSU LIMITED + +OUI:00000F* + ID_OUI_FROM_DATABASE=NEXT, INC. + +OUI:000010* + ID_OUI_FROM_DATABASE=SYTEK INC. + +OUI:000011* + ID_OUI_FROM_DATABASE=NORMEREL SYSTEMES + +OUI:000012* + ID_OUI_FROM_DATABASE=INFORMATION TECHNOLOGY LIMITED + +OUI:000013* + ID_OUI_FROM_DATABASE=CAMEX + +OUI:000014* + ID_OUI_FROM_DATABASE=NETRONIX + +OUI:000015* + ID_OUI_FROM_DATABASE=DATAPOINT CORPORATION + +OUI:000016* + ID_OUI_FROM_DATABASE=DU PONT PIXEL SYSTEMS . + +OUI:000017* + ID_OUI_FROM_DATABASE=TEKELEC + +OUI:000018* + ID_OUI_FROM_DATABASE=WEBSTER COMPUTER CORPORATION + +OUI:000019* + ID_OUI_FROM_DATABASE=APPLIED DYNAMICS INTERNATIONAL + +OUI:00001A* + ID_OUI_FROM_DATABASE=ADVANCED MICRO DEVICES + +OUI:00001B* + ID_OUI_FROM_DATABASE=NOVELL INC. + +OUI:00001C* + ID_OUI_FROM_DATABASE=BELL TECHNOLOGIES + +OUI:00001D* + ID_OUI_FROM_DATABASE=CABLETRON SYSTEMS, INC. + +OUI:00001E* + ID_OUI_FROM_DATABASE=TELSIST INDUSTRIA ELECTRONICA + +OUI:00001F* + ID_OUI_FROM_DATABASE=Telco Systems, Inc. + +OUI:000020* + ID_OUI_FROM_DATABASE=DATAINDUSTRIER DIAB AB + +OUI:000021* + ID_OUI_FROM_DATABASE=SUREMAN COMP. & COMMUN. CORP. + +OUI:000022* + ID_OUI_FROM_DATABASE=VISUAL TECHNOLOGY INC. + +OUI:000023* + ID_OUI_FROM_DATABASE=ABB INDUSTRIAL SYSTEMS AB + +OUI:000024* + ID_OUI_FROM_DATABASE=CONNECT AS + +OUI:000025* + ID_OUI_FROM_DATABASE=RAMTEK CORP. + +OUI:000026* + ID_OUI_FROM_DATABASE=SHA-KEN CO., LTD. + +OUI:000027* + ID_OUI_FROM_DATABASE=JAPAN RADIO COMPANY + +OUI:000028* + ID_OUI_FROM_DATABASE=PRODIGY SYSTEMS CORPORATION + +OUI:000029* + ID_OUI_FROM_DATABASE=IMC NETWORKS CORP. + +OUI:00002A* + ID_OUI_FROM_DATABASE=TRW - SEDD/INP + +OUI:00002B* + ID_OUI_FROM_DATABASE=CRISP AUTOMATION, INC + +OUI:00002C* + ID_OUI_FROM_DATABASE=AUTOTOTE LIMITED + +OUI:00002D* + ID_OUI_FROM_DATABASE=CHROMATICS INC + +OUI:00002E* + ID_OUI_FROM_DATABASE=SOCIETE EVIRA + +OUI:00002F* + ID_OUI_FROM_DATABASE=TIMEPLEX INC. + +OUI:000030* + ID_OUI_FROM_DATABASE=VG LABORATORY SYSTEMS LTD + +OUI:000031* + ID_OUI_FROM_DATABASE=QPSX COMMUNICATIONS PTY LTD + +OUI:000032* + ID_OUI_FROM_DATABASE=Marconi plc + +OUI:000033* + ID_OUI_FROM_DATABASE=EGAN MACHINERY COMPANY + +OUI:000034* + ID_OUI_FROM_DATABASE=NETWORK RESOURCES CORPORATION + +OUI:000035* + ID_OUI_FROM_DATABASE=SPECTRAGRAPHICS CORPORATION + +OUI:000036* + ID_OUI_FROM_DATABASE=ATARI CORPORATION + +OUI:000037* + ID_OUI_FROM_DATABASE=OXFORD METRICS LIMITED + +OUI:000038* + ID_OUI_FROM_DATABASE=CSS LABS + +OUI:000039* + ID_OUI_FROM_DATABASE=TOSHIBA CORPORATION + +OUI:00003A* + ID_OUI_FROM_DATABASE=CHYRON CORPORATION + +OUI:00003B* + ID_OUI_FROM_DATABASE=i Controls, Inc. + +OUI:00003C* + ID_OUI_FROM_DATABASE=AUSPEX SYSTEMS INC. + +OUI:00003D* + ID_OUI_FROM_DATABASE=UNISYS + +OUI:00003E* + ID_OUI_FROM_DATABASE=SIMPACT + +OUI:00003F* + ID_OUI_FROM_DATABASE=SYNTREX, INC. + +OUI:000040* + ID_OUI_FROM_DATABASE=APPLICON, INC. + +OUI:000041* + ID_OUI_FROM_DATABASE=ICE CORPORATION + +OUI:000042* + ID_OUI_FROM_DATABASE=METIER MANAGEMENT SYSTEMS LTD. + +OUI:000043* + ID_OUI_FROM_DATABASE=MICRO TECHNOLOGY + +OUI:000044* + ID_OUI_FROM_DATABASE=CASTELLE CORPORATION + +OUI:000045* + ID_OUI_FROM_DATABASE=FORD AEROSPACE & COMM. CORP. + +OUI:000046* + ID_OUI_FROM_DATABASE=OLIVETTI NORTH AMERICA + +OUI:000047* + ID_OUI_FROM_DATABASE=NICOLET INSTRUMENTS CORP. + +OUI:000048* + ID_OUI_FROM_DATABASE=SEIKO EPSON CORPORATION + +OUI:000049* + ID_OUI_FROM_DATABASE=APRICOT COMPUTERS, LTD + +OUI:00004A* + ID_OUI_FROM_DATABASE=ADC CODENOLL TECHNOLOGY CORP. + +OUI:00004B* + ID_OUI_FROM_DATABASE=ICL DATA OY + +OUI:00004C* + ID_OUI_FROM_DATABASE=NEC CORPORATION + +OUI:00004D* + ID_OUI_FROM_DATABASE=DCI CORPORATION + +OUI:00004E* + ID_OUI_FROM_DATABASE=AMPEX CORPORATION + +OUI:00004F* + ID_OUI_FROM_DATABASE=LOGICRAFT, INC. + +OUI:000050* + ID_OUI_FROM_DATABASE=RADISYS CORPORATION + +OUI:000051* + ID_OUI_FROM_DATABASE=HOB ELECTRONIC GMBH & CO. KG + +OUI:000052* + ID_OUI_FROM_DATABASE=Intrusion.com, Inc. + +OUI:000053* + ID_OUI_FROM_DATABASE=COMPUCORP + +OUI:000054* + ID_OUI_FROM_DATABASE=MODICON, INC. + +OUI:000055* + ID_OUI_FROM_DATABASE=COMMISSARIAT A L`ENERGIE ATOM. + +OUI:000056* + ID_OUI_FROM_DATABASE=DR. B. STRUCK + +OUI:000057* + ID_OUI_FROM_DATABASE=SCITEX CORPORATION LTD. + +OUI:000058* + ID_OUI_FROM_DATABASE=RACORE COMPUTER PRODUCTS INC. + +OUI:000059* + ID_OUI_FROM_DATABASE=HELLIGE GMBH + +OUI:00005A* + ID_OUI_FROM_DATABASE=SysKonnect GmbH + +OUI:00005B* + ID_OUI_FROM_DATABASE=ELTEC ELEKTRONIK AG + +OUI:00005C* + ID_OUI_FROM_DATABASE=TELEMATICS INTERNATIONAL INC. + +OUI:00005D* + ID_OUI_FROM_DATABASE=CS TELECOM + +OUI:00005E* + ID_OUI_FROM_DATABASE=USC INFORMATION SCIENCES INST + +OUI:00005F* + ID_OUI_FROM_DATABASE=SUMITOMO ELECTRIC IND., LTD. + +OUI:000060* + ID_OUI_FROM_DATABASE=KONTRON ELEKTRONIK GMBH + +OUI:000061* + ID_OUI_FROM_DATABASE=GATEWAY COMMUNICATIONS + +OUI:000062* + ID_OUI_FROM_DATABASE=BULL HN INFORMATION SYSTEMS + +OUI:000063* + ID_OUI_FROM_DATABASE=BARCO CONTROL ROOMS GMBH + +OUI:000064* + ID_OUI_FROM_DATABASE=YOKOGAWA DIGITAL COMPUTER CORP + +OUI:000065* + ID_OUI_FROM_DATABASE=Network General Corporation + +OUI:000066* + ID_OUI_FROM_DATABASE=TALARIS SYSTEMS, INC. + +OUI:000067* + ID_OUI_FROM_DATABASE=SOFT * RITE, INC. + +OUI:000068* + ID_OUI_FROM_DATABASE=ROSEMOUNT CONTROLS + +OUI:000069* + ID_OUI_FROM_DATABASE=CONCORD COMMUNICATIONS INC + +OUI:00006A* + ID_OUI_FROM_DATABASE=COMPUTER CONSOLES INC. + +OUI:00006B* + ID_OUI_FROM_DATABASE=SILICON GRAPHICS INC./MIPS + +OUI:00006D* + ID_OUI_FROM_DATABASE=CRAY COMMUNICATIONS, LTD. + +OUI:00006E* + ID_OUI_FROM_DATABASE=ARTISOFT, INC. + +OUI:00006F* + ID_OUI_FROM_DATABASE=Madge Ltd. + +OUI:000070* + ID_OUI_FROM_DATABASE=HCL LIMITED + +OUI:000071* + ID_OUI_FROM_DATABASE=ADRA SYSTEMS INC. + +OUI:000072* + ID_OUI_FROM_DATABASE=MINIWARE TECHNOLOGY + +OUI:000073* + ID_OUI_FROM_DATABASE=SIECOR CORPORATION + +OUI:000074* + ID_OUI_FROM_DATABASE=RICOH COMPANY LTD. + +OUI:000075* + ID_OUI_FROM_DATABASE=Nortel Networks + +OUI:000076* + ID_OUI_FROM_DATABASE=ABEKAS VIDEO SYSTEM + +OUI:000077* + ID_OUI_FROM_DATABASE=INTERPHASE CORPORATION + +OUI:000078* + ID_OUI_FROM_DATABASE=LABTAM LIMITED + +OUI:000079* + ID_OUI_FROM_DATABASE=NETWORTH INCORPORATED + +OUI:00007A* + ID_OUI_FROM_DATABASE=DANA COMPUTER INC. + +OUI:00007B* + ID_OUI_FROM_DATABASE=RESEARCH MACHINES + +OUI:00007C* + ID_OUI_FROM_DATABASE=AMPERE INCORPORATED + +OUI:00007D* + ID_OUI_FROM_DATABASE=Oracle Corporation + +OUI:00007E* + ID_OUI_FROM_DATABASE=CLUSTRIX CORPORATION + +OUI:00007F* + ID_OUI_FROM_DATABASE=LINOTYPE-HELL AG + +OUI:000080* + ID_OUI_FROM_DATABASE=CRAY COMMUNICATIONS A/S + +OUI:000081* + ID_OUI_FROM_DATABASE=BAY NETWORKS + +OUI:000082* + ID_OUI_FROM_DATABASE=LECTRA SYSTEMES SA + +OUI:000083* + ID_OUI_FROM_DATABASE=TADPOLE TECHNOLOGY PLC + +OUI:000084* + ID_OUI_FROM_DATABASE=SUPERNET + +OUI:000085* + ID_OUI_FROM_DATABASE=CANON INC. + +OUI:000086* + ID_OUI_FROM_DATABASE=MEGAHERTZ CORPORATION + +OUI:000087* + ID_OUI_FROM_DATABASE=HITACHI, LTD. + +OUI:000088* + ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc. + +OUI:000089* + ID_OUI_FROM_DATABASE=CAYMAN SYSTEMS INC. + +OUI:00008A* + ID_OUI_FROM_DATABASE=DATAHOUSE INFORMATION SYSTEMS + +OUI:00008B* + ID_OUI_FROM_DATABASE=INFOTRON + +OUI:00008C* + ID_OUI_FROM_DATABASE=Alloy Computer Products (Australia) Pty Ltd + +OUI:00008D* + ID_OUI_FROM_DATABASE=Cryptek Inc. + +OUI:00008E* + ID_OUI_FROM_DATABASE=SOLBOURNE COMPUTER, INC. + +OUI:00008F* + ID_OUI_FROM_DATABASE=Raytheon + +OUI:000090* + ID_OUI_FROM_DATABASE=MICROCOM + +OUI:000091* + ID_OUI_FROM_DATABASE=ANRITSU CORPORATION + +OUI:000092* + ID_OUI_FROM_DATABASE=COGENT DATA TECHNOLOGIES + +OUI:000093* + ID_OUI_FROM_DATABASE=PROTEON INC. + +OUI:000094* + ID_OUI_FROM_DATABASE=ASANTE TECHNOLOGIES + +OUI:000095* + ID_OUI_FROM_DATABASE=SONY TEKTRONIX CORP. + +OUI:000096* + ID_OUI_FROM_DATABASE=MARCONI ELECTRONICS LTD. + +OUI:000097* + ID_OUI_FROM_DATABASE=EMC Corporation + +OUI:000098* + ID_OUI_FROM_DATABASE=CROSSCOMM CORPORATION + +OUI:000099* + ID_OUI_FROM_DATABASE=MTX, INC. + +OUI:00009A* + ID_OUI_FROM_DATABASE=RC COMPUTER A/S + +OUI:00009B* + ID_OUI_FROM_DATABASE=INFORMATION INTERNATIONAL, INC + +OUI:00009C* + ID_OUI_FROM_DATABASE=ROLM MIL-SPEC COMPUTERS + +OUI:00009D* + ID_OUI_FROM_DATABASE=LOCUS COMPUTING CORPORATION + +OUI:00009E* + ID_OUI_FROM_DATABASE=MARLI S.A. + +OUI:00009F* + ID_OUI_FROM_DATABASE=AMERISTAR TECHNOLOGIES INC. + +OUI:0000A0* + ID_OUI_FROM_DATABASE=SANYO Electric Co., Ltd. + +OUI:0000A1* + ID_OUI_FROM_DATABASE=MARQUETTE ELECTRIC CO. + +OUI:0000A2* + ID_OUI_FROM_DATABASE=BAY NETWORKS + +OUI:0000A3* + ID_OUI_FROM_DATABASE=NETWORK APPLICATION TECHNOLOGY + +OUI:0000A4* + ID_OUI_FROM_DATABASE=ACORN COMPUTERS LIMITED + +OUI:0000A5* + ID_OUI_FROM_DATABASE=Tattile SRL + +OUI:0000A6* + ID_OUI_FROM_DATABASE=NETWORK GENERAL CORPORATION + +OUI:0000A7* + ID_OUI_FROM_DATABASE=NETWORK COMPUTING DEVICES INC. + +OUI:0000A8* + ID_OUI_FROM_DATABASE=STRATUS COMPUTER INC. + +OUI:0000A9* + ID_OUI_FROM_DATABASE=NETWORK SYSTEMS CORP. + +OUI:0000AA* + ID_OUI_FROM_DATABASE=XEROX CORPORATION + +OUI:0000AB* + ID_OUI_FROM_DATABASE=LOGIC MODELING CORPORATION + +OUI:0000AC* + ID_OUI_FROM_DATABASE=CONWARE COMPUTER CONSULTING + +OUI:0000AD* + ID_OUI_FROM_DATABASE=BRUKER INSTRUMENTS INC. + +OUI:0000AE* + ID_OUI_FROM_DATABASE=DASSAULT ELECTRONIQUE + +OUI:0000AF* + ID_OUI_FROM_DATABASE=NUCLEAR DATA INSTRUMENTATION + +OUI:0000B0* + ID_OUI_FROM_DATABASE=RND-RAD NETWORK DEVICES + +OUI:0000B1* + ID_OUI_FROM_DATABASE=ALPHA MICROSYSTEMS INC. + +OUI:0000B2* + ID_OUI_FROM_DATABASE=TELEVIDEO SYSTEMS, INC. + +OUI:0000B3* + ID_OUI_FROM_DATABASE=CIMLINC INCORPORATED + +OUI:0000B4* + ID_OUI_FROM_DATABASE=EDIMAX COMPUTER COMPANY + +OUI:0000B5* + ID_OUI_FROM_DATABASE=DATABILITY SOFTWARE SYS. INC. + +OUI:0000B6* + ID_OUI_FROM_DATABASE=MICRO-MATIC RESEARCH + +OUI:0000B7* + ID_OUI_FROM_DATABASE=DOVE COMPUTER CORPORATION + +OUI:0000B8* + ID_OUI_FROM_DATABASE=SEIKOSHA CO., LTD. + +OUI:0000B9* + ID_OUI_FROM_DATABASE=MCDONNELL DOUGLAS COMPUTER SYS + +OUI:0000BA* + ID_OUI_FROM_DATABASE=SIIG, INC. + +OUI:0000BB* + ID_OUI_FROM_DATABASE=TRI-DATA + +OUI:0000BC* + ID_OUI_FROM_DATABASE=Rockwell Automation + +OUI:0000BD* + ID_OUI_FROM_DATABASE=MITSUBISHI CABLE COMPANY + +OUI:0000BE* + ID_OUI_FROM_DATABASE=THE NTI GROUP + +OUI:0000BF* + ID_OUI_FROM_DATABASE=SYMMETRIC COMPUTER SYSTEMS + +OUI:0000C0* + ID_OUI_FROM_DATABASE=WESTERN DIGITAL CORPORATION + +OUI:0000C1* + ID_OUI_FROM_DATABASE=Madge Ltd. + +OUI:0000C2* + ID_OUI_FROM_DATABASE=INFORMATION PRESENTATION TECH. + +OUI:0000C3* + ID_OUI_FROM_DATABASE=HARRIS CORP COMPUTER SYS DIV + +OUI:0000C4* + ID_OUI_FROM_DATABASE=WATERS DIV. OF MILLIPORE + +OUI:0000C5* + ID_OUI_FROM_DATABASE=FARALLON COMPUTING/NETOPIA + +OUI:0000C6* + ID_OUI_FROM_DATABASE=EON SYSTEMS + +OUI:0000C7* + ID_OUI_FROM_DATABASE=ARIX CORPORATION + +OUI:0000C8* + ID_OUI_FROM_DATABASE=ALTOS COMPUTER SYSTEMS + +OUI:0000C9* + ID_OUI_FROM_DATABASE=Emulex Corporation + +OUI:0000CA* + ID_OUI_FROM_DATABASE=ARRIS International + +OUI:0000CB* + ID_OUI_FROM_DATABASE=COMPU-SHACK ELECTRONIC GMBH + +OUI:0000CC* + ID_OUI_FROM_DATABASE=DENSAN CO., LTD. + +OUI:0000CD* + ID_OUI_FROM_DATABASE=Allied Telesis Labs Ltd + +OUI:0000CE* + ID_OUI_FROM_DATABASE=MEGADATA CORP. + +OUI:0000CF* + ID_OUI_FROM_DATABASE=HAYES MICROCOMPUTER PRODUCTS + +OUI:0000D0* + ID_OUI_FROM_DATABASE=DEVELCON ELECTRONICS LTD. + +OUI:0000D1* + ID_OUI_FROM_DATABASE=ADAPTEC INCORPORATED + +OUI:0000D2* + ID_OUI_FROM_DATABASE=SBE, INC. + +OUI:0000D3* + ID_OUI_FROM_DATABASE=WANG LABORATORIES INC. + +OUI:0000D4* + ID_OUI_FROM_DATABASE=PURE DATA LTD. + +OUI:0000D5* + ID_OUI_FROM_DATABASE=MICROGNOSIS INTERNATIONAL + +OUI:0000D6* + ID_OUI_FROM_DATABASE=PUNCH LINE HOLDING + +OUI:0000D7* + ID_OUI_FROM_DATABASE=DARTMOUTH COLLEGE + +OUI:0000D8* + ID_OUI_FROM_DATABASE=NOVELL, INC. + +OUI:0000D9* + ID_OUI_FROM_DATABASE=NIPPON TELEGRAPH & TELEPHONE + +OUI:0000DA* + ID_OUI_FROM_DATABASE=ATEX + +OUI:0000DB* + ID_OUI_FROM_DATABASE=British Telecommunications plc + +OUI:0000DC* + ID_OUI_FROM_DATABASE=HAYES MICROCOMPUTER PRODUCTS + +OUI:0000DD* + ID_OUI_FROM_DATABASE=TCL INCORPORATED + +OUI:0000DE* + ID_OUI_FROM_DATABASE=CETIA + +OUI:0000DF* + ID_OUI_FROM_DATABASE=BELL & HOWELL PUB SYS DIV + +OUI:0000E0* + ID_OUI_FROM_DATABASE=QUADRAM CORP. + +OUI:0000E1* + ID_OUI_FROM_DATABASE=GRID SYSTEMS + +OUI:0000E2* + ID_OUI_FROM_DATABASE=ACER TECHNOLOGIES CORP. + +OUI:0000E3* + ID_OUI_FROM_DATABASE=INTEGRATED MICRO PRODUCTS LTD + +OUI:0000E4* + ID_OUI_FROM_DATABASE=IN2 GROUPE INTERTECHNIQUE + +OUI:0000E5* + ID_OUI_FROM_DATABASE=SIGMEX LTD. + +OUI:0000E6* + ID_OUI_FROM_DATABASE=APTOR PRODUITS DE COMM INDUST + +OUI:0000E7* + ID_OUI_FROM_DATABASE=STAR GATE TECHNOLOGIES + +OUI:0000E8* + ID_OUI_FROM_DATABASE=ACCTON TECHNOLOGY CORP. + +OUI:0000E9* + ID_OUI_FROM_DATABASE=ISICAD, INC. + +OUI:0000EA* + ID_OUI_FROM_DATABASE=UPNOD AB + +OUI:0000EB* + ID_OUI_FROM_DATABASE=MATSUSHITA COMM. IND. CO. LTD. + +OUI:0000EC* + ID_OUI_FROM_DATABASE=MICROPROCESS + +OUI:0000ED* + ID_OUI_FROM_DATABASE=APRIL + +OUI:0000EE* + ID_OUI_FROM_DATABASE=NETWORK DESIGNERS, LTD. + +OUI:0000EF* + ID_OUI_FROM_DATABASE=KTI + +OUI:0000F0* + ID_OUI_FROM_DATABASE=SAMSUNG ELECTRONICS CO., LTD. + +OUI:0000F1* + ID_OUI_FROM_DATABASE=MAGNA COMPUTER CORPORATION + +OUI:0000F2* + ID_OUI_FROM_DATABASE=SPIDER COMMUNICATIONS + +OUI:0000F3* + ID_OUI_FROM_DATABASE=GANDALF DATA LIMITED + +OUI:0000F4* + ID_OUI_FROM_DATABASE=Allied Telesis + +OUI:0000F5* + ID_OUI_FROM_DATABASE=DIAMOND SALES LIMITED + +OUI:0000F6* + ID_OUI_FROM_DATABASE=APPLIED MICROSYSTEMS CORP. + +OUI:0000F7* + ID_OUI_FROM_DATABASE=YOUTH KEEP ENTERPRISE CO LTD + +OUI:0000F8* + ID_OUI_FROM_DATABASE=DIGITAL EQUIPMENT CORPORATION + +OUI:0000F9* + ID_OUI_FROM_DATABASE=QUOTRON SYSTEMS INC. + +OUI:0000FA* + ID_OUI_FROM_DATABASE=MICROSAGE COMPUTER SYSTEMS INC + +OUI:0000FB* + ID_OUI_FROM_DATABASE=RECHNER ZUR KOMMUNIKATION + +OUI:0000FC* + ID_OUI_FROM_DATABASE=MEIKO + +OUI:0000FD* + ID_OUI_FROM_DATABASE=HIGH LEVEL HARDWARE + +OUI:0000FE* + ID_OUI_FROM_DATABASE=ANNAPOLIS MICRO SYSTEMS + +OUI:0000FF* + ID_OUI_FROM_DATABASE=CAMTEC ELECTRONICS LTD. + +OUI:000100* + ID_OUI_FROM_DATABASE=EQUIP'TRANS + +OUI:000102* + ID_OUI_FROM_DATABASE=3COM CORPORATION + +OUI:000103* + ID_OUI_FROM_DATABASE=3COM CORPORATION + +OUI:000104* + ID_OUI_FROM_DATABASE=DVICO Co., Ltd. + +OUI:000105* + ID_OUI_FROM_DATABASE=Beckhoff Automation GmbH + +OUI:000106* + ID_OUI_FROM_DATABASE=Tews Datentechnik GmbH + +OUI:000107* + ID_OUI_FROM_DATABASE=Leiser GmbH + +OUI:000108* + ID_OUI_FROM_DATABASE=AVLAB Technology, Inc. + +OUI:000109* + ID_OUI_FROM_DATABASE=Nagano Japan Radio Co., Ltd. + +OUI:00010A* + ID_OUI_FROM_DATABASE=CIS TECHNOLOGY INC. + +OUI:00010B* + ID_OUI_FROM_DATABASE=Space CyberLink, Inc. + +OUI:00010C* + ID_OUI_FROM_DATABASE=System Talks Inc. + +OUI:00010D* + ID_OUI_FROM_DATABASE=CORECO, INC. + +OUI:00010E* + ID_OUI_FROM_DATABASE=Bri-Link Technologies Co., Ltd + +OUI:00010F* + ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc. + +OUI:000110* + ID_OUI_FROM_DATABASE=Gotham Networks + +OUI:000111* + ID_OUI_FROM_DATABASE=iDigm Inc. + +OUI:000112* + ID_OUI_FROM_DATABASE=Shark Multimedia Inc. + +OUI:000113* + ID_OUI_FROM_DATABASE=OLYMPUS CORPORATION + +OUI:000114* + ID_OUI_FROM_DATABASE=KANDA TSUSHIN KOGYO CO., LTD. + +OUI:000115* + ID_OUI_FROM_DATABASE=EXTRATECH CORPORATION + +OUI:000116* + ID_OUI_FROM_DATABASE=Netspect Technologies, Inc. + +OUI:000117* + ID_OUI_FROM_DATABASE=CANAL + + +OUI:000118* + ID_OUI_FROM_DATABASE=EZ Digital Co., Ltd. + +OUI:000119* + ID_OUI_FROM_DATABASE=RTUnet (Australia) + +OUI:00011A* + ID_OUI_FROM_DATABASE=EEH DataLink GmbH + +OUI:00011B* + ID_OUI_FROM_DATABASE=Unizone Technologies, Inc. + +OUI:00011C* + ID_OUI_FROM_DATABASE=Universal Talkware Corporation + +OUI:00011D* + ID_OUI_FROM_DATABASE=Centillium Communications + +OUI:00011E* + ID_OUI_FROM_DATABASE=Precidia Technologies, Inc. + +OUI:00011F* + ID_OUI_FROM_DATABASE=RC Networks, Inc. + +OUI:000120* + ID_OUI_FROM_DATABASE=OSCILLOQUARTZ S.A. + +OUI:000121* + ID_OUI_FROM_DATABASE=Watchguard Technologies, Inc. + +OUI:000122* + ID_OUI_FROM_DATABASE=Trend Communications, Ltd. + +OUI:000123* + ID_OUI_FROM_DATABASE=DIGITAL ELECTRONICS CORP. + +OUI:000124* + ID_OUI_FROM_DATABASE=Acer Incorporated + +OUI:000125* + ID_OUI_FROM_DATABASE=YAESU MUSEN CO., LTD. + +OUI:000126* + ID_OUI_FROM_DATABASE=PAC Labs + +OUI:000127* + ID_OUI_FROM_DATABASE=OPEN Networks Pty Ltd + +OUI:000128* + ID_OUI_FROM_DATABASE=EnjoyWeb, Inc. + +OUI:000129* + ID_OUI_FROM_DATABASE=DFI Inc. + +OUI:00012A* + ID_OUI_FROM_DATABASE=Telematica Sistems Inteligente + +OUI:00012B* + ID_OUI_FROM_DATABASE=TELENET Co., Ltd. + +OUI:00012C* + ID_OUI_FROM_DATABASE=Aravox Technologies, Inc. + +OUI:00012D* + ID_OUI_FROM_DATABASE=Komodo Technology + +OUI:00012E* + ID_OUI_FROM_DATABASE=PC Partner Ltd. + +OUI:00012F* + ID_OUI_FROM_DATABASE=Twinhead International Corp + +OUI:000130* + ID_OUI_FROM_DATABASE=Extreme Networks + +OUI:000131* + ID_OUI_FROM_DATABASE=Bosch Security Systems, Inc. + +OUI:000132* + ID_OUI_FROM_DATABASE=Dranetz - BMI + +OUI:000133* + ID_OUI_FROM_DATABASE=KYOWA Electronic Instruments C + +OUI:000134* + ID_OUI_FROM_DATABASE=Selectron Systems AG + +OUI:000135* + ID_OUI_FROM_DATABASE=KDC Corp. + +OUI:000136* + ID_OUI_FROM_DATABASE=CyberTAN Technology, Inc. + +OUI:000137* + ID_OUI_FROM_DATABASE=IT Farm Corporation + +OUI:000138* + ID_OUI_FROM_DATABASE=XAVi Technologies Corp. + +OUI:000139* + ID_OUI_FROM_DATABASE=Point Multimedia Systems + +OUI:00013A* + ID_OUI_FROM_DATABASE=SHELCAD COMMUNICATIONS, LTD. + +OUI:00013B* + ID_OUI_FROM_DATABASE=BNA SYSTEMS + +OUI:00013C* + ID_OUI_FROM_DATABASE=TIW SYSTEMS + +OUI:00013D* + ID_OUI_FROM_DATABASE=RiscStation Ltd. + +OUI:00013E* + ID_OUI_FROM_DATABASE=Ascom Tateco AB + +OUI:00013F* + ID_OUI_FROM_DATABASE=Neighbor World Co., Ltd. + +OUI:000140* + ID_OUI_FROM_DATABASE=Sendtek Corporation + +OUI:000141* + ID_OUI_FROM_DATABASE=CABLE PRINT + +OUI:000142* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000143* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000144* + ID_OUI_FROM_DATABASE=EMC Corporation + +OUI:000145* + ID_OUI_FROM_DATABASE=WINSYSTEMS, INC. + +OUI:000146* + ID_OUI_FROM_DATABASE=Tesco Controls, Inc. + +OUI:000147* + ID_OUI_FROM_DATABASE=Zhone Technologies + +OUI:000148* + ID_OUI_FROM_DATABASE=X-traWeb Inc. + +OUI:000149* + ID_OUI_FROM_DATABASE=T.D.T. Transfer Data Test GmbH + +OUI:00014A* + ID_OUI_FROM_DATABASE=Sony Corporation + +OUI:00014B* + ID_OUI_FROM_DATABASE=Ennovate Networks, Inc. + +OUI:00014C* + ID_OUI_FROM_DATABASE=Berkeley Process Control + +OUI:00014D* + ID_OUI_FROM_DATABASE=Shin Kin Enterprises Co., Ltd + +OUI:00014E* + ID_OUI_FROM_DATABASE=WIN Enterprises, Inc. + +OUI:00014F* + ID_OUI_FROM_DATABASE=ADTRAN INC + +OUI:000150* + ID_OUI_FROM_DATABASE=GILAT COMMUNICATIONS, LTD. + +OUI:000151* + ID_OUI_FROM_DATABASE=Ensemble Communications + +OUI:000152* + ID_OUI_FROM_DATABASE=CHROMATEK INC. + +OUI:000153* + ID_OUI_FROM_DATABASE=ARCHTEK TELECOM CORPORATION + +OUI:000154* + ID_OUI_FROM_DATABASE=G3M Corporation + +OUI:000155* + ID_OUI_FROM_DATABASE=Promise Technology, Inc. + +OUI:000156* + ID_OUI_FROM_DATABASE=FIREWIREDIRECT.COM, INC. + +OUI:000157* + ID_OUI_FROM_DATABASE=SYSWAVE CO., LTD + +OUI:000158* + ID_OUI_FROM_DATABASE=Electro Industries/Gauge Tech + +OUI:000159* + ID_OUI_FROM_DATABASE=S1 Corporation + +OUI:00015A* + ID_OUI_FROM_DATABASE=Digital Video Broadcasting + +OUI:00015B* + ID_OUI_FROM_DATABASE=ITALTEL S.p.A/RF-UP-I + +OUI:00015C* + ID_OUI_FROM_DATABASE=CADANT INC. + +OUI:00015D* + ID_OUI_FROM_DATABASE=Oracle Corporation + +OUI:00015E* + ID_OUI_FROM_DATABASE=BEST TECHNOLOGY CO., LTD. + +OUI:00015F* + ID_OUI_FROM_DATABASE=DIGITAL DESIGN GmbH + +OUI:000160* + ID_OUI_FROM_DATABASE=ELMEX Co., LTD. + +OUI:000161* + ID_OUI_FROM_DATABASE=Meta Machine Technology + +OUI:000162* + ID_OUI_FROM_DATABASE=Cygnet Technologies, Inc. + +OUI:000163* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000164* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000165* + ID_OUI_FROM_DATABASE=AirSwitch Corporation + +OUI:000166* + ID_OUI_FROM_DATABASE=TC GROUP A/S + +OUI:000167* + ID_OUI_FROM_DATABASE=HIOKI E.E. CORPORATION + +OUI:000168* + ID_OUI_FROM_DATABASE=VITANA CORPORATION + +OUI:000169* + ID_OUI_FROM_DATABASE=Celestix Networks Pte Ltd. + +OUI:00016A* + ID_OUI_FROM_DATABASE=ALITEC + +OUI:00016B* + ID_OUI_FROM_DATABASE=LightChip, Inc. + +OUI:00016C* + ID_OUI_FROM_DATABASE=FOXCONN + +OUI:00016D* + ID_OUI_FROM_DATABASE=CarrierComm Inc. + +OUI:00016E* + ID_OUI_FROM_DATABASE=Conklin Corporation + +OUI:00016F* + ID_OUI_FROM_DATABASE=Inkel Corp. + +OUI:000170* + ID_OUI_FROM_DATABASE=ESE Embedded System Engineer'g + +OUI:000171* + ID_OUI_FROM_DATABASE=Allied Data Technologies + +OUI:000172* + ID_OUI_FROM_DATABASE=TechnoLand Co., LTD. + +OUI:000173* + ID_OUI_FROM_DATABASE=AMCC + +OUI:000174* + ID_OUI_FROM_DATABASE=CyberOptics Corporation + +OUI:000175* + ID_OUI_FROM_DATABASE=Radiant Communications Corp. + +OUI:000176* + ID_OUI_FROM_DATABASE=Orient Silver Enterprises + +OUI:000177* + ID_OUI_FROM_DATABASE=EDSL + +OUI:000178* + ID_OUI_FROM_DATABASE=MARGI Systems, Inc. + +OUI:000179* + ID_OUI_FROM_DATABASE=WIRELESS TECHNOLOGY, INC. + +OUI:00017A* + ID_OUI_FROM_DATABASE=Chengdu Maipu Electric Industrial Co., Ltd. + +OUI:00017B* + ID_OUI_FROM_DATABASE=Heidelberger Druckmaschinen AG + +OUI:00017C* + ID_OUI_FROM_DATABASE=AG-E GmbH + +OUI:00017D* + ID_OUI_FROM_DATABASE=ThermoQuest + +OUI:00017E* + ID_OUI_FROM_DATABASE=ADTEK System Science Co., Ltd. + +OUI:00017F* + ID_OUI_FROM_DATABASE=Experience Music Project + +OUI:000180* + ID_OUI_FROM_DATABASE=AOpen, Inc. + +OUI:000181* + ID_OUI_FROM_DATABASE=Nortel Networks + +OUI:000182* + ID_OUI_FROM_DATABASE=DICA TECHNOLOGIES AG + +OUI:000183* + ID_OUI_FROM_DATABASE=ANITE TELECOMS + +OUI:000184* + ID_OUI_FROM_DATABASE=SIEB & MEYER AG + +OUI:000185* + ID_OUI_FROM_DATABASE=Hitachi Aloka Medical, Ltd. + +OUI:000186* + ID_OUI_FROM_DATABASE=Uwe Disch + +OUI:000187* + ID_OUI_FROM_DATABASE=i2SE GmbH + +OUI:000188* + ID_OUI_FROM_DATABASE=LXCO Technologies ag + +OUI:000189* + ID_OUI_FROM_DATABASE=Refraction Technology, Inc. + +OUI:00018A* + ID_OUI_FROM_DATABASE=ROI COMPUTER AG + +OUI:00018B* + ID_OUI_FROM_DATABASE=NetLinks Co., Ltd. + +OUI:00018C* + ID_OUI_FROM_DATABASE=Mega Vision + +OUI:00018D* + ID_OUI_FROM_DATABASE=AudeSi Technologies + +OUI:00018E* + ID_OUI_FROM_DATABASE=Logitec Corporation + +OUI:00018F* + ID_OUI_FROM_DATABASE=Kenetec, Inc. + +OUI:000190* + ID_OUI_FROM_DATABASE=SMK-M + +OUI:000191* + ID_OUI_FROM_DATABASE=SYRED Data Systems + +OUI:000192* + ID_OUI_FROM_DATABASE=Texas Digital Systems + +OUI:000193* + ID_OUI_FROM_DATABASE=Hanbyul Telecom Co., Ltd. + +OUI:000194* + ID_OUI_FROM_DATABASE=Capital Equipment Corporation + +OUI:000195* + ID_OUI_FROM_DATABASE=Sena Technologies, Inc. + +OUI:000196* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000197* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000198* + ID_OUI_FROM_DATABASE=Darim Vision + +OUI:000199* + ID_OUI_FROM_DATABASE=HeiSei Electronics + +OUI:00019A* + ID_OUI_FROM_DATABASE=LEUNIG GmbH + +OUI:00019B* + ID_OUI_FROM_DATABASE=Kyoto Microcomputer Co., Ltd. + +OUI:00019C* + ID_OUI_FROM_DATABASE=JDS Uniphase Inc. + +OUI:00019D* + ID_OUI_FROM_DATABASE=E-Control Systems, Inc. + +OUI:00019E* + ID_OUI_FROM_DATABASE=ESS Technology, Inc. + +OUI:00019F* + ID_OUI_FROM_DATABASE=ReadyNet + +OUI:0001A0* + ID_OUI_FROM_DATABASE=Infinilink Corporation + +OUI:0001A1* + ID_OUI_FROM_DATABASE=Mag-Tek, Inc. + +OUI:0001A2* + ID_OUI_FROM_DATABASE=Logical Co., Ltd. + +OUI:0001A3* + ID_OUI_FROM_DATABASE=GENESYS LOGIC, INC. + +OUI:0001A4* + ID_OUI_FROM_DATABASE=Microlink Corporation + +OUI:0001A5* + ID_OUI_FROM_DATABASE=Nextcomm, Inc. + +OUI:0001A6* + ID_OUI_FROM_DATABASE=Scientific-Atlanta Arcodan A/S + +OUI:0001A7* + ID_OUI_FROM_DATABASE=UNEX TECHNOLOGY CORPORATION + +OUI:0001A8* + ID_OUI_FROM_DATABASE=Welltech Computer Co., Ltd. + +OUI:0001A9* + ID_OUI_FROM_DATABASE=BMW AG + +OUI:0001AA* + ID_OUI_FROM_DATABASE=Airspan Communications, Ltd. + +OUI:0001AB* + ID_OUI_FROM_DATABASE=Main Street Networks + +OUI:0001AC* + ID_OUI_FROM_DATABASE=Sitara Networks, Inc. + +OUI:0001AD* + ID_OUI_FROM_DATABASE=Coach Master International d.b.a. CMI Worldwide, Inc. + +OUI:0001AE* + ID_OUI_FROM_DATABASE=Trex Enterprises + +OUI:0001AF* + ID_OUI_FROM_DATABASE=Emerson Network Power + +OUI:0001B0* + ID_OUI_FROM_DATABASE=Fulltek Technology Co., Ltd. + +OUI:0001B1* + ID_OUI_FROM_DATABASE=General Bandwidth + +OUI:0001B2* + ID_OUI_FROM_DATABASE=Digital Processing Systems, Inc. + +OUI:0001B3* + ID_OUI_FROM_DATABASE=Precision Electronic Manufacturing + +OUI:0001B4* + ID_OUI_FROM_DATABASE=Wayport, Inc. + +OUI:0001B5* + ID_OUI_FROM_DATABASE=Turin Networks, Inc. + +OUI:0001B6* + ID_OUI_FROM_DATABASE=SAEJIN T&M Co., Ltd. + +OUI:0001B7* + ID_OUI_FROM_DATABASE=Centos, Inc. + +OUI:0001B8* + ID_OUI_FROM_DATABASE=Netsensity, Inc. + +OUI:0001B9* + ID_OUI_FROM_DATABASE=SKF Condition Monitoring + +OUI:0001BA* + ID_OUI_FROM_DATABASE=IC-Net, Inc. + +OUI:0001BB* + ID_OUI_FROM_DATABASE=Frequentis + +OUI:0001BC* + ID_OUI_FROM_DATABASE=Brains Corporation + +OUI:0001BD* + ID_OUI_FROM_DATABASE=Peterson Electro-Musical Products, Inc. + +OUI:0001BE* + ID_OUI_FROM_DATABASE=Gigalink Co., Ltd. + +OUI:0001BF* + ID_OUI_FROM_DATABASE=Teleforce Co., Ltd. + +OUI:0001C0* + ID_OUI_FROM_DATABASE=CompuLab, Ltd. + +OUI:0001C1* + ID_OUI_FROM_DATABASE=Vitesse Semiconductor Corporation + +OUI:0001C2* + ID_OUI_FROM_DATABASE=ARK Research Corp. + +OUI:0001C3* + ID_OUI_FROM_DATABASE=Acromag, Inc. + +OUI:0001C4* + ID_OUI_FROM_DATABASE=NeoWave, Inc. + +OUI:0001C5* + ID_OUI_FROM_DATABASE=Simpler Networks + +OUI:0001C6* + ID_OUI_FROM_DATABASE=Quarry Technologies + +OUI:0001C7* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0001C8* + ID_OUI_FROM_DATABASE=THOMAS CONRAD CORP. + +OUI:0001C8* + ID_OUI_FROM_DATABASE=CONRAD CORP. + +OUI:0001C9* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0001CA* + ID_OUI_FROM_DATABASE=Geocast Network Systems, Inc. + +OUI:0001CB* + ID_OUI_FROM_DATABASE=EVR + +OUI:0001CC* + ID_OUI_FROM_DATABASE=Japan Total Design Communication Co., Ltd. + +OUI:0001CD* + ID_OUI_FROM_DATABASE=ARtem + +OUI:0001CE* + ID_OUI_FROM_DATABASE=Custom Micro Products, Ltd. + +OUI:0001CF* + ID_OUI_FROM_DATABASE=Alpha Data Parallel Systems, Ltd. + +OUI:0001D0* + ID_OUI_FROM_DATABASE=VitalPoint, Inc. + +OUI:0001D1* + ID_OUI_FROM_DATABASE=CoNet Communications, Inc. + +OUI:0001D2* + ID_OUI_FROM_DATABASE=inXtron, Inc. + +OUI:0001D3* + ID_OUI_FROM_DATABASE=PAXCOMM, Inc. + +OUI:0001D4* + ID_OUI_FROM_DATABASE=Leisure Time, Inc. + +OUI:0001D5* + ID_OUI_FROM_DATABASE=HAEDONG INFO & COMM CO., LTD + +OUI:0001D6* + ID_OUI_FROM_DATABASE=manroland AG + +OUI:0001D7* + ID_OUI_FROM_DATABASE=F5 Networks, Inc. + +OUI:0001D8* + ID_OUI_FROM_DATABASE=Teltronics, Inc. + +OUI:0001D9* + ID_OUI_FROM_DATABASE=Sigma, Inc. + +OUI:0001DA* + ID_OUI_FROM_DATABASE=WINCOMM Corporation + +OUI:0001DB* + ID_OUI_FROM_DATABASE=Freecom Technologies GmbH + +OUI:0001DC* + ID_OUI_FROM_DATABASE=Activetelco + +OUI:0001DD* + ID_OUI_FROM_DATABASE=Avail Networks + +OUI:0001DE* + ID_OUI_FROM_DATABASE=Trango Systems, Inc. + +OUI:0001DF* + ID_OUI_FROM_DATABASE=ISDN Communications, Ltd. + +OUI:0001E0* + ID_OUI_FROM_DATABASE=Fast Systems, Inc. + +OUI:0001E1* + ID_OUI_FROM_DATABASE=Kinpo Electronics, Inc. + +OUI:0001E2* + ID_OUI_FROM_DATABASE=Ando Electric Corporation + +OUI:0001E3* + ID_OUI_FROM_DATABASE=Siemens AG + +OUI:0001E4* + ID_OUI_FROM_DATABASE=Sitera, Inc. + +OUI:0001E5* + ID_OUI_FROM_DATABASE=Supernet, Inc. + +OUI:0001E6* + ID_OUI_FROM_DATABASE=Hewlett-Packard Company + +OUI:0001E7* + ID_OUI_FROM_DATABASE=Hewlett-Packard Company + +OUI:0001E8* + ID_OUI_FROM_DATABASE=Force10 Networks, Inc. + +OUI:0001E9* + ID_OUI_FROM_DATABASE=Litton Marine Systems B.V. + +OUI:0001EA* + ID_OUI_FROM_DATABASE=Cirilium Corp. + +OUI:0001EB* + ID_OUI_FROM_DATABASE=C-COM Corporation + +OUI:0001EC* + ID_OUI_FROM_DATABASE=Ericsson Group + +OUI:0001ED* + ID_OUI_FROM_DATABASE=SETA Corp. + +OUI:0001EE* + ID_OUI_FROM_DATABASE=Comtrol Europe, Ltd. + +OUI:0001EF* + ID_OUI_FROM_DATABASE=Camtel Technology Corp. + +OUI:0001F0* + ID_OUI_FROM_DATABASE=Tridium, Inc. + +OUI:0001F1* + ID_OUI_FROM_DATABASE=Innovative Concepts, Inc. + +OUI:0001F2* + ID_OUI_FROM_DATABASE=Mark of the Unicorn, Inc. + +OUI:0001F3* + ID_OUI_FROM_DATABASE=QPS, Inc. + +OUI:0001F4* + ID_OUI_FROM_DATABASE=Enterasys Networks + +OUI:0001F5* + ID_OUI_FROM_DATABASE=ERIM S.A. + +OUI:0001F6* + ID_OUI_FROM_DATABASE=Association of Musical Electronics Industry + +OUI:0001F7* + ID_OUI_FROM_DATABASE=Image Display Systems, Inc. + +OUI:0001F8* + ID_OUI_FROM_DATABASE=Adherent Systems, Ltd. + +OUI:0001F9* + ID_OUI_FROM_DATABASE=TeraGlobal Communications Corp. + +OUI:0001FA* + ID_OUI_FROM_DATABASE=HOROSCAS + +OUI:0001FB* + ID_OUI_FROM_DATABASE=DoTop Technology, Inc. + +OUI:0001FC* + ID_OUI_FROM_DATABASE=Keyence Corporation + +OUI:0001FD* + ID_OUI_FROM_DATABASE=Digital Voice Systems, Inc. + +OUI:0001FE* + ID_OUI_FROM_DATABASE=DIGITAL EQUIPMENT CORPORATION + +OUI:0001FF* + ID_OUI_FROM_DATABASE=Data Direct Networks, Inc. + +OUI:000200* + ID_OUI_FROM_DATABASE=Net & Sys Co., Ltd. + +OUI:000201* + ID_OUI_FROM_DATABASE=IFM Electronic gmbh + +OUI:000202* + ID_OUI_FROM_DATABASE=Amino Communications, Ltd. + +OUI:000203* + ID_OUI_FROM_DATABASE=Woonsang Telecom, Inc. + +OUI:000204* + ID_OUI_FROM_DATABASE=Bodmann Industries Elektronik GmbH + +OUI:000205* + ID_OUI_FROM_DATABASE=Hitachi Denshi, Ltd. + +OUI:000206* + ID_OUI_FROM_DATABASE=Telital R&D Denmark A/S + +OUI:000207* + ID_OUI_FROM_DATABASE=VisionGlobal Network Corp. + +OUI:000208* + ID_OUI_FROM_DATABASE=Unify Networks, Inc. + +OUI:000209* + ID_OUI_FROM_DATABASE=Shenzhen SED Information Technology Co., Ltd. + +OUI:00020A* + ID_OUI_FROM_DATABASE=Gefran Spa + +OUI:00020B* + ID_OUI_FROM_DATABASE=Native Networks, Inc. + +OUI:00020C* + ID_OUI_FROM_DATABASE=Metro-Optix + +OUI:00020D* + ID_OUI_FROM_DATABASE=Micronpc.com + +OUI:00020E* + ID_OUI_FROM_DATABASE=ECI Telecom, Ltd., NSD-US + +OUI:00020F* + ID_OUI_FROM_DATABASE=AATR + +OUI:000210* + ID_OUI_FROM_DATABASE=Fenecom + +OUI:000211* + ID_OUI_FROM_DATABASE=Nature Worldwide Technology Corp. + +OUI:000212* + ID_OUI_FROM_DATABASE=SierraCom + +OUI:000213* + ID_OUI_FROM_DATABASE=S.D.E.L. + +OUI:000214* + ID_OUI_FROM_DATABASE=DTVRO + +OUI:000215* + ID_OUI_FROM_DATABASE=Cotas Computer Technology A/B + +OUI:000216* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000217* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000218* + ID_OUI_FROM_DATABASE=Advanced Scientific Corp + +OUI:000219* + ID_OUI_FROM_DATABASE=Paralon Technologies + +OUI:00021A* + ID_OUI_FROM_DATABASE=Zuma Networks + +OUI:00021B* + ID_OUI_FROM_DATABASE=Kollmorgen-Servotronix + +OUI:00021C* + ID_OUI_FROM_DATABASE=Network Elements, Inc. + +OUI:00021D* + ID_OUI_FROM_DATABASE=Data General Communication Ltd. + +OUI:00021E* + ID_OUI_FROM_DATABASE=SIMTEL S.R.L. + +OUI:00021F* + ID_OUI_FROM_DATABASE=Aculab PLC + +OUI:000220* + ID_OUI_FROM_DATABASE=CANON FINETECH INC. + +OUI:000221* + ID_OUI_FROM_DATABASE=DSP Application, Ltd. + +OUI:000222* + ID_OUI_FROM_DATABASE=Chromisys, Inc. + +OUI:000223* + ID_OUI_FROM_DATABASE=ClickTV + +OUI:000224* + ID_OUI_FROM_DATABASE=C-COR + +OUI:000225* + ID_OUI_FROM_DATABASE=One Stop Systems + +OUI:000226* + ID_OUI_FROM_DATABASE=XESystems, Inc. + +OUI:000227* + ID_OUI_FROM_DATABASE=ESD Electronic System Design GmbH + +OUI:000228* + ID_OUI_FROM_DATABASE=Necsom, Ltd. + +OUI:000229* + ID_OUI_FROM_DATABASE=Adtec Corporation + +OUI:00022A* + ID_OUI_FROM_DATABASE=Asound Electronic + +OUI:00022B* + ID_OUI_FROM_DATABASE=SAXA, Inc. + +OUI:00022C* + ID_OUI_FROM_DATABASE=ABB Bomem, Inc. + +OUI:00022D* + ID_OUI_FROM_DATABASE=Agere Systems + +OUI:00022E* + ID_OUI_FROM_DATABASE=TEAC Corp. R& D + +OUI:00022F* + ID_OUI_FROM_DATABASE=P-Cube, Ltd. + +OUI:000230* + ID_OUI_FROM_DATABASE=Intersoft Electronics + +OUI:000231* + ID_OUI_FROM_DATABASE=Ingersoll-Rand + +OUI:000232* + ID_OUI_FROM_DATABASE=Avision, Inc. + +OUI:000233* + ID_OUI_FROM_DATABASE=Mantra Communications, Inc. + +OUI:000234* + ID_OUI_FROM_DATABASE=Imperial Technology, Inc. + +OUI:000235* + ID_OUI_FROM_DATABASE=Paragon Networks International + +OUI:000236* + ID_OUI_FROM_DATABASE=INIT GmbH + +OUI:000237* + ID_OUI_FROM_DATABASE=Cosmo Research Corp. + +OUI:000238* + ID_OUI_FROM_DATABASE=Serome Technology, Inc. + +OUI:000239* + ID_OUI_FROM_DATABASE=Visicom + +OUI:00023A* + ID_OUI_FROM_DATABASE=ZSK Stickmaschinen GmbH + +OUI:00023B* + ID_OUI_FROM_DATABASE=Ericsson + +OUI:00023C* + ID_OUI_FROM_DATABASE=Creative Technology, Ltd. + +OUI:00023D* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc. + +OUI:00023E* + ID_OUI_FROM_DATABASE=Selta Telematica S.p.a + +OUI:00023F* + ID_OUI_FROM_DATABASE=Compal Electronics, Inc. + +OUI:000240* + ID_OUI_FROM_DATABASE=Seedek Co., Ltd. + +OUI:000241* + ID_OUI_FROM_DATABASE=Amer.com + +OUI:000242* + ID_OUI_FROM_DATABASE=Videoframe Systems + +OUI:000243* + ID_OUI_FROM_DATABASE=Raysis Co., Ltd. + +OUI:000244* + ID_OUI_FROM_DATABASE=SURECOM Technology Co. + +OUI:000245* + ID_OUI_FROM_DATABASE=Lampus Co, Ltd. + +OUI:000246* + ID_OUI_FROM_DATABASE=All-Win Tech Co., Ltd. + +OUI:000247* + ID_OUI_FROM_DATABASE=Great Dragon Information Technology (Group) Co., Ltd. + +OUI:000248* + ID_OUI_FROM_DATABASE=Pilz GmbH & Co. + +OUI:000249* + ID_OUI_FROM_DATABASE=Aviv Infocom Co, Ltd. + +OUI:00024A* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00024B* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00024C* + ID_OUI_FROM_DATABASE=SiByte, Inc. + +OUI:00024D* + ID_OUI_FROM_DATABASE=Mannesman Dematic Colby Pty. Ltd. + +OUI:00024E* + ID_OUI_FROM_DATABASE=Datacard Group + +OUI:00024F* + ID_OUI_FROM_DATABASE=IPM Datacom S.R.L. + +OUI:000250* + ID_OUI_FROM_DATABASE=Geyser Networks, Inc. + +OUI:000251* + ID_OUI_FROM_DATABASE=Soma Networks, Inc. + +OUI:000252* + ID_OUI_FROM_DATABASE=Carrier Corporation + +OUI:000253* + ID_OUI_FROM_DATABASE=Televideo, Inc. + +OUI:000254* + ID_OUI_FROM_DATABASE=WorldGate + +OUI:000255* + ID_OUI_FROM_DATABASE=IBM Corp + +OUI:000256* + ID_OUI_FROM_DATABASE=Alpha Processor, Inc. + +OUI:000257* + ID_OUI_FROM_DATABASE=Microcom Corp. + +OUI:000258* + ID_OUI_FROM_DATABASE=Flying Packets Communications + +OUI:000259* + ID_OUI_FROM_DATABASE=Tsann Kuen China (Shanghai)Enterprise Co., Ltd. IT Group + +OUI:00025A* + ID_OUI_FROM_DATABASE=Catena Networks + +OUI:00025B* + ID_OUI_FROM_DATABASE=Cambridge Silicon Radio + +OUI:00025C* + ID_OUI_FROM_DATABASE=SCI Systems (Kunshan) Co., Ltd. + +OUI:00025D* + ID_OUI_FROM_DATABASE=Calix Networks + +OUI:00025E* + ID_OUI_FROM_DATABASE=High Technology Ltd + +OUI:00025F* + ID_OUI_FROM_DATABASE=Nortel Networks + +OUI:000260* + ID_OUI_FROM_DATABASE=Accordion Networks, Inc. + +OUI:000261* + ID_OUI_FROM_DATABASE=Tilgin AB + +OUI:000262* + ID_OUI_FROM_DATABASE=Soyo Group Soyo Com Tech Co., Ltd + +OUI:000263* + ID_OUI_FROM_DATABASE=UPS Manufacturing SRL + +OUI:000264* + ID_OUI_FROM_DATABASE=AudioRamp.com + +OUI:000265* + ID_OUI_FROM_DATABASE=Virditech Co. Ltd. + +OUI:000266* + ID_OUI_FROM_DATABASE=Thermalogic Corporation + +OUI:000267* + ID_OUI_FROM_DATABASE=NODE RUNNER, INC. + +OUI:000268* + ID_OUI_FROM_DATABASE=Harris Government Communications + +OUI:000269* + ID_OUI_FROM_DATABASE=Nadatel Co., Ltd + +OUI:00026A* + ID_OUI_FROM_DATABASE=Cocess Telecom Co., Ltd. + +OUI:00026B* + ID_OUI_FROM_DATABASE=BCM Computers Co., Ltd. + +OUI:00026C* + ID_OUI_FROM_DATABASE=Philips CFT + +OUI:00026D* + ID_OUI_FROM_DATABASE=Adept Telecom + +OUI:00026E* + ID_OUI_FROM_DATABASE=NeGeN Access, Inc. + +OUI:00026F* + ID_OUI_FROM_DATABASE=Senao International Co., Ltd. + +OUI:000270* + ID_OUI_FROM_DATABASE=Crewave Co., Ltd. + +OUI:000271* + ID_OUI_FROM_DATABASE=Zhone Technologies + +OUI:000272* + ID_OUI_FROM_DATABASE=CC&C Technologies, Inc. + +OUI:000273* + ID_OUI_FROM_DATABASE=Coriolis Networks + +OUI:000274* + ID_OUI_FROM_DATABASE=Tommy Technologies Corp. + +OUI:000275* + ID_OUI_FROM_DATABASE=SMART Technologies, Inc. + +OUI:000276* + ID_OUI_FROM_DATABASE=Primax Electronics Ltd. + +OUI:000277* + ID_OUI_FROM_DATABASE=Cash Systemes Industrie + +OUI:000278* + ID_OUI_FROM_DATABASE=Samsung Electro-Mechanics Co., Ltd. + +OUI:000279* + ID_OUI_FROM_DATABASE=Control Applications, Ltd. + +OUI:00027A* + ID_OUI_FROM_DATABASE=IOI Technology Corporation + +OUI:00027B* + ID_OUI_FROM_DATABASE=Amplify Net, Inc. + +OUI:00027C* + ID_OUI_FROM_DATABASE=Trilithic, Inc. + +OUI:00027D* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00027E* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00027F* + ID_OUI_FROM_DATABASE=ask-technologies.com + +OUI:000280* + ID_OUI_FROM_DATABASE=Mu Net, Inc. + +OUI:000281* + ID_OUI_FROM_DATABASE=Madge Ltd. + +OUI:000282* + ID_OUI_FROM_DATABASE=ViaClix, Inc. + +OUI:000283* + ID_OUI_FROM_DATABASE=Spectrum Controls, Inc. + +OUI:000284* + ID_OUI_FROM_DATABASE=AREVA T&D + +OUI:000285* + ID_OUI_FROM_DATABASE=Riverstone Networks + +OUI:000286* + ID_OUI_FROM_DATABASE=Occam Networks + +OUI:000287* + ID_OUI_FROM_DATABASE=Adapcom + +OUI:000288* + ID_OUI_FROM_DATABASE=GLOBAL VILLAGE COMMUNICATION + +OUI:000289* + ID_OUI_FROM_DATABASE=DNE Technologies + +OUI:00028A* + ID_OUI_FROM_DATABASE=Ambit Microsystems Corporation + +OUI:00028B* + ID_OUI_FROM_DATABASE=VDSL Systems OY + +OUI:00028C* + ID_OUI_FROM_DATABASE=Micrel-Synergy Semiconductor + +OUI:00028D* + ID_OUI_FROM_DATABASE=Movita Technologies, Inc. + +OUI:00028E* + ID_OUI_FROM_DATABASE=Rapid 5 Networks, Inc. + +OUI:00028F* + ID_OUI_FROM_DATABASE=Globetek, Inc. + +OUI:000290* + ID_OUI_FROM_DATABASE=Woorigisool, Inc. + +OUI:000291* + ID_OUI_FROM_DATABASE=Open Network Co., Ltd. + +OUI:000292* + ID_OUI_FROM_DATABASE=Logic Innovations, Inc. + +OUI:000293* + ID_OUI_FROM_DATABASE=Solid Data Systems + +OUI:000294* + ID_OUI_FROM_DATABASE=Tokyo Sokushin Co., Ltd. + +OUI:000295* + ID_OUI_FROM_DATABASE=IP.Access Limited + +OUI:000296* + ID_OUI_FROM_DATABASE=Lectron Co,. Ltd. + +OUI:000297* + ID_OUI_FROM_DATABASE=C-COR.net + +OUI:000298* + ID_OUI_FROM_DATABASE=Broadframe Corporation + +OUI:000299* + ID_OUI_FROM_DATABASE=Apex, Inc. + +OUI:00029A* + ID_OUI_FROM_DATABASE=Storage Apps + +OUI:00029B* + ID_OUI_FROM_DATABASE=Kreatel Communications AB + +OUI:00029C* + ID_OUI_FROM_DATABASE=3COM + +OUI:00029D* + ID_OUI_FROM_DATABASE=Merix Corp. + +OUI:00029E* + ID_OUI_FROM_DATABASE=Information Equipment Co., Ltd. + +OUI:00029F* + ID_OUI_FROM_DATABASE=L-3 Communication Aviation Recorders + +OUI:0002A0* + ID_OUI_FROM_DATABASE=Flatstack Ltd. + +OUI:0002A1* + ID_OUI_FROM_DATABASE=World Wide Packets + +OUI:0002A2* + ID_OUI_FROM_DATABASE=Hilscher GmbH + +OUI:0002A3* + ID_OUI_FROM_DATABASE=ABB Switzerland Ltd, Power Systems + +OUI:0002A4* + ID_OUI_FROM_DATABASE=AddPac Technology Co., Ltd. + +OUI:0002A5* + ID_OUI_FROM_DATABASE=Hewlett-Packard Company + +OUI:0002A6* + ID_OUI_FROM_DATABASE=Effinet Systems Co., Ltd. + +OUI:0002A7* + ID_OUI_FROM_DATABASE=Vivace Networks + +OUI:0002A8* + ID_OUI_FROM_DATABASE=Air Link Technology + +OUI:0002A9* + ID_OUI_FROM_DATABASE=RACOM, s.r.o. + +OUI:0002AA* + ID_OUI_FROM_DATABASE=PLcom Co., Ltd. + +OUI:0002AB* + ID_OUI_FROM_DATABASE=CTC Union Technologies Co., Ltd. + +OUI:0002AC* + ID_OUI_FROM_DATABASE=3PAR data + +OUI:0002AD* + ID_OUI_FROM_DATABASE=HOYA Corporation + +OUI:0002AE* + ID_OUI_FROM_DATABASE=Scannex Electronics Ltd. + +OUI:0002AF* + ID_OUI_FROM_DATABASE=TeleCruz Technology, Inc. + +OUI:0002B0* + ID_OUI_FROM_DATABASE=Hokubu Communication & Industrial Co., Ltd. + +OUI:0002B1* + ID_OUI_FROM_DATABASE=Anritsu, Ltd. + +OUI:0002B2* + ID_OUI_FROM_DATABASE=Cablevision + +OUI:0002B3* + ID_OUI_FROM_DATABASE=Intel Corporation + +OUI:0002B4* + ID_OUI_FROM_DATABASE=DAPHNE + +OUI:0002B5* + ID_OUI_FROM_DATABASE=Avnet, Inc. + +OUI:0002B6* + ID_OUI_FROM_DATABASE=Acrosser Technology Co., Ltd. + +OUI:0002B7* + ID_OUI_FROM_DATABASE=Watanabe Electric Industry Co., Ltd. + +OUI:0002B8* + ID_OUI_FROM_DATABASE=WHI KONSULT AB + +OUI:0002B9* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0002BA* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0002BB* + ID_OUI_FROM_DATABASE=Continuous Computing Corp + +OUI:0002BC* + ID_OUI_FROM_DATABASE=LVL 7 Systems, Inc. + +OUI:0002BD* + ID_OUI_FROM_DATABASE=Bionet Co., Ltd. + +OUI:0002BE* + ID_OUI_FROM_DATABASE=Totsu Engineering, Inc. + +OUI:0002BF* + ID_OUI_FROM_DATABASE=dotRocket, Inc. + +OUI:0002C0* + ID_OUI_FROM_DATABASE=Bencent Tzeng Industry Co., Ltd. + +OUI:0002C1* + ID_OUI_FROM_DATABASE=Innovative Electronic Designs, Inc. + +OUI:0002C2* + ID_OUI_FROM_DATABASE=Net Vision Telecom + +OUI:0002C3* + ID_OUI_FROM_DATABASE=Arelnet Ltd. + +OUI:0002C4* + ID_OUI_FROM_DATABASE=Vector International BVBA + +OUI:0002C5* + ID_OUI_FROM_DATABASE=Evertz Microsystems Ltd. + +OUI:0002C6* + ID_OUI_FROM_DATABASE=Data Track Technology PLC + +OUI:0002C7* + ID_OUI_FROM_DATABASE=ALPS ELECTRIC Co., Ltd. + +OUI:0002C8* + ID_OUI_FROM_DATABASE=Technocom Communications Technology (pte) Ltd + +OUI:0002C9* + ID_OUI_FROM_DATABASE=Mellanox Technologies + +OUI:0002CA* + ID_OUI_FROM_DATABASE=EndPoints, Inc. + +OUI:0002CB* + ID_OUI_FROM_DATABASE=TriState Ltd. + +OUI:0002CC* + ID_OUI_FROM_DATABASE=M.C.C.I + +OUI:0002CD* + ID_OUI_FROM_DATABASE=TeleDream, Inc. + +OUI:0002CE* + ID_OUI_FROM_DATABASE=FoxJet, Inc. + +OUI:0002CF* + ID_OUI_FROM_DATABASE=ZyGate Communications, Inc. + +OUI:0002D0* + ID_OUI_FROM_DATABASE=Comdial Corporation + +OUI:0002D1* + ID_OUI_FROM_DATABASE=Vivotek, Inc. + +OUI:0002D2* + ID_OUI_FROM_DATABASE=Workstation AG + +OUI:0002D3* + ID_OUI_FROM_DATABASE=NetBotz, Inc. + +OUI:0002D4* + ID_OUI_FROM_DATABASE=PDA Peripherals, Inc. + +OUI:0002D5* + ID_OUI_FROM_DATABASE=ACR + +OUI:0002D6* + ID_OUI_FROM_DATABASE=NICE Systems + +OUI:0002D7* + ID_OUI_FROM_DATABASE=EMPEG Ltd + +OUI:0002D8* + ID_OUI_FROM_DATABASE=BRECIS Communications Corporation + +OUI:0002D9* + ID_OUI_FROM_DATABASE=Reliable Controls + +OUI:0002DA* + ID_OUI_FROM_DATABASE=ExiO Communications, Inc. + +OUI:0002DB* + ID_OUI_FROM_DATABASE=NETSEC + +OUI:0002DC* + ID_OUI_FROM_DATABASE=Fujitsu General Limited + +OUI:0002DD* + ID_OUI_FROM_DATABASE=Bromax Communications, Ltd. + +OUI:0002DE* + ID_OUI_FROM_DATABASE=Astrodesign, Inc. + +OUI:0002DF* + ID_OUI_FROM_DATABASE=Net Com Systems, Inc. + +OUI:0002E0* + ID_OUI_FROM_DATABASE=ETAS GmbH + +OUI:0002E1* + ID_OUI_FROM_DATABASE=Integrated Network Corporation + +OUI:0002E2* + ID_OUI_FROM_DATABASE=NDC Infared Engineering + +OUI:0002E3* + ID_OUI_FROM_DATABASE=LITE-ON Communications, Inc. + +OUI:0002E4* + ID_OUI_FROM_DATABASE=JC HYUN Systems, Inc. + +OUI:0002E5* + ID_OUI_FROM_DATABASE=Timeware Ltd. + +OUI:0002E6* + ID_OUI_FROM_DATABASE=Gould Instrument Systems, Inc. + +OUI:0002E7* + ID_OUI_FROM_DATABASE=CAB GmbH & Co KG + +OUI:0002E8* + ID_OUI_FROM_DATABASE=E.D.&A. + +OUI:0002E9* + ID_OUI_FROM_DATABASE=CS Systemes De Securite - C3S + +OUI:0002EA* + ID_OUI_FROM_DATABASE=Focus Enhancements + +OUI:0002EB* + ID_OUI_FROM_DATABASE=Pico Communications + +OUI:0002EC* + ID_OUI_FROM_DATABASE=Maschoff Design Engineering + +OUI:0002ED* + ID_OUI_FROM_DATABASE=DXO Telecom Co., Ltd. + +OUI:0002EE* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:0002EF* + ID_OUI_FROM_DATABASE=CCC Network Systems Group Ltd. + +OUI:0002F0* + ID_OUI_FROM_DATABASE=AME Optimedia Technology Co., Ltd. + +OUI:0002F1* + ID_OUI_FROM_DATABASE=Pinetron Co., Ltd. + +OUI:0002F2* + ID_OUI_FROM_DATABASE=eDevice, Inc. + +OUI:0002F3* + ID_OUI_FROM_DATABASE=Media Serve Co., Ltd. + +OUI:0002F4* + ID_OUI_FROM_DATABASE=PCTEL, Inc. + +OUI:0002F5* + ID_OUI_FROM_DATABASE=VIVE Synergies, Inc. + +OUI:0002F6* + ID_OUI_FROM_DATABASE=Equipe Communications + +OUI:0002F7* + ID_OUI_FROM_DATABASE=ARM + +OUI:0002F8* + ID_OUI_FROM_DATABASE=SEAKR Engineering, Inc. + +OUI:0002F9* + ID_OUI_FROM_DATABASE=Mimos Semiconductor SDN BHD + +OUI:0002FA* + ID_OUI_FROM_DATABASE=DX Antenna Co., Ltd. + +OUI:0002FB* + ID_OUI_FROM_DATABASE=Baumuller Aulugen-Systemtechnik GmbH + +OUI:0002FC* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0002FD* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0002FE* + ID_OUI_FROM_DATABASE=Viditec, Inc. + +OUI:0002FF* + ID_OUI_FROM_DATABASE=Handan BroadInfoCom + +OUI:000300* + ID_OUI_FROM_DATABASE=Barracuda Networks, Inc. + +OUI:000301* + ID_OUI_FROM_DATABASE=Avantas Networks Corporation + +OUI:000302* + ID_OUI_FROM_DATABASE=Charles Industries, Ltd. + +OUI:000303* + ID_OUI_FROM_DATABASE=JAMA Electronics Co., Ltd. + +OUI:000304* + ID_OUI_FROM_DATABASE=Pacific Broadband Communications + +OUI:000305* + ID_OUI_FROM_DATABASE=MSC Vertriebs GmbH + +OUI:000306* + ID_OUI_FROM_DATABASE=Fusion In Tech Co., Ltd. + +OUI:000307* + ID_OUI_FROM_DATABASE=Secure Works, Inc. + +OUI:000308* + ID_OUI_FROM_DATABASE=AM Communications, Inc. + +OUI:000309* + ID_OUI_FROM_DATABASE=Texcel Technology PLC + +OUI:00030A* + ID_OUI_FROM_DATABASE=Argus Technologies + +OUI:00030B* + ID_OUI_FROM_DATABASE=Hunter Technology, Inc. + +OUI:00030C* + ID_OUI_FROM_DATABASE=Telesoft Technologies Ltd. + +OUI:00030D* + ID_OUI_FROM_DATABASE=Uniwill Computer Corp. + +OUI:00030E* + ID_OUI_FROM_DATABASE=Core Communications Co., Ltd. + +OUI:00030F* + ID_OUI_FROM_DATABASE=Digital China (Shanghai) Networks Ltd. + +OUI:000310* + ID_OUI_FROM_DATABASE=ITX E-Globaledge Corporation + +OUI:000311* + ID_OUI_FROM_DATABASE=Micro Technology Co., Ltd. + +OUI:000312* + ID_OUI_FROM_DATABASE=TR-Systemtechnik GmbH + +OUI:000313* + ID_OUI_FROM_DATABASE=Access Media SPA + +OUI:000314* + ID_OUI_FROM_DATABASE=Teleware Network Systems + +OUI:000315* + ID_OUI_FROM_DATABASE=Cidco Incorporated + +OUI:000316* + ID_OUI_FROM_DATABASE=Nobell Communications, Inc. + +OUI:000317* + ID_OUI_FROM_DATABASE=Merlin Systems, Inc. + +OUI:000318* + ID_OUI_FROM_DATABASE=Cyras Systems, Inc. + +OUI:000319* + ID_OUI_FROM_DATABASE=Infineon AG + +OUI:00031A* + ID_OUI_FROM_DATABASE=Beijing Broad Telecom Ltd., China + +OUI:00031B* + ID_OUI_FROM_DATABASE=Cellvision Systems, Inc. + +OUI:00031C* + ID_OUI_FROM_DATABASE=Svenska Hardvarufabriken AB + +OUI:00031D* + ID_OUI_FROM_DATABASE=Taiwan Commate Computer, Inc. + +OUI:00031E* + ID_OUI_FROM_DATABASE=Optranet, Inc. + +OUI:00031F* + ID_OUI_FROM_DATABASE=Condev Ltd. + +OUI:000320* + ID_OUI_FROM_DATABASE=Xpeed, Inc. + +OUI:000321* + ID_OUI_FROM_DATABASE=Reco Research Co., Ltd. + +OUI:000322* + ID_OUI_FROM_DATABASE=IDIS Co., Ltd. + +OUI:000323* + ID_OUI_FROM_DATABASE=Cornet Technology, Inc. + +OUI:000324* + ID_OUI_FROM_DATABASE=SANYO Consumer Electronics Co., Ltd. + +OUI:000325* + ID_OUI_FROM_DATABASE=Arima Computer Corp. + +OUI:000326* + ID_OUI_FROM_DATABASE=Iwasaki Information Systems Co., Ltd. + +OUI:000327* + ID_OUI_FROM_DATABASE=ACT'L + +OUI:000328* + ID_OUI_FROM_DATABASE=Mace Group, Inc. + +OUI:000329* + ID_OUI_FROM_DATABASE=F3, Inc. + +OUI:00032A* + ID_OUI_FROM_DATABASE=UniData Communication Systems, Inc. + +OUI:00032B* + ID_OUI_FROM_DATABASE=GAI Datenfunksysteme GmbH + +OUI:00032C* + ID_OUI_FROM_DATABASE=ABB Switzerland Ltd + +OUI:00032D* + ID_OUI_FROM_DATABASE=IBASE Technology, Inc. + +OUI:00032E* + ID_OUI_FROM_DATABASE=Scope Information Management, Ltd. + +OUI:00032F* + ID_OUI_FROM_DATABASE=Global Sun Technology, Inc. + +OUI:000330* + ID_OUI_FROM_DATABASE=Imagenics, Co., Ltd. + +OUI:000331* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000332* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000333* + ID_OUI_FROM_DATABASE=Digitel Co., Ltd. + +OUI:000334* + ID_OUI_FROM_DATABASE=Newport Electronics + +OUI:000335* + ID_OUI_FROM_DATABASE=Mirae Technology + +OUI:000336* + ID_OUI_FROM_DATABASE=Zetes Technologies + +OUI:000337* + ID_OUI_FROM_DATABASE=Vaone, Inc. + +OUI:000338* + ID_OUI_FROM_DATABASE=Oak Technology + +OUI:000339* + ID_OUI_FROM_DATABASE=Eurologic Systems, Ltd. + +OUI:00033A* + ID_OUI_FROM_DATABASE=Silicon Wave, Inc. + +OUI:00033B* + ID_OUI_FROM_DATABASE=TAMI Tech Co., Ltd. + +OUI:00033C* + ID_OUI_FROM_DATABASE=Daiden Co., Ltd. + +OUI:00033D* + ID_OUI_FROM_DATABASE=ILSHin Lab + +OUI:00033E* + ID_OUI_FROM_DATABASE=Tateyama System Laboratory Co., Ltd. + +OUI:00033F* + ID_OUI_FROM_DATABASE=BigBand Networks, Ltd. + +OUI:000340* + ID_OUI_FROM_DATABASE=Floware Wireless Systems, Ltd. + +OUI:000341* + ID_OUI_FROM_DATABASE=Axon Digital Design + +OUI:000342* + ID_OUI_FROM_DATABASE=Nortel Networks + +OUI:000343* + ID_OUI_FROM_DATABASE=Martin Professional A/S + +OUI:000344* + ID_OUI_FROM_DATABASE=Tietech.Co., Ltd. + +OUI:000345* + ID_OUI_FROM_DATABASE=Routrek Networks Corporation + +OUI:000346* + ID_OUI_FROM_DATABASE=Hitachi Kokusai Electric, Inc. + +OUI:000347* + ID_OUI_FROM_DATABASE=Intel Corporation + +OUI:000348* + ID_OUI_FROM_DATABASE=Norscan Instruments, Ltd. + +OUI:000349* + ID_OUI_FROM_DATABASE=Vidicode Datacommunicatie B.V. + +OUI:00034A* + ID_OUI_FROM_DATABASE=RIAS Corporation + +OUI:00034B* + ID_OUI_FROM_DATABASE=Nortel Networks + +OUI:00034C* + ID_OUI_FROM_DATABASE=Shanghai DigiVision Technology Co., Ltd. + +OUI:00034D* + ID_OUI_FROM_DATABASE=Chiaro Networks, Ltd. + +OUI:00034E* + ID_OUI_FROM_DATABASE=Pos Data Company, Ltd. + +OUI:00034F* + ID_OUI_FROM_DATABASE=Sur-Gard Security + +OUI:000350* + ID_OUI_FROM_DATABASE=BTICINO SPA + +OUI:000351* + ID_OUI_FROM_DATABASE=Diebold, Inc. + +OUI:000352* + ID_OUI_FROM_DATABASE=Colubris Networks + +OUI:000353* + ID_OUI_FROM_DATABASE=Mitac, Inc. + +OUI:000354* + ID_OUI_FROM_DATABASE=Fiber Logic Communications + +OUI:000355* + ID_OUI_FROM_DATABASE=TeraBeam Internet Systems + +OUI:000356* + ID_OUI_FROM_DATABASE=Wincor Nixdorf International GmbH + +OUI:000357* + ID_OUI_FROM_DATABASE=Intervoice-Brite, Inc. + +OUI:000358* + ID_OUI_FROM_DATABASE=Hanyang Digitech Co., Ltd. + +OUI:000359* + ID_OUI_FROM_DATABASE=DigitalSis + +OUI:00035A* + ID_OUI_FROM_DATABASE=Photron Limited + +OUI:00035B* + ID_OUI_FROM_DATABASE=BridgeWave Communications + +OUI:00035C* + ID_OUI_FROM_DATABASE=Saint Song Corp. + +OUI:00035D* + ID_OUI_FROM_DATABASE=Bosung Hi-Net Co., Ltd. + +OUI:00035E* + ID_OUI_FROM_DATABASE=Metropolitan Area Networks, Inc. + +OUI:00035F* + ID_OUI_FROM_DATABASE=Prüftechnik Condition Monitoring GmbH & Co. KG + +OUI:000360* + ID_OUI_FROM_DATABASE=PAC Interactive Technology, Inc. + +OUI:000361* + ID_OUI_FROM_DATABASE=Widcomm, Inc. + +OUI:000362* + ID_OUI_FROM_DATABASE=Vodtel Communications, Inc. + +OUI:000363* + ID_OUI_FROM_DATABASE=Miraesys Co., Ltd. + +OUI:000364* + ID_OUI_FROM_DATABASE=Scenix Semiconductor, Inc. + +OUI:000365* + ID_OUI_FROM_DATABASE=Kira Information & Communications, Ltd. + +OUI:000366* + ID_OUI_FROM_DATABASE=ASM Pacific Technology + +OUI:000367* + ID_OUI_FROM_DATABASE=Jasmine Networks, Inc. + +OUI:000368* + ID_OUI_FROM_DATABASE=Embedone Co., Ltd. + +OUI:000369* + ID_OUI_FROM_DATABASE=Nippon Antenna Co., Ltd. + +OUI:00036A* + ID_OUI_FROM_DATABASE=Mainnet, Ltd. + +OUI:00036B* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00036C* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00036D* + ID_OUI_FROM_DATABASE=Runtop, Inc. + +OUI:00036E* + ID_OUI_FROM_DATABASE=Nicon Systems (Pty) Limited + +OUI:00036F* + ID_OUI_FROM_DATABASE=Telsey SPA + +OUI:000370* + ID_OUI_FROM_DATABASE=NXTV, Inc. + +OUI:000371* + ID_OUI_FROM_DATABASE=Acomz Networks Corp. + +OUI:000372* + ID_OUI_FROM_DATABASE=ULAN + +OUI:000373* + ID_OUI_FROM_DATABASE=Aselsan A.S + +OUI:000374* + ID_OUI_FROM_DATABASE=Control Microsystems + +OUI:000375* + ID_OUI_FROM_DATABASE=NetMedia, Inc. + +OUI:000376* + ID_OUI_FROM_DATABASE=Graphtec Technology, Inc. + +OUI:000377* + ID_OUI_FROM_DATABASE=Gigabit Wireless + +OUI:000378* + ID_OUI_FROM_DATABASE=HUMAX Co., Ltd. + +OUI:000379* + ID_OUI_FROM_DATABASE=Proscend Communications, Inc. + +OUI:00037A* + ID_OUI_FROM_DATABASE=Taiyo Yuden Co., Ltd. + +OUI:00037B* + ID_OUI_FROM_DATABASE=IDEC IZUMI Corporation + +OUI:00037C* + ID_OUI_FROM_DATABASE=Coax Media + +OUI:00037D* + ID_OUI_FROM_DATABASE=Stellcom + +OUI:00037E* + ID_OUI_FROM_DATABASE=PORTech Communications, Inc. + +OUI:00037F* + ID_OUI_FROM_DATABASE=Atheros Communications, Inc. + +OUI:000380* + ID_OUI_FROM_DATABASE=SSH Communications Security Corp. + +OUI:000381* + ID_OUI_FROM_DATABASE=Ingenico International + +OUI:000382* + ID_OUI_FROM_DATABASE=A-One Co., Ltd. + +OUI:000383* + ID_OUI_FROM_DATABASE=Metera Networks, Inc. + +OUI:000384* + ID_OUI_FROM_DATABASE=AETA + +OUI:000385* + ID_OUI_FROM_DATABASE=Actelis Networks, Inc. + +OUI:000386* + ID_OUI_FROM_DATABASE=Ho Net, Inc. + +OUI:000387* + ID_OUI_FROM_DATABASE=Blaze Network Products + +OUI:000388* + ID_OUI_FROM_DATABASE=Fastfame Technology Co., Ltd. + +OUI:000389* + ID_OUI_FROM_DATABASE=Plantronics + +OUI:00038A* + ID_OUI_FROM_DATABASE=America Online, Inc. + +OUI:00038B* + ID_OUI_FROM_DATABASE=PLUS-ONE I&T, Inc. + +OUI:00038C* + ID_OUI_FROM_DATABASE=Total Impact + +OUI:00038D* + ID_OUI_FROM_DATABASE=PCS Revenue Control Systems, Inc. + +OUI:00038E* + ID_OUI_FROM_DATABASE=Atoga Systems, Inc. + +OUI:00038F* + ID_OUI_FROM_DATABASE=Weinschel Corporation + +OUI:000390* + ID_OUI_FROM_DATABASE=Digital Video Communications, Inc. + +OUI:000391* + ID_OUI_FROM_DATABASE=Advanced Digital Broadcast, Ltd. + +OUI:000392* + ID_OUI_FROM_DATABASE=Hyundai Teletek Co., Ltd. + +OUI:000393* + ID_OUI_FROM_DATABASE=Apple Computer, Inc. + +OUI:000394* + ID_OUI_FROM_DATABASE=Connect One + +OUI:000395* + ID_OUI_FROM_DATABASE=California Amplifier + +OUI:000396* + ID_OUI_FROM_DATABASE=EZ Cast Co., Ltd. + +OUI:000397* + ID_OUI_FROM_DATABASE=Watchfront Limited + +OUI:000398* + ID_OUI_FROM_DATABASE=WISI + +OUI:000399* + ID_OUI_FROM_DATABASE=Dongju Informations & Communications Co., Ltd. + +OUI:00039A* + ID_OUI_FROM_DATABASE=SiConnect + +OUI:00039B* + ID_OUI_FROM_DATABASE=NetChip Technology, Inc. + +OUI:00039C* + ID_OUI_FROM_DATABASE=OptiMight Communications, Inc. + +OUI:00039D* + ID_OUI_FROM_DATABASE=Qisda Corporation + +OUI:00039E* + ID_OUI_FROM_DATABASE=Tera System Co., Ltd. + +OUI:00039F* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0003A0* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0003A1* + ID_OUI_FROM_DATABASE=HIPER Information & Communication, Inc. + +OUI:0003A2* + ID_OUI_FROM_DATABASE=Catapult Communications + +OUI:0003A3* + ID_OUI_FROM_DATABASE=MAVIX, Ltd. + +OUI:0003A4* + ID_OUI_FROM_DATABASE=Imation Corp. + +OUI:0003A5* + ID_OUI_FROM_DATABASE=Medea Corporation + +OUI:0003A6* + ID_OUI_FROM_DATABASE=Traxit Technology, Inc. + +OUI:0003A7* + ID_OUI_FROM_DATABASE=Unixtar Technology, Inc. + +OUI:0003A8* + ID_OUI_FROM_DATABASE=IDOT Computers, Inc. + +OUI:0003A9* + ID_OUI_FROM_DATABASE=AXCENT Media AG + +OUI:0003AA* + ID_OUI_FROM_DATABASE=Watlow + +OUI:0003AB* + ID_OUI_FROM_DATABASE=Bridge Information Systems + +OUI:0003AC* + ID_OUI_FROM_DATABASE=Fronius Schweissmaschinen + +OUI:0003AD* + ID_OUI_FROM_DATABASE=Emerson Energy Systems AB + +OUI:0003AE* + ID_OUI_FROM_DATABASE=Allied Advanced Manufacturing Pte, Ltd. + +OUI:0003AF* + ID_OUI_FROM_DATABASE=Paragea Communications + +OUI:0003B0* + ID_OUI_FROM_DATABASE=Xsense Technology Corp. + +OUI:0003B1* + ID_OUI_FROM_DATABASE=Hospira Inc. + +OUI:0003B2* + ID_OUI_FROM_DATABASE=Radware + +OUI:0003B3* + ID_OUI_FROM_DATABASE=IA Link Systems Co., Ltd. + +OUI:0003B4* + ID_OUI_FROM_DATABASE=Macrotek International Corp. + +OUI:0003B5* + ID_OUI_FROM_DATABASE=Entra Technology Co. + +OUI:0003B6* + ID_OUI_FROM_DATABASE=QSI Corporation + +OUI:0003B7* + ID_OUI_FROM_DATABASE=ZACCESS Systems + +OUI:0003B8* + ID_OUI_FROM_DATABASE=NetKit Solutions, LLC + +OUI:0003B9* + ID_OUI_FROM_DATABASE=Hualong Telecom Co., Ltd. + +OUI:0003BA* + ID_OUI_FROM_DATABASE=Oracle Corporation + +OUI:0003BB* + ID_OUI_FROM_DATABASE=Signal Communications Limited + +OUI:0003BC* + ID_OUI_FROM_DATABASE=COT GmbH + +OUI:0003BD* + ID_OUI_FROM_DATABASE=OmniCluster Technologies, Inc. + +OUI:0003BE* + ID_OUI_FROM_DATABASE=Netility + +OUI:0003BF* + ID_OUI_FROM_DATABASE=Centerpoint Broadband Technologies, Inc. + +OUI:0003C0* + ID_OUI_FROM_DATABASE=RFTNC Co., Ltd. + +OUI:0003C1* + ID_OUI_FROM_DATABASE=Packet Dynamics Ltd + +OUI:0003C2* + ID_OUI_FROM_DATABASE=Solphone K.K. + +OUI:0003C3* + ID_OUI_FROM_DATABASE=Micronik Multimedia + +OUI:0003C4* + ID_OUI_FROM_DATABASE=Tomra Systems ASA + +OUI:0003C5* + ID_OUI_FROM_DATABASE=Mobotix AG + +OUI:0003C6* + ID_OUI_FROM_DATABASE=ICUE Systems, Inc. + +OUI:0003C7* + ID_OUI_FROM_DATABASE=hopf Elektronik GmbH + +OUI:0003C8* + ID_OUI_FROM_DATABASE=CML Emergency Services + +OUI:0003C9* + ID_OUI_FROM_DATABASE=TECOM Co., Ltd. + +OUI:0003CA* + ID_OUI_FROM_DATABASE=MTS Systems Corp. + +OUI:0003CB* + ID_OUI_FROM_DATABASE=Nippon Systems Development Co., Ltd. + +OUI:0003CC* + ID_OUI_FROM_DATABASE=Momentum Computer, Inc. + +OUI:0003CD* + ID_OUI_FROM_DATABASE=Clovertech, Inc. + +OUI:0003CE* + ID_OUI_FROM_DATABASE=ETEN Technologies, Inc. + +OUI:0003CF* + ID_OUI_FROM_DATABASE=Muxcom, Inc. + +OUI:0003D0* + ID_OUI_FROM_DATABASE=KOANKEISO Co., Ltd. + +OUI:0003D1* + ID_OUI_FROM_DATABASE=Takaya Corporation + +OUI:0003D2* + ID_OUI_FROM_DATABASE=Crossbeam Systems, Inc. + +OUI:0003D3* + ID_OUI_FROM_DATABASE=Internet Energy Systems, Inc. + +OUI:0003D4* + ID_OUI_FROM_DATABASE=Alloptic, Inc. + +OUI:0003D5* + ID_OUI_FROM_DATABASE=Advanced Communications Co., Ltd. + +OUI:0003D6* + ID_OUI_FROM_DATABASE=RADVision, Ltd. + +OUI:0003D7* + ID_OUI_FROM_DATABASE=NextNet Wireless, Inc. + +OUI:0003D8* + ID_OUI_FROM_DATABASE=iMPath Networks, Inc. + +OUI:0003D9* + ID_OUI_FROM_DATABASE=Secheron SA + +OUI:0003DA* + ID_OUI_FROM_DATABASE=Takamisawa Cybernetics Co., Ltd. + +OUI:0003DB* + ID_OUI_FROM_DATABASE=Apogee Electronics Corp. + +OUI:0003DC* + ID_OUI_FROM_DATABASE=Lexar Media, Inc. + +OUI:0003DD* + ID_OUI_FROM_DATABASE=Comark Corp. + +OUI:0003DE* + ID_OUI_FROM_DATABASE=OTC Wireless + +OUI:0003DF* + ID_OUI_FROM_DATABASE=Desana Systems + +OUI:0003E0* + ID_OUI_FROM_DATABASE=Motorola, Inc. + +OUI:0003E1* + ID_OUI_FROM_DATABASE=Winmate Communication, Inc. + +OUI:0003E2* + ID_OUI_FROM_DATABASE=Comspace Corporation + +OUI:0003E3* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0003E4* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0003E5* + ID_OUI_FROM_DATABASE=Hermstedt SG + +OUI:0003E6* + ID_OUI_FROM_DATABASE=Entone, Inc. + +OUI:0003E7* + ID_OUI_FROM_DATABASE=Logostek Co. Ltd. + +OUI:0003E8* + ID_OUI_FROM_DATABASE=Wavelength Digital Limited + +OUI:0003E9* + ID_OUI_FROM_DATABASE=Akara Canada, Inc. + +OUI:0003EA* + ID_OUI_FROM_DATABASE=Mega System Technologies, Inc. + +OUI:0003EB* + ID_OUI_FROM_DATABASE=Atrica + +OUI:0003EC* + ID_OUI_FROM_DATABASE=ICG Research, Inc. + +OUI:0003ED* + ID_OUI_FROM_DATABASE=Shinkawa Electric Co., Ltd. + +OUI:0003EE* + ID_OUI_FROM_DATABASE=MKNet Corporation + +OUI:0003EF* + ID_OUI_FROM_DATABASE=Oneline AG + +OUI:0003F0* + ID_OUI_FROM_DATABASE=Redfern Broadband Networks + +OUI:0003F1* + ID_OUI_FROM_DATABASE=Cicada Semiconductor, Inc. + +OUI:0003F2* + ID_OUI_FROM_DATABASE=Seneca Networks + +OUI:0003F3* + ID_OUI_FROM_DATABASE=Dazzle Multimedia, Inc. + +OUI:0003F4* + ID_OUI_FROM_DATABASE=NetBurner + +OUI:0003F5* + ID_OUI_FROM_DATABASE=Chip2Chip + +OUI:0003F6* + ID_OUI_FROM_DATABASE=Allegro Networks, Inc. + +OUI:0003F7* + ID_OUI_FROM_DATABASE=Plast-Control GmbH + +OUI:0003F8* + ID_OUI_FROM_DATABASE=SanCastle Technologies, Inc. + +OUI:0003F9* + ID_OUI_FROM_DATABASE=Pleiades Communications, Inc. + +OUI:0003FA* + ID_OUI_FROM_DATABASE=TiMetra Networks + +OUI:0003FB* + ID_OUI_FROM_DATABASE=ENEGATE Co.,Ltd. + +OUI:0003FC* + ID_OUI_FROM_DATABASE=Intertex Data AB + +OUI:0003FD* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0003FE* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0003FF* + ID_OUI_FROM_DATABASE=Microsoft Corporation + +OUI:000400* + ID_OUI_FROM_DATABASE=LEXMARK INTERNATIONAL, INC. + +OUI:000401* + ID_OUI_FROM_DATABASE=Osaki Electric Co., Ltd. + +OUI:000402* + ID_OUI_FROM_DATABASE=Nexsan Technologies, Ltd. + +OUI:000403* + ID_OUI_FROM_DATABASE=Nexsi Corporation + +OUI:000404* + ID_OUI_FROM_DATABASE=Makino Milling Machine Co., Ltd. + +OUI:000405* + ID_OUI_FROM_DATABASE=ACN Technologies + +OUI:000406* + ID_OUI_FROM_DATABASE=Fa. Metabox AG + +OUI:000407* + ID_OUI_FROM_DATABASE=Topcon Positioning Systems, Inc. + +OUI:000408* + ID_OUI_FROM_DATABASE=Sanko Electronics Co., Ltd. + +OUI:000409* + ID_OUI_FROM_DATABASE=Cratos Networks + +OUI:00040A* + ID_OUI_FROM_DATABASE=Sage Systems + +OUI:00040B* + ID_OUI_FROM_DATABASE=3com Europe Ltd. + +OUI:00040C* + ID_OUI_FROM_DATABASE=KANNO Work's Ltd. + +OUI:00040D* + ID_OUI_FROM_DATABASE=Avaya, Inc. + +OUI:00040E* + ID_OUI_FROM_DATABASE=AVM GmbH + +OUI:00040F* + ID_OUI_FROM_DATABASE=Asus Network Technologies, Inc. + +OUI:000410* + ID_OUI_FROM_DATABASE=Spinnaker Networks, Inc. + +OUI:000411* + ID_OUI_FROM_DATABASE=Inkra Networks, Inc. + +OUI:000412* + ID_OUI_FROM_DATABASE=WaveSmith Networks, Inc. + +OUI:000413* + ID_OUI_FROM_DATABASE=SNOM Technology AG + +OUI:000414* + ID_OUI_FROM_DATABASE=Umezawa Musen Denki Co., Ltd. + +OUI:000415* + ID_OUI_FROM_DATABASE=Rasteme Systems Co., Ltd. + +OUI:000416* + ID_OUI_FROM_DATABASE=Parks S/A Comunicacoes Digitais + +OUI:000417* + ID_OUI_FROM_DATABASE=ELAU AG + +OUI:000418* + ID_OUI_FROM_DATABASE=Teltronic S.A.U. + +OUI:000419* + ID_OUI_FROM_DATABASE=Fibercycle Networks, Inc. + +OUI:00041A* + ID_OUI_FROM_DATABASE=Ines Test and Measurement GmbH & CoKG + +OUI:00041B* + ID_OUI_FROM_DATABASE=Bridgeworks Ltd. + +OUI:00041C* + ID_OUI_FROM_DATABASE=ipDialog, Inc. + +OUI:00041D* + ID_OUI_FROM_DATABASE=Corega of America + +OUI:00041E* + ID_OUI_FROM_DATABASE=Shikoku Instrumentation Co., Ltd. + +OUI:00041F* + ID_OUI_FROM_DATABASE=Sony Computer Entertainment, Inc. + +OUI:000420* + ID_OUI_FROM_DATABASE=Slim Devices, Inc. + +OUI:000421* + ID_OUI_FROM_DATABASE=Ocular Networks + +OUI:000422* + ID_OUI_FROM_DATABASE=Gordon Kapes, Inc. + +OUI:000423* + ID_OUI_FROM_DATABASE=Intel Corporation + +OUI:000424* + ID_OUI_FROM_DATABASE=TMC s.r.l. + +OUI:000425* + ID_OUI_FROM_DATABASE=Atmel Corporation + +OUI:000426* + ID_OUI_FROM_DATABASE=Autosys + +OUI:000427* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000428* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000429* + ID_OUI_FROM_DATABASE=Pixord Corporation + +OUI:00042A* + ID_OUI_FROM_DATABASE=Wireless Networks, Inc. + +OUI:00042B* + ID_OUI_FROM_DATABASE=IT Access Co., Ltd. + +OUI:00042C* + ID_OUI_FROM_DATABASE=Minet, Inc. + +OUI:00042D* + ID_OUI_FROM_DATABASE=Sarian Systems, Ltd. + +OUI:00042E* + ID_OUI_FROM_DATABASE=Netous Technologies, Ltd. + +OUI:00042F* + ID_OUI_FROM_DATABASE=International Communications Products, Inc. + +OUI:000430* + ID_OUI_FROM_DATABASE=Netgem + +OUI:000431* + ID_OUI_FROM_DATABASE=GlobalStreams, Inc. + +OUI:000432* + ID_OUI_FROM_DATABASE=Voyetra Turtle Beach, Inc. + +OUI:000433* + ID_OUI_FROM_DATABASE=Cyberboard A/S + +OUI:000434* + ID_OUI_FROM_DATABASE=Accelent Systems, Inc. + +OUI:000435* + ID_OUI_FROM_DATABASE=Comptek International, Inc. + +OUI:000436* + ID_OUI_FROM_DATABASE=ELANsat Technologies, Inc. + +OUI:000437* + ID_OUI_FROM_DATABASE=Powin Information Technology, Inc. + +OUI:000438* + ID_OUI_FROM_DATABASE=Nortel Networks + +OUI:000439* + ID_OUI_FROM_DATABASE=Rosco Entertainment Technology, Inc. + +OUI:00043A* + ID_OUI_FROM_DATABASE=Intelligent Telecommunications, Inc. + +OUI:00043B* + ID_OUI_FROM_DATABASE=Lava Computer Mfg., Inc. + +OUI:00043C* + ID_OUI_FROM_DATABASE=SONOS Co., Ltd. + +OUI:00043D* + ID_OUI_FROM_DATABASE=INDEL AG + +OUI:00043E* + ID_OUI_FROM_DATABASE=Telencomm + +OUI:00043F* + ID_OUI_FROM_DATABASE=ESTeem Wireless Modems, Inc + +OUI:000440* + ID_OUI_FROM_DATABASE=cyberPIXIE, Inc. + +OUI:000441* + ID_OUI_FROM_DATABASE=Half Dome Systems, Inc. + +OUI:000442* + ID_OUI_FROM_DATABASE=NACT + +OUI:000443* + ID_OUI_FROM_DATABASE=Agilent Technologies, Inc. + +OUI:000444* + ID_OUI_FROM_DATABASE=Western Multiplex Corporation + +OUI:000445* + ID_OUI_FROM_DATABASE=LMS Skalar Instruments GmbH + +OUI:000446* + ID_OUI_FROM_DATABASE=CYZENTECH Co., Ltd. + +OUI:000447* + ID_OUI_FROM_DATABASE=Acrowave Systems Co., Ltd. + +OUI:000448* + ID_OUI_FROM_DATABASE=Polaroid Corporation + +OUI:000449* + ID_OUI_FROM_DATABASE=Mapletree Networks + +OUI:00044A* + ID_OUI_FROM_DATABASE=iPolicy Networks, Inc. + +OUI:00044B* + ID_OUI_FROM_DATABASE=NVIDIA + +OUI:00044C* + ID_OUI_FROM_DATABASE=JENOPTIK + +OUI:00044D* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00044E* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00044F* + ID_OUI_FROM_DATABASE=Leukhardt Systemelektronik GmbH + +OUI:000450* + ID_OUI_FROM_DATABASE=DMD Computers SRL + +OUI:000451* + ID_OUI_FROM_DATABASE=Medrad, Inc. + +OUI:000452* + ID_OUI_FROM_DATABASE=RocketLogix, Inc. + +OUI:000453* + ID_OUI_FROM_DATABASE=YottaYotta, Inc. + +OUI:000454* + ID_OUI_FROM_DATABASE=Quadriga UK + +OUI:000455* + ID_OUI_FROM_DATABASE=ANTARA.net + +OUI:000456* + ID_OUI_FROM_DATABASE=Cambium Networks Limited + +OUI:000457* + ID_OUI_FROM_DATABASE=Universal Access Technology, Inc. + +OUI:000458* + ID_OUI_FROM_DATABASE=Fusion X Co., Ltd. + +OUI:000459* + ID_OUI_FROM_DATABASE=Veristar Corporation + +OUI:00045A* + ID_OUI_FROM_DATABASE=The Linksys Group, Inc. + +OUI:00045B* + ID_OUI_FROM_DATABASE=Techsan Electronics Co., Ltd. + +OUI:00045C* + ID_OUI_FROM_DATABASE=Mobiwave Pte Ltd + +OUI:00045D* + ID_OUI_FROM_DATABASE=BEKA Elektronik + +OUI:00045E* + ID_OUI_FROM_DATABASE=PolyTrax Information Technology AG + +OUI:00045F* + ID_OUI_FROM_DATABASE=Evalue Technology, Inc. + +OUI:000460* + ID_OUI_FROM_DATABASE=Knilink Technology, Inc. + +OUI:000461* + ID_OUI_FROM_DATABASE=EPOX Computer Co., Ltd. + +OUI:000462* + ID_OUI_FROM_DATABASE=DAKOS Data & Communication Co., Ltd. + +OUI:000463* + ID_OUI_FROM_DATABASE=Bosch Security Systems + +OUI:000464* + ID_OUI_FROM_DATABASE=Fantasma Networks, Inc. + +OUI:000465* + ID_OUI_FROM_DATABASE=i.s.t isdn-support technik GmbH + +OUI:000466* + ID_OUI_FROM_DATABASE=ARMITEL Co. + +OUI:000467* + ID_OUI_FROM_DATABASE=Wuhan Research Institute of MII + +OUI:000468* + ID_OUI_FROM_DATABASE=Vivity, Inc. + +OUI:000469* + ID_OUI_FROM_DATABASE=Innocom, Inc. + +OUI:00046A* + ID_OUI_FROM_DATABASE=Navini Networks + +OUI:00046B* + ID_OUI_FROM_DATABASE=Palm Wireless, Inc. + +OUI:00046C* + ID_OUI_FROM_DATABASE=Cyber Technology Co., Ltd. + +OUI:00046D* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00046E* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00046F* + ID_OUI_FROM_DATABASE=Digitel S/A Industria Eletronica + +OUI:000470* + ID_OUI_FROM_DATABASE=ipUnplugged AB + +OUI:000471* + ID_OUI_FROM_DATABASE=IPrad + +OUI:000472* + ID_OUI_FROM_DATABASE=Telelynx, Inc. + +OUI:000473* + ID_OUI_FROM_DATABASE=Photonex Corporation + +OUI:000474* + ID_OUI_FROM_DATABASE=LEGRAND + +OUI:000475* + ID_OUI_FROM_DATABASE=3 Com Corporation + +OUI:000476* + ID_OUI_FROM_DATABASE=3 Com Corporation + +OUI:000477* + ID_OUI_FROM_DATABASE=Scalant Systems, Inc. + +OUI:000478* + ID_OUI_FROM_DATABASE=G. Star Technology Corporation + +OUI:000479* + ID_OUI_FROM_DATABASE=Radius Co., Ltd. + +OUI:00047A* + ID_OUI_FROM_DATABASE=AXXESSIT ASA + +OUI:00047B* + ID_OUI_FROM_DATABASE=Schlumberger + +OUI:00047C* + ID_OUI_FROM_DATABASE=Skidata AG + +OUI:00047D* + ID_OUI_FROM_DATABASE=Pelco + +OUI:00047E* + ID_OUI_FROM_DATABASE=Siqura B.V. + +OUI:00047F* + ID_OUI_FROM_DATABASE=Chr. Mayr GmbH & Co. KG + +OUI:000480* + ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc + +OUI:000481* + ID_OUI_FROM_DATABASE=Econolite Control Products, Inc. + +OUI:000482* + ID_OUI_FROM_DATABASE=Medialogic Corp. + +OUI:000483* + ID_OUI_FROM_DATABASE=Deltron Technology, Inc. + +OUI:000484* + ID_OUI_FROM_DATABASE=Amann GmbH + +OUI:000485* + ID_OUI_FROM_DATABASE=PicoLight + +OUI:000486* + ID_OUI_FROM_DATABASE=ITTC, University of Kansas + +OUI:000487* + ID_OUI_FROM_DATABASE=Cogency Semiconductor, Inc. + +OUI:000488* + ID_OUI_FROM_DATABASE=Eurotherm Controls + +OUI:000489* + ID_OUI_FROM_DATABASE=YAFO Networks, Inc. + +OUI:00048A* + ID_OUI_FROM_DATABASE=Temia Vertriebs GmbH + +OUI:00048B* + ID_OUI_FROM_DATABASE=Poscon Corporation + +OUI:00048C* + ID_OUI_FROM_DATABASE=Nayna Networks, Inc. + +OUI:00048D* + ID_OUI_FROM_DATABASE=Tone Commander Systems, Inc. + +OUI:00048E* + ID_OUI_FROM_DATABASE=Ohm Tech Labs, Inc. + +OUI:00048F* + ID_OUI_FROM_DATABASE=TD Systems Corporation + +OUI:000490* + ID_OUI_FROM_DATABASE=Optical Access + +OUI:000491* + ID_OUI_FROM_DATABASE=Technovision, Inc. + +OUI:000492* + ID_OUI_FROM_DATABASE=Hive Internet, Ltd. + +OUI:000493* + ID_OUI_FROM_DATABASE=Tsinghua Unisplendour Co., Ltd. + +OUI:000494* + ID_OUI_FROM_DATABASE=Breezecom, Ltd. + +OUI:000495* + ID_OUI_FROM_DATABASE=Tejas Networks India Limited + +OUI:000496* + ID_OUI_FROM_DATABASE=Extreme Networks + +OUI:000497* + ID_OUI_FROM_DATABASE=MacroSystem Digital Video AG + +OUI:000498* + ID_OUI_FROM_DATABASE=Mahi Networks + +OUI:000499* + ID_OUI_FROM_DATABASE=Chino Corporation + +OUI:00049A* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00049B* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00049C* + ID_OUI_FROM_DATABASE=Surgient Networks, Inc. + +OUI:00049D* + ID_OUI_FROM_DATABASE=Ipanema Technologies + +OUI:00049E* + ID_OUI_FROM_DATABASE=Wirelink Co., Ltd. + +OUI:00049F* + ID_OUI_FROM_DATABASE=Freescale Semiconductor + +OUI:0004A0* + ID_OUI_FROM_DATABASE=Verity Instruments, Inc. + +OUI:0004A1* + ID_OUI_FROM_DATABASE=Pathway Connectivity + +OUI:0004A2* + ID_OUI_FROM_DATABASE=L.S.I. Japan Co., Ltd. + +OUI:0004A3* + ID_OUI_FROM_DATABASE=Microchip Technology, Inc. + +OUI:0004A4* + ID_OUI_FROM_DATABASE=NetEnabled, Inc. + +OUI:0004A5* + ID_OUI_FROM_DATABASE=Barco Projection Systems NV + +OUI:0004A6* + ID_OUI_FROM_DATABASE=SAF Tehnika Ltd. + +OUI:0004A7* + ID_OUI_FROM_DATABASE=FabiaTech Corporation + +OUI:0004A8* + ID_OUI_FROM_DATABASE=Broadmax Technologies, Inc. + +OUI:0004A9* + ID_OUI_FROM_DATABASE=SandStream Technologies, Inc. + +OUI:0004AA* + ID_OUI_FROM_DATABASE=Jetstream Communications + +OUI:0004AB* + ID_OUI_FROM_DATABASE=Comverse Network Systems, Inc. + +OUI:0004AC* + ID_OUI_FROM_DATABASE=IBM Corp + +OUI:0004AD* + ID_OUI_FROM_DATABASE=Malibu Networks + +OUI:0004AE* + ID_OUI_FROM_DATABASE=Sullair Corporation + +OUI:0004AF* + ID_OUI_FROM_DATABASE=Digital Fountain, Inc. + +OUI:0004B0* + ID_OUI_FROM_DATABASE=ELESIGN Co., Ltd. + +OUI:0004B1* + ID_OUI_FROM_DATABASE=Signal Technology, Inc. + +OUI:0004B2* + ID_OUI_FROM_DATABASE=ESSEGI SRL + +OUI:0004B3* + ID_OUI_FROM_DATABASE=Videotek, Inc. + +OUI:0004B4* + ID_OUI_FROM_DATABASE=CIAC + +OUI:0004B5* + ID_OUI_FROM_DATABASE=Equitrac Corporation + +OUI:0004B6* + ID_OUI_FROM_DATABASE=Stratex Networks, Inc. + +OUI:0004B7* + ID_OUI_FROM_DATABASE=AMB i.t. Holding + +OUI:0004B8* + ID_OUI_FROM_DATABASE=Kumahira Co., Ltd. + +OUI:0004B9* + ID_OUI_FROM_DATABASE=S.I. Soubou, Inc. + +OUI:0004BA* + ID_OUI_FROM_DATABASE=KDD Media Will Corporation + +OUI:0004BB* + ID_OUI_FROM_DATABASE=Bardac Corporation + +OUI:0004BC* + ID_OUI_FROM_DATABASE=Giantec, Inc. + +OUI:0004BD* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:0004BE* + ID_OUI_FROM_DATABASE=OptXCon, Inc. + +OUI:0004BF* + ID_OUI_FROM_DATABASE=VersaLogic Corp. + +OUI:0004C0* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0004C1* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0004C2* + ID_OUI_FROM_DATABASE=Magnipix, Inc. + +OUI:0004C3* + ID_OUI_FROM_DATABASE=CASTOR Informatique + +OUI:0004C4* + ID_OUI_FROM_DATABASE=Allen & Heath Limited + +OUI:0004C5* + ID_OUI_FROM_DATABASE=ASE Technologies, USA + +OUI:0004C6* + ID_OUI_FROM_DATABASE=Yamaha Motor Co., Ltd. + +OUI:0004C7* + ID_OUI_FROM_DATABASE=NetMount + +OUI:0004C8* + ID_OUI_FROM_DATABASE=LIBA Maschinenfabrik GmbH + +OUI:0004C9* + ID_OUI_FROM_DATABASE=Micro Electron Co., Ltd. + +OUI:0004CA* + ID_OUI_FROM_DATABASE=FreeMs Corp. + +OUI:0004CB* + ID_OUI_FROM_DATABASE=Tdsoft Communication, Ltd. + +OUI:0004CC* + ID_OUI_FROM_DATABASE=Peek Traffic B.V. + +OUI:0004CD* + ID_OUI_FROM_DATABASE=Informedia Research Group + +OUI:0004CE* + ID_OUI_FROM_DATABASE=Patria Ailon + +OUI:0004CF* + ID_OUI_FROM_DATABASE=Seagate Technology + +OUI:0004D0* + ID_OUI_FROM_DATABASE=Softlink s.r.o. + +OUI:0004D1* + ID_OUI_FROM_DATABASE=Drew Technologies, Inc. + +OUI:0004D2* + ID_OUI_FROM_DATABASE=Adcon Telemetry GmbH + +OUI:0004D3* + ID_OUI_FROM_DATABASE=Toyokeiki Co., Ltd. + +OUI:0004D4* + ID_OUI_FROM_DATABASE=Proview Electronics Co., Ltd. + +OUI:0004D5* + ID_OUI_FROM_DATABASE=Hitachi Information & Communication Engineering, Ltd. + +OUI:0004D6* + ID_OUI_FROM_DATABASE=Takagi Industrial Co., Ltd. + +OUI:0004D7* + ID_OUI_FROM_DATABASE=Omitec Instrumentation Ltd. + +OUI:0004D8* + ID_OUI_FROM_DATABASE=IPWireless, Inc. + +OUI:0004D9* + ID_OUI_FROM_DATABASE=Titan Electronics, Inc. + +OUI:0004DA* + ID_OUI_FROM_DATABASE=Relax Technology, Inc. + +OUI:0004DB* + ID_OUI_FROM_DATABASE=Tellus Group Corp. + +OUI:0004DC* + ID_OUI_FROM_DATABASE=Nortel Networks + +OUI:0004DD* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0004DE* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0004DF* + ID_OUI_FROM_DATABASE=Teracom Telematica Ltda. + +OUI:0004E0* + ID_OUI_FROM_DATABASE=Procket Networks + +OUI:0004E1* + ID_OUI_FROM_DATABASE=Infinior Microsystems + +OUI:0004E2* + ID_OUI_FROM_DATABASE=SMC Networks, Inc. + +OUI:0004E3* + ID_OUI_FROM_DATABASE=Accton Technology Corp. + +OUI:0004E4* + ID_OUI_FROM_DATABASE=Daeryung Ind., Inc. + +OUI:0004E5* + ID_OUI_FROM_DATABASE=Glonet Systems, Inc. + +OUI:0004E6* + ID_OUI_FROM_DATABASE=Banyan Network Private Limited + +OUI:0004E7* + ID_OUI_FROM_DATABASE=Lightpointe Communications, Inc + +OUI:0004E8* + ID_OUI_FROM_DATABASE=IER, Inc. + +OUI:0004E9* + ID_OUI_FROM_DATABASE=Infiniswitch Corporation + +OUI:0004EA* + ID_OUI_FROM_DATABASE=Hewlett-Packard Company + +OUI:0004EB* + ID_OUI_FROM_DATABASE=Paxonet Communications, Inc. + +OUI:0004EC* + ID_OUI_FROM_DATABASE=Memobox SA + +OUI:0004ED* + ID_OUI_FROM_DATABASE=Billion Electric Co., Ltd. + +OUI:0004EE* + ID_OUI_FROM_DATABASE=Lincoln Electric Company + +OUI:0004EF* + ID_OUI_FROM_DATABASE=Polestar Corp. + +OUI:0004F0* + ID_OUI_FROM_DATABASE=International Computers, Ltd + +OUI:0004F1* + ID_OUI_FROM_DATABASE=WhereNet + +OUI:0004F2* + ID_OUI_FROM_DATABASE=Polycom + +OUI:0004F3* + ID_OUI_FROM_DATABASE=FS FORTH-SYSTEME GmbH + +OUI:0004F4* + ID_OUI_FROM_DATABASE=Infinite Electronics Inc. + +OUI:0004F5* + ID_OUI_FROM_DATABASE=SnowShore Networks, Inc. + +OUI:0004F6* + ID_OUI_FROM_DATABASE=Amphus + +OUI:0004F7* + ID_OUI_FROM_DATABASE=Omega Band, Inc. + +OUI:0004F8* + ID_OUI_FROM_DATABASE=QUALICABLE TV Industria E Com., Ltda + +OUI:0004F9* + ID_OUI_FROM_DATABASE=Xtera Communications, Inc. + +OUI:0004FA* + ID_OUI_FROM_DATABASE=NBS Technologies Inc. + +OUI:0004FB* + ID_OUI_FROM_DATABASE=Commtech, Inc. + +OUI:0004FC* + ID_OUI_FROM_DATABASE=Stratus Computer (DE), Inc. + +OUI:0004FD* + ID_OUI_FROM_DATABASE=Japan Control Engineering Co., Ltd. + +OUI:0004FE* + ID_OUI_FROM_DATABASE=Pelago Networks + +OUI:0004FF* + ID_OUI_FROM_DATABASE=Acronet Co., Ltd. + +OUI:000500* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000501* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000502* + ID_OUI_FROM_DATABASE=APPLE COMPUTER + +OUI:000503* + ID_OUI_FROM_DATABASE=ICONAG + +OUI:000504* + ID_OUI_FROM_DATABASE=Naray Information & Communication Enterprise + +OUI:000505* + ID_OUI_FROM_DATABASE=Systems Integration Solutions, Inc. + +OUI:000506* + ID_OUI_FROM_DATABASE=Reddo Networks AB + +OUI:000507* + ID_OUI_FROM_DATABASE=Fine Appliance Corp. + +OUI:000508* + ID_OUI_FROM_DATABASE=Inetcam, Inc. + +OUI:000509* + ID_OUI_FROM_DATABASE=AVOC Nishimura Ltd. + +OUI:00050A* + ID_OUI_FROM_DATABASE=ICS Spa + +OUI:00050B* + ID_OUI_FROM_DATABASE=SICOM Systems, Inc. + +OUI:00050C* + ID_OUI_FROM_DATABASE=Network Photonics, Inc. + +OUI:00050D* + ID_OUI_FROM_DATABASE=Midstream Technologies, Inc. + +OUI:00050E* + ID_OUI_FROM_DATABASE=3ware, Inc. + +OUI:00050F* + ID_OUI_FROM_DATABASE=Tanaka S/S Ltd. + +OUI:000510* + ID_OUI_FROM_DATABASE=Infinite Shanghai Communication Terminals Ltd. + +OUI:000511* + ID_OUI_FROM_DATABASE=Complementary Technologies Ltd + +OUI:000512* + ID_OUI_FROM_DATABASE=MeshNetworks, Inc. + +OUI:000513* + ID_OUI_FROM_DATABASE=VTLinx Multimedia Systems, Inc. + +OUI:000514* + ID_OUI_FROM_DATABASE=KDT Systems Co., Ltd. + +OUI:000515* + ID_OUI_FROM_DATABASE=Nuark Co., Ltd. + +OUI:000516* + ID_OUI_FROM_DATABASE=SMART Modular Technologies + +OUI:000517* + ID_OUI_FROM_DATABASE=Shellcomm, Inc. + +OUI:000518* + ID_OUI_FROM_DATABASE=Jupiters Technology + +OUI:000519* + ID_OUI_FROM_DATABASE=Siemens Building Technologies AG, + +OUI:00051A* + ID_OUI_FROM_DATABASE=3Com Europe Ltd. + +OUI:00051B* + ID_OUI_FROM_DATABASE=Magic Control Technology Corporation + +OUI:00051C* + ID_OUI_FROM_DATABASE=Xnet Technology Corp. + +OUI:00051D* + ID_OUI_FROM_DATABASE=Airocon, Inc. + +OUI:00051E* + ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc. + +OUI:00051F* + ID_OUI_FROM_DATABASE=Taijin Media Co., Ltd. + +OUI:000520* + ID_OUI_FROM_DATABASE=Smartronix, Inc. + +OUI:000521* + ID_OUI_FROM_DATABASE=Control Microsystems + +OUI:000522* + ID_OUI_FROM_DATABASE=LEA*D Corporation, Inc. + +OUI:000523* + ID_OUI_FROM_DATABASE=AVL List GmbH + +OUI:000524* + ID_OUI_FROM_DATABASE=BTL System (HK) Limited + +OUI:000525* + ID_OUI_FROM_DATABASE=Puretek Industrial Co., Ltd. + +OUI:000526* + ID_OUI_FROM_DATABASE=IPAS GmbH + +OUI:000527* + ID_OUI_FROM_DATABASE=SJ Tek Co. Ltd + +OUI:000528* + ID_OUI_FROM_DATABASE=New Focus, Inc. + +OUI:000529* + ID_OUI_FROM_DATABASE=Shanghai Broadan Communication Technology Co., Ltd + +OUI:00052A* + ID_OUI_FROM_DATABASE=Ikegami Tsushinki Co., Ltd. + +OUI:00052B* + ID_OUI_FROM_DATABASE=HORIBA, Ltd. + +OUI:00052C* + ID_OUI_FROM_DATABASE=Supreme Magic Corporation + +OUI:00052D* + ID_OUI_FROM_DATABASE=Zoltrix International Limited + +OUI:00052E* + ID_OUI_FROM_DATABASE=Cinta Networks + +OUI:00052F* + ID_OUI_FROM_DATABASE=Leviton Network Solutions + +OUI:000530* + ID_OUI_FROM_DATABASE=Andiamo Systems, Inc. + +OUI:000531* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000532* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000533* + ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc. + +OUI:000534* + ID_OUI_FROM_DATABASE=Northstar Engineering Ltd. + +OUI:000535* + ID_OUI_FROM_DATABASE=Chip PC Ltd. + +OUI:000536* + ID_OUI_FROM_DATABASE=Danam Communications, Inc. + +OUI:000537* + ID_OUI_FROM_DATABASE=Nets Technology Co., Ltd. + +OUI:000538* + ID_OUI_FROM_DATABASE=Merilus, Inc. + +OUI:000539* + ID_OUI_FROM_DATABASE=A Brand New World in Sweden AB + +OUI:00053A* + ID_OUI_FROM_DATABASE=Willowglen Services Pte Ltd + +OUI:00053B* + ID_OUI_FROM_DATABASE=Harbour Networks Ltd., Co. Beijing + +OUI:00053C* + ID_OUI_FROM_DATABASE=Xircom + +OUI:00053D* + ID_OUI_FROM_DATABASE=Agere Systems + +OUI:00053E* + ID_OUI_FROM_DATABASE=KID Systeme GmbH + +OUI:00053F* + ID_OUI_FROM_DATABASE=VisionTek, Inc. + +OUI:000540* + ID_OUI_FROM_DATABASE=FAST Corporation + +OUI:000541* + ID_OUI_FROM_DATABASE=Advanced Systems Co., Ltd. + +OUI:000542* + ID_OUI_FROM_DATABASE=Otari, Inc. + +OUI:000543* + ID_OUI_FROM_DATABASE=IQ Wireless GmbH + +OUI:000544* + ID_OUI_FROM_DATABASE=Valley Technologies, Inc. + +OUI:000545* + ID_OUI_FROM_DATABASE=Internet Photonics + +OUI:000546* + ID_OUI_FROM_DATABASE=KDDI Network & Solultions Inc. + +OUI:000547* + ID_OUI_FROM_DATABASE=Starent Networks + +OUI:000548* + ID_OUI_FROM_DATABASE=Disco Corporation + +OUI:000549* + ID_OUI_FROM_DATABASE=Salira Optical Network Systems + +OUI:00054A* + ID_OUI_FROM_DATABASE=Ario Data Networks, Inc. + +OUI:00054B* + ID_OUI_FROM_DATABASE=Eaton Automation AG + +OUI:00054C* + ID_OUI_FROM_DATABASE=RF Innovations Pty Ltd + +OUI:00054D* + ID_OUI_FROM_DATABASE=Brans Technologies, Inc. + +OUI:00054E* + ID_OUI_FROM_DATABASE=Philips + +OUI:000550* + ID_OUI_FROM_DATABASE=Vcomms Connect Limited + +OUI:000551* + ID_OUI_FROM_DATABASE=F & S Elektronik Systeme GmbH + +OUI:000552* + ID_OUI_FROM_DATABASE=Xycotec Computer GmbH + +OUI:000553* + ID_OUI_FROM_DATABASE=DVC Company, Inc. + +OUI:000554* + ID_OUI_FROM_DATABASE=Rangestar Wireless + +OUI:000555* + ID_OUI_FROM_DATABASE=Japan Cash Machine Co., Ltd. + +OUI:000556* + ID_OUI_FROM_DATABASE=360 Systems + +OUI:000557* + ID_OUI_FROM_DATABASE=Agile TV Corporation + +OUI:000558* + ID_OUI_FROM_DATABASE=Synchronous, Inc. + +OUI:000559* + ID_OUI_FROM_DATABASE=Intracom S.A. + +OUI:00055A* + ID_OUI_FROM_DATABASE=Power Dsine Ltd. + +OUI:00055B* + ID_OUI_FROM_DATABASE=Charles Industries, Ltd. + +OUI:00055C* + ID_OUI_FROM_DATABASE=Kowa Company, Ltd. + +OUI:00055D* + ID_OUI_FROM_DATABASE=D-Link Systems, Inc. + +OUI:00055E* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00055F* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000560* + ID_OUI_FROM_DATABASE=LEADER COMM.CO., LTD + +OUI:000561* + ID_OUI_FROM_DATABASE=nac Image Technology, Inc. + +OUI:000562* + ID_OUI_FROM_DATABASE=Digital View Limited + +OUI:000563* + ID_OUI_FROM_DATABASE=J-Works, Inc. + +OUI:000564* + ID_OUI_FROM_DATABASE=Tsinghua Bitway Co., Ltd. + +OUI:000565* + ID_OUI_FROM_DATABASE=Tailyn Communication Company Ltd. + +OUI:000566* + ID_OUI_FROM_DATABASE=Secui.com Corporation + +OUI:000567* + ID_OUI_FROM_DATABASE=Etymonic Design, Inc. + +OUI:000568* + ID_OUI_FROM_DATABASE=Piltofish Networks AB + +OUI:000569* + ID_OUI_FROM_DATABASE=VMware, Inc. + +OUI:00056A* + ID_OUI_FROM_DATABASE=Heuft Systemtechnik GmbH + +OUI:00056B* + ID_OUI_FROM_DATABASE=C.P. Technology Co., Ltd. + +OUI:00056C* + ID_OUI_FROM_DATABASE=Hung Chang Co., Ltd. + +OUI:00056D* + ID_OUI_FROM_DATABASE=Pacific Corporation + +OUI:00056E* + ID_OUI_FROM_DATABASE=National Enhance Technology, Inc. + +OUI:00056F* + ID_OUI_FROM_DATABASE=Innomedia Technologies Pvt. Ltd. + +OUI:000570* + ID_OUI_FROM_DATABASE=Baydel Ltd. + +OUI:000571* + ID_OUI_FROM_DATABASE=Seiwa Electronics Co. + +OUI:000572* + ID_OUI_FROM_DATABASE=Deonet Co., Ltd. + +OUI:000573* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000574* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000575* + ID_OUI_FROM_DATABASE=CDS-Electronics BV + +OUI:000576* + ID_OUI_FROM_DATABASE=NSM Technology Ltd. + +OUI:000577* + ID_OUI_FROM_DATABASE=SM Information & Communication + +OUI:000579* + ID_OUI_FROM_DATABASE=Universal Control Solution Corp. + +OUI:00057A* + ID_OUI_FROM_DATABASE=Overture Networks + +OUI:00057B* + ID_OUI_FROM_DATABASE=Chung Nam Electronic Co., Ltd. + +OUI:00057C* + ID_OUI_FROM_DATABASE=RCO Security AB + +OUI:00057D* + ID_OUI_FROM_DATABASE=Sun Communications, Inc. + +OUI:00057E* + ID_OUI_FROM_DATABASE=Eckelmann Steuerungstechnik GmbH + +OUI:00057F* + ID_OUI_FROM_DATABASE=Acqis Technology + +OUI:000580* + ID_OUI_FROM_DATABASE=Fibrolan Ltd. + +OUI:000581* + ID_OUI_FROM_DATABASE=Snell + +OUI:000582* + ID_OUI_FROM_DATABASE=ClearCube Technology + +OUI:000583* + ID_OUI_FROM_DATABASE=ImageCom Limited + +OUI:000584* + ID_OUI_FROM_DATABASE=AbsoluteValue Systems, Inc. + +OUI:000585* + ID_OUI_FROM_DATABASE=Juniper Networks, Inc. + +OUI:000586* + ID_OUI_FROM_DATABASE=Lucent Technologies + +OUI:000587* + ID_OUI_FROM_DATABASE=Locus, Incorporated + +OUI:000588* + ID_OUI_FROM_DATABASE=Sensoria Corp. + +OUI:000589* + ID_OUI_FROM_DATABASE=National Datacomputer + +OUI:00058A* + ID_OUI_FROM_DATABASE=Netcom Co., Ltd. + +OUI:00058B* + ID_OUI_FROM_DATABASE=IPmental, Inc. + +OUI:00058C* + ID_OUI_FROM_DATABASE=Opentech Inc. + +OUI:00058D* + ID_OUI_FROM_DATABASE=Lynx Photonic Networks, Inc. + +OUI:00058E* + ID_OUI_FROM_DATABASE=Flextronics International GmbH & Co. Nfg. KG + +OUI:00058F* + ID_OUI_FROM_DATABASE=CLCsoft co. + +OUI:000590* + ID_OUI_FROM_DATABASE=Swissvoice Ltd. + +OUI:000591* + ID_OUI_FROM_DATABASE=Active Silicon Ltd. + +OUI:000592* + ID_OUI_FROM_DATABASE=Pultek Corp. + +OUI:000593* + ID_OUI_FROM_DATABASE=Grammar Engine Inc. + +OUI:000594* + ID_OUI_FROM_DATABASE=IXXAT Automation GmbH + +OUI:000595* + ID_OUI_FROM_DATABASE=Alesis Corporation + +OUI:000596* + ID_OUI_FROM_DATABASE=Genotech Co., Ltd. + +OUI:000597* + ID_OUI_FROM_DATABASE=Eagle Traffic Control Systems + +OUI:000598* + ID_OUI_FROM_DATABASE=CRONOS S.r.l. + +OUI:000599* + ID_OUI_FROM_DATABASE=DRS Test and Energy Management or DRS-TEM + +OUI:00059A* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00059B* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00059C* + ID_OUI_FROM_DATABASE=Kleinknecht GmbH, Ing. Büro + +OUI:00059D* + ID_OUI_FROM_DATABASE=Daniel Computing Systems, Inc. + +OUI:00059E* + ID_OUI_FROM_DATABASE=Zinwell Corporation + +OUI:00059F* + ID_OUI_FROM_DATABASE=Yotta Networks, Inc. + +OUI:0005A0* + ID_OUI_FROM_DATABASE=MOBILINE Kft. + +OUI:0005A1* + ID_OUI_FROM_DATABASE=Zenocom + +OUI:0005A2* + ID_OUI_FROM_DATABASE=CELOX Networks + +OUI:0005A3* + ID_OUI_FROM_DATABASE=QEI, Inc. + +OUI:0005A4* + ID_OUI_FROM_DATABASE=Lucid Voice Ltd. + +OUI:0005A5* + ID_OUI_FROM_DATABASE=KOTT + +OUI:0005A6* + ID_OUI_FROM_DATABASE=Extron Electronics + +OUI:0005A7* + ID_OUI_FROM_DATABASE=Hyperchip, Inc. + +OUI:0005A8* + ID_OUI_FROM_DATABASE=WYLE ELECTRONICS + +OUI:0005A9* + ID_OUI_FROM_DATABASE=Princeton Networks, Inc. + +OUI:0005AA* + ID_OUI_FROM_DATABASE=Moore Industries International Inc. + +OUI:0005AB* + ID_OUI_FROM_DATABASE=Cyber Fone, Inc. + +OUI:0005AC* + ID_OUI_FROM_DATABASE=Northern Digital, Inc. + +OUI:0005AD* + ID_OUI_FROM_DATABASE=Topspin Communications, Inc. + +OUI:0005AE* + ID_OUI_FROM_DATABASE=Mediaport USA + +OUI:0005AF* + ID_OUI_FROM_DATABASE=InnoScan Computing A/S + +OUI:0005B0* + ID_OUI_FROM_DATABASE=Korea Computer Technology Co., Ltd. + +OUI:0005B1* + ID_OUI_FROM_DATABASE=ASB Technology BV + +OUI:0005B2* + ID_OUI_FROM_DATABASE=Medison Co., Ltd. + +OUI:0005B3* + ID_OUI_FROM_DATABASE=Asahi-Engineering Co., Ltd. + +OUI:0005B4* + ID_OUI_FROM_DATABASE=Aceex Corporation + +OUI:0005B5* + ID_OUI_FROM_DATABASE=Broadcom Technologies + +OUI:0005B6* + ID_OUI_FROM_DATABASE=INSYS Microelectronics GmbH + +OUI:0005B7* + ID_OUI_FROM_DATABASE=Arbor Technology Corp. + +OUI:0005B8* + ID_OUI_FROM_DATABASE=Electronic Design Associates, Inc. + +OUI:0005B9* + ID_OUI_FROM_DATABASE=Airvana, Inc. + +OUI:0005BA* + ID_OUI_FROM_DATABASE=Area Netwoeks, Inc. + +OUI:0005BB* + ID_OUI_FROM_DATABASE=Myspace AB + +OUI:0005BC* + ID_OUI_FROM_DATABASE=Resorsys Ltd. + +OUI:0005BD* + ID_OUI_FROM_DATABASE=ROAX BV + +OUI:0005BE* + ID_OUI_FROM_DATABASE=Kongsberg Seatex AS + +OUI:0005BF* + ID_OUI_FROM_DATABASE=JustEzy Technology, Inc. + +OUI:0005C0* + ID_OUI_FROM_DATABASE=Digital Network Alacarte Co., Ltd. + +OUI:0005C1* + ID_OUI_FROM_DATABASE=A-Kyung Motion, Inc. + +OUI:0005C2* + ID_OUI_FROM_DATABASE=Soronti, Inc. + +OUI:0005C3* + ID_OUI_FROM_DATABASE=Pacific Instruments, Inc. + +OUI:0005C4* + ID_OUI_FROM_DATABASE=Telect, Inc. + +OUI:0005C5* + ID_OUI_FROM_DATABASE=Flaga HF + +OUI:0005C6* + ID_OUI_FROM_DATABASE=Triz Communications + +OUI:0005C7* + ID_OUI_FROM_DATABASE=I/F-COM A/S + +OUI:0005C8* + ID_OUI_FROM_DATABASE=VERYTECH + +OUI:0005C9* + ID_OUI_FROM_DATABASE=LG Innotek Co., Ltd. + +OUI:0005CA* + ID_OUI_FROM_DATABASE=Hitron Technology, Inc. + +OUI:0005CB* + ID_OUI_FROM_DATABASE=ROIS Technologies, Inc. + +OUI:0005CC* + ID_OUI_FROM_DATABASE=Sumtel Communications, Inc. + +OUI:0005CD* + ID_OUI_FROM_DATABASE=Denon, Ltd. + +OUI:0005CE* + ID_OUI_FROM_DATABASE=Prolink Microsystems Corporation + +OUI:0005CF* + ID_OUI_FROM_DATABASE=Thunder River Technologies, Inc. + +OUI:0005D0* + ID_OUI_FROM_DATABASE=Solinet Systems + +OUI:0005D1* + ID_OUI_FROM_DATABASE=Metavector Technologies + +OUI:0005D2* + ID_OUI_FROM_DATABASE=DAP Technologies + +OUI:0005D3* + ID_OUI_FROM_DATABASE=eProduction Solutions, Inc. + +OUI:0005D4* + ID_OUI_FROM_DATABASE=FutureSmart Networks, Inc. + +OUI:0005D5* + ID_OUI_FROM_DATABASE=Speedcom Wireless + +OUI:0005D6* + ID_OUI_FROM_DATABASE=Titan Wireless + +OUI:0005D7* + ID_OUI_FROM_DATABASE=Vista Imaging, Inc. + +OUI:0005D8* + ID_OUI_FROM_DATABASE=Arescom, Inc. + +OUI:0005D9* + ID_OUI_FROM_DATABASE=Techno Valley, Inc. + +OUI:0005DA* + ID_OUI_FROM_DATABASE=Apex Automationstechnik + +OUI:0005DB* + ID_OUI_FROM_DATABASE=PSI Nentec GmbH + +OUI:0005DC* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0005DD* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0005DE* + ID_OUI_FROM_DATABASE=Gi Fone Korea, Inc. + +OUI:0005DF* + ID_OUI_FROM_DATABASE=Electronic Innovation, Inc. + +OUI:0005E0* + ID_OUI_FROM_DATABASE=Empirix Corp. + +OUI:0005E1* + ID_OUI_FROM_DATABASE=Trellis Photonics, Ltd. + +OUI:0005E2* + ID_OUI_FROM_DATABASE=Creativ Network Technologies + +OUI:0005E3* + ID_OUI_FROM_DATABASE=LightSand Communications, Inc. + +OUI:0005E4* + ID_OUI_FROM_DATABASE=Red Lion Controls Inc. + +OUI:0005E5* + ID_OUI_FROM_DATABASE=Renishaw PLC + +OUI:0005E6* + ID_OUI_FROM_DATABASE=Egenera, Inc. + +OUI:0005E7* + ID_OUI_FROM_DATABASE=Netrake an AudioCodes Company + +OUI:0005E8* + ID_OUI_FROM_DATABASE=TurboWave, Inc. + +OUI:0005E9* + ID_OUI_FROM_DATABASE=Unicess Network, Inc. + +OUI:0005EA* + ID_OUI_FROM_DATABASE=Rednix + +OUI:0005EB* + ID_OUI_FROM_DATABASE=Blue Ridge Networks, Inc. + +OUI:0005EC* + ID_OUI_FROM_DATABASE=Mosaic Systems Inc. + +OUI:0005ED* + ID_OUI_FROM_DATABASE=Technikum Joanneum GmbH + +OUI:0005EE* + ID_OUI_FROM_DATABASE=BEWATOR Group + +OUI:0005EF* + ID_OUI_FROM_DATABASE=ADOIR Digital Technology + +OUI:0005F0* + ID_OUI_FROM_DATABASE=SATEC + +OUI:0005F1* + ID_OUI_FROM_DATABASE=Vrcom, Inc. + +OUI:0005F2* + ID_OUI_FROM_DATABASE=Power R, Inc. + +OUI:0005F3* + ID_OUI_FROM_DATABASE=Weboyn + +OUI:0005F4* + ID_OUI_FROM_DATABASE=System Base Co., Ltd. + +OUI:0005F5* + ID_OUI_FROM_DATABASE=OYO Geospace + +OUI:0005F6* + ID_OUI_FROM_DATABASE=Young Chang Co. Ltd. + +OUI:0005F7* + ID_OUI_FROM_DATABASE=Analog Devices, Inc. + +OUI:0005F8* + ID_OUI_FROM_DATABASE=Real Time Access, Inc. + +OUI:0005F9* + ID_OUI_FROM_DATABASE=TOA Corporation + +OUI:0005FA* + ID_OUI_FROM_DATABASE=IPOptical, Inc. + +OUI:0005FB* + ID_OUI_FROM_DATABASE=ShareGate, Inc. + +OUI:0005FC* + ID_OUI_FROM_DATABASE=Schenck Pegasus Corp. + +OUI:0005FD* + ID_OUI_FROM_DATABASE=PacketLight Networks Ltd. + +OUI:0005FE* + ID_OUI_FROM_DATABASE=Traficon N.V. + +OUI:0005FF* + ID_OUI_FROM_DATABASE=SNS Solutions, Inc. + +OUI:000600* + ID_OUI_FROM_DATABASE=Toshiba Teli Corporation + +OUI:000601* + ID_OUI_FROM_DATABASE=Otanikeiki Co., Ltd. + +OUI:000602* + ID_OUI_FROM_DATABASE=Cirkitech Electronics Co. + +OUI:000603* + ID_OUI_FROM_DATABASE=Baker Hughes Inc. + +OUI:000604* + ID_OUI_FROM_DATABASE=@Track Communications, Inc. + +OUI:000605* + ID_OUI_FROM_DATABASE=Inncom International, Inc. + +OUI:000606* + ID_OUI_FROM_DATABASE=RapidWAN, Inc. + +OUI:000607* + ID_OUI_FROM_DATABASE=Omni Directional Control Technology Inc. + +OUI:000608* + ID_OUI_FROM_DATABASE=At-Sky SAS + +OUI:000609* + ID_OUI_FROM_DATABASE=Crossport Systems + +OUI:00060A* + ID_OUI_FROM_DATABASE=Blue2space + +OUI:00060B* + ID_OUI_FROM_DATABASE=Emerson Network Power + +OUI:00060C* + ID_OUI_FROM_DATABASE=Melco Industries, Inc. + +OUI:00060D* + ID_OUI_FROM_DATABASE=Wave7 Optics + +OUI:00060E* + ID_OUI_FROM_DATABASE=IGYS Systems, Inc. + +OUI:00060F* + ID_OUI_FROM_DATABASE=Narad Networks Inc + +OUI:000610* + ID_OUI_FROM_DATABASE=Abeona Networks Inc + +OUI:000611* + ID_OUI_FROM_DATABASE=Zeus Wireless, Inc. + +OUI:000612* + ID_OUI_FROM_DATABASE=Accusys, Inc. + +OUI:000613* + ID_OUI_FROM_DATABASE=Kawasaki Microelectronics Incorporated + +OUI:000614* + ID_OUI_FROM_DATABASE=Prism Holdings + +OUI:000615* + ID_OUI_FROM_DATABASE=Kimoto Electric Co., Ltd. + +OUI:000616* + ID_OUI_FROM_DATABASE=Tel Net Co., Ltd. + +OUI:000617* + ID_OUI_FROM_DATABASE=Redswitch Inc. + +OUI:000618* + ID_OUI_FROM_DATABASE=DigiPower Manufacturing Inc. + +OUI:000619* + ID_OUI_FROM_DATABASE=Connection Technology Systems + +OUI:00061A* + ID_OUI_FROM_DATABASE=Zetari Inc. + +OUI:00061B* + ID_OUI_FROM_DATABASE=Notebook Development Lab. Lenovo Japan Ltd. + +OUI:00061C* + ID_OUI_FROM_DATABASE=Hoshino Metal Industries, Ltd. + +OUI:00061D* + ID_OUI_FROM_DATABASE=MIP Telecom, Inc. + +OUI:00061E* + ID_OUI_FROM_DATABASE=Maxan Systems + +OUI:00061F* + ID_OUI_FROM_DATABASE=Vision Components GmbH + +OUI:000620* + ID_OUI_FROM_DATABASE=Serial System Ltd. + +OUI:000621* + ID_OUI_FROM_DATABASE=Hinox, Co., Ltd. + +OUI:000622* + ID_OUI_FROM_DATABASE=Chung Fu Chen Yeh Enterprise Corp. + +OUI:000623* + ID_OUI_FROM_DATABASE=MGE UPS Systems France + +OUI:000624* + ID_OUI_FROM_DATABASE=Gentner Communications Corp. + +OUI:000625* + ID_OUI_FROM_DATABASE=The Linksys Group, Inc. + +OUI:000626* + ID_OUI_FROM_DATABASE=MWE GmbH + +OUI:000627* + ID_OUI_FROM_DATABASE=Uniwide Technologies, Inc. + +OUI:000628* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000629* + ID_OUI_FROM_DATABASE=IBM Corp + +OUI:00062A* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00062B* + ID_OUI_FROM_DATABASE=INTRASERVER TECHNOLOGY + +OUI:00062C* + ID_OUI_FROM_DATABASE=Bivio Networks + +OUI:00062D* + ID_OUI_FROM_DATABASE=TouchStar Technologies, L.L.C. + +OUI:00062E* + ID_OUI_FROM_DATABASE=Aristos Logic Corp. + +OUI:00062F* + ID_OUI_FROM_DATABASE=Pivotech Systems Inc. + +OUI:000630* + ID_OUI_FROM_DATABASE=Adtranz Sweden + +OUI:000631* + ID_OUI_FROM_DATABASE=Optical Solutions, Inc. + +OUI:000632* + ID_OUI_FROM_DATABASE=Mesco Engineering GmbH + +OUI:000633* + ID_OUI_FROM_DATABASE=Cross Match Technologies GmbH + +OUI:000634* + ID_OUI_FROM_DATABASE=GTE Airfone Inc. + +OUI:000635* + ID_OUI_FROM_DATABASE=PacketAir Networks, Inc. + +OUI:000636* + ID_OUI_FROM_DATABASE=Jedai Broadband Networks + +OUI:000637* + ID_OUI_FROM_DATABASE=Toptrend-Meta Information (ShenZhen) Inc. + +OUI:000638* + ID_OUI_FROM_DATABASE=Sungjin C&C Co., Ltd. + +OUI:000639* + ID_OUI_FROM_DATABASE=Newtec + +OUI:00063A* + ID_OUI_FROM_DATABASE=Dura Micro, Inc. + +OUI:00063B* + ID_OUI_FROM_DATABASE=Arcturus Networks, Inc. + +OUI:00063C* + ID_OUI_FROM_DATABASE=Intrinsyc Europe Ltd + +OUI:00063D* + ID_OUI_FROM_DATABASE=Microwave Data Systems Inc. + +OUI:00063E* + ID_OUI_FROM_DATABASE=Opthos Inc. + +OUI:00063F* + ID_OUI_FROM_DATABASE=Everex Communications Inc. + +OUI:000640* + ID_OUI_FROM_DATABASE=White Rock Networks + +OUI:000641* + ID_OUI_FROM_DATABASE=ITCN + +OUI:000642* + ID_OUI_FROM_DATABASE=Genetel Systems Inc. + +OUI:000643* + ID_OUI_FROM_DATABASE=SONO Computer Co., Ltd. + +OUI:000644* + ID_OUI_FROM_DATABASE=Neix,Inc + +OUI:000645* + ID_OUI_FROM_DATABASE=Meisei Electric Co. Ltd. + +OUI:000646* + ID_OUI_FROM_DATABASE=ShenZhen XunBao Network Technology Co Ltd + +OUI:000647* + ID_OUI_FROM_DATABASE=Etrali S.A. + +OUI:000648* + ID_OUI_FROM_DATABASE=Seedsware, Inc. + +OUI:000649* + ID_OUI_FROM_DATABASE=3M Deutschland GmbH + +OUI:00064A* + ID_OUI_FROM_DATABASE=Honeywell Co., Ltd. (KOREA) + +OUI:00064B* + ID_OUI_FROM_DATABASE=Alexon Co., Ltd. + +OUI:00064C* + ID_OUI_FROM_DATABASE=Invicta Networks, Inc. + +OUI:00064D* + ID_OUI_FROM_DATABASE=Sencore + +OUI:00064E* + ID_OUI_FROM_DATABASE=Broad Net Technology Inc. + +OUI:00064F* + ID_OUI_FROM_DATABASE=PRO-NETS Technology Corporation + +OUI:000650* + ID_OUI_FROM_DATABASE=Tiburon Networks, Inc. + +OUI:000651* + ID_OUI_FROM_DATABASE=Aspen Networks Inc. + +OUI:000652* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000653* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000654* + ID_OUI_FROM_DATABASE=Winpresa Building Automation Technologies GmbH + +OUI:000655* + ID_OUI_FROM_DATABASE=Yipee, Inc. + +OUI:000656* + ID_OUI_FROM_DATABASE=Tactel AB + +OUI:000657* + ID_OUI_FROM_DATABASE=Market Central, Inc. + +OUI:000658* + ID_OUI_FROM_DATABASE=Helmut Fischer GmbH Institut für Elektronik und Messtechnik + +OUI:000659* + ID_OUI_FROM_DATABASE=EAL (Apeldoorn) B.V. + +OUI:00065A* + ID_OUI_FROM_DATABASE=Strix Systems + +OUI:00065B* + ID_OUI_FROM_DATABASE=Dell Computer Corp. + +OUI:00065C* + ID_OUI_FROM_DATABASE=Malachite Technologies, Inc. + +OUI:00065D* + ID_OUI_FROM_DATABASE=Heidelberg Web Systems + +OUI:00065E* + ID_OUI_FROM_DATABASE=Photuris, Inc. + +OUI:00065F* + ID_OUI_FROM_DATABASE=ECI Telecom - NGTS Ltd. + +OUI:000660* + ID_OUI_FROM_DATABASE=NADEX Co., Ltd. + +OUI:000661* + ID_OUI_FROM_DATABASE=NIA Home Technologies Corp. + +OUI:000662* + ID_OUI_FROM_DATABASE=MBM Technology Ltd. + +OUI:000663* + ID_OUI_FROM_DATABASE=Human Technology Co., Ltd. + +OUI:000664* + ID_OUI_FROM_DATABASE=Fostex Corporation + +OUI:000665* + ID_OUI_FROM_DATABASE=Sunny Giken, Inc. + +OUI:000666* + ID_OUI_FROM_DATABASE=Roving Networks + +OUI:000667* + ID_OUI_FROM_DATABASE=Tripp Lite + +OUI:000668* + ID_OUI_FROM_DATABASE=Vicon Industries Inc. + +OUI:000669* + ID_OUI_FROM_DATABASE=Datasound Laboratories Ltd + +OUI:00066A* + ID_OUI_FROM_DATABASE=InfiniCon Systems, Inc. + +OUI:00066B* + ID_OUI_FROM_DATABASE=Sysmex Corporation + +OUI:00066C* + ID_OUI_FROM_DATABASE=Robinson Corporation + +OUI:00066D* + ID_OUI_FROM_DATABASE=Compuprint S.P.A. + +OUI:00066E* + ID_OUI_FROM_DATABASE=Delta Electronics, Inc. + +OUI:00066F* + ID_OUI_FROM_DATABASE=Korea Data Systems + +OUI:000670* + ID_OUI_FROM_DATABASE=Upponetti Oy + +OUI:000671* + ID_OUI_FROM_DATABASE=Softing AG + +OUI:000672* + ID_OUI_FROM_DATABASE=Netezza + +OUI:000673* + ID_OUI_FROM_DATABASE=TKH Security Solutions USA + +OUI:000674* + ID_OUI_FROM_DATABASE=Spectrum Control, Inc. + +OUI:000675* + ID_OUI_FROM_DATABASE=Banderacom, Inc. + +OUI:000676* + ID_OUI_FROM_DATABASE=Novra Technologies Inc. + +OUI:000677* + ID_OUI_FROM_DATABASE=SICK AG + +OUI:000678* + ID_OUI_FROM_DATABASE=Marantz Brand Company + +OUI:000679* + ID_OUI_FROM_DATABASE=Konami Corporation + +OUI:00067A* + ID_OUI_FROM_DATABASE=JMP Systems + +OUI:00067B* + ID_OUI_FROM_DATABASE=Toplink C&C Corporation + +OUI:00067C* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00067D* + ID_OUI_FROM_DATABASE=Takasago Ltd. + +OUI:00067E* + ID_OUI_FROM_DATABASE=WinCom Systems, Inc. + +OUI:00067F* + ID_OUI_FROM_DATABASE=Digeo, Inc. + +OUI:000680* + ID_OUI_FROM_DATABASE=Card Access, Inc. + +OUI:000681* + ID_OUI_FROM_DATABASE=Goepel Electronic GmbH + +OUI:000682* + ID_OUI_FROM_DATABASE=Convedia + +OUI:000683* + ID_OUI_FROM_DATABASE=Bravara Communications, Inc. + +OUI:000684* + ID_OUI_FROM_DATABASE=Biacore AB + +OUI:000685* + ID_OUI_FROM_DATABASE=NetNearU Corporation + +OUI:000686* + ID_OUI_FROM_DATABASE=ZARDCOM Co., Ltd. + +OUI:000687* + ID_OUI_FROM_DATABASE=Omnitron Systems Technology, Inc. + +OUI:000688* + ID_OUI_FROM_DATABASE=Telways Communication Co., Ltd. + +OUI:000689* + ID_OUI_FROM_DATABASE=yLez Technologies Pte Ltd + +OUI:00068A* + ID_OUI_FROM_DATABASE=NeuronNet Co. Ltd. R&D Center + +OUI:00068B* + ID_OUI_FROM_DATABASE=AirRunner Technologies, Inc. + +OUI:00068C* + ID_OUI_FROM_DATABASE=3Com Corporation + +OUI:00068D* + ID_OUI_FROM_DATABASE=SEPATON, Inc. + +OUI:00068E* + ID_OUI_FROM_DATABASE=HID Corporation + +OUI:00068F* + ID_OUI_FROM_DATABASE=Telemonitor, Inc. + +OUI:000690* + ID_OUI_FROM_DATABASE=Euracom Communication GmbH + +OUI:000691* + ID_OUI_FROM_DATABASE=PT Inovacao + +OUI:000692* + ID_OUI_FROM_DATABASE=Intruvert Networks, Inc. + +OUI:000693* + ID_OUI_FROM_DATABASE=Flexus Computer Technology, Inc. + +OUI:000694* + ID_OUI_FROM_DATABASE=Mobillian Corporation + +OUI:000695* + ID_OUI_FROM_DATABASE=Ensure Technologies, Inc. + +OUI:000696* + ID_OUI_FROM_DATABASE=Advent Networks + +OUI:000697* + ID_OUI_FROM_DATABASE=R & D Center + +OUI:000698* + ID_OUI_FROM_DATABASE=egnite Software GmbH + +OUI:000699* + ID_OUI_FROM_DATABASE=Vida Design Co. + +OUI:00069A* + ID_OUI_FROM_DATABASE=e & Tel + +OUI:00069B* + ID_OUI_FROM_DATABASE=AVT Audio Video Technologies GmbH + +OUI:00069C* + ID_OUI_FROM_DATABASE=Transmode Systems AB + +OUI:00069D* + ID_OUI_FROM_DATABASE=Petards Ltd + +OUI:00069E* + ID_OUI_FROM_DATABASE=UNIQA, Inc. + +OUI:00069F* + ID_OUI_FROM_DATABASE=Kuokoa Networks + +OUI:0006A0* + ID_OUI_FROM_DATABASE=Mx Imaging + +OUI:0006A1* + ID_OUI_FROM_DATABASE=Celsian Technologies, Inc. + +OUI:0006A2* + ID_OUI_FROM_DATABASE=Microtune, Inc. + +OUI:0006A3* + ID_OUI_FROM_DATABASE=Bitran Corporation + +OUI:0006A4* + ID_OUI_FROM_DATABASE=INNOWELL Corp. + +OUI:0006A5* + ID_OUI_FROM_DATABASE=PINON Corp. + +OUI:0006A6* + ID_OUI_FROM_DATABASE=Artistic Licence (UK) Ltd + +OUI:0006A7* + ID_OUI_FROM_DATABASE=Primarion + +OUI:0006A8* + ID_OUI_FROM_DATABASE=KC Technology, Inc. + +OUI:0006A9* + ID_OUI_FROM_DATABASE=Universal Instruments Corp. + +OUI:0006AA* + ID_OUI_FROM_DATABASE=VT Miltope + +OUI:0006AB* + ID_OUI_FROM_DATABASE=W-Link Systems, Inc. + +OUI:0006AC* + ID_OUI_FROM_DATABASE=Intersoft Co. + +OUI:0006AD* + ID_OUI_FROM_DATABASE=KB Electronics Ltd. + +OUI:0006AE* + ID_OUI_FROM_DATABASE=Himachal Futuristic Communications Ltd + +OUI:0006AF* + ID_OUI_FROM_DATABASE=Xalted Networks + +OUI:0006B0* + ID_OUI_FROM_DATABASE=Comtech EF Data Corp. + +OUI:0006B1* + ID_OUI_FROM_DATABASE=Sonicwall + +OUI:0006B2* + ID_OUI_FROM_DATABASE=Linxtek Co. + +OUI:0006B3* + ID_OUI_FROM_DATABASE=Diagraph Corporation + +OUI:0006B4* + ID_OUI_FROM_DATABASE=Vorne Industries, Inc. + +OUI:0006B5* + ID_OUI_FROM_DATABASE=Source Photonics, Inc. + +OUI:0006B6* + ID_OUI_FROM_DATABASE=Nir-Or Israel Ltd. + +OUI:0006B7* + ID_OUI_FROM_DATABASE=TELEM GmbH + +OUI:0006B8* + ID_OUI_FROM_DATABASE=Bandspeed Pty Ltd + +OUI:0006B9* + ID_OUI_FROM_DATABASE=A5TEK Corp. + +OUI:0006BA* + ID_OUI_FROM_DATABASE=Westwave Communications + +OUI:0006BB* + ID_OUI_FROM_DATABASE=ATI Technologies Inc. + +OUI:0006BC* + ID_OUI_FROM_DATABASE=Macrolink, Inc. + +OUI:0006BD* + ID_OUI_FROM_DATABASE=BNTECHNOLOGY Co., Ltd. + +OUI:0006BE* + ID_OUI_FROM_DATABASE=Baumer Optronic GmbH + +OUI:0006BF* + ID_OUI_FROM_DATABASE=Accella Technologies Co., Ltd. + +OUI:0006C0* + ID_OUI_FROM_DATABASE=United Internetworks, Inc. + +OUI:0006C1* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0006C2* + ID_OUI_FROM_DATABASE=Smartmatic Corporation + +OUI:0006C3* + ID_OUI_FROM_DATABASE=Schindler Elevator Ltd. + +OUI:0006C4* + ID_OUI_FROM_DATABASE=Piolink Inc. + +OUI:0006C5* + ID_OUI_FROM_DATABASE=INNOVI Technologies Limited + +OUI:0006C6* + ID_OUI_FROM_DATABASE=lesswire AG + +OUI:0006C7* + ID_OUI_FROM_DATABASE=RFNET Technologies Pte Ltd (S) + +OUI:0006C8* + ID_OUI_FROM_DATABASE=Sumitomo Metal Micro Devices, Inc. + +OUI:0006C9* + ID_OUI_FROM_DATABASE=Technical Marketing Research, Inc. + +OUI:0006CA* + ID_OUI_FROM_DATABASE=American Computer & Digital Components, Inc. (ACDC) + +OUI:0006CB* + ID_OUI_FROM_DATABASE=Jotron Electronics A/S + +OUI:0006CC* + ID_OUI_FROM_DATABASE=JMI Electronics Co., Ltd. + +OUI:0006CD* + ID_OUI_FROM_DATABASE=Leaf Imaging Ltd. + +OUI:0006CE* + ID_OUI_FROM_DATABASE=DATENO + +OUI:0006CF* + ID_OUI_FROM_DATABASE=Thales Avionics In-Flight Systems, LLC + +OUI:0006D0* + ID_OUI_FROM_DATABASE=Elgar Electronics Corp. + +OUI:0006D1* + ID_OUI_FROM_DATABASE=Tahoe Networks, Inc. + +OUI:0006D2* + ID_OUI_FROM_DATABASE=Tundra Semiconductor Corp. + +OUI:0006D3* + ID_OUI_FROM_DATABASE=Alpha Telecom, Inc. U.S.A. + +OUI:0006D4* + ID_OUI_FROM_DATABASE=Interactive Objects, Inc. + +OUI:0006D5* + ID_OUI_FROM_DATABASE=Diamond Systems Corp. + +OUI:0006D6* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0006D7* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0006D8* + ID_OUI_FROM_DATABASE=Maple Optical Systems + +OUI:0006D9* + ID_OUI_FROM_DATABASE=IPM-Net S.p.A. + +OUI:0006DA* + ID_OUI_FROM_DATABASE=ITRAN Communications Ltd. + +OUI:0006DB* + ID_OUI_FROM_DATABASE=ICHIPS Co., Ltd. + +OUI:0006DC* + ID_OUI_FROM_DATABASE=Syabas Technology (Amquest) + +OUI:0006DD* + ID_OUI_FROM_DATABASE=AT & T Laboratories - Cambridge Ltd + +OUI:0006DE* + ID_OUI_FROM_DATABASE=Flash Technology + +OUI:0006DF* + ID_OUI_FROM_DATABASE=AIDONIC Corporation + +OUI:0006E0* + ID_OUI_FROM_DATABASE=MAT Co., Ltd. + +OUI:0006E1* + ID_OUI_FROM_DATABASE=Techno Trade s.a + +OUI:0006E2* + ID_OUI_FROM_DATABASE=Ceemax Technology Co., Ltd. + +OUI:0006E3* + ID_OUI_FROM_DATABASE=Quantitative Imaging Corporation + +OUI:0006E4* + ID_OUI_FROM_DATABASE=Citel Technologies Ltd. + +OUI:0006E5* + ID_OUI_FROM_DATABASE=Fujian Newland Computer Ltd. Co. + +OUI:0006E6* + ID_OUI_FROM_DATABASE=DongYang Telecom Co., Ltd. + +OUI:0006E7* + ID_OUI_FROM_DATABASE=Bit Blitz Communications Inc. + +OUI:0006E8* + ID_OUI_FROM_DATABASE=Optical Network Testing, Inc. + +OUI:0006E9* + ID_OUI_FROM_DATABASE=Intime Corp. + +OUI:0006EA* + ID_OUI_FROM_DATABASE=ELZET80 Mikrocomputer GmbH&Co. KG + +OUI:0006EB* + ID_OUI_FROM_DATABASE=Global Data + +OUI:0006EC* + ID_OUI_FROM_DATABASE=Harris Corporation + +OUI:0006ED* + ID_OUI_FROM_DATABASE=Inara Networks + +OUI:0006EE* + ID_OUI_FROM_DATABASE=Shenyang Neu-era Information & Technology Stock Co., Ltd + +OUI:0006EF* + ID_OUI_FROM_DATABASE=Maxxan Systems, Inc. + +OUI:0006F0* + ID_OUI_FROM_DATABASE=Digeo, Inc. + +OUI:0006F1* + ID_OUI_FROM_DATABASE=Optillion + +OUI:0006F2* + ID_OUI_FROM_DATABASE=Platys Communications + +OUI:0006F3* + ID_OUI_FROM_DATABASE=AcceLight Networks + +OUI:0006F4* + ID_OUI_FROM_DATABASE=Prime Electronics & Satellitics Inc. + +OUI:0006F5* + ID_OUI_FROM_DATABASE=ALPS Co,. Ltd. + +OUI:0006F6* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0006F7* + ID_OUI_FROM_DATABASE=ALPS Electric Co,. Ltd. + +OUI:0006F8* + ID_OUI_FROM_DATABASE=CPU Technology, Inc. + +OUI:0006F9* + ID_OUI_FROM_DATABASE=Mitsui Zosen Systems Research Inc. + +OUI:0006FA* + ID_OUI_FROM_DATABASE=IP SQUARE Co, Ltd. + +OUI:0006FB* + ID_OUI_FROM_DATABASE=Hitachi Printing Solutions, Ltd. + +OUI:0006FC* + ID_OUI_FROM_DATABASE=Fnet Co., Ltd. + +OUI:0006FD* + ID_OUI_FROM_DATABASE=Comjet Information Systems Corp. + +OUI:0006FE* + ID_OUI_FROM_DATABASE=Ambrado, Inc + +OUI:0006FF* + ID_OUI_FROM_DATABASE=Sheba Systems Co., Ltd. + +OUI:000700* + ID_OUI_FROM_DATABASE=Zettamedia Korea + +OUI:000701* + ID_OUI_FROM_DATABASE=RACAL-DATACOM + +OUI:000702* + ID_OUI_FROM_DATABASE=Varian Medical Systems + +OUI:000703* + ID_OUI_FROM_DATABASE=CSEE Transport + +OUI:000704* + ID_OUI_FROM_DATABASE=ALPS Electric Co,. Ltd. + +OUI:000705* + ID_OUI_FROM_DATABASE=Endress & Hauser GmbH & Co + +OUI:000706* + ID_OUI_FROM_DATABASE=Sanritz Corporation + +OUI:000707* + ID_OUI_FROM_DATABASE=Interalia Inc. + +OUI:000708* + ID_OUI_FROM_DATABASE=Bitrage Inc. + +OUI:000709* + ID_OUI_FROM_DATABASE=Westerstrand Urfabrik AB + +OUI:00070A* + ID_OUI_FROM_DATABASE=Unicom Automation Co., Ltd. + +OUI:00070B* + ID_OUI_FROM_DATABASE=Novabase SGPS, SA + +OUI:00070C* + ID_OUI_FROM_DATABASE=SVA-Intrusion.com Co. Ltd. + +OUI:00070D* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00070E* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00070F* + ID_OUI_FROM_DATABASE=Fujant, Inc. + +OUI:000710* + ID_OUI_FROM_DATABASE=Adax, Inc. + +OUI:000711* + ID_OUI_FROM_DATABASE=Acterna + +OUI:000712* + ID_OUI_FROM_DATABASE=JAL Information Technology + +OUI:000713* + ID_OUI_FROM_DATABASE=IP One, Inc. + +OUI:000714* + ID_OUI_FROM_DATABASE=Brightcom + +OUI:000715* + ID_OUI_FROM_DATABASE=General Research of Electronics, Inc. + +OUI:000716* + ID_OUI_FROM_DATABASE=J & S Marine Ltd. + +OUI:000717* + ID_OUI_FROM_DATABASE=Wieland Electric GmbH + +OUI:000718* + ID_OUI_FROM_DATABASE=iCanTek Co., Ltd. + +OUI:000719* + ID_OUI_FROM_DATABASE=Mobiis Co., Ltd. + +OUI:00071A* + ID_OUI_FROM_DATABASE=Finedigital Inc. + +OUI:00071B* + ID_OUI_FROM_DATABASE=CDV Americas Ltd + +OUI:00071C* + ID_OUI_FROM_DATABASE=AT&T Fixed Wireless Services + +OUI:00071D* + ID_OUI_FROM_DATABASE=Satelsa Sistemas Y Aplicaciones De Telecomunicaciones, S.A. + +OUI:00071E* + ID_OUI_FROM_DATABASE=Tri-M Engineering / Nupak Dev. Corp. + +OUI:00071F* + ID_OUI_FROM_DATABASE=European Systems Integration + +OUI:000720* + ID_OUI_FROM_DATABASE=Trutzschler GmbH & Co. KG + +OUI:000721* + ID_OUI_FROM_DATABASE=Formac Elektronik GmbH + +OUI:000722* + ID_OUI_FROM_DATABASE=The Nielsen Company + +OUI:000723* + ID_OUI_FROM_DATABASE=ELCON Systemtechnik GmbH + +OUI:000724* + ID_OUI_FROM_DATABASE=Telemax Co., Ltd. + +OUI:000725* + ID_OUI_FROM_DATABASE=Bematech International Corp. + +OUI:000726* + ID_OUI_FROM_DATABASE=Shenzhen Gongjin Electronics Co., Ltd. + +OUI:000727* + ID_OUI_FROM_DATABASE=Zi Corporation (HK) Ltd. + +OUI:000728* + ID_OUI_FROM_DATABASE=Neo Telecom + +OUI:000729* + ID_OUI_FROM_DATABASE=Kistler Instrumente AG + +OUI:00072A* + ID_OUI_FROM_DATABASE=Innovance Networks + +OUI:00072B* + ID_OUI_FROM_DATABASE=Jung Myung Telecom Co., Ltd. + +OUI:00072C* + ID_OUI_FROM_DATABASE=Fabricom + +OUI:00072D* + ID_OUI_FROM_DATABASE=CNSystems + +OUI:00072E* + ID_OUI_FROM_DATABASE=North Node AB + +OUI:00072F* + ID_OUI_FROM_DATABASE=Intransa, Inc. + +OUI:000730* + ID_OUI_FROM_DATABASE=Hutchison OPTEL Telecom Technology Co., Ltd. + +OUI:000731* + ID_OUI_FROM_DATABASE=Ophir-Spiricon Inc + +OUI:000732* + ID_OUI_FROM_DATABASE=AAEON Technology Inc. + +OUI:000733* + ID_OUI_FROM_DATABASE=DANCONTROL Engineering + +OUI:000734* + ID_OUI_FROM_DATABASE=ONStor, Inc. + +OUI:000735* + ID_OUI_FROM_DATABASE=Flarion Technologies, Inc. + +OUI:000736* + ID_OUI_FROM_DATABASE=Data Video Technologies Co., Ltd. + +OUI:000737* + ID_OUI_FROM_DATABASE=Soriya Co. Ltd. + +OUI:000738* + ID_OUI_FROM_DATABASE=Young Technology Co., Ltd. + +OUI:000739* + ID_OUI_FROM_DATABASE=Scotty Group Austria Gmbh + +OUI:00073A* + ID_OUI_FROM_DATABASE=Inventel Systemes + +OUI:00073B* + ID_OUI_FROM_DATABASE=Tenovis GmbH & Co KG + +OUI:00073C* + ID_OUI_FROM_DATABASE=Telecom Design + +OUI:00073D* + ID_OUI_FROM_DATABASE=Nanjing Postel Telecommunications Co., Ltd. + +OUI:00073E* + ID_OUI_FROM_DATABASE=China Great-Wall Computer Shenzhen Co., Ltd. + +OUI:00073F* + ID_OUI_FROM_DATABASE=Woojyun Systec Co., Ltd. + +OUI:000740* + ID_OUI_FROM_DATABASE=Buffalo, Inc + +OUI:000741* + ID_OUI_FROM_DATABASE=Sierra Automated Systems + +OUI:000742* + ID_OUI_FROM_DATABASE=Current Technologies, LLC + +OUI:000743* + ID_OUI_FROM_DATABASE=Chelsio Communications + +OUI:000744* + ID_OUI_FROM_DATABASE=Unico, Inc. + +OUI:000745* + ID_OUI_FROM_DATABASE=Radlan Computer Communications Ltd. + +OUI:000746* + ID_OUI_FROM_DATABASE=TURCK, Inc. + +OUI:000747* + ID_OUI_FROM_DATABASE=Mecalc + +OUI:000748* + ID_OUI_FROM_DATABASE=The Imaging Source Europe + +OUI:000749* + ID_OUI_FROM_DATABASE=CENiX Inc. + +OUI:00074A* + ID_OUI_FROM_DATABASE=Carl Valentin GmbH + +OUI:00074B* + ID_OUI_FROM_DATABASE=Daihen Corporation + +OUI:00074C* + ID_OUI_FROM_DATABASE=Beicom Inc. + +OUI:00074D* + ID_OUI_FROM_DATABASE=Zebra Technologies Corp. + +OUI:00074E* + ID_OUI_FROM_DATABASE=IPFRONT Inc + +OUI:00074F* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000750* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000751* + ID_OUI_FROM_DATABASE=m-u-t AG + +OUI:000752* + ID_OUI_FROM_DATABASE=Rhythm Watch Co., Ltd. + +OUI:000753* + ID_OUI_FROM_DATABASE=Beijing Qxcomm Technology Co., Ltd. + +OUI:000754* + ID_OUI_FROM_DATABASE=Xyterra Computing, Inc. + +OUI:000755* + ID_OUI_FROM_DATABASE=Lafon SA + +OUI:000756* + ID_OUI_FROM_DATABASE=Juyoung Telecom + +OUI:000757* + ID_OUI_FROM_DATABASE=Topcall International AG + +OUI:000758* + ID_OUI_FROM_DATABASE=Dragonwave + +OUI:000759* + ID_OUI_FROM_DATABASE=Boris Manufacturing Corp. + +OUI:00075A* + ID_OUI_FROM_DATABASE=Air Products and Chemicals, Inc. + +OUI:00075B* + ID_OUI_FROM_DATABASE=Gibson Guitars + +OUI:00075C* + ID_OUI_FROM_DATABASE=Eastman Kodak Company + +OUI:00075D* + ID_OUI_FROM_DATABASE=Celleritas Inc. + +OUI:00075E* + ID_OUI_FROM_DATABASE=Ametek Power Instruments + +OUI:00075F* + ID_OUI_FROM_DATABASE=VCS Video Communication Systems AG + +OUI:000760* + ID_OUI_FROM_DATABASE=TOMIS Information & Telecom Corp. + +OUI:000761* + ID_OUI_FROM_DATABASE=Logitech SA + +OUI:000762* + ID_OUI_FROM_DATABASE=Group Sense Limited + +OUI:000763* + ID_OUI_FROM_DATABASE=Sunniwell Cyber Tech. Co., Ltd. + +OUI:000764* + ID_OUI_FROM_DATABASE=YoungWoo Telecom Co. Ltd. + +OUI:000765* + ID_OUI_FROM_DATABASE=Jade Quantum Technologies, Inc. + +OUI:000766* + ID_OUI_FROM_DATABASE=Chou Chin Industrial Co., Ltd. + +OUI:000767* + ID_OUI_FROM_DATABASE=Yuxing Electronics Company Limited + +OUI:000768* + ID_OUI_FROM_DATABASE=Danfoss A/S + +OUI:000769* + ID_OUI_FROM_DATABASE=Italiana Macchi SpA + +OUI:00076A* + ID_OUI_FROM_DATABASE=NEXTEYE Co., Ltd. + +OUI:00076B* + ID_OUI_FROM_DATABASE=Stralfors AB + +OUI:00076C* + ID_OUI_FROM_DATABASE=Daehanet, Inc. + +OUI:00076D* + ID_OUI_FROM_DATABASE=Flexlight Networks + +OUI:00076E* + ID_OUI_FROM_DATABASE=Sinetica Corporation Limited + +OUI:00076F* + ID_OUI_FROM_DATABASE=Synoptics Limited + +OUI:000770* + ID_OUI_FROM_DATABASE=Locusnetworks Corporation + +OUI:000771* + ID_OUI_FROM_DATABASE=Embedded System Corporation + +OUI:000772* + ID_OUI_FROM_DATABASE=Alcatel Shanghai Bell Co., Ltd. + +OUI:000773* + ID_OUI_FROM_DATABASE=Ascom Powerline Communications Ltd. + +OUI:000774* + ID_OUI_FROM_DATABASE=GuangZhou Thinker Technology Co. Ltd. + +OUI:000775* + ID_OUI_FROM_DATABASE=Valence Semiconductor, Inc. + +OUI:000776* + ID_OUI_FROM_DATABASE=Federal APD + +OUI:000777* + ID_OUI_FROM_DATABASE=Motah Ltd. + +OUI:000778* + ID_OUI_FROM_DATABASE=GERSTEL GmbH & Co. KG + +OUI:000779* + ID_OUI_FROM_DATABASE=Sungil Telecom Co., Ltd. + +OUI:00077A* + ID_OUI_FROM_DATABASE=Infoware System Co., Ltd. + +OUI:00077B* + ID_OUI_FROM_DATABASE=Millimetrix Broadband Networks + +OUI:00077C* + ID_OUI_FROM_DATABASE=Westermo Teleindustri AB + +OUI:00077D* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00077E* + ID_OUI_FROM_DATABASE=Elrest GmbH + +OUI:00077F* + ID_OUI_FROM_DATABASE=J Communications Co., Ltd. + +OUI:000780* + ID_OUI_FROM_DATABASE=Bluegiga Technologies OY + +OUI:000781* + ID_OUI_FROM_DATABASE=Itron Inc. + +OUI:000782* + ID_OUI_FROM_DATABASE=Oracle Corporation + +OUI:000783* + ID_OUI_FROM_DATABASE=SynCom Network, Inc. + +OUI:000784* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000785* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000786* + ID_OUI_FROM_DATABASE=Wireless Networks Inc. + +OUI:000787* + ID_OUI_FROM_DATABASE=Idea System Co., Ltd. + +OUI:000788* + ID_OUI_FROM_DATABASE=Clipcomm, Inc. + +OUI:000789* + ID_OUI_FROM_DATABASE=DONGWON SYSTEMS + +OUI:00078A* + ID_OUI_FROM_DATABASE=Mentor Data System Inc. + +OUI:00078B* + ID_OUI_FROM_DATABASE=Wegener Communications, Inc. + +OUI:00078C* + ID_OUI_FROM_DATABASE=Elektronikspecialisten i Borlange AB + +OUI:00078D* + ID_OUI_FROM_DATABASE=NetEngines Ltd. + +OUI:00078E* + ID_OUI_FROM_DATABASE=Garz & Friche GmbH + +OUI:00078F* + ID_OUI_FROM_DATABASE=Emkay Innovative Products + +OUI:000790* + ID_OUI_FROM_DATABASE=Tri-M Technologies (s) Limited + +OUI:000791* + ID_OUI_FROM_DATABASE=International Data Communications, Inc. + +OUI:000792* + ID_OUI_FROM_DATABASE=Sütron Electronic GmbH + +OUI:000793* + ID_OUI_FROM_DATABASE=Shin Satellite Public Company Limited + +OUI:000794* + ID_OUI_FROM_DATABASE=Simple Devices, Inc. + +OUI:000795* + ID_OUI_FROM_DATABASE=Elitegroup Computer System Co. (ECS) + +OUI:000796* + ID_OUI_FROM_DATABASE=LSI Systems, Inc. + +OUI:000797* + ID_OUI_FROM_DATABASE=Netpower Co., Ltd. + +OUI:000798* + ID_OUI_FROM_DATABASE=Selea SRL + +OUI:000799* + ID_OUI_FROM_DATABASE=Tipping Point Technologies, Inc. + +OUI:00079A* + ID_OUI_FROM_DATABASE=Verint Systems Inc + +OUI:00079B* + ID_OUI_FROM_DATABASE=Aurora Networks + +OUI:00079C* + ID_OUI_FROM_DATABASE=Golden Electronics Technology Co., Ltd. + +OUI:00079D* + ID_OUI_FROM_DATABASE=Musashi Co., Ltd. + +OUI:00079E* + ID_OUI_FROM_DATABASE=Ilinx Co., Ltd. + +OUI:00079F* + ID_OUI_FROM_DATABASE=Action Digital Inc. + +OUI:0007A0* + ID_OUI_FROM_DATABASE=e-Watch Inc. + +OUI:0007A1* + ID_OUI_FROM_DATABASE=VIASYS Healthcare GmbH + +OUI:0007A2* + ID_OUI_FROM_DATABASE=Opteon Corporation + +OUI:0007A3* + ID_OUI_FROM_DATABASE=Ositis Software, Inc. + +OUI:0007A4* + ID_OUI_FROM_DATABASE=GN Netcom Ltd. + +OUI:0007A5* + ID_OUI_FROM_DATABASE=Y.D.K Co. Ltd. + +OUI:0007A6* + ID_OUI_FROM_DATABASE=Home Automation, Inc. + +OUI:0007A7* + ID_OUI_FROM_DATABASE=A-Z Inc. + +OUI:0007A8* + ID_OUI_FROM_DATABASE=Haier Group Technologies Ltd. + +OUI:0007A9* + ID_OUI_FROM_DATABASE=Novasonics + +OUI:0007AA* + ID_OUI_FROM_DATABASE=Quantum Data Inc. + +OUI:0007AB* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:0007AC* + ID_OUI_FROM_DATABASE=Eolring + +OUI:0007AD* + ID_OUI_FROM_DATABASE=Pentacon GmbH Foto-und Feinwerktechnik + +OUI:0007AE* + ID_OUI_FROM_DATABASE=Britestream Networks, Inc. + +OUI:0007AF* + ID_OUI_FROM_DATABASE=N-TRON Corporation + +OUI:0007B0* + ID_OUI_FROM_DATABASE=Office Details, Inc. + +OUI:0007B1* + ID_OUI_FROM_DATABASE=Equator Technologies + +OUI:0007B2* + ID_OUI_FROM_DATABASE=Transaccess S.A. + +OUI:0007B3* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0007B4* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0007B5* + ID_OUI_FROM_DATABASE=Any One Wireless Ltd. + +OUI:0007B6* + ID_OUI_FROM_DATABASE=Telecom Technology Ltd. + +OUI:0007B7* + ID_OUI_FROM_DATABASE=Samurai Ind. Prods Eletronicos Ltda + +OUI:0007B8* + ID_OUI_FROM_DATABASE=Corvalent Corporation + +OUI:0007B9* + ID_OUI_FROM_DATABASE=Ginganet Corporation + +OUI:0007BA* + ID_OUI_FROM_DATABASE=UTStarcom, Inc. + +OUI:0007BB* + ID_OUI_FROM_DATABASE=Candera Inc. + +OUI:0007BC* + ID_OUI_FROM_DATABASE=Identix Inc. + +OUI:0007BD* + ID_OUI_FROM_DATABASE=Radionet Ltd. + +OUI:0007BE* + ID_OUI_FROM_DATABASE=DataLogic SpA + +OUI:0007BF* + ID_OUI_FROM_DATABASE=Armillaire Technologies, Inc. + +OUI:0007C0* + ID_OUI_FROM_DATABASE=NetZerver Inc. + +OUI:0007C1* + ID_OUI_FROM_DATABASE=Overture Networks, Inc. + +OUI:0007C2* + ID_OUI_FROM_DATABASE=Netsys Telecom + +OUI:0007C3* + ID_OUI_FROM_DATABASE=Thomson + +OUI:0007C4* + ID_OUI_FROM_DATABASE=JEAN Co. Ltd. + +OUI:0007C5* + ID_OUI_FROM_DATABASE=Gcom, Inc. + +OUI:0007C6* + ID_OUI_FROM_DATABASE=VDS Vosskuhler GmbH + +OUI:0007C7* + ID_OUI_FROM_DATABASE=Synectics Systems Limited + +OUI:0007C8* + ID_OUI_FROM_DATABASE=Brain21, Inc. + +OUI:0007C9* + ID_OUI_FROM_DATABASE=Technol Seven Co., Ltd. + +OUI:0007CA* + ID_OUI_FROM_DATABASE=Creatix Polymedia Ges Fur Kommunikaitonssysteme + +OUI:0007CB* + ID_OUI_FROM_DATABASE=Freebox SA + +OUI:0007CC* + ID_OUI_FROM_DATABASE=Kaba Benzing GmbH + +OUI:0007CD* + ID_OUI_FROM_DATABASE=NMTEL Co., Ltd. + +OUI:0007CE* + ID_OUI_FROM_DATABASE=Cabletime Limited + +OUI:0007CF* + ID_OUI_FROM_DATABASE=Anoto AB + +OUI:0007D0* + ID_OUI_FROM_DATABASE=Automat Engenharia de Automação Ltda. + +OUI:0007D1* + ID_OUI_FROM_DATABASE=Spectrum Signal Processing Inc. + +OUI:0007D2* + ID_OUI_FROM_DATABASE=Logopak Systeme + +OUI:0007D3* + ID_OUI_FROM_DATABASE=Stork Prints B.V. + +OUI:0007D4* + ID_OUI_FROM_DATABASE=Zhejiang Yutong Network Communication Co Ltd. + +OUI:0007D5* + ID_OUI_FROM_DATABASE=3e Technologies Int;., Inc. + +OUI:0007D6* + ID_OUI_FROM_DATABASE=Commil Ltd. + +OUI:0007D7* + ID_OUI_FROM_DATABASE=Caporis Networks AG + +OUI:0007D8* + ID_OUI_FROM_DATABASE=Hitron Systems Inc. + +OUI:0007D9* + ID_OUI_FROM_DATABASE=Splicecom + +OUI:0007DA* + ID_OUI_FROM_DATABASE=Neuro Telecom Co., Ltd. + +OUI:0007DB* + ID_OUI_FROM_DATABASE=Kirana Networks, Inc. + +OUI:0007DC* + ID_OUI_FROM_DATABASE=Atek Co, Ltd. + +OUI:0007DD* + ID_OUI_FROM_DATABASE=Cradle Technologies + +OUI:0007DE* + ID_OUI_FROM_DATABASE=eCopilt AB + +OUI:0007DF* + ID_OUI_FROM_DATABASE=Vbrick Systems Inc. + +OUI:0007E0* + ID_OUI_FROM_DATABASE=Palm Inc. + +OUI:0007E1* + ID_OUI_FROM_DATABASE=WIS Communications Co. Ltd. + +OUI:0007E2* + ID_OUI_FROM_DATABASE=Bitworks, Inc. + +OUI:0007E3* + ID_OUI_FROM_DATABASE=Navcom Technology, Inc. + +OUI:0007E4* + ID_OUI_FROM_DATABASE=SoftRadio Co., Ltd. + +OUI:0007E5* + ID_OUI_FROM_DATABASE=Coup Corporation + +OUI:0007E6* + ID_OUI_FROM_DATABASE=edgeflow Canada Inc. + +OUI:0007E7* + ID_OUI_FROM_DATABASE=FreeWave Technologies + +OUI:0007E8* + ID_OUI_FROM_DATABASE=EdgeWave + +OUI:0007E9* + ID_OUI_FROM_DATABASE=Intel Corporation + +OUI:0007EA* + ID_OUI_FROM_DATABASE=Massana, Inc. + +OUI:0007EB* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0007EC* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0007ED* + ID_OUI_FROM_DATABASE=Altera Corporation + +OUI:0007EE* + ID_OUI_FROM_DATABASE=telco Informationssysteme GmbH + +OUI:0007EF* + ID_OUI_FROM_DATABASE=Lockheed Martin Tactical Systems + +OUI:0007F0* + ID_OUI_FROM_DATABASE=LogiSync LLC + +OUI:0007F1* + ID_OUI_FROM_DATABASE=TeraBurst Networks Inc. + +OUI:0007F2* + ID_OUI_FROM_DATABASE=IOA Corporation + +OUI:0007F3* + ID_OUI_FROM_DATABASE=Thinkengine Networks + +OUI:0007F4* + ID_OUI_FROM_DATABASE=Eletex Co., Ltd. + +OUI:0007F5* + ID_OUI_FROM_DATABASE=Bridgeco Co AG + +OUI:0007F6* + ID_OUI_FROM_DATABASE=Qqest Software Systems + +OUI:0007F7* + ID_OUI_FROM_DATABASE=Galtronics + +OUI:0007F8* + ID_OUI_FROM_DATABASE=ITDevices, Inc. + +OUI:0007F9* + ID_OUI_FROM_DATABASE=Phonetics, Inc. + +OUI:0007FA* + ID_OUI_FROM_DATABASE=ITT Co., Ltd. + +OUI:0007FB* + ID_OUI_FROM_DATABASE=Giga Stream UMTS Technologies GmbH + +OUI:0007FC* + ID_OUI_FROM_DATABASE=Adept Systems Inc. + +OUI:0007FD* + ID_OUI_FROM_DATABASE=LANergy Ltd. + +OUI:0007FE* + ID_OUI_FROM_DATABASE=Rigaku Corporation + +OUI:0007FF* + ID_OUI_FROM_DATABASE=Gluon Networks + +OUI:000800* + ID_OUI_FROM_DATABASE=MULTITECH SYSTEMS, INC. + +OUI:000801* + ID_OUI_FROM_DATABASE=HighSpeed Surfing Inc. + +OUI:000802* + ID_OUI_FROM_DATABASE=Hewlett-Packard Company + +OUI:000803* + ID_OUI_FROM_DATABASE=Cos Tron + +OUI:000804* + ID_OUI_FROM_DATABASE=ICA Inc. + +OUI:000805* + ID_OUI_FROM_DATABASE=Techno-Holon Corporation + +OUI:000806* + ID_OUI_FROM_DATABASE=Raonet Systems, Inc. + +OUI:000807* + ID_OUI_FROM_DATABASE=Access Devices Limited + +OUI:000808* + ID_OUI_FROM_DATABASE=PPT Vision, Inc. + +OUI:000809* + ID_OUI_FROM_DATABASE=Systemonic AG + +OUI:00080A* + ID_OUI_FROM_DATABASE=Espera-Werke GmbH + +OUI:00080B* + ID_OUI_FROM_DATABASE=Birka BPA Informationssystem AB + +OUI:00080C* + ID_OUI_FROM_DATABASE=VDA Elettronica spa + +OUI:00080D* + ID_OUI_FROM_DATABASE=Toshiba + +OUI:00080E* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:00080F* + ID_OUI_FROM_DATABASE=Proximion Fiber Optics AB + +OUI:000810* + ID_OUI_FROM_DATABASE=Key Technology, Inc. + +OUI:000811* + ID_OUI_FROM_DATABASE=VOIX Corporation + +OUI:000812* + ID_OUI_FROM_DATABASE=GM-2 Corporation + +OUI:000813* + ID_OUI_FROM_DATABASE=Diskbank, Inc. + +OUI:000814* + ID_OUI_FROM_DATABASE=TIL Technologies + +OUI:000815* + ID_OUI_FROM_DATABASE=CATS Co., Ltd. + +OUI:000816* + ID_OUI_FROM_DATABASE=Bluetags A/S + +OUI:000817* + ID_OUI_FROM_DATABASE=EmergeCore Networks LLC + +OUI:000818* + ID_OUI_FROM_DATABASE=Pixelworks, Inc. + +OUI:000819* + ID_OUI_FROM_DATABASE=Banksys + +OUI:00081A* + ID_OUI_FROM_DATABASE=Sanrad Intelligence Storage Communications (2000) Ltd. + +OUI:00081B* + ID_OUI_FROM_DATABASE=Windigo Systems + +OUI:00081C* + ID_OUI_FROM_DATABASE=@pos.com + +OUI:00081D* + ID_OUI_FROM_DATABASE=Ipsil, Incorporated + +OUI:00081E* + ID_OUI_FROM_DATABASE=Repeatit AB + +OUI:00081F* + ID_OUI_FROM_DATABASE=Pou Yuen Tech Corp. Ltd. + +OUI:000820* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000821* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000822* + ID_OUI_FROM_DATABASE=InPro Comm + +OUI:000823* + ID_OUI_FROM_DATABASE=Texa Corp. + +OUI:000824* + ID_OUI_FROM_DATABASE=Copitrak Inc + +OUI:000825* + ID_OUI_FROM_DATABASE=Acme Packet + +OUI:000826* + ID_OUI_FROM_DATABASE=Colorado Med Tech + +OUI:000827* + ID_OUI_FROM_DATABASE=ADB Broadband Italia + +OUI:000828* + ID_OUI_FROM_DATABASE=Koei Engineering Ltd. + +OUI:000829* + ID_OUI_FROM_DATABASE=Aval Nagasaki Corporation + +OUI:00082A* + ID_OUI_FROM_DATABASE=Powerwallz Network Security + +OUI:00082B* + ID_OUI_FROM_DATABASE=Wooksung Electronics, Inc. + +OUI:00082C* + ID_OUI_FROM_DATABASE=Homag AG + +OUI:00082D* + ID_OUI_FROM_DATABASE=Indus Teqsite Private Limited + +OUI:00082E* + ID_OUI_FROM_DATABASE=Multitone Electronics PLC + +OUI:00082F* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000830* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000831* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000832* + ID_OUI_FROM_DATABASE=Cisco + +OUI:00084E* + ID_OUI_FROM_DATABASE=DivergeNet, Inc. + +OUI:00084F* + ID_OUI_FROM_DATABASE=Qualstar Corporation + +OUI:000850* + ID_OUI_FROM_DATABASE=Arizona Instrument Corp. + +OUI:000851* + ID_OUI_FROM_DATABASE=Canadian Bank Note Company, Ltd. + +OUI:000852* + ID_OUI_FROM_DATABASE=Davolink Co. Inc. + +OUI:000853* + ID_OUI_FROM_DATABASE=Schleicher GmbH & Co. Relaiswerke KG + +OUI:000854* + ID_OUI_FROM_DATABASE=Netronix, Inc. + +OUI:000855* + ID_OUI_FROM_DATABASE=NASA-Goddard Space Flight Center + +OUI:000856* + ID_OUI_FROM_DATABASE=Gamatronic Electronic Industries Ltd. + +OUI:000857* + ID_OUI_FROM_DATABASE=Polaris Networks, Inc. + +OUI:000858* + ID_OUI_FROM_DATABASE=Novatechnology Inc. + +OUI:000859* + ID_OUI_FROM_DATABASE=ShenZhen Unitone Electronics Co., Ltd. + +OUI:00085A* + ID_OUI_FROM_DATABASE=IntiGate Inc. + +OUI:00085B* + ID_OUI_FROM_DATABASE=Hanbit Electronics Co., Ltd. + +OUI:00085C* + ID_OUI_FROM_DATABASE=Shanghai Dare Technologies Co. Ltd. + +OUI:00085D* + ID_OUI_FROM_DATABASE=Aastra + +OUI:00085E* + ID_OUI_FROM_DATABASE=PCO AG + +OUI:00085F* + ID_OUI_FROM_DATABASE=Picanol N.V. + +OUI:000860* + ID_OUI_FROM_DATABASE=LodgeNet Entertainment Corp. + +OUI:000861* + ID_OUI_FROM_DATABASE=SoftEnergy Co., Ltd. + +OUI:000862* + ID_OUI_FROM_DATABASE=NEC Eluminant Technologies, Inc. + +OUI:000863* + ID_OUI_FROM_DATABASE=Entrisphere Inc. + +OUI:000864* + ID_OUI_FROM_DATABASE=Fasy S.p.A. + +OUI:000865* + ID_OUI_FROM_DATABASE=JASCOM CO., LTD + +OUI:000866* + ID_OUI_FROM_DATABASE=DSX Access Systems, Inc. + +OUI:000867* + ID_OUI_FROM_DATABASE=Uptime Devices + +OUI:000868* + ID_OUI_FROM_DATABASE=PurOptix + +OUI:000869* + ID_OUI_FROM_DATABASE=Command-e Technology Co.,Ltd. + +OUI:00086A* + ID_OUI_FROM_DATABASE=Securiton Gmbh + +OUI:00086B* + ID_OUI_FROM_DATABASE=MIPSYS + +OUI:00086C* + ID_OUI_FROM_DATABASE=Plasmon LMS + +OUI:00086D* + ID_OUI_FROM_DATABASE=Missouri FreeNet + +OUI:00086E* + ID_OUI_FROM_DATABASE=Hyglo AB + +OUI:00086F* + ID_OUI_FROM_DATABASE=Resources Computer Network Ltd. + +OUI:000870* + ID_OUI_FROM_DATABASE=Rasvia Systems, Inc. + +OUI:000871* + ID_OUI_FROM_DATABASE=NORTHDATA Co., Ltd. + +OUI:000872* + ID_OUI_FROM_DATABASE=Sorenson Communications + +OUI:000873* + ID_OUI_FROM_DATABASE=DapTechnology B.V. + +OUI:000874* + ID_OUI_FROM_DATABASE=Dell Computer Corp. + +OUI:000875* + ID_OUI_FROM_DATABASE=Acorp Electronics Corp. + +OUI:000876* + ID_OUI_FROM_DATABASE=SDSystem + +OUI:000877* + ID_OUI_FROM_DATABASE=Liebert-Hiross Spa + +OUI:000878* + ID_OUI_FROM_DATABASE=Benchmark Storage Innovations + +OUI:000879* + ID_OUI_FROM_DATABASE=CEM Corporation + +OUI:00087A* + ID_OUI_FROM_DATABASE=Wipotec GmbH + +OUI:00087B* + ID_OUI_FROM_DATABASE=RTX Telecom A/S + +OUI:00087C* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00087D* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00087E* + ID_OUI_FROM_DATABASE=Bon Electro-Telecom Inc. + +OUI:00087F* + ID_OUI_FROM_DATABASE=SPAUN electronic GmbH & Co. KG + +OUI:000880* + ID_OUI_FROM_DATABASE=BroadTel Canada Communications inc. + +OUI:000881* + ID_OUI_FROM_DATABASE=DIGITAL HANDS CO.,LTD. + +OUI:000882* + ID_OUI_FROM_DATABASE=SIGMA CORPORATION + +OUI:000883* + ID_OUI_FROM_DATABASE=Hewlett-Packard Company + +OUI:000884* + ID_OUI_FROM_DATABASE=Index Braille AB + +OUI:000885* + ID_OUI_FROM_DATABASE=EMS Dr. Thomas Wünsche + +OUI:000886* + ID_OUI_FROM_DATABASE=Hansung Teliann, Inc. + +OUI:000887* + ID_OUI_FROM_DATABASE=Maschinenfabrik Reinhausen GmbH + +OUI:000888* + ID_OUI_FROM_DATABASE=OULLIM Information Technology Inc,. + +OUI:000889* + ID_OUI_FROM_DATABASE=Echostar Technologies Corp + +OUI:00088A* + ID_OUI_FROM_DATABASE=Minds@Work + +OUI:00088B* + ID_OUI_FROM_DATABASE=Tropic Networks Inc. + +OUI:00088C* + ID_OUI_FROM_DATABASE=Quanta Network Systems Inc. + +OUI:00088D* + ID_OUI_FROM_DATABASE=Sigma-Links Inc. + +OUI:00088E* + ID_OUI_FROM_DATABASE=Nihon Computer Co., Ltd. + +OUI:00088F* + ID_OUI_FROM_DATABASE=ADVANCED DIGITAL TECHNOLOGY + +OUI:000890* + ID_OUI_FROM_DATABASE=AVILINKS SA + +OUI:000891* + ID_OUI_FROM_DATABASE=Lyan Inc. + +OUI:000892* + ID_OUI_FROM_DATABASE=EM Solutions + +OUI:000893* + ID_OUI_FROM_DATABASE=LE INFORMATION COMMUNICATION INC. + +OUI:000894* + ID_OUI_FROM_DATABASE=InnoVISION Multimedia Ltd. + +OUI:000895* + ID_OUI_FROM_DATABASE=DIRC Technologie GmbH & Co.KG + +OUI:000896* + ID_OUI_FROM_DATABASE=Printronix, Inc. + +OUI:000897* + ID_OUI_FROM_DATABASE=Quake Technologies + +OUI:000898* + ID_OUI_FROM_DATABASE=Gigabit Optics Corporation + +OUI:000899* + ID_OUI_FROM_DATABASE=Netbind, Inc. + +OUI:00089A* + ID_OUI_FROM_DATABASE=Alcatel Microelectronics + +OUI:00089B* + ID_OUI_FROM_DATABASE=ICP Electronics Inc. + +OUI:00089C* + ID_OUI_FROM_DATABASE=Elecs Industry Co., Ltd. + +OUI:00089D* + ID_OUI_FROM_DATABASE=UHD-Elektronik + +OUI:00089E* + ID_OUI_FROM_DATABASE=Beijing Enter-Net co.LTD + +OUI:00089F* + ID_OUI_FROM_DATABASE=EFM Networks + +OUI:0008A0* + ID_OUI_FROM_DATABASE=Stotz Feinmesstechnik GmbH + +OUI:0008A1* + ID_OUI_FROM_DATABASE=CNet Technology Inc. + +OUI:0008A2* + ID_OUI_FROM_DATABASE=ADI Engineering, Inc. + +OUI:0008A3* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0008A4* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0008A5* + ID_OUI_FROM_DATABASE=Peninsula Systems Inc. + +OUI:0008A6* + ID_OUI_FROM_DATABASE=Multiware & Image Co., Ltd. + +OUI:0008A7* + ID_OUI_FROM_DATABASE=iLogic Inc. + +OUI:0008A8* + ID_OUI_FROM_DATABASE=Systec Co., Ltd. + +OUI:0008A9* + ID_OUI_FROM_DATABASE=SangSang Technology, Inc. + +OUI:0008AA* + ID_OUI_FROM_DATABASE=KARAM + +OUI:0008AB* + ID_OUI_FROM_DATABASE=EnerLinx.com, Inc. + +OUI:0008AC* + ID_OUI_FROM_DATABASE=Eltromat GmbH + +OUI:0008AD* + ID_OUI_FROM_DATABASE=Toyo-Linx Co., Ltd. + +OUI:0008AE* + ID_OUI_FROM_DATABASE=PacketFront International AB + +OUI:0008AF* + ID_OUI_FROM_DATABASE=Novatec Corporation + +OUI:0008B0* + ID_OUI_FROM_DATABASE=BKtel communications GmbH + +OUI:0008B1* + ID_OUI_FROM_DATABASE=ProQuent Systems + +OUI:0008B2* + ID_OUI_FROM_DATABASE=SHENZHEN COMPASS TECHNOLOGY DEVELOPMENT CO.,LTD + +OUI:0008B3* + ID_OUI_FROM_DATABASE=Fastwel + +OUI:0008B4* + ID_OUI_FROM_DATABASE=SYSPOL + +OUI:0008B5* + ID_OUI_FROM_DATABASE=TAI GUEN ENTERPRISE CO., LTD + +OUI:0008B6* + ID_OUI_FROM_DATABASE=RouteFree, Inc. + +OUI:0008B7* + ID_OUI_FROM_DATABASE=HIT Incorporated + +OUI:0008B8* + ID_OUI_FROM_DATABASE=E.F. Johnson + +OUI:0008B9* + ID_OUI_FROM_DATABASE=KAON MEDIA Co., Ltd. + +OUI:0008BA* + ID_OUI_FROM_DATABASE=Erskine Systems Ltd + +OUI:0008BB* + ID_OUI_FROM_DATABASE=NetExcell + +OUI:0008BC* + ID_OUI_FROM_DATABASE=Ilevo AB + +OUI:0008BD* + ID_OUI_FROM_DATABASE=TEPG-US + +OUI:0008BE* + ID_OUI_FROM_DATABASE=XENPAK MSA Group + +OUI:0008BF* + ID_OUI_FROM_DATABASE=Aptus Elektronik AB + +OUI:0008C0* + ID_OUI_FROM_DATABASE=ASA SYSTEMS + +OUI:0008C1* + ID_OUI_FROM_DATABASE=Avistar Communications Corporation + +OUI:0008C2* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0008C3* + ID_OUI_FROM_DATABASE=Contex A/S + +OUI:0008C4* + ID_OUI_FROM_DATABASE=Hikari Co.,Ltd. + +OUI:0008C5* + ID_OUI_FROM_DATABASE=Liontech Co., Ltd. + +OUI:0008C6* + ID_OUI_FROM_DATABASE=Philips Consumer Communications + +OUI:0008C7* + ID_OUI_FROM_DATABASE=Hewlett-Packard Company + +OUI:0008C8* + ID_OUI_FROM_DATABASE=Soneticom, Inc. + +OUI:0008C9* + ID_OUI_FROM_DATABASE=TechniSat Digital GmbH + +OUI:0008CA* + ID_OUI_FROM_DATABASE=TwinHan Technology Co.,Ltd + +OUI:0008CB* + ID_OUI_FROM_DATABASE=Zeta Broadband Inc. + +OUI:0008CC* + ID_OUI_FROM_DATABASE=Remotec, Inc. + +OUI:0008CD* + ID_OUI_FROM_DATABASE=With-Net Inc + +OUI:0008CE* + ID_OUI_FROM_DATABASE=IPMobileNet Inc. + +OUI:0008CF* + ID_OUI_FROM_DATABASE=Nippon Koei Power Systems Co., Ltd. + +OUI:0008D0* + ID_OUI_FROM_DATABASE=Musashi Engineering Co., LTD. + +OUI:0008D1* + ID_OUI_FROM_DATABASE=KAREL INC. + +OUI:0008D2* + ID_OUI_FROM_DATABASE=ZOOM Networks Inc. + +OUI:0008D3* + ID_OUI_FROM_DATABASE=Hercules Technologies S.A. + +OUI:0008D4* + ID_OUI_FROM_DATABASE=IneoQuest Technologies, Inc + +OUI:0008D5* + ID_OUI_FROM_DATABASE=Vanguard Networks Solutions, LLC + +OUI:0008D6* + ID_OUI_FROM_DATABASE=HASSNET Inc. + +OUI:0008D7* + ID_OUI_FROM_DATABASE=HOW CORPORATION + +OUI:0008D8* + ID_OUI_FROM_DATABASE=Dowkey Microwave + +OUI:0008D9* + ID_OUI_FROM_DATABASE=Mitadenshi Co.,LTD + +OUI:0008DA* + ID_OUI_FROM_DATABASE=SofaWare Technologies Ltd. + +OUI:0008DB* + ID_OUI_FROM_DATABASE=Corrigent Systems + +OUI:0008DC* + ID_OUI_FROM_DATABASE=Wiznet + +OUI:0008DD* + ID_OUI_FROM_DATABASE=Telena Communications, Inc. + +OUI:0008DE* + ID_OUI_FROM_DATABASE=3UP Systems + +OUI:0008DF* + ID_OUI_FROM_DATABASE=Alistel Inc. + +OUI:0008E0* + ID_OUI_FROM_DATABASE=ATO Technology Ltd. + +OUI:0008E1* + ID_OUI_FROM_DATABASE=Barix AG + +OUI:0008E2* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0008E3* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0008E4* + ID_OUI_FROM_DATABASE=Envenergy Inc + +OUI:0008E5* + ID_OUI_FROM_DATABASE=IDK Corporation + +OUI:0008E6* + ID_OUI_FROM_DATABASE=Littlefeet + +OUI:0008E7* + ID_OUI_FROM_DATABASE=SHI ControlSystems,Ltd. + +OUI:0008E8* + ID_OUI_FROM_DATABASE=Excel Master Ltd. + +OUI:0008E9* + ID_OUI_FROM_DATABASE=NextGig + +OUI:0008EA* + ID_OUI_FROM_DATABASE=Motion Control Engineering, Inc + +OUI:0008EB* + ID_OUI_FROM_DATABASE=ROMWin Co.,Ltd. + +OUI:0008EC* + ID_OUI_FROM_DATABASE=Optical Zonu Corporation + +OUI:0008ED* + ID_OUI_FROM_DATABASE=ST&T Instrument Corp. + +OUI:0008EE* + ID_OUI_FROM_DATABASE=Logic Product Development + +OUI:0008EF* + ID_OUI_FROM_DATABASE=DIBAL,S.A. + +OUI:0008F0* + ID_OUI_FROM_DATABASE=Next Generation Systems, Inc. + +OUI:0008F1* + ID_OUI_FROM_DATABASE=Voltaire + +OUI:0008F2* + ID_OUI_FROM_DATABASE=C&S Technology + +OUI:0008F3* + ID_OUI_FROM_DATABASE=WANY + +OUI:0008F4* + ID_OUI_FROM_DATABASE=Bluetake Technology Co., Ltd. + +OUI:0008F5* + ID_OUI_FROM_DATABASE=YESTECHNOLOGY Co.,Ltd. + +OUI:0008F6* + ID_OUI_FROM_DATABASE=Sumitomo Electric System Solutions Co.,Ltd. + +OUI:0008F7* + ID_OUI_FROM_DATABASE=Hitachi Ltd, Semiconductor & Integrated Circuits Gr + +OUI:0008F8* + ID_OUI_FROM_DATABASE=UTC CCS + +OUI:0008F9* + ID_OUI_FROM_DATABASE=Emerson Network Power + +OUI:0008FA* + ID_OUI_FROM_DATABASE=Karl E.Brinkmann GmbH + +OUI:0008FB* + ID_OUI_FROM_DATABASE=SonoSite, Inc. + +OUI:0008FC* + ID_OUI_FROM_DATABASE=Gigaphoton Inc. + +OUI:0008FD* + ID_OUI_FROM_DATABASE=BlueKorea Co., Ltd. + +OUI:0008FE* + ID_OUI_FROM_DATABASE=UNIK C&C Co.,Ltd. + +OUI:0008FF* + ID_OUI_FROM_DATABASE=Trilogy Communications Ltd + +OUI:000900* + ID_OUI_FROM_DATABASE=TMT + +OUI:000901* + ID_OUI_FROM_DATABASE=Shenzhen Shixuntong Information & Technoligy Co + +OUI:000902* + ID_OUI_FROM_DATABASE=Redline Communications Inc. + +OUI:000903* + ID_OUI_FROM_DATABASE=Panasas, Inc + +OUI:000904* + ID_OUI_FROM_DATABASE=MONDIAL electronic + +OUI:000905* + ID_OUI_FROM_DATABASE=iTEC Technologies Ltd. + +OUI:000906* + ID_OUI_FROM_DATABASE=Esteem Networks + +OUI:000907* + ID_OUI_FROM_DATABASE=Chrysalis Development + +OUI:000908* + ID_OUI_FROM_DATABASE=VTech Technology Corp. + +OUI:000909* + ID_OUI_FROM_DATABASE=Telenor Connect A/S + +OUI:00090A* + ID_OUI_FROM_DATABASE=SnedFar Technology Co., Ltd. + +OUI:00090B* + ID_OUI_FROM_DATABASE=MTL Instruments PLC + +OUI:00090C* + ID_OUI_FROM_DATABASE=Mayekawa Mfg. Co. Ltd. + +OUI:00090D* + ID_OUI_FROM_DATABASE=LEADER ELECTRONICS CORP. + +OUI:00090E* + ID_OUI_FROM_DATABASE=Helix Technology Inc. + +OUI:00090F* + ID_OUI_FROM_DATABASE=Fortinet Inc. + +OUI:000910* + ID_OUI_FROM_DATABASE=Simple Access Inc. + +OUI:000911* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000912* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000913* + ID_OUI_FROM_DATABASE=SystemK Corporation + +OUI:000914* + ID_OUI_FROM_DATABASE=COMPUTROLS INC. + +OUI:000915* + ID_OUI_FROM_DATABASE=CAS Corp. + +OUI:000916* + ID_OUI_FROM_DATABASE=Listman Home Technologies, Inc. + +OUI:000917* + ID_OUI_FROM_DATABASE=WEM Technology Inc + +OUI:000918* + ID_OUI_FROM_DATABASE=SAMSUNG TECHWIN CO.,LTD + +OUI:000919* + ID_OUI_FROM_DATABASE=MDS Gateways + +OUI:00091A* + ID_OUI_FROM_DATABASE=Macat Optics & Electronics Co., Ltd. + +OUI:00091B* + ID_OUI_FROM_DATABASE=Digital Generation Inc. + +OUI:00091C* + ID_OUI_FROM_DATABASE=CacheVision, Inc + +OUI:00091D* + ID_OUI_FROM_DATABASE=Proteam Computer Corporation + +OUI:00091E* + ID_OUI_FROM_DATABASE=Firstech Technology Corp. + +OUI:00091F* + ID_OUI_FROM_DATABASE=A&D Co., Ltd. + +OUI:000920* + ID_OUI_FROM_DATABASE=EpoX COMPUTER CO.,LTD. + +OUI:000921* + ID_OUI_FROM_DATABASE=Planmeca Oy + +OUI:000922* + ID_OUI_FROM_DATABASE=TST Biometrics GmbH + +OUI:000923* + ID_OUI_FROM_DATABASE=Heaman System Co., Ltd + +OUI:000924* + ID_OUI_FROM_DATABASE=Telebau GmbH + +OUI:000925* + ID_OUI_FROM_DATABASE=VSN Systemen BV + +OUI:000926* + ID_OUI_FROM_DATABASE=YODA COMMUNICATIONS, INC. + +OUI:000927* + ID_OUI_FROM_DATABASE=TOYOKEIKI CO.,LTD. + +OUI:000928* + ID_OUI_FROM_DATABASE=Telecore + +OUI:000929* + ID_OUI_FROM_DATABASE=Sanyo Industries (UK) Limited + +OUI:00092A* + ID_OUI_FROM_DATABASE=MYTECS Co.,Ltd. + +OUI:00092B* + ID_OUI_FROM_DATABASE=iQstor Networks, Inc. + +OUI:00092C* + ID_OUI_FROM_DATABASE=Hitpoint Inc. + +OUI:00092D* + ID_OUI_FROM_DATABASE=HTC Corporation + +OUI:00092E* + ID_OUI_FROM_DATABASE=B&Tech System Inc. + +OUI:00092F* + ID_OUI_FROM_DATABASE=Akom Technology Corporation + +OUI:000930* + ID_OUI_FROM_DATABASE=AeroConcierge Inc. + +OUI:000931* + ID_OUI_FROM_DATABASE=Future Internet, Inc. + +OUI:000932* + ID_OUI_FROM_DATABASE=Omnilux + +OUI:000933* + ID_OUI_FROM_DATABASE=Ophit Co.Ltd. + +OUI:000934* + ID_OUI_FROM_DATABASE=Dream-Multimedia-Tv GmbH + +OUI:000935* + ID_OUI_FROM_DATABASE=Sandvine Incorporated + +OUI:000936* + ID_OUI_FROM_DATABASE=Ipetronik GmbH & Co.KG + +OUI:000937* + ID_OUI_FROM_DATABASE=Inventec Appliance Corp + +OUI:000938* + ID_OUI_FROM_DATABASE=Allot Communications + +OUI:000939* + ID_OUI_FROM_DATABASE=ShibaSoku Co.,Ltd. + +OUI:00093A* + ID_OUI_FROM_DATABASE=Molex Fiber Optics + +OUI:00093B* + ID_OUI_FROM_DATABASE=HYUNDAI NETWORKS INC. + +OUI:00093C* + ID_OUI_FROM_DATABASE=Jacques Technologies P/L + +OUI:00093D* + ID_OUI_FROM_DATABASE=Newisys,Inc. + +OUI:00093E* + ID_OUI_FROM_DATABASE=C&I Technologies + +OUI:00093F* + ID_OUI_FROM_DATABASE=Double-Win Enterpirse CO., LTD + +OUI:000940* + ID_OUI_FROM_DATABASE=AGFEO GmbH & Co. KG + +OUI:000941* + ID_OUI_FROM_DATABASE=Allied Telesis K.K. + +OUI:000942* + ID_OUI_FROM_DATABASE=Wireless Technologies, Inc + +OUI:000943* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000944* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000945* + ID_OUI_FROM_DATABASE=Palmmicro Communications Inc + +OUI:000946* + ID_OUI_FROM_DATABASE=Cluster Labs GmbH + +OUI:000947* + ID_OUI_FROM_DATABASE=Aztek, Inc. + +OUI:000948* + ID_OUI_FROM_DATABASE=Vista Control Systems, Corp. + +OUI:000949* + ID_OUI_FROM_DATABASE=Glyph Technologies Inc. + +OUI:00094A* + ID_OUI_FROM_DATABASE=Homenet Communications + +OUI:00094B* + ID_OUI_FROM_DATABASE=FillFactory NV + +OUI:00094C* + ID_OUI_FROM_DATABASE=Communication Weaver Co.,Ltd. + +OUI:00094D* + ID_OUI_FROM_DATABASE=Braintree Communications Pty Ltd + +OUI:00094E* + ID_OUI_FROM_DATABASE=BARTECH SYSTEMS INTERNATIONAL, INC + +OUI:00094F* + ID_OUI_FROM_DATABASE=elmegt GmbH & Co. KG + +OUI:000950* + ID_OUI_FROM_DATABASE=Independent Storage Corporation + +OUI:000951* + ID_OUI_FROM_DATABASE=Apogee Imaging Systems + +OUI:000952* + ID_OUI_FROM_DATABASE=Auerswald GmbH & Co. KG + +OUI:000953* + ID_OUI_FROM_DATABASE=Linkage System Integration Co.Ltd. + +OUI:000954* + ID_OUI_FROM_DATABASE=AMiT spol. s. r. o. + +OUI:000955* + ID_OUI_FROM_DATABASE=Young Generation International Corp. + +OUI:000956* + ID_OUI_FROM_DATABASE=Network Systems Group, Ltd. (NSG) + +OUI:000957* + ID_OUI_FROM_DATABASE=Supercaller, Inc. + +OUI:000958* + ID_OUI_FROM_DATABASE=INTELNET S.A. + +OUI:000959* + ID_OUI_FROM_DATABASE=Sitecsoft + +OUI:00095A* + ID_OUI_FROM_DATABASE=RACEWOOD TECHNOLOGY + +OUI:00095B* + ID_OUI_FROM_DATABASE=Netgear, Inc. + +OUI:00095C* + ID_OUI_FROM_DATABASE=Philips Medical Systems - Cardiac and Monitoring Systems (CM + +OUI:00095D* + ID_OUI_FROM_DATABASE=Dialogue Technology Corp. + +OUI:00095E* + ID_OUI_FROM_DATABASE=Masstech Group Inc. + +OUI:00095F* + ID_OUI_FROM_DATABASE=Telebyte, Inc. + +OUI:000960* + ID_OUI_FROM_DATABASE=YOZAN Inc. + +OUI:000961* + ID_OUI_FROM_DATABASE=Switchgear and Instrumentation Ltd + +OUI:000962* + ID_OUI_FROM_DATABASE=Sonitor Technologies AS + +OUI:000963* + ID_OUI_FROM_DATABASE=Dominion Lasercom Inc. + +OUI:000964* + ID_OUI_FROM_DATABASE=Hi-Techniques, Inc. + +OUI:000965* + ID_OUI_FROM_DATABASE=HyunJu Computer Co., Ltd. + +OUI:000966* + ID_OUI_FROM_DATABASE=Thales Navigation + +OUI:000967* + ID_OUI_FROM_DATABASE=Tachyon, Inc + +OUI:000968* + ID_OUI_FROM_DATABASE=TECHNOVENTURE, INC. + +OUI:000969* + ID_OUI_FROM_DATABASE=Meret Optical Communications + +OUI:00096A* + ID_OUI_FROM_DATABASE=Cloverleaf Communications Inc. + +OUI:00096B* + ID_OUI_FROM_DATABASE=IBM Corp + +OUI:00096C* + ID_OUI_FROM_DATABASE=Imedia Semiconductor Corp. + +OUI:00096D* + ID_OUI_FROM_DATABASE=Powernet Technologies Corp. + +OUI:00096E* + ID_OUI_FROM_DATABASE=GIANT ELECTRONICS LTD. + +OUI:00096F* + ID_OUI_FROM_DATABASE=Beijing Zhongqing Elegant Tech. Corp.,Limited + +OUI:000970* + ID_OUI_FROM_DATABASE=Vibration Research Corporation + +OUI:000971* + ID_OUI_FROM_DATABASE=Time Management, Inc. + +OUI:000972* + ID_OUI_FROM_DATABASE=Securebase,Inc + +OUI:000973* + ID_OUI_FROM_DATABASE=Lenten Technology Co., Ltd. + +OUI:000974* + ID_OUI_FROM_DATABASE=Innopia Technologies, Inc. + +OUI:000975* + ID_OUI_FROM_DATABASE=fSONA Communications Corporation + +OUI:000976* + ID_OUI_FROM_DATABASE=Datasoft ISDN Systems GmbH + +OUI:000977* + ID_OUI_FROM_DATABASE=Brunner Elektronik AG + +OUI:000978* + ID_OUI_FROM_DATABASE=AIJI System Co., Ltd. + +OUI:000979* + ID_OUI_FROM_DATABASE=Advanced Television Systems Committee, Inc. + +OUI:00097A* + ID_OUI_FROM_DATABASE=Louis Design Labs. + +OUI:00097B* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00097C* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00097D* + ID_OUI_FROM_DATABASE=SecWell Networks Oy + +OUI:00097E* + ID_OUI_FROM_DATABASE=IMI TECHNOLOGY CO., LTD + +OUI:00097F* + ID_OUI_FROM_DATABASE=Vsecure 2000 LTD. + +OUI:000980* + ID_OUI_FROM_DATABASE=Power Zenith Inc. + +OUI:000981* + ID_OUI_FROM_DATABASE=Newport Networks + +OUI:000982* + ID_OUI_FROM_DATABASE=Loewe Opta GmbH + +OUI:000983* + ID_OUI_FROM_DATABASE=GlobalTop Technology, Inc. + +OUI:000984* + ID_OUI_FROM_DATABASE=MyCasa Network Inc. + +OUI:000985* + ID_OUI_FROM_DATABASE=Auto Telecom Company + +OUI:000986* + ID_OUI_FROM_DATABASE=Metalink LTD. + +OUI:000987* + ID_OUI_FROM_DATABASE=NISHI NIPPON ELECTRIC WIRE & CABLE CO.,LTD. + +OUI:000988* + ID_OUI_FROM_DATABASE=Nudian Electron Co., Ltd. + +OUI:000989* + ID_OUI_FROM_DATABASE=VividLogic Inc. + +OUI:00098A* + ID_OUI_FROM_DATABASE=EqualLogic Inc + +OUI:00098B* + ID_OUI_FROM_DATABASE=Entropic Communications, Inc. + +OUI:00098C* + ID_OUI_FROM_DATABASE=Option Wireless Sweden + +OUI:00098D* + ID_OUI_FROM_DATABASE=Velocity Semiconductor + +OUI:00098E* + ID_OUI_FROM_DATABASE=ipcas GmbH + +OUI:00098F* + ID_OUI_FROM_DATABASE=Cetacean Networks + +OUI:000990* + ID_OUI_FROM_DATABASE=ACKSYS Communications & systems + +OUI:000991* + ID_OUI_FROM_DATABASE=GE Fanuc Automation Manufacturing, Inc. + +OUI:000992* + ID_OUI_FROM_DATABASE=InterEpoch Technology,INC. + +OUI:000993* + ID_OUI_FROM_DATABASE=Visteon Corporation + +OUI:000994* + ID_OUI_FROM_DATABASE=Cronyx Engineering + +OUI:000995* + ID_OUI_FROM_DATABASE=Castle Technology Ltd + +OUI:000996* + ID_OUI_FROM_DATABASE=RDI + +OUI:000997* + ID_OUI_FROM_DATABASE=Nortel Networks + +OUI:000998* + ID_OUI_FROM_DATABASE=Capinfo Company Limited + +OUI:000999* + ID_OUI_FROM_DATABASE=CP GEORGES RENAULT + +OUI:00099A* + ID_OUI_FROM_DATABASE=ELMO COMPANY, LIMITED + +OUI:00099B* + ID_OUI_FROM_DATABASE=Western Telematic Inc. + +OUI:00099C* + ID_OUI_FROM_DATABASE=Naval Research Laboratory + +OUI:00099D* + ID_OUI_FROM_DATABASE=Haliplex Communications + +OUI:00099E* + ID_OUI_FROM_DATABASE=Testech, Inc. + +OUI:00099F* + ID_OUI_FROM_DATABASE=VIDEX INC. + +OUI:0009A0* + ID_OUI_FROM_DATABASE=Microtechno Corporation + +OUI:0009A1* + ID_OUI_FROM_DATABASE=Telewise Communications, Inc. + +OUI:0009A2* + ID_OUI_FROM_DATABASE=Interface Co., Ltd. + +OUI:0009A3* + ID_OUI_FROM_DATABASE=Leadfly Techologies Corp. Ltd. + +OUI:0009A4* + ID_OUI_FROM_DATABASE=HARTEC Corporation + +OUI:0009A5* + ID_OUI_FROM_DATABASE=HANSUNG ELETRONIC INDUSTRIES DEVELOPMENT CO., LTD + +OUI:0009A6* + ID_OUI_FROM_DATABASE=Ignis Optics, Inc. + +OUI:0009A7* + ID_OUI_FROM_DATABASE=Bang & Olufsen A/S + +OUI:0009A8* + ID_OUI_FROM_DATABASE=Eastmode Pte Ltd + +OUI:0009A9* + ID_OUI_FROM_DATABASE=Ikanos Communications + +OUI:0009AA* + ID_OUI_FROM_DATABASE=Data Comm for Business, Inc. + +OUI:0009AB* + ID_OUI_FROM_DATABASE=Netcontrol Oy + +OUI:0009AC* + ID_OUI_FROM_DATABASE=LANVOICE + +OUI:0009AD* + ID_OUI_FROM_DATABASE=HYUNDAI SYSCOMM, INC. + +OUI:0009AE* + ID_OUI_FROM_DATABASE=OKANO ELECTRIC CO.,LTD + +OUI:0009AF* + ID_OUI_FROM_DATABASE=e-generis + +OUI:0009B0* + ID_OUI_FROM_DATABASE=Onkyo Corporation + +OUI:0009B1* + ID_OUI_FROM_DATABASE=Kanematsu Electronics, Ltd. + +OUI:0009B2* + ID_OUI_FROM_DATABASE=L&F Inc. + +OUI:0009B3* + ID_OUI_FROM_DATABASE=MCM Systems Ltd + +OUI:0009B4* + ID_OUI_FROM_DATABASE=KISAN TELECOM CO., LTD. + +OUI:0009B5* + ID_OUI_FROM_DATABASE=3J Tech. Co., Ltd. + +OUI:0009B6* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0009B7* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0009B8* + ID_OUI_FROM_DATABASE=Entise Systems + +OUI:0009B9* + ID_OUI_FROM_DATABASE=Action Imaging Solutions + +OUI:0009BA* + ID_OUI_FROM_DATABASE=MAKU Informationstechik GmbH + +OUI:0009BB* + ID_OUI_FROM_DATABASE=MathStar, Inc. + +OUI:0009BC* + ID_OUI_FROM_DATABASE=Digital Safety Technologies, Inc + +OUI:0009BD* + ID_OUI_FROM_DATABASE=Epygi Technologies, Ltd. + +OUI:0009BE* + ID_OUI_FROM_DATABASE=Mamiya-OP Co.,Ltd. + +OUI:0009BF* + ID_OUI_FROM_DATABASE=Nintendo Co.,Ltd. + +OUI:0009C0* + ID_OUI_FROM_DATABASE=6WIND + +OUI:0009C1* + ID_OUI_FROM_DATABASE=PROCES-DATA A/S + +OUI:0009C2* + ID_OUI_FROM_DATABASE=Onity, Inc. + +OUI:0009C3* + ID_OUI_FROM_DATABASE=NETAS + +OUI:0009C4* + ID_OUI_FROM_DATABASE=Medicore Co., Ltd + +OUI:0009C5* + ID_OUI_FROM_DATABASE=KINGENE Technology Corporation + +OUI:0009C6* + ID_OUI_FROM_DATABASE=Visionics Corporation + +OUI:0009C7* + ID_OUI_FROM_DATABASE=Movistec + +OUI:0009C8* + ID_OUI_FROM_DATABASE=SINAGAWA TSUSHIN KEISOU SERVICE + +OUI:0009C9* + ID_OUI_FROM_DATABASE=BlueWINC Co., Ltd. + +OUI:0009CA* + ID_OUI_FROM_DATABASE=iMaxNetworks(Shenzhen)Limited. + +OUI:0009CB* + ID_OUI_FROM_DATABASE=HBrain + +OUI:0009CC* + ID_OUI_FROM_DATABASE=Moog GmbH + +OUI:0009CD* + ID_OUI_FROM_DATABASE=HUDSON SOFT CO.,LTD. + +OUI:0009CE* + ID_OUI_FROM_DATABASE=SpaceBridge Semiconductor Corp. + +OUI:0009CF* + ID_OUI_FROM_DATABASE=iAd GmbH + +OUI:0009D0* + ID_OUI_FROM_DATABASE=Solacom Technologies Inc. + +OUI:0009D1* + ID_OUI_FROM_DATABASE=SERANOA NETWORKS INC + +OUI:0009D2* + ID_OUI_FROM_DATABASE=Mai Logic Inc. + +OUI:0009D3* + ID_OUI_FROM_DATABASE=Western DataCom Co., Inc. + +OUI:0009D4* + ID_OUI_FROM_DATABASE=Transtech Networks + +OUI:0009D5* + ID_OUI_FROM_DATABASE=Signal Communication, Inc. + +OUI:0009D6* + ID_OUI_FROM_DATABASE=KNC One GmbH + +OUI:0009D7* + ID_OUI_FROM_DATABASE=DC Security Products + +OUI:0009D8* + ID_OUI_FROM_DATABASE=Fält Communications AB + +OUI:0009D9* + ID_OUI_FROM_DATABASE=Neoscale Systems, Inc + +OUI:0009DA* + ID_OUI_FROM_DATABASE=Control Module Inc. + +OUI:0009DB* + ID_OUI_FROM_DATABASE=eSpace + +OUI:0009DC* + ID_OUI_FROM_DATABASE=Galaxis Technology AG + +OUI:0009DD* + ID_OUI_FROM_DATABASE=Mavin Technology Inc. + +OUI:0009DE* + ID_OUI_FROM_DATABASE=Samjin Information & Communications Co., Ltd. + +OUI:0009DF* + ID_OUI_FROM_DATABASE=Vestel Komunikasyon Sanayi ve Ticaret A.S. + +OUI:0009E0* + ID_OUI_FROM_DATABASE=XEMICS S.A. + +OUI:0009E1* + ID_OUI_FROM_DATABASE=Gemtek Technology Co., Ltd. + +OUI:0009E2* + ID_OUI_FROM_DATABASE=Sinbon Electronics Co., Ltd. + +OUI:0009E3* + ID_OUI_FROM_DATABASE=Angel Iglesias S.A. + +OUI:0009E4* + ID_OUI_FROM_DATABASE=K Tech Infosystem Inc. + +OUI:0009E5* + ID_OUI_FROM_DATABASE=Hottinger Baldwin Messtechnik GmbH + +OUI:0009E6* + ID_OUI_FROM_DATABASE=Cyber Switching Inc. + +OUI:0009E7* + ID_OUI_FROM_DATABASE=ADC Techonology + +OUI:0009E8* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0009E9* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0009EA* + ID_OUI_FROM_DATABASE=YEM Inc. + +OUI:0009EB* + ID_OUI_FROM_DATABASE=HuMANDATA LTD. + +OUI:0009EC* + ID_OUI_FROM_DATABASE=Daktronics, Inc. + +OUI:0009ED* + ID_OUI_FROM_DATABASE=CipherOptics + +OUI:0009EE* + ID_OUI_FROM_DATABASE=MEIKYO ELECTRIC CO.,LTD + +OUI:0009EF* + ID_OUI_FROM_DATABASE=Vocera Communications + +OUI:0009F0* + ID_OUI_FROM_DATABASE=Shimizu Technology Inc. + +OUI:0009F1* + ID_OUI_FROM_DATABASE=Yamaki Electric Corporation + +OUI:0009F2* + ID_OUI_FROM_DATABASE=Cohu, Inc., Electronics Division + +OUI:0009F3* + ID_OUI_FROM_DATABASE=WELL Communication Corp. + +OUI:0009F4* + ID_OUI_FROM_DATABASE=Alcon Laboratories, Inc. + +OUI:0009F5* + ID_OUI_FROM_DATABASE=Emerson Network Power Co.,Ltd + +OUI:0009F6* + ID_OUI_FROM_DATABASE=Shenzhen Eastern Digital Tech Ltd. + +OUI:0009F7* + ID_OUI_FROM_DATABASE=SED, a division of Calian + +OUI:0009F8* + ID_OUI_FROM_DATABASE=UNIMO TECHNOLOGY CO., LTD. + +OUI:0009F9* + ID_OUI_FROM_DATABASE=ART JAPAN CO., LTD. + +OUI:0009FB* + ID_OUI_FROM_DATABASE=Philips Patient Monitoring + +OUI:0009FC* + ID_OUI_FROM_DATABASE=IPFLEX Inc. + +OUI:0009FD* + ID_OUI_FROM_DATABASE=Ubinetics Limited + +OUI:0009FE* + ID_OUI_FROM_DATABASE=Daisy Technologies, Inc. + +OUI:0009FF* + ID_OUI_FROM_DATABASE=X.net 2000 GmbH + +OUI:000A00* + ID_OUI_FROM_DATABASE=Mediatek Corp. + +OUI:000A01* + ID_OUI_FROM_DATABASE=SOHOware, Inc. + +OUI:000A02* + ID_OUI_FROM_DATABASE=ANNSO CO., LTD. + +OUI:000A03* + ID_OUI_FROM_DATABASE=ENDESA SERVICIOS, S.L. + +OUI:000A04* + ID_OUI_FROM_DATABASE=3Com Ltd + +OUI:000A05* + ID_OUI_FROM_DATABASE=Widax Corp. + +OUI:000A06* + ID_OUI_FROM_DATABASE=Teledex LLC + +OUI:000A07* + ID_OUI_FROM_DATABASE=WebWayOne Ltd + +OUI:000A08* + ID_OUI_FROM_DATABASE=ALPINE ELECTRONICS, INC. + +OUI:000A09* + ID_OUI_FROM_DATABASE=TaraCom Integrated Products, Inc. + +OUI:000A0A* + ID_OUI_FROM_DATABASE=SUNIX Co., Ltd. + +OUI:000A0B* + ID_OUI_FROM_DATABASE=Sealevel Systems, Inc. + +OUI:000A0C* + ID_OUI_FROM_DATABASE=Scientific Research Corporation + +OUI:000A0D* + ID_OUI_FROM_DATABASE=FCI Deutschland GmbH + +OUI:000A0E* + ID_OUI_FROM_DATABASE=Invivo Research Inc. + +OUI:000A0F* + ID_OUI_FROM_DATABASE=Ilryung Telesys, Inc + +OUI:000A10* + ID_OUI_FROM_DATABASE=FAST media integrations AG + +OUI:000A11* + ID_OUI_FROM_DATABASE=ExPet Technologies, Inc + +OUI:000A12* + ID_OUI_FROM_DATABASE=Azylex Technology, Inc + +OUI:000A13* + ID_OUI_FROM_DATABASE=Honeywell Video Systems + +OUI:000A14* + ID_OUI_FROM_DATABASE=TECO a.s. + +OUI:000A15* + ID_OUI_FROM_DATABASE=Silicon Data, Inc + +OUI:000A16* + ID_OUI_FROM_DATABASE=Lassen Research + +OUI:000A17* + ID_OUI_FROM_DATABASE=NESTAR COMMUNICATIONS, INC + +OUI:000A18* + ID_OUI_FROM_DATABASE=Vichel Inc. + +OUI:000A19* + ID_OUI_FROM_DATABASE=Valere Power, Inc. + +OUI:000A1A* + ID_OUI_FROM_DATABASE=Imerge Ltd + +OUI:000A1B* + ID_OUI_FROM_DATABASE=Stream Labs + +OUI:000A1C* + ID_OUI_FROM_DATABASE=Bridge Information Co., Ltd. + +OUI:000A1D* + ID_OUI_FROM_DATABASE=Optical Communications Products Inc. + +OUI:000A1E* + ID_OUI_FROM_DATABASE=Red-M Products Limited + +OUI:000A1F* + ID_OUI_FROM_DATABASE=ART WARE Telecommunication Co., Ltd. + +OUI:000A20* + ID_OUI_FROM_DATABASE=SVA Networks, Inc. + +OUI:000A21* + ID_OUI_FROM_DATABASE=Integra Telecom Co. Ltd + +OUI:000A22* + ID_OUI_FROM_DATABASE=Amperion Inc + +OUI:000A23* + ID_OUI_FROM_DATABASE=Parama Networks Inc + +OUI:000A24* + ID_OUI_FROM_DATABASE=Octave Communications + +OUI:000A25* + ID_OUI_FROM_DATABASE=CERAGON NETWORKS + +OUI:000A26* + ID_OUI_FROM_DATABASE=CEIA S.p.A. + +OUI:000A27* + ID_OUI_FROM_DATABASE=Apple Computer, Inc. + +OUI:000A28* + ID_OUI_FROM_DATABASE=Motorola + +OUI:000A29* + ID_OUI_FROM_DATABASE=Pan Dacom Networking AG + +OUI:000A2A* + ID_OUI_FROM_DATABASE=QSI Systems Inc. + +OUI:000A2B* + ID_OUI_FROM_DATABASE=Etherstuff + +OUI:000A2C* + ID_OUI_FROM_DATABASE=Active Tchnology Corporation + +OUI:000A2D* + ID_OUI_FROM_DATABASE=Cabot Communications Limited + +OUI:000A2E* + ID_OUI_FROM_DATABASE=MAPLE NETWORKS CO., LTD + +OUI:000A2F* + ID_OUI_FROM_DATABASE=Artnix Inc. + +OUI:000A30* + ID_OUI_FROM_DATABASE=Johnson Controls-ASG + +OUI:000A31* + ID_OUI_FROM_DATABASE=HCV Consulting + +OUI:000A32* + ID_OUI_FROM_DATABASE=Xsido Corporation + +OUI:000A33* + ID_OUI_FROM_DATABASE=Emulex Corporation + +OUI:000A34* + ID_OUI_FROM_DATABASE=Identicard Systems Incorporated + +OUI:000A35* + ID_OUI_FROM_DATABASE=Xilinx + +OUI:000A36* + ID_OUI_FROM_DATABASE=Synelec Telecom Multimedia + +OUI:000A37* + ID_OUI_FROM_DATABASE=Procera Networks, Inc. + +OUI:000A38* + ID_OUI_FROM_DATABASE=Apani Networks + +OUI:000A39* + ID_OUI_FROM_DATABASE=LoPA Information Technology + +OUI:000A3A* + ID_OUI_FROM_DATABASE=J-THREE INTERNATIONAL Holding Co., Ltd. + +OUI:000A3B* + ID_OUI_FROM_DATABASE=GCT Semiconductor, Inc + +OUI:000A3C* + ID_OUI_FROM_DATABASE=Enerpoint Ltd. + +OUI:000A3D* + ID_OUI_FROM_DATABASE=Elo Sistemas Eletronicos S.A. + +OUI:000A3E* + ID_OUI_FROM_DATABASE=EADS Telecom + +OUI:000A3F* + ID_OUI_FROM_DATABASE=Data East Corporation + +OUI:000A40* + ID_OUI_FROM_DATABASE=Crown Audio -- Harmanm International + +OUI:000A41* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000A42* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000A43* + ID_OUI_FROM_DATABASE=Chunghwa Telecom Co., Ltd. + +OUI:000A44* + ID_OUI_FROM_DATABASE=Avery Dennison Deutschland GmbH + +OUI:000A45* + ID_OUI_FROM_DATABASE=Audio-Technica Corp. + +OUI:000A46* + ID_OUI_FROM_DATABASE=ARO WELDING TECHNOLOGIES SAS + +OUI:000A47* + ID_OUI_FROM_DATABASE=Allied Vision Technologies + +OUI:000A48* + ID_OUI_FROM_DATABASE=Albatron Technology + +OUI:000A49* + ID_OUI_FROM_DATABASE=F5 Networks, Inc. + +OUI:000A4A* + ID_OUI_FROM_DATABASE=Targa Systems Ltd. + +OUI:000A4B* + ID_OUI_FROM_DATABASE=DataPower Technology, Inc. + +OUI:000A4C* + ID_OUI_FROM_DATABASE=Molecular Devices Corporation + +OUI:000A4D* + ID_OUI_FROM_DATABASE=Noritz Corporation + +OUI:000A4E* + ID_OUI_FROM_DATABASE=UNITEK Electronics INC. + +OUI:000A4F* + ID_OUI_FROM_DATABASE=Brain Boxes Limited + +OUI:000A50* + ID_OUI_FROM_DATABASE=REMOTEK CORPORATION + +OUI:000A51* + ID_OUI_FROM_DATABASE=GyroSignal Technology Co., Ltd. + +OUI:000A52* + ID_OUI_FROM_DATABASE=AsiaRF Ltd. + +OUI:000A53* + ID_OUI_FROM_DATABASE=Intronics, Incorporated + +OUI:000A54* + ID_OUI_FROM_DATABASE=Laguna Hills, Inc. + +OUI:000A55* + ID_OUI_FROM_DATABASE=MARKEM Corporation + +OUI:000A56* + ID_OUI_FROM_DATABASE=HITACHI Maxell Ltd. + +OUI:000A57* + ID_OUI_FROM_DATABASE=Hewlett-Packard Company - Standards + +OUI:000A58* + ID_OUI_FROM_DATABASE=Ingenieur-Büro Freyer & Siegel + +OUI:000A59* + ID_OUI_FROM_DATABASE=HW server + +OUI:000A5A* + ID_OUI_FROM_DATABASE=GreenNET Technologies Co.,Ltd. + +OUI:000A5B* + ID_OUI_FROM_DATABASE=Power-One as + +OUI:000A5C* + ID_OUI_FROM_DATABASE=Carel s.p.a. + +OUI:000A5D* + ID_OUI_FROM_DATABASE=PUC Founder (MSC) Berhad + +OUI:000A5E* + ID_OUI_FROM_DATABASE=3COM Corporation + +OUI:000A5F* + ID_OUI_FROM_DATABASE=almedio inc. + +OUI:000A60* + ID_OUI_FROM_DATABASE=Autostar Technology Pte Ltd + +OUI:000A61* + ID_OUI_FROM_DATABASE=Cellinx Systems Inc. + +OUI:000A62* + ID_OUI_FROM_DATABASE=Crinis Networks, Inc. + +OUI:000A63* + ID_OUI_FROM_DATABASE=DHD GmbH + +OUI:000A64* + ID_OUI_FROM_DATABASE=Eracom Technologies + +OUI:000A65* + ID_OUI_FROM_DATABASE=GentechMedia.co.,ltd. + +OUI:000A66* + ID_OUI_FROM_DATABASE=MITSUBISHI ELECTRIC SYSTEM & SERVICE CO.,LTD. + +OUI:000A67* + ID_OUI_FROM_DATABASE=OngCorp + +OUI:000A68* + ID_OUI_FROM_DATABASE=SolarFlare Communications, Inc. + +OUI:000A69* + ID_OUI_FROM_DATABASE=SUNNY bell Technology Co., Ltd. + +OUI:000A6A* + ID_OUI_FROM_DATABASE=SVM Microwaves s.r.o. + +OUI:000A6B* + ID_OUI_FROM_DATABASE=Tadiran Telecom Business Systems LTD + +OUI:000A6C* + ID_OUI_FROM_DATABASE=Walchem Corporation + +OUI:000A6D* + ID_OUI_FROM_DATABASE=EKS Elektronikservice GmbH + +OUI:000A6E* + ID_OUI_FROM_DATABASE=Harmonic, Inc + +OUI:000A6F* + ID_OUI_FROM_DATABASE=ZyFLEX Technologies Inc + +OUI:000A70* + ID_OUI_FROM_DATABASE=MPLS Forum + +OUI:000A71* + ID_OUI_FROM_DATABASE=Avrio Technologies, Inc + +OUI:000A72* + ID_OUI_FROM_DATABASE=STEC, INC. + +OUI:000A73* + ID_OUI_FROM_DATABASE=Scientific Atlanta + +OUI:000A74* + ID_OUI_FROM_DATABASE=Manticom Networks Inc. + +OUI:000A75* + ID_OUI_FROM_DATABASE=Caterpillar, Inc + +OUI:000A76* + ID_OUI_FROM_DATABASE=Beida Jade Bird Huaguang Technology Co.,Ltd + +OUI:000A77* + ID_OUI_FROM_DATABASE=Bluewire Technologies LLC + +OUI:000A78* + ID_OUI_FROM_DATABASE=OLITEC + +OUI:000A79* + ID_OUI_FROM_DATABASE=Allied Telesis K.K. corega division + +OUI:000A7A* + ID_OUI_FROM_DATABASE=Kyoritsu Electric Co., Ltd. + +OUI:000A7B* + ID_OUI_FROM_DATABASE=Cornelius Consult + +OUI:000A7C* + ID_OUI_FROM_DATABASE=Tecton Ltd + +OUI:000A7D* + ID_OUI_FROM_DATABASE=Valo, Inc. + +OUI:000A7E* + ID_OUI_FROM_DATABASE=The Advantage Group + +OUI:000A7F* + ID_OUI_FROM_DATABASE=Teradon Industries, Inc + +OUI:000A80* + ID_OUI_FROM_DATABASE=Telkonet Inc. + +OUI:000A81* + ID_OUI_FROM_DATABASE=TEIMA Audiotex S.L. + +OUI:000A82* + ID_OUI_FROM_DATABASE=TATSUTA SYSTEM ELECTRONICS CO.,LTD. + +OUI:000A83* + ID_OUI_FROM_DATABASE=SALTO SYSTEMS S.L. + +OUI:000A84* + ID_OUI_FROM_DATABASE=Rainsun Enterprise Co., Ltd. + +OUI:000A85* + ID_OUI_FROM_DATABASE=PLAT'C2,Inc + +OUI:000A86* + ID_OUI_FROM_DATABASE=Lenze + +OUI:000A87* + ID_OUI_FROM_DATABASE=Integrated Micromachines Inc. + +OUI:000A88* + ID_OUI_FROM_DATABASE=InCypher S.A. + +OUI:000A89* + ID_OUI_FROM_DATABASE=Creval Systems, Inc. + +OUI:000A8A* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000A8B* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000A8C* + ID_OUI_FROM_DATABASE=Guardware Systems Ltd. + +OUI:000A8D* + ID_OUI_FROM_DATABASE=EUROTHERM LIMITED + +OUI:000A8E* + ID_OUI_FROM_DATABASE=Invacom Ltd + +OUI:000A8F* + ID_OUI_FROM_DATABASE=Aska International Inc. + +OUI:000A90* + ID_OUI_FROM_DATABASE=Bayside Interactive, Inc. + +OUI:000A91* + ID_OUI_FROM_DATABASE=HemoCue AB + +OUI:000A92* + ID_OUI_FROM_DATABASE=Presonus Corporation + +OUI:000A93* + ID_OUI_FROM_DATABASE=W2 Networks, Inc. + +OUI:000A94* + ID_OUI_FROM_DATABASE=ShangHai cellink CO., LTD + +OUI:000A95* + ID_OUI_FROM_DATABASE=Apple Computer, Inc. + +OUI:000A96* + ID_OUI_FROM_DATABASE=MEWTEL TECHNOLOGY INC. + +OUI:000A97* + ID_OUI_FROM_DATABASE=SONICblue, Inc. + +OUI:000A98* + ID_OUI_FROM_DATABASE=M+F Gwinner GmbH & Co + +OUI:000A99* + ID_OUI_FROM_DATABASE=Calamp Wireless Networks Inc + +OUI:000A9A* + ID_OUI_FROM_DATABASE=Aiptek International Inc + +OUI:000A9B* + ID_OUI_FROM_DATABASE=TB Group Inc + +OUI:000A9C* + ID_OUI_FROM_DATABASE=Server Technology, Inc. + +OUI:000A9D* + ID_OUI_FROM_DATABASE=King Young Technology Co. Ltd. + +OUI:000A9E* + ID_OUI_FROM_DATABASE=BroadWeb Corportation + +OUI:000A9F* + ID_OUI_FROM_DATABASE=Pannaway Technologies, Inc. + +OUI:000AA0* + ID_OUI_FROM_DATABASE=Cedar Point Communications + +OUI:000AA1* + ID_OUI_FROM_DATABASE=V V S Limited + +OUI:000AA2* + ID_OUI_FROM_DATABASE=SYSTEK INC. + +OUI:000AA3* + ID_OUI_FROM_DATABASE=SHIMAFUJI ELECTRIC CO.,LTD. + +OUI:000AA4* + ID_OUI_FROM_DATABASE=SHANGHAI SURVEILLANCE TECHNOLOGY CO,LTD + +OUI:000AA5* + ID_OUI_FROM_DATABASE=MAXLINK INDUSTRIES LIMITED + +OUI:000AA6* + ID_OUI_FROM_DATABASE=Hochiki Corporation + +OUI:000AA7* + ID_OUI_FROM_DATABASE=FEI Electron Optics + +OUI:000AA8* + ID_OUI_FROM_DATABASE=ePipe Pty. Ltd. + +OUI:000AA9* + ID_OUI_FROM_DATABASE=Brooks Automation GmbH + +OUI:000AAA* + ID_OUI_FROM_DATABASE=AltiGen Communications Inc. + +OUI:000AAB* + ID_OUI_FROM_DATABASE=Toyota Technical Development Corporation + +OUI:000AAC* + ID_OUI_FROM_DATABASE=TerraTec Electronic GmbH + +OUI:000AAD* + ID_OUI_FROM_DATABASE=Stargames Corporation + +OUI:000AAE* + ID_OUI_FROM_DATABASE=Rosemount Process Analytical + +OUI:000AAF* + ID_OUI_FROM_DATABASE=Pipal Systems + +OUI:000AB0* + ID_OUI_FROM_DATABASE=LOYTEC electronics GmbH + +OUI:000AB1* + ID_OUI_FROM_DATABASE=GENETEC Corporation + +OUI:000AB2* + ID_OUI_FROM_DATABASE=Fresnel Wireless Systems + +OUI:000AB3* + ID_OUI_FROM_DATABASE=Fa. GIRA + +OUI:000AB4* + ID_OUI_FROM_DATABASE=ETIC Telecommunications + +OUI:000AB5* + ID_OUI_FROM_DATABASE=Digital Electronic Network + +OUI:000AB6* + ID_OUI_FROM_DATABASE=COMPUNETIX, INC + +OUI:000AB7* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000AB8* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000AB9* + ID_OUI_FROM_DATABASE=Astera Technologies Corp. + +OUI:000ABA* + ID_OUI_FROM_DATABASE=Arcon Technology Limited + +OUI:000ABB* + ID_OUI_FROM_DATABASE=Taiwan Secom Co,. Ltd + +OUI:000ABC* + ID_OUI_FROM_DATABASE=Seabridge Ltd. + +OUI:000ABD* + ID_OUI_FROM_DATABASE=Rupprecht & Patashnick Co. + +OUI:000ABE* + ID_OUI_FROM_DATABASE=OPNET Technologies CO., LTD. + +OUI:000ABF* + ID_OUI_FROM_DATABASE=HIROTA SS + +OUI:000AC0* + ID_OUI_FROM_DATABASE=Fuyoh Video Industry CO., LTD. + +OUI:000AC1* + ID_OUI_FROM_DATABASE=Futuretel + +OUI:000AC2* + ID_OUI_FROM_DATABASE=FiberHome Telecommunication Technologies CO.,LTD + +OUI:000AC3* + ID_OUI_FROM_DATABASE=eM Technics Co., Ltd. + +OUI:000AC4* + ID_OUI_FROM_DATABASE=Daewoo Teletech Co., Ltd + +OUI:000AC5* + ID_OUI_FROM_DATABASE=Color Kinetics + +OUI:000AC6* + ID_OUI_FROM_DATABASE=Overture Networks. + +OUI:000AC7* + ID_OUI_FROM_DATABASE=Unication Group + +OUI:000AC8* + ID_OUI_FROM_DATABASE=ZPSYS CO.,LTD. (Planning&Management) + +OUI:000AC9* + ID_OUI_FROM_DATABASE=Zambeel Inc + +OUI:000ACA* + ID_OUI_FROM_DATABASE=YOKOYAMA SHOKAI CO.,Ltd. + +OUI:000ACB* + ID_OUI_FROM_DATABASE=XPAK MSA Group + +OUI:000ACC* + ID_OUI_FROM_DATABASE=Winnow Networks, Inc. + +OUI:000ACD* + ID_OUI_FROM_DATABASE=Sunrich Technology Limited + +OUI:000ACE* + ID_OUI_FROM_DATABASE=RADIANTECH, INC. + +OUI:000ACF* + ID_OUI_FROM_DATABASE=PROVIDEO Multimedia Co. Ltd. + +OUI:000AD0* + ID_OUI_FROM_DATABASE=Niigata Develoment Center, F.I.T. Co., Ltd. + +OUI:000AD1* + ID_OUI_FROM_DATABASE=MWS + +OUI:000AD2* + ID_OUI_FROM_DATABASE=JEPICO Corporation + +OUI:000AD3* + ID_OUI_FROM_DATABASE=INITECH Co., Ltd + +OUI:000AD4* + ID_OUI_FROM_DATABASE=CoreBell Systems Inc. + +OUI:000AD5* + ID_OUI_FROM_DATABASE=Brainchild Electronic Co., Ltd. + +OUI:000AD6* + ID_OUI_FROM_DATABASE=BeamReach Networks + +OUI:000AD7* + ID_OUI_FROM_DATABASE=Origin ELECTRIC CO.,LTD. + +OUI:000AD8* + ID_OUI_FROM_DATABASE=IPCserv Technology Corp. + +OUI:000AD9* + ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications AB + +OUI:000ADA* + ID_OUI_FROM_DATABASE=Vindicator Technologies + +OUI:000ADB* + ID_OUI_FROM_DATABASE=SkyPilot Network, Inc + +OUI:000ADC* + ID_OUI_FROM_DATABASE=RuggedCom Inc. + +OUI:000ADD* + ID_OUI_FROM_DATABASE=Allworx Corp. + +OUI:000ADE* + ID_OUI_FROM_DATABASE=Happy Communication Co., Ltd. + +OUI:000ADF* + ID_OUI_FROM_DATABASE=Gennum Corporation + +OUI:000AE0* + ID_OUI_FROM_DATABASE=Fujitsu Softek + +OUI:000AE1* + ID_OUI_FROM_DATABASE=EG Technology + +OUI:000AE2* + ID_OUI_FROM_DATABASE=Binatone Electronics International, Ltd + +OUI:000AE3* + ID_OUI_FROM_DATABASE=YANG MEI TECHNOLOGY CO., LTD + +OUI:000AE4* + ID_OUI_FROM_DATABASE=Wistron Corp. + +OUI:000AE5* + ID_OUI_FROM_DATABASE=ScottCare Corporation + +OUI:000AE6* + ID_OUI_FROM_DATABASE=Elitegroup Computer System Co. (ECS) + +OUI:000AE7* + ID_OUI_FROM_DATABASE=ELIOP S.A. + +OUI:000AE8* + ID_OUI_FROM_DATABASE=Cathay Roxus Information Technology Co. LTD + +OUI:000AE9* + ID_OUI_FROM_DATABASE=AirVast Technology Inc. + +OUI:000AEA* + ID_OUI_FROM_DATABASE=ADAM ELEKTRONIK LTD. ŞTI + +OUI:000AEB* + ID_OUI_FROM_DATABASE=Shenzhen Tp-Link Technology Co; Ltd. + +OUI:000AEC* + ID_OUI_FROM_DATABASE=Koatsu Gas Kogyo Co., Ltd. + +OUI:000AED* + ID_OUI_FROM_DATABASE=HARTING Systems GmbH & Co KG + +OUI:000AEE* + ID_OUI_FROM_DATABASE=GCD Hard- & Software GmbH + +OUI:000AEF* + ID_OUI_FROM_DATABASE=OTRUM ASA + +OUI:000AF0* + ID_OUI_FROM_DATABASE=SHIN-OH ELECTRONICS CO., LTD. R&D + +OUI:000AF1* + ID_OUI_FROM_DATABASE=Clarity Design, Inc. + +OUI:000AF2* + ID_OUI_FROM_DATABASE=NeoAxiom Corp. + +OUI:000AF3* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000AF4* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000AF5* + ID_OUI_FROM_DATABASE=Airgo Networks, Inc. + +OUI:000AF6* + ID_OUI_FROM_DATABASE=Emerson Climate Technologies Retail Solutions, Inc. + +OUI:000AF7* + ID_OUI_FROM_DATABASE=Broadcom Corp. + +OUI:000AF8* + ID_OUI_FROM_DATABASE=American Telecare Inc. + +OUI:000AF9* + ID_OUI_FROM_DATABASE=HiConnect, Inc. + +OUI:000AFA* + ID_OUI_FROM_DATABASE=Traverse Technologies Australia + +OUI:000AFB* + ID_OUI_FROM_DATABASE=Ambri Limited + +OUI:000AFC* + ID_OUI_FROM_DATABASE=Core Tec Communications, LLC + +OUI:000AFD* + ID_OUI_FROM_DATABASE=Viking Electronic Services + +OUI:000AFE* + ID_OUI_FROM_DATABASE=NovaPal Ltd + +OUI:000AFF* + ID_OUI_FROM_DATABASE=Kilchherr Elektronik AG + +OUI:000B00* + ID_OUI_FROM_DATABASE=FUJIAN START COMPUTER EQUIPMENT CO.,LTD + +OUI:000B01* + ID_OUI_FROM_DATABASE=DAIICHI ELECTRONICS CO., LTD. + +OUI:000B02* + ID_OUI_FROM_DATABASE=Dallmeier electronic + +OUI:000B03* + ID_OUI_FROM_DATABASE=Taekwang Industrial Co., Ltd + +OUI:000B04* + ID_OUI_FROM_DATABASE=Volktek Corporation + +OUI:000B05* + ID_OUI_FROM_DATABASE=Pacific Broadband Networks + +OUI:000B06* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:000B07* + ID_OUI_FROM_DATABASE=Voxpath Networks + +OUI:000B08* + ID_OUI_FROM_DATABASE=Pillar Data Systems + +OUI:000B09* + ID_OUI_FROM_DATABASE=Ifoundry Systems Singapore + +OUI:000B0A* + ID_OUI_FROM_DATABASE=dBm Optics + +OUI:000B0B* + ID_OUI_FROM_DATABASE=Corrent Corporation + +OUI:000B0C* + ID_OUI_FROM_DATABASE=Agile Systems Inc. + +OUI:000B0D* + ID_OUI_FROM_DATABASE=Air2U, Inc. + +OUI:000B0E* + ID_OUI_FROM_DATABASE=Trapeze Networks + +OUI:000B0F* + ID_OUI_FROM_DATABASE=Bosch Rexroth + +OUI:000B10* + ID_OUI_FROM_DATABASE=11wave Technonlogy Co.,Ltd + +OUI:000B11* + ID_OUI_FROM_DATABASE=HIMEJI ABC TRADING CO.,LTD. + +OUI:000B12* + ID_OUI_FROM_DATABASE=NURI Telecom Co., Ltd. + +OUI:000B13* + ID_OUI_FROM_DATABASE=ZETRON INC + +OUI:000B14* + ID_OUI_FROM_DATABASE=ViewSonic Corporation + +OUI:000B15* + ID_OUI_FROM_DATABASE=Platypus Technology + +OUI:000B16* + ID_OUI_FROM_DATABASE=Communication Machinery Corporation + +OUI:000B17* + ID_OUI_FROM_DATABASE=MKS Instruments + +OUI:000B19* + ID_OUI_FROM_DATABASE=Vernier Networks, Inc. + +OUI:000B1A* + ID_OUI_FROM_DATABASE=Industrial Defender, Inc. + +OUI:000B1B* + ID_OUI_FROM_DATABASE=Systronix, Inc. + +OUI:000B1C* + ID_OUI_FROM_DATABASE=SIBCO bv + +OUI:000B1D* + ID_OUI_FROM_DATABASE=LayerZero Power Systems, Inc. + +OUI:000B1E* + ID_OUI_FROM_DATABASE=KAPPA opto-electronics GmbH + +OUI:000B1F* + ID_OUI_FROM_DATABASE=I CON Computer Co. + +OUI:000B20* + ID_OUI_FROM_DATABASE=Hirata corporation + +OUI:000B21* + ID_OUI_FROM_DATABASE=G-Star Communications Inc. + +OUI:000B22* + ID_OUI_FROM_DATABASE=Environmental Systems and Services + +OUI:000B23* + ID_OUI_FROM_DATABASE=Siemens Subscriber Networks + +OUI:000B24* + ID_OUI_FROM_DATABASE=AirLogic + +OUI:000B25* + ID_OUI_FROM_DATABASE=Aeluros + +OUI:000B26* + ID_OUI_FROM_DATABASE=Wetek Corporation + +OUI:000B27* + ID_OUI_FROM_DATABASE=Scion Corporation + +OUI:000B28* + ID_OUI_FROM_DATABASE=Quatech Inc. + +OUI:000B29* + ID_OUI_FROM_DATABASE=LS(LG) Industrial Systems co.,Ltd + +OUI:000B2A* + ID_OUI_FROM_DATABASE=HOWTEL Co., Ltd. + +OUI:000B2B* + ID_OUI_FROM_DATABASE=HOSTNET CORPORATION + +OUI:000B2C* + ID_OUI_FROM_DATABASE=Eiki Industrial Co. Ltd. + +OUI:000B2D* + ID_OUI_FROM_DATABASE=Danfoss Inc. + +OUI:000B2E* + ID_OUI_FROM_DATABASE=Cal-Comp Electronics (Thailand) Public Company Limited Taipe + +OUI:000B2F* + ID_OUI_FROM_DATABASE=bplan GmbH + +OUI:000B30* + ID_OUI_FROM_DATABASE=Beijing Gongye Science & Technology Co.,Ltd + +OUI:000B31* + ID_OUI_FROM_DATABASE=Yantai ZhiYang Scientific and technology industry CO., LTD + +OUI:000B32* + ID_OUI_FROM_DATABASE=VORMETRIC, INC. + +OUI:000B33* + ID_OUI_FROM_DATABASE=Vivato Technologies + +OUI:000B34* + ID_OUI_FROM_DATABASE=ShangHai Broadband Technologies CO.LTD + +OUI:000B35* + ID_OUI_FROM_DATABASE=Quad Bit System co., Ltd. + +OUI:000B36* + ID_OUI_FROM_DATABASE=Productivity Systems, Inc. + +OUI:000B37* + ID_OUI_FROM_DATABASE=MANUFACTURE DES MONTRES ROLEX SA + +OUI:000B38* + ID_OUI_FROM_DATABASE=Knürr GmbH + +OUI:000B39* + ID_OUI_FROM_DATABASE=Keisoku Giken Co.,Ltd. + +OUI:000B3A* + ID_OUI_FROM_DATABASE=QuStream Corporation + +OUI:000B3B* + ID_OUI_FROM_DATABASE=devolo AG + +OUI:000B3C* + ID_OUI_FROM_DATABASE=Cygnal Integrated Products, Inc. + +OUI:000B3D* + ID_OUI_FROM_DATABASE=CONTAL OK Ltd. + +OUI:000B3E* + ID_OUI_FROM_DATABASE=BittWare, Inc + +OUI:000B3F* + ID_OUI_FROM_DATABASE=Anthology Solutions Inc. + +OUI:000B40* + ID_OUI_FROM_DATABASE=Oclaro + +OUI:000B41* + ID_OUI_FROM_DATABASE=Ing. Büro Dr. Beutlhauser + +OUI:000B42* + ID_OUI_FROM_DATABASE=commax Co., Ltd. + +OUI:000B43* + ID_OUI_FROM_DATABASE=Microscan Systems, Inc. + +OUI:000B44* + ID_OUI_FROM_DATABASE=Concord IDea Corp. + +OUI:000B45* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000B46* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000B47* + ID_OUI_FROM_DATABASE=Advanced Energy + +OUI:000B48* + ID_OUI_FROM_DATABASE=sofrel + +OUI:000B49* + ID_OUI_FROM_DATABASE=RF-Link System Inc. + +OUI:000B4A* + ID_OUI_FROM_DATABASE=Visimetrics (UK) Ltd + +OUI:000B4B* + ID_OUI_FROM_DATABASE=VISIOWAVE SA + +OUI:000B4C* + ID_OUI_FROM_DATABASE=Clarion (M) Sdn Bhd + +OUI:000B4D* + ID_OUI_FROM_DATABASE=Emuzed + +OUI:000B4E* + ID_OUI_FROM_DATABASE=VertexRSI, General Dynamics SatCOM Technologies, Inc. + +OUI:000B4F* + ID_OUI_FROM_DATABASE=Verifone, INC. + +OUI:000B50* + ID_OUI_FROM_DATABASE=Oxygnet + +OUI:000B51* + ID_OUI_FROM_DATABASE=Micetek International Inc. + +OUI:000B52* + ID_OUI_FROM_DATABASE=JOYMAX ELECTRONICS CO. LTD. + +OUI:000B53* + ID_OUI_FROM_DATABASE=INITIUM Co., Ltd. + +OUI:000B54* + ID_OUI_FROM_DATABASE=BiTMICRO Networks, Inc. + +OUI:000B55* + ID_OUI_FROM_DATABASE=ADInstruments + +OUI:000B56* + ID_OUI_FROM_DATABASE=Cybernetics + +OUI:000B57* + ID_OUI_FROM_DATABASE=Silicon Laboratories + +OUI:000B58* + ID_OUI_FROM_DATABASE=Astronautics C.A LTD + +OUI:000B59* + ID_OUI_FROM_DATABASE=ScriptPro, LLC + +OUI:000B5A* + ID_OUI_FROM_DATABASE=HyperEdge + +OUI:000B5B* + ID_OUI_FROM_DATABASE=Rincon Research Corporation + +OUI:000B5C* + ID_OUI_FROM_DATABASE=Newtech Co.,Ltd + +OUI:000B5D* + ID_OUI_FROM_DATABASE=FUJITSU LIMITED + +OUI:000B5E* + ID_OUI_FROM_DATABASE=Audio Engineering Society Inc. + +OUI:000B5F* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000B60* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000B61* + ID_OUI_FROM_DATABASE=Friedrich Lütze GmbH & Co. KG + +OUI:000B62* + ID_OUI_FROM_DATABASE=Ingenieurbüro für Elektronikdesign Ingo Mohnen + +OUI:000B63* + ID_OUI_FROM_DATABASE=Kaleidescape + +OUI:000B64* + ID_OUI_FROM_DATABASE=Kieback & Peter GmbH & Co KG + +OUI:000B65* + ID_OUI_FROM_DATABASE=Sy.A.C. srl + +OUI:000B66* + ID_OUI_FROM_DATABASE=Teralink Communications + +OUI:000B67* + ID_OUI_FROM_DATABASE=Topview Technology Corporation + +OUI:000B68* + ID_OUI_FROM_DATABASE=Addvalue Communications Pte Ltd + +OUI:000B69* + ID_OUI_FROM_DATABASE=Franke Finland Oy + +OUI:000B6A* + ID_OUI_FROM_DATABASE=Asiarock Incorporation + +OUI:000B6B* + ID_OUI_FROM_DATABASE=Wistron Neweb Corp. + +OUI:000B6C* + ID_OUI_FROM_DATABASE=Sychip Inc. + +OUI:000B6D* + ID_OUI_FROM_DATABASE=SOLECTRON JAPAN NAKANIIDA + +OUI:000B6E* + ID_OUI_FROM_DATABASE=Neff Instrument Corp. + +OUI:000B6F* + ID_OUI_FROM_DATABASE=Media Streaming Networks Inc + +OUI:000B70* + ID_OUI_FROM_DATABASE=Load Technology, Inc. + +OUI:000B71* + ID_OUI_FROM_DATABASE=Litchfield Communications Inc. + +OUI:000B72* + ID_OUI_FROM_DATABASE=Lawo AG + +OUI:000B73* + ID_OUI_FROM_DATABASE=Kodeos Communications + +OUI:000B74* + ID_OUI_FROM_DATABASE=Kingwave Technology Co., Ltd. + +OUI:000B75* + ID_OUI_FROM_DATABASE=Iosoft Ltd. + +OUI:000B76* + ID_OUI_FROM_DATABASE=ET&T Technology Co. Ltd. + +OUI:000B77* + ID_OUI_FROM_DATABASE=Cogent Systems, Inc. + +OUI:000B78* + ID_OUI_FROM_DATABASE=TAIFATECH INC. + +OUI:000B79* + ID_OUI_FROM_DATABASE=X-COM, Inc. + +OUI:000B7A* + ID_OUI_FROM_DATABASE=Wave Science Inc. + +OUI:000B7B* + ID_OUI_FROM_DATABASE=Test-Um Inc. + +OUI:000B7C* + ID_OUI_FROM_DATABASE=Telex Communications + +OUI:000B7D* + ID_OUI_FROM_DATABASE=SOLOMON EXTREME INTERNATIONAL LTD. + +OUI:000B7E* + ID_OUI_FROM_DATABASE=SAGINOMIYA Seisakusho Inc. + +OUI:000B7F* + ID_OUI_FROM_DATABASE=Align Engineering LLC + +OUI:000B80* + ID_OUI_FROM_DATABASE=Lycium Networks + +OUI:000B81* + ID_OUI_FROM_DATABASE=Kaparel Corporation + +OUI:000B82* + ID_OUI_FROM_DATABASE=Grandstream Networks, Inc. + +OUI:000B83* + ID_OUI_FROM_DATABASE=DATAWATT B.V. + +OUI:000B84* + ID_OUI_FROM_DATABASE=BODET + +OUI:000B85* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000B86* + ID_OUI_FROM_DATABASE=Aruba Networks + +OUI:000B87* + ID_OUI_FROM_DATABASE=American Reliance Inc. + +OUI:000B88* + ID_OUI_FROM_DATABASE=Vidisco ltd. + +OUI:000B89* + ID_OUI_FROM_DATABASE=Top Global Technology, Ltd. + +OUI:000B8A* + ID_OUI_FROM_DATABASE=MITEQ Inc. + +OUI:000B8B* + ID_OUI_FROM_DATABASE=KERAJET, S.A. + +OUI:000B8C* + ID_OUI_FROM_DATABASE=Flextronics + +OUI:000B8D* + ID_OUI_FROM_DATABASE=Avvio Networks + +OUI:000B8E* + ID_OUI_FROM_DATABASE=Ascent Corporation + +OUI:000B8F* + ID_OUI_FROM_DATABASE=AKITA ELECTRONICS SYSTEMS CO.,LTD. + +OUI:000B90* + ID_OUI_FROM_DATABASE=Adva Optical Networking Inc. + +OUI:000B91* + ID_OUI_FROM_DATABASE=Aglaia Gesellschaft für Bildverarbeitung und Kommunikation mbH + +OUI:000B92* + ID_OUI_FROM_DATABASE=Ascom Danmark A/S + +OUI:000B93* + ID_OUI_FROM_DATABASE=Ritter Elektronik + +OUI:000B94* + ID_OUI_FROM_DATABASE=Digital Monitoring Products, Inc. + +OUI:000B95* + ID_OUI_FROM_DATABASE=eBet Gaming Systems Pty Ltd + +OUI:000B96* + ID_OUI_FROM_DATABASE=Innotrac Diagnostics Oy + +OUI:000B97* + ID_OUI_FROM_DATABASE=Matsushita Electric Industrial Co.,Ltd. + +OUI:000B98* + ID_OUI_FROM_DATABASE=NiceTechVision + +OUI:000B99* + ID_OUI_FROM_DATABASE=SensAble Technologies, Inc. + +OUI:000B9A* + ID_OUI_FROM_DATABASE=Shanghai Ulink Telecom Equipment Co. Ltd. + +OUI:000B9B* + ID_OUI_FROM_DATABASE=Sirius System Co, Ltd. + +OUI:000B9C* + ID_OUI_FROM_DATABASE=TriBeam Technologies, Inc. + +OUI:000B9D* + ID_OUI_FROM_DATABASE=TwinMOS Technologies Inc. + +OUI:000B9E* + ID_OUI_FROM_DATABASE=Yasing Technology Corp. + +OUI:000B9F* + ID_OUI_FROM_DATABASE=Neue ELSA GmbH + +OUI:000BA0* + ID_OUI_FROM_DATABASE=T&L Information Inc. + +OUI:000BA1* + ID_OUI_FROM_DATABASE=SYSCOM Ltd. + +OUI:000BA2* + ID_OUI_FROM_DATABASE=Sumitomo Electric Networks, Inc + +OUI:000BA3* + ID_OUI_FROM_DATABASE=Siemens AG, I&S + +OUI:000BA4* + ID_OUI_FROM_DATABASE=Shiron Satellite Communications Ltd. (1996) + +OUI:000BA5* + ID_OUI_FROM_DATABASE=Quasar Cipta Mandiri, PT + +OUI:000BA6* + ID_OUI_FROM_DATABASE=Miyakawa Electric Works Ltd. + +OUI:000BA7* + ID_OUI_FROM_DATABASE=Maranti Networks + +OUI:000BA8* + ID_OUI_FROM_DATABASE=HANBACK ELECTRONICS CO., LTD. + +OUI:000BA9* + ID_OUI_FROM_DATABASE=CloudShield Technologies, Inc. + +OUI:000BAA* + ID_OUI_FROM_DATABASE=Aiphone co.,Ltd + +OUI:000BAB* + ID_OUI_FROM_DATABASE=Advantech Technology (CHINA) Co., Ltd. + +OUI:000BAC* + ID_OUI_FROM_DATABASE=3Com Ltd + +OUI:000BAD* + ID_OUI_FROM_DATABASE=PC-PoS Inc. + +OUI:000BAE* + ID_OUI_FROM_DATABASE=Vitals System Inc. + +OUI:000BAF* + ID_OUI_FROM_DATABASE=WOOJU COMMUNICATIONS Co,.Ltd + +OUI:000BB0* + ID_OUI_FROM_DATABASE=Sysnet Telematica srl + +OUI:000BB1* + ID_OUI_FROM_DATABASE=Super Star Technology Co., Ltd. + +OUI:000BB2* + ID_OUI_FROM_DATABASE=SMALLBIG TECHNOLOGY + +OUI:000BB3* + ID_OUI_FROM_DATABASE=RiT technologies Ltd. + +OUI:000BB4* + ID_OUI_FROM_DATABASE=RDC Semiconductor Inc., + +OUI:000BB5* + ID_OUI_FROM_DATABASE=nStor Technologies, Inc. + +OUI:000BB6* + ID_OUI_FROM_DATABASE=Metalligence Technology Corp. + +OUI:000BB7* + ID_OUI_FROM_DATABASE=Micro Systems Co.,Ltd. + +OUI:000BB8* + ID_OUI_FROM_DATABASE=Kihoku Electronic Co. + +OUI:000BB9* + ID_OUI_FROM_DATABASE=Imsys AB + +OUI:000BBA* + ID_OUI_FROM_DATABASE=Harmonic, Inc + +OUI:000BBB* + ID_OUI_FROM_DATABASE=Etin Systems Co., Ltd + +OUI:000BBC* + ID_OUI_FROM_DATABASE=En Garde Systems, Inc. + +OUI:000BBD* + ID_OUI_FROM_DATABASE=Connexionz Limited + +OUI:000BBE* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000BBF* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000BC0* + ID_OUI_FROM_DATABASE=China IWNComm Co., Ltd. + +OUI:000BC1* + ID_OUI_FROM_DATABASE=Bay Microsystems, Inc. + +OUI:000BC2* + ID_OUI_FROM_DATABASE=Corinex Communication Corp. + +OUI:000BC3* + ID_OUI_FROM_DATABASE=Multiplex, Inc. + +OUI:000BC4* + ID_OUI_FROM_DATABASE=BIOTRONIK GmbH & Co + +OUI:000BC5* + ID_OUI_FROM_DATABASE=SMC Networks, Inc. + +OUI:000BC6* + ID_OUI_FROM_DATABASE=ISAC, Inc. + +OUI:000BC7* + ID_OUI_FROM_DATABASE=ICET S.p.A. + +OUI:000BC8* + ID_OUI_FROM_DATABASE=AirFlow Networks + +OUI:000BC9* + ID_OUI_FROM_DATABASE=Electroline Equipment + +OUI:000BCA* + ID_OUI_FROM_DATABASE=DATAVAN International Corporation + +OUI:000BCB* + ID_OUI_FROM_DATABASE=Fagor Automation , S. Coop + +OUI:000BCC* + ID_OUI_FROM_DATABASE=JUSAN, S.A. + +OUI:000BCD* + ID_OUI_FROM_DATABASE=Hewlett-Packard Company + +OUI:000BCE* + ID_OUI_FROM_DATABASE=Free2move AB + +OUI:000BCF* + ID_OUI_FROM_DATABASE=AGFA NDT INC. + +OUI:000BD0* + ID_OUI_FROM_DATABASE=XiMeta Technology Americas Inc. + +OUI:000BD1* + ID_OUI_FROM_DATABASE=Aeronix, Inc. + +OUI:000BD2* + ID_OUI_FROM_DATABASE=Remopro Technology Inc. + +OUI:000BD3* + ID_OUI_FROM_DATABASE=cd3o + +OUI:000BD4* + ID_OUI_FROM_DATABASE=Beijing Wise Technology & Science Development Co.Ltd + +OUI:000BD5* + ID_OUI_FROM_DATABASE=Nvergence, Inc. + +OUI:000BD6* + ID_OUI_FROM_DATABASE=Paxton Access Ltd + +OUI:000BD7* + ID_OUI_FROM_DATABASE=DORMA Time + Access GmbH + +OUI:000BD8* + ID_OUI_FROM_DATABASE=Industrial Scientific Corp. + +OUI:000BD9* + ID_OUI_FROM_DATABASE=General Hydrogen + +OUI:000BDA* + ID_OUI_FROM_DATABASE=EyeCross Co.,Inc. + +OUI:000BDB* + ID_OUI_FROM_DATABASE=Dell ESG PCBA Test + +OUI:000BDC* + ID_OUI_FROM_DATABASE=AKCP + +OUI:000BDD* + ID_OUI_FROM_DATABASE=TOHOKU RICOH Co., LTD. + +OUI:000BDE* + ID_OUI_FROM_DATABASE=TELDIX GmbH + +OUI:000BDF* + ID_OUI_FROM_DATABASE=Shenzhen RouterD Networks Limited + +OUI:000BE0* + ID_OUI_FROM_DATABASE=SercoNet Ltd. + +OUI:000BE1* + ID_OUI_FROM_DATABASE=Nokia NET Product Operations + +OUI:000BE2* + ID_OUI_FROM_DATABASE=Lumenera Corporation + +OUI:000BE3* + ID_OUI_FROM_DATABASE=Key Stream Co., Ltd. + +OUI:000BE4* + ID_OUI_FROM_DATABASE=Hosiden Corporation + +OUI:000BE5* + ID_OUI_FROM_DATABASE=HIMS Korea Co., Ltd. + +OUI:000BE6* + ID_OUI_FROM_DATABASE=Datel Electronics + +OUI:000BE7* + ID_OUI_FROM_DATABASE=COMFLUX TECHNOLOGY INC. + +OUI:000BE8* + ID_OUI_FROM_DATABASE=AOIP + +OUI:000BE9* + ID_OUI_FROM_DATABASE=Actel Corporation + +OUI:000BEA* + ID_OUI_FROM_DATABASE=Zultys Technologies + +OUI:000BEB* + ID_OUI_FROM_DATABASE=Systegra AG + +OUI:000BEC* + ID_OUI_FROM_DATABASE=NIPPON ELECTRIC INSTRUMENT, INC. + +OUI:000BED* + ID_OUI_FROM_DATABASE=ELM Inc. + +OUI:000BEE* + ID_OUI_FROM_DATABASE=inc.jet, Incorporated + +OUI:000BEF* + ID_OUI_FROM_DATABASE=Code Corporation + +OUI:000BF0* + ID_OUI_FROM_DATABASE=MoTEX Products Co., Ltd. + +OUI:000BF1* + ID_OUI_FROM_DATABASE=LAP Laser Applikations + +OUI:000BF2* + ID_OUI_FROM_DATABASE=Chih-Kan Technology Co., Ltd. + +OUI:000BF3* + ID_OUI_FROM_DATABASE=BAE SYSTEMS + +OUI:000BF5* + ID_OUI_FROM_DATABASE=Shanghai Sibo Telecom Technology Co.,Ltd + +OUI:000BF6* + ID_OUI_FROM_DATABASE=Nitgen Co., Ltd + +OUI:000BF7* + ID_OUI_FROM_DATABASE=NIDEK CO.,LTD + +OUI:000BF8* + ID_OUI_FROM_DATABASE=Infinera + +OUI:000BF9* + ID_OUI_FROM_DATABASE=Gemstone communications, Inc. + +OUI:000BFA* + ID_OUI_FROM_DATABASE=EXEMYS SRL + +OUI:000BFB* + ID_OUI_FROM_DATABASE=D-NET International Corporation + +OUI:000BFC* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000BFD* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000BFE* + ID_OUI_FROM_DATABASE=CASTEL Broadband Limited + +OUI:000BFF* + ID_OUI_FROM_DATABASE=Berkeley Camera Engineering + +OUI:000C00* + ID_OUI_FROM_DATABASE=BEB Industrie-Elektronik AG + +OUI:000C01* + ID_OUI_FROM_DATABASE=Abatron AG + +OUI:000C02* + ID_OUI_FROM_DATABASE=ABB Oy + +OUI:000C03* + ID_OUI_FROM_DATABASE=HDMI Licensing, LLC + +OUI:000C04* + ID_OUI_FROM_DATABASE=Tecnova + +OUI:000C05* + ID_OUI_FROM_DATABASE=RPA Reserch Co., Ltd. + +OUI:000C06* + ID_OUI_FROM_DATABASE=Nixvue Systems Pte Ltd + +OUI:000C07* + ID_OUI_FROM_DATABASE=Iftest AG + +OUI:000C08* + ID_OUI_FROM_DATABASE=HUMEX Technologies Corp. + +OUI:000C09* + ID_OUI_FROM_DATABASE=Hitachi IE Systems Co., Ltd + +OUI:000C0A* + ID_OUI_FROM_DATABASE=Guangdong Province Electronic Technology Research Institute + +OUI:000C0B* + ID_OUI_FROM_DATABASE=Broadbus Technologies + +OUI:000C0C* + ID_OUI_FROM_DATABASE=APPRO TECHNOLOGY INC. + +OUI:000C0D* + ID_OUI_FROM_DATABASE=Communications & Power Industries / Satcom Division + +OUI:000C0E* + ID_OUI_FROM_DATABASE=XtremeSpectrum, Inc. + +OUI:000C0F* + ID_OUI_FROM_DATABASE=Techno-One Co., Ltd + +OUI:000C10* + ID_OUI_FROM_DATABASE=PNI Corporation + +OUI:000C11* + ID_OUI_FROM_DATABASE=NIPPON DEMPA CO.,LTD. + +OUI:000C12* + ID_OUI_FROM_DATABASE=Micro-Optronic-Messtechnik GmbH + +OUI:000C13* + ID_OUI_FROM_DATABASE=MediaQ + +OUI:000C14* + ID_OUI_FROM_DATABASE=Diagnostic Instruments, Inc. + +OUI:000C15* + ID_OUI_FROM_DATABASE=CyberPower Systems, Inc. + +OUI:000C16* + ID_OUI_FROM_DATABASE=Concorde Microsystems Inc. + +OUI:000C17* + ID_OUI_FROM_DATABASE=AJA Video Systems Inc + +OUI:000C18* + ID_OUI_FROM_DATABASE=Zenisu Keisoku Inc. + +OUI:000C19* + ID_OUI_FROM_DATABASE=Telio Communications GmbH + +OUI:000C1A* + ID_OUI_FROM_DATABASE=Quest Technical Solutions Inc. + +OUI:000C1B* + ID_OUI_FROM_DATABASE=ORACOM Co, Ltd. + +OUI:000C1C* + ID_OUI_FROM_DATABASE=MicroWeb Co., Ltd. + +OUI:000C1D* + ID_OUI_FROM_DATABASE=Mettler & Fuchs AG + +OUI:000C1E* + ID_OUI_FROM_DATABASE=Global Cache + +OUI:000C1F* + ID_OUI_FROM_DATABASE=Glimmerglass Networks + +OUI:000C20* + ID_OUI_FROM_DATABASE=Fi WIn, Inc. + +OUI:000C21* + ID_OUI_FROM_DATABASE=Faculty of Science and Technology, Keio University + +OUI:000C22* + ID_OUI_FROM_DATABASE=Double D Electronics Ltd + +OUI:000C23* + ID_OUI_FROM_DATABASE=Beijing Lanchuan Tech. Co., Ltd. + +OUI:000C24* + ID_OUI_FROM_DATABASE=ANATOR + +OUI:000C25* + ID_OUI_FROM_DATABASE=Allied Telesis Labs, Inc. + +OUI:000C26* + ID_OUI_FROM_DATABASE=Weintek Labs. Inc. + +OUI:000C27* + ID_OUI_FROM_DATABASE=Sammy Corporation + +OUI:000C28* + ID_OUI_FROM_DATABASE=RIFATRON + +OUI:000C29* + ID_OUI_FROM_DATABASE=VMware, Inc. + +OUI:000C2A* + ID_OUI_FROM_DATABASE=OCTTEL Communication Co., Ltd. + +OUI:000C2B* + ID_OUI_FROM_DATABASE=ELIAS Technology, Inc. + +OUI:000C2C* + ID_OUI_FROM_DATABASE=Enwiser Inc. + +OUI:000C2D* + ID_OUI_FROM_DATABASE=FullWave Technology Co., Ltd. + +OUI:000C2E* + ID_OUI_FROM_DATABASE=Openet information technology(shenzhen) Co., Ltd. + +OUI:000C2F* + ID_OUI_FROM_DATABASE=SeorimTechnology Co.,Ltd. + +OUI:000C30* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000C31* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000C32* + ID_OUI_FROM_DATABASE=Avionic Design Development GmbH + +OUI:000C33* + ID_OUI_FROM_DATABASE=Compucase Enterprise Co. Ltd. + +OUI:000C34* + ID_OUI_FROM_DATABASE=Vixen Co., Ltd. + +OUI:000C35* + ID_OUI_FROM_DATABASE=KaVo Dental GmbH & Co. KG + +OUI:000C36* + ID_OUI_FROM_DATABASE=SHARP TAKAYA ELECTRONICS INDUSTRY CO.,LTD. + +OUI:000C37* + ID_OUI_FROM_DATABASE=Geomation, Inc. + +OUI:000C38* + ID_OUI_FROM_DATABASE=TelcoBridges Inc. + +OUI:000C39* + ID_OUI_FROM_DATABASE=Sentinel Wireless Inc. + +OUI:000C3A* + ID_OUI_FROM_DATABASE=Oxance + +OUI:000C3B* + ID_OUI_FROM_DATABASE=Orion Electric Co., Ltd. + +OUI:000C3C* + ID_OUI_FROM_DATABASE=MediaChorus, Inc. + +OUI:000C3D* + ID_OUI_FROM_DATABASE=Glsystech Co., Ltd. + +OUI:000C3E* + ID_OUI_FROM_DATABASE=Crest Audio + +OUI:000C3F* + ID_OUI_FROM_DATABASE=Cogent Defence & Security Networks, + +OUI:000C40* + ID_OUI_FROM_DATABASE=Altech Controls + +OUI:000C41* + ID_OUI_FROM_DATABASE=Cisco-Linksys + +OUI:000C42* + ID_OUI_FROM_DATABASE=Routerboard.com + +OUI:000C43* + ID_OUI_FROM_DATABASE=Ralink Technology, Corp. + +OUI:000C44* + ID_OUI_FROM_DATABASE=Automated Interfaces, Inc. + +OUI:000C45* + ID_OUI_FROM_DATABASE=Animation Technologies Inc. + +OUI:000C46* + ID_OUI_FROM_DATABASE=Allied Telesyn Inc. + +OUI:000C47* + ID_OUI_FROM_DATABASE=SK Teletech(R&D Planning Team) + +OUI:000C48* + ID_OUI_FROM_DATABASE=QoStek Corporation + +OUI:000C49* + ID_OUI_FROM_DATABASE=Dangaard Telecom RTC Division A/S + +OUI:000C4A* + ID_OUI_FROM_DATABASE=Cygnus Microsystems (P) Limited + +OUI:000C4B* + ID_OUI_FROM_DATABASE=Cheops Elektronik + +OUI:000C4C* + ID_OUI_FROM_DATABASE=Arcor AG&Co. + +OUI:000C4D* + ID_OUI_FROM_DATABASE=ACRA CONTROL + +OUI:000C4E* + ID_OUI_FROM_DATABASE=Winbest Technology CO,LT + +OUI:000C4F* + ID_OUI_FROM_DATABASE=UDTech Japan Corporation + +OUI:000C50* + ID_OUI_FROM_DATABASE=Seagate Technology + +OUI:000C51* + ID_OUI_FROM_DATABASE=Scientific Technologies Inc. + +OUI:000C52* + ID_OUI_FROM_DATABASE=Roll Systems Inc. + +OUI:000C54* + ID_OUI_FROM_DATABASE=Pedestal Networks, Inc + +OUI:000C55* + ID_OUI_FROM_DATABASE=Microlink Communications Inc. + +OUI:000C56* + ID_OUI_FROM_DATABASE=Megatel Computer (1986) Corp. + +OUI:000C57* + ID_OUI_FROM_DATABASE=MACKIE Engineering Services Belgium BVBA + +OUI:000C58* + ID_OUI_FROM_DATABASE=M&S Systems + +OUI:000C59* + ID_OUI_FROM_DATABASE=Indyme Electronics, Inc. + +OUI:000C5A* + ID_OUI_FROM_DATABASE=IBSmm Industrieelektronik Multimedia + +OUI:000C5B* + ID_OUI_FROM_DATABASE=HANWANG TECHNOLOGY CO.,LTD + +OUI:000C5C* + ID_OUI_FROM_DATABASE=GTN Systems B.V. + +OUI:000C5D* + ID_OUI_FROM_DATABASE=CHIC TECHNOLOGY (CHINA) CORP. + +OUI:000C5E* + ID_OUI_FROM_DATABASE=Calypso Medical + +OUI:000C5F* + ID_OUI_FROM_DATABASE=Avtec, Inc. + +OUI:000C60* + ID_OUI_FROM_DATABASE=ACM Systems + +OUI:000C61* + ID_OUI_FROM_DATABASE=AC Tech corporation DBA Advanced Digital + +OUI:000C62* + ID_OUI_FROM_DATABASE=ABB AB, Cewe-Control + +OUI:000C63* + ID_OUI_FROM_DATABASE=Zenith Electronics Corporation + +OUI:000C64* + ID_OUI_FROM_DATABASE=X2 MSA Group + +OUI:000C65* + ID_OUI_FROM_DATABASE=Sunin Telecom + +OUI:000C66* + ID_OUI_FROM_DATABASE=Pronto Networks Inc + +OUI:000C67* + ID_OUI_FROM_DATABASE=OYO ELECTRIC CO.,LTD + +OUI:000C68* + ID_OUI_FROM_DATABASE=SigmaTel, Inc. + +OUI:000C69* + ID_OUI_FROM_DATABASE=National Radio Astronomy Observatory + +OUI:000C6A* + ID_OUI_FROM_DATABASE=MBARI + +OUI:000C6B* + ID_OUI_FROM_DATABASE=Kurz Industrie-Elektronik GmbH + +OUI:000C6C* + ID_OUI_FROM_DATABASE=Elgato Systems LLC + +OUI:000C6D* + ID_OUI_FROM_DATABASE=Edwards Ltd. + +OUI:000C6E* + ID_OUI_FROM_DATABASE=ASUSTEK COMPUTER INC. + +OUI:000C6F* + ID_OUI_FROM_DATABASE=Amtek system co.,LTD. + +OUI:000C70* + ID_OUI_FROM_DATABASE=ACC GmbH + +OUI:000C71* + ID_OUI_FROM_DATABASE=Wybron, Inc + +OUI:000C72* + ID_OUI_FROM_DATABASE=Tempearl Industrial Co., Ltd. + +OUI:000C73* + ID_OUI_FROM_DATABASE=TELSON ELECTRONICS CO., LTD + +OUI:000C74* + ID_OUI_FROM_DATABASE=RIVERTEC CORPORATION + +OUI:000C75* + ID_OUI_FROM_DATABASE=Oriental integrated electronics. LTD + +OUI:000C76* + ID_OUI_FROM_DATABASE=MICRO-STAR INTERNATIONAL CO., LTD. + +OUI:000C77* + ID_OUI_FROM_DATABASE=Life Racing Ltd + +OUI:000C78* + ID_OUI_FROM_DATABASE=In-Tech Electronics Limited + +OUI:000C79* + ID_OUI_FROM_DATABASE=Extel Communications P/L + +OUI:000C7A* + ID_OUI_FROM_DATABASE=DaTARIUS Technologies GmbH + +OUI:000C7B* + ID_OUI_FROM_DATABASE=ALPHA PROJECT Co.,Ltd. + +OUI:000C7C* + ID_OUI_FROM_DATABASE=Internet Information Image Inc. + +OUI:000C7D* + ID_OUI_FROM_DATABASE=TEIKOKU ELECTRIC MFG. CO., LTD + +OUI:000C7E* + ID_OUI_FROM_DATABASE=Tellium Incorporated + +OUI:000C7F* + ID_OUI_FROM_DATABASE=synertronixx GmbH + +OUI:000C80* + ID_OUI_FROM_DATABASE=Opelcomm Inc. + +OUI:000C81* + ID_OUI_FROM_DATABASE=Schneider Electric (Australia) + +OUI:000C82* + ID_OUI_FROM_DATABASE=NETWORK TECHNOLOGIES INC + +OUI:000C83* + ID_OUI_FROM_DATABASE=Logical Solutions + +OUI:000C84* + ID_OUI_FROM_DATABASE=Eazix, Inc. + +OUI:000C85* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000C86* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000C87* + ID_OUI_FROM_DATABASE=AMD + +OUI:000C88* + ID_OUI_FROM_DATABASE=Apache Micro Peripherals, Inc. + +OUI:000C89* + ID_OUI_FROM_DATABASE=AC Electric Vehicles, Ltd. + +OUI:000C8A* + ID_OUI_FROM_DATABASE=Bose Corporation + +OUI:000C8B* + ID_OUI_FROM_DATABASE=Connect Tech Inc + +OUI:000C8C* + ID_OUI_FROM_DATABASE=KODICOM CO.,LTD. + +OUI:000C8D* + ID_OUI_FROM_DATABASE=MATRIX VISION GmbH + +OUI:000C8E* + ID_OUI_FROM_DATABASE=Mentor Engineering Inc + +OUI:000C8F* + ID_OUI_FROM_DATABASE=Nergal s.r.l. + +OUI:000C90* + ID_OUI_FROM_DATABASE=Octasic Inc. + +OUI:000C91* + ID_OUI_FROM_DATABASE=Riverhead Networks Inc. + +OUI:000C92* + ID_OUI_FROM_DATABASE=WolfVision Gmbh + +OUI:000C93* + ID_OUI_FROM_DATABASE=Xeline Co., Ltd. + +OUI:000C94* + ID_OUI_FROM_DATABASE=United Electronic Industries, Inc. (EUI) + +OUI:000C95* + ID_OUI_FROM_DATABASE=PrimeNet + +OUI:000C96* + ID_OUI_FROM_DATABASE=OQO, Inc. + +OUI:000C97* + ID_OUI_FROM_DATABASE=NV ADB TTV Technologies SA + +OUI:000C98* + ID_OUI_FROM_DATABASE=LETEK Communications Inc. + +OUI:000C99* + ID_OUI_FROM_DATABASE=HITEL LINK Co.,Ltd + +OUI:000C9A* + ID_OUI_FROM_DATABASE=Hitech Electronics Corp. + +OUI:000C9B* + ID_OUI_FROM_DATABASE=EE Solutions, Inc + +OUI:000C9C* + ID_OUI_FROM_DATABASE=Chongho information & communications + +OUI:000C9D* + ID_OUI_FROM_DATABASE=AirWalk Communications, Inc. + +OUI:000C9E* + ID_OUI_FROM_DATABASE=MemoryLink Corp. + +OUI:000C9F* + ID_OUI_FROM_DATABASE=NKE Corporation + +OUI:000CA0* + ID_OUI_FROM_DATABASE=StorCase Technology, Inc. + +OUI:000CA1* + ID_OUI_FROM_DATABASE=SIGMACOM Co., LTD. + +OUI:000CA2* + ID_OUI_FROM_DATABASE=Harmonic Video Network + +OUI:000CA3* + ID_OUI_FROM_DATABASE=Rancho Technology, Inc. + +OUI:000CA4* + ID_OUI_FROM_DATABASE=Prompttec Product Management GmbH + +OUI:000CA5* + ID_OUI_FROM_DATABASE=Naman NZ LTd + +OUI:000CA6* + ID_OUI_FROM_DATABASE=Mintera Corporation + +OUI:000CA7* + ID_OUI_FROM_DATABASE=Metro (Suzhou) Technologies Co., Ltd. + +OUI:000CA8* + ID_OUI_FROM_DATABASE=Garuda Networks Corporation + +OUI:000CA9* + ID_OUI_FROM_DATABASE=Ebtron Inc. + +OUI:000CAA* + ID_OUI_FROM_DATABASE=Cubic Transportation Systems Inc + +OUI:000CAB* + ID_OUI_FROM_DATABASE=COMMEND International + +OUI:000CAC* + ID_OUI_FROM_DATABASE=Citizen Watch Co., Ltd. + +OUI:000CAD* + ID_OUI_FROM_DATABASE=BTU International + +OUI:000CAE* + ID_OUI_FROM_DATABASE=Ailocom Oy + +OUI:000CAF* + ID_OUI_FROM_DATABASE=TRI TERM CO.,LTD. + +OUI:000CB0* + ID_OUI_FROM_DATABASE=Star Semiconductor Corporation + +OUI:000CB1* + ID_OUI_FROM_DATABASE=Salland Engineering (Europe) BV + +OUI:000CB2* + ID_OUI_FROM_DATABASE=Comstar Co., Ltd. + +OUI:000CB3* + ID_OUI_FROM_DATABASE=ROUND Co.,Ltd. + +OUI:000CB4* + ID_OUI_FROM_DATABASE=AutoCell Laboratories, Inc. + +OUI:000CB5* + ID_OUI_FROM_DATABASE=Premier Technolgies, Inc + +OUI:000CB6* + ID_OUI_FROM_DATABASE=NANJING SEU MOBILE & INTERNET TECHNOLOGY CO.,LTD + +OUI:000CB7* + ID_OUI_FROM_DATABASE=Nanjing Huazhuo Electronics Co., Ltd. + +OUI:000CB8* + ID_OUI_FROM_DATABASE=MEDION AG + +OUI:000CB9* + ID_OUI_FROM_DATABASE=LEA + +OUI:000CBA* + ID_OUI_FROM_DATABASE=Jamex, Inc. + +OUI:000CBB* + ID_OUI_FROM_DATABASE=ISKRAEMECO + +OUI:000CBC* + ID_OUI_FROM_DATABASE=Iscutum + +OUI:000CBD* + ID_OUI_FROM_DATABASE=Interface Masters, Inc + +OUI:000CBE* + ID_OUI_FROM_DATABASE=Innominate Security Technologies AG + +OUI:000CBF* + ID_OUI_FROM_DATABASE=Holy Stone Ent. Co., Ltd. + +OUI:000CC0* + ID_OUI_FROM_DATABASE=Genera Oy + +OUI:000CC1* + ID_OUI_FROM_DATABASE=Cooper Industries Inc. + +OUI:000CC2* + ID_OUI_FROM_DATABASE=ControlNet (India) Private Limited + +OUI:000CC3* + ID_OUI_FROM_DATABASE=BeWAN systems + +OUI:000CC4* + ID_OUI_FROM_DATABASE=Tiptel AG + +OUI:000CC5* + ID_OUI_FROM_DATABASE=Nextlink Co., Ltd. + +OUI:000CC6* + ID_OUI_FROM_DATABASE=Ka-Ro electronics GmbH + +OUI:000CC7* + ID_OUI_FROM_DATABASE=Intelligent Computer Solutions Inc. + +OUI:000CC8* + ID_OUI_FROM_DATABASE=Xytronix Research & Design, Inc. + +OUI:000CC9* + ID_OUI_FROM_DATABASE=ILWOO DATA & TECHNOLOGY CO.,LTD + +OUI:000CCA* + ID_OUI_FROM_DATABASE=HGST a Western Digital Company + +OUI:000CCB* + ID_OUI_FROM_DATABASE=Design Combus Ltd + +OUI:000CCC* + ID_OUI_FROM_DATABASE=Aeroscout Ltd. + +OUI:000CCD* + ID_OUI_FROM_DATABASE=IEC - TC57 + +OUI:000CCE* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000CCF* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000CD0* + ID_OUI_FROM_DATABASE=Symetrix + +OUI:000CD1* + ID_OUI_FROM_DATABASE=SFOM Technology Corp. + +OUI:000CD2* + ID_OUI_FROM_DATABASE=Schaffner EMV AG + +OUI:000CD3* + ID_OUI_FROM_DATABASE=Prettl Elektronik Radeberg GmbH + +OUI:000CD4* + ID_OUI_FROM_DATABASE=Positron Public Safety Systems inc. + +OUI:000CD5* + ID_OUI_FROM_DATABASE=Passave Inc. + +OUI:000CD6* + ID_OUI_FROM_DATABASE=PARTNER TECH + +OUI:000CD7* + ID_OUI_FROM_DATABASE=Nallatech Ltd + +OUI:000CD8* + ID_OUI_FROM_DATABASE=M. K. Juchheim GmbH & Co + +OUI:000CD9* + ID_OUI_FROM_DATABASE=Itcare Co., Ltd + +OUI:000CDA* + ID_OUI_FROM_DATABASE=FreeHand Systems, Inc. + +OUI:000CDB* + ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc + +OUI:000CDC* + ID_OUI_FROM_DATABASE=BECS Technology, Inc + +OUI:000CDD* + ID_OUI_FROM_DATABASE=AOS Technologies AG + +OUI:000CDE* + ID_OUI_FROM_DATABASE=ABB STOTZ-KONTAKT GmbH + +OUI:000CDF* + ID_OUI_FROM_DATABASE=PULNiX America, Inc + +OUI:000CE0* + ID_OUI_FROM_DATABASE=Trek Diagnostics Inc. + +OUI:000CE1* + ID_OUI_FROM_DATABASE=The Open Group + +OUI:000CE2* + ID_OUI_FROM_DATABASE=Rolls-Royce + +OUI:000CE3* + ID_OUI_FROM_DATABASE=Option International N.V. + +OUI:000CE4* + ID_OUI_FROM_DATABASE=NeuroCom International, Inc. + +OUI:000CE5* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:000CE6* + ID_OUI_FROM_DATABASE=Meru Networks Inc + +OUI:000CE7* + ID_OUI_FROM_DATABASE=MediaTek Inc. + +OUI:000CE8* + ID_OUI_FROM_DATABASE=GuangZhou AnJuBao Co., Ltd + +OUI:000CE9* + ID_OUI_FROM_DATABASE=BLOOMBERG L.P. + +OUI:000CEA* + ID_OUI_FROM_DATABASE=aphona Kommunikationssysteme + +OUI:000CEB* + ID_OUI_FROM_DATABASE=CNMP Networks, Inc. + +OUI:000CEC* + ID_OUI_FROM_DATABASE=Spectracom Corp. + +OUI:000CED* + ID_OUI_FROM_DATABASE=Real Digital Media + +OUI:000CEE* + ID_OUI_FROM_DATABASE=jp-embedded + +OUI:000CEF* + ID_OUI_FROM_DATABASE=Open Networks Engineering Ltd + +OUI:000CF0* + ID_OUI_FROM_DATABASE=M & N GmbH + +OUI:000CF1* + ID_OUI_FROM_DATABASE=Intel Corporation + +OUI:000CF2* + ID_OUI_FROM_DATABASE=GAMESA Eólica + +OUI:000CF3* + ID_OUI_FROM_DATABASE=CALL IMAGE SA + +OUI:000CF4* + ID_OUI_FROM_DATABASE=AKATSUKI ELECTRIC MFG.CO.,LTD. + +OUI:000CF5* + ID_OUI_FROM_DATABASE=InfoExpress + +OUI:000CF6* + ID_OUI_FROM_DATABASE=Sitecom Europe BV + +OUI:000CF7* + ID_OUI_FROM_DATABASE=Nortel Networks + +OUI:000CF8* + ID_OUI_FROM_DATABASE=Nortel Networks + +OUI:000CF9* + ID_OUI_FROM_DATABASE=ITT Flygt AB + +OUI:000CFA* + ID_OUI_FROM_DATABASE=Digital Systems Corp + +OUI:000CFB* + ID_OUI_FROM_DATABASE=Korea Network Systems + +OUI:000CFC* + ID_OUI_FROM_DATABASE=S2io Technologies Corp + +OUI:000CFD* + ID_OUI_FROM_DATABASE=Hyundai ImageQuest Co.,Ltd. + +OUI:000CFE* + ID_OUI_FROM_DATABASE=Grand Electronic Co., Ltd + +OUI:000CFF* + ID_OUI_FROM_DATABASE=MRO-TEK LIMITED + +OUI:000D00* + ID_OUI_FROM_DATABASE=Seaway Networks Inc. + +OUI:000D01* + ID_OUI_FROM_DATABASE=P&E Microcomputer Systems, Inc. + +OUI:000D02* + ID_OUI_FROM_DATABASE=NEC AccessTechnica, Ltd. + +OUI:000D03* + ID_OUI_FROM_DATABASE=Matrics, Inc. + +OUI:000D04* + ID_OUI_FROM_DATABASE=Foxboro Eckardt Development GmbH + +OUI:000D05* + ID_OUI_FROM_DATABASE=cybernet manufacturing inc. + +OUI:000D06* + ID_OUI_FROM_DATABASE=Compulogic Limited + +OUI:000D07* + ID_OUI_FROM_DATABASE=Calrec Audio Ltd + +OUI:000D08* + ID_OUI_FROM_DATABASE=AboveCable, Inc. + +OUI:000D09* + ID_OUI_FROM_DATABASE=Yuehua(Zhuhai) Electronic CO. LTD + +OUI:000D0A* + ID_OUI_FROM_DATABASE=Projectiondesign as + +OUI:000D0B* + ID_OUI_FROM_DATABASE=Buffalo Inc. + +OUI:000D0C* + ID_OUI_FROM_DATABASE=MDI Security Systems + +OUI:000D0D* + ID_OUI_FROM_DATABASE=ITSupported, LLC + +OUI:000D0E* + ID_OUI_FROM_DATABASE=Inqnet Systems, Inc. + +OUI:000D0F* + ID_OUI_FROM_DATABASE=Finlux Ltd + +OUI:000D10* + ID_OUI_FROM_DATABASE=Embedtronics Oy + +OUI:000D11* + ID_OUI_FROM_DATABASE=DENTSPLY - Gendex + +OUI:000D12* + ID_OUI_FROM_DATABASE=AXELL Corporation + +OUI:000D13* + ID_OUI_FROM_DATABASE=Wilhelm Rutenbeck GmbH&Co. + +OUI:000D14* + ID_OUI_FROM_DATABASE=Vtech Innovation LP dba Advanced American Telephones + +OUI:000D15* + ID_OUI_FROM_DATABASE=Voipac s.r.o. + +OUI:000D16* + ID_OUI_FROM_DATABASE=UHS Systems Pty Ltd + +OUI:000D17* + ID_OUI_FROM_DATABASE=Turbo Networks Co.Ltd + +OUI:000D18* + ID_OUI_FROM_DATABASE=Mega-Trend Electronics CO., LTD. + +OUI:000D19* + ID_OUI_FROM_DATABASE=ROBE Show lighting + +OUI:000D1A* + ID_OUI_FROM_DATABASE=Mustek System Inc. + +OUI:000D1B* + ID_OUI_FROM_DATABASE=Kyoto Electronics Manufacturing Co., Ltd. + +OUI:000D1C* + ID_OUI_FROM_DATABASE=Amesys Defense + +OUI:000D1D* + ID_OUI_FROM_DATABASE=HIGH-TEK HARNESS ENT. CO., LTD. + +OUI:000D1E* + ID_OUI_FROM_DATABASE=Control Techniques + +OUI:000D1F* + ID_OUI_FROM_DATABASE=AV Digital + +OUI:000D20* + ID_OUI_FROM_DATABASE=ASAHIKASEI TECHNOSYSTEM CO.,LTD. + +OUI:000D21* + ID_OUI_FROM_DATABASE=WISCORE Inc. + +OUI:000D22* + ID_OUI_FROM_DATABASE=Unitronics LTD + +OUI:000D23* + ID_OUI_FROM_DATABASE=Smart Solution, Inc + +OUI:000D24* + ID_OUI_FROM_DATABASE=SENTEC E&E CO., LTD. + +OUI:000D25* + ID_OUI_FROM_DATABASE=SANDEN CORPORATION + +OUI:000D26* + ID_OUI_FROM_DATABASE=Primagraphics Limited + +OUI:000D27* + ID_OUI_FROM_DATABASE=MICROPLEX Printware AG + +OUI:000D28* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000D29* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000D2A* + ID_OUI_FROM_DATABASE=Scanmatic AS + +OUI:000D2B* + ID_OUI_FROM_DATABASE=Racal Instruments + +OUI:000D2C* + ID_OUI_FROM_DATABASE=Patapsco Designs Ltd + +OUI:000D2D* + ID_OUI_FROM_DATABASE=NCT Deutschland GmbH + +OUI:000D2E* + ID_OUI_FROM_DATABASE=Matsushita Avionics Systems Corporation + +OUI:000D2F* + ID_OUI_FROM_DATABASE=AIN Comm.Tech.Co., LTD + +OUI:000D30* + ID_OUI_FROM_DATABASE=IceFyre Semiconductor + +OUI:000D31* + ID_OUI_FROM_DATABASE=Compellent Technologies, Inc. + +OUI:000D32* + ID_OUI_FROM_DATABASE=DispenseSource, Inc. + +OUI:000D33* + ID_OUI_FROM_DATABASE=Prediwave Corp. + +OUI:000D34* + ID_OUI_FROM_DATABASE=Shell International Exploration and Production, Inc. + +OUI:000D35* + ID_OUI_FROM_DATABASE=PAC International Ltd + +OUI:000D36* + ID_OUI_FROM_DATABASE=Wu Han Routon Electronic Co., Ltd + +OUI:000D37* + ID_OUI_FROM_DATABASE=WIPLUG + +OUI:000D38* + ID_OUI_FROM_DATABASE=NISSIN INC. + +OUI:000D39* + ID_OUI_FROM_DATABASE=Network Electronics + +OUI:000D3A* + ID_OUI_FROM_DATABASE=Microsoft Corp. + +OUI:000D3B* + ID_OUI_FROM_DATABASE=Microelectronics Technology Inc. + +OUI:000D3C* + ID_OUI_FROM_DATABASE=i.Tech Dynamic Ltd + +OUI:000D3D* + ID_OUI_FROM_DATABASE=Hammerhead Systems, Inc. + +OUI:000D3E* + ID_OUI_FROM_DATABASE=APLUX Communications Ltd. + +OUI:000D3F* + ID_OUI_FROM_DATABASE=VTI Instruments Corporation + +OUI:000D40* + ID_OUI_FROM_DATABASE=Verint Loronix Video Solutions + +OUI:000D41* + ID_OUI_FROM_DATABASE=Siemens AG ICM MP UC RD IT KLF1 + +OUI:000D42* + ID_OUI_FROM_DATABASE=Newbest Development Limited + +OUI:000D43* + ID_OUI_FROM_DATABASE=DRS Tactical Systems Inc. + +OUI:000D44* + ID_OUI_FROM_DATABASE=Audio BU - Logitech + +OUI:000D45* + ID_OUI_FROM_DATABASE=Tottori SANYO Electric Co., Ltd. + +OUI:000D46* + ID_OUI_FROM_DATABASE=Parker SSD Drives + +OUI:000D47* + ID_OUI_FROM_DATABASE=Collex + +OUI:000D48* + ID_OUI_FROM_DATABASE=AEWIN Technologies Co., Ltd. + +OUI:000D49* + ID_OUI_FROM_DATABASE=Triton Systems of Delaware, Inc. + +OUI:000D4A* + ID_OUI_FROM_DATABASE=Steag ETA-Optik + +OUI:000D4B* + ID_OUI_FROM_DATABASE=Roku, LLC + +OUI:000D4C* + ID_OUI_FROM_DATABASE=Outline Electronics Ltd. + +OUI:000D4D* + ID_OUI_FROM_DATABASE=Ninelanes + +OUI:000D4E* + ID_OUI_FROM_DATABASE=NDR Co.,LTD. + +OUI:000D4F* + ID_OUI_FROM_DATABASE=Kenwood Corporation + +OUI:000D50* + ID_OUI_FROM_DATABASE=Galazar Networks + +OUI:000D51* + ID_OUI_FROM_DATABASE=DIVR Systems, Inc. + +OUI:000D52* + ID_OUI_FROM_DATABASE=Comart system + +OUI:000D53* + ID_OUI_FROM_DATABASE=Beijing 5w Communication Corp. + +OUI:000D54* + ID_OUI_FROM_DATABASE=3Com Ltd + +OUI:000D55* + ID_OUI_FROM_DATABASE=SANYCOM Technology Co.,Ltd + +OUI:000D56* + ID_OUI_FROM_DATABASE=Dell PCBA Test + +OUI:000D57* + ID_OUI_FROM_DATABASE=Fujitsu I-Network Systems Limited. + +OUI:000D59* + ID_OUI_FROM_DATABASE=Amity Systems, Inc. + +OUI:000D5A* + ID_OUI_FROM_DATABASE=Tiesse SpA + +OUI:000D5B* + ID_OUI_FROM_DATABASE=Smart Empire Investments Limited + +OUI:000D5C* + ID_OUI_FROM_DATABASE=Robert Bosch GmbH, VT-ATMO + +OUI:000D5D* + ID_OUI_FROM_DATABASE=Raritan Computer, Inc + +OUI:000D5E* + ID_OUI_FROM_DATABASE=NEC Personal Products + +OUI:000D5F* + ID_OUI_FROM_DATABASE=Minds Inc + +OUI:000D60* + ID_OUI_FROM_DATABASE=IBM Corp + +OUI:000D61* + ID_OUI_FROM_DATABASE=Giga-Byte Technology Co., Ltd. + +OUI:000D62* + ID_OUI_FROM_DATABASE=Funkwerk Dabendorf GmbH + +OUI:000D63* + ID_OUI_FROM_DATABASE=DENT Instruments, Inc. + +OUI:000D64* + ID_OUI_FROM_DATABASE=COMAG Handels AG + +OUI:000D65* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000D66* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000D67* + ID_OUI_FROM_DATABASE=BelAir Networks Inc. + +OUI:000D68* + ID_OUI_FROM_DATABASE=Vinci Systems, Inc. + +OUI:000D69* + ID_OUI_FROM_DATABASE=TMT&D Corporation + +OUI:000D6A* + ID_OUI_FROM_DATABASE=Redwood Technologies LTD + +OUI:000D6B* + ID_OUI_FROM_DATABASE=Mita-Teknik A/S + +OUI:000D6C* + ID_OUI_FROM_DATABASE=M-Audio + +OUI:000D6D* + ID_OUI_FROM_DATABASE=K-Tech Devices Corp. + +OUI:000D6E* + ID_OUI_FROM_DATABASE=K-Patents Oy + +OUI:000D6F* + ID_OUI_FROM_DATABASE=Ember Corporation + +OUI:000D70* + ID_OUI_FROM_DATABASE=Datamax Corporation + +OUI:000D71* + ID_OUI_FROM_DATABASE=boca systems + +OUI:000D72* + ID_OUI_FROM_DATABASE=2Wire, Inc + +OUI:000D73* + ID_OUI_FROM_DATABASE=Technical Support, Inc. + +OUI:000D74* + ID_OUI_FROM_DATABASE=Sand Network Systems, Inc. + +OUI:000D75* + ID_OUI_FROM_DATABASE=Kobian Pte Ltd - Taiwan Branch + +OUI:000D76* + ID_OUI_FROM_DATABASE=Hokuto Denshi Co,. Ltd. + +OUI:000D77* + ID_OUI_FROM_DATABASE=FalconStor Software + +OUI:000D78* + ID_OUI_FROM_DATABASE=Engineering & Security + +OUI:000D79* + ID_OUI_FROM_DATABASE=Dynamic Solutions Co,.Ltd. + +OUI:000D7A* + ID_OUI_FROM_DATABASE=DiGATTO Asia Pacific Pte Ltd + +OUI:000D7B* + ID_OUI_FROM_DATABASE=Consensys Computers Inc. + +OUI:000D7C* + ID_OUI_FROM_DATABASE=Codian Ltd + +OUI:000D7D* + ID_OUI_FROM_DATABASE=Afco Systems + +OUI:000D7E* + ID_OUI_FROM_DATABASE=Axiowave Networks, Inc. + +OUI:000D7F* + ID_OUI_FROM_DATABASE=MIDAS COMMUNICATION TECHNOLOGIES PTE LTD ( Foreign Branch) + +OUI:000D80* + ID_OUI_FROM_DATABASE=Online Development Inc + +OUI:000D81* + ID_OUI_FROM_DATABASE=Pepperl+Fuchs GmbH + +OUI:000D82* + ID_OUI_FROM_DATABASE=PHS srl + +OUI:000D83* + ID_OUI_FROM_DATABASE=Sanmina-SCI Hungary Ltd. + +OUI:000D84* + ID_OUI_FROM_DATABASE=Makus Inc. + +OUI:000D85* + ID_OUI_FROM_DATABASE=Tapwave, Inc. + +OUI:000D86* + ID_OUI_FROM_DATABASE=Huber + Suhner AG + +OUI:000D87* + ID_OUI_FROM_DATABASE=Elitegroup Computer System Co. (ECS) + +OUI:000D88* + ID_OUI_FROM_DATABASE=D-Link Corporation + +OUI:000D89* + ID_OUI_FROM_DATABASE=Bils Technology Inc + +OUI:000D8A* + ID_OUI_FROM_DATABASE=Winners Electronics Co., Ltd. + +OUI:000D8B* + ID_OUI_FROM_DATABASE=T&D Corporation + +OUI:000D8C* + ID_OUI_FROM_DATABASE=Shanghai Wedone Digital Ltd. CO. + +OUI:000D8D* + ID_OUI_FROM_DATABASE=ProLinx Communication Gateways, Inc. + +OUI:000D8E* + ID_OUI_FROM_DATABASE=Koden Electronics Co., Ltd. + +OUI:000D8F* + ID_OUI_FROM_DATABASE=King Tsushin Kogyo Co., LTD. + +OUI:000D90* + ID_OUI_FROM_DATABASE=Factum Electronics AB + +OUI:000D91* + ID_OUI_FROM_DATABASE=Eclipse (HQ Espana) S.L. + +OUI:000D92* + ID_OUI_FROM_DATABASE=Arima Communication Corporation + +OUI:000D93* + ID_OUI_FROM_DATABASE=Apple Computer + +OUI:000D94* + ID_OUI_FROM_DATABASE=AFAR Communications,Inc + +OUI:000D95* + ID_OUI_FROM_DATABASE=Opti-cell, Inc. + +OUI:000D96* + ID_OUI_FROM_DATABASE=Vtera Technology Inc. + +OUI:000D97* + ID_OUI_FROM_DATABASE=Tropos Networks, Inc. + +OUI:000D98* + ID_OUI_FROM_DATABASE=S.W.A.C. Schmitt-Walter Automation Consult GmbH + +OUI:000D99* + ID_OUI_FROM_DATABASE=Orbital Sciences Corp.; Launch Systems Group + +OUI:000D9A* + ID_OUI_FROM_DATABASE=INFOTEC LTD + +OUI:000D9B* + ID_OUI_FROM_DATABASE=Heraeus Electro-Nite International N.V. + +OUI:000D9C* + ID_OUI_FROM_DATABASE=Elan GmbH & Co KG + +OUI:000D9D* + ID_OUI_FROM_DATABASE=Hewlett-Packard Company + +OUI:000D9E* + ID_OUI_FROM_DATABASE=TOKUDEN OHIZUMI SEISAKUSYO Co.,Ltd. + +OUI:000D9F* + ID_OUI_FROM_DATABASE=RF Micro Devices + +OUI:000DA0* + ID_OUI_FROM_DATABASE=NEDAP N.V. + +OUI:000DA1* + ID_OUI_FROM_DATABASE=MIRAE ITS Co.,LTD. + +OUI:000DA2* + ID_OUI_FROM_DATABASE=Infrant Technologies, Inc. + +OUI:000DA3* + ID_OUI_FROM_DATABASE=Emerging Technologies Limited + +OUI:000DA4* + ID_OUI_FROM_DATABASE=DOSCH & AMAND SYSTEMS AG + +OUI:000DA5* + ID_OUI_FROM_DATABASE=Fabric7 Systems, Inc + +OUI:000DA6* + ID_OUI_FROM_DATABASE=Universal Switching Corporation + +OUI:000DA8* + ID_OUI_FROM_DATABASE=Teletronics Technology Corporation + +OUI:000DA9* + ID_OUI_FROM_DATABASE=T.E.A.M. S.L. + +OUI:000DAA* + ID_OUI_FROM_DATABASE=S.A.Tehnology co.,Ltd. + +OUI:000DAB* + ID_OUI_FROM_DATABASE=Parker Hannifin GmbH Electromechanical Division Europe + +OUI:000DAC* + ID_OUI_FROM_DATABASE=Japan CBM Corporation + +OUI:000DAD* + ID_OUI_FROM_DATABASE=Dataprobe Inc + +OUI:000DAE* + ID_OUI_FROM_DATABASE=SAMSUNG HEAVY INDUSTRIES CO., LTD. + +OUI:000DAF* + ID_OUI_FROM_DATABASE=Plexus Corp (UK) Ltd + +OUI:000DB0* + ID_OUI_FROM_DATABASE=Olym-tech Co.,Ltd. + +OUI:000DB1* + ID_OUI_FROM_DATABASE=Japan Network Service Co., Ltd. + +OUI:000DB2* + ID_OUI_FROM_DATABASE=Ammasso, Inc. + +OUI:000DB3* + ID_OUI_FROM_DATABASE=SDO Communication Corperation + +OUI:000DB4* + ID_OUI_FROM_DATABASE=NETASQ + +OUI:000DB5* + ID_OUI_FROM_DATABASE=GLOBALSAT TECHNOLOGY CORPORATION + +OUI:000DB6* + ID_OUI_FROM_DATABASE=Broadcom Corporation + +OUI:000DB7* + ID_OUI_FROM_DATABASE=SANKO ELECTRIC CO,.LTD + +OUI:000DB8* + ID_OUI_FROM_DATABASE=SCHILLER AG + +OUI:000DB9* + ID_OUI_FROM_DATABASE=PC Engines GmbH + +OUI:000DBA* + ID_OUI_FROM_DATABASE=Océ Document Technologies GmbH + +OUI:000DBB* + ID_OUI_FROM_DATABASE=Nippon Dentsu Co.,Ltd. + +OUI:000DBC* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000DBD* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000DBE* + ID_OUI_FROM_DATABASE=Bel Fuse Europe Ltd.,UK + +OUI:000DBF* + ID_OUI_FROM_DATABASE=TekTone Sound & Signal Mfg., Inc. + +OUI:000DC0* + ID_OUI_FROM_DATABASE=Spagat AS + +OUI:000DC1* + ID_OUI_FROM_DATABASE=SafeWeb Inc + +OUI:000DC3* + ID_OUI_FROM_DATABASE=First Communication, Inc. + +OUI:000DC4* + ID_OUI_FROM_DATABASE=Emcore Corporation + +OUI:000DC5* + ID_OUI_FROM_DATABASE=EchoStar Global B.V. + +OUI:000DC6* + ID_OUI_FROM_DATABASE=DigiRose Technology Co., Ltd. + +OUI:000DC7* + ID_OUI_FROM_DATABASE=COSMIC ENGINEERING INC. + +OUI:000DC8* + ID_OUI_FROM_DATABASE=AirMagnet, Inc + +OUI:000DC9* + ID_OUI_FROM_DATABASE=THALES Elektronik Systeme GmbH + +OUI:000DCA* + ID_OUI_FROM_DATABASE=Tait Electronics + +OUI:000DCB* + ID_OUI_FROM_DATABASE=Petcomkorea Co., Ltd. + +OUI:000DCC* + ID_OUI_FROM_DATABASE=NEOSMART Corp. + +OUI:000DCD* + ID_OUI_FROM_DATABASE=GROUPE TXCOM + +OUI:000DCE* + ID_OUI_FROM_DATABASE=Dynavac Technology Pte Ltd + +OUI:000DCF* + ID_OUI_FROM_DATABASE=Cidra Corp. + +OUI:000DD0* + ID_OUI_FROM_DATABASE=TetraTec Instruments GmbH + +OUI:000DD1* + ID_OUI_FROM_DATABASE=Stryker Corporation + +OUI:000DD2* + ID_OUI_FROM_DATABASE=Simrad Optronics ASA + +OUI:000DD3* + ID_OUI_FROM_DATABASE=SAMWOO Telecommunication Co.,Ltd. + +OUI:000DD4* + ID_OUI_FROM_DATABASE=Symantec Corporation + +OUI:000DD5* + ID_OUI_FROM_DATABASE=O'RITE TECHNOLOGY CO.,LTD + +OUI:000DD6* + ID_OUI_FROM_DATABASE=ITI LTD + +OUI:000DD7* + ID_OUI_FROM_DATABASE=Bright + +OUI:000DD8* + ID_OUI_FROM_DATABASE=BBN + +OUI:000DD9* + ID_OUI_FROM_DATABASE=Anton Paar GmbH + +OUI:000DDA* + ID_OUI_FROM_DATABASE=ALLIED TELESIS K.K. + +OUI:000DDB* + ID_OUI_FROM_DATABASE=AIRWAVE TECHNOLOGIES INC. + +OUI:000DDC* + ID_OUI_FROM_DATABASE=VAC + +OUI:000DDD* + ID_OUI_FROM_DATABASE=Profilo Telra Elektronik Sanayi ve Ticaret. A.Ş + +OUI:000DDE* + ID_OUI_FROM_DATABASE=Joyteck Co., Ltd. + +OUI:000DDF* + ID_OUI_FROM_DATABASE=Japan Image & Network Inc. + +OUI:000DE0* + ID_OUI_FROM_DATABASE=ICPDAS Co.,LTD + +OUI:000DE1* + ID_OUI_FROM_DATABASE=Control Products, Inc. + +OUI:000DE2* + ID_OUI_FROM_DATABASE=CMZ Sistemi Elettronici + +OUI:000DE3* + ID_OUI_FROM_DATABASE=AT Sweden AB + +OUI:000DE4* + ID_OUI_FROM_DATABASE=DIGINICS, Inc. + +OUI:000DE5* + ID_OUI_FROM_DATABASE=Samsung Thales + +OUI:000DE6* + ID_OUI_FROM_DATABASE=YOUNGBO ENGINEERING CO.,LTD + +OUI:000DE7* + ID_OUI_FROM_DATABASE=Snap-on OEM Group + +OUI:000DE8* + ID_OUI_FROM_DATABASE=Nasaco Electronics Pte. Ltd + +OUI:000DE9* + ID_OUI_FROM_DATABASE=Napatech Aps + +OUI:000DEA* + ID_OUI_FROM_DATABASE=Kingtel Telecommunication Corp. + +OUI:000DEB* + ID_OUI_FROM_DATABASE=CompXs Limited + +OUI:000DEC* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000DED* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000DEE* + ID_OUI_FROM_DATABASE=Andrew RF Power Amplifier Group + +OUI:000DEF* + ID_OUI_FROM_DATABASE=Soc. Coop. Bilanciai + +OUI:000DF0* + ID_OUI_FROM_DATABASE=QCOM TECHNOLOGY INC. + +OUI:000DF1* + ID_OUI_FROM_DATABASE=IONIX INC. + +OUI:000DF3* + ID_OUI_FROM_DATABASE=Asmax Solutions + +OUI:000DF4* + ID_OUI_FROM_DATABASE=Watertek Co. + +OUI:000DF5* + ID_OUI_FROM_DATABASE=Teletronics International Inc. + +OUI:000DF6* + ID_OUI_FROM_DATABASE=Technology Thesaurus Corp. + +OUI:000DF7* + ID_OUI_FROM_DATABASE=Space Dynamics Lab + +OUI:000DF8* + ID_OUI_FROM_DATABASE=ORGA Kartensysteme GmbH + +OUI:000DF9* + ID_OUI_FROM_DATABASE=NDS Limited + +OUI:000DFA* + ID_OUI_FROM_DATABASE=Micro Control Systems Ltd. + +OUI:000DFB* + ID_OUI_FROM_DATABASE=Komax AG + +OUI:000DFC* + ID_OUI_FROM_DATABASE=ITFOR Inc. + +OUI:000DFD* + ID_OUI_FROM_DATABASE=Huges Hi-Tech Inc., + +OUI:000DFE* + ID_OUI_FROM_DATABASE=Hauppauge Computer Works, Inc. + +OUI:000DFF* + ID_OUI_FROM_DATABASE=CHENMING MOLD INDUSTRY CORP. + +OUI:000E00* + ID_OUI_FROM_DATABASE=Atrie + +OUI:000E01* + ID_OUI_FROM_DATABASE=ASIP Technologies Inc. + +OUI:000E02* + ID_OUI_FROM_DATABASE=Advantech AMT Inc. + +OUI:000E03* + ID_OUI_FROM_DATABASE=Emulex + +OUI:000E04* + ID_OUI_FROM_DATABASE=CMA/Microdialysis AB + +OUI:000E05* + ID_OUI_FROM_DATABASE=WIRELESS MATRIX CORP. + +OUI:000E06* + ID_OUI_FROM_DATABASE=Team Simoco Ltd + +OUI:000E07* + ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications AB + +OUI:000E08* + ID_OUI_FROM_DATABASE=Cisco Linksys LLC + +OUI:000E09* + ID_OUI_FROM_DATABASE=Shenzhen Coship Software Co.,LTD. + +OUI:000E0A* + ID_OUI_FROM_DATABASE=SAKUMA DESIGN OFFICE + +OUI:000E0B* + ID_OUI_FROM_DATABASE=Netac Technology Co., Ltd. + +OUI:000E0C* + ID_OUI_FROM_DATABASE=Intel Corporation + +OUI:000E0D* + ID_OUI_FROM_DATABASE=Hesch Schröder GmbH + +OUI:000E0E* + ID_OUI_FROM_DATABASE=ESA elettronica S.P.A. + +OUI:000E0F* + ID_OUI_FROM_DATABASE=ERMME + +OUI:000E10* + ID_OUI_FROM_DATABASE=C-guys, Inc. + +OUI:000E11* + ID_OUI_FROM_DATABASE=BDT Büro und Datentechnik GmbH & Co.KG + +OUI:000E12* + ID_OUI_FROM_DATABASE=Adaptive Micro Systems Inc. + +OUI:000E13* + ID_OUI_FROM_DATABASE=Accu-Sort Systems inc. + +OUI:000E14* + ID_OUI_FROM_DATABASE=Visionary Solutions, Inc. + +OUI:000E15* + ID_OUI_FROM_DATABASE=Tadlys LTD + +OUI:000E16* + ID_OUI_FROM_DATABASE=SouthWing S.L. + +OUI:000E18* + ID_OUI_FROM_DATABASE=MyA Technology + +OUI:000E19* + ID_OUI_FROM_DATABASE=LogicaCMG Pty Ltd + +OUI:000E1A* + ID_OUI_FROM_DATABASE=JPS Communications + +OUI:000E1B* + ID_OUI_FROM_DATABASE=IAV GmbH + +OUI:000E1C* + ID_OUI_FROM_DATABASE=Hach Company + +OUI:000E1D* + ID_OUI_FROM_DATABASE=ARION Technology Inc. + +OUI:000E1E* + ID_OUI_FROM_DATABASE=QLogic Corporation + +OUI:000E1F* + ID_OUI_FROM_DATABASE=TCL Networks Equipment Co., Ltd. + +OUI:000E20* + ID_OUI_FROM_DATABASE=ACCESS Systems Americas, Inc. + +OUI:000E21* + ID_OUI_FROM_DATABASE=MTU Friedrichshafen GmbH + +OUI:000E23* + ID_OUI_FROM_DATABASE=Incipient, Inc. + +OUI:000E24* + ID_OUI_FROM_DATABASE=Huwell Technology Inc. + +OUI:000E25* + ID_OUI_FROM_DATABASE=Hannae Technology Co., Ltd + +OUI:000E26* + ID_OUI_FROM_DATABASE=Gincom Technology Corp. + +OUI:000E27* + ID_OUI_FROM_DATABASE=Crere Networks, Inc. + +OUI:000E28* + ID_OUI_FROM_DATABASE=Dynamic Ratings P/L + +OUI:000E29* + ID_OUI_FROM_DATABASE=Shester Communications Inc + +OUI:000E2B* + ID_OUI_FROM_DATABASE=Safari Technologies + +OUI:000E2C* + ID_OUI_FROM_DATABASE=Netcodec co. + +OUI:000E2D* + ID_OUI_FROM_DATABASE=Hyundai Digital Technology Co.,Ltd. + +OUI:000E2E* + ID_OUI_FROM_DATABASE=Edimax Technology Co., Ltd. + +OUI:000E2F* + ID_OUI_FROM_DATABASE=Disetronic Medical Systems AG + +OUI:000E30* + ID_OUI_FROM_DATABASE=AERAS Networks, Inc. + +OUI:000E31* + ID_OUI_FROM_DATABASE=Olympus Soft Imaging Solutions GmbH + +OUI:000E32* + ID_OUI_FROM_DATABASE=Kontron Medical + +OUI:000E33* + ID_OUI_FROM_DATABASE=Shuko Electronics Co.,Ltd + +OUI:000E34* + ID_OUI_FROM_DATABASE=NexGen City, LP + +OUI:000E35* + ID_OUI_FROM_DATABASE=Intel Corp + +OUI:000E36* + ID_OUI_FROM_DATABASE=HEINESYS, Inc. + +OUI:000E37* + ID_OUI_FROM_DATABASE=Harms & Wende GmbH & Co.KG + +OUI:000E38* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000E39* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000E3A* + ID_OUI_FROM_DATABASE=Cirrus Logic + +OUI:000E3B* + ID_OUI_FROM_DATABASE=Hawking Technologies, Inc. + +OUI:000E3C* + ID_OUI_FROM_DATABASE=Transact Technologies Inc + +OUI:000E3D* + ID_OUI_FROM_DATABASE=Televic N.V. + +OUI:000E3E* + ID_OUI_FROM_DATABASE=Sun Optronics Inc + +OUI:000E3F* + ID_OUI_FROM_DATABASE=Soronti, Inc. + +OUI:000E40* + ID_OUI_FROM_DATABASE=Nortel Networks + +OUI:000E41* + ID_OUI_FROM_DATABASE=NIHON MECHATRONICS CO.,LTD. + +OUI:000E42* + ID_OUI_FROM_DATABASE=Motic Incoporation Ltd. + +OUI:000E43* + ID_OUI_FROM_DATABASE=G-Tek Electronics Sdn. Bhd. + +OUI:000E44* + ID_OUI_FROM_DATABASE=Digital 5, Inc. + +OUI:000E45* + ID_OUI_FROM_DATABASE=Beijing Newtry Electronic Technology Ltd + +OUI:000E46* + ID_OUI_FROM_DATABASE=Niigata Seimitsu Co.,Ltd. + +OUI:000E47* + ID_OUI_FROM_DATABASE=NCI System Co.,Ltd. + +OUI:000E48* + ID_OUI_FROM_DATABASE=Lipman TransAction Solutions + +OUI:000E49* + ID_OUI_FROM_DATABASE=Forsway Scandinavia AB + +OUI:000E4A* + ID_OUI_FROM_DATABASE=Changchun Huayu WEBPAD Co.,LTD + +OUI:000E4B* + ID_OUI_FROM_DATABASE=atrium c and i + +OUI:000E4C* + ID_OUI_FROM_DATABASE=Bermai Inc. + +OUI:000E4D* + ID_OUI_FROM_DATABASE=Numesa Inc. + +OUI:000E4E* + ID_OUI_FROM_DATABASE=Waveplus Technology Co., Ltd. + +OUI:000E4F* + ID_OUI_FROM_DATABASE=Trajet GmbH + +OUI:000E50* + ID_OUI_FROM_DATABASE=Thomson Telecom Belgium + +OUI:000E51* + ID_OUI_FROM_DATABASE=tecna elettronica srl + +OUI:000E52* + ID_OUI_FROM_DATABASE=Optium Corporation + +OUI:000E53* + ID_OUI_FROM_DATABASE=AV TECH CORPORATION + +OUI:000E54* + ID_OUI_FROM_DATABASE=AlphaCell Wireless Ltd. + +OUI:000E55* + ID_OUI_FROM_DATABASE=AUVITRAN + +OUI:000E56* + ID_OUI_FROM_DATABASE=4G Systems GmbH & Co. KG + +OUI:000E57* + ID_OUI_FROM_DATABASE=Iworld Networking, Inc. + +OUI:000E58* + ID_OUI_FROM_DATABASE=Sonos, Inc. + +OUI:000E59* + ID_OUI_FROM_DATABASE=SAGEM SA + +OUI:000E5A* + ID_OUI_FROM_DATABASE=TELEFIELD inc. + +OUI:000E5B* + ID_OUI_FROM_DATABASE=ParkerVision - Direct2Data + +OUI:000E5C* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:000E5D* + ID_OUI_FROM_DATABASE=Triple Play Technologies A/S + +OUI:000E5E* + ID_OUI_FROM_DATABASE=Raisecom Technology + +OUI:000E5F* + ID_OUI_FROM_DATABASE=activ-net GmbH & Co. KG + +OUI:000E60* + ID_OUI_FROM_DATABASE=360SUN Digital Broadband Corporation + +OUI:000E61* + ID_OUI_FROM_DATABASE=MICROTROL LIMITED + +OUI:000E62* + ID_OUI_FROM_DATABASE=Nortel Networks + +OUI:000E63* + ID_OUI_FROM_DATABASE=Lemke Diagnostics GmbH + +OUI:000E64* + ID_OUI_FROM_DATABASE=Elphel, Inc + +OUI:000E65* + ID_OUI_FROM_DATABASE=TransCore + +OUI:000E66* + ID_OUI_FROM_DATABASE=Hitachi Advanced Digital, Inc. + +OUI:000E67* + ID_OUI_FROM_DATABASE=Eltis Microelectronics Ltd. + +OUI:000E68* + ID_OUI_FROM_DATABASE=E-TOP Network Technology Inc. + +OUI:000E69* + ID_OUI_FROM_DATABASE=China Electric Power Research Institute + +OUI:000E6A* + ID_OUI_FROM_DATABASE=3Com Ltd + +OUI:000E6B* + ID_OUI_FROM_DATABASE=Janitza electronics GmbH + +OUI:000E6C* + ID_OUI_FROM_DATABASE=Device Drivers Limited + +OUI:000E6D* + ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd. + +OUI:000E6E* + ID_OUI_FROM_DATABASE=MICRELEC ELECTRONICS S.A + +OUI:000E6F* + ID_OUI_FROM_DATABASE=IRIS Corporation Berhad + +OUI:000E70* + ID_OUI_FROM_DATABASE=in2 Networks + +OUI:000E71* + ID_OUI_FROM_DATABASE=Gemstar Technology Development Ltd. + +OUI:000E72* + ID_OUI_FROM_DATABASE=CTS electronics + +OUI:000E73* + ID_OUI_FROM_DATABASE=Tpack A/S + +OUI:000E74* + ID_OUI_FROM_DATABASE=Solar Telecom. Tech + +OUI:000E75* + ID_OUI_FROM_DATABASE=New York Air Brake Corp. + +OUI:000E76* + ID_OUI_FROM_DATABASE=GEMSOC INNOVISION INC. + +OUI:000E77* + ID_OUI_FROM_DATABASE=Decru, Inc. + +OUI:000E78* + ID_OUI_FROM_DATABASE=Amtelco + +OUI:000E79* + ID_OUI_FROM_DATABASE=Ample Communications Inc. + +OUI:000E7A* + ID_OUI_FROM_DATABASE=GemWon Communications Co., Ltd. + +OUI:000E7B* + ID_OUI_FROM_DATABASE=Toshiba + +OUI:000E7C* + ID_OUI_FROM_DATABASE=Televes S.A. + +OUI:000E7D* + ID_OUI_FROM_DATABASE=Electronics Line 3000 Ltd. + +OUI:000E7E* + ID_OUI_FROM_DATABASE=ionSign Oy + +OUI:000E7F* + ID_OUI_FROM_DATABASE=Hewlett-Packard Company + +OUI:000E80* + ID_OUI_FROM_DATABASE=Thomson Technology Inc + +OUI:000E81* + ID_OUI_FROM_DATABASE=Devicescape Software, Inc. + +OUI:000E82* + ID_OUI_FROM_DATABASE=Commtech Wireless + +OUI:000E83* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000E84* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000E85* + ID_OUI_FROM_DATABASE=Catalyst Enterprises, Inc. + +OUI:000E86* + ID_OUI_FROM_DATABASE=Alcatel North America + +OUI:000E87* + ID_OUI_FROM_DATABASE=adp Gauselmann GmbH + +OUI:000E88* + ID_OUI_FROM_DATABASE=VIDEOTRON CORP. + +OUI:000E89* + ID_OUI_FROM_DATABASE=CLEMATIC + +OUI:000E8A* + ID_OUI_FROM_DATABASE=Avara Technologies Pty. Ltd. + +OUI:000E8B* + ID_OUI_FROM_DATABASE=Astarte Technology Co, Ltd. + +OUI:000E8C* + ID_OUI_FROM_DATABASE=Siemens AG A&D ET + +OUI:000E8D* + ID_OUI_FROM_DATABASE=Systems in Progress Holding GmbH + +OUI:000E8E* + ID_OUI_FROM_DATABASE=SparkLAN Communications, Inc. + +OUI:000E8F* + ID_OUI_FROM_DATABASE=Sercomm Corp. + +OUI:000E90* + ID_OUI_FROM_DATABASE=PONICO CORP. + +OUI:000E91* + ID_OUI_FROM_DATABASE=Navico Auckland Ltd + +OUI:000E92* + ID_OUI_FROM_DATABASE=Millinet Co., Ltd. + +OUI:000E93* + ID_OUI_FROM_DATABASE=Milénio 3 Sistemas Electrónicos, Lda. + +OUI:000E94* + ID_OUI_FROM_DATABASE=Maas International BV + +OUI:000E95* + ID_OUI_FROM_DATABASE=Fujiya Denki Seisakusho Co.,Ltd. + +OUI:000E96* + ID_OUI_FROM_DATABASE=Cubic Defense Applications, Inc. + +OUI:000E97* + ID_OUI_FROM_DATABASE=Ultracker Technology CO., Inc + +OUI:000E98* + ID_OUI_FROM_DATABASE=HME Clear-Com LTD. + +OUI:000E99* + ID_OUI_FROM_DATABASE=Spectrum Digital, Inc + +OUI:000E9A* + ID_OUI_FROM_DATABASE=BOE TECHNOLOGY GROUP CO.,LTD + +OUI:000E9B* + ID_OUI_FROM_DATABASE=Ambit Microsystems Corporation + +OUI:000E9C* + ID_OUI_FROM_DATABASE=Pemstar + +OUI:000E9D* + ID_OUI_FROM_DATABASE=Tiscali UK Ltd + +OUI:000E9E* + ID_OUI_FROM_DATABASE=Topfield Co., Ltd + +OUI:000E9F* + ID_OUI_FROM_DATABASE=TEMIC SDS GmbH + +OUI:000EA0* + ID_OUI_FROM_DATABASE=NetKlass Technology Inc. + +OUI:000EA1* + ID_OUI_FROM_DATABASE=Formosa Teletek Corporation + +OUI:000EA2* + ID_OUI_FROM_DATABASE=McAfee, Inc + +OUI:000EA3* + ID_OUI_FROM_DATABASE=CNCR-IT CO.,LTD,HangZhou P.R.CHINA + +OUI:000EA4* + ID_OUI_FROM_DATABASE=Certance Inc. + +OUI:000EA5* + ID_OUI_FROM_DATABASE=BLIP Systems + +OUI:000EA6* + ID_OUI_FROM_DATABASE=ASUSTEK COMPUTER INC. + +OUI:000EA7* + ID_OUI_FROM_DATABASE=Endace Technology + +OUI:000EA8* + ID_OUI_FROM_DATABASE=United Technologists Europe Limited + +OUI:000EA9* + ID_OUI_FROM_DATABASE=Shanghai Xun Shi Communications Equipment Ltd. Co. + +OUI:000EAA* + ID_OUI_FROM_DATABASE=Scalent Systems, Inc. + +OUI:000EAB* + ID_OUI_FROM_DATABASE=Cray Inc + +OUI:000EAC* + ID_OUI_FROM_DATABASE=MINTRON ENTERPRISE CO., LTD. + +OUI:000EAD* + ID_OUI_FROM_DATABASE=Metanoia Technologies, Inc. + +OUI:000EAE* + ID_OUI_FROM_DATABASE=GAWELL TECHNOLOGIES CORP. + +OUI:000EAF* + ID_OUI_FROM_DATABASE=CASTEL + +OUI:000EB0* + ID_OUI_FROM_DATABASE=Solutions Radio BV + +OUI:000EB1* + ID_OUI_FROM_DATABASE=Newcotech,Ltd + +OUI:000EB2* + ID_OUI_FROM_DATABASE=Micro-Research Finland Oy + +OUI:000EB3* + ID_OUI_FROM_DATABASE=Hewlett-Packard + +OUI:000EB4* + ID_OUI_FROM_DATABASE=GUANGZHOU GAOKE COMMUNICATIONS TECHNOLOGY CO.LTD. + +OUI:000EB5* + ID_OUI_FROM_DATABASE=Ecastle Electronics Co., Ltd. + +OUI:000EB6* + ID_OUI_FROM_DATABASE=Riverbed Technology, Inc. + +OUI:000EB7* + ID_OUI_FROM_DATABASE=Knovative, Inc. + +OUI:000EB8* + ID_OUI_FROM_DATABASE=Iiga co.,Ltd + +OUI:000EB9* + ID_OUI_FROM_DATABASE=HASHIMOTO Electronics Industry Co.,Ltd. + +OUI:000EBA* + ID_OUI_FROM_DATABASE=HANMI SEMICONDUCTOR CO., LTD. + +OUI:000EBB* + ID_OUI_FROM_DATABASE=Everbee Networks + +OUI:000EBC* + ID_OUI_FROM_DATABASE=Paragon Fidelity GmbH + +OUI:000EBD* + ID_OUI_FROM_DATABASE=Burdick, a Quinton Compny + +OUI:000EBE* + ID_OUI_FROM_DATABASE=B&B Electronics Manufacturing Co. + +OUI:000EBF* + ID_OUI_FROM_DATABASE=Remsdaq Limited + +OUI:000EC0* + ID_OUI_FROM_DATABASE=Nortel Networks + +OUI:000EC1* + ID_OUI_FROM_DATABASE=MYNAH Technologies + +OUI:000EC2* + ID_OUI_FROM_DATABASE=Lowrance Electronics, Inc. + +OUI:000EC3* + ID_OUI_FROM_DATABASE=Logic Controls, Inc. + +OUI:000EC4* + ID_OUI_FROM_DATABASE=Iskra Transmission d.d. + +OUI:000EC5* + ID_OUI_FROM_DATABASE=Digital Multitools Inc + +OUI:000EC6* + ID_OUI_FROM_DATABASE=ASIX ELECTRONICS CORP. + +OUI:000EC7* + ID_OUI_FROM_DATABASE=Motorola Korea + +OUI:000EC8* + ID_OUI_FROM_DATABASE=Zoran Corporation + +OUI:000EC9* + ID_OUI_FROM_DATABASE=YOKO Technology Corp. + +OUI:000ECA* + ID_OUI_FROM_DATABASE=WTSS Inc + +OUI:000ECB* + ID_OUI_FROM_DATABASE=VineSys Technology + +OUI:000ECC* + ID_OUI_FROM_DATABASE=Tableau, LLC + +OUI:000ECD* + ID_OUI_FROM_DATABASE=SKOV A/S + +OUI:000ECE* + ID_OUI_FROM_DATABASE=S.I.T.T.I. S.p.A. + +OUI:000ECF* + ID_OUI_FROM_DATABASE=PROFIBUS Nutzerorganisation e.V. + +OUI:000ED0* + ID_OUI_FROM_DATABASE=Privaris, Inc. + +OUI:000ED1* + ID_OUI_FROM_DATABASE=Osaka Micro Computer. + +OUI:000ED2* + ID_OUI_FROM_DATABASE=Filtronic plc + +OUI:000ED3* + ID_OUI_FROM_DATABASE=Epicenter, Inc. + +OUI:000ED4* + ID_OUI_FROM_DATABASE=CRESITT INDUSTRIE + +OUI:000ED5* + ID_OUI_FROM_DATABASE=COPAN Systems Inc. + +OUI:000ED6* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000ED7* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000ED8* + ID_OUI_FROM_DATABASE=Aktino, Inc. + +OUI:000ED9* + ID_OUI_FROM_DATABASE=Aksys, Ltd. + +OUI:000EDA* + ID_OUI_FROM_DATABASE=C-TECH UNITED CORP. + +OUI:000EDB* + ID_OUI_FROM_DATABASE=XiNCOM Corp. + +OUI:000EDC* + ID_OUI_FROM_DATABASE=Tellion INC. + +OUI:000EDD* + ID_OUI_FROM_DATABASE=SHURE INCORPORATED + +OUI:000EDE* + ID_OUI_FROM_DATABASE=REMEC, Inc. + +OUI:000EDF* + ID_OUI_FROM_DATABASE=PLX Technology + +OUI:000EE0* + ID_OUI_FROM_DATABASE=Mcharge + +OUI:000EE1* + ID_OUI_FROM_DATABASE=ExtremeSpeed Inc. + +OUI:000EE2* + ID_OUI_FROM_DATABASE=Custom Engineering S.p.A. + +OUI:000EE3* + ID_OUI_FROM_DATABASE=Chiyu Technology Co.,Ltd + +OUI:000EE4* + ID_OUI_FROM_DATABASE=BOE TECHNOLOGY GROUP CO.,LTD + +OUI:000EE5* + ID_OUI_FROM_DATABASE=bitWallet, Inc. + +OUI:000EE6* + ID_OUI_FROM_DATABASE=Adimos Systems LTD + +OUI:000EE7* + ID_OUI_FROM_DATABASE=AAC ELECTRONICS CORP. + +OUI:000EE8* + ID_OUI_FROM_DATABASE=zioncom + +OUI:000EE9* + ID_OUI_FROM_DATABASE=WayTech Development, Inc. + +OUI:000EEA* + ID_OUI_FROM_DATABASE=Shadong Luneng Jicheng Electronics,Co.,Ltd + +OUI:000EEB* + ID_OUI_FROM_DATABASE=Sandmartin(zhong shan)Electronics Co.,Ltd + +OUI:000EEC* + ID_OUI_FROM_DATABASE=Orban + +OUI:000EED* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:000EEE* + ID_OUI_FROM_DATABASE=Muco Industrie BV + +OUI:000EF0* + ID_OUI_FROM_DATABASE=Festo AG & Co. KG + +OUI:000EF1* + ID_OUI_FROM_DATABASE=EZQUEST INC. + +OUI:000EF2* + ID_OUI_FROM_DATABASE=Infinico Corporation + +OUI:000EF3* + ID_OUI_FROM_DATABASE=Smarthome + +OUI:000EF4* + ID_OUI_FROM_DATABASE=Kasda Digital Technology Co.,Ltd + +OUI:000EF5* + ID_OUI_FROM_DATABASE=iPAC Technology Co., Ltd. + +OUI:000EF6* + ID_OUI_FROM_DATABASE=E-TEN Information Systems Co., Ltd. + +OUI:000EF7* + ID_OUI_FROM_DATABASE=Vulcan Portals Inc + +OUI:000EF8* + ID_OUI_FROM_DATABASE=SBC ASI + +OUI:000EF9* + ID_OUI_FROM_DATABASE=REA Elektronik GmbH + +OUI:000EFA* + ID_OUI_FROM_DATABASE=Optoway Technology Incorporation + +OUI:000EFB* + ID_OUI_FROM_DATABASE=Macey Enterprises + +OUI:000EFC* + ID_OUI_FROM_DATABASE=JTAG Technologies B.V. + +OUI:000EFD* + ID_OUI_FROM_DATABASE=FUJINON CORPORATION + +OUI:000EFE* + ID_OUI_FROM_DATABASE=EndRun Technologies LLC + +OUI:000EFF* + ID_OUI_FROM_DATABASE=Megasolution,Inc. + +OUI:000F00* + ID_OUI_FROM_DATABASE=Legra Systems, Inc. + +OUI:000F01* + ID_OUI_FROM_DATABASE=DIGITALKS INC + +OUI:000F02* + ID_OUI_FROM_DATABASE=Digicube Technology Co., Ltd + +OUI:000F03* + ID_OUI_FROM_DATABASE=COM&C CO., LTD + +OUI:000F04* + ID_OUI_FROM_DATABASE=cim-usa inc + +OUI:000F05* + ID_OUI_FROM_DATABASE=3B SYSTEM INC. + +OUI:000F06* + ID_OUI_FROM_DATABASE=Nortel Networks + +OUI:000F07* + ID_OUI_FROM_DATABASE=Mangrove Systems, Inc. + +OUI:000F08* + ID_OUI_FROM_DATABASE=Indagon Oy + +OUI:000F0A* + ID_OUI_FROM_DATABASE=Clear Edge Networks + +OUI:000F0B* + ID_OUI_FROM_DATABASE=Kentima Technologies AB + +OUI:000F0C* + ID_OUI_FROM_DATABASE=SYNCHRONIC ENGINEERING + +OUI:000F0D* + ID_OUI_FROM_DATABASE=Hunt Electronic Co., Ltd. + +OUI:000F0E* + ID_OUI_FROM_DATABASE=WaveSplitter Technologies, Inc. + +OUI:000F0F* + ID_OUI_FROM_DATABASE=Real ID Technology Co., Ltd. + +OUI:000F10* + ID_OUI_FROM_DATABASE=RDM Corporation + +OUI:000F11* + ID_OUI_FROM_DATABASE=Prodrive B.V. + +OUI:000F12* + ID_OUI_FROM_DATABASE=Panasonic Europe Ltd. + +OUI:000F13* + ID_OUI_FROM_DATABASE=Nisca corporation + +OUI:000F14* + ID_OUI_FROM_DATABASE=Mindray Co., Ltd. + +OUI:000F15* + ID_OUI_FROM_DATABASE=Kjaerulff1 A/S + +OUI:000F16* + ID_OUI_FROM_DATABASE=JAY HOW TECHNOLOGY CO., + +OUI:000F17* + ID_OUI_FROM_DATABASE=Insta Elektro GmbH + +OUI:000F18* + ID_OUI_FROM_DATABASE=Industrial Control Systems + +OUI:000F19* + ID_OUI_FROM_DATABASE=Boston Scientific + +OUI:000F1A* + ID_OUI_FROM_DATABASE=Gaming Support B.V. + +OUI:000F1B* + ID_OUI_FROM_DATABASE=Ego Systems Inc. + +OUI:000F1C* + ID_OUI_FROM_DATABASE=DigitAll World Co., Ltd + +OUI:000F1D* + ID_OUI_FROM_DATABASE=Cosmo Techs Co., Ltd. + +OUI:000F1E* + ID_OUI_FROM_DATABASE=Chengdu KT Electric Co.of High & New Technology + +OUI:000F1F* + ID_OUI_FROM_DATABASE=WW PCBA Test + +OUI:000F20* + ID_OUI_FROM_DATABASE=Hewlett-Packard Company + +OUI:000F21* + ID_OUI_FROM_DATABASE=Scientific Atlanta, Inc + +OUI:000F22* + ID_OUI_FROM_DATABASE=Helius, Inc. + +OUI:000F23* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000F24* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000F25* + ID_OUI_FROM_DATABASE=AimValley B.V. + +OUI:000F26* + ID_OUI_FROM_DATABASE=WorldAccxx LLC + +OUI:000F27* + ID_OUI_FROM_DATABASE=TEAL Electronics, Inc. + +OUI:000F28* + ID_OUI_FROM_DATABASE=Itronix Corporation + +OUI:000F29* + ID_OUI_FROM_DATABASE=Augmentix Corporation + +OUI:000F2A* + ID_OUI_FROM_DATABASE=Cableware Electronics + +OUI:000F2B* + ID_OUI_FROM_DATABASE=GREENBELL SYSTEMS + +OUI:000F2C* + ID_OUI_FROM_DATABASE=Uplogix, Inc. + +OUI:000F2D* + ID_OUI_FROM_DATABASE=CHUNG-HSIN ELECTRIC & MACHINERY MFG.CORP. + +OUI:000F2E* + ID_OUI_FROM_DATABASE=Megapower International Corp. + +OUI:000F2F* + ID_OUI_FROM_DATABASE=W-LINX TECHNOLOGY CO., LTD. + +OUI:000F30* + ID_OUI_FROM_DATABASE=Raza Microelectronics Inc + +OUI:000F31* + ID_OUI_FROM_DATABASE=Allied Vision Technologies Canada Inc + +OUI:000F32* + ID_OUI_FROM_DATABASE=Lootom Optoelectronic Technology (Wuxi) Co Ltd + +OUI:000F33* + ID_OUI_FROM_DATABASE=DUALi Inc. + +OUI:000F34* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000F35* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000F36* + ID_OUI_FROM_DATABASE=Accurate Techhnologies, Inc. + +OUI:000F37* + ID_OUI_FROM_DATABASE=Xambala Incorporated + +OUI:000F38* + ID_OUI_FROM_DATABASE=Netstar + +OUI:000F39* + ID_OUI_FROM_DATABASE=IRIS SENSORS + +OUI:000F3A* + ID_OUI_FROM_DATABASE=HISHARP + +OUI:000F3B* + ID_OUI_FROM_DATABASE=Fuji System Machines Co., Ltd. + +OUI:000F3C* + ID_OUI_FROM_DATABASE=Endeleo Limited + +OUI:000F3D* + ID_OUI_FROM_DATABASE=D-Link Corporation + +OUI:000F3E* + ID_OUI_FROM_DATABASE=CardioNet, Inc + +OUI:000F3F* + ID_OUI_FROM_DATABASE=Big Bear Networks + +OUI:000F40* + ID_OUI_FROM_DATABASE=Optical Internetworking Forum + +OUI:000F41* + ID_OUI_FROM_DATABASE=Zipher Ltd + +OUI:000F42* + ID_OUI_FROM_DATABASE=Xalyo Systems + +OUI:000F43* + ID_OUI_FROM_DATABASE=Wasabi Systems Inc. + +OUI:000F44* + ID_OUI_FROM_DATABASE=Tivella Inc. + +OUI:000F45* + ID_OUI_FROM_DATABASE=Stretch, Inc. + +OUI:000F46* + ID_OUI_FROM_DATABASE=SINAR AG + +OUI:000F47* + ID_OUI_FROM_DATABASE=ROBOX SPA + +OUI:000F48* + ID_OUI_FROM_DATABASE=Polypix Inc. + +OUI:000F49* + ID_OUI_FROM_DATABASE=Northover Solutions Limited + +OUI:000F4A* + ID_OUI_FROM_DATABASE=Kyushu-kyohan co.,ltd + +OUI:000F4B* + ID_OUI_FROM_DATABASE=Oracle Corporation + +OUI:000F4C* + ID_OUI_FROM_DATABASE=Elextech INC + +OUI:000F4D* + ID_OUI_FROM_DATABASE=TalkSwitch + +OUI:000F4E* + ID_OUI_FROM_DATABASE=Cellink + +OUI:000F4F* + ID_OUI_FROM_DATABASE=Cadmus Technology Ltd + +OUI:000F50* + ID_OUI_FROM_DATABASE=StreamScale Limited + +OUI:000F51* + ID_OUI_FROM_DATABASE=Azul Systems, Inc. + +OUI:000F52* + ID_OUI_FROM_DATABASE=YORK Refrigeration, Marine & Controls + +OUI:000F53* + ID_OUI_FROM_DATABASE=Solarflare Communications Inc + +OUI:000F54* + ID_OUI_FROM_DATABASE=Entrelogic Corporation + +OUI:000F55* + ID_OUI_FROM_DATABASE=Datawire Communication Networks Inc. + +OUI:000F56* + ID_OUI_FROM_DATABASE=Continuum Photonics Inc + +OUI:000F57* + ID_OUI_FROM_DATABASE=CABLELOGIC Co., Ltd. + +OUI:000F58* + ID_OUI_FROM_DATABASE=Adder Technology Limited + +OUI:000F59* + ID_OUI_FROM_DATABASE=Phonak Communications AG + +OUI:000F5A* + ID_OUI_FROM_DATABASE=Peribit Networks + +OUI:000F5B* + ID_OUI_FROM_DATABASE=Delta Information Systems, Inc. + +OUI:000F5C* + ID_OUI_FROM_DATABASE=Day One Digital Media Limited + +OUI:000F5D* + ID_OUI_FROM_DATABASE=PacketFront International AB + +OUI:000F5E* + ID_OUI_FROM_DATABASE=Veo + +OUI:000F5F* + ID_OUI_FROM_DATABASE=Nicety Technologies Inc. (NTS) + +OUI:000F60* + ID_OUI_FROM_DATABASE=Lifetron Co.,Ltd + +OUI:000F61* + ID_OUI_FROM_DATABASE=Hewlett-Packard Company + +OUI:000F62* + ID_OUI_FROM_DATABASE=Alcatel Bell Space N.V. + +OUI:000F63* + ID_OUI_FROM_DATABASE=Obzerv Technologies + +OUI:000F64* + ID_OUI_FROM_DATABASE=D&R Electronica Weesp BV + +OUI:000F65* + ID_OUI_FROM_DATABASE=icube Corp. + +OUI:000F66* + ID_OUI_FROM_DATABASE=Cisco-Linksys + +OUI:000F67* + ID_OUI_FROM_DATABASE=West Instruments + +OUI:000F68* + ID_OUI_FROM_DATABASE=Vavic Network Technology, Inc. + +OUI:000F69* + ID_OUI_FROM_DATABASE=SEW Eurodrive GmbH & Co. KG + +OUI:000F6A* + ID_OUI_FROM_DATABASE=Nortel Networks + +OUI:000F6B* + ID_OUI_FROM_DATABASE=GateWare Communications GmbH + +OUI:000F6C* + ID_OUI_FROM_DATABASE=ADDI-DATA GmbH + +OUI:000F6D* + ID_OUI_FROM_DATABASE=Midas Engineering + +OUI:000F6E* + ID_OUI_FROM_DATABASE=BBox + +OUI:000F6F* + ID_OUI_FROM_DATABASE=FTA Communication Technologies + +OUI:000F70* + ID_OUI_FROM_DATABASE=Wintec Industries, inc. + +OUI:000F71* + ID_OUI_FROM_DATABASE=Sanmei Electronics Co.,Ltd + +OUI:000F72* + ID_OUI_FROM_DATABASE=Sandburst + +OUI:000F73* + ID_OUI_FROM_DATABASE=RS Automation Co., Ltd + +OUI:000F74* + ID_OUI_FROM_DATABASE=Qamcom Technology AB + +OUI:000F75* + ID_OUI_FROM_DATABASE=First Silicon Solutions + +OUI:000F76* + ID_OUI_FROM_DATABASE=Digital Keystone, Inc. + +OUI:000F77* + ID_OUI_FROM_DATABASE=DENTUM CO.,LTD + +OUI:000F78* + ID_OUI_FROM_DATABASE=Datacap Systems Inc + +OUI:000F79* + ID_OUI_FROM_DATABASE=Bluetooth Interest Group Inc. + +OUI:000F7A* + ID_OUI_FROM_DATABASE=BeiJing NuQX Technology CO.,LTD + +OUI:000F7B* + ID_OUI_FROM_DATABASE=Arce Sistemas, S.A. + +OUI:000F7C* + ID_OUI_FROM_DATABASE=ACTi Corporation + +OUI:000F7D* + ID_OUI_FROM_DATABASE=Xirrus + +OUI:000F7E* + ID_OUI_FROM_DATABASE=Ablerex Electronics Co., LTD + +OUI:000F7F* + ID_OUI_FROM_DATABASE=UBSTORAGE Co.,Ltd. + +OUI:000F80* + ID_OUI_FROM_DATABASE=Trinity Security Systems,Inc. + +OUI:000F81* + ID_OUI_FROM_DATABASE=Secure Info Imaging + +OUI:000F82* + ID_OUI_FROM_DATABASE=Mortara Instrument, Inc. + +OUI:000F83* + ID_OUI_FROM_DATABASE=Brainium Technologies Inc. + +OUI:000F84* + ID_OUI_FROM_DATABASE=Astute Networks, Inc. + +OUI:000F85* + ID_OUI_FROM_DATABASE=ADDO-Japan Corporation + +OUI:000F86* + ID_OUI_FROM_DATABASE=Research In Motion Limited + +OUI:000F87* + ID_OUI_FROM_DATABASE=Maxcess International + +OUI:000F88* + ID_OUI_FROM_DATABASE=AMETEK, Inc. + +OUI:000F89* + ID_OUI_FROM_DATABASE=Winnertec System Co., Ltd. + +OUI:000F8A* + ID_OUI_FROM_DATABASE=WideView + +OUI:000F8B* + ID_OUI_FROM_DATABASE=Orion MultiSystems Inc + +OUI:000F8C* + ID_OUI_FROM_DATABASE=Gigawavetech Pte Ltd + +OUI:000F8D* + ID_OUI_FROM_DATABASE=FAST TV-Server AG + +OUI:000F8E* + ID_OUI_FROM_DATABASE=DONGYANG TELECOM CO.,LTD. + +OUI:000F8F* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000F90* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000F91* + ID_OUI_FROM_DATABASE=Aerotelecom Co.,Ltd. + +OUI:000F92* + ID_OUI_FROM_DATABASE=Microhard Systems Inc. + +OUI:000F93* + ID_OUI_FROM_DATABASE=Landis+Gyr Ltd. + +OUI:000F94* + ID_OUI_FROM_DATABASE=Genexis + +OUI:000F95* + ID_OUI_FROM_DATABASE=ELECOM Co.,LTD Laneed Division + +OUI:000F96* + ID_OUI_FROM_DATABASE=Telco Systems, Inc. + +OUI:000F97* + ID_OUI_FROM_DATABASE=Avanex Corporation + +OUI:000F98* + ID_OUI_FROM_DATABASE=Avamax Co. Ltd. + +OUI:000F99* + ID_OUI_FROM_DATABASE=APAC opto Electronics Inc. + +OUI:000F9A* + ID_OUI_FROM_DATABASE=Synchrony, Inc. + +OUI:000F9B* + ID_OUI_FROM_DATABASE=Ross Video Limited + +OUI:000F9C* + ID_OUI_FROM_DATABASE=Panduit Corp + +OUI:000F9D* + ID_OUI_FROM_DATABASE=DisplayLink (UK) Ltd + +OUI:000F9E* + ID_OUI_FROM_DATABASE=Murrelektronik GmbH + +OUI:000F9F* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:000FA0* + ID_OUI_FROM_DATABASE=CANON KOREA BUSINESS SOLUTIONS INC. + +OUI:000FA1* + ID_OUI_FROM_DATABASE=Gigabit Systems Inc. + +OUI:000FA2* + ID_OUI_FROM_DATABASE=Digital Path Networks + +OUI:000FA3* + ID_OUI_FROM_DATABASE=Alpha Networks Inc. + +OUI:000FA4* + ID_OUI_FROM_DATABASE=Sprecher Automation GmbH + +OUI:000FA5* + ID_OUI_FROM_DATABASE=BWA Technology GmbH + +OUI:000FA6* + ID_OUI_FROM_DATABASE=S2 Security Corporation + +OUI:000FA7* + ID_OUI_FROM_DATABASE=Raptor Networks Technology + +OUI:000FA8* + ID_OUI_FROM_DATABASE=Photometrics, Inc. + +OUI:000FA9* + ID_OUI_FROM_DATABASE=PC Fabrik + +OUI:000FAA* + ID_OUI_FROM_DATABASE=Nexus Technologies + +OUI:000FAB* + ID_OUI_FROM_DATABASE=Kyushu Electronics Systems Inc. + +OUI:000FAC* + ID_OUI_FROM_DATABASE=IEEE 802.11 + +OUI:000FAD* + ID_OUI_FROM_DATABASE=FMN communications GmbH + +OUI:000FAE* + ID_OUI_FROM_DATABASE=E2O Communications + +OUI:000FAF* + ID_OUI_FROM_DATABASE=Dialog Inc. + +OUI:000FB0* + ID_OUI_FROM_DATABASE=Compal Electronics,INC. + +OUI:000FB1* + ID_OUI_FROM_DATABASE=Cognio Inc. + +OUI:000FB2* + ID_OUI_FROM_DATABASE=Broadband Pacenet (India) Pvt. Ltd. + +OUI:000FB3* + ID_OUI_FROM_DATABASE=Actiontec Electronics, Inc + +OUI:000FB4* + ID_OUI_FROM_DATABASE=Timespace Technology + +OUI:000FB5* + ID_OUI_FROM_DATABASE=NETGEAR Inc + +OUI:000FB6* + ID_OUI_FROM_DATABASE=Europlex Technologies + +OUI:000FB7* + ID_OUI_FROM_DATABASE=Cavium Networks + +OUI:000FB8* + ID_OUI_FROM_DATABASE=CallURL Inc. + +OUI:000FB9* + ID_OUI_FROM_DATABASE=Adaptive Instruments + +OUI:000FBA* + ID_OUI_FROM_DATABASE=Tevebox AB + +OUI:000FBB* + ID_OUI_FROM_DATABASE=Nokia Siemens Networks GmbH & Co. KG + +OUI:000FBC* + ID_OUI_FROM_DATABASE=Onkey Technologies, Inc. + +OUI:000FBD* + ID_OUI_FROM_DATABASE=MRV Communications (Networks) LTD + +OUI:000FBE* + ID_OUI_FROM_DATABASE=e-w/you Inc. + +OUI:000FBF* + ID_OUI_FROM_DATABASE=DGT Sp. z o.o. + +OUI:000FC0* + ID_OUI_FROM_DATABASE=DELCOMp + +OUI:000FC1* + ID_OUI_FROM_DATABASE=WAVE Corporation + +OUI:000FC2* + ID_OUI_FROM_DATABASE=Uniwell Corporation + +OUI:000FC3* + ID_OUI_FROM_DATABASE=PalmPalm Technology, Inc. + +OUI:000FC4* + ID_OUI_FROM_DATABASE=NST co.,LTD. + +OUI:000FC5* + ID_OUI_FROM_DATABASE=KeyMed Ltd + +OUI:000FC6* + ID_OUI_FROM_DATABASE=Eurocom Industries A/S + +OUI:000FC7* + ID_OUI_FROM_DATABASE=Dionica R&D Ltd. + +OUI:000FC8* + ID_OUI_FROM_DATABASE=Chantry Networks + +OUI:000FC9* + ID_OUI_FROM_DATABASE=Allnet GmbH + +OUI:000FCA* + ID_OUI_FROM_DATABASE=A-JIN TECHLINE CO, LTD + +OUI:000FCB* + ID_OUI_FROM_DATABASE=3Com Ltd + +OUI:000FCC* + ID_OUI_FROM_DATABASE=Netopia, Inc. + +OUI:000FCD* + ID_OUI_FROM_DATABASE=Nortel Networks + +OUI:000FCE* + ID_OUI_FROM_DATABASE=Kikusui Electronics Corp. + +OUI:000FCF* + ID_OUI_FROM_DATABASE=Datawind Research + +OUI:000FD0* + ID_OUI_FROM_DATABASE=ASTRI + +OUI:000FD1* + ID_OUI_FROM_DATABASE=Applied Wireless Identifications Group, Inc. + +OUI:000FD2* + ID_OUI_FROM_DATABASE=EWA Technologies, Inc. + +OUI:000FD3* + ID_OUI_FROM_DATABASE=Digium + +OUI:000FD4* + ID_OUI_FROM_DATABASE=Soundcraft + +OUI:000FD5* + ID_OUI_FROM_DATABASE=Schwechat - RISE + +OUI:000FD6* + ID_OUI_FROM_DATABASE=Sarotech Co., Ltd + +OUI:000FD7* + ID_OUI_FROM_DATABASE=Harman Music Group + +OUI:000FD8* + ID_OUI_FROM_DATABASE=Force, Inc. + +OUI:000FD9* + ID_OUI_FROM_DATABASE=FlexDSL Telecommunications AG + +OUI:000FDA* + ID_OUI_FROM_DATABASE=YAZAKI CORPORATION + +OUI:000FDB* + ID_OUI_FROM_DATABASE=Westell Technologies + +OUI:000FDC* + ID_OUI_FROM_DATABASE=Ueda Japan Radio Co., Ltd. + +OUI:000FDD* + ID_OUI_FROM_DATABASE=SORDIN AB + +OUI:000FDE* + ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications AB + +OUI:000FDF* + ID_OUI_FROM_DATABASE=SOLOMON Technology Corp. + +OUI:000FE0* + ID_OUI_FROM_DATABASE=NComputing Co.,Ltd. + +OUI:000FE1* + ID_OUI_FROM_DATABASE=ID DIGITAL CORPORATION + +OUI:000FE2* + ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Ltd. + +OUI:000FE3* + ID_OUI_FROM_DATABASE=Damm Cellular Systems A/S + +OUI:000FE4* + ID_OUI_FROM_DATABASE=Pantech Co.,Ltd + +OUI:000FE5* + ID_OUI_FROM_DATABASE=MERCURY SECURITY CORPORATION + +OUI:000FE6* + ID_OUI_FROM_DATABASE=MBTech Systems, Inc. + +OUI:000FE7* + ID_OUI_FROM_DATABASE=Lutron Electronics Co., Inc. + +OUI:000FE8* + ID_OUI_FROM_DATABASE=Lobos, Inc. + +OUI:000FE9* + ID_OUI_FROM_DATABASE=GW TECHNOLOGIES CO.,LTD. + +OUI:000FEA* + ID_OUI_FROM_DATABASE=Giga-Byte Technology Co.,LTD. + +OUI:000FEB* + ID_OUI_FROM_DATABASE=Cylon Controls + +OUI:000FEC* + ID_OUI_FROM_DATABASE=Arkus Inc. + +OUI:000FED* + ID_OUI_FROM_DATABASE=Anam Electronics Co., Ltd + +OUI:000FEE* + ID_OUI_FROM_DATABASE=XTec, Incorporated + +OUI:000FEF* + ID_OUI_FROM_DATABASE=Thales e-Transactions GmbH + +OUI:000FF0* + ID_OUI_FROM_DATABASE=Sunray Co. Ltd. + +OUI:000FF1* + ID_OUI_FROM_DATABASE=nex-G Systems Pte.Ltd + +OUI:000FF2* + ID_OUI_FROM_DATABASE=Loud Technologies Inc. + +OUI:000FF3* + ID_OUI_FROM_DATABASE=Jung Myoung Communications&Technology + +OUI:000FF4* + ID_OUI_FROM_DATABASE=Guntermann & Drunck GmbH + +OUI:000FF5* + ID_OUI_FROM_DATABASE=GN&S company + +OUI:000FF6* + ID_OUI_FROM_DATABASE=Darfon Electronics Corp. + +OUI:000FF7* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000FF8* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:000FF9* + ID_OUI_FROM_DATABASE=Valcretec, Inc. + +OUI:000FFA* + ID_OUI_FROM_DATABASE=Optinel Systems, Inc. + +OUI:000FFB* + ID_OUI_FROM_DATABASE=Nippon Denso Industry Co., Ltd. + +OUI:000FFC* + ID_OUI_FROM_DATABASE=Merit Li-Lin Ent. + +OUI:000FFD* + ID_OUI_FROM_DATABASE=Glorytek Network Inc. + +OUI:000FFE* + ID_OUI_FROM_DATABASE=G-PRO COMPUTER + +OUI:000FFF* + ID_OUI_FROM_DATABASE=Control4 + +OUI:001000* + ID_OUI_FROM_DATABASE=CABLE TELEVISION LABORATORIES, INC. + +OUI:001001* + ID_OUI_FROM_DATABASE=Citel + +OUI:001002* + ID_OUI_FROM_DATABASE=ACTIA + +OUI:001003* + ID_OUI_FROM_DATABASE=IMATRON, INC. + +OUI:001004* + ID_OUI_FROM_DATABASE=THE BRANTLEY COILE COMPANY,INC + +OUI:001005* + ID_OUI_FROM_DATABASE=UEC COMMERCIAL + +OUI:001006* + ID_OUI_FROM_DATABASE=Thales Contact Solutions Ltd. + +OUI:001007* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001008* + ID_OUI_FROM_DATABASE=VIENNA SYSTEMS CORPORATION + +OUI:001009* + ID_OUI_FROM_DATABASE=HORO QUARTZ + +OUI:00100A* + ID_OUI_FROM_DATABASE=WILLIAMS COMMUNICATIONS GROUP + +OUI:00100B* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00100C* + ID_OUI_FROM_DATABASE=ITO CO., LTD. + +OUI:00100D* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00100E* + ID_OUI_FROM_DATABASE=MICRO LINEAR COPORATION + +OUI:00100F* + ID_OUI_FROM_DATABASE=INDUSTRIAL CPU SYSTEMS + +OUI:001010* + ID_OUI_FROM_DATABASE=INITIO CORPORATION + +OUI:001011* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001012* + ID_OUI_FROM_DATABASE=PROCESSOR SYSTEMS (I) PVT LTD + +OUI:001013* + ID_OUI_FROM_DATABASE=Kontron America, Inc. + +OUI:001014* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001015* + ID_OUI_FROM_DATABASE=OOmon Inc. + +OUI:001016* + ID_OUI_FROM_DATABASE=T.SQWARE + +OUI:001017* + ID_OUI_FROM_DATABASE=Bosch Access Systems GmbH + +OUI:001018* + ID_OUI_FROM_DATABASE=BROADCOM CORPORATION + +OUI:001019* + ID_OUI_FROM_DATABASE=SIRONA DENTAL SYSTEMS GmbH & Co. KG + +OUI:00101A* + ID_OUI_FROM_DATABASE=PictureTel Corp. + +OUI:00101B* + ID_OUI_FROM_DATABASE=CORNET TECHNOLOGY, INC. + +OUI:00101C* + ID_OUI_FROM_DATABASE=OHM TECHNOLOGIES INTL, LLC + +OUI:00101D* + ID_OUI_FROM_DATABASE=WINBOND ELECTRONICS CORP. + +OUI:00101E* + ID_OUI_FROM_DATABASE=MATSUSHITA ELECTRONIC INSTRUMENTS CORP. + +OUI:00101F* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001020* + ID_OUI_FROM_DATABASE=Hand Held Products Inc + +OUI:001021* + ID_OUI_FROM_DATABASE=ENCANTO NETWORKS, INC. + +OUI:001022* + ID_OUI_FROM_DATABASE=SatCom Media Corporation + +OUI:001023* + ID_OUI_FROM_DATABASE=Network Equipment Technologies + +OUI:001024* + ID_OUI_FROM_DATABASE=NAGOYA ELECTRIC WORKS CO., LTD + +OUI:001025* + ID_OUI_FROM_DATABASE=Grayhill, Inc + +OUI:001026* + ID_OUI_FROM_DATABASE=ACCELERATED NETWORKS, INC. + +OUI:001027* + ID_OUI_FROM_DATABASE=L-3 COMMUNICATIONS EAST + +OUI:001028* + ID_OUI_FROM_DATABASE=COMPUTER TECHNICA, INC. + +OUI:001029* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00102A* + ID_OUI_FROM_DATABASE=ZF MICROSYSTEMS, INC. + +OUI:00102B* + ID_OUI_FROM_DATABASE=UMAX DATA SYSTEMS, INC. + +OUI:00102C* + ID_OUI_FROM_DATABASE=Lasat Networks A/S + +OUI:00102D* + ID_OUI_FROM_DATABASE=HITACHI SOFTWARE ENGINEERING + +OUI:00102E* + ID_OUI_FROM_DATABASE=NETWORK SYSTEMS & TECHNOLOGIES PVT. LTD. + +OUI:00102F* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001030* + ID_OUI_FROM_DATABASE=EION Inc. + +OUI:001031* + ID_OUI_FROM_DATABASE=OBJECTIVE COMMUNICATIONS, INC. + +OUI:001032* + ID_OUI_FROM_DATABASE=ALTA TECHNOLOGY + +OUI:001033* + ID_OUI_FROM_DATABASE=ACCESSLAN COMMUNICATIONS, INC. + +OUI:001034* + ID_OUI_FROM_DATABASE=GNP Computers + +OUI:001035* + ID_OUI_FROM_DATABASE=ELITEGROUP COMPUTER SYSTEMS CO., LTD + +OUI:001036* + ID_OUI_FROM_DATABASE=INTER-TEL INTEGRATED SYSTEMS + +OUI:001037* + ID_OUI_FROM_DATABASE=CYQ've Technology Co., Ltd. + +OUI:001038* + ID_OUI_FROM_DATABASE=MICRO RESEARCH INSTITUTE, INC. + +OUI:001039* + ID_OUI_FROM_DATABASE=Vectron Systems AG + +OUI:00103A* + ID_OUI_FROM_DATABASE=DIAMOND NETWORK TECH + +OUI:00103B* + ID_OUI_FROM_DATABASE=HIPPI NETWORKING FORUM + +OUI:00103C* + ID_OUI_FROM_DATABASE=IC ENSEMBLE, INC. + +OUI:00103D* + ID_OUI_FROM_DATABASE=PHASECOM, LTD. + +OUI:00103E* + ID_OUI_FROM_DATABASE=NETSCHOOLS CORPORATION + +OUI:00103F* + ID_OUI_FROM_DATABASE=TOLLGRADE COMMUNICATIONS, INC. + +OUI:001040* + ID_OUI_FROM_DATABASE=INTERMEC CORPORATION + +OUI:001041* + ID_OUI_FROM_DATABASE=BRISTOL BABCOCK, INC. + +OUI:001042* + ID_OUI_FROM_DATABASE=Alacritech, Inc. + +OUI:001043* + ID_OUI_FROM_DATABASE=A2 CORPORATION + +OUI:001044* + ID_OUI_FROM_DATABASE=InnoLabs Corporation + +OUI:001045* + ID_OUI_FROM_DATABASE=Nortel Networks + +OUI:001046* + ID_OUI_FROM_DATABASE=ALCORN MCBRIDE INC. + +OUI:001047* + ID_OUI_FROM_DATABASE=ECHO ELETRIC CO. LTD. + +OUI:001048* + ID_OUI_FROM_DATABASE=HTRC AUTOMATION, INC. + +OUI:001049* + ID_OUI_FROM_DATABASE=ShoreTel, Inc + +OUI:00104A* + ID_OUI_FROM_DATABASE=The Parvus Corporation + +OUI:00104B* + ID_OUI_FROM_DATABASE=3COM CORPORATION + +OUI:00104C* + ID_OUI_FROM_DATABASE=LeCroy Corporation + +OUI:00104D* + ID_OUI_FROM_DATABASE=SURTEC INDUSTRIES, INC. + +OUI:00104E* + ID_OUI_FROM_DATABASE=CEOLOGIC + +OUI:00104F* + ID_OUI_FROM_DATABASE=Oracle Corporation + +OUI:001050* + ID_OUI_FROM_DATABASE=RION CO., LTD. + +OUI:001051* + ID_OUI_FROM_DATABASE=CMICRO CORPORATION + +OUI:001052* + ID_OUI_FROM_DATABASE=METTLER-TOLEDO (ALBSTADT) GMBH + +OUI:001053* + ID_OUI_FROM_DATABASE=COMPUTER TECHNOLOGY CORP. + +OUI:001054* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001055* + ID_OUI_FROM_DATABASE=FUJITSU MICROELECTRONICS, INC. + +OUI:001056* + ID_OUI_FROM_DATABASE=SODICK CO., LTD. + +OUI:001057* + ID_OUI_FROM_DATABASE=Rebel.com, Inc. + +OUI:001058* + ID_OUI_FROM_DATABASE=ArrowPoint Communications + +OUI:001059* + ID_OUI_FROM_DATABASE=DIABLO RESEARCH CO. LLC + +OUI:00105A* + ID_OUI_FROM_DATABASE=3COM CORPORATION + +OUI:00105B* + ID_OUI_FROM_DATABASE=NET INSIGHT AB + +OUI:00105C* + ID_OUI_FROM_DATABASE=QUANTUM DESIGNS (H.K.) LTD. + +OUI:00105D* + ID_OUI_FROM_DATABASE=Draeger Medical + +OUI:00105E* + ID_OUI_FROM_DATABASE=HEKIMIAN LABORATORIES, INC. + +OUI:00105F* + ID_OUI_FROM_DATABASE=ZODIAC DATA SYSTEMS + +OUI:001060* + ID_OUI_FROM_DATABASE=BILLIONTON SYSTEMS, INC. + +OUI:001061* + ID_OUI_FROM_DATABASE=HOSTLINK CORP. + +OUI:001062* + ID_OUI_FROM_DATABASE=NX SERVER, ILNC. + +OUI:001063* + ID_OUI_FROM_DATABASE=STARGUIDE DIGITAL NETWORKS + +OUI:001064* + ID_OUI_FROM_DATABASE=DNPG, LLC + +OUI:001065* + ID_OUI_FROM_DATABASE=RADYNE CORPORATION + +OUI:001066* + ID_OUI_FROM_DATABASE=ADVANCED CONTROL SYSTEMS, INC. + +OUI:001067* + ID_OUI_FROM_DATABASE=Ericsson + +OUI:001068* + ID_OUI_FROM_DATABASE=COMOS TELECOM + +OUI:001069* + ID_OUI_FROM_DATABASE=HELIOSS COMMUNICATIONS, INC. + +OUI:00106A* + ID_OUI_FROM_DATABASE=DIGITAL MICROWAVE CORPORATION + +OUI:00106B* + ID_OUI_FROM_DATABASE=SONUS NETWORKS, INC. + +OUI:00106C* + ID_OUI_FROM_DATABASE=Infratec AG + +OUI:00106D* + ID_OUI_FROM_DATABASE=Axxcelera Broadband Wireless + +OUI:00106E* + ID_OUI_FROM_DATABASE=TADIRAN COM. LTD. + +OUI:00106F* + ID_OUI_FROM_DATABASE=TRENTON TECHNOLOGY INC. + +OUI:001070* + ID_OUI_FROM_DATABASE=CARADON TREND LTD. + +OUI:001071* + ID_OUI_FROM_DATABASE=ADVANET INC. + +OUI:001072* + ID_OUI_FROM_DATABASE=GVN TECHNOLOGIES, INC. + +OUI:001073* + ID_OUI_FROM_DATABASE=Technobox, Inc. + +OUI:001074* + ID_OUI_FROM_DATABASE=ATEN INTERNATIONAL CO., LTD. + +OUI:001075* + ID_OUI_FROM_DATABASE=Maxtor Corporation + +OUI:001076* + ID_OUI_FROM_DATABASE=EUREM GmbH + +OUI:001077* + ID_OUI_FROM_DATABASE=SAF DRIVE SYSTEMS, LTD. + +OUI:001078* + ID_OUI_FROM_DATABASE=NUERA COMMUNICATIONS, INC. + +OUI:001079* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00107A* + ID_OUI_FROM_DATABASE=AmbiCom, Inc. + +OUI:00107B* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00107C* + ID_OUI_FROM_DATABASE=P-COM, INC. + +OUI:00107D* + ID_OUI_FROM_DATABASE=AURORA COMMUNICATIONS, LTD. + +OUI:00107E* + ID_OUI_FROM_DATABASE=BACHMANN ELECTRONIC GmbH + +OUI:00107F* + ID_OUI_FROM_DATABASE=CRESTRON ELECTRONICS, INC. + +OUI:001080* + ID_OUI_FROM_DATABASE=METAWAVE COMMUNICATIONS + +OUI:001081* + ID_OUI_FROM_DATABASE=DPS, INC. + +OUI:001082* + ID_OUI_FROM_DATABASE=JNA TELECOMMUNICATIONS LIMITED + +OUI:001083* + ID_OUI_FROM_DATABASE=HEWLETT-PACKARD COMPANY + +OUI:001084* + ID_OUI_FROM_DATABASE=K-BOT COMMUNICATIONS + +OUI:001085* + ID_OUI_FROM_DATABASE=POLARIS COMMUNICATIONS, INC. + +OUI:001086* + ID_OUI_FROM_DATABASE=ATTO Technology, Inc. + +OUI:001087* + ID_OUI_FROM_DATABASE=Xstreamis PLC + +OUI:001088* + ID_OUI_FROM_DATABASE=AMERICAN NETWORKS INC. + +OUI:001089* + ID_OUI_FROM_DATABASE=WebSonic + +OUI:00108A* + ID_OUI_FROM_DATABASE=TeraLogic, Inc. + +OUI:00108B* + ID_OUI_FROM_DATABASE=LASERANIMATION SOLLINGER GmbH + +OUI:00108C* + ID_OUI_FROM_DATABASE=FUJITSU TELECOMMUNICATIONS EUROPE, LTD. + +OUI:00108D* + ID_OUI_FROM_DATABASE=Johnson Controls, Inc. + +OUI:00108E* + ID_OUI_FROM_DATABASE=HUGH SYMONS CONCEPT Technologies Ltd. + +OUI:00108F* + ID_OUI_FROM_DATABASE=RAPTOR SYSTEMS + +OUI:001090* + ID_OUI_FROM_DATABASE=CIMETRICS, INC. + +OUI:001091* + ID_OUI_FROM_DATABASE=NO WIRES NEEDED BV + +OUI:001092* + ID_OUI_FROM_DATABASE=NETCORE INC. + +OUI:001093* + ID_OUI_FROM_DATABASE=CMS COMPUTERS, LTD. + +OUI:001094* + ID_OUI_FROM_DATABASE=Performance Analysis Broadband, Spirent plc + +OUI:001095* + ID_OUI_FROM_DATABASE=Thomson Inc. + +OUI:001096* + ID_OUI_FROM_DATABASE=TRACEWELL SYSTEMS, INC. + +OUI:001097* + ID_OUI_FROM_DATABASE=WinNet Metropolitan Communications Systems, Inc. + +OUI:001098* + ID_OUI_FROM_DATABASE=STARNET TECHNOLOGIES, INC. + +OUI:001099* + ID_OUI_FROM_DATABASE=InnoMedia, Inc. + +OUI:00109A* + ID_OUI_FROM_DATABASE=NETLINE + +OUI:00109B* + ID_OUI_FROM_DATABASE=Emulex Corporation + +OUI:00109C* + ID_OUI_FROM_DATABASE=M-SYSTEM CO., LTD. + +OUI:00109D* + ID_OUI_FROM_DATABASE=CLARINET SYSTEMS, INC. + +OUI:00109E* + ID_OUI_FROM_DATABASE=AWARE, INC. + +OUI:00109F* + ID_OUI_FROM_DATABASE=PAVO, INC. + +OUI:0010A0* + ID_OUI_FROM_DATABASE=INNOVEX TECHNOLOGIES, INC. + +OUI:0010A1* + ID_OUI_FROM_DATABASE=KENDIN SEMICONDUCTOR, INC. + +OUI:0010A2* + ID_OUI_FROM_DATABASE=TNS + +OUI:0010A3* + ID_OUI_FROM_DATABASE=OMNITRONIX, INC. + +OUI:0010A4* + ID_OUI_FROM_DATABASE=XIRCOM + +OUI:0010A5* + ID_OUI_FROM_DATABASE=OXFORD INSTRUMENTS + +OUI:0010A6* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0010A7* + ID_OUI_FROM_DATABASE=UNEX TECHNOLOGY CORPORATION + +OUI:0010A8* + ID_OUI_FROM_DATABASE=RELIANCE COMPUTER CORP. + +OUI:0010A9* + ID_OUI_FROM_DATABASE=ADHOC TECHNOLOGIES + +OUI:0010AA* + ID_OUI_FROM_DATABASE=MEDIA4, INC. + +OUI:0010AB* + ID_OUI_FROM_DATABASE=KOITO ELECTRIC INDUSTRIES, LTD. + +OUI:0010AC* + ID_OUI_FROM_DATABASE=IMCI TECHNOLOGIES + +OUI:0010AD* + ID_OUI_FROM_DATABASE=SOFTRONICS USB, INC. + +OUI:0010AE* + ID_OUI_FROM_DATABASE=SHINKO ELECTRIC INDUSTRIES CO. + +OUI:0010AF* + ID_OUI_FROM_DATABASE=TAC SYSTEMS, INC. + +OUI:0010B0* + ID_OUI_FROM_DATABASE=MERIDIAN TECHNOLOGY CORP. + +OUI:0010B1* + ID_OUI_FROM_DATABASE=FOR-A CO., LTD. + +OUI:0010B2* + ID_OUI_FROM_DATABASE=COACTIVE AESTHETICS + +OUI:0010B3* + ID_OUI_FROM_DATABASE=NOKIA MULTIMEDIA TERMINALS + +OUI:0010B4* + ID_OUI_FROM_DATABASE=ATMOSPHERE NETWORKS + +OUI:0010B5* + ID_OUI_FROM_DATABASE=ACCTON TECHNOLOGY CORPORATION + +OUI:0010B6* + ID_OUI_FROM_DATABASE=ENTRATA COMMUNICATIONS CORP. + +OUI:0010B7* + ID_OUI_FROM_DATABASE=COYOTE TECHNOLOGIES, LLC + +OUI:0010B8* + ID_OUI_FROM_DATABASE=ISHIGAKI COMPUTER SYSTEM CO. + +OUI:0010B9* + ID_OUI_FROM_DATABASE=MAXTOR CORP. + +OUI:0010BA* + ID_OUI_FROM_DATABASE=MARTINHO-DAVIS SYSTEMS, INC. + +OUI:0010BB* + ID_OUI_FROM_DATABASE=DATA & INFORMATION TECHNOLOGY + +OUI:0010BC* + ID_OUI_FROM_DATABASE=Aastra Telecom + +OUI:0010BD* + ID_OUI_FROM_DATABASE=THE TELECOMMUNICATION TECHNOLOGY COMMITTEE (TTC) + +OUI:0010BE* + ID_OUI_FROM_DATABASE=MARCH NETWORKS CORPORATION + +OUI:0010BF* + ID_OUI_FROM_DATABASE=InterAir Wireless + +OUI:0010C0* + ID_OUI_FROM_DATABASE=ARMA, Inc. + +OUI:0010C1* + ID_OUI_FROM_DATABASE=OI ELECTRIC CO., LTD. + +OUI:0010C2* + ID_OUI_FROM_DATABASE=WILLNET, INC. + +OUI:0010C3* + ID_OUI_FROM_DATABASE=CSI-CONTROL SYSTEMS + +OUI:0010C4* + ID_OUI_FROM_DATABASE=MEDIA LINKS CO., LTD. + +OUI:0010C5* + ID_OUI_FROM_DATABASE=PROTOCOL TECHNOLOGIES, INC. + +OUI:0010C6* + ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co., Ltd. + +OUI:0010C7* + ID_OUI_FROM_DATABASE=DATA TRANSMISSION NETWORK + +OUI:0010C8* + ID_OUI_FROM_DATABASE=COMMUNICATIONS ELECTRONICS SECURITY GROUP + +OUI:0010C9* + ID_OUI_FROM_DATABASE=MITSUBISHI ELECTRONICS LOGISTIC SUPPORT CO. + +OUI:0010CA* + ID_OUI_FROM_DATABASE=Telco Systems, Inc. + +OUI:0010CB* + ID_OUI_FROM_DATABASE=FACIT K.K. + +OUI:0010CC* + ID_OUI_FROM_DATABASE=CLP COMPUTER LOGISTIK PLANUNG GmbH + +OUI:0010CD* + ID_OUI_FROM_DATABASE=INTERFACE CONCEPT + +OUI:0010CE* + ID_OUI_FROM_DATABASE=VOLAMP, LTD. + +OUI:0010CF* + ID_OUI_FROM_DATABASE=FIBERLANE COMMUNICATIONS + +OUI:0010D0* + ID_OUI_FROM_DATABASE=WITCOM, LTD. + +OUI:0010D1* + ID_OUI_FROM_DATABASE=Top Layer Networks, Inc. + +OUI:0010D2* + ID_OUI_FROM_DATABASE=NITTO TSUSHINKI CO., LTD + +OUI:0010D3* + ID_OUI_FROM_DATABASE=GRIPS ELECTRONIC GMBH + +OUI:0010D4* + ID_OUI_FROM_DATABASE=STORAGE COMPUTER CORPORATION + +OUI:0010D5* + ID_OUI_FROM_DATABASE=IMASDE CANARIAS, S.A. + +OUI:0010D6* + ID_OUI_FROM_DATABASE=ITT - A/CD + +OUI:0010D7* + ID_OUI_FROM_DATABASE=ARGOSY RESEARCH INC. + +OUI:0010D8* + ID_OUI_FROM_DATABASE=CALISTA + +OUI:0010D9* + ID_OUI_FROM_DATABASE=IBM JAPAN, FUJISAWA MT+D + +OUI:0010DA* + ID_OUI_FROM_DATABASE=MOTION ENGINEERING, INC. + +OUI:0010DB* + ID_OUI_FROM_DATABASE=Juniper Networks, Inc. + +OUI:0010DC* + ID_OUI_FROM_DATABASE=MICRO-STAR INTERNATIONAL CO., LTD. + +OUI:0010DD* + ID_OUI_FROM_DATABASE=ENABLE SEMICONDUCTOR, INC. + +OUI:0010DE* + ID_OUI_FROM_DATABASE=INTERNATIONAL DATACASTING CORPORATION + +OUI:0010DF* + ID_OUI_FROM_DATABASE=RISE COMPUTER INC. + +OUI:0010E0* + ID_OUI_FROM_DATABASE=Oracle Corporation + +OUI:0010E1* + ID_OUI_FROM_DATABASE=S.I. TECH, INC. + +OUI:0010E2* + ID_OUI_FROM_DATABASE=ArrayComm, Inc. + +OUI:0010E3* + ID_OUI_FROM_DATABASE=Hewlett-Packard Company + +OUI:0010E4* + ID_OUI_FROM_DATABASE=NSI CORPORATION + +OUI:0010E5* + ID_OUI_FROM_DATABASE=SOLECTRON TEXAS + +OUI:0010E6* + ID_OUI_FROM_DATABASE=APPLIED INTELLIGENT SYSTEMS, INC. + +OUI:0010E7* + ID_OUI_FROM_DATABASE=BreezeCom + +OUI:0010E8* + ID_OUI_FROM_DATABASE=TELOCITY, INCORPORATED + +OUI:0010E9* + ID_OUI_FROM_DATABASE=RAIDTEC LTD. + +OUI:0010EA* + ID_OUI_FROM_DATABASE=ADEPT TECHNOLOGY + +OUI:0010EB* + ID_OUI_FROM_DATABASE=SELSIUS SYSTEMS, INC. + +OUI:0010EC* + ID_OUI_FROM_DATABASE=RPCG, LLC + +OUI:0010ED* + ID_OUI_FROM_DATABASE=SUNDANCE TECHNOLOGY, INC. + +OUI:0010EE* + ID_OUI_FROM_DATABASE=CTI PRODUCTS, INC. + +OUI:0010EF* + ID_OUI_FROM_DATABASE=DBTEL INCORPORATED + +OUI:0010F1* + ID_OUI_FROM_DATABASE=I-O CORPORATION + +OUI:0010F2* + ID_OUI_FROM_DATABASE=ANTEC + +OUI:0010F3* + ID_OUI_FROM_DATABASE=Nexcom International Co., Ltd. + +OUI:0010F4* + ID_OUI_FROM_DATABASE=Vertical Communications + +OUI:0010F5* + ID_OUI_FROM_DATABASE=AMHERST SYSTEMS, INC. + +OUI:0010F6* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0010F7* + ID_OUI_FROM_DATABASE=IRIICHI TECHNOLOGIES Inc. + +OUI:0010F8* + ID_OUI_FROM_DATABASE=Niikke Techno System Co. Ltd + +OUI:0010F9* + ID_OUI_FROM_DATABASE=UNIQUE SYSTEMS, INC. + +OUI:0010FA* + ID_OUI_FROM_DATABASE=Apple, Inc + +OUI:0010FB* + ID_OUI_FROM_DATABASE=ZIDA TECHNOLOGIES LIMITED + +OUI:0010FC* + ID_OUI_FROM_DATABASE=BROADBAND NETWORKS, INC. + +OUI:0010FD* + ID_OUI_FROM_DATABASE=COCOM A/S + +OUI:0010FE* + ID_OUI_FROM_DATABASE=DIGITAL EQUIPMENT CORPORATION + +OUI:0010FF* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001100* + ID_OUI_FROM_DATABASE=Schneider Electric + +OUI:001101* + ID_OUI_FROM_DATABASE=CET Technologies Pte Ltd + +OUI:001102* + ID_OUI_FROM_DATABASE=Aurora Multimedia Corp. + +OUI:001103* + ID_OUI_FROM_DATABASE=kawamura electric inc. + +OUI:001104* + ID_OUI_FROM_DATABASE=TELEXY + +OUI:001105* + ID_OUI_FROM_DATABASE=Sunplus Technology Co., Ltd. + +OUI:001106* + ID_OUI_FROM_DATABASE=Siemens NV (Belgium) + +OUI:001107* + ID_OUI_FROM_DATABASE=RGB Networks Inc. + +OUI:001108* + ID_OUI_FROM_DATABASE=Orbital Data Corporation + +OUI:001109* + ID_OUI_FROM_DATABASE=Micro-Star International + +OUI:00110A* + ID_OUI_FROM_DATABASE=Hewlett-Packard Company + +OUI:00110B* + ID_OUI_FROM_DATABASE=Franklin Technology Systems + +OUI:00110C* + ID_OUI_FROM_DATABASE=Atmark Techno, Inc. + +OUI:00110D* + ID_OUI_FROM_DATABASE=SANBlaze Technology, Inc. + +OUI:00110E* + ID_OUI_FROM_DATABASE=Tsurusaki Sealand Transportation Co. Ltd. + +OUI:00110F* + ID_OUI_FROM_DATABASE=netplat,Inc. + +OUI:001110* + ID_OUI_FROM_DATABASE=Maxanna Technology Co., Ltd. + +OUI:001111* + ID_OUI_FROM_DATABASE=Intel Corporation + +OUI:001112* + ID_OUI_FROM_DATABASE=Honeywell CMSS + +OUI:001113* + ID_OUI_FROM_DATABASE=Fraunhofer FOKUS + +OUI:001114* + ID_OUI_FROM_DATABASE=EverFocus Electronics Corp. + +OUI:001115* + ID_OUI_FROM_DATABASE=EPIN Technologies, Inc. + +OUI:001116* + ID_OUI_FROM_DATABASE=COTEAU VERT CO., LTD. + +OUI:001117* + ID_OUI_FROM_DATABASE=CESNET + +OUI:001118* + ID_OUI_FROM_DATABASE=BLX IC Design Corp., Ltd. + +OUI:001119* + ID_OUI_FROM_DATABASE=Solteras, Inc. + +OUI:00111A* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:00111B* + ID_OUI_FROM_DATABASE=Targa Systems Div L-3 Communications Canada + +OUI:00111C* + ID_OUI_FROM_DATABASE=Pleora Technologies Inc. + +OUI:00111D* + ID_OUI_FROM_DATABASE=Hectrix Limited + +OUI:00111E* + ID_OUI_FROM_DATABASE=EPSG (Ethernet Powerlink Standardization Group) + +OUI:00111F* + ID_OUI_FROM_DATABASE=Doremi Labs, Inc. + +OUI:001120* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001121* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001122* + ID_OUI_FROM_DATABASE=CIMSYS Inc + +OUI:001123* + ID_OUI_FROM_DATABASE=Appointech, Inc. + +OUI:001124* + ID_OUI_FROM_DATABASE=Apple Computer + +OUI:001125* + ID_OUI_FROM_DATABASE=IBM Corp + +OUI:001126* + ID_OUI_FROM_DATABASE=Venstar Inc. + +OUI:001127* + ID_OUI_FROM_DATABASE=TASI, Inc + +OUI:001128* + ID_OUI_FROM_DATABASE=Streamit + +OUI:001129* + ID_OUI_FROM_DATABASE=Paradise Datacom Ltd. + +OUI:00112A* + ID_OUI_FROM_DATABASE=Niko NV + +OUI:00112B* + ID_OUI_FROM_DATABASE=NetModule AG + +OUI:00112C* + ID_OUI_FROM_DATABASE=IZT GmbH + +OUI:00112D* + ID_OUI_FROM_DATABASE=iPulse Systems + +OUI:00112E* + ID_OUI_FROM_DATABASE=CEICOM + +OUI:00112F* + ID_OUI_FROM_DATABASE=ASUSTek Computer Inc. + +OUI:001130* + ID_OUI_FROM_DATABASE=Allied Telesis (Hong Kong) Ltd. + +OUI:001131* + ID_OUI_FROM_DATABASE=UNATECH. CO.,LTD + +OUI:001132* + ID_OUI_FROM_DATABASE=Synology Incorporated + +OUI:001133* + ID_OUI_FROM_DATABASE=Siemens Austria SIMEA + +OUI:001134* + ID_OUI_FROM_DATABASE=MediaCell, Inc. + +OUI:001135* + ID_OUI_FROM_DATABASE=Grandeye Ltd + +OUI:001136* + ID_OUI_FROM_DATABASE=Goodrich Sensor Systems + +OUI:001137* + ID_OUI_FROM_DATABASE=AICHI ELECTRIC CO., LTD. + +OUI:001138* + ID_OUI_FROM_DATABASE=TAISHIN CO., LTD. + +OUI:001139* + ID_OUI_FROM_DATABASE=STOEBER ANTRIEBSTECHNIK GmbH + Co. KG. + +OUI:00113A* + ID_OUI_FROM_DATABASE=SHINBORAM + +OUI:00113B* + ID_OUI_FROM_DATABASE=Micronet Communications Inc. + +OUI:00113C* + ID_OUI_FROM_DATABASE=Micronas GmbH + +OUI:00113D* + ID_OUI_FROM_DATABASE=KN SOLTEC CO.,LTD. + +OUI:00113E* + ID_OUI_FROM_DATABASE=JL Corporation + +OUI:00113F* + ID_OUI_FROM_DATABASE=Alcatel DI + +OUI:001140* + ID_OUI_FROM_DATABASE=Nanometrics Inc. + +OUI:001141* + ID_OUI_FROM_DATABASE=GoodMan Corporation + +OUI:001142* + ID_OUI_FROM_DATABASE=e-SMARTCOM INC. + +OUI:001143* + ID_OUI_FROM_DATABASE=DELL INC. + +OUI:001144* + ID_OUI_FROM_DATABASE=Assurance Technology Corp + +OUI:001145* + ID_OUI_FROM_DATABASE=ValuePoint Networks + +OUI:001146* + ID_OUI_FROM_DATABASE=Telecard-Pribor Ltd + +OUI:001147* + ID_OUI_FROM_DATABASE=Secom-Industry co.LTD. + +OUI:001148* + ID_OUI_FROM_DATABASE=Prolon Control Systems + +OUI:001149* + ID_OUI_FROM_DATABASE=Proliphix Inc. + +OUI:00114A* + ID_OUI_FROM_DATABASE=KAYABA INDUSTRY Co,.Ltd. + +OUI:00114B* + ID_OUI_FROM_DATABASE=Francotyp-Postalia GmbH + +OUI:00114C* + ID_OUI_FROM_DATABASE=caffeina applied research ltd. + +OUI:00114D* + ID_OUI_FROM_DATABASE=Atsumi Electric Co.,LTD. + +OUI:00114E* + ID_OUI_FROM_DATABASE=690885 Ontario Inc. + +OUI:00114F* + ID_OUI_FROM_DATABASE=US Digital Television, Inc + +OUI:001150* + ID_OUI_FROM_DATABASE=Belkin Corporation + +OUI:001151* + ID_OUI_FROM_DATABASE=Mykotronx + +OUI:001152* + ID_OUI_FROM_DATABASE=Eidsvoll Electronics AS + +OUI:001153* + ID_OUI_FROM_DATABASE=Trident Tek, Inc. + +OUI:001154* + ID_OUI_FROM_DATABASE=Webpro Technologies Inc. + +OUI:001155* + ID_OUI_FROM_DATABASE=Sevis Systems + +OUI:001156* + ID_OUI_FROM_DATABASE=Pharos Systems NZ + +OUI:001157* + ID_OUI_FROM_DATABASE=OF Networks Co., Ltd. + +OUI:001158* + ID_OUI_FROM_DATABASE=Nortel Networks + +OUI:001159* + ID_OUI_FROM_DATABASE=MATISSE NETWORKS INC + +OUI:00115A* + ID_OUI_FROM_DATABASE=Ivoclar Vivadent AG + +OUI:00115B* + ID_OUI_FROM_DATABASE=Elitegroup Computer System Co. (ECS) + +OUI:00115C* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00115D* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00115E* + ID_OUI_FROM_DATABASE=ProMinent Dosiertechnik GmbH + +OUI:00115F* + ID_OUI_FROM_DATABASE=ITX Security Co., Ltd. + +OUI:001160* + ID_OUI_FROM_DATABASE=ARTDIO Company Co., LTD + +OUI:001161* + ID_OUI_FROM_DATABASE=NetStreams, LLC + +OUI:001162* + ID_OUI_FROM_DATABASE=STAR MICRONICS CO.,LTD. + +OUI:001163* + ID_OUI_FROM_DATABASE=SYSTEM SPA DEPT. ELECTRONICS + +OUI:001164* + ID_OUI_FROM_DATABASE=ACARD Technology Corp. + +OUI:001165* + ID_OUI_FROM_DATABASE=Znyx Networks + +OUI:001166* + ID_OUI_FROM_DATABASE=Taelim Electronics Co., Ltd. + +OUI:001167* + ID_OUI_FROM_DATABASE=Integrated System Solution Corp. + +OUI:001168* + ID_OUI_FROM_DATABASE=HomeLogic LLC + +OUI:001169* + ID_OUI_FROM_DATABASE=EMS Satcom + +OUI:00116A* + ID_OUI_FROM_DATABASE=Domo Ltd + +OUI:00116B* + ID_OUI_FROM_DATABASE=Digital Data Communications Asia Co.,Ltd + +OUI:00116C* + ID_OUI_FROM_DATABASE=Nanwang Multimedia Inc.,Ltd + +OUI:00116D* + ID_OUI_FROM_DATABASE=American Time and Signal + +OUI:00116E* + ID_OUI_FROM_DATABASE=PePLink Ltd. + +OUI:00116F* + ID_OUI_FROM_DATABASE=Netforyou Co., LTD. + +OUI:001170* + ID_OUI_FROM_DATABASE=GSC SRL + +OUI:001171* + ID_OUI_FROM_DATABASE=DEXTER Communications, Inc. + +OUI:001172* + ID_OUI_FROM_DATABASE=COTRON CORPORATION + +OUI:001173* + ID_OUI_FROM_DATABASE=SMART Storage Systems + +OUI:001174* + ID_OUI_FROM_DATABASE=Wibhu Technologies, Inc. + +OUI:001175* + ID_OUI_FROM_DATABASE=PathScale, Inc. + +OUI:001176* + ID_OUI_FROM_DATABASE=Intellambda Systems, Inc. + +OUI:001177* + ID_OUI_FROM_DATABASE=Coaxial Networks, Inc. + +OUI:001178* + ID_OUI_FROM_DATABASE=Chiron Technology Ltd + +OUI:001179* + ID_OUI_FROM_DATABASE=Singular Technology Co. Ltd. + +OUI:00117A* + ID_OUI_FROM_DATABASE=Singim International Corp. + +OUI:00117B* + ID_OUI_FROM_DATABASE=Büchi Labortechnik AG + +OUI:00117C* + ID_OUI_FROM_DATABASE=e-zy.net + +OUI:00117D* + ID_OUI_FROM_DATABASE=ZMD America, Inc. + +OUI:00117E* + ID_OUI_FROM_DATABASE=Progeny, A division of Midmark Corp + +OUI:00117F* + ID_OUI_FROM_DATABASE=Neotune Information Technology Corporation,.LTD + +OUI:001180* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:001181* + ID_OUI_FROM_DATABASE=InterEnergy Co.Ltd, + +OUI:001182* + ID_OUI_FROM_DATABASE=IMI Norgren Ltd + +OUI:001183* + ID_OUI_FROM_DATABASE=Datalogic Mobile, Inc. + +OUI:001184* + ID_OUI_FROM_DATABASE=Humo Laboratory,Ltd. + +OUI:001185* + ID_OUI_FROM_DATABASE=Hewlett-Packard Company + +OUI:001186* + ID_OUI_FROM_DATABASE=Prime Systems, Inc. + +OUI:001187* + ID_OUI_FROM_DATABASE=Category Solutions, Inc + +OUI:001188* + ID_OUI_FROM_DATABASE=Enterasys + +OUI:001189* + ID_OUI_FROM_DATABASE=Aerotech Inc + +OUI:00118A* + ID_OUI_FROM_DATABASE=Viewtran Technology Limited + +OUI:00118B* + ID_OUI_FROM_DATABASE=Alcatel-Lucent, Enterprise Business Group + +OUI:00118C* + ID_OUI_FROM_DATABASE=Missouri Department of Transportation + +OUI:00118D* + ID_OUI_FROM_DATABASE=Hanchang System Corp. + +OUI:00118E* + ID_OUI_FROM_DATABASE=Halytech Mace + +OUI:00118F* + ID_OUI_FROM_DATABASE=EUTECH INSTRUMENTS PTE. LTD. + +OUI:001190* + ID_OUI_FROM_DATABASE=Digital Design Corporation + +OUI:001191* + ID_OUI_FROM_DATABASE=CTS-Clima Temperatur Systeme GmbH + +OUI:001192* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001193* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001194* + ID_OUI_FROM_DATABASE=Chi Mei Communication Systems, Inc. + +OUI:001195* + ID_OUI_FROM_DATABASE=D-Link Corporation + +OUI:001196* + ID_OUI_FROM_DATABASE=Actuality Systems, Inc. + +OUI:001197* + ID_OUI_FROM_DATABASE=Monitoring Technologies Limited + +OUI:001198* + ID_OUI_FROM_DATABASE=Prism Media Products Limited + +OUI:001199* + ID_OUI_FROM_DATABASE=2wcom GmbH + +OUI:00119A* + ID_OUI_FROM_DATABASE=Alkeria srl + +OUI:00119B* + ID_OUI_FROM_DATABASE=Telesynergy Research Inc. + +OUI:00119C* + ID_OUI_FROM_DATABASE=EP&T Energy + +OUI:00119D* + ID_OUI_FROM_DATABASE=Diginfo Technology Corporation + +OUI:00119E* + ID_OUI_FROM_DATABASE=Solectron Brazil + +OUI:00119F* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:0011A0* + ID_OUI_FROM_DATABASE=Vtech Engineering Canada Ltd + +OUI:0011A1* + ID_OUI_FROM_DATABASE=VISION NETWARE CO.,LTD + +OUI:0011A2* + ID_OUI_FROM_DATABASE=Manufacturing Technology Inc + +OUI:0011A3* + ID_OUI_FROM_DATABASE=LanReady Technologies Inc. + +OUI:0011A4* + ID_OUI_FROM_DATABASE=JStream Technologies Inc. + +OUI:0011A5* + ID_OUI_FROM_DATABASE=Fortuna Electronic Corp. + +OUI:0011A6* + ID_OUI_FROM_DATABASE=Sypixx Networks + +OUI:0011A7* + ID_OUI_FROM_DATABASE=Infilco Degremont Inc. + +OUI:0011A8* + ID_OUI_FROM_DATABASE=Quest Technologies + +OUI:0011A9* + ID_OUI_FROM_DATABASE=MOIMSTONE Co., LTD + +OUI:0011AA* + ID_OUI_FROM_DATABASE=Uniclass Technology, Co., LTD + +OUI:0011AB* + ID_OUI_FROM_DATABASE=TRUSTABLE TECHNOLOGY CO.,LTD. + +OUI:0011AC* + ID_OUI_FROM_DATABASE=Simtec Electronics + +OUI:0011AD* + ID_OUI_FROM_DATABASE=Shanghai Ruijie Technology + +OUI:0011AE* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:0011AF* + ID_OUI_FROM_DATABASE=Medialink-i,Inc + +OUI:0011B0* + ID_OUI_FROM_DATABASE=Fortelink Inc. + +OUI:0011B1* + ID_OUI_FROM_DATABASE=BlueExpert Technology Corp. + +OUI:0011B2* + ID_OUI_FROM_DATABASE=2001 Technology Inc. + +OUI:0011B3* + ID_OUI_FROM_DATABASE=YOSHIMIYA CO.,LTD. + +OUI:0011B4* + ID_OUI_FROM_DATABASE=Westermo Teleindustri AB + +OUI:0011B5* + ID_OUI_FROM_DATABASE=Shenzhen Powercom Co.,Ltd + +OUI:0011B6* + ID_OUI_FROM_DATABASE=Open Systems International + +OUI:0011B7* + ID_OUI_FROM_DATABASE=Octalix B.V. + +OUI:0011B8* + ID_OUI_FROM_DATABASE=Liebherr - Elektronik GmbH + +OUI:0011B9* + ID_OUI_FROM_DATABASE=Inner Range Pty. Ltd. + +OUI:0011BA* + ID_OUI_FROM_DATABASE=Elexol Pty Ltd + +OUI:0011BB* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0011BC* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0011BD* + ID_OUI_FROM_DATABASE=Bombardier Transportation + +OUI:0011BE* + ID_OUI_FROM_DATABASE=AGP Telecom Co. Ltd + +OUI:0011BF* + ID_OUI_FROM_DATABASE=AESYS S.p.A. + +OUI:0011C0* + ID_OUI_FROM_DATABASE=Aday Technology Inc + +OUI:0011C1* + ID_OUI_FROM_DATABASE=4P MOBILE DATA PROCESSING + +OUI:0011C2* + ID_OUI_FROM_DATABASE=United Fiber Optic Communication + +OUI:0011C3* + ID_OUI_FROM_DATABASE=Transceiving System Technology Corporation + +OUI:0011C4* + ID_OUI_FROM_DATABASE=Terminales de Telecomunicacion Terrestre, S.L. + +OUI:0011C5* + ID_OUI_FROM_DATABASE=TEN Technology + +OUI:0011C6* + ID_OUI_FROM_DATABASE=Seagate Technology LLC + +OUI:0011C7* + ID_OUI_FROM_DATABASE=Raymarine UK Ltd + +OUI:0011C8* + ID_OUI_FROM_DATABASE=Powercom Co., Ltd. + +OUI:0011C9* + ID_OUI_FROM_DATABASE=MTT Corporation + +OUI:0011CA* + ID_OUI_FROM_DATABASE=Long Range Systems, Inc. + +OUI:0011CB* + ID_OUI_FROM_DATABASE=Jacobsons AB + +OUI:0011CC* + ID_OUI_FROM_DATABASE=Guangzhou Jinpeng Group Co.,Ltd. + +OUI:0011CD* + ID_OUI_FROM_DATABASE=Axsun Technologies + +OUI:0011CE* + ID_OUI_FROM_DATABASE=Ubisense Limited + +OUI:0011CF* + ID_OUI_FROM_DATABASE=Thrane & Thrane A/S + +OUI:0011D0* + ID_OUI_FROM_DATABASE=Tandberg Data ASA + +OUI:0011D1* + ID_OUI_FROM_DATABASE=Soft Imaging System GmbH + +OUI:0011D2* + ID_OUI_FROM_DATABASE=Perception Digital Ltd + +OUI:0011D3* + ID_OUI_FROM_DATABASE=NextGenTel Holding ASA + +OUI:0011D4* + ID_OUI_FROM_DATABASE=NetEnrich, Inc + +OUI:0011D5* + ID_OUI_FROM_DATABASE=Hangzhou Sunyard System Engineering Co.,Ltd. + +OUI:0011D6* + ID_OUI_FROM_DATABASE=HandEra, Inc. + +OUI:0011D7* + ID_OUI_FROM_DATABASE=eWerks Inc + +OUI:0011D8* + ID_OUI_FROM_DATABASE=ASUSTek Computer Inc. + +OUI:0011D9* + ID_OUI_FROM_DATABASE=TiVo + +OUI:0011DA* + ID_OUI_FROM_DATABASE=Vivaas Technology Inc. + +OUI:0011DB* + ID_OUI_FROM_DATABASE=Land-Cellular Corporation + +OUI:0011DC* + ID_OUI_FROM_DATABASE=Glunz & Jensen + +OUI:0011DD* + ID_OUI_FROM_DATABASE=FROMUS TEC. Co., Ltd. + +OUI:0011DE* + ID_OUI_FROM_DATABASE=EURILOGIC + +OUI:0011DF* + ID_OUI_FROM_DATABASE=Current Energy + +OUI:0011E0* + ID_OUI_FROM_DATABASE=U-MEDIA Communications, Inc. + +OUI:0011E1* + ID_OUI_FROM_DATABASE=Arcelik A.S + +OUI:0011E2* + ID_OUI_FROM_DATABASE=Hua Jung Components Co., Ltd. + +OUI:0011E3* + ID_OUI_FROM_DATABASE=Thomson, Inc. + +OUI:0011E4* + ID_OUI_FROM_DATABASE=Danelec Electronics A/S + +OUI:0011E5* + ID_OUI_FROM_DATABASE=KCodes Corporation + +OUI:0011E6* + ID_OUI_FROM_DATABASE=Scientific Atlanta + +OUI:0011E7* + ID_OUI_FROM_DATABASE=WORLDSAT - Texas de France + +OUI:0011E8* + ID_OUI_FROM_DATABASE=Tixi.Com + +OUI:0011E9* + ID_OUI_FROM_DATABASE=STARNEX CO., LTD. + +OUI:0011EA* + ID_OUI_FROM_DATABASE=IWICS Inc. + +OUI:0011EB* + ID_OUI_FROM_DATABASE=Innovative Integration + +OUI:0011EC* + ID_OUI_FROM_DATABASE=AVIX INC. + +OUI:0011ED* + ID_OUI_FROM_DATABASE=802 Global + +OUI:0011EE* + ID_OUI_FROM_DATABASE=Estari, Inc. + +OUI:0011EF* + ID_OUI_FROM_DATABASE=Conitec Datensysteme GmbH + +OUI:0011F0* + ID_OUI_FROM_DATABASE=Wideful Limited + +OUI:0011F1* + ID_OUI_FROM_DATABASE=QinetiQ Ltd + +OUI:0011F2* + ID_OUI_FROM_DATABASE=Institute of Network Technologies + +OUI:0011F3* + ID_OUI_FROM_DATABASE=NeoMedia Europe AG + +OUI:0011F4* + ID_OUI_FROM_DATABASE=woori-net + +OUI:0011F5* + ID_OUI_FROM_DATABASE=ASKEY COMPUTER CORP. + +OUI:0011F6* + ID_OUI_FROM_DATABASE=Asia Pacific Microsystems , Inc. + +OUI:0011F7* + ID_OUI_FROM_DATABASE=Shenzhen Forward Industry Co., Ltd + +OUI:0011F8* + ID_OUI_FROM_DATABASE=AIRAYA Corp + +OUI:0011F9* + ID_OUI_FROM_DATABASE=Nortel Networks + +OUI:0011FA* + ID_OUI_FROM_DATABASE=Rane Corporation + +OUI:0011FB* + ID_OUI_FROM_DATABASE=Heidelberg Engineering GmbH + +OUI:0011FC* + ID_OUI_FROM_DATABASE=HARTING Electric Gmbh & Co.KG + +OUI:0011FD* + ID_OUI_FROM_DATABASE=KORG INC. + +OUI:0011FE* + ID_OUI_FROM_DATABASE=Keiyo System Research, Inc. + +OUI:0011FF* + ID_OUI_FROM_DATABASE=Digitro Tecnologia Ltda + +OUI:001200* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001201* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001202* + ID_OUI_FROM_DATABASE=Decrane Aerospace - Audio International Inc. + +OUI:001203* + ID_OUI_FROM_DATABASE=Activ Networks + +OUI:001204* + ID_OUI_FROM_DATABASE=u10 Networks, Inc. + +OUI:001205* + ID_OUI_FROM_DATABASE=Terrasat Communications, Inc. + +OUI:001206* + ID_OUI_FROM_DATABASE=iQuest (NZ) Ltd + +OUI:001207* + ID_OUI_FROM_DATABASE=Head Strong International Limited + +OUI:001208* + ID_OUI_FROM_DATABASE=Gantner Instruments GmbH + +OUI:001209* + ID_OUI_FROM_DATABASE=Fastrax Ltd + +OUI:00120A* + ID_OUI_FROM_DATABASE=Emerson Electric GmbH & Co. OHG + +OUI:00120B* + ID_OUI_FROM_DATABASE=Chinasys Technologies Limited + +OUI:00120C* + ID_OUI_FROM_DATABASE=CE-Infosys Pte Ltd + +OUI:00120D* + ID_OUI_FROM_DATABASE=Advanced Telecommunication Technologies, Inc. + +OUI:00120E* + ID_OUI_FROM_DATABASE=AboCom + +OUI:00120F* + ID_OUI_FROM_DATABASE=IEEE 802.3 + +OUI:001210* + ID_OUI_FROM_DATABASE=WideRay Corp + +OUI:001211* + ID_OUI_FROM_DATABASE=Protechna Herbst GmbH & Co. KG + +OUI:001212* + ID_OUI_FROM_DATABASE=PLUS Corporation + +OUI:001213* + ID_OUI_FROM_DATABASE=Metrohm AG + +OUI:001214* + ID_OUI_FROM_DATABASE=Koenig & Bauer AG + +OUI:001215* + ID_OUI_FROM_DATABASE=iStor Networks, Inc. + +OUI:001216* + ID_OUI_FROM_DATABASE=ICP Internet Communication Payment AG + +OUI:001217* + ID_OUI_FROM_DATABASE=Cisco-Linksys, LLC + +OUI:001218* + ID_OUI_FROM_DATABASE=ARUZE Corporation + +OUI:001219* + ID_OUI_FROM_DATABASE=Ahead Communication Systems Inc + +OUI:00121A* + ID_OUI_FROM_DATABASE=Techno Soft Systemnics Inc. + +OUI:00121B* + ID_OUI_FROM_DATABASE=Sound Devices, LLC + +OUI:00121C* + ID_OUI_FROM_DATABASE=PARROT S.A. + +OUI:00121D* + ID_OUI_FROM_DATABASE=Netfabric Corporation + +OUI:00121E* + ID_OUI_FROM_DATABASE=Juniper Networks, Inc. + +OUI:00121F* + ID_OUI_FROM_DATABASE=Harding Intruments + +OUI:001220* + ID_OUI_FROM_DATABASE=Cadco Systems + +OUI:001221* + ID_OUI_FROM_DATABASE=B.Braun Melsungen AG + +OUI:001222* + ID_OUI_FROM_DATABASE=Skardin (UK) Ltd + +OUI:001223* + ID_OUI_FROM_DATABASE=Pixim + +OUI:001224* + ID_OUI_FROM_DATABASE=NexQL Corporation + +OUI:001225* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:001226* + ID_OUI_FROM_DATABASE=Japan Direx Corporation + +OUI:001227* + ID_OUI_FROM_DATABASE=Franklin Electric Co., Inc. + +OUI:001228* + ID_OUI_FROM_DATABASE=Data Ltd. + +OUI:001229* + ID_OUI_FROM_DATABASE=BroadEasy Technologies Co.,Ltd + +OUI:00122A* + ID_OUI_FROM_DATABASE=VTech Telecommunications Ltd. + +OUI:00122B* + ID_OUI_FROM_DATABASE=Virbiage Pty Ltd + +OUI:00122C* + ID_OUI_FROM_DATABASE=Soenen Controls N.V. + +OUI:00122D* + ID_OUI_FROM_DATABASE=SiNett Corporation + +OUI:00122E* + ID_OUI_FROM_DATABASE=Signal Technology - AISD + +OUI:00122F* + ID_OUI_FROM_DATABASE=Sanei Electric Inc. + +OUI:001230* + ID_OUI_FROM_DATABASE=Picaso Infocommunication CO., LTD. + +OUI:001231* + ID_OUI_FROM_DATABASE=Motion Control Systems, Inc. + +OUI:001232* + ID_OUI_FROM_DATABASE=LeWiz Communications Inc. + +OUI:001233* + ID_OUI_FROM_DATABASE=JRC TOKKI Co.,Ltd. + +OUI:001234* + ID_OUI_FROM_DATABASE=Camille Bauer + +OUI:001235* + ID_OUI_FROM_DATABASE=Andrew Corporation + +OUI:001236* + ID_OUI_FROM_DATABASE=ConSentry Networks + +OUI:001237* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:001238* + ID_OUI_FROM_DATABASE=SetaBox Technology Co., Ltd. + +OUI:001239* + ID_OUI_FROM_DATABASE=S Net Systems Inc. + +OUI:00123A* + ID_OUI_FROM_DATABASE=Posystech Inc., Co. + +OUI:00123B* + ID_OUI_FROM_DATABASE=KeRo Systems ApS + +OUI:00123C* + ID_OUI_FROM_DATABASE=Second Rule LLC + +OUI:00123D* + ID_OUI_FROM_DATABASE=GES + +OUI:00123E* + ID_OUI_FROM_DATABASE=ERUNE technology Co., Ltd. + +OUI:00123F* + ID_OUI_FROM_DATABASE=Dell Inc + +OUI:001240* + ID_OUI_FROM_DATABASE=AMOI ELECTRONICS CO.,LTD + +OUI:001241* + ID_OUI_FROM_DATABASE=a2i marketing center + +OUI:001242* + ID_OUI_FROM_DATABASE=Millennial Net + +OUI:001243* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001244* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001245* + ID_OUI_FROM_DATABASE=Zellweger Analytics, Inc. + +OUI:001246* + ID_OUI_FROM_DATABASE=T.O.M TECHNOLOGY INC.. + +OUI:001247* + ID_OUI_FROM_DATABASE=Samsung Electronics Co., Ltd. + +OUI:001248* + ID_OUI_FROM_DATABASE=EMC Corporation (Kashya) + +OUI:001249* + ID_OUI_FROM_DATABASE=Delta Elettronica S.p.A. + +OUI:00124A* + ID_OUI_FROM_DATABASE=Dedicated Devices, Inc. + +OUI:00124B* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:00124C* + ID_OUI_FROM_DATABASE=BBWM Corporation + +OUI:00124D* + ID_OUI_FROM_DATABASE=Inducon BV + +OUI:00124E* + ID_OUI_FROM_DATABASE=XAC AUTOMATION CORP. + +OUI:00124F* + ID_OUI_FROM_DATABASE=Tyco Thermal Controls LLC. + +OUI:001250* + ID_OUI_FROM_DATABASE=Tokyo Aircaft Instrument Co., Ltd. + +OUI:001251* + ID_OUI_FROM_DATABASE=SILINK + +OUI:001252* + ID_OUI_FROM_DATABASE=Citronix, LLC + +OUI:001253* + ID_OUI_FROM_DATABASE=AudioDev AB + +OUI:001254* + ID_OUI_FROM_DATABASE=Spectra Technologies Holdings Company Ltd + +OUI:001255* + ID_OUI_FROM_DATABASE=NetEffect Incorporated + +OUI:001256* + ID_OUI_FROM_DATABASE=LG INFORMATION & COMM. + +OUI:001257* + ID_OUI_FROM_DATABASE=LeapComm Communication Technologies Inc. + +OUI:001258* + ID_OUI_FROM_DATABASE=Activis Polska + +OUI:001259* + ID_OUI_FROM_DATABASE=THERMO ELECTRON KARLSRUHE + +OUI:00125A* + ID_OUI_FROM_DATABASE=Microsoft Corporation + +OUI:00125B* + ID_OUI_FROM_DATABASE=KAIMEI ELECTRONI + +OUI:00125C* + ID_OUI_FROM_DATABASE=Green Hills Software, Inc. + +OUI:00125D* + ID_OUI_FROM_DATABASE=CyberNet Inc. + +OUI:00125E* + ID_OUI_FROM_DATABASE=CAEN + +OUI:00125F* + ID_OUI_FROM_DATABASE=AWIND Inc. + +OUI:001260* + ID_OUI_FROM_DATABASE=Stanton Magnetics,inc. + +OUI:001261* + ID_OUI_FROM_DATABASE=Adaptix, Inc + +OUI:001262* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:001263* + ID_OUI_FROM_DATABASE=Data Voice Technologies GmbH + +OUI:001264* + ID_OUI_FROM_DATABASE=daum electronic gmbh + +OUI:001265* + ID_OUI_FROM_DATABASE=Enerdyne Technologies, Inc. + +OUI:001266* + ID_OUI_FROM_DATABASE=Swisscom Hospitality Services SA + +OUI:001267* + ID_OUI_FROM_DATABASE=Matsushita Electronic Components Co., Ltd. + +OUI:001268* + ID_OUI_FROM_DATABASE=IPS d.o.o. + +OUI:001269* + ID_OUI_FROM_DATABASE=Value Electronics + +OUI:00126A* + ID_OUI_FROM_DATABASE=OPTOELECTRONICS Co., Ltd. + +OUI:00126B* + ID_OUI_FROM_DATABASE=Ascalade Communications Limited + +OUI:00126C* + ID_OUI_FROM_DATABASE=Visonic Ltd. + +OUI:00126D* + ID_OUI_FROM_DATABASE=University of California, Berkeley + +OUI:00126E* + ID_OUI_FROM_DATABASE=Seidel Elektronik GmbH Nfg.KG + +OUI:00126F* + ID_OUI_FROM_DATABASE=Rayson Technology Co., Ltd. + +OUI:001270* + ID_OUI_FROM_DATABASE=NGES Denro Systems + +OUI:001271* + ID_OUI_FROM_DATABASE=Measurement Computing Corp + +OUI:001272* + ID_OUI_FROM_DATABASE=Redux Communications Ltd. + +OUI:001273* + ID_OUI_FROM_DATABASE=Stoke Inc + +OUI:001274* + ID_OUI_FROM_DATABASE=NIT lab + +OUI:001275* + ID_OUI_FROM_DATABASE=Sentilla Corporation + +OUI:001276* + ID_OUI_FROM_DATABASE=CG Power Systems Ireland Limited + +OUI:001277* + ID_OUI_FROM_DATABASE=Korenix Technologies Co., Ltd. + +OUI:001278* + ID_OUI_FROM_DATABASE=International Bar Code + +OUI:001279* + ID_OUI_FROM_DATABASE=Hewlett-Packard Company + +OUI:00127A* + ID_OUI_FROM_DATABASE=Sanyu Industry Co.,Ltd. + +OUI:00127B* + ID_OUI_FROM_DATABASE=VIA Networking Technologies, Inc. + +OUI:00127C* + ID_OUI_FROM_DATABASE=SWEGON AB + +OUI:00127D* + ID_OUI_FROM_DATABASE=MobileAria + +OUI:00127E* + ID_OUI_FROM_DATABASE=Digital Lifestyles Group, Inc. + +OUI:00127F* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001280* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001281* + ID_OUI_FROM_DATABASE=March Networks S.p.A. + +OUI:001282* + ID_OUI_FROM_DATABASE=Qovia + +OUI:001283* + ID_OUI_FROM_DATABASE=Nortel Networks + +OUI:001284* + ID_OUI_FROM_DATABASE=Lab33 Srl + +OUI:001285* + ID_OUI_FROM_DATABASE=Gizmondo Europe Ltd + +OUI:001286* + ID_OUI_FROM_DATABASE=ENDEVCO CORP + +OUI:001287* + ID_OUI_FROM_DATABASE=Digital Everywhere Unterhaltungselektronik GmbH + +OUI:001288* + ID_OUI_FROM_DATABASE=2Wire, Inc + +OUI:001289* + ID_OUI_FROM_DATABASE=Advance Sterilization Products + +OUI:00128A* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:00128B* + ID_OUI_FROM_DATABASE=Sensory Networks Inc + +OUI:00128C* + ID_OUI_FROM_DATABASE=Woodward Governor + +OUI:00128D* + ID_OUI_FROM_DATABASE=STB Datenservice GmbH + +OUI:00128E* + ID_OUI_FROM_DATABASE=Q-Free ASA + +OUI:00128F* + ID_OUI_FROM_DATABASE=Montilio + +OUI:001290* + ID_OUI_FROM_DATABASE=KYOWA Electric & Machinery Corp. + +OUI:001291* + ID_OUI_FROM_DATABASE=KWS Computersysteme GmbH + +OUI:001292* + ID_OUI_FROM_DATABASE=Griffin Technology + +OUI:001293* + ID_OUI_FROM_DATABASE=GE Energy + +OUI:001294* + ID_OUI_FROM_DATABASE=SUMITOMO ELECTRIC DEVICE INNOVATIONS, INC + +OUI:001295* + ID_OUI_FROM_DATABASE=Aiware Inc. + +OUI:001296* + ID_OUI_FROM_DATABASE=Addlogix + +OUI:001297* + ID_OUI_FROM_DATABASE=O2Micro, Inc. + +OUI:001298* + ID_OUI_FROM_DATABASE=MICO ELECTRIC(SHENZHEN) LIMITED + +OUI:001299* + ID_OUI_FROM_DATABASE=Ktech Telecommunications Inc + +OUI:00129A* + ID_OUI_FROM_DATABASE=IRT Electronics Pty Ltd + +OUI:00129B* + ID_OUI_FROM_DATABASE=E2S Electronic Engineering Solutions, S.L. + +OUI:00129C* + ID_OUI_FROM_DATABASE=Yulinet + +OUI:00129D* + ID_OUI_FROM_DATABASE=First International Computer do Brasil + +OUI:00129E* + ID_OUI_FROM_DATABASE=Surf Communications Inc. + +OUI:00129F* + ID_OUI_FROM_DATABASE=RAE Systems + +OUI:0012A0* + ID_OUI_FROM_DATABASE=NeoMeridian Sdn Bhd + +OUI:0012A1* + ID_OUI_FROM_DATABASE=BluePacket Communications Co., Ltd. + +OUI:0012A2* + ID_OUI_FROM_DATABASE=VITA + +OUI:0012A3* + ID_OUI_FROM_DATABASE=Trust International B.V. + +OUI:0012A4* + ID_OUI_FROM_DATABASE=ThingMagic, LLC + +OUI:0012A5* + ID_OUI_FROM_DATABASE=Stargen, Inc. + +OUI:0012A6* + ID_OUI_FROM_DATABASE=Dolby Australia + +OUI:0012A7* + ID_OUI_FROM_DATABASE=ISR TECHNOLOGIES Inc + +OUI:0012A8* + ID_OUI_FROM_DATABASE=intec GmbH + +OUI:0012A9* + ID_OUI_FROM_DATABASE=3Com Ltd + +OUI:0012AA* + ID_OUI_FROM_DATABASE=IEE, Inc. + +OUI:0012AB* + ID_OUI_FROM_DATABASE=WiLife, Inc. + +OUI:0012AC* + ID_OUI_FROM_DATABASE=ONTIMETEK INC. + +OUI:0012AD* + ID_OUI_FROM_DATABASE=IDS GmbH + +OUI:0012AE* + ID_OUI_FROM_DATABASE=HLS HARD-LINE Solutions Inc. + +OUI:0012AF* + ID_OUI_FROM_DATABASE=ELPRO Technologies + +OUI:0012B0* + ID_OUI_FROM_DATABASE=Efore Oyj (Plc) + +OUI:0012B1* + ID_OUI_FROM_DATABASE=Dai Nippon Printing Co., Ltd + +OUI:0012B2* + ID_OUI_FROM_DATABASE=AVOLITES LTD. + +OUI:0012B3* + ID_OUI_FROM_DATABASE=Advance Wireless Technology Corp. + +OUI:0012B4* + ID_OUI_FROM_DATABASE=Work Microwave GmbH + +OUI:0012B5* + ID_OUI_FROM_DATABASE=Vialta, Inc. + +OUI:0012B6* + ID_OUI_FROM_DATABASE=Santa Barbara Infrared, Inc. + +OUI:0012B7* + ID_OUI_FROM_DATABASE=PTW Freiburg + +OUI:0012B8* + ID_OUI_FROM_DATABASE=G2 Microsystems + +OUI:0012B9* + ID_OUI_FROM_DATABASE=Fusion Digital Technology + +OUI:0012BA* + ID_OUI_FROM_DATABASE=FSI Systems, Inc. + +OUI:0012BB* + ID_OUI_FROM_DATABASE=Telecommunications Industry Association TR-41 Committee + +OUI:0012BC* + ID_OUI_FROM_DATABASE=Echolab LLC + +OUI:0012BD* + ID_OUI_FROM_DATABASE=Avantec Manufacturing Limited + +OUI:0012BE* + ID_OUI_FROM_DATABASE=Astek Corporation + +OUI:0012BF* + ID_OUI_FROM_DATABASE=Arcadyan Technology Corporation + +OUI:0012C0* + ID_OUI_FROM_DATABASE=HotLava Systems, Inc. + +OUI:0012C1* + ID_OUI_FROM_DATABASE=Check Point Software Technologies + +OUI:0012C2* + ID_OUI_FROM_DATABASE=Apex Electronics Factory + +OUI:0012C3* + ID_OUI_FROM_DATABASE=WIT S.A. + +OUI:0012C4* + ID_OUI_FROM_DATABASE=Viseon, Inc. + +OUI:0012C5* + ID_OUI_FROM_DATABASE=V-Show Technology (China) Co.,Ltd + +OUI:0012C6* + ID_OUI_FROM_DATABASE=TGC America, Inc + +OUI:0012C7* + ID_OUI_FROM_DATABASE=SECURAY Technologies Ltd.Co. + +OUI:0012C8* + ID_OUI_FROM_DATABASE=Perfect tech + +OUI:0012C9* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:0012CA* + ID_OUI_FROM_DATABASE=Mechatronic Brick Aps + +OUI:0012CB* + ID_OUI_FROM_DATABASE=CSS Inc. + +OUI:0012CC* + ID_OUI_FROM_DATABASE=Bitatek CO., LTD + +OUI:0012CD* + ID_OUI_FROM_DATABASE=ASEM SpA + +OUI:0012CE* + ID_OUI_FROM_DATABASE=Advanced Cybernetics Group + +OUI:0012CF* + ID_OUI_FROM_DATABASE=Accton Technology Corporation + +OUI:0012D0* + ID_OUI_FROM_DATABASE=Gossen-Metrawatt-GmbH + +OUI:0012D1* + ID_OUI_FROM_DATABASE=Texas Instruments Inc + +OUI:0012D2* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:0012D3* + ID_OUI_FROM_DATABASE=Zetta Systems, Inc. + +OUI:0012D4* + ID_OUI_FROM_DATABASE=Princeton Technology, Ltd + +OUI:0012D5* + ID_OUI_FROM_DATABASE=Motion Reality Inc. + +OUI:0012D6* + ID_OUI_FROM_DATABASE=Jiangsu Yitong High-Tech Co.,Ltd + +OUI:0012D7* + ID_OUI_FROM_DATABASE=Invento Networks, Inc. + +OUI:0012D8* + ID_OUI_FROM_DATABASE=International Games System Co., Ltd. + +OUI:0012D9* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0012DA* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0012DB* + ID_OUI_FROM_DATABASE=ZIEHL industrie-elektronik GmbH + Co KG + +OUI:0012DC* + ID_OUI_FROM_DATABASE=SunCorp Industrial Limited + +OUI:0012DD* + ID_OUI_FROM_DATABASE=Shengqu Information Technology (Shanghai) Co., Ltd. + +OUI:0012DE* + ID_OUI_FROM_DATABASE=Radio Components Sweden AB + +OUI:0012DF* + ID_OUI_FROM_DATABASE=Novomatic AG + +OUI:0012E0* + ID_OUI_FROM_DATABASE=Codan Limited + +OUI:0012E1* + ID_OUI_FROM_DATABASE=Alliant Networks, Inc + +OUI:0012E2* + ID_OUI_FROM_DATABASE=ALAXALA Networks Corporation + +OUI:0012E3* + ID_OUI_FROM_DATABASE=Agat-RT, Ltd. + +OUI:0012E4* + ID_OUI_FROM_DATABASE=ZIEHL industrie-electronik GmbH + Co KG + +OUI:0012E5* + ID_OUI_FROM_DATABASE=Time America, Inc. + +OUI:0012E6* + ID_OUI_FROM_DATABASE=SPECTEC COMPUTER CO., LTD. + +OUI:0012E7* + ID_OUI_FROM_DATABASE=Projectek Networking Electronics Corp. + +OUI:0012E8* + ID_OUI_FROM_DATABASE=Fraunhofer IMS + +OUI:0012E9* + ID_OUI_FROM_DATABASE=Abbey Systems Ltd + +OUI:0012EA* + ID_OUI_FROM_DATABASE=Trane + +OUI:0012EB* + ID_OUI_FROM_DATABASE=R2DI, LLC + +OUI:0012EC* + ID_OUI_FROM_DATABASE=Movacolor b.v. + +OUI:0012ED* + ID_OUI_FROM_DATABASE=AVG Advanced Technologies + +OUI:0012EE* + ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications AB + +OUI:0012EF* + ID_OUI_FROM_DATABASE=OneAccess SA + +OUI:0012F0* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:0012F1* + ID_OUI_FROM_DATABASE=IFOTEC + +OUI:0012F2* + ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc + +OUI:0012F3* + ID_OUI_FROM_DATABASE=connectBlue AB + +OUI:0012F4* + ID_OUI_FROM_DATABASE=Belco International Co.,Ltd. + +OUI:0012F5* + ID_OUI_FROM_DATABASE=Imarda New Zealand Limited + +OUI:0012F6* + ID_OUI_FROM_DATABASE=MDK CO.,LTD. + +OUI:0012F7* + ID_OUI_FROM_DATABASE=Xiamen Xinglian Electronics Co., Ltd. + +OUI:0012F8* + ID_OUI_FROM_DATABASE=WNI Resources, LLC + +OUI:0012F9* + ID_OUI_FROM_DATABASE=URYU SEISAKU, LTD. + +OUI:0012FA* + ID_OUI_FROM_DATABASE=THX LTD + +OUI:0012FB* + ID_OUI_FROM_DATABASE=Samsung Electronics + +OUI:0012FC* + ID_OUI_FROM_DATABASE=PLANET System Co.,LTD + +OUI:0012FD* + ID_OUI_FROM_DATABASE=OPTIMUS IC S.A. + +OUI:0012FE* + ID_OUI_FROM_DATABASE=Lenovo Mobile Communication Technology Ltd. + +OUI:0012FF* + ID_OUI_FROM_DATABASE=Lely Industries N.V. + +OUI:001300* + ID_OUI_FROM_DATABASE=IT-FACTORY, INC. + +OUI:001301* + ID_OUI_FROM_DATABASE=IronGate S.L. + +OUI:001302* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:001303* + ID_OUI_FROM_DATABASE=GateConnect Technologies GmbH + +OUI:001304* + ID_OUI_FROM_DATABASE=Flaircomm Technologies Co. LTD + +OUI:001305* + ID_OUI_FROM_DATABASE=Epicom, Inc. + +OUI:001306* + ID_OUI_FROM_DATABASE=Always On Wireless + +OUI:001307* + ID_OUI_FROM_DATABASE=Paravirtual Corporation + +OUI:001308* + ID_OUI_FROM_DATABASE=Nuvera Fuel Cells + +OUI:001309* + ID_OUI_FROM_DATABASE=Ocean Broadband Networks + +OUI:00130A* + ID_OUI_FROM_DATABASE=Nortel + +OUI:00130B* + ID_OUI_FROM_DATABASE=Mextal B.V. + +OUI:00130C* + ID_OUI_FROM_DATABASE=HF System Corporation + +OUI:00130D* + ID_OUI_FROM_DATABASE=GALILEO AVIONICA + +OUI:00130E* + ID_OUI_FROM_DATABASE=Focusrite Audio Engineering Limited + +OUI:00130F* + ID_OUI_FROM_DATABASE=EGEMEN Bilgisayar Muh San ve Tic LTD STI + +OUI:001310* + ID_OUI_FROM_DATABASE=Cisco-Linksys, LLC + +OUI:001311* + ID_OUI_FROM_DATABASE=ARRIS International + +OUI:001312* + ID_OUI_FROM_DATABASE=Amedia Networks Inc. + +OUI:001313* + ID_OUI_FROM_DATABASE=GuangZhou Post & Telecom Equipment ltd + +OUI:001314* + ID_OUI_FROM_DATABASE=Asiamajor Inc. + +OUI:001315* + ID_OUI_FROM_DATABASE=SONY Computer Entertainment inc, + +OUI:001316* + ID_OUI_FROM_DATABASE=L-S-B Broadcast Technologies GmbH + +OUI:001317* + ID_OUI_FROM_DATABASE=GN Netcom as + +OUI:001318* + ID_OUI_FROM_DATABASE=DGSTATION Co., Ltd. + +OUI:001319* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00131A* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00131B* + ID_OUI_FROM_DATABASE=BeCell Innovations Corp. + +OUI:00131C* + ID_OUI_FROM_DATABASE=LiteTouch, Inc. + +OUI:00131D* + ID_OUI_FROM_DATABASE=Scanvaegt International A/S + +OUI:00131E* + ID_OUI_FROM_DATABASE=Peiker acustic GmbH & Co. KG + +OUI:00131F* + ID_OUI_FROM_DATABASE=NxtPhase T&D, Corp. + +OUI:001320* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:001321* + ID_OUI_FROM_DATABASE=Hewlett-Packard Company + +OUI:001322* + ID_OUI_FROM_DATABASE=DAQ Electronics, Inc. + +OUI:001323* + ID_OUI_FROM_DATABASE=Cap Co., Ltd. + +OUI:001324* + ID_OUI_FROM_DATABASE=Schneider Electric Ultra Terminal + +OUI:001325* + ID_OUI_FROM_DATABASE=Cortina Systems Inc + +OUI:001326* + ID_OUI_FROM_DATABASE=ECM Systems Ltd + +OUI:001327* + ID_OUI_FROM_DATABASE=Data Acquisitions limited + +OUI:001328* + ID_OUI_FROM_DATABASE=Westech Korea Inc., + +OUI:001329* + ID_OUI_FROM_DATABASE=VSST Co., LTD + +OUI:00132A* + ID_OUI_FROM_DATABASE=Sitronics Telecom Solutions + +OUI:00132B* + ID_OUI_FROM_DATABASE=Phoenix Digital + +OUI:00132C* + ID_OUI_FROM_DATABASE=MAZ Brandenburg GmbH + +OUI:00132D* + ID_OUI_FROM_DATABASE=iWise Communications + +OUI:00132E* + ID_OUI_FROM_DATABASE=ITian Coporation + +OUI:00132F* + ID_OUI_FROM_DATABASE=Interactek + +OUI:001330* + ID_OUI_FROM_DATABASE=EURO PROTECTION SURVEILLANCE + +OUI:001331* + ID_OUI_FROM_DATABASE=CellPoint Connect + +OUI:001332* + ID_OUI_FROM_DATABASE=Beijing Topsec Network Security Technology Co., Ltd. + +OUI:001333* + ID_OUI_FROM_DATABASE=BaudTec Corporation + +OUI:001334* + ID_OUI_FROM_DATABASE=Arkados, Inc. + +OUI:001335* + ID_OUI_FROM_DATABASE=VS Industry Berhad + +OUI:001336* + ID_OUI_FROM_DATABASE=Tianjin 712 Communication Broadcasting co., ltd. + +OUI:001337* + ID_OUI_FROM_DATABASE=Orient Power Home Network Ltd. + +OUI:001338* + ID_OUI_FROM_DATABASE=FRESENIUS-VIAL + +OUI:001339* + ID_OUI_FROM_DATABASE=EL-ME AG + +OUI:00133A* + ID_OUI_FROM_DATABASE=VadaTech Inc. + +OUI:00133B* + ID_OUI_FROM_DATABASE=Speed Dragon Multimedia Limited + +OUI:00133C* + ID_OUI_FROM_DATABASE=QUINTRON SYSTEMS INC. + +OUI:00133D* + ID_OUI_FROM_DATABASE=Micro Memory Curtiss Wright Co + +OUI:00133E* + ID_OUI_FROM_DATABASE=MetaSwitch + +OUI:00133F* + ID_OUI_FROM_DATABASE=Eppendorf Instrumente GmbH + +OUI:001340* + ID_OUI_FROM_DATABASE=AD.EL s.r.l. + +OUI:001341* + ID_OUI_FROM_DATABASE=Shandong New Beiyang Information Technology Co.,Ltd + +OUI:001342* + ID_OUI_FROM_DATABASE=Vision Research, Inc. + +OUI:001343* + ID_OUI_FROM_DATABASE=Matsushita Electronic Components (Europe) GmbH + +OUI:001344* + ID_OUI_FROM_DATABASE=Fargo Electronics Inc. + +OUI:001345* + ID_OUI_FROM_DATABASE=Eaton Corporation + +OUI:001346* + ID_OUI_FROM_DATABASE=D-Link Corporation + +OUI:001347* + ID_OUI_FROM_DATABASE=BlueTree Wireless Data Inc. + +OUI:001348* + ID_OUI_FROM_DATABASE=Artila Electronics Co., Ltd. + +OUI:001349* + ID_OUI_FROM_DATABASE=ZyXEL Communications Corporation + +OUI:00134A* + ID_OUI_FROM_DATABASE=Engim, Inc. + +OUI:00134B* + ID_OUI_FROM_DATABASE=ToGoldenNet Technology Inc. + +OUI:00134C* + ID_OUI_FROM_DATABASE=YDT Technology International + +OUI:00134D* + ID_OUI_FROM_DATABASE=Inepro BV + +OUI:00134E* + ID_OUI_FROM_DATABASE=Valox Systems, Inc. + +OUI:00134F* + ID_OUI_FROM_DATABASE=Tranzeo Wireless Technologies Inc. + +OUI:001350* + ID_OUI_FROM_DATABASE=Silver Spring Networks, Inc + +OUI:001351* + ID_OUI_FROM_DATABASE=Niles Audio Corporation + +OUI:001352* + ID_OUI_FROM_DATABASE=Naztec, Inc. + +OUI:001353* + ID_OUI_FROM_DATABASE=HYDAC Filtertechnik GMBH + +OUI:001354* + ID_OUI_FROM_DATABASE=Zcomax Technologies, Inc. + +OUI:001355* + ID_OUI_FROM_DATABASE=TOMEN Cyber-business Solutions, Inc. + +OUI:001356* + ID_OUI_FROM_DATABASE=FLIR Radiation Inc + +OUI:001357* + ID_OUI_FROM_DATABASE=Soyal Technology Co., Ltd. + +OUI:001358* + ID_OUI_FROM_DATABASE=Realm Systems, Inc. + +OUI:001359* + ID_OUI_FROM_DATABASE=ProTelevision Technologies A/S + +OUI:00135A* + ID_OUI_FROM_DATABASE=Project T&E Limited + +OUI:00135B* + ID_OUI_FROM_DATABASE=PanelLink Cinema, LLC + +OUI:00135C* + ID_OUI_FROM_DATABASE=OnSite Systems, Inc. + +OUI:00135D* + ID_OUI_FROM_DATABASE=NTTPC Communications, Inc. + +OUI:00135E* + ID_OUI_FROM_DATABASE=EAB/RWI/K + +OUI:00135F* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001360* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001361* + ID_OUI_FROM_DATABASE=Biospace Co., Ltd. + +OUI:001362* + ID_OUI_FROM_DATABASE=ShinHeung Precision Co., Ltd. + +OUI:001363* + ID_OUI_FROM_DATABASE=Verascape, Inc. + +OUI:001364* + ID_OUI_FROM_DATABASE=Paradigm Technology Inc.. + +OUI:001365* + ID_OUI_FROM_DATABASE=Nortel + +OUI:001366* + ID_OUI_FROM_DATABASE=Neturity Technologies Inc. + +OUI:001367* + ID_OUI_FROM_DATABASE=Narayon. Co., Ltd. + +OUI:001368* + ID_OUI_FROM_DATABASE=Maersk Data Defence + +OUI:001369* + ID_OUI_FROM_DATABASE=Honda Electron Co., LED. + +OUI:00136A* + ID_OUI_FROM_DATABASE=Hach Lange SA + +OUI:00136B* + ID_OUI_FROM_DATABASE=E-TEC + +OUI:00136C* + ID_OUI_FROM_DATABASE=TomTom + +OUI:00136D* + ID_OUI_FROM_DATABASE=Tentaculus AB + +OUI:00136E* + ID_OUI_FROM_DATABASE=Techmetro Corp. + +OUI:00136F* + ID_OUI_FROM_DATABASE=PacketMotion, Inc. + +OUI:001370* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:001371* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:001372* + ID_OUI_FROM_DATABASE=Dell Inc. + +OUI:001373* + ID_OUI_FROM_DATABASE=BLwave Electronics Co., Ltd + +OUI:001374* + ID_OUI_FROM_DATABASE=Atheros Communications, Inc. + +OUI:001375* + ID_OUI_FROM_DATABASE=American Security Products Co. + +OUI:001376* + ID_OUI_FROM_DATABASE=Tabor Electronics Ltd. + +OUI:001377* + ID_OUI_FROM_DATABASE=Samsung Electronics CO., LTD + +OUI:001378* + ID_OUI_FROM_DATABASE=QSAN Technology, Inc. + +OUI:001379* + ID_OUI_FROM_DATABASE=PONDER INFORMATION INDUSTRIES LTD. + +OUI:00137A* + ID_OUI_FROM_DATABASE=Netvox Technology Co., Ltd. + +OUI:00137B* + ID_OUI_FROM_DATABASE=Movon Corporation + +OUI:00137C* + ID_OUI_FROM_DATABASE=Kaicom co., Ltd. + +OUI:00137D* + ID_OUI_FROM_DATABASE=Dynalab, Inc. + +OUI:00137E* + ID_OUI_FROM_DATABASE=CorEdge Networks, Inc. + +OUI:00137F* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001380* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001381* + ID_OUI_FROM_DATABASE=CHIPS & Systems, Inc. + +OUI:001382* + ID_OUI_FROM_DATABASE=Cetacea Networks Corporation + +OUI:001383* + ID_OUI_FROM_DATABASE=Application Technologies and Engineering Research Laboratory + +OUI:001384* + ID_OUI_FROM_DATABASE=Advanced Motion Controls + +OUI:001385* + ID_OUI_FROM_DATABASE=Add-On Technology Co., LTD. + +OUI:001386* + ID_OUI_FROM_DATABASE=ABB Inc./Totalflow + +OUI:001387* + ID_OUI_FROM_DATABASE=27M Technologies AB + +OUI:001388* + ID_OUI_FROM_DATABASE=WiMedia Alliance + +OUI:001389* + ID_OUI_FROM_DATABASE=Redes de Telefonía Móvil S.A. + +OUI:00138A* + ID_OUI_FROM_DATABASE=QINGDAO GOERTEK ELECTRONICS CO.,LTD. + +OUI:00138B* + ID_OUI_FROM_DATABASE=Phantom Technologies LLC + +OUI:00138C* + ID_OUI_FROM_DATABASE=Kumyoung.Co.Ltd + +OUI:00138D* + ID_OUI_FROM_DATABASE=Kinghold + +OUI:00138E* + ID_OUI_FROM_DATABASE=FOAB Elektronik AB + +OUI:00138F* + ID_OUI_FROM_DATABASE=Asiarock Incorporation + +OUI:001390* + ID_OUI_FROM_DATABASE=Termtek Computer Co., Ltd + +OUI:001391* + ID_OUI_FROM_DATABASE=OUEN CO.,LTD. + +OUI:001392* + ID_OUI_FROM_DATABASE=Ruckus Wireless + +OUI:001393* + ID_OUI_FROM_DATABASE=Panta Systems, Inc. + +OUI:001394* + ID_OUI_FROM_DATABASE=Infohand Co.,Ltd + +OUI:001395* + ID_OUI_FROM_DATABASE=congatec AG + +OUI:001396* + ID_OUI_FROM_DATABASE=Acbel Polytech Inc. + +OUI:001397* + ID_OUI_FROM_DATABASE=Oracle Corporation + +OUI:001398* + ID_OUI_FROM_DATABASE=TrafficSim Co.,Ltd + +OUI:001399* + ID_OUI_FROM_DATABASE=STAC Corporation. + +OUI:00139A* + ID_OUI_FROM_DATABASE=K-ubique ID Corp. + +OUI:00139B* + ID_OUI_FROM_DATABASE=ioIMAGE Ltd. + +OUI:00139C* + ID_OUI_FROM_DATABASE=Exavera Technologies, Inc. + +OUI:00139D* + ID_OUI_FROM_DATABASE=Marvell Hispana S.L. + +OUI:00139E* + ID_OUI_FROM_DATABASE=Ciara Technologies Inc. + +OUI:00139F* + ID_OUI_FROM_DATABASE=Electronics Design Services, Co., Ltd. + +OUI:0013A0* + ID_OUI_FROM_DATABASE=ALGOSYSTEM Co., Ltd. + +OUI:0013A1* + ID_OUI_FROM_DATABASE=Crow Electronic Engeneering + +OUI:0013A2* + ID_OUI_FROM_DATABASE=MaxStream, Inc + +OUI:0013A3* + ID_OUI_FROM_DATABASE=Siemens Com CPE Devices + +OUI:0013A4* + ID_OUI_FROM_DATABASE=KeyEye Communications + +OUI:0013A5* + ID_OUI_FROM_DATABASE=General Solutions, LTD. + +OUI:0013A6* + ID_OUI_FROM_DATABASE=Extricom Ltd + +OUI:0013A7* + ID_OUI_FROM_DATABASE=BATTELLE MEMORIAL INSTITUTE + +OUI:0013A8* + ID_OUI_FROM_DATABASE=Tanisys Technology + +OUI:0013A9* + ID_OUI_FROM_DATABASE=Sony Corporation + +OUI:0013AA* + ID_OUI_FROM_DATABASE=ALS & TEC Ltd. + +OUI:0013AB* + ID_OUI_FROM_DATABASE=Telemotive AG + +OUI:0013AC* + ID_OUI_FROM_DATABASE=Sunmyung Electronics Co., LTD + +OUI:0013AD* + ID_OUI_FROM_DATABASE=Sendo Ltd + +OUI:0013AE* + ID_OUI_FROM_DATABASE=Radiance Technologies, Inc. + +OUI:0013AF* + ID_OUI_FROM_DATABASE=NUMA Technology,Inc. + +OUI:0013B0* + ID_OUI_FROM_DATABASE=Jablotron + +OUI:0013B1* + ID_OUI_FROM_DATABASE=Intelligent Control Systems (Asia) Pte Ltd + +OUI:0013B2* + ID_OUI_FROM_DATABASE=Carallon Limited + +OUI:0013B3* + ID_OUI_FROM_DATABASE=Ecom Communications Technology Co., Ltd. + +OUI:0013B4* + ID_OUI_FROM_DATABASE=Appear TV + +OUI:0013B5* + ID_OUI_FROM_DATABASE=Wavesat + +OUI:0013B6* + ID_OUI_FROM_DATABASE=Sling Media, Inc. + +OUI:0013B7* + ID_OUI_FROM_DATABASE=Scantech ID + +OUI:0013B8* + ID_OUI_FROM_DATABASE=RyCo Electronic Systems Limited + +OUI:0013B9* + ID_OUI_FROM_DATABASE=BM SPA + +OUI:0013BA* + ID_OUI_FROM_DATABASE=ReadyLinks Inc + +OUI:0013BB* + ID_OUI_FROM_DATABASE=Smartvue Corporation + +OUI:0013BC* + ID_OUI_FROM_DATABASE=Artimi Ltd + +OUI:0013BD* + ID_OUI_FROM_DATABASE=HYMATOM SA + +OUI:0013BE* + ID_OUI_FROM_DATABASE=Virtual Conexions + +OUI:0013BF* + ID_OUI_FROM_DATABASE=Media System Planning Corp. + +OUI:0013C0* + ID_OUI_FROM_DATABASE=Trix Tecnologia Ltda. + +OUI:0013C1* + ID_OUI_FROM_DATABASE=Asoka USA Corporation + +OUI:0013C2* + ID_OUI_FROM_DATABASE=WACOM Co.,Ltd + +OUI:0013C3* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0013C4* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0013C5* + ID_OUI_FROM_DATABASE=LIGHTRON FIBER-OPTIC DEVICES INC. + +OUI:0013C6* + ID_OUI_FROM_DATABASE=OpenGear, Inc + +OUI:0013C7* + ID_OUI_FROM_DATABASE=IONOS Co.,Ltd. + +OUI:0013C8* + ID_OUI_FROM_DATABASE=ADB Broadband Italia + +OUI:0013C9* + ID_OUI_FROM_DATABASE=Beyond Achieve Enterprises Ltd. + +OUI:0013CA* + ID_OUI_FROM_DATABASE=Pico Digital + +OUI:0013CB* + ID_OUI_FROM_DATABASE=Zenitel Norway AS + +OUI:0013CC* + ID_OUI_FROM_DATABASE=Tall Maple Systems + +OUI:0013CD* + ID_OUI_FROM_DATABASE=MTI co. LTD + +OUI:0013CE* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:0013CF* + ID_OUI_FROM_DATABASE=4Access Communications + +OUI:0013D0* + ID_OUI_FROM_DATABASE=t+ Medical Ltd + +OUI:0013D1* + ID_OUI_FROM_DATABASE=KIRK telecom A/S + +OUI:0013D2* + ID_OUI_FROM_DATABASE=PAGE IBERICA, S.A. + +OUI:0013D3* + ID_OUI_FROM_DATABASE=MICRO-STAR INTERNATIONAL CO., LTD. + +OUI:0013D4* + ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. + +OUI:0013D5* + ID_OUI_FROM_DATABASE=RuggedCom + +OUI:0013D6* + ID_OUI_FROM_DATABASE=TII NETWORK TECHNOLOGIES, INC. + +OUI:0013D7* + ID_OUI_FROM_DATABASE=SPIDCOM Technologies SA + +OUI:0013D8* + ID_OUI_FROM_DATABASE=Princeton Instruments + +OUI:0013D9* + ID_OUI_FROM_DATABASE=Matrix Product Development, Inc. + +OUI:0013DA* + ID_OUI_FROM_DATABASE=Diskware Co., Ltd + +OUI:0013DB* + ID_OUI_FROM_DATABASE=SHOEI Electric Co.,Ltd + +OUI:0013DC* + ID_OUI_FROM_DATABASE=IBTEK INC. + +OUI:0013DD* + ID_OUI_FROM_DATABASE=Abbott Diagnostics + +OUI:0013DE* + ID_OUI_FROM_DATABASE=Adapt4, LLC + +OUI:0013DF* + ID_OUI_FROM_DATABASE=Ryvor Corp. + +OUI:0013E0* + ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd. + +OUI:0013E1* + ID_OUI_FROM_DATABASE=Iprobe AB + +OUI:0013E2* + ID_OUI_FROM_DATABASE=GeoVision Inc. + +OUI:0013E3* + ID_OUI_FROM_DATABASE=CoVi Technologies, Inc. + +OUI:0013E4* + ID_OUI_FROM_DATABASE=YANGJAE SYSTEMS CORP. + +OUI:0013E5* + ID_OUI_FROM_DATABASE=TENOSYS, INC. + +OUI:0013E6* + ID_OUI_FROM_DATABASE=Technolution + +OUI:0013E7* + ID_OUI_FROM_DATABASE=Halcro + +OUI:0013E8* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:0013E9* + ID_OUI_FROM_DATABASE=VeriWave, Inc. + +OUI:0013EA* + ID_OUI_FROM_DATABASE=Kamstrup A/S + +OUI:0013EB* + ID_OUI_FROM_DATABASE=Sysmaster Corporation + +OUI:0013EC* + ID_OUI_FROM_DATABASE=Sunbay Software AG + +OUI:0013ED* + ID_OUI_FROM_DATABASE=PSIA + +OUI:0013EE* + ID_OUI_FROM_DATABASE=JBX Designs Inc. + +OUI:0013EF* + ID_OUI_FROM_DATABASE=Kingjon Digital Technology Co.,Ltd + +OUI:0013F0* + ID_OUI_FROM_DATABASE=Wavefront Semiconductor + +OUI:0013F1* + ID_OUI_FROM_DATABASE=AMOD Technology Co., Ltd. + +OUI:0013F2* + ID_OUI_FROM_DATABASE=Klas Ltd + +OUI:0013F3* + ID_OUI_FROM_DATABASE=Giga-byte Communications Inc. + +OUI:0013F4* + ID_OUI_FROM_DATABASE=Psitek (Pty) Ltd + +OUI:0013F5* + ID_OUI_FROM_DATABASE=Akimbi Systems + +OUI:0013F6* + ID_OUI_FROM_DATABASE=Cintech + +OUI:0013F7* + ID_OUI_FROM_DATABASE=SMC Networks, Inc. + +OUI:0013F8* + ID_OUI_FROM_DATABASE=Dex Security Solutions + +OUI:0013F9* + ID_OUI_FROM_DATABASE=Cavera Systems + +OUI:0013FA* + ID_OUI_FROM_DATABASE=LifeSize Communications, Inc + +OUI:0013FB* + ID_OUI_FROM_DATABASE=RKC INSTRUMENT INC. + +OUI:0013FC* + ID_OUI_FROM_DATABASE=SiCortex, Inc + +OUI:0013FD* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:0013FE* + ID_OUI_FROM_DATABASE=GRANDTEC ELECTRONIC CORP. + +OUI:0013FF* + ID_OUI_FROM_DATABASE=Dage-MTI of MC, Inc. + +OUI:001400* + ID_OUI_FROM_DATABASE=MINERVA KOREA CO., LTD + +OUI:001401* + ID_OUI_FROM_DATABASE=Rivertree Networks Corp. + +OUI:001402* + ID_OUI_FROM_DATABASE=kk-electronic a/s + +OUI:001403* + ID_OUI_FROM_DATABASE=Renasis, LLC + +OUI:001404* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:001405* + ID_OUI_FROM_DATABASE=OpenIB, Inc. + +OUI:001406* + ID_OUI_FROM_DATABASE=Go Networks + +OUI:001407* + ID_OUI_FROM_DATABASE=Sperian Protection Instrumentation + +OUI:001408* + ID_OUI_FROM_DATABASE=Eka Systems Inc. + +OUI:001409* + ID_OUI_FROM_DATABASE=MAGNETI MARELLI S.E. S.p.A. + +OUI:00140A* + ID_OUI_FROM_DATABASE=WEPIO Co., Ltd. + +OUI:00140B* + ID_OUI_FROM_DATABASE=FIRST INTERNATIONAL COMPUTER, INC. + +OUI:00140C* + ID_OUI_FROM_DATABASE=GKB CCTV CO., LTD. + +OUI:00140D* + ID_OUI_FROM_DATABASE=Nortel + +OUI:00140E* + ID_OUI_FROM_DATABASE=Nortel + +OUI:00140F* + ID_OUI_FROM_DATABASE=Federal State Unitary Enterprise Leningrad R&D Institute of + +OUI:001410* + ID_OUI_FROM_DATABASE=Suzhou Keda Technology CO.,Ltd + +OUI:001411* + ID_OUI_FROM_DATABASE=Deutschmann Automation GmbH & Co. KG + +OUI:001412* + ID_OUI_FROM_DATABASE=S-TEC electronics AG + +OUI:001413* + ID_OUI_FROM_DATABASE=Trebing & Himstedt Prozeßautomation GmbH & Co. KG + +OUI:001414* + ID_OUI_FROM_DATABASE=Jumpnode Systems LLC. + +OUI:001415* + ID_OUI_FROM_DATABASE=Intec Automation Inc. + +OUI:001416* + ID_OUI_FROM_DATABASE=Scosche Industries, Inc. + +OUI:001417* + ID_OUI_FROM_DATABASE=RSE Informations Technologie GmbH + +OUI:001418* + ID_OUI_FROM_DATABASE=C4Line + +OUI:001419* + ID_OUI_FROM_DATABASE=SIDSA + +OUI:00141A* + ID_OUI_FROM_DATABASE=DEICY CORPORATION + +OUI:00141B* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00141C* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00141D* + ID_OUI_FROM_DATABASE=Lust Antriebstechnik GmbH + +OUI:00141E* + ID_OUI_FROM_DATABASE=P.A. Semi, Inc. + +OUI:00141F* + ID_OUI_FROM_DATABASE=SunKwang Electronics Co., Ltd + +OUI:001420* + ID_OUI_FROM_DATABASE=G-Links networking company + +OUI:001421* + ID_OUI_FROM_DATABASE=Total Wireless Technologies Pte. Ltd. + +OUI:001422* + ID_OUI_FROM_DATABASE=Dell Inc. + +OUI:001423* + ID_OUI_FROM_DATABASE=J-S Co. NEUROCOM + +OUI:001424* + ID_OUI_FROM_DATABASE=Merry Electrics CO., LTD. + +OUI:001425* + ID_OUI_FROM_DATABASE=Galactic Computing Corp. + +OUI:001426* + ID_OUI_FROM_DATABASE=NL Technology + +OUI:001427* + ID_OUI_FROM_DATABASE=JazzMutant + +OUI:001428* + ID_OUI_FROM_DATABASE=Vocollect, Inc + +OUI:001429* + ID_OUI_FROM_DATABASE=V Center Technologies Co., Ltd. + +OUI:00142A* + ID_OUI_FROM_DATABASE=Elitegroup Computer System Co., Ltd + +OUI:00142B* + ID_OUI_FROM_DATABASE=Edata Communication Inc. + +OUI:00142C* + ID_OUI_FROM_DATABASE=Koncept International, Inc. + +OUI:00142D* + ID_OUI_FROM_DATABASE=Toradex AG + +OUI:00142E* + ID_OUI_FROM_DATABASE=77 Elektronika Kft. + +OUI:00142F* + ID_OUI_FROM_DATABASE=WildPackets + +OUI:001430* + ID_OUI_FROM_DATABASE=ViPowER, Inc + +OUI:001431* + ID_OUI_FROM_DATABASE=PDL Electronics Ltd + +OUI:001432* + ID_OUI_FROM_DATABASE=Tarallax Wireless, Inc. + +OUI:001433* + ID_OUI_FROM_DATABASE=Empower Technologies(Canada) Inc. + +OUI:001434* + ID_OUI_FROM_DATABASE=Keri Systems, Inc + +OUI:001435* + ID_OUI_FROM_DATABASE=CityCom Corp. + +OUI:001436* + ID_OUI_FROM_DATABASE=Qwerty Elektronik AB + +OUI:001437* + ID_OUI_FROM_DATABASE=GSTeletech Co.,Ltd. + +OUI:001438* + ID_OUI_FROM_DATABASE=Hewlett-Packard Company + +OUI:001439* + ID_OUI_FROM_DATABASE=Blonder Tongue Laboratories, Inc. + +OUI:00143A* + ID_OUI_FROM_DATABASE=RAYTALK INTERNATIONAL SRL + +OUI:00143B* + ID_OUI_FROM_DATABASE=Sensovation AG + +OUI:00143C* + ID_OUI_FROM_DATABASE=Rheinmetall Canada Inc. + +OUI:00143D* + ID_OUI_FROM_DATABASE=Aevoe Inc. + +OUI:00143E* + ID_OUI_FROM_DATABASE=AirLink Communications, Inc. + +OUI:00143F* + ID_OUI_FROM_DATABASE=Hotway Technology Corporation + +OUI:001440* + ID_OUI_FROM_DATABASE=ATOMIC Corporation + +OUI:001441* + ID_OUI_FROM_DATABASE=Innovation Sound Technology Co., LTD. + +OUI:001442* + ID_OUI_FROM_DATABASE=ATTO CORPORATION + +OUI:001443* + ID_OUI_FROM_DATABASE=Consultronics Europe Ltd + +OUI:001444* + ID_OUI_FROM_DATABASE=Grundfos Electronics + +OUI:001445* + ID_OUI_FROM_DATABASE=Telefon-Gradnja d.o.o. + +OUI:001446* + ID_OUI_FROM_DATABASE=SuperVision Solutions LLC + +OUI:001447* + ID_OUI_FROM_DATABASE=BOAZ Inc. + +OUI:001448* + ID_OUI_FROM_DATABASE=Inventec Multimedia & Telecom Corporation + +OUI:001449* + ID_OUI_FROM_DATABASE=Sichuan Changhong Electric Ltd. + +OUI:00144A* + ID_OUI_FROM_DATABASE=Taiwan Thick-Film Ind. Corp. + +OUI:00144B* + ID_OUI_FROM_DATABASE=Hifn, Inc. + +OUI:00144C* + ID_OUI_FROM_DATABASE=General Meters Corp. + +OUI:00144D* + ID_OUI_FROM_DATABASE=Intelligent Systems + +OUI:00144E* + ID_OUI_FROM_DATABASE=SRISA + +OUI:00144F* + ID_OUI_FROM_DATABASE=Oracle Corporation + +OUI:001450* + ID_OUI_FROM_DATABASE=Heim Systems GmbH + +OUI:001451* + ID_OUI_FROM_DATABASE=Apple Computer Inc. + +OUI:001452* + ID_OUI_FROM_DATABASE=CALCULEX,INC. + +OUI:001453* + ID_OUI_FROM_DATABASE=ADVANTECH TECHNOLOGIES CO.,LTD + +OUI:001454* + ID_OUI_FROM_DATABASE=Symwave + +OUI:001455* + ID_OUI_FROM_DATABASE=Coder Electronics Corporation + +OUI:001456* + ID_OUI_FROM_DATABASE=Edge Products + +OUI:001457* + ID_OUI_FROM_DATABASE=T-VIPS AS + +OUI:001458* + ID_OUI_FROM_DATABASE=HS Automatic ApS + +OUI:001459* + ID_OUI_FROM_DATABASE=Moram Co., Ltd. + +OUI:00145A* + ID_OUI_FROM_DATABASE=Neratec AG + +OUI:00145B* + ID_OUI_FROM_DATABASE=SeekerNet Inc. + +OUI:00145C* + ID_OUI_FROM_DATABASE=Intronics B.V. + +OUI:00145D* + ID_OUI_FROM_DATABASE=WJ Communications, Inc. + +OUI:00145E* + ID_OUI_FROM_DATABASE=IBM Corp + +OUI:00145F* + ID_OUI_FROM_DATABASE=ADITEC CO. LTD + +OUI:001460* + ID_OUI_FROM_DATABASE=Kyocera Wireless Corp. + +OUI:001461* + ID_OUI_FROM_DATABASE=CORONA CORPORATION + +OUI:001462* + ID_OUI_FROM_DATABASE=Digiwell Technology, inc + +OUI:001463* + ID_OUI_FROM_DATABASE=IDCS N.V. + +OUI:001464* + ID_OUI_FROM_DATABASE=Cryptosoft + +OUI:001465* + ID_OUI_FROM_DATABASE=Novo Nordisk A/S + +OUI:001466* + ID_OUI_FROM_DATABASE=Kleinhenz Elektronik GmbH + +OUI:001467* + ID_OUI_FROM_DATABASE=ArrowSpan Inc. + +OUI:001468* + ID_OUI_FROM_DATABASE=CelPlan International, Inc. + +OUI:001469* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00146A* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00146B* + ID_OUI_FROM_DATABASE=Anagran, Inc. + +OUI:00146C* + ID_OUI_FROM_DATABASE=Netgear Inc. + +OUI:00146D* + ID_OUI_FROM_DATABASE=RF Technologies + +OUI:00146E* + ID_OUI_FROM_DATABASE=H. Stoll GmbH & Co. KG + +OUI:00146F* + ID_OUI_FROM_DATABASE=Kohler Co + +OUI:001470* + ID_OUI_FROM_DATABASE=Prokom Software SA + +OUI:001471* + ID_OUI_FROM_DATABASE=Eastern Asia Technology Limited + +OUI:001472* + ID_OUI_FROM_DATABASE=China Broadband Wireless IP Standard Group + +OUI:001473* + ID_OUI_FROM_DATABASE=Bookham Inc + +OUI:001474* + ID_OUI_FROM_DATABASE=K40 Electronics + +OUI:001475* + ID_OUI_FROM_DATABASE=Wiline Networks, Inc. + +OUI:001476* + ID_OUI_FROM_DATABASE=MultiCom Industries Limited + +OUI:001477* + ID_OUI_FROM_DATABASE=Nertec Inc. + +OUI:001478* + ID_OUI_FROM_DATABASE=ShenZhen TP-LINK Technologies Co., Ltd. + +OUI:001479* + ID_OUI_FROM_DATABASE=NEC Magnus Communications,Ltd. + +OUI:00147A* + ID_OUI_FROM_DATABASE=Eubus GmbH + +OUI:00147B* + ID_OUI_FROM_DATABASE=Iteris, Inc. + +OUI:00147C* + ID_OUI_FROM_DATABASE=3Com Ltd + +OUI:00147D* + ID_OUI_FROM_DATABASE=Aeon Digital International + +OUI:00147E* + ID_OUI_FROM_DATABASE=InnerWireless + +OUI:00147F* + ID_OUI_FROM_DATABASE=Thomson Telecom Belgium + +OUI:001480* + ID_OUI_FROM_DATABASE=Hitachi-LG Data Storage Korea, Inc + +OUI:001481* + ID_OUI_FROM_DATABASE=Multilink Inc + +OUI:001482* + ID_OUI_FROM_DATABASE=GoBackTV, Inc + +OUI:001483* + ID_OUI_FROM_DATABASE=eXS Inc. + +OUI:001484* + ID_OUI_FROM_DATABASE=Cermate Technologies Inc. + +OUI:001485* + ID_OUI_FROM_DATABASE=Giga-Byte + +OUI:001486* + ID_OUI_FROM_DATABASE=Echo Digital Audio Corporation + +OUI:001487* + ID_OUI_FROM_DATABASE=American Technology Integrators + +OUI:001488* + ID_OUI_FROM_DATABASE=Akorri + +OUI:001489* + ID_OUI_FROM_DATABASE=B15402100 - JANDEI, S.L. + +OUI:00148A* + ID_OUI_FROM_DATABASE=Elin Ebg Traction Gmbh + +OUI:00148B* + ID_OUI_FROM_DATABASE=Globo Electronic GmbH & Co. KG + +OUI:00148C* + ID_OUI_FROM_DATABASE=Fortress Technologies + +OUI:00148D* + ID_OUI_FROM_DATABASE=Cubic Defense Simulation Systems + +OUI:00148E* + ID_OUI_FROM_DATABASE=Tele Power Inc. + +OUI:00148F* + ID_OUI_FROM_DATABASE=Protronic (Far East) Ltd. + +OUI:001490* + ID_OUI_FROM_DATABASE=ASP Corporation + +OUI:001491* + ID_OUI_FROM_DATABASE=Daniels Electronics Ltd. + +OUI:001492* + ID_OUI_FROM_DATABASE=Liteon, Mobile Media Solution SBU + +OUI:001493* + ID_OUI_FROM_DATABASE=Systimax Solutions + +OUI:001494* + ID_OUI_FROM_DATABASE=ESU AG + +OUI:001495* + ID_OUI_FROM_DATABASE=2Wire, Inc. + +OUI:001496* + ID_OUI_FROM_DATABASE=Phonic Corp. + +OUI:001497* + ID_OUI_FROM_DATABASE=ZHIYUAN Eletronics co.,ltd. + +OUI:001498* + ID_OUI_FROM_DATABASE=Viking Design Technology + +OUI:001499* + ID_OUI_FROM_DATABASE=Helicomm Inc + +OUI:00149A* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:00149B* + ID_OUI_FROM_DATABASE=Nokota Communications, LLC + +OUI:00149C* + ID_OUI_FROM_DATABASE=HF Company + +OUI:00149D* + ID_OUI_FROM_DATABASE=Sound ID Inc. + +OUI:00149E* + ID_OUI_FROM_DATABASE=UbONE Co., Ltd + +OUI:00149F* + ID_OUI_FROM_DATABASE=System and Chips, Inc. + +OUI:0014A0* + ID_OUI_FROM_DATABASE=Accsense, Inc. + +OUI:0014A1* + ID_OUI_FROM_DATABASE=Synchronous Communication Corp + +OUI:0014A2* + ID_OUI_FROM_DATABASE=Core Micro Systems Inc. + +OUI:0014A3* + ID_OUI_FROM_DATABASE=Vitelec BV + +OUI:0014A4* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co., Ltd. + +OUI:0014A5* + ID_OUI_FROM_DATABASE=Gemtek Technology Co., Ltd. + +OUI:0014A6* + ID_OUI_FROM_DATABASE=Teranetics, Inc. + +OUI:0014A7* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:0014A8* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0014A9* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0014AA* + ID_OUI_FROM_DATABASE=Ashly Audio, Inc. + +OUI:0014AB* + ID_OUI_FROM_DATABASE=Senhai Electronic Technology Co., Ltd. + +OUI:0014AC* + ID_OUI_FROM_DATABASE=Bountiful WiFi + +OUI:0014AD* + ID_OUI_FROM_DATABASE=Gassner Wiege- und Meßtechnik GmbH + +OUI:0014AE* + ID_OUI_FROM_DATABASE=Wizlogics Co., Ltd. + +OUI:0014AF* + ID_OUI_FROM_DATABASE=Datasym Inc. + +OUI:0014B0* + ID_OUI_FROM_DATABASE=Naeil Community + +OUI:0014B1* + ID_OUI_FROM_DATABASE=Avitec AB + +OUI:0014B2* + ID_OUI_FROM_DATABASE=mCubelogics Corporation + +OUI:0014B3* + ID_OUI_FROM_DATABASE=CoreStar International Corp + +OUI:0014B4* + ID_OUI_FROM_DATABASE=General Dynamics United Kingdom Ltd + +OUI:0014B5* + ID_OUI_FROM_DATABASE=PHYSIOMETRIX,INC + +OUI:0014B6* + ID_OUI_FROM_DATABASE=Enswer Technology Inc. + +OUI:0014B7* + ID_OUI_FROM_DATABASE=AR Infotek Inc. + +OUI:0014B8* + ID_OUI_FROM_DATABASE=Hill-Rom + +OUI:0014B9* + ID_OUI_FROM_DATABASE=MSTAR SEMICONDUCTOR + +OUI:0014BA* + ID_OUI_FROM_DATABASE=Carvers SA de CV + +OUI:0014BB* + ID_OUI_FROM_DATABASE=Open Interface North America + +OUI:0014BC* + ID_OUI_FROM_DATABASE=SYNECTIC TELECOM EXPORTS PVT. LTD. + +OUI:0014BD* + ID_OUI_FROM_DATABASE=incNETWORKS, Inc + +OUI:0014BE* + ID_OUI_FROM_DATABASE=Wink communication technology CO.LTD + +OUI:0014BF* + ID_OUI_FROM_DATABASE=Cisco-Linksys LLC + +OUI:0014C0* + ID_OUI_FROM_DATABASE=Symstream Technology Group Ltd + +OUI:0014C1* + ID_OUI_FROM_DATABASE=U.S. Robotics Corporation + +OUI:0014C2* + ID_OUI_FROM_DATABASE=Hewlett-Packard Company + +OUI:0014C3* + ID_OUI_FROM_DATABASE=Seagate Technology LLC + +OUI:0014C4* + ID_OUI_FROM_DATABASE=Vitelcom Mobile Technology + +OUI:0014C5* + ID_OUI_FROM_DATABASE=Alive Technologies Pty Ltd + +OUI:0014C6* + ID_OUI_FROM_DATABASE=Quixant Ltd + +OUI:0014C7* + ID_OUI_FROM_DATABASE=Nortel + +OUI:0014C8* + ID_OUI_FROM_DATABASE=Contemporary Research Corp + +OUI:0014C9* + ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc. + +OUI:0014CA* + ID_OUI_FROM_DATABASE=Key Radio Systems Limited + +OUI:0014CB* + ID_OUI_FROM_DATABASE=LifeSync Corporation + +OUI:0014CC* + ID_OUI_FROM_DATABASE=Zetec, Inc. + +OUI:0014CD* + ID_OUI_FROM_DATABASE=DigitalZone Co., Ltd. + +OUI:0014CE* + ID_OUI_FROM_DATABASE=NF CORPORATION + +OUI:0014CF* + ID_OUI_FROM_DATABASE=INVISIO Communications + +OUI:0014D0* + ID_OUI_FROM_DATABASE=BTI Systems Inc. + +OUI:0014D1* + ID_OUI_FROM_DATABASE=TRENDnet + +OUI:0014D2* + ID_OUI_FROM_DATABASE=Kyuden Technosystems Corporation + +OUI:0014D3* + ID_OUI_FROM_DATABASE=SEPSA + +OUI:0014D4* + ID_OUI_FROM_DATABASE=K Technology Corporation + +OUI:0014D5* + ID_OUI_FROM_DATABASE=Datang Telecom Technology CO. , LCD,Optical Communication Br + +OUI:0014D6* + ID_OUI_FROM_DATABASE=Jeongmin Electronics Co.,Ltd. + +OUI:0014D7* + ID_OUI_FROM_DATABASE=Datastore Technology Corp + +OUI:0014D8* + ID_OUI_FROM_DATABASE=bio-logic SA + +OUI:0014D9* + ID_OUI_FROM_DATABASE=IP Fabrics, Inc. + +OUI:0014DA* + ID_OUI_FROM_DATABASE=Huntleigh Healthcare + +OUI:0014DB* + ID_OUI_FROM_DATABASE=Elma Trenew Electronic GmbH + +OUI:0014DC* + ID_OUI_FROM_DATABASE=Communication System Design & Manufacturing (CSDM) + +OUI:0014DD* + ID_OUI_FROM_DATABASE=Covergence Inc. + +OUI:0014DE* + ID_OUI_FROM_DATABASE=Sage Instruments Inc. + +OUI:0014DF* + ID_OUI_FROM_DATABASE=HI-P Tech Corporation + +OUI:0014E0* + ID_OUI_FROM_DATABASE=LET'S Corporation + +OUI:0014E1* + ID_OUI_FROM_DATABASE=Data Display AG + +OUI:0014E2* + ID_OUI_FROM_DATABASE=datacom systems inc. + +OUI:0014E3* + ID_OUI_FROM_DATABASE=mm-lab GmbH + +OUI:0014E4* + ID_OUI_FROM_DATABASE=infinias, LLC + +OUI:0014E5* + ID_OUI_FROM_DATABASE=Alticast + +OUI:0014E6* + ID_OUI_FROM_DATABASE=AIM Infrarotmodule GmbH + +OUI:0014E7* + ID_OUI_FROM_DATABASE=Stolinx,. Inc + +OUI:0014E8* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:0014E9* + ID_OUI_FROM_DATABASE=Nortech International + +OUI:0014EA* + ID_OUI_FROM_DATABASE=S Digm Inc. (Safe Paradigm Inc.) + +OUI:0014EB* + ID_OUI_FROM_DATABASE=AwarePoint Corporation + +OUI:0014EC* + ID_OUI_FROM_DATABASE=Acro Telecom + +OUI:0014ED* + ID_OUI_FROM_DATABASE=Airak, Inc. + +OUI:0014EE* + ID_OUI_FROM_DATABASE=Western Digital Technologies, Inc. + +OUI:0014EF* + ID_OUI_FROM_DATABASE=TZero Technologies, Inc. + +OUI:0014F0* + ID_OUI_FROM_DATABASE=Business Security OL AB + +OUI:0014F1* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0014F2* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0014F3* + ID_OUI_FROM_DATABASE=ViXS Systems Inc + +OUI:0014F4* + ID_OUI_FROM_DATABASE=DekTec Digital Video B.V. + +OUI:0014F5* + ID_OUI_FROM_DATABASE=OSI Security Devices + +OUI:0014F6* + ID_OUI_FROM_DATABASE=Juniper Networks, Inc. + +OUI:0014F7* + ID_OUI_FROM_DATABASE=Crevis + +OUI:0014F8* + ID_OUI_FROM_DATABASE=Scientific Atlanta + +OUI:0014F9* + ID_OUI_FROM_DATABASE=Vantage Controls + +OUI:0014FA* + ID_OUI_FROM_DATABASE=AsGa S.A. + +OUI:0014FB* + ID_OUI_FROM_DATABASE=Technical Solutions Inc. + +OUI:0014FC* + ID_OUI_FROM_DATABASE=Extandon, Inc. + +OUI:0014FD* + ID_OUI_FROM_DATABASE=Thecus Technology Corp. + +OUI:0014FE* + ID_OUI_FROM_DATABASE=Artech Electronics + +OUI:0014FF* + ID_OUI_FROM_DATABASE=Precise Automation, Inc. + +OUI:001500* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:001501* + ID_OUI_FROM_DATABASE=LexBox + +OUI:001502* + ID_OUI_FROM_DATABASE=BETA tech + +OUI:001503* + ID_OUI_FROM_DATABASE=PROFIcomms s.r.o. + +OUI:001504* + ID_OUI_FROM_DATABASE=GAME PLUS CO., LTD. + +OUI:001505* + ID_OUI_FROM_DATABASE=Actiontec Electronics, Inc + +OUI:001506* + ID_OUI_FROM_DATABASE=Neo Photonics + +OUI:001507* + ID_OUI_FROM_DATABASE=Renaissance Learning Inc + +OUI:001508* + ID_OUI_FROM_DATABASE=Global Target Enterprise Inc + +OUI:001509* + ID_OUI_FROM_DATABASE=Plus Technology Co., Ltd + +OUI:00150A* + ID_OUI_FROM_DATABASE=Sonoa Systems, Inc + +OUI:00150B* + ID_OUI_FROM_DATABASE=SAGE INFOTECH LTD. + +OUI:00150C* + ID_OUI_FROM_DATABASE=AVM GmbH + +OUI:00150D* + ID_OUI_FROM_DATABASE=Hoana Medical, Inc. + +OUI:00150E* + ID_OUI_FROM_DATABASE=OPENBRAIN TECHNOLOGIES CO., LTD. + +OUI:00150F* + ID_OUI_FROM_DATABASE=mingjong + +OUI:001510* + ID_OUI_FROM_DATABASE=Techsphere Co., Ltd + +OUI:001511* + ID_OUI_FROM_DATABASE=Data Center Systems + +OUI:001512* + ID_OUI_FROM_DATABASE=Zurich University of Applied Sciences + +OUI:001513* + ID_OUI_FROM_DATABASE=EFS sas + +OUI:001514* + ID_OUI_FROM_DATABASE=Hu Zhou NAVA Networks&Electronics Ltd. + +OUI:001515* + ID_OUI_FROM_DATABASE=Leipold+Co.GmbH + +OUI:001516* + ID_OUI_FROM_DATABASE=URIEL SYSTEMS INC. + +OUI:001517* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:001518* + ID_OUI_FROM_DATABASE=Shenzhen 10MOONS Technology Development CO.,Ltd + +OUI:001519* + ID_OUI_FROM_DATABASE=StoreAge Networking Technologies + +OUI:00151A* + ID_OUI_FROM_DATABASE=Hunter Engineering Company + +OUI:00151B* + ID_OUI_FROM_DATABASE=Isilon Systems Inc. + +OUI:00151C* + ID_OUI_FROM_DATABASE=LENECO + +OUI:00151D* + ID_OUI_FROM_DATABASE=M2I CORPORATION + +OUI:00151E* + ID_OUI_FROM_DATABASE=Ethernet Powerlink Standardization Group (EPSG) + +OUI:00151F* + ID_OUI_FROM_DATABASE=Multivision Intelligent Surveillance (Hong Kong) Ltd + +OUI:001520* + ID_OUI_FROM_DATABASE=Radiocrafts AS + +OUI:001521* + ID_OUI_FROM_DATABASE=Horoquartz + +OUI:001522* + ID_OUI_FROM_DATABASE=Dea Security + +OUI:001523* + ID_OUI_FROM_DATABASE=Meteor Communications Corporation + +OUI:001524* + ID_OUI_FROM_DATABASE=Numatics, Inc. + +OUI:001525* + ID_OUI_FROM_DATABASE=Chamberlain Access Solutions + +OUI:001526* + ID_OUI_FROM_DATABASE=Remote Technologies Inc + +OUI:001527* + ID_OUI_FROM_DATABASE=Balboa Instruments + +OUI:001528* + ID_OUI_FROM_DATABASE=Beacon Medical Products LLC d.b.a. BeaconMedaes + +OUI:001529* + ID_OUI_FROM_DATABASE=N3 Corporation + +OUI:00152A* + ID_OUI_FROM_DATABASE=Nokia GmbH + +OUI:00152B* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00152C* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00152D* + ID_OUI_FROM_DATABASE=TenX Networks, LLC + +OUI:00152E* + ID_OUI_FROM_DATABASE=PacketHop, Inc. + +OUI:00152F* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:001530* + ID_OUI_FROM_DATABASE=EMC Corporation + +OUI:001531* + ID_OUI_FROM_DATABASE=KOCOM + +OUI:001532* + ID_OUI_FROM_DATABASE=Consumer Technologies Group, LLC + +OUI:001533* + ID_OUI_FROM_DATABASE=NADAM.CO.,LTD + +OUI:001534* + ID_OUI_FROM_DATABASE=A Beltrónica-Companhia de Comunicações, Lda + +OUI:001535* + ID_OUI_FROM_DATABASE=OTE Spa + +OUI:001536* + ID_OUI_FROM_DATABASE=Powertech co.,Ltd + +OUI:001537* + ID_OUI_FROM_DATABASE=Ventus Networks + +OUI:001538* + ID_OUI_FROM_DATABASE=RFID, Inc. + +OUI:001539* + ID_OUI_FROM_DATABASE=Technodrive SRL + +OUI:00153A* + ID_OUI_FROM_DATABASE=Shenzhen Syscan Technology Co.,Ltd. + +OUI:00153B* + ID_OUI_FROM_DATABASE=EMH metering GmbH & Co. KG + +OUI:00153C* + ID_OUI_FROM_DATABASE=Kprotech Co., Ltd. + +OUI:00153D* + ID_OUI_FROM_DATABASE=ELIM PRODUCT CO. + +OUI:00153E* + ID_OUI_FROM_DATABASE=Q-Matic Sweden AB + +OUI:00153F* + ID_OUI_FROM_DATABASE=Alcatel Alenia Space Italia + +OUI:001540* + ID_OUI_FROM_DATABASE=Nortel + +OUI:001541* + ID_OUI_FROM_DATABASE=StrataLight Communications, Inc. + +OUI:001542* + ID_OUI_FROM_DATABASE=MICROHARD S.R.L. + +OUI:001543* + ID_OUI_FROM_DATABASE=Aberdeen Test Center + +OUI:001544* + ID_OUI_FROM_DATABASE=coM.s.a.t. AG + +OUI:001545* + ID_OUI_FROM_DATABASE=SEECODE Co., Ltd. + +OUI:001546* + ID_OUI_FROM_DATABASE=ITG Worldwide Sdn Bhd + +OUI:001547* + ID_OUI_FROM_DATABASE=AiZen Solutions Inc. + +OUI:001548* + ID_OUI_FROM_DATABASE=CUBE TECHNOLOGIES + +OUI:001549* + ID_OUI_FROM_DATABASE=Dixtal Biomedica Ind. Com. Ltda + +OUI:00154A* + ID_OUI_FROM_DATABASE=WANSHIH ELECTRONIC CO., LTD + +OUI:00154B* + ID_OUI_FROM_DATABASE=Wonde Proud Technology Co., Ltd + +OUI:00154C* + ID_OUI_FROM_DATABASE=Saunders Electronics + +OUI:00154D* + ID_OUI_FROM_DATABASE=Netronome Systems, Inc. + +OUI:00154E* + ID_OUI_FROM_DATABASE=IEC + +OUI:00154F* + ID_OUI_FROM_DATABASE=one RF Technology + +OUI:001550* + ID_OUI_FROM_DATABASE=Nits Technology Inc + +OUI:001551* + ID_OUI_FROM_DATABASE=RadioPulse Inc. + +OUI:001552* + ID_OUI_FROM_DATABASE=Wi-Gear Inc. + +OUI:001553* + ID_OUI_FROM_DATABASE=Cytyc Corporation + +OUI:001554* + ID_OUI_FROM_DATABASE=Atalum Wireless S.A. + +OUI:001555* + ID_OUI_FROM_DATABASE=DFM GmbH + +OUI:001556* + ID_OUI_FROM_DATABASE=SAGEM COMMUNICATION + +OUI:001557* + ID_OUI_FROM_DATABASE=Olivetti + +OUI:001558* + ID_OUI_FROM_DATABASE=FOXCONN + +OUI:001559* + ID_OUI_FROM_DATABASE=Securaplane Technologies, Inc. + +OUI:00155A* + ID_OUI_FROM_DATABASE=DAINIPPON PHARMACEUTICAL CO., LTD. + +OUI:00155B* + ID_OUI_FROM_DATABASE=Sampo Corporation + +OUI:00155C* + ID_OUI_FROM_DATABASE=Dresser Wayne + +OUI:00155D* + ID_OUI_FROM_DATABASE=Microsoft Corporation + +OUI:00155E* + ID_OUI_FROM_DATABASE=Morgan Stanley + +OUI:00155F* + ID_OUI_FROM_DATABASE=GreenPeak Technologies + +OUI:001560* + ID_OUI_FROM_DATABASE=Hewlett-Packard Company + +OUI:001561* + ID_OUI_FROM_DATABASE=JJPlus Corporation + +OUI:001562* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001563* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001564* + ID_OUI_FROM_DATABASE=BEHRINGER Spezielle Studiotechnik GmbH + +OUI:001565* + ID_OUI_FROM_DATABASE=XIAMEN YEALINK NETWORK TECHNOLOGY CO.,LTD + +OUI:001566* + ID_OUI_FROM_DATABASE=A-First Technology Co., Ltd. + +OUI:001567* + ID_OUI_FROM_DATABASE=RADWIN Inc. + +OUI:001568* + ID_OUI_FROM_DATABASE=Dilithium Networks + +OUI:001569* + ID_OUI_FROM_DATABASE=PECO II, Inc. + +OUI:00156A* + ID_OUI_FROM_DATABASE=DG2L Technologies Pvt. Ltd. + +OUI:00156B* + ID_OUI_FROM_DATABASE=Perfisans Networks Corp. + +OUI:00156C* + ID_OUI_FROM_DATABASE=SANE SYSTEM CO., LTD + +OUI:00156D* + ID_OUI_FROM_DATABASE=Ubiquiti Networks Inc. + +OUI:00156E* + ID_OUI_FROM_DATABASE=A. W. Communication Systems Ltd + +OUI:00156F* + ID_OUI_FROM_DATABASE=Xiranet Communications GmbH + +OUI:001570* + ID_OUI_FROM_DATABASE=Symbol TechnologiesWholly owned Subsidiary of Motorola + +OUI:001571* + ID_OUI_FROM_DATABASE=Nolan Systems + +OUI:001572* + ID_OUI_FROM_DATABASE=Red-Lemon + +OUI:001573* + ID_OUI_FROM_DATABASE=NewSoft Technology Corporation + +OUI:001574* + ID_OUI_FROM_DATABASE=Horizon Semiconductors Ltd. + +OUI:001575* + ID_OUI_FROM_DATABASE=Nevis Networks Inc. + +OUI:001576* + ID_OUI_FROM_DATABASE=LABiTec - Labor Biomedical Technologies GmbH + +OUI:001577* + ID_OUI_FROM_DATABASE=Allied Telesis + +OUI:001578* + ID_OUI_FROM_DATABASE=Audio / Video Innovations + +OUI:001579* + ID_OUI_FROM_DATABASE=Lunatone Industrielle Elektronik GmbH + +OUI:00157A* + ID_OUI_FROM_DATABASE=Telefin S.p.A. + +OUI:00157B* + ID_OUI_FROM_DATABASE=Leuze electronic GmbH + Co. KG + +OUI:00157C* + ID_OUI_FROM_DATABASE=Dave Networks, Inc. + +OUI:00157D* + ID_OUI_FROM_DATABASE=POSDATA CO., LTD. + +OUI:00157E* + ID_OUI_FROM_DATABASE=Weidmüller Interface GmbH & Co. KG + +OUI:00157F* + ID_OUI_FROM_DATABASE=ChuanG International Holding CO.,LTD. + +OUI:001580* + ID_OUI_FROM_DATABASE=U-WAY CORPORATION + +OUI:001581* + ID_OUI_FROM_DATABASE=MAKUS Inc. + +OUI:001582* + ID_OUI_FROM_DATABASE=Pulse Eight Limited + +OUI:001583* + ID_OUI_FROM_DATABASE=IVT corporation + +OUI:001584* + ID_OUI_FROM_DATABASE=Schenck Process GmbH + +OUI:001585* + ID_OUI_FROM_DATABASE=Aonvision Technolopy Corp. + +OUI:001586* + ID_OUI_FROM_DATABASE=Xiamen Overseas Chinese Electronic Co., Ltd. + +OUI:001587* + ID_OUI_FROM_DATABASE=Takenaka Seisakusho Co.,Ltd + +OUI:001588* + ID_OUI_FROM_DATABASE=Balda Solution Malaysia Sdn Bhd + +OUI:001589* + ID_OUI_FROM_DATABASE=D-MAX Technology Co.,Ltd + +OUI:00158A* + ID_OUI_FROM_DATABASE=SURECOM Technology Corp. + +OUI:00158B* + ID_OUI_FROM_DATABASE=Park Air Systems Ltd + +OUI:00158C* + ID_OUI_FROM_DATABASE=Liab ApS + +OUI:00158D* + ID_OUI_FROM_DATABASE=Jennic Ltd + +OUI:00158E* + ID_OUI_FROM_DATABASE=Plustek.INC + +OUI:00158F* + ID_OUI_FROM_DATABASE=NTT Advanced Technology Corporation + +OUI:001590* + ID_OUI_FROM_DATABASE=Hectronic GmbH + +OUI:001591* + ID_OUI_FROM_DATABASE=RLW Inc. + +OUI:001592* + ID_OUI_FROM_DATABASE=Facom UK Ltd (Melksham) + +OUI:001593* + ID_OUI_FROM_DATABASE=U4EA Technologies Inc. + +OUI:001594* + ID_OUI_FROM_DATABASE=BIXOLON CO.,LTD + +OUI:001595* + ID_OUI_FROM_DATABASE=Quester Tangent Corporation + +OUI:001596* + ID_OUI_FROM_DATABASE=ARRIS International + +OUI:001597* + ID_OUI_FROM_DATABASE=AETA AUDIO SYSTEMS + +OUI:001598* + ID_OUI_FROM_DATABASE=Kolektor group + +OUI:001599* + ID_OUI_FROM_DATABASE=Samsung Electronics Co., LTD + +OUI:00159A* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:00159B* + ID_OUI_FROM_DATABASE=Nortel + +OUI:00159C* + ID_OUI_FROM_DATABASE=B-KYUNG SYSTEM Co.,Ltd. + +OUI:00159D* + ID_OUI_FROM_DATABASE=Minicom Advanced Systems ltd + +OUI:00159E* + ID_OUI_FROM_DATABASE=Mad Catz Interactive Inc + +OUI:00159F* + ID_OUI_FROM_DATABASE=Terascala, Inc. + +OUI:0015A0* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:0015A1* + ID_OUI_FROM_DATABASE=ECA-SINTERS + +OUI:0015A2* + ID_OUI_FROM_DATABASE=ARRIS International + +OUI:0015A3* + ID_OUI_FROM_DATABASE=ARRIS International + +OUI:0015A4* + ID_OUI_FROM_DATABASE=ARRIS International + +OUI:0015A5* + ID_OUI_FROM_DATABASE=DCI Co., Ltd. + +OUI:0015A6* + ID_OUI_FROM_DATABASE=Digital Electronics Products Ltd. + +OUI:0015A7* + ID_OUI_FROM_DATABASE=Robatech AG + +OUI:0015A8* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:0015A9* + ID_OUI_FROM_DATABASE=KWANG WOO I&C CO.,LTD + +OUI:0015AA* + ID_OUI_FROM_DATABASE=Rextechnik International Co., + +OUI:0015AB* + ID_OUI_FROM_DATABASE=PRO CO SOUND INC + +OUI:0015AC* + ID_OUI_FROM_DATABASE=Capelon AB + +OUI:0015AD* + ID_OUI_FROM_DATABASE=Accedian Networks + +OUI:0015AE* + ID_OUI_FROM_DATABASE=kyung il + +OUI:0015AF* + ID_OUI_FROM_DATABASE=AzureWave Technologies, Inc. + +OUI:0015B0* + ID_OUI_FROM_DATABASE=AUTOTELENET CO.,LTD + +OUI:0015B1* + ID_OUI_FROM_DATABASE=Ambient Corporation + +OUI:0015B2* + ID_OUI_FROM_DATABASE=Advanced Industrial Computer, Inc. + +OUI:0015B3* + ID_OUI_FROM_DATABASE=Caretech AB + +OUI:0015B4* + ID_OUI_FROM_DATABASE=Polymap Wireless LLC + +OUI:0015B5* + ID_OUI_FROM_DATABASE=CI Network Corp. + +OUI:0015B6* + ID_OUI_FROM_DATABASE=ShinMaywa Industries, Ltd. + +OUI:0015B7* + ID_OUI_FROM_DATABASE=Toshiba + +OUI:0015B8* + ID_OUI_FROM_DATABASE=Tahoe + +OUI:0015B9* + ID_OUI_FROM_DATABASE=Samsung Electronics Co., Ltd. + +OUI:0015BA* + ID_OUI_FROM_DATABASE=iba AG + +OUI:0015BB* + ID_OUI_FROM_DATABASE=SMA Solar Technology AG + +OUI:0015BC* + ID_OUI_FROM_DATABASE=Develco + +OUI:0015BD* + ID_OUI_FROM_DATABASE=Group 4 Technology Ltd + +OUI:0015BE* + ID_OUI_FROM_DATABASE=Iqua Ltd. + +OUI:0015BF* + ID_OUI_FROM_DATABASE=technicob + +OUI:0015C0* + ID_OUI_FROM_DATABASE=DIGITAL TELEMEDIA CO.,LTD. + +OUI:0015C1* + ID_OUI_FROM_DATABASE=SONY Computer Entertainment inc, + +OUI:0015C2* + ID_OUI_FROM_DATABASE=3M Germany + +OUI:0015C3* + ID_OUI_FROM_DATABASE=Ruf Telematik AG + +OUI:0015C4* + ID_OUI_FROM_DATABASE=FLOVEL CO., LTD. + +OUI:0015C5* + ID_OUI_FROM_DATABASE=Dell Inc + +OUI:0015C6* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0015C7* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0015C8* + ID_OUI_FROM_DATABASE=FlexiPanel Ltd + +OUI:0015C9* + ID_OUI_FROM_DATABASE=Gumstix, Inc + +OUI:0015CA* + ID_OUI_FROM_DATABASE=TeraRecon, Inc. + +OUI:0015CB* + ID_OUI_FROM_DATABASE=Surf Communication Solutions Ltd. + +OUI:0015CC* + ID_OUI_FROM_DATABASE=UQUEST, LTD. + +OUI:0015CD* + ID_OUI_FROM_DATABASE=Exartech International Corp. + +OUI:0015CE* + ID_OUI_FROM_DATABASE=ARRIS International + +OUI:0015CF* + ID_OUI_FROM_DATABASE=ARRIS International + +OUI:0015D0* + ID_OUI_FROM_DATABASE=ARRIS International + +OUI:0015D1* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + +OUI:0015D2* + ID_OUI_FROM_DATABASE=Xantech Corporation + +OUI:0015D3* + ID_OUI_FROM_DATABASE=Pantech&Curitel Communications, Inc. + +OUI:0015D4* + ID_OUI_FROM_DATABASE=Emitor AB + +OUI:0015D5* + ID_OUI_FROM_DATABASE=NICEVT + +OUI:0015D6* + ID_OUI_FROM_DATABASE=OSLiNK Sp. z o.o. + +OUI:0015D7* + ID_OUI_FROM_DATABASE=Reti Corporation + +OUI:0015D8* + ID_OUI_FROM_DATABASE=Interlink Electronics + +OUI:0015D9* + ID_OUI_FROM_DATABASE=PKC Electronics Oy + +OUI:0015DA* + ID_OUI_FROM_DATABASE=IRITEL A.D. + +OUI:0015DB* + ID_OUI_FROM_DATABASE=Canesta Inc. + +OUI:0015DC* + ID_OUI_FROM_DATABASE=KT&C Co., Ltd. + +OUI:0015DD* + ID_OUI_FROM_DATABASE=IP Control Systems Ltd. + +OUI:0015DE* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:0015DF* + ID_OUI_FROM_DATABASE=Clivet S.p.A. + +OUI:0015E0* + ID_OUI_FROM_DATABASE=ST-Ericsson + +OUI:0015E1* + ID_OUI_FROM_DATABASE=Picochip Ltd + +OUI:0015E2* + ID_OUI_FROM_DATABASE=Dr.Ing. Herbert Knauer GmbH + +OUI:0015E3* + ID_OUI_FROM_DATABASE=Dream Technologies Corporation + +OUI:0015E4* + ID_OUI_FROM_DATABASE=Zimmer Elektromedizin + +OUI:0015E5* + ID_OUI_FROM_DATABASE=Cheertek Inc. + +OUI:0015E6* + ID_OUI_FROM_DATABASE=MOBILE TECHNIKA Inc. + +OUI:0015E7* + ID_OUI_FROM_DATABASE=Quantec ProAudio + +OUI:0015E8* + ID_OUI_FROM_DATABASE=Nortel + +OUI:0015E9* + ID_OUI_FROM_DATABASE=D-Link Corporation + +OUI:0015EA* + ID_OUI_FROM_DATABASE=Tellumat (Pty) Ltd + +OUI:0015EB* + ID_OUI_FROM_DATABASE=ZTE CORPORATION + +OUI:0015EC* + ID_OUI_FROM_DATABASE=Boca Devices LLC + +OUI:0015ED* + ID_OUI_FROM_DATABASE=Fulcrum Microsystems, Inc. + +OUI:0015EE* + ID_OUI_FROM_DATABASE=Omnex Control Systems + +OUI:0015EF* + ID_OUI_FROM_DATABASE=NEC TOKIN Corporation + +OUI:0015F0* + ID_OUI_FROM_DATABASE=EGO BV + +OUI:0015F1* + ID_OUI_FROM_DATABASE=KYLINK Communications Corp. + +OUI:0015F2* + ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. + +OUI:0015F3* + ID_OUI_FROM_DATABASE=PELTOR AB + +OUI:0015F4* + ID_OUI_FROM_DATABASE=Eventide + +OUI:0015F5* + ID_OUI_FROM_DATABASE=Sustainable Energy Systems + +OUI:0015F6* + ID_OUI_FROM_DATABASE=SCIENCE AND ENGINEERING SERVICES, INC. + +OUI:0015F7* + ID_OUI_FROM_DATABASE=Wintecronics Ltd. + +OUI:0015F8* + ID_OUI_FROM_DATABASE=Kingtronics Industrial Co. Ltd. + +OUI:0015F9* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0015FA* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0015FB* + ID_OUI_FROM_DATABASE=setex schermuly textile computer gmbh + +OUI:0015FC* + ID_OUI_FROM_DATABASE=Littelfuse Startco + +OUI:0015FD* + ID_OUI_FROM_DATABASE=Complete Media Systems + +OUI:0015FE* + ID_OUI_FROM_DATABASE=SCHILLING ROBOTICS LLC + +OUI:0015FF* + ID_OUI_FROM_DATABASE=Novatel Wireless, Inc. + +OUI:001600* + ID_OUI_FROM_DATABASE=CelleBrite Mobile Synchronization + +OUI:001601* + ID_OUI_FROM_DATABASE=Buffalo Inc. + +OUI:001602* + ID_OUI_FROM_DATABASE=CEYON TECHNOLOGY CO.,LTD. + +OUI:001603* + ID_OUI_FROM_DATABASE=COOLKSKY Co., LTD + +OUI:001604* + ID_OUI_FROM_DATABASE=Sigpro + +OUI:001605* + ID_OUI_FROM_DATABASE=YORKVILLE SOUND INC. + +OUI:001606* + ID_OUI_FROM_DATABASE=Ideal Industries + +OUI:001607* + ID_OUI_FROM_DATABASE=Curves International Inc. + +OUI:001608* + ID_OUI_FROM_DATABASE=Sequans Communications + +OUI:001609* + ID_OUI_FROM_DATABASE=Unitech electronics co., ltd. + +OUI:00160A* + ID_OUI_FROM_DATABASE=SWEEX Europe BV + +OUI:00160B* + ID_OUI_FROM_DATABASE=TVWorks LLC + +OUI:00160C* + ID_OUI_FROM_DATABASE=LPL DEVELOPMENT S.A. DE C.V + +OUI:00160D* + ID_OUI_FROM_DATABASE=Be Here Corporation + +OUI:00160E* + ID_OUI_FROM_DATABASE=Optica Technologies Inc. + +OUI:00160F* + ID_OUI_FROM_DATABASE=BADGER METER INC + +OUI:001610* + ID_OUI_FROM_DATABASE=Carina Technology + +OUI:001611* + ID_OUI_FROM_DATABASE=Altecon Srl + +OUI:001612* + ID_OUI_FROM_DATABASE=Otsuka Electronics Co., Ltd. + +OUI:001613* + ID_OUI_FROM_DATABASE=LibreStream Technologies Inc. + +OUI:001614* + ID_OUI_FROM_DATABASE=Picosecond Pulse Labs + +OUI:001615* + ID_OUI_FROM_DATABASE=Nittan Company, Limited + +OUI:001616* + ID_OUI_FROM_DATABASE=BROWAN COMMUNICATION INC. + +OUI:001617* + ID_OUI_FROM_DATABASE=MSI + +OUI:001618* + ID_OUI_FROM_DATABASE=HIVION Co., Ltd. + +OUI:001619* + ID_OUI_FROM_DATABASE=La Factoría de Comunicaciones Aplicadas,S.L. + +OUI:00161A* + ID_OUI_FROM_DATABASE=Dametric AB + +OUI:00161B* + ID_OUI_FROM_DATABASE=Micronet Corporation + +OUI:00161C* + ID_OUI_FROM_DATABASE=e:cue + +OUI:00161D* + ID_OUI_FROM_DATABASE=Innovative Wireless Technologies, Inc. + +OUI:00161E* + ID_OUI_FROM_DATABASE=Woojinnet + +OUI:00161F* + ID_OUI_FROM_DATABASE=SUNWAVETEC Co., Ltd. + +OUI:001620* + ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications AB + +OUI:001621* + ID_OUI_FROM_DATABASE=Colorado Vnet + +OUI:001622* + ID_OUI_FROM_DATABASE=BBH SYSTEMS GMBH + +OUI:001623* + ID_OUI_FROM_DATABASE=Interval Media + +OUI:001624* + ID_OUI_FROM_DATABASE=Teneros, Inc. + +OUI:001625* + ID_OUI_FROM_DATABASE=Impinj, Inc. + +OUI:001626* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:001627* + ID_OUI_FROM_DATABASE=embedded-logic DESIGN AND MORE GmbH + +OUI:001628* + ID_OUI_FROM_DATABASE=Ultra Electronics Manufacturing and Card Systems + +OUI:001629* + ID_OUI_FROM_DATABASE=Nivus GmbH + +OUI:00162A* + ID_OUI_FROM_DATABASE=Antik computers & communications s.r.o. + +OUI:00162B* + ID_OUI_FROM_DATABASE=Togami Electric Mfg.co.,Ltd. + +OUI:00162C* + ID_OUI_FROM_DATABASE=Xanboo + +OUI:00162D* + ID_OUI_FROM_DATABASE=STNet Co., Ltd. + +OUI:00162E* + ID_OUI_FROM_DATABASE=Space Shuttle Hi-Tech Co., Ltd. + +OUI:00162F* + ID_OUI_FROM_DATABASE=Geutebrück GmbH + +OUI:001630* + ID_OUI_FROM_DATABASE=Vativ Technologies + +OUI:001631* + ID_OUI_FROM_DATABASE=Xteam + +OUI:001632* + ID_OUI_FROM_DATABASE=SAMSUNG ELECTRONICS CO., LTD. + +OUI:001633* + ID_OUI_FROM_DATABASE=Oxford Diagnostics Ltd. + +OUI:001634* + ID_OUI_FROM_DATABASE=Mathtech, Inc. + +OUI:001635* + ID_OUI_FROM_DATABASE=Hewlett-Packard Company + +OUI:001636* + ID_OUI_FROM_DATABASE=Quanta Computer Inc. + +OUI:001637* + ID_OUI_FROM_DATABASE=Citel Srl + +OUI:001638* + ID_OUI_FROM_DATABASE=TECOM Co., Ltd. + +OUI:001639* + ID_OUI_FROM_DATABASE=UBIQUAM Co.,Ltd + +OUI:00163A* + ID_OUI_FROM_DATABASE=YVES TECHNOLOGY CO., LTD. + +OUI:00163B* + ID_OUI_FROM_DATABASE=VertexRSI/General Dynamics + +OUI:00163C* + ID_OUI_FROM_DATABASE=Rebox B.V. + +OUI:00163D* + ID_OUI_FROM_DATABASE=Tsinghua Tongfang Legend Silicon Tech. Co., Ltd. + +OUI:00163E* + ID_OUI_FROM_DATABASE=Xensource, Inc. + +OUI:00163F* + ID_OUI_FROM_DATABASE=CReTE SYSTEMS Inc. + +OUI:001640* + ID_OUI_FROM_DATABASE=Asmobile Communication Inc. + +OUI:001641* + ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co., Ltd. + +OUI:001642* + ID_OUI_FROM_DATABASE=Pangolin + +OUI:001643* + ID_OUI_FROM_DATABASE=Sunhillo Corporation + +OUI:001644* + ID_OUI_FROM_DATABASE=LITE-ON Technology Corp. + +OUI:001645* + ID_OUI_FROM_DATABASE=Power Distribution, Inc. + +OUI:001646* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001647* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001648* + ID_OUI_FROM_DATABASE=SSD Company Limited + +OUI:001649* + ID_OUI_FROM_DATABASE=SetOne GmbH + +OUI:00164A* + ID_OUI_FROM_DATABASE=Vibration Technology Limited + +OUI:00164B* + ID_OUI_FROM_DATABASE=Quorion Data Systems GmbH + +OUI:00164C* + ID_OUI_FROM_DATABASE=PLANET INT Co., Ltd + +OUI:00164D* + ID_OUI_FROM_DATABASE=Alcatel North America IP Division + +OUI:00164E* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:00164F* + ID_OUI_FROM_DATABASE=World Ethnic Broadcastin Inc. + +OUI:001650* + ID_OUI_FROM_DATABASE=Herley General Microwave Israel. + +OUI:001651* + ID_OUI_FROM_DATABASE=Exeo Systems + +OUI:001652* + ID_OUI_FROM_DATABASE=Hoatech Technologies, Inc. + +OUI:001653* + ID_OUI_FROM_DATABASE=LEGO System A/S IE Electronics Division + +OUI:001654* + ID_OUI_FROM_DATABASE=Flex-P Industries Sdn. Bhd. + +OUI:001655* + ID_OUI_FROM_DATABASE=FUHO TECHNOLOGY Co., LTD + +OUI:001656* + ID_OUI_FROM_DATABASE=Nintendo Co., Ltd. + +OUI:001657* + ID_OUI_FROM_DATABASE=Aegate Ltd + +OUI:001658* + ID_OUI_FROM_DATABASE=Fusiontech Technologies Inc. + +OUI:001659* + ID_OUI_FROM_DATABASE=Z.M.P. RADWAG + +OUI:00165A* + ID_OUI_FROM_DATABASE=Harman Specialty Group + +OUI:00165B* + ID_OUI_FROM_DATABASE=Grip Audio + +OUI:00165C* + ID_OUI_FROM_DATABASE=Trackflow Ltd + +OUI:00165D* + ID_OUI_FROM_DATABASE=AirDefense, Inc. + +OUI:00165E* + ID_OUI_FROM_DATABASE=Precision I/O + +OUI:00165F* + ID_OUI_FROM_DATABASE=Fairmount Automation + +OUI:001660* + ID_OUI_FROM_DATABASE=Nortel + +OUI:001661* + ID_OUI_FROM_DATABASE=Novatium Solutions (P) Ltd + +OUI:001662* + ID_OUI_FROM_DATABASE=Liyuh Technology Ltd. + +OUI:001663* + ID_OUI_FROM_DATABASE=KBT Mobile + +OUI:001664* + ID_OUI_FROM_DATABASE=Prod-El SpA + +OUI:001665* + ID_OUI_FROM_DATABASE=Cellon France + +OUI:001666* + ID_OUI_FROM_DATABASE=Quantier Communication Inc. + +OUI:001667* + ID_OUI_FROM_DATABASE=A-TEC Subsystem INC. + +OUI:001668* + ID_OUI_FROM_DATABASE=Eishin Electronics + +OUI:001669* + ID_OUI_FROM_DATABASE=MRV Communication (Networks) LTD + +OUI:00166A* + ID_OUI_FROM_DATABASE=TPS + +OUI:00166B* + ID_OUI_FROM_DATABASE=Samsung Electronics + +OUI:00166C* + ID_OUI_FROM_DATABASE=Samsung Electonics Digital Video System Division + +OUI:00166D* + ID_OUI_FROM_DATABASE=Yulong Computer Telecommunication Scientific(shenzhen)Co.,Lt + +OUI:00166E* + ID_OUI_FROM_DATABASE=Arbitron Inc. + +OUI:00166F* + ID_OUI_FROM_DATABASE=Intel Corporation + +OUI:001670* + ID_OUI_FROM_DATABASE=SKNET Corporation + +OUI:001671* + ID_OUI_FROM_DATABASE=Symphox Information Co. + +OUI:001672* + ID_OUI_FROM_DATABASE=Zenway enterprise ltd + +OUI:001673* + ID_OUI_FROM_DATABASE=Bury GmbH & Co. KG + +OUI:001674* + ID_OUI_FROM_DATABASE=EuroCB (Phils.), Inc. + +OUI:001675* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:001676* + ID_OUI_FROM_DATABASE=Intel Corporation + +OUI:001677* + ID_OUI_FROM_DATABASE=Bihl+Wiedemann GmbH + +OUI:001678* + ID_OUI_FROM_DATABASE=SHENZHEN BAOAN GAOKE ELECTRONICS CO., LTD + +OUI:001679* + ID_OUI_FROM_DATABASE=eOn Communications + +OUI:00167A* + ID_OUI_FROM_DATABASE=Skyworth Overseas Dvelopment Ltd. + +OUI:00167B* + ID_OUI_FROM_DATABASE=Haver&Boecker + +OUI:00167C* + ID_OUI_FROM_DATABASE=iRex Technologies BV + +OUI:00167D* + ID_OUI_FROM_DATABASE=Sky-Line Information Co., Ltd. + +OUI:00167E* + ID_OUI_FROM_DATABASE=DIBOSS.CO.,LTD + +OUI:00167F* + ID_OUI_FROM_DATABASE=Bluebird Soft Inc. + +OUI:001680* + ID_OUI_FROM_DATABASE=Bally Gaming + Systems + +OUI:001681* + ID_OUI_FROM_DATABASE=Vector Informatik GmbH + +OUI:001682* + ID_OUI_FROM_DATABASE=Pro Dex, Inc + +OUI:001683* + ID_OUI_FROM_DATABASE=WEBIO International Co.,.Ltd. + +OUI:001684* + ID_OUI_FROM_DATABASE=Donjin Co.,Ltd. + +OUI:001685* + ID_OUI_FROM_DATABASE=Elisa Oyj + +OUI:001686* + ID_OUI_FROM_DATABASE=Karl Storz Imaging + +OUI:001687* + ID_OUI_FROM_DATABASE=Chubb CSC-Vendor AP + +OUI:001688* + ID_OUI_FROM_DATABASE=ServerEngines LLC + +OUI:001689* + ID_OUI_FROM_DATABASE=Pilkor Electronics Co., Ltd + +OUI:00168A* + ID_OUI_FROM_DATABASE=id-Confirm Inc + +OUI:00168B* + ID_OUI_FROM_DATABASE=Paralan Corporation + +OUI:00168C* + ID_OUI_FROM_DATABASE=DSL Partner AS + +OUI:00168D* + ID_OUI_FROM_DATABASE=KORWIN CO., Ltd. + +OUI:00168E* + ID_OUI_FROM_DATABASE=Vimicro corporation + +OUI:00168F* + ID_OUI_FROM_DATABASE=GN Netcom as + +OUI:001690* + ID_OUI_FROM_DATABASE=J-TEK INCORPORATION + +OUI:001691* + ID_OUI_FROM_DATABASE=Moser-Baer AG + +OUI:001692* + ID_OUI_FROM_DATABASE=Scientific-Atlanta, Inc. + +OUI:001693* + ID_OUI_FROM_DATABASE=PowerLink Technology Inc. + +OUI:001694* + ID_OUI_FROM_DATABASE=Sennheiser Communications A/S + +OUI:001695* + ID_OUI_FROM_DATABASE=AVC Technology (International) Limited + +OUI:001696* + ID_OUI_FROM_DATABASE=QDI Technology (H.K.) Limited + +OUI:001697* + ID_OUI_FROM_DATABASE=NEC Corporation + +OUI:001698* + ID_OUI_FROM_DATABASE=T&A Mobile Phones + +OUI:001699* + ID_OUI_FROM_DATABASE=Tonic DVB Marketing Ltd + +OUI:00169A* + ID_OUI_FROM_DATABASE=Quadrics Ltd + +OUI:00169B* + ID_OUI_FROM_DATABASE=Alstom Transport + +OUI:00169C* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00169D* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00169E* + ID_OUI_FROM_DATABASE=TV One Ltd + +OUI:00169F* + ID_OUI_FROM_DATABASE=Vimtron Electronics Co., Ltd. + +OUI:0016A0* + ID_OUI_FROM_DATABASE=Auto-Maskin + +OUI:0016A1* + ID_OUI_FROM_DATABASE=3Leaf Networks + +OUI:0016A2* + ID_OUI_FROM_DATABASE=CentraLite Systems, Inc. + +OUI:0016A3* + ID_OUI_FROM_DATABASE=Ingeteam Transmission&Distribution, S.A. + +OUI:0016A4* + ID_OUI_FROM_DATABASE=Ezurio Ltd + +OUI:0016A5* + ID_OUI_FROM_DATABASE=Tandberg Storage ASA + +OUI:0016A6* + ID_OUI_FROM_DATABASE=Dovado FZ-LLC + +OUI:0016A7* + ID_OUI_FROM_DATABASE=AWETA G&P + +OUI:0016A8* + ID_OUI_FROM_DATABASE=CWT CO., LTD. + +OUI:0016A9* + ID_OUI_FROM_DATABASE=2EI + +OUI:0016AA* + ID_OUI_FROM_DATABASE=Kei Communication Technology Inc. + +OUI:0016AB* + ID_OUI_FROM_DATABASE=PBI-Dansensor A/S + +OUI:0016AC* + ID_OUI_FROM_DATABASE=Toho Technology Corp. + +OUI:0016AD* + ID_OUI_FROM_DATABASE=BT-Links Company Limited + +OUI:0016AE* + ID_OUI_FROM_DATABASE=INVENTEL + +OUI:0016AF* + ID_OUI_FROM_DATABASE=Shenzhen Union Networks Equipment Co.,Ltd. + +OUI:0016B0* + ID_OUI_FROM_DATABASE=VK Corporation + +OUI:0016B1* + ID_OUI_FROM_DATABASE=KBS + +OUI:0016B2* + ID_OUI_FROM_DATABASE=DriveCam Inc + +OUI:0016B3* + ID_OUI_FROM_DATABASE=Photonicbridges (China) Co., Ltd. + +OUI:0016B5* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:0016B6* + ID_OUI_FROM_DATABASE=Cisco-Linksys + +OUI:0016B7* + ID_OUI_FROM_DATABASE=Seoul Commtech + +OUI:0016B8* + ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications + +OUI:0016B9* + ID_OUI_FROM_DATABASE=ProCurve Networking + +OUI:0016BA* + ID_OUI_FROM_DATABASE=WEATHERNEWS INC. + +OUI:0016BB* + ID_OUI_FROM_DATABASE=Law-Chain Computer Technology Co Ltd + +OUI:0016BC* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:0016BD* + ID_OUI_FROM_DATABASE=ATI Industrial Automation + +OUI:0016BE* + ID_OUI_FROM_DATABASE=INFRANET, Inc. + +OUI:0016BF* + ID_OUI_FROM_DATABASE=PaloDEx Group Oy + +OUI:0016C0* + ID_OUI_FROM_DATABASE=Semtech Corporation + +OUI:0016C1* + ID_OUI_FROM_DATABASE=Eleksen Ltd + +OUI:0016C2* + ID_OUI_FROM_DATABASE=Avtec Systems Inc + +OUI:0016C3* + ID_OUI_FROM_DATABASE=BA Systems Inc + +OUI:0016C4* + ID_OUI_FROM_DATABASE=SiRF Technology, Inc. + +OUI:0016C5* + ID_OUI_FROM_DATABASE=Shenzhen Xing Feng Industry Co.,Ltd + +OUI:0016C6* + ID_OUI_FROM_DATABASE=North Atlantic Industries + +OUI:0016C7* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0016C8* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0016C9* + ID_OUI_FROM_DATABASE=NAT Seattle, Inc. + +OUI:0016CA* + ID_OUI_FROM_DATABASE=Nortel + +OUI:0016CB* + ID_OUI_FROM_DATABASE=Apple Computer + +OUI:0016CC* + ID_OUI_FROM_DATABASE=Xcute Mobile Corp. + +OUI:0016CD* + ID_OUI_FROM_DATABASE=HIJI HIGH-TECH CO., LTD. + +OUI:0016CE* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co., Ltd. + +OUI:0016CF* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co., Ltd. + +OUI:0016D0* + ID_OUI_FROM_DATABASE=ATech elektronika d.o.o. + +OUI:0016D1* + ID_OUI_FROM_DATABASE=ZAT a.s. + +OUI:0016D2* + ID_OUI_FROM_DATABASE=Caspian + +OUI:0016D3* + ID_OUI_FROM_DATABASE=Wistron Corporation + +OUI:0016D4* + ID_OUI_FROM_DATABASE=Compal Communications, Inc. + +OUI:0016D5* + ID_OUI_FROM_DATABASE=Synccom Co., Ltd + +OUI:0016D6* + ID_OUI_FROM_DATABASE=TDA Tech Pty Ltd + +OUI:0016D7* + ID_OUI_FROM_DATABASE=Sunways AG + +OUI:0016D8* + ID_OUI_FROM_DATABASE=Senea AB + +OUI:0016D9* + ID_OUI_FROM_DATABASE=NINGBO BIRD CO.,LTD. + +OUI:0016DA* + ID_OUI_FROM_DATABASE=Futronic Technology Co. Ltd. + +OUI:0016DB* + ID_OUI_FROM_DATABASE=Samsung Electronics Co., Ltd. + +OUI:0016DC* + ID_OUI_FROM_DATABASE=ARCHOS + +OUI:0016DD* + ID_OUI_FROM_DATABASE=Gigabeam Corporation + +OUI:0016DE* + ID_OUI_FROM_DATABASE=FAST Inc + +OUI:0016DF* + ID_OUI_FROM_DATABASE=Lundinova AB + +OUI:0016E0* + ID_OUI_FROM_DATABASE=3Com Ltd + +OUI:0016E1* + ID_OUI_FROM_DATABASE=SiliconStor, Inc. + +OUI:0016E2* + ID_OUI_FROM_DATABASE=American Fibertek, Inc. + +OUI:0016E3* + ID_OUI_FROM_DATABASE=ASKEY COMPUTER CORP. + +OUI:0016E4* + ID_OUI_FROM_DATABASE=VANGUARD SECURITY ENGINEERING CORP. + +OUI:0016E5* + ID_OUI_FROM_DATABASE=FORDLEY DEVELOPMENT LIMITED + +OUI:0016E6* + ID_OUI_FROM_DATABASE=GIGA-BYTE TECHNOLOGY CO.,LTD. + +OUI:0016E7* + ID_OUI_FROM_DATABASE=Dynamix Promotions Limited + +OUI:0016E8* + ID_OUI_FROM_DATABASE=Sigma Designs, Inc. + +OUI:0016E9* + ID_OUI_FROM_DATABASE=Tiba Medical Inc + +OUI:0016EA* + ID_OUI_FROM_DATABASE=Intel Corporation + +OUI:0016EB* + ID_OUI_FROM_DATABASE=Intel Corporation + +OUI:0016EC* + ID_OUI_FROM_DATABASE=Elitegroup Computer Systems Co., Ltd. + +OUI:0016ED* + ID_OUI_FROM_DATABASE=Digital Safety Technologies, Inc + +OUI:0016EE* + ID_OUI_FROM_DATABASE=RoyalDigital Inc. + +OUI:0016EF* + ID_OUI_FROM_DATABASE=Koko Fitness, Inc. + +OUI:0016F0* + ID_OUI_FROM_DATABASE=Dell + +OUI:0016F1* + ID_OUI_FROM_DATABASE=OmniSense, LLC + +OUI:0016F2* + ID_OUI_FROM_DATABASE=Dmobile System Co., Ltd. + +OUI:0016F3* + ID_OUI_FROM_DATABASE=CAST Information Co., Ltd + +OUI:0016F4* + ID_OUI_FROM_DATABASE=Eidicom Co., Ltd. + +OUI:0016F5* + ID_OUI_FROM_DATABASE=Dalian Golden Hualu Digital Technology Co.,Ltd + +OUI:0016F6* + ID_OUI_FROM_DATABASE=Video Products Group + +OUI:0016F7* + ID_OUI_FROM_DATABASE=L-3 Communications, Electrodynamics, Inc. + +OUI:0016F8* + ID_OUI_FROM_DATABASE=AVIQTECH TECHNOLOGY CO., LTD. + +OUI:0016F9* + ID_OUI_FROM_DATABASE=CETRTA POT, d.o.o., Kranj + +OUI:0016FA* + ID_OUI_FROM_DATABASE=ECI Telecom Ltd. + +OUI:0016FB* + ID_OUI_FROM_DATABASE=SHENZHEN MTC CO.,LTD. + +OUI:0016FC* + ID_OUI_FROM_DATABASE=TOHKEN CO.,LTD. + +OUI:0016FD* + ID_OUI_FROM_DATABASE=Jaty Electronics + +OUI:0016FE* + ID_OUI_FROM_DATABASE=Alps Electric Co., Ltd + +OUI:0016FF* + ID_OUI_FROM_DATABASE=Wamin Optocomm Mfg Corp + +OUI:001700* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:001701* + ID_OUI_FROM_DATABASE=KDE, Inc. + +OUI:001702* + ID_OUI_FROM_DATABASE=Osung Midicom Co., Ltd + +OUI:001703* + ID_OUI_FROM_DATABASE=MOSDAN Internation Co.,Ltd + +OUI:001704* + ID_OUI_FROM_DATABASE=Shinco Electronics Group Co.,Ltd + +OUI:001705* + ID_OUI_FROM_DATABASE=Methode Electronics + +OUI:001706* + ID_OUI_FROM_DATABASE=Techfaith Wireless Communication Technology Limited. + +OUI:001707* + ID_OUI_FROM_DATABASE=InGrid, Inc + +OUI:001708* + ID_OUI_FROM_DATABASE=Hewlett-Packard Company + +OUI:001709* + ID_OUI_FROM_DATABASE=Exalt Communications + +OUI:00170A* + ID_OUI_FROM_DATABASE=INEW DIGITAL COMPANY + +OUI:00170B* + ID_OUI_FROM_DATABASE=Contela, Inc. + +OUI:00170C* + ID_OUI_FROM_DATABASE=Twig Com Ltd. + +OUI:00170D* + ID_OUI_FROM_DATABASE=Dust Networks Inc. + +OUI:00170E* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00170F* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001710* + ID_OUI_FROM_DATABASE=Casa Systems Inc. + +OUI:001711* + ID_OUI_FROM_DATABASE=GE Healthcare Bio-Sciences AB + +OUI:001712* + ID_OUI_FROM_DATABASE=ISCO International + +OUI:001713* + ID_OUI_FROM_DATABASE=Tiger NetCom + +OUI:001714* + ID_OUI_FROM_DATABASE=BR Controls Nederland bv + +OUI:001715* + ID_OUI_FROM_DATABASE=Qstik + +OUI:001716* + ID_OUI_FROM_DATABASE=Qno Technology Inc. + +OUI:001717* + ID_OUI_FROM_DATABASE=Leica Geosystems AG + +OUI:001718* + ID_OUI_FROM_DATABASE=Vansco Electronics Oy + +OUI:001719* + ID_OUI_FROM_DATABASE=AudioCodes USA, Inc + +OUI:00171A* + ID_OUI_FROM_DATABASE=Winegard Company + +OUI:00171B* + ID_OUI_FROM_DATABASE=Innovation Lab Corp. + +OUI:00171C* + ID_OUI_FROM_DATABASE=NT MicroSystems, Inc. + +OUI:00171D* + ID_OUI_FROM_DATABASE=DIGIT + +OUI:00171E* + ID_OUI_FROM_DATABASE=Theo Benning GmbH & Co. KG + +OUI:00171F* + ID_OUI_FROM_DATABASE=IMV Corporation + +OUI:001720* + ID_OUI_FROM_DATABASE=Image Sensing Systems, Inc. + +OUI:001721* + ID_OUI_FROM_DATABASE=FITRE S.p.A. + +OUI:001722* + ID_OUI_FROM_DATABASE=Hanazeder Electronic GmbH + +OUI:001723* + ID_OUI_FROM_DATABASE=Summit Data Communications + +OUI:001724* + ID_OUI_FROM_DATABASE=Studer Professional Audio GmbH + +OUI:001725* + ID_OUI_FROM_DATABASE=Liquid Computing + +OUI:001726* + ID_OUI_FROM_DATABASE=m2c Electronic Technology Ltd. + +OUI:001727* + ID_OUI_FROM_DATABASE=Thermo Ramsey Italia s.r.l. + +OUI:001728* + ID_OUI_FROM_DATABASE=Selex Communications + +OUI:001729* + ID_OUI_FROM_DATABASE=Ubicod Co.LTD + +OUI:00172A* + ID_OUI_FROM_DATABASE=Proware Technology Corp. + +OUI:00172B* + ID_OUI_FROM_DATABASE=Global Technologies Inc. + +OUI:00172C* + ID_OUI_FROM_DATABASE=TAEJIN INFOTECH + +OUI:00172D* + ID_OUI_FROM_DATABASE=Axcen Photonics Corporation + +OUI:00172E* + ID_OUI_FROM_DATABASE=FXC Inc. + +OUI:00172F* + ID_OUI_FROM_DATABASE=NeuLion Incorporated + +OUI:001730* + ID_OUI_FROM_DATABASE=Automation Electronics + +OUI:001731* + ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. + +OUI:001732* + ID_OUI_FROM_DATABASE=Science-Technical Center "RISSA" + +OUI:001733* + ID_OUI_FROM_DATABASE=SFR + +OUI:001734* + ID_OUI_FROM_DATABASE=ADC Telecommunications + +OUI:001736* + ID_OUI_FROM_DATABASE=iiTron Inc. + +OUI:001737* + ID_OUI_FROM_DATABASE=Industrie Dial Face S.p.A. + +OUI:001738* + ID_OUI_FROM_DATABASE=International Business Machines + +OUI:001739* + ID_OUI_FROM_DATABASE=Bright Headphone Electronics Company + +OUI:00173A* + ID_OUI_FROM_DATABASE=Reach Systems Inc. + +OUI:00173B* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc. + +OUI:00173C* + ID_OUI_FROM_DATABASE=Extreme Engineering Solutions + +OUI:00173D* + ID_OUI_FROM_DATABASE=Neology + +OUI:00173E* + ID_OUI_FROM_DATABASE=LeucotronEquipamentos Ltda. + +OUI:00173F* + ID_OUI_FROM_DATABASE=Belkin Corporation + +OUI:001740* + ID_OUI_FROM_DATABASE=Bluberi Gaming Technologies Inc + +OUI:001741* + ID_OUI_FROM_DATABASE=DEFIDEV + +OUI:001742* + ID_OUI_FROM_DATABASE=FUJITSU LIMITED + +OUI:001743* + ID_OUI_FROM_DATABASE=Deck Srl + +OUI:001744* + ID_OUI_FROM_DATABASE=Araneo Ltd. + +OUI:001745* + ID_OUI_FROM_DATABASE=INNOTZ CO., Ltd + +OUI:001746* + ID_OUI_FROM_DATABASE=Freedom9 Inc. + +OUI:001747* + ID_OUI_FROM_DATABASE=Trimble + +OUI:001748* + ID_OUI_FROM_DATABASE=Neokoros Brasil Ltda + +OUI:001749* + ID_OUI_FROM_DATABASE=HYUNDAE YONG-O-SA CO.,LTD + +OUI:00174A* + ID_OUI_FROM_DATABASE=SOCOMEC + +OUI:00174B* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:00174C* + ID_OUI_FROM_DATABASE=Millipore + +OUI:00174D* + ID_OUI_FROM_DATABASE=DYNAMIC NETWORK FACTORY, INC. + +OUI:00174E* + ID_OUI_FROM_DATABASE=Parama-tech Co.,Ltd. + +OUI:00174F* + ID_OUI_FROM_DATABASE=iCatch Inc. + +OUI:001750* + ID_OUI_FROM_DATABASE=GSI Group, MicroE Systems + +OUI:001751* + ID_OUI_FROM_DATABASE=Online Corporation + +OUI:001752* + ID_OUI_FROM_DATABASE=DAGS, Inc + +OUI:001753* + ID_OUI_FROM_DATABASE=nFore Technology Inc. + +OUI:001754* + ID_OUI_FROM_DATABASE=Arkino HiTOP Corporation Limited + +OUI:001755* + ID_OUI_FROM_DATABASE=GE Security + +OUI:001756* + ID_OUI_FROM_DATABASE=Vinci Labs Oy + +OUI:001757* + ID_OUI_FROM_DATABASE=RIX TECHNOLOGY LIMITED + +OUI:001758* + ID_OUI_FROM_DATABASE=ThruVision Ltd + +OUI:001759* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00175A* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00175B* + ID_OUI_FROM_DATABASE=ACS Solutions Switzerland Ltd. + +OUI:00175C* + ID_OUI_FROM_DATABASE=SHARP CORPORATION + +OUI:00175D* + ID_OUI_FROM_DATABASE=Dongseo system. + +OUI:00175E* + ID_OUI_FROM_DATABASE=Zed-3 + +OUI:00175F* + ID_OUI_FROM_DATABASE=XENOLINK Communications Co., Ltd. + +OUI:001760* + ID_OUI_FROM_DATABASE=Naito Densei Machida MFG.CO.,LTD + +OUI:001761* + ID_OUI_FROM_DATABASE=ZKSoftware Inc. + +OUI:001762* + ID_OUI_FROM_DATABASE=Solar Technology, Inc. + +OUI:001763* + ID_OUI_FROM_DATABASE=Essentia S.p.A. + +OUI:001764* + ID_OUI_FROM_DATABASE=ATMedia GmbH + +OUI:001765* + ID_OUI_FROM_DATABASE=Nortel + +OUI:001766* + ID_OUI_FROM_DATABASE=Accense Technology, Inc. + +OUI:001767* + ID_OUI_FROM_DATABASE=Earforce AS + +OUI:001768* + ID_OUI_FROM_DATABASE=Zinwave Ltd + +OUI:001769* + ID_OUI_FROM_DATABASE=Cymphonix Corp + +OUI:00176A* + ID_OUI_FROM_DATABASE=Avago Technologies + +OUI:00176B* + ID_OUI_FROM_DATABASE=Kiyon, Inc. + +OUI:00176C* + ID_OUI_FROM_DATABASE=Pivot3, Inc. + +OUI:00176D* + ID_OUI_FROM_DATABASE=CORE CORPORATION + +OUI:00176E* + ID_OUI_FROM_DATABASE=DUCATI SISTEMI + +OUI:00176F* + ID_OUI_FROM_DATABASE=PAX Computer Technology(Shenzhen) Ltd. + +OUI:001770* + ID_OUI_FROM_DATABASE=Arti Industrial Electronics Ltd. + +OUI:001771* + ID_OUI_FROM_DATABASE=APD Communications Ltd + +OUI:001772* + ID_OUI_FROM_DATABASE=ASTRO Strobel Kommunikationssysteme GmbH + +OUI:001773* + ID_OUI_FROM_DATABASE=Laketune Technologies Co. Ltd + +OUI:001774* + ID_OUI_FROM_DATABASE=Elesta GmbH + +OUI:001775* + ID_OUI_FROM_DATABASE=TTE Germany GmbH + +OUI:001776* + ID_OUI_FROM_DATABASE=Meso Scale Diagnostics, LLC + +OUI:001777* + ID_OUI_FROM_DATABASE=Obsidian Research Corporation + +OUI:001778* + ID_OUI_FROM_DATABASE=Central Music Co. + +OUI:001779* + ID_OUI_FROM_DATABASE=QuickTel + +OUI:00177A* + ID_OUI_FROM_DATABASE=ASSA ABLOY AB + +OUI:00177B* + ID_OUI_FROM_DATABASE=Azalea Networks inc + +OUI:00177C* + ID_OUI_FROM_DATABASE=Smartlink Network Systems Limited + +OUI:00177D* + ID_OUI_FROM_DATABASE=IDT International Limited + +OUI:00177E* + ID_OUI_FROM_DATABASE=Meshcom Technologies Inc. + +OUI:00177F* + ID_OUI_FROM_DATABASE=Worldsmart Retech + +OUI:001780* + ID_OUI_FROM_DATABASE=Applied Biosystems B.V. + +OUI:001781* + ID_OUI_FROM_DATABASE=Greystone Data System, Inc. + +OUI:001782* + ID_OUI_FROM_DATABASE=LoBenn Inc. + +OUI:001783* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:001784* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:001785* + ID_OUI_FROM_DATABASE=Sparr Electronics Ltd + +OUI:001786* + ID_OUI_FROM_DATABASE=wisembed + +OUI:001787* + ID_OUI_FROM_DATABASE=Brother, Brother & Sons ApS + +OUI:001788* + ID_OUI_FROM_DATABASE=Philips Lighting BV + +OUI:001789* + ID_OUI_FROM_DATABASE=Zenitron Corporation + +OUI:00178A* + ID_OUI_FROM_DATABASE=DARTS TECHNOLOGIES CORP. + +OUI:00178B* + ID_OUI_FROM_DATABASE=Teledyne Technologies Incorporated + +OUI:00178C* + ID_OUI_FROM_DATABASE=Independent Witness, Inc + +OUI:00178D* + ID_OUI_FROM_DATABASE=Checkpoint Systems, Inc. + +OUI:00178E* + ID_OUI_FROM_DATABASE=Gunnebo Cash Automation AB + +OUI:00178F* + ID_OUI_FROM_DATABASE=NINGBO YIDONG ELECTRONIC CO.,LTD. + +OUI:001790* + ID_OUI_FROM_DATABASE=HYUNDAI DIGITECH Co, Ltd. + +OUI:001791* + ID_OUI_FROM_DATABASE=LinTech GmbH + +OUI:001792* + ID_OUI_FROM_DATABASE=Falcom Wireless Comunications Gmbh + +OUI:001793* + ID_OUI_FROM_DATABASE=Tigi Corporation + +OUI:001794* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001795* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001796* + ID_OUI_FROM_DATABASE=Rittmeyer AG + +OUI:001797* + ID_OUI_FROM_DATABASE=Telsy Elettronica S.p.A. + +OUI:001798* + ID_OUI_FROM_DATABASE=Azonic Technology Co., LTD + +OUI:001799* + ID_OUI_FROM_DATABASE=SmarTire Systems Inc. + +OUI:00179A* + ID_OUI_FROM_DATABASE=D-Link Corporation + +OUI:00179B* + ID_OUI_FROM_DATABASE=Chant Sincere CO., LTD. + +OUI:00179C* + ID_OUI_FROM_DATABASE=DEPRAG SCHULZ GMBH u. CO. + +OUI:00179D* + ID_OUI_FROM_DATABASE=Kelman Limited + +OUI:00179E* + ID_OUI_FROM_DATABASE=Sirit Inc + +OUI:00179F* + ID_OUI_FROM_DATABASE=Apricorn + +OUI:0017A0* + ID_OUI_FROM_DATABASE=RoboTech srl + +OUI:0017A1* + ID_OUI_FROM_DATABASE=3soft inc. + +OUI:0017A2* + ID_OUI_FROM_DATABASE=Camrivox Ltd. + +OUI:0017A3* + ID_OUI_FROM_DATABASE=MIX s.r.l. + +OUI:0017A4* + ID_OUI_FROM_DATABASE=Hewlett-Packard Company + +OUI:0017A5* + ID_OUI_FROM_DATABASE=Ralink Technology Corp + +OUI:0017A6* + ID_OUI_FROM_DATABASE=YOSIN ELECTRONICS CO., LTD. + +OUI:0017A7* + ID_OUI_FROM_DATABASE=Mobile Computing Promotion Consortium + +OUI:0017A8* + ID_OUI_FROM_DATABASE=EDM Corporation + +OUI:0017A9* + ID_OUI_FROM_DATABASE=Sentivision + +OUI:0017AA* + ID_OUI_FROM_DATABASE=elab-experience inc. + +OUI:0017AB* + ID_OUI_FROM_DATABASE=Nintendo Co., Ltd. + +OUI:0017AC* + ID_OUI_FROM_DATABASE=O'Neil Product Development Inc. + +OUI:0017AD* + ID_OUI_FROM_DATABASE=AceNet Corporation + +OUI:0017AE* + ID_OUI_FROM_DATABASE=GAI-Tronics + +OUI:0017AF* + ID_OUI_FROM_DATABASE=Enermet + +OUI:0017B0* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:0017B1* + ID_OUI_FROM_DATABASE=ACIST Medical Systems, Inc. + +OUI:0017B2* + ID_OUI_FROM_DATABASE=SK Telesys + +OUI:0017B3* + ID_OUI_FROM_DATABASE=Aftek Infosys Limited + +OUI:0017B4* + ID_OUI_FROM_DATABASE=Remote Security Systems, LLC + +OUI:0017B5* + ID_OUI_FROM_DATABASE=Peerless Systems Corporation + +OUI:0017B6* + ID_OUI_FROM_DATABASE=Aquantia + +OUI:0017B7* + ID_OUI_FROM_DATABASE=Tonze Technology Co. + +OUI:0017B8* + ID_OUI_FROM_DATABASE=NOVATRON CO., LTD. + +OUI:0017B9* + ID_OUI_FROM_DATABASE=Gambro Lundia AB + +OUI:0017BA* + ID_OUI_FROM_DATABASE=SEDO CO., LTD. + +OUI:0017BB* + ID_OUI_FROM_DATABASE=Syrinx Industrial Electronics + +OUI:0017BC* + ID_OUI_FROM_DATABASE=Touchtunes Music Corporation + +OUI:0017BD* + ID_OUI_FROM_DATABASE=Tibetsystem + +OUI:0017BE* + ID_OUI_FROM_DATABASE=Tratec Telecom B.V. + +OUI:0017BF* + ID_OUI_FROM_DATABASE=Coherent Research Limited + +OUI:0017C0* + ID_OUI_FROM_DATABASE=PureTech Systems, Inc. + +OUI:0017C1* + ID_OUI_FROM_DATABASE=CM Precision Technology LTD. + +OUI:0017C2* + ID_OUI_FROM_DATABASE=ADB Broadband Italia + +OUI:0017C3* + ID_OUI_FROM_DATABASE=KTF Technologies Inc. + +OUI:0017C4* + ID_OUI_FROM_DATABASE=Quanta Microsystems, INC. + +OUI:0017C5* + ID_OUI_FROM_DATABASE=SonicWALL + +OUI:0017C6* + ID_OUI_FROM_DATABASE=Cross Match Technologies Inc + +OUI:0017C7* + ID_OUI_FROM_DATABASE=MARA Systems Consulting AB + +OUI:0017C8* + ID_OUI_FROM_DATABASE=Kyocera Mita Corporation + +OUI:0017C9* + ID_OUI_FROM_DATABASE=Samsung Electronics Co., Ltd. + +OUI:0017CA* + ID_OUI_FROM_DATABASE=Qisda Corporation + +OUI:0017CB* + ID_OUI_FROM_DATABASE=Juniper Networks + +OUI:0017CC* + ID_OUI_FROM_DATABASE=Alcatel-Lucent + +OUI:0017CD* + ID_OUI_FROM_DATABASE=CEC Wireless R&D Ltd. + +OUI:0017CE* + ID_OUI_FROM_DATABASE=Screen Service Spa + +OUI:0017CF* + ID_OUI_FROM_DATABASE=iMCA-GmbH + +OUI:0017D0* + ID_OUI_FROM_DATABASE=Opticom Communications, LLC + +OUI:0017D1* + ID_OUI_FROM_DATABASE=Nortel + +OUI:0017D2* + ID_OUI_FROM_DATABASE=THINLINX PTY LTD + +OUI:0017D3* + ID_OUI_FROM_DATABASE=Etymotic Research, Inc. + +OUI:0017D4* + ID_OUI_FROM_DATABASE=Monsoon Multimedia, Inc + +OUI:0017D5* + ID_OUI_FROM_DATABASE=Samsung Electronics Co., Ltd. + +OUI:0017D6* + ID_OUI_FROM_DATABASE=Bluechips Microhouse Co.,Ltd. + +OUI:0017D7* + ID_OUI_FROM_DATABASE=ION Geophysical Corporation Inc. + +OUI:0017D8* + ID_OUI_FROM_DATABASE=Magnum Semiconductor, Inc. + +OUI:0017D9* + ID_OUI_FROM_DATABASE=AAI Corporation + +OUI:0017DA* + ID_OUI_FROM_DATABASE=Spans Logic + +OUI:0017DB* + ID_OUI_FROM_DATABASE=CANKO TECHNOLOGIES INC. + +OUI:0017DC* + ID_OUI_FROM_DATABASE=DAEMYUNG ZERO1 + +OUI:0017DD* + ID_OUI_FROM_DATABASE=Clipsal Australia + +OUI:0017DE* + ID_OUI_FROM_DATABASE=Advantage Six Ltd + +OUI:0017DF* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0017E0* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0017E1* + ID_OUI_FROM_DATABASE=DACOS Technologies Co., Ltd. + +OUI:0017E2* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:0017E3* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:0017E4* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:0017E5* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:0017E6* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:0017E7* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:0017E8* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:0017E9* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:0017EA* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:0017EB* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:0017EC* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:0017ED* + ID_OUI_FROM_DATABASE=WooJooIT Ltd. + +OUI:0017EE* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:0017EF* + ID_OUI_FROM_DATABASE=IBM Corp + +OUI:0017F0* + ID_OUI_FROM_DATABASE=SZCOM Broadband Network Technology Co.,Ltd + +OUI:0017F1* + ID_OUI_FROM_DATABASE=Renu Electronics Pvt Ltd + +OUI:0017F2* + ID_OUI_FROM_DATABASE=Apple Computer + +OUI:0017F3* + ID_OUI_FROM_DATABASE=Harris Corparation + +OUI:0017F4* + ID_OUI_FROM_DATABASE=ZERON ALLIANCE + +OUI:0017F5* + ID_OUI_FROM_DATABASE=LIG NEOPTEK + +OUI:0017F6* + ID_OUI_FROM_DATABASE=Pyramid Meriden Inc. + +OUI:0017F7* + ID_OUI_FROM_DATABASE=CEM Solutions Pvt Ltd + +OUI:0017F8* + ID_OUI_FROM_DATABASE=Motech Industries Inc. + +OUI:0017F9* + ID_OUI_FROM_DATABASE=Forcom Sp. z o.o. + +OUI:0017FA* + ID_OUI_FROM_DATABASE=Microsoft Corporation + +OUI:0017FB* + ID_OUI_FROM_DATABASE=FA + +OUI:0017FC* + ID_OUI_FROM_DATABASE=Suprema Inc. + +OUI:0017FD* + ID_OUI_FROM_DATABASE=Amulet Hotkey + +OUI:0017FE* + ID_OUI_FROM_DATABASE=TALOS SYSTEM INC. + +OUI:0017FF* + ID_OUI_FROM_DATABASE=PLAYLINE Co.,Ltd. + +OUI:001800* + ID_OUI_FROM_DATABASE=UNIGRAND LTD + +OUI:001801* + ID_OUI_FROM_DATABASE=Actiontec Electronics, Inc + +OUI:001802* + ID_OUI_FROM_DATABASE=Alpha Networks Inc. + +OUI:001803* + ID_OUI_FROM_DATABASE=ArcSoft Shanghai Co. LTD + +OUI:001804* + ID_OUI_FROM_DATABASE=E-TEK DIGITAL TECHNOLOGY LIMITED + +OUI:001805* + ID_OUI_FROM_DATABASE=Beijing InHand Networking Technology Co.,Ltd. + +OUI:001806* + ID_OUI_FROM_DATABASE=Hokkei Industries Co., Ltd. + +OUI:001807* + ID_OUI_FROM_DATABASE=Fanstel Corp. + +OUI:001808* + ID_OUI_FROM_DATABASE=SightLogix, Inc. + +OUI:001809* + ID_OUI_FROM_DATABASE=CRESYN + +OUI:00180A* + ID_OUI_FROM_DATABASE=Meraki, Inc. + +OUI:00180B* + ID_OUI_FROM_DATABASE=Brilliant Telecommunications + +OUI:00180C* + ID_OUI_FROM_DATABASE=Optelian Access Networks + +OUI:00180D* + ID_OUI_FROM_DATABASE=Terabytes Server Storage Tech Corp + +OUI:00180E* + ID_OUI_FROM_DATABASE=Avega Systems + +OUI:00180F* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:001810* + ID_OUI_FROM_DATABASE=IPTrade S.A. + +OUI:001811* + ID_OUI_FROM_DATABASE=Neuros Technology International, LLC. + +OUI:001812* + ID_OUI_FROM_DATABASE=Beijing Xinwei Telecom Technology Co., Ltd. + +OUI:001813* + ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications + +OUI:001814* + ID_OUI_FROM_DATABASE=Mitutoyo Corporation + +OUI:001815* + ID_OUI_FROM_DATABASE=GZ Technologies, Inc. + +OUI:001816* + ID_OUI_FROM_DATABASE=Ubixon Co., Ltd. + +OUI:001817* + ID_OUI_FROM_DATABASE=D. E. Shaw Research, LLC + +OUI:001818* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001819* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00181A* + ID_OUI_FROM_DATABASE=AVerMedia Information Inc. + +OUI:00181B* + ID_OUI_FROM_DATABASE=TaiJin Metal Co., Ltd. + +OUI:00181C* + ID_OUI_FROM_DATABASE=Exterity Limited + +OUI:00181D* + ID_OUI_FROM_DATABASE=ASIA ELECTRONICS CO.,LTD + +OUI:00181E* + ID_OUI_FROM_DATABASE=GDX Technologies Ltd. + +OUI:00181F* + ID_OUI_FROM_DATABASE=Palmmicro Communications + +OUI:001820* + ID_OUI_FROM_DATABASE=w5networks + +OUI:001821* + ID_OUI_FROM_DATABASE=SINDORICOH + +OUI:001822* + ID_OUI_FROM_DATABASE=CEC TELECOM CO.,LTD. + +OUI:001823* + ID_OUI_FROM_DATABASE=Delta Electronics, Inc. + +OUI:001824* + ID_OUI_FROM_DATABASE=Kimaldi Electronics, S.L. + +OUI:001826* + ID_OUI_FROM_DATABASE=Cale Access AB + +OUI:001827* + ID_OUI_FROM_DATABASE=NEC UNIFIED SOLUTIONS NEDERLAND B.V. + +OUI:001828* + ID_OUI_FROM_DATABASE=e2v technologies (UK) ltd. + +OUI:001829* + ID_OUI_FROM_DATABASE=Gatsometer + +OUI:00182A* + ID_OUI_FROM_DATABASE=Taiwan Video & Monitor + +OUI:00182B* + ID_OUI_FROM_DATABASE=Softier + +OUI:00182C* + ID_OUI_FROM_DATABASE=Ascend Networks, Inc. + +OUI:00182D* + ID_OUI_FROM_DATABASE=Artec Group OÜ + +OUI:00182E* + ID_OUI_FROM_DATABASE=XStreamHD, LLC + +OUI:00182F* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:001830* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:001831* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:001832* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:001833* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:001834* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:001835* + ID_OUI_FROM_DATABASE=Thoratec / ITC + +OUI:001836* + ID_OUI_FROM_DATABASE=Reliance Electric Limited + +OUI:001837* + ID_OUI_FROM_DATABASE=Universal ABIT Co., Ltd. + +OUI:001838* + ID_OUI_FROM_DATABASE=PanAccess Communications,Inc. + +OUI:001839* + ID_OUI_FROM_DATABASE=Cisco-Linksys LLC + +OUI:00183A* + ID_OUI_FROM_DATABASE=Westell Technologies + +OUI:00183B* + ID_OUI_FROM_DATABASE=CENITS Co., Ltd. + +OUI:00183C* + ID_OUI_FROM_DATABASE=Encore Software Limited + +OUI:00183D* + ID_OUI_FROM_DATABASE=Vertex Link Corporation + +OUI:00183E* + ID_OUI_FROM_DATABASE=Digilent, Inc + +OUI:00183F* + ID_OUI_FROM_DATABASE=2Wire, Inc + +OUI:001840* + ID_OUI_FROM_DATABASE=3 Phoenix, Inc. + +OUI:001841* + ID_OUI_FROM_DATABASE=High Tech Computer Corp + +OUI:001842* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:001843* + ID_OUI_FROM_DATABASE=Dawevision Ltd + +OUI:001844* + ID_OUI_FROM_DATABASE=Heads Up Technologies, Inc. + +OUI:001845* + ID_OUI_FROM_DATABASE=NPL Pulsar Ltd. + +OUI:001846* + ID_OUI_FROM_DATABASE=Crypto S.A. + +OUI:001847* + ID_OUI_FROM_DATABASE=AceNet Technology Inc. + +OUI:001848* + ID_OUI_FROM_DATABASE=Vecima Networks Inc. + +OUI:001849* + ID_OUI_FROM_DATABASE=Pigeon Point Systems + +OUI:00184A* + ID_OUI_FROM_DATABASE=Catcher, Inc. + +OUI:00184B* + ID_OUI_FROM_DATABASE=Las Vegas Gaming, Inc. + +OUI:00184C* + ID_OUI_FROM_DATABASE=Bogen Communications + +OUI:00184D* + ID_OUI_FROM_DATABASE=Netgear Inc. + +OUI:00184E* + ID_OUI_FROM_DATABASE=Lianhe Technologies, Inc. + +OUI:00184F* + ID_OUI_FROM_DATABASE=8 Ways Technology Corp. + +OUI:001850* + ID_OUI_FROM_DATABASE=Secfone Kft + +OUI:001851* + ID_OUI_FROM_DATABASE=SWsoft + +OUI:001852* + ID_OUI_FROM_DATABASE=StorLink Semiconductors, Inc. + +OUI:001853* + ID_OUI_FROM_DATABASE=Atera Networks LTD. + +OUI:001854* + ID_OUI_FROM_DATABASE=Argard Co., Ltd + +OUI:001855* + ID_OUI_FROM_DATABASE=Aeromaritime Systembau GmbH + +OUI:001856* + ID_OUI_FROM_DATABASE=EyeFi, Inc + +OUI:001857* + ID_OUI_FROM_DATABASE=Unilever R&D + +OUI:001858* + ID_OUI_FROM_DATABASE=TagMaster AB + +OUI:001859* + ID_OUI_FROM_DATABASE=Strawberry Linux Co.,Ltd. + +OUI:00185A* + ID_OUI_FROM_DATABASE=uControl, Inc. + +OUI:00185B* + ID_OUI_FROM_DATABASE=Network Chemistry, Inc + +OUI:00185C* + ID_OUI_FROM_DATABASE=EDS Lab Pte Ltd + +OUI:00185D* + ID_OUI_FROM_DATABASE=TAIGUEN TECHNOLOGY (SHEN-ZHEN) CO., LTD. + +OUI:00185E* + ID_OUI_FROM_DATABASE=Nexterm Inc. + +OUI:00185F* + ID_OUI_FROM_DATABASE=TAC Inc. + +OUI:001860* + ID_OUI_FROM_DATABASE=SIM Technology Group Shanghai Simcom Ltd., + +OUI:001861* + ID_OUI_FROM_DATABASE=Ooma, Inc. + +OUI:001862* + ID_OUI_FROM_DATABASE=Seagate Technology + +OUI:001863* + ID_OUI_FROM_DATABASE=Veritech Electronics Limited + +OUI:001864* + ID_OUI_FROM_DATABASE=Cybectec Inc. + +OUI:001865* + ID_OUI_FROM_DATABASE=Siemens Healthcare Diagnostics Manufacturing Ltd + +OUI:001866* + ID_OUI_FROM_DATABASE=Leutron Vision + +OUI:001867* + ID_OUI_FROM_DATABASE=Evolution Robotics Retail + +OUI:001868* + ID_OUI_FROM_DATABASE=Scientific Atlanta, A Cisco Company + +OUI:001869* + ID_OUI_FROM_DATABASE=KINGJIM + +OUI:00186A* + ID_OUI_FROM_DATABASE=Global Link Digital Technology Co,.LTD + +OUI:00186B* + ID_OUI_FROM_DATABASE=Sambu Communics CO., LTD. + +OUI:00186C* + ID_OUI_FROM_DATABASE=Neonode AB + +OUI:00186D* + ID_OUI_FROM_DATABASE=Zhenjiang Sapphire Electronic Industry CO. + +OUI:00186E* + ID_OUI_FROM_DATABASE=3Com Ltd + +OUI:00186F* + ID_OUI_FROM_DATABASE=Setha Industria Eletronica LTDA + +OUI:001870* + ID_OUI_FROM_DATABASE=E28 Shanghai Limited + +OUI:001871* + ID_OUI_FROM_DATABASE=Hewlett-Packard Company + +OUI:001872* + ID_OUI_FROM_DATABASE=Expertise Engineering + +OUI:001873* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001874* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001875* + ID_OUI_FROM_DATABASE=AnaCise Testnology Pte Ltd + +OUI:001876* + ID_OUI_FROM_DATABASE=WowWee Ltd. + +OUI:001877* + ID_OUI_FROM_DATABASE=Amplex A/S + +OUI:001878* + ID_OUI_FROM_DATABASE=Mackware GmbH + +OUI:001879* + ID_OUI_FROM_DATABASE=dSys + +OUI:00187A* + ID_OUI_FROM_DATABASE=Wiremold + +OUI:00187B* + ID_OUI_FROM_DATABASE=4NSYS Co. Ltd. + +OUI:00187C* + ID_OUI_FROM_DATABASE=INTERCROSS, LLC + +OUI:00187D* + ID_OUI_FROM_DATABASE=Armorlink shanghai Co. Ltd + +OUI:00187E* + ID_OUI_FROM_DATABASE=RGB Spectrum + +OUI:00187F* + ID_OUI_FROM_DATABASE=ZODIANET + +OUI:001880* + ID_OUI_FROM_DATABASE=Maxim Integrated Products + +OUI:001881* + ID_OUI_FROM_DATABASE=Buyang Electronics Industrial Co., Ltd + +OUI:001882* + ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd. + +OUI:001883* + ID_OUI_FROM_DATABASE=FORMOSA21 INC. + +OUI:001884* + ID_OUI_FROM_DATABASE=Fon Technology S.L. + +OUI:001885* + ID_OUI_FROM_DATABASE=Avigilon Corporation + +OUI:001886* + ID_OUI_FROM_DATABASE=EL-TECH, INC. + +OUI:001887* + ID_OUI_FROM_DATABASE=Metasystem SpA + +OUI:001888* + ID_OUI_FROM_DATABASE=GOTIVE a.s. + +OUI:001889* + ID_OUI_FROM_DATABASE=WinNet Solutions Limited + +OUI:00188A* + ID_OUI_FROM_DATABASE=Infinova LLC + +OUI:00188B* + ID_OUI_FROM_DATABASE=Dell + +OUI:00188C* + ID_OUI_FROM_DATABASE=Mobile Action Technology Inc. + +OUI:00188D* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:00188E* + ID_OUI_FROM_DATABASE=Ekahau, Inc. + +OUI:00188F* + ID_OUI_FROM_DATABASE=Montgomery Technology, Inc. + +OUI:001890* + ID_OUI_FROM_DATABASE=RadioCOM, s.r.o. + +OUI:001891* + ID_OUI_FROM_DATABASE=Zhongshan General K-mate Electronics Co., Ltd + +OUI:001892* + ID_OUI_FROM_DATABASE=ads-tec GmbH + +OUI:001893* + ID_OUI_FROM_DATABASE=SHENZHEN PHOTON BROADBAND TECHNOLOGY CO.,LTD + +OUI:001894* + ID_OUI_FROM_DATABASE=zimocom + +OUI:001895* + ID_OUI_FROM_DATABASE=Hansun Technologies Inc. + +OUI:001896* + ID_OUI_FROM_DATABASE=Great Well Electronic LTD + +OUI:001897* + ID_OUI_FROM_DATABASE=JESS-LINK PRODUCTS Co., LTD + +OUI:001898* + ID_OUI_FROM_DATABASE=KINGSTATE ELECTRONICS CORPORATION + +OUI:001899* + ID_OUI_FROM_DATABASE=ShenZhen jieshun Science&Technology Industry CO,LTD. + +OUI:00189A* + ID_OUI_FROM_DATABASE=HANA Micron Inc. + +OUI:00189B* + ID_OUI_FROM_DATABASE=Thomson Inc. + +OUI:00189C* + ID_OUI_FROM_DATABASE=Weldex Corporation + +OUI:00189D* + ID_OUI_FROM_DATABASE=Navcast Inc. + +OUI:00189E* + ID_OUI_FROM_DATABASE=OMNIKEY GmbH. + +OUI:00189F* + ID_OUI_FROM_DATABASE=Lenntek Corporation + +OUI:0018A0* + ID_OUI_FROM_DATABASE=Cierma Ascenseurs + +OUI:0018A1* + ID_OUI_FROM_DATABASE=Tiqit Computers, Inc. + +OUI:0018A2* + ID_OUI_FROM_DATABASE=XIP Technology AB + +OUI:0018A3* + ID_OUI_FROM_DATABASE=ZIPPY TECHNOLOGY CORP. + +OUI:0018A4* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:0018A5* + ID_OUI_FROM_DATABASE=ADigit Technologies Corp. + +OUI:0018A6* + ID_OUI_FROM_DATABASE=Persistent Systems, LLC + +OUI:0018A7* + ID_OUI_FROM_DATABASE=Yoggie Security Systems LTD. + +OUI:0018A8* + ID_OUI_FROM_DATABASE=AnNeal Technology Inc. + +OUI:0018A9* + ID_OUI_FROM_DATABASE=Ethernet Direct Corporation + +OUI:0018AA* + ID_OUI_FROM_DATABASE=Protec Fire Detection plc + +OUI:0018AB* + ID_OUI_FROM_DATABASE=BEIJING LHWT MICROELECTRONICS INC. + +OUI:0018AC* + ID_OUI_FROM_DATABASE=Shanghai Jiao Da HISYS Technology Co. Ltd. + +OUI:0018AD* + ID_OUI_FROM_DATABASE=NIDEC SANKYO CORPORATION + +OUI:0018AE* + ID_OUI_FROM_DATABASE=TVT CO.,LTD + +OUI:0018AF* + ID_OUI_FROM_DATABASE=Samsung Electronics Co., Ltd. + +OUI:0018B0* + ID_OUI_FROM_DATABASE=Nortel + +OUI:0018B1* + ID_OUI_FROM_DATABASE=IBM Corp + +OUI:0018B2* + ID_OUI_FROM_DATABASE=ADEUNIS RF + +OUI:0018B3* + ID_OUI_FROM_DATABASE=TEC WizHome Co., Ltd. + +OUI:0018B4* + ID_OUI_FROM_DATABASE=Dawon Media Inc. + +OUI:0018B5* + ID_OUI_FROM_DATABASE=Magna Carta + +OUI:0018B6* + ID_OUI_FROM_DATABASE=S3C, Inc. + +OUI:0018B7* + ID_OUI_FROM_DATABASE=D3 LED, LLC + +OUI:0018B8* + ID_OUI_FROM_DATABASE=New Voice International AG + +OUI:0018B9* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0018BA* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0018BB* + ID_OUI_FROM_DATABASE=Eliwell Controls srl + +OUI:0018BC* + ID_OUI_FROM_DATABASE=ZAO NVP Bolid + +OUI:0018BD* + ID_OUI_FROM_DATABASE=SHENZHEN DVBWORLD TECHNOLOGY CO., LTD. + +OUI:0018BE* + ID_OUI_FROM_DATABASE=ANSA Corporation + +OUI:0018BF* + ID_OUI_FROM_DATABASE=Essence Technology Solution, Inc. + +OUI:0018C0* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:0018C1* + ID_OUI_FROM_DATABASE=Almitec Informática e Comércio + +OUI:0018C2* + ID_OUI_FROM_DATABASE=Firetide, Inc + +OUI:0018C3* + ID_OUI_FROM_DATABASE=CS Corporation + +OUI:0018C4* + ID_OUI_FROM_DATABASE=Raba Technologies LLC + +OUI:0018C5* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:0018C6* + ID_OUI_FROM_DATABASE=OPW Fuel Management Systems + +OUI:0018C7* + ID_OUI_FROM_DATABASE=Real Time Automation + +OUI:0018C8* + ID_OUI_FROM_DATABASE=ISONAS Inc. + +OUI:0018C9* + ID_OUI_FROM_DATABASE=EOps Technology Limited + +OUI:0018CA* + ID_OUI_FROM_DATABASE=Viprinet GmbH + +OUI:0018CB* + ID_OUI_FROM_DATABASE=Tecobest Technology Limited + +OUI:0018CC* + ID_OUI_FROM_DATABASE=AXIOHM SAS + +OUI:0018CD* + ID_OUI_FROM_DATABASE=Erae Electronics Industry Co., Ltd + +OUI:0018CE* + ID_OUI_FROM_DATABASE=Dreamtech Co., Ltd + +OUI:0018CF* + ID_OUI_FROM_DATABASE=Baldor Electric Company + +OUI:0018D0* + ID_OUI_FROM_DATABASE=AtRoad, A Trimble Company + +OUI:0018D1* + ID_OUI_FROM_DATABASE=Siemens Home & Office Comm. Devices + +OUI:0018D2* + ID_OUI_FROM_DATABASE=High-Gain Antennas LLC + +OUI:0018D3* + ID_OUI_FROM_DATABASE=TEAMCAST + +OUI:0018D4* + ID_OUI_FROM_DATABASE=Unified Display Interface SIG + +OUI:0018D5* + ID_OUI_FROM_DATABASE=REIGNCOM + +OUI:0018D6* + ID_OUI_FROM_DATABASE=Swirlnet A/S + +OUI:0018D7* + ID_OUI_FROM_DATABASE=Javad Navigation Systems Inc. + +OUI:0018D8* + ID_OUI_FROM_DATABASE=ARCH METER Corporation + +OUI:0018D9* + ID_OUI_FROM_DATABASE=Santosha Internatonal, Inc + +OUI:0018DA* + ID_OUI_FROM_DATABASE=AMBER wireless GmbH + +OUI:0018DB* + ID_OUI_FROM_DATABASE=EPL Technology Ltd + +OUI:0018DC* + ID_OUI_FROM_DATABASE=Prostar Co., Ltd. + +OUI:0018DD* + ID_OUI_FROM_DATABASE=Silicondust Engineering Ltd + +OUI:0018DE* + ID_OUI_FROM_DATABASE=Intel Corporation + +OUI:0018DF* + ID_OUI_FROM_DATABASE=The Morey Corporation + +OUI:0018E0* + ID_OUI_FROM_DATABASE=ANAVEO + +OUI:0018E1* + ID_OUI_FROM_DATABASE=Verkerk Service Systemen + +OUI:0018E2* + ID_OUI_FROM_DATABASE=Topdata Sistemas de Automacao Ltda + +OUI:0018E3* + ID_OUI_FROM_DATABASE=Visualgate Systems, Inc. + +OUI:0018E4* + ID_OUI_FROM_DATABASE=YIGUANG + +OUI:0018E5* + ID_OUI_FROM_DATABASE=Adhoco AG + +OUI:0018E6* + ID_OUI_FROM_DATABASE=Computer Hardware Design SIA + +OUI:0018E7* + ID_OUI_FROM_DATABASE=Cameo Communications, INC. + +OUI:0018E8* + ID_OUI_FROM_DATABASE=Hacetron Corporation + +OUI:0018E9* + ID_OUI_FROM_DATABASE=Numata Corporation + +OUI:0018EA* + ID_OUI_FROM_DATABASE=Alltec GmbH + +OUI:0018EB* + ID_OUI_FROM_DATABASE=BroVis Wireless Networks + +OUI:0018EC* + ID_OUI_FROM_DATABASE=Welding Technology Corporation + +OUI:0018ED* + ID_OUI_FROM_DATABASE=Accutech Ultrasystems Co., Ltd. + +OUI:0018EE* + ID_OUI_FROM_DATABASE=Videology Imaging Solutions, Inc. + +OUI:0018EF* + ID_OUI_FROM_DATABASE=Escape Communications, Inc. + +OUI:0018F0* + ID_OUI_FROM_DATABASE=JOYTOTO Co., Ltd. + +OUI:0018F1* + ID_OUI_FROM_DATABASE=Chunichi Denshi Co.,LTD. + +OUI:0018F2* + ID_OUI_FROM_DATABASE=Beijing Tianyu Communication Equipment Co., Ltd + +OUI:0018F3* + ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. + +OUI:0018F4* + ID_OUI_FROM_DATABASE=EO TECHNICS Co., Ltd. + +OUI:0018F5* + ID_OUI_FROM_DATABASE=Shenzhen Streaming Video Technology Company Limited + +OUI:0018F6* + ID_OUI_FROM_DATABASE=Thomson Telecom Belgium + +OUI:0018F7* + ID_OUI_FROM_DATABASE=Kameleon Technologies + +OUI:0018F8* + ID_OUI_FROM_DATABASE=Cisco-Linksys LLC + +OUI:0018F9* + ID_OUI_FROM_DATABASE=VVOND, Inc. + +OUI:0018FA* + ID_OUI_FROM_DATABASE=Yushin Precision Equipment Co.,Ltd. + +OUI:0018FB* + ID_OUI_FROM_DATABASE=Compro Technology + +OUI:0018FC* + ID_OUI_FROM_DATABASE=Altec Electronic AG + +OUI:0018FD* + ID_OUI_FROM_DATABASE=Optimal Technologies International Inc. + +OUI:0018FE* + ID_OUI_FROM_DATABASE=Hewlett-Packard Company + +OUI:0018FF* + ID_OUI_FROM_DATABASE=PowerQuattro Co. + +OUI:001900* + ID_OUI_FROM_DATABASE=Intelliverese - DBA Voicecom + +OUI:001901* + ID_OUI_FROM_DATABASE=F1MEDIA + +OUI:001902* + ID_OUI_FROM_DATABASE=Cambridge Consultants Ltd + +OUI:001903* + ID_OUI_FROM_DATABASE=Bigfoot Networks Inc + +OUI:001904* + ID_OUI_FROM_DATABASE=WB Electronics Sp. z o.o. + +OUI:001905* + ID_OUI_FROM_DATABASE=SCHRACK Seconet AG + +OUI:001906* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001907* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001908* + ID_OUI_FROM_DATABASE=Duaxes Corporation + +OUI:001909* + ID_OUI_FROM_DATABASE=Devi A/S + +OUI:00190A* + ID_OUI_FROM_DATABASE=HASWARE INC. + +OUI:00190B* + ID_OUI_FROM_DATABASE=Southern Vision Systems, Inc. + +OUI:00190C* + ID_OUI_FROM_DATABASE=Encore Electronics, Inc. + +OUI:00190D* + ID_OUI_FROM_DATABASE=IEEE 1394c + +OUI:00190E* + ID_OUI_FROM_DATABASE=Atech Technology Co., Ltd. + +OUI:00190F* + ID_OUI_FROM_DATABASE=Advansus Corp. + +OUI:001910* + ID_OUI_FROM_DATABASE=Knick Elektronische Messgeraete GmbH & Co. KG + +OUI:001911* + ID_OUI_FROM_DATABASE=Just In Mobile Information Technologies (Shanghai) Co., Ltd. + +OUI:001912* + ID_OUI_FROM_DATABASE=Welcat Inc + +OUI:001913* + ID_OUI_FROM_DATABASE=Chuang-Yi Network Equipment Co.Ltd. + +OUI:001914* + ID_OUI_FROM_DATABASE=Winix Co., Ltd + +OUI:001915* + ID_OUI_FROM_DATABASE=TECOM Co., Ltd. + +OUI:001916* + ID_OUI_FROM_DATABASE=PayTec AG + +OUI:001917* + ID_OUI_FROM_DATABASE=Posiflex Inc. + +OUI:001918* + ID_OUI_FROM_DATABASE=Interactive Wear AG + +OUI:001919* + ID_OUI_FROM_DATABASE=ASTEL Inc. + +OUI:00191A* + ID_OUI_FROM_DATABASE=IRLINK + +OUI:00191B* + ID_OUI_FROM_DATABASE=Sputnik Engineering AG + +OUI:00191C* + ID_OUI_FROM_DATABASE=Sensicast Systems + +OUI:00191D* + ID_OUI_FROM_DATABASE=Nintendo Co.,Ltd. + +OUI:00191E* + ID_OUI_FROM_DATABASE=Beyondwiz Co., Ltd. + +OUI:00191F* + ID_OUI_FROM_DATABASE=Microlink communications Inc. + +OUI:001920* + ID_OUI_FROM_DATABASE=KUME electric Co.,Ltd. + +OUI:001921* + ID_OUI_FROM_DATABASE=Elitegroup Computer System Co. + +OUI:001922* + ID_OUI_FROM_DATABASE=CM Comandos Lineares + +OUI:001923* + ID_OUI_FROM_DATABASE=Phonex Korea Co., LTD. + +OUI:001924* + ID_OUI_FROM_DATABASE=LBNL Engineering + +OUI:001925* + ID_OUI_FROM_DATABASE=Intelicis Corporation + +OUI:001926* + ID_OUI_FROM_DATABASE=BitsGen Co., Ltd. + +OUI:001927* + ID_OUI_FROM_DATABASE=ImCoSys Ltd + +OUI:001928* + ID_OUI_FROM_DATABASE=Siemens AG, Transportation Systems + +OUI:001929* + ID_OUI_FROM_DATABASE=2M2B Montadora de Maquinas Bahia Brasil LTDA + +OUI:00192A* + ID_OUI_FROM_DATABASE=Antiope Associates + +OUI:00192B* + ID_OUI_FROM_DATABASE=Aclara RF Systems Inc. + +OUI:00192C* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:00192D* + ID_OUI_FROM_DATABASE=Nokia Corporation + +OUI:00192E* + ID_OUI_FROM_DATABASE=Spectral Instruments, Inc. + +OUI:00192F* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001930* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001931* + ID_OUI_FROM_DATABASE=Balluff GmbH + +OUI:001932* + ID_OUI_FROM_DATABASE=Gude Analog- und Digialsysteme GmbH + +OUI:001933* + ID_OUI_FROM_DATABASE=Strix Systems, Inc. + +OUI:001934* + ID_OUI_FROM_DATABASE=TRENDON TOUCH TECHNOLOGY CORP. + +OUI:001935* + ID_OUI_FROM_DATABASE=Duerr Dental GmbH & Co. KG + +OUI:001936* + ID_OUI_FROM_DATABASE=STERLITE OPTICAL TECHNOLOGIES LIMITED + +OUI:001937* + ID_OUI_FROM_DATABASE=CommerceGuard AB + +OUI:001938* + ID_OUI_FROM_DATABASE=UMB Communications Co., Ltd. + +OUI:001939* + ID_OUI_FROM_DATABASE=Gigamips + +OUI:00193A* + ID_OUI_FROM_DATABASE=OESOLUTIONS + +OUI:00193B* + ID_OUI_FROM_DATABASE=Wilibox Deliberant Group LLC + +OUI:00193C* + ID_OUI_FROM_DATABASE=HighPoint Technologies Incorporated + +OUI:00193D* + ID_OUI_FROM_DATABASE=GMC Guardian Mobility Corp. + +OUI:00193E* + ID_OUI_FROM_DATABASE=ADB Broadband Italia + +OUI:00193F* + ID_OUI_FROM_DATABASE=RDI technology(Shenzhen) Co.,LTD + +OUI:001940* + ID_OUI_FROM_DATABASE=Rackable Systems + +OUI:001941* + ID_OUI_FROM_DATABASE=Pitney Bowes, Inc + +OUI:001942* + ID_OUI_FROM_DATABASE=ON SOFTWARE INTERNATIONAL LIMITED + +OUI:001943* + ID_OUI_FROM_DATABASE=Belden + +OUI:001944* + ID_OUI_FROM_DATABASE=Fossil Partners, L.P. + +OUI:001945* + ID_OUI_FROM_DATABASE=Ten-Tec Inc. + +OUI:001946* + ID_OUI_FROM_DATABASE=Cianet Industria e Comercio S/A + +OUI:001947* + ID_OUI_FROM_DATABASE=Scientific Atlanta, A Cisco Company + +OUI:001948* + ID_OUI_FROM_DATABASE=AireSpider Networks + +OUI:001949* + ID_OUI_FROM_DATABASE=TENTEL COMTECH CO., LTD. + +OUI:00194A* + ID_OUI_FROM_DATABASE=TESTO AG + +OUI:00194B* + ID_OUI_FROM_DATABASE=SAGEM COMMUNICATION + +OUI:00194C* + ID_OUI_FROM_DATABASE=Fujian Stelcom information & Technology CO.,Ltd + +OUI:00194D* + ID_OUI_FROM_DATABASE=Avago Technologies Sdn Bhd + +OUI:00194E* + ID_OUI_FROM_DATABASE=Ultra Electronics - TCS (Tactical Communication Systems) + +OUI:00194F* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:001950* + ID_OUI_FROM_DATABASE=Harman Multimedia + +OUI:001951* + ID_OUI_FROM_DATABASE=NETCONS, s.r.o. + +OUI:001952* + ID_OUI_FROM_DATABASE=ACOGITO Co., Ltd + +OUI:001953* + ID_OUI_FROM_DATABASE=Chainleader Communications Corp. + +OUI:001954* + ID_OUI_FROM_DATABASE=Leaf Corporation. + +OUI:001955* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001956* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001957* + ID_OUI_FROM_DATABASE=Saafnet Canada Inc. + +OUI:001958* + ID_OUI_FROM_DATABASE=Bluetooth SIG, Inc. + +OUI:001959* + ID_OUI_FROM_DATABASE=Staccato Communications Inc. + +OUI:00195A* + ID_OUI_FROM_DATABASE=Jenaer Antriebstechnik GmbH + +OUI:00195B* + ID_OUI_FROM_DATABASE=D-Link Corporation + +OUI:00195C* + ID_OUI_FROM_DATABASE=Innotech Corporation + +OUI:00195D* + ID_OUI_FROM_DATABASE=ShenZhen XinHuaTong Opto Electronics Co.,Ltd + +OUI:00195E* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:00195F* + ID_OUI_FROM_DATABASE=Valemount Networks Corporation + +OUI:001960* + ID_OUI_FROM_DATABASE=DoCoMo Systems, Inc. + +OUI:001961* + ID_OUI_FROM_DATABASE=Blaupunkt Embedded Systems GmbH + +OUI:001962* + ID_OUI_FROM_DATABASE=Commerciant, LP + +OUI:001963* + ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications AB + +OUI:001964* + ID_OUI_FROM_DATABASE=Doorking Inc. + +OUI:001965* + ID_OUI_FROM_DATABASE=YuHua TelTech (ShangHai) Co., Ltd. + +OUI:001966* + ID_OUI_FROM_DATABASE=Asiarock Technology Limited + +OUI:001967* + ID_OUI_FROM_DATABASE=TELDAT Sp.J. + +OUI:001968* + ID_OUI_FROM_DATABASE=Digital Video Networks(Shanghai) CO. LTD. + +OUI:001969* + ID_OUI_FROM_DATABASE=Nortel + +OUI:00196A* + ID_OUI_FROM_DATABASE=MikroM GmbH + +OUI:00196B* + ID_OUI_FROM_DATABASE=Danpex Corporation + +OUI:00196C* + ID_OUI_FROM_DATABASE=ETROVISION TECHNOLOGY + +OUI:00196D* + ID_OUI_FROM_DATABASE=Raybit Systems Korea, Inc + +OUI:00196E* + ID_OUI_FROM_DATABASE=Metacom (Pty) Ltd. + +OUI:00196F* + ID_OUI_FROM_DATABASE=SensoPart GmbH + +OUI:001970* + ID_OUI_FROM_DATABASE=Z-Com, Inc. + +OUI:001971* + ID_OUI_FROM_DATABASE=Guangzhou Unicomp Technology Co.,Ltd + +OUI:001972* + ID_OUI_FROM_DATABASE=Plexus (Xiamen) Co.,ltd + +OUI:001973* + ID_OUI_FROM_DATABASE=Zeugma Systems + +OUI:001974* + ID_OUI_FROM_DATABASE=AboCom Systems, Inc. + +OUI:001975* + ID_OUI_FROM_DATABASE=Beijing Huisen networks technology Inc + +OUI:001976* + ID_OUI_FROM_DATABASE=Xipher Technologies, LLC + +OUI:001977* + ID_OUI_FROM_DATABASE=Aerohive Networks, Inc. + +OUI:001978* + ID_OUI_FROM_DATABASE=Datum Systems, Inc. + +OUI:001979* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:00197A* + ID_OUI_FROM_DATABASE=MAZeT GmbH + +OUI:00197B* + ID_OUI_FROM_DATABASE=Picotest Corp. + +OUI:00197C* + ID_OUI_FROM_DATABASE=Riedel Communications GmbH + +OUI:00197D* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co., Ltd + +OUI:00197E* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co., Ltd + +OUI:00197F* + ID_OUI_FROM_DATABASE=PLANTRONICS, INC. + +OUI:001980* + ID_OUI_FROM_DATABASE=Gridpoint Systems + +OUI:001981* + ID_OUI_FROM_DATABASE=Vivox Inc + +OUI:001982* + ID_OUI_FROM_DATABASE=SmarDTV + +OUI:001983* + ID_OUI_FROM_DATABASE=CCT R&D Limited + +OUI:001984* + ID_OUI_FROM_DATABASE=ESTIC Corporation + +OUI:001985* + ID_OUI_FROM_DATABASE=IT Watchdogs, Inc + +OUI:001986* + ID_OUI_FROM_DATABASE=Cheng Hongjian + +OUI:001987* + ID_OUI_FROM_DATABASE=Panasonic Mobile Communications Co., Ltd. + +OUI:001988* + ID_OUI_FROM_DATABASE=Wi2Wi, Inc + +OUI:001989* + ID_OUI_FROM_DATABASE=Sonitrol Corporation + +OUI:00198A* + ID_OUI_FROM_DATABASE=Northrop Grumman Systems Corp. + +OUI:00198B* + ID_OUI_FROM_DATABASE=Novera Optics Korea, Inc. + +OUI:00198C* + ID_OUI_FROM_DATABASE=iXSea + +OUI:00198D* + ID_OUI_FROM_DATABASE=Ocean Optics, Inc. + +OUI:00198E* + ID_OUI_FROM_DATABASE=Oticon A/S + +OUI:00198F* + ID_OUI_FROM_DATABASE=Alcatel Bell N.V. + +OUI:001990* + ID_OUI_FROM_DATABASE=ELM DATA Co., Ltd. + +OUI:001991* + ID_OUI_FROM_DATABASE=avinfo + +OUI:001992* + ID_OUI_FROM_DATABASE=ADTRAN INC. + +OUI:001993* + ID_OUI_FROM_DATABASE=Changshu Switchgear MFG. Co.,Ltd. (Former Changshu Switchgea + +OUI:001994* + ID_OUI_FROM_DATABASE=Jorjin Technologies Inc. + +OUI:001995* + ID_OUI_FROM_DATABASE=Jurong Hi-Tech (Suzhou)Co.ltd + +OUI:001996* + ID_OUI_FROM_DATABASE=TurboChef Technologies Inc. + +OUI:001997* + ID_OUI_FROM_DATABASE=Soft Device Sdn Bhd + +OUI:001998* + ID_OUI_FROM_DATABASE=SATO CORPORATION + +OUI:001999* + ID_OUI_FROM_DATABASE=Fujitsu Technology Solutions + +OUI:00199A* + ID_OUI_FROM_DATABASE=EDO-EVI + +OUI:00199B* + ID_OUI_FROM_DATABASE=Diversified Technical Systems, Inc. + +OUI:00199C* + ID_OUI_FROM_DATABASE=CTRING + +OUI:00199D* + ID_OUI_FROM_DATABASE=VIZIO, Inc. + +OUI:00199E* + ID_OUI_FROM_DATABASE=SHOWADENSHI ELECTRONICS,INC. + +OUI:00199F* + ID_OUI_FROM_DATABASE=DKT A/S + +OUI:0019A0* + ID_OUI_FROM_DATABASE=NIHON DATA SYSTENS, INC. + +OUI:0019A1* + ID_OUI_FROM_DATABASE=LG INFORMATION & COMM. + +OUI:0019A2* + ID_OUI_FROM_DATABASE=ORDYN TECHNOLOGIES + +OUI:0019A3* + ID_OUI_FROM_DATABASE=asteel electronique atlantique + +OUI:0019A4* + ID_OUI_FROM_DATABASE=Austar Technology (hang zhou) Co.,Ltd + +OUI:0019A5* + ID_OUI_FROM_DATABASE=RadarFind Corporation + +OUI:0019A6* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:0019A7* + ID_OUI_FROM_DATABASE=ITU-T + +OUI:0019A8* + ID_OUI_FROM_DATABASE=WiQuest Communications + +OUI:0019A9* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0019AA* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0019AB* + ID_OUI_FROM_DATABASE=Raycom CO ., LTD + +OUI:0019AC* + ID_OUI_FROM_DATABASE=GSP SYSTEMS Inc. + +OUI:0019AD* + ID_OUI_FROM_DATABASE=BOBST SA + +OUI:0019AE* + ID_OUI_FROM_DATABASE=Hopling Technologies b.v. + +OUI:0019AF* + ID_OUI_FROM_DATABASE=Rigol Technologies, Inc. + +OUI:0019B0* + ID_OUI_FROM_DATABASE=HanYang System + +OUI:0019B1* + ID_OUI_FROM_DATABASE=Arrow7 Corporation + +OUI:0019B2* + ID_OUI_FROM_DATABASE=XYnetsoft Co.,Ltd + +OUI:0019B3* + ID_OUI_FROM_DATABASE=Stanford Research Systems + +OUI:0019B4* + ID_OUI_FROM_DATABASE=VideoCast Ltd. + +OUI:0019B5* + ID_OUI_FROM_DATABASE=Famar Fueguina S.A. + +OUI:0019B6* + ID_OUI_FROM_DATABASE=Euro Emme s.r.l. + +OUI:0019B7* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:0019B8* + ID_OUI_FROM_DATABASE=Boundary Devices + +OUI:0019B9* + ID_OUI_FROM_DATABASE=Dell Inc. + +OUI:0019BA* + ID_OUI_FROM_DATABASE=Paradox Security Systems Ltd + +OUI:0019BB* + ID_OUI_FROM_DATABASE=Hewlett-Packard Company + +OUI:0019BC* + ID_OUI_FROM_DATABASE=ELECTRO CHANCE SRL + +OUI:0019BD* + ID_OUI_FROM_DATABASE=New Media Life + +OUI:0019BE* + ID_OUI_FROM_DATABASE=Altai Technologies Limited + +OUI:0019BF* + ID_OUI_FROM_DATABASE=Citiway technology Co.,ltd + +OUI:0019C0* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:0019C1* + ID_OUI_FROM_DATABASE=Alps Electric Co., Ltd + +OUI:0019C2* + ID_OUI_FROM_DATABASE=Equustek Solutions, Inc. + +OUI:0019C3* + ID_OUI_FROM_DATABASE=Qualitrol + +OUI:0019C4* + ID_OUI_FROM_DATABASE=Infocrypt Inc. + +OUI:0019C5* + ID_OUI_FROM_DATABASE=SONY Computer Entertainment inc, + +OUI:0019C6* + ID_OUI_FROM_DATABASE=ZTE Corporation + +OUI:0019C7* + ID_OUI_FROM_DATABASE=Cambridge Industries(Group) Co.,Ltd. + +OUI:0019C8* + ID_OUI_FROM_DATABASE=AnyDATA Corporation + +OUI:0019C9* + ID_OUI_FROM_DATABASE=S&C ELECTRIC COMPANY + +OUI:0019CA* + ID_OUI_FROM_DATABASE=Broadata Communications, Inc + +OUI:0019CB* + ID_OUI_FROM_DATABASE=ZyXEL Communications Corporation + +OUI:0019CC* + ID_OUI_FROM_DATABASE=RCG (HK) Ltd + +OUI:0019CD* + ID_OUI_FROM_DATABASE=Chengdu ethercom information technology Ltd. + +OUI:0019CE* + ID_OUI_FROM_DATABASE=Progressive Gaming International + +OUI:0019CF* + ID_OUI_FROM_DATABASE=SALICRU, S.A. + +OUI:0019D0* + ID_OUI_FROM_DATABASE=Cathexis + +OUI:0019D1* + ID_OUI_FROM_DATABASE=Intel Corporation + +OUI:0019D2* + ID_OUI_FROM_DATABASE=Intel Corporation + +OUI:0019D3* + ID_OUI_FROM_DATABASE=TRAK Microwave + +OUI:0019D4* + ID_OUI_FROM_DATABASE=ICX Technologies + +OUI:0019D5* + ID_OUI_FROM_DATABASE=IP Innovations, Inc. + +OUI:0019D6* + ID_OUI_FROM_DATABASE=LS Cable Ltd. + +OUI:0019D7* + ID_OUI_FROM_DATABASE=FORTUNETEK CO., LTD + +OUI:0019D8* + ID_OUI_FROM_DATABASE=MAXFOR + +OUI:0019D9* + ID_OUI_FROM_DATABASE=Zeutschel GmbH + +OUI:0019DA* + ID_OUI_FROM_DATABASE=Welltrans O&E Technology Co. , Ltd. + +OUI:0019DB* + ID_OUI_FROM_DATABASE=MICRO-STAR INTERNATIONAL CO., LTD. + +OUI:0019DC* + ID_OUI_FROM_DATABASE=ENENSYS Technologies + +OUI:0019DD* + ID_OUI_FROM_DATABASE=FEI-Zyfer, Inc. + +OUI:0019DE* + ID_OUI_FROM_DATABASE=MOBITEK + +OUI:0019DF* + ID_OUI_FROM_DATABASE=Thomson Inc. + +OUI:0019E0* + ID_OUI_FROM_DATABASE=TP-LINK Technologies Co., Ltd. + +OUI:0019E1* + ID_OUI_FROM_DATABASE=Nortel + +OUI:0019E2* + ID_OUI_FROM_DATABASE=Juniper Networks + +OUI:0019E3* + ID_OUI_FROM_DATABASE=Apple Computer Inc. + +OUI:0019E4* + ID_OUI_FROM_DATABASE=2Wire, Inc + +OUI:0019E5* + ID_OUI_FROM_DATABASE=Lynx Studio Technology, Inc. + +OUI:0019E6* + ID_OUI_FROM_DATABASE=TOYO MEDIC CO.,LTD. + +OUI:0019E7* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0019E8* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0019E9* + ID_OUI_FROM_DATABASE=S-Information Technolgy, Co., Ltd. + +OUI:0019EA* + ID_OUI_FROM_DATABASE=TeraMage Technologies Co., Ltd. + +OUI:0019EB* + ID_OUI_FROM_DATABASE=Pyronix Ltd + +OUI:0019EC* + ID_OUI_FROM_DATABASE=Sagamore Systems, Inc. + +OUI:0019ED* + ID_OUI_FROM_DATABASE=Axesstel Inc. + +OUI:0019EE* + ID_OUI_FROM_DATABASE=CARLO GAVAZZI CONTROLS SPA-Controls Division + +OUI:0019EF* + ID_OUI_FROM_DATABASE=SHENZHEN LINNKING ELECTRONICS CO.,LTD + +OUI:0019F0* + ID_OUI_FROM_DATABASE=UNIONMAN TECHNOLOGY CO.,LTD + +OUI:0019F1* + ID_OUI_FROM_DATABASE=Star Communication Network Technology Co.,Ltd + +OUI:0019F2* + ID_OUI_FROM_DATABASE=Teradyne K.K. + +OUI:0019F3* + ID_OUI_FROM_DATABASE=Cetis, Inc + +OUI:0019F4* + ID_OUI_FROM_DATABASE=Convergens Oy Ltd + +OUI:0019F5* + ID_OUI_FROM_DATABASE=Imagination Technologies Ltd + +OUI:0019F6* + ID_OUI_FROM_DATABASE=Acconet (PTE) Ltd + +OUI:0019F7* + ID_OUI_FROM_DATABASE=Onset Computer Corporation + +OUI:0019F8* + ID_OUI_FROM_DATABASE=Embedded Systems Design, Inc. + +OUI:0019F9* + ID_OUI_FROM_DATABASE=TDK-Lambda + +OUI:0019FA* + ID_OUI_FROM_DATABASE=Cable Vision Electronics CO., LTD. + +OUI:0019FB* + ID_OUI_FROM_DATABASE=BSkyB Ltd + +OUI:0019FC* + ID_OUI_FROM_DATABASE=PT. Ufoakses Sukses Luarbiasa + +OUI:0019FD* + ID_OUI_FROM_DATABASE=Nintendo Co., Ltd. + +OUI:0019FE* + ID_OUI_FROM_DATABASE=SHENZHEN SEECOMM TECHNOLOGY CO.,LTD. + +OUI:0019FF* + ID_OUI_FROM_DATABASE=Finnzymes + +OUI:001A00* + ID_OUI_FROM_DATABASE=MATRIX INC. + +OUI:001A01* + ID_OUI_FROM_DATABASE=Smiths Medical + +OUI:001A02* + ID_OUI_FROM_DATABASE=SECURE CARE PRODUCTS, INC + +OUI:001A03* + ID_OUI_FROM_DATABASE=Angel Electronics Co., Ltd. + +OUI:001A04* + ID_OUI_FROM_DATABASE=Interay Solutions BV + +OUI:001A05* + ID_OUI_FROM_DATABASE=OPTIBASE LTD + +OUI:001A06* + ID_OUI_FROM_DATABASE=OpVista, Inc. + +OUI:001A07* + ID_OUI_FROM_DATABASE=Arecont Vision + +OUI:001A08* + ID_OUI_FROM_DATABASE=Dalman Technical Services + +OUI:001A09* + ID_OUI_FROM_DATABASE=Wayfarer Transit Systems Ltd + +OUI:001A0A* + ID_OUI_FROM_DATABASE=Adaptive Micro-Ware Inc. + +OUI:001A0B* + ID_OUI_FROM_DATABASE=BONA TECHNOLOGY INC. + +OUI:001A0C* + ID_OUI_FROM_DATABASE=Swe-Dish Satellite Systems AB + +OUI:001A0D* + ID_OUI_FROM_DATABASE=HandHeld entertainment, Inc. + +OUI:001A0E* + ID_OUI_FROM_DATABASE=Cheng Uei Precision Industry Co.,Ltd + +OUI:001A0F* + ID_OUI_FROM_DATABASE=Sistemas Avanzados de Control, S.A. + +OUI:001A10* + ID_OUI_FROM_DATABASE=LUCENT TRANS ELECTRONICS CO.,LTD + +OUI:001A11* + ID_OUI_FROM_DATABASE=Google Inc. + +OUI:001A12* + ID_OUI_FROM_DATABASE=Essilor + +OUI:001A13* + ID_OUI_FROM_DATABASE=Wanlida Group Co., LTD + +OUI:001A14* + ID_OUI_FROM_DATABASE=Xin Hua Control Engineering Co.,Ltd. + +OUI:001A15* + ID_OUI_FROM_DATABASE=gemalto e-Payment + +OUI:001A16* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:001A17* + ID_OUI_FROM_DATABASE=Teak Technologies, Inc. + +OUI:001A18* + ID_OUI_FROM_DATABASE=Advanced Simulation Technology inc. + +OUI:001A19* + ID_OUI_FROM_DATABASE=Computer Engineering Limited + +OUI:001A1A* + ID_OUI_FROM_DATABASE=Gentex Corporation/Electro-Acoustic Products + +OUI:001A1B* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:001A1C* + ID_OUI_FROM_DATABASE=GT&T Engineering Pte Ltd + +OUI:001A1D* + ID_OUI_FROM_DATABASE=PChome Online Inc. + +OUI:001A1E* + ID_OUI_FROM_DATABASE=Aruba Networks + +OUI:001A1F* + ID_OUI_FROM_DATABASE=Coastal Environmental Systems + +OUI:001A20* + ID_OUI_FROM_DATABASE=CMOTECH Co. Ltd. + +OUI:001A21* + ID_OUI_FROM_DATABASE=Indac B.V. + +OUI:001A22* + ID_OUI_FROM_DATABASE=eQ-3 Entwicklung GmbH + +OUI:001A23* + ID_OUI_FROM_DATABASE=Ice Qube, Inc + +OUI:001A24* + ID_OUI_FROM_DATABASE=Galaxy Telecom Technologies Ltd + +OUI:001A25* + ID_OUI_FROM_DATABASE=DELTA DORE + +OUI:001A26* + ID_OUI_FROM_DATABASE=Deltanode Solutions AB + +OUI:001A27* + ID_OUI_FROM_DATABASE=Ubistar + +OUI:001A28* + ID_OUI_FROM_DATABASE=ASWT Co., LTD. Taiwan Branch H.K. + +OUI:001A29* + ID_OUI_FROM_DATABASE=Techsonic Industries d/b/a Humminbird + +OUI:001A2A* + ID_OUI_FROM_DATABASE=Arcadyan Technology Corporation + +OUI:001A2B* + ID_OUI_FROM_DATABASE=Ayecom Technology Co., Ltd. + +OUI:001A2C* + ID_OUI_FROM_DATABASE=SATEC Co.,LTD + +OUI:001A2D* + ID_OUI_FROM_DATABASE=The Navvo Group + +OUI:001A2E* + ID_OUI_FROM_DATABASE=Ziova Coporation + +OUI:001A2F* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001A30* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001A31* + ID_OUI_FROM_DATABASE=SCAN COIN Industries AB + +OUI:001A32* + ID_OUI_FROM_DATABASE=ACTIVA MULTIMEDIA + +OUI:001A33* + ID_OUI_FROM_DATABASE=ASI Communications, Inc. + +OUI:001A34* + ID_OUI_FROM_DATABASE=Konka Group Co., Ltd. + +OUI:001A35* + ID_OUI_FROM_DATABASE=BARTEC GmbH + +OUI:001A36* + ID_OUI_FROM_DATABASE=Aipermon GmbH & Co. KG + +OUI:001A37* + ID_OUI_FROM_DATABASE=Lear Corporation + +OUI:001A38* + ID_OUI_FROM_DATABASE=Sanmina-SCI + +OUI:001A39* + ID_OUI_FROM_DATABASE=Merten GmbH&CoKG + +OUI:001A3A* + ID_OUI_FROM_DATABASE=Dongahelecomm + +OUI:001A3B* + ID_OUI_FROM_DATABASE=Doah Elecom Inc. + +OUI:001A3C* + ID_OUI_FROM_DATABASE=Technowave Ltd. + +OUI:001A3D* + ID_OUI_FROM_DATABASE=Ajin Vision Co.,Ltd + +OUI:001A3E* + ID_OUI_FROM_DATABASE=Faster Technology LLC + +OUI:001A3F* + ID_OUI_FROM_DATABASE=intelbras + +OUI:001A40* + ID_OUI_FROM_DATABASE=A-FOUR TECH CO., LTD. + +OUI:001A41* + ID_OUI_FROM_DATABASE=INOCOVA Co.,Ltd + +OUI:001A42* + ID_OUI_FROM_DATABASE=Techcity Technology co., Ltd. + +OUI:001A43* + ID_OUI_FROM_DATABASE=Logical Link Communications + +OUI:001A44* + ID_OUI_FROM_DATABASE=JWTrading Co., Ltd + +OUI:001A45* + ID_OUI_FROM_DATABASE=GN Netcom as + +OUI:001A46* + ID_OUI_FROM_DATABASE=Digital Multimedia Technology Co., Ltd + +OUI:001A47* + ID_OUI_FROM_DATABASE=Agami Systems, Inc. + +OUI:001A48* + ID_OUI_FROM_DATABASE=Takacom Corporation + +OUI:001A49* + ID_OUI_FROM_DATABASE=Micro Vision Co.,LTD + +OUI:001A4A* + ID_OUI_FROM_DATABASE=Qumranet Inc. + +OUI:001A4B* + ID_OUI_FROM_DATABASE=Hewlett-Packard Company + +OUI:001A4C* + ID_OUI_FROM_DATABASE=Crossbow Technology, Inc + +OUI:001A4D* + ID_OUI_FROM_DATABASE=GIGA-BYTE TECHNOLOGY CO.,LTD. + +OUI:001A4E* + ID_OUI_FROM_DATABASE=NTI AG / LinMot + +OUI:001A4F* + ID_OUI_FROM_DATABASE=AVM GmbH + +OUI:001A50* + ID_OUI_FROM_DATABASE=PheeNet Technology Corp. + +OUI:001A51* + ID_OUI_FROM_DATABASE=Alfred Mann Foundation + +OUI:001A52* + ID_OUI_FROM_DATABASE=Meshlinx Wireless Inc. + +OUI:001A53* + ID_OUI_FROM_DATABASE=Zylaya + +OUI:001A54* + ID_OUI_FROM_DATABASE=Hip Shing Electronics Ltd. + +OUI:001A55* + ID_OUI_FROM_DATABASE=ACA-Digital Corporation + +OUI:001A56* + ID_OUI_FROM_DATABASE=ViewTel Co,. Ltd. + +OUI:001A57* + ID_OUI_FROM_DATABASE=Matrix Design Group, LLC + +OUI:001A58* + ID_OUI_FROM_DATABASE=CCV Deutschland GmbH - Celectronic eHealth Div. + +OUI:001A59* + ID_OUI_FROM_DATABASE=Ircona + +OUI:001A5A* + ID_OUI_FROM_DATABASE=Korea Electric Power Data Network (KDN) Co., Ltd + +OUI:001A5B* + ID_OUI_FROM_DATABASE=NetCare Service Co., Ltd. + +OUI:001A5C* + ID_OUI_FROM_DATABASE=Euchner GmbH+Co. KG + +OUI:001A5D* + ID_OUI_FROM_DATABASE=Mobinnova Corp. + +OUI:001A5E* + ID_OUI_FROM_DATABASE=Thincom Technology Co.,Ltd + +OUI:001A5F* + ID_OUI_FROM_DATABASE=KitWorks.fi Ltd. + +OUI:001A60* + ID_OUI_FROM_DATABASE=Wave Electronics Co.,Ltd. + +OUI:001A61* + ID_OUI_FROM_DATABASE=PacStar Corp. + +OUI:001A62* + ID_OUI_FROM_DATABASE=Data Robotics, Incorporated + +OUI:001A63* + ID_OUI_FROM_DATABASE=Elster Solutions, LLC, + +OUI:001A64* + ID_OUI_FROM_DATABASE=IBM Corp + +OUI:001A65* + ID_OUI_FROM_DATABASE=Seluxit + +OUI:001A66* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:001A67* + ID_OUI_FROM_DATABASE=Infinite QL Sdn Bhd + +OUI:001A68* + ID_OUI_FROM_DATABASE=Weltec Enterprise Co., Ltd. + +OUI:001A69* + ID_OUI_FROM_DATABASE=Wuhan Yangtze Optical Technology CO.,Ltd. + +OUI:001A6A* + ID_OUI_FROM_DATABASE=Tranzas, Inc. + +OUI:001A6B* + ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co., Ltd. + +OUI:001A6C* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001A6D* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001A6E* + ID_OUI_FROM_DATABASE=Impro Technologies + +OUI:001A6F* + ID_OUI_FROM_DATABASE=MI.TEL s.r.l. + +OUI:001A70* + ID_OUI_FROM_DATABASE=Cisco-Linksys, LLC + +OUI:001A71* + ID_OUI_FROM_DATABASE=Diostech Co., Ltd. + +OUI:001A72* + ID_OUI_FROM_DATABASE=Mosart Semiconductor Corp. + +OUI:001A73* + ID_OUI_FROM_DATABASE=Gemtek Technology Co., Ltd. + +OUI:001A74* + ID_OUI_FROM_DATABASE=Procare International Co + +OUI:001A75* + ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications + +OUI:001A76* + ID_OUI_FROM_DATABASE=SDT information Technology Co.,LTD. + +OUI:001A77* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:001A78* + ID_OUI_FROM_DATABASE=ubtos + +OUI:001A79* + ID_OUI_FROM_DATABASE=TELECOMUNICATION TECHNOLOGIES LTD. + +OUI:001A7A* + ID_OUI_FROM_DATABASE=Lismore Instruments Limited + +OUI:001A7B* + ID_OUI_FROM_DATABASE=Teleco, Inc. + +OUI:001A7C* + ID_OUI_FROM_DATABASE=Hirschmann Multimedia B.V. + +OUI:001A7D* + ID_OUI_FROM_DATABASE=cyber-blue(HK)Ltd + +OUI:001A7E* + ID_OUI_FROM_DATABASE=LN Srithai Comm Ltd. + +OUI:001A7F* + ID_OUI_FROM_DATABASE=GCI Science&Technology Co.,Ltd. + +OUI:001A80* + ID_OUI_FROM_DATABASE=Sony Corporation + +OUI:001A81* + ID_OUI_FROM_DATABASE=Zelax + +OUI:001A82* + ID_OUI_FROM_DATABASE=PROBA Building Automation Co.,LTD + +OUI:001A83* + ID_OUI_FROM_DATABASE=Pegasus Technologies Inc. + +OUI:001A84* + ID_OUI_FROM_DATABASE=V One Multimedia Pte Ltd + +OUI:001A85* + ID_OUI_FROM_DATABASE=NV Michel Van de Wiele + +OUI:001A86* + ID_OUI_FROM_DATABASE=AdvancedIO Systems Inc + +OUI:001A87* + ID_OUI_FROM_DATABASE=Canhold International Limited + +OUI:001A88* + ID_OUI_FROM_DATABASE=Venergy,Co,Ltd + +OUI:001A89* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:001A8A* + ID_OUI_FROM_DATABASE=Samsung Electronics Co., Ltd. + +OUI:001A8B* + ID_OUI_FROM_DATABASE=CHUNIL ELECTRIC IND., CO. + +OUI:001A8C* + ID_OUI_FROM_DATABASE=Astaro AG + +OUI:001A8D* + ID_OUI_FROM_DATABASE=AVECS Bergen GmbH + +OUI:001A8E* + ID_OUI_FROM_DATABASE=3Way Networks Ltd + +OUI:001A8F* + ID_OUI_FROM_DATABASE=Nortel + +OUI:001A90* + ID_OUI_FROM_DATABASE=Trópico Sistemas e Telecomunicações da Amazônia LTDA. + +OUI:001A91* + ID_OUI_FROM_DATABASE=FusionDynamic Ltd. + +OUI:001A92* + ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. + +OUI:001A93* + ID_OUI_FROM_DATABASE=ERCO Leuchten GmbH + +OUI:001A94* + ID_OUI_FROM_DATABASE=Votronic GmbH + +OUI:001A95* + ID_OUI_FROM_DATABASE=Hisense Mobile Communications Technoligy Co.,Ltd. + +OUI:001A96* + ID_OUI_FROM_DATABASE=ECLER S.A. + +OUI:001A97* + ID_OUI_FROM_DATABASE=fitivision technology Inc. + +OUI:001A98* + ID_OUI_FROM_DATABASE=Asotel Communication Limited Taiwan Branch + +OUI:001A99* + ID_OUI_FROM_DATABASE=Smarty (HZ) Information Electronics Co., Ltd + +OUI:001A9A* + ID_OUI_FROM_DATABASE=Skyworth Digital technology(shenzhen)co.ltd. + +OUI:001A9B* + ID_OUI_FROM_DATABASE=ADEC & Parter AG + +OUI:001A9C* + ID_OUI_FROM_DATABASE=RightHand Technologies, Inc. + +OUI:001A9D* + ID_OUI_FROM_DATABASE=Skipper Wireless, Inc. + +OUI:001A9E* + ID_OUI_FROM_DATABASE=ICON Digital International Limited + +OUI:001A9F* + ID_OUI_FROM_DATABASE=A-Link Europe Ltd + +OUI:001AA0* + ID_OUI_FROM_DATABASE=Dell Inc + +OUI:001AA1* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001AA2* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001AA3* + ID_OUI_FROM_DATABASE=DELORME + +OUI:001AA4* + ID_OUI_FROM_DATABASE=Future University-Hakodate + +OUI:001AA5* + ID_OUI_FROM_DATABASE=BRN Phoenix + +OUI:001AA6* + ID_OUI_FROM_DATABASE=Telefunken Radio Communication Systems GmbH &CO.KG + +OUI:001AA7* + ID_OUI_FROM_DATABASE=Torian Wireless + +OUI:001AA8* + ID_OUI_FROM_DATABASE=Mamiya Digital Imaging Co., Ltd. + +OUI:001AA9* + ID_OUI_FROM_DATABASE=FUJIAN STAR-NET COMMUNICATION CO.,LTD + +OUI:001AAA* + ID_OUI_FROM_DATABASE=Analogic Corp. + +OUI:001AAB* + ID_OUI_FROM_DATABASE=eWings s.r.l. + +OUI:001AAC* + ID_OUI_FROM_DATABASE=Corelatus AB + +OUI:001AAD* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:001AAE* + ID_OUI_FROM_DATABASE=Savant Systems LLC + +OUI:001AAF* + ID_OUI_FROM_DATABASE=BLUSENS TECHNOLOGY + +OUI:001AB0* + ID_OUI_FROM_DATABASE=Signal Networks Pvt. Ltd., + +OUI:001AB1* + ID_OUI_FROM_DATABASE=Asia Pacific Satellite Industries Co., Ltd. + +OUI:001AB2* + ID_OUI_FROM_DATABASE=Cyber Solutions Inc. + +OUI:001AB3* + ID_OUI_FROM_DATABASE=VISIONITE INC. + +OUI:001AB4* + ID_OUI_FROM_DATABASE=FFEI Ltd. + +OUI:001AB5* + ID_OUI_FROM_DATABASE=Home Network System + +OUI:001AB6* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:001AB7* + ID_OUI_FROM_DATABASE=Ethos Networks LTD. + +OUI:001AB8* + ID_OUI_FROM_DATABASE=Anseri Corporation + +OUI:001AB9* + ID_OUI_FROM_DATABASE=PMC + +OUI:001ABA* + ID_OUI_FROM_DATABASE=Caton Overseas Limited + +OUI:001ABB* + ID_OUI_FROM_DATABASE=Fontal Technology Incorporation + +OUI:001ABC* + ID_OUI_FROM_DATABASE=U4EA Technologies Ltd + +OUI:001ABD* + ID_OUI_FROM_DATABASE=Impatica Inc. + +OUI:001ABE* + ID_OUI_FROM_DATABASE=COMPUTER HI-TECH INC. + +OUI:001ABF* + ID_OUI_FROM_DATABASE=TRUMPF Laser Marking Systems AG + +OUI:001AC0* + ID_OUI_FROM_DATABASE=JOYBIEN TECHNOLOGIES CO., LTD. + +OUI:001AC1* + ID_OUI_FROM_DATABASE=3Com Ltd + +OUI:001AC2* + ID_OUI_FROM_DATABASE=YEC Co.,Ltd. + +OUI:001AC3* + ID_OUI_FROM_DATABASE=Scientific-Atlanta, Inc + +OUI:001AC4* + ID_OUI_FROM_DATABASE=2Wire, Inc + +OUI:001AC5* + ID_OUI_FROM_DATABASE=BreakingPoint Systems, Inc. + +OUI:001AC6* + ID_OUI_FROM_DATABASE=Micro Control Designs + +OUI:001AC7* + ID_OUI_FROM_DATABASE=UNIPOINT + +OUI:001AC8* + ID_OUI_FROM_DATABASE=ISL (Instrumentation Scientifique de Laboratoire) + +OUI:001AC9* + ID_OUI_FROM_DATABASE=SUZUKEN CO.,LTD + +OUI:001ACA* + ID_OUI_FROM_DATABASE=Tilera Corporation + +OUI:001ACB* + ID_OUI_FROM_DATABASE=Autocom Products Ltd + +OUI:001ACC* + ID_OUI_FROM_DATABASE=Celestial Semiconductor, Ltd + +OUI:001ACD* + ID_OUI_FROM_DATABASE=Tidel Engineering LP + +OUI:001ACE* + ID_OUI_FROM_DATABASE=YUPITERU CORPORATION + +OUI:001ACF* + ID_OUI_FROM_DATABASE=C.T. ELETTRONICA + +OUI:001AD0* + ID_OUI_FROM_DATABASE=Albis Technologies AG + +OUI:001AD1* + ID_OUI_FROM_DATABASE=FARGO CO., LTD. + +OUI:001AD2* + ID_OUI_FROM_DATABASE=Eletronica Nitron Ltda + +OUI:001AD3* + ID_OUI_FROM_DATABASE=Vamp Ltd. + +OUI:001AD4* + ID_OUI_FROM_DATABASE=iPOX Technology Co., Ltd. + +OUI:001AD5* + ID_OUI_FROM_DATABASE=KMC CHAIN INDUSTRIAL CO., LTD. + +OUI:001AD6* + ID_OUI_FROM_DATABASE=JIAGNSU AETNA ELECTRIC CO.,LTD + +OUI:001AD7* + ID_OUI_FROM_DATABASE=Christie Digital Systems, Inc. + +OUI:001AD8* + ID_OUI_FROM_DATABASE=AlsterAero GmbH + +OUI:001AD9* + ID_OUI_FROM_DATABASE=International Broadband Electric Communications, Inc. + +OUI:001ADA* + ID_OUI_FROM_DATABASE=Biz-2-Me Inc. + +OUI:001ADB* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:001ADC* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:001ADD* + ID_OUI_FROM_DATABASE=PePWave Ltd + +OUI:001ADE* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:001ADF* + ID_OUI_FROM_DATABASE=Interactivetv Pty Limited + +OUI:001AE0* + ID_OUI_FROM_DATABASE=Mythology Tech Express Inc. + +OUI:001AE1* + ID_OUI_FROM_DATABASE=EDGE ACCESS INC + +OUI:001AE2* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001AE3* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001AE4* + ID_OUI_FROM_DATABASE=Medicis Technologies Corporation + +OUI:001AE5* + ID_OUI_FROM_DATABASE=Mvox Technologies Inc. + +OUI:001AE6* + ID_OUI_FROM_DATABASE=Atlanta Advanced Communications Holdings Limited + +OUI:001AE7* + ID_OUI_FROM_DATABASE=Aztek Networks, Inc. + +OUI:001AE8* + ID_OUI_FROM_DATABASE=Siemens Enterprise Communications GmbH & Co. KG + +OUI:001AE9* + ID_OUI_FROM_DATABASE=Nintendo Co., Ltd. + +OUI:001AEA* + ID_OUI_FROM_DATABASE=Radio Terminal Systems Pty Ltd + +OUI:001AEB* + ID_OUI_FROM_DATABASE=Allied Telesis K.K. + +OUI:001AEC* + ID_OUI_FROM_DATABASE=Keumbee Electronics Co.,Ltd. + +OUI:001AED* + ID_OUI_FROM_DATABASE=INCOTEC GmbH + +OUI:001AEE* + ID_OUI_FROM_DATABASE=Shenztech Ltd + +OUI:001AEF* + ID_OUI_FROM_DATABASE=Loopcomm Technology, Inc. + +OUI:001AF0* + ID_OUI_FROM_DATABASE=Alcatel - IPD + +OUI:001AF1* + ID_OUI_FROM_DATABASE=Embedded Artists AB + +OUI:001AF2* + ID_OUI_FROM_DATABASE=Dynavisions Schweiz AG + +OUI:001AF3* + ID_OUI_FROM_DATABASE=Samyoung Electronics + +OUI:001AF4* + ID_OUI_FROM_DATABASE=Handreamnet + +OUI:001AF5* + ID_OUI_FROM_DATABASE=PENTAONE. CO., LTD. + +OUI:001AF6* + ID_OUI_FROM_DATABASE=Woven Systems, Inc. + +OUI:001AF7* + ID_OUI_FROM_DATABASE=dataschalt e+a GmbH + +OUI:001AF8* + ID_OUI_FROM_DATABASE=Copley Controls Corporation + +OUI:001AF9* + ID_OUI_FROM_DATABASE=AeroVIronment (AV Inc) + +OUI:001AFA* + ID_OUI_FROM_DATABASE=Welch Allyn, Inc. + +OUI:001AFB* + ID_OUI_FROM_DATABASE=Joby Inc. + +OUI:001AFC* + ID_OUI_FROM_DATABASE=ModusLink Corporation + +OUI:001AFD* + ID_OUI_FROM_DATABASE=EVOLIS + +OUI:001AFE* + ID_OUI_FROM_DATABASE=SOFACREAL + +OUI:001AFF* + ID_OUI_FROM_DATABASE=Wizyoung Tech. + +OUI:001B00* + ID_OUI_FROM_DATABASE=Neopost Technologies + +OUI:001B01* + ID_OUI_FROM_DATABASE=Applied Radio Technologies + +OUI:001B02* + ID_OUI_FROM_DATABASE=ED Co.Ltd + +OUI:001B03* + ID_OUI_FROM_DATABASE=Action Technology (SZ) Co., Ltd + +OUI:001B04* + ID_OUI_FROM_DATABASE=Affinity International S.p.a + +OUI:001B05* + ID_OUI_FROM_DATABASE=YMC AG + +OUI:001B06* + ID_OUI_FROM_DATABASE=Ateliers R. LAUMONIER + +OUI:001B07* + ID_OUI_FROM_DATABASE=Mendocino Software + +OUI:001B08* + ID_OUI_FROM_DATABASE=Danfoss Drives A/S + +OUI:001B09* + ID_OUI_FROM_DATABASE=Matrix Telecom Pvt. Ltd. + +OUI:001B0A* + ID_OUI_FROM_DATABASE=Intelligent Distributed Controls Ltd + +OUI:001B0B* + ID_OUI_FROM_DATABASE=Phidgets Inc. + +OUI:001B0C* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001B0D* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001B0E* + ID_OUI_FROM_DATABASE=InoTec GmbH Organisationssysteme + +OUI:001B0F* + ID_OUI_FROM_DATABASE=Petratec + +OUI:001B10* + ID_OUI_FROM_DATABASE=ShenZhen Kang Hui Technology Co.,ltd + +OUI:001B11* + ID_OUI_FROM_DATABASE=D-Link Corporation + +OUI:001B12* + ID_OUI_FROM_DATABASE=Apprion + +OUI:001B13* + ID_OUI_FROM_DATABASE=Icron Technologies Corporation + +OUI:001B14* + ID_OUI_FROM_DATABASE=Carex Lighting Equipment Factory + +OUI:001B15* + ID_OUI_FROM_DATABASE=Voxtel, Inc. + +OUI:001B16* + ID_OUI_FROM_DATABASE=Celtro Ltd. + +OUI:001B17* + ID_OUI_FROM_DATABASE=Palo Alto Networks + +OUI:001B18* + ID_OUI_FROM_DATABASE=Tsuken Electric Ind. Co.,Ltd + +OUI:001B19* + ID_OUI_FROM_DATABASE=IEEE I&M Society TC9 + +OUI:001B1A* + ID_OUI_FROM_DATABASE=e-trees Japan, Inc. + +OUI:001B1B* + ID_OUI_FROM_DATABASE=Siemens AG, + +OUI:001B1C* + ID_OUI_FROM_DATABASE=Coherent + +OUI:001B1D* + ID_OUI_FROM_DATABASE=Phoenix International Co., Ltd + +OUI:001B1E* + ID_OUI_FROM_DATABASE=HART Communication Foundation + +OUI:001B1F* + ID_OUI_FROM_DATABASE=DELTA - Danish Electronics, Light & Acoustics + +OUI:001B20* + ID_OUI_FROM_DATABASE=TPine Technology + +OUI:001B21* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:001B22* + ID_OUI_FROM_DATABASE=Palit Microsystems ( H.K.) Ltd. + +OUI:001B23* + ID_OUI_FROM_DATABASE=SimpleComTools + +OUI:001B24* + ID_OUI_FROM_DATABASE=Quanta Computer Inc. + +OUI:001B25* + ID_OUI_FROM_DATABASE=Nortel + +OUI:001B26* + ID_OUI_FROM_DATABASE=RON-Telecom ZAO + +OUI:001B27* + ID_OUI_FROM_DATABASE=Merlin CSI + +OUI:001B28* + ID_OUI_FROM_DATABASE=POLYGON, JSC + +OUI:001B29* + ID_OUI_FROM_DATABASE=Avantis.Co.,Ltd + +OUI:001B2A* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001B2B* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001B2C* + ID_OUI_FROM_DATABASE=ATRON electronic GmbH + +OUI:001B2D* + ID_OUI_FROM_DATABASE=Med-Eng Systems Inc. + +OUI:001B2E* + ID_OUI_FROM_DATABASE=Sinkyo Electron Inc + +OUI:001B2F* + ID_OUI_FROM_DATABASE=NETGEAR Inc. + +OUI:001B30* + ID_OUI_FROM_DATABASE=Solitech Inc. + +OUI:001B31* + ID_OUI_FROM_DATABASE=Neural Image. Co. Ltd. + +OUI:001B32* + ID_OUI_FROM_DATABASE=QLogic Corporation + +OUI:001B33* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:001B34* + ID_OUI_FROM_DATABASE=Focus System Inc. + +OUI:001B35* + ID_OUI_FROM_DATABASE=ChongQing JINOU Science & Technology Development CO.,Ltd + +OUI:001B36* + ID_OUI_FROM_DATABASE=Tsubata Engineering Co.,Ltd. (Head Office) + +OUI:001B37* + ID_OUI_FROM_DATABASE=Computec Oy + +OUI:001B38* + ID_OUI_FROM_DATABASE=COMPAL INFORMATION (KUNSHAN) CO., LTD. + +OUI:001B39* + ID_OUI_FROM_DATABASE=Proxicast + +OUI:001B3A* + ID_OUI_FROM_DATABASE=SIMS Corp. + +OUI:001B3B* + ID_OUI_FROM_DATABASE=Yi-Qing CO., LTD + +OUI:001B3C* + ID_OUI_FROM_DATABASE=Software Technologies Group,Inc. + +OUI:001B3D* + ID_OUI_FROM_DATABASE=EuroTel Spa + +OUI:001B3E* + ID_OUI_FROM_DATABASE=Curtis, Inc. + +OUI:001B3F* + ID_OUI_FROM_DATABASE=ProCurve Networking by HP + +OUI:001B40* + ID_OUI_FROM_DATABASE=Network Automation mxc AB + +OUI:001B41* + ID_OUI_FROM_DATABASE=General Infinity Co.,Ltd. + +OUI:001B42* + ID_OUI_FROM_DATABASE=Wise & Blue + +OUI:001B43* + ID_OUI_FROM_DATABASE=Beijing DG Telecommunications equipment Co.,Ltd + +OUI:001B44* + ID_OUI_FROM_DATABASE=SanDisk Corporation + +OUI:001B45* + ID_OUI_FROM_DATABASE=ABB AS, Division Automation Products + +OUI:001B46* + ID_OUI_FROM_DATABASE=Blueone Technology Co.,Ltd + +OUI:001B47* + ID_OUI_FROM_DATABASE=Futarque A/S + +OUI:001B48* + ID_OUI_FROM_DATABASE=Shenzhen Lantech Electronics Co., Ltd. + +OUI:001B49* + ID_OUI_FROM_DATABASE=Roberts Radio limited + +OUI:001B4A* + ID_OUI_FROM_DATABASE=W&W Communications, Inc. + +OUI:001B4B* + ID_OUI_FROM_DATABASE=SANION Co., Ltd. + +OUI:001B4C* + ID_OUI_FROM_DATABASE=Signtech + +OUI:001B4D* + ID_OUI_FROM_DATABASE=Areca Technology Corporation + +OUI:001B4E* + ID_OUI_FROM_DATABASE=Navman New Zealand + +OUI:001B4F* + ID_OUI_FROM_DATABASE=Avaya Inc. + +OUI:001B50* + ID_OUI_FROM_DATABASE=Nizhny Novgorod Factory named after M.Frunze, FSUE (NZiF) + +OUI:001B51* + ID_OUI_FROM_DATABASE=Vector Technology Corp. + +OUI:001B52* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:001B53* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001B54* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001B55* + ID_OUI_FROM_DATABASE=Hurco Automation Ltd. + +OUI:001B56* + ID_OUI_FROM_DATABASE=Tehuti Networks Ltd. + +OUI:001B57* + ID_OUI_FROM_DATABASE=SEMINDIA SYSTEMS PRIVATE LIMITED + +OUI:001B58* + ID_OUI_FROM_DATABASE=ACE CAD Enterprise Co., Ltd. + +OUI:001B59* + ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications AB + +OUI:001B5A* + ID_OUI_FROM_DATABASE=Apollo Imaging Technologies, Inc. + +OUI:001B5B* + ID_OUI_FROM_DATABASE=2Wire, Inc. + +OUI:001B5C* + ID_OUI_FROM_DATABASE=Azuretec Co., Ltd. + +OUI:001B5D* + ID_OUI_FROM_DATABASE=Vololink Pty Ltd + +OUI:001B5E* + ID_OUI_FROM_DATABASE=BPL Limited + +OUI:001B5F* + ID_OUI_FROM_DATABASE=Alien Technology + +OUI:001B60* + ID_OUI_FROM_DATABASE=NAVIGON AG + +OUI:001B61* + ID_OUI_FROM_DATABASE=Digital Acoustics, LLC + +OUI:001B62* + ID_OUI_FROM_DATABASE=JHT Optoelectronics Co.,Ltd. + +OUI:001B63* + ID_OUI_FROM_DATABASE=Apple Computer Inc. + +OUI:001B64* + ID_OUI_FROM_DATABASE=IsaacLandKorea Co., Ltd, + +OUI:001B65* + ID_OUI_FROM_DATABASE=China Gridcom Co., Ltd + +OUI:001B66* + ID_OUI_FROM_DATABASE=Sennheiser electronic GmbH & Co. KG + +OUI:001B67* + ID_OUI_FROM_DATABASE=Ubiquisys Ltd + +OUI:001B68* + ID_OUI_FROM_DATABASE=Modnnet Co., Ltd + +OUI:001B69* + ID_OUI_FROM_DATABASE=Equaline Corporation + +OUI:001B6A* + ID_OUI_FROM_DATABASE=Powerwave Technologies Sweden AB + +OUI:001B6B* + ID_OUI_FROM_DATABASE=Swyx Solutions AG + +OUI:001B6C* + ID_OUI_FROM_DATABASE=LookX Digital Media BV + +OUI:001B6D* + ID_OUI_FROM_DATABASE=Midtronics, Inc. + +OUI:001B6E* + ID_OUI_FROM_DATABASE=Anue Systems, Inc. + +OUI:001B6F* + ID_OUI_FROM_DATABASE=Teletrak Ltd + +OUI:001B70* + ID_OUI_FROM_DATABASE=IRI Ubiteq, INC. + +OUI:001B71* + ID_OUI_FROM_DATABASE=Telular Corp. + +OUI:001B72* + ID_OUI_FROM_DATABASE=Sicep s.p.a. + +OUI:001B73* + ID_OUI_FROM_DATABASE=DTL Broadcast Ltd + +OUI:001B74* + ID_OUI_FROM_DATABASE=MiraLink Corporation + +OUI:001B75* + ID_OUI_FROM_DATABASE=Hypermedia Systems + +OUI:001B76* + ID_OUI_FROM_DATABASE=Ripcode, Inc. + +OUI:001B77* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:001B78* + ID_OUI_FROM_DATABASE=Hewlett-Packard Company + +OUI:001B79* + ID_OUI_FROM_DATABASE=FAIVELEY TRANSPORT + +OUI:001B7A* + ID_OUI_FROM_DATABASE=Nintendo Co., Ltd. + +OUI:001B7B* + ID_OUI_FROM_DATABASE=The Tintometer Ltd + +OUI:001B7C* + ID_OUI_FROM_DATABASE=A & R Cambridge + +OUI:001B7D* + ID_OUI_FROM_DATABASE=CXR Anderson Jacobson + +OUI:001B7E* + ID_OUI_FROM_DATABASE=Beckmann GmbH + +OUI:001B7F* + ID_OUI_FROM_DATABASE=TMN Technologies Telecomunicacoes Ltda + +OUI:001B80* + ID_OUI_FROM_DATABASE=LORD Corporation + +OUI:001B81* + ID_OUI_FROM_DATABASE=DATAQ Instruments, Inc. + +OUI:001B82* + ID_OUI_FROM_DATABASE=Taiwan Semiconductor Co., Ltd. + +OUI:001B83* + ID_OUI_FROM_DATABASE=Finsoft Ltd + +OUI:001B84* + ID_OUI_FROM_DATABASE=Scan Engineering Telecom + +OUI:001B85* + ID_OUI_FROM_DATABASE=MAN Diesel SE + +OUI:001B86* + ID_OUI_FROM_DATABASE=Bosch Access Systems GmbH + +OUI:001B87* + ID_OUI_FROM_DATABASE=Deepsound Tech. Co., Ltd + +OUI:001B88* + ID_OUI_FROM_DATABASE=Divinet Access Technologies Ltd + +OUI:001B89* + ID_OUI_FROM_DATABASE=EMZA Visual Sense Ltd. + +OUI:001B8A* + ID_OUI_FROM_DATABASE=2M Electronic A/S + +OUI:001B8B* + ID_OUI_FROM_DATABASE=NEC AccessTechnica, Ltd. + +OUI:001B8C* + ID_OUI_FROM_DATABASE=JMicron Technology Corp. + +OUI:001B8D* + ID_OUI_FROM_DATABASE=Electronic Computer Systems, Inc. + +OUI:001B8E* + ID_OUI_FROM_DATABASE=Hulu Sweden AB + +OUI:001B8F* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001B90* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001B91* + ID_OUI_FROM_DATABASE=EFKON AG + +OUI:001B92* + ID_OUI_FROM_DATABASE=l-acoustics + +OUI:001B93* + ID_OUI_FROM_DATABASE=JC Decaux SA DNT + +OUI:001B94* + ID_OUI_FROM_DATABASE=T.E.M.A. S.p.A. + +OUI:001B95* + ID_OUI_FROM_DATABASE=VIDEO SYSTEMS SRL + +OUI:001B96* + ID_OUI_FROM_DATABASE=General Sensing + +OUI:001B97* + ID_OUI_FROM_DATABASE=Violin Technologies + +OUI:001B98* + ID_OUI_FROM_DATABASE=Samsung Electronics Co., Ltd. + +OUI:001B99* + ID_OUI_FROM_DATABASE=KS System GmbH + +OUI:001B9A* + ID_OUI_FROM_DATABASE=Apollo Fire Detectors Ltd + +OUI:001B9B* + ID_OUI_FROM_DATABASE=Hose-McCann Communications + +OUI:001B9C* + ID_OUI_FROM_DATABASE=SATEL sp. z o.o. + +OUI:001B9D* + ID_OUI_FROM_DATABASE=Novus Security Sp. z o.o. + +OUI:001B9E* + ID_OUI_FROM_DATABASE=ASKEY COMPUTER CORP + +OUI:001B9F* + ID_OUI_FROM_DATABASE=Calyptech Pty Ltd + +OUI:001BA0* + ID_OUI_FROM_DATABASE=Awox + +OUI:001BA1* + ID_OUI_FROM_DATABASE=Åmic AB + +OUI:001BA2* + ID_OUI_FROM_DATABASE=IDS Imaging Development Systems GmbH + +OUI:001BA3* + ID_OUI_FROM_DATABASE=Flexit Group GmbH + +OUI:001BA4* + ID_OUI_FROM_DATABASE=S.A.E Afikim + +OUI:001BA5* + ID_OUI_FROM_DATABASE=MyungMin Systems, Inc. + +OUI:001BA6* + ID_OUI_FROM_DATABASE=intotech inc. + +OUI:001BA7* + ID_OUI_FROM_DATABASE=Lorica Solutions + +OUI:001BA8* + ID_OUI_FROM_DATABASE=UBI&MOBI,.Inc + +OUI:001BA9* + ID_OUI_FROM_DATABASE=BROTHER INDUSTRIES, LTD. + +OUI:001BAA* + ID_OUI_FROM_DATABASE=XenICs nv + +OUI:001BAB* + ID_OUI_FROM_DATABASE=Telchemy, Incorporated + +OUI:001BAC* + ID_OUI_FROM_DATABASE=Curtiss Wright Controls Embedded Computing + +OUI:001BAD* + ID_OUI_FROM_DATABASE=iControl Incorporated + +OUI:001BAE* + ID_OUI_FROM_DATABASE=Micro Control Systems, Inc + +OUI:001BAF* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:001BB0* + ID_OUI_FROM_DATABASE=BHARAT ELECTRONICS + +OUI:001BB1* + ID_OUI_FROM_DATABASE=Wistron Neweb Corp. + +OUI:001BB2* + ID_OUI_FROM_DATABASE=Intellect International NV + +OUI:001BB3* + ID_OUI_FROM_DATABASE=Condalo GmbH + +OUI:001BB4* + ID_OUI_FROM_DATABASE=Airvod Limited + +OUI:001BB5* + ID_OUI_FROM_DATABASE=ZF Electronics GmbH + +OUI:001BB6* + ID_OUI_FROM_DATABASE=Bird Electronic Corp. + +OUI:001BB7* + ID_OUI_FROM_DATABASE=Alta Heights Technology Corp. + +OUI:001BB8* + ID_OUI_FROM_DATABASE=BLUEWAY ELECTRONIC CO;LTD + +OUI:001BB9* + ID_OUI_FROM_DATABASE=Elitegroup Computer System Co. + +OUI:001BBA* + ID_OUI_FROM_DATABASE=Nortel + +OUI:001BBB* + ID_OUI_FROM_DATABASE=RFTech Co.,Ltd + +OUI:001BBC* + ID_OUI_FROM_DATABASE=Silver Peak Systems, Inc. + +OUI:001BBD* + ID_OUI_FROM_DATABASE=FMC Kongsberg Subsea AS + +OUI:001BBE* + ID_OUI_FROM_DATABASE=ICOP Digital + +OUI:001BBF* + ID_OUI_FROM_DATABASE=SAGEM COMMUNICATION + +OUI:001BC0* + ID_OUI_FROM_DATABASE=Juniper Networks + +OUI:001BC1* + ID_OUI_FROM_DATABASE=HOLUX Technology, Inc. + +OUI:001BC2* + ID_OUI_FROM_DATABASE=Integrated Control Technology Limitied + +OUI:001BC3* + ID_OUI_FROM_DATABASE=Mobisolution Co.,Ltd + +OUI:001BC4* + ID_OUI_FROM_DATABASE=Ultratec, Inc. + +OUI:001BC5* + ID_OUI_FROM_DATABASE=IEEE Registration Authority + +OUI:001BC6* + ID_OUI_FROM_DATABASE=Strato Rechenzentrum AG + +OUI:001BC7* + ID_OUI_FROM_DATABASE=StarVedia Technology Inc. + +OUI:001BC8* + ID_OUI_FROM_DATABASE=MIURA CO.,LTD + +OUI:001BC9* + ID_OUI_FROM_DATABASE=FSN DISPLAY INC + +OUI:001BCA* + ID_OUI_FROM_DATABASE=Beijing Run Technology LTD. Company + +OUI:001BCB* + ID_OUI_FROM_DATABASE=PEMPEK SYSTEMS PTY LTD + +OUI:001BCC* + ID_OUI_FROM_DATABASE=KINGTEK CCTV ALLIANCE CO., LTD. + +OUI:001BCD* + ID_OUI_FROM_DATABASE=DAVISCOMMS (S) PTE LTD + +OUI:001BCE* + ID_OUI_FROM_DATABASE=Measurement Devices Ltd + +OUI:001BCF* + ID_OUI_FROM_DATABASE=Dataupia Corporation + +OUI:001BD0* + ID_OUI_FROM_DATABASE=IDENTEC SOLUTIONS + +OUI:001BD1* + ID_OUI_FROM_DATABASE=SOGESTMATIC + +OUI:001BD2* + ID_OUI_FROM_DATABASE=ULTRA-X ASIA PACIFIC Inc. + +OUI:001BD3* + ID_OUI_FROM_DATABASE=Matsushita Electric Panasonic AVC + +OUI:001BD4* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001BD5* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001BD6* + ID_OUI_FROM_DATABASE=Kelvin Hughes Ltd + +OUI:001BD7* + ID_OUI_FROM_DATABASE=Scientific Atlanta, A Cisco Company + +OUI:001BD8* + ID_OUI_FROM_DATABASE=DVTel LTD + +OUI:001BD9* + ID_OUI_FROM_DATABASE=Edgewater Computer Systems + +OUI:001BDA* + ID_OUI_FROM_DATABASE=UTStarcom Inc + +OUI:001BDB* + ID_OUI_FROM_DATABASE=Valeo VECS + +OUI:001BDC* + ID_OUI_FROM_DATABASE=Vencer Co., Ltd. + +OUI:001BDD* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:001BDE* + ID_OUI_FROM_DATABASE=Renkus-Heinz, Inc. + +OUI:001BDF* + ID_OUI_FROM_DATABASE=Iskra MIS + +OUI:001BE0* + ID_OUI_FROM_DATABASE=TELENOT ELECTRONIC GmbH + +OUI:001BE1* + ID_OUI_FROM_DATABASE=ViaLogy + +OUI:001BE2* + ID_OUI_FROM_DATABASE=AhnLab,Inc. + +OUI:001BE3* + ID_OUI_FROM_DATABASE=Health Hero Network, Inc. + +OUI:001BE4* + ID_OUI_FROM_DATABASE=TOWNET SRL + +OUI:001BE5* + ID_OUI_FROM_DATABASE=802automation Limited + +OUI:001BE6* + ID_OUI_FROM_DATABASE=VR AG + +OUI:001BE7* + ID_OUI_FROM_DATABASE=Postek Electronics Co., Ltd. + +OUI:001BE8* + ID_OUI_FROM_DATABASE=Ultratronik GmbH + +OUI:001BE9* + ID_OUI_FROM_DATABASE=Broadcom Corporation + +OUI:001BEA* + ID_OUI_FROM_DATABASE=Nintendo Co., Ltd. + +OUI:001BEB* + ID_OUI_FROM_DATABASE=DMP Electronics INC. + +OUI:001BEC* + ID_OUI_FROM_DATABASE=Netio Technologies Co., Ltd + +OUI:001BED* + ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc + +OUI:001BEE* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:001BEF* + ID_OUI_FROM_DATABASE=Blossoms Digital Technology Co.,Ltd. + +OUI:001BF0* + ID_OUI_FROM_DATABASE=Value Platforms Limited + +OUI:001BF1* + ID_OUI_FROM_DATABASE=Nanjing SilverNet Software Co., Ltd. + +OUI:001BF2* + ID_OUI_FROM_DATABASE=KWORLD COMPUTER CO., LTD + +OUI:001BF3* + ID_OUI_FROM_DATABASE=TRANSRADIO SenderSysteme Berlin AG + +OUI:001BF4* + ID_OUI_FROM_DATABASE=KENWIN INDUSTRIAL(HK) LTD. + +OUI:001BF5* + ID_OUI_FROM_DATABASE=Tellink Sistemas de Telecomunicación S.L. + +OUI:001BF6* + ID_OUI_FROM_DATABASE=CONWISE Technology Corporation Ltd. + +OUI:001BF7* + ID_OUI_FROM_DATABASE=Lund IP Products AB + +OUI:001BF8* + ID_OUI_FROM_DATABASE=Digitrax Inc. + +OUI:001BF9* + ID_OUI_FROM_DATABASE=Intellitect Water Ltd + +OUI:001BFA* + ID_OUI_FROM_DATABASE=G.i.N. mbH + +OUI:001BFB* + ID_OUI_FROM_DATABASE=Alps Electric Co., Ltd + +OUI:001BFC* + ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. + +OUI:001BFD* + ID_OUI_FROM_DATABASE=Dignsys Inc. + +OUI:001BFE* + ID_OUI_FROM_DATABASE=Zavio Inc. + +OUI:001BFF* + ID_OUI_FROM_DATABASE=Millennia Media inc. + +OUI:001C00* + ID_OUI_FROM_DATABASE=Entry Point, LLC + +OUI:001C01* + ID_OUI_FROM_DATABASE=ABB Oy Drives + +OUI:001C02* + ID_OUI_FROM_DATABASE=Pano Logic + +OUI:001C03* + ID_OUI_FROM_DATABASE=Betty TV Technology AG + +OUI:001C04* + ID_OUI_FROM_DATABASE=Airgain, Inc. + +OUI:001C05* + ID_OUI_FROM_DATABASE=Nonin Medical Inc. + +OUI:001C06* + ID_OUI_FROM_DATABASE=Siemens Numerical Control Ltd., Nanjing + +OUI:001C07* + ID_OUI_FROM_DATABASE=Cwlinux Limited + +OUI:001C08* + ID_OUI_FROM_DATABASE=Echo360, Inc. + +OUI:001C09* + ID_OUI_FROM_DATABASE=SAE Electronic Co.,Ltd. + +OUI:001C0A* + ID_OUI_FROM_DATABASE=Shenzhen AEE Technology Co.,Ltd. + +OUI:001C0B* + ID_OUI_FROM_DATABASE=SmartAnt Telecom + +OUI:001C0C* + ID_OUI_FROM_DATABASE=TANITA Corporation + +OUI:001C0D* + ID_OUI_FROM_DATABASE=G-Technology, Inc. + +OUI:001C0E* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001C0F* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001C10* + ID_OUI_FROM_DATABASE=Cisco-Linksys, LLC + +OUI:001C11* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:001C12* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:001C13* + ID_OUI_FROM_DATABASE=OPTSYS TECHNOLOGY CO., LTD. + +OUI:001C14* + ID_OUI_FROM_DATABASE=VMware, Inc + +OUI:001C15* + ID_OUI_FROM_DATABASE=TXP Corporation + +OUI:001C16* + ID_OUI_FROM_DATABASE=ThyssenKrupp Elevator + +OUI:001C17* + ID_OUI_FROM_DATABASE=Nortel + +OUI:001C18* + ID_OUI_FROM_DATABASE=Sicert S.r.L. + +OUI:001C19* + ID_OUI_FROM_DATABASE=secunet Security Networks AG + +OUI:001C1A* + ID_OUI_FROM_DATABASE=Thomas Instrumentation, Inc + +OUI:001C1B* + ID_OUI_FROM_DATABASE=Hyperstone GmbH + +OUI:001C1C* + ID_OUI_FROM_DATABASE=Center Communication Systems GmbH + +OUI:001C1D* + ID_OUI_FROM_DATABASE=CHENZHOU GOSPELL DIGITAL TECHNOLOGY CO.,LTD + +OUI:001C1E* + ID_OUI_FROM_DATABASE=emtrion GmbH + +OUI:001C1F* + ID_OUI_FROM_DATABASE=Quest Retail Technology Pty Ltd + +OUI:001C20* + ID_OUI_FROM_DATABASE=CLB Benelux + +OUI:001C21* + ID_OUI_FROM_DATABASE=Nucsafe Inc. + +OUI:001C22* + ID_OUI_FROM_DATABASE=Aeris Elettronica s.r.l. + +OUI:001C23* + ID_OUI_FROM_DATABASE=Dell Inc + +OUI:001C24* + ID_OUI_FROM_DATABASE=Formosa Wireless Systems Corp. + +OUI:001C25* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + +OUI:001C26* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + +OUI:001C27* + ID_OUI_FROM_DATABASE=Sunell Electronics Co. + +OUI:001C28* + ID_OUI_FROM_DATABASE=Sphairon Technologies GmbH + +OUI:001C29* + ID_OUI_FROM_DATABASE=CORE DIGITAL ELECTRONICS CO., LTD + +OUI:001C2A* + ID_OUI_FROM_DATABASE=Envisacor Technologies Inc. + +OUI:001C2B* + ID_OUI_FROM_DATABASE=Alertme.com Limited + +OUI:001C2C* + ID_OUI_FROM_DATABASE=Synapse + +OUI:001C2D* + ID_OUI_FROM_DATABASE=FlexRadio Systems + +OUI:001C2E* + ID_OUI_FROM_DATABASE=ProCurve Networking by HP + +OUI:001C2F* + ID_OUI_FROM_DATABASE=Pfister GmbH + +OUI:001C30* + ID_OUI_FROM_DATABASE=Mode Lighting (UK ) Ltd. + +OUI:001C31* + ID_OUI_FROM_DATABASE=Mobile XP Technology Co., LTD + +OUI:001C32* + ID_OUI_FROM_DATABASE=Telian Corporation + +OUI:001C33* + ID_OUI_FROM_DATABASE=Sutron + +OUI:001C34* + ID_OUI_FROM_DATABASE=HUEY CHIAO INTERNATIONAL CO., LTD. + +OUI:001C35* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:001C36* + ID_OUI_FROM_DATABASE=iNEWiT NV + +OUI:001C37* + ID_OUI_FROM_DATABASE=Callpod, Inc. + +OUI:001C38* + ID_OUI_FROM_DATABASE=Bio-Rad Laboratories, Inc. + +OUI:001C39* + ID_OUI_FROM_DATABASE=S Netsystems Inc. + +OUI:001C3A* + ID_OUI_FROM_DATABASE=Element Labs, Inc. + +OUI:001C3B* + ID_OUI_FROM_DATABASE=AmRoad Technology Inc. + +OUI:001C3C* + ID_OUI_FROM_DATABASE=Seon Design Inc. + +OUI:001C3D* + ID_OUI_FROM_DATABASE=WaveStorm + +OUI:001C3E* + ID_OUI_FROM_DATABASE=ECKey Limited + +OUI:001C3F* + ID_OUI_FROM_DATABASE=International Police Technologies, Inc. + +OUI:001C40* + ID_OUI_FROM_DATABASE=VDG-Security bv + +OUI:001C41* + ID_OUI_FROM_DATABASE=scemtec Transponder Technology GmbH + +OUI:001C42* + ID_OUI_FROM_DATABASE=Parallels, Inc. + +OUI:001C43* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:001C44* + ID_OUI_FROM_DATABASE=Bosch Security Systems BV + +OUI:001C45* + ID_OUI_FROM_DATABASE=Chenbro Micom Co., Ltd. + +OUI:001C46* + ID_OUI_FROM_DATABASE=QTUM + +OUI:001C47* + ID_OUI_FROM_DATABASE=Hangzhou Hollysys Automation Co., Ltd + +OUI:001C48* + ID_OUI_FROM_DATABASE=WiDeFi, Inc. + +OUI:001C49* + ID_OUI_FROM_DATABASE=Zoltan Technology Inc. + +OUI:001C4A* + ID_OUI_FROM_DATABASE=AVM GmbH + +OUI:001C4B* + ID_OUI_FROM_DATABASE=Gener8, Inc. + +OUI:001C4C* + ID_OUI_FROM_DATABASE=Petrotest Instruments + +OUI:001C4D* + ID_OUI_FROM_DATABASE=Zeemote Technology Inc. (part of Aplix). + +OUI:001C4E* + ID_OUI_FROM_DATABASE=TASA International Limited + +OUI:001C4F* + ID_OUI_FROM_DATABASE=MACAB AB + +OUI:001C50* + ID_OUI_FROM_DATABASE=TCL Technoly Electronics(Huizhou)Co.,Ltd + +OUI:001C51* + ID_OUI_FROM_DATABASE=Celeno Communications + +OUI:001C52* + ID_OUI_FROM_DATABASE=VISIONEE SRL + +OUI:001C53* + ID_OUI_FROM_DATABASE=Synergy Lighting Controls + +OUI:001C54* + ID_OUI_FROM_DATABASE=Hillstone Networks Inc + +OUI:001C55* + ID_OUI_FROM_DATABASE=Shenzhen Kaifa Technology Co. + +OUI:001C56* + ID_OUI_FROM_DATABASE=Pado Systems, Inc. + +OUI:001C57* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001C58* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001C59* + ID_OUI_FROM_DATABASE=DEVON IT + +OUI:001C5A* + ID_OUI_FROM_DATABASE=Advanced Relay Corporation + +OUI:001C5B* + ID_OUI_FROM_DATABASE=Chubb Electronic Security Systems Ltd + +OUI:001C5C* + ID_OUI_FROM_DATABASE=Integrated Medical Systems, Inc. + +OUI:001C5D* + ID_OUI_FROM_DATABASE=Leica Microsystems + +OUI:001C5E* + ID_OUI_FROM_DATABASE=ASTON France + +OUI:001C5F* + ID_OUI_FROM_DATABASE=Winland Electronics, Inc. + +OUI:001C60* + ID_OUI_FROM_DATABASE=CSP Frontier Technologies,Inc. + +OUI:001C61* + ID_OUI_FROM_DATABASE=Galaxy Microsystems LImited + +OUI:001C62* + ID_OUI_FROM_DATABASE=LG Electronics Inc + +OUI:001C63* + ID_OUI_FROM_DATABASE=TRUEN + +OUI:001C64* + ID_OUI_FROM_DATABASE=Cellnet+Hunt + +OUI:001C65* + ID_OUI_FROM_DATABASE=JoeScan, Inc. + +OUI:001C66* + ID_OUI_FROM_DATABASE=UCAMP CO.,LTD + +OUI:001C67* + ID_OUI_FROM_DATABASE=Pumpkin Networks, Inc. + +OUI:001C68* + ID_OUI_FROM_DATABASE=Anhui Sun Create Electronics Co., Ltd + +OUI:001C69* + ID_OUI_FROM_DATABASE=Packet Vision Ltd + +OUI:001C6A* + ID_OUI_FROM_DATABASE=Weiss Engineering Ltd. + +OUI:001C6B* + ID_OUI_FROM_DATABASE=COVAX Co. Ltd + +OUI:001C6C* + ID_OUI_FROM_DATABASE=Jabil Circuit (Guangzhou) Limited + +OUI:001C6D* + ID_OUI_FROM_DATABASE=KYOHRITSU ELECTRONIC INDUSTRY CO., LTD. + +OUI:001C6E* + ID_OUI_FROM_DATABASE=Newbury Networks, Inc. + +OUI:001C6F* + ID_OUI_FROM_DATABASE=Emfit Ltd + +OUI:001C70* + ID_OUI_FROM_DATABASE=NOVACOMM LTDA + +OUI:001C71* + ID_OUI_FROM_DATABASE=Emergent Electronics + +OUI:001C72* + ID_OUI_FROM_DATABASE=Mayer & Cie GmbH & Co KG + +OUI:001C73* + ID_OUI_FROM_DATABASE=Arista Networks, Inc. + +OUI:001C74* + ID_OUI_FROM_DATABASE=Syswan Technologies Inc. + +OUI:001C75* + ID_OUI_FROM_DATABASE=RF Systems GmbH + +OUI:001C76* + ID_OUI_FROM_DATABASE=The Wandsworth Group Ltd + +OUI:001C77* + ID_OUI_FROM_DATABASE=Prodys + +OUI:001C78* + ID_OUI_FROM_DATABASE=WYPLAY SAS + +OUI:001C79* + ID_OUI_FROM_DATABASE=Cohesive Financial Technologies LLC + +OUI:001C7A* + ID_OUI_FROM_DATABASE=Perfectone Netware Company Ltd + +OUI:001C7B* + ID_OUI_FROM_DATABASE=Castlenet Technology Inc. + +OUI:001C7C* + ID_OUI_FROM_DATABASE=PERQ SYSTEMS CORPORATION + +OUI:001C7D* + ID_OUI_FROM_DATABASE=Excelpoint Manufacturing Pte Ltd + +OUI:001C7E* + ID_OUI_FROM_DATABASE=Toshiba + +OUI:001C7F* + ID_OUI_FROM_DATABASE=Check Point Software Technologies + +OUI:001C80* + ID_OUI_FROM_DATABASE=New Business Division/Rhea-Information CO., LTD. + +OUI:001C81* + ID_OUI_FROM_DATABASE=NextGen Venturi LTD + +OUI:001C82* + ID_OUI_FROM_DATABASE=Genew Technologies + +OUI:001C83* + ID_OUI_FROM_DATABASE=New Level Telecom Co., Ltd. + +OUI:001C84* + ID_OUI_FROM_DATABASE=STL Solution Co.,Ltd. + +OUI:001C85* + ID_OUI_FROM_DATABASE=Eunicorn + +OUI:001C86* + ID_OUI_FROM_DATABASE=Cranite Systems, Inc. + +OUI:001C87* + ID_OUI_FROM_DATABASE=Uriver Inc. + +OUI:001C88* + ID_OUI_FROM_DATABASE=TRANSYSTEM INC. + +OUI:001C89* + ID_OUI_FROM_DATABASE=Force Communications, Inc. + +OUI:001C8A* + ID_OUI_FROM_DATABASE=Cirrascale Corporation + +OUI:001C8B* + ID_OUI_FROM_DATABASE=MJ Innovations Ltd. + +OUI:001C8C* + ID_OUI_FROM_DATABASE=DIAL TECHNOLOGY LTD. + +OUI:001C8D* + ID_OUI_FROM_DATABASE=Mesa Imaging + +OUI:001C8E* + ID_OUI_FROM_DATABASE=Alcatel-Lucent IPD + +OUI:001C8F* + ID_OUI_FROM_DATABASE=Advanced Electronic Design, Inc. + +OUI:001C90* + ID_OUI_FROM_DATABASE=Empacket Corporation + +OUI:001C91* + ID_OUI_FROM_DATABASE=Gefen Inc. + +OUI:001C92* + ID_OUI_FROM_DATABASE=Tervela + +OUI:001C93* + ID_OUI_FROM_DATABASE=ExaDigm Inc + +OUI:001C94* + ID_OUI_FROM_DATABASE=LI-COR Biosciences + +OUI:001C95* + ID_OUI_FROM_DATABASE=Opticomm Corporation + +OUI:001C96* + ID_OUI_FROM_DATABASE=Linkwise Technology Pte Ltd + +OUI:001C97* + ID_OUI_FROM_DATABASE=Enzytek Technology Inc., + +OUI:001C98* + ID_OUI_FROM_DATABASE=LUCKY TECHNOLOGY (HK) COMPANY LIMITED + +OUI:001C99* + ID_OUI_FROM_DATABASE=Shunra Software Ltd. + +OUI:001C9A* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:001C9B* + ID_OUI_FROM_DATABASE=FEIG ELECTRONIC GmbH + +OUI:001C9C* + ID_OUI_FROM_DATABASE=Nortel + +OUI:001C9D* + ID_OUI_FROM_DATABASE=Liecthi AG + +OUI:001C9E* + ID_OUI_FROM_DATABASE=Dualtech IT AB + +OUI:001C9F* + ID_OUI_FROM_DATABASE=Razorstream, LLC + +OUI:001CA0* + ID_OUI_FROM_DATABASE=Production Resource Group, LLC + +OUI:001CA1* + ID_OUI_FROM_DATABASE=AKAMAI TECHNOLOGIES, INC. + +OUI:001CA2* + ID_OUI_FROM_DATABASE=ADB Broadband Italia + +OUI:001CA3* + ID_OUI_FROM_DATABASE=Terra + +OUI:001CA4* + ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications + +OUI:001CA5* + ID_OUI_FROM_DATABASE=Zygo Corporation + +OUI:001CA6* + ID_OUI_FROM_DATABASE=Win4NET + +OUI:001CA7* + ID_OUI_FROM_DATABASE=International Quartz Limited + +OUI:001CA8* + ID_OUI_FROM_DATABASE=AirTies Wireless Networks + +OUI:001CA9* + ID_OUI_FROM_DATABASE=Audiomatica Srl + +OUI:001CAA* + ID_OUI_FROM_DATABASE=Bellon Pty Ltd + +OUI:001CAB* + ID_OUI_FROM_DATABASE=Meyer Sound Laboratories, Inc. + +OUI:001CAC* + ID_OUI_FROM_DATABASE=Qniq Technology Corp. + +OUI:001CAD* + ID_OUI_FROM_DATABASE=Wuhan Telecommunication Devices Co.,Ltd + +OUI:001CAE* + ID_OUI_FROM_DATABASE=WiChorus, Inc. + +OUI:001CAF* + ID_OUI_FROM_DATABASE=Plato Networks Inc. + +OUI:001CB0* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001CB1* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001CB2* + ID_OUI_FROM_DATABASE=BPT SPA + +OUI:001CB3* + ID_OUI_FROM_DATABASE=APPLE, INC + +OUI:001CB4* + ID_OUI_FROM_DATABASE=Iridium Satellite LLC + +OUI:001CB5* + ID_OUI_FROM_DATABASE=Neihua Network Technology Co.,LTD.(NHN) + +OUI:001CB6* + ID_OUI_FROM_DATABASE=Duzon CNT Co., Ltd. + +OUI:001CB7* + ID_OUI_FROM_DATABASE=USC DigiArk Corporation + +OUI:001CB8* + ID_OUI_FROM_DATABASE=CBC Co., Ltd + +OUI:001CB9* + ID_OUI_FROM_DATABASE=KWANG SUNG ELECTRONICS CO., LTD. + +OUI:001CBA* + ID_OUI_FROM_DATABASE=VerScient, Inc. + +OUI:001CBB* + ID_OUI_FROM_DATABASE=MusicianLink + +OUI:001CBC* + ID_OUI_FROM_DATABASE=CastGrabber, LLC + +OUI:001CBD* + ID_OUI_FROM_DATABASE=Ezze Mobile Tech., Inc. + +OUI:001CBE* + ID_OUI_FROM_DATABASE=Nintendo Co., Ltd. + +OUI:001CBF* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:001CC0* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:001CC1* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:001CC2* + ID_OUI_FROM_DATABASE=Part II Research, Inc. + +OUI:001CC3* + ID_OUI_FROM_DATABASE=Pace plc + +OUI:001CC4* + ID_OUI_FROM_DATABASE=Hewlett-Packard Company + +OUI:001CC5* + ID_OUI_FROM_DATABASE=3COM LTD + +OUI:001CC6* + ID_OUI_FROM_DATABASE=ProStor Systems + +OUI:001CC7* + ID_OUI_FROM_DATABASE=Rembrandt Technologies, LLC d/b/a REMSTREAM + +OUI:001CC8* + ID_OUI_FROM_DATABASE=INDUSTRONIC Industrie-Electronic GmbH & Co. KG + +OUI:001CC9* + ID_OUI_FROM_DATABASE=Kaise Electronic Technology Co., Ltd. + +OUI:001CCA* + ID_OUI_FROM_DATABASE=Shanghai Gaozhi Science & Technology Development Co. + +OUI:001CCB* + ID_OUI_FROM_DATABASE=Forth Corporation Public Company Limited + +OUI:001CCC* + ID_OUI_FROM_DATABASE=Research In Motion Limited + +OUI:001CCD* + ID_OUI_FROM_DATABASE=Alektrona Corporation + +OUI:001CCE* + ID_OUI_FROM_DATABASE=By Techdesign + +OUI:001CCF* + ID_OUI_FROM_DATABASE=LIMETEK + +OUI:001CD0* + ID_OUI_FROM_DATABASE=Circleone Co.,Ltd. + +OUI:001CD1* + ID_OUI_FROM_DATABASE=Waves Audio LTD + +OUI:001CD2* + ID_OUI_FROM_DATABASE=King Champion (Hong Kong) Limited + +OUI:001CD3* + ID_OUI_FROM_DATABASE=ZP Engineering SEL + +OUI:001CD4* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:001CD5* + ID_OUI_FROM_DATABASE=ZeeVee, Inc. + +OUI:001CD6* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:001CD7* + ID_OUI_FROM_DATABASE=Harman/Becker Automotive Systems GmbH + +OUI:001CD8* + ID_OUI_FROM_DATABASE=BlueAnt Wireless + +OUI:001CD9* + ID_OUI_FROM_DATABASE=GlobalTop Technology Inc. + +OUI:001CDA* + ID_OUI_FROM_DATABASE=Exegin Technologies Limited + +OUI:001CDB* + ID_OUI_FROM_DATABASE=CARPOINT CO.,LTD + +OUI:001CDC* + ID_OUI_FROM_DATABASE=Custom Computer Services, Inc. + +OUI:001CDD* + ID_OUI_FROM_DATABASE=COWBELL ENGINEERING CO., LTD. + +OUI:001CDE* + ID_OUI_FROM_DATABASE=Interactive Multimedia eXchange Inc. + +OUI:001CDF* + ID_OUI_FROM_DATABASE=Belkin International Inc. + +OUI:001CE0* + ID_OUI_FROM_DATABASE=DASAN TPS + +OUI:001CE1* + ID_OUI_FROM_DATABASE=INDRA SISTEMAS, S.A. + +OUI:001CE2* + ID_OUI_FROM_DATABASE=Attero Tech, LLC. + +OUI:001CE3* + ID_OUI_FROM_DATABASE=Optimedical Systems + +OUI:001CE4* + ID_OUI_FROM_DATABASE=EleSy JSC + +OUI:001CE5* + ID_OUI_FROM_DATABASE=MBS Electronic Systems GmbH + +OUI:001CE6* + ID_OUI_FROM_DATABASE=INNES + +OUI:001CE7* + ID_OUI_FROM_DATABASE=Rocon PLC Research Centre + +OUI:001CE8* + ID_OUI_FROM_DATABASE=Cummins Inc + +OUI:001CE9* + ID_OUI_FROM_DATABASE=Galaxy Technology Limited + +OUI:001CEA* + ID_OUI_FROM_DATABASE=Scientific-Atlanta, Inc + +OUI:001CEB* + ID_OUI_FROM_DATABASE=Nortel + +OUI:001CEC* + ID_OUI_FROM_DATABASE=Mobilesoft (Aust.) Pty Ltd + +OUI:001CED* + ID_OUI_FROM_DATABASE=ENVIRONNEMENT SA + +OUI:001CEE* + ID_OUI_FROM_DATABASE=SHARP Corporation + +OUI:001CEF* + ID_OUI_FROM_DATABASE=Primax Electronics LTD + +OUI:001CF0* + ID_OUI_FROM_DATABASE=D-Link Corporation + +OUI:001CF1* + ID_OUI_FROM_DATABASE=SUPoX Technology Co. , LTD. + +OUI:001CF2* + ID_OUI_FROM_DATABASE=Tenlon Technology Co.,Ltd. + +OUI:001CF3* + ID_OUI_FROM_DATABASE=EVS BROADCAST EQUIPMENT + +OUI:001CF4* + ID_OUI_FROM_DATABASE=Media Technology Systems Inc + +OUI:001CF5* + ID_OUI_FROM_DATABASE=Wiseblue Technology Limited + +OUI:001CF6* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001CF7* + ID_OUI_FROM_DATABASE=AudioScience + +OUI:001CF8* + ID_OUI_FROM_DATABASE=Parade Technologies, Ltd. + +OUI:001CF9* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001CFA* + ID_OUI_FROM_DATABASE=Alarm.com + +OUI:001CFB* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:001CFC* + ID_OUI_FROM_DATABASE=Suminet Communication Technologies (Shanghai) Co., Ltd. + +OUI:001CFD* + ID_OUI_FROM_DATABASE=Universal Electronics + +OUI:001CFE* + ID_OUI_FROM_DATABASE=Quartics Inc + +OUI:001CFF* + ID_OUI_FROM_DATABASE=Napera Networks Inc + +OUI:001D00* + ID_OUI_FROM_DATABASE=Brivo Systems, LLC + +OUI:001D01* + ID_OUI_FROM_DATABASE=Neptune Digital + +OUI:001D02* + ID_OUI_FROM_DATABASE=Cybertech Telecom Development + +OUI:001D03* + ID_OUI_FROM_DATABASE=Design Solutions Inc. + +OUI:001D04* + ID_OUI_FROM_DATABASE=Zipit Wireless, Inc. + +OUI:001D05* + ID_OUI_FROM_DATABASE=iLight + +OUI:001D06* + ID_OUI_FROM_DATABASE=HM Electronics, Inc. + +OUI:001D07* + ID_OUI_FROM_DATABASE=Shenzhen Sang Fei Consumer Communications Co.,Ltd + +OUI:001D08* + ID_OUI_FROM_DATABASE=JIANGSU YINHE ELECTRONICS CO., LTD + +OUI:001D09* + ID_OUI_FROM_DATABASE=Dell Inc + +OUI:001D0A* + ID_OUI_FROM_DATABASE=Davis Instruments, Inc. + +OUI:001D0B* + ID_OUI_FROM_DATABASE=Power Standards Lab + +OUI:001D0C* + ID_OUI_FROM_DATABASE=MobileCompia + +OUI:001D0D* + ID_OUI_FROM_DATABASE=Sony Computer Entertainment inc. + +OUI:001D0E* + ID_OUI_FROM_DATABASE=Agapha Technology co., Ltd. + +OUI:001D0F* + ID_OUI_FROM_DATABASE=TP-LINK Technologies Co., Ltd. + +OUI:001D10* + ID_OUI_FROM_DATABASE=LightHaus Logic, Inc. + +OUI:001D11* + ID_OUI_FROM_DATABASE=Analogue & Micro Ltd + +OUI:001D12* + ID_OUI_FROM_DATABASE=ROHM CO., LTD. + +OUI:001D13* + ID_OUI_FROM_DATABASE=NextGTV + +OUI:001D14* + ID_OUI_FROM_DATABASE=SPERADTONE INFORMATION TECHNOLOGY LIMITED + +OUI:001D15* + ID_OUI_FROM_DATABASE=Shenzhen Dolphin Electronic Co., Ltd + +OUI:001D16* + ID_OUI_FROM_DATABASE=Efixo + +OUI:001D17* + ID_OUI_FROM_DATABASE=Digital Sky Corporation + +OUI:001D18* + ID_OUI_FROM_DATABASE=Power Innovation GmbH + +OUI:001D19* + ID_OUI_FROM_DATABASE=Arcadyan Technology Corporation + +OUI:001D1A* + ID_OUI_FROM_DATABASE=OvisLink S.A. + +OUI:001D1B* + ID_OUI_FROM_DATABASE=Sangean Electronics Inc. + +OUI:001D1C* + ID_OUI_FROM_DATABASE=Gennet s.a. + +OUI:001D1D* + ID_OUI_FROM_DATABASE=Inter-M Corporation + +OUI:001D1E* + ID_OUI_FROM_DATABASE=KYUSHU TEN CO.,LTD + +OUI:001D1F* + ID_OUI_FROM_DATABASE=Siauliu Tauro Televizoriai, JSC + +OUI:001D20* + ID_OUI_FROM_DATABASE=COMTREND CO. + +OUI:001D21* + ID_OUI_FROM_DATABASE=Alcad SL + +OUI:001D22* + ID_OUI_FROM_DATABASE=Foss Analytical A/S + +OUI:001D23* + ID_OUI_FROM_DATABASE=SENSUS + +OUI:001D24* + ID_OUI_FROM_DATABASE=Aclara Power-Line Systems Inc. + +OUI:001D25* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:001D26* + ID_OUI_FROM_DATABASE=Rockridgesound Technology Co. + +OUI:001D27* + ID_OUI_FROM_DATABASE=NAC-INTERCOM + +OUI:001D28* + ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications AB + +OUI:001D29* + ID_OUI_FROM_DATABASE=Doro AB + +OUI:001D2A* + ID_OUI_FROM_DATABASE=Tideway Electronic LTD + +OUI:001D2B* + ID_OUI_FROM_DATABASE=Wuhan Pont Technology CO. , LTD + +OUI:001D2C* + ID_OUI_FROM_DATABASE=Wavetrend Technologies (Pty) Limited + +OUI:001D2D* + ID_OUI_FROM_DATABASE=Pylone, Inc. + +OUI:001D2E* + ID_OUI_FROM_DATABASE=Ruckus Wireless + +OUI:001D2F* + ID_OUI_FROM_DATABASE=QuantumVision Corporation + +OUI:001D30* + ID_OUI_FROM_DATABASE=YX Wireless S.A. + +OUI:001D31* + ID_OUI_FROM_DATABASE=HIGHPRO INTERNATIONAL R&D CO,.LTD. + +OUI:001D32* + ID_OUI_FROM_DATABASE=Longkay Communication & Technology (Shanghai) Co. Ltd + +OUI:001D33* + ID_OUI_FROM_DATABASE=Maverick Systems Inc. + +OUI:001D34* + ID_OUI_FROM_DATABASE=SYRIS Technology Corp + +OUI:001D35* + ID_OUI_FROM_DATABASE=Viconics Electronics Inc. + +OUI:001D36* + ID_OUI_FROM_DATABASE=ELECTRONICS CORPORATION OF INDIA LIMITED + +OUI:001D37* + ID_OUI_FROM_DATABASE=Thales-Panda Transportation System + +OUI:001D38* + ID_OUI_FROM_DATABASE=Seagate Technology + +OUI:001D39* + ID_OUI_FROM_DATABASE=MOOHADIGITAL CO., LTD + +OUI:001D3A* + ID_OUI_FROM_DATABASE=mh acoustics LLC + +OUI:001D3B* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:001D3C* + ID_OUI_FROM_DATABASE=Muscle Corporation + +OUI:001D3D* + ID_OUI_FROM_DATABASE=Avidyne Corporation + +OUI:001D3E* + ID_OUI_FROM_DATABASE=SAKA TECHNO SCIENCE CO.,LTD + +OUI:001D3F* + ID_OUI_FROM_DATABASE=Mitron Pty Ltd + +OUI:001D40* + ID_OUI_FROM_DATABASE=Living Independently Group, Inc. + +OUI:001D41* + ID_OUI_FROM_DATABASE=Hardy Instruments + +OUI:001D42* + ID_OUI_FROM_DATABASE=Nortel + +OUI:001D43* + ID_OUI_FROM_DATABASE=Shenzhen G-link Digital Technology Co., Ltd. + +OUI:001D44* + ID_OUI_FROM_DATABASE=Krohne + +OUI:001D45* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001D46* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001D47* + ID_OUI_FROM_DATABASE=Covote GmbH & Co KG + +OUI:001D48* + ID_OUI_FROM_DATABASE=Sensor-Technik Wiedemann GmbH + +OUI:001D49* + ID_OUI_FROM_DATABASE=Innovation Wireless Inc. + +OUI:001D4A* + ID_OUI_FROM_DATABASE=Carestream Health, Inc. + +OUI:001D4B* + ID_OUI_FROM_DATABASE=Grid Connect Inc. + +OUI:001D4C* + ID_OUI_FROM_DATABASE=Alcatel-Lucent + +OUI:001D4D* + ID_OUI_FROM_DATABASE=Adaptive Recognition Hungary, Inc + +OUI:001D4E* + ID_OUI_FROM_DATABASE=TCM Mobile LLC + +OUI:001D4F* + ID_OUI_FROM_DATABASE=Apple Computer Inc. + +OUI:001D50* + ID_OUI_FROM_DATABASE=SPINETIX SA + +OUI:001D51* + ID_OUI_FROM_DATABASE=Babcock & Wilcox Power Generation Group, Inc + +OUI:001D52* + ID_OUI_FROM_DATABASE=Defzone B.V. + +OUI:001D53* + ID_OUI_FROM_DATABASE=S&O Electronics (Malaysia) Sdn. Bhd. + +OUI:001D54* + ID_OUI_FROM_DATABASE=Sunnic Technology & Merchandise INC. + +OUI:001D55* + ID_OUI_FROM_DATABASE=ZANTAZ, Inc + +OUI:001D56* + ID_OUI_FROM_DATABASE=Kramer Electronics Ltd. + +OUI:001D57* + ID_OUI_FROM_DATABASE=CAETEC Messtechnik + +OUI:001D58* + ID_OUI_FROM_DATABASE=CQ Inc + +OUI:001D59* + ID_OUI_FROM_DATABASE=Mitra Energy & Infrastructure + +OUI:001D5A* + ID_OUI_FROM_DATABASE=2Wire Inc. + +OUI:001D5B* + ID_OUI_FROM_DATABASE=Tecvan Informática Ltda + +OUI:001D5C* + ID_OUI_FROM_DATABASE=Tom Communication Industrial Co.,Ltd. + +OUI:001D5D* + ID_OUI_FROM_DATABASE=Control Dynamics Pty. Ltd. + +OUI:001D5E* + ID_OUI_FROM_DATABASE=COMING MEDIA CORP. + +OUI:001D5F* + ID_OUI_FROM_DATABASE=OverSpeed SARL + +OUI:001D60* + ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. + +OUI:001D61* + ID_OUI_FROM_DATABASE=BIJ Corporation + +OUI:001D62* + ID_OUI_FROM_DATABASE=InPhase Technologies + +OUI:001D63* + ID_OUI_FROM_DATABASE=Miele & Cie. KG + +OUI:001D64* + ID_OUI_FROM_DATABASE=Adam Communications Systems Int Ltd + +OUI:001D65* + ID_OUI_FROM_DATABASE=Microwave Radio Communications + +OUI:001D66* + ID_OUI_FROM_DATABASE=Hyundai Telecom + +OUI:001D67* + ID_OUI_FROM_DATABASE=AMEC + +OUI:001D68* + ID_OUI_FROM_DATABASE=Thomson Telecom Belgium + +OUI:001D69* + ID_OUI_FROM_DATABASE=Knorr-Bremse AG + +OUI:001D6A* + ID_OUI_FROM_DATABASE=Alpha Networks Inc. + +OUI:001D6B* + ID_OUI_FROM_DATABASE=Motorola (formerly Netopia, Inc + +OUI:001D6C* + ID_OUI_FROM_DATABASE=ClariPhy Communications, Inc. + +OUI:001D6D* + ID_OUI_FROM_DATABASE=Confidant International LLC + +OUI:001D6E* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:001D6F* + ID_OUI_FROM_DATABASE=Chainzone Technology Co., Ltd + +OUI:001D70* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001D71* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001D72* + ID_OUI_FROM_DATABASE=Wistron Corporation + +OUI:001D73* + ID_OUI_FROM_DATABASE=Buffalo Inc. + +OUI:001D74* + ID_OUI_FROM_DATABASE=Tianjin China-Silicon Microelectronics Co., Ltd. + +OUI:001D75* + ID_OUI_FROM_DATABASE=Radioscape PLC + +OUI:001D76* + ID_OUI_FROM_DATABASE=Eyeheight Ltd. + +OUI:001D77* + ID_OUI_FROM_DATABASE=NSGate + +OUI:001D78* + ID_OUI_FROM_DATABASE=Invengo Information Technology Co.,Ltd + +OUI:001D79* + ID_OUI_FROM_DATABASE=SIGNAMAX LLC + +OUI:001D7A* + ID_OUI_FROM_DATABASE=Wideband Semiconductor, Inc. + +OUI:001D7B* + ID_OUI_FROM_DATABASE=Ice Energy, Inc. + +OUI:001D7C* + ID_OUI_FROM_DATABASE=ABE Elettronica S.p.A. + +OUI:001D7D* + ID_OUI_FROM_DATABASE=GIGA-BYTE TECHNOLOGY CO.,LTD. + +OUI:001D7E* + ID_OUI_FROM_DATABASE=Cisco-Linksys, LLC + +OUI:001D7F* + ID_OUI_FROM_DATABASE=Tekron International Ltd + +OUI:001D80* + ID_OUI_FROM_DATABASE=Beijing Huahuan Eletronics Co.,Ltd + +OUI:001D81* + ID_OUI_FROM_DATABASE=GUANGZHOU GATEWAY ELECTRONICS CO., LTD + +OUI:001D82* + ID_OUI_FROM_DATABASE=GN A/S (GN Netcom A/S) + +OUI:001D83* + ID_OUI_FROM_DATABASE=Emitech Corporation + +OUI:001D84* + ID_OUI_FROM_DATABASE=Gateway, Inc. + +OUI:001D85* + ID_OUI_FROM_DATABASE=Call Direct Cellular Solutions + +OUI:001D86* + ID_OUI_FROM_DATABASE=Shinwa Industries(China) Ltd. + +OUI:001D87* + ID_OUI_FROM_DATABASE=VigTech Labs Sdn Bhd + +OUI:001D88* + ID_OUI_FROM_DATABASE=Clearwire + +OUI:001D89* + ID_OUI_FROM_DATABASE=VaultStor Corporation + +OUI:001D8A* + ID_OUI_FROM_DATABASE=TechTrex Inc + +OUI:001D8B* + ID_OUI_FROM_DATABASE=ADB Broadband Italia + +OUI:001D8C* + ID_OUI_FROM_DATABASE=La Crosse Technology LTD + +OUI:001D8D* + ID_OUI_FROM_DATABASE=Raytek GmbH + +OUI:001D8E* + ID_OUI_FROM_DATABASE=Alereon, Inc. + +OUI:001D8F* + ID_OUI_FROM_DATABASE=PureWave Networks + +OUI:001D90* + ID_OUI_FROM_DATABASE=EMCO Flow Systems + +OUI:001D91* + ID_OUI_FROM_DATABASE=Digitize, Inc + +OUI:001D92* + ID_OUI_FROM_DATABASE=MICRO-STAR INT'L CO.,LTD. + +OUI:001D93* + ID_OUI_FROM_DATABASE=Modacom + +OUI:001D94* + ID_OUI_FROM_DATABASE=Climax Technology Co., Ltd + +OUI:001D95* + ID_OUI_FROM_DATABASE=Flash, Inc. + +OUI:001D96* + ID_OUI_FROM_DATABASE=WatchGuard Video + +OUI:001D97* + ID_OUI_FROM_DATABASE=Alertus Technologies LLC + +OUI:001D98* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:001D99* + ID_OUI_FROM_DATABASE=Cyan Optic, Inc. + +OUI:001D9A* + ID_OUI_FROM_DATABASE=GODEX INTERNATIONAL CO., LTD + +OUI:001D9B* + ID_OUI_FROM_DATABASE=Hokuyo Automatic Co., Ltd. + +OUI:001D9C* + ID_OUI_FROM_DATABASE=Rockwell Automation + +OUI:001D9D* + ID_OUI_FROM_DATABASE=ARTJOY INTERNATIONAL LIMITED + +OUI:001D9E* + ID_OUI_FROM_DATABASE=AXION TECHNOLOGIES + +OUI:001D9F* + ID_OUI_FROM_DATABASE=MATT R.P.Traczynscy Sp.J. + +OUI:001DA0* + ID_OUI_FROM_DATABASE=Heng Yu Electronic Manufacturing Company Limited + +OUI:001DA1* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001DA2* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001DA3* + ID_OUI_FROM_DATABASE=SabiOso + +OUI:001DA4* + ID_OUI_FROM_DATABASE=Hangzhou System Technology CO., LTD + +OUI:001DA5* + ID_OUI_FROM_DATABASE=WB Electronics + +OUI:001DA6* + ID_OUI_FROM_DATABASE=Media Numerics Limited + +OUI:001DA7* + ID_OUI_FROM_DATABASE=Seamless Internet + +OUI:001DA8* + ID_OUI_FROM_DATABASE=Takahata Electronics Co.,Ltd + +OUI:001DA9* + ID_OUI_FROM_DATABASE=Castles Technology, Co., LTD + +OUI:001DAA* + ID_OUI_FROM_DATABASE=DrayTek Corp. + +OUI:001DAB* + ID_OUI_FROM_DATABASE=SwissQual License AG + +OUI:001DAC* + ID_OUI_FROM_DATABASE=Gigamon Systems LLC + +OUI:001DAD* + ID_OUI_FROM_DATABASE=Sinotech Engineering Consultants, Inc. Geotechnical Enginee + +OUI:001DAE* + ID_OUI_FROM_DATABASE=CHANG TSENG TECHNOLOGY CO., LTD + +OUI:001DAF* + ID_OUI_FROM_DATABASE=Nortel + +OUI:001DB0* + ID_OUI_FROM_DATABASE=FuJian HengTong Information Technology Co.,Ltd + +OUI:001DB1* + ID_OUI_FROM_DATABASE=Crescendo Networks + +OUI:001DB2* + ID_OUI_FROM_DATABASE=HOKKAIDO ELECTRIC ENGINEERING CO.,LTD. + +OUI:001DB3* + ID_OUI_FROM_DATABASE=ProCurve Networking by HP + +OUI:001DB4* + ID_OUI_FROM_DATABASE=KUMHO ENG CO.,LTD + +OUI:001DB5* + ID_OUI_FROM_DATABASE=Juniper networks + +OUI:001DB6* + ID_OUI_FROM_DATABASE=BestComm Networks, Inc. + +OUI:001DB7* + ID_OUI_FROM_DATABASE=Tendril Networks, Inc. + +OUI:001DB8* + ID_OUI_FROM_DATABASE=Intoto Inc. + +OUI:001DB9* + ID_OUI_FROM_DATABASE=Wellspring Wireless + +OUI:001DBA* + ID_OUI_FROM_DATABASE=Sony Corporation + +OUI:001DBB* + ID_OUI_FROM_DATABASE=Dynamic System Electronics Corp. + +OUI:001DBC* + ID_OUI_FROM_DATABASE=Nintendo Co., Ltd. + +OUI:001DBD* + ID_OUI_FROM_DATABASE=Versamed Inc. + +OUI:001DBE* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:001DBF* + ID_OUI_FROM_DATABASE=Radiient Technologies, Inc. + +OUI:001DC0* + ID_OUI_FROM_DATABASE=Enphase Energy + +OUI:001DC1* + ID_OUI_FROM_DATABASE=Audinate Pty L + +OUI:001DC2* + ID_OUI_FROM_DATABASE=XORTEC OY + +OUI:001DC3* + ID_OUI_FROM_DATABASE=RIKOR TV, Ltd + +OUI:001DC4* + ID_OUI_FROM_DATABASE=AIOI Systems Co., Ltd. + +OUI:001DC5* + ID_OUI_FROM_DATABASE=Beijing Jiaxun Feihong Electricial Co., Ltd. + +OUI:001DC6* + ID_OUI_FROM_DATABASE=SNR Inc. + +OUI:001DC7* + ID_OUI_FROM_DATABASE=L-3 Communications Geneva Aerospace + +OUI:001DC8* + ID_OUI_FROM_DATABASE=ScadaMetrcs, LLC. + +OUI:001DC9* + ID_OUI_FROM_DATABASE=GainSpan Corp. + +OUI:001DCA* + ID_OUI_FROM_DATABASE=PAV Electronics Limited + +OUI:001DCB* + ID_OUI_FROM_DATABASE=Exéns Development Oy + +OUI:001DCC* + ID_OUI_FROM_DATABASE=Hetra Secure Solutions + +OUI:001DCD* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + +OUI:001DCE* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + +OUI:001DCF* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + +OUI:001DD0* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + +OUI:001DD1* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + +OUI:001DD2* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + +OUI:001DD3* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + +OUI:001DD4* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + +OUI:001DD5* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + +OUI:001DD6* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + +OUI:001DD7* + ID_OUI_FROM_DATABASE=Algolith + +OUI:001DD8* + ID_OUI_FROM_DATABASE=Microsoft Corporation + +OUI:001DD9* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind.Co.,Ltd. + +OUI:001DDA* + ID_OUI_FROM_DATABASE=Mikroelektronika spol. s r. o. + +OUI:001DDB* + ID_OUI_FROM_DATABASE=C-BEL Corporation + +OUI:001DDC* + ID_OUI_FROM_DATABASE=HangZhou DeChangLong Tech&Info Co.,Ltd + +OUI:001DDD* + ID_OUI_FROM_DATABASE=DAT H.K. LIMITED + +OUI:001DDE* + ID_OUI_FROM_DATABASE=Zhejiang Broadcast&Television Technology Co.,Ltd. + +OUI:001DDF* + ID_OUI_FROM_DATABASE=Sunitec Enterprise Co., Ltd. + +OUI:001DE0* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:001DE1* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:001DE2* + ID_OUI_FROM_DATABASE=Radionor Communications + +OUI:001DE3* + ID_OUI_FROM_DATABASE=Intuicom + +OUI:001DE4* + ID_OUI_FROM_DATABASE=Visioneered Image Systems + +OUI:001DE5* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001DE6* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001DE7* + ID_OUI_FROM_DATABASE=Marine Sonic Technology, Ltd. + +OUI:001DE8* + ID_OUI_FROM_DATABASE=Nikko Denki Tsushin Company(NDTC) + +OUI:001DE9* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:001DEA* + ID_OUI_FROM_DATABASE=Commtest Instruments Ltd + +OUI:001DEB* + ID_OUI_FROM_DATABASE=DINEC International + +OUI:001DEC* + ID_OUI_FROM_DATABASE=Marusys + +OUI:001DED* + ID_OUI_FROM_DATABASE=Grid Net, Inc. + +OUI:001DEE* + ID_OUI_FROM_DATABASE=NEXTVISION SISTEMAS DIGITAIS DE TELEVISÃO LTDA. + +OUI:001DEF* + ID_OUI_FROM_DATABASE=TRIMM, INC. + +OUI:001DF0* + ID_OUI_FROM_DATABASE=Vidient Systems, Inc. + +OUI:001DF1* + ID_OUI_FROM_DATABASE=Intego Systems, Inc. + +OUI:001DF2* + ID_OUI_FROM_DATABASE=Netflix, Inc. + +OUI:001DF3* + ID_OUI_FROM_DATABASE=SBS Science & Technology Co., Ltd + +OUI:001DF4* + ID_OUI_FROM_DATABASE=Magellan Technology Pty Limited + +OUI:001DF5* + ID_OUI_FROM_DATABASE=Sunshine Co,LTD + +OUI:001DF6* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:001DF7* + ID_OUI_FROM_DATABASE=R. STAHL Schaltgeräte GmbH + +OUI:001DF8* + ID_OUI_FROM_DATABASE=Webpro Vision Technology Corporation + +OUI:001DF9* + ID_OUI_FROM_DATABASE=Cybiotronics (Far East) Limited + +OUI:001DFA* + ID_OUI_FROM_DATABASE=Fujian LANDI Commercial Equipment Co.,Ltd + +OUI:001DFB* + ID_OUI_FROM_DATABASE=NETCLEUS Systems Corporation + +OUI:001DFC* + ID_OUI_FROM_DATABASE=KSIC + +OUI:001DFD* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:001DFE* + ID_OUI_FROM_DATABASE=Palm, Inc + +OUI:001DFF* + ID_OUI_FROM_DATABASE=Network Critical Solutions Ltd + +OUI:001E00* + ID_OUI_FROM_DATABASE=Shantou Institute of Ultrasonic Instruments + +OUI:001E01* + ID_OUI_FROM_DATABASE=Renesas Technology Sales Co., Ltd. + +OUI:001E02* + ID_OUI_FROM_DATABASE=Sougou Keikaku Kougyou Co.,Ltd. + +OUI:001E03* + ID_OUI_FROM_DATABASE=LiComm Co., Ltd. + +OUI:001E04* + ID_OUI_FROM_DATABASE=Hanson Research Corporation + +OUI:001E05* + ID_OUI_FROM_DATABASE=Xseed Technologies & Computing + +OUI:001E06* + ID_OUI_FROM_DATABASE=WIBRAIN + +OUI:001E07* + ID_OUI_FROM_DATABASE=Winy Technology Co., Ltd. + +OUI:001E08* + ID_OUI_FROM_DATABASE=Centec Networks Inc + +OUI:001E09* + ID_OUI_FROM_DATABASE=ZEFATEK Co.,LTD + +OUI:001E0A* + ID_OUI_FROM_DATABASE=Syba Tech Limited + +OUI:001E0B* + ID_OUI_FROM_DATABASE=Hewlett-Packard Company + +OUI:001E0C* + ID_OUI_FROM_DATABASE=Sherwood Information Partners, Inc. + +OUI:001E0D* + ID_OUI_FROM_DATABASE=Micran Ltd. + +OUI:001E0E* + ID_OUI_FROM_DATABASE=MAXI VIEW HOLDINGS LIMITED + +OUI:001E0F* + ID_OUI_FROM_DATABASE=Briot International + +OUI:001E10* + ID_OUI_FROM_DATABASE=ShenZhen Huawei Communication Technologies Co.,Ltd. + +OUI:001E11* + ID_OUI_FROM_DATABASE=ELELUX INTERNATIONAL LTD + +OUI:001E12* + ID_OUI_FROM_DATABASE=Ecolab + +OUI:001E13* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001E14* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001E15* + ID_OUI_FROM_DATABASE=Beech Hill Electronics + +OUI:001E16* + ID_OUI_FROM_DATABASE=Keytronix + +OUI:001E17* + ID_OUI_FROM_DATABASE=STN BV + +OUI:001E18* + ID_OUI_FROM_DATABASE=Radio Activity srl + +OUI:001E19* + ID_OUI_FROM_DATABASE=GTRI + +OUI:001E1A* + ID_OUI_FROM_DATABASE=Best Source Taiwan Inc. + +OUI:001E1B* + ID_OUI_FROM_DATABASE=Digital Stream Technology, Inc. + +OUI:001E1C* + ID_OUI_FROM_DATABASE=SWS Australia Pty Limited + +OUI:001E1D* + ID_OUI_FROM_DATABASE=East Coast Datacom, Inc. + +OUI:001E1E* + ID_OUI_FROM_DATABASE=Honeywell Life Safety + +OUI:001E1F* + ID_OUI_FROM_DATABASE=Nortel + +OUI:001E20* + ID_OUI_FROM_DATABASE=Intertain Inc. + +OUI:001E21* + ID_OUI_FROM_DATABASE=Qisda Co. + +OUI:001E22* + ID_OUI_FROM_DATABASE=ARVOO Imaging Products BV + +OUI:001E23* + ID_OUI_FROM_DATABASE=Electronic Educational Devices, Inc + +OUI:001E24* + ID_OUI_FROM_DATABASE=Zhejiang Bell Technology Co.,ltd + +OUI:001E25* + ID_OUI_FROM_DATABASE=Intek Digital Inc + +OUI:001E26* + ID_OUI_FROM_DATABASE=Digifriends Co. Ltd + +OUI:001E27* + ID_OUI_FROM_DATABASE=SBN TECH Co.,Ltd. + +OUI:001E28* + ID_OUI_FROM_DATABASE=Lumexis Corporation + +OUI:001E29* + ID_OUI_FROM_DATABASE=Hypertherm Inc + +OUI:001E2A* + ID_OUI_FROM_DATABASE=Netgear Inc. + +OUI:001E2B* + ID_OUI_FROM_DATABASE=Radio Systems Design, Inc. + +OUI:001E2C* + ID_OUI_FROM_DATABASE=CyVerse Corporation + +OUI:001E2D* + ID_OUI_FROM_DATABASE=STIM + +OUI:001E2E* + ID_OUI_FROM_DATABASE=SIRTI S.p.A. + +OUI:001E2F* + ID_OUI_FROM_DATABASE=DiMoto Pty Ltd + +OUI:001E30* + ID_OUI_FROM_DATABASE=Shireen Inc + +OUI:001E31* + ID_OUI_FROM_DATABASE=INFOMARK CO.,LTD. + +OUI:001E32* + ID_OUI_FROM_DATABASE=Zensys + +OUI:001E33* + ID_OUI_FROM_DATABASE=Inventec Corporation + +OUI:001E34* + ID_OUI_FROM_DATABASE=CryptoMetrics + +OUI:001E35* + ID_OUI_FROM_DATABASE=Nintendo Co., Ltd. + +OUI:001E36* + ID_OUI_FROM_DATABASE=IPTE + +OUI:001E37* + ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co., Ltd. + +OUI:001E38* + ID_OUI_FROM_DATABASE=Bluecard Software Technology Co., Ltd. + +OUI:001E39* + ID_OUI_FROM_DATABASE=Comsys Communication Ltd. + +OUI:001E3A* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:001E3B* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:001E3C* + ID_OUI_FROM_DATABASE=Lyngbox Media AB + +OUI:001E3D* + ID_OUI_FROM_DATABASE=Alps Electric Co., Ltd + +OUI:001E3E* + ID_OUI_FROM_DATABASE=KMW Inc. + +OUI:001E3F* + ID_OUI_FROM_DATABASE=TrellisWare Technologies, Inc. + +OUI:001E40* + ID_OUI_FROM_DATABASE=Shanghai DareGlobal Technologies Co.,Ltd. + +OUI:001E41* + ID_OUI_FROM_DATABASE=Microwave Communication & Component, Inc. + +OUI:001E42* + ID_OUI_FROM_DATABASE=Teltonika + +OUI:001E43* + ID_OUI_FROM_DATABASE=AISIN AW CO.,LTD. + +OUI:001E44* + ID_OUI_FROM_DATABASE=SANTEC + +OUI:001E45* + ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications AB + +OUI:001E46* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:001E47* + ID_OUI_FROM_DATABASE=PT. Hariff Daya Tunggal Engineering + +OUI:001E48* + ID_OUI_FROM_DATABASE=Wi-Links + +OUI:001E49* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001E4A* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001E4B* + ID_OUI_FROM_DATABASE=City Theatrical + +OUI:001E4C* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind.Co., Ltd. + +OUI:001E4D* + ID_OUI_FROM_DATABASE=Welkin Sciences, LLC + +OUI:001E4E* + ID_OUI_FROM_DATABASE=DAKO EDV-Ingenieur- und Systemhaus GmbH + +OUI:001E4F* + ID_OUI_FROM_DATABASE=Dell Inc. + +OUI:001E50* + ID_OUI_FROM_DATABASE=BATTISTONI RESEARCH + +OUI:001E51* + ID_OUI_FROM_DATABASE=Converter Industry Srl + +OUI:001E52* + ID_OUI_FROM_DATABASE=Apple Computer Inc + +OUI:001E53* + ID_OUI_FROM_DATABASE=Further Tech Co., LTD + +OUI:001E54* + ID_OUI_FROM_DATABASE=TOYO ELECTRIC Corporation + +OUI:001E55* + ID_OUI_FROM_DATABASE=COWON SYSTEMS,Inc. + +OUI:001E56* + ID_OUI_FROM_DATABASE=Bally Wulff Entertainment GmbH + +OUI:001E57* + ID_OUI_FROM_DATABASE=ALCOMA, spol. s r.o. + +OUI:001E58* + ID_OUI_FROM_DATABASE=D-Link Corporation + +OUI:001E59* + ID_OUI_FROM_DATABASE=Silicon Turnkey Express, LLC + +OUI:001E5A* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:001E5B* + ID_OUI_FROM_DATABASE=Unitron Company, Inc. + +OUI:001E5C* + ID_OUI_FROM_DATABASE=RB GeneralEkonomik + +OUI:001E5D* + ID_OUI_FROM_DATABASE=Holosys d.o.o. + +OUI:001E5E* + ID_OUI_FROM_DATABASE=COmputime Ltd. + +OUI:001E5F* + ID_OUI_FROM_DATABASE=KwikByte, LLC + +OUI:001E60* + ID_OUI_FROM_DATABASE=Digital Lighting Systems, Inc + +OUI:001E61* + ID_OUI_FROM_DATABASE=ITEC GmbH + +OUI:001E62* + ID_OUI_FROM_DATABASE=Siemon + +OUI:001E63* + ID_OUI_FROM_DATABASE=Vibro-Meter SA + +OUI:001E64* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:001E65* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:001E66* + ID_OUI_FROM_DATABASE=RESOL Elektronische Regelungen GmbH + +OUI:001E67* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:001E68* + ID_OUI_FROM_DATABASE=Quanta Computer + +OUI:001E69* + ID_OUI_FROM_DATABASE=Thomson Inc. + +OUI:001E6A* + ID_OUI_FROM_DATABASE=Beijing Bluexon Technology Co.,Ltd + +OUI:001E6B* + ID_OUI_FROM_DATABASE=Scientific Atlanta, A Cisco Company + +OUI:001E6C* + ID_OUI_FROM_DATABASE=Carbon Mountain LLC + +OUI:001E6D* + ID_OUI_FROM_DATABASE=IT R&D Center + +OUI:001E6E* + ID_OUI_FROM_DATABASE=Shenzhen First Mile Communications Ltd + +OUI:001E6F* + ID_OUI_FROM_DATABASE=Magna-Power Electronics, Inc. + +OUI:001E70* + ID_OUI_FROM_DATABASE=Cobham Defence Communications Ltd + +OUI:001E71* + ID_OUI_FROM_DATABASE=Igeacare Solutions Inc. + +OUI:001E72* + ID_OUI_FROM_DATABASE=PCS + +OUI:001E73* + ID_OUI_FROM_DATABASE=ZTE CORPORATION + +OUI:001E74* + ID_OUI_FROM_DATABASE=SAGEM COMMUNICATION + +OUI:001E75* + ID_OUI_FROM_DATABASE=LG Electronics + +OUI:001E76* + ID_OUI_FROM_DATABASE=Thermo Fisher Scientific + +OUI:001E77* + ID_OUI_FROM_DATABASE=Air2App + +OUI:001E78* + ID_OUI_FROM_DATABASE=Owitek Technology Ltd., + +OUI:001E79* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001E7A* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001E7B* + ID_OUI_FROM_DATABASE=R.I.CO. S.r.l. + +OUI:001E7C* + ID_OUI_FROM_DATABASE=Taiwick Limited + +OUI:001E7D* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:001E7E* + ID_OUI_FROM_DATABASE=Nortel + +OUI:001E7F* + ID_OUI_FROM_DATABASE=CBM of America + +OUI:001E80* + ID_OUI_FROM_DATABASE=Last Mile Ltd. + +OUI:001E81* + ID_OUI_FROM_DATABASE=CNB Technology Inc. + +OUI:001E82* + ID_OUI_FROM_DATABASE=SanDisk Corporation + +OUI:001E83* + ID_OUI_FROM_DATABASE=LAN/MAN Standards Association (LMSC) + +OUI:001E84* + ID_OUI_FROM_DATABASE=Pika Technologies Inc. + +OUI:001E85* + ID_OUI_FROM_DATABASE=Lagotek Corporation + +OUI:001E86* + ID_OUI_FROM_DATABASE=MEL Co.,Ltd. + +OUI:001E87* + ID_OUI_FROM_DATABASE=Realease Limited + +OUI:001E88* + ID_OUI_FROM_DATABASE=ANDOR SYSTEM SUPPORT CO., LTD. + +OUI:001E89* + ID_OUI_FROM_DATABASE=CRFS Limited + +OUI:001E8A* + ID_OUI_FROM_DATABASE=eCopy, Inc + +OUI:001E8B* + ID_OUI_FROM_DATABASE=Infra Access Korea Co., Ltd. + +OUI:001E8C* + ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. + +OUI:001E8D* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:001E8E* + ID_OUI_FROM_DATABASE=Hunkeler AG + +OUI:001E8F* + ID_OUI_FROM_DATABASE=CANON INC. + +OUI:001E90* + ID_OUI_FROM_DATABASE=Elitegroup Computer Systems Co + +OUI:001E91* + ID_OUI_FROM_DATABASE=KIMIN Electronic Co., Ltd. + +OUI:001E92* + ID_OUI_FROM_DATABASE=JEULIN S.A. + +OUI:001E93* + ID_OUI_FROM_DATABASE=CiriTech Systems Inc + +OUI:001E94* + ID_OUI_FROM_DATABASE=SUPERCOM TECHNOLOGY CORPORATION + +OUI:001E95* + ID_OUI_FROM_DATABASE=SIGMALINK + +OUI:001E96* + ID_OUI_FROM_DATABASE=Sepura Plc + +OUI:001E97* + ID_OUI_FROM_DATABASE=Medium Link System Technology CO., LTD, + +OUI:001E98* + ID_OUI_FROM_DATABASE=GreenLine Communications + +OUI:001E99* + ID_OUI_FROM_DATABASE=Vantanol Industrial Corporation + +OUI:001E9A* + ID_OUI_FROM_DATABASE=HAMILTON Bonaduz AG + +OUI:001E9B* + ID_OUI_FROM_DATABASE=San-Eisha, Ltd. + +OUI:001E9C* + ID_OUI_FROM_DATABASE=Fidustron INC + +OUI:001E9D* + ID_OUI_FROM_DATABASE=Recall Technologies, Inc. + +OUI:001E9E* + ID_OUI_FROM_DATABASE=ddm hopt + schuler Gmbh + Co. KG + +OUI:001E9F* + ID_OUI_FROM_DATABASE=Visioneering Systems, Inc. + +OUI:001EA0* + ID_OUI_FROM_DATABASE=XLN-t + +OUI:001EA1* + ID_OUI_FROM_DATABASE=Brunata a/s + +OUI:001EA2* + ID_OUI_FROM_DATABASE=Symx Systems, Inc. + +OUI:001EA3* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:001EA4* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:001EA5* + ID_OUI_FROM_DATABASE=ROBOTOUS, Inc. + +OUI:001EA6* + ID_OUI_FROM_DATABASE=Best IT World (India) Pvt. Ltd. + +OUI:001EA7* + ID_OUI_FROM_DATABASE=ActionTec Electronics, Inc + +OUI:001EA8* + ID_OUI_FROM_DATABASE=Datang Mobile Communications Equipment CO.,LTD + +OUI:001EA9* + ID_OUI_FROM_DATABASE=Nintendo Co., Ltd. + +OUI:001EAA* + ID_OUI_FROM_DATABASE=E-Senza Technologies GmbH + +OUI:001EAB* + ID_OUI_FROM_DATABASE=TeleWell Oy + +OUI:001EAC* + ID_OUI_FROM_DATABASE=Armadeus Systems + +OUI:001EAD* + ID_OUI_FROM_DATABASE=Wingtech Group Limited + +OUI:001EAE* + ID_OUI_FROM_DATABASE=Continental Automotive Systems + +OUI:001EAF* + ID_OUI_FROM_DATABASE=Ophir Optronics Ltd + +OUI:001EB0* + ID_OUI_FROM_DATABASE=ImesD Electronica S.L. + +OUI:001EB1* + ID_OUI_FROM_DATABASE=Cryptsoft Pty Ltd + +OUI:001EB2* + ID_OUI_FROM_DATABASE=LG innotek + +OUI:001EB3* + ID_OUI_FROM_DATABASE=Primex Wireless + +OUI:001EB4* + ID_OUI_FROM_DATABASE=UNIFAT TECHNOLOGY LTD. + +OUI:001EB5* + ID_OUI_FROM_DATABASE=Ever Sparkle Technologies Ltd + +OUI:001EB6* + ID_OUI_FROM_DATABASE=TAG Heuer SA + +OUI:001EB7* + ID_OUI_FROM_DATABASE=TBTech, Co., Ltd. + +OUI:001EB8* + ID_OUI_FROM_DATABASE=Fortis, Inc. + +OUI:001EB9* + ID_OUI_FROM_DATABASE=Sing Fai Technology Limited + +OUI:001EBA* + ID_OUI_FROM_DATABASE=High Density Devices AS + +OUI:001EBB* + ID_OUI_FROM_DATABASE=BLUELIGHT TECHNOLOGY INC. + +OUI:001EBC* + ID_OUI_FROM_DATABASE=WINTECH AUTOMATION CO.,LTD. + +OUI:001EBD* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001EBE* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001EBF* + ID_OUI_FROM_DATABASE=Haas Automation Inc. + +OUI:001EC0* + ID_OUI_FROM_DATABASE=Microchip Technology Inc. + +OUI:001EC1* + ID_OUI_FROM_DATABASE=3COM EUROPE LTD + +OUI:001EC2* + ID_OUI_FROM_DATABASE=Apple, Inc + +OUI:001EC3* + ID_OUI_FROM_DATABASE=Kozio, Inc. + +OUI:001EC4* + ID_OUI_FROM_DATABASE=Celio Corp + +OUI:001EC5* + ID_OUI_FROM_DATABASE=Middle Atlantic Products Inc + +OUI:001EC6* + ID_OUI_FROM_DATABASE=Obvius Holdings LLC + +OUI:001EC7* + ID_OUI_FROM_DATABASE=2Wire + +OUI:001EC8* + ID_OUI_FROM_DATABASE=Rapid Mobile (Pty) Ltd + +OUI:001EC9* + ID_OUI_FROM_DATABASE=Dell Inc + +OUI:001ECA* + ID_OUI_FROM_DATABASE=Nortel + +OUI:001ECB* + ID_OUI_FROM_DATABASE="RPC "Energoautomatika" Ltd + +OUI:001ECC* + ID_OUI_FROM_DATABASE=CDVI + +OUI:001ECD* + ID_OUI_FROM_DATABASE=KYLAND + +OUI:001ECE* + ID_OUI_FROM_DATABASE=BISA Technologies (Hong Kong) Limited + +OUI:001ECF* + ID_OUI_FROM_DATABASE=PHILIPS ELECTRONICS UK LTD + +OUI:001ED0* + ID_OUI_FROM_DATABASE=Ingespace + +OUI:001ED1* + ID_OUI_FROM_DATABASE=Keyprocessor B.V. + +OUI:001ED2* + ID_OUI_FROM_DATABASE=Ray Shine Video Technology Inc + +OUI:001ED3* + ID_OUI_FROM_DATABASE=Dot Technology Int'l Co., Ltd. + +OUI:001ED4* + ID_OUI_FROM_DATABASE=Doble Engineering + +OUI:001ED5* + ID_OUI_FROM_DATABASE=Tekon-Automatics + +OUI:001ED6* + ID_OUI_FROM_DATABASE=Alentec & Orion AB + +OUI:001ED7* + ID_OUI_FROM_DATABASE=H-Stream Wireless, Inc. + +OUI:001ED8* + ID_OUI_FROM_DATABASE=Digital United Inc. + +OUI:001ED9* + ID_OUI_FROM_DATABASE=Mitsubishi Precision Co.,LTd. + +OUI:001EDA* + ID_OUI_FROM_DATABASE=Wesemann Elektrotechniek B.V. + +OUI:001EDB* + ID_OUI_FROM_DATABASE=Giken Trastem Co., Ltd. + +OUI:001EDC* + ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications AB + +OUI:001EDD* + ID_OUI_FROM_DATABASE=WASKO S.A. + +OUI:001EDE* + ID_OUI_FROM_DATABASE=BYD COMPANY LIMITED + +OUI:001EDF* + ID_OUI_FROM_DATABASE=Master Industrialization Center Kista + +OUI:001EE0* + ID_OUI_FROM_DATABASE=Urmet Domus SpA + +OUI:001EE1* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:001EE2* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:001EE3* + ID_OUI_FROM_DATABASE=T&W Electronics (ShenZhen) Co.,Ltd + +OUI:001EE4* + ID_OUI_FROM_DATABASE=ACS Solutions France + +OUI:001EE5* + ID_OUI_FROM_DATABASE=Cisco-Linksys, LLC + +OUI:001EE6* + ID_OUI_FROM_DATABASE=Shenzhen Advanced Video Info-Tech Co., Ltd. + +OUI:001EE7* + ID_OUI_FROM_DATABASE=Epic Systems Inc + +OUI:001EE8* + ID_OUI_FROM_DATABASE=Mytek + +OUI:001EE9* + ID_OUI_FROM_DATABASE=Stoneridge Electronics AB + +OUI:001EEA* + ID_OUI_FROM_DATABASE=Sensor Switch, Inc. + +OUI:001EEB* + ID_OUI_FROM_DATABASE=Talk-A-Phone Co. + +OUI:001EEC* + ID_OUI_FROM_DATABASE=COMPAL INFORMATION (KUNSHAN) CO., LTD. + +OUI:001EED* + ID_OUI_FROM_DATABASE=Adventiq Ltd. + +OUI:001EEE* + ID_OUI_FROM_DATABASE=ETL Systems Ltd + +OUI:001EEF* + ID_OUI_FROM_DATABASE=Cantronic International Limited + +OUI:001EF0* + ID_OUI_FROM_DATABASE=Gigafin Networks + +OUI:001EF1* + ID_OUI_FROM_DATABASE=Servimat + +OUI:001EF2* + ID_OUI_FROM_DATABASE=Micro Motion Inc + +OUI:001EF3* + ID_OUI_FROM_DATABASE=From2 + +OUI:001EF4* + ID_OUI_FROM_DATABASE=L-3 Communications Display Systems + +OUI:001EF5* + ID_OUI_FROM_DATABASE=Hitek Automated Inc. + +OUI:001EF6* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001EF7* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001EF8* + ID_OUI_FROM_DATABASE=Emfinity Inc. + +OUI:001EF9* + ID_OUI_FROM_DATABASE=Pascom Kommunikations systeme GmbH. + +OUI:001EFA* + ID_OUI_FROM_DATABASE=PROTEI Ltd. + +OUI:001EFB* + ID_OUI_FROM_DATABASE=Trio Motion Technology Ltd + +OUI:001EFC* + ID_OUI_FROM_DATABASE=JSC "MASSA-K" + +OUI:001EFD* + ID_OUI_FROM_DATABASE=Microbit 2.0 AB + +OUI:001EFE* + ID_OUI_FROM_DATABASE=LEVEL s.r.o. + +OUI:001EFF* + ID_OUI_FROM_DATABASE=Mueller-Elektronik GmbH & Co. KG + +OUI:001F00* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:001F01* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:001F02* + ID_OUI_FROM_DATABASE=Pixelmetrix Corporation Pte Ltd + +OUI:001F03* + ID_OUI_FROM_DATABASE=NUM AG + +OUI:001F04* + ID_OUI_FROM_DATABASE=Granch Ltd. + +OUI:001F05* + ID_OUI_FROM_DATABASE=iTAS Technology Corp. + +OUI:001F06* + ID_OUI_FROM_DATABASE=Integrated Dispatch Solutions + +OUI:001F07* + ID_OUI_FROM_DATABASE=AZTEQ Mobile + +OUI:001F08* + ID_OUI_FROM_DATABASE=RISCO LTD + +OUI:001F09* + ID_OUI_FROM_DATABASE=JASTEC CO., LTD. + +OUI:001F0A* + ID_OUI_FROM_DATABASE=Nortel + +OUI:001F0B* + ID_OUI_FROM_DATABASE=Federal State Unitary Enterprise Industrial Union"Electropribor" + +OUI:001F0C* + ID_OUI_FROM_DATABASE=Intelligent Digital Services GmbH + +OUI:001F0D* + ID_OUI_FROM_DATABASE=L3 Communications - Telemetry West + +OUI:001F0E* + ID_OUI_FROM_DATABASE=Japan Kyastem Co., Ltd + +OUI:001F0F* + ID_OUI_FROM_DATABASE=Select Engineered Systems + +OUI:001F10* + ID_OUI_FROM_DATABASE=TOLEDO DO BRASIL INDUSTRIA DE BALANCAS LTDA + +OUI:001F11* + ID_OUI_FROM_DATABASE=OPENMOKO, INC. + +OUI:001F12* + ID_OUI_FROM_DATABASE=Juniper Networks + +OUI:001F13* + ID_OUI_FROM_DATABASE=S.& A.S. Ltd. + +OUI:001F14* + ID_OUI_FROM_DATABASE=NexG + +OUI:001F15* + ID_OUI_FROM_DATABASE=Bioscrypt Inc + +OUI:001F16* + ID_OUI_FROM_DATABASE=Wistron Corporation + +OUI:001F17* + ID_OUI_FROM_DATABASE=IDX Company, Ltd. + +OUI:001F18* + ID_OUI_FROM_DATABASE=Hakusan.Mfg.Co,.Ltd + +OUI:001F19* + ID_OUI_FROM_DATABASE=BEN-RI ELECTRONICA S.A. + +OUI:001F1A* + ID_OUI_FROM_DATABASE=Prominvest + +OUI:001F1B* + ID_OUI_FROM_DATABASE=RoyalTek Company Ltd. + +OUI:001F1C* + ID_OUI_FROM_DATABASE=KOBISHI ELECTRIC Co.,Ltd. + +OUI:001F1D* + ID_OUI_FROM_DATABASE=Atlas Material Testing Technology LLC + +OUI:001F1E* + ID_OUI_FROM_DATABASE=Astec Technology Co., Ltd + +OUI:001F1F* + ID_OUI_FROM_DATABASE=Edimax Technology Co. Ltd. + +OUI:001F20* + ID_OUI_FROM_DATABASE=Logitech Europe SA + +OUI:001F21* + ID_OUI_FROM_DATABASE=Inner Mongolia Yin An Science & Technology Development Co.,L + +OUI:001F22* + ID_OUI_FROM_DATABASE=Source Photonics, Inc. + +OUI:001F23* + ID_OUI_FROM_DATABASE=Interacoustics + +OUI:001F24* + ID_OUI_FROM_DATABASE=DIGITVIEW TECHNOLOGY CO., LTD. + +OUI:001F25* + ID_OUI_FROM_DATABASE=MBS GmbH + +OUI:001F26* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001F27* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001F28* + ID_OUI_FROM_DATABASE=ProCurve Networking by HP + +OUI:001F29* + ID_OUI_FROM_DATABASE=Hewlett-Packard Company + +OUI:001F2A* + ID_OUI_FROM_DATABASE=ACCM + +OUI:001F2B* + ID_OUI_FROM_DATABASE=Orange Logic + +OUI:001F2C* + ID_OUI_FROM_DATABASE=Starbridge Networks + +OUI:001F2D* + ID_OUI_FROM_DATABASE=Electro-Optical Imaging, Inc. + +OUI:001F2E* + ID_OUI_FROM_DATABASE=Triangle Research Int'l Pte Ltd + +OUI:001F2F* + ID_OUI_FROM_DATABASE=Berker GmbH & Co. KG + +OUI:001F30* + ID_OUI_FROM_DATABASE=Travelping + +OUI:001F31* + ID_OUI_FROM_DATABASE=Radiocomp + +OUI:001F32* + ID_OUI_FROM_DATABASE=Nintendo Co., Ltd. + +OUI:001F33* + ID_OUI_FROM_DATABASE=Netgear Inc. + +OUI:001F34* + ID_OUI_FROM_DATABASE=Lung Hwa Electronics Co., Ltd. + +OUI:001F35* + ID_OUI_FROM_DATABASE=AIR802 LLC + +OUI:001F36* + ID_OUI_FROM_DATABASE=Bellwin Information Co. Ltd., + +OUI:001F37* + ID_OUI_FROM_DATABASE=Genesis I&C + +OUI:001F38* + ID_OUI_FROM_DATABASE=POSITRON + +OUI:001F39* + ID_OUI_FROM_DATABASE=Construcciones y Auxiliar de Ferrocarriles, S.A. + +OUI:001F3A* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind.Co., Ltd. + +OUI:001F3B* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:001F3C* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:001F3D* + ID_OUI_FROM_DATABASE=Qbit GmbH + +OUI:001F3E* + ID_OUI_FROM_DATABASE=RP-Technik e.K. + +OUI:001F3F* + ID_OUI_FROM_DATABASE=AVM GmbH + +OUI:001F40* + ID_OUI_FROM_DATABASE=Speakercraft Inc. + +OUI:001F41* + ID_OUI_FROM_DATABASE=Ruckus Wireless + +OUI:001F42* + ID_OUI_FROM_DATABASE=Etherstack Pty Ltd + +OUI:001F43* + ID_OUI_FROM_DATABASE=ENTES ELEKTRONIK + +OUI:001F44* + ID_OUI_FROM_DATABASE=GE Transportation Systems + +OUI:001F45* + ID_OUI_FROM_DATABASE=Enterasys + +OUI:001F46* + ID_OUI_FROM_DATABASE=Nortel + +OUI:001F47* + ID_OUI_FROM_DATABASE=MCS Logic Inc. + +OUI:001F48* + ID_OUI_FROM_DATABASE=Mojix Inc. + +OUI:001F49* + ID_OUI_FROM_DATABASE=Eurosat Distribution Ltd + +OUI:001F4A* + ID_OUI_FROM_DATABASE=Albentia Systems S.A. + +OUI:001F4B* + ID_OUI_FROM_DATABASE=Lineage Power + +OUI:001F4C* + ID_OUI_FROM_DATABASE=Roseman Engineering Ltd + +OUI:001F4D* + ID_OUI_FROM_DATABASE=Segnetics LLC + +OUI:001F4E* + ID_OUI_FROM_DATABASE=ConMed Linvatec + +OUI:001F4F* + ID_OUI_FROM_DATABASE=Thinkware Co. Ltd. + +OUI:001F50* + ID_OUI_FROM_DATABASE=Swissdis AG + +OUI:001F51* + ID_OUI_FROM_DATABASE=HD Communications Corp + +OUI:001F52* + ID_OUI_FROM_DATABASE=UVT Unternehmensberatung fur Verkehr und Technik GmbH + +OUI:001F53* + ID_OUI_FROM_DATABASE=GEMAC Gesellschaft für Mikroelektronikanwendung Chemnitz mbH + +OUI:001F54* + ID_OUI_FROM_DATABASE=Lorex Technology Inc. + +OUI:001F55* + ID_OUI_FROM_DATABASE=Honeywell Security (China) Co., Ltd. + +OUI:001F56* + ID_OUI_FROM_DATABASE=DIGITAL FORECAST + +OUI:001F57* + ID_OUI_FROM_DATABASE=Phonik Innovation Co.,LTD + +OUI:001F58* + ID_OUI_FROM_DATABASE=EMH Energiemesstechnik GmbH & co.KG + +OUI:001F59* + ID_OUI_FROM_DATABASE=Kronback Tracers + +OUI:001F5A* + ID_OUI_FROM_DATABASE=Beckwith Electric Co. + +OUI:001F5B* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:001F5C* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:001F5D* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:001F5E* + ID_OUI_FROM_DATABASE=Dyna Technology Co.,Ltd. + +OUI:001F5F* + ID_OUI_FROM_DATABASE=Blatand GmbH + +OUI:001F60* + ID_OUI_FROM_DATABASE=COMPASS SYSTEMS CORP. + +OUI:001F61* + ID_OUI_FROM_DATABASE=Talent Communication Networks Inc. + +OUI:001F62* + ID_OUI_FROM_DATABASE=JSC "Stilsoft" + +OUI:001F63* + ID_OUI_FROM_DATABASE=JSC Goodwin-Europa + +OUI:001F64* + ID_OUI_FROM_DATABASE=Beijing Autelan Technology Inc. + +OUI:001F65* + ID_OUI_FROM_DATABASE=KOREA ELECTRIC TERMINAL CO., LTD. + +OUI:001F66* + ID_OUI_FROM_DATABASE=PLANAR LLC + +OUI:001F67* + ID_OUI_FROM_DATABASE=Hitachi,Ltd. + +OUI:001F68* + ID_OUI_FROM_DATABASE=Martinsson Elektronik AB + +OUI:001F69* + ID_OUI_FROM_DATABASE=Pingood Technology Co., Ltd. + +OUI:001F6A* + ID_OUI_FROM_DATABASE=PacketFlux Technologies, Inc. + +OUI:001F6B* + ID_OUI_FROM_DATABASE=LG Electronics + +OUI:001F6C* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001F6D* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001F6E* + ID_OUI_FROM_DATABASE=Vtech Engineering Corporation + +OUI:001F6F* + ID_OUI_FROM_DATABASE=Fujian Sunnada Communication Co.,Ltd. + +OUI:001F70* + ID_OUI_FROM_DATABASE=Botik Technologies LTD + +OUI:001F71* + ID_OUI_FROM_DATABASE=xG Technology, Inc. + +OUI:001F72* + ID_OUI_FROM_DATABASE=QingDao Hiphone Technology Co,.Ltd + +OUI:001F73* + ID_OUI_FROM_DATABASE=Teraview Technology Co., Ltd. + +OUI:001F74* + ID_OUI_FROM_DATABASE=Eigen Development + +OUI:001F75* + ID_OUI_FROM_DATABASE=GiBahn Media + +OUI:001F76* + ID_OUI_FROM_DATABASE=AirLogic Systems Inc. + +OUI:001F77* + ID_OUI_FROM_DATABASE=HEOL DESIGN + +OUI:001F78* + ID_OUI_FROM_DATABASE=Blue Fox Porini Textile + +OUI:001F79* + ID_OUI_FROM_DATABASE=Lodam Electronics A/S + +OUI:001F7A* + ID_OUI_FROM_DATABASE=WiWide Inc. + +OUI:001F7B* + ID_OUI_FROM_DATABASE=TechNexion Ltd. + +OUI:001F7C* + ID_OUI_FROM_DATABASE=Witelcom AS + +OUI:001F7D* + ID_OUI_FROM_DATABASE=embedded wireless GmbH + +OUI:001F7E* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:001F7F* + ID_OUI_FROM_DATABASE=Phabrix Limited + +OUI:001F80* + ID_OUI_FROM_DATABASE=Lucas Holding bv + +OUI:001F81* + ID_OUI_FROM_DATABASE=Accel Semiconductor Corp + +OUI:001F82* + ID_OUI_FROM_DATABASE=Cal-Comp Electronics & Communications Co., Ltd + +OUI:001F83* + ID_OUI_FROM_DATABASE=Teleplan Technology Services Sdn Bhd + +OUI:001F84* + ID_OUI_FROM_DATABASE=Gigle Semiconductor + +OUI:001F85* + ID_OUI_FROM_DATABASE=Apriva ISS, LLC + +OUI:001F86* + ID_OUI_FROM_DATABASE=digEcor + +OUI:001F87* + ID_OUI_FROM_DATABASE=Skydigital Inc. + +OUI:001F88* + ID_OUI_FROM_DATABASE=FMS Force Measuring Systems AG + +OUI:001F89* + ID_OUI_FROM_DATABASE=Signalion GmbH + +OUI:001F8A* + ID_OUI_FROM_DATABASE=Ellion Digital Inc. + +OUI:001F8B* + ID_OUI_FROM_DATABASE=Cache IQ + +OUI:001F8C* + ID_OUI_FROM_DATABASE=CCS Inc. + +OUI:001F8D* + ID_OUI_FROM_DATABASE=Ingenieurbuero Stark GmbH und Ko. KG + +OUI:001F8E* + ID_OUI_FROM_DATABASE=Metris USA Inc. + +OUI:001F8F* + ID_OUI_FROM_DATABASE=Shanghai Bellmann Digital Source Co.,Ltd. + +OUI:001F90* + ID_OUI_FROM_DATABASE=Actiontec Electronics, Inc + +OUI:001F91* + ID_OUI_FROM_DATABASE=DBS Lodging Technologies, LLC + +OUI:001F92* + ID_OUI_FROM_DATABASE=VideoIQ, Inc. + +OUI:001F93* + ID_OUI_FROM_DATABASE=Xiotech Corporation + +OUI:001F94* + ID_OUI_FROM_DATABASE=Lascar Electronics Ltd + +OUI:001F95* + ID_OUI_FROM_DATABASE=SAGEM COMMUNICATION + +OUI:001F96* + ID_OUI_FROM_DATABASE=APROTECH CO.LTD + +OUI:001F97* + ID_OUI_FROM_DATABASE=BERTANA SRL + +OUI:001F98* + ID_OUI_FROM_DATABASE=DAIICHI-DENTSU LTD. + +OUI:001F99* + ID_OUI_FROM_DATABASE=SERONICS co.ltd + +OUI:001F9A* + ID_OUI_FROM_DATABASE=Nortel Networks + +OUI:001F9B* + ID_OUI_FROM_DATABASE=POSBRO + +OUI:001F9C* + ID_OUI_FROM_DATABASE=LEDCO + +OUI:001F9D* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001F9E* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001F9F* + ID_OUI_FROM_DATABASE=Thomson Telecom Belgium + +OUI:001FA0* + ID_OUI_FROM_DATABASE=A10 Networks + +OUI:001FA1* + ID_OUI_FROM_DATABASE=Gtran Inc + +OUI:001FA2* + ID_OUI_FROM_DATABASE=Datron World Communications, Inc. + +OUI:001FA3* + ID_OUI_FROM_DATABASE=T&W Electronics(Shenzhen)Co.,Ltd. + +OUI:001FA4* + ID_OUI_FROM_DATABASE=ShenZhen Gongjin Electronics Co.,Ltd + +OUI:001FA5* + ID_OUI_FROM_DATABASE=Blue-White Industries + +OUI:001FA6* + ID_OUI_FROM_DATABASE=Stilo srl + +OUI:001FA7* + ID_OUI_FROM_DATABASE=Sony Computer Entertainment Inc. + +OUI:001FA8* + ID_OUI_FROM_DATABASE=Smart Energy Instruments Inc. + +OUI:001FA9* + ID_OUI_FROM_DATABASE=Atlanta DTH, Inc. + +OUI:001FAA* + ID_OUI_FROM_DATABASE=Taseon, Inc. + +OUI:001FAB* + ID_OUI_FROM_DATABASE=I.S HIGH TECH.INC + +OUI:001FAC* + ID_OUI_FROM_DATABASE=Goodmill Systems Ltd + +OUI:001FAD* + ID_OUI_FROM_DATABASE=Brown Innovations, Inc + +OUI:001FAE* + ID_OUI_FROM_DATABASE=Blick South Africa (Pty) Ltd + +OUI:001FAF* + ID_OUI_FROM_DATABASE=NextIO, Inc. + +OUI:001FB0* + ID_OUI_FROM_DATABASE=TimeIPS, Inc. + +OUI:001FB1* + ID_OUI_FROM_DATABASE=Cybertech Inc. + +OUI:001FB2* + ID_OUI_FROM_DATABASE=Sontheim Industrie Elektronik GmbH + +OUI:001FB3* + ID_OUI_FROM_DATABASE=2Wire + +OUI:001FB4* + ID_OUI_FROM_DATABASE=SmartShare Systems + +OUI:001FB5* + ID_OUI_FROM_DATABASE=I/O Interconnect Inc. + +OUI:001FB6* + ID_OUI_FROM_DATABASE=Chi Lin Technology Co., Ltd. + +OUI:001FB7* + ID_OUI_FROM_DATABASE=WiMate Technologies Corp. + +OUI:001FB8* + ID_OUI_FROM_DATABASE=Universal Remote Control, Inc. + +OUI:001FB9* + ID_OUI_FROM_DATABASE=Paltronics + +OUI:001FBA* + ID_OUI_FROM_DATABASE=BoYoung Tech. & Marketing, Inc. + +OUI:001FBB* + ID_OUI_FROM_DATABASE=Xenatech Co.,LTD + +OUI:001FBC* + ID_OUI_FROM_DATABASE=EVGA Corporation + +OUI:001FBD* + ID_OUI_FROM_DATABASE=Kyocera Wireless Corp. + +OUI:001FBE* + ID_OUI_FROM_DATABASE=Shenzhen Mopnet Industrial Co.,Ltd + +OUI:001FBF* + ID_OUI_FROM_DATABASE=Fulhua Microelectronics Corp. Taiwan Branch + +OUI:001FC0* + ID_OUI_FROM_DATABASE=Control Express Finland Oy + +OUI:001FC1* + ID_OUI_FROM_DATABASE=Hanlong Technology Co.,LTD + +OUI:001FC2* + ID_OUI_FROM_DATABASE=Jow Tong Technology Co Ltd + +OUI:001FC3* + ID_OUI_FROM_DATABASE=SmartSynch, Inc + +OUI:001FC4* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:001FC5* + ID_OUI_FROM_DATABASE=Nintendo Co., Ltd. + +OUI:001FC6* + ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. + +OUI:001FC7* + ID_OUI_FROM_DATABASE=Casio Hitachi Mobile Comunications Co., Ltd. + +OUI:001FC8* + ID_OUI_FROM_DATABASE=Up-Today Industrial Co., Ltd. + +OUI:001FC9* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001FCA* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:001FCB* + ID_OUI_FROM_DATABASE=NIW Solutions + +OUI:001FCC* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:001FCD* + ID_OUI_FROM_DATABASE=Samsung Electronics + +OUI:001FCE* + ID_OUI_FROM_DATABASE=QTECH LLC + +OUI:001FCF* + ID_OUI_FROM_DATABASE=MSI Technology GmbH + +OUI:001FD0* + ID_OUI_FROM_DATABASE=GIGA-BYTE TECHNOLOGY CO.,LTD. + +OUI:001FD1* + ID_OUI_FROM_DATABASE=OPTEX CO.,LTD. + +OUI:001FD2* + ID_OUI_FROM_DATABASE=COMMTECH TECHNOLOGY MACAO COMMERCIAL OFFSHORE LTD. + +OUI:001FD3* + ID_OUI_FROM_DATABASE=RIVA Networks Inc. + +OUI:001FD4* + ID_OUI_FROM_DATABASE=4IPNET, INC. + +OUI:001FD5* + ID_OUI_FROM_DATABASE=MICRORISC s.r.o. + +OUI:001FD6* + ID_OUI_FROM_DATABASE=Shenzhen Allywll + +OUI:001FD7* + ID_OUI_FROM_DATABASE=TELERAD SA + +OUI:001FD8* + ID_OUI_FROM_DATABASE=A-TRUST COMPUTER CORPORATION + +OUI:001FD9* + ID_OUI_FROM_DATABASE=RSD Communications Ltd + +OUI:001FDA* + ID_OUI_FROM_DATABASE=Nortel Networks + +OUI:001FDB* + ID_OUI_FROM_DATABASE=Network Supply Corp., + +OUI:001FDC* + ID_OUI_FROM_DATABASE=Mobile Safe Track Ltd + +OUI:001FDD* + ID_OUI_FROM_DATABASE=GDI LLC + +OUI:001FDE* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:001FDF* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:001FE0* + ID_OUI_FROM_DATABASE=EdgeVelocity Corp + +OUI:001FE1* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co., Ltd. + +OUI:001FE2* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co., Ltd. + +OUI:001FE3* + ID_OUI_FROM_DATABASE=LG Electronics + +OUI:001FE4* + ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications + +OUI:001FE5* + ID_OUI_FROM_DATABASE=In-Circuit GmbH + +OUI:001FE6* + ID_OUI_FROM_DATABASE=Alphion Corporation + +OUI:001FE7* + ID_OUI_FROM_DATABASE=Simet + +OUI:001FE8* + ID_OUI_FROM_DATABASE=KURUSUGAWA Electronics Industry Inc,. + +OUI:001FE9* + ID_OUI_FROM_DATABASE=Printrex, Inc. + +OUI:001FEA* + ID_OUI_FROM_DATABASE=Applied Media Technologies Corporation + +OUI:001FEB* + ID_OUI_FROM_DATABASE=Trio Datacom Pty Ltd + +OUI:001FEC* + ID_OUI_FROM_DATABASE=Synapse Électronique + +OUI:001FED* + ID_OUI_FROM_DATABASE=Tecan Systems Inc. + +OUI:001FEE* + ID_OUI_FROM_DATABASE=ubisys technologies GmbH + +OUI:001FEF* + ID_OUI_FROM_DATABASE=SHINSEI INDUSTRIES CO.,LTD + +OUI:001FF0* + ID_OUI_FROM_DATABASE=Audio Partnership + +OUI:001FF1* + ID_OUI_FROM_DATABASE=Paradox Hellas S.A. + +OUI:001FF2* + ID_OUI_FROM_DATABASE=VIA Technologies, Inc. + +OUI:001FF3* + ID_OUI_FROM_DATABASE=Apple, Inc + +OUI:001FF4* + ID_OUI_FROM_DATABASE=Power Monitors, Inc. + +OUI:001FF5* + ID_OUI_FROM_DATABASE=Kongsberg Defence & Aerospace + +OUI:001FF6* + ID_OUI_FROM_DATABASE=PS Audio International + +OUI:001FF7* + ID_OUI_FROM_DATABASE=Nakajima All Precision Co., Ltd. + +OUI:001FF8* + ID_OUI_FROM_DATABASE=Siemens AG, Sector Industry, Drive Technologies, Motion Control Systems + +OUI:001FF9* + ID_OUI_FROM_DATABASE=Advanced Knowledge Associates + +OUI:001FFA* + ID_OUI_FROM_DATABASE=Coretree, Co, Ltd + +OUI:001FFB* + ID_OUI_FROM_DATABASE=Green Packet Bhd + +OUI:001FFC* + ID_OUI_FROM_DATABASE=Riccius+Sohn GmbH + +OUI:001FFD* + ID_OUI_FROM_DATABASE=Indigo Mobile Technologies Corp. + +OUI:001FFE* + ID_OUI_FROM_DATABASE=ProCurve Networking by HP + +OUI:001FFF* + ID_OUI_FROM_DATABASE=Respironics, Inc. + +OUI:002000* + ID_OUI_FROM_DATABASE=LEXMARK INTERNATIONAL, INC. + +OUI:002001* + ID_OUI_FROM_DATABASE=DSP SOLUTIONS, INC. + +OUI:002002* + ID_OUI_FROM_DATABASE=SERITECH ENTERPRISE CO., LTD. + +OUI:002003* + ID_OUI_FROM_DATABASE=PIXEL POWER LTD. + +OUI:002004* + ID_OUI_FROM_DATABASE=YAMATAKE-HONEYWELL CO., LTD. + +OUI:002005* + ID_OUI_FROM_DATABASE=SIMPLE TECHNOLOGY + +OUI:002006* + ID_OUI_FROM_DATABASE=GARRETT COMMUNICATIONS, INC. + +OUI:002007* + ID_OUI_FROM_DATABASE=SFA, INC. + +OUI:002008* + ID_OUI_FROM_DATABASE=CABLE & COMPUTER TECHNOLOGY + +OUI:002009* + ID_OUI_FROM_DATABASE=PACKARD BELL ELEC., INC. + +OUI:00200A* + ID_OUI_FROM_DATABASE=SOURCE-COMM CORP. + +OUI:00200B* + ID_OUI_FROM_DATABASE=OCTAGON SYSTEMS CORP. + +OUI:00200C* + ID_OUI_FROM_DATABASE=ADASTRA SYSTEMS CORP. + +OUI:00200D* + ID_OUI_FROM_DATABASE=CARL ZEISS + +OUI:00200E* + ID_OUI_FROM_DATABASE=SATELLITE TECHNOLOGY MGMT, INC + +OUI:00200F* + ID_OUI_FROM_DATABASE=TANBAC CO., LTD. + +OUI:002010* + ID_OUI_FROM_DATABASE=JEOL SYSTEM TECHNOLOGY CO. LTD + +OUI:002011* + ID_OUI_FROM_DATABASE=CANOPUS CO., LTD. + +OUI:002012* + ID_OUI_FROM_DATABASE=CAMTRONICS MEDICAL SYSTEMS + +OUI:002013* + ID_OUI_FROM_DATABASE=DIVERSIFIED TECHNOLOGY, INC. + +OUI:002014* + ID_OUI_FROM_DATABASE=GLOBAL VIEW CO., LTD. + +OUI:002015* + ID_OUI_FROM_DATABASE=ACTIS COMPUTER SA + +OUI:002016* + ID_OUI_FROM_DATABASE=SHOWA ELECTRIC WIRE & CABLE CO + +OUI:002017* + ID_OUI_FROM_DATABASE=ORBOTECH + +OUI:002018* + ID_OUI_FROM_DATABASE=CIS TECHNOLOGY INC. + +OUI:002019* + ID_OUI_FROM_DATABASE=OHLER GmbH + +OUI:00201A* + ID_OUI_FROM_DATABASE=MRV Communications, Inc. + +OUI:00201B* + ID_OUI_FROM_DATABASE=NORTHERN TELECOM/NETWORK + +OUI:00201C* + ID_OUI_FROM_DATABASE=EXCEL, INC. + +OUI:00201D* + ID_OUI_FROM_DATABASE=KATANA PRODUCTS + +OUI:00201E* + ID_OUI_FROM_DATABASE=NETQUEST CORPORATION + +OUI:00201F* + ID_OUI_FROM_DATABASE=BEST POWER TECHNOLOGY, INC. + +OUI:002020* + ID_OUI_FROM_DATABASE=MEGATRON COMPUTER INDUSTRIES PTY, LTD. + +OUI:002021* + ID_OUI_FROM_DATABASE=ALGORITHMS SOFTWARE PVT. LTD. + +OUI:002022* + ID_OUI_FROM_DATABASE=NMS Communications + +OUI:002023* + ID_OUI_FROM_DATABASE=T.C. TECHNOLOGIES PTY. LTD + +OUI:002024* + ID_OUI_FROM_DATABASE=PACIFIC COMMUNICATION SCIENCES + +OUI:002025* + ID_OUI_FROM_DATABASE=CONTROL TECHNOLOGY, INC. + +OUI:002026* + ID_OUI_FROM_DATABASE=AMKLY SYSTEMS, INC. + +OUI:002027* + ID_OUI_FROM_DATABASE=MING FORTUNE INDUSTRY CO., LTD + +OUI:002028* + ID_OUI_FROM_DATABASE=WEST EGG SYSTEMS, INC. + +OUI:002029* + ID_OUI_FROM_DATABASE=TELEPROCESSING PRODUCTS, INC. + +OUI:00202A* + ID_OUI_FROM_DATABASE=N.V. DZINE + +OUI:00202B* + ID_OUI_FROM_DATABASE=ADVANCED TELECOMMUNICATIONS MODULES, LTD. + +OUI:00202C* + ID_OUI_FROM_DATABASE=WELLTRONIX CO., LTD. + +OUI:00202D* + ID_OUI_FROM_DATABASE=TAIYO CORPORATION + +OUI:00202E* + ID_OUI_FROM_DATABASE=DAYSTAR DIGITAL + +OUI:00202F* + ID_OUI_FROM_DATABASE=ZETA COMMUNICATIONS, LTD. + +OUI:002030* + ID_OUI_FROM_DATABASE=ANALOG & DIGITAL SYSTEMS + +OUI:002031* + ID_OUI_FROM_DATABASE=Tattile SRL + +OUI:002032* + ID_OUI_FROM_DATABASE=ALCATEL TAISEL + +OUI:002033* + ID_OUI_FROM_DATABASE=SYNAPSE TECHNOLOGIES, INC. + +OUI:002034* + ID_OUI_FROM_DATABASE=ROTEC INDUSTRIEAUTOMATION GMBH + +OUI:002035* + ID_OUI_FROM_DATABASE=IBM Corp + +OUI:002036* + ID_OUI_FROM_DATABASE=BMC SOFTWARE + +OUI:002037* + ID_OUI_FROM_DATABASE=SEAGATE TECHNOLOGY + +OUI:002038* + ID_OUI_FROM_DATABASE=VME MICROSYSTEMS INTERNATIONAL CORPORATION + +OUI:002039* + ID_OUI_FROM_DATABASE=SCINETS + +OUI:00203A* + ID_OUI_FROM_DATABASE=DIGITAL BI0METRICS INC. + +OUI:00203B* + ID_OUI_FROM_DATABASE=WISDM LTD. + +OUI:00203C* + ID_OUI_FROM_DATABASE=EUROTIME AB + +OUI:00203D* + ID_OUI_FROM_DATABASE=Honeywell ECC + +OUI:00203E* + ID_OUI_FROM_DATABASE=LogiCan Technologies, Inc. + +OUI:00203F* + ID_OUI_FROM_DATABASE=JUKI CORPORATION + +OUI:002040* + ID_OUI_FROM_DATABASE=Motorola Broadband Communications Sector + +OUI:002041* + ID_OUI_FROM_DATABASE=DATA NET + +OUI:002042* + ID_OUI_FROM_DATABASE=DATAMETRICS CORP. + +OUI:002043* + ID_OUI_FROM_DATABASE=NEURON COMPANY LIMITED + +OUI:002044* + ID_OUI_FROM_DATABASE=GENITECH PTY LTD + +OUI:002045* + ID_OUI_FROM_DATABASE=ION Networks, Inc. + +OUI:002046* + ID_OUI_FROM_DATABASE=CIPRICO, INC. + +OUI:002047* + ID_OUI_FROM_DATABASE=STEINBRECHER CORP. + +OUI:002048* + ID_OUI_FROM_DATABASE=Marconi Communications + +OUI:002049* + ID_OUI_FROM_DATABASE=COMTRON, INC. + +OUI:00204A* + ID_OUI_FROM_DATABASE=PRONET GMBH + +OUI:00204B* + ID_OUI_FROM_DATABASE=AUTOCOMPUTER CO., LTD. + +OUI:00204C* + ID_OUI_FROM_DATABASE=MITRON COMPUTER PTE LTD. + +OUI:00204D* + ID_OUI_FROM_DATABASE=INOVIS GMBH + +OUI:00204E* + ID_OUI_FROM_DATABASE=NETWORK SECURITY SYSTEMS, INC. + +OUI:00204F* + ID_OUI_FROM_DATABASE=DEUTSCHE AEROSPACE AG + +OUI:002050* + ID_OUI_FROM_DATABASE=KOREA COMPUTER INC. + +OUI:002051* + ID_OUI_FROM_DATABASE=Verilink Corporation + +OUI:002052* + ID_OUI_FROM_DATABASE=RAGULA SYSTEMS + +OUI:002053* + ID_OUI_FROM_DATABASE=HUNTSVILLE MICROSYSTEMS, INC. + +OUI:002054* + ID_OUI_FROM_DATABASE=Sycamore Networks + +OUI:002055* + ID_OUI_FROM_DATABASE=ALTECH CO., LTD. + +OUI:002056* + ID_OUI_FROM_DATABASE=NEOPRODUCTS + +OUI:002057* + ID_OUI_FROM_DATABASE=TITZE DATENTECHNIK GmbH + +OUI:002058* + ID_OUI_FROM_DATABASE=ALLIED SIGNAL INC. + +OUI:002059* + ID_OUI_FROM_DATABASE=MIRO COMPUTER PRODUCTS AG + +OUI:00205A* + ID_OUI_FROM_DATABASE=COMPUTER IDENTICS + +OUI:00205B* + ID_OUI_FROM_DATABASE=Kentrox, LLC + +OUI:00205C* + ID_OUI_FROM_DATABASE=InterNet Systems of Florida, Inc. + +OUI:00205D* + ID_OUI_FROM_DATABASE=NANOMATIC OY + +OUI:00205E* + ID_OUI_FROM_DATABASE=CASTLE ROCK, INC. + +OUI:00205F* + ID_OUI_FROM_DATABASE=GAMMADATA COMPUTER GMBH + +OUI:002060* + ID_OUI_FROM_DATABASE=ALCATEL ITALIA S.p.A. + +OUI:002061* + ID_OUI_FROM_DATABASE=GarrettCom, Inc. + +OUI:002062* + ID_OUI_FROM_DATABASE=SCORPION LOGIC, LTD. + +OUI:002063* + ID_OUI_FROM_DATABASE=WIPRO INFOTECH LTD. + +OUI:002064* + ID_OUI_FROM_DATABASE=PROTEC MICROSYSTEMS, INC. + +OUI:002065* + ID_OUI_FROM_DATABASE=SUPERNET NETWORKING INC. + +OUI:002066* + ID_OUI_FROM_DATABASE=GENERAL MAGIC, INC. + +OUI:002068* + ID_OUI_FROM_DATABASE=ISDYNE + +OUI:002069* + ID_OUI_FROM_DATABASE=ISDN SYSTEMS CORPORATION + +OUI:00206A* + ID_OUI_FROM_DATABASE=OSAKA COMPUTER CORP. + +OUI:00206B* + ID_OUI_FROM_DATABASE=KONICA MINOLTA HOLDINGS, INC. + +OUI:00206C* + ID_OUI_FROM_DATABASE=EVERGREEN TECHNOLOGY CORP. + +OUI:00206D* + ID_OUI_FROM_DATABASE=DATA RACE, INC. + +OUI:00206E* + ID_OUI_FROM_DATABASE=XACT, INC. + +OUI:00206F* + ID_OUI_FROM_DATABASE=FLOWPOINT CORPORATION + +OUI:002070* + ID_OUI_FROM_DATABASE=HYNET, LTD. + +OUI:002071* + ID_OUI_FROM_DATABASE=IBR GMBH + +OUI:002072* + ID_OUI_FROM_DATABASE=WORKLINK INNOVATIONS + +OUI:002073* + ID_OUI_FROM_DATABASE=FUSION SYSTEMS CORPORATION + +OUI:002074* + ID_OUI_FROM_DATABASE=SUNGWOON SYSTEMS + +OUI:002075* + ID_OUI_FROM_DATABASE=MOTOROLA COMMUNICATION ISRAEL + +OUI:002076* + ID_OUI_FROM_DATABASE=REUDO CORPORATION + +OUI:002077* + ID_OUI_FROM_DATABASE=KARDIOS SYSTEMS CORP. + +OUI:002078* + ID_OUI_FROM_DATABASE=RUNTOP, INC. + +OUI:002079* + ID_OUI_FROM_DATABASE=MIKRON GMBH + +OUI:00207A* + ID_OUI_FROM_DATABASE=WiSE Communications, Inc. + +OUI:00207B* + ID_OUI_FROM_DATABASE=Intel Corporation + +OUI:00207C* + ID_OUI_FROM_DATABASE=AUTEC GmbH + +OUI:00207D* + ID_OUI_FROM_DATABASE=ADVANCED COMPUTER APPLICATIONS + +OUI:00207E* + ID_OUI_FROM_DATABASE=FINECOM Co., Ltd. + +OUI:00207F* + ID_OUI_FROM_DATABASE=KYOEI SANGYO CO., LTD. + +OUI:002080* + ID_OUI_FROM_DATABASE=SYNERGY (UK) LTD. + +OUI:002081* + ID_OUI_FROM_DATABASE=TITAN ELECTRONICS + +OUI:002082* + ID_OUI_FROM_DATABASE=ONEAC CORPORATION + +OUI:002083* + ID_OUI_FROM_DATABASE=PRESTICOM INCORPORATED + +OUI:002084* + ID_OUI_FROM_DATABASE=OCE PRINTING SYSTEMS, GMBH + +OUI:002085* + ID_OUI_FROM_DATABASE=EXIDE ELECTRONICS + +OUI:002086* + ID_OUI_FROM_DATABASE=MICROTECH ELECTRONICS LIMITED + +OUI:002087* + ID_OUI_FROM_DATABASE=MEMOTEC, INC. + +OUI:002088* + ID_OUI_FROM_DATABASE=GLOBAL VILLAGE COMMUNICATION + +OUI:002089* + ID_OUI_FROM_DATABASE=T3PLUS NETWORKING, INC. + +OUI:00208A* + ID_OUI_FROM_DATABASE=SONIX COMMUNICATIONS, LTD. + +OUI:00208B* + ID_OUI_FROM_DATABASE=LAPIS TECHNOLOGIES, INC. + +OUI:00208C* + ID_OUI_FROM_DATABASE=GALAXY NETWORKS, INC. + +OUI:00208D* + ID_OUI_FROM_DATABASE=CMD TECHNOLOGY + +OUI:00208E* + ID_OUI_FROM_DATABASE=CHEVIN SOFTWARE ENG. LTD. + +OUI:00208F* + ID_OUI_FROM_DATABASE=ECI TELECOM LTD. + +OUI:002090* + ID_OUI_FROM_DATABASE=ADVANCED COMPRESSION TECHNOLOGY, INC. + +OUI:002091* + ID_OUI_FROM_DATABASE=J125, NATIONAL SECURITY AGENCY + +OUI:002092* + ID_OUI_FROM_DATABASE=CHESS ENGINEERING B.V. + +OUI:002093* + ID_OUI_FROM_DATABASE=LANDINGS TECHNOLOGY CORP. + +OUI:002094* + ID_OUI_FROM_DATABASE=CUBIX CORPORATION + +OUI:002095* + ID_OUI_FROM_DATABASE=RIVA ELECTRONICS + +OUI:002096* + ID_OUI_FROM_DATABASE=Invensys + +OUI:002097* + ID_OUI_FROM_DATABASE=APPLIED SIGNAL TECHNOLOGY + +OUI:002098* + ID_OUI_FROM_DATABASE=HECTRONIC AB + +OUI:002099* + ID_OUI_FROM_DATABASE=BON ELECTRIC CO., LTD. + +OUI:00209A* + ID_OUI_FROM_DATABASE=THE 3DO COMPANY + +OUI:00209B* + ID_OUI_FROM_DATABASE=ERSAT ELECTRONIC GMBH + +OUI:00209C* + ID_OUI_FROM_DATABASE=PRIMARY ACCESS CORP. + +OUI:00209D* + ID_OUI_FROM_DATABASE=LIPPERT AUTOMATIONSTECHNIK + +OUI:00209E* + ID_OUI_FROM_DATABASE=BROWN'S OPERATING SYSTEM SERVICES, LTD. + +OUI:00209F* + ID_OUI_FROM_DATABASE=MERCURY COMPUTER SYSTEMS, INC. + +OUI:0020A0* + ID_OUI_FROM_DATABASE=OA LABORATORY CO., LTD. + +OUI:0020A1* + ID_OUI_FROM_DATABASE=DOVATRON + +OUI:0020A2* + ID_OUI_FROM_DATABASE=GALCOM NETWORKING LTD. + +OUI:0020A3* + ID_OUI_FROM_DATABASE=Harmonic, Inc + +OUI:0020A4* + ID_OUI_FROM_DATABASE=MULTIPOINT NETWORKS + +OUI:0020A5* + ID_OUI_FROM_DATABASE=API ENGINEERING + +OUI:0020A6* + ID_OUI_FROM_DATABASE=Proxim Wireless + +OUI:0020A7* + ID_OUI_FROM_DATABASE=PAIRGAIN TECHNOLOGIES, INC. + +OUI:0020A8* + ID_OUI_FROM_DATABASE=SAST TECHNOLOGY CORP. + +OUI:0020A9* + ID_OUI_FROM_DATABASE=WHITE HORSE INDUSTRIAL + +OUI:0020AA* + ID_OUI_FROM_DATABASE=Ericsson Television Limited + +OUI:0020AB* + ID_OUI_FROM_DATABASE=MICRO INDUSTRIES CORP. + +OUI:0020AC* + ID_OUI_FROM_DATABASE=INTERFLEX DATENSYSTEME GMBH + +OUI:0020AD* + ID_OUI_FROM_DATABASE=LINQ SYSTEMS + +OUI:0020AE* + ID_OUI_FROM_DATABASE=ORNET DATA COMMUNICATION TECH. + +OUI:0020AF* + ID_OUI_FROM_DATABASE=3COM CORPORATION + +OUI:0020B0* + ID_OUI_FROM_DATABASE=GATEWAY DEVICES, INC. + +OUI:0020B1* + ID_OUI_FROM_DATABASE=COMTECH RESEARCH INC. + +OUI:0020B2* + ID_OUI_FROM_DATABASE=GKD Gesellschaft Fur Kommunikation Und Datentechnik + +OUI:0020B3* + ID_OUI_FROM_DATABASE=Tattile SRL + +OUI:0020B4* + ID_OUI_FROM_DATABASE=TERMA ELEKTRONIK AS + +OUI:0020B5* + ID_OUI_FROM_DATABASE=YASKAWA ELECTRIC CORPORATION + +OUI:0020B6* + ID_OUI_FROM_DATABASE=AGILE NETWORKS, INC. + +OUI:0020B7* + ID_OUI_FROM_DATABASE=NAMAQUA COMPUTERWARE + +OUI:0020B8* + ID_OUI_FROM_DATABASE=PRIME OPTION, INC. + +OUI:0020B9* + ID_OUI_FROM_DATABASE=METRICOM, INC. + +OUI:0020BA* + ID_OUI_FROM_DATABASE=CENTER FOR HIGH PERFORMANCE + +OUI:0020BB* + ID_OUI_FROM_DATABASE=ZAX CORPORATION + +OUI:0020BC* + ID_OUI_FROM_DATABASE=Long Reach Networks Pty Ltd + +OUI:0020BD* + ID_OUI_FROM_DATABASE=NIOBRARA R & D CORPORATION + +OUI:0020BE* + ID_OUI_FROM_DATABASE=LAN ACCESS CORP. + +OUI:0020BF* + ID_OUI_FROM_DATABASE=AEHR TEST SYSTEMS + +OUI:0020C0* + ID_OUI_FROM_DATABASE=PULSE ELECTRONICS, INC. + +OUI:0020C1* + ID_OUI_FROM_DATABASE=SAXA, Inc. + +OUI:0020C2* + ID_OUI_FROM_DATABASE=TEXAS MEMORY SYSTEMS, INC. + +OUI:0020C3* + ID_OUI_FROM_DATABASE=COUNTER SOLUTIONS LTD. + +OUI:0020C4* + ID_OUI_FROM_DATABASE=INET,INC. + +OUI:0020C5* + ID_OUI_FROM_DATABASE=EAGLE TECHNOLOGY + +OUI:0020C6* + ID_OUI_FROM_DATABASE=NECTEC + +OUI:0020C7* + ID_OUI_FROM_DATABASE=AKAI Professional M.I. Corp. + +OUI:0020C8* + ID_OUI_FROM_DATABASE=LARSCOM INCORPORATED + +OUI:0020C9* + ID_OUI_FROM_DATABASE=VICTRON BV + +OUI:0020CA* + ID_OUI_FROM_DATABASE=DIGITAL OCEAN + +OUI:0020CB* + ID_OUI_FROM_DATABASE=PRETEC ELECTRONICS CORP. + +OUI:0020CC* + ID_OUI_FROM_DATABASE=DIGITAL SERVICES, LTD. + +OUI:0020CD* + ID_OUI_FROM_DATABASE=HYBRID NETWORKS, INC. + +OUI:0020CE* + ID_OUI_FROM_DATABASE=LOGICAL DESIGN GROUP, INC. + +OUI:0020CF* + ID_OUI_FROM_DATABASE=TEST & MEASUREMENT SYSTEMS INC + +OUI:0020D0* + ID_OUI_FROM_DATABASE=VERSALYNX CORPORATION + +OUI:0020D1* + ID_OUI_FROM_DATABASE=MICROCOMPUTER SYSTEMS (M) SDN. + +OUI:0020D2* + ID_OUI_FROM_DATABASE=RAD DATA COMMUNICATIONS, LTD. + +OUI:0020D3* + ID_OUI_FROM_DATABASE=OST (OUEST STANDARD TELEMATIQU + +OUI:0020D4* + ID_OUI_FROM_DATABASE=CABLETRON - ZEITTNET INC. + +OUI:0020D5* + ID_OUI_FROM_DATABASE=VIPA GMBH + +OUI:0020D6* + ID_OUI_FROM_DATABASE=BREEZECOM + +OUI:0020D7* + ID_OUI_FROM_DATABASE=JAPAN MINICOMPUTER SYSTEMS CO., Ltd. + +OUI:0020D8* + ID_OUI_FROM_DATABASE=Nortel Networks + +OUI:0020D9* + ID_OUI_FROM_DATABASE=PANASONIC TECHNOLOGIES, INC./MIECO-US + +OUI:0020DA* + ID_OUI_FROM_DATABASE=Alcatel North America ESD + +OUI:0020DB* + ID_OUI_FROM_DATABASE=XNET TECHNOLOGY, INC. + +OUI:0020DC* + ID_OUI_FROM_DATABASE=DENSITRON TAIWAN LTD. + +OUI:0020DD* + ID_OUI_FROM_DATABASE=Cybertec Pty Ltd + +OUI:0020DE* + ID_OUI_FROM_DATABASE=JAPAN DIGITAL LABORAT'Y CO.LTD + +OUI:0020DF* + ID_OUI_FROM_DATABASE=KYOSAN ELECTRIC MFG. CO., LTD. + +OUI:0020E0* + ID_OUI_FROM_DATABASE=Actiontec Electronics, Inc. + +OUI:0020E1* + ID_OUI_FROM_DATABASE=ALAMAR ELECTRONICS + +OUI:0020E2* + ID_OUI_FROM_DATABASE=INFORMATION RESOURCE ENGINEERING + +OUI:0020E3* + ID_OUI_FROM_DATABASE=MCD KENCOM CORPORATION + +OUI:0020E4* + ID_OUI_FROM_DATABASE=HSING TECH ENTERPRISE CO., LTD + +OUI:0020E5* + ID_OUI_FROM_DATABASE=APEX DATA, INC. + +OUI:0020E6* + ID_OUI_FROM_DATABASE=LIDKOPING MACHINE TOOLS AB + +OUI:0020E7* + ID_OUI_FROM_DATABASE=B&W NUCLEAR SERVICE COMPANY + +OUI:0020E8* + ID_OUI_FROM_DATABASE=DATATREK CORPORATION + +OUI:0020E9* + ID_OUI_FROM_DATABASE=DANTEL + +OUI:0020EA* + ID_OUI_FROM_DATABASE=EFFICIENT NETWORKS, INC. + +OUI:0020EB* + ID_OUI_FROM_DATABASE=CINCINNATI MICROWAVE, INC. + +OUI:0020EC* + ID_OUI_FROM_DATABASE=TECHWARE SYSTEMS CORP. + +OUI:0020ED* + ID_OUI_FROM_DATABASE=GIGA-BYTE TECHNOLOGY CO., LTD. + +OUI:0020EE* + ID_OUI_FROM_DATABASE=GTECH CORPORATION + +OUI:0020EF* + ID_OUI_FROM_DATABASE=USC CORPORATION + +OUI:0020F0* + ID_OUI_FROM_DATABASE=UNIVERSAL MICROELECTRONICS CO. + +OUI:0020F1* + ID_OUI_FROM_DATABASE=ALTOS INDIA LIMITED + +OUI:0020F2* + ID_OUI_FROM_DATABASE=Oracle Corporation + +OUI:0020F3* + ID_OUI_FROM_DATABASE=RAYNET CORPORATION + +OUI:0020F4* + ID_OUI_FROM_DATABASE=SPECTRIX CORPORATION + +OUI:0020F5* + ID_OUI_FROM_DATABASE=PANDATEL AG + +OUI:0020F6* + ID_OUI_FROM_DATABASE=NET TEK AND KARLNET, INC. + +OUI:0020F7* + ID_OUI_FROM_DATABASE=CYBERDATA CORPORATION + +OUI:0020F8* + ID_OUI_FROM_DATABASE=CARRERA COMPUTERS, INC. + +OUI:0020F9* + ID_OUI_FROM_DATABASE=PARALINK NETWORKS, INC. + +OUI:0020FA* + ID_OUI_FROM_DATABASE=GDE SYSTEMS, INC. + +OUI:0020FB* + ID_OUI_FROM_DATABASE=OCTEL COMMUNICATIONS CORP. + +OUI:0020FC* + ID_OUI_FROM_DATABASE=MATROX + +OUI:0020FD* + ID_OUI_FROM_DATABASE=ITV TECHNOLOGIES, INC. + +OUI:0020FE* + ID_OUI_FROM_DATABASE=TOPWARE INC. / GRAND COMPUTER + +OUI:0020FF* + ID_OUI_FROM_DATABASE=SYMMETRICAL TECHNOLOGIES + +OUI:002100* + ID_OUI_FROM_DATABASE=GemTek Technology Co., Ltd. + +OUI:002101* + ID_OUI_FROM_DATABASE=Aplicaciones Electronicas Quasar (AEQ) + +OUI:002102* + ID_OUI_FROM_DATABASE=UpdateLogic Inc. + +OUI:002103* + ID_OUI_FROM_DATABASE=GHI Electronics, LLC + +OUI:002104* + ID_OUI_FROM_DATABASE=Gigaset Communications GmbH + +OUI:002105* + ID_OUI_FROM_DATABASE=Alcatel-Lucent + +OUI:002106* + ID_OUI_FROM_DATABASE=RIM Testing Services + +OUI:002107* + ID_OUI_FROM_DATABASE=Seowonintech Co Ltd. + +OUI:002108* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:002109* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:00210A* + ID_OUI_FROM_DATABASE=byd:sign Corporation + +OUI:00210B* + ID_OUI_FROM_DATABASE=GEMINI TRAZE RFID PVT. LTD. + +OUI:00210C* + ID_OUI_FROM_DATABASE=Cymtec Systems, Inc. + +OUI:00210D* + ID_OUI_FROM_DATABASE=SAMSIN INNOTEC + +OUI:00210E* + ID_OUI_FROM_DATABASE=Orpak Systems L.T.D. + +OUI:00210F* + ID_OUI_FROM_DATABASE=Cernium Corp + +OUI:002110* + ID_OUI_FROM_DATABASE=Clearbox Systems + +OUI:002111* + ID_OUI_FROM_DATABASE=Uniphone Inc. + +OUI:002112* + ID_OUI_FROM_DATABASE=WISCOM SYSTEM CO.,LTD + +OUI:002113* + ID_OUI_FROM_DATABASE=Padtec S/A + +OUI:002114* + ID_OUI_FROM_DATABASE=Hylab Technology Inc. + +OUI:002115* + ID_OUI_FROM_DATABASE=PHYWE Systeme GmbH & Co. KG + +OUI:002116* + ID_OUI_FROM_DATABASE=Transcon Electronic Systems, spol. s r. o. + +OUI:002117* + ID_OUI_FROM_DATABASE=Tellord + +OUI:002118* + ID_OUI_FROM_DATABASE=Athena Tech, Inc. + +OUI:002119* + ID_OUI_FROM_DATABASE=Samsung Electro-Mechanics + +OUI:00211A* + ID_OUI_FROM_DATABASE=LInTech Corporation + +OUI:00211B* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00211C* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00211D* + ID_OUI_FROM_DATABASE=Dataline AB + +OUI:00211E* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:00211F* + ID_OUI_FROM_DATABASE=SHINSUNG DELTATECH CO.,LTD. + +OUI:002120* + ID_OUI_FROM_DATABASE=Sequel Technologies + +OUI:002121* + ID_OUI_FROM_DATABASE=VRmagic GmbH + +OUI:002122* + ID_OUI_FROM_DATABASE=Chip-pro Ltd. + +OUI:002123* + ID_OUI_FROM_DATABASE=Aerosat Avionics + +OUI:002124* + ID_OUI_FROM_DATABASE=Optos Plc + +OUI:002125* + ID_OUI_FROM_DATABASE=KUK JE TONG SHIN Co.,LTD + +OUI:002126* + ID_OUI_FROM_DATABASE=Shenzhen Torch Equipment Co., Ltd. + +OUI:002127* + ID_OUI_FROM_DATABASE=TP-LINK Technology Co., Ltd. + +OUI:002128* + ID_OUI_FROM_DATABASE=Oracle Corporation + +OUI:002129* + ID_OUI_FROM_DATABASE=Cisco-Linksys, LLC + +OUI:00212A* + ID_OUI_FROM_DATABASE=Audiovox Corporation + +OUI:00212B* + ID_OUI_FROM_DATABASE=MSA Auer + +OUI:00212C* + ID_OUI_FROM_DATABASE=SemIndia System Private Limited + +OUI:00212D* + ID_OUI_FROM_DATABASE=SCIMOLEX CORPORATION + +OUI:00212E* + ID_OUI_FROM_DATABASE=dresden-elektronik + +OUI:00212F* + ID_OUI_FROM_DATABASE=Phoebe Micro Inc. + +OUI:002130* + ID_OUI_FROM_DATABASE=Keico Hightech Inc. + +OUI:002131* + ID_OUI_FROM_DATABASE=Blynke Inc. + +OUI:002132* + ID_OUI_FROM_DATABASE=Masterclock, Inc. + +OUI:002133* + ID_OUI_FROM_DATABASE=Building B, Inc + +OUI:002134* + ID_OUI_FROM_DATABASE=Brandywine Communications + +OUI:002135* + ID_OUI_FROM_DATABASE=ALCATEL-LUCENT + +OUI:002136* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:002137* + ID_OUI_FROM_DATABASE=Bay Controls, LLC + +OUI:002138* + ID_OUI_FROM_DATABASE=Cepheid + +OUI:002139* + ID_OUI_FROM_DATABASE=Escherlogic Inc. + +OUI:00213A* + ID_OUI_FROM_DATABASE=Winchester Systems Inc. + +OUI:00213B* + ID_OUI_FROM_DATABASE=Berkshire Products, Inc + +OUI:00213C* + ID_OUI_FROM_DATABASE=AliphCom + +OUI:00213D* + ID_OUI_FROM_DATABASE=Cermetek Microelectronics, Inc. + +OUI:00213E* + ID_OUI_FROM_DATABASE=TomTom + +OUI:00213F* + ID_OUI_FROM_DATABASE=A-Team Technology Ltd. + +OUI:002140* + ID_OUI_FROM_DATABASE=EN Technologies Inc. + +OUI:002141* + ID_OUI_FROM_DATABASE=RADLIVE + +OUI:002142* + ID_OUI_FROM_DATABASE=Advanced Control Systems doo + +OUI:002143* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:002144* + ID_OUI_FROM_DATABASE=SS Telecoms + +OUI:002145* + ID_OUI_FROM_DATABASE=Semptian Technologies Ltd. + +OUI:002146* + ID_OUI_FROM_DATABASE=SCI Technology + +OUI:002147* + ID_OUI_FROM_DATABASE=Nintendo Co., Ltd. + +OUI:002148* + ID_OUI_FROM_DATABASE=Kaco Solar Korea + +OUI:002149* + ID_OUI_FROM_DATABASE=China Daheng Group ,Inc. + +OUI:00214A* + ID_OUI_FROM_DATABASE=Pixel Velocity, Inc + +OUI:00214B* + ID_OUI_FROM_DATABASE=Shenzhen HAMP Science & Technology Co.,Ltd + +OUI:00214C* + ID_OUI_FROM_DATABASE=SAMSUNG ELECTRONICS CO., LTD. + +OUI:00214D* + ID_OUI_FROM_DATABASE=Guangzhou Skytone Transmission Technology Com. Ltd. + +OUI:00214E* + ID_OUI_FROM_DATABASE=GS Yuasa Power Supply Ltd. + +OUI:00214F* + ID_OUI_FROM_DATABASE=ALPS Electric Co., Ltd + +OUI:002150* + ID_OUI_FROM_DATABASE=EYEVIEW ELECTRONICS + +OUI:002151* + ID_OUI_FROM_DATABASE=Millinet Co., Ltd. + +OUI:002152* + ID_OUI_FROM_DATABASE=General Satellite Research & Development Limited + +OUI:002153* + ID_OUI_FROM_DATABASE=SeaMicro Inc. + +OUI:002154* + ID_OUI_FROM_DATABASE=D-TACQ Solutions Ltd + +OUI:002155* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:002156* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:002157* + ID_OUI_FROM_DATABASE=National Datacast, Inc. + +OUI:002158* + ID_OUI_FROM_DATABASE=Style Flying Technology Co. + +OUI:002159* + ID_OUI_FROM_DATABASE=Juniper Networks + +OUI:00215A* + ID_OUI_FROM_DATABASE=Hewlett-Packard Company + +OUI:00215B* + ID_OUI_FROM_DATABASE=Inotive + +OUI:00215C* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:00215D* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:00215E* + ID_OUI_FROM_DATABASE=IBM Corp + +OUI:00215F* + ID_OUI_FROM_DATABASE=IHSE GmbH + +OUI:002160* + ID_OUI_FROM_DATABASE=Hidea Solutions Co. Ltd. + +OUI:002161* + ID_OUI_FROM_DATABASE=Yournet Inc. + +OUI:002162* + ID_OUI_FROM_DATABASE=Nortel + +OUI:002163* + ID_OUI_FROM_DATABASE=ASKEY COMPUTER CORP + +OUI:002164* + ID_OUI_FROM_DATABASE=Special Design Bureau for Seismic Instrumentation + +OUI:002165* + ID_OUI_FROM_DATABASE=Presstek Inc. + +OUI:002166* + ID_OUI_FROM_DATABASE=NovAtel Inc. + +OUI:002167* + ID_OUI_FROM_DATABASE=HWA JIN T&I Corp. + +OUI:002168* + ID_OUI_FROM_DATABASE=iVeia, LLC + +OUI:002169* + ID_OUI_FROM_DATABASE=Prologix, LLC. + +OUI:00216A* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:00216B* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:00216C* + ID_OUI_FROM_DATABASE=ODVA + +OUI:00216D* + ID_OUI_FROM_DATABASE=Soltech Co., Ltd. + +OUI:00216E* + ID_OUI_FROM_DATABASE=Function ATI (Huizhou) Telecommunications Co., Ltd. + +OUI:00216F* + ID_OUI_FROM_DATABASE=SymCom, Inc. + +OUI:002170* + ID_OUI_FROM_DATABASE=Dell Inc + +OUI:002171* + ID_OUI_FROM_DATABASE=Wesung TNC Co., Ltd. + +OUI:002172* + ID_OUI_FROM_DATABASE=Seoultek Valley + +OUI:002173* + ID_OUI_FROM_DATABASE=Ion Torrent Systems, Inc. + +OUI:002174* + ID_OUI_FROM_DATABASE=AvaLAN Wireless + +OUI:002175* + ID_OUI_FROM_DATABASE=Pacific Satellite International Ltd. + +OUI:002176* + ID_OUI_FROM_DATABASE=YMax Telecom Ltd. + +OUI:002177* + ID_OUI_FROM_DATABASE=W. L. Gore & Associates + +OUI:002178* + ID_OUI_FROM_DATABASE=Matuschek Messtechnik GmbH + +OUI:002179* + ID_OUI_FROM_DATABASE=IOGEAR, Inc. + +OUI:00217A* + ID_OUI_FROM_DATABASE=Sejin Electron, Inc. + +OUI:00217B* + ID_OUI_FROM_DATABASE=Bastec AB + +OUI:00217C* + ID_OUI_FROM_DATABASE=2Wire + +OUI:00217D* + ID_OUI_FROM_DATABASE=PYXIS S.R.L. + +OUI:00217E* + ID_OUI_FROM_DATABASE=Telit Communication s.p.a + +OUI:00217F* + ID_OUI_FROM_DATABASE=Intraco Technology Pte Ltd + +OUI:002180* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:002181* + ID_OUI_FROM_DATABASE=Si2 Microsystems Limited + +OUI:002182* + ID_OUI_FROM_DATABASE=SandLinks Systems, Ltd. + +OUI:002183* + ID_OUI_FROM_DATABASE=VATECH HYDRO + +OUI:002184* + ID_OUI_FROM_DATABASE=POWERSOFT SRL + +OUI:002185* + ID_OUI_FROM_DATABASE=MICRO-STAR INT'L CO.,LTD. + +OUI:002186* + ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co., Ltd + +OUI:002187* + ID_OUI_FROM_DATABASE=Imacs GmbH + +OUI:002188* + ID_OUI_FROM_DATABASE=EMC Corporation + +OUI:002189* + ID_OUI_FROM_DATABASE=AppTech, Inc. + +OUI:00218A* + ID_OUI_FROM_DATABASE=Electronic Design and Manufacturing Company + +OUI:00218B* + ID_OUI_FROM_DATABASE=Wescon Technology, Inc. + +OUI:00218C* + ID_OUI_FROM_DATABASE=TopControl GMBH + +OUI:00218D* + ID_OUI_FROM_DATABASE=AP Router Ind. Eletronica LTDA + +OUI:00218E* + ID_OUI_FROM_DATABASE=MEKICS CO., LTD. + +OUI:00218F* + ID_OUI_FROM_DATABASE=Avantgarde Acoustic Lautsprechersysteme GmbH + +OUI:002190* + ID_OUI_FROM_DATABASE=Goliath Solutions + +OUI:002191* + ID_OUI_FROM_DATABASE=D-Link Corporation + +OUI:002192* + ID_OUI_FROM_DATABASE=Baoding Galaxy Electronic Technology Co.,Ltd + +OUI:002193* + ID_OUI_FROM_DATABASE=Videofon MV + +OUI:002194* + ID_OUI_FROM_DATABASE=Ping Communication + +OUI:002195* + ID_OUI_FROM_DATABASE=GWD Media Limited + +OUI:002196* + ID_OUI_FROM_DATABASE=Telsey S.p.A. + +OUI:002197* + ID_OUI_FROM_DATABASE=ELITEGROUP COMPUTER SYSTEM + +OUI:002198* + ID_OUI_FROM_DATABASE=Thai Radio Co, LTD + +OUI:002199* + ID_OUI_FROM_DATABASE=Vacon Plc + +OUI:00219A* + ID_OUI_FROM_DATABASE=Cambridge Visual Networks Ltd + +OUI:00219B* + ID_OUI_FROM_DATABASE=Dell Inc + +OUI:00219C* + ID_OUI_FROM_DATABASE=Honeywld Technology Corp. + +OUI:00219D* + ID_OUI_FROM_DATABASE=Adesys BV + +OUI:00219E* + ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications + +OUI:00219F* + ID_OUI_FROM_DATABASE=SATEL OY + +OUI:0021A0* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0021A1* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0021A2* + ID_OUI_FROM_DATABASE=EKE-Electronics Ltd. + +OUI:0021A3* + ID_OUI_FROM_DATABASE=Micromint + +OUI:0021A4* + ID_OUI_FROM_DATABASE=Dbii Networks + +OUI:0021A5* + ID_OUI_FROM_DATABASE=ERLPhase Power Technologies Ltd. + +OUI:0021A6* + ID_OUI_FROM_DATABASE=Videotec Spa + +OUI:0021A7* + ID_OUI_FROM_DATABASE=Hantle System Co., Ltd. + +OUI:0021A8* + ID_OUI_FROM_DATABASE=Telephonics Corporation + +OUI:0021A9* + ID_OUI_FROM_DATABASE=Mobilink Telecom Co.,Ltd + +OUI:0021AA* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:0021AB* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:0021AC* + ID_OUI_FROM_DATABASE=Infrared Integrated Systems Ltd + +OUI:0021AD* + ID_OUI_FROM_DATABASE=Nordic ID Oy + +OUI:0021AE* + ID_OUI_FROM_DATABASE=ALCATEL-LUCENT FRANCE - WTD + +OUI:0021AF* + ID_OUI_FROM_DATABASE=Radio Frequency Systems + +OUI:0021B0* + ID_OUI_FROM_DATABASE=Tyco Telecommunications + +OUI:0021B1* + ID_OUI_FROM_DATABASE=DIGITAL SOLUTIONS LTD + +OUI:0021B2* + ID_OUI_FROM_DATABASE=Fiberblaze A/S + +OUI:0021B3* + ID_OUI_FROM_DATABASE=Ross Controls + +OUI:0021B4* + ID_OUI_FROM_DATABASE=APRO MEDIA CO., LTD + +OUI:0021B5* + ID_OUI_FROM_DATABASE=Vyro Games Limited + +OUI:0021B6* + ID_OUI_FROM_DATABASE=Triacta Power Technologies Inc. + +OUI:0021B7* + ID_OUI_FROM_DATABASE=Lexmark International Inc. + +OUI:0021B8* + ID_OUI_FROM_DATABASE=Inphi Corporation + +OUI:0021B9* + ID_OUI_FROM_DATABASE=Universal Devices Inc. + +OUI:0021BA* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:0021BB* + ID_OUI_FROM_DATABASE=Riken Keiki Co., Ltd. + +OUI:0021BC* + ID_OUI_FROM_DATABASE=ZALA COMPUTER + +OUI:0021BD* + ID_OUI_FROM_DATABASE=Nintendo Co., Ltd. + +OUI:0021BE* + ID_OUI_FROM_DATABASE=Cisco, Service Provider Video Technology Group + +OUI:0021BF* + ID_OUI_FROM_DATABASE=Hitachi High-Tech Control Systems Corporation + +OUI:0021C0* + ID_OUI_FROM_DATABASE=Mobile Appliance, Inc. + +OUI:0021C1* + ID_OUI_FROM_DATABASE=ABB Oy / Distribution Automation + +OUI:0021C2* + ID_OUI_FROM_DATABASE=GL Communications Inc + +OUI:0021C3* + ID_OUI_FROM_DATABASE=CORNELL Communications, Inc. + +OUI:0021C4* + ID_OUI_FROM_DATABASE=Consilium AB + +OUI:0021C5* + ID_OUI_FROM_DATABASE=3DSP Corp + +OUI:0021C6* + ID_OUI_FROM_DATABASE=CSJ Global, Inc. + +OUI:0021C7* + ID_OUI_FROM_DATABASE=Russound + +OUI:0021C8* + ID_OUI_FROM_DATABASE=LOHUIS Networks + +OUI:0021C9* + ID_OUI_FROM_DATABASE=Wavecom Asia Pacific Limited + +OUI:0021CA* + ID_OUI_FROM_DATABASE=ART System Co., Ltd. + +OUI:0021CB* + ID_OUI_FROM_DATABASE=SMS TECNOLOGIA ELETRONICA LTDA + +OUI:0021CC* + ID_OUI_FROM_DATABASE=Flextronics International + +OUI:0021CD* + ID_OUI_FROM_DATABASE=LiveTV + +OUI:0021CE* + ID_OUI_FROM_DATABASE=NTC-Metrotek + +OUI:0021CF* + ID_OUI_FROM_DATABASE=The Crypto Group + +OUI:0021D0* + ID_OUI_FROM_DATABASE=Global Display Solutions Spa + +OUI:0021D1* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:0021D2* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:0021D3* + ID_OUI_FROM_DATABASE=BOCOM SECURITY(ASIA PACIFIC) LIMITED + +OUI:0021D4* + ID_OUI_FROM_DATABASE=Vollmer Werke GmbH + +OUI:0021D5* + ID_OUI_FROM_DATABASE=X2E GmbH + +OUI:0021D6* + ID_OUI_FROM_DATABASE=LXI Consortium + +OUI:0021D7* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0021D8* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0021D9* + ID_OUI_FROM_DATABASE=SEKONIC CORPORATION + +OUI:0021DA* + ID_OUI_FROM_DATABASE=Automation Products Group Inc. + +OUI:0021DB* + ID_OUI_FROM_DATABASE=Santachi Video Technology (Shenzhen) Co., Ltd. + +OUI:0021DC* + ID_OUI_FROM_DATABASE=TECNOALARM S.r.l. + +OUI:0021DD* + ID_OUI_FROM_DATABASE=Northstar Systems Corp + +OUI:0021DE* + ID_OUI_FROM_DATABASE=Firepro Wireless + +OUI:0021DF* + ID_OUI_FROM_DATABASE=Martin Christ GmbH + +OUI:0021E0* + ID_OUI_FROM_DATABASE=CommAgility Ltd + +OUI:0021E1* + ID_OUI_FROM_DATABASE=Nortel Networks + +OUI:0021E2* + ID_OUI_FROM_DATABASE=Creative Electronic GmbH + +OUI:0021E3* + ID_OUI_FROM_DATABASE=SerialTek LLC + +OUI:0021E4* + ID_OUI_FROM_DATABASE=I-WIN + +OUI:0021E5* + ID_OUI_FROM_DATABASE=Display Solution AG + +OUI:0021E6* + ID_OUI_FROM_DATABASE=Starlight Video Limited + +OUI:0021E7* + ID_OUI_FROM_DATABASE=Informatics Services Corporation + +OUI:0021E8* + ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd. + +OUI:0021E9* + ID_OUI_FROM_DATABASE=Apple, Inc + +OUI:0021EA* + ID_OUI_FROM_DATABASE=Bystronic Laser AG + +OUI:0021EB* + ID_OUI_FROM_DATABASE=ESP SYSTEMS, LLC + +OUI:0021EC* + ID_OUI_FROM_DATABASE=Solutronic GmbH + +OUI:0021ED* + ID_OUI_FROM_DATABASE=Telegesis + +OUI:0021EE* + ID_OUI_FROM_DATABASE=Full Spectrum Inc. + +OUI:0021EF* + ID_OUI_FROM_DATABASE=Kapsys + +OUI:0021F0* + ID_OUI_FROM_DATABASE=EW3 Technologies LLC + +OUI:0021F1* + ID_OUI_FROM_DATABASE=Tutus Data AB + +OUI:0021F2* + ID_OUI_FROM_DATABASE=EASY3CALL Technology Limited + +OUI:0021F3* + ID_OUI_FROM_DATABASE=Si14 SpA + +OUI:0021F4* + ID_OUI_FROM_DATABASE=INRange Systems, Inc + +OUI:0021F5* + ID_OUI_FROM_DATABASE=Western Engravers Supply, Inc. + +OUI:0021F6* + ID_OUI_FROM_DATABASE=Oracle Corporation + +OUI:0021F7* + ID_OUI_FROM_DATABASE=ProCurve Networking by HP + +OUI:0021F8* + ID_OUI_FROM_DATABASE=Enseo, Inc. + +OUI:0021F9* + ID_OUI_FROM_DATABASE=WIRECOM Technologies + +OUI:0021FA* + ID_OUI_FROM_DATABASE=A4SP Technologies Ltd. + +OUI:0021FB* + ID_OUI_FROM_DATABASE=LG Electronics + +OUI:0021FC* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:0021FD* + ID_OUI_FROM_DATABASE=DSTA S.L. + +OUI:0021FE* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:0021FF* + ID_OUI_FROM_DATABASE=Cyfrowy Polsat SA + +OUI:002200* + ID_OUI_FROM_DATABASE=IBM Corp + +OUI:002201* + ID_OUI_FROM_DATABASE=Aksys Networks Inc + +OUI:002202* + ID_OUI_FROM_DATABASE=Excito Elektronik i Skåne AB + +OUI:002203* + ID_OUI_FROM_DATABASE=Glensound Electronics Ltd + +OUI:002204* + ID_OUI_FROM_DATABASE=KORATEK + +OUI:002205* + ID_OUI_FROM_DATABASE=WeLink Solutions, Inc. + +OUI:002206* + ID_OUI_FROM_DATABASE=Cyberdyne Inc. + +OUI:002207* + ID_OUI_FROM_DATABASE=Inteno Broadband Technology AB + +OUI:002208* + ID_OUI_FROM_DATABASE=Certicom Corp + +OUI:002209* + ID_OUI_FROM_DATABASE=Omron Healthcare Co., Ltd + +OUI:00220A* + ID_OUI_FROM_DATABASE=OnLive, Inc + +OUI:00220B* + ID_OUI_FROM_DATABASE=National Source Coding Center + +OUI:00220C* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00220D* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00220E* + ID_OUI_FROM_DATABASE=Indigo Security Co., Ltd. + +OUI:00220F* + ID_OUI_FROM_DATABASE=MoCA (Multimedia over Coax Alliance) + +OUI:002210* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:002211* + ID_OUI_FROM_DATABASE=Rohati Systems + +OUI:002212* + ID_OUI_FROM_DATABASE=CAI Networks, Inc. + +OUI:002213* + ID_OUI_FROM_DATABASE=PCI CORPORATION + +OUI:002214* + ID_OUI_FROM_DATABASE=RINNAI KOREA + +OUI:002215* + ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. + +OUI:002216* + ID_OUI_FROM_DATABASE=SHIBAURA VENDING MACHINE CORPORATION + +OUI:002217* + ID_OUI_FROM_DATABASE=Neat Electronics + +OUI:002218* + ID_OUI_FROM_DATABASE=Verivue Inc. + +OUI:002219* + ID_OUI_FROM_DATABASE=Dell Inc + +OUI:00221A* + ID_OUI_FROM_DATABASE=Audio Precision + +OUI:00221B* + ID_OUI_FROM_DATABASE=Morega Systems + +OUI:00221D* + ID_OUI_FROM_DATABASE=Freegene Technology LTD + +OUI:00221E* + ID_OUI_FROM_DATABASE=Media Devices Co., Ltd. + +OUI:00221F* + ID_OUI_FROM_DATABASE=eSang Technologies Co., Ltd. + +OUI:002220* + ID_OUI_FROM_DATABASE=Mitac Technology Corp + +OUI:002221* + ID_OUI_FROM_DATABASE=ITOH DENKI CO,LTD. + +OUI:002222* + ID_OUI_FROM_DATABASE=Schaffner Deutschland GmbH + +OUI:002223* + ID_OUI_FROM_DATABASE=TimeKeeping Systems, Inc. + +OUI:002224* + ID_OUI_FROM_DATABASE=Good Will Instrument Co., Ltd. + +OUI:002225* + ID_OUI_FROM_DATABASE=Thales Avionics Ltd + +OUI:002226* + ID_OUI_FROM_DATABASE=Avaak, Inc. + +OUI:002227* + ID_OUI_FROM_DATABASE=uv-electronic GmbH + +OUI:002228* + ID_OUI_FROM_DATABASE=Breeze Innovations Ltd. + +OUI:002229* + ID_OUI_FROM_DATABASE=Compumedics Ltd + +OUI:00222A* + ID_OUI_FROM_DATABASE=SoundEar A/S + +OUI:00222B* + ID_OUI_FROM_DATABASE=Nucomm, Inc. + +OUI:00222C* + ID_OUI_FROM_DATABASE=Ceton Corp + +OUI:00222D* + ID_OUI_FROM_DATABASE=SMC Networks Inc. + +OUI:00222E* + ID_OUI_FROM_DATABASE=maintech GmbH + +OUI:00222F* + ID_OUI_FROM_DATABASE=Open Grid Computing, Inc. + +OUI:002230* + ID_OUI_FROM_DATABASE=FutureLogic Inc. + +OUI:002231* + ID_OUI_FROM_DATABASE=SMT&C Co., Ltd. + +OUI:002232* + ID_OUI_FROM_DATABASE=Design Design Technology Ltd + +OUI:002233* + ID_OUI_FROM_DATABASE=ADB Broadband Italia + +OUI:002234* + ID_OUI_FROM_DATABASE=Corventis Inc. + +OUI:002235* + ID_OUI_FROM_DATABASE=Strukton Systems bv + +OUI:002236* + ID_OUI_FROM_DATABASE=VECTOR SP. Z O.O. + +OUI:002237* + ID_OUI_FROM_DATABASE=Shinhint Group + +OUI:002238* + ID_OUI_FROM_DATABASE=LOGIPLUS + +OUI:002239* + ID_OUI_FROM_DATABASE=Indiana Life Sciences Incorporated + +OUI:00223A* + ID_OUI_FROM_DATABASE=Scientific Atlanta, Cisco SPVT Group + +OUI:00223B* + ID_OUI_FROM_DATABASE=Communication Networks, LLC + +OUI:00223C* + ID_OUI_FROM_DATABASE=RATIO Entwicklungen GmbH + +OUI:00223D* + ID_OUI_FROM_DATABASE=JumpGen Systems, LLC + +OUI:00223E* + ID_OUI_FROM_DATABASE=IRTrans GmbH + +OUI:00223F* + ID_OUI_FROM_DATABASE=Netgear Inc. + +OUI:002240* + ID_OUI_FROM_DATABASE=Universal Telecom S/A + +OUI:002241* + ID_OUI_FROM_DATABASE=Apple, Inc + +OUI:002242* + ID_OUI_FROM_DATABASE=Alacron Inc. + +OUI:002243* + ID_OUI_FROM_DATABASE=AzureWave Technologies, Inc. + +OUI:002244* + ID_OUI_FROM_DATABASE=Chengdu Linkon Communications Device Co., Ltd + +OUI:002245* + ID_OUI_FROM_DATABASE=Leine & Linde AB + +OUI:002246* + ID_OUI_FROM_DATABASE=Evoc Intelligent Technology Co.,Ltd. + +OUI:002247* + ID_OUI_FROM_DATABASE=DAC ENGINEERING CO., LTD. + +OUI:002248* + ID_OUI_FROM_DATABASE=Microsoft Corporation + +OUI:002249* + ID_OUI_FROM_DATABASE=HOME MULTIENERGY SL + +OUI:00224A* + ID_OUI_FROM_DATABASE=RAYLASE AG + +OUI:00224B* + ID_OUI_FROM_DATABASE=AIRTECH TECHNOLOGIES, INC. + +OUI:00224C* + ID_OUI_FROM_DATABASE=Nintendo Co., Ltd. + +OUI:00224D* + ID_OUI_FROM_DATABASE=MITAC INTERNATIONAL CORP. + +OUI:00224E* + ID_OUI_FROM_DATABASE=SEEnergy Corp. + +OUI:00224F* + ID_OUI_FROM_DATABASE=Byzoro Networks Ltd. + +OUI:002250* + ID_OUI_FROM_DATABASE=Point Six Wireless, LLC + +OUI:002251* + ID_OUI_FROM_DATABASE=Lumasense Technologies + +OUI:002252* + ID_OUI_FROM_DATABASE=ZOLL Lifecor Corporation + +OUI:002253* + ID_OUI_FROM_DATABASE=Entorian Technologies + +OUI:002254* + ID_OUI_FROM_DATABASE=Bigelow Aerospace + +OUI:002255* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:002256* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:002257* + ID_OUI_FROM_DATABASE=3Com Europe Ltd + +OUI:002258* + ID_OUI_FROM_DATABASE=Taiyo Yuden Co., Ltd. + +OUI:002259* + ID_OUI_FROM_DATABASE=Guangzhou New Postcom Equipment Co.,Ltd. + +OUI:00225A* + ID_OUI_FROM_DATABASE=Garde Security AB + +OUI:00225B* + ID_OUI_FROM_DATABASE=Teradici Corporation + +OUI:00225C* + ID_OUI_FROM_DATABASE=Multimedia & Communication Technology + +OUI:00225D* + ID_OUI_FROM_DATABASE=Digicable Network India Pvt. Ltd. + +OUI:00225E* + ID_OUI_FROM_DATABASE=Uwin Technologies Co.,LTD + +OUI:00225F* + ID_OUI_FROM_DATABASE=Liteon Technology Corporation + +OUI:002260* + ID_OUI_FROM_DATABASE=AFREEY Inc. + +OUI:002261* + ID_OUI_FROM_DATABASE=Frontier Silicon Ltd + +OUI:002262* + ID_OUI_FROM_DATABASE=BEP Marine + +OUI:002263* + ID_OUI_FROM_DATABASE=Koos Technical Services, Inc. + +OUI:002264* + ID_OUI_FROM_DATABASE=Hewlett-Packard Company + +OUI:002265* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:002266* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:002267* + ID_OUI_FROM_DATABASE=Nortel Networks + +OUI:002268* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co., Ltd. + +OUI:002269* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co., Ltd. + +OUI:00226A* + ID_OUI_FROM_DATABASE=Honeywell + +OUI:00226B* + ID_OUI_FROM_DATABASE=Cisco-Linksys, LLC + +OUI:00226C* + ID_OUI_FROM_DATABASE=LinkSprite Technologies, Inc. + +OUI:00226D* + ID_OUI_FROM_DATABASE=Shenzhen GIEC Electronics Co., Ltd. + +OUI:00226E* + ID_OUI_FROM_DATABASE=Gowell Electronic Limited + +OUI:00226F* + ID_OUI_FROM_DATABASE=3onedata Technology Co. Ltd. + +OUI:002270* + ID_OUI_FROM_DATABASE=ABK North America, LLC + +OUI:002271* + ID_OUI_FROM_DATABASE=Jäger Computergesteuerte Meßtechnik GmbH. + +OUI:002272* + ID_OUI_FROM_DATABASE=American Micro-Fuel Device Corp. + +OUI:002273* + ID_OUI_FROM_DATABASE=Techway + +OUI:002274* + ID_OUI_FROM_DATABASE=FamilyPhone AB + +OUI:002275* + ID_OUI_FROM_DATABASE=Belkin International, Inc. + +OUI:002276* + ID_OUI_FROM_DATABASE=Triple EYE B.V. + +OUI:002277* + ID_OUI_FROM_DATABASE=NEC Australia Pty Ltd + +OUI:002278* + ID_OUI_FROM_DATABASE=Shenzhen Tongfang Multimedia Technology Co.,Ltd. + +OUI:002279* + ID_OUI_FROM_DATABASE=Nippon Conlux Co., Ltd. + +OUI:00227A* + ID_OUI_FROM_DATABASE=Telecom Design + +OUI:00227B* + ID_OUI_FROM_DATABASE=Apogee Labs, Inc. + +OUI:00227C* + ID_OUI_FROM_DATABASE=Woori SMT Co.,ltd + +OUI:00227D* + ID_OUI_FROM_DATABASE=YE DATA INC. + +OUI:00227E* + ID_OUI_FROM_DATABASE=Chengdu 30Kaitian Communication Industry Co.Ltd + +OUI:00227F* + ID_OUI_FROM_DATABASE=Ruckus Wireless + +OUI:002280* + ID_OUI_FROM_DATABASE=A2B Electronics AB + +OUI:002281* + ID_OUI_FROM_DATABASE=Daintree Networks Inc + +OUI:002282* + ID_OUI_FROM_DATABASE=8086 Limited + +OUI:002283* + ID_OUI_FROM_DATABASE=Juniper Networks + +OUI:002284* + ID_OUI_FROM_DATABASE=DESAY A&V SCIENCE AND TECHNOLOGY CO.,LTD + +OUI:002285* + ID_OUI_FROM_DATABASE=NOMUS COMM SYSTEMS + +OUI:002286* + ID_OUI_FROM_DATABASE=ASTRON + +OUI:002287* + ID_OUI_FROM_DATABASE=Titan Wireless LLC + +OUI:002288* + ID_OUI_FROM_DATABASE=Sagrad, Inc. + +OUI:002289* + ID_OUI_FROM_DATABASE=Optosecurity Inc. + +OUI:00228A* + ID_OUI_FROM_DATABASE=Teratronik elektronische systeme gmbh + +OUI:00228B* + ID_OUI_FROM_DATABASE=Kensington Computer Products Group + +OUI:00228C* + ID_OUI_FROM_DATABASE=Photon Europe GmbH + +OUI:00228D* + ID_OUI_FROM_DATABASE=GBS Laboratories LLC + +OUI:00228E* + ID_OUI_FROM_DATABASE=TV-NUMERIC + +OUI:00228F* + ID_OUI_FROM_DATABASE=CNRS + +OUI:002290* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:002291* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:002292* + ID_OUI_FROM_DATABASE=Cinetal + +OUI:002293* + ID_OUI_FROM_DATABASE=ZTE Corporation + +OUI:002294* + ID_OUI_FROM_DATABASE=Kyocera Corporation + +OUI:002295* + ID_OUI_FROM_DATABASE=SGM Technology for lighting spa + +OUI:002296* + ID_OUI_FROM_DATABASE=LinoWave Corporation + +OUI:002297* + ID_OUI_FROM_DATABASE=XMOS Semiconductor + +OUI:002298* + ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications + +OUI:002299* + ID_OUI_FROM_DATABASE=SeaMicro Inc. + +OUI:00229A* + ID_OUI_FROM_DATABASE=Lastar, Inc. + +OUI:00229B* + ID_OUI_FROM_DATABASE=AverLogic Technologies, Inc. + +OUI:00229C* + ID_OUI_FROM_DATABASE=Verismo Networks Inc + +OUI:00229D* + ID_OUI_FROM_DATABASE=PYUNG-HWA IND.CO.,LTD + +OUI:00229E* + ID_OUI_FROM_DATABASE=Social Aid Research Co., Ltd. + +OUI:00229F* + ID_OUI_FROM_DATABASE=Sensys Traffic AB + +OUI:0022A0* + ID_OUI_FROM_DATABASE=Delphi Corporation + +OUI:0022A1* + ID_OUI_FROM_DATABASE=Huawei Symantec Technologies Co.,Ltd. + +OUI:0022A2* + ID_OUI_FROM_DATABASE=Xtramus Technologies + +OUI:0022A3* + ID_OUI_FROM_DATABASE=California Eastern Laboratories + +OUI:0022A4* + ID_OUI_FROM_DATABASE=2Wire + +OUI:0022A5* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:0022A6* + ID_OUI_FROM_DATABASE=Sony Computer Entertainment America + +OUI:0022A7* + ID_OUI_FROM_DATABASE=Tyco Electronics AMP GmbH + +OUI:0022A8* + ID_OUI_FROM_DATABASE=Ouman Finland Oy + +OUI:0022A9* + ID_OUI_FROM_DATABASE=LG Electronics Inc + +OUI:0022AA* + ID_OUI_FROM_DATABASE=Nintendo Co., Ltd. + +OUI:0022AB* + ID_OUI_FROM_DATABASE=Shenzhen Turbosight Technology Ltd + +OUI:0022AC* + ID_OUI_FROM_DATABASE=Hangzhou Siyuan Tech. Co., Ltd + +OUI:0022AD* + ID_OUI_FROM_DATABASE=TELESIS TECHNOLOGIES, INC. + +OUI:0022AE* + ID_OUI_FROM_DATABASE=Mattel Inc. + +OUI:0022AF* + ID_OUI_FROM_DATABASE=Safety Vision + +OUI:0022B0* + ID_OUI_FROM_DATABASE=D-Link Corporation + +OUI:0022B1* + ID_OUI_FROM_DATABASE=Elbit Systems + +OUI:0022B2* + ID_OUI_FROM_DATABASE=4RF Communications Ltd + +OUI:0022B3* + ID_OUI_FROM_DATABASE=Sei S.p.A. + +OUI:0022B4* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:0022B5* + ID_OUI_FROM_DATABASE=NOVITA + +OUI:0022B6* + ID_OUI_FROM_DATABASE=Superflow Technologies Group + +OUI:0022B7* + ID_OUI_FROM_DATABASE=GSS Grundig SAT-Systems GmbH + +OUI:0022B8* + ID_OUI_FROM_DATABASE=Norcott + +OUI:0022B9* + ID_OUI_FROM_DATABASE=Analogix Seminconductor, Inc + +OUI:0022BA* + ID_OUI_FROM_DATABASE=HUTH Elektronik Systeme GmbH + +OUI:0022BB* + ID_OUI_FROM_DATABASE=beyerdynamic GmbH & Co. KG + +OUI:0022BC* + ID_OUI_FROM_DATABASE=JDSU France SAS + +OUI:0022BD* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0022BE* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0022BF* + ID_OUI_FROM_DATABASE=SieAmp Group of Companies + +OUI:0022C0* + ID_OUI_FROM_DATABASE=Shenzhen Forcelink Electronic Co, Ltd + +OUI:0022C1* + ID_OUI_FROM_DATABASE=Active Storage Inc. + +OUI:0022C2* + ID_OUI_FROM_DATABASE=Proview Eletrônica do Brasil LTDA + +OUI:0022C3* + ID_OUI_FROM_DATABASE=Zeeport Technology Inc. + +OUI:0022C4* + ID_OUI_FROM_DATABASE=epro GmbH + +OUI:0022C5* + ID_OUI_FROM_DATABASE=INFORSON Co,Ltd. + +OUI:0022C6* + ID_OUI_FROM_DATABASE=Sutus Inc + +OUI:0022C7* + ID_OUI_FROM_DATABASE=SEGGER Microcontroller GmbH & Co. KG + +OUI:0022C8* + ID_OUI_FROM_DATABASE=Applied Instruments + +OUI:0022C9* + ID_OUI_FROM_DATABASE=Lenord, Bauer & Co GmbH + +OUI:0022CA* + ID_OUI_FROM_DATABASE=Anviz Biometric Tech. Co., Ltd. + +OUI:0022CB* + ID_OUI_FROM_DATABASE=IONODES Inc. + +OUI:0022CC* + ID_OUI_FROM_DATABASE=SciLog, Inc. + +OUI:0022CD* + ID_OUI_FROM_DATABASE=Ared Technology Co., Ltd. + +OUI:0022CE* + ID_OUI_FROM_DATABASE=Cisco, Service Provider Video Technology Group + +OUI:0022CF* + ID_OUI_FROM_DATABASE=PLANEX Communications INC + +OUI:0022D0* + ID_OUI_FROM_DATABASE=Polar Electro Oy + +OUI:0022D1* + ID_OUI_FROM_DATABASE=Albrecht Jung GmbH & Co. KG + +OUI:0022D2* + ID_OUI_FROM_DATABASE=All Earth Comércio de Eletrônicos LTDA. + +OUI:0022D3* + ID_OUI_FROM_DATABASE=Hub-Tech + +OUI:0022D4* + ID_OUI_FROM_DATABASE=ComWorth Co., Ltd. + +OUI:0022D5* + ID_OUI_FROM_DATABASE=Eaton Corp. Electrical Group Data Center Solutions - Pulizzi + +OUI:0022D6* + ID_OUI_FROM_DATABASE=Cypak AB + +OUI:0022D7* + ID_OUI_FROM_DATABASE=Nintendo Co., Ltd. + +OUI:0022D8* + ID_OUI_FROM_DATABASE=Shenzhen GST Security and Safety Technology Limited + +OUI:0022D9* + ID_OUI_FROM_DATABASE=Fortex Industrial Ltd. + +OUI:0022DA* + ID_OUI_FROM_DATABASE=ANATEK, LLC + +OUI:0022DB* + ID_OUI_FROM_DATABASE=Translogic Corporation + +OUI:0022DC* + ID_OUI_FROM_DATABASE=Vigil Health Solutions Inc. + +OUI:0022DD* + ID_OUI_FROM_DATABASE=Protecta Electronics Ltd + +OUI:0022DE* + ID_OUI_FROM_DATABASE=OPPO Digital, Inc. + +OUI:0022DF* + ID_OUI_FROM_DATABASE=TAMUZ Monitors + +OUI:0022E0* + ID_OUI_FROM_DATABASE=Atlantic Software Technologies S.r.L. + +OUI:0022E1* + ID_OUI_FROM_DATABASE=ZORT Labs, LLC. + +OUI:0022E2* + ID_OUI_FROM_DATABASE=WABTEC Transit Division + +OUI:0022E3* + ID_OUI_FROM_DATABASE=Amerigon + +OUI:0022E4* + ID_OUI_FROM_DATABASE=APASS TECHNOLOGY CO., LTD. + +OUI:0022E5* + ID_OUI_FROM_DATABASE=Fisher-Rosemount Systems Inc. + +OUI:0022E6* + ID_OUI_FROM_DATABASE=Intelligent Data + +OUI:0022E7* + ID_OUI_FROM_DATABASE=WPS Parking Systems + +OUI:0022E8* + ID_OUI_FROM_DATABASE=Applition Co., Ltd. + +OUI:0022E9* + ID_OUI_FROM_DATABASE=ProVision Communications + +OUI:0022EA* + ID_OUI_FROM_DATABASE=Rustelcom Inc. + +OUI:0022EB* + ID_OUI_FROM_DATABASE=Data Respons A/S + +OUI:0022EC* + ID_OUI_FROM_DATABASE=IDEALBT TECHNOLOGY CORPORATION + +OUI:0022ED* + ID_OUI_FROM_DATABASE=TSI Power Corporation + +OUI:0022EE* + ID_OUI_FROM_DATABASE=Algo Communication Products Ltd + +OUI:0022EF* + ID_OUI_FROM_DATABASE=Ibis Tek, LLC + +OUI:0022F0* + ID_OUI_FROM_DATABASE=3 Greens Aviation Limited + +OUI:0022F2* + ID_OUI_FROM_DATABASE=SunPower Corp + +OUI:0022F3* + ID_OUI_FROM_DATABASE=SHARP CORPORATION + +OUI:0022F4* + ID_OUI_FROM_DATABASE=AMPAK Technology, Inc. + +OUI:0022F5* + ID_OUI_FROM_DATABASE=Advanced Realtime Tracking GmbH + +OUI:0022F6* + ID_OUI_FROM_DATABASE=Syracuse Research Corporation + +OUI:0022F7* + ID_OUI_FROM_DATABASE=Conceptronic + +OUI:0022F8* + ID_OUI_FROM_DATABASE=PIMA Electronic Systems Ltd. + +OUI:0022F9* + ID_OUI_FROM_DATABASE=Pollin Electronic GmbH + +OUI:0022FA* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:0022FB* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:0022FC* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:0022FD* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:0022FE* + ID_OUI_FROM_DATABASE=Microprocessor Designs Inc + +OUI:0022FF* + ID_OUI_FROM_DATABASE=NIVIS LLC + +OUI:002300* + ID_OUI_FROM_DATABASE=Cayee Computer Ltd. + +OUI:002301* + ID_OUI_FROM_DATABASE=Witron Technology Limited + +OUI:002302* + ID_OUI_FROM_DATABASE=Cobalt Digital, Inc. + +OUI:002303* + ID_OUI_FROM_DATABASE=LITE-ON IT Corporation + +OUI:002304* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:002305* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:002306* + ID_OUI_FROM_DATABASE=ALPS Electric Co., Ltd + +OUI:002307* + ID_OUI_FROM_DATABASE=FUTURE INNOVATION TECH CO.,LTD + +OUI:002308* + ID_OUI_FROM_DATABASE=Arcadyan Technology Corporation + +OUI:002309* + ID_OUI_FROM_DATABASE=Janam Technologies LLC + +OUI:00230A* + ID_OUI_FROM_DATABASE=ARBURG GmbH & Co KG + +OUI:00230B* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:00230C* + ID_OUI_FROM_DATABASE=CLOVER ELECTRONICS CO.,LTD. + +OUI:00230D* + ID_OUI_FROM_DATABASE=Nortel Networks + +OUI:00230E* + ID_OUI_FROM_DATABASE=Gorba AG + +OUI:00230F* + ID_OUI_FROM_DATABASE=Hirsch Electronics Corporation + +OUI:002310* + ID_OUI_FROM_DATABASE=LNC Technology Co., Ltd. + +OUI:002311* + ID_OUI_FROM_DATABASE=Gloscom Co., Ltd. + +OUI:002312* + ID_OUI_FROM_DATABASE=Apple, Inc + +OUI:002313* + ID_OUI_FROM_DATABASE=Qool Technologies Ltd. + +OUI:002314* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:002315* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:002316* + ID_OUI_FROM_DATABASE=KISAN ELECTRONICS CO + +OUI:002317* + ID_OUI_FROM_DATABASE=Lasercraft Inc + +OUI:002318* + ID_OUI_FROM_DATABASE=Toshiba + +OUI:002319* + ID_OUI_FROM_DATABASE=Sielox LLC + +OUI:00231A* + ID_OUI_FROM_DATABASE=ITF Co., Ltd. + +OUI:00231B* + ID_OUI_FROM_DATABASE=Danaher Motion - Kollmorgen + +OUI:00231C* + ID_OUI_FROM_DATABASE=Fourier Systems Ltd. + +OUI:00231D* + ID_OUI_FROM_DATABASE=Deltacom Electronics Ltd + +OUI:00231E* + ID_OUI_FROM_DATABASE=Cezzer Multimedia Technologies + +OUI:00231F* + ID_OUI_FROM_DATABASE=Guangda Electronic & Telecommunication Technology Development Co., Ltd. + +OUI:002320* + ID_OUI_FROM_DATABASE=Nicira Networks + +OUI:002321* + ID_OUI_FROM_DATABASE=Avitech International Corp + +OUI:002322* + ID_OUI_FROM_DATABASE=KISS Teknical Solutions, Inc. + +OUI:002323* + ID_OUI_FROM_DATABASE=Zylin AS + +OUI:002324* + ID_OUI_FROM_DATABASE=G-PRO COMPUTER + +OUI:002325* + ID_OUI_FROM_DATABASE=IOLAN Holding + +OUI:002326* + ID_OUI_FROM_DATABASE=Fujitsu Limited + +OUI:002327* + ID_OUI_FROM_DATABASE=Shouyo Electronics CO., LTD + +OUI:002328* + ID_OUI_FROM_DATABASE=ALCON TELECOMMUNICATIONS CO., LTD. + +OUI:002329* + ID_OUI_FROM_DATABASE=DDRdrive LLC + +OUI:00232A* + ID_OUI_FROM_DATABASE=eonas IT-Beratung und -Entwicklung GmbH + +OUI:00232B* + ID_OUI_FROM_DATABASE=IRD A/S + +OUI:00232C* + ID_OUI_FROM_DATABASE=Senticare + +OUI:00232D* + ID_OUI_FROM_DATABASE=SandForce + +OUI:00232E* + ID_OUI_FROM_DATABASE=Kedah Electronics Engineering, LLC + +OUI:00232F* + ID_OUI_FROM_DATABASE=Advanced Card Systems Ltd. + +OUI:002330* + ID_OUI_FROM_DATABASE=DIZIPIA, INC. + +OUI:002331* + ID_OUI_FROM_DATABASE=Nintendo Co., Ltd. + +OUI:002332* + ID_OUI_FROM_DATABASE=Apple, Inc + +OUI:002333* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:002334* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:002335* + ID_OUI_FROM_DATABASE=Linkflex Co.,Ltd + +OUI:002336* + ID_OUI_FROM_DATABASE=METEL s.r.o. + +OUI:002337* + ID_OUI_FROM_DATABASE=Global Star Solutions ULC + +OUI:002338* + ID_OUI_FROM_DATABASE=OJ-Electronics A/S + +OUI:002339* + ID_OUI_FROM_DATABASE=Samsung Electronics + +OUI:00233A* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:00233B* + ID_OUI_FROM_DATABASE=C-Matic Systems Ltd + +OUI:00233C* + ID_OUI_FROM_DATABASE=Alflex + +OUI:00233D* + ID_OUI_FROM_DATABASE=Novero holding B.V. + +OUI:00233E* + ID_OUI_FROM_DATABASE=Alcatel-Lucent-IPD + +OUI:00233F* + ID_OUI_FROM_DATABASE=Purechoice Inc + +OUI:002340* + ID_OUI_FROM_DATABASE=MiX Telematics + +OUI:002341* + ID_OUI_FROM_DATABASE=Siemens AG, Infrastructure & Cities Sector, Building Technologies Division + +OUI:002342* + ID_OUI_FROM_DATABASE=Coffee Equipment Company + +OUI:002343* + ID_OUI_FROM_DATABASE=TEM AG + +OUI:002344* + ID_OUI_FROM_DATABASE=Objective Interface Systems + +OUI:002345* + ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications + +OUI:002346* + ID_OUI_FROM_DATABASE=Vestac + +OUI:002347* + ID_OUI_FROM_DATABASE=ProCurve Networking by HP + +OUI:002348* + ID_OUI_FROM_DATABASE=SAGEM COMMUNICATION + +OUI:002349* + ID_OUI_FROM_DATABASE=Helmholtz Centre Berlin for Material and Energy + +OUI:00234B* + ID_OUI_FROM_DATABASE=Inyuan Technology Inc. + +OUI:00234C* + ID_OUI_FROM_DATABASE=KTC AB + +OUI:00234D* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co., Ltd. + +OUI:00234E* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co., Ltd. + +OUI:00234F* + ID_OUI_FROM_DATABASE=Luminous Power Technologies Pvt. Ltd. + +OUI:002350* + ID_OUI_FROM_DATABASE=LynTec + +OUI:002351* + ID_OUI_FROM_DATABASE=2Wire + +OUI:002352* + ID_OUI_FROM_DATABASE=DATASENSOR S.p.A. + +OUI:002353* + ID_OUI_FROM_DATABASE=F E T Elettronica snc + +OUI:002354* + ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. + +OUI:002355* + ID_OUI_FROM_DATABASE=Kinco Automation(Shanghai) Ltd. + +OUI:002356* + ID_OUI_FROM_DATABASE=Packet Forensics LLC + +OUI:002357* + ID_OUI_FROM_DATABASE=Pitronot Technologies and Engineering P.T.E. Ltd. + +OUI:002358* + ID_OUI_FROM_DATABASE=SYSTEL SA + +OUI:002359* + ID_OUI_FROM_DATABASE=Benchmark Electronics ( Thailand ) Public Company Limited + +OUI:00235A* + ID_OUI_FROM_DATABASE=COMPAL INFORMATION (KUNSHAN) CO., Ltd. + +OUI:00235B* + ID_OUI_FROM_DATABASE=Gulfstream + +OUI:00235C* + ID_OUI_FROM_DATABASE=Aprius, Inc. + +OUI:00235D* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00235E* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00235F* + ID_OUI_FROM_DATABASE=Silicon Micro Sensors GmbH + +OUI:002360* + ID_OUI_FROM_DATABASE=Lookit Technology Co., Ltd + +OUI:002361* + ID_OUI_FROM_DATABASE=Unigen Corporation + +OUI:002362* + ID_OUI_FROM_DATABASE=Goldline Controls + +OUI:002363* + ID_OUI_FROM_DATABASE=Zhuhai RaySharp Technology Co., Ltd. + +OUI:002364* + ID_OUI_FROM_DATABASE=Power Instruments Pte Ltd + +OUI:002365* + ID_OUI_FROM_DATABASE=ELKA-Elektronik GmbH + +OUI:002366* + ID_OUI_FROM_DATABASE=Beijing Siasun Electronic System Co.,Ltd. + +OUI:002367* + ID_OUI_FROM_DATABASE=UniControls a.s. + +OUI:002368* + ID_OUI_FROM_DATABASE=Motorola + +OUI:002369* + ID_OUI_FROM_DATABASE=Cisco-Linksys, LLC + +OUI:00236A* + ID_OUI_FROM_DATABASE=SmartRG Inc + +OUI:00236B* + ID_OUI_FROM_DATABASE=Xembedded, Inc. + +OUI:00236C* + ID_OUI_FROM_DATABASE=Apple, Inc + +OUI:00236D* + ID_OUI_FROM_DATABASE=ResMed Ltd + +OUI:00236E* + ID_OUI_FROM_DATABASE=Burster GmbH & Co KG + +OUI:00236F* + ID_OUI_FROM_DATABASE=DAQ System + +OUI:002370* + ID_OUI_FROM_DATABASE=Snell + +OUI:002371* + ID_OUI_FROM_DATABASE=SOAM Systel + +OUI:002372* + ID_OUI_FROM_DATABASE=MORE STAR INDUSTRIAL GROUP LIMITED + +OUI:002373* + ID_OUI_FROM_DATABASE=GridIron Systems, Inc. + +OUI:002374* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:002375* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:002376* + ID_OUI_FROM_DATABASE=HTC Corporation + +OUI:002377* + ID_OUI_FROM_DATABASE=Isotek Electronics Ltd + +OUI:002378* + ID_OUI_FROM_DATABASE=GN Netcom A/S + +OUI:002379* + ID_OUI_FROM_DATABASE=Union Business Machines Co. Ltd. + +OUI:00237A* + ID_OUI_FROM_DATABASE=RIM + +OUI:00237B* + ID_OUI_FROM_DATABASE=WHDI LLC + +OUI:00237C* + ID_OUI_FROM_DATABASE=NEOTION + +OUI:00237D* + ID_OUI_FROM_DATABASE=Hewlett-Packard Company + +OUI:00237E* + ID_OUI_FROM_DATABASE=ELSTER GMBH + +OUI:00237F* + ID_OUI_FROM_DATABASE=PLANTRONICS + +OUI:002380* + ID_OUI_FROM_DATABASE=Nanoteq + +OUI:002381* + ID_OUI_FROM_DATABASE=Lengda Technology(Xiamen) Co.,Ltd. + +OUI:002382* + ID_OUI_FROM_DATABASE=Lih Rong Electronic Enterprise Co., Ltd. + +OUI:002383* + ID_OUI_FROM_DATABASE=InMage Systems Inc + +OUI:002384* + ID_OUI_FROM_DATABASE=GGH Engineering s.r.l. + +OUI:002385* + ID_OUI_FROM_DATABASE=ANTIPODE + +OUI:002386* + ID_OUI_FROM_DATABASE=Tour & Andersson AB + +OUI:002387* + ID_OUI_FROM_DATABASE=ThinkFlood, Inc. + +OUI:002388* + ID_OUI_FROM_DATABASE=V.T. Telematica S.p.a. + +OUI:002389* + ID_OUI_FROM_DATABASE=HANGZHOU H3C Technologies Co., Ltd. + +OUI:00238A* + ID_OUI_FROM_DATABASE=Ciena Corporation + +OUI:00238B* + ID_OUI_FROM_DATABASE=Quanta Computer Inc. + +OUI:00238D* + ID_OUI_FROM_DATABASE=Techno Design Co., Ltd. + +OUI:00238E* + ID_OUI_FROM_DATABASE=ADB Broadband Italia + +OUI:00238F* + ID_OUI_FROM_DATABASE=NIDEC COPAL CORPORATION + +OUI:002390* + ID_OUI_FROM_DATABASE=Algolware Corporation + +OUI:002391* + ID_OUI_FROM_DATABASE=Maxian + +OUI:002392* + ID_OUI_FROM_DATABASE=Proteus Industries Inc. + +OUI:002393* + ID_OUI_FROM_DATABASE=AJINEXTEK + +OUI:002394* + ID_OUI_FROM_DATABASE=Samjeon + +OUI:002395* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:002396* + ID_OUI_FROM_DATABASE=ANDES TECHNOLOGY CORPORATION + +OUI:002397* + ID_OUI_FROM_DATABASE=Westell Technologies Inc. + +OUI:002398* + ID_OUI_FROM_DATABASE=Sky Control + +OUI:002399* + ID_OUI_FROM_DATABASE=VD Division, Samsung Electronics Co. + +OUI:00239A* + ID_OUI_FROM_DATABASE=EasyData Software GmbH + +OUI:00239B* + ID_OUI_FROM_DATABASE=Elster Solutions, LLC + +OUI:00239C* + ID_OUI_FROM_DATABASE=Juniper Networks + +OUI:00239D* + ID_OUI_FROM_DATABASE=Mapower Electronics Co., Ltd + +OUI:00239E* + ID_OUI_FROM_DATABASE=Jiangsu Lemote Technology Corporation Limited + +OUI:00239F* + ID_OUI_FROM_DATABASE=Institut für Prüftechnik + +OUI:0023A0* + ID_OUI_FROM_DATABASE=Hana CNS Co., LTD. + +OUI:0023A1* + ID_OUI_FROM_DATABASE=Trend Electronics Ltd + +OUI:0023A2* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:0023A3* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:0023A4* + ID_OUI_FROM_DATABASE=New Concepts Development Corp. + +OUI:0023A5* + ID_OUI_FROM_DATABASE=SageTV, LLC + +OUI:0023A6* + ID_OUI_FROM_DATABASE=E-Mon + +OUI:0023A7* + ID_OUI_FROM_DATABASE=Redpine Signals, Inc. + +OUI:0023A8* + ID_OUI_FROM_DATABASE=Marshall Electronics + +OUI:0023A9* + ID_OUI_FROM_DATABASE=Beijing Detianquan Electromechanical Equipment Co., Ltd + +OUI:0023AA* + ID_OUI_FROM_DATABASE=HFR, Inc. + +OUI:0023AB* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0023AC* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0023AD* + ID_OUI_FROM_DATABASE=Xmark Corporation + +OUI:0023AE* + ID_OUI_FROM_DATABASE=Dell Inc. + +OUI:0023AF* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:0023B0* + ID_OUI_FROM_DATABASE=COMXION Technology Inc. + +OUI:0023B1* + ID_OUI_FROM_DATABASE=Longcheer Technology (Singapore) Pte Ltd + +OUI:0023B2* + ID_OUI_FROM_DATABASE=Intelligent Mechatronic Systems Inc + +OUI:0023B3* + ID_OUI_FROM_DATABASE=Lyyn AB + +OUI:0023B4* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:0023B5* + ID_OUI_FROM_DATABASE=ORTANA LTD + +OUI:0023B6* + ID_OUI_FROM_DATABASE=SECURITE COMMUNICATIONS / HONEYWELL + +OUI:0023B7* + ID_OUI_FROM_DATABASE=Q-Light Co., Ltd. + +OUI:0023B8* + ID_OUI_FROM_DATABASE=Sichuan Jiuzhou Electronic Technology Co.,Ltd + +OUI:0023B9* + ID_OUI_FROM_DATABASE=EADS Deutschland GmbH + +OUI:0023BA* + ID_OUI_FROM_DATABASE=Chroma + +OUI:0023BB* + ID_OUI_FROM_DATABASE=Schmitt Industries + +OUI:0023BC* + ID_OUI_FROM_DATABASE=EQ-SYS GmbH + +OUI:0023BD* + ID_OUI_FROM_DATABASE=Digital Ally, Inc. + +OUI:0023BE* + ID_OUI_FROM_DATABASE=Cisco SPVTG + +OUI:0023BF* + ID_OUI_FROM_DATABASE=Mainpine, Inc. + +OUI:0023C0* + ID_OUI_FROM_DATABASE=Broadway Networks + +OUI:0023C1* + ID_OUI_FROM_DATABASE=Securitas Direct AB + +OUI:0023C2* + ID_OUI_FROM_DATABASE=SAMSUNG Electronics. Co. LTD + +OUI:0023C3* + ID_OUI_FROM_DATABASE=LogMeIn, Inc. + +OUI:0023C4* + ID_OUI_FROM_DATABASE=Lux Lumen + +OUI:0023C5* + ID_OUI_FROM_DATABASE=Radiation Safety and Control Services Inc + +OUI:0023C6* + ID_OUI_FROM_DATABASE=SMC Corporation + +OUI:0023C7* + ID_OUI_FROM_DATABASE=AVSystem + +OUI:0023C8* + ID_OUI_FROM_DATABASE=TEAM-R + +OUI:0023C9* + ID_OUI_FROM_DATABASE=Sichuan Tianyi Information Science & Technology Stock CO.,LTD + +OUI:0023CA* + ID_OUI_FROM_DATABASE=Behind The Set, LLC + +OUI:0023CB* + ID_OUI_FROM_DATABASE=Shenzhen Full-join Technology Co.,Ltd + +OUI:0023CC* + ID_OUI_FROM_DATABASE=Nintendo Co., Ltd. + +OUI:0023CD* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO., LTD. + +OUI:0023CE* + ID_OUI_FROM_DATABASE=KITA DENSHI CORPORATION + +OUI:0023CF* + ID_OUI_FROM_DATABASE=CUMMINS-ALLISON CORP. + +OUI:0023D0* + ID_OUI_FROM_DATABASE=Uniloc USA Inc. + +OUI:0023D1* + ID_OUI_FROM_DATABASE=TRG + +OUI:0023D2* + ID_OUI_FROM_DATABASE=Inhand Electronics, Inc. + +OUI:0023D3* + ID_OUI_FROM_DATABASE=AirLink WiFi Networking Corp. + +OUI:0023D4* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:0023D5* + ID_OUI_FROM_DATABASE=WAREMA electronic GmbH + +OUI:0023D6* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,LTD + +OUI:0023D7* + ID_OUI_FROM_DATABASE=Samsung Electronics + +OUI:0023D8* + ID_OUI_FROM_DATABASE=Ball-It Oy + +OUI:0023D9* + ID_OUI_FROM_DATABASE=Banner Engineering + +OUI:0023DA* + ID_OUI_FROM_DATABASE=Industrial Computer Source (Deutschland)GmbH + +OUI:0023DB* + ID_OUI_FROM_DATABASE=saxnet gmbh + +OUI:0023DC* + ID_OUI_FROM_DATABASE=Benein, Inc + +OUI:0023DD* + ID_OUI_FROM_DATABASE=ELGIN S.A. + +OUI:0023DE* + ID_OUI_FROM_DATABASE=Ansync Inc. + +OUI:0023DF* + ID_OUI_FROM_DATABASE=Apple, Inc + +OUI:0023E0* + ID_OUI_FROM_DATABASE=INO Therapeutics LLC + +OUI:0023E1* + ID_OUI_FROM_DATABASE=Cavena Image Products AB + +OUI:0023E2* + ID_OUI_FROM_DATABASE=SEA Signalisation + +OUI:0023E3* + ID_OUI_FROM_DATABASE=Microtronic AG + +OUI:0023E4* + ID_OUI_FROM_DATABASE=IPnect co. ltd. + +OUI:0023E5* + ID_OUI_FROM_DATABASE=IPaXiom Networks + +OUI:0023E6* + ID_OUI_FROM_DATABASE=Pirkus, Inc. + +OUI:0023E7* + ID_OUI_FROM_DATABASE=Hinke A/S + +OUI:0023E8* + ID_OUI_FROM_DATABASE=Demco Corp. + +OUI:0023E9* + ID_OUI_FROM_DATABASE=F5 Networks, Inc. + +OUI:0023EA* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0023EB* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0023EC* + ID_OUI_FROM_DATABASE=Algorithmix GmbH + +OUI:0023ED* + ID_OUI_FROM_DATABASE=Motorola CHS + +OUI:0023EE* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:0023EF* + ID_OUI_FROM_DATABASE=Zuend Systemtechnik AG + +OUI:0023F0* + ID_OUI_FROM_DATABASE=Shanghai Jinghan Weighing Apparatus Co. Ltd. + +OUI:0023F1* + ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications + +OUI:0023F2* + ID_OUI_FROM_DATABASE=TVLogic + +OUI:0023F3* + ID_OUI_FROM_DATABASE=Glocom, Inc. + +OUI:0023F4* + ID_OUI_FROM_DATABASE=Masternaut + +OUI:0023F5* + ID_OUI_FROM_DATABASE=WILO SE + +OUI:0023F6* + ID_OUI_FROM_DATABASE=Softwell Technology Co., Ltd. + +OUI:0023F8* + ID_OUI_FROM_DATABASE=ZyXEL Communications Corporation + +OUI:0023F9* + ID_OUI_FROM_DATABASE=Double-Take Software, INC. + +OUI:0023FA* + ID_OUI_FROM_DATABASE=RG Nets, Inc. + +OUI:0023FB* + ID_OUI_FROM_DATABASE=IP Datatel, Inc. + +OUI:0023FC* + ID_OUI_FROM_DATABASE=Ultra Stereo Labs, Inc + +OUI:0023FD* + ID_OUI_FROM_DATABASE=AFT Atlas Fahrzeugtechnik GmbH + +OUI:0023FE* + ID_OUI_FROM_DATABASE=Biodevices, SA + +OUI:0023FF* + ID_OUI_FROM_DATABASE=Beijing HTTC Technology Ltd. + +OUI:002400* + ID_OUI_FROM_DATABASE=Nortel Networks + +OUI:002401* + ID_OUI_FROM_DATABASE=D-Link Corporation + +OUI:002402* + ID_OUI_FROM_DATABASE=Op-Tection GmbH + +OUI:002403* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:002404* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:002405* + ID_OUI_FROM_DATABASE=Dilog Nordic AB + +OUI:002406* + ID_OUI_FROM_DATABASE=Pointmobile + +OUI:002407* + ID_OUI_FROM_DATABASE=TELEM SAS + +OUI:002408* + ID_OUI_FROM_DATABASE=Pacific Biosciences + +OUI:002409* + ID_OUI_FROM_DATABASE=The Toro Company + +OUI:00240A* + ID_OUI_FROM_DATABASE=US Beverage Net + +OUI:00240B* + ID_OUI_FROM_DATABASE=Virtual Computer Inc. + +OUI:00240C* + ID_OUI_FROM_DATABASE=DELEC GmbH + +OUI:00240D* + ID_OUI_FROM_DATABASE=OnePath Networks LTD. + +OUI:00240E* + ID_OUI_FROM_DATABASE=Inventec Besta Co., Ltd. + +OUI:00240F* + ID_OUI_FROM_DATABASE=Ishii Tool & Engineering Corporation + +OUI:002410* + ID_OUI_FROM_DATABASE=NUETEQ Technology,Inc. + +OUI:002411* + ID_OUI_FROM_DATABASE=PharmaSmart LLC + +OUI:002412* + ID_OUI_FROM_DATABASE=Benign Technologies Co, Ltd. + +OUI:002413* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:002414* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:002415* + ID_OUI_FROM_DATABASE=Magnetic Autocontrol GmbH + +OUI:002416* + ID_OUI_FROM_DATABASE=Any Use + +OUI:002417* + ID_OUI_FROM_DATABASE=Thomson Telecom Belgium + +OUI:002418* + ID_OUI_FROM_DATABASE=Nextwave Semiconductor + +OUI:00241A* + ID_OUI_FROM_DATABASE=Red Beetle Inc. + +OUI:00241B* + ID_OUI_FROM_DATABASE=iWOW Communications Pte Ltd + +OUI:00241C* + ID_OUI_FROM_DATABASE=FuGang Electronic (DG) Co.,Ltd + +OUI:00241D* + ID_OUI_FROM_DATABASE=GIGA-BYTE TECHNOLOGY CO.,LTD. + +OUI:00241E* + ID_OUI_FROM_DATABASE=Nintendo Co., Ltd. + +OUI:00241F* + ID_OUI_FROM_DATABASE=DCT-Delta GmbH + +OUI:002420* + ID_OUI_FROM_DATABASE=NetUP Inc. + +OUI:002421* + ID_OUI_FROM_DATABASE=MICRO-STAR INT'L CO., LTD. + +OUI:002422* + ID_OUI_FROM_DATABASE=Knapp Logistik Automation GmbH + +OUI:002423* + ID_OUI_FROM_DATABASE=AzureWave Technologies (Shanghai) Inc. + +OUI:002424* + ID_OUI_FROM_DATABASE=Axis Network Technology + +OUI:002425* + ID_OUI_FROM_DATABASE=Shenzhenshi chuangzhicheng Technology Co.,Ltd + +OUI:002426* + ID_OUI_FROM_DATABASE=NOHMI BOSAI LTD. + +OUI:002427* + ID_OUI_FROM_DATABASE=SSI COMPUTER CORP + +OUI:002428* + ID_OUI_FROM_DATABASE=EnergyICT + +OUI:002429* + ID_OUI_FROM_DATABASE=MK MASTER INC. + +OUI:00242A* + ID_OUI_FROM_DATABASE=Hittite Microwave Corporation + +OUI:00242B* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind.Co.,Ltd. + +OUI:00242C* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co., Ltd. + +OUI:00242E* + ID_OUI_FROM_DATABASE=Datastrip Inc. + +OUI:00242F* + ID_OUI_FROM_DATABASE=VirtenSys Inc + +OUI:002430* + ID_OUI_FROM_DATABASE=Ruby Tech Corp. + +OUI:002431* + ID_OUI_FROM_DATABASE=Uni-v co.,ltd + +OUI:002432* + ID_OUI_FROM_DATABASE=Neostar Technology Co.,LTD + +OUI:002433* + ID_OUI_FROM_DATABASE=Alps Electric Co., Ltd + +OUI:002434* + ID_OUI_FROM_DATABASE=Lectrosonics, Inc. + +OUI:002435* + ID_OUI_FROM_DATABASE=WIDE CORPORATION + +OUI:002436* + ID_OUI_FROM_DATABASE=Apple, Inc + +OUI:002437* + ID_OUI_FROM_DATABASE=Motorola - BSG + +OUI:002438* + ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc + +OUI:002439* + ID_OUI_FROM_DATABASE=Essential Viewing Systems Limited + +OUI:00243A* + ID_OUI_FROM_DATABASE=Ludl Electronic Products + +OUI:00243B* + ID_OUI_FROM_DATABASE=CSSI (S) Pte Ltd + +OUI:00243C* + ID_OUI_FROM_DATABASE=S.A.A.A. + +OUI:00243D* + ID_OUI_FROM_DATABASE=Emerson Appliance Motors and Controls + +OUI:00243F* + ID_OUI_FROM_DATABASE=Storwize, Inc. + +OUI:002440* + ID_OUI_FROM_DATABASE=Halo Monitoring, Inc. + +OUI:002441* + ID_OUI_FROM_DATABASE=Wanzl Metallwarenfabrik GmbH + +OUI:002442* + ID_OUI_FROM_DATABASE=Axona Limited + +OUI:002443* + ID_OUI_FROM_DATABASE=Nortel Networks + +OUI:002444* + ID_OUI_FROM_DATABASE=Nintendo Co., Ltd. + +OUI:002445* + ID_OUI_FROM_DATABASE=LiquidxStream Systems Inc. + +OUI:002446* + ID_OUI_FROM_DATABASE=MMB Research Inc. + +OUI:002447* + ID_OUI_FROM_DATABASE=Kaztek Systems + +OUI:002448* + ID_OUI_FROM_DATABASE=SpiderCloud Wireless, Inc + +OUI:002449* + ID_OUI_FROM_DATABASE=Shen Zhen Lite Star Electronics Technology Co., Ltd + +OUI:00244A* + ID_OUI_FROM_DATABASE=Voyant International + +OUI:00244B* + ID_OUI_FROM_DATABASE=PERCEPTRON INC + +OUI:00244C* + ID_OUI_FROM_DATABASE=Solartron Metrology Ltd + +OUI:00244D* + ID_OUI_FROM_DATABASE=Hokkaido Electronics Corporation + +OUI:00244E* + ID_OUI_FROM_DATABASE=RadChips, Inc. + +OUI:00244F* + ID_OUI_FROM_DATABASE=Asantron Technologies Ltd. + +OUI:002450* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:002451* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:002452* + ID_OUI_FROM_DATABASE=Silicon Software GmbH + +OUI:002453* + ID_OUI_FROM_DATABASE=Initra d.o.o. + +OUI:002454* + ID_OUI_FROM_DATABASE=Samsung Electronics Co., LTD + +OUI:002455* + ID_OUI_FROM_DATABASE=MuLogic BV + +OUI:002456* + ID_OUI_FROM_DATABASE=2Wire + +OUI:002458* + ID_OUI_FROM_DATABASE=PA Bastion CC + +OUI:002459* + ID_OUI_FROM_DATABASE=ABB STOTZ-KONTAKT GmbH + +OUI:00245A* + ID_OUI_FROM_DATABASE=Nanjing Panda Electronics Company Limited + +OUI:00245B* + ID_OUI_FROM_DATABASE=RAIDON TECHNOLOGY, INC. + +OUI:00245C* + ID_OUI_FROM_DATABASE=Design-Com Technologies Pty. Ltd. + +OUI:00245D* + ID_OUI_FROM_DATABASE=Terberg besturingstechniek B.V. + +OUI:00245E* + ID_OUI_FROM_DATABASE=Hivision Co.,ltd + +OUI:00245F* + ID_OUI_FROM_DATABASE=Vine Telecom CO.,Ltd. + +OUI:002460* + ID_OUI_FROM_DATABASE=Giaval Science Development Co. Ltd. + +OUI:002461* + ID_OUI_FROM_DATABASE=Shin Wang Tech. + +OUI:002462* + ID_OUI_FROM_DATABASE=Rayzone Corporation + +OUI:002463* + ID_OUI_FROM_DATABASE=Phybridge Inc + +OUI:002464* + ID_OUI_FROM_DATABASE=Bridge Technologies Co AS + +OUI:002465* + ID_OUI_FROM_DATABASE=Elentec + +OUI:002466* + ID_OUI_FROM_DATABASE=Unitron nv + +OUI:002467* + ID_OUI_FROM_DATABASE=AOC International (Europe) GmbH + +OUI:002468* + ID_OUI_FROM_DATABASE=Sumavision Technologies Co.,Ltd + +OUI:002469* + ID_OUI_FROM_DATABASE=Smart Doorphones + +OUI:00246A* + ID_OUI_FROM_DATABASE=Solid Year Co., Ltd. + +OUI:00246B* + ID_OUI_FROM_DATABASE=Covia, Inc. + +OUI:00246C* + ID_OUI_FROM_DATABASE=ARUBA NETWORKS, INC. + +OUI:00246D* + ID_OUI_FROM_DATABASE=Weinzierl Engineering GmbH + +OUI:00246E* + ID_OUI_FROM_DATABASE=Phihong USA Corp. + +OUI:00246F* + ID_OUI_FROM_DATABASE=Onda Communication spa + +OUI:002470* + ID_OUI_FROM_DATABASE=AUROTECH ultrasound AS. + +OUI:002471* + ID_OUI_FROM_DATABASE=Fusion MultiSystems dba Fusion-io + +OUI:002472* + ID_OUI_FROM_DATABASE=ReDriven Power Inc. + +OUI:002473* + ID_OUI_FROM_DATABASE=3Com Europe Ltd + +OUI:002474* + ID_OUI_FROM_DATABASE=Autronica Fire And Securirty + +OUI:002475* + ID_OUI_FROM_DATABASE=Compass System(Embedded Dept.) + +OUI:002476* + ID_OUI_FROM_DATABASE=TAP.tv + +OUI:002477* + ID_OUI_FROM_DATABASE=Tibbo Technology + +OUI:002478* + ID_OUI_FROM_DATABASE=Mag Tech Electronics Co Limited + +OUI:002479* + ID_OUI_FROM_DATABASE=Optec Displays, Inc. + +OUI:00247A* + ID_OUI_FROM_DATABASE=FU YI CHENG Technology Co., Ltd. + +OUI:00247B* + ID_OUI_FROM_DATABASE=Actiontec Electronics, Inc + +OUI:00247C* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:00247D* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:00247E* + ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co., Ltd + +OUI:00247F* + ID_OUI_FROM_DATABASE=Nortel Networks + +OUI:002480* + ID_OUI_FROM_DATABASE=Meteocontrol GmbH + +OUI:002481* + ID_OUI_FROM_DATABASE=Hewlett-Packard Company + +OUI:002482* + ID_OUI_FROM_DATABASE=Ruckus Wireless + +OUI:002483* + ID_OUI_FROM_DATABASE=LG Electronics + +OUI:002484* + ID_OUI_FROM_DATABASE=Bang and Olufsen Medicom a/s + +OUI:002485* + ID_OUI_FROM_DATABASE=ConteXtream Ltd + +OUI:002486* + ID_OUI_FROM_DATABASE=DesignArt Networks + +OUI:002487* + ID_OUI_FROM_DATABASE=Blackboard Inc. + +OUI:002488* + ID_OUI_FROM_DATABASE=Centre For Development Of Telematics + +OUI:002489* + ID_OUI_FROM_DATABASE=Vodafone Omnitel N.V. + +OUI:00248A* + ID_OUI_FROM_DATABASE=Kaga Electronics Co., Ltd. + +OUI:00248B* + ID_OUI_FROM_DATABASE=HYBUS CO., LTD. + +OUI:00248C* + ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. + +OUI:00248D* + ID_OUI_FROM_DATABASE=Sony Computer Entertainment Inc. + +OUI:00248E* + ID_OUI_FROM_DATABASE=Infoware ZRt. + +OUI:00248F* + ID_OUI_FROM_DATABASE=DO-MONIX + +OUI:002490* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,LTD + +OUI:002491* + ID_OUI_FROM_DATABASE=Samsung Electronics + +OUI:002492* + ID_OUI_FROM_DATABASE=Motorola, Broadband Solutions Group + +OUI:002493* + ID_OUI_FROM_DATABASE=Motorola, Inc + +OUI:002494* + ID_OUI_FROM_DATABASE=Shenzhen Baoxin Tech CO., Ltd. + +OUI:002495* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:002496* + ID_OUI_FROM_DATABASE=Ginzinger electronic systems + +OUI:002497* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:002498* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:002499* + ID_OUI_FROM_DATABASE=Aquila Technologies + +OUI:00249A* + ID_OUI_FROM_DATABASE=Beijing Zhongchuang Telecommunication Test Co., Ltd. + +OUI:00249B* + ID_OUI_FROM_DATABASE=Action Star Enterprise Co., Ltd. + +OUI:00249C* + ID_OUI_FROM_DATABASE=Bimeng Comunication System Co. Ltd + +OUI:00249D* + ID_OUI_FROM_DATABASE=NES Technology Inc. + +OUI:00249E* + ID_OUI_FROM_DATABASE=ADC-Elektronik GmbH + +OUI:00249F* + ID_OUI_FROM_DATABASE=RIM Testing Services + +OUI:0024A0* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:0024A1* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:0024A2* + ID_OUI_FROM_DATABASE=Hong Kong Middleware Technology Limited + +OUI:0024A3* + ID_OUI_FROM_DATABASE=Sonim Technologies Inc + +OUI:0024A4* + ID_OUI_FROM_DATABASE=Siklu Communication + +OUI:0024A5* + ID_OUI_FROM_DATABASE=Buffalo Inc. + +OUI:0024A6* + ID_OUI_FROM_DATABASE=TELESTAR DIGITAL GmbH + +OUI:0024A7* + ID_OUI_FROM_DATABASE=Advanced Video Communications Inc. + +OUI:0024A8* + ID_OUI_FROM_DATABASE=ProCurve Networking by HP + +OUI:0024A9* + ID_OUI_FROM_DATABASE=Ag Leader Technology + +OUI:0024AA* + ID_OUI_FROM_DATABASE=Dycor Technologies Ltd. + +OUI:0024AB* + ID_OUI_FROM_DATABASE=A7 Engineering, Inc. + +OUI:0024AC* + ID_OUI_FROM_DATABASE=Hangzhou DPtech Technologies Co., Ltd. + +OUI:0024AD* + ID_OUI_FROM_DATABASE=Adolf Thies Gmbh & Co. KG + +OUI:0024AE* + ID_OUI_FROM_DATABASE=Morpho + +OUI:0024AF* + ID_OUI_FROM_DATABASE=EchoStar Technologies + +OUI:0024B0* + ID_OUI_FROM_DATABASE=ESAB AB + +OUI:0024B1* + ID_OUI_FROM_DATABASE=Coulomb Technologies + +OUI:0024B2* + ID_OUI_FROM_DATABASE=Netgear + +OUI:0024B3* + ID_OUI_FROM_DATABASE=Graf-Syteco GmbH & Co. KG + +OUI:0024B4* + ID_OUI_FROM_DATABASE=ESCATRONIC GmbH + +OUI:0024B5* + ID_OUI_FROM_DATABASE=Nortel Networks + +OUI:0024B6* + ID_OUI_FROM_DATABASE=Seagate Technology + +OUI:0024B7* + ID_OUI_FROM_DATABASE=GridPoint, Inc. + +OUI:0024B8* + ID_OUI_FROM_DATABASE=free alliance sdn bhd + +OUI:0024B9* + ID_OUI_FROM_DATABASE=Wuhan Higheasy Electronic Technology Development Co.Ltd + +OUI:0024BA* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:0024BB* + ID_OUI_FROM_DATABASE=CENTRAL Corporation + +OUI:0024BC* + ID_OUI_FROM_DATABASE=HuRob Co.,Ltd + +OUI:0024BD* + ID_OUI_FROM_DATABASE=Hainzl Industriesysteme GmbH + +OUI:0024BE* + ID_OUI_FROM_DATABASE=Sony Corporation + +OUI:0024BF* + ID_OUI_FROM_DATABASE=CIAT + +OUI:0024C0* + ID_OUI_FROM_DATABASE=NTI COMODO INC + +OUI:0024C1* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:0024C2* + ID_OUI_FROM_DATABASE=Asumo Co.,Ltd. + +OUI:0024C3* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0024C4* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0024C5* + ID_OUI_FROM_DATABASE=Meridian Audio Limited + +OUI:0024C6* + ID_OUI_FROM_DATABASE=Hager Electro SAS + +OUI:0024C7* + ID_OUI_FROM_DATABASE=Mobilarm Ltd + +OUI:0024C8* + ID_OUI_FROM_DATABASE=Broadband Solutions Group + +OUI:0024C9* + ID_OUI_FROM_DATABASE=Broadband Solutions Group + +OUI:0024CA* + ID_OUI_FROM_DATABASE=Tobii Technology AB + +OUI:0024CB* + ID_OUI_FROM_DATABASE=Autonet Mobile + +OUI:0024CC* + ID_OUI_FROM_DATABASE=Fascinations Toys and Gifts, Inc. + +OUI:0024CD* + ID_OUI_FROM_DATABASE=Willow Garage, Inc. + +OUI:0024CE* + ID_OUI_FROM_DATABASE=Exeltech Inc + +OUI:0024CF* + ID_OUI_FROM_DATABASE=Inscape Data Corporation + +OUI:0024D0* + ID_OUI_FROM_DATABASE=Shenzhen SOGOOD Industry CO.,LTD. + +OUI:0024D1* + ID_OUI_FROM_DATABASE=Thomson Inc. + +OUI:0024D2* + ID_OUI_FROM_DATABASE=Askey Computer + +OUI:0024D3* + ID_OUI_FROM_DATABASE=QUALICA Inc. + +OUI:0024D4* + ID_OUI_FROM_DATABASE=FREEBOX SA + +OUI:0024D5* + ID_OUI_FROM_DATABASE=Winward Industrial Limited + +OUI:0024D6* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:0024D7* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:0024D8* + ID_OUI_FROM_DATABASE=IlSung Precision + +OUI:0024D9* + ID_OUI_FROM_DATABASE=BICOM, Inc. + +OUI:0024DA* + ID_OUI_FROM_DATABASE=Innovar Systems Limited + +OUI:0024DB* + ID_OUI_FROM_DATABASE=Alcohol Monitoring Systems + +OUI:0024DC* + ID_OUI_FROM_DATABASE=Juniper Networks + +OUI:0024DD* + ID_OUI_FROM_DATABASE=Centrak, Inc. + +OUI:0024DE* + ID_OUI_FROM_DATABASE=GLOBAL Technology Inc. + +OUI:0024DF* + ID_OUI_FROM_DATABASE=Digitalbox Europe GmbH + +OUI:0024E0* + ID_OUI_FROM_DATABASE=DS Tech, LLC + +OUI:0024E1* + ID_OUI_FROM_DATABASE=Convey Computer Corp. + +OUI:0024E2* + ID_OUI_FROM_DATABASE=HASEGAWA ELECTRIC CO.,LTD. + +OUI:0024E3* + ID_OUI_FROM_DATABASE=CAO Group + +OUI:0024E4* + ID_OUI_FROM_DATABASE=Withings + +OUI:0024E5* + ID_OUI_FROM_DATABASE=Seer Technology, Inc + +OUI:0024E6* + ID_OUI_FROM_DATABASE=In Motion Technology Inc. + +OUI:0024E7* + ID_OUI_FROM_DATABASE=Plaster Networks + +OUI:0024E8* + ID_OUI_FROM_DATABASE=Dell Inc. + +OUI:0024E9* + ID_OUI_FROM_DATABASE=Samsung Electronics Co., Ltd., Storage System Division + +OUI:0024EA* + ID_OUI_FROM_DATABASE=iris-GmbH infrared & intelligent sensors + +OUI:0024EB* + ID_OUI_FROM_DATABASE=ClearPath Networks, Inc. + +OUI:0024EC* + ID_OUI_FROM_DATABASE=United Information Technology Co.,Ltd. + +OUI:0024ED* + ID_OUI_FROM_DATABASE=YT Elec. Co,.Ltd. + +OUI:0024EE* + ID_OUI_FROM_DATABASE=Wynmax Inc. + +OUI:0024EF* + ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications + +OUI:0024F0* + ID_OUI_FROM_DATABASE=Seanodes + +OUI:0024F1* + ID_OUI_FROM_DATABASE=Shenzhen Fanhai Sanjiang Electronics Co., Ltd. + +OUI:0024F2* + ID_OUI_FROM_DATABASE=Uniphone Telecommunication Co., Ltd. + +OUI:0024F3* + ID_OUI_FROM_DATABASE=Nintendo Co., Ltd. + +OUI:0024F4* + ID_OUI_FROM_DATABASE=Kaminario Technologies Ltd. + +OUI:0024F5* + ID_OUI_FROM_DATABASE=NDS Surgical Imaging + +OUI:0024F6* + ID_OUI_FROM_DATABASE=MIYOSHI ELECTRONICS CORPORATION + +OUI:0024F7* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0024F8* + ID_OUI_FROM_DATABASE=Technical Solutions Company Ltd. + +OUI:0024F9* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0024FA* + ID_OUI_FROM_DATABASE=Hilger u. Kern GMBH + +OUI:0024FC* + ID_OUI_FROM_DATABASE=QuoPin Co., Ltd. + +OUI:0024FD* + ID_OUI_FROM_DATABASE=Accedian Networks Inc + +OUI:0024FE* + ID_OUI_FROM_DATABASE=AVM GmbH + +OUI:0024FF* + ID_OUI_FROM_DATABASE=QLogic Corporation + +OUI:002500* + ID_OUI_FROM_DATABASE=Apple, Inc + +OUI:002501* + ID_OUI_FROM_DATABASE=JSC "Supertel" + +OUI:002502* + ID_OUI_FROM_DATABASE=NaturalPoint + +OUI:002503* + ID_OUI_FROM_DATABASE=IBM Corp + +OUI:002504* + ID_OUI_FROM_DATABASE=Valiant Communications Limited + +OUI:002505* + ID_OUI_FROM_DATABASE=eks Engel GmbH & Co. KG + +OUI:002506* + ID_OUI_FROM_DATABASE=A.I. ANTITACCHEGGIO ITALIA SRL + +OUI:002507* + ID_OUI_FROM_DATABASE=ASTAK Inc. + +OUI:002508* + ID_OUI_FROM_DATABASE=Maquet Cardiopulmonary AG + +OUI:002509* + ID_OUI_FROM_DATABASE=SHARETRONIC Group LTD + +OUI:00250A* + ID_OUI_FROM_DATABASE=Security Expert Co. Ltd + +OUI:00250B* + ID_OUI_FROM_DATABASE=CENTROFACTOR INC + +OUI:00250C* + ID_OUI_FROM_DATABASE=Enertrac + +OUI:00250D* + ID_OUI_FROM_DATABASE=GZT Telkom-Telmor sp. z o.o. + +OUI:00250E* + ID_OUI_FROM_DATABASE=gt german telematics gmbh + +OUI:00250F* + ID_OUI_FROM_DATABASE=On-Ramp Wireless, Inc. + +OUI:002510* + ID_OUI_FROM_DATABASE=Pico-Tesla Magnetic Therapies + +OUI:002511* + ID_OUI_FROM_DATABASE=ELITEGROUP COMPUTER SYSTEM CO., LTD. + +OUI:002512* + ID_OUI_FROM_DATABASE=ZTE Corporation + +OUI:002513* + ID_OUI_FROM_DATABASE=CXP DIGITAL BV + +OUI:002514* + ID_OUI_FROM_DATABASE=PC Worth Int'l Co., Ltd. + +OUI:002515* + ID_OUI_FROM_DATABASE=SFR + +OUI:002516* + ID_OUI_FROM_DATABASE=Integrated Design Tools, Inc. + +OUI:002517* + ID_OUI_FROM_DATABASE=Venntis, LLC + +OUI:002518* + ID_OUI_FROM_DATABASE=Power PLUS Communications AG + +OUI:002519* + ID_OUI_FROM_DATABASE=Viaas Inc + +OUI:00251A* + ID_OUI_FROM_DATABASE=Psiber Data Systems Inc. + +OUI:00251B* + ID_OUI_FROM_DATABASE=Philips CareServant + +OUI:00251C* + ID_OUI_FROM_DATABASE=EDT + +OUI:00251D* + ID_OUI_FROM_DATABASE=DSA Encore, LLC + +OUI:00251E* + ID_OUI_FROM_DATABASE=ROTEL TECHNOLOGIES + +OUI:00251F* + ID_OUI_FROM_DATABASE=ZYNUS VISION INC. + +OUI:002520* + ID_OUI_FROM_DATABASE=SMA Railway Technology GmbH + +OUI:002521* + ID_OUI_FROM_DATABASE=Logitek Electronic Systems, Inc. + +OUI:002522* + ID_OUI_FROM_DATABASE=ASRock Incorporation + +OUI:002523* + ID_OUI_FROM_DATABASE=OCP Inc. + +OUI:002524* + ID_OUI_FROM_DATABASE=Lightcomm Technology Co., Ltd + +OUI:002525* + ID_OUI_FROM_DATABASE=CTERA Networks Ltd. + +OUI:002526* + ID_OUI_FROM_DATABASE=Genuine Technologies Co., Ltd. + +OUI:002527* + ID_OUI_FROM_DATABASE=Bitrode Corp. + +OUI:002528* + ID_OUI_FROM_DATABASE=Daido Signal Co., Ltd. + +OUI:002529* + ID_OUI_FROM_DATABASE=COMELIT GROUP S.P.A + +OUI:00252A* + ID_OUI_FROM_DATABASE=Chengdu GeeYa Technology Co.,LTD + +OUI:00252B* + ID_OUI_FROM_DATABASE=Stirling Energy Systems + +OUI:00252C* + ID_OUI_FROM_DATABASE=Entourage Systems, Inc. + +OUI:00252D* + ID_OUI_FROM_DATABASE=Kiryung Electronics + +OUI:00252E* + ID_OUI_FROM_DATABASE=Cisco SPVTG + +OUI:00252F* + ID_OUI_FROM_DATABASE=Energy, Inc. + +OUI:002530* + ID_OUI_FROM_DATABASE=Aetas Systems Inc. + +OUI:002531* + ID_OUI_FROM_DATABASE=Cloud Engines, Inc. + +OUI:002532* + ID_OUI_FROM_DATABASE=Digital Recorders + +OUI:002533* + ID_OUI_FROM_DATABASE=WITTENSTEIN AG + +OUI:002535* + ID_OUI_FROM_DATABASE=Minimax GmbH & Co KG + +OUI:002536* + ID_OUI_FROM_DATABASE=Oki Electric Industry Co., Ltd. + +OUI:002537* + ID_OUI_FROM_DATABASE=Runcom Technologies Ltd. + +OUI:002538* + ID_OUI_FROM_DATABASE=Samsung Electronics Co., Ltd., Memory Division + +OUI:002539* + ID_OUI_FROM_DATABASE=IfTA GmbH + +OUI:00253A* + ID_OUI_FROM_DATABASE=CEVA, Ltd. + +OUI:00253B* + ID_OUI_FROM_DATABASE=din Dietmar Nocker Facilitymanagement GmbH + +OUI:00253C* + ID_OUI_FROM_DATABASE=2Wire + +OUI:00253D* + ID_OUI_FROM_DATABASE=DRS Consolidated Controls + +OUI:00253E* + ID_OUI_FROM_DATABASE=Sensus Metering Systems + +OUI:002540* + ID_OUI_FROM_DATABASE=Quasar Technologies, Inc. + +OUI:002541* + ID_OUI_FROM_DATABASE=Maquet Critical Care AB + +OUI:002542* + ID_OUI_FROM_DATABASE=Pittasoft + +OUI:002543* + ID_OUI_FROM_DATABASE=MONEYTECH + +OUI:002544* + ID_OUI_FROM_DATABASE=LoJack Corporation + +OUI:002545* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:002546* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:002547* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:002548* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:002549* + ID_OUI_FROM_DATABASE=Jeorich Tech. Co.,Ltd. + +OUI:00254A* + ID_OUI_FROM_DATABASE=RingCube Technologies, Inc. + +OUI:00254B* + ID_OUI_FROM_DATABASE=Apple, Inc + +OUI:00254C* + ID_OUI_FROM_DATABASE=Videon Central, Inc. + +OUI:00254D* + ID_OUI_FROM_DATABASE=Singapore Technologies Electronics Limited + +OUI:00254E* + ID_OUI_FROM_DATABASE=Vertex Wireless Co., Ltd. + +OUI:00254F* + ID_OUI_FROM_DATABASE=ELETTROLAB Srl + +OUI:002550* + ID_OUI_FROM_DATABASE=Riverbed Technology + +OUI:002551* + ID_OUI_FROM_DATABASE=SE-Elektronic GmbH + +OUI:002552* + ID_OUI_FROM_DATABASE=VXI CORPORATION + +OUI:002553* + ID_OUI_FROM_DATABASE=ADB Broadband Italia + +OUI:002554* + ID_OUI_FROM_DATABASE=Pixel8 Networks + +OUI:002555* + ID_OUI_FROM_DATABASE=Visonic Technologies 1993 Ltd + +OUI:002556* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co., Ltd. + +OUI:002557* + ID_OUI_FROM_DATABASE=Research In Motion + +OUI:002558* + ID_OUI_FROM_DATABASE=MPEDIA + +OUI:002559* + ID_OUI_FROM_DATABASE=Syphan Technologies Ltd + +OUI:00255A* + ID_OUI_FROM_DATABASE=Tantalus Systems Corp. + +OUI:00255B* + ID_OUI_FROM_DATABASE=CoachComm, LLC + +OUI:00255C* + ID_OUI_FROM_DATABASE=NEC Corporation + +OUI:00255D* + ID_OUI_FROM_DATABASE=Morningstar Corporation + +OUI:00255E* + ID_OUI_FROM_DATABASE=Shanghai Dare Technologies Co.,Ltd. + +OUI:00255F* + ID_OUI_FROM_DATABASE=SenTec AG + +OUI:002560* + ID_OUI_FROM_DATABASE=Ibridge Networks & Communications Ltd. + +OUI:002561* + ID_OUI_FROM_DATABASE=ProCurve Networking by HP + +OUI:002562* + ID_OUI_FROM_DATABASE=interbro Co. Ltd. + +OUI:002563* + ID_OUI_FROM_DATABASE=Luxtera Inc + +OUI:002564* + ID_OUI_FROM_DATABASE=Dell Inc. + +OUI:002565* + ID_OUI_FROM_DATABASE=Vizimax Inc. + +OUI:002566* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:002567* + ID_OUI_FROM_DATABASE=Samsung Electronics + +OUI:002568* + ID_OUI_FROM_DATABASE=Shenzhen Huawei Communication Technologies Co., Ltd + +OUI:002569* + ID_OUI_FROM_DATABASE=SAGEM COMMUNICATION + +OUI:00256A* + ID_OUI_FROM_DATABASE=inIT - Institut Industrial IT + +OUI:00256B* + ID_OUI_FROM_DATABASE=ATENIX E.E. s.r.l. + +OUI:00256C* + ID_OUI_FROM_DATABASE="Azimut" Production Association JSC + +OUI:00256D* + ID_OUI_FROM_DATABASE=Broadband Forum + +OUI:00256E* + ID_OUI_FROM_DATABASE=Van Breda B.V. + +OUI:00256F* + ID_OUI_FROM_DATABASE=Dantherm Power + +OUI:002570* + ID_OUI_FROM_DATABASE=Eastern Communications Company Limited + +OUI:002571* + ID_OUI_FROM_DATABASE=Zhejiang Tianle Digital Electric Co.,Ltd + +OUI:002572* + ID_OUI_FROM_DATABASE=Nemo-Q International AB + +OUI:002573* + ID_OUI_FROM_DATABASE=ST Electronics (Info-Security) Pte Ltd + +OUI:002574* + ID_OUI_FROM_DATABASE=KUNIMI MEDIA DEVICE Co., Ltd. + +OUI:002575* + ID_OUI_FROM_DATABASE=FiberPlex Inc + +OUI:002576* + ID_OUI_FROM_DATABASE=NELI TECHNOLOGIES + +OUI:002577* + ID_OUI_FROM_DATABASE=D-BOX Technologies + +OUI:002578* + ID_OUI_FROM_DATABASE=JSC "Concern "Sozvezdie" + +OUI:002579* + ID_OUI_FROM_DATABASE=J & F Labs + +OUI:00257A* + ID_OUI_FROM_DATABASE=CAMCO Produktions- und Vertriebs-GmbH für Beschallungs- und Beleuchtungsanlagen + +OUI:00257B* + ID_OUI_FROM_DATABASE=STJ ELECTRONICS PVT LTD + +OUI:00257C* + ID_OUI_FROM_DATABASE=Huachentel Technology Development Co., Ltd + +OUI:00257D* + ID_OUI_FROM_DATABASE=PointRed Telecom Private Ltd. + +OUI:00257E* + ID_OUI_FROM_DATABASE=NEW POS Technology Limited + +OUI:00257F* + ID_OUI_FROM_DATABASE=CallTechSolution Co.,Ltd + +OUI:002580* + ID_OUI_FROM_DATABASE=Equipson S.A. + +OUI:002581* + ID_OUI_FROM_DATABASE=x-star networks Inc. + +OUI:002582* + ID_OUI_FROM_DATABASE=Maksat Technologies (P) Ltd + +OUI:002583* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:002584* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:002585* + ID_OUI_FROM_DATABASE=KOKUYO S&T Co., Ltd. + +OUI:002586* + ID_OUI_FROM_DATABASE=TP-LINK Technologies Co., Ltd. + +OUI:002587* + ID_OUI_FROM_DATABASE=Vitality, Inc. + +OUI:002588* + ID_OUI_FROM_DATABASE=Genie Industries, Inc. + +OUI:002589* + ID_OUI_FROM_DATABASE=Hills Industries Limited + +OUI:00258A* + ID_OUI_FROM_DATABASE=Pole/Zero Corporation + +OUI:00258B* + ID_OUI_FROM_DATABASE=Mellanox Technologies Ltd + +OUI:00258C* + ID_OUI_FROM_DATABASE=ESUS ELEKTRONIK SAN. VE DIS. TIC. LTD. STI. + +OUI:00258D* + ID_OUI_FROM_DATABASE=Haier + +OUI:00258E* + ID_OUI_FROM_DATABASE=The Weather Channel + +OUI:00258F* + ID_OUI_FROM_DATABASE=Trident Microsystems, Inc. + +OUI:002590* + ID_OUI_FROM_DATABASE=Super Micro Computer, Inc. + +OUI:002591* + ID_OUI_FROM_DATABASE=NEXTEK, Inc. + +OUI:002592* + ID_OUI_FROM_DATABASE=Guangzhou Shirui Electronic Co., Ltd + +OUI:002593* + ID_OUI_FROM_DATABASE=DatNet Informatikai Kft. + +OUI:002594* + ID_OUI_FROM_DATABASE=Eurodesign BG LTD + +OUI:002595* + ID_OUI_FROM_DATABASE=Northwest Signal Supply, Inc + +OUI:002596* + ID_OUI_FROM_DATABASE=GIGAVISION srl + +OUI:002597* + ID_OUI_FROM_DATABASE=Kalki Communication Technologies + +OUI:002598* + ID_OUI_FROM_DATABASE=Zhong Shan City Litai Electronic Industrial Co. Ltd + +OUI:002599* + ID_OUI_FROM_DATABASE=Hedon e.d. B.V. + +OUI:00259A* + ID_OUI_FROM_DATABASE=CEStronics GmbH + +OUI:00259B* + ID_OUI_FROM_DATABASE=Beijing PKUNITY Microsystems Technology Co., Ltd + +OUI:00259C* + ID_OUI_FROM_DATABASE=Cisco-Linksys, LLC + +OUI:00259E* + ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd. + +OUI:00259F* + ID_OUI_FROM_DATABASE=TechnoDigital Technologies GmbH + +OUI:0025A0* + ID_OUI_FROM_DATABASE=Nintendo Co., Ltd. + +OUI:0025A1* + ID_OUI_FROM_DATABASE=Enalasys + +OUI:0025A2* + ID_OUI_FROM_DATABASE=Alta Definicion LINCEO S.L. + +OUI:0025A3* + ID_OUI_FROM_DATABASE=Trimax Wireless, Inc. + +OUI:0025A4* + ID_OUI_FROM_DATABASE=EuroDesign embedded technologies GmbH + +OUI:0025A5* + ID_OUI_FROM_DATABASE=Walnut Media Network + +OUI:0025A6* + ID_OUI_FROM_DATABASE=Central Network Solution Co., Ltd. + +OUI:0025A7* + ID_OUI_FROM_DATABASE=Comverge, Inc. + +OUI:0025A8* + ID_OUI_FROM_DATABASE=Kontron (BeiJing) Technology Co.,Ltd + +OUI:0025A9* + ID_OUI_FROM_DATABASE=Shanghai Embedway Information Technologies Co.,Ltd + +OUI:0025AA* + ID_OUI_FROM_DATABASE=Beijing Soul Technology Co.,Ltd. + +OUI:0025AB* + ID_OUI_FROM_DATABASE=AIO LCD PC BU / TPV + +OUI:0025AC* + ID_OUI_FROM_DATABASE=I-Tech corporation + +OUI:0025AD* + ID_OUI_FROM_DATABASE=Manufacturing Resources International + +OUI:0025AE* + ID_OUI_FROM_DATABASE=Microsoft Corporation + +OUI:0025AF* + ID_OUI_FROM_DATABASE=COMFILE Technology + +OUI:0025B0* + ID_OUI_FROM_DATABASE=Schmartz Inc + +OUI:0025B1* + ID_OUI_FROM_DATABASE=Maya-Creation Corporation + +OUI:0025B2* + ID_OUI_FROM_DATABASE=LFK-Lenkflugkörpersysteme GmbH + +OUI:0025B3* + ID_OUI_FROM_DATABASE=Hewlett-Packard Company + +OUI:0025B4* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0025B5* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0025B6* + ID_OUI_FROM_DATABASE=Telecom FM + +OUI:0025B7* + ID_OUI_FROM_DATABASE=Costar electronics, inc., + +OUI:0025B8* + ID_OUI_FROM_DATABASE=Agile Communications, Inc. + +OUI:0025B9* + ID_OUI_FROM_DATABASE=Agilink Systems Corp. + +OUI:0025BA* + ID_OUI_FROM_DATABASE=Alcatel-Lucent IPD + +OUI:0025BB* + ID_OUI_FROM_DATABASE=INNERINT Co., Ltd. + +OUI:0025BC* + ID_OUI_FROM_DATABASE=Apple, Inc + +OUI:0025BD* + ID_OUI_FROM_DATABASE=Italdata Ingegneria dell'Idea S.p.A. + +OUI:0025BE* + ID_OUI_FROM_DATABASE=Tektrap Systems Inc. + +OUI:0025BF* + ID_OUI_FROM_DATABASE=Wireless Cables Inc. + +OUI:0025C0* + ID_OUI_FROM_DATABASE=ZillionTV Corporation + +OUI:0025C1* + ID_OUI_FROM_DATABASE=Nawoo Korea Corp. + +OUI:0025C2* + ID_OUI_FROM_DATABASE=RingBell Co.,Ltd. + +OUI:0025C3* + ID_OUI_FROM_DATABASE=Nortel Networks + +OUI:0025C4* + ID_OUI_FROM_DATABASE=Ruckus Wireless + +OUI:0025C5* + ID_OUI_FROM_DATABASE=Star Link Communication Pvt. Ltd. + +OUI:0025C6* + ID_OUI_FROM_DATABASE=kasercorp, ltd + +OUI:0025C7* + ID_OUI_FROM_DATABASE=altek Corporation + +OUI:0025C8* + ID_OUI_FROM_DATABASE=S-Access GmbH + +OUI:0025C9* + ID_OUI_FROM_DATABASE=SHENZHEN HUAPU DIGITAL CO., LTD + +OUI:0025CA* + ID_OUI_FROM_DATABASE=LS Research, LLC + +OUI:0025CB* + ID_OUI_FROM_DATABASE=Reiner SCT + +OUI:0025CC* + ID_OUI_FROM_DATABASE=Mobile Communications Korea Incorporated + +OUI:0025CD* + ID_OUI_FROM_DATABASE=Skylane Optics + +OUI:0025CE* + ID_OUI_FROM_DATABASE=InnerSpace + +OUI:0025CF* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:0025D0* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:0025D1* + ID_OUI_FROM_DATABASE=Eastech Electronics (Taiwan) Inc. + +OUI:0025D2* + ID_OUI_FROM_DATABASE=InpegVision Co., Ltd + +OUI:0025D3* + ID_OUI_FROM_DATABASE=AzureWave Technologies, Inc + +OUI:0025D4* + ID_OUI_FROM_DATABASE=Fortress Technologies + +OUI:0025D5* + ID_OUI_FROM_DATABASE=Robonica (Pty) Ltd + +OUI:0025D6* + ID_OUI_FROM_DATABASE=The Kroger Co. + +OUI:0025D7* + ID_OUI_FROM_DATABASE=CEDO + +OUI:0025D8* + ID_OUI_FROM_DATABASE=KOREA MAINTENANCE + +OUI:0025D9* + ID_OUI_FROM_DATABASE=DataFab Systems Inc. + +OUI:0025DA* + ID_OUI_FROM_DATABASE=Secura Key + +OUI:0025DB* + ID_OUI_FROM_DATABASE=ATI Electronics(Shenzhen) Co., LTD + +OUI:0025DC* + ID_OUI_FROM_DATABASE=Sumitomo Electric Networks, Inc + +OUI:0025DD* + ID_OUI_FROM_DATABASE=SUNNYTEK INFORMATION CO., LTD. + +OUI:0025DE* + ID_OUI_FROM_DATABASE=Probits Co., LTD. + +OUI:0025E0* + ID_OUI_FROM_DATABASE=CeedTec Sdn Bhd + +OUI:0025E1* + ID_OUI_FROM_DATABASE=SHANGHAI SEEYOO ELECTRONIC & TECHNOLOGY CO., LTD + +OUI:0025E2* + ID_OUI_FROM_DATABASE=Everspring Industry Co., Ltd. + +OUI:0025E3* + ID_OUI_FROM_DATABASE=Hanshinit Inc. + +OUI:0025E4* + ID_OUI_FROM_DATABASE=OMNI-WiFi, LLC + +OUI:0025E5* + ID_OUI_FROM_DATABASE=LG Electronics Inc + +OUI:0025E6* + ID_OUI_FROM_DATABASE=Belgian Monitoring Systems bvba + +OUI:0025E7* + ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications + +OUI:0025E8* + ID_OUI_FROM_DATABASE=Idaho Technology + +OUI:0025E9* + ID_OUI_FROM_DATABASE=i-mate Development, Inc. + +OUI:0025EA* + ID_OUI_FROM_DATABASE=Iphion BV + +OUI:0025EB* + ID_OUI_FROM_DATABASE=Reutech Radar Systems (PTY) Ltd + +OUI:0025EC* + ID_OUI_FROM_DATABASE=Humanware + +OUI:0025ED* + ID_OUI_FROM_DATABASE=NuVo Technologies LLC + +OUI:0025EE* + ID_OUI_FROM_DATABASE=Avtex Ltd + +OUI:0025EF* + ID_OUI_FROM_DATABASE=I-TEC Co., Ltd. + +OUI:0025F0* + ID_OUI_FROM_DATABASE=Suga Electronics Limited + +OUI:0025F1* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:0025F2* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:0025F3* + ID_OUI_FROM_DATABASE=Nordwestdeutsche Zählerrevision + +OUI:0025F4* + ID_OUI_FROM_DATABASE=KoCo Connector AG + +OUI:0025F5* + ID_OUI_FROM_DATABASE=DVS Korea, Co., Ltd + +OUI:0025F6* + ID_OUI_FROM_DATABASE=netTALK.com, Inc. + +OUI:0025F7* + ID_OUI_FROM_DATABASE=Ansaldo STS USA + +OUI:0025F9* + ID_OUI_FROM_DATABASE=GMK electronic design GmbH + +OUI:0025FA* + ID_OUI_FROM_DATABASE=J&M Analytik AG + +OUI:0025FB* + ID_OUI_FROM_DATABASE=Tunstall Healthcare A/S + +OUI:0025FC* + ID_OUI_FROM_DATABASE=ENDA ENDUSTRIYEL ELEKTRONIK LTD. STI. + +OUI:0025FD* + ID_OUI_FROM_DATABASE=OBR Centrum Techniki Morskiej S.A. + +OUI:0025FE* + ID_OUI_FROM_DATABASE=Pilot Electronics Corporation + +OUI:0025FF* + ID_OUI_FROM_DATABASE=CreNova Technology GmbH + +OUI:002600* + ID_OUI_FROM_DATABASE=TEAC Australia Pty Ltd. + +OUI:002601* + ID_OUI_FROM_DATABASE=Cutera Inc + +OUI:002602* + ID_OUI_FROM_DATABASE=SMART Temps LLC + +OUI:002603* + ID_OUI_FROM_DATABASE=Shenzhen Wistar Technology Co., Ltd + +OUI:002604* + ID_OUI_FROM_DATABASE=Audio Processing Technology Ltd + +OUI:002605* + ID_OUI_FROM_DATABASE=CC Systems AB + +OUI:002606* + ID_OUI_FROM_DATABASE=RAUMFELD GmbH + +OUI:002607* + ID_OUI_FROM_DATABASE=Enabling Technology Pty Ltd + +OUI:002608* + ID_OUI_FROM_DATABASE=Apple, Inc + +OUI:002609* + ID_OUI_FROM_DATABASE=Phyllis Co., Ltd. + +OUI:00260A* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00260B* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00260C* + ID_OUI_FROM_DATABASE=Dataram + +OUI:00260D* + ID_OUI_FROM_DATABASE=Micronetics, Inc. + +OUI:00260E* + ID_OUI_FROM_DATABASE=Ablaze Systems, LLC + +OUI:00260F* + ID_OUI_FROM_DATABASE=Linn Products Ltd + +OUI:002610* + ID_OUI_FROM_DATABASE=Apacewave Technologies + +OUI:002611* + ID_OUI_FROM_DATABASE=Licera AB + +OUI:002612* + ID_OUI_FROM_DATABASE=Space Exploration Technologies + +OUI:002613* + ID_OUI_FROM_DATABASE=Engel Axil S.L. + +OUI:002614* + ID_OUI_FROM_DATABASE=KTNF + +OUI:002615* + ID_OUI_FROM_DATABASE=Teracom Limited + +OUI:002616* + ID_OUI_FROM_DATABASE=Rosemount Inc. + +OUI:002617* + ID_OUI_FROM_DATABASE=OEM Worldwide + +OUI:002618* + ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. + +OUI:002619* + ID_OUI_FROM_DATABASE=FRC + +OUI:00261A* + ID_OUI_FROM_DATABASE=Femtocomm System Technology Corp. + +OUI:00261B* + ID_OUI_FROM_DATABASE=LAUREL BANK MACHINES CO., LTD. + +OUI:00261C* + ID_OUI_FROM_DATABASE=NEOVIA INC. + +OUI:00261D* + ID_OUI_FROM_DATABASE=COP SECURITY SYSTEM CORP. + +OUI:00261E* + ID_OUI_FROM_DATABASE=QINGBANG ELEC(SZ) CO., LTD + +OUI:00261F* + ID_OUI_FROM_DATABASE=SAE Magnetics (H.K.) Ltd. + +OUI:002620* + ID_OUI_FROM_DATABASE=ISGUS GmbH + +OUI:002621* + ID_OUI_FROM_DATABASE=InteliCloud Technology Inc. + +OUI:002622* + ID_OUI_FROM_DATABASE=COMPAL INFORMATION (KUNSHAN) CO., LTD. + +OUI:002623* + ID_OUI_FROM_DATABASE=JRD Communication Inc + +OUI:002624* + ID_OUI_FROM_DATABASE=Thomson Inc. + +OUI:002625* + ID_OUI_FROM_DATABASE=MediaSputnik + +OUI:002626* + ID_OUI_FROM_DATABASE=Geophysical Survey Systems, Inc. + +OUI:002627* + ID_OUI_FROM_DATABASE=Truesell + +OUI:002628* + ID_OUI_FROM_DATABASE=companytec automação e controle ltda. + +OUI:002629* + ID_OUI_FROM_DATABASE=Juphoon System Software Inc. + +OUI:00262A* + ID_OUI_FROM_DATABASE=Proxense, LLC + +OUI:00262B* + ID_OUI_FROM_DATABASE=Wongs Electronics Co. Ltd. + +OUI:00262C* + ID_OUI_FROM_DATABASE=IKT Advanced Technologies s.r.o. + +OUI:00262D* + ID_OUI_FROM_DATABASE=Wistron Corporation + +OUI:00262E* + ID_OUI_FROM_DATABASE=Chengdu Jiuzhou Electronic Technology Inc + +OUI:00262F* + ID_OUI_FROM_DATABASE=HAMAMATSU TOA ELECTRONICS + +OUI:002630* + ID_OUI_FROM_DATABASE=ACOREL S.A.S + +OUI:002631* + ID_OUI_FROM_DATABASE=COMMTACT LTD + +OUI:002632* + ID_OUI_FROM_DATABASE=Instrumentation Technologies d.d. + +OUI:002633* + ID_OUI_FROM_DATABASE=MIR - Medical International Research + +OUI:002634* + ID_OUI_FROM_DATABASE=Infineta Systems, Inc + +OUI:002635* + ID_OUI_FROM_DATABASE=Bluetechnix GmbH + +OUI:002636* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:002637* + ID_OUI_FROM_DATABASE=Samsung Electro-Mechanics + +OUI:002638* + ID_OUI_FROM_DATABASE=Xia Men Joyatech Co., Ltd. + +OUI:002639* + ID_OUI_FROM_DATABASE=T.M. Electronics, Inc. + +OUI:00263A* + ID_OUI_FROM_DATABASE=Digitec Systems + +OUI:00263B* + ID_OUI_FROM_DATABASE=Onbnetech + +OUI:00263C* + ID_OUI_FROM_DATABASE=Bachmann GmbH & Co. KG + +OUI:00263D* + ID_OUI_FROM_DATABASE=MIA Corporation + +OUI:00263E* + ID_OUI_FROM_DATABASE=Trapeze Networks + +OUI:00263F* + ID_OUI_FROM_DATABASE=LIOS Technology GmbH + +OUI:002640* + ID_OUI_FROM_DATABASE=Baustem Broadband Technologies, Ltd. + +OUI:002641* + ID_OUI_FROM_DATABASE=Motorola, Inc + +OUI:002642* + ID_OUI_FROM_DATABASE=Motorola, Inc + +OUI:002643* + ID_OUI_FROM_DATABASE=Alps Electric Co., Ltd + +OUI:002644* + ID_OUI_FROM_DATABASE=Thomson Telecom Belgium + +OUI:002645* + ID_OUI_FROM_DATABASE=Circontrol S.A. + +OUI:002646* + ID_OUI_FROM_DATABASE=SHENYANG TONGFANG MULTIMEDIA TECHNOLOGY COMPANY LIMITED + +OUI:002647* + ID_OUI_FROM_DATABASE=WFE TECHNOLOGY CORP. + +OUI:002648* + ID_OUI_FROM_DATABASE=Emitech Corp. + +OUI:00264A* + ID_OUI_FROM_DATABASE=Apple, Inc + +OUI:00264C* + ID_OUI_FROM_DATABASE=Shanghai DigiVision Technology Co., Ltd. + +OUI:00264D* + ID_OUI_FROM_DATABASE=Arcadyan Technology Corporation + +OUI:00264E* + ID_OUI_FROM_DATABASE=Rail & Road Protec GmbH + +OUI:00264F* + ID_OUI_FROM_DATABASE=Krüger &Gothe GmbH + +OUI:002650* + ID_OUI_FROM_DATABASE=2Wire + +OUI:002651* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:002652* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:002653* + ID_OUI_FROM_DATABASE=DaySequerra Corporation + +OUI:002654* + ID_OUI_FROM_DATABASE=3Com Corporation + +OUI:002655* + ID_OUI_FROM_DATABASE=Hewlett-Packard Company + +OUI:002656* + ID_OUI_FROM_DATABASE=Sansonic Electronics USA + +OUI:002657* + ID_OUI_FROM_DATABASE=OOO NPP EKRA + +OUI:002658* + ID_OUI_FROM_DATABASE=T-Platforms (Cyprus) Limited + +OUI:002659* + ID_OUI_FROM_DATABASE=Nintendo Co., Ltd. + +OUI:00265A* + ID_OUI_FROM_DATABASE=D-Link Corporation + +OUI:00265B* + ID_OUI_FROM_DATABASE=Hitron Technologies. Inc + +OUI:00265C* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + +OUI:00265D* + ID_OUI_FROM_DATABASE=Samsung Electronics + +OUI:00265E* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + +OUI:00265F* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:002660* + ID_OUI_FROM_DATABASE=Logiways + +OUI:002661* + ID_OUI_FROM_DATABASE=Irumtek Co., Ltd. + +OUI:002662* + ID_OUI_FROM_DATABASE=Actiontec Electronics, Inc + +OUI:002663* + ID_OUI_FROM_DATABASE=Shenzhen Huitaiwei Tech. Ltd, co. + +OUI:002664* + ID_OUI_FROM_DATABASE=Core System Japan + +OUI:002665* + ID_OUI_FROM_DATABASE=ProtectedLogic Corporation + +OUI:002666* + ID_OUI_FROM_DATABASE=EFM Networks + +OUI:002667* + ID_OUI_FROM_DATABASE=CARECOM CO.,LTD. + +OUI:002668* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:002669* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:00266A* + ID_OUI_FROM_DATABASE=ESSENSIUM NV + +OUI:00266B* + ID_OUI_FROM_DATABASE=SHINE UNION ENTERPRISE LIMITED + +OUI:00266C* + ID_OUI_FROM_DATABASE=Inventec + +OUI:00266D* + ID_OUI_FROM_DATABASE=MobileAccess Networks + +OUI:00266E* + ID_OUI_FROM_DATABASE=Nissho-denki Co.,LTD. + +OUI:00266F* + ID_OUI_FROM_DATABASE=Coordiwise Technology Corp. + +OUI:002670* + ID_OUI_FROM_DATABASE=Cinch Connectors + +OUI:002671* + ID_OUI_FROM_DATABASE=AUTOVISION Co., Ltd + +OUI:002672* + ID_OUI_FROM_DATABASE=AAMP of America + +OUI:002673* + ID_OUI_FROM_DATABASE=RICOH COMPANY LTD. + +OUI:002674* + ID_OUI_FROM_DATABASE=Electronic Solutions, Inc. + +OUI:002675* + ID_OUI_FROM_DATABASE=Aztech Electronics Pte Ltd + +OUI:002676* + ID_OUI_FROM_DATABASE=COMMidt AS + +OUI:002677* + ID_OUI_FROM_DATABASE=DEIF A/S + +OUI:002678* + ID_OUI_FROM_DATABASE=Logic Instrument SA + +OUI:002679* + ID_OUI_FROM_DATABASE=Euphonic Technologies, Inc. + +OUI:00267A* + ID_OUI_FROM_DATABASE=wuhan hongxin telecommunication technologies co.,ltd + +OUI:00267B* + ID_OUI_FROM_DATABASE=GSI Helmholtzzentrum für Schwerionenforschung GmbH + +OUI:00267C* + ID_OUI_FROM_DATABASE=Metz-Werke GmbH & Co KG + +OUI:00267D* + ID_OUI_FROM_DATABASE=A-Max Technology Macao Commercial Offshore Company Limited + +OUI:00267E* + ID_OUI_FROM_DATABASE=Parrot SA + +OUI:00267F* + ID_OUI_FROM_DATABASE=Zenterio AB + +OUI:002680* + ID_OUI_FROM_DATABASE=Lockie Innovation Pty Ltd + +OUI:002681* + ID_OUI_FROM_DATABASE=Interspiro AB + +OUI:002682* + ID_OUI_FROM_DATABASE=Gemtek Technology Co., Ltd. + +OUI:002683* + ID_OUI_FROM_DATABASE=Ajoho Enterprise Co., Ltd. + +OUI:002684* + ID_OUI_FROM_DATABASE=KISAN SYSTEM + +OUI:002685* + ID_OUI_FROM_DATABASE=Digital Innovation + +OUI:002686* + ID_OUI_FROM_DATABASE=Quantenna Communcations, Inc. + +OUI:002687* + ID_OUI_FROM_DATABASE=ALLIED TELESIS, K.K corega division. + +OUI:002688* + ID_OUI_FROM_DATABASE=Juniper Networks + +OUI:002689* + ID_OUI_FROM_DATABASE=General Dynamics Robotic Systems + +OUI:00268A* + ID_OUI_FROM_DATABASE=Terrier SC Ltd + +OUI:00268B* + ID_OUI_FROM_DATABASE=Guangzhou Escene Computer Technology Limited + +OUI:00268C* + ID_OUI_FROM_DATABASE=StarLeaf Ltd. + +OUI:00268D* + ID_OUI_FROM_DATABASE=CellTel S.p.A. + +OUI:00268E* + ID_OUI_FROM_DATABASE=Alta Solutions, Inc. + +OUI:00268F* + ID_OUI_FROM_DATABASE=MTA SpA + +OUI:002690* + ID_OUI_FROM_DATABASE=I DO IT + +OUI:002691* + ID_OUI_FROM_DATABASE=SAGEM COMMUNICATION + +OUI:002692* + ID_OUI_FROM_DATABASE=Mitsubishi Electric Co. + +OUI:002693* + ID_OUI_FROM_DATABASE=QVidium Technologies, Inc. + +OUI:002694* + ID_OUI_FROM_DATABASE=Senscient Ltd + +OUI:002695* + ID_OUI_FROM_DATABASE=ZT Group Int'l Inc + +OUI:002696* + ID_OUI_FROM_DATABASE=NOOLIX Co., Ltd + +OUI:002697* + ID_OUI_FROM_DATABASE=Cheetah Technologies, L.P. + +OUI:002698* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:002699* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00269A* + ID_OUI_FROM_DATABASE=carina system co., ltd. + +OUI:00269B* + ID_OUI_FROM_DATABASE=SOKRAT Ltd. + +OUI:00269C* + ID_OUI_FROM_DATABASE=ITUS JAPAN CO. LTD + +OUI:00269D* + ID_OUI_FROM_DATABASE=M2Mnet Co., Ltd. + +OUI:00269E* + ID_OUI_FROM_DATABASE=Quanta Computer Inc + +OUI:0026A0* + ID_OUI_FROM_DATABASE=moblic + +OUI:0026A1* + ID_OUI_FROM_DATABASE=Megger + +OUI:0026A2* + ID_OUI_FROM_DATABASE=Instrumentation Technology Systems + +OUI:0026A3* + ID_OUI_FROM_DATABASE=FQ Ingenieria Electronica S.A. + +OUI:0026A4* + ID_OUI_FROM_DATABASE=Novus Produtos Eletronicos Ltda + +OUI:0026A5* + ID_OUI_FROM_DATABASE=MICROROBOT.CO.,LTD + +OUI:0026A6* + ID_OUI_FROM_DATABASE=TRIXELL + +OUI:0026A7* + ID_OUI_FROM_DATABASE=CONNECT SRL + +OUI:0026A8* + ID_OUI_FROM_DATABASE=DAEHAP HYPER-TECH + +OUI:0026A9* + ID_OUI_FROM_DATABASE=Strong Technologies Pty Ltd + +OUI:0026AA* + ID_OUI_FROM_DATABASE=Kenmec Mechanical Engineering Co., Ltd. + +OUI:0026AB* + ID_OUI_FROM_DATABASE=SEIKO EPSON CORPORATION + +OUI:0026AC* + ID_OUI_FROM_DATABASE=Shanghai LUSTER Teraband photonic Co., Ltd. + +OUI:0026AD* + ID_OUI_FROM_DATABASE=Arada Systems, Inc. + +OUI:0026AE* + ID_OUI_FROM_DATABASE=Wireless Measurement Ltd + +OUI:0026AF* + ID_OUI_FROM_DATABASE=Duelco A/S + +OUI:0026B0* + ID_OUI_FROM_DATABASE=Apple, Inc + +OUI:0026B1* + ID_OUI_FROM_DATABASE=Navis Auto Motive Systems, Inc. + +OUI:0026B2* + ID_OUI_FROM_DATABASE=Setrix AG + +OUI:0026B3* + ID_OUI_FROM_DATABASE=Thales Communications Inc + +OUI:0026B4* + ID_OUI_FROM_DATABASE=Ford Motor Company + +OUI:0026B5* + ID_OUI_FROM_DATABASE=ICOMM Tele Ltd + +OUI:0026B6* + ID_OUI_FROM_DATABASE=Askey Computer + +OUI:0026B7* + ID_OUI_FROM_DATABASE=Kingston Technology Company, Inc. + +OUI:0026B8* + ID_OUI_FROM_DATABASE=Actiontec Electronics, Inc + +OUI:0026B9* + ID_OUI_FROM_DATABASE=Dell Inc + +OUI:0026BA* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:0026BB* + ID_OUI_FROM_DATABASE=Apple, Inc + +OUI:0026BC* + ID_OUI_FROM_DATABASE=General Jack Technology Ltd. + +OUI:0026BD* + ID_OUI_FROM_DATABASE=JTEC Card & Communication Co., Ltd. + +OUI:0026BE* + ID_OUI_FROM_DATABASE=Schoonderbeek Elektronica Systemen B.V. + +OUI:0026BF* + ID_OUI_FROM_DATABASE=ShenZhen Temobi Science&Tech Development Co.,Ltd + +OUI:0026C0* + ID_OUI_FROM_DATABASE=EnergyHub + +OUI:0026C1* + ID_OUI_FROM_DATABASE=ARTRAY CO., LTD. + +OUI:0026C2* + ID_OUI_FROM_DATABASE=SCDI Co. LTD + +OUI:0026C3* + ID_OUI_FROM_DATABASE=Insightek Corp. + +OUI:0026C4* + ID_OUI_FROM_DATABASE=Cadmos microsystems S.r.l. + +OUI:0026C5* + ID_OUI_FROM_DATABASE=Guangdong Gosun Telecommunications Co.,Ltd + +OUI:0026C6* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:0026C7* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:0026C8* + ID_OUI_FROM_DATABASE=System Sensor + +OUI:0026C9* + ID_OUI_FROM_DATABASE=Proventix Systems, Inc. + +OUI:0026CA* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0026CB* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0026CC* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:0026CD* + ID_OUI_FROM_DATABASE=PurpleComm, Inc. + +OUI:0026CE* + ID_OUI_FROM_DATABASE=Kozumi USA Corp. + +OUI:0026CF* + ID_OUI_FROM_DATABASE=DEKA R&D + +OUI:0026D0* + ID_OUI_FROM_DATABASE=Semihalf + +OUI:0026D1* + ID_OUI_FROM_DATABASE=S Squared Innovations Inc. + +OUI:0026D2* + ID_OUI_FROM_DATABASE=Pcube Systems, Inc. + +OUI:0026D3* + ID_OUI_FROM_DATABASE=Zeno Information System + +OUI:0026D4* + ID_OUI_FROM_DATABASE=IRCA SpA + +OUI:0026D5* + ID_OUI_FROM_DATABASE=Ory Solucoes em Comercio de Informatica Ltda. + +OUI:0026D6* + ID_OUI_FROM_DATABASE=Ningbo Andy Optoelectronic Co., Ltd. + +OUI:0026D7* + ID_OUI_FROM_DATABASE=Xiamen BB Electron & Technology Co., Ltd. + +OUI:0026D8* + ID_OUI_FROM_DATABASE=Magic Point Inc. + +OUI:0026D9* + ID_OUI_FROM_DATABASE=Pace plc + +OUI:0026DA* + ID_OUI_FROM_DATABASE=Universal Media Corporation /Slovakia/ s.r.o. + +OUI:0026DB* + ID_OUI_FROM_DATABASE=Ionics EMS Inc. + +OUI:0026DC* + ID_OUI_FROM_DATABASE=Optical Systems Design + +OUI:0026DD* + ID_OUI_FROM_DATABASE=Fival Corporation + +OUI:0026DE* + ID_OUI_FROM_DATABASE=FDI MATELEC + +OUI:0026DF* + ID_OUI_FROM_DATABASE=TaiDoc Technology Corp. + +OUI:0026E0* + ID_OUI_FROM_DATABASE=ASITEQ + +OUI:0026E1* + ID_OUI_FROM_DATABASE=Stanford University, OpenFlow Group + +OUI:0026E2* + ID_OUI_FROM_DATABASE=LG Electronics + +OUI:0026E3* + ID_OUI_FROM_DATABASE=DTI + +OUI:0026E4* + ID_OUI_FROM_DATABASE=CANAL OVERSEAS + +OUI:0026E5* + ID_OUI_FROM_DATABASE=AEG Power Solutions + +OUI:0026E6* + ID_OUI_FROM_DATABASE=Visionhitech Co., Ltd. + +OUI:0026E7* + ID_OUI_FROM_DATABASE=Shanghai ONLAN Communication Tech. Co., Ltd. + +OUI:0026E8* + ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd. + +OUI:0026E9* + ID_OUI_FROM_DATABASE=SP Corp + +OUI:0026EA* + ID_OUI_FROM_DATABASE=Cheerchip Electronic Technology (ShangHai) Co., Ltd. + +OUI:0026EB* + ID_OUI_FROM_DATABASE=Advanced Spectrum Technology Co., Ltd. + +OUI:0026EC* + ID_OUI_FROM_DATABASE=Legrand Home Systems, Inc + +OUI:0026ED* + ID_OUI_FROM_DATABASE=zte corporation + +OUI:0026EE* + ID_OUI_FROM_DATABASE=TKM GmbH + +OUI:0026EF* + ID_OUI_FROM_DATABASE=Technology Advancement Group, Inc. + +OUI:0026F0* + ID_OUI_FROM_DATABASE=cTrixs International GmbH. + +OUI:0026F1* + ID_OUI_FROM_DATABASE=ProCurve Networking by HP + +OUI:0026F2* + ID_OUI_FROM_DATABASE=Netgear + +OUI:0026F3* + ID_OUI_FROM_DATABASE=SMC Networks + +OUI:0026F4* + ID_OUI_FROM_DATABASE=Nesslab + +OUI:0026F5* + ID_OUI_FROM_DATABASE=XRPLUS Inc. + +OUI:0026F6* + ID_OUI_FROM_DATABASE=Military Communication Institute + +OUI:0026F7* + ID_OUI_FROM_DATABASE=Infosys Technologies Ltd. + +OUI:0026F8* + ID_OUI_FROM_DATABASE=Golden Highway Industry Development Co., Ltd. + +OUI:0026F9* + ID_OUI_FROM_DATABASE=S.E.M. srl + +OUI:0026FA* + ID_OUI_FROM_DATABASE=BandRich Inc. + +OUI:0026FB* + ID_OUI_FROM_DATABASE=AirDio Wireless, Inc. + +OUI:0026FC* + ID_OUI_FROM_DATABASE=AcSiP Technology Corp. + +OUI:0026FD* + ID_OUI_FROM_DATABASE=Interactive Intelligence + +OUI:0026FE* + ID_OUI_FROM_DATABASE=MKD Technology Inc. + +OUI:0026FF* + ID_OUI_FROM_DATABASE=Research In Motion + +OUI:002700* + ID_OUI_FROM_DATABASE=Shenzhen Siglent Technology Co., Ltd. + +OUI:002701* + ID_OUI_FROM_DATABASE=INCOstartec GmbH + +OUI:002702* + ID_OUI_FROM_DATABASE=SolarEdge Technologies + +OUI:002703* + ID_OUI_FROM_DATABASE=Testech Electronics Pte Ltd + +OUI:002704* + ID_OUI_FROM_DATABASE=Accelerated Concepts, Inc + +OUI:002705* + ID_OUI_FROM_DATABASE=Sectronic + +OUI:002706* + ID_OUI_FROM_DATABASE=YOISYS + +OUI:002707* + ID_OUI_FROM_DATABASE=Lift Complex DS, JSC + +OUI:002708* + ID_OUI_FROM_DATABASE=Nordiag ASA + +OUI:002709* + ID_OUI_FROM_DATABASE=Nintendo Co., Ltd. + +OUI:00270A* + ID_OUI_FROM_DATABASE=IEE S.A. + +OUI:00270B* + ID_OUI_FROM_DATABASE=Adura Technologies + +OUI:00270C* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00270D* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00270E* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:00270F* + ID_OUI_FROM_DATABASE=Envisionnovation Inc + +OUI:002710* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:002711* + ID_OUI_FROM_DATABASE=LanPro Inc + +OUI:002712* + ID_OUI_FROM_DATABASE=MaxVision LLC + +OUI:002713* + ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co., Ltd. + +OUI:002714* + ID_OUI_FROM_DATABASE=Grainmustards, Co,ltd. + +OUI:002715* + ID_OUI_FROM_DATABASE=Rebound Telecom. Co., Ltd + +OUI:002716* + ID_OUI_FROM_DATABASE=Adachi-Syokai Co., Ltd. + +OUI:002717* + ID_OUI_FROM_DATABASE=CE Digital(Zhenjiang)Co.,Ltd + +OUI:002718* + ID_OUI_FROM_DATABASE=Suzhou NEW SEAUNION Video Technology Co.,Ltd + +OUI:002719* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO., LTD. + +OUI:00271A* + ID_OUI_FROM_DATABASE=Geenovo Technology Ltd. + +OUI:00271B* + ID_OUI_FROM_DATABASE=Alec Sicherheitssysteme GmbH + +OUI:00271C* + ID_OUI_FROM_DATABASE=MERCURY CORPORATION + +OUI:00271D* + ID_OUI_FROM_DATABASE=Comba Telecom Systems (China) Ltd. + +OUI:00271E* + ID_OUI_FROM_DATABASE=Xagyl Communications + +OUI:00271F* + ID_OUI_FROM_DATABASE=MIPRO Electronics Co., Ltd + +OUI:002720* + ID_OUI_FROM_DATABASE=NEW-SOL COM + +OUI:002721* + ID_OUI_FROM_DATABASE=Shenzhen Baoan Fenda Industrial Co., Ltd + +OUI:002722* + ID_OUI_FROM_DATABASE=Ubiquiti Networks + +OUI:0027F8* + ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc + +OUI:002A6A* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:002AAF* + ID_OUI_FROM_DATABASE=LARsys-Automation GmbH + +OUI:002D76* + ID_OUI_FROM_DATABASE=TITECH GmbH + +OUI:003000* + ID_OUI_FROM_DATABASE=ALLWELL TECHNOLOGY CORP. + +OUI:003001* + ID_OUI_FROM_DATABASE=SMP + +OUI:003002* + ID_OUI_FROM_DATABASE=Expand Networks + +OUI:003003* + ID_OUI_FROM_DATABASE=Phasys Ltd. + +OUI:003004* + ID_OUI_FROM_DATABASE=LEADTEK RESEARCH INC. + +OUI:003005* + ID_OUI_FROM_DATABASE=Fujitsu Siemens Computers + +OUI:003006* + ID_OUI_FROM_DATABASE=SUPERPOWER COMPUTER + +OUI:003007* + ID_OUI_FROM_DATABASE=OPTI, INC. + +OUI:003008* + ID_OUI_FROM_DATABASE=AVIO DIGITAL, INC. + +OUI:003009* + ID_OUI_FROM_DATABASE=Tachion Networks, Inc. + +OUI:00300A* + ID_OUI_FROM_DATABASE=AZTECH Electronics Pte Ltd + +OUI:00300B* + ID_OUI_FROM_DATABASE=mPHASE Technologies, Inc. + +OUI:00300C* + ID_OUI_FROM_DATABASE=CONGRUENCY, LTD. + +OUI:00300D* + ID_OUI_FROM_DATABASE=MMC Technology, Inc. + +OUI:00300E* + ID_OUI_FROM_DATABASE=Klotz Digital AG + +OUI:00300F* + ID_OUI_FROM_DATABASE=IMT - Information Management T + +OUI:003010* + ID_OUI_FROM_DATABASE=VISIONETICS INTERNATIONAL + +OUI:003011* + ID_OUI_FROM_DATABASE=HMS Industrial Networks + +OUI:003012* + ID_OUI_FROM_DATABASE=DIGITAL ENGINEERING LTD. + +OUI:003013* + ID_OUI_FROM_DATABASE=NEC Corporation + +OUI:003014* + ID_OUI_FROM_DATABASE=DIVIO, INC. + +OUI:003015* + ID_OUI_FROM_DATABASE=CP CLARE CORP. + +OUI:003016* + ID_OUI_FROM_DATABASE=ISHIDA CO., LTD. + +OUI:003017* + ID_OUI_FROM_DATABASE=BlueArc UK Ltd + +OUI:003018* + ID_OUI_FROM_DATABASE=Jetway Information Co., Ltd. + +OUI:003019* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00301A* + ID_OUI_FROM_DATABASE=SMARTBRIDGES PTE. LTD. + +OUI:00301B* + ID_OUI_FROM_DATABASE=SHUTTLE, INC. + +OUI:00301C* + ID_OUI_FROM_DATABASE=ALTVATER AIRDATA SYSTEMS + +OUI:00301D* + ID_OUI_FROM_DATABASE=SKYSTREAM, INC. + +OUI:00301E* + ID_OUI_FROM_DATABASE=3COM Europe Ltd. + +OUI:00301F* + ID_OUI_FROM_DATABASE=OPTICAL NETWORKS, INC. + +OUI:003020* + ID_OUI_FROM_DATABASE=TSI, Inc.. + +OUI:003021* + ID_OUI_FROM_DATABASE=HSING TECH. ENTERPRISE CO.,LTD + +OUI:003022* + ID_OUI_FROM_DATABASE=Fong Kai Industrial Co., Ltd. + +OUI:003023* + ID_OUI_FROM_DATABASE=COGENT COMPUTER SYSTEMS, INC. + +OUI:003024* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:003025* + ID_OUI_FROM_DATABASE=CHECKOUT COMPUTER SYSTEMS, LTD + +OUI:003026* + ID_OUI_FROM_DATABASE=HeiTel Digital Video GmbH + +OUI:003027* + ID_OUI_FROM_DATABASE=KERBANGO, INC. + +OUI:003028* + ID_OUI_FROM_DATABASE=FASE Saldatura srl + +OUI:003029* + ID_OUI_FROM_DATABASE=OPICOM + +OUI:00302A* + ID_OUI_FROM_DATABASE=SOUTHERN INFORMATION + +OUI:00302B* + ID_OUI_FROM_DATABASE=INALP NETWORKS, INC. + +OUI:00302C* + ID_OUI_FROM_DATABASE=SYLANTRO SYSTEMS CORPORATION + +OUI:00302D* + ID_OUI_FROM_DATABASE=QUANTUM BRIDGE COMMUNICATIONS + +OUI:00302E* + ID_OUI_FROM_DATABASE=Hoft & Wessel AG + +OUI:00302F* + ID_OUI_FROM_DATABASE=GE Aviation System + +OUI:003030* + ID_OUI_FROM_DATABASE=HARMONIX CORPORATION + +OUI:003031* + ID_OUI_FROM_DATABASE=LIGHTWAVE COMMUNICATIONS, INC. + +OUI:003032* + ID_OUI_FROM_DATABASE=MagicRam, Inc. + +OUI:003033* + ID_OUI_FROM_DATABASE=ORIENT TELECOM CO., LTD. + +OUI:003034* + ID_OUI_FROM_DATABASE=SET ENGINEERING + +OUI:003035* + ID_OUI_FROM_DATABASE=Corning Incorporated + +OUI:003036* + ID_OUI_FROM_DATABASE=RMP ELEKTRONIKSYSTEME GMBH + +OUI:003037* + ID_OUI_FROM_DATABASE=Packard Bell Nec Services + +OUI:003038* + ID_OUI_FROM_DATABASE=XCP, INC. + +OUI:003039* + ID_OUI_FROM_DATABASE=SOFTBOOK PRESS + +OUI:00303A* + ID_OUI_FROM_DATABASE=MAATEL + +OUI:00303B* + ID_OUI_FROM_DATABASE=PowerCom Technology + +OUI:00303C* + ID_OUI_FROM_DATABASE=ONNTO CORP. + +OUI:00303D* + ID_OUI_FROM_DATABASE=IVA CORPORATION + +OUI:00303E* + ID_OUI_FROM_DATABASE=Radcom Ltd. + +OUI:00303F* + ID_OUI_FROM_DATABASE=TurboComm Tech Inc. + +OUI:003040* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:003041* + ID_OUI_FROM_DATABASE=SAEJIN T & M CO., LTD. + +OUI:003042* + ID_OUI_FROM_DATABASE=DeTeWe-Deutsche Telephonwerke + +OUI:003043* + ID_OUI_FROM_DATABASE=IDREAM TECHNOLOGIES, PTE. LTD. + +OUI:003044* + ID_OUI_FROM_DATABASE=CradlePoint, Inc + +OUI:003045* + ID_OUI_FROM_DATABASE=Village Networks, Inc. (VNI) + +OUI:003046* + ID_OUI_FROM_DATABASE=Controlled Electronic Manageme + +OUI:003047* + ID_OUI_FROM_DATABASE=NISSEI ELECTRIC CO., LTD. + +OUI:003048* + ID_OUI_FROM_DATABASE=Supermicro Computer, Inc. + +OUI:003049* + ID_OUI_FROM_DATABASE=BRYANT TECHNOLOGY, LTD. + +OUI:00304A* + ID_OUI_FROM_DATABASE=Fraunhofer IPMS + +OUI:00304B* + ID_OUI_FROM_DATABASE=ORBACOM SYSTEMS, INC. + +OUI:00304C* + ID_OUI_FROM_DATABASE=APPIAN COMMUNICATIONS, INC. + +OUI:00304D* + ID_OUI_FROM_DATABASE=ESI + +OUI:00304E* + ID_OUI_FROM_DATABASE=BUSTEC PRODUCTION LTD. + +OUI:00304F* + ID_OUI_FROM_DATABASE=PLANET Technology Corporation + +OUI:003050* + ID_OUI_FROM_DATABASE=Versa Technology + +OUI:003051* + ID_OUI_FROM_DATABASE=ORBIT AVIONIC & COMMUNICATION + +OUI:003052* + ID_OUI_FROM_DATABASE=ELASTIC NETWORKS + +OUI:003053* + ID_OUI_FROM_DATABASE=Basler AG + +OUI:003054* + ID_OUI_FROM_DATABASE=CASTLENET TECHNOLOGY, INC. + +OUI:003055* + ID_OUI_FROM_DATABASE=Renesas Technology America, Inc. + +OUI:003056* + ID_OUI_FROM_DATABASE=Beck IPC GmbH + +OUI:003057* + ID_OUI_FROM_DATABASE=QTelNet, Inc. + +OUI:003058* + ID_OUI_FROM_DATABASE=API MOTION + +OUI:003059* + ID_OUI_FROM_DATABASE=KONTRON COMPACT COMPUTERS AG + +OUI:00305A* + ID_OUI_FROM_DATABASE=TELGEN CORPORATION + +OUI:00305B* + ID_OUI_FROM_DATABASE=Toko Inc. + +OUI:00305C* + ID_OUI_FROM_DATABASE=SMAR Laboratories Corp. + +OUI:00305D* + ID_OUI_FROM_DATABASE=DIGITRA SYSTEMS, INC. + +OUI:00305E* + ID_OUI_FROM_DATABASE=Abelko Innovation + +OUI:00305F* + ID_OUI_FROM_DATABASE=Hasselblad + +OUI:003060* + ID_OUI_FROM_DATABASE=Powerfile, Inc. + +OUI:003061* + ID_OUI_FROM_DATABASE=MobyTEL + +OUI:003062* + ID_OUI_FROM_DATABASE=PATH 1 NETWORK TECHNOL'S INC. + +OUI:003063* + ID_OUI_FROM_DATABASE=SANTERA SYSTEMS, INC. + +OUI:003064* + ID_OUI_FROM_DATABASE=ADLINK TECHNOLOGY, INC. + +OUI:003065* + ID_OUI_FROM_DATABASE=APPLE COMPUTER, INC. + +OUI:003066* + ID_OUI_FROM_DATABASE=RFM + +OUI:003067* + ID_OUI_FROM_DATABASE=BIOSTAR MICROTECH INT'L CORP. + +OUI:003068* + ID_OUI_FROM_DATABASE=CYBERNETICS TECH. CO., LTD. + +OUI:003069* + ID_OUI_FROM_DATABASE=IMPACCT TECHNOLOGY CORP. + +OUI:00306A* + ID_OUI_FROM_DATABASE=PENTA MEDIA CO., LTD. + +OUI:00306B* + ID_OUI_FROM_DATABASE=CMOS SYSTEMS, INC. + +OUI:00306C* + ID_OUI_FROM_DATABASE=Hitex Holding GmbH + +OUI:00306D* + ID_OUI_FROM_DATABASE=LUCENT TECHNOLOGIES + +OUI:00306E* + ID_OUI_FROM_DATABASE=HEWLETT PACKARD + +OUI:00306F* + ID_OUI_FROM_DATABASE=SEYEON TECH. CO., LTD. + +OUI:003070* + ID_OUI_FROM_DATABASE=1Net Corporation + +OUI:003071* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:003072* + ID_OUI_FROM_DATABASE=Intellibyte Inc. + +OUI:003073* + ID_OUI_FROM_DATABASE=International Microsystems, In + +OUI:003074* + ID_OUI_FROM_DATABASE=EQUIINET LTD. + +OUI:003075* + ID_OUI_FROM_DATABASE=ADTECH + +OUI:003076* + ID_OUI_FROM_DATABASE=Akamba Corporation + +OUI:003077* + ID_OUI_FROM_DATABASE=ONPREM NETWORKS + +OUI:003078* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:003079* + ID_OUI_FROM_DATABASE=CQOS, INC. + +OUI:00307A* + ID_OUI_FROM_DATABASE=Advanced Technology & Systems + +OUI:00307B* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00307C* + ID_OUI_FROM_DATABASE=ADID SA + +OUI:00307D* + ID_OUI_FROM_DATABASE=GRE AMERICA, INC. + +OUI:00307E* + ID_OUI_FROM_DATABASE=Redflex Communication Systems + +OUI:00307F* + ID_OUI_FROM_DATABASE=IRLAN LTD. + +OUI:003080* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:003081* + ID_OUI_FROM_DATABASE=ALTOS C&C + +OUI:003082* + ID_OUI_FROM_DATABASE=TAIHAN ELECTRIC WIRE CO., LTD. + +OUI:003083* + ID_OUI_FROM_DATABASE=Ivron Systems + +OUI:003084* + ID_OUI_FROM_DATABASE=ALLIED TELESYN INTERNAIONAL + +OUI:003085* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:003086* + ID_OUI_FROM_DATABASE=Transistor Devices, Inc. + +OUI:003087* + ID_OUI_FROM_DATABASE=VEGA GRIESHABER KG + +OUI:003088* + ID_OUI_FROM_DATABASE=Ericsson + +OUI:003089* + ID_OUI_FROM_DATABASE=Spectrapoint Wireless, LLC + +OUI:00308A* + ID_OUI_FROM_DATABASE=NICOTRA SISTEMI S.P.A + +OUI:00308B* + ID_OUI_FROM_DATABASE=Brix Networks + +OUI:00308C* + ID_OUI_FROM_DATABASE=Quantum Corporation + +OUI:00308D* + ID_OUI_FROM_DATABASE=Pinnacle Systems, Inc. + +OUI:00308E* + ID_OUI_FROM_DATABASE=CROSS MATCH TECHNOLOGIES, INC. + +OUI:00308F* + ID_OUI_FROM_DATABASE=MICRILOR, Inc. + +OUI:003090* + ID_OUI_FROM_DATABASE=CYRA TECHNOLOGIES, INC. + +OUI:003091* + ID_OUI_FROM_DATABASE=TAIWAN FIRST LINE ELEC. CORP. + +OUI:003092* + ID_OUI_FROM_DATABASE=ModuNORM GmbH + +OUI:003093* + ID_OUI_FROM_DATABASE=Sonnet Technologies, Inc + +OUI:003094* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:003095* + ID_OUI_FROM_DATABASE=Procomp Informatics, Ltd. + +OUI:003096* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:003097* + ID_OUI_FROM_DATABASE=AB Regin + +OUI:003098* + ID_OUI_FROM_DATABASE=Global Converging Technologies + +OUI:003099* + ID_OUI_FROM_DATABASE=BOENIG UND KALLENBACH OHG + +OUI:00309A* + ID_OUI_FROM_DATABASE=ASTRO TERRA CORP. + +OUI:00309B* + ID_OUI_FROM_DATABASE=Smartware + +OUI:00309C* + ID_OUI_FROM_DATABASE=Timing Applications, Inc. + +OUI:00309D* + ID_OUI_FROM_DATABASE=Nimble Microsystems, Inc. + +OUI:00309E* + ID_OUI_FROM_DATABASE=WORKBIT CORPORATION. + +OUI:00309F* + ID_OUI_FROM_DATABASE=AMBER NETWORKS + +OUI:0030A0* + ID_OUI_FROM_DATABASE=TYCO SUBMARINE SYSTEMS, LTD. + +OUI:0030A1* + ID_OUI_FROM_DATABASE=WEBGATE Inc. + +OUI:0030A2* + ID_OUI_FROM_DATABASE=Lightner Engineering + +OUI:0030A3* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0030A4* + ID_OUI_FROM_DATABASE=Woodwind Communications System + +OUI:0030A5* + ID_OUI_FROM_DATABASE=ACTIVE POWER + +OUI:0030A6* + ID_OUI_FROM_DATABASE=VIANET TECHNOLOGIES, LTD. + +OUI:0030A7* + ID_OUI_FROM_DATABASE=SCHWEITZER ENGINEERING + +OUI:0030A8* + ID_OUI_FROM_DATABASE=OL'E COMMUNICATIONS, INC. + +OUI:0030A9* + ID_OUI_FROM_DATABASE=Netiverse, Inc. + +OUI:0030AA* + ID_OUI_FROM_DATABASE=AXUS MICROSYSTEMS, INC. + +OUI:0030AB* + ID_OUI_FROM_DATABASE=DELTA NETWORKS, INC. + +OUI:0030AC* + ID_OUI_FROM_DATABASE=Systeme Lauer GmbH & Co., Ltd. + +OUI:0030AD* + ID_OUI_FROM_DATABASE=SHANGHAI COMMUNICATION + +OUI:0030AE* + ID_OUI_FROM_DATABASE=Times N System, Inc. + +OUI:0030AF* + ID_OUI_FROM_DATABASE=Honeywell GmbH + +OUI:0030B0* + ID_OUI_FROM_DATABASE=Convergenet Technologies + +OUI:0030B1* + ID_OUI_FROM_DATABASE=TrunkNet + +OUI:0030B2* + ID_OUI_FROM_DATABASE=L-3 Sonoma EO + +OUI:0030B3* + ID_OUI_FROM_DATABASE=San Valley Systems, Inc. + +OUI:0030B4* + ID_OUI_FROM_DATABASE=INTERSIL CORP. + +OUI:0030B5* + ID_OUI_FROM_DATABASE=Tadiran Microwave Networks + +OUI:0030B6* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0030B7* + ID_OUI_FROM_DATABASE=Teletrol Systems, Inc. + +OUI:0030B8* + ID_OUI_FROM_DATABASE=RiverDelta Networks + +OUI:0030B9* + ID_OUI_FROM_DATABASE=ECTEL + +OUI:0030BA* + ID_OUI_FROM_DATABASE=AC&T SYSTEM CO., LTD. + +OUI:0030BB* + ID_OUI_FROM_DATABASE=CacheFlow, Inc. + +OUI:0030BC* + ID_OUI_FROM_DATABASE=Optronic AG + +OUI:0030BD* + ID_OUI_FROM_DATABASE=BELKIN COMPONENTS + +OUI:0030BE* + ID_OUI_FROM_DATABASE=City-Net Technology, Inc. + +OUI:0030BF* + ID_OUI_FROM_DATABASE=MULTIDATA GMBH + +OUI:0030C0* + ID_OUI_FROM_DATABASE=Lara Technology, Inc. + +OUI:0030C1* + ID_OUI_FROM_DATABASE=HEWLETT-PACKARD + +OUI:0030C2* + ID_OUI_FROM_DATABASE=COMONE + +OUI:0030C3* + ID_OUI_FROM_DATABASE=FLUECKIGER ELEKTRONIK AG + +OUI:0030C4* + ID_OUI_FROM_DATABASE=Canon Imaging Systems Inc. + +OUI:0030C5* + ID_OUI_FROM_DATABASE=CADENCE DESIGN SYSTEMS + +OUI:0030C6* + ID_OUI_FROM_DATABASE=CONTROL SOLUTIONS, INC. + +OUI:0030C7* + ID_OUI_FROM_DATABASE=Macromate Corp. + +OUI:0030C8* + ID_OUI_FROM_DATABASE=GAD LINE, LTD. + +OUI:0030C9* + ID_OUI_FROM_DATABASE=LuxN, N + +OUI:0030CA* + ID_OUI_FROM_DATABASE=Discovery Com + +OUI:0030CB* + ID_OUI_FROM_DATABASE=OMNI FLOW COMPUTERS, INC. + +OUI:0030CC* + ID_OUI_FROM_DATABASE=Tenor Networks, Inc. + +OUI:0030CD* + ID_OUI_FROM_DATABASE=CONEXANT SYSTEMS, INC. + +OUI:0030CE* + ID_OUI_FROM_DATABASE=Zaffire + +OUI:0030CF* + ID_OUI_FROM_DATABASE=TWO TECHNOLOGIES, INC. + +OUI:0030D0* + ID_OUI_FROM_DATABASE=Tellabs + +OUI:0030D1* + ID_OUI_FROM_DATABASE=INOVA CORPORATION + +OUI:0030D2* + ID_OUI_FROM_DATABASE=WIN TECHNOLOGIES, CO., LTD. + +OUI:0030D3* + ID_OUI_FROM_DATABASE=Agilent Technologies + +OUI:0030D4* + ID_OUI_FROM_DATABASE=AAE Systems, Inc + +OUI:0030D5* + ID_OUI_FROM_DATABASE=DResearch GmbH + +OUI:0030D6* + ID_OUI_FROM_DATABASE=MSC VERTRIEBS GMBH + +OUI:0030D7* + ID_OUI_FROM_DATABASE=Innovative Systems, L.L.C. + +OUI:0030D8* + ID_OUI_FROM_DATABASE=SITEK + +OUI:0030D9* + ID_OUI_FROM_DATABASE=DATACORE SOFTWARE CORP. + +OUI:0030DA* + ID_OUI_FROM_DATABASE=COMTREND CO. + +OUI:0030DB* + ID_OUI_FROM_DATABASE=Mindready Solutions, Inc. + +OUI:0030DC* + ID_OUI_FROM_DATABASE=RIGHTECH CORPORATION + +OUI:0030DD* + ID_OUI_FROM_DATABASE=INDIGITA CORPORATION + +OUI:0030DE* + ID_OUI_FROM_DATABASE=WAGO Kontakttechnik GmbH + +OUI:0030DF* + ID_OUI_FROM_DATABASE=KB/TEL TELECOMUNICACIONES + +OUI:0030E0* + ID_OUI_FROM_DATABASE=OXFORD SEMICONDUCTOR LTD. + +OUI:0030E1* + ID_OUI_FROM_DATABASE=Network Equipment Technologies, Inc. + +OUI:0030E2* + ID_OUI_FROM_DATABASE=GARNET SYSTEMS CO., LTD. + +OUI:0030E3* + ID_OUI_FROM_DATABASE=SEDONA NETWORKS CORP. + +OUI:0030E4* + ID_OUI_FROM_DATABASE=CHIYODA SYSTEM RIKEN + +OUI:0030E5* + ID_OUI_FROM_DATABASE=Amper Datos S.A. + +OUI:0030E6* + ID_OUI_FROM_DATABASE=Draeger Medical Systems, Inc. + +OUI:0030E7* + ID_OUI_FROM_DATABASE=CNF MOBILE SOLUTIONS, INC. + +OUI:0030E8* + ID_OUI_FROM_DATABASE=ENSIM CORP. + +OUI:0030E9* + ID_OUI_FROM_DATABASE=GMA COMMUNICATION MANUFACT'G + +OUI:0030EA* + ID_OUI_FROM_DATABASE=TeraForce Technology Corporation + +OUI:0030EB* + ID_OUI_FROM_DATABASE=TURBONET COMMUNICATIONS, INC. + +OUI:0030EC* + ID_OUI_FROM_DATABASE=BORGARDT + +OUI:0030ED* + ID_OUI_FROM_DATABASE=Expert Magnetics Corp. + +OUI:0030EE* + ID_OUI_FROM_DATABASE=DSG Technology, Inc. + +OUI:0030EF* + ID_OUI_FROM_DATABASE=NEON TECHNOLOGY, INC. + +OUI:0030F0* + ID_OUI_FROM_DATABASE=Uniform Industrial Corp. + +OUI:0030F1* + ID_OUI_FROM_DATABASE=Accton Technology Corp. + +OUI:0030F2* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0030F3* + ID_OUI_FROM_DATABASE=At Work Computers + +OUI:0030F4* + ID_OUI_FROM_DATABASE=STARDOT TECHNOLOGIES + +OUI:0030F5* + ID_OUI_FROM_DATABASE=Wild Lab. Ltd. + +OUI:0030F6* + ID_OUI_FROM_DATABASE=SECURELOGIX CORPORATION + +OUI:0030F7* + ID_OUI_FROM_DATABASE=RAMIX INC. + +OUI:0030F8* + ID_OUI_FROM_DATABASE=Dynapro Systems, Inc. + +OUI:0030F9* + ID_OUI_FROM_DATABASE=Sollae Systems Co., Ltd. + +OUI:0030FA* + ID_OUI_FROM_DATABASE=TELICA, INC. + +OUI:0030FB* + ID_OUI_FROM_DATABASE=AZS Technology AG + +OUI:0030FC* + ID_OUI_FROM_DATABASE=Terawave Communications, Inc. + +OUI:0030FD* + ID_OUI_FROM_DATABASE=INTEGRATED SYSTEMS DESIGN + +OUI:0030FE* + ID_OUI_FROM_DATABASE=DSA GmbH + +OUI:0030FF* + ID_OUI_FROM_DATABASE=DATAFAB SYSTEMS, INC. + +OUI:00336C* + ID_OUI_FROM_DATABASE=SynapSense Corporation + +OUI:0034F1* + ID_OUI_FROM_DATABASE=Radicom Research, Inc. + +OUI:003532* + ID_OUI_FROM_DATABASE=Electro-Metrics Corporation + +OUI:0036F8* + ID_OUI_FROM_DATABASE=Conti Temic microelectronic GmbH + +OUI:0036FE* + ID_OUI_FROM_DATABASE=SuperVision + +OUI:00376D* + ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd. + +OUI:003A98* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:003A99* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:003A9A* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:003A9B* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:003A9C* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:003A9D* + ID_OUI_FROM_DATABASE=NEC AccessTechnica, Ltd. + +OUI:003AAF* + ID_OUI_FROM_DATABASE=BlueBit Ltd. + +OUI:003CC5* + ID_OUI_FROM_DATABASE=WONWOO Engineering Co., Ltd + +OUI:003D41* + ID_OUI_FROM_DATABASE=Hatteland Computer AS + +OUI:003EE1* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:004000* + ID_OUI_FROM_DATABASE=PCI COMPONENTES DA AMZONIA LTD + +OUI:004001* + ID_OUI_FROM_DATABASE=Zero One Technology Co. Ltd. + +OUI:004002* + ID_OUI_FROM_DATABASE=PERLE SYSTEMS LIMITED + +OUI:004003* + ID_OUI_FROM_DATABASE=Emerson Process Management Power & Water Solutions, Inc. + +OUI:004004* + ID_OUI_FROM_DATABASE=ICM CO. LTD. + +OUI:004005* + ID_OUI_FROM_DATABASE=ANI COMMUNICATIONS INC. + +OUI:004006* + ID_OUI_FROM_DATABASE=SAMPO TECHNOLOGY CORPORATION + +OUI:004007* + ID_OUI_FROM_DATABASE=TELMAT INFORMATIQUE + +OUI:004008* + ID_OUI_FROM_DATABASE=A PLUS INFO CORPORATION + +OUI:004009* + ID_OUI_FROM_DATABASE=TACHIBANA TECTRON CO., LTD. + +OUI:00400A* + ID_OUI_FROM_DATABASE=PIVOTAL TECHNOLOGIES, INC. + +OUI:00400B* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00400C* + ID_OUI_FROM_DATABASE=GENERAL MICRO SYSTEMS, INC. + +OUI:00400D* + ID_OUI_FROM_DATABASE=LANNET DATA COMMUNICATIONS,LTD + +OUI:00400E* + ID_OUI_FROM_DATABASE=MEMOTEC, INC. + +OUI:00400F* + ID_OUI_FROM_DATABASE=DATACOM TECHNOLOGIES + +OUI:004010* + ID_OUI_FROM_DATABASE=SONIC SYSTEMS, INC. + +OUI:004011* + ID_OUI_FROM_DATABASE=ANDOVER CONTROLS CORPORATION + +OUI:004012* + ID_OUI_FROM_DATABASE=WINDATA, INC. + +OUI:004013* + ID_OUI_FROM_DATABASE=NTT DATA COMM. SYSTEMS CORP. + +OUI:004014* + ID_OUI_FROM_DATABASE=COMSOFT GMBH + +OUI:004015* + ID_OUI_FROM_DATABASE=ASCOM INFRASYS AG + +OUI:004016* + ID_OUI_FROM_DATABASE=ADC - Global Connectivity Solutions Division + +OUI:004017* + ID_OUI_FROM_DATABASE=Silex Technology America + +OUI:004018* + ID_OUI_FROM_DATABASE=ADOBE SYSTEMS, INC. + +OUI:004019* + ID_OUI_FROM_DATABASE=AEON SYSTEMS, INC. + +OUI:00401A* + ID_OUI_FROM_DATABASE=FUJI ELECTRIC CO., LTD. + +OUI:00401B* + ID_OUI_FROM_DATABASE=PRINTER SYSTEMS CORP. + +OUI:00401C* + ID_OUI_FROM_DATABASE=AST RESEARCH, INC. + +OUI:00401D* + ID_OUI_FROM_DATABASE=INVISIBLE SOFTWARE, INC. + +OUI:00401E* + ID_OUI_FROM_DATABASE=ICC + +OUI:00401F* + ID_OUI_FROM_DATABASE=COLORGRAPH LTD + +OUI:004020* + ID_OUI_FROM_DATABASE=TE Connectivity Ltd. + +OUI:004021* + ID_OUI_FROM_DATABASE=RASTER GRAPHICS + +OUI:004022* + ID_OUI_FROM_DATABASE=KLEVER COMPUTERS, INC. + +OUI:004023* + ID_OUI_FROM_DATABASE=LOGIC CORPORATION + +OUI:004024* + ID_OUI_FROM_DATABASE=COMPAC INC. + +OUI:004025* + ID_OUI_FROM_DATABASE=MOLECULAR DYNAMICS + +OUI:004026* + ID_OUI_FROM_DATABASE=Buffalo, Inc + +OUI:004027* + ID_OUI_FROM_DATABASE=SMC MASSACHUSETTS, INC. + +OUI:004028* + ID_OUI_FROM_DATABASE=NETCOMM LIMITED + +OUI:004029* + ID_OUI_FROM_DATABASE=COMPEX + +OUI:00402A* + ID_OUI_FROM_DATABASE=CANOGA-PERKINS + +OUI:00402B* + ID_OUI_FROM_DATABASE=TRIGEM COMPUTER, INC. + +OUI:00402C* + ID_OUI_FROM_DATABASE=ISIS DISTRIBUTED SYSTEMS, INC. + +OUI:00402D* + ID_OUI_FROM_DATABASE=HARRIS ADACOM CORPORATION + +OUI:00402E* + ID_OUI_FROM_DATABASE=PRECISION SOFTWARE, INC. + +OUI:00402F* + ID_OUI_FROM_DATABASE=XLNT DESIGNS INC. + +OUI:004030* + ID_OUI_FROM_DATABASE=GK COMPUTER + +OUI:004031* + ID_OUI_FROM_DATABASE=KOKUSAI ELECTRIC CO., LTD + +OUI:004032* + ID_OUI_FROM_DATABASE=DIGITAL COMMUNICATIONS + +OUI:004033* + ID_OUI_FROM_DATABASE=ADDTRON TECHNOLOGY CO., LTD. + +OUI:004034* + ID_OUI_FROM_DATABASE=BUSTEK CORPORATION + +OUI:004035* + ID_OUI_FROM_DATABASE=OPCOM + +OUI:004036* + ID_OUI_FROM_DATABASE=TRIBE COMPUTER WORKS, INC. + +OUI:004037* + ID_OUI_FROM_DATABASE=SEA-ILAN, INC. + +OUI:004038* + ID_OUI_FROM_DATABASE=TALENT ELECTRIC INCORPORATED + +OUI:004039* + ID_OUI_FROM_DATABASE=OPTEC DAIICHI DENKO CO., LTD. + +OUI:00403A* + ID_OUI_FROM_DATABASE=IMPACT TECHNOLOGIES + +OUI:00403B* + ID_OUI_FROM_DATABASE=SYNERJET INTERNATIONAL CORP. + +OUI:00403C* + ID_OUI_FROM_DATABASE=FORKS, INC. + +OUI:00403D* + ID_OUI_FROM_DATABASE=Teradata Corporation + +OUI:00403E* + ID_OUI_FROM_DATABASE=RASTER OPS CORPORATION + +OUI:00403F* + ID_OUI_FROM_DATABASE=SSANGYONG COMPUTER SYSTEMS + +OUI:004040* + ID_OUI_FROM_DATABASE=RING ACCESS, INC. + +OUI:004041* + ID_OUI_FROM_DATABASE=FUJIKURA LTD. + +OUI:004042* + ID_OUI_FROM_DATABASE=N.A.T. GMBH + +OUI:004043* + ID_OUI_FROM_DATABASE=Nokia Siemens Networks GmbH & Co. KG. + +OUI:004044* + ID_OUI_FROM_DATABASE=QNIX COMPUTER CO., LTD. + +OUI:004045* + ID_OUI_FROM_DATABASE=TWINHEAD CORPORATION + +OUI:004046* + ID_OUI_FROM_DATABASE=UDC RESEARCH LIMITED + +OUI:004047* + ID_OUI_FROM_DATABASE=WIND RIVER SYSTEMS + +OUI:004048* + ID_OUI_FROM_DATABASE=SMD INFORMATICA S.A. + +OUI:004049* + ID_OUI_FROM_DATABASE=Roche Diagnostics Ltd. + +OUI:00404A* + ID_OUI_FROM_DATABASE=WEST AUSTRALIAN DEPARTMENT + +OUI:00404B* + ID_OUI_FROM_DATABASE=MAPLE COMPUTER SYSTEMS + +OUI:00404C* + ID_OUI_FROM_DATABASE=HYPERTEC PTY LTD. + +OUI:00404D* + ID_OUI_FROM_DATABASE=TELECOMMUNICATIONS TECHNIQUES + +OUI:00404E* + ID_OUI_FROM_DATABASE=FLUENT, INC. + +OUI:00404F* + ID_OUI_FROM_DATABASE=SPACE & NAVAL WARFARE SYSTEMS + +OUI:004050* + ID_OUI_FROM_DATABASE=IRONICS, INCORPORATED + +OUI:004051* + ID_OUI_FROM_DATABASE=GRACILIS, INC. + +OUI:004052* + ID_OUI_FROM_DATABASE=STAR TECHNOLOGIES, INC. + +OUI:004053* + ID_OUI_FROM_DATABASE=AMPRO COMPUTERS + +OUI:004054* + ID_OUI_FROM_DATABASE=CONNECTION MACHINES SERVICES + +OUI:004055* + ID_OUI_FROM_DATABASE=METRONIX GMBH + +OUI:004056* + ID_OUI_FROM_DATABASE=MCM JAPAN LTD. + +OUI:004057* + ID_OUI_FROM_DATABASE=LOCKHEED - SANDERS + +OUI:004058* + ID_OUI_FROM_DATABASE=KRONOS, INC. + +OUI:004059* + ID_OUI_FROM_DATABASE=YOSHIDA KOGYO K. K. + +OUI:00405A* + ID_OUI_FROM_DATABASE=GOLDSTAR INFORMATION & COMM. + +OUI:00405B* + ID_OUI_FROM_DATABASE=FUNASSET LIMITED + +OUI:00405C* + ID_OUI_FROM_DATABASE=FUTURE SYSTEMS, INC. + +OUI:00405D* + ID_OUI_FROM_DATABASE=STAR-TEK, INC. + +OUI:00405E* + ID_OUI_FROM_DATABASE=NORTH HILLS ISRAEL + +OUI:00405F* + ID_OUI_FROM_DATABASE=AFE COMPUTERS LTD. + +OUI:004060* + ID_OUI_FROM_DATABASE=COMENDEC LTD + +OUI:004061* + ID_OUI_FROM_DATABASE=DATATECH ENTERPRISES CO., LTD. + +OUI:004062* + ID_OUI_FROM_DATABASE=E-SYSTEMS, INC./GARLAND DIV. + +OUI:004063* + ID_OUI_FROM_DATABASE=VIA TECHNOLOGIES, INC. + +OUI:004064* + ID_OUI_FROM_DATABASE=KLA INSTRUMENTS CORPORATION + +OUI:004065* + ID_OUI_FROM_DATABASE=GTE SPACENET + +OUI:004066* + ID_OUI_FROM_DATABASE=HITACHI CABLE, LTD. + +OUI:004067* + ID_OUI_FROM_DATABASE=OMNIBYTE CORPORATION + +OUI:004068* + ID_OUI_FROM_DATABASE=EXTENDED SYSTEMS + +OUI:004069* + ID_OUI_FROM_DATABASE=LEMCOM SYSTEMS, INC. + +OUI:00406A* + ID_OUI_FROM_DATABASE=KENTEK INFORMATION SYSTEMS,INC + +OUI:00406B* + ID_OUI_FROM_DATABASE=SYSGEN + +OUI:00406C* + ID_OUI_FROM_DATABASE=COPERNIQUE + +OUI:00406D* + ID_OUI_FROM_DATABASE=LANCO, INC. + +OUI:00406E* + ID_OUI_FROM_DATABASE=COROLLARY, INC. + +OUI:00406F* + ID_OUI_FROM_DATABASE=SYNC RESEARCH INC. + +OUI:004070* + ID_OUI_FROM_DATABASE=INTERWARE CO., LTD. + +OUI:004071* + ID_OUI_FROM_DATABASE=ATM COMPUTER GMBH + +OUI:004072* + ID_OUI_FROM_DATABASE=Applied Innovation Inc. + +OUI:004073* + ID_OUI_FROM_DATABASE=BASS ASSOCIATES + +OUI:004074* + ID_OUI_FROM_DATABASE=CABLE AND WIRELESS + +OUI:004075* + ID_OUI_FROM_DATABASE=Tattile SRL + +OUI:004076* + ID_OUI_FROM_DATABASE=Sun Conversion Technologies + +OUI:004077* + ID_OUI_FROM_DATABASE=MAXTON TECHNOLOGY CORPORATION + +OUI:004078* + ID_OUI_FROM_DATABASE=WEARNES AUTOMATION PTE LTD + +OUI:004079* + ID_OUI_FROM_DATABASE=JUKO MANUFACTURE COMPANY, LTD. + +OUI:00407A* + ID_OUI_FROM_DATABASE=SOCIETE D'EXPLOITATION DU CNIT + +OUI:00407B* + ID_OUI_FROM_DATABASE=SCIENTIFIC ATLANTA + +OUI:00407C* + ID_OUI_FROM_DATABASE=QUME CORPORATION + +OUI:00407D* + ID_OUI_FROM_DATABASE=EXTENSION TECHNOLOGY CORP. + +OUI:00407E* + ID_OUI_FROM_DATABASE=EVERGREEN SYSTEMS, INC. + +OUI:00407F* + ID_OUI_FROM_DATABASE=FLIR Systems + +OUI:004080* + ID_OUI_FROM_DATABASE=ATHENIX CORPORATION + +OUI:004081* + ID_OUI_FROM_DATABASE=MANNESMANN SCANGRAPHIC GMBH + +OUI:004082* + ID_OUI_FROM_DATABASE=LABORATORY EQUIPMENT CORP. + +OUI:004083* + ID_OUI_FROM_DATABASE=TDA INDUSTRIA DE PRODUTOS + +OUI:004084* + ID_OUI_FROM_DATABASE=HONEYWELL ACS + +OUI:004085* + ID_OUI_FROM_DATABASE=SAAB INSTRUMENTS AB + +OUI:004086* + ID_OUI_FROM_DATABASE=MICHELS & KLEBERHOFF COMPUTER + +OUI:004087* + ID_OUI_FROM_DATABASE=UBITREX CORPORATION + +OUI:004088* + ID_OUI_FROM_DATABASE=MOBIUS TECHNOLOGIES, INC. + +OUI:004089* + ID_OUI_FROM_DATABASE=MEIDENSHA CORPORATION + +OUI:00408A* + ID_OUI_FROM_DATABASE=TPS TELEPROCESSING SYS. GMBH + +OUI:00408B* + ID_OUI_FROM_DATABASE=RAYLAN CORPORATION + +OUI:00408C* + ID_OUI_FROM_DATABASE=AXIS COMMUNICATIONS AB + +OUI:00408D* + ID_OUI_FROM_DATABASE=THE GOODYEAR TIRE & RUBBER CO. + +OUI:00408E* + ID_OUI_FROM_DATABASE=Tattile SRL + +OUI:00408F* + ID_OUI_FROM_DATABASE=WM-DATA MINFO AB + +OUI:004090* + ID_OUI_FROM_DATABASE=ANSEL COMMUNICATIONS + +OUI:004091* + ID_OUI_FROM_DATABASE=PROCOMP INDUSTRIA ELETRONICA + +OUI:004092* + ID_OUI_FROM_DATABASE=ASP COMPUTER PRODUCTS, INC. + +OUI:004093* + ID_OUI_FROM_DATABASE=PAXDATA NETWORKS LTD. + +OUI:004094* + ID_OUI_FROM_DATABASE=SHOGRAPHICS, INC. + +OUI:004095* + ID_OUI_FROM_DATABASE=R.P.T. INTERGROUPS INT'L LTD. + +OUI:004096* + ID_OUI_FROM_DATABASE=Cisco Systems, Inc. + +OUI:004097* + ID_OUI_FROM_DATABASE=DATEX DIVISION OF + +OUI:004098* + ID_OUI_FROM_DATABASE=DRESSLER GMBH & CO. + +OUI:004099* + ID_OUI_FROM_DATABASE=NEWGEN SYSTEMS CORP. + +OUI:00409A* + ID_OUI_FROM_DATABASE=NETWORK EXPRESS, INC. + +OUI:00409B* + ID_OUI_FROM_DATABASE=HAL COMPUTER SYSTEMS INC. + +OUI:00409C* + ID_OUI_FROM_DATABASE=TRANSWARE + +OUI:00409D* + ID_OUI_FROM_DATABASE=DIGIBOARD, INC. + +OUI:00409E* + ID_OUI_FROM_DATABASE=CONCURRENT TECHNOLOGIES LTD. + +OUI:00409F* + ID_OUI_FROM_DATABASE=Telco Systems, Inc. + +OUI:0040A0* + ID_OUI_FROM_DATABASE=GOLDSTAR CO., LTD. + +OUI:0040A1* + ID_OUI_FROM_DATABASE=ERGO COMPUTING + +OUI:0040A2* + ID_OUI_FROM_DATABASE=KINGSTAR TECHNOLOGY INC. + +OUI:0040A3* + ID_OUI_FROM_DATABASE=MICROUNITY SYSTEMS ENGINEERING + +OUI:0040A4* + ID_OUI_FROM_DATABASE=ROSE ELECTRONICS + +OUI:0040A5* + ID_OUI_FROM_DATABASE=CLINICOMP INTL. + +OUI:0040A6* + ID_OUI_FROM_DATABASE=Cray, Inc. + +OUI:0040A7* + ID_OUI_FROM_DATABASE=ITAUTEC PHILCO S.A. + +OUI:0040A8* + ID_OUI_FROM_DATABASE=IMF INTERNATIONAL LTD. + +OUI:0040A9* + ID_OUI_FROM_DATABASE=DATACOM INC. + +OUI:0040AA* + ID_OUI_FROM_DATABASE=VALMET AUTOMATION INC. + +OUI:0040AB* + ID_OUI_FROM_DATABASE=ROLAND DG CORPORATION + +OUI:0040AC* + ID_OUI_FROM_DATABASE=SUPER WORKSTATION, INC. + +OUI:0040AD* + ID_OUI_FROM_DATABASE=SMA REGELSYSTEME GMBH + +OUI:0040AE* + ID_OUI_FROM_DATABASE=DELTA CONTROLS, INC. + +OUI:0040AF* + ID_OUI_FROM_DATABASE=DIGITAL PRODUCTS, INC. + +OUI:0040B0* + ID_OUI_FROM_DATABASE=BYTEX CORPORATION, ENGINEERING + +OUI:0040B1* + ID_OUI_FROM_DATABASE=CODONICS INC. + +OUI:0040B2* + ID_OUI_FROM_DATABASE=SYSTEMFORSCHUNG + +OUI:0040B3* + ID_OUI_FROM_DATABASE=ParTech Inc. + +OUI:0040B4* + ID_OUI_FROM_DATABASE=NEXTCOM K.K. + +OUI:0040B5* + ID_OUI_FROM_DATABASE=VIDEO TECHNOLOGY COMPUTERS LTD + +OUI:0040B6* + ID_OUI_FROM_DATABASE=COMPUTERM CORPORATION + +OUI:0040B7* + ID_OUI_FROM_DATABASE=STEALTH COMPUTER SYSTEMS + +OUI:0040B8* + ID_OUI_FROM_DATABASE=IDEA ASSOCIATES + +OUI:0040B9* + ID_OUI_FROM_DATABASE=MACQ ELECTRONIQUE SA + +OUI:0040BA* + ID_OUI_FROM_DATABASE=ALLIANT COMPUTER SYSTEMS CORP. + +OUI:0040BB* + ID_OUI_FROM_DATABASE=GOLDSTAR CABLE CO., LTD. + +OUI:0040BC* + ID_OUI_FROM_DATABASE=ALGORITHMICS LTD. + +OUI:0040BD* + ID_OUI_FROM_DATABASE=STARLIGHT NETWORKS, INC. + +OUI:0040BE* + ID_OUI_FROM_DATABASE=BOEING DEFENSE & SPACE + +OUI:0040BF* + ID_OUI_FROM_DATABASE=CHANNEL SYSTEMS INTERN'L INC. + +OUI:0040C0* + ID_OUI_FROM_DATABASE=VISTA CONTROLS CORPORATION + +OUI:0040C1* + ID_OUI_FROM_DATABASE=BIZERBA-WERKE WILHEIM KRAUT + +OUI:0040C2* + ID_OUI_FROM_DATABASE=APPLIED COMPUTING DEVICES + +OUI:0040C3* + ID_OUI_FROM_DATABASE=FISCHER AND PORTER CO. + +OUI:0040C4* + ID_OUI_FROM_DATABASE=KINKEI SYSTEM CORPORATION + +OUI:0040C5* + ID_OUI_FROM_DATABASE=MICOM COMMUNICATIONS INC. + +OUI:0040C6* + ID_OUI_FROM_DATABASE=FIBERNET RESEARCH, INC. + +OUI:0040C7* + ID_OUI_FROM_DATABASE=RUBY TECH CORPORATION + +OUI:0040C8* + ID_OUI_FROM_DATABASE=MILAN TECHNOLOGY CORPORATION + +OUI:0040C9* + ID_OUI_FROM_DATABASE=NCUBE + +OUI:0040CA* + ID_OUI_FROM_DATABASE=FIRST INTERNAT'L COMPUTER, INC + +OUI:0040CB* + ID_OUI_FROM_DATABASE=LANWAN TECHNOLOGIES + +OUI:0040CC* + ID_OUI_FROM_DATABASE=SILCOM MANUF'G TECHNOLOGY INC. + +OUI:0040CD* + ID_OUI_FROM_DATABASE=TERA MICROSYSTEMS, INC. + +OUI:0040CE* + ID_OUI_FROM_DATABASE=NET-SOURCE, INC. + +OUI:0040CF* + ID_OUI_FROM_DATABASE=STRAWBERRY TREE, INC. + +OUI:0040D0* + ID_OUI_FROM_DATABASE=MITAC INTERNATIONAL CORP. + +OUI:0040D1* + ID_OUI_FROM_DATABASE=FUKUDA DENSHI CO., LTD. + +OUI:0040D2* + ID_OUI_FROM_DATABASE=PAGINE CORPORATION + +OUI:0040D3* + ID_OUI_FROM_DATABASE=KIMPSION INTERNATIONAL CORP. + +OUI:0040D4* + ID_OUI_FROM_DATABASE=GAGE TALKER CORP. + +OUI:0040D5* + ID_OUI_FROM_DATABASE=Sartorius Mechatronics T&H GmbH + +OUI:0040D6* + ID_OUI_FROM_DATABASE=LOCAMATION B.V. + +OUI:0040D7* + ID_OUI_FROM_DATABASE=STUDIO GEN INC. + +OUI:0040D8* + ID_OUI_FROM_DATABASE=OCEAN OFFICE AUTOMATION LTD. + +OUI:0040D9* + ID_OUI_FROM_DATABASE=AMERICAN MEGATRENDS INC. + +OUI:0040DA* + ID_OUI_FROM_DATABASE=TELSPEC LTD + +OUI:0040DB* + ID_OUI_FROM_DATABASE=ADVANCED TECHNICAL SOLUTIONS + +OUI:0040DC* + ID_OUI_FROM_DATABASE=TRITEC ELECTRONIC GMBH + +OUI:0040DD* + ID_OUI_FROM_DATABASE=HONG TECHNOLOGIES + +OUI:0040DE* + ID_OUI_FROM_DATABASE=Elsag Datamat spa + +OUI:0040DF* + ID_OUI_FROM_DATABASE=DIGALOG SYSTEMS, INC. + +OUI:0040E0* + ID_OUI_FROM_DATABASE=ATOMWIDE LTD. + +OUI:0040E1* + ID_OUI_FROM_DATABASE=MARNER INTERNATIONAL, INC. + +OUI:0040E2* + ID_OUI_FROM_DATABASE=MESA RIDGE TECHNOLOGIES, INC. + +OUI:0040E3* + ID_OUI_FROM_DATABASE=QUIN SYSTEMS LTD + +OUI:0040E4* + ID_OUI_FROM_DATABASE=E-M TECHNOLOGY, INC. + +OUI:0040E5* + ID_OUI_FROM_DATABASE=SYBUS CORPORATION + +OUI:0040E6* + ID_OUI_FROM_DATABASE=C.A.E.N. + +OUI:0040E7* + ID_OUI_FROM_DATABASE=ARNOS INSTRUMENTS & COMPUTER + +OUI:0040E8* + ID_OUI_FROM_DATABASE=CHARLES RIVER DATA SYSTEMS,INC + +OUI:0040E9* + ID_OUI_FROM_DATABASE=ACCORD SYSTEMS, INC. + +OUI:0040EA* + ID_OUI_FROM_DATABASE=PLAIN TREE SYSTEMS INC + +OUI:0040EB* + ID_OUI_FROM_DATABASE=MARTIN MARIETTA CORPORATION + +OUI:0040EC* + ID_OUI_FROM_DATABASE=MIKASA SYSTEM ENGINEERING + +OUI:0040ED* + ID_OUI_FROM_DATABASE=NETWORK CONTROLS INT'NATL INC. + +OUI:0040EE* + ID_OUI_FROM_DATABASE=OPTIMEM + +OUI:0040EF* + ID_OUI_FROM_DATABASE=HYPERCOM, INC. + +OUI:0040F0* + ID_OUI_FROM_DATABASE=MicroBrain,Inc. + +OUI:0040F1* + ID_OUI_FROM_DATABASE=CHUO ELECTRONICS CO., LTD. + +OUI:0040F2* + ID_OUI_FROM_DATABASE=JANICH & KLASS COMPUTERTECHNIK + +OUI:0040F3* + ID_OUI_FROM_DATABASE=NETCOR + +OUI:0040F4* + ID_OUI_FROM_DATABASE=CAMEO COMMUNICATIONS, INC. + +OUI:0040F5* + ID_OUI_FROM_DATABASE=OEM ENGINES + +OUI:0040F6* + ID_OUI_FROM_DATABASE=KATRON COMPUTERS INC. + +OUI:0040F7* + ID_OUI_FROM_DATABASE=Polaroid Corporation + +OUI:0040F8* + ID_OUI_FROM_DATABASE=SYSTEMHAUS DISCOM + +OUI:0040F9* + ID_OUI_FROM_DATABASE=COMBINET + +OUI:0040FA* + ID_OUI_FROM_DATABASE=MICROBOARDS, INC. + +OUI:0040FB* + ID_OUI_FROM_DATABASE=CASCADE COMMUNICATIONS CORP. + +OUI:0040FC* + ID_OUI_FROM_DATABASE=IBR COMPUTER TECHNIK GMBH + +OUI:0040FD* + ID_OUI_FROM_DATABASE=LXE + +OUI:0040FE* + ID_OUI_FROM_DATABASE=SYMPLEX COMMUNICATIONS + +OUI:0040FF* + ID_OUI_FROM_DATABASE=TELEBIT CORPORATION + +OUI:0041B4* + ID_OUI_FROM_DATABASE=Wuxi Zhongxing Optoelectronics Technology Co.,Ltd. + +OUI:004252* + ID_OUI_FROM_DATABASE=RLX Technologies + +OUI:0043FF* + ID_OUI_FROM_DATABASE=KETRON S.R.L. + +OUI:004501* + ID_OUI_FROM_DATABASE=Versus Technology, Inc. + +OUI:00464B* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +OUI:004D32* + ID_OUI_FROM_DATABASE=Andon Health Co.,Ltd. + +OUI:005000* + ID_OUI_FROM_DATABASE=NEXO COMMUNICATIONS, INC. + +OUI:005001* + ID_OUI_FROM_DATABASE=YAMASHITA SYSTEMS CORP. + +OUI:005002* + ID_OUI_FROM_DATABASE=OMNISEC AG + +OUI:005003* + ID_OUI_FROM_DATABASE=Xrite Inc + +OUI:005004* + ID_OUI_FROM_DATABASE=3COM CORPORATION + +OUI:005006* + ID_OUI_FROM_DATABASE=TAC AB + +OUI:005007* + ID_OUI_FROM_DATABASE=SIEMENS TELECOMMUNICATION SYSTEMS LIMITED + +OUI:005008* + ID_OUI_FROM_DATABASE=TIVA MICROCOMPUTER CORP. (TMC) + +OUI:005009* + ID_OUI_FROM_DATABASE=PHILIPS BROADBAND NETWORKS + +OUI:00500A* + ID_OUI_FROM_DATABASE=IRIS TECHNOLOGIES, INC. + +OUI:00500B* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00500C* + ID_OUI_FROM_DATABASE=e-Tek Labs, Inc. + +OUI:00500D* + ID_OUI_FROM_DATABASE=SATORI ELECTORIC CO., LTD. + +OUI:00500E* + ID_OUI_FROM_DATABASE=CHROMATIS NETWORKS, INC. + +OUI:00500F* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:005010* + ID_OUI_FROM_DATABASE=NovaNET Learning, Inc. + +OUI:005012* + ID_OUI_FROM_DATABASE=CBL - GMBH + +OUI:005013* + ID_OUI_FROM_DATABASE=Chaparral Network Storage + +OUI:005014* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:005015* + ID_OUI_FROM_DATABASE=BRIGHT STAR ENGINEERING + +OUI:005016* + ID_OUI_FROM_DATABASE=SST/WOODHEAD INDUSTRIES + +OUI:005017* + ID_OUI_FROM_DATABASE=RSR S.R.L. + +OUI:005018* + ID_OUI_FROM_DATABASE=AMIT, Inc. + +OUI:005019* + ID_OUI_FROM_DATABASE=SPRING TIDE NETWORKS, INC. + +OUI:00501A* + ID_OUI_FROM_DATABASE=IQinVision + +OUI:00501B* + ID_OUI_FROM_DATABASE=ABL CANADA, INC. + +OUI:00501C* + ID_OUI_FROM_DATABASE=JATOM SYSTEMS, INC. + +OUI:00501E* + ID_OUI_FROM_DATABASE=Miranda Technologies, Inc. + +OUI:00501F* + ID_OUI_FROM_DATABASE=MRG SYSTEMS, LTD. + +OUI:005020* + ID_OUI_FROM_DATABASE=MEDIASTAR CO., LTD. + +OUI:005021* + ID_OUI_FROM_DATABASE=EIS INTERNATIONAL, INC. + +OUI:005022* + ID_OUI_FROM_DATABASE=ZONET TECHNOLOGY, INC. + +OUI:005023* + ID_OUI_FROM_DATABASE=PG DESIGN ELECTRONICS, INC. + +OUI:005024* + ID_OUI_FROM_DATABASE=NAVIC SYSTEMS, INC. + +OUI:005026* + ID_OUI_FROM_DATABASE=COSYSTEMS, INC. + +OUI:005027* + ID_OUI_FROM_DATABASE=GENICOM CORPORATION + +OUI:005028* + ID_OUI_FROM_DATABASE=AVAL COMMUNICATIONS + +OUI:005029* + ID_OUI_FROM_DATABASE=1394 PRINTER WORKING GROUP + +OUI:00502A* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00502B* + ID_OUI_FROM_DATABASE=GENRAD LTD. + +OUI:00502C* + ID_OUI_FROM_DATABASE=SOYO COMPUTER, INC. + +OUI:00502D* + ID_OUI_FROM_DATABASE=ACCEL, INC. + +OUI:00502E* + ID_OUI_FROM_DATABASE=CAMBEX CORPORATION + +OUI:00502F* + ID_OUI_FROM_DATABASE=TollBridge Technologies, Inc. + +OUI:005030* + ID_OUI_FROM_DATABASE=FUTURE PLUS SYSTEMS + +OUI:005031* + ID_OUI_FROM_DATABASE=AEROFLEX LABORATORIES, INC. + +OUI:005032* + ID_OUI_FROM_DATABASE=PICAZO COMMUNICATIONS, INC. + +OUI:005033* + ID_OUI_FROM_DATABASE=MAYAN NETWORKS + +OUI:005036* + ID_OUI_FROM_DATABASE=NETCAM, LTD. + +OUI:005037* + ID_OUI_FROM_DATABASE=KOGA ELECTRONICS CO. + +OUI:005038* + ID_OUI_FROM_DATABASE=DAIN TELECOM CO., LTD. + +OUI:005039* + ID_OUI_FROM_DATABASE=MARINER NETWORKS + +OUI:00503A* + ID_OUI_FROM_DATABASE=DATONG ELECTRONICS LTD. + +OUI:00503B* + ID_OUI_FROM_DATABASE=MEDIAFIRE CORPORATION + +OUI:00503C* + ID_OUI_FROM_DATABASE=TSINGHUA NOVEL ELECTRONICS + +OUI:00503E* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00503F* + ID_OUI_FROM_DATABASE=ANCHOR GAMES + +OUI:005040* + ID_OUI_FROM_DATABASE=Panasonic Electric Works Co., Ltd. + +OUI:005041* + ID_OUI_FROM_DATABASE=Coretronic Corporation + +OUI:005042* + ID_OUI_FROM_DATABASE=SCI MANUFACTURING SINGAPORE PTE, LTD. + +OUI:005043* + ID_OUI_FROM_DATABASE=MARVELL SEMICONDUCTOR, INC. + +OUI:005044* + ID_OUI_FROM_DATABASE=ASACA CORPORATION + +OUI:005045* + ID_OUI_FROM_DATABASE=RIOWORKS SOLUTIONS, INC. + +OUI:005046* + ID_OUI_FROM_DATABASE=MENICX INTERNATIONAL CO., LTD. + +OUI:005048* + ID_OUI_FROM_DATABASE=INFOLIBRIA + +OUI:005049* + ID_OUI_FROM_DATABASE=Arbor Networks Inc + +OUI:00504A* + ID_OUI_FROM_DATABASE=ELTECO A.S. + +OUI:00504B* + ID_OUI_FROM_DATABASE=BARCONET N.V. + +OUI:00504C* + ID_OUI_FROM_DATABASE=Galil Motion Control + +OUI:00504D* + ID_OUI_FROM_DATABASE=Tokyo Electron Device Limited + +OUI:00504E* + ID_OUI_FROM_DATABASE=SIERRA MONITOR CORP. + +OUI:00504F* + ID_OUI_FROM_DATABASE=OLENCOM ELECTRONICS + +OUI:005050* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:005051* + ID_OUI_FROM_DATABASE=IWATSU ELECTRIC CO., LTD. + +OUI:005052* + ID_OUI_FROM_DATABASE=TIARA NETWORKS, INC. + +OUI:005053* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:005054* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:005055* + ID_OUI_FROM_DATABASE=DOMS A/S + +OUI:005056* + ID_OUI_FROM_DATABASE=VMware, Inc. + +OUI:005057* + ID_OUI_FROM_DATABASE=BROADBAND ACCESS SYSTEMS + +OUI:005058* + ID_OUI_FROM_DATABASE=VegaStream Group Limted + +OUI:005059* + ID_OUI_FROM_DATABASE=iBAHN + +OUI:00505A* + ID_OUI_FROM_DATABASE=NETWORK ALCHEMY, INC. + +OUI:00505B* + ID_OUI_FROM_DATABASE=KAWASAKI LSI U.S.A., INC. + +OUI:00505C* + ID_OUI_FROM_DATABASE=TUNDO CORPORATION + +OUI:00505E* + ID_OUI_FROM_DATABASE=DIGITEK MICROLOGIC S.A. + +OUI:00505F* + ID_OUI_FROM_DATABASE=BRAND INNOVATORS + +OUI:005060* + ID_OUI_FROM_DATABASE=TANDBERG TELECOM AS + +OUI:005062* + ID_OUI_FROM_DATABASE=KOUWELL ELECTRONICS CORP. ** + +OUI:005063* + ID_OUI_FROM_DATABASE=OY COMSEL SYSTEM AB + +OUI:005064* + ID_OUI_FROM_DATABASE=CAE ELECTRONICS + +OUI:005065* + ID_OUI_FROM_DATABASE=TDK-Lambda Corporation + +OUI:005066* + ID_OUI_FROM_DATABASE=AtecoM GmbH advanced telecomunication modules + +OUI:005067* + ID_OUI_FROM_DATABASE=AEROCOMM, INC. + +OUI:005068* + ID_OUI_FROM_DATABASE=ELECTRONIC INDUSTRIES ASSOCIATION + +OUI:005069* + ID_OUI_FROM_DATABASE=PixStream Incorporated + +OUI:00506A* + ID_OUI_FROM_DATABASE=EDEVA, INC. + +OUI:00506B* + ID_OUI_FROM_DATABASE=SPX-ATEG + +OUI:00506C* + ID_OUI_FROM_DATABASE=Beijer Electronics Products AB + +OUI:00506D* + ID_OUI_FROM_DATABASE=VIDEOJET SYSTEMS + +OUI:00506E* + ID_OUI_FROM_DATABASE=CORDER ENGINEERING CORPORATION + +OUI:00506F* + ID_OUI_FROM_DATABASE=G-CONNECT + +OUI:005070* + ID_OUI_FROM_DATABASE=CHAINTECH COMPUTER CO., LTD. + +OUI:005071* + ID_OUI_FROM_DATABASE=AIWA CO., LTD. + +OUI:005072* + ID_OUI_FROM_DATABASE=CORVIS CORPORATION + +OUI:005073* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:005074* + ID_OUI_FROM_DATABASE=ADVANCED HI-TECH CORP. + +OUI:005075* + ID_OUI_FROM_DATABASE=KESTREL SOLUTIONS + +OUI:005076* + ID_OUI_FROM_DATABASE=IBM Corp + +OUI:005077* + ID_OUI_FROM_DATABASE=PROLIFIC TECHNOLOGY, INC. + +OUI:005078* + ID_OUI_FROM_DATABASE=MEGATON HOUSE, LTD. + +OUI:00507A* + ID_OUI_FROM_DATABASE=XPEED, INC. + +OUI:00507B* + ID_OUI_FROM_DATABASE=MERLOT COMMUNICATIONS + +OUI:00507C* + ID_OUI_FROM_DATABASE=VIDEOCON AG + +OUI:00507D* + ID_OUI_FROM_DATABASE=IFP + +OUI:00507E* + ID_OUI_FROM_DATABASE=NEWER TECHNOLOGY + +OUI:00507F* + ID_OUI_FROM_DATABASE=DrayTek Corp. + +OUI:005080* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:005081* + ID_OUI_FROM_DATABASE=MURATA MACHINERY, LTD. + +OUI:005082* + ID_OUI_FROM_DATABASE=FORESSON CORPORATION + +OUI:005083* + ID_OUI_FROM_DATABASE=GILBARCO, INC. + +OUI:005084* + ID_OUI_FROM_DATABASE=ATL PRODUCTS + +OUI:005086* + ID_OUI_FROM_DATABASE=TELKOM SA, LTD. + +OUI:005087* + ID_OUI_FROM_DATABASE=TERASAKI ELECTRIC CO., LTD. + +OUI:005088* + ID_OUI_FROM_DATABASE=AMANO CORPORATION + +OUI:005089* + ID_OUI_FROM_DATABASE=SAFETY MANAGEMENT SYSTEMS + +OUI:00508B* + ID_OUI_FROM_DATABASE=Hewlett-Packard Company + +OUI:00508C* + ID_OUI_FROM_DATABASE=RSI SYSTEMS + +OUI:00508D* + ID_OUI_FROM_DATABASE=ABIT COMPUTER CORPORATION + +OUI:00508E* + ID_OUI_FROM_DATABASE=OPTIMATION, INC. + +OUI:00508F* + ID_OUI_FROM_DATABASE=ASITA TECHNOLOGIES INT'L LTD. + +OUI:005090* + ID_OUI_FROM_DATABASE=DCTRI + +OUI:005091* + ID_OUI_FROM_DATABASE=NETACCESS, INC. + +OUI:005092* + ID_OUI_FROM_DATABASE=RIGAKU INDUSTRIAL CORPORATION + +OUI:005093* + ID_OUI_FROM_DATABASE=BOEING + +OUI:005094* + ID_OUI_FROM_DATABASE=PACE plc + +OUI:005095* + ID_OUI_FROM_DATABASE=PERACOM NETWORKS + +OUI:005096* + ID_OUI_FROM_DATABASE=SALIX TECHNOLOGIES, INC. + +OUI:005097* + ID_OUI_FROM_DATABASE=MMC-EMBEDDED COMPUTERTECHNIK GmbH + +OUI:005098* + ID_OUI_FROM_DATABASE=GLOBALOOP, LTD. + +OUI:005099* + ID_OUI_FROM_DATABASE=3COM EUROPE, LTD. + +OUI:00509A* + ID_OUI_FROM_DATABASE=TAG ELECTRONIC SYSTEMS + +OUI:00509B* + ID_OUI_FROM_DATABASE=SWITCHCORE AB + +OUI:00509C* + ID_OUI_FROM_DATABASE=BETA RESEARCH + +OUI:00509D* + ID_OUI_FROM_DATABASE=THE INDUSTREE B.V. + +OUI:00509E* + ID_OUI_FROM_DATABASE=Les Technologies SoftAcoustik Inc. + +OUI:00509F* + ID_OUI_FROM_DATABASE=HORIZON COMPUTER + +OUI:0050A0* + ID_OUI_FROM_DATABASE=DELTA COMPUTER SYSTEMS, INC. + +OUI:0050A1* + ID_OUI_FROM_DATABASE=CARLO GAVAZZI, INC. + +OUI:0050A2* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0050A3* + ID_OUI_FROM_DATABASE=TransMedia Communications, Inc. + +OUI:0050A4* + ID_OUI_FROM_DATABASE=IO TECH, INC. + +OUI:0050A5* + ID_OUI_FROM_DATABASE=CAPITOL BUSINESS SYSTEMS, LTD. + +OUI:0050A6* + ID_OUI_FROM_DATABASE=OPTRONICS + +OUI:0050A7* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0050A8* + ID_OUI_FROM_DATABASE=OpenCon Systems, Inc. + +OUI:0050A9* + ID_OUI_FROM_DATABASE=MOLDAT WIRELESS TECHNOLGIES + +OUI:0050AA* + ID_OUI_FROM_DATABASE=KONICA MINOLTA HOLDINGS, INC. + +OUI:0050AB* + ID_OUI_FROM_DATABASE=NALTEC, Inc. + +OUI:0050AC* + ID_OUI_FROM_DATABASE=MAPLE COMPUTER CORPORATION + +OUI:0050AD* + ID_OUI_FROM_DATABASE=CommUnique Wireless Corp. + +OUI:0050AE* + ID_OUI_FROM_DATABASE=FDK Co., Ltd + +OUI:0050AF* + ID_OUI_FROM_DATABASE=INTERGON, INC. + +OUI:0050B0* + ID_OUI_FROM_DATABASE=TECHNOLOGY ATLANTA CORPORATION + +OUI:0050B1* + ID_OUI_FROM_DATABASE=GIDDINGS & LEWIS + +OUI:0050B2* + ID_OUI_FROM_DATABASE=BRODEL AUTOMATION + +OUI:0050B3* + ID_OUI_FROM_DATABASE=VOICEBOARD CORPORATION + +OUI:0050B4* + ID_OUI_FROM_DATABASE=SATCHWELL CONTROL SYSTEMS, LTD + +OUI:0050B5* + ID_OUI_FROM_DATABASE=FICHET-BAUCHE + +OUI:0050B6* + ID_OUI_FROM_DATABASE=GOOD WAY IND. CO., LTD. + +OUI:0050B7* + ID_OUI_FROM_DATABASE=BOSER TECHNOLOGY CO., LTD. + +OUI:0050B8* + ID_OUI_FROM_DATABASE=INOVA COMPUTERS GMBH & CO. KG + +OUI:0050B9* + ID_OUI_FROM_DATABASE=XITRON TECHNOLOGIES, INC. + +OUI:0050BA* + ID_OUI_FROM_DATABASE=D-LINK + +OUI:0050BB* + ID_OUI_FROM_DATABASE=CMS TECHNOLOGIES + +OUI:0050BC* + ID_OUI_FROM_DATABASE=HAMMER STORAGE SOLUTIONS + +OUI:0050BD* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0050BE* + ID_OUI_FROM_DATABASE=FAST MULTIMEDIA AG + +OUI:0050BF* + ID_OUI_FROM_DATABASE=Metalligence Technology Corp. + +OUI:0050C0* + ID_OUI_FROM_DATABASE=GATAN, INC. + +OUI:0050C1* + ID_OUI_FROM_DATABASE=GEMFLEX NETWORKS, LTD. + +OUI:0050C4* + ID_OUI_FROM_DATABASE=IMD + +OUI:0050C5* + ID_OUI_FROM_DATABASE=ADS Technologies, Inc + +OUI:0050C6* + ID_OUI_FROM_DATABASE=LOOP TELECOMMUNICATION INTERNATIONAL, INC. + +OUI:0050C8* + ID_OUI_FROM_DATABASE=Addonics Technologies, Inc. + +OUI:0050C9* + ID_OUI_FROM_DATABASE=MASPRO DENKOH CORP. + +OUI:0050CA* + ID_OUI_FROM_DATABASE=NET TO NET TECHNOLOGIES + +OUI:0050CB* + ID_OUI_FROM_DATABASE=JETTER + +OUI:0050CC* + ID_OUI_FROM_DATABASE=XYRATEX + +OUI:0050CD* + ID_OUI_FROM_DATABASE=DIGIANSWER A/S + +OUI:0050CE* + ID_OUI_FROM_DATABASE=LG INTERNATIONAL CORP. + +OUI:0050CF* + ID_OUI_FROM_DATABASE=VANLINK COMMUNICATION TECHNOLOGY RESEARCH INSTITUTE + +OUI:0050D0* + ID_OUI_FROM_DATABASE=MINERVA SYSTEMS + +OUI:0050D1* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0050D2* + ID_OUI_FROM_DATABASE=CMC Electronics Inc + +OUI:0050D3* + ID_OUI_FROM_DATABASE=DIGITAL AUDIO PROCESSING PTY. LTD. + +OUI:0050D4* + ID_OUI_FROM_DATABASE=JOOHONG INFORMATION & + +OUI:0050D5* + ID_OUI_FROM_DATABASE=AD SYSTEMS CORP. + +OUI:0050D6* + ID_OUI_FROM_DATABASE=ATLAS COPCO TOOLS AB + +OUI:0050D7* + ID_OUI_FROM_DATABASE=TELSTRAT + +OUI:0050D8* + ID_OUI_FROM_DATABASE=UNICORN COMPUTER CORP. + +OUI:0050D9* + ID_OUI_FROM_DATABASE=ENGETRON-ENGENHARIA ELETRONICA IND. e COM. LTDA + +OUI:0050DA* + ID_OUI_FROM_DATABASE=3COM CORPORATION + +OUI:0050DB* + ID_OUI_FROM_DATABASE=CONTEMPORARY CONTROL + +OUI:0050DC* + ID_OUI_FROM_DATABASE=TAS TELEFONBAU A. SCHWABE GMBH & CO. KG + +OUI:0050DD* + ID_OUI_FROM_DATABASE=SERRA SOLDADURA, S.A. + +OUI:0050DE* + ID_OUI_FROM_DATABASE=SIGNUM SYSTEMS CORP. + +OUI:0050DF* + ID_OUI_FROM_DATABASE=AirFiber, Inc. + +OUI:0050E1* + ID_OUI_FROM_DATABASE=NS TECH ELECTRONICS SDN BHD + +OUI:0050E2* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0050E3* + ID_OUI_FROM_DATABASE=Motorola, Inc. + +OUI:0050E4* + ID_OUI_FROM_DATABASE=APPLE COMPUTER, INC. + +OUI:0050E6* + ID_OUI_FROM_DATABASE=HAKUSAN CORPORATION + +OUI:0050E7* + ID_OUI_FROM_DATABASE=PARADISE INNOVATIONS (ASIA) + +OUI:0050E8* + ID_OUI_FROM_DATABASE=NOMADIX INC. + +OUI:0050EA* + ID_OUI_FROM_DATABASE=XEL COMMUNICATIONS, INC. + +OUI:0050EB* + ID_OUI_FROM_DATABASE=ALPHA-TOP CORPORATION + +OUI:0050EC* + ID_OUI_FROM_DATABASE=OLICOM A/S + +OUI:0050ED* + ID_OUI_FROM_DATABASE=ANDA NETWORKS + +OUI:0050EE* + ID_OUI_FROM_DATABASE=TEK DIGITEL CORPORATION + +OUI:0050EF* + ID_OUI_FROM_DATABASE=SPE Systemhaus GmbH + +OUI:0050F0* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0050F1* + ID_OUI_FROM_DATABASE=Intel Corporation + +OUI:0050F2* + ID_OUI_FROM_DATABASE=MICROSOFT CORP. + +OUI:0050F3* + ID_OUI_FROM_DATABASE=GLOBAL NET INFORMATION CO., Ltd. + +OUI:0050F4* + ID_OUI_FROM_DATABASE=SIGMATEK GMBH & CO. KG + +OUI:0050F6* + ID_OUI_FROM_DATABASE=PAN-INTERNATIONAL INDUSTRIAL CORP. + +OUI:0050F7* + ID_OUI_FROM_DATABASE=VENTURE MANUFACTURING (SINGAPORE) LTD. + +OUI:0050F8* + ID_OUI_FROM_DATABASE=ENTREGA TECHNOLOGIES, INC. + +OUI:0050F9* + ID_OUI_FROM_DATABASE=SENSORMATIC ACD + +OUI:0050FA* + ID_OUI_FROM_DATABASE=OXTEL, LTD. + +OUI:0050FB* + ID_OUI_FROM_DATABASE=VSK ELECTRONICS + +OUI:0050FC* + ID_OUI_FROM_DATABASE=EDIMAX TECHNOLOGY CO., LTD. + +OUI:0050FD* + ID_OUI_FROM_DATABASE=VISIONCOMM CO., LTD. + +OUI:0050FE* + ID_OUI_FROM_DATABASE=PCTVnet ASA + +OUI:0050FF* + ID_OUI_FROM_DATABASE=HAKKO ELECTRONICS CO., LTD. + +OUI:005218* + ID_OUI_FROM_DATABASE=Wuxi Keboda Electron Co.Ltd + +OUI:0054AF* + ID_OUI_FROM_DATABASE=Continental Automotive Systems Inc. + +OUI:005CB1* + ID_OUI_FROM_DATABASE=Gospell DIGITAL TECHNOLOGY CO., LTD + +OUI:005D03* + ID_OUI_FROM_DATABASE=Xilinx, Inc + +OUI:006000* + ID_OUI_FROM_DATABASE=XYCOM INC. + +OUI:006001* + ID_OUI_FROM_DATABASE=InnoSys, Inc. + +OUI:006002* + ID_OUI_FROM_DATABASE=SCREEN SUBTITLING SYSTEMS, LTD + +OUI:006003* + ID_OUI_FROM_DATABASE=TERAOKA WEIGH SYSTEM PTE, LTD. + +OUI:006004* + ID_OUI_FROM_DATABASE=COMPUTADORES MODULARES SA + +OUI:006005* + ID_OUI_FROM_DATABASE=FEEDBACK DATA LTD. + +OUI:006006* + ID_OUI_FROM_DATABASE=SOTEC CO., LTD + +OUI:006007* + ID_OUI_FROM_DATABASE=ACRES GAMING, INC. + +OUI:006008* + ID_OUI_FROM_DATABASE=3COM CORPORATION + +OUI:006009* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00600A* + ID_OUI_FROM_DATABASE=SORD COMPUTER CORPORATION + +OUI:00600B* + ID_OUI_FROM_DATABASE=LOGWARE GmbH + +OUI:00600C* + ID_OUI_FROM_DATABASE=Eurotech Inc. + +OUI:00600D* + ID_OUI_FROM_DATABASE=Digital Logic GmbH + +OUI:00600E* + ID_OUI_FROM_DATABASE=WAVENET INTERNATIONAL, INC. + +OUI:00600F* + ID_OUI_FROM_DATABASE=WESTELL, INC. + +OUI:006010* + ID_OUI_FROM_DATABASE=NETWORK MACHINES, INC. + +OUI:006011* + ID_OUI_FROM_DATABASE=CRYSTAL SEMICONDUCTOR CORP. + +OUI:006012* + ID_OUI_FROM_DATABASE=POWER COMPUTING CORPORATION + +OUI:006013* + ID_OUI_FROM_DATABASE=NETSTAL MASCHINEN AG + +OUI:006014* + ID_OUI_FROM_DATABASE=EDEC CO., LTD. + +OUI:006015* + ID_OUI_FROM_DATABASE=NET2NET CORPORATION + +OUI:006016* + ID_OUI_FROM_DATABASE=CLARIION + +OUI:006017* + ID_OUI_FROM_DATABASE=TOKIMEC INC. + +OUI:006018* + ID_OUI_FROM_DATABASE=STELLAR ONE CORPORATION + +OUI:006019* + ID_OUI_FROM_DATABASE=Roche Diagnostics + +OUI:00601A* + ID_OUI_FROM_DATABASE=KEITHLEY INSTRUMENTS + +OUI:00601B* + ID_OUI_FROM_DATABASE=MESA ELECTRONICS + +OUI:00601C* + ID_OUI_FROM_DATABASE=TELXON CORPORATION + +OUI:00601D* + ID_OUI_FROM_DATABASE=LUCENT TECHNOLOGIES + +OUI:00601E* + ID_OUI_FROM_DATABASE=SOFTLAB, INC. + +OUI:00601F* + ID_OUI_FROM_DATABASE=STALLION TECHNOLOGIES + +OUI:006020* + ID_OUI_FROM_DATABASE=PIVOTAL NETWORKING, INC. + +OUI:006021* + ID_OUI_FROM_DATABASE=DSC CORPORATION + +OUI:006022* + ID_OUI_FROM_DATABASE=VICOM SYSTEMS, INC. + +OUI:006023* + ID_OUI_FROM_DATABASE=PERICOM SEMICONDUCTOR CORP. + +OUI:006024* + ID_OUI_FROM_DATABASE=GRADIENT TECHNOLOGIES, INC. + +OUI:006025* + ID_OUI_FROM_DATABASE=ACTIVE IMAGING PLC + +OUI:006026* + ID_OUI_FROM_DATABASE=VIKING Modular Solutions + +OUI:006027* + ID_OUI_FROM_DATABASE=Superior Modular Products + +OUI:006028* + ID_OUI_FROM_DATABASE=MACROVISION CORPORATION + +OUI:006029* + ID_OUI_FROM_DATABASE=CARY PERIPHERALS INC. + +OUI:00602A* + ID_OUI_FROM_DATABASE=SYMICRON COMPUTER COMMUNICATIONS, LTD. + +OUI:00602B* + ID_OUI_FROM_DATABASE=PEAK AUDIO + +OUI:00602C* + ID_OUI_FROM_DATABASE=LINX Data Terminals, Inc. + +OUI:00602D* + ID_OUI_FROM_DATABASE=ALERTON TECHNOLOGIES, INC. + +OUI:00602E* + ID_OUI_FROM_DATABASE=CYCLADES CORPORATION + +OUI:00602F* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:006030* + ID_OUI_FROM_DATABASE=VILLAGE TRONIC ENTWICKLUNG + +OUI:006031* + ID_OUI_FROM_DATABASE=HRK SYSTEMS + +OUI:006032* + ID_OUI_FROM_DATABASE=I-CUBE, INC. + +OUI:006033* + ID_OUI_FROM_DATABASE=ACUITY IMAGING, INC. + +OUI:006034* + ID_OUI_FROM_DATABASE=ROBERT BOSCH GmbH + +OUI:006035* + ID_OUI_FROM_DATABASE=DALLAS SEMICONDUCTOR, INC. + +OUI:006036* + ID_OUI_FROM_DATABASE=AIT Austrian Institute of Technology GmbH + +OUI:006037* + ID_OUI_FROM_DATABASE=NXP Semiconductors + +OUI:006038* + ID_OUI_FROM_DATABASE=Nortel Networks + +OUI:006039* + ID_OUI_FROM_DATABASE=SanCom Technology, Inc. + +OUI:00603A* + ID_OUI_FROM_DATABASE=QUICK CONTROLS LTD. + +OUI:00603B* + ID_OUI_FROM_DATABASE=AMTEC spa + +OUI:00603C* + ID_OUI_FROM_DATABASE=HAGIWARA SYS-COM CO., LTD. + +OUI:00603D* + ID_OUI_FROM_DATABASE=3CX + +OUI:00603E* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00603F* + ID_OUI_FROM_DATABASE=PATAPSCO DESIGNS + +OUI:006040* + ID_OUI_FROM_DATABASE=NETRO CORP. + +OUI:006041* + ID_OUI_FROM_DATABASE=Yokogawa Electric Corporation + +OUI:006042* + ID_OUI_FROM_DATABASE=TKS (USA), INC. + +OUI:006043* + ID_OUI_FROM_DATABASE=iDirect, INC. + +OUI:006044* + ID_OUI_FROM_DATABASE=LITTON/POLY-SCIENTIFIC + +OUI:006045* + ID_OUI_FROM_DATABASE=PATHLIGHT TECHNOLOGIES + +OUI:006046* + ID_OUI_FROM_DATABASE=VMETRO, INC. + +OUI:006047* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:006048* + ID_OUI_FROM_DATABASE=EMC CORPORATION + +OUI:006049* + ID_OUI_FROM_DATABASE=VINA TECHNOLOGIES + +OUI:00604A* + ID_OUI_FROM_DATABASE=SAIC IDEAS GROUP + +OUI:00604B* + ID_OUI_FROM_DATABASE=Safe-com GmbH & Co. KG + +OUI:00604C* + ID_OUI_FROM_DATABASE=SAGEM COMMUNICATION + +OUI:00604D* + ID_OUI_FROM_DATABASE=MMC NETWORKS, INC. + +OUI:00604E* + ID_OUI_FROM_DATABASE=CYCLE COMPUTER CORPORATION, INC. + +OUI:00604F* + ID_OUI_FROM_DATABASE=Tattile SRL + +OUI:006050* + ID_OUI_FROM_DATABASE=INTERNIX INC. + +OUI:006051* + ID_OUI_FROM_DATABASE=QUALITY SEMICONDUCTOR + +OUI:006052* + ID_OUI_FROM_DATABASE=PERIPHERALS ENTERPRISE CO., Ltd. + +OUI:006053* + ID_OUI_FROM_DATABASE=TOYODA MACHINE WORKS, LTD. + +OUI:006054* + ID_OUI_FROM_DATABASE=CONTROLWARE GMBH + +OUI:006055* + ID_OUI_FROM_DATABASE=CORNELL UNIVERSITY + +OUI:006056* + ID_OUI_FROM_DATABASE=NETWORK TOOLS, INC. + +OUI:006057* + ID_OUI_FROM_DATABASE=MURATA MANUFACTURING CO., LTD. + +OUI:006058* + ID_OUI_FROM_DATABASE=COPPER MOUNTAIN COMMUNICATIONS, INC. + +OUI:006059* + ID_OUI_FROM_DATABASE=TECHNICAL COMMUNICATIONS CORP. + +OUI:00605A* + ID_OUI_FROM_DATABASE=CELCORE, INC. + +OUI:00605B* + ID_OUI_FROM_DATABASE=IntraServer Technology, Inc. + +OUI:00605C* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00605D* + ID_OUI_FROM_DATABASE=SCANIVALVE CORP. + +OUI:00605E* + ID_OUI_FROM_DATABASE=LIBERTY TECHNOLOGY NETWORKING + +OUI:00605F* + ID_OUI_FROM_DATABASE=NIPPON UNISOFT CORPORATION + +OUI:006060* + ID_OUI_FROM_DATABASE=DAWNING TECHNOLOGIES, INC. + +OUI:006061* + ID_OUI_FROM_DATABASE=WHISTLE COMMUNICATIONS CORP. + +OUI:006062* + ID_OUI_FROM_DATABASE=TELESYNC, INC. + +OUI:006063* + ID_OUI_FROM_DATABASE=PSION DACOM PLC. + +OUI:006064* + ID_OUI_FROM_DATABASE=NETCOMM LIMITED + +OUI:006065* + ID_OUI_FROM_DATABASE=BERNECKER & RAINER INDUSTRIE-ELEKTRONIC GmbH + +OUI:006066* + ID_OUI_FROM_DATABASE=LACROIX Trafic + +OUI:006067* + ID_OUI_FROM_DATABASE=ACER NETXUS INC. + +OUI:006068* + ID_OUI_FROM_DATABASE=Dialogic Corporation + +OUI:006069* + ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc. + +OUI:00606A* + ID_OUI_FROM_DATABASE=MITSUBISHI WIRELESS COMMUNICATIONS. INC. + +OUI:00606B* + ID_OUI_FROM_DATABASE=Synclayer Inc. + +OUI:00606C* + ID_OUI_FROM_DATABASE=ARESCOM + +OUI:00606D* + ID_OUI_FROM_DATABASE=DIGITAL EQUIPMENT CORP. + +OUI:00606E* + ID_OUI_FROM_DATABASE=DAVICOM SEMICONDUCTOR, INC. + +OUI:00606F* + ID_OUI_FROM_DATABASE=CLARION CORPORATION OF AMERICA + +OUI:006070* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:006071* + ID_OUI_FROM_DATABASE=MIDAS LAB, INC. + +OUI:006072* + ID_OUI_FROM_DATABASE=VXL INSTRUMENTS, LIMITED + +OUI:006073* + ID_OUI_FROM_DATABASE=REDCREEK COMMUNICATIONS, INC. + +OUI:006074* + ID_OUI_FROM_DATABASE=QSC AUDIO PRODUCTS + +OUI:006075* + ID_OUI_FROM_DATABASE=PENTEK, INC. + +OUI:006076* + ID_OUI_FROM_DATABASE=SCHLUMBERGER TECHNOLOGIES RETAIL PETROLEUM SYSTEMS + +OUI:006077* + ID_OUI_FROM_DATABASE=PRISA NETWORKS + +OUI:006078* + ID_OUI_FROM_DATABASE=POWER MEASUREMENT LTD. + +OUI:006079* + ID_OUI_FROM_DATABASE=Mainstream Data, Inc. + +OUI:00607A* + ID_OUI_FROM_DATABASE=DVS GmbH + +OUI:00607B* + ID_OUI_FROM_DATABASE=FORE SYSTEMS, INC. + +OUI:00607C* + ID_OUI_FROM_DATABASE=WaveAccess, Ltd. + +OUI:00607D* + ID_OUI_FROM_DATABASE=SENTIENT NETWORKS INC. + +OUI:00607E* + ID_OUI_FROM_DATABASE=GIGALABS, INC. + +OUI:00607F* + ID_OUI_FROM_DATABASE=AURORA TECHNOLOGIES, INC. + +OUI:006080* + ID_OUI_FROM_DATABASE=MICROTRONIX DATACOM LTD. + +OUI:006081* + ID_OUI_FROM_DATABASE=TV/COM INTERNATIONAL + +OUI:006082* + ID_OUI_FROM_DATABASE=NOVALINK TECHNOLOGIES, INC. + +OUI:006083* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:006084* + ID_OUI_FROM_DATABASE=DIGITAL VIDEO + +OUI:006085* + ID_OUI_FROM_DATABASE=Storage Concepts + +OUI:006086* + ID_OUI_FROM_DATABASE=LOGIC REPLACEMENT TECH. LTD. + +OUI:006087* + ID_OUI_FROM_DATABASE=KANSAI ELECTRIC CO., LTD. + +OUI:006088* + ID_OUI_FROM_DATABASE=WHITE MOUNTAIN DSP, INC. + +OUI:006089* + ID_OUI_FROM_DATABASE=XATA + +OUI:00608A* + ID_OUI_FROM_DATABASE=CITADEL COMPUTER + +OUI:00608B* + ID_OUI_FROM_DATABASE=ConferTech International + +OUI:00608C* + ID_OUI_FROM_DATABASE=3COM CORPORATION + +OUI:00608D* + ID_OUI_FROM_DATABASE=UNIPULSE CORP. + +OUI:00608E* + ID_OUI_FROM_DATABASE=HE ELECTRONICS, TECHNOLOGIE & SYSTEMTECHNIK GmbH + +OUI:00608F* + ID_OUI_FROM_DATABASE=TEKRAM TECHNOLOGY CO., LTD. + +OUI:006090* + ID_OUI_FROM_DATABASE=Artiza Networks Inc + +OUI:006091* + ID_OUI_FROM_DATABASE=FIRST PACIFIC NETWORKS, INC. + +OUI:006092* + ID_OUI_FROM_DATABASE=MICRO/SYS, INC. + +OUI:006093* + ID_OUI_FROM_DATABASE=VARIAN + +OUI:006094* + ID_OUI_FROM_DATABASE=IBM Corp + +OUI:006095* + ID_OUI_FROM_DATABASE=ACCU-TIME SYSTEMS, INC. + +OUI:006096* + ID_OUI_FROM_DATABASE=T.S. MICROTECH INC. + +OUI:006097* + ID_OUI_FROM_DATABASE=3COM CORPORATION + +OUI:006098* + ID_OUI_FROM_DATABASE=HT COMMUNICATIONS + +OUI:006099* + ID_OUI_FROM_DATABASE=SBE, Inc. + +OUI:00609A* + ID_OUI_FROM_DATABASE=NJK TECHNO CO. + +OUI:00609B* + ID_OUI_FROM_DATABASE=ASTRO-MED, INC. + +OUI:00609C* + ID_OUI_FROM_DATABASE=Perkin-Elmer Incorporated + +OUI:00609D* + ID_OUI_FROM_DATABASE=PMI FOOD EQUIPMENT GROUP + +OUI:00609E* + ID_OUI_FROM_DATABASE=ASC X3 - INFORMATION TECHNOLOGY STANDARDS SECRETARIATS + +OUI:00609F* + ID_OUI_FROM_DATABASE=PHAST CORPORATION + +OUI:0060A0* + ID_OUI_FROM_DATABASE=SWITCHED NETWORK TECHNOLOGIES, INC. + +OUI:0060A1* + ID_OUI_FROM_DATABASE=VPNet, Inc. + +OUI:0060A2* + ID_OUI_FROM_DATABASE=NIHON UNISYS LIMITED CO. + +OUI:0060A3* + ID_OUI_FROM_DATABASE=CONTINUUM TECHNOLOGY CORP. + +OUI:0060A4* + ID_OUI_FROM_DATABASE=GRINAKER SYSTEM TECHNOLOGIES + +OUI:0060A5* + ID_OUI_FROM_DATABASE=PERFORMANCE TELECOM CORP. + +OUI:0060A6* + ID_OUI_FROM_DATABASE=PARTICLE MEASURING SYSTEMS + +OUI:0060A7* + ID_OUI_FROM_DATABASE=MICROSENS GmbH & CO. KG + +OUI:0060A8* + ID_OUI_FROM_DATABASE=TIDOMAT AB + +OUI:0060A9* + ID_OUI_FROM_DATABASE=GESYTEC MbH + +OUI:0060AA* + ID_OUI_FROM_DATABASE=INTELLIGENT DEVICES INC. (IDI) + +OUI:0060AB* + ID_OUI_FROM_DATABASE=LARSCOM INCORPORATED + +OUI:0060AC* + ID_OUI_FROM_DATABASE=RESILIENCE CORPORATION + +OUI:0060AD* + ID_OUI_FROM_DATABASE=MegaChips Corporation + +OUI:0060AE* + ID_OUI_FROM_DATABASE=TRIO INFORMATION SYSTEMS AB + +OUI:0060AF* + ID_OUI_FROM_DATABASE=PACIFIC MICRO DATA, INC. + +OUI:0060B0* + ID_OUI_FROM_DATABASE=HEWLETT-PACKARD CO. + +OUI:0060B1* + ID_OUI_FROM_DATABASE=INPUT/OUTPUT, INC. + +OUI:0060B2* + ID_OUI_FROM_DATABASE=PROCESS CONTROL CORP. + +OUI:0060B3* + ID_OUI_FROM_DATABASE=Z-COM, INC. + +OUI:0060B4* + ID_OUI_FROM_DATABASE=GLENAYRE R&D INC. + +OUI:0060B5* + ID_OUI_FROM_DATABASE=KEBA GmbH + +OUI:0060B6* + ID_OUI_FROM_DATABASE=LAND COMPUTER CO., LTD. + +OUI:0060B7* + ID_OUI_FROM_DATABASE=CHANNELMATIC, INC. + +OUI:0060B8* + ID_OUI_FROM_DATABASE=CORELIS Inc. + +OUI:0060B9* + ID_OUI_FROM_DATABASE=NEC Infrontia Corporation + +OUI:0060BA* + ID_OUI_FROM_DATABASE=SAHARA NETWORKS, INC. + +OUI:0060BB* + ID_OUI_FROM_DATABASE=CABLETRON - NETLINK, INC. + +OUI:0060BC* + ID_OUI_FROM_DATABASE=KeunYoung Electronics & Communication Co., Ltd. + +OUI:0060BD* + ID_OUI_FROM_DATABASE=HUBBELL-PULSECOM + +OUI:0060BE* + ID_OUI_FROM_DATABASE=WEBTRONICS + +OUI:0060BF* + ID_OUI_FROM_DATABASE=MACRAIGOR SYSTEMS, INC. + +OUI:0060C0* + ID_OUI_FROM_DATABASE=Nera Networks AS + +OUI:0060C1* + ID_OUI_FROM_DATABASE=WaveSpan Corporation + +OUI:0060C2* + ID_OUI_FROM_DATABASE=MPL AG + +OUI:0060C3* + ID_OUI_FROM_DATABASE=NETVISION CORPORATION + +OUI:0060C4* + ID_OUI_FROM_DATABASE=SOLITON SYSTEMS K.K. + +OUI:0060C5* + ID_OUI_FROM_DATABASE=ANCOT CORP. + +OUI:0060C6* + ID_OUI_FROM_DATABASE=DCS AG + +OUI:0060C7* + ID_OUI_FROM_DATABASE=AMATI COMMUNICATIONS CORP. + +OUI:0060C8* + ID_OUI_FROM_DATABASE=KUKA WELDING SYSTEMS & ROBOTS + +OUI:0060C9* + ID_OUI_FROM_DATABASE=ControlNet, Inc. + +OUI:0060CA* + ID_OUI_FROM_DATABASE=HARMONIC SYSTEMS INCORPORATED + +OUI:0060CB* + ID_OUI_FROM_DATABASE=HITACHI ZOSEN CORPORATION + +OUI:0060CC* + ID_OUI_FROM_DATABASE=EMTRAK, INCORPORATED + +OUI:0060CD* + ID_OUI_FROM_DATABASE=VideoServer, Inc. + +OUI:0060CE* + ID_OUI_FROM_DATABASE=ACCLAIM COMMUNICATIONS + +OUI:0060CF* + ID_OUI_FROM_DATABASE=ALTEON NETWORKS, INC. + +OUI:0060D0* + ID_OUI_FROM_DATABASE=SNMP RESEARCH INCORPORATED + +OUI:0060D1* + ID_OUI_FROM_DATABASE=CASCADE COMMUNICATIONS + +OUI:0060D2* + ID_OUI_FROM_DATABASE=LUCENT TECHNOLOGIES TAIWAN TELECOMMUNICATIONS CO., LTD. + +OUI:0060D3* + ID_OUI_FROM_DATABASE=AT&T + +OUI:0060D4* + ID_OUI_FROM_DATABASE=ELDAT COMMUNICATION LTD. + +OUI:0060D5* + ID_OUI_FROM_DATABASE=MIYACHI TECHNOS CORP. + +OUI:0060D6* + ID_OUI_FROM_DATABASE=NovAtel Wireless Technologies Ltd. + +OUI:0060D7* + ID_OUI_FROM_DATABASE=ECOLE POLYTECHNIQUE FEDERALE DE LAUSANNE (EPFL) + +OUI:0060D8* + ID_OUI_FROM_DATABASE=ELMIC SYSTEMS, INC. + +OUI:0060D9* + ID_OUI_FROM_DATABASE=TRANSYS NETWORKS INC. + +OUI:0060DA* + ID_OUI_FROM_DATABASE=JBM ELECTRONICS CO. + +OUI:0060DB* + ID_OUI_FROM_DATABASE=NTP ELEKTRONIK A/S + +OUI:0060DC* + ID_OUI_FROM_DATABASE=Toyo Network Systems & System Integration Co. LTD + +OUI:0060DD* + ID_OUI_FROM_DATABASE=MYRICOM, INC. + +OUI:0060DE* + ID_OUI_FROM_DATABASE=Kayser-Threde GmbH + +OUI:0060DF* + ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc. + +OUI:0060E0* + ID_OUI_FROM_DATABASE=AXIOM TECHNOLOGY CO., LTD. + +OUI:0060E1* + ID_OUI_FROM_DATABASE=ORCKIT COMMUNICATIONS LTD. + +OUI:0060E2* + ID_OUI_FROM_DATABASE=QUEST ENGINEERING & DEVELOPMENT + +OUI:0060E3* + ID_OUI_FROM_DATABASE=ARBIN INSTRUMENTS + +OUI:0060E4* + ID_OUI_FROM_DATABASE=COMPUSERVE, INC. + +OUI:0060E5* + ID_OUI_FROM_DATABASE=FUJI AUTOMATION CO., LTD. + +OUI:0060E6* + ID_OUI_FROM_DATABASE=SHOMITI SYSTEMS INCORPORATED + +OUI:0060E7* + ID_OUI_FROM_DATABASE=RANDATA + +OUI:0060E8* + ID_OUI_FROM_DATABASE=HITACHI COMPUTER PRODUCTS (AMERICA), INC. + +OUI:0060E9* + ID_OUI_FROM_DATABASE=ATOP TECHNOLOGIES, INC. + +OUI:0060EA* + ID_OUI_FROM_DATABASE=StreamLogic + +OUI:0060EB* + ID_OUI_FROM_DATABASE=FOURTHTRACK SYSTEMS + +OUI:0060EC* + ID_OUI_FROM_DATABASE=HERMARY OPTO ELECTRONICS INC. + +OUI:0060ED* + ID_OUI_FROM_DATABASE=RICARDO TEST AUTOMATION LTD. + +OUI:0060EE* + ID_OUI_FROM_DATABASE=APOLLO + +OUI:0060EF* + ID_OUI_FROM_DATABASE=FLYTECH TECHNOLOGY CO., LTD. + +OUI:0060F0* + ID_OUI_FROM_DATABASE=JOHNSON & JOHNSON MEDICAL, INC + +OUI:0060F1* + ID_OUI_FROM_DATABASE=EXP COMPUTER, INC. + +OUI:0060F2* + ID_OUI_FROM_DATABASE=LASERGRAPHICS, INC. + +OUI:0060F3* + ID_OUI_FROM_DATABASE=Performance Analysis Broadband, Spirent plc + +OUI:0060F4* + ID_OUI_FROM_DATABASE=ADVANCED COMPUTER SOLUTIONS, Inc. + +OUI:0060F5* + ID_OUI_FROM_DATABASE=ICON WEST, INC. + +OUI:0060F6* + ID_OUI_FROM_DATABASE=NEXTEST COMMUNICATIONS PRODUCTS, INC. + +OUI:0060F7* + ID_OUI_FROM_DATABASE=DATAFUSION SYSTEMS + +OUI:0060F8* + ID_OUI_FROM_DATABASE=Loran International Technologies Inc. + +OUI:0060F9* + ID_OUI_FROM_DATABASE=DIAMOND LANE COMMUNICATIONS + +OUI:0060FA* + ID_OUI_FROM_DATABASE=EDUCATIONAL TECHNOLOGY RESOURCES, INC. + +OUI:0060FB* + ID_OUI_FROM_DATABASE=PACKETEER, INC. + +OUI:0060FC* + ID_OUI_FROM_DATABASE=CONSERVATION THROUGH INNOVATION LTD. + +OUI:0060FD* + ID_OUI_FROM_DATABASE=NetICs, Inc. + +OUI:0060FE* + ID_OUI_FROM_DATABASE=LYNX SYSTEM DEVELOPERS, INC. + +OUI:0060FF* + ID_OUI_FROM_DATABASE=QuVis, Inc. + +OUI:006440* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0064A6* + ID_OUI_FROM_DATABASE=Maquet CardioVascular + +OUI:006B9E* + ID_OUI_FROM_DATABASE=VIZIO Inc + +OUI:006BA0* + ID_OUI_FROM_DATABASE=SHENZHEN UNIVERSAL INTELLISYS PTE LTD + +OUI:006DFB* + ID_OUI_FROM_DATABASE=Vutrix (UK) Ltd + +OUI:0070B0* + ID_OUI_FROM_DATABASE=M/A-COM INC. COMPANIES + +OUI:0070B3* + ID_OUI_FROM_DATABASE=DATA RECALL LTD. + +OUI:00789E* + ID_OUI_FROM_DATABASE=SAGEMCOM + +OUI:007F28* + ID_OUI_FROM_DATABASE=Actiontec Electronics, Inc + +OUI:008000* + ID_OUI_FROM_DATABASE=MULTITECH SYSTEMS, INC. + +OUI:008001* + ID_OUI_FROM_DATABASE=PERIPHONICS CORPORATION + +OUI:008002* + ID_OUI_FROM_DATABASE=SATELCOM (UK) LTD + +OUI:008003* + ID_OUI_FROM_DATABASE=HYTEC ELECTRONICS LTD. + +OUI:008004* + ID_OUI_FROM_DATABASE=ANTLOW COMMUNICATIONS, LTD. + +OUI:008005* + ID_OUI_FROM_DATABASE=CACTUS COMPUTER INC. + +OUI:008006* + ID_OUI_FROM_DATABASE=COMPUADD CORPORATION + +OUI:008007* + ID_OUI_FROM_DATABASE=DLOG NC-SYSTEME + +OUI:008008* + ID_OUI_FROM_DATABASE=DYNATECH COMPUTER SYSTEMS + +OUI:008009* + ID_OUI_FROM_DATABASE=JUPITER SYSTEMS, INC. + +OUI:00800A* + ID_OUI_FROM_DATABASE=JAPAN COMPUTER CORP. + +OUI:00800B* + ID_OUI_FROM_DATABASE=CSK CORPORATION + +OUI:00800C* + ID_OUI_FROM_DATABASE=VIDECOM LIMITED + +OUI:00800D* + ID_OUI_FROM_DATABASE=VOSSWINKEL F.U. + +OUI:00800E* + ID_OUI_FROM_DATABASE=ATLANTIX CORPORATION + +OUI:00800F* + ID_OUI_FROM_DATABASE=STANDARD MICROSYSTEMS + +OUI:008010* + ID_OUI_FROM_DATABASE=COMMODORE INTERNATIONAL + +OUI:008011* + ID_OUI_FROM_DATABASE=DIGITAL SYSTEMS INT'L. INC. + +OUI:008012* + ID_OUI_FROM_DATABASE=INTEGRATED MEASUREMENT SYSTEMS + +OUI:008013* + ID_OUI_FROM_DATABASE=THOMAS-CONRAD CORPORATION + +OUI:008014* + ID_OUI_FROM_DATABASE=ESPRIT SYSTEMS + +OUI:008015* + ID_OUI_FROM_DATABASE=SEIKO SYSTEMS, INC. + +OUI:008016* + ID_OUI_FROM_DATABASE=WANDEL AND GOLTERMANN + +OUI:008017* + ID_OUI_FROM_DATABASE=PFU LIMITED + +OUI:008018* + ID_OUI_FROM_DATABASE=KOBE STEEL, LTD. + +OUI:008019* + ID_OUI_FROM_DATABASE=DAYNA COMMUNICATIONS, INC. + +OUI:00801A* + ID_OUI_FROM_DATABASE=BELL ATLANTIC + +OUI:00801B* + ID_OUI_FROM_DATABASE=KODIAK TECHNOLOGY + +OUI:00801C* + ID_OUI_FROM_DATABASE=NEWPORT SYSTEMS SOLUTIONS + +OUI:00801D* + ID_OUI_FROM_DATABASE=INTEGRATED INFERENCE MACHINES + +OUI:00801E* + ID_OUI_FROM_DATABASE=XINETRON, INC. + +OUI:00801F* + ID_OUI_FROM_DATABASE=KRUPP ATLAS ELECTRONIK GMBH + +OUI:008020* + ID_OUI_FROM_DATABASE=NETWORK PRODUCTS + +OUI:008021* + ID_OUI_FROM_DATABASE=Alcatel Canada Inc. + +OUI:008022* + ID_OUI_FROM_DATABASE=SCAN-OPTICS + +OUI:008023* + ID_OUI_FROM_DATABASE=INTEGRATED BUSINESS NETWORKS + +OUI:008024* + ID_OUI_FROM_DATABASE=KALPANA, INC. + +OUI:008025* + ID_OUI_FROM_DATABASE=STOLLMANN GMBH + +OUI:008026* + ID_OUI_FROM_DATABASE=NETWORK PRODUCTS CORPORATION + +OUI:008027* + ID_OUI_FROM_DATABASE=ADAPTIVE SYSTEMS, INC. + +OUI:008028* + ID_OUI_FROM_DATABASE=TRADPOST (HK) LTD + +OUI:008029* + ID_OUI_FROM_DATABASE=EAGLE TECHNOLOGY, INC. + +OUI:00802A* + ID_OUI_FROM_DATABASE=TEST SYSTEMS & SIMULATIONS INC + +OUI:00802B* + ID_OUI_FROM_DATABASE=INTEGRATED MARKETING CO + +OUI:00802C* + ID_OUI_FROM_DATABASE=THE SAGE GROUP PLC + +OUI:00802D* + ID_OUI_FROM_DATABASE=XYLOGICS INC + +OUI:00802E* + ID_OUI_FROM_DATABASE=CASTLE ROCK COMPUTING + +OUI:00802F* + ID_OUI_FROM_DATABASE=NATIONAL INSTRUMENTS CORP. + +OUI:008030* + ID_OUI_FROM_DATABASE=NEXUS ELECTRONICS + +OUI:008031* + ID_OUI_FROM_DATABASE=BASYS, CORP. + +OUI:008032* + ID_OUI_FROM_DATABASE=ACCESS CO., LTD. + +OUI:008033* + ID_OUI_FROM_DATABASE=EMS Aviation, Inc. + +OUI:008034* + ID_OUI_FROM_DATABASE=SMT GOUPIL + +OUI:008035* + ID_OUI_FROM_DATABASE=TECHNOLOGY WORKS, INC. + +OUI:008036* + ID_OUI_FROM_DATABASE=REFLEX MANUFACTURING SYSTEMS + +OUI:008037* + ID_OUI_FROM_DATABASE=Ericsson Group + +OUI:008038* + ID_OUI_FROM_DATABASE=DATA RESEARCH & APPLICATIONS + +OUI:008039* + ID_OUI_FROM_DATABASE=ALCATEL STC AUSTRALIA + +OUI:00803A* + ID_OUI_FROM_DATABASE=VARITYPER, INC. + +OUI:00803B* + ID_OUI_FROM_DATABASE=APT COMMUNICATIONS, INC. + +OUI:00803C* + ID_OUI_FROM_DATABASE=TVS ELECTRONICS LTD + +OUI:00803D* + ID_OUI_FROM_DATABASE=SURIGIKEN CO., LTD. + +OUI:00803E* + ID_OUI_FROM_DATABASE=SYNERNETICS + +OUI:00803F* + ID_OUI_FROM_DATABASE=TATUNG COMPANY + +OUI:008040* + ID_OUI_FROM_DATABASE=JOHN FLUKE MANUFACTURING CO. + +OUI:008041* + ID_OUI_FROM_DATABASE=VEB KOMBINAT ROBOTRON + +OUI:008042* + ID_OUI_FROM_DATABASE=Emerson Network Power + +OUI:008043* + ID_OUI_FROM_DATABASE=NETWORLD, INC. + +OUI:008044* + ID_OUI_FROM_DATABASE=SYSTECH COMPUTER CORP. + +OUI:008045* + ID_OUI_FROM_DATABASE=MATSUSHITA ELECTRIC IND. CO + +OUI:008046* + ID_OUI_FROM_DATABASE=Tattile SRL + +OUI:008047* + ID_OUI_FROM_DATABASE=IN-NET CORP. + +OUI:008048* + ID_OUI_FROM_DATABASE=COMPEX INCORPORATED + +OUI:008049* + ID_OUI_FROM_DATABASE=NISSIN ELECTRIC CO., LTD. + +OUI:00804A* + ID_OUI_FROM_DATABASE=PRO-LOG + +OUI:00804B* + ID_OUI_FROM_DATABASE=EAGLE TECHNOLOGIES PTY.LTD. + +OUI:00804C* + ID_OUI_FROM_DATABASE=CONTEC CO., LTD. + +OUI:00804D* + ID_OUI_FROM_DATABASE=CYCLONE MICROSYSTEMS, INC. + +OUI:00804E* + ID_OUI_FROM_DATABASE=APEX COMPUTER COMPANY + +OUI:00804F* + ID_OUI_FROM_DATABASE=DAIKIN INDUSTRIES, LTD. + +OUI:008050* + ID_OUI_FROM_DATABASE=ZIATECH CORPORATION + +OUI:008051* + ID_OUI_FROM_DATABASE=FIBERMUX + +OUI:008052* + ID_OUI_FROM_DATABASE=TECHNICALLY ELITE CONCEPTS + +OUI:008053* + ID_OUI_FROM_DATABASE=INTELLICOM, INC. + +OUI:008054* + ID_OUI_FROM_DATABASE=FRONTIER TECHNOLOGIES CORP. + +OUI:008055* + ID_OUI_FROM_DATABASE=FERMILAB + +OUI:008056* + ID_OUI_FROM_DATABASE=SPHINX ELEKTRONIK GMBH + +OUI:008057* + ID_OUI_FROM_DATABASE=ADSOFT, LTD. + +OUI:008058* + ID_OUI_FROM_DATABASE=PRINTER SYSTEMS CORPORATION + +OUI:008059* + ID_OUI_FROM_DATABASE=STANLEY ELECTRIC CO., LTD + +OUI:00805A* + ID_OUI_FROM_DATABASE=TULIP COMPUTERS INTERNAT'L B.V + +OUI:00805B* + ID_OUI_FROM_DATABASE=CONDOR SYSTEMS, INC. + +OUI:00805C* + ID_OUI_FROM_DATABASE=AGILIS CORPORATION + +OUI:00805D* + ID_OUI_FROM_DATABASE=CANSTAR + +OUI:00805E* + ID_OUI_FROM_DATABASE=LSI LOGIC CORPORATION + +OUI:00805F* + ID_OUI_FROM_DATABASE=Hewlett-Packard Company + +OUI:008060* + ID_OUI_FROM_DATABASE=NETWORK INTERFACE CORPORATION + +OUI:008061* + ID_OUI_FROM_DATABASE=LITTON SYSTEMS, INC. + +OUI:008062* + ID_OUI_FROM_DATABASE=INTERFACE CO. + +OUI:008063* + ID_OUI_FROM_DATABASE=Hirschmann Automation and Control GmbH + +OUI:008064* + ID_OUI_FROM_DATABASE=Tattile SRL + +OUI:008065* + ID_OUI_FROM_DATABASE=CYBERGRAPHIC SYSTEMS PTY LTD. + +OUI:008066* + ID_OUI_FROM_DATABASE=ARCOM CONTROL SYSTEMS, LTD. + +OUI:008067* + ID_OUI_FROM_DATABASE=SQUARE D COMPANY + +OUI:008068* + ID_OUI_FROM_DATABASE=YAMATECH SCIENTIFIC LTD. + +OUI:008069* + ID_OUI_FROM_DATABASE=COMPUTONE SYSTEMS + +OUI:00806A* + ID_OUI_FROM_DATABASE=ERI (EMPAC RESEARCH INC.) + +OUI:00806B* + ID_OUI_FROM_DATABASE=SCHMID TELECOMMUNICATION + +OUI:00806C* + ID_OUI_FROM_DATABASE=CEGELEC PROJECTS LTD + +OUI:00806D* + ID_OUI_FROM_DATABASE=CENTURY SYSTEMS CORP. + +OUI:00806E* + ID_OUI_FROM_DATABASE=NIPPON STEEL CORPORATION + +OUI:00806F* + ID_OUI_FROM_DATABASE=ONELAN LTD. + +OUI:008070* + ID_OUI_FROM_DATABASE=COMPUTADORAS MICRON + +OUI:008071* + ID_OUI_FROM_DATABASE=SAI TECHNOLOGY + +OUI:008072* + ID_OUI_FROM_DATABASE=MICROPLEX SYSTEMS LTD. + +OUI:008073* + ID_OUI_FROM_DATABASE=DWB ASSOCIATES + +OUI:008074* + ID_OUI_FROM_DATABASE=FISHER CONTROLS + +OUI:008075* + ID_OUI_FROM_DATABASE=PARSYTEC GMBH + +OUI:008076* + ID_OUI_FROM_DATABASE=MCNC + +OUI:008077* + ID_OUI_FROM_DATABASE=BROTHER INDUSTRIES, LTD. + +OUI:008078* + ID_OUI_FROM_DATABASE=PRACTICAL PERIPHERALS, INC. + +OUI:008079* + ID_OUI_FROM_DATABASE=MICROBUS DESIGNS LTD. + +OUI:00807A* + ID_OUI_FROM_DATABASE=AITECH SYSTEMS LTD. + +OUI:00807B* + ID_OUI_FROM_DATABASE=ARTEL COMMUNICATIONS CORP. + +OUI:00807C* + ID_OUI_FROM_DATABASE=FIBERCOM, INC. + +OUI:00807D* + ID_OUI_FROM_DATABASE=EQUINOX SYSTEMS INC. + +OUI:00807E* + ID_OUI_FROM_DATABASE=SOUTHERN PACIFIC LTD. + +OUI:00807F* + ID_OUI_FROM_DATABASE=DY-4 INCORPORATED + +OUI:008080* + ID_OUI_FROM_DATABASE=DATAMEDIA CORPORATION + +OUI:008081* + ID_OUI_FROM_DATABASE=KENDALL SQUARE RESEARCH CORP. + +OUI:008082* + ID_OUI_FROM_DATABASE=PEP MODULAR COMPUTERS GMBH + +OUI:008083* + ID_OUI_FROM_DATABASE=AMDAHL + +OUI:008084* + ID_OUI_FROM_DATABASE=THE CLOUD INC. + +OUI:008085* + ID_OUI_FROM_DATABASE=H-THREE SYSTEMS CORPORATION + +OUI:008086* + ID_OUI_FROM_DATABASE=COMPUTER GENERATION INC. + +OUI:008087* + ID_OUI_FROM_DATABASE=OKI ELECTRIC INDUSTRY CO., LTD + +OUI:008088* + ID_OUI_FROM_DATABASE=VICTOR COMPANY OF JAPAN, LTD. + +OUI:008089* + ID_OUI_FROM_DATABASE=TECNETICS (PTY) LTD. + +OUI:00808A* + ID_OUI_FROM_DATABASE=SUMMIT MICROSYSTEMS CORP. + +OUI:00808B* + ID_OUI_FROM_DATABASE=DACOLL LIMITED + +OUI:00808C* + ID_OUI_FROM_DATABASE=NetScout Systems, Inc. + +OUI:00808D* + ID_OUI_FROM_DATABASE=WESTCOAST TECHNOLOGY B.V. + +OUI:00808E* + ID_OUI_FROM_DATABASE=RADSTONE TECHNOLOGY + +OUI:00808F* + ID_OUI_FROM_DATABASE=C. ITOH ELECTRONICS, INC. + +OUI:008090* + ID_OUI_FROM_DATABASE=MICROTEK INTERNATIONAL, INC. + +OUI:008091* + ID_OUI_FROM_DATABASE=TOKYO ELECTRIC CO.,LTD + +OUI:008092* + ID_OUI_FROM_DATABASE=Silex Technology, Inc. + +OUI:008093* + ID_OUI_FROM_DATABASE=XYRON CORPORATION + +OUI:008094* + ID_OUI_FROM_DATABASE=ALFA LAVAL AUTOMATION AB + +OUI:008095* + ID_OUI_FROM_DATABASE=BASIC MERTON HANDELSGES.M.B.H. + +OUI:008096* + ID_OUI_FROM_DATABASE=HUMAN DESIGNED SYSTEMS, INC. + +OUI:008097* + ID_OUI_FROM_DATABASE=CENTRALP AUTOMATISMES + +OUI:008098* + ID_OUI_FROM_DATABASE=TDK CORPORATION + +OUI:008099* + ID_OUI_FROM_DATABASE=Eaton Industries GmbH + +OUI:00809A* + ID_OUI_FROM_DATABASE=NOVUS NETWORKS LTD + +OUI:00809B* + ID_OUI_FROM_DATABASE=JUSTSYSTEM CORPORATION + +OUI:00809C* + ID_OUI_FROM_DATABASE=LUXCOM, INC. + +OUI:00809D* + ID_OUI_FROM_DATABASE=Commscraft Ltd. + +OUI:00809E* + ID_OUI_FROM_DATABASE=DATUS GMBH + +OUI:00809F* + ID_OUI_FROM_DATABASE=ALCATEL BUSINESS SYSTEMS + +OUI:0080A0* + ID_OUI_FROM_DATABASE=EDISA HEWLETT PACKARD S/A + +OUI:0080A1* + ID_OUI_FROM_DATABASE=MICROTEST, INC. + +OUI:0080A2* + ID_OUI_FROM_DATABASE=Tattile SRL + +OUI:0080A3* + ID_OUI_FROM_DATABASE=Lantronix + +OUI:0080A4* + ID_OUI_FROM_DATABASE=LIBERTY ELECTRONICS + +OUI:0080A5* + ID_OUI_FROM_DATABASE=SPEED INTERNATIONAL + +OUI:0080A6* + ID_OUI_FROM_DATABASE=REPUBLIC TECHNOLOGY, INC. + +OUI:0080A7* + ID_OUI_FROM_DATABASE=Honeywell International Inc + +OUI:0080A8* + ID_OUI_FROM_DATABASE=VITACOM CORPORATION + +OUI:0080A9* + ID_OUI_FROM_DATABASE=CLEARPOINT RESEARCH + +OUI:0080AA* + ID_OUI_FROM_DATABASE=MAXPEED + +OUI:0080AB* + ID_OUI_FROM_DATABASE=DUKANE NETWORK INTEGRATION + +OUI:0080AC* + ID_OUI_FROM_DATABASE=IMLOGIX, DIVISION OF GENESYS + +OUI:0080AD* + ID_OUI_FROM_DATABASE=CNET TECHNOLOGY, INC. + +OUI:0080AE* + ID_OUI_FROM_DATABASE=HUGHES NETWORK SYSTEMS + +OUI:0080AF* + ID_OUI_FROM_DATABASE=ALLUMER CO., LTD. + +OUI:0080B0* + ID_OUI_FROM_DATABASE=ADVANCED INFORMATION + +OUI:0080B1* + ID_OUI_FROM_DATABASE=SOFTCOM A/S + +OUI:0080B2* + ID_OUI_FROM_DATABASE=NETWORK EQUIPMENT TECHNOLOGIES + +OUI:0080B3* + ID_OUI_FROM_DATABASE=AVAL DATA CORPORATION + +OUI:0080B4* + ID_OUI_FROM_DATABASE=SOPHIA SYSTEMS + +OUI:0080B5* + ID_OUI_FROM_DATABASE=UNITED NETWORKS INC. + +OUI:0080B6* + ID_OUI_FROM_DATABASE=THEMIS COMPUTER + +OUI:0080B7* + ID_OUI_FROM_DATABASE=STELLAR COMPUTER + +OUI:0080B8* + ID_OUI_FROM_DATABASE=BUG, INCORPORATED + +OUI:0080B9* + ID_OUI_FROM_DATABASE=ARCHE TECHNOLIGIES INC. + +OUI:0080BA* + ID_OUI_FROM_DATABASE=SPECIALIX (ASIA) PTE, LTD + +OUI:0080BB* + ID_OUI_FROM_DATABASE=HUGHES LAN SYSTEMS + +OUI:0080BC* + ID_OUI_FROM_DATABASE=HITACHI ENGINEERING CO., LTD + +OUI:0080BD* + ID_OUI_FROM_DATABASE=THE FURUKAWA ELECTRIC CO., LTD + +OUI:0080BE* + ID_OUI_FROM_DATABASE=ARIES RESEARCH + +OUI:0080BF* + ID_OUI_FROM_DATABASE=TAKAOKA ELECTRIC MFG. CO. LTD. + +OUI:0080C0* + ID_OUI_FROM_DATABASE=PENRIL DATACOMM + +OUI:0080C1* + ID_OUI_FROM_DATABASE=LANEX CORPORATION + +OUI:0080C2* + ID_OUI_FROM_DATABASE=IEEE 802.1 COMMITTEE + +OUI:0080C3* + ID_OUI_FROM_DATABASE=BICC INFORMATION SYSTEMS & SVC + +OUI:0080C4* + ID_OUI_FROM_DATABASE=DOCUMENT TECHNOLOGIES, INC. + +OUI:0080C5* + ID_OUI_FROM_DATABASE=NOVELLCO DE MEXICO + +OUI:0080C6* + ID_OUI_FROM_DATABASE=NATIONAL DATACOMM CORPORATION + +OUI:0080C7* + ID_OUI_FROM_DATABASE=XIRCOM + +OUI:0080C8* + ID_OUI_FROM_DATABASE=D-LINK SYSTEMS, INC. + +OUI:0080C9* + ID_OUI_FROM_DATABASE=ALBERTA MICROELECTRONIC CENTRE + +OUI:0080CA* + ID_OUI_FROM_DATABASE=NETCOM RESEARCH INCORPORATED + +OUI:0080CB* + ID_OUI_FROM_DATABASE=FALCO DATA PRODUCTS + +OUI:0080CC* + ID_OUI_FROM_DATABASE=MICROWAVE BYPASS SYSTEMS + +OUI:0080CD* + ID_OUI_FROM_DATABASE=MICRONICS COMPUTER, INC. + +OUI:0080CE* + ID_OUI_FROM_DATABASE=BROADCAST TELEVISION SYSTEMS + +OUI:0080CF* + ID_OUI_FROM_DATABASE=EMBEDDED PERFORMANCE INC. + +OUI:0080D0* + ID_OUI_FROM_DATABASE=COMPUTER PERIPHERALS, INC. + +OUI:0080D1* + ID_OUI_FROM_DATABASE=KIMTRON CORPORATION + +OUI:0080D2* + ID_OUI_FROM_DATABASE=SHINNIHONDENKO CO., LTD. + +OUI:0080D3* + ID_OUI_FROM_DATABASE=SHIVA CORP. + +OUI:0080D4* + ID_OUI_FROM_DATABASE=CHASE RESEARCH LTD. + +OUI:0080D5* + ID_OUI_FROM_DATABASE=CADRE TECHNOLOGIES + +OUI:0080D6* + ID_OUI_FROM_DATABASE=NUVOTECH, INC. + +OUI:0080D7* + ID_OUI_FROM_DATABASE=Fantum Engineering + +OUI:0080D8* + ID_OUI_FROM_DATABASE=NETWORK PERIPHERALS INC. + +OUI:0080D9* + ID_OUI_FROM_DATABASE=EMK Elektronik GmbH & Co. KG + +OUI:0080DA* + ID_OUI_FROM_DATABASE=Bruel & Kjaer Sound & Vibration Measurement A/S + +OUI:0080DB* + ID_OUI_FROM_DATABASE=GRAPHON CORPORATION + +OUI:0080DC* + ID_OUI_FROM_DATABASE=PICKER INTERNATIONAL + +OUI:0080DD* + ID_OUI_FROM_DATABASE=GMX INC/GIMIX + +OUI:0080DE* + ID_OUI_FROM_DATABASE=GIPSI S.A. + +OUI:0080DF* + ID_OUI_FROM_DATABASE=ADC CODENOLL TECHNOLOGY CORP. + +OUI:0080E0* + ID_OUI_FROM_DATABASE=XTP SYSTEMS, INC. + +OUI:0080E1* + ID_OUI_FROM_DATABASE=STMICROELECTRONICS + +OUI:0080E2* + ID_OUI_FROM_DATABASE=T.D.I. CO., LTD. + +OUI:0080E3* + ID_OUI_FROM_DATABASE=CORAL NETWORK CORPORATION + +OUI:0080E4* + ID_OUI_FROM_DATABASE=NORTHWEST DIGITAL SYSTEMS, INC + +OUI:0080E5* + ID_OUI_FROM_DATABASE=LSI Logic Corporation + +OUI:0080E6* + ID_OUI_FROM_DATABASE=PEER NETWORKS, INC. + +OUI:0080E7* + ID_OUI_FROM_DATABASE=LYNWOOD SCIENTIFIC DEV. LTD. + +OUI:0080E8* + ID_OUI_FROM_DATABASE=CUMULUS CORPORATIION + +OUI:0080E9* + ID_OUI_FROM_DATABASE=Madge Ltd. + +OUI:0080EA* + ID_OUI_FROM_DATABASE=ADVA Optical Networking Ltd. + +OUI:0080EB* + ID_OUI_FROM_DATABASE=COMPCONTROL B.V. + +OUI:0080EC* + ID_OUI_FROM_DATABASE=SUPERCOMPUTING SOLUTIONS, INC. + +OUI:0080ED* + ID_OUI_FROM_DATABASE=IQ TECHNOLOGIES, INC. + +OUI:0080EE* + ID_OUI_FROM_DATABASE=THOMSON CSF + +OUI:0080EF* + ID_OUI_FROM_DATABASE=RATIONAL + +OUI:0080F0* + ID_OUI_FROM_DATABASE=Panasonic Communications Co., Ltd. + +OUI:0080F1* + ID_OUI_FROM_DATABASE=OPUS SYSTEMS + +OUI:0080F2* + ID_OUI_FROM_DATABASE=RAYCOM SYSTEMS INC + +OUI:0080F3* + ID_OUI_FROM_DATABASE=SUN ELECTRONICS CORP. + +OUI:0080F4* + ID_OUI_FROM_DATABASE=TELEMECANIQUE ELECTRIQUE + +OUI:0080F5* + ID_OUI_FROM_DATABASE=Quantel Ltd + +OUI:0080F6* + ID_OUI_FROM_DATABASE=SYNERGY MICROSYSTEMS + +OUI:0080F7* + ID_OUI_FROM_DATABASE=ZENITH ELECTRONICS + +OUI:0080F8* + ID_OUI_FROM_DATABASE=MIZAR, INC. + +OUI:0080F9* + ID_OUI_FROM_DATABASE=HEURIKON CORPORATION + +OUI:0080FA* + ID_OUI_FROM_DATABASE=RWT GMBH + +OUI:0080FB* + ID_OUI_FROM_DATABASE=BVM LIMITED + +OUI:0080FC* + ID_OUI_FROM_DATABASE=AVATAR CORPORATION + +OUI:0080FD* + ID_OUI_FROM_DATABASE=EXSCEED CORPRATION + +OUI:0080FE* + ID_OUI_FROM_DATABASE=AZURE TECHNOLOGIES, INC. + +OUI:0080FF* + ID_OUI_FROM_DATABASE=SOC. DE TELEINFORMATIQUE RTC + +OUI:008865* + ID_OUI_FROM_DATABASE=Apple + +OUI:008C10* + ID_OUI_FROM_DATABASE=Black Box Corp. + +OUI:008C54* + ID_OUI_FROM_DATABASE=ADB Broadband Italia + +OUI:008CFA* + ID_OUI_FROM_DATABASE=Inventec Corporation + +OUI:008D4E* + ID_OUI_FROM_DATABASE=CJSC NII STT + +OUI:008DDA* + ID_OUI_FROM_DATABASE=Link One Co., Ltd. + +OUI:008EF2* + ID_OUI_FROM_DATABASE=NETGEAR INC., + +OUI:009000* + ID_OUI_FROM_DATABASE=DIAMOND MULTIMEDIA + +OUI:009001* + ID_OUI_FROM_DATABASE=NISHIMU ELECTRONICS INDUSTRIES CO., LTD. + +OUI:009002* + ID_OUI_FROM_DATABASE=ALLGON AB + +OUI:009003* + ID_OUI_FROM_DATABASE=APLIO + +OUI:009004* + ID_OUI_FROM_DATABASE=3COM EUROPE LTD. + +OUI:009005* + ID_OUI_FROM_DATABASE=PROTECH SYSTEMS CO., LTD. + +OUI:009006* + ID_OUI_FROM_DATABASE=HAMAMATSU PHOTONICS K.K. + +OUI:009007* + ID_OUI_FROM_DATABASE=DOMEX TECHNOLOGY CORP. + +OUI:009008* + ID_OUI_FROM_DATABASE=HanA Systems Inc. + +OUI:009009* + ID_OUI_FROM_DATABASE=i Controls, Inc. + +OUI:00900A* + ID_OUI_FROM_DATABASE=PROTON ELECTRONIC INDUSTRIAL CO., LTD. + +OUI:00900B* + ID_OUI_FROM_DATABASE=LANNER ELECTRONICS, INC. + +OUI:00900C* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00900D* + ID_OUI_FROM_DATABASE=Overland Storage Inc. + +OUI:00900E* + ID_OUI_FROM_DATABASE=HANDLINK TECHNOLOGIES, INC. + +OUI:00900F* + ID_OUI_FROM_DATABASE=KAWASAKI HEAVY INDUSTRIES, LTD + +OUI:009010* + ID_OUI_FROM_DATABASE=SIMULATION LABORATORIES, INC. + +OUI:009011* + ID_OUI_FROM_DATABASE=WAVTrace, Inc. + +OUI:009012* + ID_OUI_FROM_DATABASE=GLOBESPAN SEMICONDUCTOR, INC. + +OUI:009013* + ID_OUI_FROM_DATABASE=SAMSAN CORP. + +OUI:009014* + ID_OUI_FROM_DATABASE=ROTORK INSTRUMENTS, LTD. + +OUI:009015* + ID_OUI_FROM_DATABASE=CENTIGRAM COMMUNICATIONS CORP. + +OUI:009016* + ID_OUI_FROM_DATABASE=ZAC + +OUI:009017* + ID_OUI_FROM_DATABASE=Zypcom, Inc + +OUI:009018* + ID_OUI_FROM_DATABASE=ITO ELECTRIC INDUSTRY CO, LTD. + +OUI:009019* + ID_OUI_FROM_DATABASE=HERMES ELECTRONICS CO., LTD. + +OUI:00901A* + ID_OUI_FROM_DATABASE=UNISPHERE SOLUTIONS + +OUI:00901B* + ID_OUI_FROM_DATABASE=DIGITAL CONTROLS + +OUI:00901C* + ID_OUI_FROM_DATABASE=mps Software Gmbh + +OUI:00901D* + ID_OUI_FROM_DATABASE=PEC (NZ) LTD. + +OUI:00901E* + ID_OUI_FROM_DATABASE=Selesta Ingegneria S.p.A. + +OUI:00901F* + ID_OUI_FROM_DATABASE=ADTEC PRODUCTIONS, INC. + +OUI:009020* + ID_OUI_FROM_DATABASE=PHILIPS ANALYTICAL X-RAY B.V. + +OUI:009021* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:009022* + ID_OUI_FROM_DATABASE=IVEX + +OUI:009023* + ID_OUI_FROM_DATABASE=ZILOG INC. + +OUI:009024* + ID_OUI_FROM_DATABASE=PIPELINKS, INC. + +OUI:009025* + ID_OUI_FROM_DATABASE=BAE Systems Australia (Electronic Systems) Pty Ltd + +OUI:009026* + ID_OUI_FROM_DATABASE=ADVANCED SWITCHING COMMUNICATIONS, INC. + +OUI:009027* + ID_OUI_FROM_DATABASE=INTEL CORPORATION + +OUI:009028* + ID_OUI_FROM_DATABASE=NIPPON SIGNAL CO., LTD. + +OUI:009029* + ID_OUI_FROM_DATABASE=CRYPTO AG + +OUI:00902A* + ID_OUI_FROM_DATABASE=COMMUNICATION DEVICES, INC. + +OUI:00902B* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00902C* + ID_OUI_FROM_DATABASE=DATA & CONTROL EQUIPMENT LTD. + +OUI:00902D* + ID_OUI_FROM_DATABASE=DATA ELECTRONICS (AUST.) PTY, LTD. + +OUI:00902E* + ID_OUI_FROM_DATABASE=NAMCO LIMITED + +OUI:00902F* + ID_OUI_FROM_DATABASE=NETCORE SYSTEMS, INC. + +OUI:009030* + ID_OUI_FROM_DATABASE=HONEYWELL-DATING + +OUI:009031* + ID_OUI_FROM_DATABASE=MYSTICOM, LTD. + +OUI:009032* + ID_OUI_FROM_DATABASE=PELCOMBE GROUP LTD. + +OUI:009033* + ID_OUI_FROM_DATABASE=INNOVAPHONE AG + +OUI:009034* + ID_OUI_FROM_DATABASE=IMAGIC, INC. + +OUI:009035* + ID_OUI_FROM_DATABASE=ALPHA TELECOM, INC. + +OUI:009036* + ID_OUI_FROM_DATABASE=ens, inc. + +OUI:009037* + ID_OUI_FROM_DATABASE=ACUCOMM, INC. + +OUI:009038* + ID_OUI_FROM_DATABASE=FOUNTAIN TECHNOLOGIES, INC. + +OUI:009039* + ID_OUI_FROM_DATABASE=SHASTA NETWORKS + +OUI:00903A* + ID_OUI_FROM_DATABASE=NIHON MEDIA TOOL INC. + +OUI:00903B* + ID_OUI_FROM_DATABASE=TriEMS Research Lab, Inc. + +OUI:00903C* + ID_OUI_FROM_DATABASE=ATLANTIC NETWORK SYSTEMS + +OUI:00903D* + ID_OUI_FROM_DATABASE=BIOPAC SYSTEMS, INC. + +OUI:00903E* + ID_OUI_FROM_DATABASE=N.V. PHILIPS INDUSTRIAL ACTIVITIES + +OUI:00903F* + ID_OUI_FROM_DATABASE=AZTEC RADIOMEDIA + +OUI:009040* + ID_OUI_FROM_DATABASE=Siemens Network Convergence LLC + +OUI:009041* + ID_OUI_FROM_DATABASE=APPLIED DIGITAL ACCESS + +OUI:009042* + ID_OUI_FROM_DATABASE=ECCS, Inc. + +OUI:009043* + ID_OUI_FROM_DATABASE=Tattile SRL + +OUI:009044* + ID_OUI_FROM_DATABASE=ASSURED DIGITAL, INC. + +OUI:009045* + ID_OUI_FROM_DATABASE=Marconi Communications + +OUI:009046* + ID_OUI_FROM_DATABASE=DEXDYNE, LTD. + +OUI:009047* + ID_OUI_FROM_DATABASE=GIGA FAST E. LTD. + +OUI:009048* + ID_OUI_FROM_DATABASE=ZEAL CORPORATION + +OUI:009049* + ID_OUI_FROM_DATABASE=ENTRIDIA CORPORATION + +OUI:00904A* + ID_OUI_FROM_DATABASE=CONCUR SYSTEM TECHNOLOGIES + +OUI:00904B* + ID_OUI_FROM_DATABASE=GemTek Technology Co., Ltd. + +OUI:00904C* + ID_OUI_FROM_DATABASE=EPIGRAM, INC. + +OUI:00904D* + ID_OUI_FROM_DATABASE=SPEC S.A. + +OUI:00904E* + ID_OUI_FROM_DATABASE=DELEM BV + +OUI:00904F* + ID_OUI_FROM_DATABASE=ABB POWER T&D COMPANY, INC. + +OUI:009050* + ID_OUI_FROM_DATABASE=TELESTE OY + +OUI:009051* + ID_OUI_FROM_DATABASE=ULTIMATE TECHNOLOGY CORP. + +OUI:009052* + ID_OUI_FROM_DATABASE=SELCOM ELETTRONICA S.R.L. + +OUI:009053* + ID_OUI_FROM_DATABASE=DAEWOO ELECTRONICS CO., LTD. + +OUI:009054* + ID_OUI_FROM_DATABASE=INNOVATIVE SEMICONDUCTORS, INC + +OUI:009055* + ID_OUI_FROM_DATABASE=PARKER HANNIFIN CORPORATION COMPUMOTOR DIVISION + +OUI:009056* + ID_OUI_FROM_DATABASE=TELESTREAM, INC. + +OUI:009057* + ID_OUI_FROM_DATABASE=AANetcom, Inc. + +OUI:009058* + ID_OUI_FROM_DATABASE=Ultra Electronics Ltd., Command and Control Systems + +OUI:009059* + ID_OUI_FROM_DATABASE=TELECOM DEVICE K.K. + +OUI:00905A* + ID_OUI_FROM_DATABASE=DEARBORN GROUP, INC. + +OUI:00905B* + ID_OUI_FROM_DATABASE=RAYMOND AND LAE ENGINEERING + +OUI:00905C* + ID_OUI_FROM_DATABASE=EDMI + +OUI:00905D* + ID_OUI_FROM_DATABASE=NETCOM SICHERHEITSTECHNIK GmbH + +OUI:00905E* + ID_OUI_FROM_DATABASE=RAULAND-BORG CORPORATION + +OUI:00905F* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:009060* + ID_OUI_FROM_DATABASE=SYSTEM CREATE CORP. + +OUI:009061* + ID_OUI_FROM_DATABASE=PACIFIC RESEARCH & ENGINEERING CORPORATION + +OUI:009062* + ID_OUI_FROM_DATABASE=ICP VORTEX COMPUTERSYSTEME GmbH + +OUI:009063* + ID_OUI_FROM_DATABASE=COHERENT COMMUNICATIONS SYSTEMS CORPORATION + +OUI:009064* + ID_OUI_FROM_DATABASE=Thomson Inc. + +OUI:009065* + ID_OUI_FROM_DATABASE=FINISAR CORPORATION + +OUI:009066* + ID_OUI_FROM_DATABASE=Troika Networks, Inc. + +OUI:009067* + ID_OUI_FROM_DATABASE=WalkAbout Computers, Inc. + +OUI:009068* + ID_OUI_FROM_DATABASE=DVT CORP. + +OUI:009069* + ID_OUI_FROM_DATABASE=JUNIPER NETWORKS, INC. + +OUI:00906A* + ID_OUI_FROM_DATABASE=TURNSTONE SYSTEMS, INC. + +OUI:00906B* + ID_OUI_FROM_DATABASE=APPLIED RESOURCES, INC. + +OUI:00906C* + ID_OUI_FROM_DATABASE=Sartorius Hamburg GmbH + +OUI:00906D* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00906E* + ID_OUI_FROM_DATABASE=PRAXON, INC. + +OUI:00906F* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:009070* + ID_OUI_FROM_DATABASE=NEO NETWORKS, INC. + +OUI:009071* + ID_OUI_FROM_DATABASE=Applied Innovation Inc. + +OUI:009072* + ID_OUI_FROM_DATABASE=SIMRAD AS + +OUI:009073* + ID_OUI_FROM_DATABASE=GAIO TECHNOLOGY + +OUI:009074* + ID_OUI_FROM_DATABASE=ARGON NETWORKS, INC. + +OUI:009075* + ID_OUI_FROM_DATABASE=NEC DO BRASIL S.A. + +OUI:009076* + ID_OUI_FROM_DATABASE=FMT AIRCRAFT GATE SUPPORT SYSTEMS AB + +OUI:009077* + ID_OUI_FROM_DATABASE=ADVANCED FIBRE COMMUNICATIONS + +OUI:009078* + ID_OUI_FROM_DATABASE=MER TELEMANAGEMENT SOLUTIONS, LTD. + +OUI:009079* + ID_OUI_FROM_DATABASE=ClearOne, Inc. + +OUI:00907A* + ID_OUI_FROM_DATABASE=Polycom, Inc. + +OUI:00907B* + ID_OUI_FROM_DATABASE=E-TECH, INC. + +OUI:00907C* + ID_OUI_FROM_DATABASE=DIGITALCAST, INC. + +OUI:00907D* + ID_OUI_FROM_DATABASE=Lake Communications + +OUI:00907E* + ID_OUI_FROM_DATABASE=VETRONIX CORP. + +OUI:00907F* + ID_OUI_FROM_DATABASE=WatchGuard Technologies, Inc. + +OUI:009080* + ID_OUI_FROM_DATABASE=NOT LIMITED, INC. + +OUI:009081* + ID_OUI_FROM_DATABASE=ALOHA NETWORKS, INC. + +OUI:009082* + ID_OUI_FROM_DATABASE=FORCE INSTITUTE + +OUI:009083* + ID_OUI_FROM_DATABASE=TURBO COMMUNICATION, INC. + +OUI:009084* + ID_OUI_FROM_DATABASE=ATECH SYSTEM + +OUI:009085* + ID_OUI_FROM_DATABASE=GOLDEN ENTERPRISES, INC. + +OUI:009086* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:009087* + ID_OUI_FROM_DATABASE=ITIS + +OUI:009088* + ID_OUI_FROM_DATABASE=BAXALL SECURITY LTD. + +OUI:009089* + ID_OUI_FROM_DATABASE=SOFTCOM MICROSYSTEMS, INC. + +OUI:00908A* + ID_OUI_FROM_DATABASE=BAYLY COMMUNICATIONS, INC. + +OUI:00908B* + ID_OUI_FROM_DATABASE=Tattile SRL + +OUI:00908C* + ID_OUI_FROM_DATABASE=ETREND ELECTRONICS, INC. + +OUI:00908D* + ID_OUI_FROM_DATABASE=VICKERS ELECTRONICS SYSTEMS + +OUI:00908E* + ID_OUI_FROM_DATABASE=Nortel Networks Broadband Access + +OUI:00908F* + ID_OUI_FROM_DATABASE=AUDIO CODES LTD. + +OUI:009090* + ID_OUI_FROM_DATABASE=I-BUS + +OUI:009091* + ID_OUI_FROM_DATABASE=DigitalScape, Inc. + +OUI:009092* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:009093* + ID_OUI_FROM_DATABASE=NANAO CORPORATION + +OUI:009094* + ID_OUI_FROM_DATABASE=OSPREY TECHNOLOGIES, INC. + +OUI:009095* + ID_OUI_FROM_DATABASE=UNIVERSAL AVIONICS + +OUI:009096* + ID_OUI_FROM_DATABASE=ASKEY COMPUTER CORP. + +OUI:009097* + ID_OUI_FROM_DATABASE=Sycamore Networks + +OUI:009098* + ID_OUI_FROM_DATABASE=SBC DESIGNS, INC. + +OUI:009099* + ID_OUI_FROM_DATABASE=ALLIED TELESIS, K.K. + +OUI:00909A* + ID_OUI_FROM_DATABASE=ONE WORLD SYSTEMS, INC. + +OUI:00909B* + ID_OUI_FROM_DATABASE=IMAJE + +OUI:00909C* + ID_OUI_FROM_DATABASE=Motorola, Inc. + +OUI:00909D* + ID_OUI_FROM_DATABASE=NovaTech Process Solutions, LLC + +OUI:00909E* + ID_OUI_FROM_DATABASE=Critical IO, LLC + +OUI:00909F* + ID_OUI_FROM_DATABASE=DIGI-DATA CORPORATION + +OUI:0090A0* + ID_OUI_FROM_DATABASE=8X8 INC. + +OUI:0090A1* + ID_OUI_FROM_DATABASE=Flying Pig Systems/High End Systems Inc. + +OUI:0090A2* + ID_OUI_FROM_DATABASE=CYBERTAN TECHNOLOGY, INC. + +OUI:0090A3* + ID_OUI_FROM_DATABASE=Corecess Inc. + +OUI:0090A4* + ID_OUI_FROM_DATABASE=ALTIGA NETWORKS + +OUI:0090A5* + ID_OUI_FROM_DATABASE=SPECTRA LOGIC + +OUI:0090A6* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0090A7* + ID_OUI_FROM_DATABASE=CLIENTEC CORPORATION + +OUI:0090A8* + ID_OUI_FROM_DATABASE=NineTiles Networks, Ltd. + +OUI:0090A9* + ID_OUI_FROM_DATABASE=WESTERN DIGITAL + +OUI:0090AA* + ID_OUI_FROM_DATABASE=INDIGO ACTIVE VISION SYSTEMS LIMITED + +OUI:0090AB* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0090AC* + ID_OUI_FROM_DATABASE=OPTIVISION, INC. + +OUI:0090AD* + ID_OUI_FROM_DATABASE=ASPECT ELECTRONICS, INC. + +OUI:0090AE* + ID_OUI_FROM_DATABASE=ITALTEL S.p.A. + +OUI:0090AF* + ID_OUI_FROM_DATABASE=J. MORITA MFG. CORP. + +OUI:0090B0* + ID_OUI_FROM_DATABASE=VADEM + +OUI:0090B1* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0090B2* + ID_OUI_FROM_DATABASE=AVICI SYSTEMS INC. + +OUI:0090B3* + ID_OUI_FROM_DATABASE=AGRANAT SYSTEMS + +OUI:0090B4* + ID_OUI_FROM_DATABASE=WILLOWBROOK TECHNOLOGIES + +OUI:0090B5* + ID_OUI_FROM_DATABASE=NIKON CORPORATION + +OUI:0090B6* + ID_OUI_FROM_DATABASE=FIBEX SYSTEMS + +OUI:0090B7* + ID_OUI_FROM_DATABASE=DIGITAL LIGHTWAVE, INC. + +OUI:0090B8* + ID_OUI_FROM_DATABASE=ROHDE & SCHWARZ GMBH & CO. KG + +OUI:0090B9* + ID_OUI_FROM_DATABASE=BERAN INSTRUMENTS LTD. + +OUI:0090BA* + ID_OUI_FROM_DATABASE=VALID NETWORKS, INC. + +OUI:0090BB* + ID_OUI_FROM_DATABASE=TAINET COMMUNICATION SYSTEM Corp. + +OUI:0090BC* + ID_OUI_FROM_DATABASE=TELEMANN CO., LTD. + +OUI:0090BD* + ID_OUI_FROM_DATABASE=OMNIA COMMUNICATIONS, INC. + +OUI:0090BE* + ID_OUI_FROM_DATABASE=IBC/INTEGRATED BUSINESS COMPUTERS + +OUI:0090BF* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0090C0* + ID_OUI_FROM_DATABASE=K.J. LAW ENGINEERS, INC. + +OUI:0090C1* + ID_OUI_FROM_DATABASE=Peco II, Inc. + +OUI:0090C2* + ID_OUI_FROM_DATABASE=JK microsystems, Inc. + +OUI:0090C3* + ID_OUI_FROM_DATABASE=TOPIC SEMICONDUCTOR CORP. + +OUI:0090C4* + ID_OUI_FROM_DATABASE=JAVELIN SYSTEMS, INC. + +OUI:0090C5* + ID_OUI_FROM_DATABASE=INTERNET MAGIC, INC. + +OUI:0090C6* + ID_OUI_FROM_DATABASE=OPTIM SYSTEMS, INC. + +OUI:0090C7* + ID_OUI_FROM_DATABASE=ICOM INC. + +OUI:0090C8* + ID_OUI_FROM_DATABASE=WAVERIDER COMMUNICATIONS (CANADA) INC. + +OUI:0090C9* + ID_OUI_FROM_DATABASE=DPAC Technologies + +OUI:0090CA* + ID_OUI_FROM_DATABASE=ACCORD VIDEO TELECOMMUNICATIONS, LTD. + +OUI:0090CB* + ID_OUI_FROM_DATABASE=Wireless OnLine, Inc. + +OUI:0090CC* + ID_OUI_FROM_DATABASE=Planex Communications + +OUI:0090CD* + ID_OUI_FROM_DATABASE=ENT-EMPRESA NACIONAL DE TELECOMMUNICACOES, S.A. + +OUI:0090CE* + ID_OUI_FROM_DATABASE=TETRA GmbH + +OUI:0090CF* + ID_OUI_FROM_DATABASE=NORTEL + +OUI:0090D0* + ID_OUI_FROM_DATABASE=Thomson Telecom Belgium + +OUI:0090D1* + ID_OUI_FROM_DATABASE=LEICHU ENTERPRISE CO., LTD. + +OUI:0090D2* + ID_OUI_FROM_DATABASE=ARTEL VIDEO SYSTEMS + +OUI:0090D3* + ID_OUI_FROM_DATABASE=GIESECKE & DEVRIENT GmbH + +OUI:0090D4* + ID_OUI_FROM_DATABASE=BindView Development Corp. + +OUI:0090D5* + ID_OUI_FROM_DATABASE=EUPHONIX, INC. + +OUI:0090D6* + ID_OUI_FROM_DATABASE=CRYSTAL GROUP + +OUI:0090D7* + ID_OUI_FROM_DATABASE=NetBoost Corp. + +OUI:0090D8* + ID_OUI_FROM_DATABASE=WHITECROSS SYSTEMS + +OUI:0090D9* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0090DA* + ID_OUI_FROM_DATABASE=DYNARC, INC. + +OUI:0090DB* + ID_OUI_FROM_DATABASE=NEXT LEVEL COMMUNICATIONS + +OUI:0090DC* + ID_OUI_FROM_DATABASE=TECO INFORMATION SYSTEMS + +OUI:0090DD* + ID_OUI_FROM_DATABASE=THE MIHARU COMMUNICATIONS CO., LTD. + +OUI:0090DE* + ID_OUI_FROM_DATABASE=CARDKEY SYSTEMS, INC. + +OUI:0090DF* + ID_OUI_FROM_DATABASE=MITSUBISHI CHEMICAL AMERICA, INC. + +OUI:0090E0* + ID_OUI_FROM_DATABASE=SYSTRAN CORP. + +OUI:0090E1* + ID_OUI_FROM_DATABASE=TELENA S.P.A. + +OUI:0090E2* + ID_OUI_FROM_DATABASE=DISTRIBUTED PROCESSING TECHNOLOGY + +OUI:0090E3* + ID_OUI_FROM_DATABASE=AVEX ELECTRONICS INC. + +OUI:0090E4* + ID_OUI_FROM_DATABASE=NEC AMERICA, INC. + +OUI:0090E5* + ID_OUI_FROM_DATABASE=TEKNEMA, INC. + +OUI:0090E6* + ID_OUI_FROM_DATABASE=ALi Corporation + +OUI:0090E7* + ID_OUI_FROM_DATABASE=HORSCH ELEKTRONIK AG + +OUI:0090E8* + ID_OUI_FROM_DATABASE=MOXA TECHNOLOGIES CORP., LTD. + +OUI:0090E9* + ID_OUI_FROM_DATABASE=JANZ COMPUTER AG + +OUI:0090EA* + ID_OUI_FROM_DATABASE=ALPHA TECHNOLOGIES, INC. + +OUI:0090EB* + ID_OUI_FROM_DATABASE=SENTRY TELECOM SYSTEMS + +OUI:0090EC* + ID_OUI_FROM_DATABASE=PYRESCOM + +OUI:0090ED* + ID_OUI_FROM_DATABASE=CENTRAL SYSTEM RESEARCH CO., LTD. + +OUI:0090EE* + ID_OUI_FROM_DATABASE=PERSONAL COMMUNICATIONS TECHNOLOGIES + +OUI:0090EF* + ID_OUI_FROM_DATABASE=INTEGRIX, INC. + +OUI:0090F0* + ID_OUI_FROM_DATABASE=Harmonic Video Systems Ltd. + +OUI:0090F1* + ID_OUI_FROM_DATABASE=DOT HILL SYSTEMS CORPORATION + +OUI:0090F2* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0090F3* + ID_OUI_FROM_DATABASE=ASPECT COMMUNICATIONS + +OUI:0090F4* + ID_OUI_FROM_DATABASE=LIGHTNING INSTRUMENTATION + +OUI:0090F5* + ID_OUI_FROM_DATABASE=CLEVO CO. + +OUI:0090F6* + ID_OUI_FROM_DATABASE=ESCALATE NETWORKS, INC. + +OUI:0090F7* + ID_OUI_FROM_DATABASE=NBASE COMMUNICATIONS LTD. + +OUI:0090F8* + ID_OUI_FROM_DATABASE=MEDIATRIX TELECOM + +OUI:0090F9* + ID_OUI_FROM_DATABASE=LEITCH + +OUI:0090FA* + ID_OUI_FROM_DATABASE=EMULEX Corp + +OUI:0090FB* + ID_OUI_FROM_DATABASE=PORTWELL, INC. + +OUI:0090FC* + ID_OUI_FROM_DATABASE=NETWORK COMPUTING DEVICES + +OUI:0090FD* + ID_OUI_FROM_DATABASE=CopperCom, Inc. + +OUI:0090FE* + ID_OUI_FROM_DATABASE=ELECOM CO., LTD. (LANEED DIV.) + +OUI:0090FF* + ID_OUI_FROM_DATABASE=TELLUS TECHNOLOGY INC. + +OUI:0091D6* + ID_OUI_FROM_DATABASE=Crystal Group, Inc. + +OUI:0091FA* + ID_OUI_FROM_DATABASE=Synapse Product Development + +OUI:009363* + ID_OUI_FROM_DATABASE=Uni-Link Technology Co., Ltd. + +OUI:009569* + ID_OUI_FROM_DATABASE=LSD Science and Technology Co.,Ltd. + +OUI:0097FF* + ID_OUI_FROM_DATABASE=Heimann Sensor GmbH + +OUI:009C02* + ID_OUI_FROM_DATABASE=Hewlett-Packard Company + +OUI:009D8E* + ID_OUI_FROM_DATABASE=CARDIAC RECORDERS, INC. + +OUI:00A000* + ID_OUI_FROM_DATABASE=CENTILLION NETWORKS, INC. + +OUI:00A001* + ID_OUI_FROM_DATABASE=DRS Signal Solutions + +OUI:00A002* + ID_OUI_FROM_DATABASE=LEEDS & NORTHRUP AUSTRALIA PTY LTD + +OUI:00A003* + ID_OUI_FROM_DATABASE=Siemens Switzerland Ltd., I B T HVP + +OUI:00A004* + ID_OUI_FROM_DATABASE=NETPOWER, INC. + +OUI:00A005* + ID_OUI_FROM_DATABASE=DANIEL INSTRUMENTS, LTD. + +OUI:00A006* + ID_OUI_FROM_DATABASE=IMAGE DATA PROCESSING SYSTEM GROUP + +OUI:00A007* + ID_OUI_FROM_DATABASE=APEXX TECHNOLOGY, INC. + +OUI:00A008* + ID_OUI_FROM_DATABASE=NETCORP + +OUI:00A009* + ID_OUI_FROM_DATABASE=WHITETREE NETWORK + +OUI:00A00A* + ID_OUI_FROM_DATABASE=Airspan + +OUI:00A00B* + ID_OUI_FROM_DATABASE=COMPUTEX CO., LTD. + +OUI:00A00C* + ID_OUI_FROM_DATABASE=KINGMAX TECHNOLOGY, INC. + +OUI:00A00D* + ID_OUI_FROM_DATABASE=THE PANDA PROJECT + +OUI:00A00E* + ID_OUI_FROM_DATABASE=VISUAL NETWORKS, INC. + +OUI:00A00F* + ID_OUI_FROM_DATABASE=Broadband Technologies + +OUI:00A010* + ID_OUI_FROM_DATABASE=SYSLOGIC DATENTECHNIK AG + +OUI:00A011* + ID_OUI_FROM_DATABASE=MUTOH INDUSTRIES LTD. + +OUI:00A012* + ID_OUI_FROM_DATABASE=Telco Systems, Inc. + +OUI:00A013* + ID_OUI_FROM_DATABASE=TELTREND LTD. + +OUI:00A014* + ID_OUI_FROM_DATABASE=CSIR + +OUI:00A015* + ID_OUI_FROM_DATABASE=WYLE + +OUI:00A016* + ID_OUI_FROM_DATABASE=MICROPOLIS CORP. + +OUI:00A017* + ID_OUI_FROM_DATABASE=J B M CORPORATION + +OUI:00A018* + ID_OUI_FROM_DATABASE=CREATIVE CONTROLLERS, INC. + +OUI:00A019* + ID_OUI_FROM_DATABASE=NEBULA CONSULTANTS, INC. + +OUI:00A01A* + ID_OUI_FROM_DATABASE=BINAR ELEKTRONIK AB + +OUI:00A01B* + ID_OUI_FROM_DATABASE=PREMISYS COMMUNICATIONS, INC. + +OUI:00A01C* + ID_OUI_FROM_DATABASE=NASCENT NETWORKS CORPORATION + +OUI:00A01D* + ID_OUI_FROM_DATABASE=SIXNET + +OUI:00A01E* + ID_OUI_FROM_DATABASE=EST CORPORATION + +OUI:00A01F* + ID_OUI_FROM_DATABASE=TRICORD SYSTEMS, INC. + +OUI:00A020* + ID_OUI_FROM_DATABASE=CITICORP/TTI + +OUI:00A021* + ID_OUI_FROM_DATABASE=General Dynamics + +OUI:00A022* + ID_OUI_FROM_DATABASE=CENTRE FOR DEVELOPMENT OF ADVANCED COMPUTING + +OUI:00A023* + ID_OUI_FROM_DATABASE=APPLIED CREATIVE TECHNOLOGY, INC. + +OUI:00A024* + ID_OUI_FROM_DATABASE=3COM CORPORATION + +OUI:00A025* + ID_OUI_FROM_DATABASE=REDCOM LABS INC. + +OUI:00A026* + ID_OUI_FROM_DATABASE=TELDAT, S.A. + +OUI:00A027* + ID_OUI_FROM_DATABASE=FIREPOWER SYSTEMS, INC. + +OUI:00A028* + ID_OUI_FROM_DATABASE=CONNER PERIPHERALS + +OUI:00A029* + ID_OUI_FROM_DATABASE=COULTER CORPORATION + +OUI:00A02A* + ID_OUI_FROM_DATABASE=TRANCELL SYSTEMS + +OUI:00A02B* + ID_OUI_FROM_DATABASE=TRANSITIONS RESEARCH CORP. + +OUI:00A02C* + ID_OUI_FROM_DATABASE=interWAVE Communications + +OUI:00A02D* + ID_OUI_FROM_DATABASE=1394 Trade Association + +OUI:00A02E* + ID_OUI_FROM_DATABASE=BRAND COMMUNICATIONS, LTD. + +OUI:00A02F* + ID_OUI_FROM_DATABASE=PIRELLI CAVI + +OUI:00A030* + ID_OUI_FROM_DATABASE=CAPTOR NV/SA + +OUI:00A031* + ID_OUI_FROM_DATABASE=HAZELTINE CORPORATION, MS 1-17 + +OUI:00A032* + ID_OUI_FROM_DATABASE=GES SINGAPORE PTE. LTD. + +OUI:00A033* + ID_OUI_FROM_DATABASE=imc MeBsysteme GmbH + +OUI:00A034* + ID_OUI_FROM_DATABASE=AXEL + +OUI:00A035* + ID_OUI_FROM_DATABASE=CYLINK CORPORATION + +OUI:00A036* + ID_OUI_FROM_DATABASE=APPLIED NETWORK TECHNOLOGY + +OUI:00A037* + ID_OUI_FROM_DATABASE=Mindray DS USA, Inc. + +OUI:00A038* + ID_OUI_FROM_DATABASE=EMAIL ELECTRONICS + +OUI:00A039* + ID_OUI_FROM_DATABASE=ROSS TECHNOLOGY, INC. + +OUI:00A03A* + ID_OUI_FROM_DATABASE=KUBOTEK CORPORATION + +OUI:00A03B* + ID_OUI_FROM_DATABASE=TOSHIN ELECTRIC CO., LTD. + +OUI:00A03C* + ID_OUI_FROM_DATABASE=EG&G NUCLEAR INSTRUMENTS + +OUI:00A03D* + ID_OUI_FROM_DATABASE=OPTO-22 + +OUI:00A03E* + ID_OUI_FROM_DATABASE=ATM FORUM + +OUI:00A03F* + ID_OUI_FROM_DATABASE=COMPUTER SOCIETY MICROPROCESSOR & MICROPROCESSOR STANDARDS C + +OUI:00A040* + ID_OUI_FROM_DATABASE=APPLE COMPUTER + +OUI:00A041* + ID_OUI_FROM_DATABASE=INFICON + +OUI:00A042* + ID_OUI_FROM_DATABASE=SPUR PRODUCTS CORP. + +OUI:00A043* + ID_OUI_FROM_DATABASE=AMERICAN TECHNOLOGY LABS, INC. + +OUI:00A044* + ID_OUI_FROM_DATABASE=NTT IT CO., LTD. + +OUI:00A045* + ID_OUI_FROM_DATABASE=PHOENIX CONTACT GMBH & CO. + +OUI:00A046* + ID_OUI_FROM_DATABASE=SCITEX CORP. LTD. + +OUI:00A047* + ID_OUI_FROM_DATABASE=INTEGRATED FITNESS CORP. + +OUI:00A048* + ID_OUI_FROM_DATABASE=QUESTECH, LTD. + +OUI:00A049* + ID_OUI_FROM_DATABASE=DIGITECH INDUSTRIES, INC. + +OUI:00A04A* + ID_OUI_FROM_DATABASE=NISSHIN ELECTRIC CO., LTD. + +OUI:00A04B* + ID_OUI_FROM_DATABASE=TFL LAN INC. + +OUI:00A04C* + ID_OUI_FROM_DATABASE=INNOVATIVE SYSTEMS & TECHNOLOGIES, INC. + +OUI:00A04D* + ID_OUI_FROM_DATABASE=EDA INSTRUMENTS, INC. + +OUI:00A04E* + ID_OUI_FROM_DATABASE=VOELKER TECHNOLOGIES, INC. + +OUI:00A04F* + ID_OUI_FROM_DATABASE=AMERITEC CORP. + +OUI:00A050* + ID_OUI_FROM_DATABASE=CYPRESS SEMICONDUCTOR + +OUI:00A051* + ID_OUI_FROM_DATABASE=ANGIA COMMUNICATIONS. INC. + +OUI:00A052* + ID_OUI_FROM_DATABASE=STANILITE ELECTRONICS PTY. LTD + +OUI:00A053* + ID_OUI_FROM_DATABASE=COMPACT DEVICES, INC. + +OUI:00A055* + ID_OUI_FROM_DATABASE=Data Device Corporation + +OUI:00A056* + ID_OUI_FROM_DATABASE=MICROPROSS + +OUI:00A057* + ID_OUI_FROM_DATABASE=LANCOM Systems GmbH + +OUI:00A058* + ID_OUI_FROM_DATABASE=GLORY, LTD. + +OUI:00A059* + ID_OUI_FROM_DATABASE=HAMILTON HALLMARK + +OUI:00A05A* + ID_OUI_FROM_DATABASE=KOFAX IMAGE PRODUCTS + +OUI:00A05B* + ID_OUI_FROM_DATABASE=MARQUIP, INC. + +OUI:00A05C* + ID_OUI_FROM_DATABASE=INVENTORY CONVERSION, INC./ + +OUI:00A05D* + ID_OUI_FROM_DATABASE=CS COMPUTER SYSTEME GmbH + +OUI:00A05E* + ID_OUI_FROM_DATABASE=MYRIAD LOGIC INC. + +OUI:00A05F* + ID_OUI_FROM_DATABASE=BTG Electronics Design BV + +OUI:00A060* + ID_OUI_FROM_DATABASE=ACER PERIPHERALS, INC. + +OUI:00A061* + ID_OUI_FROM_DATABASE=PURITAN BENNETT + +OUI:00A062* + ID_OUI_FROM_DATABASE=AES PRODATA + +OUI:00A063* + ID_OUI_FROM_DATABASE=JRL SYSTEMS, INC. + +OUI:00A064* + ID_OUI_FROM_DATABASE=KVB/ANALECT + +OUI:00A065* + ID_OUI_FROM_DATABASE=Symantec Corporation + +OUI:00A066* + ID_OUI_FROM_DATABASE=ISA CO., LTD. + +OUI:00A067* + ID_OUI_FROM_DATABASE=NETWORK SERVICES GROUP + +OUI:00A068* + ID_OUI_FROM_DATABASE=BHP LIMITED + +OUI:00A069* + ID_OUI_FROM_DATABASE=Symmetricom, Inc. + +OUI:00A06A* + ID_OUI_FROM_DATABASE=Verilink Corporation + +OUI:00A06B* + ID_OUI_FROM_DATABASE=DMS DORSCH MIKROSYSTEM GMBH + +OUI:00A06C* + ID_OUI_FROM_DATABASE=SHINDENGEN ELECTRIC MFG. CO., LTD. + +OUI:00A06D* + ID_OUI_FROM_DATABASE=MANNESMANN TALLY CORPORATION + +OUI:00A06E* + ID_OUI_FROM_DATABASE=AUSTRON, INC. + +OUI:00A06F* + ID_OUI_FROM_DATABASE=THE APPCON GROUP, INC. + +OUI:00A070* + ID_OUI_FROM_DATABASE=COASTCOM + +OUI:00A071* + ID_OUI_FROM_DATABASE=VIDEO LOTTERY TECHNOLOGIES,INC + +OUI:00A072* + ID_OUI_FROM_DATABASE=OVATION SYSTEMS LTD. + +OUI:00A073* + ID_OUI_FROM_DATABASE=COM21, INC. + +OUI:00A074* + ID_OUI_FROM_DATABASE=PERCEPTION TECHNOLOGY + +OUI:00A075* + ID_OUI_FROM_DATABASE=MICRON TECHNOLOGY, INC. + +OUI:00A076* + ID_OUI_FROM_DATABASE=CARDWARE LAB, INC. + +OUI:00A077* + ID_OUI_FROM_DATABASE=FUJITSU NEXION, INC. + +OUI:00A078* + ID_OUI_FROM_DATABASE=Marconi Communications + +OUI:00A079* + ID_OUI_FROM_DATABASE=ALPS ELECTRIC (USA), INC. + +OUI:00A07A* + ID_OUI_FROM_DATABASE=ADVANCED PERIPHERALS TECHNOLOGIES, INC. + +OUI:00A07B* + ID_OUI_FROM_DATABASE=DAWN COMPUTER INCORPORATION + +OUI:00A07C* + ID_OUI_FROM_DATABASE=TONYANG NYLON CO., LTD. + +OUI:00A07D* + ID_OUI_FROM_DATABASE=SEEQ TECHNOLOGY, INC. + +OUI:00A07E* + ID_OUI_FROM_DATABASE=AVID TECHNOLOGY, INC. + +OUI:00A07F* + ID_OUI_FROM_DATABASE=GSM-SYNTEL, LTD. + +OUI:00A080* + ID_OUI_FROM_DATABASE=Tattile SRL + +OUI:00A081* + ID_OUI_FROM_DATABASE=ALCATEL DATA NETWORKS + +OUI:00A082* + ID_OUI_FROM_DATABASE=NKT ELEKTRONIK A/S + +OUI:00A083* + ID_OUI_FROM_DATABASE=ASIMMPHONY TURKEY + +OUI:00A084* + ID_OUI_FROM_DATABASE=Dataplex Pty Ltd + +OUI:00A086* + ID_OUI_FROM_DATABASE=AMBER WAVE SYSTEMS, INC. + +OUI:00A087* + ID_OUI_FROM_DATABASE=Zarlink Semiconductor Ltd. + +OUI:00A088* + ID_OUI_FROM_DATABASE=ESSENTIAL COMMUNICATIONS + +OUI:00A089* + ID_OUI_FROM_DATABASE=XPOINT TECHNOLOGIES, INC. + +OUI:00A08A* + ID_OUI_FROM_DATABASE=BROOKTROUT TECHNOLOGY, INC. + +OUI:00A08B* + ID_OUI_FROM_DATABASE=ASTON ELECTRONIC DESIGNS LTD. + +OUI:00A08C* + ID_OUI_FROM_DATABASE=MultiMedia LANs, Inc. + +OUI:00A08D* + ID_OUI_FROM_DATABASE=JACOMO CORPORATION + +OUI:00A08E* + ID_OUI_FROM_DATABASE=Check Point Software Technologies + +OUI:00A08F* + ID_OUI_FROM_DATABASE=DESKNET SYSTEMS, INC. + +OUI:00A090* + ID_OUI_FROM_DATABASE=TimeStep Corporation + +OUI:00A091* + ID_OUI_FROM_DATABASE=APPLICOM INTERNATIONAL + +OUI:00A092* + ID_OUI_FROM_DATABASE=H. BOLLMANN MANUFACTURERS, LTD + +OUI:00A093* + ID_OUI_FROM_DATABASE=B/E AEROSPACE, Inc. + +OUI:00A094* + ID_OUI_FROM_DATABASE=COMSAT CORPORATION + +OUI:00A095* + ID_OUI_FROM_DATABASE=ACACIA NETWORKS, INC. + +OUI:00A096* + ID_OUI_FROM_DATABASE=MITSUMI ELECTRIC CO., LTD. + +OUI:00A097* + ID_OUI_FROM_DATABASE=JC INFORMATION SYSTEMS + +OUI:00A098* + ID_OUI_FROM_DATABASE=NetApp + +OUI:00A099* + ID_OUI_FROM_DATABASE=K-NET LTD. + +OUI:00A09A* + ID_OUI_FROM_DATABASE=NIHON KOHDEN AMERICA + +OUI:00A09B* + ID_OUI_FROM_DATABASE=QPSX COMMUNICATIONS, LTD. + +OUI:00A09C* + ID_OUI_FROM_DATABASE=Xyplex, Inc. + +OUI:00A09D* + ID_OUI_FROM_DATABASE=JOHNATHON FREEMAN TECHNOLOGIES + +OUI:00A09E* + ID_OUI_FROM_DATABASE=ICTV + +OUI:00A09F* + ID_OUI_FROM_DATABASE=COMMVISION CORP. + +OUI:00A0A0* + ID_OUI_FROM_DATABASE=COMPACT DATA, LTD. + +OUI:00A0A1* + ID_OUI_FROM_DATABASE=EPIC DATA INC. + +OUI:00A0A2* + ID_OUI_FROM_DATABASE=DIGICOM S.P.A. + +OUI:00A0A3* + ID_OUI_FROM_DATABASE=RELIABLE POWER METERS + +OUI:00A0A4* + ID_OUI_FROM_DATABASE=MICROS SYSTEMS, INC. + +OUI:00A0A5* + ID_OUI_FROM_DATABASE=TEKNOR MICROSYSTEME, INC. + +OUI:00A0A6* + ID_OUI_FROM_DATABASE=M.I. SYSTEMS, K.K. + +OUI:00A0A7* + ID_OUI_FROM_DATABASE=VORAX CORPORATION + +OUI:00A0A8* + ID_OUI_FROM_DATABASE=RENEX CORPORATION + +OUI:00A0A9* + ID_OUI_FROM_DATABASE=NAVTEL COMMUNICATIONS INC. + +OUI:00A0AA* + ID_OUI_FROM_DATABASE=SPACELABS MEDICAL + +OUI:00A0AB* + ID_OUI_FROM_DATABASE=NETCS INFORMATIONSTECHNIK GMBH + +OUI:00A0AC* + ID_OUI_FROM_DATABASE=GILAT SATELLITE NETWORKS, LTD. + +OUI:00A0AD* + ID_OUI_FROM_DATABASE=MARCONI SPA + +OUI:00A0AE* + ID_OUI_FROM_DATABASE=NUCOM SYSTEMS, INC. + +OUI:00A0AF* + ID_OUI_FROM_DATABASE=WMS INDUSTRIES + +OUI:00A0B0* + ID_OUI_FROM_DATABASE=I-O DATA DEVICE, INC. + +OUI:00A0B1* + ID_OUI_FROM_DATABASE=FIRST VIRTUAL CORPORATION + +OUI:00A0B2* + ID_OUI_FROM_DATABASE=SHIMA SEIKI + +OUI:00A0B3* + ID_OUI_FROM_DATABASE=ZYKRONIX + +OUI:00A0B4* + ID_OUI_FROM_DATABASE=TEXAS MICROSYSTEMS, INC. + +OUI:00A0B5* + ID_OUI_FROM_DATABASE=3H TECHNOLOGY + +OUI:00A0B6* + ID_OUI_FROM_DATABASE=SANRITZ AUTOMATION CO., LTD. + +OUI:00A0B7* + ID_OUI_FROM_DATABASE=CORDANT, INC. + +OUI:00A0B8* + ID_OUI_FROM_DATABASE=SYMBIOS LOGIC INC. + +OUI:00A0B9* + ID_OUI_FROM_DATABASE=EAGLE TECHNOLOGY, INC. + +OUI:00A0BA* + ID_OUI_FROM_DATABASE=PATTON ELECTRONICS CO. + +OUI:00A0BB* + ID_OUI_FROM_DATABASE=HILAN GMBH + +OUI:00A0BC* + ID_OUI_FROM_DATABASE=VIASAT, INCORPORATED + +OUI:00A0BD* + ID_OUI_FROM_DATABASE=I-TECH CORP. + +OUI:00A0BE* + ID_OUI_FROM_DATABASE=INTEGRATED CIRCUIT SYSTEMS, INC. COMMUNICATIONS GROUP + +OUI:00A0BF* + ID_OUI_FROM_DATABASE=WIRELESS DATA GROUP MOTOROLA + +OUI:00A0C0* + ID_OUI_FROM_DATABASE=DIGITAL LINK CORP. + +OUI:00A0C1* + ID_OUI_FROM_DATABASE=ORTIVUS MEDICAL AB + +OUI:00A0C2* + ID_OUI_FROM_DATABASE=R.A. SYSTEMS CO., LTD. + +OUI:00A0C3* + ID_OUI_FROM_DATABASE=UNICOMPUTER GMBH + +OUI:00A0C4* + ID_OUI_FROM_DATABASE=CRISTIE ELECTRONICS LTD. + +OUI:00A0C5* + ID_OUI_FROM_DATABASE=ZYXEL COMMUNICATION + +OUI:00A0C6* + ID_OUI_FROM_DATABASE=QUALCOMM INCORPORATED + +OUI:00A0C7* + ID_OUI_FROM_DATABASE=TADIRAN TELECOMMUNICATIONS + +OUI:00A0C8* + ID_OUI_FROM_DATABASE=ADTRAN INC. + +OUI:00A0C9* + ID_OUI_FROM_DATABASE=INTEL CORPORATION - HF1-06 + +OUI:00A0CA* + ID_OUI_FROM_DATABASE=FUJITSU DENSO LTD. + +OUI:00A0CB* + ID_OUI_FROM_DATABASE=ARK TELECOMMUNICATIONS, INC. + +OUI:00A0CC* + ID_OUI_FROM_DATABASE=LITE-ON COMMUNICATIONS, INC. + +OUI:00A0CD* + ID_OUI_FROM_DATABASE=DR. JOHANNES HEIDENHAIN GmbH + +OUI:00A0CE* + ID_OUI_FROM_DATABASE=Ecessa + +OUI:00A0CF* + ID_OUI_FROM_DATABASE=SOTAS, INC. + +OUI:00A0D0* + ID_OUI_FROM_DATABASE=TEN X TECHNOLOGY, INC. + +OUI:00A0D1* + ID_OUI_FROM_DATABASE=INVENTEC CORPORATION + +OUI:00A0D2* + ID_OUI_FROM_DATABASE=ALLIED TELESIS INTERNATIONAL CORPORATION + +OUI:00A0D3* + ID_OUI_FROM_DATABASE=INSTEM COMPUTER SYSTEMS, LTD. + +OUI:00A0D4* + ID_OUI_FROM_DATABASE=RADIOLAN, INC. + +OUI:00A0D5* + ID_OUI_FROM_DATABASE=SIERRA WIRELESS INC. + +OUI:00A0D6* + ID_OUI_FROM_DATABASE=SBE, INC. + +OUI:00A0D7* + ID_OUI_FROM_DATABASE=KASTEN CHASE APPLIED RESEARCH + +OUI:00A0D8* + ID_OUI_FROM_DATABASE=SPECTRA - TEK + +OUI:00A0D9* + ID_OUI_FROM_DATABASE=CONVEX COMPUTER CORPORATION + +OUI:00A0DA* + ID_OUI_FROM_DATABASE=INTEGRATED SYSTEMS Technology, Inc. + +OUI:00A0DB* + ID_OUI_FROM_DATABASE=FISHER & PAYKEL PRODUCTION + +OUI:00A0DC* + ID_OUI_FROM_DATABASE=O.N. ELECTRONIC CO., LTD. + +OUI:00A0DD* + ID_OUI_FROM_DATABASE=AZONIX CORPORATION + +OUI:00A0DE* + ID_OUI_FROM_DATABASE=YAMAHA CORPORATION + +OUI:00A0DF* + ID_OUI_FROM_DATABASE=STS TECHNOLOGIES, INC. + +OUI:00A0E0* + ID_OUI_FROM_DATABASE=TENNYSON TECHNOLOGIES PTY LTD + +OUI:00A0E1* + ID_OUI_FROM_DATABASE=WESTPORT RESEARCH ASSOCIATES, INC. + +OUI:00A0E2* + ID_OUI_FROM_DATABASE=Keisokugiken Corporation + +OUI:00A0E3* + ID_OUI_FROM_DATABASE=XKL SYSTEMS CORP. + +OUI:00A0E4* + ID_OUI_FROM_DATABASE=OPTIQUEST + +OUI:00A0E5* + ID_OUI_FROM_DATABASE=NHC COMMUNICATIONS + +OUI:00A0E6* + ID_OUI_FROM_DATABASE=DIALOGIC CORPORATION + +OUI:00A0E7* + ID_OUI_FROM_DATABASE=CENTRAL DATA CORPORATION + +OUI:00A0E8* + ID_OUI_FROM_DATABASE=REUTERS HOLDINGS PLC + +OUI:00A0E9* + ID_OUI_FROM_DATABASE=ELECTRONIC RETAILING SYSTEMS INTERNATIONAL + +OUI:00A0EA* + ID_OUI_FROM_DATABASE=ETHERCOM CORP. + +OUI:00A0EB* + ID_OUI_FROM_DATABASE=Encore Networks, Inc. + +OUI:00A0EC* + ID_OUI_FROM_DATABASE=TRANSMITTON LTD. + +OUI:00A0ED* + ID_OUI_FROM_DATABASE=Brooks Automation, Inc. + +OUI:00A0EE* + ID_OUI_FROM_DATABASE=NASHOBA NETWORKS + +OUI:00A0EF* + ID_OUI_FROM_DATABASE=LUCIDATA LTD. + +OUI:00A0F0* + ID_OUI_FROM_DATABASE=TORONTO MICROELECTRONICS INC. + +OUI:00A0F1* + ID_OUI_FROM_DATABASE=MTI + +OUI:00A0F2* + ID_OUI_FROM_DATABASE=INFOTEK COMMUNICATIONS, INC. + +OUI:00A0F3* + ID_OUI_FROM_DATABASE=STAUBLI + +OUI:00A0F4* + ID_OUI_FROM_DATABASE=GE + +OUI:00A0F5* + ID_OUI_FROM_DATABASE=RADGUARD LTD. + +OUI:00A0F6* + ID_OUI_FROM_DATABASE=AutoGas Systems Inc. + +OUI:00A0F7* + ID_OUI_FROM_DATABASE=V.I COMPUTER CORP. + +OUI:00A0F8* + ID_OUI_FROM_DATABASE=SYMBOL TECHNOLOGIES, INC. + +OUI:00A0F9* + ID_OUI_FROM_DATABASE=BINTEC COMMUNICATIONS GMBH + +OUI:00A0FA* + ID_OUI_FROM_DATABASE=Marconi Communication GmbH + +OUI:00A0FB* + ID_OUI_FROM_DATABASE=TORAY ENGINEERING CO., LTD. + +OUI:00A0FC* + ID_OUI_FROM_DATABASE=IMAGE SCIENCES, INC. + +OUI:00A0FD* + ID_OUI_FROM_DATABASE=SCITEX DIGITAL PRINTING, INC. + +OUI:00A0FE* + ID_OUI_FROM_DATABASE=BOSTON TECHNOLOGY, INC. + +OUI:00A0FF* + ID_OUI_FROM_DATABASE=TELLABS OPERATIONS, INC. + +OUI:00A1DE* + ID_OUI_FROM_DATABASE=ShenZhen ShiHua Technology CO.,LTD + +OUI:00A2DA* + ID_OUI_FROM_DATABASE=INAT GmbH + +OUI:00AA00* + ID_OUI_FROM_DATABASE=INTEL CORPORATION + +OUI:00AA01* + ID_OUI_FROM_DATABASE=INTEL CORPORATION + +OUI:00AA02* + ID_OUI_FROM_DATABASE=INTEL CORPORATION + +OUI:00AA3C* + ID_OUI_FROM_DATABASE=OLIVETTI TELECOM SPA (OLTECO) + +OUI:00AA70* + ID_OUI_FROM_DATABASE=LG Electronics + +OUI:00B009* + ID_OUI_FROM_DATABASE=Grass Valley Group + +OUI:00B017* + ID_OUI_FROM_DATABASE=InfoGear Technology Corp. + +OUI:00B019* + ID_OUI_FROM_DATABASE=UTC CCS + +OUI:00B01C* + ID_OUI_FROM_DATABASE=Westport Technologies + +OUI:00B01E* + ID_OUI_FROM_DATABASE=Rantic Labs, Inc. + +OUI:00B02A* + ID_OUI_FROM_DATABASE=ORSYS GmbH + +OUI:00B02D* + ID_OUI_FROM_DATABASE=ViaGate Technologies, Inc. + +OUI:00B033* + ID_OUI_FROM_DATABASE=OAO "Izhevskiy radiozavod" + +OUI:00B03B* + ID_OUI_FROM_DATABASE=HiQ Networks + +OUI:00B048* + ID_OUI_FROM_DATABASE=Marconi Communications Inc. + +OUI:00B04A* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00B052* + ID_OUI_FROM_DATABASE=Atheros Communications + +OUI:00B064* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00B069* + ID_OUI_FROM_DATABASE=Honewell Oy + +OUI:00B06D* + ID_OUI_FROM_DATABASE=Jones Futurex Inc. + +OUI:00B080* + ID_OUI_FROM_DATABASE=Mannesmann Ipulsys B.V. + +OUI:00B086* + ID_OUI_FROM_DATABASE=LocSoft Limited + +OUI:00B08E* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00B091* + ID_OUI_FROM_DATABASE=Transmeta Corp. + +OUI:00B094* + ID_OUI_FROM_DATABASE=Alaris, Inc. + +OUI:00B09A* + ID_OUI_FROM_DATABASE=Morrow Technologies Corp. + +OUI:00B09D* + ID_OUI_FROM_DATABASE=Point Grey Research Inc. + +OUI:00B0AC* + ID_OUI_FROM_DATABASE=SIAE-Microelettronica S.p.A. + +OUI:00B0AE* + ID_OUI_FROM_DATABASE=Symmetricom + +OUI:00B0B3* + ID_OUI_FROM_DATABASE=Xstreamis PLC + +OUI:00B0C2* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00B0C7* + ID_OUI_FROM_DATABASE=Tellabs Operations, Inc. + +OUI:00B0CE* + ID_OUI_FROM_DATABASE=TECHNOLOGY RESCUE + +OUI:00B0D0* + ID_OUI_FROM_DATABASE=Dell Computer Corp. + +OUI:00B0DB* + ID_OUI_FROM_DATABASE=Nextcell, Inc. + +OUI:00B0DF* + ID_OUI_FROM_DATABASE=Starboard Storage Systems + +OUI:00B0E7* + ID_OUI_FROM_DATABASE=British Federal Ltd. + +OUI:00B0EC* + ID_OUI_FROM_DATABASE=EACEM + +OUI:00B0EE* + ID_OUI_FROM_DATABASE=Ajile Systems, Inc. + +OUI:00B0F0* + ID_OUI_FROM_DATABASE=CALY NETWORKS + +OUI:00B0F5* + ID_OUI_FROM_DATABASE=NetWorth Technologies, Inc. + +OUI:00B338* + ID_OUI_FROM_DATABASE=Kontron Design Manufacturing Services (M) Sdn. Bhd + +OUI:00B342* + ID_OUI_FROM_DATABASE=MacroSAN Technologies Co., Ltd. + +OUI:00B56D* + ID_OUI_FROM_DATABASE=David Electronics Co., LTD. + +OUI:00B5D6* + ID_OUI_FROM_DATABASE=Omnibit Inc. + +OUI:00B9F6* + ID_OUI_FROM_DATABASE=Shenzhen Super Rich Electronics Co.,Ltd + +OUI:00BAC0* + ID_OUI_FROM_DATABASE=Biometric Access Company + +OUI:00BB01* + ID_OUI_FROM_DATABASE=OCTOTHORPE CORP. + +OUI:00BB8E* + ID_OUI_FROM_DATABASE=HME Co., Ltd. + +OUI:00BBF0* + ID_OUI_FROM_DATABASE=UNGERMANN-BASS INC. + +OUI:00BD27* + ID_OUI_FROM_DATABASE=Exar Corp. + +OUI:00BD3A* + ID_OUI_FROM_DATABASE=Nokia Corporation + +OUI:00BF15* + ID_OUI_FROM_DATABASE=Genetec Inc. + +OUI:00C000* + ID_OUI_FROM_DATABASE=LANOPTICS, LTD. + +OUI:00C001* + ID_OUI_FROM_DATABASE=DIATEK PATIENT MANAGMENT + +OUI:00C002* + ID_OUI_FROM_DATABASE=SERCOMM CORPORATION + +OUI:00C003* + ID_OUI_FROM_DATABASE=GLOBALNET COMMUNICATIONS + +OUI:00C004* + ID_OUI_FROM_DATABASE=JAPAN BUSINESS COMPUTER CO.LTD + +OUI:00C005* + ID_OUI_FROM_DATABASE=LIVINGSTON ENTERPRISES, INC. + +OUI:00C006* + ID_OUI_FROM_DATABASE=NIPPON AVIONICS CO., LTD. + +OUI:00C007* + ID_OUI_FROM_DATABASE=PINNACLE DATA SYSTEMS, INC. + +OUI:00C008* + ID_OUI_FROM_DATABASE=SECO SRL + +OUI:00C009* + ID_OUI_FROM_DATABASE=KT TECHNOLOGY (S) PTE LTD + +OUI:00C00A* + ID_OUI_FROM_DATABASE=MICRO CRAFT + +OUI:00C00B* + ID_OUI_FROM_DATABASE=NORCONTROL A.S. + +OUI:00C00C* + ID_OUI_FROM_DATABASE=RELIA TECHNOLGIES + +OUI:00C00D* + ID_OUI_FROM_DATABASE=ADVANCED LOGIC RESEARCH, INC. + +OUI:00C00E* + ID_OUI_FROM_DATABASE=PSITECH, INC. + +OUI:00C00F* + ID_OUI_FROM_DATABASE=QUANTUM SOFTWARE SYSTEMS LTD. + +OUI:00C010* + ID_OUI_FROM_DATABASE=HIRAKAWA HEWTECH CORP. + +OUI:00C011* + ID_OUI_FROM_DATABASE=INTERACTIVE COMPUTING DEVICES + +OUI:00C012* + ID_OUI_FROM_DATABASE=NETSPAN CORPORATION + +OUI:00C013* + ID_OUI_FROM_DATABASE=NETRIX + +OUI:00C014* + ID_OUI_FROM_DATABASE=TELEMATICS CALABASAS INT'L,INC + +OUI:00C015* + ID_OUI_FROM_DATABASE=NEW MEDIA CORPORATION + +OUI:00C016* + ID_OUI_FROM_DATABASE=ELECTRONIC THEATRE CONTROLS + +OUI:00C017* + ID_OUI_FROM_DATABASE=Fluke Corporation + +OUI:00C018* + ID_OUI_FROM_DATABASE=LANART CORPORATION + +OUI:00C019* + ID_OUI_FROM_DATABASE=LEAP TECHNOLOGY, INC. + +OUI:00C01A* + ID_OUI_FROM_DATABASE=COROMETRICS MEDICAL SYSTEMS + +OUI:00C01B* + ID_OUI_FROM_DATABASE=SOCKET COMMUNICATIONS, INC. + +OUI:00C01C* + ID_OUI_FROM_DATABASE=INTERLINK COMMUNICATIONS LTD. + +OUI:00C01D* + ID_OUI_FROM_DATABASE=GRAND JUNCTION NETWORKS, INC. + +OUI:00C01E* + ID_OUI_FROM_DATABASE=LA FRANCAISE DES JEUX + +OUI:00C01F* + ID_OUI_FROM_DATABASE=S.E.R.C.E.L. + +OUI:00C020* + ID_OUI_FROM_DATABASE=ARCO ELECTRONIC, CONTROL LTD. + +OUI:00C021* + ID_OUI_FROM_DATABASE=NETEXPRESS + +OUI:00C022* + ID_OUI_FROM_DATABASE=LASERMASTER TECHNOLOGIES, INC. + +OUI:00C023* + ID_OUI_FROM_DATABASE=TUTANKHAMON ELECTRONICS + +OUI:00C024* + ID_OUI_FROM_DATABASE=EDEN SISTEMAS DE COMPUTACAO SA + +OUI:00C025* + ID_OUI_FROM_DATABASE=DATAPRODUCTS CORPORATION + +OUI:00C026* + ID_OUI_FROM_DATABASE=LANS TECHNOLOGY CO., LTD. + +OUI:00C027* + ID_OUI_FROM_DATABASE=CIPHER SYSTEMS, INC. + +OUI:00C028* + ID_OUI_FROM_DATABASE=JASCO CORPORATION + +OUI:00C029* + ID_OUI_FROM_DATABASE=Nexans Deutschland GmbH - ANS + +OUI:00C02A* + ID_OUI_FROM_DATABASE=OHKURA ELECTRIC CO., LTD. + +OUI:00C02B* + ID_OUI_FROM_DATABASE=GERLOFF GESELLSCHAFT FUR + +OUI:00C02C* + ID_OUI_FROM_DATABASE=CENTRUM COMMUNICATIONS, INC. + +OUI:00C02D* + ID_OUI_FROM_DATABASE=FUJI PHOTO FILM CO., LTD. + +OUI:00C02E* + ID_OUI_FROM_DATABASE=NETWIZ + +OUI:00C02F* + ID_OUI_FROM_DATABASE=OKUMA CORPORATION + +OUI:00C030* + ID_OUI_FROM_DATABASE=INTEGRATED ENGINEERING B. V. + +OUI:00C031* + ID_OUI_FROM_DATABASE=DESIGN RESEARCH SYSTEMS, INC. + +OUI:00C032* + ID_OUI_FROM_DATABASE=I-CUBED LIMITED + +OUI:00C033* + ID_OUI_FROM_DATABASE=TELEBIT COMMUNICATIONS APS + +OUI:00C034* + ID_OUI_FROM_DATABASE=TRANSACTION NETWORK + +OUI:00C035* + ID_OUI_FROM_DATABASE=QUINTAR COMPANY + +OUI:00C036* + ID_OUI_FROM_DATABASE=RAYTECH ELECTRONIC CORP. + +OUI:00C037* + ID_OUI_FROM_DATABASE=DYNATEM + +OUI:00C038* + ID_OUI_FROM_DATABASE=RASTER IMAGE PROCESSING SYSTEM + +OUI:00C039* + ID_OUI_FROM_DATABASE=Teridian Semiconductor Corporation + +OUI:00C03A* + ID_OUI_FROM_DATABASE=MEN-MIKRO ELEKTRONIK GMBH + +OUI:00C03B* + ID_OUI_FROM_DATABASE=MULTIACCESS COMPUTING CORP. + +OUI:00C03C* + ID_OUI_FROM_DATABASE=TOWER TECH S.R.L. + +OUI:00C03D* + ID_OUI_FROM_DATABASE=WIESEMANN & THEIS GMBH + +OUI:00C03E* + ID_OUI_FROM_DATABASE=FA. GEBR. HELLER GMBH + +OUI:00C03F* + ID_OUI_FROM_DATABASE=STORES AUTOMATED SYSTEMS, INC. + +OUI:00C040* + ID_OUI_FROM_DATABASE=ECCI + +OUI:00C041* + ID_OUI_FROM_DATABASE=DIGITAL TRANSMISSION SYSTEMS + +OUI:00C042* + ID_OUI_FROM_DATABASE=DATALUX CORP. + +OUI:00C043* + ID_OUI_FROM_DATABASE=STRATACOM + +OUI:00C044* + ID_OUI_FROM_DATABASE=EMCOM CORPORATION + +OUI:00C045* + ID_OUI_FROM_DATABASE=ISOLATION SYSTEMS, LTD. + +OUI:00C046* + ID_OUI_FROM_DATABASE=Blue Chip Technology Ltd + +OUI:00C047* + ID_OUI_FROM_DATABASE=UNIMICRO SYSTEMS, INC. + +OUI:00C048* + ID_OUI_FROM_DATABASE=BAY TECHNICAL ASSOCIATES + +OUI:00C049* + ID_OUI_FROM_DATABASE=U.S. ROBOTICS, INC. + +OUI:00C04A* + ID_OUI_FROM_DATABASE=GROUP 2000 AG + +OUI:00C04B* + ID_OUI_FROM_DATABASE=CREATIVE MICROSYSTEMS + +OUI:00C04C* + ID_OUI_FROM_DATABASE=DEPARTMENT OF FOREIGN AFFAIRS + +OUI:00C04D* + ID_OUI_FROM_DATABASE=MITEC, INC. + +OUI:00C04E* + ID_OUI_FROM_DATABASE=COMTROL CORPORATION + +OUI:00C04F* + ID_OUI_FROM_DATABASE=DELL COMPUTER CORPORATION + +OUI:00C050* + ID_OUI_FROM_DATABASE=TOYO DENKI SEIZO K.K. + +OUI:00C051* + ID_OUI_FROM_DATABASE=ADVANCED INTEGRATION RESEARCH + +OUI:00C052* + ID_OUI_FROM_DATABASE=BURR-BROWN + +OUI:00C053* + ID_OUI_FROM_DATABASE=Aspect Software Inc. + +OUI:00C054* + ID_OUI_FROM_DATABASE=NETWORK PERIPHERALS, LTD. + +OUI:00C055* + ID_OUI_FROM_DATABASE=MODULAR COMPUTING TECHNOLOGIES + +OUI:00C056* + ID_OUI_FROM_DATABASE=SOMELEC + +OUI:00C057* + ID_OUI_FROM_DATABASE=MYCO ELECTRONICS + +OUI:00C058* + ID_OUI_FROM_DATABASE=DATAEXPERT CORP. + +OUI:00C059* + ID_OUI_FROM_DATABASE=DENSO CORPORATION + +OUI:00C05A* + ID_OUI_FROM_DATABASE=SEMAPHORE COMMUNICATIONS CORP. + +OUI:00C05B* + ID_OUI_FROM_DATABASE=NETWORKS NORTHWEST, INC. + +OUI:00C05C* + ID_OUI_FROM_DATABASE=ELONEX PLC + +OUI:00C05D* + ID_OUI_FROM_DATABASE=L&N TECHNOLOGIES + +OUI:00C05E* + ID_OUI_FROM_DATABASE=VARI-LITE, INC. + +OUI:00C05F* + ID_OUI_FROM_DATABASE=FINE-PAL COMPANY LIMITED + +OUI:00C060* + ID_OUI_FROM_DATABASE=ID SCANDINAVIA AS + +OUI:00C061* + ID_OUI_FROM_DATABASE=SOLECTEK CORPORATION + +OUI:00C062* + ID_OUI_FROM_DATABASE=IMPULSE TECHNOLOGY + +OUI:00C063* + ID_OUI_FROM_DATABASE=MORNING STAR TECHNOLOGIES, INC + +OUI:00C064* + ID_OUI_FROM_DATABASE=GENERAL DATACOMM IND. INC. + +OUI:00C065* + ID_OUI_FROM_DATABASE=SCOPE COMMUNICATIONS, INC. + +OUI:00C066* + ID_OUI_FROM_DATABASE=DOCUPOINT, INC. + +OUI:00C067* + ID_OUI_FROM_DATABASE=UNITED BARCODE INDUSTRIES + +OUI:00C068* + ID_OUI_FROM_DATABASE=HME Clear-Com LTD. + +OUI:00C069* + ID_OUI_FROM_DATABASE=Axxcelera Broadband Wireless + +OUI:00C06A* + ID_OUI_FROM_DATABASE=ZAHNER-ELEKTRIK GMBH & CO. KG + +OUI:00C06B* + ID_OUI_FROM_DATABASE=OSI PLUS CORPORATION + +OUI:00C06C* + ID_OUI_FROM_DATABASE=SVEC COMPUTER CORP. + +OUI:00C06D* + ID_OUI_FROM_DATABASE=BOCA RESEARCH, INC. + +OUI:00C06E* + ID_OUI_FROM_DATABASE=HAFT TECHNOLOGY, INC. + +OUI:00C06F* + ID_OUI_FROM_DATABASE=KOMATSU LTD. + +OUI:00C070* + ID_OUI_FROM_DATABASE=SECTRA SECURE-TRANSMISSION AB + +OUI:00C071* + ID_OUI_FROM_DATABASE=AREANEX COMMUNICATIONS, INC. + +OUI:00C072* + ID_OUI_FROM_DATABASE=KNX LTD. + +OUI:00C073* + ID_OUI_FROM_DATABASE=XEDIA CORPORATION + +OUI:00C074* + ID_OUI_FROM_DATABASE=TOYODA AUTOMATIC LOOM + +OUI:00C075* + ID_OUI_FROM_DATABASE=XANTE CORPORATION + +OUI:00C076* + ID_OUI_FROM_DATABASE=I-DATA INTERNATIONAL A-S + +OUI:00C077* + ID_OUI_FROM_DATABASE=DAEWOO TELECOM LTD. + +OUI:00C078* + ID_OUI_FROM_DATABASE=COMPUTER SYSTEMS ENGINEERING + +OUI:00C079* + ID_OUI_FROM_DATABASE=FONSYS CO.,LTD. + +OUI:00C07A* + ID_OUI_FROM_DATABASE=PRIVA B.V. + +OUI:00C07B* + ID_OUI_FROM_DATABASE=ASCEND COMMUNICATIONS, INC. + +OUI:00C07C* + ID_OUI_FROM_DATABASE=HIGHTECH INFORMATION + +OUI:00C07D* + ID_OUI_FROM_DATABASE=RISC DEVELOPMENTS LTD. + +OUI:00C07E* + ID_OUI_FROM_DATABASE=KUBOTA CORPORATION ELECTRONIC + +OUI:00C07F* + ID_OUI_FROM_DATABASE=NUPON COMPUTING CORP. + +OUI:00C080* + ID_OUI_FROM_DATABASE=NETSTAR, INC. + +OUI:00C081* + ID_OUI_FROM_DATABASE=METRODATA LTD. + +OUI:00C082* + ID_OUI_FROM_DATABASE=MOORE PRODUCTS CO. + +OUI:00C083* + ID_OUI_FROM_DATABASE=TRACE MOUNTAIN PRODUCTS, INC. + +OUI:00C084* + ID_OUI_FROM_DATABASE=DATA LINK CORP. LTD. + +OUI:00C085* + ID_OUI_FROM_DATABASE=ELECTRONICS FOR IMAGING, INC. + +OUI:00C086* + ID_OUI_FROM_DATABASE=THE LYNK CORPORATION + +OUI:00C087* + ID_OUI_FROM_DATABASE=UUNET TECHNOLOGIES, INC. + +OUI:00C088* + ID_OUI_FROM_DATABASE=EKF ELEKTRONIK GMBH + +OUI:00C089* + ID_OUI_FROM_DATABASE=TELINDUS DISTRIBUTION + +OUI:00C08A* + ID_OUI_FROM_DATABASE=Lauterbach GmbH + +OUI:00C08B* + ID_OUI_FROM_DATABASE=RISQ MODULAR SYSTEMS, INC. + +OUI:00C08C* + ID_OUI_FROM_DATABASE=PERFORMANCE TECHNOLOGIES, INC. + +OUI:00C08D* + ID_OUI_FROM_DATABASE=TRONIX PRODUCT DEVELOPMENT + +OUI:00C08E* + ID_OUI_FROM_DATABASE=NETWORK INFORMATION TECHNOLOGY + +OUI:00C08F* + ID_OUI_FROM_DATABASE=Panasonic Electric Works Co., Ltd. + +OUI:00C090* + ID_OUI_FROM_DATABASE=PRAIM S.R.L. + +OUI:00C091* + ID_OUI_FROM_DATABASE=JABIL CIRCUIT, INC. + +OUI:00C092* + ID_OUI_FROM_DATABASE=MENNEN MEDICAL INC. + +OUI:00C093* + ID_OUI_FROM_DATABASE=ALTA RESEARCH CORP. + +OUI:00C094* + ID_OUI_FROM_DATABASE=VMX INC. + +OUI:00C095* + ID_OUI_FROM_DATABASE=ZNYX + +OUI:00C096* + ID_OUI_FROM_DATABASE=TAMURA CORPORATION + +OUI:00C097* + ID_OUI_FROM_DATABASE=ARCHIPEL SA + +OUI:00C098* + ID_OUI_FROM_DATABASE=CHUNTEX ELECTRONIC CO., LTD. + +OUI:00C099* + ID_OUI_FROM_DATABASE=YOSHIKI INDUSTRIAL CO.,LTD. + +OUI:00C09A* + ID_OUI_FROM_DATABASE=PHOTONICS CORPORATION + +OUI:00C09B* + ID_OUI_FROM_DATABASE=RELIANCE COMM/TEC, R-TEC + +OUI:00C09C* + ID_OUI_FROM_DATABASE=HIOKI E.E. CORPORATION + +OUI:00C09D* + ID_OUI_FROM_DATABASE=DISTRIBUTED SYSTEMS INT'L, INC + +OUI:00C09E* + ID_OUI_FROM_DATABASE=CACHE COMPUTERS, INC. + +OUI:00C09F* + ID_OUI_FROM_DATABASE=QUANTA COMPUTER, INC. + +OUI:00C0A0* + ID_OUI_FROM_DATABASE=ADVANCE MICRO RESEARCH, INC. + +OUI:00C0A1* + ID_OUI_FROM_DATABASE=TOKYO DENSHI SEKEI CO. + +OUI:00C0A2* + ID_OUI_FROM_DATABASE=INTERMEDIUM A/S + +OUI:00C0A3* + ID_OUI_FROM_DATABASE=DUAL ENTERPRISES CORPORATION + +OUI:00C0A4* + ID_OUI_FROM_DATABASE=UNIGRAF OY + +OUI:00C0A5* + ID_OUI_FROM_DATABASE=DICKENS DATA SYSTEMS + +OUI:00C0A6* + ID_OUI_FROM_DATABASE=EXICOM AUSTRALIA PTY. LTD + +OUI:00C0A7* + ID_OUI_FROM_DATABASE=SEEL LTD. + +OUI:00C0A8* + ID_OUI_FROM_DATABASE=GVC CORPORATION + +OUI:00C0A9* + ID_OUI_FROM_DATABASE=BARRON MCCANN LTD. + +OUI:00C0AA* + ID_OUI_FROM_DATABASE=SILICON VALLEY COMPUTER + +OUI:00C0AB* + ID_OUI_FROM_DATABASE=Telco Systems, Inc. + +OUI:00C0AC* + ID_OUI_FROM_DATABASE=GAMBIT COMPUTER COMMUNICATIONS + +OUI:00C0AD* + ID_OUI_FROM_DATABASE=MARBEN COMMUNICATION SYSTEMS + +OUI:00C0AE* + ID_OUI_FROM_DATABASE=TOWERCOM CO. INC. DBA PC HOUSE + +OUI:00C0AF* + ID_OUI_FROM_DATABASE=TEKLOGIX INC. + +OUI:00C0B0* + ID_OUI_FROM_DATABASE=GCC TECHNOLOGIES,INC. + +OUI:00C0B1* + ID_OUI_FROM_DATABASE=GENIUS NET CO. + +OUI:00C0B2* + ID_OUI_FROM_DATABASE=NORAND CORPORATION + +OUI:00C0B3* + ID_OUI_FROM_DATABASE=COMSTAT DATACOMM CORPORATION + +OUI:00C0B4* + ID_OUI_FROM_DATABASE=MYSON TECHNOLOGY, INC. + +OUI:00C0B5* + ID_OUI_FROM_DATABASE=CORPORATE NETWORK SYSTEMS,INC. + +OUI:00C0B6* + ID_OUI_FROM_DATABASE=Overland Storage, Inc. + +OUI:00C0B7* + ID_OUI_FROM_DATABASE=AMERICAN POWER CONVERSION CORP + +OUI:00C0B8* + ID_OUI_FROM_DATABASE=FRASER'S HILL LTD. + +OUI:00C0B9* + ID_OUI_FROM_DATABASE=FUNK SOFTWARE, INC. + +OUI:00C0BA* + ID_OUI_FROM_DATABASE=NETVANTAGE + +OUI:00C0BB* + ID_OUI_FROM_DATABASE=FORVAL CREATIVE, INC. + +OUI:00C0BC* + ID_OUI_FROM_DATABASE=TELECOM AUSTRALIA/CSSC + +OUI:00C0BD* + ID_OUI_FROM_DATABASE=INEX TECHNOLOGIES, INC. + +OUI:00C0BE* + ID_OUI_FROM_DATABASE=ALCATEL - SEL + +OUI:00C0BF* + ID_OUI_FROM_DATABASE=TECHNOLOGY CONCEPTS, LTD. + +OUI:00C0C0* + ID_OUI_FROM_DATABASE=SHORE MICROSYSTEMS, INC. + +OUI:00C0C1* + ID_OUI_FROM_DATABASE=QUAD/GRAPHICS, INC. + +OUI:00C0C2* + ID_OUI_FROM_DATABASE=INFINITE NETWORKS LTD. + +OUI:00C0C3* + ID_OUI_FROM_DATABASE=ACUSON COMPUTED SONOGRAPHY + +OUI:00C0C4* + ID_OUI_FROM_DATABASE=COMPUTER OPERATIONAL + +OUI:00C0C5* + ID_OUI_FROM_DATABASE=SID INFORMATICA + +OUI:00C0C6* + ID_OUI_FROM_DATABASE=PERSONAL MEDIA CORP. + +OUI:00C0C7* + ID_OUI_FROM_DATABASE=SPARKTRUM MICROSYSTEMS, INC. + +OUI:00C0C8* + ID_OUI_FROM_DATABASE=MICRO BYTE PTY. LTD. + +OUI:00C0C9* + ID_OUI_FROM_DATABASE=ELSAG BAILEY PROCESS + +OUI:00C0CA* + ID_OUI_FROM_DATABASE=ALFA, INC. + +OUI:00C0CB* + ID_OUI_FROM_DATABASE=CONTROL TECHNOLOGY CORPORATION + +OUI:00C0CC* + ID_OUI_FROM_DATABASE=TELESCIENCES CO SYSTEMS, INC. + +OUI:00C0CD* + ID_OUI_FROM_DATABASE=COMELTA, S.A. + +OUI:00C0CE* + ID_OUI_FROM_DATABASE=CEI SYSTEMS & ENGINEERING PTE + +OUI:00C0CF* + ID_OUI_FROM_DATABASE=IMATRAN VOIMA OY + +OUI:00C0D0* + ID_OUI_FROM_DATABASE=RATOC SYSTEM INC. + +OUI:00C0D1* + ID_OUI_FROM_DATABASE=COMTREE TECHNOLOGY CORPORATION + +OUI:00C0D2* + ID_OUI_FROM_DATABASE=SYNTELLECT, INC. + +OUI:00C0D3* + ID_OUI_FROM_DATABASE=OLYMPUS IMAGE SYSTEMS, INC. + +OUI:00C0D4* + ID_OUI_FROM_DATABASE=AXON NETWORKS, INC. + +OUI:00C0D5* + ID_OUI_FROM_DATABASE=Werbeagentur Jürgen Siebert + +OUI:00C0D6* + ID_OUI_FROM_DATABASE=J1 SYSTEMS, INC. + +OUI:00C0D7* + ID_OUI_FROM_DATABASE=TAIWAN TRADING CENTER DBA + +OUI:00C0D8* + ID_OUI_FROM_DATABASE=UNIVERSAL DATA SYSTEMS + +OUI:00C0D9* + ID_OUI_FROM_DATABASE=QUINTE NETWORK CONFIDENTIALITY + +OUI:00C0DA* + ID_OUI_FROM_DATABASE=NICE SYSTEMS LTD. + +OUI:00C0DB* + ID_OUI_FROM_DATABASE=IPC CORPORATION (PTE) LTD. + +OUI:00C0DC* + ID_OUI_FROM_DATABASE=EOS TECHNOLOGIES, INC. + +OUI:00C0DD* + ID_OUI_FROM_DATABASE=QLogic Corporation + +OUI:00C0DE* + ID_OUI_FROM_DATABASE=ZCOMM, INC. + +OUI:00C0DF* + ID_OUI_FROM_DATABASE=KYE Systems Corp. + +OUI:00C0E0* + ID_OUI_FROM_DATABASE=DSC COMMUNICATION CORP. + +OUI:00C0E1* + ID_OUI_FROM_DATABASE=SONIC SOLUTIONS + +OUI:00C0E2* + ID_OUI_FROM_DATABASE=CALCOMP, INC. + +OUI:00C0E3* + ID_OUI_FROM_DATABASE=OSITECH COMMUNICATIONS, INC. + +OUI:00C0E4* + ID_OUI_FROM_DATABASE=SIEMENS BUILDING + +OUI:00C0E5* + ID_OUI_FROM_DATABASE=GESPAC, S.A. + +OUI:00C0E6* + ID_OUI_FROM_DATABASE=Verilink Corporation + +OUI:00C0E7* + ID_OUI_FROM_DATABASE=FIBERDATA AB + +OUI:00C0E8* + ID_OUI_FROM_DATABASE=PLEXCOM, INC. + +OUI:00C0E9* + ID_OUI_FROM_DATABASE=OAK SOLUTIONS, LTD. + +OUI:00C0EA* + ID_OUI_FROM_DATABASE=ARRAY TECHNOLOGY LTD. + +OUI:00C0EB* + ID_OUI_FROM_DATABASE=SEH COMPUTERTECHNIK GMBH + +OUI:00C0EC* + ID_OUI_FROM_DATABASE=DAUPHIN TECHNOLOGY + +OUI:00C0ED* + ID_OUI_FROM_DATABASE=US ARMY ELECTRONIC + +OUI:00C0EE* + ID_OUI_FROM_DATABASE=KYOCERA CORPORATION + +OUI:00C0EF* + ID_OUI_FROM_DATABASE=ABIT CORPORATION + +OUI:00C0F0* + ID_OUI_FROM_DATABASE=KINGSTON TECHNOLOGY CORP. + +OUI:00C0F1* + ID_OUI_FROM_DATABASE=SHINKO ELECTRIC CO., LTD. + +OUI:00C0F2* + ID_OUI_FROM_DATABASE=TRANSITION NETWORKS + +OUI:00C0F3* + ID_OUI_FROM_DATABASE=NETWORK COMMUNICATIONS CORP. + +OUI:00C0F4* + ID_OUI_FROM_DATABASE=INTERLINK SYSTEM CO., LTD. + +OUI:00C0F5* + ID_OUI_FROM_DATABASE=METACOMP, INC. + +OUI:00C0F6* + ID_OUI_FROM_DATABASE=CELAN TECHNOLOGY INC. + +OUI:00C0F7* + ID_OUI_FROM_DATABASE=ENGAGE COMMUNICATION, INC. + +OUI:00C0F8* + ID_OUI_FROM_DATABASE=ABOUT COMPUTING INC. + +OUI:00C0F9* + ID_OUI_FROM_DATABASE=Emerson Network Power + +OUI:00C0FA* + ID_OUI_FROM_DATABASE=CANARY COMMUNICATIONS, INC. + +OUI:00C0FB* + ID_OUI_FROM_DATABASE=ADVANCED TECHNOLOGY LABS + +OUI:00C0FC* + ID_OUI_FROM_DATABASE=ELASTIC REALITY, INC. + +OUI:00C0FD* + ID_OUI_FROM_DATABASE=PROSUM + +OUI:00C0FE* + ID_OUI_FROM_DATABASE=APTEC COMPUTER SYSTEMS, INC. + +OUI:00C0FF* + ID_OUI_FROM_DATABASE=DOT HILL SYSTEMS CORPORATION + +OUI:00C14F* + ID_OUI_FROM_DATABASE=DDL Co,.ltd. + +OUI:00C2C6* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:00C610* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:00CBBD* + ID_OUI_FROM_DATABASE=Cambridge Broadband Networks Ltd. + +OUI:00CD90* + ID_OUI_FROM_DATABASE=MAS Elektronik AG + +OUI:00CF1C* + ID_OUI_FROM_DATABASE=COMMUNICATION MACHINERY CORP. + +OUI:00D000* + ID_OUI_FROM_DATABASE=FERRAN SCIENTIFIC, INC. + +OUI:00D001* + ID_OUI_FROM_DATABASE=VST TECHNOLOGIES, INC. + +OUI:00D002* + ID_OUI_FROM_DATABASE=DITECH CORPORATION + +OUI:00D003* + ID_OUI_FROM_DATABASE=COMDA ENTERPRISES CORP. + +OUI:00D004* + ID_OUI_FROM_DATABASE=PENTACOM LTD. + +OUI:00D005* + ID_OUI_FROM_DATABASE=ZHS ZEITMANAGEMENTSYSTEME + +OUI:00D006* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00D007* + ID_OUI_FROM_DATABASE=MIC ASSOCIATES, INC. + +OUI:00D008* + ID_OUI_FROM_DATABASE=MACTELL CORPORATION + +OUI:00D009* + ID_OUI_FROM_DATABASE=HSING TECH. ENTERPRISE CO. LTD + +OUI:00D00A* + ID_OUI_FROM_DATABASE=LANACCESS TELECOM S.A. + +OUI:00D00B* + ID_OUI_FROM_DATABASE=RHK TECHNOLOGY, INC. + +OUI:00D00C* + ID_OUI_FROM_DATABASE=SNIJDER MICRO SYSTEMS + +OUI:00D00D* + ID_OUI_FROM_DATABASE=MICROMERITICS INSTRUMENT + +OUI:00D00E* + ID_OUI_FROM_DATABASE=PLURIS, INC. + +OUI:00D00F* + ID_OUI_FROM_DATABASE=SPEECH DESIGN GMBH + +OUI:00D010* + ID_OUI_FROM_DATABASE=CONVERGENT NETWORKS, INC. + +OUI:00D011* + ID_OUI_FROM_DATABASE=PRISM VIDEO, INC. + +OUI:00D012* + ID_OUI_FROM_DATABASE=GATEWORKS CORP. + +OUI:00D013* + ID_OUI_FROM_DATABASE=PRIMEX AEROSPACE COMPANY + +OUI:00D014* + ID_OUI_FROM_DATABASE=ROOT, INC. + +OUI:00D015* + ID_OUI_FROM_DATABASE=UNIVEX MICROTECHNOLOGY CORP. + +OUI:00D016* + ID_OUI_FROM_DATABASE=SCM MICROSYSTEMS, INC. + +OUI:00D017* + ID_OUI_FROM_DATABASE=SYNTECH INFORMATION CO., LTD. + +OUI:00D018* + ID_OUI_FROM_DATABASE=QWES. COM, INC. + +OUI:00D019* + ID_OUI_FROM_DATABASE=DAINIPPON SCREEN CORPORATE + +OUI:00D01A* + ID_OUI_FROM_DATABASE=URMET TLC S.P.A. + +OUI:00D01B* + ID_OUI_FROM_DATABASE=MIMAKI ENGINEERING CO., LTD. + +OUI:00D01C* + ID_OUI_FROM_DATABASE=SBS TECHNOLOGIES, + +OUI:00D01D* + ID_OUI_FROM_DATABASE=FURUNO ELECTRIC CO., LTD. + +OUI:00D01E* + ID_OUI_FROM_DATABASE=PINGTEL CORP. + +OUI:00D01F* + ID_OUI_FROM_DATABASE=CTAM PTY. LTD. + +OUI:00D020* + ID_OUI_FROM_DATABASE=AIM SYSTEM, INC. + +OUI:00D021* + ID_OUI_FROM_DATABASE=REGENT ELECTRONICS CORP. + +OUI:00D022* + ID_OUI_FROM_DATABASE=INCREDIBLE TECHNOLOGIES, INC. + +OUI:00D023* + ID_OUI_FROM_DATABASE=INFORTREND TECHNOLOGY, INC. + +OUI:00D024* + ID_OUI_FROM_DATABASE=Cognex Corporation + +OUI:00D025* + ID_OUI_FROM_DATABASE=XROSSTECH, INC. + +OUI:00D026* + ID_OUI_FROM_DATABASE=HIRSCHMANN AUSTRIA GMBH + +OUI:00D027* + ID_OUI_FROM_DATABASE=APPLIED AUTOMATION, INC. + +OUI:00D028* + ID_OUI_FROM_DATABASE=Harmonic, Inc + +OUI:00D029* + ID_OUI_FROM_DATABASE=WAKEFERN FOOD CORPORATION + +OUI:00D02A* + ID_OUI_FROM_DATABASE=Voxent Systems Ltd. + +OUI:00D02B* + ID_OUI_FROM_DATABASE=JETCELL, INC. + +OUI:00D02C* + ID_OUI_FROM_DATABASE=CAMPBELL SCIENTIFIC, INC. + +OUI:00D02D* + ID_OUI_FROM_DATABASE=ADEMCO + +OUI:00D02E* + ID_OUI_FROM_DATABASE=COMMUNICATION AUTOMATION CORP. + +OUI:00D02F* + ID_OUI_FROM_DATABASE=VLSI TECHNOLOGY INC. + +OUI:00D030* + ID_OUI_FROM_DATABASE=Safetran Systems Corp + +OUI:00D031* + ID_OUI_FROM_DATABASE=INDUSTRIAL LOGIC CORPORATION + +OUI:00D032* + ID_OUI_FROM_DATABASE=YANO ELECTRIC CO., LTD. + +OUI:00D033* + ID_OUI_FROM_DATABASE=DALIAN DAXIAN NETWORK + +OUI:00D034* + ID_OUI_FROM_DATABASE=ORMEC SYSTEMS CORP. + +OUI:00D035* + ID_OUI_FROM_DATABASE=BEHAVIOR TECH. COMPUTER CORP. + +OUI:00D036* + ID_OUI_FROM_DATABASE=TECHNOLOGY ATLANTA CORP. + +OUI:00D037* + ID_OUI_FROM_DATABASE=Pace France + +OUI:00D038* + ID_OUI_FROM_DATABASE=FIVEMERE, LTD. + +OUI:00D039* + ID_OUI_FROM_DATABASE=UTILICOM, INC. + +OUI:00D03A* + ID_OUI_FROM_DATABASE=ZONEWORX, INC. + +OUI:00D03B* + ID_OUI_FROM_DATABASE=VISION PRODUCTS PTY. LTD. + +OUI:00D03C* + ID_OUI_FROM_DATABASE=Vieo, Inc. + +OUI:00D03D* + ID_OUI_FROM_DATABASE=GALILEO TECHNOLOGY, LTD. + +OUI:00D03E* + ID_OUI_FROM_DATABASE=ROCKETCHIPS, INC. + +OUI:00D03F* + ID_OUI_FROM_DATABASE=AMERICAN COMMUNICATION + +OUI:00D040* + ID_OUI_FROM_DATABASE=SYSMATE CO., LTD. + +OUI:00D041* + ID_OUI_FROM_DATABASE=AMIGO TECHNOLOGY CO., LTD. + +OUI:00D042* + ID_OUI_FROM_DATABASE=MAHLO GMBH & CO. UG + +OUI:00D043* + ID_OUI_FROM_DATABASE=ZONAL RETAIL DATA SYSTEMS + +OUI:00D044* + ID_OUI_FROM_DATABASE=ALIDIAN NETWORKS, INC. + +OUI:00D045* + ID_OUI_FROM_DATABASE=KVASER AB + +OUI:00D046* + ID_OUI_FROM_DATABASE=DOLBY LABORATORIES, INC. + +OUI:00D047* + ID_OUI_FROM_DATABASE=XN TECHNOLOGIES + +OUI:00D048* + ID_OUI_FROM_DATABASE=ECTON, INC. + +OUI:00D049* + ID_OUI_FROM_DATABASE=IMPRESSTEK CO., LTD. + +OUI:00D04A* + ID_OUI_FROM_DATABASE=PRESENCE TECHNOLOGY GMBH + +OUI:00D04B* + ID_OUI_FROM_DATABASE=LA CIE GROUP S.A. + +OUI:00D04C* + ID_OUI_FROM_DATABASE=EUROTEL TELECOM LTD. + +OUI:00D04D* + ID_OUI_FROM_DATABASE=DIV OF RESEARCH & STATISTICS + +OUI:00D04E* + ID_OUI_FROM_DATABASE=LOGIBAG + +OUI:00D04F* + ID_OUI_FROM_DATABASE=BITRONICS, INC. + +OUI:00D050* + ID_OUI_FROM_DATABASE=ISKRATEL + +OUI:00D051* + ID_OUI_FROM_DATABASE=O2 MICRO, INC. + +OUI:00D052* + ID_OUI_FROM_DATABASE=ASCEND COMMUNICATIONS, INC. + +OUI:00D053* + ID_OUI_FROM_DATABASE=CONNECTED SYSTEMS + +OUI:00D054* + ID_OUI_FROM_DATABASE=SAS INSTITUTE INC. + +OUI:00D055* + ID_OUI_FROM_DATABASE=KATHREIN-WERKE KG + +OUI:00D056* + ID_OUI_FROM_DATABASE=SOMAT CORPORATION + +OUI:00D057* + ID_OUI_FROM_DATABASE=ULTRAK, INC. + +OUI:00D058* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00D059* + ID_OUI_FROM_DATABASE=AMBIT MICROSYSTEMS CORP. + +OUI:00D05A* + ID_OUI_FROM_DATABASE=SYMBIONICS, LTD. + +OUI:00D05B* + ID_OUI_FROM_DATABASE=ACROLOOP MOTION CONTROL + +OUI:00D05C* + ID_OUI_FROM_DATABASE=TECHNOTREND SYSTEMTECHNIK GMBH + +OUI:00D05D* + ID_OUI_FROM_DATABASE=INTELLIWORXX, INC. + +OUI:00D05E* + ID_OUI_FROM_DATABASE=STRATABEAM TECHNOLOGY, INC. + +OUI:00D05F* + ID_OUI_FROM_DATABASE=VALCOM, INC. + +OUI:00D060* + ID_OUI_FROM_DATABASE=Panasonic Europe Ltd. + +OUI:00D061* + ID_OUI_FROM_DATABASE=TREMON ENTERPRISES CO., LTD. + +OUI:00D062* + ID_OUI_FROM_DATABASE=DIGIGRAM + +OUI:00D063* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00D064* + ID_OUI_FROM_DATABASE=MULTITEL + +OUI:00D065* + ID_OUI_FROM_DATABASE=TOKO ELECTRIC + +OUI:00D066* + ID_OUI_FROM_DATABASE=WINTRISS ENGINEERING CORP. + +OUI:00D067* + ID_OUI_FROM_DATABASE=CAMPIO COMMUNICATIONS + +OUI:00D068* + ID_OUI_FROM_DATABASE=IWILL CORPORATION + +OUI:00D069* + ID_OUI_FROM_DATABASE=TECHNOLOGIC SYSTEMS + +OUI:00D06A* + ID_OUI_FROM_DATABASE=LINKUP SYSTEMS CORPORATION + +OUI:00D06B* + ID_OUI_FROM_DATABASE=SR TELECOM INC. + +OUI:00D06C* + ID_OUI_FROM_DATABASE=SHAREWAVE, INC. + +OUI:00D06D* + ID_OUI_FROM_DATABASE=ACRISON, INC. + +OUI:00D06E* + ID_OUI_FROM_DATABASE=TRENDVIEW RECORDERS LTD. + +OUI:00D06F* + ID_OUI_FROM_DATABASE=KMC CONTROLS + +OUI:00D070* + ID_OUI_FROM_DATABASE=LONG WELL ELECTRONICS CORP. + +OUI:00D071* + ID_OUI_FROM_DATABASE=ECHELON CORP. + +OUI:00D072* + ID_OUI_FROM_DATABASE=BROADLOGIC + +OUI:00D073* + ID_OUI_FROM_DATABASE=ACN ADVANCED COMMUNICATIONS + +OUI:00D074* + ID_OUI_FROM_DATABASE=TAQUA SYSTEMS, INC. + +OUI:00D075* + ID_OUI_FROM_DATABASE=ALARIS MEDICAL SYSTEMS, INC. + +OUI:00D076* + ID_OUI_FROM_DATABASE=Bank of America + +OUI:00D077* + ID_OUI_FROM_DATABASE=LUCENT TECHNOLOGIES + +OUI:00D078* + ID_OUI_FROM_DATABASE=Eltex of Sweden AB + +OUI:00D079* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00D07A* + ID_OUI_FROM_DATABASE=AMAQUEST COMPUTER CORP. + +OUI:00D07B* + ID_OUI_FROM_DATABASE=COMCAM INTERNATIONAL INC + +OUI:00D07C* + ID_OUI_FROM_DATABASE=KOYO ELECTRONICS INC. CO.,LTD. + +OUI:00D07D* + ID_OUI_FROM_DATABASE=COSINE COMMUNICATIONS + +OUI:00D07E* + ID_OUI_FROM_DATABASE=KEYCORP LTD. + +OUI:00D07F* + ID_OUI_FROM_DATABASE=STRATEGY & TECHNOLOGY, LIMITED + +OUI:00D080* + ID_OUI_FROM_DATABASE=EXABYTE CORPORATION + +OUI:00D081* + ID_OUI_FROM_DATABASE=RTD Embedded Technologies, Inc. + +OUI:00D082* + ID_OUI_FROM_DATABASE=IOWAVE INC. + +OUI:00D083* + ID_OUI_FROM_DATABASE=INVERTEX, INC. + +OUI:00D084* + ID_OUI_FROM_DATABASE=NEXCOMM SYSTEMS, INC. + +OUI:00D085* + ID_OUI_FROM_DATABASE=OTIS ELEVATOR COMPANY + +OUI:00D086* + ID_OUI_FROM_DATABASE=FOVEON, INC. + +OUI:00D087* + ID_OUI_FROM_DATABASE=MICROFIRST INC. + +OUI:00D088* + ID_OUI_FROM_DATABASE=Motorola, Inc. + +OUI:00D089* + ID_OUI_FROM_DATABASE=DYNACOLOR, INC. + +OUI:00D08A* + ID_OUI_FROM_DATABASE=PHOTRON USA + +OUI:00D08B* + ID_OUI_FROM_DATABASE=ADVA Optical Networking Ltd + +OUI:00D08C* + ID_OUI_FROM_DATABASE=GENOA TECHNOLOGY, INC. + +OUI:00D08D* + ID_OUI_FROM_DATABASE=PHOENIX GROUP, INC. + +OUI:00D08E* + ID_OUI_FROM_DATABASE=NVISION INC. + +OUI:00D08F* + ID_OUI_FROM_DATABASE=ARDENT TECHNOLOGIES, INC. + +OUI:00D090* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00D091* + ID_OUI_FROM_DATABASE=SMARTSAN SYSTEMS, INC. + +OUI:00D092* + ID_OUI_FROM_DATABASE=GLENAYRE WESTERN MULTIPLEX + +OUI:00D093* + ID_OUI_FROM_DATABASE=TQ - COMPONENTS GMBH + +OUI:00D094* + ID_OUI_FROM_DATABASE=TIMELINE VISTA, INC. + +OUI:00D095* + ID_OUI_FROM_DATABASE=Alcatel-Lucent, Enterprise Business Group + +OUI:00D096* + ID_OUI_FROM_DATABASE=3COM EUROPE LTD. + +OUI:00D097* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00D098* + ID_OUI_FROM_DATABASE=Photon Dynamics Canada Inc. + +OUI:00D099* + ID_OUI_FROM_DATABASE=Elcard Wireless Systems Oy + +OUI:00D09A* + ID_OUI_FROM_DATABASE=FILANET CORPORATION + +OUI:00D09B* + ID_OUI_FROM_DATABASE=SPECTEL LTD. + +OUI:00D09C* + ID_OUI_FROM_DATABASE=KAPADIA COMMUNICATIONS + +OUI:00D09D* + ID_OUI_FROM_DATABASE=VERIS INDUSTRIES + +OUI:00D09E* + ID_OUI_FROM_DATABASE=2WIRE, INC. + +OUI:00D09F* + ID_OUI_FROM_DATABASE=NOVTEK TEST SYSTEMS + +OUI:00D0A0* + ID_OUI_FROM_DATABASE=MIPS DENMARK + +OUI:00D0A1* + ID_OUI_FROM_DATABASE=OSKAR VIERLING GMBH + CO. KG + +OUI:00D0A2* + ID_OUI_FROM_DATABASE=INTEGRATED DEVICE + +OUI:00D0A3* + ID_OUI_FROM_DATABASE=VOCAL DATA, INC. + +OUI:00D0A4* + ID_OUI_FROM_DATABASE=ALANTRO COMMUNICATIONS + +OUI:00D0A5* + ID_OUI_FROM_DATABASE=AMERICAN ARIUM + +OUI:00D0A6* + ID_OUI_FROM_DATABASE=LANBIRD TECHNOLOGY CO., LTD. + +OUI:00D0A7* + ID_OUI_FROM_DATABASE=TOKYO SOKKI KENKYUJO CO., LTD. + +OUI:00D0A8* + ID_OUI_FROM_DATABASE=NETWORK ENGINES, INC. + +OUI:00D0A9* + ID_OUI_FROM_DATABASE=SHINANO KENSHI CO., LTD. + +OUI:00D0AA* + ID_OUI_FROM_DATABASE=CHASE COMMUNICATIONS + +OUI:00D0AB* + ID_OUI_FROM_DATABASE=DELTAKABEL TELECOM CV + +OUI:00D0AC* + ID_OUI_FROM_DATABASE=GRAYSON WIRELESS + +OUI:00D0AD* + ID_OUI_FROM_DATABASE=TL INDUSTRIES + +OUI:00D0AE* + ID_OUI_FROM_DATABASE=ORESIS COMMUNICATIONS, INC. + +OUI:00D0AF* + ID_OUI_FROM_DATABASE=CUTLER-HAMMER, INC. + +OUI:00D0B0* + ID_OUI_FROM_DATABASE=BITSWITCH LTD. + +OUI:00D0B1* + ID_OUI_FROM_DATABASE=OMEGA ELECTRONICS SA + +OUI:00D0B2* + ID_OUI_FROM_DATABASE=XIOTECH CORPORATION + +OUI:00D0B3* + ID_OUI_FROM_DATABASE=DRS Technologies Canada Ltd + +OUI:00D0B4* + ID_OUI_FROM_DATABASE=KATSUJIMA CO., LTD. + +OUI:00D0B5* + ID_OUI_FROM_DATABASE=IPricot formerly DotCom + +OUI:00D0B6* + ID_OUI_FROM_DATABASE=CRESCENT NETWORKS, INC. + +OUI:00D0B7* + ID_OUI_FROM_DATABASE=INTEL CORPORATION + +OUI:00D0B8* + ID_OUI_FROM_DATABASE=Iomega Corporation + +OUI:00D0B9* + ID_OUI_FROM_DATABASE=MICROTEK INTERNATIONAL, INC. + +OUI:00D0BA* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00D0BB* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00D0BC* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00D0BD* + ID_OUI_FROM_DATABASE=Silicon Image GmbH + +OUI:00D0BE* + ID_OUI_FROM_DATABASE=EMUTEC INC. + +OUI:00D0BF* + ID_OUI_FROM_DATABASE=PIVOTAL TECHNOLOGIES + +OUI:00D0C0* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00D0C1* + ID_OUI_FROM_DATABASE=HARMONIC DATA SYSTEMS, LTD. + +OUI:00D0C2* + ID_OUI_FROM_DATABASE=BALTHAZAR TECHNOLOGY AB + +OUI:00D0C3* + ID_OUI_FROM_DATABASE=VIVID TECHNOLOGY PTE, LTD. + +OUI:00D0C4* + ID_OUI_FROM_DATABASE=TERATECH CORPORATION + +OUI:00D0C5* + ID_OUI_FROM_DATABASE=COMPUTATIONAL SYSTEMS, INC. + +OUI:00D0C6* + ID_OUI_FROM_DATABASE=THOMAS & BETTS CORP. + +OUI:00D0C7* + ID_OUI_FROM_DATABASE=PATHWAY, INC. + +OUI:00D0C8* + ID_OUI_FROM_DATABASE=Prevas A/S + +OUI:00D0C9* + ID_OUI_FROM_DATABASE=ADVANTECH CO., LTD. + +OUI:00D0CA* + ID_OUI_FROM_DATABASE=Intrinsyc Software International Inc. + +OUI:00D0CB* + ID_OUI_FROM_DATABASE=DASAN CO., LTD. + +OUI:00D0CC* + ID_OUI_FROM_DATABASE=TECHNOLOGIES LYRE INC. + +OUI:00D0CD* + ID_OUI_FROM_DATABASE=ATAN TECHNOLOGY INC. + +OUI:00D0CE* + ID_OUI_FROM_DATABASE=ASYST ELECTRONIC + +OUI:00D0CF* + ID_OUI_FROM_DATABASE=MORETON BAY + +OUI:00D0D0* + ID_OUI_FROM_DATABASE=ZHONGXING TELECOM LTD. + +OUI:00D0D1* + ID_OUI_FROM_DATABASE=Sycamore Networks + +OUI:00D0D2* + ID_OUI_FROM_DATABASE=EPILOG CORPORATION + +OUI:00D0D3* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00D0D4* + ID_OUI_FROM_DATABASE=V-BITS, INC. + +OUI:00D0D5* + ID_OUI_FROM_DATABASE=GRUNDIG AG + +OUI:00D0D6* + ID_OUI_FROM_DATABASE=AETHRA TELECOMUNICAZIONI + +OUI:00D0D7* + ID_OUI_FROM_DATABASE=B2C2, INC. + +OUI:00D0D8* + ID_OUI_FROM_DATABASE=3Com Corporation + +OUI:00D0D9* + ID_OUI_FROM_DATABASE=DEDICATED MICROCOMPUTERS + +OUI:00D0DA* + ID_OUI_FROM_DATABASE=TAICOM DATA SYSTEMS CO., LTD. + +OUI:00D0DB* + ID_OUI_FROM_DATABASE=MCQUAY INTERNATIONAL + +OUI:00D0DC* + ID_OUI_FROM_DATABASE=MODULAR MINING SYSTEMS, INC. + +OUI:00D0DD* + ID_OUI_FROM_DATABASE=SUNRISE TELECOM, INC. + +OUI:00D0DE* + ID_OUI_FROM_DATABASE=PHILIPS MULTIMEDIA NETWORK + +OUI:00D0DF* + ID_OUI_FROM_DATABASE=KUZUMI ELECTRONICS, INC. + +OUI:00D0E0* + ID_OUI_FROM_DATABASE=DOOIN ELECTRONICS CO. + +OUI:00D0E1* + ID_OUI_FROM_DATABASE=AVIONITEK ISRAEL INC. + +OUI:00D0E2* + ID_OUI_FROM_DATABASE=MRT MICRO, INC. + +OUI:00D0E3* + ID_OUI_FROM_DATABASE=ELE-CHEM ENGINEERING CO., LTD. + +OUI:00D0E4* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00D0E5* + ID_OUI_FROM_DATABASE=SOLIDUM SYSTEMS CORP. + +OUI:00D0E6* + ID_OUI_FROM_DATABASE=IBOND INC. + +OUI:00D0E7* + ID_OUI_FROM_DATABASE=VCON TELECOMMUNICATION LTD. + +OUI:00D0E8* + ID_OUI_FROM_DATABASE=MAC SYSTEM CO., LTD. + +OUI:00D0E9* + ID_OUI_FROM_DATABASE=Advantage Century Telecommunication Corp. + +OUI:00D0EA* + ID_OUI_FROM_DATABASE=NEXTONE COMMUNICATIONS, INC. + +OUI:00D0EB* + ID_OUI_FROM_DATABASE=LIGHTERA NETWORKS, INC. + +OUI:00D0EC* + ID_OUI_FROM_DATABASE=NAKAYO TELECOMMUNICATIONS, INC + +OUI:00D0ED* + ID_OUI_FROM_DATABASE=XIOX + +OUI:00D0EE* + ID_OUI_FROM_DATABASE=DICTAPHONE CORPORATION + +OUI:00D0EF* + ID_OUI_FROM_DATABASE=IGT + +OUI:00D0F0* + ID_OUI_FROM_DATABASE=CONVISION TECHNOLOGY GMBH + +OUI:00D0F1* + ID_OUI_FROM_DATABASE=SEGA ENTERPRISES, LTD. + +OUI:00D0F2* + ID_OUI_FROM_DATABASE=MONTEREY NETWORKS + +OUI:00D0F3* + ID_OUI_FROM_DATABASE=SOLARI DI UDINE SPA + +OUI:00D0F4* + ID_OUI_FROM_DATABASE=CARINTHIAN TECH INSTITUTE + +OUI:00D0F5* + ID_OUI_FROM_DATABASE=ORANGE MICRO, INC. + +OUI:00D0F6* + ID_OUI_FROM_DATABASE=Alcatel Canada + +OUI:00D0F7* + ID_OUI_FROM_DATABASE=NEXT NETS CORPORATION + +OUI:00D0F8* + ID_OUI_FROM_DATABASE=FUJIAN STAR TERMINAL + +OUI:00D0F9* + ID_OUI_FROM_DATABASE=ACUTE COMMUNICATIONS CORP. + +OUI:00D0FA* + ID_OUI_FROM_DATABASE=Thales e-Security Ltd. + +OUI:00D0FB* + ID_OUI_FROM_DATABASE=TEK MICROSYSTEMS, INCORPORATED + +OUI:00D0FC* + ID_OUI_FROM_DATABASE=GRANITE MICROSYSTEMS + +OUI:00D0FD* + ID_OUI_FROM_DATABASE=OPTIMA TELE.COM, INC. + +OUI:00D0FE* + ID_OUI_FROM_DATABASE=ASTRAL POINT + +OUI:00D0FF* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00D11C* + ID_OUI_FROM_DATABASE=ACETEL + +OUI:00D38D* + ID_OUI_FROM_DATABASE=Hotel Technology Next Generation + +OUI:00D632* + ID_OUI_FROM_DATABASE=GE Energy + +OUI:00DB1E* + ID_OUI_FROM_DATABASE=Albedo Telecom SL + +OUI:00DB45* + ID_OUI_FROM_DATABASE=THAMWAY CO.,LTD. + +OUI:00DBDF* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:00DD00* + ID_OUI_FROM_DATABASE=UNGERMANN-BASS INC. + +OUI:00DD01* + ID_OUI_FROM_DATABASE=UNGERMANN-BASS INC. + +OUI:00DD02* + ID_OUI_FROM_DATABASE=UNGERMANN-BASS INC. + +OUI:00DD03* + ID_OUI_FROM_DATABASE=UNGERMANN-BASS INC. + +OUI:00DD04* + ID_OUI_FROM_DATABASE=UNGERMANN-BASS INC. + +OUI:00DD05* + ID_OUI_FROM_DATABASE=UNGERMANN-BASS INC. + +OUI:00DD06* + ID_OUI_FROM_DATABASE=UNGERMANN-BASS INC. + +OUI:00DD07* + ID_OUI_FROM_DATABASE=UNGERMANN-BASS INC. + +OUI:00DD08* + ID_OUI_FROM_DATABASE=UNGERMANN-BASS INC. + +OUI:00DD09* + ID_OUI_FROM_DATABASE=UNGERMANN-BASS INC. + +OUI:00DD0A* + ID_OUI_FROM_DATABASE=UNGERMANN-BASS INC. + +OUI:00DD0B* + ID_OUI_FROM_DATABASE=UNGERMANN-BASS INC. + +OUI:00DD0C* + ID_OUI_FROM_DATABASE=UNGERMANN-BASS INC. + +OUI:00DD0D* + ID_OUI_FROM_DATABASE=UNGERMANN-BASS INC. + +OUI:00DD0E* + ID_OUI_FROM_DATABASE=UNGERMANN-BASS INC. + +OUI:00DD0F* + ID_OUI_FROM_DATABASE=UNGERMANN-BASS INC. + +OUI:00DEFB* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00E000* + ID_OUI_FROM_DATABASE=Fujitsu Limited + +OUI:00E001* + ID_OUI_FROM_DATABASE=STRAND LIGHTING LIMITED + +OUI:00E002* + ID_OUI_FROM_DATABASE=CROSSROADS SYSTEMS, INC. + +OUI:00E003* + ID_OUI_FROM_DATABASE=NOKIA WIRELESS BUSINESS COMMUN + +OUI:00E004* + ID_OUI_FROM_DATABASE=PMC-SIERRA, INC. + +OUI:00E005* + ID_OUI_FROM_DATABASE=TECHNICAL CORP. + +OUI:00E006* + ID_OUI_FROM_DATABASE=SILICON INTEGRATED SYS. CORP. + +OUI:00E007* + ID_OUI_FROM_DATABASE=Avaya ECS Ltd + +OUI:00E008* + ID_OUI_FROM_DATABASE=AMAZING CONTROLS! INC. + +OUI:00E009* + ID_OUI_FROM_DATABASE=MARATHON TECHNOLOGIES CORP. + +OUI:00E00A* + ID_OUI_FROM_DATABASE=DIBA, INC. + +OUI:00E00B* + ID_OUI_FROM_DATABASE=ROOFTOP COMMUNICATIONS CORP. + +OUI:00E00C* + ID_OUI_FROM_DATABASE=MOTOROLA + +OUI:00E00D* + ID_OUI_FROM_DATABASE=RADIANT SYSTEMS + +OUI:00E00E* + ID_OUI_FROM_DATABASE=AVALON IMAGING SYSTEMS, INC. + +OUI:00E00F* + ID_OUI_FROM_DATABASE=SHANGHAI BAUD DATA + +OUI:00E010* + ID_OUI_FROM_DATABASE=HESS SB-AUTOMATENBAU GmbH + +OUI:00E011* + ID_OUI_FROM_DATABASE=Uniden Corporation + +OUI:00E012* + ID_OUI_FROM_DATABASE=PLUTO TECHNOLOGIES INTERNATIONAL INC. + +OUI:00E013* + ID_OUI_FROM_DATABASE=EASTERN ELECTRONIC CO., LTD. + +OUI:00E014* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00E015* + ID_OUI_FROM_DATABASE=HEIWA CORPORATION + +OUI:00E016* + ID_OUI_FROM_DATABASE=RAPID CITY COMMUNICATIONS + +OUI:00E017* + ID_OUI_FROM_DATABASE=EXXACT GmbH + +OUI:00E018* + ID_OUI_FROM_DATABASE=ASUSTEK COMPUTER INC. + +OUI:00E019* + ID_OUI_FROM_DATABASE=ING. GIORDANO ELETTRONICA + +OUI:00E01A* + ID_OUI_FROM_DATABASE=COMTEC SYSTEMS. CO., LTD. + +OUI:00E01B* + ID_OUI_FROM_DATABASE=SPHERE COMMUNICATIONS, INC. + +OUI:00E01C* + ID_OUI_FROM_DATABASE=Cradlepoint, Inc + +OUI:00E01D* + ID_OUI_FROM_DATABASE=WebTV NETWORKS, INC. + +OUI:00E01E* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00E01F* + ID_OUI_FROM_DATABASE=AVIDIA Systems, Inc. + +OUI:00E020* + ID_OUI_FROM_DATABASE=TECNOMEN OY + +OUI:00E021* + ID_OUI_FROM_DATABASE=FREEGATE CORP. + +OUI:00E022* + ID_OUI_FROM_DATABASE=Analog Devices Inc. + +OUI:00E023* + ID_OUI_FROM_DATABASE=TELRAD + +OUI:00E024* + ID_OUI_FROM_DATABASE=GADZOOX NETWORKS + +OUI:00E025* + ID_OUI_FROM_DATABASE=dit Co., Ltd. + +OUI:00E026* + ID_OUI_FROM_DATABASE=Redlake MASD LLC + +OUI:00E027* + ID_OUI_FROM_DATABASE=DUX, INC. + +OUI:00E028* + ID_OUI_FROM_DATABASE=APTIX CORPORATION + +OUI:00E029* + ID_OUI_FROM_DATABASE=STANDARD MICROSYSTEMS CORP. + +OUI:00E02A* + ID_OUI_FROM_DATABASE=TANDBERG TELEVISION AS + +OUI:00E02B* + ID_OUI_FROM_DATABASE=EXTREME NETWORKS + +OUI:00E02C* + ID_OUI_FROM_DATABASE=AST COMPUTER + +OUI:00E02D* + ID_OUI_FROM_DATABASE=InnoMediaLogic, Inc. + +OUI:00E02E* + ID_OUI_FROM_DATABASE=SPC ELECTRONICS CORPORATION + +OUI:00E02F* + ID_OUI_FROM_DATABASE=MCNS HOLDINGS, L.P. + +OUI:00E030* + ID_OUI_FROM_DATABASE=MELITA INTERNATIONAL CORP. + +OUI:00E031* + ID_OUI_FROM_DATABASE=HAGIWARA ELECTRIC CO., LTD. + +OUI:00E032* + ID_OUI_FROM_DATABASE=MISYS FINANCIAL SYSTEMS, LTD. + +OUI:00E033* + ID_OUI_FROM_DATABASE=E.E.P.D. GmbH + +OUI:00E034* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00E035* + ID_OUI_FROM_DATABASE=Emerson Network Power + +OUI:00E036* + ID_OUI_FROM_DATABASE=PIONEER CORPORATION + +OUI:00E037* + ID_OUI_FROM_DATABASE=CENTURY CORPORATION + +OUI:00E038* + ID_OUI_FROM_DATABASE=PROXIMA CORPORATION + +OUI:00E039* + ID_OUI_FROM_DATABASE=PARADYNE CORP. + +OUI:00E03A* + ID_OUI_FROM_DATABASE=CABLETRON SYSTEMS, INC. + +OUI:00E03B* + ID_OUI_FROM_DATABASE=PROMINET CORPORATION + +OUI:00E03C* + ID_OUI_FROM_DATABASE=AdvanSys + +OUI:00E03D* + ID_OUI_FROM_DATABASE=FOCON ELECTRONIC SYSTEMS A/S + +OUI:00E03E* + ID_OUI_FROM_DATABASE=ALFATECH, INC. + +OUI:00E03F* + ID_OUI_FROM_DATABASE=JATON CORPORATION + +OUI:00E040* + ID_OUI_FROM_DATABASE=DeskStation Technology, Inc. + +OUI:00E041* + ID_OUI_FROM_DATABASE=CSPI + +OUI:00E042* + ID_OUI_FROM_DATABASE=Pacom Systems Ltd. + +OUI:00E043* + ID_OUI_FROM_DATABASE=VitalCom + +OUI:00E044* + ID_OUI_FROM_DATABASE=LSICS CORPORATION + +OUI:00E045* + ID_OUI_FROM_DATABASE=TOUCHWAVE, INC. + +OUI:00E046* + ID_OUI_FROM_DATABASE=BENTLY NEVADA CORP. + +OUI:00E047* + ID_OUI_FROM_DATABASE=InFocus Corporation + +OUI:00E048* + ID_OUI_FROM_DATABASE=SDL COMMUNICATIONS, INC. + +OUI:00E049* + ID_OUI_FROM_DATABASE=MICROWI ELECTRONIC GmbH + +OUI:00E04A* + ID_OUI_FROM_DATABASE=ENHANCED MESSAGING SYSTEMS, INC + +OUI:00E04B* + ID_OUI_FROM_DATABASE=JUMP INDUSTRIELLE COMPUTERTECHNIK GmbH + +OUI:00E04C* + ID_OUI_FROM_DATABASE=REALTEK SEMICONDUCTOR CORP. + +OUI:00E04D* + ID_OUI_FROM_DATABASE=INTERNET INITIATIVE JAPAN, INC + +OUI:00E04E* + ID_OUI_FROM_DATABASE=SANYO DENKI CO., LTD. + +OUI:00E04F* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00E050* + ID_OUI_FROM_DATABASE=EXECUTONE INFORMATION SYSTEMS, INC. + +OUI:00E051* + ID_OUI_FROM_DATABASE=TALX CORPORATION + +OUI:00E052* + ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc + +OUI:00E053* + ID_OUI_FROM_DATABASE=CELLPORT LABS, INC. + +OUI:00E054* + ID_OUI_FROM_DATABASE=KODAI HITEC CO., LTD. + +OUI:00E055* + ID_OUI_FROM_DATABASE=INGENIERIA ELECTRONICA COMERCIAL INELCOM S.A. + +OUI:00E056* + ID_OUI_FROM_DATABASE=HOLONTECH CORPORATION + +OUI:00E057* + ID_OUI_FROM_DATABASE=HAN MICROTELECOM. CO., LTD. + +OUI:00E058* + ID_OUI_FROM_DATABASE=PHASE ONE DENMARK A/S + +OUI:00E059* + ID_OUI_FROM_DATABASE=CONTROLLED ENVIRONMENTS, LTD. + +OUI:00E05A* + ID_OUI_FROM_DATABASE=GALEA NETWORK SECURITY + +OUI:00E05B* + ID_OUI_FROM_DATABASE=WEST END SYSTEMS CORP. + +OUI:00E05C* + ID_OUI_FROM_DATABASE=MATSUSHITA KOTOBUKI ELECTRONICS INDUSTRIES, LTD. + +OUI:00E05D* + ID_OUI_FROM_DATABASE=UNITEC CO., LTD. + +OUI:00E05E* + ID_OUI_FROM_DATABASE=JAPAN AVIATION ELECTRONICS INDUSTRY, LTD. + +OUI:00E05F* + ID_OUI_FROM_DATABASE=e-Net, Inc. + +OUI:00E060* + ID_OUI_FROM_DATABASE=SHERWOOD + +OUI:00E061* + ID_OUI_FROM_DATABASE=EdgePoint Networks, Inc. + +OUI:00E062* + ID_OUI_FROM_DATABASE=HOST ENGINEERING + +OUI:00E063* + ID_OUI_FROM_DATABASE=CABLETRON - YAGO SYSTEMS, INC. + +OUI:00E064* + ID_OUI_FROM_DATABASE=SAMSUNG ELECTRONICS + +OUI:00E065* + ID_OUI_FROM_DATABASE=OPTICAL ACCESS INTERNATIONAL + +OUI:00E066* + ID_OUI_FROM_DATABASE=ProMax Systems, Inc. + +OUI:00E067* + ID_OUI_FROM_DATABASE=eac AUTOMATION-CONSULTING GmbH + +OUI:00E068* + ID_OUI_FROM_DATABASE=MERRIMAC SYSTEMS INC. + +OUI:00E069* + ID_OUI_FROM_DATABASE=JAYCOR + +OUI:00E06A* + ID_OUI_FROM_DATABASE=KAPSCH AG + +OUI:00E06B* + ID_OUI_FROM_DATABASE=W&G SPECIAL PRODUCTS + +OUI:00E06C* + ID_OUI_FROM_DATABASE=AEP Systems International Ltd + +OUI:00E06D* + ID_OUI_FROM_DATABASE=COMPUWARE CORPORATION + +OUI:00E06E* + ID_OUI_FROM_DATABASE=FAR SYSTEMS S.p.A. + +OUI:00E06F* + ID_OUI_FROM_DATABASE=Motorola, Inc. + +OUI:00E070* + ID_OUI_FROM_DATABASE=DH TECHNOLOGY + +OUI:00E071* + ID_OUI_FROM_DATABASE=EPIS MICROCOMPUTER + +OUI:00E072* + ID_OUI_FROM_DATABASE=LYNK + +OUI:00E073* + ID_OUI_FROM_DATABASE=NATIONAL AMUSEMENT NETWORK, INC. + +OUI:00E074* + ID_OUI_FROM_DATABASE=TIERNAN COMMUNICATIONS, INC. + +OUI:00E075* + ID_OUI_FROM_DATABASE=Verilink Corporation + +OUI:00E076* + ID_OUI_FROM_DATABASE=DEVELOPMENT CONCEPTS, INC. + +OUI:00E077* + ID_OUI_FROM_DATABASE=WEBGEAR, INC. + +OUI:00E078* + ID_OUI_FROM_DATABASE=BERKELEY NETWORKS + +OUI:00E079* + ID_OUI_FROM_DATABASE=A.T.N.R. + +OUI:00E07A* + ID_OUI_FROM_DATABASE=MIKRODIDAKT AB + +OUI:00E07B* + ID_OUI_FROM_DATABASE=BAY NETWORKS + +OUI:00E07C* + ID_OUI_FROM_DATABASE=METTLER-TOLEDO, INC. + +OUI:00E07D* + ID_OUI_FROM_DATABASE=NETRONIX, INC. + +OUI:00E07E* + ID_OUI_FROM_DATABASE=WALT DISNEY IMAGINEERING + +OUI:00E07F* + ID_OUI_FROM_DATABASE=LOGISTISTEM s.r.l. + +OUI:00E080* + ID_OUI_FROM_DATABASE=CONTROL RESOURCES CORPORATION + +OUI:00E081* + ID_OUI_FROM_DATABASE=TYAN COMPUTER CORP. + +OUI:00E082* + ID_OUI_FROM_DATABASE=ANERMA + +OUI:00E083* + ID_OUI_FROM_DATABASE=JATO TECHNOLOGIES, INC. + +OUI:00E084* + ID_OUI_FROM_DATABASE=COMPULITE R&D + +OUI:00E085* + ID_OUI_FROM_DATABASE=GLOBAL MAINTECH, INC. + +OUI:00E086* + ID_OUI_FROM_DATABASE=CYBEX COMPUTER PRODUCTS + +OUI:00E087* + ID_OUI_FROM_DATABASE=LeCroy - Networking Productions Division + +OUI:00E088* + ID_OUI_FROM_DATABASE=LTX CORPORATION + +OUI:00E089* + ID_OUI_FROM_DATABASE=ION Networks, Inc. + +OUI:00E08A* + ID_OUI_FROM_DATABASE=GEC AVERY, LTD. + +OUI:00E08B* + ID_OUI_FROM_DATABASE=QLogic Corp. + +OUI:00E08C* + ID_OUI_FROM_DATABASE=NEOPARADIGM LABS, INC. + +OUI:00E08D* + ID_OUI_FROM_DATABASE=PRESSURE SYSTEMS, INC. + +OUI:00E08E* + ID_OUI_FROM_DATABASE=UTSTARCOM + +OUI:00E08F* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00E090* + ID_OUI_FROM_DATABASE=BECKMAN LAB. AUTOMATION DIV. + +OUI:00E091* + ID_OUI_FROM_DATABASE=LG ELECTRONICS, INC. + +OUI:00E092* + ID_OUI_FROM_DATABASE=ADMTEK INCORPORATED + +OUI:00E093* + ID_OUI_FROM_DATABASE=ACKFIN NETWORKS + +OUI:00E094* + ID_OUI_FROM_DATABASE=OSAI SRL + +OUI:00E095* + ID_OUI_FROM_DATABASE=ADVANCED-VISION TECHNOLGIES CORP. + +OUI:00E096* + ID_OUI_FROM_DATABASE=SHIMADZU CORPORATION + +OUI:00E097* + ID_OUI_FROM_DATABASE=CARRIER ACCESS CORPORATION + +OUI:00E098* + ID_OUI_FROM_DATABASE=AboCom Systems, Inc. + +OUI:00E099* + ID_OUI_FROM_DATABASE=SAMSON AG + +OUI:00E09A* + ID_OUI_FROM_DATABASE=Positron Inc. + +OUI:00E09B* + ID_OUI_FROM_DATABASE=ENGAGE NETWORKS, INC. + +OUI:00E09C* + ID_OUI_FROM_DATABASE=MII + +OUI:00E09D* + ID_OUI_FROM_DATABASE=SARNOFF CORPORATION + +OUI:00E09E* + ID_OUI_FROM_DATABASE=QUANTUM CORPORATION + +OUI:00E09F* + ID_OUI_FROM_DATABASE=PIXEL VISION + +OUI:00E0A0* + ID_OUI_FROM_DATABASE=WILTRON CO. + +OUI:00E0A1* + ID_OUI_FROM_DATABASE=HIMA PAUL HILDEBRANDT GmbH Co. KG + +OUI:00E0A2* + ID_OUI_FROM_DATABASE=MICROSLATE INC. + +OUI:00E0A3* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00E0A4* + ID_OUI_FROM_DATABASE=ESAOTE S.p.A. + +OUI:00E0A5* + ID_OUI_FROM_DATABASE=ComCore Semiconductor, Inc. + +OUI:00E0A6* + ID_OUI_FROM_DATABASE=TELOGY NETWORKS, INC. + +OUI:00E0A7* + ID_OUI_FROM_DATABASE=IPC INFORMATION SYSTEMS, INC. + +OUI:00E0A8* + ID_OUI_FROM_DATABASE=SAT GmbH & Co. + +OUI:00E0A9* + ID_OUI_FROM_DATABASE=FUNAI ELECTRIC CO., LTD. + +OUI:00E0AA* + ID_OUI_FROM_DATABASE=ELECTROSONIC LTD. + +OUI:00E0AB* + ID_OUI_FROM_DATABASE=DIMAT S.A. + +OUI:00E0AC* + ID_OUI_FROM_DATABASE=MIDSCO, INC. + +OUI:00E0AD* + ID_OUI_FROM_DATABASE=EES TECHNOLOGY, LTD. + +OUI:00E0AE* + ID_OUI_FROM_DATABASE=XAQTI CORPORATION + +OUI:00E0AF* + ID_OUI_FROM_DATABASE=GENERAL DYNAMICS INFORMATION SYSTEMS + +OUI:00E0B0* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00E0B1* + ID_OUI_FROM_DATABASE=Alcatel-Lucent, Enterprise Business Group + +OUI:00E0B2* + ID_OUI_FROM_DATABASE=TELMAX COMMUNICATIONS CORP. + +OUI:00E0B3* + ID_OUI_FROM_DATABASE=EtherWAN Systems, Inc. + +OUI:00E0B4* + ID_OUI_FROM_DATABASE=TECHNO SCOPE CO., LTD. + +OUI:00E0B5* + ID_OUI_FROM_DATABASE=ARDENT COMMUNICATIONS CORP. + +OUI:00E0B6* + ID_OUI_FROM_DATABASE=Entrada Networks + +OUI:00E0B7* + ID_OUI_FROM_DATABASE=PI GROUP, LTD. + +OUI:00E0B8* + ID_OUI_FROM_DATABASE=GATEWAY 2000 + +OUI:00E0B9* + ID_OUI_FROM_DATABASE=BYAS SYSTEMS + +OUI:00E0BA* + ID_OUI_FROM_DATABASE=BERGHOF AUTOMATIONSTECHNIK GmbH + +OUI:00E0BB* + ID_OUI_FROM_DATABASE=NBX CORPORATION + +OUI:00E0BC* + ID_OUI_FROM_DATABASE=SYMON COMMUNICATIONS, INC. + +OUI:00E0BD* + ID_OUI_FROM_DATABASE=INTERFACE SYSTEMS, INC. + +OUI:00E0BE* + ID_OUI_FROM_DATABASE=GENROCO INTERNATIONAL, INC. + +OUI:00E0BF* + ID_OUI_FROM_DATABASE=TORRENT NETWORKING TECHNOLOGIES CORP. + +OUI:00E0C0* + ID_OUI_FROM_DATABASE=SEIWA ELECTRIC MFG. CO., LTD. + +OUI:00E0C1* + ID_OUI_FROM_DATABASE=MEMOREX TELEX JAPAN, LTD. + +OUI:00E0C2* + ID_OUI_FROM_DATABASE=NECSY S.p.A. + +OUI:00E0C3* + ID_OUI_FROM_DATABASE=SAKAI SYSTEM DEVELOPMENT CORP. + +OUI:00E0C4* + ID_OUI_FROM_DATABASE=HORNER ELECTRIC, INC. + +OUI:00E0C5* + ID_OUI_FROM_DATABASE=BCOM ELECTRONICS INC. + +OUI:00E0C6* + ID_OUI_FROM_DATABASE=LINK2IT, L.L.C. + +OUI:00E0C7* + ID_OUI_FROM_DATABASE=EUROTECH SRL + +OUI:00E0C8* + ID_OUI_FROM_DATABASE=VIRTUAL ACCESS, LTD. + +OUI:00E0C9* + ID_OUI_FROM_DATABASE=AutomatedLogic Corporation + +OUI:00E0CA* + ID_OUI_FROM_DATABASE=BEST DATA PRODUCTS + +OUI:00E0CB* + ID_OUI_FROM_DATABASE=RESON, INC. + +OUI:00E0CC* + ID_OUI_FROM_DATABASE=HERO SYSTEMS, LTD. + +OUI:00E0CD* + ID_OUI_FROM_DATABASE=SENSIS CORPORATION + +OUI:00E0CE* + ID_OUI_FROM_DATABASE=ARN + +OUI:00E0CF* + ID_OUI_FROM_DATABASE=INTEGRATED DEVICE TECHNOLOGY, INC. + +OUI:00E0D0* + ID_OUI_FROM_DATABASE=NETSPEED, INC. + +OUI:00E0D1* + ID_OUI_FROM_DATABASE=TELSIS LIMITED + +OUI:00E0D2* + ID_OUI_FROM_DATABASE=VERSANET COMMUNICATIONS, INC. + +OUI:00E0D3* + ID_OUI_FROM_DATABASE=DATENTECHNIK GmbH + +OUI:00E0D4* + ID_OUI_FROM_DATABASE=EXCELLENT COMPUTER + +OUI:00E0D5* + ID_OUI_FROM_DATABASE=Emulex Corporation + +OUI:00E0D6* + ID_OUI_FROM_DATABASE=COMPUTER & COMMUNICATION RESEARCH LAB. + +OUI:00E0D7* + ID_OUI_FROM_DATABASE=SUNSHINE ELECTRONICS, INC. + +OUI:00E0D8* + ID_OUI_FROM_DATABASE=LANBit Computer, Inc. + +OUI:00E0D9* + ID_OUI_FROM_DATABASE=TAZMO CO., LTD. + +OUI:00E0DA* + ID_OUI_FROM_DATABASE=Alcatel North America ESD + +OUI:00E0DB* + ID_OUI_FROM_DATABASE=ViaVideo Communications, Inc. + +OUI:00E0DC* + ID_OUI_FROM_DATABASE=NEXWARE CORP. + +OUI:00E0DD* + ID_OUI_FROM_DATABASE=ZENITH ELECTRONICS CORPORATION + +OUI:00E0DE* + ID_OUI_FROM_DATABASE=DATAX NV + +OUI:00E0DF* + ID_OUI_FROM_DATABASE=KEYMILE GmbH + +OUI:00E0E0* + ID_OUI_FROM_DATABASE=SI ELECTRONICS, LTD. + +OUI:00E0E1* + ID_OUI_FROM_DATABASE=G2 NETWORKS, INC. + +OUI:00E0E2* + ID_OUI_FROM_DATABASE=INNOVA CORP. + +OUI:00E0E3* + ID_OUI_FROM_DATABASE=SK-ELEKTRONIK GmbH + +OUI:00E0E4* + ID_OUI_FROM_DATABASE=FANUC ROBOTICS NORTH AMERICA, Inc. + +OUI:00E0E5* + ID_OUI_FROM_DATABASE=CINCO NETWORKS, INC. + +OUI:00E0E6* + ID_OUI_FROM_DATABASE=INCAA DATACOM B.V. + +OUI:00E0E7* + ID_OUI_FROM_DATABASE=RAYTHEON E-SYSTEMS, INC. + +OUI:00E0E8* + ID_OUI_FROM_DATABASE=GRETACODER Data Systems AG + +OUI:00E0E9* + ID_OUI_FROM_DATABASE=DATA LABS, INC. + +OUI:00E0EA* + ID_OUI_FROM_DATABASE=INNOVAT COMMUNICATIONS, INC. + +OUI:00E0EB* + ID_OUI_FROM_DATABASE=DIGICOM SYSTEMS, INCORPORATED + +OUI:00E0EC* + ID_OUI_FROM_DATABASE=CELESTICA INC. + +OUI:00E0ED* + ID_OUI_FROM_DATABASE=SILICOM, LTD. + +OUI:00E0EE* + ID_OUI_FROM_DATABASE=MAREL HF + +OUI:00E0EF* + ID_OUI_FROM_DATABASE=DIONEX + +OUI:00E0F0* + ID_OUI_FROM_DATABASE=ABLER TECHNOLOGY, INC. + +OUI:00E0F1* + ID_OUI_FROM_DATABASE=THAT CORPORATION + +OUI:00E0F2* + ID_OUI_FROM_DATABASE=ARLOTTO COMNET, INC. + +OUI:00E0F3* + ID_OUI_FROM_DATABASE=WebSprint Communications, Inc. + +OUI:00E0F4* + ID_OUI_FROM_DATABASE=INSIDE Technology A/S + +OUI:00E0F5* + ID_OUI_FROM_DATABASE=TELES AG + +OUI:00E0F6* + ID_OUI_FROM_DATABASE=DECISION EUROPE + +OUI:00E0F7* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00E0F8* + ID_OUI_FROM_DATABASE=DICNA CONTROL AB + +OUI:00E0F9* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00E0FA* + ID_OUI_FROM_DATABASE=TRL TECHNOLOGY, LTD. + +OUI:00E0FB* + ID_OUI_FROM_DATABASE=LEIGHTRONIX, INC. + +OUI:00E0FC* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO., LTD. + +OUI:00E0FD* + ID_OUI_FROM_DATABASE=A-TREND TECHNOLOGY CO., LTD. + +OUI:00E0FE* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:00E0FF* + ID_OUI_FROM_DATABASE=SECURITY DYNAMICS TECHNOLOGIES, Inc. + +OUI:00E175* + ID_OUI_FROM_DATABASE=AK-Systems Ltd + +OUI:00E666* + ID_OUI_FROM_DATABASE=ARIMA Communications Corp. + +OUI:00E6D3* + ID_OUI_FROM_DATABASE=NIXDORF COMPUTER CORP. + +OUI:00E8AB* + ID_OUI_FROM_DATABASE=Meggitt Training Systems, Inc. + +OUI:00EB2D* + ID_OUI_FROM_DATABASE=Sony Mobile Communications AB + +OUI:00F051* + ID_OUI_FROM_DATABASE=KWB Gmbh + +OUI:00F403* + ID_OUI_FROM_DATABASE=Orbis Systems Oy + +OUI:00F4B9* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:00F860* + ID_OUI_FROM_DATABASE=PT. Panggung Electric Citrabuana + +OUI:00FA3B* + ID_OUI_FROM_DATABASE=CLOOS ELECTRONIC GMBH + +OUI:00FC58* + ID_OUI_FROM_DATABASE=WebSilicon Ltd. + +OUI:00FC70* + ID_OUI_FROM_DATABASE=Intrepid Control Systems, Inc. + +OUI:00FD4C* + ID_OUI_FROM_DATABASE=NEVATEC + +OUI:020701* + ID_OUI_FROM_DATABASE=RACAL-DATACOM + +OUI:021C7C* + ID_OUI_FROM_DATABASE=PERQ SYSTEMS CORPORATION + +OUI:026086* + ID_OUI_FROM_DATABASE=LOGIC REPLACEMENT TECH. LTD. + +OUI:02608C* + ID_OUI_FROM_DATABASE=3COM CORPORATION + +OUI:027001* + ID_OUI_FROM_DATABASE=RACAL-DATACOM + +OUI:0270B0* + ID_OUI_FROM_DATABASE=M/A-COM INC. COMPANIES + +OUI:0270B3* + ID_OUI_FROM_DATABASE=DATA RECALL LTD + +OUI:029D8E* + ID_OUI_FROM_DATABASE=CARDIAC RECORDERS INC. + +OUI:02AA3C* + ID_OUI_FROM_DATABASE=OLIVETTI TELECOMM SPA (OLTECO) + +OUI:02BB01* + ID_OUI_FROM_DATABASE=OCTOTHORPE CORP. + +OUI:02C08C* + ID_OUI_FROM_DATABASE=3COM CORPORATION + +OUI:02CF1C* + ID_OUI_FROM_DATABASE=COMMUNICATION MACHINERY CORP. + +OUI:02E6D3* + ID_OUI_FROM_DATABASE=NIXDORF COMPUTER CORPORATION + +OUI:040A83* + ID_OUI_FROM_DATABASE=Alcatel-Lucent + +OUI:040AE0* + ID_OUI_FROM_DATABASE=XMIT AG COMPUTER NETWORKS + +OUI:040CCE* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:040EC2* + ID_OUI_FROM_DATABASE=ViewSonic Mobile China Limited + +OUI:041552* + ID_OUI_FROM_DATABASE=Apple + +OUI:04180F* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:0418D6* + ID_OUI_FROM_DATABASE=Ubiquiti Networks + +OUI:041D10* + ID_OUI_FROM_DATABASE=Dream Ware Inc. + +OUI:041E64* + ID_OUI_FROM_DATABASE=Apple, Inc + +OUI:04209A* + ID_OUI_FROM_DATABASE=Panasonic AVC Networks Company + +OUI:042234* + ID_OUI_FROM_DATABASE=Wireless Standard Extensions + +OUI:042605* + ID_OUI_FROM_DATABASE=GFR Gesellschaft für Regelungstechnik und Energieeinsparung mbH + +OUI:042665* + ID_OUI_FROM_DATABASE=Apple + +OUI:042BBB* + ID_OUI_FROM_DATABASE=PicoCELA, Inc. + +OUI:042F56* + ID_OUI_FROM_DATABASE=ATOCS (Shenzhen) LTD + +OUI:0432F4* + ID_OUI_FROM_DATABASE=Partron + +OUI:043604* + ID_OUI_FROM_DATABASE=Gyeyoung I&T + +OUI:044665* + ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd. + +OUI:044A50* + ID_OUI_FROM_DATABASE=Ramaxel Technology (Shenzhen) limited company + +OUI:044BFF* + ID_OUI_FROM_DATABASE=GuangZhou Hedy Digital Technology Co., Ltd + +OUI:044FAA* + ID_OUI_FROM_DATABASE=Ruckus Wireless + +OUI:045453* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:0455CA* + ID_OUI_FROM_DATABASE=BriView (Xiamen) Corp. + +OUI:04586F* + ID_OUI_FROM_DATABASE=Sichuan Whayer information industry Co.,LTD + +OUI:045A95* + ID_OUI_FROM_DATABASE=Nokia Corporation + +OUI:045C06* + ID_OUI_FROM_DATABASE=Zmodo Technology Corporation + +OUI:045D56* + ID_OUI_FROM_DATABASE=camtron industrial inc. + +OUI:045FA7* + ID_OUI_FROM_DATABASE=Shenzhen Yichen Technology Development Co.,LTD + +OUI:0462D7* + ID_OUI_FROM_DATABASE=ALSTOM HYDRO FRANCE + +OUI:0463E0* + ID_OUI_FROM_DATABASE=Nome Oy + +OUI:046D42* + ID_OUI_FROM_DATABASE=Bryston Ltd. + +OUI:046E49* + ID_OUI_FROM_DATABASE=TaiYear Electronic Technology (Suzhou) Co., Ltd + +OUI:0470BC* + ID_OUI_FROM_DATABASE=Globalstar Inc. + +OUI:0474A1* + ID_OUI_FROM_DATABASE=Aligera Equipamentos Digitais Ltda + +OUI:0475F5* + ID_OUI_FROM_DATABASE=CSST + +OUI:04766E* + ID_OUI_FROM_DATABASE=ALPS Co,. Ltd. + +OUI:047D7B* + ID_OUI_FROM_DATABASE=Quanta Computer Inc. + +OUI:0481AE* + ID_OUI_FROM_DATABASE=Clack Corporation + +OUI:04888C* + ID_OUI_FROM_DATABASE=Eifelwerk Butler Systeme GmbH + +OUI:048A15* + ID_OUI_FROM_DATABASE=Avaya, Inc + +OUI:048B42* + ID_OUI_FROM_DATABASE=Skspruce Technology Limited + +OUI:0494A1* + ID_OUI_FROM_DATABASE=CATCH THE WIND INC + +OUI:0498F3* + ID_OUI_FROM_DATABASE=ALPS Electric Co,. Ltd. + +OUI:049C62* + ID_OUI_FROM_DATABASE=BMT Medical Technology s.r.o. + +OUI:049F06* + ID_OUI_FROM_DATABASE=Smobile Co., Ltd. + +OUI:049F81* + ID_OUI_FROM_DATABASE=Simena, LLC + +OUI:04A3F3* + ID_OUI_FROM_DATABASE=Emicon + +OUI:04A82A* + ID_OUI_FROM_DATABASE=Nokia Corporation + +OUI:04B3B6* + ID_OUI_FROM_DATABASE=Seamap (UK) Ltd + +OUI:04B466* + ID_OUI_FROM_DATABASE=BSP Co., Ltd. + +OUI:04C05B* + ID_OUI_FROM_DATABASE=Tigo Energy + +OUI:04C06F* + ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd + +OUI:04C1B9* + ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Tech.Co.,Ltd. + +OUI:04C5A4* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:04C880* + ID_OUI_FROM_DATABASE=Samtec Inc + +OUI:04CE14* + ID_OUI_FROM_DATABASE=Wilocity LTD. + +OUI:04D783* + ID_OUI_FROM_DATABASE=Y&H E&C Co.,LTD. + +OUI:04DAD2* + ID_OUI_FROM_DATABASE=Cisco + +OUI:04DD4C* + ID_OUI_FROM_DATABASE=IPBlaze + +OUI:04E0C4* + ID_OUI_FROM_DATABASE=TRIUMPH-ADLER AG + +OUI:04E1C8* + ID_OUI_FROM_DATABASE=IMS Soluções em Energia Ltda. + +OUI:04E2F8* + ID_OUI_FROM_DATABASE=AEP srl + +OUI:04E451* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:04E548* + ID_OUI_FROM_DATABASE=Cohda Wireless Pty Ltd + +OUI:04E662* + ID_OUI_FROM_DATABASE=Acroname Inc. + +OUI:04E9E5* + ID_OUI_FROM_DATABASE=PJRC.COM, LLC + +OUI:04EE91* + ID_OUI_FROM_DATABASE=x-fabric GmbH + +OUI:04F021* + ID_OUI_FROM_DATABASE=Compex Systems Pte Ltd + +OUI:04F17D* + ID_OUI_FROM_DATABASE=Tarana Wireless + +OUI:04F4BC* + ID_OUI_FROM_DATABASE=Xena Networks + +OUI:04F7E4* + ID_OUI_FROM_DATABASE=Apple + +OUI:04F8C2* + ID_OUI_FROM_DATABASE=Flaircomm Microelectronics, Inc. + +OUI:04FE31* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:04FE7F* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:04FF51* + ID_OUI_FROM_DATABASE=NOVAMEDIA INNOVISION SP. Z O.O. + +OUI:080001* + ID_OUI_FROM_DATABASE=COMPUTERVISION CORPORATION + +OUI:080002* + ID_OUI_FROM_DATABASE=BRIDGE COMMUNICATIONS INC. + +OUI:080003* + ID_OUI_FROM_DATABASE=ADVANCED COMPUTER COMM. + +OUI:080004* + ID_OUI_FROM_DATABASE=CROMEMCO INCORPORATED + +OUI:080005* + ID_OUI_FROM_DATABASE=SYMBOLICS INC. + +OUI:080006* + ID_OUI_FROM_DATABASE=SIEMENS AG + +OUI:080007* + ID_OUI_FROM_DATABASE=APPLE COMPUTER INC. + +OUI:080008* + ID_OUI_FROM_DATABASE=BOLT BERANEK AND NEWMAN INC. + +OUI:080009* + ID_OUI_FROM_DATABASE=HEWLETT PACKARD + +OUI:08000A* + ID_OUI_FROM_DATABASE=NESTAR SYSTEMS INCORPORATED + +OUI:08000B* + ID_OUI_FROM_DATABASE=UNISYS CORPORATION + +OUI:08000C* + ID_OUI_FROM_DATABASE=MIKLYN DEVELOPMENT CO. + +OUI:08000D* + ID_OUI_FROM_DATABASE=INTERNATIONAL COMPUTERS LTD. + +OUI:08000E* + ID_OUI_FROM_DATABASE=NCR CORPORATION + +OUI:08000F* + ID_OUI_FROM_DATABASE=MITEL CORPORATION + +OUI:080011* + ID_OUI_FROM_DATABASE=TEKTRONIX INC. + +OUI:080012* + ID_OUI_FROM_DATABASE=BELL ATLANTIC INTEGRATED SYST. + +OUI:080013* + ID_OUI_FROM_DATABASE=EXXON + +OUI:080014* + ID_OUI_FROM_DATABASE=EXCELAN + +OUI:080015* + ID_OUI_FROM_DATABASE=STC BUSINESS SYSTEMS + +OUI:080016* + ID_OUI_FROM_DATABASE=BARRISTER INFO SYS CORP + +OUI:080017* + ID_OUI_FROM_DATABASE=NATIONAL SEMICONDUCTOR + +OUI:080018* + ID_OUI_FROM_DATABASE=PIRELLI FOCOM NETWORKS + +OUI:080019* + ID_OUI_FROM_DATABASE=GENERAL ELECTRIC CORPORATION + +OUI:08001A* + ID_OUI_FROM_DATABASE=TIARA/ 10NET + +OUI:08001B* + ID_OUI_FROM_DATABASE=EMC Corporation + +OUI:08001C* + ID_OUI_FROM_DATABASE=KDD-KOKUSAI DEBNSIN DENWA CO. + +OUI:08001D* + ID_OUI_FROM_DATABASE=ABLE COMMUNICATIONS INC. + +OUI:08001E* + ID_OUI_FROM_DATABASE=APOLLO COMPUTER INC. + +OUI:08001F* + ID_OUI_FROM_DATABASE=SHARP CORPORATION + +OUI:080020* + ID_OUI_FROM_DATABASE=Oracle Corporation + +OUI:080021* + ID_OUI_FROM_DATABASE=3M COMPANY + +OUI:080022* + ID_OUI_FROM_DATABASE=NBI INC. + +OUI:080023* + ID_OUI_FROM_DATABASE=Panasonic Communications Co., Ltd. + +OUI:080024* + ID_OUI_FROM_DATABASE=10NET COMMUNICATIONS/DCA + +OUI:080025* + ID_OUI_FROM_DATABASE=CONTROL DATA + +OUI:080026* + ID_OUI_FROM_DATABASE=NORSK DATA A.S. + +OUI:080027* + ID_OUI_FROM_DATABASE=CADMUS COMPUTER SYSTEMS + +OUI:080028* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:080029* + ID_OUI_FROM_DATABASE=MEGATEK CORPORATION + +OUI:08002A* + ID_OUI_FROM_DATABASE=MOSAIC TECHNOLOGIES INC. + +OUI:08002B* + ID_OUI_FROM_DATABASE=DIGITAL EQUIPMENT CORPORATION + +OUI:08002C* + ID_OUI_FROM_DATABASE=BRITTON LEE INC. + +OUI:08002D* + ID_OUI_FROM_DATABASE=LAN-TEC INC. + +OUI:08002E* + ID_OUI_FROM_DATABASE=METAPHOR COMPUTER SYSTEMS + +OUI:08002F* + ID_OUI_FROM_DATABASE=PRIME COMPUTER INC. + +OUI:080030* + ID_OUI_FROM_DATABASE=NETWORK RESEARCH CORPORATION + +OUI:080030* + ID_OUI_FROM_DATABASE=CERN + +OUI:080030* + ID_OUI_FROM_DATABASE=ROYAL MELBOURNE INST OF TECH + +OUI:080031* + ID_OUI_FROM_DATABASE=LITTLE MACHINES INC. + +OUI:080032* + ID_OUI_FROM_DATABASE=TIGAN INCORPORATED + +OUI:080033* + ID_OUI_FROM_DATABASE=BAUSCH & LOMB + +OUI:080034* + ID_OUI_FROM_DATABASE=FILENET CORPORATION + +OUI:080035* + ID_OUI_FROM_DATABASE=MICROFIVE CORPORATION + +OUI:080036* + ID_OUI_FROM_DATABASE=INTERGRAPH CORPORATION + +OUI:080037* + ID_OUI_FROM_DATABASE=FUJI-XEROX CO. LTD. + +OUI:080038* + ID_OUI_FROM_DATABASE=BULL S.A.S. + +OUI:080039* + ID_OUI_FROM_DATABASE=SPIDER SYSTEMS LIMITED + +OUI:08003A* + ID_OUI_FROM_DATABASE=ORCATECH INC. + +OUI:08003B* + ID_OUI_FROM_DATABASE=TORUS SYSTEMS LIMITED + +OUI:08003C* + ID_OUI_FROM_DATABASE=SCHLUMBERGER WELL SERVICES + +OUI:08003D* + ID_OUI_FROM_DATABASE=CADNETIX CORPORATIONS + +OUI:08003E* + ID_OUI_FROM_DATABASE=CODEX CORPORATION + +OUI:08003F* + ID_OUI_FROM_DATABASE=FRED KOSCHARA ENTERPRISES + +OUI:080040* + ID_OUI_FROM_DATABASE=FERRANTI COMPUTER SYS. LIMITED + +OUI:080041* + ID_OUI_FROM_DATABASE=RACAL-MILGO INFORMATION SYS.. + +OUI:080042* + ID_OUI_FROM_DATABASE=JAPAN MACNICS CORP. + +OUI:080043* + ID_OUI_FROM_DATABASE=PIXEL COMPUTER INC. + +OUI:080044* + ID_OUI_FROM_DATABASE=DAVID SYSTEMS INC. + +OUI:080045* + ID_OUI_FROM_DATABASE=CONCURRENT COMPUTER CORP. + +OUI:080046* + ID_OUI_FROM_DATABASE=Sony Corporation + +OUI:080047* + ID_OUI_FROM_DATABASE=SEQUENT COMPUTER SYSTEMS INC. + +OUI:080048* + ID_OUI_FROM_DATABASE=EUROTHERM GAUGING SYSTEMS + +OUI:080049* + ID_OUI_FROM_DATABASE=UNIVATION + +OUI:08004A* + ID_OUI_FROM_DATABASE=BANYAN SYSTEMS INC. + +OUI:08004B* + ID_OUI_FROM_DATABASE=PLANNING RESEARCH CORP. + +OUI:08004C* + ID_OUI_FROM_DATABASE=HYDRA COMPUTER SYSTEMS INC. + +OUI:08004D* + ID_OUI_FROM_DATABASE=CORVUS SYSTEMS INC. + +OUI:08004E* + ID_OUI_FROM_DATABASE=3COM EUROPE LTD. + +OUI:08004F* + ID_OUI_FROM_DATABASE=CYGNET SYSTEMS + +OUI:080050* + ID_OUI_FROM_DATABASE=DAISY SYSTEMS CORP. + +OUI:080051* + ID_OUI_FROM_DATABASE=EXPERDATA + +OUI:080052* + ID_OUI_FROM_DATABASE=INSYSTEC + +OUI:080053* + ID_OUI_FROM_DATABASE=MIDDLE EAST TECH. UNIVERSITY + +OUI:080055* + ID_OUI_FROM_DATABASE=STANFORD TELECOMM. INC. + +OUI:080056* + ID_OUI_FROM_DATABASE=STANFORD LINEAR ACCEL. CENTER + +OUI:080057* + ID_OUI_FROM_DATABASE=EVANS & SUTHERLAND + +OUI:080058* + ID_OUI_FROM_DATABASE=SYSTEMS CONCEPTS + +OUI:080059* + ID_OUI_FROM_DATABASE=A/S MYCRON + +OUI:08005A* + ID_OUI_FROM_DATABASE=IBM Corp + +OUI:08005B* + ID_OUI_FROM_DATABASE=VTA TECHNOLOGIES INC. + +OUI:08005C* + ID_OUI_FROM_DATABASE=FOUR PHASE SYSTEMS + +OUI:08005D* + ID_OUI_FROM_DATABASE=GOULD INC. + +OUI:08005E* + ID_OUI_FROM_DATABASE=COUNTERPOINT COMPUTER INC. + +OUI:08005F* + ID_OUI_FROM_DATABASE=SABER TECHNOLOGY CORP. + +OUI:080060* + ID_OUI_FROM_DATABASE=INDUSTRIAL NETWORKING INC. + +OUI:080061* + ID_OUI_FROM_DATABASE=JAROGATE LTD. + +OUI:080062* + ID_OUI_FROM_DATABASE=GENERAL DYNAMICS + +OUI:080063* + ID_OUI_FROM_DATABASE=PLESSEY + +OUI:080064* + ID_OUI_FROM_DATABASE=Sitasys AG + +OUI:080065* + ID_OUI_FROM_DATABASE=GENRAD INC. + +OUI:080066* + ID_OUI_FROM_DATABASE=AGFA CORPORATION + +OUI:080067* + ID_OUI_FROM_DATABASE=COMDESIGN + +OUI:080068* + ID_OUI_FROM_DATABASE=RIDGE COMPUTERS + +OUI:080069* + ID_OUI_FROM_DATABASE=SILICON GRAPHICS INC. + +OUI:08006A* + ID_OUI_FROM_DATABASE=ATT BELL LABORATORIES + +OUI:08006B* + ID_OUI_FROM_DATABASE=ACCEL TECHNOLOGIES INC. + +OUI:08006C* + ID_OUI_FROM_DATABASE=SUNTEK TECHNOLOGY INT'L + +OUI:08006D* + ID_OUI_FROM_DATABASE=WHITECHAPEL COMPUTER WORKS + +OUI:08006E* + ID_OUI_FROM_DATABASE=MASSCOMP + +OUI:08006F* + ID_OUI_FROM_DATABASE=PHILIPS APELDOORN B.V. + +OUI:080070* + ID_OUI_FROM_DATABASE=MITSUBISHI ELECTRIC CORP. + +OUI:080071* + ID_OUI_FROM_DATABASE=MATRA (DSIE) + +OUI:080072* + ID_OUI_FROM_DATABASE=XEROX CORP UNIV GRANT PROGRAM + +OUI:080073* + ID_OUI_FROM_DATABASE=TECMAR INC. + +OUI:080074* + ID_OUI_FROM_DATABASE=CASIO COMPUTER CO. LTD. + +OUI:080075* + ID_OUI_FROM_DATABASE=DANSK DATA ELECTRONIK + +OUI:080076* + ID_OUI_FROM_DATABASE=PC LAN TECHNOLOGIES + +OUI:080077* + ID_OUI_FROM_DATABASE=TSL COMMUNICATIONS LTD. + +OUI:080078* + ID_OUI_FROM_DATABASE=ACCELL CORPORATION + +OUI:080079* + ID_OUI_FROM_DATABASE=THE DROID WORKS + +OUI:08007A* + ID_OUI_FROM_DATABASE=INDATA + +OUI:08007B* + ID_OUI_FROM_DATABASE=SANYO ELECTRIC CO. LTD. + +OUI:08007C* + ID_OUI_FROM_DATABASE=VITALINK COMMUNICATIONS CORP. + +OUI:08007E* + ID_OUI_FROM_DATABASE=AMALGAMATED WIRELESS(AUS) LTD + +OUI:08007F* + ID_OUI_FROM_DATABASE=CARNEGIE-MELLON UNIVERSITY + +OUI:080080* + ID_OUI_FROM_DATABASE=AES DATA INC. + +OUI:080081* + ID_OUI_FROM_DATABASE=,ASTECH INC. + +OUI:080082* + ID_OUI_FROM_DATABASE=VERITAS SOFTWARE + +OUI:080083* + ID_OUI_FROM_DATABASE=Seiko Instruments Inc. + +OUI:080084* + ID_OUI_FROM_DATABASE=TOMEN ELECTRONICS CORP. + +OUI:080085* + ID_OUI_FROM_DATABASE=ELXSI + +OUI:080086* + ID_OUI_FROM_DATABASE=KONICA MINOLTA HOLDINGS, INC. + +OUI:080087* + ID_OUI_FROM_DATABASE=XYPLEX + +OUI:080088* + ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc. + +OUI:080089* + ID_OUI_FROM_DATABASE=KINETICS + +OUI:08008A* + ID_OUI_FROM_DATABASE=PerfTech, Inc. + +OUI:08008B* + ID_OUI_FROM_DATABASE=PYRAMID TECHNOLOGY CORP. + +OUI:08008C* + ID_OUI_FROM_DATABASE=NETWORK RESEARCH CORPORATION + +OUI:08008D* + ID_OUI_FROM_DATABASE=XYVISION INC. + +OUI:08008E* + ID_OUI_FROM_DATABASE=TANDEM COMPUTERS + +OUI:08008F* + ID_OUI_FROM_DATABASE=CHIPCOM CORPORATION + +OUI:080090* + ID_OUI_FROM_DATABASE=SONOMA SYSTEMS + +OUI:0808C2* + ID_OUI_FROM_DATABASE=Samsung Electronics + +OUI:0808EA* + ID_OUI_FROM_DATABASE=AMSC + +OUI:080C0B* + ID_OUI_FROM_DATABASE=SysMik GmbH Dresden + +OUI:080CC9* + ID_OUI_FROM_DATABASE=Mission Technology Group, dba Magma + +OUI:080D84* + ID_OUI_FROM_DATABASE=GECO, Inc. + +OUI:080FFA* + ID_OUI_FROM_DATABASE=KSP INC. + +OUI:081196* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:081443* + ID_OUI_FROM_DATABASE=UNIBRAIN S.A. + +OUI:081651* + ID_OUI_FROM_DATABASE=Shenzhen Sea Star Technology Co.,Ltd + +OUI:081735* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0817F4* + ID_OUI_FROM_DATABASE=IBM Corp + +OUI:08181A* + ID_OUI_FROM_DATABASE=zte corporation + +OUI:08184C* + ID_OUI_FROM_DATABASE=A. S. Thomas, Inc. + +OUI:0819A6* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +OUI:081DFB* + ID_OUI_FROM_DATABASE=Shanghai Mexon Communication Technology Co.,Ltd + +OUI:081F3F* + ID_OUI_FROM_DATABASE=WondaLink Inc. + +OUI:081FF3* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:082522* + ID_OUI_FROM_DATABASE=ADVANSEE + +OUI:082AD0* + ID_OUI_FROM_DATABASE=SRD Innovations Inc. + +OUI:082E5F* + ID_OUI_FROM_DATABASE=Hewlett Packard + +OUI:08373D* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:08379C* + ID_OUI_FROM_DATABASE=Topaz Co. LTD. + +OUI:0838A5* + ID_OUI_FROM_DATABASE=Funkwerk plettac electronic GmbH + +OUI:083AB8* + ID_OUI_FROM_DATABASE=Shinoda Plasma Co., Ltd. + +OUI:083E8E* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind.Co.Ltd + +OUI:084E1C* + ID_OUI_FROM_DATABASE=H2A Systems, LLC + +OUI:084EBF* + ID_OUI_FROM_DATABASE=Broad Net Mux Corporation + +OUI:08512E* + ID_OUI_FROM_DATABASE=Orion Diagnostica Oy + +OUI:085B0E* + ID_OUI_FROM_DATABASE=Fortinet, Inc. + +OUI:08606E* + ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. + +OUI:0868D0* + ID_OUI_FROM_DATABASE=Japan System Design + +OUI:0868EA* + ID_OUI_FROM_DATABASE=EITO ELECTRONICS CO., LTD. + +OUI:087572* + ID_OUI_FROM_DATABASE=Obelux Oy + +OUI:087618* + ID_OUI_FROM_DATABASE=ViE Technologies Sdn. Bhd. + +OUI:087695* + ID_OUI_FROM_DATABASE=Auto Industrial Co., Ltd. + +OUI:0876FF* + ID_OUI_FROM_DATABASE=Thomson Telecom Belgium + +OUI:087999* + ID_OUI_FROM_DATABASE=AIM GmbH + +OUI:087BAA* + ID_OUI_FROM_DATABASE=SVYAZKOMPLEKTSERVICE, LLC + +OUI:087CBE* + ID_OUI_FROM_DATABASE=Quintic Corp. + +OUI:087D21* + ID_OUI_FROM_DATABASE=Altasec technology corporation + +OUI:0881F4* + ID_OUI_FROM_DATABASE=Juniper Networks + +OUI:08863B* + ID_OUI_FROM_DATABASE=Belkin International, Inc. + +OUI:088DC8* + ID_OUI_FROM_DATABASE=Ryowa Electronics Co.,Ltd + +OUI:088F2C* + ID_OUI_FROM_DATABASE=Hills Sound Vision & Lighting + +OUI:089E01* + ID_OUI_FROM_DATABASE=QUANTA COMPUTER INC. + +OUI:089F97* + ID_OUI_FROM_DATABASE=LEROY AUTOMATION + +OUI:08A12B* + ID_OUI_FROM_DATABASE=ShenZhen EZL Technology Co., Ltd + +OUI:08A95A* + ID_OUI_FROM_DATABASE=Azurewave + +OUI:08ACA5* + ID_OUI_FROM_DATABASE=Benu Video, Inc. + +OUI:08AF78* + ID_OUI_FROM_DATABASE=Totus Solutions, Inc. + +OUI:08B4CF* + ID_OUI_FROM_DATABASE=Abicom International + +OUI:08B738* + ID_OUI_FROM_DATABASE=Lite-On Technogy Corp. + +OUI:08B7EC* + ID_OUI_FROM_DATABASE=Wireless Seismic + +OUI:08BBCC* + ID_OUI_FROM_DATABASE=AK-NORD EDV VERTRIEBSGES. mbH + +OUI:08BE09* + ID_OUI_FROM_DATABASE=Astrol Electronic AG + +OUI:08D09F* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:08D29A* + ID_OUI_FROM_DATABASE=Proformatique + +OUI:08D40C* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:08D42B* + ID_OUI_FROM_DATABASE=Samsung Electronics + +OUI:08D5C0* + ID_OUI_FROM_DATABASE=Seers Technology Co., Ltd + +OUI:08E5DA* + ID_OUI_FROM_DATABASE=NANJING FUJITSU COMPUTER PRODUCTS CO.,LTD. + +OUI:08E672* + ID_OUI_FROM_DATABASE=JEBSEE ELECTRONICS CO.,LTD. + +OUI:08EA44* + ID_OUI_FROM_DATABASE=Aerohive Networks, Inc. + +OUI:08EB74* + ID_OUI_FROM_DATABASE=Humax + +OUI:08EBED* + ID_OUI_FROM_DATABASE=World Elite Technology Co.,LTD + +OUI:08EDB9* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + +OUI:08F1B7* + ID_OUI_FROM_DATABASE=Towerstream Corpration + +OUI:08F2F4* + ID_OUI_FROM_DATABASE=Net One Partners Co.,Ltd. + +OUI:08F6F8* + ID_OUI_FROM_DATABASE=GET Engineering + +OUI:08FAE0* + ID_OUI_FROM_DATABASE=Fohhn Audio AG + +OUI:08FC52* + ID_OUI_FROM_DATABASE=OpenXS BV + +OUI:0C130B* + ID_OUI_FROM_DATABASE=Uniqoteq Ltd. + +OUI:0C1420* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:0C15C5* + ID_OUI_FROM_DATABASE=SDTEC Co., Ltd. + +OUI:0C17F1* + ID_OUI_FROM_DATABASE=TELECSYS + +OUI:0C191F* + ID_OUI_FROM_DATABASE=Inform Electronik + +OUI:0C1DC2* + ID_OUI_FROM_DATABASE=SeAH Networks + +OUI:0C2755* + ID_OUI_FROM_DATABASE=Valuable Techologies Limited + +OUI:0C2A69* + ID_OUI_FROM_DATABASE=electric imp, incorporated + +OUI:0C37DC* + ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd + +OUI:0C3956* + ID_OUI_FROM_DATABASE=Observator instruments + +OUI:0C3C65* + ID_OUI_FROM_DATABASE=Dome Imaging Inc + +OUI:0C469D* + ID_OUI_FROM_DATABASE=MS Sedco + +OUI:0C4C39* + ID_OUI_FROM_DATABASE=Mitrastar Technology + +OUI:0C51F7* + ID_OUI_FROM_DATABASE=CHAUVIN ARNOUX + +OUI:0C5521* + ID_OUI_FROM_DATABASE=Axiros GmbH + +OUI:0C565C* + ID_OUI_FROM_DATABASE=HyBroad Vision (Hong Kong) Technology Co Ltd + +OUI:0C57EB* + ID_OUI_FROM_DATABASE=Mueller Systems + +OUI:0C5A19* + ID_OUI_FROM_DATABASE=Axtion Sdn Bhd + +OUI:0C6076* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + +OUI:0C6E4F* + ID_OUI_FROM_DATABASE=PrimeVOLT Co., Ltd. + +OUI:0C715D* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:0C722C* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. + +OUI:0C74C2* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:0C7523* + ID_OUI_FROM_DATABASE=BEIJING GEHUA CATV NETWORK CO.,LTD + +OUI:0C771A* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:0C7D7C* + ID_OUI_FROM_DATABASE=Kexiang Information Technology Co, Ltd. + +OUI:0C8230* + ID_OUI_FROM_DATABASE=SHENZHEN MAGNUS TECHNOLOGIES CO.,LTD + +OUI:0C826A* + ID_OUI_FROM_DATABASE=Wuhan Huagong Genuine Optics Technology Co., Ltd + +OUI:0C8411* + ID_OUI_FROM_DATABASE=A.O. Smith Water Products + +OUI:0C8525* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0C8BFD* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:0C8CDC* + ID_OUI_FROM_DATABASE=Suunto Oy + +OUI:0C8D98* + ID_OUI_FROM_DATABASE=TOP EIGHT IND CORP + +OUI:0C924E* + ID_OUI_FROM_DATABASE=Rice Lake Weighing Systems + +OUI:0C93FB* + ID_OUI_FROM_DATABASE=BNS Solutions + +OUI:0C9D56* + ID_OUI_FROM_DATABASE=Consort Controls Ltd + +OUI:0C9E91* + ID_OUI_FROM_DATABASE=Sankosha Corporation + +OUI:0CA138* + ID_OUI_FROM_DATABASE=Blinq Wireless Inc. + +OUI:0CA2F4* + ID_OUI_FROM_DATABASE=Chameleon Technology (UK) Limited + +OUI:0CA402* + ID_OUI_FROM_DATABASE=Alcatel Lucent IPD + +OUI:0CA42A* + ID_OUI_FROM_DATABASE=OB Telecom Electronic Technology Co., Ltd + +OUI:0CAF5A* + ID_OUI_FROM_DATABASE=GENUS POWER INFRASTRUCTURES LIMITED + +OUI:0CB4EF* + ID_OUI_FROM_DATABASE=Digience Co.,Ltd. + +OUI:0CBF15* + ID_OUI_FROM_DATABASE=Genetec + +OUI:0CC0C0* + ID_OUI_FROM_DATABASE=MAGNETI MARELLI SISTEMAS ELECTRONICOS MEXICO + +OUI:0CC3A7* + ID_OUI_FROM_DATABASE=Meritec + +OUI:0CC47E* + ID_OUI_FROM_DATABASE=EUCAST Co., Ltd. + +OUI:0CC655* + ID_OUI_FROM_DATABASE=Wuxi YSTen Technology Co.,Ltd. + +OUI:0CC66A* + ID_OUI_FROM_DATABASE=Nokia Corporation + +OUI:0CC6AC* + ID_OUI_FROM_DATABASE=DAGS + +OUI:0CC9C6* + ID_OUI_FROM_DATABASE=Samwin Hong Kong Limited + +OUI:0CCDD3* + ID_OUI_FROM_DATABASE=EASTRIVER TECHNOLOGY CO., LTD. + +OUI:0CCDFB* + ID_OUI_FROM_DATABASE=EDIC Systems Inc. + +OUI:0CD292* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:0CD2B5* + ID_OUI_FROM_DATABASE=Binatone Telecommunication Pvt. Ltd + +OUI:0CD502* + ID_OUI_FROM_DATABASE=Westell + +OUI:0CD696* + ID_OUI_FROM_DATABASE=Amimon Ltd + +OUI:0CD7C2* + ID_OUI_FROM_DATABASE=Axium Technologies, Inc. + +OUI:0CD996* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:0CD9C1* + ID_OUI_FROM_DATABASE=Johnson Controls-ASG + +OUI:0CDA41* + ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited + +OUI:0CDCCC* + ID_OUI_FROM_DATABASE=Inala Technologies + +OUI:0CDDEF* + ID_OUI_FROM_DATABASE=Nokia Corporation + +OUI:0CDFA4* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:0CE5D3* + ID_OUI_FROM_DATABASE=DH electronics GmbH + +OUI:0CE709* + ID_OUI_FROM_DATABASE=Fox Crypto B.V. + +OUI:0CE82F* + ID_OUI_FROM_DATABASE=Bonfiglioli Vectron GmbH + +OUI:0CE936* + ID_OUI_FROM_DATABASE=ELIMOS srl + +OUI:0CEEE6* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + +OUI:0CEF7C* + ID_OUI_FROM_DATABASE=AnaCom Inc + +OUI:0CF0B4* + ID_OUI_FROM_DATABASE=Globalsat International Technology Ltd + +OUI:0CF361* + ID_OUI_FROM_DATABASE=Java Information + +OUI:0CF3EE* + ID_OUI_FROM_DATABASE=EM Microelectronic + +OUI:0CF893* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + +OUI:0CFC83* + ID_OUI_FROM_DATABASE=Airoha Technology Corp., + +OUI:10005A* + ID_OUI_FROM_DATABASE=IBM Corp + +OUI:1000E8* + ID_OUI_FROM_DATABASE=NATIONAL SEMICONDUCTOR + +OUI:1000FD* + ID_OUI_FROM_DATABASE=LaonPeople + +OUI:10090C* + ID_OUI_FROM_DATABASE=Janome Sewing Machine Co., Ltd. + +OUI:100BA9* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:100C24* + ID_OUI_FROM_DATABASE=pomdevices, LLC + +OUI:100D2F* + ID_OUI_FROM_DATABASE=Online Security Pty. Ltd. + +OUI:100D32* + ID_OUI_FROM_DATABASE=Embedian, Inc. + +OUI:100D7F* + ID_OUI_FROM_DATABASE=NETGEAR INC., + +OUI:100E2B* + ID_OUI_FROM_DATABASE=NEC CASIO Mobile Communications + +OUI:1010B6* + ID_OUI_FROM_DATABASE=McCain Inc + +OUI:101212* + ID_OUI_FROM_DATABASE=Vivo International Corporation Pty Ltd + +OUI:101248* + ID_OUI_FROM_DATABASE=ITG, Inc. + +OUI:1013EE* + ID_OUI_FROM_DATABASE=Justec International Technology INC. + +OUI:10189E* + ID_OUI_FROM_DATABASE=Elmo Motion Control + +OUI:101B54* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +OUI:101D51* + ID_OUI_FROM_DATABASE=ON-Q LLC dba ON-Q Mesh Networks + +OUI:101DC0* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:101F74* + ID_OUI_FROM_DATABASE=Hewlett-Packard Company + +OUI:102D96* + ID_OUI_FROM_DATABASE=Looxcie Inc. + +OUI:102EAF* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:103711* + ID_OUI_FROM_DATABASE=Simlink AS + +OUI:103DEA* + ID_OUI_FROM_DATABASE=HFC Technology (Beijing) Ltd. Co. + +OUI:1040F3* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:104369* + ID_OUI_FROM_DATABASE=Soundmax Electronic Limited + +OUI:10445A* + ID_OUI_FROM_DATABASE=Shaanxi Hitech Electronic Co., LTD + +OUI:1045BE* + ID_OUI_FROM_DATABASE=Norphonic AS + +OUI:1045F8* + ID_OUI_FROM_DATABASE=LNT-Automation GmbH + +OUI:104780* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +OUI:1048B1* + ID_OUI_FROM_DATABASE=Beijing Duokan Technology Limited + +OUI:104D77* + ID_OUI_FROM_DATABASE=Innovative Computer Engineering + +OUI:1056CA* + ID_OUI_FROM_DATABASE=Peplink International Ltd. + +OUI:105CBF* + ID_OUI_FROM_DATABASE=DuroByte Inc + +OUI:105F06* + ID_OUI_FROM_DATABASE=Actiontec Electronics, Inc + +OUI:105F49* + ID_OUI_FROM_DATABASE=Cisco SPVTG + +OUI:10604B* + ID_OUI_FROM_DATABASE=Hewlett Packard + +OUI:1062C9* + ID_OUI_FROM_DATABASE=Adatis GmbH & Co. KG + +OUI:1064E2* + ID_OUI_FROM_DATABASE=ADFweb.com s.r.l. + +OUI:1065A3* + ID_OUI_FROM_DATABASE=Panamax Inc. + +OUI:1065CF* + ID_OUI_FROM_DATABASE=IQSIM + +OUI:10683F* + ID_OUI_FROM_DATABASE=LG Electronics + +OUI:106F3F* + ID_OUI_FROM_DATABASE=Buffalo Inc. + +OUI:106FEF* + ID_OUI_FROM_DATABASE=Ad-Sol Nissin Corp + +OUI:1071F9* + ID_OUI_FROM_DATABASE=Cloud Telecomputers, LLC + +OUI:10768A* + ID_OUI_FROM_DATABASE=EoCell + +OUI:1078D2* + ID_OUI_FROM_DATABASE=ELITEGROUP COMPUTER SYSTEM CO., LTD. + +OUI:1083D2* + ID_OUI_FROM_DATABASE=Microseven Systems, LLC + +OUI:10880F* + ID_OUI_FROM_DATABASE=Daruma Telecomunicações e Informática S.A. + +OUI:108CCF* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:1093E9* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:109ADD* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:109FA9* + ID_OUI_FROM_DATABASE=Actiontec Electronics, Inc + +OUI:10A13B* + ID_OUI_FROM_DATABASE=FUJIKURA RUBBER LTD. + +OUI:10A743* + ID_OUI_FROM_DATABASE=SK Mtek Limited + +OUI:10A932* + ID_OUI_FROM_DATABASE=Beijing Cyber Cloud Technology Co. ,Ltd. + +OUI:10B7F6* + ID_OUI_FROM_DATABASE=Plastoform Industries Ltd. + +OUI:10B9FE* + ID_OUI_FROM_DATABASE=Lika srl + +OUI:10BAA5* + ID_OUI_FROM_DATABASE=GANA I&C CO., LTD + +OUI:10BD18* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:10BF48* + ID_OUI_FROM_DATABASE=ASUSTEK COMPUTER INC. + +OUI:10C2BA* + ID_OUI_FROM_DATABASE=UTT Co., Ltd. + +OUI:10C586* + ID_OUI_FROM_DATABASE=BIO SOUND LAB CO., LTD. + +OUI:10C61F* + ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd + +OUI:10C6FC* + ID_OUI_FROM_DATABASE=Garmin International + +OUI:10C73F* + ID_OUI_FROM_DATABASE=Midas Klark Teknik Ltd + +OUI:10CA81* + ID_OUI_FROM_DATABASE=PRECIA + +OUI:10CCDB* + ID_OUI_FROM_DATABASE=AXIMUM PRODUITS ELECTRONIQUES + +OUI:10D1DC* + ID_OUI_FROM_DATABASE=INSTAR Deutschland GmbH + +OUI:10DDB1* + ID_OUI_FROM_DATABASE=Apple + +OUI:10E2D5* + ID_OUI_FROM_DATABASE=Qi Hardware Inc. + +OUI:10E3C7* + ID_OUI_FROM_DATABASE=Seohwa Telecom + +OUI:10E4AF* + ID_OUI_FROM_DATABASE=APR, LLC + +OUI:10E6AE* + ID_OUI_FROM_DATABASE=Source Technologies, LLC + +OUI:10E8EE* + ID_OUI_FROM_DATABASE=PhaseSpace + +OUI:10EA59* + ID_OUI_FROM_DATABASE=Cisco SPVTG + +OUI:10EED9* + ID_OUI_FROM_DATABASE=Canoga Perkins Corporation + +OUI:10F3DB* + ID_OUI_FROM_DATABASE=Gridco Systems, Inc. + +OUI:10F49A* + ID_OUI_FROM_DATABASE=T3 Innovation + +OUI:10F96F* + ID_OUI_FROM_DATABASE=LG Electronics + +OUI:10F9EE* + ID_OUI_FROM_DATABASE=Nokia Corporation + +OUI:10FBF0* + ID_OUI_FROM_DATABASE=KangSheng LTD. + +OUI:10FC54* + ID_OUI_FROM_DATABASE=Shany Electronic Co., Ltd. + +OUI:10FEED* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO., LTD. + +OUI:1407E0* + ID_OUI_FROM_DATABASE=Abrantix AG + +OUI:140C76* + ID_OUI_FROM_DATABASE=FREEBOX SAS + +OUI:14109F* + ID_OUI_FROM_DATABASE=Apple Inc + +OUI:14144B* + ID_OUI_FROM_DATABASE=FUJIAN STAR-NET COMMUNICATION CO.,LTD + +OUI:141A51* + ID_OUI_FROM_DATABASE=Treetech Sistemas Digitais + +OUI:141BBD* + ID_OUI_FROM_DATABASE=Volex Inc. + +OUI:141BF0* + ID_OUI_FROM_DATABASE=Intellimedia Systems Ltd + +OUI:142DF5* + ID_OUI_FROM_DATABASE=Amphitech + +OUI:14307A* + ID_OUI_FROM_DATABASE=Avermetrics + +OUI:14358B* + ID_OUI_FROM_DATABASE=Mediabridge Products, LLC. + +OUI:1435B3* + ID_OUI_FROM_DATABASE=Future Designs, Inc. + +OUI:143605* + ID_OUI_FROM_DATABASE=Nokia Corporation + +OUI:14373B* + ID_OUI_FROM_DATABASE=PROCOM Systems + +OUI:143AEA* + ID_OUI_FROM_DATABASE=Dynapower Company LLC + +OUI:143E60* + ID_OUI_FROM_DATABASE=Alcatel-Lucent + +OUI:144319* + ID_OUI_FROM_DATABASE=Creative&Link Technology Limited + +OUI:144978* + ID_OUI_FROM_DATABASE=Digital Control Incorporated + +OUI:144C1A* + ID_OUI_FROM_DATABASE=Max Communication GmbH + +OUI:145412* + ID_OUI_FROM_DATABASE=Entis Co., Ltd. + +OUI:145A05* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:145BD1* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:146308* + ID_OUI_FROM_DATABASE=JABIL CIRCUIT (SHANGHAI) LTD. + +OUI:146A0B* + ID_OUI_FROM_DATABASE=Cypress Electronics Limited + +OUI:147373* + ID_OUI_FROM_DATABASE=TUBITAK UEKAE + +OUI:147411* + ID_OUI_FROM_DATABASE=RIM + +OUI:147DB3* + ID_OUI_FROM_DATABASE=JOA TELECOM.CO.,LTD + +OUI:147DC5* + ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd. + +OUI:14825B* + ID_OUI_FROM_DATABASE=Hefei Radio Communication Technology Co., Ltd + +OUI:1489FD* + ID_OUI_FROM_DATABASE=Samsung Electronics + +OUI:148A70* + ID_OUI_FROM_DATABASE=ADS GmbH + +OUI:148FC6* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:149090* + ID_OUI_FROM_DATABASE=KongTop industrial(shen zhen)CO.,LTD + +OUI:149FE8* + ID_OUI_FROM_DATABASE=Lenovo Mobile Communication Technology Ltd. + +OUI:14A62C* + ID_OUI_FROM_DATABASE=S.M. Dezac S.A. + +OUI:14A86B* + ID_OUI_FROM_DATABASE=ShenZhen Telacom Science&Technology Co., Ltd + +OUI:14A9E3* + ID_OUI_FROM_DATABASE=MST CORPORATION + +OUI:14B1C8* + ID_OUI_FROM_DATABASE=InfiniWing, Inc. + +OUI:14B73D* + ID_OUI_FROM_DATABASE=ARCHEAN Technologies + +OUI:14C21D* + ID_OUI_FROM_DATABASE=Sabtech Industries + +OUI:14CF8D* + ID_OUI_FROM_DATABASE=OHSUNG ELECTRONICS CO., LTD. + +OUI:14CF92* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO., LTD. + +OUI:14D4FE* + ID_OUI_FROM_DATABASE=Pace plc + +OUI:14D64D* + ID_OUI_FROM_DATABASE=D-Link International + +OUI:14D76E* + ID_OUI_FROM_DATABASE=CONCH ELECTRONIC Co.,Ltd + +OUI:14DAE9* + ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. + +OUI:14DB85* + ID_OUI_FROM_DATABASE=S NET MEDIA + +OUI:14E4EC* + ID_OUI_FROM_DATABASE=mLogic LLC + +OUI:14E6E4* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO., LTD. + +OUI:14EB33* + ID_OUI_FROM_DATABASE=BSMediasoft Co., Ltd. + +OUI:14EE9D* + ID_OUI_FROM_DATABASE=AirNav Systems LLC + +OUI:14F0C5* + ID_OUI_FROM_DATABASE=Xtremio Ltd. + +OUI:14F42A* + ID_OUI_FROM_DATABASE=Samsung Electronics + +OUI:14FEAF* + ID_OUI_FROM_DATABASE=SAGITTAR LIMITED + +OUI:14FEB5* + ID_OUI_FROM_DATABASE=Dell Inc + +OUI:18002D* + ID_OUI_FROM_DATABASE=Sony Mobile Communications AB + +OUI:1801E3* + ID_OUI_FROM_DATABASE=Elektrobit Wireless Communications Ltd + +OUI:180373* + ID_OUI_FROM_DATABASE=Dell Inc + +OUI:1803FA* + ID_OUI_FROM_DATABASE=IBT Interfaces + +OUI:180675* + ID_OUI_FROM_DATABASE=DILAX Intelcom GmbH + +OUI:180B52* + ID_OUI_FROM_DATABASE=Nanotron Technologies GmbH + +OUI:180C77* + ID_OUI_FROM_DATABASE=Westinghouse Electric Company, LLC + +OUI:180CAC* + ID_OUI_FROM_DATABASE=CANON INC. + +OUI:181420* + ID_OUI_FROM_DATABASE=TEB SAS + +OUI:181456* + ID_OUI_FROM_DATABASE=Nokia Corporation + +OUI:181714* + ID_OUI_FROM_DATABASE=DAEWOOIS + +OUI:181725* + ID_OUI_FROM_DATABASE=Cameo Communications, Inc. + +OUI:18193F* + ID_OUI_FROM_DATABASE=Tamtron Oy + +OUI:182032* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:182861* + ID_OUI_FROM_DATABASE=AirTies Wireless Networks + +OUI:182A7B* + ID_OUI_FROM_DATABASE=Nintendo Co., Ltd. + +OUI:182B05* + ID_OUI_FROM_DATABASE=8D Technologies + +OUI:182C91* + ID_OUI_FROM_DATABASE=Concept Development, Inc. + +OUI:18339D* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:183451* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:183825* + ID_OUI_FROM_DATABASE=Wuhan Lingjiu High-tech Co.,Ltd. + +OUI:183919* + ID_OUI_FROM_DATABASE=Unicoi Systems + +OUI:183BD2* + ID_OUI_FROM_DATABASE=BYD Precision Manufacture Company Ltd. + +OUI:183DA2* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:183F47* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:18422F* + ID_OUI_FROM_DATABASE=Alcatel Lucent + +OUI:184617* + ID_OUI_FROM_DATABASE=Samsung Electronics + +OUI:1848D8* + ID_OUI_FROM_DATABASE=Fastback Networks + +OUI:184E94* + ID_OUI_FROM_DATABASE=MESSOA TECHNOLOGIES INC. + +OUI:185253* + ID_OUI_FROM_DATABASE=Pixord Corporation + +OUI:1853E0* + ID_OUI_FROM_DATABASE=Hanyang Digitech Co.Ltd + +OUI:18550F* + ID_OUI_FROM_DATABASE=Cisco SPVTG + +OUI:185933* + ID_OUI_FROM_DATABASE=Cisco SPVTG + +OUI:185AE8* + ID_OUI_FROM_DATABASE=Zenotech.Co.,Ltd + +OUI:1866E3* + ID_OUI_FROM_DATABASE=Veros Systems, Inc. + +OUI:18673F* + ID_OUI_FROM_DATABASE=Hanover Displays Limited + +OUI:186751* + ID_OUI_FROM_DATABASE=KOMEG Industrielle Messtechnik GmbH + +OUI:1867B0* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,LTD + +OUI:186D99* + ID_OUI_FROM_DATABASE=Adanis Inc. + +OUI:187A93* + ID_OUI_FROM_DATABASE=AMICCOM Electronics Corporation + +OUI:187C81* + ID_OUI_FROM_DATABASE=Valeo Vision Systems + +OUI:1880CE* + ID_OUI_FROM_DATABASE=Barberry Solutions Ltd + +OUI:1880F5* + ID_OUI_FROM_DATABASE=Alcatel-Lucent Shanghai Bell Co., Ltd + +OUI:18863A* + ID_OUI_FROM_DATABASE=DIGITAL ART SYSTEM + +OUI:1886AC* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:188796* + ID_OUI_FROM_DATABASE=HTC Corporation + +OUI:188ED5* + ID_OUI_FROM_DATABASE=Philips Innovative Application NV + +OUI:18922C* + ID_OUI_FROM_DATABASE=Virtual Instruments + +OUI:1897FF* + ID_OUI_FROM_DATABASE=TechFaith Wireless Technology Limited + +OUI:189A67* + ID_OUI_FROM_DATABASE=CSE-Servelec Limited + +OUI:189EFC* + ID_OUI_FROM_DATABASE=Apple Inc + +OUI:18A905* + ID_OUI_FROM_DATABASE=Hewlett-Packard Company + +OUI:18ABF5* + ID_OUI_FROM_DATABASE=Ultra Electronics - Electrics + +OUI:18AD4D* + ID_OUI_FROM_DATABASE=Polostar Technology Corporation + +OUI:18AEBB* + ID_OUI_FROM_DATABASE=Siemens Programm- und Systementwicklung GmbH&Co.KG + +OUI:18AF9F* + ID_OUI_FROM_DATABASE=DIGITRONIC Automationsanlagen GmbH + +OUI:18B209* + ID_OUI_FROM_DATABASE=Torrey Pines Logic, Inc + +OUI:18B3BA* + ID_OUI_FROM_DATABASE=Netlogic AB + +OUI:18B430* + ID_OUI_FROM_DATABASE=Nest Labs Inc. + +OUI:18B591* + ID_OUI_FROM_DATABASE=I-Storm + +OUI:18B79E* + ID_OUI_FROM_DATABASE=Invoxia + +OUI:18C086* + ID_OUI_FROM_DATABASE=Broadcom Corporation + +OUI:18C451* + ID_OUI_FROM_DATABASE=Tucson Embedded Systems + +OUI:18D071* + ID_OUI_FROM_DATABASE=DASAN SMC, Inc. + +OUI:18D66A* + ID_OUI_FROM_DATABASE=Inmarsat + +OUI:18D949* + ID_OUI_FROM_DATABASE=Qvis Labs, LLC + +OUI:18DC56* + ID_OUI_FROM_DATABASE=Yulong Computer Telecommunication Scientific(shenzhen)Co.,Lt + +OUI:18E288* + ID_OUI_FROM_DATABASE=STT Condigi + +OUI:18E2C2* + ID_OUI_FROM_DATABASE=Samsung Electronics + +OUI:18E7F4* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:18E80F* + ID_OUI_FROM_DATABASE=Viking Electronics Inc. + +OUI:18EF63* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:18F46A* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + +OUI:18F650* + ID_OUI_FROM_DATABASE=Multimedia Pacific Limited + +OUI:18F87A* + ID_OUI_FROM_DATABASE=i3 International Inc. + +OUI:18FC9F* + ID_OUI_FROM_DATABASE=Changhe Electronics Co., Ltd. + +OUI:1C0656* + ID_OUI_FROM_DATABASE=IDY Corporation + +OUI:1C0B52* + ID_OUI_FROM_DATABASE=EPICOM S.A + +OUI:1C0FCF* + ID_OUI_FROM_DATABASE=Sypro Optics GmbH + +OUI:1C11E1* + ID_OUI_FROM_DATABASE=Wartsila Finland Oy + +OUI:1C129D* + ID_OUI_FROM_DATABASE=IEEE PES PSRC/SUB + +OUI:1C1448* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:1C17D3* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:1C184A* + ID_OUI_FROM_DATABASE=ShenZhen RicherLink Technologies Co.,LTD + +OUI:1C19DE* + ID_OUI_FROM_DATABASE=eyevis GmbH + +OUI:1C1D67* + ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd + +OUI:1C334D* + ID_OUI_FROM_DATABASE=ITS Telecom + +OUI:1C3477* + ID_OUI_FROM_DATABASE=Innovation Wireless + +OUI:1C35F1* + ID_OUI_FROM_DATABASE=NEW Lift Neue Elektronische Wege Steuerungsbau GmbH + +OUI:1C3A4F* + ID_OUI_FROM_DATABASE=AccuSpec Electronics, LLC + +OUI:1C3DE7* + ID_OUI_FROM_DATABASE=Sigma Koki Co.,Ltd. + +OUI:1C43EC* + ID_OUI_FROM_DATABASE=JAPAN CIRCUIT CO.,LTD + +OUI:1C4593* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:1C4BD6* + ID_OUI_FROM_DATABASE=AzureWave + +OUI:1C51B5* + ID_OUI_FROM_DATABASE=Techaya LTD + +OUI:1C52D6* + ID_OUI_FROM_DATABASE=FLAT DISPLAY TECHNOLOGY CORPORATION + +OUI:1C5A3E* + ID_OUI_FROM_DATABASE=Samsung Eletronics Co., Ltd (Visual Display Divison) + +OUI:1C5A6B* + ID_OUI_FROM_DATABASE=Philips Electronics Nederland BV + +OUI:1C5C55* + ID_OUI_FROM_DATABASE=PRIMA Cinema, Inc + +OUI:1C5C60* + ID_OUI_FROM_DATABASE=Shenzhen Belzon Technology Co.,LTD. + +OUI:1C5FFF* + ID_OUI_FROM_DATABASE=Beijing Ereneben Information Technology Co.,Ltd Shenzhen Branch + +OUI:1C62B8* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:1C659D* + ID_OUI_FROM_DATABASE=Liteon Technology Corporation + +OUI:1C666D* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind.Co.Ltd + +OUI:1C66AA* + ID_OUI_FROM_DATABASE=Samsung Electronics + +OUI:1C69A5* + ID_OUI_FROM_DATABASE=Research In Motion + +OUI:1C6BCA* + ID_OUI_FROM_DATABASE=Mitsunami Co., Ltd. + +OUI:1C6F65* + ID_OUI_FROM_DATABASE=GIGA-BYTE TECHNOLOGY CO.,LTD. + +OUI:1C7508* + ID_OUI_FROM_DATABASE=COMPAL INFORMATION (KUNSHAN) CO., LTD. + +OUI:1C7C11* + ID_OUI_FROM_DATABASE=EID + +OUI:1C7C45* + ID_OUI_FROM_DATABASE=Vitek Industrial Video Products, Inc. + +OUI:1C7EE5* + ID_OUI_FROM_DATABASE=D-Link International + +OUI:1C83B0* + ID_OUI_FROM_DATABASE=Linked IP GmbH + +OUI:1C8464* + ID_OUI_FROM_DATABASE=FORMOSA WIRELESS COMMUNICATION CORP. + +OUI:1C8E8E* + ID_OUI_FROM_DATABASE=DB Communication & Systems Co., ltd. + +OUI:1C8F8A* + ID_OUI_FROM_DATABASE=Phase Motion Control SpA + +OUI:1C9179* + ID_OUI_FROM_DATABASE=Integrated System Technologies Ltd + +OUI:1C9492* + ID_OUI_FROM_DATABASE=RUAG Schweiz AG + +OUI:1C955D* + ID_OUI_FROM_DATABASE=I-LAX ELECTRONICS INC. + +OUI:1C959F* + ID_OUI_FROM_DATABASE=Veethree Electronics And Marine LLC + +OUI:1C973D* + ID_OUI_FROM_DATABASE=PRICOM Design + +OUI:1CAA07* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:1CABA7* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:1CAFF7* + ID_OUI_FROM_DATABASE=D-LINK INTERNATIONAL PTE LIMITED + +OUI:1CB094* + ID_OUI_FROM_DATABASE=HTC Corporation + +OUI:1CB17F* + ID_OUI_FROM_DATABASE=NEC AccessTechnica, Ltd. + +OUI:1CB243* + ID_OUI_FROM_DATABASE=TDC A/S + +OUI:1CBBA8* + ID_OUI_FROM_DATABASE=OJSC "Ufimskiy Zavod "Promsvyaz" + +OUI:1CBD0E* + ID_OUI_FROM_DATABASE=Amplified Engineering Pty Ltd + +OUI:1CBDB9* + ID_OUI_FROM_DATABASE=D-LINK INTERNATIONAL PTE LIMITED + +OUI:1CC1DE* + ID_OUI_FROM_DATABASE=Hewlett-Packard Company + +OUI:1CC316* + ID_OUI_FROM_DATABASE=MileSight Technology Co., Ltd. + +OUI:1CC63C* + ID_OUI_FROM_DATABASE=Arcadyan Technology Corporation + +OUI:1CD40C* + ID_OUI_FROM_DATABASE=Kriwan Industrie-Elektronik GmbH + +OUI:1CDF0F* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:1CE165* + ID_OUI_FROM_DATABASE=Marshal Corporation + +OUI:1CE192* + ID_OUI_FROM_DATABASE=Qisda Corporation + +OUI:1CE2CC* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:1CE6C7* + ID_OUI_FROM_DATABASE=Cisco + +OUI:1CF061* + ID_OUI_FROM_DATABASE=SCAPS GmbH + +OUI:1CF5E7* + ID_OUI_FROM_DATABASE=Turtle Industry Co., Ltd. + +OUI:1CFEA7* + ID_OUI_FROM_DATABASE=IDentytech Solutins Ltd. + +OUI:20014F* + ID_OUI_FROM_DATABASE=Linea Research Ltd + +OUI:2002AF* + ID_OUI_FROM_DATABASE=Murata Manufactuaring Co.,Ltd. + +OUI:200505* + ID_OUI_FROM_DATABASE=RADMAX COMMUNICATION PRIVATE LIMITED + +OUI:2005E8* + ID_OUI_FROM_DATABASE=OOO "InProMedia" + +OUI:200A5E* + ID_OUI_FROM_DATABASE=Xiangshan Giant Eagle Technology Developing co.,LTD + +OUI:20107A* + ID_OUI_FROM_DATABASE=Gemtek Technology Co., Ltd. + +OUI:201257* + ID_OUI_FROM_DATABASE=Most Lucky Trading Ltd + +OUI:2013E0* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:2016D8* + ID_OUI_FROM_DATABASE=Liteon Technology Corporation + +OUI:201A06* + ID_OUI_FROM_DATABASE=COMPAL INFORMATION (KUNSHAN) CO., LTD. + +OUI:2021A5* + ID_OUI_FROM_DATABASE=LG Electronics Inc + +OUI:202598* + ID_OUI_FROM_DATABASE=Teleview + +OUI:202BC1* + ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd + +OUI:202CB7* + ID_OUI_FROM_DATABASE=Kong Yue Electronics & Information Industry (Xinhui) Ltd. + +OUI:203706* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:2037BC* + ID_OUI_FROM_DATABASE=Kuipers Electronic Engineering BV + +OUI:203A07* + ID_OUI_FROM_DATABASE=Cisco + +OUI:204005* + ID_OUI_FROM_DATABASE=feno GmbH + +OUI:20415A* + ID_OUI_FROM_DATABASE=Smarteh d.o.o. + +OUI:20443A* + ID_OUI_FROM_DATABASE=Schneider Electric Asia Pacific Ltd + +OUI:2046A1* + ID_OUI_FROM_DATABASE=VECOW Co., Ltd + +OUI:2046F9* + ID_OUI_FROM_DATABASE=Advanced Network Devices (dba:AND) + +OUI:204AAA* + ID_OUI_FROM_DATABASE=Hanscan Spain S.A. + +OUI:204E6B* + ID_OUI_FROM_DATABASE=Axxana(israel) ltd + +OUI:204E7F* + ID_OUI_FROM_DATABASE=NETGEAR + +OUI:205476* + ID_OUI_FROM_DATABASE=Sony Mobile Communications AB + +OUI:2059A0* + ID_OUI_FROM_DATABASE=Paragon Technologies Inc. + +OUI:205B5E* + ID_OUI_FROM_DATABASE=Shenzhen Wonhe Technology Co., Ltd + +OUI:206432* + ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO MECHANICS CO.,LTD. + +OUI:2067B1* + ID_OUI_FROM_DATABASE=Pluto inc. + +OUI:20689D* + ID_OUI_FROM_DATABASE=Liteon Technology Corporation + +OUI:206A8A* + ID_OUI_FROM_DATABASE=Wistron InfoComm Manufacturing(Kunshan)Co.,Ltd. + +OUI:206AFF* + ID_OUI_FROM_DATABASE=Atlas Elektronik UK Limited + +OUI:206FEC* + ID_OUI_FROM_DATABASE=Braemac CA LLC + +OUI:207355* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + +OUI:2074CF* + ID_OUI_FROM_DATABASE=Shenzhen Voxtech Co.,Ltd + +OUI:207600* + ID_OUI_FROM_DATABASE=Actiontec Electronics, Inc + +OUI:207C8F* + ID_OUI_FROM_DATABASE=Quanta Microsystems,Inc. + +OUI:207D74* + ID_OUI_FROM_DATABASE=Apple + +OUI:20858C* + ID_OUI_FROM_DATABASE=Assa + +OUI:208984* + ID_OUI_FROM_DATABASE=COMPAL INFORMATION (KUNSHAN) CO., LTD + +OUI:20918A* + ID_OUI_FROM_DATABASE=PROFALUX + +OUI:2091D9* + ID_OUI_FROM_DATABASE=I'M SPA + +OUI:209BA5* + ID_OUI_FROM_DATABASE=JIAXING GLEAD Electronics Co.,Ltd + +OUI:20A2E7* + ID_OUI_FROM_DATABASE=Lee-Dickens Ltd + +OUI:20AA25* + ID_OUI_FROM_DATABASE=IP-NET LLC + +OUI:20AA4B* + ID_OUI_FROM_DATABASE=Cisco-Linksys, LLC + +OUI:20B0F7* + ID_OUI_FROM_DATABASE=Enclustra GmbH + +OUI:20B399* + ID_OUI_FROM_DATABASE=Enterasys + +OUI:20B5C6* + ID_OUI_FROM_DATABASE=Mimosa Networks + +OUI:20B7C0* + ID_OUI_FROM_DATABASE=Omicron electronics GmbH + +OUI:20BBC0* + ID_OUI_FROM_DATABASE=Cisco + +OUI:20BBC6* + ID_OUI_FROM_DATABASE=Jabil Circuit Hungary Ltd. + +OUI:20BFDB* + ID_OUI_FROM_DATABASE=DVL + +OUI:20C1AF* + ID_OUI_FROM_DATABASE=i Wit Digital Co., Limited + +OUI:20C8B3* + ID_OUI_FROM_DATABASE=SHENZHEN BUL-TECH CO.,LTD. + +OUI:20C9D0* + ID_OUI_FROM_DATABASE=Apple Inc + +OUI:20CF30* + ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. + +OUI:20D5AB* + ID_OUI_FROM_DATABASE=Korea Infocom Co.,Ltd. + +OUI:20D5BF* + ID_OUI_FROM_DATABASE=Samsung Eletronics Co., Ltd + +OUI:20D607* + ID_OUI_FROM_DATABASE=Nokia Corporation + +OUI:20D906* + ID_OUI_FROM_DATABASE=Iota, Inc. + +OUI:20DC93* + ID_OUI_FROM_DATABASE=Cheetah Hi-Tech, Inc. + +OUI:20DCE6* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO., LTD. + +OUI:20E52A* + ID_OUI_FROM_DATABASE=NETGEAR INC., + +OUI:20E564* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:20EEC6* + ID_OUI_FROM_DATABASE=Elefirst Science & Tech Co ., ltd + +OUI:20F002* + ID_OUI_FROM_DATABASE=MTData Developments Pty. Ltd. + +OUI:20F3A3* + ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd + +OUI:20F85E* + ID_OUI_FROM_DATABASE=Delta Electronics + +OUI:20FABB* + ID_OUI_FROM_DATABASE=Cambridge Executive Limited + +OUI:20FDF1* + ID_OUI_FROM_DATABASE=3COM EUROPE LTD + +OUI:20FECD* + ID_OUI_FROM_DATABASE=System In Frontier Inc. + +OUI:20FEDB* + ID_OUI_FROM_DATABASE=M2M Solution S.A.S. + +OUI:2401C7* + ID_OUI_FROM_DATABASE=Cisco + +OUI:240917* + ID_OUI_FROM_DATABASE=Devlin Electronics Limited + +OUI:240B2A* + ID_OUI_FROM_DATABASE=Viettel Group + +OUI:240BB1* + ID_OUI_FROM_DATABASE=KOSTAL Industrie Elektrik GmbH + +OUI:241064* + ID_OUI_FROM_DATABASE=Shenzhen Ecsino Tecnical Co. Ltd + +OUI:241125* + ID_OUI_FROM_DATABASE=Hutek Co., Ltd. + +OUI:2411D0* + ID_OUI_FROM_DATABASE=Chongqing Ehs Science and Technology Development Co.,Ltd. + +OUI:241A8C* + ID_OUI_FROM_DATABASE=Squarehead Technology AS + +OUI:241B13* + ID_OUI_FROM_DATABASE=Shanghai Nutshell Electronic Co., Ltd. + +OUI:241F2C* + ID_OUI_FROM_DATABASE=Calsys, Inc. + +OUI:2421AB* + ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications + +OUI:242FFA* + ID_OUI_FROM_DATABASE=Toshiba Global Commerce Solutions + +OUI:24374C* + ID_OUI_FROM_DATABASE=Cisco SPVTG + +OUI:2437EF* + ID_OUI_FROM_DATABASE=EMC Electronic Media Communication SA + +OUI:243C20* + ID_OUI_FROM_DATABASE=Dynamode Group + +OUI:244597* + ID_OUI_FROM_DATABASE=GEMUE Gebr. Mueller Apparatebau + +OUI:24470E* + ID_OUI_FROM_DATABASE=PentronicAB + +OUI:24497B* + ID_OUI_FROM_DATABASE=Innovative Converged Devices Inc + +OUI:245FDF* + ID_OUI_FROM_DATABASE=KYOCERA Corporation + +OUI:246511* + ID_OUI_FROM_DATABASE=AVM GmbH + +OUI:24694A* + ID_OUI_FROM_DATABASE=Jasmine Systems Inc. + +OUI:2469A5* + ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd + +OUI:24767D* + ID_OUI_FROM_DATABASE=Cisco SPVTG + +OUI:247703* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:24828A* + ID_OUI_FROM_DATABASE=Prowave Technologies Ltd. + +OUI:2486F4* + ID_OUI_FROM_DATABASE=Ctek, Inc. + +OUI:248707* + ID_OUI_FROM_DATABASE=SEnergy Corporation + +OUI:249442* + ID_OUI_FROM_DATABASE=OPEN ROAD SOLUTIONS , INC. + +OUI:24A42C* + ID_OUI_FROM_DATABASE=KOUKAAM a.s. + +OUI:24A43C* + ID_OUI_FROM_DATABASE=Ubiquiti Networks, INC + +OUI:24A937* + ID_OUI_FROM_DATABASE=PURE Storage + +OUI:24AB81* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:24AF4A* + ID_OUI_FROM_DATABASE=Alcatel-Lucent-IPD + +OUI:24AF54* + ID_OUI_FROM_DATABASE=NEXGEN Mediatech Inc. + +OUI:24B657* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:24B6B8* + ID_OUI_FROM_DATABASE=FRIEM SPA + +OUI:24B6FD* + ID_OUI_FROM_DATABASE=Dell Inc + +OUI:24B88C* + ID_OUI_FROM_DATABASE=Crenus Co.,Ltd. + +OUI:24B8D2* + ID_OUI_FROM_DATABASE=Opzoon Technology Co.,Ltd. + +OUI:24BA30* + ID_OUI_FROM_DATABASE=Technical Consumer Products, Inc. + +OUI:24BBC1* + ID_OUI_FROM_DATABASE=Absolute Analysis + +OUI:24BC82* + ID_OUI_FROM_DATABASE=Dali Wireless, Inc. + +OUI:24BE05* + ID_OUI_FROM_DATABASE=Hewlett Packard + +OUI:24C0B3* + ID_OUI_FROM_DATABASE=RSF + +OUI:24C86E* + ID_OUI_FROM_DATABASE=Chaney Instrument Co. + +OUI:24C9DE* + ID_OUI_FROM_DATABASE=Genoray + +OUI:24CBE7* + ID_OUI_FROM_DATABASE=MYK, Inc. + +OUI:24CF21* + ID_OUI_FROM_DATABASE=Shenzhen State Micro Technology Co., Ltd + +OUI:24D2CC* + ID_OUI_FROM_DATABASE=SmartDrive Systems Inc. + +OUI:24D921* + ID_OUI_FROM_DATABASE=Avaya, Inc + +OUI:24DAB6* + ID_OUI_FROM_DATABASE=Sistemas de Gestión Energética S.A. de C.V + +OUI:24DBAC* + ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd + +OUI:24DBAD* + ID_OUI_FROM_DATABASE=ShopperTrak RCT Corporation + +OUI:24DEC6* + ID_OUI_FROM_DATABASE=Aruba Networks + +OUI:24E6BA* + ID_OUI_FROM_DATABASE=JSC Zavod im. Kozitsky + +OUI:24EC99* + ID_OUI_FROM_DATABASE=Askey Computer Corp + +OUI:24EE3A* + ID_OUI_FROM_DATABASE=Chengdu Yingji Electronic Hi-tech Co Ltd + +OUI:24F0FF* + ID_OUI_FROM_DATABASE=GHT Co., Ltd. + +OUI:24F2DD* + ID_OUI_FROM_DATABASE=Radiant Zemax LLC + +OUI:2804E0* + ID_OUI_FROM_DATABASE=FERMAX ELECTRONICA S.A.U. + +OUI:28061E* + ID_OUI_FROM_DATABASE=NINGBO GLOBAL USEFUL ELECTRIC CO.,LTD + +OUI:28068D* + ID_OUI_FROM_DATABASE=ITL, LLC + +OUI:280CB8* + ID_OUI_FROM_DATABASE=Mikrosay Yazilim ve Elektronik A.S. + +OUI:280DFC* + ID_OUI_FROM_DATABASE=Sony Computer Entertainment Inc. + +OUI:28107B* + ID_OUI_FROM_DATABASE=D-Link International + +OUI:281471* + ID_OUI_FROM_DATABASE=Lantis co., LTD. + +OUI:28162E* + ID_OUI_FROM_DATABASE=2Wire + +OUI:2817CE* + ID_OUI_FROM_DATABASE=Omnisense Ltd + +OUI:2818FD* + ID_OUI_FROM_DATABASE=Aditya Infotech Ltd. + +OUI:2826A6* + ID_OUI_FROM_DATABASE=PBR electronics GmbH + +OUI:2829D9* + ID_OUI_FROM_DATABASE=GlobalBeiMing technology (Beijing)Co. Ltd + +OUI:283410* + ID_OUI_FROM_DATABASE=Enigma Diagnostics Limited + +OUI:283737* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:2838CF* + ID_OUI_FROM_DATABASE=Gen2wave + +OUI:2839E7* + ID_OUI_FROM_DATABASE=Preceno Technology Pte.Ltd. + +OUI:283CE4* + ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd + +OUI:28401A* + ID_OUI_FROM_DATABASE=C8 MediSensors, Inc. + +OUI:284121* + ID_OUI_FROM_DATABASE=OptiSense Network, LLC + +OUI:284846* + ID_OUI_FROM_DATABASE=GridCentric Inc. + +OUI:284C53* + ID_OUI_FROM_DATABASE=Intune Networks + +OUI:285132* + ID_OUI_FROM_DATABASE=Shenzhen Prayfly Technology Co.,Ltd + +OUI:285FDB* + ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd + +OUI:286046* + ID_OUI_FROM_DATABASE=Lantech Communications Global, Inc. + +OUI:286094* + ID_OUI_FROM_DATABASE=CAPELEC + +OUI:286AB8* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:286ABA* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:286ED4* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +OUI:287184* + ID_OUI_FROM_DATABASE=Spire Payments + +OUI:2872C5* + ID_OUI_FROM_DATABASE=Smartmatic Corp + +OUI:2872F0* + ID_OUI_FROM_DATABASE=ATHENA + +OUI:28852D* + ID_OUI_FROM_DATABASE=Touch Networks + +OUI:288915* + ID_OUI_FROM_DATABASE=CashGuard Sverige AB + +OUI:2891D0* + ID_OUI_FROM_DATABASE=Stage Tec Entwicklungsgesellschaft für professionelle Audiotechnik mbH + +OUI:28924A* + ID_OUI_FROM_DATABASE=Hewlett Packard + +OUI:2893FE* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:28940F* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:28987B* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:289A4B* + ID_OUI_FROM_DATABASE=SteelSeries ApS + +OUI:289EDF* + ID_OUI_FROM_DATABASE=Danfoss Turbocor Compressors, Inc + +OUI:28A186* + ID_OUI_FROM_DATABASE=enblink + +OUI:28A192* + ID_OUI_FROM_DATABASE=GERP Solution + +OUI:28A574* + ID_OUI_FROM_DATABASE=Miller Electric Mfg. Co. + +OUI:28AF0A* + ID_OUI_FROM_DATABASE=Sirius XM Radio Inc + +OUI:28B0CC* + ID_OUI_FROM_DATABASE=Xenya d.o.o. + +OUI:28B3AB* + ID_OUI_FROM_DATABASE=Genmark Automation + +OUI:28BA18* + ID_OUI_FROM_DATABASE=NextNav, LLC + +OUI:28BE9B* + ID_OUI_FROM_DATABASE=Technicolor USA Inc. + +OUI:28C0DA* + ID_OUI_FROM_DATABASE=Juniper Networks + +OUI:28C68E* + ID_OUI_FROM_DATABASE=NETGEAR INC., + +OUI:28C718* + ID_OUI_FROM_DATABASE=Altierre + +OUI:28C914* + ID_OUI_FROM_DATABASE=Taimag Corporation + +OUI:28CC01* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:28CCFF* + ID_OUI_FROM_DATABASE=Corporacion Empresarial Altra SL + +OUI:28CD1C* + ID_OUI_FROM_DATABASE=Espotel Oy + +OUI:28CD4C* + ID_OUI_FROM_DATABASE=Individual Computers GmbH + +OUI:28CFDA* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:28D1AF* + ID_OUI_FROM_DATABASE=Nokia Corporation + +OUI:28D244* + ID_OUI_FROM_DATABASE=LCFC(HeFei) Electronics Technology Co., Ltd. + +OUI:28D576* + ID_OUI_FROM_DATABASE=Premier Wireless, Inc. + +OUI:28D997* + ID_OUI_FROM_DATABASE=Yuduan Mobile Co., Ltd. + +OUI:28E02C* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:28E297* + ID_OUI_FROM_DATABASE=Shanghai InfoTM Microelectronics Co.,Ltd. + +OUI:28E608* + ID_OUI_FROM_DATABASE=Tokheim + +OUI:28E794* + ID_OUI_FROM_DATABASE=Microtime Computer Inc. + +OUI:28E7CF* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:28ED58* + ID_OUI_FROM_DATABASE=JAG Jakob AG + +OUI:28EE2C* + ID_OUI_FROM_DATABASE=Frontline Test Equipment + +OUI:28F358* + ID_OUI_FROM_DATABASE=2C - Trifonov & Co + +OUI:28F606* + ID_OUI_FROM_DATABASE=Syes srl + +OUI:28FBD3* + ID_OUI_FROM_DATABASE=Shanghai RagenTek Communication Technology Co.,Ltd. + +OUI:2C002C* + ID_OUI_FROM_DATABASE=UNOWHY + +OUI:2C0033* + ID_OUI_FROM_DATABASE=EControls, LLC + +OUI:2C00F7* + ID_OUI_FROM_DATABASE=XOS + +OUI:2C0623* + ID_OUI_FROM_DATABASE=Win Leader Inc. + +OUI:2C10C1* + ID_OUI_FROM_DATABASE=Nintendo Co., Ltd. + +OUI:2C1984* + ID_OUI_FROM_DATABASE=IDN Telecom, Inc. + +OUI:2C1EEA* + ID_OUI_FROM_DATABASE=AERODEV + +OUI:2C2172* + ID_OUI_FROM_DATABASE=Juniper Networks + +OUI:2C26C5* + ID_OUI_FROM_DATABASE=zte corporation + +OUI:2C27D7* + ID_OUI_FROM_DATABASE=Hewlett-Packard Company + +OUI:2C2D48* + ID_OUI_FROM_DATABASE=bct electronic GesmbH + +OUI:2C3068* + ID_OUI_FROM_DATABASE=Pantech Co.,Ltd + +OUI:2C3427* + ID_OUI_FROM_DATABASE=ERCO & GENER + +OUI:2C3557* + ID_OUI_FROM_DATABASE=ELLIY Power CO..Ltd + +OUI:2C36A0* + ID_OUI_FROM_DATABASE=Capisco Limited + +OUI:2C36F8* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:2C3A28* + ID_OUI_FROM_DATABASE=Fagor Electrónica + +OUI:2C3BFD* + ID_OUI_FROM_DATABASE=Netstor Technology Co., Ltd. + +OUI:2C3F38* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:2C3F3E* + ID_OUI_FROM_DATABASE=Alge-Timing GmbH + +OUI:2C4138* + ID_OUI_FROM_DATABASE=Hewlett-Packard Company + +OUI:2C4401* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:2C441B* + ID_OUI_FROM_DATABASE=Spectrum Medical Limited + +OUI:2C542D* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:2C5AA3* + ID_OUI_FROM_DATABASE=PROMATE ELECTRONIC CO.LTD + +OUI:2C625A* + ID_OUI_FROM_DATABASE=Finest Security Systems Co., Ltd + +OUI:2C6289* + ID_OUI_FROM_DATABASE=Regenersis (Glenrothes) Ltd + +OUI:2C67FB* + ID_OUI_FROM_DATABASE=ShenZhen Zhengjili Electronics Co., LTD + +OUI:2C6BF5* + ID_OUI_FROM_DATABASE=Juniper networks + +OUI:2C750F* + ID_OUI_FROM_DATABASE=Shanghai Dongzhou-Lawton Communication Technology Co. Ltd. + +OUI:2C768A* + ID_OUI_FROM_DATABASE=Hewlett-Packard Company + +OUI:2C7AFE* + ID_OUI_FROM_DATABASE=IEE&E "Black" ops + +OUI:2C7B5A* + ID_OUI_FROM_DATABASE=Milper Ltd + +OUI:2C7ECF* + ID_OUI_FROM_DATABASE=Onzo Ltd + +OUI:2C8065* + ID_OUI_FROM_DATABASE=HARTING Inc. of North America + +OUI:2C8158* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd + +OUI:2C8BF2* + ID_OUI_FROM_DATABASE=Hitachi Metals America Ltd + +OUI:2C9127* + ID_OUI_FROM_DATABASE=Eintechno Corporation + +OUI:2C9717* + ID_OUI_FROM_DATABASE=I.C.Y. B.V. + +OUI:2C9E5F* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:2C9EFC* + ID_OUI_FROM_DATABASE=CANON INC. + +OUI:2CA157* + ID_OUI_FROM_DATABASE=ACROMATE, INC. + +OUI:2CA780* + ID_OUI_FROM_DATABASE=True Technologies Inc. + +OUI:2CA835* + ID_OUI_FROM_DATABASE=RIM + +OUI:2CAB25* + ID_OUI_FROM_DATABASE=Shenzhen Gongjin Electronics Co.,Ltd + +OUI:2CB05D* + ID_OUI_FROM_DATABASE=NETGEAR + +OUI:2CB0DF* + ID_OUI_FROM_DATABASE=Soliton Technologies Pvt Ltd + +OUI:2CB69D* + ID_OUI_FROM_DATABASE=RED Digital Cinema + +OUI:2CBE97* + ID_OUI_FROM_DATABASE=Ingenieurbuero Bickele und Buehler GmbH + +OUI:2CC260* + ID_OUI_FROM_DATABASE=Ravello Systems + +OUI:2CCD27* + ID_OUI_FROM_DATABASE=Precor Inc + +OUI:2CCD43* + ID_OUI_FROM_DATABASE=Summit Technology Group + +OUI:2CD1DA* + ID_OUI_FROM_DATABASE=Sanjole, Inc. + +OUI:2CD2E7* + ID_OUI_FROM_DATABASE=Nokia Corporation + +OUI:2CD444* + ID_OUI_FROM_DATABASE=Fujitsu Limited + +OUI:2CDD0C* + ID_OUI_FROM_DATABASE=Discovergy GmbH + +OUI:2CE2A8* + ID_OUI_FROM_DATABASE=DeviceDesign + +OUI:2CE412* + ID_OUI_FROM_DATABASE=SAGEMCOM SAS + +OUI:2CE871* + ID_OUI_FROM_DATABASE=Alert Metalguard ApS + +OUI:2CEDEB* + ID_OUI_FROM_DATABASE=Alpheus Digital Company Limited + +OUI:2CEE26* + ID_OUI_FROM_DATABASE=Petroleum Geo-Services + +OUI:2CF4C5* + ID_OUI_FROM_DATABASE=Avaya Inc + +OUI:300B9C* + ID_OUI_FROM_DATABASE=Delta Mobile Systems, Inc. + +OUI:300ED5* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind.Co.Ltd + +OUI:30142D* + ID_OUI_FROM_DATABASE=Piciorgros GmbH + +OUI:30144A* + ID_OUI_FROM_DATABASE=Wistron Neweb Corp. + +OUI:301518* + ID_OUI_FROM_DATABASE=Ubiquitous Communication Co. ltd. + +OUI:30168D* + ID_OUI_FROM_DATABASE=ProLon + +OUI:3017C8* + ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications AB + +OUI:3018CF* + ID_OUI_FROM_DATABASE=DEOS control systems GmbH + +OUI:301A28* + ID_OUI_FROM_DATABASE=Mako Networks Ltd + +OUI:30215B* + ID_OUI_FROM_DATABASE=Shenzhen Ostar Display Electronic Co.,Ltd + +OUI:302DE8* + ID_OUI_FROM_DATABASE=JDA, LLC (JDA Systems) + +OUI:303294* + ID_OUI_FROM_DATABASE=W-IE-NE-R Plein & Baus GmbH + +OUI:3032D4* + ID_OUI_FROM_DATABASE=Hanilstm Co., Ltd. + +OUI:3037A6* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:303855* + ID_OUI_FROM_DATABASE=Nokia Corporation + +OUI:303926* + ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications AB + +OUI:303955* + ID_OUI_FROM_DATABASE=Shenzhen Jinhengjia Electronic Co., Ltd. + +OUI:3039F2* + ID_OUI_FROM_DATABASE=ADB Broadband Italia + +OUI:303D08* + ID_OUI_FROM_DATABASE=GLINTT TES S.A. + +OUI:304174* + ID_OUI_FROM_DATABASE=ALTEC LANSING LLC + +OUI:304449* + ID_OUI_FROM_DATABASE=PLATH GmbH + +OUI:30469A* + ID_OUI_FROM_DATABASE=NETGEAR + +OUI:30493B* + ID_OUI_FROM_DATABASE=Nanjing Z-Com Wireless Co.,Ltd + +OUI:304C7E* + ID_OUI_FROM_DATABASE=Panasonic Electric Works Automation Controls Techno Co.,Ltd. + +OUI:304EC3* + ID_OUI_FROM_DATABASE=Tianjin Techua Technology Co., Ltd. + +OUI:30525A* + ID_OUI_FROM_DATABASE=NST Co., LTD + +OUI:3055ED* + ID_OUI_FROM_DATABASE=Trex Network LLC + +OUI:3057AC* + ID_OUI_FROM_DATABASE=IRLAB LTD. + +OUI:305D38* + ID_OUI_FROM_DATABASE=Beissbarth + +OUI:306118* + ID_OUI_FROM_DATABASE=Paradom Inc. + +OUI:30688C* + ID_OUI_FROM_DATABASE=Reach Technology Inc. + +OUI:30694B* + ID_OUI_FROM_DATABASE=RIM + +OUI:306CBE* + ID_OUI_FROM_DATABASE=Skymotion Technology (HK) Limited + +OUI:306E5C* + ID_OUI_FROM_DATABASE=Validus Technologies + +OUI:3071B2* + ID_OUI_FROM_DATABASE=Hangzhou Prevail Optoelectronic Equipment Co.,LTD. + +OUI:3078C2* + ID_OUI_FROM_DATABASE=Innowireless, Co. Ltd. + +OUI:307C30* + ID_OUI_FROM_DATABASE=RIM + +OUI:307ECB* + ID_OUI_FROM_DATABASE=SFR + +OUI:3085A9* + ID_OUI_FROM_DATABASE=Asustek Computer Inc + +OUI:308730* + ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd + +OUI:308CFB* + ID_OUI_FROM_DATABASE=Dropcam + +OUI:3090AB* + ID_OUI_FROM_DATABASE=Apple + +OUI:3092F6* + ID_OUI_FROM_DATABASE=SHANGHAI SUNMON COMMUNICATION TECHNOGY CO.,LTD + +OUI:30AEF6* + ID_OUI_FROM_DATABASE=Radio Mobile Access + +OUI:30B216* + ID_OUI_FROM_DATABASE=Hytec Geraetebau GmbH + +OUI:30B3A2* + ID_OUI_FROM_DATABASE=Shenzhen Heguang Measurement & Control Technology Co.,Ltd + +OUI:30C82A* + ID_OUI_FROM_DATABASE=Wi-Next s.r.l. + +OUI:30CDA7* + ID_OUI_FROM_DATABASE=Samsung Electronics ITS, Printer division + +OUI:30D357* + ID_OUI_FROM_DATABASE=Logosol, Inc. + +OUI:30DE86* + ID_OUI_FROM_DATABASE=Cedac Software S.r.l. + +OUI:30E48E* + ID_OUI_FROM_DATABASE=Vodafone UK + +OUI:30E4DB* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:30EB25* + ID_OUI_FROM_DATABASE=INTEK DIGITAL + +OUI:30EFD1* + ID_OUI_FROM_DATABASE=Alstom Strongwish (Shenzhen) Co., Ltd. + +OUI:30F33A* + ID_OUI_FROM_DATABASE=+plugg srl + +OUI:30F70D* + ID_OUI_FROM_DATABASE=Cisco Systems + +OUI:30F7C5* + ID_OUI_FROM_DATABASE=Apple + +OUI:30F9ED* + ID_OUI_FROM_DATABASE=Sony Corporation + +OUI:30FD11* + ID_OUI_FROM_DATABASE=MACROTECH (USA) INC. + +OUI:3407FB* + ID_OUI_FROM_DATABASE=Ericsson AB + +OUI:340804* + ID_OUI_FROM_DATABASE=D-Link Corporation + +OUI:34159E* + ID_OUI_FROM_DATABASE=Apple, Inc + +OUI:342109* + ID_OUI_FROM_DATABASE=Jensen Scandinavia AS + +OUI:34255D* + ID_OUI_FROM_DATABASE=Shenzhen Loadcom Technology Co.,Ltd + +OUI:3429EA* + ID_OUI_FROM_DATABASE=MCD ELECTRONICS SP. Z O.O. + +OUI:342F6E* + ID_OUI_FROM_DATABASE=Anywire corporation + +OUI:3440B5* + ID_OUI_FROM_DATABASE=IBM + +OUI:344B3D* + ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Tech.Co.,Ltd. + +OUI:344B50* + ID_OUI_FROM_DATABASE=ZTE Corporation + +OUI:344F69* + ID_OUI_FROM_DATABASE=EKINOPS SAS + +OUI:3451C9* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:345B11* + ID_OUI_FROM_DATABASE=EVI HEAT AB + +OUI:34684A* + ID_OUI_FROM_DATABASE=Teraworks Co., Ltd. + +OUI:346BD3* + ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd + +OUI:346E8A* + ID_OUI_FROM_DATABASE=Ecosense + +OUI:346F92* + ID_OUI_FROM_DATABASE=White Rodgers Division + +OUI:3475C7* + ID_OUI_FROM_DATABASE=Avaya, Inc + +OUI:3476C5* + ID_OUI_FROM_DATABASE=I-O DATA DEVICE, INC. + +OUI:347877* + ID_OUI_FROM_DATABASE=O-NET Communications(Shenzhen) Limited + +OUI:347E39* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:348137* + ID_OUI_FROM_DATABASE=UNICARD SA + +OUI:3482DE* + ID_OUI_FROM_DATABASE=Kayo Technology, Inc. + +OUI:348302* + ID_OUI_FROM_DATABASE=iForcom Co., Ltd + +OUI:348446* + ID_OUI_FROM_DATABASE=Ericsson AB + +OUI:34862A* + ID_OUI_FROM_DATABASE=Heinz Lackmann GmbH & Co KG + +OUI:3497FB* + ID_OUI_FROM_DATABASE=ADVANCED RF TECHNOLOGIES INC + +OUI:34996F* + ID_OUI_FROM_DATABASE=VPI Engineering + +OUI:3499D7* + ID_OUI_FROM_DATABASE=Universal Flow Monitors, Inc. + +OUI:349A0D* + ID_OUI_FROM_DATABASE=ZBD Displays Ltd + +OUI:34A183* + ID_OUI_FROM_DATABASE=AWare, Inc + +OUI:34A55D* + ID_OUI_FROM_DATABASE=TECHNOSOFT INTERNATIONAL SRL + +OUI:34A709* + ID_OUI_FROM_DATABASE=Trevil srl + +OUI:34A7BA* + ID_OUI_FROM_DATABASE=Fischer International Systems Corporation + +OUI:34A84E* + ID_OUI_FROM_DATABASE=Cisco + +OUI:34AA99* + ID_OUI_FROM_DATABASE=Alcatel-Lucent + +OUI:34AAEE* + ID_OUI_FROM_DATABASE=Mikrovisatos Servisas UAB + +OUI:34ADE4* + ID_OUI_FROM_DATABASE=Shanghai Chint Power Systems Co., Ltd. + +OUI:34AF2C* + ID_OUI_FROM_DATABASE=Nintendo Co., Ltd. + +OUI:34B1F7* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:34B571* + ID_OUI_FROM_DATABASE=PLDS + +OUI:34BA51* + ID_OUI_FROM_DATABASE=Se-Kure Controls, Inc. + +OUI:34BA9A* + ID_OUI_FROM_DATABASE=Asiatelco Technologies Co. + +OUI:34BB1F* + ID_OUI_FROM_DATABASE=Research In Motion + +OUI:34BCA6* + ID_OUI_FROM_DATABASE=Beijing Ding Qing Technology, Ltd. + +OUI:34BDC8* + ID_OUI_FROM_DATABASE=Cisco Systems + +OUI:34BDF9* + ID_OUI_FROM_DATABASE=Shanghai WDK Industrial Co.,Ltd. + +OUI:34BDFA* + ID_OUI_FROM_DATABASE=Cisco SPVTG + +OUI:34C059* + ID_OUI_FROM_DATABASE=Apple + +OUI:34C3AC* + ID_OUI_FROM_DATABASE=Samsung Electronics + +OUI:34C69A* + ID_OUI_FROM_DATABASE=Enecsys Ltd + +OUI:34C731* + ID_OUI_FROM_DATABASE=ALPS Electric Co,. Ltd. + +OUI:34C803* + ID_OUI_FROM_DATABASE=Nokia Corporation + +OUI:34C99D* + ID_OUI_FROM_DATABASE=EIDOLON COMMUNICATIONS TECHNOLOGY CO. LTD. + +OUI:34CE94* + ID_OUI_FROM_DATABASE=Parsec (Pty) Ltd + +OUI:34D09B* + ID_OUI_FROM_DATABASE=MobilMAX Technology Inc. + +OUI:34D2C4* + ID_OUI_FROM_DATABASE=RENA GmbH Print Systeme + +OUI:34D7B4* + ID_OUI_FROM_DATABASE=Tributary Systems, Inc. + +OUI:34DF2A* + ID_OUI_FROM_DATABASE=Fujikon Industrial Co.,Limited + +OUI:34E0CF* + ID_OUI_FROM_DATABASE=zte corporation + +OUI:34E0D7* + ID_OUI_FROM_DATABASE=DONGGUAN QISHENG ELECTRONICS INDUSTRIAL CO., LTD + +OUI:34EF44* + ID_OUI_FROM_DATABASE=2Wire + +OUI:34EF8B* + ID_OUI_FROM_DATABASE=NTT Communications Corporation + +OUI:34F39B* + ID_OUI_FROM_DATABASE=WizLAN Ltd. + +OUI:34F62D* + ID_OUI_FROM_DATABASE=SHARP Corporation + +OUI:34F968* + ID_OUI_FROM_DATABASE=ATEK Products, LLC + +OUI:34FA40* + ID_OUI_FROM_DATABASE=Guangzhou Robustel Technologies Co., Limited + +OUI:34FC6F* + ID_OUI_FROM_DATABASE=ALCEA + +OUI:380197* + ID_OUI_FROM_DATABASE=Toshiba Samsung Storage Technolgoy Korea Corporation + +OUI:380A0A* + ID_OUI_FROM_DATABASE=Sky-City Communication and Electronics Limited Company + +OUI:380A94* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:380DD4* + ID_OUI_FROM_DATABASE=Primax Electronics LTD. + +OUI:380FE4* + ID_OUI_FROM_DATABASE=Dedicated Network Partners Oy + +OUI:3816D1* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:38192F* + ID_OUI_FROM_DATABASE=Nokia Corporation + +OUI:381C4A* + ID_OUI_FROM_DATABASE=SIMCom Wireless Solutions Co.,Ltd. + +OUI:38229D* + ID_OUI_FROM_DATABASE=ADB Broadband Italia + +OUI:3822D6* + ID_OUI_FROM_DATABASE=H3C Technologies Co., Limited + +OUI:3826CD* + ID_OUI_FROM_DATABASE=ANDTEK + +OUI:3828EA* + ID_OUI_FROM_DATABASE=Fujian Netcom Technology Co., LTD + +OUI:3831AC* + ID_OUI_FROM_DATABASE=WEG + +OUI:383F10* + ID_OUI_FROM_DATABASE=DBL Technology Ltd. + +OUI:384369* + ID_OUI_FROM_DATABASE=Patrol Products Consortium LLC + +OUI:38458C* + ID_OUI_FROM_DATABASE=MyCloud Technology corporation + +OUI:384608* + ID_OUI_FROM_DATABASE=ZTE Corporation + +OUI:38484C* + ID_OUI_FROM_DATABASE=Apple + +OUI:38521A* + ID_OUI_FROM_DATABASE=Alcatel-Lucent 7705 + +OUI:38580C* + ID_OUI_FROM_DATABASE=Panaccess Systems GmbH + +OUI:3859F9* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + +OUI:385FC3* + ID_OUI_FROM_DATABASE=Yu Jeong System, Co.Ltd + +OUI:386077* + ID_OUI_FROM_DATABASE=PEGATRON CORPORATION + +OUI:3863F6* + ID_OUI_FROM_DATABASE=3NOD MULTIMEDIA(SHENZHEN)CO.,LTD + +OUI:386645* + ID_OUI_FROM_DATABASE=OOSIC Technology CO.,Ltd + +OUI:386BBB* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:386E21* + ID_OUI_FROM_DATABASE=Wasion Group Ltd. + +OUI:3872C0* + ID_OUI_FROM_DATABASE=COMTREND + +OUI:388345* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO., LTD. + +OUI:388AB7* + ID_OUI_FROM_DATABASE=ITC Networks + +OUI:388EE7* + ID_OUI_FROM_DATABASE=Fanhattan LLC + +OUI:3891FB* + ID_OUI_FROM_DATABASE=Xenox Holding BV + +OUI:389592* + ID_OUI_FROM_DATABASE=Beijing Tendyron Corporation + +OUI:389F83* + ID_OUI_FROM_DATABASE=OTN Systems N.V. + +OUI:38A5B6* + ID_OUI_FROM_DATABASE=SHENZHEN MEGMEET ELECTRICAL CO.,LTD + +OUI:38A851* + ID_OUI_FROM_DATABASE=Quickset International Inc + +OUI:38A95F* + ID_OUI_FROM_DATABASE=Actifio Inc + +OUI:38AA3C* + ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO-MECHANICS + +OUI:38B12D* + ID_OUI_FROM_DATABASE=Sonotronic Nagel GmbH + +OUI:38B5BD* + ID_OUI_FROM_DATABASE=E.G.O. Elektro-Ger + +OUI:38BB23* + ID_OUI_FROM_DATABASE=OzVision America LLC + +OUI:38BC1A* + ID_OUI_FROM_DATABASE=Meizu technology co.,ltd + +OUI:38BF33* + ID_OUI_FROM_DATABASE=NEC CASIO Mobile Communications + +OUI:38C096* + ID_OUI_FROM_DATABASE=ALPS ELECTRIC CO.,LTD. + +OUI:38C7BA* + ID_OUI_FROM_DATABASE=CS Services Co.,Ltd. + +OUI:38C85C* + ID_OUI_FROM_DATABASE=Cisco SPVTG + +OUI:38D135* + ID_OUI_FROM_DATABASE=EasyIO Corporation Sdn. Bhd. + +OUI:38DE60* + ID_OUI_FROM_DATABASE=Mohlenhoff GmbH + +OUI:38E08E* + ID_OUI_FROM_DATABASE=Mitsubishi Electric Co. + +OUI:38E595* + ID_OUI_FROM_DATABASE=Shenzhen Gongjin Electronics Co.,Ltd + +OUI:38E7D8* + ID_OUI_FROM_DATABASE=HTC Corporation + +OUI:38E8DF* + ID_OUI_FROM_DATABASE=b gmbh medien + datenbanken + +OUI:38E98C* + ID_OUI_FROM_DATABASE=Reco S.p.A. + +OUI:38EAA7* + ID_OUI_FROM_DATABASE=Hewlett Packard + +OUI:38ECE4* + ID_OUI_FROM_DATABASE=Samsung Electronics + +OUI:38EE9D* + ID_OUI_FROM_DATABASE=Anedo Ltd. + +OUI:38F597* + ID_OUI_FROM_DATABASE=home2net GmbH + +OUI:38F8B7* + ID_OUI_FROM_DATABASE=V2COM PARTICIPACOES S.A. + +OUI:38FEC5* + ID_OUI_FROM_DATABASE=Ellips B.V. + +OUI:3C02B1* + ID_OUI_FROM_DATABASE=Creation Technologies LP + +OUI:3C04BF* + ID_OUI_FROM_DATABASE=PRAVIS SYSTEMS Co.Ltd., + +OUI:3C05AB* + ID_OUI_FROM_DATABASE=Product Creation Studio + +OUI:3C0754* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:3C0771* + ID_OUI_FROM_DATABASE=Sony Corporation + +OUI:3C096D* + ID_OUI_FROM_DATABASE=Powerhouse Dynamics + +OUI:3C0FC1* + ID_OUI_FROM_DATABASE=KBC Networks + +OUI:3C106F* + ID_OUI_FROM_DATABASE=ALBAHITH TECHNOLOGIES + +OUI:3C1915* + ID_OUI_FROM_DATABASE=GFI Chrono Time + +OUI:3C197D* + ID_OUI_FROM_DATABASE=Ericsson AB + +OUI:3C1A79* + ID_OUI_FROM_DATABASE=Huayuan Technology CO.,LTD + +OUI:3C1CBE* + ID_OUI_FROM_DATABASE=JADAK LLC + +OUI:3C26D5* + ID_OUI_FROM_DATABASE=Sotera Wireless + +OUI:3C2763* + ID_OUI_FROM_DATABASE=SLE quality engineering GmbH & Co. KG + +OUI:3C2DB7* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:3C2F3A* + ID_OUI_FROM_DATABASE=SFORZATO Corp. + +OUI:3C363D* + ID_OUI_FROM_DATABASE=Nokia Corporation + +OUI:3C3888* + ID_OUI_FROM_DATABASE=ConnectQuest, llc + +OUI:3C39C3* + ID_OUI_FROM_DATABASE=JW Electronics Co., Ltd. + +OUI:3C3A73* + ID_OUI_FROM_DATABASE=Avaya, Inc + +OUI:3C438E* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:3C4A92* + ID_OUI_FROM_DATABASE=Hewlett-Packard Company + +OUI:3C4C69* + ID_OUI_FROM_DATABASE=Infinity System S.L. + +OUI:3C4E47* + ID_OUI_FROM_DATABASE=Etronic A/S + +OUI:3C57BD* + ID_OUI_FROM_DATABASE=Kessler Crane Inc. + +OUI:3C57D5* + ID_OUI_FROM_DATABASE=FiveCo + +OUI:3C5A37* + ID_OUI_FROM_DATABASE=Samsung Electronics + +OUI:3C5F01* + ID_OUI_FROM_DATABASE=Synerchip Co., Ltd. + +OUI:3C6200* + ID_OUI_FROM_DATABASE=Samsung electronics CO., LTD + +OUI:3C6278* + ID_OUI_FROM_DATABASE=SHENZHEN JETNET TECHNOLOGY CO.,LTD. + +OUI:3C672C* + ID_OUI_FROM_DATABASE=Sciovid Inc. + +OUI:3C6A7D* + ID_OUI_FROM_DATABASE=Niigata Power Systems Co., Ltd. + +OUI:3C6F45* + ID_OUI_FROM_DATABASE=Fiberpro Inc. + +OUI:3C6FF7* + ID_OUI_FROM_DATABASE=EnTek Systems, Inc. + +OUI:3C7059* + ID_OUI_FROM_DATABASE=MakerBot Industries + +OUI:3C7437* + ID_OUI_FROM_DATABASE=RIM + +OUI:3C754A* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:3C7DB1* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:3C81D8* + ID_OUI_FROM_DATABASE=SAGEMCOM SAS + +OUI:3C83B5* + ID_OUI_FROM_DATABASE=Advance Vision Electronics Co. Ltd. + +OUI:3C8AE5* + ID_OUI_FROM_DATABASE=Tensun Information Technology(Hangzhou) Co.,LTD + +OUI:3C8BFE* + ID_OUI_FROM_DATABASE=Samsung Electronics + +OUI:3C9157* + ID_OUI_FROM_DATABASE=Hangzhou Yulong Conmunication Co.,Ltd + +OUI:3C9174* + ID_OUI_FROM_DATABASE=ALONG COMMUNICATION TECHNOLOGY + +OUI:3C94D5* + ID_OUI_FROM_DATABASE=Juniper Networks + +OUI:3C970E* + ID_OUI_FROM_DATABASE=Wistron InfoComm(Kunshan)Co.,Ltd. + +OUI:3C98BF* + ID_OUI_FROM_DATABASE=Quest Controls, Inc. + +OUI:3C99F7* + ID_OUI_FROM_DATABASE=Lansentechnology AB + +OUI:3C9F81* + ID_OUI_FROM_DATABASE=Shenzhen CATIC Bit Communications Technology Co.,Ltd + +OUI:3CA315* + ID_OUI_FROM_DATABASE=Bless Information & Communications Co., Ltd + +OUI:3CA72B* + ID_OUI_FROM_DATABASE=MRV Communications (Networks) LTD + +OUI:3CA9F4* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:3CB15B* + ID_OUI_FROM_DATABASE=Avaya, Inc + +OUI:3CB17F* + ID_OUI_FROM_DATABASE=Wattwatchers Pty Ld + +OUI:3CB9A6* + ID_OUI_FROM_DATABASE=Belden Deutschland GmbH + +OUI:3CBDD8* + ID_OUI_FROM_DATABASE=LG ELECTRONICS INC + +OUI:3CC0C6* + ID_OUI_FROM_DATABASE=d&b audiotechnik GmbH + +OUI:3CC12C* + ID_OUI_FROM_DATABASE=AES Corporation + +OUI:3CC1F6* + ID_OUI_FROM_DATABASE=Melange Systems Pvt. Ltd. + +OUI:3CC99E* + ID_OUI_FROM_DATABASE=Huiyang Technology Co., Ltd + +OUI:3CCE73* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:3CD0F8* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:3CD16E* + ID_OUI_FROM_DATABASE=Telepower Communication Co., Ltd + +OUI:3CD7DA* + ID_OUI_FROM_DATABASE=SK Mtek microelectronics(shenzhen)limited + +OUI:3CD92B* + ID_OUI_FROM_DATABASE=Hewlett-Packard Company + +OUI:3CDF1E* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:3CE072* + ID_OUI_FROM_DATABASE=Apple + +OUI:3CE5A6* + ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Ltd. + +OUI:3CE5B4* + ID_OUI_FROM_DATABASE=KIDASEN INDUSTRIA E COMERCIO DE ANTENAS LTDA + +OUI:3CE624* + ID_OUI_FROM_DATABASE=LG Display + +OUI:3CEA4F* + ID_OUI_FROM_DATABASE=2Wire + +OUI:3CEAFB* + ID_OUI_FROM_DATABASE=NSE AG + +OUI:3CF392* + ID_OUI_FROM_DATABASE=Virtualtek. Co. Ltd + +OUI:3CF52C* + ID_OUI_FROM_DATABASE=DSPECIALISTS GmbH + +OUI:3CF72A* + ID_OUI_FROM_DATABASE=Nokia Corporation + +OUI:4001C6* + ID_OUI_FROM_DATABASE=3COM EUROPE LTD + +OUI:40040C* + ID_OUI_FROM_DATABASE=A&T + +OUI:400E67* + ID_OUI_FROM_DATABASE=Tremol Ltd. + +OUI:4012E4* + ID_OUI_FROM_DATABASE=Compass-EOS + +OUI:4013D9* + ID_OUI_FROM_DATABASE=Global ES + +OUI:401597* + ID_OUI_FROM_DATABASE=Protect America, Inc. + +OUI:40169F* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO., LTD. + +OUI:4016FA* + ID_OUI_FROM_DATABASE=EKM Metering + +OUI:4018B1* + ID_OUI_FROM_DATABASE=Aerohive Networks Inc. + +OUI:4018D7* + ID_OUI_FROM_DATABASE=Wyle Telemetry and Data Systems + +OUI:401D59* + ID_OUI_FROM_DATABASE=Biometric Associates, LP + +OUI:4022ED* + ID_OUI_FROM_DATABASE=Digital Projection Ltd + +OUI:4025C2* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:40270B* + ID_OUI_FROM_DATABASE=Mobileeco Co., Ltd + +OUI:402BA1* + ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications AB + +OUI:402CF4* + ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co., Ltd. + +OUI:403004* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:40336C* + ID_OUI_FROM_DATABASE=Godrej & Boyce Mfg. co. ltd + +OUI:4037AD* + ID_OUI_FROM_DATABASE=Macro Image Technology, Inc. + +OUI:403CFC* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:404022* + ID_OUI_FROM_DATABASE=ZIV + +OUI:40406B* + ID_OUI_FROM_DATABASE=Icomera + +OUI:404A03* + ID_OUI_FROM_DATABASE=ZyXEL Communications Corporation + +OUI:404D8E* + ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd + +OUI:4050E0* + ID_OUI_FROM_DATABASE=Milton Security Group LLC + +OUI:40520D* + ID_OUI_FROM_DATABASE=Pico Technology + +OUI:405539* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:405A9B* + ID_OUI_FROM_DATABASE=ANOVO + +OUI:405FBE* + ID_OUI_FROM_DATABASE=RIM + +OUI:405FC2* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:40605A* + ID_OUI_FROM_DATABASE=Hawkeye Tech Co. Ltd + +OUI:406186* + ID_OUI_FROM_DATABASE=MICRO-STAR INT'L CO.,LTD + +OUI:40618E* + ID_OUI_FROM_DATABASE=Stella-Green Co + +OUI:40667A* + ID_OUI_FROM_DATABASE=mediola - connected living AG + +OUI:406AAB* + ID_OUI_FROM_DATABASE=RIM + +OUI:406C8F* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:406F2A* + ID_OUI_FROM_DATABASE=Research In Motion + +OUI:40704A* + ID_OUI_FROM_DATABASE=Power Idea Technology Limited + +OUI:407074* + ID_OUI_FROM_DATABASE=Life Technology (China) Co., Ltd + +OUI:407B1B* + ID_OUI_FROM_DATABASE=Mettle Networks Inc. + +OUI:4083DE* + ID_OUI_FROM_DATABASE=Motorola + +OUI:408493* + ID_OUI_FROM_DATABASE=Clavister AB + +OUI:4088E0* + ID_OUI_FROM_DATABASE=Beijing Ereneben Information Technology Limited Shenzhen Branch + +OUI:408A9A* + ID_OUI_FROM_DATABASE=TITENG CO., Ltd. + +OUI:408B07* + ID_OUI_FROM_DATABASE=Actiontec Electronics, Inc + +OUI:408BF6* + ID_OUI_FROM_DATABASE=Shenzhen TCL New Technology Co; Ltd. + +OUI:409558* + ID_OUI_FROM_DATABASE=Aisino Corporation + +OUI:4097D1* + ID_OUI_FROM_DATABASE=BK Electronics cc + +OUI:40984C* + ID_OUI_FROM_DATABASE=Casacom Solutions AG + +OUI:40984E* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:40987B* + ID_OUI_FROM_DATABASE=Aisino Corporation + +OUI:409FC7* + ID_OUI_FROM_DATABASE=BAEKCHUN ENC Co., Ltd. + +OUI:40A6A4* + ID_OUI_FROM_DATABASE=PassivSystems Ltd + +OUI:40A6D9* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:40AC8D* + ID_OUI_FROM_DATABASE=Data Management, Inc. + +OUI:40B2C8* + ID_OUI_FROM_DATABASE=Nortel Networks + +OUI:40B395* + ID_OUI_FROM_DATABASE=Apple + +OUI:40B3FC* + ID_OUI_FROM_DATABASE=Logital Co. Limited + +OUI:40B4F0* + ID_OUI_FROM_DATABASE=Juniper Networks + +OUI:40B7F3* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:40BA61* + ID_OUI_FROM_DATABASE=Arima Communications Corp. + +OUI:40BC8B* + ID_OUI_FROM_DATABASE=itelio GmbH + +OUI:40BF17* + ID_OUI_FROM_DATABASE=Digistar Telecom. SA + +OUI:40C245* + ID_OUI_FROM_DATABASE=Shenzhen Hexicom Technology Co., Ltd. + +OUI:40C7C9* + ID_OUI_FROM_DATABASE=Naviit Inc. + +OUI:40CD3A* + ID_OUI_FROM_DATABASE=Z3 Technology + +OUI:40D32D* + ID_OUI_FROM_DATABASE=Apple, Inc + +OUI:40D40E* + ID_OUI_FROM_DATABASE=Biodata Ltd + +OUI:40D559* + ID_OUI_FROM_DATABASE=MICRO S.E.R.I. + +OUI:40E793* + ID_OUI_FROM_DATABASE=Shenzhen Siviton Technology Co.,Ltd + +OUI:40ECF8* + ID_OUI_FROM_DATABASE=Siemens AG + +OUI:40EF4C* + ID_OUI_FROM_DATABASE=Fihonest communication co.,Ltd + +OUI:40F14C* + ID_OUI_FROM_DATABASE=ISE Europe SPRL + +OUI:40F2E9* + ID_OUI_FROM_DATABASE=IBM + +OUI:40F407* + ID_OUI_FROM_DATABASE=Nintendo Co., Ltd. + +OUI:40F4EC* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:40F52E* + ID_OUI_FROM_DATABASE=Leica Microsystems (Schweiz) AG + +OUI:40FC89* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:4403A7* + ID_OUI_FROM_DATABASE=Cisco + +OUI:440CFD* + ID_OUI_FROM_DATABASE=NetMan Co., Ltd. + +OUI:441319* + ID_OUI_FROM_DATABASE=WKK TECHNOLOGY LTD. + +OUI:44184F* + ID_OUI_FROM_DATABASE=Fitview + +OUI:4419B6* + ID_OUI_FROM_DATABASE=Hangzhou Hikvision Digital Technology Co.,Ltd. + +OUI:441EA1* + ID_OUI_FROM_DATABASE=Hewlett-Packard Company + +OUI:4423AA* + ID_OUI_FROM_DATABASE=Farmage Co., Ltd. + +OUI:4425BB* + ID_OUI_FROM_DATABASE=Bamboo Entertainment Corporation + +OUI:442A60* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:442B03* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:44322A* + ID_OUI_FROM_DATABASE=Avaya Inc + +OUI:44334C* + ID_OUI_FROM_DATABASE=Shenzhen Bilian electronic CO.,LTD + +OUI:44348F* + ID_OUI_FROM_DATABASE=MXT INDUSTRIAL LTDA + +OUI:443719* + ID_OUI_FROM_DATABASE=2 Save Energy Ltd + +OUI:44376F* + ID_OUI_FROM_DATABASE=Young Electric Sign Co + +OUI:4437E6* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind.Co.Ltd + +OUI:443839* + ID_OUI_FROM_DATABASE=Cumulus Networks, inc + +OUI:443D21* + ID_OUI_FROM_DATABASE=Nuvolt + +OUI:443EB2* + ID_OUI_FROM_DATABASE=DEOTRON Co., LTD. + +OUI:444C0C* + ID_OUI_FROM_DATABASE=Apple Inc + +OUI:444E1A* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:444F5E* + ID_OUI_FROM_DATABASE=Pan Studios Co.,Ltd. + +OUI:4451DB* + ID_OUI_FROM_DATABASE=Raytheon BBN Technologies + +OUI:4454C0* + ID_OUI_FROM_DATABASE=Thompson Aerospace + +OUI:44568D* + ID_OUI_FROM_DATABASE=PNC Technologies Co., Ltd. + +OUI:4456B7* + ID_OUI_FROM_DATABASE=Spawn Labs, Inc + +OUI:445829* + ID_OUI_FROM_DATABASE=Cisco SPVTG + +OUI:44599F* + ID_OUI_FROM_DATABASE=Criticare Systems, Inc + +OUI:445EF3* + ID_OUI_FROM_DATABASE=Tonalite Holding B.V. + +OUI:445F7A* + ID_OUI_FROM_DATABASE=Shihlin Electric & Engineering Corp. + +OUI:446132* + ID_OUI_FROM_DATABASE=ecobee inc + +OUI:4468AB* + ID_OUI_FROM_DATABASE=JUIN COMPANY, LIMITED + +OUI:446C24* + ID_OUI_FROM_DATABASE=Reallin Electronic Co.,Ltd + +OUI:446D57* + ID_OUI_FROM_DATABASE=Liteon Technology Corporation + +OUI:447C7F* + ID_OUI_FROM_DATABASE=Innolight Technology Corporation + +OUI:447DA5* + ID_OUI_FROM_DATABASE=VTION INFORMATION TECHNOLOGY (FUJIAN) CO.,LTD + +OUI:447E95* + ID_OUI_FROM_DATABASE=Alpha and Omega, Inc + +OUI:448312* + ID_OUI_FROM_DATABASE=Star-Net + +OUI:448500* + ID_OUI_FROM_DATABASE=Intel Corporation + +OUI:4487FC* + ID_OUI_FROM_DATABASE=ELITEGROUP COMPUTER SYSTEM CO., LTD. + +OUI:448C52* + ID_OUI_FROM_DATABASE=KTIS CO., Ltd + +OUI:448E12* + ID_OUI_FROM_DATABASE=DT Research, Inc. + +OUI:448E81* + ID_OUI_FROM_DATABASE=VIG + +OUI:4491DB* + ID_OUI_FROM_DATABASE=Shanghai Huaqin Telecom Technology Co.,Ltd + +OUI:4495FA* + ID_OUI_FROM_DATABASE=Qingdao Santong Digital Technology Co.Ltd + +OUI:449B78* + ID_OUI_FROM_DATABASE=The Now Factory + +OUI:449CB5* + ID_OUI_FROM_DATABASE=Alcomp, Inc + +OUI:44A42D* + ID_OUI_FROM_DATABASE=TCT Mobile Limited + +OUI:44A689* + ID_OUI_FROM_DATABASE=PROMAX ELECTRONICA SA + +OUI:44A7CF* + ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd. + +OUI:44A8C2* + ID_OUI_FROM_DATABASE=SEWOO TECH CO., LTD + +OUI:44AA27* + ID_OUI_FROM_DATABASE=udworks Co., Ltd. + +OUI:44AAE8* + ID_OUI_FROM_DATABASE=Nanotec Electronic GmbH & Co. KG + +OUI:44B382* + ID_OUI_FROM_DATABASE=Kuang-chi Institute of Advanced Technology + +OUI:44C15C* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:44C233* + ID_OUI_FROM_DATABASE=Guangzhou Comet Technology Development Co.Ltd + +OUI:44C39B* + ID_OUI_FROM_DATABASE=OOO RUBEZH NPO + +OUI:44C9A2* + ID_OUI_FROM_DATABASE=Greenwald Industries + +OUI:44D15E* + ID_OUI_FROM_DATABASE=Shanghai Kingto Information Technology Ltd + +OUI:44D2CA* + ID_OUI_FROM_DATABASE=Anvia TV Oy + +OUI:44D3CA* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:44D63D* + ID_OUI_FROM_DATABASE=Talari Networks + +OUI:44D832* + ID_OUI_FROM_DATABASE=Azurewave Technologies, Inc. + +OUI:44D884* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:44DC91* + ID_OUI_FROM_DATABASE=PLANEX COMMUNICATIONS INC. + +OUI:44DCCB* + ID_OUI_FROM_DATABASE=SEMINDIA SYSTEMS PVT LTD + +OUI:44E08E* + ID_OUI_FROM_DATABASE=Cisco SPVTG + +OUI:44E49A* + ID_OUI_FROM_DATABASE=OMNITRONICS PTY LTD + +OUI:44E4D9* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:44E8A5* + ID_OUI_FROM_DATABASE=Myreka Technologies Sdn. Bhd. + +OUI:44ED57* + ID_OUI_FROM_DATABASE=Longicorn, inc. + +OUI:44F459* + ID_OUI_FROM_DATABASE=Samsung Electronics + +OUI:44FB42* + ID_OUI_FROM_DATABASE=Apple + +OUI:48022A* + ID_OUI_FROM_DATABASE=B-Link Electronic Limited + +OUI:480362* + ID_OUI_FROM_DATABASE=DESAY ELECTRONICS(HUIZHOU)CO.,LTD + +OUI:481249* + ID_OUI_FROM_DATABASE=Luxcom Technologies Inc. + +OUI:4813F3* + ID_OUI_FROM_DATABASE=BBK Electronics Corp., Ltd. + +OUI:48174C* + ID_OUI_FROM_DATABASE=MicroPower technologies + +OUI:481BD2* + ID_OUI_FROM_DATABASE=Intron Scientific co., ltd. + +OUI:48282F* + ID_OUI_FROM_DATABASE=ZTE Corporation + +OUI:482CEA* + ID_OUI_FROM_DATABASE=Motorola Inc Business Light Radios + +OUI:4833DD* + ID_OUI_FROM_DATABASE=ZENNIO AVANCE Y TECNOLOGIA, S.L. + +OUI:48343D* + ID_OUI_FROM_DATABASE=IEP GmbH + +OUI:484487* + ID_OUI_FROM_DATABASE=Cisco SPVTG + +OUI:4844F7* + ID_OUI_FROM_DATABASE=Samsung Electronics Co., LTD + +OUI:4846F1* + ID_OUI_FROM_DATABASE=Uros Oy + +OUI:485261* + ID_OUI_FROM_DATABASE=SOREEL + +OUI:485A3F* + ID_OUI_FROM_DATABASE=WISOL + +OUI:485B39* + ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. + +OUI:485D60* + ID_OUI_FROM_DATABASE=Azurewave Technologies, Inc. + +OUI:4860BC* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:4861A3* + ID_OUI_FROM_DATABASE=Concern "Axion" JSC + +OUI:486B91* + ID_OUI_FROM_DATABASE=Fleetwood Group Inc. + +OUI:486FD2* + ID_OUI_FROM_DATABASE=StorSimple Inc + +OUI:487119* + ID_OUI_FROM_DATABASE=SGB GROUP LTD. + +OUI:488E42* + ID_OUI_FROM_DATABASE=DIGALOG GmbH + +OUI:489153* + ID_OUI_FROM_DATABASE=Weinmann Geräte für Medizin GmbH + Co. KG + +OUI:4891F6* + ID_OUI_FROM_DATABASE=Shenzhen Reach software technology CO.,LTD + +OUI:489BE2* + ID_OUI_FROM_DATABASE=SCI Innovations Ltd + +OUI:48A22D* + ID_OUI_FROM_DATABASE=Shenzhen Huaxuchang Telecom Technology Co.,Ltd + +OUI:48A6D2* + ID_OUI_FROM_DATABASE=GJsun Optical Science and Tech Co.,Ltd. + +OUI:48AA5D* + ID_OUI_FROM_DATABASE=Store Electronic Systems + +OUI:48B253* + ID_OUI_FROM_DATABASE=Marketaxess Corporation + +OUI:48B8DE* + ID_OUI_FROM_DATABASE=HOMEWINS TECHNOLOGY CO.,LTD. + +OUI:48B9C2* + ID_OUI_FROM_DATABASE=Teletics Inc. + +OUI:48BE2D* + ID_OUI_FROM_DATABASE=Symanitron + +OUI:48C1AC* + ID_OUI_FROM_DATABASE=PLANTRONICS, INC. + +OUI:48C862* + ID_OUI_FROM_DATABASE=Simo Wireless,Inc. + +OUI:48C8B6* + ID_OUI_FROM_DATABASE=SysTec GmbH + +OUI:48CB6E* + ID_OUI_FROM_DATABASE=Cello Electronics (UK) Ltd + +OUI:48D54C* + ID_OUI_FROM_DATABASE=Jeda Networks + +OUI:48D7FF* + ID_OUI_FROM_DATABASE=BLANKOM Antennentechnik GmbH + +OUI:48D8FE* + ID_OUI_FROM_DATABASE=ClarIDy Solutions, Inc. + +OUI:48DCFB* + ID_OUI_FROM_DATABASE=Nokia Corporation + +OUI:48DF1C* + ID_OUI_FROM_DATABASE=Wuhan NEC Fibre Optic Communications industry Co. Ltd + +OUI:48E1AF* + ID_OUI_FROM_DATABASE=Vity + +OUI:48EA63* + ID_OUI_FROM_DATABASE=Zhejiang Uniview Technologies Co., Ltd. + +OUI:48EB30* + ID_OUI_FROM_DATABASE=ETERNA TECHNOLOGY, INC. + +OUI:48ED80* + ID_OUI_FROM_DATABASE=daesung eltec + +OUI:48F230* + ID_OUI_FROM_DATABASE=Ubizcore Co.,LTD + +OUI:48F47D* + ID_OUI_FROM_DATABASE=TechVision Holding Internation Limited + +OUI:48F7F1* + ID_OUI_FROM_DATABASE=Alcatel-Lucent + +OUI:48F8B3* + ID_OUI_FROM_DATABASE=Cisco-Linksys, LLC + +OUI:48F8E1* + ID_OUI_FROM_DATABASE=Alcatel Lucent WT + +OUI:48FCB8* + ID_OUI_FROM_DATABASE=Woodstream Corporation + +OUI:4C022E* + ID_OUI_FROM_DATABASE=CMR KOREA CO., LTD + +OUI:4C0289* + ID_OUI_FROM_DATABASE=LEX COMPUTECH CO., LTD + +OUI:4C068A* + ID_OUI_FROM_DATABASE=Basler Electric Company + +OUI:4C07C9* + ID_OUI_FROM_DATABASE=COMPUTER OFFICE Co.,Ltd. + +OUI:4C09B4* + ID_OUI_FROM_DATABASE=zte corporation + +OUI:4C0B3A* + ID_OUI_FROM_DATABASE=TCT Mobile Limited + +OUI:4C0F6E* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + +OUI:4C0FC7* + ID_OUI_FROM_DATABASE=Earda Electronics Co.,Ltd + +OUI:4C1480* + ID_OUI_FROM_DATABASE=NOREGON SYSTEMS, INC + +OUI:4C17EB* + ID_OUI_FROM_DATABASE=SAGEMCOM + +OUI:4C1A3A* + ID_OUI_FROM_DATABASE=PRIMA Research And Production Enterprise Ltd. + +OUI:4C1A95* + ID_OUI_FROM_DATABASE=Novakon Co., Ltd. + +OUI:4C1FCC* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +OUI:4C2258* + ID_OUI_FROM_DATABASE=cozybit, Inc. + +OUI:4C2578* + ID_OUI_FROM_DATABASE=Nokia Corporation + +OUI:4C2C80* + ID_OUI_FROM_DATABASE=Beijing Skyway Technologies Co.,Ltd + +OUI:4C2F9D* + ID_OUI_FROM_DATABASE=ICM Controls + +OUI:4C3089* + ID_OUI_FROM_DATABASE=Thales Transportation Systems GmbH + +OUI:4C322D* + ID_OUI_FROM_DATABASE=TELEDATA NETWORKS + +OUI:4C32D9* + ID_OUI_FROM_DATABASE=M Rutty Holdings Pty. Ltd. + +OUI:4C3910* + ID_OUI_FROM_DATABASE=Newtek Electronics co., Ltd. + +OUI:4C3B74* + ID_OUI_FROM_DATABASE=VOGTEC(H.K.) Co., Ltd + +OUI:4C4B68* + ID_OUI_FROM_DATABASE=Mobile Device, Inc. + +OUI:4C4E35* + ID_OUI_FROM_DATABASE=Cisco + +OUI:4C5427* + ID_OUI_FROM_DATABASE=Linepro Sp. z o.o. + +OUI:4C5499* + ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd + +OUI:4C5585* + ID_OUI_FROM_DATABASE=Hamilton Systems + +OUI:4C5DCD* + ID_OUI_FROM_DATABASE=Oy Finnish Electric Vehicle Technologies Ltd + +OUI:4C5FD2* + ID_OUI_FROM_DATABASE=Alcatel-Lucent + +OUI:4C60D5* + ID_OUI_FROM_DATABASE=airPointe of New Hampshire + +OUI:4C60DE* + ID_OUI_FROM_DATABASE=NETGEAR + +OUI:4C63EB* + ID_OUI_FROM_DATABASE=Application Solutions (Electronics and Vision) Ltd + +OUI:4C64D9* + ID_OUI_FROM_DATABASE=Guangdong Leawin Group Co., Ltd + +OUI:4C72B9* + ID_OUI_FROM_DATABASE=Pegatron Corporation + +OUI:4C7367* + ID_OUI_FROM_DATABASE=Genius Bytes Software Solutions GmbH + +OUI:4C73A5* + ID_OUI_FROM_DATABASE=KOVE + +OUI:4C774F* + ID_OUI_FROM_DATABASE=Embedded Wireless Labs + +OUI:4C7897* + ID_OUI_FROM_DATABASE=Arrowhead Alarm Products Ltd + +OUI:4C8093* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:4C8B55* + ID_OUI_FROM_DATABASE=Grupo Digicon + +OUI:4C8BEF* + ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd + +OUI:4C8D79* + ID_OUI_FROM_DATABASE=Apple + +OUI:4C8FA5* + ID_OUI_FROM_DATABASE=Jastec + +OUI:4C98EF* + ID_OUI_FROM_DATABASE=Zeo + +OUI:4C9E80* + ID_OUI_FROM_DATABASE=KYOKKO ELECTRIC Co., Ltd. + +OUI:4C9EE4* + ID_OUI_FROM_DATABASE=Hanyang Navicom Co.,Ltd. + +OUI:4CA74B* + ID_OUI_FROM_DATABASE=Alcatel Lucent + +OUI:4CAA16* + ID_OUI_FROM_DATABASE=AzureWave Technologies (Shanghai) Inc. + +OUI:4CAB33* + ID_OUI_FROM_DATABASE=KST technology + +OUI:4CAC0A* + ID_OUI_FROM_DATABASE=ZTE Corporation + +OUI:4CB16C* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +OUI:4CB199* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:4CB4EA* + ID_OUI_FROM_DATABASE=HRD (S) PTE., LTD. + +OUI:4CB9C8* + ID_OUI_FROM_DATABASE=CONET CO., LTD. + +OUI:4CBAA3* + ID_OUI_FROM_DATABASE=Bison Electronics Inc. + +OUI:4CBCA5* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:4CC452* + ID_OUI_FROM_DATABASE=Shang Hai Tyd. Electon Technology Ltd. + +OUI:4CC602* + ID_OUI_FROM_DATABASE=Radios, Inc. + +OUI:4CC94F* + ID_OUI_FROM_DATABASE=Alcatel-Lucent + +OUI:4CCA53* + ID_OUI_FROM_DATABASE=Skyera, Inc. + +OUI:4CE676* + ID_OUI_FROM_DATABASE=Buffalo Inc. + +OUI:4CEB42* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:4CEDDE* + ID_OUI_FROM_DATABASE=Askey Computer Corp + +OUI:4CF737* + ID_OUI_FROM_DATABASE=SamJi Electronics Co., Ltd + +OUI:50008C* + ID_OUI_FROM_DATABASE=Hong Kong Telecommunications (HKT) Limited + +OUI:5001BB* + ID_OUI_FROM_DATABASE=Samsung Electronics + +OUI:50053D* + ID_OUI_FROM_DATABASE=CyWee Group Ltd + +OUI:500B32* + ID_OUI_FROM_DATABASE=Foxda Technology Industrial(ShenZhen)Co.,LTD + +OUI:500E6D* + ID_OUI_FROM_DATABASE=TrafficCast International + +OUI:5011EB* + ID_OUI_FROM_DATABASE=SilverNet Ltd + +OUI:502267* + ID_OUI_FROM_DATABASE=PixeLINK + +OUI:50252B* + ID_OUI_FROM_DATABASE=Nethra Imaging Incorporated + +OUI:502690* + ID_OUI_FROM_DATABASE=Fujitsu Limited + +OUI:502A7E* + ID_OUI_FROM_DATABASE=Smart electronic GmbH + +OUI:502A8B* + ID_OUI_FROM_DATABASE=Telekom Research and Development Sdn Bhd + +OUI:502D1D* + ID_OUI_FROM_DATABASE=Nokia Corporation + +OUI:502DA2* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:502DF4* + ID_OUI_FROM_DATABASE=Phytec Messtechnik GmbH + +OUI:502ECE* + ID_OUI_FROM_DATABASE=Asahi Electronics Co.,Ltd + +OUI:503955* + ID_OUI_FROM_DATABASE=Cisco SPVTG + +OUI:503DE5* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:503F56* + ID_OUI_FROM_DATABASE=Syncmold Enterprise Corp + +OUI:50465D* + ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. + +OUI:5048EB* + ID_OUI_FROM_DATABASE=BEIJING HAIHEJINSHENG NETWORK TECHNOLOGY CO. LTD. + +OUI:504A5E* + ID_OUI_FROM_DATABASE=Masimo Corporation + +OUI:504F94* + ID_OUI_FROM_DATABASE=Loxone Electronics GmbH + +OUI:505663* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:5057A8* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:506028* + ID_OUI_FROM_DATABASE=Xirrus Inc. + +OUI:506313* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + +OUI:506441* + ID_OUI_FROM_DATABASE=Greenlee + +OUI:5067F0* + ID_OUI_FROM_DATABASE=ZyXEL Communications Corporation + +OUI:506F9A* + ID_OUI_FROM_DATABASE=Wi-Fi Alliance + +OUI:5070E5* + ID_OUI_FROM_DATABASE=He Shan World Fair Electronics Technology Limited + +OUI:50724D* + ID_OUI_FROM_DATABASE=BEG Brueck Electronic GmbH + +OUI:5076A6* + ID_OUI_FROM_DATABASE=Ecil Informatica Ind. Com. Ltda + +OUI:50795B* + ID_OUI_FROM_DATABASE=Interexport Telecomunicaciones S.A. + +OUI:507D02* + ID_OUI_FROM_DATABASE=BIODIT + +OUI:507E5D* + ID_OUI_FROM_DATABASE=Arcadyan Technology Corporation + +OUI:5087B8* + ID_OUI_FROM_DATABASE=Nuvyyo Inc + +OUI:508A42* + ID_OUI_FROM_DATABASE=Uptmate Technology Co., LTD + +OUI:508ACB* + ID_OUI_FROM_DATABASE=SHENZHEN MAXMADE TECHNOLOGY CO., LTD. + +OUI:508C77* + ID_OUI_FROM_DATABASE=DIRMEIER Schanktechnik GmbH &Co KG + +OUI:50934F* + ID_OUI_FROM_DATABASE=Gradual Tecnologia Ltda. + +OUI:509772* + ID_OUI_FROM_DATABASE=Westinghouse Digital + +OUI:50A4C8* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:50A6E3* + ID_OUI_FROM_DATABASE=David Clark Company + +OUI:50A733* + ID_OUI_FROM_DATABASE=Ruckus Wireless + +OUI:50ABBF* + ID_OUI_FROM_DATABASE=Hoseo Telecom + +OUI:50AF73* + ID_OUI_FROM_DATABASE=Shenzhen Bitland Information Technology Co., Ltd. + +OUI:50B7C3* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,LTD + +OUI:50C58D* + ID_OUI_FROM_DATABASE=Juniper Networks + +OUI:50C971* + ID_OUI_FROM_DATABASE=GN Netcom A/S + +OUI:50CCF8* + ID_OUI_FROM_DATABASE=Samsung Electro Mechanics + +OUI:50CE75* + ID_OUI_FROM_DATABASE=Measy Electronics Ltd + +OUI:50D274* + ID_OUI_FROM_DATABASE=Steffes Corporation + +OUI:50D6D7* + ID_OUI_FROM_DATABASE=Takahata Precision + +OUI:50E549* + ID_OUI_FROM_DATABASE=GIGA-BYTE TECHNOLOGY CO.,LTD. + +OUI:50EAD6* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:50EB1A* + ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc + +OUI:50ED94* + ID_OUI_FROM_DATABASE=Egatel SL + +OUI:50F003* + ID_OUI_FROM_DATABASE=Open Stack, Inc. + +OUI:50F61A* + ID_OUI_FROM_DATABASE=Kunshan JADE Technologies co., Ltd. + +OUI:50FAAB* + ID_OUI_FROM_DATABASE=L-tek d.o.o. + +OUI:50FC30* + ID_OUI_FROM_DATABASE=Treehouse Labs + +OUI:5403F5* + ID_OUI_FROM_DATABASE=EBN Technology Corp. + +OUI:540496* + ID_OUI_FROM_DATABASE=Gigawave LTD + +OUI:5404A6* + ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. + +OUI:54055F* + ID_OUI_FROM_DATABASE=Alcatel Lucent + +OUI:54115F* + ID_OUI_FROM_DATABASE=Atamo Pty Ltd + +OUI:541DFB* + ID_OUI_FROM_DATABASE=Freestyle Energy Ltd + +OUI:541FD5* + ID_OUI_FROM_DATABASE=Advantage Electronics + +OUI:542018* + ID_OUI_FROM_DATABASE=Tely Labs + +OUI:542696* + ID_OUI_FROM_DATABASE=Apple + +OUI:542A9C* + ID_OUI_FROM_DATABASE=LSY Defense, LLC. + +OUI:543131* + ID_OUI_FROM_DATABASE=Raster Vision Ltd + +OUI:5435DF* + ID_OUI_FROM_DATABASE=Symeo GmbH + +OUI:543968* + ID_OUI_FROM_DATABASE=Edgewater Networks Inc + +OUI:543D37* + ID_OUI_FROM_DATABASE=Ruckus Wireless + +OUI:544249* + ID_OUI_FROM_DATABASE=Sony Corporation + +OUI:54466B* + ID_OUI_FROM_DATABASE=Shenzhen CZTIC Electronic Technology Co., Ltd + +OUI:544A05* + ID_OUI_FROM_DATABASE=wenglor sensoric gmbh + +OUI:5453ED* + ID_OUI_FROM_DATABASE=Sony Corporation + +OUI:545EBD* + ID_OUI_FROM_DATABASE=NL Technologies + +OUI:545FA9* + ID_OUI_FROM_DATABASE=Teracom Limited + +OUI:5461EA* + ID_OUI_FROM_DATABASE=Zaplox AB + +OUI:547398* + ID_OUI_FROM_DATABASE=Toyo Electronics Corporation + +OUI:5474E6* + ID_OUI_FROM_DATABASE=Webtech Wireless + +OUI:5475D0* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:54781A* + ID_OUI_FROM_DATABASE=Cisco + +OUI:547975* + ID_OUI_FROM_DATABASE=Nokia Corporation + +OUI:547F54* + ID_OUI_FROM_DATABASE=INGENICO + +OUI:547FA8* + ID_OUI_FROM_DATABASE=TELCO systems, s.r.o. + +OUI:547FEE* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:5481AD* + ID_OUI_FROM_DATABASE=Eagle Research Corporation + +OUI:54847B* + ID_OUI_FROM_DATABASE=Digital Devices GmbH + +OUI:548922* + ID_OUI_FROM_DATABASE=Zelfy Inc + +OUI:548998* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +OUI:5492BE* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:549478* + ID_OUI_FROM_DATABASE=Silvershore Technology Partners + +OUI:549A16* + ID_OUI_FROM_DATABASE=Uzushio Electric Co.,Ltd. + +OUI:549B12* + ID_OUI_FROM_DATABASE=Samsung Electronics + +OUI:549D85* + ID_OUI_FROM_DATABASE=EnerAccess inc + +OUI:54A04F* + ID_OUI_FROM_DATABASE=t-mac Technologies Ltd + +OUI:54A51B* + ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd + +OUI:54A9D4* + ID_OUI_FROM_DATABASE=Minibar Systems + +OUI:54B620* + ID_OUI_FROM_DATABASE=SUHDOL E&C Co.Ltd. + +OUI:54CDA7* + ID_OUI_FROM_DATABASE=Fujian Shenzhou Electronic Co.,Ltd + +OUI:54D0ED* + ID_OUI_FROM_DATABASE=AXIM Communications + +OUI:54D1B0* + ID_OUI_FROM_DATABASE=Universal Laser Systems, Inc + +OUI:54D46F* + ID_OUI_FROM_DATABASE=Cisco SPVTG + +OUI:54DF63* + ID_OUI_FROM_DATABASE=Intrakey technologies GmbH + +OUI:54E032* + ID_OUI_FROM_DATABASE=Juniper Networks + +OUI:54E63F* + ID_OUI_FROM_DATABASE=ShenZhen LingKeWeiEr Technology Co., Ltd. + +OUI:54E6FC* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO., LTD. + +OUI:54F5B6* + ID_OUI_FROM_DATABASE=ORIENTAL PACIFIC INTERNATIONAL LIMITED + +OUI:54F666* + ID_OUI_FROM_DATABASE=Berthold Technologies GmbH and Co.KG + +OUI:54FDBF* + ID_OUI_FROM_DATABASE=Scheidt & Bachmann GmbH + +OUI:580556* + ID_OUI_FROM_DATABASE=Elettronica GF S.r.L. + +OUI:5808FA* + ID_OUI_FROM_DATABASE=Fiber Optic & telecommunication INC. + +OUI:5809E5* + ID_OUI_FROM_DATABASE=Kivic Inc. + +OUI:581243* + ID_OUI_FROM_DATABASE=AcSiP Technology Corp. + +OUI:581626* + ID_OUI_FROM_DATABASE=Avaya, Inc + +OUI:58170C* + ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications AB + +OUI:581D91* + ID_OUI_FROM_DATABASE=Advanced Mobile Telecom co.,ltd. + +OUI:581FAA* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:581FEF* + ID_OUI_FROM_DATABASE=Tuttnaer LTD + +OUI:582EFE* + ID_OUI_FROM_DATABASE=Lighting Science Group + +OUI:582F42* + ID_OUI_FROM_DATABASE=Universal Electric Corporation + +OUI:58343B* + ID_OUI_FROM_DATABASE=Glovast Technology Ltd. + +OUI:5835D9* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:583CC6* + ID_OUI_FROM_DATABASE=Omneality Ltd. + +OUI:5842E4* + ID_OUI_FROM_DATABASE=Sigma International General Medical Apparatus, LLC. + +OUI:5846E1* + ID_OUI_FROM_DATABASE=Baxter Healthcare + +OUI:5848C0* + ID_OUI_FROM_DATABASE=COFLEC + +OUI:5849BA* + ID_OUI_FROM_DATABASE=Chitai Electronic Corp. + +OUI:584C19* + ID_OUI_FROM_DATABASE=Chongqing Guohong Technology Development Company Limited + +OUI:584CEE* + ID_OUI_FROM_DATABASE=Digital One Technologies, Limited + +OUI:585076* + ID_OUI_FROM_DATABASE=Linear Equipamentos Eletronicos SA + +OUI:5850E6* + ID_OUI_FROM_DATABASE=Best Buy Corporation + +OUI:5855CA* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:58570D* + ID_OUI_FROM_DATABASE=Danfoss Solar Inverters + +OUI:5865E6* + ID_OUI_FROM_DATABASE=INFOMARK CO., LTD. + +OUI:5866BA* + ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited + +OUI:58671A* + ID_OUI_FROM_DATABASE=BARNES&NOBLE.COM + +OUI:58677F* + ID_OUI_FROM_DATABASE=Clare Controls Inc. + +OUI:58696C* + ID_OUI_FROM_DATABASE=Fujian Ruijie Networks co, ltd + +OUI:5869F9* + ID_OUI_FROM_DATABASE=Fusion Transactive Ltd. + +OUI:586D8F* + ID_OUI_FROM_DATABASE=Cisco-Linksys, LLC + +OUI:587521* + ID_OUI_FROM_DATABASE=CJSC RTSoft + +OUI:587675* + ID_OUI_FROM_DATABASE=Beijing ECHO Technologies Co.,Ltd + +OUI:587FC8* + ID_OUI_FROM_DATABASE=S2M + +OUI:5884E4* + ID_OUI_FROM_DATABASE=IP500 Alliance e.V. + +OUI:58874C* + ID_OUI_FROM_DATABASE=LITE-ON CLEAN ENERGY TECHNOLOGY CORP. + +OUI:5887E2* + ID_OUI_FROM_DATABASE=Shenzhen Coship Electronics Co., Ltd. + +OUI:588D09* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:5891CF* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:58920D* + ID_OUI_FROM_DATABASE=Kinetic Avionics Limited + +OUI:589396* + ID_OUI_FROM_DATABASE=Ruckus Wireless + +OUI:58946B* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:5894CF* + ID_OUI_FROM_DATABASE=Vertex Standard LMR, Inc. + +OUI:58971E* + ID_OUI_FROM_DATABASE=Cisco + +OUI:589835* + ID_OUI_FROM_DATABASE=Technicolor + +OUI:58986F* + ID_OUI_FROM_DATABASE=Revolution Display + +OUI:58A76F* + ID_OUI_FROM_DATABASE=iD corporation + +OUI:58B035* + ID_OUI_FROM_DATABASE=Apple, Inc + +OUI:58B0D4* + ID_OUI_FROM_DATABASE=ZuniData Systems Inc. + +OUI:58B9E1* + ID_OUI_FROM_DATABASE=Crystalfontz America, Inc. + +OUI:58BC27* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:58BDA3* + ID_OUI_FROM_DATABASE=Nintendo Co., Ltd. + +OUI:58BFEA* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:58C232* + ID_OUI_FROM_DATABASE=NEC Corporation + +OUI:58C38B* + ID_OUI_FROM_DATABASE=Samsung Electronics + +OUI:58CF4B* + ID_OUI_FROM_DATABASE=Lufkin Industries + +OUI:58D071* + ID_OUI_FROM_DATABASE=BW Broadcast + +OUI:58D08F* + ID_OUI_FROM_DATABASE=IEEE 1904.1 Working Group + +OUI:58D6D3* + ID_OUI_FROM_DATABASE=Dairy Cheq Inc + +OUI:58DB8D* + ID_OUI_FROM_DATABASE=Fast Co., Ltd. + +OUI:58E476* + ID_OUI_FROM_DATABASE=CENTRON COMMUNICATIONS TECHNOLOGIES FUJIAN CO.,LTD + +OUI:58E636* + ID_OUI_FROM_DATABASE=EVRsafe Technologies + +OUI:58E747* + ID_OUI_FROM_DATABASE=Deltanet AG + +OUI:58E808* + ID_OUI_FROM_DATABASE=AUTONICS CORPORATION + +OUI:58EB14* + ID_OUI_FROM_DATABASE=Proteus Digital Health + +OUI:58ECE1* + ID_OUI_FROM_DATABASE=Newport Corporation + +OUI:58EECE* + ID_OUI_FROM_DATABASE=Icon Time Systems + +OUI:58F67B* + ID_OUI_FROM_DATABASE=Xia Men UnionCore Technology LTD. + +OUI:58F6BF* + ID_OUI_FROM_DATABASE=Kyoto University + +OUI:58F98E* + ID_OUI_FROM_DATABASE=SECUDOS GmbH + +OUI:58FD20* + ID_OUI_FROM_DATABASE=Bravida Sakerhet AB + +OUI:5C076F* + ID_OUI_FROM_DATABASE=Thought Creator + +OUI:5C0A5B* + ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO-MECHANICS CO., LTD. + +OUI:5C0CBB* + ID_OUI_FROM_DATABASE=CELIZION Inc. + +OUI:5C0E8B* + ID_OUI_FROM_DATABASE=Motorola + +OUI:5C1437* + ID_OUI_FROM_DATABASE=Thyssenkrupp Aufzugswerke GmbH + +OUI:5C16C7* + ID_OUI_FROM_DATABASE=Big Switch Networks + +OUI:5C1737* + ID_OUI_FROM_DATABASE=I-View Now, LLC. + +OUI:5C17D3* + ID_OUI_FROM_DATABASE=LGE + +OUI:5C18B5* + ID_OUI_FROM_DATABASE=Talon Communications + +OUI:5C20D0* + ID_OUI_FROM_DATABASE=Asoni Communication Co., Ltd. + +OUI:5C2479* + ID_OUI_FROM_DATABASE=Baltech AG + +OUI:5C260A* + ID_OUI_FROM_DATABASE=Dell Inc. + +OUI:5C338E* + ID_OUI_FROM_DATABASE=Alpha Networkc Inc. + +OUI:5C353B* + ID_OUI_FROM_DATABASE=Compal Broadband Networks Inc. + +OUI:5C35DA* + ID_OUI_FROM_DATABASE=There Corporation Oy + +OUI:5C38E0* + ID_OUI_FROM_DATABASE=Shanghai Super Electronics Technology Co.,LTD + +OUI:5C4058* + ID_OUI_FROM_DATABASE=Jefferson Audio Video Systems, Inc. + +OUI:5C43D2* + ID_OUI_FROM_DATABASE=HAZEMEYER + +OUI:5C4A26* + ID_OUI_FROM_DATABASE=Enguity Technology Corp + +OUI:5C4CA9* + ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd + +OUI:5C5015* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:5C514F* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:5C56ED* + ID_OUI_FROM_DATABASE=3pleplay Electronics Private Limited + +OUI:5C571A* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + +OUI:5C57C8* + ID_OUI_FROM_DATABASE=Nokia Corporation + +OUI:5C5948* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:5C5EAB* + ID_OUI_FROM_DATABASE=Juniper Networks + +OUI:5C63BF* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO., LTD. + +OUI:5C6984* + ID_OUI_FROM_DATABASE=NUVICO + +OUI:5C6A7D* + ID_OUI_FROM_DATABASE=KENTKART EGE ELEKTRONIK SAN. VE TIC. LTD. STI. + +OUI:5C6B32* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:5C6D20* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + +OUI:5C6F4F* + ID_OUI_FROM_DATABASE=S.A. SISTEL + +OUI:5C7757* + ID_OUI_FROM_DATABASE=Haivision Network Video + +OUI:5C7D5E* + ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd + +OUI:5C864A* + ID_OUI_FROM_DATABASE=Secret Labs LLC + +OUI:5C8778* + ID_OUI_FROM_DATABASE=Cybertelbridge co.,ltd + +OUI:5C89D4* + ID_OUI_FROM_DATABASE=Beijing Banner Electric Co.,Ltd + +OUI:5C95AE* + ID_OUI_FROM_DATABASE=Apple Inc + +OUI:5C969D* + ID_OUI_FROM_DATABASE=Apple + +OUI:5C9AD8* + ID_OUI_FROM_DATABASE=Fujitsu Limited + +OUI:5CA39D* + ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO-MECHANICS CO., LTD. + +OUI:5CAC4C* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + +OUI:5CB524* + ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications AB + +OUI:5CBD9E* + ID_OUI_FROM_DATABASE=HONGKONG MIRACLE EAGLE TECHNOLOGY(GROUP) LIMITED + +OUI:5CC213* + ID_OUI_FROM_DATABASE=Fr. Sauter AG + +OUI:5CC6D0* + ID_OUI_FROM_DATABASE=Skyworth Digital technology(shenzhen)co.ltd. + +OUI:5CC9D3* + ID_OUI_FROM_DATABASE=PALLADIUM ENERGY ELETRONICA DA AMAZONIA LTDA + +OUI:5CCA32* + ID_OUI_FROM_DATABASE=Theben AG + +OUI:5CCEAD* + ID_OUI_FROM_DATABASE=CDYNE Corporation + +OUI:5CD135* + ID_OUI_FROM_DATABASE=Xtreme Power Systems + +OUI:5CD2E4* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:5CD41B* + ID_OUI_FROM_DATABASE=UCZOON Technology Co., LTD + +OUI:5CD4AB* + ID_OUI_FROM_DATABASE=Zektor + +OUI:5CD998* + ID_OUI_FROM_DATABASE=D-Link Corporation + +OUI:5CDAD4* + ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd. + +OUI:5CE0CA* + ID_OUI_FROM_DATABASE=FeiTian United (Beijing) System Technology Co., Ltd. + +OUI:5CE0F6* + ID_OUI_FROM_DATABASE=NIC.br- Nucleo de Informacao e Coordenacao do Ponto BR + +OUI:5CE223* + ID_OUI_FROM_DATABASE=Delphin Technology AG + +OUI:5CE286* + ID_OUI_FROM_DATABASE=Nortel Networks + +OUI:5CE2F4* + ID_OUI_FROM_DATABASE=AcSiP Technology Corp. + +OUI:5CE8EB* + ID_OUI_FROM_DATABASE=Samsung Electronics + +OUI:5CEB4E* + ID_OUI_FROM_DATABASE=R. STAHL HMI Systems GmbH + +OUI:5CEE79* + ID_OUI_FROM_DATABASE=Global Digitech Co LTD + +OUI:5CF207* + ID_OUI_FROM_DATABASE=Speco Technologies + +OUI:5CF3FC* + ID_OUI_FROM_DATABASE=IBM Corp + +OUI:5CF9DD* + ID_OUI_FROM_DATABASE=Dell Inc + +OUI:5CFF35* + ID_OUI_FROM_DATABASE=Wistron Corporation + +OUI:6002B4* + ID_OUI_FROM_DATABASE=Wistron NeWeb Corp. + +OUI:600F77* + ID_OUI_FROM_DATABASE=SilverPlus, Inc + +OUI:601199* + ID_OUI_FROM_DATABASE=Data-Tester Inc. + +OUI:601283* + ID_OUI_FROM_DATABASE=Soluciones Tecnologicas para la Salud y el Bienestar SA + +OUI:6015C7* + ID_OUI_FROM_DATABASE=IdaTech + +OUI:60190C* + ID_OUI_FROM_DATABASE=RRAMAC + +OUI:601929* + ID_OUI_FROM_DATABASE=VOLTRONIC POWER TECHNOLOGY(SHENZHEN) CORP. + +OUI:601D0F* + ID_OUI_FROM_DATABASE=Midnite Solar + +OUI:6021C0* + ID_OUI_FROM_DATABASE=Murata Manufactuaring Co.,Ltd. + +OUI:602A54* + ID_OUI_FROM_DATABASE=CardioTek B.V. + +OUI:602AD0* + ID_OUI_FROM_DATABASE=Cisco SPVTG + +OUI:6032F0* + ID_OUI_FROM_DATABASE=Mplus technology + +OUI:60334B* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:603553* + ID_OUI_FROM_DATABASE=Buwon Technology + +OUI:6036DD* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:60380E* + ID_OUI_FROM_DATABASE=Alps Electric Co., + +OUI:60391F* + ID_OUI_FROM_DATABASE=ABB Ltd + +OUI:603FC5* + ID_OUI_FROM_DATABASE=COX CO., LTD + +OUI:6044F5* + ID_OUI_FROM_DATABASE=Easy Digital Ltd. + +OUI:60455E* + ID_OUI_FROM_DATABASE=Liptel s.r.o. + +OUI:6045BD* + ID_OUI_FROM_DATABASE=Microsoft + +OUI:604616* + ID_OUI_FROM_DATABASE=XIAMEN VANN INTELLIGENT CO., LTD + +OUI:6052D0* + ID_OUI_FROM_DATABASE=FACTS Engineering + +OUI:605464* + ID_OUI_FROM_DATABASE=Eyedro Green Solutions Inc. + +OUI:6063FD* + ID_OUI_FROM_DATABASE=Transcend Communication Beijing Co.,Ltd. + +OUI:606720* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:606BBD* + ID_OUI_FROM_DATABASE=Samsung Electronics Co., LTD + +OUI:606C66* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:60735C* + ID_OUI_FROM_DATABASE=Cisco + +OUI:60748D* + ID_OUI_FROM_DATABASE=Atmaca Elektronik + +OUI:607688* + ID_OUI_FROM_DATABASE=Velodyne + +OUI:6083B2* + ID_OUI_FROM_DATABASE=GkWare e.K. + +OUI:60843B* + ID_OUI_FROM_DATABASE=Soladigm, Inc. + +OUI:608645* + ID_OUI_FROM_DATABASE=Avery Weigh-Tronix, LLC + +OUI:60893C* + ID_OUI_FROM_DATABASE=Thermo Fisher Scientific P.O.A. + +OUI:6089B1* + ID_OUI_FROM_DATABASE=Key Digital Systems + +OUI:6089B7* + ID_OUI_FROM_DATABASE=KAEL MÜHENDİSLİK ELEKTRONİK TİCARET SANAYİ LİMİTED ŞİRKETİ + +OUI:608C2B* + ID_OUI_FROM_DATABASE=Hanson Technology + +OUI:608D17* + ID_OUI_FROM_DATABASE=Sentrus Government Systems Division, Inc + +OUI:609084* + ID_OUI_FROM_DATABASE=DSSD Inc + +OUI:609AA4* + ID_OUI_FROM_DATABASE=GVI SECURITY INC. + +OUI:609E64* + ID_OUI_FROM_DATABASE=Vivonic GmbH + +OUI:609F9D* + ID_OUI_FROM_DATABASE=CloudSwitch + +OUI:60A10A* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:60A44C* + ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. + +OUI:60B185* + ID_OUI_FROM_DATABASE=ATH system + +OUI:60B3C4* + ID_OUI_FROM_DATABASE=Elber Srl + +OUI:60B606* + ID_OUI_FROM_DATABASE=Phorus + +OUI:60B933* + ID_OUI_FROM_DATABASE=Deutron Electronics Corp. + +OUI:60B982* + ID_OUI_FROM_DATABASE=RO.VE.R. Laboratories S.p.A. + +OUI:60BB0C* + ID_OUI_FROM_DATABASE=Beijing HuaqinWorld Technology Co,Ltd + +OUI:60BC4C* + ID_OUI_FROM_DATABASE=EWM Hightec Welding GmbH + +OUI:60BD91* + ID_OUI_FROM_DATABASE=Move Innovation + +OUI:60C547* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:60C5A8* + ID_OUI_FROM_DATABASE=Beijing LT Honway Technology Co.,Ltd + +OUI:60C980* + ID_OUI_FROM_DATABASE=Trymus + +OUI:60CBFB* + ID_OUI_FROM_DATABASE=AirScape Inc. + +OUI:60CDC5* + ID_OUI_FROM_DATABASE=Taiwan Carol Electronics., Ltd + +OUI:60D0A9* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:60D1AA* + ID_OUI_FROM_DATABASE=Vishal Telecommunications Pvt Ltd + +OUI:60D2B9* + ID_OUI_FROM_DATABASE=REALAND BIO CO., LTD. + +OUI:60D30A* + ID_OUI_FROM_DATABASE=Quatius Limited + +OUI:60D819* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + +OUI:60DA23* + ID_OUI_FROM_DATABASE=Estech Co.,Ltd + +OUI:60DE44* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +OUI:60E956* + ID_OUI_FROM_DATABASE=Ayla Networks, Inc + +OUI:60EB69* + ID_OUI_FROM_DATABASE=Quanta computer Inc. + +OUI:60F13D* + ID_OUI_FROM_DATABASE=JABLOCOM s.r.o. + +OUI:60F281* + ID_OUI_FROM_DATABASE=TRANWO TECHNOLOGY CO., LTD. + +OUI:60F2EF* + ID_OUI_FROM_DATABASE=VisionVera International Co., Ltd. + +OUI:60F3DA* + ID_OUI_FROM_DATABASE=Logic Way GmbH + +OUI:60F494* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + +OUI:60F59C* + ID_OUI_FROM_DATABASE=CRU-Dataport + +OUI:60F673* + ID_OUI_FROM_DATABASE=TERUMO CORPORATION + +OUI:60FACD* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:60FB42* + ID_OUI_FROM_DATABASE=Apple, Inc + +OUI:6400F1* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:64094C* + ID_OUI_FROM_DATABASE=Beijing Superbee Wireless Technology Co.,Ltd + +OUI:640E36* + ID_OUI_FROM_DATABASE=TAZTAG + +OUI:640E94* + ID_OUI_FROM_DATABASE=Pluribus Networks, Inc. + +OUI:640F28* + ID_OUI_FROM_DATABASE=2wire + +OUI:641084* + ID_OUI_FROM_DATABASE=HEXIUM Technical Development Co., Ltd. + +OUI:64168D* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:6416F0* + ID_OUI_FROM_DATABASE=Shehzhen Huawei Communication Technologies Co., Ltd. + +OUI:641A22* + ID_OUI_FROM_DATABASE=Heliospectra/Woodhill Investments + +OUI:641C67* + ID_OUI_FROM_DATABASE=DIGIBRAS INDUSTRIA DO BRASILS/A + +OUI:641E81* + ID_OUI_FROM_DATABASE=Dowslake Microsystems + +OUI:64200C* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:642216* + ID_OUI_FROM_DATABASE=Shandong Taixin Electronic co.,Ltd + +OUI:642400* + ID_OUI_FROM_DATABASE=Xorcom Ltd. + +OUI:642737* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + +OUI:642DB7* + ID_OUI_FROM_DATABASE=SEUNGIL ELECTRONICS + +OUI:643150* + ID_OUI_FROM_DATABASE=Hewlett-Packard Company + +OUI:64317E* + ID_OUI_FROM_DATABASE=Dexin Corporation + +OUI:643409* + ID_OUI_FROM_DATABASE=BITwave Pte Ltd + +OUI:644346* + ID_OUI_FROM_DATABASE=GuangDong Quick Network Computer CO.,LTD + +OUI:644BC3* + ID_OUI_FROM_DATABASE=Shanghai WOASiS Telecommunications Ltd., Co. + +OUI:644BF0* + ID_OUI_FROM_DATABASE=CalDigit, Inc + +OUI:644D70* + ID_OUI_FROM_DATABASE=dSPACE GmbH + +OUI:644F74* + ID_OUI_FROM_DATABASE=LENUS Co., Ltd. + +OUI:64517E* + ID_OUI_FROM_DATABASE=LONG BEN (DONGGUAN) ELECTRONIC TECHNOLOGY CO.,LTD. + +OUI:645299* + ID_OUI_FROM_DATABASE=Chamberlain + +OUI:64535D* + ID_OUI_FROM_DATABASE=Frauscher Sensortechnik + +OUI:645422* + ID_OUI_FROM_DATABASE=Equinox Payments + +OUI:645563* + ID_OUI_FROM_DATABASE=Intelight Inc. + +OUI:64557F* + ID_OUI_FROM_DATABASE=NSFOCUS Information Technology Co., Ltd. + +OUI:645A04* + ID_OUI_FROM_DATABASE=Chicony Electronics Co., Ltd. + +OUI:645DD7* + ID_OUI_FROM_DATABASE=Shenzhen Lifesense Medical Electronics Co., Ltd. + +OUI:645EBE* + ID_OUI_FROM_DATABASE=Yahoo! JAPAN + +OUI:645FFF* + ID_OUI_FROM_DATABASE=Nicolet Neuro + +OUI:646223* + ID_OUI_FROM_DATABASE=Cellient Co., Ltd. + +OUI:6465C0* + ID_OUI_FROM_DATABASE=Nuvon, Inc + +OUI:6466B3* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO., LTD. + +OUI:646707* + ID_OUI_FROM_DATABASE=Beijing Omnific Technology, Ltd. + +OUI:64680C* + ID_OUI_FROM_DATABASE=COMTREND + +OUI:6469BC* + ID_OUI_FROM_DATABASE=Hytera Communications Co .,ltd + +OUI:646E6C* + ID_OUI_FROM_DATABASE=Radio Datacom LLC + +OUI:647002* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO., LTD. + +OUI:6473E2* + ID_OUI_FROM_DATABASE=Arbiter Systems, Inc. + +OUI:647657* + ID_OUI_FROM_DATABASE=Innovative Security Designs + +OUI:647791* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:647BD4* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:647C34* + ID_OUI_FROM_DATABASE=Ubee Interactive Corp. + +OUI:647D81* + ID_OUI_FROM_DATABASE=YOKOTA INDUSTRIAL CO,.LTD + +OUI:647FDA* + ID_OUI_FROM_DATABASE=TEKTELIC Communications Inc. + +OUI:64808B* + ID_OUI_FROM_DATABASE=VG Controls, Inc. + +OUI:648099* + ID_OUI_FROM_DATABASE=Intel Corporation + +OUI:648125* + ID_OUI_FROM_DATABASE=Alphatron Marine BV + +OUI:648788* + ID_OUI_FROM_DATABASE=Juniper Networks + +OUI:6487D7* + ID_OUI_FROM_DATABASE=ADB Broadband Italia + +OUI:64995D* + ID_OUI_FROM_DATABASE=LGE + +OUI:649968* + ID_OUI_FROM_DATABASE=Elentec + +OUI:6499A0* + ID_OUI_FROM_DATABASE=AG Elektronik AB + +OUI:649B24* + ID_OUI_FROM_DATABASE=V Technology Co., Ltd. + +OUI:649C8E* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:649EF3* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:649FF7* + ID_OUI_FROM_DATABASE=Kone OYj + +OUI:64A0E7* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:64A232* + ID_OUI_FROM_DATABASE=OOO Samlight + +OUI:64A341* + ID_OUI_FROM_DATABASE=Wonderlan (Beijing) Technology Co., Ltd. + +OUI:64A3CB* + ID_OUI_FROM_DATABASE=Apple + +OUI:64A769* + ID_OUI_FROM_DATABASE=HTC Corporation + +OUI:64A837* + ID_OUI_FROM_DATABASE=Juni Korea Co., Ltd + +OUI:64AE0C* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:64AE88* + ID_OUI_FROM_DATABASE=Polytec GmbH + +OUI:64B64A* + ID_OUI_FROM_DATABASE=ViVOtech, Inc. + +OUI:64B9E8* + ID_OUI_FROM_DATABASE=Apple, Inc + +OUI:64BC11* + ID_OUI_FROM_DATABASE=CombiQ AB + +OUI:64C5AA* + ID_OUI_FROM_DATABASE=South African Broadcasting Corporation + +OUI:64C6AF* + ID_OUI_FROM_DATABASE=AXERRA Networks Ltd + +OUI:64C944* + ID_OUI_FROM_DATABASE=LARK Technologies, Inc + +OUI:64D02D* + ID_OUI_FROM_DATABASE=Next Generation Integration (NGI) + +OUI:64D1A3* + ID_OUI_FROM_DATABASE=Sitecom Europe BV + +OUI:64D241* + ID_OUI_FROM_DATABASE=Keith & Koep GmbH + +OUI:64D4DA* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:64D814* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:64D912* + ID_OUI_FROM_DATABASE=Solidica, Inc. + +OUI:64D989* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:64DB18* + ID_OUI_FROM_DATABASE=OpenPattern + +OUI:64DC01* + ID_OUI_FROM_DATABASE=Static Systems Group PLC + +OUI:64DE1C* + ID_OUI_FROM_DATABASE=Kingnetic Pte Ltd + +OUI:64E161* + ID_OUI_FROM_DATABASE=DEP Corp. + +OUI:64E682* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:64E84F* + ID_OUI_FROM_DATABASE=Serialway Communication Technology Co. Ltd + +OUI:64E8E6* + ID_OUI_FROM_DATABASE=global moisture management system + +OUI:64ED57* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:64ED62* + ID_OUI_FROM_DATABASE=WOORI SYSTEMS Co., Ltd + +OUI:64F242* + ID_OUI_FROM_DATABASE=Gerdes Aktiengesellschaft + +OUI:64F50E* + ID_OUI_FROM_DATABASE=Kinion Technology Company Limited + +OUI:64F970* + ID_OUI_FROM_DATABASE=Kenade Electronics Technology Co.,LTD. + +OUI:64F987* + ID_OUI_FROM_DATABASE=Avvasi Inc. + +OUI:64FC8C* + ID_OUI_FROM_DATABASE=Zonar Systems + +OUI:6805CA* + ID_OUI_FROM_DATABASE=Intel Corporation + +OUI:680927* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:68122D* + ID_OUI_FROM_DATABASE=Special Instrument Development Co., Ltd. + +OUI:6815D3* + ID_OUI_FROM_DATABASE=Zaklady Elektroniki i Mechaniki Precyzyjnej R&G S.A. + +OUI:681605* + ID_OUI_FROM_DATABASE=Systems And Electronic Development FZCO + +OUI:681729* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:681AB2* + ID_OUI_FROM_DATABASE=zte corporation + +OUI:681CA2* + ID_OUI_FROM_DATABASE=Rosewill Inc. + +OUI:681E8B* + ID_OUI_FROM_DATABASE=InfoSight Corporation + +OUI:681FD8* + ID_OUI_FROM_DATABASE=Advanced Telemetry + +OUI:68234B* + ID_OUI_FROM_DATABASE=Nihon Dengyo Kousaku + +OUI:683B1E* + ID_OUI_FROM_DATABASE=Countwise LTD + +OUI:684352* + ID_OUI_FROM_DATABASE=Bhuu Limited + +OUI:684B88* + ID_OUI_FROM_DATABASE=Galtronics Telemetry Inc. + +OUI:684CA8* + ID_OUI_FROM_DATABASE=Shenzhen Herotel Tech. Co., Ltd. + +OUI:6851B7* + ID_OUI_FROM_DATABASE=PowerCloud Systems, Inc. + +OUI:6854F5* + ID_OUI_FROM_DATABASE=enLighted Inc + +OUI:68597F* + ID_OUI_FROM_DATABASE=Alcatel Lucent + +OUI:685B36* + ID_OUI_FROM_DATABASE=POWERTECH INDUSTRIAL CO., LTD. + +OUI:685D43* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:685E6B* + ID_OUI_FROM_DATABASE=PowerRay Co., Ltd. + +OUI:686359* + ID_OUI_FROM_DATABASE=Advanced Digital Broadcast SA + +OUI:6869F2* + ID_OUI_FROM_DATABASE=ComAp s.r.o. + +OUI:686E23* + ID_OUI_FROM_DATABASE=Wi3 Inc. + +OUI:687251* + ID_OUI_FROM_DATABASE=Ubiquiti Networks + +OUI:68784C* + ID_OUI_FROM_DATABASE=Nortel Networks + +OUI:687924* + ID_OUI_FROM_DATABASE=ELS-GmbH & Co. KG + +OUI:6879ED* + ID_OUI_FROM_DATABASE=SHARP Corporation + +OUI:687F74* + ID_OUI_FROM_DATABASE=Cisco-Linksys, LLC + +OUI:688470* + ID_OUI_FROM_DATABASE=eSSys Co.,Ltd + +OUI:688540* + ID_OUI_FROM_DATABASE=IGI Mobile, Inc. + +OUI:6886A7* + ID_OUI_FROM_DATABASE=Cisco + +OUI:6886E7* + ID_OUI_FROM_DATABASE=Orbotix, Inc. + +OUI:68876B* + ID_OUI_FROM_DATABASE=INQ Mobile Limited + +OUI:689234* + ID_OUI_FROM_DATABASE=Ruckus Wireless + +OUI:689423* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + +OUI:68967B* + ID_OUI_FROM_DATABASE=Apple Inc + +OUI:68974B* + ID_OUI_FROM_DATABASE=Shenzhen Costar Electronics Co. Ltd. + +OUI:689C5E* + ID_OUI_FROM_DATABASE=AcSiP Technology Corp. + +OUI:68A1B7* + ID_OUI_FROM_DATABASE=Honghao Mingchuan Technology (Beijing) CO.,Ltd. + +OUI:68A3C4* + ID_OUI_FROM_DATABASE=Liteon Technology Corporation + +OUI:68A40E* + ID_OUI_FROM_DATABASE=BSH Bosch and Siemens Home Appliances GmbH + +OUI:68A86D* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:68AAD2* + ID_OUI_FROM_DATABASE=DATECS LTD., + +OUI:68AB8A* + ID_OUI_FROM_DATABASE=RF IDeas + +OUI:68AF13* + ID_OUI_FROM_DATABASE=Futura Mobility + +OUI:68B43A* + ID_OUI_FROM_DATABASE=WaterFurnace International, Inc. + +OUI:68B599* + ID_OUI_FROM_DATABASE=Hewlett-Packard Company + +OUI:68B6FC* + ID_OUI_FROM_DATABASE=Hitron Technologies. Inc + +OUI:68B8D9* + ID_OUI_FROM_DATABASE=Act KDE, Inc. + +OUI:68BC0C* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:68BDAB* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:68CA00* + ID_OUI_FROM_DATABASE=Octopus Systems Limited + +OUI:68CC9C* + ID_OUI_FROM_DATABASE=Mine Site Technologies + +OUI:68CD0F* + ID_OUI_FROM_DATABASE=U Tek Company Limited + +OUI:68CE4E* + ID_OUI_FROM_DATABASE=L-3 Communications Infrared Products + +OUI:68D1FD* + ID_OUI_FROM_DATABASE=Shenzhen Trimax Technology Co.,Ltd + +OUI:68D925* + ID_OUI_FROM_DATABASE=ProSys Development Services + +OUI:68DB96* + ID_OUI_FROM_DATABASE=OPWILL Technologies CO .,LTD + +OUI:68DCE8* + ID_OUI_FROM_DATABASE=PacketStorm Communications + +OUI:68E41F* + ID_OUI_FROM_DATABASE=Unglaube Identech GmbH + +OUI:68EBAE* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:68EBC5* + ID_OUI_FROM_DATABASE=Angstrem Telecom + +OUI:68ED43* + ID_OUI_FROM_DATABASE=Research In Motion + +OUI:68EFBD* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:68F125* + ID_OUI_FROM_DATABASE=Data Controls Inc. + +OUI:68F895* + ID_OUI_FROM_DATABASE=Redflow Limited + +OUI:68FB95* + ID_OUI_FROM_DATABASE=Generalplus Technology Inc. + +OUI:6C0460* + ID_OUI_FROM_DATABASE=RBH Access Technologies Inc. + +OUI:6C0E0D* + ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications AB + +OUI:6C0F6A* + ID_OUI_FROM_DATABASE=JDC Tech Co., Ltd. + +OUI:6C1811* + ID_OUI_FROM_DATABASE=Decatur Electronics + +OUI:6C2056* + ID_OUI_FROM_DATABASE=Cisco + +OUI:6C22AB* + ID_OUI_FROM_DATABASE=Ainsworth Game Technology + +OUI:6C23B9* + ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications AB + +OUI:6C2995* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:6C2E33* + ID_OUI_FROM_DATABASE=Accelink Technologies Co.,Ltd. + +OUI:6C2E85* + ID_OUI_FROM_DATABASE=SAGEMCOM + +OUI:6C32DE* + ID_OUI_FROM_DATABASE=Indieon Technologies Pvt. Ltd. + +OUI:6C33A9* + ID_OUI_FROM_DATABASE=Magicjack LP + +OUI:6C391D* + ID_OUI_FROM_DATABASE=Beijing ZhongHuaHun Network Information center + +OUI:6C3A84* + ID_OUI_FROM_DATABASE=Shenzhen Aero-Startech. Co.Ltd + +OUI:6C3BE5* + ID_OUI_FROM_DATABASE=Hewlett Packard + +OUI:6C3E6D* + ID_OUI_FROM_DATABASE=Apple Inc + +OUI:6C3E9C* + ID_OUI_FROM_DATABASE=KE Knestel Elektronik GmbH + +OUI:6C40C6* + ID_OUI_FROM_DATABASE=Nimbus Data Systems, Inc. + +OUI:6C504D* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:6C5A34* + ID_OUI_FROM_DATABASE=Shenzhen Haitianxiong Electronic Co., Ltd. + +OUI:6C5CDE* + ID_OUI_FROM_DATABASE=SunReports, Inc. + +OUI:6C5D63* + ID_OUI_FROM_DATABASE=ShenZhen Rapoo Technology Co., Ltd. + +OUI:6C5E7A* + ID_OUI_FROM_DATABASE=Ubiquitous Internet Telecom Co., Ltd + +OUI:6C626D* + ID_OUI_FROM_DATABASE=Micro-Star INT'L CO., LTD + +OUI:6C6F18* + ID_OUI_FROM_DATABASE=Stereotaxis, Inc. + +OUI:6C7039* + ID_OUI_FROM_DATABASE=Novar GmbH + +OUI:6C71D9* + ID_OUI_FROM_DATABASE=AzureWave Technologies, Inc + +OUI:6C81FE* + ID_OUI_FROM_DATABASE=Mitsuba Corporation + +OUI:6C8336* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:6C8814* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:6C8CDB* + ID_OUI_FROM_DATABASE=Otus Technologies Ltd + +OUI:6C8D65* + ID_OUI_FROM_DATABASE=Wireless Glue Networks, Inc. + +OUI:6C92BF* + ID_OUI_FROM_DATABASE=Inspur Electronic Information Industry Co.,Ltd. + +OUI:6C9AC9* + ID_OUI_FROM_DATABASE=Valentine Research, Inc. + +OUI:6C9B02* + ID_OUI_FROM_DATABASE=Nokia Corporation + +OUI:6C9CE9* + ID_OUI_FROM_DATABASE=Nimble Storage + +OUI:6C9CED* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:6CA682* + ID_OUI_FROM_DATABASE=EDAM information & communications + +OUI:6CA780* + ID_OUI_FROM_DATABASE=Nokia Corporation + +OUI:6CA906* + ID_OUI_FROM_DATABASE=Telefield Ltd + +OUI:6CA96F* + ID_OUI_FROM_DATABASE=TransPacket AS + +OUI:6CAB4D* + ID_OUI_FROM_DATABASE=Digital Payment Technologies + +OUI:6CAC60* + ID_OUI_FROM_DATABASE=Venetex Corp + +OUI:6CAD3F* + ID_OUI_FROM_DATABASE=Hubbell Building Automation, Inc. + +OUI:6CADEF* + ID_OUI_FROM_DATABASE=KZ Broadband Technologies, Ltd. + +OUI:6CAE8B* + ID_OUI_FROM_DATABASE=IBM Corporation + +OUI:6CB311* + ID_OUI_FROM_DATABASE=Shenzhen Lianrui Electronics Co.,Ltd + +OUI:6CBEE9* + ID_OUI_FROM_DATABASE=Alcatel-Lucent-IPD + +OUI:6CC1D2* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:6CC26B* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:6CD032* + ID_OUI_FROM_DATABASE=LG Electronics + +OUI:6CD146* + ID_OUI_FROM_DATABASE=Smartek d.o.o. + +OUI:6CD68A* + ID_OUI_FROM_DATABASE=LG Electronics Inc + +OUI:6CDC6A* + ID_OUI_FROM_DATABASE=Promethean Limited + +OUI:6CE0B0* + ID_OUI_FROM_DATABASE=SOUND4 + +OUI:6CE4CE* + ID_OUI_FROM_DATABASE=Villiger Security Solutions AG + +OUI:6CE873* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO., LTD. + +OUI:6CE907* + ID_OUI_FROM_DATABASE=Nokia Corporation + +OUI:6CE983* + ID_OUI_FROM_DATABASE=Gastron Co., LTD. + +OUI:6CF049* + ID_OUI_FROM_DATABASE=GIGA-BYTE TECHNOLOGY CO.,LTD. + +OUI:6CF373* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:6CF37F* + ID_OUI_FROM_DATABASE=Aruba Networks + +OUI:6CFDB9* + ID_OUI_FROM_DATABASE=Proware Technologies Co Ltd. + +OUI:6CFFBE* + ID_OUI_FROM_DATABASE=MPB Communications Inc. + +OUI:700258* + ID_OUI_FROM_DATABASE=01DB-METRAVIB + +OUI:700514* + ID_OUI_FROM_DATABASE=LG Electronics + +OUI:700BC0* + ID_OUI_FROM_DATABASE=Dewav Technology Company + +OUI:701124* + ID_OUI_FROM_DATABASE=Apple + +OUI:701404* + ID_OUI_FROM_DATABASE=Limited Liability Company "Research Center "Bresler" + +OUI:701A04* + ID_OUI_FROM_DATABASE=Liteon Tech Corp. + +OUI:701AED* + ID_OUI_FROM_DATABASE=ADVAS CO., LTD. + +OUI:702393* + ID_OUI_FROM_DATABASE=fos4X GmbH + +OUI:702526* + ID_OUI_FROM_DATABASE=Alcatel-Lucent + +OUI:702559* + ID_OUI_FROM_DATABASE=CyberTAN Technology, Inc. + +OUI:702B1D* + ID_OUI_FROM_DATABASE=E-Domus International Limited + +OUI:702F4B* + ID_OUI_FROM_DATABASE=PolyVision Inc. + +OUI:702F97* + ID_OUI_FROM_DATABASE=Aava Mobile Oy + +OUI:703018* + ID_OUI_FROM_DATABASE=Avaya, Inc + +OUI:703187* + ID_OUI_FROM_DATABASE=ACX GmbH + +OUI:7032D5* + ID_OUI_FROM_DATABASE=Athena Wireless Communications Inc + +OUI:703811* + ID_OUI_FROM_DATABASE=Invensys Rail + +OUI:7038EE* + ID_OUI_FROM_DATABASE=Avaya Inc + +OUI:703AD8* + ID_OUI_FROM_DATABASE=Shenzhen Afoundry Electronic Co., Ltd + +OUI:703C39* + ID_OUI_FROM_DATABASE=SEAWING Kft + +OUI:7041B7* + ID_OUI_FROM_DATABASE=Edwards Lifesciences LLC + +OUI:704642* + ID_OUI_FROM_DATABASE=CHYNG HONG ELECTRONIC CO., LTD. + +OUI:704AAE* + ID_OUI_FROM_DATABASE=Xstream Flow (Pty) Ltd + +OUI:704AE4* + ID_OUI_FROM_DATABASE=Rinstrum Pty Ltd + +OUI:7054D2* + ID_OUI_FROM_DATABASE=PEGATRON CORPORATION + +OUI:7054F5* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +OUI:705681* + ID_OUI_FROM_DATABASE=Apple Inc + +OUI:705812* + ID_OUI_FROM_DATABASE=Panasonic AVC Networks Company + +OUI:705AB6* + ID_OUI_FROM_DATABASE=COMPAL INFORMATION (KUNSHAN) CO., LTD. + +OUI:705CAD* + ID_OUI_FROM_DATABASE=Konami Gaming Inc + +OUI:705EAA* + ID_OUI_FROM_DATABASE=Action Target, Inc. + +OUI:706417* + ID_OUI_FROM_DATABASE=ORBIS TECNOLOGIA ELECTRICA S.A. + +OUI:706582* + ID_OUI_FROM_DATABASE=Suzhou Hanming Technologies Co., Ltd. + +OUI:70704C* + ID_OUI_FROM_DATABASE=Purple Communications, Inc + +OUI:7071BC* + ID_OUI_FROM_DATABASE=PEGATRON CORPORATION + +OUI:70723C* + ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd + +OUI:7072CF* + ID_OUI_FROM_DATABASE=EdgeCore Networks + +OUI:7073CB* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:7076DD* + ID_OUI_FROM_DATABASE=Oxyguard International A/S + +OUI:7076F0* + ID_OUI_FROM_DATABASE=LevelOne Communications (India) Private Limited + +OUI:707BE8* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +OUI:707E43* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:707EDE* + ID_OUI_FROM_DATABASE=NASTEC LTD. + +OUI:708105* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:70828E* + ID_OUI_FROM_DATABASE=OleumTech Corporation + +OUI:708B78* + ID_OUI_FROM_DATABASE=citygrow technology co., ltd + +OUI:7093F8* + ID_OUI_FROM_DATABASE=Space Monkey, Inc. + +OUI:709756* + ID_OUI_FROM_DATABASE=Happyelectronics Co.,Ltd + +OUI:709A0B* + ID_OUI_FROM_DATABASE=Italian Institute of Technology + +OUI:709BA5* + ID_OUI_FROM_DATABASE=Shenzhen Y&D Electronics Co.,LTD. + +OUI:709E86* + ID_OUI_FROM_DATABASE=X6D Limited + +OUI:70A191* + ID_OUI_FROM_DATABASE=Trendsetter Medical, LLC + +OUI:70A41C* + ID_OUI_FROM_DATABASE=Advanced Wireless Dynamics S.L. + +OUI:70A66A* + ID_OUI_FROM_DATABASE=Prox Dynamics AS + +OUI:70AAB2* + ID_OUI_FROM_DATABASE=Research In Motion + +OUI:70B035* + ID_OUI_FROM_DATABASE=Shenzhen Zowee Technology Co., Ltd + +OUI:70B08C* + ID_OUI_FROM_DATABASE=Shenou Communication Equipment Co.,Ltd + +OUI:70B265* + ID_OUI_FROM_DATABASE=Hiltron s.r.l. + +OUI:70B599* + ID_OUI_FROM_DATABASE=Embedded Technologies s.r.o. + +OUI:70B921* + ID_OUI_FROM_DATABASE=FiberHome Telecommunication Technologies CO.,LTD + +OUI:70CA9B* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:70CD60* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:70D4F2* + ID_OUI_FROM_DATABASE=RIM + +OUI:70D57E* + ID_OUI_FROM_DATABASE=Scalar Corporation + +OUI:70D5E7* + ID_OUI_FROM_DATABASE=Wellcore Corporation + +OUI:70D6B6* + ID_OUI_FROM_DATABASE=Metrum Technologies + +OUI:70D880* + ID_OUI_FROM_DATABASE=Upos System sp. z o.o. + +OUI:70DDA1* + ID_OUI_FROM_DATABASE=Tellabs + +OUI:70DEE2* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:70E139* + ID_OUI_FROM_DATABASE=3view Ltd + +OUI:70E24C* + ID_OUI_FROM_DATABASE=SAE IT-systems GmbH & Co. KG + +OUI:70E843* + ID_OUI_FROM_DATABASE=Beijing C&W Optical Communication Technology Co.,Ltd. + +OUI:70EE50* + ID_OUI_FROM_DATABASE=Netatmo + +OUI:70F1A1* + ID_OUI_FROM_DATABASE=Liteon Technology Corporation + +OUI:70F1E5* + ID_OUI_FROM_DATABASE=Xetawave LLC + +OUI:70F395* + ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co., Ltd. + +OUI:70F927* + ID_OUI_FROM_DATABASE=Samsung Electronics + +OUI:740ABC* + ID_OUI_FROM_DATABASE=JSJS Designs (Europe) Limited + +OUI:741489* + ID_OUI_FROM_DATABASE=SRT Wireless + +OUI:7415E2* + ID_OUI_FROM_DATABASE=Tri-Sen Systems Corporation + +OUI:741E93* + ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Tech.Co.,Ltd. + +OUI:74273C* + ID_OUI_FROM_DATABASE=ChangYang Technology (Nanjing) Co., LTD + +OUI:7427EA* + ID_OUI_FROM_DATABASE=Elitegroup Computer Systems Co., Ltd. + +OUI:742B0F* + ID_OUI_FROM_DATABASE=Infinidat Ltd. + +OUI:742D0A* + ID_OUI_FROM_DATABASE=Norfolk Elektronik AG + +OUI:742F68* + ID_OUI_FROM_DATABASE=Azurewave Technologies, Inc. + +OUI:743170* + ID_OUI_FROM_DATABASE=Arcadyan Technology Corporation + +OUI:743256* + ID_OUI_FROM_DATABASE=NT-ware Systemprg GmbH + +OUI:74372F* + ID_OUI_FROM_DATABASE=Tongfang Shenzhen Cloudcomputing Technology Co.,Ltd + +OUI:743889* + ID_OUI_FROM_DATABASE=ANNAX Anzeigesysteme GmbH + +OUI:744401* + ID_OUI_FROM_DATABASE=NETGEAR + +OUI:74458A* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:7446A0* + ID_OUI_FROM_DATABASE=Hewlett Packard + +OUI:744D79* + ID_OUI_FROM_DATABASE=Arrive Systems Inc. + +OUI:745327* + ID_OUI_FROM_DATABASE=COMMSEN CO., LIMITED + +OUI:745612* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:745798* + ID_OUI_FROM_DATABASE=TRUMPF Laser GmbH + Co. KG + +OUI:745E1C* + ID_OUI_FROM_DATABASE=PIONEER CORPORATION + +OUI:745F00* + ID_OUI_FROM_DATABASE=Samsung Semiconductor Inc. + +OUI:745FAE* + ID_OUI_FROM_DATABASE=TSL PPL + +OUI:7463DF* + ID_OUI_FROM_DATABASE=VTS GmbH + +OUI:7465D1* + ID_OUI_FROM_DATABASE=Atlinks + +OUI:746A89* + ID_OUI_FROM_DATABASE=Rezolt Corporation + +OUI:746B82* + ID_OUI_FROM_DATABASE=MOVEK + +OUI:7472F2* + ID_OUI_FROM_DATABASE=Chipsip Technology Co., Ltd. + +OUI:747818* + ID_OUI_FROM_DATABASE=ServiceAssure + +OUI:747B7A* + ID_OUI_FROM_DATABASE=ETH Inc. + +OUI:747DB6* + ID_OUI_FROM_DATABASE=Aliwei Communications, Inc + +OUI:747E1A* + ID_OUI_FROM_DATABASE=Red Embedded Design Limited + +OUI:747E2D* + ID_OUI_FROM_DATABASE=Beijing Thomson CITIC Digital Technology Co. LTD. + +OUI:74888B* + ID_OUI_FROM_DATABASE=ADB Broadband Italia + +OUI:748EF8* + ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc. + +OUI:749050* + ID_OUI_FROM_DATABASE=Renesas Electronics Corporation + +OUI:74911A* + ID_OUI_FROM_DATABASE=Ruckus Wireless + +OUI:7493A4* + ID_OUI_FROM_DATABASE=Zebra Technologies Corp. + +OUI:74943D* + ID_OUI_FROM_DATABASE=Hemisphere GPS + +OUI:749975* + ID_OUI_FROM_DATABASE=IBM Corporation + +OUI:749DDC* + ID_OUI_FROM_DATABASE=2Wire + +OUI:74A4A7* + ID_OUI_FROM_DATABASE=QRS Music Technologies, Inc. + +OUI:74A722* + ID_OUI_FROM_DATABASE=LG Electronics + +OUI:74AE76* + ID_OUI_FROM_DATABASE=iNovo Broadband, Inc. + +OUI:74B00C* + ID_OUI_FROM_DATABASE=Network Video Technologies, Inc + +OUI:74B9EB* + ID_OUI_FROM_DATABASE=Fujian JinQianMao Electronic Technology Co.,Ltd + +OUI:74BE08* + ID_OUI_FROM_DATABASE=ATEK Products, LLC + +OUI:74BFA1* + ID_OUI_FROM_DATABASE=HYUNTECK + +OUI:74CD0C* + ID_OUI_FROM_DATABASE=Smith Myers Communications Ltd. + +OUI:74CE56* + ID_OUI_FROM_DATABASE=Packet Force Technology Limited Company + +OUI:74D0DC* + ID_OUI_FROM_DATABASE=ERICSSON AB + +OUI:74D675* + ID_OUI_FROM_DATABASE=WYMA Tecnologia + +OUI:74D850* + ID_OUI_FROM_DATABASE=Evrisko Systems + +OUI:74DE2B* + ID_OUI_FROM_DATABASE=Liteon Technology Corporation + +OUI:74E06E* + ID_OUI_FROM_DATABASE=Ergophone GmbH + +OUI:74E1B6* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:74E2F5* + ID_OUI_FROM_DATABASE=Apple Inc + +OUI:74E424* + ID_OUI_FROM_DATABASE=APISTE CORPORATION + +OUI:74E50B* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:74E537* + ID_OUI_FROM_DATABASE=RADSPIN + +OUI:74E543* + ID_OUI_FROM_DATABASE=Liteon Technology Corporation + +OUI:74E7C6* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:74EA3A* + ID_OUI_FROM_DATABASE=TP-LINK Technologies Co.,Ltd. + +OUI:74ECF1* + ID_OUI_FROM_DATABASE=Acumen + +OUI:74F06D* + ID_OUI_FROM_DATABASE=AzureWave Technologies, Inc. + +OUI:74F07D* + ID_OUI_FROM_DATABASE=BnCOM Co.,Ltd + +OUI:74F612* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:74F726* + ID_OUI_FROM_DATABASE=Neuron Robotics + +OUI:74FDA0* + ID_OUI_FROM_DATABASE=Compupal (Group) Corporation + +OUI:74FE48* + ID_OUI_FROM_DATABASE=ADVANTECH CO., LTD. + +OUI:74FF7D* + ID_OUI_FROM_DATABASE=Wren Sound Systems, LLC + +OUI:78028F* + ID_OUI_FROM_DATABASE=Adaptive Spectrum and Signal Alignment (ASSIA), Inc. + +OUI:780738* + ID_OUI_FROM_DATABASE=Z.U.K. Elzab S.A. + +OUI:781185* + ID_OUI_FROM_DATABASE=NBS Payment Solutions Inc. + +OUI:7812B8* + ID_OUI_FROM_DATABASE=ORANTEK LIMITED + +OUI:781881* + ID_OUI_FROM_DATABASE=AzureWave Technologies, Inc. + +OUI:78192E* + ID_OUI_FROM_DATABASE=NASCENT Technology + +OUI:7819F7* + ID_OUI_FROM_DATABASE=Juniper Networks + +OUI:781C5A* + ID_OUI_FROM_DATABASE=SHARP Corporation + +OUI:781DBA* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +OUI:781DFD* + ID_OUI_FROM_DATABASE=Jabil Inc + +OUI:78223D* + ID_OUI_FROM_DATABASE=Affirmed Networks + +OUI:782544* + ID_OUI_FROM_DATABASE=Omnima Limited + +OUI:7825AD* + ID_OUI_FROM_DATABASE=SAMSUNG ELECTRONICS CO., LTD. + +OUI:782BCB* + ID_OUI_FROM_DATABASE=Dell Inc + +OUI:782EEF* + ID_OUI_FROM_DATABASE=Nokia Corporation + +OUI:7830E1* + ID_OUI_FROM_DATABASE=UltraClenz, LLC + +OUI:78324F* + ID_OUI_FROM_DATABASE=Millennium Group, Inc. + +OUI:783CE3* + ID_OUI_FROM_DATABASE=Kai-EE + +OUI:783F15* + ID_OUI_FROM_DATABASE=EasySYNC Ltd. + +OUI:784405* + ID_OUI_FROM_DATABASE=FUJITU(HONG KONG) ELECTRONIC Co.,LTD. + +OUI:784476* + ID_OUI_FROM_DATABASE=Zioncom technology co.,ltd + +OUI:7845C4* + ID_OUI_FROM_DATABASE=Dell Inc + +OUI:7846C4* + ID_OUI_FROM_DATABASE=DAEHAP HYPER-TECH + +OUI:78471D* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:78510C* + ID_OUI_FROM_DATABASE=LiveU Ltd. + +OUI:785262* + ID_OUI_FROM_DATABASE=Shenzhen Hojy Software Co., Ltd. + +OUI:785517* + ID_OUI_FROM_DATABASE=SankyuElectronics + +OUI:785712* + ID_OUI_FROM_DATABASE=Mobile Integration Workgroup + +OUI:78593E* + ID_OUI_FROM_DATABASE=RAFI GmbH & Co.KG + +OUI:78595E* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:785C72* + ID_OUI_FROM_DATABASE=Hioso Technology Co., Ltd. + +OUI:78617C* + ID_OUI_FROM_DATABASE=MITSUMI ELECTRIC CO.,LTD + +OUI:7866AE* + ID_OUI_FROM_DATABASE=ZTEC Instruments, Inc. + +OUI:786C1C* + ID_OUI_FROM_DATABASE=Apple + +OUI:787F62* + ID_OUI_FROM_DATABASE=GiK mbH + +OUI:78818F* + ID_OUI_FROM_DATABASE=Server Racks Australia Pty Ltd + +OUI:78843C* + ID_OUI_FROM_DATABASE=Sony Corporation + +OUI:7884EE* + ID_OUI_FROM_DATABASE=INDRA ESPACIO S.A. + +OUI:788973* + ID_OUI_FROM_DATABASE=CMC + +OUI:788C54* + ID_OUI_FROM_DATABASE=Enkom Technologies Ltd. + +OUI:78929C* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:7898FD* + ID_OUI_FROM_DATABASE=Q9 Networks Inc. + +OUI:78995C* + ID_OUI_FROM_DATABASE=Nationz Technologies Inc + +OUI:78998F* + ID_OUI_FROM_DATABASE=MEDILINE ITALIA SRL + +OUI:789ED0* + ID_OUI_FROM_DATABASE=Samsung Electronics + +OUI:789F87* + ID_OUI_FROM_DATABASE=Siemens AG I IA PP PRM + +OUI:78A051* + ID_OUI_FROM_DATABASE=iiNet Labs Pty Ltd + +OUI:78A183* + ID_OUI_FROM_DATABASE=Advidia + +OUI:78A2A0* + ID_OUI_FROM_DATABASE=Nintendo Co., Ltd. + +OUI:78A3E4* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:78A5DD* + ID_OUI_FROM_DATABASE=Shenzhen Smarteye Digital Electronics Co., Ltd + +OUI:78A683* + ID_OUI_FROM_DATABASE=Precidata + +OUI:78A6BD* + ID_OUI_FROM_DATABASE=DAEYEON Control&Instrument Co,.Ltd + +OUI:78A714* + ID_OUI_FROM_DATABASE=Amphenol + +OUI:78AB60* + ID_OUI_FROM_DATABASE=ABB Australia + +OUI:78ACC0* + ID_OUI_FROM_DATABASE=Hewlett-Packard Company + +OUI:78B6C1* + ID_OUI_FROM_DATABASE=AOBO Telecom Co.,Ltd + +OUI:78B81A* + ID_OUI_FROM_DATABASE=INTER SALES A/S + +OUI:78BAD0* + ID_OUI_FROM_DATABASE=Shinybow Technology Co. Ltd. + +OUI:78BEB6* + ID_OUI_FROM_DATABASE=Enhanced Vision + +OUI:78BEBD* + ID_OUI_FROM_DATABASE=STULZ GmbH + +OUI:78C40E* + ID_OUI_FROM_DATABASE=H&D Wireless + +OUI:78C4AB* + ID_OUI_FROM_DATABASE=Shenzhen Runsil Technology Co.,Ltd + +OUI:78C5E5* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:78C6BB* + ID_OUI_FROM_DATABASE=Innovasic, Inc. + +OUI:78CA04* + ID_OUI_FROM_DATABASE=Nokia Corporation + +OUI:78CA39* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:78CD8E* + ID_OUI_FROM_DATABASE=SMC Networks Inc + +OUI:78D004* + ID_OUI_FROM_DATABASE=Neousys Technology Inc. + +OUI:78D129* + ID_OUI_FROM_DATABASE=Vicos + +OUI:78D34F* + ID_OUI_FROM_DATABASE=Pace-O-Matic, Inc. + +OUI:78D6F0* + ID_OUI_FROM_DATABASE=Samsung Electro Mechanics + +OUI:78DD08* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + +OUI:78DDD6* + ID_OUI_FROM_DATABASE=c-scape + +OUI:78DEE4* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:78E3B5* + ID_OUI_FROM_DATABASE=Hewlett-Packard Company + +OUI:78E400* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + +OUI:78E7D1* + ID_OUI_FROM_DATABASE=Hewlett-Packard Company + +OUI:78EC22* + ID_OUI_FROM_DATABASE=Shanghai Qihui Telecom Technology Co., LTD + +OUI:78EF4C* + ID_OUI_FROM_DATABASE=Unetconvergence Co., Ltd. + +OUI:78F5FD* + ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd + +OUI:78F7D0* + ID_OUI_FROM_DATABASE=Silverbrook Research + +OUI:78FE3D* + ID_OUI_FROM_DATABASE=Juniper Networks + +OUI:7C0187* + ID_OUI_FROM_DATABASE=Curtis Instruments, Inc. + +OUI:7C02BC* + ID_OUI_FROM_DATABASE=Hansung Electronics Co. LTD + +OUI:7C034C* + ID_OUI_FROM_DATABASE=SAGEMCOM + +OUI:7C03D8* + ID_OUI_FROM_DATABASE=SAGEMCOM SAS + +OUI:7C051E* + ID_OUI_FROM_DATABASE=RAFAEL LTD. + +OUI:7C08D9* + ID_OUI_FROM_DATABASE=Shanghai Engineering Research Center for Broadband Technologies and Applications + +OUI:7C092B* + ID_OUI_FROM_DATABASE=Bekey A/S + +OUI:7C0A50* + ID_OUI_FROM_DATABASE=J-MEX Inc. + +OUI:7C11BE* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:7C1476* + ID_OUI_FROM_DATABASE=Damall Technologies S.A.S. Di Ludovic Anselme Glaglanon & C. + +OUI:7C160D* + ID_OUI_FROM_DATABASE=Saia-Burgess Controls AG + +OUI:7C1E52* + ID_OUI_FROM_DATABASE=Microsoft + +OUI:7C1EB3* + ID_OUI_FROM_DATABASE=2N TELEKOMUNIKACE a.s. + +OUI:7C2064* + ID_OUI_FROM_DATABASE=Alcatel Lucent IPD + +OUI:7C2CF3* + ID_OUI_FROM_DATABASE=Secure Electrans Ltd + +OUI:7C2E0D* + ID_OUI_FROM_DATABASE=Blackmagic Design + +OUI:7C2F80* + ID_OUI_FROM_DATABASE=Gigaset Communications GmbH + +OUI:7C336E* + ID_OUI_FROM_DATABASE=MEG Electronics Inc. + +OUI:7C386C* + ID_OUI_FROM_DATABASE=Real Time Logic + +OUI:7C3920* + ID_OUI_FROM_DATABASE=SSOMA SECURITY + +OUI:7C3BD5* + ID_OUI_FROM_DATABASE=Imago Group + +OUI:7C3E9D* + ID_OUI_FROM_DATABASE=PATECH + +OUI:7C438F* + ID_OUI_FROM_DATABASE=E-Band Communications Corp. + +OUI:7C4A82* + ID_OUI_FROM_DATABASE=Portsmith LLC + +OUI:7C4AA8* + ID_OUI_FROM_DATABASE=MindTree Wireless PVT Ltd + +OUI:7C4B78* + ID_OUI_FROM_DATABASE=Red Sun Synthesis Pte Ltd + +OUI:7C4C58* + ID_OUI_FROM_DATABASE=Scale Computing, Inc. + +OUI:7C4CA5* + ID_OUI_FROM_DATABASE=BSkyB Ltd + +OUI:7C4FB5* + ID_OUI_FROM_DATABASE=Arcadyan Technology Corporation + +OUI:7C55E7* + ID_OUI_FROM_DATABASE=YSI, Inc. + +OUI:7C6193* + ID_OUI_FROM_DATABASE=HTC Corporation + +OUI:7C6ADB* + ID_OUI_FROM_DATABASE=SafeTone Technology Co.,Ltd + +OUI:7C6B33* + ID_OUI_FROM_DATABASE=Tenyu Tech Co. Ltd. + +OUI:7C6B52* + ID_OUI_FROM_DATABASE=Tigaro Wireless + +OUI:7C6C39* + ID_OUI_FROM_DATABASE=PIXSYS SRL + +OUI:7C6C8F* + ID_OUI_FROM_DATABASE=AMS NEVE LTD + +OUI:7C6D62* + ID_OUI_FROM_DATABASE=Apple, Inc + +OUI:7C6F06* + ID_OUI_FROM_DATABASE=Caterpillar Trimble Control Technologies + +OUI:7C7673* + ID_OUI_FROM_DATABASE=ENMAS GmbH + +OUI:7C7A91* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:7C7BE4* + ID_OUI_FROM_DATABASE=Z'SEDAI KENKYUSHO CORPORATION + +OUI:7C7D41* + ID_OUI_FROM_DATABASE=Jinmuyu Electronics Co., Ltd. + +OUI:7C822D* + ID_OUI_FROM_DATABASE=Nortec + +OUI:7C8EE4* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:7C94B2* + ID_OUI_FROM_DATABASE=Philips Healthcare PCCI + +OUI:7C9A9B* + ID_OUI_FROM_DATABASE=VSE valencia smart energy + +OUI:7CA29B* + ID_OUI_FROM_DATABASE=D.SignT GmbH & Co. KG + +OUI:7CA61D* + ID_OUI_FROM_DATABASE=MHL, LLC + +OUI:7CACB2* + ID_OUI_FROM_DATABASE=Bosch Software Innovations GmbH + +OUI:7CB03E* + ID_OUI_FROM_DATABASE=OSRAM AG + +OUI:7CB21B* + ID_OUI_FROM_DATABASE=Cisco SPVTG + +OUI:7CB232* + ID_OUI_FROM_DATABASE=TCL King High Frequency EI,Co.,LTD + +OUI:7CB542* + ID_OUI_FROM_DATABASE=ACES Technology + +OUI:7CBB6F* + ID_OUI_FROM_DATABASE=Cosco Electronics Co., Ltd. + +OUI:7CBFB1* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:7CC3A1* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:7CC537* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:7CC8AB* + ID_OUI_FROM_DATABASE=Acro Associates, Inc. + +OUI:7CC8D0* + ID_OUI_FROM_DATABASE=TIANJIN YAAN TECHNOLOGY CO., LTD. + +OUI:7CC8D7* + ID_OUI_FROM_DATABASE=Damalisk + +OUI:7CCB0D* + ID_OUI_FROM_DATABASE=Aaxeon Technologies Inc. + +OUI:7CCFCF* + ID_OUI_FROM_DATABASE=Shanghai SEARI Intelligent System Co., Ltd + +OUI:7CD1C3* + ID_OUI_FROM_DATABASE=Apple Inc + +OUI:7CD9FE* + ID_OUI_FROM_DATABASE=New Cosmos Electric Co., Ltd. + +OUI:7CDA84* + ID_OUI_FROM_DATABASE=Dongnian Networks Inc. + +OUI:7CDD11* + ID_OUI_FROM_DATABASE=Chongqing MAS SCI&TECH.Co.,Ltd + +OUI:7CDD20* + ID_OUI_FROM_DATABASE=IOXOS Technologies S.A. + +OUI:7CDD90* + ID_OUI_FROM_DATABASE=Shenzhen Ogemray Technology Co., Ltd. + +OUI:7CE044* + ID_OUI_FROM_DATABASE=NEON Inc + +OUI:7CE9D3* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + +OUI:7CEBEA* + ID_OUI_FROM_DATABASE=ASCT + +OUI:7CED8D* + ID_OUI_FROM_DATABASE=MICROSOFT + +OUI:7CEF18* + ID_OUI_FROM_DATABASE=Creative Product Design Pty. Ltd. + +OUI:7CEF8A* + ID_OUI_FROM_DATABASE=Inhon International Ltd. + +OUI:7CF05F* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:7CF098* + ID_OUI_FROM_DATABASE=Bee Beans Technologies, Inc. + +OUI:7CF0BA* + ID_OUI_FROM_DATABASE=Linkwell Telesystems Pvt Ltd + +OUI:7CF429* + ID_OUI_FROM_DATABASE=NUUO Inc. + +OUI:7CFE28* + ID_OUI_FROM_DATABASE=Salutron Inc. + +OUI:80000B* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:800010* + ID_OUI_FROM_DATABASE=ATT BELL LABORATORIES + +OUI:8007A2* + ID_OUI_FROM_DATABASE=Esson Technology Inc. + +OUI:800A06* + ID_OUI_FROM_DATABASE=COMTEC co.,ltd + +OUI:801440* + ID_OUI_FROM_DATABASE=Sunlit System Technology Corp + +OUI:8016B7* + ID_OUI_FROM_DATABASE=Brunel University + +OUI:80177D* + ID_OUI_FROM_DATABASE=Nortel Networks + +OUI:8018A7* + ID_OUI_FROM_DATABASE=Samsung Eletronics Co., Ltd + +OUI:801DAA* + ID_OUI_FROM_DATABASE=Avaya Inc + +OUI:801F02* + ID_OUI_FROM_DATABASE=Edimax Technology Co. Ltd. + +OUI:8020AF* + ID_OUI_FROM_DATABASE=Trade FIDES, a.s. + +OUI:802275* + ID_OUI_FROM_DATABASE=Beijing Beny Wave Technology Co Ltd + +OUI:802AFA* + ID_OUI_FROM_DATABASE=Germaneers GmbH + +OUI:802DE1* + ID_OUI_FROM_DATABASE=Solarbridge Technologies + +OUI:802E14* + ID_OUI_FROM_DATABASE=azeti Networks AG + +OUI:802FDE* + ID_OUI_FROM_DATABASE=Zurich Instruments AG + +OUI:803457* + ID_OUI_FROM_DATABASE=OT Systems Limited + +OUI:8038FD* + ID_OUI_FROM_DATABASE=LeapFrog Enterprises, Inc. + +OUI:8039E5* + ID_OUI_FROM_DATABASE=PATLITE CORPORATION + +OUI:803B9A* + ID_OUI_FROM_DATABASE=ghe-ces electronic ag + +OUI:803F5D* + ID_OUI_FROM_DATABASE=Winstars Technology Ltd + +OUI:803FD6* + ID_OUI_FROM_DATABASE=bytes at work AG + +OUI:80427C* + ID_OUI_FROM_DATABASE=Adolf Tedsen GmbH & Co. KG + +OUI:804731* + ID_OUI_FROM_DATABASE=Packet Design, Inc. + +OUI:804971* + ID_OUI_FROM_DATABASE=Apple Inc + +OUI:804F58* + ID_OUI_FROM_DATABASE=ThinkEco, Inc. + +OUI:80501B* + ID_OUI_FROM_DATABASE=Nokia Corporation + +OUI:8058C5* + ID_OUI_FROM_DATABASE=NovaTec Kommunikationstechnik GmbH + +OUI:806007* + ID_OUI_FROM_DATABASE=RIM + +OUI:806459* + ID_OUI_FROM_DATABASE=Nimbus Inc. + +OUI:8065E9* + ID_OUI_FROM_DATABASE=BenQ Corporation + +OUI:806629* + ID_OUI_FROM_DATABASE=Prescope Technologies CO.,LTD. + +OUI:806CBC* + ID_OUI_FROM_DATABASE=NET New Electronic Technology GmbH + +OUI:80711F* + ID_OUI_FROM_DATABASE=Juniper Networks + +OUI:807693* + ID_OUI_FROM_DATABASE=Newag SA + +OUI:807A7F* + ID_OUI_FROM_DATABASE=ABB Genway Xiamen Electrical Equipment CO., LTD + +OUI:807B1E* + ID_OUI_FROM_DATABASE=Corsair Components + +OUI:807D1B* + ID_OUI_FROM_DATABASE=Neosystem Co. Ltd. + +OUI:807DE3* + ID_OUI_FROM_DATABASE=Chongqing Sichuan Instrument Microcircuit Co.LTD. + +OUI:8081A5* + ID_OUI_FROM_DATABASE=TONGQING COMMUNICATION EQUIPMENT (SHENZHEN) Co.,Ltd + +OUI:808287* + ID_OUI_FROM_DATABASE=ATCOM Technology Co.Ltd. + +OUI:808698* + ID_OUI_FROM_DATABASE=Netronics Technologies Inc. + +OUI:808B5C* + ID_OUI_FROM_DATABASE=Shenzhen Runhuicheng Technology Co., Ltd + +OUI:80912A* + ID_OUI_FROM_DATABASE=Lih Rong electronic Enterprise Co., Ltd. + +OUI:8091C0* + ID_OUI_FROM_DATABASE=AgileMesh, Inc. + +OUI:80929F* + ID_OUI_FROM_DATABASE=Apple + +OUI:809393* + ID_OUI_FROM_DATABASE=Xapt GmbH + +OUI:80946C* + ID_OUI_FROM_DATABASE=TOKYO RADAR CORPORATION + +OUI:8096B1* + ID_OUI_FROM_DATABASE=Motorola Mobility + +OUI:80971B* + ID_OUI_FROM_DATABASE=Altenergy Power System,Inc. + +OUI:809B20* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:80A1D7* + ID_OUI_FROM_DATABASE=Shanghai DareGlobal Technologies Co.,Ltd + +OUI:80AAA4* + ID_OUI_FROM_DATABASE=USAG + +OUI:80B289* + ID_OUI_FROM_DATABASE=Forworld Electronics Ltd. + +OUI:80B32A* + ID_OUI_FROM_DATABASE=Alstom Grid + +OUI:80B686* + ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd + +OUI:80B95C* + ID_OUI_FROM_DATABASE=ELFTECH Co., Ltd. + +OUI:80BAAC* + ID_OUI_FROM_DATABASE=TeleAdapt Ltd + +OUI:80C16E* + ID_OUI_FROM_DATABASE=Hewlett Packard + +OUI:80C63F* + ID_OUI_FROM_DATABASE=Remec Broadband Wireless , LLC + +OUI:80C6AB* + ID_OUI_FROM_DATABASE=Technicolor USA Inc. + +OUI:80C6CA* + ID_OUI_FROM_DATABASE=Endian s.r.l. + +OUI:80C862* + ID_OUI_FROM_DATABASE=Openpeak, Inc + +OUI:80CEB1* + ID_OUI_FROM_DATABASE=Theissen Training Systems GmbH + +OUI:80CF41* + ID_OUI_FROM_DATABASE=Lenovo Mobile Communication Technology Ltd. + +OUI:80D019* + ID_OUI_FROM_DATABASE=Embed, Inc + +OUI:80D18B* + ID_OUI_FROM_DATABASE=Hangzhou I'converge Technology Co.,Ltd + +OUI:80D733* + ID_OUI_FROM_DATABASE=QSR Automations, Inc. + +OUI:80DB31* + ID_OUI_FROM_DATABASE=Power Quotient International Co., Ltd. + +OUI:80EE73* + ID_OUI_FROM_DATABASE=Shuttle Inc. + +OUI:80F593* + ID_OUI_FROM_DATABASE=IRCO Sistemas de Telecomunicación S.A. + +OUI:80F62E* + ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited + +OUI:80FA5B* + ID_OUI_FROM_DATABASE=CLEVO CO. + +OUI:80FB06* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +OUI:80FFA8* + ID_OUI_FROM_DATABASE=UNIDIS + +OUI:8400D2* + ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications AB + +OUI:840B2D* + ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO-MECHANICS CO., LTD + +OUI:841715* + ID_OUI_FROM_DATABASE=GP Electronics (HK) Ltd. + +OUI:841888* + ID_OUI_FROM_DATABASE=Juniper Networks + +OUI:841B5E* + ID_OUI_FROM_DATABASE=NETGEAR + +OUI:842141* + ID_OUI_FROM_DATABASE=Shenzhen Ginwave Technologies Ltd. + +OUI:84248D* + ID_OUI_FROM_DATABASE=Motorola Solutions Inc + +OUI:8425DB* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:8427CE* + ID_OUI_FROM_DATABASE=Corporation of the Presiding Bishop of The Church of Jesus Christ of Latter-day Saints + +OUI:842914* + ID_OUI_FROM_DATABASE=EMPORIA TELECOM Produktions- und VertriebsgesmbH & Co KG + +OUI:842999* + ID_OUI_FROM_DATABASE=Apple Inc + +OUI:842B2B* + ID_OUI_FROM_DATABASE=Dell Inc. + +OUI:842B50* + ID_OUI_FROM_DATABASE=Huria Co.,Ltd. + +OUI:842BBC* + ID_OUI_FROM_DATABASE=Modelleisenbahn GmbH + +OUI:8430E5* + ID_OUI_FROM_DATABASE=SkyHawke Technologies, LLC + +OUI:843497* + ID_OUI_FROM_DATABASE=Hewlett Packard + +OUI:843611* + ID_OUI_FROM_DATABASE=hyungseul publishing networks + +OUI:843A4B* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:843F4E* + ID_OUI_FROM_DATABASE=Tri-Tech Manufacturing, Inc. + +OUI:844823* + ID_OUI_FROM_DATABASE=WOXTER TECHNOLOGY Co. Ltd + +OUI:844915* + ID_OUI_FROM_DATABASE=vArmour Networks, Inc. + +OUI:844BF5* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + +OUI:845181* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:845787* + ID_OUI_FROM_DATABASE=DVR C&C Co., Ltd. + +OUI:845DD7* + ID_OUI_FROM_DATABASE=Shenzhen Netcom Electronics Co.,Ltd + +OUI:8462A6* + ID_OUI_FROM_DATABASE=EuroCB (Phils), Inc. + +OUI:846AED* + ID_OUI_FROM_DATABASE=Wireless Tsukamoto.,co.LTD + +OUI:846EB1* + ID_OUI_FROM_DATABASE=Park Assist LLC + +OUI:84742A* + ID_OUI_FROM_DATABASE=zte corporation + +OUI:8478AC* + ID_OUI_FROM_DATABASE=Cisco + +OUI:847A88* + ID_OUI_FROM_DATABASE=HTC Corporation + +OUI:847E40* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:8482F4* + ID_OUI_FROM_DATABASE=Beijing Huasun Unicreate Technology Co., Ltd + +OUI:848506* + ID_OUI_FROM_DATABASE=Apple Inc + +OUI:848D84* + ID_OUI_FROM_DATABASE=Rajant Corporation + +OUI:848E96* + ID_OUI_FROM_DATABASE=Embertec Pty Ltd + +OUI:848F69* + ID_OUI_FROM_DATABASE=Dell Inc. + +OUI:849000* + ID_OUI_FROM_DATABASE=Arnold & Richter Cine Technik + +OUI:8497B8* + ID_OUI_FROM_DATABASE=Memjet Inc. + +OUI:849CA6* + ID_OUI_FROM_DATABASE=Arcadyan Technology Corporation + +OUI:849DC5* + ID_OUI_FROM_DATABASE=Centera Photonics Inc. + +OUI:84A6C8* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:84A8E4* + ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd + +OUI:84A991* + ID_OUI_FROM_DATABASE=Cyber Trans Japan Co.,Ltd. + +OUI:84ACA4* + ID_OUI_FROM_DATABASE=Beijing Novel Super Digital TV Technology Co., Ltd + +OUI:84AF1F* + ID_OUI_FROM_DATABASE=Beat System Service Co,. Ltd. + +OUI:84C2E4* + ID_OUI_FROM_DATABASE=Jiangsu Qinheng Co., Ltd. + +OUI:84C727* + ID_OUI_FROM_DATABASE=Gnodal Ltd + +OUI:84C7A9* + ID_OUI_FROM_DATABASE=C3PO S.A. + +OUI:84C8B1* + ID_OUI_FROM_DATABASE=Incognito Software Inc. + +OUI:84C9B2* + ID_OUI_FROM_DATABASE=D-Link International + +OUI:84D32A* + ID_OUI_FROM_DATABASE=IEEE P1905.1 + +OUI:84D9C8* + ID_OUI_FROM_DATABASE=Unipattern Co., + +OUI:84DB2F* + ID_OUI_FROM_DATABASE=Sierra Wireless Inc + +OUI:84DE3D* + ID_OUI_FROM_DATABASE=Crystal Vision Ltd + +OUI:84DF0C* + ID_OUI_FROM_DATABASE=NET2GRID BV + +OUI:84E714* + ID_OUI_FROM_DATABASE=Liang Herng Enterprise,Co.Ltd. + +OUI:84EA99* + ID_OUI_FROM_DATABASE=Vieworks + +OUI:84ED33* + ID_OUI_FROM_DATABASE=BBMC Co.,Ltd + +OUI:84F64C* + ID_OUI_FROM_DATABASE=Cross Point BV + +OUI:84FCFE* + ID_OUI_FROM_DATABASE=Apple + +OUI:881036* + ID_OUI_FROM_DATABASE=Panodic(ShenZhen) Electronics Limted + +OUI:881544* + ID_OUI_FROM_DATABASE=Meraki, Inc. + +OUI:8818AE* + ID_OUI_FROM_DATABASE=Tamron Co., Ltd + +OUI:882012* + ID_OUI_FROM_DATABASE=LMI Technologies + +OUI:8821E3* + ID_OUI_FROM_DATABASE=Nebusens, S.L. + +OUI:8823FE* + ID_OUI_FROM_DATABASE=TTTech Computertechnik AG + +OUI:88252C* + ID_OUI_FROM_DATABASE=Arcadyan Technology Corporation + +OUI:88308A* + ID_OUI_FROM_DATABASE=Murata Manufactuaring Co.,Ltd. + +OUI:88329B* + ID_OUI_FROM_DATABASE=Samsung Electro Mechanics co.,LTD. + +OUI:8841C1* + ID_OUI_FROM_DATABASE=ORBISAT DA AMAZONIA IND E AEROL SA + +OUI:8843E1* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:884B39* + ID_OUI_FROM_DATABASE=Siemens AG, Healthcare Sector + +OUI:8851FB* + ID_OUI_FROM_DATABASE=Hewlett Packard + +OUI:88532E* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:885395* + ID_OUI_FROM_DATABASE=Apple + +OUI:8853D4* + ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd + +OUI:885C4F* + ID_OUI_FROM_DATABASE=Alcatel Lucent + +OUI:88615A* + ID_OUI_FROM_DATABASE=Siano Mobile Silicon Ltd. + +OUI:886B76* + ID_OUI_FROM_DATABASE=CHINA HOPEFUL GROUP HOPEFUL ELECTRIC CO.,LTD + +OUI:887556* + ID_OUI_FROM_DATABASE=Cisco + +OUI:8886A0* + ID_OUI_FROM_DATABASE=Simton Technologies, Ltd. + +OUI:888717* + ID_OUI_FROM_DATABASE=CANON INC. + +OUI:8887DD* + ID_OUI_FROM_DATABASE=DarbeeVision Inc. + +OUI:888B5D* + ID_OUI_FROM_DATABASE=Storage Appliance Corporation + +OUI:888C19* + ID_OUI_FROM_DATABASE=Brady Corp Asia Pacific Ltd + +OUI:8891DD* + ID_OUI_FROM_DATABASE=Racktivity + +OUI:8894F9* + ID_OUI_FROM_DATABASE=Gemicom Technology, Inc. + +OUI:8895B9* + ID_OUI_FROM_DATABASE=Unified Packet Systems Crop + +OUI:889676* + ID_OUI_FROM_DATABASE=TTC MARCONI s.r.o. + +OUI:8897DF* + ID_OUI_FROM_DATABASE=Entrypass Corporation Sdn. Bhd. + +OUI:889821* + ID_OUI_FROM_DATABASE=TERAON + +OUI:889FFA* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + +OUI:88A3CC* + ID_OUI_FROM_DATABASE=Amatis Controls + +OUI:88A5BD* + ID_OUI_FROM_DATABASE=QPCOM INC. + +OUI:88ACC1* + ID_OUI_FROM_DATABASE=Generiton Co., Ltd. + +OUI:88AE1D* + ID_OUI_FROM_DATABASE=COMPAL INFORMATION(KUNSHAN)CO.,LTD + +OUI:88B168* + ID_OUI_FROM_DATABASE=Delta Control GmbH + +OUI:88B627* + ID_OUI_FROM_DATABASE=Gembird Europe BV + +OUI:88BA7F* + ID_OUI_FROM_DATABASE=Qfiednet Co., Ltd. + +OUI:88BFD5* + ID_OUI_FROM_DATABASE=Simple Audio Ltd + +OUI:88C36E* + ID_OUI_FROM_DATABASE=Beijing Ereneben lnformation Technology Limited + +OUI:88C663* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:88CB87* + ID_OUI_FROM_DATABASE=Apple + +OUI:88D7BC* + ID_OUI_FROM_DATABASE=DEP Company + +OUI:88DC96* + ID_OUI_FROM_DATABASE=SENAO Networks, Inc. + +OUI:88DD79* + ID_OUI_FROM_DATABASE=Voltaire + +OUI:88E0A0* + ID_OUI_FROM_DATABASE=Shenzhen VisionSTOR Technologies Co., Ltd + +OUI:88E0F3* + ID_OUI_FROM_DATABASE=Juniper Networks + +OUI:88E712* + ID_OUI_FROM_DATABASE=Whirlpool Corporation + +OUI:88E7A6* + ID_OUI_FROM_DATABASE=iKnowledge Integration Corp. + +OUI:88E917* + ID_OUI_FROM_DATABASE=Tamaggo + +OUI:88ED1C* + ID_OUI_FROM_DATABASE=Cudo Communication Co., Ltd. + +OUI:88F077* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:88F488* + ID_OUI_FROM_DATABASE=cellon communications technology(shenzhen)Co.,Ltd. + +OUI:88F490* + ID_OUI_FROM_DATABASE=Jetmobile Pte Ltd + +OUI:88FD15* + ID_OUI_FROM_DATABASE=LINEEYE CO., LTD + +OUI:8C04FF* + ID_OUI_FROM_DATABASE=Technicolor USA Inc. + +OUI:8C078C* + ID_OUI_FROM_DATABASE=FLOW DATA INC + +OUI:8C0C90* + ID_OUI_FROM_DATABASE=Ruckus Wireless + +OUI:8C0CA3* + ID_OUI_FROM_DATABASE=Amper + +OUI:8C0EE3* + ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD. + +OUI:8C11CB* + ID_OUI_FROM_DATABASE=ABUS Security-Center GmbH & Co. KG + +OUI:8C1F94* + ID_OUI_FROM_DATABASE=RF Surgical System Inc. + +OUI:8C210A* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO., LTD. + +OUI:8C271D* + ID_OUI_FROM_DATABASE=QuantHouse + +OUI:8C278A* + ID_OUI_FROM_DATABASE=Vocollect Inc + +OUI:8C2DAA* + ID_OUI_FROM_DATABASE=Apple Inc + +OUI:8C3330* + ID_OUI_FROM_DATABASE=EmFirst Co., Ltd. + +OUI:8C3C4A* + ID_OUI_FROM_DATABASE=NAKAYO TELECOMMUNICATIONS,INC. + +OUI:8C4435* + ID_OUI_FROM_DATABASE=Shanghai BroadMobi Communication Technology Co., Ltd. + +OUI:8C4AEE* + ID_OUI_FROM_DATABASE=GIGA TMS INC + +OUI:8C4CDC* + ID_OUI_FROM_DATABASE=PLANEX COMMUNICATIONS INC. + +OUI:8C4DEA* + ID_OUI_FROM_DATABASE=Cerio Corporation + +OUI:8C5105* + ID_OUI_FROM_DATABASE=Shenzhen ireadygo Information Technology CO.,LTD. + +OUI:8C53F7* + ID_OUI_FROM_DATABASE=A&D ENGINEERING CO., LTD. + +OUI:8C541D* + ID_OUI_FROM_DATABASE=LGE + +OUI:8C56C5* + ID_OUI_FROM_DATABASE=Nintendo Co., Ltd. + +OUI:8C57FD* + ID_OUI_FROM_DATABASE=LVX Western + +OUI:8C5877* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:8C598B* + ID_OUI_FROM_DATABASE=C Technologies AB + +OUI:8C5CA1* + ID_OUI_FROM_DATABASE=d-broad,INC + +OUI:8C5FDF* + ID_OUI_FROM_DATABASE=Beijing Railway Signal Factory + +OUI:8C604F* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:8C640B* + ID_OUI_FROM_DATABASE=Beyond Devices d.o.o. + +OUI:8C6422* + ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications AB + +OUI:8C6878* + ID_OUI_FROM_DATABASE=Nortek-AS + +OUI:8C6AE4* + ID_OUI_FROM_DATABASE=Viogem Limited + +OUI:8C705A* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:8C71F8* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:8C736E* + ID_OUI_FROM_DATABASE=Fujitsu Limited + +OUI:8C76C1* + ID_OUI_FROM_DATABASE=Goden Tech Limited + +OUI:8C7712* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:8C7B9D* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:8C7CB5* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + +OUI:8C7CFF* + ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc. + +OUI:8C7EB3* + ID_OUI_FROM_DATABASE=Lytro, Inc. + +OUI:8C82A8* + ID_OUI_FROM_DATABASE=Insigma Technology Co.,Ltd + +OUI:8C89A5* + ID_OUI_FROM_DATABASE=Micro-Star INT'L CO., LTD + +OUI:8C8A6E* + ID_OUI_FROM_DATABASE=ESTUN AUTOMATION TECHNOLOY CO., LTD + +OUI:8C8E76* + ID_OUI_FROM_DATABASE=taskit GmbH + +OUI:8C90D3* + ID_OUI_FROM_DATABASE=Alcatel Lucent + +OUI:8C9236* + ID_OUI_FROM_DATABASE=Aus.Linx Technology Co., Ltd. + +OUI:8C94CF* + ID_OUI_FROM_DATABASE=Encell Technology, Inc. + +OUI:8CA048* + ID_OUI_FROM_DATABASE=Beijing NeTopChip Technology Co.,LTD + +OUI:8CA982* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:8CAE4C* + ID_OUI_FROM_DATABASE=Plugable Technologies + +OUI:8CB64F* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:8CB82C* + ID_OUI_FROM_DATABASE=IPitomy Communications + +OUI:8CB864* + ID_OUI_FROM_DATABASE=AcSiP Technology Corp. + +OUI:8CC121* + ID_OUI_FROM_DATABASE=Panasonic AVC Networks Company + +OUI:8CC5E1* + ID_OUI_FROM_DATABASE=ShenZhen Konka Telecommunication Technology Co.,Ltd + +OUI:8CC7AA* + ID_OUI_FROM_DATABASE=Radinet Communications Inc. + +OUI:8CC8CD* + ID_OUI_FROM_DATABASE=Samsung Electronics Co., LTD + +OUI:8CCDE8* + ID_OUI_FROM_DATABASE=Nintendo Co., Ltd. + +OUI:8CCF5C* + ID_OUI_FROM_DATABASE=BEFEGA GmbH + +OUI:8CD17B* + ID_OUI_FROM_DATABASE=CG Mobile + +OUI:8CD3A2* + ID_OUI_FROM_DATABASE=VisSim AS + +OUI:8CD628* + ID_OUI_FROM_DATABASE=Ikor Metering + +OUI:8CDB25* + ID_OUI_FROM_DATABASE=ESG Solutions + +OUI:8CDD8D* + ID_OUI_FROM_DATABASE=Wifly-City System Inc. + +OUI:8CDE52* + ID_OUI_FROM_DATABASE=ISSC Technologies Corp. + +OUI:8CE081* + ID_OUI_FROM_DATABASE=zte corporation + +OUI:8CE7B3* + ID_OUI_FROM_DATABASE=Sonardyne International Ltd + +OUI:8CEEC6* + ID_OUI_FROM_DATABASE=Precepscion Pty. Ltd. + +OUI:8CF9C9* + ID_OUI_FROM_DATABASE=MESADA Technology Co.,Ltd. + +OUI:8CFABA* + ID_OUI_FROM_DATABASE=Apple Inc + +OUI:8CFDF0* + ID_OUI_FROM_DATABASE=QUALCOMM Incorporated + +OUI:90004E* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + +OUI:90013B* + ID_OUI_FROM_DATABASE=SAGEMCOM + +OUI:9002A9* + ID_OUI_FROM_DATABASE=ZHEJIANG DAHUA TECHNOLOGY CO.,LTD + +OUI:9003B7* + ID_OUI_FROM_DATABASE=PARROT + +OUI:900917* + ID_OUI_FROM_DATABASE=Far-sighted mobile + +OUI:900A3A* + ID_OUI_FROM_DATABASE=PSG Plastic Service GmbH + +OUI:900D66* + ID_OUI_FROM_DATABASE=Digimore Electronics Co., Ltd + +OUI:900DCB* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + +OUI:90185E* + ID_OUI_FROM_DATABASE=Apex Tool Group GmbH & Co OHG + +OUI:90187C* + ID_OUI_FROM_DATABASE=Samsung Electro Mechanics co., LTD. + +OUI:9018AE* + ID_OUI_FROM_DATABASE=Shanghai Meridian Technologies, Co. Ltd. + +OUI:901900* + ID_OUI_FROM_DATABASE=SCS SA + +OUI:901B0E* + ID_OUI_FROM_DATABASE=Fujitsu Technology Solutions GmbH + +OUI:901EDD* + ID_OUI_FROM_DATABASE=GREAT COMPUTER CORPORATION + +OUI:902155* + ID_OUI_FROM_DATABASE=HTC Corporation + +OUI:9027E4* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:902B34* + ID_OUI_FROM_DATABASE=GIGA-BYTE TECHNOLOGY CO.,LTD. + +OUI:902E87* + ID_OUI_FROM_DATABASE=LabJack + +OUI:90342B* + ID_OUI_FROM_DATABASE=Gatekeeper Systems, Inc. + +OUI:9034FC* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + +OUI:9038DF* + ID_OUI_FROM_DATABASE=Changzhou Tiannengbo System Co. Ltd. + +OUI:903AA0* + ID_OUI_FROM_DATABASE=Alcatel-Lucent + +OUI:903CAE* + ID_OUI_FROM_DATABASE=Yunnan KSEC Digital Technology Co.,Ltd. + +OUI:903D5A* + ID_OUI_FROM_DATABASE=Shenzhen Wision Technology Holding Limited + +OUI:903D6B* + ID_OUI_FROM_DATABASE=Zicon Technology Corp. + +OUI:904716* + ID_OUI_FROM_DATABASE=RORZE CORPORATION + +OUI:904CE5* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + +OUI:90507B* + ID_OUI_FROM_DATABASE=Advanced PANMOBIL Systems GmbH & Co. KG + +OUI:90513F* + ID_OUI_FROM_DATABASE=Elettronica Santerno + +OUI:905446* + ID_OUI_FROM_DATABASE=TES ELECTRONIC SOLUTIONS + +OUI:9055AE* + ID_OUI_FROM_DATABASE=Ericsson, EAB/RWI/K + +OUI:905682* + ID_OUI_FROM_DATABASE=Lenbrook Industries Limited + +OUI:9059AF* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:905F2E* + ID_OUI_FROM_DATABASE=TCT Mobile Limited + +OUI:905F8D* + ID_OUI_FROM_DATABASE=modas GmbH + +OUI:90610C* + ID_OUI_FROM_DATABASE=Fida International (S) Pte Ltd + +OUI:9067B5* + ID_OUI_FROM_DATABASE=Alcatel-Lucent + +OUI:9067F3* + ID_OUI_FROM_DATABASE=Alcatel Lucent + +OUI:906DC8* + ID_OUI_FROM_DATABASE=DLG Automação Industrial Ltda + +OUI:906EBB* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + +OUI:907025* + ID_OUI_FROM_DATABASE=Garea Microsys Co.,Ltd. + +OUI:907F61* + ID_OUI_FROM_DATABASE=Chicony Electronics Co., Ltd. + +OUI:908260* + ID_OUI_FROM_DATABASE=IEEE 1904.1 Working Group + +OUI:90840D* + ID_OUI_FROM_DATABASE=Apple, Inc + +OUI:9088A2* + ID_OUI_FROM_DATABASE=IONICS TECHNOLOGY ME LTDA + +OUI:908D1D* + ID_OUI_FROM_DATABASE=GH Technologies + +OUI:908FCF* + ID_OUI_FROM_DATABASE=UNO System Co., Ltd + +OUI:90903C* + ID_OUI_FROM_DATABASE=TRISON TECHNOLOGY CORPORATION + +OUI:909060* + ID_OUI_FROM_DATABASE=RSI VIDEO TECHNOLOGIES + +OUI:9092B4* + ID_OUI_FROM_DATABASE=Diehl BGT Defence GmbH & Co. KG + +OUI:9094E4* + ID_OUI_FROM_DATABASE=D-Link International + +OUI:909DE0* + ID_OUI_FROM_DATABASE=Newland Design + Assoc. Inc. + +OUI:90A2DA* + ID_OUI_FROM_DATABASE=GHEO SA + +OUI:90A4DE* + ID_OUI_FROM_DATABASE=Wistron Neweb Corp. + +OUI:90A783* + ID_OUI_FROM_DATABASE=JSW PACIFIC CORPORATION + +OUI:90A7C1* + ID_OUI_FROM_DATABASE=Pakedge Device and Software Inc. + +OUI:90AC3F* + ID_OUI_FROM_DATABASE=BrightSign LLC + +OUI:90B11C* + ID_OUI_FROM_DATABASE=Dell Inc. + +OUI:90B134* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:90B8D0* + ID_OUI_FROM_DATABASE=Joyent, Inc. + +OUI:90B97D* + ID_OUI_FROM_DATABASE=Johnson Outdoors Marine Electronics d/b/a Minnkota + +OUI:90C115* + ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications AB + +OUI:90CC24* + ID_OUI_FROM_DATABASE=Synaptics, Inc + +OUI:90CF15* + ID_OUI_FROM_DATABASE=Nokia Corporation + +OUI:90CF6F* + ID_OUI_FROM_DATABASE=Dlogixs Co Ltd + +OUI:90CF7D* + ID_OUI_FROM_DATABASE=Qingdao Hisense Electric Co.,Ltd. + +OUI:90D11B* + ID_OUI_FROM_DATABASE=Palomar Medical Technologies + +OUI:90D74F* + ID_OUI_FROM_DATABASE=Bookeen + +OUI:90D7EB* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:90D852* + ID_OUI_FROM_DATABASE=Comtec Co., Ltd. + +OUI:90D92C* + ID_OUI_FROM_DATABASE=HUG-WITSCHI AG + +OUI:90E0F0* + ID_OUI_FROM_DATABASE=IEEE P1722 + +OUI:90E2BA* + ID_OUI_FROM_DATABASE=Intel Corporation + +OUI:90E6BA* + ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. + +OUI:90EA60* + ID_OUI_FROM_DATABASE=SPI Lasers Ltd + +OUI:90F278* + ID_OUI_FROM_DATABASE=Radius Gateway + +OUI:90F4C1* + ID_OUI_FROM_DATABASE=Rand McNally + +OUI:90F652* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO., LTD. + +OUI:90F72F* + ID_OUI_FROM_DATABASE=Phillips Machine & Welding Co., Inc. + +OUI:90FB5B* + ID_OUI_FROM_DATABASE=Avaya, Inc + +OUI:90FBA6* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind.Co.Ltd + +OUI:90FF79* + ID_OUI_FROM_DATABASE=Metro Ethernet Forum + +OUI:940070* + ID_OUI_FROM_DATABASE=Nokia Corporation + +OUI:940149* + ID_OUI_FROM_DATABASE=AutoHotBox + +OUI:940B2D* + ID_OUI_FROM_DATABASE=NetView Technologies(Shenzhen) Co., Ltd + +OUI:940C6D* + ID_OUI_FROM_DATABASE=TP-LINK Technologies Co.,Ltd. + +OUI:9411DA* + ID_OUI_FROM_DATABASE=ITF Fröschl GmbH + +OUI:941673* + ID_OUI_FROM_DATABASE=Point Core SARL + +OUI:941D1C* + ID_OUI_FROM_DATABASE=TLab West Systems AB + +OUI:942053* + ID_OUI_FROM_DATABASE=Nokia Corporation + +OUI:942197* + ID_OUI_FROM_DATABASE=Stalmart Technology Limited + +OUI:94236E* + ID_OUI_FROM_DATABASE=Shenzhen Junlan Electronic Ltd + +OUI:942E17* + ID_OUI_FROM_DATABASE=Schneider Electric Canada Inc + +OUI:942E63* + ID_OUI_FROM_DATABASE=Finsécur + +OUI:94319B* + ID_OUI_FROM_DATABASE=Alphatronics BV + +OUI:9433DD* + ID_OUI_FROM_DATABASE=Taco Electronic Solutions, Inc. + +OUI:9439E5* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + +OUI:943AF0* + ID_OUI_FROM_DATABASE=Nokia Corporation + +OUI:944444* + ID_OUI_FROM_DATABASE=LG Innotek + +OUI:944452* + ID_OUI_FROM_DATABASE=Belkin International, Inc. + +OUI:944696* + ID_OUI_FROM_DATABASE=BaudTec Corporation + +OUI:944A09* + ID_OUI_FROM_DATABASE=BitWise Controls + +OUI:945103* + ID_OUI_FROM_DATABASE=Samsung Electronics + +OUI:94592D* + ID_OUI_FROM_DATABASE=EKE Building Technology Systems Ltd + +OUI:945B7E* + ID_OUI_FROM_DATABASE=TRILOBIT LTDA. + +OUI:946124* + ID_OUI_FROM_DATABASE=Pason Systems + +OUI:9463D1* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:9471AC* + ID_OUI_FROM_DATABASE=TCT Mobile Limited + +OUI:94756E* + ID_OUI_FROM_DATABASE=QinetiQ North America + +OUI:9481A4* + ID_OUI_FROM_DATABASE=Azuray Technologies + +OUI:94857A* + ID_OUI_FROM_DATABASE=Evantage Industries Corp + +OUI:948854* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:948B03* + ID_OUI_FROM_DATABASE=EAGET Innovation and Technology Co., Ltd. + +OUI:948D50* + ID_OUI_FROM_DATABASE=Beamex Oy Ab + +OUI:948FEE* + ID_OUI_FROM_DATABASE=Hughes Telematics, Inc. + +OUI:949426* + ID_OUI_FROM_DATABASE=Apple + +OUI:949BFD* + ID_OUI_FROM_DATABASE=Trans New Technology, Inc. + +OUI:949C55* + ID_OUI_FROM_DATABASE=Alta Data Technologies + +OUI:94A7BC* + ID_OUI_FROM_DATABASE=BodyMedia, Inc. + +OUI:94AAB8* + ID_OUI_FROM_DATABASE=Joview(Beijing) Technology Co. Ltd. + +OUI:94AE61* + ID_OUI_FROM_DATABASE=Alcatel Lucent + +OUI:94BA31* + ID_OUI_FROM_DATABASE=Visiontec da Amazônia Ltda. + +OUI:94C4E9* + ID_OUI_FROM_DATABASE=PowerLayer Microsystems HongKong Limited + +OUI:94C6EB* + ID_OUI_FROM_DATABASE=NOVA electronics, Inc. + +OUI:94C7AF* + ID_OUI_FROM_DATABASE=Raylios Technology + +OUI:94C962* + ID_OUI_FROM_DATABASE=Teseq AG + +OUI:94CA0F* + ID_OUI_FROM_DATABASE=Honeywell Analytics + +OUI:94CCB9* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:94CDAC* + ID_OUI_FROM_DATABASE=Creowave Oy + +OUI:94D019* + ID_OUI_FROM_DATABASE=Cydle Corp. + +OUI:94D723* + ID_OUI_FROM_DATABASE=Shanghai DareGlobal Technologies Co., Ltd + +OUI:94D93C* + ID_OUI_FROM_DATABASE=ENELPS + +OUI:94DB49* + ID_OUI_FROM_DATABASE=SITCORP + +OUI:94DBC9* + ID_OUI_FROM_DATABASE=Azurewave + +OUI:94DD3F* + ID_OUI_FROM_DATABASE=A+V Link Technologies, Corp. + +OUI:94DE0E* + ID_OUI_FROM_DATABASE=SmartOptics AS + +OUI:94DE80* + ID_OUI_FROM_DATABASE=GIGA-BYTE TECHNOLOGY CO.,LTD. + +OUI:94DF58* + ID_OUI_FROM_DATABASE=IJ Electron CO.,Ltd. + +OUI:94E0D0* + ID_OUI_FROM_DATABASE=HealthStream Taiwan Inc. + +OUI:94E226* + ID_OUI_FROM_DATABASE=D. ORtiz Consulting, LLC + +OUI:94E711* + ID_OUI_FROM_DATABASE=Xirka Dama Persada PT + +OUI:94E848* + ID_OUI_FROM_DATABASE=FYLDE MICRO LTD + +OUI:94F692* + ID_OUI_FROM_DATABASE=Geminico co.,Ltd. + +OUI:94F720* + ID_OUI_FROM_DATABASE=Tianjin Deviser Electronics Instrument Co., Ltd + +OUI:94FAE8* + ID_OUI_FROM_DATABASE=Shenzhen Eycom Technology Co., Ltd + +OUI:94FD1D* + ID_OUI_FROM_DATABASE=WhereWhen Corp + +OUI:94FD2E* + ID_OUI_FROM_DATABASE=Shanghai Uniscope Technologies Co.,Ltd + +OUI:94FEF4* + ID_OUI_FROM_DATABASE=SAGEMCOM + +OUI:980284* + ID_OUI_FROM_DATABASE=Theobroma Systems GmbH + +OUI:9803A0* + ID_OUI_FROM_DATABASE=ABB n.v. Power Quality Products + +OUI:9803D8* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:980C82* + ID_OUI_FROM_DATABASE=Samsung Electro Mechanics + +OUI:98208E* + ID_OUI_FROM_DATABASE=Definium Technologies + +OUI:98262A* + ID_OUI_FROM_DATABASE=Applied Research Associates, Inc + +OUI:98291D* + ID_OUI_FROM_DATABASE=Jaguar de Mexico, SA de CV + +OUI:98293F* + ID_OUI_FROM_DATABASE=Fujian Start Computer Equipment Co.,Ltd + +OUI:982CBE* + ID_OUI_FROM_DATABASE=2Wire + +OUI:982D56* + ID_OUI_FROM_DATABASE=Resolution Audio + +OUI:983000* + ID_OUI_FROM_DATABASE=Beijing KEMACOM Technologies Co., Ltd. + +OUI:983571* + ID_OUI_FROM_DATABASE=Sub10 Systems Ltd + +OUI:9835B8* + ID_OUI_FROM_DATABASE=Assembled Products Corporation + +OUI:983F9F* + ID_OUI_FROM_DATABASE=China SSJ (Suzhou) Network Technology Inc. + +OUI:984246* + ID_OUI_FROM_DATABASE=SOL INDUSTRY PTE., LTD + +OUI:98473C* + ID_OUI_FROM_DATABASE=SHANGHAI SUNMON COMMUNICATION TECHNOGY CO.,LTD + +OUI:984A47* + ID_OUI_FROM_DATABASE=CHG Hospital Beds + +OUI:984B4A* + ID_OUI_FROM_DATABASE=Motorola Mobility Inc. + +OUI:984BE1* + ID_OUI_FROM_DATABASE=Hewlett-Packard Company + +OUI:984C04* + ID_OUI_FROM_DATABASE=Zhangzhou Keneng Electrical Equipment Co Ltd + +OUI:984CD3* + ID_OUI_FROM_DATABASE=Mantis Deposition + +OUI:984E97* + ID_OUI_FROM_DATABASE=Starlight Marketing (H. K.) Ltd. + +OUI:9852B1* + ID_OUI_FROM_DATABASE=Samsung Electronics + +OUI:9857D3* + ID_OUI_FROM_DATABASE=HON HAI-CCPBG PRECISION IND.CO.,LTD. + +OUI:98588A* + ID_OUI_FROM_DATABASE=SYSGRATION Ltd. + +OUI:985945* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:985E1B* + ID_OUI_FROM_DATABASE=ConversDigital Co., Ltd. + +OUI:986022* + ID_OUI_FROM_DATABASE=EMW Co., Ltd. + +OUI:9866EA* + ID_OUI_FROM_DATABASE=Industrial Control Communications, Inc. + +OUI:986DC8* + ID_OUI_FROM_DATABASE=TOSHIBA MITSUBISHI-ELECTRIC INDUSTRIAL SYSTEMS CORPORATION + +OUI:9873C4* + ID_OUI_FROM_DATABASE=Sage Electronic Engineering LLC + +OUI:988217* + ID_OUI_FROM_DATABASE=Disruptive Ltd + +OUI:9886B1* + ID_OUI_FROM_DATABASE=Flyaudio corporation (China) + +OUI:9889ED* + ID_OUI_FROM_DATABASE=Anadem Information Inc. + +OUI:988B5D* + ID_OUI_FROM_DATABASE=SAGEM COMMUNICATION + +OUI:988BAD* + ID_OUI_FROM_DATABASE=Corintech Ltd. + +OUI:988E34* + ID_OUI_FROM_DATABASE=ZHEJIANG BOXSAM ELECTRONIC CO.,LTD + +OUI:988EDD* + ID_OUI_FROM_DATABASE=TE Connectivity Limerick + +OUI:989080* + ID_OUI_FROM_DATABASE=Linkpower Network System Inc Ltd. + +OUI:989449* + ID_OUI_FROM_DATABASE=Skyworth Wireless Technology Ltd. + +OUI:98A7B0* + ID_OUI_FROM_DATABASE=MCST ZAO + +OUI:98AAD7* + ID_OUI_FROM_DATABASE=BLUE WAVE NETWORKING CO LTD + +OUI:98B8E3* + ID_OUI_FROM_DATABASE=Apple + +OUI:98BC57* + ID_OUI_FROM_DATABASE=SVA TECHNOLOGIES CO.LTD + +OUI:98BC99* + ID_OUI_FROM_DATABASE=Edeltech Co.,Ltd. + +OUI:98C845* + ID_OUI_FROM_DATABASE=PacketAccess + +OUI:98D686* + ID_OUI_FROM_DATABASE=Chyi Lee industry Co., ltd. + +OUI:98D6BB* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:98D6F7* + ID_OUI_FROM_DATABASE=LG Electronics + +OUI:98D88C* + ID_OUI_FROM_DATABASE=Nortel Networks + +OUI:98DCD9* + ID_OUI_FROM_DATABASE=UNITEC Co., Ltd. + +OUI:98E165* + ID_OUI_FROM_DATABASE=Accutome + +OUI:98E79A* + ID_OUI_FROM_DATABASE=Foxconn(NanJing) Communication Co.,Ltd. + +OUI:98EC65* + ID_OUI_FROM_DATABASE=Cosesy ApS + +OUI:98F537* + ID_OUI_FROM_DATABASE=zte corporation + +OUI:98F8DB* + ID_OUI_FROM_DATABASE=Marini Impianti Industriali s.r.l. + +OUI:98FC11* + ID_OUI_FROM_DATABASE=Cisco-Linksys, LLC + +OUI:98FE03* + ID_OUI_FROM_DATABASE=Ericsson - North America + +OUI:98FE94* + ID_OUI_FROM_DATABASE=Apple Inc + +OUI:9C0111* + ID_OUI_FROM_DATABASE=Shenzhen Newabel Electronic Co., Ltd. + +OUI:9C0298* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:9C0473* + ID_OUI_FROM_DATABASE=Tecmobile (International) Ltd. + +OUI:9C04EB* + ID_OUI_FROM_DATABASE=Apple + +OUI:9C066E* + ID_OUI_FROM_DATABASE=Hytera Communications Corporation Limited + +OUI:9C0DAC* + ID_OUI_FROM_DATABASE=Tymphany HK Limited + +OUI:9C1874* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:9C1C12* + ID_OUI_FROM_DATABASE=Aruba Networks + +OUI:9C1FDD* + ID_OUI_FROM_DATABASE=Accupix Inc. + +OUI:9C207B* + ID_OUI_FROM_DATABASE=Apple Inc + +OUI:9C220E* + ID_OUI_FROM_DATABASE=TASCAN Service GmbH + +OUI:9C28BF* + ID_OUI_FROM_DATABASE=Continental Automotive Czech Republic s.r.o. + +OUI:9C2A70* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + +OUI:9C3178* + ID_OUI_FROM_DATABASE=Foshan Huadian Intelligent Communications Teachnologies Co.,Ltd + +OUI:9C31B6* + ID_OUI_FROM_DATABASE=Kulite Semiconductor Products Inc + +OUI:9C417C* + ID_OUI_FROM_DATABASE=Hame Technology Co., Limited + +OUI:9C4563* + ID_OUI_FROM_DATABASE=DIMEP Sistemas + +OUI:9C4A7B* + ID_OUI_FROM_DATABASE=Nokia Corporation + +OUI:9C4CAE* + ID_OUI_FROM_DATABASE=Mesa Labs + +OUI:9C4E20* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:9C4E36* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:9C4E8E* + ID_OUI_FROM_DATABASE=ALT Systems Ltd + +OUI:9C53CD* + ID_OUI_FROM_DATABASE=ENGICAM s.r.l. + +OUI:9C541C* + ID_OUI_FROM_DATABASE=Shenzhen My-power Technology Co.,Ltd + +OUI:9C54CA* + ID_OUI_FROM_DATABASE=Zhengzhou VCOM Science and Technology Co.,Ltd + +OUI:9C55B4* + ID_OUI_FROM_DATABASE=I.S.E. S.r.l. + +OUI:9C5711* + ID_OUI_FROM_DATABASE=Feitian Xunda(Beijing) Aeronautical Information Technology Co., Ltd. + +OUI:9C5B96* + ID_OUI_FROM_DATABASE=NMR Corporation + +OUI:9C5C8D* + ID_OUI_FROM_DATABASE=FIREMAX INDÚSTRIA E COMÉRCIO DE PRODUTOS ELETRÔNICOS LTDA + +OUI:9C5D12* + ID_OUI_FROM_DATABASE=Aerohive Networks Inc + +OUI:9C5D95* + ID_OUI_FROM_DATABASE=VTC Electronics Corp. + +OUI:9C5E73* + ID_OUI_FROM_DATABASE=Calibre UK Ltd + +OUI:9C611D* + ID_OUI_FROM_DATABASE=Omni-ID USA, Inc. + +OUI:9C645E* + ID_OUI_FROM_DATABASE=Harman Consumer Group + +OUI:9C6650* + ID_OUI_FROM_DATABASE=Glodio Technolies Co.,Ltd Tianjin Branch + +OUI:9C6ABE* + ID_OUI_FROM_DATABASE=QEES ApS. + +OUI:9C7514* + ID_OUI_FROM_DATABASE=Wildix srl + +OUI:9C77AA* + ID_OUI_FROM_DATABASE=NADASNV + +OUI:9C7BD2* + ID_OUI_FROM_DATABASE=NEOLAB Convergence + +OUI:9C807D* + ID_OUI_FROM_DATABASE=SYSCABLE Korea Inc. + +OUI:9C8BF1* + ID_OUI_FROM_DATABASE=The Warehouse Limited + +OUI:9C8D1A* + ID_OUI_FROM_DATABASE=INTEG process group inc + +OUI:9C8E99* + ID_OUI_FROM_DATABASE=Hewlett-Packard Company + +OUI:9C8EDC* + ID_OUI_FROM_DATABASE=Teracom Limited + +OUI:9C934E* + ID_OUI_FROM_DATABASE=Xerox Corporation + +OUI:9C95F8* + ID_OUI_FROM_DATABASE=SmartDoor Systems, LLC + +OUI:9C9811* + ID_OUI_FROM_DATABASE=Guangzhou Sunrise Electronics Development Co., Ltd + +OUI:9C9C1D* + ID_OUI_FROM_DATABASE=Starkey Labs Inc. + +OUI:9CA134* + ID_OUI_FROM_DATABASE=Nike, Inc. + +OUI:9CA3BA* + ID_OUI_FROM_DATABASE=SAKURA Internet Inc. + +OUI:9CADEF* + ID_OUI_FROM_DATABASE=Obihai Technology, Inc. + +OUI:9CAFCA* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:9CB008* + ID_OUI_FROM_DATABASE=Ubiquitous Computing Technology Corporation + +OUI:9CB206* + ID_OUI_FROM_DATABASE=PROCENTEC + +OUI:9CB70D* + ID_OUI_FROM_DATABASE=Liteon Technology Corporation + +OUI:9CC077* + ID_OUI_FROM_DATABASE=PrintCounts, LLC + +OUI:9CC0D2* + ID_OUI_FROM_DATABASE=Conductix-Wampfler AG + +OUI:9CC7A6* + ID_OUI_FROM_DATABASE=AVM GmbH + +OUI:9CC7D1* + ID_OUI_FROM_DATABASE=SHARP Corporation + +OUI:9CCAD9* + ID_OUI_FROM_DATABASE=Nokia Corporation + +OUI:9CCD82* + ID_OUI_FROM_DATABASE=CHENG UEI PRECISION INDUSTRY CO.,LTD + +OUI:9CD24B* + ID_OUI_FROM_DATABASE=zte corporation + +OUI:9CD36D* + ID_OUI_FROM_DATABASE=NETGEAR INC., + +OUI:9CDF03* + ID_OUI_FROM_DATABASE=Harman/Becker Automotive Systems GmbH + +OUI:9CE10E* + ID_OUI_FROM_DATABASE=NCTech Ltd + +OUI:9CE1D6* + ID_OUI_FROM_DATABASE=Junger Audio-Studiotechnik GmbH + +OUI:9CE635* + ID_OUI_FROM_DATABASE=Nintendo Co., Ltd. + +OUI:9CEBE8* + ID_OUI_FROM_DATABASE=BizLink (Kunshan) Co.,Ltd + +OUI:9CF61A* + ID_OUI_FROM_DATABASE=UTC Fire and Security + +OUI:9CF67D* + ID_OUI_FROM_DATABASE=Ricardo Prague, s.r.o. + +OUI:9CF938* + ID_OUI_FROM_DATABASE=AREVA NP GmbH + +OUI:9CFFBE* + ID_OUI_FROM_DATABASE=OTSL Inc. + +OUI:A00363* + ID_OUI_FROM_DATABASE=Robert Bosch Healthcare GmbH + +OUI:A00798* + ID_OUI_FROM_DATABASE=Samsung Electronics + +OUI:A007B6* + ID_OUI_FROM_DATABASE=Advanced Technical Support, Inc. + +OUI:A00ABF* + ID_OUI_FROM_DATABASE=Wieson Technologies Co., Ltd. + +OUI:A00BBA* + ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO-MECHANICS + +OUI:A00CA1* + ID_OUI_FROM_DATABASE=SKTB "SKiT" + +OUI:A0133B* + ID_OUI_FROM_DATABASE=Copyright © HiTi Digital, Inc. + +OUI:A0165C* + ID_OUI_FROM_DATABASE=TangoTec Ltd. + +OUI:A01859* + ID_OUI_FROM_DATABASE=Shenzhen Yidashi Electronics Co Ltd + +OUI:A01917* + ID_OUI_FROM_DATABASE=Bertel S.p.a. + +OUI:A02195* + ID_OUI_FROM_DATABASE=Samsung Electronics Digital Imaging + +OUI:A021B7* + ID_OUI_FROM_DATABASE=NETGEAR + +OUI:A0231B* + ID_OUI_FROM_DATABASE=TeleComp R&D Corp. + +OUI:A02EF3* + ID_OUI_FROM_DATABASE=United Integrated Services Co., Led. + +OUI:A0369F* + ID_OUI_FROM_DATABASE=Intel Corporation + +OUI:A036F0* + ID_OUI_FROM_DATABASE=Comprehensive Power + +OUI:A036FA* + ID_OUI_FROM_DATABASE=Ettus Research LLC + +OUI:A03A75* + ID_OUI_FROM_DATABASE=PSS Belgium N.V. + +OUI:A04025* + ID_OUI_FROM_DATABASE=Actioncable, Inc. + +OUI:A04041* + ID_OUI_FROM_DATABASE=SAMWONFA Co.,Ltd. + +OUI:A041A7* + ID_OUI_FROM_DATABASE=NL Ministry of Defense + +OUI:A0423F* + ID_OUI_FROM_DATABASE=Tyan Computer Corp + +OUI:A04CC1* + ID_OUI_FROM_DATABASE=Helixtech Corp. + +OUI:A04E04* + ID_OUI_FROM_DATABASE=Nokia Corporation + +OUI:A051C6* + ID_OUI_FROM_DATABASE=Avaya, Inc + +OUI:A055DE* + ID_OUI_FROM_DATABASE=Pace plc + +OUI:A0593A* + ID_OUI_FROM_DATABASE=V.D.S. Video Display Systems srl + +OUI:A05AA4* + ID_OUI_FROM_DATABASE=Grand Products Nevada, Inc. + +OUI:A05DC1* + ID_OUI_FROM_DATABASE=TMCT Co., LTD. + +OUI:A05DE7* + ID_OUI_FROM_DATABASE=DIRECTV, Inc. + +OUI:A05E6B* + ID_OUI_FROM_DATABASE=MELPER Co., Ltd. + +OUI:A06986* + ID_OUI_FROM_DATABASE=Wellav Technologies Ltd + +OUI:A06A00* + ID_OUI_FROM_DATABASE=Verilink Corporation + +OUI:A06CEC* + ID_OUI_FROM_DATABASE=RIM + +OUI:A06D09* + ID_OUI_FROM_DATABASE=Intelcan Technosystems Inc. + +OUI:A06E50* + ID_OUI_FROM_DATABASE=Nanotek Elektronik Sistemler Ltd. Sti. + +OUI:A071A9* + ID_OUI_FROM_DATABASE=Nokia Corporation + +OUI:A07332* + ID_OUI_FROM_DATABASE=Cashmaster International Limited + +OUI:A07591* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:A078BA* + ID_OUI_FROM_DATABASE=Pantech Co., Ltd. + +OUI:A082C7* + ID_OUI_FROM_DATABASE=P.T.I Co.,LTD + +OUI:A086EC* + ID_OUI_FROM_DATABASE=SAEHAN HITEC Co., Ltd + +OUI:A08869* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:A088B4* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:A08C15* + ID_OUI_FROM_DATABASE=Gerhard D. Wempe KG + +OUI:A08C9B* + ID_OUI_FROM_DATABASE=Xtreme Technologies Corp + +OUI:A090DE* + ID_OUI_FROM_DATABASE=VEEDIMS,LLC + +OUI:A09805* + ID_OUI_FROM_DATABASE=OpenVox Communication Co Ltd + +OUI:A098ED* + ID_OUI_FROM_DATABASE=Shandong Intelligent Optical Communication Development Co., Ltd. + +OUI:A09A5A* + ID_OUI_FROM_DATABASE=Time Domain + +OUI:A0A130* + ID_OUI_FROM_DATABASE=DLI Taiwan Branch office + +OUI:A0A763* + ID_OUI_FROM_DATABASE=Polytron Vertrieb GmbH + +OUI:A0AAFD* + ID_OUI_FROM_DATABASE=EraThink Technologies Corp. + +OUI:A0B3CC* + ID_OUI_FROM_DATABASE=Hewlett Packard + +OUI:A0B5DA* + ID_OUI_FROM_DATABASE=HongKong THTF Co., Ltd + +OUI:A0B662* + ID_OUI_FROM_DATABASE=Acutvista Innovation Co., Ltd. + +OUI:A0B9ED* + ID_OUI_FROM_DATABASE=Skytap + +OUI:A0BAB8* + ID_OUI_FROM_DATABASE=Pixon Imaging + +OUI:A0BFA5* + ID_OUI_FROM_DATABASE=CORESYS + +OUI:A0C3DE* + ID_OUI_FROM_DATABASE=Triton Electronic Systems Ltd. + +OUI:A0CF5B* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:A0DC04* + ID_OUI_FROM_DATABASE=Becker-Antriebe GmbH + +OUI:A0DD97* + ID_OUI_FROM_DATABASE=PolarLink Technologies, Ltd + +OUI:A0DDE5* + ID_OUI_FROM_DATABASE=SHARP CORPORATION + +OUI:A0DE05* + ID_OUI_FROM_DATABASE=JSC "Irbis-T" + +OUI:A0E201* + ID_OUI_FROM_DATABASE=AVTrace Ltd.(China) + +OUI:A0E25A* + ID_OUI_FROM_DATABASE=Amicus SK, s.r.o. + +OUI:A0E295* + ID_OUI_FROM_DATABASE=DAT System Co.,Ltd + +OUI:A0E534* + ID_OUI_FROM_DATABASE=Stratec Biomedical AG + +OUI:A0E9DB* + ID_OUI_FROM_DATABASE=Ningbo FreeWings Technologies Co.,Ltd + +OUI:A0EF84* + ID_OUI_FROM_DATABASE=Seine Image Int'l Co., Ltd + +OUI:A0F217* + ID_OUI_FROM_DATABASE=GE Medical System(China) Co., Ltd. + +OUI:A0F3C1* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO., LTD. + +OUI:A0F3E4* + ID_OUI_FROM_DATABASE=Alcatel Lucent IPD + +OUI:A0F419* + ID_OUI_FROM_DATABASE=Nokia Corporation + +OUI:A0F450* + ID_OUI_FROM_DATABASE=HTC Corporation + +OUI:A0FE91* + ID_OUI_FROM_DATABASE=AVAT Automation GmbH + +OUI:A40130* + ID_OUI_FROM_DATABASE=ABIsystems Co., LTD + +OUI:A40BED* + ID_OUI_FROM_DATABASE=Carry Technology Co.,Ltd + +OUI:A40CC3* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:A4134E* + ID_OUI_FROM_DATABASE=Luxul + +OUI:A41731* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + +OUI:A41875* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:A41BC0* + ID_OUI_FROM_DATABASE=Fastec Imaging Corporation + +OUI:A41F72* + ID_OUI_FROM_DATABASE=Dell Inc. + +OUI:A4218A* + ID_OUI_FROM_DATABASE=Nortel Networks + +OUI:A424B3* + ID_OUI_FROM_DATABASE=FlatFrog Laboratories AB + +OUI:A429B7* + ID_OUI_FROM_DATABASE=bluesky + +OUI:A42C08* + ID_OUI_FROM_DATABASE=Masterwork Automodules + +OUI:A433D1* + ID_OUI_FROM_DATABASE=Fibrlink Communications Co.,Ltd. + +OUI:A438FC* + ID_OUI_FROM_DATABASE=Plastic Logic + +OUI:A4466B* + ID_OUI_FROM_DATABASE=EOC Technology + +OUI:A446FA* + ID_OUI_FROM_DATABASE=AmTRAN Video Corporation + +OUI:A44B15* + ID_OUI_FROM_DATABASE=Sun Cupid Technology (HK) LTD + +OUI:A44C11* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:A44E2D* + ID_OUI_FROM_DATABASE=Adaptive Wireless Solutions, LLC + +OUI:A44E31* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:A45055* + ID_OUI_FROM_DATABASE=busware.de + +OUI:A4526F* + ID_OUI_FROM_DATABASE=ADB Broadband Italia + +OUI:A4561B* + ID_OUI_FROM_DATABASE=MCOT Corporation + +OUI:A45630* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:A45A1C* + ID_OUI_FROM_DATABASE=smart-electronic GmbH + +OUI:A45C27* + ID_OUI_FROM_DATABASE=Nintendo Co., Ltd. + +OUI:A46706* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:A46E79* + ID_OUI_FROM_DATABASE=DFT System Co.Ltd + +OUI:A479E4* + ID_OUI_FROM_DATABASE=KLINFO Corp + +OUI:A47AA4* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:A47C14* + ID_OUI_FROM_DATABASE=ChargeStorm AB + +OUI:A47C1F* + ID_OUI_FROM_DATABASE=Global Microwave Systems Inc. + +OUI:A4856B* + ID_OUI_FROM_DATABASE=Q Electronics Ltd + +OUI:A49005* + ID_OUI_FROM_DATABASE=CHINA GREATWALL COMPUTER SHENZHEN CO.,LTD + +OUI:A4934C* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:A497BB* + ID_OUI_FROM_DATABASE=Hitachi Industrial Equipment Systems Co.,Ltd + +OUI:A49947* + ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd + +OUI:A49981* + ID_OUI_FROM_DATABASE=FuJian Elite Power Tech CO.,LTD. + +OUI:A49B13* + ID_OUI_FROM_DATABASE=Burroughs Payment Systems, Inc. + +OUI:A4A24A* + ID_OUI_FROM_DATABASE=Cisco SPVTG + +OUI:A4A80F* + ID_OUI_FROM_DATABASE=Shenzhen Coship Electronics Co., Ltd. + +OUI:A4AD00* + ID_OUI_FROM_DATABASE=Ragsdale Technology + +OUI:A4ADB8* + ID_OUI_FROM_DATABASE=Vitec Group, Camera Dynamics Ltd + +OUI:A4AE9A* + ID_OUI_FROM_DATABASE=Maestro Wireless Solutions ltd. + +OUI:A4B121* + ID_OUI_FROM_DATABASE=Arantia 2010 S.L. + +OUI:A4B197* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:A4B1E9* + ID_OUI_FROM_DATABASE=Technicolor + +OUI:A4B1EE* + ID_OUI_FROM_DATABASE=H. ZANDER GmbH & Co. KG + +OUI:A4B2A7* + ID_OUI_FROM_DATABASE=Adaxys Solutions AG + +OUI:A4B36A* + ID_OUI_FROM_DATABASE=JSC SDO Chromatec + +OUI:A4B980* + ID_OUI_FROM_DATABASE=Parking BOXX Inc. + +OUI:A4BADB* + ID_OUI_FROM_DATABASE=Dell Inc. + +OUI:A4BE61* + ID_OUI_FROM_DATABASE=EutroVision System, Inc. + +OUI:A4C0E1* + ID_OUI_FROM_DATABASE=Nintendo Co., Ltd. + +OUI:A4C2AB* + ID_OUI_FROM_DATABASE=Hangzhou LEAD-IT Information & Technology Co.,Ltd + +OUI:A4D18F* + ID_OUI_FROM_DATABASE=Shenzhen Skyee Optical Fiber Communication Technology Ltd. + +OUI:A4D1D1* + ID_OUI_FROM_DATABASE=ECOtality North America + +OUI:A4D1D2* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:A4D856* + ID_OUI_FROM_DATABASE=Qualcomm Labs Inc. + +OUI:A4DA3F* + ID_OUI_FROM_DATABASE=Bionics Corp. + +OUI:A4DB2E* + ID_OUI_FROM_DATABASE=Kingspan Environmental Ltd + +OUI:A4DE50* + ID_OUI_FROM_DATABASE=Total Walther GmbH + +OUI:A4E32E* + ID_OUI_FROM_DATABASE=Silicon & Software Systems Ltd. + +OUI:A4E391* + ID_OUI_FROM_DATABASE=DENY FONTAINE + +OUI:A4E731* + ID_OUI_FROM_DATABASE=Nokia Corporation + +OUI:A4E7E4* + ID_OUI_FROM_DATABASE=Connex GmbH + +OUI:A4ED4E* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:A4EE57* + ID_OUI_FROM_DATABASE=SEIKO EPSON CORPORATION + +OUI:A4EF52* + ID_OUI_FROM_DATABASE=Telewave Co., Ltd. + +OUI:A4F7D0* + ID_OUI_FROM_DATABASE=LAN Accessories Co., Ltd. + +OUI:A80180* + ID_OUI_FROM_DATABASE=IMAGO Technologies GmbH + +OUI:A80600* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:A816B2* + ID_OUI_FROM_DATABASE=LG Electronics + +OUI:A81758* + ID_OUI_FROM_DATABASE=Elektronik System i Umeå AB + +OUI:A81B18* + ID_OUI_FROM_DATABASE=XTS CORP + +OUI:A81FAF* + ID_OUI_FROM_DATABASE=KRYPTON POLSKA + +OUI:A82066* + ID_OUI_FROM_DATABASE=Apple Inc + +OUI:A826D9* + ID_OUI_FROM_DATABASE=HTC Corporation + +OUI:A82BD6* + ID_OUI_FROM_DATABASE=Shina System Co., Ltd + +OUI:A830AD* + ID_OUI_FROM_DATABASE=Wei Fang Goertek Electronics Co.,Ltd + +OUI:A83944* + ID_OUI_FROM_DATABASE=Actiontec Electronics, Inc + +OUI:A84041* + ID_OUI_FROM_DATABASE=Dragino Technology Co., Limited + +OUI:A84481* + ID_OUI_FROM_DATABASE=Nokia Corporation + +OUI:A845E9* + ID_OUI_FROM_DATABASE=Firich Enterprises CO., LTD. + +OUI:A849A5* + ID_OUI_FROM_DATABASE=Lisantech Co., Ltd. + +OUI:A854B2* + ID_OUI_FROM_DATABASE=Wistron Neweb Corp. + +OUI:A8556A* + ID_OUI_FROM_DATABASE=Pocketnet Technology Inc. + +OUI:A85BB0* + ID_OUI_FROM_DATABASE=Shenzhen Dehoo Technology Co.,Ltd + +OUI:A85BF3* + ID_OUI_FROM_DATABASE=Audivo GmbH + +OUI:A862A2* + ID_OUI_FROM_DATABASE=JIWUMEDIA CO., LTD. + +OUI:A863DF* + ID_OUI_FROM_DATABASE=DISPLAIRE CORPORATION + +OUI:A863F2* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:A865B2* + ID_OUI_FROM_DATABASE=DONGGUAN YISHANG ELECTRONIC TECHNOLOGY CO., LIMITED + +OUI:A86A6F* + ID_OUI_FROM_DATABASE=RIM + +OUI:A870A5* + ID_OUI_FROM_DATABASE=UniComm Inc. + +OUI:A875D6* + ID_OUI_FROM_DATABASE=FreeTek International Co., Ltd. + +OUI:A8776F* + ID_OUI_FROM_DATABASE=Zonoff + +OUI:A87B39* + ID_OUI_FROM_DATABASE=Nokia Corporation + +OUI:A87E33* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:A88792* + ID_OUI_FROM_DATABASE=Broadband Antenna Tracking Systems + +OUI:A887ED* + ID_OUI_FROM_DATABASE=ARC Wireless LLC + +OUI:A88CEE* + ID_OUI_FROM_DATABASE=MicroMade Galka i Drozdz sp.j. + +OUI:A8922C* + ID_OUI_FROM_DATABASE=LG Electronics + +OUI:A893E6* + ID_OUI_FROM_DATABASE=JIANGXI JINGGANGSHAN CKING COMMUNICATION TECHNOLOGY CO.,LTD + +OUI:A895B0* + ID_OUI_FROM_DATABASE=Aker Subsea Ltd + +OUI:A8968A* + ID_OUI_FROM_DATABASE=Apple + +OUI:A898C6* + ID_OUI_FROM_DATABASE=Shinbo Co., Ltd. + +OUI:A8995C* + ID_OUI_FROM_DATABASE=aizo ag + +OUI:A89B10* + ID_OUI_FROM_DATABASE=inMotion Ltd. + +OUI:A8AD3D* + ID_OUI_FROM_DATABASE=Alcatel-Lucent Shanghai Bell Co., Ltd + +OUI:A8B0AE* + ID_OUI_FROM_DATABASE=LEONI + +OUI:A8B1D4* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:A8BD1A* + ID_OUI_FROM_DATABASE=Honey Bee (Hong Kong) Limited + +OUI:A8C222* + ID_OUI_FROM_DATABASE=TM-Research Inc. + +OUI:A8CB95* + ID_OUI_FROM_DATABASE=EAST BEST CO., LTD. + +OUI:A8CE90* + ID_OUI_FROM_DATABASE=CVC + +OUI:A8D0E5* + ID_OUI_FROM_DATABASE=Juniper Networks + +OUI:A8D3C8* + ID_OUI_FROM_DATABASE=Wachendorff Elektronik GmbH & Co. KG + +OUI:A8E018* + ID_OUI_FROM_DATABASE=Nokia Corporation + +OUI:A8E3EE* + ID_OUI_FROM_DATABASE=Sony Computer Entertainment Inc. + +OUI:A8EF26* + ID_OUI_FROM_DATABASE=Tritonwave + +OUI:A8F274* + ID_OUI_FROM_DATABASE=Samsung Electronics + +OUI:A8F470* + ID_OUI_FROM_DATABASE=Fujian Newland Communication Science Technologies Co.,Ltd. + +OUI:A8F94B* + ID_OUI_FROM_DATABASE=Eltex Enterprise Ltd. + +OUI:A8FAD8* + ID_OUI_FROM_DATABASE=Apple + +OUI:A8FCB7* + ID_OUI_FROM_DATABASE=Consolidated Resource Imaging + +OUI:AA0000* + ID_OUI_FROM_DATABASE=DIGITAL EQUIPMENT CORPORATION + +OUI:AA0001* + ID_OUI_FROM_DATABASE=DIGITAL EQUIPMENT CORPORATION + +OUI:AA0002* + ID_OUI_FROM_DATABASE=DIGITAL EQUIPMENT CORPORATION + +OUI:AA0003* + ID_OUI_FROM_DATABASE=DIGITAL EQUIPMENT CORPORATION + +OUI:AA0004* + ID_OUI_FROM_DATABASE=DIGITAL EQUIPMENT CORPORATION + +OUI:AC0142* + ID_OUI_FROM_DATABASE=Uriel Technologies SIA + +OUI:AC02CF* + ID_OUI_FROM_DATABASE=RW Tecnologia Industria e Comercio Ltda + +OUI:AC02EF* + ID_OUI_FROM_DATABASE=Comsis + +OUI:AC0613* + ID_OUI_FROM_DATABASE=Senselogix Ltd + +OUI:AC0A61* + ID_OUI_FROM_DATABASE=Labor S.r.L. + +OUI:AC0DFE* + ID_OUI_FROM_DATABASE=Ekon GmbH - myGEKKO + +OUI:AC1461* + ID_OUI_FROM_DATABASE=ATAW Co., Ltd. + +OUI:AC14D2* + ID_OUI_FROM_DATABASE=wi-daq, inc. + +OUI:AC162D* + ID_OUI_FROM_DATABASE=Hewlett Packard + +OUI:AC1702* + ID_OUI_FROM_DATABASE=Fibar Group sp. z o.o. + +OUI:AC199F* + ID_OUI_FROM_DATABASE=SUNGROW POWER SUPPLY CO.,LTD. + +OUI:AC20AA* + ID_OUI_FROM_DATABASE=DMATEK Co., Ltd. + +OUI:AC2FA8* + ID_OUI_FROM_DATABASE=Humannix Co.,Ltd. + +OUI:AC319D* + ID_OUI_FROM_DATABASE=Shenzhen TG-NET Botone Technology Co.,Ltd. + +OUI:AC34CB* + ID_OUI_FROM_DATABASE=Shanhai GBCOM Communication Technology Co. Ltd + +OUI:AC3C0B* + ID_OUI_FROM_DATABASE=Apple + +OUI:AC3CB4* + ID_OUI_FROM_DATABASE=Nilan A/S + +OUI:AC3D05* + ID_OUI_FROM_DATABASE=Instorescreen Aisa + +OUI:AC3D75* + ID_OUI_FROM_DATABASE=HANGZHOU ZHIWAY TECHNOLOGIES CO.,LTD. + +OUI:AC3FA4* + ID_OUI_FROM_DATABASE=TAIYO YUDEN CO.,LTD + +OUI:AC40EA* + ID_OUI_FROM_DATABASE=C&T Solution Inc. + +OUI:AC44F2* + ID_OUI_FROM_DATABASE=Revolabs Inc + +OUI:AC4723* + ID_OUI_FROM_DATABASE=Genelec + +OUI:AC4AFE* + ID_OUI_FROM_DATABASE=Hisense Broadband Multimedia Technology Co.,Ltd. + +OUI:AC4BC8* + ID_OUI_FROM_DATABASE=Juniper Networks + +OUI:AC4FFC* + ID_OUI_FROM_DATABASE=SVS-VISTEK GmbH + +OUI:AC5135* + ID_OUI_FROM_DATABASE=MPI TECH + +OUI:AC51EE* + ID_OUI_FROM_DATABASE=Cambridge Communication Systems Ltd + +OUI:AC54EC* + ID_OUI_FROM_DATABASE=IEEE P1823 Standards Working Group + +OUI:AC583B* + ID_OUI_FROM_DATABASE=Human Assembler, Inc. + +OUI:AC5D10* + ID_OUI_FROM_DATABASE=Pace Americas + +OUI:AC5E8C* + ID_OUI_FROM_DATABASE=Utillink + +OUI:AC6123* + ID_OUI_FROM_DATABASE=Drivven, Inc. + +OUI:AC6706* + ID_OUI_FROM_DATABASE=Ruckus Wireless + +OUI:AC6E1A* + ID_OUI_FROM_DATABASE=Shenzhen Gongjin Electronics Co.,Ltd + +OUI:AC6F4F* + ID_OUI_FROM_DATABASE=Enspert Inc + +OUI:AC6FBB* + ID_OUI_FROM_DATABASE=TATUNG Technology Inc. + +OUI:AC6FD9* + ID_OUI_FROM_DATABASE=Valueplus Inc. + +OUI:AC7236* + ID_OUI_FROM_DATABASE=Lexking Technology Co., Ltd. + +OUI:AC7289* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:AC7A42* + ID_OUI_FROM_DATABASE=iConnectivity + +OUI:AC7BA1* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:AC80D6* + ID_OUI_FROM_DATABASE=Hexatronic AB + +OUI:AC8112* + ID_OUI_FROM_DATABASE=Gemtek Technology Co., Ltd. + +OUI:AC81F3* + ID_OUI_FROM_DATABASE=Nokia Corporation + +OUI:AC8317* + ID_OUI_FROM_DATABASE=Shenzhen Furtunetel Communication Co., Ltd + +OUI:AC83F0* + ID_OUI_FROM_DATABASE=Magenta Video Networks + +OUI:AC8674* + ID_OUI_FROM_DATABASE=Open Mesh, Inc. + +OUI:AC867E* + ID_OUI_FROM_DATABASE=Create New Technology (HK) Limited Company + +OUI:AC8ACD* + ID_OUI_FROM_DATABASE=ROGER D.Wensker, G.Wensker sp.j. + +OUI:AC8D14* + ID_OUI_FROM_DATABASE=Smartrove Inc + +OUI:AC932F* + ID_OUI_FROM_DATABASE=Nokia Corporation + +OUI:AC9403* + ID_OUI_FROM_DATABASE=Envision Peripherals Inc + +OUI:AC9A96* + ID_OUI_FROM_DATABASE=Lantiq Deutschland GmbH + +OUI:AC9B84* + ID_OUI_FROM_DATABASE=Smak Tecnologia e Automacao + +OUI:AC9CE4* + ID_OUI_FROM_DATABASE=Alcatel-Lucent Shanghai Bell Co., Ltd + +OUI:ACA016* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:ACA22C* + ID_OUI_FROM_DATABASE=Baycity Technologies Ltd + +OUI:ACA430* + ID_OUI_FROM_DATABASE=Peerless AV + +OUI:ACAB8D* + ID_OUI_FROM_DATABASE=Lyngso Marine A/S + +OUI:ACBD0B* + ID_OUI_FROM_DATABASE=IMAC CO.,LTD + +OUI:ACBE75* + ID_OUI_FROM_DATABASE=Ufine Technologies Co.,Ltd. + +OUI:ACBEB6* + ID_OUI_FROM_DATABASE=Visualedge Technology Co., Ltd. + +OUI:ACC2EC* + ID_OUI_FROM_DATABASE=CLT INT'L IND. CORP. + +OUI:ACC698* + ID_OUI_FROM_DATABASE=Kohzu Precision Co., Ltd. + +OUI:ACC935* + ID_OUI_FROM_DATABASE=Ness Corporation + +OUI:ACCA54* + ID_OUI_FROM_DATABASE=Telldus Technologies AB + +OUI:ACCABA* + ID_OUI_FROM_DATABASE=Midokura Co., Ltd. + +OUI:ACCB09* + ID_OUI_FROM_DATABASE=Hefcom Metering (Pty) Ltd + +OUI:ACCC8E* + ID_OUI_FROM_DATABASE=Axis Communications AB + +OUI:ACCE8F* + ID_OUI_FROM_DATABASE=HWA YAO TECHNOLOGIES CO., LTD + +OUI:ACCF23* + ID_OUI_FROM_DATABASE=Hi-flying electronics technology Co.,Ltd + +OUI:ACD180* + ID_OUI_FROM_DATABASE=Crexendo Business Solutions, Inc. + +OUI:ACD364* + ID_OUI_FROM_DATABASE=ABB SPA, ABB SACE DIV. + +OUI:ACD9D6* + ID_OUI_FROM_DATABASE=tci GmbH + +OUI:ACDBDA* + ID_OUI_FROM_DATABASE=Shenzhen Geniatech Inc, Ltd + +OUI:ACE215* + ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd + +OUI:ACE348* + ID_OUI_FROM_DATABASE=MadgeTech, Inc + +OUI:ACE64B* + ID_OUI_FROM_DATABASE=Shenzhen Baojia Battery Technology Co., Ltd. + +OUI:ACE87B* + ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd + +OUI:ACE87E* + ID_OUI_FROM_DATABASE=Bytemark Computer Consulting Ltd + +OUI:ACE97F* + ID_OUI_FROM_DATABASE=IoT Tech Limited + +OUI:ACE9AA* + ID_OUI_FROM_DATABASE=Hay Systems Ltd + +OUI:ACEA6A* + ID_OUI_FROM_DATABASE=GENIX INFOCOMM CO., LTD. + +OUI:ACEE3B* + ID_OUI_FROM_DATABASE=6harmonics Inc + +OUI:ACF0B2* + ID_OUI_FROM_DATABASE=Becker Electronics Taiwan Ltd. + +OUI:ACF1DF* + ID_OUI_FROM_DATABASE=D-Link International + +OUI:ACF2C5* + ID_OUI_FROM_DATABASE=Cisco + +OUI:ACF7F3* + ID_OUI_FROM_DATABASE=XIAOMI CORPORATION + +OUI:ACF97E* + ID_OUI_FROM_DATABASE=ELESYS INC. + +OUI:B01203* + ID_OUI_FROM_DATABASE=Dynamics Hong Kong Limited + +OUI:B01266* + ID_OUI_FROM_DATABASE=Futaba-Kikaku + +OUI:B01408* + ID_OUI_FROM_DATABASE=LIGHTSPEED INTERNATIONAL CO. + +OUI:B01B7C* + ID_OUI_FROM_DATABASE=Ontrol A.S. + +OUI:B01C91* + ID_OUI_FROM_DATABASE=Elim Co + +OUI:B0358D* + ID_OUI_FROM_DATABASE=Nokia Corporation + +OUI:B03829* + ID_OUI_FROM_DATABASE=Siliconware Precision Industries Co., Ltd. + +OUI:B0435D* + ID_OUI_FROM_DATABASE=NuLEDs, Inc. + +OUI:B046FC* + ID_OUI_FROM_DATABASE=MitraStar Technology Corp. + +OUI:B0487A* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO., LTD. + +OUI:B0518E* + ID_OUI_FROM_DATABASE=Holl technology CO.Ltd. + +OUI:B058C4* + ID_OUI_FROM_DATABASE=Broadcast Microwave Services, Inc + +OUI:B05B1F* + ID_OUI_FROM_DATABASE=THERMO FISHER SCIENTIFIC S.P.A. + +OUI:B05CE5* + ID_OUI_FROM_DATABASE=Nokia Corporation + +OUI:B06563* + ID_OUI_FROM_DATABASE=Shanghai Railway Communication Factory + +OUI:B065BD* + ID_OUI_FROM_DATABASE=Apple Inc + +OUI:B06CBF* + ID_OUI_FROM_DATABASE=3ality Digital Systems GmbH + +OUI:B0750C* + ID_OUI_FROM_DATABASE=QA Cafe + +OUI:B075D5* + ID_OUI_FROM_DATABASE=ZTE Corporation + +OUI:B077AC* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:B07994* + ID_OUI_FROM_DATABASE=Motorola Mobility LLC + +OUI:B07D62* + ID_OUI_FROM_DATABASE=Dipl.-Ing. H. Horstmann GmbH + +OUI:B081D8* + ID_OUI_FROM_DATABASE=I-sys Corp + +OUI:B08991* + ID_OUI_FROM_DATABASE=LGE + +OUI:B08E1A* + ID_OUI_FROM_DATABASE=URadio Systems Co., Ltd + +OUI:B09074* + ID_OUI_FROM_DATABASE=Fulan Electronics Limited + +OUI:B09134* + ID_OUI_FROM_DATABASE=Taleo + +OUI:B0973A* + ID_OUI_FROM_DATABASE=E-Fuel Corporation + +OUI:B09928* + ID_OUI_FROM_DATABASE=Fujitsu Limited + +OUI:B09AE2* + ID_OUI_FROM_DATABASE=STEMMER IMAGING GmbH + +OUI:B09BD4* + ID_OUI_FROM_DATABASE=GNH Software India Private Limited + +OUI:B0A10A* + ID_OUI_FROM_DATABASE=Pivotal Systems Corporation + +OUI:B0A72A* + ID_OUI_FROM_DATABASE=Ensemble Designs, Inc. + +OUI:B0A86E* + ID_OUI_FROM_DATABASE=Juniper Networks + +OUI:B0AA36* + ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD. + +OUI:B0ACFA* + ID_OUI_FROM_DATABASE=Fujitsu Limited + +OUI:B0B2DC* + ID_OUI_FROM_DATABASE=Zyxel Communications Corporation + +OUI:B0B32B* + ID_OUI_FROM_DATABASE=Slican Sp. z o.o. + +OUI:B0B8D5* + ID_OUI_FROM_DATABASE=Nanjing Nengrui Auto Equipment CO.,Ltd + +OUI:B0BD6D* + ID_OUI_FROM_DATABASE=Echostreams Innovative Solutions + +OUI:B0BDA1* + ID_OUI_FROM_DATABASE=ZAKLAD ELEKTRONICZNY SIMS + +OUI:B0BF99* + ID_OUI_FROM_DATABASE=WIZITDONGDO + +OUI:B0C4E7* + ID_OUI_FROM_DATABASE=Samsung Electronics + +OUI:B0C69A* + ID_OUI_FROM_DATABASE=Juniper Networks + +OUI:B0C745* + ID_OUI_FROM_DATABASE=Buffalo Inc. + +OUI:B0C83F* + ID_OUI_FROM_DATABASE=Jiangsu Cynray IOT Co., Ltd. + +OUI:B0C8AD* + ID_OUI_FROM_DATABASE=People Power Company + +OUI:B0C95B* + ID_OUI_FROM_DATABASE=Beijing Symtech CO.,LTD + +OUI:B0CF4D* + ID_OUI_FROM_DATABASE=MI-Zone Technology Ireland + +OUI:B0D09C* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:B0D2F5* + ID_OUI_FROM_DATABASE=Vello Systems, Inc. + +OUI:B0E39D* + ID_OUI_FROM_DATABASE=CAT SYSTEM CO.,LTD. + +OUI:B0E50E* + ID_OUI_FROM_DATABASE=NRG SYSTEMS INC + +OUI:B0E754* + ID_OUI_FROM_DATABASE=2Wire + +OUI:B0E892* + ID_OUI_FROM_DATABASE=SEIKO EPSON CORPORATION + +OUI:B0E97E* + ID_OUI_FROM_DATABASE=Advanced Micro Peripherals + +OUI:B0EC71* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:B0EE45* + ID_OUI_FROM_DATABASE=AzureWave Technologies, Inc. + +OUI:B0F1BC* + ID_OUI_FROM_DATABASE=Dhemax Ingenieros Ltda + +OUI:B0FAEB* + ID_OUI_FROM_DATABASE=Cisco + +OUI:B4009C* + ID_OUI_FROM_DATABASE=CableWorld Ltd. + +OUI:B40142* + ID_OUI_FROM_DATABASE=GCI Science & Technology Co.,LTD + +OUI:B40418* + ID_OUI_FROM_DATABASE=Smartchip Integrated Inc. + +OUI:B407F9* + ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO-MECHANICS + +OUI:B40832* + ID_OUI_FROM_DATABASE=TC Communications + +OUI:B40B7A* + ID_OUI_FROM_DATABASE=Brusa Elektronik AG + +OUI:B40C25* + ID_OUI_FROM_DATABASE=Palo Alto Networks + +OUI:B40E96* + ID_OUI_FROM_DATABASE=HERAN + +OUI:B40EDC* + ID_OUI_FROM_DATABASE=LG-Ericsson Co.,Ltd. + +OUI:B41489* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:B41DEF* + ID_OUI_FROM_DATABASE=Internet Laboratories, Inc. + +OUI:B4211D* + ID_OUI_FROM_DATABASE=Beijing GuangXin Technology Co., Ltd + +OUI:B4218A* + ID_OUI_FROM_DATABASE=Dog Hunter LLC + +OUI:B428F1* + ID_OUI_FROM_DATABASE=E-Prime Co., Ltd. + +OUI:B42A39* + ID_OUI_FROM_DATABASE=ORBIT MERRET, spol. s r. o. + +OUI:B42CBE* + ID_OUI_FROM_DATABASE=Direct Payment Solutions Limited + +OUI:B431B8* + ID_OUI_FROM_DATABASE=Aviwest + +OUI:B43564* + ID_OUI_FROM_DATABASE=Fujian Tian Cheng Electron Science & Technical Development Co.,Ltd. + +OUI:B435F7* + ID_OUI_FROM_DATABASE=Zhejiang Pearmain Electronics Co.ltd. + +OUI:B43741* + ID_OUI_FROM_DATABASE=Consert, Inc. + +OUI:B439D6* + ID_OUI_FROM_DATABASE=ProCurve Networking by HP + +OUI:B43DB2* + ID_OUI_FROM_DATABASE=Degreane Horizon + +OUI:B4417A* + ID_OUI_FROM_DATABASE=ShenZhen Gongjin Electronics Co.,Ltd + +OUI:B44CC2* + ID_OUI_FROM_DATABASE=NR ELECTRIC CO., LTD + +OUI:B451F9* + ID_OUI_FROM_DATABASE=NB Software + +OUI:B45253* + ID_OUI_FROM_DATABASE=Seagate Technology + +OUI:B45570* + ID_OUI_FROM_DATABASE=Borea + +OUI:B45861* + ID_OUI_FROM_DATABASE=CRemote, LLC + +OUI:B45CA4* + ID_OUI_FROM_DATABASE=Thing-talk Wireless Communication Technologies Corporation Limited + +OUI:B461FF* + ID_OUI_FROM_DATABASE=Lumigon A/S + +OUI:B46238* + ID_OUI_FROM_DATABASE=Exablox + +OUI:B46293* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:B467E9* + ID_OUI_FROM_DATABASE=Qingdao GoerTek Technology Co., Ltd. + +OUI:B4749F* + ID_OUI_FROM_DATABASE=askey computer corp + +OUI:B47F5E* + ID_OUI_FROM_DATABASE=Foresight Manufacture (S) Pte Ltd + +OUI:B48255* + ID_OUI_FROM_DATABASE=Research Products Corporation + +OUI:B482C5* + ID_OUI_FROM_DATABASE=Relay2, Inc. + +OUI:B482FE* + ID_OUI_FROM_DATABASE=Askey Computer Corp + +OUI:B48910* + ID_OUI_FROM_DATABASE=Coster T.E. S.P.A. + +OUI:B4944E* + ID_OUI_FROM_DATABASE=WeTelecom Co., Ltd. + +OUI:B49842* + ID_OUI_FROM_DATABASE=zte corporation + +OUI:B499BA* + ID_OUI_FROM_DATABASE=Hewlett-Packard Company + +OUI:B49DB4* + ID_OUI_FROM_DATABASE=Axion Technologies Inc. + +OUI:B49EE6* + ID_OUI_FROM_DATABASE=SHENZHEN TECHNOLOGY CO LTD + +OUI:B4A4B5* + ID_OUI_FROM_DATABASE=Zen Eye Co.,Ltd + +OUI:B4A4E3* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:B4A5A9* + ID_OUI_FROM_DATABASE=MODI GmbH + +OUI:B4AA4D* + ID_OUI_FROM_DATABASE=Ensequence, Inc. + +OUI:B4AB2C* + ID_OUI_FROM_DATABASE=MtM Technology Corporation + +OUI:B4B017* + ID_OUI_FROM_DATABASE=Avaya, Inc + +OUI:B4B362* + ID_OUI_FROM_DATABASE=ZTE Corporation + +OUI:B4B52F* + ID_OUI_FROM_DATABASE=Hewlett Packard + +OUI:B4B5AF* + ID_OUI_FROM_DATABASE=Minsung Electronics + +OUI:B4B676* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:B4B88D* + ID_OUI_FROM_DATABASE=Thuh Company + +OUI:B4C44E* + ID_OUI_FROM_DATABASE=VXL eTech Pvt Ltd + +OUI:B4C799* + ID_OUI_FROM_DATABASE=Motorola Solutions Inc. + +OUI:B4C810* + ID_OUI_FROM_DATABASE=UMPI Elettronica + +OUI:B4CFDB* + ID_OUI_FROM_DATABASE=Shenzhen Jiuzhou Electric Co.,LTD + +OUI:B4D8A9* + ID_OUI_FROM_DATABASE=BetterBots + +OUI:B4D8DE* + ID_OUI_FROM_DATABASE=iota Computing, Inc. + +OUI:B4DF3B* + ID_OUI_FROM_DATABASE=Chromlech + +OUI:B4DFFA* + ID_OUI_FROM_DATABASE=Litemax Electronics Inc. + +OUI:B4E0CD* + ID_OUI_FROM_DATABASE=IO Turbine, Inc. + +OUI:B4E9B0* + ID_OUI_FROM_DATABASE=Cisco + +OUI:B4ED19* + ID_OUI_FROM_DATABASE=Pie Digital, Inc. + +OUI:B4ED54* + ID_OUI_FROM_DATABASE=Wohler Technologies + +OUI:B4EED4* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:B4F0AB* + ID_OUI_FROM_DATABASE=Apple + +OUI:B4F2E8* + ID_OUI_FROM_DATABASE=Pace plc + +OUI:B4F323* + ID_OUI_FROM_DATABASE=PETATEL INC. + +OUI:B4FC75* + ID_OUI_FROM_DATABASE=SEMA Electronics(HK) CO.,LTD + +OUI:B80305* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:B80415* + ID_OUI_FROM_DATABASE=Bayan Audio + +OUI:B80B9D* + ID_OUI_FROM_DATABASE=ROPEX Industrie-Elektronik GmbH + +OUI:B81413* + ID_OUI_FROM_DATABASE=Keen High Holding(HK) Ltd. + +OUI:B817C2* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:B81999* + ID_OUI_FROM_DATABASE=Nesys + +OUI:B820E7* + ID_OUI_FROM_DATABASE=Guangzhou Horizontal Information & Network Integration Co. Ltd + +OUI:B82410* + ID_OUI_FROM_DATABASE=Magneti Marelli Slovakia s.r.o. + +OUI:B826D4* + ID_OUI_FROM_DATABASE=Furukawa Industrial S.A. Produtos Elétricos + +OUI:B827EB* + ID_OUI_FROM_DATABASE=Raspberry Pi Foundation + +OUI:B8288B* + ID_OUI_FROM_DATABASE=Parker Hannifin + +OUI:B829F7* + ID_OUI_FROM_DATABASE=Blaster Tech + +OUI:B82ADC* + ID_OUI_FROM_DATABASE=EFR Europäische Funk-Rundsteuerung GmbH + +OUI:B82CA0* + ID_OUI_FROM_DATABASE=Honeywell HomMed + +OUI:B838CA* + ID_OUI_FROM_DATABASE=Kyokko Tsushin System CO.,LTD + +OUI:B83A7B* + ID_OUI_FROM_DATABASE=Worldplay (Canada) Inc. + +OUI:B83D4E* + ID_OUI_FROM_DATABASE=Shenzhen Cultraview Digital Technology Co.,Ltd Shanghai Branch + +OUI:B83E59* + ID_OUI_FROM_DATABASE=Roku, Inc + +OUI:B8415F* + ID_OUI_FROM_DATABASE=ASP AG + +OUI:B85510* + ID_OUI_FROM_DATABASE=Zioncom Electronics (Shenzhen) Ltd. + +OUI:B85810* + ID_OUI_FROM_DATABASE=NUMERA, INC. + +OUI:B85AF7* + ID_OUI_FROM_DATABASE=Ouya, Inc + +OUI:B85AFE* + ID_OUI_FROM_DATABASE=Handaer Communication Technology (Beijing) Co., Ltd + +OUI:B86091* + ID_OUI_FROM_DATABASE=Onnet Technologies and Innovations LLC + +OUI:B8616F* + ID_OUI_FROM_DATABASE=Accton Wireless Broadband(AWB), Corp. + +OUI:B8621F* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:B86491* + ID_OUI_FROM_DATABASE=CK Telecom Ltd + +OUI:B8653B* + ID_OUI_FROM_DATABASE=Bolymin, Inc. + +OUI:B86B23* + ID_OUI_FROM_DATABASE=Toshiba + +OUI:B870F4* + ID_OUI_FROM_DATABASE=COMPAL INFORMATION (KUNSHAN) CO., LTD. + +OUI:B87424* + ID_OUI_FROM_DATABASE=Viessmann Elektronik GmbH + +OUI:B87447* + ID_OUI_FROM_DATABASE=Convergence Technologies + +OUI:B8763F* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + +OUI:B877C3* + ID_OUI_FROM_DATABASE=Decagon Devices, Inc. + +OUI:B8797E* + ID_OUI_FROM_DATABASE=Secure Meters (UK) Limited + +OUI:B8871E* + ID_OUI_FROM_DATABASE=Good Mind Industries Co., Ltd. + +OUI:B888E3* + ID_OUI_FROM_DATABASE=COMPAL INFORMATION (KUNSHAN) CO., LTD + +OUI:B889CA* + ID_OUI_FROM_DATABASE=ILJIN ELECTRIC Co., Ltd. + +OUI:B88A60* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:B88D12* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:B88E3A* + ID_OUI_FROM_DATABASE=Infinite Technologies JLT + +OUI:B88F14* + ID_OUI_FROM_DATABASE=Analytica GmbH + +OUI:B8921D* + ID_OUI_FROM_DATABASE=BG T&A + +OUI:B894D2* + ID_OUI_FROM_DATABASE=Retail Innovation HTT AB + +OUI:B89674* + ID_OUI_FROM_DATABASE=AllDSP GmbH & Co. KG + +OUI:B8975A* + ID_OUI_FROM_DATABASE=BIOSTAR Microtech Int'l Corp. + +OUI:B898B0* + ID_OUI_FROM_DATABASE=Atlona Inc. + +OUI:B89AED* + ID_OUI_FROM_DATABASE=OceanServer Technology, Inc + +OUI:B89BC9* + ID_OUI_FROM_DATABASE=SMC Networks Inc + +OUI:B8A386* + ID_OUI_FROM_DATABASE=D-Link International + +OUI:B8A3E0* + ID_OUI_FROM_DATABASE=BenRui Technology Co.,Ltd + +OUI:B8A8AF* + ID_OUI_FROM_DATABASE=Logic S.p.A. + +OUI:B8AC6F* + ID_OUI_FROM_DATABASE=Dell Inc + +OUI:B8AF67* + ID_OUI_FROM_DATABASE=Hewlett-Packard Company + +OUI:B8B1C7* + ID_OUI_FROM_DATABASE=BT&COM CO.,LTD + +OUI:B8B42E* + ID_OUI_FROM_DATABASE=Gionee Communication Equipment Co,Ltd.ShenZhen + +OUI:B8B7D7* + ID_OUI_FROM_DATABASE=2GIG Technologies + +OUI:B8B94E* + ID_OUI_FROM_DATABASE=Shenzhen iBaby Labs, Inc. + +OUI:B8BA68* + ID_OUI_FROM_DATABASE=Xi'an Jizhong Digital Communication Co.,Ltd + +OUI:B8BA72* + ID_OUI_FROM_DATABASE=Cynove + +OUI:B8BB6D* + ID_OUI_FROM_DATABASE=ENERES Co.,Ltd. + +OUI:B8BEBF* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:B8C68E* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:B8C716* + ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD + +OUI:B8C75D* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:B8CA3A* + ID_OUI_FROM_DATABASE=Dell PCBA Test + +OUI:B8CDA7* + ID_OUI_FROM_DATABASE=Maxeler Technologies Ltd. + +OUI:B8D06F* + ID_OUI_FROM_DATABASE=GUANGZHOU HKUST FOK YING TUNG RESEARCH INSTITUTE + +OUI:B8D49D* + ID_OUI_FROM_DATABASE=M Seven System Ltd. + +OUI:B8D9CE* + ID_OUI_FROM_DATABASE=Samsung Electronics + +OUI:B8DAF1* + ID_OUI_FROM_DATABASE=Strahlenschutz- Entwicklungs- und Ausruestungsgesellschaft mbH + +OUI:B8DAF7* + ID_OUI_FROM_DATABASE=Advanced Photonics, Inc. + +OUI:B8E589* + ID_OUI_FROM_DATABASE=Payter BV + +OUI:B8E625* + ID_OUI_FROM_DATABASE=2Wire + +OUI:B8E779* + ID_OUI_FROM_DATABASE=9Solutions Oy + +OUI:B8E937* + ID_OUI_FROM_DATABASE=Sonos, Inc. + +OUI:B8EE79* + ID_OUI_FROM_DATABASE=YWire Technologies, Inc. + +OUI:B8F4D0* + ID_OUI_FROM_DATABASE=Herrmann Ultraschalltechnik GmbH & Co. Kg + +OUI:B8F5E7* + ID_OUI_FROM_DATABASE=WayTools, LLC + +OUI:B8F6B1* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:B8F732* + ID_OUI_FROM_DATABASE=Aryaka Networks Inc + +OUI:B8F934* + ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications AB + +OUI:B8FD32* + ID_OUI_FROM_DATABASE=Zhejiang ROICX Microelectronics + +OUI:B8FF61* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:B8FF6F* + ID_OUI_FROM_DATABASE=Shanghai Typrotech Technology Co.Ltd + +OUI:B8FFFE* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:BC0200* + ID_OUI_FROM_DATABASE=Stewart Audio + +OUI:BC0543* + ID_OUI_FROM_DATABASE=AVM GmbH + +OUI:BC0DA5* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:BC0F2B* + ID_OUI_FROM_DATABASE=FORTUNE TECHGROUP CO.,LTD + +OUI:BC125E* + ID_OUI_FROM_DATABASE=Beijing WisVideo INC. + +OUI:BC1401* + ID_OUI_FROM_DATABASE=Hitron Technologies. Inc + +OUI:BC15A6* + ID_OUI_FROM_DATABASE=Taiwan Jantek Electronics,Ltd. + +OUI:BC20A4* + ID_OUI_FROM_DATABASE=Samsung Electronics + +OUI:BC20BA* + ID_OUI_FROM_DATABASE=Inspur (Shandong) Electronic Information Co., Ltd + +OUI:BC2846* + ID_OUI_FROM_DATABASE=NextBIT Computing Pvt. Ltd. + +OUI:BC28D6* + ID_OUI_FROM_DATABASE=Rowley Associates Limited + +OUI:BC2C55* + ID_OUI_FROM_DATABASE=Bear Flag Design, Inc. + +OUI:BC305B* + ID_OUI_FROM_DATABASE=Dell Inc. + +OUI:BC35E5* + ID_OUI_FROM_DATABASE=Hydro Systems Company + +OUI:BC38D2* + ID_OUI_FROM_DATABASE=Pandachip Limited + +OUI:BC39A6* + ID_OUI_FROM_DATABASE=CSUN System Technology Co.,LTD + +OUI:BC3BAF* + ID_OUI_FROM_DATABASE=Apple + +OUI:BC3E13* + ID_OUI_FROM_DATABASE=Accordance Systems Inc. + +OUI:BC4377* + ID_OUI_FROM_DATABASE=Hang Zhou Huite Technology Co.,ltd. + +OUI:BC4760* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:BC4B79* + ID_OUI_FROM_DATABASE=SensingTek + +OUI:BC4E3C* + ID_OUI_FROM_DATABASE=CORE STAFF CO., LTD. + +OUI:BC51FE* + ID_OUI_FROM_DATABASE=Swann Communications Pty Ltd + +OUI:BC52B7* + ID_OUI_FROM_DATABASE=Apple Inc + +OUI:BC5FF4* + ID_OUI_FROM_DATABASE=ASRock Incorporation + +OUI:BC629F* + ID_OUI_FROM_DATABASE=Telenet Systems P. Ltd. + +OUI:BC6778* + ID_OUI_FROM_DATABASE=Apple Inc + +OUI:BC6784* + ID_OUI_FROM_DATABASE=Environics Oy + +OUI:BC6A16* + ID_OUI_FROM_DATABASE=tdvine + +OUI:BC6A29* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:BC6E76* + ID_OUI_FROM_DATABASE=Green Energy Options Ltd + +OUI:BC71C1* + ID_OUI_FROM_DATABASE=XTrillion, Inc. + +OUI:BC764E* + ID_OUI_FROM_DATABASE=Rackspace US, Inc. + +OUI:BC7670* + ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd + +OUI:BC7737* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:BC779F* + ID_OUI_FROM_DATABASE=SBM Co., Ltd. + +OUI:BC7DD1* + ID_OUI_FROM_DATABASE=Radio Data Comms + +OUI:BC811F* + ID_OUI_FROM_DATABASE=Ingate Systems + +OUI:BC8199* + ID_OUI_FROM_DATABASE=BASIC Co.,Ltd. + +OUI:BC83A7* + ID_OUI_FROM_DATABASE=SHENZHEN CHUANGWEI-RGB ELECTRONICS CO.,LT + +OUI:BC851F* + ID_OUI_FROM_DATABASE=Samsung Electronics + +OUI:BC8B55* + ID_OUI_FROM_DATABASE=NPP ELIKS America Inc. DBA T&M Atlantic + +OUI:BC99BC* + ID_OUI_FROM_DATABASE=FonSee Technology Inc. + +OUI:BC9DA5* + ID_OUI_FROM_DATABASE=DASCOM Europe GmbH + +OUI:BCA4E1* + ID_OUI_FROM_DATABASE=Nabto + +OUI:BCA9D6* + ID_OUI_FROM_DATABASE=Cyber-Rain, Inc. + +OUI:BCAEC5* + ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. + +OUI:BCB181* + ID_OUI_FROM_DATABASE=SHARP CORPORATION + +OUI:BCB1F3* + ID_OUI_FROM_DATABASE=Samsung Electronics + +OUI:BCB852* + ID_OUI_FROM_DATABASE=Cybera, Inc. + +OUI:BCBBC9* + ID_OUI_FROM_DATABASE=Kellendonk Elektronik GmbH + +OUI:BCC168* + ID_OUI_FROM_DATABASE=DInBox Sverige AB + +OUI:BCC23A* + ID_OUI_FROM_DATABASE=Thomson Video Networks + +OUI:BCC61A* + ID_OUI_FROM_DATABASE=SPECTRA EMBEDDED SYSTEMS + +OUI:BCC810* + ID_OUI_FROM_DATABASE=Cisco SPVTG + +OUI:BCCD45* + ID_OUI_FROM_DATABASE=VOISMART + +OUI:BCCFCC* + ID_OUI_FROM_DATABASE=HTC Corporation + +OUI:BCD5B6* + ID_OUI_FROM_DATABASE=d2d technologies + +OUI:BCD940* + ID_OUI_FROM_DATABASE=ASR Co,.Ltd. + +OUI:BCE09D* + ID_OUI_FROM_DATABASE=Eoslink + +OUI:BCE59F* + ID_OUI_FROM_DATABASE=WATERWORLD Technology Co.,LTD + +OUI:BCEA2B* + ID_OUI_FROM_DATABASE=CityCom GmbH + +OUI:BCF2AF* + ID_OUI_FROM_DATABASE=devolo AG + +OUI:BCF685* + ID_OUI_FROM_DATABASE=D-Link International + +OUI:BCFE8C* + ID_OUI_FROM_DATABASE=Altronic, LLC + +OUI:BCFFAC* + ID_OUI_FROM_DATABASE=TOPCON CORPORATION + +OUI:C00D7E* + ID_OUI_FROM_DATABASE=Additech, Inc. + +OUI:C011A6* + ID_OUI_FROM_DATABASE=Fort-Telecom ltd. + +OUI:C01242* + ID_OUI_FROM_DATABASE=Alpha Security Products + +OUI:C0143D* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + +OUI:C01885* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + +OUI:C01E9B* + ID_OUI_FROM_DATABASE=Pixavi AS + +OUI:C02506* + ID_OUI_FROM_DATABASE=AVM GmbH + +OUI:C027B9* + ID_OUI_FROM_DATABASE=Beijing National Railway Research & Design Institute of Signal & Communication + +OUI:C02973* + ID_OUI_FROM_DATABASE=Audyssey Laboratories Inc. + +OUI:C029F3* + ID_OUI_FROM_DATABASE=XySystem + +OUI:C02BFC* + ID_OUI_FROM_DATABASE=iNES. applied informatics GmbH + +OUI:C02C7A* + ID_OUI_FROM_DATABASE=Shen Zhen Horn audio Co., Ltd. + +OUI:C035BD* + ID_OUI_FROM_DATABASE=Velocytech Aps + +OUI:C038F9* + ID_OUI_FROM_DATABASE=Nokia Danmark A/S + +OUI:C03B8F* + ID_OUI_FROM_DATABASE=Minicom Digital Signage + +OUI:C03F0E* + ID_OUI_FROM_DATABASE=NETGEAR + +OUI:C03F2A* + ID_OUI_FROM_DATABASE=Biscotti, Inc. + +OUI:C041F6* + ID_OUI_FROM_DATABASE=LG Electronics Inc + +OUI:C044E3* + ID_OUI_FROM_DATABASE=Shenzhen Sinkna Electronics Co., LTD + +OUI:C0493D* + ID_OUI_FROM_DATABASE=MAITRISE TECHNOLOGIQUE + +OUI:C04A00* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD. + +OUI:C058A7* + ID_OUI_FROM_DATABASE=Pico Systems Co., Ltd. + +OUI:C05E6F* + ID_OUI_FROM_DATABASE=V. Stonkaus firma "Kodinis Raktas" + +OUI:C05E79* + ID_OUI_FROM_DATABASE=SHENZHEN HUAXUN ARK TECHNOLOGIES CO.,LTD + +OUI:C0626B* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:C06C0F* + ID_OUI_FROM_DATABASE=Dobbs Stanford + +OUI:C07E40* + ID_OUI_FROM_DATABASE=SHENZHEN XDK COMMUNICATION EQUIPMENT CO.,LTD + +OUI:C08170* + ID_OUI_FROM_DATABASE=Effigis GeoSolutions + +OUI:C0830A* + ID_OUI_FROM_DATABASE=2Wire + +OUI:C0847A* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:C08ADE* + ID_OUI_FROM_DATABASE=Ruckus Wireless + +OUI:C08B6F* + ID_OUI_FROM_DATABASE=S I Sistemas Inteligentes Eletrônicos Ltda + +OUI:C09132* + ID_OUI_FROM_DATABASE=Patriot Memory + +OUI:C09134* + ID_OUI_FROM_DATABASE=ProCurve Networking by HP + +OUI:C09C92* + ID_OUI_FROM_DATABASE=COBY + +OUI:C09F42* + ID_OUI_FROM_DATABASE=Apple Inc + +OUI:C0A0C7* + ID_OUI_FROM_DATABASE=FAIRFIELD INDUSTRIES + +OUI:C0A0DE* + ID_OUI_FROM_DATABASE=Multi Touch Oy + +OUI:C0A0E2* + ID_OUI_FROM_DATABASE=Eden Innovations + +OUI:C0A26D* + ID_OUI_FROM_DATABASE=Abbott Point of Care + +OUI:C0A364* + ID_OUI_FROM_DATABASE=3D Systems Burlington + +OUI:C0AA68* + ID_OUI_FROM_DATABASE=OSASI Technos Inc. + +OUI:C0AC54* + ID_OUI_FROM_DATABASE=SAGEMCOM + +OUI:C0B339* + ID_OUI_FROM_DATABASE=Comigo Ltd. + +OUI:C0B357* + ID_OUI_FROM_DATABASE=Yoshiki Electronics Industry Ltd. + +OUI:C0B8B1* + ID_OUI_FROM_DATABASE=BitBox Ltd + +OUI:C0BAE6* + ID_OUI_FROM_DATABASE=Application Solutions (Safety and Security) Ltd + +OUI:C0BD42* + ID_OUI_FROM_DATABASE=ZPA Smart Energy a.s. + +OUI:C0C1C0* + ID_OUI_FROM_DATABASE=Cisco-Linksys, LLC + +OUI:C0C520* + ID_OUI_FROM_DATABASE=Ruckus Wireless + +OUI:C0C946* + ID_OUI_FROM_DATABASE=MITSUYA LABORATORIES INC. + +OUI:C0CB38* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + +OUI:C0CFA3* + ID_OUI_FROM_DATABASE=Creative Electronics & Software, Inc. + +OUI:C0D044* + ID_OUI_FROM_DATABASE=SAGEMCOM + +OUI:C0D962* + ID_OUI_FROM_DATABASE=Askey Computer Corp. + +OUI:C0DF77* + ID_OUI_FROM_DATABASE=Conrad Electronic SE + +OUI:C0E422* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:C0E54E* + ID_OUI_FROM_DATABASE=DENX Computer Systems GmbH + +OUI:C0EAE4* + ID_OUI_FROM_DATABASE=Sonicwall + +OUI:C0F8DA* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + +OUI:C40142* + ID_OUI_FROM_DATABASE=MaxMedia Technology Limited + +OUI:C4017C* + ID_OUI_FROM_DATABASE=Ruckus Wireless + +OUI:C401B1* + ID_OUI_FROM_DATABASE=SeekTech INC + +OUI:C40ACB* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:C40F09* + ID_OUI_FROM_DATABASE=Hermes electronic GmbH + +OUI:C4108A* + ID_OUI_FROM_DATABASE=Ruckus Wireless + +OUI:C416FA* + ID_OUI_FROM_DATABASE=Prysm Inc + +OUI:C417FE* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + +OUI:C4198B* + ID_OUI_FROM_DATABASE=Dominion Voting Systems Corporation + +OUI:C41ECE* + ID_OUI_FROM_DATABASE=HMI Sources Ltd. + +OUI:C4237A* + ID_OUI_FROM_DATABASE=WhizNets Inc. + +OUI:C4242E* + ID_OUI_FROM_DATABASE=Galvanic Applied Sciences Inc + +OUI:C42C03* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:C436DA* + ID_OUI_FROM_DATABASE=Rusteletech Ltd. + +OUI:C438D3* + ID_OUI_FROM_DATABASE=TAGATEC CO.,LTD + +OUI:C4393A* + ID_OUI_FROM_DATABASE=SMC Networks Inc + +OUI:C43A9F* + ID_OUI_FROM_DATABASE=Siconix Inc. + +OUI:C43C3C* + ID_OUI_FROM_DATABASE=CYBELEC SA + +OUI:C43DC7* + ID_OUI_FROM_DATABASE=NETGEAR + +OUI:C44567* + ID_OUI_FROM_DATABASE=SAMBON PRECISON and ELECTRONICS + +OUI:C44619* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + +OUI:C44AD0* + ID_OUI_FROM_DATABASE=FIREFLIES RTLS + +OUI:C44B44* + ID_OUI_FROM_DATABASE=Omniprint Inc. + +OUI:C44EAC* + ID_OUI_FROM_DATABASE=Shenzhen Shiningworth Technology Co., Ltd. + +OUI:C455A6* + ID_OUI_FROM_DATABASE=Cadac Holdings Ltd + +OUI:C455C2* + ID_OUI_FROM_DATABASE=Bach-Simpson + +OUI:C45600* + ID_OUI_FROM_DATABASE=Galleon Embedded Computing + +OUI:C458C2* + ID_OUI_FROM_DATABASE=Shenzhen TATFOOK Technology Co., Ltd. + +OUI:C45976* + ID_OUI_FROM_DATABASE=Fugoo + +OUI:C45DD8* + ID_OUI_FROM_DATABASE=HDMI Forum + +OUI:C46044* + ID_OUI_FROM_DATABASE=Everex Electronics Limited + +OUI:C46354* + ID_OUI_FROM_DATABASE=U-Raku, Inc. + +OUI:C46413* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:C467B5* + ID_OUI_FROM_DATABASE=Libratone A/S + +OUI:C46AB7* + ID_OUI_FROM_DATABASE=Xiaomi Technology,Inc. + +OUI:C46DF1* + ID_OUI_FROM_DATABASE=DataGravity + +OUI:C47130* + ID_OUI_FROM_DATABASE=Fon Technology S.L. + +OUI:C471FE* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:C4731E* + ID_OUI_FROM_DATABASE=Samsung Eletronics Co., Ltd + +OUI:C47B2F* + ID_OUI_FROM_DATABASE=Beijing JoinHope Image Technology Ltd. + +OUI:C47BA3* + ID_OUI_FROM_DATABASE=NAVIS Inc. + +OUI:C47D4F* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:C47DCC* + ID_OUI_FROM_DATABASE=Motorola Solutions Inc. + +OUI:C4823F* + ID_OUI_FROM_DATABASE=Fujian Newland Auto-ID Tech. Co,.Ltd. + +OUI:C48508* + ID_OUI_FROM_DATABASE=Intel Corporation + +OUI:C488E5* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:C49300* + ID_OUI_FROM_DATABASE=8Devices + +OUI:C49313* + ID_OUI_FROM_DATABASE=100fio networks technology llc + +OUI:C495A2* + ID_OUI_FROM_DATABASE=SHENZHEN WEIJIU INDUSTRY AND TRADE DEVELOPMENT CO., LTD + +OUI:C49805* + ID_OUI_FROM_DATABASE=Minieum Networks, Inc + +OUI:C4AAA1* + ID_OUI_FROM_DATABASE=SUMMIT DEVELOPMENT, spol.s r.o. + +OUI:C4AD21* + ID_OUI_FROM_DATABASE=MEDIAEDGE Corporation + +OUI:C4B512* + ID_OUI_FROM_DATABASE=General Electric Digital Energy + +OUI:C4BA99* + ID_OUI_FROM_DATABASE=I+ME Actia Informatik und Mikro-Elektronik GmbH + +OUI:C4C19F* + ID_OUI_FROM_DATABASE=National Oilwell Varco Instrumentation, Monitoring, and Optimization (NOV IMO) + +OUI:C4CAD9* + ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited + +OUI:C4CD45* + ID_OUI_FROM_DATABASE=Beijing Boomsense Technology CO.,LTD. + +OUI:C4D489* + ID_OUI_FROM_DATABASE=JiangSu Joyque Information Industry Co.,Ltd + +OUI:C4D987* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:C4DA26* + ID_OUI_FROM_DATABASE=NOBLEX SA + +OUI:C4E032* + ID_OUI_FROM_DATABASE=IEEE 1904.1 Working Group + +OUI:C4E17C* + ID_OUI_FROM_DATABASE=U2S co. + +OUI:C4E7BE* + ID_OUI_FROM_DATABASE=SCSpro Co.,Ltd + +OUI:C4EBE3* + ID_OUI_FROM_DATABASE=RRCN SAS + +OUI:C4EDBA* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:C4EEAE* + ID_OUI_FROM_DATABASE=VSS Monitoring + +OUI:C4EEF5* + ID_OUI_FROM_DATABASE=Oclaro, Inc. + +OUI:C4F464* + ID_OUI_FROM_DATABASE=Spica international + +OUI:C4F57C* + ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc. + +OUI:C4FCE4* + ID_OUI_FROM_DATABASE=DishTV NZ Ltd + +OUI:C802A6* + ID_OUI_FROM_DATABASE=Beijing Newmine Technology + +OUI:C80718* + ID_OUI_FROM_DATABASE=TDSi + +OUI:C80AA9* + ID_OUI_FROM_DATABASE=Quanta Computer Inc. + +OUI:C80E77* + ID_OUI_FROM_DATABASE=Le Shi Zhi Xin Electronic Technology (Tianjin) Co.,Ltd + +OUI:C80E95* + ID_OUI_FROM_DATABASE=OmniLync Inc. + +OUI:C819F7* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:C81AFE* + ID_OUI_FROM_DATABASE=DLOGIC GmbH + +OUI:C81E8E* + ID_OUI_FROM_DATABASE=ADV Security (S) Pte Ltd + +OUI:C8208E* + ID_OUI_FROM_DATABASE=Storagedata + +OUI:C8292A* + ID_OUI_FROM_DATABASE=Barun Electronics + +OUI:C82A14* + ID_OUI_FROM_DATABASE=Apple, Inc + +OUI:C82E94* + ID_OUI_FROM_DATABASE=Halfa Enterprise Co., Ltd. + +OUI:C83232* + ID_OUI_FROM_DATABASE=Hunting Innova + +OUI:C8334B* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:C835B8* + ID_OUI_FROM_DATABASE=Ericsson, EAB/RWI/K + +OUI:C83A35* + ID_OUI_FROM_DATABASE=Tenda Technology Co., Ltd. + +OUI:C83B45* + ID_OUI_FROM_DATABASE=JRI-Maxant + +OUI:C83D97* + ID_OUI_FROM_DATABASE=Nokia Corporation + +OUI:C83E99* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:C83EA7* + ID_OUI_FROM_DATABASE=KUNBUS GmbH + +OUI:C84529* + ID_OUI_FROM_DATABASE=IMK Networks Co.,Ltd + +OUI:C84544* + ID_OUI_FROM_DATABASE=Shanghai Enlogic Electric Technology Co., Ltd. + +OUI:C848F5* + ID_OUI_FROM_DATABASE=MEDISON Xray Co., Ltd + +OUI:C84C75* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:C85645* + ID_OUI_FROM_DATABASE=Intermas France + +OUI:C86000* + ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. + +OUI:C864C7* + ID_OUI_FROM_DATABASE=zte corporation + +OUI:C86C1E* + ID_OUI_FROM_DATABASE=Display Systems Ltd + +OUI:C86C87* + ID_OUI_FROM_DATABASE=Zyxel Communications Corp + +OUI:C86CB6* + ID_OUI_FROM_DATABASE=Optcom Co., Ltd. + +OUI:C86F1D* + ID_OUI_FROM_DATABASE=Apple + +OUI:C87248* + ID_OUI_FROM_DATABASE=Aplicom Oy + +OUI:C87B5B* + ID_OUI_FROM_DATABASE=zte corporation + +OUI:C87CBC* + ID_OUI_FROM_DATABASE=Valink Co., Ltd. + +OUI:C87D77* + ID_OUI_FROM_DATABASE=Shenzhen Kingtech Communication Equipment Co.,Ltd + +OUI:C87E75* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:C88439* + ID_OUI_FROM_DATABASE=Sunrise Technologies + +OUI:C88447* + ID_OUI_FROM_DATABASE=Beautiful Enterprise Co., Ltd + +OUI:C8873B* + ID_OUI_FROM_DATABASE=Net Optics + +OUI:C88A83* + ID_OUI_FROM_DATABASE=Dongguan HuaHong Electronics Co.,Ltd + +OUI:C88B47* + ID_OUI_FROM_DATABASE=Nolangroup S.P.A con Socio Unico + +OUI:C8903E* + ID_OUI_FROM_DATABASE=Pakton Technologies + +OUI:C89383* + ID_OUI_FROM_DATABASE=Embedded Automation, Inc. + +OUI:C894D2* + ID_OUI_FROM_DATABASE=Jiangsu Datang Electronic Products Co., Ltd + +OUI:C8979F* + ID_OUI_FROM_DATABASE=Nokia Corporation + +OUI:C89C1D* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:C89CDC* + ID_OUI_FROM_DATABASE=ELITEGROUP COMPUTER SYSTEM CO., LTD. + +OUI:C89F42* + ID_OUI_FROM_DATABASE=VDII Innovation AB + +OUI:C8A030* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:C8A1B6* + ID_OUI_FROM_DATABASE=Shenzhen Longway Technologies Co., Ltd + +OUI:C8A1BA* + ID_OUI_FROM_DATABASE=Neul Ltd + +OUI:C8A620* + ID_OUI_FROM_DATABASE=Nebula, Inc + +OUI:C8A70A* + ID_OUI_FROM_DATABASE=Verizon Business + +OUI:C8A729* + ID_OUI_FROM_DATABASE=SYStronics Co., Ltd. + +OUI:C8AA21* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:C8AE9C* + ID_OUI_FROM_DATABASE=Shanghai TYD Elecronic Technology Co. Ltd + +OUI:C8AF40* + ID_OUI_FROM_DATABASE=marco Systemanalyse und Entwicklung GmbH + +OUI:C8BBD3* + ID_OUI_FROM_DATABASE=Embrane + +OUI:C8BCC8* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:C8BE19* + ID_OUI_FROM_DATABASE=D-Link International + +OUI:C8C126* + ID_OUI_FROM_DATABASE=ZPM Industria e Comercio Ltda + +OUI:C8C13C* + ID_OUI_FROM_DATABASE=RuggedTek Hangzhou Co., Ltd + +OUI:C8C791* + ID_OUI_FROM_DATABASE=Zero1.tv GmbH + +OUI:C8CBB8* + ID_OUI_FROM_DATABASE=Hewlett Packard + +OUI:C8CD72* + ID_OUI_FROM_DATABASE=SAGEMCOM + +OUI:C8D15E* + ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd + +OUI:C8D1D1* + ID_OUI_FROM_DATABASE=AGAiT Technology Corporation + +OUI:C8D2C1* + ID_OUI_FROM_DATABASE=Jetlun (Shenzhen) Corporation + +OUI:C8D3A3* + ID_OUI_FROM_DATABASE=D-Link International + +OUI:C8D5FE* + ID_OUI_FROM_DATABASE=Shenzhen Zowee Technology Co., Ltd + +OUI:C8D719* + ID_OUI_FROM_DATABASE=Cisco Consumer Products, LLC + +OUI:C8DE51* + ID_OUI_FROM_DATABASE=Integra Networks, Inc. + +OUI:C8DF7C* + ID_OUI_FROM_DATABASE=Nokia Corporation + +OUI:C8E1A7* + ID_OUI_FROM_DATABASE=Vertu Corporation Limited + +OUI:C8EE08* + ID_OUI_FROM_DATABASE=TANGTOP TECHNOLOGY CO.,LTD + +OUI:C8EF2E* + ID_OUI_FROM_DATABASE=Beijing Gefei Tech. Co., Ltd + +OUI:C8F406* + ID_OUI_FROM_DATABASE=Avaya, Inc + +OUI:C8F704* + ID_OUI_FROM_DATABASE=Building Block Video + +OUI:C8F733* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:C8F981* + ID_OUI_FROM_DATABASE=Seneca s.r.l. + +OUI:C8F9F9* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:C8FB26* + ID_OUI_FROM_DATABASE=Cisco SPVTG + +OUI:C8FE30* + ID_OUI_FROM_DATABASE=Bejing DAYO Mobile Communication Technology Ltd. + +OUI:CC0080* + ID_OUI_FROM_DATABASE=TRUST SYSTEM Co., + +OUI:CC047C* + ID_OUI_FROM_DATABASE=G-WAY Microwave + +OUI:CC051B* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:CC08E0* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:CC09C8* + ID_OUI_FROM_DATABASE=IMAQLIQ LTD + +OUI:CC0CDA* + ID_OUI_FROM_DATABASE=Miljovakt AS + +OUI:CC14A6* + ID_OUI_FROM_DATABASE=Yichun MyEnergy Domain, Inc + +OUI:CC187B* + ID_OUI_FROM_DATABASE=Manzanita Systems, Inc. + +OUI:CC1EFF* + ID_OUI_FROM_DATABASE=Metrological Group BV + +OUI:CC2218* + ID_OUI_FROM_DATABASE=InnoDigital Co., Ltd. + +OUI:CC262D* + ID_OUI_FROM_DATABASE=Verifi, LLC + +OUI:CC2D8C* + ID_OUI_FROM_DATABASE=LG ELECTRONICS INC + +OUI:CC34D7* + ID_OUI_FROM_DATABASE=GEWISS S.P.A. + +OUI:CC3A61* + ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO MECHANICS CO., LTD. + +OUI:CC3E5F* + ID_OUI_FROM_DATABASE=Hewlett Packard + +OUI:CC43E3* + ID_OUI_FROM_DATABASE=Trump s.a. + +OUI:CC4BFB* + ID_OUI_FROM_DATABASE=Hellberg Safety AB + +OUI:CC4E24* + ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc. + +OUI:CC501C* + ID_OUI_FROM_DATABASE=KVH Industries, Inc. + +OUI:CC5076* + ID_OUI_FROM_DATABASE=Ocom Communications, Inc. + +OUI:CC52AF* + ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co., Ltd. + +OUI:CC53B5* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +OUI:CC5459* + ID_OUI_FROM_DATABASE=OnTime Networks AS + +OUI:CC55AD* + ID_OUI_FROM_DATABASE=RIM + +OUI:CC593E* + ID_OUI_FROM_DATABASE=TOUMAZ LTD + +OUI:CC5C75* + ID_OUI_FROM_DATABASE=Weightech Com. Imp. Exp. Equip. Pesagem Ltda + +OUI:CC5D4E* + ID_OUI_FROM_DATABASE=ZyXEL Communications Corporation + +OUI:CC60BB* + ID_OUI_FROM_DATABASE=Empower RF Systems + +OUI:CC69B0* + ID_OUI_FROM_DATABASE=Global Traffic Technologies, LLC + +OUI:CC6B98* + ID_OUI_FROM_DATABASE=Minetec Wireless Technologies + +OUI:CC6BF1* + ID_OUI_FROM_DATABASE=Sound Masking Inc. + +OUI:CC6DA0* + ID_OUI_FROM_DATABASE=Roku, Inc. + +OUI:CC6DEF* + ID_OUI_FROM_DATABASE=TJK Tietolaite Oy + +OUI:CC7669* + ID_OUI_FROM_DATABASE=SEETECH + +OUI:CC785F* + ID_OUI_FROM_DATABASE=Apple + +OUI:CC7A30* + ID_OUI_FROM_DATABASE=CMAX Wireless Co., Ltd. + +OUI:CC7D37* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:CC7EE7* + ID_OUI_FROM_DATABASE=Panasonic AVC Networks Company + +OUI:CC8CE3* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:CC9093* + ID_OUI_FROM_DATABASE=Hansong Tehnologies + +OUI:CC912B* + ID_OUI_FROM_DATABASE=TE Connectivity Touch Solutions + +OUI:CC944A* + ID_OUI_FROM_DATABASE=Pfeiffer Vacuum GmbH + +OUI:CC96A0* + ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd + +OUI:CC9E00* + ID_OUI_FROM_DATABASE=Nintendo Co., Ltd. + +OUI:CCA374* + ID_OUI_FROM_DATABASE=Guangdong Guanglian Electronic Technology Co.Ltd + +OUI:CCA462* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc + +OUI:CCAF78* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + +OUI:CCB255* + ID_OUI_FROM_DATABASE=D-Link International + +OUI:CCB3F8* + ID_OUI_FROM_DATABASE=FUJITSU ISOTEC LIMITED + +OUI:CCB55A* + ID_OUI_FROM_DATABASE=Fraunhofer ITWM + +OUI:CCB888* + ID_OUI_FROM_DATABASE=AnB Securite s.a. + +OUI:CCB8F1* + ID_OUI_FROM_DATABASE=EAGLE KINGDOM TECHNOLOGIES LIMITED + +OUI:CCBE71* + ID_OUI_FROM_DATABASE=OptiLogix BV + +OUI:CCC104* + ID_OUI_FROM_DATABASE=Applied Technical Systems + +OUI:CCC50A* + ID_OUI_FROM_DATABASE=SHENZHEN DAJIAHAO TECHNOLOGY CO.,LTD + +OUI:CCC62B* + ID_OUI_FROM_DATABASE=Tri-Systems Corporation + +OUI:CCC8D7* + ID_OUI_FROM_DATABASE=CIAS Elettronica srl + +OUI:CCCC4E* + ID_OUI_FROM_DATABASE=Sun Fountainhead USA. Corp + +OUI:CCCC81* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +OUI:CCCD64* + ID_OUI_FROM_DATABASE=SM-Electronic GmbH + +OUI:CCCE40* + ID_OUI_FROM_DATABASE=Janteq Corp + +OUI:CCD539* + ID_OUI_FROM_DATABASE=Cisco + +OUI:CCD811* + ID_OUI_FROM_DATABASE=Aiconn Technology Corporation + +OUI:CCD9E9* + ID_OUI_FROM_DATABASE=SCR Engineers Ltd. + +OUI:CCE798* + ID_OUI_FROM_DATABASE=My Social Stuff + +OUI:CCE7DF* + ID_OUI_FROM_DATABASE=American Magnetics, Inc. + +OUI:CCEA1C* + ID_OUI_FROM_DATABASE=DCONWORKS Co., Ltd + +OUI:CCEED9* + ID_OUI_FROM_DATABASE=Deto Mechatronic GmbH + +OUI:CCEF48* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:CCF3A5* + ID_OUI_FROM_DATABASE=Chi Mei Communication Systems, Inc + +OUI:CCF67A* + ID_OUI_FROM_DATABASE=Ayecka Communication Systems LTD + +OUI:CCF841* + ID_OUI_FROM_DATABASE=Lumewave + +OUI:CCF8F0* + ID_OUI_FROM_DATABASE=Xi'an HISU Multimedia Technology Co.,Ltd. + +OUI:CCF954* + ID_OUI_FROM_DATABASE=Avaya, Inc + +OUI:CCF9E8* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:CCFC6D* + ID_OUI_FROM_DATABASE=RIZ TRANSMITTERS + +OUI:CCFCB1* + ID_OUI_FROM_DATABASE=Wireless Technology, Inc. + +OUI:CCFE3C* + ID_OUI_FROM_DATABASE=Samsung Electronics + +OUI:D00790* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:D0131E* + ID_OUI_FROM_DATABASE=Sunrex Technology Corp + +OUI:D0154A* + ID_OUI_FROM_DATABASE=zte corporation + +OUI:D0176A* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:D01AA7* + ID_OUI_FROM_DATABASE=UniPrint + +OUI:D01CBB* + ID_OUI_FROM_DATABASE=Beijing Ctimes Digital Technology Co., Ltd. + +OUI:D023DB* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:D02788* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind.Co.Ltd + +OUI:D03110* + ID_OUI_FROM_DATABASE=Ingenic Semiconductor Co.,Ltd + +OUI:D03761* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:D046DC* + ID_OUI_FROM_DATABASE=Southwest Research Institute + +OUI:D04CC1* + ID_OUI_FROM_DATABASE=SINTRONES Technology Corp. + +OUI:D05162* + ID_OUI_FROM_DATABASE=Sony Mobile Communications AB + +OUI:D052A8* + ID_OUI_FROM_DATABASE=Physical Graph Corporation + +OUI:D0542D* + ID_OUI_FROM_DATABASE=Cambridge Industries(Group) Co.,Ltd. + +OUI:D0574C* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:D05785* + ID_OUI_FROM_DATABASE=Pantech Co., Ltd. + +OUI:D05875* + ID_OUI_FROM_DATABASE=Active Control Technology Inc. + +OUI:D059C3* + ID_OUI_FROM_DATABASE=CeraMicro Technology Corporation + +OUI:D05A0F* + ID_OUI_FROM_DATABASE=I-BT DIGITAL CO.,LTD + +OUI:D05FCE* + ID_OUI_FROM_DATABASE=Hitachi Data Systems + +OUI:D063B4* + ID_OUI_FROM_DATABASE=SolidRun Ltd. + +OUI:D0667B* + ID_OUI_FROM_DATABASE=Samsung Electronics Co., LTD + +OUI:D067E5* + ID_OUI_FROM_DATABASE=Dell Inc + +OUI:D0699E* + ID_OUI_FROM_DATABASE=LUMINEX Lighting Control Equipment + +OUI:D0738E* + ID_OUI_FROM_DATABASE=DONG OH PRECISION CO., LTD. + +OUI:D075BE* + ID_OUI_FROM_DATABASE=Reno A&E + +OUI:D07DE5* + ID_OUI_FROM_DATABASE=Forward Pay Systems, Inc. + +OUI:D07E28* + ID_OUI_FROM_DATABASE=Hewlett Packard + +OUI:D08999* + ID_OUI_FROM_DATABASE=APCON, Inc. + +OUI:D08B7E* + ID_OUI_FROM_DATABASE=Passif Semiconductor + +OUI:D08CB5* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:D08CFF* + ID_OUI_FROM_DATABASE=UPWIS AB + +OUI:D093F8* + ID_OUI_FROM_DATABASE=Stonestreet One LLC + +OUI:D09B05* + ID_OUI_FROM_DATABASE=Emtronix + +OUI:D0A311* + ID_OUI_FROM_DATABASE=Neuberger Gebäudeautomation GmbH + +OUI:D0AEEC* + ID_OUI_FROM_DATABASE=Alpha Networks Inc. + +OUI:D0AFB6* + ID_OUI_FROM_DATABASE=Linktop Technology Co., LTD + +OUI:D0B33F* + ID_OUI_FROM_DATABASE=SHENZHEN TINNO MOBILE TECHNOLOGY CO.,LTD. + +OUI:D0B498* + ID_OUI_FROM_DATABASE=Robert Bosch LLC Automotive Electronics + +OUI:D0B53D* + ID_OUI_FROM_DATABASE=SEPRO ROBOTIQUE + +OUI:D0BB80* + ID_OUI_FROM_DATABASE=SHL Telemedicine International Ltd. + +OUI:D0C1B1* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:D0C282* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:D0CDE1* + ID_OUI_FROM_DATABASE=Scientech Electronics + +OUI:D0CF5E* + ID_OUI_FROM_DATABASE=Energy Micro AS + +OUI:D0D0FD* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:D0D212* + ID_OUI_FROM_DATABASE=K2NET Co.,Ltd. + +OUI:D0D286* + ID_OUI_FROM_DATABASE=Beckman Coulter Biomedical K.K. + +OUI:D0D3FC* + ID_OUI_FROM_DATABASE=Mios, Ltd. + +OUI:D0D6CC* + ID_OUI_FROM_DATABASE=Wintop + +OUI:D0DB32* + ID_OUI_FROM_DATABASE=Nokia Corporation + +OUI:D0DF9A* + ID_OUI_FROM_DATABASE=Liteon Technology Corporation + +OUI:D0DFB2* + ID_OUI_FROM_DATABASE=Genie Networks Limited + +OUI:D0DFC7* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:D0E347* + ID_OUI_FROM_DATABASE=Yoga + +OUI:D0E40B* + ID_OUI_FROM_DATABASE=Wearable Inc. + +OUI:D0E54D* + ID_OUI_FROM_DATABASE=Pace plc + +OUI:D0E782* + ID_OUI_FROM_DATABASE=Azurewave Technologies, Inc. + +OUI:D0EB9E* + ID_OUI_FROM_DATABASE=Seowoo Inc. + +OUI:D0F0DB* + ID_OUI_FROM_DATABASE=Ericsson + +OUI:D0F73B* + ID_OUI_FROM_DATABASE=Helmut Mauell GmbH + +OUI:D4000D* + ID_OUI_FROM_DATABASE=Phoenix Broadband Technologies, LLC. + +OUI:D40057* + ID_OUI_FROM_DATABASE=MC Technologies GmbH + +OUI:D4024A* + ID_OUI_FROM_DATABASE=Delphian Systems LLC + +OUI:D40FB2* + ID_OUI_FROM_DATABASE=Applied Micro Electronics AME bv + +OUI:D410CF* + ID_OUI_FROM_DATABASE=Huanshun Network Science and Technology Co., Ltd. + +OUI:D411D6* + ID_OUI_FROM_DATABASE=ShotSpotter, Inc. + +OUI:D41296* + ID_OUI_FROM_DATABASE=Anobit Technologies Ltd. + +OUI:D412BB* + ID_OUI_FROM_DATABASE=Quadrant Components Inc. Ltd + +OUI:D4136F* + ID_OUI_FROM_DATABASE=Asia Pacific Brands + +OUI:D41C1C* + ID_OUI_FROM_DATABASE=RCF S.P.A. + +OUI:D41E35* + ID_OUI_FROM_DATABASE=TOHO Electronics INC. + +OUI:D41F0C* + ID_OUI_FROM_DATABASE=TVI Vision Oy + +OUI:D4206D* + ID_OUI_FROM_DATABASE=HTC Corporation + +OUI:D4223F* + ID_OUI_FROM_DATABASE=Lenovo Mobile Communication Technology Ltd. + +OUI:D42751* + ID_OUI_FROM_DATABASE=Infopia Co., Ltd + +OUI:D428B2* + ID_OUI_FROM_DATABASE=ioBridge, Inc. + +OUI:D429EA* + ID_OUI_FROM_DATABASE=Zimory GmbH + +OUI:D42C3D* + ID_OUI_FROM_DATABASE=Sky Light Digital Limited + +OUI:D43AE9* + ID_OUI_FROM_DATABASE=DONGGUAN ipt INDUSTRIAL CO., LTD + +OUI:D43D67* + ID_OUI_FROM_DATABASE=Carma Industries Inc. + +OUI:D43D7E* + ID_OUI_FROM_DATABASE=Micro-Star Int'l Co, Ltd + +OUI:D443A8* + ID_OUI_FROM_DATABASE=Changzhou Haojie Electric Co., Ltd. + +OUI:D44B5E* + ID_OUI_FROM_DATABASE=TAIYO YUDEN CO., LTD. + +OUI:D44C24* + ID_OUI_FROM_DATABASE=Vuppalamritha Magnetic Components LTD + +OUI:D44CA7* + ID_OUI_FROM_DATABASE=Informtekhnika & Communication, LLC + +OUI:D44F80* + ID_OUI_FROM_DATABASE=Kemper Digital GmbH + +OUI:D4507A* + ID_OUI_FROM_DATABASE=CEIVA Logic, Inc + +OUI:D45251* + ID_OUI_FROM_DATABASE=IBT Ingenieurbureau Broennimann Thun + +OUI:D45297* + ID_OUI_FROM_DATABASE=nSTREAMS Technologies, Inc. + +OUI:D453AF* + ID_OUI_FROM_DATABASE=VIGO System S.A. + +OUI:D45AB2* + ID_OUI_FROM_DATABASE=Galleon Systems + +OUI:D45C70* + ID_OUI_FROM_DATABASE=Wireless Gigabit Alliance + +OUI:D45D42* + ID_OUI_FROM_DATABASE=Nokia Corporation + +OUI:D466A8* + ID_OUI_FROM_DATABASE=Riedo Networks GmbH + +OUI:D46CBF* + ID_OUI_FROM_DATABASE=Goodrich ISR + +OUI:D46CDA* + ID_OUI_FROM_DATABASE=CSM GmbH + +OUI:D46F42* + ID_OUI_FROM_DATABASE=WAXESS USA Inc + +OUI:D479C3* + ID_OUI_FROM_DATABASE=Cameronet GmbH & Co. KG + +OUI:D47B75* + ID_OUI_FROM_DATABASE=HARTING Electronics GmbH & Co. KG + +OUI:D4823E* + ID_OUI_FROM_DATABASE=Argosy Technologies, Ltd. + +OUI:D48564* + ID_OUI_FROM_DATABASE=Hewlett-Packard Company + +OUI:D487D8* + ID_OUI_FROM_DATABASE=Samsung Electronics + +OUI:D48890* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:D48CB5* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:D48FAA* + ID_OUI_FROM_DATABASE=Sogecam Industrial, S.A. + +OUI:D491AF* + ID_OUI_FROM_DATABASE=Electroacustica General Iberica, S.A. + +OUI:D493A0* + ID_OUI_FROM_DATABASE=Fidelix Oy + +OUI:D4945A* + ID_OUI_FROM_DATABASE=COSMO CO., LTD + +OUI:D494A1* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:D496DF* + ID_OUI_FROM_DATABASE=SUNGJIN C&T CO.,LTD + +OUI:D49A20* + ID_OUI_FROM_DATABASE=Apple, Inc + +OUI:D49C28* + ID_OUI_FROM_DATABASE=JayBird Gear LLC + +OUI:D49C8E* + ID_OUI_FROM_DATABASE=University of FUKUI + +OUI:D49E6D* + ID_OUI_FROM_DATABASE=Wuhan Zhongyuan Huadian Science & Technology Co., + +OUI:D4A02A* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:D4A425* + ID_OUI_FROM_DATABASE=SMAX Technology Co., Ltd. + +OUI:D4A928* + ID_OUI_FROM_DATABASE=GreenWave Reality Inc + +OUI:D4AAFF* + ID_OUI_FROM_DATABASE=MICRO WORLD + +OUI:D4AE52* + ID_OUI_FROM_DATABASE=Dell Inc + +OUI:D4BED9* + ID_OUI_FROM_DATABASE=Dell Inc + +OUI:D4BF2D* + ID_OUI_FROM_DATABASE=SE Controls Asia Pacific Ltd + +OUI:D4C1FC* + ID_OUI_FROM_DATABASE=Nokia Corporation + +OUI:D4C766* + ID_OUI_FROM_DATABASE=Acentic GmbH + +OUI:D4CA6D* + ID_OUI_FROM_DATABASE=Routerboard.com + +OUI:D4CA6E* + ID_OUI_FROM_DATABASE=u-blox AG + +OUI:D4CBAF* + ID_OUI_FROM_DATABASE=Nokia Corporation + +OUI:D4CEB8* + ID_OUI_FROM_DATABASE=Enatel LTD + +OUI:D4D184* + ID_OUI_FROM_DATABASE=ADB Broadband Italia + +OUI:D4D249* + ID_OUI_FROM_DATABASE=Power Ethernet + +OUI:D4D748* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:D4D898* + ID_OUI_FROM_DATABASE=Korea CNO Tech Co., Ltd + +OUI:D4DF57* + ID_OUI_FROM_DATABASE=Alpinion Medical Systems + +OUI:D4E32C* + ID_OUI_FROM_DATABASE=S. Siedle & Sohne + +OUI:D4E33F* + ID_OUI_FROM_DATABASE=Alcatel-Lucent + +OUI:D4E8B2* + ID_OUI_FROM_DATABASE=Samsung Electronics + +OUI:D4EA0E* + ID_OUI_FROM_DATABASE=Avaya, Inc + +OUI:D4EC0C* + ID_OUI_FROM_DATABASE=Harley-Davidson Motor Company + +OUI:D4EE07* + ID_OUI_FROM_DATABASE=HIWIFI Co., Ltd. + +OUI:D4F027* + ID_OUI_FROM_DATABASE=Navetas Energy Management + +OUI:D4F0B4* + ID_OUI_FROM_DATABASE=Napco Security Technologies + +OUI:D4F143* + ID_OUI_FROM_DATABASE=IPROAD.,Inc + +OUI:D4F63F* + ID_OUI_FROM_DATABASE=IEA S.R.L. + +OUI:D8004D* + ID_OUI_FROM_DATABASE=Apple + +OUI:D8052E* + ID_OUI_FROM_DATABASE=Skyviia Corporation + +OUI:D806D1* + ID_OUI_FROM_DATABASE=Honeywell Fire System (Shanghai) Co,. Ltd. + +OUI:D808F5* + ID_OUI_FROM_DATABASE=Arcadia Networks Co. Ltd. + +OUI:D809C3* + ID_OUI_FROM_DATABASE=Cercacor Labs + +OUI:D80DE3* + ID_OUI_FROM_DATABASE=FXI TECHNOLOGIES AS + +OUI:D8160A* + ID_OUI_FROM_DATABASE=Nippon Electro-Sensory Devices + +OUI:D8182B* + ID_OUI_FROM_DATABASE=Conti Temic Microelectronic GmbH + +OUI:D819CE* + ID_OUI_FROM_DATABASE=Telesquare + +OUI:D81BFE* + ID_OUI_FROM_DATABASE=TWINLINX CORPORATION + +OUI:D81C14* + ID_OUI_FROM_DATABASE=Compacta International, Ltd. + +OUI:D824BD* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:D826B9* + ID_OUI_FROM_DATABASE=Guangdong Coagent Electronics S &T Co., Ltd. + +OUI:D828C9* + ID_OUI_FROM_DATABASE=General Electric Consumer and Industrial + +OUI:D82986* + ID_OUI_FROM_DATABASE=Best Wish Technology LTD + +OUI:D82A7E* + ID_OUI_FROM_DATABASE=Nokia Corporation + +OUI:D82DE1* + ID_OUI_FROM_DATABASE=Tricascade Inc. + +OUI:D83062* + ID_OUI_FROM_DATABASE=Apple, Inc + +OUI:D831CF* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:D8337F* + ID_OUI_FROM_DATABASE=Office FA.com Co.,Ltd. + +OUI:D842AC* + ID_OUI_FROM_DATABASE=FreeComm Data Communication Co.,Ltd. + +OUI:D84606* + ID_OUI_FROM_DATABASE=Silicon Valley Global Marketing + +OUI:D84B2A* + ID_OUI_FROM_DATABASE=Cognitas Technologies, Inc. + +OUI:D8543A* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:D857EF* + ID_OUI_FROM_DATABASE=Samsung Electronics + +OUI:D85D4C* + ID_OUI_FROM_DATABASE=TP-LINK Technologies Co.,Ltd. + +OUI:D85D84* + ID_OUI_FROM_DATABASE=CAx soft GmbH + +OUI:D867D9* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:D86BF7* + ID_OUI_FROM_DATABASE=Nintendo Co., Ltd. + +OUI:D86CE9* + ID_OUI_FROM_DATABASE=SAGEMCOM SAS + +OUI:D87157* + ID_OUI_FROM_DATABASE=Lenovo Mobile Communication Technology Ltd. + +OUI:D87533* + ID_OUI_FROM_DATABASE=Nokia Corporation + +OUI:D8760A* + ID_OUI_FROM_DATABASE=Escort, Inc. + +OUI:D878E5* + ID_OUI_FROM_DATABASE=KUHN SA + +OUI:D87988* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co., Ltd. + +OUI:D88A3B* + ID_OUI_FROM_DATABASE=UNIT-EM + +OUI:D8952F* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:D89685* + ID_OUI_FROM_DATABASE=GoPro + +OUI:D8973B* + ID_OUI_FROM_DATABASE=Emerson Network Power Embedded Power + +OUI:D89760* + ID_OUI_FROM_DATABASE=C2 Development, Inc. + +OUI:D89D67* + ID_OUI_FROM_DATABASE=Hewlett Packard + +OUI:D89DB9* + ID_OUI_FROM_DATABASE=eMegatech International Corp. + +OUI:D89E3F* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:D8A25E* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:D8AE90* + ID_OUI_FROM_DATABASE=Itibia Technologies + +OUI:D8AF3B* + ID_OUI_FROM_DATABASE=Hangzhou Bigbright Integrated communications system Co.,Ltd + +OUI:D8AFF1* + ID_OUI_FROM_DATABASE=Panasonic Appliances Company + +OUI:D8B12A* + ID_OUI_FROM_DATABASE=Panasonic Mobile Communications Co., Ltd. + +OUI:D8B377* + ID_OUI_FROM_DATABASE=HTC Corporation + +OUI:D8B6C1* + ID_OUI_FROM_DATABASE=NetworkAccountant, Inc. + +OUI:D8B8F6* + ID_OUI_FROM_DATABASE=Nantworks + +OUI:D8B90E* + ID_OUI_FROM_DATABASE=Triple Domain Vision Co.,Ltd. + +OUI:D8BF4C* + ID_OUI_FROM_DATABASE=Victory Concept Electronics Limited + +OUI:D8C068* + ID_OUI_FROM_DATABASE=Netgenetech.co.,ltd. + +OUI:D8C3FB* + ID_OUI_FROM_DATABASE=DETRACOM + +OUI:D8C691* + ID_OUI_FROM_DATABASE=Hichan Technology Corp. + +OUI:D8C7C8* + ID_OUI_FROM_DATABASE=Aruba Networks + +OUI:D8C99D* + ID_OUI_FROM_DATABASE=EA DISPLAY LIMITED + +OUI:D8D1CB* + ID_OUI_FROM_DATABASE=Apple + +OUI:D8D27C* + ID_OUI_FROM_DATABASE=JEMA ENERGY, SA + +OUI:D8D385* + ID_OUI_FROM_DATABASE=Hewlett-Packard Company + +OUI:D8D5B9* + ID_OUI_FROM_DATABASE=Rainforest Automation, Inc. + +OUI:D8D67E* + ID_OUI_FROM_DATABASE=GSK CNC EQUIPMENT CO.,LTD + +OUI:D8DF0D* + ID_OUI_FROM_DATABASE=beroNet GmbH + +OUI:D8E3AE* + ID_OUI_FROM_DATABASE=CIRTEC MEDICAL SYSTEMS + +OUI:D8E72B* + ID_OUI_FROM_DATABASE=OnPATH Technologies + +OUI:D8E743* + ID_OUI_FROM_DATABASE=Wush, Inc + +OUI:D8E952* + ID_OUI_FROM_DATABASE=KEOPSYS + +OUI:D8EB97* + ID_OUI_FROM_DATABASE=TRENDnet, Inc. + +OUI:D8F0F2* + ID_OUI_FROM_DATABASE=Zeebo Inc + +OUI:D8FE8F* + ID_OUI_FROM_DATABASE=IDFone Co., Ltd. + +OUI:DC0265* + ID_OUI_FROM_DATABASE=Meditech Kft + +OUI:DC028E* + ID_OUI_FROM_DATABASE=zte corporation + +OUI:DC05ED* + ID_OUI_FROM_DATABASE=Nabtesco Corporation + +OUI:DC07C1* + ID_OUI_FROM_DATABASE=HangZhou QiYang Technology Co.,Ltd. + +OUI:DC0B1A* + ID_OUI_FROM_DATABASE=ADB Broadband SpA + +OUI:DC0EA1* + ID_OUI_FROM_DATABASE=COMPAL INFORMATION (KUNSHAN) CO., LTD + +OUI:DC16A2* + ID_OUI_FROM_DATABASE=Medtronic Diabetes + +OUI:DC175A* + ID_OUI_FROM_DATABASE=Hitachi High-Technologies Corporation + +OUI:DC1D9F* + ID_OUI_FROM_DATABASE=U & B tech + +OUI:DC1EA3* + ID_OUI_FROM_DATABASE=Accensus LLC + +OUI:DC2008* + ID_OUI_FROM_DATABASE=ASD Electronics Ltd + +OUI:DC2A14* + ID_OUI_FROM_DATABASE=Shanghai Longjing Technology Co. + +OUI:DC2B61* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:DC2B66* + ID_OUI_FROM_DATABASE=Infoblock + +OUI:DC2C26* + ID_OUI_FROM_DATABASE=Iton Technology Limited + +OUI:DC2E6A* + ID_OUI_FROM_DATABASE=HCT. Co., Ltd. + +OUI:DC309C* + ID_OUI_FROM_DATABASE=SAY Systems Limited + +OUI:DC3350* + ID_OUI_FROM_DATABASE=TechSAT GmbH + +OUI:DC37D2* + ID_OUI_FROM_DATABASE=Hunan HKT Electronic Technology Co., Ltd + +OUI:DC3A5E* + ID_OUI_FROM_DATABASE=Roku, Inc + +OUI:DC3C2E* + ID_OUI_FROM_DATABASE=Manufacturing System Insights, Inc. + +OUI:DC3C84* + ID_OUI_FROM_DATABASE=Ticom Geomatics, Inc. + +OUI:DC3E51* + ID_OUI_FROM_DATABASE=Solberg & Andersen AS + +OUI:DC4517* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:DC49C9* + ID_OUI_FROM_DATABASE=CASCO SIGNAL LTD + +OUI:DC4EDE* + ID_OUI_FROM_DATABASE=SHINYEI TECHNOLOGY CO., LTD. + +OUI:DC6F08* + ID_OUI_FROM_DATABASE=Bay Storage Technology + +OUI:DC7144* + ID_OUI_FROM_DATABASE=Samsung Electro Mechanics + +OUI:DC7B94* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:DC85DE* + ID_OUI_FROM_DATABASE=Azurewave Technologies., inc. + +OUI:DC9B1E* + ID_OUI_FROM_DATABASE=Intercom, Inc. + +OUI:DC9C52* + ID_OUI_FROM_DATABASE=Sapphire Technology Limited. + +OUI:DC9FA4* + ID_OUI_FROM_DATABASE=Nokia Corporation + +OUI:DC9FDB* + ID_OUI_FROM_DATABASE=Ubiquiti Networks, Inc. + +OUI:DCA6BD* + ID_OUI_FROM_DATABASE=Beijing Lanbo Technology Co., Ltd. + +OUI:DCA7D9* + ID_OUI_FROM_DATABASE=Compressor Controls Corp + +OUI:DCA8CF* + ID_OUI_FROM_DATABASE=New Spin Golf, LLC. + +OUI:DCA971* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:DCA989* + ID_OUI_FROM_DATABASE=MACANDC + +OUI:DCB058* + ID_OUI_FROM_DATABASE=Burkert Werke GmbH + +OUI:DCB4C4* + ID_OUI_FROM_DATABASE=Microsoft XCG + +OUI:DCBF90* + ID_OUI_FROM_DATABASE=HUIZHOU QIAOXING TELECOMMUNICATION INDUSTRY CO.,LTD. + +OUI:DCC0DB* + ID_OUI_FROM_DATABASE=Shenzhen Kaiboer Technology Co., Ltd. + +OUI:DCC101* + ID_OUI_FROM_DATABASE=SOLiD Technologies, Inc. + +OUI:DCCBA8* + ID_OUI_FROM_DATABASE=Explora Technologies Inc + +OUI:DCCE41* + ID_OUI_FROM_DATABASE=FE GLOBAL HONG KONG LIMITED + +OUI:DCCF94* + ID_OUI_FROM_DATABASE=Beijing Rongcheng Hutong Technology Co., Ltd. + +OUI:DCD0F7* + ID_OUI_FROM_DATABASE=Bentek Systems Ltd. + +OUI:DCD2FC* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +OUI:DCD321* + ID_OUI_FROM_DATABASE=HUMAX co.,tld + +OUI:DCD87F* + ID_OUI_FROM_DATABASE=Shenzhen JoinCyber Telecom Equipment Ltd + +OUI:DCDECA* + ID_OUI_FROM_DATABASE=Akyllor + +OUI:DCE2AC* + ID_OUI_FROM_DATABASE=Lumens Digital Optics Inc. + +OUI:DCE71C* + ID_OUI_FROM_DATABASE=AUG Elektronik GmbH + +OUI:DCF05D* + ID_OUI_FROM_DATABASE=Letta Teknoloji + +OUI:DCF858* + ID_OUI_FROM_DATABASE=Lorent Networks, Inc. + +OUI:DCFAD5* + ID_OUI_FROM_DATABASE=STRONG Ges.m.b.H. + +OUI:E005C5* + ID_OUI_FROM_DATABASE=TP-LINK Technologies Co.,Ltd. + +OUI:E006E6* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + +OUI:E00B28* + ID_OUI_FROM_DATABASE=Inovonics + +OUI:E00C7F* + ID_OUI_FROM_DATABASE=Nintendo Co., Ltd. + +OUI:E0143E* + ID_OUI_FROM_DATABASE=Modoosis Inc. + +OUI:E01C41* + ID_OUI_FROM_DATABASE=Aerohive Networks Inc. + +OUI:E01CEE* + ID_OUI_FROM_DATABASE=Bravo Tech, Inc. + +OUI:E01D3B* + ID_OUI_FROM_DATABASE=Cambridge Industries(Group) Co.,Ltd + +OUI:E01E07* + ID_OUI_FROM_DATABASE=Anite Telecoms US. Inc + +OUI:E01F0A* + ID_OUI_FROM_DATABASE=Xslent Energy Technologies. LLC + +OUI:E0247F* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +OUI:E02538* + ID_OUI_FROM_DATABASE=Titan Pet Products + +OUI:E02630* + ID_OUI_FROM_DATABASE=Intrigue Technologies, Inc. + +OUI:E02636* + ID_OUI_FROM_DATABASE=Nortel Networks + +OUI:E0271A* + ID_OUI_FROM_DATABASE=TTC Next-generation Home Network System WG + +OUI:E02A82* + ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co., Ltd. + +OUI:E02F6D* + ID_OUI_FROM_DATABASE=Cisco + +OUI:E03005* + ID_OUI_FROM_DATABASE=Alcatel-Lucent Shanghai Bell Co., Ltd + +OUI:E039D7* + ID_OUI_FROM_DATABASE=Plexxi, Inc. + +OUI:E03C5B* + ID_OUI_FROM_DATABASE=SHENZHEN JIAXINJIE ELECTRON CO.,LTD + +OUI:E03E7D* + ID_OUI_FROM_DATABASE=data-complex GmbH + +OUI:E0469A* + ID_OUI_FROM_DATABASE=NETGEAR + +OUI:E05597* + ID_OUI_FROM_DATABASE=Emergent Vision Technologies Inc. + +OUI:E0589E* + ID_OUI_FROM_DATABASE=Laerdal Medical + +OUI:E05B70* + ID_OUI_FROM_DATABASE=Innovid, Co., Ltd. + +OUI:E05DA6* + ID_OUI_FROM_DATABASE=Detlef Fink Elektronik & Softwareentwicklung + +OUI:E05FB9* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:E061B2* + ID_OUI_FROM_DATABASE=HANGZHOU ZENOINTEL TECHNOLOGY CO., LTD + +OUI:E06290* + ID_OUI_FROM_DATABASE=Jinan Jovision Science & Technology Co., Ltd. + +OUI:E064BB* + ID_OUI_FROM_DATABASE=DigiView S.r.l. + +OUI:E06995* + ID_OUI_FROM_DATABASE=PEGATRON CORPORATION + +OUI:E0757D* + ID_OUI_FROM_DATABASE=Motorola Mobility LLC + +OUI:E08177* + ID_OUI_FROM_DATABASE=GreenBytes, Inc. + +OUI:E087B1* + ID_OUI_FROM_DATABASE=Nata-Info Ltd. + +OUI:E08A7E* + ID_OUI_FROM_DATABASE=Exponent + +OUI:E08FEC* + ID_OUI_FROM_DATABASE=REPOTEC CO., LTD. + +OUI:E09153* + ID_OUI_FROM_DATABASE=XAVi Technologies Corp. + +OUI:E091F5* + ID_OUI_FROM_DATABASE=NETGEAR + +OUI:E09467* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:E09579* + ID_OUI_FROM_DATABASE=ORTHOsoft inc, d/b/a Zimmer CAS + +OUI:E09D31* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:E09DB8* + ID_OUI_FROM_DATABASE=PLANEX COMMUNICATIONS INC. + +OUI:E0A1D7* + ID_OUI_FROM_DATABASE=SFR + +OUI:E0A30F* + ID_OUI_FROM_DATABASE=Pevco + +OUI:E0A670* + ID_OUI_FROM_DATABASE=Nokia Corporation + +OUI:E0AAB0* + ID_OUI_FROM_DATABASE=GENERAL VISION ELECTRONICS CO. LTD. + +OUI:E0ABFE* + ID_OUI_FROM_DATABASE=Orb Networks, Inc. + +OUI:E0AE5E* + ID_OUI_FROM_DATABASE=ALPS Electric Co,. Ltd. + +OUI:E0AEED* + ID_OUI_FROM_DATABASE=LOENK + +OUI:E0B7B1* + ID_OUI_FROM_DATABASE=Pace plc + +OUI:E0B9A5* + ID_OUI_FROM_DATABASE=Azurewave + +OUI:E0B9BA* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:E0BC43* + ID_OUI_FROM_DATABASE=C2 Microsystems, Inc. + +OUI:E0C286* + ID_OUI_FROM_DATABASE=Aisai Communication Technology Co., Ltd. + +OUI:E0C2B7* + ID_OUI_FROM_DATABASE=Masimo Corporation + +OUI:E0C3F3* + ID_OUI_FROM_DATABASE=ZTE Corporation + +OUI:E0C79D* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:E0C922* + ID_OUI_FROM_DATABASE=Jireh Energy Tech., Ltd. + +OUI:E0C97A* + ID_OUI_FROM_DATABASE=Apple Inc + +OUI:E0CA4D* + ID_OUI_FROM_DATABASE=Shenzhen Unistar Communication Co.,LTD + +OUI:E0CA94* + ID_OUI_FROM_DATABASE=Askey Computer + +OUI:E0CB4E* + ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. + +OUI:E0CEC3* + ID_OUI_FROM_DATABASE=ASKEY COMPUTER CORP + +OUI:E0CF2D* + ID_OUI_FROM_DATABASE=Gemintek Corporation + +OUI:E0D10A* + ID_OUI_FROM_DATABASE=Katoudenkikougyousyo co ltd + +OUI:E0D7BA* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:E0D9A2* + ID_OUI_FROM_DATABASE=Hippih aps + +OUI:E0DADC* + ID_OUI_FROM_DATABASE=JVC KENWOOD Corporation + +OUI:E0DB55* + ID_OUI_FROM_DATABASE=Dell Inc + +OUI:E0E751* + ID_OUI_FROM_DATABASE=Nintendo Co., Ltd. + +OUI:E0E8E8* + ID_OUI_FROM_DATABASE=Olive Telecommunication Pvt. Ltd + +OUI:E0ED1A* + ID_OUI_FROM_DATABASE=vastriver Technology Co., Ltd + +OUI:E0EE1B* + ID_OUI_FROM_DATABASE=Panasonic Automotive Systems Company of America + +OUI:E0EF25* + ID_OUI_FROM_DATABASE=Lintes Technology Co., Ltd. + +OUI:E0F211* + ID_OUI_FROM_DATABASE=Digitalwatt + +OUI:E0F379* + ID_OUI_FROM_DATABASE=Vaddio + +OUI:E0F5CA* + ID_OUI_FROM_DATABASE=CHENG UEI PRECISION INDUSTRY CO.,LTD. + +OUI:E0F847* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:E0F9BE* + ID_OUI_FROM_DATABASE=Cloudena Corp. + +OUI:E4115B* + ID_OUI_FROM_DATABASE=Hewlett Packard + +OUI:E41289* + ID_OUI_FROM_DATABASE=topsystem Systemhaus GmbH + +OUI:E41C4B* + ID_OUI_FROM_DATABASE=V2 TECHNOLOGY, INC. + +OUI:E41F13* + ID_OUI_FROM_DATABASE=IBM Corp + +OUI:E425E9* + ID_OUI_FROM_DATABASE=Color-Chip + +OUI:E42771* + ID_OUI_FROM_DATABASE=Smartlabs + +OUI:E42AD3* + ID_OUI_FROM_DATABASE=Magneti Marelli S.p.A. Powertrain + +OUI:E42C56* + ID_OUI_FROM_DATABASE=Lilee Systems, Ltd. + +OUI:E42F26* + ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Tech.Co.,Ltd. + +OUI:E42FF6* + ID_OUI_FROM_DATABASE=Unicore communication Inc. + +OUI:E43593* + ID_OUI_FROM_DATABASE=Hangzhou GoTo technology Co.Ltd + +OUI:E435FB* + ID_OUI_FROM_DATABASE=Sabre Technology (Hull) Ltd + +OUI:E437D7* + ID_OUI_FROM_DATABASE=HENRI DEPAEPE S.A.S. + +OUI:E43FA2* + ID_OUI_FROM_DATABASE=Wuxi DSP Technologies Inc. + +OUI:E441E6* + ID_OUI_FROM_DATABASE=Ottec Technology GmbH + +OUI:E446BD* + ID_OUI_FROM_DATABASE=C&C TECHNIC TAIWAN CO., LTD. + +OUI:E448C7* + ID_OUI_FROM_DATABASE=Cisco SPVTG + +OUI:E44E18* + ID_OUI_FROM_DATABASE=Gardasoft VisionLimited + +OUI:E44F29* + ID_OUI_FROM_DATABASE=MA Lighting Technology GmbH + +OUI:E44F5F* + ID_OUI_FROM_DATABASE=EDS Elektronik Destek San.Tic.Ltd.Sti + +OUI:E455EA* + ID_OUI_FROM_DATABASE=Dedicated Computing + +OUI:E45614* + ID_OUI_FROM_DATABASE=Suttle Apparatus + +OUI:E46449* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:E467BA* + ID_OUI_FROM_DATABASE=Danish Interpretation Systems A/S + +OUI:E46C21* + ID_OUI_FROM_DATABASE=messMa GmbH + +OUI:E47185* + ID_OUI_FROM_DATABASE=Securifi Ltd + +OUI:E4751E* + ID_OUI_FROM_DATABASE=Getinge Sterilization AB + +OUI:E477D4* + ID_OUI_FROM_DATABASE=Minrray Industry Co.,Ltd + +OUI:E47CF9* + ID_OUI_FROM_DATABASE=Samsung Electronics Co., LTD + +OUI:E48399* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:E48AD5* + ID_OUI_FROM_DATABASE=RF WINDOW CO., LTD. + +OUI:E48B7F* + ID_OUI_FROM_DATABASE=Apple + +OUI:E49069* + ID_OUI_FROM_DATABASE=Rockwell Automation + +OUI:E492E7* + ID_OUI_FROM_DATABASE=Gridlink Tech. Co.,Ltd. + +OUI:E496AE* + ID_OUI_FROM_DATABASE=ALTOGRAPHICS Inc. + +OUI:E497F0* + ID_OUI_FROM_DATABASE=Shanghai VLC Technologies Ltd. Co. + +OUI:E4A5EF* + ID_OUI_FROM_DATABASE=TRON LINK ELECTRONICS CO., LTD. + +OUI:E4A7FD* + ID_OUI_FROM_DATABASE=Cellco Partnership + +OUI:E4AB46* + ID_OUI_FROM_DATABASE=UAB Selteka + +OUI:E4AD7D* + ID_OUI_FROM_DATABASE=SCL Elements + +OUI:E4AFA1* + ID_OUI_FROM_DATABASE=HES-SO + +OUI:E4B021* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:E4C146* + ID_OUI_FROM_DATABASE=Objetivos y Servicios de Valor A + +OUI:E4C6E6* + ID_OUI_FROM_DATABASE=Mophie, LLC + +OUI:E4C806* + ID_OUI_FROM_DATABASE=Ceiec Electric Technology Inc. + +OUI:E4CE8F* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:E4D3F1* + ID_OUI_FROM_DATABASE=Cisco + +OUI:E4D53D* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + +OUI:E4D71D* + ID_OUI_FROM_DATABASE=Oraya Therapeutics + +OUI:E4DD79* + ID_OUI_FROM_DATABASE=En-Vision America, Inc. + +OUI:E4E0C5* + ID_OUI_FROM_DATABASE=Samsung Electronics Co., LTD + +OUI:E4E409* + ID_OUI_FROM_DATABASE=LEIFHEIT AG + +OUI:E4EC10* + ID_OUI_FROM_DATABASE=Nokia Corporation + +OUI:E4EEFD* + ID_OUI_FROM_DATABASE=MR&D Manufacturing + +OUI:E4F365* + ID_OUI_FROM_DATABASE=Time-O-Matic, Inc. + +OUI:E4FA1D* + ID_OUI_FROM_DATABASE=PAD Peripheral Advanced Design Inc. + +OUI:E4FFDD* + ID_OUI_FROM_DATABASE=ELECTRON INDIA + +OUI:E8039A* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,LTD + +OUI:E8040B* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:E80462* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:E804F3* + ID_OUI_FROM_DATABASE=Throughtek Co., Ltd. + +OUI:E8056D* + ID_OUI_FROM_DATABASE=Nortel Networks + +OUI:E80688* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:E80B13* + ID_OUI_FROM_DATABASE=Akib Systems Taiwan, INC + +OUI:E80C38* + ID_OUI_FROM_DATABASE=DAEYOUNG INFORMATION SYSTEM CO., LTD + +OUI:E80C75* + ID_OUI_FROM_DATABASE=Syncbak, Inc. + +OUI:E8102E* + ID_OUI_FROM_DATABASE=Really Simple Software, Inc + +OUI:E81132* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,LTD + +OUI:E81324* + ID_OUI_FROM_DATABASE=GuangZhou Bonsoninfo System CO.,LTD + +OUI:E82877* + ID_OUI_FROM_DATABASE=TMY Co., Ltd. + +OUI:E828D5* + ID_OUI_FROM_DATABASE=Cots Technology + +OUI:E82E24* + ID_OUI_FROM_DATABASE=Out of the Fog Research LLC + +OUI:E83935* + ID_OUI_FROM_DATABASE=Hewlett Packard + +OUI:E839DF* + ID_OUI_FROM_DATABASE=Askey Computer + +OUI:E83A97* + ID_OUI_FROM_DATABASE=OCZ Technology Group + +OUI:E83EB6* + ID_OUI_FROM_DATABASE=RIM + +OUI:E83EFB* + ID_OUI_FROM_DATABASE=GEODESIC LTD. + +OUI:E83EFC* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc + +OUI:E84040* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:E840F2* + ID_OUI_FROM_DATABASE=PEGATRON CORPORATION + +OUI:E843B6* + ID_OUI_FROM_DATABASE=QNAP Systems, Inc. + +OUI:E84E06* + ID_OUI_FROM_DATABASE=EDUP INTERNATIONAL (HK) CO., LTD + +OUI:E84ECE* + ID_OUI_FROM_DATABASE=Nintendo Co., Ltd. + +OUI:E85484* + ID_OUI_FROM_DATABASE=NEO INFORMATION SYSTEMS CO., LTD. + +OUI:E856D6* + ID_OUI_FROM_DATABASE=NCTech Ltd + +OUI:E85AA7* + ID_OUI_FROM_DATABASE=LLC Emzior + +OUI:E85B5B* + ID_OUI_FROM_DATABASE=LG ELECTRONICS INC + +OUI:E85BF0* + ID_OUI_FROM_DATABASE=Imaging Diagnostics + +OUI:E85E53* + ID_OUI_FROM_DATABASE=Infratec Datentechnik GmbH + +OUI:E86CDA* + ID_OUI_FROM_DATABASE=Supercomputers and Neurocomputers Research Center + +OUI:E86D52* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:E86D54* + ID_OUI_FROM_DATABASE=Digit Mobile Inc + +OUI:E86D6E* + ID_OUI_FROM_DATABASE=Control & Display Systems Ltd t/a CDSRail + +OUI:E8718D* + ID_OUI_FROM_DATABASE=Elsys Equipamentos Eletronicos Ltda + +OUI:E8757F* + ID_OUI_FROM_DATABASE=FIRS Technologies(Shenzhen) Co., Ltd + +OUI:E878A1* + ID_OUI_FROM_DATABASE=BEOVIEW INTERCOM DOO + +OUI:E87AF3* + ID_OUI_FROM_DATABASE=S5 Tech S.r.l. + +OUI:E8892C* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc + +OUI:E88D28* + ID_OUI_FROM_DATABASE=Apple + +OUI:E88DF5* + ID_OUI_FROM_DATABASE=ZNYX Networks, Inc. + +OUI:E892A4* + ID_OUI_FROM_DATABASE=LG Electronics + +OUI:E8944C* + ID_OUI_FROM_DATABASE=Cogent Healthcare Systems Ltd + +OUI:E8995A* + ID_OUI_FROM_DATABASE=PiiGAB, Processinformation i Goteborg AB + +OUI:E899C4* + ID_OUI_FROM_DATABASE=HTC Corporation + +OUI:E89A8F* + ID_OUI_FROM_DATABASE=Quanta Computer Inc. + +OUI:E89AFF* + ID_OUI_FROM_DATABASE=Fujian Landi Commercial Equipment Co.,Ltd + +OUI:E89D87* + ID_OUI_FROM_DATABASE=Toshiba + +OUI:E8A364* + ID_OUI_FROM_DATABASE=Signal Path International / Peachtree Audio + +OUI:E8A4C1* + ID_OUI_FROM_DATABASE=Deep Sea Electronics PLC + +OUI:E8ABFA* + ID_OUI_FROM_DATABASE=Shenzhen Reecam Tech.Ltd. + +OUI:E8B4AE* + ID_OUI_FROM_DATABASE=Shenzhen C&D Electronics Co.,Ltd + +OUI:E8B748* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:E8BA70* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:E8BE81* + ID_OUI_FROM_DATABASE=SAGEMCOM + +OUI:E8C229* + ID_OUI_FROM_DATABASE=H-Displays (MSC) Bhd + +OUI:E8C320* + ID_OUI_FROM_DATABASE=Austco Communication Systems Pty Ltd + +OUI:E8CBA1* + ID_OUI_FROM_DATABASE=Nokia Corporation + +OUI:E8CC32* + ID_OUI_FROM_DATABASE=Micronet LTD + +OUI:E8D0FA* + ID_OUI_FROM_DATABASE=MKS Instruments Deutschland GmbH + +OUI:E8D483* + ID_OUI_FROM_DATABASE=ULTIMATE Europe Transportation Equipment GmbH + +OUI:E8DA96* + ID_OUI_FROM_DATABASE=Zhuhai Tianrui Electrical Power Tech. Co., Ltd. + +OUI:E8DAAA* + ID_OUI_FROM_DATABASE=VideoHome Technology Corp. + +OUI:E8DFF2* + ID_OUI_FROM_DATABASE=PRF Co., Ltd. + +OUI:E8E08F* + ID_OUI_FROM_DATABASE=GRAVOTECH MARKING SAS + +OUI:E8E0B7* + ID_OUI_FROM_DATABASE=Toshiba + +OUI:E8E1E2* + ID_OUI_FROM_DATABASE=Energotest + +OUI:E8E5D6* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:E8E732* + ID_OUI_FROM_DATABASE=Alcatel-Lucent + +OUI:E8E776* + ID_OUI_FROM_DATABASE=Shenzhen Kootion Technology Co., Ltd + +OUI:E8E875* + ID_OUI_FROM_DATABASE=iS5 Communications Inc. + +OUI:E8F1B0* + ID_OUI_FROM_DATABASE=SAGEMCOM SAS + +OUI:E8F928* + ID_OUI_FROM_DATABASE=RFTECH SRL + +OUI:EC0ED6* + ID_OUI_FROM_DATABASE=ITECH INSTRUMENTS SAS + +OUI:EC1120* + ID_OUI_FROM_DATABASE=FloDesign Wind Turbine Corporation + +OUI:EC14F6* + ID_OUI_FROM_DATABASE=BioControl AS + +OUI:EC172F* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO., LTD. + +OUI:EC1A59* + ID_OUI_FROM_DATABASE=Belkin International Inc. + +OUI:EC233D* + ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd + +OUI:EC2368* + ID_OUI_FROM_DATABASE=IntelliVoice Co.,Ltd. + +OUI:EC3091* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:EC3BF0* + ID_OUI_FROM_DATABASE=NovelSat + +OUI:EC3F05* + ID_OUI_FROM_DATABASE=Institute 706, The Second Academy China Aerospace Science & Industry Corp + +OUI:EC42F0* + ID_OUI_FROM_DATABASE=ADL Embedded Solutions, Inc. + +OUI:EC43E6* + ID_OUI_FROM_DATABASE=AWCER Ltd. + +OUI:EC43F6* + ID_OUI_FROM_DATABASE=ZyXEL Communications Corporation + +OUI:EC4476* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:EC4644* + ID_OUI_FROM_DATABASE=TTK SAS + +OUI:EC4670* + ID_OUI_FROM_DATABASE=Meinberg Funkuhren GmbH & Co. KG + +OUI:EC473C* + ID_OUI_FROM_DATABASE=Redwire, LLC + +OUI:EC4993* + ID_OUI_FROM_DATABASE=Qihan Technology Co., Ltd + +OUI:EC4C4D* + ID_OUI_FROM_DATABASE=ZAO NPK RoTeK + +OUI:EC542E* + ID_OUI_FROM_DATABASE=Shanghai XiMei Electronic Technology Co. Ltd + +OUI:EC55F9* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + +OUI:EC5C69* + ID_OUI_FROM_DATABASE=MITSUBISHI HEAVY INDUSTRIES MECHATRONICS SYSTEMS,LTD. + +OUI:EC6264* + ID_OUI_FROM_DATABASE=Global411 Internet Services, LLC + +OUI:EC63E5* + ID_OUI_FROM_DATABASE=ePBoard Design LLC + +OUI:EC66D1* + ID_OUI_FROM_DATABASE=B&W Group LTD + +OUI:EC6C9F* + ID_OUI_FROM_DATABASE=Chengdu Volans Technology CO.,LTD + +OUI:EC7C74* + ID_OUI_FROM_DATABASE=Justone Technologies Co., Ltd. + +OUI:EC7D9D* + ID_OUI_FROM_DATABASE=MEI + +OUI:EC836C* + ID_OUI_FROM_DATABASE=RM Tech Co., Ltd. + +OUI:EC852F* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:EC888F* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO., LTD. + +OUI:EC89F5* + ID_OUI_FROM_DATABASE=Lenovo Mobile Communication Technology Ltd. + +OUI:EC8EAD* + ID_OUI_FROM_DATABASE=DLX + +OUI:EC9233* + ID_OUI_FROM_DATABASE=Eddyfi NDT Inc + +OUI:EC9327* + ID_OUI_FROM_DATABASE=MEMMERT GmbH + Co. KG + +OUI:EC9681* + ID_OUI_FROM_DATABASE=2276427 Ontario Inc + +OUI:EC986C* + ID_OUI_FROM_DATABASE=Lufft Mess- und Regeltechnik GmbH + +OUI:EC98C1* + ID_OUI_FROM_DATABASE=Beijing Risbo Network Technology Co.,Ltd + +OUI:EC9A74* + ID_OUI_FROM_DATABASE=Hewlett Packard + +OUI:EC9B5B* + ID_OUI_FROM_DATABASE=Nokia Corporation + +OUI:EC9ECD* + ID_OUI_FROM_DATABASE=Emerson Network Power and Embedded Computing + +OUI:ECA29B* + ID_OUI_FROM_DATABASE=Kemppi Oy + +OUI:ECA86B* + ID_OUI_FROM_DATABASE=ELITEGROUP COMPUTER SYSTEMS CO., LTD. + +OUI:ECB106* + ID_OUI_FROM_DATABASE=Acuro Networks, Inc + +OUI:ECB541* + ID_OUI_FROM_DATABASE=SHINANO E and E Co.Ltd. + +OUI:ECBBAE* + ID_OUI_FROM_DATABASE=Digivoice Tecnologia em Eletronica Ltda + +OUI:ECBD09* + ID_OUI_FROM_DATABASE=FUSION Electronics Ltd + +OUI:ECC38A* + ID_OUI_FROM_DATABASE=Accuenergy (CANADA) Inc + +OUI:ECC882* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:ECCD6D* + ID_OUI_FROM_DATABASE=Allied Telesis, Inc. + +OUI:ECD00E* + ID_OUI_FROM_DATABASE=MiraeRecognition Co., Ltd. + +OUI:ECD19A* + ID_OUI_FROM_DATABASE=Zhuhai Liming Industries Co., Ltd + +OUI:ECD925* + ID_OUI_FROM_DATABASE=RAMI + +OUI:ECD950* + ID_OUI_FROM_DATABASE=IRT SA + +OUI:ECDE3D* + ID_OUI_FROM_DATABASE=Lamprey Networks, Inc. + +OUI:ECE09B* + ID_OUI_FROM_DATABASE=Samsung electronics CO., LTD + +OUI:ECE555* + ID_OUI_FROM_DATABASE=Hirschmann Automation + +OUI:ECE744* + ID_OUI_FROM_DATABASE=Omntec mfg. inc + +OUI:ECE90B* + ID_OUI_FROM_DATABASE=SISTEMA SOLUCOES ELETRONICAS LTDA - EASYTECH + +OUI:ECE915* + ID_OUI_FROM_DATABASE=STI Ltd + +OUI:ECE9F8* + ID_OUI_FROM_DATABASE=Guang Zhou TRI-SUN Electronics Technology Co., Ltd + +OUI:ECEA03* + ID_OUI_FROM_DATABASE=DARFON LIGHTING CORP + +OUI:ECF00E* + ID_OUI_FROM_DATABASE=Abocom + +OUI:ECF236* + ID_OUI_FROM_DATABASE=NEOMONTANA ELECTRONICS + +OUI:ECFAAA* + ID_OUI_FROM_DATABASE=The IMS Company + +OUI:ECFC55* + ID_OUI_FROM_DATABASE=A. Eberle GmbH & Co. KG + +OUI:ECFE7E* + ID_OUI_FROM_DATABASE=BlueRadios, Inc. + +OUI:F0007F* + ID_OUI_FROM_DATABASE=Janz - Contadores de Energia, SA + +OUI:F0022B* + ID_OUI_FROM_DATABASE=Chrontel + +OUI:F00248* + ID_OUI_FROM_DATABASE=SmarteBuilding + +OUI:F00786* + ID_OUI_FROM_DATABASE=Shandong Bittel Electronics Co., Ltd + +OUI:F008F1* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:F013C3* + ID_OUI_FROM_DATABASE=SHENZHEN FENDA TECHNOLOGY CO., LTD + +OUI:F01C13* + ID_OUI_FROM_DATABASE=LG Electronics + +OUI:F0219D* + ID_OUI_FROM_DATABASE=Cal-Comp Electronics & Communications Company Ltd. + +OUI:F02329* + ID_OUI_FROM_DATABASE=SHOWA DENKI CO.,LTD. + +OUI:F02408* + ID_OUI_FROM_DATABASE=Talaris (Sweden) AB + +OUI:F02572* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:F0264C* + ID_OUI_FROM_DATABASE=Dr. Sigrist AG + +OUI:F02929* + ID_OUI_FROM_DATABASE=Cisco + +OUI:F02A61* + ID_OUI_FROM_DATABASE=Waldo Networks, Inc. + +OUI:F02FD8* + ID_OUI_FROM_DATABASE=Bi2-Vision + +OUI:F03A55* + ID_OUI_FROM_DATABASE=Omega Elektronik AS + +OUI:F04335* + ID_OUI_FROM_DATABASE=DVN(Shanghai)Ltd. + +OUI:F04A2B* + ID_OUI_FROM_DATABASE=PYRAMID Computer GmbH + +OUI:F04B6A* + ID_OUI_FROM_DATABASE=Scientific Production Association Siberian Arsenal, Ltd. + +OUI:F04BF2* + ID_OUI_FROM_DATABASE=JTECH Communications, Inc. + +OUI:F04DA2* + ID_OUI_FROM_DATABASE=Dell Inc. + +OUI:F05849* + ID_OUI_FROM_DATABASE=CareView Communications + +OUI:F05D89* + ID_OUI_FROM_DATABASE=Dycon Limited + +OUI:F05F5A* + ID_OUI_FROM_DATABASE=Getriebebau NORD GmbH and Co. KG + +OUI:F0620D* + ID_OUI_FROM_DATABASE=Shenzhen Egreat Tech Corp.,Ltd + +OUI:F06281* + ID_OUI_FROM_DATABASE=ProCurve Networking by HP + +OUI:F065DD* + ID_OUI_FROM_DATABASE=Primax Electronics Ltd. + +OUI:F06853* + ID_OUI_FROM_DATABASE=Integrated Corporation + +OUI:F073AE* + ID_OUI_FROM_DATABASE=PEAK-System Technik + +OUI:F077D0* + ID_OUI_FROM_DATABASE=Xcellen + +OUI:F07BCB* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + +OUI:F07D68* + ID_OUI_FROM_DATABASE=D-Link Corporation + +OUI:F081AF* + ID_OUI_FROM_DATABASE=IRZ AUTOMATION TECHNOLOGIES LTD + +OUI:F08BFE* + ID_OUI_FROM_DATABASE=COSTEL.,CO.LTD + +OUI:F0933A* + ID_OUI_FROM_DATABASE=NxtConect + +OUI:F093C5* + ID_OUI_FROM_DATABASE=Garland Technology + +OUI:F09CBB* + ID_OUI_FROM_DATABASE=RaonThink Inc. + +OUI:F09CE9* + ID_OUI_FROM_DATABASE=Aerohive Networks Inc + +OUI:F0A764* + ID_OUI_FROM_DATABASE=GST Co., Ltd. + +OUI:F0ACA4* + ID_OUI_FROM_DATABASE=HBC-radiomatic + +OUI:F0AD4E* + ID_OUI_FROM_DATABASE=Globalscale Technologies, Inc. + +OUI:F0AE51* + ID_OUI_FROM_DATABASE=Xi3 Corp + +OUI:F0B479* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:F0B6EB* + ID_OUI_FROM_DATABASE=Poslab Technology Co., Ltd. + +OUI:F0BCC8* + ID_OUI_FROM_DATABASE=MaxID (Pty) Ltd + +OUI:F0BDF1* + ID_OUI_FROM_DATABASE=Sipod Inc. + +OUI:F0BF97* + ID_OUI_FROM_DATABASE=Sony Corporation + +OUI:F0C24C* + ID_OUI_FROM_DATABASE=Zhejiang FeiYue Digital Technology Co., Ltd + +OUI:F0C27C* + ID_OUI_FROM_DATABASE=Mianyang Netop Telecom Equipment Co.,Ltd. + +OUI:F0C88C* + ID_OUI_FROM_DATABASE=LeddarTech Inc. + +OUI:F0CBA1* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:F0D14F* + ID_OUI_FROM_DATABASE=LINEAR LLC + +OUI:F0D1A9* + ID_OUI_FROM_DATABASE=Apple + +OUI:F0D3E7* + ID_OUI_FROM_DATABASE=Sensometrix SA + +OUI:F0D767* + ID_OUI_FROM_DATABASE=Axema Passagekontroll AB + +OUI:F0DA7C* + ID_OUI_FROM_DATABASE=RLH INDUSTRIES,INC. + +OUI:F0DB30* + ID_OUI_FROM_DATABASE=Yottabyte + +OUI:F0DCE2* + ID_OUI_FROM_DATABASE=Apple Inc + +OUI:F0DE71* + ID_OUI_FROM_DATABASE=Shanghai EDO Technologies Co.,Ltd. + +OUI:F0DEB9* + ID_OUI_FROM_DATABASE=ShangHai Y&Y Electronics Co., Ltd + +OUI:F0DEF1* + ID_OUI_FROM_DATABASE=Wistron InfoComm (Kunshan)Co + +OUI:F0E5C3* + ID_OUI_FROM_DATABASE=Drägerwerk AG & Co. KG aA + +OUI:F0E77E* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:F0EC39* + ID_OUI_FROM_DATABASE=Essec + +OUI:F0ED1E* + ID_OUI_FROM_DATABASE=Bilkon Bilgisayar Kontrollu Cih. Im.Ltd. + +OUI:F0EEBB* + ID_OUI_FROM_DATABASE=VIPAR GmbH + +OUI:F0F002* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + +OUI:F0F644* + ID_OUI_FROM_DATABASE=Whitesky Science & Technology Co.,Ltd. + +OUI:F0F669* + ID_OUI_FROM_DATABASE=Motion Analysis Corporation + +OUI:F0F755* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:F0F7B3* + ID_OUI_FROM_DATABASE=Phorm + +OUI:F0F842* + ID_OUI_FROM_DATABASE=KEEBOX, Inc. + +OUI:F0F9F7* + ID_OUI_FROM_DATABASE=IES GmbH & Co. KG + +OUI:F0FDA0* + ID_OUI_FROM_DATABASE=Acurix Networks LP + +OUI:F40321* + ID_OUI_FROM_DATABASE=BeNeXt B.V. + +OUI:F4044C* + ID_OUI_FROM_DATABASE=ValenceTech Limited + +OUI:F40B93* + ID_OUI_FROM_DATABASE=Research In Motion + +OUI:F40F9B* + ID_OUI_FROM_DATABASE=WAVELINK + +OUI:F41BA1* + ID_OUI_FROM_DATABASE=Apple + +OUI:F41E26* + ID_OUI_FROM_DATABASE=Simon-Kaloi Engineering + +OUI:F41F0B* + ID_OUI_FROM_DATABASE=YAMABISHI Corporation + +OUI:F436E1* + ID_OUI_FROM_DATABASE=Abilis Systems SARL + +OUI:F43814* + ID_OUI_FROM_DATABASE=Shanghai Howell Electronic Co.,Ltd + +OUI:F43D80* + ID_OUI_FROM_DATABASE=FAG Industrial Services GmbH + +OUI:F43E61* + ID_OUI_FROM_DATABASE=Shenzhen Gongjin Electronics Co., Ltd + +OUI:F43E9D* + ID_OUI_FROM_DATABASE=Benu Networks, Inc. + +OUI:F44227* + ID_OUI_FROM_DATABASE=S & S Research Inc. + +OUI:F44450* + ID_OUI_FROM_DATABASE=BND Co., Ltd. + +OUI:F445ED* + ID_OUI_FROM_DATABASE=Portable Innovation Technology Ltd. + +OUI:F4472A* + ID_OUI_FROM_DATABASE=Nanjing Rousing Sci. and Tech. Industrial Co., Ltd + +OUI:F44848* + ID_OUI_FROM_DATABASE=Amscreen Group Ltd + +OUI:F44EFD* + ID_OUI_FROM_DATABASE=Actions Semiconductor Co.,Ltd.(Cayman Islands) + +OUI:F450EB* + ID_OUI_FROM_DATABASE=Telechips Inc + +OUI:F45214* + ID_OUI_FROM_DATABASE=Mellanox Technologies, Inc. + +OUI:F45433* + ID_OUI_FROM_DATABASE=Rockwell Automation + +OUI:F45595* + ID_OUI_FROM_DATABASE=HENGBAO Corporation LTD. + +OUI:F4559C* + ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd + +OUI:F455E0* + ID_OUI_FROM_DATABASE=Niceway CNC Technology Co.,Ltd.Hunan Province + +OUI:F45FD4* + ID_OUI_FROM_DATABASE=Cisco SPVTG + +OUI:F45FF7* + ID_OUI_FROM_DATABASE=DQ Technology Inc. + +OUI:F4600D* + ID_OUI_FROM_DATABASE=Panoptic Technology, Inc + +OUI:F46349* + ID_OUI_FROM_DATABASE=Diffon Corporation + +OUI:F46D04* + ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. + +OUI:F46DE2* + ID_OUI_FROM_DATABASE=zte corporation + +OUI:F473CA* + ID_OUI_FROM_DATABASE=Conversion Sound Inc. + +OUI:F47626* + ID_OUI_FROM_DATABASE=Viltechmeda UAB + +OUI:F47ACC* + ID_OUI_FROM_DATABASE=SolidFire, Inc. + +OUI:F47B5E* + ID_OUI_FROM_DATABASE=Samsung Eletronics Co., Ltd + +OUI:F47F35* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:F48771* + ID_OUI_FROM_DATABASE=Infoblox + +OUI:F48E09* + ID_OUI_FROM_DATABASE=Nokia Corporation + +OUI:F490EA* + ID_OUI_FROM_DATABASE=Deciso B.V. + +OUI:F49461* + ID_OUI_FROM_DATABASE=NexGen Storage + +OUI:F49466* + ID_OUI_FROM_DATABASE=CountMax, ltd + +OUI:F49F54* + ID_OUI_FROM_DATABASE=Samsung Electronics + +OUI:F4A52A* + ID_OUI_FROM_DATABASE=Hawa Technologies Inc + +OUI:F4ACC1* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:F4B164* + ID_OUI_FROM_DATABASE=Lightning Telecommunications Technology Co. Ltd + +OUI:F4B549* + ID_OUI_FROM_DATABASE=Yeastar Technology Co., Ltd. + +OUI:F4B72A* + ID_OUI_FROM_DATABASE=TIME INTERCONNECT LTD + +OUI:F4B7E2* + ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd. + +OUI:F4C6D7* + ID_OUI_FROM_DATABASE=blackned GmbH + +OUI:F4C714* + ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd + +OUI:F4C795* + ID_OUI_FROM_DATABASE=WEY Elektronik AG + +OUI:F4CAE5* + ID_OUI_FROM_DATABASE=FREEBOX SA + +OUI:F4CE46* + ID_OUI_FROM_DATABASE=Hewlett-Packard Company + +OUI:F4D9FB* + ID_OUI_FROM_DATABASE=Samsung Electronics CO., LTD + +OUI:F4DC4D* + ID_OUI_FROM_DATABASE=Beijing CCD Digital Technology Co., Ltd + +OUI:F4DCDA* + ID_OUI_FROM_DATABASE=Zhuhai Jiahe Communication Technology Co., limited + +OUI:F4E142* + ID_OUI_FROM_DATABASE=Delta Elektronika BV + +OUI:F4E6D7* + ID_OUI_FROM_DATABASE=Solar Power Technologies, Inc. + +OUI:F4EA67* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:F4EC38* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO., LTD. + +OUI:F4F15A* + ID_OUI_FROM_DATABASE=Apple + +OUI:F4FC32* + ID_OUI_FROM_DATABASE=Texas Instruments + +OUI:F80113* + ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd + +OUI:F80332* + ID_OUI_FROM_DATABASE=Khomp + +OUI:F8051C* + ID_OUI_FROM_DATABASE=DRS Imaging and Targeting Solutions + +OUI:F80BBE* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:F80BD0* + ID_OUI_FROM_DATABASE=Datang Telecom communication terminal (Tianjin) Co., Ltd. + +OUI:F80CF3* + ID_OUI_FROM_DATABASE=LG Electronics + +OUI:F80F41* + ID_OUI_FROM_DATABASE=Wistron InfoComm(ZhongShan) Corporation + +OUI:F80F84* + ID_OUI_FROM_DATABASE=Natural Security SAS + +OUI:F81037* + ID_OUI_FROM_DATABASE=Atopia Systems, LP + +OUI:F81A67* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO., LTD. + +OUI:F81D93* + ID_OUI_FROM_DATABASE=Longdhua(Beijing) Controls Technology Co.,Ltd + +OUI:F81EDF* + ID_OUI_FROM_DATABASE=Apple, Inc + +OUI:F82285* + ID_OUI_FROM_DATABASE=Cypress Technology CO., LTD. + +OUI:F82EDB* + ID_OUI_FROM_DATABASE=RTW GmbH & Co. KG + +OUI:F82F5B* + ID_OUI_FROM_DATABASE=eGauge Systems LLC + +OUI:F83094* + ID_OUI_FROM_DATABASE=Alcatel-Lucent Telecom Limited + +OUI:F8313E* + ID_OUI_FROM_DATABASE=endeavour GmbH + +OUI:F83376* + ID_OUI_FROM_DATABASE=Good Mind Innovation Co., Ltd. + +OUI:F83553* + ID_OUI_FROM_DATABASE=Magenta Research Ltd. + +OUI:F83DFF* + ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd + +OUI:F8462D* + ID_OUI_FROM_DATABASE=SYNTEC Incorporation + +OUI:F8472D* + ID_OUI_FROM_DATABASE=X2gen Digital Corp. Ltd + +OUI:F84897* + ID_OUI_FROM_DATABASE=Hitachi, Ltd. + +OUI:F85063* + ID_OUI_FROM_DATABASE=Verathon + +OUI:F852DF* + ID_OUI_FROM_DATABASE=VNL Europe AB + +OUI:F85F2A* + ID_OUI_FROM_DATABASE=Nokia Corporation + +OUI:F866F2* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. + +OUI:F86971* + ID_OUI_FROM_DATABASE=Seibu Electric Co., + +OUI:F86ECF* + ID_OUI_FROM_DATABASE=Arcx Inc + +OUI:F871FE* + ID_OUI_FROM_DATABASE=The Goldman Sachs Group, Inc. + +OUI:F8769B* + ID_OUI_FROM_DATABASE=Neopis Co., Ltd. + +OUI:F87B62* + ID_OUI_FROM_DATABASE=FASTWEL INTERNATIONAL CO., LTD. Taiwan Branch + +OUI:F87B7A* + ID_OUI_FROM_DATABASE=Motorola Mobility, Inc. + +OUI:F87B8C* + ID_OUI_FROM_DATABASE=Amped Wireless + +OUI:F8811A* + ID_OUI_FROM_DATABASE=OVERKIZ + +OUI:F88C1C* + ID_OUI_FROM_DATABASE=KAISHUN ELECTRONIC TECHNOLOGY CO., LTD. BEIJING + +OUI:F88DEF* + ID_OUI_FROM_DATABASE=Tenebraex + +OUI:F88E85* + ID_OUI_FROM_DATABASE=COMTREND CORPORATION + +OUI:F88FCA* + ID_OUI_FROM_DATABASE=Google Fiber, Inc + +OUI:F8912A* + ID_OUI_FROM_DATABASE=GLP German Light Products GmbH + +OUI:F893F3* + ID_OUI_FROM_DATABASE=VOLANS + +OUI:F897CF* + ID_OUI_FROM_DATABASE=DAESHIN-INFORMATION TECHNOLOGY CO., LTD. + +OUI:F89955* + ID_OUI_FROM_DATABASE=Fortress Technology Inc + +OUI:F89D0D* + ID_OUI_FROM_DATABASE=Control Technology Inc. + +OUI:F8A03D* + ID_OUI_FROM_DATABASE=Dinstar Technologies Co., Ltd. + +OUI:F8A9DE* + ID_OUI_FROM_DATABASE=PUISSANCE PLUS + +OUI:F8AA8A* + ID_OUI_FROM_DATABASE=Axview Technology (Shenzhen) Co.,Ltd + +OUI:F8AC6D* + ID_OUI_FROM_DATABASE=Deltenna Ltd + +OUI:F8B599* + ID_OUI_FROM_DATABASE=Guangzhou CHNAVS Digital Technology Co.,Ltd + +OUI:F8C001* + ID_OUI_FROM_DATABASE=Juniper Networks + +OUI:F8C091* + ID_OUI_FROM_DATABASE=Highgates Technology + +OUI:F8C678* + ID_OUI_FROM_DATABASE=Carefusion + +OUI:F8D0AC* + ID_OUI_FROM_DATABASE=Sony Computer Entertainment Inc. + +OUI:F8D0BD* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:F8D111* + ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO., LTD. + +OUI:F8D3A9* + ID_OUI_FROM_DATABASE=AXAN Networks + +OUI:F8D462* + ID_OUI_FROM_DATABASE=Pumatronix Equipamentos Eletronicos Ltda. + +OUI:F8D756* + ID_OUI_FROM_DATABASE=Simm Tronic Limited + +OUI:F8D7BF* + ID_OUI_FROM_DATABASE=REV Ritter GmbH + +OUI:F8DAE2* + ID_OUI_FROM_DATABASE=Beta LaserMike + +OUI:F8DAF4* + ID_OUI_FROM_DATABASE=Taishan Online Technology Co., Ltd. + +OUI:F8DB4C* + ID_OUI_FROM_DATABASE=PNY Technologies, INC. + +OUI:F8DB7F* + ID_OUI_FROM_DATABASE=HTC Corporation + +OUI:F8DC7A* + ID_OUI_FROM_DATABASE=Variscite LTD + +OUI:F8DFA8* + ID_OUI_FROM_DATABASE=ZTE Corporation + +OUI:F8E4FB* + ID_OUI_FROM_DATABASE=Actiontec Electronics, Inc + +OUI:F8E7B5* + ID_OUI_FROM_DATABASE=µTech Engenharia e Automação LTDA + +OUI:F8E968* + ID_OUI_FROM_DATABASE=Egker Kft. + +OUI:F8EA0A* + ID_OUI_FROM_DATABASE=Dipl.-Math. Michael Rauch + +OUI:F8EDA5* + ID_OUI_FROM_DATABASE=ARRIS Group, Inc. + +OUI:F8F014* + ID_OUI_FROM_DATABASE=RackWare Inc. + +OUI:F8F082* + ID_OUI_FROM_DATABASE=NAG LLC + +OUI:F8F25A* + ID_OUI_FROM_DATABASE=G-Lab GmbH + +OUI:F8F7D3* + ID_OUI_FROM_DATABASE=International Communications Corporation + +OUI:F8F7FF* + ID_OUI_FROM_DATABASE=SYN-TECH SYSTEMS INC + +OUI:F8FB2F* + ID_OUI_FROM_DATABASE=Santur Corporation + +OUI:F8FE5C* + ID_OUI_FROM_DATABASE=Reciprocal Labs Corp + +OUI:FC0012* + ID_OUI_FROM_DATABASE=Toshiba Samsung Storage Technolgoy Korea Corporation + +OUI:FC01CD* + ID_OUI_FROM_DATABASE=FUNDACION TEKNIKER + +OUI:FC0647* + ID_OUI_FROM_DATABASE=Cortland Research, LLC + +OUI:FC0877* + ID_OUI_FROM_DATABASE=Prentke Romich Company + +OUI:FC0A81* + ID_OUI_FROM_DATABASE=Motorola Solutions Inc. + +OUI:FC0FE6* + ID_OUI_FROM_DATABASE=Sony Computer Entertainment Inc. + +OUI:FC10BD* + ID_OUI_FROM_DATABASE=Control Sistematizado S.A. + +OUI:FC1794* + ID_OUI_FROM_DATABASE=InterCreative Co., Ltd + +OUI:FC1D59* + ID_OUI_FROM_DATABASE=I Smart Cities HK Ltd + +OUI:FC1F19* + ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO-MECHANICS CO., LTD. + +OUI:FC1FC0* + ID_OUI_FROM_DATABASE=EURECAM + +OUI:FC253F* + ID_OUI_FROM_DATABASE=Apple, Inc. + +OUI:FC2A54* + ID_OUI_FROM_DATABASE=connected data + +OUI:FC2E2D* + ID_OUI_FROM_DATABASE=Lorom Industrial Co.LTD. + +OUI:FC2F40* + ID_OUI_FROM_DATABASE=Calxeda, Inc. + +OUI:FC3598* + ID_OUI_FROM_DATABASE=Favite Inc. + +OUI:FC4463* + ID_OUI_FROM_DATABASE=Universal Audio + +OUI:FC455F* + ID_OUI_FROM_DATABASE=JIANGXI SHANSHUI OPTOELECTRONIC TECHNOLOGY CO.,LTD + +OUI:FC48EF* + ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD + +OUI:FC4DD4* + ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co., Ltd. + +OUI:FC5090* + ID_OUI_FROM_DATABASE=SIMEX Sp. z o.o. + +OUI:FC52CE* + ID_OUI_FROM_DATABASE=Control iD + +OUI:FC5B24* + ID_OUI_FROM_DATABASE=Weibel Scientific A/S + +OUI:FC5B26* + ID_OUI_FROM_DATABASE=MikroBits + +OUI:FC6198* + ID_OUI_FROM_DATABASE=NEC Personal Products, Ltd + +OUI:FC626E* + ID_OUI_FROM_DATABASE=Beijing MDC Telecom + +OUI:FC683E* + ID_OUI_FROM_DATABASE=Directed Perception, Inc + +OUI:FC6C31* + ID_OUI_FROM_DATABASE=LXinstruments GmbH + +OUI:FC7516* + ID_OUI_FROM_DATABASE=D-Link International + +OUI:FC75E6* + ID_OUI_FROM_DATABASE=Handreamnet + +OUI:FC7CE7* + ID_OUI_FROM_DATABASE=FCI USA LLC + +OUI:FC8329* + ID_OUI_FROM_DATABASE=Trei technics + +OUI:FC8399* + ID_OUI_FROM_DATABASE=Avaya, Inc + +OUI:FC8E7E* + ID_OUI_FROM_DATABASE=Pace plc + +OUI:FC8FC4* + ID_OUI_FROM_DATABASE=Intelligent Technology Inc. + +OUI:FC946C* + ID_OUI_FROM_DATABASE=UBIVELOX + +OUI:FC94E3* + ID_OUI_FROM_DATABASE=Technicolor USA Inc. + +OUI:FC9947* + ID_OUI_FROM_DATABASE=Cisco + +OUI:FC9FAE* + ID_OUI_FROM_DATABASE=Fidus Systems Inc + +OUI:FCA13E* + ID_OUI_FROM_DATABASE=Samsung Electronics + +OUI:FCA841* + ID_OUI_FROM_DATABASE=Avaya, Inc + +OUI:FCA9B0* + ID_OUI_FROM_DATABASE=MIARTECH (SHANGHAI),INC. + +OUI:FCAD0F* + ID_OUI_FROM_DATABASE=QTS NETWORKS + +OUI:FCAF6A* + ID_OUI_FROM_DATABASE=Conemtech AB + +OUI:FCC23D* + ID_OUI_FROM_DATABASE=Atmel Corporation + +OUI:FCC734* + ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd + +OUI:FCC897* + ID_OUI_FROM_DATABASE=ZTE Corporation + +OUI:FCCCE4* + ID_OUI_FROM_DATABASE=Ascon Ltd. + +OUI:FCCF62* + ID_OUI_FROM_DATABASE=IBM Corp + +OUI:FCD4F2* + ID_OUI_FROM_DATABASE=The Coca Cola Company + +OUI:FCD4F6* + ID_OUI_FROM_DATABASE=Messana Air.Ray Conditioning s.r.l. + +OUI:FCD6BD* + ID_OUI_FROM_DATABASE=Robert Bosch GmbH + +OUI:FCE192* + ID_OUI_FROM_DATABASE=Sichuan Jinwangtong Electronic Science&Technology Co,.Ltd + +OUI:FCE23F* + ID_OUI_FROM_DATABASE=CLAY PAKY SPA + +OUI:FCE557* + ID_OUI_FROM_DATABASE=Nokia Corporation + +OUI:FCE892* + ID_OUI_FROM_DATABASE=Hangzhou Lancable Technology Co.,Ltd + +OUI:FCEDB9* + ID_OUI_FROM_DATABASE=Arrayent + +OUI:FCF1CD* + ID_OUI_FROM_DATABASE=OPTEX-FA CO.,LTD. + +OUI:FCF528* + ID_OUI_FROM_DATABASE=ZyXEL Communications Corporation + +OUI:FCF8AE* + ID_OUI_FROM_DATABASE=Intel Corporate + +OUI:FCFAF7* + ID_OUI_FROM_DATABASE=Shanghai Baud Data Communication Co.,Ltd. + +OUI:FCFBFB* + ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC. diff --git a/hwdb/20-acpi-vendor.hwdb b/hwdb/20-acpi-vendor.hwdb new file mode 100644 index 000000000..09fc3bddc --- /dev/null +++ b/hwdb/20-acpi-vendor.hwdb @@ -0,0 +1,6596 @@ +# This file is part of systemd. +# +# Data imported from: +# http://download.microsoft.com/download/7/E/7/7E7662CF-CBEA-470B-A97E-CE7CE0D98DC2/ISA_PNPID_List.xlsx +# Non-unique, duplicate assignements manually removed. + +acpi:AAA*: + ID_VENDOR_FROM_DATABASE=Avolites Ltd + +acpi:AAE*: + ID_VENDOR_FROM_DATABASE=Anatek Electronics Inc. + +acpi:AAT*: + ID_VENDOR_FROM_DATABASE=Ann Arbor Technologies + +acpi:ABA*: + ID_VENDOR_FROM_DATABASE=ABBAHOME INC. + +acpi:ABC*: + ID_VENDOR_FROM_DATABASE=AboCom System Inc + +acpi:ABD*: + ID_VENDOR_FROM_DATABASE=Allen Bradley Company + +acpi:ABE*: + ID_VENDOR_FROM_DATABASE=Alcatel Bell + +acpi:ABO*: + ID_VENDOR_FROM_DATABASE=D-Link Systems Inc + +acpi:ABT*: + ID_VENDOR_FROM_DATABASE=Anchor Bay Technologies, Inc. + +acpi:ABV*: + ID_VENDOR_FROM_DATABASE=Advanced Research Technology + +acpi:ACA*: + ID_VENDOR_FROM_DATABASE=Ariel Corporation + +acpi:ACB*: + ID_VENDOR_FROM_DATABASE=Aculab Ltd + +acpi:ACC*: + ID_VENDOR_FROM_DATABASE=Accton Technology Corporation + +acpi:ACD*: + ID_VENDOR_FROM_DATABASE=AWETA BV + +acpi:ACE*: + ID_VENDOR_FROM_DATABASE=Actek Engineering Pty Ltd + +acpi:ACG*: + ID_VENDOR_FROM_DATABASE=A&R Cambridge Ltd + +acpi:ACH*: + ID_VENDOR_FROM_DATABASE=Archtek Telecom Corporation + +acpi:ACI*: + ID_VENDOR_FROM_DATABASE=Ancor Communications Inc + +acpi:ACK*: + ID_VENDOR_FROM_DATABASE=Acksys + +acpi:ACL*: + ID_VENDOR_FROM_DATABASE=Apricot Computers + +acpi:ACM*: + ID_VENDOR_FROM_DATABASE=Acroloop Motion Control Systems Inc + +acpi:ACO*: + ID_VENDOR_FROM_DATABASE=Allion Computer Inc. + +acpi:ACP[0-9A-F]*: + ID_VENDOR_FROM_DATABASE=Aspen Tech Inc + +acpi:ACR*: + ID_VENDOR_FROM_DATABASE=Acer Technologies + +acpi:ACS*: + ID_VENDOR_FROM_DATABASE=Altos Computer Systems + +acpi:ACT*: + ID_VENDOR_FROM_DATABASE=Applied Creative Technology + +acpi:ACU*: + ID_VENDOR_FROM_DATABASE=Acculogic + +acpi:ACV*: + ID_VENDOR_FROM_DATABASE=ActivCard S.A + +acpi:ADA*: + ID_VENDOR_FROM_DATABASE=Addi-Data GmbH + +acpi:ADB*: + ID_VENDOR_FROM_DATABASE=Aldebbaron + +acpi:ADC*: + ID_VENDOR_FROM_DATABASE=Acnhor Datacomm + +acpi:ADD*: + ID_VENDOR_FROM_DATABASE=Advanced Peripheral Devices Inc + +acpi:ADE*: + ID_VENDOR_FROM_DATABASE=Arithmos, Inc. + +acpi:ADH*: + ID_VENDOR_FROM_DATABASE=Aerodata Holdings Ltd + +acpi:ADI*: + ID_VENDOR_FROM_DATABASE=ADI Systems Inc + +acpi:ADK*: + ID_VENDOR_FROM_DATABASE=Adtek System Science Company Ltd + +acpi:ADL*: + ID_VENDOR_FROM_DATABASE=ASTRA Security Products Ltd + +acpi:ADM*: + ID_VENDOR_FROM_DATABASE=Ad Lib MultiMedia Inc + +acpi:ADN*: + ID_VENDOR_FROM_DATABASE=Analog & Digital Devices Tel. Inc + +acpi:ADP*: + ID_VENDOR_FROM_DATABASE=Adaptec Inc + +acpi:ADR*: + ID_VENDOR_FROM_DATABASE=Nasa Ames Research Center + +acpi:ADS*: + ID_VENDOR_FROM_DATABASE=Analog Devices Inc + +acpi:ADT*: + ID_VENDOR_FROM_DATABASE=Aved Display Technologies + +acpi:ADV*: + ID_VENDOR_FROM_DATABASE=Advanced Micro Devices Inc + +acpi:ADX*: + ID_VENDOR_FROM_DATABASE=Adax Inc + +acpi:AEC*: + ID_VENDOR_FROM_DATABASE=Antex Electronics Corporation + +acpi:AED*: + ID_VENDOR_FROM_DATABASE=Advanced Electronic Designs, Inc. + +acpi:AEI*: + ID_VENDOR_FROM_DATABASE=Actiontec Electric Inc + +acpi:AEJ*: + ID_VENDOR_FROM_DATABASE=Alpha Electronics Company + +acpi:AEM*: + ID_VENDOR_FROM_DATABASE=ASEM S.p.A. + +acpi:AEN*: + ID_VENDOR_FROM_DATABASE=Avencall + +acpi:AEP*: + ID_VENDOR_FROM_DATABASE=Aetas Peripheral International + +acpi:AET*: + ID_VENDOR_FROM_DATABASE=Aethra Telecomunicazioni S.r.l. + +acpi:AFA*: + ID_VENDOR_FROM_DATABASE=Alfa Inc + +acpi:AGC*: + ID_VENDOR_FROM_DATABASE=Beijing Aerospace Golden Card Electronic Engineering Co.,Ltd. + +acpi:AGI*: + ID_VENDOR_FROM_DATABASE=Artish Graphics Inc + +acpi:AGL*: + ID_VENDOR_FROM_DATABASE=Argolis + +acpi:AGM*: + ID_VENDOR_FROM_DATABASE=Advan Int'l Corporation + +acpi:AGT*: + ID_VENDOR_FROM_DATABASE=Agilent Technologies + +acpi:AHC*: + ID_VENDOR_FROM_DATABASE=Advantech Co., Ltd. + +acpi:AIC*: + ID_VENDOR_FROM_DATABASE=Arnos Insturments & Computer Systems + +acpi:AIE*: + ID_VENDOR_FROM_DATABASE=Altmann Industrieelektronik + +acpi:AII*: + ID_VENDOR_FROM_DATABASE=Amptron International Inc. + +acpi:AIL*: + ID_VENDOR_FROM_DATABASE=Altos India Ltd + +acpi:AIM*: + ID_VENDOR_FROM_DATABASE=AIMS Lab Inc + +acpi:AIR*: + ID_VENDOR_FROM_DATABASE=Advanced Integ. Research Inc + +acpi:AIS*: + ID_VENDOR_FROM_DATABASE=Alien Internet Services + +acpi:AIW*: + ID_VENDOR_FROM_DATABASE=Aiwa Company Ltd + +acpi:AIX*: + ID_VENDOR_FROM_DATABASE=ALTINEX, INC. + +acpi:AJA*: + ID_VENDOR_FROM_DATABASE=AJA Video Systems, Inc. + +acpi:AKB*: + ID_VENDOR_FROM_DATABASE=Akebia Ltd + +acpi:AKE*: + ID_VENDOR_FROM_DATABASE=AKAMI Electric Co.,Ltd + +acpi:AKI*: + ID_VENDOR_FROM_DATABASE=AKIA Corporation + +acpi:AKL*: + ID_VENDOR_FROM_DATABASE=AMiT Ltd + +acpi:AKM*: + ID_VENDOR_FROM_DATABASE=Asahi Kasei Microsystems Company Ltd + +acpi:AKP*: + ID_VENDOR_FROM_DATABASE=Atom Komplex Prylad + +acpi:AKY*: + ID_VENDOR_FROM_DATABASE=Askey Computer Corporation + +acpi:ALA*: + ID_VENDOR_FROM_DATABASE=Alacron Inc + +acpi:ALC*: + ID_VENDOR_FROM_DATABASE=Altec Corporation + +acpi:ALD*: + ID_VENDOR_FROM_DATABASE=In4S Inc + +acpi:ALG*: + ID_VENDOR_FROM_DATABASE=Realtek Semiconductor Corp. + +acpi:ALH*: + ID_VENDOR_FROM_DATABASE=AL Systems + +acpi:ALI*: + ID_VENDOR_FROM_DATABASE=Acer Labs + +acpi:ALJ*: + ID_VENDOR_FROM_DATABASE=Altec Lansing + +acpi:ALK*: + ID_VENDOR_FROM_DATABASE=Acrolink Inc + +acpi:ALL*: + ID_VENDOR_FROM_DATABASE=Alliance Semiconductor Corporation + +acpi:ALM*: + ID_VENDOR_FROM_DATABASE=Acutec Ltd. + +acpi:ALN*: + ID_VENDOR_FROM_DATABASE=Alana Technologies + +acpi:ALO*: + ID_VENDOR_FROM_DATABASE=Algolith Inc. + +acpi:ALP*: + ID_VENDOR_FROM_DATABASE=Alps Electric Company Ltd + +acpi:ALR*: + ID_VENDOR_FROM_DATABASE=Advanced Logic + +acpi:ALS*: + ID_VENDOR_FROM_DATABASE=Avance Logic Inc + +acpi:ALT*: + ID_VENDOR_FROM_DATABASE=Altra + +acpi:ALV*: + ID_VENDOR_FROM_DATABASE=AlphaView LCD + +acpi:ALX*: + ID_VENDOR_FROM_DATABASE=ALEXON Co.,Ltd. + +acpi:AMA*: + ID_VENDOR_FROM_DATABASE=Asia Microelectronic Development Inc + +acpi:AMB*: + ID_VENDOR_FROM_DATABASE=Ambient Technologies, Inc. + +acpi:AMC*: + ID_VENDOR_FROM_DATABASE=Attachmate Corporation + +acpi:AMD*: + ID_VENDOR_FROM_DATABASE=Amdek Corporation + +acpi:AMI*: + ID_VENDOR_FROM_DATABASE=American Megatrends Inc + +acpi:AML*: + ID_VENDOR_FROM_DATABASE=Anderson Multimedia Communications (HK) Limited + +acpi:AMN*: + ID_VENDOR_FROM_DATABASE=Amimon LTD. + +acpi:AMO*: + ID_VENDOR_FROM_DATABASE=Amino Technologies PLC and Amino Communications Limited + +acpi:AMP*: + ID_VENDOR_FROM_DATABASE=AMP Inc + +acpi:AMS *: + ID_VENDOR_FROM_DATABASE=ARMSTEL, Inc. + +acpi:AMT*: + ID_VENDOR_FROM_DATABASE=AMT International Industry + +acpi:AMX*: + ID_VENDOR_FROM_DATABASE=AMX LLC + +acpi:ANA*: + ID_VENDOR_FROM_DATABASE=Anakron + +acpi:ANC*: + ID_VENDOR_FROM_DATABASE=Ancot + +acpi:AND*: + ID_VENDOR_FROM_DATABASE=Adtran Inc + +acpi:ANI*: + ID_VENDOR_FROM_DATABASE=Anigma Inc + +acpi:ANK*: + ID_VENDOR_FROM_DATABASE=Anko Electronic Company Ltd + +acpi:ANL*: + ID_VENDOR_FROM_DATABASE=Analogix Semiconductor, Inc + +acpi:ANO*: + ID_VENDOR_FROM_DATABASE=Anorad Corporation + +acpi:ANP*: + ID_VENDOR_FROM_DATABASE=Andrew Network Production + +acpi:ANR*: + ID_VENDOR_FROM_DATABASE=ANR Ltd + +acpi:ANS*: + ID_VENDOR_FROM_DATABASE=Ansel Communication Company + +acpi:ANT*: + ID_VENDOR_FROM_DATABASE=Ace CAD Enterprise Company Ltd + +acpi:ANX*: + ID_VENDOR_FROM_DATABASE=Acer Netxus Inc + +acpi:AOA*: + ID_VENDOR_FROM_DATABASE=AOpen Inc. + +acpi:AOE*: + ID_VENDOR_FROM_DATABASE=Advanced Optics Electronics, Inc. + +acpi:AOL*: + ID_VENDOR_FROM_DATABASE=America OnLine + +acpi:AOT*: + ID_VENDOR_FROM_DATABASE=Alcatel + +acpi:APC*: + ID_VENDOR_FROM_DATABASE=American Power Conversion + +acpi:APD*: + ID_VENDOR_FROM_DATABASE=AppliAdata + +acpi:APG*: + ID_VENDOR_FROM_DATABASE=Horner Electric Inc + +acpi:API*: + ID_VENDOR_FROM_DATABASE=A Plus Info Corporation + +acpi:APL*: + ID_VENDOR_FROM_DATABASE=Aplicom Oy + +acpi:APM*: + ID_VENDOR_FROM_DATABASE=Applied Memory Tech + +acpi:APN*: + ID_VENDOR_FROM_DATABASE=Appian Tech Inc + +acpi:APP*: + ID_VENDOR_FROM_DATABASE=Apple Computer Inc + +acpi:APR*: + ID_VENDOR_FROM_DATABASE=Aprilia s.p.a. + +acpi:APS*: + ID_VENDOR_FROM_DATABASE=Autologic Inc + +acpi:APT*: + ID_VENDOR_FROM_DATABASE=Audio Processing Technology Ltd + +acpi:APV*: + ID_VENDOR_FROM_DATABASE=A+V Link + +acpi:APX*: + ID_VENDOR_FROM_DATABASE=AP Designs Ltd + +acpi:ARC*: + ID_VENDOR_FROM_DATABASE=Alta Research Corporation + +acpi:ARE*: + ID_VENDOR_FROM_DATABASE=ICET S.p.A. + +acpi:ARG*: + ID_VENDOR_FROM_DATABASE=Argus Electronics Co., LTD + +acpi:ARI*: + ID_VENDOR_FROM_DATABASE=Argosy Research Inc + +acpi:ARK*: + ID_VENDOR_FROM_DATABASE=Ark Logic Inc + +acpi:ARL*: + ID_VENDOR_FROM_DATABASE=Arlotto Comnet Inc + +acpi:ARM*: + ID_VENDOR_FROM_DATABASE=Arima + +acpi:ARO*: + ID_VENDOR_FROM_DATABASE=Poso International B.V. + +acpi:ARS*: + ID_VENDOR_FROM_DATABASE=Arescom Inc + +acpi:ART*: + ID_VENDOR_FROM_DATABASE=Corion Industrial Corporation + +acpi:ASC*: + ID_VENDOR_FROM_DATABASE=Ascom Strategic Technology Unit + +acpi:ASD*: + ID_VENDOR_FROM_DATABASE=USC Information Sciences Institute + +acpi:ASE*: + ID_VENDOR_FROM_DATABASE=AseV Display Labs + +acpi:ASI*: + ID_VENDOR_FROM_DATABASE=Ahead Systems + +acpi:ASK*: + ID_VENDOR_FROM_DATABASE=Ask A/S + +acpi:ASL*: + ID_VENDOR_FROM_DATABASE=AccuScene Corporation Ltd + +acpi:ASM*: + ID_VENDOR_FROM_DATABASE=ASEM S.p.A. + +acpi:ASN*: + ID_VENDOR_FROM_DATABASE=Asante Tech Inc + +acpi:ASP*: + ID_VENDOR_FROM_DATABASE=ASP Microelectronics Ltd + +acpi:AST*: + ID_VENDOR_FROM_DATABASE=AST Research Inc + +acpi:ASU*: + ID_VENDOR_FROM_DATABASE=Asuscom Network Inc + +acpi:ASX*: + ID_VENDOR_FROM_DATABASE=AudioScience + +acpi:ASY*: + ID_VENDOR_FROM_DATABASE=Rockwell Collins / Airshow Systems + +acpi:ATA*: + ID_VENDOR_FROM_DATABASE=Allied Telesyn International (Asia) Pte Ltd + +acpi:ATC*: + ID_VENDOR_FROM_DATABASE=Ably-Tech Corporation + +acpi:ATD*: + ID_VENDOR_FROM_DATABASE=Alpha Telecom Inc + +acpi:ATE*: + ID_VENDOR_FROM_DATABASE=Innovate Ltd + +acpi:ATH*: + ID_VENDOR_FROM_DATABASE=Athena Informatica S.R.L. + +acpi:ATI*: + ID_VENDOR_FROM_DATABASE=Allied Telesis KK + +acpi:ATK*: + ID_VENDOR_FROM_DATABASE=Allied Telesyn Int'l + +acpi:ATL*: + ID_VENDOR_FROM_DATABASE=Arcus Technology Ltd + +acpi:ATM*: + ID_VENDOR_FROM_DATABASE=ATM Ltd + +acpi:ATN*: + ID_VENDOR_FROM_DATABASE=Athena Smartcard Solutions Ltd. + +acpi:ATO*: + ID_VENDOR_FROM_DATABASE=ASTRO DESIGN, INC. + +acpi:ATP*: + ID_VENDOR_FROM_DATABASE=Alpha-Top Corporation + +acpi:ATT*: + ID_VENDOR_FROM_DATABASE=AT&T + +acpi:ATV*: + ID_VENDOR_FROM_DATABASE=Office Depot, Inc. + +acpi:ATX*: + ID_VENDOR_FROM_DATABASE=Athenix Corporation + +acpi:AUI*: + ID_VENDOR_FROM_DATABASE=Alps Electric Inc + +acpi:AUR*: + ID_VENDOR_FROM_DATABASE=Aureal Semiconductor + +acpi:AUT*: + ID_VENDOR_FROM_DATABASE=Autotime Corporation + +acpi:AVA*: + ID_VENDOR_FROM_DATABASE=Avaya Communication + +acpi:AVC*: + ID_VENDOR_FROM_DATABASE=Auravision Corporation + +acpi:AVD*: + ID_VENDOR_FROM_DATABASE=Avid Electronics Corporation + +acpi:AVE*: + ID_VENDOR_FROM_DATABASE=Add Value Enterpises (Asia) Pte Ltd + +acpi:AVI*: + ID_VENDOR_FROM_DATABASE=Nippon Avionics Co.,Ltd + +acpi:AVL*: + ID_VENDOR_FROM_DATABASE=Avalue Technology Inc. + +acpi:AVM*: + ID_VENDOR_FROM_DATABASE=AVM GmbH + +acpi:AVN *: + ID_VENDOR_FROM_DATABASE=Advance Computer Corporation + +acpi:AVO*: + ID_VENDOR_FROM_DATABASE=Avocent Corporation + +acpi:AVR*: + ID_VENDOR_FROM_DATABASE=AVer Information Inc. + +acpi:AVT*: + ID_VENDOR_FROM_DATABASE=Avtek (Electronics) Pty Ltd + +acpi:AVV*: + ID_VENDOR_FROM_DATABASE=SBS Technologies (Canada), Inc. (was Avvida Systems, Inc.) + +acpi:AWC*: + ID_VENDOR_FROM_DATABASE=Access Works Comm Inc + +acpi:AWL*: + ID_VENDOR_FROM_DATABASE=Aironet Wireless Communications, Inc + +acpi:AWS*: + ID_VENDOR_FROM_DATABASE=Wave Systems + +acpi:AXB*: + ID_VENDOR_FROM_DATABASE=Adrienne Electronics Corporation + +acpi:AXC*: + ID_VENDOR_FROM_DATABASE=AXIOMTEK CO., LTD. + +acpi:AXE*: + ID_VENDOR_FROM_DATABASE=D-Link Systems Inc (used as 2nd pnpid) + +acpi:AXI*: + ID_VENDOR_FROM_DATABASE=American Magnetics + +acpi:AXL*: + ID_VENDOR_FROM_DATABASE=Axel + +acpi:AXO*: + ID_VENDOR_FROM_DATABASE=Axonic Labs LLC + +acpi:AXP*: + ID_VENDOR_FROM_DATABASE=American Express + +acpi:AXT*: + ID_VENDOR_FROM_DATABASE=Axtend Technologies Inc + +acpi:AXX*: + ID_VENDOR_FROM_DATABASE=Axxon Computer Corporation + +acpi:AXY*: + ID_VENDOR_FROM_DATABASE=AXYZ Automation Services, Inc + +acpi:AYD*: + ID_VENDOR_FROM_DATABASE=Aydin Displays + +acpi:AYR*: + ID_VENDOR_FROM_DATABASE=Airlib, Inc + +acpi:AZM*: + ID_VENDOR_FROM_DATABASE=AZ Middelheim - Radiotherapy + +acpi:AZT*: + ID_VENDOR_FROM_DATABASE=Aztech Systems Ltd + +acpi:BAC*: + ID_VENDOR_FROM_DATABASE=Biometric Access Corporation + +acpi:BAN*: + ID_VENDOR_FROM_DATABASE=Banyan + +acpi:BBB*: + ID_VENDOR_FROM_DATABASE=an-najah university + +acpi:BBH*: + ID_VENDOR_FROM_DATABASE=B&Bh + +acpi:BBL*: + ID_VENDOR_FROM_DATABASE=Brain Boxes Limited + +acpi:BCC*: + ID_VENDOR_FROM_DATABASE=Beaver Computer Corporaton + +acpi:BCD*: + ID_VENDOR_FROM_DATABASE=Barco GmbH + +acpi:BCM*: + ID_VENDOR_FROM_DATABASE=Broadcom + +acpi:BCQ*: + ID_VENDOR_FROM_DATABASE=Deutsche Telekom Berkom GmbH + +acpi:BCS*: + ID_VENDOR_FROM_DATABASE=Booria CAD/CAM systems + +acpi:BDO*: + ID_VENDOR_FROM_DATABASE=Brahler ICS + +acpi:BDR*: + ID_VENDOR_FROM_DATABASE=Blonder Tongue Labs, Inc. + +acpi:BDS*: + ID_VENDOR_FROM_DATABASE=Barco Display Systems + +acpi:BEC*: + ID_VENDOR_FROM_DATABASE=Elektro Beckhoff GmbH + +acpi:BEI*: + ID_VENDOR_FROM_DATABASE=Beckworth Enterprises Inc + +acpi:BEK*: + ID_VENDOR_FROM_DATABASE=Beko Elektronik A.S. + +acpi:BEL*: + ID_VENDOR_FROM_DATABASE=Beltronic Industrieelektronik GmbH + +acpi:BEO*: + ID_VENDOR_FROM_DATABASE=Baug & Olufsen + +acpi:BFE*: + ID_VENDOR_FROM_DATABASE=B.F. Engineering Corporation + +acpi:BGB*: + ID_VENDOR_FROM_DATABASE=Barco Graphics N.V + +acpi:BGT*: + ID_VENDOR_FROM_DATABASE=Budzetron Inc + +acpi:BHZ*: + ID_VENDOR_FROM_DATABASE=BitHeadz, Inc. + +acpi:BIC*: + ID_VENDOR_FROM_DATABASE=Big Island Communications + +acpi:BII*: + ID_VENDOR_FROM_DATABASE=Boeckeler Instruments Inc + +acpi:BIL*: + ID_VENDOR_FROM_DATABASE=Billion Electric Company Ltd + +acpi:BIO*: + ID_VENDOR_FROM_DATABASE=BioLink Technologies International, Inc. + +acpi:BIT*: + ID_VENDOR_FROM_DATABASE=Bit 3 Computer + +acpi:BLI*: + ID_VENDOR_FROM_DATABASE=Busicom + +acpi:BLN*: + ID_VENDOR_FROM_DATABASE=BioLink Technologies + +acpi:BLP*: + ID_VENDOR_FROM_DATABASE=Bloomberg L.P. + +acpi:BMI*: + ID_VENDOR_FROM_DATABASE=Benson Medical Instruments Company + +acpi:BML*: + ID_VENDOR_FROM_DATABASE=BIOMED Lab + +acpi:BMS*: + ID_VENDOR_FROM_DATABASE=BIOMEDISYS + +acpi:BNE*: + ID_VENDOR_FROM_DATABASE=Bull AB + +acpi:BNK*: + ID_VENDOR_FROM_DATABASE=Banksia Tech Pty Ltd + +acpi:BNO*: + ID_VENDOR_FROM_DATABASE=Bang & Olufsen + +acpi:BNS*: + ID_VENDOR_FROM_DATABASE=Boulder Nonlinear Systems + +acpi:BOB*: + ID_VENDOR_FROM_DATABASE=Rainy Orchard + +acpi:BOE*: + ID_VENDOR_FROM_DATABASE=BOE + +acpi:BOI*: + ID_VENDOR_FROM_DATABASE=NINGBO BOIGLE DIGITAL TECHNOLOGY CO.,LTD + +acpi:BOS*: + ID_VENDOR_FROM_DATABASE=BOS + +acpi:BPD*: + ID_VENDOR_FROM_DATABASE=Micro Solutions, Inc. + +acpi:BPU*: + ID_VENDOR_FROM_DATABASE=Best Power + +acpi:BRA*: + ID_VENDOR_FROM_DATABASE=Braemac Pty Ltd + +acpi:BRC*: + ID_VENDOR_FROM_DATABASE=BARC + +acpi:BRG*: + ID_VENDOR_FROM_DATABASE=Bridge Information Co., Ltd + +acpi:BRI*: + ID_VENDOR_FROM_DATABASE=Boca Research Inc + +acpi:BRM*: + ID_VENDOR_FROM_DATABASE=Braemar Inc + +acpi:BRO*: + ID_VENDOR_FROM_DATABASE=BROTHER INDUSTRIES,LTD. + +acpi:BSE*: + ID_VENDOR_FROM_DATABASE=Bose Corporation + +acpi:BSL*: + ID_VENDOR_FROM_DATABASE=Biomedical Systems Laboratory + +acpi:BSN*: + ID_VENDOR_FROM_DATABASE=BRIGHTSIGN, LLC + +acpi:BST*: + ID_VENDOR_FROM_DATABASE=BodySound Technologies, Inc. + +acpi:BTC*: + ID_VENDOR_FROM_DATABASE=Bit 3 Computer + +acpi:BTE*: + ID_VENDOR_FROM_DATABASE=Brilliant Technology + +acpi:BTF*: + ID_VENDOR_FROM_DATABASE=Bitfield Oy + +acpi:BTI*: + ID_VENDOR_FROM_DATABASE=BusTech Inc + +acpi:BTO*: + ID_VENDOR_FROM_DATABASE=BioTao Ltd + +acpi:BUF*: + ID_VENDOR_FROM_DATABASE=Yasuhiko Shirai Melco Inc + +acpi:BUG*: + ID_VENDOR_FROM_DATABASE=B.U.G., Inc. + +acpi:BUJ*: + ID_VENDOR_FROM_DATABASE=ATI Tech Inc + +acpi:BUL*: + ID_VENDOR_FROM_DATABASE=Bull + +acpi:BUR*: + ID_VENDOR_FROM_DATABASE=Bernecker & Rainer Ind-Eletronik GmbH + +acpi:BUS*: + ID_VENDOR_FROM_DATABASE=BusTek + +acpi:BUT*: + ID_VENDOR_FROM_DATABASE=21ST CENTURY ENTERTAINMENT + +acpi:BWK*: + ID_VENDOR_FROM_DATABASE=Bitworks Inc. + +acpi:BXE*: + ID_VENDOR_FROM_DATABASE=Buxco Electronics + +acpi:BYD*: + ID_VENDOR_FROM_DATABASE=byd:sign corporation + +acpi:CAA*: + ID_VENDOR_FROM_DATABASE=Castles Automation Co., Ltd + +acpi:CAC*: + ID_VENDOR_FROM_DATABASE=CA & F Elettronica + +acpi:CAG*: + ID_VENDOR_FROM_DATABASE=CalComp + +acpi:CAI*: + ID_VENDOR_FROM_DATABASE=Canon Inc. + +acpi:CAL*: + ID_VENDOR_FROM_DATABASE=Acon + +acpi:CAM*: + ID_VENDOR_FROM_DATABASE=Cambridge Audio + +acpi:CAN*: + ID_VENDOR_FROM_DATABASE=Canopus Company Ltd + +acpi:CAR*: + ID_VENDOR_FROM_DATABASE=Cardinal Company Ltd + +acpi:CAS*: + ID_VENDOR_FROM_DATABASE=CASIO COMPUTER CO.,LTD + +acpi:CAT*: + ID_VENDOR_FROM_DATABASE=Consultancy in Advanced Technology + +acpi:CAV*: + ID_VENDOR_FROM_DATABASE=Cavium Networks, Inc + +acpi:CBI*: + ID_VENDOR_FROM_DATABASE=ComputerBoards Inc + +acpi:CBR*: + ID_VENDOR_FROM_DATABASE=Cebra Tech A/S + +acpi:CBT*: + ID_VENDOR_FROM_DATABASE=Cabletime Ltd + +acpi:CBX*: + ID_VENDOR_FROM_DATABASE=Cybex Computer Products Corporation + +acpi:CCC*: + ID_VENDOR_FROM_DATABASE=C-Cube Microsystems + +acpi:CCI*: + ID_VENDOR_FROM_DATABASE=Cache + +acpi:CCJ*: + ID_VENDOR_FROM_DATABASE=CONTEC CO.,LTD. + +acpi:CCL*: + ID_VENDOR_FROM_DATABASE=CCL/ITRI + +acpi:CCP*: + ID_VENDOR_FROM_DATABASE=Capetronic USA Inc + +acpi:CDC*: + ID_VENDOR_FROM_DATABASE=Core Dynamics Corporation + +acpi:CDD*: + ID_VENDOR_FROM_DATABASE=Convergent Data Devices + +acpi:CDE*: + ID_VENDOR_FROM_DATABASE=Colin.de + +acpi:CDG*: + ID_VENDOR_FROM_DATABASE=Christie Digital Systems Inc + +acpi:CDI*: + ID_VENDOR_FROM_DATABASE=Concept Development Inc + +acpi:CDK*: + ID_VENDOR_FROM_DATABASE=Cray Communications + +acpi:CDN*: + ID_VENDOR_FROM_DATABASE=Codenoll Technical Corporation + +acpi:CDP*: + ID_VENDOR_FROM_DATABASE=CalComp + +acpi:CDS*: + ID_VENDOR_FROM_DATABASE=Computer Diagnostic Systems + +acpi:CDT*: + ID_VENDOR_FROM_DATABASE=IBM Corporation + +acpi:CDV*: + ID_VENDOR_FROM_DATABASE=Convergent Design Inc. + +acpi:CEA*: + ID_VENDOR_FROM_DATABASE=Consumer Electronics Association + +acpi:CEC*: + ID_VENDOR_FROM_DATABASE=Chicony Electronics Company Ltd + +acpi:CED*: + ID_VENDOR_FROM_DATABASE=Cambridge Electronic Design Ltd + +acpi:CEF*: + ID_VENDOR_FROM_DATABASE=Cefar Digital Vision + +acpi:CEI*: + ID_VENDOR_FROM_DATABASE=Crestron Electronics, Inc. + +acpi:CEM*: + ID_VENDOR_FROM_DATABASE=MEC Electronics GmbH + +acpi:CEN*: + ID_VENDOR_FROM_DATABASE=Centurion Technologies P/L + +acpi:CEP*: + ID_VENDOR_FROM_DATABASE=C-DAC + +acpi:CER*: + ID_VENDOR_FROM_DATABASE=Ceronix + +acpi:CET*: + ID_VENDOR_FROM_DATABASE=TEC CORPORATION + +acpi:CFG*: + ID_VENDOR_FROM_DATABASE=Atlantis + +acpi:CGA*: + ID_VENDOR_FROM_DATABASE=Chunghwa Picture Tubes, LTD + +acpi:CGS*: + ID_VENDOR_FROM_DATABASE=Chyron Corp + +acpi:CGT*: + ID_VENDOR_FROM_DATABASE=congatec AG + +acpi:CHA*: + ID_VENDOR_FROM_DATABASE=Chase Research PLC + +acpi:CHC*: + ID_VENDOR_FROM_DATABASE=Chic Technology Corp. + +acpi:CHD*: + ID_VENDOR_FROM_DATABASE=ChangHong Electric Co.,Ltd + +acpi:CHE*: + ID_VENDOR_FROM_DATABASE=Acer Inc + +acpi:CHG*: + ID_VENDOR_FROM_DATABASE=Sichuan Changhong Electric CO, LTD. + +acpi:CHI*: + ID_VENDOR_FROM_DATABASE=Chrontel Inc + +acpi:CHL*: + ID_VENDOR_FROM_DATABASE=Chloride-R&D + +acpi:CHM*: + ID_VENDOR_FROM_DATABASE=CHIC TECHNOLOGY CORP. + +acpi:CHO*: + ID_VENDOR_FROM_DATABASE=Sichuang Changhong Corporation + +acpi:CHP*: + ID_VENDOR_FROM_DATABASE=CH Products + +acpi:CHS*: + ID_VENDOR_FROM_DATABASE=Agentur Chairos + +acpi:CHT*: + ID_VENDOR_FROM_DATABASE=Chunghwa Picture Tubes,LTD. + +acpi:CHY*: + ID_VENDOR_FROM_DATABASE=Cherry GmbH + +acpi:CIC*: + ID_VENDOR_FROM_DATABASE=Comm. Intelligence Corporation + +acpi:CII*: + ID_VENDOR_FROM_DATABASE=Cromack Industries Inc + +acpi:CIL*: + ID_VENDOR_FROM_DATABASE=Citicom Infotech Private Limited + +acpi:CIN*: + ID_VENDOR_FROM_DATABASE=Citron GmbH + +acpi:CIP*: + ID_VENDOR_FROM_DATABASE=Ciprico Inc + +acpi:CIR*: + ID_VENDOR_FROM_DATABASE=Cirrus Logic Inc + +acpi:CIS*: + ID_VENDOR_FROM_DATABASE=Cisco Systems Inc + +acpi:CIT*: + ID_VENDOR_FROM_DATABASE=Citifax Limited + +acpi:CKC*: + ID_VENDOR_FROM_DATABASE=The Concept Keyboard Company Ltd + +acpi:CKJ*: + ID_VENDOR_FROM_DATABASE=Carina System Co., Ltd. + +acpi:CLA*: + ID_VENDOR_FROM_DATABASE=Clarion Company Ltd + +acpi:CLD*: + ID_VENDOR_FROM_DATABASE=COMMAT L.t.d. + +acpi:CLE*: + ID_VENDOR_FROM_DATABASE=Classe Audio + +acpi:CLG*: + ID_VENDOR_FROM_DATABASE=CoreLogic + +acpi:CLI*: + ID_VENDOR_FROM_DATABASE=Cirrus Logic Inc + +acpi:CLM*: + ID_VENDOR_FROM_DATABASE=CrystaLake Multimedia + +acpi:CLO*: + ID_VENDOR_FROM_DATABASE=Clone Computers + +acpi:CLT*: + ID_VENDOR_FROM_DATABASE=automated computer control systems + +acpi:CLV*: + ID_VENDOR_FROM_DATABASE=Clevo Company + +acpi:CLX*: + ID_VENDOR_FROM_DATABASE=CardLogix + +acpi:CMC*: + ID_VENDOR_FROM_DATABASE=CMC Ltd + +acpi:CMD*: + ID_VENDOR_FROM_DATABASE=Colorado MicroDisplay, Inc. + +acpi:CMG*: + ID_VENDOR_FROM_DATABASE=Chenming Mold Ind. Corp. + +acpi:CMI*: + ID_VENDOR_FROM_DATABASE=C-Media Electronics + +acpi:CMM*: + ID_VENDOR_FROM_DATABASE=Comtime GmbH + +acpi:CMN*: + ID_VENDOR_FROM_DATABASE=Chimei Innolux Corporation + +acpi:CMO*: + ID_VENDOR_FROM_DATABASE=Chi Mei Optoelectronics corp. + +acpi:CMR*: + ID_VENDOR_FROM_DATABASE=Cambridge Research Systems Ltd + +acpi:CMS*: + ID_VENDOR_FROM_DATABASE=CompuMaster Srl + +acpi:CMX*: + ID_VENDOR_FROM_DATABASE=Comex Electronics AB + +acpi:CNB*: + ID_VENDOR_FROM_DATABASE=American Power Conversion + +acpi:CNC*: + ID_VENDOR_FROM_DATABASE=Alvedon Computers Ltd + +acpi:CNE*: + ID_VENDOR_FROM_DATABASE=Cine-tal + +acpi:CNI*: + ID_VENDOR_FROM_DATABASE=Connect Int'l A/S + +acpi:CNN*: + ID_VENDOR_FROM_DATABASE=Canon Inc + +acpi:CNT*: + ID_VENDOR_FROM_DATABASE=COINT Multimedia Systems + +acpi:COB*: + ID_VENDOR_FROM_DATABASE=COBY Electronics Co., Ltd + +acpi:COD*: + ID_VENDOR_FROM_DATABASE=CODAN Pty. Ltd. + +acpi:COI*: + ID_VENDOR_FROM_DATABASE=Codec Inc. + +acpi:COL*: + ID_VENDOR_FROM_DATABASE=Rockwell Collins, Inc. + +acpi:COM*: + ID_VENDOR_FROM_DATABASE=Comtrol Corporation + +acpi:CON*: + ID_VENDOR_FROM_DATABASE=Contec Company Ltd + +acpi:COO*: + ID_VENDOR_FROM_DATABASE=coolux GmbH + +acpi:COR*: + ID_VENDOR_FROM_DATABASE=Corollary Inc + +acpi:COS*: + ID_VENDOR_FROM_DATABASE=CoStar Corporation + +acpi:COT*: + ID_VENDOR_FROM_DATABASE=Core Technology Inc + +acpi:COW*: + ID_VENDOR_FROM_DATABASE=Polycow Productions + +acpi:COX*: + ID_VENDOR_FROM_DATABASE=Comrex + +acpi:CPC*: + ID_VENDOR_FROM_DATABASE=Ciprico Inc + +acpi:CPD*: + ID_VENDOR_FROM_DATABASE=CompuAdd + +acpi:CPI*: + ID_VENDOR_FROM_DATABASE=Computer Peripherals Inc + +acpi:CPL*: + ID_VENDOR_FROM_DATABASE=Compal Electronics Inc + +acpi:CPM*: + ID_VENDOR_FROM_DATABASE=Capella Microsystems Inc. + +acpi:CPQ*: + ID_VENDOR_FROM_DATABASE=Compaq Computer Company + +acpi:CPT*: + ID_VENDOR_FROM_DATABASE=cPATH + +acpi:CPX*: + ID_VENDOR_FROM_DATABASE=Powermatic Data Systems + +acpi:CRC*: + ID_VENDOR_FROM_DATABASE=CONRAC GmbH + +acpi:CRD*: + ID_VENDOR_FROM_DATABASE=Cardinal Technical Inc + +acpi:CRE*: + ID_VENDOR_FROM_DATABASE=Creative Labs Inc + +acpi:CRI*: + ID_VENDOR_FROM_DATABASE=Crio Inc. + +acpi:CRL*: + ID_VENDOR_FROM_DATABASE=Creative Logic   + +acpi:CRN*: + ID_VENDOR_FROM_DATABASE=Cornerstone Imaging + +acpi:CRO*: + ID_VENDOR_FROM_DATABASE=Extraordinary Technologies PTY Limited + +acpi:CRQ*: + ID_VENDOR_FROM_DATABASE=Cirque Corporation + +acpi:CRS*: + ID_VENDOR_FROM_DATABASE=Crescendo Communication Inc + +acpi:CRV*: + ID_VENDOR_FROM_DATABASE=Cerevo Inc. + +acpi:CRX*: + ID_VENDOR_FROM_DATABASE=Cyrix Corporation + +acpi:CSB*: + ID_VENDOR_FROM_DATABASE=Transtex SA + +acpi:CSC*: + ID_VENDOR_FROM_DATABASE=Crystal Semiconductor + +acpi:CSD*: + ID_VENDOR_FROM_DATABASE=Cresta Systems Inc + +acpi:CSE*: + ID_VENDOR_FROM_DATABASE=Concept Solutions & Engineering + +acpi:CSI*: + ID_VENDOR_FROM_DATABASE=Cabletron System Inc + +acpi:CSM*: + ID_VENDOR_FROM_DATABASE=Cosmic Engineering Inc. + +acpi:CSO*: + ID_VENDOR_FROM_DATABASE=California Institute of Technology + +acpi:CSS*: + ID_VENDOR_FROM_DATABASE=CSS Laboratories + +acpi:CST*: + ID_VENDOR_FROM_DATABASE=CSTI Inc + +acpi:CTA*: + ID_VENDOR_FROM_DATABASE=CoSystems Inc + +acpi:CTC*: + ID_VENDOR_FROM_DATABASE=CTC Communication Development Company Ltd + +acpi:CTE*: + ID_VENDOR_FROM_DATABASE=Chunghwa Telecom Co., Ltd. + +acpi:CTL*: + ID_VENDOR_FROM_DATABASE=Creative Technology Ltd + +acpi:CTM*: + ID_VENDOR_FROM_DATABASE=Computerm Corporation + +acpi:CTN*: + ID_VENDOR_FROM_DATABASE=Computone Products + +acpi:CTP*: + ID_VENDOR_FROM_DATABASE=Computer Technology Corporation + +acpi:CTS*: + ID_VENDOR_FROM_DATABASE=Comtec Systems Co., Ltd. + +acpi:CTX*: + ID_VENDOR_FROM_DATABASE=Creatix Polymedia GmbH + +acpi:CUB*: + ID_VENDOR_FROM_DATABASE=Cubix Corporation + +acpi:CUK*: + ID_VENDOR_FROM_DATABASE=Calibre UK Ltd + +acpi:CVA*: + ID_VENDOR_FROM_DATABASE=Covia Inc. + +acpi:CVS*: + ID_VENDOR_FROM_DATABASE=Clarity Visual Systems + +acpi:CWR*: + ID_VENDOR_FROM_DATABASE=Connectware Inc + +acpi:CXT*: + ID_VENDOR_FROM_DATABASE=Conexant Systems + +acpi:CYB*: + ID_VENDOR_FROM_DATABASE=CyberVision + +acpi:CYC*: + ID_VENDOR_FROM_DATABASE=Cylink Corporation + +acpi:CYD*: + ID_VENDOR_FROM_DATABASE=Cyclades Corporation + +acpi:CYL*: + ID_VENDOR_FROM_DATABASE=Cyberlabs + +acpi:CYT*: + ID_VENDOR_FROM_DATABASE=Cytechinfo Inc + +acpi:CYV*: + ID_VENDOR_FROM_DATABASE=Cyviz AS + +acpi:CYW*: + ID_VENDOR_FROM_DATABASE=Cyberware + +acpi:CYX*: + ID_VENDOR_FROM_DATABASE=Cyrix Corporation + +acpi:CZE*: + ID_VENDOR_FROM_DATABASE=Carl Zeiss AG + +acpi:DAC*: + ID_VENDOR_FROM_DATABASE=Digital Acoustics Corporation + +acpi:DAE*: + ID_VENDOR_FROM_DATABASE=Digatron Industrie Elektronik GmbH + +acpi:DAI*: + ID_VENDOR_FROM_DATABASE=DAIS SET Ltd. + +acpi:DAK*: + ID_VENDOR_FROM_DATABASE=Daktronics + +acpi:DAL*: + ID_VENDOR_FROM_DATABASE=Digital Audio Labs Inc + +acpi:DAN*: + ID_VENDOR_FROM_DATABASE=Danelec Marine A/S + +acpi:DAS*: + ID_VENDOR_FROM_DATABASE=DAVIS AS + +acpi:DAT*: + ID_VENDOR_FROM_DATABASE=Datel Inc + +acpi:DAU*: + ID_VENDOR_FROM_DATABASE=Daou Tech Inc + +acpi:DAV*: + ID_VENDOR_FROM_DATABASE=Davicom Semiconductor Inc + +acpi:DAW*: + ID_VENDOR_FROM_DATABASE=DA2 Technologies Inc + +acpi:DAX*: + ID_VENDOR_FROM_DATABASE=Data Apex Ltd + +acpi:DBD*: + ID_VENDOR_FROM_DATABASE=Diebold Inc. + +acpi:DBI*: + ID_VENDOR_FROM_DATABASE=DigiBoard Inc + +acpi:DBK*: + ID_VENDOR_FROM_DATABASE=Databook Inc + +acpi:DBL*: + ID_VENDOR_FROM_DATABASE=Doble Engineering Company + +acpi:DBN*: + ID_VENDOR_FROM_DATABASE=DB Networks Inc + +acpi:DCA*: + ID_VENDOR_FROM_DATABASE=Digital Communications Association + +acpi:DCC*: + ID_VENDOR_FROM_DATABASE=Dale Computer Corporation + +acpi:DCD*: + ID_VENDOR_FROM_DATABASE=Datacast LLC + +acpi:DCE*: + ID_VENDOR_FROM_DATABASE=dSPACE GmbH + +acpi:DCI*: + ID_VENDOR_FROM_DATABASE=Concepts Inc + +acpi:DCL*: + ID_VENDOR_FROM_DATABASE=Dynamic Controls Ltd + +acpi:DCM*: + ID_VENDOR_FROM_DATABASE=DCM Data Products + +acpi:DCO*: + ID_VENDOR_FROM_DATABASE=Dialogue Technology Corporation + +acpi:DCR*: + ID_VENDOR_FROM_DATABASE=Decros Ltd + +acpi:DCS*: + ID_VENDOR_FROM_DATABASE=Diamond Computer Systems Inc + +acpi:DCT*: + ID_VENDOR_FROM_DATABASE=Dancall Telecom A/S + +acpi:DCV*: + ID_VENDOR_FROM_DATABASE=Datatronics Technology Inc + +acpi:DDA*: + ID_VENDOR_FROM_DATABASE=DA2 Technologies Corporation + +acpi:DDD*: + ID_VENDOR_FROM_DATABASE=Danka Data Devices + +acpi:DDE*: + ID_VENDOR_FROM_DATABASE=Datasat Digital Entertainment + +acpi:DDI*: + ID_VENDOR_FROM_DATABASE=Data Display AG + +acpi:DDS*: + ID_VENDOR_FROM_DATABASE=Barco, n.v. + +acpi:DDT*: + ID_VENDOR_FROM_DATABASE=Datadesk Technologies Inc + +acpi:DDV*: + ID_VENDOR_FROM_DATABASE=Delta Information Systems, Inc + +acpi:DEC*: + ID_VENDOR_FROM_DATABASE=Digital Equipment Corporation + +acpi:DEI*: + ID_VENDOR_FROM_DATABASE=Deico Electronics + +acpi:DEL*: + ID_VENDOR_FROM_DATABASE=Dell Inc. + +acpi:DEN*: + ID_VENDOR_FROM_DATABASE=Densitron Computers Ltd + +acpi:DEX*: + ID_VENDOR_FROM_DATABASE=idex displays + +acpi:DFI*: + ID_VENDOR_FROM_DATABASE=DFI + +acpi:DFK*: + ID_VENDOR_FROM_DATABASE=SharkTec A/S + +acpi:DFT*: + ID_VENDOR_FROM_DATABASE=DEI Holdings dba Definitive Technology + +acpi:DGA*: + ID_VENDOR_FROM_DATABASE=Digiital Arts Inc + +acpi:DGC*: + ID_VENDOR_FROM_DATABASE=Data General Corporation + +acpi:DGI*: + ID_VENDOR_FROM_DATABASE=DIGI International + +acpi:DGK*: + ID_VENDOR_FROM_DATABASE=DugoTech Co., LTD + +acpi:DGP*: + ID_VENDOR_FROM_DATABASE=Digicorp European sales S.A. + +acpi:DGS*: + ID_VENDOR_FROM_DATABASE=Diagsoft Inc + +acpi:DGT*: + ID_VENDOR_FROM_DATABASE=The Dearborn Group + +acpi:DHP*: + ID_VENDOR_FROM_DATABASE=DH Print + +acpi:DHQ*: + ID_VENDOR_FROM_DATABASE=Quadram + +acpi:DHT*: + ID_VENDOR_FROM_DATABASE=Projectavision Inc + +acpi:DIA*: + ID_VENDOR_FROM_DATABASE=Diadem + +acpi:DIG*: + ID_VENDOR_FROM_DATABASE=Digicom S.p.A. + +acpi:DII*: + ID_VENDOR_FROM_DATABASE=Dataq Instruments Inc + +acpi:DIM*: + ID_VENDOR_FROM_DATABASE=dPict Imaging, Inc. + +acpi:DIN*: + ID_VENDOR_FROM_DATABASE=Daintelecom Co., Ltd + +acpi:DIS*: + ID_VENDOR_FROM_DATABASE=Diseda S.A. + +acpi:DIT*: + ID_VENDOR_FROM_DATABASE=Dragon Information Technology + +acpi:DJE*: + ID_VENDOR_FROM_DATABASE=Capstone Visual Product Development + +acpi:DJP*: + ID_VENDOR_FROM_DATABASE=Maygay Machines, Ltd + +acpi:DKY*: + ID_VENDOR_FROM_DATABASE=Datakey Inc + +acpi:DLB*: + ID_VENDOR_FROM_DATABASE=Dolby Laboratories Inc. + +acpi:DLC*: + ID_VENDOR_FROM_DATABASE=Diamond Lane Comm. Corporation + +acpi:DLG*: + ID_VENDOR_FROM_DATABASE=Digital-Logic GmbH + +acpi:DLK*: + ID_VENDOR_FROM_DATABASE=D-Link Systems Inc + +acpi:DLL*: + ID_VENDOR_FROM_DATABASE=Dell Inc + +acpi:DLT*: + ID_VENDOR_FROM_DATABASE=Digitelec Informatique Park Cadera + +acpi:DMB*: + ID_VENDOR_FROM_DATABASE=Digicom Systems Inc + +acpi:DMC*: + ID_VENDOR_FROM_DATABASE=Dune Microsystems Corporation + +acpi:DMM*: + ID_VENDOR_FROM_DATABASE=Dimond Multimedia Systems Inc + +acpi:DMP*: + ID_VENDOR_FROM_DATABASE=D&M Holdings Inc, Professional Business Company + +acpi:DMS*: + ID_VENDOR_FROM_DATABASE=DOME imaging systems + +acpi:DMT*: + ID_VENDOR_FROM_DATABASE=Distributed Management Task Force, Inc. (DMTF) + +acpi:DMV*: + ID_VENDOR_FROM_DATABASE=NDS Ltd + +acpi:DNA*: + ID_VENDOR_FROM_DATABASE=DNA Enterprises, Inc. + +acpi:DNG*: + ID_VENDOR_FROM_DATABASE=Apache Micro Peripherals Inc + +acpi:DNI*: + ID_VENDOR_FROM_DATABASE=Deterministic Networks Inc. + +acpi:DNT*: + ID_VENDOR_FROM_DATABASE=Dr. Neuhous Telekommunikation GmbH + +acpi:DNV*: + ID_VENDOR_FROM_DATABASE=DiCon + +acpi:DOL*: + ID_VENDOR_FROM_DATABASE=Dolman Technologies Group Inc + +acpi:DOM*: + ID_VENDOR_FROM_DATABASE=Dome Imaging Systems + +acpi:DON*: + ID_VENDOR_FROM_DATABASE=DENON, Ltd. + +acpi:DOT*: + ID_VENDOR_FROM_DATABASE=Dotronic Mikroelektronik GmbH + +acpi:DPA*: + ID_VENDOR_FROM_DATABASE=DigiTalk Pro AV + +acpi:DPC*: + ID_VENDOR_FROM_DATABASE=Delta Electronics Inc + +acpi:DPI*: + ID_VENDOR_FROM_DATABASE=DocuPoint + +acpi:DPL*: + ID_VENDOR_FROM_DATABASE=Digital Projection Limited + +acpi:DPM*: + ID_VENDOR_FROM_DATABASE=ADPM Synthesis sas + +acpi:DPS*: + ID_VENDOR_FROM_DATABASE=Digital Processing Systems + +acpi:DPT*: + ID_VENDOR_FROM_DATABASE=DPT + +acpi:DPX*: + ID_VENDOR_FROM_DATABASE=DpiX, Inc. + +acpi:DQB*: + ID_VENDOR_FROM_DATABASE=Datacube Inc + +acpi:DRB*: + ID_VENDOR_FROM_DATABASE=Dr. Bott KG + +acpi:DRC*: + ID_VENDOR_FROM_DATABASE=Data Ray Corp. + +acpi:DRD*: + ID_VENDOR_FROM_DATABASE=DIGITAL REFLECTION INC. + +acpi:DRI*: + ID_VENDOR_FROM_DATABASE=Data Race Inc + +acpi:DRS*: + ID_VENDOR_FROM_DATABASE=DRS Defense Solutions, LLC + +acpi:DSD*: + ID_VENDOR_FROM_DATABASE=DS Multimedia Pte Ltd + +acpi:DSI*: + ID_VENDOR_FROM_DATABASE=Digitan Systems Inc + +acpi:DSM*: + ID_VENDOR_FROM_DATABASE=DSM Digital Services GmbH + +acpi:DSP*: + ID_VENDOR_FROM_DATABASE=Domain Technology Inc + +acpi:DTA*: + ID_VENDOR_FROM_DATABASE=DELTATEC + +acpi:DTC*: + ID_VENDOR_FROM_DATABASE=DTC Tech Corporation + +acpi:DTE*: + ID_VENDOR_FROM_DATABASE=Dimension Technologies, Inc. + +acpi:DTI*: + ID_VENDOR_FROM_DATABASE=Diversified Technology, Inc. + +acpi:DTK*: + ID_VENDOR_FROM_DATABASE=Dynax Electronics (HK) Ltd + +acpi:DTL*: + ID_VENDOR_FROM_DATABASE=e-Net Inc + +acpi:DTN*: + ID_VENDOR_FROM_DATABASE=Datang Telephone Co + +acpi:DTO*: + ID_VENDOR_FROM_DATABASE=Deutsche Thomson OHG + +acpi:DTT*: + ID_VENDOR_FROM_DATABASE=Design & Test Technology, Inc. + +acpi:DTX*: + ID_VENDOR_FROM_DATABASE=Data Translation + +acpi:DUA*: + ID_VENDOR_FROM_DATABASE=Dosch & Amand GmbH & Company KG + +acpi:DUN*: + ID_VENDOR_FROM_DATABASE=NCR Corporation + +acpi:DVD*: + ID_VENDOR_FROM_DATABASE=Dictaphone Corporation + +acpi:DVL*: + ID_VENDOR_FROM_DATABASE=Devolo AG + +acpi:DVS*: + ID_VENDOR_FROM_DATABASE=Digital Video System + +acpi:DVT*: + ID_VENDOR_FROM_DATABASE=Data Video + +acpi:DWE*: + ID_VENDOR_FROM_DATABASE=Daewoo Electronics Company Ltd + +acpi:DXC*: + ID_VENDOR_FROM_DATABASE=Digipronix Control Systems + +acpi:DXD*: + ID_VENDOR_FROM_DATABASE=DECIMATOR DESIGN PTY LTD + +acpi:DXL*: + ID_VENDOR_FROM_DATABASE=Dextera Labs Inc + +acpi:DXP*: + ID_VENDOR_FROM_DATABASE=Data Expert Corporation + +acpi:DXS*: + ID_VENDOR_FROM_DATABASE=Signet + +acpi:DYC*: + ID_VENDOR_FROM_DATABASE=Dycam Inc + +acpi:DYM*: + ID_VENDOR_FROM_DATABASE=Dymo-CoStar Corporation + +acpi:DYN*: + ID_VENDOR_FROM_DATABASE=Askey Computer Corporation + +acpi:DYX*: + ID_VENDOR_FROM_DATABASE=Dynax Electronics (HK) Ltd + +acpi:EAS*: + ID_VENDOR_FROM_DATABASE=Evans and Sutherland Computer + +acpi:EBH*: + ID_VENDOR_FROM_DATABASE=Data Price Informatica + +acpi:EBT*: + ID_VENDOR_FROM_DATABASE=HUALONG TECHNOLOGY CO., LTD + +acpi:ECA*: + ID_VENDOR_FROM_DATABASE=Electro Cam Corp. + +acpi:ECC*: + ID_VENDOR_FROM_DATABASE=ESSential Comm. Corporation + +acpi:ECI*: + ID_VENDOR_FROM_DATABASE=Enciris Technologies + +acpi:ECK*: + ID_VENDOR_FROM_DATABASE=Eugene Chukhlomin Sole Proprietorship, d.b.a. + +acpi:ECL*: + ID_VENDOR_FROM_DATABASE=Excel Company Ltd + +acpi:ECM*: + ID_VENDOR_FROM_DATABASE=E-Cmos Tech Corporation + +acpi:ECO*: + ID_VENDOR_FROM_DATABASE=Echo Speech Corporation + +acpi:ECP*: + ID_VENDOR_FROM_DATABASE=Elecom Company Ltd + +acpi:ECS*: + ID_VENDOR_FROM_DATABASE=Elitegroup Computer Systems Company Ltd + +acpi:ECT*: + ID_VENDOR_FROM_DATABASE=Enciris Technologies + +acpi:EDC*: + ID_VENDOR_FROM_DATABASE=e.Digital Corporation + +acpi:EDG*: + ID_VENDOR_FROM_DATABASE=Electronic-Design GmbH + +acpi:EDI*: + ID_VENDOR_FROM_DATABASE=Edimax Tech. Company Ltd + +acpi:EDM*: + ID_VENDOR_FROM_DATABASE=EDMI + +acpi:EDT*: + ID_VENDOR_FROM_DATABASE=Emerging Display Technologies Corp + +acpi:EEE*: + ID_VENDOR_FROM_DATABASE=ET&T Technology Company Ltd + +acpi:EEH*: + ID_VENDOR_FROM_DATABASE=EEH Datalink GmbH + +acpi:EEP*: + ID_VENDOR_FROM_DATABASE=E.E.P.D. GmbH + +acpi:EES*: + ID_VENDOR_FROM_DATABASE=EE Solutions, Inc. + +acpi:EGA*: + ID_VENDOR_FROM_DATABASE=Elgato Systems LLC + +acpi:EGD*: + ID_VENDOR_FROM_DATABASE=EIZO GmbH Display Technologies + +acpi:EGL*: + ID_VENDOR_FROM_DATABASE=Eagle Technology + +acpi:EGN*: + ID_VENDOR_FROM_DATABASE=Egenera, Inc. + +acpi:EGO*: + ID_VENDOR_FROM_DATABASE=Ergo Electronics + +acpi:EHJ*: + ID_VENDOR_FROM_DATABASE=Epson Research + +acpi:EHN*: + ID_VENDOR_FROM_DATABASE=Enhansoft + +acpi:EIC*: + ID_VENDOR_FROM_DATABASE=Eicon Technology Corporation + +acpi:EKA*: + ID_VENDOR_FROM_DATABASE=MagTek Inc. + +acpi:EKC*: + ID_VENDOR_FROM_DATABASE=Eastman Kodak Company + +acpi:EKS*: + ID_VENDOR_FROM_DATABASE=EKSEN YAZILIM + +acpi:ELA*: + ID_VENDOR_FROM_DATABASE=ELAD srl + +acpi:ELC*: + ID_VENDOR_FROM_DATABASE=Electro Scientific Ind + +acpi:ELE*: + ID_VENDOR_FROM_DATABASE=Elecom Company Ltd + +acpi:ELG*: + ID_VENDOR_FROM_DATABASE=Elmeg GmbH Kommunikationstechnik + +acpi:ELI*: + ID_VENDOR_FROM_DATABASE=Edsun Laboratories + +acpi:ELL*: + ID_VENDOR_FROM_DATABASE=Electrosonic Ltd + +acpi:ELM*: + ID_VENDOR_FROM_DATABASE=Elmic Systems Inc + +acpi:ELO*: + ID_VENDOR_FROM_DATABASE=Elo TouchSystems Inc + +acpi:ELS*: + ID_VENDOR_FROM_DATABASE=ELSA GmbH + +acpi:ELT*: + ID_VENDOR_FROM_DATABASE=Element Labs, Inc. + +acpi:ELX*: + ID_VENDOR_FROM_DATABASE=Elonex PLC + +acpi:EMB*: + ID_VENDOR_FROM_DATABASE=Embedded computing inc ltd + +acpi:EMC*: + ID_VENDOR_FROM_DATABASE=eMicro Corporation + +acpi:EME*: + ID_VENDOR_FROM_DATABASE=EMiNE TECHNOLOGY COMPANY, LTD. + +acpi:EMG*: + ID_VENDOR_FROM_DATABASE=EMG Consultants Inc + +acpi:EMI*: + ID_VENDOR_FROM_DATABASE=Ex Machina Inc + +acpi:EMK*: + ID_VENDOR_FROM_DATABASE=Emcore Corporation + +acpi:EMO*: + ID_VENDOR_FROM_DATABASE=ELMO COMPANY, LIMITED + +acpi:EMU*: + ID_VENDOR_FROM_DATABASE=Emulex Corporation + +acpi:ENC*: + ID_VENDOR_FROM_DATABASE=Eizo Nanao Corporation + +acpi:END*: + ID_VENDOR_FROM_DATABASE=ENIDAN Technologies Ltd + +acpi:ENE*: + ID_VENDOR_FROM_DATABASE=ENE Technology Inc. + +acpi:ENI*: + ID_VENDOR_FROM_DATABASE=Efficient Networks + +acpi:ENS*: + ID_VENDOR_FROM_DATABASE=Ensoniq Corporation + +acpi:ENT*: + ID_VENDOR_FROM_DATABASE=Enterprise Comm. & Computing Inc + +acpi:EPC*: + ID_VENDOR_FROM_DATABASE=Empac + +acpi:EPH *: + ID_VENDOR_FROM_DATABASE=Epiphan Systems Inc.  + +acpi:EPI*: + ID_VENDOR_FROM_DATABASE=Envision Peripherals, Inc + +acpi:EPN*: + ID_VENDOR_FROM_DATABASE=EPiCON Inc. + +acpi:EPS*: + ID_VENDOR_FROM_DATABASE=KEPS + +acpi:EQP*: + ID_VENDOR_FROM_DATABASE=Equipe Electronics Ltd. + +acpi:EQX*: + ID_VENDOR_FROM_DATABASE=Equinox Systems Inc + +acpi:ERG*: + ID_VENDOR_FROM_DATABASE=Ergo System + +acpi:ERI*: + ID_VENDOR_FROM_DATABASE=Ericsson Mobile Communications AB + +acpi:ERN*: + ID_VENDOR_FROM_DATABASE=Ericsson, Inc. + +acpi:ERP*: + ID_VENDOR_FROM_DATABASE=Euraplan GmbH + +acpi:ERT*: + ID_VENDOR_FROM_DATABASE=Escort Insturments Corporation + +acpi:ESA*: + ID_VENDOR_FROM_DATABASE=Elbit Systems of America + +acpi:ESC*: + ID_VENDOR_FROM_DATABASE=Eden Sistemas de Computacao S/A + +acpi:ESD*: + ID_VENDOR_FROM_DATABASE=Ensemble Designs, Inc + +acpi:ESG*: + ID_VENDOR_FROM_DATABASE=ELCON Systemtechnik GmbH + +acpi:ESI*: + ID_VENDOR_FROM_DATABASE=Extended Systems, Inc. + +acpi:ESK*: + ID_VENDOR_FROM_DATABASE=ES&S + +acpi:ESL*: + ID_VENDOR_FROM_DATABASE=Esterline Technologies + +acpi:ESN*: + ID_VENDOR_FROM_DATABASE=eSATURNUS + +acpi:ESS*: + ID_VENDOR_FROM_DATABASE=ESS Technology Inc + +acpi:EST*: + ID_VENDOR_FROM_DATABASE=Embedded Solution Technology + +acpi:ESY*: + ID_VENDOR_FROM_DATABASE=E-Systems Inc + +acpi:ETC*: + ID_VENDOR_FROM_DATABASE=Everton Technology Company Ltd + +acpi:ETD*: + ID_VENDOR_FROM_DATABASE=ELAN MICROELECTRONICS CORPORATION + +acpi:ETH*: + ID_VENDOR_FROM_DATABASE=Etherboot Project + +acpi:ETI*: + ID_VENDOR_FROM_DATABASE=Eclipse Tech Inc + +acpi:ETK*: + ID_VENDOR_FROM_DATABASE=eTEK Labs Inc. + +acpi:ETL*: + ID_VENDOR_FROM_DATABASE=Evertz Microsystems Ltd. + +acpi:ETS*: + ID_VENDOR_FROM_DATABASE=Electronic Trade Solutions Ltd + +acpi:ETT*: + ID_VENDOR_FROM_DATABASE=E-Tech Inc + +acpi:EUT*: + ID_VENDOR_FROM_DATABASE=Ericsson Mobile Networks B.V. + +acpi:EVE*: + ID_VENDOR_FROM_DATABASE=Advanced Micro Peripherals Ltd + +acpi:EVI*: + ID_VENDOR_FROM_DATABASE=eviateg GmbH + +acpi:EVX*: + ID_VENDOR_FROM_DATABASE=Everex + +acpi:EXA*: + ID_VENDOR_FROM_DATABASE=Exabyte + +acpi:EXC*: + ID_VENDOR_FROM_DATABASE=Excession Audio + +acpi:EXI*: + ID_VENDOR_FROM_DATABASE=Exide Electronics + +acpi:EXN*: + ID_VENDOR_FROM_DATABASE=RGB Systems, Inc. dba Extron Electronics + +acpi:EXP*: + ID_VENDOR_FROM_DATABASE=Data Export Corporation + +acpi:EXT*: + ID_VENDOR_FROM_DATABASE=Exatech Computadores & Servicos Ltda + +acpi:EXX*: + ID_VENDOR_FROM_DATABASE=Exxact GmbH + +acpi:EXY*: + ID_VENDOR_FROM_DATABASE=Exterity Ltd + +acpi:EYE*: + ID_VENDOR_FROM_DATABASE=eyevis GmbH + +acpi:EZE*: + ID_VENDOR_FROM_DATABASE=EzE Technologies + +acpi:EZP*: + ID_VENDOR_FROM_DATABASE=Storm Technology + +acpi:FAR*: + ID_VENDOR_FROM_DATABASE=Farallon Computing + +acpi:FBI*: + ID_VENDOR_FROM_DATABASE=Interface Corporation + +acpi:FCB*: + ID_VENDOR_FROM_DATABASE=Furukawa Electric Company Ltd + +acpi:FCG*: + ID_VENDOR_FROM_DATABASE=First International Computer Ltd + +acpi:FCS*: + ID_VENDOR_FROM_DATABASE=Focus Enhancements, Inc. + +acpi:FDC*: + ID_VENDOR_FROM_DATABASE=Future Domain + +acpi:FDT*: + ID_VENDOR_FROM_DATABASE=Fujitsu Display Technologies Corp. + +acpi:FEC*: + ID_VENDOR_FROM_DATABASE=FURUNO ELECTRIC CO., LTD. + +acpi:FEL*: + ID_VENDOR_FROM_DATABASE=Fellowes & Questec + +acpi:FEN*: + ID_VENDOR_FROM_DATABASE=Fen Systems Ltd. + +acpi:FER*: + ID_VENDOR_FROM_DATABASE=Ferranti Int'L + +acpi:FFC*: + ID_VENDOR_FROM_DATABASE=FUJIFILM Corporation + +acpi:FFI*: + ID_VENDOR_FROM_DATABASE=Fairfield Industries + +acpi:FGD*: + ID_VENDOR_FROM_DATABASE=Lisa Draexlmaier GmbH + +acpi:FGL*: + ID_VENDOR_FROM_DATABASE=Fujitsu General Limited. + +acpi:FHL*: + ID_VENDOR_FROM_DATABASE=FHLP + +acpi:FIC*: + ID_VENDOR_FROM_DATABASE=Formosa Industrial Computing Inc + +acpi:FIL*: + ID_VENDOR_FROM_DATABASE=Forefront Int'l Ltd + +acpi:FIN*: + ID_VENDOR_FROM_DATABASE=Finecom Co., Ltd. + +acpi:FIR*: + ID_VENDOR_FROM_DATABASE=Chaplet Systems Inc + +acpi:FIS*: + ID_VENDOR_FROM_DATABASE=FLY-IT Simulators + +acpi:FIT*: + ID_VENDOR_FROM_DATABASE=Feature Integration Technology Inc. + +acpi:FJC*: + ID_VENDOR_FROM_DATABASE=Fujitsu Takamisawa Component Limited + +acpi:FJS*: + ID_VENDOR_FROM_DATABASE=Fujitsu Spain + +acpi:FJT*: + ID_VENDOR_FROM_DATABASE=F.J. Tieman BV + +acpi:FLE*: + ID_VENDOR_FROM_DATABASE=ADTI Media, Inc + +acpi:FLI*: + ID_VENDOR_FROM_DATABASE=Faroudja Laboratories + +acpi:FLY*: + ID_VENDOR_FROM_DATABASE=Butterfly Communications + +acpi:FMA*: + ID_VENDOR_FROM_DATABASE=Fast Multimedia AG + +acpi:FMC*: + ID_VENDOR_FROM_DATABASE=Ford Microelectronics Inc + +acpi:FMI*: + ID_VENDOR_FROM_DATABASE=Fujitsu Microelect Inc + +acpi:FML*: + ID_VENDOR_FROM_DATABASE=Fujitsu Microelect Ltd + +acpi:FMZ*: + ID_VENDOR_FROM_DATABASE=Formoza-Altair + +acpi:FNC*: + ID_VENDOR_FROM_DATABASE=Fanuc LTD + +acpi:FNI*: + ID_VENDOR_FROM_DATABASE=Funai Electric Co., Ltd. + +acpi:FOA*: + ID_VENDOR_FROM_DATABASE=FOR-A Company Limited + +acpi:FOS*: + ID_VENDOR_FROM_DATABASE=Foss Tecator + +acpi:FOX*: + ID_VENDOR_FROM_DATABASE=HON HAI PRECISON IND.CO.,LTD. + +acpi:FPE*: + ID_VENDOR_FROM_DATABASE=Fujitsu Peripherals Ltd + +acpi:FPS*: + ID_VENDOR_FROM_DATABASE=Deltec Corporation + +acpi:FPX*: + ID_VENDOR_FROM_DATABASE=Cirel Systemes + +acpi:FRC*: + ID_VENDOR_FROM_DATABASE=Force Computers + +acpi:FRD*: + ID_VENDOR_FROM_DATABASE=Freedom Scientific BLV + +acpi:FRE*: + ID_VENDOR_FROM_DATABASE=Forvus Research Inc + +acpi:FRI*: + ID_VENDOR_FROM_DATABASE=Fibernet Research Inc + +acpi:FRS*: + ID_VENDOR_FROM_DATABASE=South Mountain Technologies, LTD + +acpi:FSC*: + ID_VENDOR_FROM_DATABASE=Future Systems Consulting KK + +acpi:FSI*: + ID_VENDOR_FROM_DATABASE=Fore Systems Inc + +acpi:FST*: + ID_VENDOR_FROM_DATABASE=Modesto PC Inc + +acpi:FTC*: + ID_VENDOR_FROM_DATABASE=Futuretouch Corporation + +acpi:FTE*: + ID_VENDOR_FROM_DATABASE=Frontline Test Equipment Inc. + +acpi:FTG*: + ID_VENDOR_FROM_DATABASE=FTG Data Systems + +acpi:FTI*: + ID_VENDOR_FROM_DATABASE=FastPoint Technologies, Inc. + +acpi:FTL*: + ID_VENDOR_FROM_DATABASE=FUJITSU TEN LIMITED + +acpi:FTN*: + ID_VENDOR_FROM_DATABASE=Fountain Technologies Inc + +acpi:FTR*: + ID_VENDOR_FROM_DATABASE=Mediasonic + +acpi:FTW*: + ID_VENDOR_FROM_DATABASE=MindTribe Product Engineering, Inc. + +acpi:FUJ*: + ID_VENDOR_FROM_DATABASE=Fujitsu Ltd + +acpi:FUN*: + ID_VENDOR_FROM_DATABASE=sisel muhendislik + +acpi:FUS*: + ID_VENDOR_FROM_DATABASE=Fujitsu Siemens Computers GmbH + +acpi:FVC*: + ID_VENDOR_FROM_DATABASE=First Virtual Corporation + +acpi:FVX*: + ID_VENDOR_FROM_DATABASE=C-C-C Group Plc + +acpi:FWA*: + ID_VENDOR_FROM_DATABASE=Attero Tech, LLC + +acpi:FWR*: + ID_VENDOR_FROM_DATABASE=Flat Connections Inc + +acpi:FXX*: + ID_VENDOR_FROM_DATABASE=Fuji Xerox + +acpi:FZC*: + ID_VENDOR_FROM_DATABASE=Founder Group Shenzhen Co. + +acpi:FZI*: + ID_VENDOR_FROM_DATABASE=FZI Forschungszentrum Informatik + +acpi:GAG*: + ID_VENDOR_FROM_DATABASE=Gage Applied Sciences Inc + +acpi:GAL*: + ID_VENDOR_FROM_DATABASE=Galil Motion Control + +acpi:GAU*: + ID_VENDOR_FROM_DATABASE=Gaudi Co., Ltd. + +acpi:GCC*: + ID_VENDOR_FROM_DATABASE=GCC Technologies Inc + +acpi:GCI*: + ID_VENDOR_FROM_DATABASE=Gateway Comm. Inc + +acpi:GCS*: + ID_VENDOR_FROM_DATABASE=Grey Cell Systems Ltd + +acpi:GDC*: + ID_VENDOR_FROM_DATABASE=General Datacom + +acpi:GDI*: + ID_VENDOR_FROM_DATABASE=G. Diehl ISDN GmbH + +acpi:GDS*: + ID_VENDOR_FROM_DATABASE=GDS + +acpi:GDT*: + ID_VENDOR_FROM_DATABASE=Vortex Computersysteme GmbH + +acpi:GEF*: + ID_VENDOR_FROM_DATABASE=GE Fanuc Embedded Systems + +acpi:GEH*: + ID_VENDOR_FROM_DATABASE=GE Intelligent Platforms - Huntsville + +acpi:GEM*: + ID_VENDOR_FROM_DATABASE=Gem Plus + +acpi:GEN*: + ID_VENDOR_FROM_DATABASE=Genesys ATE Inc + +acpi:GEO*: + ID_VENDOR_FROM_DATABASE=GEO Sense + +acpi:GER*: + ID_VENDOR_FROM_DATABASE=GERMANEERS GmbH + +acpi:GES*: + ID_VENDOR_FROM_DATABASE=GES Singapore Pte Ltd + +acpi:GET*: + ID_VENDOR_FROM_DATABASE=Getac Technology Corporation + +acpi:GFM*: + ID_VENDOR_FROM_DATABASE=GFMesstechnik GmbH + +acpi:GFN*: + ID_VENDOR_FROM_DATABASE=Gefen Inc. + +acpi:GGL*: + ID_VENDOR_FROM_DATABASE=Google Inc. + +acpi:GIC*: + ID_VENDOR_FROM_DATABASE=General Inst. Corporation + +acpi:GIM*: + ID_VENDOR_FROM_DATABASE=Guillemont International + +acpi:GIP*: + ID_VENDOR_FROM_DATABASE=GI Provision Ltd + +acpi:GIS*: + ID_VENDOR_FROM_DATABASE=AT&T Global Info Solutions + +acpi:GJN*: + ID_VENDOR_FROM_DATABASE=Grand Junction Networks + +acpi:GLD*: + ID_VENDOR_FROM_DATABASE=Goldmund - Digital Audio SA + +acpi:GLE*: + ID_VENDOR_FROM_DATABASE=AD electronics + +acpi:GLM*: + ID_VENDOR_FROM_DATABASE=Genesys Logic + +acpi:GLS*: + ID_VENDOR_FROM_DATABASE=Gadget Labs LLC + +acpi:GMK*: + ID_VENDOR_FROM_DATABASE=GMK Electronic Design GmbH + +acpi:GML*: + ID_VENDOR_FROM_DATABASE=General Information Systems + +acpi:GMM*: + ID_VENDOR_FROM_DATABASE=GMM Research Inc + +acpi:GMN*: + ID_VENDOR_FROM_DATABASE=GEMINI 2000 Ltd + +acpi:GMX*: + ID_VENDOR_FROM_DATABASE=GMX Inc + +acpi:GND*: + ID_VENDOR_FROM_DATABASE=Gennum Corporation + +acpi:GNN*: + ID_VENDOR_FROM_DATABASE=GN Nettest Inc + +acpi:GNZ*: + ID_VENDOR_FROM_DATABASE=Gunze Ltd + +acpi:GRA*: + ID_VENDOR_FROM_DATABASE=Graphica Computer + +acpi:GRE*: + ID_VENDOR_FROM_DATABASE=GOLD RAIN ENTERPRISES CORP. + +acpi:GRH*: + ID_VENDOR_FROM_DATABASE=Granch Ltd + +acpi:GRM*: + ID_VENDOR_FROM_DATABASE=Garmin International + +acpi:GRV*: + ID_VENDOR_FROM_DATABASE=Advanced Gravis + +acpi:GRY*: + ID_VENDOR_FROM_DATABASE=Robert Gray Company + +acpi:GSB*: + ID_VENDOR_FROM_DATABASE=NIPPONDENCHI CO,.LTD + +acpi:GSC*: + ID_VENDOR_FROM_DATABASE=General Standards Corporation + +acpi:GSM*: + ID_VENDOR_FROM_DATABASE=Goldstar Company Ltd + +acpi:GST*: + ID_VENDOR_FROM_DATABASE=Graphic SystemTechnology + +acpi:GSY*: + ID_VENDOR_FROM_DATABASE=Grossenbacher Systeme AG + +acpi:GTC*: + ID_VENDOR_FROM_DATABASE=Graphtec Corporation + +acpi:GTI*: + ID_VENDOR_FROM_DATABASE=Goldtouch + +acpi:GTK*: + ID_VENDOR_FROM_DATABASE=G-Tech Corporation + +acpi:GTM*: + ID_VENDOR_FROM_DATABASE=Garnet System Company Ltd + +acpi:GTS*: + ID_VENDOR_FROM_DATABASE=Geotest Marvin Test Systems Inc + +acpi:GTT*: + ID_VENDOR_FROM_DATABASE=General Touch Technology Co., Ltd. + +acpi:GUD*: + ID_VENDOR_FROM_DATABASE=Guntermann & Drunck GmbH + +acpi:GUZ*: + ID_VENDOR_FROM_DATABASE=Guzik Technical Enterprises + +acpi:GVC*: + ID_VENDOR_FROM_DATABASE=GVC Corporation + +acpi:GVL*: + ID_VENDOR_FROM_DATABASE=Global Village Communication + +acpi:GWI*: + ID_VENDOR_FROM_DATABASE=GW Instruments + +acpi:GWY*: + ID_VENDOR_FROM_DATABASE=Gateway 2000 + +acpi:GZE*: + ID_VENDOR_FROM_DATABASE=GUNZE Limited + +acpi:HAE*: + ID_VENDOR_FROM_DATABASE=Haider electronics + +acpi:HAI*: + ID_VENDOR_FROM_DATABASE=Haivision Systems Inc. + +acpi:HAL*: + ID_VENDOR_FROM_DATABASE=Halberthal + +acpi:HAN*: + ID_VENDOR_FROM_DATABASE=Hanchang System Corporation + +acpi:HAR*: + ID_VENDOR_FROM_DATABASE=Harris Corporation + +acpi:HAY*: + ID_VENDOR_FROM_DATABASE=Hayes Microcomputer Products Inc + +acpi:HCA*: + ID_VENDOR_FROM_DATABASE=DAT + +acpi:HCE*: + ID_VENDOR_FROM_DATABASE=Hitachi Consumer Electronics Co., Ltd + +acpi:HCL*: + ID_VENDOR_FROM_DATABASE=HCL America Inc + +acpi:HCM*: + ID_VENDOR_FROM_DATABASE=HCL Peripherals + +acpi:HCP*: + ID_VENDOR_FROM_DATABASE=Hitachi Computer Products Inc + +acpi:HCW*: + ID_VENDOR_FROM_DATABASE=Hauppauge Computer Works Inc + +acpi:HDC*: + ID_VENDOR_FROM_DATABASE=HardCom Elektronik & Datateknik + +acpi:HDI*: + ID_VENDOR_FROM_DATABASE=HD-INFO d.o.o. + +acpi:HDV*: + ID_VENDOR_FROM_DATABASE=Holografika kft. + +acpi:HEC*: + ID_VENDOR_FROM_DATABASE=Hisense Electric Co., Ltd. + +acpi:HEL*: + ID_VENDOR_FROM_DATABASE=Hitachi Micro Systems Europe Ltd + +acpi:HER*: + ID_VENDOR_FROM_DATABASE=Ascom Business Systems + +acpi:HET*: + ID_VENDOR_FROM_DATABASE=HETEC Datensysteme GmbH + +acpi:HHC*: + ID_VENDOR_FROM_DATABASE=HIRAKAWA HEWTECH CORP. + +acpi:HHI*: + ID_VENDOR_FROM_DATABASE=Fraunhofer Heinrich-Hertz-Institute + +acpi:HIB*: + ID_VENDOR_FROM_DATABASE=Hibino Corporation + +acpi:HIC*: + ID_VENDOR_FROM_DATABASE=Hitachi Information Technology Co., Ltd. + +acpi:HIK*: + ID_VENDOR_FROM_DATABASE=Hikom Co., Ltd. + +acpi:HIL*: + ID_VENDOR_FROM_DATABASE=Hilevel Technology + +acpi:HIQ*: + ID_VENDOR_FROM_DATABASE=Kaohsiung Opto Electronics Americas, Inc. + +acpi:HIT*: + ID_VENDOR_FROM_DATABASE=Hitachi America Ltd + +acpi:HJI*: + ID_VENDOR_FROM_DATABASE=Harris & Jeffries Inc + +acpi:HKA*: + ID_VENDOR_FROM_DATABASE=HONKO MFG. CO., LTD. + +acpi:HKG*: + ID_VENDOR_FROM_DATABASE=Josef Heim KG + +acpi:HMC*: + ID_VENDOR_FROM_DATABASE=Hualon Microelectric Corporation + +acpi:HMK*: + ID_VENDOR_FROM_DATABASE=hmk Daten-System-Technik BmbH + +acpi:HMX*: + ID_VENDOR_FROM_DATABASE=HUMAX Co., Ltd. + +acpi:HNS*: + ID_VENDOR_FROM_DATABASE=Hughes Network Systems + +acpi:HOB*: + ID_VENDOR_FROM_DATABASE=HOB Electronic GmbH + +acpi:HOE*: + ID_VENDOR_FROM_DATABASE=Hosiden Corporation + +acpi:HOL*: + ID_VENDOR_FROM_DATABASE=Holoeye Photonics AG + +acpi:HON*: + ID_VENDOR_FROM_DATABASE=Sonitronix + +acpi:HPA*: + ID_VENDOR_FROM_DATABASE=Zytor Communications + +acpi:HPC*: + ID_VENDOR_FROM_DATABASE=Hewlett Packard Co. + +acpi:HPD*: + ID_VENDOR_FROM_DATABASE=Hewlett Packard + +acpi:HPI*: + ID_VENDOR_FROM_DATABASE=Headplay, Inc. + +acpi:HPK*: + ID_VENDOR_FROM_DATABASE=HAMAMATSU PHOTONICS K.K. + +acpi:HPQ*: + ID_VENDOR_FROM_DATABASE=HP + +acpi:HPR*: + ID_VENDOR_FROM_DATABASE=H.P.R. Electronics GmbH + +acpi:HRC*: + ID_VENDOR_FROM_DATABASE=Hercules + +acpi:HRE*: + ID_VENDOR_FROM_DATABASE=Qingdao Haier Electronics Co., Ltd. + +acpi:HRI*: + ID_VENDOR_FROM_DATABASE=Hall Research + +acpi:HRL*: + ID_VENDOR_FROM_DATABASE=Herolab GmbH + +acpi:HRS*: + ID_VENDOR_FROM_DATABASE=Harris Semiconductor + +acpi:HRT*: + ID_VENDOR_FROM_DATABASE=HERCULES + +acpi:HSC*: + ID_VENDOR_FROM_DATABASE=Hagiwara Sys-Com Company Ltd + +acpi:HSD*: + ID_VENDOR_FROM_DATABASE=HannStar Display Corp + +acpi:HSM*: + ID_VENDOR_FROM_DATABASE=AT&T Microelectronics + +acpi:HSP*: + ID_VENDOR_FROM_DATABASE=HannStar Display Corp + +acpi:HTC*: + ID_VENDOR_FROM_DATABASE=Hitachi Ltd + +acpi:HTI*: + ID_VENDOR_FROM_DATABASE=Hampshire Company, Inc. + +acpi:HTK*: + ID_VENDOR_FROM_DATABASE=Holtek Microelectronics Inc + +acpi:HTX*: + ID_VENDOR_FROM_DATABASE=Hitex Systementwicklung GmbH + +acpi:HUB*: + ID_VENDOR_FROM_DATABASE=GAI-Tronics, A Hubbell Company + +acpi:HUM*: + ID_VENDOR_FROM_DATABASE=IMP Electronics Ltd. + +acpi:HWA*: + ID_VENDOR_FROM_DATABASE=Harris Canada Inc + +acpi:HWC*: + ID_VENDOR_FROM_DATABASE=DBA Hans Wedemeyer + +acpi:HWD*: + ID_VENDOR_FROM_DATABASE=Highwater Designs Ltd + +acpi:HWP*: + ID_VENDOR_FROM_DATABASE=Hewlett Packard + +acpi:HXM*: + ID_VENDOR_FROM_DATABASE=Hexium Ltd. + +acpi:HYC*: + ID_VENDOR_FROM_DATABASE=Hypercope Gmbh Aachen + +acpi:HYD*: + ID_VENDOR_FROM_DATABASE=Hydis Technologies.Co.,LTD + +acpi:HYO*: + ID_VENDOR_FROM_DATABASE=HYC CO., LTD. + +acpi:HYP*: + ID_VENDOR_FROM_DATABASE=Hyphen Ltd + +acpi:HYR*: + ID_VENDOR_FROM_DATABASE=Hypertec Pty Ltd + +acpi:HYT*: + ID_VENDOR_FROM_DATABASE=Heng Yu Technology (HK) Limited + +acpi:HYV*: + ID_VENDOR_FROM_DATABASE=Hynix Semiconductor + +acpi:IAF*: + ID_VENDOR_FROM_DATABASE=Institut f r angewandte Funksystemtechnik GmbH + +acpi:IAI*: + ID_VENDOR_FROM_DATABASE=Integration Associates, Inc. + +acpi:IAT*: + ID_VENDOR_FROM_DATABASE=IAT Germany GmbH + +acpi:IBC*: + ID_VENDOR_FROM_DATABASE=Integrated Business Systems + +acpi:IBI*: + ID_VENDOR_FROM_DATABASE=INBINE.CO.LTD + +acpi:IBM*: + ID_VENDOR_FROM_DATABASE=IBM + +acpi:IBP*: + ID_VENDOR_FROM_DATABASE=IBP Instruments GmbH + +acpi:IBR*: + ID_VENDOR_FROM_DATABASE=IBR GmbH + +acpi:ICA*: + ID_VENDOR_FROM_DATABASE=ICA Inc + +acpi:ICC*: + ID_VENDOR_FROM_DATABASE=BICC Data Networks Ltd + +acpi:ICD*: + ID_VENDOR_FROM_DATABASE=ICD Inc + +acpi:ICE*: + ID_VENDOR_FROM_DATABASE=IC Ensemble + +acpi:ICI*: + ID_VENDOR_FROM_DATABASE=Infotek Communication Inc + +acpi:ICM*: + ID_VENDOR_FROM_DATABASE=Intracom SA + +acpi:ICN*: + ID_VENDOR_FROM_DATABASE=Sanyo Icon + +acpi:ICO*: + ID_VENDOR_FROM_DATABASE=Intel Corp + +acpi:ICS*: + ID_VENDOR_FROM_DATABASE=Integrated Circuit Systems + +acpi:ICV*: + ID_VENDOR_FROM_DATABASE=Inside Contactless + +acpi:ICX*: + ID_VENDOR_FROM_DATABASE=ICCC A/S + +acpi:IDC*: + ID_VENDOR_FROM_DATABASE=International Datacasting Corporation + +acpi:IDE*: + ID_VENDOR_FROM_DATABASE=IDE Associates + +acpi:IDK*: + ID_VENDOR_FROM_DATABASE=IDK Corporation + +acpi:IDN*: + ID_VENDOR_FROM_DATABASE=Idneo Technologies + +acpi:IDO*: + ID_VENDOR_FROM_DATABASE=IDEO Product Development + +acpi:IDP*: + ID_VENDOR_FROM_DATABASE=Integrated Device Technology, Inc. + +acpi:IDS*: + ID_VENDOR_FROM_DATABASE=Interdigital Sistemas de Informacao + +acpi:IDT*: + ID_VENDOR_FROM_DATABASE=International Display Technology + +acpi:IDX*: + ID_VENDOR_FROM_DATABASE=IDEXX Labs + +acpi:IEC*: + ID_VENDOR_FROM_DATABASE=Interlace Engineering Corporation + +acpi:IEE*: + ID_VENDOR_FROM_DATABASE=IEE + +acpi:IEI*: + ID_VENDOR_FROM_DATABASE=Interlink Electronics + +acpi:IFS*: + ID_VENDOR_FROM_DATABASE=In Focus Systems Inc + +acpi:IFT*: + ID_VENDOR_FROM_DATABASE=Informtech + +acpi:IFX*: + ID_VENDOR_FROM_DATABASE=Infineon Technologies AG + +acpi:IFZ*: + ID_VENDOR_FROM_DATABASE=Infinite Z + +acpi:IGC*: + ID_VENDOR_FROM_DATABASE=Intergate Pty Ltd + +acpi:IGM*: + ID_VENDOR_FROM_DATABASE=IGM Communi + +acpi:IHE*: + ID_VENDOR_FROM_DATABASE=InHand Electronics + +acpi:IIC*: + ID_VENDOR_FROM_DATABASE=ISIC Innoscan Industrial Computers A/S + +acpi:III*: + ID_VENDOR_FROM_DATABASE=Intelligent Instrumentation + +acpi:IIN*: + ID_VENDOR_FROM_DATABASE=IINFRA Co., Ltd + +acpi:IKS*: + ID_VENDOR_FROM_DATABASE=Ikos Systems Inc + +acpi:ILC*: + ID_VENDOR_FROM_DATABASE=Image Logic Corporation + +acpi:ILS*: + ID_VENDOR_FROM_DATABASE=Innotech Corporation + +acpi:IMA*: + ID_VENDOR_FROM_DATABASE=Imagraph + +acpi:IMB*: + ID_VENDOR_FROM_DATABASE=ART s.r.l. + +acpi:IMC*: + ID_VENDOR_FROM_DATABASE=IMC Networks + +acpi:IMD*: + ID_VENDOR_FROM_DATABASE=ImasDe Canarias S.A. + +acpi:IME*: + ID_VENDOR_FROM_DATABASE=Imagraph + +acpi:IMG*: + ID_VENDOR_FROM_DATABASE=IMAGENICS Co., Ltd. + +acpi:IMI*: + ID_VENDOR_FROM_DATABASE=International Microsystems Inc + +acpi:IMM*: + ID_VENDOR_FROM_DATABASE=Immersion Corporation + +acpi:IMN*: + ID_VENDOR_FROM_DATABASE=Impossible Production + +acpi:IMP*: + ID_VENDOR_FROM_DATABASE=Impression Products Incorporated + +acpi:IMT*: + ID_VENDOR_FROM_DATABASE=Inmax Technology Corporation + +acpi:INC*: + ID_VENDOR_FROM_DATABASE=Home Row Inc + +acpi:IND*: + ID_VENDOR_FROM_DATABASE=ILC + +acpi:INE*: + ID_VENDOR_FROM_DATABASE=Inventec Electronics (M) Sdn. Bhd. + +acpi:INF*: + ID_VENDOR_FROM_DATABASE=Inframetrics Inc + +acpi:ING*: + ID_VENDOR_FROM_DATABASE=Integraph Corporation + +acpi:INI*: + ID_VENDOR_FROM_DATABASE=Initio Corporation + +acpi:INK*: + ID_VENDOR_FROM_DATABASE=Indtek Co., Ltd. + +acpi:INL*: + ID_VENDOR_FROM_DATABASE=InnoLux Display Corporation + +acpi:INM*: + ID_VENDOR_FROM_DATABASE=InnoMedia Inc + +acpi:INN*: + ID_VENDOR_FROM_DATABASE=Innovent Systems, Inc. + +acpi:INO*: + ID_VENDOR_FROM_DATABASE=Innolab Pte Ltd + +acpi:INP*: + ID_VENDOR_FROM_DATABASE=Interphase Corporation + +acpi:INS*: + ID_VENDOR_FROM_DATABASE=Ines GmbH + +acpi:INT*: + ID_VENDOR_FROM_DATABASE=Interphase Corporation + +acpi:inu*: + ID_VENDOR_FROM_DATABASE=Inovatec S.p.A. + +acpi:INV*: + ID_VENDOR_FROM_DATABASE=Inviso, Inc. + +acpi:INZ*: + ID_VENDOR_FROM_DATABASE=Best Buy + +acpi:IOA*: + ID_VENDOR_FROM_DATABASE=CRE Technology Corporation + +acpi:IOD*: + ID_VENDOR_FROM_DATABASE=I-O Data Device Inc + +acpi:IOM*: + ID_VENDOR_FROM_DATABASE=Iomega + +acpi:ION*: + ID_VENDOR_FROM_DATABASE=Inside Out Networks + +acpi:IOS*: + ID_VENDOR_FROM_DATABASE=i-O Display System + +acpi:IOT*: + ID_VENDOR_FROM_DATABASE=I/OTech Inc + +acpi:IPC*: + ID_VENDOR_FROM_DATABASE=IPC Corporation + +acpi:IPD*: + ID_VENDOR_FROM_DATABASE=Industrial Products Design, Inc. + +acpi:IPI*: + ID_VENDOR_FROM_DATABASE=Intelligent Platform Management Interface (IPMI) forum (Intel, HP, NEC, Dell) + +acpi:IPM*: + ID_VENDOR_FROM_DATABASE=IPM Industria Politecnica Meridionale SpA + +acpi:IPN*: + ID_VENDOR_FROM_DATABASE=Performance Technologies + +acpi:IPP*: + ID_VENDOR_FROM_DATABASE=IP Power Technologies GmbH + +acpi:IPR*: + ID_VENDOR_FROM_DATABASE=Ithaca Peripherals + +acpi:IPS*: + ID_VENDOR_FROM_DATABASE=IPS, Inc. (Intellectual Property Solutions, Inc.) + +acpi:IPT*: + ID_VENDOR_FROM_DATABASE=International Power Technologies + +acpi:IPW*: + ID_VENDOR_FROM_DATABASE=IPWireless, Inc + +acpi:IQI*: + ID_VENDOR_FROM_DATABASE=IneoQuest Technologies, Inc + +acpi:IQT*: + ID_VENDOR_FROM_DATABASE=IMAGEQUEST Co., Ltd + +acpi:IRD*: + ID_VENDOR_FROM_DATABASE=IRdata + +acpi:ISA*: + ID_VENDOR_FROM_DATABASE=Symbol Technologies + +acpi:ISC*: + ID_VENDOR_FROM_DATABASE=Id3 Semiconductors + +acpi:ISG*: + ID_VENDOR_FROM_DATABASE=Insignia Solutions Inc + +acpi:ISI*: + ID_VENDOR_FROM_DATABASE=Interface Solutions + +acpi:ISL*: + ID_VENDOR_FROM_DATABASE=Isolation Systems + +acpi:ISM*: + ID_VENDOR_FROM_DATABASE=Image Stream Medical + +acpi:ISP*: + ID_VENDOR_FROM_DATABASE=IntreSource Systems Pte Ltd + +acpi:ISR*: + ID_VENDOR_FROM_DATABASE=INSIS Co., LTD. + +acpi:ISS*: + ID_VENDOR_FROM_DATABASE=ISS Inc + +acpi:IST*: + ID_VENDOR_FROM_DATABASE=Intersolve Technologies + +acpi:ISY*: + ID_VENDOR_FROM_DATABASE=International Integrated Systems,Inc.(IISI) + +acpi:ITA*: + ID_VENDOR_FROM_DATABASE=Itausa Export North America + +acpi:ITC*: + ID_VENDOR_FROM_DATABASE=Intercom Inc + +acpi:ITD*: + ID_VENDOR_FROM_DATABASE=Internet Technology Corporation + +acpi:ITE*: + ID_VENDOR_FROM_DATABASE=Integrated Tech Express Inc + +acpi:ITK*: + ID_VENDOR_FROM_DATABASE=ITK Telekommunikation AG + +acpi:ITL*: + ID_VENDOR_FROM_DATABASE=Inter-Tel + +acpi:ITM*: + ID_VENDOR_FROM_DATABASE=ITM inc. + +acpi:ITN*: + ID_VENDOR_FROM_DATABASE=The NTI Group + +acpi:ITP*: + ID_VENDOR_FROM_DATABASE=IT-PRO Consulting und Systemhaus GmbH + +acpi:ITR*: + ID_VENDOR_FROM_DATABASE=Infotronic America, Inc. + +acpi:ITS*: + ID_VENDOR_FROM_DATABASE=IDTECH + +acpi:ITT*: + ID_VENDOR_FROM_DATABASE=I&T Telecom. + +acpi:ITX*: + ID_VENDOR_FROM_DATABASE=integrated Technology Express Inc + +acpi:IUC*: + ID_VENDOR_FROM_DATABASE=ICSL + +acpi:IVI*: + ID_VENDOR_FROM_DATABASE=Intervoice Inc + +acpi:IVM*: + ID_VENDOR_FROM_DATABASE=Iiyama North America + +acpi:IVS*: + ID_VENDOR_FROM_DATABASE=Intevac Photonics Inc. + +acpi:IWR*: + ID_VENDOR_FROM_DATABASE=Icuiti Corporation + +acpi:IWX*: + ID_VENDOR_FROM_DATABASE=Intelliworxx, Inc. + +acpi:IXD*: + ID_VENDOR_FROM_DATABASE=Intertex Data AB + +acpi:JAC*: + ID_VENDOR_FROM_DATABASE=Astec Inc + +acpi:JAE*: + ID_VENDOR_FROM_DATABASE=Japan Aviation Electronics Industry, Limited + +acpi:JAS*: + ID_VENDOR_FROM_DATABASE=Janz Automationssysteme AG + +acpi:JAT*: + ID_VENDOR_FROM_DATABASE=Jaton Corporation + +acpi:JAZ*: + ID_VENDOR_FROM_DATABASE=Carrera Computer Inc + +acpi:JCE*: + ID_VENDOR_FROM_DATABASE=Jace Tech Inc + +acpi:JDL*: + ID_VENDOR_FROM_DATABASE=Japan Digital Laboratory Co.,Ltd. + +acpi:JEN*: + ID_VENDOR_FROM_DATABASE=N-Vision + +acpi:JET*: + ID_VENDOR_FROM_DATABASE=JET POWER TECHNOLOGY CO., LTD. + +acpi:JFX*: + ID_VENDOR_FROM_DATABASE=Jones Futurex Inc + +acpi:JGD*: + ID_VENDOR_FROM_DATABASE=University College + +acpi:JIC*: + ID_VENDOR_FROM_DATABASE=Jaeik Information & Communication Co., Ltd. + +acpi:JKC*: + ID_VENDOR_FROM_DATABASE=JVC KENWOOD Corporation + +acpi:JMT*: + ID_VENDOR_FROM_DATABASE=Micro Technical Company Ltd + +acpi:JPC*: + ID_VENDOR_FROM_DATABASE=JPC Technology Limited + +acpi:JPW*: + ID_VENDOR_FROM_DATABASE=Wallis Hamilton Industries + +acpi:JQE*: + ID_VENDOR_FROM_DATABASE=CNet Technical Inc + +acpi:JSD*: + ID_VENDOR_FROM_DATABASE=JS DigiTech, Inc + +acpi:JSI*: + ID_VENDOR_FROM_DATABASE=Jupiter Systems, Inc. + +acpi:JSK*: + ID_VENDOR_FROM_DATABASE=SANKEN ELECTRIC CO., LTD + +acpi:JTS*: + ID_VENDOR_FROM_DATABASE=JS Motorsports + +acpi:JTY*: + ID_VENDOR_FROM_DATABASE=jetway security micro,inc + +acpi:JUK*: + ID_VENDOR_FROM_DATABASE=Janich & Klass Computertechnik GmbH + +acpi:JUP*: + ID_VENDOR_FROM_DATABASE=Jupiter Systems + +acpi:JVC*: + ID_VENDOR_FROM_DATABASE=JVC + +acpi:JWD*: + ID_VENDOR_FROM_DATABASE=Video International Inc. + +acpi:JWL*: + ID_VENDOR_FROM_DATABASE=Jewell Instruments, LLC + +acpi:JWS*: + ID_VENDOR_FROM_DATABASE=JWSpencer & Co. + +acpi:JWY*: + ID_VENDOR_FROM_DATABASE=Jetway Information Co., Ltd + +acpi:KAR*: + ID_VENDOR_FROM_DATABASE=Karna + +acpi:KBI*: + ID_VENDOR_FROM_DATABASE=Kidboard Inc + +acpi:KBL*: + ID_VENDOR_FROM_DATABASE=Kobil Systems GmbH + +acpi:KCD*: + ID_VENDOR_FROM_DATABASE=Chunichi Denshi Co.,LTD. + +acpi:KCL*: + ID_VENDOR_FROM_DATABASE=Keycorp Ltd + +acpi:KDE*: + ID_VENDOR_FROM_DATABASE=KDE + +acpi:KDK*: + ID_VENDOR_FROM_DATABASE=Kodiak Tech + +acpi:KDM*: + ID_VENDOR_FROM_DATABASE=Korea Data Systems Co., Ltd. + +acpi:KDS*: + ID_VENDOR_FROM_DATABASE=KDS USA + +acpi:KDT*: + ID_VENDOR_FROM_DATABASE=KDDI Technology Corporation + +acpi:KEC*: + ID_VENDOR_FROM_DATABASE=Kyushu Electronics Systems Inc + +acpi:KEM*: + ID_VENDOR_FROM_DATABASE=Kontron Embedded Modules GmbH + +acpi:KES*: + ID_VENDOR_FROM_DATABASE=Kesa Corporation + +acpi:KEY*: + ID_VENDOR_FROM_DATABASE=Key Tech Inc + +acpi:KFC*: + ID_VENDOR_FROM_DATABASE=SCD Tech + +acpi:KFE*: + ID_VENDOR_FROM_DATABASE=Komatsu Forest + +acpi:KFX*: + ID_VENDOR_FROM_DATABASE=Kofax Image Products + +acpi:KGL*: + ID_VENDOR_FROM_DATABASE=KEISOKU GIKEN Co.,Ltd. + +acpi:KIS*: + ID_VENDOR_FROM_DATABASE=KiSS Technology A/S + +acpi:KMC*: + ID_VENDOR_FROM_DATABASE=Mitsumi Company Ltd + +acpi:KME*: + ID_VENDOR_FROM_DATABASE=KIMIN Electronics Co., Ltd. + +acpi:KML*: + ID_VENDOR_FROM_DATABASE=Kensington Microware Ltd + +acpi:KNC*: + ID_VENDOR_FROM_DATABASE=Konica corporation + +acpi:KNX*: + ID_VENDOR_FROM_DATABASE=Nutech Marketing PTL + +acpi:KOB*: + ID_VENDOR_FROM_DATABASE=Kobil Systems GmbH + +acpi:KOD*: + ID_VENDOR_FROM_DATABASE=Eastman Kodak Company + +acpi:KOE*: + ID_VENDOR_FROM_DATABASE=KOLTER ELECTRONIC + +acpi:KOL*: + ID_VENDOR_FROM_DATABASE=Kollmorgen Motion Technologies Group + +acpi:KOU*: + ID_VENDOR_FROM_DATABASE=KOUZIRO Co.,Ltd. + +acpi:KOW*: + ID_VENDOR_FROM_DATABASE=KOWA Company,LTD. + +acpi:KPC*: + ID_VENDOR_FROM_DATABASE=King Phoenix Company + +acpi:KRL*: + ID_VENDOR_FROM_DATABASE=Krell Industries Inc. + +acpi:KRM*: + ID_VENDOR_FROM_DATABASE=Kroma Telecom + +acpi:KRY*: + ID_VENDOR_FROM_DATABASE=Kroy LLC + +acpi:KSC*: + ID_VENDOR_FROM_DATABASE=Kinetic Systems Corporation + +acpi:KSL*: + ID_VENDOR_FROM_DATABASE=Karn Solutions Ltd. + +acpi:KSX*: + ID_VENDOR_FROM_DATABASE=King Tester Corporation + +acpi:KTC*: + ID_VENDOR_FROM_DATABASE=Kingston Tech Corporation + +acpi:KTD*: + ID_VENDOR_FROM_DATABASE=Takahata Electronics Co.,Ltd. + +acpi:KTE*: + ID_VENDOR_FROM_DATABASE=K-Tech + +acpi:KTG*: + ID_VENDOR_FROM_DATABASE=Kayser-Threde GmbH + +acpi:KTI*: + ID_VENDOR_FROM_DATABASE=Konica Technical Inc + +acpi:KTK*: + ID_VENDOR_FROM_DATABASE=Key Tronic Corporation + +acpi:KTN*: + ID_VENDOR_FROM_DATABASE=Katron Tech Inc + +acpi:KUR*: + ID_VENDOR_FROM_DATABASE=Kurta Corporation + +acpi:KVA*: + ID_VENDOR_FROM_DATABASE=Kvaser AB + +acpi:KVX*: + ID_VENDOR_FROM_DATABASE=KeyView + +acpi:KWD*: + ID_VENDOR_FROM_DATABASE=Kenwood Corporation + +acpi:KYC*: + ID_VENDOR_FROM_DATABASE=Kyocera Corporation + +acpi:KYE*: + ID_VENDOR_FROM_DATABASE=KYE Syst Corporation + +acpi:KYK*: + ID_VENDOR_FROM_DATABASE=Samsung Electronics America Inc + +acpi:KZI*: + ID_VENDOR_FROM_DATABASE=K-Zone International co. Ltd. + +acpi:KZN*: + ID_VENDOR_FROM_DATABASE=K-Zone International + +acpi:LAB*: + ID_VENDOR_FROM_DATABASE=ACT Labs Ltd + +acpi:LAC*: + ID_VENDOR_FROM_DATABASE=LaCie + +acpi:LAF*: + ID_VENDOR_FROM_DATABASE=Microline + +acpi:LAG*: + ID_VENDOR_FROM_DATABASE=Laguna Systems + +acpi:LAN*: + ID_VENDOR_FROM_DATABASE=Sodeman Lancom Inc + +acpi:LAS*: + ID_VENDOR_FROM_DATABASE=LASAT Comm. A/S + +acpi:LAV*: + ID_VENDOR_FROM_DATABASE=Lava Computer MFG Inc + +acpi:LBO*: + ID_VENDOR_FROM_DATABASE=Lubosoft + +acpi:LCC*: + ID_VENDOR_FROM_DATABASE=LCI + +acpi:LCD*: + ID_VENDOR_FROM_DATABASE=Toshiba Matsushita Display Technology Co., Ltd + +acpi:LCE*: + ID_VENDOR_FROM_DATABASE=La Commande Electronique + +acpi:LCI*: + ID_VENDOR_FROM_DATABASE=Lite-On Communication Inc + +acpi:LCM*: + ID_VENDOR_FROM_DATABASE=Latitude Comm. + +acpi:LCN*: + ID_VENDOR_FROM_DATABASE=LEXICON + +acpi:LCS*: + ID_VENDOR_FROM_DATABASE=Longshine Electronics Company + +acpi:LCT*: + ID_VENDOR_FROM_DATABASE=Labcal Technologies + +acpi:LDT*: + ID_VENDOR_FROM_DATABASE=LogiDataTech Electronic GmbH + +acpi:LEC*: + ID_VENDOR_FROM_DATABASE=Lectron Company Ltd + +acpi:LED*: + ID_VENDOR_FROM_DATABASE=Long Engineering Design Inc + +acpi:LEG*: + ID_VENDOR_FROM_DATABASE=Legerity, Inc + +acpi:LEN*: + ID_VENDOR_FROM_DATABASE=Lenovo Group Limited + +acpi:LEO*: + ID_VENDOR_FROM_DATABASE=First International Computer Inc + +acpi:LEX*: + ID_VENDOR_FROM_DATABASE=Lexical Ltd + +acpi:LGC*: + ID_VENDOR_FROM_DATABASE=Logic Ltd + +acpi:LGI*: + ID_VENDOR_FROM_DATABASE=Logitech Inc + +acpi:LGS*: + ID_VENDOR_FROM_DATABASE=LG Semicom Company Ltd + +acpi:LGX*: + ID_VENDOR_FROM_DATABASE=Lasergraphics, Inc. + +acpi:LHA*: + ID_VENDOR_FROM_DATABASE=Lars Haagh ApS + +acpi:LHE*: + ID_VENDOR_FROM_DATABASE=Lung Hwa Electronics Company Ltd + +acpi:LHT*: + ID_VENDOR_FROM_DATABASE=Lighthouse Technologies Limited + +acpi:LIN*: + ID_VENDOR_FROM_DATABASE=Lenovo Beijing Co. Ltd. + +acpi:LIP*: + ID_VENDOR_FROM_DATABASE=Linked IP GmbH + +acpi:LIT*: + ID_VENDOR_FROM_DATABASE=Lithics Silicon Technology + +acpi:LJX*: + ID_VENDOR_FROM_DATABASE=Datalogic Corporation + +acpi:LKM*: + ID_VENDOR_FROM_DATABASE=Likom Technology Sdn. Bhd. + +acpi:LLL*: + ID_VENDOR_FROM_DATABASE=L-3 Communications + +acpi:LMG*: + ID_VENDOR_FROM_DATABASE=Lucent Technologies + +acpi:LMI*: + ID_VENDOR_FROM_DATABASE=Lexmark Int'l Inc + +acpi:LMP*: + ID_VENDOR_FROM_DATABASE=Leda Media Products + +acpi:LMT*: + ID_VENDOR_FROM_DATABASE=Laser Master + +acpi:LND*: + ID_VENDOR_FROM_DATABASE=Land Computer Company Ltd + +acpi:LNK*: + ID_VENDOR_FROM_DATABASE=Link Tech Inc + +acpi:LNR*: + ID_VENDOR_FROM_DATABASE=Linear Systems Ltd. + +acpi:LNT*: + ID_VENDOR_FROM_DATABASE=LANETCO International + +acpi:LNV*: + ID_VENDOR_FROM_DATABASE=Lenovo + +acpi:LOC*: + ID_VENDOR_FROM_DATABASE=Locamation B.V. + +acpi:LOE*: + ID_VENDOR_FROM_DATABASE=Loewe Opta GmbH + +acpi:LOG*: + ID_VENDOR_FROM_DATABASE=Logicode Technology Inc + +acpi:LOL*: + ID_VENDOR_FROM_DATABASE=Litelogic Operations Ltd + +acpi:LPE*: + ID_VENDOR_FROM_DATABASE=El-PUSK Co., Ltd. + +acpi:LPI*: + ID_VENDOR_FROM_DATABASE=Design Technology + +acpi:LSC*: + ID_VENDOR_FROM_DATABASE=LifeSize Communications + +acpi:LSD*: + ID_VENDOR_FROM_DATABASE=Intersil Corporation + +acpi:LSI*: + ID_VENDOR_FROM_DATABASE=Loughborough Sound Images + +acpi:LSJ*: + ID_VENDOR_FROM_DATABASE=LSI Japan Company Ltd + +acpi:LSL*: + ID_VENDOR_FROM_DATABASE=Logical Solutions + +acpi:LSY*: + ID_VENDOR_FROM_DATABASE=LSI Systems Inc + +acpi:LTC*: + ID_VENDOR_FROM_DATABASE=Labtec Inc + +acpi:LTI*: + ID_VENDOR_FROM_DATABASE=Jongshine Tech Inc + +acpi:LTK*: + ID_VENDOR_FROM_DATABASE=Lucidity Technology Company Ltd + +acpi:LTN*: + ID_VENDOR_FROM_DATABASE=Litronic Inc + +acpi:LTS*: + ID_VENDOR_FROM_DATABASE=LTS Scale LLC + +acpi:LTV*: + ID_VENDOR_FROM_DATABASE=Leitch Technology International Inc. + +acpi:LTW*: + ID_VENDOR_FROM_DATABASE=Lightware, Inc + +acpi:LUC*: + ID_VENDOR_FROM_DATABASE=Lucent Technologies + +acpi:LUM*: + ID_VENDOR_FROM_DATABASE=Lumagen, Inc. + +acpi:LUX*: + ID_VENDOR_FROM_DATABASE=Luxxell Research Inc + +acpi:LVI*: + ID_VENDOR_FROM_DATABASE=LVI Low Vision International AB + +acpi:LWC*: + ID_VENDOR_FROM_DATABASE=Labway Corporation + +acpi:LWR*: + ID_VENDOR_FROM_DATABASE=Lightware Visual Engineering + +acpi:LWW*: + ID_VENDOR_FROM_DATABASE=Lanier Worldwide + +acpi:LXC*: + ID_VENDOR_FROM_DATABASE=LXCO Technologies AG + +acpi:LXN*: + ID_VENDOR_FROM_DATABASE=Luxeon + +acpi:LXS*: + ID_VENDOR_FROM_DATABASE=ELEA CardWare + +acpi:LZX*: + ID_VENDOR_FROM_DATABASE=Lightwell Company Ltd + +acpi:MAC*: + ID_VENDOR_FROM_DATABASE=MAC System Company Ltd + +acpi:MAD*: + ID_VENDOR_FROM_DATABASE=Xedia Corporation + +acpi:MAE*: + ID_VENDOR_FROM_DATABASE=Maestro Pty Ltd + +acpi:MAG*: + ID_VENDOR_FROM_DATABASE=MAG InnoVision + +acpi:MAI*: + ID_VENDOR_FROM_DATABASE=Mutoh America Inc + +acpi:MAL*: + ID_VENDOR_FROM_DATABASE=Meridian Audio Ltd + +acpi:MAN*: + ID_VENDOR_FROM_DATABASE=LGIC + +acpi:MAS*: + ID_VENDOR_FROM_DATABASE=Mass Inc. + +acpi:MAT*: + ID_VENDOR_FROM_DATABASE=Matsushita Electric Ind. Company Ltd + +acpi:MAX*: + ID_VENDOR_FROM_DATABASE=Rogen Tech Distribution Inc + +acpi:MAY*: + ID_VENDOR_FROM_DATABASE=Maynard Electronics + +acpi:MAZ*: + ID_VENDOR_FROM_DATABASE=MAZeT GmbH + +acpi:MBC*: + ID_VENDOR_FROM_DATABASE=MBC + +acpi:MBD*: + ID_VENDOR_FROM_DATABASE=Microbus PLC + +acpi:MBM*: + ID_VENDOR_FROM_DATABASE=Marshall Electronics + +acpi:MBV*: + ID_VENDOR_FROM_DATABASE=Moreton Bay + +acpi:MCA*: + ID_VENDOR_FROM_DATABASE=American Nuclear Systems Inc + +acpi:MCC*: + ID_VENDOR_FROM_DATABASE=Micro Industries + +acpi:MCD*: + ID_VENDOR_FROM_DATABASE=McDATA Corporation + +acpi:MCE*: + ID_VENDOR_FROM_DATABASE=Metz-Werke GmbH & Co KG + +acpi:MCG*: + ID_VENDOR_FROM_DATABASE=Motorola Computer Group + +acpi:MCI*: + ID_VENDOR_FROM_DATABASE=Micronics Computers + +acpi:MCL*: + ID_VENDOR_FROM_DATABASE=Motorola Communications Israel + +acpi:MCM*: + ID_VENDOR_FROM_DATABASE=Metricom Inc + +acpi:MCN*: + ID_VENDOR_FROM_DATABASE=Micron Electronics Inc + +acpi:MCO*: + ID_VENDOR_FROM_DATABASE=Motion Computing Inc. + +acpi:MCP*: + ID_VENDOR_FROM_DATABASE=Magni Systems Inc + +acpi:MCQ*: + ID_VENDOR_FROM_DATABASE=Mat's Computers + +acpi:MCR*: + ID_VENDOR_FROM_DATABASE=Marina Communicaitons + +acpi:MCS*: + ID_VENDOR_FROM_DATABASE=Micro Computer Systems + +acpi:MCT*: + ID_VENDOR_FROM_DATABASE=Microtec + +acpi:MDA*: + ID_VENDOR_FROM_DATABASE=Media4 Inc + +acpi:MDC*: + ID_VENDOR_FROM_DATABASE=Midori Electronics + +acpi:MDD*: + ID_VENDOR_FROM_DATABASE=MODIS + +acpi:MDG*: + ID_VENDOR_FROM_DATABASE=Madge Networks + +acpi:MDI*: + ID_VENDOR_FROM_DATABASE=Micro Design Inc + +acpi:MDK*: + ID_VENDOR_FROM_DATABASE=Mediatek Corporation + +acpi:MDO*: + ID_VENDOR_FROM_DATABASE=Panasonic + +acpi:MDR*: + ID_VENDOR_FROM_DATABASE=Medar Inc + +acpi:MDS*: + ID_VENDOR_FROM_DATABASE=Micro Display Systems Inc + +acpi:MDT*: + ID_VENDOR_FROM_DATABASE=Magus Data Tech + +acpi:MDV*: + ID_VENDOR_FROM_DATABASE=MET Development Inc + +acpi:MDX*: + ID_VENDOR_FROM_DATABASE=MicroDatec GmbH + +acpi:MDY*: + ID_VENDOR_FROM_DATABASE=Microdyne Inc + +acpi:MEC*: + ID_VENDOR_FROM_DATABASE=Mega System Technologies Inc + +acpi:MED*: + ID_VENDOR_FROM_DATABASE=Messeltronik Dresden GmbH + +acpi:MEE*: + ID_VENDOR_FROM_DATABASE=Mitsubishi Electric Engineering Co., Ltd. + +acpi:MEG*: + ID_VENDOR_FROM_DATABASE=Abeam Tech Ltd + +acpi:MEI*: + ID_VENDOR_FROM_DATABASE=Panasonic Industry Company + +acpi:MEJ*: + ID_VENDOR_FROM_DATABASE=Mac-Eight Co., LTD. + +acpi:MEL*: + ID_VENDOR_FROM_DATABASE=Mitsubishi Electric Corporation + +acpi:MEN*: + ID_VENDOR_FROM_DATABASE=MEN Mikroelectronik Nueruberg GmbH + +acpi:MEQ*: + ID_VENDOR_FROM_DATABASE=Matelect Ltd. + +acpi:MET*: + ID_VENDOR_FROM_DATABASE=Metheus Corporation + +acpi:MEX*: + ID_VENDOR_FROM_DATABASE=MSC Vertriebs GmbH + +acpi:MFG*: + ID_VENDOR_FROM_DATABASE=MicroField Graphics Inc + +acpi:MFI*: + ID_VENDOR_FROM_DATABASE=Micro Firmware + +acpi:MFR*: + ID_VENDOR_FROM_DATABASE=MediaFire Corp. + +acpi:MGA*: + ID_VENDOR_FROM_DATABASE=Mega System Technologies, Inc. + +acpi:MGC*: + ID_VENDOR_FROM_DATABASE=Mentor Graphics Corporation + +acpi:MGE*: + ID_VENDOR_FROM_DATABASE=Schneider Electric S.A. + +acpi:MGL*: + ID_VENDOR_FROM_DATABASE=M-G Technology Ltd + +acpi:MGT*: + ID_VENDOR_FROM_DATABASE=Megatech R & D Company + +acpi:MIC*: + ID_VENDOR_FROM_DATABASE=Micom Communications Inc + +acpi:MID*: + ID_VENDOR_FROM_DATABASE=miro Displays + +acpi:MII*: + ID_VENDOR_FROM_DATABASE=Mitec Inc + +acpi:MIL*: + ID_VENDOR_FROM_DATABASE=Marconi Instruments Ltd + +acpi:MIM*: + ID_VENDOR_FROM_DATABASE=Mimio – A Newell Rubbermaid Company + +acpi:MIN*: + ID_VENDOR_FROM_DATABASE=Minicom Digital Signage + +acpi:MIP*: + ID_VENDOR_FROM_DATABASE=micronpc.com + +acpi:MIR*: + ID_VENDOR_FROM_DATABASE=Miro Computer Prod. + +acpi:MIS*: + ID_VENDOR_FROM_DATABASE=Modular Industrial Solutions Inc + +acpi:MIT*: + ID_VENDOR_FROM_DATABASE=MCM Industrial Technology GmbH + +acpi:MJI*: + ID_VENDOR_FROM_DATABASE=MARANTZ JAPAN, INC. + +acpi:MJS*: + ID_VENDOR_FROM_DATABASE=MJS Designs + +acpi:MKC*: + ID_VENDOR_FROM_DATABASE=Media Tek Inc. + +acpi:MKT*: + ID_VENDOR_FROM_DATABASE=MICROTEK Inc. + +acpi:MKV*: + ID_VENDOR_FROM_DATABASE=Trtheim Technology + +acpi:MLD*: + ID_VENDOR_FROM_DATABASE=Deep Video Imaging Ltd + +acpi:MLG*: + ID_VENDOR_FROM_DATABASE=Micrologica AG + +acpi:MLI*: + ID_VENDOR_FROM_DATABASE=McIntosh Laboratory Inc. + +acpi:MLM*: + ID_VENDOR_FROM_DATABASE=Millennium Engineering Inc + +acpi:MLN*: + ID_VENDOR_FROM_DATABASE=Mark Levinson + +acpi:MLS*: + ID_VENDOR_FROM_DATABASE=Milestone EPE + +acpi:MLX*: + ID_VENDOR_FROM_DATABASE=Mylex Corporation + +acpi:MMA*: + ID_VENDOR_FROM_DATABASE=Micromedia AG + +acpi:MMD*: + ID_VENDOR_FROM_DATABASE=Micromed Biotecnologia Ltd + +acpi:MMF*: + ID_VENDOR_FROM_DATABASE=Minnesota Mining and Manufacturing + +acpi:MMI*: + ID_VENDOR_FROM_DATABASE=Multimax + +acpi:MMM*: + ID_VENDOR_FROM_DATABASE=Electronic Measurements + +acpi:MMN*: + ID_VENDOR_FROM_DATABASE=MiniMan Inc + +acpi:MMS*: + ID_VENDOR_FROM_DATABASE=MMS Electronics + +acpi:MNC*: + ID_VENDOR_FROM_DATABASE=Mini Micro Methods Ltd + +acpi:MNL*: + ID_VENDOR_FROM_DATABASE=Monorail Inc + +acpi:MNP*: + ID_VENDOR_FROM_DATABASE=Microcom + +acpi:MOD*: + ID_VENDOR_FROM_DATABASE=Modular Technology + +acpi:MOM*: + ID_VENDOR_FROM_DATABASE=Momentum Data Systems + +acpi:MOS*: + ID_VENDOR_FROM_DATABASE=Moses Corporation + +acpi:MOT*: + ID_VENDOR_FROM_DATABASE=Motorola UDS + +acpi:MPC*: + ID_VENDOR_FROM_DATABASE=M-Pact Inc + +acpi:MPI*: + ID_VENDOR_FROM_DATABASE=Mediatrix Peripherals Inc + +acpi:MPJ*: + ID_VENDOR_FROM_DATABASE=Microlab + +acpi:MPL*: + ID_VENDOR_FROM_DATABASE=Maple Research Inst. Company Ltd + +acpi:MPN*: + ID_VENDOR_FROM_DATABASE=Mainpine Limited + +acpi:MPS*: + ID_VENDOR_FROM_DATABASE=mps Software GmbH + +acpi:MPX*: + ID_VENDOR_FROM_DATABASE=Micropix Technologies, Ltd. + +acpi:MQP*: + ID_VENDOR_FROM_DATABASE=MultiQ Products AB + +acpi:MRA*: + ID_VENDOR_FROM_DATABASE=Miranda Technologies Inc + +acpi:MRC*: + ID_VENDOR_FROM_DATABASE=Marconi Simulation & Ty-Coch Way Training + +acpi:MRD*: + ID_VENDOR_FROM_DATABASE=MicroDisplay Corporation + +acpi:MRK*: + ID_VENDOR_FROM_DATABASE=Maruko & Company Ltd + +acpi:MRL*: + ID_VENDOR_FROM_DATABASE=Miratel + +acpi:MRO*: + ID_VENDOR_FROM_DATABASE=Medikro Oy + +acpi:MRT*: + ID_VENDOR_FROM_DATABASE=Merging Technologies + +acpi:MSA*: + ID_VENDOR_FROM_DATABASE=Micro Systemation AB + +acpi:MSC*: + ID_VENDOR_FROM_DATABASE=Mouse Systems Corporation + +acpi:MSD*: + ID_VENDOR_FROM_DATABASE=Datenerfassungs- und Informationssysteme + +acpi:MSF*: + ID_VENDOR_FROM_DATABASE=M-Systems Flash Disk Pioneers + +acpi:MSG*: + ID_VENDOR_FROM_DATABASE=MSI GmbH + +acpi:MSH*: + ID_VENDOR_FROM_DATABASE=Microsoft + +acpi:MSI*: + ID_VENDOR_FROM_DATABASE=Microstep + +acpi:MSK*: + ID_VENDOR_FROM_DATABASE=Megasoft Inc + +acpi:MSL*: + ID_VENDOR_FROM_DATABASE=MicroSlate Inc. + +acpi:MSM*: + ID_VENDOR_FROM_DATABASE=Advanced Digital Systems + +acpi:MSP*: + ID_VENDOR_FROM_DATABASE=Mistral Solutions [P] Ltd. + +acpi:MST*: + ID_VENDOR_FROM_DATABASE=MS Telematica + +acpi:MSU*: + ID_VENDOR_FROM_DATABASE=motorola + +acpi:MSV*: + ID_VENDOR_FROM_DATABASE=Mosgi Corporation + +acpi:MSX*: + ID_VENDOR_FROM_DATABASE=Micomsoft Co., Ltd. + +acpi:MSY*: + ID_VENDOR_FROM_DATABASE=MicroTouch Systems Inc + +acpi:MTB*: + ID_VENDOR_FROM_DATABASE=Media Technologies Ltd. + +acpi:MTC*: + ID_VENDOR_FROM_DATABASE=Mars-Tech Corporation + +acpi:MTD*: + ID_VENDOR_FROM_DATABASE=MindTech Display Co. Ltd + +acpi:MTE*: + ID_VENDOR_FROM_DATABASE=MediaTec GmbH + +acpi:MTH*: + ID_VENDOR_FROM_DATABASE=Micro-Tech Hearing Instruments + +acpi:MTI*: + ID_VENDOR_FROM_DATABASE=MaxCom Technical Inc + +acpi:MTK*: + ID_VENDOR_FROM_DATABASE=Microtek International Inc. + +acpi:MTL*: + ID_VENDOR_FROM_DATABASE=Mitel Corporation + +acpi:MTM*: + ID_VENDOR_FROM_DATABASE=Motium + +acpi:MTN*: + ID_VENDOR_FROM_DATABASE=Mtron Storage Technology Co., Ltd. + +acpi:MTR*: + ID_VENDOR_FROM_DATABASE=Mitron computer Inc + +acpi:MTS*: + ID_VENDOR_FROM_DATABASE=Multi-Tech Systems + +acpi:MTU*: + ID_VENDOR_FROM_DATABASE=Mark of the Unicorn Inc + +acpi:MTX*: + ID_VENDOR_FROM_DATABASE=Matrox + +acpi:MUD*: + ID_VENDOR_FROM_DATABASE=Multi-Dimension Institute + +acpi:MUK*: + ID_VENDOR_FROM_DATABASE=mainpine limited + +acpi:MVD*: + ID_VENDOR_FROM_DATABASE=Microvitec PLC + +acpi:MVI*: + ID_VENDOR_FROM_DATABASE=Media Vision Inc + +acpi:MVM*: + ID_VENDOR_FROM_DATABASE=SOBO VISION + +acpi:MVS*: + ID_VENDOR_FROM_DATABASE=Microvision + +acpi:MVX*: + ID_VENDOR_FROM_DATABASE=COM 1 + +acpi:MWI*: + ID_VENDOR_FROM_DATABASE=Multiwave Innovation Pte Ltd + +acpi:MWR*: + ID_VENDOR_FROM_DATABASE=mware + +acpi:MWY*: + ID_VENDOR_FROM_DATABASE=Microway Inc + +acpi:MXD*: + ID_VENDOR_FROM_DATABASE=MaxData Computer GmbH & Co.KG + +acpi:MXI*: + ID_VENDOR_FROM_DATABASE=Macronix Inc + +acpi:MXL*: + ID_VENDOR_FROM_DATABASE=Hitachi Maxell, Ltd. + +acpi:MXP*: + ID_VENDOR_FROM_DATABASE=Maxpeed Corporation + +acpi:MXT*: + ID_VENDOR_FROM_DATABASE=Maxtech Corporation + +acpi:MXV*: + ID_VENDOR_FROM_DATABASE=MaxVision Corporation + +acpi:MYA*: + ID_VENDOR_FROM_DATABASE=Monydata + +acpi:MYR*: + ID_VENDOR_FROM_DATABASE=Myriad Solutions Ltd + +acpi:MYX*: + ID_VENDOR_FROM_DATABASE=Micronyx Inc + +acpi:NAC*: + ID_VENDOR_FROM_DATABASE=Ncast Corporation + +acpi:NAD*: + ID_VENDOR_FROM_DATABASE=NAD Electronics + +acpi:NAK*: + ID_VENDOR_FROM_DATABASE=Nakano Engineering Co.,Ltd. + +acpi:NAL*: + ID_VENDOR_FROM_DATABASE=Network Alchemy + +acpi:NAT*: + ID_VENDOR_FROM_DATABASE=NaturalPoint Inc. + +acpi:NAV*: + ID_VENDOR_FROM_DATABASE=Navigation Corporation + +acpi:NAX*: + ID_VENDOR_FROM_DATABASE=Naxos Tecnologia + +acpi:NBL*: + ID_VENDOR_FROM_DATABASE=N*Able Technologies Inc + +acpi:NBS*: + ID_VENDOR_FROM_DATABASE=National Key Lab. on ISN + +acpi:NBT*: + ID_VENDOR_FROM_DATABASE=NingBo Bestwinning Technology CO., Ltd + +acpi:NCA*: + ID_VENDOR_FROM_DATABASE=Nixdorf Company + +acpi:NCC*: + ID_VENDOR_FROM_DATABASE=NCR Corporation + +acpi:NCE*: + ID_VENDOR_FROM_DATABASE=Norcent Technology, Inc. + +acpi:NCI*: + ID_VENDOR_FROM_DATABASE=NewCom Inc + +acpi:NCL*: + ID_VENDOR_FROM_DATABASE=NetComm Ltd + +acpi:NCR*: + ID_VENDOR_FROM_DATABASE=NCR Electronics + +acpi:NCS*: + ID_VENDOR_FROM_DATABASE=Northgate Computer Systems + +acpi:NCT*: + ID_VENDOR_FROM_DATABASE=NEC CustomTechnica, Ltd. + +acpi:NDC*: + ID_VENDOR_FROM_DATABASE=National DataComm Corporaiton + +acpi:NDI*: + ID_VENDOR_FROM_DATABASE=National Display Systems + +acpi:NDK*: + ID_VENDOR_FROM_DATABASE=Naitoh Densei CO., LTD. + +acpi:NDL*: + ID_VENDOR_FROM_DATABASE=Network Designers + +acpi:NDS*: + ID_VENDOR_FROM_DATABASE=Nokia Data + +acpi:NEC*: + ID_VENDOR_FROM_DATABASE=NEC Corporation + +acpi:NEO*: + ID_VENDOR_FROM_DATABASE=NEO TELECOM CO.,LTD. + +acpi:NET*: + ID_VENDOR_FROM_DATABASE=Mettler Toledo + +acpi:NEU*: + ID_VENDOR_FROM_DATABASE=NEUROTEC - EMPRESA DE PESQUISA E DESENVOLVIMENTO EM BIOMEDICINA + +acpi:NEX*: + ID_VENDOR_FROM_DATABASE=Nexgen Mediatech Inc., + +acpi:NFC*: + ID_VENDOR_FROM_DATABASE=BTC Korea Co., Ltd + +acpi:NFS*: + ID_VENDOR_FROM_DATABASE=Number Five Software + +acpi:NGC*: + ID_VENDOR_FROM_DATABASE=Network General + +acpi:NGS*: + ID_VENDOR_FROM_DATABASE=A D S Exports + +acpi:NHT*: + ID_VENDOR_FROM_DATABASE=Vinci Labs + +acpi:NIC*: + ID_VENDOR_FROM_DATABASE=National Instruments Corporation + +acpi:NIS*: + ID_VENDOR_FROM_DATABASE=Nissei Electric Company + +acpi:NIT*: + ID_VENDOR_FROM_DATABASE=Network Info Technology + +acpi:NIX*: + ID_VENDOR_FROM_DATABASE=Seanix Technology Inc + +acpi:NLC*: + ID_VENDOR_FROM_DATABASE=Next Level Communications + +acpi:NMP*: + ID_VENDOR_FROM_DATABASE=Nokia Mobile Phones + +acpi:NMS*: + ID_VENDOR_FROM_DATABASE=Natural Micro System + +acpi:NMV*: + ID_VENDOR_FROM_DATABASE=NEC-Mitsubishi Electric Visual Systems Corporation + +acpi:NMX*: + ID_VENDOR_FROM_DATABASE=Neomagic + +acpi:NNC*: + ID_VENDOR_FROM_DATABASE=NNC + +acpi:NOE*: + ID_VENDOR_FROM_DATABASE=NordicEye AB + +acpi:NOI*: + ID_VENDOR_FROM_DATABASE=North Invent A/S + +acpi:NOK*: + ID_VENDOR_FROM_DATABASE=Nokia Display Products + +acpi:NOR*: + ID_VENDOR_FROM_DATABASE=Norand Corporation + +acpi:NOT*: + ID_VENDOR_FROM_DATABASE=Not Limited Inc + +acpi:NPI*: + ID_VENDOR_FROM_DATABASE=Network Peripherals Inc + +acpi:NRL*: + ID_VENDOR_FROM_DATABASE=U.S. Naval Research Lab + +acpi:NRT*: + ID_VENDOR_FROM_DATABASE=Beijing Northern Radiantelecom Co. + +acpi:NRV*: + ID_VENDOR_FROM_DATABASE=Taugagreining hf + +acpi:NSC*: + ID_VENDOR_FROM_DATABASE=National Semiconductor Corporation + +acpi:NSI*: + ID_VENDOR_FROM_DATABASE=NISSEI ELECTRIC CO.,LTD + +acpi:NSP*: + ID_VENDOR_FROM_DATABASE=Nspire System Inc. + +acpi:NSS*: + ID_VENDOR_FROM_DATABASE=Newport Systems Solutions + +acpi:NST*: + ID_VENDOR_FROM_DATABASE=Network Security Technology Co + +acpi:NTC*: + ID_VENDOR_FROM_DATABASE=NeoTech S.R.L + +acpi:NTI*: + ID_VENDOR_FROM_DATABASE=New Tech Int'l Company + +acpi:NTL*: + ID_VENDOR_FROM_DATABASE=National Transcomm. Ltd + +acpi:NTN*: + ID_VENDOR_FROM_DATABASE=Nuvoton Technology Corporation + +acpi:NTR*: + ID_VENDOR_FROM_DATABASE=N-trig Innovative Technologies, Inc. + +acpi:NTS*: + ID_VENDOR_FROM_DATABASE=Nits Technology Inc. + +acpi:NTT*: + ID_VENDOR_FROM_DATABASE=NTT Advanced Technology Corporation + +acpi:NTW*: + ID_VENDOR_FROM_DATABASE=Networth Inc + +acpi:NTX*: + ID_VENDOR_FROM_DATABASE=Netaccess Inc + +acpi:NUG*: + ID_VENDOR_FROM_DATABASE=NU Technology, Inc. + +acpi:NUI*: + ID_VENDOR_FROM_DATABASE=NU Inc. + +acpi:NVC*: + ID_VENDOR_FROM_DATABASE=NetVision Corporation + +acpi:NVD*: + ID_VENDOR_FROM_DATABASE=Nvidia + +acpi:NVI*: + ID_VENDOR_FROM_DATABASE=NuVision US, Inc. + +acpi:NVL*: + ID_VENDOR_FROM_DATABASE=Novell Inc + +acpi:NVT*: + ID_VENDOR_FROM_DATABASE=Navatek Engineering Corporation + +acpi:NWC*: + ID_VENDOR_FROM_DATABASE=NW Computer Engineering + +acpi:NWP*: + ID_VENDOR_FROM_DATABASE=NovaWeb Technologies Inc + +acpi:NWS*: + ID_VENDOR_FROM_DATABASE=Newisys, Inc. + +acpi:NXC*: + ID_VENDOR_FROM_DATABASE=NextCom K.K. + +acpi:NXG*: + ID_VENDOR_FROM_DATABASE=Nexgen + +acpi:NXP*: + ID_VENDOR_FROM_DATABASE=NXP Semiconductors bv. + +acpi:NXQ*: + ID_VENDOR_FROM_DATABASE=Nexiq Technologies, Inc. + +acpi:NXS*: + ID_VENDOR_FROM_DATABASE=Technology Nexus Secure Open Systems AB + +acpi:NYC*: + ID_VENDOR_FROM_DATABASE=nakayo telecommunications,inc. + +acpi:OAK*: + ID_VENDOR_FROM_DATABASE=Oak Tech Inc + +acpi:OAS*: + ID_VENDOR_FROM_DATABASE=Oasys Technology Company + +acpi:OBS*: + ID_VENDOR_FROM_DATABASE=Optibase Technologies + +acpi:OCD*: + ID_VENDOR_FROM_DATABASE=Macraigor Systems Inc + +acpi:OCN*: + ID_VENDOR_FROM_DATABASE=Olfan + +acpi:OCS*: + ID_VENDOR_FROM_DATABASE=Open Connect Solutions + +acpi:ODM*: + ID_VENDOR_FROM_DATABASE=ODME Inc. + +acpi:ODR*: + ID_VENDOR_FROM_DATABASE=Odrac + +acpi:OEC*: + ID_VENDOR_FROM_DATABASE=ORION ELECTRIC CO.,LTD + +acpi:OEI*: + ID_VENDOR_FROM_DATABASE=Optum Engineering Inc. + +acpi:OIC*: + ID_VENDOR_FROM_DATABASE=Option Industrial Computers + +acpi:OIM*: + ID_VENDOR_FROM_DATABASE=Option International + +acpi:OIN*: + ID_VENDOR_FROM_DATABASE=Option International + +acpi:OKI*: + ID_VENDOR_FROM_DATABASE=OKI Electric Industrial Company Ltd + +acpi:OLC*: + ID_VENDOR_FROM_DATABASE=Olicom A/S + +acpi:OLD*: + ID_VENDOR_FROM_DATABASE=Olidata S.p.A. + +acpi:OLI*: + ID_VENDOR_FROM_DATABASE=Olivetti + +acpi:OLT*: + ID_VENDOR_FROM_DATABASE=Olitec S.A. + +acpi:OLV*: + ID_VENDOR_FROM_DATABASE=Olitec S.A. + +acpi:OLY*: + ID_VENDOR_FROM_DATABASE=OLYMPUS CORPORATION + +acpi:OMC*: + ID_VENDOR_FROM_DATABASE=OBJIX Multimedia Corporation + +acpi:OMN*: + ID_VENDOR_FROM_DATABASE=Omnitel + +acpi:OMR*: + ID_VENDOR_FROM_DATABASE=Omron Corporation + +acpi:ONE*: + ID_VENDOR_FROM_DATABASE=Oneac Corporation + +acpi:ONK*: + ID_VENDOR_FROM_DATABASE=ONKYO Corporation + +acpi:ONL*: + ID_VENDOR_FROM_DATABASE=OnLive, Inc + +acpi:ONS*: + ID_VENDOR_FROM_DATABASE=On Systems Inc + +acpi:ONW*: + ID_VENDOR_FROM_DATABASE=OPEN Networks Ltd + +acpi:ONX*: + ID_VENDOR_FROM_DATABASE=SOMELEC Z.I. Du Vert Galanta + +acpi:OOS*: + ID_VENDOR_FROM_DATABASE=OSRAM + +acpi:OPC*: + ID_VENDOR_FROM_DATABASE=Opcode Inc + +acpi:OPI*: + ID_VENDOR_FROM_DATABASE=D.N.S. Corporation + +acpi:OPP*: + ID_VENDOR_FROM_DATABASE=OPPO Digital, Inc. + +acpi:OPT*: + ID_VENDOR_FROM_DATABASE=OPTi Inc + +acpi:OPV*: + ID_VENDOR_FROM_DATABASE=Optivision Inc + +acpi:OQI*: + ID_VENDOR_FROM_DATABASE=Oksori Company Ltd + +acpi:ORG*: + ID_VENDOR_FROM_DATABASE=ORGA Kartensysteme GmbH + +acpi:ORI*: + ID_VENDOR_FROM_DATABASE=OSR Open Systems Resources, Inc. + +acpi:ORN*: + ID_VENDOR_FROM_DATABASE=ORION ELECTRIC CO., LTD. + +acpi:OSA*: + ID_VENDOR_FROM_DATABASE=OSAKA Micro Computer, Inc. + +acpi:OSP*: + ID_VENDOR_FROM_DATABASE=OPTI-UPS Corporation + +acpi:OSR*: + ID_VENDOR_FROM_DATABASE=Oksori Company Ltd + +acpi:OTB*: + ID_VENDOR_FROM_DATABASE=outsidetheboxstuff.com + +acpi:OTI*: + ID_VENDOR_FROM_DATABASE=Orchid Technology + +acpi:OTM*: + ID_VENDOR_FROM_DATABASE=Optoma Corporation           + +acpi:OTT*: + ID_VENDOR_FROM_DATABASE=OPTO22, Inc. + +acpi:OUK*: + ID_VENDOR_FROM_DATABASE=OUK Company Ltd + +acpi:OWL*: + ID_VENDOR_FROM_DATABASE=Mediacom Technologies Pte Ltd + +acpi:OXU*: + ID_VENDOR_FROM_DATABASE=Oxus Research S.A. + +acpi:OYO*: + ID_VENDOR_FROM_DATABASE=Shadow Systems + +acpi:OZC*: + ID_VENDOR_FROM_DATABASE=OZ Corporation + +acpi:OZO*: + ID_VENDOR_FROM_DATABASE=Tribe Computer Works Inc + +acpi:PAC*: + ID_VENDOR_FROM_DATABASE=Pacific Avionics Corporation + +acpi:PAD*: + ID_VENDOR_FROM_DATABASE=Promotion and Display Technology Ltd. + +acpi:PAK*: + ID_VENDOR_FROM_DATABASE=Many CNC System Co., Ltd. + +acpi:PAM*: + ID_VENDOR_FROM_DATABASE=Peter Antesberger Messtechnik + +acpi:PAN*: + ID_VENDOR_FROM_DATABASE=The Panda Project + +acpi:PAR*: + ID_VENDOR_FROM_DATABASE=Parallan Comp Inc + +acpi:PBI*: + ID_VENDOR_FROM_DATABASE=Pitney Bowes + +acpi:PBL*: + ID_VENDOR_FROM_DATABASE=Packard Bell Electronics + +acpi:PBN*: + ID_VENDOR_FROM_DATABASE=Packard Bell NEC + +acpi:PBV*: + ID_VENDOR_FROM_DATABASE=Pitney Bowes + +acpi:PCA*: + ID_VENDOR_FROM_DATABASE=Philips BU Add On Card + +acpi:PCB*: + ID_VENDOR_FROM_DATABASE=OCTAL S.A. + +acpi:PCC*: + ID_VENDOR_FROM_DATABASE=PowerCom Technology Company Ltd + +acpi:PCG*: + ID_VENDOR_FROM_DATABASE=First Industrial Computer Inc + +acpi:PCI*: + ID_VENDOR_FROM_DATABASE=Pioneer Computer Inc + +acpi:PCK*: + ID_VENDOR_FROM_DATABASE=PCBANK21 + +acpi:PCL*: + ID_VENDOR_FROM_DATABASE=pentel.co.,ltd + +acpi:PCM*: + ID_VENDOR_FROM_DATABASE=PCM Systems Corporation + +acpi:PCO*: + ID_VENDOR_FROM_DATABASE=Performance Concepts Inc., + +acpi:PCP*: + ID_VENDOR_FROM_DATABASE=Procomp USA Inc + +acpi:PCS*: + ID_VENDOR_FROM_DATABASE=TOSHIBA PERSONAL COMPUTER SYSTEM CORPRATION + +acpi:PCT*: + ID_VENDOR_FROM_DATABASE=PC-Tel Inc + +acpi:PCW*: + ID_VENDOR_FROM_DATABASE=Pacific CommWare Inc + +acpi:PCX*: + ID_VENDOR_FROM_DATABASE=PC Xperten + +acpi:PDM*: + ID_VENDOR_FROM_DATABASE=Psion Dacom Plc. + +acpi:PDN*: + ID_VENDOR_FROM_DATABASE=AT&T Paradyne + +acpi:PDR*: + ID_VENDOR_FROM_DATABASE=Pure Data Inc + +acpi:PDS*: + ID_VENDOR_FROM_DATABASE=PD Systems International Ltd + +acpi:PDT*: + ID_VENDOR_FROM_DATABASE=PDTS - Prozessdatentechnik und Systeme + +acpi:PDV*: + ID_VENDOR_FROM_DATABASE=Prodrive B.V. + +acpi:PEC*: + ID_VENDOR_FROM_DATABASE=POTRANS Electrical Corp. + +acpi:PEI*: + ID_VENDOR_FROM_DATABASE=PEI Electronics Inc + +acpi:PEL*: + ID_VENDOR_FROM_DATABASE=Primax Electric Ltd + +acpi:PEN*: + ID_VENDOR_FROM_DATABASE=Interactive Computer Products Inc + +acpi:PEP*: + ID_VENDOR_FROM_DATABASE=Peppercon AG + +acpi:PER*: + ID_VENDOR_FROM_DATABASE=Perceptive Signal Technologies + +acpi:PET*: + ID_VENDOR_FROM_DATABASE=Practical Electronic Tools + +acpi:PFT*: + ID_VENDOR_FROM_DATABASE=Telia ProSoft AB + +acpi:PGI*: + ID_VENDOR_FROM_DATABASE=PACSGEAR, Inc. + +acpi:PGM*: + ID_VENDOR_FROM_DATABASE=Paradigm Advanced Research Centre + +acpi:PGP*: + ID_VENDOR_FROM_DATABASE=propagamma kommunikation + +acpi:PGS*: + ID_VENDOR_FROM_DATABASE=Princeton Graphic Systems + +acpi:PHC*: + ID_VENDOR_FROM_DATABASE=Pijnenburg Beheer N.V. + +acpi:PHE*: + ID_VENDOR_FROM_DATABASE=Philips Medical Systems Boeblingen GmbH + +acpi:PHL*: + ID_VENDOR_FROM_DATABASE=Philips Consumer Electronics Company + +acpi:PHO*: + ID_VENDOR_FROM_DATABASE=Photonics Systems Inc. + +acpi:PHS*: + ID_VENDOR_FROM_DATABASE=Philips Communication Systems + +acpi:PHY*: + ID_VENDOR_FROM_DATABASE=Phylon Communications + +acpi:PIE*: + ID_VENDOR_FROM_DATABASE=Pacific Image Electronics Company Ltd + +acpi:PIM*: + ID_VENDOR_FROM_DATABASE=Prism, LLC + +acpi:PIO*: + ID_VENDOR_FROM_DATABASE=Pioneer Electronic Corporation + +acpi:PIX*: + ID_VENDOR_FROM_DATABASE=Pixie Tech Inc + +acpi:PJA*: + ID_VENDOR_FROM_DATABASE=Projecta + +acpi:PJD*: + ID_VENDOR_FROM_DATABASE=Projectiondesign AS + +acpi:PJT*: + ID_VENDOR_FROM_DATABASE=Pan Jit International Inc. + +acpi:PKA*: + ID_VENDOR_FROM_DATABASE=Acco UK ltd. + +acpi:PLC*: + ID_VENDOR_FROM_DATABASE=Pro-Log Corporation + +acpi:PLF*: + ID_VENDOR_FROM_DATABASE=Panasonic Avionics Corporation + +acpi:PLM*: + ID_VENDOR_FROM_DATABASE=PROLINK Microsystems Corp. + +acpi:PLT*: + ID_VENDOR_FROM_DATABASE=PT Hartono Istana Teknologi + +acpi:PLV*: + ID_VENDOR_FROM_DATABASE=PLUS Vision Corp. + +acpi:PLX*: + ID_VENDOR_FROM_DATABASE=Parallax Graphics + +acpi:PLY*: + ID_VENDOR_FROM_DATABASE=Polycom Inc. + +acpi:PMC*: + ID_VENDOR_FROM_DATABASE=PMC Consumer Electronics Ltd + +acpi:PMD*: + ID_VENDOR_FROM_DATABASE=TDK USA Corporation + +acpi:PMM*: + ID_VENDOR_FROM_DATABASE=Point Multimedia System + +acpi:PMT*: + ID_VENDOR_FROM_DATABASE=Promate Electronic Co., Ltd. + +acpi:PMX*: + ID_VENDOR_FROM_DATABASE=Photomatrix + +acpi:PNG*: + ID_VENDOR_FROM_DATABASE=Microsoft + +acpi:PNL*: + ID_VENDOR_FROM_DATABASE=Panelview, Inc. + +acpi:PNP*: + ID_VENDOR_FROM_DATABASE=Microsoft + +acpi:PNR*: + ID_VENDOR_FROM_DATABASE=Planar Systems, Inc. + +acpi:PNS*: + ID_VENDOR_FROM_DATABASE=PanaScope + +acpi:PNX*: + ID_VENDOR_FROM_DATABASE=Phoenix Technologies, Ltd. + +acpi:POL*: + ID_VENDOR_FROM_DATABASE=PolyComp (PTY) Ltd. + +acpi:PON*: + ID_VENDOR_FROM_DATABASE=Perpetual Technologies, LLC + +acpi:POR*: + ID_VENDOR_FROM_DATABASE=Portalis LC + +acpi:PPC*: + ID_VENDOR_FROM_DATABASE=Phoenixtec Power Company Ltd + +acpi:PPD*: + ID_VENDOR_FROM_DATABASE=MEPhI + +acpi:PPI*: + ID_VENDOR_FROM_DATABASE=Practical Peripherals + +acpi:PPM*: + ID_VENDOR_FROM_DATABASE=Clinton Electronics Corp. + +acpi:PPP*: + ID_VENDOR_FROM_DATABASE=Purup Prepress AS + +acpi:PPR*: + ID_VENDOR_FROM_DATABASE=PicPro + +acpi:PPX*: + ID_VENDOR_FROM_DATABASE=Perceptive Pixel Inc. + +acpi:PQI*: + ID_VENDOR_FROM_DATABASE=Pixel Qi + +acpi:PRA*: + ID_VENDOR_FROM_DATABASE=PRO/AUTOMATION + +acpi:PRC*: + ID_VENDOR_FROM_DATABASE=PerComm + +acpi:PRD*: + ID_VENDOR_FROM_DATABASE=Praim S.R.L. + +acpi:PRF*: + ID_VENDOR_FROM_DATABASE=Digital Electronics Corporation + +acpi:PRG*: + ID_VENDOR_FROM_DATABASE=The Phoenix Research Group Inc + +acpi:PRI*: + ID_VENDOR_FROM_DATABASE=Priva Hortimation BV + +acpi:PRM*: + ID_VENDOR_FROM_DATABASE=Prometheus + +acpi:PRO*: + ID_VENDOR_FROM_DATABASE=Proteon + +acpi:PRS*: + ID_VENDOR_FROM_DATABASE=Leutron Vision + +acpi:PRT*: + ID_VENDOR_FROM_DATABASE=Parade Technologies, Ltd. + +acpi:PRX*: + ID_VENDOR_FROM_DATABASE=Proxima Corporation + +acpi:PSA*: + ID_VENDOR_FROM_DATABASE=Advanced Signal Processing Technologies + +acpi:PSC*: + ID_VENDOR_FROM_DATABASE=Philips Semiconductors + +acpi:PSD*: + ID_VENDOR_FROM_DATABASE=Peus-Systems GmbH + +acpi:PSE*: + ID_VENDOR_FROM_DATABASE=Practical Solutions Pte., Ltd. + +acpi:PSI*: + ID_VENDOR_FROM_DATABASE=PSI-Perceptive Solutions Inc + +acpi:PSL*: + ID_VENDOR_FROM_DATABASE=Perle Systems Limited + +acpi:PSM*: + ID_VENDOR_FROM_DATABASE=Prosum + +acpi:PST*: + ID_VENDOR_FROM_DATABASE=Global Data SA + +acpi:PTA*: + ID_VENDOR_FROM_DATABASE=PAR Tech Inc. + +acpi:PTC*: + ID_VENDOR_FROM_DATABASE=PS Technology Corporation + +acpi:PTG*: + ID_VENDOR_FROM_DATABASE=Cipher Systems Inc + +acpi:PTH*: + ID_VENDOR_FROM_DATABASE=Pathlight Technology Inc + +acpi:PTI*: + ID_VENDOR_FROM_DATABASE=Promise Technology Inc + +acpi:PTL*: + ID_VENDOR_FROM_DATABASE=Pantel Inc + +acpi:PTS*: + ID_VENDOR_FROM_DATABASE=Plain Tree Systems Inc + +acpi:PVG*: + ID_VENDOR_FROM_DATABASE=Proview Global Co., Ltd + +acpi:PVI*: + ID_VENDOR_FROM_DATABASE=Prime view international Co., Ltd + +acpi:PVM*: + ID_VENDOR_FROM_DATABASE=Penta Studiotechnik GmbH + +acpi:PVN*: + ID_VENDOR_FROM_DATABASE=Pixel Vision + +acpi:PVP*: + ID_VENDOR_FROM_DATABASE=Klos Technologies, Inc. + +acpi:PXC*: + ID_VENDOR_FROM_DATABASE=Phoenix Contact + +acpi:PXE*: + ID_VENDOR_FROM_DATABASE=PIXELA CORPORATION + +acpi:PXL*: + ID_VENDOR_FROM_DATABASE=The Moving Pixel Company + +acpi:PXM*: + ID_VENDOR_FROM_DATABASE=Proxim Inc + +acpi:QCC*: + ID_VENDOR_FROM_DATABASE=QuakeCom Company Ltd + +acpi:QCH*: + ID_VENDOR_FROM_DATABASE=Metronics Inc + +acpi:QCI*: + ID_VENDOR_FROM_DATABASE=Quanta Computer Inc + +acpi:QCK*: + ID_VENDOR_FROM_DATABASE=Quick Corporation + +acpi:QCL*: + ID_VENDOR_FROM_DATABASE=Quadrant Components Inc + +acpi:QCP*: + ID_VENDOR_FROM_DATABASE=Qualcomm Inc + +acpi:QDI*: + ID_VENDOR_FROM_DATABASE=Quantum Data Incorporated + +acpi:QDM*: + ID_VENDOR_FROM_DATABASE=Quadram + +acpi:QDS*: + ID_VENDOR_FROM_DATABASE=Quanta Display Inc. + +acpi:QFF*: + ID_VENDOR_FROM_DATABASE=Padix Co., Inc. + +acpi:QFI*: + ID_VENDOR_FROM_DATABASE=Quickflex, Inc + +acpi:QLC*: + ID_VENDOR_FROM_DATABASE=Q-Logic + +acpi:QQQ*: + ID_VENDOR_FROM_DATABASE=Chuomusen Co., Ltd. + +acpi:QSI*: + ID_VENDOR_FROM_DATABASE=Quantum Solutions, Inc. + +acpi:QTD*: + ID_VENDOR_FROM_DATABASE=Quantum 3D Inc + +acpi:QTH*: + ID_VENDOR_FROM_DATABASE=Questech Ltd + +acpi:QTI*: + ID_VENDOR_FROM_DATABASE=Quicknet Technologies Inc + +acpi:QTM*: + ID_VENDOR_FROM_DATABASE=Quantum + +acpi:QTR*: + ID_VENDOR_FROM_DATABASE=Qtronix Corporation + +acpi:QUA*: + ID_VENDOR_FROM_DATABASE=Quatographic AG + +acpi:QUE*: + ID_VENDOR_FROM_DATABASE=Questra Consulting + +acpi:QVU*: + ID_VENDOR_FROM_DATABASE=Quartics + +acpi:RAC*: + ID_VENDOR_FROM_DATABASE=Racore Computer Products Inc + +acpi:RAD*: + ID_VENDOR_FROM_DATABASE=Radisys Corporation + +acpi:RAI*: + ID_VENDOR_FROM_DATABASE=Rockwell Automation/Intecolor + +acpi:RAN*: + ID_VENDOR_FROM_DATABASE=Rancho Tech Inc + +acpi:RAR*: + ID_VENDOR_FROM_DATABASE=Raritan, Inc. + +acpi:RAS*: + ID_VENDOR_FROM_DATABASE=RAScom Inc + +acpi:RAT*: + ID_VENDOR_FROM_DATABASE=Rent-A-Tech + +acpi:RAY*: + ID_VENDOR_FROM_DATABASE=Raylar Design, Inc. + +acpi:RCE*: + ID_VENDOR_FROM_DATABASE=Parc d'Activite des Bellevues + +acpi:RCH*: + ID_VENDOR_FROM_DATABASE=Reach Technology Inc + +acpi:RCI*: + ID_VENDOR_FROM_DATABASE=RC International + +acpi:RCN*: + ID_VENDOR_FROM_DATABASE=Radio Consult SRL + +acpi:RCO*: + ID_VENDOR_FROM_DATABASE=Rockwell Collins + +acpi:RDI*: + ID_VENDOR_FROM_DATABASE=Rainbow Displays, Inc. + +acpi:RDM*: + ID_VENDOR_FROM_DATABASE=Tremon Enterprises Company Ltd + +acpi:RDN*: + ID_VENDOR_FROM_DATABASE=RADIODATA GmbH + +acpi:RDS*: + ID_VENDOR_FROM_DATABASE=Radius Inc + +acpi:REA*: + ID_VENDOR_FROM_DATABASE=Real D + +acpi:REC*: + ID_VENDOR_FROM_DATABASE=ReCom + +acpi:RED*: + ID_VENDOR_FROM_DATABASE=Research Electronics Development Inc + +acpi:REF*: + ID_VENDOR_FROM_DATABASE=Reflectivity, Inc. + +acpi:REH*: + ID_VENDOR_FROM_DATABASE=Rehan Electronics Ltd. + +acpi:REL*: + ID_VENDOR_FROM_DATABASE=Reliance Electric Ind Corporation + +acpi:REM*: + ID_VENDOR_FROM_DATABASE=SCI Systems Inc. + +acpi:REN*: + ID_VENDOR_FROM_DATABASE=Renesas Technology Corp. + +acpi:RES*: + ID_VENDOR_FROM_DATABASE=ResMed Pty Ltd + +acpi:RET*: + ID_VENDOR_FROM_DATABASE=Resonance Technology, Inc. + +acpi:REX*: + ID_VENDOR_FROM_DATABASE=RATOC Systems, Inc. + +acpi:RGL*: + ID_VENDOR_FROM_DATABASE=Robertson Geologging Ltd + +acpi:RHD*: + ID_VENDOR_FROM_DATABASE=RightHand Technologies + +acpi:RHM*: + ID_VENDOR_FROM_DATABASE=Rohm Company Ltd + +acpi:RHT*: + ID_VENDOR_FROM_DATABASE=Red Hat, Inc. + +acpi:RIC*: + ID_VENDOR_FROM_DATABASE=RICOH COMPANY, LTD. + +acpi:RII*: + ID_VENDOR_FROM_DATABASE=Racal Interlan Inc + +acpi:RIO*: + ID_VENDOR_FROM_DATABASE=Rios Systems Company Ltd + +acpi:RIT*: + ID_VENDOR_FROM_DATABASE=Ritech Inc + +acpi:RIV*: + ID_VENDOR_FROM_DATABASE=Rivulet Communications + +acpi:RJA*: + ID_VENDOR_FROM_DATABASE=Roland Corporation + +acpi:RJS*: + ID_VENDOR_FROM_DATABASE=Advanced Engineering + +acpi:RKC*: + ID_VENDOR_FROM_DATABASE=Reakin Technolohy Corporation + +acpi:RLD*: + ID_VENDOR_FROM_DATABASE=MEPCO + +acpi:RLN*: + ID_VENDOR_FROM_DATABASE=RadioLAN Inc + +acpi:RMC*: + ID_VENDOR_FROM_DATABASE=Raritan Computer, Inc + +acpi:RMP*: + ID_VENDOR_FROM_DATABASE=Research Machines + +acpi:RMT*: + ID_VENDOR_FROM_DATABASE=Roper Mobile + +acpi:RNB*: + ID_VENDOR_FROM_DATABASE=Rainbow Technologies + +acpi:ROB*: + ID_VENDOR_FROM_DATABASE=Robust Electronics GmbH + +acpi:ROH*: + ID_VENDOR_FROM_DATABASE=Rohm Co., Ltd. + +acpi:ROK*: + ID_VENDOR_FROM_DATABASE=Rockwell International + +acpi:ROP*: + ID_VENDOR_FROM_DATABASE=Roper International Ltd + +acpi:ROS*: + ID_VENDOR_FROM_DATABASE=Rohde & Schwarz + +acpi:RPI*: + ID_VENDOR_FROM_DATABASE=RoomPro Technologies + +acpi:RPT*: + ID_VENDOR_FROM_DATABASE=R.P.T.Intergroups + +acpi:RRI*: + ID_VENDOR_FROM_DATABASE=Radicom Research Inc + +acpi:RSC*: + ID_VENDOR_FROM_DATABASE=PhotoTelesis + +acpi:RSH*: + ID_VENDOR_FROM_DATABASE=ADC-Centre + +acpi:RSI*: + ID_VENDOR_FROM_DATABASE=Rampage Systems Inc + +acpi:RSN*: + ID_VENDOR_FROM_DATABASE=Radiospire Networks, Inc. + +acpi:RSQ*: + ID_VENDOR_FROM_DATABASE=R Squared + +acpi:RSS*: + ID_VENDOR_FROM_DATABASE=Rockwell Semiconductor Systems + +acpi:RSV*: + ID_VENDOR_FROM_DATABASE=Ross Video Ltd + +acpi:RSX*: + ID_VENDOR_FROM_DATABASE=Rapid Tech Corporation + +acpi:RTC*: + ID_VENDOR_FROM_DATABASE=Relia Technologies + +acpi:RTI*: + ID_VENDOR_FROM_DATABASE=Rancho Tech Inc + +acpi:RTL*: + ID_VENDOR_FROM_DATABASE=Realtek Semiconductor Company Ltd + +acpi:RTS*: + ID_VENDOR_FROM_DATABASE=Raintree Systems + +acpi:RUN*: + ID_VENDOR_FROM_DATABASE=RUNCO International + +acpi:RUP*: + ID_VENDOR_FROM_DATABASE=Ups Manufactoring s.r.l. + +acpi:RVC*: + ID_VENDOR_FROM_DATABASE=RSI Systems Inc + +acpi:RVI*: + ID_VENDOR_FROM_DATABASE=Realvision Inc + +acpi:RVL*: + ID_VENDOR_FROM_DATABASE=Reveal Computer Prod + +acpi:RWC*: + ID_VENDOR_FROM_DATABASE=Red Wing Corporation + +acpi:RXT*: + ID_VENDOR_FROM_DATABASE=Tectona SoftSolutions (P) Ltd., + +acpi:SAA*: + ID_VENDOR_FROM_DATABASE=Sanritz Automation Co.,Ltd. + +acpi:SAE*: + ID_VENDOR_FROM_DATABASE=Saab Aerotech + +acpi:SAG*: + ID_VENDOR_FROM_DATABASE=Sedlbauer + +acpi:SAI*: + ID_VENDOR_FROM_DATABASE=Sage Inc + +acpi:SAK*: + ID_VENDOR_FROM_DATABASE=Saitek Ltd + +acpi:SAM*: + ID_VENDOR_FROM_DATABASE=Samsung Electric Company + +acpi:SAN*: + ID_VENDOR_FROM_DATABASE=Sanyo Electric Co.,Ltd. + +acpi:SAS*: + ID_VENDOR_FROM_DATABASE=Stores Automated Systems Inc + +acpi:SAT*: + ID_VENDOR_FROM_DATABASE=Shuttle Tech + +acpi:SBC*: + ID_VENDOR_FROM_DATABASE=Shanghai Bell Telephone Equip Mfg Co + +acpi:SBD*: + ID_VENDOR_FROM_DATABASE=Softbed - Consulting & Development Ltd + +acpi:SBI*: + ID_VENDOR_FROM_DATABASE=SMART Technologies Inc. + +acpi:SBS*: + ID_VENDOR_FROM_DATABASE=SBS-or Industrial Computers GmbH + +acpi:SBT*: + ID_VENDOR_FROM_DATABASE=Senseboard Technologies AB + +acpi:SCC*: + ID_VENDOR_FROM_DATABASE=SORD Computer Corporation + +acpi:SCD*: + ID_VENDOR_FROM_DATABASE=Sanyo Electric Company Ltd + +acpi:SCE*: + ID_VENDOR_FROM_DATABASE=Sun Corporation + +acpi:SCH*: + ID_VENDOR_FROM_DATABASE=Schlumberger Cards + +acpi:SCI*: + ID_VENDOR_FROM_DATABASE=System Craft + +acpi:SCL*: + ID_VENDOR_FROM_DATABASE=Sigmacom Co., Ltd. + +acpi:SCM*: + ID_VENDOR_FROM_DATABASE=SCM Microsystems Inc + +acpi:SCN*: + ID_VENDOR_FROM_DATABASE=Scanport, Inc. + +acpi:SCO*: + ID_VENDOR_FROM_DATABASE=SORCUS Computer GmbH + +acpi:SCP*: + ID_VENDOR_FROM_DATABASE=Scriptel Corporation + +acpi:SCR*: + ID_VENDOR_FROM_DATABASE=Systran Corporation + +acpi:SCS*: + ID_VENDOR_FROM_DATABASE=Nanomach Anstalt + +acpi:SCT*: + ID_VENDOR_FROM_DATABASE=Smart Card Technology + +acpi:SDA*: + ID_VENDOR_FROM_DATABASE=SAT (Societe Anonyme) + +acpi:SDD*: + ID_VENDOR_FROM_DATABASE=Intrada-SDD Ltd + +acpi:SDE*: + ID_VENDOR_FROM_DATABASE=Sherwood Digital Electronics Corporation + +acpi:SDF*: + ID_VENDOR_FROM_DATABASE=SODIFF E&T CO., Ltd. + +acpi:SDH*: + ID_VENDOR_FROM_DATABASE=Communications Specialies, Inc. + +acpi:SDI*: + ID_VENDOR_FROM_DATABASE=Samtron Displays Inc + +acpi:SDK*: + ID_VENDOR_FROM_DATABASE=SAIT-Devlonics + +acpi:SDR*: + ID_VENDOR_FROM_DATABASE=SDR Systems + +acpi:SDS*: + ID_VENDOR_FROM_DATABASE=SunRiver Data System + +acpi:SDT*: + ID_VENDOR_FROM_DATABASE=Siemens AG + +acpi:SDX*: + ID_VENDOR_FROM_DATABASE=SDX Business Systems Ltd + +acpi:SEA*: + ID_VENDOR_FROM_DATABASE=Seanix Technology Inc. + +acpi:SEB*: + ID_VENDOR_FROM_DATABASE=system elektronik GmbH + +acpi:SEC*: + ID_VENDOR_FROM_DATABASE=Seiko Epson Corporation + +acpi:SEE*: + ID_VENDOR_FROM_DATABASE=SeeColor Corporation + +acpi:SEI*: + ID_VENDOR_FROM_DATABASE=Seitz & Associates Inc + +acpi:SEL*: + ID_VENDOR_FROM_DATABASE=Way2Call Communications + +acpi:SEM*: + ID_VENDOR_FROM_DATABASE=Samsung Electronics Company Ltd + +acpi:SEN*: + ID_VENDOR_FROM_DATABASE=Sencore + +acpi:SEO*: + ID_VENDOR_FROM_DATABASE=SEOS Ltd + +acpi:SEP*: + ID_VENDOR_FROM_DATABASE=SEP Eletronica Ltda. + +acpi:SER*: + ID_VENDOR_FROM_DATABASE=Sony Ericsson Mobile Communications Inc. + +acpi:SES*: + ID_VENDOR_FROM_DATABASE=Session Control LLC + +acpi:SET*: + ID_VENDOR_FROM_DATABASE=SendTek Corporation + +acpi:SFM*: + ID_VENDOR_FROM_DATABASE=TORNADO Company + +acpi:SFT*: + ID_VENDOR_FROM_DATABASE=Mikroforum Ring 3 + +acpi:SGC*: + ID_VENDOR_FROM_DATABASE=Spectragraphics Corporation + +acpi:SGD*: + ID_VENDOR_FROM_DATABASE=Sigma Designs, Inc. + +acpi:SGE*: + ID_VENDOR_FROM_DATABASE=Kansai Electric Company Ltd + +acpi:SGI*: + ID_VENDOR_FROM_DATABASE=Scan Group Ltd + +acpi:SGL*: + ID_VENDOR_FROM_DATABASE=Super Gate Technology Company Ltd + +acpi:SGM*: + ID_VENDOR_FROM_DATABASE=SAGEM + +acpi:SGO*: + ID_VENDOR_FROM_DATABASE=Logos Design A/S + +acpi:SGT*: + ID_VENDOR_FROM_DATABASE=Stargate Technology + +acpi:SGW*: + ID_VENDOR_FROM_DATABASE=Shanghai Guowei Science and Technology Co., Ltd. + +acpi:SGX*: + ID_VENDOR_FROM_DATABASE=Silicon Graphics Inc + +acpi:SGZ*: + ID_VENDOR_FROM_DATABASE=Systec Computer GmbH + +acpi:SHC*: + ID_VENDOR_FROM_DATABASE=ShibaSoku Co., Ltd. + +acpi:SHG*: + ID_VENDOR_FROM_DATABASE=Soft & Hardware development Goldammer GmbH + +acpi:SHI*: + ID_VENDOR_FROM_DATABASE=Jiangsu Shinco Electronic Group Co., Ltd + +acpi:SHP*: + ID_VENDOR_FROM_DATABASE=Sharp Corporation + +acpi:SHR*: + ID_VENDOR_FROM_DATABASE=Digital Discovery + +acpi:SHT*: + ID_VENDOR_FROM_DATABASE=Shin Ho Tech + +acpi:SIA*: + ID_VENDOR_FROM_DATABASE=SIEMENS AG + +acpi:SIB*: + ID_VENDOR_FROM_DATABASE=Sanyo Electric Company Ltd + +acpi:SIC*: + ID_VENDOR_FROM_DATABASE=Sysmate Corporation + +acpi:SID*: + ID_VENDOR_FROM_DATABASE=Seiko Instruments Information Devices Inc + +acpi:SIE*: + ID_VENDOR_FROM_DATABASE=Siemens + +acpi:SIG*: + ID_VENDOR_FROM_DATABASE=Sigma Designs Inc + +acpi:SII*: + ID_VENDOR_FROM_DATABASE=Silicon Image, Inc. + +acpi:SIL*: + ID_VENDOR_FROM_DATABASE=Silicon Laboratories, Inc + +acpi:SIM*: + ID_VENDOR_FROM_DATABASE=S3 Inc + +acpi:SIN*: + ID_VENDOR_FROM_DATABASE=Singular Technology Co., Ltd. + +acpi:SIR*: + ID_VENDOR_FROM_DATABASE=Sirius Technologies Pty Ltd + +acpi:SIS*: + ID_VENDOR_FROM_DATABASE=Silicon Integrated Systems Corporation + +acpi:SIT*: + ID_VENDOR_FROM_DATABASE=Sitintel + +acpi:SIU*: + ID_VENDOR_FROM_DATABASE=Seiko Instruments USA Inc + +acpi:SIX*: + ID_VENDOR_FROM_DATABASE=Zuniq Data Corporation + +acpi:SJE*: + ID_VENDOR_FROM_DATABASE=Sejin Electron Inc + +acpi:SKD*: + ID_VENDOR_FROM_DATABASE=Schneider & Koch + +acpi:SKT*: + ID_VENDOR_FROM_DATABASE=Samsung Electro-Mechanics Company Ltd + +acpi:SKY*: + ID_VENDOR_FROM_DATABASE=SKYDATA S.P.A. + +acpi:SLA*: + ID_VENDOR_FROM_DATABASE=Systeme Lauer GmbH&Co KG + +acpi:SLB*: + ID_VENDOR_FROM_DATABASE=Shlumberger Ltd + +acpi:SLC*: + ID_VENDOR_FROM_DATABASE=Syslogic Datentechnik AG + +acpi:SLF*: + ID_VENDOR_FROM_DATABASE=StarLeaf + +acpi:SLH*: + ID_VENDOR_FROM_DATABASE=Silicon Library Inc. + +acpi:SLI*: + ID_VENDOR_FROM_DATABASE=Symbios Logic Inc + +acpi:SLK*: + ID_VENDOR_FROM_DATABASE=Silitek Corporation + +acpi:SLM*: + ID_VENDOR_FROM_DATABASE=Solomon Technology Corporation + +acpi:SLR*: + ID_VENDOR_FROM_DATABASE=Schlumberger Technology Corporate + +acpi:SLS*: + ID_VENDOR_FROM_DATABASE=Schnick-Schnack-Systems GmbH + +acpi:SLT*: + ID_VENDOR_FROM_DATABASE=Salt Internatioinal Corp. + +acpi:SLX*: + ID_VENDOR_FROM_DATABASE=Specialix + +acpi:SMA*: + ID_VENDOR_FROM_DATABASE=SMART Modular Technologies + +acpi:SMB*: + ID_VENDOR_FROM_DATABASE=Schlumberger + +acpi:SMC*: + ID_VENDOR_FROM_DATABASE=Standard Microsystems Corporation + +acpi:SME*: + ID_VENDOR_FROM_DATABASE=Sysmate Company + +acpi:SMI*: + ID_VENDOR_FROM_DATABASE=SpaceLabs Medical Inc + +acpi:SMK*: + ID_VENDOR_FROM_DATABASE=SMK CORPORATION + +acpi:SML*: + ID_VENDOR_FROM_DATABASE=Sumitomo Metal Industries, Ltd. + +acpi:SMM*: + ID_VENDOR_FROM_DATABASE=Shark Multimedia Inc + +acpi:SMO*: + ID_VENDOR_FROM_DATABASE=STMicroelectronics + +acpi:SMP*: + ID_VENDOR_FROM_DATABASE=Simple Computing + +acpi:SMR*: + ID_VENDOR_FROM_DATABASE=B.& V. s.r.l. + +acpi:SMS*: + ID_VENDOR_FROM_DATABASE=Silicom Multimedia Systems Inc + +acpi:SMT*: + ID_VENDOR_FROM_DATABASE=Silcom Manufacturing Tech Inc + +acpi:SNC*: + ID_VENDOR_FROM_DATABASE=Sentronic International Corp. + +acpi:SNI*: + ID_VENDOR_FROM_DATABASE=Siemens Microdesign GmbH + +acpi:SNK*: + ID_VENDOR_FROM_DATABASE=S&K Electronics + +acpi:SNO*: + ID_VENDOR_FROM_DATABASE=SINOSUN TECHNOLOGY CO., LTD + +acpi:SNP*: + ID_VENDOR_FROM_DATABASE=Siemens Nixdorf Info Systems + +acpi:SNS*: + ID_VENDOR_FROM_DATABASE=Cirtech (UK) Ltd + +acpi:SNT*: + ID_VENDOR_FROM_DATABASE=SuperNet Inc + +acpi:SNW*: + ID_VENDOR_FROM_DATABASE=Snell & Wilcox + +acpi:SNX*: + ID_VENDOR_FROM_DATABASE=Sonix Comm. Ltd + +acpi:SNY*: + ID_VENDOR_FROM_DATABASE=Sony + +acpi:SOI*: + ID_VENDOR_FROM_DATABASE=Silicon Optix Corporation + +acpi:SOL*: + ID_VENDOR_FROM_DATABASE=Solitron Technologies Inc + +acpi:SON*: + ID_VENDOR_FROM_DATABASE=Sony + +acpi:SOR*: + ID_VENDOR_FROM_DATABASE=Sorcus Computer GmbH + +acpi:SOT*: + ID_VENDOR_FROM_DATABASE=Sotec Company Ltd + +acpi:SOY*: + ID_VENDOR_FROM_DATABASE=SOYO Group, Inc + +acpi:SPC*: + ID_VENDOR_FROM_DATABASE=SpinCore Technologies, Inc + +acpi:SPE*: + ID_VENDOR_FROM_DATABASE=SPEA Software AG + +acpi:SPH*: + ID_VENDOR_FROM_DATABASE=G&W Instruments GmbH + +acpi:SPI*: + ID_VENDOR_FROM_DATABASE=SPACE-I Co., Ltd. + +acpi:SPK*: + ID_VENDOR_FROM_DATABASE=SpeakerCraft + +acpi:SPL*: + ID_VENDOR_FROM_DATABASE=Smart Silicon Systems Pty Ltd + +acpi:SPN*: + ID_VENDOR_FROM_DATABASE=Sapience Corporation + +acpi:SPR*: + ID_VENDOR_FROM_DATABASE=pmns GmbH + +acpi:SPS*: + ID_VENDOR_FROM_DATABASE=Synopsys Inc + +acpi:SPT*: + ID_VENDOR_FROM_DATABASE=Sceptre Tech Inc + +acpi:SPU*: + ID_VENDOR_FROM_DATABASE=SIM2 Multimedia S.P.A. + +acpi:SPX*: + ID_VENDOR_FROM_DATABASE=Simplex Time Recorder Co. + +acpi:SQT*: + ID_VENDOR_FROM_DATABASE=Sequent Computer Systems Inc + +acpi:SRC*: + ID_VENDOR_FROM_DATABASE=Integrated Tech Express Inc + +acpi:SRD*: + ID_VENDOR_FROM_DATABASE=Setred + +acpi:SRF*: + ID_VENDOR_FROM_DATABASE=Surf Communication Solutions Ltd + +acpi:SRG*: + ID_VENDOR_FROM_DATABASE=Intuitive Surgical, Inc. + +acpi:SRT*: + ID_VENDOR_FROM_DATABASE=SeeReal Technologies GmbH + +acpi:SSC*: + ID_VENDOR_FROM_DATABASE=Sierra Semiconductor Inc + +acpi:SSD*: + ID_VENDOR_FROM_DATABASE=FlightSafety International + +acpi:SSE*: + ID_VENDOR_FROM_DATABASE=Samsung Electronic Co. + +acpi:SSI*: + ID_VENDOR_FROM_DATABASE=S-S Technology Inc + +acpi:SSJ*: + ID_VENDOR_FROM_DATABASE=Sankyo Seiki Mfg.co., Ltd + +acpi:SSP*: + ID_VENDOR_FROM_DATABASE=Spectrum Signal Proecessing Inc + +acpi:SSS*: + ID_VENDOR_FROM_DATABASE=S3 Inc + +acpi:SST*: + ID_VENDOR_FROM_DATABASE=SystemSoft Corporation + +acpi:STA*: + ID_VENDOR_FROM_DATABASE=ST Electronics Systems Assembly Pte Ltd + +acpi:STB*: + ID_VENDOR_FROM_DATABASE=STB Systems Inc + +acpi:STC*: + ID_VENDOR_FROM_DATABASE=STAC Electronics + +acpi:STD*: + ID_VENDOR_FROM_DATABASE=STD Computer Inc + +acpi:STE*: + ID_VENDOR_FROM_DATABASE=SII Ido-Tsushin Inc + +acpi:STF*: + ID_VENDOR_FROM_DATABASE=Starflight Electronics + +acpi:STG*: + ID_VENDOR_FROM_DATABASE=StereoGraphics Corp. + +acpi:STH*: + ID_VENDOR_FROM_DATABASE=Semtech Corporation + +acpi:STI*: + ID_VENDOR_FROM_DATABASE=Smart Tech Inc + +acpi:STK*: + ID_VENDOR_FROM_DATABASE=SANTAK CORP. + +acpi:STL*: + ID_VENDOR_FROM_DATABASE=SigmaTel Inc + +acpi:STM*: + ID_VENDOR_FROM_DATABASE=SGS Thomson Microelectronics + +acpi:STN*: + ID_VENDOR_FROM_DATABASE=Samsung Electronics America + +acpi:STO*: + ID_VENDOR_FROM_DATABASE=Stollmann E+V GmbH + +acpi:STP*: + ID_VENDOR_FROM_DATABASE=StreamPlay Ltd + +acpi:STR*: + ID_VENDOR_FROM_DATABASE=Starlight Networks Inc + +acpi:STS*: + ID_VENDOR_FROM_DATABASE=SITECSYSTEM CO., LTD. + +acpi:STT*: + ID_VENDOR_FROM_DATABASE=Star Paging Telecom Tech (Shenzhen) Co. Ltd. + +acpi:STU*: + ID_VENDOR_FROM_DATABASE=Sentelic Corporation + +acpi:STW*: + ID_VENDOR_FROM_DATABASE=Starwin Inc. + +acpi:STX*: + ID_VENDOR_FROM_DATABASE=ST-Ericsson + +acpi:STY*: + ID_VENDOR_FROM_DATABASE=SDS Technologies + +acpi:SUB*: + ID_VENDOR_FROM_DATABASE=Subspace Comm. Inc + +acpi:SUM*: + ID_VENDOR_FROM_DATABASE=Summagraphics Corporation + +acpi:SUN*: + ID_VENDOR_FROM_DATABASE=Sun Electronics Corporation + +acpi:SUP*: + ID_VENDOR_FROM_DATABASE=Supra Corporation + +acpi:SUR*: + ID_VENDOR_FROM_DATABASE=Surenam Computer Corporation + +acpi:SVA*: + ID_VENDOR_FROM_DATABASE=SGEG + +acpi:SVC*: + ID_VENDOR_FROM_DATABASE=Intellix Corp. + +acpi:SVD*: + ID_VENDOR_FROM_DATABASE=SVD Computer + +acpi:SVI*: + ID_VENDOR_FROM_DATABASE=Sun Microsystems + +acpi:SVS*: + ID_VENDOR_FROM_DATABASE=SVSI + +acpi:SVT*: + ID_VENDOR_FROM_DATABASE=SEVIT Co., Ltd. + +acpi:SWC*: + ID_VENDOR_FROM_DATABASE=Software Café + +acpi:SWI*: + ID_VENDOR_FROM_DATABASE=Sierra Wireless Inc. + +acpi:SWL*: + ID_VENDOR_FROM_DATABASE=Sharedware Ltd + +acpi:SWS*: + ID_VENDOR_FROM_DATABASE=Static + +acpi:SWT*: + ID_VENDOR_FROM_DATABASE=Software Technologies Group,Inc. + +acpi:SXB*: + ID_VENDOR_FROM_DATABASE=Syntax-Brillian + +acpi:SXD*: + ID_VENDOR_FROM_DATABASE=Silex technology, Inc. + +acpi:SXL*: + ID_VENDOR_FROM_DATABASE=SolutionInside + +acpi:SXT*: + ID_VENDOR_FROM_DATABASE=SHARP TAKAYA ELECTRONIC INDUSTRY CO.,LTD. + +acpi:SYC*: + ID_VENDOR_FROM_DATABASE=Sysmic + +acpi:SYE*: + ID_VENDOR_FROM_DATABASE=SY Electronics Ltd + +acpi:SYK*: + ID_VENDOR_FROM_DATABASE=Stryker Communications + +acpi:SYL*: + ID_VENDOR_FROM_DATABASE=Sylvania Computer Products + +acpi:SYM*: + ID_VENDOR_FROM_DATABASE=Symicron Computer Communications Ltd. + +acpi:SYN*: + ID_VENDOR_FROM_DATABASE=Synaptics Inc + +acpi:SYP*: + ID_VENDOR_FROM_DATABASE=SYPRO Co Ltd + +acpi:SYS*: + ID_VENDOR_FROM_DATABASE=Sysgration Ltd + +acpi:SYT*: + ID_VENDOR_FROM_DATABASE=Seyeon Tech Company Ltd + +acpi:SYV*: + ID_VENDOR_FROM_DATABASE=SYVAX Inc + +acpi:SYX*: + ID_VENDOR_FROM_DATABASE=Prime Systems, Inc. + +acpi:TAA*: + ID_VENDOR_FROM_DATABASE=Tandberg + +acpi:TAB*: + ID_VENDOR_FROM_DATABASE=Todos Data System AB + +acpi:TAG*: + ID_VENDOR_FROM_DATABASE=Teles AG + +acpi:TAI*: + ID_VENDOR_FROM_DATABASE=Toshiba America Info Systems Inc + +acpi:TAM*: + ID_VENDOR_FROM_DATABASE=Tamura Seisakusyo Ltd + +acpi:TAS*: + ID_VENDOR_FROM_DATABASE=Taskit Rechnertechnik GmbH + +acpi:TAT*: + ID_VENDOR_FROM_DATABASE=Teleliaison Inc + +acpi:TAX*: + ID_VENDOR_FROM_DATABASE=Taxan (Europe) Ltd + +acpi:TBB*: + ID_VENDOR_FROM_DATABASE=Triple S Engineering Inc + +acpi:TBC*: + ID_VENDOR_FROM_DATABASE=Turbo Communication, Inc + +acpi:TBS*: + ID_VENDOR_FROM_DATABASE=Turtle Beach System + +acpi:TCC*: + ID_VENDOR_FROM_DATABASE=Tandon Corporation + +acpi:TCD*: + ID_VENDOR_FROM_DATABASE=Taicom Data Systems Co., Ltd. + +acpi:TCE*: + ID_VENDOR_FROM_DATABASE=Century Corporation + +acpi:TCH*: + ID_VENDOR_FROM_DATABASE=Interaction Systems, Inc + +acpi:TCI*: + ID_VENDOR_FROM_DATABASE=Tulip Computers Int'l B.V. + +acpi:TCJ*: + ID_VENDOR_FROM_DATABASE=TEAC America Inc + +acpi:TCL*: + ID_VENDOR_FROM_DATABASE=Technical Concepts Ltd + +acpi:TCM*: + ID_VENDOR_FROM_DATABASE=3Com Corporation + +acpi:TCN*: + ID_VENDOR_FROM_DATABASE=Tecnetics (PTY) Ltd + +acpi:TCO*: + ID_VENDOR_FROM_DATABASE=Thomas-Conrad Corporation + +acpi:TCR*: + ID_VENDOR_FROM_DATABASE=Thomson Consumer Electronics + +acpi:TCS*: + ID_VENDOR_FROM_DATABASE=Tatung Company of America Inc + +acpi:TCT*: + ID_VENDOR_FROM_DATABASE=Telecom Technology Centre Co. Ltd. + +acpi:TCX*: + ID_VENDOR_FROM_DATABASE=FREEMARS Heavy Industries + +acpi:TDC*: + ID_VENDOR_FROM_DATABASE=Teradici + +acpi:TDD*: + ID_VENDOR_FROM_DATABASE=Tandberg Data Display AS + +acpi:TDK*: + ID_VENDOR_FROM_DATABASE=TDK USA Corporation + +acpi:TDM*: + ID_VENDOR_FROM_DATABASE=Tandem Computer Europe Inc + +acpi:TDP*: + ID_VENDOR_FROM_DATABASE=3D Perception + +acpi:TDS*: + ID_VENDOR_FROM_DATABASE=Tri-Data Systems Inc + +acpi:TDT*: + ID_VENDOR_FROM_DATABASE=TDT + +acpi:TDV*: + ID_VENDOR_FROM_DATABASE=TDVision Systems, Inc. + +acpi:TDY*: + ID_VENDOR_FROM_DATABASE=Tandy Electronics + +acpi:TEA*: + ID_VENDOR_FROM_DATABASE=TEAC System Corporation + +acpi:TEC*: + ID_VENDOR_FROM_DATABASE=Tecmar Inc + +acpi:TEK*: + ID_VENDOR_FROM_DATABASE=Tektronix Inc + +acpi:TEL*: + ID_VENDOR_FROM_DATABASE=Promotion and Display Technology Ltd. + +acpi:TER*: + ID_VENDOR_FROM_DATABASE=TerraTec Electronic GmbH + +acpi:TGC*: + ID_VENDOR_FROM_DATABASE=Toshiba Global Commerce Solutions, Inc. + +acpi:TGI*: + ID_VENDOR_FROM_DATABASE=TriGem Computer Inc + +acpi:TGM*: + ID_VENDOR_FROM_DATABASE=TriGem Computer,Inc. + +acpi:TGS*: + ID_VENDOR_FROM_DATABASE=Torus Systems Ltd + +acpi:TGV*: + ID_VENDOR_FROM_DATABASE=Grass Valley Germany GmbH + +acpi:THN*: + ID_VENDOR_FROM_DATABASE=Thundercom Holdings Sdn. Bhd. + +acpi:TIC*: + ID_VENDOR_FROM_DATABASE=Trigem KinfoComm + +acpi:TIP*: + ID_VENDOR_FROM_DATABASE=TIPTEL AG + +acpi:TIV*: + ID_VENDOR_FROM_DATABASE=OOO Technoinvest + +acpi:TIX*: + ID_VENDOR_FROM_DATABASE=Tixi.Com GmbH + +acpi:TKC*: + ID_VENDOR_FROM_DATABASE=Taiko Electric Works.LTD + +acpi:TKN*: + ID_VENDOR_FROM_DATABASE=Teknor Microsystem Inc + +acpi:TKO*: + ID_VENDOR_FROM_DATABASE=TouchKo, Inc. + +acpi:TKS*: + ID_VENDOR_FROM_DATABASE=TimeKeeping Systems, Inc. + +acpi:TLA*: + ID_VENDOR_FROM_DATABASE=Ferrari Electronic GmbH + +acpi:TLD*: + ID_VENDOR_FROM_DATABASE=Telindus + +acpi:TLI*: + ID_VENDOR_FROM_DATABASE=TOSHIBA TELI CORPORATION + +acpi:TLK*: + ID_VENDOR_FROM_DATABASE=Telelink AG + +acpi:TLS*: + ID_VENDOR_FROM_DATABASE=Teleste Educational OY + +acpi:TLT*: + ID_VENDOR_FROM_DATABASE=Dai Telecom S.p.A. + +acpi:TLV*: + ID_VENDOR_FROM_DATABASE=S3 Inc + +acpi:TLX*: + ID_VENDOR_FROM_DATABASE=Telxon Corporation + +acpi:TMC*: + ID_VENDOR_FROM_DATABASE=Techmedia Computer Systems Corporation + +acpi:TME*: + ID_VENDOR_FROM_DATABASE=AT&T Microelectronics + +acpi:TMI*: + ID_VENDOR_FROM_DATABASE=Texas Microsystem + +acpi:TMM*: + ID_VENDOR_FROM_DATABASE=Time Management, Inc. + +acpi:TMR*: + ID_VENDOR_FROM_DATABASE=Taicom International Inc + +acpi:TMS*: + ID_VENDOR_FROM_DATABASE=Trident Microsystems Ltd + +acpi:TMT*: + ID_VENDOR_FROM_DATABASE=T-Metrics Inc. + +acpi:TMX*: + ID_VENDOR_FROM_DATABASE=Thermotrex Corporation + +acpi:TNC*: + ID_VENDOR_FROM_DATABASE=TNC Industrial Company Ltd + +acpi:TNM*: + ID_VENDOR_FROM_DATABASE=TECNIMAGEN SA + +acpi:TNY*: + ID_VENDOR_FROM_DATABASE=Tennyson Tech Pty Ltd + +acpi:TOE*: + ID_VENDOR_FROM_DATABASE=TOEI Electronics Co., Ltd. + +acpi:TOG*: + ID_VENDOR_FROM_DATABASE=The OPEN Group + +acpi:TON*: + ID_VENDOR_FROM_DATABASE=TONNA + +acpi:TOP*: + ID_VENDOR_FROM_DATABASE=Orion Communications Co., Ltd. + +acpi:TOS*: + ID_VENDOR_FROM_DATABASE=Toshiba Corporation + +acpi:TOU*: + ID_VENDOR_FROM_DATABASE=Touchstone Technology + +acpi:TPC*: + ID_VENDOR_FROM_DATABASE=Touch Panel Systems Corporation + +acpi:TPE*: + ID_VENDOR_FROM_DATABASE=Technology Power Enterprises Inc + +acpi:TPJ*: + ID_VENDOR_FROM_DATABASE=Junnila + +acpi:TPK*: + ID_VENDOR_FROM_DATABASE=TOPRE CORPORATION + +acpi:TPR*: + ID_VENDOR_FROM_DATABASE=Topro Technology Inc + +acpi:TPS*: + ID_VENDOR_FROM_DATABASE=Teleprocessing Systeme GmbH + +acpi:TPT*: + ID_VENDOR_FROM_DATABASE=Thruput Ltd + +acpi:TPV*: + ID_VENDOR_FROM_DATABASE=Top Victory Electronics ( Fujian ) Company Ltd + +acpi:TPZ*: + ID_VENDOR_FROM_DATABASE=Ypoaz Systems Inc + +acpi:TRA*: + ID_VENDOR_FROM_DATABASE=TriTech Microelectronics International + +acpi:TRC*: + ID_VENDOR_FROM_DATABASE=Trioc AB + +acpi:TRD*: + ID_VENDOR_FROM_DATABASE=Trident Microsystem Inc + +acpi:TRE*: + ID_VENDOR_FROM_DATABASE=Tremetrics + +acpi:TRI*: + ID_VENDOR_FROM_DATABASE=Tricord Systems + +acpi:TRL*: + ID_VENDOR_FROM_DATABASE=Royal Information + +acpi:TRM*: + ID_VENDOR_FROM_DATABASE=Tekram Technology Company Ltd + +acpi:TRN*: + ID_VENDOR_FROM_DATABASE=Datacommunicatie Tron B.V. + +acpi:TRS*: + ID_VENDOR_FROM_DATABASE=Torus Systems Ltd + +acpi:TRT*: + ID_VENDOR_FROM_DATABASE=Tritec Electronic AG + +acpi:TRU*: + ID_VENDOR_FROM_DATABASE=Aashima Technology B.V. + +acpi:TRV*: + ID_VENDOR_FROM_DATABASE=Trivisio Prototyping GmbH + +acpi:TRX*: + ID_VENDOR_FROM_DATABASE=Trex Enterprises + +acpi:TSB*: + ID_VENDOR_FROM_DATABASE=Toshiba America Info Systems Inc + +acpi:TSC*: + ID_VENDOR_FROM_DATABASE=Sanyo Electric Company Ltd + +acpi:TSD*: + ID_VENDOR_FROM_DATABASE=TechniSat Digital GmbH + +acpi:TSE*: + ID_VENDOR_FROM_DATABASE=Tottori Sanyo Electric + +acpi:TSF*: + ID_VENDOR_FROM_DATABASE=Racal-Airtech Software Forge Ltd + +acpi:TSG*: + ID_VENDOR_FROM_DATABASE=The Software Group Ltd + +acpi:TSI*: + ID_VENDOR_FROM_DATABASE=TeleVideo Systems + +acpi:TSL*: + ID_VENDOR_FROM_DATABASE=Tottori SANYO Electric Co., Ltd. + +acpi:TSP*: + ID_VENDOR_FROM_DATABASE=U.S. Navy + +acpi:TST*: + ID_VENDOR_FROM_DATABASE=Transtream Inc + +acpi:TSV*: + ID_VENDOR_FROM_DATABASE=TRANSVIDEO + +acpi:TSY*: + ID_VENDOR_FROM_DATABASE=TouchSystems + +acpi:TTA*: + ID_VENDOR_FROM_DATABASE=Topson Technology Co., Ltd. + +acpi:TTB*: + ID_VENDOR_FROM_DATABASE=National Semiconductor Japan Ltd + +acpi:TTC*: + ID_VENDOR_FROM_DATABASE=Telecommunications Techniques Corporation + +acpi:TTE*: + ID_VENDOR_FROM_DATABASE=TTE, Inc. + +acpi:TTI*: + ID_VENDOR_FROM_DATABASE=Trenton Terminals Inc + +acpi:TTK*: + ID_VENDOR_FROM_DATABASE=Totoku Electric Company Ltd + +acpi:TTL*: + ID_VENDOR_FROM_DATABASE=2-Tel B.V. + +acpi:TTS*: + ID_VENDOR_FROM_DATABASE=TechnoTrend Systemtechnik GmbH + +acpi:TTY*: + ID_VENDOR_FROM_DATABASE=TRIDELITY Display Solutions GmbH + +acpi:TUA*: + ID_VENDOR_FROM_DATABASE=T+A elektroakustik GmbH + +acpi:TUT*: + ID_VENDOR_FROM_DATABASE=Tut Systems + +acpi:TVD*: + ID_VENDOR_FROM_DATABASE=Tecnovision + +acpi:TVI*: + ID_VENDOR_FROM_DATABASE=Truevision + +acpi:TVM*: + ID_VENDOR_FROM_DATABASE=Taiwan Video & Monitor Corporation + +acpi:TVO*: + ID_VENDOR_FROM_DATABASE=TV One Ltd + +acpi:TVR*: + ID_VENDOR_FROM_DATABASE=TV Interactive Corporation + +acpi:TVS*: + ID_VENDOR_FROM_DATABASE=TVS Electronics Limited + +acpi:TVV*: + ID_VENDOR_FROM_DATABASE=TV1 GmbH + +acpi:TWA*: + ID_VENDOR_FROM_DATABASE=Tidewater Association + +acpi:TWE*: + ID_VENDOR_FROM_DATABASE=Kontron Electronik + +acpi:TWH*: + ID_VENDOR_FROM_DATABASE=Twinhead International Corporation + +acpi:TWI*: + ID_VENDOR_FROM_DATABASE=Easytel oy + +acpi:TWK*: + ID_VENDOR_FROM_DATABASE=TOWITOKO electronics GmbH + +acpi:TWX*: + ID_VENDOR_FROM_DATABASE=TEKWorx Limited + +acpi:TXL*: + ID_VENDOR_FROM_DATABASE=Trixel Ltd + +acpi:TXN*: + ID_VENDOR_FROM_DATABASE=Texas Insturments + +acpi:TXT*: + ID_VENDOR_FROM_DATABASE=Textron Defense System + +acpi:TYN*: + ID_VENDOR_FROM_DATABASE=Tyan Computer Corporation + +acpi:UAS*: + ID_VENDOR_FROM_DATABASE=Ultima Associates Pte Ltd + +acpi:UBI*: + ID_VENDOR_FROM_DATABASE=Ungermann-Bass Inc + +acpi:UBL*: + ID_VENDOR_FROM_DATABASE=Ubinetics Ltd. + +acpi:UDN*: + ID_VENDOR_FROM_DATABASE=Uniden Corporation + +acpi:UEC*: + ID_VENDOR_FROM_DATABASE=Ultima Electronics Corporation + +acpi:UEG*: + ID_VENDOR_FROM_DATABASE=Elitegroup Computer Systems Company Ltd + +acpi:UEI*: + ID_VENDOR_FROM_DATABASE=Universal Electronics Inc + +acpi:UET*: + ID_VENDOR_FROM_DATABASE=Universal Empowering Technologies + +acpi:UFG*: + ID_VENDOR_FROM_DATABASE=UNIGRAF-USA + +acpi:UFO*: + ID_VENDOR_FROM_DATABASE=UFO Systems Inc + +acpi:UHB*: + ID_VENDOR_FROM_DATABASE=XOCECO + +acpi:UIC*: + ID_VENDOR_FROM_DATABASE=Uniform Industrial Corporation + +acpi:UJR*: + ID_VENDOR_FROM_DATABASE=Ueda Japan Radio Co., Ltd. + +acpi:ULT*: + ID_VENDOR_FROM_DATABASE=Ultra Network Tech + +acpi:UMC*: + ID_VENDOR_FROM_DATABASE=United Microelectr Corporation + +acpi:UMG*: + ID_VENDOR_FROM_DATABASE=Umezawa Giken Co.,Ltd + +acpi:UMM*: + ID_VENDOR_FROM_DATABASE=Universal Multimedia + +acpi:UNA*: + ID_VENDOR_FROM_DATABASE=Unisys DSD + +acpi:UNB*: + ID_VENDOR_FROM_DATABASE=Unisys Corporation + +acpi:UNC*: + ID_VENDOR_FROM_DATABASE=Unisys Corporation + +acpi:UNI*: + ID_VENDOR_FROM_DATABASE=Unisys Corporation + +acpi:UNM*: + ID_VENDOR_FROM_DATABASE=Unisys Corporation + +acpi:UNO*: + ID_VENDOR_FROM_DATABASE=Unisys Corporation + +acpi:UNP*: + ID_VENDOR_FROM_DATABASE=Unitop + +acpi:UNS*: + ID_VENDOR_FROM_DATABASE=Unisys Corporation + +acpi:UNT*: + ID_VENDOR_FROM_DATABASE=Unisys Corporation + +acpi:UNY*: + ID_VENDOR_FROM_DATABASE=Unicate + +acpi:UPP*: + ID_VENDOR_FROM_DATABASE=UPPI + +acpi:UPS*: + ID_VENDOR_FROM_DATABASE=Systems Enhancement + +acpi:URD*: + ID_VENDOR_FROM_DATABASE=Video Computer S.p.A. + +acpi:USA*: + ID_VENDOR_FROM_DATABASE=Utimaco Safeware AG + +acpi:USD*: + ID_VENDOR_FROM_DATABASE=U.S. Digital Corporation + +acpi:USI*: + ID_VENDOR_FROM_DATABASE=Universal Scientific Industrial Co., Ltd. + +acpi:USR*: + ID_VENDOR_FROM_DATABASE=U.S. Robotics Inc + +acpi:UTD*: + ID_VENDOR_FROM_DATABASE=Up to Date Tech + +acpi:UWC*: + ID_VENDOR_FROM_DATABASE=Uniwill Computer Corp. + +acpi:VAL*: + ID_VENDOR_FROM_DATABASE=Valence Computing Corporation + +acpi:VAR*: + ID_VENDOR_FROM_DATABASE=Varian Australia Pty Ltd + +acpi:VBR*: + ID_VENDOR_FROM_DATABASE=VBrick Systems Inc. + +acpi:VBT*: + ID_VENDOR_FROM_DATABASE=Valley Board Ltda + +acpi:VCC*: + ID_VENDOR_FROM_DATABASE=Virtual Computer Corporation + +acpi:VCI*: + ID_VENDOR_FROM_DATABASE=VistaCom Inc + +acpi:VCJ*: + ID_VENDOR_FROM_DATABASE=Victor Company of Japan, Limited + +acpi:VCM*: + ID_VENDOR_FROM_DATABASE=Vector Magnetics, LLC + +acpi:VCX*: + ID_VENDOR_FROM_DATABASE=VCONEX + +acpi:VDA*: + ID_VENDOR_FROM_DATABASE=Victor Data Systems + +acpi:VDC*: + ID_VENDOR_FROM_DATABASE=VDC Display Systems + +acpi:VDM*: + ID_VENDOR_FROM_DATABASE=Vadem + +acpi:VDO*: + ID_VENDOR_FROM_DATABASE=Video & Display Oriented Corporation + +acpi:VDS*: + ID_VENDOR_FROM_DATABASE=Vidisys GmbH & Company + +acpi:VDT*: + ID_VENDOR_FROM_DATABASE=Viditec, Inc. + +acpi:VEC*: + ID_VENDOR_FROM_DATABASE=Vector Informatik GmbH + +acpi:VEK*: + ID_VENDOR_FROM_DATABASE=Vektrex + +acpi:VES*: + ID_VENDOR_FROM_DATABASE=Vestel Elektronik Sanayi ve Ticaret A. S. + +acpi:VFI*: + ID_VENDOR_FROM_DATABASE=VeriFone Inc + +acpi:VHI*: + ID_VENDOR_FROM_DATABASE=Macrocad Development Inc. + +acpi:VIA*: + ID_VENDOR_FROM_DATABASE=VIA Tech Inc + +acpi:VIB*: + ID_VENDOR_FROM_DATABASE=Tatung UK Ltd + +acpi:VIC*: + ID_VENDOR_FROM_DATABASE=Victron B.V. + +acpi:VID*: + ID_VENDOR_FROM_DATABASE=Ingram Macrotron Germany + +acpi:VIK*: + ID_VENDOR_FROM_DATABASE=Viking Connectors + +acpi:VIN*: + ID_VENDOR_FROM_DATABASE=Vine Micros Ltd + +acpi:VIR*: + ID_VENDOR_FROM_DATABASE=Visual Interface, Inc + +acpi:VIS*: + ID_VENDOR_FROM_DATABASE=Visioneer + +acpi:VIT*: + ID_VENDOR_FROM_DATABASE=Visitech AS + +acpi:VIZ*: + ID_VENDOR_FROM_DATABASE=VIZIO, Inc + +acpi:VLB*: + ID_VENDOR_FROM_DATABASE=ValleyBoard Ltda. + +acpi:VLT*: + ID_VENDOR_FROM_DATABASE=VideoLan Technologies + +acpi:VMI*: + ID_VENDOR_FROM_DATABASE=Vermont Microsystems + +acpi:VML*: + ID_VENDOR_FROM_DATABASE=Vine Micros Limited + +acpi:VMW*: + ID_VENDOR_FROM_DATABASE=VMware Inc., + +acpi:VNC*: + ID_VENDOR_FROM_DATABASE=Vinca Corporation + +acpi:VOB*: + ID_VENDOR_FROM_DATABASE=MaxData Computer AG + +acpi:VPI*: + ID_VENDOR_FROM_DATABASE=Video Products Inc + +acpi:VPR*: + ID_VENDOR_FROM_DATABASE=Best Buy + +acpi:VQ@*: + ID_VENDOR_FROM_DATABASE=Vision Quest + +acpi:VRC*: + ID_VENDOR_FROM_DATABASE=Virtual Resources Corporation + +acpi:VSC*: + ID_VENDOR_FROM_DATABASE=ViewSonic Corporation + +acpi:VSD*: + ID_VENDOR_FROM_DATABASE=3M + +acpi:VSI*: + ID_VENDOR_FROM_DATABASE=VideoServer + +acpi:VSN*: + ID_VENDOR_FROM_DATABASE=Ingram Macrotron + +acpi:VSP*: + ID_VENDOR_FROM_DATABASE=Vision Systems GmbH + +acpi:VSR*: + ID_VENDOR_FROM_DATABASE=V-Star Electronics Inc. + +acpi:VTC*: + ID_VENDOR_FROM_DATABASE=VTel Corporation + +acpi:VTG*: + ID_VENDOR_FROM_DATABASE=Voice Technologies Group Inc + +acpi:VTI*: + ID_VENDOR_FROM_DATABASE=VLSI Tech Inc + +acpi:VTK*: + ID_VENDOR_FROM_DATABASE=Viewteck Co., Ltd. + +acpi:VTL*: + ID_VENDOR_FROM_DATABASE=Vivid Technology Pte Ltd + +acpi:VTM*: + ID_VENDOR_FROM_DATABASE=Miltope Corporation + +acpi:VTN*: + ID_VENDOR_FROM_DATABASE=VIDEOTRON CORP. + +acpi:VTS*: + ID_VENDOR_FROM_DATABASE=VTech Computers Ltd + +acpi:VTV*: + ID_VENDOR_FROM_DATABASE=VATIV Technologies + +acpi:VTX*: + ID_VENDOR_FROM_DATABASE=Vestax Corporation + +acpi:VUT*: + ID_VENDOR_FROM_DATABASE=Vutrix (UK) Ltd + +acpi:VWB*: + ID_VENDOR_FROM_DATABASE=Vweb Corp. + +acpi:WAC*: + ID_VENDOR_FROM_DATABASE=Wacom Tech + +acpi:WAL*: + ID_VENDOR_FROM_DATABASE=Wave Access + +acpi:WAV*: + ID_VENDOR_FROM_DATABASE=Wavephore + +acpi:WBN*: + ID_VENDOR_FROM_DATABASE=MicroSoftWare + +acpi:WBS*: + ID_VENDOR_FROM_DATABASE=WB Systemtechnik GmbH + +acpi:WCI*: + ID_VENDOR_FROM_DATABASE=Wisecom Inc + +acpi:WCS*: + ID_VENDOR_FROM_DATABASE=Woodwind Communications Systems Inc + +acpi:WDC*: + ID_VENDOR_FROM_DATABASE=Western Digital + +acpi:WDE*: + ID_VENDOR_FROM_DATABASE=Westinghouse Digital Electronics + +acpi:WEB*: + ID_VENDOR_FROM_DATABASE=WebGear Inc + +acpi:WEC*: + ID_VENDOR_FROM_DATABASE=Winbond Electronics Corporation + +acpi:WEL *: + ID_VENDOR_FROM_DATABASE=W-DEV + +acpi:WEY*: + ID_VENDOR_FROM_DATABASE=WEY Design AG + +acpi:WHI*: + ID_VENDOR_FROM_DATABASE=Whistle Communications + +acpi:WII*: + ID_VENDOR_FROM_DATABASE=Innoware Inc + +acpi:WIL*: + ID_VENDOR_FROM_DATABASE=WIPRO Information Technology Ltd + +acpi:WIN*: + ID_VENDOR_FROM_DATABASE=Wintop Technology Inc + +acpi:WIP*: + ID_VENDOR_FROM_DATABASE=Wipro Infotech + +acpi:WKH*: + ID_VENDOR_FROM_DATABASE=Uni-Take Int'l Inc. + +acpi:WLD*: + ID_VENDOR_FROM_DATABASE=Wildfire Communications Inc + +acpi:WML*: + ID_VENDOR_FROM_DATABASE=Wolfson Microelectronics Ltd + +acpi:WMO*: + ID_VENDOR_FROM_DATABASE=Westermo Teleindustri AB + +acpi:WMT*: + ID_VENDOR_FROM_DATABASE=Winmate Communication Inc + +acpi:WNI*: + ID_VENDOR_FROM_DATABASE=WillNet Inc. + +acpi:WNV*: + ID_VENDOR_FROM_DATABASE=Winnov L.P. + +acpi:WNX*: + ID_VENDOR_FROM_DATABASE=Wincor Nixdorf International GmbH + +acpi:WPA*: + ID_VENDOR_FROM_DATABASE=Matsushita Communication Industrial Co., Ltd. + +acpi:WPI*: + ID_VENDOR_FROM_DATABASE=Wearnes Peripherals International (Pte) Ltd + +acpi:WRC*: + ID_VENDOR_FROM_DATABASE=WiNRADiO Communications + +acpi:WSC*: + ID_VENDOR_FROM_DATABASE=CIS Technology Inc + +acpi:WSP*: + ID_VENDOR_FROM_DATABASE=Wireless And Smart Products Inc. + +acpi:WST*: + ID_VENDOR_FROM_DATABASE=Wistron Corporation + +acpi:WTC*: + ID_VENDOR_FROM_DATABASE=ACC Microelectronics + +acpi:WTI*: + ID_VENDOR_FROM_DATABASE=WorkStation Tech + +acpi:WTK*: + ID_VENDOR_FROM_DATABASE=Wearnes Thakral Pte + +acpi:WTS*: + ID_VENDOR_FROM_DATABASE=Restek Electric Company Ltd + +acpi:WVM*: + ID_VENDOR_FROM_DATABASE=Wave Systems Corporation + +acpi:WWV*: + ID_VENDOR_FROM_DATABASE=World Wide Video, Inc. + +acpi:WXT*: + ID_VENDOR_FROM_DATABASE=Woxter Technology Co. Ltd + +acpi:WYS*: + ID_VENDOR_FROM_DATABASE=Myse Technology + +acpi:WYT*: + ID_VENDOR_FROM_DATABASE=Wooyoung Image & Information Co.,Ltd. + +acpi:XAC*: + ID_VENDOR_FROM_DATABASE=XAC Automation Corp + +acpi:XAD*: + ID_VENDOR_FROM_DATABASE=Alpha Data + +acpi:XDM*: + ID_VENDOR_FROM_DATABASE=XDM Ltd. + +acpi:XFG*: + ID_VENDOR_FROM_DATABASE=Jan Strapko - FOTO + +acpi:XFO*: + ID_VENDOR_FROM_DATABASE=EXFO Electro Optical Engineering + +acpi:XIN*: + ID_VENDOR_FROM_DATABASE=Xinex Networks Inc + +acpi:XIO*: + ID_VENDOR_FROM_DATABASE=Xiotech Corporation + +acpi:XIR*: + ID_VENDOR_FROM_DATABASE=Xirocm Inc + +acpi:XIT*: + ID_VENDOR_FROM_DATABASE=Xitel Pty ltd + +acpi:XLX*: + ID_VENDOR_FROM_DATABASE=Xilinx, Inc. + +acpi:XMM*: + ID_VENDOR_FROM_DATABASE=C3PO S.L. + +acpi:XNT*: + ID_VENDOR_FROM_DATABASE=XN Technologies, Inc. + +acpi:XQU*: + ID_VENDOR_FROM_DATABASE=SHANGHAI SVA-DAV ELECTRONICS CO., LTD + +acpi:XRC*: + ID_VENDOR_FROM_DATABASE=Xircom Inc + +acpi:XRO*: + ID_VENDOR_FROM_DATABASE=XORO ELECTRONICS (CHENGDU) LIMITED + +acpi:XSN*: + ID_VENDOR_FROM_DATABASE=Xscreen AS + +acpi:XST*: + ID_VENDOR_FROM_DATABASE=XS Technologies Inc + +acpi:XSY*: + ID_VENDOR_FROM_DATABASE=XSYS + +acpi:XTD*: + ID_VENDOR_FROM_DATABASE=Icuiti Corporation + +acpi:XTE*: + ID_VENDOR_FROM_DATABASE=X2E GmbH + +acpi:XTL*: + ID_VENDOR_FROM_DATABASE=Crystal Computer + +acpi:XTN*: + ID_VENDOR_FROM_DATABASE=X-10 (USA) Inc + +acpi:XYC*: + ID_VENDOR_FROM_DATABASE=Xycotec Computer GmbH + +acpi:YED*: + ID_VENDOR_FROM_DATABASE=Y-E Data Inc + +acpi:YHQ*: + ID_VENDOR_FROM_DATABASE=Yokogawa Electric Corporation + +acpi:YHW*: + ID_VENDOR_FROM_DATABASE=Exacom SA + +acpi:YMH*: + ID_VENDOR_FROM_DATABASE=Yamaha Corporation + +acpi:YOW*: + ID_VENDOR_FROM_DATABASE=American Biometric Company + +acpi:ZAN*: + ID_VENDOR_FROM_DATABASE=Zandar Technologies plc + +acpi:ZAX*: + ID_VENDOR_FROM_DATABASE=Zefiro Acoustics + +acpi:ZAZ*: + ID_VENDOR_FROM_DATABASE=Zazzle Technologies + +acpi:ZBR*: + ID_VENDOR_FROM_DATABASE=Zebra Technologies International, LLC + +acpi:ZCT*: + ID_VENDOR_FROM_DATABASE=ZeitControl cardsystems GmbH + +acpi:ZDS*: + ID_VENDOR_FROM_DATABASE=Zenith Data Systems + +acpi:ZGT*: + ID_VENDOR_FROM_DATABASE=Zenith Data Systems + +acpi:ZIC*: + ID_VENDOR_FROM_DATABASE=Nationz Technologies Inc. + +acpi:ZMT*: + ID_VENDOR_FROM_DATABASE=Zalman Tech Co., Ltd. + +acpi:ZMZ*: + ID_VENDOR_FROM_DATABASE=Z Microsystems + +acpi:ZNI*: + ID_VENDOR_FROM_DATABASE=Zetinet Inc + +acpi:ZNX*: + ID_VENDOR_FROM_DATABASE=Znyx Adv. Systems + +acpi:ZOW*: + ID_VENDOR_FROM_DATABASE=Zowie Intertainment, Inc + +acpi:ZRN*: + ID_VENDOR_FROM_DATABASE=Zoran Corporation + +acpi:ZSE*: + ID_VENDOR_FROM_DATABASE=Zenith Data Systems + +acpi:ZTC*: + ID_VENDOR_FROM_DATABASE=ZyDAS Technology Corporation + +acpi:ZTE*: + ID_VENDOR_FROM_DATABASE=ZTE Corporation + +acpi:ZTI*: + ID_VENDOR_FROM_DATABASE=Zoom Telephonics Inc + +acpi:ZTM*: + ID_VENDOR_FROM_DATABASE=ZT Group Int'l Inc. + +acpi:ZTT*: + ID_VENDOR_FROM_DATABASE=Z3 Technology + +acpi:ZYD*: + ID_VENDOR_FROM_DATABASE=Zydacron Inc + +acpi:ZYP*: + ID_VENDOR_FROM_DATABASE=Zypcom Inc + +acpi:ZYT*: + ID_VENDOR_FROM_DATABASE=Zytex Computers + +acpi:ZYX*: + ID_VENDOR_FROM_DATABASE=Zyxel + +acpi:ZZZ*: + ID_VENDOR_FROM_DATABASE=Boca Research Inc diff --git a/hwdb/20-bluetooth-vendor-product.hwdb b/hwdb/20-bluetooth-vendor-product.hwdb new file mode 100644 index 000000000..c8cb322d1 --- /dev/null +++ b/hwdb/20-bluetooth-vendor-product.hwdb @@ -0,0 +1,541 @@ +# This file is part of systemd. +# +# Data imported from: +# http://www.bluetooth.org/Technical/AssignedNumbers/identifiers.htm + +bluetooth:v0000* + ID_VENDOR_FROM_DATABASE=Ericsson Technology Licensing + +bluetooth:v0001* + ID_VENDOR_FROM_DATABASE=Nokia Mobile Phones + +bluetooth:v0002* + ID_VENDOR_FROM_DATABASE=Intel Corp. + +bluetooth:v0003* + ID_VENDOR_FROM_DATABASE=IBM Corp. + +bluetooth:v0004* + ID_VENDOR_FROM_DATABASE=Toshiba Corp. + +bluetooth:v0005* + ID_VENDOR_FROM_DATABASE=3Com + +bluetooth:v0006* + ID_VENDOR_FROM_DATABASE=Microsoft + +bluetooth:v0007* + ID_VENDOR_FROM_DATABASE=Lucent + +bluetooth:v0008* + ID_VENDOR_FROM_DATABASE=Motorola + +bluetooth:v0009* + ID_VENDOR_FROM_DATABASE=Infineon Technologies AG + +bluetooth:v000A* + ID_VENDOR_FROM_DATABASE=Cambridge Silicon Radio + +bluetooth:v000B* + ID_VENDOR_FROM_DATABASE=Silicon Wave + +bluetooth:v000C* + ID_VENDOR_FROM_DATABASE=Digianswer A/S + +bluetooth:v000D* + ID_VENDOR_FROM_DATABASE=Texas Instruments Inc. + +bluetooth:v000E* + ID_VENDOR_FROM_DATABASE=Ceva, Inc. (formerly Parthus Technologies Inc.) + +bluetooth:v000F* + ID_VENDOR_FROM_DATABASE=Broadcom Corporation + +bluetooth:v0010* + ID_VENDOR_FROM_DATABASE=Mitel Semiconductor + +bluetooth:v0011* + ID_VENDOR_FROM_DATABASE=Widcomm, Inc. + +bluetooth:v0012* + ID_VENDOR_FROM_DATABASE=Zeevo, Inc. + +bluetooth:v0013* + ID_VENDOR_FROM_DATABASE=Atmel Corporation + +bluetooth:v0014* + ID_VENDOR_FROM_DATABASE=Mitsubishi Electric Corporation + +bluetooth:v0015* + ID_VENDOR_FROM_DATABASE=RTX Telecom A/S + +bluetooth:v0016* + ID_VENDOR_FROM_DATABASE=KC Technology Inc. + +bluetooth:v0017* + ID_VENDOR_FROM_DATABASE=Newlogic + +bluetooth:v0018* + ID_VENDOR_FROM_DATABASE=Transilica, Inc. + +bluetooth:v0019* + ID_VENDOR_FROM_DATABASE=Rohde & Schwartz GmbH & Co. KG + +bluetooth:v001A* + ID_VENDOR_FROM_DATABASE=TTPCom Limited + +bluetooth:v001B* + ID_VENDOR_FROM_DATABASE=Signia Technologies, Inc. + +bluetooth:v001C* + ID_VENDOR_FROM_DATABASE=Conexant Systems Inc. + +bluetooth:v001D* + ID_VENDOR_FROM_DATABASE=Qualcomm + +bluetooth:v001E* + ID_VENDOR_FROM_DATABASE=Inventel + +bluetooth:v001F* + ID_VENDOR_FROM_DATABASE=AVM Berlin + +bluetooth:v0020* + ID_VENDOR_FROM_DATABASE=BandSpeed, Inc. + +bluetooth:v0021* + ID_VENDOR_FROM_DATABASE=Mansella Ltd + +bluetooth:v0022* + ID_VENDOR_FROM_DATABASE=NEC Corporation + +bluetooth:v0023* + ID_VENDOR_FROM_DATABASE=WavePlus Technology Co., Ltd. + +bluetooth:v0024* + ID_VENDOR_FROM_DATABASE=Alcatel + +bluetooth:v0025* + ID_VENDOR_FROM_DATABASE=Philips Semiconductors + +bluetooth:v0026* + ID_VENDOR_FROM_DATABASE=C Technologies + +bluetooth:v0027* + ID_VENDOR_FROM_DATABASE=Open Interface + +bluetooth:v0028* + ID_VENDOR_FROM_DATABASE=R F Micro Devices + +bluetooth:v0029* + ID_VENDOR_FROM_DATABASE=Hitachi Ltd + +bluetooth:v002A* + ID_VENDOR_FROM_DATABASE=Symbol Technologies, Inc. + +bluetooth:v002B* + ID_VENDOR_FROM_DATABASE=Tenovis + +bluetooth:v002C* + ID_VENDOR_FROM_DATABASE=Macronix International Co. Ltd. + +bluetooth:v002D* + ID_VENDOR_FROM_DATABASE=GCT Semiconductor + +bluetooth:v002E* + ID_VENDOR_FROM_DATABASE=Norwood Systems + +bluetooth:v002F* + ID_VENDOR_FROM_DATABASE=MewTel Technology Inc. + +bluetooth:v0030* + ID_VENDOR_FROM_DATABASE=ST Microelectronics + +bluetooth:v0031* + ID_VENDOR_FROM_DATABASE=Synopsys + +bluetooth:v0032* + ID_VENDOR_FROM_DATABASE=Red-M (Communications) Ltd + +bluetooth:v0033* + ID_VENDOR_FROM_DATABASE=Commil Ltd + +bluetooth:v0034* + ID_VENDOR_FROM_DATABASE=Computer Access Technology Corporation (CATC) + +bluetooth:v0035* + ID_VENDOR_FROM_DATABASE=Eclipse (HQ Espana) S.L. + +bluetooth:v0036* + ID_VENDOR_FROM_DATABASE=Renesas Technology Corp. + +bluetooth:v0037* + ID_VENDOR_FROM_DATABASE=Mobilian Corporation + +bluetooth:v0038* + ID_VENDOR_FROM_DATABASE=Terax + +bluetooth:v0039* + ID_VENDOR_FROM_DATABASE=Integrated System Solution Corp. + +bluetooth:v003A* + ID_VENDOR_FROM_DATABASE=Matsushita Electric Industrial Co., Ltd. + +bluetooth:v003B* + ID_VENDOR_FROM_DATABASE=Gennum Corporation + +bluetooth:v003C* + ID_VENDOR_FROM_DATABASE=Research In Motion + +bluetooth:v003D* + ID_VENDOR_FROM_DATABASE=IPextreme, Inc. + +bluetooth:v003E* + ID_VENDOR_FROM_DATABASE=Systems and Chips, Inc + +bluetooth:v003F* + ID_VENDOR_FROM_DATABASE=Bluetooth SIG, Inc + +bluetooth:v0040* + ID_VENDOR_FROM_DATABASE=Seiko Epson Corporation + +bluetooth:v0041* + ID_VENDOR_FROM_DATABASE=Integrated Silicon Solution Taiwain, Inc. + +bluetooth:v0042* + ID_VENDOR_FROM_DATABASE=CONWISE Technology Corporation Ltd + +bluetooth:v0043* + ID_VENDOR_FROM_DATABASE=PARROT SA + +bluetooth:v0044* + ID_VENDOR_FROM_DATABASE=Socket Mobile + +bluetooth:v0045* + ID_VENDOR_FROM_DATABASE=Atheros Communications, Inc. + +bluetooth:v0046* + ID_VENDOR_FROM_DATABASE=MediaTek, Inc. + +bluetooth:v0047* + ID_VENDOR_FROM_DATABASE=Bluegiga + +bluetooth:v0048* + ID_VENDOR_FROM_DATABASE=Marvell Technology Group Ltd. + +bluetooth:v0049* + ID_VENDOR_FROM_DATABASE=3DSP Corporation + +bluetooth:v004A* + ID_VENDOR_FROM_DATABASE=Accel Semiconductor Ltd. + +bluetooth:v004B* + ID_VENDOR_FROM_DATABASE=Continental Automotive Systems + +bluetooth:v004C* + ID_VENDOR_FROM_DATABASE=Apple, Inc. + +bluetooth:v004D* + ID_VENDOR_FROM_DATABASE=Staccato Communications, Inc. + +bluetooth:v004E* + ID_VENDOR_FROM_DATABASE=Avago Technologies + +bluetooth:v004F* + ID_VENDOR_FROM_DATABASE=APT Licensing Ltd. + +bluetooth:v0050* + ID_VENDOR_FROM_DATABASE=SiRF Technology, Inc. + +bluetooth:v0051* + ID_VENDOR_FROM_DATABASE=Tzero Technologies, Inc. + +bluetooth:v0052* + ID_VENDOR_FROM_DATABASE=J&M Corporation + +bluetooth:v0053* + ID_VENDOR_FROM_DATABASE=Free2move AB + +bluetooth:v0054* + ID_VENDOR_FROM_DATABASE=3DiJoy Corporation + +bluetooth:v0055* + ID_VENDOR_FROM_DATABASE=Plantronics, Inc. + +bluetooth:v0056* + ID_VENDOR_FROM_DATABASE=Sony Ericsson Mobile Communications + +bluetooth:v0057* + ID_VENDOR_FROM_DATABASE=Harman International Industries, Inc. + +bluetooth:v0058* + ID_VENDOR_FROM_DATABASE=Vizio, Inc. + +bluetooth:v0059* + ID_VENDOR_FROM_DATABASE=Nordic Semiconductor ASA + +bluetooth:v005A* + ID_VENDOR_FROM_DATABASE=EM Microelectronic-Marin SA + +bluetooth:v005B* + ID_VENDOR_FROM_DATABASE=Ralink Technology Corporation + +bluetooth:v005C* + ID_VENDOR_FROM_DATABASE=Belkin International, Inc. + +bluetooth:v005D* + ID_VENDOR_FROM_DATABASE=Realtek Semiconductor Corporation + +bluetooth:v005E* + ID_VENDOR_FROM_DATABASE=Stonestreet One, LLC + +bluetooth:v005F* + ID_VENDOR_FROM_DATABASE=Wicentric, Inc. + +bluetooth:v0060* + ID_VENDOR_FROM_DATABASE=RivieraWaves S.A.S + +bluetooth:v0061* + ID_VENDOR_FROM_DATABASE=RDA Microelectronics + +bluetooth:v0062* + ID_VENDOR_FROM_DATABASE=Gibson Guitars + +bluetooth:v0063* + ID_VENDOR_FROM_DATABASE=MiCommand Inc. + +bluetooth:v0064* + ID_VENDOR_FROM_DATABASE=Band XI International, LLC + +bluetooth:v0065* + ID_VENDOR_FROM_DATABASE=Hewlett-Packard Company + +bluetooth:v0066* + ID_VENDOR_FROM_DATABASE=9Solutions Oy + +bluetooth:v0067* + ID_VENDOR_FROM_DATABASE=GN Netcom A/S + +bluetooth:v0068* + ID_VENDOR_FROM_DATABASE=General Motors + +bluetooth:v0069* + ID_VENDOR_FROM_DATABASE=A&D Engineering, Inc. + +bluetooth:v006A* + ID_VENDOR_FROM_DATABASE=MindTree Ltd. + +bluetooth:v006B* + ID_VENDOR_FROM_DATABASE=Polar Electro OY + +bluetooth:v006C* + ID_VENDOR_FROM_DATABASE=Beautiful Enterprise Co., Ltd. + +bluetooth:v006D* + ID_VENDOR_FROM_DATABASE=BriarTek, Inc. + +bluetooth:v006E* + ID_VENDOR_FROM_DATABASE=Summit Data Communications, Inc. + +bluetooth:v006F* + ID_VENDOR_FROM_DATABASE=Sound ID + +bluetooth:v0070* + ID_VENDOR_FROM_DATABASE=Monster, LLC + +bluetooth:v0071* + ID_VENDOR_FROM_DATABASE=connectBlue AB + +bluetooth:v0072* + ID_VENDOR_FROM_DATABASE=ShangHai Super Smart Electronics Co. Ltd. + +bluetooth:v0073* + ID_VENDOR_FROM_DATABASE=Group Sense Ltd. + +bluetooth:v0074* + ID_VENDOR_FROM_DATABASE=Zomm, LLC + +bluetooth:v0075* + ID_VENDOR_FROM_DATABASE=Samsung Electronics Co. Ltd. + +bluetooth:v0076* + ID_VENDOR_FROM_DATABASE=Creative Technology Ltd. + +bluetooth:v0077* + ID_VENDOR_FROM_DATABASE=Laird Technologies + +bluetooth:v0078* + ID_VENDOR_FROM_DATABASE=Nike, Inc. + +bluetooth:v0079* + ID_VENDOR_FROM_DATABASE=lesswire AG + +bluetooth:v007A* + ID_VENDOR_FROM_DATABASE=MStar Semiconductor, Inc. + +bluetooth:v007B* + ID_VENDOR_FROM_DATABASE=Hanlynn Technologies + +bluetooth:v007C* + ID_VENDOR_FROM_DATABASE=A & R Cambridge + +bluetooth:v007D* + ID_VENDOR_FROM_DATABASE=Seers Technology Co. Ltd. + +bluetooth:v007E* + ID_VENDOR_FROM_DATABASE=Sports Tracking Technologies Ltd. + +bluetooth:v007F* + ID_VENDOR_FROM_DATABASE=Autonet Mobile + +bluetooth:v0080* + ID_VENDOR_FROM_DATABASE=DeLorme Publishing Company, Inc. + +bluetooth:v0081* + ID_VENDOR_FROM_DATABASE=WuXi Vimicro + +bluetooth:v0082* + ID_VENDOR_FROM_DATABASE=Sennheiser Communications A/S + +bluetooth:v0083* + ID_VENDOR_FROM_DATABASE=TimeKeeping Systems, Inc. + +bluetooth:v0084* + ID_VENDOR_FROM_DATABASE=Ludus Helsinki Ltd. + +bluetooth:v0085* + ID_VENDOR_FROM_DATABASE=BlueRadios, Inc. + +bluetooth:v0086* + ID_VENDOR_FROM_DATABASE=equinux AG + +bluetooth:v0087* + ID_VENDOR_FROM_DATABASE=Garmin International, Inc. + +bluetooth:v0088* + ID_VENDOR_FROM_DATABASE=Ecotest + +bluetooth:v0089* + ID_VENDOR_FROM_DATABASE=GN ReSound A/S + +bluetooth:v008A* + ID_VENDOR_FROM_DATABASE=Jawbone + +bluetooth:v008B* + ID_VENDOR_FROM_DATABASE=Topcon Positioning Systems, LLC + +bluetooth:v008C* + ID_VENDOR_FROM_DATABASE=Qualcomm Labs, Inc. + +bluetooth:v008D* + ID_VENDOR_FROM_DATABASE=Zscan Software + +bluetooth:v008E* + ID_VENDOR_FROM_DATABASE=Quintic Corp. + +bluetooth:v008F* + ID_VENDOR_FROM_DATABASE=Stollmann E+V GmbH + +bluetooth:v0090* + ID_VENDOR_FROM_DATABASE=Funai Electric Co., Ltd. + +bluetooth:v0091* + ID_VENDOR_FROM_DATABASE=Advanced PANMOBIL systems GmbH & Co. KG + +bluetooth:v0092* + ID_VENDOR_FROM_DATABASE=ThinkOptics, Inc. + +bluetooth:v0093* + ID_VENDOR_FROM_DATABASE=Universal Electronics, Inc. + +bluetooth:v0094* + ID_VENDOR_FROM_DATABASE=Airoha Technology Corp. + +bluetooth:v0095* + ID_VENDOR_FROM_DATABASE=NEC Lighting, Ltd. + +bluetooth:v0096* + ID_VENDOR_FROM_DATABASE=ODM Technology, Inc. + +bluetooth:v0097* + ID_VENDOR_FROM_DATABASE=Bluetrek Technologies Limited + +bluetooth:v0098* + ID_VENDOR_FROM_DATABASE=zero1.tv GmbH + +bluetooth:v0099* + ID_VENDOR_FROM_DATABASE=i.Tech Dynamic Global Distribution Ltd. + +bluetooth:v009A* + ID_VENDOR_FROM_DATABASE=Alpwise + +bluetooth:v009B* + ID_VENDOR_FROM_DATABASE=Jiangsu Toppower Automotive Electronics Co., Ltd. + +bluetooth:v009C* + ID_VENDOR_FROM_DATABASE=Colorfy, Inc. + +bluetooth:v009D* + ID_VENDOR_FROM_DATABASE=Geoforce Inc. + +bluetooth:v009E* + ID_VENDOR_FROM_DATABASE=Bose Corporation + +bluetooth:v009F* + ID_VENDOR_FROM_DATABASE=Suunto Oy + +bluetooth:v00A0* + ID_VENDOR_FROM_DATABASE=Kensington Computer Products Group + +bluetooth:v00A1* + ID_VENDOR_FROM_DATABASE=SR-Medizinelektronik + +bluetooth:v00A2* + ID_VENDOR_FROM_DATABASE=Vertu Corporation Limited + +bluetooth:v00A3* + ID_VENDOR_FROM_DATABASE=Meta Watch Ltd. + +bluetooth:v00A4* + ID_VENDOR_FROM_DATABASE=LINAK A/S + +bluetooth:v00A5* + ID_VENDOR_FROM_DATABASE=OTL Dynamics LLC + +bluetooth:v00A6* + ID_VENDOR_FROM_DATABASE=Panda Ocean Inc. + +bluetooth:v00A7* + ID_VENDOR_FROM_DATABASE=Visteon Corporation + +bluetooth:v00A8* + ID_VENDOR_FROM_DATABASE=ARP Devices Limited + +bluetooth:v00A9* + ID_VENDOR_FROM_DATABASE=Magneti Marelli S.p.A. + +bluetooth:v00AA* + ID_VENDOR_FROM_DATABASE=CAEN RFID srl + +bluetooth:v00AB* + ID_VENDOR_FROM_DATABASE=Ingenieur-Systemgruppe Zahn GmbH + +bluetooth:v00AC* + ID_VENDOR_FROM_DATABASE=Green Throttle Games + +bluetooth:v00AD* + ID_VENDOR_FROM_DATABASE=Peter Systemtechnik GmbH + +bluetooth:v00AE* + ID_VENDOR_FROM_DATABASE=Omegawave Oy + +bluetooth:v00AF* + ID_VENDOR_FROM_DATABASE=Cinetix + +bluetooth:v00B0* + ID_VENDOR_FROM_DATABASE=Passif Semiconductor Corp + +bluetooth:v00B1* + ID_VENDOR_FROM_DATABASE=Saris Cycling Group, Inc + +bluetooth:v00B2* + ID_VENDOR_FROM_DATABASE=Bekey A/S diff --git a/hwdb/20-pci-classes.hwdb b/hwdb/20-pci-classes.hwdb new file mode 100644 index 000000000..fd1d5d0c6 --- /dev/null +++ b/hwdb/20-pci-classes.hwdb @@ -0,0 +1,531 @@ +# This file is part of systemd. +# +# Data imported from: http://pci-ids.ucw.cz/v2.2/pci.ids + +pci:v*d*sv*sd*bc00* + ID_PCI_CLASS_FROM_DATABASE=Unclassified device + +pci:v*d*sv*sd*bc00sc00* + ID_PCI_SUBCLASS_FROM_DATABASE=Non-VGA unclassified device + +pci:v*d*sv*sd*bc00sc01* + ID_PCI_SUBCLASS_FROM_DATABASE=VGA compatible unclassified device + +pci:v*d*sv*sd*bc01* + ID_PCI_CLASS_FROM_DATABASE=Mass storage controller + +pci:v*d*sv*sd*bc01sc00* + ID_PCI_SUBCLASS_FROM_DATABASE=SCSI storage controller + +pci:v*d*sv*sd*bc01sc01* + ID_PCI_SUBCLASS_FROM_DATABASE=IDE interface + +pci:v*d*sv*sd*bc01sc02* + ID_PCI_SUBCLASS_FROM_DATABASE=Floppy disk controller + +pci:v*d*sv*sd*bc01sc03* + ID_PCI_SUBCLASS_FROM_DATABASE=IPI bus controller + +pci:v*d*sv*sd*bc01sc04* + ID_PCI_SUBCLASS_FROM_DATABASE=RAID bus controller + +pci:v*d*sv*sd*bc01sc05* + ID_PCI_SUBCLASS_FROM_DATABASE=ATA controller + +pci:v*d*sv*sd*bc01sc05i20* + ID_PCI_INTERFACE_FROM_DATABASE=ADMA single stepping + +pci:v*d*sv*sd*bc01sc05i30* + ID_PCI_INTERFACE_FROM_DATABASE=ADMA continuous operation + +pci:v*d*sv*sd*bc01sc06* + ID_PCI_SUBCLASS_FROM_DATABASE=SATA controller + +pci:v*d*sv*sd*bc01sc06i00* + ID_PCI_INTERFACE_FROM_DATABASE=Vendor specific + +pci:v*d*sv*sd*bc01sc06i01* + ID_PCI_INTERFACE_FROM_DATABASE=AHCI 1.0 + +pci:v*d*sv*sd*bc01sc07* + ID_PCI_SUBCLASS_FROM_DATABASE=Serial Attached SCSI controller + +pci:v*d*sv*sd*bc01sc08* + ID_PCI_SUBCLASS_FROM_DATABASE=Non-Volatile memory controller + +pci:v*d*sv*sd*bc01sc80* + ID_PCI_SUBCLASS_FROM_DATABASE=Mass storage controller + +pci:v*d*sv*sd*bc02* + ID_PCI_CLASS_FROM_DATABASE=Network controller + +pci:v*d*sv*sd*bc02sc00* + ID_PCI_SUBCLASS_FROM_DATABASE=Ethernet controller + +pci:v*d*sv*sd*bc02sc01* + ID_PCI_SUBCLASS_FROM_DATABASE=Token ring network controller + +pci:v*d*sv*sd*bc02sc02* + ID_PCI_SUBCLASS_FROM_DATABASE=FDDI network controller + +pci:v*d*sv*sd*bc02sc03* + ID_PCI_SUBCLASS_FROM_DATABASE=ATM network controller + +pci:v*d*sv*sd*bc02sc04* + ID_PCI_SUBCLASS_FROM_DATABASE=ISDN controller + +pci:v*d*sv*sd*bc02sc05* + ID_PCI_SUBCLASS_FROM_DATABASE=WorldFip controller + +pci:v*d*sv*sd*bc02sc06* + ID_PCI_SUBCLASS_FROM_DATABASE=PICMG controller + +pci:v*d*sv*sd*bc02sc80* + ID_PCI_SUBCLASS_FROM_DATABASE=Network controller + +pci:v*d*sv*sd*bc03* + ID_PCI_CLASS_FROM_DATABASE=Display controller + +pci:v*d*sv*sd*bc03sc00* + ID_PCI_SUBCLASS_FROM_DATABASE=VGA compatible controller + +pci:v*d*sv*sd*bc03sc00i00* + ID_PCI_INTERFACE_FROM_DATABASE=VGA controller + +pci:v*d*sv*sd*bc03sc00i01* + ID_PCI_INTERFACE_FROM_DATABASE=8514 controller + +pci:v*d*sv*sd*bc03sc01* + ID_PCI_SUBCLASS_FROM_DATABASE=XGA compatible controller + +pci:v*d*sv*sd*bc03sc02* + ID_PCI_SUBCLASS_FROM_DATABASE=3D controller + +pci:v*d*sv*sd*bc03sc80* + ID_PCI_SUBCLASS_FROM_DATABASE=Display controller + +pci:v*d*sv*sd*bc04* + ID_PCI_CLASS_FROM_DATABASE=Multimedia controller + +pci:v*d*sv*sd*bc04sc00* + ID_PCI_SUBCLASS_FROM_DATABASE=Multimedia video controller + +pci:v*d*sv*sd*bc04sc01* + ID_PCI_SUBCLASS_FROM_DATABASE=Multimedia audio controller + +pci:v*d*sv*sd*bc04sc02* + ID_PCI_SUBCLASS_FROM_DATABASE=Computer telephony device + +pci:v*d*sv*sd*bc04sc03* + ID_PCI_SUBCLASS_FROM_DATABASE=Audio device + +pci:v*d*sv*sd*bc04sc80* + ID_PCI_SUBCLASS_FROM_DATABASE=Multimedia controller + +pci:v*d*sv*sd*bc05* + ID_PCI_CLASS_FROM_DATABASE=Memory controller + +pci:v*d*sv*sd*bc05sc00* + ID_PCI_SUBCLASS_FROM_DATABASE=RAM memory + +pci:v*d*sv*sd*bc05sc01* + ID_PCI_SUBCLASS_FROM_DATABASE=FLASH memory + +pci:v*d*sv*sd*bc05sc80* + ID_PCI_SUBCLASS_FROM_DATABASE=Memory controller + +pci:v*d*sv*sd*bc06* + ID_PCI_CLASS_FROM_DATABASE=Bridge + +pci:v*d*sv*sd*bc06sc00* + ID_PCI_SUBCLASS_FROM_DATABASE=Host bridge + +pci:v*d*sv*sd*bc06sc01* + ID_PCI_SUBCLASS_FROM_DATABASE=ISA bridge + +pci:v*d*sv*sd*bc06sc02* + ID_PCI_SUBCLASS_FROM_DATABASE=EISA bridge + +pci:v*d*sv*sd*bc06sc03* + ID_PCI_SUBCLASS_FROM_DATABASE=MicroChannel bridge + +pci:v*d*sv*sd*bc06sc04* + ID_PCI_SUBCLASS_FROM_DATABASE=PCI bridge + +pci:v*d*sv*sd*bc06sc04i00* + ID_PCI_INTERFACE_FROM_DATABASE=Normal decode + +pci:v*d*sv*sd*bc06sc04i01* + ID_PCI_INTERFACE_FROM_DATABASE=Subtractive decode + +pci:v*d*sv*sd*bc06sc05* + ID_PCI_SUBCLASS_FROM_DATABASE=PCMCIA bridge + +pci:v*d*sv*sd*bc06sc06* + ID_PCI_SUBCLASS_FROM_DATABASE=NuBus bridge + +pci:v*d*sv*sd*bc06sc07* + ID_PCI_SUBCLASS_FROM_DATABASE=CardBus bridge + +pci:v*d*sv*sd*bc06sc08* + ID_PCI_SUBCLASS_FROM_DATABASE=RACEway bridge + +pci:v*d*sv*sd*bc06sc08i00* + ID_PCI_INTERFACE_FROM_DATABASE=Transparent mode + +pci:v*d*sv*sd*bc06sc08i01* + ID_PCI_INTERFACE_FROM_DATABASE=Endpoint mode + +pci:v*d*sv*sd*bc06sc09* + ID_PCI_SUBCLASS_FROM_DATABASE=Semi-transparent PCI-to-PCI bridge + +pci:v*d*sv*sd*bc06sc09i40* + ID_PCI_INTERFACE_FROM_DATABASE=Primary bus towards host CPU + +pci:v*d*sv*sd*bc06sc09i80* + ID_PCI_INTERFACE_FROM_DATABASE=Secondary bus towards host CPU + +pci:v*d*sv*sd*bc06sc0A* + ID_PCI_SUBCLASS_FROM_DATABASE=InfiniBand to PCI host bridge + +pci:v*d*sv*sd*bc06sc80* + ID_PCI_SUBCLASS_FROM_DATABASE=Bridge + +pci:v*d*sv*sd*bc07* + ID_PCI_CLASS_FROM_DATABASE=Communication controller + +pci:v*d*sv*sd*bc07sc00* + ID_PCI_SUBCLASS_FROM_DATABASE=Serial controller + +pci:v*d*sv*sd*bc07sc00i00* + ID_PCI_INTERFACE_FROM_DATABASE=8250 + +pci:v*d*sv*sd*bc07sc00i01* + ID_PCI_INTERFACE_FROM_DATABASE=16450 + +pci:v*d*sv*sd*bc07sc00i02* + ID_PCI_INTERFACE_FROM_DATABASE=16550 + +pci:v*d*sv*sd*bc07sc00i03* + ID_PCI_INTERFACE_FROM_DATABASE=16650 + +pci:v*d*sv*sd*bc07sc00i04* + ID_PCI_INTERFACE_FROM_DATABASE=16750 + +pci:v*d*sv*sd*bc07sc00i05* + ID_PCI_INTERFACE_FROM_DATABASE=16850 + +pci:v*d*sv*sd*bc07sc00i06* + ID_PCI_INTERFACE_FROM_DATABASE=16950 + +pci:v*d*sv*sd*bc07sc01* + ID_PCI_SUBCLASS_FROM_DATABASE=Parallel controller + +pci:v*d*sv*sd*bc07sc01i00* + ID_PCI_INTERFACE_FROM_DATABASE=SPP + +pci:v*d*sv*sd*bc07sc01i01* + ID_PCI_INTERFACE_FROM_DATABASE=BiDir + +pci:v*d*sv*sd*bc07sc01i02* + ID_PCI_INTERFACE_FROM_DATABASE=ECP + +pci:v*d*sv*sd*bc07sc01i03* + ID_PCI_INTERFACE_FROM_DATABASE=IEEE1284 + +pci:v*d*sv*sd*bc07sc01iFE* + ID_PCI_INTERFACE_FROM_DATABASE=IEEE1284 Target + +pci:v*d*sv*sd*bc07sc02* + ID_PCI_SUBCLASS_FROM_DATABASE=Multiport serial controller + +pci:v*d*sv*sd*bc07sc03* + ID_PCI_SUBCLASS_FROM_DATABASE=Modem + +pci:v*d*sv*sd*bc07sc03i00* + ID_PCI_INTERFACE_FROM_DATABASE=Generic + +pci:v*d*sv*sd*bc07sc03i01* + ID_PCI_INTERFACE_FROM_DATABASE=Hayes/16450 + +pci:v*d*sv*sd*bc07sc03i02* + ID_PCI_INTERFACE_FROM_DATABASE=Hayes/16550 + +pci:v*d*sv*sd*bc07sc03i03* + ID_PCI_INTERFACE_FROM_DATABASE=Hayes/16650 + +pci:v*d*sv*sd*bc07sc03i04* + ID_PCI_INTERFACE_FROM_DATABASE=Hayes/16750 + +pci:v*d*sv*sd*bc07sc04* + ID_PCI_SUBCLASS_FROM_DATABASE=GPIB controller + +pci:v*d*sv*sd*bc07sc05* + ID_PCI_SUBCLASS_FROM_DATABASE=Smard Card controller + +pci:v*d*sv*sd*bc07sc80* + ID_PCI_SUBCLASS_FROM_DATABASE=Communication controller + +pci:v*d*sv*sd*bc08* + ID_PCI_CLASS_FROM_DATABASE=Generic system peripheral + +pci:v*d*sv*sd*bc08sc00* + ID_PCI_SUBCLASS_FROM_DATABASE=PIC + +pci:v*d*sv*sd*bc08sc00i00* + ID_PCI_INTERFACE_FROM_DATABASE=8259 + +pci:v*d*sv*sd*bc08sc00i01* + ID_PCI_INTERFACE_FROM_DATABASE=ISA PIC + +pci:v*d*sv*sd*bc08sc00i02* + ID_PCI_INTERFACE_FROM_DATABASE=EISA PIC + +pci:v*d*sv*sd*bc08sc00i10* + ID_PCI_INTERFACE_FROM_DATABASE=IO-APIC + +pci:v*d*sv*sd*bc08sc00i20* + ID_PCI_INTERFACE_FROM_DATABASE=IO(X)-APIC + +pci:v*d*sv*sd*bc08sc01* + ID_PCI_SUBCLASS_FROM_DATABASE=DMA controller + +pci:v*d*sv*sd*bc08sc01i00* + ID_PCI_INTERFACE_FROM_DATABASE=8237 + +pci:v*d*sv*sd*bc08sc01i01* + ID_PCI_INTERFACE_FROM_DATABASE=ISA DMA + +pci:v*d*sv*sd*bc08sc01i02* + ID_PCI_INTERFACE_FROM_DATABASE=EISA DMA + +pci:v*d*sv*sd*bc08sc02* + ID_PCI_SUBCLASS_FROM_DATABASE=Timer + +pci:v*d*sv*sd*bc08sc02i00* + ID_PCI_INTERFACE_FROM_DATABASE=8254 + +pci:v*d*sv*sd*bc08sc02i01* + ID_PCI_INTERFACE_FROM_DATABASE=ISA Timer + +pci:v*d*sv*sd*bc08sc02i02* + ID_PCI_INTERFACE_FROM_DATABASE=EISA Timers + +pci:v*d*sv*sd*bc08sc03* + ID_PCI_SUBCLASS_FROM_DATABASE=RTC + +pci:v*d*sv*sd*bc08sc03i00* + ID_PCI_INTERFACE_FROM_DATABASE=Generic + +pci:v*d*sv*sd*bc08sc03i01* + ID_PCI_INTERFACE_FROM_DATABASE=ISA RTC + +pci:v*d*sv*sd*bc08sc04* + ID_PCI_SUBCLASS_FROM_DATABASE=PCI Hot-plug controller + +pci:v*d*sv*sd*bc08sc05* + ID_PCI_SUBCLASS_FROM_DATABASE=SD Host controller + +pci:v*d*sv*sd*bc08sc06* + ID_PCI_SUBCLASS_FROM_DATABASE=IOMMU + +pci:v*d*sv*sd*bc08sc80* + ID_PCI_SUBCLASS_FROM_DATABASE=System peripheral + +pci:v*d*sv*sd*bc09* + ID_PCI_CLASS_FROM_DATABASE=Input device controller + +pci:v*d*sv*sd*bc09sc00* + ID_PCI_SUBCLASS_FROM_DATABASE=Keyboard controller + +pci:v*d*sv*sd*bc09sc01* + ID_PCI_SUBCLASS_FROM_DATABASE=Digitizer Pen + +pci:v*d*sv*sd*bc09sc02* + ID_PCI_SUBCLASS_FROM_DATABASE=Mouse controller + +pci:v*d*sv*sd*bc09sc03* + ID_PCI_SUBCLASS_FROM_DATABASE=Scanner controller + +pci:v*d*sv*sd*bc09sc04* + ID_PCI_SUBCLASS_FROM_DATABASE=Gameport controller + +pci:v*d*sv*sd*bc09sc04i00* + ID_PCI_INTERFACE_FROM_DATABASE=Generic + +pci:v*d*sv*sd*bc09sc04i10* + ID_PCI_INTERFACE_FROM_DATABASE=Extended + +pci:v*d*sv*sd*bc09sc80* + ID_PCI_SUBCLASS_FROM_DATABASE=Input device controller + +pci:v*d*sv*sd*bc0A* + ID_PCI_CLASS_FROM_DATABASE=Docking station + +pci:v*d*sv*sd*bc0Asc00* + ID_PCI_SUBCLASS_FROM_DATABASE=Generic Docking Station + +pci:v*d*sv*sd*bc0Asc80* + ID_PCI_SUBCLASS_FROM_DATABASE=Docking Station + +pci:v*d*sv*sd*bc0B* + ID_PCI_CLASS_FROM_DATABASE=Processor + +pci:v*d*sv*sd*bc0Bsc00* + ID_PCI_SUBCLASS_FROM_DATABASE=386 + +pci:v*d*sv*sd*bc0Bsc01* + ID_PCI_SUBCLASS_FROM_DATABASE=486 + +pci:v*d*sv*sd*bc0Bsc02* + ID_PCI_SUBCLASS_FROM_DATABASE=Pentium + +pci:v*d*sv*sd*bc0Bsc10* + ID_PCI_SUBCLASS_FROM_DATABASE=Alpha + +pci:v*d*sv*sd*bc0Bsc20* + ID_PCI_SUBCLASS_FROM_DATABASE=Power PC + +pci:v*d*sv*sd*bc0Bsc30* + ID_PCI_SUBCLASS_FROM_DATABASE=MIPS + +pci:v*d*sv*sd*bc0Bsc40* + ID_PCI_SUBCLASS_FROM_DATABASE=Co-processor + +pci:v*d*sv*sd*bc0C* + ID_PCI_CLASS_FROM_DATABASE=Serial bus controller + +pci:v*d*sv*sd*bc0Csc00* + ID_PCI_SUBCLASS_FROM_DATABASE=FireWire (IEEE 1394) + +pci:v*d*sv*sd*bc0Csc00i00* + ID_PCI_INTERFACE_FROM_DATABASE=Generic + +pci:v*d*sv*sd*bc0Csc00i10* + ID_PCI_INTERFACE_FROM_DATABASE=OHCI + +pci:v*d*sv*sd*bc0Csc01* + ID_PCI_SUBCLASS_FROM_DATABASE=ACCESS Bus + +pci:v*d*sv*sd*bc0Csc02* + ID_PCI_SUBCLASS_FROM_DATABASE=SSA + +pci:v*d*sv*sd*bc0Csc03* + ID_PCI_SUBCLASS_FROM_DATABASE=USB controller + +pci:v*d*sv*sd*bc0Csc03i00* + ID_PCI_INTERFACE_FROM_DATABASE=UHCI + +pci:v*d*sv*sd*bc0Csc03i10* + ID_PCI_INTERFACE_FROM_DATABASE=OHCI + +pci:v*d*sv*sd*bc0Csc03i20* + ID_PCI_INTERFACE_FROM_DATABASE=EHCI + +pci:v*d*sv*sd*bc0Csc03i30* + ID_PCI_INTERFACE_FROM_DATABASE=XHCI + +pci:v*d*sv*sd*bc0Csc03i80* + ID_PCI_INTERFACE_FROM_DATABASE=Unspecified + +pci:v*d*sv*sd*bc0Csc03iFE* + ID_PCI_INTERFACE_FROM_DATABASE=USB Device + +pci:v*d*sv*sd*bc0Csc04* + ID_PCI_SUBCLASS_FROM_DATABASE=Fibre Channel + +pci:v*d*sv*sd*bc0Csc05* + ID_PCI_SUBCLASS_FROM_DATABASE=SMBus + +pci:v*d*sv*sd*bc0Csc06* + ID_PCI_SUBCLASS_FROM_DATABASE=InfiniBand + +pci:v*d*sv*sd*bc0Csc07* + ID_PCI_SUBCLASS_FROM_DATABASE=IPMI SMIC interface + +pci:v*d*sv*sd*bc0Csc08* + ID_PCI_SUBCLASS_FROM_DATABASE=SERCOS interface + +pci:v*d*sv*sd*bc0Csc09* + ID_PCI_SUBCLASS_FROM_DATABASE=CANBUS + +pci:v*d*sv*sd*bc0D* + ID_PCI_CLASS_FROM_DATABASE=Wireless controller + +pci:v*d*sv*sd*bc0Dsc00* + ID_PCI_SUBCLASS_FROM_DATABASE=IRDA controller + +pci:v*d*sv*sd*bc0Dsc01* + ID_PCI_SUBCLASS_FROM_DATABASE=Consumer IR controller + +pci:v*d*sv*sd*bc0Dsc10* + ID_PCI_SUBCLASS_FROM_DATABASE=RF controller + +pci:v*d*sv*sd*bc0Dsc11* + ID_PCI_SUBCLASS_FROM_DATABASE=Bluetooth + +pci:v*d*sv*sd*bc0Dsc12* + ID_PCI_SUBCLASS_FROM_DATABASE=Broadband + +pci:v*d*sv*sd*bc0Dsc20* + ID_PCI_SUBCLASS_FROM_DATABASE=802.1a controller + +pci:v*d*sv*sd*bc0Dsc21* + ID_PCI_SUBCLASS_FROM_DATABASE=802.1b controller + +pci:v*d*sv*sd*bc0Dsc80* + ID_PCI_SUBCLASS_FROM_DATABASE=Wireless controller + +pci:v*d*sv*sd*bc0E* + ID_PCI_CLASS_FROM_DATABASE=Intelligent controller + +pci:v*d*sv*sd*bc0Esc00* + ID_PCI_SUBCLASS_FROM_DATABASE=I2O + +pci:v*d*sv*sd*bc0F* + ID_PCI_CLASS_FROM_DATABASE=Satellite communications controller + +pci:v*d*sv*sd*bc0Fsc01* + ID_PCI_SUBCLASS_FROM_DATABASE=Satellite TV controller + +pci:v*d*sv*sd*bc0Fsc02* + ID_PCI_SUBCLASS_FROM_DATABASE=Satellite audio communication controller + +pci:v*d*sv*sd*bc0Fsc03* + ID_PCI_SUBCLASS_FROM_DATABASE=Satellite voice communication controller + +pci:v*d*sv*sd*bc0Fsc04* + ID_PCI_SUBCLASS_FROM_DATABASE=Satellite data communication controller + +pci:v*d*sv*sd*bc10* + ID_PCI_CLASS_FROM_DATABASE=Encryption controller + +pci:v*d*sv*sd*bc10sc00* + ID_PCI_SUBCLASS_FROM_DATABASE=Network and computing encryption device + +pci:v*d*sv*sd*bc10sc10* + ID_PCI_SUBCLASS_FROM_DATABASE=Entertainment encryption device + +pci:v*d*sv*sd*bc10sc80* + ID_PCI_SUBCLASS_FROM_DATABASE=Encryption controller + +pci:v*d*sv*sd*bc11* + ID_PCI_CLASS_FROM_DATABASE=Signal processing controller + +pci:v*d*sv*sd*bc11sc00* + ID_PCI_SUBCLASS_FROM_DATABASE=DPIO module + +pci:v*d*sv*sd*bc11sc01* + ID_PCI_SUBCLASS_FROM_DATABASE=Performance counters + +pci:v*d*sv*sd*bc11sc10* + ID_PCI_SUBCLASS_FROM_DATABASE=Communication synchronizer + +pci:v*d*sv*sd*bc11sc20* + ID_PCI_SUBCLASS_FROM_DATABASE=Signal processing management + +pci:v*d*sv*sd*bc11sc80* + ID_PCI_SUBCLASS_FROM_DATABASE=Signal processing controller + +pci:v*d*sv*sd*bcFF* + ID_PCI_CLASS_FROM_DATABASE=Unassigned class diff --git a/hwdb/20-pci-vendor-product.hwdb b/hwdb/20-pci-vendor-product.hwdb new file mode 100644 index 000000000..2e87004fc --- /dev/null +++ b/hwdb/20-pci-vendor-product.hwdb @@ -0,0 +1,63993 @@ +# This file is part of systemd. +# +# Data imported from: http://pci-ids.ucw.cz/v2.2/pci.ids + +pci:v00000010* + ID_VENDOR_FROM_DATABASE=Allied Telesis, Inc + +pci:v00000010d00008139* + ID_PRODUCT_FROM_DATABASE=AT-2500TX V3 Ethernet + +pci:v0000001A* + ID_VENDOR_FROM_DATABASE=Ascend Communications, Inc. + +pci:v0000001C* + ID_VENDOR_FROM_DATABASE=PEAK-System Technik GmbH + +pci:v0000001Cd00000001* + ID_PRODUCT_FROM_DATABASE=PCAN-PCI CAN-Bus controller + +pci:v0000001Cd00000001sv0000001Csd00000004* + ID_PRODUCT_FROM_DATABASE=2 Channel CAN Bus SJC1000 + +pci:v0000001Cd00000001sv0000001Csd00000005* + ID_PRODUCT_FROM_DATABASE=2 Channel CAN Bus SJC1000 (Optically Isolated) + +pci:v00000033* + ID_VENDOR_FROM_DATABASE=Paradyne corp. + +pci:v0000003D* + ID_VENDOR_FROM_DATABASE=Lockheed Martin-Marietta Corp + +pci:v00000059* + ID_VENDOR_FROM_DATABASE=Tiger Jet Network Inc. (Wrong ID) + +pci:v00000070* + ID_VENDOR_FROM_DATABASE=Hauppauge computer works Inc. + +pci:v00000070d00000003* + ID_PRODUCT_FROM_DATABASE=WinTV PVR-250 + +pci:v00000070d00000009* + ID_PRODUCT_FROM_DATABASE=WinTV PVR-150 + +pci:v00000070d00000801* + ID_PRODUCT_FROM_DATABASE=WinTV PVR-150 + +pci:v00000070d00000807* + ID_PRODUCT_FROM_DATABASE=WinTV PVR-150 + +pci:v00000070d00004000* + ID_PRODUCT_FROM_DATABASE=WinTV PVR-350 + +pci:v00000070d00004001* + ID_PRODUCT_FROM_DATABASE=WinTV PVR-250 (v1) + +pci:v00000070d00004009* + ID_PRODUCT_FROM_DATABASE=WinTV PVR-250 + +pci:v00000070d00004800* + ID_PRODUCT_FROM_DATABASE=WinTV PVR-350 + +pci:v00000070d00004801* + ID_PRODUCT_FROM_DATABASE=WinTV PVR-250 MCE + +pci:v00000070d00004803* + ID_PRODUCT_FROM_DATABASE=WinTV PVR-250 + +pci:v00000070d00007444* + ID_PRODUCT_FROM_DATABASE=WinTV HVR-1600 + +pci:v00000070d00007801* + ID_PRODUCT_FROM_DATABASE=WinTV HVR-1800 MCE + +pci:v00000070d00008003* + ID_PRODUCT_FROM_DATABASE=WinTV PVR-150 + +pci:v00000070d00008801* + ID_PRODUCT_FROM_DATABASE=WinTV PVR-150 + +pci:v00000070d0000C108* + ID_PRODUCT_FROM_DATABASE=WinTV-HVR-4400-HD model 1278 + +pci:v00000070d0000C801* + ID_PRODUCT_FROM_DATABASE=WinTV PVR-150 + +pci:v00000070d0000E807* + ID_PRODUCT_FROM_DATABASE=WinTV PVR-500 MCE (1st tuner) + +pci:v00000070d0000E817* + ID_PRODUCT_FROM_DATABASE=WinTV PVR-500 MCE (2nd tuner) + +pci:v00000071* + ID_VENDOR_FROM_DATABASE=Nebula Electronics Ltd. + +pci:v00000095* + ID_VENDOR_FROM_DATABASE=Silicon Image, Inc. (Wrong ID) + +pci:v00000095d00000680* + ID_PRODUCT_FROM_DATABASE=Ultra ATA/133 IDE RAID CONTROLLER CARD + +pci:v000000A7* + ID_VENDOR_FROM_DATABASE=Teles AG (Wrong ID) + +pci:v000000F5* + ID_VENDOR_FROM_DATABASE=BFG Technologies, Inc. + +pci:v00000100* + ID_VENDOR_FROM_DATABASE=Ncipher Corp Ltd + +pci:v00000123* + ID_VENDOR_FROM_DATABASE=General Dynamics + +pci:v0000018A* + ID_VENDOR_FROM_DATABASE=LevelOne + +pci:v0000018Ad00000106* + ID_PRODUCT_FROM_DATABASE=FPC-0106TX misprogrammed [RTL81xx] + +pci:v0000021B* + ID_VENDOR_FROM_DATABASE=Compaq Computer Corporation + +pci:v0000021Bd00008139* + ID_PRODUCT_FROM_DATABASE=HNE-300 (RealTek RTL8139c) [iPaq Networking] + +pci:v00000270* + ID_VENDOR_FROM_DATABASE=Hauppauge computer works Inc. (Wrong ID) + +pci:v00000291* + ID_VENDOR_FROM_DATABASE=Davicom Semiconductor, Inc. + +pci:v00000291d00008212* + ID_PRODUCT_FROM_DATABASE=DM9102A(DM9102AE, SM9102AF) Ethernet 100/10 MBit(Rev 40) + +pci:v000002AC* + ID_VENDOR_FROM_DATABASE=SpeedStream + +pci:v000002ACd00001012* + ID_PRODUCT_FROM_DATABASE=1012 PCMCIA 10/100 Ethernet Card [RTL81xx] + +pci:v000002E0* + ID_VENDOR_FROM_DATABASE=XFX Pine Group Inc + +pci:v00000303* + ID_VENDOR_FROM_DATABASE=Hewlett-Packard Company (Wrong ID) + +pci:v00000308* + ID_VENDOR_FROM_DATABASE=ZyXEL Communications Corporation + +pci:v00000315* + ID_VENDOR_FROM_DATABASE=SK-Electronics Co., Ltd. + +pci:v00000357* + ID_VENDOR_FROM_DATABASE=TTTech AG + +pci:v00000357d0000000A* + ID_PRODUCT_FROM_DATABASE=TTP-Monitoring Card V2.0 + +pci:v0000036F* + ID_VENDOR_FROM_DATABASE=Trigem Computer Inc. + +pci:v00000432* + ID_VENDOR_FROM_DATABASE=SCM Microsystems, Inc. + +pci:v00000432d00000001* + ID_PRODUCT_FROM_DATABASE=Pluto2 DVB-T Receiver for PCMCIA [EasyWatch MobilSet] + +pci:v00000675* + ID_VENDOR_FROM_DATABASE=Dynalink + +pci:v00000675d00001700* + ID_PRODUCT_FROM_DATABASE=IS64PH ISDN Adapter + +pci:v00000675d00001702* + ID_PRODUCT_FROM_DATABASE=IS64PH ISDN Adapter + +pci:v00000675d00001703* + ID_PRODUCT_FROM_DATABASE=ISDN Adapter (PCI Bus, DV, W) + +pci:v00000675d00001704* + ID_PRODUCT_FROM_DATABASE=ISDN Adapter (PCI Bus, D, C) + +pci:v00000721* + ID_VENDOR_FROM_DATABASE=Sapphire, Inc. + +pci:v00000777* + ID_VENDOR_FROM_DATABASE=Ubiquiti Networks, Inc. + +pci:v00000777d00003005* + ID_PRODUCT_FROM_DATABASE=XtremeRange5 + +pci:v00000795* + ID_VENDOR_FROM_DATABASE=Wired Inc. + +pci:v00000795d00006663* + ID_PRODUCT_FROM_DATABASE=Butane II (MPEG2 encoder board) + +pci:v00000795d00006666* + ID_PRODUCT_FROM_DATABASE=MediaPress (MPEG2 encoder board) + +pci:v000007CA* + ID_VENDOR_FROM_DATABASE=AVerMedia Technologies Inc. + +pci:v000007CAd0000534A* + ID_PRODUCT_FROM_DATABASE=Slim mobile Express DVB-T (Fujitsu) + +pci:v000007CAd0000A301* + ID_PRODUCT_FROM_DATABASE=AVerTV 301 + +pci:v000007CAd0000B808* + ID_PRODUCT_FROM_DATABASE=AVerTV DVB-T Volar (USB 2.0) + +pci:v000007D0* + ID_VENDOR_FROM_DATABASE=ITT Geospatial Systems + +pci:v000007D1* + ID_VENDOR_FROM_DATABASE=D-Link System Inc + +pci:v000007E2* + ID_VENDOR_FROM_DATABASE=ELMEG Communication Systems GmbH + +pci:v00000842* + ID_VENDOR_FROM_DATABASE=NPG, Personal Grand Technology + +pci:v000008E6* + ID_VENDOR_FROM_DATABASE=Gemalto NV + +pci:v000008FF* + ID_VENDOR_FROM_DATABASE=AuthenTec + +pci:v000008FFd0000AFE4* + ID_PRODUCT_FROM_DATABASE=[Anchor] AF-S2 FingerLoc Sensor Module + +pci:v00000925* + ID_VENDOR_FROM_DATABASE=VIA Technologies, Inc. (Wrong ID) + +pci:v00000925d00001234* + ID_PRODUCT_FROM_DATABASE=VT82C686/A/B USB Controller + +pci:v0000093A* + ID_VENDOR_FROM_DATABASE=PixArt Imaging Inc. + +pci:v0000093Ad0000010E* + ID_PRODUCT_FROM_DATABASE=Innovage Mini Digital Camera + +pci:v0000093Ad0000010F* + ID_PRODUCT_FROM_DATABASE=SDC-300 Webcam + +pci:v0000093Ad0000020F* + ID_PRODUCT_FROM_DATABASE=Digital Photo Viewer + +pci:v0000093Ad00002468* + ID_PRODUCT_FROM_DATABASE=CIF Single Chip + +pci:v0000093Ad00002600* + ID_PRODUCT_FROM_DATABASE=PAC7311 + +pci:v0000093Ad00002603* + ID_PRODUCT_FROM_DATABASE=Philips Webcam SPC500NC + +pci:v0000093Ad00002608* + ID_PRODUCT_FROM_DATABASE=Maxell MaxCam RotaWeb + +pci:v0000093Ad00002620* + ID_PRODUCT_FROM_DATABASE=C3 Tech Mod. 153 + +pci:v000009C1* + ID_VENDOR_FROM_DATABASE=Arris + +pci:v000009C1d00000704* + ID_PRODUCT_FROM_DATABASE=CM 200E Cable Modem + +pci:v00000A89* + ID_VENDOR_FROM_DATABASE=BREA Technologies Inc + +pci:v00000B0B* + ID_VENDOR_FROM_DATABASE=Rhino Equipment Corp. + +pci:v00000B0Bd00000105* + ID_PRODUCT_FROM_DATABASE=Rhino R1T1 + +pci:v00000B0Bd00000205* + ID_PRODUCT_FROM_DATABASE=Rhino R4FXO + +pci:v00000B0Bd00000206* + ID_PRODUCT_FROM_DATABASE=RCB4FXO 4-channel FXO analog telphony card + +pci:v00000B0Bd00000305* + ID_PRODUCT_FROM_DATABASE=Rhino R4T1 + +pci:v00000B0Bd00000405* + ID_PRODUCT_FROM_DATABASE=Rhino R8FXX + +pci:v00000B0Bd00000406* + ID_PRODUCT_FROM_DATABASE=RCB8FXX 8-channel modular analog telphony card + +pci:v00000B0Bd00000505* + ID_PRODUCT_FROM_DATABASE=Rhino R24FXX + +pci:v00000B0Bd00000506* + ID_PRODUCT_FROM_DATABASE=RCB24FXS 24-Channel FXS analog telphony card + +pci:v00000B0Bd00000605* + ID_PRODUCT_FROM_DATABASE=Rhino R2T1 + +pci:v00000B0Bd00000705* + ID_PRODUCT_FROM_DATABASE=Rhino R24FXS + +pci:v00000B0Bd00000706* + ID_PRODUCT_FROM_DATABASE=RCB24FXO 24-Channel FXO analog telphony card + +pci:v00000B0Bd00000905* + ID_PRODUCT_FROM_DATABASE=R1T3 Single T3 Digital Telephony Card + +pci:v00000B0Bd00000906* + ID_PRODUCT_FROM_DATABASE=RCB24FXX 24-channel modular analog telphony card + +pci:v00000B0Bd00000A06* + ID_PRODUCT_FROM_DATABASE=RCB672FXX 672-channel modular analog telphony card + +pci:v00000B3D* + ID_VENDOR_FROM_DATABASE=Brontes Technologies + +pci:v00000CCD* + ID_VENDOR_FROM_DATABASE=TerraTec Electronic GmbH + +pci:v00000CCDd00000038* + ID_PRODUCT_FROM_DATABASE=Cinergy T^2 DVB-T Receiver + +pci:v00000E11* + ID_VENDOR_FROM_DATABASE=Compaq Computer Corporation + +pci:v00000E11d00000001* + ID_PRODUCT_FROM_DATABASE=PCI to EISA Bridge + +pci:v00000E11d00000002* + ID_PRODUCT_FROM_DATABASE=PCI to ISA Bridge + +pci:v00000E11d00000046* + ID_PRODUCT_FROM_DATABASE=Smart Array 64xx + +pci:v00000E11d00000046sv00000E11sd00004091* + ID_PRODUCT_FROM_DATABASE=Smart Array 6i + +pci:v00000E11d00000046sv00000E11sd0000409A* + ID_PRODUCT_FROM_DATABASE=Smart Array 641 + +pci:v00000E11d00000046sv00000E11sd0000409B* + ID_PRODUCT_FROM_DATABASE=Smart Array 642 + +pci:v00000E11d00000046sv00000E11sd0000409C* + ID_PRODUCT_FROM_DATABASE=Smart Array 6400 + +pci:v00000E11d00000046sv00000E11sd0000409D* + ID_PRODUCT_FROM_DATABASE=Smart Array 6400 EM + +pci:v00000E11d00000049* + ID_PRODUCT_FROM_DATABASE=NC7132 Gigabit Upgrade Module + +pci:v00000E11d0000004A* + ID_PRODUCT_FROM_DATABASE=NC6136 Gigabit Server Adapter + +pci:v00000E11d0000005A* + ID_PRODUCT_FROM_DATABASE=Remote Insight II board - Lights-Out + +pci:v00000E11d0000007C* + ID_PRODUCT_FROM_DATABASE=NC7770 1000BaseTX + +pci:v00000E11d0000007D* + ID_PRODUCT_FROM_DATABASE=NC6770 1000BaseTX + +pci:v00000E11d00000085* + ID_PRODUCT_FROM_DATABASE=NC7780 1000BaseTX + +pci:v00000E11d000000B1* + ID_PRODUCT_FROM_DATABASE=Remote Insight II board - PCI device + +pci:v00000E11d000000BB* + ID_PRODUCT_FROM_DATABASE=NC7760 + +pci:v00000E11d000000CA* + ID_PRODUCT_FROM_DATABASE=NC7771 + +pci:v00000E11d000000CB* + ID_PRODUCT_FROM_DATABASE=NC7781 + +pci:v00000E11d000000CF* + ID_PRODUCT_FROM_DATABASE=NC7772 + +pci:v00000E11d000000D0* + ID_PRODUCT_FROM_DATABASE=NC7782 + +pci:v00000E11d000000D1* + ID_PRODUCT_FROM_DATABASE=NC7783 + +pci:v00000E11d000000E3* + ID_PRODUCT_FROM_DATABASE=NC7761 + +pci:v00000E11d00000508* + ID_PRODUCT_FROM_DATABASE=Netelligent 4/16 Token Ring + +pci:v00000E11d00001000* + ID_PRODUCT_FROM_DATABASE=Triflex/Pentium Bridge, Model 1000 + +pci:v00000E11d00002000* + ID_PRODUCT_FROM_DATABASE=Triflex/Pentium Bridge, Model 2000 + +pci:v00000E11d00003032* + ID_PRODUCT_FROM_DATABASE=QVision 1280/p + +pci:v00000E11d00003033* + ID_PRODUCT_FROM_DATABASE=QVision 1280/p + +pci:v00000E11d00003034* + ID_PRODUCT_FROM_DATABASE=QVision 1280/p + +pci:v00000E11d00004000* + ID_PRODUCT_FROM_DATABASE=4000 [Triflex] + +pci:v00000E11d00004040* + ID_PRODUCT_FROM_DATABASE=Integrated Array + +pci:v00000E11d00004048* + ID_PRODUCT_FROM_DATABASE=Compaq Raid LC2 + +pci:v00000E11d00004050* + ID_PRODUCT_FROM_DATABASE=Smart Array 4200 + +pci:v00000E11d00004051* + ID_PRODUCT_FROM_DATABASE=Smart Array 4250ES + +pci:v00000E11d00004058* + ID_PRODUCT_FROM_DATABASE=Smart Array 431 + +pci:v00000E11d00004070* + ID_PRODUCT_FROM_DATABASE=Smart Array 5300 + +pci:v00000E11d00004080* + ID_PRODUCT_FROM_DATABASE=Smart Array 5i + +pci:v00000E11d00004082* + ID_PRODUCT_FROM_DATABASE=Smart Array 532 + +pci:v00000E11d00004083* + ID_PRODUCT_FROM_DATABASE=Smart Array 5312 + +pci:v00000E11d00004091* + ID_PRODUCT_FROM_DATABASE=Smart Array 6i + +pci:v00000E11d0000409A* + ID_PRODUCT_FROM_DATABASE=Smart Array 641 + +pci:v00000E11d0000409B* + ID_PRODUCT_FROM_DATABASE=Smart Array 642 + +pci:v00000E11d0000409C* + ID_PRODUCT_FROM_DATABASE=Smart Array 6400 + +pci:v00000E11d0000409D* + ID_PRODUCT_FROM_DATABASE=Smart Array 6400 EM + +pci:v00000E11d00006010* + ID_PRODUCT_FROM_DATABASE=HotPlug PCI Bridge 6010 + +pci:v00000E11d00007020* + ID_PRODUCT_FROM_DATABASE=USB Controller + +pci:v00000E11d0000A0EC* + ID_PRODUCT_FROM_DATABASE=Fibre Channel Host Controller + +pci:v00000E11d0000A0F0* + ID_PRODUCT_FROM_DATABASE=Advanced System Management Controller + +pci:v00000E11d0000A0F0sv00000E11sd0000B0F3* + ID_PRODUCT_FROM_DATABASE=ProLiant DL360 + +pci:v00000E11d0000A0F3* + ID_PRODUCT_FROM_DATABASE=Triflex PCI to ISA Bridge + +pci:v00000E11d0000A0F7* + ID_PRODUCT_FROM_DATABASE=PCI Hotplug Controller + +pci:v00000E11d0000A0F7sv00008086sd0000002A* + ID_PRODUCT_FROM_DATABASE=PCI Hotplug Controller A + +pci:v00000E11d0000A0F7sv00008086sd0000002B* + ID_PRODUCT_FROM_DATABASE=PCI Hotplug Controller B + +pci:v00000E11d0000A0F8* + ID_PRODUCT_FROM_DATABASE=ZFMicro Chipset USB + +pci:v00000E11d0000A0FC* + ID_PRODUCT_FROM_DATABASE=FibreChannel HBA Tachyon + +pci:v00000E11d0000AE10* + ID_PRODUCT_FROM_DATABASE=Smart-2/P RAID Controller + +pci:v00000E11d0000AE10sv00000E11sd00004030* + ID_PRODUCT_FROM_DATABASE=Smart-2/P Array Controller + +pci:v00000E11d0000AE10sv00000E11sd00004031* + ID_PRODUCT_FROM_DATABASE=Smart-2SL Array Controller + +pci:v00000E11d0000AE10sv00000E11sd00004032* + ID_PRODUCT_FROM_DATABASE=Smart Array 3200 Controller + +pci:v00000E11d0000AE10sv00000E11sd00004033* + ID_PRODUCT_FROM_DATABASE=Smart Array 3100ES Controller + +pci:v00000E11d0000AE10sv00000E11sd00004034* + ID_PRODUCT_FROM_DATABASE=Smart Array 221 Controller + +pci:v00000E11d0000AE29* + ID_PRODUCT_FROM_DATABASE=MIS-L + +pci:v00000E11d0000AE2A* + ID_PRODUCT_FROM_DATABASE=MPC + +pci:v00000E11d0000AE2B* + ID_PRODUCT_FROM_DATABASE=MIS-E + +pci:v00000E11d0000AE31* + ID_PRODUCT_FROM_DATABASE=System Management Controller + +pci:v00000E11d0000AE32* + ID_PRODUCT_FROM_DATABASE=Netelligent 10/100 TX PCI UTP + +pci:v00000E11d0000AE33* + ID_PRODUCT_FROM_DATABASE=Triflex Dual EIDE Controller + +pci:v00000E11d0000AE34* + ID_PRODUCT_FROM_DATABASE=Netelligent 10 T PCI UTP + +pci:v00000E11d0000AE35* + ID_PRODUCT_FROM_DATABASE=Integrated NetFlex-3/P + +pci:v00000E11d0000AE40* + ID_PRODUCT_FROM_DATABASE=Netelligent Dual 10/100 TX PCI UTP + +pci:v00000E11d0000AE43* + ID_PRODUCT_FROM_DATABASE=Netelligent Integrated 10/100 TX UTP + +pci:v00000E11d0000AE69* + ID_PRODUCT_FROM_DATABASE=CETUS-L + +pci:v00000E11d0000AE6C* + ID_PRODUCT_FROM_DATABASE=Northstar + +pci:v00000E11d0000AE6D* + ID_PRODUCT_FROM_DATABASE=NorthStar CPU to PCI Bridge + +pci:v00000E11d0000B011* + ID_PRODUCT_FROM_DATABASE=Netelligent 10/100 TX Embedded UTP + +pci:v00000E11d0000B012* + ID_PRODUCT_FROM_DATABASE=Netelligent 10 T/2 PCI UTP/Coax + +pci:v00000E11d0000B01E* + ID_PRODUCT_FROM_DATABASE=NC3120 Fast Ethernet NIC + +pci:v00000E11d0000B01F* + ID_PRODUCT_FROM_DATABASE=NC3122 Fast Ethernet NIC + +pci:v00000E11d0000B02F* + ID_PRODUCT_FROM_DATABASE=NC1120 Ethernet NIC + +pci:v00000E11d0000B030* + ID_PRODUCT_FROM_DATABASE=Netelligent 10/100 TX UTP + +pci:v00000E11d0000B04A* + ID_PRODUCT_FROM_DATABASE=10/100 TX PCI Intel WOL UTP Controller + +pci:v00000E11d0000B060* + ID_PRODUCT_FROM_DATABASE=Smart Array 5300 Controller + +pci:v00000E11d0000B0C6* + ID_PRODUCT_FROM_DATABASE=NC3161 Fast Ethernet NIC + +pci:v00000E11d0000B0C7* + ID_PRODUCT_FROM_DATABASE=NC3160 Fast Ethernet NIC + +pci:v00000E11d0000B0D7* + ID_PRODUCT_FROM_DATABASE=NC3121 Fast Ethernet NIC + +pci:v00000E11d0000B0DD* + ID_PRODUCT_FROM_DATABASE=NC3131 Fast Ethernet NIC + +pci:v00000E11d0000B0DE* + ID_PRODUCT_FROM_DATABASE=NC3132 Fast Ethernet Module + +pci:v00000E11d0000B0DF* + ID_PRODUCT_FROM_DATABASE=NC6132 Gigabit Module + +pci:v00000E11d0000B0E0* + ID_PRODUCT_FROM_DATABASE=NC6133 Gigabit Module + +pci:v00000E11d0000B0E1* + ID_PRODUCT_FROM_DATABASE=NC3133 Fast Ethernet Module + +pci:v00000E11d0000B123* + ID_PRODUCT_FROM_DATABASE=NC6134 Gigabit NIC + +pci:v00000E11d0000B134* + ID_PRODUCT_FROM_DATABASE=NC3163 Fast Ethernet NIC + +pci:v00000E11d0000B13C* + ID_PRODUCT_FROM_DATABASE=NC3162 Fast Ethernet NIC + +pci:v00000E11d0000B144* + ID_PRODUCT_FROM_DATABASE=NC3123 Fast Ethernet NIC + +pci:v00000E11d0000B163* + ID_PRODUCT_FROM_DATABASE=NC3134 Fast Ethernet NIC + +pci:v00000E11d0000B164* + ID_PRODUCT_FROM_DATABASE=NC3165 Fast Ethernet Upgrade Module + +pci:v00000E11d0000B178* + ID_PRODUCT_FROM_DATABASE=Smart Array 5i/532 + +pci:v00000E11d0000B178sv00000E11sd00004080* + ID_PRODUCT_FROM_DATABASE=Smart Array 5i + +pci:v00000E11d0000B178sv00000E11sd00004082* + ID_PRODUCT_FROM_DATABASE=Smart Array 532 + +pci:v00000E11d0000B178sv00000E11sd00004083* + ID_PRODUCT_FROM_DATABASE=Smart Array 5312 + +pci:v00000E11d0000B1A4* + ID_PRODUCT_FROM_DATABASE=NC7131 Gigabit Server Adapter + +pci:v00000E11d0000B200* + ID_PRODUCT_FROM_DATABASE=Memory Hot-Plug Controller + +pci:v00000E11d0000B203* + ID_PRODUCT_FROM_DATABASE=Integrated Lights Out Controller + +pci:v00000E11d0000B204* + ID_PRODUCT_FROM_DATABASE=Integrated Lights Out Processor + +pci:v00000E11d0000C000* + ID_PRODUCT_FROM_DATABASE=Remote Insight Lights-Out Edition + +pci:v00000E11d0000F130* + ID_PRODUCT_FROM_DATABASE=NetFlex-3/P ThunderLAN 1.0 + +pci:v00000E11d0000F150* + ID_PRODUCT_FROM_DATABASE=NetFlex-3/P ThunderLAN 2.3 + +pci:v00000E21* + ID_VENDOR_FROM_DATABASE=Cowon Systems, Inc. + +pci:v00000E55* + ID_VENDOR_FROM_DATABASE=HaSoTec GmbH + +pci:v00000EAC* + ID_VENDOR_FROM_DATABASE=SHF Communication Technologies AG + +pci:v00000EACd00000008* + ID_PRODUCT_FROM_DATABASE=Ethernet Powerlink Managing Node 01 + +pci:v00000F62* + ID_VENDOR_FROM_DATABASE=Acrox Technologies Co., Ltd. + +pci:v00001000* + ID_VENDOR_FROM_DATABASE=LSI Logic / Symbios Logic + +pci:v00001000d00000001* + ID_PRODUCT_FROM_DATABASE=53c810 + +pci:v00001000d00000001sv00001000sd00001000* + ID_PRODUCT_FROM_DATABASE=LSI53C810AE PCI to SCSI I/O Processor + +pci:v00001000d00000002* + ID_PRODUCT_FROM_DATABASE=53c820 + +pci:v00001000d00000003* + ID_PRODUCT_FROM_DATABASE=53c825 + +pci:v00001000d00000003sv00001000sd00001000* + ID_PRODUCT_FROM_DATABASE=LSI53C825AE PCI to SCSI I/O Processor (Ultra Wide) + +pci:v00001000d00000004* + ID_PRODUCT_FROM_DATABASE=53c815 + +pci:v00001000d00000005* + ID_PRODUCT_FROM_DATABASE=53c810AP + +pci:v00001000d00000006* + ID_PRODUCT_FROM_DATABASE=53c860 + +pci:v00001000d00000006sv00001000sd00001000* + ID_PRODUCT_FROM_DATABASE=LSI53C860E PCI to Ultra SCSI I/O Processor + +pci:v00001000d0000000A* + ID_PRODUCT_FROM_DATABASE=53c1510 + +pci:v00001000d0000000Asv00000E11sd0000B143* + ID_PRODUCT_FROM_DATABASE=Integrated Dual Channel Wide Ultra2 SCSI Controller + +pci:v00001000d0000000Asv00001000sd00001000* + ID_PRODUCT_FROM_DATABASE=LSI53C1510 PCI to Dual Channel Wide Ultra2 SCSI Controller (Nonintelligent mode) + +pci:v00001000d0000000B* + ID_PRODUCT_FROM_DATABASE=53C896/897 + +pci:v00001000d0000000Bsv00000E11sd00006004* + ID_PRODUCT_FROM_DATABASE=EOB003 Series SCSI host adapter + +pci:v00001000d0000000Bsv00001000sd00001000* + ID_PRODUCT_FROM_DATABASE=LSI53C896/7 PCI to Dual Channel Ultra2 SCSI Multifunction Controller + +pci:v00001000d0000000Bsv00001000sd00001010* + ID_PRODUCT_FROM_DATABASE=LSI22910 PCI to Dual Channel Ultra2 SCSI host adapter + +pci:v00001000d0000000Bsv00001000sd00001020* + ID_PRODUCT_FROM_DATABASE=LSI21002 PCI to Dual Channel Ultra2 SCSI host adapter + +pci:v00001000d0000000Bsv000013E9sd00001000* + ID_PRODUCT_FROM_DATABASE=6221L-4U (Dual U2W SCSI, dual 10/100TX, graphics) + +pci:v00001000d0000000C* + ID_PRODUCT_FROM_DATABASE=53c895 + +pci:v00001000d0000000Csv00001000sd00001010* + ID_PRODUCT_FROM_DATABASE=LSI8951U PCI to Ultra2 SCSI host adapter + +pci:v00001000d0000000Csv00001000sd00001020* + ID_PRODUCT_FROM_DATABASE=LSI8952U PCI to Ultra2 SCSI host adapter + +pci:v00001000d0000000Csv00001DE1sd00003906* + ID_PRODUCT_FROM_DATABASE=DC-390U2B SCSI adapter + +pci:v00001000d0000000Csv00001DE1sd00003907* + ID_PRODUCT_FROM_DATABASE=DC-390U2W + +pci:v00001000d0000000D* + ID_PRODUCT_FROM_DATABASE=53c885 + +pci:v00001000d0000000F* + ID_PRODUCT_FROM_DATABASE=53c875 + +pci:v00001000d0000000Fsv00000E11sd00007004* + ID_PRODUCT_FROM_DATABASE=Embedded Ultra Wide SCSI Controller + +pci:v00001000d0000000Fsv00001000sd00001000* + ID_PRODUCT_FROM_DATABASE=LSI53C876/E PCI to Dual Channel SCSI Controller + +pci:v00001000d0000000Fsv00001000sd00001010* + ID_PRODUCT_FROM_DATABASE=LSI22801 PCI to Dual Channel Ultra SCSI host adapter + +pci:v00001000d0000000Fsv00001000sd00001020* + ID_PRODUCT_FROM_DATABASE=LSI22802 PCI to Dual Channel Ultra SCSI host adapter + +pci:v00001000d0000000Fsv00001092sd00008760* + ID_PRODUCT_FROM_DATABASE=FirePort 40 Dual SCSI Controller + +pci:v00001000d0000000Fsv00001775sd000010D0* + ID_PRODUCT_FROM_DATABASE=V5D Single Board Computer Wide Ultra SCSI + +pci:v00001000d0000000Fsv00001775sd000010D1* + ID_PRODUCT_FROM_DATABASE=V5D Single Board Computer Ultra SCSI + +pci:v00001000d0000000Fsv00001DE1sd00003904* + ID_PRODUCT_FROM_DATABASE=DC390F/U Ultra Wide SCSI Adapter + +pci:v00001000d0000000Fsv00004C53sd00001000* + ID_PRODUCT_FROM_DATABASE=CC7/CR7/CP7/VC7/VP7/VR7 mainboard + +pci:v00001000d0000000Fsv00004C53sd00001050* + ID_PRODUCT_FROM_DATABASE=CT7 mainboard + +pci:v00001000d00000010* + ID_PRODUCT_FROM_DATABASE=53C1510 + +pci:v00001000d00000010sv00000E11sd00004040* + ID_PRODUCT_FROM_DATABASE=Integrated Smart Array Controller + +pci:v00001000d00000010sv00000E11sd00004048* + ID_PRODUCT_FROM_DATABASE=RAID LC2 Controller + +pci:v00001000d00000010sv00001000sd00001000* + ID_PRODUCT_FROM_DATABASE=53C1510 PCI to Dual Channel Wide Ultra2 SCSI Controller (Intelligent mode) + +pci:v00001000d00000012* + ID_PRODUCT_FROM_DATABASE=53c895a + +pci:v00001000d00000012sv00001000sd00001000* + ID_PRODUCT_FROM_DATABASE=LSI53C895A PCI to Ultra2 SCSI Controller + +pci:v00001000d00000013* + ID_PRODUCT_FROM_DATABASE=53c875a + +pci:v00001000d00000013sv00001000sd00001000* + ID_PRODUCT_FROM_DATABASE=LSI53C875A PCI to Ultra SCSI Controller + +pci:v00001000d00000020* + ID_PRODUCT_FROM_DATABASE=53c1010 Ultra3 SCSI Adapter + +pci:v00001000d00000020sv00001000sd00001000* + ID_PRODUCT_FROM_DATABASE=LSI53C1010-33 PCI to Dual Channel Ultra160 SCSI Controller + +pci:v00001000d00000020sv0000107Bsd00001040* + ID_PRODUCT_FROM_DATABASE=Server Onboard 53C1010-33 + +pci:v00001000d00000020sv00001DE1sd00001020* + ID_PRODUCT_FROM_DATABASE=DC-390U3W + +pci:v00001000d00000021* + ID_PRODUCT_FROM_DATABASE=53c1010 66MHz Ultra3 SCSI Adapter + +pci:v00001000d00000021sv00001000sd00001000* + ID_PRODUCT_FROM_DATABASE=LSI53C1000/1000R/1010R/1010-66 PCI to Ultra160 SCSI Controller + +pci:v00001000d00000021sv00001000sd00001010* + ID_PRODUCT_FROM_DATABASE=Asus TR-DLS onboard 53C1010-66 + +pci:v00001000d00000021sv0000103Csd00001300* + ID_PRODUCT_FROM_DATABASE=Ultra160 SCSI [AB306A] + +pci:v00001000d00000021sv0000103Csd00001310* + ID_PRODUCT_FROM_DATABASE=Ultra160 SCSI [A9918A] + +pci:v00001000d00000021sv0000103Csd00001330* + ID_PRODUCT_FROM_DATABASE=Ultra160 SCSI [A7059A] + +pci:v00001000d00000021sv0000103Csd00001340* + ID_PRODUCT_FROM_DATABASE=Ultra160 SCSI [A7060A] + +pci:v00001000d00000021sv0000124Bsd00001070* + ID_PRODUCT_FROM_DATABASE=PMC-USCSI3 + +pci:v00001000d00000021sv00004C53sd00001080* + ID_PRODUCT_FROM_DATABASE=CT8 mainboard + +pci:v00001000d00000021sv00004C53sd00001300* + ID_PRODUCT_FROM_DATABASE=P017 mezzanine (32-bit PMC) + +pci:v00001000d00000021sv00004C53sd00001310* + ID_PRODUCT_FROM_DATABASE=P017 mezzanine (64-bit PMC) + +pci:v00001000d0000002F* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 2208 IOV [Thunderbolt] + +pci:v00001000d0000002Fsv00001028sd00001F3E* + ID_PRODUCT_FROM_DATABASE=SPERC 8 + +pci:v00001000d00000030* + ID_PRODUCT_FROM_DATABASE=53c1030 PCI-X Fusion-MPT Dual Ultra320 SCSI + +pci:v00001000d00000030sv00000E11sd000000DA* + ID_PRODUCT_FROM_DATABASE=ProLiant ML 350 + +pci:v00001000d00000030sv00001028sd00000123* + ID_PRODUCT_FROM_DATABASE=LSI Logic 1020/1030 + +pci:v00001000d00000030sv00001028sd0000014A* + ID_PRODUCT_FROM_DATABASE=LSI Logic 1020/1030 + +pci:v00001000d00000030sv00001028sd0000016C* + ID_PRODUCT_FROM_DATABASE=PowerEdge 1850 MPT Fusion SCSI/RAID (Perc 4) + +pci:v00001000d00000030sv00001028sd00000183* + ID_PRODUCT_FROM_DATABASE=LSI Logic 1020/1030 + +pci:v00001000d00000030sv00001028sd0000018A* + ID_PRODUCT_FROM_DATABASE=PERC 4/IM + +pci:v00001000d00000030sv00001028sd00001010* + ID_PRODUCT_FROM_DATABASE=LSI U320 SCSI Controller + +pci:v00001000d00000030sv0000103Csd000012C5* + ID_PRODUCT_FROM_DATABASE=Ultra320 SCSI [A7173A] + +pci:v00001000d00000030sv0000103Csd00001323* + ID_PRODUCT_FROM_DATABASE=Core I/O LAN/SCSI Combo [AB314A] + +pci:v00001000d00000030sv0000103Csd00003108* + ID_PRODUCT_FROM_DATABASE=Single Channel Ultra320 SCSI HBA G2 + +pci:v00001000d00000030sv0000124Bsd00001170* + ID_PRODUCT_FROM_DATABASE=PMC-USCSI320 + +pci:v00001000d00000030sv000015ADsd00001976* + ID_PRODUCT_FROM_DATABASE=LSI Logic Parallel SCSI Controller + +pci:v00001000d00000030sv00001734sd00001052* + ID_PRODUCT_FROM_DATABASE=PRIMERGY BX/RX/TX S2 series onboard SCSI(IME) + +pci:v00001000d00000031* + ID_PRODUCT_FROM_DATABASE=53c1030ZC PCI-X Fusion-MPT Dual Ultra320 SCSI + +pci:v00001000d00000032* + ID_PRODUCT_FROM_DATABASE=53c1035 PCI-X Fusion-MPT Dual Ultra320 SCSI + +pci:v00001000d00000032sv00001000sd00001000* + ID_PRODUCT_FROM_DATABASE=LSI53C1020/1030 PCI-X to Ultra320 SCSI Controller + +pci:v00001000d00000033* + ID_PRODUCT_FROM_DATABASE=1030ZC_53c1035 PCI-X Fusion-MPT Dual Ultra320 SCSI + +pci:v00001000d00000040* + ID_PRODUCT_FROM_DATABASE=53c1035 PCI-X Fusion-MPT Dual Ultra320 SCSI + +pci:v00001000d00000040sv00001000sd00000033* + ID_PRODUCT_FROM_DATABASE=MegaRAID SCSI 320-2XR + +pci:v00001000d00000040sv00001000sd00000066* + ID_PRODUCT_FROM_DATABASE=MegaRAID SCSI 320-2XRWS + +pci:v00001000d00000041* + ID_PRODUCT_FROM_DATABASE=53C1035ZC PCI-X Fusion-MPT Dual Ultra320 SCSI + +pci:v00001000d00000050* + ID_PRODUCT_FROM_DATABASE=SAS1064 PCI-X Fusion-MPT SAS + +pci:v00001000d00000050sv00001028sd00001F04* + ID_PRODUCT_FROM_DATABASE=SAS 5/E + +pci:v00001000d00000050sv00001028sd00001F09* + ID_PRODUCT_FROM_DATABASE=SAS 5i/R + +pci:v00001000d00000054* + ID_PRODUCT_FROM_DATABASE=SAS1068 PCI-X Fusion-MPT SAS + +pci:v00001000d00000054sv00001028sd00001F04* + ID_PRODUCT_FROM_DATABASE=SAS 5/E Adapter Controller + +pci:v00001000d00000054sv00001028sd00001F05* + ID_PRODUCT_FROM_DATABASE=SAS 5/i Adapter Controller + +pci:v00001000d00000054sv00001028sd00001F06* + ID_PRODUCT_FROM_DATABASE=SAS 5/i Integrated Controller + +pci:v00001000d00000054sv00001028sd00001F07* + ID_PRODUCT_FROM_DATABASE=SAS 5/iR Integrated RAID Controller + +pci:v00001000d00000054sv00001028sd00001F08* + ID_PRODUCT_FROM_DATABASE=SAS 5/iR Integrated RAID Controller + +pci:v00001000d00000054sv00001028sd00001F09* + ID_PRODUCT_FROM_DATABASE=SAS 5/iR Adapter RAID Controller + +pci:v00001000d00000054sv000015ADsd00001976* + ID_PRODUCT_FROM_DATABASE=SAS Controller + +pci:v00001000d00000055* + ID_PRODUCT_FROM_DATABASE=SAS1068 PCI-X Fusion-MPT SAS + +pci:v00001000d00000055sv00001033sd00008336* + ID_PRODUCT_FROM_DATABASE=SAS1068 + +pci:v00001000d00000056* + ID_PRODUCT_FROM_DATABASE=SAS1064ET PCI-Express Fusion-MPT SAS + +pci:v00001000d00000056sv00001014sd000003BB* + ID_PRODUCT_FROM_DATABASE=ServeRAID BR10il SAS/SATA Controller v2 + +pci:v00001000d00000057* + ID_PRODUCT_FROM_DATABASE=M1064E MegaRAID SAS + +pci:v00001000d00000057sv00008086sd0000346C* + ID_PRODUCT_FROM_DATABASE=Embedded Software RAID Technology II (ESTRII) + +pci:v00001000d00000058* + ID_PRODUCT_FROM_DATABASE=SAS1068E PCI-Express Fusion-MPT SAS + +pci:v00001000d00000058sv00001000sd00003140* + ID_PRODUCT_FROM_DATABASE=SAS3081E-R 8-Port SAS/SATA Host Bus Adapter + +pci:v00001000d00000058sv00001028sd0000021D* + ID_PRODUCT_FROM_DATABASE=SAS 6/iR Integrated Workstations RAID Controller + +pci:v00001000d00000058sv00001028sd00001F0E* + ID_PRODUCT_FROM_DATABASE=SAS 6/iR Adapter RAID Controller + +pci:v00001000d00000058sv00001028sd00001F0F* + ID_PRODUCT_FROM_DATABASE=SAS 6/iR Integrated Blades RAID Controller + +pci:v00001000d00000058sv00001028sd00001F10* + ID_PRODUCT_FROM_DATABASE=SAS 6/iR Integrated RAID Controller + +pci:v00001000d00000058sv0000103Csd00003229* + ID_PRODUCT_FROM_DATABASE=SC44Ge Host Bus Adapter + +pci:v00001000d00000059* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 8208ELP/8208ELP + +pci:v00001000d0000005A* + ID_PRODUCT_FROM_DATABASE=SAS1066E PCI-Express Fusion-MPT SAS + +pci:v00001000d0000005B* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 2208 [Thunderbolt] + +pci:v00001000d0000005Bsv00001000sd00009265* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9265-8i + +pci:v00001000d0000005Bsv00001000sd00009266* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9266-8i + +pci:v00001000d0000005Bsv00001000sd00009267* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9267-8i + +pci:v00001000d0000005Bsv00001000sd00009268* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9265CV-8i / 9270CV-8i + +pci:v00001000d0000005Bsv00001000sd00009269* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9266-4i + +pci:v00001000d0000005Bsv00001000sd00009270* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9270-8i + +pci:v00001000d0000005Bsv00001000sd00009271* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9271-8i + +pci:v00001000d0000005Bsv00001000sd00009272* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9272-8i + +pci:v00001000d0000005Bsv00001000sd00009273* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9270CV-8i + +pci:v00001000d0000005Bsv00001000sd00009274* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9270-4i + +pci:v00001000d0000005Bsv00001000sd00009275* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9271-8iCC + +pci:v00001000d0000005Bsv00001000sd00009276* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9271-4i + +pci:v00001000d0000005Bsv00001000sd00009285* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9285-8e + +pci:v00001000d0000005Bsv00001000sd00009288* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9285CV-8e + +pci:v00001000d0000005Bsv00001000sd00009290* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9286-8e + +pci:v00001000d0000005Bsv00001000sd00009291* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9286CV-8e + +pci:v00001000d0000005Bsv00001000sd00009295* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9286CV-8eCC + +pci:v00001000d0000005Bsv00001014sd0000040B* + ID_PRODUCT_FROM_DATABASE=ServeRAID M5110 SAS/SATA Controller + +pci:v00001000d0000005Bsv00001014sd00000412* + ID_PRODUCT_FROM_DATABASE=ServeRAID M5110e SAS/SATA Controller + +pci:v00001000d0000005Bsv00001028sd00001F2D* + ID_PRODUCT_FROM_DATABASE=PERC H810 Adapter + +pci:v00001000d0000005Bsv00001028sd00001F30* + ID_PRODUCT_FROM_DATABASE=PERC H710 Embedded + +pci:v00001000d0000005Bsv00001028sd00001F31* + ID_PRODUCT_FROM_DATABASE=PERC H710P Adapter + +pci:v00001000d0000005Bsv00001028sd00001F33* + ID_PRODUCT_FROM_DATABASE=PERC H710P Mini (for blades) + +pci:v00001000d0000005Bsv00001028sd00001F34* + ID_PRODUCT_FROM_DATABASE=PERC H710P Mini (for monolithics) + +pci:v00001000d0000005Bsv00001028sd00001F35* + ID_PRODUCT_FROM_DATABASE=PERC H710 Adapter + +pci:v00001000d0000005Bsv00001028sd00001F37* + ID_PRODUCT_FROM_DATABASE=PERC H710 Mini (for blades) + +pci:v00001000d0000005Bsv00001028sd00001F38* + ID_PRODUCT_FROM_DATABASE=PERC H710 Mini (for monolithics) + +pci:v00001000d0000005Bsv00008086sd00003513* + ID_PRODUCT_FROM_DATABASE=RMS25CB080 RAID Controller + +pci:v00001000d0000005C* + ID_PRODUCT_FROM_DATABASE=SAS1064A PCI-X Fusion-MPT SAS + +pci:v00001000d0000005D* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS-3 3108 [Invader] + +pci:v00001000d0000005E* + ID_PRODUCT_FROM_DATABASE=SAS1066 PCI-X Fusion-MPT SAS + +pci:v00001000d0000005F* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS-3 3008 [Fury] + +pci:v00001000d00000060* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 1078 + +pci:v00001000d00000060sv00001000sd00001006* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 8888ELP + +pci:v00001000d00000060sv00001000sd0000100A* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 8708ELP + +pci:v00001000d00000060sv00001000sd0000100E* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 8884E + +pci:v00001000d00000060sv00001000sd0000100F* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 8708E + +pci:v00001000d00000060sv00001000sd00001010* + ID_PRODUCT_FROM_DATABASE=MegaRAID SATA 350-8ELP + +pci:v00001000d00000060sv00001000sd00001011* + ID_PRODUCT_FROM_DATABASE=MegaRAID SATA 350-4ELP + +pci:v00001000d00000060sv00001000sd00001012* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 8704ELP + +pci:v00001000d00000060sv00001000sd00001016* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 8880EM2 + +pci:v00001000d00000060sv00001014sd00000363* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS PCI Express ROMB + +pci:v00001000d00000060sv00001014sd00000364* + ID_PRODUCT_FROM_DATABASE=SystemX MegaRAID SAS 8808E + +pci:v00001000d00000060sv00001014sd00000365* + ID_PRODUCT_FROM_DATABASE=SystemX MegaRAID SAS 8884E + +pci:v00001000d00000060sv00001014sd00000379* + ID_PRODUCT_FROM_DATABASE=SystemX MegaRAID SAS 8880EM2 + +pci:v00001000d00000060sv00001028sd00001F0A* + ID_PRODUCT_FROM_DATABASE=PERC 6/E Adapter RAID Controller + +pci:v00001000d00000060sv00001028sd00001F0B* + ID_PRODUCT_FROM_DATABASE=PERC 6/i Adapter RAID Controller + +pci:v00001000d00000060sv00001028sd00001F0C* + ID_PRODUCT_FROM_DATABASE=PERC 6/i Integrated RAID Controller + +pci:v00001000d00000060sv00001028sd00001F0D* + ID_PRODUCT_FROM_DATABASE=PERC 6/i Integrated RAID Controller + +pci:v00001000d00000060sv00001028sd00001F11* + ID_PRODUCT_FROM_DATABASE=CERC 6/i Integrated RAID Controller + +pci:v00001000d00000060sv00001033sd0000835A* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS PCI Express ROMB + +pci:v00001000d00000060sv00001043sd0000824D* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS PCI Express ROMB + +pci:v00001000d00000060sv00001170sd0000002F* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS PCI Express ROMB + +pci:v00001000d00000060sv00001170sd00000036* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS PCI Express ROMB + +pci:v00001000d00000060sv000015D9sd0000C080* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS PCI Express ROMB + +pci:v00001000d00000060sv000017AAsd00006B7C* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS PCI Express ROMB + +pci:v00001000d00000060sv000018A1sd00000003* + ID_PRODUCT_FROM_DATABASE=LSI MegaRAID SAS PCI Express ROMB + +pci:v00001000d00000060sv00008086sd00001006* + ID_PRODUCT_FROM_DATABASE=RAID Controller SRCSAS28EP + +pci:v00001000d00000060sv00008086sd0000100A* + ID_PRODUCT_FROM_DATABASE=RAID Controller SRCSAS28EV + +pci:v00001000d00000060sv00008086sd00001010* + ID_PRODUCT_FROM_DATABASE=RAID Controller SRCSATA28E + +pci:v00001000d00000060sv00008086sd000034CC* + ID_PRODUCT_FROM_DATABASE=Integrated RAID Controller SROMBSAS28E + +pci:v00001000d00000060sv00008086sd000034CD* + ID_PRODUCT_FROM_DATABASE=Integrated RAID Controller SROMBSAS28E + +pci:v00001000d00000060sv00008086sd00003505* + ID_PRODUCT_FROM_DATABASE=Integrated RAID Controller SROMBSASMP2 + +pci:v00001000d00000062* + ID_PRODUCT_FROM_DATABASE=SAS1078 PCI-Express Fusion-MPT SAS + +pci:v00001000d00000062sv00001000sd00000062* + ID_PRODUCT_FROM_DATABASE=SAS1078 PCI-Express Fusion-MPT SAS + +pci:v00001000d00000064* + ID_PRODUCT_FROM_DATABASE=SAS2116 PCI-Express Fusion-MPT SAS-2 [Meteor] + +pci:v00001000d00000065* + ID_PRODUCT_FROM_DATABASE=SAS2116 PCI-Express Fusion-MPT SAS-2 [Meteor] + +pci:v00001000d0000006E* + ID_PRODUCT_FROM_DATABASE=SAS2308 PCI-Express Fusion-MPT SAS-2 + +pci:v00001000d00000070* + ID_PRODUCT_FROM_DATABASE=SAS2004 PCI-Express Fusion-MPT SAS-2 [Spitfire] + +pci:v00001000d00000071* + ID_PRODUCT_FROM_DATABASE=MR SAS HBA 2004 + +pci:v00001000d00000072* + ID_PRODUCT_FROM_DATABASE=SAS2008 PCI-Express Fusion-MPT SAS-2 [Falcon] + +pci:v00001000d00000072sv00001028sd00001F1C* + ID_PRODUCT_FROM_DATABASE=6Gbps SAS HBA Adapter + +pci:v00001000d00000072sv00001028sd00001F1D* + ID_PRODUCT_FROM_DATABASE=PERC H200 Adapter + +pci:v00001000d00000072sv00001028sd00001F1E* + ID_PRODUCT_FROM_DATABASE=PERC H200 Integrated + +pci:v00001000d00000072sv00001028sd00001F1F* + ID_PRODUCT_FROM_DATABASE=PERC H200 Modular + +pci:v00001000d00000072sv00001028sd00001F20* + ID_PRODUCT_FROM_DATABASE=PERC H200 Embedded + +pci:v00001000d00000072sv00001028sd00001F22* + ID_PRODUCT_FROM_DATABASE=Internal Tape Adapter + +pci:v00001000d00000072sv00008086sd0000350F* + ID_PRODUCT_FROM_DATABASE=RMS2LL040 RAID Controller + +pci:v00001000d00000073* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 2008 [Falcon] + +pci:v00001000d00000073sv00001000sd00009240* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9240-8i + +pci:v00001000d00000073sv00001000sd00009241* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9240-4i + +pci:v00001000d00000073sv00001000sd000092A0* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9220-8i + +pci:v00001000d00000073sv00001014sd000003B1* + ID_PRODUCT_FROM_DATABASE=ServeRAID M1015 SAS/SATA Controller + +pci:v00001000d00000073sv00001028sd00001F4E* + ID_PRODUCT_FROM_DATABASE=PERC H310 Adapter + +pci:v00001000d00000073sv00001028sd00001F4F* + ID_PRODUCT_FROM_DATABASE=PERC H310 Integrated + +pci:v00001000d00000073sv00001028sd00001F50* + ID_PRODUCT_FROM_DATABASE=PERC H310 Mini Blades + +pci:v00001000d00000073sv00001028sd00001F51* + ID_PRODUCT_FROM_DATABASE=PERC H310 Mini Monolithics + +pci:v00001000d00000073sv00001028sd00001F52* + ID_PRODUCT_FROM_DATABASE=PERC H310 Embedded1 + +pci:v00001000d00000073sv00001028sd00001F53* + ID_PRODUCT_FROM_DATABASE=PERC H310 Embedded2 + +pci:v00001000d00000073sv00001028sd00001F54* + ID_PRODUCT_FROM_DATABASE=PERC H310 Reserved + +pci:v00001000d00000073sv00001054sd00003035* + ID_PRODUCT_FROM_DATABASE=LSI MegaRAID SAS 9240-8i + +pci:v00001000d00000073sv00001137sd00000072* + ID_PRODUCT_FROM_DATABASE=2004 iMR ROMB + +pci:v00001000d00000073sv00001137sd00000073* + ID_PRODUCT_FROM_DATABASE=2008 ROMB + +pci:v00001000d00000073sv00001137sd000000B0* + ID_PRODUCT_FROM_DATABASE=UCSC RAID SAS 2008M-8i + +pci:v00001000d00000073sv00001137sd000000B1* + ID_PRODUCT_FROM_DATABASE=UCSC RAID SAS 2008M-8i + +pci:v00001000d00000073sv000015D9sd00000400* + ID_PRODUCT_FROM_DATABASE=Supermicro SMC2008-iMR + +pci:v00001000d00000073sv00001734sd00001177* + ID_PRODUCT_FROM_DATABASE=RAID Ctrl SAS 6G 0/1 (D2607) + +pci:v00001000d00000073sv00008086sd0000350D* + ID_PRODUCT_FROM_DATABASE=RMS2AF040 RAID Controller + +pci:v00001000d00000073sv00008086sd00009240* + ID_PRODUCT_FROM_DATABASE=RAID Controller RS2WC080 + +pci:v00001000d00000073sv00008086sd00009241* + ID_PRODUCT_FROM_DATABASE=RAID Controller RS2WC040 + +pci:v00001000d00000074* + ID_PRODUCT_FROM_DATABASE=SAS2108 PCI-Express Fusion-MPT SAS-2 [Liberator] + +pci:v00001000d00000076* + ID_PRODUCT_FROM_DATABASE=SAS2108 PCI-Express Fusion-MPT SAS-2 [Liberator] + +pci:v00001000d00000077* + ID_PRODUCT_FROM_DATABASE=SAS2108 PCI-Express Fusion-MPT SAS-2 [Liberator] + +pci:v00001000d00000079* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 2108 [Liberator] + +pci:v00001000d00000079sv00001000sd00009251* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9260-4ix + +pci:v00001000d00000079sv00001000sd00009256* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9260-8ix + +pci:v00001000d00000079sv00001000sd00009260* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9260-4i + +pci:v00001000d00000079sv00001000sd00009261* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9260-8i + +pci:v00001000d00000079sv00001000sd00009262* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9262-8i + +pci:v00001000d00000079sv00001000sd00009263* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9261-8i + +pci:v00001000d00000079sv00001000sd00009264* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9264-8i + +pci:v00001000d00000079sv00001000sd00009267* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9260CV-4i + +pci:v00001000d00000079sv00001000sd00009268* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9260CV-8i + +pci:v00001000d00000079sv00001000sd00009275* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9280-8ex + +pci:v00001000d00000079sv00001000sd00009276* + ID_PRODUCT_FROM_DATABASE=MR9260-16i + +pci:v00001000d00000079sv00001000sd00009280* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9280-8e + +pci:v00001000d00000079sv00001000sd00009281* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9281-8E + +pci:v00001000d00000079sv00001000sd00009282* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9280-4i4e + +pci:v00001000d00000079sv00001000sd00009290* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9280DE-24i4e + +pci:v00001000d00000079sv00001014sd000003B2* + ID_PRODUCT_FROM_DATABASE=ServeRAID M5015 SAS/SATA Controller + +pci:v00001000d00000079sv00001014sd000003B3* + ID_PRODUCT_FROM_DATABASE=ServeRAID M5025 SAS/SATA Controller + +pci:v00001000d00000079sv00001028sd00001F15* + ID_PRODUCT_FROM_DATABASE=PERC H800 Adapter + +pci:v00001000d00000079sv00001028sd00001F16* + ID_PRODUCT_FROM_DATABASE=PERC H700 Adapter + +pci:v00001000d00000079sv00001028sd00001F17* + ID_PRODUCT_FROM_DATABASE=PERC H700 Integrated + +pci:v00001000d00000079sv00001028sd00001F18* + ID_PRODUCT_FROM_DATABASE=PERC H700 Modular + +pci:v00001000d00000079sv00001028sd00001F1A* + ID_PRODUCT_FROM_DATABASE=PERC H800 Proto Adapter + +pci:v00001000d00000079sv00001028sd00001F1B* + ID_PRODUCT_FROM_DATABASE=PERC H700 Integrated + +pci:v00001000d00000079sv00001043sd00008480* + ID_PRODUCT_FROM_DATABASE=PIKE-2108 16PD + +pci:v00001000d00000079sv00001734sd00001176* + ID_PRODUCT_FROM_DATABASE=RAID Ctrl SAS 6G 5/6 512MB (D2616) + +pci:v00001000d00000079sv00001734sd00001177* + ID_PRODUCT_FROM_DATABASE=RAID Ctrl SAS 6G 0/1 (D2607) + +pci:v00001000d00000079sv00008086sd00009256* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 9260DE-8i + +pci:v00001000d00000079sv00008086sd00009260* + ID_PRODUCT_FROM_DATABASE=RAID Controller RS2BL040 + +pci:v00001000d00000079sv00008086sd00009261* + ID_PRODUCT_FROM_DATABASE=RAID Controller RS2BL080 + +pci:v00001000d00000079sv00008086sd00009264* + ID_PRODUCT_FROM_DATABASE=Warm Beach (Caster Lite) + +pci:v00001000d00000079sv00008086sd00009267* + ID_PRODUCT_FROM_DATABASE=RAID Controller RS2VB040 + +pci:v00001000d00000079sv00008086sd00009268* + ID_PRODUCT_FROM_DATABASE=RAID Controller RS2VB080 + +pci:v00001000d0000007C* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 1078DE + +pci:v00001000d0000007Csv00001014sd00000395* + ID_PRODUCT_FROM_DATABASE=ServeRAID-AR10is SAS/SATA Controller + +pci:v00001000d0000007E* + ID_PRODUCT_FROM_DATABASE=SSS6200 PCI-Express Flash SSD + +pci:v00001000d00000080* + ID_PRODUCT_FROM_DATABASE=SAS2208 PCI-Express Fusion-MPT SAS-2 + +pci:v00001000d00000081* + ID_PRODUCT_FROM_DATABASE=SAS2208 PCI-Express Fusion-MPT SAS-2 + +pci:v00001000d00000082* + ID_PRODUCT_FROM_DATABASE=SAS2208 PCI-Express Fusion-MPT SAS-2 + +pci:v00001000d00000083* + ID_PRODUCT_FROM_DATABASE=SAS2208 PCI-Express Fusion-MPT SAS-2 + +pci:v00001000d00000084* + ID_PRODUCT_FROM_DATABASE=SAS2208 PCI-Express Fusion-MPT SAS-2 + +pci:v00001000d00000085* + ID_PRODUCT_FROM_DATABASE=SAS2208 PCI-Express Fusion-MPT SAS-2 + +pci:v00001000d00000086* + ID_PRODUCT_FROM_DATABASE=SAS2308 PCI-Express Fusion-MPT SAS-2 + +pci:v00001000d00000087* + ID_PRODUCT_FROM_DATABASE=SAS2308 PCI-Express Fusion-MPT SAS-2 + +pci:v00001000d00000087sv00001590sd00000044* + ID_PRODUCT_FROM_DATABASE=H220i + +pci:v00001000d0000008F* + ID_PRODUCT_FROM_DATABASE=53c875J + +pci:v00001000d0000008Fsv00001092sd00008000* + ID_PRODUCT_FROM_DATABASE=FirePort 40 SCSI Controller + +pci:v00001000d0000008Fsv00001092sd00008760* + ID_PRODUCT_FROM_DATABASE=FirePort 40 Dual SCSI Host Adapter + +pci:v00001000d00000090* + ID_PRODUCT_FROM_DATABASE=SAS3108 PCI-Express Fusion-MPT SAS-3 + +pci:v00001000d00000091* + ID_PRODUCT_FROM_DATABASE=SAS3108 PCI-Express Fusion-MPT SAS-3 + +pci:v00001000d00000094* + ID_PRODUCT_FROM_DATABASE=SAS3108 PCI-Express Fusion-MPT SAS-3 + +pci:v00001000d00000095* + ID_PRODUCT_FROM_DATABASE=SAS3108 PCI-Express Fusion-MPT SAS-3 + +pci:v00001000d00000096* + ID_PRODUCT_FROM_DATABASE=SAS3004 PCI-Express Fusion-MPT SAS-3 + +pci:v00001000d00000097* + ID_PRODUCT_FROM_DATABASE=SAS3008 PCI-Express Fusion-MPT SAS-3 + +pci:v00001000d00000407* + ID_PRODUCT_FROM_DATABASE=MegaRAID + +pci:v00001000d00000407sv00001000sd00000530* + ID_PRODUCT_FROM_DATABASE=MegaRAID 530 SCSI 320-0X RAID Controller + +pci:v00001000d00000407sv00001000sd00000531* + ID_PRODUCT_FROM_DATABASE=MegaRAID 531 SCSI 320-4X RAID Controller + +pci:v00001000d00000407sv00001000sd00000532* + ID_PRODUCT_FROM_DATABASE=MegaRAID 532 SCSI 320-2X RAID Controller + +pci:v00001000d00000407sv00001028sd00000531* + ID_PRODUCT_FROM_DATABASE=PowerEdge Expandable RAID Controller 4/QC + +pci:v00001000d00000407sv00001028sd00000533* + ID_PRODUCT_FROM_DATABASE=PowerEdge Expandable RAID Controller 4/QC + +pci:v00001000d00000407sv00008086sd00000530* + ID_PRODUCT_FROM_DATABASE=MegaRAID Intel RAID Controller SRCZCRX + +pci:v00001000d00000407sv00008086sd00000532* + ID_PRODUCT_FROM_DATABASE=MegaRAID Intel RAID Controller SRCU42X + +pci:v00001000d00000408* + ID_PRODUCT_FROM_DATABASE=MegaRAID + +pci:v00001000d00000408sv00001000sd00000001* + ID_PRODUCT_FROM_DATABASE=MegaRAID SCSI 320-1E RAID Controller + +pci:v00001000d00000408sv00001000sd00000002* + ID_PRODUCT_FROM_DATABASE=MegaRAID SCSI 320-2E RAID Controller + +pci:v00001000d00000408sv00001025sd0000004D* + ID_PRODUCT_FROM_DATABASE=MegaRAID ACER ROMB-2E RAID Controller + +pci:v00001000d00000408sv00001028sd00000001* + ID_PRODUCT_FROM_DATABASE=PowerEdge RAID Controller PERC4e/SC + +pci:v00001000d00000408sv00001028sd00000002* + ID_PRODUCT_FROM_DATABASE=PowerEdge RAID Controller PERC4e/DC + +pci:v00001000d00000408sv00001028sd00000012* + ID_PRODUCT_FROM_DATABASE=PowerEdge RAID Controller RAC4 + +pci:v00001000d00000408sv00001028sd00000015* + ID_PRODUCT_FROM_DATABASE=PowerEdge RAID Controller PERC5 + +pci:v00001000d00000408sv00001028sd00001F03* + ID_PRODUCT_FROM_DATABASE=PowerEdge RAID Controller PERC5 + +pci:v00001000d00000408sv00001734sd00001065* + ID_PRODUCT_FROM_DATABASE=FSC MegaRAID PCI Express ROMB + +pci:v00001000d00000408sv00008086sd00000002* + ID_PRODUCT_FROM_DATABASE=MegaRAID Intel RAID Controller SRCU42E + +pci:v00001000d00000408sv00008086sd00003449* + ID_PRODUCT_FROM_DATABASE=MegaRAID Intel RAID Controller SROMBU + +pci:v00001000d00000409* + ID_PRODUCT_FROM_DATABASE=MegaRAID + +pci:v00001000d00000409sv00001000sd00003004* + ID_PRODUCT_FROM_DATABASE=MegaRAID SATA 300-4X RAID Controller + +pci:v00001000d00000409sv00001000sd00003008* + ID_PRODUCT_FROM_DATABASE=MegaRAID SATA 300-8X RAID Controller + +pci:v00001000d00000409sv00008086sd00003008* + ID_PRODUCT_FROM_DATABASE=MegaRAID RAID Controller SRCS28X + +pci:v00001000d00000409sv00008086sd00003431* + ID_PRODUCT_FROM_DATABASE=MegaRAID RAID Controller Alief SROMBU42E + +pci:v00001000d00000409sv00008086sd00003499* + ID_PRODUCT_FROM_DATABASE=MegaRAID RAID Controller Harwich SROMBU42E + +pci:v00001000d00000411* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 1068 + +pci:v00001000d00000411sv00001000sd00001001* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 8408E + +pci:v00001000d00000411sv00001000sd00001002* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 8480E + +pci:v00001000d00000411sv00001000sd00001003* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 8344ELP + +pci:v00001000d00000411sv00001000sd00001004* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 8308ELP + +pci:v00001000d00000411sv00001000sd00001008* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 84016E + +pci:v00001000d00000411sv00001000sd0000100C* + ID_PRODUCT_FROM_DATABASE=MegaRAID SATA 300-12E + +pci:v00001000d00000411sv00001000sd0000100D* + ID_PRODUCT_FROM_DATABASE=MegaRAID SATA 300-16E + +pci:v00001000d00000411sv00001000sd00002004* + ID_PRODUCT_FROM_DATABASE=MegaRAID SATA 300-8ELP + +pci:v00001000d00000411sv00001000sd00002005* + ID_PRODUCT_FROM_DATABASE=MegaRAID SATA 300-4ELP + +pci:v00001000d00000411sv00001033sd00008287* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS PCI Express ROMB + +pci:v00001000d00000411sv00001054sd00003016* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS RoMB Server + +pci:v00001000d00000411sv00001734sd00001081* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS PCI Express ROMB + +pci:v00001000d00000411sv00001734sd000010A3* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS PCI Express ROMB + +pci:v00001000d00000411sv00008086sd00001001* + ID_PRODUCT_FROM_DATABASE=RAID Controller SRCSAS18E + +pci:v00001000d00000411sv00008086sd00001003* + ID_PRODUCT_FROM_DATABASE=RAID Controller SRCSAS144E + +pci:v00001000d00000411sv00008086sd00003500* + ID_PRODUCT_FROM_DATABASE=SROMBSAS18E RAID Controller + +pci:v00001000d00000411sv00008086sd00003501* + ID_PRODUCT_FROM_DATABASE=SROMBSAS18E RAID Controller + +pci:v00001000d00000411sv00008086sd00003504* + ID_PRODUCT_FROM_DATABASE=SROMBSAS18E RAID Controller + +pci:v00001000d00000413* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 1068 [Verde ZCR] + +pci:v00001000d00000413sv00001000sd00001005* + ID_PRODUCT_FROM_DATABASE=MegaRAID SAS 8300XLP + +pci:v00001000d00000621* + ID_PRODUCT_FROM_DATABASE=FC909 Fibre Channel Adapter + +pci:v00001000d00000622* + ID_PRODUCT_FROM_DATABASE=FC929 Fibre Channel Adapter + +pci:v00001000d00000622sv00001000sd00001020* + ID_PRODUCT_FROM_DATABASE=44929 O Dual Fibre Channel card + +pci:v00001000d00000623* + ID_PRODUCT_FROM_DATABASE=FC929 LAN + +pci:v00001000d00000624* + ID_PRODUCT_FROM_DATABASE=FC919 Fibre Channel Adapter + +pci:v00001000d00000625* + ID_PRODUCT_FROM_DATABASE=FC919 LAN + +pci:v00001000d00000626* + ID_PRODUCT_FROM_DATABASE=FC929X Fibre Channel Adapter + +pci:v00001000d00000626sv00001000sd00001010* + ID_PRODUCT_FROM_DATABASE=7202-XP-LC Dual Fibre Channel card + +pci:v00001000d00000627* + ID_PRODUCT_FROM_DATABASE=FC929X LAN + +pci:v00001000d00000628* + ID_PRODUCT_FROM_DATABASE=FC919X Fibre Channel Adapter + +pci:v00001000d00000629* + ID_PRODUCT_FROM_DATABASE=FC919X LAN + +pci:v00001000d00000640* + ID_PRODUCT_FROM_DATABASE=FC949X Fibre Channel Adapter + +pci:v00001000d00000642* + ID_PRODUCT_FROM_DATABASE=FC939X Fibre Channel Adapter + +pci:v00001000d00000646* + ID_PRODUCT_FROM_DATABASE=FC949ES Fibre Channel Adapter + +pci:v00001000d00000701* + ID_PRODUCT_FROM_DATABASE=83C885 NT50 DigitalScape Fast Ethernet + +pci:v00001000d00000702* + ID_PRODUCT_FROM_DATABASE=Yellowfin G-NIC gigabit ethernet + +pci:v00001000d00000702sv00001318sd00000000* + ID_PRODUCT_FROM_DATABASE=PEI100X + +pci:v00001000d00000804* + ID_PRODUCT_FROM_DATABASE=SA2010 + +pci:v00001000d00000805* + ID_PRODUCT_FROM_DATABASE=SA2010ZC + +pci:v00001000d00000806* + ID_PRODUCT_FROM_DATABASE=SA2020 + +pci:v00001000d00000807* + ID_PRODUCT_FROM_DATABASE=SA2020ZC + +pci:v00001000d00000901* + ID_PRODUCT_FROM_DATABASE=61C102 + +pci:v00001000d00001000* + ID_PRODUCT_FROM_DATABASE=63C815 + +pci:v00001000d00001960* + ID_PRODUCT_FROM_DATABASE=MegaRAID + +pci:v00001000d00001960sv00001000sd00000518* + ID_PRODUCT_FROM_DATABASE=MegaRAID 518 SCSI 320-2 Controller + +pci:v00001000d00001960sv00001000sd00000520* + ID_PRODUCT_FROM_DATABASE=MegaRAID 520 SCSI 320-1 Controller + +pci:v00001000d00001960sv00001000sd00000522* + ID_PRODUCT_FROM_DATABASE=MegaRAID 522 i4 133 RAID Controller + +pci:v00001000d00001960sv00001000sd00000523* + ID_PRODUCT_FROM_DATABASE=MegaRAID SATA 150-6 RAID Controller + +pci:v00001000d00001960sv00001000sd00004523* + ID_PRODUCT_FROM_DATABASE=MegaRAID SATA 150-4 RAID Controller + +pci:v00001000d00001960sv00001000sd0000A520* + ID_PRODUCT_FROM_DATABASE=MegaRAID ZCR SCSI 320-0 Controller + +pci:v00001000d00001960sv00001028sd00000518* + ID_PRODUCT_FROM_DATABASE=MegaRAID 518 DELL PERC 4/DC RAID Controller + +pci:v00001000d00001960sv00001028sd00000520* + ID_PRODUCT_FROM_DATABASE=MegaRAID 520 DELL PERC 4/SC RAID Controller + +pci:v00001000d00001960sv00001028sd00000531* + ID_PRODUCT_FROM_DATABASE=PowerEdge Expandable RAID Controller 4/QC + +pci:v00001000d00001960sv00001028sd00000533* + ID_PRODUCT_FROM_DATABASE=PowerEdge Expandable RAID Controller 4/QC + +pci:v00001000d00001960sv00008086sd00000520* + ID_PRODUCT_FROM_DATABASE=MegaRAID RAID Controller SRCU41L + +pci:v00001000d00001960sv00008086sd00000523* + ID_PRODUCT_FROM_DATABASE=MegaRAID RAID Controller SRCS16 + +pci:v00001000d00006001* + ID_PRODUCT_FROM_DATABASE=DX1 Multiformat Broadcast HD/SD Encoder/Decoder + +pci:v00001001* + ID_VENDOR_FROM_DATABASE=Kolter Electronic + +pci:v00001001d00000010* + ID_PRODUCT_FROM_DATABASE=PCI 1616 Measurement card with 32 digital I/O lines + +pci:v00001001d00000011* + ID_PRODUCT_FROM_DATABASE=OPTO-PCI Opto-Isolated digital I/O board + +pci:v00001001d00000012* + ID_PRODUCT_FROM_DATABASE=PCI-AD/DA Analogue I/O board + +pci:v00001001d00000013* + ID_PRODUCT_FROM_DATABASE=PCI-OPTO-RELAIS Digital I/O board with relay outputs + +pci:v00001001d00000014* + ID_PRODUCT_FROM_DATABASE=PCI-Counter/Timer Counter Timer board + +pci:v00001001d00000015* + ID_PRODUCT_FROM_DATABASE=PCI-DAC416 Analogue output board + +pci:v00001001d00000016* + ID_PRODUCT_FROM_DATABASE=PCI-MFB Analogue I/O board + +pci:v00001001d00000017* + ID_PRODUCT_FROM_DATABASE=PROTO-3 PCI Prototyping board + +pci:v00001001d00009100* + ID_PRODUCT_FROM_DATABASE=INI-9100/9100W SCSI Host + +pci:v00001002* + ID_VENDOR_FROM_DATABASE=Advanced Micro Devices [AMD] nee ATI + +pci:v00001002d00001314* + ID_PRODUCT_FROM_DATABASE=Wrestler HDMI Audio [Radeon HD 6250/6310] + +pci:v00001002d00001314sv0000174Bsd00001001* + ID_PRODUCT_FROM_DATABASE=Sapphire PURE Fusion Mini + +pci:v00001002d00001714* + ID_PRODUCT_FROM_DATABASE=BeaverCreek HDMI Audio [Radeon HD 6500D and 6400G-6600G series] + +pci:v00001002d00001714sv0000103Csd0000168B* + ID_PRODUCT_FROM_DATABASE=ProBook 4535s + +pci:v00001002d00003150* + ID_PRODUCT_FROM_DATABASE=M24 1P [Radeon Mobility X600] + +pci:v00001002d00003150sv0000103Csd00000934* + ID_PRODUCT_FROM_DATABASE=nx8220 + +pci:v00001002d00003151* + ID_PRODUCT_FROM_DATABASE=M24 [FireMV 2400] + +pci:v00001002d00003152* + ID_PRODUCT_FROM_DATABASE=RV370 [Mobility Radeon X300] + +pci:v00001002d00003154* + ID_PRODUCT_FROM_DATABASE=M24GL [Mobility FireGL V3200] + +pci:v00001002d00003171* + ID_PRODUCT_FROM_DATABASE=M24 [FireMV 2400] (Secondary) + +pci:v00001002d00003E50* + ID_PRODUCT_FROM_DATABASE=RV380 0x3e50 [Radeon X600] + +pci:v00001002d00003E54* + ID_PRODUCT_FROM_DATABASE=RV380 0x3e54 [FireGL V3200] + +pci:v00001002d00003E70* + ID_PRODUCT_FROM_DATABASE=RV380 [Radeon X600] (Secondary) + +pci:v00001002d00004136* + ID_PRODUCT_FROM_DATABASE=RS100 [Radeon IGP320(M)] + +pci:v00001002d00004137* + ID_PRODUCT_FROM_DATABASE=RS200 [Radeon IGP330/340/350] + +pci:v00001002d00004144* + ID_PRODUCT_FROM_DATABASE=R300 AD [Radeon 9500 Pro] + +pci:v00001002d00004145* + ID_PRODUCT_FROM_DATABASE=R300 AE [Radeon 9700 Pro] + +pci:v00001002d00004146* + ID_PRODUCT_FROM_DATABASE=R300 AF [Radeon 9700 Pro] + +pci:v00001002d00004147* + ID_PRODUCT_FROM_DATABASE=R300 AG [FireGL Z1/X1] + +pci:v00001002d00004148* + ID_PRODUCT_FROM_DATABASE=R350 AH [Radeon 9800] + +pci:v00001002d00004149* + ID_PRODUCT_FROM_DATABASE=R350 AI [Radeon 9800] + +pci:v00001002d0000414A* + ID_PRODUCT_FROM_DATABASE=R350 AJ [Radeon 9800] + +pci:v00001002d0000414B* + ID_PRODUCT_FROM_DATABASE=R350 AK [FireGL X2] + +pci:v00001002d00004150* + ID_PRODUCT_FROM_DATABASE=RV350 AP [Radeon 9600] + +pci:v00001002d00004150sv00001002sd00000002* + ID_PRODUCT_FROM_DATABASE=R9600 Pro primary (Asus OEM for HP) + +pci:v00001002d00004150sv00001002sd00000003* + ID_PRODUCT_FROM_DATABASE=R9600 Pro secondary (Asus OEM for HP) + +pci:v00001002d00004150sv00001002sd00004722* + ID_PRODUCT_FROM_DATABASE=All-in-Wonder 2006 AGP Edition + +pci:v00001002d00004150sv00001458sd00004024* + ID_PRODUCT_FROM_DATABASE=Giga-Byte GV-R96128D (Primary) + +pci:v00001002d00004150sv0000148Csd00002064* + ID_PRODUCT_FROM_DATABASE=PowerColor R96A-C3N + +pci:v00001002d00004150sv0000148Csd00002066* + ID_PRODUCT_FROM_DATABASE=PowerColor R96A-C3N + +pci:v00001002d00004150sv0000174Bsd00007C19* + ID_PRODUCT_FROM_DATABASE=Sapphire Atlantis Radeon 9600 Pro + +pci:v00001002d00004150sv0000174Bsd00007C29* + ID_PRODUCT_FROM_DATABASE=GC-R9600PRO [Sapphire] (Primary) + +pci:v00001002d00004150sv000017EEsd00002002* + ID_PRODUCT_FROM_DATABASE=Radeon 9600 256Mb Primary + +pci:v00001002d00004150sv000018BCsd00000101* + ID_PRODUCT_FROM_DATABASE=GC-R9600PRO (Primary) + +pci:v00001002d00004151* + ID_PRODUCT_FROM_DATABASE=RV350 AQ [Radeon 9600] + +pci:v00001002d00004151sv00001043sd0000C004* + ID_PRODUCT_FROM_DATABASE=A9600SE + +pci:v00001002d00004152* + ID_PRODUCT_FROM_DATABASE=RV350 AR [Radeon 9600] + +pci:v00001002d00004152sv00001002sd00000002* + ID_PRODUCT_FROM_DATABASE=Radeon 9600XT + +pci:v00001002d00004152sv00001002sd00004772* + ID_PRODUCT_FROM_DATABASE=All-in-Wonder 9600 XT + +pci:v00001002d00004152sv00001043sd0000C002* + ID_PRODUCT_FROM_DATABASE=Radeon 9600 XT TVD + +pci:v00001002d00004152sv00001043sd0000C01A* + ID_PRODUCT_FROM_DATABASE=A9600XT/TD + +pci:v00001002d00004152sv0000174Bsd00007C29* + ID_PRODUCT_FROM_DATABASE=Sapphire Radeon 9600XT + +pci:v00001002d00004152sv00001787sd00004002* + ID_PRODUCT_FROM_DATABASE=Radeon 9600 XT + +pci:v00001002d00004153* + ID_PRODUCT_FROM_DATABASE=RV350 AS [Radeon 9550] + +pci:v00001002d00004153sv00001043sd0000010C* + ID_PRODUCT_FROM_DATABASE=A9550GE/TD + +pci:v00001002d00004153sv00001462sd0000932C* + ID_PRODUCT_FROM_DATABASE=RX9550SE-TD128 (MS-8932) + +pci:v00001002d00004154* + ID_PRODUCT_FROM_DATABASE=RV350 AT [FireGL T2] + +pci:v00001002d00004155* + ID_PRODUCT_FROM_DATABASE=RV350 AU [FireGL T2] + +pci:v00001002d00004156* + ID_PRODUCT_FROM_DATABASE=RV350 AV [FireGL T2] + +pci:v00001002d00004157* + ID_PRODUCT_FROM_DATABASE=RV350 AW [FireGL T2] + +pci:v00001002d00004158* + ID_PRODUCT_FROM_DATABASE=68800AX [Mach32] + +pci:v00001002d00004164* + ID_PRODUCT_FROM_DATABASE=R300 AD [Radeon 9500 Pro] (Secondary) + +pci:v00001002d00004165* + ID_PRODUCT_FROM_DATABASE=R300 AE [Radeon 9700 Pro] (Secondary) + +pci:v00001002d00004166* + ID_PRODUCT_FROM_DATABASE=R300 AF [Radeon 9700 Pro] (Secondary) + +pci:v00001002d00004168* + ID_PRODUCT_FROM_DATABASE=R350 [Radeon 9800] (Secondary) + +pci:v00001002d00004170* + ID_PRODUCT_FROM_DATABASE=RV350 AP [Radeon 9600] (Secondary) + +pci:v00001002d00004170sv00001002sd00000003* + ID_PRODUCT_FROM_DATABASE=R9600 Pro secondary (Asus OEM for HP) + +pci:v00001002d00004170sv00001002sd00004723* + ID_PRODUCT_FROM_DATABASE=All-in-Wonder 2006 AGP Edition (Secondary) + +pci:v00001002d00004170sv00001458sd00004025* + ID_PRODUCT_FROM_DATABASE=Giga-Byte GV-R96128D (Secondary) + +pci:v00001002d00004170sv0000148Csd00002067* + ID_PRODUCT_FROM_DATABASE=PowerColor R96A-C3N (Secondary) + +pci:v00001002d00004170sv0000174Bsd00007C28* + ID_PRODUCT_FROM_DATABASE=GC-R9600PRO [Sapphire] (Secondary) + +pci:v00001002d00004170sv000017EEsd00002003* + ID_PRODUCT_FROM_DATABASE=Radeon 9600 256Mb (Secondary) + +pci:v00001002d00004170sv000018BCsd00000100* + ID_PRODUCT_FROM_DATABASE=GC-R9600PRO (Secondary) + +pci:v00001002d00004171* + ID_PRODUCT_FROM_DATABASE=RV350 AQ [Radeon 9600] (Secondary) + +pci:v00001002d00004171sv00001043sd0000C005* + ID_PRODUCT_FROM_DATABASE=A9600SE (Secondary) + +pci:v00001002d00004172* + ID_PRODUCT_FROM_DATABASE=RV350 AR [Radeon 9600] (Secondary) + +pci:v00001002d00004172sv00001002sd00000003* + ID_PRODUCT_FROM_DATABASE=Radeon 9600XT (Secondary) + +pci:v00001002d00004172sv00001002sd00004773* + ID_PRODUCT_FROM_DATABASE=All-in-Wonder 9600 XT (Secondary) + +pci:v00001002d00004172sv00001043sd0000C003* + ID_PRODUCT_FROM_DATABASE=A9600XT (Secondary) + +pci:v00001002d00004172sv00001043sd0000C01B* + ID_PRODUCT_FROM_DATABASE=A9600XT/TD (Secondary) + +pci:v00001002d00004172sv0000174Bsd00007C28* + ID_PRODUCT_FROM_DATABASE=Sapphire Radeon 9600XT (Secondary) + +pci:v00001002d00004172sv00001787sd00004003* + ID_PRODUCT_FROM_DATABASE=Radeon 9600 XT (Secondary) + +pci:v00001002d00004173* + ID_PRODUCT_FROM_DATABASE=RV350 AS [Radeon 9550] (Secondary) + +pci:v00001002d00004173sv00001043sd0000010D* + ID_PRODUCT_FROM_DATABASE=A9550GE/TD (Secondary) + +pci:v00001002d00004237* + ID_PRODUCT_FROM_DATABASE=RS250 [Radeon Mobility 7000 IGP] + +pci:v00001002d00004242* + ID_PRODUCT_FROM_DATABASE=R200 BB [Radeon All in Wonder 8500DV] + +pci:v00001002d00004242sv00001002sd000002AA* + ID_PRODUCT_FROM_DATABASE=Radeon 8500 AIW DV Edition + +pci:v00001002d00004243* + ID_PRODUCT_FROM_DATABASE=R200 BC [Radeon All in Wonder 8500] + +pci:v00001002d00004336* + ID_PRODUCT_FROM_DATABASE=RS100 [Radeon IGP320M] + +pci:v00001002d00004336sv00001002sd00004336* + ID_PRODUCT_FROM_DATABASE=Pavilion ze4300 ATI Radeon Mobility U1 (IGP 320 M) + +pci:v00001002d00004336sv0000103Csd00000024* + ID_PRODUCT_FROM_DATABASE=Pavilion ze4400 builtin Video + +pci:v00001002d00004336sv0000161Fsd00002029* + ID_PRODUCT_FROM_DATABASE=eMachines M5312 builtin Video + +pci:v00001002d00004337* + ID_PRODUCT_FROM_DATABASE=RS200 [Radeon IGP330M/340M/350M] + +pci:v00001002d00004337sv00001014sd0000053A* + ID_PRODUCT_FROM_DATABASE=ThinkPad R40e + +pci:v00001002d00004337sv0000103Csd00000850* + ID_PRODUCT_FROM_DATABASE=Radeon IGP 345M + +pci:v00001002d00004341* + ID_PRODUCT_FROM_DATABASE=IXP150 AC'97 Audio Controller + +pci:v00001002d00004342* + ID_PRODUCT_FROM_DATABASE=IXP200 3COM 3C920B Ethernet Controller + +pci:v00001002d00004345* + ID_PRODUCT_FROM_DATABASE=EHCI USB Controller + +pci:v00001002d00004347* + ID_PRODUCT_FROM_DATABASE=OHCI USB Controller #1 + +pci:v00001002d00004348* + ID_PRODUCT_FROM_DATABASE=OHCI USB Controller #2 + +pci:v00001002d00004349* + ID_PRODUCT_FROM_DATABASE=Dual Channel Bus Master PCI IDE Controller + +pci:v00001002d0000434D* + ID_PRODUCT_FROM_DATABASE=IXP AC'97 Modem + +pci:v00001002d00004353* + ID_PRODUCT_FROM_DATABASE=SMBus + +pci:v00001002d00004354* + ID_PRODUCT_FROM_DATABASE=215CT [Mach64 CT] + +pci:v00001002d00004358* + ID_PRODUCT_FROM_DATABASE=210888CX [Mach64 CX] + +pci:v00001002d00004361* + ID_PRODUCT_FROM_DATABASE=IXP SB300 AC'97 Audio Controller + +pci:v00001002d00004363* + ID_PRODUCT_FROM_DATABASE=SMBus + +pci:v00001002d0000436E* + ID_PRODUCT_FROM_DATABASE=436E Serial ATA Controller + +pci:v00001002d00004370* + ID_PRODUCT_FROM_DATABASE=IXP SB400 AC'97 Audio Controller + +pci:v00001002d00004370sv00001025sd00000079* + ID_PRODUCT_FROM_DATABASE=Aspire 5024WLMMi + +pci:v00001002d00004370sv00001025sd00000091* + ID_PRODUCT_FROM_DATABASE=Aspire 5032WXMi + +pci:v00001002d00004370sv0000103Csd00002A05* + ID_PRODUCT_FROM_DATABASE=Pavilion t3030.de Desktop PC + +pci:v00001002d00004370sv0000103Csd0000308B* + ID_PRODUCT_FROM_DATABASE=MX6125 + +pci:v00001002d00004370sv0000105Bsd00000C81* + ID_PRODUCT_FROM_DATABASE=Realtek ALC 653 + +pci:v00001002d00004370sv0000107Bsd00000300* + ID_PRODUCT_FROM_DATABASE=MX6421 + +pci:v00001002d00004370sv00001462sd00000131* + ID_PRODUCT_FROM_DATABASE=MS-1013 Notebook + +pci:v00001002d00004371* + ID_PRODUCT_FROM_DATABASE=IXP SB400 PCI-PCI Bridge + +pci:v00001002d00004371sv0000103Csd0000308B* + ID_PRODUCT_FROM_DATABASE=MX6125 + +pci:v00001002d00004371sv00001462sd00007217* + ID_PRODUCT_FROM_DATABASE=Aspire L250 + +pci:v00001002d00004372* + ID_PRODUCT_FROM_DATABASE=IXP SB400 SMBus Controller + +pci:v00001002d00004372sv00001025sd00000080* + ID_PRODUCT_FROM_DATABASE=Aspire 5024WLMMi + +pci:v00001002d00004372sv0000103Csd00002A20* + ID_PRODUCT_FROM_DATABASE=Pavilion t3030.de Desktop PC + +pci:v00001002d00004372sv0000103Csd0000308B* + ID_PRODUCT_FROM_DATABASE=MX6125 + +pci:v00001002d00004372sv00001462sd00000131* + ID_PRODUCT_FROM_DATABASE=MS-1013 Notebook + +pci:v00001002d00004372sv00001462sd00007217* + ID_PRODUCT_FROM_DATABASE=Aspire L250 + +pci:v00001002d00004373* + ID_PRODUCT_FROM_DATABASE=IXP SB400 USB2 Host Controller + +pci:v00001002d00004373sv00001025sd00000080* + ID_PRODUCT_FROM_DATABASE=Aspire 5024WLMMi + +pci:v00001002d00004373sv0000103Csd00002A20* + ID_PRODUCT_FROM_DATABASE=Pavilion t3030.de Desktop PC + +pci:v00001002d00004373sv0000103Csd0000308B* + ID_PRODUCT_FROM_DATABASE=MX6125 + +pci:v00001002d00004373sv00001462sd00007217* + ID_PRODUCT_FROM_DATABASE=Aspire L250 + +pci:v00001002d00004374* + ID_PRODUCT_FROM_DATABASE=IXP SB400 USB Host Controller + +pci:v00001002d00004374sv0000103Csd00002A20* + ID_PRODUCT_FROM_DATABASE=Pavilion t3030.de Desktop PC + +pci:v00001002d00004374sv0000103Csd0000308B* + ID_PRODUCT_FROM_DATABASE=MX6125 + +pci:v00001002d00004374sv00001462sd00007217* + ID_PRODUCT_FROM_DATABASE=Aspire L250 + +pci:v00001002d00004375* + ID_PRODUCT_FROM_DATABASE=IXP SB400 USB Host Controller + +pci:v00001002d00004375sv00001025sd00000080* + ID_PRODUCT_FROM_DATABASE=Aspire 5024WLMMi + +pci:v00001002d00004375sv0000103Csd00002A20* + ID_PRODUCT_FROM_DATABASE=Pavilion t3030.de Desktop PC + +pci:v00001002d00004375sv0000103Csd0000308B* + ID_PRODUCT_FROM_DATABASE=MX6125 + +pci:v00001002d00004375sv00001462sd00007217* + ID_PRODUCT_FROM_DATABASE=Aspire L250 + +pci:v00001002d00004376* + ID_PRODUCT_FROM_DATABASE=IXP SB400 IDE Controller + +pci:v00001002d00004376sv00001025sd00000080* + ID_PRODUCT_FROM_DATABASE=Aspire 5024WLMMi + +pci:v00001002d00004376sv0000103Csd00002A20* + ID_PRODUCT_FROM_DATABASE=Pavilion t3030.de Desktop PC + +pci:v00001002d00004376sv0000103Csd0000308B* + ID_PRODUCT_FROM_DATABASE=MX6125 + +pci:v00001002d00004376sv00001462sd00000131* + ID_PRODUCT_FROM_DATABASE=MS-1013 Notebook + +pci:v00001002d00004376sv00001462sd00007217* + ID_PRODUCT_FROM_DATABASE=Aspire L250 + +pci:v00001002d00004377* + ID_PRODUCT_FROM_DATABASE=IXP SB400 PCI-ISA Bridge + +pci:v00001002d00004377sv00001025sd00000080* + ID_PRODUCT_FROM_DATABASE=Aspire 5024WLMi + +pci:v00001002d00004377sv0000103Csd00002A20* + ID_PRODUCT_FROM_DATABASE=Pavilion t3030.de Desktop PC + +pci:v00001002d00004377sv0000103Csd0000308B* + ID_PRODUCT_FROM_DATABASE=MX6125 + +pci:v00001002d00004377sv00001462sd00007217* + ID_PRODUCT_FROM_DATABASE=Aspire L250 + +pci:v00001002d00004378* + ID_PRODUCT_FROM_DATABASE=IXP SB400 AC'97 Modem Controller + +pci:v00001002d00004378sv00001025sd00000080* + ID_PRODUCT_FROM_DATABASE=Aspire 5024WLMMi + +pci:v00001002d00004378sv0000103Csd0000308B* + ID_PRODUCT_FROM_DATABASE=MX6125 + +pci:v00001002d00004378sv00001462sd00000131* + ID_PRODUCT_FROM_DATABASE=MS-1013 Notebook + +pci:v00001002d00004379* + ID_PRODUCT_FROM_DATABASE=IXP SB400 Serial ATA Controller + +pci:v00001002d00004379sv00001462sd00007141* + ID_PRODUCT_FROM_DATABASE=Aspire L250 + +pci:v00001002d0000437A* + ID_PRODUCT_FROM_DATABASE=IXP SB400 Serial ATA Controller + +pci:v00001002d0000437Asv00001002sd00004379* + ID_PRODUCT_FROM_DATABASE=4379 Serial ATA Controller + +pci:v00001002d0000437Asv00001002sd0000437A* + ID_PRODUCT_FROM_DATABASE=437A Serial ATA Controller + +pci:v00001002d0000437Asv00001462sd00007141* + ID_PRODUCT_FROM_DATABASE=Aspire L250 + +pci:v00001002d0000437Asv000014F1sd00008800* + ID_PRODUCT_FROM_DATABASE=Leadtek WinFast TV2000XP Expert + +pci:v00001002d0000437B* + ID_PRODUCT_FROM_DATABASE=IXP SB4x0 High Definition Audio Controller + +pci:v00001002d0000437Bsv00001002sd0000437B* + ID_PRODUCT_FROM_DATABASE=IXP SB4x0 High Definition Audio Controller + +pci:v00001002d0000437Bsv000010CFsd00001326* + ID_PRODUCT_FROM_DATABASE=Fujitsu Lifebook A3040 + +pci:v00001002d0000437Bsv00001734sd000010B8* + ID_PRODUCT_FROM_DATABASE=Realtek High Definition Audio + +pci:v00001002d00004380* + ID_PRODUCT_FROM_DATABASE=SB600 Non-Raid-5 SATA + +pci:v00001002d00004380sv0000103Csd00002813* + ID_PRODUCT_FROM_DATABASE=DC5750 Microtower + +pci:v00001002d00004380sv00001179sd0000FF50* + ID_PRODUCT_FROM_DATABASE=Satellite P305D-S8995E + +pci:v00001002d00004380sv00001458sd0000B003* + ID_PRODUCT_FROM_DATABASE=GA-MA790FX-DS5 (rev. 1.0) + +pci:v00001002d00004380sv00001458sd0000B005* + ID_PRODUCT_FROM_DATABASE=Gigabyte GA-MA69G-S3H Motherboard + +pci:v00001002d00004380sv00001462sd00007327* + ID_PRODUCT_FROM_DATABASE=K9AG Neo2 + +pci:v00001002d00004380sv000017F2sd00005999* + ID_PRODUCT_FROM_DATABASE=KI690-AM2 Motherboard + +pci:v00001002d00004381* + ID_PRODUCT_FROM_DATABASE=SB400 SATA Controller (RAID 5 mode) + +pci:v00001002d00004382* + ID_PRODUCT_FROM_DATABASE=SB600 AC97 Audio + +pci:v00001002d00004383* + ID_PRODUCT_FROM_DATABASE=SBx00 Azalia (Intel HDA) + +pci:v00001002d00004383sv0000103Csd00001611* + ID_PRODUCT_FROM_DATABASE=Pavilion DM1Z-3000 + +pci:v00001002d00004383sv0000103Csd0000280A* + ID_PRODUCT_FROM_DATABASE=DC5750 Microtower + +pci:v00001002d00004383sv00001043sd00008230* + ID_PRODUCT_FROM_DATABASE=M3A78-EH Motherboard + +pci:v00001002d00004383sv00001043sd0000836C* + ID_PRODUCT_FROM_DATABASE=M4A785TD Motherboard + +pci:v00001002d00004383sv00001043sd00008410* + ID_PRODUCT_FROM_DATABASE=M4A89GTD PRO/USB3 Motherboard + +pci:v00001002d00004383sv00001043sd0000841B* + ID_PRODUCT_FROM_DATABASE=M5A88-V EVO + +pci:v00001002d00004383sv00001179sd0000FF50* + ID_PRODUCT_FROM_DATABASE=Satellite P305D-S8995E + +pci:v00001002d00004383sv00001458sd0000A022* + ID_PRODUCT_FROM_DATABASE=GA-MA770-DS3rev2.0 Motherboard + +pci:v00001002d00004383sv000017F2sd00005000* + ID_PRODUCT_FROM_DATABASE=KI690-AM2 Motherboard + +pci:v00001002d00004384* + ID_PRODUCT_FROM_DATABASE=SBx00 PCI to PCI Bridge + +pci:v00001002d00004385* + ID_PRODUCT_FROM_DATABASE=SBx00 SMBus Controller + +pci:v00001002d00004385sv0000103Csd00001611* + ID_PRODUCT_FROM_DATABASE=Pavilion DM1Z-3000 + +pci:v00001002d00004385sv0000103Csd0000280A* + ID_PRODUCT_FROM_DATABASE=DC5750 Microtower + +pci:v00001002d00004385sv00001043sd000082EF* + ID_PRODUCT_FROM_DATABASE=M3A78-EH Motherboard + +pci:v00001002d00004385sv00001043sd00008389* + ID_PRODUCT_FROM_DATABASE=M4A785TD Motherboard + +pci:v00001002d00004385sv00001179sd0000FF50* + ID_PRODUCT_FROM_DATABASE=Satellite P305D-S8995E + +pci:v00001002d00004385sv00001458sd00004385* + ID_PRODUCT_FROM_DATABASE=GA-MA770-DS3rev2.0 Motherboard + +pci:v00001002d00004385sv00001462sd00007368* + ID_PRODUCT_FROM_DATABASE=K9AG Neo2 + +pci:v00001002d00004385sv000015D9sd0000A811* + ID_PRODUCT_FROM_DATABASE=H8DGU + +pci:v00001002d00004385sv0000174Bsd00001001* + ID_PRODUCT_FROM_DATABASE=Sapphire PURE Fusion Mini + +pci:v00001002d00004385sv000017F2sd00005000* + ID_PRODUCT_FROM_DATABASE=KI690-AM2 Motherboard + +pci:v00001002d00004386* + ID_PRODUCT_FROM_DATABASE=SB600 USB Controller (EHCI) + +pci:v00001002d00004386sv0000103Csd0000280A* + ID_PRODUCT_FROM_DATABASE=DC5750 Microtower + +pci:v00001002d00004386sv00001179sd0000FF50* + ID_PRODUCT_FROM_DATABASE=Satellite P305D-S8995E + +pci:v00001002d00004386sv00001462sd00007368* + ID_PRODUCT_FROM_DATABASE=K9AG Neo2 + +pci:v00001002d00004386sv000017F2sd00005000* + ID_PRODUCT_FROM_DATABASE=KI690-AM2 Motherboard + +pci:v00001002d00004387* + ID_PRODUCT_FROM_DATABASE=SB600 USB (OHCI0) + +pci:v00001002d00004387sv0000103Csd0000280A* + ID_PRODUCT_FROM_DATABASE=DC5750 Microtower + +pci:v00001002d00004387sv00001179sd0000FF50* + ID_PRODUCT_FROM_DATABASE=Satellite P305D-S8995E + +pci:v00001002d00004387sv00001462sd00007368* + ID_PRODUCT_FROM_DATABASE=K9AG Neo2 + +pci:v00001002d00004387sv000017F2sd00005000* + ID_PRODUCT_FROM_DATABASE=KI690-AM2 Motherboard + +pci:v00001002d00004388* + ID_PRODUCT_FROM_DATABASE=SB600 USB (OHCI1) + +pci:v00001002d00004388sv0000103Csd0000280A* + ID_PRODUCT_FROM_DATABASE=DC5750 Microtower + +pci:v00001002d00004388sv00001179sd0000FF50* + ID_PRODUCT_FROM_DATABASE=Satellite P305D-S8995E + +pci:v00001002d00004388sv00001462sd00007368* + ID_PRODUCT_FROM_DATABASE=K9AG Neo2 + +pci:v00001002d00004388sv000017F2sd00005000* + ID_PRODUCT_FROM_DATABASE=KI690-AM2 Motherboard + +pci:v00001002d00004389* + ID_PRODUCT_FROM_DATABASE=SB600 USB (OHCI2) + +pci:v00001002d00004389sv0000103Csd0000280A* + ID_PRODUCT_FROM_DATABASE=DC5750 Microtower + +pci:v00001002d00004389sv00001179sd0000FF50* + ID_PRODUCT_FROM_DATABASE=Satellite P305D-S8995E + +pci:v00001002d00004389sv00001462sd00007368* + ID_PRODUCT_FROM_DATABASE=K9AG Neo2 + +pci:v00001002d00004389sv000017F2sd00005000* + ID_PRODUCT_FROM_DATABASE=KI690-AM2 Motherboard + +pci:v00001002d0000438A* + ID_PRODUCT_FROM_DATABASE=SB600 USB (OHCI3) + +pci:v00001002d0000438Asv0000103Csd0000280A* + ID_PRODUCT_FROM_DATABASE=DC5750 Microtower + +pci:v00001002d0000438Asv00001179sd0000FF50* + ID_PRODUCT_FROM_DATABASE=Satellite P305D-S8995E + +pci:v00001002d0000438Asv00001462sd00007368* + ID_PRODUCT_FROM_DATABASE=K9AG Neo2 + +pci:v00001002d0000438Asv000017F2sd00005000* + ID_PRODUCT_FROM_DATABASE=KI690-AM2 Motherboard + +pci:v00001002d0000438B* + ID_PRODUCT_FROM_DATABASE=SB600 USB (OHCI4) + +pci:v00001002d0000438Bsv0000103Csd0000280A* + ID_PRODUCT_FROM_DATABASE=DC5750 Microtower + +pci:v00001002d0000438Bsv00001179sd0000FF50* + ID_PRODUCT_FROM_DATABASE=Satellite P305D-S8995E + +pci:v00001002d0000438Bsv00001462sd00007368* + ID_PRODUCT_FROM_DATABASE=K9AG Neo2 + +pci:v00001002d0000438Bsv000017F2sd00005000* + ID_PRODUCT_FROM_DATABASE=KI690-AM2 Motherboard + +pci:v00001002d0000438C* + ID_PRODUCT_FROM_DATABASE=SB600 IDE + +pci:v00001002d0000438Csv0000103Csd0000280A* + ID_PRODUCT_FROM_DATABASE=DC5750 Microtower + +pci:v00001002d0000438Csv00001179sd0000FF50* + ID_PRODUCT_FROM_DATABASE=Satellite P305D-S8995E + +pci:v00001002d0000438Csv00001458sd00005002* + ID_PRODUCT_FROM_DATABASE=Gigabyte GA-MA69G-S3H Motherboard + +pci:v00001002d0000438Csv00001462sd00007368* + ID_PRODUCT_FROM_DATABASE=K9AG Neo2 + +pci:v00001002d0000438Csv000017F2sd00005000* + ID_PRODUCT_FROM_DATABASE=KI690-AM2 Motherboard + +pci:v00001002d0000438D* + ID_PRODUCT_FROM_DATABASE=SB600 PCI to LPC Bridge + +pci:v00001002d0000438Dsv0000103Csd0000280A* + ID_PRODUCT_FROM_DATABASE=DC5750 Microtower + +pci:v00001002d0000438Dsv00001179sd0000FF50* + ID_PRODUCT_FROM_DATABASE=Satellite P305D-S8995E + +pci:v00001002d0000438Dsv00001462sd00007368* + ID_PRODUCT_FROM_DATABASE=K9AG Neo2 + +pci:v00001002d0000438Dsv000017F2sd00005000* + ID_PRODUCT_FROM_DATABASE=KI690-AM2 Motherboard + +pci:v00001002d0000438E* + ID_PRODUCT_FROM_DATABASE=SB600 AC97 Modem + +pci:v00001002d00004390* + ID_PRODUCT_FROM_DATABASE=SB7x0/SB8x0/SB9x0 SATA Controller [IDE mode] + +pci:v00001002d00004390sv00001043sd000082EF* + ID_PRODUCT_FROM_DATABASE=M3A78-EH Motherboard + +pci:v00001002d00004390sv00001043sd00008389* + ID_PRODUCT_FROM_DATABASE=M4A785TD Motherboard + +pci:v00001002d00004390sv00001458sd0000B002* + ID_PRODUCT_FROM_DATABASE=GA-MA770-DS3rev2.0 Motherboard + +pci:v00001002d00004390sv00001849sd00004390* + ID_PRODUCT_FROM_DATABASE=Motherboard (one of many) + +pci:v00001002d00004391* + ID_PRODUCT_FROM_DATABASE=SB7x0/SB8x0/SB9x0 SATA Controller [AHCI mode] + +pci:v00001002d00004391sv0000103Csd00001611* + ID_PRODUCT_FROM_DATABASE=Pavilion DM1Z-3000 + +pci:v00001002d00004391sv00001043sd000082EF* + ID_PRODUCT_FROM_DATABASE=M3A78-EH Motherboard + +pci:v00001002d00004391sv00001043sd00008443* + ID_PRODUCT_FROM_DATABASE=M5A88-V EVO + +pci:v00001002d00004391sv0000174Bsd00001001* + ID_PRODUCT_FROM_DATABASE=Sapphire PURE Fusion Mini + +pci:v00001002d00004392* + ID_PRODUCT_FROM_DATABASE=SB7x0/SB8x0/SB9x0 SATA Controller [Non-RAID5 mode] + +pci:v00001002d00004393* + ID_PRODUCT_FROM_DATABASE=SB7x0/SB8x0/SB9x0 SATA Controller [RAID5 mode] + +pci:v00001002d00004394* + ID_PRODUCT_FROM_DATABASE=SB7x0/SB8x0/SB9x0 SATA Controller [AHCI mode] + +pci:v00001002d00004395* + ID_PRODUCT_FROM_DATABASE=SB8x0/SB9x0 SATA Controller [Storage mode] + +pci:v00001002d00004396* + ID_PRODUCT_FROM_DATABASE=SB7x0/SB8x0/SB9x0 USB EHCI Controller + +pci:v00001002d00004396sv0000103Csd00001611* + ID_PRODUCT_FROM_DATABASE=Pavilion DM1Z-3000 + +pci:v00001002d00004396sv00001043sd000082EF* + ID_PRODUCT_FROM_DATABASE=M3A78-EH Motherboard + +pci:v00001002d00004396sv00001043sd00008443* + ID_PRODUCT_FROM_DATABASE=M5A88-V EVO + +pci:v00001002d00004396sv000015D9sd0000A811* + ID_PRODUCT_FROM_DATABASE=H8DGU + +pci:v00001002d00004396sv0000174Bsd00001001* + ID_PRODUCT_FROM_DATABASE=Sapphire PURE Fusion Mini + +pci:v00001002d00004397* + ID_PRODUCT_FROM_DATABASE=SB7x0/SB8x0/SB9x0 USB OHCI0 Controller + +pci:v00001002d00004397sv0000103Csd00001611* + ID_PRODUCT_FROM_DATABASE=Pavilion DM1Z-3000 + +pci:v00001002d00004397sv00001043sd000082EF* + ID_PRODUCT_FROM_DATABASE=M3A78-EH Motherboard + +pci:v00001002d00004397sv00001043sd00008443* + ID_PRODUCT_FROM_DATABASE=M5A88-V EVO + +pci:v00001002d00004397sv000015D9sd0000A811* + ID_PRODUCT_FROM_DATABASE=H8DGU + +pci:v00001002d00004397sv0000174Bsd00001001* + ID_PRODUCT_FROM_DATABASE=Sapphire PURE Fusion Mini + +pci:v00001002d00004398* + ID_PRODUCT_FROM_DATABASE=SB7x0 USB OHCI1 Controller + +pci:v00001002d00004398sv00001043sd000082EF* + ID_PRODUCT_FROM_DATABASE=M3A78-EH Motherboard + +pci:v00001002d00004398sv000015D9sd0000A811* + ID_PRODUCT_FROM_DATABASE=H8DGU + +pci:v00001002d00004399* + ID_PRODUCT_FROM_DATABASE=SB7x0/SB8x0/SB9x0 USB OHCI2 Controller + +pci:v00001002d00004399sv00001043sd000082EF* + ID_PRODUCT_FROM_DATABASE=M3A78-EH Motherboard + +pci:v00001002d00004399sv00001043sd00008443* + ID_PRODUCT_FROM_DATABASE=M5A88-V EVO + +pci:v00001002d00004399sv0000174Bsd00001001* + ID_PRODUCT_FROM_DATABASE=Sapphire PURE Fusion Mini + +pci:v00001002d0000439C* + ID_PRODUCT_FROM_DATABASE=SB7x0/SB8x0/SB9x0 IDE Controller + +pci:v00001002d0000439Csv00001043sd000082EF* + ID_PRODUCT_FROM_DATABASE=M3A78-EH Motherboard + +pci:v00001002d0000439D* + ID_PRODUCT_FROM_DATABASE=SB7x0/SB8x0/SB9x0 LPC host controller + +pci:v00001002d0000439Dsv0000103Csd00001611* + ID_PRODUCT_FROM_DATABASE=Pavilion DM1Z-3000 + +pci:v00001002d0000439Dsv00001043sd000082EF* + ID_PRODUCT_FROM_DATABASE=M3A78-EH Motherboard + +pci:v00001002d0000439Dsv00001043sd00008443* + ID_PRODUCT_FROM_DATABASE=M5A88-V EVO + +pci:v00001002d0000439Dsv0000174Bsd00001001* + ID_PRODUCT_FROM_DATABASE=Sapphire PURE Fusion Mini + +pci:v00001002d000043A0* + ID_PRODUCT_FROM_DATABASE=SB700/SB800/SB900 PCI to PCI bridge (PCIE port 0) + +pci:v00001002d000043A1* + ID_PRODUCT_FROM_DATABASE=SB700/SB800/SB900 PCI to PCI bridge (PCIE port 1) + +pci:v00001002d000043A2* + ID_PRODUCT_FROM_DATABASE=SB900 PCI to PCI bridge (PCIE port 2) + +pci:v00001002d000043A3* + ID_PRODUCT_FROM_DATABASE=SB900 PCI to PCI bridge (PCIE port 3) + +pci:v00001002d00004437* + ID_PRODUCT_FROM_DATABASE=RS250 [Radeon Mobility 7000 IGP] + +pci:v00001002d00004554* + ID_PRODUCT_FROM_DATABASE=210888ET [Mach64 ET] + +pci:v00001002d00004654* + ID_PRODUCT_FROM_DATABASE=Mach64 VT + +pci:v00001002d00004742* + ID_PRODUCT_FROM_DATABASE=3D Rage Pro AGP 1X/2X + +pci:v00001002d00004742sv00001002sd00000040* + ID_PRODUCT_FROM_DATABASE=Rage Pro Turbo AGP 2X + +pci:v00001002d00004742sv00001002sd00000044* + ID_PRODUCT_FROM_DATABASE=Rage Pro Turbo AGP 2X + +pci:v00001002d00004742sv00001002sd00000061* + ID_PRODUCT_FROM_DATABASE=Rage Pro AIW AGP 2X + +pci:v00001002d00004742sv00001002sd00000062* + ID_PRODUCT_FROM_DATABASE=Rage Pro AIW AGP 2X + +pci:v00001002d00004742sv00001002sd00000063* + ID_PRODUCT_FROM_DATABASE=Rage Pro AIW AGP 2X + +pci:v00001002d00004742sv00001002sd00000080* + ID_PRODUCT_FROM_DATABASE=Rage Pro Turbo AGP 2X + +pci:v00001002d00004742sv00001002sd00000084* + ID_PRODUCT_FROM_DATABASE=Rage Pro Turbo AGP 2X + +pci:v00001002d00004742sv00001002sd00004742* + ID_PRODUCT_FROM_DATABASE=Rage Pro Turbo AGP 2X + +pci:v00001002d00004742sv00001002sd00008001* + ID_PRODUCT_FROM_DATABASE=Rage Pro Turbo AGP 2X + +pci:v00001002d00004742sv00001028sd00000082* + ID_PRODUCT_FROM_DATABASE=Rage Pro Turbo AGP 2X + +pci:v00001002d00004742sv00001028sd00004082* + ID_PRODUCT_FROM_DATABASE=Optiplex GX1 Onboard Display Adapter + +pci:v00001002d00004742sv00001028sd00008082* + ID_PRODUCT_FROM_DATABASE=Rage Pro Turbo AGP 2X + +pci:v00001002d00004742sv00001028sd0000C082* + ID_PRODUCT_FROM_DATABASE=Rage Pro Turbo AGP 2X + +pci:v00001002d00004742sv00008086sd00004152* + ID_PRODUCT_FROM_DATABASE=Xpert 98D AGP 2X + +pci:v00001002d00004742sv00008086sd0000464A* + ID_PRODUCT_FROM_DATABASE=Rage Pro Turbo AGP 2X + +pci:v00001002d00004744* + ID_PRODUCT_FROM_DATABASE=3D Rage Pro AGP 1X + +pci:v00001002d00004744sv00001002sd00004744* + ID_PRODUCT_FROM_DATABASE=Rage Pro Turbo AGP + +pci:v00001002d00004744sv00008086sd00004D55* + ID_PRODUCT_FROM_DATABASE=Rage 3D Pro AGP 1X [Intel MU440EX] + +pci:v00001002d00004747* + ID_PRODUCT_FROM_DATABASE=3D Rage Pro + +pci:v00001002d00004749* + ID_PRODUCT_FROM_DATABASE=3D Rage Pro + +pci:v00001002d00004749sv00001002sd00000061* + ID_PRODUCT_FROM_DATABASE=Rage Pro AIW + +pci:v00001002d00004749sv00001002sd00000062* + ID_PRODUCT_FROM_DATABASE=Rage Pro AIW + +pci:v00001002d0000474C* + ID_PRODUCT_FROM_DATABASE=Rage XC + +pci:v00001002d0000474D* + ID_PRODUCT_FROM_DATABASE=Rage XL AGP 2X + +pci:v00001002d0000474Dsv00001002sd00000004* + ID_PRODUCT_FROM_DATABASE=Xpert 98 RXL AGP 2X + +pci:v00001002d0000474Dsv00001002sd00000008* + ID_PRODUCT_FROM_DATABASE=Xpert 98 RXL AGP 2X + +pci:v00001002d0000474Dsv00001002sd00000080* + ID_PRODUCT_FROM_DATABASE=Rage XL AGP 2X + +pci:v00001002d0000474Dsv00001002sd00000084* + ID_PRODUCT_FROM_DATABASE=Xpert 98 AGP 2X + +pci:v00001002d0000474Dsv00001002sd0000474D* + ID_PRODUCT_FROM_DATABASE=Rage XL AGP + +pci:v00001002d0000474Dsv00001033sd0000806A* + ID_PRODUCT_FROM_DATABASE=Rage XL AGP + +pci:v00001002d0000474E* + ID_PRODUCT_FROM_DATABASE=Rage XC AGP + +pci:v00001002d0000474Esv00001002sd0000474E* + ID_PRODUCT_FROM_DATABASE=Rage XC AGP + +pci:v00001002d0000474F* + ID_PRODUCT_FROM_DATABASE=Rage XL + +pci:v00001002d0000474Fsv00001002sd00000008* + ID_PRODUCT_FROM_DATABASE=Rage XL + +pci:v00001002d0000474Fsv00001002sd0000474F* + ID_PRODUCT_FROM_DATABASE=Rage XL + +pci:v00001002d00004750* + ID_PRODUCT_FROM_DATABASE=3D Rage Pro 215GP + +pci:v00001002d00004750sv00001002sd00000040* + ID_PRODUCT_FROM_DATABASE=Rage Pro Turbo + +pci:v00001002d00004750sv00001002sd00000044* + ID_PRODUCT_FROM_DATABASE=Rage Pro Turbo + +pci:v00001002d00004750sv00001002sd00000080* + ID_PRODUCT_FROM_DATABASE=Rage Pro Turbo + +pci:v00001002d00004750sv00001002sd00000084* + ID_PRODUCT_FROM_DATABASE=Rage Pro Turbo + +pci:v00001002d00004750sv00001002sd00004750* + ID_PRODUCT_FROM_DATABASE=Rage Pro Turbo + +pci:v00001002d00004751* + ID_PRODUCT_FROM_DATABASE=3D Rage Pro 215GQ + +pci:v00001002d00004752* + ID_PRODUCT_FROM_DATABASE=Rage XL + +pci:v00001002d00004752sv00000E11sd0000001E* + ID_PRODUCT_FROM_DATABASE=Proliant Rage XL + +pci:v00001002d00004752sv00001002sd00000008* + ID_PRODUCT_FROM_DATABASE=Rage XL + +pci:v00001002d00004752sv00001002sd00004752* + ID_PRODUCT_FROM_DATABASE=Proliant Rage XL + +pci:v00001002d00004752sv00001002sd00008008* + ID_PRODUCT_FROM_DATABASE=Rage XL + +pci:v00001002d00004752sv00001014sd00000240* + ID_PRODUCT_FROM_DATABASE=eServer xSeries server mainboard + +pci:v00001002d00004752sv00001028sd000000CE* + ID_PRODUCT_FROM_DATABASE=PowerEdge 1400 + +pci:v00001002d00004752sv00001028sd000000D1* + ID_PRODUCT_FROM_DATABASE=PowerEdge 2550 + +pci:v00001002d00004752sv00001028sd000000D9* + ID_PRODUCT_FROM_DATABASE=PowerEdge 2500 + +pci:v00001002d00004752sv00001028sd00000134* + ID_PRODUCT_FROM_DATABASE=PowerEdge 600SC + +pci:v00001002d00004752sv00001028sd0000014A* + ID_PRODUCT_FROM_DATABASE=PowerEdge 1750 + +pci:v00001002d00004752sv00001028sd00000165* + ID_PRODUCT_FROM_DATABASE=PowerEdge 750 + +pci:v00001002d00004752sv0000103Csd000010E1* + ID_PRODUCT_FROM_DATABASE=NetServer Rage XL + +pci:v00001002d00004752sv0000103Csd00003208* + ID_PRODUCT_FROM_DATABASE=ProLiant DL140 G2 + +pci:v00001002d00004752sv0000107Bsd00006400* + ID_PRODUCT_FROM_DATABASE=6400 Server + +pci:v00001002d00004752sv00001734sd0000007A* + ID_PRODUCT_FROM_DATABASE=PRIMERGY RX/TX series onboard VGA + +pci:v00001002d00004752sv00008086sd00003411* + ID_PRODUCT_FROM_DATABASE=SDS2 Mainboard + +pci:v00001002d00004752sv00008086sd00003427* + ID_PRODUCT_FROM_DATABASE=S875WP1-E mainboard + +pci:v00001002d00004752sv00008086sd00005744* + ID_PRODUCT_FROM_DATABASE=S845WD1-E mainboard + +pci:v00001002d00004753* + ID_PRODUCT_FROM_DATABASE=Rage XC + +pci:v00001002d00004753sv00001002sd00004753* + ID_PRODUCT_FROM_DATABASE=Rage XC + +pci:v00001002d00004754* + ID_PRODUCT_FROM_DATABASE=3D Rage I/II 215GT [Mach64 GT] + +pci:v00001002d00004755* + ID_PRODUCT_FROM_DATABASE=3D Rage II+ 215GTB [Mach64 GTB] + +pci:v00001002d00004756* + ID_PRODUCT_FROM_DATABASE=3D Rage IIC 215IIC [Mach64 GT IIC] + +pci:v00001002d00004756sv00001002sd00004756* + ID_PRODUCT_FROM_DATABASE=Rage IIC + +pci:v00001002d00004757* + ID_PRODUCT_FROM_DATABASE=3D Rage IIC AGP + +pci:v00001002d00004757sv00001002sd00004757* + ID_PRODUCT_FROM_DATABASE=Rage IIC AGP + +pci:v00001002d00004757sv00001028sd00000089* + ID_PRODUCT_FROM_DATABASE=Rage 3D IIC + +pci:v00001002d00004757sv00001028sd0000008E* + ID_PRODUCT_FROM_DATABASE=PowerEdge 1300 onboard video + +pci:v00001002d00004757sv00001028sd00004082* + ID_PRODUCT_FROM_DATABASE=Rage 3D IIC + +pci:v00001002d00004757sv00001028sd00008082* + ID_PRODUCT_FROM_DATABASE=Rage 3D IIC + +pci:v00001002d00004757sv00001028sd0000C082* + ID_PRODUCT_FROM_DATABASE=Rage 3D IIC + +pci:v00001002d00004758* + ID_PRODUCT_FROM_DATABASE=210888GX [Mach64 GX] + +pci:v00001002d00004759* + ID_PRODUCT_FROM_DATABASE=3D Rage IIC + +pci:v00001002d0000475A* + ID_PRODUCT_FROM_DATABASE=3D Rage IIC AGP + +pci:v00001002d0000475Asv00001002sd00000084* + ID_PRODUCT_FROM_DATABASE=Rage 3D Pro AGP 2x XPERT 98 + +pci:v00001002d0000475Asv00001002sd00000087* + ID_PRODUCT_FROM_DATABASE=Rage 3D IIC + +pci:v00001002d0000475Asv00001002sd0000475A* + ID_PRODUCT_FROM_DATABASE=Rage IIC AGP + +pci:v00001002d00004964* + ID_PRODUCT_FROM_DATABASE=RV250 Id [Radeon 9000] + +pci:v00001002d00004965* + ID_PRODUCT_FROM_DATABASE=RV250 Ie [Radeon 9000] + +pci:v00001002d00004966* + ID_PRODUCT_FROM_DATABASE=R250 If [Radeon 9000] + +pci:v00001002d00004966sv000010F1sd00000002* + ID_PRODUCT_FROM_DATABASE=RV250 If [Tachyon G9000 PRO] + +pci:v00001002d00004966sv0000148Csd00002039* + ID_PRODUCT_FROM_DATABASE=RV250 If [Radeon 9000 Pro "Evil Commando"] + +pci:v00001002d00004966sv00001509sd00009A00* + ID_PRODUCT_FROM_DATABASE=RV250 If [Radeon 9000 "AT009"] + +pci:v00001002d00004966sv00001681sd00000040* + ID_PRODUCT_FROM_DATABASE=RV250 If [3D prophet 9000] + +pci:v00001002d00004966sv0000174Bsd00007176* + ID_PRODUCT_FROM_DATABASE=RV250 If [Sapphire Radeon 9000 Pro] + +pci:v00001002d00004966sv0000174Bsd00007192* + ID_PRODUCT_FROM_DATABASE=RV250 If [Radeon 9000 "Atlantis"] + +pci:v00001002d00004966sv000017AFsd00002005* + ID_PRODUCT_FROM_DATABASE=RV250 If [Excalibur Radeon 9000 Pro] + +pci:v00001002d00004966sv000017AFsd00002006* + ID_PRODUCT_FROM_DATABASE=RV250 If [Excalibur Radeon 9000] + +pci:v00001002d00004967* + ID_PRODUCT_FROM_DATABASE=RV250 Ig [Radeon 9000] + +pci:v00001002d0000496E* + ID_PRODUCT_FROM_DATABASE=RV250 [Radeon 9000] (Secondary) + +pci:v00001002d00004A48* + ID_PRODUCT_FROM_DATABASE=R420 JH [Radeon X800] + +pci:v00001002d00004A49* + ID_PRODUCT_FROM_DATABASE=R420 JI [Radeon X800PRO] + +pci:v00001002d00004A4A* + ID_PRODUCT_FROM_DATABASE=R420 JJ [Radeon X800SE] + +pci:v00001002d00004A4B* + ID_PRODUCT_FROM_DATABASE=R420 JK [Radeon X800] + +pci:v00001002d00004A4C* + ID_PRODUCT_FROM_DATABASE=R420 JL [Radeon X800] + +pci:v00001002d00004A4D* + ID_PRODUCT_FROM_DATABASE=R420 JM [FireGL X3] + +pci:v00001002d00004A4E* + ID_PRODUCT_FROM_DATABASE=R420 JN [Mobility Radeon 9800] + +pci:v00001002d00004A4F* + ID_PRODUCT_FROM_DATABASE=R420 [Radeon X800 AGP] + +pci:v00001002d00004A50* + ID_PRODUCT_FROM_DATABASE=R420 JP [Radeon X800XT] + +pci:v00001002d00004A54* + ID_PRODUCT_FROM_DATABASE=R420 [Radeon X800 VE] + +pci:v00001002d00004A69* + ID_PRODUCT_FROM_DATABASE=R420 [Radeon X800 PRO/GTO] (Secondary) + +pci:v00001002d00004A6A* + ID_PRODUCT_FROM_DATABASE=R420 [Radeon X800] (Secondary) + +pci:v00001002d00004A6B* + ID_PRODUCT_FROM_DATABASE=R420 [Radeon X800] (Secondary) + +pci:v00001002d00004A70* + ID_PRODUCT_FROM_DATABASE=R420 [X800XT-PE] (Secondary) + +pci:v00001002d00004A74* + ID_PRODUCT_FROM_DATABASE=R420 [Radeon X800 VE] (Secondary) + +pci:v00001002d00004B48* + ID_PRODUCT_FROM_DATABASE=R481 [Radeon X850 PCIe] + +pci:v00001002d00004B49* + ID_PRODUCT_FROM_DATABASE=R480 [Radeon X850XT] + +pci:v00001002d00004B4A* + ID_PRODUCT_FROM_DATABASE=R480 [Radeon X850SE AGP] + +pci:v00001002d00004B4B* + ID_PRODUCT_FROM_DATABASE=R480 [Radeon X850Pro] + +pci:v00001002d00004B4C* + ID_PRODUCT_FROM_DATABASE=R481 [Radeon X850XT-PE] + +pci:v00001002d00004B69* + ID_PRODUCT_FROM_DATABASE=R480 [Radeon X850XT] (Secondary) + +pci:v00001002d00004B6B* + ID_PRODUCT_FROM_DATABASE=R480 [Radeon X850Pro] (Secondary) + +pci:v00001002d00004B6C* + ID_PRODUCT_FROM_DATABASE=R481 [Radeon X850XT-PE] (Secondary) + +pci:v00001002d00004C42* + ID_PRODUCT_FROM_DATABASE=3D Rage LT Pro AGP-133 + +pci:v00001002d00004C42sv00000E11sd0000B0E7* + ID_PRODUCT_FROM_DATABASE=Rage LT Pro (Compaq Presario 5240) + +pci:v00001002d00004C42sv00000E11sd0000B0E8* + ID_PRODUCT_FROM_DATABASE=Rage 3D LT Pro + +pci:v00001002d00004C42sv00000E11sd0000B10E* + ID_PRODUCT_FROM_DATABASE=3D Rage LT Pro (Compaq Armada 1750) + +pci:v00001002d00004C42sv00001002sd00000040* + ID_PRODUCT_FROM_DATABASE=Rage LT Pro AGP 2X + +pci:v00001002d00004C42sv00001002sd00000044* + ID_PRODUCT_FROM_DATABASE=Rage LT Pro AGP 2X + +pci:v00001002d00004C42sv00001002sd00004C42* + ID_PRODUCT_FROM_DATABASE=Rage LT Pro AGP 2X + +pci:v00001002d00004C42sv00001002sd00008001* + ID_PRODUCT_FROM_DATABASE=Rage LT Pro AGP 2X + +pci:v00001002d00004C42sv00001028sd00000085* + ID_PRODUCT_FROM_DATABASE=Rage 3D LT Pro + +pci:v00001002d00004C44* + ID_PRODUCT_FROM_DATABASE=3D Rage LT Pro AGP-66 + +pci:v00001002d00004C45* + ID_PRODUCT_FROM_DATABASE=Rage Mobility M3 AGP + +pci:v00001002d00004C46* + ID_PRODUCT_FROM_DATABASE=Rage Mobility M3 AGP 2x + +pci:v00001002d00004C46sv00001002sd00000155* + ID_PRODUCT_FROM_DATABASE=IBM Thinkpad A22p + +pci:v00001002d00004C46sv00001014sd00000155* + ID_PRODUCT_FROM_DATABASE=IBM Thinkpad A22p + +pci:v00001002d00004C46sv00001028sd000000B1* + ID_PRODUCT_FROM_DATABASE=Latitude C600 + +pci:v00001002d00004C47* + ID_PRODUCT_FROM_DATABASE=3D Rage LT-G 215LG + +pci:v00001002d00004C49* + ID_PRODUCT_FROM_DATABASE=3D Rage LT Pro + +pci:v00001002d00004C49sv00001002sd00000004* + ID_PRODUCT_FROM_DATABASE=Rage LT Pro + +pci:v00001002d00004C49sv00001002sd00000040* + ID_PRODUCT_FROM_DATABASE=Rage LT Pro + +pci:v00001002d00004C49sv00001002sd00000044* + ID_PRODUCT_FROM_DATABASE=Rage LT Pro + +pci:v00001002d00004C49sv00001002sd00004C49* + ID_PRODUCT_FROM_DATABASE=Rage LT Pro + +pci:v00001002d00004C4D* + ID_PRODUCT_FROM_DATABASE=Rage Mobility P/M AGP 2x + +pci:v00001002d00004C4Dsv00000E11sd0000B111* + ID_PRODUCT_FROM_DATABASE=Armada M700 + +pci:v00001002d00004C4Dsv00000E11sd0000B160* + ID_PRODUCT_FROM_DATABASE=Armada E500 + +pci:v00001002d00004C4Dsv00001002sd00000084* + ID_PRODUCT_FROM_DATABASE=Xpert 98 AGP 2X (Mobility) + +pci:v00001002d00004C4Dsv00001014sd00000154* + ID_PRODUCT_FROM_DATABASE=ThinkPad A20m/A21m + +pci:v00001002d00004C4Dsv00001028sd000000AA* + ID_PRODUCT_FROM_DATABASE=Latitude CPt + +pci:v00001002d00004C4Dsv00001028sd000000BB* + ID_PRODUCT_FROM_DATABASE=Latitude CPx + +pci:v00001002d00004C4Dsv00001179sd0000FF00* + ID_PRODUCT_FROM_DATABASE=Satellite 1715XCDS laptop + +pci:v00001002d00004C4Dsv000013BDsd00001019* + ID_PRODUCT_FROM_DATABASE=PC-AR10 + +pci:v00001002d00004C4E* + ID_PRODUCT_FROM_DATABASE=Rage Mobility L AGP 2x + +pci:v00001002d00004C50* + ID_PRODUCT_FROM_DATABASE=3D Rage LT Pro + +pci:v00001002d00004C50sv00001002sd00004C50* + ID_PRODUCT_FROM_DATABASE=Rage LT Pro + +pci:v00001002d00004C51* + ID_PRODUCT_FROM_DATABASE=3D Rage LT Pro + +pci:v00001002d00004C52* + ID_PRODUCT_FROM_DATABASE=Rage Mobility P/M + +pci:v00001002d00004C52sv00001033sd00008112* + ID_PRODUCT_FROM_DATABASE=Versa Note VXi + +pci:v00001002d00004C53* + ID_PRODUCT_FROM_DATABASE=Rage Mobility L + +pci:v00001002d00004C54* + ID_PRODUCT_FROM_DATABASE=264LT [Mach64 LT] + +pci:v00001002d00004C57* + ID_PRODUCT_FROM_DATABASE=RV200 [Mobility Radeon 7500] + +pci:v00001002d00004C57sv00001014sd00000517* + ID_PRODUCT_FROM_DATABASE=ThinkPad T30 + +pci:v00001002d00004C57sv00001014sd00000530* + ID_PRODUCT_FROM_DATABASE=ThinkPad T42 2373-4WU + +pci:v00001002d00004C57sv00001028sd000000E6* + ID_PRODUCT_FROM_DATABASE=Radeon Mobility M7 LW (Dell Inspiron 8100) + +pci:v00001002d00004C57sv00001028sd0000012A* + ID_PRODUCT_FROM_DATABASE=Latitude C640 + +pci:v00001002d00004C57sv00001043sd00001622* + ID_PRODUCT_FROM_DATABASE=Mobility Radeon M7 (L3C/S) + +pci:v00001002d00004C57sv0000144Dsd0000C006* + ID_PRODUCT_FROM_DATABASE=Radeon Mobility M7 LW in vpr Matrix 170B4 + +pci:v00001002d00004C58* + ID_PRODUCT_FROM_DATABASE=Radeon RV200 LX [Mobility FireGL 7800 M7] + +pci:v00001002d00004C59* + ID_PRODUCT_FROM_DATABASE=RV100 LY [Mobility Radeon 7000] + +pci:v00001002d00004C59sv00000E11sd0000B111* + ID_PRODUCT_FROM_DATABASE=Evo N600c + +pci:v00001002d00004C59sv00001014sd00000235* + ID_PRODUCT_FROM_DATABASE=ThinkPad A30/A30p (2652/2653) + +pci:v00001002d00004C59sv00001014sd00000239* + ID_PRODUCT_FROM_DATABASE=ThinkPad X22/X23/X24 + +pci:v00001002d00004C59sv0000103Csd00000025* + ID_PRODUCT_FROM_DATABASE=XE4500 Notebook + +pci:v00001002d00004C59sv0000104Dsd000080E7* + ID_PRODUCT_FROM_DATABASE=VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP + +pci:v00001002d00004C59sv0000104Dsd00008140* + ID_PRODUCT_FROM_DATABASE=PCG-Z1SP laptop + +pci:v00001002d00004C59sv00001509sd00001930* + ID_PRODUCT_FROM_DATABASE=Medion MD9703 + +pci:v00001002d00004C5A* + ID_PRODUCT_FROM_DATABASE=RV100 LZ [Mobility Radeon 7000] + +pci:v00001002d00004C64* + ID_PRODUCT_FROM_DATABASE=Radeon RV250 Ld [Radeon Mobility 9000 M9] + +pci:v00001002d00004C65* + ID_PRODUCT_FROM_DATABASE=Radeon RV250 Le [Radeon Mobility 9000 M9] + +pci:v00001002d00004C66* + ID_PRODUCT_FROM_DATABASE=Radeon RV250 [Mobility FireGL 9000] + +pci:v00001002d00004C66sv00001014sd0000054D* + ID_PRODUCT_FROM_DATABASE=ThinkPad T41 + +pci:v00001002d00004C67* + ID_PRODUCT_FROM_DATABASE=Radeon RV250 Lg [Radeon Mobility 9000 M9] + +pci:v00001002d00004C6E* + ID_PRODUCT_FROM_DATABASE=Radeon RV250 Ln [Radeon Mobility 9000 M9] (Secondary) + +pci:v00001002d00004D46* + ID_PRODUCT_FROM_DATABASE=Rage Mobility M4 AGP + +pci:v00001002d00004D4C* + ID_PRODUCT_FROM_DATABASE=Rage Mobility M4 AGP + +pci:v00001002d00004D52* + ID_PRODUCT_FROM_DATABASE=Theater 550 PRO PCI [ATI TV Wonder 550] + +pci:v00001002d00004D53* + ID_PRODUCT_FROM_DATABASE=Theater 550 PRO PCIe + +pci:v00001002d00004E44* + ID_PRODUCT_FROM_DATABASE=Radeon R300 ND [Radeon 9700 Pro] + +pci:v00001002d00004E44sv00001002sd0000515E* + ID_PRODUCT_FROM_DATABASE=Radeon ES1000 + +pci:v00001002d00004E44sv00001002sd00005965* + ID_PRODUCT_FROM_DATABASE=Radeon ES1000 + +pci:v00001002d00004E45* + ID_PRODUCT_FROM_DATABASE=Radeon R300 NE [Radeon 9500 Pro] + +pci:v00001002d00004E45sv00001002sd00000002* + ID_PRODUCT_FROM_DATABASE=Radeon R300 NE [Radeon 9500 Pro] + +pci:v00001002d00004E45sv00001681sd00000002* + ID_PRODUCT_FROM_DATABASE=Hercules 3D Prophet 9500 PRO [Radeon 9500 Pro] + +pci:v00001002d00004E46* + ID_PRODUCT_FROM_DATABASE=R300 NF [Radeon 9600 TX] + +pci:v00001002d00004E47* + ID_PRODUCT_FROM_DATABASE=Radeon R300 NG [FireGL X1] + +pci:v00001002d00004E48* + ID_PRODUCT_FROM_DATABASE=Radeon R350 [Radeon 9800 Pro] + +pci:v00001002d00004E49* + ID_PRODUCT_FROM_DATABASE=Radeon R350 [Radeon 9800] + +pci:v00001002d00004E4A* + ID_PRODUCT_FROM_DATABASE=R360 NJ [Radeon 9800 XT] + +pci:v00001002d00004E4Asv00001002sd00004E4A* + ID_PRODUCT_FROM_DATABASE=R360 [Radeon 9800 XT] + +pci:v00001002d00004E4B* + ID_PRODUCT_FROM_DATABASE=R350 NK [FireGL X2] + +pci:v00001002d00004E50* + ID_PRODUCT_FROM_DATABASE=RV350 [Mobility Radeon 9600 M10] + +pci:v00001002d00004E50sv00001025sd0000005A* + ID_PRODUCT_FROM_DATABASE=TravelMate 290 + +pci:v00001002d00004E50sv0000103Csd0000088C* + ID_PRODUCT_FROM_DATABASE=NC8000 laptop + +pci:v00001002d00004E50sv0000103Csd00000890* + ID_PRODUCT_FROM_DATABASE=NC6000 laptop + +pci:v00001002d00004E50sv0000144Dsd0000C00C* + ID_PRODUCT_FROM_DATABASE=P35 notebook + +pci:v00001002d00004E50sv00001462sd00000311* + ID_PRODUCT_FROM_DATABASE=MSI M510A + +pci:v00001002d00004E50sv00001734sd00001055* + ID_PRODUCT_FROM_DATABASE=Amilo M1420W + +pci:v00001002d00004E51* + ID_PRODUCT_FROM_DATABASE=RV350 NQ [Mobility Radeon 9600] + +pci:v00001002d00004E52* + ID_PRODUCT_FROM_DATABASE=RV350 [Mobility Radeon 9600 M10] + +pci:v00001002d00004E52sv0000144Dsd0000C00C* + ID_PRODUCT_FROM_DATABASE=P35 notebook + +pci:v00001002d00004E53* + ID_PRODUCT_FROM_DATABASE=RV350 NS [Mobility Radeon 9600] + +pci:v00001002d00004E54* + ID_PRODUCT_FROM_DATABASE=M10 NT [FireGL Mobility T2] + +pci:v00001002d00004E56* + ID_PRODUCT_FROM_DATABASE=M11 NV [FireGL Mobility T2e] + +pci:v00001002d00004E64* + ID_PRODUCT_FROM_DATABASE=Radeon R300 [Radeon 9700 Pro] (Secondary) + +pci:v00001002d00004E65* + ID_PRODUCT_FROM_DATABASE=Radeon R300 [Radeon 9500 Pro] (Secondary) + +pci:v00001002d00004E65sv00001002sd00000003* + ID_PRODUCT_FROM_DATABASE=Radeon R300 NE [Radeon 9500 Pro] + +pci:v00001002d00004E65sv00001681sd00000003* + ID_PRODUCT_FROM_DATABASE=Hercules 3D Prophet 9500 PRO [Radeon 9500 Pro] (Secondary) + +pci:v00001002d00004E66* + ID_PRODUCT_FROM_DATABASE=RV350 NF [Radeon 9600] (Secondary) + +pci:v00001002d00004E67* + ID_PRODUCT_FROM_DATABASE=Radeon R300 [FireGL X1] (Secondary) + +pci:v00001002d00004E68* + ID_PRODUCT_FROM_DATABASE=Radeon R350 [Radeon 9800 Pro] (Secondary) + +pci:v00001002d00004E69* + ID_PRODUCT_FROM_DATABASE=Radeon R350 [Radeon 9800] (Secondary) + +pci:v00001002d00004E6A* + ID_PRODUCT_FROM_DATABASE=RV350 NJ [Radeon 9800 XT] (Secondary) + +pci:v00001002d00004E6Asv00001002sd00004E6A* + ID_PRODUCT_FROM_DATABASE=R360 [Radeon 9800 XT] (Secondary) + +pci:v00001002d00004E6Asv00001002sd00004E71* + ID_PRODUCT_FROM_DATABASE=M10 NQ [Radeon Mobility 9600] + +pci:v00001002d00004E71* + ID_PRODUCT_FROM_DATABASE=M10 NQ [Radeon Mobility 9600] (Secondary) + +pci:v00001002d00004F72* + ID_PRODUCT_FROM_DATABASE=RV250 [Radeon 9000 Series] + +pci:v00001002d00004F73* + ID_PRODUCT_FROM_DATABASE=Radeon RV250 [Radeon 9000 Series] (Secondary) + +pci:v00001002d00005041* + ID_PRODUCT_FROM_DATABASE=Rage 128 PA/PRO + +pci:v00001002d00005042* + ID_PRODUCT_FROM_DATABASE=Rage 128 PB/PRO AGP 2x + +pci:v00001002d00005043* + ID_PRODUCT_FROM_DATABASE=Rage 128 PC/PRO AGP 4x + +pci:v00001002d00005044* + ID_PRODUCT_FROM_DATABASE=Rage 128 PD/PRO TMDS + +pci:v00001002d00005044sv00001002sd00000028* + ID_PRODUCT_FROM_DATABASE=Rage 128 AIW + +pci:v00001002d00005044sv00001002sd00000029* + ID_PRODUCT_FROM_DATABASE=Rage 128 AIW + +pci:v00001002d00005045* + ID_PRODUCT_FROM_DATABASE=Rage 128 PE/PRO AGP 2x TMDS + +pci:v00001002d00005046* + ID_PRODUCT_FROM_DATABASE=Rage 128 PF/PRO AGP 4x TMDS + +pci:v00001002d00005046sv00001002sd00000004* + ID_PRODUCT_FROM_DATABASE=Rage Fury Pro + +pci:v00001002d00005046sv00001002sd00000008* + ID_PRODUCT_FROM_DATABASE=Rage Fury Pro/Xpert 2000 Pro + +pci:v00001002d00005046sv00001002sd00000014* + ID_PRODUCT_FROM_DATABASE=Rage Fury Pro + +pci:v00001002d00005046sv00001002sd00000018* + ID_PRODUCT_FROM_DATABASE=Rage Fury Pro/Xpert 2000 Pro + +pci:v00001002d00005046sv00001002sd00000028* + ID_PRODUCT_FROM_DATABASE=Rage 128 Pro AIW AGP + +pci:v00001002d00005046sv00001002sd0000002A* + ID_PRODUCT_FROM_DATABASE=Rage 128 Pro AIW AGP + +pci:v00001002d00005046sv00001002sd00000048* + ID_PRODUCT_FROM_DATABASE=Rage Fury Pro + +pci:v00001002d00005046sv00001002sd00002000* + ID_PRODUCT_FROM_DATABASE=Rage Fury MAXX AGP 4x (TMDS) (VGA device) + +pci:v00001002d00005046sv00001002sd00002001* + ID_PRODUCT_FROM_DATABASE=Rage Fury MAXX AGP 4x (TMDS) (Extra device?!) + +pci:v00001002d00005047* + ID_PRODUCT_FROM_DATABASE=Rage 128 PG/PRO + +pci:v00001002d00005048* + ID_PRODUCT_FROM_DATABASE=Rage 128 PH/PRO AGP 2x + +pci:v00001002d00005049* + ID_PRODUCT_FROM_DATABASE=Rage 128 PI/PRO AGP 4x + +pci:v00001002d0000504A* + ID_PRODUCT_FROM_DATABASE=Rage 128 PJ/PRO TMDS + +pci:v00001002d0000504B* + ID_PRODUCT_FROM_DATABASE=Rage 128 PK/PRO AGP 2x TMDS + +pci:v00001002d0000504C* + ID_PRODUCT_FROM_DATABASE=Rage 128 PL/PRO AGP 4x TMDS + +pci:v00001002d0000504D* + ID_PRODUCT_FROM_DATABASE=Rage 128 PM/PRO + +pci:v00001002d0000504E* + ID_PRODUCT_FROM_DATABASE=Rage 128 PN/PRO AGP 2x + +pci:v00001002d0000504F* + ID_PRODUCT_FROM_DATABASE=Rage 128 PO/PRO AGP 4x + +pci:v00001002d00005050* + ID_PRODUCT_FROM_DATABASE=Rage 128 PP/PRO TMDS [Xpert 128] + +pci:v00001002d00005050sv00001002sd00000008* + ID_PRODUCT_FROM_DATABASE=Xpert 128 + +pci:v00001002d00005051* + ID_PRODUCT_FROM_DATABASE=Rage 128 PQ/PRO AGP 2x TMDS + +pci:v00001002d00005052* + ID_PRODUCT_FROM_DATABASE=Rage 128 PR/PRO AGP 4x TMDS + +pci:v00001002d00005053* + ID_PRODUCT_FROM_DATABASE=Rage 128 PS/PRO + +pci:v00001002d00005054* + ID_PRODUCT_FROM_DATABASE=Rage 128 PT/PRO AGP 2x + +pci:v00001002d00005055* + ID_PRODUCT_FROM_DATABASE=Rage 128 PU/PRO AGP 4x + +pci:v00001002d00005056* + ID_PRODUCT_FROM_DATABASE=Rage 128 PV/PRO TMDS + +pci:v00001002d00005057* + ID_PRODUCT_FROM_DATABASE=Rage 128 PW/PRO AGP 2x TMDS + +pci:v00001002d00005058* + ID_PRODUCT_FROM_DATABASE=Rage 128 PX/PRO AGP 4x TMDS + +pci:v00001002d00005144* + ID_PRODUCT_FROM_DATABASE=Radeon R100 QD [Radeon 7200] + +pci:v00001002d00005144sv00001002sd00000008* + ID_PRODUCT_FROM_DATABASE=Radeon 7000/Radeon VE + +pci:v00001002d00005144sv00001002sd00000009* + ID_PRODUCT_FROM_DATABASE=Radeon 7000/Radeon + +pci:v00001002d00005144sv00001002sd0000000A* + ID_PRODUCT_FROM_DATABASE=Radeon 7000/Radeon + +pci:v00001002d00005144sv00001002sd0000001A* + ID_PRODUCT_FROM_DATABASE=Radeon 7000/Radeon + +pci:v00001002d00005144sv00001002sd00000029* + ID_PRODUCT_FROM_DATABASE=Radeon AIW + +pci:v00001002d00005144sv00001002sd00000038* + ID_PRODUCT_FROM_DATABASE=Radeon 7000/Radeon + +pci:v00001002d00005144sv00001002sd00000039* + ID_PRODUCT_FROM_DATABASE=Radeon 7000/Radeon + +pci:v00001002d00005144sv00001002sd0000008A* + ID_PRODUCT_FROM_DATABASE=Radeon 7000/Radeon + +pci:v00001002d00005144sv00001002sd000000BA* + ID_PRODUCT_FROM_DATABASE=Radeon 7000/Radeon + +pci:v00001002d00005144sv00001002sd00000139* + ID_PRODUCT_FROM_DATABASE=Radeon 7000/Radeon + +pci:v00001002d00005144sv00001002sd0000028A* + ID_PRODUCT_FROM_DATABASE=Radeon 7000/Radeon + +pci:v00001002d00005144sv00001002sd000002AA* + ID_PRODUCT_FROM_DATABASE=Radeon AIW + +pci:v00001002d00005144sv00001002sd0000053A* + ID_PRODUCT_FROM_DATABASE=Radeon 7000/Radeon + +pci:v00001002d00005145* + ID_PRODUCT_FROM_DATABASE=Radeon R100 QE + +pci:v00001002d00005146* + ID_PRODUCT_FROM_DATABASE=Radeon R100 QF + +pci:v00001002d00005147* + ID_PRODUCT_FROM_DATABASE=Radeon R100 QG + +pci:v00001002d00005148* + ID_PRODUCT_FROM_DATABASE=Radeon R200 QH [Radeon 8500] + +pci:v00001002d00005148sv00001002sd0000010A* + ID_PRODUCT_FROM_DATABASE=FireGL 8800 64Mb + +pci:v00001002d00005148sv00001002sd00000152* + ID_PRODUCT_FROM_DATABASE=FireGL 8800 128Mb + +pci:v00001002d00005148sv00001002sd00000162* + ID_PRODUCT_FROM_DATABASE=FireGL 8700 32Mb + +pci:v00001002d00005148sv00001002sd00000172* + ID_PRODUCT_FROM_DATABASE=FireGL 8700 64Mb + +pci:v00001002d00005149* + ID_PRODUCT_FROM_DATABASE=Radeon R200 QI + +pci:v00001002d0000514A* + ID_PRODUCT_FROM_DATABASE=Radeon R200 QJ + +pci:v00001002d0000514B* + ID_PRODUCT_FROM_DATABASE=Radeon R200 QK + +pci:v00001002d0000514C* + ID_PRODUCT_FROM_DATABASE=Radeon R200 QL [Radeon 8500 LE] + +pci:v00001002d0000514Csv00001002sd0000003A* + ID_PRODUCT_FROM_DATABASE=Radeon R200 QL [Radeon 8500 LE] + +pci:v00001002d0000514Csv00001002sd0000013A* + ID_PRODUCT_FROM_DATABASE=Radeon 8500 + +pci:v00001002d0000514Csv0000148Csd00002026* + ID_PRODUCT_FROM_DATABASE=R200 QL [Radeon 8500 Evil Master II Multi Display Edition] + +pci:v00001002d0000514Csv00001681sd00000010* + ID_PRODUCT_FROM_DATABASE=Radeon 8500 [3D Prophet 8500 128Mb] + +pci:v00001002d0000514Csv0000174Bsd00007149* + ID_PRODUCT_FROM_DATABASE=Radeon R200 QL [Sapphire Radeon 8500 LE] + +pci:v00001002d0000514Csv00001787sd00000F08* + ID_PRODUCT_FROM_DATABASE=Radeon R200 QL [PowerMagic Radeon 8500] + +pci:v00001002d0000514D* + ID_PRODUCT_FROM_DATABASE=Radeon R200 QM [Radeon 9100] + +pci:v00001002d0000514E* + ID_PRODUCT_FROM_DATABASE=Radeon R200 QN [Radeon 8500LE] + +pci:v00001002d0000514F* + ID_PRODUCT_FROM_DATABASE=Radeon R200 QO [Radeon 8500LE] + +pci:v00001002d00005154* + ID_PRODUCT_FROM_DATABASE=R200 QT [Radeon 8500] + +pci:v00001002d00005155* + ID_PRODUCT_FROM_DATABASE=R200 QU [Radeon 9100] + +pci:v00001002d00005157* + ID_PRODUCT_FROM_DATABASE=RV200 QW [Radeon 7500] + +pci:v00001002d00005157sv00001002sd0000013A* + ID_PRODUCT_FROM_DATABASE=Radeon 7500 + +pci:v00001002d00005157sv00001002sd00000F2B* + ID_PRODUCT_FROM_DATABASE=ALL-IN-WONDER VE PCI + +pci:v00001002d00005157sv00001002sd0000103A* + ID_PRODUCT_FROM_DATABASE=Dell Optiplex GX260 + +pci:v00001002d00005157sv00001458sd00004000* + ID_PRODUCT_FROM_DATABASE=RV200 QW [RADEON 7500 PRO MAYA AR] + +pci:v00001002d00005157sv0000148Csd00002024* + ID_PRODUCT_FROM_DATABASE=RV200 QW [Radeon 7500LE Dual Display] + +pci:v00001002d00005157sv0000148Csd00002025* + ID_PRODUCT_FROM_DATABASE=RV200 QW [Radeon 7500 Evil Master Multi Display Edition] + +pci:v00001002d00005157sv0000148Csd00002036* + ID_PRODUCT_FROM_DATABASE=RV200 QW [Radeon 7500 PCI Dual Display] + +pci:v00001002d00005157sv0000174Bsd00007146* + ID_PRODUCT_FROM_DATABASE=RV200 QW [Radeon 7500 LE] + +pci:v00001002d00005157sv0000174Bsd00007147* + ID_PRODUCT_FROM_DATABASE=RV200 QW [Sapphire Radeon 7500LE] + +pci:v00001002d00005157sv0000174Bsd00007161* + ID_PRODUCT_FROM_DATABASE=Radeon RV200 QW [Radeon 7500 LE] + +pci:v00001002d00005157sv000017AFsd00000202* + ID_PRODUCT_FROM_DATABASE=RV200 QW [Excalibur Radeon 7500LE] + +pci:v00001002d00005158* + ID_PRODUCT_FROM_DATABASE=RV200 QX [Radeon 7500] + +pci:v00001002d00005159* + ID_PRODUCT_FROM_DATABASE=RV100 QY [Radeon 7000/VE] + +pci:v00001002d00005159sv00001002sd0000000A* + ID_PRODUCT_FROM_DATABASE=Radeon 7000/Radeon VE + +pci:v00001002d00005159sv00001002sd0000000B* + ID_PRODUCT_FROM_DATABASE=Radeon 7000 + +pci:v00001002d00005159sv00001002sd00000038* + ID_PRODUCT_FROM_DATABASE=Radeon 7000/Radeon VE + +pci:v00001002d00005159sv00001002sd0000003A* + ID_PRODUCT_FROM_DATABASE=Radeon 7000/Radeon VE + +pci:v00001002d00005159sv00001002sd000000BA* + ID_PRODUCT_FROM_DATABASE=Radeon 7000/Radeon VE + +pci:v00001002d00005159sv00001002sd0000013A* + ID_PRODUCT_FROM_DATABASE=Radeon 7000/Radeon VE + +pci:v00001002d00005159sv00001002sd00000908* + ID_PRODUCT_FROM_DATABASE=XVR-100 (supplied by Sun) + +pci:v00001002d00005159sv00001014sd0000029A* + ID_PRODUCT_FROM_DATABASE=Remote Supervisor Adapter II (RSA2) + +pci:v00001002d00005159sv00001014sd000002C8* + ID_PRODUCT_FROM_DATABASE=eServer xSeries server mainboard + +pci:v00001002d00005159sv00001028sd0000016C* + ID_PRODUCT_FROM_DATABASE=PowerEdge 1850 Embedded Radeon 7000/VE + +pci:v00001002d00005159sv00001028sd0000016D* + ID_PRODUCT_FROM_DATABASE=PowerEdge 2850 Embedded Radeon 7000-M + +pci:v00001002d00005159sv00001028sd00000170* + ID_PRODUCT_FROM_DATABASE=PowerEdge 6850 Embedded Radeon 7000/VE + +pci:v00001002d00005159sv00001028sd0000019A* + ID_PRODUCT_FROM_DATABASE=PowerEdge SC1425 + +pci:v00001002d00005159sv0000103Csd00001292* + ID_PRODUCT_FROM_DATABASE=Radeon 7000 + +pci:v00001002d00005159sv00001043sd0000C00A* + ID_PRODUCT_FROM_DATABASE=A7000/T/64M + +pci:v00001002d00005159sv00001458sd00004002* + ID_PRODUCT_FROM_DATABASE=RV100 QY [RADEON 7000 PRO MAYA AV Series] + +pci:v00001002d00005159sv0000148Csd00002003* + ID_PRODUCT_FROM_DATABASE=RV100 QY [Radeon 7000 Multi-Display Edition] + +pci:v00001002d00005159sv0000148Csd00002023* + ID_PRODUCT_FROM_DATABASE=RV100 QY [Radeon 7000 Evil Master Multi-Display] + +pci:v00001002d00005159sv0000174Bsd00000280* + ID_PRODUCT_FROM_DATABASE=Radeon RV100 QY [Radeon 7000/VE] + +pci:v00001002d00005159sv0000174Bsd00007112* + ID_PRODUCT_FROM_DATABASE=RV100 QY [Sapphire Radeon VE 7000] + +pci:v00001002d00005159sv0000174Bsd00007C28* + ID_PRODUCT_FROM_DATABASE=Sapphire Radeon VE 7000 DDR + +pci:v00001002d00005159sv00001787sd00000202* + ID_PRODUCT_FROM_DATABASE=RV100 QY [Excalibur Radeon 7000] + +pci:v00001002d00005159sv000017EEsd00001001* + ID_PRODUCT_FROM_DATABASE=Radeon 7000 64MB DDR + DVI + +pci:v00001002d0000515A* + ID_PRODUCT_FROM_DATABASE=RV100 QZ [Radeon 7000/VE] + +pci:v00001002d0000515E* + ID_PRODUCT_FROM_DATABASE=ES1000 + +pci:v00001002d0000515Esv00001028sd000001BB* + ID_PRODUCT_FROM_DATABASE=PowerEdge 1955 Embedded ATI ES1000 + +pci:v00001002d0000515Esv00001028sd000001DF* + ID_PRODUCT_FROM_DATABASE=PowerEdge SC440 + +pci:v00001002d0000515Esv00001028sd000001E6* + ID_PRODUCT_FROM_DATABASE=PowerEdge 860 + +pci:v00001002d0000515Esv00001028sd000001F0* + ID_PRODUCT_FROM_DATABASE=PowerEdge R900 Embedded ATI ES1000 + +pci:v00001002d0000515Esv00001028sd00000205* + ID_PRODUCT_FROM_DATABASE=PowerEdge 2970 Embedded ATI ES1000 + +pci:v00001002d0000515Esv00001028sd0000020B* + ID_PRODUCT_FROM_DATABASE=PowerEdge T605 Embedded ATI ES1000 + +pci:v00001002d0000515Esv00001028sd0000020F* + ID_PRODUCT_FROM_DATABASE=PowerEdge R300 Embedded ATI ES1000 + +pci:v00001002d0000515Esv00001028sd00000210* + ID_PRODUCT_FROM_DATABASE=PowerEdge T300 Embedded ATI ES1000 + +pci:v00001002d0000515Esv00001028sd00000221* + ID_PRODUCT_FROM_DATABASE=PowerEdge R805 Embedded ATI ES1000 + +pci:v00001002d0000515Esv00001028sd00000223* + ID_PRODUCT_FROM_DATABASE=PowerEdge R905 Embedded ATI ES1000 + +pci:v00001002d0000515Esv00001028sd00000225* + ID_PRODUCT_FROM_DATABASE=PowerEdge T105 Embedded ATI ES1000 + +pci:v00001002d0000515Esv00001028sd0000023C* + ID_PRODUCT_FROM_DATABASE=PowerEdge R200 Embedded ATI ES1000 + +pci:v00001002d0000515Esv0000103Csd00001304* + ID_PRODUCT_FROM_DATABASE=Integrity iLO2 Advanced KVM VGA [AD307A] + +pci:v00001002d0000515Esv000015D9sd00008680* + ID_PRODUCT_FROM_DATABASE=X7DVL-E-O motherboard + +pci:v00001002d0000515Esv00008086sd00003476* + ID_PRODUCT_FROM_DATABASE=S5000PSLSATA Server Board + +pci:v00001002d0000515F* + ID_PRODUCT_FROM_DATABASE=ES1000 + +pci:v00001002d00005168* + ID_PRODUCT_FROM_DATABASE=Radeon R200 Qh + +pci:v00001002d00005169* + ID_PRODUCT_FROM_DATABASE=Radeon R200 Qi + +pci:v00001002d0000516A* + ID_PRODUCT_FROM_DATABASE=Radeon R200 Qj + +pci:v00001002d0000516B* + ID_PRODUCT_FROM_DATABASE=Radeon R200 Qk + +pci:v00001002d0000516C* + ID_PRODUCT_FROM_DATABASE=Radeon R200 Ql + +pci:v00001002d00005245* + ID_PRODUCT_FROM_DATABASE=Rage 128 RE/SG + +pci:v00001002d00005245sv00001002sd00000008* + ID_PRODUCT_FROM_DATABASE=Xpert 128 + +pci:v00001002d00005245sv00001002sd00000028* + ID_PRODUCT_FROM_DATABASE=Rage 128 AIW + +pci:v00001002d00005245sv00001002sd00000029* + ID_PRODUCT_FROM_DATABASE=Rage 128 AIW + +pci:v00001002d00005245sv00001002sd00000068* + ID_PRODUCT_FROM_DATABASE=Rage 128 AIW + +pci:v00001002d00005246* + ID_PRODUCT_FROM_DATABASE=Rage 128 RF/SG AGP + +pci:v00001002d00005246sv00001002sd00000004* + ID_PRODUCT_FROM_DATABASE=Magnum/Xpert 128/Xpert 99 + +pci:v00001002d00005246sv00001002sd00000008* + ID_PRODUCT_FROM_DATABASE=Magnum/Xpert128/X99/Xpert2000 + +pci:v00001002d00005246sv00001002sd00000028* + ID_PRODUCT_FROM_DATABASE=Rage 128 AIW AGP + +pci:v00001002d00005246sv00001002sd00000044* + ID_PRODUCT_FROM_DATABASE=Rage Fury/Xpert 128/Xpert 2000 + +pci:v00001002d00005246sv00001002sd00000068* + ID_PRODUCT_FROM_DATABASE=Rage 128 AIW AGP + +pci:v00001002d00005246sv00001002sd00000448* + ID_PRODUCT_FROM_DATABASE=Rage Fury + +pci:v00001002d00005247* + ID_PRODUCT_FROM_DATABASE=Rage 128 RG + +pci:v00001002d0000524B* + ID_PRODUCT_FROM_DATABASE=Rage 128 RK/VR + +pci:v00001002d0000524C* + ID_PRODUCT_FROM_DATABASE=Rage 128 RL/VR AGP + +pci:v00001002d0000524Csv00001002sd00000008* + ID_PRODUCT_FROM_DATABASE=Xpert 99/Xpert 2000 + +pci:v00001002d0000524Csv00001002sd00000088* + ID_PRODUCT_FROM_DATABASE=Xpert 99 + +pci:v00001002d00005345* + ID_PRODUCT_FROM_DATABASE=Rage 128 SE/4x + +pci:v00001002d00005346* + ID_PRODUCT_FROM_DATABASE=Rage 128 SF/4x AGP 2x + +pci:v00001002d00005346sv00001002sd00000048* + ID_PRODUCT_FROM_DATABASE=RAGE 128 16MB VGA TVOUT AMC PAL + +pci:v00001002d00005347* + ID_PRODUCT_FROM_DATABASE=Rage 128 SG/4x AGP 4x + +pci:v00001002d00005348* + ID_PRODUCT_FROM_DATABASE=Rage 128 SH + +pci:v00001002d0000534B* + ID_PRODUCT_FROM_DATABASE=Rage 128 SK/4x + +pci:v00001002d0000534C* + ID_PRODUCT_FROM_DATABASE=Rage 128 SL/4x AGP 2x + +pci:v00001002d0000534D* + ID_PRODUCT_FROM_DATABASE=Rage 128 SM/4x AGP 4x + +pci:v00001002d0000534Dsv00001002sd00000008* + ID_PRODUCT_FROM_DATABASE=Xpert 99/Xpert 2000 + +pci:v00001002d0000534Dsv00001002sd00000018* + ID_PRODUCT_FROM_DATABASE=Xpert 2000 + +pci:v00001002d0000534E* + ID_PRODUCT_FROM_DATABASE=Rage 128 4x + +pci:v00001002d00005354* + ID_PRODUCT_FROM_DATABASE=Mach 64 VT + +pci:v00001002d00005354sv00001002sd00005654* + ID_PRODUCT_FROM_DATABASE=Mach 64 reference + +pci:v00001002d00005446* + ID_PRODUCT_FROM_DATABASE=Rage 128 Pro Ultra TF + +pci:v00001002d00005446sv00001002sd00000004* + ID_PRODUCT_FROM_DATABASE=Rage Fury Pro + +pci:v00001002d00005446sv00001002sd00000008* + ID_PRODUCT_FROM_DATABASE=Rage Fury Pro/Xpert 2000 Pro + +pci:v00001002d00005446sv00001002sd00000018* + ID_PRODUCT_FROM_DATABASE=Rage Fury Pro/Xpert 2000 Pro + +pci:v00001002d00005446sv00001002sd00000028* + ID_PRODUCT_FROM_DATABASE=Rage 128 AIW Pro AGP + +pci:v00001002d00005446sv00001002sd00000029* + ID_PRODUCT_FROM_DATABASE=Rage 128 AIW + +pci:v00001002d00005446sv00001002sd0000002A* + ID_PRODUCT_FROM_DATABASE=Rage 128 AIW Pro AGP + +pci:v00001002d00005446sv00001002sd0000002B* + ID_PRODUCT_FROM_DATABASE=Rage 128 AIW + +pci:v00001002d00005446sv00001002sd00000048* + ID_PRODUCT_FROM_DATABASE=Xpert 2000 Pro + +pci:v00001002d0000544C* + ID_PRODUCT_FROM_DATABASE=Rage 128 Pro Ultra TL + +pci:v00001002d00005452* + ID_PRODUCT_FROM_DATABASE=Rage 128 Pro Ultra TR + +pci:v00001002d00005452sv00001002sd0000001C* + ID_PRODUCT_FROM_DATABASE=Rage 128 Pro 4XL + +pci:v00001002d00005452sv0000103Csd00001279* + ID_PRODUCT_FROM_DATABASE=Rage 128 Pro 4XL + +pci:v00001002d00005453* + ID_PRODUCT_FROM_DATABASE=Rage 128 Pro Ultra TS + +pci:v00001002d00005454* + ID_PRODUCT_FROM_DATABASE=Rage 128 Pro Ultra TT + +pci:v00001002d00005455* + ID_PRODUCT_FROM_DATABASE=Rage 128 Pro Ultra TU + +pci:v00001002d00005460* + ID_PRODUCT_FROM_DATABASE=RV370 [Mobility Radeon X300] + +pci:v00001002d00005460sv00001775sd00001100* + ID_PRODUCT_FROM_DATABASE=CR11/VR11 Single Board Computer + +pci:v00001002d00005461* + ID_PRODUCT_FROM_DATABASE=RV370 [Mobility Radeon X300] + +pci:v00001002d00005462* + ID_PRODUCT_FROM_DATABASE=RV380 [Mobility Radeon X600] + +pci:v00001002d00005464* + ID_PRODUCT_FROM_DATABASE=RV370 [Mobility FireGL V3100] + +pci:v00001002d00005548* + ID_PRODUCT_FROM_DATABASE=R423 UH [Radeon X800 (PCIE)] + +pci:v00001002d00005549* + ID_PRODUCT_FROM_DATABASE=R423 UI [Radeon X800PRO (PCIE)] + +pci:v00001002d0000554A* + ID_PRODUCT_FROM_DATABASE=R423 UJ [Radeon X800LE (PCIE)] + +pci:v00001002d0000554B* + ID_PRODUCT_FROM_DATABASE=R423 UK [Radeon X800SE (PCIE)] + +pci:v00001002d0000554C* + ID_PRODUCT_FROM_DATABASE=R430 [Radeon X800XTP PCIe] + +pci:v00001002d0000554D* + ID_PRODUCT_FROM_DATABASE=R430 [Radeon X800 XL] (PCIe) + +pci:v00001002d0000554Dsv00001458sd00002124* + ID_PRODUCT_FROM_DATABASE=GV-R80L256V-B (AGP) + +pci:v00001002d0000554E* + ID_PRODUCT_FROM_DATABASE=R430 [Radeon X800 SE PCIe] + +pci:v00001002d0000554F* + ID_PRODUCT_FROM_DATABASE=R430 [Radeon X800 (PCIE)] + +pci:v00001002d00005550* + ID_PRODUCT_FROM_DATABASE=R423 [FireGL V7100] + +pci:v00001002d00005551* + ID_PRODUCT_FROM_DATABASE=R423 [FireGL V5100 (PCIE)] + +pci:v00001002d00005552* + ID_PRODUCT_FROM_DATABASE=R423 UR [FireGL V5100 (PCIE)] + +pci:v00001002d00005554* + ID_PRODUCT_FROM_DATABASE=R423 UT [FireGL V7100 (PCIE)] + +pci:v00001002d00005555* + ID_PRODUCT_FROM_DATABASE=R430 GL PRO + +pci:v00001002d00005569* + ID_PRODUCT_FROM_DATABASE=R423 UI [Radeon X800PRO (PCIE)] (Secondary) + +pci:v00001002d0000556B* + ID_PRODUCT_FROM_DATABASE=Radeon R423 UK (PCIE) [X800 SE] (Secondary) + +pci:v00001002d0000556D* + ID_PRODUCT_FROM_DATABASE=R430 [Radeon X800 XL] (PCIe) (Secondary) + +pci:v00001002d0000556Dsv00001458sd00002125* + ID_PRODUCT_FROM_DATABASE=GV-R80L256V-B (AGP) + +pci:v00001002d0000556F* + ID_PRODUCT_FROM_DATABASE=R430 [Radeon X800] (PCIE) (Secondary) + +pci:v00001002d00005571* + ID_PRODUCT_FROM_DATABASE=R423GL-SE [FireGL V5100 (PCIE)] (Secondary) + +pci:v00001002d0000564A* + ID_PRODUCT_FROM_DATABASE=M26 [Mobility FireGL V5000] + +pci:v00001002d0000564B* + ID_PRODUCT_FROM_DATABASE=M26 [Mobility FireGL V5000] + +pci:v00001002d0000564F* + ID_PRODUCT_FROM_DATABASE=M26 [Radeon Mobility X700 XL (PCIE)] + +pci:v00001002d00005652* + ID_PRODUCT_FROM_DATABASE=M26 [Radeon Mobility X700] + +pci:v00001002d00005653* + ID_PRODUCT_FROM_DATABASE=Radeon Mobility X700 (PCIE) + +pci:v00001002d00005653sv00001025sd00000080* + ID_PRODUCT_FROM_DATABASE=Aspire 5024WLMi + +pci:v00001002d00005653sv0000103Csd00000940* + ID_PRODUCT_FROM_DATABASE=HP Compaq NW8240 Mobile Workstation + +pci:v00001002d00005654* + ID_PRODUCT_FROM_DATABASE=264VT [Mach64 VT] + +pci:v00001002d00005654sv00001002sd00005654* + ID_PRODUCT_FROM_DATABASE=Mach64VT Reference + +pci:v00001002d00005655* + ID_PRODUCT_FROM_DATABASE=264VT3 [Mach64 VT3] + +pci:v00001002d00005656* + ID_PRODUCT_FROM_DATABASE=264VT4 [Mach64 VT4] + +pci:v00001002d00005657* + ID_PRODUCT_FROM_DATABASE=Radeon X550/X700 Series (RV410) + +pci:v00001002d00005830* + ID_PRODUCT_FROM_DATABASE=RS300 Host Bridge + +pci:v00001002d00005831* + ID_PRODUCT_FROM_DATABASE=RS300 Host Bridge + +pci:v00001002d00005832* + ID_PRODUCT_FROM_DATABASE=RS300 Host Bridge + +pci:v00001002d00005833* + ID_PRODUCT_FROM_DATABASE=Radeon 9100 IGP Host Bridge + +pci:v00001002d00005834* + ID_PRODUCT_FROM_DATABASE=RS300 [Radeon 9100 IGP] + +pci:v00001002d00005835* + ID_PRODUCT_FROM_DATABASE=RS300M AGP [Radeon Mobility 9100IGP] + +pci:v00001002d00005838* + ID_PRODUCT_FROM_DATABASE=Radeon 9100 IGP AGP Bridge + +pci:v00001002d00005854* + ID_PRODUCT_FROM_DATABASE=Radeon Xpress Series (RS480) + +pci:v00001002d00005874* + ID_PRODUCT_FROM_DATABASE=Radeon Xpress Series (RS482) + +pci:v00001002d00005940* + ID_PRODUCT_FROM_DATABASE=RV280 [Radeon 9200 PRO] (Secondary) + +pci:v00001002d00005940sv000017AFsd00002021* + ID_PRODUCT_FROM_DATABASE=Excalibur Radeon 9250 (Secondary) + +pci:v00001002d00005941* + ID_PRODUCT_FROM_DATABASE=RV280 [Radeon 9200] (Secondary) + +pci:v00001002d00005941sv00001458sd00004019* + ID_PRODUCT_FROM_DATABASE=Gigabyte Radeon 9200 + +pci:v00001002d00005941sv0000174Bsd00007C12* + ID_PRODUCT_FROM_DATABASE=Sapphire Radeon 9200 + +pci:v00001002d00005941sv000017AFsd0000200D* + ID_PRODUCT_FROM_DATABASE=Excalibur Radeon 9200 + +pci:v00001002d00005941sv000018BCsd00000050* + ID_PRODUCT_FROM_DATABASE=GeXcube GC-R9200-C3 (Secondary) + +pci:v00001002d00005944* + ID_PRODUCT_FROM_DATABASE=RV280 [Radeon 9200 SE (PCI)] + +pci:v00001002d00005950* + ID_PRODUCT_FROM_DATABASE=RS480 Host Bridge + +pci:v00001002d00005950sv00001025sd00000080* + ID_PRODUCT_FROM_DATABASE=Aspire 5024WLMMi + +pci:v00001002d00005950sv0000103Csd0000280A* + ID_PRODUCT_FROM_DATABASE=DC5750 Microtower + +pci:v00001002d00005950sv0000103Csd00002A20* + ID_PRODUCT_FROM_DATABASE=Pavilion t3030.de Desktop PC + +pci:v00001002d00005950sv0000103Csd0000308B* + ID_PRODUCT_FROM_DATABASE=MX6125 + +pci:v00001002d00005950sv00001462sd00000131* + ID_PRODUCT_FROM_DATABASE=MS-1013 Notebook + +pci:v00001002d00005950sv00001462sd00007217* + ID_PRODUCT_FROM_DATABASE=Aspire L250 + +pci:v00001002d00005951* + ID_PRODUCT_FROM_DATABASE=Radeon Xpress 200 (RS480/RS482/RX480/RX482) Chipset - Host bridge + +pci:v00001002d00005952* + ID_PRODUCT_FROM_DATABASE=RD580 [CrossFire Xpress 3200] Chipset Host Bridge + +pci:v00001002d00005954* + ID_PRODUCT_FROM_DATABASE=RS480 [Radeon Xpress 200G Series] + +pci:v00001002d00005954sv00001002sd00005954* + ID_PRODUCT_FROM_DATABASE=RV370 [Radeon Xpress 200G Series] + +pci:v00001002d00005955* + ID_PRODUCT_FROM_DATABASE=Radeon XPRESS 200M 5955 (PCIE) + +pci:v00001002d00005955sv00001002sd00005955* + ID_PRODUCT_FROM_DATABASE=RS480 0x5955 [Radeon XPRESS 200M 5955 (PCIE)] + +pci:v00001002d00005955sv0000103Csd0000308B* + ID_PRODUCT_FROM_DATABASE=MX6125 + +pci:v00001002d00005955sv00001462sd00000131* + ID_PRODUCT_FROM_DATABASE=MS-1013 Notebook + +pci:v00001002d00005956* + ID_PRODUCT_FROM_DATABASE=RD790 Northbridge only dual slot PCI-e_GFX and HT3 K8 part + +pci:v00001002d00005957* + ID_PRODUCT_FROM_DATABASE=RX780/RX790 Chipset Host Bridge + +pci:v00001002d00005957sv00001849sd00005957* + ID_PRODUCT_FROM_DATABASE=A770CrossFire Motherboard + +pci:v00001002d00005958* + ID_PRODUCT_FROM_DATABASE=RD780 Northbridge only dual slot PCI-e_GFX and HT1 K8 part + +pci:v00001002d00005960* + ID_PRODUCT_FROM_DATABASE=RV280 [Radeon 9200 PRO] + +pci:v00001002d00005960sv000017AFsd00002020* + ID_PRODUCT_FROM_DATABASE=Excalibur Radeon 9250 + +pci:v00001002d00005961* + ID_PRODUCT_FROM_DATABASE=RV280 [Radeon 9200] + +pci:v00001002d00005961sv00001002sd00002F72* + ID_PRODUCT_FROM_DATABASE=All-in-Wonder 9200 Series + +pci:v00001002d00005961sv00001019sd00004C30* + ID_PRODUCT_FROM_DATABASE=Radeon 9200 VIVO + +pci:v00001002d00005961sv000012ABsd00005961* + ID_PRODUCT_FROM_DATABASE=YUAN SMARTVGA Radeon 9200 + +pci:v00001002d00005961sv00001458sd00004018* + ID_PRODUCT_FROM_DATABASE=Gigabyte Radeon 9200 + +pci:v00001002d00005961sv0000174Bsd00007C13* + ID_PRODUCT_FROM_DATABASE=Sapphire Radeon 9200 + +pci:v00001002d00005961sv000017AFsd0000200C* + ID_PRODUCT_FROM_DATABASE=Excalibur Radeon 9200 + +pci:v00001002d00005961sv000018BCsd00000050* + ID_PRODUCT_FROM_DATABASE=Radeon 9200 Game Buster + +pci:v00001002d00005961sv000018BCsd00000051* + ID_PRODUCT_FROM_DATABASE=GeXcube GC-R9200-C3 + +pci:v00001002d00005961sv000018BCsd00000053* + ID_PRODUCT_FROM_DATABASE=Radeon 9200 Game Buster VIVO + +pci:v00001002d00005962* + ID_PRODUCT_FROM_DATABASE=RV280 [Radeon 9200] + +pci:v00001002d00005964* + ID_PRODUCT_FROM_DATABASE=RV280 [Radeon 9200 SE] + +pci:v00001002d00005964sv00001002sd00005964* + ID_PRODUCT_FROM_DATABASE=Radeon 9200 SE, 64-bit 128MB DDR, 200/166MHz + +pci:v00001002d00005964sv00001043sd0000C006* + ID_PRODUCT_FROM_DATABASE=ASUS Radeon 9200 SE / TD / 128M + +pci:v00001002d00005964sv00001458sd00004018* + ID_PRODUCT_FROM_DATABASE=Radeon 9200 SE + +pci:v00001002d00005964sv00001458sd00004032* + ID_PRODUCT_FROM_DATABASE=Radeon 9200 SE 128MB + +pci:v00001002d00005964sv0000147Bsd00006191* + ID_PRODUCT_FROM_DATABASE=R9200SE-DT + +pci:v00001002d00005964sv0000148Csd00002073* + ID_PRODUCT_FROM_DATABASE=CN-AG92E + +pci:v00001002d00005964sv0000174Bsd00007C13* + ID_PRODUCT_FROM_DATABASE=Sapphire Radeon 9200 SE + +pci:v00001002d00005964sv00001787sd00005964* + ID_PRODUCT_FROM_DATABASE=Excalibur 9200SE VIVO 128M + +pci:v00001002d00005964sv000017AFsd00002012* + ID_PRODUCT_FROM_DATABASE=Radeon 9200 SE Excalibur + +pci:v00001002d00005964sv000018BCsd00000170* + ID_PRODUCT_FROM_DATABASE=Sapphire Radeon 9200 SE 128MB Game Buster + +pci:v00001002d00005964sv000018BCsd00000173* + ID_PRODUCT_FROM_DATABASE=GC-R9200L(SE)-C3H [Radeon 9200 Game Buster] + +pci:v00001002d00005965* + ID_PRODUCT_FROM_DATABASE=RV280 [FireMV 2200 PCI] + +pci:v00001002d00005969* + ID_PRODUCT_FROM_DATABASE=ES1000 + +pci:v00001002d00005974* + ID_PRODUCT_FROM_DATABASE=RS482 [Radeon Xpress 200] + +pci:v00001002d00005974sv0000103Csd0000280A* + ID_PRODUCT_FROM_DATABASE=DC5750 Microtower + +pci:v00001002d00005974sv00001462sd00007141* + ID_PRODUCT_FROM_DATABASE=Aspire L250 + +pci:v00001002d00005975* + ID_PRODUCT_FROM_DATABASE=RS482 [Radeon Xpress 200M] + +pci:v00001002d00005978* + ID_PRODUCT_FROM_DATABASE=RD790 PCI to PCI bridge (external gfx0 port A) + +pci:v00001002d00005978sv00001849sd00005957* + ID_PRODUCT_FROM_DATABASE=A770CrossFire Motherboard + +pci:v00001002d00005979* + ID_PRODUCT_FROM_DATABASE=RD790 PCI to PCI bridge (external gfx0 port B) + +pci:v00001002d0000597A* + ID_PRODUCT_FROM_DATABASE=RD790 PCI to PCI bridge (PCI express gpp port A) + +pci:v00001002d0000597B* + ID_PRODUCT_FROM_DATABASE=RD790 PCI to PCI bridge (PCI express gpp port B) + +pci:v00001002d0000597C* + ID_PRODUCT_FROM_DATABASE=RD790 PCI to PCI bridge (PCI express gpp port C) + +pci:v00001002d0000597D* + ID_PRODUCT_FROM_DATABASE=RD790 PCI to PCI bridge (PCI express gpp port D) + +pci:v00001002d0000597E* + ID_PRODUCT_FROM_DATABASE=RD790 PCI to PCI bridge (PCI express gpp port E) + +pci:v00001002d0000597Esv00001849sd00005957* + ID_PRODUCT_FROM_DATABASE=A770CrossFire Motherboard + +pci:v00001002d0000597F* + ID_PRODUCT_FROM_DATABASE=RD790 PCI to PCI bridge (PCI express gpp port F) + +pci:v00001002d0000597Fsv00001849sd00005957* + ID_PRODUCT_FROM_DATABASE=A770CrossFire Motherboard + +pci:v00001002d00005980* + ID_PRODUCT_FROM_DATABASE=RD790 PCI to PCI bridge (external gfx1 port A) + +pci:v00001002d00005981* + ID_PRODUCT_FROM_DATABASE=RD790 PCI to PCI bridge (external gfx1 port B) + +pci:v00001002d00005982* + ID_PRODUCT_FROM_DATABASE=RD790 PCI to PCI bridge (NB-SB link) + +pci:v00001002d00005A10* + ID_PRODUCT_FROM_DATABASE=RD890 Northbridge only dual slot (2x16) PCI-e GFX Hydra part + +pci:v00001002d00005A11* + ID_PRODUCT_FROM_DATABASE=RD890 Northbridge only single slot PCI-e GFX Hydra part + +pci:v00001002d00005A12* + ID_PRODUCT_FROM_DATABASE=RD890 Northbridge only dual slot (2x8) PCI-e GFX Hydra part + +pci:v00001002d00005A12sv000015D9sd0000A811* + ID_PRODUCT_FROM_DATABASE=H8DGU + +pci:v00001002d00005A13* + ID_PRODUCT_FROM_DATABASE=RD890 PCI to PCI bridge (external gfx0 port A) + +pci:v00001002d00005A14* + ID_PRODUCT_FROM_DATABASE=RD890 PCI to PCI bridge (external gfx0 port B) + +pci:v00001002d00005A15* + ID_PRODUCT_FROM_DATABASE=RD890 PCI to PCI bridge (PCI express gpp port A) + +pci:v00001002d00005A16* + ID_PRODUCT_FROM_DATABASE=RD890 PCI to PCI bridge (PCI express gpp port B) + +pci:v00001002d00005A17* + ID_PRODUCT_FROM_DATABASE=RD890 PCI to PCI bridge (PCI express gpp port C) + +pci:v00001002d00005A18* + ID_PRODUCT_FROM_DATABASE=RD890 PCI to PCI bridge (PCI express gpp port D) + +pci:v00001002d00005A18sv000015D9sd0000A811* + ID_PRODUCT_FROM_DATABASE=H8DGU + +pci:v00001002d00005A19* + ID_PRODUCT_FROM_DATABASE=RD890 PCI to PCI bridge (PCI express gpp port E) + +pci:v00001002d00005A1A* + ID_PRODUCT_FROM_DATABASE=RD890 PCI to PCI bridge (PCI express gpp port F) + +pci:v00001002d00005A1B* + ID_PRODUCT_FROM_DATABASE=RD890 PCI to PCI bridge (PCI express gpp port G) + +pci:v00001002d00005A1C* + ID_PRODUCT_FROM_DATABASE=RD890 PCI to PCI bridge (PCI express gpp port H) + +pci:v00001002d00005A1D* + ID_PRODUCT_FROM_DATABASE=RD890 PCI to PCI bridge (external gfx1 port A) + +pci:v00001002d00005A1E* + ID_PRODUCT_FROM_DATABASE=RD890 PCI to PCI bridge (external gfx1 port B) + +pci:v00001002d00005A1F* + ID_PRODUCT_FROM_DATABASE=RD890 PCI to PCI bridge (NB-SB link) + +pci:v00001002d00005A1Fsv000015D9sd0000A811* + ID_PRODUCT_FROM_DATABASE=H8DGU + +pci:v00001002d00005A20* + ID_PRODUCT_FROM_DATABASE=RD890S PCI Express bridge for GPP2 port 1 + +pci:v00001002d00005A23* + ID_PRODUCT_FROM_DATABASE=RD990 I/O Memory Management Unit (IOMMU) + +pci:v00001002d00005A33* + ID_PRODUCT_FROM_DATABASE=Radeon Xpress 200 Host Bridge + +pci:v00001002d00005A34* + ID_PRODUCT_FROM_DATABASE=RS480 PCI-X Root Port + +pci:v00001002d00005A36* + ID_PRODUCT_FROM_DATABASE=RS480 PCI Bridge + +pci:v00001002d00005A37* + ID_PRODUCT_FROM_DATABASE=RS480 PCI Bridge + +pci:v00001002d00005A38* + ID_PRODUCT_FROM_DATABASE=RS480 PCI Bridge + +pci:v00001002d00005A39* + ID_PRODUCT_FROM_DATABASE=RS480 PCI Bridge + +pci:v00001002d00005A3F* + ID_PRODUCT_FROM_DATABASE=RS480 PCI Bridge + +pci:v00001002d00005A3Fsv00001462sd00007217* + ID_PRODUCT_FROM_DATABASE=Aspire L250 + +pci:v00001002d00005A41* + ID_PRODUCT_FROM_DATABASE=RS400 [Radeon Xpress 200] + +pci:v00001002d00005A42* + ID_PRODUCT_FROM_DATABASE=RS400 [Radeon Xpress 200M] + +pci:v00001002d00005A43* + ID_PRODUCT_FROM_DATABASE=Radeon Xpress Series (RS400) + +pci:v00001002d00005A61* + ID_PRODUCT_FROM_DATABASE=RC410 [Radeon Xpress 200] + +pci:v00001002d00005A62* + ID_PRODUCT_FROM_DATABASE=RC410 [Radeon Xpress 200M] + +pci:v00001002d00005A63* + ID_PRODUCT_FROM_DATABASE=Radeon Xpress Series (RC410) + +pci:v00001002d00005B60* + ID_PRODUCT_FROM_DATABASE=RV370 5B60 [Radeon X300 (PCIE)] + +pci:v00001002d00005B60sv00001043sd0000002A* + ID_PRODUCT_FROM_DATABASE=Extreme AX300SE-X + +pci:v00001002d00005B60sv00001043sd0000032E* + ID_PRODUCT_FROM_DATABASE=Extreme AX300/TD + +pci:v00001002d00005B60sv00001458sd00002102* + ID_PRODUCT_FROM_DATABASE=GV-RX30S128D (X300SE) + +pci:v00001002d00005B60sv00001462sd00000400* + ID_PRODUCT_FROM_DATABASE=RX300SE-TD128E (MS-8940 REV:200) + +pci:v00001002d00005B60sv00001462sd00000402* + ID_PRODUCT_FROM_DATABASE=RX300SE-TD128E (MS-8940) + +pci:v00001002d00005B60sv0000174Bsd00000500* + ID_PRODUCT_FROM_DATABASE=Radeon X300 (PCIE) + +pci:v00001002d00005B60sv0000196Dsd00001086* + ID_PRODUCT_FROM_DATABASE=X300SE HM + +pci:v00001002d00005B62* + ID_PRODUCT_FROM_DATABASE=RV380 [Radeon X600 (PCIE)] + +pci:v00001002d00005B63* + ID_PRODUCT_FROM_DATABASE=RV370 [Radeon X550] + +pci:v00001002d00005B64* + ID_PRODUCT_FROM_DATABASE=RV370 5B64 [FireGL V3100 (PCIE)] + +pci:v00001002d00005B65* + ID_PRODUCT_FROM_DATABASE=RV370 5B65 [FireGL D1100 (PCIE)] + +pci:v00001002d00005B66* + ID_PRODUCT_FROM_DATABASE=RV370X + +pci:v00001002d00005B70* + ID_PRODUCT_FROM_DATABASE=RV370 [Radeon X300SE] + +pci:v00001002d00005B70sv00001462sd00000403* + ID_PRODUCT_FROM_DATABASE=RX300SE-TD128E (MS-8940) (secondary display) + +pci:v00001002d00005B70sv0000174Bsd00000501* + ID_PRODUCT_FROM_DATABASE=Radeon X300SE + +pci:v00001002d00005B70sv0000196Dsd00001087* + ID_PRODUCT_FROM_DATABASE=X300SE HM + +pci:v00001002d00005B72* + ID_PRODUCT_FROM_DATABASE=RV380 [Radeon X600] + +pci:v00001002d00005B73* + ID_PRODUCT_FROM_DATABASE=RV370 secondary [Sapphire X550 Silent] + +pci:v00001002d00005B74* + ID_PRODUCT_FROM_DATABASE=RV370 5B64 [FireGL V3100 (PCIE)] (Secondary) + +pci:v00001002d00005B75* + ID_PRODUCT_FROM_DATABASE=RV370 5B75 [FireGL D1100 (PCIE)] (Secondary) + +pci:v00001002d00005C61* + ID_PRODUCT_FROM_DATABASE=M9+ 5C61 [Radeon Mobility 9200 (AGP)] + +pci:v00001002d00005C63* + ID_PRODUCT_FROM_DATABASE=M9+ 5C63 [Radeon Mobility 9200 (AGP)] + +pci:v00001002d00005C63sv00001002sd00005C63* + ID_PRODUCT_FROM_DATABASE=Apple iBook G4 2004 + +pci:v00001002d00005C63sv0000144Dsd0000C00C* + ID_PRODUCT_FROM_DATABASE=P30 notebook + +pci:v00001002d00005D44* + ID_PRODUCT_FROM_DATABASE=RV280 [Radeon 9200 SE] (Secondary) + +pci:v00001002d00005D44sv00001458sd00004019* + ID_PRODUCT_FROM_DATABASE=Radeon 9200 SE (Secondary) + +pci:v00001002d00005D44sv00001458sd00004032* + ID_PRODUCT_FROM_DATABASE=Radeon 9200 SE 128MB + +pci:v00001002d00005D44sv0000147Bsd00006190* + ID_PRODUCT_FROM_DATABASE=R9200SE-DT (Secondary) + +pci:v00001002d00005D44sv0000174Bsd00007C12* + ID_PRODUCT_FROM_DATABASE=Sapphire Radeon 9200 SE (Secondary) + +pci:v00001002d00005D44sv00001787sd00005965* + ID_PRODUCT_FROM_DATABASE=Excalibur 9200SE VIVO 128M (Secondary) + +pci:v00001002d00005D44sv000017AFsd00002013* + ID_PRODUCT_FROM_DATABASE=Radeon 9200 SE Excalibur (Secondary) + +pci:v00001002d00005D44sv000018BCsd00000171* + ID_PRODUCT_FROM_DATABASE=Radeon 9200 SE 128MB Game Buster (Secondary) + +pci:v00001002d00005D44sv000018BCsd00000172* + ID_PRODUCT_FROM_DATABASE=GC-R9200L(SE)-C3H [Radeon 9200 Game Buster] + +pci:v00001002d00005D45* + ID_PRODUCT_FROM_DATABASE=RV280 [FireMV 2200 PCI] (secondary) + +pci:v00001002d00005D48* + ID_PRODUCT_FROM_DATABASE=M28 [Radeon Mobility X800XT] + +pci:v00001002d00005D49* + ID_PRODUCT_FROM_DATABASE=M28 [Mobility FireGL V5100] + +pci:v00001002d00005D4A* + ID_PRODUCT_FROM_DATABASE=Mobility Radeon X800 + +pci:v00001002d00005D4C* + ID_PRODUCT_FROM_DATABASE=Radeon X850 (PCIE) + +pci:v00001002d00005D4D* + ID_PRODUCT_FROM_DATABASE=R480 [Radeon X850XT Platinum (PCIE)] + +pci:v00001002d00005D4E* + ID_PRODUCT_FROM_DATABASE=Radeon X850 SE (R480) (PCIE) + +pci:v00001002d00005D4F* + ID_PRODUCT_FROM_DATABASE=R480 [Radeon X800 GTO (PCIE)] + +pci:v00001002d00005D50* + ID_PRODUCT_FROM_DATABASE=R480 [FireGL V7200 (PCIE)] + +pci:v00001002d00005D51* + ID_PRODUCT_FROM_DATABASE=R480 GL 12P + +pci:v00001002d00005D52* + ID_PRODUCT_FROM_DATABASE=R480 [Radeon X850XT (PCIE)] (Primary) + +pci:v00001002d00005D52sv00001002sd00000B12* + ID_PRODUCT_FROM_DATABASE=PowerColor X850XT PCIe (Primary) + +pci:v00001002d00005D52sv00001002sd00000B13* + ID_PRODUCT_FROM_DATABASE=PowerColor X850XT PCIe (Secondary) + +pci:v00001002d00005D57* + ID_PRODUCT_FROM_DATABASE=R423 5F57 [Radeon X800XT (PCIE)] + +pci:v00001002d00005D6D* + ID_PRODUCT_FROM_DATABASE=R480 [Radeon X850XT Platinum (PCIE)] (Secondary) + +pci:v00001002d00005D6F* + ID_PRODUCT_FROM_DATABASE=R480 [Radeon X800 GTO (PCIE)] (Secondary) + +pci:v00001002d00005D72* + ID_PRODUCT_FROM_DATABASE=R480 [Radeon X850XT (PCIE)] (Secondary) + +pci:v00001002d00005D77* + ID_PRODUCT_FROM_DATABASE=R423 5F57 [Radeon X800XT (PCIE)] (Secondary) + +pci:v00001002d00005E48* + ID_PRODUCT_FROM_DATABASE=RV410 [FireGL V5000] + +pci:v00001002d00005E49* + ID_PRODUCT_FROM_DATABASE=RV410 [FireGL V3300] + +pci:v00001002d00005E4A* + ID_PRODUCT_FROM_DATABASE=RV410 [Radeon X700XT] + +pci:v00001002d00005E4B* + ID_PRODUCT_FROM_DATABASE=RV410 [Radeon X700 Pro (PCIE)] + +pci:v00001002d00005E4C* + ID_PRODUCT_FROM_DATABASE=RV410 [Radeon X700SE] + +pci:v00001002d00005E4D* + ID_PRODUCT_FROM_DATABASE=RV410 [Radeon X700 (PCIE)] + +pci:v00001002d00005E4Dsv0000148Csd00002116* + ID_PRODUCT_FROM_DATABASE=PowerColor Bravo X700 + +pci:v00001002d00005E4F* + ID_PRODUCT_FROM_DATABASE=RV410 [Radeon X700] + +pci:v00001002d00005E6B* + ID_PRODUCT_FROM_DATABASE=RV410 [Radeon X700 Pro (PCIE)] (Secondary) + +pci:v00001002d00005E6D* + ID_PRODUCT_FROM_DATABASE=RV410 [Radeon X700 (PCIE)] (Secondary) + +pci:v00001002d00005E6Dsv0000148Csd00002117* + ID_PRODUCT_FROM_DATABASE=PowerColor Bravo X700 + +pci:v00001002d00005F57* + ID_PRODUCT_FROM_DATABASE=R423 [Radeon X800XT (PCIE)] + +pci:v00001002d00006600* + ID_PRODUCT_FROM_DATABASE=Mars [Radeon HD 8600/8700M Series] + +pci:v00001002d00006601* + ID_PRODUCT_FROM_DATABASE=Mars [Radeon HD 8500/8700M Series] + +pci:v00001002d00006606* + ID_PRODUCT_FROM_DATABASE=Mars [Radeon HD 8790M] + +pci:v00001002d00006610* + ID_PRODUCT_FROM_DATABASE=Oland [Radeon HD 8600 Series] + +pci:v00001002d00006611* + ID_PRODUCT_FROM_DATABASE=Oland [Radeon HD 8500 Series] + +pci:v00001002d00006704* + ID_PRODUCT_FROM_DATABASE=Cayman PRO GL [FirePro V7900] + +pci:v00001002d00006707* + ID_PRODUCT_FROM_DATABASE=Cayman LE GL [FirePro V5900] + +pci:v00001002d00006718* + ID_PRODUCT_FROM_DATABASE=Cayman XT [Radeon HD 6970] + +pci:v00001002d00006719* + ID_PRODUCT_FROM_DATABASE=Cayman PRO [Radeon HD 6950] + +pci:v00001002d0000671D* + ID_PRODUCT_FROM_DATABASE=Antilles [AMD Radeon HD 6990] + +pci:v00001002d0000671F* + ID_PRODUCT_FROM_DATABASE=Cayman [Radeon HD 6900 Series] + +pci:v00001002d00006720* + ID_PRODUCT_FROM_DATABASE=Blackcomb [Radeon HD 6900M series] + +pci:v00001002d00006738* + ID_PRODUCT_FROM_DATABASE=Barts XT [Radeon HD 6800 Series] + +pci:v00001002d00006739* + ID_PRODUCT_FROM_DATABASE=Barts PRO [Radeon HD 6800 Series] + +pci:v00001002d00006739sv00001043sd000003B4* + ID_PRODUCT_FROM_DATABASE=EAH6850 [Radeon HD 6850] + +pci:v00001002d0000673E* + ID_PRODUCT_FROM_DATABASE=Barts LE [AMD Radeon HD 6700 Series] + +pci:v00001002d00006740* + ID_PRODUCT_FROM_DATABASE=Whistler XT [AMD Radeon HD 6700M Series] + +pci:v00001002d00006741* + ID_PRODUCT_FROM_DATABASE=Whistler [AMD Radeon HD 6600M Series] + +pci:v00001002d00006741sv0000106Bsd000000E2* + ID_PRODUCT_FROM_DATABASE=MacBookPro8,2 [Core i7, 15", Late 2011] + +pci:v00001002d00006742* + ID_PRODUCT_FROM_DATABASE=Whistler LE [AMD Radeon HD 6625M Graphics] + +pci:v00001002d00006743* + ID_PRODUCT_FROM_DATABASE=Whistler [Radeon E6760] + +pci:v00001002d00006749* + ID_PRODUCT_FROM_DATABASE=Turks [FirePro V4900] + +pci:v00001002d0000674A* + ID_PRODUCT_FROM_DATABASE=Turks [AMD FirePro V3900] + +pci:v00001002d00006750* + ID_PRODUCT_FROM_DATABASE=Turks [AMD Radeon HD 6570] + +pci:v00001002d00006751* + ID_PRODUCT_FROM_DATABASE=Turks [Radeon HD 7600A Series] + +pci:v00001002d00006758* + ID_PRODUCT_FROM_DATABASE=Turks [Radeon HD 6670] + +pci:v00001002d00006759* + ID_PRODUCT_FROM_DATABASE=Turks [Radeon HD 6570] + +pci:v00001002d0000675D* + ID_PRODUCT_FROM_DATABASE=Turks [Radeon HD 7500 Series] + +pci:v00001002d00006760* + ID_PRODUCT_FROM_DATABASE=Caicos [Radeon HD 6400M/7400M Series] + +pci:v00001002d00006760sv00001028sd000004CC* + ID_PRODUCT_FROM_DATABASE=Vostro 3350 + +pci:v00001002d00006761* + ID_PRODUCT_FROM_DATABASE=Seymour LP [Radeon HD 6430M] + +pci:v00001002d00006763* + ID_PRODUCT_FROM_DATABASE=Seymour [Radeon E6460] + +pci:v00001002d00006770* + ID_PRODUCT_FROM_DATABASE=Caicos [Radeon HD 6400 Series] + +pci:v00001002d00006772* + ID_PRODUCT_FROM_DATABASE=Caicos [Radeon HD 7400A Series] + +pci:v00001002d00006778* + ID_PRODUCT_FROM_DATABASE=Caicos [Radeon HD 7000 Series] + +pci:v00001002d00006779* + ID_PRODUCT_FROM_DATABASE=Caicos [Radeon HD 6450] + +pci:v00001002d00006779sv0000174Bsd0000E164* + ID_PRODUCT_FROM_DATABASE=Sapphire HD 6450 1GB DDR3 + +pci:v00001002d0000677B* + ID_PRODUCT_FROM_DATABASE=Caicos [Radeon HD 7400 Series] + +pci:v00001002d00006798* + ID_PRODUCT_FROM_DATABASE=Tahiti XT [Radeon HD 7970] + +pci:v00001002d00006799* + ID_PRODUCT_FROM_DATABASE=New Zealand [Radeon HD 7990] + +pci:v00001002d0000679A* + ID_PRODUCT_FROM_DATABASE=Tahiti PRO [Radeon HD 7950] + +pci:v00001002d0000679E* + ID_PRODUCT_FROM_DATABASE=Tahiti LE [Radeon HD 7800 Series] + +pci:v00001002d00006800* + ID_PRODUCT_FROM_DATABASE=Wimbledon XT [Radeon HD 7970M] + +pci:v00001002d00006818* + ID_PRODUCT_FROM_DATABASE=Pitcairn [Radeon HD 7800] + +pci:v00001002d00006819* + ID_PRODUCT_FROM_DATABASE=Pitcairn PRO [Radeon HD 7800] + +pci:v00001002d00006820* + ID_PRODUCT_FROM_DATABASE=Radeon HD 8800M Series + +pci:v00001002d00006821* + ID_PRODUCT_FROM_DATABASE=Radeon HD 8800M Series + +pci:v00001002d00006823* + ID_PRODUCT_FROM_DATABASE=Radeon HD 8800M Series + +pci:v00001002d00006825* + ID_PRODUCT_FROM_DATABASE=Cape Verde [Radeon HD 7800M Series] + +pci:v00001002d0000682B* + ID_PRODUCT_FROM_DATABASE=Radeon HD 8800M Series + +pci:v00001002d0000682F* + ID_PRODUCT_FROM_DATABASE=Cape Verde [Radeon HD 7700M Series] + +pci:v00001002d0000683B* + ID_PRODUCT_FROM_DATABASE=Cape Verde [Radeon HD 7700 Series] + +pci:v00001002d0000683D* + ID_PRODUCT_FROM_DATABASE=Cape Verde [Radeon HD 7700 Series] + +pci:v00001002d0000683F* + ID_PRODUCT_FROM_DATABASE=Cape Verde PRO [Radeon HD 7700 Series] + +pci:v00001002d00006840* + ID_PRODUCT_FROM_DATABASE=Thames XT/GL [Radeon HD 7600M Series] + +pci:v00001002d00006841* + ID_PRODUCT_FROM_DATABASE=Thames [Radeon 7500M/7600M Series] + +pci:v00001002d00006842* + ID_PRODUCT_FROM_DATABASE=Thames LE [Radeon HD 7000M Series] + +pci:v00001002d00006843* + ID_PRODUCT_FROM_DATABASE=Thames [Radeon HD 7670M] + +pci:v00001002d00006850* + ID_PRODUCT_FROM_DATABASE=Lombok GL AIO [Radeon HD 7570] + +pci:v00001002d00006858* + ID_PRODUCT_FROM_DATABASE=Lombok [Radeon HD 7400 series] + +pci:v00001002d00006888* + ID_PRODUCT_FROM_DATABASE=Cypress [FirePro 3D V8800] + +pci:v00001002d00006889* + ID_PRODUCT_FROM_DATABASE=Cypress [FirePro V7800] + +pci:v00001002d0000688A* + ID_PRODUCT_FROM_DATABASE=Cypress XT [FirePro 3D V9800] + +pci:v00001002d0000688C* + ID_PRODUCT_FROM_DATABASE=Cypress [AMD FireStream 9370] + +pci:v00001002d0000688D* + ID_PRODUCT_FROM_DATABASE=Cypress [AMD FireStream 9350] + +pci:v00001002d00006898* + ID_PRODUCT_FROM_DATABASE=Cypress XT [Radeon HD 5870] + +pci:v00001002d00006898sv00001462sd00008032* + ID_PRODUCT_FROM_DATABASE=R5870 PM2D1G + +pci:v00001002d00006899* + ID_PRODUCT_FROM_DATABASE=Cypress PRO [Radeon HD 5800 Series] + +pci:v00001002d00006899sv00001043sd00000330* + ID_PRODUCT_FROM_DATABASE=EAH5850 [Radeon HD5850] + +pci:v00001002d0000689B* + ID_PRODUCT_FROM_DATABASE=Cypress [Radeon HD 6800 Series] + +pci:v00001002d0000689C* + ID_PRODUCT_FROM_DATABASE=Hemlock [Radeon HD 5900 Series] + +pci:v00001002d0000689E* + ID_PRODUCT_FROM_DATABASE=Cypress LE [Radeon HD 5800 Series] + +pci:v00001002d000068A0* + ID_PRODUCT_FROM_DATABASE=Broadway XT [Mobility Radeon HD 5800 Series] + +pci:v00001002d000068A0sv0000103Csd00001520* + ID_PRODUCT_FROM_DATABASE=Broadway XT [FirePro M7820] + +pci:v00001002d000068A1* + ID_PRODUCT_FROM_DATABASE=Broadway PRO [Mobility Radeon HD 5800 Series] + +pci:v00001002d000068A8* + ID_PRODUCT_FROM_DATABASE=Broadway [ATI Mobility Radeon HD 6800 Series] + +pci:v00001002d000068A9* + ID_PRODUCT_FROM_DATABASE=Juniper XT [FirePro 3D V5800] + +pci:v00001002d000068B8* + ID_PRODUCT_FROM_DATABASE=Juniper [Radeon HD 5700 Series] + +pci:v00001002d000068B8sv0000106Bsd000000CF* + ID_PRODUCT_FROM_DATABASE=MacPro5,1 [Mac Pro 2.8GHz DDR3] + +pci:v00001002d000068B9* + ID_PRODUCT_FROM_DATABASE=Juniper [Radeon HD 5600/5700] + +pci:v00001002d000068BA* + ID_PRODUCT_FROM_DATABASE=Juniper XT [AMD Radeon HD 6000 Series] + +pci:v00001002d000068BE* + ID_PRODUCT_FROM_DATABASE=Juniper [Radeon HD 5700 Series] + +pci:v00001002d000068BF* + ID_PRODUCT_FROM_DATABASE=Juniper LE [Radeon HD 6700 Series] + +pci:v00001002d000068C0* + ID_PRODUCT_FROM_DATABASE=Madison [Mobility Radeon HD 5000 Series] + +pci:v00001002d000068C0sv0000103Csd00001521* + ID_PRODUCT_FROM_DATABASE=Madison XT [FirePro M5800] + +pci:v00001002d000068C1* + ID_PRODUCT_FROM_DATABASE=Madison [Radeon HD 5000M Series] + +pci:v00001002d000068C1sv00001025sd0000033D* + ID_PRODUCT_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d000068C1sv00001025sd00000347* + ID_PRODUCT_FROM_DATABASE=Aspire 7740G + +pci:v00001002d000068C1sv0000103Csd00001521* + ID_PRODUCT_FROM_DATABASE=Madison Pro [FirePro M5800] + +pci:v00001002d000068C7* + ID_PRODUCT_FROM_DATABASE=Pinewood [Radeon HD 5570] + +pci:v00001002d000068C8* + ID_PRODUCT_FROM_DATABASE=FirePro V4800 + +pci:v00001002d000068D8* + ID_PRODUCT_FROM_DATABASE=Redwood [Radeon HD 5670] + +pci:v00001002d000068D9* + ID_PRODUCT_FROM_DATABASE=Redwood PRO [Radeon HD 5500 Series] + +pci:v00001002d000068DA* + ID_PRODUCT_FROM_DATABASE=Redwood PRO [Radeon HD 5500 Series] + +pci:v00001002d000068E0* + ID_PRODUCT_FROM_DATABASE=Manhattan [Mobility Radeon HD 5400 Series] + +pci:v00001002d000068E0sv0000103Csd00001486* + ID_PRODUCT_FROM_DATABASE=TouchSmart tm2-2050er discrete GPU (Mobility Radeon HD 5450) + +pci:v00001002d000068E1* + ID_PRODUCT_FROM_DATABASE=Manhattan [Mobility Radeon HD 5430 Series] + +pci:v00001002d000068E4* + ID_PRODUCT_FROM_DATABASE=Robson CE [AMD Radeon HD 6300 Series] + +pci:v00001002d000068E5* + ID_PRODUCT_FROM_DATABASE=Robson LE [AMD Radeon HD 6300M Series] + +pci:v00001002d000068F1* + ID_PRODUCT_FROM_DATABASE=Cedar [FirePro 2460] + +pci:v00001002d000068F2* + ID_PRODUCT_FROM_DATABASE=Cedar [FirePro 2270] + +pci:v00001002d000068F9* + ID_PRODUCT_FROM_DATABASE=Cedar PRO [Radeon HD 5450/6350] + +pci:v00001002d000068F9sv00001028sd0000010E* + ID_PRODUCT_FROM_DATABASE=XPS 8300 + +pci:v00001002d000068FA* + ID_PRODUCT_FROM_DATABASE=EG Cedar [Radeon HD 7300 Series] + +pci:v00001002d0000700F* + ID_PRODUCT_FROM_DATABASE=PCI Bridge [IGP 320M] + +pci:v00001002d00007010* + ID_PRODUCT_FROM_DATABASE=PCI Bridge [IGP 340M] + +pci:v00001002d00007100* + ID_PRODUCT_FROM_DATABASE=R520 [Radeon X1800] + +pci:v00001002d00007102* + ID_PRODUCT_FROM_DATABASE=M58 [Radeon Mobility X1800] + +pci:v00001002d00007103* + ID_PRODUCT_FROM_DATABASE=M58 [Mobility FireGL V7200] + +pci:v00001002d00007104* + ID_PRODUCT_FROM_DATABASE=R520GL [FireGL V7200] (Primary) + +pci:v00001002d00007105* + ID_PRODUCT_FROM_DATABASE=R520 [FireGL] + +pci:v00001002d00007106* + ID_PRODUCT_FROM_DATABASE=M58 [Mobility FireGL V7100] + +pci:v00001002d00007108* + ID_PRODUCT_FROM_DATABASE=M58 [Radeon Mobility X1800] + +pci:v00001002d00007109* + ID_PRODUCT_FROM_DATABASE=R520 [Radeon X1800] + +pci:v00001002d00007109sv00001002sd00000322* + ID_PRODUCT_FROM_DATABASE=All-in-Wonder X1800XL + +pci:v00001002d00007109sv00001002sd00000D02* + ID_PRODUCT_FROM_DATABASE=Radeon X1800 CrossFire Edition + +pci:v00001002d0000710A* + ID_PRODUCT_FROM_DATABASE=R520 [Radeon X1800] + +pci:v00001002d0000710B* + ID_PRODUCT_FROM_DATABASE=R520 [Radeon X1800] + +pci:v00001002d0000710C* + ID_PRODUCT_FROM_DATABASE=R520 [Radeon X1800] + +pci:v00001002d00007120* + ID_PRODUCT_FROM_DATABASE=R520 [Radeon X1800] (Secondary) + +pci:v00001002d00007124* + ID_PRODUCT_FROM_DATABASE=R520GL [FireGL V7200] (Secondary) + +pci:v00001002d00007129* + ID_PRODUCT_FROM_DATABASE=R520 [Radeon X1800] (Secondary) + +pci:v00001002d00007129sv00001002sd00000323* + ID_PRODUCT_FROM_DATABASE=All-in-Wonder X1800XL (Secondary) + +pci:v00001002d00007129sv00001002sd00000D03* + ID_PRODUCT_FROM_DATABASE=Radeon X1800 CrossFire Edition (Secondary) + +pci:v00001002d00007140* + ID_PRODUCT_FROM_DATABASE=RV515 [Radeon X1600] + +pci:v00001002d00007142* + ID_PRODUCT_FROM_DATABASE=RV515 PRO [Radeon X1300/X1550 Series] + +pci:v00001002d00007142sv00001002sd00000322* + ID_PRODUCT_FROM_DATABASE=All-in-Wonder 2006 PCI-E Edition + +pci:v00001002d00007142sv00001043sd00000142* + ID_PRODUCT_FROM_DATABASE=EAX1300PRO/TD/256M + +pci:v00001002d00007143* + ID_PRODUCT_FROM_DATABASE=RV505 [Radeon X1550 Series] + +pci:v00001002d00007145* + ID_PRODUCT_FROM_DATABASE=Radeon Mobility X1400 + +pci:v00001002d00007145sv000017AAsd00002006* + ID_PRODUCT_FROM_DATABASE=Thinkpad T60 model 2007 + +pci:v00001002d00007146* + ID_PRODUCT_FROM_DATABASE=RV515 [Radeon X1300] + +pci:v00001002d00007146sv00001002sd00000322* + ID_PRODUCT_FROM_DATABASE=All-in-Wonder 2006 PCI-E Edition + +pci:v00001002d00007146sv00001545sd00001996* + ID_PRODUCT_FROM_DATABASE=Radeon X1300 512MB PCI-e + +pci:v00001002d00007147* + ID_PRODUCT_FROM_DATABASE=RV505 [Radeon X1550 64-bit] + +pci:v00001002d00007149* + ID_PRODUCT_FROM_DATABASE=M52 [Mobility Radeon X1300] + +pci:v00001002d0000714A* + ID_PRODUCT_FROM_DATABASE=M52 [Mobility Radeon X1300] + +pci:v00001002d0000714B* + ID_PRODUCT_FROM_DATABASE=M52 [Mobility Radeon X1300] + +pci:v00001002d0000714C* + ID_PRODUCT_FROM_DATABASE=M52 [Mobility Radeon X1300] + +pci:v00001002d0000714D* + ID_PRODUCT_FROM_DATABASE=RV515 [Radeon X1300] + +pci:v00001002d0000714E* + ID_PRODUCT_FROM_DATABASE=RV515LE [Radeon X1300] + +pci:v00001002d00007152* + ID_PRODUCT_FROM_DATABASE=RV515GL [FireGL V3300] (Primary) + +pci:v00001002d00007153* + ID_PRODUCT_FROM_DATABASE=RV515GL [FireGL V3350] + +pci:v00001002d0000715E* + ID_PRODUCT_FROM_DATABASE=RV515 [Radeon X1300] + +pci:v00001002d0000715F* + ID_PRODUCT_FROM_DATABASE=RV505 CE [Radeon X1550 64-bit] + +pci:v00001002d00007162* + ID_PRODUCT_FROM_DATABASE=RV515 PRO [Radeon X1300/X1550 Series] (Secondary) + +pci:v00001002d00007162sv00001002sd00000323* + ID_PRODUCT_FROM_DATABASE=All-in-Wonder 2006 PCI-E Edition (Secondary) + +pci:v00001002d00007163* + ID_PRODUCT_FROM_DATABASE=RV505 [Radeon X1550 Series] (Secondary) + +pci:v00001002d00007166* + ID_PRODUCT_FROM_DATABASE=RV515 [Radeon X1300] (Secondary) + +pci:v00001002d00007166sv00001002sd00000323* + ID_PRODUCT_FROM_DATABASE=All-in-Wonder 2006 PCI-E Edition (Secondary) + +pci:v00001002d00007166sv00001545sd00001997* + ID_PRODUCT_FROM_DATABASE=Radeon X1300 512MB PCI-e (Secondary) + +pci:v00001002d00007167* + ID_PRODUCT_FROM_DATABASE=RV515 [Radeon X1550 64-bit] (Secondary) + +pci:v00001002d0000716E* + ID_PRODUCT_FROM_DATABASE=RV515LE [Radeon X1300] Secondary + +pci:v00001002d00007172* + ID_PRODUCT_FROM_DATABASE=RV515GL [FireGL V3300] (Secondary) + +pci:v00001002d00007173* + ID_PRODUCT_FROM_DATABASE=RV515GL [FireGL V3350] (Secondary) + +pci:v00001002d00007180* + ID_PRODUCT_FROM_DATABASE=RV516 [Radeon X1300/X1550 Series] + +pci:v00001002d00007181* + ID_PRODUCT_FROM_DATABASE=RV516 XT Radeon X1600 Series (Primary) + +pci:v00001002d00007183* + ID_PRODUCT_FROM_DATABASE=RV516 [Radeon X1300/X1550 Series] + +pci:v00001002d00007186* + ID_PRODUCT_FROM_DATABASE=RV515 [Radeon Mobility X1450] + +pci:v00001002d00007187* + ID_PRODUCT_FROM_DATABASE=RV516 [Radeon X1300/X1550 Series] + +pci:v00001002d00007188* + ID_PRODUCT_FROM_DATABASE=M64-S [Mobility Radeon X2300] + +pci:v00001002d00007188sv0000103Csd000030C1* + ID_PRODUCT_FROM_DATABASE=6910p + +pci:v00001002d0000718A* + ID_PRODUCT_FROM_DATABASE=Mobility Radeon X2300 + +pci:v00001002d0000718C* + ID_PRODUCT_FROM_DATABASE=M62CSP64 [Mobility Radeon X1350] + +pci:v00001002d0000718D* + ID_PRODUCT_FROM_DATABASE=M64CSP128 [Mobility Radeon X1450] + +pci:v00001002d00007193* + ID_PRODUCT_FROM_DATABASE=RV516 [Radeon X1550 Series] + +pci:v00001002d00007196* + ID_PRODUCT_FROM_DATABASE=RV516 [Mobility Radeon X1350] + +pci:v00001002d0000719B* + ID_PRODUCT_FROM_DATABASE=FireMV 2250 + +pci:v00001002d0000719F* + ID_PRODUCT_FROM_DATABASE=RV516LE [Radeon X1550 64-bit] + +pci:v00001002d000071A0* + ID_PRODUCT_FROM_DATABASE=RV516 [Radeon X1300/X1550 Series] (Secondary) + +pci:v00001002d000071A1* + ID_PRODUCT_FROM_DATABASE=RV516 XT Radeon X1600 Series (Secondary) + +pci:v00001002d000071A3* + ID_PRODUCT_FROM_DATABASE=RV516 [Radeon X1300 Pro] (Secondary) + +pci:v00001002d000071A7* + ID_PRODUCT_FROM_DATABASE=RV516 [Radeon X1300/X1550 Series] (Secondary) + +pci:v00001002d000071BB* + ID_PRODUCT_FROM_DATABASE=FireMV 2250 (Secondary) + +pci:v00001002d000071C0* + ID_PRODUCT_FROM_DATABASE=RV530 [Radeon X1600] + +pci:v00001002d000071C1* + ID_PRODUCT_FROM_DATABASE=Radeon X1650 Pro + +pci:v00001002d000071C2* + ID_PRODUCT_FROM_DATABASE=RV530 [Radeon X1600] + +pci:v00001002d000071C4* + ID_PRODUCT_FROM_DATABASE=M56GL [Mobility FireGL V5200] + +pci:v00001002d000071C4sv000017AAsd00002007* + ID_PRODUCT_FROM_DATABASE=ThinkPad T60p + +pci:v00001002d000071C5* + ID_PRODUCT_FROM_DATABASE=M56P [Radeon Mobility X1600] + +pci:v00001002d000071C5sv0000103Csd0000309F* + ID_PRODUCT_FROM_DATABASE=Compaq nx9420 Notebook + +pci:v00001002d000071C5sv0000103Csd000030A3* + ID_PRODUCT_FROM_DATABASE=Compaq NW8440 + +pci:v00001002d000071C5sv00001043sd000010B2* + ID_PRODUCT_FROM_DATABASE=A6J-Q008 + +pci:v00001002d000071C5sv0000106Bsd00000080* + ID_PRODUCT_FROM_DATABASE=MacBook Pro + +pci:v00001002d000071C6* + ID_PRODUCT_FROM_DATABASE=RV530LE [Radeon X1600/X1650 PRO] + +pci:v00001002d000071C7* + ID_PRODUCT_FROM_DATABASE=RV535 [Radeon X1650 Series] + +pci:v00001002d000071CE* + ID_PRODUCT_FROM_DATABASE=RV530LE [Radeon X1600] + +pci:v00001002d000071D2* + ID_PRODUCT_FROM_DATABASE=RV530GL [FireGL V3400] + +pci:v00001002d000071D4* + ID_PRODUCT_FROM_DATABASE=M66GL [ATI Mobility FireGL V5250] + +pci:v00001002d000071D5* + ID_PRODUCT_FROM_DATABASE=M66-P [Mobility Radeon X1700] + +pci:v00001002d000071D6* + ID_PRODUCT_FROM_DATABASE=M66-XT [Mobility Radeon X1700] + +pci:v00001002d000071DE* + ID_PRODUCT_FROM_DATABASE=RV530LE [Radeon X1600] + +pci:v00001002d000071E0* + ID_PRODUCT_FROM_DATABASE=RV530 [Radeon X1600] (Secondary) + +pci:v00001002d000071E1* + ID_PRODUCT_FROM_DATABASE=Radeon X1650 Pro (Secondary) + +pci:v00001002d000071E2* + ID_PRODUCT_FROM_DATABASE=RV530 [Radeon X1600] (Secondary) + +pci:v00001002d000071E6* + ID_PRODUCT_FROM_DATABASE=RV530LE [Radeon X1650 PRO] (Secondary) + +pci:v00001002d000071E7* + ID_PRODUCT_FROM_DATABASE=RV535 [Radeon X1650 Series] + +pci:v00001002d000071F2* + ID_PRODUCT_FROM_DATABASE=RV530GL [FireGL V3400 (Secondary)] + +pci:v00001002d00007210* + ID_PRODUCT_FROM_DATABASE=M71 [Mobility Radeon X2100] + +pci:v00001002d00007211* + ID_PRODUCT_FROM_DATABASE=M71 [Mobility Radeon X2100] (Secondary) + +pci:v00001002d00007240* + ID_PRODUCT_FROM_DATABASE=R580 [Radeon X1900] + +pci:v00001002d00007241* + ID_PRODUCT_FROM_DATABASE=R580 [Radeon X1900] + +pci:v00001002d00007242* + ID_PRODUCT_FROM_DATABASE=R580 [Radeon X1900] + +pci:v00001002d00007243* + ID_PRODUCT_FROM_DATABASE=R580 [Radeon X1900] + +pci:v00001002d00007244* + ID_PRODUCT_FROM_DATABASE=R580 [Radeon X1900] + +pci:v00001002d00007245* + ID_PRODUCT_FROM_DATABASE=R580 [Radeon X1900] + +pci:v00001002d00007246* + ID_PRODUCT_FROM_DATABASE=R580 [Radeon X1900] + +pci:v00001002d00007247* + ID_PRODUCT_FROM_DATABASE=R580 [Radeon X1900] + +pci:v00001002d00007248* + ID_PRODUCT_FROM_DATABASE=R580 [Radeon X1900] + +pci:v00001002d00007249* + ID_PRODUCT_FROM_DATABASE=R580 [Radeon X1900 XT] (Primary) + +pci:v00001002d0000724A* + ID_PRODUCT_FROM_DATABASE=R580 [Radeon X1900] + +pci:v00001002d0000724B* + ID_PRODUCT_FROM_DATABASE=R580 [Radeon X1900] + +pci:v00001002d0000724Bsv00001002sd00000B12* + ID_PRODUCT_FROM_DATABASE=Radeon X1900 (Primary) + +pci:v00001002d0000724Bsv00001002sd00000B13* + ID_PRODUCT_FROM_DATABASE=Radeon X1900 (Secondary) + +pci:v00001002d0000724C* + ID_PRODUCT_FROM_DATABASE=R580 [Radeon X1900] + +pci:v00001002d0000724D* + ID_PRODUCT_FROM_DATABASE=R580 [Radeon X1900] + +pci:v00001002d0000724E* + ID_PRODUCT_FROM_DATABASE=R580 [AMD Stream Processor] + +pci:v00001002d00007269* + ID_PRODUCT_FROM_DATABASE=R580 [Radeon X1900 XT] (Secondary) + +pci:v00001002d0000726B* + ID_PRODUCT_FROM_DATABASE=R580 [Radeon X1900] + +pci:v00001002d0000726E* + ID_PRODUCT_FROM_DATABASE=R580 [AMD Stream Processor] (Secondary) + +pci:v00001002d00007280* + ID_PRODUCT_FROM_DATABASE=RV570 [Radeon X1950 Pro] + +pci:v00001002d00007288* + ID_PRODUCT_FROM_DATABASE=Radeon X1950 GT + +pci:v00001002d00007291* + ID_PRODUCT_FROM_DATABASE=Radeon X1650 XT (Primary) (PCIE) + +pci:v00001002d00007293* + ID_PRODUCT_FROM_DATABASE=Radeon X1650 Series + +pci:v00001002d000072A0* + ID_PRODUCT_FROM_DATABASE=RV570 [Radeon X1950 Pro] (secondary) + +pci:v00001002d000072A8* + ID_PRODUCT_FROM_DATABASE=Radeon X1950 GT (Secondary) + +pci:v00001002d000072B1* + ID_PRODUCT_FROM_DATABASE=Radeon X1650 XT (Secondary) (PCIE) + +pci:v00001002d000072B3* + ID_PRODUCT_FROM_DATABASE=Radeon X1650 Series (Secondary) + +pci:v00001002d00007833* + ID_PRODUCT_FROM_DATABASE=Radeon 9100 IGP Host Bridge + +pci:v00001002d00007834* + ID_PRODUCT_FROM_DATABASE=Radeon 9100 PRO IGP + +pci:v00001002d00007835* + ID_PRODUCT_FROM_DATABASE=Radeon Mobility 9200 IGP + +pci:v00001002d00007838* + ID_PRODUCT_FROM_DATABASE=Radeon 9100 IGP PCI/AGP Bridge + +pci:v00001002d00007910* + ID_PRODUCT_FROM_DATABASE=RS690 Host Bridge + +pci:v00001002d00007910sv00001179sd0000FF50* + ID_PRODUCT_FROM_DATABASE=Satellite P305D-S8995E + +pci:v00001002d00007910sv000017F2sd00005000* + ID_PRODUCT_FROM_DATABASE=KI690-AM2 Motherboard + +pci:v00001002d00007911* + ID_PRODUCT_FROM_DATABASE=RS690 Host Bridge + +pci:v00001002d00007912* + ID_PRODUCT_FROM_DATABASE=RS690 PCI to PCI Bridge (Internal gfx) + +pci:v00001002d00007913* + ID_PRODUCT_FROM_DATABASE=RS690 PCI to PCI Bridge (PCI Express Graphics Port 0) + +pci:v00001002d00007915* + ID_PRODUCT_FROM_DATABASE=RS690 PCI to PCI Bridge (PCI Express Port 1) + +pci:v00001002d00007916* + ID_PRODUCT_FROM_DATABASE=RS690 PCI to PCI Bridge (PCI Express Port 2) + +pci:v00001002d00007917* + ID_PRODUCT_FROM_DATABASE=RS690 PCI to PCI Bridge (PCI Express Port 3) + +pci:v00001002d00007917sv00001002sd00007910* + ID_PRODUCT_FROM_DATABASE=RS690 PCI to PCI Bridge + +pci:v00001002d00007919* + ID_PRODUCT_FROM_DATABASE=Radeon X1200 Series Audio Controller + +pci:v00001002d00007919sv00001179sd00007919* + ID_PRODUCT_FROM_DATABASE=Satellite P305D-S8995E + +pci:v00001002d00007919sv000017F2sd00005000* + ID_PRODUCT_FROM_DATABASE=KI690-AM2 Motherboard + +pci:v00001002d0000791E* + ID_PRODUCT_FROM_DATABASE=RS690 [Radeon X1200 Series] + +pci:v00001002d0000791Esv00001462sd00007327* + ID_PRODUCT_FROM_DATABASE=K9AG Neo2 + +pci:v00001002d0000791Esv000017F2sd00005000* + ID_PRODUCT_FROM_DATABASE=KI690-AM2 Motherboard + +pci:v00001002d0000791F* + ID_PRODUCT_FROM_DATABASE=RS690M [Radeon X1200 Series] + +pci:v00001002d0000791Fsv00001179sd0000FF50* + ID_PRODUCT_FROM_DATABASE=Satellite P305D-S8995E + +pci:v00001002d00007930* + ID_PRODUCT_FROM_DATABASE=RS600 Host Bridge + +pci:v00001002d00007932* + ID_PRODUCT_FROM_DATABASE=RS600 PCI to PCI Bridge (Internal gfx) + +pci:v00001002d00007933* + ID_PRODUCT_FROM_DATABASE=RS600 PCI to PCI Bridge (PCI Express Graphics Port 0) + +pci:v00001002d00007935* + ID_PRODUCT_FROM_DATABASE=RS600 PCI to PCI Bridge (PCI Express Port 1) + +pci:v00001002d00007936* + ID_PRODUCT_FROM_DATABASE=RS600 PCI to PCI Bridge (PCI Express Port 2) + +pci:v00001002d00007937* + ID_PRODUCT_FROM_DATABASE=RS690 PCI to PCI Bridge (PCI Express Port 3) + +pci:v00001002d0000793B* + ID_PRODUCT_FROM_DATABASE=RS600 HDMI Audio [Radeon Xpress 1250] + +pci:v00001002d0000793F* + ID_PRODUCT_FROM_DATABASE=RS600 [Radeon Xpress 1250] + +pci:v00001002d00007941* + ID_PRODUCT_FROM_DATABASE=RS600 [Radeon Xpress 1250] + +pci:v00001002d00007942* + ID_PRODUCT_FROM_DATABASE=RS600 [Radeon Xpress 1250] + +pci:v00001002d0000796E* + ID_PRODUCT_FROM_DATABASE=Radeon 2100 + +pci:v00001002d00007C37* + ID_PRODUCT_FROM_DATABASE=RV350 AQ [Radeon 9600 SE] + +pci:v00001002d00009400* + ID_PRODUCT_FROM_DATABASE=R600 [Radeon HD 2900 Series] + +pci:v00001002d00009400sv00001002sd00003000* + ID_PRODUCT_FROM_DATABASE=Sapphire Radeon HD 2900 XT + +pci:v00001002d00009400sv00001002sd00003142* + ID_PRODUCT_FROM_DATABASE=HIS Radeon HD 2900XT 512MB GDDR3 VIVO PCIe + +pci:v00001002d00009403* + ID_PRODUCT_FROM_DATABASE=R600 [Radeon HD 2900 PRO] + +pci:v00001002d0000940A* + ID_PRODUCT_FROM_DATABASE=R600GL [Fire GL V8650] + +pci:v00001002d0000940B* + ID_PRODUCT_FROM_DATABASE=R600GL [Fire GL V8600] + +pci:v00001002d0000940F* + ID_PRODUCT_FROM_DATABASE=R600 [FireGL V7600] + +pci:v00001002d00009440* + ID_PRODUCT_FROM_DATABASE=RV770 [Radeon HD 4870] + +pci:v00001002d00009441* + ID_PRODUCT_FROM_DATABASE=R700 [Radeon HD 4870 X2] + +pci:v00001002d00009442* + ID_PRODUCT_FROM_DATABASE=RV770 [Radeon HD 4850] + +pci:v00001002d00009442sv00001002sd00000502* + ID_PRODUCT_FROM_DATABASE=MSI R4850-T2D512 + +pci:v00001002d00009442sv0000174Bsd0000E810* + ID_PRODUCT_FROM_DATABASE=Sapphire HD 4850 512MB GDDR3 PCI-E Dual Slot Fansink + +pci:v00001002d00009443* + ID_PRODUCT_FROM_DATABASE=R700 [Radeon HD 4850] + +pci:v00001002d0000944A* + ID_PRODUCT_FROM_DATABASE=M98L [Mobility Radeon HD 4850] + +pci:v00001002d0000944C* + ID_PRODUCT_FROM_DATABASE=RV770 LE [Radeon HD 4800 Series] + +pci:v00001002d0000944E* + ID_PRODUCT_FROM_DATABASE=RV770 CE [Radeon HD 4710] + +pci:v00001002d00009450* + ID_PRODUCT_FROM_DATABASE=RV770 [FireStream 9270] + +pci:v00001002d00009452* + ID_PRODUCT_FROM_DATABASE=RV770 [FireStream 9250] + +pci:v00001002d0000945A* + ID_PRODUCT_FROM_DATABASE=M98 XT [Mobility Radeon HD 4870] + +pci:v00001002d00009460* + ID_PRODUCT_FROM_DATABASE=RV790 [Radeon HD 4890] + +pci:v00001002d00009462* + ID_PRODUCT_FROM_DATABASE=RV790LE [Radeon HD 4800 Series] + +pci:v00001002d00009480* + ID_PRODUCT_FROM_DATABASE=M96 [Mobility Radeon HD 4650] + +pci:v00001002d00009480sv0000103Csd00003628* + ID_PRODUCT_FROM_DATABASE=ATI Mobility Radeon HD 4650 [dv6-1190en] + +pci:v00001002d00009485* + ID_PRODUCT_FROM_DATABASE=RV740 Pro [Radeon HD 4770] + +pci:v00001002d00009488* + ID_PRODUCT_FROM_DATABASE=RV730 XT [Mobility Radeon HD 4670] + +pci:v00001002d00009489* + ID_PRODUCT_FROM_DATABASE=M96 XT [Mobility FireGL V5725] + +pci:v00001002d00009490* + ID_PRODUCT_FROM_DATABASE=RV730XT [Radeon HD 4670] + +pci:v00001002d00009490sv0000174Bsd0000E880* + ID_PRODUCT_FROM_DATABASE=Radeon HD 4670 512MB DDR3 + +pci:v00001002d00009491* + ID_PRODUCT_FROM_DATABASE=M96 CSP [ATI RADEON E4690] + +pci:v00001002d00009495* + ID_PRODUCT_FROM_DATABASE=RV730 Pro AGP [Radeon HD 4600 Series] + +pci:v00001002d00009495sv00001002sd00009495* + ID_PRODUCT_FROM_DATABASE=RV730 XT [PowerColor Radeon HD4670 AGP 1GB DDR] + +pci:v00001002d00009495sv00001458sd00000028* + ID_PRODUCT_FROM_DATABASE=HD4650 + +pci:v00001002d00009498* + ID_PRODUCT_FROM_DATABASE=RV730 PRO [Radeon HD 4650] + +pci:v00001002d0000949E* + ID_PRODUCT_FROM_DATABASE=RV370 [FirePro V5700] + +pci:v00001002d0000949F* + ID_PRODUCT_FROM_DATABASE=RV730 [FirePro V5700] + +pci:v00001002d000094A0* + ID_PRODUCT_FROM_DATABASE=Mobility Radeon HD 4830 [M97] + +pci:v00001002d000094A1* + ID_PRODUCT_FROM_DATABASE=[M97 XT] Mobility Radeon HD 4860 + +pci:v00001002d000094A3* + ID_PRODUCT_FROM_DATABASE=M97 GL [ATI FirePro M7740] + +pci:v00001002d000094B3* + ID_PRODUCT_FROM_DATABASE=Radeon HD 4770 [RV740] + +pci:v00001002d000094B4* + ID_PRODUCT_FROM_DATABASE=RV740 LE [ATI Radeon HD 4700 Series] + +pci:v00001002d000094C1* + ID_PRODUCT_FROM_DATABASE=RV610 [Radeon HD 2400 XT] + +pci:v00001002d000094C1sv00001028sd00000211* + ID_PRODUCT_FROM_DATABASE=Optiplex 755 + +pci:v00001002d000094C1sv00001028sd00000D02* + ID_PRODUCT_FROM_DATABASE=Optiplex 755 + +pci:v00001002d000094C3* + ID_PRODUCT_FROM_DATABASE=RV610 video device [Radeon HD 2400 PRO] + +pci:v00001002d000094C3sv00001002sd000094C3* + ID_PRODUCT_FROM_DATABASE=Radeon HD 2400PRO + +pci:v00001002d000094C3sv00001028sd00000302* + ID_PRODUCT_FROM_DATABASE=Radeon HD 2400 Pro + +pci:v00001002d000094C3sv0000174Bsd0000E400* + ID_PRODUCT_FROM_DATABASE=Sapphire HD 2400 PRO video device + +pci:v00001002d000094C3sv000018BCsd00003550* + ID_PRODUCT_FROM_DATABASE=GeCube Radeon HD2400 PRO + +pci:v00001002d000094C4* + ID_PRODUCT_FROM_DATABASE=RV610 LE AGP [Radeon HD 2400 PRO AGP] + +pci:v00001002d000094C8* + ID_PRODUCT_FROM_DATABASE=Radeon HD 2400 XT + +pci:v00001002d000094C9* + ID_PRODUCT_FROM_DATABASE=Mobility Radeon HD 2400 + +pci:v00001002d000094C9sv00001002sd000094C9* + ID_PRODUCT_FROM_DATABASE=Radeon HD2400 + +pci:v00001002d000094CB* + ID_PRODUCT_FROM_DATABASE=Radeon E2400 + +pci:v00001002d000094CC* + ID_PRODUCT_FROM_DATABASE=RV610 LE [Radeon HD 2400 Pro PCI] + +pci:v00001002d00009501* + ID_PRODUCT_FROM_DATABASE=RV670 [Radeon HD 3870] + +pci:v00001002d00009501sv0000174Bsd0000E620* + ID_PRODUCT_FROM_DATABASE=Sapphire Radeon HD 3870 PCIe 2.0 + +pci:v00001002d00009504* + ID_PRODUCT_FROM_DATABASE=RV670 [Mobility Radeon HD 3850] + +pci:v00001002d00009505* + ID_PRODUCT_FROM_DATABASE=RV670PRO [Radeon HD 3850] + +pci:v00001002d00009507* + ID_PRODUCT_FROM_DATABASE=RV670 [Radeon HD 3850] + +pci:v00001002d00009508* + ID_PRODUCT_FROM_DATABASE=M88 XT Mobility Radeon HD 3870] + +pci:v00001002d0000950F* + ID_PRODUCT_FROM_DATABASE=R680 [Radeon HD 3870 x2] + +pci:v00001002d00009511* + ID_PRODUCT_FROM_DATABASE=RV670 [FireGL 7700] + +pci:v00001002d00009515* + ID_PRODUCT_FROM_DATABASE=RV670 AGP [Radeon HD 3850] + +pci:v00001002d00009519* + ID_PRODUCT_FROM_DATABASE=RV670 [FireStream 9170] + +pci:v00001002d00009540* + ID_PRODUCT_FROM_DATABASE=RV710 [Radeon HD 4550] + +pci:v00001002d0000954F* + ID_PRODUCT_FROM_DATABASE=RV710 [Radeon HD 4350] + +pci:v00001002d0000954Fsv00001462sd00001618* + ID_PRODUCT_FROM_DATABASE=R4350 MD512H (MS-V161) + +pci:v00001002d00009552* + ID_PRODUCT_FROM_DATABASE=RV710 [Mobility Radeon HD 4300 Series] + +pci:v00001002d00009553* + ID_PRODUCT_FROM_DATABASE=RV710 [Mobility Radeon HD 4500/5100 Series] + +pci:v00001002d00009553sv00001179sd0000FF82* + ID_PRODUCT_FROM_DATABASE=Satellite L505-13T GPU (Mobility Radeon HD 5145) + +pci:v00001002d00009555* + ID_PRODUCT_FROM_DATABASE=RV710 [Mobility Radeon HD 4300/4500 Series] + +pci:v00001002d00009555sv0000103Csd00001411* + ID_PRODUCT_FROM_DATABASE=ProBook 4720s GPU (Mobility Radeon HD 4350) + +pci:v00001002d00009559* + ID_PRODUCT_FROM_DATABASE=RV635 [Mobility Radeon HD 3600 Series] + +pci:v00001002d0000955F* + ID_PRODUCT_FROM_DATABASE=RV710 [Mobility Radeon HD 4330] + +pci:v00001002d00009581* + ID_PRODUCT_FROM_DATABASE=RV630 [Mobility Radeon HD 2600] + +pci:v00001002d00009583* + ID_PRODUCT_FROM_DATABASE=RV630 [Mobility Radeon HD 2600 XT] + +pci:v00001002d00009586* + ID_PRODUCT_FROM_DATABASE=RV 630 XT AGP [Radeon HD 2600 XT AGP] + +pci:v00001002d00009587* + ID_PRODUCT_FROM_DATABASE=RV630 PRO AGP [Radeon HD 2600 PRO AGP] + +pci:v00001002d00009588* + ID_PRODUCT_FROM_DATABASE=RV630 [Radeon HD 2600XT] + +pci:v00001002d00009588sv00001458sd0000216C* + ID_PRODUCT_FROM_DATABASE=Radeon HD 2600 XT, 256MB GDDR3, 2x DVI, TV-out, PCIe (GV-RX26T256H) + +pci:v00001002d00009589* + ID_PRODUCT_FROM_DATABASE=RV630 [Radeon HD 2600 Series] + +pci:v00001002d0000958C* + ID_PRODUCT_FROM_DATABASE=RV630GL [FireGL v5600] + +pci:v00001002d0000958D* + ID_PRODUCT_FROM_DATABASE=RV630 [FireGL V3600] + +pci:v00001002d00009591* + ID_PRODUCT_FROM_DATABASE=RV635 [Mobility Radeon HD 3650] + +pci:v00001002d00009591sv00001002sd00009591* + ID_PRODUCT_FROM_DATABASE=Mobility Radeon HD 3650 + +pci:v00001002d00009593* + ID_PRODUCT_FROM_DATABASE=RV635 [Mobility Radeon HD 3670] + +pci:v00001002d00009595* + ID_PRODUCT_FROM_DATABASE=M86GL [Mobility FireGL V5700] + +pci:v00001002d00009596* + ID_PRODUCT_FROM_DATABASE=RV635 PRO AGP [Radeon HD 3650] + +pci:v00001002d00009596sv00001043sd00000028* + ID_PRODUCT_FROM_DATABASE=EAH3650 SILENT/HTDI/512M/A + +pci:v00001002d00009598* + ID_PRODUCT_FROM_DATABASE=RV630 [Radeon HD 3600 Series] + +pci:v00001002d00009598sv00001002sd00009598* + ID_PRODUCT_FROM_DATABASE=Mobility Radeon HD 3600 + +pci:v00001002d00009598sv00001043sd000001D6* + ID_PRODUCT_FROM_DATABASE=EAH3650 Silent + +pci:v00001002d000095C0* + ID_PRODUCT_FROM_DATABASE=RV620 PRO [Radeon HD 3470] + +pci:v00001002d000095C0sv00001002sd000095C0* + ID_PRODUCT_FROM_DATABASE=Mobility Radeon HD 3470 + +pci:v00001002d000095C4* + ID_PRODUCT_FROM_DATABASE=RV620 [Mobility Radeon HD 3400 Series] + +pci:v00001002d000095C4sv00001002sd000095C4* + ID_PRODUCT_FROM_DATABASE=Mobility Radeon HD 3400 + +pci:v00001002d000095C5* + ID_PRODUCT_FROM_DATABASE=RV620 LE [Radeon HD 3450] + +pci:v00001002d000095C5sv00001028sd00000342* + ID_PRODUCT_FROM_DATABASE=OptiPlex 980 + +pci:v00001002d000095C6* + ID_PRODUCT_FROM_DATABASE=RV620 LE AGP [Radeon HD 3450] + +pci:v00001002d000095C7* + ID_PRODUCT_FROM_DATABASE=RV620 CE [Radeon HD 3430] + +pci:v00001002d000095C9* + ID_PRODUCT_FROM_DATABASE=RV620 PCI [Radeon HD 3450] + +pci:v00001002d000095CC* + ID_PRODUCT_FROM_DATABASE=RV620 [ATI FireGL V3700] + +pci:v00001002d000095CD* + ID_PRODUCT_FROM_DATABASE=RV620 [FireMV 2450] + +pci:v00001002d000095CE* + ID_PRODUCT_FROM_DATABASE=RV620 [FirePro 2260] + +pci:v00001002d000095CF* + ID_PRODUCT_FROM_DATABASE=RV620 [FirePro 2260] + +pci:v00001002d0000960F* + ID_PRODUCT_FROM_DATABASE=RS780 HDMI Audio [Radeon HD 3000-3300 Series] + +pci:v00001002d00009610* + ID_PRODUCT_FROM_DATABASE=RS780 [Radeon HD 3200] + +pci:v00001002d00009610sv00001458sd0000D000* + ID_PRODUCT_FROM_DATABASE=GA-MA78GM-S2H Motherboard + +pci:v00001002d00009611* + ID_PRODUCT_FROM_DATABASE=RS780C [Radeon HD 3100] + +pci:v00001002d00009612* + ID_PRODUCT_FROM_DATABASE=RS780M/RS780MN [Mobility Radeon HD 3200 Graphics] + +pci:v00001002d00009613* + ID_PRODUCT_FROM_DATABASE=RS780MC [Mobility Radeon HD 3100 Graphics] + +pci:v00001002d00009614* + ID_PRODUCT_FROM_DATABASE=RS780D [Radeon HD 3300] + +pci:v00001002d00009615* + ID_PRODUCT_FROM_DATABASE=RS780E [Radeon HD 3200] + +pci:v00001002d00009616* + ID_PRODUCT_FROM_DATABASE=RS780L [Radeon HD 3000] + +pci:v00001002d00009640* + ID_PRODUCT_FROM_DATABASE=BeaverCreek [Radeon HD 6550D] + +pci:v00001002d00009641* + ID_PRODUCT_FROM_DATABASE=BeaverCreek [Mobility Radeon HD 6620G] + +pci:v00001002d00009647* + ID_PRODUCT_FROM_DATABASE=BeaverCreek [Radeon HD 6520G] + +pci:v00001002d0000964A* + ID_PRODUCT_FROM_DATABASE=BeaverCreek [Radeon HD 6530D] + +pci:v00001002d0000970F* + ID_PRODUCT_FROM_DATABASE=RS880 HDMI Audio [Radeon HD 4200 Series] + +pci:v00001002d0000970Fsv00001043sd000083A2* + ID_PRODUCT_FROM_DATABASE=M4A785TD Motherboard + +pci:v00001002d0000970Fsv00001043sd0000843E* + ID_PRODUCT_FROM_DATABASE=M5A88-V EVO + +pci:v00001002d00009710* + ID_PRODUCT_FROM_DATABASE=RS880 [Radeon HD 4200] + +pci:v00001002d00009710sv00001043sd000083A2* + ID_PRODUCT_FROM_DATABASE=M4A785TD Motherboard + +pci:v00001002d00009712* + ID_PRODUCT_FROM_DATABASE=RS880M [Mobility Radeon HD 4200 Series] + +pci:v00001002d00009713* + ID_PRODUCT_FROM_DATABASE=RS880M [Mobility Radeon HD 4100] + +pci:v00001002d00009714* + ID_PRODUCT_FROM_DATABASE=RS880 [Radeon HD 4290] + +pci:v00001002d00009715* + ID_PRODUCT_FROM_DATABASE=RS880 [Radeon HD 4250] + +pci:v00001002d00009715sv00001043sd0000843E* + ID_PRODUCT_FROM_DATABASE=M5A88-V EVO + +pci:v00001002d00009802* + ID_PRODUCT_FROM_DATABASE=Wrestler [Radeon HD 6310] + +pci:v00001002d00009802sv0000174Bsd00001001* + ID_PRODUCT_FROM_DATABASE=Sapphire PURE Fusion Mini + +pci:v00001002d00009804* + ID_PRODUCT_FROM_DATABASE=Wrestler [Radeon HD 6250] + +pci:v00001002d00009806* + ID_PRODUCT_FROM_DATABASE=Wrestler [Radeon HD 6320] + +pci:v00001002d00009807* + ID_PRODUCT_FROM_DATABASE=Wrestler [Radeon HD 6290] + +pci:v00001002d00009901* + ID_PRODUCT_FROM_DATABASE=Trinity [Radeon HD 7660D] + +pci:v00001002d00009902* + ID_PRODUCT_FROM_DATABASE=Trinity HDMI Audio Controller + +pci:v00001002d00009904* + ID_PRODUCT_FROM_DATABASE=Trinity [Radeon HD 7560D] + +pci:v00001002d00009990* + ID_PRODUCT_FROM_DATABASE=Trinity [Radeon HD 7520G] + +pci:v00001002d0000AA00* + ID_PRODUCT_FROM_DATABASE=R600 Audio Device [Radeon HD 2900 Series] + +pci:v00001002d0000AA08* + ID_PRODUCT_FROM_DATABASE=RV630 audio device [Radeon HD 2600 Series] + +pci:v00001002d0000AA10* + ID_PRODUCT_FROM_DATABASE=RV610 HDMI Audio [Radeon HD 2350/2400 Series] + +pci:v00001002d0000AA10sv0000174Bsd0000AA10* + ID_PRODUCT_FROM_DATABASE=Sapphire HD 2400 PRO audio device + +pci:v00001002d0000AA10sv000018BCsd0000AA10* + ID_PRODUCT_FROM_DATABASE=GeCube Radeon HD 2400 PRO HDCP-capable digital-only audio device + +pci:v00001002d0000AA18* + ID_PRODUCT_FROM_DATABASE=RV670/680 HDMI Audio [Radeon HD 3690/3800 Series] + +pci:v00001002d0000AA20* + ID_PRODUCT_FROM_DATABASE=RV635 HDMI Audio [Radeon HD 3600 Series] + +pci:v00001002d0000AA28* + ID_PRODUCT_FROM_DATABASE=RV620 HDMI Audio [Radeon HD 3400 Series] + +pci:v00001002d0000AA30* + ID_PRODUCT_FROM_DATABASE=RV770 HDMI Audio [Radeon HD 4850/4870] + +pci:v00001002d0000AA30sv0000174Bsd0000AA30* + ID_PRODUCT_FROM_DATABASE=Sapphire HD 4850 512MB GDDR3 PCI-E Dual Slot Fansink + +pci:v00001002d0000AA38* + ID_PRODUCT_FROM_DATABASE=RV710/730 HDMI Audio [Radeon HD 4000 series] + +pci:v00001002d0000AA38sv0000103Csd00003628* + ID_PRODUCT_FROM_DATABASE=ATI RV710/730 [dv6-1190en] + +pci:v00001002d0000AA38sv0000174Bsd0000AA38* + ID_PRODUCT_FROM_DATABASE=R700 Audio Device [Radeon HD 4000 Series] + +pci:v00001002d0000AA50* + ID_PRODUCT_FROM_DATABASE=Cypress HDMI Audio [Radeon HD 5800 Series] + +pci:v00001002d0000AA58* + ID_PRODUCT_FROM_DATABASE=Juniper HDMI Audio [Radeon HD 5700 Series] + +pci:v00001002d0000AA60* + ID_PRODUCT_FROM_DATABASE=Redwood HDMI Audio [Radeon HD 5000 Series] + +pci:v00001002d0000AA60sv00001025sd0000033D* + ID_PRODUCT_FROM_DATABASE=Mobility Radeon HD 5650 + +pci:v00001002d0000AA60sv00001025sd00000347* + ID_PRODUCT_FROM_DATABASE=Aspire 7740G + +pci:v00001002d0000AA68* + ID_PRODUCT_FROM_DATABASE=Cedar HDMI Audio [Radeon HD 5400/6300 Series] + +pci:v00001002d0000AA68sv00001028sd0000AA68* + ID_PRODUCT_FROM_DATABASE=XPS 8300 + +pci:v00001002d0000AA80* + ID_PRODUCT_FROM_DATABASE=Cayman/Antilles HDMI Audio [Radeon HD 6900 Series] + +pci:v00001002d0000AA88* + ID_PRODUCT_FROM_DATABASE=Barts HDMI Audio [Radeon HD 6800 Series] + +pci:v00001002d0000AA90* + ID_PRODUCT_FROM_DATABASE=Turks/Whistler HDMI Audio [Radeon HD 6000 Series] + +pci:v00001002d0000AA98* + ID_PRODUCT_FROM_DATABASE=Caicos HDMI Audio [Radeon HD 6400 Series] + +pci:v00001002d0000AA98sv0000174Bsd0000AA98* + ID_PRODUCT_FROM_DATABASE=Sapphire HD 6450 1GB DDR3 + +pci:v00001002d0000AAA0* + ID_PRODUCT_FROM_DATABASE=Tahiti XT HDMI Audio [Radeon HD 7970 Series] + +pci:v00001002d0000AC00* + ID_PRODUCT_FROM_DATABASE=Theater 600 Pro + +pci:v00001002d0000AC02* + ID_PRODUCT_FROM_DATABASE=TV Wonder HD 600 PCIe + +pci:v00001002d0000AC12* + ID_PRODUCT_FROM_DATABASE=Theater HD T507 (DVB-T) TV tuner/capture device + +pci:v00001002d0000CAB0* + ID_PRODUCT_FROM_DATABASE=RS100 AGP Bridge [IGP 320M] + +pci:v00001002d0000CAB2* + ID_PRODUCT_FROM_DATABASE=RS200/RS200M AGP Bridge [IGP 340M] + +pci:v00001002d0000CAB3* + ID_PRODUCT_FROM_DATABASE=R200 AGP Bridge [Mobility Radeon 7000 IGP] + +pci:v00001002d0000CBB2* + ID_PRODUCT_FROM_DATABASE=RS200/RS200M AGP Bridge [IGP 340M] + +pci:v00001003* + ID_VENDOR_FROM_DATABASE=ULSI Systems + +pci:v00001003d00000201* + ID_PRODUCT_FROM_DATABASE=US201 + +pci:v00001004* + ID_VENDOR_FROM_DATABASE=VLSI Technology Inc + +pci:v00001004d00000005* + ID_PRODUCT_FROM_DATABASE=82C592-FC1 + +pci:v00001004d00000006* + ID_PRODUCT_FROM_DATABASE=82C593-FC1 + +pci:v00001004d00000007* + ID_PRODUCT_FROM_DATABASE=82C594-AFC2 + +pci:v00001004d00000008* + ID_PRODUCT_FROM_DATABASE=82C596/7 [Wildcat] + +pci:v00001004d00000009* + ID_PRODUCT_FROM_DATABASE=82C597-AFC2 + +pci:v00001004d0000000C* + ID_PRODUCT_FROM_DATABASE=82C541 [Lynx] + +pci:v00001004d0000000D* + ID_PRODUCT_FROM_DATABASE=82C543 [Lynx] + +pci:v00001004d00000101* + ID_PRODUCT_FROM_DATABASE=82C532 + +pci:v00001004d00000102* + ID_PRODUCT_FROM_DATABASE=82C534 [Eagle] + +pci:v00001004d00000103* + ID_PRODUCT_FROM_DATABASE=82C538 + +pci:v00001004d00000104* + ID_PRODUCT_FROM_DATABASE=82C535 + +pci:v00001004d00000105* + ID_PRODUCT_FROM_DATABASE=82C147 + +pci:v00001004d00000200* + ID_PRODUCT_FROM_DATABASE=82C975 + +pci:v00001004d00000280* + ID_PRODUCT_FROM_DATABASE=82C925 + +pci:v00001004d00000304* + ID_PRODUCT_FROM_DATABASE=QSound ThunderBird PCI Audio + +pci:v00001004d00000304sv00001004sd00000304* + ID_PRODUCT_FROM_DATABASE=QSound ThunderBird PCI Audio + +pci:v00001004d00000304sv0000122Dsd00001206* + ID_PRODUCT_FROM_DATABASE=DSP368 Audio + +pci:v00001004d00000304sv00001483sd00005020* + ID_PRODUCT_FROM_DATABASE=XWave Thunder 3D Audio + +pci:v00001004d00000305* + ID_PRODUCT_FROM_DATABASE=QSound ThunderBird PCI Audio Gameport + +pci:v00001004d00000305sv00001004sd00000305* + ID_PRODUCT_FROM_DATABASE=QSound ThunderBird PCI Audio Gameport + +pci:v00001004d00000305sv0000122Dsd00001207* + ID_PRODUCT_FROM_DATABASE=DSP368 Audio Gameport + +pci:v00001004d00000305sv00001483sd00005021* + ID_PRODUCT_FROM_DATABASE=XWave Thunder 3D Audio Gameport + +pci:v00001004d00000306* + ID_PRODUCT_FROM_DATABASE=QSound ThunderBird PCI Audio Support Registers + +pci:v00001004d00000306sv00001004sd00000306* + ID_PRODUCT_FROM_DATABASE=QSound ThunderBird PCI Audio Support Registers + +pci:v00001004d00000306sv0000122Dsd00001208* + ID_PRODUCT_FROM_DATABASE=DSP368 Audio Support Registers + +pci:v00001004d00000306sv00001483sd00005022* + ID_PRODUCT_FROM_DATABASE=XWave Thunder 3D Audio Support Registers + +pci:v00001004d00000307* + ID_PRODUCT_FROM_DATABASE=SAA7785 ThunderBird PCI Audio + +pci:v00001004d00000307sv00001004sd00000703* + ID_PRODUCT_FROM_DATABASE=Philips Rhythmic Edge PSC703 + +pci:v00001004d00000307sv00001004sd00000705* + ID_PRODUCT_FROM_DATABASE=Philips Seismic Edge PSC705 + +pci:v00001004d00000307sv00001004sd00000706* + ID_PRODUCT_FROM_DATABASE=Philips Acoustic Edge PSC706 + +pci:v00001004d00000308* + ID_PRODUCT_FROM_DATABASE=SAA7785 ThunderBird PCI Audio Gameport + +pci:v00001004d00000702* + ID_PRODUCT_FROM_DATABASE=VAS96011 [Golden Gate II] + +pci:v00001004d00000703* + ID_PRODUCT_FROM_DATABASE=Tollgate + +pci:v00001005* + ID_VENDOR_FROM_DATABASE=Avance Logic Inc. [ALI] + +pci:v00001005d00002064* + ID_PRODUCT_FROM_DATABASE=ALG2032/2064 + +pci:v00001005d00002128* + ID_PRODUCT_FROM_DATABASE=ALG2364A + +pci:v00001005d00002301* + ID_PRODUCT_FROM_DATABASE=ALG2301 + +pci:v00001005d00002302* + ID_PRODUCT_FROM_DATABASE=ALG2302 + +pci:v00001005d00002364* + ID_PRODUCT_FROM_DATABASE=ALG2364 + +pci:v00001005d00002464* + ID_PRODUCT_FROM_DATABASE=ALG2364A + +pci:v00001005d00002501* + ID_PRODUCT_FROM_DATABASE=ALG2564A/25128A + +pci:v00001006* + ID_VENDOR_FROM_DATABASE=Reply Group + +pci:v00001007* + ID_VENDOR_FROM_DATABASE=NetFrame Systems Inc + +pci:v00001008* + ID_VENDOR_FROM_DATABASE=Epson + +pci:v0000100A* + ID_VENDOR_FROM_DATABASE=Phoenix Technologies + +pci:v0000100B* + ID_VENDOR_FROM_DATABASE=National Semiconductor Corporation + +pci:v0000100Bd00000001* + ID_PRODUCT_FROM_DATABASE=DP83810 + +pci:v0000100Bd00000002* + ID_PRODUCT_FROM_DATABASE=87415/87560 IDE + +pci:v0000100Bd0000000E* + ID_PRODUCT_FROM_DATABASE=87560 Legacy I/O + +pci:v0000100Bd0000000F* + ID_PRODUCT_FROM_DATABASE=FireWire Controller + +pci:v0000100Bd00000011* + ID_PRODUCT_FROM_DATABASE=NS87560 National PCI System I/O + +pci:v0000100Bd00000012* + ID_PRODUCT_FROM_DATABASE=USB Controller + +pci:v0000100Bd00000020* + ID_PRODUCT_FROM_DATABASE=DP83815 (MacPhyter) Ethernet Controller + +pci:v0000100Bd00000020sv0000103Csd00000024* + ID_PRODUCT_FROM_DATABASE=Pavilion ze4400 builtin Network + +pci:v0000100Bd00000020sv000012D9sd0000000C* + ID_PRODUCT_FROM_DATABASE=Aculab E1/T1 PMXc cPCI carrier card + +pci:v0000100Bd00000020sv00001385sd0000F311* + ID_PRODUCT_FROM_DATABASE=FA311 / FA312 (FA311 with WoL HW) + +pci:v0000100Bd00000021* + ID_PRODUCT_FROM_DATABASE=PC87200 PCI to ISA Bridge + +pci:v0000100Bd00000022* + ID_PRODUCT_FROM_DATABASE=DP83820 10/100/1000 Ethernet Controller + +pci:v0000100Bd00000022sv00001186sd00004900* + ID_PRODUCT_FROM_DATABASE=DGE-500T + +pci:v0000100Bd00000022sv00001385sd0000621A* + ID_PRODUCT_FROM_DATABASE=GA621 + +pci:v0000100Bd00000022sv00001385sd0000622A* + ID_PRODUCT_FROM_DATABASE=GA622T + +pci:v0000100Bd00000028* + ID_PRODUCT_FROM_DATABASE=Geode GX2 Host Bridge + +pci:v0000100Bd0000002A* + ID_PRODUCT_FROM_DATABASE=CS5535 South Bridge + +pci:v0000100Bd0000002B* + ID_PRODUCT_FROM_DATABASE=CS5535 ISA bridge + +pci:v0000100Bd0000002D* + ID_PRODUCT_FROM_DATABASE=CS5535 IDE + +pci:v0000100Bd0000002E* + ID_PRODUCT_FROM_DATABASE=CS5535 Audio + +pci:v0000100Bd0000002F* + ID_PRODUCT_FROM_DATABASE=CS5535 USB + +pci:v0000100Bd00000030* + ID_PRODUCT_FROM_DATABASE=Geode GX2 Graphics Processor + +pci:v0000100Bd00000035* + ID_PRODUCT_FROM_DATABASE=DP83065 [Saturn] 10/100/1000 Ethernet Controller + +pci:v0000100Bd00000500* + ID_PRODUCT_FROM_DATABASE=SCx200 Bridge + +pci:v0000100Bd00000501* + ID_PRODUCT_FROM_DATABASE=SCx200 SMI + +pci:v0000100Bd00000502* + ID_PRODUCT_FROM_DATABASE=SCx200, SC1100 IDE controller + +pci:v0000100Bd00000502sv0000100Bsd00000502* + ID_PRODUCT_FROM_DATABASE=IDE Controller + +pci:v0000100Bd00000503* + ID_PRODUCT_FROM_DATABASE=SCx200, SC1100 Audio Controller + +pci:v0000100Bd00000503sv0000100Bsd00000503* + ID_PRODUCT_FROM_DATABASE=XpressAudio controller + +pci:v0000100Bd00000504* + ID_PRODUCT_FROM_DATABASE=SCx200 Video + +pci:v0000100Bd00000505* + ID_PRODUCT_FROM_DATABASE=SCx200 XBus + +pci:v0000100Bd00000510* + ID_PRODUCT_FROM_DATABASE=SC1100 Bridge + +pci:v0000100Bd00000510sv0000100Bsd00000500* + ID_PRODUCT_FROM_DATABASE=GPIO and LPC support bridge + +pci:v0000100Bd00000511* + ID_PRODUCT_FROM_DATABASE=SC1100 SMI & ACPI + +pci:v0000100Bd00000511sv0000100Bsd00000501* + ID_PRODUCT_FROM_DATABASE=SC1100 SMI & ACPI bridge + +pci:v0000100Bd00000515* + ID_PRODUCT_FROM_DATABASE=SC1100 XBus + +pci:v0000100Bd00000515sv0000100Bsd00000505* + ID_PRODUCT_FROM_DATABASE=SC1100 PCI to XBus bridge + +pci:v0000100Bd0000D001* + ID_PRODUCT_FROM_DATABASE=87410 IDE + +pci:v0000100C* + ID_VENDOR_FROM_DATABASE=Tseng Labs Inc + +pci:v0000100Cd00003202* + ID_PRODUCT_FROM_DATABASE=ET4000/W32p rev A + +pci:v0000100Cd00003205* + ID_PRODUCT_FROM_DATABASE=ET4000/W32p rev B + +pci:v0000100Cd00003206* + ID_PRODUCT_FROM_DATABASE=ET4000/W32p rev C + +pci:v0000100Cd00003207* + ID_PRODUCT_FROM_DATABASE=ET4000/W32p rev D + +pci:v0000100Cd00003208* + ID_PRODUCT_FROM_DATABASE=ET6000 + +pci:v0000100Cd00004702* + ID_PRODUCT_FROM_DATABASE=ET6300 + +pci:v0000100D* + ID_VENDOR_FROM_DATABASE=AST Research Inc + +pci:v0000100E* + ID_VENDOR_FROM_DATABASE=Weitek + +pci:v0000100Ed00009000* + ID_PRODUCT_FROM_DATABASE=P9000 Viper + +pci:v0000100Ed00009001* + ID_PRODUCT_FROM_DATABASE=P9000 Viper + +pci:v0000100Ed00009002* + ID_PRODUCT_FROM_DATABASE=P9000 Viper + +pci:v0000100Ed00009100* + ID_PRODUCT_FROM_DATABASE=P9100 Viper Pro/SE + +pci:v00001010* + ID_VENDOR_FROM_DATABASE=Video Logic, Ltd. + +pci:v00001011* + ID_VENDOR_FROM_DATABASE=Digital Equipment Corporation + +pci:v00001011d00000001* + ID_PRODUCT_FROM_DATABASE=DECchip 21050 + +pci:v00001011d00000002* + ID_PRODUCT_FROM_DATABASE=DECchip 21040 [Tulip] + +pci:v00001011d00000004* + ID_PRODUCT_FROM_DATABASE=DECchip 21030 [TGA] + +pci:v00001011d00000007* + ID_PRODUCT_FROM_DATABASE=NVRAM [Zephyr NVRAM] + +pci:v00001011d00000008* + ID_PRODUCT_FROM_DATABASE=KZPSA [KZPSA] + +pci:v00001011d00000009* + ID_PRODUCT_FROM_DATABASE=DECchip 21140 [FasterNet] + +pci:v00001011d00000009sv00001025sd00000310* + ID_PRODUCT_FROM_DATABASE=21140 Fast Ethernet + +pci:v00001011d00000009sv000010B8sd00002001* + ID_PRODUCT_FROM_DATABASE=SMC9332BDT EtherPower 10/100 + +pci:v00001011d00000009sv000010B8sd00002002* + ID_PRODUCT_FROM_DATABASE=SMC9332BVT EtherPower T4 10/100 + +pci:v00001011d00000009sv000010B8sd00002003* + ID_PRODUCT_FROM_DATABASE=SMC9334BDT EtherPower 10/100 (1-port) + +pci:v00001011d00000009sv00001109sd00002400* + ID_PRODUCT_FROM_DATABASE=ANA-6944A/TX Fast Ethernet + +pci:v00001011d00000009sv00001112sd00002300* + ID_PRODUCT_FROM_DATABASE=RNS2300 Fast Ethernet + +pci:v00001011d00000009sv00001112sd00002320* + ID_PRODUCT_FROM_DATABASE=RNS2320 Fast Ethernet + +pci:v00001011d00000009sv00001112sd00002340* + ID_PRODUCT_FROM_DATABASE=RNS2340 Fast Ethernet + +pci:v00001011d00000009sv00001113sd00001207* + ID_PRODUCT_FROM_DATABASE=EN-1207-TX Fast Ethernet + +pci:v00001011d00000009sv00001186sd00001100* + ID_PRODUCT_FROM_DATABASE=DFE-500TX Fast Ethernet + +pci:v00001011d00000009sv00001186sd00001112* + ID_PRODUCT_FROM_DATABASE=DFE-570TX Fast Ethernet + +pci:v00001011d00000009sv00001186sd00001140* + ID_PRODUCT_FROM_DATABASE=DFE-660 Cardbus Ethernet 10/100 + +pci:v00001011d00000009sv00001186sd00001142* + ID_PRODUCT_FROM_DATABASE=DFE-660 Cardbus Ethernet 10/100 + +pci:v00001011d00000009sv000011F6sd00000503* + ID_PRODUCT_FROM_DATABASE=Freedomline Fast Ethernet + +pci:v00001011d00000009sv00001282sd00009100* + ID_PRODUCT_FROM_DATABASE=AEF-380TXD Fast Ethernet + +pci:v00001011d00000009sv00001385sd00001100* + ID_PRODUCT_FROM_DATABASE=FA310TX Fast Ethernet + +pci:v00001011d00000009sv00002646sd00000001* + ID_PRODUCT_FROM_DATABASE=KNE100TX Fast Ethernet + +pci:v00001011d0000000A* + ID_PRODUCT_FROM_DATABASE=21230 Video Codec + +pci:v00001011d0000000D* + ID_PRODUCT_FROM_DATABASE=PBXGB [TGA2] + +pci:v00001011d0000000F* + ID_PRODUCT_FROM_DATABASE=PCI-to-PDQ Interface Chip [PFI] + +pci:v00001011d0000000Fsv00001011sd0000DEF1* + ID_PRODUCT_FROM_DATABASE=FDDI controller (DEFPA) + +pci:v00001011d0000000Fsv0000103Csd0000DEF1* + ID_PRODUCT_FROM_DATABASE=FDDI controller (3X-DEFPA) + +pci:v00001011d00000014* + ID_PRODUCT_FROM_DATABASE=DECchip 21041 [Tulip Pass 3] + +pci:v00001011d00000014sv00001186sd00000100* + ID_PRODUCT_FROM_DATABASE=DE-530+ + +pci:v00001011d00000016* + ID_PRODUCT_FROM_DATABASE=DGLPB [OPPO] + +pci:v00001011d00000017* + ID_PRODUCT_FROM_DATABASE=PV-PCI Graphics Controller (ZLXp-L) + +pci:v00001011d00000018* + ID_PRODUCT_FROM_DATABASE=Memory Channel interface + +pci:v00001011d00000019* + ID_PRODUCT_FROM_DATABASE=DECchip 21142/43 + +pci:v00001011d00000019sv00001011sd0000500A* + ID_PRODUCT_FROM_DATABASE=DE500A Fast Ethernet + +pci:v00001011d00000019sv00001011sd0000500B* + ID_PRODUCT_FROM_DATABASE=DE500B Fast Ethernet + +pci:v00001011d00000019sv00001014sd00000001* + ID_PRODUCT_FROM_DATABASE=10/100 EtherJet Cardbus + +pci:v00001011d00000019sv00001025sd00000315* + ID_PRODUCT_FROM_DATABASE=ALN315 Fast Ethernet + +pci:v00001011d00000019sv00001033sd0000800C* + ID_PRODUCT_FROM_DATABASE=PC-9821-CS01 100BASE-TX Interface Card + +pci:v00001011d00000019sv00001033sd0000800D* + ID_PRODUCT_FROM_DATABASE=PC-9821NR-B06 100BASE-TX Interface Card + +pci:v00001011d00000019sv0000103Csd0000125A* + ID_PRODUCT_FROM_DATABASE=10/100Base-TX (PCI) [A5506B] + +pci:v00001011d00000019sv0000108Dsd00000016* + ID_PRODUCT_FROM_DATABASE=Rapidfire 2327 10/100 Ethernet + +pci:v00001011d00000019sv0000108Dsd00000017* + ID_PRODUCT_FROM_DATABASE=GoCard 2250 Ethernet 10/100 Cardbus + +pci:v00001011d00000019sv000010B8sd00002005* + ID_PRODUCT_FROM_DATABASE=SMC8032DT Extreme Ethernet 10/100 + +pci:v00001011d00000019sv000010B8sd00008034* + ID_PRODUCT_FROM_DATABASE=SMC8034 Extreme Ethernet 10/100 + +pci:v00001011d00000019sv000010EFsd00008169* + ID_PRODUCT_FROM_DATABASE=Cardbus Fast Ethernet + +pci:v00001011d00000019sv00001109sd00002A00* + ID_PRODUCT_FROM_DATABASE=ANA-6911A/TX Fast Ethernet + +pci:v00001011d00000019sv00001109sd00002B00* + ID_PRODUCT_FROM_DATABASE=ANA-6911A/TXC Fast Ethernet + +pci:v00001011d00000019sv00001109sd00003000* + ID_PRODUCT_FROM_DATABASE=ANA-6922/TX Fast Ethernet + +pci:v00001011d00000019sv00001113sd00001207* + ID_PRODUCT_FROM_DATABASE=Cheetah Fast Ethernet + +pci:v00001011d00000019sv00001113sd00002220* + ID_PRODUCT_FROM_DATABASE=Cardbus Fast Ethernet + +pci:v00001011d00000019sv0000115Dsd00000002* + ID_PRODUCT_FROM_DATABASE=Cardbus Ethernet 10/100 + +pci:v00001011d00000019sv00001179sd00000203* + ID_PRODUCT_FROM_DATABASE=Fast Ethernet + +pci:v00001011d00000019sv00001179sd00000204* + ID_PRODUCT_FROM_DATABASE=Cardbus Fast Ethernet + +pci:v00001011d00000019sv00001186sd00001100* + ID_PRODUCT_FROM_DATABASE=DFE-500TX Fast Ethernet + +pci:v00001011d00000019sv00001186sd00001101* + ID_PRODUCT_FROM_DATABASE=DFE-500TX Fast Ethernet + +pci:v00001011d00000019sv00001186sd00001102* + ID_PRODUCT_FROM_DATABASE=DFE-500TX Fast Ethernet + +pci:v00001011d00000019sv00001186sd00001112* + ID_PRODUCT_FROM_DATABASE=DFE-570TX Quad Fast Ethernet + +pci:v00001011d00000019sv00001259sd00002800* + ID_PRODUCT_FROM_DATABASE=AT-2800Tx Fast Ethernet + +pci:v00001011d00000019sv00001266sd00000004* + ID_PRODUCT_FROM_DATABASE=Eagle Fast EtherMAX + +pci:v00001011d00000019sv000012AFsd00000019* + ID_PRODUCT_FROM_DATABASE=NetFlyer Cardbus Fast Ethernet + +pci:v00001011d00000019sv00001374sd00000001* + ID_PRODUCT_FROM_DATABASE=Cardbus Ethernet Card 10/100 + +pci:v00001011d00000019sv00001374sd00000002* + ID_PRODUCT_FROM_DATABASE=Cardbus Ethernet Card 10/100 + +pci:v00001011d00000019sv00001374sd00000007* + ID_PRODUCT_FROM_DATABASE=Cardbus Ethernet Card 10/100 + +pci:v00001011d00000019sv00001374sd00000008* + ID_PRODUCT_FROM_DATABASE=Cardbus Ethernet Card 10/100 + +pci:v00001011d00000019sv00001385sd00002100* + ID_PRODUCT_FROM_DATABASE=FA510 + +pci:v00001011d00000019sv00001395sd00000001* + ID_PRODUCT_FROM_DATABASE=10/100 Ethernet CardBus PC Card + +pci:v00001011d00000019sv000013D1sd0000AB01* + ID_PRODUCT_FROM_DATABASE=EtherFast 10/100 Cardbus (PCMPC200) + +pci:v00001011d00000019sv00001498sd0000000A* + ID_PRODUCT_FROM_DATABASE=TPMC880-10 10/100Base-T and 10Base2 PMC Ethernet Adapter + +pci:v00001011d00000019sv00001498sd0000000B* + ID_PRODUCT_FROM_DATABASE=TPMC880-11 Single 10/100Base-T PMC Ethernet Adapter + +pci:v00001011d00000019sv00001498sd0000000C* + ID_PRODUCT_FROM_DATABASE=TPMC880-12 Single 10Base2 PMC Ethernet Adapter + +pci:v00001011d00000019sv000014CBsd00000100* + ID_PRODUCT_FROM_DATABASE=LNDL-100N 100Base-TX Ethernet PC Card + +pci:v00001011d00000019sv00001668sd00002000* + ID_PRODUCT_FROM_DATABASE=FastNet Pro (PE2000) + +pci:v00001011d00000019sv00002646sd00000001* + ID_PRODUCT_FROM_DATABASE=KNE100TX + +pci:v00001011d00000019sv00002646sd00000002* + ID_PRODUCT_FROM_DATABASE=KNE-CB4TX + +pci:v00001011d00000019sv00008086sd00000001* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 Mobile CardBus 32 + +pci:v00001011d0000001A* + ID_PRODUCT_FROM_DATABASE=Farallon PN9000SX Gigabit Ethernet + +pci:v00001011d00000021* + ID_PRODUCT_FROM_DATABASE=DECchip 21052 + +pci:v00001011d00000022* + ID_PRODUCT_FROM_DATABASE=DECchip 21150 + +pci:v00001011d00000023* + ID_PRODUCT_FROM_DATABASE=DECchip 21150 + +pci:v00001011d00000024* + ID_PRODUCT_FROM_DATABASE=DECchip 21152 + +pci:v00001011d00000025* + ID_PRODUCT_FROM_DATABASE=DECchip 21153 + +pci:v00001011d00000026* + ID_PRODUCT_FROM_DATABASE=DECchip 21154 + +pci:v00001011d00000034* + ID_PRODUCT_FROM_DATABASE=56k Modem Cardbus + +pci:v00001011d00000034sv00001374sd00000003* + ID_PRODUCT_FROM_DATABASE=56k Modem Cardbus + +pci:v00001011d00000045* + ID_PRODUCT_FROM_DATABASE=DECchip 21553 + +pci:v00001011d00000046* + ID_PRODUCT_FROM_DATABASE=DECchip 21554 + +pci:v00001011d00000046sv00000E11sd00004050* + ID_PRODUCT_FROM_DATABASE=Smart Array 4200 Controller + +pci:v00001011d00000046sv00000E11sd00004051* + ID_PRODUCT_FROM_DATABASE=Smart Array 4250ES Controller + +pci:v00001011d00000046sv00000E11sd00004058* + ID_PRODUCT_FROM_DATABASE=Smart Array 431 Controller + +pci:v00001011d00000046sv0000103Csd000010C2* + ID_PRODUCT_FROM_DATABASE=NetRAID-4M + +pci:v00001011d00000046sv000012D9sd0000000A* + ID_PRODUCT_FROM_DATABASE=IP Telephony card + +pci:v00001011d00000046sv00004C53sd00001050* + ID_PRODUCT_FROM_DATABASE=CT7 mainboard + +pci:v00001011d00000046sv00004C53sd00001051* + ID_PRODUCT_FROM_DATABASE=CE7 mainboard + +pci:v00001011d00000046sv00009005sd00000364* + ID_PRODUCT_FROM_DATABASE=5400S (Mustang) + +pci:v00001011d00000046sv00009005sd00000365* + ID_PRODUCT_FROM_DATABASE=5400S (Mustang) + +pci:v00001011d00000046sv00009005sd00001364* + ID_PRODUCT_FROM_DATABASE=Dell PowerEdge RAID Controller 2 + +pci:v00001011d00000046sv00009005sd00001365* + ID_PRODUCT_FROM_DATABASE=Dell PowerEdge RAID Controller 2 + +pci:v00001011d00000046sv0000E4BFsd00001000* + ID_PRODUCT_FROM_DATABASE=CC8-1-BLUES + +pci:v00001011d00001065* + ID_PRODUCT_FROM_DATABASE=StrongARM DC21285 + +pci:v00001011d00001065sv00001069sd00000020* + ID_PRODUCT_FROM_DATABASE=DAC960P / DAC1164P + +pci:v00001012* + ID_VENDOR_FROM_DATABASE=Micronics Computers Inc + +pci:v00001013* + ID_VENDOR_FROM_DATABASE=Cirrus Logic + +pci:v00001013d00000038* + ID_PRODUCT_FROM_DATABASE=GD 7548 + +pci:v00001013d00000040* + ID_PRODUCT_FROM_DATABASE=GD 7555 Flat Panel GUI Accelerator + +pci:v00001013d0000004C* + ID_PRODUCT_FROM_DATABASE=GD 7556 Video/Graphics LCD/CRT Ctrlr + +pci:v00001013d000000A0* + ID_PRODUCT_FROM_DATABASE=GD 5430/40 [Alpine] + +pci:v00001013d000000A2* + ID_PRODUCT_FROM_DATABASE=GD 5432 [Alpine] + +pci:v00001013d000000A4* + ID_PRODUCT_FROM_DATABASE=GD 5434-4 [Alpine] + +pci:v00001013d000000A8* + ID_PRODUCT_FROM_DATABASE=GD 5434-8 [Alpine] + +pci:v00001013d000000AC* + ID_PRODUCT_FROM_DATABASE=GD 5436 [Alpine] + +pci:v00001013d000000B0* + ID_PRODUCT_FROM_DATABASE=GD 5440 + +pci:v00001013d000000B8* + ID_PRODUCT_FROM_DATABASE=GD 5446 + +pci:v00001013d000000BC* + ID_PRODUCT_FROM_DATABASE=GD 5480 + +pci:v00001013d000000BCsv00001013sd000000BC* + ID_PRODUCT_FROM_DATABASE=CL-GD5480 + +pci:v00001013d000000D0* + ID_PRODUCT_FROM_DATABASE=GD 5462 + +pci:v00001013d000000D2* + ID_PRODUCT_FROM_DATABASE=GD 5462 [Laguna I] + +pci:v00001013d000000D4* + ID_PRODUCT_FROM_DATABASE=GD 5464 [Laguna] + +pci:v00001013d000000D5* + ID_PRODUCT_FROM_DATABASE=GD 5464 BD [Laguna] + +pci:v00001013d000000D6* + ID_PRODUCT_FROM_DATABASE=GD 5465 [Laguna] + +pci:v00001013d000000D6sv000013CEsd00008031* + ID_PRODUCT_FROM_DATABASE=Barco Metheus 2 Megapixel, Dual Head + +pci:v00001013d000000D6sv000013CFsd00008031* + ID_PRODUCT_FROM_DATABASE=Barco Metheus 2 Megapixel, Dual Head + +pci:v00001013d000000E8* + ID_PRODUCT_FROM_DATABASE=GD 5436U + +pci:v00001013d00001100* + ID_PRODUCT_FROM_DATABASE=CL 6729 + +pci:v00001013d00001110* + ID_PRODUCT_FROM_DATABASE=PD 6832 PCMCIA/CardBus Ctrlr + +pci:v00001013d00001112* + ID_PRODUCT_FROM_DATABASE=PD 6834 PCMCIA/CardBus Ctrlr + +pci:v00001013d00001113* + ID_PRODUCT_FROM_DATABASE=PD 6833 PCMCIA/CardBus Ctrlr + +pci:v00001013d00001200* + ID_PRODUCT_FROM_DATABASE=GD 7542 [Nordic] + +pci:v00001013d00001202* + ID_PRODUCT_FROM_DATABASE=GD 7543 [Viking] + +pci:v00001013d00001204* + ID_PRODUCT_FROM_DATABASE=GD 7541 [Nordic Light] + +pci:v00001013d00004000* + ID_PRODUCT_FROM_DATABASE=MD 5620 [CLM Data Fax Voice] + +pci:v00001013d00004400* + ID_PRODUCT_FROM_DATABASE=CD 4400 + +pci:v00001013d00006001* + ID_PRODUCT_FROM_DATABASE=CS 4610/11 [CrystalClear SoundFusion Audio Accelerator] + +pci:v00001013d00006001sv00001014sd00001010* + ID_PRODUCT_FROM_DATABASE=CS4610 SoundFusion Audio Accelerator + +pci:v00001013d00006003* + ID_PRODUCT_FROM_DATABASE=CS 4614/22/24/30 [CrystalClear SoundFusion Audio Accelerator] + +pci:v00001013d00006003sv00001013sd00004280* + ID_PRODUCT_FROM_DATABASE=Crystal SoundFusion PCI Audio Accelerator + +pci:v00001013d00006003sv00001014sd00000153* + ID_PRODUCT_FROM_DATABASE=ThinkPad 600X/A20m + +pci:v00001013d00006003sv0000153Bsd0000112E* + ID_PRODUCT_FROM_DATABASE=DMX XFire 1024 + +pci:v00001013d00006003sv0000153Bsd00001136* + ID_PRODUCT_FROM_DATABASE=SiXPack 5.1+ + +pci:v00001013d00006003sv00001681sd00000050* + ID_PRODUCT_FROM_DATABASE=Game Theater XP + +pci:v00001013d00006003sv00001681sd0000A010* + ID_PRODUCT_FROM_DATABASE=Gamesurround Fortissimo II + +pci:v00001013d00006003sv00001681sd0000A011* + ID_PRODUCT_FROM_DATABASE=Gamesurround Fortissimo III 7.1 + +pci:v00001013d00006003sv00005053sd00003357* + ID_PRODUCT_FROM_DATABASE=Santa Cruz + +pci:v00001013d00006004* + ID_PRODUCT_FROM_DATABASE=CS 4614/22/24 [CrystalClear SoundFusion Audio Accelerator] + +pci:v00001013d00006005* + ID_PRODUCT_FROM_DATABASE=Crystal CS4281 PCI Audio + +pci:v00001013d00006005sv00001013sd00004281* + ID_PRODUCT_FROM_DATABASE=Crystal CS4281 PCI Audio + +pci:v00001013d00006005sv000010CFsd000010A8* + ID_PRODUCT_FROM_DATABASE=Crystal CS4281 PCI Audio + +pci:v00001013d00006005sv000010CFsd000010A9* + ID_PRODUCT_FROM_DATABASE=Crystal CS4281 PCI Audio + +pci:v00001013d00006005sv000010CFsd000010AA* + ID_PRODUCT_FROM_DATABASE=Crystal CS4281 PCI Audio + +pci:v00001013d00006005sv000010CFsd000010AB* + ID_PRODUCT_FROM_DATABASE=Crystal CS4281 PCI Audio + +pci:v00001013d00006005sv000010CFsd000010AC* + ID_PRODUCT_FROM_DATABASE=Crystal CS4281 PCI Audio + +pci:v00001013d00006005sv000010CFsd000010AD* + ID_PRODUCT_FROM_DATABASE=Crystal CS4281 PCI Audio + +pci:v00001013d00006005sv000010CFsd000010B4* + ID_PRODUCT_FROM_DATABASE=Crystal CS4281 PCI Audio + +pci:v00001013d00006005sv00001179sd00000001* + ID_PRODUCT_FROM_DATABASE=Crystal CS4281 PCI Audio + +pci:v00001013d00006005sv000014C0sd0000000C* + ID_PRODUCT_FROM_DATABASE=Crystal CS4281 PCI Audio + +pci:v00001014* + ID_VENDOR_FROM_DATABASE=IBM + +pci:v00001014d00000002* + ID_PRODUCT_FROM_DATABASE=PCI to MCA Bridge + +pci:v00001014d00000005* + ID_PRODUCT_FROM_DATABASE=Processor to I/O Controller [Alta Lite] + +pci:v00001014d00000007* + ID_PRODUCT_FROM_DATABASE=Processor to I/O Controller [Alta MP] + +pci:v00001014d0000000A* + ID_PRODUCT_FROM_DATABASE=PCI to ISA Bridge (IBM27-82376) [Fire Coral] + +pci:v00001014d00000017* + ID_PRODUCT_FROM_DATABASE=CPU to PCI Bridge + +pci:v00001014d00000018* + ID_PRODUCT_FROM_DATABASE=TR Auto LANstreamer + +pci:v00001014d0000001B* + ID_PRODUCT_FROM_DATABASE=GXT-150P + +pci:v00001014d0000001C* + ID_PRODUCT_FROM_DATABASE=Carrera + +pci:v00001014d0000001D* + ID_PRODUCT_FROM_DATABASE=SCSI-2 FAST PCI Adapter (82G2675) + +pci:v00001014d00000020* + ID_PRODUCT_FROM_DATABASE=GXT1000 Graphics Adapter + +pci:v00001014d00000022* + ID_PRODUCT_FROM_DATABASE=PCI to PCI Bridge (IBM27-82351) + +pci:v00001014d0000002D* + ID_PRODUCT_FROM_DATABASE=Processor to I/O Controller [Python] + +pci:v00001014d0000002E* + ID_PRODUCT_FROM_DATABASE=SCSI RAID Adapter [ServeRAID] + +pci:v00001014d0000002Esv00001014sd0000002E* + ID_PRODUCT_FROM_DATABASE=ServeRAID-3x + +pci:v00001014d0000002Esv00001014sd0000022E* + ID_PRODUCT_FROM_DATABASE=ServeRAID-4H + +pci:v00001014d00000031* + ID_PRODUCT_FROM_DATABASE=2 Port Serial Adapter + +pci:v00001014d00000031sv00001014sd00000031* + ID_PRODUCT_FROM_DATABASE=2721 WAN IOA - 2 Port Sync Serial Adapter + +pci:v00001014d00000036* + ID_PRODUCT_FROM_DATABASE=PCI to 32-bit LocalBus Bridge [Miami] + +pci:v00001014d00000037* + ID_PRODUCT_FROM_DATABASE=PowerPC to PCI Bridge (IBM27-82660) + +pci:v00001014d0000003A* + ID_PRODUCT_FROM_DATABASE=CPU to PCI Bridge + +pci:v00001014d0000003C* + ID_PRODUCT_FROM_DATABASE=GXT250P/GXT255P Graphics Adapter + +pci:v00001014d0000003E* + ID_PRODUCT_FROM_DATABASE=16/4 Token ring UTP/STP controller + +pci:v00001014d0000003Esv00001014sd0000003E* + ID_PRODUCT_FROM_DATABASE=Token-Ring Adapter + +pci:v00001014d0000003Esv00001014sd000000CD* + ID_PRODUCT_FROM_DATABASE=Token-Ring Adapter + Wake-On-LAN + +pci:v00001014d0000003Esv00001014sd000000CE* + ID_PRODUCT_FROM_DATABASE=16/4 Token-Ring Adapter 2 + +pci:v00001014d0000003Esv00001014sd000000CF* + ID_PRODUCT_FROM_DATABASE=16/4 Token-Ring Adapter Special + +pci:v00001014d0000003Esv00001014sd000000E4* + ID_PRODUCT_FROM_DATABASE=High-Speed 100/16/4 Token-Ring Adapter + +pci:v00001014d0000003Esv00001014sd000000E5* + ID_PRODUCT_FROM_DATABASE=16/4 Token-Ring Adapter 2 + Wake-On-LAN + +pci:v00001014d0000003Esv00001014sd0000016D* + ID_PRODUCT_FROM_DATABASE=iSeries 2744 Card + +pci:v00001014d00000045* + ID_PRODUCT_FROM_DATABASE=SSA Adapter + +pci:v00001014d00000046* + ID_PRODUCT_FROM_DATABASE=MPIC interrupt controller + +pci:v00001014d00000047* + ID_PRODUCT_FROM_DATABASE=PCI to PCI Bridge + +pci:v00001014d00000048* + ID_PRODUCT_FROM_DATABASE=PCI to PCI Bridge + +pci:v00001014d00000049* + ID_PRODUCT_FROM_DATABASE=Warhead SCSI Controller + +pci:v00001014d0000004E* + ID_PRODUCT_FROM_DATABASE=ATM Controller (14104e00) + +pci:v00001014d0000004F* + ID_PRODUCT_FROM_DATABASE=ATM Controller (14104f00) + +pci:v00001014d00000050* + ID_PRODUCT_FROM_DATABASE=ATM Controller (14105000) + +pci:v00001014d00000053* + ID_PRODUCT_FROM_DATABASE=25 MBit ATM Controller + +pci:v00001014d00000054* + ID_PRODUCT_FROM_DATABASE=GXT500P/GXT550P Graphics Adapter + +pci:v00001014d00000057* + ID_PRODUCT_FROM_DATABASE=MPEG PCI Bridge + +pci:v00001014d00000058* + ID_PRODUCT_FROM_DATABASE=SSA Adapter [Advanced SerialRAID/X] + +pci:v00001014d0000005C* + ID_PRODUCT_FROM_DATABASE=i82557B 10/100 + +pci:v00001014d0000005E* + ID_PRODUCT_FROM_DATABASE=GXT800P Graphics Adapter + +pci:v00001014d0000007C* + ID_PRODUCT_FROM_DATABASE=ATM Controller (14107c00) + +pci:v00001014d0000007D* + ID_PRODUCT_FROM_DATABASE=3780IDSP [MWave] + +pci:v00001014d0000008B* + ID_PRODUCT_FROM_DATABASE=EADS PCI to PCI Bridge + +pci:v00001014d0000008E* + ID_PRODUCT_FROM_DATABASE=GXT3000P Graphics Adapter + +pci:v00001014d00000090* + ID_PRODUCT_FROM_DATABASE=GXT 3000P + +pci:v00001014d00000090sv00001014sd0000008E* + ID_PRODUCT_FROM_DATABASE=GXT-3000P + +pci:v00001014d00000091* + ID_PRODUCT_FROM_DATABASE=SSA Adapter + +pci:v00001014d00000095* + ID_PRODUCT_FROM_DATABASE=20H2999 PCI Docking Bridge + +pci:v00001014d00000096* + ID_PRODUCT_FROM_DATABASE=Chukar chipset SCSI controller + +pci:v00001014d00000096sv00001014sd00000097* + ID_PRODUCT_FROM_DATABASE=iSeries 2778 DASD IOA + +pci:v00001014d00000096sv00001014sd00000098* + ID_PRODUCT_FROM_DATABASE=iSeries 2763 DASD IOA + +pci:v00001014d00000096sv00001014sd00000099* + ID_PRODUCT_FROM_DATABASE=iSeries 2748 DASD IOA + +pci:v00001014d0000009F* + ID_PRODUCT_FROM_DATABASE=PCI 4758 Cryptographic Accelerator + +pci:v00001014d000000A5* + ID_PRODUCT_FROM_DATABASE=ATM Controller (1410a500) + +pci:v00001014d000000A6* + ID_PRODUCT_FROM_DATABASE=ATM 155MBPS MM Controller (1410a600) + +pci:v00001014d000000B7* + ID_PRODUCT_FROM_DATABASE=256-bit Graphics Rasterizer [FireGL1] + +pci:v00001014d000000B7sv00001092sd000000B8* + ID_PRODUCT_FROM_DATABASE=FireGL1 AGP 32Mb + +pci:v00001014d000000B8* + ID_PRODUCT_FROM_DATABASE=GXT2000P Graphics Adapter + +pci:v00001014d000000BE* + ID_PRODUCT_FROM_DATABASE=ATM 622MBPS Controller (1410be00) + +pci:v00001014d000000DC* + ID_PRODUCT_FROM_DATABASE=Advanced Systems Management Adapter (ASMA) + +pci:v00001014d000000FC* + ID_PRODUCT_FROM_DATABASE=CPC710 Dual Bridge and Memory Controller (PCI-64) + +pci:v00001014d00000104* + ID_PRODUCT_FROM_DATABASE=Gigabit Ethernet-SX Adapter + +pci:v00001014d00000105* + ID_PRODUCT_FROM_DATABASE=CPC710 Dual Bridge and Memory Controller (PCI-32) + +pci:v00001014d0000010F* + ID_PRODUCT_FROM_DATABASE=Remote Supervisor Adapter (RSA) + +pci:v00001014d00000142* + ID_PRODUCT_FROM_DATABASE=Yotta Video Compositor Input + +pci:v00001014d00000142sv00001014sd00000143* + ID_PRODUCT_FROM_DATABASE=Yotta Input Controller (ytin) + +pci:v00001014d00000144* + ID_PRODUCT_FROM_DATABASE=Yotta Video Compositor Output + +pci:v00001014d00000144sv00001014sd00000145* + ID_PRODUCT_FROM_DATABASE=Yotta Output Controller (ytout) + +pci:v00001014d00000156* + ID_PRODUCT_FROM_DATABASE=405GP PLB to PCI Bridge + +pci:v00001014d0000015E* + ID_PRODUCT_FROM_DATABASE=622Mbps ATM PCI Adapter + +pci:v00001014d00000160* + ID_PRODUCT_FROM_DATABASE=64bit/66MHz PCI ATM 155 MMF + +pci:v00001014d0000016E* + ID_PRODUCT_FROM_DATABASE=GXT4000P Graphics Adapter + +pci:v00001014d00000170* + ID_PRODUCT_FROM_DATABASE=GXT6000P Graphics Adapter + +pci:v00001014d0000017D* + ID_PRODUCT_FROM_DATABASE=GXT300P Graphics Adapter + +pci:v00001014d00000180* + ID_PRODUCT_FROM_DATABASE=Snipe chipset SCSI controller + +pci:v00001014d00000180sv00001014sd00000241* + ID_PRODUCT_FROM_DATABASE=iSeries 2757 DASD IOA + +pci:v00001014d00000180sv00001014sd00000264* + ID_PRODUCT_FROM_DATABASE=Quad Channel PCI-X U320 SCSI RAID Adapter (2780) + +pci:v00001014d00000188* + ID_PRODUCT_FROM_DATABASE=EADS-X PCI-X to PCI-X Bridge + +pci:v00001014d000001A7* + ID_PRODUCT_FROM_DATABASE=PCI-X to PCI-X Bridge + +pci:v00001014d000001BD* + ID_PRODUCT_FROM_DATABASE=ServeRAID Controller + +pci:v00001014d000001BDsv00001014sd000001BD* + ID_PRODUCT_FROM_DATABASE=ServeRAID 4Lx + +pci:v00001014d000001BDsv00001014sd000001BE* + ID_PRODUCT_FROM_DATABASE=ServeRAID-4M + +pci:v00001014d000001BDsv00001014sd000001BF* + ID_PRODUCT_FROM_DATABASE=ServeRAID-4L + +pci:v00001014d000001BDsv00001014sd00000208* + ID_PRODUCT_FROM_DATABASE=ServeRAID-4Mx + +pci:v00001014d000001BDsv00001014sd0000020E* + ID_PRODUCT_FROM_DATABASE=ServeRAID-4Lx + +pci:v00001014d000001BDsv00001014sd0000022E* + ID_PRODUCT_FROM_DATABASE=ServeRAID-4H + +pci:v00001014d000001BDsv00001014sd00000258* + ID_PRODUCT_FROM_DATABASE=ServeRAID-5i + +pci:v00001014d000001BDsv00001014sd00000259* + ID_PRODUCT_FROM_DATABASE=ServeRAID-5i + +pci:v00001014d000001C1* + ID_PRODUCT_FROM_DATABASE=64bit/66MHz PCI ATM 155 UTP + +pci:v00001014d000001E6* + ID_PRODUCT_FROM_DATABASE=Cryptographic Accelerator + +pci:v00001014d000001EF* + ID_PRODUCT_FROM_DATABASE=PowerPC 440GP PCI Bridge + +pci:v00001014d000001EFsv00001734sd0000102B* + ID_PRODUCT_FROM_DATABASE=PCEAS PCI-X Dual Port ESCON Adapter + +pci:v00001014d000001EFsv00001734sd000010F8* + ID_PRODUCT_FROM_DATABASE=PCEAT PCI-Express Dual Port ESCON Adapter + +pci:v00001014d000001FF* + ID_PRODUCT_FROM_DATABASE=10/100 Mbps Ethernet + +pci:v00001014d00000219* + ID_PRODUCT_FROM_DATABASE=Multiport Serial Adapter + +pci:v00001014d00000219sv00001014sd0000021A* + ID_PRODUCT_FROM_DATABASE=Dual RVX + +pci:v00001014d00000219sv00001014sd00000251* + ID_PRODUCT_FROM_DATABASE=Internal Modem/RVX + +pci:v00001014d00000219sv00001014sd00000252* + ID_PRODUCT_FROM_DATABASE=Quad Internal Modem + +pci:v00001014d0000021B* + ID_PRODUCT_FROM_DATABASE=GXT6500P Graphics Adapter + +pci:v00001014d0000021C* + ID_PRODUCT_FROM_DATABASE=GXT4500P Graphics Adapter + +pci:v00001014d00000233* + ID_PRODUCT_FROM_DATABASE=GXT135P Graphics Adapter + +pci:v00001014d00000266* + ID_PRODUCT_FROM_DATABASE=PCI-X Dual Channel SCSI + +pci:v00001014d00000268* + ID_PRODUCT_FROM_DATABASE=Gigabit Ethernet-SX Adapter (PCI-X) + +pci:v00001014d00000269* + ID_PRODUCT_FROM_DATABASE=10/100/1000 Base-TX Ethernet Adapter (PCI-X) + +pci:v00001014d0000028C* + ID_PRODUCT_FROM_DATABASE=Citrine chipset SCSI controller + +pci:v00001014d0000028Csv00001014sd0000028D* + ID_PRODUCT_FROM_DATABASE=Dual Channel PCI-X DDR SAS RAID Adapter (572E) + +pci:v00001014d0000028Csv00001014sd000002BE* + ID_PRODUCT_FROM_DATABASE=Dual Channel PCI-X DDR U320 SCSI RAID Adapter (571B) + +pci:v00001014d0000028Csv00001014sd000002C0* + ID_PRODUCT_FROM_DATABASE=Dual Channel PCI-X DDR U320 SCSI Adapter (571A) + +pci:v00001014d0000028Csv00001014sd0000030D* + ID_PRODUCT_FROM_DATABASE=PCI-X DDR Auxiliary Cache Adapter (575B) + +pci:v00001014d000002A1* + ID_PRODUCT_FROM_DATABASE=Calgary PCI-X Host Bridge + +pci:v00001014d000002BD* + ID_PRODUCT_FROM_DATABASE=Obsidian chipset SCSI controller + +pci:v00001014d000002BDsv00001014sd000002C1* + ID_PRODUCT_FROM_DATABASE=PCI-X DDR 3Gb SAS Adapter (572A/572C) + +pci:v00001014d000002BDsv00001014sd000002C2* + ID_PRODUCT_FROM_DATABASE=PCI-X DDR 3Gb SAS RAID Adapter (572B/571D) + +pci:v00001014d000002BDsv00001014sd00000338* + ID_PRODUCT_FROM_DATABASE=PCI-X DDR Auxiliary Cache Adapter (575C) + +pci:v00001014d00000302* + ID_PRODUCT_FROM_DATABASE=Winnipeg PCI-X Host Bridge + +pci:v00001014d00000308* + ID_PRODUCT_FROM_DATABASE=CalIOC2 PCI-E Root Port + +pci:v00001014d00000314* + ID_PRODUCT_FROM_DATABASE=ZISC 036 Neural accelerator card + +pci:v00001014d0000032D* + ID_PRODUCT_FROM_DATABASE=Axon - Cell Companion Chip + +pci:v00001014d0000032Dsv00001014sd000003A1* + ID_PRODUCT_FROM_DATABASE=PCIe PowerXCell 8i Cell Accelerator Board + +pci:v00001014d00000339* + ID_PRODUCT_FROM_DATABASE=Obsidian-E PCI-E SCSI controller + +pci:v00001014d00000339sv00001014sd0000030A* + ID_PRODUCT_FROM_DATABASE=PCIe 3Gb SAS RAID Adapter (574E) + +pci:v00001014d00000339sv00001014sd0000033A* + ID_PRODUCT_FROM_DATABASE=PCIe 3Gb SAS Adapter (57B3) + +pci:v00001014d00000339sv00001014sd0000035C* + ID_PRODUCT_FROM_DATABASE=PCIe x8 Internal 3Gb SAS adapter (57CC) + +pci:v00001014d00000339sv00001014sd00000360* + ID_PRODUCT_FROM_DATABASE=PCI-E Auxiliary Cache Adapter (57B7) + +pci:v00001014d0000033D* + ID_PRODUCT_FROM_DATABASE=PCI-E IPR SAS Adapter (FPGA) + +pci:v00001014d0000033Dsv00001014sd0000033C* + ID_PRODUCT_FROM_DATABASE=PCIe2 1.8GB Cache 6Gb SAS RAID Adapter Tri-port (57B5) + +pci:v00001014d0000033Dsv00001014sd00000353* + ID_PRODUCT_FROM_DATABASE=PCIe2 3.1GB Cache 6Gb SAS RAID Enclosure (57C3) + +pci:v00001014d0000033Dsv00001014sd00000354* + ID_PRODUCT_FROM_DATABASE=PCIe2 6Gb SAS Adapter Dual-port (57C4) + +pci:v00001014d0000033Dsv00001014sd00000356* + ID_PRODUCT_FROM_DATABASE=PCIe2 1.8GB Cache 6Gb SAS RAID & SSD Adapter (574D) + +pci:v00001014d0000033Dsv00001014sd0000035F* + ID_PRODUCT_FROM_DATABASE=PCIe2 6Gb SAS Adapter Quad-port (57B2) + +pci:v00001014d0000034A* + ID_PRODUCT_FROM_DATABASE=PCI-E IPR SAS Adapter (ASIC) + +pci:v00001014d0000034Asv00001014sd0000033B* + ID_PRODUCT_FROM_DATABASE=PCIe2 6Gb SAS RAID Adapter Quad-port (57B4) + +pci:v00001014d0000034Asv00001014sd00000355* + ID_PRODUCT_FROM_DATABASE=PCIe2 3.6GB Cache 6Gb SAS RAID Adapter Quad-port (57B1) + +pci:v00001014d0000034Asv00001014sd00000357* + ID_PRODUCT_FROM_DATABASE=PCIe2 6Gb SAS Adapter Quad-port (57C6) + +pci:v00001014d0000034Asv00001014sd0000035D* + ID_PRODUCT_FROM_DATABASE=PCIe3 1.8GB Cache RAID SAS Adapter Quad-port 6GB (57C8) + +pci:v00001014d0000034Asv00001014sd0000035E* + ID_PRODUCT_FROM_DATABASE=PCIe2 3.6GB Cache 6Gb SAS RAID Adapter Quad-port (57CE) + +pci:v00001014d0000034Asv00001014sd000003FB* + ID_PRODUCT_FROM_DATABASE=PCIe3 28GB Cache RAID SAS Enclosure 6Gb x 16 (57D5) + +pci:v00001014d00003022* + ID_PRODUCT_FROM_DATABASE=QLA3022 Network Adapter + +pci:v00001014d00004022* + ID_PRODUCT_FROM_DATABASE=QLA3022 Network Adapter + +pci:v00001014d0000FFFF* + ID_PRODUCT_FROM_DATABASE=MPIC-2 interrupt controller + +pci:v00001015* + ID_VENDOR_FROM_DATABASE=LSI Logic Corp of Canada + +pci:v00001016* + ID_VENDOR_FROM_DATABASE=ICL Personal Systems + +pci:v00001017* + ID_VENDOR_FROM_DATABASE=SPEA Software AG + +pci:v00001017d00005343* + ID_PRODUCT_FROM_DATABASE=SPEA 3D Accelerator + +pci:v00001018* + ID_VENDOR_FROM_DATABASE=Unisys Systems + +pci:v00001019* + ID_VENDOR_FROM_DATABASE=Elitegroup Computer Systems + +pci:v0000101A* + ID_VENDOR_FROM_DATABASE=AT&T GIS (NCR) + +pci:v0000101Ad00000005* + ID_PRODUCT_FROM_DATABASE=100VG ethernet + +pci:v0000101Ad00000007* + ID_PRODUCT_FROM_DATABASE=BYNET BIC4G/2C/2G + +pci:v0000101Ad00000007sv0000101Asd00000019* + ID_PRODUCT_FROM_DATABASE=BYNET BIC2C + +pci:v0000101Ad00000007sv0000101Asd0000001C* + ID_PRODUCT_FROM_DATABASE=BYNET BIC2G + +pci:v0000101Ad00000007sv0000101Asd0000001F* + ID_PRODUCT_FROM_DATABASE=BYNET BIC4G + +pci:v0000101Ad00000009* + ID_PRODUCT_FROM_DATABASE=PQS Memory Controller + +pci:v0000101Ad0000000A* + ID_PRODUCT_FROM_DATABASE=BYNET BPCI Adapter + +pci:v0000101Ad0000000B* + ID_PRODUCT_FROM_DATABASE=BYNET 4 Port BYA Switch (BYA4P) + +pci:v0000101Ad0000000C* + ID_PRODUCT_FROM_DATABASE=BYNET 4 Port BYA Switch (BYA4G) + +pci:v0000101Ad00000010* + ID_PRODUCT_FROM_DATABASE=NCR AMC Memory Controller + +pci:v0000101Ad00001DC1* + ID_PRODUCT_FROM_DATABASE=BYNET BIC2M/BIC4M/BYA4M + +pci:v0000101Ad00001DC1sv0000101Asd00000019* + ID_PRODUCT_FROM_DATABASE=BIC2M + +pci:v0000101Ad00001DC1sv0000101Asd0000001F* + ID_PRODUCT_FROM_DATABASE=BIC4M + +pci:v0000101Ad00001DC1sv0000101Asd00000ECE* + ID_PRODUCT_FROM_DATABASE=BYA4M + +pci:v0000101Ad00001FA8* + ID_PRODUCT_FROM_DATABASE=BYNET Multi-port BIC Adapter (XBIC Based) + +pci:v0000101Ad00001FA8sv0000101Asd000000C3* + ID_PRODUCT_FROM_DATABASE=BYNET BIC2SE + +pci:v0000101B* + ID_VENDOR_FROM_DATABASE=Vitesse Semiconductor + +pci:v0000101Bd00000452* + ID_PRODUCT_FROM_DATABASE=VSC452 [SuperBMC] + +pci:v0000101C* + ID_VENDOR_FROM_DATABASE=Western Digital + +pci:v0000101Cd00000193* + ID_PRODUCT_FROM_DATABASE=33C193A + +pci:v0000101Cd00000196* + ID_PRODUCT_FROM_DATABASE=33C196A + +pci:v0000101Cd00000197* + ID_PRODUCT_FROM_DATABASE=33C197A + +pci:v0000101Cd00000296* + ID_PRODUCT_FROM_DATABASE=33C296A + +pci:v0000101Cd00003193* + ID_PRODUCT_FROM_DATABASE=7193 + +pci:v0000101Cd00003197* + ID_PRODUCT_FROM_DATABASE=7197 + +pci:v0000101Cd00003296* + ID_PRODUCT_FROM_DATABASE=33C296A + +pci:v0000101Cd00004296* + ID_PRODUCT_FROM_DATABASE=34C296 + +pci:v0000101Cd00009710* + ID_PRODUCT_FROM_DATABASE=Pipeline 9710 + +pci:v0000101Cd00009712* + ID_PRODUCT_FROM_DATABASE=Pipeline 9712 + +pci:v0000101Cd0000C24A* + ID_PRODUCT_FROM_DATABASE=90C + +pci:v0000101D* + ID_VENDOR_FROM_DATABASE=Maxim Integrated Products + +pci:v0000101E* + ID_VENDOR_FROM_DATABASE=American Megatrends Inc. + +pci:v0000101Ed00000009* + ID_PRODUCT_FROM_DATABASE=MegaRAID 428 Ultra RAID Controller (rev 03) + +pci:v0000101Ed00001960* + ID_PRODUCT_FROM_DATABASE=MegaRAID + +pci:v0000101Ed00001960sv0000101Esd00000471* + ID_PRODUCT_FROM_DATABASE=MegaRAID 471 Enterprise 1600 RAID Controller + +pci:v0000101Ed00001960sv0000101Esd00000475* + ID_PRODUCT_FROM_DATABASE=MegaRAID 475 Express 500/500LC RAID Controller + +pci:v0000101Ed00001960sv0000101Esd00000477* + ID_PRODUCT_FROM_DATABASE=MegaRAID 477 Elite 3100 RAID Controller + +pci:v0000101Ed00001960sv0000101Esd00000493* + ID_PRODUCT_FROM_DATABASE=MegaRAID 493 Elite 1600 RAID Controller + +pci:v0000101Ed00001960sv0000101Esd00000494* + ID_PRODUCT_FROM_DATABASE=MegaRAID 494 Elite 1650 RAID Controller + +pci:v0000101Ed00001960sv0000101Esd00000503* + ID_PRODUCT_FROM_DATABASE=MegaRAID 503 Enterprise 1650 RAID Controller + +pci:v0000101Ed00001960sv0000101Esd00000511* + ID_PRODUCT_FROM_DATABASE=MegaRAID 511 i4 IDE RAID Controller + +pci:v0000101Ed00001960sv0000101Esd00000522* + ID_PRODUCT_FROM_DATABASE=MegaRAID 522 i4133 RAID Controller + +pci:v0000101Ed00001960sv00001028sd00000471* + ID_PRODUCT_FROM_DATABASE=PowerEdge RAID Controller 3/QC + +pci:v0000101Ed00001960sv00001028sd00000475* + ID_PRODUCT_FROM_DATABASE=PowerEdge RAID Controller 3/SC + +pci:v0000101Ed00001960sv00001028sd00000493* + ID_PRODUCT_FROM_DATABASE=PowerEdge RAID Controller 3/DC + +pci:v0000101Ed00001960sv00001028sd00000511* + ID_PRODUCT_FROM_DATABASE=PowerEdge Cost Effective RAID Controller ATA100/4Ch + +pci:v0000101Ed00001960sv0000103Csd000060E7* + ID_PRODUCT_FROM_DATABASE=NetRAID-1M + +pci:v0000101Ed00009010* + ID_PRODUCT_FROM_DATABASE=MegaRAID 428 Ultra RAID Controller + +pci:v0000101Ed00009030* + ID_PRODUCT_FROM_DATABASE=EIDE Controller + +pci:v0000101Ed00009031* + ID_PRODUCT_FROM_DATABASE=EIDE Controller + +pci:v0000101Ed00009032* + ID_PRODUCT_FROM_DATABASE=EIDE & SCSI Controller + +pci:v0000101Ed00009033* + ID_PRODUCT_FROM_DATABASE=SCSI Controller + +pci:v0000101Ed00009040* + ID_PRODUCT_FROM_DATABASE=Multimedia card + +pci:v0000101Ed00009060* + ID_PRODUCT_FROM_DATABASE=MegaRAID 434 Ultra GT RAID Controller + +pci:v0000101Ed00009063* + ID_PRODUCT_FROM_DATABASE=MegaRAC + +pci:v0000101Ed00009063sv0000101Esd00000767* + ID_PRODUCT_FROM_DATABASE=Dell Remote Assistant Card 2 + +pci:v0000101F* + ID_VENDOR_FROM_DATABASE=PictureTel + +pci:v00001020* + ID_VENDOR_FROM_DATABASE=Hitachi Computer Products + +pci:v00001021* + ID_VENDOR_FROM_DATABASE=OKI Electric Industry Co. Ltd. + +pci:v00001022* + ID_VENDOR_FROM_DATABASE=Advanced Micro Devices [AMD] + +pci:v00001022d00001100* + ID_PRODUCT_FROM_DATABASE=K8 [Athlon64/Opteron] HyperTransport Technology Configuration + +pci:v00001022d00001101* + ID_PRODUCT_FROM_DATABASE=K8 [Athlon64/Opteron] Address Map + +pci:v00001022d00001102* + ID_PRODUCT_FROM_DATABASE=K8 [Athlon64/Opteron] DRAM Controller + +pci:v00001022d00001103* + ID_PRODUCT_FROM_DATABASE=K8 [Athlon64/Opteron] Miscellaneous Control + +pci:v00001022d00001200* + ID_PRODUCT_FROM_DATABASE=Family 10h Processor HyperTransport Configuration + +pci:v00001022d00001201* + ID_PRODUCT_FROM_DATABASE=Family 10h Processor Address Map + +pci:v00001022d00001202* + ID_PRODUCT_FROM_DATABASE=Family 10h Processor DRAM Controller + +pci:v00001022d00001203* + ID_PRODUCT_FROM_DATABASE=Family 10h Processor Miscellaneous Control + +pci:v00001022d00001204* + ID_PRODUCT_FROM_DATABASE=Family 10h Processor Link Control + +pci:v00001022d00001300* + ID_PRODUCT_FROM_DATABASE=Family 11h Processor HyperTransport Configuration + +pci:v00001022d00001301* + ID_PRODUCT_FROM_DATABASE=Family 11h Processor Address Map + +pci:v00001022d00001302* + ID_PRODUCT_FROM_DATABASE=Family 11h Processor DRAM Controller + +pci:v00001022d00001303* + ID_PRODUCT_FROM_DATABASE=Family 11h Processor Miscellaneous Control + +pci:v00001022d00001304* + ID_PRODUCT_FROM_DATABASE=Family 11h Processor Link Control + +pci:v00001022d00001400* + ID_PRODUCT_FROM_DATABASE=Family 15h (Models 10h-1fh) Processor Function 0 + +pci:v00001022d00001401* + ID_PRODUCT_FROM_DATABASE=Family 15h (Models 10h-1fh) Processor Function 1 + +pci:v00001022d00001402* + ID_PRODUCT_FROM_DATABASE=Family 15h (Models 10h-1fh) Processor Function 2 + +pci:v00001022d00001403* + ID_PRODUCT_FROM_DATABASE=Family 15h (Models 10h-1fh) Processor Function 3 + +pci:v00001022d00001404* + ID_PRODUCT_FROM_DATABASE=Family 15h (Models 10h-1fh) Processor Function 4 + +pci:v00001022d00001405* + ID_PRODUCT_FROM_DATABASE=Family 15h (Models 10h-1fh) Processor Function 5 + +pci:v00001022d00001410* + ID_PRODUCT_FROM_DATABASE=Family 15h (Models 10h-1fh) Processor Root Complex + +pci:v00001022d00001412* + ID_PRODUCT_FROM_DATABASE=Family 15h (Models 10h-1fh) Processor Root Port + +pci:v00001022d00001413* + ID_PRODUCT_FROM_DATABASE=Family 15h (Models 10h-1fh) Processor Root Port + +pci:v00001022d00001414* + ID_PRODUCT_FROM_DATABASE=Family 15h (Models 10h-1fh) Processor Root Port + +pci:v00001022d00001415* + ID_PRODUCT_FROM_DATABASE=Family 15h (Models 10h-1fh) Processor Root Port + +pci:v00001022d00001416* + ID_PRODUCT_FROM_DATABASE=Family 15h (Models 10h-1fh) Processor Root Port + +pci:v00001022d00001417* + ID_PRODUCT_FROM_DATABASE=Family 15h (Models 10h-1fh) Processor Root Port + +pci:v00001022d00001418* + ID_PRODUCT_FROM_DATABASE=Family 15h (Models 10h-1fh) Processor Root Port + +pci:v00001022d00001419* + ID_PRODUCT_FROM_DATABASE=Family 15h (Models 10h-1fh) I/O Memory Management Unit + +pci:v00001022d00001439* + ID_PRODUCT_FROM_DATABASE=Family 16h Processor Functions 5:1 + +pci:v00001022d00001510* + ID_PRODUCT_FROM_DATABASE=Family 14h Processor Root Complex + +pci:v00001022d00001510sv0000174Bsd00001001* + ID_PRODUCT_FROM_DATABASE=Sapphire PURE Fusion Mini + +pci:v00001022d00001512* + ID_PRODUCT_FROM_DATABASE=Family 14h Processor Root Port + +pci:v00001022d00001512sv0000174Bsd00001001* + ID_PRODUCT_FROM_DATABASE=Sapphire PURE Fusion Mini + +pci:v00001022d00001513* + ID_PRODUCT_FROM_DATABASE=Family 14h Processor Root Port + +pci:v00001022d00001514* + ID_PRODUCT_FROM_DATABASE=Family 14h Processor Root Port + +pci:v00001022d00001515* + ID_PRODUCT_FROM_DATABASE=Family 14h Processor Root Port + +pci:v00001022d00001516* + ID_PRODUCT_FROM_DATABASE=Family 14h Processor Root Port + +pci:v00001022d00001530* + ID_PRODUCT_FROM_DATABASE=Family 16h Processor Function 0 + +pci:v00001022d00001531* + ID_PRODUCT_FROM_DATABASE=Family 16h Processor Function 1 + +pci:v00001022d00001532* + ID_PRODUCT_FROM_DATABASE=Family 16h Processor Function 2 + +pci:v00001022d00001533* + ID_PRODUCT_FROM_DATABASE=Family 16h Processor Function 3 + +pci:v00001022d00001534* + ID_PRODUCT_FROM_DATABASE=Family 16h Processor Function 4 + +pci:v00001022d00001535* + ID_PRODUCT_FROM_DATABASE=Family 16h Processor Function 5 + +pci:v00001022d00001536* + ID_PRODUCT_FROM_DATABASE=Family 16h Processor Root Complex + +pci:v00001022d00001538* + ID_PRODUCT_FROM_DATABASE=Family 16h Processor Function 0 + +pci:v00001022d00001600* + ID_PRODUCT_FROM_DATABASE=Family 15h Processor Function 0 + +pci:v00001022d00001601* + ID_PRODUCT_FROM_DATABASE=Family 15h Processor Function 1 + +pci:v00001022d00001602* + ID_PRODUCT_FROM_DATABASE=Family 15h Processor Function 2 + +pci:v00001022d00001603* + ID_PRODUCT_FROM_DATABASE=Family 15h Processor Function 3 + +pci:v00001022d00001604* + ID_PRODUCT_FROM_DATABASE=Family 15h Processor Function 4 + +pci:v00001022d00001605* + ID_PRODUCT_FROM_DATABASE=Family 15h Processor Function 5 + +pci:v00001022d00001700* + ID_PRODUCT_FROM_DATABASE=Family 12h/14h Processor Function 0 + +pci:v00001022d00001701* + ID_PRODUCT_FROM_DATABASE=Family 12h/14h Processor Function 1 + +pci:v00001022d00001702* + ID_PRODUCT_FROM_DATABASE=Family 12h/14h Processor Function 2 + +pci:v00001022d00001703* + ID_PRODUCT_FROM_DATABASE=Family 12h/14h Processor Function 3 + +pci:v00001022d00001704* + ID_PRODUCT_FROM_DATABASE=Family 12h/14h Processor Function 4 + +pci:v00001022d00001705* + ID_PRODUCT_FROM_DATABASE=Family 12h Processor Root Complex + +pci:v00001022d00001707* + ID_PRODUCT_FROM_DATABASE=Family 12h Processor Root Port + +pci:v00001022d00001708* + ID_PRODUCT_FROM_DATABASE=Family 12h Processor Root Port + +pci:v00001022d00001709* + ID_PRODUCT_FROM_DATABASE=Family 12h Processor Root Port + +pci:v00001022d0000170A* + ID_PRODUCT_FROM_DATABASE=Family 12h Processor Root Port + +pci:v00001022d0000170B* + ID_PRODUCT_FROM_DATABASE=Family 12h Processor Root Port + +pci:v00001022d0000170C* + ID_PRODUCT_FROM_DATABASE=Family 12h Processor Root Port + +pci:v00001022d0000170D* + ID_PRODUCT_FROM_DATABASE=Family 12h Processor Root Port + +pci:v00001022d00001716* + ID_PRODUCT_FROM_DATABASE=Family 12h/14h Processor Function 5 + +pci:v00001022d00001718* + ID_PRODUCT_FROM_DATABASE=Family 12h/14h Processor Function 6 + +pci:v00001022d00001719* + ID_PRODUCT_FROM_DATABASE=Family 12h/14h Processor Function 7 + +pci:v00001022d00002000* + ID_PRODUCT_FROM_DATABASE=79c970 [PCnet32 LANCE] + +pci:v00001022d00002000sv00001014sd00002000* + ID_PRODUCT_FROM_DATABASE=NetFinity 10/100 Fast Ethernet + +pci:v00001022d00002000sv00001022sd00002000* + ID_PRODUCT_FROM_DATABASE=PCnet - Fast 79C971 + +pci:v00001022d00002000sv0000103Csd0000104C* + ID_PRODUCT_FROM_DATABASE=Ethernet with LAN remote power Adapter + +pci:v00001022d00002000sv0000103Csd00001064* + ID_PRODUCT_FROM_DATABASE=Ethernet with LAN remote power Adapter + +pci:v00001022d00002000sv0000103Csd00001065* + ID_PRODUCT_FROM_DATABASE=Ethernet with LAN remote power Adapter + +pci:v00001022d00002000sv0000103Csd0000106C* + ID_PRODUCT_FROM_DATABASE=Ethernet with LAN remote power Adapter + +pci:v00001022d00002000sv0000103Csd0000106E* + ID_PRODUCT_FROM_DATABASE=Ethernet with LAN remote power Adapter + +pci:v00001022d00002000sv0000103Csd000010EA* + ID_PRODUCT_FROM_DATABASE=Ethernet with LAN remote power Adapter + +pci:v00001022d00002000sv00001113sd00001220* + ID_PRODUCT_FROM_DATABASE=EN1220 10/100 Fast Ethernet + +pci:v00001022d00002000sv00001259sd00002450* + ID_PRODUCT_FROM_DATABASE=AT-2450 10/100 Fast Ethernet + +pci:v00001022d00002000sv00001259sd00002454* + ID_PRODUCT_FROM_DATABASE=AT-2450v4 10Mb Ethernet Adapter + +pci:v00001022d00002000sv00001259sd00002700* + ID_PRODUCT_FROM_DATABASE=AT-2700TX 10/100 Fast Ethernet + +pci:v00001022d00002000sv00001259sd00002701* + ID_PRODUCT_FROM_DATABASE=AT-2700FX 100Mb Ethernet + +pci:v00001022d00002000sv00001259sd00002702* + ID_PRODUCT_FROM_DATABASE=AT-2700FTX 10/100 Mb Fiber/Copper Fast Ethernet + +pci:v00001022d00002000sv00001259sd00002703* + ID_PRODUCT_FROM_DATABASE=AT-2701FX + +pci:v00001022d00002000sv00001259sd00002704* + ID_PRODUCT_FROM_DATABASE=AT-2701FTX 10/100 Mb Fiber/Copper Fast Ethernet + +pci:v00001022d00002000sv00004C53sd00001000* + ID_PRODUCT_FROM_DATABASE=CC7/CR7/CP7/VC7/VP7/VR7 mainboard + +pci:v00001022d00002000sv00004C53sd00001010* + ID_PRODUCT_FROM_DATABASE=CP5/CR6 mainboard + +pci:v00001022d00002000sv00004C53sd00001020* + ID_PRODUCT_FROM_DATABASE=VR6 mainboard + +pci:v00001022d00002000sv00004C53sd00001030* + ID_PRODUCT_FROM_DATABASE=PC5 mainboard + +pci:v00001022d00002000sv00004C53sd00001040* + ID_PRODUCT_FROM_DATABASE=CL7 mainboard + +pci:v00001022d00002000sv00004C53sd00001060* + ID_PRODUCT_FROM_DATABASE=PC7 mainboard + +pci:v00001022d00002001* + ID_PRODUCT_FROM_DATABASE=79c978 [HomePNA] + +pci:v00001022d00002001sv00001092sd00000A78* + ID_PRODUCT_FROM_DATABASE=Multimedia Home Network Adapter + +pci:v00001022d00002001sv00001668sd00000299* + ID_PRODUCT_FROM_DATABASE=ActionLink Home Network Adapter + +pci:v00001022d00002003* + ID_PRODUCT_FROM_DATABASE=Am 1771 MBW [Alchemy] + +pci:v00001022d00002020* + ID_PRODUCT_FROM_DATABASE=53c974 [PCscsi] + +pci:v00001022d00002040* + ID_PRODUCT_FROM_DATABASE=79c974 + +pci:v00001022d00002080* + ID_PRODUCT_FROM_DATABASE=CS5536 [Geode companion] Host Bridge + +pci:v00001022d00002081* + ID_PRODUCT_FROM_DATABASE=Geode LX Video + +pci:v00001022d00002082* + ID_PRODUCT_FROM_DATABASE=Geode LX AES Security Block + +pci:v00001022d0000208F* + ID_PRODUCT_FROM_DATABASE=CS5536 GeodeLink PCI South Bridge + +pci:v00001022d00002090* + ID_PRODUCT_FROM_DATABASE=CS5536 [Geode companion] ISA + +pci:v00001022d00002091* + ID_PRODUCT_FROM_DATABASE=CS5536 [Geode companion] FLASH + +pci:v00001022d00002093* + ID_PRODUCT_FROM_DATABASE=CS5536 [Geode companion] Audio + +pci:v00001022d00002094* + ID_PRODUCT_FROM_DATABASE=CS5536 [Geode companion] OHC + +pci:v00001022d00002095* + ID_PRODUCT_FROM_DATABASE=CS5536 [Geode companion] EHC + +pci:v00001022d00002096* + ID_PRODUCT_FROM_DATABASE=CS5536 [Geode companion] UDC + +pci:v00001022d00002097* + ID_PRODUCT_FROM_DATABASE=CS5536 [Geode companion] UOC + +pci:v00001022d0000209A* + ID_PRODUCT_FROM_DATABASE=CS5536 [Geode companion] IDE + +pci:v00001022d00003000* + ID_PRODUCT_FROM_DATABASE=ELanSC520 Microcontroller + +pci:v00001022d000043A0* + ID_PRODUCT_FROM_DATABASE=Hudson PCI to PCI bridge (PCIE port 0) + +pci:v00001022d000043A1* + ID_PRODUCT_FROM_DATABASE=Hudson PCI to PCI bridge (PCIE port 1) + +pci:v00001022d000043A2* + ID_PRODUCT_FROM_DATABASE=Hudson PCI to PCI bridge (PCIE port 2) + +pci:v00001022d000043A3* + ID_PRODUCT_FROM_DATABASE=Hudson PCI to PCI bridge (PCIE port 3) + +pci:v00001022d00007006* + ID_PRODUCT_FROM_DATABASE=AMD-751 [Irongate] System Controller + +pci:v00001022d00007007* + ID_PRODUCT_FROM_DATABASE=AMD-751 [Irongate] AGP Bridge + +pci:v00001022d0000700A* + ID_PRODUCT_FROM_DATABASE=AMD-IGR4 AGP Host to PCI Bridge + +pci:v00001022d0000700B* + ID_PRODUCT_FROM_DATABASE=AMD-IGR4 PCI to PCI Bridge + +pci:v00001022d0000700C* + ID_PRODUCT_FROM_DATABASE=AMD-760 MP [IGD4-2P] System Controller + +pci:v00001022d0000700D* + ID_PRODUCT_FROM_DATABASE=AMD-760 MP [IGD4-2P] AGP Bridge + +pci:v00001022d0000700E* + ID_PRODUCT_FROM_DATABASE=AMD-760 [IGD4-1P] System Controller + +pci:v00001022d0000700F* + ID_PRODUCT_FROM_DATABASE=AMD-760 [IGD4-1P] AGP Bridge + +pci:v00001022d00007400* + ID_PRODUCT_FROM_DATABASE=AMD-755 [Cobra] ISA + +pci:v00001022d00007401* + ID_PRODUCT_FROM_DATABASE=AMD-755 [Cobra] IDE + +pci:v00001022d00007403* + ID_PRODUCT_FROM_DATABASE=AMD-755 [Cobra] ACPI + +pci:v00001022d00007404* + ID_PRODUCT_FROM_DATABASE=AMD-755 [Cobra] USB + +pci:v00001022d00007408* + ID_PRODUCT_FROM_DATABASE=AMD-756 [Viper] ISA + +pci:v00001022d00007409* + ID_PRODUCT_FROM_DATABASE=AMD-756 [Viper] IDE + +pci:v00001022d0000740B* + ID_PRODUCT_FROM_DATABASE=AMD-756 [Viper] ACPI + +pci:v00001022d0000740C* + ID_PRODUCT_FROM_DATABASE=AMD-756 [Viper] USB + +pci:v00001022d00007410* + ID_PRODUCT_FROM_DATABASE=AMD-766 [ViperPlus] ISA + +pci:v00001022d00007411* + ID_PRODUCT_FROM_DATABASE=AMD-766 [ViperPlus] IDE + +pci:v00001022d00007413* + ID_PRODUCT_FROM_DATABASE=AMD-766 [ViperPlus] ACPI + +pci:v00001022d00007414* + ID_PRODUCT_FROM_DATABASE=AMD-766 [ViperPlus] USB + +pci:v00001022d00007440* + ID_PRODUCT_FROM_DATABASE=AMD-768 [Opus] ISA + +pci:v00001022d00007440sv00001043sd00008044* + ID_PRODUCT_FROM_DATABASE=A7M-D Mainboard + +pci:v00001022d00007441* + ID_PRODUCT_FROM_DATABASE=AMD-768 [Opus] IDE + +pci:v00001022d00007443* + ID_PRODUCT_FROM_DATABASE=AMD-768 [Opus] ACPI + +pci:v00001022d00007443sv00001043sd00008044* + ID_PRODUCT_FROM_DATABASE=A7M-D Mainboard + +pci:v00001022d00007445* + ID_PRODUCT_FROM_DATABASE=AMD-768 [Opus] Audio + +pci:v00001022d00007446* + ID_PRODUCT_FROM_DATABASE=AMD-768 [Opus] MC97 Modem + +pci:v00001022d00007448* + ID_PRODUCT_FROM_DATABASE=AMD-768 [Opus] PCI + +pci:v00001022d00007449* + ID_PRODUCT_FROM_DATABASE=AMD-768 [Opus] USB + +pci:v00001022d00007450* + ID_PRODUCT_FROM_DATABASE=AMD-8131 PCI-X Bridge + +pci:v00001022d00007451* + ID_PRODUCT_FROM_DATABASE=AMD-8131 PCI-X IOAPIC + +pci:v00001022d00007454* + ID_PRODUCT_FROM_DATABASE=AMD-8151 System Controller + +pci:v00001022d00007455* + ID_PRODUCT_FROM_DATABASE=AMD-8151 AGP Bridge + +pci:v00001022d00007458* + ID_PRODUCT_FROM_DATABASE=AMD-8132 PCI-X Bridge + +pci:v00001022d00007459* + ID_PRODUCT_FROM_DATABASE=AMD-8132 PCI-X IOAPIC + +pci:v00001022d00007460* + ID_PRODUCT_FROM_DATABASE=AMD-8111 PCI + +pci:v00001022d00007460sv0000161Fsd00003017* + ID_PRODUCT_FROM_DATABASE=HDAMB + +pci:v00001022d00007461* + ID_PRODUCT_FROM_DATABASE=AMD-8111 USB + +pci:v00001022d00007462* + ID_PRODUCT_FROM_DATABASE=AMD-8111 Ethernet + +pci:v00001022d00007463* + ID_PRODUCT_FROM_DATABASE=AMD-8111 USB EHCI + +pci:v00001022d00007464* + ID_PRODUCT_FROM_DATABASE=AMD-8111 USB OHCI + +pci:v00001022d00007464sv0000161Fsd00003017* + ID_PRODUCT_FROM_DATABASE=HDAMB + +pci:v00001022d00007468* + ID_PRODUCT_FROM_DATABASE=AMD-8111 LPC + +pci:v00001022d00007468sv0000161Fsd00003017* + ID_PRODUCT_FROM_DATABASE=HDAMB + +pci:v00001022d00007469* + ID_PRODUCT_FROM_DATABASE=AMD-8111 IDE + +pci:v00001022d00007469sv00001022sd00002B80* + ID_PRODUCT_FROM_DATABASE=AMD-8111 IDE [Quartet] + +pci:v00001022d00007469sv0000161Fsd00003017* + ID_PRODUCT_FROM_DATABASE=HDAMB + +pci:v00001022d0000746A* + ID_PRODUCT_FROM_DATABASE=AMD-8111 SMBus 2.0 + +pci:v00001022d0000746B* + ID_PRODUCT_FROM_DATABASE=AMD-8111 ACPI + +pci:v00001022d0000746Bsv0000161Fsd00003017* + ID_PRODUCT_FROM_DATABASE=HDAMB + +pci:v00001022d0000746D* + ID_PRODUCT_FROM_DATABASE=AMD-8111 AC97 Audio + +pci:v00001022d0000746Dsv0000161Fsd00003017* + ID_PRODUCT_FROM_DATABASE=HDAMB + +pci:v00001022d0000746E* + ID_PRODUCT_FROM_DATABASE=AMD-8111 MC97 Modem + +pci:v00001022d0000756B* + ID_PRODUCT_FROM_DATABASE=AMD-8111 ACPI + +pci:v00001022d00007800* + ID_PRODUCT_FROM_DATABASE=FCH SATA Controller [IDE mode] + +pci:v00001022d00007801* + ID_PRODUCT_FROM_DATABASE=FCH SATA Controller [AHCI mode] + +pci:v00001022d00007802* + ID_PRODUCT_FROM_DATABASE=FCH SATA Controller [RAID mode] + +pci:v00001022d00007803* + ID_PRODUCT_FROM_DATABASE=FCH SATA Controller [RAID mode] + +pci:v00001022d00007804* + ID_PRODUCT_FROM_DATABASE=FCH SATA Controller [AHCI mode] + +pci:v00001022d00007805* + ID_PRODUCT_FROM_DATABASE=FCH SATA Controller [RAID mode] + +pci:v00001022d00007806* + ID_PRODUCT_FROM_DATABASE=FCH SD Flash Controller + +pci:v00001022d00007807* + ID_PRODUCT_FROM_DATABASE=FCH USB OHCI Controller + +pci:v00001022d00007808* + ID_PRODUCT_FROM_DATABASE=FCH USB EHCI Controller + +pci:v00001022d00007809* + ID_PRODUCT_FROM_DATABASE=FCH USB OHCI Controller + +pci:v00001022d0000780B* + ID_PRODUCT_FROM_DATABASE=FCH SMBus Controller + +pci:v00001022d0000780C* + ID_PRODUCT_FROM_DATABASE=FCH IDE Controller + +pci:v00001022d0000780D* + ID_PRODUCT_FROM_DATABASE=FCH Azalia Controller + +pci:v00001022d0000780E* + ID_PRODUCT_FROM_DATABASE=FCH LPC Bridge + +pci:v00001022d0000780F* + ID_PRODUCT_FROM_DATABASE=FCH PCI Bridge + +pci:v00001022d00007812* + ID_PRODUCT_FROM_DATABASE=FCH USB XHCI Controller + +pci:v00001022d00007813* + ID_PRODUCT_FROM_DATABASE=FCH SD Flash Controller + +pci:v00001022d00007814* + ID_PRODUCT_FROM_DATABASE=FCH USB XHCI Controller + +pci:v00001022d00009600* + ID_PRODUCT_FROM_DATABASE=RS780 Host Bridge + +pci:v00001022d00009600sv00001043sd000082F1* + ID_PRODUCT_FROM_DATABASE=M3A78-EH Motherboard + +pci:v00001022d00009601* + ID_PRODUCT_FROM_DATABASE=RS880 Host Bridge + +pci:v00001022d00009601sv00001043sd0000843E* + ID_PRODUCT_FROM_DATABASE=M5A88-V EVO + +pci:v00001022d00009602* + ID_PRODUCT_FROM_DATABASE=RS780/RS880 PCI to PCI bridge (int gfx) + +pci:v00001022d00009603* + ID_PRODUCT_FROM_DATABASE=RS780 PCI to PCI bridge (ext gfx port 0) + +pci:v00001022d00009604* + ID_PRODUCT_FROM_DATABASE=RS780/RS880 PCI to PCI bridge (PCIE port 0) + +pci:v00001022d00009605* + ID_PRODUCT_FROM_DATABASE=RS780/RS880 PCI to PCI bridge (PCIE port 1) + +pci:v00001022d00009606* + ID_PRODUCT_FROM_DATABASE=RS780 PCI to PCI bridge (PCIE port 2) + +pci:v00001022d00009607* + ID_PRODUCT_FROM_DATABASE=RS780 PCI to PCI bridge (PCIE port 3) + +pci:v00001022d00009608* + ID_PRODUCT_FROM_DATABASE=RS780/RS880 PCI to PCI bridge (PCIE port 4) + +pci:v00001022d00009609* + ID_PRODUCT_FROM_DATABASE=RS780/RS880 PCI to PCI bridge (PCIE port 5) + +pci:v00001022d0000960A* + ID_PRODUCT_FROM_DATABASE=RS780 PCI to PCI bridge (NB-SB link) + +pci:v00001022d0000960B* + ID_PRODUCT_FROM_DATABASE=RS780 PCI to PCI bridge (ext gfx port 1) + +pci:v00001023* + ID_VENDOR_FROM_DATABASE=Trident Microsystems + +pci:v00001023d00000194* + ID_PRODUCT_FROM_DATABASE=82C194 + +pci:v00001023d00002000* + ID_PRODUCT_FROM_DATABASE=4DWave DX + +pci:v00001023d00002001* + ID_PRODUCT_FROM_DATABASE=4DWave NX + +pci:v00001023d00002001sv0000122Dsd00001400* + ID_PRODUCT_FROM_DATABASE=Trident PCI288-Q3DII (NX) + +pci:v00001023d00002100* + ID_PRODUCT_FROM_DATABASE=CyberBlade XP4m32 + +pci:v00001023d00002200* + ID_PRODUCT_FROM_DATABASE=XGI Volari XP5 + +pci:v00001023d00008400* + ID_PRODUCT_FROM_DATABASE=CyberBlade/i7 + +pci:v00001023d00008400sv00001023sd00008400* + ID_PRODUCT_FROM_DATABASE=CyberBlade i7 AGP + +pci:v00001023d00008420* + ID_PRODUCT_FROM_DATABASE=CyberBlade/i7d + +pci:v00001023d00008420sv00000E11sd0000B15A* + ID_PRODUCT_FROM_DATABASE=CyberBlade i7 AGP + +pci:v00001023d00008500* + ID_PRODUCT_FROM_DATABASE=CyberBlade/i1 + +pci:v00001023d00008520* + ID_PRODUCT_FROM_DATABASE=CyberBlade i1 + +pci:v00001023d00008520sv00000E11sd0000B16E* + ID_PRODUCT_FROM_DATABASE=CyberBlade i1 AGP + +pci:v00001023d00008520sv00001023sd00008520* + ID_PRODUCT_FROM_DATABASE=CyberBlade i1 AGP + +pci:v00001023d00008620* + ID_PRODUCT_FROM_DATABASE=CyberBlade/i1 + +pci:v00001023d00008620sv00001014sd00000502* + ID_PRODUCT_FROM_DATABASE=ThinkPad R30/T30 + +pci:v00001023d00008620sv00001014sd00001025* + ID_PRODUCT_FROM_DATABASE=Travelmate 352TE + +pci:v00001023d00008820* + ID_PRODUCT_FROM_DATABASE=CyberBlade XPAi1 + +pci:v00001023d00009320* + ID_PRODUCT_FROM_DATABASE=TGUI 9320 + +pci:v00001023d00009350* + ID_PRODUCT_FROM_DATABASE=GUI Accelerator + +pci:v00001023d00009360* + ID_PRODUCT_FROM_DATABASE=Flat panel GUI Accelerator + +pci:v00001023d00009382* + ID_PRODUCT_FROM_DATABASE=Cyber 9382 [Reference design] + +pci:v00001023d00009383* + ID_PRODUCT_FROM_DATABASE=Cyber 9383 [Reference design] + +pci:v00001023d00009385* + ID_PRODUCT_FROM_DATABASE=Cyber 9385 [Reference design] + +pci:v00001023d00009386* + ID_PRODUCT_FROM_DATABASE=Cyber 9386 + +pci:v00001023d00009388* + ID_PRODUCT_FROM_DATABASE=Cyber 9388 + +pci:v00001023d00009397* + ID_PRODUCT_FROM_DATABASE=Cyber 9397 + +pci:v00001023d0000939A* + ID_PRODUCT_FROM_DATABASE=Cyber 9397DVD + +pci:v00001023d00009420* + ID_PRODUCT_FROM_DATABASE=TGUI 9420 + +pci:v00001023d00009430* + ID_PRODUCT_FROM_DATABASE=TGUI 9430 + +pci:v00001023d00009440* + ID_PRODUCT_FROM_DATABASE=TGUI 9440 + +pci:v00001023d00009460* + ID_PRODUCT_FROM_DATABASE=TGUI 9460 + +pci:v00001023d00009470* + ID_PRODUCT_FROM_DATABASE=TGUI 9470 + +pci:v00001023d00009520* + ID_PRODUCT_FROM_DATABASE=Cyber 9520 + +pci:v00001023d00009525* + ID_PRODUCT_FROM_DATABASE=Cyber 9525 + +pci:v00001023d00009540* + ID_PRODUCT_FROM_DATABASE=Cyber 9540 + +pci:v00001023d00009660* + ID_PRODUCT_FROM_DATABASE=TGUI 9660/938x/968x + +pci:v00001023d00009680* + ID_PRODUCT_FROM_DATABASE=TGUI 9680 + +pci:v00001023d00009682* + ID_PRODUCT_FROM_DATABASE=TGUI 9682 + +pci:v00001023d00009683* + ID_PRODUCT_FROM_DATABASE=TGUI 9683 + +pci:v00001023d00009685* + ID_PRODUCT_FROM_DATABASE=ProVIDIA 9685 + +pci:v00001023d00009750* + ID_PRODUCT_FROM_DATABASE=3DImage 9750 + +pci:v00001023d00009750sv00001014sd00009750* + ID_PRODUCT_FROM_DATABASE=3DImage 9750 + +pci:v00001023d00009750sv00001023sd00009750* + ID_PRODUCT_FROM_DATABASE=3DImage 9750 + +pci:v00001023d00009753* + ID_PRODUCT_FROM_DATABASE=TGUI 9753 + +pci:v00001023d00009754* + ID_PRODUCT_FROM_DATABASE=TGUI 9754 + +pci:v00001023d00009759* + ID_PRODUCT_FROM_DATABASE=TGUI 975 + +pci:v00001023d00009783* + ID_PRODUCT_FROM_DATABASE=TGUI 9783 + +pci:v00001023d00009785* + ID_PRODUCT_FROM_DATABASE=TGUI 9785 + +pci:v00001023d00009850* + ID_PRODUCT_FROM_DATABASE=3DImage 9850 + +pci:v00001023d00009880* + ID_PRODUCT_FROM_DATABASE=Blade 3D PCI/AGP + +pci:v00001023d00009880sv00001023sd00009880* + ID_PRODUCT_FROM_DATABASE=Blade 3D + +pci:v00001023d00009910* + ID_PRODUCT_FROM_DATABASE=CyberBlade/XP + +pci:v00001023d00009930* + ID_PRODUCT_FROM_DATABASE=CyberBlade/XPm + +pci:v00001023d00009960* + ID_PRODUCT_FROM_DATABASE=CyberBlade XP2 + +pci:v00001024* + ID_VENDOR_FROM_DATABASE=Zenith Data Systems + +pci:v00001025* + ID_VENDOR_FROM_DATABASE=Acer Incorporated [ALI] + +pci:v00001025d00001435* + ID_PRODUCT_FROM_DATABASE=M1435 + +pci:v00001025d00001445* + ID_PRODUCT_FROM_DATABASE=M1445 + +pci:v00001025d00001449* + ID_PRODUCT_FROM_DATABASE=M1449 + +pci:v00001025d00001451* + ID_PRODUCT_FROM_DATABASE=M1451 + +pci:v00001025d00001461* + ID_PRODUCT_FROM_DATABASE=M1461 + +pci:v00001025d00001489* + ID_PRODUCT_FROM_DATABASE=M1489 + +pci:v00001025d00001511* + ID_PRODUCT_FROM_DATABASE=M1511 + +pci:v00001025d00001512* + ID_PRODUCT_FROM_DATABASE=ALI M1512 Aladdin + +pci:v00001025d00001513* + ID_PRODUCT_FROM_DATABASE=M1513 + +pci:v00001025d00001521* + ID_PRODUCT_FROM_DATABASE=ALI M1521 Aladdin III CPU Bridge + +pci:v00001025d00001521sv000010B9sd00001521* + ID_PRODUCT_FROM_DATABASE=ALI M1521 Aladdin III CPU Bridge + +pci:v00001025d00001523* + ID_PRODUCT_FROM_DATABASE=ALI M1523 ISA Bridge + +pci:v00001025d00001523sv000010B9sd00001523* + ID_PRODUCT_FROM_DATABASE=ALI M1523 ISA Bridge + +pci:v00001025d00001531* + ID_PRODUCT_FROM_DATABASE=M1531 Northbridge [Aladdin IV/IV+] + +pci:v00001025d00001533* + ID_PRODUCT_FROM_DATABASE=M1533 PCI-to-ISA Bridge + +pci:v00001025d00001533sv000010B9sd00001533* + ID_PRODUCT_FROM_DATABASE=ALI M1533 Aladdin IV/V ISA South Bridge + +pci:v00001025d00001535* + ID_PRODUCT_FROM_DATABASE=M1535 PCI Bridge + Super I/O + FIR + +pci:v00001025d00001541* + ID_PRODUCT_FROM_DATABASE=M1541 Northbridge [Aladdin V] + +pci:v00001025d00001541sv000010B9sd00001541* + ID_PRODUCT_FROM_DATABASE=ALI M1541 Aladdin V/V+ AGP+PCI North Bridge + +pci:v00001025d00001542* + ID_PRODUCT_FROM_DATABASE=M1542 Northbridge [Aladdin V] + +pci:v00001025d00001543* + ID_PRODUCT_FROM_DATABASE=M1543 PCI-to-ISA Bridge + Super I/O + FIR + +pci:v00001025d00001561* + ID_PRODUCT_FROM_DATABASE=M1561 Northbridge [Aladdin 7] + +pci:v00001025d00001621* + ID_PRODUCT_FROM_DATABASE=M1621 Northbridge [Aladdin-Pro II] + +pci:v00001025d00001631* + ID_PRODUCT_FROM_DATABASE=M1631 Northbridge+3D Graphics [Aladdin TNT2] + +pci:v00001025d00001641* + ID_PRODUCT_FROM_DATABASE=M1641 Northbridge [Aladdin-Pro IV] + +pci:v00001025d00001647* + ID_PRODUCT_FROM_DATABASE=M1647 [MaGiK1] PCI North Bridge + +pci:v00001025d00001671* + ID_PRODUCT_FROM_DATABASE=M1671 Northbridge [ALADDiN-P4] + +pci:v00001025d00001672* + ID_PRODUCT_FROM_DATABASE=Northbridge [CyberALADDiN-P4] + +pci:v00001025d00003141* + ID_PRODUCT_FROM_DATABASE=M3141 + +pci:v00001025d00003143* + ID_PRODUCT_FROM_DATABASE=M3143 + +pci:v00001025d00003145* + ID_PRODUCT_FROM_DATABASE=M3145 + +pci:v00001025d00003147* + ID_PRODUCT_FROM_DATABASE=M3147 + +pci:v00001025d00003149* + ID_PRODUCT_FROM_DATABASE=M3149 + +pci:v00001025d00003151* + ID_PRODUCT_FROM_DATABASE=M3151 + +pci:v00001025d00003307* + ID_PRODUCT_FROM_DATABASE=M3307 MPEG-I Video Controller + +pci:v00001025d00003309* + ID_PRODUCT_FROM_DATABASE=M3309 MPEG-II Video w/ Software Audio Decoder + +pci:v00001025d00003321* + ID_PRODUCT_FROM_DATABASE=M3321 MPEG-II Audio/Video Decoder + +pci:v00001025d00005212* + ID_PRODUCT_FROM_DATABASE=M4803 + +pci:v00001025d00005215* + ID_PRODUCT_FROM_DATABASE=ALI PCI EIDE Controller + +pci:v00001025d00005217* + ID_PRODUCT_FROM_DATABASE=M5217H + +pci:v00001025d00005219* + ID_PRODUCT_FROM_DATABASE=M5219 + +pci:v00001025d00005225* + ID_PRODUCT_FROM_DATABASE=M5225 + +pci:v00001025d00005229* + ID_PRODUCT_FROM_DATABASE=M5229 + +pci:v00001025d00005235* + ID_PRODUCT_FROM_DATABASE=M5235 + +pci:v00001025d00005237* + ID_PRODUCT_FROM_DATABASE=M5237 PCI USB Host Controller + +pci:v00001025d00005240* + ID_PRODUCT_FROM_DATABASE=EIDE Controller + +pci:v00001025d00005241* + ID_PRODUCT_FROM_DATABASE=PCMCIA Bridge + +pci:v00001025d00005242* + ID_PRODUCT_FROM_DATABASE=General Purpose Controller + +pci:v00001025d00005243* + ID_PRODUCT_FROM_DATABASE=PCI to PCI Bridge Controller + +pci:v00001025d00005244* + ID_PRODUCT_FROM_DATABASE=Floppy Disk Controller + +pci:v00001025d00005247* + ID_PRODUCT_FROM_DATABASE=M1541 PCI to PCI Bridge + +pci:v00001025d00005251* + ID_PRODUCT_FROM_DATABASE=M5251 P1394 Controller + +pci:v00001025d00005427* + ID_PRODUCT_FROM_DATABASE=PCI to AGP Bridge + +pci:v00001025d00005451* + ID_PRODUCT_FROM_DATABASE=M5451 PCI AC-Link Controller Audio Device + +pci:v00001025d00005453* + ID_PRODUCT_FROM_DATABASE=M5453 PCI AC-Link Controller Modem Device + +pci:v00001025d00007101* + ID_PRODUCT_FROM_DATABASE=M7101 PCI PMU Power Management Controller + +pci:v00001025d00007101sv000010B9sd00007101* + ID_PRODUCT_FROM_DATABASE=M7101 PCI PMU Power Management Controller + +pci:v00001025d00009602* + ID_PRODUCT_FROM_DATABASE=AMD RS780/RS880 PCI to PCI bridge (int gfx) + +pci:v00001028* + ID_VENDOR_FROM_DATABASE=Dell + +pci:v00001028d00000001* + ID_PRODUCT_FROM_DATABASE=PowerEdge Expandable RAID Controller 2/Si + +pci:v00001028d00000001sv00001028sd00000001* + ID_PRODUCT_FROM_DATABASE=PowerEdge 2400 + +pci:v00001028d00000002* + ID_PRODUCT_FROM_DATABASE=PowerEdge Expandable RAID Controller 3/Di + +pci:v00001028d00000002sv00001028sd00000002* + ID_PRODUCT_FROM_DATABASE=PowerEdge 4400 + +pci:v00001028d00000002sv00001028sd000000D1* + ID_PRODUCT_FROM_DATABASE=PERC 3/DiV [Viper] + +pci:v00001028d00000002sv00001028sd000000D9* + ID_PRODUCT_FROM_DATABASE=PERC 3/DiL [Lexus] + +pci:v00001028d00000003* + ID_PRODUCT_FROM_DATABASE=PowerEdge Expandable RAID Controller 3/Si + +pci:v00001028d00000003sv00001028sd00000003* + ID_PRODUCT_FROM_DATABASE=PowerEdge 2450 + +pci:v00001028d00000004* + ID_PRODUCT_FROM_DATABASE=PowerEdge Expandable RAID Controller 3/Di [Iguana] + +pci:v00001028d00000004sv00001028sd00000004* + ID_PRODUCT_FROM_DATABASE=PERC 3/DiF [Iguana] + +pci:v00001028d00000006* + ID_PRODUCT_FROM_DATABASE=PowerEdge Expandable RAID Controller 3/Di + +pci:v00001028d00000007* + ID_PRODUCT_FROM_DATABASE=Remote Access Card III + +pci:v00001028d00000008* + ID_PRODUCT_FROM_DATABASE=Remote Access Card III + +pci:v00001028d00000009* + ID_PRODUCT_FROM_DATABASE=Remote Access Card III: BMC/SMIC device not present + +pci:v00001028d0000000A* + ID_PRODUCT_FROM_DATABASE=PowerEdge Expandable RAID Controller 3/Di + +pci:v00001028d0000000Asv00001028sd00000106* + ID_PRODUCT_FROM_DATABASE=PERC 3/DiJ [Jaguar] + +pci:v00001028d0000000Asv00001028sd0000011B* + ID_PRODUCT_FROM_DATABASE=PERC 3/DiD [Dagger] + +pci:v00001028d0000000Asv00001028sd00000121* + ID_PRODUCT_FROM_DATABASE=PERC 3/DiB [Boxster] + +pci:v00001028d0000000C* + ID_PRODUCT_FROM_DATABASE=Embedded Remote Access or ERA/O + +pci:v00001028d0000000D* + ID_PRODUCT_FROM_DATABASE=Embedded Remote Access: BMC/SMIC device + +pci:v00001028d0000000E* + ID_PRODUCT_FROM_DATABASE=PowerEdge Expandable RAID controller 4/Di + +pci:v00001028d0000000F* + ID_PRODUCT_FROM_DATABASE=PowerEdge Expandable RAID controller 4/Di + +pci:v00001028d0000000Fsv00001028sd0000014A* + ID_PRODUCT_FROM_DATABASE=PowerEdge 1750 + +pci:v00001028d00000010* + ID_PRODUCT_FROM_DATABASE=Remote Access Card 4 + +pci:v00001028d00000011* + ID_PRODUCT_FROM_DATABASE=Remote Access Card 4 Daughter Card + +pci:v00001028d00000012* + ID_PRODUCT_FROM_DATABASE=Remote Access Card 4 Daughter Card Virtual UART + +pci:v00001028d00000013* + ID_PRODUCT_FROM_DATABASE=PowerEdge Expandable RAID controller 4 + +pci:v00001028d00000013sv00001028sd0000016C* + ID_PRODUCT_FROM_DATABASE=PowerEdge Expandable RAID Controller 4e/Si + +pci:v00001028d00000013sv00001028sd0000016D* + ID_PRODUCT_FROM_DATABASE=PowerEdge Expandable RAID Controller 4e/Di + +pci:v00001028d00000013sv00001028sd0000016E* + ID_PRODUCT_FROM_DATABASE=PowerEdge Expandable RAID Controller 4e/Di + +pci:v00001028d00000013sv00001028sd0000016F* + ID_PRODUCT_FROM_DATABASE=PowerEdge Expandable RAID Controller 4e/Di + +pci:v00001028d00000013sv00001028sd00000170* + ID_PRODUCT_FROM_DATABASE=PowerEdge Expandable RAID Controller 4e/Di + +pci:v00001028d00000014* + ID_PRODUCT_FROM_DATABASE=Remote Access Card 4 Daughter Card SMIC interface + +pci:v00001028d00000015* + ID_PRODUCT_FROM_DATABASE=PowerEdge Expandable RAID controller 5 + +pci:v00001028d00000015sv00001028sd00001F01* + ID_PRODUCT_FROM_DATABASE=PERC 5/E Adapter RAID Controller + +pci:v00001028d00000015sv00001028sd00001F02* + ID_PRODUCT_FROM_DATABASE=PERC 5/i Adapter RAID Controller + +pci:v00001028d00000015sv00001028sd00001F03* + ID_PRODUCT_FROM_DATABASE=PERC 5/i Integrated RAID Controller + +pci:v00001028d00000016* + ID_PRODUCT_FROM_DATABASE=PowerEdge Expandable RAID controller S300 + +pci:v00001028d00000016sv00001028sd00001F24* + ID_PRODUCT_FROM_DATABASE=PERC S300 Controller + +pci:v00001029* + ID_VENDOR_FROM_DATABASE=Siemens Nixdorf IS + +pci:v0000102A* + ID_VENDOR_FROM_DATABASE=LSI Logic + +pci:v0000102Ad00000000* + ID_PRODUCT_FROM_DATABASE=HYDRA + +pci:v0000102Ad00000010* + ID_PRODUCT_FROM_DATABASE=ASPEN + +pci:v0000102Ad0000001F* + ID_PRODUCT_FROM_DATABASE=AHA-2940U2/U2W /7890/7891 SCSI Controllers + +pci:v0000102Ad0000001Fsv00009005sd0000000F* + ID_PRODUCT_FROM_DATABASE=2940U2W SCSI Controller + +pci:v0000102Ad0000001Fsv00009005sd00000106* + ID_PRODUCT_FROM_DATABASE=2940U2W SCSI Controller + +pci:v0000102Ad0000001Fsv00009005sd0000A180* + ID_PRODUCT_FROM_DATABASE=2940U2W SCSI Controller + +pci:v0000102Ad000000C5* + ID_PRODUCT_FROM_DATABASE=AIC-7899 U160/m SCSI Controller + +pci:v0000102Ad000000C5sv00001028sd000000C5* + ID_PRODUCT_FROM_DATABASE=PowerEdge 2550/2650/4600 + +pci:v0000102Ad000000CF* + ID_PRODUCT_FROM_DATABASE=AIC-7899P U160/m + +pci:v0000102Ad000000CFsv00001028sd00000106* + ID_PRODUCT_FROM_DATABASE=PowerEdge 4600 + +pci:v0000102Ad000000CFsv00001028sd00000121* + ID_PRODUCT_FROM_DATABASE=PowerEdge 2650 + +pci:v0000102B* + ID_VENDOR_FROM_DATABASE=Matrox Electronics Systems Ltd. + +pci:v0000102Bd00000010* + ID_PRODUCT_FROM_DATABASE=MGA-I [Impression?] + +pci:v0000102Bd00000100* + ID_PRODUCT_FROM_DATABASE=MGA 1064SG [Mystique] + +pci:v0000102Bd00000518* + ID_PRODUCT_FROM_DATABASE=MGA-II [Athena] + +pci:v0000102Bd00000519* + ID_PRODUCT_FROM_DATABASE=MGA 2064W [Millennium] + +pci:v0000102Bd0000051A* + ID_PRODUCT_FROM_DATABASE=MGA 1064SG [Mystique] + +pci:v0000102Bd0000051Asv0000102Bsd00000100* + ID_PRODUCT_FROM_DATABASE=MGA-1064SG Mystique + +pci:v0000102Bd0000051Asv0000102Bsd00001100* + ID_PRODUCT_FROM_DATABASE=MGA-1084SG Mystique + +pci:v0000102Bd0000051Asv0000102Bsd00001200* + ID_PRODUCT_FROM_DATABASE=MGA-1084SG Mystique + +pci:v0000102Bd0000051Asv00001100sd0000102B* + ID_PRODUCT_FROM_DATABASE=MGA-1084SG Mystique + +pci:v0000102Bd0000051Asv0000110Asd00000018* + ID_PRODUCT_FROM_DATABASE=Scenic Pro C5 (D1025) + +pci:v0000102Bd0000051B* + ID_PRODUCT_FROM_DATABASE=MGA 2164W [Millennium II] + +pci:v0000102Bd0000051Bsv0000102Bsd0000051B* + ID_PRODUCT_FROM_DATABASE=MGA-2164W Millennium II + +pci:v0000102Bd0000051Bsv0000102Bsd00001100* + ID_PRODUCT_FROM_DATABASE=MGA-2164W Millennium II + +pci:v0000102Bd0000051Bsv0000102Bsd00001200* + ID_PRODUCT_FROM_DATABASE=MGA-2164W Millennium II + +pci:v0000102Bd0000051Bsv0000102Bsd00002100* + ID_PRODUCT_FROM_DATABASE=MGA-2164W Millennium II + +pci:v0000102Bd0000051E* + ID_PRODUCT_FROM_DATABASE=MGA 1064SG [Mystique] AGP + +pci:v0000102Bd0000051F* + ID_PRODUCT_FROM_DATABASE=MGA 2164W [Millennium II] AGP + +pci:v0000102Bd00000520* + ID_PRODUCT_FROM_DATABASE=MGA G200 + +pci:v0000102Bd00000520sv0000102Bsd0000DBC2* + ID_PRODUCT_FROM_DATABASE=G200 Multi-Monitor + +pci:v0000102Bd00000520sv0000102Bsd0000DBC8* + ID_PRODUCT_FROM_DATABASE=G200 Multi-Monitor + +pci:v0000102Bd00000520sv0000102Bsd0000DBE2* + ID_PRODUCT_FROM_DATABASE=G200 Multi-Monitor + +pci:v0000102Bd00000520sv0000102Bsd0000DBE8* + ID_PRODUCT_FROM_DATABASE=G200 Multi-Monitor + +pci:v0000102Bd00000520sv0000102Bsd0000FF03* + ID_PRODUCT_FROM_DATABASE=Millennium G200 SD + +pci:v0000102Bd00000520sv0000102Bsd0000FF04* + ID_PRODUCT_FROM_DATABASE=Marvel G200 + +pci:v0000102Bd00000521* + ID_PRODUCT_FROM_DATABASE=MGA G200 AGP + +pci:v0000102Bd00000521sv00001014sd0000FF03* + ID_PRODUCT_FROM_DATABASE=Millennium G200 AGP + +pci:v0000102Bd00000521sv0000102Bsd000048E9* + ID_PRODUCT_FROM_DATABASE=Mystique G200 AGP + +pci:v0000102Bd00000521sv0000102Bsd000048F8* + ID_PRODUCT_FROM_DATABASE=Millennium G200 SD AGP + +pci:v0000102Bd00000521sv0000102Bsd00004A60* + ID_PRODUCT_FROM_DATABASE=Millennium G200 LE AGP + +pci:v0000102Bd00000521sv0000102Bsd00004A64* + ID_PRODUCT_FROM_DATABASE=Millennium G200 AGP + +pci:v0000102Bd00000521sv0000102Bsd0000C93C* + ID_PRODUCT_FROM_DATABASE=Millennium G200 AGP + +pci:v0000102Bd00000521sv0000102Bsd0000C9B0* + ID_PRODUCT_FROM_DATABASE=Millennium G200 AGP + +pci:v0000102Bd00000521sv0000102Bsd0000C9BC* + ID_PRODUCT_FROM_DATABASE=Millennium G200 AGP + +pci:v0000102Bd00000521sv0000102Bsd0000CA60* + ID_PRODUCT_FROM_DATABASE=Millennium G250 LE AGP + +pci:v0000102Bd00000521sv0000102Bsd0000CA6C* + ID_PRODUCT_FROM_DATABASE=Millennium G250 AGP + +pci:v0000102Bd00000521sv0000102Bsd0000DBBC* + ID_PRODUCT_FROM_DATABASE=Millennium G200 AGP + +pci:v0000102Bd00000521sv0000102Bsd0000DBC2* + ID_PRODUCT_FROM_DATABASE=Millennium G200 MMS (Dual G200) + +pci:v0000102Bd00000521sv0000102Bsd0000DBC3* + ID_PRODUCT_FROM_DATABASE=G200 Multi-Monitor + +pci:v0000102Bd00000521sv0000102Bsd0000DBC8* + ID_PRODUCT_FROM_DATABASE=Millennium G200 MMS (Dual G200) + +pci:v0000102Bd00000521sv0000102Bsd0000DBD2* + ID_PRODUCT_FROM_DATABASE=G200 Multi-Monitor + +pci:v0000102Bd00000521sv0000102Bsd0000DBD3* + ID_PRODUCT_FROM_DATABASE=G200 Multi-Monitor + +pci:v0000102Bd00000521sv0000102Bsd0000DBD4* + ID_PRODUCT_FROM_DATABASE=G200 Multi-Monitor + +pci:v0000102Bd00000521sv0000102Bsd0000DBD5* + ID_PRODUCT_FROM_DATABASE=G200 Multi-Monitor + +pci:v0000102Bd00000521sv0000102Bsd0000DBD8* + ID_PRODUCT_FROM_DATABASE=G200 Multi-Monitor + +pci:v0000102Bd00000521sv0000102Bsd0000DBD9* + ID_PRODUCT_FROM_DATABASE=G200 Multi-Monitor + +pci:v0000102Bd00000521sv0000102Bsd0000DBE2* + ID_PRODUCT_FROM_DATABASE=Millennium G200 MMS (Quad G200) + +pci:v0000102Bd00000521sv0000102Bsd0000DBE3* + ID_PRODUCT_FROM_DATABASE=G200 Multi-Monitor + +pci:v0000102Bd00000521sv0000102Bsd0000DBE8* + ID_PRODUCT_FROM_DATABASE=Millennium G200 MMS (Quad G200) + +pci:v0000102Bd00000521sv0000102Bsd0000DBF2* + ID_PRODUCT_FROM_DATABASE=G200 Multi-Monitor + +pci:v0000102Bd00000521sv0000102Bsd0000DBF3* + ID_PRODUCT_FROM_DATABASE=G200 Multi-Monitor + +pci:v0000102Bd00000521sv0000102Bsd0000DBF4* + ID_PRODUCT_FROM_DATABASE=G200 Multi-Monitor + +pci:v0000102Bd00000521sv0000102Bsd0000DBF5* + ID_PRODUCT_FROM_DATABASE=G200 Multi-Monitor + +pci:v0000102Bd00000521sv0000102Bsd0000DBF8* + ID_PRODUCT_FROM_DATABASE=G200 Multi-Monitor + +pci:v0000102Bd00000521sv0000102Bsd0000DBF9* + ID_PRODUCT_FROM_DATABASE=G200 Multi-Monitor + +pci:v0000102Bd00000521sv0000102Bsd0000F806* + ID_PRODUCT_FROM_DATABASE=Mystique G200 Video AGP + +pci:v0000102Bd00000521sv0000102Bsd0000FF00* + ID_PRODUCT_FROM_DATABASE=MGA-G200 AGP + +pci:v0000102Bd00000521sv0000102Bsd0000FF02* + ID_PRODUCT_FROM_DATABASE=Mystique G200 AGP + +pci:v0000102Bd00000521sv0000102Bsd0000FF03* + ID_PRODUCT_FROM_DATABASE=Millennium G200 AGP + +pci:v0000102Bd00000521sv0000102Bsd0000FF04* + ID_PRODUCT_FROM_DATABASE=Marvel G200 AGP + +pci:v0000102Bd00000521sv0000110Asd00000032* + ID_PRODUCT_FROM_DATABASE=MGA-G200 AGP + +pci:v0000102Bd00000522* + ID_PRODUCT_FROM_DATABASE=MGA G200e [Pilot] ServerEngines (SEP1) + +pci:v0000102Bd00000522sv0000103Csd000031FA* + ID_PRODUCT_FROM_DATABASE=ProLiant DL140 G3 + +pci:v0000102Bd00000525* + ID_PRODUCT_FROM_DATABASE=MGA G400/G450 + +pci:v0000102Bd00000525sv00000E11sd0000B16F* + ID_PRODUCT_FROM_DATABASE=MGA-G400 AGP + +pci:v0000102Bd00000525sv0000102Bsd00000328* + ID_PRODUCT_FROM_DATABASE=Millennium G400 16Mb SDRAM + +pci:v0000102Bd00000525sv0000102Bsd00000338* + ID_PRODUCT_FROM_DATABASE=Millennium G400 16Mb SDRAM + +pci:v0000102Bd00000525sv0000102Bsd00000378* + ID_PRODUCT_FROM_DATABASE=Millennium G400 32Mb SDRAM + +pci:v0000102Bd00000525sv0000102Bsd00000541* + ID_PRODUCT_FROM_DATABASE=Millennium G450 Dual Head + +pci:v0000102Bd00000525sv0000102Bsd00000542* + ID_PRODUCT_FROM_DATABASE=Millennium G450 Dual Head LX + +pci:v0000102Bd00000525sv0000102Bsd00000543* + ID_PRODUCT_FROM_DATABASE=Millennium G450 Single Head LX + +pci:v0000102Bd00000525sv0000102Bsd00000641* + ID_PRODUCT_FROM_DATABASE=Millennium G450 32Mb SDRAM Dual Head + +pci:v0000102Bd00000525sv0000102Bsd00000642* + ID_PRODUCT_FROM_DATABASE=Millennium G450 32Mb SDRAM Dual Head LX + +pci:v0000102Bd00000525sv0000102Bsd00000643* + ID_PRODUCT_FROM_DATABASE=Millennium G450 32Mb SDRAM Single Head LX + +pci:v0000102Bd00000525sv0000102Bsd000007C0* + ID_PRODUCT_FROM_DATABASE=Millennium G450 Dual Head LE + +pci:v0000102Bd00000525sv0000102Bsd000007C1* + ID_PRODUCT_FROM_DATABASE=Millennium G450 SDR Dual Head LE + +pci:v0000102Bd00000525sv0000102Bsd00000D41* + ID_PRODUCT_FROM_DATABASE=Millennium G450 Dual Head PCI + +pci:v0000102Bd00000525sv0000102Bsd00000D42* + ID_PRODUCT_FROM_DATABASE=Millennium G450 Dual Head LX PCI + +pci:v0000102Bd00000525sv0000102Bsd00000D43* + ID_PRODUCT_FROM_DATABASE=Millennium G450 32Mb Dual Head PCI + +pci:v0000102Bd00000525sv0000102Bsd00000E00* + ID_PRODUCT_FROM_DATABASE=Marvel G450 eTV + +pci:v0000102Bd00000525sv0000102Bsd00000E01* + ID_PRODUCT_FROM_DATABASE=Marvel G450 eTV + +pci:v0000102Bd00000525sv0000102Bsd00000E02* + ID_PRODUCT_FROM_DATABASE=Marvel G450 eTV + +pci:v0000102Bd00000525sv0000102Bsd00000E03* + ID_PRODUCT_FROM_DATABASE=Marvel G450 eTV + +pci:v0000102Bd00000525sv0000102Bsd00000F80* + ID_PRODUCT_FROM_DATABASE=Millennium G450 Low Profile + +pci:v0000102Bd00000525sv0000102Bsd00000F81* + ID_PRODUCT_FROM_DATABASE=Millennium G450 Low Profile + +pci:v0000102Bd00000525sv0000102Bsd00000F82* + ID_PRODUCT_FROM_DATABASE=Millennium G450 Low Profile DVI + +pci:v0000102Bd00000525sv0000102Bsd00000F83* + ID_PRODUCT_FROM_DATABASE=Millennium G450 Low Profile DVI + +pci:v0000102Bd00000525sv0000102Bsd000019D8* + ID_PRODUCT_FROM_DATABASE=Millennium G400 16Mb SGRAM + +pci:v0000102Bd00000525sv0000102Bsd000019F8* + ID_PRODUCT_FROM_DATABASE=Millennium G400 32Mb SGRAM + +pci:v0000102Bd00000525sv0000102Bsd00002159* + ID_PRODUCT_FROM_DATABASE=Millennium G400 Dual Head 16Mb + +pci:v0000102Bd00000525sv0000102Bsd00002179* + ID_PRODUCT_FROM_DATABASE=Millennium G400 MAX/Dual Head 32Mb + +pci:v0000102Bd00000525sv0000102Bsd0000217D* + ID_PRODUCT_FROM_DATABASE=Millennium G400 Dual Head Max + +pci:v0000102Bd00000525sv0000102Bsd000023C0* + ID_PRODUCT_FROM_DATABASE=Millennium G450 + +pci:v0000102Bd00000525sv0000102Bsd000023C1* + ID_PRODUCT_FROM_DATABASE=Millennium G450 + +pci:v0000102Bd00000525sv0000102Bsd000023C2* + ID_PRODUCT_FROM_DATABASE=Millennium G450 DVI + +pci:v0000102Bd00000525sv0000102Bsd000023C3* + ID_PRODUCT_FROM_DATABASE=Millennium G450 DVI + +pci:v0000102Bd00000525sv0000102Bsd00002F58* + ID_PRODUCT_FROM_DATABASE=Millennium G400 + +pci:v0000102Bd00000525sv0000102Bsd00002F78* + ID_PRODUCT_FROM_DATABASE=Millennium G400 + +pci:v0000102Bd00000525sv0000102Bsd00003693* + ID_PRODUCT_FROM_DATABASE=Marvel G400 AGP + +pci:v0000102Bd00000525sv0000102Bsd00005DD0* + ID_PRODUCT_FROM_DATABASE=4Sight II + +pci:v0000102Bd00000525sv0000102Bsd00005F50* + ID_PRODUCT_FROM_DATABASE=4Sight II + +pci:v0000102Bd00000525sv0000102Bsd00005F51* + ID_PRODUCT_FROM_DATABASE=4Sight II + +pci:v0000102Bd00000525sv0000102Bsd00005F52* + ID_PRODUCT_FROM_DATABASE=4Sight II + +pci:v0000102Bd00000525sv0000102Bsd00009010* + ID_PRODUCT_FROM_DATABASE=Millennium G400 Dual Head + +pci:v0000102Bd00000525sv00001458sd00000400* + ID_PRODUCT_FROM_DATABASE=GA-G400 + +pci:v0000102Bd00000525sv00001705sd00000001* + ID_PRODUCT_FROM_DATABASE=Millennium G450 32MB SGRAM + +pci:v0000102Bd00000525sv00001705sd00000002* + ID_PRODUCT_FROM_DATABASE=Millennium G450 16MB SGRAM + +pci:v0000102Bd00000525sv00001705sd00000003* + ID_PRODUCT_FROM_DATABASE=Millennium G450 32MB + +pci:v0000102Bd00000525sv00001705sd00000004* + ID_PRODUCT_FROM_DATABASE=Millennium G450 16MB + +pci:v0000102Bd00000527* + ID_PRODUCT_FROM_DATABASE=Parhelia + +pci:v0000102Bd00000527sv0000102Bsd00000840* + ID_PRODUCT_FROM_DATABASE=Parhelia 128Mb + +pci:v0000102Bd00000527sv0000102Bsd00000850* + ID_PRODUCT_FROM_DATABASE=Parhelia 256MB + +pci:v0000102Bd00000527sv0000102Bsd00000870* + ID_PRODUCT_FROM_DATABASE=MED2mp-DVI + +pci:v0000102Bd00000527sv0000102Bsd00000880* + ID_PRODUCT_FROM_DATABASE=P-256 Edge Overlap Controller + +pci:v0000102Bd00000528* + ID_PRODUCT_FROM_DATABASE=Parhelia + +pci:v0000102Bd00000528sv0000102Bsd00001020* + ID_PRODUCT_FROM_DATABASE=Parhelia 128MB + +pci:v0000102Bd00000528sv0000102Bsd00001030* + ID_PRODUCT_FROM_DATABASE=Parhelia 256 MB Dual DVI + +pci:v0000102Bd00000528sv0000102Bsd00001040* + ID_PRODUCT_FROM_DATABASE=MED2mp-DVI + +pci:v0000102Bd00000528sv0000102Bsd00001050* + ID_PRODUCT_FROM_DATABASE=Sono S20 + +pci:v0000102Bd00000528sv0000102Bsd00001060* + ID_PRODUCT_FROM_DATABASE=PJ-30L + +pci:v0000102Bd00000528sv0000102Bsd00001070* + ID_PRODUCT_FROM_DATABASE=PJ-40L + +pci:v0000102Bd00000528sv0000102Bsd00001421* + ID_PRODUCT_FROM_DATABASE=MED5mp + +pci:v0000102Bd00000528sv0000102Bsd00001431* + ID_PRODUCT_FROM_DATABASE=MED3mp-DVI + +pci:v0000102Bd00000528sv0000102Bsd00001451* + ID_PRODUCT_FROM_DATABASE=MED5mp-DVI + +pci:v0000102Bd00000528sv0000102Bsd00001491* + ID_PRODUCT_FROM_DATABASE=MED2mp-DVI + +pci:v0000102Bd00000528sv0000102Bsd000014B1* + ID_PRODUCT_FROM_DATABASE=MED3mp-DVI + +pci:v0000102Bd00000528sv0000102Bsd000014C1* + ID_PRODUCT_FROM_DATABASE=MED5mp-DVI + +pci:v0000102Bd00000528sv0000102Bsd000014E1* + ID_PRODUCT_FROM_DATABASE=Parhelia PCI 256MB + +pci:v0000102Bd00000528sv0000102Bsd000014F1* + ID_PRODUCT_FROM_DATABASE=Parhelia Precision SGT + +pci:v0000102Bd00000528sv0000102Bsd00001501* + ID_PRODUCT_FROM_DATABASE=ATC-4MP + +pci:v0000102Bd00000528sv0000102Bsd00001511* + ID_PRODUCT_FROM_DATABASE=ATC-4MP + +pci:v0000102Bd00000528sv0000102Bsd00001521* + ID_PRODUCT_FROM_DATABASE=TheatreVUE T30 + +pci:v0000102Bd00000528sv0000102Bsd00001531* + ID_PRODUCT_FROM_DATABASE=TheatreVUE T20 + +pci:v0000102Bd00000528sv0000102Bsd00001541* + ID_PRODUCT_FROM_DATABASE=MED2mp-DVI + +pci:v0000102Bd00000528sv0000102Bsd00001551* + ID_PRODUCT_FROM_DATABASE=MED3mp-DVI + +pci:v0000102Bd00000528sv0000102Bsd00001561* + ID_PRODUCT_FROM_DATABASE=MED5mp-DVI + +pci:v0000102Bd00000528sv0000102Bsd00001571* + ID_PRODUCT_FROM_DATABASE=Parhelia DL256 PCI + +pci:v0000102Bd00000528sv0000102Bsd00001591* + ID_PRODUCT_FROM_DATABASE=Parhelia Precision SDT + +pci:v0000102Bd00000528sv0000102Bsd000015A1* + ID_PRODUCT_FROM_DATABASE=MED4mp-DVI + +pci:v0000102Bd00000528sv0000102Bsd00002011* + ID_PRODUCT_FROM_DATABASE=Parhelia HR256 + +pci:v0000102Bd00000528sv0000102Bsd00002021* + ID_PRODUCT_FROM_DATABASE=QID Pro + +pci:v0000102Bd00000528sv0000102Bsd00002061* + ID_PRODUCT_FROM_DATABASE=PJ-40LP + +pci:v0000102Bd00000528sv0000102Bsd00002081* + ID_PRODUCT_FROM_DATABASE=EWS Quad + +pci:v0000102Bd00000528sv0000102Bsd00002411* + ID_PRODUCT_FROM_DATABASE=PPX-OUT8 + +pci:v0000102Bd00000528sv0000102Bsd00002421* + ID_PRODUCT_FROM_DATABASE=VPX-OUT8 + +pci:v0000102Bd00000528sv0000102Bsd00002441* + ID_PRODUCT_FROM_DATABASE=PPX-OUT4 + +pci:v0000102Bd00000528sv0000102Bsd00002451* + ID_PRODUCT_FROM_DATABASE=VPX-OUT4 + +pci:v0000102Bd00000528sv0000102Bsd00002491* + ID_PRODUCT_FROM_DATABASE=LPX-OUT4 + +pci:v0000102Bd00000530* + ID_PRODUCT_FROM_DATABASE=MGA G200EV + +pci:v0000102Bd00000532* + ID_PRODUCT_FROM_DATABASE=MGA G200eW WPCM450 + +pci:v0000102Bd00000532sv00001028sd00000235* + ID_PRODUCT_FROM_DATABASE=PowerEdge R710 MGA G200eW WPCM450 + +pci:v0000102Bd00000532sv00001028sd00000236* + ID_PRODUCT_FROM_DATABASE=PowerEdge R610 MGA G200eW WPCM450 + +pci:v0000102Bd00000532sv00001028sd00000237* + ID_PRODUCT_FROM_DATABASE=PowerEdge T610 MGA G200eW WPCM450 + +pci:v0000102Bd00000532sv00001028sd00000287* + ID_PRODUCT_FROM_DATABASE=PowerEdge M610 MGA G200eW WPCM450 + +pci:v0000102Bd00000532sv00001028sd0000028C* + ID_PRODUCT_FROM_DATABASE=PowerEdge R410 MGA G200eW WPCM450 + +pci:v0000102Bd00000532sv00001028sd0000028D* + ID_PRODUCT_FROM_DATABASE=PowerEdge T410 MGA G200eW WPCM450 + +pci:v0000102Bd00000532sv00001028sd0000029C* + ID_PRODUCT_FROM_DATABASE=PowerEdge M710 MGA G200eW WPCM450 + +pci:v0000102Bd00000532sv00001028sd000002A4* + ID_PRODUCT_FROM_DATABASE=PowerEdge T310 MGA G200eW WPCM450 + +pci:v0000102Bd00000532sv000015D9sd0000A811* + ID_PRODUCT_FROM_DATABASE=H8DGU + +pci:v0000102Bd00000533* + ID_PRODUCT_FROM_DATABASE=MGA G200EH + +pci:v0000102Bd00000533sv0000103Csd00003381* + ID_PRODUCT_FROM_DATABASE=iLO4 + +pci:v0000102Bd00000534* + ID_PRODUCT_FROM_DATABASE=G200eR2 + +pci:v0000102Bd00000540* + ID_PRODUCT_FROM_DATABASE=M91XX + +pci:v0000102Bd00000540sv0000102Bsd00002080* + ID_PRODUCT_FROM_DATABASE=M9140 LP PCIe x16 + +pci:v0000102Bd00000540sv0000102Bsd000020C0* + ID_PRODUCT_FROM_DATABASE=Xenia + +pci:v0000102Bd00000540sv0000102Bsd000020C1* + ID_PRODUCT_FROM_DATABASE=Xenia Pro + +pci:v0000102Bd00000540sv0000102Bsd00002100* + ID_PRODUCT_FROM_DATABASE=M9120 PCIe x16 + +pci:v0000102Bd00000540sv0000102Bsd00002140* + ID_PRODUCT_FROM_DATABASE=M9125 PCIe x16 + +pci:v0000102Bd00000540sv0000102Bsd00002180* + ID_PRODUCT_FROM_DATABASE=M9120 Plus LP PCIe x16 + +pci:v0000102Bd00000540sv0000102Bsd000021C0* + ID_PRODUCT_FROM_DATABASE=M9120 Plus LP PCIe x1 + +pci:v0000102Bd00000540sv0000102Bsd00002200* + ID_PRODUCT_FROM_DATABASE=VDA1164 Output Board + +pci:v0000102Bd00000540sv0000102Bsd00002240* + ID_PRODUCT_FROM_DATABASE=M9148 LP PCIe x16 + +pci:v0000102Bd00000540sv0000102Bsd00002241* + ID_PRODUCT_FROM_DATABASE=M9138 LP PCIe x16 + +pci:v0000102Bd00000540sv0000102Bsd00002280* + ID_PRODUCT_FROM_DATABASE=M9188 ATX PCIe x16 + +pci:v0000102Bd00000540sv0000102Bsd000022C0* + ID_PRODUCT_FROM_DATABASE=M9128 LP PCIe x16 + +pci:v0000102Bd00000D10* + ID_PRODUCT_FROM_DATABASE=MGA Ultima/Impression + +pci:v0000102Bd00001000* + ID_PRODUCT_FROM_DATABASE=MGA G100 [Productiva] + +pci:v0000102Bd00001000sv0000102Bsd0000FF01* + ID_PRODUCT_FROM_DATABASE=Productiva G100 + +pci:v0000102Bd00001000sv0000102Bsd0000FF05* + ID_PRODUCT_FROM_DATABASE=Productiva G100 Multi-Monitor + +pci:v0000102Bd00001001* + ID_PRODUCT_FROM_DATABASE=MGA G100 [Productiva] AGP + +pci:v0000102Bd00001001sv0000102Bsd00001001* + ID_PRODUCT_FROM_DATABASE=MGA-G100 AGP + +pci:v0000102Bd00001001sv0000102Bsd0000FF00* + ID_PRODUCT_FROM_DATABASE=MGA-G100 AGP + +pci:v0000102Bd00001001sv0000102Bsd0000FF01* + ID_PRODUCT_FROM_DATABASE=MGA-G100 Productiva AGP + +pci:v0000102Bd00001001sv0000102Bsd0000FF03* + ID_PRODUCT_FROM_DATABASE=Millennium G100 AGP + +pci:v0000102Bd00001001sv0000102Bsd0000FF04* + ID_PRODUCT_FROM_DATABASE=MGA-G100 AGP + +pci:v0000102Bd00001001sv0000102Bsd0000FF05* + ID_PRODUCT_FROM_DATABASE=MGA-G100 Productiva AGP Multi-Monitor + +pci:v0000102Bd00001001sv0000110Asd0000001E* + ID_PRODUCT_FROM_DATABASE=MGA-G100 AGP + +pci:v0000102Bd00002007* + ID_PRODUCT_FROM_DATABASE=MGA Mistral + +pci:v0000102Bd00002527* + ID_PRODUCT_FROM_DATABASE=Millennium G550 + +pci:v0000102Bd00002527sv0000102Bsd00000F83* + ID_PRODUCT_FROM_DATABASE=Millennium G550 + +pci:v0000102Bd00002527sv0000102Bsd00000F84* + ID_PRODUCT_FROM_DATABASE=Millennium G550 Dual Head DDR 32Mb + +pci:v0000102Bd00002527sv0000102Bsd00001E41* + ID_PRODUCT_FROM_DATABASE=Millennium G550 + +pci:v0000102Bd00002527sv0000102Bsd00002300* + ID_PRODUCT_FROM_DATABASE=Millennium G550 LP PCIE + +pci:v0000102Bd00002537* + ID_PRODUCT_FROM_DATABASE=Millenium P650/P750 + +pci:v0000102Bd00002537sv0000102Bsd00001820* + ID_PRODUCT_FROM_DATABASE=Millennium P750 64MB + +pci:v0000102Bd00002537sv0000102Bsd00001830* + ID_PRODUCT_FROM_DATABASE=Millennium P650 64MB + +pci:v0000102Bd00002537sv0000102Bsd00001850* + ID_PRODUCT_FROM_DATABASE=RAD2mp + +pci:v0000102Bd00002537sv0000102Bsd00001860* + ID_PRODUCT_FROM_DATABASE=RAD3mp + +pci:v0000102Bd00002537sv0000102Bsd00001880* + ID_PRODUCT_FROM_DATABASE=Sono S10 + +pci:v0000102Bd00002537sv0000102Bsd00001C10* + ID_PRODUCT_FROM_DATABASE=QID 128MB + +pci:v0000102Bd00002537sv0000102Bsd00002811* + ID_PRODUCT_FROM_DATABASE=Millennium P650 Low-profile PCI 64MB + +pci:v0000102Bd00002537sv0000102Bsd00002821* + ID_PRODUCT_FROM_DATABASE=Millenium P650 Low-profile PCI + +pci:v0000102Bd00002537sv0000102Bsd00002841* + ID_PRODUCT_FROM_DATABASE=RAD PCI + +pci:v0000102Bd00002537sv0000102Bsd00002851* + ID_PRODUCT_FROM_DATABASE=Spectrum PCI + +pci:v0000102Bd00002537sv0000102Bsd00002871* + ID_PRODUCT_FROM_DATABASE=EpicA TC2 + +pci:v0000102Bd00002537sv0000102Bsd00002C11* + ID_PRODUCT_FROM_DATABASE=QID Low-profile PCI + +pci:v0000102Bd00002537sv0000102Bsd00002C21* + ID_PRODUCT_FROM_DATABASE=QID LP PCI LW + +pci:v0000102Bd00002537sv0000102Bsd00002C31* + ID_PRODUCT_FROM_DATABASE=QID LP PCI + +pci:v0000102Bd00002537sv0000102Bsd00002C41* + ID_PRODUCT_FROM_DATABASE=EpicA TC4 + +pci:v0000102Bd00002537sv0000102Bsd00003001* + ID_PRODUCT_FROM_DATABASE=Extio F1400 + +pci:v0000102Bd00002537sv0000102Bsd00003011* + ID_PRODUCT_FROM_DATABASE=Extio F1220 + +pci:v0000102Bd00002537sv0000102Bsd00003041* + ID_PRODUCT_FROM_DATABASE=RG-200DL + +pci:v0000102Bd00002537sv0000102Bsd00003051* + ID_PRODUCT_FROM_DATABASE=RG-400SL + +pci:v0000102Bd00002537sv0000102Bsd00003061* + ID_PRODUCT_FROM_DATABASE=Extio F1420 + +pci:v0000102Bd00002537sv0000102Bsd00003081* + ID_PRODUCT_FROM_DATABASE=Extio F1240 + +pci:v0000102Bd00002538* + ID_PRODUCT_FROM_DATABASE=Millenium P650 PCIe + +pci:v0000102Bd00002538sv0000102Bsd00000847* + ID_PRODUCT_FROM_DATABASE=RAD PCIe + +pci:v0000102Bd00002538sv0000102Bsd000008C7* + ID_PRODUCT_FROM_DATABASE=Millennium P650 PCIe 128MB + +pci:v0000102Bd00002538sv0000102Bsd00000907* + ID_PRODUCT_FROM_DATABASE=Millennium P650 PCIe 64MB + +pci:v0000102Bd00002538sv0000102Bsd00000947* + ID_PRODUCT_FROM_DATABASE=Parhelia APVe + +pci:v0000102Bd00002538sv0000102Bsd00000987* + ID_PRODUCT_FROM_DATABASE=ATC PCIe 4MP + +pci:v0000102Bd00002538sv0000102Bsd00001047* + ID_PRODUCT_FROM_DATABASE=Millennium P650 LP PCIe 128MB + +pci:v0000102Bd00002538sv0000102Bsd00001087* + ID_PRODUCT_FROM_DATABASE=Millennium P650 LP PCIe 64MB + +pci:v0000102Bd00002538sv0000102Bsd00001801* + ID_PRODUCT_FROM_DATABASE=Millenium P650 PCIe x1 + +pci:v0000102Bd00002538sv0000102Bsd00002538* + ID_PRODUCT_FROM_DATABASE=Parhelia APVe + +pci:v0000102Bd00002538sv0000102Bsd00003007* + ID_PRODUCT_FROM_DATABASE=QID Low-profile PCIe + +pci:v0000102Bd00002538sv0000102Bsd00003087* + ID_PRODUCT_FROM_DATABASE=Aurora VX3mp + +pci:v0000102Bd00002538sv0000102Bsd000030C7* + ID_PRODUCT_FROM_DATABASE=QID LP PCIe + +pci:v0000102Bd00002539* + ID_PRODUCT_FROM_DATABASE=Millennium P690 + +pci:v0000102Bd00002539sv0000102Bsd00000040* + ID_PRODUCT_FROM_DATABASE=Millenium P690 PCIe x16 + +pci:v0000102Bd00002539sv0000102Bsd00000042* + ID_PRODUCT_FROM_DATABASE=ONYX + +pci:v0000102Bd00002539sv0000102Bsd00000043* + ID_PRODUCT_FROM_DATABASE=SPECTRA + +pci:v0000102Bd00002539sv0000102Bsd00000080* + ID_PRODUCT_FROM_DATABASE=Millenium P690 Plus LP PCIe x16 + +pci:v0000102Bd00002539sv0000102Bsd00000081* + ID_PRODUCT_FROM_DATABASE=Millenium P690 LP PCIe x16 + +pci:v0000102Bd00002539sv0000102Bsd00000082* + ID_PRODUCT_FROM_DATABASE=RAD LPX PCIe x16 + +pci:v0000102Bd00002539sv0000102Bsd000000C0* + ID_PRODUCT_FROM_DATABASE=Millenium P690 Plus LP PCI + +pci:v0000102Bd00002539sv0000102Bsd000000C2* + ID_PRODUCT_FROM_DATABASE=Millenium P690 LP PCI + +pci:v0000102Bd00002539sv0000102Bsd000000C3* + ID_PRODUCT_FROM_DATABASE=RAD LPX PCI + +pci:v0000102Bd00002539sv0000102Bsd00000101* + ID_PRODUCT_FROM_DATABASE=Millenium P690 PCI + +pci:v0000102Bd00002539sv0000102Bsd00000140* + ID_PRODUCT_FROM_DATABASE=Millenium P690 LP PCIe x1 + +pci:v0000102Bd00002539sv0000102Bsd00000180* + ID_PRODUCT_FROM_DATABASE=Display Wall IP Decode 128 MB + +pci:v0000102Bd00004164* + ID_PRODUCT_FROM_DATABASE=Morphis QxT frame grabber + +pci:v0000102Bd000043B4* + ID_PRODUCT_FROM_DATABASE=Morphis Qxt encoding engine + +pci:v0000102Bd00004510* + ID_PRODUCT_FROM_DATABASE=Morphis COM port + +pci:v0000102Bd00004536* + ID_PRODUCT_FROM_DATABASE=VIA Framegrabber + +pci:v0000102Bd00004686* + ID_PRODUCT_FROM_DATABASE=Concord GX (customized Intel 82541) + +pci:v0000102Bd0000475B* + ID_PRODUCT_FROM_DATABASE=Solios eCL/XCL-B frame grabber + +pci:v0000102Bd0000475D* + ID_PRODUCT_FROM_DATABASE=Vio frame grabber family + +pci:v0000102Bd0000475Dsv0000102Bsd00004B90* + ID_PRODUCT_FROM_DATABASE=Vio Duo frame grabber (single channel) + +pci:v0000102Bd0000475Dsv0000102Bsd00004B91* + ID_PRODUCT_FROM_DATABASE=Vio Duo frame grabber + +pci:v0000102Bd0000475Dsv0000102Bsd00004B92* + ID_PRODUCT_FROM_DATABASE=Vio Analog frame grabber + +pci:v0000102Bd0000475Dsv0000102Bsd00004B93* + ID_PRODUCT_FROM_DATABASE=Vio SDI Frame Grabber + +pci:v0000102Bd0000475Dsv0000102Bsd00004B94* + ID_PRODUCT_FROM_DATABASE=Vio DVI-A frame grabber + +pci:v0000102Bd0000475F* + ID_PRODUCT_FROM_DATABASE=Solios (single-Full) CL frame grabber + +pci:v0000102Bd0000475Fsv0000102Bsd0000475F* + ID_PRODUCT_FROM_DATABASE=Solios eCL/XCL-F frame grabber + +pci:v0000102Bd0000475Fsv0000102Bsd00004D5F* + ID_PRODUCT_FROM_DATABASE=Solios eV-CL (single-Full) frame grabber + +pci:v0000102Bd0000475Fsv0000102Bsd00004E5F* + ID_PRODUCT_FROM_DATABASE=Solios eM-CL (single-Full) frame grabber + +pci:v0000102Bd000047A1* + ID_PRODUCT_FROM_DATABASE=Solios eA/XA frame grabber + +pci:v0000102Bd000047A1sv0000102Bsd00004BE0* + ID_PRODUCT_FROM_DATABASE=Solios eA/XA (single) frame grabber + +pci:v0000102Bd000047A1sv0000102Bsd00004BE1* + ID_PRODUCT_FROM_DATABASE=Solios eA/XA (dual) frame grabber + +pci:v0000102Bd000047A1sv0000102Bsd00004BE2* + ID_PRODUCT_FROM_DATABASE=Solios eA/XA (quad) frame grabber + +pci:v0000102Bd000047A2* + ID_PRODUCT_FROM_DATABASE=Solios COM port + +pci:v0000102Bd000047C1* + ID_PRODUCT_FROM_DATABASE=Solios (dual-Base/single-Medium) CL frame grabber + +pci:v0000102Bd000047C1sv0000102Bsd00000000* + ID_PRODUCT_FROM_DATABASE=Solios frame grabber + +pci:v0000102Bd000047C1sv0000102Bsd00004B80* + ID_PRODUCT_FROM_DATABASE=Solios eCL/XCL (single-Medium) frame grabber + +pci:v0000102Bd000047C1sv0000102Bsd00004B81* + ID_PRODUCT_FROM_DATABASE=Solios eCL/XCL (dual-Base) frame grabber + +pci:v0000102Bd000047C1sv0000102Bsd00004D80* + ID_PRODUCT_FROM_DATABASE=Solios eV-CL (single-Medium) frame grabber + +pci:v0000102Bd000047C1sv0000102Bsd00004D81* + ID_PRODUCT_FROM_DATABASE=Solios eV-CL (dual-Base) frame grabber + +pci:v0000102Bd000047C1sv0000102Bsd00004E80* + ID_PRODUCT_FROM_DATABASE=Solios eM-CL (single-Medium) frame grabber + +pci:v0000102Bd000047C1sv0000102Bsd00004E81* + ID_PRODUCT_FROM_DATABASE=Solios eM-CL (dual-Base) frame grabber + +pci:v0000102Bd000047C2* + ID_PRODUCT_FROM_DATABASE=Solios COM port + +pci:v0000102Bd00004949* + ID_PRODUCT_FROM_DATABASE=Radient frame grabber family + +pci:v0000102Bd00004949sv0000102Bsd00000010* + ID_PRODUCT_FROM_DATABASE=Radient eCL (Single-full) frame grabber + +pci:v0000102Bd00004949sv0000102Bsd00000020* + ID_PRODUCT_FROM_DATABASE=Radient eCL (Dual-base) frame grabber + +pci:v0000102Bd00004949sv0000102Bsd00000030* + ID_PRODUCT_FROM_DATABASE=Radient eCL (Dual-full) frame grabber + +pci:v0000102Bd00004949sv0000102Bsd00000040* + ID_PRODUCT_FROM_DATABASE=Radient eCL (Quad-base) frame grabber + +pci:v0000102Bd00004949sv0000102Bsd00000050* + ID_PRODUCT_FROM_DATABASE=Radient eCL (Golden) frame grabber + +pci:v0000102Bd00004CDC* + ID_PRODUCT_FROM_DATABASE=Morphis JPEG2000 accelerator + +pci:v0000102Bd00004F54* + ID_PRODUCT_FROM_DATABASE=Morphis (e)Quad frame grabber + +pci:v0000102Bd00004FC5* + ID_PRODUCT_FROM_DATABASE=Morphis (e)Dual frame grabber + +pci:v0000102Bd00005E10* + ID_PRODUCT_FROM_DATABASE=Morphis aux I/O + +pci:v0000102Bd00006573* + ID_PRODUCT_FROM_DATABASE=Shark 10/100 Multiport SwitchNIC + +pci:v0000102C* + ID_VENDOR_FROM_DATABASE=Chips and Technologies + +pci:v0000102Cd000000B8* + ID_PRODUCT_FROM_DATABASE=F64310 + +pci:v0000102Cd000000C0* + ID_PRODUCT_FROM_DATABASE=F69000 HiQVideo + +pci:v0000102Cd000000C0sv0000102Csd000000C0* + ID_PRODUCT_FROM_DATABASE=F69000 HiQVideo + +pci:v0000102Cd000000C0sv00004C53sd00001000* + ID_PRODUCT_FROM_DATABASE=CC7/CR7/CP7/VC7/VP7/VR7 mainboard + +pci:v0000102Cd000000C0sv00004C53sd00001010* + ID_PRODUCT_FROM_DATABASE=CP5/CR6 mainboard + +pci:v0000102Cd000000C0sv00004C53sd00001020* + ID_PRODUCT_FROM_DATABASE=VR6 mainboard + +pci:v0000102Cd000000C0sv00004C53sd00001030* + ID_PRODUCT_FROM_DATABASE=PC5 mainboard + +pci:v0000102Cd000000C0sv00004C53sd00001050* + ID_PRODUCT_FROM_DATABASE=CT7 mainboard + +pci:v0000102Cd000000C0sv00004C53sd00001051* + ID_PRODUCT_FROM_DATABASE=CE7 mainboard + +pci:v0000102Cd000000D0* + ID_PRODUCT_FROM_DATABASE=F65545 + +pci:v0000102Cd000000D8* + ID_PRODUCT_FROM_DATABASE=F65545 + +pci:v0000102Cd000000DC* + ID_PRODUCT_FROM_DATABASE=F65548 + +pci:v0000102Cd000000E0* + ID_PRODUCT_FROM_DATABASE=F65550 + +pci:v0000102Cd000000E4* + ID_PRODUCT_FROM_DATABASE=F65554 + +pci:v0000102Cd000000E5* + ID_PRODUCT_FROM_DATABASE=F65555 HiQVPro + +pci:v0000102Cd000000E5sv00000E11sd0000B049* + ID_PRODUCT_FROM_DATABASE=Armada 1700 Laptop Display Controller + +pci:v0000102Cd000000E5sv00001179sd00000001* + ID_PRODUCT_FROM_DATABASE=Satellite Pro/Satellite + +pci:v0000102Cd000000F0* + ID_PRODUCT_FROM_DATABASE=F68554 + +pci:v0000102Cd000000F4* + ID_PRODUCT_FROM_DATABASE=F68554 HiQVision + +pci:v0000102Cd000000F5* + ID_PRODUCT_FROM_DATABASE=F68555 + +pci:v0000102Cd00000C30* + ID_PRODUCT_FROM_DATABASE=F69030 + +pci:v0000102Cd00000C30sv00004C53sd00001000* + ID_PRODUCT_FROM_DATABASE=CC7/CR7/CP7/VC7/VP7/VR7 mainboard + +pci:v0000102Cd00000C30sv00004C53sd00001050* + ID_PRODUCT_FROM_DATABASE=CT7 mainboard + +pci:v0000102Cd00000C30sv00004C53sd00001051* + ID_PRODUCT_FROM_DATABASE=CE7 mainboard + +pci:v0000102Cd00000C30sv00004C53sd00001080* + ID_PRODUCT_FROM_DATABASE=CT8 mainboard + +pci:v0000102D* + ID_VENDOR_FROM_DATABASE=Wyse Technology Inc. + +pci:v0000102Dd000050DC* + ID_PRODUCT_FROM_DATABASE=3328 Audio + +pci:v0000102E* + ID_VENDOR_FROM_DATABASE=Olivetti Advanced Technology + +pci:v0000102F* + ID_VENDOR_FROM_DATABASE=Toshiba America + +pci:v0000102Fd00000009* + ID_PRODUCT_FROM_DATABASE=r4x00 + +pci:v0000102Fd0000000A* + ID_PRODUCT_FROM_DATABASE=TX3927 MIPS RISC PCI Controller + +pci:v0000102Fd00000020* + ID_PRODUCT_FROM_DATABASE=ATM Meteor 155 + +pci:v0000102Fd00000020sv0000102Fsd000000F8* + ID_PRODUCT_FROM_DATABASE=ATM Meteor 155 + +pci:v0000102Fd00000030* + ID_PRODUCT_FROM_DATABASE=TC35815CF PCI 10/100 Mbit Ethernet Controller + +pci:v0000102Fd00000031* + ID_PRODUCT_FROM_DATABASE=TC35815CF PCI 10/100 Mbit Ethernet Controller with WOL + +pci:v0000102Fd00000032* + ID_PRODUCT_FROM_DATABASE=TC35815CF PCI 10/100 Mbit Ethernet Controller on TX4939 + +pci:v0000102Fd00000105* + ID_PRODUCT_FROM_DATABASE=TC86C001 [goku-s] IDE + +pci:v0000102Fd00000106* + ID_PRODUCT_FROM_DATABASE=TC86C001 [goku-s] USB 1.1 Host + +pci:v0000102Fd00000107* + ID_PRODUCT_FROM_DATABASE=TC86C001 [goku-s] USB Device Controller + +pci:v0000102Fd00000108* + ID_PRODUCT_FROM_DATABASE=TC86C001 [goku-s] I2C/SIO/GPIO Controller + +pci:v0000102Fd00000180* + ID_PRODUCT_FROM_DATABASE=TX4927/38 MIPS RISC PCI Controller + +pci:v0000102Fd00000181* + ID_PRODUCT_FROM_DATABASE=TX4925 MIPS RISC PCI Controller + +pci:v0000102Fd00000182* + ID_PRODUCT_FROM_DATABASE=TX4937 MIPS RISC PCI Controller + +pci:v0000102Fd000001B4* + ID_PRODUCT_FROM_DATABASE=Celleb platform IDE interface + +pci:v0000102Fd000001B5* + ID_PRODUCT_FROM_DATABASE=SCC USB 2.0 EHCI controller + +pci:v0000102Fd000001B6* + ID_PRODUCT_FROM_DATABASE=SCC USB 1.1 OHCI controller + +pci:v00001030* + ID_VENDOR_FROM_DATABASE=TMC Research + +pci:v00001031* + ID_VENDOR_FROM_DATABASE=Miro Computer Products AG + +pci:v00001031d00005601* + ID_PRODUCT_FROM_DATABASE=DC20 ASIC + +pci:v00001031d00005607* + ID_PRODUCT_FROM_DATABASE=Video I/O & motion JPEG compressor + +pci:v00001031d00005631* + ID_PRODUCT_FROM_DATABASE=Media 3D + +pci:v00001031d00006057* + ID_PRODUCT_FROM_DATABASE=MiroVideo DC10/DC30+ + +pci:v00001032* + ID_VENDOR_FROM_DATABASE=Compaq + +pci:v00001033* + ID_VENDOR_FROM_DATABASE=NEC Corporation + +pci:v00001033d00000000* + ID_PRODUCT_FROM_DATABASE=Vr4181A USB Host or Function Control Unit + +pci:v00001033d00000001* + ID_PRODUCT_FROM_DATABASE=PCI to 486-like bus Bridge + +pci:v00001033d00000002* + ID_PRODUCT_FROM_DATABASE=PCI to VL98 Bridge + +pci:v00001033d00000003* + ID_PRODUCT_FROM_DATABASE=ATM Controller + +pci:v00001033d00000004* + ID_PRODUCT_FROM_DATABASE=R4000 PCI Bridge + +pci:v00001033d00000005* + ID_PRODUCT_FROM_DATABASE=PCI to 486-like bus Bridge + +pci:v00001033d00000006* + ID_PRODUCT_FROM_DATABASE=PC-9800 Graphic Accelerator + +pci:v00001033d00000007* + ID_PRODUCT_FROM_DATABASE=PCI to UX-Bus Bridge + +pci:v00001033d00000008* + ID_PRODUCT_FROM_DATABASE=PC-9800 Graphic Accelerator + +pci:v00001033d00000009* + ID_PRODUCT_FROM_DATABASE=PCI to PC9800 Core-Graph Bridge + +pci:v00001033d00000016* + ID_PRODUCT_FROM_DATABASE=PCI to VL Bridge + +pci:v00001033d0000001A* + ID_PRODUCT_FROM_DATABASE=[Nile II] + +pci:v00001033d00000021* + ID_PRODUCT_FROM_DATABASE=Vrc4373 [Nile I] + +pci:v00001033d00000029* + ID_PRODUCT_FROM_DATABASE=PowerVR PCX1 + +pci:v00001033d0000002A* + ID_PRODUCT_FROM_DATABASE=PowerVR 3D + +pci:v00001033d0000002C* + ID_PRODUCT_FROM_DATABASE=Star Alpha 2 + +pci:v00001033d0000002D* + ID_PRODUCT_FROM_DATABASE=PCI to C-bus Bridge + +pci:v00001033d00000035* + ID_PRODUCT_FROM_DATABASE=USB + +pci:v00001033d00000035sv00001033sd00000035* + ID_PRODUCT_FROM_DATABASE=Hama USB 2.0 CardBus + +pci:v00001033d00000035sv0000103Csd00001293* + ID_PRODUCT_FROM_DATABASE=USB add-in card + +pci:v00001033d00000035sv0000103Csd00001294* + ID_PRODUCT_FROM_DATABASE=USB 2.0 add-in card + +pci:v00001033d00000035sv00001179sd00000001* + ID_PRODUCT_FROM_DATABASE=USB + +pci:v00001033d00000035sv000012EEsd00007000* + ID_PRODUCT_FROM_DATABASE=Root Hub + +pci:v00001033d00000035sv000014C2sd00000105* + ID_PRODUCT_FROM_DATABASE=PTI-205N USB 2.0 Host Controller + +pci:v00001033d00000035sv00001799sd00000001* + ID_PRODUCT_FROM_DATABASE=Root Hub + +pci:v00001033d00000035sv00001931sd0000000A* + ID_PRODUCT_FROM_DATABASE=GlobeTrotter Fusion Quad Lite (PPP data) + +pci:v00001033d00000035sv00001931sd0000000B* + ID_PRODUCT_FROM_DATABASE=GlobeTrotter Fusion Quad Lite (GSM data) + +pci:v00001033d00000035sv0000807Dsd00000035* + ID_PRODUCT_FROM_DATABASE=PCI-USB2 (OHCI subsystem) + +pci:v00001033d0000003B* + ID_PRODUCT_FROM_DATABASE=PCI to C-bus Bridge + +pci:v00001033d0000003E* + ID_PRODUCT_FROM_DATABASE=NAPCCARD Cardbus Controller + +pci:v00001033d00000046* + ID_PRODUCT_FROM_DATABASE=PowerVR PCX2 [midas] + +pci:v00001033d0000005A* + ID_PRODUCT_FROM_DATABASE=Vrc5074 [Nile 4] + +pci:v00001033d00000063* + ID_PRODUCT_FROM_DATABASE=uPD72862 [Firewarden] IEEE1394 OHCI 1.0 Link Controller + +pci:v00001033d00000067* + ID_PRODUCT_FROM_DATABASE=PowerVR Neon 250 Chipset + +pci:v00001033d00000067sv00001010sd00000020* + ID_PRODUCT_FROM_DATABASE=PowerVR Neon 250 AGP 32Mb + +pci:v00001033d00000067sv00001010sd00000080* + ID_PRODUCT_FROM_DATABASE=PowerVR Neon 250 AGP 16Mb + +pci:v00001033d00000067sv00001010sd00000088* + ID_PRODUCT_FROM_DATABASE=PowerVR Neon 250 16Mb + +pci:v00001033d00000067sv00001010sd00000090* + ID_PRODUCT_FROM_DATABASE=PowerVR Neon 250 AGP 16Mb + +pci:v00001033d00000067sv00001010sd00000098* + ID_PRODUCT_FROM_DATABASE=PowerVR Neon 250 16Mb + +pci:v00001033d00000067sv00001010sd000000A0* + ID_PRODUCT_FROM_DATABASE=PowerVR Neon 250 AGP 32Mb + +pci:v00001033d00000067sv00001010sd000000A8* + ID_PRODUCT_FROM_DATABASE=PowerVR Neon 250 32Mb + +pci:v00001033d00000067sv00001010sd00000120* + ID_PRODUCT_FROM_DATABASE=PowerVR Neon 250 AGP 32Mb + +pci:v00001033d00000072* + ID_PRODUCT_FROM_DATABASE=uPD72874 IEEE1394 OHCI 1.1 3-port PHY-Link Ctrlr + +pci:v00001033d00000074* + ID_PRODUCT_FROM_DATABASE=56k Voice Modem + +pci:v00001033d00000074sv00001033sd00008014* + ID_PRODUCT_FROM_DATABASE=RCV56ACF 56k Voice Modem + +pci:v00001033d0000009B* + ID_PRODUCT_FROM_DATABASE=Vrc5476 + +pci:v00001033d000000A5* + ID_PRODUCT_FROM_DATABASE=VRC4173 + +pci:v00001033d000000A6* + ID_PRODUCT_FROM_DATABASE=VRC5477 AC97 + +pci:v00001033d000000CD* + ID_PRODUCT_FROM_DATABASE=uPD72870 [Firewarden] IEEE1394a OHCI 1.0 Link/3-port PHY Controller + +pci:v00001033d000000CDsv000012EEsd00008011* + ID_PRODUCT_FROM_DATABASE=Root hub + +pci:v00001033d000000CE* + ID_PRODUCT_FROM_DATABASE=uPD72871 [Firewarden] IEEE1394a OHCI 1.0 Link/1-port PHY Controller + +pci:v00001033d000000DF* + ID_PRODUCT_FROM_DATABASE=Vr4131 + +pci:v00001033d000000E0* + ID_PRODUCT_FROM_DATABASE=USB 2.0 + +pci:v00001033d000000E0sv000012EEsd00007001* + ID_PRODUCT_FROM_DATABASE=Root hub + +pci:v00001033d000000E0sv000014C2sd00000205* + ID_PRODUCT_FROM_DATABASE=PTI-205N USB 2.0 Host Controller + +pci:v00001033d000000E0sv00001799sd00000002* + ID_PRODUCT_FROM_DATABASE=Root Hub + +pci:v00001033d000000E0sv0000807Dsd00001043* + ID_PRODUCT_FROM_DATABASE=PCI-USB2 (EHCI subsystem) + +pci:v00001033d000000E7* + ID_PRODUCT_FROM_DATABASE=uPD72873 [Firewarden] IEEE1394a OHCI 1.1 Link/2-port PHY Controller + +pci:v00001033d000000F2* + ID_PRODUCT_FROM_DATABASE=uPD72874 [Firewarden] IEEE1394a OHCI 1.1 Link/3-port PHY Controller + +pci:v00001033d000000F3* + ID_PRODUCT_FROM_DATABASE=uPD6113x Multimedia Decoder/Processor [EMMA2] + +pci:v00001033d0000010C* + ID_PRODUCT_FROM_DATABASE=VR7701 + +pci:v00001033d00000125* + ID_PRODUCT_FROM_DATABASE=uPD720400 PCI Express - PCI/PCI-X Bridge + +pci:v00001033d0000013A* + ID_PRODUCT_FROM_DATABASE=Dual Tuner/MPEG Encoder + +pci:v00001033d00000194* + ID_PRODUCT_FROM_DATABASE=uPD720200 USB 3.0 Host Controller + +pci:v00001033d00000194sv00001028sd000004B2* + ID_PRODUCT_FROM_DATABASE=Vostro 3350 + +pci:v00001033d00000194sv00001028sd000004DA* + ID_PRODUCT_FROM_DATABASE=Vostro 3750 + +pci:v00001033d00000194sv00001043sd00008413* + ID_PRODUCT_FROM_DATABASE=P8P67 Deluxe Motherboard + +pci:v00001033d00000194sv00001B96sd00000001* + ID_PRODUCT_FROM_DATABASE=USB 3.0 PCIe Card + +pci:v00001033d000001E7* + ID_PRODUCT_FROM_DATABASE=uPD72873 [Firewarden] IEEE1394a OHCI 1.1 Link/2-port PHY Controller + +pci:v00001033d000001F2* + ID_PRODUCT_FROM_DATABASE=uPD72874 [Firewarden] IEEE1394a OHCI 1.1 Link/3-port PHY Controller + +pci:v00001034* + ID_VENDOR_FROM_DATABASE=Framatome Connectors USA Inc. + +pci:v00001035* + ID_VENDOR_FROM_DATABASE=Comp. & Comm. Research Lab + +pci:v00001036* + ID_VENDOR_FROM_DATABASE=Future Domain Corp. + +pci:v00001036d00000000* + ID_PRODUCT_FROM_DATABASE=TMC-18C30 [36C70] + +pci:v00001037* + ID_VENDOR_FROM_DATABASE=Hitachi Micro Systems + +pci:v00001038* + ID_VENDOR_FROM_DATABASE=AMP, Inc + +pci:v00001039* + ID_VENDOR_FROM_DATABASE=Silicon Integrated Systems [SiS] + +pci:v00001039d00000001* + ID_PRODUCT_FROM_DATABASE=AGP Port (virtual PCI-to-PCI bridge) + +pci:v00001039d00000002* + ID_PRODUCT_FROM_DATABASE=AGP Port (virtual PCI-to-PCI bridge) + +pci:v00001039d00000003* + ID_PRODUCT_FROM_DATABASE=AGP Port (virtual PCI-to-PCI bridge) + +pci:v00001039d00000004* + ID_PRODUCT_FROM_DATABASE=PCI-to-PCI bridge + +pci:v00001039d00000006* + ID_PRODUCT_FROM_DATABASE=85C501/2/3 + +pci:v00001039d00000008* + ID_PRODUCT_FROM_DATABASE=SiS85C503/5513 (LPC Bridge) + +pci:v00001039d00000009* + ID_PRODUCT_FROM_DATABASE=5595 Power Management Controller + +pci:v00001039d0000000A* + ID_PRODUCT_FROM_DATABASE=PCI-to-PCI bridge + +pci:v00001039d00000016* + ID_PRODUCT_FROM_DATABASE=SiS961/2/3 SMBus controller + +pci:v00001039d00000018* + ID_PRODUCT_FROM_DATABASE=SiS85C503/5513 (LPC Bridge) + +pci:v00001039d00000180* + ID_PRODUCT_FROM_DATABASE=RAID bus controller 180 SATA/PATA [SiS] + +pci:v00001039d00000181* + ID_PRODUCT_FROM_DATABASE=SATA + +pci:v00001039d00000182* + ID_PRODUCT_FROM_DATABASE=182 SATA/RAID Controller + +pci:v00001039d00000182sv00001734sd00001095* + ID_PRODUCT_FROM_DATABASE=D2030-A1 + +pci:v00001039d00000186* + ID_PRODUCT_FROM_DATABASE=AHCI Controller (0106) + +pci:v00001039d00000190* + ID_PRODUCT_FROM_DATABASE=190 Ethernet Adapter + +pci:v00001039d00000191* + ID_PRODUCT_FROM_DATABASE=191 Gigabit Ethernet Adapter + +pci:v00001039d00000200* + ID_PRODUCT_FROM_DATABASE=5597/5598/6326 VGA + +pci:v00001039d00000200sv00001039sd00000000* + ID_PRODUCT_FROM_DATABASE=SiS5597 SVGA (Shared RAM) + +pci:v00001039d00000204* + ID_PRODUCT_FROM_DATABASE=82C204 + +pci:v00001039d00000205* + ID_PRODUCT_FROM_DATABASE=SG86C205 + +pci:v00001039d00000300* + ID_PRODUCT_FROM_DATABASE=300/305 PCI/AGP VGA Display Adapter + +pci:v00001039d00000300sv0000107Dsd00002720* + ID_PRODUCT_FROM_DATABASE=Leadtek WinFast VR300 + +pci:v00001039d00000310* + ID_PRODUCT_FROM_DATABASE=315H PCI/AGP VGA Display Adapter + +pci:v00001039d00000315* + ID_PRODUCT_FROM_DATABASE=315 PCI/AGP VGA Display Adapter + +pci:v00001039d00000325* + ID_PRODUCT_FROM_DATABASE=315PRO PCI/AGP VGA Display Adapter + +pci:v00001039d00000330* + ID_PRODUCT_FROM_DATABASE=330 [Xabre] PCI/AGP VGA Display Adapter + +pci:v00001039d00000406* + ID_PRODUCT_FROM_DATABASE=85C501/2 + +pci:v00001039d00000496* + ID_PRODUCT_FROM_DATABASE=85C496 + +pci:v00001039d00000530* + ID_PRODUCT_FROM_DATABASE=530 Host + +pci:v00001039d00000540* + ID_PRODUCT_FROM_DATABASE=540 Host + +pci:v00001039d00000550* + ID_PRODUCT_FROM_DATABASE=550 Host + +pci:v00001039d00000597* + ID_PRODUCT_FROM_DATABASE=5513C + +pci:v00001039d00000601* + ID_PRODUCT_FROM_DATABASE=85C601 + +pci:v00001039d00000620* + ID_PRODUCT_FROM_DATABASE=620 Host + +pci:v00001039d00000630* + ID_PRODUCT_FROM_DATABASE=630 Host + +pci:v00001039d00000633* + ID_PRODUCT_FROM_DATABASE=633 Host + +pci:v00001039d00000635* + ID_PRODUCT_FROM_DATABASE=635 Host + +pci:v00001039d00000645* + ID_PRODUCT_FROM_DATABASE=SiS645 Host & Memory & AGP Controller + +pci:v00001039d00000646* + ID_PRODUCT_FROM_DATABASE=SiS645DX Host & Memory & AGP Controller + +pci:v00001039d00000648* + ID_PRODUCT_FROM_DATABASE=645xx + +pci:v00001039d00000649* + ID_PRODUCT_FROM_DATABASE=SiS649 Host + +pci:v00001039d00000650* + ID_PRODUCT_FROM_DATABASE=650/M650 Host + +pci:v00001039d00000651* + ID_PRODUCT_FROM_DATABASE=651 Host + +pci:v00001039d00000655* + ID_PRODUCT_FROM_DATABASE=655 Host + +pci:v00001039d00000660* + ID_PRODUCT_FROM_DATABASE=660 Host + +pci:v00001039d00000661* + ID_PRODUCT_FROM_DATABASE=661FX/M661FX/M661MX Host + +pci:v00001039d00000662* + ID_PRODUCT_FROM_DATABASE=662 Host + +pci:v00001039d00000671* + ID_PRODUCT_FROM_DATABASE=671MX + +pci:v00001039d00000730* + ID_PRODUCT_FROM_DATABASE=730 Host + +pci:v00001039d00000733* + ID_PRODUCT_FROM_DATABASE=733 Host + +pci:v00001039d00000735* + ID_PRODUCT_FROM_DATABASE=735 Host + +pci:v00001039d00000740* + ID_PRODUCT_FROM_DATABASE=740 Host + +pci:v00001039d00000741* + ID_PRODUCT_FROM_DATABASE=741/741GX/M741 Host + +pci:v00001039d00000741sv00001849sd00000741* + ID_PRODUCT_FROM_DATABASE=K7S41/K7S41GX motherboard + +pci:v00001039d00000745* + ID_PRODUCT_FROM_DATABASE=745 Host + +pci:v00001039d00000746* + ID_PRODUCT_FROM_DATABASE=746 Host + +pci:v00001039d00000755* + ID_PRODUCT_FROM_DATABASE=755 Host + +pci:v00001039d00000760* + ID_PRODUCT_FROM_DATABASE=760/M760 Host + +pci:v00001039d00000761* + ID_PRODUCT_FROM_DATABASE=761/M761 Host + +pci:v00001039d00000761sv00001734sd00001099* + ID_PRODUCT_FROM_DATABASE=D2030-A1 Motherboard + +pci:v00001039d00000900* + ID_PRODUCT_FROM_DATABASE=SiS900 PCI Fast Ethernet + +pci:v00001039d00000900sv00001019sd00000A14* + ID_PRODUCT_FROM_DATABASE=K7S5A motherboard + +pci:v00001039d00000900sv00001039sd00000900* + ID_PRODUCT_FROM_DATABASE=SiS900 10/100 Ethernet Adapter onboard [Asus P4SC-EA] + +pci:v00001039d00000900sv00001043sd00008035* + ID_PRODUCT_FROM_DATABASE=CUSI-FX motherboard + +pci:v00001039d00000900sv00001043sd000080A7* + ID_PRODUCT_FROM_DATABASE=Motherboard P4S800D-X + +pci:v00001039d00000900sv00001462sd00000900* + ID_PRODUCT_FROM_DATABASE=MS-6701 motherboard + +pci:v00001039d00000961* + ID_PRODUCT_FROM_DATABASE=SiS961 [MuTIOL Media IO] + +pci:v00001039d00000962* + ID_PRODUCT_FROM_DATABASE=SiS962 [MuTIOL Media IO] LPC Controller + +pci:v00001039d00000963* + ID_PRODUCT_FROM_DATABASE=SiS963 [MuTIOL Media IO] LPC Controller + +pci:v00001039d00000964* + ID_PRODUCT_FROM_DATABASE=SiS964 [MuTIOL Media IO] LPC Controller + +pci:v00001039d00000965* + ID_PRODUCT_FROM_DATABASE=SiS965 [MuTIOL Media IO] + +pci:v00001039d00000966* + ID_PRODUCT_FROM_DATABASE=SiS966 [MuTIOL Media IO] + +pci:v00001039d00000968* + ID_PRODUCT_FROM_DATABASE=SiS968 [MuTIOL Media IO] + +pci:v00001039d00001180* + ID_PRODUCT_FROM_DATABASE=SATA Controller / IDE mode + +pci:v00001039d00001182* + ID_PRODUCT_FROM_DATABASE=SATA Controller / RAID mode + +pci:v00001039d00001183* + ID_PRODUCT_FROM_DATABASE=SATA Controller / IDE mode + +pci:v00001039d00001184* + ID_PRODUCT_FROM_DATABASE=AHCI Controller / RAID mode + +pci:v00001039d00001185* + ID_PRODUCT_FROM_DATABASE=AHCI IDE Controller (0106) + +pci:v00001039d00003602* + ID_PRODUCT_FROM_DATABASE=83C602 + +pci:v00001039d00005107* + ID_PRODUCT_FROM_DATABASE=5107 + +pci:v00001039d00005300* + ID_PRODUCT_FROM_DATABASE=SiS540 PCI Display Adapter + +pci:v00001039d00005315* + ID_PRODUCT_FROM_DATABASE=550 PCI/AGP VGA Display Adapter + +pci:v00001039d00005401* + ID_PRODUCT_FROM_DATABASE=486 PCI Chipset + +pci:v00001039d00005511* + ID_PRODUCT_FROM_DATABASE=5511/5512 + +pci:v00001039d00005513* + ID_PRODUCT_FROM_DATABASE=5513 IDE Controller + +pci:v00001039d00005513sv00001019sd00000970* + ID_PRODUCT_FROM_DATABASE=P6STP-FL motherboard + +pci:v00001039d00005513sv00001039sd00005513* + ID_PRODUCT_FROM_DATABASE=SiS5513 EIDE Controller (A,B step) + +pci:v00001039d00005513sv00001043sd00008035* + ID_PRODUCT_FROM_DATABASE=CUSI-FX motherboard + +pci:v00001039d00005513sv00001462sd00007010* + ID_PRODUCT_FROM_DATABASE=MS-6701 motherboard + +pci:v00001039d00005513sv00001631sd00005513* + ID_PRODUCT_FROM_DATABASE=GA-8SIML Rev1.0 Motherboard + +pci:v00001039d00005513sv00001734sd00001095* + ID_PRODUCT_FROM_DATABASE=D2030-A1 Motherboard + +pci:v00001039d00005517* + ID_PRODUCT_FROM_DATABASE=5517 + +pci:v00001039d00005571* + ID_PRODUCT_FROM_DATABASE=5571 + +pci:v00001039d00005581* + ID_PRODUCT_FROM_DATABASE=5581 Pentium Chipset + +pci:v00001039d00005582* + ID_PRODUCT_FROM_DATABASE=5582 + +pci:v00001039d00005591* + ID_PRODUCT_FROM_DATABASE=5591/5592 Host + +pci:v00001039d00005596* + ID_PRODUCT_FROM_DATABASE=5596 Pentium Chipset + +pci:v00001039d00005597* + ID_PRODUCT_FROM_DATABASE=5597 [SiS5582] + +pci:v00001039d00005600* + ID_PRODUCT_FROM_DATABASE=5600 Host + +pci:v00001039d00006204* + ID_PRODUCT_FROM_DATABASE=Video decoder & MPEG interface + +pci:v00001039d00006205* + ID_PRODUCT_FROM_DATABASE=VGA Controller + +pci:v00001039d00006236* + ID_PRODUCT_FROM_DATABASE=6236 3D-AGP + +pci:v00001039d00006300* + ID_PRODUCT_FROM_DATABASE=630/730 PCI/AGP VGA Display Adapter + +pci:v00001039d00006300sv00001019sd00000970* + ID_PRODUCT_FROM_DATABASE=P6STP-FL motherboard + +pci:v00001039d00006300sv00001043sd00008035* + ID_PRODUCT_FROM_DATABASE=CUSI-FX motherboard + +pci:v00001039d00006300sv0000104Dsd000080E2* + ID_PRODUCT_FROM_DATABASE=VAIO PCV-J200 + +pci:v00001039d00006306* + ID_PRODUCT_FROM_DATABASE=530/620 PCI/AGP VGA Display Adapter + +pci:v00001039d00006325* + ID_PRODUCT_FROM_DATABASE=65x/M650/740 PCI/AGP VGA Display Adapter + +pci:v00001039d00006325sv00001039sd00006325* + ID_PRODUCT_FROM_DATABASE=SiS 651 onboard [Asus P4SC-EA] + +pci:v00001039d00006325sv00001631sd00001004* + ID_PRODUCT_FROM_DATABASE=SiS 651C onboard [Gigabyte GA-8SIML Rev1.0] + +pci:v00001039d00006326* + ID_PRODUCT_FROM_DATABASE=86C326 5598/6326 + +pci:v00001039d00006326sv00001039sd00006326* + ID_PRODUCT_FROM_DATABASE=SiS6326 GUI Accelerator + +pci:v00001039d00006326sv00001092sd00000A50* + ID_PRODUCT_FROM_DATABASE=SpeedStar A50 + +pci:v00001039d00006326sv00001092sd00000A70* + ID_PRODUCT_FROM_DATABASE=SpeedStar A70 + +pci:v00001039d00006326sv00001092sd00004910* + ID_PRODUCT_FROM_DATABASE=SpeedStar A70 + +pci:v00001039d00006326sv00001092sd00004920* + ID_PRODUCT_FROM_DATABASE=SpeedStar A70 + +pci:v00001039d00006326sv000010B0sd00006326* + ID_PRODUCT_FROM_DATABASE=S6110-B (AGP) + +pci:v00001039d00006326sv00001569sd00006326* + ID_PRODUCT_FROM_DATABASE=SiS6326 GUI Accelerator + +pci:v00001039d00006330* + ID_PRODUCT_FROM_DATABASE=661/741/760 PCI/AGP or 662/761Gx PCIE VGA Display Adapter + +pci:v00001039d00006330sv00001039sd00006330* + ID_PRODUCT_FROM_DATABASE=[M]661xX/[M]741[GX]/[M]760 PCI/AGP VGA Adapter + +pci:v00001039d00006330sv00001043sd00008113* + ID_PRODUCT_FROM_DATABASE=SiS Real 256E (ASUS P5S800-VM motherboard) + +pci:v00001039d00006330sv00001458sd0000D000* + ID_PRODUCT_FROM_DATABASE=SiS661FX GUI 2D/3D Accelerator + +pci:v00001039d00006330sv00001734sd00001099* + ID_PRODUCT_FROM_DATABASE=D2030-A1 + +pci:v00001039d00006350* + ID_PRODUCT_FROM_DATABASE=770/670 PCIE VGA Display Adapter + +pci:v00001039d00006351* + ID_PRODUCT_FROM_DATABASE=771/671 PCIE VGA Display Adapter + +pci:v00001039d00007001* + ID_PRODUCT_FROM_DATABASE=USB 1.1 Controller + +pci:v00001039d00007001sv00001019sd00000A14* + ID_PRODUCT_FROM_DATABASE=K7S5A motherboard + +pci:v00001039d00007001sv00001039sd00007000* + ID_PRODUCT_FROM_DATABASE=Onboard USB Controller + +pci:v00001039d00007001sv00001462sd00005470* + ID_PRODUCT_FROM_DATABASE=ECS K7SOM+ motherboard + +pci:v00001039d00007001sv00001462sd00007010* + ID_PRODUCT_FROM_DATABASE=MS-6701 motherboard + +pci:v00001039d00007001sv00001734sd00001095* + ID_PRODUCT_FROM_DATABASE=D2030-A1 Motherboard + +pci:v00001039d00007002* + ID_PRODUCT_FROM_DATABASE=USB 2.0 Controller + +pci:v00001039d00007002sv00001462sd00005470* + ID_PRODUCT_FROM_DATABASE=K7SOM+ 5.2C Motherboard + +pci:v00001039d00007002sv00001462sd00007010* + ID_PRODUCT_FROM_DATABASE=MS-6701 motherboard + +pci:v00001039d00007002sv00001509sd00007002* + ID_PRODUCT_FROM_DATABASE=Onboard USB Controller + +pci:v00001039d00007002sv00001734sd00001095* + ID_PRODUCT_FROM_DATABASE=D2030-A1 + +pci:v00001039d00007007* + ID_PRODUCT_FROM_DATABASE=FireWire Controller + +pci:v00001039d00007007sv00001462sd0000701D* + ID_PRODUCT_FROM_DATABASE=MS-6701 + +pci:v00001039d00007012* + ID_PRODUCT_FROM_DATABASE=SiS7012 AC'97 Sound Controller + +pci:v00001039d00007012sv00001019sd00000F05* + ID_PRODUCT_FROM_DATABASE=A928 (i-Buddie) + +pci:v00001039d00007012sv00001039sd00007012* + ID_PRODUCT_FROM_DATABASE=SiS 7012 onboard [Asus P4SC-EA] AC'97 Sound Controller + +pci:v00001039d00007012sv00001043sd0000818F* + ID_PRODUCT_FROM_DATABASE=A8S-X Motherboard + +pci:v00001039d00007012sv000013F6sd00000300* + ID_PRODUCT_FROM_DATABASE=CMI9739(A) on ECS K7SOM+ motherboard + +pci:v00001039d00007012sv00001462sd00005850* + ID_PRODUCT_FROM_DATABASE=MSI 648 Max (MS-6585) + +pci:v00001039d00007012sv00001462sd00007010* + ID_PRODUCT_FROM_DATABASE=MS-6701 motherboard + +pci:v00001039d00007012sv000015BDsd00001001* + ID_PRODUCT_FROM_DATABASE=DFI 661FX motherboard + +pci:v00001039d00007012sv00001734sd0000109F* + ID_PRODUCT_FROM_DATABASE=D2030-A1 Motherboard + +pci:v00001039d00007012sv00001849sd00007012* + ID_PRODUCT_FROM_DATABASE=K7S41GX motherboard + +pci:v00001039d00007013* + ID_PRODUCT_FROM_DATABASE=AC'97 Modem Controller + +pci:v00001039d00007016* + ID_PRODUCT_FROM_DATABASE=SiS7016 PCI Fast Ethernet Adapter + +pci:v00001039d00007016sv00001039sd00007016* + ID_PRODUCT_FROM_DATABASE=SiS7016 10/100 Ethernet Adapter + +pci:v00001039d00007018* + ID_PRODUCT_FROM_DATABASE=SiS PCI Audio Accelerator + +pci:v00001039d00007018sv00001014sd000001B6* + ID_PRODUCT_FROM_DATABASE=SiS PCI Audio Accelerator + +pci:v00001039d00007018sv00001014sd000001B7* + ID_PRODUCT_FROM_DATABASE=SiS PCI Audio Accelerator + +pci:v00001039d00007018sv00001019sd00007018* + ID_PRODUCT_FROM_DATABASE=SiS PCI Audio Accelerator + +pci:v00001039d00007018sv00001025sd0000000E* + ID_PRODUCT_FROM_DATABASE=SiS PCI Audio Accelerator + +pci:v00001039d00007018sv00001025sd00000018* + ID_PRODUCT_FROM_DATABASE=SiS PCI Audio Accelerator + +pci:v00001039d00007018sv00001039sd00007018* + ID_PRODUCT_FROM_DATABASE=SiS PCI Audio Accelerator + +pci:v00001039d00007018sv00001043sd00001453* + ID_PRODUCT_FROM_DATABASE=SiS PCI Audio Accelerator + +pci:v00001039d00007018sv00001043sd0000800B* + ID_PRODUCT_FROM_DATABASE=SiS PCI Audio Accelerator + +pci:v00001039d00007018sv0000104Dsd000080E2* + ID_PRODUCT_FROM_DATABASE=VAIO PCV-J200 + +pci:v00001039d00007018sv00001054sd00007018* + ID_PRODUCT_FROM_DATABASE=SiS PCI Audio Accelerator + +pci:v00001039d00007018sv0000107Dsd00005330* + ID_PRODUCT_FROM_DATABASE=SiS PCI Audio Accelerator + +pci:v00001039d00007018sv0000107Dsd00005350* + ID_PRODUCT_FROM_DATABASE=SiS PCI Audio Accelerator + +pci:v00001039d00007018sv00001170sd00003209* + ID_PRODUCT_FROM_DATABASE=SiS PCI Audio Accelerator + +pci:v00001039d00007018sv00001462sd0000400A* + ID_PRODUCT_FROM_DATABASE=SiS PCI Audio Accelerator + +pci:v00001039d00007018sv000014A4sd00002089* + ID_PRODUCT_FROM_DATABASE=SiS PCI Audio Accelerator + +pci:v00001039d00007018sv000014CDsd00002194* + ID_PRODUCT_FROM_DATABASE=SiS PCI Audio Accelerator + +pci:v00001039d00007018sv000014FFsd00001100* + ID_PRODUCT_FROM_DATABASE=SiS PCI Audio Accelerator + +pci:v00001039d00007018sv0000152Dsd00008808* + ID_PRODUCT_FROM_DATABASE=SiS PCI Audio Accelerator + +pci:v00001039d00007018sv00001558sd00001103* + ID_PRODUCT_FROM_DATABASE=SiS PCI Audio Accelerator + +pci:v00001039d00007018sv00001558sd00002200* + ID_PRODUCT_FROM_DATABASE=SiS PCI Audio Accelerator + +pci:v00001039d00007018sv00001563sd00007018* + ID_PRODUCT_FROM_DATABASE=SiS PCI Audio Accelerator + +pci:v00001039d00007018sv000015C5sd00000111* + ID_PRODUCT_FROM_DATABASE=SiS PCI Audio Accelerator + +pci:v00001039d00007018sv0000270Fsd0000A171* + ID_PRODUCT_FROM_DATABASE=SiS PCI Audio Accelerator + +pci:v00001039d00007018sv0000A0A0sd00000022* + ID_PRODUCT_FROM_DATABASE=SiS PCI Audio Accelerator + +pci:v00001039d00007019* + ID_PRODUCT_FROM_DATABASE=SiS7019 Audio Accelerator + +pci:v00001039d00007502* + ID_PRODUCT_FROM_DATABASE=Azalia Audio Controller + +pci:v0000103A* + ID_VENDOR_FROM_DATABASE=Seiko Epson Corporation + +pci:v0000103B* + ID_VENDOR_FROM_DATABASE=Tatung Corp. Of America + +pci:v0000103C* + ID_VENDOR_FROM_DATABASE=Hewlett-Packard Company + +pci:v0000103Cd00000025* + ID_PRODUCT_FROM_DATABASE=XE4500 Notebook + +pci:v0000103Cd0000002A* + ID_PRODUCT_FROM_DATABASE=NX9000 Notebook + +pci:v0000103Cd000008BC* + ID_PRODUCT_FROM_DATABASE=NX5000 Notebook + +pci:v0000103Cd00001005* + ID_PRODUCT_FROM_DATABASE=A4977A Visualize EG + +pci:v0000103Cd00001008* + ID_PRODUCT_FROM_DATABASE=Visualize FX + +pci:v0000103Cd00001028* + ID_PRODUCT_FROM_DATABASE=Tach TL Fibre Channel Host Adapter + +pci:v0000103Cd00001029* + ID_PRODUCT_FROM_DATABASE=Tach XL2 Fibre Channel Host Adapter + +pci:v0000103Cd00001029sv0000107Esd0000000F* + ID_PRODUCT_FROM_DATABASE=Interphase 5560 Fibre Channel Adapter + +pci:v0000103Cd00001029sv00009004sd00009210* + ID_PRODUCT_FROM_DATABASE=1Gb/2Gb Family Fibre Channel Controller + +pci:v0000103Cd00001029sv00009004sd00009211* + ID_PRODUCT_FROM_DATABASE=1Gb/2Gb Family Fibre Channel Controller + +pci:v0000103Cd0000102A* + ID_PRODUCT_FROM_DATABASE=Tach TS Fibre Channel Host Adapter + +pci:v0000103Cd0000102Asv0000107Esd0000000E* + ID_PRODUCT_FROM_DATABASE=Interphase 5540/5541 Fibre Channel Adapter + +pci:v0000103Cd0000102Asv00009004sd00009110* + ID_PRODUCT_FROM_DATABASE=1Gb/2Gb Family Fibre Channel Controller + +pci:v0000103Cd0000102Asv00009004sd00009111* + ID_PRODUCT_FROM_DATABASE=1Gb/2Gb Family Fibre Channel Controller + +pci:v0000103Cd00001030* + ID_PRODUCT_FROM_DATABASE=J2585A DeskDirect 10/100VG NIC + +pci:v0000103Cd00001031* + ID_PRODUCT_FROM_DATABASE=J2585B HP 10/100VG PCI LAN Adapter + +pci:v0000103Cd00001031sv0000103Csd00001040* + ID_PRODUCT_FROM_DATABASE=J2973A DeskDirect 10BaseT NIC + +pci:v0000103Cd00001031sv0000103Csd00001041* + ID_PRODUCT_FROM_DATABASE=J2585B DeskDirect 10/100VG NIC + +pci:v0000103Cd00001031sv0000103Csd00001042* + ID_PRODUCT_FROM_DATABASE=J2970A DeskDirect 10BaseT/2 NIC + +pci:v0000103Cd00001040* + ID_PRODUCT_FROM_DATABASE=J2973A DeskDirect 10BaseT NIC + +pci:v0000103Cd00001041* + ID_PRODUCT_FROM_DATABASE=J2585B DeskDirect 10/100 NIC + +pci:v0000103Cd00001042* + ID_PRODUCT_FROM_DATABASE=J2970A DeskDirect 10BaseT/2 NIC + +pci:v0000103Cd00001048* + ID_PRODUCT_FROM_DATABASE=Diva Serial [GSP] Multiport UART + +pci:v0000103Cd00001048sv0000103Csd00001049* + ID_PRODUCT_FROM_DATABASE=Tosca Console + +pci:v0000103Cd00001048sv0000103Csd0000104A* + ID_PRODUCT_FROM_DATABASE=Tosca Secondary + +pci:v0000103Cd00001048sv0000103Csd0000104B* + ID_PRODUCT_FROM_DATABASE=Maestro SP2 + +pci:v0000103Cd00001048sv0000103Csd00001223* + ID_PRODUCT_FROM_DATABASE=Superdome Console + +pci:v0000103Cd00001048sv0000103Csd00001226* + ID_PRODUCT_FROM_DATABASE=Keystone SP2 + +pci:v0000103Cd00001048sv0000103Csd00001227* + ID_PRODUCT_FROM_DATABASE=Powerbar SP2 + +pci:v0000103Cd00001048sv0000103Csd00001282* + ID_PRODUCT_FROM_DATABASE=Everest SP2 + +pci:v0000103Cd00001048sv0000103Csd00001301* + ID_PRODUCT_FROM_DATABASE=Diva RMP3 + +pci:v0000103Cd00001054* + ID_PRODUCT_FROM_DATABASE=PCI Local Bus Adapter + +pci:v0000103Cd00001064* + ID_PRODUCT_FROM_DATABASE=79C970 PCnet Ethernet Controller + +pci:v0000103Cd0000108B* + ID_PRODUCT_FROM_DATABASE=Visualize FXe + +pci:v0000103Cd000010C1* + ID_PRODUCT_FROM_DATABASE=NetServer Smart IRQ Router + +pci:v0000103Cd000010ED* + ID_PRODUCT_FROM_DATABASE=TopTools Remote Control + +pci:v0000103Cd000010F0* + ID_PRODUCT_FROM_DATABASE=rio System Bus Adapter + +pci:v0000103Cd000010F1* + ID_PRODUCT_FROM_DATABASE=rio I/O Controller + +pci:v0000103Cd00001200* + ID_PRODUCT_FROM_DATABASE=82557B 10/100 NIC + +pci:v0000103Cd00001219* + ID_PRODUCT_FROM_DATABASE=NetServer PCI Hot-Plug Controller + +pci:v0000103Cd0000121A* + ID_PRODUCT_FROM_DATABASE=NetServer SMIC Controller + +pci:v0000103Cd0000121B* + ID_PRODUCT_FROM_DATABASE=NetServer Legacy COM Port Decoder + +pci:v0000103Cd0000121C* + ID_PRODUCT_FROM_DATABASE=NetServer PCI COM Port Decoder + +pci:v0000103Cd00001229* + ID_PRODUCT_FROM_DATABASE=zx1 System Bus Adapter + +pci:v0000103Cd0000122A* + ID_PRODUCT_FROM_DATABASE=zx1 I/O Controller + +pci:v0000103Cd0000122E* + ID_PRODUCT_FROM_DATABASE=PCI-X Local Bus Adapter + +pci:v0000103Cd0000127B* + ID_PRODUCT_FROM_DATABASE=sx1000 System Bus Adapter + +pci:v0000103Cd0000127C* + ID_PRODUCT_FROM_DATABASE=sx1000 I/O Controller + +pci:v0000103Cd00001290* + ID_PRODUCT_FROM_DATABASE=Auxiliary Diva Serial Port + +pci:v0000103Cd00001290sv0000103Csd00001291* + ID_PRODUCT_FROM_DATABASE=Diva SP2 + +pci:v0000103Cd00001291* + ID_PRODUCT_FROM_DATABASE=Auxiliary Diva Serial Port + +pci:v0000103Cd000012B4* + ID_PRODUCT_FROM_DATABASE=zx1 QuickSilver AGP8x Local Bus Adapter + +pci:v0000103Cd000012EB* + ID_PRODUCT_FROM_DATABASE=sx2000 System Bus Adapter + +pci:v0000103Cd000012EC* + ID_PRODUCT_FROM_DATABASE=sx2000 I/O Controller + +pci:v0000103Cd000012EE* + ID_PRODUCT_FROM_DATABASE=PCI-X 2.0 Local Bus Adapter + +pci:v0000103Cd000012F8* + ID_PRODUCT_FROM_DATABASE=Broadcom BCM4306 802.11b/g Wireless LAN + +pci:v0000103Cd000012FA* + ID_PRODUCT_FROM_DATABASE=BCM4306 802.11b/g Wireless LAN Controller + +pci:v0000103Cd00001302* + ID_PRODUCT_FROM_DATABASE=RMP-3 Shared Memory Driver + +pci:v0000103Cd00001303* + ID_PRODUCT_FROM_DATABASE=RMP-3 (Remote Management Processor) + +pci:v0000103Cd00001361* + ID_PRODUCT_FROM_DATABASE=BCM4312 802.11a/b/g WLAN Controller + +pci:v0000103Cd00001371* + ID_PRODUCT_FROM_DATABASE=Broadcom Corporation BCM4312 802.11a/b/g (rev 02) + +pci:v0000103Cd00001717* + ID_PRODUCT_FROM_DATABASE=Intel 82571EB dual 1 Gb Ethernet controller + +pci:v0000103Cd0000179B* + ID_PRODUCT_FROM_DATABASE=EliteBook 8470p Notebook + +pci:v0000103Cd0000179D* + ID_PRODUCT_FROM_DATABASE=EliteBook 8470p Notebook + +pci:v0000103Cd00002910* + ID_PRODUCT_FROM_DATABASE=E2910A PCIBus Exerciser + +pci:v0000103Cd00002925* + ID_PRODUCT_FROM_DATABASE=E2925A 32 Bit, 33 MHzPCI Exerciser & Analyzer + +pci:v0000103Cd00003080* + ID_PRODUCT_FROM_DATABASE=Pavilion ze2028ea + +pci:v0000103Cd00003085* + ID_PRODUCT_FROM_DATABASE=Realtek RTL8139/8139C/8139C+ + +pci:v0000103Cd000030A3* + ID_PRODUCT_FROM_DATABASE=Compaq NW8440 Notebook + +pci:v0000103Cd000030B5* + ID_PRODUCT_FROM_DATABASE=Compaq Presario V3000Z + +pci:v0000103Cd000031FB* + ID_PRODUCT_FROM_DATABASE=DL365 ATI ES1000 VGA controller + +pci:v0000103Cd00003206* + ID_PRODUCT_FROM_DATABASE=Adaptec Embedded Serial ATA HostRAID + +pci:v0000103Cd00003220* + ID_PRODUCT_FROM_DATABASE=Smart Array P600 + +pci:v0000103Cd00003220sv0000103Csd00003225* + ID_PRODUCT_FROM_DATABASE=3 Gb/s SAS RAID + +pci:v0000103Cd00003230* + ID_PRODUCT_FROM_DATABASE=Smart Array Controller + +pci:v0000103Cd00003230sv0000103Csd00003223* + ID_PRODUCT_FROM_DATABASE=Smart Array P800 + +pci:v0000103Cd00003230sv0000103Csd00003234* + ID_PRODUCT_FROM_DATABASE=P400 SAS Controller + +pci:v0000103Cd00003230sv0000103Csd00003235* + ID_PRODUCT_FROM_DATABASE=P400i SAS Controller + +pci:v0000103Cd00003230sv0000103Csd00003237* + ID_PRODUCT_FROM_DATABASE=E500 SAS Controller + +pci:v0000103Cd00003230sv0000103Csd0000323D* + ID_PRODUCT_FROM_DATABASE=P700m SAS Controller + +pci:v0000103Cd00003238* + ID_PRODUCT_FROM_DATABASE=Smart Array E200i (SAS Controller) + +pci:v0000103Cd00003238sv0000103Csd00003211* + ID_PRODUCT_FROM_DATABASE=Smart Array E200i + +pci:v0000103Cd00003238sv0000103Csd00003212* + ID_PRODUCT_FROM_DATABASE=Smart Array E200 + +pci:v0000103Cd0000323A* + ID_PRODUCT_FROM_DATABASE=Smart Array G6 controllers + +pci:v0000103Cd0000323Asv0000103Csd00003241* + ID_PRODUCT_FROM_DATABASE=Smart Array P212 + +pci:v0000103Cd0000323Asv0000103Csd00003243* + ID_PRODUCT_FROM_DATABASE=Smart Array P410 + +pci:v0000103Cd0000323Asv0000103Csd00003245* + ID_PRODUCT_FROM_DATABASE=Smart Array P410i + +pci:v0000103Cd0000323Asv0000103Csd00003247* + ID_PRODUCT_FROM_DATABASE=Smart Array P411 + +pci:v0000103Cd0000323Asv0000103Csd00003249* + ID_PRODUCT_FROM_DATABASE=Smart Array P812 + +pci:v0000103Cd0000323Asv0000103Csd0000324A* + ID_PRODUCT_FROM_DATABASE=HP Smart Array 712m (Mezzanine RAID controller) + +pci:v0000103Cd0000323Asv0000103Csd0000324B* + ID_PRODUCT_FROM_DATABASE=Smart Array P711m (Mezzanine RAID controller) + +pci:v0000103Cd0000323B* + ID_PRODUCT_FROM_DATABASE=Smart Array Gen8 Controllers + +pci:v0000103Cd0000323Bsv0000103Csd00003350* + ID_PRODUCT_FROM_DATABASE=P222 + +pci:v0000103Cd0000323Bsv0000103Csd00003351* + ID_PRODUCT_FROM_DATABASE=P420 + +pci:v0000103Cd0000323Bsv0000103Csd00003352* + ID_PRODUCT_FROM_DATABASE=P421 + +pci:v0000103Cd0000323Bsv0000103Csd00003354* + ID_PRODUCT_FROM_DATABASE=P420i + +pci:v0000103Cd0000323Bsv0000103Csd00003355* + ID_PRODUCT_FROM_DATABASE=P220i + +pci:v0000103Cd00003300* + ID_PRODUCT_FROM_DATABASE=Integrated Lights-Out Standard Virtual USB Controller + +pci:v0000103Cd00003300sv0000103Csd00003304* + ID_PRODUCT_FROM_DATABASE=iLO2 + +pci:v0000103Cd00003300sv0000103Csd00003305* + ID_PRODUCT_FROM_DATABASE=iLO2 + +pci:v0000103Cd00003300sv0000103Csd00003309* + ID_PRODUCT_FROM_DATABASE=iLO2 GXL/iLO3 GXE + +pci:v0000103Cd00003300sv0000103Csd0000330E* + ID_PRODUCT_FROM_DATABASE=iLO3 + +pci:v0000103Cd00003300sv0000103Csd00003381* + ID_PRODUCT_FROM_DATABASE=iLO4 + +pci:v0000103Cd00003301* + ID_PRODUCT_FROM_DATABASE=Integrated Lights-Out Standard Serial Port + +pci:v0000103Cd00003301sv0000103Csd00003304* + ID_PRODUCT_FROM_DATABASE=iLO2 + +pci:v0000103Cd00003301sv0000103Csd00003305* + ID_PRODUCT_FROM_DATABASE=iLO2 + +pci:v0000103Cd00003301sv0000103Csd0000330E* + ID_PRODUCT_FROM_DATABASE=iLO3 + +pci:v0000103Cd00003301sv0000103Csd00003381* + ID_PRODUCT_FROM_DATABASE=iLO4 + +pci:v0000103Cd00003302* + ID_PRODUCT_FROM_DATABASE=Integrated Lights-Out Standard KCS Interface + +pci:v0000103Cd00003302sv0000103Csd00003304* + ID_PRODUCT_FROM_DATABASE=iLO2 + +pci:v0000103Cd00003302sv0000103Csd00003305* + ID_PRODUCT_FROM_DATABASE=iLO2 + +pci:v0000103Cd00003302sv0000103Csd0000330E* + ID_PRODUCT_FROM_DATABASE=iLO3 + +pci:v0000103Cd00003302sv0000103Csd00003381* + ID_PRODUCT_FROM_DATABASE=iLO4 + +pci:v0000103Cd00003305* + ID_PRODUCT_FROM_DATABASE=Integrated Lights-Out (iLO2) Controller + +pci:v0000103Cd00003306* + ID_PRODUCT_FROM_DATABASE=Integrated Lights-Out Standard Slave Instrumentation & System Support + +pci:v0000103Cd00003306sv0000103Csd0000330E* + ID_PRODUCT_FROM_DATABASE=iLO3 + +pci:v0000103Cd00003306sv0000103Csd00003381* + ID_PRODUCT_FROM_DATABASE=iLO4 + +pci:v0000103Cd00003307* + ID_PRODUCT_FROM_DATABASE=Integrated Lights-Out Standard Management Processor Support and Messaging + +pci:v0000103Cd00003307sv0000103Csd00003309* + ID_PRODUCT_FROM_DATABASE=iLO 2 + +pci:v0000103Cd00003307sv0000103Csd0000330E* + ID_PRODUCT_FROM_DATABASE=iLO3 + +pci:v0000103Cd00003307sv0000103Csd00003381* + ID_PRODUCT_FROM_DATABASE=iLO4 + +pci:v0000103Cd00003308* + ID_PRODUCT_FROM_DATABASE=Integrated Lights-Out Standard MS Watchdog Timer + +pci:v0000103Cd00003308sv0000103Csd0000330E* + ID_PRODUCT_FROM_DATABASE=iLO3 + +pci:v0000103Cd00003308sv0000103Csd00003381* + ID_PRODUCT_FROM_DATABASE=iLO4 + +pci:v0000103Cd0000402F* + ID_PRODUCT_FROM_DATABASE=PCIe Root Port + +pci:v0000103Cd00004030* + ID_PRODUCT_FROM_DATABASE=zx2 System Bus Adapter + +pci:v0000103Cd00004031* + ID_PRODUCT_FROM_DATABASE=zx2 I/O Controller + +pci:v0000103Cd00004037* + ID_PRODUCT_FROM_DATABASE=PCIe Local Bus Adapter + +pci:v0000103Cd0000403B* + ID_PRODUCT_FROM_DATABASE=PCIe Root Port + +pci:v0000103Cd000060E8* + ID_PRODUCT_FROM_DATABASE=NetRAID-2M : ZX1/M (OEM AMI MegaRAID 493) + +pci:v0000103E* + ID_VENDOR_FROM_DATABASE=Solliday Engineering + +pci:v0000103F* + ID_VENDOR_FROM_DATABASE=Synopsys/Logic Modeling Group + +pci:v00001040* + ID_VENDOR_FROM_DATABASE=Accelgraphics Inc. + +pci:v00001041* + ID_VENDOR_FROM_DATABASE=Computrend + +pci:v00001042* + ID_VENDOR_FROM_DATABASE=Micron + +pci:v00001042d00001000* + ID_PRODUCT_FROM_DATABASE=PC Tech RZ1000 + +pci:v00001042d00001001* + ID_PRODUCT_FROM_DATABASE=PC Tech RZ1001 + +pci:v00001042d00003000* + ID_PRODUCT_FROM_DATABASE=Samurai_0 + +pci:v00001042d00003010* + ID_PRODUCT_FROM_DATABASE=Samurai_1 + +pci:v00001042d00003020* + ID_PRODUCT_FROM_DATABASE=Samurai_IDE + +pci:v00001043* + ID_VENDOR_FROM_DATABASE=ASUSTeK Computer Inc. + +pci:v00001043d00000675* + ID_PRODUCT_FROM_DATABASE=ISDNLink P-IN100-ST-D + +pci:v00001043d00000675sv00000675sd00001704* + ID_PRODUCT_FROM_DATABASE=ISDN Adapter (PCI Bus, D, C) + +pci:v00001043d00000675sv00000675sd00001707* + ID_PRODUCT_FROM_DATABASE=ISDN Adapter (PCI Bus, DV, W) + +pci:v00001043d00000675sv000010CFsd0000105E* + ID_PRODUCT_FROM_DATABASE=ISDN Adapter (PCI Bus, DV, W) + +pci:v00001043d00000C11* + ID_PRODUCT_FROM_DATABASE=A7N8X Motherboard nForce2 IDE/USB/SMBus + +pci:v00001043d00004015* + ID_PRODUCT_FROM_DATABASE=v7100 SDRAM [GeForce2 MX] + +pci:v00001043d00004021* + ID_PRODUCT_FROM_DATABASE=v7100 Combo Deluxe [GeForce2 MX + TV tuner] + +pci:v00001043d00004057* + ID_PRODUCT_FROM_DATABASE=v8200 GeForce 3 + +pci:v00001043d00008043* + ID_PRODUCT_FROM_DATABASE=v8240 PAL 128M [P4T] Motherboard + +pci:v00001043d00008047* + ID_PRODUCT_FROM_DATABASE=v8420 Deluxe [GeForce4 Ti4200] + +pci:v00001043d0000807B* + ID_PRODUCT_FROM_DATABASE=v9280/TD [GeForce4 TI4200 8X With TV-Out and DVI] + +pci:v00001043d00008095* + ID_PRODUCT_FROM_DATABASE=A7N8X Motherboard nForce2 AC97 Audio + +pci:v00001043d000080AC* + ID_PRODUCT_FROM_DATABASE=A7N8X Motherboard nForce2 AGP/Memory + +pci:v00001043d000080BB* + ID_PRODUCT_FROM_DATABASE=v9180 Magic/T [GeForce4 MX440 AGP 8x 64MB TV-out] + +pci:v00001043d000080C5* + ID_PRODUCT_FROM_DATABASE=nForce3 chipset motherboard [SK8N] + +pci:v00001043d000080DF* + ID_PRODUCT_FROM_DATABASE=v9520 Magic/T + +pci:v00001043d0000815A* + ID_PRODUCT_FROM_DATABASE=A8N-SLI Motherboard nForce4 SATA + +pci:v00001043d00008168* + ID_PRODUCT_FROM_DATABASE=Realtek PCI-E Gigabit Ethernet Controller (RTL8111B) + +pci:v00001043d00008187* + ID_PRODUCT_FROM_DATABASE=802.11a/b/g Wireless LAN Card + +pci:v00001043d00008188* + ID_PRODUCT_FROM_DATABASE=Tiger Hybrid TV Capture Device + +pci:v00001043d000081E7* + ID_PRODUCT_FROM_DATABASE=Realtek ALC-660 6-channel CODEC + +pci:v00001043d000081F4* + ID_PRODUCT_FROM_DATABASE=EN7300TC512/TD/128M/A(C262G) [Graphics Card EN7300TC512] + +pci:v00001043d00008233* + ID_PRODUCT_FROM_DATABASE=EEE-PC 701 Netbook + +pci:v00001043d000082CA* + ID_PRODUCT_FROM_DATABASE=G96 GeForce 9500 GT + +pci:v00001043d000082E8* + ID_PRODUCT_FROM_DATABASE=M3N72-D + +pci:v00001043d00008383* + ID_PRODUCT_FROM_DATABASE=P7P55D Series Motherboard + +pci:v00001043d000083A4* + ID_PRODUCT_FROM_DATABASE=Motherboard M2N68-AM SE2 + +pci:v00001043d00008410* + ID_PRODUCT_FROM_DATABASE=SBx00 [Azalia] + +pci:v00001043d0000843E* + ID_PRODUCT_FROM_DATABASE=M5A88-V EVO + +pci:v00001043d00009602* + ID_PRODUCT_FROM_DATABASE=RS880 PCI to PCI bridge (int gfx) + +pci:v00001043d00009602sv00001043sd000083A2* + ID_PRODUCT_FROM_DATABASE=M4A785TD Motherboard + +pci:v00001044* + ID_VENDOR_FROM_DATABASE=Adaptec (formerly DPT) + +pci:v00001044d00001012* + ID_PRODUCT_FROM_DATABASE=Domino RAID Engine + +pci:v00001044d0000A400* + ID_PRODUCT_FROM_DATABASE=SmartCache/Raid I-IV Controller + +pci:v00001044d0000A500* + ID_PRODUCT_FROM_DATABASE=PCI Bridge + +pci:v00001044d0000A501* + ID_PRODUCT_FROM_DATABASE=SmartRAID V Controller + +pci:v00001044d0000A501sv00001044sd0000C001* + ID_PRODUCT_FROM_DATABASE=PM1554U2 Ultra2 Single Channel + +pci:v00001044d0000A501sv00001044sd0000C002* + ID_PRODUCT_FROM_DATABASE=PM1654U2 Ultra2 Single Channel + +pci:v00001044d0000A501sv00001044sd0000C003* + ID_PRODUCT_FROM_DATABASE=PM1564U3 Ultra3 Single Channel + +pci:v00001044d0000A501sv00001044sd0000C004* + ID_PRODUCT_FROM_DATABASE=PM1564U3 Ultra3 Dual Channel + +pci:v00001044d0000A501sv00001044sd0000C005* + ID_PRODUCT_FROM_DATABASE=PM1554U2 Ultra2 Single Channel (NON ACPI) + +pci:v00001044d0000A501sv00001044sd0000C00A* + ID_PRODUCT_FROM_DATABASE=PM2554U2 Ultra2 Single Channel + +pci:v00001044d0000A501sv00001044sd0000C00B* + ID_PRODUCT_FROM_DATABASE=PM2654U2 Ultra2 Single Channel + +pci:v00001044d0000A501sv00001044sd0000C00C* + ID_PRODUCT_FROM_DATABASE=PM2664U3 Ultra3 Single Channel + +pci:v00001044d0000A501sv00001044sd0000C00D* + ID_PRODUCT_FROM_DATABASE=PM2664U3 Ultra3 Dual Channel + +pci:v00001044d0000A501sv00001044sd0000C00E* + ID_PRODUCT_FROM_DATABASE=PM2554U2 Ultra2 Single Channel (NON ACPI) + +pci:v00001044d0000A501sv00001044sd0000C00F* + ID_PRODUCT_FROM_DATABASE=PM2654U2 Ultra2 Single Channel (NON ACPI) + +pci:v00001044d0000A501sv00001044sd0000C014* + ID_PRODUCT_FROM_DATABASE=PM3754U2 Ultra2 Single Channel (NON ACPI) + +pci:v00001044d0000A501sv00001044sd0000C015* + ID_PRODUCT_FROM_DATABASE=PM3755U2B Ultra2 Single Channel (NON ACPI) + +pci:v00001044d0000A501sv00001044sd0000C016* + ID_PRODUCT_FROM_DATABASE=PM3755F Fibre Channel (NON ACPI) + +pci:v00001044d0000A501sv00001044sd0000C01E* + ID_PRODUCT_FROM_DATABASE=PM3757U2 Ultra2 Single Channel + +pci:v00001044d0000A501sv00001044sd0000C01F* + ID_PRODUCT_FROM_DATABASE=PM3757U2 Ultra2 Dual Channel + +pci:v00001044d0000A501sv00001044sd0000C020* + ID_PRODUCT_FROM_DATABASE=PM3767U3 Ultra3 Dual Channel + +pci:v00001044d0000A501sv00001044sd0000C021* + ID_PRODUCT_FROM_DATABASE=PM3767U3 Ultra3 Quad Channel + +pci:v00001044d0000A501sv00001044sd0000C028* + ID_PRODUCT_FROM_DATABASE=PM2865U3 Ultra3 Single Channel + +pci:v00001044d0000A501sv00001044sd0000C029* + ID_PRODUCT_FROM_DATABASE=PM2865U3 Ultra3 Dual Channel + +pci:v00001044d0000A501sv00001044sd0000C02A* + ID_PRODUCT_FROM_DATABASE=PM2865F Fibre Channel + +pci:v00001044d0000A501sv00001044sd0000C03C* + ID_PRODUCT_FROM_DATABASE=2000S Ultra3 Single Channel + +pci:v00001044d0000A501sv00001044sd0000C03D* + ID_PRODUCT_FROM_DATABASE=2000S Ultra3 Dual Channel + +pci:v00001044d0000A501sv00001044sd0000C03E* + ID_PRODUCT_FROM_DATABASE=2000F Fibre Channel + +pci:v00001044d0000A501sv00001044sd0000C046* + ID_PRODUCT_FROM_DATABASE=3000S Ultra3 Single Channel + +pci:v00001044d0000A501sv00001044sd0000C047* + ID_PRODUCT_FROM_DATABASE=3000S Ultra3 Dual Channel + +pci:v00001044d0000A501sv00001044sd0000C048* + ID_PRODUCT_FROM_DATABASE=3000F Fibre Channel + +pci:v00001044d0000A501sv00001044sd0000C050* + ID_PRODUCT_FROM_DATABASE=5000S Ultra3 Single Channel + +pci:v00001044d0000A501sv00001044sd0000C051* + ID_PRODUCT_FROM_DATABASE=5000S Ultra3 Dual Channel + +pci:v00001044d0000A501sv00001044sd0000C052* + ID_PRODUCT_FROM_DATABASE=5000F Fibre Channel + +pci:v00001044d0000A501sv00001044sd0000C05A* + ID_PRODUCT_FROM_DATABASE=2400A UDMA Four Channel + +pci:v00001044d0000A501sv00001044sd0000C05B* + ID_PRODUCT_FROM_DATABASE=2400A UDMA Four Channel DAC + +pci:v00001044d0000A501sv00001044sd0000C064* + ID_PRODUCT_FROM_DATABASE=3010S Ultra3 Dual Channel + +pci:v00001044d0000A501sv00001044sd0000C065* + ID_PRODUCT_FROM_DATABASE=3410S Ultra160 Four Channel + +pci:v00001044d0000A501sv00001044sd0000C066* + ID_PRODUCT_FROM_DATABASE=3010S Fibre Channel + +pci:v00001044d0000A511* + ID_PRODUCT_FROM_DATABASE=SmartRAID V Controller + +pci:v00001044d0000A511sv00001044sd0000C032* + ID_PRODUCT_FROM_DATABASE=ASR-2005S I2O Zero Channel + +pci:v00001044d0000A511sv00001044sd0000C035* + ID_PRODUCT_FROM_DATABASE=ASR-2010S I2O Zero Channel + +pci:v00001044d0000C066* + ID_PRODUCT_FROM_DATABASE=3010S Ultra3 Dual Channel + +pci:v00001045* + ID_VENDOR_FROM_DATABASE=OPTi Inc. + +pci:v00001045d0000A0F8* + ID_PRODUCT_FROM_DATABASE=82C750 [Vendetta] USB Controller + +pci:v00001045d0000C101* + ID_PRODUCT_FROM_DATABASE=92C264 + +pci:v00001045d0000C178* + ID_PRODUCT_FROM_DATABASE=92C178 + +pci:v00001045d0000C556* + ID_PRODUCT_FROM_DATABASE=82X556 [Viper] + +pci:v00001045d0000C557* + ID_PRODUCT_FROM_DATABASE=82C557 [Viper-M] + +pci:v00001045d0000C558* + ID_PRODUCT_FROM_DATABASE=82C558 [Viper-M ISA+IDE] + +pci:v00001045d0000C567* + ID_PRODUCT_FROM_DATABASE=82C750 [Vendetta], device 0 + +pci:v00001045d0000C568* + ID_PRODUCT_FROM_DATABASE=82C750 [Vendetta], device 1 + +pci:v00001045d0000C569* + ID_PRODUCT_FROM_DATABASE=82C579 [Viper XPress+ Chipset] + +pci:v00001045d0000C621* + ID_PRODUCT_FROM_DATABASE=82C621 [Viper-M/N+] + +pci:v00001045d0000C700* + ID_PRODUCT_FROM_DATABASE=82C700 [FireStar] + +pci:v00001045d0000C701* + ID_PRODUCT_FROM_DATABASE=82C701 [FireStar Plus] + +pci:v00001045d0000C814* + ID_PRODUCT_FROM_DATABASE=82C814 [Firebridge 1] + +pci:v00001045d0000C822* + ID_PRODUCT_FROM_DATABASE=82C822 + +pci:v00001045d0000C824* + ID_PRODUCT_FROM_DATABASE=82C824 + +pci:v00001045d0000C825* + ID_PRODUCT_FROM_DATABASE=82C825 [Firebridge 2] + +pci:v00001045d0000C832* + ID_PRODUCT_FROM_DATABASE=82C832 + +pci:v00001045d0000C861* + ID_PRODUCT_FROM_DATABASE=82C861 + +pci:v00001045d0000C881* + ID_PRODUCT_FROM_DATABASE=82C881 [FireLink] 1394 OHCI Link Controller + +pci:v00001045d0000C895* + ID_PRODUCT_FROM_DATABASE=82C895 + +pci:v00001045d0000C935* + ID_PRODUCT_FROM_DATABASE=EV1935 ECTIVA MachOne PCIAudio + +pci:v00001045d0000D568* + ID_PRODUCT_FROM_DATABASE=82C825 [Firebridge 2] + +pci:v00001045d0000D721* + ID_PRODUCT_FROM_DATABASE=IDE [FireStar] + +pci:v00001046* + ID_VENDOR_FROM_DATABASE=IPC Corporation, Ltd. + +pci:v00001047* + ID_VENDOR_FROM_DATABASE=Genoa Systems Corp + +pci:v00001048* + ID_VENDOR_FROM_DATABASE=Elsa AG + +pci:v00001048d00000C60* + ID_PRODUCT_FROM_DATABASE=Gladiac MX + +pci:v00001048d00000D22* + ID_PRODUCT_FROM_DATABASE=Quadro4 900XGL [ELSA GLoria4 900XGL] + +pci:v00001048d00001000* + ID_PRODUCT_FROM_DATABASE=QuickStep 1000 + +pci:v00001048d00003000* + ID_PRODUCT_FROM_DATABASE=QuickStep 3000 + +pci:v00001048d00008901* + ID_PRODUCT_FROM_DATABASE=Gloria XL + +pci:v00001048d00008901sv00001048sd00000935* + ID_PRODUCT_FROM_DATABASE=GLoria XL (Virge) + +pci:v00001049* + ID_VENDOR_FROM_DATABASE=Fountain Technologies, Inc. + +pci:v0000104A* + ID_VENDOR_FROM_DATABASE=STMicroelectronics + +pci:v0000104Ad00000000* + ID_PRODUCT_FROM_DATABASE=STLS2F Host Bridge + +pci:v0000104Ad00000008* + ID_PRODUCT_FROM_DATABASE=STG 2000X + +pci:v0000104Ad00000009* + ID_PRODUCT_FROM_DATABASE=STG 1764X + +pci:v0000104Ad00000010* + ID_PRODUCT_FROM_DATABASE=STG4000 [3D Prophet Kyro Series] + +pci:v0000104Ad00000010sv00001681sd0000C069* + ID_PRODUCT_FROM_DATABASE=3D Prophet 4000XT + +pci:v0000104Ad00000201* + ID_PRODUCT_FROM_DATABASE=STPC Vega Northbridge + +pci:v0000104Ad00000209* + ID_PRODUCT_FROM_DATABASE=STPC Consumer/Industrial North- and Southbridge + +pci:v0000104Ad0000020A* + ID_PRODUCT_FROM_DATABASE=STPC Atlas/ConsumerS/Consumer IIA Northbridge + +pci:v0000104Ad0000020B* + ID_PRODUCT_FROM_DATABASE=STPC Consumer II ISA Bridge + +pci:v0000104Ad00000210* + ID_PRODUCT_FROM_DATABASE=STPC Atlas ISA Bridge + +pci:v0000104Ad0000021A* + ID_PRODUCT_FROM_DATABASE=STPC Consumer S Southbridge + +pci:v0000104Ad0000021B* + ID_PRODUCT_FROM_DATABASE=STPC Consumer IIA Southbridge + +pci:v0000104Ad00000220* + ID_PRODUCT_FROM_DATABASE=STPC Industrial PCI to PCCard bridge + +pci:v0000104Ad00000228* + ID_PRODUCT_FROM_DATABASE=STPC Atlas IDE + +pci:v0000104Ad00000229* + ID_PRODUCT_FROM_DATABASE=STPC Vega IDE + +pci:v0000104Ad00000230* + ID_PRODUCT_FROM_DATABASE=STPC Atlas/Vega OHCI USB Controller + +pci:v0000104Ad00000238* + ID_PRODUCT_FROM_DATABASE=STPC Vega LAN + +pci:v0000104Ad00000500* + ID_PRODUCT_FROM_DATABASE=ST70137 [Unicorn] ADSL DMT Transceiver + +pci:v0000104Ad00000500sv0000104Asd00000500* + ID_PRODUCT_FROM_DATABASE=BeWAN ADSL PCI st + +pci:v0000104Ad00000564* + ID_PRODUCT_FROM_DATABASE=STPC Client Northbridge + +pci:v0000104Ad00000981* + ID_PRODUCT_FROM_DATABASE=21x4x DEC-Tulip compatible 10/100 Ethernet + +pci:v0000104Ad00001746* + ID_PRODUCT_FROM_DATABASE=STG 1764X + +pci:v0000104Ad00002774* + ID_PRODUCT_FROM_DATABASE=21x4x DEC-Tulip compatible 10/100 Ethernet + +pci:v0000104Ad00003520* + ID_PRODUCT_FROM_DATABASE=MPEG-II decoder card + +pci:v0000104Ad000055CC* + ID_PRODUCT_FROM_DATABASE=STPC Client Southbridge + +pci:v0000104B* + ID_VENDOR_FROM_DATABASE=BusLogic + +pci:v0000104Bd00000140* + ID_PRODUCT_FROM_DATABASE=BT-946C (old) [multimaster 01] + +pci:v0000104Bd00001040* + ID_PRODUCT_FROM_DATABASE=BT-946C (BA80C30) [MultiMaster 10] + +pci:v0000104Bd00008130* + ID_PRODUCT_FROM_DATABASE=Flashpoint LT + +pci:v0000104C* + ID_VENDOR_FROM_DATABASE=Texas Instruments + +pci:v0000104Cd00000500* + ID_PRODUCT_FROM_DATABASE=100 MBit LAN Controller + +pci:v0000104Cd00000508* + ID_PRODUCT_FROM_DATABASE=TMS380C2X Compressor Interface + +pci:v0000104Cd00001000* + ID_PRODUCT_FROM_DATABASE=Eagle i/f AS + +pci:v0000104Cd0000104C* + ID_PRODUCT_FROM_DATABASE=PCI1510 PC card Cardbus Controller + +pci:v0000104Cd00003D04* + ID_PRODUCT_FROM_DATABASE=TVP4010 [Permedia] + +pci:v0000104Cd00003D07* + ID_PRODUCT_FROM_DATABASE=TVP4020 [Permedia 2] + +pci:v0000104Cd00003D07sv00001011sd00004D10* + ID_PRODUCT_FROM_DATABASE=Comet + +pci:v0000104Cd00003D07sv00001040sd0000000F* + ID_PRODUCT_FROM_DATABASE=AccelStar II + +pci:v0000104Cd00003D07sv00001040sd00000011* + ID_PRODUCT_FROM_DATABASE=AccelStar II + +pci:v0000104Cd00003D07sv00001048sd00000A31* + ID_PRODUCT_FROM_DATABASE=WINNER 2000 + +pci:v0000104Cd00003D07sv00001048sd00000A32* + ID_PRODUCT_FROM_DATABASE=GLoria Synergy + +pci:v0000104Cd00003D07sv00001048sd00000A34* + ID_PRODUCT_FROM_DATABASE=GLoria Synergy + +pci:v0000104Cd00003D07sv00001048sd00000A35* + ID_PRODUCT_FROM_DATABASE=GLoria Synergy + +pci:v0000104Cd00003D07sv00001048sd00000A36* + ID_PRODUCT_FROM_DATABASE=GLoria Synergy + +pci:v0000104Cd00003D07sv00001048sd00000A43* + ID_PRODUCT_FROM_DATABASE=GLoria Synergy + +pci:v0000104Cd00003D07sv00001048sd00000A44* + ID_PRODUCT_FROM_DATABASE=GLoria Synergy + +pci:v0000104Cd00003D07sv0000107Dsd00002633* + ID_PRODUCT_FROM_DATABASE=WinFast 3D L2300 + +pci:v0000104Cd00003D07sv00001092sd00000126* + ID_PRODUCT_FROM_DATABASE=FIRE GL 1000 PRO + +pci:v0000104Cd00003D07sv00001092sd00000127* + ID_PRODUCT_FROM_DATABASE=FIRE GL 1000 PRO + +pci:v0000104Cd00003D07sv00001092sd00000136* + ID_PRODUCT_FROM_DATABASE=FIRE GL 1000 PRO + +pci:v0000104Cd00003D07sv00001092sd00000141* + ID_PRODUCT_FROM_DATABASE=FIRE GL 1000 PRO + +pci:v0000104Cd00003D07sv00001092sd00000146* + ID_PRODUCT_FROM_DATABASE=FIRE GL 1000 PRO + +pci:v0000104Cd00003D07sv00001092sd00000148* + ID_PRODUCT_FROM_DATABASE=FIRE GL 1000 PRO + +pci:v0000104Cd00003D07sv00001092sd00000149* + ID_PRODUCT_FROM_DATABASE=FIRE GL 1000 PRO + +pci:v0000104Cd00003D07sv00001092sd00000152* + ID_PRODUCT_FROM_DATABASE=FIRE GL 1000 PRO + +pci:v0000104Cd00003D07sv00001092sd00000154* + ID_PRODUCT_FROM_DATABASE=FIRE GL 1000 PRO + +pci:v0000104Cd00003D07sv00001092sd00000155* + ID_PRODUCT_FROM_DATABASE=FIRE GL 1000 PRO + +pci:v0000104Cd00003D07sv00001092sd00000156* + ID_PRODUCT_FROM_DATABASE=FIRE GL 1000 PRO + +pci:v0000104Cd00003D07sv00001092sd00000157* + ID_PRODUCT_FROM_DATABASE=FIRE GL 1000 PRO + +pci:v0000104Cd00003D07sv00001097sd00003D01* + ID_PRODUCT_FROM_DATABASE=Jeronimo Pro + +pci:v0000104Cd00003D07sv00001102sd0000100F* + ID_PRODUCT_FROM_DATABASE=Graphics Blaster Extreme + +pci:v0000104Cd00003D07sv00003D3Dsd00000100* + ID_PRODUCT_FROM_DATABASE=Reference Permedia 2 3D + +pci:v0000104Cd00008000* + ID_PRODUCT_FROM_DATABASE=PCILynx/PCILynx2 IEEE 1394 Link Layer Controller + +pci:v0000104Cd00008000sv0000105Esd00008003* + ID_PRODUCT_FROM_DATABASE=FireBoard200 + +pci:v0000104Cd00008000sv00001443sd00008003* + ID_PRODUCT_FROM_DATABASE=FireBoard200 + +pci:v0000104Cd00008000sv00001443sd00008005* + ID_PRODUCT_FROM_DATABASE=FireBoard400 + +pci:v0000104Cd00008000sv00001443sd00008006* + ID_PRODUCT_FROM_DATABASE=FireBoard400 + +pci:v0000104Cd00008000sv0000E4BFsd00001010* + ID_PRODUCT_FROM_DATABASE=CF1-1-SNARE + +pci:v0000104Cd00008000sv0000E4BFsd00001020* + ID_PRODUCT_FROM_DATABASE=CF1-2-SNARE + +pci:v0000104Cd00008000sv0000E4BFsd00001040* + ID_PRODUCT_FROM_DATABASE=FireCompact400 + +pci:v0000104Cd00008009* + ID_PRODUCT_FROM_DATABASE=TSB12LV22 IEEE-1394 Controller + +pci:v0000104Cd00008009sv0000104Dsd00008032* + ID_PRODUCT_FROM_DATABASE=8032 OHCI i.LINK (IEEE 1394) Controller + +pci:v0000104Cd00008009sv00001443sd00008010* + ID_PRODUCT_FROM_DATABASE=FireBoard400-OHCI + +pci:v0000104Cd00008017* + ID_PRODUCT_FROM_DATABASE=PCI4410 FireWire Controller + +pci:v0000104Cd00008019* + ID_PRODUCT_FROM_DATABASE=TSB12LV23 IEEE-1394 Controller + +pci:v0000104Cd00008019sv000011BDsd0000000A* + ID_PRODUCT_FROM_DATABASE=Studio DV500-1394 + +pci:v0000104Cd00008019sv000011BDsd0000000E* + ID_PRODUCT_FROM_DATABASE=Studio DV + +pci:v0000104Cd00008019sv00001443sd00008010* + ID_PRODUCT_FROM_DATABASE=FireBoard400-OHCI + +pci:v0000104Cd00008019sv0000E4BFsd00001010* + ID_PRODUCT_FROM_DATABASE=CF2-1-CYMBAL + +pci:v0000104Cd00008020* + ID_PRODUCT_FROM_DATABASE=TSB12LV26 IEEE-1394 Controller (Link) + +pci:v0000104Cd00008020sv00001028sd000000D8* + ID_PRODUCT_FROM_DATABASE=Precision 530 + +pci:v0000104Cd00008020sv0000104Dsd000080E2* + ID_PRODUCT_FROM_DATABASE=VAIO PCV-J200 + +pci:v0000104Cd00008020sv000011BDsd0000000F* + ID_PRODUCT_FROM_DATABASE=Studio DV500-1394 + +pci:v0000104Cd00008020sv000011BDsd0000001C* + ID_PRODUCT_FROM_DATABASE=Excalibur 4.1 + +pci:v0000104Cd00008020sv00001443sd00008010* + ID_PRODUCT_FROM_DATABASE=FireBoard400-OHCI + +pci:v0000104Cd00008021* + ID_PRODUCT_FROM_DATABASE=TSB43AA22 IEEE-1394 Controller (PHY/Link Integrated) + +pci:v0000104Cd00008021sv0000104Dsd000080DF* + ID_PRODUCT_FROM_DATABASE=Vaio PCG-FX403 + +pci:v0000104Cd00008021sv0000104Dsd000080E7* + ID_PRODUCT_FROM_DATABASE=VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP + +pci:v0000104Cd00008022* + ID_PRODUCT_FROM_DATABASE=TSB43AB22 IEEE-1394a-2000 Controller (PHY/Link) [iOHCI-Lynx] + +pci:v0000104Cd00008022sv0000104Csd00008023* + ID_PRODUCT_FROM_DATABASE=TSB43AB22/A IEEE-1394a-2000 Controller (PHY/Link) + +pci:v0000104Cd00008023* + ID_PRODUCT_FROM_DATABASE=TSB43AB22A IEEE-1394a-2000 Controller (PHY/Link) [iOHCI-Lynx] + +pci:v0000104Cd00008023sv0000103Csd0000088C* + ID_PRODUCT_FROM_DATABASE=NC8000 laptop + +pci:v0000104Cd00008023sv00001043sd0000808B* + ID_PRODUCT_FROM_DATABASE=K8N4-E Mainboard + +pci:v0000104Cd00008023sv00001043sd0000815B* + ID_PRODUCT_FROM_DATABASE=P5W DH Deluxe Motherboard + +pci:v0000104Cd00008023sv00001443sd00008023* + ID_PRODUCT_FROM_DATABASE=FireCard400 + +pci:v0000104Cd00008023sv00008086sd00005044* + ID_PRODUCT_FROM_DATABASE=Desktop Board DP35DP + +pci:v0000104Cd00008024* + ID_PRODUCT_FROM_DATABASE=TSB43AB23 IEEE-1394a-2000 Controller (PHY/Link) + +pci:v0000104Cd00008024sv0000107Dsd00006620* + ID_PRODUCT_FROM_DATABASE=Winfast DV2000 FireWire Controller + +pci:v0000104Cd00008024sv00001443sd00008024* + ID_PRODUCT_FROM_DATABASE=FireBoard Blue + +pci:v0000104Cd00008024sv00001458sd00001000* + ID_PRODUCT_FROM_DATABASE=GA-EP45-DS5/GA-EG45M-DS2H Motherboard + +pci:v0000104Cd00008025* + ID_PRODUCT_FROM_DATABASE=TSB82AA2 IEEE-1394b Link Layer Controller + +pci:v0000104Cd00008025sv00001043sd0000813C* + ID_PRODUCT_FROM_DATABASE=P5P series mainboard + +pci:v0000104Cd00008025sv00001443sd00008025* + ID_PRODUCT_FROM_DATABASE=FireBoard800 + +pci:v0000104Cd00008025sv00001458sd00001000* + ID_PRODUCT_FROM_DATABASE=GA-K8N Ultra-9 Mainboard + +pci:v0000104Cd00008025sv00001546sd00008025* + ID_PRODUCT_FROM_DATABASE=FWB-PCI01 + +pci:v0000104Cd00008025sv000017FCsd00008025* + ID_PRODUCT_FROM_DATABASE=GIC3800 + +pci:v0000104Cd00008026* + ID_PRODUCT_FROM_DATABASE=TSB43AB21 IEEE-1394a-2000 Controller (PHY/Link) + +pci:v0000104Cd00008026sv00001025sd00000035* + ID_PRODUCT_FROM_DATABASE=TravelMate 660 + +pci:v0000104Cd00008026sv00001025sd0000003C* + ID_PRODUCT_FROM_DATABASE=Aspire 2001WLCi (Compaq CL50 motherboard) + +pci:v0000104Cd00008026sv0000103Csd00000025* + ID_PRODUCT_FROM_DATABASE=XE4500 Notebook + +pci:v0000104Cd00008026sv0000103Csd0000006A* + ID_PRODUCT_FROM_DATABASE=NX9500 + +pci:v0000104Cd00008026sv00001043sd0000808D* + ID_PRODUCT_FROM_DATABASE=A7V333 mainboard. + +pci:v0000104Cd00008027* + ID_PRODUCT_FROM_DATABASE=PCI4451 IEEE-1394 Controller + +pci:v0000104Cd00008027sv00001028sd000000E6* + ID_PRODUCT_FROM_DATABASE=PCI4451 IEEE-1394 Controller (Dell Inspiron 8100) + +pci:v0000104Cd00008029* + ID_PRODUCT_FROM_DATABASE=PCI4510 IEEE-1394 Controller + +pci:v0000104Cd00008029sv00001028sd00000163* + ID_PRODUCT_FROM_DATABASE=Latitude D505 + +pci:v0000104Cd00008029sv00001028sd00000196* + ID_PRODUCT_FROM_DATABASE=Inspiron 5160 + +pci:v0000104Cd00008029sv00001071sd00008160* + ID_PRODUCT_FROM_DATABASE=MIM2900 + +pci:v0000104Cd0000802B* + ID_PRODUCT_FROM_DATABASE=PCI7410,7510,7610 OHCI-Lynx Controller + +pci:v0000104Cd0000802Bsv00001028sd00000139* + ID_PRODUCT_FROM_DATABASE=Latitude D400 + +pci:v0000104Cd0000802Bsv00001028sd0000014E* + ID_PRODUCT_FROM_DATABASE=PCI7410,7510,7610 OHCI-Lynx Controller (Latitude D800) + +pci:v0000104Cd0000802E* + ID_PRODUCT_FROM_DATABASE=PCI7x20 1394a-2000 OHCI Two-Port PHY/Link-Layer Controller + +pci:v0000104Cd0000802Esv00001028sd0000018D* + ID_PRODUCT_FROM_DATABASE=Inspiron 700m/710m + +pci:v0000104Cd00008031* + ID_PRODUCT_FROM_DATABASE=PCIxx21/x515 Cardbus Controller + +pci:v0000104Cd00008031sv00001025sd00000080* + ID_PRODUCT_FROM_DATABASE=Aspire 5024WLMi + +pci:v0000104Cd00008031sv0000103Csd00000934* + ID_PRODUCT_FROM_DATABASE=Compaq nw8240/nx8220 + +pci:v0000104Cd00008031sv0000103Csd0000099C* + ID_PRODUCT_FROM_DATABASE=NX6110/NC6120 + +pci:v0000104Cd00008031sv0000103Csd0000308B* + ID_PRODUCT_FROM_DATABASE=MX6125 + +pci:v0000104Cd00008032* + ID_PRODUCT_FROM_DATABASE=OHCI Compliant IEEE 1394 Host Controller + +pci:v0000104Cd00008032sv00001025sd00000080* + ID_PRODUCT_FROM_DATABASE=Aspire 5024WLMi + +pci:v0000104Cd00008032sv0000103Csd00000934* + ID_PRODUCT_FROM_DATABASE=Compaq nw8240/nx8220 + +pci:v0000104Cd00008032sv0000103Csd0000099C* + ID_PRODUCT_FROM_DATABASE=NX6110/NC6120 + +pci:v0000104Cd00008032sv0000103Csd0000308B* + ID_PRODUCT_FROM_DATABASE=MX6125 + +pci:v0000104Cd00008033* + ID_PRODUCT_FROM_DATABASE=PCIxx21 Integrated FlashMedia Controller + +pci:v0000104Cd00008033sv00001025sd00000080* + ID_PRODUCT_FROM_DATABASE=Aspire 5024WLMi + +pci:v0000104Cd00008033sv0000103Csd00000934* + ID_PRODUCT_FROM_DATABASE=Compaq nw8240/nx8220 + +pci:v0000104Cd00008033sv0000103Csd0000099C* + ID_PRODUCT_FROM_DATABASE=NX6110/NC6120 + +pci:v0000104Cd00008033sv0000103Csd0000308B* + ID_PRODUCT_FROM_DATABASE=MX6125 + +pci:v0000104Cd00008034* + ID_PRODUCT_FROM_DATABASE=PCI6411/6421/6611/6621/7411/7421/7611/7621 Secure Digital Controller + +pci:v0000104Cd00008034sv00001025sd00000080* + ID_PRODUCT_FROM_DATABASE=Aspire 5024WLMi + +pci:v0000104Cd00008034sv0000103Csd00000934* + ID_PRODUCT_FROM_DATABASE=Compaq nw8240/nx8220 + +pci:v0000104Cd00008034sv0000103Csd0000099C* + ID_PRODUCT_FROM_DATABASE=NX6110/NC6120 + +pci:v0000104Cd00008034sv0000103Csd0000308B* + ID_PRODUCT_FROM_DATABASE=MX6125 + +pci:v0000104Cd00008035* + ID_PRODUCT_FROM_DATABASE=PCI6411/6421/6611/6621/7411/7421/7611/7621 Smart Card Controller + +pci:v0000104Cd00008035sv0000103Csd00000934* + ID_PRODUCT_FROM_DATABASE=Compaq nw8240/nx8220 + +pci:v0000104Cd00008035sv0000103Csd0000099C* + ID_PRODUCT_FROM_DATABASE=NX6110/NC6120 + +pci:v0000104Cd00008036* + ID_PRODUCT_FROM_DATABASE=PCI6515 Cardbus Controller + +pci:v0000104Cd00008038* + ID_PRODUCT_FROM_DATABASE=PCI6515 SmartCard Controller + +pci:v0000104Cd00008039* + ID_PRODUCT_FROM_DATABASE=PCIxx12 Cardbus Controller + +pci:v0000104Cd00008039sv0000103Csd0000309F* + ID_PRODUCT_FROM_DATABASE=Compaq nx9420 Notebook + +pci:v0000104Cd00008039sv0000103Csd000030A1* + ID_PRODUCT_FROM_DATABASE=NC2400 + +pci:v0000104Cd00008039sv0000103Csd000030A3* + ID_PRODUCT_FROM_DATABASE=Compaq nw8440 + +pci:v0000104Cd00008039sv0000104Dsd0000902D* + ID_PRODUCT_FROM_DATABASE=VAIO VGN-NR120E + +pci:v0000104Cd0000803A* + ID_PRODUCT_FROM_DATABASE=PCIxx12 OHCI Compliant IEEE 1394 Host Controller + +pci:v0000104Cd0000803Asv0000103Csd0000309F* + ID_PRODUCT_FROM_DATABASE=nx9420 + +pci:v0000104Cd0000803Asv0000103Csd000030A1* + ID_PRODUCT_FROM_DATABASE=NC2400 + +pci:v0000104Cd0000803Asv0000103Csd000030A3* + ID_PRODUCT_FROM_DATABASE=Compaq nw8440 + +pci:v0000104Cd0000803Asv0000104Dsd0000902D* + ID_PRODUCT_FROM_DATABASE=VAIO VGN-NR120E + +pci:v0000104Cd0000803B* + ID_PRODUCT_FROM_DATABASE=5-in-1 Multimedia Card Reader (SD/MMC/MS/MS PRO/xD) + +pci:v0000104Cd0000803Bsv0000103Csd0000309F* + ID_PRODUCT_FROM_DATABASE=nx9420 + +pci:v0000104Cd0000803Bsv0000103Csd000030A3* + ID_PRODUCT_FROM_DATABASE=Compaq nw8440 + +pci:v0000104Cd0000803Bsv0000104Dsd0000902D* + ID_PRODUCT_FROM_DATABASE=VAIO VGN-NR120E + +pci:v0000104Cd0000803C* + ID_PRODUCT_FROM_DATABASE=PCIxx12 SDA Standard Compliant SD Host Controller + +pci:v0000104Cd0000803Csv0000103Csd0000309F* + ID_PRODUCT_FROM_DATABASE=nx9420 + +pci:v0000104Cd0000803Csv0000103Csd000030A3* + ID_PRODUCT_FROM_DATABASE=Compaq nw8440 + +pci:v0000104Cd0000803D* + ID_PRODUCT_FROM_DATABASE=PCIxx12 GemCore based SmartCard controller + +pci:v0000104Cd0000803Dsv0000103Csd0000309F* + ID_PRODUCT_FROM_DATABASE=Compaq nx9420 Notebook + +pci:v0000104Cd0000803Dsv0000103Csd000030A1* + ID_PRODUCT_FROM_DATABASE=NC2400 + +pci:v0000104Cd0000803Dsv0000103Csd000030A3* + ID_PRODUCT_FROM_DATABASE=nc8430 + +pci:v0000104Cd0000803Dsv0000103Csd000030AA* + ID_PRODUCT_FROM_DATABASE=nc6310 + +pci:v0000104Cd00008101* + ID_PRODUCT_FROM_DATABASE=TSB43DB42 IEEE-1394a-2000 Controller (PHY/Link) + +pci:v0000104Cd00008201* + ID_PRODUCT_FROM_DATABASE=PCI1620 Firmware Loading Function + +pci:v0000104Cd00008204* + ID_PRODUCT_FROM_DATABASE=PCI7410,7510,7610 PCI Firmware Loading Function + +pci:v0000104Cd00008204sv00001028sd00000139* + ID_PRODUCT_FROM_DATABASE=Latitude D400 + +pci:v0000104Cd00008204sv00001028sd0000014E* + ID_PRODUCT_FROM_DATABASE=Latitude D800 + +pci:v0000104Cd00008231* + ID_PRODUCT_FROM_DATABASE=XIO2000(A)/XIO2200A PCI Express-to-PCI Bridge + +pci:v0000104Cd00008231sv00005678sd00001234* + ID_PRODUCT_FROM_DATABASE=DC-1394 PCIe + +pci:v0000104Cd00008232* + ID_PRODUCT_FROM_DATABASE=XIO3130 PCI Express Switch (Upstream) + +pci:v0000104Cd00008233* + ID_PRODUCT_FROM_DATABASE=XIO3130 PCI Express Switch (Downstream) + +pci:v0000104Cd00008235* + ID_PRODUCT_FROM_DATABASE=XIO2200A IEEE-1394a-2000 Controller (PHY/Link) + +pci:v0000104Cd00008235sv00005678sd00001234* + ID_PRODUCT_FROM_DATABASE=DC-1394 PCIe + +pci:v0000104Cd0000823E* + ID_PRODUCT_FROM_DATABASE=XIO2213A/B/XIO2221 PCI Express to PCI Bridge [Cheetah Express] + +pci:v0000104Cd0000823F* + ID_PRODUCT_FROM_DATABASE=XIO2213A/B/XIO2221 IEEE-1394b OHCI Controller [Cheetah Express] + +pci:v0000104Cd0000823Fsv00001546sd0000803C* + ID_PRODUCT_FROM_DATABASE=FWB-PCIE1X11B + +pci:v0000104Cd00008240* + ID_PRODUCT_FROM_DATABASE=XIO2001 PCI Express-to-PCI Bridge + +pci:v0000104Cd00008241* + ID_PRODUCT_FROM_DATABASE=TUSB73x0 SuperSpeed USB 3.0 xHCI Host Controller + +pci:v0000104Cd00008400* + ID_PRODUCT_FROM_DATABASE=ACX 100 22Mbps Wireless Interface + +pci:v0000104Cd00008400sv00001186sd00003B00* + ID_PRODUCT_FROM_DATABASE=DWL-650+ PC Card cardbus 22Mbs Wireless Adapter [AirPlus] + +pci:v0000104Cd00008400sv00001186sd00003B01* + ID_PRODUCT_FROM_DATABASE=DWL-520+ 22Mbps PCI Wireless Adapter + +pci:v0000104Cd00008400sv00001395sd00002201* + ID_PRODUCT_FROM_DATABASE=WL22-PC + +pci:v0000104Cd00008400sv000016ABsd00008501* + ID_PRODUCT_FROM_DATABASE=WL-8305 IEEE802.11b+ Wireless LAN PCI Adapter + +pci:v0000104Cd00008401* + ID_PRODUCT_FROM_DATABASE=ACX 100 22Mbps Wireless Interface + +pci:v0000104Cd00009000* + ID_PRODUCT_FROM_DATABASE=Wireless Interface (of unknown type) + +pci:v0000104Cd00009065* + ID_PRODUCT_FROM_DATABASE=TMS320DM642 + +pci:v0000104Cd00009066* + ID_PRODUCT_FROM_DATABASE=ACX 111 54Mbps Wireless Interface + +pci:v0000104Cd00009066sv00000308sd00003404* + ID_PRODUCT_FROM_DATABASE=G-102 v1 802.11g Wireless Cardbus Adapter + +pci:v0000104Cd00009066sv00000308sd00003406* + ID_PRODUCT_FROM_DATABASE=G-162 v2 802.11g Wireless Cardbus Adapter + +pci:v0000104Cd00009066sv0000104Csd00009066* + ID_PRODUCT_FROM_DATABASE=WL212 Sitecom Wireless Network PCI-Card 100M (Version 1) + +pci:v0000104Cd00009066sv0000104Csd00009096* + ID_PRODUCT_FROM_DATABASE=Trendnet TEW-412PC Wireless PCI Adapter (Version A) + +pci:v0000104Cd00009066sv00001186sd00003B04* + ID_PRODUCT_FROM_DATABASE=DWL-G520+ Wireless PCI Adapter + +pci:v0000104Cd00009066sv00001186sd00003B05* + ID_PRODUCT_FROM_DATABASE=DWL-G650+ AirPlusG+ CardBus Wireless LAN + +pci:v0000104Cd00009066sv00001186sd00003B08* + ID_PRODUCT_FROM_DATABASE=AirPlus G DWL-G630 Wireless Cardbus Adapter (rev.B1) + +pci:v0000104Cd00009066sv00001385sd00004C00* + ID_PRODUCT_FROM_DATABASE=WG311v2 802.11g Wireless PCI Adapter + +pci:v0000104Cd00009066sv000013D1sd0000ABA0* + ID_PRODUCT_FROM_DATABASE=SWLMP-54108 108Mbps Wireless mini PCI card 802.11g+ + +pci:v0000104Cd00009066sv000014EAsd0000AB07* + ID_PRODUCT_FROM_DATABASE=GW-NS54GM Wireless Cardbus Adapter + +pci:v0000104Cd00009066sv000016ECsd0000010D* + ID_PRODUCT_FROM_DATABASE=USR5416 802.11g Wireless Turbo PCI Adapter + +pci:v0000104Cd00009066sv000016ECsd0000010E* + ID_PRODUCT_FROM_DATABASE=USR5410 802.11g Wireless Cardbus Adapter + +pci:v0000104Cd00009066sv00001737sd00000033* + ID_PRODUCT_FROM_DATABASE=WPC54G v2 802.11g Wireless-G Notebook Adapter + +pci:v0000104Cd00009066sv000017CFsd00000032* + ID_PRODUCT_FROM_DATABASE=G-162 v1 802.11g Wireless Cardbus Adapter + +pci:v0000104Cd00009066sv000017CFsd00000033* + ID_PRODUCT_FROM_DATABASE=Z-Com XG650 Wireless miniPCI 802.11b/g + +pci:v0000104Cd00009066sv0000187Esd0000340B* + ID_PRODUCT_FROM_DATABASE=G-302 v2 802.11g Wireless PCI Adapter + +pci:v0000104Cd00009066sv0000187Esd0000340C* + ID_PRODUCT_FROM_DATABASE=G-360 v2 802.11g Wireless PCI Adapter + +pci:v0000104Cd0000A001* + ID_PRODUCT_FROM_DATABASE=TDC1570 + +pci:v0000104Cd0000A100* + ID_PRODUCT_FROM_DATABASE=TDC1561 + +pci:v0000104Cd0000A102* + ID_PRODUCT_FROM_DATABASE=TNETA1575 HyperSAR Plus w/PCI Host i/f & UTOPIA i/f + +pci:v0000104Cd0000A106* + ID_PRODUCT_FROM_DATABASE=TMS320C6414 TMS320C6415 TMS320C6416 + +pci:v0000104Cd0000A106sv0000175Csd00005000* + ID_PRODUCT_FROM_DATABASE=ASI50xx Audio Adapter + +pci:v0000104Cd0000A106sv0000175Csd00006400* + ID_PRODUCT_FROM_DATABASE=ASI6400 Cobranet series + +pci:v0000104Cd0000A106sv0000175Csd00008700* + ID_PRODUCT_FROM_DATABASE=ASI87xx Radio Tuner card + +pci:v0000104Cd0000AC10* + ID_PRODUCT_FROM_DATABASE=PCI1050 + +pci:v0000104Cd0000AC11* + ID_PRODUCT_FROM_DATABASE=PCI1053 + +pci:v0000104Cd0000AC12* + ID_PRODUCT_FROM_DATABASE=PCI1130 + +pci:v0000104Cd0000AC13* + ID_PRODUCT_FROM_DATABASE=PCI1031 + +pci:v0000104Cd0000AC15* + ID_PRODUCT_FROM_DATABASE=PCI1131 + +pci:v0000104Cd0000AC16* + ID_PRODUCT_FROM_DATABASE=PCI1250 + +pci:v0000104Cd0000AC16sv00001014sd00000092* + ID_PRODUCT_FROM_DATABASE=ThinkPad 600 + +pci:v0000104Cd0000AC17* + ID_PRODUCT_FROM_DATABASE=PCI1220 + +pci:v0000104Cd0000AC18* + ID_PRODUCT_FROM_DATABASE=PCI1260 + +pci:v0000104Cd0000AC19* + ID_PRODUCT_FROM_DATABASE=PCI1221 + +pci:v0000104Cd0000AC1A* + ID_PRODUCT_FROM_DATABASE=PCI1210 + +pci:v0000104Cd0000AC1B* + ID_PRODUCT_FROM_DATABASE=PCI1450 + +pci:v0000104Cd0000AC1Bsv00000E11sd0000B113* + ID_PRODUCT_FROM_DATABASE=Armada M700 + +pci:v0000104Cd0000AC1Bsv00001014sd00000130* + ID_PRODUCT_FROM_DATABASE=ThinkPad 600X/A21m/T20/T22 + +pci:v0000104Cd0000AC1C* + ID_PRODUCT_FROM_DATABASE=PCI1225 + +pci:v0000104Cd0000AC1Csv00000E11sd0000B121* + ID_PRODUCT_FROM_DATABASE=Armada E500 + +pci:v0000104Cd0000AC1Csv00001028sd00000088* + ID_PRODUCT_FROM_DATABASE=Latitude CPi A400XT + +pci:v0000104Cd0000AC1D* + ID_PRODUCT_FROM_DATABASE=PCI1251A + +pci:v0000104Cd0000AC1E* + ID_PRODUCT_FROM_DATABASE=PCI1211 + +pci:v0000104Cd0000AC1F* + ID_PRODUCT_FROM_DATABASE=PCI1251B + +pci:v0000104Cd0000AC20* + ID_PRODUCT_FROM_DATABASE=TI 2030 + +pci:v0000104Cd0000AC21* + ID_PRODUCT_FROM_DATABASE=PCI2031 + +pci:v0000104Cd0000AC22* + ID_PRODUCT_FROM_DATABASE=PCI2032 PCI Docking Bridge + +pci:v0000104Cd0000AC23* + ID_PRODUCT_FROM_DATABASE=PCI2250 PCI-to-PCI Bridge + +pci:v0000104Cd0000AC28* + ID_PRODUCT_FROM_DATABASE=PCI2050 PCI-to-PCI Bridge + +pci:v0000104Cd0000AC2C* + ID_PRODUCT_FROM_DATABASE=PCI2060 PCI-to-PCI Bridge + +pci:v0000104Cd0000AC30* + ID_PRODUCT_FROM_DATABASE=PCI1260 PC card Cardbus Controller + +pci:v0000104Cd0000AC40* + ID_PRODUCT_FROM_DATABASE=PCI4450 PC card Cardbus Controller + +pci:v0000104Cd0000AC41* + ID_PRODUCT_FROM_DATABASE=PCI4410 PC card Cardbus Controller + +pci:v0000104Cd0000AC42* + ID_PRODUCT_FROM_DATABASE=PCI4451 PC card Cardbus Controller + +pci:v0000104Cd0000AC42sv00001028sd000000E6* + ID_PRODUCT_FROM_DATABASE=PCI4451 PC card CardBus Controller (Inspiron 8100) + +pci:v0000104Cd0000AC44* + ID_PRODUCT_FROM_DATABASE=PCI4510 PC card Cardbus Controller + +pci:v0000104Cd0000AC44sv00001028sd00000149* + ID_PRODUCT_FROM_DATABASE=Inspiron 5100 + +pci:v0000104Cd0000AC44sv00001028sd00000163* + ID_PRODUCT_FROM_DATABASE=Latitude D505 + +pci:v0000104Cd0000AC44sv00001028sd00000196* + ID_PRODUCT_FROM_DATABASE=Inspiron 5160 + +pci:v0000104Cd0000AC44sv00001071sd00008160* + ID_PRODUCT_FROM_DATABASE=MIM2000 + +pci:v0000104Cd0000AC46* + ID_PRODUCT_FROM_DATABASE=PCI4520 PC card Cardbus Controller + +pci:v0000104Cd0000AC46sv00001014sd00000552* + ID_PRODUCT_FROM_DATABASE=ThinkPad + +pci:v0000104Cd0000AC47* + ID_PRODUCT_FROM_DATABASE=PCI7510 PC card Cardbus Controller + +pci:v0000104Cd0000AC47sv00001028sd00000139* + ID_PRODUCT_FROM_DATABASE=Latitude D400 + +pci:v0000104Cd0000AC47sv00001028sd0000013F* + ID_PRODUCT_FROM_DATABASE=Precision M60 + +pci:v0000104Cd0000AC47sv00001028sd0000014E* + ID_PRODUCT_FROM_DATABASE=Latitude D800 + +pci:v0000104Cd0000AC48* + ID_PRODUCT_FROM_DATABASE=PCI7610 PC Card Cardbus Controller + +pci:v0000104Cd0000AC49* + ID_PRODUCT_FROM_DATABASE=PCI7410 PC Card Cardbus Controller + +pci:v0000104Cd0000AC4A* + ID_PRODUCT_FROM_DATABASE=PCI7510,7610 PC card Cardbus Controller + +pci:v0000104Cd0000AC4Asv00001028sd00000139* + ID_PRODUCT_FROM_DATABASE=Latitude D400 + +pci:v0000104Cd0000AC4Asv00001028sd0000014E* + ID_PRODUCT_FROM_DATABASE=Latitude D800 + +pci:v0000104Cd0000AC4B* + ID_PRODUCT_FROM_DATABASE=PCI7610 SD/MMC controller + +pci:v0000104Cd0000AC4C* + ID_PRODUCT_FROM_DATABASE=PCI7610 Memory Stick controller + +pci:v0000104Cd0000AC50* + ID_PRODUCT_FROM_DATABASE=PCI1410 PC card Cardbus Controller + +pci:v0000104Cd0000AC51* + ID_PRODUCT_FROM_DATABASE=PCI1420 PC card Cardbus Controller + +pci:v0000104Cd0000AC51sv00000E11sd0000004E* + ID_PRODUCT_FROM_DATABASE=Evo N600c + +pci:v0000104Cd0000AC51sv00001014sd00000148* + ID_PRODUCT_FROM_DATABASE=ThinkPad A20m + +pci:v0000104Cd0000AC51sv00001014sd0000023B* + ID_PRODUCT_FROM_DATABASE=ThinkPad T23 + +pci:v0000104Cd0000AC51sv00001028sd000000B1* + ID_PRODUCT_FROM_DATABASE=Latitude C600 + +pci:v0000104Cd0000AC51sv00001028sd0000012A* + ID_PRODUCT_FROM_DATABASE=Latitude C640 + +pci:v0000104Cd0000AC51sv00001033sd000080CD* + ID_PRODUCT_FROM_DATABASE=Versa Note VXi + +pci:v0000104Cd0000AC51sv000010CFsd00001095* + ID_PRODUCT_FROM_DATABASE=Lifebook S-4510/C6155 + +pci:v0000104Cd0000AC51sv0000E4BFsd00001000* + ID_PRODUCT_FROM_DATABASE=CP2-2-HIPHOP + +pci:v0000104Cd0000AC52* + ID_PRODUCT_FROM_DATABASE=PCI1451 PC card Cardbus Controller + +pci:v0000104Cd0000AC53* + ID_PRODUCT_FROM_DATABASE=PCI1421 PC card Cardbus Controller + +pci:v0000104Cd0000AC54* + ID_PRODUCT_FROM_DATABASE=PCI1620 PC Card Controller + +pci:v0000104Cd0000AC54sv0000103Csd000008B0* + ID_PRODUCT_FROM_DATABASE=tc1100 tablet + +pci:v0000104Cd0000AC55* + ID_PRODUCT_FROM_DATABASE=PCI1520 PC card Cardbus Controller + +pci:v0000104Cd0000AC55sv00001014sd00000512* + ID_PRODUCT_FROM_DATABASE=ThinkPad T30/T40 + +pci:v0000104Cd0000AC55sv0000103Csd00000025* + ID_PRODUCT_FROM_DATABASE=XE4500 Notebook + +pci:v0000104Cd0000AC56* + ID_PRODUCT_FROM_DATABASE=PCI1510 PC card Cardbus Controller + +pci:v0000104Cd0000AC56sv00001014sd00000512* + ID_PRODUCT_FROM_DATABASE=ThinkPad R50e + +pci:v0000104Cd0000AC56sv00001014sd00000528* + ID_PRODUCT_FROM_DATABASE=ThinkPad R40e + +pci:v0000104Cd0000AC56sv000017AAsd00002012* + ID_PRODUCT_FROM_DATABASE=ThinkPad T60/R60 series + +pci:v0000104Cd0000AC60* + ID_PRODUCT_FROM_DATABASE=PCI2040 PCI to DSP Bridge Controller + +pci:v0000104Cd0000AC60sv0000175Csd00005100* + ID_PRODUCT_FROM_DATABASE=ASI51xx Audio Adapter + +pci:v0000104Cd0000AC60sv0000175Csd00006100* + ID_PRODUCT_FROM_DATABASE=ASI61xx Audio Adapter + +pci:v0000104Cd0000AC60sv0000175Csd00006200* + ID_PRODUCT_FROM_DATABASE=ASI62xx Audio Adapter + +pci:v0000104Cd0000AC60sv0000175Csd00008800* + ID_PRODUCT_FROM_DATABASE=ASI88xx Audio Adapter + +pci:v0000104Cd0000AC60sv0000186Fsd00003001* + ID_PRODUCT_FROM_DATABASE=WR-G303 PCI radio receiver + +pci:v0000104Cd0000AC60sv0000186Fsd00003005* + ID_PRODUCT_FROM_DATABASE=WR-G305 PCI radio receiver + +pci:v0000104Cd0000AC60sv0000186Fsd00003101* + ID_PRODUCT_FROM_DATABASE=WR-G313 PCI radio receiver + +pci:v0000104Cd0000AC60sv0000186Fsd00003105* + ID_PRODUCT_FROM_DATABASE=WR-G315 PCI radio receiver + +pci:v0000104Cd0000AC8D* + ID_PRODUCT_FROM_DATABASE=PCI 7620 + +pci:v0000104Cd0000AC8E* + ID_PRODUCT_FROM_DATABASE=PCI7420 CardBus Controller + +pci:v0000104Cd0000AC8Esv00001028sd0000018D* + ID_PRODUCT_FROM_DATABASE=Inspiron 700m/710m + +pci:v0000104Cd0000AC8F* + ID_PRODUCT_FROM_DATABASE=PCI7420/7620 Combo CardBus, 1394a-2000 OHCI and SD/MS-Pro Controller + +pci:v0000104Cd0000AC8Fsv00001028sd0000018D* + ID_PRODUCT_FROM_DATABASE=Inspiron 700m/710m + +pci:v0000104Cd0000B001* + ID_PRODUCT_FROM_DATABASE=TMS320C6424 + +pci:v0000104Cd0000FE00* + ID_PRODUCT_FROM_DATABASE=FireWire Host Controller + +pci:v0000104Cd0000FE03* + ID_PRODUCT_FROM_DATABASE=12C01A FireWire Host Controller + +pci:v0000104D* + ID_VENDOR_FROM_DATABASE=Sony Corporation + +pci:v0000104Dd00008004* + ID_PRODUCT_FROM_DATABASE=DTL-H2500 [Playstation development board] + +pci:v0000104Dd00008009* + ID_PRODUCT_FROM_DATABASE=CXD1947Q i.LINK Controller + +pci:v0000104Dd00008039* + ID_PRODUCT_FROM_DATABASE=CXD3222 i.LINK Controller + +pci:v0000104Dd00008056* + ID_PRODUCT_FROM_DATABASE=Rockwell HCF 56K modem + +pci:v0000104Dd0000808A* + ID_PRODUCT_FROM_DATABASE=Memory Stick Controller + +pci:v0000104Dd000081CE* + ID_PRODUCT_FROM_DATABASE=SxS Pro memory card + +pci:v0000104Dd0000902D* + ID_PRODUCT_FROM_DATABASE=VAIO VGN-NR120E + +pci:v0000104E* + ID_VENDOR_FROM_DATABASE=Oak Technology, Inc + +pci:v0000104Ed00000017* + ID_PRODUCT_FROM_DATABASE=OTI-64017 + +pci:v0000104Ed00000107* + ID_PRODUCT_FROM_DATABASE=OTI-107 [Spitfire] + +pci:v0000104Ed00000109* + ID_PRODUCT_FROM_DATABASE=Video Adapter + +pci:v0000104Ed00000111* + ID_PRODUCT_FROM_DATABASE=OTI-64111 [Spitfire] + +pci:v0000104Ed00000217* + ID_PRODUCT_FROM_DATABASE=OTI-64217 + +pci:v0000104Ed00000317* + ID_PRODUCT_FROM_DATABASE=OTI-64317 + +pci:v0000104F* + ID_VENDOR_FROM_DATABASE=Co-time Computer Ltd + +pci:v00001050* + ID_VENDOR_FROM_DATABASE=Winbond Electronics Corp + +pci:v00001050d00000000* + ID_PRODUCT_FROM_DATABASE=NE2000 + +pci:v00001050d00000001* + ID_PRODUCT_FROM_DATABASE=W83769F + +pci:v00001050d00000033* + ID_PRODUCT_FROM_DATABASE=W89C33D 802.11 a/b/g BB/MAC + +pci:v00001050d00000105* + ID_PRODUCT_FROM_DATABASE=W82C105 + +pci:v00001050d00000840* + ID_PRODUCT_FROM_DATABASE=W89C840 + +pci:v00001050d00000840sv00001050sd00000001* + ID_PRODUCT_FROM_DATABASE=W89C840 Ethernet Adapter + +pci:v00001050d00000840sv00001050sd00000840* + ID_PRODUCT_FROM_DATABASE=W89C840 Ethernet Adapter + +pci:v00001050d00000940* + ID_PRODUCT_FROM_DATABASE=W89C940 + +pci:v00001050d00005A5A* + ID_PRODUCT_FROM_DATABASE=W89C940F + +pci:v00001050d00006692* + ID_PRODUCT_FROM_DATABASE=W6692 + +pci:v00001050d00006692sv00001043sd00001702* + ID_PRODUCT_FROM_DATABASE=ISDN Adapter (PCI Bus, D, W) + +pci:v00001050d00006692sv00001043sd00001703* + ID_PRODUCT_FROM_DATABASE=ISDN Adapter (PCI Bus, DV, W) + +pci:v00001050d00006692sv00001043sd00001707* + ID_PRODUCT_FROM_DATABASE=ISDN Adapter (PCI Bus, DV, W) + +pci:v00001050d00006692sv0000144Fsd00001702* + ID_PRODUCT_FROM_DATABASE=ISDN Adapter (PCI Bus, D, W) + +pci:v00001050d00006692sv0000144Fsd00001703* + ID_PRODUCT_FROM_DATABASE=ISDN Adapter (PCI Bus, DV, W) + +pci:v00001050d00006692sv0000144Fsd00001707* + ID_PRODUCT_FROM_DATABASE=ISDN Adapter (PCI Bus, DV, W) + +pci:v00001050d00009921* + ID_PRODUCT_FROM_DATABASE=W99200F MPEG-1 Video Encoder + +pci:v00001050d00009922* + ID_PRODUCT_FROM_DATABASE=W99200F/W9922PF MPEG-1/2 Video Encoder + +pci:v00001050d00009970* + ID_PRODUCT_FROM_DATABASE=W9970CF + +pci:v00001051* + ID_VENDOR_FROM_DATABASE=Anigma, Inc. + +pci:v00001052* + ID_VENDOR_FROM_DATABASE=?Young Micro Systems + +pci:v00001053* + ID_VENDOR_FROM_DATABASE=Young Micro Systems + +pci:v00001054* + ID_VENDOR_FROM_DATABASE=Hitachi, Ltd + +pci:v00001054d00003009* + ID_PRODUCT_FROM_DATABASE=2Gbps Fibre Channel to PCI HBA 3009 + +pci:v00001054d0000300A* + ID_PRODUCT_FROM_DATABASE=4Gbps Fibre Channel to PCI-X HBA 300a + +pci:v00001054d0000300B* + ID_PRODUCT_FROM_DATABASE=4Gbps Fibre Channel to PCI-X HBA 300b + +pci:v00001054d0000300F* + ID_PRODUCT_FROM_DATABASE=ColdFusion 3 Chipset Processor to I/O Controller + +pci:v00001054d00003010* + ID_PRODUCT_FROM_DATABASE=ColdFusion 3 Chipset Memory Controller Hub + +pci:v00001054d00003011* + ID_PRODUCT_FROM_DATABASE=ColdFusion 3e Chipset Processor to I/O Controller + +pci:v00001054d00003012* + ID_PRODUCT_FROM_DATABASE=ColdFusion 3e Chipset Memory Controller Hub + +pci:v00001054d00003017* + ID_PRODUCT_FROM_DATABASE=Unassigned Hitachi Shared FC Device 3017 + +pci:v00001054d0000301B* + ID_PRODUCT_FROM_DATABASE=Virtual VGA Device + +pci:v00001054d0000301D* + ID_PRODUCT_FROM_DATABASE=PCIe-to-PCIe Bridge with Virtualization IO Assist Feature + +pci:v00001054d00003020* + ID_PRODUCT_FROM_DATABASE=FIVE-EX based Fibre Channel to PCIe HBA + +pci:v00001054d0000302C* + ID_PRODUCT_FROM_DATABASE=M001 PCI Express Switch Upstream Port + +pci:v00001054d0000302D* + ID_PRODUCT_FROM_DATABASE=M001 PCI Express Switch Downstream Port + +pci:v00001054d00003505* + ID_PRODUCT_FROM_DATABASE=SH7751 PCI Controller (PCIC) + +pci:v00001054d0000350E* + ID_PRODUCT_FROM_DATABASE=SH7751R PCI Controller (PCIC) + +pci:v00001055* + ID_VENDOR_FROM_DATABASE=Efar Microsystems + +pci:v00001055d00009130* + ID_PRODUCT_FROM_DATABASE=SLC90E66 [Victory66] IDE + +pci:v00001055d00009460* + ID_PRODUCT_FROM_DATABASE=SLC90E66 [Victory66] ISA + +pci:v00001055d00009462* + ID_PRODUCT_FROM_DATABASE=SLC90E66 [Victory66] USB + +pci:v00001055d00009463* + ID_PRODUCT_FROM_DATABASE=SLC90E66 [Victory66] ACPI + +pci:v00001055d0000E420* + ID_PRODUCT_FROM_DATABASE=LAN9420/LAN9420i + +pci:v00001056* + ID_VENDOR_FROM_DATABASE=ICL + +pci:v00001057* + ID_VENDOR_FROM_DATABASE=Motorola + +pci:v00001057d00000001* + ID_PRODUCT_FROM_DATABASE=MPC105 [Eagle] + +pci:v00001057d00000002* + ID_PRODUCT_FROM_DATABASE=MPC106 [Grackle] + +pci:v00001057d00000003* + ID_PRODUCT_FROM_DATABASE=MPC8240 [Kahlua] + +pci:v00001057d00000004* + ID_PRODUCT_FROM_DATABASE=MPC107 + +pci:v00001057d00000006* + ID_PRODUCT_FROM_DATABASE=MPC8245 [Unity] + +pci:v00001057d00000008* + ID_PRODUCT_FROM_DATABASE=MPC8540 + +pci:v00001057d00000009* + ID_PRODUCT_FROM_DATABASE=MPC8560 + +pci:v00001057d00000012* + ID_PRODUCT_FROM_DATABASE=MPC8548 [PowerQUICC III] + +pci:v00001057d00000100* + ID_PRODUCT_FROM_DATABASE=MC145575 [HFC-PCI] + +pci:v00001057d00000431* + ID_PRODUCT_FROM_DATABASE=KTI829c 100VG + +pci:v00001057d00001073* + ID_PRODUCT_FROM_DATABASE=Nokia N770 + +pci:v00001057d00001219* + ID_PRODUCT_FROM_DATABASE=Nokia N800 + +pci:v00001057d00001801* + ID_PRODUCT_FROM_DATABASE=DSP56301 Digital Signal Processor + +pci:v00001057d00001801sv000014FBsd00000101* + ID_PRODUCT_FROM_DATABASE=Transas Radar Imitator Board [RIM] + +pci:v00001057d00001801sv000014FBsd00000102* + ID_PRODUCT_FROM_DATABASE=Transas Radar Imitator Board [RIM-2] + +pci:v00001057d00001801sv000014FBsd00000202* + ID_PRODUCT_FROM_DATABASE=Transas Radar Integrator Board [RIB-2] + +pci:v00001057d00001801sv000014FBsd00000611* + ID_PRODUCT_FROM_DATABASE=1 channel CAN bus Controller [CanPci-1] + +pci:v00001057d00001801sv000014FBsd00000612* + ID_PRODUCT_FROM_DATABASE=2 channels CAN bus Controller [CanPci-2] + +pci:v00001057d00001801sv000014FBsd00000613* + ID_PRODUCT_FROM_DATABASE=3 channels CAN bus Controller [CanPci-3] + +pci:v00001057d00001801sv000014FBsd00000614* + ID_PRODUCT_FROM_DATABASE=4 channels CAN bus Controller [CanPci-4] + +pci:v00001057d00001801sv000014FBsd00000621* + ID_PRODUCT_FROM_DATABASE=1 channel CAN bus Controller [CanPci2-1] + +pci:v00001057d00001801sv000014FBsd00000622* + ID_PRODUCT_FROM_DATABASE=2 channels CAN bus Controller [CanPci2-2] + +pci:v00001057d00001801sv000014FBsd00000810* + ID_PRODUCT_FROM_DATABASE=Transas VTS Radar Integrator Board [RIB-4] + +pci:v00001057d00001801sv0000175Csd00004200* + ID_PRODUCT_FROM_DATABASE=ASI4215 Audio Adapter + +pci:v00001057d00001801sv0000175Csd00004300* + ID_PRODUCT_FROM_DATABASE=ASI43xx Audio Adapter + +pci:v00001057d00001801sv0000175Csd00004400* + ID_PRODUCT_FROM_DATABASE=ASI4401 Audio Adapter + +pci:v00001057d00001801sv0000ECC0sd00000010* + ID_PRODUCT_FROM_DATABASE=Darla + +pci:v00001057d00001801sv0000ECC0sd00000020* + ID_PRODUCT_FROM_DATABASE=Gina + +pci:v00001057d00001801sv0000ECC0sd00000030* + ID_PRODUCT_FROM_DATABASE=Layla rev.0 + +pci:v00001057d00001801sv0000ECC0sd00000031* + ID_PRODUCT_FROM_DATABASE=Layla rev.1 + +pci:v00001057d00001801sv0000ECC0sd00000040* + ID_PRODUCT_FROM_DATABASE=Darla24 rev.0 + +pci:v00001057d00001801sv0000ECC0sd00000041* + ID_PRODUCT_FROM_DATABASE=Darla24 rev.1 + +pci:v00001057d00001801sv0000ECC0sd00000050* + ID_PRODUCT_FROM_DATABASE=Gina24 rev.0 + +pci:v00001057d00001801sv0000ECC0sd00000051* + ID_PRODUCT_FROM_DATABASE=Gina24 rev.1 + +pci:v00001057d00001801sv0000ECC0sd00000070* + ID_PRODUCT_FROM_DATABASE=Mona rev.0 + +pci:v00001057d00001801sv0000ECC0sd00000071* + ID_PRODUCT_FROM_DATABASE=Mona rev.1 + +pci:v00001057d00001801sv0000ECC0sd00000072* + ID_PRODUCT_FROM_DATABASE=Mona rev.2 + +pci:v00001057d000018C0* + ID_PRODUCT_FROM_DATABASE=MPC8265A/8266/8272 + +pci:v00001057d000018C1* + ID_PRODUCT_FROM_DATABASE=MPC8271/MPC8272 + +pci:v00001057d00003052* + ID_PRODUCT_FROM_DATABASE=SM56 Data Fax Modem + +pci:v00001057d00003055* + ID_PRODUCT_FROM_DATABASE=SM56 Data Fax Modem + +pci:v00001057d00003410* + ID_PRODUCT_FROM_DATABASE=DSP56361 Digital Signal Processor + +pci:v00001057d00003410sv0000ECC0sd00000050* + ID_PRODUCT_FROM_DATABASE=Gina24 rev.0 + +pci:v00001057d00003410sv0000ECC0sd00000051* + ID_PRODUCT_FROM_DATABASE=Gina24 rev.1 + +pci:v00001057d00003410sv0000ECC0sd00000060* + ID_PRODUCT_FROM_DATABASE=Layla24 + +pci:v00001057d00003410sv0000ECC0sd00000070* + ID_PRODUCT_FROM_DATABASE=Mona rev.0 + +pci:v00001057d00003410sv0000ECC0sd00000071* + ID_PRODUCT_FROM_DATABASE=Mona rev.1 + +pci:v00001057d00003410sv0000ECC0sd00000072* + ID_PRODUCT_FROM_DATABASE=Mona rev.2 + +pci:v00001057d00003410sv0000ECC0sd00000080* + ID_PRODUCT_FROM_DATABASE=Mia rev.0 + +pci:v00001057d00003410sv0000ECC0sd00000081* + ID_PRODUCT_FROM_DATABASE=Mia rev.1 + +pci:v00001057d00003410sv0000ECC0sd00000090* + ID_PRODUCT_FROM_DATABASE=Indigo + +pci:v00001057d00003410sv0000ECC0sd000000A0* + ID_PRODUCT_FROM_DATABASE=Indigo IO + +pci:v00001057d00003410sv0000ECC0sd000000B0* + ID_PRODUCT_FROM_DATABASE=Indigo DJ + +pci:v00001057d00003410sv0000ECC0sd00000100* + ID_PRODUCT_FROM_DATABASE=3G + +pci:v00001057d00004801* + ID_PRODUCT_FROM_DATABASE=Raven + +pci:v00001057d00004802* + ID_PRODUCT_FROM_DATABASE=Falcon + +pci:v00001057d00004803* + ID_PRODUCT_FROM_DATABASE=Hawk + +pci:v00001057d00004806* + ID_PRODUCT_FROM_DATABASE=CPX8216 + +pci:v00001057d00004D68* + ID_PRODUCT_FROM_DATABASE=20268 + +pci:v00001057d00005600* + ID_PRODUCT_FROM_DATABASE=SM56 PCI Modem + +pci:v00001057d00005600sv00001057sd00000300* + ID_PRODUCT_FROM_DATABASE=SM56 PCI Speakerphone Modem + +pci:v00001057d00005600sv00001057sd00000301* + ID_PRODUCT_FROM_DATABASE=SM56 PCI Voice Modem + +pci:v00001057d00005600sv00001057sd00000302* + ID_PRODUCT_FROM_DATABASE=SM56 PCI Fax Modem + +pci:v00001057d00005600sv00001057sd00005600* + ID_PRODUCT_FROM_DATABASE=SM56 PCI Voice modem + +pci:v00001057d00005600sv000013D2sd00000300* + ID_PRODUCT_FROM_DATABASE=SM56 PCI Speakerphone Modem + +pci:v00001057d00005600sv000013D2sd00000301* + ID_PRODUCT_FROM_DATABASE=SM56 PCI Voice modem + +pci:v00001057d00005600sv000013D2sd00000302* + ID_PRODUCT_FROM_DATABASE=SM56 PCI Fax Modem + +pci:v00001057d00005600sv00001436sd00000300* + ID_PRODUCT_FROM_DATABASE=SM56 PCI Speakerphone Modem + +pci:v00001057d00005600sv00001436sd00000301* + ID_PRODUCT_FROM_DATABASE=SM56 PCI Voice modem + +pci:v00001057d00005600sv00001436sd00000302* + ID_PRODUCT_FROM_DATABASE=SM56 PCI Fax Modem + +pci:v00001057d00005600sv0000144Fsd0000100C* + ID_PRODUCT_FROM_DATABASE=SM56 PCI Fax Modem + +pci:v00001057d00005600sv00001494sd00000300* + ID_PRODUCT_FROM_DATABASE=SM56 PCI Speakerphone Modem + +pci:v00001057d00005600sv00001494sd00000301* + ID_PRODUCT_FROM_DATABASE=SM56 PCI Voice modem + +pci:v00001057d00005600sv000014C8sd00000300* + ID_PRODUCT_FROM_DATABASE=SM56 PCI Speakerphone Modem + +pci:v00001057d00005600sv000014C8sd00000302* + ID_PRODUCT_FROM_DATABASE=SM56 PCI Fax Modem + +pci:v00001057d00005600sv00001668sd00000300* + ID_PRODUCT_FROM_DATABASE=SM56 PCI Speakerphone Modem + +pci:v00001057d00005600sv00001668sd00000302* + ID_PRODUCT_FROM_DATABASE=SM56 PCI Fax Modem + +pci:v00001057d00005608* + ID_PRODUCT_FROM_DATABASE=Wildcard X100P + +pci:v00001057d00005803* + ID_PRODUCT_FROM_DATABASE=MPC5200 + +pci:v00001057d00005806* + ID_PRODUCT_FROM_DATABASE=MCF54 Coldfire + +pci:v00001057d00005808* + ID_PRODUCT_FROM_DATABASE=MPC8220 + +pci:v00001057d00005809* + ID_PRODUCT_FROM_DATABASE=MPC5200B + +pci:v00001057d00006400* + ID_PRODUCT_FROM_DATABASE=MPC190 Security Processor (S1 family, encryption) + +pci:v00001057d00006405* + ID_PRODUCT_FROM_DATABASE=MPC184 Security Processor (S1 family) + +pci:v00001058* + ID_VENDOR_FROM_DATABASE=Electronics & Telecommunications RSH + +pci:v00001059* + ID_VENDOR_FROM_DATABASE=Kontron + +pci:v0000105A* + ID_VENDOR_FROM_DATABASE=Promise Technology, Inc. + +pci:v0000105Ad00000D30* + ID_PRODUCT_FROM_DATABASE=PDC20265 (FastTrak100 Lite/Ultra100) + +pci:v0000105Ad00000D30sv00001043sd00008042* + ID_PRODUCT_FROM_DATABASE=AV7266-E South Bridge Promise RAID + +pci:v0000105Ad00000D30sv0000105Asd00004D33* + ID_PRODUCT_FROM_DATABASE=Ultra100 + +pci:v0000105Ad00000D38* + ID_PRODUCT_FROM_DATABASE=20263 + +pci:v0000105Ad00000D38sv0000105Asd00004D39* + ID_PRODUCT_FROM_DATABASE=Fasttrak66 + +pci:v0000105Ad00001275* + ID_PRODUCT_FROM_DATABASE=20275 + +pci:v0000105Ad00003318* + ID_PRODUCT_FROM_DATABASE=PDC20318 (SATA150 TX4) + +pci:v0000105Ad00003319* + ID_PRODUCT_FROM_DATABASE=PDC20319 (FastTrak S150 TX4) + +pci:v0000105Ad00003319sv00008086sd00003427* + ID_PRODUCT_FROM_DATABASE=S875WP1-E mainboard + +pci:v0000105Ad00003371* + ID_PRODUCT_FROM_DATABASE=PDC20371 (FastTrak S150 TX2plus) + +pci:v0000105Ad00003373* + ID_PRODUCT_FROM_DATABASE=PDC20378 (FastTrak 378/SATA 378) + +pci:v0000105Ad00003373sv00001043sd000080F5* + ID_PRODUCT_FROM_DATABASE=K8V Deluxe/PC-DL Deluxe motherboard + +pci:v0000105Ad00003373sv00001462sd0000590D* + ID_PRODUCT_FROM_DATABASE=KT6 Delta-FIS2R (MS-6590) + +pci:v0000105Ad00003373sv00001462sd0000702E* + ID_PRODUCT_FROM_DATABASE=K8T NEO FIS2R motherboard + +pci:v0000105Ad00003375* + ID_PRODUCT_FROM_DATABASE=PDC20375 (SATA150 TX2plus) + +pci:v0000105Ad00003376* + ID_PRODUCT_FROM_DATABASE=PDC20376 (FastTrak 376) + +pci:v0000105Ad00003376sv00001043sd0000809E* + ID_PRODUCT_FROM_DATABASE=A7V8X motherboard + +pci:v0000105Ad00003515* + ID_PRODUCT_FROM_DATABASE=PDC40719 [FastTrak TX4300/TX4310] + +pci:v0000105Ad00003519* + ID_PRODUCT_FROM_DATABASE=PDC40519 (FastTrak TX4200) + +pci:v0000105Ad00003570* + ID_PRODUCT_FROM_DATABASE=PDC20771 [FastTrak TX2300] + +pci:v0000105Ad00003571* + ID_PRODUCT_FROM_DATABASE=PDC20571 (FastTrak TX2200) + +pci:v0000105Ad00003574* + ID_PRODUCT_FROM_DATABASE=PDC20579 SATAII 150 IDE Controller + +pci:v0000105Ad00003577* + ID_PRODUCT_FROM_DATABASE=PDC40779 (SATA 300 779) + +pci:v0000105Ad00003D17* + ID_PRODUCT_FROM_DATABASE=PDC40718 (SATA 300 TX4) + +pci:v0000105Ad00003D18* + ID_PRODUCT_FROM_DATABASE=PDC20518/PDC40518 (SATAII 150 TX4) + +pci:v0000105Ad00003D73* + ID_PRODUCT_FROM_DATABASE=PDC40775 (SATA 300 TX2plus) + +pci:v0000105Ad00003D75* + ID_PRODUCT_FROM_DATABASE=PDC20575 (SATAII150 TX2plus) + +pci:v0000105Ad00003F20* + ID_PRODUCT_FROM_DATABASE=PDC42819 [FastTrak TX2650/TX4650] + +pci:v0000105Ad00004302* + ID_PRODUCT_FROM_DATABASE=80333 [SuperTrak EX4350] + +pci:v0000105Ad00004D30* + ID_PRODUCT_FROM_DATABASE=PDC20267 (FastTrak100/Ultra100) + +pci:v0000105Ad00004D30sv0000105Asd00004D33* + ID_PRODUCT_FROM_DATABASE=Ultra100 + +pci:v0000105Ad00004D30sv0000105Asd00004D39* + ID_PRODUCT_FROM_DATABASE=FastTrak100 + +pci:v0000105Ad00004D30sv00008086sd00005744* + ID_PRODUCT_FROM_DATABASE=S845WD1-E mainboard + +pci:v0000105Ad00004D33* + ID_PRODUCT_FROM_DATABASE=20246 + +pci:v0000105Ad00004D33sv0000105Asd00004D33* + ID_PRODUCT_FROM_DATABASE=20246 IDE Controller + +pci:v0000105Ad00004D38* + ID_PRODUCT_FROM_DATABASE=PDC20262 (FastTrak66/Ultra66) + +pci:v0000105Ad00004D38sv0000105Asd00004D30* + ID_PRODUCT_FROM_DATABASE=Ultra Device on SuperTrak + +pci:v0000105Ad00004D38sv0000105Asd00004D33* + ID_PRODUCT_FROM_DATABASE=Ultra66 + +pci:v0000105Ad00004D38sv0000105Asd00004D39* + ID_PRODUCT_FROM_DATABASE=FastTrak66 + +pci:v0000105Ad00004D68* + ID_PRODUCT_FROM_DATABASE=PDC20268 [Ultra100 TX2] + +pci:v0000105Ad00004D68sv0000105Asd00004D68* + ID_PRODUCT_FROM_DATABASE=Ultra100 TX2 + +pci:v0000105Ad00004D69* + ID_PRODUCT_FROM_DATABASE=20269 + +pci:v0000105Ad00004D69sv0000105Asd00004D68* + ID_PRODUCT_FROM_DATABASE=Ultra133TX2 + +pci:v0000105Ad00005275* + ID_PRODUCT_FROM_DATABASE=PDC20276 (MBFastTrak133 Lite) + +pci:v0000105Ad00005275sv00001043sd0000807E* + ID_PRODUCT_FROM_DATABASE=A7V333 motherboard. + +pci:v0000105Ad00005275sv0000105Asd00000275* + ID_PRODUCT_FROM_DATABASE=SuperTrak SX6000 IDE + +pci:v0000105Ad00005275sv0000105Asd00001275* + ID_PRODUCT_FROM_DATABASE=MBFastTrak133 Lite (tm) Controller (RAID mode) + +pci:v0000105Ad00005275sv00001458sd0000B001* + ID_PRODUCT_FROM_DATABASE=MBUltra 133 + +pci:v0000105Ad00005300* + ID_PRODUCT_FROM_DATABASE=DC5300 + +pci:v0000105Ad00006268* + ID_PRODUCT_FROM_DATABASE=PDC20270 (FastTrak100 LP/TX2/TX4) + +pci:v0000105Ad00006268sv0000105Asd00004D68* + ID_PRODUCT_FROM_DATABASE=FastTrak100 TX2 + +pci:v0000105Ad00006269* + ID_PRODUCT_FROM_DATABASE=PDC20271 (FastTrak TX2000) + +pci:v0000105Ad00006269sv0000105Asd00006269* + ID_PRODUCT_FROM_DATABASE=FastTrak TX2/TX2000 + +pci:v0000105Ad00006300* + ID_PRODUCT_FROM_DATABASE=PDC81731 [FastTrak SX8300] + +pci:v0000105Ad00006621* + ID_PRODUCT_FROM_DATABASE=PDC20621 (FastTrak S150 SX4/FastTrak SX4000 lite) + +pci:v0000105Ad00006622* + ID_PRODUCT_FROM_DATABASE=PDC20621 [SATA150 SX4] 4 Channel IDE RAID Controller + +pci:v0000105Ad00006624* + ID_PRODUCT_FROM_DATABASE=PDC20621 [FastTrak SX4100] + +pci:v0000105Ad00006626* + ID_PRODUCT_FROM_DATABASE=PDC20618 (Ultra 618) + +pci:v0000105Ad00006629* + ID_PRODUCT_FROM_DATABASE=PDC20619 (FastTrak TX4000) + +pci:v0000105Ad00007275* + ID_PRODUCT_FROM_DATABASE=PDC20277 (SBFastTrak133 Lite) + +pci:v0000105Ad00008002* + ID_PRODUCT_FROM_DATABASE=SATAII150 SX8 + +pci:v0000105Ad00008350* + ID_PRODUCT_FROM_DATABASE=80333 [SuperTrak EX8350/EX16350], 80331 [SuperTrak EX8300/EX16300] + +pci:v0000105Ad00008650* + ID_PRODUCT_FROM_DATABASE=81384 [SuperTrak EX SAS and SATA RAID Controller] + +pci:v0000105Ad00008650sv0000105Asd00004600* + ID_PRODUCT_FROM_DATABASE=SuperTrak EX4650A + +pci:v0000105Ad00008650sv0000105Asd00004601* + ID_PRODUCT_FROM_DATABASE=SuperTrak EX4650 + +pci:v0000105Ad00008650sv0000105Asd00004610* + ID_PRODUCT_FROM_DATABASE=SuperTrak EX4650EL + +pci:v0000105Ad00008650sv0000105Asd00008600* + ID_PRODUCT_FROM_DATABASE=SuperTrak EX8650EL + +pci:v0000105Ad00008650sv0000105Asd00008601* + ID_PRODUCT_FROM_DATABASE=SuperTrak EX8650A + +pci:v0000105Ad00008650sv0000105Asd00008602* + ID_PRODUCT_FROM_DATABASE=SuperTrak EX8654 + +pci:v0000105Ad00008650sv0000105Asd00008603* + ID_PRODUCT_FROM_DATABASE=SuperTrak EX8658 + +pci:v0000105Ad00008650sv0000105Asd00008604* + ID_PRODUCT_FROM_DATABASE=SuperTrak EX8650 + +pci:v0000105Ad00008650sv0000105Asd00008610* + ID_PRODUCT_FROM_DATABASE=SuperTrak EX8650M + +pci:v0000105Ad00008650sv0000105Asd0000A600* + ID_PRODUCT_FROM_DATABASE=SuperTrak EX12650 + +pci:v0000105Ad00008650sv0000105Asd0000B600* + ID_PRODUCT_FROM_DATABASE=SuperTrak EX16650 + +pci:v0000105Ad00008650sv0000105Asd0000B601* + ID_PRODUCT_FROM_DATABASE=SuperTrak EX16654 + +pci:v0000105Ad00008650sv0000105Asd0000B602* + ID_PRODUCT_FROM_DATABASE=SuperTrak EX16658 + +pci:v0000105Ad00008760* + ID_PRODUCT_FROM_DATABASE=PM8010 [SuperTrak EX SAS and SATA 6G RAID Controller] + +pci:v0000105Ad0000C350* + ID_PRODUCT_FROM_DATABASE=80333 [SuperTrak EX12350] + +pci:v0000105Ad0000E350* + ID_PRODUCT_FROM_DATABASE=80333 [SuperTrak EX24350] + +pci:v0000105B* + ID_VENDOR_FROM_DATABASE=Foxconn International, Inc. + +pci:v0000105Bd00000C4D* + ID_PRODUCT_FROM_DATABASE=SiS AC'97 Sound Controller + +pci:v0000105C* + ID_VENDOR_FROM_DATABASE=Wipro Infotech Limited + +pci:v0000105D* + ID_VENDOR_FROM_DATABASE=Number 9 Computer Company + +pci:v0000105Dd00002309* + ID_PRODUCT_FROM_DATABASE=Imagine 128 + +pci:v0000105Dd00002339* + ID_PRODUCT_FROM_DATABASE=Imagine 128-II + +pci:v0000105Dd00002339sv0000105Dsd00000000* + ID_PRODUCT_FROM_DATABASE=Imagine 128 series 2 4Mb VRAM + +pci:v0000105Dd00002339sv0000105Dsd00000001* + ID_PRODUCT_FROM_DATABASE=Imagine 128 series 2 4Mb VRAM + +pci:v0000105Dd00002339sv0000105Dsd00000002* + ID_PRODUCT_FROM_DATABASE=Imagine 128 series 2 4Mb VRAM + +pci:v0000105Dd00002339sv0000105Dsd00000003* + ID_PRODUCT_FROM_DATABASE=Imagine 128 series 2 4Mb VRAM + +pci:v0000105Dd00002339sv0000105Dsd00000004* + ID_PRODUCT_FROM_DATABASE=Imagine 128 series 2 4Mb VRAM + +pci:v0000105Dd00002339sv0000105Dsd00000005* + ID_PRODUCT_FROM_DATABASE=Imagine 128 series 2 4Mb VRAM + +pci:v0000105Dd00002339sv0000105Dsd00000006* + ID_PRODUCT_FROM_DATABASE=Imagine 128 series 2 4Mb VRAM + +pci:v0000105Dd00002339sv0000105Dsd00000007* + ID_PRODUCT_FROM_DATABASE=Imagine 128 series 2 4Mb VRAM + +pci:v0000105Dd00002339sv0000105Dsd00000008* + ID_PRODUCT_FROM_DATABASE=Imagine 128 series 2e 4Mb DRAM + +pci:v0000105Dd00002339sv0000105Dsd00000009* + ID_PRODUCT_FROM_DATABASE=Imagine 128 series 2e 4Mb DRAM + +pci:v0000105Dd00002339sv0000105Dsd0000000A* + ID_PRODUCT_FROM_DATABASE=Imagine 128 series 2 8Mb VRAM + +pci:v0000105Dd00002339sv0000105Dsd0000000B* + ID_PRODUCT_FROM_DATABASE=Imagine 128 series 2 8Mb H-VRAM + +pci:v0000105Dd00002339sv000011A4sd0000000A* + ID_PRODUCT_FROM_DATABASE=Barco Metheus 5 Megapixel + +pci:v0000105Dd00002339sv000013CCsd00000000* + ID_PRODUCT_FROM_DATABASE=Barco Metheus 5 Megapixel + +pci:v0000105Dd00002339sv000013CCsd00000004* + ID_PRODUCT_FROM_DATABASE=Barco Metheus 5 Megapixel + +pci:v0000105Dd00002339sv000013CCsd00000005* + ID_PRODUCT_FROM_DATABASE=Barco Metheus 5 Megapixel + +pci:v0000105Dd00002339sv000013CCsd00000006* + ID_PRODUCT_FROM_DATABASE=Barco Metheus 5 Megapixel + +pci:v0000105Dd00002339sv000013CCsd00000008* + ID_PRODUCT_FROM_DATABASE=Barco Metheus 5 Megapixel + +pci:v0000105Dd00002339sv000013CCsd00000009* + ID_PRODUCT_FROM_DATABASE=Barco Metheus 5 Megapixel + +pci:v0000105Dd00002339sv000013CCsd0000000A* + ID_PRODUCT_FROM_DATABASE=Barco Metheus 5 Megapixel + +pci:v0000105Dd00002339sv000013CCsd0000000C* + ID_PRODUCT_FROM_DATABASE=Barco Metheus 5 Megapixel + +pci:v0000105Dd0000493D* + ID_PRODUCT_FROM_DATABASE=Imagine 128 T2R [Ticket to Ride] + +pci:v0000105Dd0000493Dsv000011A4sd0000000A* + ID_PRODUCT_FROM_DATABASE=Barco Metheus 5 Megapixel, Dual Head + +pci:v0000105Dd0000493Dsv000011A4sd0000000B* + ID_PRODUCT_FROM_DATABASE=Barco Metheus 5 Megapixel, Dual Head + +pci:v0000105Dd0000493Dsv000013CCsd00000002* + ID_PRODUCT_FROM_DATABASE=Barco Metheus 4 Megapixel, Dual Head + +pci:v0000105Dd0000493Dsv000013CCsd00000003* + ID_PRODUCT_FROM_DATABASE=Barco Metheus 5 Megapixel, Dual Head + +pci:v0000105Dd0000493Dsv000013CCsd00000007* + ID_PRODUCT_FROM_DATABASE=Barco Metheus 5 Megapixel, Dual Head + +pci:v0000105Dd0000493Dsv000013CCsd00000008* + ID_PRODUCT_FROM_DATABASE=Barco Metheus 5 Megapixel, Dual Head + +pci:v0000105Dd0000493Dsv000013CCsd00000009* + ID_PRODUCT_FROM_DATABASE=Barco Metheus 5 Megapixel, Dual Head + +pci:v0000105Dd0000493Dsv000013CCsd0000000A* + ID_PRODUCT_FROM_DATABASE=Barco Metheus 5 Megapixel, Dual Head + +pci:v0000105Dd00005348* + ID_PRODUCT_FROM_DATABASE=Revolution 4 + +pci:v0000105Dd00005348sv0000105Dsd00000037* + ID_PRODUCT_FROM_DATABASE=Revolution IV-FP AGP (For SGI 1600SW) + +pci:v0000105Dd00005348sv000011A4sd00000028* + ID_PRODUCT_FROM_DATABASE=PVS5600M + +pci:v0000105Dd00005348sv000011A4sd00000038* + ID_PRODUCT_FROM_DATABASE=PVS5600D + +pci:v0000105E* + ID_VENDOR_FROM_DATABASE=Vtech Computers Ltd + +pci:v0000105F* + ID_VENDOR_FROM_DATABASE=Infotronic America Inc + +pci:v00001060* + ID_VENDOR_FROM_DATABASE=United Microelectronics [UMC] + +pci:v00001060d00000001* + ID_PRODUCT_FROM_DATABASE=UM82C881 + +pci:v00001060d00000002* + ID_PRODUCT_FROM_DATABASE=UM82C886 + +pci:v00001060d00000101* + ID_PRODUCT_FROM_DATABASE=UM8673F + +pci:v00001060d00000881* + ID_PRODUCT_FROM_DATABASE=UM8881 + +pci:v00001060d00000886* + ID_PRODUCT_FROM_DATABASE=UM8886F + +pci:v00001060d00000891* + ID_PRODUCT_FROM_DATABASE=UM8891A + +pci:v00001060d00001001* + ID_PRODUCT_FROM_DATABASE=UM886A + +pci:v00001060d0000673A* + ID_PRODUCT_FROM_DATABASE=UM8886BF + +pci:v00001060d0000673B* + ID_PRODUCT_FROM_DATABASE=EIDE Master/DMA + +pci:v00001060d00008710* + ID_PRODUCT_FROM_DATABASE=UM8710 + +pci:v00001060d0000886A* + ID_PRODUCT_FROM_DATABASE=UM8886A + +pci:v00001060d00008881* + ID_PRODUCT_FROM_DATABASE=UM8881F + +pci:v00001060d00008886* + ID_PRODUCT_FROM_DATABASE=UM8886F + +pci:v00001060d0000888A* + ID_PRODUCT_FROM_DATABASE=UM8886A + +pci:v00001060d00008891* + ID_PRODUCT_FROM_DATABASE=UM8891A + +pci:v00001060d00009017* + ID_PRODUCT_FROM_DATABASE=UM9017F + +pci:v00001060d00009018* + ID_PRODUCT_FROM_DATABASE=UM9018 + +pci:v00001060d00009026* + ID_PRODUCT_FROM_DATABASE=UM9026 + +pci:v00001060d0000E881* + ID_PRODUCT_FROM_DATABASE=UM8881N + +pci:v00001060d0000E886* + ID_PRODUCT_FROM_DATABASE=UM8886N + +pci:v00001060d0000E88A* + ID_PRODUCT_FROM_DATABASE=UM8886N + +pci:v00001060d0000E891* + ID_PRODUCT_FROM_DATABASE=UM8891N + +pci:v00001061* + ID_VENDOR_FROM_DATABASE=I.I.T. + +pci:v00001061d00000001* + ID_PRODUCT_FROM_DATABASE=AGX016 + +pci:v00001061d00000002* + ID_PRODUCT_FROM_DATABASE=IIT3204/3501 + +pci:v00001062* + ID_VENDOR_FROM_DATABASE=Maspar Computer Corp + +pci:v00001063* + ID_VENDOR_FROM_DATABASE=Ocean Office Automation + +pci:v00001064* + ID_VENDOR_FROM_DATABASE=Alcatel + +pci:v00001064d00001102* + ID_PRODUCT_FROM_DATABASE=Dynamite 2840 (ADSL PCI modem) + +pci:v00001065* + ID_VENDOR_FROM_DATABASE=Texas Microsystems + +pci:v00001066* + ID_VENDOR_FROM_DATABASE=PicoPower Technology + +pci:v00001066d00000000* + ID_PRODUCT_FROM_DATABASE=PT80C826 + +pci:v00001066d00000001* + ID_PRODUCT_FROM_DATABASE=PT86C521 [Vesuvius v1] Host Bridge + +pci:v00001066d00000002* + ID_PRODUCT_FROM_DATABASE=PT86C523 [Vesuvius v3] PCI-ISA Bridge Master + +pci:v00001066d00000003* + ID_PRODUCT_FROM_DATABASE=PT86C524 [Nile] PCI-to-PCI Bridge + +pci:v00001066d00000004* + ID_PRODUCT_FROM_DATABASE=PT86C525 [Nile-II] PCI-to-PCI Bridge + +pci:v00001066d00000005* + ID_PRODUCT_FROM_DATABASE=National PC87550 System Controller + +pci:v00001066d00008002* + ID_PRODUCT_FROM_DATABASE=PT86C523 [Vesuvius v3] PCI-ISA Bridge Slave + +pci:v00001067* + ID_VENDOR_FROM_DATABASE=Mitsubishi Electric + +pci:v00001067d00000301* + ID_PRODUCT_FROM_DATABASE=AccelGraphics AccelECLIPSE + +pci:v00001067d00000304* + ID_PRODUCT_FROM_DATABASE=AccelGALAXY A2100 [OEM Evans & Sutherland] + +pci:v00001067d00000308* + ID_PRODUCT_FROM_DATABASE=Tornado 3000 [OEM Evans & Sutherland] + +pci:v00001067d00001002* + ID_PRODUCT_FROM_DATABASE=VG500 [VolumePro Volume Rendering Accelerator] + +pci:v00001068* + ID_VENDOR_FROM_DATABASE=Diversified Technology + +pci:v00001069* + ID_VENDOR_FROM_DATABASE=Mylex Corporation + +pci:v00001069d00000001* + ID_PRODUCT_FROM_DATABASE=DAC960P + +pci:v00001069d00000002* + ID_PRODUCT_FROM_DATABASE=DAC960PD + +pci:v00001069d00000010* + ID_PRODUCT_FROM_DATABASE=DAC960PG + +pci:v00001069d00000020* + ID_PRODUCT_FROM_DATABASE=DAC960LA + +pci:v00001069d00000050* + ID_PRODUCT_FROM_DATABASE=AcceleRAID 352/170/160 support Device + +pci:v00001069d00000050sv00001069sd00000050* + ID_PRODUCT_FROM_DATABASE=AcceleRAID 352 support Device + +pci:v00001069d00000050sv00001069sd00000052* + ID_PRODUCT_FROM_DATABASE=AcceleRAID 170 support Device + +pci:v00001069d00000050sv00001069sd00000054* + ID_PRODUCT_FROM_DATABASE=AcceleRAID 160 support Device + +pci:v00001069d0000B166* + ID_PRODUCT_FROM_DATABASE=AcceleRAID 600/500/400/Sapphire support Device + +pci:v00001069d0000B166sv00001014sd00000242* + ID_PRODUCT_FROM_DATABASE=iSeries 2872 DASD IOA + +pci:v00001069d0000B166sv00001014sd00000266* + ID_PRODUCT_FROM_DATABASE=Dual Channel PCI-X U320 SCSI Adapter + +pci:v00001069d0000B166sv00001014sd00000278* + ID_PRODUCT_FROM_DATABASE=Dual Channel PCI-X U320 SCSI RAID Adapter + +pci:v00001069d0000B166sv00001014sd000002D3* + ID_PRODUCT_FROM_DATABASE=Dual Channel PCI-X U320 SCSI Adapter + +pci:v00001069d0000B166sv00001014sd000002D4* + ID_PRODUCT_FROM_DATABASE=Dual Channel PCI-X U320 SCSI RAID Adapter + +pci:v00001069d0000B166sv00001069sd00000200* + ID_PRODUCT_FROM_DATABASE=AcceleRAID 400, Single Channel, PCI-X, U320, SCSI RAID + +pci:v00001069d0000B166sv00001069sd00000202* + ID_PRODUCT_FROM_DATABASE=AcceleRAID Sapphire, Dual Channel, PCI-X, U320, SCSI RAID + +pci:v00001069d0000B166sv00001069sd00000204* + ID_PRODUCT_FROM_DATABASE=AcceleRAID 500, Dual Channel, Low-Profile, PCI-X, U320, SCSI RAID + +pci:v00001069d0000B166sv00001069sd00000206* + ID_PRODUCT_FROM_DATABASE=AcceleRAID 600, Dual Channel, PCI-X, U320, SCSI RAID + +pci:v00001069d0000BA55* + ID_PRODUCT_FROM_DATABASE=eXtremeRAID 1100 support Device + +pci:v00001069d0000BA56* + ID_PRODUCT_FROM_DATABASE=eXtremeRAID 2000/3000 support Device + +pci:v00001069d0000BA56sv00001069sd00000030* + ID_PRODUCT_FROM_DATABASE=eXtremeRAID 3000 support Device + +pci:v00001069d0000BA56sv00001069sd00000040* + ID_PRODUCT_FROM_DATABASE=eXtremeRAID 2000 support Device + +pci:v00001069d0000BA57* + ID_PRODUCT_FROM_DATABASE=eXtremeRAID 4000/5000 support Device + +pci:v00001069d0000BA57sv00001069sd00000072* + ID_PRODUCT_FROM_DATABASE=eXtremeRAID 5000 support Device + +pci:v0000106A* + ID_VENDOR_FROM_DATABASE=Aten Research Inc + +pci:v0000106B* + ID_VENDOR_FROM_DATABASE=Apple Inc. + +pci:v0000106Bd00000001* + ID_PRODUCT_FROM_DATABASE=Bandit PowerPC host bridge + +pci:v0000106Bd00000002* + ID_PRODUCT_FROM_DATABASE=Grand Central I/O + +pci:v0000106Bd00000003* + ID_PRODUCT_FROM_DATABASE=Control Video + +pci:v0000106Bd00000004* + ID_PRODUCT_FROM_DATABASE=PlanB Video-In + +pci:v0000106Bd00000007* + ID_PRODUCT_FROM_DATABASE=O'Hare I/O + +pci:v0000106Bd0000000C* + ID_PRODUCT_FROM_DATABASE=DOS on Mac + +pci:v0000106Bd0000000E* + ID_PRODUCT_FROM_DATABASE=Hydra Mac I/O + +pci:v0000106Bd00000010* + ID_PRODUCT_FROM_DATABASE=Heathrow Mac I/O + +pci:v0000106Bd00000017* + ID_PRODUCT_FROM_DATABASE=Paddington Mac I/O + +pci:v0000106Bd00000018* + ID_PRODUCT_FROM_DATABASE=UniNorth FireWire + +pci:v0000106Bd00000019* + ID_PRODUCT_FROM_DATABASE=KeyLargo USB + +pci:v0000106Bd0000001E* + ID_PRODUCT_FROM_DATABASE=UniNorth Internal PCI + +pci:v0000106Bd0000001F* + ID_PRODUCT_FROM_DATABASE=UniNorth PCI + +pci:v0000106Bd00000020* + ID_PRODUCT_FROM_DATABASE=UniNorth AGP + +pci:v0000106Bd00000021* + ID_PRODUCT_FROM_DATABASE=UniNorth GMAC (Sun GEM) + +pci:v0000106Bd00000022* + ID_PRODUCT_FROM_DATABASE=KeyLargo Mac I/O + +pci:v0000106Bd00000024* + ID_PRODUCT_FROM_DATABASE=UniNorth/Pangea GMAC (Sun GEM) + +pci:v0000106Bd00000025* + ID_PRODUCT_FROM_DATABASE=KeyLargo/Pangea Mac I/O + +pci:v0000106Bd00000026* + ID_PRODUCT_FROM_DATABASE=KeyLargo/Pangea USB + +pci:v0000106Bd00000027* + ID_PRODUCT_FROM_DATABASE=UniNorth/Pangea AGP + +pci:v0000106Bd00000028* + ID_PRODUCT_FROM_DATABASE=UniNorth/Pangea PCI + +pci:v0000106Bd00000029* + ID_PRODUCT_FROM_DATABASE=UniNorth/Pangea Internal PCI + +pci:v0000106Bd0000002D* + ID_PRODUCT_FROM_DATABASE=UniNorth 1.5 AGP + +pci:v0000106Bd0000002E* + ID_PRODUCT_FROM_DATABASE=UniNorth 1.5 PCI + +pci:v0000106Bd0000002F* + ID_PRODUCT_FROM_DATABASE=UniNorth 1.5 Internal PCI + +pci:v0000106Bd00000030* + ID_PRODUCT_FROM_DATABASE=UniNorth/Pangea FireWire + +pci:v0000106Bd00000031* + ID_PRODUCT_FROM_DATABASE=UniNorth 2 FireWire + +pci:v0000106Bd00000031sv0000106Bsd00005811* + ID_PRODUCT_FROM_DATABASE=iBook G4 2004 + +pci:v0000106Bd00000032* + ID_PRODUCT_FROM_DATABASE=UniNorth 2 GMAC (Sun GEM) + +pci:v0000106Bd00000033* + ID_PRODUCT_FROM_DATABASE=UniNorth 2 ATA/100 + +pci:v0000106Bd00000034* + ID_PRODUCT_FROM_DATABASE=UniNorth 2 AGP + +pci:v0000106Bd00000035* + ID_PRODUCT_FROM_DATABASE=UniNorth 2 PCI + +pci:v0000106Bd00000036* + ID_PRODUCT_FROM_DATABASE=UniNorth 2 Internal PCI + +pci:v0000106Bd0000003B* + ID_PRODUCT_FROM_DATABASE=UniNorth/Intrepid ATA/100 + +pci:v0000106Bd0000003E* + ID_PRODUCT_FROM_DATABASE=KeyLargo/Intrepid Mac I/O + +pci:v0000106Bd0000003F* + ID_PRODUCT_FROM_DATABASE=KeyLargo/Intrepid USB + +pci:v0000106Bd00000040* + ID_PRODUCT_FROM_DATABASE=K2 KeyLargo USB + +pci:v0000106Bd00000041* + ID_PRODUCT_FROM_DATABASE=K2 KeyLargo Mac/IO + +pci:v0000106Bd00000042* + ID_PRODUCT_FROM_DATABASE=K2 FireWire + +pci:v0000106Bd00000043* + ID_PRODUCT_FROM_DATABASE=K2 ATA/100 + +pci:v0000106Bd00000045* + ID_PRODUCT_FROM_DATABASE=K2 HT-PCI Bridge + +pci:v0000106Bd00000046* + ID_PRODUCT_FROM_DATABASE=K2 HT-PCI Bridge + +pci:v0000106Bd00000047* + ID_PRODUCT_FROM_DATABASE=K2 HT-PCI Bridge + +pci:v0000106Bd00000048* + ID_PRODUCT_FROM_DATABASE=K2 HT-PCI Bridge + +pci:v0000106Bd00000049* + ID_PRODUCT_FROM_DATABASE=K2 HT-PCI Bridge + +pci:v0000106Bd0000004A* + ID_PRODUCT_FROM_DATABASE=CPC945 HT Bridge + +pci:v0000106Bd0000004B* + ID_PRODUCT_FROM_DATABASE=U3 AGP + +pci:v0000106Bd0000004C* + ID_PRODUCT_FROM_DATABASE=K2 GMAC (Sun GEM) + +pci:v0000106Bd0000004F* + ID_PRODUCT_FROM_DATABASE=Shasta Mac I/O + +pci:v0000106Bd00000050* + ID_PRODUCT_FROM_DATABASE=Shasta IDE + +pci:v0000106Bd00000051* + ID_PRODUCT_FROM_DATABASE=Shasta (Sun GEM) + +pci:v0000106Bd00000052* + ID_PRODUCT_FROM_DATABASE=Shasta Firewire + +pci:v0000106Bd00000053* + ID_PRODUCT_FROM_DATABASE=Shasta PCI Bridge + +pci:v0000106Bd00000054* + ID_PRODUCT_FROM_DATABASE=Shasta PCI Bridge + +pci:v0000106Bd00000055* + ID_PRODUCT_FROM_DATABASE=Shasta PCI Bridge + +pci:v0000106Bd00000056* + ID_PRODUCT_FROM_DATABASE=U4 PCIe + +pci:v0000106Bd00000057* + ID_PRODUCT_FROM_DATABASE=U3 HT Bridge + +pci:v0000106Bd00000058* + ID_PRODUCT_FROM_DATABASE=U3L AGP Bridge + +pci:v0000106Bd00000059* + ID_PRODUCT_FROM_DATABASE=U3H AGP Bridge + +pci:v0000106Bd0000005B* + ID_PRODUCT_FROM_DATABASE=CPC945 PCIe Bridge + +pci:v0000106Bd00000066* + ID_PRODUCT_FROM_DATABASE=Intrepid2 AGP Bridge + +pci:v0000106Bd00000067* + ID_PRODUCT_FROM_DATABASE=Intrepid2 PCI Bridge + +pci:v0000106Bd00000068* + ID_PRODUCT_FROM_DATABASE=Intrepid2 PCI Bridge + +pci:v0000106Bd00000069* + ID_PRODUCT_FROM_DATABASE=Intrepid2 ATA/100 + +pci:v0000106Bd0000006A* + ID_PRODUCT_FROM_DATABASE=Intrepid2 Firewire + +pci:v0000106Bd0000006B* + ID_PRODUCT_FROM_DATABASE=Intrepid2 GMAC (Sun GEM) + +pci:v0000106Bd00000074* + ID_PRODUCT_FROM_DATABASE=U4 HT Bridge + +pci:v0000106Bd00001645* + ID_PRODUCT_FROM_DATABASE=Tigon3 Gigabit Ethernet NIC (BCM5701) + +pci:v0000106C* + ID_VENDOR_FROM_DATABASE=Hynix Semiconductor + +pci:v0000106Cd00008139* + ID_PRODUCT_FROM_DATABASE=8139c 100BaseTX Ethernet Controller + +pci:v0000106Cd00008801* + ID_PRODUCT_FROM_DATABASE=Dual Pentium ISA/PCI Motherboard + +pci:v0000106Cd00008802* + ID_PRODUCT_FROM_DATABASE=PowerPC ISA/PCI Motherboard + +pci:v0000106Cd00008803* + ID_PRODUCT_FROM_DATABASE=Dual Window Graphics Accelerator + +pci:v0000106Cd00008804* + ID_PRODUCT_FROM_DATABASE=LAN Controller + +pci:v0000106Cd00008805* + ID_PRODUCT_FROM_DATABASE=100-BaseT LAN + +pci:v0000106D* + ID_VENDOR_FROM_DATABASE=Sequent Computer Systems + +pci:v0000106E* + ID_VENDOR_FROM_DATABASE=DFI, Inc + +pci:v0000106F* + ID_VENDOR_FROM_DATABASE=City Gate Development Ltd + +pci:v00001070* + ID_VENDOR_FROM_DATABASE=Daewoo Telecom Ltd + +pci:v00001071* + ID_VENDOR_FROM_DATABASE=Mitac + +pci:v00001071d00008160* + ID_PRODUCT_FROM_DATABASE=Mitac 8060B Mobile Platform + +pci:v00001072* + ID_VENDOR_FROM_DATABASE=GIT Co Ltd + +pci:v00001073* + ID_VENDOR_FROM_DATABASE=Yamaha Corporation + +pci:v00001073d00000001* + ID_PRODUCT_FROM_DATABASE=3D GUI Accelerator + +pci:v00001073d00000002* + ID_PRODUCT_FROM_DATABASE=YGV615 [RPA3 3D-Graphics Controller] + +pci:v00001073d00000003* + ID_PRODUCT_FROM_DATABASE=YMF-740 + +pci:v00001073d00000004* + ID_PRODUCT_FROM_DATABASE=YMF-724 + +pci:v00001073d00000004sv00001073sd00000004* + ID_PRODUCT_FROM_DATABASE=YMF724-Based PCI Audio Adapter + +pci:v00001073d00000005* + ID_PRODUCT_FROM_DATABASE=DS1 Audio + +pci:v00001073d00000005sv00001073sd00000005* + ID_PRODUCT_FROM_DATABASE=DS-XG PCI Audio CODEC + +pci:v00001073d00000006* + ID_PRODUCT_FROM_DATABASE=DS1 Audio + +pci:v00001073d00000008* + ID_PRODUCT_FROM_DATABASE=DS1 Audio + +pci:v00001073d00000008sv00001073sd00000008* + ID_PRODUCT_FROM_DATABASE=DS-XG PCI Audio CODEC + +pci:v00001073d0000000A* + ID_PRODUCT_FROM_DATABASE=DS1L Audio + +pci:v00001073d0000000Asv00001073sd00000004* + ID_PRODUCT_FROM_DATABASE=DS-XG PCI Audio CODEC + +pci:v00001073d0000000Asv00001073sd0000000A* + ID_PRODUCT_FROM_DATABASE=DS-XG PCI Audio CODEC + +pci:v00001073d0000000Asv00008086sd00004D55* + ID_PRODUCT_FROM_DATABASE=DS-XG PCI Audio CODEC [Intel MU440EX] + +pci:v00001073d0000000C* + ID_PRODUCT_FROM_DATABASE=YMF-740C [DS-1L Audio Controller] + +pci:v00001073d0000000Csv0000107Asd0000000C* + ID_PRODUCT_FROM_DATABASE=DS-XG PCI Audio CODEC + +pci:v00001073d0000000D* + ID_PRODUCT_FROM_DATABASE=YMF-724F [DS-1 Audio Controller] + +pci:v00001073d0000000Dsv00001073sd0000000D* + ID_PRODUCT_FROM_DATABASE=DS-XG PCI Audio CODEC + +pci:v00001073d00000010* + ID_PRODUCT_FROM_DATABASE=YMF-744B [DS-1S Audio Controller] + +pci:v00001073d00000010sv00001073sd00000006* + ID_PRODUCT_FROM_DATABASE=DS-XG PCI Audio CODEC + +pci:v00001073d00000010sv00001073sd00000010* + ID_PRODUCT_FROM_DATABASE=DS-XG PCI Audio CODEC + +pci:v00001073d00000012* + ID_PRODUCT_FROM_DATABASE=YMF-754 [DS-1E Audio Controller] + +pci:v00001073d00000012sv00001073sd00000012* + ID_PRODUCT_FROM_DATABASE=DS-XG PCI Audio Codec + +pci:v00001073d00000020* + ID_PRODUCT_FROM_DATABASE=DS-1 Audio + +pci:v00001073d00001000* + ID_PRODUCT_FROM_DATABASE=SW1000XG [XG Factory] + +pci:v00001073d00002000* + ID_PRODUCT_FROM_DATABASE=DS2416 Digital Mixing Card + +pci:v00001073d00002000sv00001073sd00002000* + ID_PRODUCT_FROM_DATABASE=DS2416 Digital Mixing Card + +pci:v00001074* + ID_VENDOR_FROM_DATABASE=NexGen Microsystems + +pci:v00001074d00004E78* + ID_PRODUCT_FROM_DATABASE=82c500/1 + +pci:v00001075* + ID_VENDOR_FROM_DATABASE=Advanced Integrations Research + +pci:v00001076* + ID_VENDOR_FROM_DATABASE=Chaintech Computer Co. Ltd + +pci:v00001077* + ID_VENDOR_FROM_DATABASE=QLogic Corp. + +pci:v00001077d00001016* + ID_PRODUCT_FROM_DATABASE=ISP10160 Single Channel Ultra3 SCSI Processor + +pci:v00001077d00001020* + ID_PRODUCT_FROM_DATABASE=ISP1020 Fast-wide SCSI + +pci:v00001077d00001022* + ID_PRODUCT_FROM_DATABASE=ISP1022 Fast-wide SCSI + +pci:v00001077d00001080* + ID_PRODUCT_FROM_DATABASE=ISP1080 SCSI Host Adapter + +pci:v00001077d00001216* + ID_PRODUCT_FROM_DATABASE=ISP12160 Dual Channel Ultra3 SCSI Processor + +pci:v00001077d00001216sv0000101Esd00008471* + ID_PRODUCT_FROM_DATABASE=QLA12160 on AMI MegaRAID + +pci:v00001077d00001216sv0000101Esd00008493* + ID_PRODUCT_FROM_DATABASE=QLA12160 on AMI MegaRAID + +pci:v00001077d00001240* + ID_PRODUCT_FROM_DATABASE=ISP1240 SCSI Host Adapter + +pci:v00001077d00001280* + ID_PRODUCT_FROM_DATABASE=ISP1280 SCSI Host Adapter + +pci:v00001077d00002020* + ID_PRODUCT_FROM_DATABASE=ISP2020A Fast!SCSI Basic Adapter + +pci:v00001077d00002100* + ID_PRODUCT_FROM_DATABASE=QLA2100 64-bit Fibre Channel Adapter + +pci:v00001077d00002100sv00001077sd00000001* + ID_PRODUCT_FROM_DATABASE=QLA2100 64-bit Fibre Channel Adapter + +pci:v00001077d00002200* + ID_PRODUCT_FROM_DATABASE=QLA2200 64-bit Fibre Channel Adapter + +pci:v00001077d00002200sv00001077sd00000002* + ID_PRODUCT_FROM_DATABASE=QLA2200 + +pci:v00001077d00002300* + ID_PRODUCT_FROM_DATABASE=QLA2300 64-bit Fibre Channel Adapter + +pci:v00001077d00002312* + ID_PRODUCT_FROM_DATABASE=ISP2312-based 2Gb Fibre Channel to PCI-X HBA + +pci:v00001077d00002312sv0000103Csd00000131* + ID_PRODUCT_FROM_DATABASE=2Gb Fibre Channel - Single port [A7538A] + +pci:v00001077d00002312sv0000103Csd000012BA* + ID_PRODUCT_FROM_DATABASE=2Gb Fibre Channel - Dual port [A6826A] + +pci:v00001077d00002322* + ID_PRODUCT_FROM_DATABASE=ISP2322-based 2Gb Fibre Channel to PCI-X HBA + +pci:v00001077d00002422* + ID_PRODUCT_FROM_DATABASE=ISP2422-based 4Gb Fibre Channel to PCI-X HBA + +pci:v00001077d00002422sv0000103Csd000012D7* + ID_PRODUCT_FROM_DATABASE=4Gb Fibre Channel [AB379A] + +pci:v00001077d00002422sv0000103Csd000012DD* + ID_PRODUCT_FROM_DATABASE=4Gb Fibre Channel [AB429A] + +pci:v00001077d00002432* + ID_PRODUCT_FROM_DATABASE=ISP2432-based 4Gb Fibre Channel to PCI Express HBA + +pci:v00001077d00002532* + ID_PRODUCT_FROM_DATABASE=ISP2532-based 8Gb Fibre Channel to PCI Express HBA + +pci:v00001077d00002532sv00001077sd00000167* + ID_PRODUCT_FROM_DATABASE=QME2572 Dual Port FC8 HBA Mezzanine + +pci:v00001077d00003022* + ID_PRODUCT_FROM_DATABASE=ISP4022-based Ethernet NIC + +pci:v00001077d00003032* + ID_PRODUCT_FROM_DATABASE=ISP4032-based Ethernet IPv6 NIC + +pci:v00001077d00004010* + ID_PRODUCT_FROM_DATABASE=ISP4010-based iSCSI TOE HBA + +pci:v00001077d00004022* + ID_PRODUCT_FROM_DATABASE=ISP4022-based iSCSI TOE HBA + +pci:v00001077d00004032* + ID_PRODUCT_FROM_DATABASE=ISP4032-based iSCSI TOE IPv6 HBA + +pci:v00001077d00005432* + ID_PRODUCT_FROM_DATABASE=SP232-based 4Gb Fibre Channel to PCI Express HBA + +pci:v00001077d00006312* + ID_PRODUCT_FROM_DATABASE=SP202-based 2Gb Fibre Channel to PCI-X HBA + +pci:v00001077d00006322* + ID_PRODUCT_FROM_DATABASE=SP212-based 2Gb Fibre Channel to PCI-X HBA + +pci:v00001077d00007220* + ID_PRODUCT_FROM_DATABASE=IBA7220 InfiniBand HCA + +pci:v00001077d00007322* + ID_PRODUCT_FROM_DATABASE=IBA7322 QDR InfiniBand HCA + +pci:v00001077d00008000* + ID_PRODUCT_FROM_DATABASE=10GbE Converged Network Adapter (TCP/IP Networking) + +pci:v00001077d00008001* + ID_PRODUCT_FROM_DATABASE=10GbE Converged Network Adapter (FCoE) + +pci:v00001077d00008020* + ID_PRODUCT_FROM_DATABASE=cLOM8214 1/10GbE Controller + +pci:v00001077d00008020sv0000103Csd00003346* + ID_PRODUCT_FROM_DATABASE=CN1000Q Dual Port Converged Network Adapter + +pci:v00001077d00008020sv0000103Csd00003733* + ID_PRODUCT_FROM_DATABASE=NC523SFP 10Gb 2-port Server Adapter + +pci:v00001077d00008020sv00001077sd00000203* + ID_PRODUCT_FROM_DATABASE=8200 Series Single Port 10GbE Converged Network Adapter (TCP/IP Networking) + +pci:v00001077d00008020sv00001077sd00000207* + ID_PRODUCT_FROM_DATABASE=8200 Series Dual Port 10GbE Converged Network Adapter (TCP/IP Networking) + +pci:v00001077d00008020sv00001077sd0000020B* + ID_PRODUCT_FROM_DATABASE=3200 Series Dual Port 10Gb Intelligent Ethernet Adapter + +pci:v00001077d00008020sv00001077sd0000020C* + ID_PRODUCT_FROM_DATABASE=3200 Series Quad Port 1Gb Intelligent Ethernet Adapter + +pci:v00001077d00008020sv00001077sd0000020F* + ID_PRODUCT_FROM_DATABASE=3200 Series Single Port 10Gb Intelligent Ethernet Adapter + +pci:v00001077d00008020sv00001077sd00000210* + ID_PRODUCT_FROM_DATABASE=QME8242-k 10GbE Dual Port Mezzanine Card + +pci:v00001077d00008021* + ID_PRODUCT_FROM_DATABASE=8200 Series 10GbE Converged Network Adapter (FCoE) + +pci:v00001077d00008021sv0000103Csd00003348* + ID_PRODUCT_FROM_DATABASE=CN1000Q Dual Port Converged Network Adapter + +pci:v00001077d00008021sv00001077sd00000211* + ID_PRODUCT_FROM_DATABASE=QME8242-k 10GbE Dual Port Mezzanine Card, FCoE + +pci:v00001077d00008022* + ID_PRODUCT_FROM_DATABASE=8200 Series 10GbE Converged Network Adapter (iSCSI) + +pci:v00001077d00008022sv0000103Csd00003347* + ID_PRODUCT_FROM_DATABASE=CN1000Q Dual Port Converged Network Adapter + +pci:v00001077d00008022sv00001077sd00000212* + ID_PRODUCT_FROM_DATABASE=QME8242-k 10GbE Dual Port Mezzanine Card, iSCSI + +pci:v00001077d00008432* + ID_PRODUCT_FROM_DATABASE=ISP2432M-based 10GbE Converged Network Adapter (CNA) + +pci:v00001078* + ID_VENDOR_FROM_DATABASE=Cyrix Corporation + +pci:v00001078d00000000* + ID_PRODUCT_FROM_DATABASE=5510 [Grappa] + +pci:v00001078d00000001* + ID_PRODUCT_FROM_DATABASE=PCI Master + +pci:v00001078d00000002* + ID_PRODUCT_FROM_DATABASE=5520 [Cognac] + +pci:v00001078d00000100* + ID_PRODUCT_FROM_DATABASE=5530 Legacy [Kahlua] + +pci:v00001078d00000101* + ID_PRODUCT_FROM_DATABASE=5530 SMI [Kahlua] + +pci:v00001078d00000102* + ID_PRODUCT_FROM_DATABASE=5530 IDE [Kahlua] + +pci:v00001078d00000103* + ID_PRODUCT_FROM_DATABASE=5530 Audio [Kahlua] + +pci:v00001078d00000104* + ID_PRODUCT_FROM_DATABASE=5530 Video [Kahlua] + +pci:v00001078d00000400* + ID_PRODUCT_FROM_DATABASE=ZFMicro PCI Bridge + +pci:v00001078d00000401* + ID_PRODUCT_FROM_DATABASE=ZFMicro Chipset SMI + +pci:v00001078d00000402* + ID_PRODUCT_FROM_DATABASE=ZFMicro Chipset IDE + +pci:v00001078d00000403* + ID_PRODUCT_FROM_DATABASE=ZFMicro Expansion Bus + +pci:v00001079* + ID_VENDOR_FROM_DATABASE=I-Bus + +pci:v0000107A* + ID_VENDOR_FROM_DATABASE=NetWorth + +pci:v0000107B* + ID_VENDOR_FROM_DATABASE=Gateway 2000 + +pci:v0000107C* + ID_VENDOR_FROM_DATABASE=LG Electronics [Lucky Goldstar Co. Ltd] + +pci:v0000107D* + ID_VENDOR_FROM_DATABASE=LeadTek Research Inc. + +pci:v0000107Dd00000000* + ID_PRODUCT_FROM_DATABASE=P86C850 + +pci:v0000107Dd00002134* + ID_PRODUCT_FROM_DATABASE=WinFast 3D S320 II + +pci:v0000107Dd00006609* + ID_PRODUCT_FROM_DATABASE=Winfast TV 2000 XP RM + +pci:v0000107Dd00006654* + ID_PRODUCT_FROM_DATABASE=Conexant CX23883 [WinFast DTV1800 H] + +pci:v0000107Dd00006F22* + ID_PRODUCT_FROM_DATABASE=WinFast PxTV1200 + +pci:v0000107Dd00006F34* + ID_PRODUCT_FROM_DATABASE=WinFast DVR3100 H + +pci:v0000107E* + ID_VENDOR_FROM_DATABASE=Interphase Corporation + +pci:v0000107Ed00000001* + ID_PRODUCT_FROM_DATABASE=5515 ATM Adapter [Flipper] + +pci:v0000107Ed00000002* + ID_PRODUCT_FROM_DATABASE=100 VG AnyLan Controller + +pci:v0000107Ed00000004* + ID_PRODUCT_FROM_DATABASE=5526 Fibre Channel Host Adapter + +pci:v0000107Ed00000005* + ID_PRODUCT_FROM_DATABASE=x526 Fibre Channel Host Adapter + +pci:v0000107Ed00000008* + ID_PRODUCT_FROM_DATABASE=5525/5575 ATM Adapter (155 Mbit) [Atlantic] + +pci:v0000107Ed00009003* + ID_PRODUCT_FROM_DATABASE=5535-4P-BRI-ST + +pci:v0000107Ed00009007* + ID_PRODUCT_FROM_DATABASE=5535-4P-BRI-U + +pci:v0000107Ed00009008* + ID_PRODUCT_FROM_DATABASE=5535-1P-SR + +pci:v0000107Ed0000900C* + ID_PRODUCT_FROM_DATABASE=5535-1P-SR-ST + +pci:v0000107Ed0000900E* + ID_PRODUCT_FROM_DATABASE=5535-1P-SR-U + +pci:v0000107Ed00009011* + ID_PRODUCT_FROM_DATABASE=5535-1P-PRI + +pci:v0000107Ed00009013* + ID_PRODUCT_FROM_DATABASE=5535-2P-PRI + +pci:v0000107Ed00009023* + ID_PRODUCT_FROM_DATABASE=5536-4P-BRI-ST + +pci:v0000107Ed00009027* + ID_PRODUCT_FROM_DATABASE=5536-4P-BRI-U + +pci:v0000107Ed00009031* + ID_PRODUCT_FROM_DATABASE=5536-1P-PRI + +pci:v0000107Ed00009033* + ID_PRODUCT_FROM_DATABASE=5536-2P-PRI + +pci:v0000107F* + ID_VENDOR_FROM_DATABASE=Data Technology Corporation + +pci:v0000107Fd00000802* + ID_PRODUCT_FROM_DATABASE=SL82C105 + +pci:v00001080* + ID_VENDOR_FROM_DATABASE=Contaq Microsystems + +pci:v00001080d00000600* + ID_PRODUCT_FROM_DATABASE=82C599 + +pci:v00001080d0000C691* + ID_PRODUCT_FROM_DATABASE=Cypress CY82C691 + +pci:v00001080d0000C693* + ID_PRODUCT_FROM_DATABASE=82c693 + +pci:v00001081* + ID_VENDOR_FROM_DATABASE=Supermac Technology + +pci:v00001081d00000D47* + ID_PRODUCT_FROM_DATABASE=Radius PCI to NuBUS Bridge + +pci:v00001082* + ID_VENDOR_FROM_DATABASE=EFA Corporation of America + +pci:v00001083* + ID_VENDOR_FROM_DATABASE=Forex Computer Corporation + +pci:v00001083d00000001* + ID_PRODUCT_FROM_DATABASE=FR710 + +pci:v00001084* + ID_VENDOR_FROM_DATABASE=Parador + +pci:v00001085* + ID_VENDOR_FROM_DATABASE=Tulip Computers Int.B.V. + +pci:v00001086* + ID_VENDOR_FROM_DATABASE=J. Bond Computer Systems + +pci:v00001087* + ID_VENDOR_FROM_DATABASE=Cache Computer + +pci:v00001088* + ID_VENDOR_FROM_DATABASE=Microcomputer Systems (M) Son + +pci:v00001089* + ID_VENDOR_FROM_DATABASE=Data General Corporation + +pci:v0000108A* + ID_VENDOR_FROM_DATABASE=SBS Technologies + +pci:v0000108Ad00000001* + ID_PRODUCT_FROM_DATABASE=VME Bridge Model 617 + +pci:v0000108Ad00000010* + ID_PRODUCT_FROM_DATABASE=VME Bridge Model 618 + +pci:v0000108Ad00000040* + ID_PRODUCT_FROM_DATABASE=dataBLIZZARD + +pci:v0000108Ad00003000* + ID_PRODUCT_FROM_DATABASE=VME Bridge Model 2706 + +pci:v0000108C* + ID_VENDOR_FROM_DATABASE=Oakleigh Systems Inc. + +pci:v0000108D* + ID_VENDOR_FROM_DATABASE=Olicom + +pci:v0000108Dd00000001* + ID_PRODUCT_FROM_DATABASE=Token-Ring 16/4 PCI Adapter (3136/3137) + +pci:v0000108Dd00000002* + ID_PRODUCT_FROM_DATABASE=16/4 Token Ring + +pci:v0000108Dd00000004* + ID_PRODUCT_FROM_DATABASE=RapidFire 3139 Token-Ring 16/4 PCI Adapter + +pci:v0000108Dd00000004sv0000108Dsd00000004* + ID_PRODUCT_FROM_DATABASE=OC-3139/3140 RapidFire Token-Ring 16/4 Adapter + +pci:v0000108Dd00000005* + ID_PRODUCT_FROM_DATABASE=GoCard 3250 Token-Ring 16/4 CardBus PC Card + +pci:v0000108Dd00000006* + ID_PRODUCT_FROM_DATABASE=OC-3530 RapidFire Token-Ring 100 + +pci:v0000108Dd00000007* + ID_PRODUCT_FROM_DATABASE=RapidFire 3141 Token-Ring 16/4 PCI Fiber Adapter + +pci:v0000108Dd00000007sv0000108Dsd00000007* + ID_PRODUCT_FROM_DATABASE=OC-3141 RapidFire Token-Ring 16/4 Adapter + +pci:v0000108Dd00000008* + ID_PRODUCT_FROM_DATABASE=RapidFire 3540 HSTR 100/16/4 PCI Adapter + +pci:v0000108Dd00000008sv0000108Dsd00000008* + ID_PRODUCT_FROM_DATABASE=OC-3540 RapidFire HSTR 100/16/4 Adapter + +pci:v0000108Dd00000011* + ID_PRODUCT_FROM_DATABASE=OC-2315 + +pci:v0000108Dd00000012* + ID_PRODUCT_FROM_DATABASE=OC-2325 + +pci:v0000108Dd00000013* + ID_PRODUCT_FROM_DATABASE=OC-2183/2185 + +pci:v0000108Dd00000014* + ID_PRODUCT_FROM_DATABASE=OC-2326 + +pci:v0000108Dd00000019* + ID_PRODUCT_FROM_DATABASE=OC-2327/2250 10/100 Ethernet Adapter + +pci:v0000108Dd00000019sv0000108Dsd00000016* + ID_PRODUCT_FROM_DATABASE=OC-2327 Rapidfire 10/100 Ethernet Adapter + +pci:v0000108Dd00000019sv0000108Dsd00000017* + ID_PRODUCT_FROM_DATABASE=OC-2250 GoCard 10/100 Ethernet Adapter + +pci:v0000108Dd00000021* + ID_PRODUCT_FROM_DATABASE=OC-6151/6152 [RapidFire ATM 155] + +pci:v0000108Dd00000022* + ID_PRODUCT_FROM_DATABASE=ATM Adapter + +pci:v0000108E* + ID_VENDOR_FROM_DATABASE=Oracle/SUN + +pci:v0000108Ed00000001* + ID_PRODUCT_FROM_DATABASE=EBUS + +pci:v0000108Ed00001000* + ID_PRODUCT_FROM_DATABASE=EBUS + +pci:v0000108Ed00001001* + ID_PRODUCT_FROM_DATABASE=Happy Meal 10/100 Ethernet [hme] + +pci:v0000108Ed00001100* + ID_PRODUCT_FROM_DATABASE=RIO EBUS + +pci:v0000108Ed00001100sv0000108Esd00001100* + ID_PRODUCT_FROM_DATABASE=RIO EBUS on Blade 100 motherboard + +pci:v0000108Ed00001101* + ID_PRODUCT_FROM_DATABASE=RIO 10/100 Ethernet [eri] + +pci:v0000108Ed00001101sv0000108Esd00001101* + ID_PRODUCT_FROM_DATABASE=RIO GEM on Blade 100 motherboard + +pci:v0000108Ed00001102* + ID_PRODUCT_FROM_DATABASE=RIO 1394 + +pci:v0000108Ed00001102sv0000108Esd00001102* + ID_PRODUCT_FROM_DATABASE=RIO 1394 on Blade 100 motherboard + +pci:v0000108Ed00001103* + ID_PRODUCT_FROM_DATABASE=RIO USB + +pci:v0000108Ed00001103sv0000108Esd00001103* + ID_PRODUCT_FROM_DATABASE=RIO USB on Blade 100 motherboard + +pci:v0000108Ed00001647* + ID_PRODUCT_FROM_DATABASE=Broadcom 570x 10/100/1000 Ethernet [bge] + +pci:v0000108Ed00001648* + ID_PRODUCT_FROM_DATABASE=Broadcom 570x 10/100/1000 Ethernet [bge] + +pci:v0000108Ed000016A7* + ID_PRODUCT_FROM_DATABASE=Broadcom 570x 10/100/1000 Ethernet [bge] + +pci:v0000108Ed000016A8* + ID_PRODUCT_FROM_DATABASE=Broadcom 570x 10/100/1000 Ethernet [bge] + +pci:v0000108Ed00002BAD* + ID_PRODUCT_FROM_DATABASE=GEM 10/100/1000 Ethernet [ge] + +pci:v0000108Ed00005000* + ID_PRODUCT_FROM_DATABASE=Simba Advanced PCI Bridge + +pci:v0000108Ed00005000sv0000108Esd00005000* + ID_PRODUCT_FROM_DATABASE=Netra AX1105-500 + +pci:v0000108Ed00005043* + ID_PRODUCT_FROM_DATABASE=SunPCI Co-processor + +pci:v0000108Ed00005CA0* + ID_PRODUCT_FROM_DATABASE=Crypto Accelerator 6000 [mca] + +pci:v0000108Ed00006300* + ID_PRODUCT_FROM_DATABASE=Intel 21554 PCI-PCI bus bridge [db21554] + +pci:v0000108Ed00006301* + ID_PRODUCT_FROM_DATABASE=Intel 21554 PCI-PCI bus bridge [db21554] + +pci:v0000108Ed00006302* + ID_PRODUCT_FROM_DATABASE=Intel 21554 PCI-PCI bus bridge [db21554] + +pci:v0000108Ed00006303* + ID_PRODUCT_FROM_DATABASE=Intel 21554 PCI-PCI bus bridge [db21554] + +pci:v0000108Ed00006310* + ID_PRODUCT_FROM_DATABASE=Intel 21554 PCI-PCI bus bridge [db21554] + +pci:v0000108Ed00006311* + ID_PRODUCT_FROM_DATABASE=Intel 21554 PCI-PCI bus bridge [db21554] + +pci:v0000108Ed00006312* + ID_PRODUCT_FROM_DATABASE=Intel 21554 PCI-PCI bus bridge [db21554] + +pci:v0000108Ed00006313* + ID_PRODUCT_FROM_DATABASE=Intel 21554 PCI-PCI bus bridge [db21554] + +pci:v0000108Ed00006320* + ID_PRODUCT_FROM_DATABASE=Intel 21554 PCI-PCI bus bridge [db21554] + +pci:v0000108Ed00006323* + ID_PRODUCT_FROM_DATABASE=Intel 21554 PCI-PCI bus bridge [db21554] + +pci:v0000108Ed00006330* + ID_PRODUCT_FROM_DATABASE=Intel 21554 PCI-PCI bus bridge [db21554] + +pci:v0000108Ed00006331* + ID_PRODUCT_FROM_DATABASE=Intel 21554 PCI-PCI bus bridge [db21554] + +pci:v0000108Ed00006332* + ID_PRODUCT_FROM_DATABASE=Intel 21554 PCI-PCI bus bridge [db21554] + +pci:v0000108Ed00006333* + ID_PRODUCT_FROM_DATABASE=Intel 21554 PCI-PCI bus bridge [db21554] + +pci:v0000108Ed00006340* + ID_PRODUCT_FROM_DATABASE=Intel 21554 PCI-PCI bus bridge [db21554] + +pci:v0000108Ed00006343* + ID_PRODUCT_FROM_DATABASE=Intel 21554 PCI-PCI bus bridge [db21554] + +pci:v0000108Ed00006350* + ID_PRODUCT_FROM_DATABASE=Intel 21554 PCI-PCI bus bridge [db21554] + +pci:v0000108Ed00006353* + ID_PRODUCT_FROM_DATABASE=Intel 21554 PCI-PCI bus bridge [db21554] + +pci:v0000108Ed00006722* + ID_PRODUCT_FROM_DATABASE=Intel 21554 PCI-PCI bus bridge [db21554] + +pci:v0000108Ed0000676E* + ID_PRODUCT_FROM_DATABASE=SunPCiIII + +pci:v0000108Ed00007063* + ID_PRODUCT_FROM_DATABASE=SunPCiII / SunPCiIIpro + +pci:v0000108Ed00008000* + ID_PRODUCT_FROM_DATABASE=Psycho PCI Bus Module + +pci:v0000108Ed00008001* + ID_PRODUCT_FROM_DATABASE=Schizo PCI Bus Module + +pci:v0000108Ed00008002* + ID_PRODUCT_FROM_DATABASE=Schizo+ PCI Bus Module + +pci:v0000108Ed000080F0* + ID_PRODUCT_FROM_DATABASE=PCIe switch [px] + +pci:v0000108Ed000080F8* + ID_PRODUCT_FROM_DATABASE=PCIe switch [px] + +pci:v0000108Ed00009010* + ID_PRODUCT_FROM_DATABASE=PCIe/PCI bridge switch [pxb_plx] + +pci:v0000108Ed00009020* + ID_PRODUCT_FROM_DATABASE=PCIe/PCI bridge switch [pxb_plx] + +pci:v0000108Ed00009102* + ID_PRODUCT_FROM_DATABASE=Davicom Fast Ethernet driver for Davicom DM9102A [dmfe] + +pci:v0000108Ed0000A000* + ID_PRODUCT_FROM_DATABASE=Psycho UPA-PCI Bus Module [pcipsy] + +pci:v0000108Ed0000A001* + ID_PRODUCT_FROM_DATABASE=Psycho UPA-PCI Bus Module [pcipsy] + +pci:v0000108Ed0000A001sv0000108Esd0000A001* + ID_PRODUCT_FROM_DATABASE=Ultra IIe on Blade 100 motherboard + +pci:v0000108Ed0000A801* + ID_PRODUCT_FROM_DATABASE=Schizo Fireplane-PCI bus bridge module [pcisch] + +pci:v0000108Ed0000AAAA* + ID_PRODUCT_FROM_DATABASE=Multithreaded Shared 10GbE Ethernet Network Controller + +pci:v0000108Ed0000ABBA* + ID_PRODUCT_FROM_DATABASE=Cassini 10/100/1000 + +pci:v0000108Ed0000ABCD* + ID_PRODUCT_FROM_DATABASE=Multithreaded 10-Gigabit Ethernet Network Controller + +pci:v0000108Ed0000C416* + ID_PRODUCT_FROM_DATABASE=Sun Fire System/System Controller Interface chip [sbbc] + +pci:v0000108F* + ID_VENDOR_FROM_DATABASE=Systemsoft + +pci:v00001090* + ID_VENDOR_FROM_DATABASE=Compro Computer Services, Inc. + +pci:v00001090d00004610* + ID_PRODUCT_FROM_DATABASE=PCI RTOM + +pci:v00001090d00004620* + ID_PRODUCT_FROM_DATABASE=GPIO HSD + +pci:v00001091* + ID_VENDOR_FROM_DATABASE=Intergraph Corporation + +pci:v00001091d00000020* + ID_PRODUCT_FROM_DATABASE=3D graphics processor + +pci:v00001091d00000021* + ID_PRODUCT_FROM_DATABASE=3D graphics processor w/Texturing + +pci:v00001091d00000040* + ID_PRODUCT_FROM_DATABASE=3D graphics frame buffer + +pci:v00001091d00000041* + ID_PRODUCT_FROM_DATABASE=3D graphics frame buffer + +pci:v00001091d00000060* + ID_PRODUCT_FROM_DATABASE=Proprietary bus bridge + +pci:v00001091d000000E4* + ID_PRODUCT_FROM_DATABASE=Powerstorm 4D50T + +pci:v00001091d00000720* + ID_PRODUCT_FROM_DATABASE=Motion JPEG codec + +pci:v00001091d00000780* + ID_PRODUCT_FROM_DATABASE=Intense3D Wildcat 3410 (MSMT496) + +pci:v00001091d000007A0* + ID_PRODUCT_FROM_DATABASE=Sun Expert3D-Lite Graphics Accelerator + +pci:v00001091d00001091* + ID_PRODUCT_FROM_DATABASE=Sun Expert3D Graphics Accelerator + +pci:v00001092* + ID_VENDOR_FROM_DATABASE=Diamond Multimedia Systems + +pci:v00001092d00000028* + ID_PRODUCT_FROM_DATABASE=Viper V770 + +pci:v00001092d00000028sv00001092sd00004A00* + ID_PRODUCT_FROM_DATABASE=Viper V770 32MB + +pci:v00001092d000000A0* + ID_PRODUCT_FROM_DATABASE=Speedstar Pro SE + +pci:v00001092d000000A8* + ID_PRODUCT_FROM_DATABASE=Speedstar 64 + +pci:v00001092d00000550* + ID_PRODUCT_FROM_DATABASE=Viper V550 + +pci:v00001092d000008D4* + ID_PRODUCT_FROM_DATABASE=Supra 2260 Modem + +pci:v00001092d0000094C* + ID_PRODUCT_FROM_DATABASE=SupraExpress 56i Pro + +pci:v00001092d00001001* + ID_PRODUCT_FROM_DATABASE=Video Crunch It 1001 capture card + +pci:v00001092d00001092* + ID_PRODUCT_FROM_DATABASE=Viper V330 + +pci:v00001092d00006120* + ID_PRODUCT_FROM_DATABASE=Maximum DVD + +pci:v00001092d00008810* + ID_PRODUCT_FROM_DATABASE=Stealth SE + +pci:v00001092d00008811* + ID_PRODUCT_FROM_DATABASE=Stealth 64/SE + +pci:v00001092d00008880* + ID_PRODUCT_FROM_DATABASE=Stealth + +pci:v00001092d00008881* + ID_PRODUCT_FROM_DATABASE=Stealth + +pci:v00001092d000088B0* + ID_PRODUCT_FROM_DATABASE=Stealth 64 + +pci:v00001092d000088B1* + ID_PRODUCT_FROM_DATABASE=Stealth 64 + +pci:v00001092d000088C0* + ID_PRODUCT_FROM_DATABASE=Stealth 64 + +pci:v00001092d000088C1* + ID_PRODUCT_FROM_DATABASE=Stealth 64 + +pci:v00001092d000088D0* + ID_PRODUCT_FROM_DATABASE=Stealth 64 + +pci:v00001092d000088D1* + ID_PRODUCT_FROM_DATABASE=Stealth 64 + +pci:v00001092d000088F0* + ID_PRODUCT_FROM_DATABASE=Stealth 64 + +pci:v00001092d000088F1* + ID_PRODUCT_FROM_DATABASE=Stealth 64 + +pci:v00001092d00009999* + ID_PRODUCT_FROM_DATABASE=DMD-I0928-1 "Monster sound" sound chip + +pci:v00001093* + ID_VENDOR_FROM_DATABASE=National Instruments + +pci:v00001093d00000160* + ID_PRODUCT_FROM_DATABASE=PCI-DIO-96 + +pci:v00001093d00000162* + ID_PRODUCT_FROM_DATABASE=PCI-MIO-16XE-50 + +pci:v00001093d00001150* + ID_PRODUCT_FROM_DATABASE=PCI-DIO-32HS High Speed Digital I/O Board + +pci:v00001093d00001170* + ID_PRODUCT_FROM_DATABASE=PCI-MIO-16XE-10 + +pci:v00001093d00001180* + ID_PRODUCT_FROM_DATABASE=PCI-MIO-16E-1 + +pci:v00001093d00001190* + ID_PRODUCT_FROM_DATABASE=PCI-MIO-16E-4 + +pci:v00001093d000011B0* + ID_PRODUCT_FROM_DATABASE=PXI-6070E + +pci:v00001093d000011C0* + ID_PRODUCT_FROM_DATABASE=PXI-6040e + +pci:v00001093d000011D0* + ID_PRODUCT_FROM_DATABASE=PXI-6030e + +pci:v00001093d00001270* + ID_PRODUCT_FROM_DATABASE=PCI-6032e + +pci:v00001093d00001310* + ID_PRODUCT_FROM_DATABASE=PCI-6602 + +pci:v00001093d00001330* + ID_PRODUCT_FROM_DATABASE=PCI-6031E + +pci:v00001093d00001340* + ID_PRODUCT_FROM_DATABASE=PCI-6033e + +pci:v00001093d00001350* + ID_PRODUCT_FROM_DATABASE=PCI-6071E + +pci:v00001093d00001360* + ID_PRODUCT_FROM_DATABASE=PXI-6602 + +pci:v00001093d000014E0* + ID_PRODUCT_FROM_DATABASE=PCI-6110 + +pci:v00001093d000014F0* + ID_PRODUCT_FROM_DATABASE=PCI-6111 + +pci:v00001093d00001580* + ID_PRODUCT_FROM_DATABASE=PXI-6031E + +pci:v00001093d000015B0* + ID_PRODUCT_FROM_DATABASE=PXI-6071E + +pci:v00001093d00001710* + ID_PRODUCT_FROM_DATABASE=PXI-6509 + +pci:v00001093d000017D0* + ID_PRODUCT_FROM_DATABASE=PCI-6503 + +pci:v00001093d00001870* + ID_PRODUCT_FROM_DATABASE=PCI-6713 + +pci:v00001093d00001880* + ID_PRODUCT_FROM_DATABASE=PCI-6711 + +pci:v00001093d000018B0* + ID_PRODUCT_FROM_DATABASE=PCI-6052E + +pci:v00001093d000018C0* + ID_PRODUCT_FROM_DATABASE=PXI-6052E + +pci:v00001093d00002410* + ID_PRODUCT_FROM_DATABASE=PCI-6733 + +pci:v00001093d00002420* + ID_PRODUCT_FROM_DATABASE=PXI-6733 + +pci:v00001093d00002430* + ID_PRODUCT_FROM_DATABASE=PCI-6731 + +pci:v00001093d00002880* + ID_PRODUCT_FROM_DATABASE=DAQCard-6601 + +pci:v00001093d00002890* + ID_PRODUCT_FROM_DATABASE=PCI-6036E + +pci:v00001093d000028C0* + ID_PRODUCT_FROM_DATABASE=PCI-6014 + +pci:v00001093d00002A60* + ID_PRODUCT_FROM_DATABASE=PCI-6023E + +pci:v00001093d00002A70* + ID_PRODUCT_FROM_DATABASE=PCI-6024E + +pci:v00001093d00002A80* + ID_PRODUCT_FROM_DATABASE=PCI-6025E + +pci:v00001093d00002AB0* + ID_PRODUCT_FROM_DATABASE=PXI-6025e + +pci:v00001093d00002B80* + ID_PRODUCT_FROM_DATABASE=PXI-6713 + +pci:v00001093d00002B90* + ID_PRODUCT_FROM_DATABASE=PXI-6711 + +pci:v00001093d00002C60* + ID_PRODUCT_FROM_DATABASE=PCI-6601 + +pci:v00001093d00002C70* + ID_PRODUCT_FROM_DATABASE=PXI-6601 + +pci:v00001093d00002C80* + ID_PRODUCT_FROM_DATABASE=PCI-6035E + +pci:v00001093d00002CA0* + ID_PRODUCT_FROM_DATABASE=PCI-6034E + +pci:v00001093d00002CC0* + ID_PRODUCT_FROM_DATABASE=PXI-6608 + +pci:v00001093d00002DB0* + ID_PRODUCT_FROM_DATABASE=PCI-6608 + +pci:v00001093d000070A9* + ID_PRODUCT_FROM_DATABASE=PCI-6528 (Digital I/O at 60V) + +pci:v00001093d000070AA* + ID_PRODUCT_FROM_DATABASE=PCI-6229 + +pci:v00001093d000070AB* + ID_PRODUCT_FROM_DATABASE=PCI-6259 + +pci:v00001093d000070AC* + ID_PRODUCT_FROM_DATABASE=PCI-6289 + +pci:v00001093d000070AE* + ID_PRODUCT_FROM_DATABASE=PXI-6220 + +pci:v00001093d000070AF* + ID_PRODUCT_FROM_DATABASE=PCI-6221 + +pci:v00001093d000070B0* + ID_PRODUCT_FROM_DATABASE=PCI-6220 + +pci:v00001093d000070B4* + ID_PRODUCT_FROM_DATABASE=PCI-6250 + +pci:v00001093d000070B6* + ID_PRODUCT_FROM_DATABASE=PCI-6280 + +pci:v00001093d000070B7* + ID_PRODUCT_FROM_DATABASE=PCI-6254 + +pci:v00001093d000070B8* + ID_PRODUCT_FROM_DATABASE=PCI-6251 [M Series - High Speed Multifunction DAQ] + +pci:v00001093d000070BC* + ID_PRODUCT_FROM_DATABASE=PCI-6284 + +pci:v00001093d000070BD* + ID_PRODUCT_FROM_DATABASE=PCI-6281 + +pci:v00001093d000070BF* + ID_PRODUCT_FROM_DATABASE=PXI-6281 + +pci:v00001093d000070C0* + ID_PRODUCT_FROM_DATABASE=PCI-6143 + +pci:v00001093d000070F2* + ID_PRODUCT_FROM_DATABASE=PCI-6224 + +pci:v00001093d00007144* + ID_PRODUCT_FROM_DATABASE=PXI-5124 (12-bit 200 MS/s Digitizer) + +pci:v00001093d0000716C* + ID_PRODUCT_FROM_DATABASE=PCI-6225 + +pci:v00001093d0000717D* + ID_PRODUCT_FROM_DATABASE=PCIE-6251 + +pci:v00001093d0000717F* + ID_PRODUCT_FROM_DATABASE=PCIe-6259 + +pci:v00001093d000071BC* + ID_PRODUCT_FROM_DATABASE=PCI-6221 (37pin) + +pci:v00001093d000071D0* + ID_PRODUCT_FROM_DATABASE=PXI-6143 + +pci:v00001093d0000B001* + ID_PRODUCT_FROM_DATABASE=IMAQ-PCI-1408 + +pci:v00001093d0000B011* + ID_PRODUCT_FROM_DATABASE=IMAQ-PXI-1408 + +pci:v00001093d0000B021* + ID_PRODUCT_FROM_DATABASE=IMAQ-PCI-1424 + +pci:v00001093d0000B031* + ID_PRODUCT_FROM_DATABASE=IMAQ-PCI-1413 + +pci:v00001093d0000B041* + ID_PRODUCT_FROM_DATABASE=IMAQ-PCI-1407 + +pci:v00001093d0000B051* + ID_PRODUCT_FROM_DATABASE=IMAQ-PXI-1407 + +pci:v00001093d0000B061* + ID_PRODUCT_FROM_DATABASE=IMAQ-PCI-1411 + +pci:v00001093d0000B071* + ID_PRODUCT_FROM_DATABASE=IMAQ-PCI-1422 + +pci:v00001093d0000B081* + ID_PRODUCT_FROM_DATABASE=IMAQ-PXI-1422 + +pci:v00001093d0000B091* + ID_PRODUCT_FROM_DATABASE=IMAQ-PXI-1411 + +pci:v00001093d0000C4C4* + ID_PRODUCT_FROM_DATABASE=PXIe-4353 + +pci:v00001093d0000C801* + ID_PRODUCT_FROM_DATABASE=PCI-GPIB + +pci:v00001093d0000C831* + ID_PRODUCT_FROM_DATABASE=PCI-GPIB bridge + +pci:v00001094* + ID_VENDOR_FROM_DATABASE=First International Computers [FIC] + +pci:v00001095* + ID_VENDOR_FROM_DATABASE=Silicon Image, Inc. + +pci:v00001095d00000240* + ID_PRODUCT_FROM_DATABASE=Adaptec AAR-1210SA SATA HostRAID Controller + +pci:v00001095d00000640* + ID_PRODUCT_FROM_DATABASE=PCI0640 + +pci:v00001095d00000643* + ID_PRODUCT_FROM_DATABASE=PCI0643 + +pci:v00001095d00000646* + ID_PRODUCT_FROM_DATABASE=PCI0646 + +pci:v00001095d00000647* + ID_PRODUCT_FROM_DATABASE=PCI0647 + +pci:v00001095d00000648* + ID_PRODUCT_FROM_DATABASE=PCI0648 + +pci:v00001095d00000648sv00001043sd00008025* + ID_PRODUCT_FROM_DATABASE=CUBX motherboard + +pci:v00001095d00000649* + ID_PRODUCT_FROM_DATABASE=SiI 0649 Ultra ATA/100 PCI to ATA Host Controller + +pci:v00001095d00000649sv00000E11sd0000005D* + ID_PRODUCT_FROM_DATABASE=Integrated Ultra ATA-100 Dual Channel Controller + +pci:v00001095d00000649sv00000E11sd0000007E* + ID_PRODUCT_FROM_DATABASE=Integrated Ultra ATA-100 IDE RAID Controller + +pci:v00001095d00000649sv0000101Esd00000649* + ID_PRODUCT_FROM_DATABASE=AMI MegaRAID IDE 100 Controller + +pci:v00001095d00000650* + ID_PRODUCT_FROM_DATABASE=PBC0650A + +pci:v00001095d00000670* + ID_PRODUCT_FROM_DATABASE=USB0670 + +pci:v00001095d00000670sv00001095sd00000670* + ID_PRODUCT_FROM_DATABASE=USB0670 + +pci:v00001095d00000673* + ID_PRODUCT_FROM_DATABASE=USB0673 + +pci:v00001095d00000680* + ID_PRODUCT_FROM_DATABASE=PCI0680 Ultra ATA-133 Host Controller + +pci:v00001095d00000680sv00001095sd00000680* + ID_PRODUCT_FROM_DATABASE=SiI 0680 ATA/133 Controller + +pci:v00001095d00000680sv00001095sd00003680* + ID_PRODUCT_FROM_DATABASE=Winic W-680 (Silicon Image 680 based) + +pci:v00001095d00003112* + ID_PRODUCT_FROM_DATABASE=SiI 3112 [SATALink/SATARaid] Serial ATA Controller + +pci:v00001095d00003112sv00001095sd00003112* + ID_PRODUCT_FROM_DATABASE=SiI 3112 SATALink Controller + +pci:v00001095d00003112sv00001095sd00006112* + ID_PRODUCT_FROM_DATABASE=SiI 3112 SATARaid Controller + +pci:v00001095d00003112sv00009005sd00000250* + ID_PRODUCT_FROM_DATABASE=SATAConnect 1205SA Host Controller + +pci:v00001095d00003114* + ID_PRODUCT_FROM_DATABASE=SiI 3114 [SATALink/SATARaid] Serial ATA Controller + +pci:v00001095d00003114sv00001095sd00003114* + ID_PRODUCT_FROM_DATABASE=SiI 3114 SATALink Controller + +pci:v00001095d00003114sv00001095sd00006114* + ID_PRODUCT_FROM_DATABASE=SiI 3114 SATARaid Controller + +pci:v00001095d00003124* + ID_PRODUCT_FROM_DATABASE=SiI 3124 PCI-X Serial ATA Controller + +pci:v00001095d00003124sv00001095sd00003124* + ID_PRODUCT_FROM_DATABASE=SiI 3124 PCI-X Serial ATA Controller + +pci:v00001095d00003132* + ID_PRODUCT_FROM_DATABASE=SiI 3132 Serial ATA Raid II Controller + +pci:v00001095d00003512* + ID_PRODUCT_FROM_DATABASE=SiI 3512 [SATALink/SATARaid] Serial ATA Controller + +pci:v00001095d00003512sv00001095sd00003512* + ID_PRODUCT_FROM_DATABASE=SiI 3512 SATALink Controller + +pci:v00001095d00003512sv00001095sd00006512* + ID_PRODUCT_FROM_DATABASE=SiI 3512 SATARaid Controller + +pci:v00001095d00003531* + ID_PRODUCT_FROM_DATABASE=SiI 3531 [SATALink/SATARaid] Serial ATA Controller + +pci:v00001096* + ID_VENDOR_FROM_DATABASE=Alacron + +pci:v00001097* + ID_VENDOR_FROM_DATABASE=Appian Technology + +pci:v00001098* + ID_VENDOR_FROM_DATABASE=Quantum Designs (H.K.) Ltd + +pci:v00001098d00000001* + ID_PRODUCT_FROM_DATABASE=QD-8500 + +pci:v00001098d00000002* + ID_PRODUCT_FROM_DATABASE=QD-8580 + +pci:v00001099* + ID_VENDOR_FROM_DATABASE=Samsung Electronics Co., Ltd + +pci:v0000109A* + ID_VENDOR_FROM_DATABASE=Packard Bell + +pci:v0000109B* + ID_VENDOR_FROM_DATABASE=Gemlight Computer Ltd. + +pci:v0000109C* + ID_VENDOR_FROM_DATABASE=Megachips Corporation + +pci:v0000109D* + ID_VENDOR_FROM_DATABASE=Zida Technologies Ltd. + +pci:v0000109E* + ID_VENDOR_FROM_DATABASE=Brooktree Corporation + +pci:v0000109Ed00000310* + ID_PRODUCT_FROM_DATABASE=Bt848 Video Capture + +pci:v0000109Ed0000032E* + ID_PRODUCT_FROM_DATABASE=Bt878 Video Capture + +pci:v0000109Ed00000350* + ID_PRODUCT_FROM_DATABASE=Bt848 Video Capture + +pci:v0000109Ed00000351* + ID_PRODUCT_FROM_DATABASE=Bt849A Video capture + +pci:v0000109Ed00000369* + ID_PRODUCT_FROM_DATABASE=Bt878 Video Capture + +pci:v0000109Ed00000369sv00001002sd00000001* + ID_PRODUCT_FROM_DATABASE=TV-Wonder + +pci:v0000109Ed00000369sv00001002sd00000003* + ID_PRODUCT_FROM_DATABASE=TV-Wonder/VE + +pci:v0000109Ed0000036C* + ID_PRODUCT_FROM_DATABASE=Bt879(??) Video Capture + +pci:v0000109Ed0000036Csv000013E9sd00000070* + ID_PRODUCT_FROM_DATABASE=Win/TV (Video Section) + +pci:v0000109Ed0000036E* + ID_PRODUCT_FROM_DATABASE=Bt878 Video Capture + +pci:v0000109Ed0000036Esv00000070sd000013EB* + ID_PRODUCT_FROM_DATABASE=WinTV Series + +pci:v0000109Ed0000036Esv00000070sd0000FF01* + ID_PRODUCT_FROM_DATABASE=Viewcast Osprey 200 + +pci:v0000109Ed0000036Esv00000071sd00000101* + ID_PRODUCT_FROM_DATABASE=DigiTV PCI + +pci:v0000109Ed0000036Esv0000107Dsd00006606* + ID_PRODUCT_FROM_DATABASE=WinFast TV 2000 + +pci:v0000109Ed0000036Esv000011BDsd00000012* + ID_PRODUCT_FROM_DATABASE=PCTV pro (TV + FM stereo receiver) + +pci:v0000109Ed0000036Esv000011BDsd0000001C* + ID_PRODUCT_FROM_DATABASE=PCTV Sat (DBC receiver) + +pci:v0000109Ed0000036Esv0000127Asd00000001* + ID_PRODUCT_FROM_DATABASE=Bt878 Mediastream Controller NTSC + +pci:v0000109Ed0000036Esv0000127Asd00000002* + ID_PRODUCT_FROM_DATABASE=Bt878 Mediastream Controller PAL BG + +pci:v0000109Ed0000036Esv0000127Asd00000003* + ID_PRODUCT_FROM_DATABASE=Bt878a Mediastream Controller PAL BG + +pci:v0000109Ed0000036Esv0000127Asd00000048* + ID_PRODUCT_FROM_DATABASE=Bt878/832 Mediastream Controller + +pci:v0000109Ed0000036Esv0000144Fsd00003000* + ID_PRODUCT_FROM_DATABASE=MagicTView CPH060 - Video + +pci:v0000109Ed0000036Esv00001461sd00000002* + ID_PRODUCT_FROM_DATABASE=TV98 Series (TV/No FM/Remote) + +pci:v0000109Ed0000036Esv00001461sd00000003* + ID_PRODUCT_FROM_DATABASE=AverMedia UltraTV PCI 350 + +pci:v0000109Ed0000036Esv00001461sd00000004* + ID_PRODUCT_FROM_DATABASE=AVerTV WDM Video Capture + +pci:v0000109Ed0000036Esv00001461sd00000761* + ID_PRODUCT_FROM_DATABASE=AverTV DVB-T + +pci:v0000109Ed0000036Esv00001461sd00000771* + ID_PRODUCT_FROM_DATABASE=AverMedia AVerTV DVB-T 771 + +pci:v0000109Ed0000036Esv000014F1sd00000001* + ID_PRODUCT_FROM_DATABASE=Bt878 Mediastream Controller NTSC + +pci:v0000109Ed0000036Esv000014F1sd00000002* + ID_PRODUCT_FROM_DATABASE=Bt878 Mediastream Controller PAL BG + +pci:v0000109Ed0000036Esv000014F1sd00000003* + ID_PRODUCT_FROM_DATABASE=Bt878a Mediastream Controller PAL BG + +pci:v0000109Ed0000036Esv000014F1sd00000048* + ID_PRODUCT_FROM_DATABASE=Bt878/832 Mediastream Controller + +pci:v0000109Ed0000036Esv00001822sd00000001* + ID_PRODUCT_FROM_DATABASE=VisionPlus DVB card + +pci:v0000109Ed0000036Esv00001851sd00001850* + ID_PRODUCT_FROM_DATABASE=FlyVideo'98 - Video + +pci:v0000109Ed0000036Esv00001851sd00001851* + ID_PRODUCT_FROM_DATABASE=FlyVideo II + +pci:v0000109Ed0000036Esv00001852sd00001852* + ID_PRODUCT_FROM_DATABASE=FlyVideo'98 - Video (with FM Tuner) + +pci:v0000109Ed0000036Esv000018ACsd0000D500* + ID_PRODUCT_FROM_DATABASE=DViCO FusionHDTV5 Lite + +pci:v0000109Ed0000036Esv0000270Fsd0000FC00* + ID_PRODUCT_FROM_DATABASE=Digitop DTT-1000 + +pci:v0000109Ed0000036Esv0000BD11sd00001200* + ID_PRODUCT_FROM_DATABASE=PCTV pro (TV + FM stereo receiver) + +pci:v0000109Ed0000036F* + ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture + +pci:v0000109Ed0000036Fsv0000127Asd00000044* + ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture NTSC + +pci:v0000109Ed0000036Fsv0000127Asd00000122* + ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture PAL I + +pci:v0000109Ed0000036Fsv0000127Asd00000144* + ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture NTSC + +pci:v0000109Ed0000036Fsv0000127Asd00000222* + ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture PAL BG + +pci:v0000109Ed0000036Fsv0000127Asd00000244* + ID_PRODUCT_FROM_DATABASE=Bt879a Video Capture NTSC + +pci:v0000109Ed0000036Fsv0000127Asd00000322* + ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture NTSC + +pci:v0000109Ed0000036Fsv0000127Asd00000422* + ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture NTSC + +pci:v0000109Ed0000036Fsv0000127Asd00001122* + ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture PAL I + +pci:v0000109Ed0000036Fsv0000127Asd00001222* + ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture PAL BG + +pci:v0000109Ed0000036Fsv0000127Asd00001322* + ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture NTSC + +pci:v0000109Ed0000036Fsv0000127Asd00001522* + ID_PRODUCT_FROM_DATABASE=Bt879a Video Capture PAL I + +pci:v0000109Ed0000036Fsv0000127Asd00001622* + ID_PRODUCT_FROM_DATABASE=Bt879a Video Capture PAL BG + +pci:v0000109Ed0000036Fsv0000127Asd00001722* + ID_PRODUCT_FROM_DATABASE=Bt879a Video Capture NTSC + +pci:v0000109Ed0000036Fsv000014F1sd00000044* + ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture NTSC + +pci:v0000109Ed0000036Fsv000014F1sd00000122* + ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture PAL I + +pci:v0000109Ed0000036Fsv000014F1sd00000144* + ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture NTSC + +pci:v0000109Ed0000036Fsv000014F1sd00000222* + ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture PAL BG + +pci:v0000109Ed0000036Fsv000014F1sd00000244* + ID_PRODUCT_FROM_DATABASE=Bt879a Video Capture NTSC + +pci:v0000109Ed0000036Fsv000014F1sd00000322* + ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture NTSC + +pci:v0000109Ed0000036Fsv000014F1sd00000422* + ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture NTSC + +pci:v0000109Ed0000036Fsv000014F1sd00001122* + ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture PAL I + +pci:v0000109Ed0000036Fsv000014F1sd00001222* + ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture PAL BG + +pci:v0000109Ed0000036Fsv000014F1sd00001322* + ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture NTSC + +pci:v0000109Ed0000036Fsv000014F1sd00001522* + ID_PRODUCT_FROM_DATABASE=Bt879a Video Capture PAL I + +pci:v0000109Ed0000036Fsv000014F1sd00001622* + ID_PRODUCT_FROM_DATABASE=Bt879a Video Capture PAL BG + +pci:v0000109Ed0000036Fsv000014F1sd00001722* + ID_PRODUCT_FROM_DATABASE=Bt879a Video Capture NTSC + +pci:v0000109Ed0000036Fsv00001851sd00001850* + ID_PRODUCT_FROM_DATABASE=FlyVideo'98 - Video + +pci:v0000109Ed0000036Fsv00001851sd00001851* + ID_PRODUCT_FROM_DATABASE=FlyVideo II + +pci:v0000109Ed0000036Fsv00001852sd00001852* + ID_PRODUCT_FROM_DATABASE=FlyVideo'98 - Video (with FM Tuner) + +pci:v0000109Ed00000370* + ID_PRODUCT_FROM_DATABASE=Bt880 Video Capture + +pci:v0000109Ed00000370sv00001851sd00001850* + ID_PRODUCT_FROM_DATABASE=FlyVideo'98 + +pci:v0000109Ed00000370sv00001851sd00001851* + ID_PRODUCT_FROM_DATABASE=FlyVideo'98 EZ - video + +pci:v0000109Ed00000370sv00001852sd00001852* + ID_PRODUCT_FROM_DATABASE=FlyVideo'98 (with FM Tuner) + +pci:v0000109Ed00000878* + ID_PRODUCT_FROM_DATABASE=Bt878 Audio Capture + +pci:v0000109Ed00000878sv00000070sd000013EB* + ID_PRODUCT_FROM_DATABASE=WinTV Series + +pci:v0000109Ed00000878sv00000070sd0000FF01* + ID_PRODUCT_FROM_DATABASE=Viewcast Osprey 200 + +pci:v0000109Ed00000878sv00000071sd00000101* + ID_PRODUCT_FROM_DATABASE=DigiTV PCI + +pci:v0000109Ed00000878sv00001002sd00000001* + ID_PRODUCT_FROM_DATABASE=TV-Wonder + +pci:v0000109Ed00000878sv00001002sd00000003* + ID_PRODUCT_FROM_DATABASE=TV-Wonder/VE + +pci:v0000109Ed00000878sv000011BDsd00000012* + ID_PRODUCT_FROM_DATABASE=PCTV pro (TV + FM stereo receiver, audio section) + +pci:v0000109Ed00000878sv000011BDsd0000001C* + ID_PRODUCT_FROM_DATABASE=PCTV Sat (DBC receiver) + +pci:v0000109Ed00000878sv0000127Asd00000001* + ID_PRODUCT_FROM_DATABASE=Bt878 Video Capture (Audio Section) + +pci:v0000109Ed00000878sv0000127Asd00000002* + ID_PRODUCT_FROM_DATABASE=Bt878 Video Capture (Audio Section) + +pci:v0000109Ed00000878sv0000127Asd00000003* + ID_PRODUCT_FROM_DATABASE=Bt878 Video Capture (Audio Section) + +pci:v0000109Ed00000878sv0000127Asd00000048* + ID_PRODUCT_FROM_DATABASE=Bt878 Video Capture (Audio Section) + +pci:v0000109Ed00000878sv000013E9sd00000070* + ID_PRODUCT_FROM_DATABASE=Win/TV (Audio Section) + +pci:v0000109Ed00000878sv0000144Fsd00003000* + ID_PRODUCT_FROM_DATABASE=MagicTView CPH060 - Audio + +pci:v0000109Ed00000878sv00001461sd00000002* + ID_PRODUCT_FROM_DATABASE=Avermedia PCTV98 Audio Capture + +pci:v0000109Ed00000878sv00001461sd00000003* + ID_PRODUCT_FROM_DATABASE=UltraTV PCI 350 + +pci:v0000109Ed00000878sv00001461sd00000004* + ID_PRODUCT_FROM_DATABASE=AVerTV WDM Audio Capture + +pci:v0000109Ed00000878sv00001461sd00000761* + ID_PRODUCT_FROM_DATABASE=AVerTV DVB-T + +pci:v0000109Ed00000878sv00001461sd00000771* + ID_PRODUCT_FROM_DATABASE=AverMedia AVerTV DVB-T 771 + +pci:v0000109Ed00000878sv000014F1sd00000001* + ID_PRODUCT_FROM_DATABASE=Bt878 Video Capture (Audio Section) + +pci:v0000109Ed00000878sv000014F1sd00000002* + ID_PRODUCT_FROM_DATABASE=Bt878 Video Capture (Audio Section) + +pci:v0000109Ed00000878sv000014F1sd00000003* + ID_PRODUCT_FROM_DATABASE=Bt878 Video Capture (Audio Section) + +pci:v0000109Ed00000878sv000014F1sd00000048* + ID_PRODUCT_FROM_DATABASE=Bt878 Video Capture (Audio Section) + +pci:v0000109Ed00000878sv00001822sd00000001* + ID_PRODUCT_FROM_DATABASE=VisionPlus DVB Card + +pci:v0000109Ed00000878sv000018ACsd0000D500* + ID_PRODUCT_FROM_DATABASE=DViCO FusionHDTV5 Lite + +pci:v0000109Ed00000878sv0000270Fsd0000FC00* + ID_PRODUCT_FROM_DATABASE=Digitop DTT-1000 + +pci:v0000109Ed00000878sv0000BD11sd00001200* + ID_PRODUCT_FROM_DATABASE=PCTV pro (TV + FM stereo receiver, audio section) + +pci:v0000109Ed00000879* + ID_PRODUCT_FROM_DATABASE=Bt879 Audio Capture + +pci:v0000109Ed00000879sv0000127Asd00000044* + ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture (Audio Section) + +pci:v0000109Ed00000879sv0000127Asd00000122* + ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture (Audio Section) + +pci:v0000109Ed00000879sv0000127Asd00000144* + ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture (Audio Section) + +pci:v0000109Ed00000879sv0000127Asd00000222* + ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture (Audio Section) + +pci:v0000109Ed00000879sv0000127Asd00000244* + ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture (Audio Section) + +pci:v0000109Ed00000879sv0000127Asd00000322* + ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture (Audio Section) + +pci:v0000109Ed00000879sv0000127Asd00000422* + ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture (Audio Section) + +pci:v0000109Ed00000879sv0000127Asd00001122* + ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture (Audio Section) + +pci:v0000109Ed00000879sv0000127Asd00001222* + ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture (Audio Section) + +pci:v0000109Ed00000879sv0000127Asd00001322* + ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture (Audio Section) + +pci:v0000109Ed00000879sv0000127Asd00001522* + ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture (Audio Section) + +pci:v0000109Ed00000879sv0000127Asd00001622* + ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture (Audio Section) + +pci:v0000109Ed00000879sv0000127Asd00001722* + ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture (Audio Section) + +pci:v0000109Ed00000879sv000014F1sd00000044* + ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture (Audio Section) + +pci:v0000109Ed00000879sv000014F1sd00000122* + ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture (Audio Section) + +pci:v0000109Ed00000879sv000014F1sd00000144* + ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture (Audio Section) + +pci:v0000109Ed00000879sv000014F1sd00000222* + ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture (Audio Section) + +pci:v0000109Ed00000879sv000014F1sd00000244* + ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture (Audio Section) + +pci:v0000109Ed00000879sv000014F1sd00000322* + ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture (Audio Section) + +pci:v0000109Ed00000879sv000014F1sd00000422* + ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture (Audio Section) + +pci:v0000109Ed00000879sv000014F1sd00001122* + ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture (Audio Section) + +pci:v0000109Ed00000879sv000014F1sd00001222* + ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture (Audio Section) + +pci:v0000109Ed00000879sv000014F1sd00001322* + ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture (Audio Section) + +pci:v0000109Ed00000879sv000014F1sd00001522* + ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture (Audio Section) + +pci:v0000109Ed00000879sv000014F1sd00001622* + ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture (Audio Section) + +pci:v0000109Ed00000879sv000014F1sd00001722* + ID_PRODUCT_FROM_DATABASE=Bt879 Video Capture (Audio Section) + +pci:v0000109Ed00000880* + ID_PRODUCT_FROM_DATABASE=Bt880 Audio Capture + +pci:v0000109Ed00002115* + ID_PRODUCT_FROM_DATABASE=BtV 2115 Mediastream controller + +pci:v0000109Ed00002125* + ID_PRODUCT_FROM_DATABASE=BtV 2125 Mediastream controller + +pci:v0000109Ed00002164* + ID_PRODUCT_FROM_DATABASE=BtV 2164 + +pci:v0000109Ed00002165* + ID_PRODUCT_FROM_DATABASE=BtV 2165 + +pci:v0000109Ed00008230* + ID_PRODUCT_FROM_DATABASE=Bt8230 ATM Segment/Reassembly Ctrlr (SRC) + +pci:v0000109Ed00008472* + ID_PRODUCT_FROM_DATABASE=Bt8472 + +pci:v0000109Ed00008474* + ID_PRODUCT_FROM_DATABASE=Bt8474 + +pci:v0000109F* + ID_VENDOR_FROM_DATABASE=Trigem Computer Inc. + +pci:v000010A0* + ID_VENDOR_FROM_DATABASE=Meidensha Corporation + +pci:v000010A1* + ID_VENDOR_FROM_DATABASE=Juko Electronics Ind. Co. Ltd + +pci:v000010A2* + ID_VENDOR_FROM_DATABASE=Quantum Corporation + +pci:v000010A3* + ID_VENDOR_FROM_DATABASE=Everex Systems Inc + +pci:v000010A4* + ID_VENDOR_FROM_DATABASE=Globe Manufacturing Sales + +pci:v000010A5* + ID_VENDOR_FROM_DATABASE=Smart Link Ltd. + +pci:v000010A5d00003052* + ID_PRODUCT_FROM_DATABASE=SmartPCI562 56K Modem + +pci:v000010A5d00005449* + ID_PRODUCT_FROM_DATABASE=SmartPCI561 modem + +pci:v000010A6* + ID_VENDOR_FROM_DATABASE=Informtech Industrial Ltd. + +pci:v000010A7* + ID_VENDOR_FROM_DATABASE=Benchmarq Microelectronics + +pci:v000010A8* + ID_VENDOR_FROM_DATABASE=Sierra Semiconductor + +pci:v000010A8d00000000* + ID_PRODUCT_FROM_DATABASE=STB Horizon 64 + +pci:v000010A9* + ID_VENDOR_FROM_DATABASE=Silicon Graphics Intl. Corp. + +pci:v000010A9d00000001* + ID_PRODUCT_FROM_DATABASE=Crosstalk to PCI Bridge + +pci:v000010A9d00000002* + ID_PRODUCT_FROM_DATABASE=Linc I/O controller + +pci:v000010A9d00000003* + ID_PRODUCT_FROM_DATABASE=IOC3 I/O controller + +pci:v000010A9d00000004* + ID_PRODUCT_FROM_DATABASE=O2 MACE + +pci:v000010A9d00000005* + ID_PRODUCT_FROM_DATABASE=RAD Audio + +pci:v000010A9d00000006* + ID_PRODUCT_FROM_DATABASE=HPCEX + +pci:v000010A9d00000007* + ID_PRODUCT_FROM_DATABASE=RPCEX + +pci:v000010A9d00000008* + ID_PRODUCT_FROM_DATABASE=DiVO VIP + +pci:v000010A9d00000009* + ID_PRODUCT_FROM_DATABASE=AceNIC Gigabit Ethernet + +pci:v000010A9d00000009sv000010A9sd00008002* + ID_PRODUCT_FROM_DATABASE=AceNIC Gigabit Ethernet + +pci:v000010A9d00000010* + ID_PRODUCT_FROM_DATABASE=AMP Video I/O + +pci:v000010A9d00000011* + ID_PRODUCT_FROM_DATABASE=GRIP + +pci:v000010A9d00000012* + ID_PRODUCT_FROM_DATABASE=SGH PSHAC GSN + +pci:v000010A9d00000208* + ID_PRODUCT_FROM_DATABASE=SSIM1 SAS Adapter + +pci:v000010A9d00001001* + ID_PRODUCT_FROM_DATABASE=Magic Carpet + +pci:v000010A9d00001002* + ID_PRODUCT_FROM_DATABASE=Lithium + +pci:v000010A9d00001003* + ID_PRODUCT_FROM_DATABASE=Dual JPEG 1 + +pci:v000010A9d00001004* + ID_PRODUCT_FROM_DATABASE=Dual JPEG 2 + +pci:v000010A9d00001005* + ID_PRODUCT_FROM_DATABASE=Dual JPEG 3 + +pci:v000010A9d00001006* + ID_PRODUCT_FROM_DATABASE=Dual JPEG 4 + +pci:v000010A9d00001007* + ID_PRODUCT_FROM_DATABASE=Dual JPEG 5 + +pci:v000010A9d00001008* + ID_PRODUCT_FROM_DATABASE=Cesium + +pci:v000010A9d0000100A* + ID_PRODUCT_FROM_DATABASE=IOC4 I/O controller + +pci:v000010A9d00001504* + ID_PRODUCT_FROM_DATABASE=SSIM1 Fibre Channel Adapter + +pci:v000010A9d00002001* + ID_PRODUCT_FROM_DATABASE=Fibre Channel + +pci:v000010A9d00002002* + ID_PRODUCT_FROM_DATABASE=ASDE + +pci:v000010A9d00004001* + ID_PRODUCT_FROM_DATABASE=TIO-CE PCI Express Bridge + +pci:v000010A9d00004002* + ID_PRODUCT_FROM_DATABASE=TIO-CE PCI Express Port + +pci:v000010A9d00008001* + ID_PRODUCT_FROM_DATABASE=O2 1394 + +pci:v000010A9d00008002* + ID_PRODUCT_FROM_DATABASE=G-net NT + +pci:v000010AA* + ID_VENDOR_FROM_DATABASE=ACC Microelectronics + +pci:v000010AAd00000000* + ID_PRODUCT_FROM_DATABASE=ACCM 2188 + +pci:v000010AAd00002051* + ID_PRODUCT_FROM_DATABASE=2051 CPU bridge + +pci:v000010AAd00005842* + ID_PRODUCT_FROM_DATABASE=2051 ISA bridge + +pci:v000010AB* + ID_VENDOR_FROM_DATABASE=Digicom + +pci:v000010AC* + ID_VENDOR_FROM_DATABASE=Honeywell IAC + +pci:v000010AD* + ID_VENDOR_FROM_DATABASE=Symphony Labs + +pci:v000010ADd00000001* + ID_PRODUCT_FROM_DATABASE=W83769F + +pci:v000010ADd00000003* + ID_PRODUCT_FROM_DATABASE=SL82C103 + +pci:v000010ADd00000005* + ID_PRODUCT_FROM_DATABASE=SL82C105 + +pci:v000010ADd00000103* + ID_PRODUCT_FROM_DATABASE=SL82c103 + +pci:v000010ADd00000105* + ID_PRODUCT_FROM_DATABASE=SL82c105 + +pci:v000010ADd00000565* + ID_PRODUCT_FROM_DATABASE=W83C553F/W83C554F + +pci:v000010AE* + ID_VENDOR_FROM_DATABASE=Cornerstone Technology + +pci:v000010AF* + ID_VENDOR_FROM_DATABASE=Micro Computer Systems Inc + +pci:v000010B0* + ID_VENDOR_FROM_DATABASE=CardExpert Technology + +pci:v000010B1* + ID_VENDOR_FROM_DATABASE=Cabletron Systems Inc + +pci:v000010B2* + ID_VENDOR_FROM_DATABASE=Raytheon Company + +pci:v000010B3* + ID_VENDOR_FROM_DATABASE=Databook Inc + +pci:v000010B3d00003106* + ID_PRODUCT_FROM_DATABASE=DB87144 + +pci:v000010B3d0000B106* + ID_PRODUCT_FROM_DATABASE=DB87144 + +pci:v000010B4* + ID_VENDOR_FROM_DATABASE=STB Systems Inc + +pci:v000010B4d00001B1D* + ID_PRODUCT_FROM_DATABASE=Velocity 128 3D + +pci:v000010B4d00001B1Dsv000010B4sd0000237E* + ID_PRODUCT_FROM_DATABASE=Velocity 4400 + +pci:v000010B5* + ID_VENDOR_FROM_DATABASE=PLX Technology, Inc. + +pci:v000010B5d00000001* + ID_PRODUCT_FROM_DATABASE=i960 PCI bus interface + +pci:v000010B5d00000557* + ID_PRODUCT_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge + +pci:v000010B5d00000557sv0000105Bsd00009030* + ID_PRODUCT_FROM_DATABASE=Digium Tormenta 2 T400P-SS7 or E400P-SS7 Quad T1 or E1 PCI card + +pci:v000010B5d00001000* + ID_PRODUCT_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge + +pci:v000010B5d00001000sv0000105Bsd00009030* + ID_PRODUCT_FROM_DATABASE=ATCOM AT400P Quad T1 PCI card + +pci:v000010B5d00001024* + ID_PRODUCT_FROM_DATABASE=Acromag, Inc. IndustryPack Carrier Card + +pci:v000010B5d00001042* + ID_PRODUCT_FROM_DATABASE=Brandywine / jxi2, Inc. - PMC-SyncClock32, IRIG A & B, Nasa 36 + +pci:v000010B5d0000106A* + ID_PRODUCT_FROM_DATABASE=Dual OX16C952 4 port serial adapter [Megawolf Romulus/4] + +pci:v000010B5d00001076* + ID_PRODUCT_FROM_DATABASE=VScom 800 8 port serial adaptor + +pci:v000010B5d00001077* + ID_PRODUCT_FROM_DATABASE=VScom 400 4 port serial adaptor + +pci:v000010B5d00001078* + ID_PRODUCT_FROM_DATABASE=VScom 210 2 port serial and 1 port parallel adaptor + +pci:v000010B5d00001103* + ID_PRODUCT_FROM_DATABASE=VScom 200 2 port serial adaptor + +pci:v000010B5d00001146* + ID_PRODUCT_FROM_DATABASE=VScom 010 1 port parallel adaptor + +pci:v000010B5d00001147* + ID_PRODUCT_FROM_DATABASE=VScom 020 2 port parallel adaptor + +pci:v000010B5d00002000* + ID_PRODUCT_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge + +pci:v000010B5d00002000sv0000105Bsd00009030* + ID_PRODUCT_FROM_DATABASE=ATCOM AE400P Quad E1 PCI card + +pci:v000010B5d00002540* + ID_PRODUCT_FROM_DATABASE=IXXAT CAN-Interface PC-I 04/PCI + +pci:v000010B5d00002724* + ID_PRODUCT_FROM_DATABASE=Thales PCSM Security Card + +pci:v000010B5d00003376* + ID_PRODUCT_FROM_DATABASE=Cosateq 4 Port CAN Card + +pci:v000010B5d00004000* + ID_PRODUCT_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge + +pci:v000010B5d00004000sv000010B5sd00009030* + ID_PRODUCT_FROM_DATABASE=Tormenta 3 Varion V400P/ATCOM TE400P Quad E1/T1/J1 PCI card + +pci:v000010B5d00004001* + ID_PRODUCT_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge + +pci:v000010B5d00004001sv0000105Bsd00009030* + ID_PRODUCT_FROM_DATABASE=ATCOM A400PE Quad E1 PCI card + +pci:v000010B5d00004002* + ID_PRODUCT_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge + +pci:v000010B5d00004002sv0000105Bsd00009030* + ID_PRODUCT_FROM_DATABASE=ATCOM A400PT Quad T1 PCI card + +pci:v000010B5d00006140* + ID_PRODUCT_FROM_DATABASE=PCI6140 32-bit 33MHz PCI-to-PCI Bridge + +pci:v000010B5d00006150* + ID_PRODUCT_FROM_DATABASE=PCI6150 32-bit 33MHz PCI-to-PCI Bridge + +pci:v000010B5d00006152* + ID_PRODUCT_FROM_DATABASE=PCI6152 32-bit 66MHz PCI-to-PCI Bridge + +pci:v000010B5d00006154* + ID_PRODUCT_FROM_DATABASE=PCI6154 64-bit 66MHz PCI-to-PCI Bridge + +pci:v000010B5d00006254* + ID_PRODUCT_FROM_DATABASE=PCI6254 64-bit 66MHz PCI-to-PCI Bridge + +pci:v000010B5d00006466* + ID_PRODUCT_FROM_DATABASE=PCI6466 64-bit 66MHz PCI-to-PCI Bridge + +pci:v000010B5d00006520* + ID_PRODUCT_FROM_DATABASE=PCI6520 64-bit 133MHz PCI-X-to-PCI-X Bridge + +pci:v000010B5d00006540* + ID_PRODUCT_FROM_DATABASE=PCI6540 64-bit 133MHz PCI-X-to-PCI-X Bridge + +pci:v000010B5d00006540sv00001775sd00001100* + ID_PRODUCT_FROM_DATABASE=CR11 Single Board Computer + +pci:v000010B5d00006540sv00004C53sd000010E0* + ID_PRODUCT_FROM_DATABASE=PSL09 PrPMC + +pci:v000010B5d00006541* + ID_PRODUCT_FROM_DATABASE=PCI6540/6466 PCI-PCI bridge (non-transparent mode, primary side) + +pci:v000010B5d00006541sv00001775sd00001100* + ID_PRODUCT_FROM_DATABASE=CR11 Single Board Computer + +pci:v000010B5d00006541sv00004C53sd000010E0* + ID_PRODUCT_FROM_DATABASE=PSL09 PrPMC + +pci:v000010B5d00006542* + ID_PRODUCT_FROM_DATABASE=PCI6540/6466 PCI-PCI bridge (non-transparent mode, secondary side) + +pci:v000010B5d00006542sv00001775sd00001100* + ID_PRODUCT_FROM_DATABASE=CR11 Single Board Computer + +pci:v000010B5d00006542sv00004C53sd000010E0* + ID_PRODUCT_FROM_DATABASE=PSL09 PrPMC + +pci:v000010B5d00008111* + ID_PRODUCT_FROM_DATABASE=PEX 8111 PCI Express-to-PCI Bridge + +pci:v000010B5d00008112* + ID_PRODUCT_FROM_DATABASE=PEX8112 x1 Lane PCI Express-to-PCI Bridge + +pci:v000010B5d00008114* + ID_PRODUCT_FROM_DATABASE=PEX 8114 PCI Express-to-PCI/PCI-X Bridge + +pci:v000010B5d00008311* + ID_PRODUCT_FROM_DATABASE=PEX8311 x1 Lane PCI Express-to-Generic Local Bus Bridge + +pci:v000010B5d00008505* + ID_PRODUCT_FROM_DATABASE=PEX 8505 5-lane, 5-port PCI Express Switch + +pci:v000010B5d00008508* + ID_PRODUCT_FROM_DATABASE=PEX 8508 8-lane, 5-port PCI Express Switch + +pci:v000010B5d00008509* + ID_PRODUCT_FROM_DATABASE=PEX 8509 8-lane, 8-port PCI Express Switch + +pci:v000010B5d00008512* + ID_PRODUCT_FROM_DATABASE=PEX 8512 12-lane, 5-port PCI Express Switch + +pci:v000010B5d00008516* + ID_PRODUCT_FROM_DATABASE=PEX 8516 Versatile PCI Express Switch + +pci:v000010B5d00008517* + ID_PRODUCT_FROM_DATABASE=PEX 8517 16-lane, 5-port PCI Express Switch + +pci:v000010B5d00008518* + ID_PRODUCT_FROM_DATABASE=PEX 8518 16-lane, 5-port PCI Express Switch + +pci:v000010B5d00008524* + ID_PRODUCT_FROM_DATABASE=PEX 8524 24-lane, 6-port PCI Express Switch + +pci:v000010B5d00008525* + ID_PRODUCT_FROM_DATABASE=PEX 8525 24-lane, 5-port PCI Express Switch + +pci:v000010B5d00008532* + ID_PRODUCT_FROM_DATABASE=PEX 8532 Versatile PCI Express Switch + +pci:v000010B5d00008533* + ID_PRODUCT_FROM_DATABASE=PEX 8533 32-lane, 6-port PCI Express Switch + +pci:v000010B5d00008547* + ID_PRODUCT_FROM_DATABASE=PEX 8547 48-lane, 3-port PCI Express Switch + +pci:v000010B5d00008548* + ID_PRODUCT_FROM_DATABASE=PEX 8548 48-lane, 9-port PCI Express Switch + +pci:v000010B5d00008604* + ID_PRODUCT_FROM_DATABASE=PEX 8604 4-lane, 4-Port PCI Express Gen 2 (5.0 GT/s) Switch + +pci:v000010B5d00008605* + ID_PRODUCT_FROM_DATABASE=PEX 8605 PCI Express 4-port Gen2 Switch + +pci:v000010B5d00008606* + ID_PRODUCT_FROM_DATABASE=PEX 8606 6 Lane, 6 Port PCI Express Gen 2 (5.0 GT/s) Switch + +pci:v000010B5d00008608* + ID_PRODUCT_FROM_DATABASE=PEX 8608 8-lane, 8-Port PCI Express Gen 2 (5.0 GT/s) Switch + +pci:v000010B5d00008609* + ID_PRODUCT_FROM_DATABASE=PEX 8609 8-lane, 8-Port PCI Express Gen 2 (5.0 GT/s) Switch with DMA + +pci:v000010B5d00008612* + ID_PRODUCT_FROM_DATABASE=PEX 8612 12-lane, 4-Port PCI Express Gen 2 (5.0 GT/s) Switch + +pci:v000010B5d00008613* + ID_PRODUCT_FROM_DATABASE=PEX 8613 12-lane, 3-Port PCI Express Gen 2 (5.0 GT/s) Switch + +pci:v000010B5d00008614* + ID_PRODUCT_FROM_DATABASE=PEX 8614 12-lane, 12-Port PCI Express Gen 2 (5.0 GT/s) Switch + +pci:v000010B5d00008615* + ID_PRODUCT_FROM_DATABASE=PEX 8615 12-lane, 12-Port PCI Express Gen 2 (5.0 GT/s) Switch with DMA + +pci:v000010B5d00008616* + ID_PRODUCT_FROM_DATABASE=PEX 8616 16-lane, 4-Port PCI Express Gen 2 (5.0 GT/s) Switch + +pci:v000010B5d00008617* + ID_PRODUCT_FROM_DATABASE=PEX 8617 16-lane, 4-Port PCI Express Gen 2 (5.0 GT/s) Switch with P2P + +pci:v000010B5d00008618* + ID_PRODUCT_FROM_DATABASE=PEX 8618 16-lane, 16-Port PCI Express Gen 2 (5.0 GT/s) Switch + +pci:v000010B5d00008619* + ID_PRODUCT_FROM_DATABASE=PEX 8619 16-lane, 16-Port PCI Express Gen 2 (5.0 GT/s) Switch with DMA + +pci:v000010B5d00008624* + ID_PRODUCT_FROM_DATABASE=PEX 8624 24-lane, 6-Port PCI Express Gen 2 (5.0 GT/s) Switch [ExpressLane] + +pci:v000010B5d00008624sv000013A3sd00001845* + ID_PRODUCT_FROM_DATABASE=DX1845 Acceleration Card + +pci:v000010B5d00008625* + ID_PRODUCT_FROM_DATABASE=PEX 8625 24-lane, 24-Port PCI Express Gen 2 (5.0 GT/s) Switch + +pci:v000010B5d00008632* + ID_PRODUCT_FROM_DATABASE=PEX 8632 32-lane, 12-Port PCI Express Gen 2 (5.0 GT/s) Switch + +pci:v000010B5d00008636* + ID_PRODUCT_FROM_DATABASE=PEX 8636 36-lane, 24-Port PCI Express Gen 2 (5.0 GT/s) Switch + +pci:v000010B5d00008647* + ID_PRODUCT_FROM_DATABASE=PEX 8647 48-Lane, 3-Port PCI Express Gen 2 (5.0 GT/s) Switch + +pci:v000010B5d00008648* + ID_PRODUCT_FROM_DATABASE=PEX 8648 48-lane, 12-Port PCI Express Gen 2 (5.0 GT/s) Switch + +pci:v000010B5d00008649* + ID_PRODUCT_FROM_DATABASE=PEX 8649 48-lane, 12-Port PCI Express Gen 2 (5.0 GT/s) Switch + +pci:v000010B5d00008664* + ID_PRODUCT_FROM_DATABASE=PEX 8664 64-lane, 16-Port PCI Express Gen 2 (5.0 GT/s) Switch + +pci:v000010B5d00008680* + ID_PRODUCT_FROM_DATABASE=PEX 8680 80-lane, 20-Port PCI Express Gen 2 (5.0 GT/s) Multi-Root Switch + +pci:v000010B5d00008696* + ID_PRODUCT_FROM_DATABASE=PEX 8696 96-lane, 24-Port PCI Express Gen 2 (5.0 GT/s) Multi-Root Switch + +pci:v000010B5d00008732* + ID_PRODUCT_FROM_DATABASE=PEX 8732 32-lane, 8-Port PCI Express Gen 3 (8.0 GT/s) Switch + +pci:v000010B5d000087B0* + ID_PRODUCT_FROM_DATABASE=PEX 8732 32-lane, 8-Port PCI Express Gen 3 (8.0 GT/s) Switch + +pci:v000010B5d00009016* + ID_PRODUCT_FROM_DATABASE=PLX 9016 8-port serial controller + +pci:v000010B5d00009030* + ID_PRODUCT_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge + +pci:v000010B5d00009030sv000010B5sd00002695* + ID_PRODUCT_FROM_DATABASE=Hilscher CIF50-PB/DPS Profibus + +pci:v000010B5d00009030sv000010B5sd00002862* + ID_PRODUCT_FROM_DATABASE=Alpermann+Velte PCL PCI LV (3V/5V): Timecode Reader Board + +pci:v000010B5d00009030sv000010B5sd00002906* + ID_PRODUCT_FROM_DATABASE=Alpermann+Velte PCI TS (3V/5V): Time Synchronisation Board + +pci:v000010B5d00009030sv000010B5sd00002940* + ID_PRODUCT_FROM_DATABASE=Alpermann+Velte PCL PCI D (3V/5V): Timecode Reader Board + +pci:v000010B5d00009030sv000010B5sd00002977* + ID_PRODUCT_FROM_DATABASE=IXXAT iPC-I XC16/PCI CAN Board + +pci:v000010B5d00009030sv000010B5sd00002978* + ID_PRODUCT_FROM_DATABASE=SH ARC-PCIu/SH ARC-PCI104/SH ARC-PCIe SOHARD ARCNET card + +pci:v000010B5d00009030sv000010B5sd00003025* + ID_PRODUCT_FROM_DATABASE=Alpermann+Velte PCL PCI L (3V/5V): Timecode Reader Board + +pci:v000010B5d00009030sv000010B5sd00003068* + ID_PRODUCT_FROM_DATABASE=Alpermann+Velte PCL PCI HD (3V/5V): Timecode Reader Board + +pci:v000010B5d00009030sv000010B5sd00003463* + ID_PRODUCT_FROM_DATABASE=Alpermann+Velte PCL PCI D (v2) (3V/5V): Timecode Reader Board + +pci:v000010B5d00009030sv000012FEsd00000111* + ID_PRODUCT_FROM_DATABASE=CPCI-ASIO4 (ESD 4-port Serial Interface Board) + +pci:v000010B5d00009030sv00001369sd00009C01* + ID_PRODUCT_FROM_DATABASE=VX222v2 + +pci:v000010B5d00009030sv00001369sd00009D01* + ID_PRODUCT_FROM_DATABASE=VX222-Mic + +pci:v000010B5d00009030sv00001369sd00009D02* + ID_PRODUCT_FROM_DATABASE=VX222-Mic + +pci:v000010B5d00009030sv00001369sd00009E01* + ID_PRODUCT_FROM_DATABASE=PCX924v2 + +pci:v000010B5d00009030sv00001369sd00009F01* + ID_PRODUCT_FROM_DATABASE=PCX924-Mic + +pci:v000010B5d00009030sv00001369sd00009F02* + ID_PRODUCT_FROM_DATABASE=PCX924-Mic + +pci:v000010B5d00009030sv00001369sd0000A001* + ID_PRODUCT_FROM_DATABASE=PCX22v2 + +pci:v000010B5d00009030sv00001369sd0000A701* + ID_PRODUCT_FROM_DATABASE=LCM220v2 + +pci:v000010B5d00009030sv00001369sd0000A801* + ID_PRODUCT_FROM_DATABASE=LCM200 + +pci:v000010B5d00009030sv00001397sd00003136* + ID_PRODUCT_FROM_DATABASE=4xS0-ISDN PCI Adapter + +pci:v000010B5d00009030sv00001397sd00003137* + ID_PRODUCT_FROM_DATABASE=S2M-E1-ISDN PCI Adapter + +pci:v000010B5d00009030sv00001518sd00000200* + ID_PRODUCT_FROM_DATABASE=Kontron ThinkIO-C + +pci:v000010B5d00009030sv000015EDsd00001002* + ID_PRODUCT_FROM_DATABASE=MCCS 8-port Serial Hot Swap + +pci:v000010B5d00009030sv000015EDsd00001003* + ID_PRODUCT_FROM_DATABASE=MCCS 16-port Serial Hot Swap + +pci:v000010B5d00009030sv0000E1C5sd00000001* + ID_PRODUCT_FROM_DATABASE=TE1-PCI + +pci:v000010B5d00009030sv0000E1C5sd00000005* + ID_PRODUCT_FROM_DATABASE=TA1-PCI + +pci:v000010B5d00009030sv0000E1C5sd00000006* + ID_PRODUCT_FROM_DATABASE=TA1-PCI4 + +pci:v000010B5d00009036* + ID_PRODUCT_FROM_DATABASE=9036 + +pci:v000010B5d00009050* + ID_PRODUCT_FROM_DATABASE=PCI <-> IOBus Bridge + +pci:v000010B5d00009050sv000010B5sd00001067* + ID_PRODUCT_FROM_DATABASE=IXXAT CAN i165 + +pci:v000010B5d00009050sv000010B5sd0000114E* + ID_PRODUCT_FROM_DATABASE=Wasco WITIO PCI168extended + +pci:v000010B5d00009050sv000010B5sd00001169* + ID_PRODUCT_FROM_DATABASE=Wasco OPTOIO32standard 32 digital in, 32 digital out + +pci:v000010B5d00009050sv000010B5sd00001172* + ID_PRODUCT_FROM_DATABASE=IK220 (Heidenhain) + +pci:v000010B5d00009050sv000010B5sd00002036* + ID_PRODUCT_FROM_DATABASE=SatPak GPS + +pci:v000010B5d00009050sv000010B5sd00002221* + ID_PRODUCT_FROM_DATABASE=Alpermann+Velte PCL PCI LV: Timecode Reader Board + +pci:v000010B5d00009050sv000010B5sd00002273* + ID_PRODUCT_FROM_DATABASE=SH ARC-PCI SOHARD ARCNET card + +pci:v000010B5d00009050sv000010B5sd00002431* + ID_PRODUCT_FROM_DATABASE=Alpermann+Velte PCL PCI D: Timecode Reader Board + +pci:v000010B5d00009050sv000010B5sd00002905* + ID_PRODUCT_FROM_DATABASE=Alpermann+Velte PCI TS: Time Synchronisation Board + +pci:v000010B5d00009050sv000010B5sd00003196* + ID_PRODUCT_FROM_DATABASE=Goramo PLX200SYN sync serial card + +pci:v000010B5d00009050sv000010B5sd00009050* + ID_PRODUCT_FROM_DATABASE=PCI-I04 PCI Passive PC/CAN Interface + +pci:v000010B5d00009050sv00001369sd00008901* + ID_PRODUCT_FROM_DATABASE=PCX11+ PCI + +pci:v000010B5d00009050sv00001369sd00008F01* + ID_PRODUCT_FROM_DATABASE=VX222 + +pci:v000010B5d00009050sv00001369sd00009401* + ID_PRODUCT_FROM_DATABASE=PCX924 + +pci:v000010B5d00009050sv00001369sd00009501* + ID_PRODUCT_FROM_DATABASE=PCX22 + +pci:v000010B5d00009050sv00001498sd00000362* + ID_PRODUCT_FROM_DATABASE=TPMC866 8 Channel Serial Card + +pci:v000010B5d00009050sv00001522sd00000001* + ID_PRODUCT_FROM_DATABASE=RockForce 4 Port V.90 Data/Fax/Voice Modem + +pci:v000010B5d00009050sv00001522sd00000002* + ID_PRODUCT_FROM_DATABASE=RockForce 2 Port V.90 Data/Fax/Voice Modem + +pci:v000010B5d00009050sv00001522sd00000003* + ID_PRODUCT_FROM_DATABASE=RockForce 6 Port V.90 Data/Fax/Voice Modem + +pci:v000010B5d00009050sv00001522sd00000004* + ID_PRODUCT_FROM_DATABASE=RockForce 8 Port V.90 Data/Fax/Voice Modem + +pci:v000010B5d00009050sv00001522sd00000010* + ID_PRODUCT_FROM_DATABASE=RockForce2000 4 Port V.90 Data/Fax/Voice Modem + +pci:v000010B5d00009050sv00001522sd00000020* + ID_PRODUCT_FROM_DATABASE=RockForce2000 2 Port V.90 Data/Fax/Voice Modem + +pci:v000010B5d00009050sv000015EDsd00001000* + ID_PRODUCT_FROM_DATABASE=Macrolink MCCS 8-port Serial + +pci:v000010B5d00009050sv000015EDsd00001001* + ID_PRODUCT_FROM_DATABASE=Macrolink MCCS 16-port Serial + +pci:v000010B5d00009050sv000015EDsd00001002* + ID_PRODUCT_FROM_DATABASE=Macrolink MCCS 8-port Serial Hot Swap + +pci:v000010B5d00009050sv000015EDsd00001003* + ID_PRODUCT_FROM_DATABASE=Macrolink MCCS 16-port Serial Hot Swap + +pci:v000010B5d00009050sv00005654sd00002036* + ID_PRODUCT_FROM_DATABASE=OpenSwitch 6 Telephony card + +pci:v000010B5d00009050sv00005654sd00003132* + ID_PRODUCT_FROM_DATABASE=OpenSwitch 12 Telephony card + +pci:v000010B5d00009050sv00005654sd00005634* + ID_PRODUCT_FROM_DATABASE=OpenLine4 Telephony Card + +pci:v000010B5d00009050sv0000D531sd0000C002* + ID_PRODUCT_FROM_DATABASE=PCIntelliCAN 2xSJA1000 CAN bus + +pci:v000010B5d00009050sv0000D84Dsd00004006* + ID_PRODUCT_FROM_DATABASE=EX-4006 1P + +pci:v000010B5d00009050sv0000D84Dsd00004008* + ID_PRODUCT_FROM_DATABASE=EX-4008 1P EPP/ECP + +pci:v000010B5d00009050sv0000D84Dsd00004014* + ID_PRODUCT_FROM_DATABASE=EX-4014 2P + +pci:v000010B5d00009050sv0000D84Dsd00004018* + ID_PRODUCT_FROM_DATABASE=EX-4018 3P EPP/ECP + +pci:v000010B5d00009050sv0000D84Dsd00004025* + ID_PRODUCT_FROM_DATABASE=EX-4025 1S(16C550) RS-232 + +pci:v000010B5d00009050sv0000D84Dsd00004027* + ID_PRODUCT_FROM_DATABASE=EX-4027 1S(16C650) RS-232 + +pci:v000010B5d00009050sv0000D84Dsd00004028* + ID_PRODUCT_FROM_DATABASE=EX-4028 1S(16C850) RS-232 + +pci:v000010B5d00009050sv0000D84Dsd00004036* + ID_PRODUCT_FROM_DATABASE=EX-4036 2S(16C650) RS-232 + +pci:v000010B5d00009050sv0000D84Dsd00004037* + ID_PRODUCT_FROM_DATABASE=EX-4037 2S(16C650) RS-232 + +pci:v000010B5d00009050sv0000D84Dsd00004038* + ID_PRODUCT_FROM_DATABASE=EX-4038 2S(16C850) RS-232 + +pci:v000010B5d00009050sv0000D84Dsd00004052* + ID_PRODUCT_FROM_DATABASE=EX-4052 1S(16C550) RS-422/485 + +pci:v000010B5d00009050sv0000D84Dsd00004053* + ID_PRODUCT_FROM_DATABASE=EX-4053 2S(16C550) RS-422/485 + +pci:v000010B5d00009050sv0000D84Dsd00004055* + ID_PRODUCT_FROM_DATABASE=EX-4055 4S(16C550) RS-232 + +pci:v000010B5d00009050sv0000D84Dsd00004058* + ID_PRODUCT_FROM_DATABASE=EX-4055 4S(16C650) RS-232 + +pci:v000010B5d00009050sv0000D84Dsd00004065* + ID_PRODUCT_FROM_DATABASE=EX-4065 8S(16C550) RS-232 + +pci:v000010B5d00009050sv0000D84Dsd00004068* + ID_PRODUCT_FROM_DATABASE=EX-4068 8S(16C650) RS-232 + +pci:v000010B5d00009050sv0000D84Dsd00004078* + ID_PRODUCT_FROM_DATABASE=EX-4078 2S(16C552) RS-232+1P + +pci:v000010B5d00009052* + ID_PRODUCT_FROM_DATABASE=PCI9052 PCI <-> IOBus Bridge + +pci:v000010B5d00009054* + ID_PRODUCT_FROM_DATABASE=PCI9054 32-bit 33MHz PCI <-> IOBus Bridge + +pci:v000010B5d00009054sv000010B5sd00002455* + ID_PRODUCT_FROM_DATABASE=Wessex Techology PHIL-PCI + +pci:v000010B5d00009054sv000010B5sd00002696* + ID_PRODUCT_FROM_DATABASE=Innes Corp AM Radcap card + +pci:v000010B5d00009054sv000010B5sd00002717* + ID_PRODUCT_FROM_DATABASE=Innes Corp Auricon card + +pci:v000010B5d00009054sv000010B5sd00002844* + ID_PRODUCT_FROM_DATABASE=Innes Corp TVS Encoder card + +pci:v000010B5d00009054sv000012C7sd00004001* + ID_PRODUCT_FROM_DATABASE=Intel Dialogic DM/V960-4T1 PCI + +pci:v000010B5d00009054sv000012D9sd00000002* + ID_PRODUCT_FROM_DATABASE=PCI Prosody Card rev 1.5 + +pci:v000010B5d00009054sv000014B4sd0000D100* + ID_PRODUCT_FROM_DATABASE=Dektec DTA-100 + +pci:v000010B5d00009054sv000014B4sd0000D114* + ID_PRODUCT_FROM_DATABASE=Dektec DTA-120 + +pci:v000010B5d00009054sv000016DFsd00000011* + ID_PRODUCT_FROM_DATABASE=PIKA PrimeNet MM PCI + +pci:v000010B5d00009054sv000016DFsd00000012* + ID_PRODUCT_FROM_DATABASE=PIKA PrimeNet MM cPCI 8 + +pci:v000010B5d00009054sv000016DFsd00000013* + ID_PRODUCT_FROM_DATABASE=PIKA PrimeNet MM cPCI 8 (without CAS Signaling) + +pci:v000010B5d00009054sv000016DFsd00000014* + ID_PRODUCT_FROM_DATABASE=PIKA PrimeNet MM cPCI 4 + +pci:v000010B5d00009054sv000016DFsd00000015* + ID_PRODUCT_FROM_DATABASE=PIKA Daytona MM + +pci:v000010B5d00009054sv000016DFsd00000016* + ID_PRODUCT_FROM_DATABASE=PIKA InLine MM + +pci:v000010B5d00009056* + ID_PRODUCT_FROM_DATABASE=PCI9056 32-bit 66MHz PCI <-> IOBus Bridge + +pci:v000010B5d00009056sv000010B5sd00002979* + ID_PRODUCT_FROM_DATABASE=CellinkBlade 11 - CPCI board VoATM AAL1 + +pci:v000010B5d00009056sv000010B5sd00003268* + ID_PRODUCT_FROM_DATABASE=IXXAT iPC-I XC16/PCIe CAN Board + +pci:v000010B5d00009056sv000010B5sd00003352* + ID_PRODUCT_FROM_DATABASE=Alpermann+Velte PCL PCIe HD: Timecode Reader Board + +pci:v000010B5d00009056sv000010B5sd00003353* + ID_PRODUCT_FROM_DATABASE=Alpermann+Velte PCL PCIe D: Timecode Reader Board + +pci:v000010B5d00009056sv000010B5sd00003354* + ID_PRODUCT_FROM_DATABASE=Alpermann+Velte PCL PCIe LV: Timecode Reader Board + +pci:v000010B5d00009056sv000010B5sd00003355* + ID_PRODUCT_FROM_DATABASE=Alpermann+Velte PCL PCIe L: Timecode Reader Board + +pci:v000010B5d00009056sv000010B5sd00003415* + ID_PRODUCT_FROM_DATABASE=Alpermann+Velte PCIe TS: Time Synchronisation Board + +pci:v000010B5d00009056sv00001369sd0000C001* + ID_PRODUCT_FROM_DATABASE=LX6464ES + +pci:v000010B5d00009056sv00001369sd0000C201* + ID_PRODUCT_FROM_DATABASE=LX1616ES + +pci:v000010B5d00009056sv000014B4sd0000D10A* + ID_PRODUCT_FROM_DATABASE=DekTec DTA-110T + +pci:v000010B5d00009056sv000014B4sd0000D140* + ID_PRODUCT_FROM_DATABASE=Dektec DTA-140 + +pci:v000010B5d00009056sv00001A0Esd0000006F* + ID_PRODUCT_FROM_DATABASE=Dektec DTA-111 + +pci:v000010B5d00009060* + ID_PRODUCT_FROM_DATABASE=PCI9060 32-bit 33MHz PCI <-> IOBus Bridge + +pci:v000010B5d0000906D* + ID_PRODUCT_FROM_DATABASE=9060SD + +pci:v000010B5d0000906Dsv0000125Csd00000640* + ID_PRODUCT_FROM_DATABASE=Aries 16000P + +pci:v000010B5d0000906E* + ID_PRODUCT_FROM_DATABASE=9060ES + +pci:v000010B5d00009080* + ID_PRODUCT_FROM_DATABASE=PCI9080 32-bit; 33MHz PCI <-> IOBus Bridge + +pci:v000010B5d00009080sv0000103Csd000010EB* + ID_PRODUCT_FROM_DATABASE=(Agilent) E2777B 83K Series Optical Communication Interface + +pci:v000010B5d00009080sv0000103Csd000010EC* + ID_PRODUCT_FROM_DATABASE=(Agilent) E6978-66442 PCI CIC + +pci:v000010B5d00009080sv000010B5sd00001123* + ID_PRODUCT_FROM_DATABASE=Sectra KK631 encryption board + +pci:v000010B5d00009080sv000010B5sd00009080* + ID_PRODUCT_FROM_DATABASE=9080 [real subsystem ID not set] + +pci:v000010B5d00009080sv000012D9sd00000002* + ID_PRODUCT_FROM_DATABASE=PCI Prosody Card + +pci:v000010B5d00009080sv000012DFsd00004422* + ID_PRODUCT_FROM_DATABASE=4422PCI ["Do-All" Telemetry Data Aquisition System] + +pci:v000010B5d00009080sv00001369sd00009601* + ID_PRODUCT_FROM_DATABASE=PCX822np + +pci:v000010B5d00009080sv00001369sd0000A102* + ID_PRODUCT_FROM_DATABASE=PCX822v2 + +pci:v000010B5d00009080sv00001369sd0000A201* + ID_PRODUCT_FROM_DATABASE=PCX442 + +pci:v000010B5d00009080sv00001369sd0000A301* + ID_PRODUCT_FROM_DATABASE=LCM440v2 + +pci:v000010B5d00009080sv00001369sd0000A401* + ID_PRODUCT_FROM_DATABASE=VX822 + +pci:v000010B5d00009080sv00001369sd0000A402* + ID_PRODUCT_FROM_DATABASE=VX822v2 + +pci:v000010B5d00009080sv00001369sd0000A901* + ID_PRODUCT_FROM_DATABASE=LCM420 + +pci:v000010B5d00009080sv00001369sd0000AA01* + ID_PRODUCT_FROM_DATABASE=VX820v2 + +pci:v000010B5d00009080sv00001517sd0000000B* + ID_PRODUCT_FROM_DATABASE=ECSG-1R3ADC-PMC Clock synthesizer + +pci:v000010B5d00009656* + ID_PRODUCT_FROM_DATABASE=PCI9656 PCI <-> IOBus Bridge + +pci:v000010B5d00009656sv00001517sd0000000F* + ID_PRODUCT_FROM_DATABASE=ECDR-GC314-PMC Receiver + +pci:v000010B5d00009656sv00001885sd00000700* + ID_PRODUCT_FROM_DATABASE=Tsunami FPGA PMC with Altera Stratix S40 + +pci:v000010B5d00009656sv00001885sd00000701* + ID_PRODUCT_FROM_DATABASE=Tsunami FPGA PMC with Altera Stratix S30 + +pci:v000010B5d0000A100* + ID_PRODUCT_FROM_DATABASE=Blackmagic Design DeckLink + +pci:v000010B5d0000BB04* + ID_PRODUCT_FROM_DATABASE=B&B 3PCIOSD1A Isolated PCI Serial + +pci:v000010B5d0000C001* + ID_PRODUCT_FROM_DATABASE=CronyxOmega-PCI (8-port RS232) + +pci:v000010B5d0000D00D* + ID_PRODUCT_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge + +pci:v000010B5d0000D00Dsv000010B5sd00009030* + ID_PRODUCT_FROM_DATABASE=Digium Tormenta 2 T400P or E400P Quad T1 or E1 PCI card + +pci:v000010B5d0000D33D* + ID_PRODUCT_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge + +pci:v000010B5d0000D33Dsv0000105Bsd00009030* + ID_PRODUCT_FROM_DATABASE=Tormenta 3 Varion V401PT Quad T1/J1 PCI card + +pci:v000010B5d0000D44D* + ID_PRODUCT_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge + +pci:v000010B5d0000D44Dsv0000105Bsd00009030* + ID_PRODUCT_FROM_DATABASE=Tormenta 3 Varion V401PE Quad E1 PCI card + +pci:v000010B5d0000D44Dsv000010B5sd000017F6* + ID_PRODUCT_FROM_DATABASE=Allo CP100P/E 1-port E1/T1/J1 PCI/PCIe card + +pci:v000010B5d0000D44Dsv000010B5sd000017F7* + ID_PRODUCT_FROM_DATABASE=Allo CP400P/E 4-port E1/T1/J1 PCI/PCIe card + +pci:v000010B5d0000D44Dsv000010B5sd000017F8* + ID_PRODUCT_FROM_DATABASE=Allo CP200P/E 2-port E1/T1/J1 PCI/PCIe card + +pci:v000010B6* + ID_VENDOR_FROM_DATABASE=Madge Networks + +pci:v000010B6d00000001* + ID_PRODUCT_FROM_DATABASE=Smart 16/4 PCI Ringnode + +pci:v000010B6d00000002* + ID_PRODUCT_FROM_DATABASE=Smart 16/4 PCI Ringnode Mk2 + +pci:v000010B6d00000002sv000010B6sd00000002* + ID_PRODUCT_FROM_DATABASE=Smart 16/4 PCI Ringnode Mk2 + +pci:v000010B6d00000002sv000010B6sd00000006* + ID_PRODUCT_FROM_DATABASE=16/4 CardBus Adapter + +pci:v000010B6d00000003* + ID_PRODUCT_FROM_DATABASE=Smart 16/4 PCI Ringnode Mk3 + +pci:v000010B6d00000003sv00000E11sd0000B0FD* + ID_PRODUCT_FROM_DATABASE=Compaq NC4621 PCI, 4/16, WOL + +pci:v000010B6d00000003sv000010B6sd00000003* + ID_PRODUCT_FROM_DATABASE=Smart 16/4 PCI Ringnode Mk3 + +pci:v000010B6d00000003sv000010B6sd00000007* + ID_PRODUCT_FROM_DATABASE=Presto PCI Plus Adapter + +pci:v000010B6d00000004* + ID_PRODUCT_FROM_DATABASE=Smart 16/4 PCI Ringnode Mk1 + +pci:v000010B6d00000006* + ID_PRODUCT_FROM_DATABASE=16/4 Cardbus Adapter + +pci:v000010B6d00000006sv000010B6sd00000006* + ID_PRODUCT_FROM_DATABASE=16/4 CardBus Adapter + +pci:v000010B6d00000007* + ID_PRODUCT_FROM_DATABASE=Presto PCI Adapter + +pci:v000010B6d00000007sv000010B6sd00000007* + ID_PRODUCT_FROM_DATABASE=Presto PCI + +pci:v000010B6d00000009* + ID_PRODUCT_FROM_DATABASE=Smart 100/16/4 PCI-HS Ringnode + +pci:v000010B6d00000009sv000010B6sd00000009* + ID_PRODUCT_FROM_DATABASE=Smart 100/16/4 PCI-HS Ringnode + +pci:v000010B6d0000000A* + ID_PRODUCT_FROM_DATABASE=Smart 100/16/4 PCI Ringnode + +pci:v000010B6d0000000Asv000010B6sd0000000A* + ID_PRODUCT_FROM_DATABASE=Smart 100/16/4 PCI Ringnode + +pci:v000010B6d0000000B* + ID_PRODUCT_FROM_DATABASE=16/4 CardBus Adapter Mk2 + +pci:v000010B6d0000000Bsv000010B6sd00000008* + ID_PRODUCT_FROM_DATABASE=16/4 CardBus Adapter Mk2 + +pci:v000010B6d0000000Bsv000010B6sd0000000B* + ID_PRODUCT_FROM_DATABASE=16/4 Cardbus Adapter Mk2 + +pci:v000010B6d0000000C* + ID_PRODUCT_FROM_DATABASE=RapidFire 3140V2 16/4 TR Adapter + +pci:v000010B6d0000000Csv000010B6sd0000000C* + ID_PRODUCT_FROM_DATABASE=RapidFire 3140V2 16/4 TR Adapter + +pci:v000010B6d00001000* + ID_PRODUCT_FROM_DATABASE=Collage 25/155 ATM Client Adapter + +pci:v000010B6d00001001* + ID_PRODUCT_FROM_DATABASE=Collage 155 ATM Server Adapter + +pci:v000010B7* + ID_VENDOR_FROM_DATABASE=3Com Corporation + +pci:v000010B7d00000001* + ID_PRODUCT_FROM_DATABASE=3c985 1000BaseSX (SX/TX) + +pci:v000010B7d00000013* + ID_PRODUCT_FROM_DATABASE=AR5212 802.11abg NIC (3CRDAG675) + +pci:v000010B7d00000013sv000010B7sd00002031* + ID_PRODUCT_FROM_DATABASE=3CRDAG675 11a/b/g Wireless PCI Adapter + +pci:v000010B7d00000910* + ID_PRODUCT_FROM_DATABASE=3C910-A01 + +pci:v000010B7d00001006* + ID_PRODUCT_FROM_DATABASE=MINI PCI type 3B Data Fax Modem + +pci:v000010B7d00001007* + ID_PRODUCT_FROM_DATABASE=Mini PCI 56k Winmodem + +pci:v000010B7d00001007sv000010B7sd0000615B* + ID_PRODUCT_FROM_DATABASE=Mini PCI 56K Modem + +pci:v000010B7d00001007sv000010B7sd0000615C* + ID_PRODUCT_FROM_DATABASE=Mini PCI 56K Modem + +pci:v000010B7d00001201* + ID_PRODUCT_FROM_DATABASE=3c982-TXM 10/100baseTX Dual Port A [Hydra] + +pci:v000010B7d00001202* + ID_PRODUCT_FROM_DATABASE=3c982-TXM 10/100baseTX Dual Port B [Hydra] + +pci:v000010B7d00001700* + ID_PRODUCT_FROM_DATABASE=3c940 10/100/1000Base-T [Marvell] + +pci:v000010B7d00001700sv00001043sd000080EB* + ID_PRODUCT_FROM_DATABASE=A7V600/P4P800/K8V motherboard + +pci:v000010B7d00001700sv000010B7sd00000010* + ID_PRODUCT_FROM_DATABASE=3C940 Gigabit LOM Ethernet Adapter + +pci:v000010B7d00001700sv000010B7sd00000020* + ID_PRODUCT_FROM_DATABASE=3C941 Gigabit LOM Ethernet Adapter + +pci:v000010B7d00001700sv0000147Bsd00001407* + ID_PRODUCT_FROM_DATABASE=KV8-MAX3 motherboard + +pci:v000010B7d00003390* + ID_PRODUCT_FROM_DATABASE=3c339 TokenLink Velocity + +pci:v000010B7d00003590* + ID_PRODUCT_FROM_DATABASE=3c359 TokenLink Velocity XL + +pci:v000010B7d00003590sv000010B7sd00003590* + ID_PRODUCT_FROM_DATABASE=TokenLink Velocity XL Adapter (3C359/359B) + +pci:v000010B7d00004500* + ID_PRODUCT_FROM_DATABASE=3c450 HomePNA [Tornado] + +pci:v000010B7d00005055* + ID_PRODUCT_FROM_DATABASE=3c555 Laptop Hurricane + +pci:v000010B7d00005057* + ID_PRODUCT_FROM_DATABASE=3c575 Megahertz 10/100 LAN CardBus [Boomerang] + +pci:v000010B7d00005057sv000010B7sd00005A57* + ID_PRODUCT_FROM_DATABASE=3C575 Megahertz 10/100 LAN Cardbus PC Card + +pci:v000010B7d00005157* + ID_PRODUCT_FROM_DATABASE=3cCFE575BT Megahertz 10/100 LAN CardBus [Cyclone] + +pci:v000010B7d00005157sv000010B7sd00005B57* + ID_PRODUCT_FROM_DATABASE=3C575 Megahertz 10/100 LAN Cardbus PC Card + +pci:v000010B7d00005257* + ID_PRODUCT_FROM_DATABASE=3cCFE575CT CardBus [Cyclone] + +pci:v000010B7d00005257sv000010B7sd00005C57* + ID_PRODUCT_FROM_DATABASE=FE575C-3Com 10/100 LAN CardBus-Fast Ethernet + +pci:v000010B7d00005900* + ID_PRODUCT_FROM_DATABASE=3c590 10BaseT [Vortex] + +pci:v000010B7d00005920* + ID_PRODUCT_FROM_DATABASE=3c592 EISA 10mbps Demon/Vortex + +pci:v000010B7d00005950* + ID_PRODUCT_FROM_DATABASE=3c595 100BaseTX [Vortex] + +pci:v000010B7d00005951* + ID_PRODUCT_FROM_DATABASE=3c595 100BaseT4 [Vortex] + +pci:v000010B7d00005952* + ID_PRODUCT_FROM_DATABASE=3c595 100Base-MII [Vortex] + +pci:v000010B7d00005970* + ID_PRODUCT_FROM_DATABASE=3c597 EISA Fast Demon/Vortex + +pci:v000010B7d00005B57* + ID_PRODUCT_FROM_DATABASE=3c595 Megahertz 10/100 LAN CardBus [Boomerang] + +pci:v000010B7d00005B57sv000010B7sd00005B57* + ID_PRODUCT_FROM_DATABASE=3C575 Megahertz 10/100 LAN Cardbus PC Card + +pci:v000010B7d00006000* + ID_PRODUCT_FROM_DATABASE=3CRSHPW796 [OfficeConnect Wireless CardBus] + +pci:v000010B7d00006001* + ID_PRODUCT_FROM_DATABASE=3com 3CRWE154G72 [Office Connect Wireless LAN Adapter] + +pci:v000010B7d00006055* + ID_PRODUCT_FROM_DATABASE=3c556 Hurricane CardBus [Cyclone] + +pci:v000010B7d00006056* + ID_PRODUCT_FROM_DATABASE=3c556B CardBus [Tornado] + +pci:v000010B7d00006056sv000010B7sd00006556* + ID_PRODUCT_FROM_DATABASE=10/100 Mini PCI Ethernet Adapter + +pci:v000010B7d00006560* + ID_PRODUCT_FROM_DATABASE=3cCFE656 CardBus [Cyclone] + +pci:v000010B7d00006560sv000010B7sd0000656A* + ID_PRODUCT_FROM_DATABASE=3CCFEM656 10/100 LAN+56K Modem CardBus + +pci:v000010B7d00006561* + ID_PRODUCT_FROM_DATABASE=3cCFEM656 10/100 LAN+56K Modem CardBus + +pci:v000010B7d00006561sv000010B7sd0000656B* + ID_PRODUCT_FROM_DATABASE=3CCFEM656 10/100 LAN+56K Modem CardBus + +pci:v000010B7d00006562* + ID_PRODUCT_FROM_DATABASE=3cCFEM656B 10/100 LAN+Winmodem CardBus [Cyclone] + +pci:v000010B7d00006562sv000010B7sd0000656B* + ID_PRODUCT_FROM_DATABASE=3CCFEM656B 10/100 LAN+56K Modem CardBus + +pci:v000010B7d00006563* + ID_PRODUCT_FROM_DATABASE=3cCFEM656B 10/100 LAN+56K Modem CardBus + +pci:v000010B7d00006563sv000010B7sd0000656B* + ID_PRODUCT_FROM_DATABASE=3CCFEM656 10/100 LAN+56K Modem CardBus + +pci:v000010B7d00006564* + ID_PRODUCT_FROM_DATABASE=3cXFEM656C 10/100 LAN+Winmodem CardBus [Tornado] + +pci:v000010B7d00007646* + ID_PRODUCT_FROM_DATABASE=3cSOHO100-TX Hurricane + +pci:v000010B7d00007770* + ID_PRODUCT_FROM_DATABASE=3CRWE777 PCI(PLX) Wireless Adaptor [Airconnect] + +pci:v000010B7d00007940* + ID_PRODUCT_FROM_DATABASE=3c803 FDDILink UTP Controller + +pci:v000010B7d00007980* + ID_PRODUCT_FROM_DATABASE=3c804 FDDILink SAS Controller + +pci:v000010B7d00007990* + ID_PRODUCT_FROM_DATABASE=3c805 FDDILink DAS Controller + +pci:v000010B7d000080EB* + ID_PRODUCT_FROM_DATABASE=3c940B 10/100/1000Base-T + +pci:v000010B7d00008811* + ID_PRODUCT_FROM_DATABASE=Token ring + +pci:v000010B7d00009000* + ID_PRODUCT_FROM_DATABASE=3c900 10BaseT [Boomerang] + +pci:v000010B7d00009001* + ID_PRODUCT_FROM_DATABASE=3c900 10Mbps Combo [Boomerang] + +pci:v000010B7d00009004* + ID_PRODUCT_FROM_DATABASE=3c900B-TPO Etherlink XL [Cyclone] + +pci:v000010B7d00009004sv000010B7sd00009004* + ID_PRODUCT_FROM_DATABASE=3C900B-TPO Etherlink XL TPO 10Mb + +pci:v000010B7d00009005* + ID_PRODUCT_FROM_DATABASE=3c900B-Combo Etherlink XL [Cyclone] + +pci:v000010B7d00009005sv000010B7sd00009005* + ID_PRODUCT_FROM_DATABASE=3C900B-Combo Etherlink XL Combo + +pci:v000010B7d00009006* + ID_PRODUCT_FROM_DATABASE=3c900B-TPC Etherlink XL [Cyclone] + +pci:v000010B7d0000900A* + ID_PRODUCT_FROM_DATABASE=3c900B-FL 10base-FL [Cyclone] + +pci:v000010B7d00009050* + ID_PRODUCT_FROM_DATABASE=3c905 100BaseTX [Boomerang] + +pci:v000010B7d00009051* + ID_PRODUCT_FROM_DATABASE=3c905 100BaseT4 [Boomerang] + +pci:v000010B7d00009054* + ID_PRODUCT_FROM_DATABASE=3C905B-TX Fast Etherlink XL PCI + +pci:v000010B7d00009054sv000010B7sd00009054* + ID_PRODUCT_FROM_DATABASE=3C905B-TX Fast Etherlink XL PCI + +pci:v000010B7d00009055* + ID_PRODUCT_FROM_DATABASE=3c905B 100BaseTX [Cyclone] + +pci:v000010B7d00009055sv00001028sd00000080* + ID_PRODUCT_FROM_DATABASE=3C905B Fast Etherlink XL 10/100 + +pci:v000010B7d00009055sv00001028sd00000081* + ID_PRODUCT_FROM_DATABASE=3C905B Fast Etherlink XL 10/100 + +pci:v000010B7d00009055sv00001028sd00000082* + ID_PRODUCT_FROM_DATABASE=3C905B Fast Etherlink XL 10/100 + +pci:v000010B7d00009055sv00001028sd00000083* + ID_PRODUCT_FROM_DATABASE=3C905B Fast Etherlink XL 10/100 + +pci:v000010B7d00009055sv00001028sd00000084* + ID_PRODUCT_FROM_DATABASE=3C905B Fast Etherlink XL 10/100 + +pci:v000010B7d00009055sv00001028sd00000085* + ID_PRODUCT_FROM_DATABASE=3C905B Fast Etherlink XL 10/100 + +pci:v000010B7d00009055sv00001028sd00000086* + ID_PRODUCT_FROM_DATABASE=3C905B Fast Etherlink XL 10/100 + +pci:v000010B7d00009055sv00001028sd00000087* + ID_PRODUCT_FROM_DATABASE=3C905B Fast Etherlink XL 10/100 + +pci:v000010B7d00009055sv00001028sd00000088* + ID_PRODUCT_FROM_DATABASE=3C905B Fast Etherlink XL 10/100 + +pci:v000010B7d00009055sv00001028sd00000089* + ID_PRODUCT_FROM_DATABASE=3C905B Fast Etherlink XL 10/100 + +pci:v000010B7d00009055sv00001028sd00000090* + ID_PRODUCT_FROM_DATABASE=3C905B Fast Etherlink XL 10/100 + +pci:v000010B7d00009055sv00001028sd00000091* + ID_PRODUCT_FROM_DATABASE=3C905B Fast Etherlink XL 10/100 + +pci:v000010B7d00009055sv00001028sd00000092* + ID_PRODUCT_FROM_DATABASE=3C905B Fast Etherlink XL 10/100 + +pci:v000010B7d00009055sv00001028sd00000093* + ID_PRODUCT_FROM_DATABASE=3C905B Fast Etherlink XL 10/100 + +pci:v000010B7d00009055sv00001028sd00000094* + ID_PRODUCT_FROM_DATABASE=3C905B Fast Etherlink XL 10/100 + +pci:v000010B7d00009055sv00001028sd00000095* + ID_PRODUCT_FROM_DATABASE=3C905B Fast Etherlink XL 10/100 + +pci:v000010B7d00009055sv00001028sd00000096* + ID_PRODUCT_FROM_DATABASE=3C905B Fast Etherlink XL 10/100 + +pci:v000010B7d00009055sv00001028sd00000097* + ID_PRODUCT_FROM_DATABASE=3C905B Fast Etherlink XL 10/100 + +pci:v000010B7d00009055sv00001028sd00000098* + ID_PRODUCT_FROM_DATABASE=3C905B Fast Etherlink XL 10/100 + +pci:v000010B7d00009055sv00001028sd00000099* + ID_PRODUCT_FROM_DATABASE=3C905B Fast Etherlink XL 10/100 + +pci:v000010B7d00009055sv000010B7sd00009055* + ID_PRODUCT_FROM_DATABASE=3C905B Fast Etherlink XL 10/100 + +pci:v000010B7d00009056* + ID_PRODUCT_FROM_DATABASE=3c905B-T4 Fast EtherLink XL [Cyclone] + +pci:v000010B7d00009058* + ID_PRODUCT_FROM_DATABASE=3c905B Deluxe Etherlink 10/100/BNC [Cyclone] + +pci:v000010B7d0000905A* + ID_PRODUCT_FROM_DATABASE=3c905B-FX Fast Etherlink XL FX 100baseFx [Cyclone] + +pci:v000010B7d00009200* + ID_PRODUCT_FROM_DATABASE=3c905C-TX/TX-M [Tornado] + +pci:v000010B7d00009200sv00001028sd00000095* + ID_PRODUCT_FROM_DATABASE=3C920 Integrated Fast Ethernet Controller + +pci:v000010B7d00009200sv00001028sd00000097* + ID_PRODUCT_FROM_DATABASE=3C920 Integrated Fast Ethernet Controller + +pci:v000010B7d00009200sv00001028sd000000B4* + ID_PRODUCT_FROM_DATABASE=OptiPlex GX110 + +pci:v000010B7d00009200sv00001028sd000000D8* + ID_PRODUCT_FROM_DATABASE=Precision 530 + +pci:v000010B7d00009200sv00001028sd000000FE* + ID_PRODUCT_FROM_DATABASE=Optiplex GX240 + +pci:v000010B7d00009200sv00001028sd0000012A* + ID_PRODUCT_FROM_DATABASE=3C920 Integrated Fast Ethernet Controller [Latitude C640] + +pci:v000010B7d00009200sv000010B7sd00001000* + ID_PRODUCT_FROM_DATABASE=3C905CX-TX/TX-M Fast Etherlink for PC Management NIC + +pci:v000010B7d00009200sv000010B7sd00007000* + ID_PRODUCT_FROM_DATABASE=10/100 Mini PCI Ethernet Adapter + +pci:v000010B7d00009200sv000010F1sd00002466* + ID_PRODUCT_FROM_DATABASE=Tiger MPX S2466 (3C920 Integrated Fast Ethernet Controller) + +pci:v000010B7d00009200sv0000144Dsd0000C005* + ID_PRODUCT_FROM_DATABASE=X10 Laptop + +pci:v000010B7d00009201* + ID_PRODUCT_FROM_DATABASE=3C920B-EMB Integrated Fast Ethernet Controller [Tornado] + +pci:v000010B7d00009201sv00001043sd000080AB* + ID_PRODUCT_FROM_DATABASE=A7N8X Deluxe onboard 3C920B-EMB Integrated Fast Ethernet Controller + +pci:v000010B7d00009202* + ID_PRODUCT_FROM_DATABASE=3Com 3C920B-EMB-WNM Integrated Fast Ethernet Controller + +pci:v000010B7d00009210* + ID_PRODUCT_FROM_DATABASE=3C920B-EMB-WNM Integrated Fast Ethernet Controller + +pci:v000010B7d00009300* + ID_PRODUCT_FROM_DATABASE=3CSOHO100B-TX 910-A01 [tulip] + +pci:v000010B7d00009800* + ID_PRODUCT_FROM_DATABASE=3c980-TX Fast Etherlink XL Server Adapter [Cyclone] + +pci:v000010B7d00009800sv000010B7sd00009800* + ID_PRODUCT_FROM_DATABASE=3c980-TX Fast Etherlink XL Server Adapter + +pci:v000010B7d00009805* + ID_PRODUCT_FROM_DATABASE=3c980-C 10/100baseTX NIC [Python-T] + +pci:v000010B7d00009805sv000010B7sd00001201* + ID_PRODUCT_FROM_DATABASE=EtherLink Server 10/100 Dual Port A + +pci:v000010B7d00009805sv000010B7sd00001202* + ID_PRODUCT_FROM_DATABASE=EtherLink Server 10/100 Dual Port B + +pci:v000010B7d00009805sv000010B7sd00009805* + ID_PRODUCT_FROM_DATABASE=3c980 10/100baseTX NIC [Python-T] + +pci:v000010B7d00009805sv000010F1sd00002462* + ID_PRODUCT_FROM_DATABASE=Thunder K7 S2462 + +pci:v000010B7d00009900* + ID_PRODUCT_FROM_DATABASE=3C990-TX [Typhoon] + +pci:v000010B7d00009902* + ID_PRODUCT_FROM_DATABASE=3CR990-TX-95 [Typhoon 56-bit] + +pci:v000010B7d00009903* + ID_PRODUCT_FROM_DATABASE=3CR990-TX-97 [Typhoon 168-bit] + +pci:v000010B7d00009904* + ID_PRODUCT_FROM_DATABASE=3C990B-TX-M/3C990BSVR [Typhoon2] + +pci:v000010B7d00009904sv000010B7sd00001000* + ID_PRODUCT_FROM_DATABASE=3CR990B-TX-M [Typhoon2] + +pci:v000010B7d00009904sv000010B7sd00002000* + ID_PRODUCT_FROM_DATABASE=3CR990BSVR [Typhoon2 Server] + +pci:v000010B7d00009905* + ID_PRODUCT_FROM_DATABASE=3CR990-FX-95/97/95 [Typhon Fiber] + +pci:v000010B7d00009905sv000010B7sd00001101* + ID_PRODUCT_FROM_DATABASE=3CR990-FX-95 [Typhoon Fiber 56-bit] + +pci:v000010B7d00009905sv000010B7sd00001102* + ID_PRODUCT_FROM_DATABASE=3CR990-FX-97 [Typhoon Fiber 168-bit] + +pci:v000010B7d00009905sv000010B7sd00002101* + ID_PRODUCT_FROM_DATABASE=3CR990-FX-95 Server [Typhoon Fiber 56-bit] + +pci:v000010B7d00009905sv000010B7sd00002102* + ID_PRODUCT_FROM_DATABASE=3CR990-FX-97 Server [Typhoon Fiber 168-bit] + +pci:v000010B7d00009908* + ID_PRODUCT_FROM_DATABASE=3CR990SVR95 [Typhoon Server 56-bit] + +pci:v000010B7d00009909* + ID_PRODUCT_FROM_DATABASE=3CR990SVR97 [Typhoon Server 168-bit] + +pci:v000010B7d0000990A* + ID_PRODUCT_FROM_DATABASE=3C990SVR [Typhoon Server] + +pci:v000010B7d0000990B* + ID_PRODUCT_FROM_DATABASE=3C990SVR [Typhoon Server] + +pci:v000010B8* + ID_VENDOR_FROM_DATABASE=Standard Microsystems Corp [SMC] + +pci:v000010B8d00000005* + ID_PRODUCT_FROM_DATABASE=83c170 EPIC/100 Fast Ethernet Adapter + +pci:v000010B8d00000005sv00001055sd0000E000* + ID_PRODUCT_FROM_DATABASE=LANEPIC 10/100 [EVB171Q-PCI] + +pci:v000010B8d00000005sv00001055sd0000E002* + ID_PRODUCT_FROM_DATABASE=LANEPIC 10/100 [EVB171G-PCI] + +pci:v000010B8d00000005sv000010B8sd0000A011* + ID_PRODUCT_FROM_DATABASE=EtherPower II 10/100 + +pci:v000010B8d00000005sv000010B8sd0000A014* + ID_PRODUCT_FROM_DATABASE=EtherPower II 10/100 + +pci:v000010B8d00000005sv000010B8sd0000A015* + ID_PRODUCT_FROM_DATABASE=EtherPower II 10/100 + +pci:v000010B8d00000005sv000010B8sd0000A016* + ID_PRODUCT_FROM_DATABASE=EtherPower II 10/100 + +pci:v000010B8d00000005sv000010B8sd0000A017* + ID_PRODUCT_FROM_DATABASE=EtherPower II 10/100 + +pci:v000010B8d00000006* + ID_PRODUCT_FROM_DATABASE=83c175 EPIC/100 Fast Ethernet Adapter + +pci:v000010B8d00000006sv00001055sd0000E100* + ID_PRODUCT_FROM_DATABASE=LANEPIC Cardbus Fast Ethernet Adapter + +pci:v000010B8d00000006sv00001055sd0000E102* + ID_PRODUCT_FROM_DATABASE=LANEPIC Cardbus Fast Ethernet Adapter + +pci:v000010B8d00000006sv00001055sd0000E300* + ID_PRODUCT_FROM_DATABASE=LANEPIC Cardbus Fast Ethernet Adapter + +pci:v000010B8d00000006sv00001055sd0000E302* + ID_PRODUCT_FROM_DATABASE=LANEPIC Cardbus Fast Ethernet Adapter + +pci:v000010B8d00000006sv000010B8sd0000A012* + ID_PRODUCT_FROM_DATABASE=LANEPIC Cardbus Fast Ethernet Adapter + +pci:v000010B8d00000006sv000013A2sd00008002* + ID_PRODUCT_FROM_DATABASE=LANEPIC Cardbus Fast Ethernet Adapter + +pci:v000010B8d00000006sv000013A2sd00008006* + ID_PRODUCT_FROM_DATABASE=LANEPIC Cardbus Fast Ethernet Adapter + +pci:v000010B8d00001000* + ID_PRODUCT_FROM_DATABASE=FDC 37c665 + +pci:v000010B8d00001001* + ID_PRODUCT_FROM_DATABASE=FDC 37C922 + +pci:v000010B8d0000A011* + ID_PRODUCT_FROM_DATABASE=83C170QF + +pci:v000010B8d0000B106* + ID_PRODUCT_FROM_DATABASE=SMC34C90 + +pci:v000010B9* + ID_VENDOR_FROM_DATABASE=ULi Electronics Inc. + +pci:v000010B9d00000101* + ID_PRODUCT_FROM_DATABASE=CMI8338/C3DX PCI Audio Device + +pci:v000010B9d00000111* + ID_PRODUCT_FROM_DATABASE=C-Media CMI8738/C3DX Audio Device (OEM) + +pci:v000010B9d00000111sv000010B9sd00000111* + ID_PRODUCT_FROM_DATABASE=C-Media CMI8738/C3DX Audio Device (OEM) + +pci:v000010B9d00000780* + ID_PRODUCT_FROM_DATABASE=Multi-IO Card + +pci:v000010B9d00000782* + ID_PRODUCT_FROM_DATABASE=Multi-IO Card + +pci:v000010B9d00001435* + ID_PRODUCT_FROM_DATABASE=M1435 + +pci:v000010B9d00001445* + ID_PRODUCT_FROM_DATABASE=M1445 + +pci:v000010B9d00001449* + ID_PRODUCT_FROM_DATABASE=M1449 + +pci:v000010B9d00001451* + ID_PRODUCT_FROM_DATABASE=M1451 + +pci:v000010B9d00001461* + ID_PRODUCT_FROM_DATABASE=M1461 + +pci:v000010B9d00001489* + ID_PRODUCT_FROM_DATABASE=M1489 + +pci:v000010B9d00001511* + ID_PRODUCT_FROM_DATABASE=M1511 [Aladdin] + +pci:v000010B9d00001512* + ID_PRODUCT_FROM_DATABASE=M1512 [Aladdin] + +pci:v000010B9d00001513* + ID_PRODUCT_FROM_DATABASE=M1513 [Aladdin] + +pci:v000010B9d00001521* + ID_PRODUCT_FROM_DATABASE=M1521 [Aladdin III] + +pci:v000010B9d00001521sv000010B9sd00001521* + ID_PRODUCT_FROM_DATABASE=ALI M1521 Aladdin III CPU Bridge + +pci:v000010B9d00001523* + ID_PRODUCT_FROM_DATABASE=M1523 + +pci:v000010B9d00001523sv000010B9sd00001523* + ID_PRODUCT_FROM_DATABASE=ALI M1523 ISA Bridge + +pci:v000010B9d00001531* + ID_PRODUCT_FROM_DATABASE=M1531 [Aladdin IV] + +pci:v000010B9d00001533* + ID_PRODUCT_FROM_DATABASE=M1533/M1535/M1543 PCI to ISA Bridge [Aladdin IV/V/V+] + +pci:v000010B9d00001533sv00001014sd0000053B* + ID_PRODUCT_FROM_DATABASE=ThinkPad R40e + +pci:v000010B9d00001533sv000010B9sd00001533* + ID_PRODUCT_FROM_DATABASE=ALi M1533 Aladdin IV/V ISA Bridge + +pci:v000010B9d00001541* + ID_PRODUCT_FROM_DATABASE=M1541 + +pci:v000010B9d00001541sv000010B9sd00001541* + ID_PRODUCT_FROM_DATABASE=ALI M1541 Aladdin V/V+ AGP System Controller + +pci:v000010B9d00001543* + ID_PRODUCT_FROM_DATABASE=M1543 + +pci:v000010B9d00001563* + ID_PRODUCT_FROM_DATABASE=M1563 HyperTransport South Bridge + +pci:v000010B9d00001563sv000010B9sd00001563* + ID_PRODUCT_FROM_DATABASE=ASRock 939Dual-SATA2 Motherboard + +pci:v000010B9d00001563sv00001849sd00001563* + ID_PRODUCT_FROM_DATABASE=ASRock 939Dual-SATA2 Motherboard + +pci:v000010B9d00001573* + ID_PRODUCT_FROM_DATABASE=PCI to LPC Controller + +pci:v000010B9d00001575* + ID_PRODUCT_FROM_DATABASE=M1575 South Bridge + +pci:v000010B9d00001621* + ID_PRODUCT_FROM_DATABASE=M1621 + +pci:v000010B9d00001631* + ID_PRODUCT_FROM_DATABASE=ALI M1631 PCI North Bridge Aladdin Pro III + +pci:v000010B9d00001632* + ID_PRODUCT_FROM_DATABASE=M1632M Northbridge+Trident + +pci:v000010B9d00001641* + ID_PRODUCT_FROM_DATABASE=ALI M1641 PCI North Bridge Aladdin Pro IV + +pci:v000010B9d00001644* + ID_PRODUCT_FROM_DATABASE=M1644/M1644T Northbridge+Trident + +pci:v000010B9d00001646* + ID_PRODUCT_FROM_DATABASE=M1646 Northbridge+Trident + +pci:v000010B9d00001647* + ID_PRODUCT_FROM_DATABASE=M1647 Northbridge [MAGiK 1 / MobileMAGiK 1] + +pci:v000010B9d00001651* + ID_PRODUCT_FROM_DATABASE=M1651/M1651T Northbridge [Aladdin-Pro 5/5M,Aladdin-Pro 5T/5TM] + +pci:v000010B9d00001671* + ID_PRODUCT_FROM_DATABASE=M1671 Super P4 Northbridge [AGP4X,PCI and SDR/DDR] + +pci:v000010B9d00001672* + ID_PRODUCT_FROM_DATABASE=M1672 Northbridge [CyberALADDiN-P4] + +pci:v000010B9d00001681* + ID_PRODUCT_FROM_DATABASE=M1681 P4 Northbridge [AGP8X,HyperTransport and SDR/DDR] + +pci:v000010B9d00001687* + ID_PRODUCT_FROM_DATABASE=M1687 K8 Northbridge [AGP8X and HyperTransport] + +pci:v000010B9d00001689* + ID_PRODUCT_FROM_DATABASE=M1689 K8 Northbridge [Super K8 Single Chip] + +pci:v000010B9d00001695* + ID_PRODUCT_FROM_DATABASE=M1695 K8 Northbridge [PCI Express and HyperTransport] + +pci:v000010B9d00001697* + ID_PRODUCT_FROM_DATABASE=M1697 HTT Host Bridge + +pci:v000010B9d00003141* + ID_PRODUCT_FROM_DATABASE=M3141 + +pci:v000010B9d00003143* + ID_PRODUCT_FROM_DATABASE=M3143 + +pci:v000010B9d00003145* + ID_PRODUCT_FROM_DATABASE=M3145 + +pci:v000010B9d00003147* + ID_PRODUCT_FROM_DATABASE=M3147 + +pci:v000010B9d00003149* + ID_PRODUCT_FROM_DATABASE=M3149 + +pci:v000010B9d00003151* + ID_PRODUCT_FROM_DATABASE=M3151 + +pci:v000010B9d00003307* + ID_PRODUCT_FROM_DATABASE=M3307 + +pci:v000010B9d00003309* + ID_PRODUCT_FROM_DATABASE=M3309 + +pci:v000010B9d00003323* + ID_PRODUCT_FROM_DATABASE=M3325 Video/Audio Decoder + +pci:v000010B9d00005212* + ID_PRODUCT_FROM_DATABASE=M4803 + +pci:v000010B9d00005215* + ID_PRODUCT_FROM_DATABASE=MS4803 + +pci:v000010B9d00005217* + ID_PRODUCT_FROM_DATABASE=M5217H + +pci:v000010B9d00005219* + ID_PRODUCT_FROM_DATABASE=M5219 + +pci:v000010B9d00005225* + ID_PRODUCT_FROM_DATABASE=M5225 + +pci:v000010B9d00005228* + ID_PRODUCT_FROM_DATABASE=M5228 ALi ATA/RAID Controller + +pci:v000010B9d00005229* + ID_PRODUCT_FROM_DATABASE=M5229 IDE + +pci:v000010B9d00005229sv00001014sd0000050F* + ID_PRODUCT_FROM_DATABASE=ThinkPad R30 + +pci:v000010B9d00005229sv00001014sd0000053D* + ID_PRODUCT_FROM_DATABASE=ThinkPad R40e + +pci:v000010B9d00005229sv0000103Csd00000024* + ID_PRODUCT_FROM_DATABASE=Pavilion ze4400 builtin IDE + +pci:v000010B9d00005229sv0000103Csd00000025* + ID_PRODUCT_FROM_DATABASE=XE4500 Notebook + +pci:v000010B9d00005229sv00001043sd00008053* + ID_PRODUCT_FROM_DATABASE=A7A266 Motherboard IDE + +pci:v000010B9d00005229sv00001849sd00005229* + ID_PRODUCT_FROM_DATABASE=ASRock 939Dual-SATA2 Motherboard IDE (PATA) + +pci:v000010B9d00005235* + ID_PRODUCT_FROM_DATABASE=M5225 + +pci:v000010B9d00005237* + ID_PRODUCT_FROM_DATABASE=USB 1.1 Controller + +pci:v000010B9d00005237sv00001014sd00000540* + ID_PRODUCT_FROM_DATABASE=ThinkPad R40e + +pci:v000010B9d00005237sv0000103Csd00000024* + ID_PRODUCT_FROM_DATABASE=Pavilion ze4400 builtin USB + +pci:v000010B9d00005237sv0000103Csd00000025* + ID_PRODUCT_FROM_DATABASE=XE4500 Notebook + +pci:v000010B9d00005237sv0000104Dsd0000810F* + ID_PRODUCT_FROM_DATABASE=VAIO PCG-U1 USB/OHCI Revision 1.0 + +pci:v000010B9d00005237sv000010B9sd00005237* + ID_PRODUCT_FROM_DATABASE=ASRock 939Dual-SATA2 Motherboard + +pci:v000010B9d00005237sv00001849sd00005237* + ID_PRODUCT_FROM_DATABASE=ASRock 939Dual-SATA2 Motherboard + +pci:v000010B9d00005239* + ID_PRODUCT_FROM_DATABASE=USB 2.0 Controller + +pci:v000010B9d00005239sv000010B9sd00005239* + ID_PRODUCT_FROM_DATABASE=ASRock 939Dual-SATA2 Motherboard + +pci:v000010B9d00005239sv00001849sd00005239* + ID_PRODUCT_FROM_DATABASE=ASRock 939Dual-SATA2 Motherboard + +pci:v000010B9d00005243* + ID_PRODUCT_FROM_DATABASE=M1541 PCI to AGP Controller + +pci:v000010B9d00005246* + ID_PRODUCT_FROM_DATABASE=AGP8X Controller + +pci:v000010B9d00005247* + ID_PRODUCT_FROM_DATABASE=PCI to AGP Controller + +pci:v000010B9d00005249* + ID_PRODUCT_FROM_DATABASE=M5249 HTT to PCI Bridge + +pci:v000010B9d0000524B* + ID_PRODUCT_FROM_DATABASE=PCI Express Root Port + +pci:v000010B9d0000524C* + ID_PRODUCT_FROM_DATABASE=PCI Express Root Port + +pci:v000010B9d0000524D* + ID_PRODUCT_FROM_DATABASE=PCI Express Root Port + +pci:v000010B9d0000524E* + ID_PRODUCT_FROM_DATABASE=PCI Express Root Port + +pci:v000010B9d00005251* + ID_PRODUCT_FROM_DATABASE=M5251 P1394 OHCI 1.0 Controller + +pci:v000010B9d00005253* + ID_PRODUCT_FROM_DATABASE=M5253 P1394 OHCI 1.1 Controller + +pci:v000010B9d00005261* + ID_PRODUCT_FROM_DATABASE=M5261 Ethernet Controller + +pci:v000010B9d00005263* + ID_PRODUCT_FROM_DATABASE=ULi 1689,1573 integrated ethernet. + +pci:v000010B9d00005281* + ID_PRODUCT_FROM_DATABASE=ALi M5281 Serial ATA / RAID Host Controller + +pci:v000010B9d00005287* + ID_PRODUCT_FROM_DATABASE=ULi 5287 SATA + +pci:v000010B9d00005288* + ID_PRODUCT_FROM_DATABASE=ULi M5288 SATA + +pci:v000010B9d00005288sv00001043sd00008056* + ID_PRODUCT_FROM_DATABASE=A8R-MVP Mainboard + +pci:v000010B9d00005289* + ID_PRODUCT_FROM_DATABASE=ULi 5289 SATA + +pci:v000010B9d00005450* + ID_PRODUCT_FROM_DATABASE=Lucent Technologies Soft Modem AMR + +pci:v000010B9d00005451* + ID_PRODUCT_FROM_DATABASE=M5451 PCI AC-Link Controller Audio Device + +pci:v000010B9d00005451sv00001014sd00000506* + ID_PRODUCT_FROM_DATABASE=ThinkPad R30 + +pci:v000010B9d00005451sv00001014sd0000053E* + ID_PRODUCT_FROM_DATABASE=ThinkPad R40e + +pci:v000010B9d00005451sv0000103Csd00000024* + ID_PRODUCT_FROM_DATABASE=Pavilion ze4400 builtin Audio + +pci:v000010B9d00005451sv0000103Csd00000025* + ID_PRODUCT_FROM_DATABASE=XE4500 Notebook + +pci:v000010B9d00005453* + ID_PRODUCT_FROM_DATABASE=M5453 PCI AC-Link Controller Modem Device + +pci:v000010B9d00005455* + ID_PRODUCT_FROM_DATABASE=M5455 PCI AC-Link Controller Audio Device + +pci:v000010B9d00005455sv000010B9sd00005455* + ID_PRODUCT_FROM_DATABASE=ASRock 939Dual-SATA2 Motherboard + +pci:v000010B9d00005455sv00001849sd00000850* + ID_PRODUCT_FROM_DATABASE=ASRock 939Dual-SATA2 Motherboard + +pci:v000010B9d00005457* + ID_PRODUCT_FROM_DATABASE=M5457 AC'97 Modem Controller + +pci:v000010B9d00005457sv00001014sd00000535* + ID_PRODUCT_FROM_DATABASE=ThinkPad R40e + +pci:v000010B9d00005457sv0000103Csd00000024* + ID_PRODUCT_FROM_DATABASE=Pavilion ze4400 builtin Modem Device + +pci:v000010B9d00005457sv0000103Csd00000025* + ID_PRODUCT_FROM_DATABASE=XE4500 Notebook + +pci:v000010B9d00005459* + ID_PRODUCT_FROM_DATABASE=SmartLink SmartPCI561 56K Modem + +pci:v000010B9d0000545A* + ID_PRODUCT_FROM_DATABASE=SmartLink SmartPCI563 56K Modem + +pci:v000010B9d00005461* + ID_PRODUCT_FROM_DATABASE=HD Audio Controller + +pci:v000010B9d00005471* + ID_PRODUCT_FROM_DATABASE=M5471 Memory Stick Controller + +pci:v000010B9d00005473* + ID_PRODUCT_FROM_DATABASE=M5473 SD-MMC Controller + +pci:v000010B9d00007101* + ID_PRODUCT_FROM_DATABASE=M7101 Power Management Controller [PMU] + +pci:v000010B9d00007101sv00001014sd00000510* + ID_PRODUCT_FROM_DATABASE=ThinkPad R30 + +pci:v000010B9d00007101sv00001014sd0000053C* + ID_PRODUCT_FROM_DATABASE=ThinkPad R40e + +pci:v000010B9d00007101sv0000103Csd00000024* + ID_PRODUCT_FROM_DATABASE=Pavilion ze4400 + +pci:v000010B9d00007101sv0000103Csd00000025* + ID_PRODUCT_FROM_DATABASE=XE4500 Notebook + +pci:v000010B9d00007101sv00001849sd00007101* + ID_PRODUCT_FROM_DATABASE=ASRock 939Dual-SATA2 Motherboard + +pci:v000010BA* + ID_VENDOR_FROM_DATABASE=Mitsubishi Electric Corp. + +pci:v000010BAd00000301* + ID_PRODUCT_FROM_DATABASE=AccelGraphics AccelECLIPSE + +pci:v000010BAd00000304* + ID_PRODUCT_FROM_DATABASE=AccelGALAXY A2100 [OEM Evans & Sutherland] + +pci:v000010BAd00000308* + ID_PRODUCT_FROM_DATABASE=Tornado 3000 [OEM Evans & Sutherland] + +pci:v000010BAd00000308sv000010DDsd00000024* + ID_PRODUCT_FROM_DATABASE=Tornado 3000 + +pci:v000010BAd00001002* + ID_PRODUCT_FROM_DATABASE=VG500 [VolumePro Volume Rendering Accelerator] + +pci:v000010BB* + ID_VENDOR_FROM_DATABASE=Dapha Electronics Corporation + +pci:v000010BC* + ID_VENDOR_FROM_DATABASE=Advanced Logic Research + +pci:v000010BD* + ID_VENDOR_FROM_DATABASE=Surecom Technology + +pci:v000010BDd00000E34* + ID_PRODUCT_FROM_DATABASE=NE-34 + +pci:v000010BE* + ID_VENDOR_FROM_DATABASE=Tseng Labs International Co. + +pci:v000010BF* + ID_VENDOR_FROM_DATABASE=Most Inc + +pci:v000010C0* + ID_VENDOR_FROM_DATABASE=Boca Research Inc. + +pci:v000010C1* + ID_VENDOR_FROM_DATABASE=ICM Co., Ltd. + +pci:v000010C2* + ID_VENDOR_FROM_DATABASE=Auspex Systems Inc. + +pci:v000010C3* + ID_VENDOR_FROM_DATABASE=Samsung Semiconductors, Inc. + +pci:v000010C3d00001100* + ID_PRODUCT_FROM_DATABASE=Smartether100 SC1100 LAN Adapter (i82557B) + +pci:v000010C4* + ID_VENDOR_FROM_DATABASE=Award Software International Inc. + +pci:v000010C5* + ID_VENDOR_FROM_DATABASE=Xerox Corporation + +pci:v000010C6* + ID_VENDOR_FROM_DATABASE=Rambus Inc. + +pci:v000010C7* + ID_VENDOR_FROM_DATABASE=Media Vision + +pci:v000010C8* + ID_VENDOR_FROM_DATABASE=Neomagic Corporation + +pci:v000010C8d00000001* + ID_PRODUCT_FROM_DATABASE=NM2070 [MagicGraph 128] + +pci:v000010C8d00000002* + ID_PRODUCT_FROM_DATABASE=NM2090 [MagicGraph 128V] + +pci:v000010C8d00000003* + ID_PRODUCT_FROM_DATABASE=NM2093 [MagicGraph 128ZV] + +pci:v000010C8d00000004* + ID_PRODUCT_FROM_DATABASE=NM2160 [MagicGraph 128XD] + +pci:v000010C8d00000004sv00001014sd000000BA* + ID_PRODUCT_FROM_DATABASE=MagicGraph 128XD + +pci:v000010C8d00000004sv00001025sd00001007* + ID_PRODUCT_FROM_DATABASE=MagicGraph 128XD + +pci:v000010C8d00000004sv00001028sd00000074* + ID_PRODUCT_FROM_DATABASE=MagicGraph 128XD + +pci:v000010C8d00000004sv00001028sd00000075* + ID_PRODUCT_FROM_DATABASE=MagicGraph 128XD + +pci:v000010C8d00000004sv00001028sd0000007D* + ID_PRODUCT_FROM_DATABASE=MagicGraph 128XD + +pci:v000010C8d00000004sv00001028sd0000007E* + ID_PRODUCT_FROM_DATABASE=MagicGraph 128XD + +pci:v000010C8d00000004sv00001033sd0000802F* + ID_PRODUCT_FROM_DATABASE=MagicGraph 128XD + +pci:v000010C8d00000004sv0000104Dsd0000801B* + ID_PRODUCT_FROM_DATABASE=MagicGraph 128XD + +pci:v000010C8d00000004sv0000104Dsd0000802F* + ID_PRODUCT_FROM_DATABASE=MagicGraph 128XD + +pci:v000010C8d00000004sv0000104Dsd0000830B* + ID_PRODUCT_FROM_DATABASE=MagicGraph 128XD + +pci:v000010C8d00000004sv000010BAsd00000E00* + ID_PRODUCT_FROM_DATABASE=MagicGraph 128XD + +pci:v000010C8d00000004sv000010C8sd00000004* + ID_PRODUCT_FROM_DATABASE=MagicGraph 128XD + +pci:v000010C8d00000004sv000010CFsd00001029* + ID_PRODUCT_FROM_DATABASE=MagicGraph 128XD + +pci:v000010C8d00000004sv000010F7sd00008308* + ID_PRODUCT_FROM_DATABASE=MagicGraph 128XD + +pci:v000010C8d00000004sv000010F7sd00008309* + ID_PRODUCT_FROM_DATABASE=MagicGraph 128XD + +pci:v000010C8d00000004sv000010F7sd0000830B* + ID_PRODUCT_FROM_DATABASE=MagicGraph 128XD + +pci:v000010C8d00000004sv000010F7sd0000830D* + ID_PRODUCT_FROM_DATABASE=MagicGraph 128XD + +pci:v000010C8d00000004sv000010F7sd00008312* + ID_PRODUCT_FROM_DATABASE=MagicGraph 128XD + +pci:v000010C8d00000005* + ID_PRODUCT_FROM_DATABASE=NM2200 [MagicGraph 256AV] + +pci:v000010C8d00000005sv00001014sd000000DD* + ID_PRODUCT_FROM_DATABASE=ThinkPad 570 + +pci:v000010C8d00000005sv00001028sd00000088* + ID_PRODUCT_FROM_DATABASE=Latitude CPi A + +pci:v000010C8d00000006* + ID_PRODUCT_FROM_DATABASE=NM2360 [MagicMedia 256ZX] + +pci:v000010C8d00000006sv00001014sd00000152* + ID_PRODUCT_FROM_DATABASE=ThinkPad 600X + +pci:v000010C8d00000016* + ID_PRODUCT_FROM_DATABASE=NM2380 [MagicMedia 256XL+] + +pci:v000010C8d00000016sv000010C8sd00000016* + ID_PRODUCT_FROM_DATABASE=MagicMedia 256XL+ + +pci:v000010C8d00000025* + ID_PRODUCT_FROM_DATABASE=NM2230 [MagicGraph 256AV+] + +pci:v000010C8d00000083* + ID_PRODUCT_FROM_DATABASE=NM2093 [MagicGraph 128ZV+] + +pci:v000010C8d00008005* + ID_PRODUCT_FROM_DATABASE=NM2200 [MagicMedia 256AV Audio] + +pci:v000010C8d00008005sv00000E11sd0000B0D1* + ID_PRODUCT_FROM_DATABASE=MagicMedia 256AV Audio Device on Discovery + +pci:v000010C8d00008005sv00000E11sd0000B126* + ID_PRODUCT_FROM_DATABASE=MagicMedia 256AV Audio Device on Durango + +pci:v000010C8d00008005sv00001014sd000000DD* + ID_PRODUCT_FROM_DATABASE=ThinkPad 390/i1720/i1721 + +pci:v000010C8d00008005sv00001025sd00001003* + ID_PRODUCT_FROM_DATABASE=MagicMedia 256AV Audio Device on TravelMate 720 + +pci:v000010C8d00008005sv00001028sd00000088* + ID_PRODUCT_FROM_DATABASE=Latitude CPi A + +pci:v000010C8d00008005sv00001028sd0000008F* + ID_PRODUCT_FROM_DATABASE=MagicMedia 256AV Audio Device on Colorado Inspiron + +pci:v000010C8d00008005sv0000103Csd00000007* + ID_PRODUCT_FROM_DATABASE=MagicMedia 256AV Audio Device on Voyager II + +pci:v000010C8d00008005sv0000103Csd00000008* + ID_PRODUCT_FROM_DATABASE=MagicMedia 256AV Audio Device on Voyager III + +pci:v000010C8d00008005sv0000103Csd0000000D* + ID_PRODUCT_FROM_DATABASE=MagicMedia 256AV Audio Device on Omnibook 900 + +pci:v000010C8d00008005sv000010C8sd00008005* + ID_PRODUCT_FROM_DATABASE=MagicMedia 256AV Audio Device on FireAnt + +pci:v000010C8d00008005sv0000110Asd00008005* + ID_PRODUCT_FROM_DATABASE=MagicMedia 256AV Audio Device + +pci:v000010C8d00008005sv000014C0sd00000004* + ID_PRODUCT_FROM_DATABASE=MagicMedia 256AV Audio Device + +pci:v000010C8d00008006* + ID_PRODUCT_FROM_DATABASE=NM2360 [MagicMedia 256ZX Audio] + +pci:v000010C8d00008016* + ID_PRODUCT_FROM_DATABASE=NM2380 [MagicMedia 256XL+ Audio] + +pci:v000010C9* + ID_VENDOR_FROM_DATABASE=Dataexpert Corporation + +pci:v000010CA* + ID_VENDOR_FROM_DATABASE=Fujitsu Microelectr., Inc. + +pci:v000010CB* + ID_VENDOR_FROM_DATABASE=Omron Corporation + +pci:v000010CC* + ID_VENDOR_FROM_DATABASE=Mai Logic Incorporated + +pci:v000010CCd00000660* + ID_PRODUCT_FROM_DATABASE=Articia S Host Bridge + +pci:v000010CCd00000661* + ID_PRODUCT_FROM_DATABASE=Articia S PCI Bridge + +pci:v000010CD* + ID_VENDOR_FROM_DATABASE=Advanced System Products, Inc + +pci:v000010CDd00001100* + ID_PRODUCT_FROM_DATABASE=ASC1100 + +pci:v000010CDd00001200* + ID_PRODUCT_FROM_DATABASE=ASC1200 [(abp940) Fast SCSI-II] + +pci:v000010CDd00001300* + ID_PRODUCT_FROM_DATABASE=ABP940-U / ABP960-U + +pci:v000010CDd00001300sv000010CDsd00001310* + ID_PRODUCT_FROM_DATABASE=ASC1300 SCSI Adapter + +pci:v000010CDd00001300sv00001195sd00001320* + ID_PRODUCT_FROM_DATABASE=Ultra-SCSI CardBus PC Card REX CB31 + +pci:v000010CDd00002300* + ID_PRODUCT_FROM_DATABASE=ABP940-UW + +pci:v000010CDd00002500* + ID_PRODUCT_FROM_DATABASE=ABP940-U2W + +pci:v000010CDd00002700* + ID_PRODUCT_FROM_DATABASE=ABP3950-U3W + +pci:v000010CE* + ID_VENDOR_FROM_DATABASE=Radius + +pci:v000010CF* + ID_VENDOR_FROM_DATABASE=Fujitsu Limited. + +pci:v000010CFd000001EF* + ID_PRODUCT_FROM_DATABASE=PCEA4 PCI-Express Dual Port ESCON Adapter + +pci:v000010CFd00001414* + ID_PRODUCT_FROM_DATABASE=On-board USB 1.1 companion controller + +pci:v000010CFd00001415* + ID_PRODUCT_FROM_DATABASE=On-board USB 2.0 EHCI controller + +pci:v000010CFd00001422* + ID_PRODUCT_FROM_DATABASE=E8410 nVidia graphics adapter + +pci:v000010CFd0000142D* + ID_PRODUCT_FROM_DATABASE=HD audio (Realtek ALC262) + +pci:v000010CFd00001430* + ID_PRODUCT_FROM_DATABASE=82566MM Intel 1Gb copper LAN interface + +pci:v000010CFd00001623* + ID_PRODUCT_FROM_DATABASE=PCEA4 PCI-Express Dual Port ESCON Adapter + +pci:v000010CFd00002001* + ID_PRODUCT_FROM_DATABASE=mb86605 + +pci:v000010CFd0000200C* + ID_PRODUCT_FROM_DATABASE=MB86613L IEEE1394 OHCI 1.0 Controller + +pci:v000010CFd00002010* + ID_PRODUCT_FROM_DATABASE=MB86613S IEEE1394 OHCI 1.1 Controller + +pci:v000010CFd00002019* + ID_PRODUCT_FROM_DATABASE=MB86295S [CORAL P] + +pci:v000010CFd0000201E* + ID_PRODUCT_FROM_DATABASE=MB86296S [CORAL PA] + +pci:v000010CFd0000202B* + ID_PRODUCT_FROM_DATABASE=MB86297A [Carmine Graphics Controller] + +pci:v000010D1* + ID_VENDOR_FROM_DATABASE=FuturePlus Systems Corp. + +pci:v000010D2* + ID_VENDOR_FROM_DATABASE=Molex Incorporated + +pci:v000010D3* + ID_VENDOR_FROM_DATABASE=Jabil Circuit Inc + +pci:v000010D4* + ID_VENDOR_FROM_DATABASE=Hualon Microelectronics + +pci:v000010D5* + ID_VENDOR_FROM_DATABASE=Autologic Inc. + +pci:v000010D6* + ID_VENDOR_FROM_DATABASE=Cetia + +pci:v000010D7* + ID_VENDOR_FROM_DATABASE=BCM Advanced Research + +pci:v000010D8* + ID_VENDOR_FROM_DATABASE=Advanced Peripherals Labs + +pci:v000010D9* + ID_VENDOR_FROM_DATABASE=Macronix, Inc. [MXIC] + +pci:v000010D9d00000431* + ID_PRODUCT_FROM_DATABASE=MX98715 + +pci:v000010D9d00000512* + ID_PRODUCT_FROM_DATABASE=MX98713 + +pci:v000010D9d00000531* + ID_PRODUCT_FROM_DATABASE=MX987x5 + +pci:v000010D9d00000531sv00001186sd00001200* + ID_PRODUCT_FROM_DATABASE=DFE-540TX ProFAST 10/100 Adapter + +pci:v000010D9d00008625* + ID_PRODUCT_FROM_DATABASE=MX86250 + +pci:v000010D9d00008626* + ID_PRODUCT_FROM_DATABASE=Macronix MX86251 + 3Dfx Voodoo Rush + +pci:v000010D9d00008888* + ID_PRODUCT_FROM_DATABASE=MX86200 + +pci:v000010DA* + ID_VENDOR_FROM_DATABASE=Compaq IPG-Austin + +pci:v000010DAd00000508* + ID_PRODUCT_FROM_DATABASE=TC4048 Token Ring 4/16 + +pci:v000010DAd00003390* + ID_PRODUCT_FROM_DATABASE=Tl3c3x9 + +pci:v000010DB* + ID_VENDOR_FROM_DATABASE=Rohm LSI Systems, Inc. + +pci:v000010DC* + ID_VENDOR_FROM_DATABASE=CERN/ECP/EDU + +pci:v000010DCd00000001* + ID_PRODUCT_FROM_DATABASE=STAR/RD24 SCI-PCI (PMC) + +pci:v000010DCd00000002* + ID_PRODUCT_FROM_DATABASE=TAR/RD24 SCI-PCI (PMC) + +pci:v000010DCd00000021* + ID_PRODUCT_FROM_DATABASE=HIPPI destination + +pci:v000010DCd00000022* + ID_PRODUCT_FROM_DATABASE=HIPPI source + +pci:v000010DCd000010DC* + ID_PRODUCT_FROM_DATABASE=ATT2C15-3 FPGA + +pci:v000010DD* + ID_VENDOR_FROM_DATABASE=Evans & Sutherland + +pci:v000010DDd00000100* + ID_PRODUCT_FROM_DATABASE=Lightning 1200 + +pci:v000010DDd00000100sv000010DDsd00000023* + ID_PRODUCT_FROM_DATABASE=Lightning 1200 15+16M + +pci:v000010DE* + ID_VENDOR_FROM_DATABASE=NVIDIA Corporation + +pci:v000010DEd00000008* + ID_PRODUCT_FROM_DATABASE=NV1 [EDGE 3D] + +pci:v000010DEd00000009* + ID_PRODUCT_FROM_DATABASE=NV1 [EDGE 3D] + +pci:v000010DEd00000020* + ID_PRODUCT_FROM_DATABASE=NV4 [RIVA TNT] + +pci:v000010DEd00000020sv00001043sd00000200* + ID_PRODUCT_FROM_DATABASE=V3400 TNT + +pci:v000010DEd00000020sv00001048sd00000C18* + ID_PRODUCT_FROM_DATABASE=Erazor II SGRAM + +pci:v000010DEd00000020sv00001048sd00000C19* + ID_PRODUCT_FROM_DATABASE=Erazor II + +pci:v000010DEd00000020sv00001048sd00000C1B* + ID_PRODUCT_FROM_DATABASE=Erazor II + +pci:v000010DEd00000020sv00001048sd00000C1C* + ID_PRODUCT_FROM_DATABASE=Erazor II + +pci:v000010DEd00000020sv00001092sd00000550* + ID_PRODUCT_FROM_DATABASE=Viper V550 + +pci:v000010DEd00000020sv00001092sd00000552* + ID_PRODUCT_FROM_DATABASE=Viper V550 + +pci:v000010DEd00000020sv00001092sd00004804* + ID_PRODUCT_FROM_DATABASE=Viper V550 + +pci:v000010DEd00000020sv00001092sd00004808* + ID_PRODUCT_FROM_DATABASE=Viper V550 + +pci:v000010DEd00000020sv00001092sd00004810* + ID_PRODUCT_FROM_DATABASE=Viper V550 + +pci:v000010DEd00000020sv00001092sd00004812* + ID_PRODUCT_FROM_DATABASE=Viper V550 + +pci:v000010DEd00000020sv00001092sd00004815* + ID_PRODUCT_FROM_DATABASE=Viper V550 + +pci:v000010DEd00000020sv00001092sd00004820* + ID_PRODUCT_FROM_DATABASE=Viper V550 with TV out + +pci:v000010DEd00000020sv00001092sd00004822* + ID_PRODUCT_FROM_DATABASE=Viper V550 + +pci:v000010DEd00000020sv00001092sd00004904* + ID_PRODUCT_FROM_DATABASE=Viper V550 + +pci:v000010DEd00000020sv00001092sd00004914* + ID_PRODUCT_FROM_DATABASE=Viper V550 + +pci:v000010DEd00000020sv00001092sd00008225* + ID_PRODUCT_FROM_DATABASE=Viper V550 + +pci:v000010DEd00000020sv000010B4sd0000273D* + ID_PRODUCT_FROM_DATABASE=Velocity 4400 + +pci:v000010DEd00000020sv000010B4sd0000273E* + ID_PRODUCT_FROM_DATABASE=Velocity 4400 + +pci:v000010DEd00000020sv000010B4sd00002740* + ID_PRODUCT_FROM_DATABASE=Velocity 4400 + +pci:v000010DEd00000020sv000010DEsd00000020* + ID_PRODUCT_FROM_DATABASE=Riva TNT + +pci:v000010DEd00000020sv00001102sd00001015* + ID_PRODUCT_FROM_DATABASE=Graphics Blaster CT6710 + +pci:v000010DEd00000020sv00001102sd00001016* + ID_PRODUCT_FROM_DATABASE=Graphics Blaster RIVA TNT + +pci:v000010DEd00000028* + ID_PRODUCT_FROM_DATABASE=NV5 [RIVA TNT2/TNT2 Pro] + +pci:v000010DEd00000028sv00001043sd00000200* + ID_PRODUCT_FROM_DATABASE=AGP-V3800 SGRAM + +pci:v000010DEd00000028sv00001043sd00000201* + ID_PRODUCT_FROM_DATABASE=AGP-V3800 SDRAM + +pci:v000010DEd00000028sv00001043sd00000205* + ID_PRODUCT_FROM_DATABASE=PCI-V3800 + +pci:v000010DEd00000028sv00001043sd00004000* + ID_PRODUCT_FROM_DATABASE=AGP-V3800PRO + +pci:v000010DEd00000028sv00001048sd00000C21* + ID_PRODUCT_FROM_DATABASE=Synergy II + +pci:v000010DEd00000028sv00001048sd00000C28* + ID_PRODUCT_FROM_DATABASE=Erazor III + +pci:v000010DEd00000028sv00001048sd00000C29* + ID_PRODUCT_FROM_DATABASE=Erazor III + +pci:v000010DEd00000028sv00001048sd00000C2A* + ID_PRODUCT_FROM_DATABASE=Erazor III + +pci:v000010DEd00000028sv00001048sd00000C2B* + ID_PRODUCT_FROM_DATABASE=Erazor III + +pci:v000010DEd00000028sv00001048sd00000C31* + ID_PRODUCT_FROM_DATABASE=Erazor III Pro + +pci:v000010DEd00000028sv00001048sd00000C32* + ID_PRODUCT_FROM_DATABASE=Erazor III Pro + +pci:v000010DEd00000028sv00001048sd00000C33* + ID_PRODUCT_FROM_DATABASE=Erazor III Pro + +pci:v000010DEd00000028sv00001048sd00000C34* + ID_PRODUCT_FROM_DATABASE=Erazor III Pro + +pci:v000010DEd00000028sv0000107Dsd00002134* + ID_PRODUCT_FROM_DATABASE=WinFast 3D S320 II + TV-Out + +pci:v000010DEd00000028sv00001092sd00004804* + ID_PRODUCT_FROM_DATABASE=Viper V770 + +pci:v000010DEd00000028sv00001092sd00004A00* + ID_PRODUCT_FROM_DATABASE=Viper V770 + +pci:v000010DEd00000028sv00001092sd00004A02* + ID_PRODUCT_FROM_DATABASE=Viper V770 Ultra + +pci:v000010DEd00000028sv00001092sd00005A00* + ID_PRODUCT_FROM_DATABASE=RIVA TNT2/TNT2 Pro + +pci:v000010DEd00000028sv00001092sd00006A02* + ID_PRODUCT_FROM_DATABASE=Viper V770 Ultra + +pci:v000010DEd00000028sv00001092sd00007A02* + ID_PRODUCT_FROM_DATABASE=Viper V770 Ultra + +pci:v000010DEd00000028sv000010DEsd00000005* + ID_PRODUCT_FROM_DATABASE=RIVA TNT2 Pro + +pci:v000010DEd00000028sv000010DEsd0000000F* + ID_PRODUCT_FROM_DATABASE=Compaq NVIDIA TNT2 Pro + +pci:v000010DEd00000028sv00001102sd00001020* + ID_PRODUCT_FROM_DATABASE=3D Blaster RIVA TNT2 + +pci:v000010DEd00000028sv00001102sd00001026* + ID_PRODUCT_FROM_DATABASE=3D Blaster RIVA TNT2 Digital + +pci:v000010DEd00000028sv00001462sd00008806* + ID_PRODUCT_FROM_DATABASE=MS-8806 AGPhantom Graphics Card + +pci:v000010DEd00000028sv000014AFsd00005810* + ID_PRODUCT_FROM_DATABASE=Maxi Gamer Xentor + +pci:v000010DEd00000029* + ID_PRODUCT_FROM_DATABASE=NV5 [RIVA TNT2 Ultra] + +pci:v000010DEd00000029sv00001043sd00000200* + ID_PRODUCT_FROM_DATABASE=AGP-V3800 Deluxe + +pci:v000010DEd00000029sv00001043sd00000201* + ID_PRODUCT_FROM_DATABASE=AGP-V3800 Ultra SDRAM + +pci:v000010DEd00000029sv00001043sd00000205* + ID_PRODUCT_FROM_DATABASE=PCI-V3800 Ultra + +pci:v000010DEd00000029sv00001048sd00000C2E* + ID_PRODUCT_FROM_DATABASE=Erazor III Ultra + +pci:v000010DEd00000029sv00001048sd00000C2F* + ID_PRODUCT_FROM_DATABASE=Erazor III Ultra + +pci:v000010DEd00000029sv00001048sd00000C30* + ID_PRODUCT_FROM_DATABASE=Erazor III Ultra + +pci:v000010DEd00000029sv00001102sd00001021* + ID_PRODUCT_FROM_DATABASE=3D Blaster RIVA TNT2 Ultra + +pci:v000010DEd00000029sv00001102sd00001029* + ID_PRODUCT_FROM_DATABASE=3D Blaster RIVA TNT2 Ultra + +pci:v000010DEd00000029sv00001102sd0000102F* + ID_PRODUCT_FROM_DATABASE=3D Blaster RIVA TNT2 Ultra + +pci:v000010DEd00000029sv000014AFsd00005820* + ID_PRODUCT_FROM_DATABASE=Maxi Gamer Xentor 32 + +pci:v000010DEd0000002A* + ID_PRODUCT_FROM_DATABASE=NV5 [Riva TNT2] + +pci:v000010DEd0000002B* + ID_PRODUCT_FROM_DATABASE=NV5 [Riva TNT2] + +pci:v000010DEd0000002C* + ID_PRODUCT_FROM_DATABASE=NV6 [Vanta/Vanta LT] + +pci:v000010DEd0000002Csv00001043sd00000200* + ID_PRODUCT_FROM_DATABASE=AGP-V3800 Combat SDRAM + +pci:v000010DEd0000002Csv00001043sd00000201* + ID_PRODUCT_FROM_DATABASE=AGP-V3800 Combat + +pci:v000010DEd0000002Csv00001048sd00000C20* + ID_PRODUCT_FROM_DATABASE=TNT2 Vanta + +pci:v000010DEd0000002Csv00001048sd00000C21* + ID_PRODUCT_FROM_DATABASE=TNT2 Vanta + +pci:v000010DEd0000002Csv00001092sd00006820* + ID_PRODUCT_FROM_DATABASE=Viper V730 + +pci:v000010DEd0000002Csv00001102sd00001031* + ID_PRODUCT_FROM_DATABASE=CT6938 VANTA 8MB + +pci:v000010DEd0000002Csv00001102sd00001034* + ID_PRODUCT_FROM_DATABASE=CT6894 VANTA 16MB + +pci:v000010DEd0000002Csv000014AFsd00005008* + ID_PRODUCT_FROM_DATABASE=Maxi Gamer Phoenix 2 + +pci:v000010DEd0000002D* + ID_PRODUCT_FROM_DATABASE=NV5M64 [RIVA TNT2 Model 64/Model 64 Pro] + +pci:v000010DEd0000002Dsv00001043sd00000200* + ID_PRODUCT_FROM_DATABASE=AGP-V3800M + +pci:v000010DEd0000002Dsv00001043sd00000201* + ID_PRODUCT_FROM_DATABASE=AGP-V3800M + +pci:v000010DEd0000002Dsv00001048sd00000C3A* + ID_PRODUCT_FROM_DATABASE=Erazor III LT + +pci:v000010DEd0000002Dsv00001048sd00000C3B* + ID_PRODUCT_FROM_DATABASE=Erazor III LT + +pci:v000010DEd0000002Dsv000010DEsd00000006* + ID_PRODUCT_FROM_DATABASE=RIVA TNT2 Model 64/Model 64 Pro + +pci:v000010DEd0000002Dsv000010DEsd0000001E* + ID_PRODUCT_FROM_DATABASE=M64 AGP4x + +pci:v000010DEd0000002Dsv00001102sd00001023* + ID_PRODUCT_FROM_DATABASE=CT6892 RIVA TNT2 Value + +pci:v000010DEd0000002Dsv00001102sd00001024* + ID_PRODUCT_FROM_DATABASE=CT6932 RIVA TNT2 Value 32Mb + +pci:v000010DEd0000002Dsv00001102sd0000102C* + ID_PRODUCT_FROM_DATABASE=CT6931 RIVA TNT2 Value [Jumper] + +pci:v000010DEd0000002Dsv00001462sd00008808* + ID_PRODUCT_FROM_DATABASE=MSI-8808 + +pci:v000010DEd0000002Dsv00001554sd00001041* + ID_PRODUCT_FROM_DATABASE=Pixelview RIVA TNT2 M64 + +pci:v000010DEd0000002Dsv00001569sd0000002D* + ID_PRODUCT_FROM_DATABASE=Palit Microsystems Daytona TNT2 M64 + +pci:v000010DEd0000002E* + ID_PRODUCT_FROM_DATABASE=NV6 [Vanta] + +pci:v000010DEd0000002F* + ID_PRODUCT_FROM_DATABASE=NV6 [Vanta] + +pci:v000010DEd00000034* + ID_PRODUCT_FROM_DATABASE=MCP04 SMBus + +pci:v000010DEd00000035* + ID_PRODUCT_FROM_DATABASE=MCP04 IDE + +pci:v000010DEd00000036* + ID_PRODUCT_FROM_DATABASE=MCP04 Serial ATA Controller + +pci:v000010DEd00000037* + ID_PRODUCT_FROM_DATABASE=MCP04 Ethernet Controller + +pci:v000010DEd00000038* + ID_PRODUCT_FROM_DATABASE=MCP04 Ethernet Controller + +pci:v000010DEd0000003A* + ID_PRODUCT_FROM_DATABASE=MCP04 AC'97 Audio Controller + +pci:v000010DEd0000003B* + ID_PRODUCT_FROM_DATABASE=MCP04 USB Controller + +pci:v000010DEd0000003C* + ID_PRODUCT_FROM_DATABASE=MCP04 USB Controller + +pci:v000010DEd0000003D* + ID_PRODUCT_FROM_DATABASE=MCP04 PCI Bridge + +pci:v000010DEd0000003E* + ID_PRODUCT_FROM_DATABASE=MCP04 Serial ATA Controller + +pci:v000010DEd00000040* + ID_PRODUCT_FROM_DATABASE=NV40 [GeForce 6800 Ultra] + +pci:v000010DEd00000041* + ID_PRODUCT_FROM_DATABASE=NV40 [GeForce 6800] + +pci:v000010DEd00000041sv00001043sd0000817B* + ID_PRODUCT_FROM_DATABASE=V9999 Gamer Edition + +pci:v000010DEd00000042* + ID_PRODUCT_FROM_DATABASE=NV40.2 [GeForce 6800 LE] + +pci:v000010DEd00000043* + ID_PRODUCT_FROM_DATABASE=NV40.3 [GeForce 6800 XE] + +pci:v000010DEd00000044* + ID_PRODUCT_FROM_DATABASE=NV40 [GeForce 6800 XT] + +pci:v000010DEd00000045* + ID_PRODUCT_FROM_DATABASE=NV40 [GeForce 6800 GT] + +pci:v000010DEd00000046* + ID_PRODUCT_FROM_DATABASE=NV45 [GeForce 6800 GT] + +pci:v000010DEd00000047* + ID_PRODUCT_FROM_DATABASE=NV40 [GeForce 6800 GS] + +pci:v000010DEd00000047sv00001682sd00002109* + ID_PRODUCT_FROM_DATABASE=GeForce 6800 GS + +pci:v000010DEd00000048* + ID_PRODUCT_FROM_DATABASE=NV40 [GeForce 6800 XT] + +pci:v000010DEd00000049* + ID_PRODUCT_FROM_DATABASE=NV40GL + +pci:v000010DEd0000004D* + ID_PRODUCT_FROM_DATABASE=NV40GL [Quadro FX 4000] + +pci:v000010DEd0000004E* + ID_PRODUCT_FROM_DATABASE=NV40GL [Quadro FX 4000] + +pci:v000010DEd00000050* + ID_PRODUCT_FROM_DATABASE=CK804 ISA Bridge + +pci:v000010DEd00000050sv00001043sd0000815A* + ID_PRODUCT_FROM_DATABASE=K8N4-E or A8N-E Mainboard + +pci:v000010DEd00000050sv000010F1sd00002865* + ID_PRODUCT_FROM_DATABASE=Tomcat K8E (S2865) + +pci:v000010DEd00000050sv00001458sd00000C11* + ID_PRODUCT_FROM_DATABASE=GA-K8N Ultra-9 Mainboard + +pci:v000010DEd00000050sv00001462sd00007100* + ID_PRODUCT_FROM_DATABASE=MSI K8N Diamond + +pci:v000010DEd00000050sv00001462sd00007125* + ID_PRODUCT_FROM_DATABASE=K8N Neo4-F mainboard + +pci:v000010DEd00000050sv0000147Bsd00001C1A* + ID_PRODUCT_FROM_DATABASE=KN8-Ultra Mainboard + +pci:v000010DEd00000050sv00001565sd00003402* + ID_PRODUCT_FROM_DATABASE=NF4 AM2L Mainboard + +pci:v000010DEd00000051* + ID_PRODUCT_FROM_DATABASE=CK804 ISA Bridge + +pci:v000010DEd00000051sv00001028sd00000225* + ID_PRODUCT_FROM_DATABASE=PowerEdge T105 ISA Bridge + +pci:v000010DEd00000052* + ID_PRODUCT_FROM_DATABASE=CK804 SMBus + +pci:v000010DEd00000052sv00001028sd00000225* + ID_PRODUCT_FROM_DATABASE=PowerEdge T105 SMBus + +pci:v000010DEd00000052sv00001043sd0000815A* + ID_PRODUCT_FROM_DATABASE=K8N4-E or A8N-E Mainboard + +pci:v000010DEd00000052sv000010F1sd00002865* + ID_PRODUCT_FROM_DATABASE=Tomcat K8E (S2865) + +pci:v000010DEd00000052sv00001458sd00000C11* + ID_PRODUCT_FROM_DATABASE=GA-K8N Ultra-9 Mainboard + +pci:v000010DEd00000052sv00001462sd00007100* + ID_PRODUCT_FROM_DATABASE=MSI K8N Diamond + +pci:v000010DEd00000052sv00001462sd00007125* + ID_PRODUCT_FROM_DATABASE=K8N Neo4-F mainboard + +pci:v000010DEd00000052sv0000147Bsd00001C1A* + ID_PRODUCT_FROM_DATABASE=KN8-Ultra Mainboard + +pci:v000010DEd00000052sv00001565sd00003402* + ID_PRODUCT_FROM_DATABASE=NF4 AM2L Mainboard + +pci:v000010DEd00000053* + ID_PRODUCT_FROM_DATABASE=CK804 IDE + +pci:v000010DEd00000053sv00001043sd0000815A* + ID_PRODUCT_FROM_DATABASE=K8N4-E or A8N-E Mainboard + +pci:v000010DEd00000053sv000010F1sd00002865* + ID_PRODUCT_FROM_DATABASE=Tomcat K8E (S2865) + +pci:v000010DEd00000053sv00001458sd00005002* + ID_PRODUCT_FROM_DATABASE=GA-K8N Ultra-9 Mainboard + +pci:v000010DEd00000053sv00001462sd00007100* + ID_PRODUCT_FROM_DATABASE=MSI K8N Diamond + +pci:v000010DEd00000053sv00001462sd00007125* + ID_PRODUCT_FROM_DATABASE=K8N Neo4-F mainboard + +pci:v000010DEd00000053sv0000147Bsd00001C1A* + ID_PRODUCT_FROM_DATABASE=KN8-Ultra Mainboard + +pci:v000010DEd00000053sv00001565sd00003402* + ID_PRODUCT_FROM_DATABASE=NF4 AM2L Mainboard + +pci:v000010DEd00000054* + ID_PRODUCT_FROM_DATABASE=CK804 Serial ATA Controller + +pci:v000010DEd00000054sv00001028sd00000225* + ID_PRODUCT_FROM_DATABASE=PowerEdge T105 Serial ATA + +pci:v000010DEd00000054sv00001043sd0000815A* + ID_PRODUCT_FROM_DATABASE=A8N-E Mainboard + +pci:v000010DEd00000054sv000010F1sd00002865* + ID_PRODUCT_FROM_DATABASE=Tomcat K8E (S2865) + +pci:v000010DEd00000054sv00001458sd0000B003* + ID_PRODUCT_FROM_DATABASE=GA-K8N Ultra-9 Mainboard + +pci:v000010DEd00000054sv00001462sd00007100* + ID_PRODUCT_FROM_DATABASE=MSI K8N Diamond + +pci:v000010DEd00000054sv00001462sd00007125* + ID_PRODUCT_FROM_DATABASE=K8N Neo4-F mainboard + +pci:v000010DEd00000054sv0000147Bsd00001C1A* + ID_PRODUCT_FROM_DATABASE=KN8-Ultra Mainboard + +pci:v000010DEd00000054sv00001565sd00005401* + ID_PRODUCT_FROM_DATABASE=NF4 AM2L Mainboard + +pci:v000010DEd00000055* + ID_PRODUCT_FROM_DATABASE=CK804 Serial ATA Controller + +pci:v000010DEd00000055sv00001028sd00000225* + ID_PRODUCT_FROM_DATABASE=PowerEdge T105 Serial ATA + +pci:v000010DEd00000055sv00001043sd0000815A* + ID_PRODUCT_FROM_DATABASE=K8N4-E or A8N-E Mainboard + +pci:v000010DEd00000055sv000010F1sd00002865* + ID_PRODUCT_FROM_DATABASE=Tomcat K8E (S2865) + +pci:v000010DEd00000055sv00001458sd0000B003* + ID_PRODUCT_FROM_DATABASE=GA-K8N Ultra-9 Mainboard + +pci:v000010DEd00000055sv00001462sd00007125* + ID_PRODUCT_FROM_DATABASE=K8N Neo4-F mainboard + +pci:v000010DEd00000055sv0000147Bsd00001C1A* + ID_PRODUCT_FROM_DATABASE=KN8-Ultra Mainboard + +pci:v000010DEd00000055sv00001565sd00005401* + ID_PRODUCT_FROM_DATABASE=NF4 AM2L Mainboard + +pci:v000010DEd00000056* + ID_PRODUCT_FROM_DATABASE=CK804 Ethernet Controller + +pci:v000010DEd00000057* + ID_PRODUCT_FROM_DATABASE=CK804 Ethernet Controller + +pci:v000010DEd00000057sv00001043sd00008141* + ID_PRODUCT_FROM_DATABASE=K8N4-E or A8N-E Mainboard + +pci:v000010DEd00000057sv000010DEsd0000CB84* + ID_PRODUCT_FROM_DATABASE=NF4 Lanparty + +pci:v000010DEd00000057sv000010F1sd00002865* + ID_PRODUCT_FROM_DATABASE=Tomcat K8E (S2865) + +pci:v000010DEd00000057sv00001458sd0000E000* + ID_PRODUCT_FROM_DATABASE=GA-K8N Ultra-9 Mainboard + +pci:v000010DEd00000057sv00001462sd00007100* + ID_PRODUCT_FROM_DATABASE=MSI K8N Diamond + +pci:v000010DEd00000057sv00001462sd00007125* + ID_PRODUCT_FROM_DATABASE=K8N Neo4-F mainboard + +pci:v000010DEd00000057sv0000147Bsd00001C1A* + ID_PRODUCT_FROM_DATABASE=KN8-Ultra Mainboard + +pci:v000010DEd00000057sv00001565sd00002501* + ID_PRODUCT_FROM_DATABASE=NF4 AM2L Mainboard + +pci:v000010DEd00000058* + ID_PRODUCT_FROM_DATABASE=CK804 AC'97 Modem + +pci:v000010DEd00000059* + ID_PRODUCT_FROM_DATABASE=CK804 AC'97 Audio Controller + +pci:v000010DEd00000059sv00001043sd0000812A* + ID_PRODUCT_FROM_DATABASE=K8N4-E or A8N-E Mainboard + +pci:v000010DEd00000059sv000010F1sd00002865* + ID_PRODUCT_FROM_DATABASE=Tomcat K8E (S2865) + +pci:v000010DEd00000059sv00001462sd00007585* + ID_PRODUCT_FROM_DATABASE=K8N Neo4-F mainboard + +pci:v000010DEd00000059sv0000147Bsd00001C1A* + ID_PRODUCT_FROM_DATABASE=KN8-Ultra Mainboard + +pci:v000010DEd00000059sv00001565sd00008211* + ID_PRODUCT_FROM_DATABASE=NF4 AM2L Mainboard + +pci:v000010DEd0000005A* + ID_PRODUCT_FROM_DATABASE=CK804 USB Controller + +pci:v000010DEd0000005Asv00001028sd00000225* + ID_PRODUCT_FROM_DATABASE=PowerEdge T105 onboard USB + +pci:v000010DEd0000005Asv00001043sd0000815A* + ID_PRODUCT_FROM_DATABASE=K8N4-E or A8N-E Mainboard + +pci:v000010DEd0000005Asv000010F1sd00002865* + ID_PRODUCT_FROM_DATABASE=Tomcat K8E (S2865) + +pci:v000010DEd0000005Asv00001458sd00005004* + ID_PRODUCT_FROM_DATABASE=GA-K8N Ultra-9 Mainboard + +pci:v000010DEd0000005Asv00001462sd00007100* + ID_PRODUCT_FROM_DATABASE=MSI K8N Diamond + +pci:v000010DEd0000005Asv00001462sd00007125* + ID_PRODUCT_FROM_DATABASE=K8N Neo4-F mainboard + +pci:v000010DEd0000005Asv0000147Bsd00001C1A* + ID_PRODUCT_FROM_DATABASE=KN8-Ultra Mainboard + +pci:v000010DEd0000005Asv00001565sd00003402* + ID_PRODUCT_FROM_DATABASE=NF4 AM2L Mainboard + +pci:v000010DEd0000005B* + ID_PRODUCT_FROM_DATABASE=CK804 USB Controller + +pci:v000010DEd0000005Bsv00001028sd00000225* + ID_PRODUCT_FROM_DATABASE=PowerEdge T105 onboard USB + +pci:v000010DEd0000005Bsv00001043sd0000815A* + ID_PRODUCT_FROM_DATABASE=K8N4-E or A8N-E Mainboard + +pci:v000010DEd0000005Bsv000010F1sd00002865* + ID_PRODUCT_FROM_DATABASE=Tomcat K8E (S2865) + +pci:v000010DEd0000005Bsv00001458sd00005004* + ID_PRODUCT_FROM_DATABASE=GA-K8N Ultra-9 Mainboard + +pci:v000010DEd0000005Bsv00001462sd00007100* + ID_PRODUCT_FROM_DATABASE=MSI K8N Diamond + +pci:v000010DEd0000005Bsv00001462sd00007125* + ID_PRODUCT_FROM_DATABASE=K8N Neo4-F mainboard + +pci:v000010DEd0000005Bsv0000147Bsd00001C1A* + ID_PRODUCT_FROM_DATABASE=KN8-Ultra Mainboard + +pci:v000010DEd0000005Bsv00001565sd00003402* + ID_PRODUCT_FROM_DATABASE=NF4 AM2L Mainboard + +pci:v000010DEd0000005C* + ID_PRODUCT_FROM_DATABASE=CK804 PCI Bridge + +pci:v000010DEd0000005D* + ID_PRODUCT_FROM_DATABASE=CK804 PCIE Bridge + +pci:v000010DEd0000005E* + ID_PRODUCT_FROM_DATABASE=CK804 Memory Controller + +pci:v000010DEd0000005Esv00001028sd00000225* + ID_PRODUCT_FROM_DATABASE=PowerEdge T105 Memory Controller + +pci:v000010DEd0000005Esv00001043sd0000815A* + ID_PRODUCT_FROM_DATABASE=A8N-E Mainboard + +pci:v000010DEd0000005Esv000010DEsd0000005E* + ID_PRODUCT_FROM_DATABASE=ECS Elitegroup NFORCE3-A939 motherboard. + +pci:v000010DEd0000005Esv000010F1sd00002865* + ID_PRODUCT_FROM_DATABASE=Tomcat K8E (S2865) + +pci:v000010DEd0000005Esv000010F1sd00002891* + ID_PRODUCT_FROM_DATABASE=Thunder K8SRE Mainboard + +pci:v000010DEd0000005Esv00001458sd00005000* + ID_PRODUCT_FROM_DATABASE=GA-K8N Ultra-9 Mainboard + +pci:v000010DEd0000005Esv00001462sd00007100* + ID_PRODUCT_FROM_DATABASE=K8N Diamond Mainboard + +pci:v000010DEd0000005Esv00001462sd00007125* + ID_PRODUCT_FROM_DATABASE=K8N Neo4-F Mainboard + +pci:v000010DEd0000005Esv0000147Bsd00001C1A* + ID_PRODUCT_FROM_DATABASE=KN8-Ultra Mainboard + +pci:v000010DEd0000005Esv00001565sd00003402* + ID_PRODUCT_FROM_DATABASE=NF4 AM2L Mainboard + +pci:v000010DEd0000005F* + ID_PRODUCT_FROM_DATABASE=CK804 Memory Controller + +pci:v000010DEd00000060* + ID_PRODUCT_FROM_DATABASE=nForce2 ISA Bridge + +pci:v000010DEd00000060sv00001043sd000080AD* + ID_PRODUCT_FROM_DATABASE=A7N8X Mainboard + +pci:v000010DEd00000060sv0000147Bsd00001C02* + ID_PRODUCT_FROM_DATABASE=NF7-S/NF7 (nVidia-nForce2) 2.X + +pci:v000010DEd00000060sv0000A0A0sd000003BA* + ID_PRODUCT_FROM_DATABASE=UK79G-1394 motherboard + +pci:v000010DEd00000064* + ID_PRODUCT_FROM_DATABASE=nForce2 SMBus (MCP) + +pci:v000010DEd00000064sv0000147Bsd00001C02* + ID_PRODUCT_FROM_DATABASE=NF7-S/NF7 (nVidia-nForce2) 2.X + +pci:v000010DEd00000064sv0000A0A0sd000003BB* + ID_PRODUCT_FROM_DATABASE=UK79G-1394 motherboard + +pci:v000010DEd00000065* + ID_PRODUCT_FROM_DATABASE=nForce2 IDE + +pci:v000010DEd00000065sv000010DEsd00000C11* + ID_PRODUCT_FROM_DATABASE=nForce 2 EIDE Controller + +pci:v000010DEd00000065sv0000A0A0sd000003B2* + ID_PRODUCT_FROM_DATABASE=UK79G-1394 motherboard + +pci:v000010DEd00000066* + ID_PRODUCT_FROM_DATABASE=nForce2 Ethernet Controller + +pci:v000010DEd00000066sv00001043sd000080A7* + ID_PRODUCT_FROM_DATABASE=A7N8X Mainboard onboard nForce2 Ethernet + +pci:v000010DEd00000066sv000010DEsd00000C11* + ID_PRODUCT_FROM_DATABASE=nForce MCP-T Networking Adapter + +pci:v000010DEd00000066sv0000A0A0sd000003B3* + ID_PRODUCT_FROM_DATABASE=UK79G-1394 motherboard + +pci:v000010DEd00000067* + ID_PRODUCT_FROM_DATABASE=nForce2 USB Controller + +pci:v000010DEd00000067sv00001043sd00000C11* + ID_PRODUCT_FROM_DATABASE=A7N8X Mainboard + +pci:v000010DEd00000067sv0000A0A0sd000003B4* + ID_PRODUCT_FROM_DATABASE=UK79G-1394 motherboard + +pci:v000010DEd00000068* + ID_PRODUCT_FROM_DATABASE=nForce2 USB Controller + +pci:v000010DEd00000068sv00001043sd00000C11* + ID_PRODUCT_FROM_DATABASE=A7N8X Mainboard + +pci:v000010DEd00000068sv0000A0A0sd000003B4* + ID_PRODUCT_FROM_DATABASE=UK79G-1394 motherboard + +pci:v000010DEd0000006A* + ID_PRODUCT_FROM_DATABASE=nForce2 AC97 Audio Controler (MCP) + +pci:v000010DEd0000006Asv00001043sd00008095* + ID_PRODUCT_FROM_DATABASE=nForce2 AC97 Audio Controler (MCP) + +pci:v000010DEd0000006Asv0000A0A0sd00000304* + ID_PRODUCT_FROM_DATABASE=UK79G-1394 motherboard + +pci:v000010DEd0000006B* + ID_PRODUCT_FROM_DATABASE=nForce Audio Processing Unit + +pci:v000010DEd0000006Bsv000010DEsd0000006B* + ID_PRODUCT_FROM_DATABASE=nForce2 MCP Audio Processing Unit + +pci:v000010DEd0000006Bsv0000A0A0sd00000304* + ID_PRODUCT_FROM_DATABASE=UK79G-1394 motherboard + +pci:v000010DEd0000006C* + ID_PRODUCT_FROM_DATABASE=nForce2 External PCI Bridge + +pci:v000010DEd0000006D* + ID_PRODUCT_FROM_DATABASE=nForce2 PCI Bridge + +pci:v000010DEd0000006E* + ID_PRODUCT_FROM_DATABASE=nForce2 FireWire (IEEE 1394) Controller + +pci:v000010DEd0000006Esv0000A0A0sd00000306* + ID_PRODUCT_FROM_DATABASE=UK79G-1394 motherboard + +pci:v000010DEd00000080* + ID_PRODUCT_FROM_DATABASE=MCP2A ISA bridge + +pci:v000010DEd00000080sv0000147Bsd00001C09* + ID_PRODUCT_FROM_DATABASE=NV7 Motherboard + +pci:v000010DEd00000084* + ID_PRODUCT_FROM_DATABASE=MCP2A SMBus + +pci:v000010DEd00000084sv0000147Bsd00001C09* + ID_PRODUCT_FROM_DATABASE=NV7 Motherboard + +pci:v000010DEd00000085* + ID_PRODUCT_FROM_DATABASE=MCP2A IDE + +pci:v000010DEd00000085sv0000147Bsd00001C09* + ID_PRODUCT_FROM_DATABASE=NV7 Motherboard + +pci:v000010DEd00000086* + ID_PRODUCT_FROM_DATABASE=MCP2A Ethernet Controller + +pci:v000010DEd00000087* + ID_PRODUCT_FROM_DATABASE=MCP2A USB Controller + +pci:v000010DEd00000087sv0000147Bsd00001C09* + ID_PRODUCT_FROM_DATABASE=NV7 Motherboard + +pci:v000010DEd00000088* + ID_PRODUCT_FROM_DATABASE=MCP2A USB Controller + +pci:v000010DEd00000088sv0000147Bsd00001C09* + ID_PRODUCT_FROM_DATABASE=NV7 Motherboard + +pci:v000010DEd0000008A* + ID_PRODUCT_FROM_DATABASE=MCP2S AC'97 Audio Controller + +pci:v000010DEd0000008Asv0000147Bsd00001C09* + ID_PRODUCT_FROM_DATABASE=NV7 Motherboard + +pci:v000010DEd0000008B* + ID_PRODUCT_FROM_DATABASE=MCP2A PCI Bridge + +pci:v000010DEd0000008C* + ID_PRODUCT_FROM_DATABASE=MCP2A Ethernet Controller + +pci:v000010DEd0000008E* + ID_PRODUCT_FROM_DATABASE=nForce2 Serial ATA Controller + +pci:v000010DEd00000090* + ID_PRODUCT_FROM_DATABASE=G70 [GeForce 7800 GTX] + +pci:v000010DEd00000091* + ID_PRODUCT_FROM_DATABASE=G70 [GeForce 7800 GTX] + +pci:v000010DEd00000092* + ID_PRODUCT_FROM_DATABASE=G70 [GeForce 7800 GT] + +pci:v000010DEd00000093* + ID_PRODUCT_FROM_DATABASE=G70 [GeForce 7800 GS] + +pci:v000010DEd00000095* + ID_PRODUCT_FROM_DATABASE=G70 [GeForce 7800 SLI] + +pci:v000010DEd00000098* + ID_PRODUCT_FROM_DATABASE=G70 [GeForce Go 7800] + +pci:v000010DEd00000099* + ID_PRODUCT_FROM_DATABASE=G70 [GeForce Go 7800 GTX] + +pci:v000010DEd0000009D* + ID_PRODUCT_FROM_DATABASE=G70GL [Quadro FX 4500] + +pci:v000010DEd000000A0* + ID_PRODUCT_FROM_DATABASE=NV5 [Aladdin TNT2] + +pci:v000010DEd000000A0sv000014AFsd00005810* + ID_PRODUCT_FROM_DATABASE=Maxi Gamer Xentor + +pci:v000010DEd000000C0* + ID_PRODUCT_FROM_DATABASE=NV41 [GeForce 6800 GS] + +pci:v000010DEd000000C1* + ID_PRODUCT_FROM_DATABASE=NV41.1 [GeForce 6800] + +pci:v000010DEd000000C2* + ID_PRODUCT_FROM_DATABASE=NV41.2 [GeForce 6800 LE] + +pci:v000010DEd000000C3* + ID_PRODUCT_FROM_DATABASE=NV42 [GeForce 6800 XT] + +pci:v000010DEd000000C8* + ID_PRODUCT_FROM_DATABASE=NV41.8 [GeForce Go 6800] + +pci:v000010DEd000000C9* + ID_PRODUCT_FROM_DATABASE=NV41.9 [GeForce Go 6800 Ultra] + +pci:v000010DEd000000CC* + ID_PRODUCT_FROM_DATABASE=NV41 [Quadro FX Go1400] + +pci:v000010DEd000000CD* + ID_PRODUCT_FROM_DATABASE=NV41 [Quadro FX 3450/4000 SDI] + +pci:v000010DEd000000CDsv000010DEsd0000029B* + ID_PRODUCT_FROM_DATABASE=wx4300 Workstation + +pci:v000010DEd000000CE* + ID_PRODUCT_FROM_DATABASE=NV41GL [Quadro FX 1400] + +pci:v000010DEd000000D0* + ID_PRODUCT_FROM_DATABASE=nForce3 LPC Bridge + +pci:v000010DEd000000D1* + ID_PRODUCT_FROM_DATABASE=nForce3 Host Bridge + +pci:v000010DEd000000D2* + ID_PRODUCT_FROM_DATABASE=nForce3 AGP Bridge + +pci:v000010DEd000000D3* + ID_PRODUCT_FROM_DATABASE=CK804 Memory Controller + +pci:v000010DEd000000D4* + ID_PRODUCT_FROM_DATABASE=nForce3 SMBus + +pci:v000010DEd000000D5* + ID_PRODUCT_FROM_DATABASE=nForce3 IDE + +pci:v000010DEd000000D6* + ID_PRODUCT_FROM_DATABASE=nForce3 Ethernet + +pci:v000010DEd000000D7* + ID_PRODUCT_FROM_DATABASE=nForce3 USB 1.1 + +pci:v000010DEd000000D8* + ID_PRODUCT_FROM_DATABASE=nForce3 USB 2.0 + +pci:v000010DEd000000D9* + ID_PRODUCT_FROM_DATABASE=nForce3 Audio + +pci:v000010DEd000000DA* + ID_PRODUCT_FROM_DATABASE=nForce3 Audio + +pci:v000010DEd000000DD* + ID_PRODUCT_FROM_DATABASE=nForce3 PCI Bridge + +pci:v000010DEd000000DF* + ID_PRODUCT_FROM_DATABASE=CK8S Ethernet Controller + +pci:v000010DEd000000DFsv00001043sd000080A7* + ID_PRODUCT_FROM_DATABASE=K8N-E + +pci:v000010DEd000000DFsv0000105Bsd00000C43* + ID_PRODUCT_FROM_DATABASE=Winfast NF3250K8AA + +pci:v000010DEd000000DFsv0000147Bsd00001C0B* + ID_PRODUCT_FROM_DATABASE=NF8 Mainboard + +pci:v000010DEd000000E0* + ID_PRODUCT_FROM_DATABASE=nForce3 250Gb LPC Bridge + +pci:v000010DEd000000E0sv00001043sd0000813F* + ID_PRODUCT_FROM_DATABASE=K8N-E + +pci:v000010DEd000000E0sv000010DEsd00000C11* + ID_PRODUCT_FROM_DATABASE=Winfast NF3250K8AA + +pci:v000010DEd000000E0sv00001462sd00007030* + ID_PRODUCT_FROM_DATABASE=K8N Neo-FSR v2.0 + +pci:v000010DEd000000E0sv0000147Bsd00001C0B* + ID_PRODUCT_FROM_DATABASE=NF8 Mainboard + +pci:v000010DEd000000E0sv00001849sd000000E0* + ID_PRODUCT_FROM_DATABASE=Motherboard (one of many) + +pci:v000010DEd000000E1* + ID_PRODUCT_FROM_DATABASE=nForce3 250Gb Host Bridge + +pci:v000010DEd000000E1sv00001043sd0000813F* + ID_PRODUCT_FROM_DATABASE=K8N-E + +pci:v000010DEd000000E1sv00001462sd00007030* + ID_PRODUCT_FROM_DATABASE=K8N Neo-FSR v2.0 + +pci:v000010DEd000000E1sv0000147Bsd00001C0B* + ID_PRODUCT_FROM_DATABASE=NF8 Mainboard + +pci:v000010DEd000000E1sv00001849sd000000E1* + ID_PRODUCT_FROM_DATABASE=Motherboard (one of many) + +pci:v000010DEd000000E2* + ID_PRODUCT_FROM_DATABASE=nForce3 250Gb AGP Host to PCI Bridge + +pci:v000010DEd000000E3* + ID_PRODUCT_FROM_DATABASE=nForce3 Serial ATA Controller + +pci:v000010DEd000000E3sv00001043sd0000813F* + ID_PRODUCT_FROM_DATABASE=K8N-E + +pci:v000010DEd000000E3sv0000105Bsd00000C43* + ID_PRODUCT_FROM_DATABASE=Winfast NF3250K8AA + +pci:v000010DEd000000E3sv0000147Bsd00001C0B* + ID_PRODUCT_FROM_DATABASE=NF8 Mainboard + +pci:v000010DEd000000E3sv00001849sd000000E3* + ID_PRODUCT_FROM_DATABASE=Motherboard (one of many) + +pci:v000010DEd000000E4* + ID_PRODUCT_FROM_DATABASE=nForce 250Gb PCI System Management + +pci:v000010DEd000000E4sv00001043sd0000813F* + ID_PRODUCT_FROM_DATABASE=K8N-E + +pci:v000010DEd000000E4sv0000105Bsd00000C43* + ID_PRODUCT_FROM_DATABASE=Winfast NF3250K8AA + +pci:v000010DEd000000E4sv00001462sd00007030* + ID_PRODUCT_FROM_DATABASE=K8N Neo-FSR v2.0 + +pci:v000010DEd000000E4sv0000147Bsd00001C0B* + ID_PRODUCT_FROM_DATABASE=NF8 Mainboard + +pci:v000010DEd000000E4sv00001849sd000000E4* + ID_PRODUCT_FROM_DATABASE=Motherboard (one of many) + +pci:v000010DEd000000E5* + ID_PRODUCT_FROM_DATABASE=CK8S Parallel ATA Controller (v2.5) + +pci:v000010DEd000000E5sv00001043sd0000813F* + ID_PRODUCT_FROM_DATABASE=K8N-E + +pci:v000010DEd000000E5sv0000105Bsd00000C43* + ID_PRODUCT_FROM_DATABASE=Winfast NF3250K8AA + +pci:v000010DEd000000E5sv00001462sd00007030* + ID_PRODUCT_FROM_DATABASE=K8N Neo-FSR v2.0 + +pci:v000010DEd000000E5sv0000147Bsd00001C0B* + ID_PRODUCT_FROM_DATABASE=NF8 Mainboard + +pci:v000010DEd000000E5sv00001849sd000000E5* + ID_PRODUCT_FROM_DATABASE=Motherboard (one of many) + +pci:v000010DEd000000E5sv0000F849sd000000E5* + ID_PRODUCT_FROM_DATABASE=Motherboard (one of many) + +pci:v000010DEd000000E6* + ID_PRODUCT_FROM_DATABASE=CK8S Ethernet Controller + +pci:v000010DEd000000E7* + ID_PRODUCT_FROM_DATABASE=CK8S USB Controller + +pci:v000010DEd000000E7sv00001043sd0000813F* + ID_PRODUCT_FROM_DATABASE=K8N-E + +pci:v000010DEd000000E7sv0000105Bsd00000C43* + ID_PRODUCT_FROM_DATABASE=Winfast NF3250K8AA + +pci:v000010DEd000000E7sv00001462sd00007030* + ID_PRODUCT_FROM_DATABASE=K8N Neo-FSR v2.0 + +pci:v000010DEd000000E7sv0000147Bsd00001C0B* + ID_PRODUCT_FROM_DATABASE=NF8 Mainboard + +pci:v000010DEd000000E7sv00001849sd000000E7* + ID_PRODUCT_FROM_DATABASE=Motherboard (one of many) + +pci:v000010DEd000000E8* + ID_PRODUCT_FROM_DATABASE=nForce3 EHCI USB 2.0 Controller + +pci:v000010DEd000000E8sv00001043sd0000813F* + ID_PRODUCT_FROM_DATABASE=K8N-E + +pci:v000010DEd000000E8sv0000105Bsd00000C43* + ID_PRODUCT_FROM_DATABASE=Winfast NF3250K8AA + +pci:v000010DEd000000E8sv00001462sd00007030* + ID_PRODUCT_FROM_DATABASE=K8N Neo-FSR v2.0 + +pci:v000010DEd000000E8sv0000147Bsd00001C0B* + ID_PRODUCT_FROM_DATABASE=NF8 Mainboard + +pci:v000010DEd000000E8sv00001849sd000000E8* + ID_PRODUCT_FROM_DATABASE=Motherboard (one of many) + +pci:v000010DEd000000EA* + ID_PRODUCT_FROM_DATABASE=nForce3 250Gb AC'97 Audio Controller + +pci:v000010DEd000000EAsv00001043sd0000819D* + ID_PRODUCT_FROM_DATABASE=K8N-E + +pci:v000010DEd000000EAsv0000105Bsd00000C43* + ID_PRODUCT_FROM_DATABASE=Winfast NF3250K8AA + +pci:v000010DEd000000EAsv00001462sd0000B010* + ID_PRODUCT_FROM_DATABASE=K8N Neo-FSR v2.0 + +pci:v000010DEd000000EAsv0000147Bsd00001C0B* + ID_PRODUCT_FROM_DATABASE=NF8 Mainboard + +pci:v000010DEd000000ED* + ID_PRODUCT_FROM_DATABASE=nForce3 250Gb PCI-to-PCI Bridge + +pci:v000010DEd000000EE* + ID_PRODUCT_FROM_DATABASE=nForce3 Serial ATA Controller 2 + +pci:v000010DEd000000F0* + ID_PRODUCT_FROM_DATABASE=NV40 [GeForce 6800 Ultra] + +pci:v000010DEd000000F1* + ID_PRODUCT_FROM_DATABASE=NV43 [GeForce 6600 GT] + +pci:v000010DEd000000F1sv00001043sd000081A6* + ID_PRODUCT_FROM_DATABASE=N6600GT TD 128M AGP + +pci:v000010DEd000000F1sv00001043sd000081C6* + ID_PRODUCT_FROM_DATABASE=N6600GT TD 128M AGP + +pci:v000010DEd000000F1sv00001458sd00003150* + ID_PRODUCT_FROM_DATABASE=GV-N66T128VP + +pci:v000010DEd000000F1sv00001554sd00001191* + ID_PRODUCT_FROM_DATABASE=PixelView PV-N43UA (128KD) + +pci:v000010DEd000000F1sv00001682sd00002119* + ID_PRODUCT_FROM_DATABASE=GeForce 6600 GT AGP + +pci:v000010DEd000000F2* + ID_PRODUCT_FROM_DATABASE=NV43 [GeForce 6600] + +pci:v000010DEd000000F2sv00001554sd00001194* + ID_PRODUCT_FROM_DATABASE=PixelView PV-N43AT (256KD) + +pci:v000010DEd000000F2sv00001682sd0000211C* + ID_PRODUCT_FROM_DATABASE=GeForce 6600 256MB DDR DUAL DVI TV + +pci:v000010DEd000000F3* + ID_PRODUCT_FROM_DATABASE=NV43 [GeForce 6200] + +pci:v000010DEd000000F4* + ID_PRODUCT_FROM_DATABASE=NV43 [GeForce 6600 LE] + +pci:v000010DEd000000F5* + ID_PRODUCT_FROM_DATABASE=G70 [GeForce 7800 GS] + +pci:v000010DEd000000F6* + ID_PRODUCT_FROM_DATABASE=NV43 [GeForce 6800 GS] + +pci:v000010DEd000000F6sv00001682sd0000217E* + ID_PRODUCT_FROM_DATABASE=XFX GeForce 6800 XTreme 256MB DDR3 AGP + +pci:v000010DEd000000F8* + ID_PRODUCT_FROM_DATABASE=NV45GL [Quadro FX 3400/4400] + +pci:v000010DEd000000F9* + ID_PRODUCT_FROM_DATABASE=NV45 [GeForce 6800 GTO] + +pci:v000010DEd000000F9sv000010DEsd000000F9* + ID_PRODUCT_FROM_DATABASE=NV40 [GeForce 6800 GT] + +pci:v000010DEd000000F9sv00001682sd00002120* + ID_PRODUCT_FROM_DATABASE=GEFORCE 6800 GT PCI-E + +pci:v000010DEd000000FA* + ID_PRODUCT_FROM_DATABASE=NV36 [GeForce PCX 5750] + +pci:v000010DEd000000FB* + ID_PRODUCT_FROM_DATABASE=NV35 [GeForce PCX 5900] + +pci:v000010DEd000000FC* + ID_PRODUCT_FROM_DATABASE=NV37GL [Quadro FX 330/GeForce PCX 5300] + +pci:v000010DEd000000FD* + ID_PRODUCT_FROM_DATABASE=NV37GL [Quadro PCI-E Series] + +pci:v000010DEd000000FE* + ID_PRODUCT_FROM_DATABASE=NV38GL [Quadro FX 1300] + +pci:v000010DEd000000FF* + ID_PRODUCT_FROM_DATABASE=NV18 [GeForce PCX 4300] + +pci:v000010DEd00000100* + ID_PRODUCT_FROM_DATABASE=NV10 [GeForce 256 SDR] + +pci:v000010DEd00000100sv00001043sd00000200* + ID_PRODUCT_FROM_DATABASE=AGP-V6600 SGRAM + +pci:v000010DEd00000100sv00001043sd00000201* + ID_PRODUCT_FROM_DATABASE=AGP-V6600 SDRAM + +pci:v000010DEd00000100sv00001043sd00004008* + ID_PRODUCT_FROM_DATABASE=AGP-V6600 SGRAM + +pci:v000010DEd00000100sv00001043sd00004009* + ID_PRODUCT_FROM_DATABASE=AGP-V6600 SDRAM + +pci:v000010DEd00000100sv00001048sd00000C41* + ID_PRODUCT_FROM_DATABASE=Erazor X + +pci:v000010DEd00000100sv00001048sd00000C43* + ID_PRODUCT_FROM_DATABASE=ERAZOR X PCI + +pci:v000010DEd00000100sv00001048sd00000C48* + ID_PRODUCT_FROM_DATABASE=Synergy Force + +pci:v000010DEd00000100sv00001102sd0000102D* + ID_PRODUCT_FROM_DATABASE=CT6941 GeForce 256 + +pci:v000010DEd00000100sv000014AFsd00005022* + ID_PRODUCT_FROM_DATABASE=3D Prophet SE + +pci:v000010DEd00000101* + ID_PRODUCT_FROM_DATABASE=NV10DDR [GeForce 256 DDR] + +pci:v000010DEd00000101sv00001043sd00000202* + ID_PRODUCT_FROM_DATABASE=AGP-V6800 DDR + +pci:v000010DEd00000101sv00001043sd0000400A* + ID_PRODUCT_FROM_DATABASE=AGP-V6800 DDR SGRAM + +pci:v000010DEd00000101sv00001043sd0000400B* + ID_PRODUCT_FROM_DATABASE=AGP-V6800 DDR SDRAM + +pci:v000010DEd00000101sv00001048sd00000C42* + ID_PRODUCT_FROM_DATABASE=Erazor X + +pci:v000010DEd00000101sv0000107Dsd00002822* + ID_PRODUCT_FROM_DATABASE=WinFast GeForce 256 + +pci:v000010DEd00000101sv00001102sd0000102E* + ID_PRODUCT_FROM_DATABASE=CT6971 GeForce 256 DDR + +pci:v000010DEd00000101sv000014AFsd00005021* + ID_PRODUCT_FROM_DATABASE=3D Prophet DDR-DVI + +pci:v000010DEd00000103* + ID_PRODUCT_FROM_DATABASE=NV10GL [Quadro] + +pci:v000010DEd00000103sv00001048sd00000C40* + ID_PRODUCT_FROM_DATABASE=GLoria II-64 + +pci:v000010DEd00000103sv00001048sd00000C44* + ID_PRODUCT_FROM_DATABASE=GLoria II + +pci:v000010DEd00000103sv00001048sd00000C45* + ID_PRODUCT_FROM_DATABASE=GLoria II + +pci:v000010DEd00000103sv00001048sd00000C4A* + ID_PRODUCT_FROM_DATABASE=GLoria II-64 Pro + +pci:v000010DEd00000103sv00001048sd00000C4B* + ID_PRODUCT_FROM_DATABASE=GLoria II-64 Pro DVII + +pci:v000010DEd00000110* + ID_PRODUCT_FROM_DATABASE=NV11 [GeForce2 MX/MX 400] + +pci:v000010DEd00000110sv00001043sd00004015* + ID_PRODUCT_FROM_DATABASE=AGP-V7100 Pro + +pci:v000010DEd00000110sv00001043sd00004021* + ID_PRODUCT_FROM_DATABASE=V7100 Deluxe Combo + +pci:v000010DEd00000110sv00001043sd00004031* + ID_PRODUCT_FROM_DATABASE=V7100 Pro with TV output + +pci:v000010DEd00000110sv00001048sd00000C60* + ID_PRODUCT_FROM_DATABASE=Gladiac MX + +pci:v000010DEd00000110sv00001048sd00000C61* + ID_PRODUCT_FROM_DATABASE=Gladiac 511PCI + +pci:v000010DEd00000110sv00001048sd00000C63* + ID_PRODUCT_FROM_DATABASE=Gladiac 511TV-OUT 32MB + +pci:v000010DEd00000110sv00001048sd00000C64* + ID_PRODUCT_FROM_DATABASE=Gladiac 511TV-OUT 64MB + +pci:v000010DEd00000110sv00001048sd00000C65* + ID_PRODUCT_FROM_DATABASE=Gladiac 511TWIN + +pci:v000010DEd00000110sv00001048sd00000C66* + ID_PRODUCT_FROM_DATABASE=Gladiac 311 + +pci:v000010DEd00000110sv000010DEsd00000091* + ID_PRODUCT_FROM_DATABASE=Dell OEM GeForce 2 MX 400 + +pci:v000010DEd00000110sv000010DEsd000000A1* + ID_PRODUCT_FROM_DATABASE=Apple OEM GeForce2 MX + +pci:v000010DEd00000110sv00001462sd00008817* + ID_PRODUCT_FROM_DATABASE=MSI GeForce2 MX400 Pro32S [MS-8817] + +pci:v000010DEd00000110sv000014AFsd00007102* + ID_PRODUCT_FROM_DATABASE=3D Prophet II MX + +pci:v000010DEd00000110sv000014AFsd00007103* + ID_PRODUCT_FROM_DATABASE=3D Prophet II MX Dual-Display + +pci:v000010DEd00000110sv00001545sd00000023* + ID_PRODUCT_FROM_DATABASE=Xtasy Rev. B2 + +pci:v000010DEd00000111* + ID_PRODUCT_FROM_DATABASE=NV11DDR [GeForce2 MX200] + +pci:v000010DEd00000112* + ID_PRODUCT_FROM_DATABASE=NV11 [GeForce2 Go] + +pci:v000010DEd00000113* + ID_PRODUCT_FROM_DATABASE=NV11GL [Quadro2 MXR/EX/Go] + +pci:v000010DEd00000140* + ID_PRODUCT_FROM_DATABASE=NV43 [GeForce 6600 GT] + +pci:v000010DEd00000141* + ID_PRODUCT_FROM_DATABASE=NV43 [GeForce 6600] + +pci:v000010DEd00000141sv00001043sd000081B0* + ID_PRODUCT_FROM_DATABASE=EN6600 Silencer + +pci:v000010DEd00000141sv00001458sd00003124* + ID_PRODUCT_FROM_DATABASE=GV-NX66128DP Turbo Force Edition + +pci:v000010DEd00000142* + ID_PRODUCT_FROM_DATABASE=NV43 [GeForce 6600 LE] + +pci:v000010DEd00000143* + ID_PRODUCT_FROM_DATABASE=NV43 [GeForce 6600 VE] + +pci:v000010DEd00000144* + ID_PRODUCT_FROM_DATABASE=NV43 [GeForce Go 6600] + +pci:v000010DEd00000145* + ID_PRODUCT_FROM_DATABASE=NV43 [GeForce 6610 XL] + +pci:v000010DEd00000146* + ID_PRODUCT_FROM_DATABASE=NV43 [GeForce Go 6600TE/6200TE] + +pci:v000010DEd00000147* + ID_PRODUCT_FROM_DATABASE=NV43 [GeForce 6700 XL] + +pci:v000010DEd00000148* + ID_PRODUCT_FROM_DATABASE=NV43 [GeForce Go 6600] + +pci:v000010DEd00000149* + ID_PRODUCT_FROM_DATABASE=NV43 [GeForce Go 6600 GT] + +pci:v000010DEd0000014A* + ID_PRODUCT_FROM_DATABASE=NV43 [Quadro NVS 440] + +pci:v000010DEd0000014C* + ID_PRODUCT_FROM_DATABASE=NV43 [Quadro FX 540 MXM] + +pci:v000010DEd0000014D* + ID_PRODUCT_FROM_DATABASE=NV43GL [Quadro FX 550] + +pci:v000010DEd0000014E* + ID_PRODUCT_FROM_DATABASE=NV43GL [Quadro FX 540] + +pci:v000010DEd0000014F* + ID_PRODUCT_FROM_DATABASE=NV43 [GeForce 6200] + +pci:v000010DEd00000150* + ID_PRODUCT_FROM_DATABASE=NV15 [GeForce2 GTS/Pro] + +pci:v000010DEd00000150sv00001043sd00004016* + ID_PRODUCT_FROM_DATABASE=V7700 AGP Video Card + +pci:v000010DEd00000150sv00001048sd00000C50* + ID_PRODUCT_FROM_DATABASE=Gladiac + +pci:v000010DEd00000150sv00001048sd00000C52* + ID_PRODUCT_FROM_DATABASE=Gladiac-64 + +pci:v000010DEd00000150sv0000107Dsd00002840* + ID_PRODUCT_FROM_DATABASE=WinFast GeForce2 GTS with TV output + +pci:v000010DEd00000150sv0000107Dsd00002842* + ID_PRODUCT_FROM_DATABASE=WinFast GeForce 2 Pro + +pci:v000010DEd00000150sv000010DEsd0000002E* + ID_PRODUCT_FROM_DATABASE=GeForce2 GTS + +pci:v000010DEd00000150sv00001462sd00008831* + ID_PRODUCT_FROM_DATABASE=Creative GeForce2 Pro + +pci:v000010DEd00000151* + ID_PRODUCT_FROM_DATABASE=NV15DDR [GeForce2 Ti] + +pci:v000010DEd00000151sv00001043sd0000405F* + ID_PRODUCT_FROM_DATABASE=V7700Ti + +pci:v000010DEd00000151sv00001462sd00005506* + ID_PRODUCT_FROM_DATABASE=Creative 3D Blaster GeForce2 Titanium + +pci:v000010DEd00000152* + ID_PRODUCT_FROM_DATABASE=NV15BR [GeForce2 Ultra, Bladerunner] + +pci:v000010DEd00000152sv00001048sd00000C56* + ID_PRODUCT_FROM_DATABASE=GLADIAC Ultra + +pci:v000010DEd00000153* + ID_PRODUCT_FROM_DATABASE=NV15GL [Quadro2 Pro] + +pci:v000010DEd00000160* + ID_PRODUCT_FROM_DATABASE=NV44 [GeForce 6500] + +pci:v000010DEd00000161* + ID_PRODUCT_FROM_DATABASE=NV44 [GeForce 6200 TurboCache(TM)] + +pci:v000010DEd00000162* + ID_PRODUCT_FROM_DATABASE=NV44 [GeForce 6200SE TurboCache (TM)] + +pci:v000010DEd00000163* + ID_PRODUCT_FROM_DATABASE=NV44 [GeForce 6200 LE] + +pci:v000010DEd00000164* + ID_PRODUCT_FROM_DATABASE=NV44 [GeForce Go 6200] + +pci:v000010DEd00000165* + ID_PRODUCT_FROM_DATABASE=NV44 [Quadro NVS 285] + +pci:v000010DEd00000166* + ID_PRODUCT_FROM_DATABASE=NV44 [GeForce Go 6400] + +pci:v000010DEd00000167* + ID_PRODUCT_FROM_DATABASE=NV44 [GeForce Go 6200] + +pci:v000010DEd00000168* + ID_PRODUCT_FROM_DATABASE=NV44 [GeForce Go 6400] + +pci:v000010DEd00000169* + ID_PRODUCT_FROM_DATABASE=NV44 [GeForce 6250] + +pci:v000010DEd0000016A* + ID_PRODUCT_FROM_DATABASE=NV44 [GeForce 7100 GS] + +pci:v000010DEd00000170* + ID_PRODUCT_FROM_DATABASE=NV17 [GeForce4 MX 460] + +pci:v000010DEd00000171* + ID_PRODUCT_FROM_DATABASE=NV17 [GeForce4 MX 440] + +pci:v000010DEd00000171sv000010B0sd00000002* + ID_PRODUCT_FROM_DATABASE=Gainward Pro/600 TV + +pci:v000010DEd00000171sv000010DEsd00000008* + ID_PRODUCT_FROM_DATABASE=Apple OEM GeForce4 MX 440 + +pci:v000010DEd00000171sv00001462sd00008661* + ID_PRODUCT_FROM_DATABASE=G4MX440-VTP + +pci:v000010DEd00000171sv00001462sd00008730* + ID_PRODUCT_FROM_DATABASE=MX440SES-T (MS-8873) + +pci:v000010DEd00000171sv00001462sd00008852* + ID_PRODUCT_FROM_DATABASE=GeForce4 MX440 PCI + +pci:v000010DEd00000171sv0000147Bsd00008F00* + ID_PRODUCT_FROM_DATABASE=Abit Siluro GeForce4MX440 + +pci:v000010DEd00000172* + ID_PRODUCT_FROM_DATABASE=NV17 [GeForce4 MX 420] + +pci:v000010DEd00000173* + ID_PRODUCT_FROM_DATABASE=NV17 [GeForce4 MX 440-SE] + +pci:v000010DEd00000174* + ID_PRODUCT_FROM_DATABASE=NV17 [GeForce4 440 Go] + +pci:v000010DEd00000175* + ID_PRODUCT_FROM_DATABASE=NV17 [GeForce4 420 Go] + +pci:v000010DEd00000176* + ID_PRODUCT_FROM_DATABASE=NV17 [GeForce4 420 Go 32M] + +pci:v000010DEd00000176sv0000103Csd000008B0* + ID_PRODUCT_FROM_DATABASE=tc1100 tablet + +pci:v000010DEd00000176sv0000144Dsd0000C005* + ID_PRODUCT_FROM_DATABASE=X10 Laptop + +pci:v000010DEd00000176sv00004C53sd00001090* + ID_PRODUCT_FROM_DATABASE=Cx9 / Vx9 mainboard + +pci:v000010DEd00000177* + ID_PRODUCT_FROM_DATABASE=NV17 [GeForce4 460 Go] + +pci:v000010DEd00000178* + ID_PRODUCT_FROM_DATABASE=NV17GL [Quadro4 550 XGL] + +pci:v000010DEd00000179* + ID_PRODUCT_FROM_DATABASE=NV17 [GeForce4 440 Go 64M] + +pci:v000010DEd00000179sv000010DEsd00000179* + ID_PRODUCT_FROM_DATABASE=GeForce4 MX (Mac) + +pci:v000010DEd0000017A* + ID_PRODUCT_FROM_DATABASE=NV17GL [Quadro NVS] + +pci:v000010DEd0000017B* + ID_PRODUCT_FROM_DATABASE=NV17GL [Quadro4 550 XGL] + +pci:v000010DEd0000017C* + ID_PRODUCT_FROM_DATABASE=NV17GL [Quadro4 500 GoGL] + +pci:v000010DEd0000017D* + ID_PRODUCT_FROM_DATABASE=NV17 [GeForce4 410 Go 16M] + +pci:v000010DEd00000181* + ID_PRODUCT_FROM_DATABASE=NV18 [GeForce4 MX 440 AGP 8x] + +pci:v000010DEd00000181sv00001043sd00008063* + ID_PRODUCT_FROM_DATABASE=GeForce4 MX 440 AGP 8X + +pci:v000010DEd00000181sv00001043sd0000806F* + ID_PRODUCT_FROM_DATABASE=V9180 Magic + +pci:v000010DEd00000181sv00001462sd00008880* + ID_PRODUCT_FROM_DATABASE=MS-StarForce GeForce4 MX 440 with AGP8X + +pci:v000010DEd00000181sv00001462sd00008900* + ID_PRODUCT_FROM_DATABASE=MS-8890 GeForce 4 MX440 AGP8X + +pci:v000010DEd00000181sv00001462sd00009350* + ID_PRODUCT_FROM_DATABASE=MSI GeForce4 MX T8X with AGP8X + +pci:v000010DEd00000181sv0000147Bsd00008F0D* + ID_PRODUCT_FROM_DATABASE=Siluro GF4 MX-8X + +pci:v000010DEd00000181sv00001554sd00001111* + ID_PRODUCT_FROM_DATABASE=PixelView MVGA-NVG18A + +pci:v000010DEd00000182* + ID_PRODUCT_FROM_DATABASE=NV18 [GeForce4 MX 440SE AGP 8x] + +pci:v000010DEd00000183* + ID_PRODUCT_FROM_DATABASE=NV18 [GeForce4 MX 420 AGP 8x] + +pci:v000010DEd00000184* + ID_PRODUCT_FROM_DATABASE=NV18 [GeForce4 MX] + +pci:v000010DEd00000185* + ID_PRODUCT_FROM_DATABASE=NV18 [GeForce4 MX 4000] + +pci:v000010DEd00000186* + ID_PRODUCT_FROM_DATABASE=NV18M [GeForce4 448 Go] + +pci:v000010DEd00000187* + ID_PRODUCT_FROM_DATABASE=NV18M [GeForce4 488 Go] + +pci:v000010DEd00000188* + ID_PRODUCT_FROM_DATABASE=NV18GL [Quadro4 580 XGL] + +pci:v000010DEd00000189* + ID_PRODUCT_FROM_DATABASE=NV18 [GeForce4 MX with AGP8X (Mac)] + +pci:v000010DEd0000018A* + ID_PRODUCT_FROM_DATABASE=NV18GL [Quadro NVS 280 SD] + +pci:v000010DEd0000018B* + ID_PRODUCT_FROM_DATABASE=NV18GL [Quadro4 380 XGL] + +pci:v000010DEd0000018C* + ID_PRODUCT_FROM_DATABASE=NV18GL [Quadro NVS 50 PCI] + +pci:v000010DEd0000018D* + ID_PRODUCT_FROM_DATABASE=NV18M [GeForce4 448 Go] + +pci:v000010DEd00000191* + ID_PRODUCT_FROM_DATABASE=G80 [GeForce 8800 GTX] + +pci:v000010DEd00000193* + ID_PRODUCT_FROM_DATABASE=G80 [GeForce 8800 GTS] + +pci:v000010DEd00000193sv0000107Dsd000020BD* + ID_PRODUCT_FROM_DATABASE=WinFast PX 8800 GTS TDH + +pci:v000010DEd00000194* + ID_PRODUCT_FROM_DATABASE=G80 [GeForce 8800 Ultra] + +pci:v000010DEd00000197* + ID_PRODUCT_FROM_DATABASE=G80 [Tesla C870] + +pci:v000010DEd0000019D* + ID_PRODUCT_FROM_DATABASE=G80 [Quadro FX 5600] + +pci:v000010DEd0000019E* + ID_PRODUCT_FROM_DATABASE=G80 [Quadro FX 4600] + +pci:v000010DEd000001A0* + ID_PRODUCT_FROM_DATABASE=nForce 220/420 NV11 [GeForce2 MX] + +pci:v000010DEd000001A4* + ID_PRODUCT_FROM_DATABASE=nForce CPU bridge + +pci:v000010DEd000001AB* + ID_PRODUCT_FROM_DATABASE=nForce 420 Memory Controller (DDR) + +pci:v000010DEd000001AC* + ID_PRODUCT_FROM_DATABASE=nForce 220/420 Memory Controller + +pci:v000010DEd000001AD* + ID_PRODUCT_FROM_DATABASE=nForce 220/420 Memory Controller + +pci:v000010DEd000001B0* + ID_PRODUCT_FROM_DATABASE=nForce Audio Processing Unit + +pci:v000010DEd000001B1* + ID_PRODUCT_FROM_DATABASE=nForce AC'97 Audio Controller + +pci:v000010DEd000001B2* + ID_PRODUCT_FROM_DATABASE=nForce ISA Bridge + +pci:v000010DEd000001B4* + ID_PRODUCT_FROM_DATABASE=nForce PCI System Management + +pci:v000010DEd000001B7* + ID_PRODUCT_FROM_DATABASE=nForce AGP to PCI Bridge + +pci:v000010DEd000001B8* + ID_PRODUCT_FROM_DATABASE=nForce PCI-to-PCI bridge + +pci:v000010DEd000001BC* + ID_PRODUCT_FROM_DATABASE=nForce IDE + +pci:v000010DEd000001C1* + ID_PRODUCT_FROM_DATABASE=nForce AC'97 Modem Controller + +pci:v000010DEd000001C2* + ID_PRODUCT_FROM_DATABASE=nForce USB Controller + +pci:v000010DEd000001C3* + ID_PRODUCT_FROM_DATABASE=nForce Ethernet Controller + +pci:v000010DEd000001D0* + ID_PRODUCT_FROM_DATABASE=G72 [GeForce 7350 LE] + +pci:v000010DEd000001D1* + ID_PRODUCT_FROM_DATABASE=G72 [GeForce 7300 LE] + +pci:v000010DEd000001D1sv00001462sd00000345* + ID_PRODUCT_FROM_DATABASE=7300LE PCI Express Graphics Adapter + +pci:v000010DEd000001D2* + ID_PRODUCT_FROM_DATABASE=G72 [GeForce 7550 LE] + +pci:v000010DEd000001D3* + ID_PRODUCT_FROM_DATABASE=G72 [GeForce 7300 SE/7200 GS] + +pci:v000010DEd000001D6* + ID_PRODUCT_FROM_DATABASE=G72M [GeForce Go 7200] + +pci:v000010DEd000001D7* + ID_PRODUCT_FROM_DATABASE=G72M [Quadro NVS 110M/GeForce Go 7300] + +pci:v000010DEd000001D8* + ID_PRODUCT_FROM_DATABASE=G72M [GeForce Go 7400] + +pci:v000010DEd000001D8sv00001028sd000001D7* + ID_PRODUCT_FROM_DATABASE=XPS M1210 + +pci:v000010DEd000001D9* + ID_PRODUCT_FROM_DATABASE=G72M [GeForce Go 7450] + +pci:v000010DEd000001DA* + ID_PRODUCT_FROM_DATABASE=G72M [Quadro NVS 110M] + +pci:v000010DEd000001DB* + ID_PRODUCT_FROM_DATABASE=G72M [Quadro NVS 120M] + +pci:v000010DEd000001DC* + ID_PRODUCT_FROM_DATABASE=G72GL [Quadro FX 350M] + +pci:v000010DEd000001DD* + ID_PRODUCT_FROM_DATABASE=G72 [GeForce 7500 LE] + +pci:v000010DEd000001DE* + ID_PRODUCT_FROM_DATABASE=G72GL [Quadro FX 350] + +pci:v000010DEd000001DEsv000010DEsd000001DC* + ID_PRODUCT_FROM_DATABASE=Quadro FX Go350M + +pci:v000010DEd000001DF* + ID_PRODUCT_FROM_DATABASE=G71 [GeForce 7300 GS] + +pci:v000010DEd000001E0* + ID_PRODUCT_FROM_DATABASE=nForce2 IGP2 + +pci:v000010DEd000001E0sv0000147Bsd00001C09* + ID_PRODUCT_FROM_DATABASE=NV7 Motherboard + +pci:v000010DEd000001E8* + ID_PRODUCT_FROM_DATABASE=nForce2 AGP + +pci:v000010DEd000001EA* + ID_PRODUCT_FROM_DATABASE=nForce2 Memory Controller 0 + +pci:v000010DEd000001EAsv0000A0A0sd000003B9* + ID_PRODUCT_FROM_DATABASE=UK79G-1394 motherboard + +pci:v000010DEd000001EB* + ID_PRODUCT_FROM_DATABASE=nForce2 Memory Controller 1 + +pci:v000010DEd000001EBsv0000A0A0sd000003B9* + ID_PRODUCT_FROM_DATABASE=UK79G-1394 motherboard + +pci:v000010DEd000001EC* + ID_PRODUCT_FROM_DATABASE=nForce2 Memory Controller 2 + +pci:v000010DEd000001ECsv0000A0A0sd000003B9* + ID_PRODUCT_FROM_DATABASE=UK79G-1394 motherboard + +pci:v000010DEd000001ED* + ID_PRODUCT_FROM_DATABASE=nForce2 Memory Controller 3 + +pci:v000010DEd000001EDsv0000A0A0sd000003B9* + ID_PRODUCT_FROM_DATABASE=UK79G-1394 motherboard + +pci:v000010DEd000001EE* + ID_PRODUCT_FROM_DATABASE=nForce2 Memory Controller 4 + +pci:v000010DEd000001EEsv000010DEsd000001EE* + ID_PRODUCT_FROM_DATABASE=MSI Delta-L nForce2 memory controller + +pci:v000010DEd000001EEsv0000A0A0sd000003B9* + ID_PRODUCT_FROM_DATABASE=UK79G-1394 motherboard + +pci:v000010DEd000001EF* + ID_PRODUCT_FROM_DATABASE=nForce2 Memory Controller 5 + +pci:v000010DEd000001EFsv0000A0A0sd000003B9* + ID_PRODUCT_FROM_DATABASE=UK79G-1394 motherboard + +pci:v000010DEd000001F0* + ID_PRODUCT_FROM_DATABASE=NV18 [GeForce4 MX - nForce GPU] + +pci:v000010DEd000001F0sv0000A0A0sd000003B5* + ID_PRODUCT_FROM_DATABASE=UK79G-1394 motherboard + +pci:v000010DEd00000200* + ID_PRODUCT_FROM_DATABASE=NV20 [GeForce3] + +pci:v000010DEd00000200sv00001043sd0000402F* + ID_PRODUCT_FROM_DATABASE=AGP-V8200 DDR + +pci:v000010DEd00000200sv00001048sd00000C70* + ID_PRODUCT_FROM_DATABASE=GLADIAC 920 + +pci:v000010DEd00000201* + ID_PRODUCT_FROM_DATABASE=NV20 [GeForce3 Ti 200] + +pci:v000010DEd00000202* + ID_PRODUCT_FROM_DATABASE=NV20 [GeForce3 Ti 500] + +pci:v000010DEd00000202sv00001043sd0000405B* + ID_PRODUCT_FROM_DATABASE=V8200 T5 + +pci:v000010DEd00000202sv00001545sd0000002F* + ID_PRODUCT_FROM_DATABASE=Xtasy 6964 + +pci:v000010DEd00000203* + ID_PRODUCT_FROM_DATABASE=NV20DCC [Quadro DCC] + +pci:v000010DEd00000211* + ID_PRODUCT_FROM_DATABASE=NV48 [GeForce 6800] + +pci:v000010DEd00000212* + ID_PRODUCT_FROM_DATABASE=NV48 [GeForce 6800 LE] + +pci:v000010DEd00000215* + ID_PRODUCT_FROM_DATABASE=NV48 [GeForce 6800 GT] + +pci:v000010DEd00000218* + ID_PRODUCT_FROM_DATABASE=NV48 [GeForce 6800 XT] + +pci:v000010DEd00000221* + ID_PRODUCT_FROM_DATABASE=NV44A [GeForce 6200] + +pci:v000010DEd00000221sv00001043sd000081E1* + ID_PRODUCT_FROM_DATABASE=N6200/TD/256M/A + +pci:v000010DEd00000221sv00003842sd0000A341* + ID_PRODUCT_FROM_DATABASE=256A8N341DX + +pci:v000010DEd00000222* + ID_PRODUCT_FROM_DATABASE=NV44 [GeForce 6200 A-LE] + +pci:v000010DEd00000240* + ID_PRODUCT_FROM_DATABASE=C51PV [GeForce 6150] + +pci:v000010DEd00000240sv00001043sd000081CD* + ID_PRODUCT_FROM_DATABASE=A8N-VM CSM + +pci:v000010DEd00000240sv00001462sd00007207* + ID_PRODUCT_FROM_DATABASE=K8NGM2 series + +pci:v000010DEd00000241* + ID_PRODUCT_FROM_DATABASE=C51 [GeForce 6150 LE] + +pci:v000010DEd00000242* + ID_PRODUCT_FROM_DATABASE=C51G [GeForce 6100] + +pci:v000010DEd00000242sv0000105Bsd00000CAD* + ID_PRODUCT_FROM_DATABASE=Winfast 6100K8MB + +pci:v000010DEd00000243* + ID_PRODUCT_FROM_DATABASE=C51 PCI Express Bridge + +pci:v000010DEd00000244* + ID_PRODUCT_FROM_DATABASE=C51 [GeForce Go 6150] + +pci:v000010DEd00000244sv0000103Csd000030B5* + ID_PRODUCT_FROM_DATABASE=Presario V3242AU + +pci:v000010DEd00000244sv0000103Csd000030B7* + ID_PRODUCT_FROM_DATABASE=Presario V6133CL + +pci:v000010DEd00000244sv000010DEsd00000244* + ID_PRODUCT_FROM_DATABASE=GeForce Go 6150 + +pci:v000010DEd00000245* + ID_PRODUCT_FROM_DATABASE=C51 [Quadro NVS 210S/GeForce 6150LE] + +pci:v000010DEd00000246* + ID_PRODUCT_FROM_DATABASE=C51 PCI Express Bridge + +pci:v000010DEd00000247* + ID_PRODUCT_FROM_DATABASE=C51 [GeForce Go 6100] + +pci:v000010DEd00000247sv00001043sd00001382* + ID_PRODUCT_FROM_DATABASE=MCP51 PCI-X GeForce Go 6100 + +pci:v000010DEd00000248* + ID_PRODUCT_FROM_DATABASE=C51 PCI Express Bridge + +pci:v000010DEd00000249* + ID_PRODUCT_FROM_DATABASE=C51 PCI Express Bridge + +pci:v000010DEd0000024A* + ID_PRODUCT_FROM_DATABASE=C51 PCI Express Bridge + +pci:v000010DEd0000024B* + ID_PRODUCT_FROM_DATABASE=C51 PCI Express Bridge + +pci:v000010DEd0000024C* + ID_PRODUCT_FROM_DATABASE=C51 PCI Express Bridge + +pci:v000010DEd0000024D* + ID_PRODUCT_FROM_DATABASE=C51 PCI Express Bridge + +pci:v000010DEd0000024E* + ID_PRODUCT_FROM_DATABASE=C51 PCI Express Bridge + +pci:v000010DEd0000024F* + ID_PRODUCT_FROM_DATABASE=C51 PCI Express Bridge + +pci:v000010DEd00000250* + ID_PRODUCT_FROM_DATABASE=NV25 [GeForce4 Ti 4600] + +pci:v000010DEd00000251* + ID_PRODUCT_FROM_DATABASE=NV25 [GeForce4 Ti 4400] + +pci:v000010DEd00000251sv00001043sd00008023* + ID_PRODUCT_FROM_DATABASE=v8440 GeForce 4 Ti4400 + +pci:v000010DEd00000251sv000010DEsd00000251* + ID_PRODUCT_FROM_DATABASE=PNY GeForce4 Ti 4400 + +pci:v000010DEd00000251sv00001462sd00008710* + ID_PRODUCT_FROM_DATABASE=PNY GeForce4 Ti 4400 + +pci:v000010DEd00000252* + ID_PRODUCT_FROM_DATABASE=NV25 [GeForce4 Ti] + +pci:v000010DEd00000253* + ID_PRODUCT_FROM_DATABASE=NV25 [GeForce4 Ti 4200] + +pci:v000010DEd00000253sv0000107Dsd00002896* + ID_PRODUCT_FROM_DATABASE=WinFast A250 LE TD (Dual VGA/TV-out/DVI) + +pci:v000010DEd00000253sv0000147Bsd00008F09* + ID_PRODUCT_FROM_DATABASE=Siluro (Dual VGA/TV-out/DVI) + +pci:v000010DEd00000258* + ID_PRODUCT_FROM_DATABASE=NV25GL [Quadro4 900 XGL] + +pci:v000010DEd00000259* + ID_PRODUCT_FROM_DATABASE=NV25GL [Quadro4 750 XGL] + +pci:v000010DEd0000025B* + ID_PRODUCT_FROM_DATABASE=NV25GL [Quadro4 700 XGL] + +pci:v000010DEd00000260* + ID_PRODUCT_FROM_DATABASE=MCP51 LPC Bridge + +pci:v000010DEd00000260sv0000103Csd00002A34* + ID_PRODUCT_FROM_DATABASE=Pavilion a1677c + +pci:v000010DEd00000260sv0000103Csd000030B7* + ID_PRODUCT_FROM_DATABASE=Presario V6133CL + +pci:v000010DEd00000260sv00001043sd000081BC* + ID_PRODUCT_FROM_DATABASE=A8N-VM CSM Mainboard + +pci:v000010DEd00000260sv00001458sd00005001* + ID_PRODUCT_FROM_DATABASE=GA-M55plus-S3G + +pci:v000010DEd00000260sv00001462sd00007207* + ID_PRODUCT_FROM_DATABASE=K8NGM2 series + +pci:v000010DEd00000261* + ID_PRODUCT_FROM_DATABASE=MCP51 LPC Bridge + +pci:v000010DEd00000261sv0000105Bsd00000CAD* + ID_PRODUCT_FROM_DATABASE=Winfast 6100K8MB + +pci:v000010DEd00000262* + ID_PRODUCT_FROM_DATABASE=MCP51 LPC Bridge + +pci:v000010DEd00000263* + ID_PRODUCT_FROM_DATABASE=MCP51 LPC Bridge + +pci:v000010DEd00000264* + ID_PRODUCT_FROM_DATABASE=MCP51 SMBus + +pci:v000010DEd00000264sv0000103Csd00002A34* + ID_PRODUCT_FROM_DATABASE=Pavilion a1677c + +pci:v000010DEd00000264sv0000103Csd000030B7* + ID_PRODUCT_FROM_DATABASE=Presario V6133CL + +pci:v000010DEd00000264sv00001043sd000081BC* + ID_PRODUCT_FROM_DATABASE=A8N-VM CSM Mainboard + +pci:v000010DEd00000264sv0000105Bsd00000CAD* + ID_PRODUCT_FROM_DATABASE=Winfast 6100K8MB + +pci:v000010DEd00000264sv00001462sd00007207* + ID_PRODUCT_FROM_DATABASE=K8NGM2 series + +pci:v000010DEd00000265* + ID_PRODUCT_FROM_DATABASE=MCP51 IDE + +pci:v000010DEd00000265sv0000103Csd00002A34* + ID_PRODUCT_FROM_DATABASE=Pavilion a1677c + +pci:v000010DEd00000265sv0000103Csd000030B7* + ID_PRODUCT_FROM_DATABASE=Presario V6133CL + +pci:v000010DEd00000265sv00001043sd000081BC* + ID_PRODUCT_FROM_DATABASE=A8N-VM CSM Mainboard + +pci:v000010DEd00000265sv00001462sd00007207* + ID_PRODUCT_FROM_DATABASE=K8NGM2 series + +pci:v000010DEd00000265sv0000F05Bsd00000CAD* + ID_PRODUCT_FROM_DATABASE=Winfast 6100K8MB + +pci:v000010DEd00000266* + ID_PRODUCT_FROM_DATABASE=MCP51 Serial ATA Controller + +pci:v000010DEd00000266sv0000103Csd00002A34* + ID_PRODUCT_FROM_DATABASE=Pavilion a1677c + +pci:v000010DEd00000266sv0000103Csd000030B7* + ID_PRODUCT_FROM_DATABASE=Presario V6133CL + +pci:v000010DEd00000266sv00001043sd000081BC* + ID_PRODUCT_FROM_DATABASE=A8N-VM CSM Mainboard + +pci:v000010DEd00000266sv00001462sd00007207* + ID_PRODUCT_FROM_DATABASE=K8NGM2 series + +pci:v000010DEd00000267* + ID_PRODUCT_FROM_DATABASE=MCP51 Serial ATA Controller + +pci:v000010DEd00000267sv0000103Csd00002A34* + ID_PRODUCT_FROM_DATABASE=Pavilion a1677c + +pci:v000010DEd00000267sv00001043sd000081BC* + ID_PRODUCT_FROM_DATABASE=A8N-VM CSM Mainboard + +pci:v000010DEd00000267sv00001462sd00007207* + ID_PRODUCT_FROM_DATABASE=K8NGM2 series + +pci:v000010DEd00000268* + ID_PRODUCT_FROM_DATABASE=MCP51 Ethernet Controller + +pci:v000010DEd00000269* + ID_PRODUCT_FROM_DATABASE=MCP51 Ethernet Controller + +pci:v000010DEd00000269sv0000103Csd00002A34* + ID_PRODUCT_FROM_DATABASE=Pavilion a1677c + +pci:v000010DEd00000269sv0000103Csd000030B7* + ID_PRODUCT_FROM_DATABASE=Presario V6133CL + +pci:v000010DEd00000269sv00001043sd00008141* + ID_PRODUCT_FROM_DATABASE=A8N-VM CSM Mainboard + +pci:v000010DEd00000269sv00001462sd00007207* + ID_PRODUCT_FROM_DATABASE=K8NGM2 series + +pci:v000010DEd0000026A* + ID_PRODUCT_FROM_DATABASE=MCP51 MCI + +pci:v000010DEd0000026B* + ID_PRODUCT_FROM_DATABASE=MCP51 AC97 Audio Controller + +pci:v000010DEd0000026Bsv0000105Bsd00000CAD* + ID_PRODUCT_FROM_DATABASE=Winfast 6100K8MB + +pci:v000010DEd0000026C* + ID_PRODUCT_FROM_DATABASE=MCP51 High Definition Audio + +pci:v000010DEd0000026Csv0000103Csd00002A34* + ID_PRODUCT_FROM_DATABASE=Pavilion a1677c + +pci:v000010DEd0000026Csv0000103Csd000030B5* + ID_PRODUCT_FROM_DATABASE=Presario V3242AU + +pci:v000010DEd0000026Csv0000103Csd000030B7* + ID_PRODUCT_FROM_DATABASE=Presario V6133CL + +pci:v000010DEd0000026Csv000010DEsd0000CB84* + ID_PRODUCT_FROM_DATABASE=ASUSTeK Computer Inc. A8N-VM CSM Mainboard + +pci:v000010DEd0000026Csv00001462sd00007207* + ID_PRODUCT_FROM_DATABASE=K8NGM2 series + +pci:v000010DEd0000026D* + ID_PRODUCT_FROM_DATABASE=MCP51 USB Controller + +pci:v000010DEd0000026Dsv0000103Csd00002A34* + ID_PRODUCT_FROM_DATABASE=Pavilion a1677c + +pci:v000010DEd0000026Dsv0000103Csd000030B7* + ID_PRODUCT_FROM_DATABASE=Presario V6133CL + +pci:v000010DEd0000026Dsv00001043sd000081BC* + ID_PRODUCT_FROM_DATABASE=A8N-VM CSM Mainboard + +pci:v000010DEd0000026Dsv0000105Bsd00000CAD* + ID_PRODUCT_FROM_DATABASE=Winfast 6100K8MB + +pci:v000010DEd0000026Dsv00001462sd00007207* + ID_PRODUCT_FROM_DATABASE=K8NGM2 series + +pci:v000010DEd0000026E* + ID_PRODUCT_FROM_DATABASE=MCP51 USB Controller + +pci:v000010DEd0000026Esv0000103Csd00002A34* + ID_PRODUCT_FROM_DATABASE=Pavilion a1677c + +pci:v000010DEd0000026Esv0000103Csd000030B7* + ID_PRODUCT_FROM_DATABASE=Presario V6133CL + +pci:v000010DEd0000026Esv00001043sd000081BC* + ID_PRODUCT_FROM_DATABASE=A8N-VM CSM Mainboard + +pci:v000010DEd0000026Esv0000105Bsd00000CAD* + ID_PRODUCT_FROM_DATABASE=Winfast 6100K8MB + +pci:v000010DEd0000026Esv00001462sd00007207* + ID_PRODUCT_FROM_DATABASE=K8NGM2 series + +pci:v000010DEd0000026F* + ID_PRODUCT_FROM_DATABASE=MCP51 PCI Bridge + +pci:v000010DEd0000026Fsv0000103Csd000030B7* + ID_PRODUCT_FROM_DATABASE=Presario V6133CL + +pci:v000010DEd00000270* + ID_PRODUCT_FROM_DATABASE=MCP51 Host Bridge + +pci:v000010DEd00000270sv0000103Csd00002A34* + ID_PRODUCT_FROM_DATABASE=Pavilion a1677c + +pci:v000010DEd00000270sv0000103Csd000030B7* + ID_PRODUCT_FROM_DATABASE=Presario V6133CL + +pci:v000010DEd00000270sv00001043sd000081BC* + ID_PRODUCT_FROM_DATABASE=A8N-VM CSM Mainboard + +pci:v000010DEd00000270sv0000105Bsd00000CAD* + ID_PRODUCT_FROM_DATABASE=Winfast 6100K8MB + +pci:v000010DEd00000270sv00001458sd00005001* + ID_PRODUCT_FROM_DATABASE=GA-M55plus-S3G + +pci:v000010DEd00000270sv00001462sd00007207* + ID_PRODUCT_FROM_DATABASE=K8NGM2 series + +pci:v000010DEd00000271* + ID_PRODUCT_FROM_DATABASE=MCP51 PMU + +pci:v000010DEd00000271sv0000103Csd000030B5* + ID_PRODUCT_FROM_DATABASE=Presario V3242AU + +pci:v000010DEd00000271sv0000103Csd000030B7* + ID_PRODUCT_FROM_DATABASE=Presario V6133CL + +pci:v000010DEd00000272* + ID_PRODUCT_FROM_DATABASE=MCP51 Memory Controller 0 + +pci:v000010DEd00000272sv0000103Csd00002A34* + ID_PRODUCT_FROM_DATABASE=Pavilion a1677c + +pci:v000010DEd00000272sv0000105Bsd00000CAD* + ID_PRODUCT_FROM_DATABASE=Winfast 6100K8MB + +pci:v000010DEd0000027E* + ID_PRODUCT_FROM_DATABASE=C51 Memory Controller 2 + +pci:v000010DEd0000027Esv0000103Csd00002A34* + ID_PRODUCT_FROM_DATABASE=Pavilion a1677c + +pci:v000010DEd0000027Esv0000103Csd000030B7* + ID_PRODUCT_FROM_DATABASE=Presario V6133CL + +pci:v000010DEd0000027Esv00001043sd000081CD* + ID_PRODUCT_FROM_DATABASE=A8N-VM CSM Mainboard + +pci:v000010DEd0000027Esv00001458sd00005000* + ID_PRODUCT_FROM_DATABASE=GA-M55plus-S3G + +pci:v000010DEd0000027Esv00001462sd00007207* + ID_PRODUCT_FROM_DATABASE=K8NGM2 series + +pci:v000010DEd0000027F* + ID_PRODUCT_FROM_DATABASE=C51 Memory Controller 3 + +pci:v000010DEd0000027Fsv0000103Csd00002A34* + ID_PRODUCT_FROM_DATABASE=Pavilion a1677c + +pci:v000010DEd0000027Fsv0000103Csd000030B7* + ID_PRODUCT_FROM_DATABASE=Presario V6133CL + +pci:v000010DEd0000027Fsv00001043sd000081CD* + ID_PRODUCT_FROM_DATABASE=A8N-VM CSM Mainboard + +pci:v000010DEd0000027Fsv00001458sd00005000* + ID_PRODUCT_FROM_DATABASE=GA-M55plus-S3G + +pci:v000010DEd0000027Fsv00001462sd00007207* + ID_PRODUCT_FROM_DATABASE=K8NGM2 series + +pci:v000010DEd00000280* + ID_PRODUCT_FROM_DATABASE=NV28 [GeForce4 Ti 4800] + +pci:v000010DEd00000281* + ID_PRODUCT_FROM_DATABASE=NV28 [GeForce4 Ti 4200 AGP 8x] + +pci:v000010DEd00000282* + ID_PRODUCT_FROM_DATABASE=NV28 [GeForce4 Ti 4800 SE] + +pci:v000010DEd00000286* + ID_PRODUCT_FROM_DATABASE=NV28 [GeForce4 Ti 4200 Go AGP 8x] + +pci:v000010DEd00000288* + ID_PRODUCT_FROM_DATABASE=NV28GL [Quadro4 980 XGL] + +pci:v000010DEd00000289* + ID_PRODUCT_FROM_DATABASE=NV28GL [Quadro4 780 XGL] + +pci:v000010DEd0000028C* + ID_PRODUCT_FROM_DATABASE=NV28GLM [Quadro4 Go700] + +pci:v000010DEd00000290* + ID_PRODUCT_FROM_DATABASE=G71 [GeForce 7900 GTX] + +pci:v000010DEd00000291* + ID_PRODUCT_FROM_DATABASE=G71 [GeForce 7900 GT/GTO] + +pci:v000010DEd00000291sv000010DEsd0000042B* + ID_PRODUCT_FROM_DATABASE=NX7900GTO-T2D512E [7900 GTO] + +pci:v000010DEd00000292* + ID_PRODUCT_FROM_DATABASE=G71 [GeForce 7900 GS] + +pci:v000010DEd00000293* + ID_PRODUCT_FROM_DATABASE=G71 [GeForce 7900 GX2] + +pci:v000010DEd00000294* + ID_PRODUCT_FROM_DATABASE=G71 [GeForce 7950 GX2] + +pci:v000010DEd00000295* + ID_PRODUCT_FROM_DATABASE=G71 [GeForce 7950 GT] + +pci:v000010DEd00000295sv00001043sd00008225* + ID_PRODUCT_FROM_DATABASE=GeForce 7950 GT + +pci:v000010DEd00000295sv0000107Dsd00002A68* + ID_PRODUCT_FROM_DATABASE=WinFast PX7950GT TDH + +pci:v000010DEd00000295sv00001462sd00000663* + ID_PRODUCT_FROM_DATABASE=NX7950GT-VT2D512EZ-HD + +pci:v000010DEd00000297* + ID_PRODUCT_FROM_DATABASE=G71 [GeForce Go 7950 GTX] + +pci:v000010DEd00000298* + ID_PRODUCT_FROM_DATABASE=G71 [GeForce Go 7900 GS] + +pci:v000010DEd00000299* + ID_PRODUCT_FROM_DATABASE=G71 [GeForce Go 7900 GTX] + +pci:v000010DEd0000029A* + ID_PRODUCT_FROM_DATABASE=G71 [Quadro FX 2500M] + +pci:v000010DEd0000029B* + ID_PRODUCT_FROM_DATABASE=G71 [Quadro FX 1500M] + +pci:v000010DEd0000029C* + ID_PRODUCT_FROM_DATABASE=G71 [Quadro FX 5500] + +pci:v000010DEd0000029D* + ID_PRODUCT_FROM_DATABASE=G71GL [Quadro FX 3500] + +pci:v000010DEd0000029E* + ID_PRODUCT_FROM_DATABASE=G71 [Quadro FX 1500] + +pci:v000010DEd0000029F* + ID_PRODUCT_FROM_DATABASE=G70 [Quadro FX 4500 X2] + +pci:v000010DEd000002A0* + ID_PRODUCT_FROM_DATABASE=NV2A [XGPU] + +pci:v000010DEd000002A5* + ID_PRODUCT_FROM_DATABASE=MCPX CPU Bridge + +pci:v000010DEd000002A6* + ID_PRODUCT_FROM_DATABASE=MCPX Memory Controller + +pci:v000010DEd000002E0* + ID_PRODUCT_FROM_DATABASE=G73 [GeForce 7600 GT] + +pci:v000010DEd000002E0sv000002E0sd00002249* + ID_PRODUCT_FROM_DATABASE=GF 7600GT 560M 256MB DDR3 DUAL DVI TV + +pci:v000010DEd000002E1* + ID_PRODUCT_FROM_DATABASE=G73 [GeForce 7600 GS] + +pci:v000010DEd000002E1sv00001682sd0000222B* + ID_PRODUCT_FROM_DATABASE=PV-T73K-UAL3 (256MB) + +pci:v000010DEd000002E1sv00001682sd00002247* + ID_PRODUCT_FROM_DATABASE=GF 7600GS 512MB DDR2 + +pci:v000010DEd000002E2* + ID_PRODUCT_FROM_DATABASE=G73 [GeForce 7300 GT] + +pci:v000010DEd000002E3* + ID_PRODUCT_FROM_DATABASE=G71 [GeForce 7900 GS] + +pci:v000010DEd000002E4* + ID_PRODUCT_FROM_DATABASE=G71 [GeForce 7950 GT] + +pci:v000010DEd000002E4sv00001682sd00002271* + ID_PRODUCT_FROM_DATABASE=PV-T71A-YDF7 (512MB) + +pci:v000010DEd000002F0* + ID_PRODUCT_FROM_DATABASE=C51 Host Bridge + +pci:v000010DEd000002F0sv0000103Csd00002A34* + ID_PRODUCT_FROM_DATABASE=Pavilion a1677c + +pci:v000010DEd000002F0sv0000103Csd000030B7* + ID_PRODUCT_FROM_DATABASE=Presario V6133CL + +pci:v000010DEd000002F0sv00001043sd000081CD* + ID_PRODUCT_FROM_DATABASE=A8N-VM CSM Mainboard + +pci:v000010DEd000002F0sv00001462sd00007207* + ID_PRODUCT_FROM_DATABASE=K8NGM2 series + +pci:v000010DEd000002F1* + ID_PRODUCT_FROM_DATABASE=C51 Host Bridge + +pci:v000010DEd000002F1sv00001458sd00005000* + ID_PRODUCT_FROM_DATABASE=GA-M55plus-S3G + +pci:v000010DEd000002F2* + ID_PRODUCT_FROM_DATABASE=C51 Host Bridge + +pci:v000010DEd000002F3* + ID_PRODUCT_FROM_DATABASE=C51 Host Bridge + +pci:v000010DEd000002F4* + ID_PRODUCT_FROM_DATABASE=C51 Host Bridge + +pci:v000010DEd000002F5* + ID_PRODUCT_FROM_DATABASE=C51 Host Bridge + +pci:v000010DEd000002F6* + ID_PRODUCT_FROM_DATABASE=C51 Host Bridge + +pci:v000010DEd000002F7* + ID_PRODUCT_FROM_DATABASE=C51 Host Bridge + +pci:v000010DEd000002F8* + ID_PRODUCT_FROM_DATABASE=C51 Memory Controller 5 + +pci:v000010DEd000002F8sv0000103Csd00002A34* + ID_PRODUCT_FROM_DATABASE=Pavilion a1677c + +pci:v000010DEd000002F8sv0000103Csd000030B7* + ID_PRODUCT_FROM_DATABASE=Presario V6133CL + +pci:v000010DEd000002F8sv00001043sd000081CD* + ID_PRODUCT_FROM_DATABASE=A8N-VM CSM Mainboard + +pci:v000010DEd000002F8sv00001458sd00005000* + ID_PRODUCT_FROM_DATABASE=GA-M55plus-S3G + +pci:v000010DEd000002F8sv00001462sd00007207* + ID_PRODUCT_FROM_DATABASE=K8NGM2 series + +pci:v000010DEd000002F9* + ID_PRODUCT_FROM_DATABASE=C51 Memory Controller 4 + +pci:v000010DEd000002F9sv0000103Csd00002A34* + ID_PRODUCT_FROM_DATABASE=Pavilion a1677c + +pci:v000010DEd000002F9sv0000103Csd000030B7* + ID_PRODUCT_FROM_DATABASE=Presario V6133CL + +pci:v000010DEd000002F9sv00001043sd000081CD* + ID_PRODUCT_FROM_DATABASE=A8N-VM CSM Mainboard + +pci:v000010DEd000002F9sv00001458sd00005000* + ID_PRODUCT_FROM_DATABASE=GA-M55plus-S3G + +pci:v000010DEd000002F9sv00001462sd00007207* + ID_PRODUCT_FROM_DATABASE=K8NGM2 series + +pci:v000010DEd000002FA* + ID_PRODUCT_FROM_DATABASE=C51 Memory Controller 0 + +pci:v000010DEd000002FAsv0000103Csd00002A34* + ID_PRODUCT_FROM_DATABASE=Pavilion a1677c + +pci:v000010DEd000002FAsv0000103Csd000030B7* + ID_PRODUCT_FROM_DATABASE=Presario V6133CL + +pci:v000010DEd000002FAsv00001043sd000081CD* + ID_PRODUCT_FROM_DATABASE=A8N-VM CSM Mainboard + +pci:v000010DEd000002FAsv00001458sd00005000* + ID_PRODUCT_FROM_DATABASE=GA-M55plus-S3G + +pci:v000010DEd000002FAsv00001462sd00007207* + ID_PRODUCT_FROM_DATABASE=K8NGM2 series + +pci:v000010DEd000002FB* + ID_PRODUCT_FROM_DATABASE=C51 PCI Express Bridge + +pci:v000010DEd000002FC* + ID_PRODUCT_FROM_DATABASE=C51 PCI Express Bridge + +pci:v000010DEd000002FCsv0000103Csd000030B7* + ID_PRODUCT_FROM_DATABASE=Presario V6133CL + +pci:v000010DEd000002FD* + ID_PRODUCT_FROM_DATABASE=C51 PCI Express Bridge + +pci:v000010DEd000002FDsv0000103Csd000030B7* + ID_PRODUCT_FROM_DATABASE=Presario V6133CL + +pci:v000010DEd000002FE* + ID_PRODUCT_FROM_DATABASE=C51 Memory Controller 1 + +pci:v000010DEd000002FEsv0000103Csd00002A34* + ID_PRODUCT_FROM_DATABASE=Pavilion a1677c + +pci:v000010DEd000002FEsv0000103Csd000030B7* + ID_PRODUCT_FROM_DATABASE=Presario V6133CL + +pci:v000010DEd000002FEsv00001043sd000081CD* + ID_PRODUCT_FROM_DATABASE=A8N-VM CSM Mainboard + +pci:v000010DEd000002FEsv00001458sd00005000* + ID_PRODUCT_FROM_DATABASE=GA-M55plus-S3G + +pci:v000010DEd000002FEsv00001462sd00007207* + ID_PRODUCT_FROM_DATABASE=K8NGM2 series + +pci:v000010DEd000002FF* + ID_PRODUCT_FROM_DATABASE=C51 Host Bridge + +pci:v000010DEd000002FFsv0000103Csd00002A34* + ID_PRODUCT_FROM_DATABASE=Pavilion a1677c + +pci:v000010DEd000002FFsv0000103Csd000030B7* + ID_PRODUCT_FROM_DATABASE=Presario V6133CL + +pci:v000010DEd000002FFsv00001043sd000081CD* + ID_PRODUCT_FROM_DATABASE=A8N-VM CSM Mainboard + +pci:v000010DEd000002FFsv00001458sd00005000* + ID_PRODUCT_FROM_DATABASE=GA-M55plus-S3G + +pci:v000010DEd000002FFsv00001462sd00007207* + ID_PRODUCT_FROM_DATABASE=K8NGM2 series + +pci:v000010DEd00000300* + ID_PRODUCT_FROM_DATABASE=NV30 [GeForce FX] + +pci:v000010DEd00000301* + ID_PRODUCT_FROM_DATABASE=NV30 [GeForce FX 5800 Ultra] + +pci:v000010DEd00000302* + ID_PRODUCT_FROM_DATABASE=NV30 [GeForce FX 5800] + +pci:v000010DEd00000308* + ID_PRODUCT_FROM_DATABASE=NV30GL [Quadro FX 2000] + +pci:v000010DEd00000309* + ID_PRODUCT_FROM_DATABASE=NV30GL [Quadro FX 1000] + +pci:v000010DEd00000311* + ID_PRODUCT_FROM_DATABASE=NV31 [GeForce FX 5600 Ultra] + +pci:v000010DEd00000312* + ID_PRODUCT_FROM_DATABASE=NV31 [GeForce FX 5600] + +pci:v000010DEd00000313* + ID_PRODUCT_FROM_DATABASE=NV31 + +pci:v000010DEd00000314* + ID_PRODUCT_FROM_DATABASE=NV31 [GeForce FX 5600XT] + +pci:v000010DEd00000314sv00001043sd0000814A* + ID_PRODUCT_FROM_DATABASE=V9560XT/TD + +pci:v000010DEd00000316* + ID_PRODUCT_FROM_DATABASE=NV31M + +pci:v000010DEd00000317* + ID_PRODUCT_FROM_DATABASE=NV31M Pro + +pci:v000010DEd0000031A* + ID_PRODUCT_FROM_DATABASE=NV31M [GeForce FX Go5600] + +pci:v000010DEd0000031B* + ID_PRODUCT_FROM_DATABASE=NV31M [GeForce FX Go5650] + +pci:v000010DEd0000031C* + ID_PRODUCT_FROM_DATABASE=NV31 [Quadro FX Go700] + +pci:v000010DEd0000031D* + ID_PRODUCT_FROM_DATABASE=NV31GLM + +pci:v000010DEd0000031E* + ID_PRODUCT_FROM_DATABASE=NV31GLM Pro + +pci:v000010DEd0000031F* + ID_PRODUCT_FROM_DATABASE=NV31GLM Pro + +pci:v000010DEd00000320* + ID_PRODUCT_FROM_DATABASE=NV34 [GeForce FX 5200] + +pci:v000010DEd00000321* + ID_PRODUCT_FROM_DATABASE=NV34 [GeForce FX 5200 Ultra] + +pci:v000010DEd00000322* + ID_PRODUCT_FROM_DATABASE=NV34 [GeForce FX 5200] + +pci:v000010DEd00000322sv00001043sd000002FB* + ID_PRODUCT_FROM_DATABASE=V9250 Magic + +pci:v000010DEd00000322sv00001043sd00008180* + ID_PRODUCT_FROM_DATABASE=V9520-X/TD/128M + +pci:v000010DEd00000322sv00001462sd00009110* + ID_PRODUCT_FROM_DATABASE=MS-8911 (FX5200-TD128) + +pci:v000010DEd00000322sv00001462sd00009171* + ID_PRODUCT_FROM_DATABASE=MS-8917 (FX5200-T128) + +pci:v000010DEd00000322sv00001462sd00009360* + ID_PRODUCT_FROM_DATABASE=MS-8936 (FX5200-T128) + +pci:v000010DEd00000322sv00001682sd00001351* + ID_PRODUCT_FROM_DATABASE=GeForce FX 5200 + +pci:v000010DEd00000323* + ID_PRODUCT_FROM_DATABASE=NV34 [GeForce FX 5200LE] + +pci:v000010DEd00000324* + ID_PRODUCT_FROM_DATABASE=NV34M [GeForce FX Go5200 64M] + +pci:v000010DEd00000324sv00001028sd00000196* + ID_PRODUCT_FROM_DATABASE=Inspiron 5160 + +pci:v000010DEd00000324sv0000103Csd0000006A* + ID_PRODUCT_FROM_DATABASE=Pavilion ZD7000 laptop + +pci:v000010DEd00000324sv00001071sd00008160* + ID_PRODUCT_FROM_DATABASE=MIM2000 + +pci:v000010DEd00000325* + ID_PRODUCT_FROM_DATABASE=NV34M [GeForce FX Go5250] + +pci:v000010DEd00000326* + ID_PRODUCT_FROM_DATABASE=NV34 [GeForce FX 5500] + +pci:v000010DEd00000326sv00001458sd0000310D* + ID_PRODUCT_FROM_DATABASE=GeForce FX 5500 128 MB + +pci:v000010DEd00000326sv00001682sd00002034* + ID_PRODUCT_FROM_DATABASE=GeForce 5500 256 MB + +pci:v000010DEd00000327* + ID_PRODUCT_FROM_DATABASE=NV34 [GeForce FX 5100] + +pci:v000010DEd00000328* + ID_PRODUCT_FROM_DATABASE=NV34M [GeForce FX Go5200 32M/64M] + +pci:v000010DEd00000329* + ID_PRODUCT_FROM_DATABASE=NV34M [GeForce FX Go5200] + +pci:v000010DEd00000329sv000010DEsd00000010* + ID_PRODUCT_FROM_DATABASE=Powerbook G4 + +pci:v000010DEd0000032A* + ID_PRODUCT_FROM_DATABASE=NV34GL [Quadro NVS 280 PCI] + +pci:v000010DEd0000032B* + ID_PRODUCT_FROM_DATABASE=NV34GL [Quadro FX 500/600 PCI] + +pci:v000010DEd0000032C* + ID_PRODUCT_FROM_DATABASE=NV34GLM [GeForce FX Go 5300] + +pci:v000010DEd0000032D* + ID_PRODUCT_FROM_DATABASE=NV34 [GeForce FX Go5100] + +pci:v000010DEd0000032F* + ID_PRODUCT_FROM_DATABASE=NV34GL + +pci:v000010DEd00000330* + ID_PRODUCT_FROM_DATABASE=NV35 [GeForce FX 5900 Ultra] + +pci:v000010DEd00000330sv00001043sd00008137* + ID_PRODUCT_FROM_DATABASE=V9950 Ultra / 256 MB + +pci:v000010DEd00000331* + ID_PRODUCT_FROM_DATABASE=NV35 [GeForce FX 5900] + +pci:v000010DEd00000331sv00001043sd00008145* + ID_PRODUCT_FROM_DATABASE=V9950GE + +pci:v000010DEd00000332* + ID_PRODUCT_FROM_DATABASE=NV35 [GeForce FX 5900XT] + +pci:v000010DEd00000333* + ID_PRODUCT_FROM_DATABASE=NV38 [GeForce FX 5950 Ultra] + +pci:v000010DEd00000334* + ID_PRODUCT_FROM_DATABASE=NV35 [GeForce FX 5900ZT] + +pci:v000010DEd00000334sv00001462sd00009373* + ID_PRODUCT_FROM_DATABASE=FX5900ZT-VTD128 (MS-8937) + +pci:v000010DEd00000338* + ID_PRODUCT_FROM_DATABASE=NV35GL [Quadro FX 3000] + +pci:v000010DEd0000033F* + ID_PRODUCT_FROM_DATABASE=NV35GL [Quadro FX 700] + +pci:v000010DEd00000341* + ID_PRODUCT_FROM_DATABASE=NV36.1 [GeForce FX 5700 Ultra] + +pci:v000010DEd00000341sv00001462sd00009380* + ID_PRODUCT_FROM_DATABASE=MS-8938 (FX5700U-TD128) + +pci:v000010DEd00000342* + ID_PRODUCT_FROM_DATABASE=NV36.2 [GeForce FX 5700] + +pci:v000010DEd00000343* + ID_PRODUCT_FROM_DATABASE=NV36 [GeForce FX 5700LE] + +pci:v000010DEd00000344* + ID_PRODUCT_FROM_DATABASE=NV36.4 [GeForce FX 5700VE] + +pci:v000010DEd00000345* + ID_PRODUCT_FROM_DATABASE=NV36.5 + +pci:v000010DEd00000347* + ID_PRODUCT_FROM_DATABASE=NV36 [GeForce FX Go5700] + +pci:v000010DEd00000347sv0000103Csd0000006A* + ID_PRODUCT_FROM_DATABASE=NX9500 + +pci:v000010DEd00000348* + ID_PRODUCT_FROM_DATABASE=NV36 [GeForce FX Go5700] + +pci:v000010DEd00000349* + ID_PRODUCT_FROM_DATABASE=NV36M Pro + +pci:v000010DEd0000034B* + ID_PRODUCT_FROM_DATABASE=NV36MAP + +pci:v000010DEd0000034C* + ID_PRODUCT_FROM_DATABASE=NV36 [Quadro FX Go1000] + +pci:v000010DEd0000034E* + ID_PRODUCT_FROM_DATABASE=NV36GL [Quadro FX 1100] + +pci:v000010DEd0000034F* + ID_PRODUCT_FROM_DATABASE=NV36GL + +pci:v000010DEd00000360* + ID_PRODUCT_FROM_DATABASE=MCP55 LPC Bridge + +pci:v000010DEd00000361* + ID_PRODUCT_FROM_DATABASE=MCP55 LPC Bridge + +pci:v000010DEd00000361sv00001028sd00000221* + ID_PRODUCT_FROM_DATABASE=PowerEdge R805 MCP55 LPC Bridge + +pci:v000010DEd00000362* + ID_PRODUCT_FROM_DATABASE=MCP55 LPC Bridge + +pci:v000010DEd00000362sv0000147Bsd00001C24* + ID_PRODUCT_FROM_DATABASE=KN9 series mainboard + +pci:v000010DEd00000363* + ID_PRODUCT_FROM_DATABASE=MCP55 LPC Bridge + +pci:v000010DEd00000364* + ID_PRODUCT_FROM_DATABASE=MCP55 LPC Bridge + +pci:v000010DEd00000364sv00001028sd00000221* + ID_PRODUCT_FROM_DATABASE=PowerEdge R805 MCP55 LPC Bridge + +pci:v000010DEd00000365* + ID_PRODUCT_FROM_DATABASE=MCP55 LPC Bridge + +pci:v000010DEd00000366* + ID_PRODUCT_FROM_DATABASE=MCP55 LPC Bridge + +pci:v000010DEd00000367* + ID_PRODUCT_FROM_DATABASE=MCP55 LPC Bridge + +pci:v000010DEd00000368* + ID_PRODUCT_FROM_DATABASE=MCP55 SMBus + +pci:v000010DEd00000368sv00001028sd0000020C* + ID_PRODUCT_FROM_DATABASE=PowerEdge M605 MCP55 SMBus + +pci:v000010DEd00000368sv00001028sd00000221* + ID_PRODUCT_FROM_DATABASE=PowerEdge R805 MCP55 SMBus + +pci:v000010DEd00000368sv0000147Bsd00001C24* + ID_PRODUCT_FROM_DATABASE=KN9 series mainboard + +pci:v000010DEd00000369* + ID_PRODUCT_FROM_DATABASE=MCP55 Memory Controller + +pci:v000010DEd00000369sv0000147Bsd00001C24* + ID_PRODUCT_FROM_DATABASE=KN9 series mainboard + +pci:v000010DEd0000036A* + ID_PRODUCT_FROM_DATABASE=MCP55 Memory Controller + +pci:v000010DEd0000036B* + ID_PRODUCT_FROM_DATABASE=MCP55 SMU + +pci:v000010DEd0000036C* + ID_PRODUCT_FROM_DATABASE=MCP55 USB Controller + +pci:v000010DEd0000036Csv00001028sd0000020C* + ID_PRODUCT_FROM_DATABASE=PowerEdge M605 MCP55 USB Controller + +pci:v000010DEd0000036Csv00001028sd00000221* + ID_PRODUCT_FROM_DATABASE=PowerEdge R805 MCP55 USB Controller + +pci:v000010DEd0000036Csv0000147Bsd00001C24* + ID_PRODUCT_FROM_DATABASE=KN9 series mainboard + +pci:v000010DEd0000036D* + ID_PRODUCT_FROM_DATABASE=MCP55 USB Controller + +pci:v000010DEd0000036Dsv00001028sd0000020C* + ID_PRODUCT_FROM_DATABASE=PowerEdge M605 MCP55 USB Controller + +pci:v000010DEd0000036Dsv00001028sd00000221* + ID_PRODUCT_FROM_DATABASE=PowerEdge R805 MCP55 USB Controller + +pci:v000010DEd0000036Dsv0000147Bsd00001C24* + ID_PRODUCT_FROM_DATABASE=KN9 series mainboard + +pci:v000010DEd0000036E* + ID_PRODUCT_FROM_DATABASE=MCP55 IDE + +pci:v000010DEd0000036Esv0000147Bsd00001C24* + ID_PRODUCT_FROM_DATABASE=KN9 series mainboard + +pci:v000010DEd00000370* + ID_PRODUCT_FROM_DATABASE=MCP55 PCI bridge + +pci:v000010DEd00000371* + ID_PRODUCT_FROM_DATABASE=MCP55 High Definition Audio + +pci:v000010DEd00000371sv0000147Bsd00001C24* + ID_PRODUCT_FROM_DATABASE=KN9 series mainboard + +pci:v000010DEd00000372* + ID_PRODUCT_FROM_DATABASE=MCP55 Ethernet + +pci:v000010DEd00000373* + ID_PRODUCT_FROM_DATABASE=MCP55 Ethernet + +pci:v000010DEd00000373sv0000147Bsd00001C24* + ID_PRODUCT_FROM_DATABASE=KN9 series mainboard + +pci:v000010DEd00000374* + ID_PRODUCT_FROM_DATABASE=MCP55 PCI Express bridge + +pci:v000010DEd00000375* + ID_PRODUCT_FROM_DATABASE=MCP55 PCI Express bridge + +pci:v000010DEd00000376* + ID_PRODUCT_FROM_DATABASE=MCP55 PCI Express bridge + +pci:v000010DEd00000377* + ID_PRODUCT_FROM_DATABASE=MCP55 PCI Express bridge + +pci:v000010DEd00000378* + ID_PRODUCT_FROM_DATABASE=MCP55 PCI Express bridge + +pci:v000010DEd0000037A* + ID_PRODUCT_FROM_DATABASE=MCP55 Memory Controller + +pci:v000010DEd0000037E* + ID_PRODUCT_FROM_DATABASE=MCP55 SATA Controller + +pci:v000010DEd0000037F* + ID_PRODUCT_FROM_DATABASE=MCP55 SATA Controller + +pci:v000010DEd0000037Fsv00001028sd00000221* + ID_PRODUCT_FROM_DATABASE=PowerEdge R805 MCP55 SATA Controller + +pci:v000010DEd0000037Fsv0000147Bsd00001C24* + ID_PRODUCT_FROM_DATABASE=KN9 series mainboard + +pci:v000010DEd0000038B* + ID_PRODUCT_FROM_DATABASE=G73 [GeForce 7650 GS] + +pci:v000010DEd00000390* + ID_PRODUCT_FROM_DATABASE=G73 [GeForce 7650 GS] + +pci:v000010DEd00000391* + ID_PRODUCT_FROM_DATABASE=G73 [GeForce 7600 GT] + +pci:v000010DEd00000391sv00001458sd00003427* + ID_PRODUCT_FROM_DATABASE=GV-NX76T128D-RH + +pci:v000010DEd00000392* + ID_PRODUCT_FROM_DATABASE=G73 [GeForce 7600 GS] + +pci:v000010DEd00000392sv00001462sd00000622* + ID_PRODUCT_FROM_DATABASE=NX7600GS-T2D256EH + +pci:v000010DEd00000393* + ID_PRODUCT_FROM_DATABASE=G73 [GeForce 7300 GT] + +pci:v000010DEd00000393sv000010DEsd00000412* + ID_PRODUCT_FROM_DATABASE=NX7300GT-TD256EH + +pci:v000010DEd00000393sv00001462sd00000412* + ID_PRODUCT_FROM_DATABASE=NX7300GT-TD256EH + +pci:v000010DEd00000394* + ID_PRODUCT_FROM_DATABASE=G73 [GeForce 7600 LE] + +pci:v000010DEd00000395* + ID_PRODUCT_FROM_DATABASE=G73 [GeForce 7300 GT] + +pci:v000010DEd00000397* + ID_PRODUCT_FROM_DATABASE=G73 [GeForce Go 7700] + +pci:v000010DEd00000398* + ID_PRODUCT_FROM_DATABASE=G73 [GeForce Go 7600] + +pci:v000010DEd00000398sv00001025sd0000006C* + ID_PRODUCT_FROM_DATABASE=Acer 9814 WKMI + +pci:v000010DEd00000399* + ID_PRODUCT_FROM_DATABASE=G73 [GeForce Go 7600 GT] + +pci:v000010DEd0000039A* + ID_PRODUCT_FROM_DATABASE=G73M [Quadro NVS 300M] + +pci:v000010DEd0000039B* + ID_PRODUCT_FROM_DATABASE=G73 [GeForce Go 7900 SE] + +pci:v000010DEd0000039C* + ID_PRODUCT_FROM_DATABASE=G73 [Quadro FX 550M] + +pci:v000010DEd0000039Csv000010DEsd0000039C* + ID_PRODUCT_FROM_DATABASE=Quadro FX 560M + +pci:v000010DEd0000039E* + ID_PRODUCT_FROM_DATABASE=G73GL [Quadro FX 560] + +pci:v000010DEd000003A0* + ID_PRODUCT_FROM_DATABASE=C55 Host Bridge + +pci:v000010DEd000003A1* + ID_PRODUCT_FROM_DATABASE=C55 Host Bridge + +pci:v000010DEd000003A2* + ID_PRODUCT_FROM_DATABASE=C55 Host Bridge + +pci:v000010DEd000003A3* + ID_PRODUCT_FROM_DATABASE=C55 Host Bridge + +pci:v000010DEd000003A4* + ID_PRODUCT_FROM_DATABASE=C55 Host Bridge + +pci:v000010DEd000003A5* + ID_PRODUCT_FROM_DATABASE=C55 Host Bridge + +pci:v000010DEd000003A6* + ID_PRODUCT_FROM_DATABASE=C55 Host Bridge + +pci:v000010DEd000003A7* + ID_PRODUCT_FROM_DATABASE=C55 Host Bridge + +pci:v000010DEd000003A8* + ID_PRODUCT_FROM_DATABASE=C55 Memory Controller + +pci:v000010DEd000003A9* + ID_PRODUCT_FROM_DATABASE=C55 Memory Controller + +pci:v000010DEd000003AA* + ID_PRODUCT_FROM_DATABASE=C55 Memory Controller + +pci:v000010DEd000003AB* + ID_PRODUCT_FROM_DATABASE=C55 Memory Controller + +pci:v000010DEd000003AC* + ID_PRODUCT_FROM_DATABASE=C55 Memory Controller + +pci:v000010DEd000003AD* + ID_PRODUCT_FROM_DATABASE=C55 Memory Controller + +pci:v000010DEd000003AE* + ID_PRODUCT_FROM_DATABASE=C55 Memory Controller + +pci:v000010DEd000003AF* + ID_PRODUCT_FROM_DATABASE=C55 Memory Controller + +pci:v000010DEd000003B0* + ID_PRODUCT_FROM_DATABASE=C55 Memory Controller + +pci:v000010DEd000003B1* + ID_PRODUCT_FROM_DATABASE=C55 Memory Controller + +pci:v000010DEd000003B2* + ID_PRODUCT_FROM_DATABASE=C55 Memory Controller + +pci:v000010DEd000003B3* + ID_PRODUCT_FROM_DATABASE=C55 Memory Controller + +pci:v000010DEd000003B4* + ID_PRODUCT_FROM_DATABASE=C55 Memory Controller + +pci:v000010DEd000003B5* + ID_PRODUCT_FROM_DATABASE=C55 Memory Controller + +pci:v000010DEd000003B6* + ID_PRODUCT_FROM_DATABASE=C55 Memory Controller + +pci:v000010DEd000003B7* + ID_PRODUCT_FROM_DATABASE=C55 PCI Express bridge + +pci:v000010DEd000003B8* + ID_PRODUCT_FROM_DATABASE=C55 PCI Express bridge + +pci:v000010DEd000003B9* + ID_PRODUCT_FROM_DATABASE=C55 PCI Express bridge + +pci:v000010DEd000003BA* + ID_PRODUCT_FROM_DATABASE=C55 Memory Controller + +pci:v000010DEd000003BB* + ID_PRODUCT_FROM_DATABASE=C55 PCI Express bridge + +pci:v000010DEd000003BC* + ID_PRODUCT_FROM_DATABASE=C55 Memory Controller + +pci:v000010DEd000003D0* + ID_PRODUCT_FROM_DATABASE=C61 [GeForce 6150SE nForce 430] + +pci:v000010DEd000003D0sv00001028sd0000020E* + ID_PRODUCT_FROM_DATABASE=Inspiron 531 + +pci:v000010DEd000003D1* + ID_PRODUCT_FROM_DATABASE=C61 [GeForce 6100 nForce 405] + +pci:v000010DEd000003D2* + ID_PRODUCT_FROM_DATABASE=C61 [GeForce 6100 nForce 400] + +pci:v000010DEd000003D5* + ID_PRODUCT_FROM_DATABASE=C61 [GeForce 6100 nForce 420] + +pci:v000010DEd000003D6* + ID_PRODUCT_FROM_DATABASE=C61 [GeForce 7025 / nForce 630a] + +pci:v000010DEd000003E0* + ID_PRODUCT_FROM_DATABASE=MCP61 LPC Bridge + +pci:v000010DEd000003E0sv00001028sd0000020E* + ID_PRODUCT_FROM_DATABASE=Inspiron 531 + +pci:v000010DEd000003E0sv00001849sd000003E0* + ID_PRODUCT_FROM_DATABASE=939NF6G-VSTA Board + +pci:v000010DEd000003E1* + ID_PRODUCT_FROM_DATABASE=MCP61 LPC Bridge + +pci:v000010DEd000003E1sv00001043sd000083A4* + ID_PRODUCT_FROM_DATABASE=M4N68T series motherboard + +pci:v000010DEd000003E2* + ID_PRODUCT_FROM_DATABASE=MCP61 Host Bridge + +pci:v000010DEd000003E2sv00001043sd000083A4* + ID_PRODUCT_FROM_DATABASE=M4N68T series motherboard + +pci:v000010DEd000003E3* + ID_PRODUCT_FROM_DATABASE=MCP61 LPC Bridge + +pci:v000010DEd000003E4* + ID_PRODUCT_FROM_DATABASE=MCP61 High Definition Audio + +pci:v000010DEd000003E5* + ID_PRODUCT_FROM_DATABASE=MCP61 Ethernet + +pci:v000010DEd000003E6* + ID_PRODUCT_FROM_DATABASE=MCP61 Ethernet + +pci:v000010DEd000003E7* + ID_PRODUCT_FROM_DATABASE=MCP61 SATA Controller + +pci:v000010DEd000003E8* + ID_PRODUCT_FROM_DATABASE=MCP61 PCI Express bridge + +pci:v000010DEd000003E8sv00001028sd0000020E* + ID_PRODUCT_FROM_DATABASE=Inspiron 531 + +pci:v000010DEd000003E8sv00001849sd000003E8* + ID_PRODUCT_FROM_DATABASE=939NF6G-VSTA Board + +pci:v000010DEd000003E9* + ID_PRODUCT_FROM_DATABASE=MCP61 PCI Express bridge + +pci:v000010DEd000003E9sv00001028sd0000020E* + ID_PRODUCT_FROM_DATABASE=Inspiron 531 + +pci:v000010DEd000003E9sv00001849sd000003E9* + ID_PRODUCT_FROM_DATABASE=939NF6G-VSTA Board + +pci:v000010DEd000003EA* + ID_PRODUCT_FROM_DATABASE=MCP61 Memory Controller + +pci:v000010DEd000003EAsv00001028sd0000020E* + ID_PRODUCT_FROM_DATABASE=Inspiron 531 + +pci:v000010DEd000003EAsv00001849sd000003EA* + ID_PRODUCT_FROM_DATABASE=939NF6G-VSTA Board + +pci:v000010DEd000003EB* + ID_PRODUCT_FROM_DATABASE=MCP61 SMBus + +pci:v000010DEd000003EBsv00001028sd0000020E* + ID_PRODUCT_FROM_DATABASE=Inspiron 531 + +pci:v000010DEd000003EBsv00001043sd000083A4* + ID_PRODUCT_FROM_DATABASE=M4N68T series motherboard + +pci:v000010DEd000003EBsv00001849sd000003EB* + ID_PRODUCT_FROM_DATABASE=939NF6G-VSTA Board + +pci:v000010DEd000003EC* + ID_PRODUCT_FROM_DATABASE=MCP61 IDE + +pci:v000010DEd000003ECsv00001025sd00000392* + ID_PRODUCT_FROM_DATABASE=ET1350 + +pci:v000010DEd000003ECsv00001028sd0000020E* + ID_PRODUCT_FROM_DATABASE=Inspiron 531 + +pci:v000010DEd000003ECsv00001043sd000083A4* + ID_PRODUCT_FROM_DATABASE=M4N68T series motherboard + +pci:v000010DEd000003ECsv00001849sd000003EC* + ID_PRODUCT_FROM_DATABASE=939NF6G-VSTA Board + +pci:v000010DEd000003EE* + ID_PRODUCT_FROM_DATABASE=MCP61 Ethernet + +pci:v000010DEd000003EF* + ID_PRODUCT_FROM_DATABASE=MCP61 Ethernet + +pci:v000010DEd000003EFsv00001025sd00008000* + ID_PRODUCT_FROM_DATABASE=ET1350 + +pci:v000010DEd000003EFsv00001028sd0000020E* + ID_PRODUCT_FROM_DATABASE=Inspiron 531 + +pci:v000010DEd000003EFsv00001043sd000083A4* + ID_PRODUCT_FROM_DATABASE=M4N68T series motherboard + +pci:v000010DEd000003EFsv00001849sd000003EF* + ID_PRODUCT_FROM_DATABASE=939NF6G-VSTA Board + +pci:v000010DEd000003F0* + ID_PRODUCT_FROM_DATABASE=MCP61 High Definition Audio + +pci:v000010DEd000003F0sv00001028sd0000020E* + ID_PRODUCT_FROM_DATABASE=Inspiron 531 + +pci:v000010DEd000003F0sv00001043sd00008415* + ID_PRODUCT_FROM_DATABASE=M4N68T series motherboard + +pci:v000010DEd000003F0sv00001849sd00000888* + ID_PRODUCT_FROM_DATABASE=939NF6G-VSTA Board + +pci:v000010DEd000003F1* + ID_PRODUCT_FROM_DATABASE=MCP61 USB 1.1 Controller + +pci:v000010DEd000003F1sv00001028sd0000020E* + ID_PRODUCT_FROM_DATABASE=Inspiron 531 + +pci:v000010DEd000003F1sv00001043sd000083A4* + ID_PRODUCT_FROM_DATABASE=M4N68T series motherboard + +pci:v000010DEd000003F1sv00001849sd000003F1* + ID_PRODUCT_FROM_DATABASE=939NF6G-VSTA Board + +pci:v000010DEd000003F2* + ID_PRODUCT_FROM_DATABASE=MCP61 USB 2.0 Controller + +pci:v000010DEd000003F2sv00001028sd0000020E* + ID_PRODUCT_FROM_DATABASE=Inspiron 531 + +pci:v000010DEd000003F2sv00001043sd000083A4* + ID_PRODUCT_FROM_DATABASE=M4N68T series motherboard + +pci:v000010DEd000003F2sv00001849sd000003F2* + ID_PRODUCT_FROM_DATABASE=939NF6G-VSTA Board + +pci:v000010DEd000003F3* + ID_PRODUCT_FROM_DATABASE=MCP61 PCI bridge + +pci:v000010DEd000003F3sv00001028sd0000020E* + ID_PRODUCT_FROM_DATABASE=Inspiron 531 + +pci:v000010DEd000003F3sv00001849sd000003F3* + ID_PRODUCT_FROM_DATABASE=939NF6G-VSTA Board + +pci:v000010DEd000003F4* + ID_PRODUCT_FROM_DATABASE=MCP61 SMU + +pci:v000010DEd000003F5* + ID_PRODUCT_FROM_DATABASE=MCP61 Memory Controller + +pci:v000010DEd000003F5sv00001028sd0000020E* + ID_PRODUCT_FROM_DATABASE=Inspiron 531 + +pci:v000010DEd000003F5sv00001043sd000083A4* + ID_PRODUCT_FROM_DATABASE=M4N68T series motherboard + +pci:v000010DEd000003F5sv00001849sd000003EB* + ID_PRODUCT_FROM_DATABASE=939NF6G-VSTA Board + +pci:v000010DEd000003F6* + ID_PRODUCT_FROM_DATABASE=MCP61 SATA Controller + +pci:v000010DEd000003F6sv00001028sd0000020E* + ID_PRODUCT_FROM_DATABASE=Inspiron 531 + +pci:v000010DEd000003F6sv00001043sd000083A4* + ID_PRODUCT_FROM_DATABASE=M4N68T series motherboard + +pci:v000010DEd000003F6sv00001849sd000003F6* + ID_PRODUCT_FROM_DATABASE=939NF6G-VSTA Board + +pci:v000010DEd000003F7* + ID_PRODUCT_FROM_DATABASE=MCP61 SATA Controller + +pci:v000010DEd00000400* + ID_PRODUCT_FROM_DATABASE=G84 [GeForce 8600 GTS] + +pci:v000010DEd00000400sv00001043sd00008241* + ID_PRODUCT_FROM_DATABASE=EN8600GTS + +pci:v000010DEd00000401* + ID_PRODUCT_FROM_DATABASE=G84 [GeForce 8600GT] + +pci:v000010DEd00000402* + ID_PRODUCT_FROM_DATABASE=G84 [GeForce 8600 GT] + +pci:v000010DEd00000402sv00001458sd00003455* + ID_PRODUCT_FROM_DATABASE=GV-NX86T512H + +pci:v000010DEd00000402sv00001462sd00000910* + ID_PRODUCT_FROM_DATABASE=NX8600GT-T2D256EZ + +pci:v000010DEd00000403* + ID_PRODUCT_FROM_DATABASE=G84 [GeForce 8600 GS] + +pci:v000010DEd00000404* + ID_PRODUCT_FROM_DATABASE=G84 [GeForce 8400 GS] + +pci:v000010DEd00000404sv00001462sd00001230* + ID_PRODUCT_FROM_DATABASE=NX8400GS-TD256E + +pci:v000010DEd00000405* + ID_PRODUCT_FROM_DATABASE=G84 [GeForce 9500M GS] + +pci:v000010DEd00000406* + ID_PRODUCT_FROM_DATABASE=G84 [GeForce 8300 GS] + +pci:v000010DEd00000407* + ID_PRODUCT_FROM_DATABASE=G84 [GeForce 8600M GT] + +pci:v000010DEd00000408* + ID_PRODUCT_FROM_DATABASE=G84 [GeForce 9650M GS] + +pci:v000010DEd00000409* + ID_PRODUCT_FROM_DATABASE=G84 [GeForce 8700M GT] + +pci:v000010DEd0000040A* + ID_PRODUCT_FROM_DATABASE=G84 [Quadro FX 370] + +pci:v000010DEd0000040B* + ID_PRODUCT_FROM_DATABASE=G84M [Quadro NVS 320M] + +pci:v000010DEd0000040C* + ID_PRODUCT_FROM_DATABASE=G84M [Quadro FX 570M] + +pci:v000010DEd0000040Csv000017AAsd000020D9* + ID_PRODUCT_FROM_DATABASE=ThinkPad T61p + +pci:v000010DEd0000040D* + ID_PRODUCT_FROM_DATABASE=G84 [Quadro FX 1600M] + +pci:v000010DEd0000040E* + ID_PRODUCT_FROM_DATABASE=G84 [Quadro FX 570] + +pci:v000010DEd0000040F* + ID_PRODUCT_FROM_DATABASE=G84 [Quadro FX 1700] + +pci:v000010DEd00000410* + ID_PRODUCT_FROM_DATABASE=G92 [GeForce GT 330] + +pci:v000010DEd00000420* + ID_PRODUCT_FROM_DATABASE=G86 [GeForce 8400 SE] + +pci:v000010DEd00000421* + ID_PRODUCT_FROM_DATABASE=G86 [GeForce 8500 GT] + +pci:v000010DEd00000421sv00001462sd00000960* + ID_PRODUCT_FROM_DATABASE=NX8500GT-TD512EH/M2 + +pci:v000010DEd00000422* + ID_PRODUCT_FROM_DATABASE=G86 [GeForce 8400 GS] + +pci:v000010DEd00000423* + ID_PRODUCT_FROM_DATABASE=G86 [GeForce 8300 GS] + +pci:v000010DEd00000424* + ID_PRODUCT_FROM_DATABASE=G86 [GeForce 8400 GS] + +pci:v000010DEd00000425* + ID_PRODUCT_FROM_DATABASE=G86 [GeForce 8600M GS] + +pci:v000010DEd00000425sv00001025sd00000121* + ID_PRODUCT_FROM_DATABASE=Aspire 5920G + +pci:v000010DEd00000426* + ID_PRODUCT_FROM_DATABASE=G86 [GeForce 8400M GT] + +pci:v000010DEd00000427* + ID_PRODUCT_FROM_DATABASE=G86 [GeForce 8400M GS] + +pci:v000010DEd00000427sv0000103Csd000030CC* + ID_PRODUCT_FROM_DATABASE=Pavilion dv6700 + +pci:v000010DEd00000428* + ID_PRODUCT_FROM_DATABASE=G86 [GeForce 8400M G] + +pci:v000010DEd00000429* + ID_PRODUCT_FROM_DATABASE=G86 [Quadro NVS 140M] + +pci:v000010DEd00000429sv000017AAsd000020D8* + ID_PRODUCT_FROM_DATABASE=ThinkPad T61 + +pci:v000010DEd0000042A* + ID_PRODUCT_FROM_DATABASE=G86M [Quadro NVS 130M] + +pci:v000010DEd0000042B* + ID_PRODUCT_FROM_DATABASE=G86M [Quadro NVS 135M] + +pci:v000010DEd0000042C* + ID_PRODUCT_FROM_DATABASE=G86 [GeForce 9400 GT] + +pci:v000010DEd0000042D* + ID_PRODUCT_FROM_DATABASE=G86M [Quadro FX 360M] + +pci:v000010DEd0000042E* + ID_PRODUCT_FROM_DATABASE=G86 [GeForce 9300M G] + +pci:v000010DEd0000042F* + ID_PRODUCT_FROM_DATABASE=G86 [Quadro NVS 290] + +pci:v000010DEd00000440* + ID_PRODUCT_FROM_DATABASE=MCP65 LPC Bridge + +pci:v000010DEd00000441* + ID_PRODUCT_FROM_DATABASE=MCP65 LPC Bridge + +pci:v000010DEd00000442* + ID_PRODUCT_FROM_DATABASE=MCP65 LPC Bridge + +pci:v000010DEd00000443* + ID_PRODUCT_FROM_DATABASE=MCP65 LPC Bridge + +pci:v000010DEd00000444* + ID_PRODUCT_FROM_DATABASE=MCP65 Memory Controller + +pci:v000010DEd00000445* + ID_PRODUCT_FROM_DATABASE=MCP65 Memory Controller + +pci:v000010DEd00000446* + ID_PRODUCT_FROM_DATABASE=MCP65 SMBus + +pci:v000010DEd00000447* + ID_PRODUCT_FROM_DATABASE=MCP65 SMU + +pci:v000010DEd00000448* + ID_PRODUCT_FROM_DATABASE=MCP65 IDE + +pci:v000010DEd00000449* + ID_PRODUCT_FROM_DATABASE=MCP65 PCI bridge + +pci:v000010DEd0000044A* + ID_PRODUCT_FROM_DATABASE=MCP65 High Definition Audio + +pci:v000010DEd0000044B* + ID_PRODUCT_FROM_DATABASE=MCP65 High Definition Audio + +pci:v000010DEd0000044C* + ID_PRODUCT_FROM_DATABASE=MCP65 AHCI Controller + +pci:v000010DEd0000044D* + ID_PRODUCT_FROM_DATABASE=MCP65 AHCI Controller + +pci:v000010DEd0000044E* + ID_PRODUCT_FROM_DATABASE=MCP65 AHCI Controller + +pci:v000010DEd0000044F* + ID_PRODUCT_FROM_DATABASE=MCP65 AHCI Controller + +pci:v000010DEd00000450* + ID_PRODUCT_FROM_DATABASE=MCP65 Ethernet + +pci:v000010DEd00000451* + ID_PRODUCT_FROM_DATABASE=MCP65 Ethernet + +pci:v000010DEd00000452* + ID_PRODUCT_FROM_DATABASE=MCP65 Ethernet + +pci:v000010DEd00000453* + ID_PRODUCT_FROM_DATABASE=MCP65 Ethernet + +pci:v000010DEd00000454* + ID_PRODUCT_FROM_DATABASE=MCP65 USB Controller + +pci:v000010DEd00000455* + ID_PRODUCT_FROM_DATABASE=MCP65 USB Controller + +pci:v000010DEd00000456* + ID_PRODUCT_FROM_DATABASE=MCP65 USB Controller + +pci:v000010DEd00000457* + ID_PRODUCT_FROM_DATABASE=MCP65 USB Controller + +pci:v000010DEd00000458* + ID_PRODUCT_FROM_DATABASE=MCP65 PCI Express bridge + +pci:v000010DEd00000459* + ID_PRODUCT_FROM_DATABASE=MCP65 PCI Express bridge + +pci:v000010DEd0000045A* + ID_PRODUCT_FROM_DATABASE=MCP65 PCI Express bridge + +pci:v000010DEd0000045C* + ID_PRODUCT_FROM_DATABASE=MCP65 SATA Controller + +pci:v000010DEd0000045D* + ID_PRODUCT_FROM_DATABASE=MCP65 SATA Controller + +pci:v000010DEd0000045E* + ID_PRODUCT_FROM_DATABASE=MCP65 SATA Controller + +pci:v000010DEd0000045F* + ID_PRODUCT_FROM_DATABASE=MCP65 SATA Controller + +pci:v000010DEd00000531* + ID_PRODUCT_FROM_DATABASE=C67 [GeForce 7150M / nForce 630M] + +pci:v000010DEd00000533* + ID_PRODUCT_FROM_DATABASE=C67 [GeForce 7000M / nForce 610M] + +pci:v000010DEd0000053A* + ID_PRODUCT_FROM_DATABASE=C68 [GeForce 7050 PV / nForce 630a] + +pci:v000010DEd0000053B* + ID_PRODUCT_FROM_DATABASE=C68 [GeForce 7050 PV / nForce 630a] + +pci:v000010DEd0000053Bsv00001043sd00008308* + ID_PRODUCT_FROM_DATABASE=M2N68-AM Motherbord + +pci:v000010DEd0000053E* + ID_PRODUCT_FROM_DATABASE=C68 [GeForce 7025 / nForce 630a] + +pci:v000010DEd00000541* + ID_PRODUCT_FROM_DATABASE=MCP67 Memory Controller + +pci:v000010DEd00000542* + ID_PRODUCT_FROM_DATABASE=MCP67 SMBus + +pci:v000010DEd00000542sv00001043sd00008308* + ID_PRODUCT_FROM_DATABASE=M2N68-AM Motherbord + +pci:v000010DEd00000543* + ID_PRODUCT_FROM_DATABASE=MCP67 Co-processor + +pci:v000010DEd00000547* + ID_PRODUCT_FROM_DATABASE=MCP67 Memory Controller + +pci:v000010DEd00000547sv00001043sd00008308* + ID_PRODUCT_FROM_DATABASE=M2N68-AM Motherbord + +pci:v000010DEd00000547sv00001849sd00000547* + ID_PRODUCT_FROM_DATABASE=ALiveNF7G-HDready + +pci:v000010DEd00000548* + ID_PRODUCT_FROM_DATABASE=MCP67 ISA Bridge + +pci:v000010DEd00000548sv00001043sd00008308* + ID_PRODUCT_FROM_DATABASE=M2N68-AM Motherboard + +pci:v000010DEd0000054C* + ID_PRODUCT_FROM_DATABASE=MCP67 Ethernet + +pci:v000010DEd0000054Csv00001043sd00008308* + ID_PRODUCT_FROM_DATABASE=M2N68-AM Motherbord + +pci:v000010DEd0000054Csv00001849sd0000054C* + ID_PRODUCT_FROM_DATABASE=ALiveNF7G-HDready, MCP67 Gigabit Ethernet + +pci:v000010DEd0000054D* + ID_PRODUCT_FROM_DATABASE=MCP67 Ethernet + +pci:v000010DEd0000054E* + ID_PRODUCT_FROM_DATABASE=MCP67 Ethernet + +pci:v000010DEd0000054F* + ID_PRODUCT_FROM_DATABASE=MCP67 Ethernet + +pci:v000010DEd00000550* + ID_PRODUCT_FROM_DATABASE=MCP67 AHCI Controller + +pci:v000010DEd00000550sv00001043sd00008308* + ID_PRODUCT_FROM_DATABASE=M2N68-AM Motherboard + +pci:v000010DEd00000554* + ID_PRODUCT_FROM_DATABASE=MCP67 AHCI Controller + +pci:v000010DEd00000554sv00001043sd00008308* + ID_PRODUCT_FROM_DATABASE=M2N68-AM Motherboard + +pci:v000010DEd00000555* + ID_PRODUCT_FROM_DATABASE=MCP67 SATA Controller + +pci:v000010DEd00000555sv00001043sd00008308* + ID_PRODUCT_FROM_DATABASE=M2N68-AM Motherboard + +pci:v000010DEd0000055C* + ID_PRODUCT_FROM_DATABASE=MCP67 High Definition Audio + +pci:v000010DEd0000055Csv00001043sd00008290* + ID_PRODUCT_FROM_DATABASE=M2N68-AM Motherboard + +pci:v000010DEd0000055D* + ID_PRODUCT_FROM_DATABASE=MCP67 High Definition Audio + +pci:v000010DEd0000055E* + ID_PRODUCT_FROM_DATABASE=MCP67 OHCI USB 1.1 Controller + +pci:v000010DEd0000055Esv00001043sd00008308* + ID_PRODUCT_FROM_DATABASE=M2N68-AM Motherboard + +pci:v000010DEd0000055F* + ID_PRODUCT_FROM_DATABASE=MCP67 EHCI USB 2.0 Controller + +pci:v000010DEd0000055Fsv00001043sd00008308* + ID_PRODUCT_FROM_DATABASE=M2N68-AM Motherboard + +pci:v000010DEd00000560* + ID_PRODUCT_FROM_DATABASE=MCP67 IDE Controller + +pci:v000010DEd00000560sv0000F043sd00008308* + ID_PRODUCT_FROM_DATABASE=M2N68-AM Motherboard + +pci:v000010DEd00000561* + ID_PRODUCT_FROM_DATABASE=MCP67 PCI Bridge + +pci:v000010DEd00000562* + ID_PRODUCT_FROM_DATABASE=MCP67 PCI Express Bridge + +pci:v000010DEd00000562sv00001849sd00000562* + ID_PRODUCT_FROM_DATABASE=ALiveNF7G-HDready + +pci:v000010DEd00000563* + ID_PRODUCT_FROM_DATABASE=MCP67 PCI Express Bridge + +pci:v000010DEd00000568* + ID_PRODUCT_FROM_DATABASE=MCP78S [GeForce 8200] Memory Controller + +pci:v000010DEd00000568sv0000103Csd00002A9E* + ID_PRODUCT_FROM_DATABASE=Pavilion p6310f + +pci:v000010DEd00000568sv00001043sd000082E8* + ID_PRODUCT_FROM_DATABASE=M3N72-D + +pci:v000010DEd00000568sv00001462sd00007508* + ID_PRODUCT_FROM_DATABASE=K9N2GM-FIH + +pci:v000010DEd00000568sv00001849sd00000568* + ID_PRODUCT_FROM_DATABASE=K10N78FullHD-hSLI R3.0 Memory Controller + +pci:v000010DEd00000569* + ID_PRODUCT_FROM_DATABASE=MCP78S [GeForce 8200] PCI Express Bridge + +pci:v000010DEd00000569sv0000103Csd00002A9E* + ID_PRODUCT_FROM_DATABASE=Pavilion p6310f + +pci:v000010DEd00000569sv00001043sd000082E8* + ID_PRODUCT_FROM_DATABASE=M3N72-D + +pci:v000010DEd00000569sv00001462sd00007508* + ID_PRODUCT_FROM_DATABASE=K9N2GM-FIH + +pci:v000010DEd00000569sv00001849sd00000569* + ID_PRODUCT_FROM_DATABASE=K10N78FullHD-hSLI R3.0 PCI Express Bridge + +pci:v000010DEd0000056A* + ID_PRODUCT_FROM_DATABASE=MCP73 [nForce 630i] USB 2.0 Controller (EHCI) + +pci:v000010DEd0000056Asv00001019sd0000297A* + ID_PRODUCT_FROM_DATABASE=MCP73PVT-SM + +pci:v000010DEd0000056C* + ID_PRODUCT_FROM_DATABASE=MCP73 IDE + +pci:v000010DEd0000056Csv00001019sd0000297A* + ID_PRODUCT_FROM_DATABASE=MCP73PVT-SM + +pci:v000010DEd0000056Csv00001AFAsd00007150* + ID_PRODUCT_FROM_DATABASE=JW-IN7150-HD + +pci:v000010DEd0000056D* + ID_PRODUCT_FROM_DATABASE=MCP73 PCI Express bridge + +pci:v000010DEd0000056Dsv00001019sd0000297A* + ID_PRODUCT_FROM_DATABASE=MCP73PVT-SM + +pci:v000010DEd0000056E* + ID_PRODUCT_FROM_DATABASE=MCP73 PCI Express bridge + +pci:v000010DEd0000056Esv00001019sd0000297A* + ID_PRODUCT_FROM_DATABASE=MCP73PVT-SM + +pci:v000010DEd0000056F* + ID_PRODUCT_FROM_DATABASE=MCP73 PCI Express bridge + +pci:v000010DEd0000056Fsv00001019sd0000297A* + ID_PRODUCT_FROM_DATABASE=MCP73PVT-SM + +pci:v000010DEd000005B1* + ID_PRODUCT_FROM_DATABASE=NF200 PCIe 2.0 switch + +pci:v000010DEd000005B8* + ID_PRODUCT_FROM_DATABASE=NF200 PCIe 2.0 switch for GTX 295 + +pci:v000010DEd000005BE* + ID_PRODUCT_FROM_DATABASE=NF200 PCIe 2.0 switch for Quadro Plex S4 / Tesla S870 / Tesla S1070 / Tesla S2050 + +pci:v000010DEd000005E0* + ID_PRODUCT_FROM_DATABASE=GT200b [GeForce GTX 295] + +pci:v000010DEd000005E1* + ID_PRODUCT_FROM_DATABASE=GT200 [GeForce GTX 280] + +pci:v000010DEd000005E2* + ID_PRODUCT_FROM_DATABASE=GT200 [GeForce GTX 260] + +pci:v000010DEd000005E3* + ID_PRODUCT_FROM_DATABASE=GT200b [GeForce GTX 285] + +pci:v000010DEd000005E6* + ID_PRODUCT_FROM_DATABASE=GT200b [GeForce GTX 275] + +pci:v000010DEd000005E7* + ID_PRODUCT_FROM_DATABASE=GT200 [Tesla C1060] + +pci:v000010DEd000005EA* + ID_PRODUCT_FROM_DATABASE=GT200 [GeForce GTX 260] + +pci:v000010DEd000005EB* + ID_PRODUCT_FROM_DATABASE=GT200 [GeForce GTX 295] + +pci:v000010DEd000005ED* + ID_PRODUCT_FROM_DATABASE=GT200GL [Quadro Plex 2200 D2] + +pci:v000010DEd000005F8* + ID_PRODUCT_FROM_DATABASE=GT200GL [Quadro Plex 2200 S4] + +pci:v000010DEd000005F9* + ID_PRODUCT_FROM_DATABASE=GT200GL [Quadro CX] + +pci:v000010DEd000005FD* + ID_PRODUCT_FROM_DATABASE=GT200GL [Quadro FX 5800] + +pci:v000010DEd000005FE* + ID_PRODUCT_FROM_DATABASE=GT200GL [Quadro FX 4800] + +pci:v000010DEd000005FF* + ID_PRODUCT_FROM_DATABASE=GT200GL [NVIDIA Quadro FX 3800] + +pci:v000010DEd00000600* + ID_PRODUCT_FROM_DATABASE=G92 [GeForce 8800 GTS 512] + +pci:v000010DEd00000601* + ID_PRODUCT_FROM_DATABASE=G92 [GeForce 9800 GT] + +pci:v000010DEd00000602* + ID_PRODUCT_FROM_DATABASE=G92 [GeForce 8800 GT] + +pci:v000010DEd00000603* + ID_PRODUCT_FROM_DATABASE=G92 [GeForce GT 230] + +pci:v000010DEd00000604* + ID_PRODUCT_FROM_DATABASE=G92 [GeForce 9800 GX2] + +pci:v000010DEd00000605* + ID_PRODUCT_FROM_DATABASE=G92 [GeForce 9800 GT] + +pci:v000010DEd00000606* + ID_PRODUCT_FROM_DATABASE=G92 [GeForce 8800 GS] + +pci:v000010DEd00000607* + ID_PRODUCT_FROM_DATABASE=G92 [GeForce GTS 240] + +pci:v000010DEd00000608* + ID_PRODUCT_FROM_DATABASE=G92 [GeForce 9800M GTX] + +pci:v000010DEd00000609* + ID_PRODUCT_FROM_DATABASE=G92 [GeForce 8800M GTS] + +pci:v000010DEd0000060A* + ID_PRODUCT_FROM_DATABASE=GT200 [GeForce GTX 280M] + +pci:v000010DEd0000060B* + ID_PRODUCT_FROM_DATABASE=G92 [GeForce 9800M GT] + +pci:v000010DEd0000060C* + ID_PRODUCT_FROM_DATABASE=G92 [GeForce 8800M GTX] + +pci:v000010DEd0000060D* + ID_PRODUCT_FROM_DATABASE=G92 [GeForce 8800 GS] + +pci:v000010DEd0000060F* + ID_PRODUCT_FROM_DATABASE=G92 [GeForce GTX 285M] + +pci:v000010DEd00000610* + ID_PRODUCT_FROM_DATABASE=G92 [GeForce 9600 GSO] + +pci:v000010DEd00000610sv00001682sd00002385* + ID_PRODUCT_FROM_DATABASE=GeForce 9600 GSO 768mb + +pci:v000010DEd00000611* + ID_PRODUCT_FROM_DATABASE=G92 [GeForce 8800 GT] + +pci:v000010DEd00000611sv0000107Dsd00002AB0* + ID_PRODUCT_FROM_DATABASE=Winfast PX8800 GT PCI-E + +pci:v000010DEd00000611sv000019DAsd00001040* + ID_PRODUCT_FROM_DATABASE=ZT-88TES2P-FSP + +pci:v000010DEd00000612* + ID_PRODUCT_FROM_DATABASE=G92 [GeForce 9800 GTX] + +pci:v000010DEd00000613* + ID_PRODUCT_FROM_DATABASE=G92 [GeForce 9800 GTX+] + +pci:v000010DEd00000614* + ID_PRODUCT_FROM_DATABASE=G92 [GeForce 9800 GT] + +pci:v000010DEd00000614sv0000107Dsd00002AB3* + ID_PRODUCT_FROM_DATABASE=WinFast PX9800 GT (S-Fanpipe) + +pci:v000010DEd00000615* + ID_PRODUCT_FROM_DATABASE=G92 [GeForce GTS 250] + +pci:v000010DEd00000615sv00003842sd00001150* + ID_PRODUCT_FROM_DATABASE=GeForce GTS 250 P/N 512-P3-1150-TR + +pci:v000010DEd00000615sv00003842sd00001151* + ID_PRODUCT_FROM_DATABASE=GeForce GTS 250 P/N 512-P3-1151-TR + +pci:v000010DEd00000615sv00003842sd00001155* + ID_PRODUCT_FROM_DATABASE=GeForce GTS 250 P/N 01G-P3-1155-TR + +pci:v000010DEd00000615sv00003842sd00001156* + ID_PRODUCT_FROM_DATABASE=GeForce GTS 250 P/N 01G-P3-1156-TR + +pci:v000010DEd00000617* + ID_PRODUCT_FROM_DATABASE=G92 [GeForce 9800M GTX] + +pci:v000010DEd00000618* + ID_PRODUCT_FROM_DATABASE=G92 [GeForce GTX 260M] + +pci:v000010DEd00000619* + ID_PRODUCT_FROM_DATABASE=G92GL [Quadro FX 4700 X2] + +pci:v000010DEd0000061A* + ID_PRODUCT_FROM_DATABASE=G92 [Quadro FX 3700] + +pci:v000010DEd0000061B* + ID_PRODUCT_FROM_DATABASE=G92GL [Quadro VX 200] + +pci:v000010DEd0000061C* + ID_PRODUCT_FROM_DATABASE=G92M [Quadro FX 3600M] + +pci:v000010DEd0000061D* + ID_PRODUCT_FROM_DATABASE=G92 [Quadro FX 2800M] + +pci:v000010DEd0000061E* + ID_PRODUCT_FROM_DATABASE=G92 [Quadro FX 3700M] + +pci:v000010DEd0000061F* + ID_PRODUCT_FROM_DATABASE=G92 [Quadro FX 3800M] + +pci:v000010DEd00000622* + ID_PRODUCT_FROM_DATABASE=G94 [GeForce 9600 GT] + +pci:v000010DEd00000622sv0000107Dsd00002AC1* + ID_PRODUCT_FROM_DATABASE=WinFast PX9600GT 1024MB + +pci:v000010DEd00000622sv00001458sd00003481* + ID_PRODUCT_FROM_DATABASE=GV-NX96T512HP + +pci:v000010DEd00000623* + ID_PRODUCT_FROM_DATABASE=G94 [GeForce 9600 GS] + +pci:v000010DEd00000624* + ID_PRODUCT_FROM_DATABASE=G94 [GeForce 9600 GT Green Edition] + +pci:v000010DEd00000625* + ID_PRODUCT_FROM_DATABASE=G94 [GeForce 9600 GSO 512] + +pci:v000010DEd00000626* + ID_PRODUCT_FROM_DATABASE=G94 [GeForce GT 130] + +pci:v000010DEd00000627* + ID_PRODUCT_FROM_DATABASE=G94 [GeForce GT 140] + +pci:v000010DEd00000628* + ID_PRODUCT_FROM_DATABASE=G94 [GeForce 9800M GTS] + +pci:v000010DEd0000062A* + ID_PRODUCT_FROM_DATABASE=G94 [GeForce 9700M GTS] + +pci:v000010DEd0000062B* + ID_PRODUCT_FROM_DATABASE=G94 [GeForce 9800M GS] + +pci:v000010DEd0000062C* + ID_PRODUCT_FROM_DATABASE=G94 [GeForce 9800M GTS] + +pci:v000010DEd0000062D* + ID_PRODUCT_FROM_DATABASE=G94 [GeForce 9600 GT] + +pci:v000010DEd0000062E* + ID_PRODUCT_FROM_DATABASE=G94 [GeForce 9600 GT] + +pci:v000010DEd00000631* + ID_PRODUCT_FROM_DATABASE=G94M [GeForce GTS 160M] + +pci:v000010DEd00000632* + ID_PRODUCT_FROM_DATABASE=G94M [GeForce GTS 150M] + +pci:v000010DEd00000635* + ID_PRODUCT_FROM_DATABASE=G94 [GeForce 9600 GSO] + +pci:v000010DEd00000637* + ID_PRODUCT_FROM_DATABASE=G94 [GeForce 9600 GT] + +pci:v000010DEd00000638* + ID_PRODUCT_FROM_DATABASE=G94 [Quadro FX 1800] + +pci:v000010DEd0000063A* + ID_PRODUCT_FROM_DATABASE=G94M [Quadro FX 2700M] + +pci:v000010DEd00000640* + ID_PRODUCT_FROM_DATABASE=G96 [GeForce 9500 GT] + +pci:v000010DEd00000641* + ID_PRODUCT_FROM_DATABASE=G96 [GeForce 9400 GT] + +pci:v000010DEd00000643* + ID_PRODUCT_FROM_DATABASE=G96 [GeForce 9500 GT] + +pci:v000010DEd00000644* + ID_PRODUCT_FROM_DATABASE=G96 [GeForce 9500 GS] + +pci:v000010DEd00000645* + ID_PRODUCT_FROM_DATABASE=G96 [GeForce 9500 GS] + +pci:v000010DEd00000646* + ID_PRODUCT_FROM_DATABASE=G96 [GeForce GT 120] + +pci:v000010DEd00000647* + ID_PRODUCT_FROM_DATABASE=G96 [GeForce 9600M GT] + +pci:v000010DEd00000648* + ID_PRODUCT_FROM_DATABASE=G96 [GeForce 9600M GS] + +pci:v000010DEd00000649* + ID_PRODUCT_FROM_DATABASE=G96 [GeForce 9600M GT] + +pci:v000010DEd0000064A* + ID_PRODUCT_FROM_DATABASE=G96 [GeForce 9700M GT] + +pci:v000010DEd0000064B* + ID_PRODUCT_FROM_DATABASE=G96 [GeForce 9500M G] + +pci:v000010DEd0000064C* + ID_PRODUCT_FROM_DATABASE=G96 [GeForce 9650M GT] + +pci:v000010DEd00000651* + ID_PRODUCT_FROM_DATABASE=G96 [GeForce G 110M] + +pci:v000010DEd00000652* + ID_PRODUCT_FROM_DATABASE=G96 [GeForce GT 130M] + +pci:v000010DEd00000653* + ID_PRODUCT_FROM_DATABASE=G96M [GeForce GT 120M] + +pci:v000010DEd00000654* + ID_PRODUCT_FROM_DATABASE=G96 [GeForce GT 220M] + +pci:v000010DEd00000656* + ID_PRODUCT_FROM_DATABASE=G96 [GeForce 9650 S] + +pci:v000010DEd00000658* + ID_PRODUCT_FROM_DATABASE=G96 [Quadro FX 380] + +pci:v000010DEd00000659* + ID_PRODUCT_FROM_DATABASE=G96 [Quadro FX 580] + +pci:v000010DEd0000065A* + ID_PRODUCT_FROM_DATABASE=G96 [Quadro FX 1700M] + +pci:v000010DEd0000065B* + ID_PRODUCT_FROM_DATABASE=G96 [GeForce 9400 GT] + +pci:v000010DEd0000065C* + ID_PRODUCT_FROM_DATABASE=G96M [Quadro FX 770M] + +pci:v000010DEd000006C0* + ID_PRODUCT_FROM_DATABASE=GF100 [GeForce GTX 480] + +pci:v000010DEd000006CD* + ID_PRODUCT_FROM_DATABASE=GF100 [GeForce GTX 470] + +pci:v000010DEd000006D1* + ID_PRODUCT_FROM_DATABASE=GF100 [Tesla C2050 / C2070] + +pci:v000010DEd000006D2* + ID_PRODUCT_FROM_DATABASE=GF100 [Tesla M2070] + +pci:v000010DEd000006D8* + ID_PRODUCT_FROM_DATABASE=GF100GL [Quadro 6000] + +pci:v000010DEd000006D9* + ID_PRODUCT_FROM_DATABASE=GF100GL [Quadro 5000] + +pci:v000010DEd000006DD* + ID_PRODUCT_FROM_DATABASE=GF100GL [Quadro 4000] + +pci:v000010DEd000006DE* + ID_PRODUCT_FROM_DATABASE=GF100 [Tesla S2050] + +pci:v000010DEd000006DF* + ID_PRODUCT_FROM_DATABASE=GF100 [Tesla M2070Q] + +pci:v000010DEd000006E0* + ID_PRODUCT_FROM_DATABASE=G98 [GeForce 9300 GE] + +pci:v000010DEd000006E1* + ID_PRODUCT_FROM_DATABASE=G98 [GeForce 9300 GS] + +pci:v000010DEd000006E2* + ID_PRODUCT_FROM_DATABASE=G98 [GeForce 8400] + +pci:v000010DEd000006E3* + ID_PRODUCT_FROM_DATABASE=G98 [GeForce 8300 GS] + +pci:v000010DEd000006E4* + ID_PRODUCT_FROM_DATABASE=G98 [GeForce 8400 GS] + +pci:v000010DEd000006E4sv00001458sd00003475* + ID_PRODUCT_FROM_DATABASE=GV-NX84S256HE [GeForce 8400 GS] + +pci:v000010DEd000006E5* + ID_PRODUCT_FROM_DATABASE=G98 [GeForce 9300M GS] + +pci:v000010DEd000006E6* + ID_PRODUCT_FROM_DATABASE=G98 [GeForce G 100] + +pci:v000010DEd000006E7* + ID_PRODUCT_FROM_DATABASE=G98 [GeForce 9300 SE] + +pci:v000010DEd000006E8* + ID_PRODUCT_FROM_DATABASE=G98 [GeForce 9200M GS] + +pci:v000010DEd000006E9* + ID_PRODUCT_FROM_DATABASE=G98 [GeForce 9300M GS] + +pci:v000010DEd000006E9sv00001043sd000019B2* + ID_PRODUCT_FROM_DATABASE=U6V laptop + +pci:v000010DEd000006EA* + ID_PRODUCT_FROM_DATABASE=G86M [Quadro NVS 150M] + +pci:v000010DEd000006EB* + ID_PRODUCT_FROM_DATABASE=G98M [Quadro NVS 160M] + +pci:v000010DEd000006EC* + ID_PRODUCT_FROM_DATABASE=G98M [GeForce G 105M] + +pci:v000010DEd000006EF* + ID_PRODUCT_FROM_DATABASE=G98M [GeForce G 103M] + +pci:v000010DEd000006F1* + ID_PRODUCT_FROM_DATABASE=G98M [GeForce G 105M] + +pci:v000010DEd000006F8* + ID_PRODUCT_FROM_DATABASE=G98 [Quadro NVS 420] + +pci:v000010DEd000006F9* + ID_PRODUCT_FROM_DATABASE=G98 [Quadro FX 370 LP] + +pci:v000010DEd000006FA* + ID_PRODUCT_FROM_DATABASE=G98 [Quadro NVS 450] + +pci:v000010DEd000006FB* + ID_PRODUCT_FROM_DATABASE=G98 [Quadro FX 370M] + +pci:v000010DEd000006FD* + ID_PRODUCT_FROM_DATABASE=G98 [Quadro NVS 295] + +pci:v000010DEd000006FF* + ID_PRODUCT_FROM_DATABASE=G98 [HICx16 + Graphics] + +pci:v000010DEd00000751* + ID_PRODUCT_FROM_DATABASE=MCP78S [GeForce 8200] Memory Controller + +pci:v000010DEd00000751sv0000103Csd00002A9E* + ID_PRODUCT_FROM_DATABASE=Pavilion p6310f + +pci:v000010DEd00000751sv00001043sd000082E8* + ID_PRODUCT_FROM_DATABASE=M3N72-D + +pci:v000010DEd00000751sv00001462sd00007508* + ID_PRODUCT_FROM_DATABASE=K9N2GM-FIH + +pci:v000010DEd00000751sv00001849sd00000751* + ID_PRODUCT_FROM_DATABASE=K10N78FullHD-hSLI R3.0 Memory Controller + +pci:v000010DEd00000752* + ID_PRODUCT_FROM_DATABASE=MCP78S [GeForce 8200] SMBus + +pci:v000010DEd00000752sv0000103Csd00002A9E* + ID_PRODUCT_FROM_DATABASE=Pavilion p6310f + +pci:v000010DEd00000752sv00001043sd000082E8* + ID_PRODUCT_FROM_DATABASE=M3N72-D + +pci:v000010DEd00000752sv00001462sd00007508* + ID_PRODUCT_FROM_DATABASE=K9N2GM-FIH + +pci:v000010DEd00000752sv00001849sd00000752* + ID_PRODUCT_FROM_DATABASE=K10N78FullHD-hSLI R3.0 SMBus + +pci:v000010DEd00000753* + ID_PRODUCT_FROM_DATABASE=MCP78S [GeForce 8200] Co-Processor + +pci:v000010DEd00000753sv0000103Csd00002A9E* + ID_PRODUCT_FROM_DATABASE=Pavilion p6310f + +pci:v000010DEd00000753sv00001043sd000082E8* + ID_PRODUCT_FROM_DATABASE=M3N72-D + +pci:v000010DEd00000753sv00001462sd00007508* + ID_PRODUCT_FROM_DATABASE=K9N2GM-FIH + +pci:v000010DEd00000753sv00001849sd00000753* + ID_PRODUCT_FROM_DATABASE=K10N78FullHD-hSLI R3.0 Co-Processor + +pci:v000010DEd00000754* + ID_PRODUCT_FROM_DATABASE=MCP78S [GeForce 8200] Memory Controller + +pci:v000010DEd00000754sv0000103Csd00002A9E* + ID_PRODUCT_FROM_DATABASE=Pavilion p6310f + +pci:v000010DEd00000754sv00001043sd000082E8* + ID_PRODUCT_FROM_DATABASE=M3N72-D + +pci:v000010DEd00000754sv00001462sd00007508* + ID_PRODUCT_FROM_DATABASE=K9N2GM-FIH + +pci:v000010DEd00000754sv00001849sd00000754* + ID_PRODUCT_FROM_DATABASE=K10N78FullHD-hSLI R3.0 Memory Controller + +pci:v000010DEd00000759* + ID_PRODUCT_FROM_DATABASE=MCP78S [GeForce 8200] IDE + +pci:v000010DEd00000759sv00001043sd000082E8* + ID_PRODUCT_FROM_DATABASE=M3N72-D + +pci:v000010DEd00000759sv00001462sd00007508* + ID_PRODUCT_FROM_DATABASE=K9N2GM-FIH + +pci:v000010DEd00000759sv00001849sd00000759* + ID_PRODUCT_FROM_DATABASE=K10N78FullHD-hSLI R3.0 IDE + +pci:v000010DEd0000075A* + ID_PRODUCT_FROM_DATABASE=MCP78S [GeForce 8200] PCI Bridge + +pci:v000010DEd0000075Asv0000103Csd00002A9E* + ID_PRODUCT_FROM_DATABASE=Pavilion p6310f + +pci:v000010DEd0000075Asv00001043sd000082E8* + ID_PRODUCT_FROM_DATABASE=M3N72-D + +pci:v000010DEd0000075Asv00001849sd0000075A* + ID_PRODUCT_FROM_DATABASE=K10N78FullHD-hSLI R3.0 PCI Bridge + +pci:v000010DEd0000075B* + ID_PRODUCT_FROM_DATABASE=MCP78S [GeForce 8200] PCI Express Bridge + +pci:v000010DEd0000075Bsv0000103Csd00002A9E* + ID_PRODUCT_FROM_DATABASE=Pavilion p6310f + +pci:v000010DEd0000075Bsv00001043sd000082E8* + ID_PRODUCT_FROM_DATABASE=M3N72-D + +pci:v000010DEd0000075Bsv00001462sd00007508* + ID_PRODUCT_FROM_DATABASE=K9N2GM-FIH + +pci:v000010DEd0000075Bsv00001849sd0000075B* + ID_PRODUCT_FROM_DATABASE=K10N78FullHD-hSLI R3.0 PCI Express Bridge + +pci:v000010DEd0000075C* + ID_PRODUCT_FROM_DATABASE=MCP78S [GeForce 8200] LPC Bridge + +pci:v000010DEd0000075Csv0000103Csd00002A9E* + ID_PRODUCT_FROM_DATABASE=Pavilion p6310f + +pci:v000010DEd0000075Csv00001462sd00007508* + ID_PRODUCT_FROM_DATABASE=K9N2GM-FIH + +pci:v000010DEd0000075Csv00001849sd0000075C* + ID_PRODUCT_FROM_DATABASE=K10N78FullHD-hSLI R3.0 LPC Bridge + +pci:v000010DEd0000075D* + ID_PRODUCT_FROM_DATABASE=MCP78S [GeForce 8200] LPC Bridge + +pci:v000010DEd0000075Dsv00001043sd000082E8* + ID_PRODUCT_FROM_DATABASE=M3N72-D + +pci:v000010DEd00000760* + ID_PRODUCT_FROM_DATABASE=MCP77 Ethernet + +pci:v000010DEd00000760sv0000103Csd00002A9E* + ID_PRODUCT_FROM_DATABASE=Pavilion p6310f + +pci:v000010DEd00000760sv00001043sd000082E8* + ID_PRODUCT_FROM_DATABASE=M3N72-D + +pci:v000010DEd00000760sv00001462sd00007508* + ID_PRODUCT_FROM_DATABASE=K9N2GM-FIH + +pci:v000010DEd00000760sv00001849sd00000760* + ID_PRODUCT_FROM_DATABASE=K10N78FullHD-hSLI R3.0 Ethernet + +pci:v000010DEd00000761* + ID_PRODUCT_FROM_DATABASE=MCP77 Ethernet + +pci:v000010DEd00000762* + ID_PRODUCT_FROM_DATABASE=MCP77 Ethernet + +pci:v000010DEd00000763* + ID_PRODUCT_FROM_DATABASE=MCP77 Ethernet + +pci:v000010DEd00000774* + ID_PRODUCT_FROM_DATABASE=MCP72XE/MCP72P/MCP78U/MCP78S High Definition Audio + +pci:v000010DEd00000774sv0000103Csd00002A9E* + ID_PRODUCT_FROM_DATABASE=Pavilion p6310f + +pci:v000010DEd00000774sv00001043sd000082FE* + ID_PRODUCT_FROM_DATABASE=M3N72-D + +pci:v000010DEd00000774sv00001462sd00007508* + ID_PRODUCT_FROM_DATABASE=K9N2GM-FIH + +pci:v000010DEd00000774sv00001849sd00003662* + ID_PRODUCT_FROM_DATABASE=K10N78FullHD-hSLI R3.0 High Definition Audio + +pci:v000010DEd00000778* + ID_PRODUCT_FROM_DATABASE=MCP78S [GeForce 8200] PCI Express Bridge + +pci:v000010DEd00000778sv0000103Csd00002A9E* + ID_PRODUCT_FROM_DATABASE=Pavilion p6310f + +pci:v000010DEd00000778sv00001043sd000082E8* + ID_PRODUCT_FROM_DATABASE=M3N72-D + +pci:v000010DEd00000778sv00001462sd00007508* + ID_PRODUCT_FROM_DATABASE=K9N2GM-FIH + +pci:v000010DEd00000778sv00001849sd00000778* + ID_PRODUCT_FROM_DATABASE=K10N78FullHD-hSLI R3.0 PCI Express Bridge + +pci:v000010DEd0000077A* + ID_PRODUCT_FROM_DATABASE=MCP78S [GeForce 8200] PCI Bridge + +pci:v000010DEd0000077Asv0000103Csd00002A9E* + ID_PRODUCT_FROM_DATABASE=Pavilion p6310f + +pci:v000010DEd0000077Asv00001043sd000082E8* + ID_PRODUCT_FROM_DATABASE=M3N72-D + +pci:v000010DEd0000077Asv00001462sd00007508* + ID_PRODUCT_FROM_DATABASE=K9N2GM-FIH + +pci:v000010DEd0000077Asv00001849sd0000077A* + ID_PRODUCT_FROM_DATABASE=K10N78FullHD-hSLI R3.0 PCI Bridge + +pci:v000010DEd0000077B* + ID_PRODUCT_FROM_DATABASE=MCP78S [GeForce 8200] OHCI USB 1.1 Controller + +pci:v000010DEd0000077Bsv0000103Csd00002A9E* + ID_PRODUCT_FROM_DATABASE=Pavilion p6310f + +pci:v000010DEd0000077Bsv00001043sd000082E8* + ID_PRODUCT_FROM_DATABASE=M3N72-D + +pci:v000010DEd0000077Bsv00001462sd00007508* + ID_PRODUCT_FROM_DATABASE=K9N2GM-FIH + +pci:v000010DEd0000077Bsv00001849sd0000077B* + ID_PRODUCT_FROM_DATABASE=K10N78FullHD-hSLI R3.0 OHCI USB 1.1 Controller + +pci:v000010DEd0000077C* + ID_PRODUCT_FROM_DATABASE=MCP78S [GeForce 8200] EHCI USB 2.0 Controller + +pci:v000010DEd0000077Csv0000103Csd00002A9E* + ID_PRODUCT_FROM_DATABASE=Pavilion p6310f + +pci:v000010DEd0000077Csv00001043sd000082E8* + ID_PRODUCT_FROM_DATABASE=M3N72-D + +pci:v000010DEd0000077Csv00001462sd00007508* + ID_PRODUCT_FROM_DATABASE=K9N2GM-FIH + +pci:v000010DEd0000077Csv00001849sd0000077C* + ID_PRODUCT_FROM_DATABASE=K10N78FullHD-hSLI R3.0 EHCI USB 2.0 Controller + +pci:v000010DEd0000077D* + ID_PRODUCT_FROM_DATABASE=MCP78S [GeForce 8200] OHCI USB 1.1 Controller + +pci:v000010DEd0000077Dsv0000103Csd00002A9E* + ID_PRODUCT_FROM_DATABASE=Pavilion p6310f + +pci:v000010DEd0000077Dsv00001043sd000082E8* + ID_PRODUCT_FROM_DATABASE=M3N72-D + +pci:v000010DEd0000077Dsv00001462sd00007508* + ID_PRODUCT_FROM_DATABASE=K9N2GM-FIH + +pci:v000010DEd0000077Dsv00001849sd0000077D* + ID_PRODUCT_FROM_DATABASE=K10N78FullHD-hSLI R3.0 OHCI USB 1.1 Controller + +pci:v000010DEd0000077E* + ID_PRODUCT_FROM_DATABASE=MCP78S [GeForce 8200] EHCI USB 2.0 Controller + +pci:v000010DEd0000077Esv0000103Csd00002A9E* + ID_PRODUCT_FROM_DATABASE=Pavilion p6310f + +pci:v000010DEd0000077Esv00001043sd000082E8* + ID_PRODUCT_FROM_DATABASE=M3N72-D + +pci:v000010DEd0000077Esv00001462sd00007508* + ID_PRODUCT_FROM_DATABASE=K9N2GM-FIH + +pci:v000010DEd0000077Esv00001849sd0000077E* + ID_PRODUCT_FROM_DATABASE=K10N78FullHD-hSLI R3.0 EHCI USB 2.0 Controller + +pci:v000010DEd000007C0* + ID_PRODUCT_FROM_DATABASE=MCP73 Host Bridge + +pci:v000010DEd000007C0sv00001AFAsd00007150* + ID_PRODUCT_FROM_DATABASE=JW-IN7150-HD + +pci:v000010DEd000007C1* + ID_PRODUCT_FROM_DATABASE=MCP73 Host Bridge + +pci:v000010DEd000007C1sv00001019sd0000297A* + ID_PRODUCT_FROM_DATABASE=MCP73PVT-SM + +pci:v000010DEd000007C2* + ID_PRODUCT_FROM_DATABASE=MCP73 Host Bridge + +pci:v000010DEd000007C5* + ID_PRODUCT_FROM_DATABASE=MCP73 Host Bridge + +pci:v000010DEd000007C8* + ID_PRODUCT_FROM_DATABASE=MCP73 Memory Controller + +pci:v000010DEd000007C8sv00001019sd0000297A* + ID_PRODUCT_FROM_DATABASE=MCP73PVT-SM + +pci:v000010DEd000007C8sv00001AFAsd00007150* + ID_PRODUCT_FROM_DATABASE=JW-IN7150-HD + +pci:v000010DEd000007CB* + ID_PRODUCT_FROM_DATABASE=nForce 630i memory controller + +pci:v000010DEd000007CBsv00001019sd0000297A* + ID_PRODUCT_FROM_DATABASE=MCP73PVT-SM + +pci:v000010DEd000007CBsv00001AFAsd00007150* + ID_PRODUCT_FROM_DATABASE=JW-IN7150-HD + +pci:v000010DEd000007CD* + ID_PRODUCT_FROM_DATABASE=nForce 630i memory controller + +pci:v000010DEd000007CDsv00001019sd0000297A* + ID_PRODUCT_FROM_DATABASE=MCP73PVT-SM + +pci:v000010DEd000007CDsv00001AFAsd00007150* + ID_PRODUCT_FROM_DATABASE=JW-IN7150-HD + +pci:v000010DEd000007CE* + ID_PRODUCT_FROM_DATABASE=nForce 630i memory controller + +pci:v000010DEd000007CEsv00001019sd0000297A* + ID_PRODUCT_FROM_DATABASE=MCP73PVT-SM + +pci:v000010DEd000007CEsv00001AFAsd00007150* + ID_PRODUCT_FROM_DATABASE=JW-IN7150-HD + +pci:v000010DEd000007CF* + ID_PRODUCT_FROM_DATABASE=nForce 630i memory controller + +pci:v000010DEd000007CFsv00001019sd0000297A* + ID_PRODUCT_FROM_DATABASE=MCP73PVT-SM + +pci:v000010DEd000007CFsv00001AFAsd00007150* + ID_PRODUCT_FROM_DATABASE=JW-IN7150-HD + +pci:v000010DEd000007D0* + ID_PRODUCT_FROM_DATABASE=nForce 630i memory controller + +pci:v000010DEd000007D0sv00001019sd0000297A* + ID_PRODUCT_FROM_DATABASE=MCP73PVT-SM + +pci:v000010DEd000007D0sv00001AFAsd00007150* + ID_PRODUCT_FROM_DATABASE=JW-IN7150-HD + +pci:v000010DEd000007D1* + ID_PRODUCT_FROM_DATABASE=nForce 630i memory controller + +pci:v000010DEd000007D1sv00001019sd0000297A* + ID_PRODUCT_FROM_DATABASE=MCP73PVT-SM + +pci:v000010DEd000007D1sv00001AFAsd00007150* + ID_PRODUCT_FROM_DATABASE=JW-IN7150-HD + +pci:v000010DEd000007D2* + ID_PRODUCT_FROM_DATABASE=nForce 630i memory controller + +pci:v000010DEd000007D2sv00001019sd0000297A* + ID_PRODUCT_FROM_DATABASE=MCP73PVT-SM + +pci:v000010DEd000007D2sv00001AFAsd00007150* + ID_PRODUCT_FROM_DATABASE=JW-IN7150-HD + +pci:v000010DEd000007D3* + ID_PRODUCT_FROM_DATABASE=nForce 630i memory controller + +pci:v000010DEd000007D3sv00001019sd0000297A* + ID_PRODUCT_FROM_DATABASE=MCP73PVT-SM + +pci:v000010DEd000007D3sv00001AFAsd00007150* + ID_PRODUCT_FROM_DATABASE=JW-IN7150-HD + +pci:v000010DEd000007D6* + ID_PRODUCT_FROM_DATABASE=nForce 630i memory controller + +pci:v000010DEd000007D6sv00001019sd0000297A* + ID_PRODUCT_FROM_DATABASE=MCP73PVT-SM + +pci:v000010DEd000007D6sv00001AFAsd00007150* + ID_PRODUCT_FROM_DATABASE=JW-IN7150-HD + +pci:v000010DEd000007D7* + ID_PRODUCT_FROM_DATABASE=MCP73 LPC Bridge + +pci:v000010DEd000007D7sv00001019sd0000297A* + ID_PRODUCT_FROM_DATABASE=MCP73PVT-SM + +pci:v000010DEd000007D7sv00001AFAsd00007150* + ID_PRODUCT_FROM_DATABASE=JW-IN7150-HD + +pci:v000010DEd000007D8* + ID_PRODUCT_FROM_DATABASE=MCP73 SMBus + +pci:v000010DEd000007D8sv00001019sd0000297A* + ID_PRODUCT_FROM_DATABASE=MCP73PVT-SM + +pci:v000010DEd000007D8sv00001AFAsd00007150* + ID_PRODUCT_FROM_DATABASE=JW-IN7150-HD + +pci:v000010DEd000007D9* + ID_PRODUCT_FROM_DATABASE=MCP73 Memory Controller + +pci:v000010DEd000007D9sv00001019sd0000297A* + ID_PRODUCT_FROM_DATABASE=MCP73PVT-SM + +pci:v000010DEd000007D9sv00001AFAsd00007150* + ID_PRODUCT_FROM_DATABASE=JW-IN7150-HD + +pci:v000010DEd000007DA* + ID_PRODUCT_FROM_DATABASE=MCP73 Co-processor + +pci:v000010DEd000007DAsv00001AFAsd00007150* + ID_PRODUCT_FROM_DATABASE=JW-IN7150-HD + +pci:v000010DEd000007DC* + ID_PRODUCT_FROM_DATABASE=MCP73 Ethernet + +pci:v000010DEd000007DD* + ID_PRODUCT_FROM_DATABASE=MCP73 Ethernet + +pci:v000010DEd000007DE* + ID_PRODUCT_FROM_DATABASE=MCP73 Ethernet + +pci:v000010DEd000007DF* + ID_PRODUCT_FROM_DATABASE=MCP73 Ethernet + +pci:v000010DEd000007E0* + ID_PRODUCT_FROM_DATABASE=C73 [GeForce 7150 / nForce 630i] + +pci:v000010DEd000007E0sv00001AFAsd00007150* + ID_PRODUCT_FROM_DATABASE=JW-IN7150-HD + +pci:v000010DEd000007E1* + ID_PRODUCT_FROM_DATABASE=C73 [GeForce 7100 / nForce 630i] + +pci:v000010DEd000007E1sv00001019sd0000297A* + ID_PRODUCT_FROM_DATABASE=MCP73PVT-SM + +pci:v000010DEd000007E2* + ID_PRODUCT_FROM_DATABASE=C73 [GeForce 7050 / nForce 630i] + +pci:v000010DEd000007E3* + ID_PRODUCT_FROM_DATABASE=C73 [GeForce 7050 / nForce 610i] + +pci:v000010DEd000007E5* + ID_PRODUCT_FROM_DATABASE=C73 [GeForce 7100 / nForce 620i] + +pci:v000010DEd000007F0* + ID_PRODUCT_FROM_DATABASE=MCP73 IDE + +pci:v000010DEd000007F4* + ID_PRODUCT_FROM_DATABASE=GeForce 7100/nForce 630i SATA + +pci:v000010DEd000007F4sv00001019sd0000297A* + ID_PRODUCT_FROM_DATABASE=MCP73PVT-SM + +pci:v000010DEd000007F8* + ID_PRODUCT_FROM_DATABASE=MCP73 SATA RAID Controller + +pci:v000010DEd000007FC* + ID_PRODUCT_FROM_DATABASE=MCP73 High Definition Audio + +pci:v000010DEd000007FCsv00001019sd0000297A* + ID_PRODUCT_FROM_DATABASE=MCP73PVT-SM + +pci:v000010DEd000007FCsv000010DEsd000007FC* + ID_PRODUCT_FROM_DATABASE=MCP73 High Definition Audio + +pci:v000010DEd000007FE* + ID_PRODUCT_FROM_DATABASE=GeForce 7100/nForce 630i USB + +pci:v000010DEd000007FEsv00001019sd0000297A* + ID_PRODUCT_FROM_DATABASE=MCP73PVT-SM + +pci:v000010DEd000007FEsv00001AFAsd00007150* + ID_PRODUCT_FROM_DATABASE=JW-IN7150-HD + +pci:v000010DEd00000844* + ID_PRODUCT_FROM_DATABASE=C77 [GeForce 9100M G] + +pci:v000010DEd00000845* + ID_PRODUCT_FROM_DATABASE=C77 [GeForce 8200M G] + +pci:v000010DEd00000846* + ID_PRODUCT_FROM_DATABASE=C77 [GeForce 9200] + +pci:v000010DEd00000847* + ID_PRODUCT_FROM_DATABASE=C78 [GeForce 9100] + +pci:v000010DEd00000847sv0000103Csd00002A9E* + ID_PRODUCT_FROM_DATABASE=Pavilion p6310f + +pci:v000010DEd00000848* + ID_PRODUCT_FROM_DATABASE=C77 [GeForce 8300] + +pci:v000010DEd00000849* + ID_PRODUCT_FROM_DATABASE=C77 [GeForce 8200] + +pci:v000010DEd00000849sv00001462sd00007508* + ID_PRODUCT_FROM_DATABASE=K9N2GM-FIH + +pci:v000010DEd00000849sv00001849sd00000849* + ID_PRODUCT_FROM_DATABASE=K10N78FullHD-hSLI R3.0 GeForce 8200 + +pci:v000010DEd0000084A* + ID_PRODUCT_FROM_DATABASE=C77 [nForce 730a] + +pci:v000010DEd0000084B* + ID_PRODUCT_FROM_DATABASE=C77 [GeForce 8200] + +pci:v000010DEd0000084C* + ID_PRODUCT_FROM_DATABASE=C77 [nForce 780a SLI] + +pci:v000010DEd0000084D* + ID_PRODUCT_FROM_DATABASE=C77 [nForce 750a SLI] + +pci:v000010DEd0000084Dsv00001043sd000082E8* + ID_PRODUCT_FROM_DATABASE=M3N72-D mGPU + +pci:v000010DEd0000084F* + ID_PRODUCT_FROM_DATABASE=C77 [GeForce 8100 / nForce 720a] + +pci:v000010DEd00000860* + ID_PRODUCT_FROM_DATABASE=C79 [GeForce 9300] + +pci:v000010DEd00000861* + ID_PRODUCT_FROM_DATABASE=C79 [GeForce 9400] + +pci:v000010DEd00000862* + ID_PRODUCT_FROM_DATABASE=C79 [GeForce 9400M G] + +pci:v000010DEd00000863* + ID_PRODUCT_FROM_DATABASE=C79 [GeForce 9400M] + +pci:v000010DEd00000864* + ID_PRODUCT_FROM_DATABASE=C79 [GeForce 9300] + +pci:v000010DEd00000865* + ID_PRODUCT_FROM_DATABASE=C79 [GeForce 9300] + +pci:v000010DEd00000866* + ID_PRODUCT_FROM_DATABASE=C79 [GeForce 9400M G] + +pci:v000010DEd00000867* + ID_PRODUCT_FROM_DATABASE=C79 [GeForce 9400] + +pci:v000010DEd00000868* + ID_PRODUCT_FROM_DATABASE=C79 [nForce 760i SLI] + +pci:v000010DEd0000086A* + ID_PRODUCT_FROM_DATABASE=C79 [GeForce 9400] + +pci:v000010DEd0000086C* + ID_PRODUCT_FROM_DATABASE=C79 [GeForce 9300 / nForce 730i] + +pci:v000010DEd0000086D* + ID_PRODUCT_FROM_DATABASE=C79 [GeForce 9200] + +pci:v000010DEd0000086E* + ID_PRODUCT_FROM_DATABASE=C79 [GeForce 9100M G] + +pci:v000010DEd0000086F* + ID_PRODUCT_FROM_DATABASE=C79 [GeForce 9200M G] + +pci:v000010DEd00000870* + ID_PRODUCT_FROM_DATABASE=C79 [GeForce 9400M] + +pci:v000010DEd00000871* + ID_PRODUCT_FROM_DATABASE=C79 [GeForce 9200] + +pci:v000010DEd00000872* + ID_PRODUCT_FROM_DATABASE=C79 [GeForce G102M] + +pci:v000010DEd00000873* + ID_PRODUCT_FROM_DATABASE=C79 [GeForce G102M] + +pci:v000010DEd00000874* + ID_PRODUCT_FROM_DATABASE=C79 [ION] + +pci:v000010DEd00000876* + ID_PRODUCT_FROM_DATABASE=ION VGA [GeForce 9400M] + +pci:v000010DEd0000087A* + ID_PRODUCT_FROM_DATABASE=C79 [GeForce 9400] + +pci:v000010DEd0000087D* + ID_PRODUCT_FROM_DATABASE=ION VGA + +pci:v000010DEd0000087Dsv000019DAsd0000A123* + ID_PRODUCT_FROM_DATABASE=IONITX-F-E + +pci:v000010DEd0000087E* + ID_PRODUCT_FROM_DATABASE=ION LE VGA + +pci:v000010DEd0000087F* + ID_PRODUCT_FROM_DATABASE=ION LE VGA + +pci:v000010DEd000008A3* + ID_PRODUCT_FROM_DATABASE=MCP89 [GeForce 320M] + +pci:v000010DEd000008A4* + ID_PRODUCT_FROM_DATABASE=MCP89 [GeForce 320M] + +pci:v000010DEd00000A20* + ID_PRODUCT_FROM_DATABASE=GT216 [GeForce GT 220] + +pci:v000010DEd00000A20sv00001043sd00008311* + ID_PRODUCT_FROM_DATABASE=ENGT220/DI/1GD3(LP)/V2 + +pci:v000010DEd00000A23* + ID_PRODUCT_FROM_DATABASE=GT218 [GeForce 210] + +pci:v000010DEd00000A28* + ID_PRODUCT_FROM_DATABASE=GT216 [GeForce GT 230M] + +pci:v000010DEd00000A29* + ID_PRODUCT_FROM_DATABASE=GT216 [GeForce GT 330M] + +pci:v000010DEd00000A2A* + ID_PRODUCT_FROM_DATABASE=GT216 [GeForce GT 230M] + +pci:v000010DEd00000A2B* + ID_PRODUCT_FROM_DATABASE=GT216 [GeForce GT 330M] + +pci:v000010DEd00000A2C* + ID_PRODUCT_FROM_DATABASE=GT216 [NVS 5100M] + +pci:v000010DEd00000A2D* + ID_PRODUCT_FROM_DATABASE=GT216 [GeForce GT 320M] + +pci:v000010DEd00000A34* + ID_PRODUCT_FROM_DATABASE=GT216 [GeForce GT 240M] + +pci:v000010DEd00000A35* + ID_PRODUCT_FROM_DATABASE=GT216 [GeForce GT 325M] + +pci:v000010DEd00000A38* + ID_PRODUCT_FROM_DATABASE=GT216GL [Quadro 400] + +pci:v000010DEd00000A3C* + ID_PRODUCT_FROM_DATABASE=GT216 [Quadro FX 880M] + +pci:v000010DEd00000A60* + ID_PRODUCT_FROM_DATABASE=GT218 [GeForce G210] + +pci:v000010DEd00000A62* + ID_PRODUCT_FROM_DATABASE=GT218 [GeForce 205] + +pci:v000010DEd00000A63* + ID_PRODUCT_FROM_DATABASE=GT218 [GeForce 310] + +pci:v000010DEd00000A64* + ID_PRODUCT_FROM_DATABASE=GT218 [ION] + +pci:v000010DEd00000A65* + ID_PRODUCT_FROM_DATABASE=GT218 [GeForce 210] + +pci:v000010DEd00000A65sv00001043sd00008334* + ID_PRODUCT_FROM_DATABASE=EN210 SILENT + +pci:v000010DEd00000A66* + ID_PRODUCT_FROM_DATABASE=GT218 [GeForce 310] + +pci:v000010DEd00000A67* + ID_PRODUCT_FROM_DATABASE=GT218 [GeForce 315] + +pci:v000010DEd00000A68* + ID_PRODUCT_FROM_DATABASE=G98M [GeForce G105M] + +pci:v000010DEd00000A69* + ID_PRODUCT_FROM_DATABASE=G98M [GeForce G105M] + +pci:v000010DEd00000A6A* + ID_PRODUCT_FROM_DATABASE=GT218 [NVS 2100M] + +pci:v000010DEd00000A6C* + ID_PRODUCT_FROM_DATABASE=GT218 [NVS 3100M] + +pci:v000010DEd00000A6Csv00001028sd0000040B* + ID_PRODUCT_FROM_DATABASE=Latitude E6510 + +pci:v000010DEd00000A6Csv000017AAsd00002142* + ID_PRODUCT_FROM_DATABASE=ThinkPad T410 + +pci:v000010DEd00000A6E* + ID_PRODUCT_FROM_DATABASE=GT218 [GeForce 305M] + +pci:v000010DEd00000A6F* + ID_PRODUCT_FROM_DATABASE=GT218 [ION] + +pci:v000010DEd00000A70* + ID_PRODUCT_FROM_DATABASE=GT218 [GeForce 310M] + +pci:v000010DEd00000A71* + ID_PRODUCT_FROM_DATABASE=GT218 [GeForce 305M] + +pci:v000010DEd00000A72* + ID_PRODUCT_FROM_DATABASE=GT218 [GeForce 310M] + +pci:v000010DEd00000A73* + ID_PRODUCT_FROM_DATABASE=GT218 [GeForce 305M] + +pci:v000010DEd00000A74* + ID_PRODUCT_FROM_DATABASE=GT218 [GeForce G210M] + +pci:v000010DEd00000A75* + ID_PRODUCT_FROM_DATABASE=GT218 [GeForce 310M] + +pci:v000010DEd00000A76* + ID_PRODUCT_FROM_DATABASE=GT218 [ION 2] + +pci:v000010DEd00000A78* + ID_PRODUCT_FROM_DATABASE=GT218GL [Quadro FX 380 LP] + +pci:v000010DEd00000A7C* + ID_PRODUCT_FROM_DATABASE=GT218 [Quadro FX 380M] + +pci:v000010DEd00000A80* + ID_PRODUCT_FROM_DATABASE=MCP79 Host Bridge + +pci:v000010DEd00000A81* + ID_PRODUCT_FROM_DATABASE=MCP79 Host Bridge + +pci:v000010DEd00000A82* + ID_PRODUCT_FROM_DATABASE=MCP79 Host Bridge + +pci:v000010DEd00000A83* + ID_PRODUCT_FROM_DATABASE=MCP79 Host Bridge + +pci:v000010DEd00000A84* + ID_PRODUCT_FROM_DATABASE=MCP79 Host Bridge + +pci:v000010DEd00000A85* + ID_PRODUCT_FROM_DATABASE=MCP79 Host Bridge + +pci:v000010DEd00000A86* + ID_PRODUCT_FROM_DATABASE=MCP79 Host Bridge + +pci:v000010DEd00000A87* + ID_PRODUCT_FROM_DATABASE=MCP79 Host Bridge + +pci:v000010DEd00000A88* + ID_PRODUCT_FROM_DATABASE=MCP79 Memory Controller + +pci:v000010DEd00000A89* + ID_PRODUCT_FROM_DATABASE=MCP79 Memory Controller + +pci:v000010DEd00000AA0* + ID_PRODUCT_FROM_DATABASE=MCP79 PCI Express Bridge + +pci:v000010DEd00000AA2* + ID_PRODUCT_FROM_DATABASE=MCP79 SMBus + +pci:v000010DEd00000AA2sv000019DAsd0000A123* + ID_PRODUCT_FROM_DATABASE=IONITX-F-E + +pci:v000010DEd00000AA3* + ID_PRODUCT_FROM_DATABASE=MCP79 Co-processor + +pci:v000010DEd00000AA3sv000019DAsd0000A123* + ID_PRODUCT_FROM_DATABASE=IONITX-F-E + +pci:v000010DEd00000AA4* + ID_PRODUCT_FROM_DATABASE=MCP79 Memory Controller + +pci:v000010DEd00000AA4sv000019DAsd0000A123* + ID_PRODUCT_FROM_DATABASE=IONITX-F-E + +pci:v000010DEd00000AA5* + ID_PRODUCT_FROM_DATABASE=MCP79 OHCI USB 1.1 Controller + +pci:v000010DEd00000AA5sv000019DAsd0000A123* + ID_PRODUCT_FROM_DATABASE=IONITX-F-E + +pci:v000010DEd00000AA6* + ID_PRODUCT_FROM_DATABASE=MCP79 EHCI USB 2.0 Controller + +pci:v000010DEd00000AA6sv000019DAsd0000A123* + ID_PRODUCT_FROM_DATABASE=IONITX-F-E + +pci:v000010DEd00000AA7* + ID_PRODUCT_FROM_DATABASE=MCP79 OHCI USB 1.1 Controller + +pci:v000010DEd00000AA7sv000019DAsd0000A123* + ID_PRODUCT_FROM_DATABASE=IONITX-F-E + +pci:v000010DEd00000AA8* + ID_PRODUCT_FROM_DATABASE=MCP79 OHCI USB 1.1 Controller + +pci:v000010DEd00000AA9* + ID_PRODUCT_FROM_DATABASE=MCP79 EHCI USB 2.0 Controller + +pci:v000010DEd00000AA9sv000019DAsd0000A123* + ID_PRODUCT_FROM_DATABASE=IONITX-F-E + +pci:v000010DEd00000AAA* + ID_PRODUCT_FROM_DATABASE=MCP79 EHCI USB 2.0 Controller + +pci:v000010DEd00000AAB* + ID_PRODUCT_FROM_DATABASE=MCP79 PCI Bridge + +pci:v000010DEd00000AAC* + ID_PRODUCT_FROM_DATABASE=MCP79 LPC Bridge + +pci:v000010DEd00000AAD* + ID_PRODUCT_FROM_DATABASE=MCP79 LPC Bridge + +pci:v000010DEd00000AADsv000019DAsd0000A123* + ID_PRODUCT_FROM_DATABASE=IONITX-F-E + +pci:v000010DEd00000AAE* + ID_PRODUCT_FROM_DATABASE=MCP79 LPC Bridge + +pci:v000010DEd00000AAF* + ID_PRODUCT_FROM_DATABASE=MCP79 LPC Bridge + +pci:v000010DEd00000AB0* + ID_PRODUCT_FROM_DATABASE=MCP79 Ethernet + +pci:v000010DEd00000AB0sv000019DAsd0000A123* + ID_PRODUCT_FROM_DATABASE=IONITX-F-E + +pci:v000010DEd00000AB1* + ID_PRODUCT_FROM_DATABASE=MCP79 Ethernet + +pci:v000010DEd00000AB2* + ID_PRODUCT_FROM_DATABASE=MCP79 Ethernet + +pci:v000010DEd00000AB3* + ID_PRODUCT_FROM_DATABASE=MCP79 Ethernet + +pci:v000010DEd00000AB4* + ID_PRODUCT_FROM_DATABASE=MCP79 SATA Controller + +pci:v000010DEd00000AB4sv000019DAsd0000A123* + ID_PRODUCT_FROM_DATABASE=IONITX-F-E + +pci:v000010DEd00000AB5* + ID_PRODUCT_FROM_DATABASE=MCP79 SATA Controller + +pci:v000010DEd00000AB6* + ID_PRODUCT_FROM_DATABASE=MCP79 SATA Controller + +pci:v000010DEd00000AB7* + ID_PRODUCT_FROM_DATABASE=MCP79 SATA Controller + +pci:v000010DEd00000AB8* + ID_PRODUCT_FROM_DATABASE=MCP79 AHCI Controller + +pci:v000010DEd00000AB9* + ID_PRODUCT_FROM_DATABASE=MCP79 AHCI Controller + +pci:v000010DEd00000ABA* + ID_PRODUCT_FROM_DATABASE=MCP79 AHCI Controller + +pci:v000010DEd00000ABB* + ID_PRODUCT_FROM_DATABASE=MCP79 AHCI Controller + +pci:v000010DEd00000ABC* + ID_PRODUCT_FROM_DATABASE=MCP79 RAID Controller + +pci:v000010DEd00000ABD* + ID_PRODUCT_FROM_DATABASE=MCP79 RAID Controller + +pci:v000010DEd00000ABE* + ID_PRODUCT_FROM_DATABASE=MCP79 RAID Controller + +pci:v000010DEd00000ABF* + ID_PRODUCT_FROM_DATABASE=MCP79 RAID Controller + +pci:v000010DEd00000AC0* + ID_PRODUCT_FROM_DATABASE=MCP79 High Definition Audio + +pci:v000010DEd00000AC1* + ID_PRODUCT_FROM_DATABASE=MCP79 High Definition Audio + +pci:v000010DEd00000AC2* + ID_PRODUCT_FROM_DATABASE=MCP79 High Definition Audio + +pci:v000010DEd00000AC3* + ID_PRODUCT_FROM_DATABASE=MCP79 High Definition Audio + +pci:v000010DEd00000AC4* + ID_PRODUCT_FROM_DATABASE=MCP79 PCI Express Bridge + +pci:v000010DEd00000AC5* + ID_PRODUCT_FROM_DATABASE=MCP79 PCI Express Bridge + +pci:v000010DEd00000AC6* + ID_PRODUCT_FROM_DATABASE=MCP79 PCI Express Bridge + +pci:v000010DEd00000AC7* + ID_PRODUCT_FROM_DATABASE=MCP79 PCI Express Bridge + +pci:v000010DEd00000AC8* + ID_PRODUCT_FROM_DATABASE=MCP79 PCI Express Bridge + +pci:v000010DEd00000AD0* + ID_PRODUCT_FROM_DATABASE=MCP78S [GeForce 8200] SATA Controller (non-AHCI mode) + +pci:v000010DEd00000AD0sv00001462sd00007508* + ID_PRODUCT_FROM_DATABASE=K9N2GM-FIH + +pci:v000010DEd00000AD0sv00001849sd00000AD0* + ID_PRODUCT_FROM_DATABASE=K10N78FullHD-hSLI R3.0 IDE + +pci:v000010DEd00000AD4* + ID_PRODUCT_FROM_DATABASE=MCP78S [GeForce 8200] AHCI Controller + +pci:v000010DEd00000AD4sv0000103Csd00002A9E* + ID_PRODUCT_FROM_DATABASE=Pavilion p6310f + +pci:v000010DEd00000AD4sv00001043sd000082E8* + ID_PRODUCT_FROM_DATABASE=M3N72-D + +pci:v000010DEd00000AD4sv00001849sd00000AD4* + ID_PRODUCT_FROM_DATABASE=K10N78FullHD-hSLI R3.0 AHCI Controller + +pci:v000010DEd00000AD8* + ID_PRODUCT_FROM_DATABASE=MCP78S [GeForce 8200] SATA Controller (RAID mode) + +pci:v000010DEd00000BE2* + ID_PRODUCT_FROM_DATABASE=High Definition Audio Controller + +pci:v000010DEd00000BE2sv00001043sd00008311* + ID_PRODUCT_FROM_DATABASE=ENGT220/DI/1GD3(LP)/V2 + +pci:v000010DEd00000BE3* + ID_PRODUCT_FROM_DATABASE=High Definition Audio Controller + +pci:v000010DEd00000BE3sv00001028sd0000040B* + ID_PRODUCT_FROM_DATABASE=Latitude E6510 + +pci:v000010DEd00000BE3sv000010DEsd0000066D* + ID_PRODUCT_FROM_DATABASE=G98 [GeForce 8400GS] + +pci:v000010DEd00000BE4* + ID_PRODUCT_FROM_DATABASE=High Definition Audio Controller + +pci:v000010DEd00000BE5* + ID_PRODUCT_FROM_DATABASE=GF100 High Definition Audio Controller + +pci:v000010DEd00000BE9* + ID_PRODUCT_FROM_DATABASE=GF106 High Definition Audio Controller + +pci:v000010DEd00000BE9sv00001558sd00008687* + ID_PRODUCT_FROM_DATABASE=CLEVO/KAPOK W860CU + +pci:v000010DEd00000BEA* + ID_PRODUCT_FROM_DATABASE=GF108 High Definition Audio Controller + +pci:v000010DEd00000BEAsv00003842sd00001430* + ID_PRODUCT_FROM_DATABASE=GeForce GT 430 + +pci:v000010DEd00000BEB* + ID_PRODUCT_FROM_DATABASE=GF104 High Definition Audio Controller + +pci:v000010DEd00000BEBsv00001462sd00002322* + ID_PRODUCT_FROM_DATABASE=N460GTX Cyclone 1GD5/OC + +pci:v000010DEd00000BEE* + ID_PRODUCT_FROM_DATABASE=GF116 High Definition Audio Controller + +pci:v000010DEd00000CA0* + ID_PRODUCT_FROM_DATABASE=GT215 [GeForce GT 330] + +pci:v000010DEd00000CA2* + ID_PRODUCT_FROM_DATABASE=GT215 [GeForce GT 320] + +pci:v000010DEd00000CA3* + ID_PRODUCT_FROM_DATABASE=GT215 [GeForce GT 240] + +pci:v000010DEd00000CA4* + ID_PRODUCT_FROM_DATABASE=GT215 [GeForce GT 340] + +pci:v000010DEd00000CA5* + ID_PRODUCT_FROM_DATABASE=GT215 [GeForce GT 220] + +pci:v000010DEd00000CA7* + ID_PRODUCT_FROM_DATABASE=GT215 [GeForce GT 330] + +pci:v000010DEd00000CA8* + ID_PRODUCT_FROM_DATABASE=GT215 [GeForce GTS 260M] + +pci:v000010DEd00000CA9* + ID_PRODUCT_FROM_DATABASE=GT215 [GeForce GTS 250M] + +pci:v000010DEd00000CAC* + ID_PRODUCT_FROM_DATABASE=GT215 [GeForce GT 220] + +pci:v000010DEd00000CAF* + ID_PRODUCT_FROM_DATABASE=GT215 [GeForce GT 335M] + +pci:v000010DEd00000CB0* + ID_PRODUCT_FROM_DATABASE=GT215 [GeForce GTS 350M] + +pci:v000010DEd00000CB1* + ID_PRODUCT_FROM_DATABASE=GT215 [GeForce GTS 360M] + +pci:v000010DEd00000CBC* + ID_PRODUCT_FROM_DATABASE=GT215 [Quadro FX 1800M] + +pci:v000010DEd00000D60* + ID_PRODUCT_FROM_DATABASE=MCP89 HOST Bridge + +pci:v000010DEd00000D68* + ID_PRODUCT_FROM_DATABASE=MCP89 Memory Controller + +pci:v000010DEd00000D69* + ID_PRODUCT_FROM_DATABASE=MCP89 Memory Controller + +pci:v000010DEd00000D76* + ID_PRODUCT_FROM_DATABASE=MCP89 PCI Express Bridge + +pci:v000010DEd00000D79* + ID_PRODUCT_FROM_DATABASE=MCP89 SMBus + +pci:v000010DEd00000D7A* + ID_PRODUCT_FROM_DATABASE=MCP89 Co-Processor + +pci:v000010DEd00000D7B* + ID_PRODUCT_FROM_DATABASE=MCP89 Memory Controller + +pci:v000010DEd00000D7D* + ID_PRODUCT_FROM_DATABASE=MCP89 Ethernet + +pci:v000010DEd00000D80* + ID_PRODUCT_FROM_DATABASE=MCP89 LPC Bridge + +pci:v000010DEd00000D85* + ID_PRODUCT_FROM_DATABASE=MCP89 SATA Controller + +pci:v000010DEd00000D88* + ID_PRODUCT_FROM_DATABASE=MCP89 SATA Controller (AHCI mode) + +pci:v000010DEd00000D89* + ID_PRODUCT_FROM_DATABASE=MCP89 SATA Controller (AHCI mode) + +pci:v000010DEd00000D8D* + ID_PRODUCT_FROM_DATABASE=MCP89 SATA Controller (RAID mode) + +pci:v000010DEd00000D94* + ID_PRODUCT_FROM_DATABASE=MCP89 High Definition Audio + +pci:v000010DEd00000D9C* + ID_PRODUCT_FROM_DATABASE=MCP89 OHCI USB 1.1 Controller + +pci:v000010DEd00000D9D* + ID_PRODUCT_FROM_DATABASE=MCP89 EHCI USB 2.0 Controller + +pci:v000010DEd00000DC0* + ID_PRODUCT_FROM_DATABASE=GF108 [GeForce GT 440] + +pci:v000010DEd00000DC4* + ID_PRODUCT_FROM_DATABASE=GF106 [GeForce GTS 450] + +pci:v000010DEd00000DC5* + ID_PRODUCT_FROM_DATABASE=GF106 [GeForce GTS 450] + +pci:v000010DEd00000DC6* + ID_PRODUCT_FROM_DATABASE=GF106 [GeForce GTS 450] + +pci:v000010DEd00000DCD* + ID_PRODUCT_FROM_DATABASE=GF106 [GeForce GT 555M] + +pci:v000010DEd00000DCE* + ID_PRODUCT_FROM_DATABASE=GF106 [GeForce GT 555M] + +pci:v000010DEd00000DD1* + ID_PRODUCT_FROM_DATABASE=GF106 [GeForce GTX 460M] + +pci:v000010DEd00000DD1sv00001558sd00008687* + ID_PRODUCT_FROM_DATABASE=CLEVO/KAPOK W860CU + +pci:v000010DEd00000DD2* + ID_PRODUCT_FROM_DATABASE=GF106 [GeForce GT 445M] + +pci:v000010DEd00000DD8* + ID_PRODUCT_FROM_DATABASE=GF106GL [Quadro 2000] + +pci:v000010DEd00000DDA* + ID_PRODUCT_FROM_DATABASE=GF106GLM [Quadro 2000M] + +pci:v000010DEd00000DE0* + ID_PRODUCT_FROM_DATABASE=GF108 [GeForce GT 440] + +pci:v000010DEd00000DE1* + ID_PRODUCT_FROM_DATABASE=GF108 [GeForce GT 430] + +pci:v000010DEd00000DE1sv00003842sd00001430* + ID_PRODUCT_FROM_DATABASE=GeForce GT 430 + +pci:v000010DEd00000DE2* + ID_PRODUCT_FROM_DATABASE=GF108 [GeForce GT 420] + +pci:v000010DEd00000DE4* + ID_PRODUCT_FROM_DATABASE=GF108 [GeForce GT 520] + +pci:v000010DEd00000DE5* + ID_PRODUCT_FROM_DATABASE=GF108 [GeForce GT 530] + +pci:v000010DEd00000DE9* + ID_PRODUCT_FROM_DATABASE=GF108 [GeForce GT 630M] + +pci:v000010DEd00000DEB* + ID_PRODUCT_FROM_DATABASE=GF108 [GeForce GT 555M] + +pci:v000010DEd00000DEE* + ID_PRODUCT_FROM_DATABASE=GF108 [GeForce GT 415M] + +pci:v000010DEd00000DEF* + ID_PRODUCT_FROM_DATABASE=GF108 [Quadro NVS 5400M] + +pci:v000010DEd00000DF0* + ID_PRODUCT_FROM_DATABASE=GF108 [GeForce GT 425M] + +pci:v000010DEd00000DF2* + ID_PRODUCT_FROM_DATABASE=GF108 [GeForce GT 435M] + +pci:v000010DEd00000DF4* + ID_PRODUCT_FROM_DATABASE=GF108 [GeForce GT 540M] + +pci:v000010DEd00000DF5* + ID_PRODUCT_FROM_DATABASE=GF108 [GeForce GT 540M] + +pci:v000010DEd00000DF7* + ID_PRODUCT_FROM_DATABASE=GF108 [GeForce GT 520M] + +pci:v000010DEd00000DF8* + ID_PRODUCT_FROM_DATABASE=GF108GL [Quadro 600] + +pci:v000010DEd00000DF9* + ID_PRODUCT_FROM_DATABASE=GF108GLM [Quadro 500M] + +pci:v000010DEd00000DFA* + ID_PRODUCT_FROM_DATABASE=GF108GLM [Quadro 1000M] + +pci:v000010DEd00000E08* + ID_PRODUCT_FROM_DATABASE=GF119 HDMI Audio Controller + +pci:v000010DEd00000E09* + ID_PRODUCT_FROM_DATABASE=GF110 High Definition Audio Controller + +pci:v000010DEd00000E0A* + ID_PRODUCT_FROM_DATABASE=GK104 HDMI Audio Controller + +pci:v000010DEd00000E0C* + ID_PRODUCT_FROM_DATABASE=GF114 HDMI Audio Controller + +pci:v000010DEd00000E1B* + ID_PRODUCT_FROM_DATABASE=GK107 HDMI Audio Controller + +pci:v000010DEd00000E1Bsv00001043sd00008428* + ID_PRODUCT_FROM_DATABASE=GTX650-DC-1GD5 + +pci:v000010DEd00000E22* + ID_PRODUCT_FROM_DATABASE=GF104 [GeForce GTX 460] + +pci:v000010DEd00000E22sv00001462sd00002322* + ID_PRODUCT_FROM_DATABASE=N460GTX Cyclone 1GD5/OC + +pci:v000010DEd00000E23* + ID_PRODUCT_FROM_DATABASE=GF104 [GeForce GTX 460 SE] + +pci:v000010DEd00000E24* + ID_PRODUCT_FROM_DATABASE=GF104 [GeForce GTX 460] + +pci:v000010DEd00000E3A* + ID_PRODUCT_FROM_DATABASE=GF104 [Quadro 3000M] + +pci:v000010DEd00000E3B* + ID_PRODUCT_FROM_DATABASE=GF104 [Quadro 4000M] + +pci:v000010DEd00000F00* + ID_PRODUCT_FROM_DATABASE=GK107 [GeForce GT 630] + +pci:v000010DEd00000F01* + ID_PRODUCT_FROM_DATABASE=GeForce GT 620 + +pci:v000010DEd00000FC0* + ID_PRODUCT_FROM_DATABASE=GK107 [GeForce GT 640] + +pci:v000010DEd00000FC1* + ID_PRODUCT_FROM_DATABASE=GK107 [GeForce GT 640] + +pci:v000010DEd00000FC6* + ID_PRODUCT_FROM_DATABASE=GK107 [GeForce GTX 650] + +pci:v000010DEd00000FC6sv00001043sd00008428* + ID_PRODUCT_FROM_DATABASE=GTX650-DC-1GD5 + +pci:v000010DEd00000FD1* + ID_PRODUCT_FROM_DATABASE=GK107 [GeForce GT 650M] + +pci:v000010DEd00000FD1sv00001043sd00002103* + ID_PRODUCT_FROM_DATABASE=N56VZ + +pci:v000010DEd00000FD2* + ID_PRODUCT_FROM_DATABASE=GK107 [GeForce GT 640M] + +pci:v000010DEd00000FF2* + ID_PRODUCT_FROM_DATABASE=GK107 [VGX K1] + +pci:v000010DEd00000FFA* + ID_PRODUCT_FROM_DATABASE=GK107 [Quadro K600] + +pci:v000010DEd00000FFB* + ID_PRODUCT_FROM_DATABASE=GK107 [Quadro K2000M] + +pci:v000010DEd00000FFC* + ID_PRODUCT_FROM_DATABASE=GK107 [Quadro K1000M] + +pci:v000010DEd00000FFE* + ID_PRODUCT_FROM_DATABASE=GK107 [Quadro K2000] + +pci:v000010DEd00000FFF* + ID_PRODUCT_FROM_DATABASE=GK107 [Quadro 410] + +pci:v000010DEd00001040* + ID_PRODUCT_FROM_DATABASE=GF119 [GeForce GT 520] + +pci:v000010DEd00001042* + ID_PRODUCT_FROM_DATABASE=GF119 [GeForce 510] + +pci:v000010DEd00001048* + ID_PRODUCT_FROM_DATABASE=GF119 [GeForce 605] + +pci:v000010DEd00001049* + ID_PRODUCT_FROM_DATABASE=GF119 [GeForce GT 620] + +pci:v000010DEd0000104A* + ID_PRODUCT_FROM_DATABASE=GF119 [GeForce GT 610] + +pci:v000010DEd00001050* + ID_PRODUCT_FROM_DATABASE=GF119 [GeForce GT 520M] + +pci:v000010DEd00001051* + ID_PRODUCT_FROM_DATABASE=GF119 [GeForce GT 520MX] + +pci:v000010DEd00001055* + ID_PRODUCT_FROM_DATABASE=GF119 [GeForce 410M] + +pci:v000010DEd00001056* + ID_PRODUCT_FROM_DATABASE=GF119 [Quadro NVS 4200M] + +pci:v000010DEd00001057* + ID_PRODUCT_FROM_DATABASE=GF119 [Quadro NVS 4200M] + +pci:v000010DEd0000105A* + ID_PRODUCT_FROM_DATABASE=GF119 [GeForce 610M] + +pci:v000010DEd0000107D* + ID_PRODUCT_FROM_DATABASE=GF119 [Quadro NVS 310] + +pci:v000010DEd00001080* + ID_PRODUCT_FROM_DATABASE=GF110 [GeForce GTX 580] + +pci:v000010DEd00001081* + ID_PRODUCT_FROM_DATABASE=GF110 [GeForce GTX 570] + +pci:v000010DEd00001081sv000010DEsd0000087E* + ID_PRODUCT_FROM_DATABASE=Leadtek WinFast GTX 570 + +pci:v000010DEd00001082* + ID_PRODUCT_FROM_DATABASE=GF110 [GeForce GTX 560 Ti] + +pci:v000010DEd00001084* + ID_PRODUCT_FROM_DATABASE=GF110 [GeForce GTX 560] + +pci:v000010DEd00001086* + ID_PRODUCT_FROM_DATABASE=GF110 [GeForce GTX 570 HD] + +pci:v000010DEd00001087* + ID_PRODUCT_FROM_DATABASE=GF110 [GeForce GTX 560 Ti 448 Cores] + +pci:v000010DEd00001088* + ID_PRODUCT_FROM_DATABASE=GF110 [GeForce GTX 590] + +pci:v000010DEd00001089* + ID_PRODUCT_FROM_DATABASE=GF110 [GeForce GTX 580] + +pci:v000010DEd0000108B* + ID_PRODUCT_FROM_DATABASE=GF110 [GeForce GTX 580] + +pci:v000010DEd00001091* + ID_PRODUCT_FROM_DATABASE=Tesla M2090 + +pci:v000010DEd00001094* + ID_PRODUCT_FROM_DATABASE=Tesla M2075 Dual-Slot Computing Processor Module + +pci:v000010DEd00001096* + ID_PRODUCT_FROM_DATABASE=Tesla C2075 + +pci:v000010DEd0000109B* + ID_PRODUCT_FROM_DATABASE=GF100GL [Quadro 7000] + +pci:v000010DEd000010C3* + ID_PRODUCT_FROM_DATABASE=GT218 [GeForce 8400 GS] + +pci:v000010DEd000010C3sv000010DEsd0000066D* + ID_PRODUCT_FROM_DATABASE=G98 [GeForce 8400GS] + +pci:v000010DEd000010C5* + ID_PRODUCT_FROM_DATABASE=GT218 [GeForce 405] + +pci:v000010DEd000010D8* + ID_PRODUCT_FROM_DATABASE=GT218 [Quadro NVS 300] + +pci:v000010DEd00001180* + ID_PRODUCT_FROM_DATABASE=GK104 [GeForce GTX 680] + +pci:v000010DEd00001183* + ID_PRODUCT_FROM_DATABASE=GK104 [GeForce GTX 660 Ti] + +pci:v000010DEd00001188* + ID_PRODUCT_FROM_DATABASE=GK104 [GeForce GTX 690] + +pci:v000010DEd00001189* + ID_PRODUCT_FROM_DATABASE=GK104 [GeForce GTX 670] + +pci:v000010DEd000011BA* + ID_PRODUCT_FROM_DATABASE=GK104 [Quadro K5000] + +pci:v000010DEd000011BC* + ID_PRODUCT_FROM_DATABASE=GK104 [Quadro K5000M] + +pci:v000010DEd000011BD* + ID_PRODUCT_FROM_DATABASE=GK104 [Quadro K4000M] + +pci:v000010DEd000011BE* + ID_PRODUCT_FROM_DATABASE=GK104 [Quadro K3000M] + +pci:v000010DEd000011BF* + ID_PRODUCT_FROM_DATABASE=GK104GL [VGX K2] + +pci:v000010DEd000011FA* + ID_PRODUCT_FROM_DATABASE=GK104 [Quadro K4000] + +pci:v000010DEd00001200* + ID_PRODUCT_FROM_DATABASE=GF114 [GeForce GTX 560 Ti] + +pci:v000010DEd00001201* + ID_PRODUCT_FROM_DATABASE=GF114 [GeForce GTX 560] + +pci:v000010DEd00001205* + ID_PRODUCT_FROM_DATABASE=GF114 [GeForce GTX 460 v2] + +pci:v000010DEd00001206* + ID_PRODUCT_FROM_DATABASE=GF114 [GeForce GTX 555] + +pci:v000010DEd00001207* + ID_PRODUCT_FROM_DATABASE=GF114 [GeForce GTX 645] + +pci:v000010DEd00001208* + ID_PRODUCT_FROM_DATABASE=GF114 [GeForce GTX 560 SE] + +pci:v000010DEd00001210* + ID_PRODUCT_FROM_DATABASE=GF114 [GeForce GTX 570M] + +pci:v000010DEd00001241* + ID_PRODUCT_FROM_DATABASE=GF116 [GeForce GT 545] + +pci:v000010DEd00001243* + ID_PRODUCT_FROM_DATABASE=GF116 [GeForce GT 545] + +pci:v000010DEd00001244* + ID_PRODUCT_FROM_DATABASE=GF116 [GeForce GTX 550 Ti] + +pci:v000010DEd00001245* + ID_PRODUCT_FROM_DATABASE=GF116 [GeForce GTS 450] + +pci:v000010DEd00001247* + ID_PRODUCT_FROM_DATABASE=GF116 [GeForce GT 555M] + +pci:v000010DEd00001249* + ID_PRODUCT_FROM_DATABASE=GF116 [GeForce GTS 450] + +pci:v000010DEd0000124B* + ID_PRODUCT_FROM_DATABASE=GF116 [GeForce GT 640] + +pci:v000010DF* + ID_VENDOR_FROM_DATABASE=Emulex Corporation + +pci:v000010DFd00000720* + ID_PRODUCT_FROM_DATABASE=OneConnect NIC (Skyhawk) + +pci:v000010DFd00000722* + ID_PRODUCT_FROM_DATABASE=OneConnect iSCSI Initiator (Skyhawk) + +pci:v000010DFd00000723* + ID_PRODUCT_FROM_DATABASE=OneConnect iSCSI Initiator + Target (Skyhawk) + +pci:v000010DFd00000724* + ID_PRODUCT_FROM_DATABASE=OneConnect FCoE Initiator (Skyhawk) + +pci:v000010DFd00000728* + ID_PRODUCT_FROM_DATABASE=OneConnect NIC (Skyhawk-VF) + +pci:v000010DFd0000072A* + ID_PRODUCT_FROM_DATABASE=OneConnect iSCSI Initiator (Skyhawk-VF) + +pci:v000010DFd0000072B* + ID_PRODUCT_FROM_DATABASE=OneConnect iSCSI Initiator + Target (Skyhawk-VF) + +pci:v000010DFd0000072C* + ID_PRODUCT_FROM_DATABASE=OneConnect FCoE Initiator (Skyhawk-VF) + +pci:v000010DFd00001AE5* + ID_PRODUCT_FROM_DATABASE=LP6000 Fibre Channel Host Adapter + +pci:v000010DFd0000E100* + ID_PRODUCT_FROM_DATABASE=Proteus-X: LightPulse IOV Fibre Channel Host Adapter + +pci:v000010DFd0000E131* + ID_PRODUCT_FROM_DATABASE=LightPulse 8Gb/s PCIe Shared I/O Fibre Channel Adapter + +pci:v000010DFd0000E180* + ID_PRODUCT_FROM_DATABASE=Proteus-X: LightPulse IOV Fibre Channel Host Adapter + +pci:v000010DFd0000E200* + ID_PRODUCT_FROM_DATABASE=Lancer-X: LightPulse Fibre Channel Host Adapter + +pci:v000010DFd0000E208* + ID_PRODUCT_FROM_DATABASE=LightPulse 16Gb Fibre Channel Host Adapter (Lancer-VF) + +pci:v000010DFd0000E220* + ID_PRODUCT_FROM_DATABASE=OneConnect NIC (Lancer) + +pci:v000010DFd0000E240* + ID_PRODUCT_FROM_DATABASE=OneConnect iSCSI Initiator (Lancer) + +pci:v000010DFd0000E260* + ID_PRODUCT_FROM_DATABASE=OneConnect FCoE Initiator (Lancer) + +pci:v000010DFd0000E268* + ID_PRODUCT_FROM_DATABASE=OneConnect 10Gb FCoE Converged Network Adapter (Lancer-VF) + +pci:v000010DFd0000F011* + ID_PRODUCT_FROM_DATABASE=Saturn: LightPulse Fibre Channel Host Adapter + +pci:v000010DFd0000F015* + ID_PRODUCT_FROM_DATABASE=Saturn: LightPulse Fibre Channel Host Adapter + +pci:v000010DFd0000F085* + ID_PRODUCT_FROM_DATABASE=LP850 Fibre Channel Host Adapter + +pci:v000010DFd0000F095* + ID_PRODUCT_FROM_DATABASE=LP952 Fibre Channel Host Adapter + +pci:v000010DFd0000F098* + ID_PRODUCT_FROM_DATABASE=LP982 Fibre Channel Host Adapter + +pci:v000010DFd0000F0A1* + ID_PRODUCT_FROM_DATABASE=Thor LightPulse Fibre Channel Host Adapter + +pci:v000010DFd0000F0A5* + ID_PRODUCT_FROM_DATABASE=Thor LightPulse Fibre Channel Host Adapter + +pci:v000010DFd0000F0B5* + ID_PRODUCT_FROM_DATABASE=Viper LightPulse Fibre Channel Host Adapter + +pci:v000010DFd0000F0D1* + ID_PRODUCT_FROM_DATABASE=Helios LightPulse Fibre Channel Host Adapter + +pci:v000010DFd0000F0D5* + ID_PRODUCT_FROM_DATABASE=Helios LightPulse Fibre Channel Host Adapter + +pci:v000010DFd0000F0E1* + ID_PRODUCT_FROM_DATABASE=Zephyr LightPulse Fibre Channel Host Adapter + +pci:v000010DFd0000F0E5* + ID_PRODUCT_FROM_DATABASE=Zephyr LightPulse Fibre Channel Host Adapter + +pci:v000010DFd0000F0F5* + ID_PRODUCT_FROM_DATABASE=Neptune LightPulse Fibre Channel Host Adapter + +pci:v000010DFd0000F100* + ID_PRODUCT_FROM_DATABASE=Saturn-X: LightPulse Fibre Channel Host Adapter + +pci:v000010DFd0000F111* + ID_PRODUCT_FROM_DATABASE=Saturn-X LightPulse Fibre Channel Host Adapter + +pci:v000010DFd0000F112* + ID_PRODUCT_FROM_DATABASE=Saturn-X LightPulse Fibre Channel Host Adapter + +pci:v000010DFd0000F180* + ID_PRODUCT_FROM_DATABASE=LPSe12002 EmulexSecure Fibre Channel Adapter + +pci:v000010DFd0000F700* + ID_PRODUCT_FROM_DATABASE=LP7000 Fibre Channel Host Adapter + +pci:v000010DFd0000F701* + ID_PRODUCT_FROM_DATABASE=LP7000 Fibre Channel Host Adapter Alternate ID (JX1:2-3, JX2:1-2) + +pci:v000010DFd0000F800* + ID_PRODUCT_FROM_DATABASE=LP8000 Fibre Channel Host Adapter + +pci:v000010DFd0000F801* + ID_PRODUCT_FROM_DATABASE=LP8000 Fibre Channel Host Adapter Alternate ID (JX1:2-3, JX2:1-2) + +pci:v000010DFd0000F900* + ID_PRODUCT_FROM_DATABASE=LP9000 Fibre Channel Host Adapter + +pci:v000010DFd0000F901* + ID_PRODUCT_FROM_DATABASE=LP9000 Fibre Channel Host Adapter Alternate ID (JX1:2-3, JX2:1-2) + +pci:v000010DFd0000F980* + ID_PRODUCT_FROM_DATABASE=LP9802 Fibre Channel Host Adapter + +pci:v000010DFd0000F981* + ID_PRODUCT_FROM_DATABASE=LP9802 Fibre Channel Host Adapter Alternate ID + +pci:v000010DFd0000F982* + ID_PRODUCT_FROM_DATABASE=LP9802 Fibre Channel Host Adapter Alternate ID + +pci:v000010DFd0000FA00* + ID_PRODUCT_FROM_DATABASE=Thor-X LightPulse Fibre Channel Host Adapter + +pci:v000010DFd0000FB00* + ID_PRODUCT_FROM_DATABASE=Viper LightPulse Fibre Channel Host Adapter + +pci:v000010DFd0000FC00* + ID_PRODUCT_FROM_DATABASE=Thor-X LightPulse Fibre Channel Host Adapter + +pci:v000010DFd0000FC00sv000010DFsd0000FC00* + ID_PRODUCT_FROM_DATABASE=LP10000 LightPulse Fibre Channel Host Adapter + +pci:v000010DFd0000FC10* + ID_PRODUCT_FROM_DATABASE=Helios-X LightPulse Fibre Channel Host Adapter + +pci:v000010DFd0000FC20* + ID_PRODUCT_FROM_DATABASE=Zephyr-X LightPulse Fibre Channel Host Adapter + +pci:v000010DFd0000FC40* + ID_PRODUCT_FROM_DATABASE=Saturn-X: LightPulse Fibre Channel Host Adapter + +pci:v000010DFd0000FC50* + ID_PRODUCT_FROM_DATABASE=Proteus-X: LightPulse IOV Fibre Channel Host Adapter + +pci:v000010DFd0000FD00* + ID_PRODUCT_FROM_DATABASE=Helios-X LightPulse Fibre Channel Host Adapter + +pci:v000010DFd0000FD11* + ID_PRODUCT_FROM_DATABASE=Helios-X LightPulse Fibre Channel Host Adapter + +pci:v000010DFd0000FD12* + ID_PRODUCT_FROM_DATABASE=Helios-X LightPulse Fibre Channel Host Adapter + +pci:v000010DFd0000FE00* + ID_PRODUCT_FROM_DATABASE=Zephyr-X LightPulse Fibre Channel Host Adapter + +pci:v000010DFd0000FE05* + ID_PRODUCT_FROM_DATABASE=Zephyr-X: LightPulse FCoE Adapter + +pci:v000010DFd0000FE11* + ID_PRODUCT_FROM_DATABASE=Zephyr-X LightPulse Fibre Channel Host Adapter + +pci:v000010DFd0000FE12* + ID_PRODUCT_FROM_DATABASE=Zephyr-X LightPulse FCoE Adapter + +pci:v000010DFd0000FF00* + ID_PRODUCT_FROM_DATABASE=Neptune LightPulse Fibre Channel Host Adapter + +pci:v000010E0* + ID_VENDOR_FROM_DATABASE=Integrated Micro Solutions Inc. + +pci:v000010E0d00005026* + ID_PRODUCT_FROM_DATABASE=IMS5026/27/28 + +pci:v000010E0d00005027* + ID_PRODUCT_FROM_DATABASE=IMS5027 + +pci:v000010E0d00005028* + ID_PRODUCT_FROM_DATABASE=IMS5028 + +pci:v000010E0d00008849* + ID_PRODUCT_FROM_DATABASE=IMS8849 + +pci:v000010E0d00008853* + ID_PRODUCT_FROM_DATABASE=IMS8853 + +pci:v000010E0d00009128* + ID_PRODUCT_FROM_DATABASE=IMS9128 [Twin turbo 128] + +pci:v000010E1* + ID_VENDOR_FROM_DATABASE=Tekram Technology Co.,Ltd. + +pci:v000010E1d00000391* + ID_PRODUCT_FROM_DATABASE=TRM-S1040 + +pci:v000010E1d00000391sv000010E1sd00000391* + ID_PRODUCT_FROM_DATABASE=DC-315U SCSI-3 Host Adapter + +pci:v000010E1d0000690C* + ID_PRODUCT_FROM_DATABASE=DC-690c + +pci:v000010E1d0000DC29* + ID_PRODUCT_FROM_DATABASE=DC-290 + +pci:v000010E2* + ID_VENDOR_FROM_DATABASE=Aptix Corporation + +pci:v000010E3* + ID_VENDOR_FROM_DATABASE=Tundra Semiconductor Corp. + +pci:v000010E3d00000000* + ID_PRODUCT_FROM_DATABASE=CA91C042 [Universe] + +pci:v000010E3d00000108* + ID_PRODUCT_FROM_DATABASE=Tsi108 Host Bridge for Single PowerPC + +pci:v000010E3d00000148* + ID_PRODUCT_FROM_DATABASE=Tsi148 [Tempe] + +pci:v000010E3d00000148sv00001775sd00001100* + ID_PRODUCT_FROM_DATABASE=VR11 Single Board Computer + +pci:v000010E3d00000860* + ID_PRODUCT_FROM_DATABASE=CA91C860 [QSpan] + +pci:v000010E3d00000862* + ID_PRODUCT_FROM_DATABASE=CA91C862A [QSpan-II] + +pci:v000010E3d00008260* + ID_PRODUCT_FROM_DATABASE=CA91L8200B [Dual PCI PowerSpan II] + +pci:v000010E3d00008261* + ID_PRODUCT_FROM_DATABASE=CA91L8260B [Single PCI PowerSpan II] + +pci:v000010E3d0000A108* + ID_PRODUCT_FROM_DATABASE=Tsi109 Host Bridge for Dual PowerPC + +pci:v000010E4* + ID_VENDOR_FROM_DATABASE=Tandem Computers + +pci:v000010E4d00008029* + ID_PRODUCT_FROM_DATABASE=Realtek 8029 Network Card + +pci:v000010E5* + ID_VENDOR_FROM_DATABASE=Micro Industries Corporation + +pci:v000010E6* + ID_VENDOR_FROM_DATABASE=Gainbery Computer Products Inc. + +pci:v000010E7* + ID_VENDOR_FROM_DATABASE=Vadem + +pci:v000010E8* + ID_VENDOR_FROM_DATABASE=Applied Micro Circuits Corp. + +pci:v000010E8d00001072* + ID_PRODUCT_FROM_DATABASE=INES GPIB-PCI (AMCC5920 based) + +pci:v000010E8d00002011* + ID_PRODUCT_FROM_DATABASE=Q-Motion Video Capture/Edit board + +pci:v000010E8d00004750* + ID_PRODUCT_FROM_DATABASE=S5930 [Matchmaker] + +pci:v000010E8d00005920* + ID_PRODUCT_FROM_DATABASE=S5920 + +pci:v000010E8d00008043* + ID_PRODUCT_FROM_DATABASE=LANai4.x [Myrinet LANai interface chip] + +pci:v000010E8d00008062* + ID_PRODUCT_FROM_DATABASE=S5933_PARASTATION + +pci:v000010E8d0000807D* + ID_PRODUCT_FROM_DATABASE=S5933 [Matchmaker] + +pci:v000010E8d00008088* + ID_PRODUCT_FROM_DATABASE=Kongsberg Spacetec Format Synchronizer + +pci:v000010E8d00008089* + ID_PRODUCT_FROM_DATABASE=Kongsberg Spacetec Serial Output Board + +pci:v000010E8d0000809C* + ID_PRODUCT_FROM_DATABASE=S5933_HEPC3 + +pci:v000010E8d000080B9* + ID_PRODUCT_FROM_DATABASE=Harmonix Hi-Card P8 (4x active ISDN BRI) + +pci:v000010E8d000080D7* + ID_PRODUCT_FROM_DATABASE=PCI-9112 + +pci:v000010E8d000080D8* + ID_PRODUCT_FROM_DATABASE=PCI-7200 + +pci:v000010E8d000080D9* + ID_PRODUCT_FROM_DATABASE=PCI-9118 + +pci:v000010E8d000080DA* + ID_PRODUCT_FROM_DATABASE=PCI-9812 + +pci:v000010E8d000080FC* + ID_PRODUCT_FROM_DATABASE=APCI1500 Signal processing controller (16 dig. inputs + 16 dig. outputs) + +pci:v000010E8d0000811A* + ID_PRODUCT_FROM_DATABASE=PCI-IEEE1355-DS-DE Interface + +pci:v000010E8d0000814C* + ID_PRODUCT_FROM_DATABASE=Fastcom ESCC-PCI (Commtech, Inc.) + +pci:v000010E8d00008170* + ID_PRODUCT_FROM_DATABASE=S5933 [Matchmaker] (Chipset Development Tool) + +pci:v000010E8d000081E6* + ID_PRODUCT_FROM_DATABASE=Multimedia video controller + +pci:v000010E8d0000828D* + ID_PRODUCT_FROM_DATABASE=APCI3001 Signal processing controller (up to 16 analog inputs) + +pci:v000010E8d00008291* + ID_PRODUCT_FROM_DATABASE=Fastcom 232/8-PCI (Commtech, Inc.) + +pci:v000010E8d000082C4* + ID_PRODUCT_FROM_DATABASE=Fastcom 422/4-PCI (Commtech, Inc.) + +pci:v000010E8d000082C5* + ID_PRODUCT_FROM_DATABASE=Fastcom 422/2-PCI (Commtech, Inc.) + +pci:v000010E8d000082C6* + ID_PRODUCT_FROM_DATABASE=Fastcom IG422/1-PCI (Commtech, Inc.) + +pci:v000010E8d000082C7* + ID_PRODUCT_FROM_DATABASE=Fastcom IG232/2-PCI (Commtech, Inc.) + +pci:v000010E8d000082CA* + ID_PRODUCT_FROM_DATABASE=Fastcom 232/4-PCI (Commtech, Inc.) + +pci:v000010E8d000082DB* + ID_PRODUCT_FROM_DATABASE=AJA HDNTV HD SDI Framestore + +pci:v000010E8d000082E2* + ID_PRODUCT_FROM_DATABASE=Fastcom DIO24H-PCI (Commtech, Inc.) + +pci:v000010E8d00008406* + ID_PRODUCT_FROM_DATABASE=PCIcanx/PCIcan CAN interface [Kvaser AB] + +pci:v000010E8d00008407* + ID_PRODUCT_FROM_DATABASE=PCIcan II CAN interface (A1021, PCB-07, PCB-08) [Kvaser AB] + +pci:v000010E8d00008851* + ID_PRODUCT_FROM_DATABASE=S5933 on Innes Corp FM Radio Capture card + +pci:v000010E9* + ID_VENDOR_FROM_DATABASE=Alps Electric Co., Ltd. + +pci:v000010EA* + ID_VENDOR_FROM_DATABASE=Integraphics + +pci:v000010EAd00001680* + ID_PRODUCT_FROM_DATABASE=IGA-1680 + +pci:v000010EAd00001682* + ID_PRODUCT_FROM_DATABASE=IGA-1682 + +pci:v000010EAd00001683* + ID_PRODUCT_FROM_DATABASE=IGA-1683 + +pci:v000010EAd00002000* + ID_PRODUCT_FROM_DATABASE=CyberPro 2000 + +pci:v000010EAd00002010* + ID_PRODUCT_FROM_DATABASE=CyberPro 2000A + +pci:v000010EAd00005000* + ID_PRODUCT_FROM_DATABASE=CyberPro 5000 + +pci:v000010EAd00005050* + ID_PRODUCT_FROM_DATABASE=CyberPro 5050 + +pci:v000010EAd00005202* + ID_PRODUCT_FROM_DATABASE=CyberPro 5202 + +pci:v000010EAd00005252* + ID_PRODUCT_FROM_DATABASE=CyberPro5252 + +pci:v000010EB* + ID_VENDOR_FROM_DATABASE=Artists Graphics + +pci:v000010EBd00000101* + ID_PRODUCT_FROM_DATABASE=3GA + +pci:v000010EBd00008111* + ID_PRODUCT_FROM_DATABASE=Twist3 Frame Grabber + +pci:v000010EC* + ID_VENDOR_FROM_DATABASE=Realtek Semiconductor Co., Ltd. + +pci:v000010ECd00000139* + ID_PRODUCT_FROM_DATABASE=Zonet Zen3200 + +pci:v000010ECd00000260* + ID_PRODUCT_FROM_DATABASE=Realtek 260 High Definition Audio + +pci:v000010ECd00000261* + ID_PRODUCT_FROM_DATABASE=Realtek 261 High Definition Audio + +pci:v000010ECd00000262* + ID_PRODUCT_FROM_DATABASE=Realtek 262 High Definition Audio + +pci:v000010ECd00000269* + ID_PRODUCT_FROM_DATABASE=Realtek ALC269 High Definition Audio (82801G) + +pci:v000010ECd00000280* + ID_PRODUCT_FROM_DATABASE=Realtek 280 High Definition Audio + +pci:v000010ECd00000660* + ID_PRODUCT_FROM_DATABASE=Realtek 660 High Definition Audio + +pci:v000010ECd00000662* + ID_PRODUCT_FROM_DATABASE=Realtek 662 High Definition Audio + +pci:v000010ECd00000861* + ID_PRODUCT_FROM_DATABASE=Realtek 861 High Definition Audio + +pci:v000010ECd00000862* + ID_PRODUCT_FROM_DATABASE=Realtek 862 High Definition Audio + +pci:v000010ECd00000880* + ID_PRODUCT_FROM_DATABASE=Realtek 880 High Definition Audio + +pci:v000010ECd00000883* + ID_PRODUCT_FROM_DATABASE=Realtek 883 High Definition Audio + +pci:v000010ECd00000883sv00001025sd00001605* + ID_PRODUCT_FROM_DATABASE=TravelMate 5600 series + +pci:v000010ECd00000885* + ID_PRODUCT_FROM_DATABASE=Realtek 885 High Definition Audio + +pci:v000010ECd00000888* + ID_PRODUCT_FROM_DATABASE=Realtek 888 High Definition Audio + +pci:v000010ECd00000888sv00001028sd0000020D* + ID_PRODUCT_FROM_DATABASE=Inspiron 530 + +pci:v000010ECd00000892* + ID_PRODUCT_FROM_DATABASE=Realtek 892 High Definition Audio + +pci:v000010ECd00005209* + ID_PRODUCT_FROM_DATABASE=RTS5209 PCI Express Card Reader + +pci:v000010ECd00005229* + ID_PRODUCT_FROM_DATABASE=RTS5229 PCI Express Card Reader + +pci:v000010ECd00005288* + ID_PRODUCT_FROM_DATABASE=Barossa PCI Express Card Reader + +pci:v000010ECd00008029* + ID_PRODUCT_FROM_DATABASE=RTL-8029(AS) + +pci:v000010ECd00008029sv000010B8sd00002011* + ID_PRODUCT_FROM_DATABASE=EZ-Card (SMC1208) + +pci:v000010ECd00008029sv000010ECsd00008029* + ID_PRODUCT_FROM_DATABASE=RTL-8029(AS) + +pci:v000010ECd00008029sv00001113sd00001208* + ID_PRODUCT_FROM_DATABASE=EN1208 + +pci:v000010ECd00008029sv00001186sd00000300* + ID_PRODUCT_FROM_DATABASE=DE-528 + +pci:v000010ECd00008029sv00001259sd00002400* + ID_PRODUCT_FROM_DATABASE=AT-2400 + +pci:v000010ECd00008029sv00001AF4sd00001100* + ID_PRODUCT_FROM_DATABASE=Qemu virtual machine + +pci:v000010ECd00008129* + ID_PRODUCT_FROM_DATABASE=RTL-8129 + +pci:v000010ECd00008129sv000010ECsd00008129* + ID_PRODUCT_FROM_DATABASE=RT8129 Fast Ethernet Adapter + +pci:v000010ECd00008129sv000011ECsd00008129* + ID_PRODUCT_FROM_DATABASE=RT8129 Fast Ethernet Adapter + +pci:v000010ECd00008136* + ID_PRODUCT_FROM_DATABASE=RTL8101E/RTL8102E PCI Express Fast Ethernet controller + +pci:v000010ECd00008136sv0000103Csd00002AB1* + ID_PRODUCT_FROM_DATABASE=Pavillion p6774 + +pci:v000010ECd00008136sv0000103Csd000030CC* + ID_PRODUCT_FROM_DATABASE=Pavilion dv6700 + +pci:v000010ECd00008136sv00001179sd0000FF64* + ID_PRODUCT_FROM_DATABASE=RTL8102E PCI-E Fast Ethernet NIC + +pci:v000010ECd00008138* + ID_PRODUCT_FROM_DATABASE=RT8139 (B/C) Cardbus Fast Ethernet Adapter + +pci:v000010ECd00008138sv000010ECsd00008138* + ID_PRODUCT_FROM_DATABASE=RT8139 (B/C) Fast Ethernet Adapter + +pci:v000010ECd00008139* + ID_PRODUCT_FROM_DATABASE=RTL-8139/8139C/8139C+ + +pci:v000010ECd00008139sv00000357sd0000000A* + ID_PRODUCT_FROM_DATABASE=TTP-Monitoring Card V2.0 + +pci:v000010ECd00008139sv00001025sd0000005A* + ID_PRODUCT_FROM_DATABASE=TravelMate 290 + +pci:v000010ECd00008139sv00001025sd00008920* + ID_PRODUCT_FROM_DATABASE=ALN-325 + +pci:v000010ECd00008139sv00001025sd00008921* + ID_PRODUCT_FROM_DATABASE=ALN-325 + +pci:v000010ECd00008139sv0000103Csd0000006A* + ID_PRODUCT_FROM_DATABASE=NX9500 + +pci:v000010ECd00008139sv0000103Csd00002A20* + ID_PRODUCT_FROM_DATABASE=Pavilion t3030.de Desktop PC + +pci:v000010ECd00008139sv0000103Csd000030D9* + ID_PRODUCT_FROM_DATABASE=Presario C700 + +pci:v000010ECd00008139sv00001043sd00001045* + ID_PRODUCT_FROM_DATABASE=L8400B or L3C/S notebook + +pci:v000010ECd00008139sv00001043sd00008109* + ID_PRODUCT_FROM_DATABASE=P5P800-MX Mainboard + +pci:v000010ECd00008139sv00001071sd00008160* + ID_PRODUCT_FROM_DATABASE=MIM2000 + +pci:v000010ECd00008139sv000010BDsd00000320* + ID_PRODUCT_FROM_DATABASE=EP-320X-R + +pci:v000010ECd00008139sv000010F7sd00008338* + ID_PRODUCT_FROM_DATABASE=Panasonic CF-Y5 laptop + +pci:v000010ECd00008139sv00001113sd0000EC01* + ID_PRODUCT_FROM_DATABASE=FNC-0107TX + +pci:v000010ECd00008139sv00001186sd00001300* + ID_PRODUCT_FROM_DATABASE=DFE-538TX + +pci:v000010ECd00008139sv00001186sd00001320* + ID_PRODUCT_FROM_DATABASE=SN5200 + +pci:v000010ECd00008139sv00001186sd00008139* + ID_PRODUCT_FROM_DATABASE=DRN-32TX + +pci:v000010ECd00008139sv000011F6sd00008139* + ID_PRODUCT_FROM_DATABASE=FN22-3(A) LinxPRO Ethernet Adapter + +pci:v000010ECd00008139sv00001259sd00002500* + ID_PRODUCT_FROM_DATABASE=AT-2500TX + +pci:v000010ECd00008139sv00001259sd00002503* + ID_PRODUCT_FROM_DATABASE=AT-2500TX/ACPI + +pci:v000010ECd00008139sv00001385sd0000F31D* + ID_PRODUCT_FROM_DATABASE=FA311 v2 + +pci:v000010ECd00008139sv00001395sd00002100* + ID_PRODUCT_FROM_DATABASE=AMB2100 + +pci:v000010ECd00008139sv00001429sd0000D010* + ID_PRODUCT_FROM_DATABASE=ND010/ND012 + +pci:v000010ECd00008139sv00001432sd00009130* + ID_PRODUCT_FROM_DATABASE=EN-9130TX + +pci:v000010ECd00008139sv00001436sd00008139* + ID_PRODUCT_FROM_DATABASE=RT8139 + +pci:v000010ECd00008139sv0000144Dsd0000C00C* + ID_PRODUCT_FROM_DATABASE=P30/P35 notebook + +pci:v000010ECd00008139sv00001458sd0000E000* + ID_PRODUCT_FROM_DATABASE=GA-7VM400M/7VT600 Motherboard + +pci:v000010ECd00008139sv00001462sd00000131* + ID_PRODUCT_FROM_DATABASE=MS-1013 Notebook + +pci:v000010ECd00008139sv00001462sd0000217C* + ID_PRODUCT_FROM_DATABASE=Aspire L250 + +pci:v000010ECd00008139sv00001462sd0000788C* + ID_PRODUCT_FROM_DATABASE=865PE Neo2-V Mainboard + +pci:v000010ECd00008139sv0000146Csd00001439* + ID_PRODUCT_FROM_DATABASE=FE-1439TX + +pci:v000010ECd00008139sv00001489sd00006001* + ID_PRODUCT_FROM_DATABASE=GF100TXRII + +pci:v000010ECd00008139sv00001489sd00006002* + ID_PRODUCT_FROM_DATABASE=GF100TXRA + +pci:v000010ECd00008139sv0000149Csd0000139A* + ID_PRODUCT_FROM_DATABASE=LFE-8139ATX + +pci:v000010ECd00008139sv0000149Csd00008139* + ID_PRODUCT_FROM_DATABASE=LFE-8139TX + +pci:v000010ECd00008139sv000014CBsd00000200* + ID_PRODUCT_FROM_DATABASE=LNR-100 Family 10/100 Base-TX Ethernet + +pci:v000010ECd00008139sv00001565sd00002300* + ID_PRODUCT_FROM_DATABASE=P4TSV Onboard LAN (RTL8100B) + +pci:v000010ECd00008139sv00001631sd00007003* + ID_PRODUCT_FROM_DATABASE=Onboard RTL8111 on GA-8SIML Rev1.0 Mainboard + +pci:v000010ECd00008139sv00001695sd00009001* + ID_PRODUCT_FROM_DATABASE=Onboard RTL8101L 10/100 MBit + +pci:v000010ECd00008139sv000016ECsd000000FF* + ID_PRODUCT_FROM_DATABASE=USR997900A + +pci:v000010ECd00008139sv00001799sd00005000* + ID_PRODUCT_FROM_DATABASE=F5D5000 PCI Card/Desktop Network PCI Card + +pci:v000010ECd00008139sv00001799sd00005010* + ID_PRODUCT_FROM_DATABASE=F5D5010 CardBus Notebook Network Card + +pci:v000010ECd00008139sv0000187Esd00003303* + ID_PRODUCT_FROM_DATABASE=FN312 + +pci:v000010ECd00008139sv00001904sd00008139* + ID_PRODUCT_FROM_DATABASE=RTL8139D Fast Ethernet Adapter + +pci:v000010ECd00008139sv00002646sd00000001* + ID_PRODUCT_FROM_DATABASE=KNE120TX + +pci:v000010ECd00008139sv00008E2Esd00007000* + ID_PRODUCT_FROM_DATABASE=KF-230TX + +pci:v000010ECd00008139sv00008E2Esd00007100* + ID_PRODUCT_FROM_DATABASE=KF-230TX/2 + +pci:v000010ECd00008139sv0000A0A0sd00000007* + ID_PRODUCT_FROM_DATABASE=ALN-325C + +pci:v000010ECd00008167* + ID_PRODUCT_FROM_DATABASE=RTL-8110SC/8169SC Gigabit Ethernet + +pci:v000010ECd00008167sv00001458sd0000E000* + ID_PRODUCT_FROM_DATABASE=GA-MA69G-S3H Motherboard + +pci:v000010ECd00008167sv00001462sd0000235C* + ID_PRODUCT_FROM_DATABASE=P965 Neo MS-7235 mainboard + +pci:v000010ECd00008167sv00001462sd0000236C* + ID_PRODUCT_FROM_DATABASE=945P Neo3-F motherboard + +pci:v000010ECd00008168* + ID_PRODUCT_FROM_DATABASE=RTL8111/8168B PCI Express Gigabit Ethernet controller + +pci:v000010ECd00008168sv00001019sd00008168* + ID_PRODUCT_FROM_DATABASE=MCP73PVT-SM + +pci:v000010ECd00008168sv00001028sd000004B2* + ID_PRODUCT_FROM_DATABASE=Vostro 3350 + +pci:v000010ECd00008168sv00001028sd000004DA* + ID_PRODUCT_FROM_DATABASE=Vostro 3750 + +pci:v000010ECd00008168sv0000103Csd00001611* + ID_PRODUCT_FROM_DATABASE=Pavilion DM1Z-3000 + +pci:v000010ECd00008168sv00001043sd000011F5* + ID_PRODUCT_FROM_DATABASE=A6J-Q008 + +pci:v000010ECd00008168sv00001043sd000016D5* + ID_PRODUCT_FROM_DATABASE=U6V/U31J laptop + +pci:v000010ECd00008168sv00001043sd000081AA* + ID_PRODUCT_FROM_DATABASE=P5B + +pci:v000010ECd00008168sv00001043sd000082C6* + ID_PRODUCT_FROM_DATABASE=M3A78-EH Motherboard + +pci:v000010ECd00008168sv00001043sd000083A3* + ID_PRODUCT_FROM_DATABASE=M4A785TD Motherboard + +pci:v000010ECd00008168sv00001043sd00008432* + ID_PRODUCT_FROM_DATABASE=P8P67 and other motherboards + +pci:v000010ECd00008168sv000010ECsd00008168* + ID_PRODUCT_FROM_DATABASE=TEG-ECTX Gigabit PCI-E Adapter [Trendnet] + +pci:v000010ECd00008168sv00001458sd0000E000* + ID_PRODUCT_FROM_DATABASE=GA-EP45-DS5/GA-EG45M-DS2H Motherboard + +pci:v000010ECd00008168sv00001462sd0000238C* + ID_PRODUCT_FROM_DATABASE=Onboard RTL8111b on MSI P965 Platinum Mainboard + +pci:v000010ECd00008168sv00001462sd0000368C* + ID_PRODUCT_FROM_DATABASE=K9AG Neo2 + +pci:v000010ECd00008168sv00001462sd00007522* + ID_PRODUCT_FROM_DATABASE=X58 Pro-E + +pci:v000010ECd00008168sv00001775sd000011CC* + ID_PRODUCT_FROM_DATABASE=CC11/CL11 + +pci:v000010ECd00008168sv00001849sd00008168* + ID_PRODUCT_FROM_DATABASE=Motherboard (one of many) + +pci:v000010ECd00008168sv00008086sd0000D615* + ID_PRODUCT_FROM_DATABASE=Desktop Board D510MO + +pci:v000010ECd00008169* + ID_PRODUCT_FROM_DATABASE=RTL8169 PCI Gigabit Ethernet Controller + +pci:v000010ECd00008169sv00001025sd00000079* + ID_PRODUCT_FROM_DATABASE=Aspire 5024WLMi + +pci:v000010ECd00008169sv000010BDsd00003202* + ID_PRODUCT_FROM_DATABASE=EP-320G-TX1 32-bit PCI Gigabit Ethernet Adapter + +pci:v000010ECd00008169sv000010ECsd00008169* + ID_PRODUCT_FROM_DATABASE=RTL8169/8110 Family PCI Gigabit Ethernet NIC + +pci:v000010ECd00008169sv00001259sd0000C107* + ID_PRODUCT_FROM_DATABASE=CG-LAPCIGT + +pci:v000010ECd00008169sv00001371sd0000434E* + ID_PRODUCT_FROM_DATABASE=ProG-2000L + +pci:v000010ECd00008169sv00001385sd0000311A* + ID_PRODUCT_FROM_DATABASE=GA311 + +pci:v000010ECd00008169sv00001458sd0000E000* + ID_PRODUCT_FROM_DATABASE=GA-8I915ME-G Mainboard + +pci:v000010ECd00008169sv00001462sd0000030C* + ID_PRODUCT_FROM_DATABASE=K8N Neo-FSR v2.0 mainboard + +pci:v000010ECd00008169sv00001462sd0000065C* + ID_PRODUCT_FROM_DATABASE=Hetis 865GV-E (MS-7065) + +pci:v000010ECd00008169sv00001462sd0000702C* + ID_PRODUCT_FROM_DATABASE=K8T NEO 2 motherboard + +pci:v000010ECd00008169sv00001462sd00007094* + ID_PRODUCT_FROM_DATABASE=K8T Neo2-F V2.0 + +pci:v000010ECd00008169sv000016ECsd0000011F* + ID_PRODUCT_FROM_DATABASE=USR997903 + +pci:v000010ECd00008169sv00001734sd00001091* + ID_PRODUCT_FROM_DATABASE=D2030-A1 + +pci:v000010ECd00008169sv0000A0A0sd00000449* + ID_PRODUCT_FROM_DATABASE=AK86-L motherboard + +pci:v000010ECd00008171* + ID_PRODUCT_FROM_DATABASE=RTL8191SEvA Wireless LAN Controller + +pci:v000010ECd00008172* + ID_PRODUCT_FROM_DATABASE=RTL8191SEvB Wireless LAN Controller + +pci:v000010ECd00008173* + ID_PRODUCT_FROM_DATABASE=RTL8192SE Wireless LAN Controller + +pci:v000010ECd00008174* + ID_PRODUCT_FROM_DATABASE=RTL8192SE Wireless LAN Controller + +pci:v000010ECd00008176* + ID_PRODUCT_FROM_DATABASE=RTL8188CE 802.11b/g/n WiFi Adapter + +pci:v000010ECd00008176sv00001A3Bsd00001139* + ID_PRODUCT_FROM_DATABASE=AW-NE139H Half-size Mini PCIe Card + +pci:v000010ECd00008177* + ID_PRODUCT_FROM_DATABASE=RTL8188CE 802.11b/g/n WiFi Adapter + +pci:v000010ECd00008178* + ID_PRODUCT_FROM_DATABASE=RTL8188CE 802.11b/g/n WiFi Adapter + +pci:v000010ECd00008180* + ID_PRODUCT_FROM_DATABASE=RTL8180L 802.11b MAC + +pci:v000010ECd00008180sv00001385sd00004700* + ID_PRODUCT_FROM_DATABASE=MA521 802.11b Wireless PC Card + +pci:v000010ECd00008180sv00001737sd00000019* + ID_PRODUCT_FROM_DATABASE=WPC11v4 802.11b Wireless-B Notebook Adapter + +pci:v000010ECd00008185* + ID_PRODUCT_FROM_DATABASE=RTL-8185 IEEE 802.11a/b/g Wireless LAN Controller + +pci:v000010ECd00008190* + ID_PRODUCT_FROM_DATABASE=RTL8190 802.11n Wireless LAN + +pci:v000010ECd00008191* + ID_PRODUCT_FROM_DATABASE=RTL8188CE 802.11b/g/n WiFi Adapter + +pci:v000010ECd00008192* + ID_PRODUCT_FROM_DATABASE=RTL8192E/RTL8192SE Wireless LAN Controller + +pci:v000010ECd00008193* + ID_PRODUCT_FROM_DATABASE=RTL8192DE Wireless LAN Controller + +pci:v000010ECd00008197* + ID_PRODUCT_FROM_DATABASE=SmartLAN56 56K Modem + +pci:v000010ECd00008199* + ID_PRODUCT_FROM_DATABASE=RTL8187SE Wireless LAN Controller + +pci:v000010ECd00008199sv00001462sd00006894* + ID_PRODUCT_FROM_DATABASE=MN54G2 / MS-6894 Wireless Mini PCIe Card + +pci:v000010ED* + ID_VENDOR_FROM_DATABASE=Ascii Corporation + +pci:v000010EDd00007310* + ID_PRODUCT_FROM_DATABASE=V7310 + +pci:v000010EE* + ID_VENDOR_FROM_DATABASE=Xilinx Corporation + +pci:v000010EEd00000001* + ID_PRODUCT_FROM_DATABASE=EUROCOM for PCI (ECOMP) + +pci:v000010EEd00000002* + ID_PRODUCT_FROM_DATABASE=Octal E1/T1 for PCI ETP Card + +pci:v000010EEd00000007* + ID_PRODUCT_FROM_DATABASE=Default PCIe endpoint ID + +pci:v000010EEd00000205* + ID_PRODUCT_FROM_DATABASE=Wildcard TE205P + +pci:v000010EEd00000210* + ID_PRODUCT_FROM_DATABASE=Wildcard TE210P + +pci:v000010EEd00000300* + ID_PRODUCT_FROM_DATABASE=Spartan 3 Designs (Xilinx IP) + +pci:v000010EEd00000314* + ID_PRODUCT_FROM_DATABASE=Wildcard TE405P/TE410P (1st Gen) + +pci:v000010EEd00000405* + ID_PRODUCT_FROM_DATABASE=Wildcard TE405P (2nd Gen) + +pci:v000010EEd00000410* + ID_PRODUCT_FROM_DATABASE=Wildcard TE410P (2nd Gen) + +pci:v000010EEd00000600* + ID_PRODUCT_FROM_DATABASE=Xilinx 6 Designs (Xilinx IP) + +pci:v000010EEd00002B00* + ID_PRODUCT_FROM_DATABASE=Zomojo Zcard + +pci:v000010EEd00003FC0* + ID_PRODUCT_FROM_DATABASE=RME Digi96 + +pci:v000010EEd00003FC1* + ID_PRODUCT_FROM_DATABASE=RME Digi96/8 + +pci:v000010EEd00003FC2* + ID_PRODUCT_FROM_DATABASE=RME Digi96/8 Pro + +pci:v000010EEd00003FC3* + ID_PRODUCT_FROM_DATABASE=RME Digi96/8 Pad + +pci:v000010EEd00003FC4* + ID_PRODUCT_FROM_DATABASE=RME Digi9652 (Hammerfall) + +pci:v000010EEd00003FC5* + ID_PRODUCT_FROM_DATABASE=RME Hammerfall DSP + +pci:v000010EEd00003FC6* + ID_PRODUCT_FROM_DATABASE=RME Hammerfall DSP MADI + +pci:v000010EEd00008380* + ID_PRODUCT_FROM_DATABASE=Ellips ProfiXpress Profibus Master + +pci:v000010EEd00008381* + ID_PRODUCT_FROM_DATABASE=Ellips Santos Frame Grabber + +pci:v000010EEd0000D154* + ID_PRODUCT_FROM_DATABASE=Copley Controls CAN card (PCI-CAN-02) + +pci:v000010EEd0000EBF0* + ID_PRODUCT_FROM_DATABASE=SED Systems Modulator/Demodulator + +pci:v000010EEd0000EBF1* + ID_PRODUCT_FROM_DATABASE=SED Systems Audio Interface Card + +pci:v000010EEd0000EBF2* + ID_PRODUCT_FROM_DATABASE=SED Systems Common PCI Interface + +pci:v000010EF* + ID_VENDOR_FROM_DATABASE=Racore Computer Products, Inc. + +pci:v000010EFd00008154* + ID_PRODUCT_FROM_DATABASE=M815x Token Ring Adapter + +pci:v000010F0* + ID_VENDOR_FROM_DATABASE=Peritek Corporation + +pci:v000010F1* + ID_VENDOR_FROM_DATABASE=Tyan Computer + +pci:v000010F1d00002865* + ID_PRODUCT_FROM_DATABASE=Tyan Thunder K8E S2865 + +pci:v000010F1d00005300* + ID_PRODUCT_FROM_DATABASE=Tyan S5380 Mainboard + +pci:v000010F2* + ID_VENDOR_FROM_DATABASE=Achme Computer, Inc. + +pci:v000010F3* + ID_VENDOR_FROM_DATABASE=Alaris, Inc. + +pci:v000010F4* + ID_VENDOR_FROM_DATABASE=S-MOS Systems, Inc. + +pci:v000010F5* + ID_VENDOR_FROM_DATABASE=NKK Corporation + +pci:v000010F5d0000A001* + ID_PRODUCT_FROM_DATABASE=NDR4000 [NR4600 Bridge] + +pci:v000010F6* + ID_VENDOR_FROM_DATABASE=Creative Electronic Systems SA + +pci:v000010F7* + ID_VENDOR_FROM_DATABASE=Matsushita Electric Industrial Co., Ltd. + +pci:v000010F8* + ID_VENDOR_FROM_DATABASE=Altos India Ltd + +pci:v000010F9* + ID_VENDOR_FROM_DATABASE=PC Direct + +pci:v000010FA* + ID_VENDOR_FROM_DATABASE=Truevision + +pci:v000010FAd0000000C* + ID_PRODUCT_FROM_DATABASE=TARGA 1000 + +pci:v000010FB* + ID_VENDOR_FROM_DATABASE=Thesys Gesellschaft fuer Mikroelektronik mbH + +pci:v000010FBd0000186F* + ID_PRODUCT_FROM_DATABASE=TH 6255 + +pci:v000010FC* + ID_VENDOR_FROM_DATABASE=I-O Data Device, Inc. + +pci:v000010FCd00000003* + ID_PRODUCT_FROM_DATABASE=Cardbus IDE Controller + +pci:v000010FCd00000005* + ID_PRODUCT_FROM_DATABASE=Cardbus SCSI CBSC II + +pci:v000010FD* + ID_VENDOR_FROM_DATABASE=Soyo Computer, Inc + +pci:v000010FE* + ID_VENDOR_FROM_DATABASE=Fast Multimedia AG + +pci:v000010FF* + ID_VENDOR_FROM_DATABASE=NCube + +pci:v00001100* + ID_VENDOR_FROM_DATABASE=Jazz Multimedia + +pci:v00001101* + ID_VENDOR_FROM_DATABASE=Initio Corporation + +pci:v00001101d00000002* + ID_PRODUCT_FROM_DATABASE=INI-920 Ultra SCSI Adapter + +pci:v00001101d00001060* + ID_PRODUCT_FROM_DATABASE=INI-A100U2W + +pci:v00001101d00001622* + ID_PRODUCT_FROM_DATABASE=INI-1623 PCI SATA-II Controller + +pci:v00001101d00009100* + ID_PRODUCT_FROM_DATABASE=INI-9100/9100W + +pci:v00001101d00009400* + ID_PRODUCT_FROM_DATABASE=INI-940 Fast Wide SCSI Adapter + +pci:v00001101d00009401* + ID_PRODUCT_FROM_DATABASE=INI-935 Fast Wide SCSI Adapter + +pci:v00001101d00009500* + ID_PRODUCT_FROM_DATABASE=INI-950 SCSI Adapter + +pci:v00001101d00009502* + ID_PRODUCT_FROM_DATABASE=INI-950P Ultra Wide SCSI Adapter + +pci:v00001102* + ID_VENDOR_FROM_DATABASE=Creative Labs + +pci:v00001102d00000002* + ID_PRODUCT_FROM_DATABASE=SB Live! EMU10k1 + +pci:v00001102d00000002sv0000100Asd00001102* + ID_PRODUCT_FROM_DATABASE=SB Live! 5.1 Digital OEM SB0220 EMU10K1-JFF + +pci:v00001102d00000002sv00001102sd00000020* + ID_PRODUCT_FROM_DATABASE=CT4850 SBLive! Value + +pci:v00001102d00000002sv00001102sd00000021* + ID_PRODUCT_FROM_DATABASE=CT4620 SBLive! + +pci:v00001102d00000002sv00001102sd0000002F* + ID_PRODUCT_FROM_DATABASE=SBLive! mainboard implementation + +pci:v00001102d00000002sv00001102sd0000100A* + ID_PRODUCT_FROM_DATABASE=SB Live! 5.1 Digital OEM [SB0220] + +pci:v00001102d00000002sv00001102sd00004001* + ID_PRODUCT_FROM_DATABASE=E-mu APS + +pci:v00001102d00000002sv00001102sd00008022* + ID_PRODUCT_FROM_DATABASE=CT4780 SBLive! Value + +pci:v00001102d00000002sv00001102sd00008023* + ID_PRODUCT_FROM_DATABASE=CT4790 SoundBlaster PCI512 + +pci:v00001102d00000002sv00001102sd00008024* + ID_PRODUCT_FROM_DATABASE=CT4760 SBLive! + +pci:v00001102d00000002sv00001102sd00008025* + ID_PRODUCT_FROM_DATABASE=SBLive! Mainboard Implementation + +pci:v00001102d00000002sv00001102sd00008026* + ID_PRODUCT_FROM_DATABASE=CT4830 SBLive! Value + +pci:v00001102d00000002sv00001102sd00008027* + ID_PRODUCT_FROM_DATABASE=CT4832 SBLive! Value + +pci:v00001102d00000002sv00001102sd00008028* + ID_PRODUCT_FROM_DATABASE=CT4760 SBLive! OEM version + +pci:v00001102d00000002sv00001102sd00008031* + ID_PRODUCT_FROM_DATABASE=CT4831 SBLive! Value + +pci:v00001102d00000002sv00001102sd00008040* + ID_PRODUCT_FROM_DATABASE=CT4760 SBLive! + +pci:v00001102d00000002sv00001102sd00008051* + ID_PRODUCT_FROM_DATABASE=CT4850 SBLive! Value + +pci:v00001102d00000002sv00001102sd00008061* + ID_PRODUCT_FROM_DATABASE=SBLive! Player 5.1 + +pci:v00001102d00000002sv00001102sd00008064* + ID_PRODUCT_FROM_DATABASE=SBLive! 5.1 Model SB0100 + +pci:v00001102d00000002sv00001102sd00008065* + ID_PRODUCT_FROM_DATABASE=SBLive! 5.1 Digital Model SB0220 + +pci:v00001102d00000002sv00001102sd00008066* + ID_PRODUCT_FROM_DATABASE=Live! 5.1 Digital [SB0228] + +pci:v00001102d00000002sv00001102sd00008067* + ID_PRODUCT_FROM_DATABASE=SBLive! 5.1 eMicro 28028 + +pci:v00001102d00000004* + ID_PRODUCT_FROM_DATABASE=SB Audigy + +pci:v00001102d00000004sv00001102sd00000051* + ID_PRODUCT_FROM_DATABASE=SB0090 Audigy Player + +pci:v00001102d00000004sv00001102sd00000053* + ID_PRODUCT_FROM_DATABASE=SB0090 Audigy Player/OEM + +pci:v00001102d00000004sv00001102sd00000058* + ID_PRODUCT_FROM_DATABASE=SB0090 Audigy Player/OEM + +pci:v00001102d00000004sv00001102sd00001002* + ID_PRODUCT_FROM_DATABASE=SB Audigy2 Platinum + +pci:v00001102d00000004sv00001102sd00001007* + ID_PRODUCT_FROM_DATABASE=SB0240 Audigy 2 Platinum 6.1 + +pci:v00001102d00000004sv00001102sd00001009* + ID_PRODUCT_FROM_DATABASE=SB Audigy2 OEM HP + +pci:v00001102d00000004sv00001102sd00002002* + ID_PRODUCT_FROM_DATABASE=SB Audigy 2 ZS (SB0350) + +pci:v00001102d00000004sv00001102sd00004001* + ID_PRODUCT_FROM_DATABASE=E-MU 1010 + +pci:v00001102d00000004sv00001102sd00004002* + ID_PRODUCT_FROM_DATABASE=E-MU 0404 + +pci:v00001102d00000005* + ID_PRODUCT_FROM_DATABASE=SB X-Fi + +pci:v00001102d00000005sv00001102sd00000021* + ID_PRODUCT_FROM_DATABASE=X-Fi Platinum + +pci:v00001102d00000005sv00001102sd0000002C* + ID_PRODUCT_FROM_DATABASE=X-Fi XtremeGamer FATAL1TY PRO + +pci:v00001102d00000005sv00001102sd00001003* + ID_PRODUCT_FROM_DATABASE=X-Fi XtremeMusic + +pci:v00001102d00000006* + ID_PRODUCT_FROM_DATABASE=[SB Live! Value] EMU10k1X + +pci:v00001102d00000007* + ID_PRODUCT_FROM_DATABASE=CA0106 Soundblaster + +pci:v00001102d00000007sv00001102sd00000007* + ID_PRODUCT_FROM_DATABASE=SBLive! 24bit + +pci:v00001102d00000007sv00001102sd00001001* + ID_PRODUCT_FROM_DATABASE=SB0310 Audigy LS + +pci:v00001102d00000007sv00001102sd00001002* + ID_PRODUCT_FROM_DATABASE=SB0312 Audigy LS + +pci:v00001102d00000007sv00001102sd00001006* + ID_PRODUCT_FROM_DATABASE=SB0410 SBLive! 24-bit + +pci:v00001102d00000007sv00001102sd0000100A* + ID_PRODUCT_FROM_DATABASE=SB0570 [SB Audigy SE] + +pci:v00001102d00000007sv00001102sd00001012* + ID_PRODUCT_FROM_DATABASE=SB0790 X-Fi XA + +pci:v00001102d00000007sv00001102sd00001013* + ID_PRODUCT_FROM_DATABASE=Soundblaster X-Fi Xtreme Audio + +pci:v00001102d00000007sv00001462sd00001009* + ID_PRODUCT_FROM_DATABASE=K8N Diamond + +pci:v00001102d00000008* + ID_PRODUCT_FROM_DATABASE=SB0400 Audigy2 Value + +pci:v00001102d00000008sv00001102sd00000008* + ID_PRODUCT_FROM_DATABASE=EMU0404 Digital Audio System + +pci:v00001102d00000008sv00001102sd00004004* + ID_PRODUCT_FROM_DATABASE=EMU1010 Digital Audio System [MAEM8960] + +pci:v00001102d00000009* + ID_PRODUCT_FROM_DATABASE=[SB X-Fi Xtreme Audio] CA0110-IBG + +pci:v00001102d00000009sv00001102sd00000010* + ID_PRODUCT_FROM_DATABASE=[SB X-Fi Xtreme Audio] CA0110-IBG + +pci:v00001102d00000009sv00001102sd00000018* + ID_PRODUCT_FROM_DATABASE=SB1040 + +pci:v00001102d0000000B* + ID_PRODUCT_FROM_DATABASE=EMU20k2 [X-Fi Titanium Series] + +pci:v00001102d0000000Bsv00001102sd00000041* + ID_PRODUCT_FROM_DATABASE=SB0880 [SoundBlaster X-Fi Titanium PCI-e] + +pci:v00001102d00004001* + ID_PRODUCT_FROM_DATABASE=SB Audigy FireWire Port + +pci:v00001102d00004001sv00001102sd00000010* + ID_PRODUCT_FROM_DATABASE=SB Audigy FireWire Port + +pci:v00001102d00007002* + ID_PRODUCT_FROM_DATABASE=SB Live! Game Port + +pci:v00001102d00007002sv00001102sd00000020* + ID_PRODUCT_FROM_DATABASE=Gameport Joystick + +pci:v00001102d00007003* + ID_PRODUCT_FROM_DATABASE=SB Audigy Game Port + +pci:v00001102d00007003sv00001102sd00000040* + ID_PRODUCT_FROM_DATABASE=SB Audigy Game Port + +pci:v00001102d00007003sv00001102sd00000060* + ID_PRODUCT_FROM_DATABASE=SB Audigy2 MIDI/Game Port + +pci:v00001102d00007004* + ID_PRODUCT_FROM_DATABASE=[SB Live! Value] Input device controller + +pci:v00001102d00007005* + ID_PRODUCT_FROM_DATABASE=SB Audigy LS Game Port + +pci:v00001102d00007005sv00001102sd00001001* + ID_PRODUCT_FROM_DATABASE=SB0310 Audigy LS MIDI/Game port + +pci:v00001102d00007005sv00001102sd00001002* + ID_PRODUCT_FROM_DATABASE=SB0312 Audigy LS MIDI/Game port + +pci:v00001102d00007006* + ID_PRODUCT_FROM_DATABASE=[SB X-Fi Xtreme Audio] CA0110-IBG PCI to PCIe Bridge + +pci:v00001102d00008938* + ID_PRODUCT_FROM_DATABASE=Ectiva EV1938 + +pci:v00001102d00008938sv00001033sd000080E5* + ID_PRODUCT_FROM_DATABASE=SlimTower-Jim (NEC) + +pci:v00001102d00008938sv00001071sd00007150* + ID_PRODUCT_FROM_DATABASE=Mitac 7150 + +pci:v00001102d00008938sv0000110Asd00005938* + ID_PRODUCT_FROM_DATABASE=Siemens Scenic Mobile 510PIII + +pci:v00001102d00008938sv000013BDsd0000100C* + ID_PRODUCT_FROM_DATABASE=Ceres-C (Sharp, Intel BX) + +pci:v00001102d00008938sv000013BDsd0000100D* + ID_PRODUCT_FROM_DATABASE=Sharp, Intel Banister + +pci:v00001102d00008938sv000013BDsd0000100E* + ID_PRODUCT_FROM_DATABASE=TwinHead P09S/P09S3 (Sharp) + +pci:v00001102d00008938sv000013BDsd0000F6F1* + ID_PRODUCT_FROM_DATABASE=Marlin (Sharp) + +pci:v00001102d00008938sv000014FFsd00000E70* + ID_PRODUCT_FROM_DATABASE=P88TE (TWINHEAD INTERNATIONAL Corp) + +pci:v00001102d00008938sv000014FFsd0000C401* + ID_PRODUCT_FROM_DATABASE=Notebook 9100/9200/2000 (TWINHEAD INTERNATIONAL Corp) + +pci:v00001102d00008938sv0000156Dsd0000B400* + ID_PRODUCT_FROM_DATABASE=G400 - Geo (AlphaTop (Taiwan)) + +pci:v00001102d00008938sv0000156Dsd0000B550* + ID_PRODUCT_FROM_DATABASE=G560 (AlphaTop (Taiwan)) + +pci:v00001102d00008938sv0000156Dsd0000B560* + ID_PRODUCT_FROM_DATABASE=G560 (AlphaTop (Taiwan)) + +pci:v00001102d00008938sv0000156Dsd0000B700* + ID_PRODUCT_FROM_DATABASE=G700/U700 (AlphaTop (Taiwan)) + +pci:v00001102d00008938sv0000156Dsd0000B795* + ID_PRODUCT_FROM_DATABASE=G795 (AlphaTop (Taiwan)) + +pci:v00001102d00008938sv0000156Dsd0000B797* + ID_PRODUCT_FROM_DATABASE=G797 (AlphaTop (Taiwan)) + +pci:v00001103* + ID_VENDOR_FROM_DATABASE=HighPoint Technologies, Inc. + +pci:v00001103d00000003* + ID_PRODUCT_FROM_DATABASE=HPT343/345/346/363 + +pci:v00001103d00000004* + ID_PRODUCT_FROM_DATABASE=HPT366/368/370/370A/372/372N + +pci:v00001103d00000004sv00001103sd00000001* + ID_PRODUCT_FROM_DATABASE=HPT370A + +pci:v00001103d00000004sv00001103sd00000004* + ID_PRODUCT_FROM_DATABASE=HPT366 UDMA66 (r1) / HPT368 UDMA66 (r2) / HPT370 UDMA100 (r3) / HPT370 UDMA100 RAID (r4) + +pci:v00001103d00000004sv00001103sd00000005* + ID_PRODUCT_FROM_DATABASE=HPT370 UDMA100 + +pci:v00001103d00000004sv00001103sd00000006* + ID_PRODUCT_FROM_DATABASE=HPT302/302N + +pci:v00001103d00000005* + ID_PRODUCT_FROM_DATABASE=HPT372A/372N + +pci:v00001103d00000006* + ID_PRODUCT_FROM_DATABASE=HPT302/302N + +pci:v00001103d00000007* + ID_PRODUCT_FROM_DATABASE=HPT371/371N + +pci:v00001103d00000008* + ID_PRODUCT_FROM_DATABASE=HPT374 + +pci:v00001103d00000009* + ID_PRODUCT_FROM_DATABASE=HPT372N + +pci:v00001103d00000620* + ID_PRODUCT_FROM_DATABASE=RocketRAID 620 2 Port SATA-III Controller + +pci:v00001103d00000622* + ID_PRODUCT_FROM_DATABASE=RocketRAID 622 2 Port SATA-III Controller + +pci:v00001103d00000640* + ID_PRODUCT_FROM_DATABASE=RocketRAID 640 4 Port SATA-III Controller + +pci:v00001103d00001720* + ID_PRODUCT_FROM_DATABASE=RocketRAID 1720 (2x SATA II RAID Controller) + +pci:v00001103d00001740* + ID_PRODUCT_FROM_DATABASE=RocketRAID 1740 + +pci:v00001103d00001742* + ID_PRODUCT_FROM_DATABASE=RocketRAID 1742 + +pci:v00001103d00002210* + ID_PRODUCT_FROM_DATABASE=RocketRAID 2210 SATA-II Controller + +pci:v00001103d00002300* + ID_PRODUCT_FROM_DATABASE=RocketRAID 230x 4 Port SATA-II Controller + +pci:v00001103d00002310* + ID_PRODUCT_FROM_DATABASE=RocketRAID 2310 4 Port SATA-II Controller + +pci:v00001103d00002320* + ID_PRODUCT_FROM_DATABASE=RocketRAID 2320 SATA-II Controller + +pci:v00001103d00002322* + ID_PRODUCT_FROM_DATABASE=RocketRAID 2322 SATA-II Controller + +pci:v00001103d00002340* + ID_PRODUCT_FROM_DATABASE=RocketRAID 2340 16 Port SATA-II Controller + +pci:v00001103d00002640* + ID_PRODUCT_FROM_DATABASE=RocketRAID 2640 SAS/SATA Controller + +pci:v00001103d00002722* + ID_PRODUCT_FROM_DATABASE=RocketRAID 2722 + +pci:v00001103d00002740* + ID_PRODUCT_FROM_DATABASE=RocketRAID 2740 + +pci:v00001103d00002744* + ID_PRODUCT_FROM_DATABASE=RocketRaid 2744 + +pci:v00001103d00002782* + ID_PRODUCT_FROM_DATABASE=RocketRAID 2782 + +pci:v00001103d00003120* + ID_PRODUCT_FROM_DATABASE=RocketRAID 3120 + +pci:v00001103d00003220* + ID_PRODUCT_FROM_DATABASE=RocketRAID 3220 + +pci:v00001103d00003320* + ID_PRODUCT_FROM_DATABASE=RocketRAID 3320 + +pci:v00001103d00004310* + ID_PRODUCT_FROM_DATABASE=RocketRaid 4310 + +pci:v00001104* + ID_VENDOR_FROM_DATABASE=RasterOps Corp. + +pci:v00001105* + ID_VENDOR_FROM_DATABASE=Sigma Designs, Inc. + +pci:v00001105d00001105* + ID_PRODUCT_FROM_DATABASE=REALmagic Xcard MPEG 1/2/3/4 DVD Decoder + +pci:v00001105d00008300* + ID_PRODUCT_FROM_DATABASE=REALmagic Hollywood Plus DVD Decoder + +pci:v00001105d00008400* + ID_PRODUCT_FROM_DATABASE=EM840x REALmagic DVD/MPEG-2 Audio/Video Decoder + +pci:v00001105d00008401* + ID_PRODUCT_FROM_DATABASE=EM8401 REALmagic DVD/MPEG-2 A/V Decoder + +pci:v00001105d00008470* + ID_PRODUCT_FROM_DATABASE=EM8470 REALmagic DVD/MPEG-4 A/V Decoder + +pci:v00001105d00008471* + ID_PRODUCT_FROM_DATABASE=EM8471 REALmagic DVD/MPEG-4 A/V Decoder + +pci:v00001105d00008475* + ID_PRODUCT_FROM_DATABASE=EM8475 REALmagic DVD/MPEG-4 A/V Decoder + +pci:v00001105d00008475sv00001105sd00000001* + ID_PRODUCT_FROM_DATABASE=REALmagic X-Card + +pci:v00001105d00008476* + ID_PRODUCT_FROM_DATABASE=EM8476 REALmagic DVD/MPEG-4 A/V Decoder + +pci:v00001105d00008476sv0000127Dsd00000000* + ID_PRODUCT_FROM_DATABASE=CineView II + +pci:v00001105d00008485* + ID_PRODUCT_FROM_DATABASE=EM8485 REALmagic DVD/MPEG-4 A/V Decoder + +pci:v00001105d00008486* + ID_PRODUCT_FROM_DATABASE=EM8486 REALmagic DVD/MPEG-4 A/V Decoder + +pci:v00001105d0000C622* + ID_PRODUCT_FROM_DATABASE=EM8622L MPEG-4.10 (H.264) and SMPTE 421M (VC-1) A/V Decoder + +pci:v00001106* + ID_VENDOR_FROM_DATABASE=VIA Technologies, Inc. + +pci:v00001106d00000102* + ID_PRODUCT_FROM_DATABASE=Embedded VIA Ethernet Controller + +pci:v00001106d00000130* + ID_PRODUCT_FROM_DATABASE=VT6305 1394.A Controller + +pci:v00001106d00000198* + ID_PRODUCT_FROM_DATABASE=P4X600 Host Bridge + +pci:v00001106d00000204* + ID_PRODUCT_FROM_DATABASE=K8M800 Host Bridge + +pci:v00001106d00000208* + ID_PRODUCT_FROM_DATABASE=PT890 Host Bridge + +pci:v00001106d00000238* + ID_PRODUCT_FROM_DATABASE=K8T890 Host Bridge + +pci:v00001106d00000258* + ID_PRODUCT_FROM_DATABASE=PT880 Host Bridge + +pci:v00001106d00000259* + ID_PRODUCT_FROM_DATABASE=CN333/CN400/PM880 Host Bridge + +pci:v00001106d00000269* + ID_PRODUCT_FROM_DATABASE=KT880 Host Bridge + +pci:v00001106d00000282* + ID_PRODUCT_FROM_DATABASE=K8T800Pro Host Bridge + +pci:v00001106d00000282sv00001043sd000080A3* + ID_PRODUCT_FROM_DATABASE=A8V Deluxe + +pci:v00001106d00000290* + ID_PRODUCT_FROM_DATABASE=K8M890 Host Bridge + +pci:v00001106d00000293* + ID_PRODUCT_FROM_DATABASE=PM896 Host Bridge + +pci:v00001106d00000296* + ID_PRODUCT_FROM_DATABASE=P4M800 Host Bridge + +pci:v00001106d00000305* + ID_PRODUCT_FROM_DATABASE=VT8363/8365 [KT133/KM133] + +pci:v00001106d00000305sv00001019sd00000987* + ID_PRODUCT_FROM_DATABASE=K7VZA Mainboard + +pci:v00001106d00000305sv00001043sd00008033* + ID_PRODUCT_FROM_DATABASE=A7V Mainboard + +pci:v00001106d00000305sv00001043sd0000803E* + ID_PRODUCT_FROM_DATABASE=A7V-E Mainboard + +pci:v00001106d00000305sv00001043sd00008042* + ID_PRODUCT_FROM_DATABASE=A7V133/A7V133-C Mainboard + +pci:v00001106d00000305sv0000147Bsd0000A401* + ID_PRODUCT_FROM_DATABASE=KT7/KT7-RAID/KT7A/KT7A-RAID Mainboard + +pci:v00001106d00000308* + ID_PRODUCT_FROM_DATABASE=PT880 Ultra/PT894 Host Bridge + +pci:v00001106d00000308sv00001043sd00008199* + ID_PRODUCT_FROM_DATABASE=P4V800D-X Mainboard + +pci:v00001106d00000314* + ID_PRODUCT_FROM_DATABASE=CN700/VN800/P4M800CE/Pro Host Bridge + +pci:v00001106d00000324* + ID_PRODUCT_FROM_DATABASE=CX700/VX700 Host Bridge + +pci:v00001106d00000327* + ID_PRODUCT_FROM_DATABASE=P4M890 Host Bridge + +pci:v00001106d00000336* + ID_PRODUCT_FROM_DATABASE=K8M890CE Host Bridge + +pci:v00001106d00000340* + ID_PRODUCT_FROM_DATABASE=PT900 Host Bridge + +pci:v00001106d00000351* + ID_PRODUCT_FROM_DATABASE=K8T890CF Host Bridge + +pci:v00001106d00000353* + ID_PRODUCT_FROM_DATABASE=VX800 Host Bridge + +pci:v00001106d00000364* + ID_PRODUCT_FROM_DATABASE=CN896/VN896/P4M900 Host Bridge + +pci:v00001106d00000364sv00001043sd000081CE* + ID_PRODUCT_FROM_DATABASE=P5VD2-VM mothervoard + +pci:v00001106d00000391* + ID_PRODUCT_FROM_DATABASE=VT8371 [KX133] + +pci:v00001106d00000397* + ID_PRODUCT_FROM_DATABASE=VT1708S HD Audio + +pci:v00001106d00000397sv00001043sd0000836C* + ID_PRODUCT_FROM_DATABASE=P7H55 + +pci:v00001106d00000397sv00001043sd000083C7* + ID_PRODUCT_FROM_DATABASE=P5KPL-AM EPU + +pci:v00001106d00000409* + ID_PRODUCT_FROM_DATABASE=VX855/VX875 Host Bridge: Host Control + +pci:v00001106d00000410* + ID_PRODUCT_FROM_DATABASE=VX900 Host Bridge: Host Control + +pci:v00001106d00000415* + ID_PRODUCT_FROM_DATABASE=VT6415 PATA IDE Host Controller + +pci:v00001106d00000415sv00001043sd0000838F* + ID_PRODUCT_FROM_DATABASE=M5A88-V EVO + +pci:v00001106d00000501* + ID_PRODUCT_FROM_DATABASE=VT8501 [Apollo MVP4] + +pci:v00001106d00000505* + ID_PRODUCT_FROM_DATABASE=VT82C505 + +pci:v00001106d00000561* + ID_PRODUCT_FROM_DATABASE=VT82C576MV + +pci:v00001106d00000571* + ID_PRODUCT_FROM_DATABASE=VT82C586A/B/VT82C686/A/B/VT823x/A/C PIPC Bus Master IDE + +pci:v00001106d00000571sv00001019sd00000985* + ID_PRODUCT_FROM_DATABASE=P6VXA Motherboard + +pci:v00001106d00000571sv00001019sd00000A81* + ID_PRODUCT_FROM_DATABASE=L7VTA v1.0 Motherboard (KT400-8235) + +pci:v00001106d00000571sv00001043sd00008052* + ID_PRODUCT_FROM_DATABASE=VT8233A Bus Master ATA100/66/33 IDE + +pci:v00001106d00000571sv00001043sd0000808C* + ID_PRODUCT_FROM_DATABASE=A7V8X / A7V333 motherboard + +pci:v00001106d00000571sv00001043sd000080A1* + ID_PRODUCT_FROM_DATABASE=A7V8X-X motherboard rev. 1.01 + +pci:v00001106d00000571sv00001043sd000080ED* + ID_PRODUCT_FROM_DATABASE=A7V600/K8V-X/A8V Deluxe motherboard + +pci:v00001106d00000571sv00001106sd00000571* + ID_PRODUCT_FROM_DATABASE=VT82C586/B/VT82C686/A/B/VT8233/A/C/VT8235 PIPC Bus Master IDE + +pci:v00001106d00000571sv00001179sd00000001* + ID_PRODUCT_FROM_DATABASE=Magnia Z310 + +pci:v00001106d00000571sv00001297sd0000F641* + ID_PRODUCT_FROM_DATABASE=FX41 motherboard + +pci:v00001106d00000571sv00001458sd00005002* + ID_PRODUCT_FROM_DATABASE=GA-7VAX Mainboard + +pci:v00001106d00000571sv00001462sd00005901* + ID_PRODUCT_FROM_DATABASE=KT6 Delta-FIS2R (MS-6590) + +pci:v00001106d00000571sv00001462sd00007020* + ID_PRODUCT_FROM_DATABASE=K8T NEO 2 motherboard + +pci:v00001106d00000571sv00001462sd00007094* + ID_PRODUCT_FROM_DATABASE=K8T Neo2-F V2.0 + +pci:v00001106d00000571sv00001462sd00007120* + ID_PRODUCT_FROM_DATABASE=KT4AV motherboard + +pci:v00001106d00000571sv00001462sd00007181* + ID_PRODUCT_FROM_DATABASE=K8MM3-V mainboard + +pci:v00001106d00000571sv0000147Bsd00001407* + ID_PRODUCT_FROM_DATABASE=KV8-MAX3 motherboard + +pci:v00001106d00000571sv00001849sd00000571* + ID_PRODUCT_FROM_DATABASE=K7VT2/K7VT6 motherboard + +pci:v00001106d00000576* + ID_PRODUCT_FROM_DATABASE=VT82C576 3V [Apollo Master] + +pci:v00001106d00000581* + ID_PRODUCT_FROM_DATABASE=CX700/VX700 RAID Controller + +pci:v00001106d00000581sv00001106sd00000581* + ID_PRODUCT_FROM_DATABASE=Wrong IDE ID + +pci:v00001106d00000585* + ID_PRODUCT_FROM_DATABASE=VT82C585VP [Apollo VP1/VPX] + +pci:v00001106d00000586* + ID_PRODUCT_FROM_DATABASE=VT82C586/A/B PCI-to-ISA [Apollo VP] + +pci:v00001106d00000586sv00001106sd00000000* + ID_PRODUCT_FROM_DATABASE=MVP3 ISA Bridge + +pci:v00001106d00000591* + ID_PRODUCT_FROM_DATABASE=VT8237A SATA 2-Port Controller + +pci:v00001106d00000595* + ID_PRODUCT_FROM_DATABASE=VT82C595 [Apollo VP2] + +pci:v00001106d00000596* + ID_PRODUCT_FROM_DATABASE=VT82C596 ISA [Mobile South] + +pci:v00001106d00000596sv00001106sd00000000* + ID_PRODUCT_FROM_DATABASE=VT82C596/A/B PCI to ISA Bridge + +pci:v00001106d00000596sv00001458sd00000596* + ID_PRODUCT_FROM_DATABASE=VT82C596/A/B PCI to ISA Bridge + +pci:v00001106d00000597* + ID_PRODUCT_FROM_DATABASE=VT82C597 [Apollo VP3] + +pci:v00001106d00000598* + ID_PRODUCT_FROM_DATABASE=VT82C598 [Apollo MVP3] + +pci:v00001106d00000601* + ID_PRODUCT_FROM_DATABASE=VT8601 [Apollo ProMedia] + +pci:v00001106d00000605* + ID_PRODUCT_FROM_DATABASE=VT8605 [ProSavage PM133] + +pci:v00001106d00000605sv0000103Csd00001254* + ID_PRODUCT_FROM_DATABASE=D9840-60001 [Brio BA410 Motherboard] + +pci:v00001106d00000605sv00001043sd0000802C* + ID_PRODUCT_FROM_DATABASE=CUV4X mainboard + +pci:v00001106d00000680* + ID_PRODUCT_FROM_DATABASE=VT82C680 [Apollo P6] + +pci:v00001106d00000686* + ID_PRODUCT_FROM_DATABASE=VT82C686 [Apollo Super South] + +pci:v00001106d00000686sv00001019sd00000985* + ID_PRODUCT_FROM_DATABASE=P6VXA Motherboard + +pci:v00001106d00000686sv0000103Csd00001256* + ID_PRODUCT_FROM_DATABASE=D9840-60001 [Brio BA410 Motherboard] + +pci:v00001106d00000686sv00001043sd0000802C* + ID_PRODUCT_FROM_DATABASE=CUV4X mainboard + +pci:v00001106d00000686sv00001043sd00008033* + ID_PRODUCT_FROM_DATABASE=A7V Mainboard + +pci:v00001106d00000686sv00001043sd0000803E* + ID_PRODUCT_FROM_DATABASE=A7V-E Mainboard + +pci:v00001106d00000686sv00001043sd00008040* + ID_PRODUCT_FROM_DATABASE=A7M266 Mainboard + +pci:v00001106d00000686sv00001043sd00008042* + ID_PRODUCT_FROM_DATABASE=A7V133/A7V133-C Mainboard + +pci:v00001106d00000686sv00001106sd00000000* + ID_PRODUCT_FROM_DATABASE=VT82C686/A PCI to ISA Bridge + +pci:v00001106d00000686sv00001106sd00000686* + ID_PRODUCT_FROM_DATABASE=VT82C686/A PCI to ISA Bridge + +pci:v00001106d00000686sv00001179sd00000001* + ID_PRODUCT_FROM_DATABASE=Magnia Z310 + +pci:v00001106d00000686sv0000147Bsd0000A702* + ID_PRODUCT_FROM_DATABASE=KG7-Lite Mainboard + +pci:v00001106d00000691* + ID_PRODUCT_FROM_DATABASE=VT82C693A/694x [Apollo PRO133x] + +pci:v00001106d00000691sv00001019sd00000985* + ID_PRODUCT_FROM_DATABASE=P6VXA Motherboard + +pci:v00001106d00000691sv00001179sd00000001* + ID_PRODUCT_FROM_DATABASE=Magnia Z310 + +pci:v00001106d00000691sv00001458sd00000691* + ID_PRODUCT_FROM_DATABASE=VT82C691 Apollo Pro System Controller + +pci:v00001106d00000693* + ID_PRODUCT_FROM_DATABASE=VT82C693 [Apollo Pro Plus] + +pci:v00001106d00000698* + ID_PRODUCT_FROM_DATABASE=VT82C693A [Apollo Pro133 AGP] + +pci:v00001106d00000926* + ID_PRODUCT_FROM_DATABASE=VT82C926 [Amazon] + +pci:v00001106d00001000* + ID_PRODUCT_FROM_DATABASE=VT82C570MV + +pci:v00001106d00001106* + ID_PRODUCT_FROM_DATABASE=VT82C570MV + +pci:v00001106d00001122* + ID_PRODUCT_FROM_DATABASE=VX800/VX820 Chrome 9 HC3 Integrated Graphics + +pci:v00001106d00001204* + ID_PRODUCT_FROM_DATABASE=K8M800 Host Bridge + +pci:v00001106d00001208* + ID_PRODUCT_FROM_DATABASE=PT890 Host Bridge + +pci:v00001106d00001238* + ID_PRODUCT_FROM_DATABASE=K8T890 Host Bridge + +pci:v00001106d00001258* + ID_PRODUCT_FROM_DATABASE=PT880 Host Bridge + +pci:v00001106d00001259* + ID_PRODUCT_FROM_DATABASE=CN333/CN400/PM880 Host Bridge + +pci:v00001106d00001269* + ID_PRODUCT_FROM_DATABASE=KT880 Host Bridge + +pci:v00001106d00001282* + ID_PRODUCT_FROM_DATABASE=K8T800Pro Host Bridge + +pci:v00001106d00001290* + ID_PRODUCT_FROM_DATABASE=K8M890 Host Bridge + +pci:v00001106d00001293* + ID_PRODUCT_FROM_DATABASE=PM896 Host Bridge + +pci:v00001106d00001296* + ID_PRODUCT_FROM_DATABASE=P4M800 Host Bridge + +pci:v00001106d00001308* + ID_PRODUCT_FROM_DATABASE=PT894 Host Bridge + +pci:v00001106d00001314* + ID_PRODUCT_FROM_DATABASE=CN700/VN800/P4M800CE/Pro Host Bridge + +pci:v00001106d00001324* + ID_PRODUCT_FROM_DATABASE=CX700/VX700 Host Bridge + +pci:v00001106d00001327* + ID_PRODUCT_FROM_DATABASE=P4M890 Host Bridge + +pci:v00001106d00001336* + ID_PRODUCT_FROM_DATABASE=K8M890CE Host Bridge + +pci:v00001106d00001340* + ID_PRODUCT_FROM_DATABASE=PT900 Host Bridge + +pci:v00001106d00001351* + ID_PRODUCT_FROM_DATABASE=VT3351 Host Bridge + +pci:v00001106d00001353* + ID_PRODUCT_FROM_DATABASE=VX800/VX820 Error Reporting + +pci:v00001106d00001364* + ID_PRODUCT_FROM_DATABASE=CN896/VN896/P4M900 Host Bridge + +pci:v00001106d00001409* + ID_PRODUCT_FROM_DATABASE=VX855/VX875 Error Reporting + +pci:v00001106d00001410* + ID_PRODUCT_FROM_DATABASE=VX900 Error Reporting + +pci:v00001106d00001571* + ID_PRODUCT_FROM_DATABASE=VT82C576M/VT82C586 + +pci:v00001106d00001595* + ID_PRODUCT_FROM_DATABASE=VT82C595/97 [Apollo VP2/97] + +pci:v00001106d00001732* + ID_PRODUCT_FROM_DATABASE=VT1732 [Envy24 II] PCI Multi-Channel Audio Controller + +pci:v00001106d00002106* + ID_PRODUCT_FROM_DATABASE=VIA Rhine Family Fast Ethernet Adapter (VT6105) + +pci:v00001106d00002204* + ID_PRODUCT_FROM_DATABASE=K8M800 Host Bridge + +pci:v00001106d00002208* + ID_PRODUCT_FROM_DATABASE=PT890 Host Bridge + +pci:v00001106d00002238* + ID_PRODUCT_FROM_DATABASE=K8T890 Host Bridge + +pci:v00001106d00002258* + ID_PRODUCT_FROM_DATABASE=PT880 Host Bridge + +pci:v00001106d00002259* + ID_PRODUCT_FROM_DATABASE=CN333/CN400/PM880 CPU Host Bridge + +pci:v00001106d00002269* + ID_PRODUCT_FROM_DATABASE=KT880 Host Bridge + +pci:v00001106d00002282* + ID_PRODUCT_FROM_DATABASE=K8T800Pro Host Bridge + +pci:v00001106d00002290* + ID_PRODUCT_FROM_DATABASE=K8M890 Host Bridge + +pci:v00001106d00002293* + ID_PRODUCT_FROM_DATABASE=PM896 Host Bridge + +pci:v00001106d00002296* + ID_PRODUCT_FROM_DATABASE=P4M800 Host Bridge + +pci:v00001106d00002308* + ID_PRODUCT_FROM_DATABASE=PT894 Host Bridge + +pci:v00001106d00002314* + ID_PRODUCT_FROM_DATABASE=CN700/VN800/P4M800CE/Pro Host Bridge + +pci:v00001106d00002324* + ID_PRODUCT_FROM_DATABASE=CX700/VX700 Host Bridge + +pci:v00001106d00002327* + ID_PRODUCT_FROM_DATABASE=P4M890 Host Bridge + +pci:v00001106d00002336* + ID_PRODUCT_FROM_DATABASE=K8M890CE Host Bridge + +pci:v00001106d00002340* + ID_PRODUCT_FROM_DATABASE=PT900 Host Bridge + +pci:v00001106d00002351* + ID_PRODUCT_FROM_DATABASE=VT3351 Host Bridge + +pci:v00001106d00002353* + ID_PRODUCT_FROM_DATABASE=VX800/VX820 Host Bus Control + +pci:v00001106d00002364* + ID_PRODUCT_FROM_DATABASE=CN896/VN896/P4M900 Host Bridge + +pci:v00001106d00002409* + ID_PRODUCT_FROM_DATABASE=VX855/VX875 Host Bus Control + +pci:v00001106d00002410* + ID_PRODUCT_FROM_DATABASE=VX900 CPU Bus Controller + +pci:v00001106d0000287A* + ID_PRODUCT_FROM_DATABASE=VT8251 PCI to PCI Bridge + +pci:v00001106d0000287B* + ID_PRODUCT_FROM_DATABASE=VT8251 Host Bridge + +pci:v00001106d0000287C* + ID_PRODUCT_FROM_DATABASE=VT8251 PCIE Root Port + +pci:v00001106d0000287D* + ID_PRODUCT_FROM_DATABASE=VT8251 PCIE Root Port + +pci:v00001106d0000287E* + ID_PRODUCT_FROM_DATABASE=VT8237/8251 Ultra VLINK Controller + +pci:v00001106d00003022* + ID_PRODUCT_FROM_DATABASE=CLE266 + +pci:v00001106d00003038* + ID_PRODUCT_FROM_DATABASE=VT82xxxxx UHCI USB 1.1 Controller + +pci:v00001106d00003038sv00000925sd00001234* + ID_PRODUCT_FROM_DATABASE=VA-502 Mainboard + +pci:v00001106d00003038sv00001019sd00000985* + ID_PRODUCT_FROM_DATABASE=P6VXA Motherboard + +pci:v00001106d00003038sv00001019sd00000A81* + ID_PRODUCT_FROM_DATABASE=L7VTA v1.0 Motherboard (KT400-8235) + +pci:v00001106d00003038sv00001043sd00008080* + ID_PRODUCT_FROM_DATABASE=A7V333 motherboard + +pci:v00001106d00003038sv00001043sd0000808C* + ID_PRODUCT_FROM_DATABASE=VT6202 USB2.0 4 port controller + +pci:v00001106d00003038sv00001043sd000080A1* + ID_PRODUCT_FROM_DATABASE=A7V8X-X motherboard + +pci:v00001106d00003038sv00001043sd000080ED* + ID_PRODUCT_FROM_DATABASE=A7V600/K8V-X/A8V Deluxe motherboard + +pci:v00001106d00003038sv00001179sd00000001* + ID_PRODUCT_FROM_DATABASE=Magnia Z310 + +pci:v00001106d00003038sv00001458sd00005004* + ID_PRODUCT_FROM_DATABASE=GA-7VAX Mainboard + +pci:v00001106d00003038sv00001462sd00005901* + ID_PRODUCT_FROM_DATABASE=KT6 Delta-FIS2R (MS-6590) + +pci:v00001106d00003038sv00001462sd00007020* + ID_PRODUCT_FROM_DATABASE=K8T NEO 2 motherboard + +pci:v00001106d00003038sv00001462sd00007094* + ID_PRODUCT_FROM_DATABASE=K8T Neo2-F V2.0 + +pci:v00001106d00003038sv00001462sd00007120* + ID_PRODUCT_FROM_DATABASE=KT4AV motherboard + +pci:v00001106d00003038sv00001462sd00007181* + ID_PRODUCT_FROM_DATABASE=K8MM3-V mainboard + +pci:v00001106d00003038sv0000147Bsd00001407* + ID_PRODUCT_FROM_DATABASE=KV8-MAX3 motherboard + +pci:v00001106d00003038sv0000182Dsd0000201D* + ID_PRODUCT_FROM_DATABASE=CN-029 USB2.0 4 port PCI Card + +pci:v00001106d00003038sv00001849sd00003038* + ID_PRODUCT_FROM_DATABASE=K7VT6 + +pci:v00001106d00003038sv000019DAsd0000A179* + ID_PRODUCT_FROM_DATABASE=ZBOX nano VD01 + +pci:v00001106d00003040* + ID_PRODUCT_FROM_DATABASE=VT82C586B ACPI + +pci:v00001106d00003043* + ID_PRODUCT_FROM_DATABASE=VT86C100A [Rhine] + +pci:v00001106d00003043sv000010BDsd00000000* + ID_PRODUCT_FROM_DATABASE=VT86C100A Fast Ethernet Adapter + +pci:v00001106d00003043sv00001106sd00000100* + ID_PRODUCT_FROM_DATABASE=VT86C100A Fast Ethernet Adapter + +pci:v00001106d00003043sv00001186sd00001400* + ID_PRODUCT_FROM_DATABASE=DFE-530TX rev A + +pci:v00001106d00003044* + ID_PRODUCT_FROM_DATABASE=VT6306/7/8 [Fire II(M)] IEEE 1394 OHCI Controller + +pci:v00001106d00003044sv00000010sd00000001* + ID_PRODUCT_FROM_DATABASE=IEEE 1394 4port DCST 1394-3+1B + +pci:v00001106d00003044sv00001025sd0000005A* + ID_PRODUCT_FROM_DATABASE=TravelMate 290 + +pci:v00001106d00003044sv0000103Csd00002A20* + ID_PRODUCT_FROM_DATABASE=Pavilion t3030.de Desktop PC + +pci:v00001106d00003044sv0000103Csd00002A3B* + ID_PRODUCT_FROM_DATABASE=Media Center PC m7590n + +pci:v00001106d00003044sv00001043sd0000808A* + ID_PRODUCT_FROM_DATABASE=A8V/A8N/P4P800 series motherboard + +pci:v00001106d00003044sv00001043sd000081FE* + ID_PRODUCT_FROM_DATABASE=M4A series motherboard + +pci:v00001106d00003044sv00001458sd00001000* + ID_PRODUCT_FROM_DATABASE=GA-7VT600-1394 Motherboard + +pci:v00001106d00003044sv00001462sd0000207D* + ID_PRODUCT_FROM_DATABASE=K8NGM2 series motherboard + +pci:v00001106d00003044sv00001462sd0000217D* + ID_PRODUCT_FROM_DATABASE=Aspire L250 + +pci:v00001106d00003044sv00001462sd0000590D* + ID_PRODUCT_FROM_DATABASE=KT6 Delta-FIS2R (MS-6590) + +pci:v00001106d00003044sv00001462sd0000702D* + ID_PRODUCT_FROM_DATABASE=K8T NEO 2 motherboard + +pci:v00001106d00003044sv00001462sd0000971D* + ID_PRODUCT_FROM_DATABASE=MS-6917 + +pci:v00001106d00003050* + ID_PRODUCT_FROM_DATABASE=VT82C596 Power Management + +pci:v00001106d00003051* + ID_PRODUCT_FROM_DATABASE=VT82C596 Power Management + +pci:v00001106d00003053* + ID_PRODUCT_FROM_DATABASE=VT6105M [Rhine-III] + +pci:v00001106d00003057* + ID_PRODUCT_FROM_DATABASE=VT82C686 [Apollo Super ACPI] + +pci:v00001106d00003057sv00001019sd00000985* + ID_PRODUCT_FROM_DATABASE=P6VXA Motherboard + +pci:v00001106d00003057sv00001019sd00000987* + ID_PRODUCT_FROM_DATABASE=K7VZA Motherboard + +pci:v00001106d00003057sv00001043sd00008033* + ID_PRODUCT_FROM_DATABASE=A7V Mainboard + +pci:v00001106d00003057sv00001043sd0000803E* + ID_PRODUCT_FROM_DATABASE=A7V-E Mainboard + +pci:v00001106d00003057sv00001043sd00008040* + ID_PRODUCT_FROM_DATABASE=A7M266 Mainboard + +pci:v00001106d00003057sv00001043sd00008042* + ID_PRODUCT_FROM_DATABASE=A7V133/A7V133-C Mainboard + +pci:v00001106d00003057sv00001179sd00000001* + ID_PRODUCT_FROM_DATABASE=Magnia Z310 + +pci:v00001106d00003058* + ID_PRODUCT_FROM_DATABASE=VT82C686 AC97 Audio Controller + +pci:v00001106d00003058sv00000E11sd00000097* + ID_PRODUCT_FROM_DATABASE=SoundMax Digital Integrated Audio + +pci:v00001106d00003058sv00000E11sd0000B194* + ID_PRODUCT_FROM_DATABASE=Soundmax integrated digital audio + +pci:v00001106d00003058sv00001019sd00000985* + ID_PRODUCT_FROM_DATABASE=P6VXA Motherboard + +pci:v00001106d00003058sv00001019sd00000987* + ID_PRODUCT_FROM_DATABASE=K7VZA Motherboard + +pci:v00001106d00003058sv0000103Csd00001251* + ID_PRODUCT_FROM_DATABASE=D9840-60001 [Brio BA410 Motherboard] + +pci:v00001106d00003058sv00001043sd00001106* + ID_PRODUCT_FROM_DATABASE=A7V133/A7V133-C Mainboard + +pci:v00001106d00003058sv00001106sd00004511* + ID_PRODUCT_FROM_DATABASE=Onboard Audio on EP7KXA + +pci:v00001106d00003058sv00001106sd0000AA03* + ID_PRODUCT_FROM_DATABASE=VT1612A AC'97 Audio Controller + +pci:v00001106d00003058sv000011D4sd00005348* + ID_PRODUCT_FROM_DATABASE=AD1881A audio + +pci:v00001106d00003058sv00001458sd00007600* + ID_PRODUCT_FROM_DATABASE=Onboard Audio + +pci:v00001106d00003058sv00001462sd00003091* + ID_PRODUCT_FROM_DATABASE=MS-6309 Onboard Audio + +pci:v00001106d00003058sv00001462sd00003092* + ID_PRODUCT_FROM_DATABASE=MS-6309 v2.x Mainboard (VIA VT1611A codec) + +pci:v00001106d00003058sv00001462sd00003300* + ID_PRODUCT_FROM_DATABASE=MS-6330 Onboard Audio + +pci:v00001106d00003058sv000015DDsd00007609* + ID_PRODUCT_FROM_DATABASE=Onboard Audio + +pci:v00001106d00003059* + ID_PRODUCT_FROM_DATABASE=VT8233/A/8235/8237 AC97 Audio Controller + +pci:v00001106d00003059sv00001019sd00000A81* + ID_PRODUCT_FROM_DATABASE=L7VTA v1.0 Motherboard (KT400-8235) + +pci:v00001106d00003059sv00001019sd00001877* + ID_PRODUCT_FROM_DATABASE=K8M800-M2 (V2.0) onboard audio + +pci:v00001106d00003059sv00001043sd00008095* + ID_PRODUCT_FROM_DATABASE=A7V8X Motherboard (Realtek ALC650 codec) + +pci:v00001106d00003059sv00001043sd000080A1* + ID_PRODUCT_FROM_DATABASE=A7V8X-X Motherboard + +pci:v00001106d00003059sv00001043sd000080B0* + ID_PRODUCT_FROM_DATABASE=A7V600/K8V-X/K8V Deluxe motherboard (ADI AD1980 codec [SoundMAX]) + +pci:v00001106d00003059sv00001043sd0000810D* + ID_PRODUCT_FROM_DATABASE=Asus P5VD1-X (AD1888 codec [SoundMax]) + +pci:v00001106d00003059sv00001043sd0000812A* + ID_PRODUCT_FROM_DATABASE=A8V Deluxe motherboard (Realtek ALC850 codec) + +pci:v00001106d00003059sv000010ECsd00008168* + ID_PRODUCT_FROM_DATABASE=High Definition Audio + +pci:v00001106d00003059sv00001106sd00003059* + ID_PRODUCT_FROM_DATABASE=L7VMM2 Motherboard + +pci:v00001106d00003059sv00001106sd00004161* + ID_PRODUCT_FROM_DATABASE=K7VT2 motherboard + +pci:v00001106d00003059sv00001106sd00004170* + ID_PRODUCT_FROM_DATABASE=PCPartner P4M800-8237R Motherboard + +pci:v00001106d00003059sv00001106sd00004552* + ID_PRODUCT_FROM_DATABASE=Soyo KT-600 Dragon Plus (Realtek ALC 650) + +pci:v00001106d00003059sv00001297sd0000C160* + ID_PRODUCT_FROM_DATABASE=FX41 motherboard (Realtek ALC650 codec) + +pci:v00001106d00003059sv00001413sd0000147B* + ID_PRODUCT_FROM_DATABASE=KV8 Pro motherboard onboard audio + +pci:v00001106d00003059sv00001458sd0000A002* + ID_PRODUCT_FROM_DATABASE=GA-7VAX Onboard Audio (Realtek ALC650) + +pci:v00001106d00003059sv00001462sd00000080* + ID_PRODUCT_FROM_DATABASE=K8T NEO 2 motherboard + +pci:v00001106d00003059sv00001462sd00003800* + ID_PRODUCT_FROM_DATABASE=KT266 onboard audio + +pci:v00001106d00003059sv00001462sd00005901* + ID_PRODUCT_FROM_DATABASE=KT6 Delta-FIS2R (MS-6590) + +pci:v00001106d00003059sv00001462sd00007181* + ID_PRODUCT_FROM_DATABASE=K8MM3-V mainboard + +pci:v00001106d00003059sv0000147Bsd00001407* + ID_PRODUCT_FROM_DATABASE=KV8-MAX3 motherboard + +pci:v00001106d00003059sv00001695sd0000300C* + ID_PRODUCT_FROM_DATABASE=EP-8KRA2+ Mainboard + +pci:v00001106d00003059sv00001849sd00000850* + ID_PRODUCT_FROM_DATABASE=ASRock 775Dual-880 Pro onboard audio (Realtek ALC850) + +pci:v00001106d00003059sv00001849sd00009739* + ID_PRODUCT_FROM_DATABASE=P4VT8 Mainboard (C-Media CMI9739A codec) + +pci:v00001106d00003059sv00001849sd00009761* + ID_PRODUCT_FROM_DATABASE=K7VT6 motherboard + +pci:v00001106d00003059sv00004005sd00004710* + ID_PRODUCT_FROM_DATABASE=MSI K7T266 Pro2-RU (MSI-6380 v2) onboard audio (Realtek/ALC 200/200P) + +pci:v00001106d00003059sv0000A0A0sd000001B6* + ID_PRODUCT_FROM_DATABASE=AK77-8XN onboard audio + +pci:v00001106d00003059sv0000A0A0sd00000342* + ID_PRODUCT_FROM_DATABASE=AK86-L motherboard + +pci:v00001106d00003065* + ID_PRODUCT_FROM_DATABASE=VT6102 [Rhine-II] + +pci:v00001106d00003065sv00001043sd000080A1* + ID_PRODUCT_FROM_DATABASE=A7V8X-X Motherboard + +pci:v00001106d00003065sv00001043sd000080ED* + ID_PRODUCT_FROM_DATABASE=A7V600-X Motherboard + +pci:v00001106d00003065sv00001106sd00000102* + ID_PRODUCT_FROM_DATABASE=VT6102 [Rhine II] Embeded Ethernet Controller on VT8235 + +pci:v00001106d00003065sv00001186sd00001400* + ID_PRODUCT_FROM_DATABASE=DFE-530TX rev A + +pci:v00001106d00003065sv00001186sd00001401* + ID_PRODUCT_FROM_DATABASE=DFE-530TX rev B + +pci:v00001106d00003065sv000013B9sd00001421* + ID_PRODUCT_FROM_DATABASE=LD-10/100AL PCI Fast Ethernet Adapter (rev.B) + +pci:v00001106d00003065sv00001462sd00007061* + ID_PRODUCT_FROM_DATABASE=MS-7061 + +pci:v00001106d00003065sv00001462sd00007181* + ID_PRODUCT_FROM_DATABASE=K8MM3-V mainboard + +pci:v00001106d00003065sv0000147Bsd00001C09* + ID_PRODUCT_FROM_DATABASE=NV7 Motherboard + +pci:v00001106d00003065sv00001695sd00003005* + ID_PRODUCT_FROM_DATABASE=VT6103 + +pci:v00001106d00003065sv00001695sd0000300C* + ID_PRODUCT_FROM_DATABASE=Realtek ALC655 sound chip + +pci:v00001106d00003065sv00001849sd00003065* + ID_PRODUCT_FROM_DATABASE=K7VT6 motherboard + +pci:v00001106d00003068* + ID_PRODUCT_FROM_DATABASE=AC'97 Modem Controller + +pci:v00001106d00003068sv00001462sd0000309E* + ID_PRODUCT_FROM_DATABASE=MS-6309 Saturn Motherboard + +pci:v00001106d00003074* + ID_PRODUCT_FROM_DATABASE=VT8233 PCI to ISA Bridge + +pci:v00001106d00003074sv00001043sd00008052* + ID_PRODUCT_FROM_DATABASE=VT8233A + +pci:v00001106d00003091* + ID_PRODUCT_FROM_DATABASE=VT8633 [Apollo Pro266] + +pci:v00001106d00003099* + ID_PRODUCT_FROM_DATABASE=VT8366/A/7 [Apollo KT266/A/333] + +pci:v00001106d00003099sv00001043sd00008064* + ID_PRODUCT_FROM_DATABASE=A7V266-E Mainboard + +pci:v00001106d00003099sv00001043sd0000807F* + ID_PRODUCT_FROM_DATABASE=A7V333 Mainboard + +pci:v00001106d00003099sv00001849sd00003099* + ID_PRODUCT_FROM_DATABASE=K7VT2 motherboard + +pci:v00001106d00003101* + ID_PRODUCT_FROM_DATABASE=VT8653 Host Bridge + +pci:v00001106d00003102* + ID_PRODUCT_FROM_DATABASE=VT8662 Host Bridge + +pci:v00001106d00003103* + ID_PRODUCT_FROM_DATABASE=VT8615 Host Bridge + +pci:v00001106d00003104* + ID_PRODUCT_FROM_DATABASE=USB 2.0 + +pci:v00001106d00003104sv00001019sd00000A81* + ID_PRODUCT_FROM_DATABASE=L7VTA v1.0 Motherboard (KT400-8235) + +pci:v00001106d00003104sv00001043sd0000808C* + ID_PRODUCT_FROM_DATABASE=A7V8X motherboard + +pci:v00001106d00003104sv00001043sd000080A1* + ID_PRODUCT_FROM_DATABASE=A7V8X-X motherboard rev 1.01 + +pci:v00001106d00003104sv00001043sd000080ED* + ID_PRODUCT_FROM_DATABASE=A7V600/K8V-X/A8V Deluxe motherboard + +pci:v00001106d00003104sv00001297sd0000F641* + ID_PRODUCT_FROM_DATABASE=FX41 motherboard + +pci:v00001106d00003104sv00001458sd00005004* + ID_PRODUCT_FROM_DATABASE=GA-7VAX Mainboard + +pci:v00001106d00003104sv00001462sd00005901* + ID_PRODUCT_FROM_DATABASE=KT6 Delta-FIS2R (MS-6590) + +pci:v00001106d00003104sv00001462sd00007020* + ID_PRODUCT_FROM_DATABASE=K8T NEO 2 motherboard + +pci:v00001106d00003104sv00001462sd00007094* + ID_PRODUCT_FROM_DATABASE=K8T Neo2-F V2.0 + +pci:v00001106d00003104sv00001462sd00007120* + ID_PRODUCT_FROM_DATABASE=KT4AV motherboard + +pci:v00001106d00003104sv00001462sd00007181* + ID_PRODUCT_FROM_DATABASE=K8MM3-V mainboard + +pci:v00001106d00003104sv0000147Bsd00001407* + ID_PRODUCT_FROM_DATABASE=KV8-MAX3 motherboard + +pci:v00001106d00003104sv0000182Dsd0000201D* + ID_PRODUCT_FROM_DATABASE=CN-029 USB 2.0 4 port PCI Card + +pci:v00001106d00003104sv00001849sd00003104* + ID_PRODUCT_FROM_DATABASE=K7VT6 motherboard + +pci:v00001106d00003104sv000019DAsd0000A179* + ID_PRODUCT_FROM_DATABASE=ZBOX nano VD01 + +pci:v00001106d00003106* + ID_PRODUCT_FROM_DATABASE=VT6105/VT6106S [Rhine-III] + +pci:v00001106d00003106sv00001106sd00000105* + ID_PRODUCT_FROM_DATABASE=VT6106S [Rhine-III] + +pci:v00001106d00003106sv00001186sd00001403* + ID_PRODUCT_FROM_DATABASE=DFE-530TX rev C + +pci:v00001106d00003106sv00001186sd00001406* + ID_PRODUCT_FROM_DATABASE=DFE-530TX+ rev F2 + +pci:v00001106d00003106sv00001186sd00001407* + ID_PRODUCT_FROM_DATABASE=DFE-538TX + +pci:v00001106d00003108* + ID_PRODUCT_FROM_DATABASE=K8M800/K8N800/K8N800A [S3 UniChrome Pro] + +pci:v00001106d00003109* + ID_PRODUCT_FROM_DATABASE=VT8233C PCI to ISA Bridge + +pci:v00001106d00003112* + ID_PRODUCT_FROM_DATABASE=VT8361 [KLE133] Host Bridge + +pci:v00001106d00003113* + ID_PRODUCT_FROM_DATABASE=VPX/VPX2 PCI to PCI Bridge Controller + +pci:v00001106d00003116* + ID_PRODUCT_FROM_DATABASE=VT8375 [KM266/KL266] Host Bridge + +pci:v00001106d00003116sv00001297sd0000F641* + ID_PRODUCT_FROM_DATABASE=FX41 motherboard + +pci:v00001106d00003118* + ID_PRODUCT_FROM_DATABASE=CN400/PM800/PM880/PN800/PN880 [S3 UniChrome Pro] + +pci:v00001106d00003119* + ID_PRODUCT_FROM_DATABASE=VT6120/VT6121/VT6122 Gigabit Ethernet Adapter + +pci:v00001106d00003122* + ID_PRODUCT_FROM_DATABASE=VT8623 [Apollo CLE266] integrated CastleRock graphics + +pci:v00001106d00003123* + ID_PRODUCT_FROM_DATABASE=VT8623 [Apollo CLE266] + +pci:v00001106d00003128* + ID_PRODUCT_FROM_DATABASE=VT8753 [P4X266 AGP] + +pci:v00001106d00003133* + ID_PRODUCT_FROM_DATABASE=VT3133 Host Bridge + +pci:v00001106d00003142* + ID_PRODUCT_FROM_DATABASE=VT6651 WiFi Adapter, 802.11b + +pci:v00001106d00003147* + ID_PRODUCT_FROM_DATABASE=VT8233A ISA Bridge + +pci:v00001106d00003147sv00001043sd0000808C* + ID_PRODUCT_FROM_DATABASE=A7V333 motherboard + +pci:v00001106d00003148* + ID_PRODUCT_FROM_DATABASE=P4M266 Host Bridge + +pci:v00001106d00003149* + ID_PRODUCT_FROM_DATABASE=VIA VT6420 SATA RAID Controller + +pci:v00001106d00003149sv00001043sd000080ED* + ID_PRODUCT_FROM_DATABASE=A7V600/K8V Deluxe/K8V-X/A8V Deluxe motherboard + +pci:v00001106d00003149sv00001458sd0000B003* + ID_PRODUCT_FROM_DATABASE=GA-7VM400AM(F) Motherboard + +pci:v00001106d00003149sv00001462sd00005901* + ID_PRODUCT_FROM_DATABASE=KT6 Delta-FIS2R (MS-6590) + +pci:v00001106d00003149sv00001462sd00007020* + ID_PRODUCT_FROM_DATABASE=K8T Neo 2 Motherboard + +pci:v00001106d00003149sv00001462sd00007094* + ID_PRODUCT_FROM_DATABASE=K8T Neo2-F V2.0 + +pci:v00001106d00003149sv00001462sd00007181* + ID_PRODUCT_FROM_DATABASE=K8MM3-V mainboard + +pci:v00001106d00003149sv0000147Bsd00001407* + ID_PRODUCT_FROM_DATABASE=KV8-MAX3 motherboard + +pci:v00001106d00003149sv0000147Bsd00001408* + ID_PRODUCT_FROM_DATABASE=KV7 + +pci:v00001106d00003149sv00001849sd00003149* + ID_PRODUCT_FROM_DATABASE=K7VT6 motherboard + +pci:v00001106d00003149sv0000A0A0sd000004AD* + ID_PRODUCT_FROM_DATABASE=AK86-L motherboard + +pci:v00001106d00003156* + ID_PRODUCT_FROM_DATABASE=P/KN266 Host Bridge + +pci:v00001106d00003157* + ID_PRODUCT_FROM_DATABASE=CX700/VX700 [S3 UniChrome Pro] + +pci:v00001106d00003164* + ID_PRODUCT_FROM_DATABASE=VT6410 ATA133 RAID controller + +pci:v00001106d00003164sv00001043sd000080F4* + ID_PRODUCT_FROM_DATABASE=P4P800 Mainboard Deluxe ATX + +pci:v00001106d00003164sv00001462sd00007028* + ID_PRODUCT_FROM_DATABASE=915P/G Neo2 + +pci:v00001106d00003168* + ID_PRODUCT_FROM_DATABASE=P4X333/P4X400/PT800 AGP Bridge + +pci:v00001106d00003168sv00001849sd00003168* + ID_PRODUCT_FROM_DATABASE=P4VT8 Mainboard + +pci:v00001106d00003177* + ID_PRODUCT_FROM_DATABASE=VT8235 ISA Bridge + +pci:v00001106d00003177sv00001019sd00000A81* + ID_PRODUCT_FROM_DATABASE=L7VTA v1.0 Motherboard (KT400-8235) + +pci:v00001106d00003177sv00001043sd0000808C* + ID_PRODUCT_FROM_DATABASE=A7V8X motherboard + +pci:v00001106d00003177sv00001043sd000080A1* + ID_PRODUCT_FROM_DATABASE=A7V8X-X motherboard + +pci:v00001106d00003177sv00001106sd00000000* + ID_PRODUCT_FROM_DATABASE=KT4AV motherboard + +pci:v00001106d00003177sv00001297sd0000F641* + ID_PRODUCT_FROM_DATABASE=FX41 motherboard + +pci:v00001106d00003177sv00001458sd00005001* + ID_PRODUCT_FROM_DATABASE=GA-7VAX Mainboard + +pci:v00001106d00003177sv00001849sd00003177* + ID_PRODUCT_FROM_DATABASE=K7VT2 motherboard + +pci:v00001106d00003178* + ID_PRODUCT_FROM_DATABASE=ProSavageDDR P4N333 Host Bridge + +pci:v00001106d00003188* + ID_PRODUCT_FROM_DATABASE=VT8385 [K8T800 AGP] Host Bridge + +pci:v00001106d00003188sv00001043sd000080A3* + ID_PRODUCT_FROM_DATABASE=K8V Deluxe/K8V-X motherboard + +pci:v00001106d00003188sv0000147Bsd00001407* + ID_PRODUCT_FROM_DATABASE=KV8-MAX3 motherboard + +pci:v00001106d00003189* + ID_PRODUCT_FROM_DATABASE=VT8377 [KT400/KT600 AGP] Host Bridge + +pci:v00001106d00003189sv00001043sd0000807F* + ID_PRODUCT_FROM_DATABASE=A7V8X motherboard + +pci:v00001106d00003189sv00001106sd00000000* + ID_PRODUCT_FROM_DATABASE=KT4AV motherboard (KT400A) + +pci:v00001106d00003189sv00001458sd00005000* + ID_PRODUCT_FROM_DATABASE=GA-7VAX Mainboard + +pci:v00001106d00003189sv00001849sd00003189* + ID_PRODUCT_FROM_DATABASE=K7VT6 motherboard + +pci:v00001106d00003204* + ID_PRODUCT_FROM_DATABASE=K8M800 Host Bridge + +pci:v00001106d00003205* + ID_PRODUCT_FROM_DATABASE=VT8378 [KM400/A] Chipset Host Bridge + +pci:v00001106d00003205sv00001458sd00005000* + ID_PRODUCT_FROM_DATABASE=GA-7VM400M Motherboard + +pci:v00001106d00003208* + ID_PRODUCT_FROM_DATABASE=PT890 Host Bridge + +pci:v00001106d00003213* + ID_PRODUCT_FROM_DATABASE=VPX/VPX2 PCI to PCI Bridge Controller + +pci:v00001106d00003218* + ID_PRODUCT_FROM_DATABASE=K8T800M Host Bridge + +pci:v00001106d00003227* + ID_PRODUCT_FROM_DATABASE=VT8237 ISA bridge [KT600/K8T800/K8T890 South] + +pci:v00001106d00003227sv00001043sd000080ED* + ID_PRODUCT_FROM_DATABASE=A7V600/K8V-X/A8V Deluxe motherboard + +pci:v00001106d00003227sv00001106sd00003227* + ID_PRODUCT_FROM_DATABASE=DFI KT600-AL / Soltek SL-B9D-FGR Motherboard + +pci:v00001106d00003227sv00001458sd00005001* + ID_PRODUCT_FROM_DATABASE=GA-7VT600 Motherboard + +pci:v00001106d00003227sv0000147Bsd00001407* + ID_PRODUCT_FROM_DATABASE=KV8-MAX3 motherboard + +pci:v00001106d00003227sv00001849sd00003227* + ID_PRODUCT_FROM_DATABASE=K7VT4 motherboard + +pci:v00001106d00003230* + ID_PRODUCT_FROM_DATABASE=K8M890CE/K8N890CE [Chrome 9] + +pci:v00001106d00003238* + ID_PRODUCT_FROM_DATABASE=K8T890 Host Bridge + +pci:v00001106d00003249* + ID_PRODUCT_FROM_DATABASE=VT6421 IDE/SATA Controller + +pci:v00001106d0000324A* + ID_PRODUCT_FROM_DATABASE=CX700/VX700 PCI to PCI Bridge + +pci:v00001106d0000324B* + ID_PRODUCT_FROM_DATABASE=CX700/VX700 Host Bridge + +pci:v00001106d0000324E* + ID_PRODUCT_FROM_DATABASE=CX700/VX700 Internal Module Bus + +pci:v00001106d00003253* + ID_PRODUCT_FROM_DATABASE=VT6655 WiFi Adapter, 802.11a/b/g + +pci:v00001106d00003258* + ID_PRODUCT_FROM_DATABASE=PT880 Host Bridge + +pci:v00001106d00003259* + ID_PRODUCT_FROM_DATABASE=CN333/CN400/PM880 Host Bridge + +pci:v00001106d00003260* + ID_PRODUCT_FROM_DATABASE=VIA Chrome9 HC IGP + +pci:v00001106d00003269* + ID_PRODUCT_FROM_DATABASE=KT880 Host Bridge + +pci:v00001106d00003282* + ID_PRODUCT_FROM_DATABASE=K8T800Pro Host Bridge + +pci:v00001106d00003287* + ID_PRODUCT_FROM_DATABASE=VT8251 PCI to ISA Bridge + +pci:v00001106d00003288* + ID_PRODUCT_FROM_DATABASE=VT8237A/VT8251 HDA Controller + +pci:v00001106d00003288sv000019DAsd0000A179* + ID_PRODUCT_FROM_DATABASE=ZBOX VD01 + +pci:v00001106d00003290* + ID_PRODUCT_FROM_DATABASE=K8M890 Host Bridge + +pci:v00001106d00003296* + ID_PRODUCT_FROM_DATABASE=P4M800 Host Bridge + +pci:v00001106d00003324* + ID_PRODUCT_FROM_DATABASE=CX700/VX700 Host Bridge + +pci:v00001106d00003327* + ID_PRODUCT_FROM_DATABASE=P4M890 Host Bridge + +pci:v00001106d00003336* + ID_PRODUCT_FROM_DATABASE=K8M890CE Host Bridge + +pci:v00001106d00003337* + ID_PRODUCT_FROM_DATABASE=VT8237A PCI to ISA Bridge + +pci:v00001106d00003340* + ID_PRODUCT_FROM_DATABASE=PT900 Host Bridge + +pci:v00001106d00003343* + ID_PRODUCT_FROM_DATABASE=P4M890 [S3 UniChrome Pro] + +pci:v00001106d00003344* + ID_PRODUCT_FROM_DATABASE=CN700/P4M800 Pro/P4M800 CE/VN800 Graphics [S3 UniChrome Pro] + +pci:v00001106d00003349* + ID_PRODUCT_FROM_DATABASE=VT8251 AHCI/SATA 4-Port Controller + +pci:v00001106d00003351* + ID_PRODUCT_FROM_DATABASE=VT3351 Host Bridge + +pci:v00001106d00003353* + ID_PRODUCT_FROM_DATABASE=VX800 PCI to PCI Bridge + +pci:v00001106d00003364* + ID_PRODUCT_FROM_DATABASE=CN896/VN896/P4M900 Host Bridge + +pci:v00001106d00003371* + ID_PRODUCT_FROM_DATABASE=CN896/VN896/P4M900 [Chrome 9 HC] + +pci:v00001106d00003372* + ID_PRODUCT_FROM_DATABASE=VT8237S PCI to ISA Bridge + +pci:v00001106d0000337A* + ID_PRODUCT_FROM_DATABASE=VT8237A PCI to PCI Bridge + +pci:v00001106d0000337B* + ID_PRODUCT_FROM_DATABASE=VT8237A Host Bridge + +pci:v00001106d00003403* + ID_PRODUCT_FROM_DATABASE=VT6315 Series Firewire Controller + +pci:v00001106d00003403sv00001043sd00008374* + ID_PRODUCT_FROM_DATABASE=M5A88-V EVO + +pci:v00001106d00003403sv00001043sd00008384* + ID_PRODUCT_FROM_DATABASE=P8P67 Deluxe Motherboard + +pci:v00001106d00003409* + ID_PRODUCT_FROM_DATABASE=VX855/VX875 DRAM Bus Control + +pci:v00001106d00003410* + ID_PRODUCT_FROM_DATABASE=VX900 DRAM Bus Control + +pci:v00001106d00003410sv000019DAsd0000A179* + ID_PRODUCT_FROM_DATABASE=ZBOX nano VD01 + +pci:v00001106d00003432* + ID_PRODUCT_FROM_DATABASE=VL80x xHCI USB 3.0 Controller + +pci:v00001106d00004149* + ID_PRODUCT_FROM_DATABASE=VIA VT6420 (ATA133) Controller + +pci:v00001106d00004204* + ID_PRODUCT_FROM_DATABASE=K8M800 Host Bridge + +pci:v00001106d00004208* + ID_PRODUCT_FROM_DATABASE=PT890 Host Bridge + +pci:v00001106d00004238* + ID_PRODUCT_FROM_DATABASE=K8T890 Host Bridge + +pci:v00001106d00004258* + ID_PRODUCT_FROM_DATABASE=PT880 Host Bridge + +pci:v00001106d00004259* + ID_PRODUCT_FROM_DATABASE=CN333/CN400/PM880 Host Bridge + +pci:v00001106d00004269* + ID_PRODUCT_FROM_DATABASE=KT880 Host Bridge + +pci:v00001106d00004282* + ID_PRODUCT_FROM_DATABASE=K8T800Pro Host Bridge + +pci:v00001106d00004290* + ID_PRODUCT_FROM_DATABASE=K8M890 Host Bridge + +pci:v00001106d00004293* + ID_PRODUCT_FROM_DATABASE=PM896 Host Bridge + +pci:v00001106d00004296* + ID_PRODUCT_FROM_DATABASE=P4M800 Host Bridge + +pci:v00001106d00004308* + ID_PRODUCT_FROM_DATABASE=PT894 Host Bridge + +pci:v00001106d00004314* + ID_PRODUCT_FROM_DATABASE=CN700/VN800/P4M800CE/Pro Host Bridge + +pci:v00001106d00004324* + ID_PRODUCT_FROM_DATABASE=CX700/VX700 Host Bridge + +pci:v00001106d00004327* + ID_PRODUCT_FROM_DATABASE=P4M890 Host Bridge + +pci:v00001106d00004336* + ID_PRODUCT_FROM_DATABASE=K8M890CE Host Bridge + +pci:v00001106d00004340* + ID_PRODUCT_FROM_DATABASE=PT900 Host Bridge + +pci:v00001106d00004351* + ID_PRODUCT_FROM_DATABASE=VT3351 Host Bridge + +pci:v00001106d00004353* + ID_PRODUCT_FROM_DATABASE=VX800/VX820 Power Management Control + +pci:v00001106d00004364* + ID_PRODUCT_FROM_DATABASE=CN896/VN896/P4M900 Host Bridge + +pci:v00001106d00004397* + ID_PRODUCT_FROM_DATABASE=VT1708B/1702S/1708S HD audio codec + +pci:v00001106d00004409* + ID_PRODUCT_FROM_DATABASE=VX855/VX875 Power Management Control + +pci:v00001106d00004410* + ID_PRODUCT_FROM_DATABASE=VX900 Power Management and Chip Testing Control + +pci:v00001106d00004410sv000019DAsd0000A179* + ID_PRODUCT_FROM_DATABASE=ZBOX nano VD01 + +pci:v00001106d00004428* + ID_PRODUCT_FROM_DATABASE=VT1718S HD Audio Codec + +pci:v00001106d00005030* + ID_PRODUCT_FROM_DATABASE=VT82C596 ACPI [Apollo PRO] + +pci:v00001106d00005122* + ID_PRODUCT_FROM_DATABASE=VX855/VX875 Chrome 9 HCM Integrated Graphics + +pci:v00001106d00005208* + ID_PRODUCT_FROM_DATABASE=PT890 I/O APIC Interrupt Controller + +pci:v00001106d00005238* + ID_PRODUCT_FROM_DATABASE=K8T890 I/O APIC Interrupt Controller + +pci:v00001106d00005287* + ID_PRODUCT_FROM_DATABASE=VT8251 Serial ATA Controller + +pci:v00001106d00005290* + ID_PRODUCT_FROM_DATABASE=K8M890 I/O APIC Interrupt Controller + +pci:v00001106d00005308* + ID_PRODUCT_FROM_DATABASE=PT894 I/O APIC Interrupt Controller + +pci:v00001106d00005324* + ID_PRODUCT_FROM_DATABASE=VX800 Serial ATA and EIDE Controller + +pci:v00001106d00005327* + ID_PRODUCT_FROM_DATABASE=P4M890 I/O APIC Interrupt Controller + +pci:v00001106d00005336* + ID_PRODUCT_FROM_DATABASE=K8M890CE I/O APIC Interrupt Controller + +pci:v00001106d00005340* + ID_PRODUCT_FROM_DATABASE=PT900 I/O APIC Interrupt Controller + +pci:v00001106d00005351* + ID_PRODUCT_FROM_DATABASE=VT3351 I/O APIC Interrupt Controller + +pci:v00001106d00005353* + ID_PRODUCT_FROM_DATABASE=VX800/VX820 APIC and Central Traffic Control + +pci:v00001106d00005364* + ID_PRODUCT_FROM_DATABASE=CN896/VN896/P4M900 I/O APIC Interrupt Controller + +pci:v00001106d00005372* + ID_PRODUCT_FROM_DATABASE=VT8237/8251 Serial ATA Controller + +pci:v00001106d00005409* + ID_PRODUCT_FROM_DATABASE=VX855/VX875 APIC and Central Traffic Control + +pci:v00001106d00005410* + ID_PRODUCT_FROM_DATABASE=VX900 APIC and Central Traffic Control + +pci:v00001106d00006100* + ID_PRODUCT_FROM_DATABASE=VT85C100A [Rhine II] + +pci:v00001106d00006287* + ID_PRODUCT_FROM_DATABASE=SATA RAID Controller + +pci:v00001106d00006290* + ID_PRODUCT_FROM_DATABASE=K8M890CE Host Bridge + +pci:v00001106d00006327* + ID_PRODUCT_FROM_DATABASE=P4M890 Security Device + +pci:v00001106d00006353* + ID_PRODUCT_FROM_DATABASE=VX800/VX820 Scratch Registers + +pci:v00001106d00006364* + ID_PRODUCT_FROM_DATABASE=CN896/VN896/P4M900 Security Device + +pci:v00001106d00006409* + ID_PRODUCT_FROM_DATABASE=VX855/VX875 Scratch Registers + +pci:v00001106d00006410* + ID_PRODUCT_FROM_DATABASE=VX900 Scratch Registers + +pci:v00001106d00006410sv000019DAsd0000A179* + ID_PRODUCT_FROM_DATABASE=ZBOX nano VD01 + +pci:v00001106d00007122* + ID_PRODUCT_FROM_DATABASE=VX900 Graphics [Chrome9 HD] + +pci:v00001106d00007204* + ID_PRODUCT_FROM_DATABASE=K8M800 Host Bridge + +pci:v00001106d00007205* + ID_PRODUCT_FROM_DATABASE=KM400/KN400/P4M800 [S3 UniChrome] + +pci:v00001106d00007205sv00001458sd0000D000* + ID_PRODUCT_FROM_DATABASE=Gigabyte GA-7VM400(A)M(F) Motherboard + +pci:v00001106d00007205sv00001462sd00007061* + ID_PRODUCT_FROM_DATABASE=MS-7061 + +pci:v00001106d00007208* + ID_PRODUCT_FROM_DATABASE=PT890 Host Bridge + +pci:v00001106d00007238* + ID_PRODUCT_FROM_DATABASE=K8T890 Host Bridge + +pci:v00001106d00007258* + ID_PRODUCT_FROM_DATABASE=PT880 Host Bridge + +pci:v00001106d00007259* + ID_PRODUCT_FROM_DATABASE=CN333/CN400/PM880 Host Bridge + +pci:v00001106d00007269* + ID_PRODUCT_FROM_DATABASE=KT880 Host Bridge + +pci:v00001106d00007282* + ID_PRODUCT_FROM_DATABASE=K8T800Pro Host Bridge + +pci:v00001106d00007290* + ID_PRODUCT_FROM_DATABASE=K8M890 Host Bridge + +pci:v00001106d00007293* + ID_PRODUCT_FROM_DATABASE=PM896 Host Bridge + +pci:v00001106d00007296* + ID_PRODUCT_FROM_DATABASE=P4M800 Host Bridge + +pci:v00001106d00007308* + ID_PRODUCT_FROM_DATABASE=PT894 Host Bridge + +pci:v00001106d00007314* + ID_PRODUCT_FROM_DATABASE=CN700/VN800/P4M800CE/Pro Host Bridge + +pci:v00001106d00007324* + ID_PRODUCT_FROM_DATABASE=CX700/VX700 Host Bridge + +pci:v00001106d00007327* + ID_PRODUCT_FROM_DATABASE=P4M890 Host Bridge + +pci:v00001106d00007336* + ID_PRODUCT_FROM_DATABASE=K8M890CE Host Bridge + +pci:v00001106d00007340* + ID_PRODUCT_FROM_DATABASE=PT900 Host Bridge + +pci:v00001106d00007351* + ID_PRODUCT_FROM_DATABASE=VT3351 Host Bridge + +pci:v00001106d00007353* + ID_PRODUCT_FROM_DATABASE=VX800/VX820 North-South Module Interface Control + +pci:v00001106d00007364* + ID_PRODUCT_FROM_DATABASE=CN896/VN896/P4M900 Host Bridge + +pci:v00001106d00007409* + ID_PRODUCT_FROM_DATABASE=VX855/VX875 North-South Module Interface Control + +pci:v00001106d00007410* + ID_PRODUCT_FROM_DATABASE=VX900 North-South Module Interface Control + +pci:v00001106d00007410sv000019DAsd0000A179* + ID_PRODUCT_FROM_DATABASE=ZBOX nano VD01 + +pci:v00001106d00008231* + ID_PRODUCT_FROM_DATABASE=VT8231 [PCI-to-ISA Bridge] + +pci:v00001106d00008235* + ID_PRODUCT_FROM_DATABASE=VT8235 ACPI + +pci:v00001106d00008305* + ID_PRODUCT_FROM_DATABASE=VT8363/8365 [KT133/KM133 AGP] + +pci:v00001106d00008324* + ID_PRODUCT_FROM_DATABASE=CX700/VX700 PCI to ISA Bridge + +pci:v00001106d00008353* + ID_PRODUCT_FROM_DATABASE=VX800/VX820 Bus Control and Power Management + +pci:v00001106d00008391* + ID_PRODUCT_FROM_DATABASE=VT8371 [KX133 AGP] + +pci:v00001106d00008400* + ID_PRODUCT_FROM_DATABASE=MVP4 + +pci:v00001106d00008409* + ID_PRODUCT_FROM_DATABASE=VX855/VX875 Bus Control and Power Management + +pci:v00001106d00008410* + ID_PRODUCT_FROM_DATABASE=VX900 Bus Control and Power Management + +pci:v00001106d00008410sv000019DAsd0000A179* + ID_PRODUCT_FROM_DATABASE=ZBOX VD01 + +pci:v00001106d00008500* + ID_PRODUCT_FROM_DATABASE=KLE133/PLE133/PLE133T + +pci:v00001106d00008501* + ID_PRODUCT_FROM_DATABASE=VT8501 [Apollo MVP4 AGP] + +pci:v00001106d00008596* + ID_PRODUCT_FROM_DATABASE=VT82C596 [Apollo PRO AGP] + +pci:v00001106d00008597* + ID_PRODUCT_FROM_DATABASE=VT82C597 [Apollo VP3 AGP] + +pci:v00001106d00008598* + ID_PRODUCT_FROM_DATABASE=VT82C598/694x [Apollo MVP3/Pro133x AGP] + +pci:v00001106d00008598sv00001019sd00000985* + ID_PRODUCT_FROM_DATABASE=P6VXA Motherboard + +pci:v00001106d00008601* + ID_PRODUCT_FROM_DATABASE=VT8601 [Apollo ProMedia AGP] + +pci:v00001106d00008605* + ID_PRODUCT_FROM_DATABASE=VT8605 [PM133 AGP] + +pci:v00001106d00008691* + ID_PRODUCT_FROM_DATABASE=VT82C691 [Apollo Pro] + +pci:v00001106d00008693* + ID_PRODUCT_FROM_DATABASE=VT82C693 [Apollo Pro Plus] PCI Bridge + +pci:v00001106d00008A25* + ID_PRODUCT_FROM_DATABASE=PL133/PL133T [S3 ProSavage] + +pci:v00001106d00008A26* + ID_PRODUCT_FROM_DATABASE=KL133/KL133A/KM133/KM133A [S3 ProSavage] + +pci:v00001106d00008D01* + ID_PRODUCT_FROM_DATABASE=PN133/PN133T [S3 Twister] + +pci:v00001106d00008D04* + ID_PRODUCT_FROM_DATABASE=KM266/P4M266/P4M266A/P4N266 [S3 ProSavageDDR] + +pci:v00001106d00009001* + ID_PRODUCT_FROM_DATABASE=VX900 Serial ATA Controller + +pci:v00001106d00009530* + ID_PRODUCT_FROM_DATABASE=Secure Digital Memory Card Controller + +pci:v00001106d000095D0* + ID_PRODUCT_FROM_DATABASE=SDIO Host Controller + +pci:v00001106d0000A208* + ID_PRODUCT_FROM_DATABASE=PT890 PCI to PCI Bridge Controller + +pci:v00001106d0000A238* + ID_PRODUCT_FROM_DATABASE=K8T890 PCI to PCI Bridge Controller + +pci:v00001106d0000A327* + ID_PRODUCT_FROM_DATABASE=P4M890 PCI to PCI Bridge Controller + +pci:v00001106d0000A353* + ID_PRODUCT_FROM_DATABASE=VX8xx South-North Module Interface Control + +pci:v00001106d0000A364* + ID_PRODUCT_FROM_DATABASE=CN896/VN896/P4M900 PCI to PCI Bridge Controller + +pci:v00001106d0000A409* + ID_PRODUCT_FROM_DATABASE=VX855/VX875 USB Device Controller + +pci:v00001106d0000B091* + ID_PRODUCT_FROM_DATABASE=VT8633 [Apollo Pro266 AGP] + +pci:v00001106d0000B099* + ID_PRODUCT_FROM_DATABASE=VT8366/A/7 [Apollo KT266/A/333 AGP] + +pci:v00001106d0000B101* + ID_PRODUCT_FROM_DATABASE=VT8653 AGP Bridge + +pci:v00001106d0000B102* + ID_PRODUCT_FROM_DATABASE=VT8362 AGP Bridge + +pci:v00001106d0000B103* + ID_PRODUCT_FROM_DATABASE=VT8615 AGP Bridge + +pci:v00001106d0000B112* + ID_PRODUCT_FROM_DATABASE=VT8361 [KLE133] AGP Bridge + +pci:v00001106d0000B113* + ID_PRODUCT_FROM_DATABASE=VPX/VPX2 I/O APIC Interrupt Controller + +pci:v00001106d0000B115* + ID_PRODUCT_FROM_DATABASE=VT8363/8365 [KT133/KM133] PCI Bridge + +pci:v00001106d0000B168* + ID_PRODUCT_FROM_DATABASE=VT8235 PCI Bridge + +pci:v00001106d0000B188* + ID_PRODUCT_FROM_DATABASE=VT8237/8251 PCI bridge [K8M890/K8T800/K8T890 South] + +pci:v00001106d0000B188sv0000147Bsd00001407* + ID_PRODUCT_FROM_DATABASE=KV8-MAX3 motherboard + +pci:v00001106d0000B198* + ID_PRODUCT_FROM_DATABASE=VT8237/VX700 PCI Bridge + +pci:v00001106d0000B213* + ID_PRODUCT_FROM_DATABASE=VPX/VPX2 I/O APIC Interrupt Controller + +pci:v00001106d0000B353* + ID_PRODUCT_FROM_DATABASE=VX855/VX875/VX900 PCI to PCI Bridge + +pci:v00001106d0000B999* + ID_PRODUCT_FROM_DATABASE=[K8T890 North / VT8237 South] PCI Bridge + +pci:v00001106d0000C208* + ID_PRODUCT_FROM_DATABASE=PT890 PCI to PCI Bridge Controller + +pci:v00001106d0000C238* + ID_PRODUCT_FROM_DATABASE=K8T890 PCI to PCI Bridge Controller + +pci:v00001106d0000C327* + ID_PRODUCT_FROM_DATABASE=P4M890 PCI to PCI Bridge Controller + +pci:v00001106d0000C340* + ID_PRODUCT_FROM_DATABASE=PT900 PCI to PCI Bridge Controller + +pci:v00001106d0000C353* + ID_PRODUCT_FROM_DATABASE=VX800/VX820 PCI Express Root Port + +pci:v00001106d0000C364* + ID_PRODUCT_FROM_DATABASE=CN896/VN896/P4M900 PCI to PCI Bridge Controller + +pci:v00001106d0000C409* + ID_PRODUCT_FROM_DATABASE=VX855/VX875 EIDE Controller + +pci:v00001106d0000D104* + ID_PRODUCT_FROM_DATABASE=VT8237R USB UDCI Controller + +pci:v00001106d0000D208* + ID_PRODUCT_FROM_DATABASE=PT890 PCI to PCI Bridge Controller + +pci:v00001106d0000D213* + ID_PRODUCT_FROM_DATABASE=VPX/VPX2 PCI to PCI Bridge Controller + +pci:v00001106d0000D238* + ID_PRODUCT_FROM_DATABASE=K8T890 PCI to PCI Bridge Controller + +pci:v00001106d0000D340* + ID_PRODUCT_FROM_DATABASE=PT900 PCI to PCI Bridge Controller + +pci:v00001106d0000E208* + ID_PRODUCT_FROM_DATABASE=PT890 PCI to PCI Bridge Controller + +pci:v00001106d0000E238* + ID_PRODUCT_FROM_DATABASE=K8T890 PCI to PCI Bridge Controller + +pci:v00001106d0000E340* + ID_PRODUCT_FROM_DATABASE=PT900 PCI to PCI Bridge Controller + +pci:v00001106d0000E353* + ID_PRODUCT_FROM_DATABASE=VX800/VX820 PCI Express Root Port + +pci:v00001106d0000E721* + ID_PRODUCT_FROM_DATABASE=VT1708B 8-channel High Definition Audio CODEC + +pci:v00001106d0000F208* + ID_PRODUCT_FROM_DATABASE=PT890 PCI to PCI Bridge Controller + +pci:v00001106d0000F238* + ID_PRODUCT_FROM_DATABASE=K8T890 PCI to PCI Bridge Controller + +pci:v00001106d0000F340* + ID_PRODUCT_FROM_DATABASE=PT900 PCI to PCI Bridge Controller + +pci:v00001106d0000F353* + ID_PRODUCT_FROM_DATABASE=VX800/VX820 PCI Express Root Port + +pci:v00001107* + ID_VENDOR_FROM_DATABASE=Stratus Computers + +pci:v00001107d00000576* + ID_PRODUCT_FROM_DATABASE=VIA VT82C570MV [Apollo] (Wrong vendor ID!) + +pci:v00001108* + ID_VENDOR_FROM_DATABASE=Proteon, Inc. + +pci:v00001108d00000100* + ID_PRODUCT_FROM_DATABASE=p1690plus_AA + +pci:v00001108d00000101* + ID_PRODUCT_FROM_DATABASE=p1690plus_AB + +pci:v00001108d00000105* + ID_PRODUCT_FROM_DATABASE=P1690Plus + +pci:v00001108d00000108* + ID_PRODUCT_FROM_DATABASE=P1690Plus + +pci:v00001108d00000138* + ID_PRODUCT_FROM_DATABASE=P1690Plus + +pci:v00001108d00000139* + ID_PRODUCT_FROM_DATABASE=P1690Plus + +pci:v00001108d0000013C* + ID_PRODUCT_FROM_DATABASE=P1690Plus + +pci:v00001108d0000013D* + ID_PRODUCT_FROM_DATABASE=P1690Plus + +pci:v00001109* + ID_VENDOR_FROM_DATABASE=Cogent Data Technologies, Inc. + +pci:v00001109d00001400* + ID_PRODUCT_FROM_DATABASE=EM110TX [EX110TX] + +pci:v0000110A* + ID_VENDOR_FROM_DATABASE=Siemens Nixdorf AG + +pci:v0000110Ad00000002* + ID_PRODUCT_FROM_DATABASE=Pirahna 2-port + +pci:v0000110Ad00000005* + ID_PRODUCT_FROM_DATABASE=Tulip controller, power management, switch extender + +pci:v0000110Ad00000006* + ID_PRODUCT_FROM_DATABASE=FSC PINC (I/O-APIC) + +pci:v0000110Ad00000015* + ID_PRODUCT_FROM_DATABASE=FSC Multiprocessor Interrupt Controller + +pci:v0000110Ad0000001D* + ID_PRODUCT_FROM_DATABASE=FSC Copernicus Management Controller + +pci:v0000110Ad0000007B* + ID_PRODUCT_FROM_DATABASE=FSC Remote Service Controller, mailbox device + +pci:v0000110Ad0000007C* + ID_PRODUCT_FROM_DATABASE=FSC Remote Service Controller, shared memory device + +pci:v0000110Ad0000007D* + ID_PRODUCT_FROM_DATABASE=FSC Remote Service Controller, SMIC device + +pci:v0000110Ad00002101* + ID_PRODUCT_FROM_DATABASE=HST SAPHIR V Primary PCI (ISDN/PMx) + +pci:v0000110Ad00002102* + ID_PRODUCT_FROM_DATABASE=DSCC4 PEB/PEF 20534 DMA Supported Serial Communication Controller with 4 Channels + +pci:v0000110Ad00002104* + ID_PRODUCT_FROM_DATABASE=Eicon Diva 2.02 compatible passive ISDN card + +pci:v0000110Ad00003141* + ID_PRODUCT_FROM_DATABASE=SIMATIC NET CP 5611 (Profibus Adapter) + +pci:v0000110Ad00003142* + ID_PRODUCT_FROM_DATABASE=SIMATIC NET CP 5613A1 (Profibus Adapter) + +pci:v0000110Ad00004021* + ID_PRODUCT_FROM_DATABASE=SIMATIC NET CP 5512 (Profibus and MPI Cardbus Adapter) + +pci:v0000110Ad00004029* + ID_PRODUCT_FROM_DATABASE=SIMATIC NET CP 5613A2 (Profibus Adapter) + +pci:v0000110Ad00004942* + ID_PRODUCT_FROM_DATABASE=FPGA I-Bus Tracer for MBD + +pci:v0000110Ad00006120* + ID_PRODUCT_FROM_DATABASE=SZB6120 + +pci:v0000110B* + ID_VENDOR_FROM_DATABASE=Chromatic Research Inc. + +pci:v0000110Bd00000001* + ID_PRODUCT_FROM_DATABASE=Mpact Media Processor + +pci:v0000110Bd00000004* + ID_PRODUCT_FROM_DATABASE=Mpact 2 + +pci:v0000110C* + ID_VENDOR_FROM_DATABASE=Mini-Max Technology, Inc. + +pci:v0000110D* + ID_VENDOR_FROM_DATABASE=Znyx Advanced Systems + +pci:v0000110E* + ID_VENDOR_FROM_DATABASE=CPU Technology + +pci:v0000110F* + ID_VENDOR_FROM_DATABASE=Ross Technology + +pci:v00001110* + ID_VENDOR_FROM_DATABASE=Powerhouse Systems + +pci:v00001110d00006037* + ID_PRODUCT_FROM_DATABASE=Firepower Powerized SMP I/O ASIC + +pci:v00001110d00006073* + ID_PRODUCT_FROM_DATABASE=Firepower Powerized SMP I/O ASIC + +pci:v00001111* + ID_VENDOR_FROM_DATABASE=Santa Cruz Operation + +pci:v00001112* + ID_VENDOR_FROM_DATABASE=Osicom Technologies Inc + +pci:v00001112d00002200* + ID_PRODUCT_FROM_DATABASE=FDDI Adapter + +pci:v00001112d00002300* + ID_PRODUCT_FROM_DATABASE=Fast Ethernet Adapter + +pci:v00001112d00002340* + ID_PRODUCT_FROM_DATABASE=4 Port Fast Ethernet Adapter + +pci:v00001112d00002400* + ID_PRODUCT_FROM_DATABASE=ATM Adapter + +pci:v00001113* + ID_VENDOR_FROM_DATABASE=Accton Technology Corporation + +pci:v00001113d00001211* + ID_PRODUCT_FROM_DATABASE=SMC2-1211TX + +pci:v00001113d00001211sv0000103Csd00001207* + ID_PRODUCT_FROM_DATABASE=EN-1207D Fast Ethernet Adapter + +pci:v00001113d00001211sv00001113sd00001211* + ID_PRODUCT_FROM_DATABASE=EN-1207D Fast Ethernet Adapter + +pci:v00001113d00001216* + ID_PRODUCT_FROM_DATABASE=EN-1216 Ethernet Adapter + +pci:v00001113d00001216sv00001113sd00001216* + ID_PRODUCT_FROM_DATABASE=EN1207F series PCI Fast Ethernet Adapter + +pci:v00001113d00001216sv00001113sd00002220* + ID_PRODUCT_FROM_DATABASE=EN2220A Cardbus Fast Ethernet Adapter + +pci:v00001113d00001216sv00001113sd00002242* + ID_PRODUCT_FROM_DATABASE=EN2242 10/100 Ethernet Mini-PCI Card + +pci:v00001113d00001216sv0000111Asd00001020* + ID_PRODUCT_FROM_DATABASE=SpeedStream 1020 PCI 10/100 Ethernet Adaptor [EN-1207F-TX ?] + +pci:v00001113d00001217* + ID_PRODUCT_FROM_DATABASE=EN-1217 Ethernet Adapter + +pci:v00001113d00005105* + ID_PRODUCT_FROM_DATABASE=10Mbps Network card + +pci:v00001113d00009211* + ID_PRODUCT_FROM_DATABASE=EN-1207D Fast Ethernet Adapter + +pci:v00001113d00009211sv00001113sd00009211* + ID_PRODUCT_FROM_DATABASE=EN-1207D Fast Ethernet Adapter + +pci:v00001113d00009511* + ID_PRODUCT_FROM_DATABASE=21x4x DEC-Tulip compatible Fast Ethernet + +pci:v00001113d0000D301* + ID_PRODUCT_FROM_DATABASE=CPWNA100 (Philips wireless PCMCIA) + +pci:v00001113d0000EC02* + ID_PRODUCT_FROM_DATABASE=SMC 1244TX v3 + +pci:v00001113d0000EE23* + ID_PRODUCT_FROM_DATABASE=SMCWPCIT-G 108Mbps Wireless PCI adapter + +pci:v00001114* + ID_VENDOR_FROM_DATABASE=Atmel Corporation + +pci:v00001114d00000506* + ID_PRODUCT_FROM_DATABASE=at76c506 802.11b Wireless Network Adaptor + +pci:v00001115* + ID_VENDOR_FROM_DATABASE=3D Labs + +pci:v00001116* + ID_VENDOR_FROM_DATABASE=Data Translation + +pci:v00001116d00000022* + ID_PRODUCT_FROM_DATABASE=DT3001 + +pci:v00001116d00000023* + ID_PRODUCT_FROM_DATABASE=DT3002 + +pci:v00001116d00000024* + ID_PRODUCT_FROM_DATABASE=DT3003 + +pci:v00001116d00000025* + ID_PRODUCT_FROM_DATABASE=DT3004 + +pci:v00001116d00000026* + ID_PRODUCT_FROM_DATABASE=DT3005 + +pci:v00001116d00000027* + ID_PRODUCT_FROM_DATABASE=DT3001-PGL + +pci:v00001116d00000028* + ID_PRODUCT_FROM_DATABASE=DT3003-PGL + +pci:v00001116d00000051* + ID_PRODUCT_FROM_DATABASE=DT322 + +pci:v00001116d00000060* + ID_PRODUCT_FROM_DATABASE=DT340 + +pci:v00001116d00000069* + ID_PRODUCT_FROM_DATABASE=DT332 + +pci:v00001116d000080C2* + ID_PRODUCT_FROM_DATABASE=DT3162 + +pci:v00001117* + ID_VENDOR_FROM_DATABASE=Datacube, Inc + +pci:v00001117d00009500* + ID_PRODUCT_FROM_DATABASE=Max-1C SVGA card + +pci:v00001117d00009501* + ID_PRODUCT_FROM_DATABASE=Max-1C image processing + +pci:v00001118* + ID_VENDOR_FROM_DATABASE=Berg Electronics + +pci:v00001119* + ID_VENDOR_FROM_DATABASE=ICP Vortex Computersysteme GmbH + +pci:v00001119d00000000* + ID_PRODUCT_FROM_DATABASE=GDT 6000/6020/6050 + +pci:v00001119d00000001* + ID_PRODUCT_FROM_DATABASE=GDT 6000B/6010 + +pci:v00001119d00000002* + ID_PRODUCT_FROM_DATABASE=GDT 6110/6510 + +pci:v00001119d00000003* + ID_PRODUCT_FROM_DATABASE=GDT 6120/6520 + +pci:v00001119d00000004* + ID_PRODUCT_FROM_DATABASE=GDT 6530 + +pci:v00001119d00000005* + ID_PRODUCT_FROM_DATABASE=GDT 6550 + +pci:v00001119d00000006* + ID_PRODUCT_FROM_DATABASE=GDT 6117/6517 + +pci:v00001119d00000007* + ID_PRODUCT_FROM_DATABASE=GDT 6127/6527 + +pci:v00001119d00000008* + ID_PRODUCT_FROM_DATABASE=GDT 6537 + +pci:v00001119d00000009* + ID_PRODUCT_FROM_DATABASE=GDT 6557/6557-ECC + +pci:v00001119d0000000A* + ID_PRODUCT_FROM_DATABASE=GDT 6115/6515 + +pci:v00001119d0000000B* + ID_PRODUCT_FROM_DATABASE=GDT 6125/6525 + +pci:v00001119d0000000C* + ID_PRODUCT_FROM_DATABASE=GDT 6535 + +pci:v00001119d0000000D* + ID_PRODUCT_FROM_DATABASE=GDT 6555/6555-ECC + +pci:v00001119d00000100* + ID_PRODUCT_FROM_DATABASE=GDT 6117RP/6517RP + +pci:v00001119d00000101* + ID_PRODUCT_FROM_DATABASE=GDT 6127RP/6527RP + +pci:v00001119d00000102* + ID_PRODUCT_FROM_DATABASE=GDT 6537RP + +pci:v00001119d00000103* + ID_PRODUCT_FROM_DATABASE=GDT 6557RP + +pci:v00001119d00000104* + ID_PRODUCT_FROM_DATABASE=GDT 6111RP/6511RP + +pci:v00001119d00000105* + ID_PRODUCT_FROM_DATABASE=GDT 6121RP/6521RP + +pci:v00001119d00000110* + ID_PRODUCT_FROM_DATABASE=GDT 6117RD/6517RD + +pci:v00001119d00000111* + ID_PRODUCT_FROM_DATABASE=GDT 6127RD/6527RD + +pci:v00001119d00000112* + ID_PRODUCT_FROM_DATABASE=GDT 6537RD + +pci:v00001119d00000113* + ID_PRODUCT_FROM_DATABASE=GDT 6557RD + +pci:v00001119d00000114* + ID_PRODUCT_FROM_DATABASE=GDT 6111RD/6511RD + +pci:v00001119d00000115* + ID_PRODUCT_FROM_DATABASE=GDT 6121RD/6521RD + +pci:v00001119d00000118* + ID_PRODUCT_FROM_DATABASE=GDT 6118RD/6518RD/6618RD + +pci:v00001119d00000119* + ID_PRODUCT_FROM_DATABASE=GDT 6128RD/6528RD/6628RD + +pci:v00001119d0000011A* + ID_PRODUCT_FROM_DATABASE=GDT 6538RD/6638RD + +pci:v00001119d0000011B* + ID_PRODUCT_FROM_DATABASE=GDT 6558RD/6658RD + +pci:v00001119d00000120* + ID_PRODUCT_FROM_DATABASE=GDT 6117RP2/6517RP2 + +pci:v00001119d00000121* + ID_PRODUCT_FROM_DATABASE=GDT 6127RP2/6527RP2 + +pci:v00001119d00000122* + ID_PRODUCT_FROM_DATABASE=GDT 6537RP2 + +pci:v00001119d00000123* + ID_PRODUCT_FROM_DATABASE=GDT 6557RP2 + +pci:v00001119d00000124* + ID_PRODUCT_FROM_DATABASE=GDT 6111RP2/6511RP2 + +pci:v00001119d00000125* + ID_PRODUCT_FROM_DATABASE=GDT 6121RP2/6521RP2 + +pci:v00001119d00000136* + ID_PRODUCT_FROM_DATABASE=GDT 6113RS/6513RS + +pci:v00001119d00000137* + ID_PRODUCT_FROM_DATABASE=GDT 6123RS/6523RS + +pci:v00001119d00000138* + ID_PRODUCT_FROM_DATABASE=GDT 6118RS/6518RS/6618RS + +pci:v00001119d00000139* + ID_PRODUCT_FROM_DATABASE=GDT 6128RS/6528RS/6628RS + +pci:v00001119d0000013A* + ID_PRODUCT_FROM_DATABASE=GDT 6538RS/6638RS + +pci:v00001119d0000013B* + ID_PRODUCT_FROM_DATABASE=GDT 6558RS/6658RS + +pci:v00001119d0000013C* + ID_PRODUCT_FROM_DATABASE=GDT 6533RS/6633RS + +pci:v00001119d0000013D* + ID_PRODUCT_FROM_DATABASE=GDT 6543RS/6643RS + +pci:v00001119d0000013E* + ID_PRODUCT_FROM_DATABASE=GDT 6553RS/6653RS + +pci:v00001119d0000013F* + ID_PRODUCT_FROM_DATABASE=GDT 6563RS/6663RS + +pci:v00001119d00000166* + ID_PRODUCT_FROM_DATABASE=GDT 7113RN/7513RN/7613RN + +pci:v00001119d00000167* + ID_PRODUCT_FROM_DATABASE=GDT 7123RN/7523RN/7623RN + +pci:v00001119d00000168* + ID_PRODUCT_FROM_DATABASE=GDT 7118RN/7518RN/7518RN + +pci:v00001119d00000169* + ID_PRODUCT_FROM_DATABASE=GDT 7128RN/7528RN/7628RN + +pci:v00001119d0000016A* + ID_PRODUCT_FROM_DATABASE=GDT 7538RN/7638RN + +pci:v00001119d0000016B* + ID_PRODUCT_FROM_DATABASE=GDT 7558RN/7658RN + +pci:v00001119d0000016C* + ID_PRODUCT_FROM_DATABASE=GDT 7533RN/7633RN + +pci:v00001119d0000016D* + ID_PRODUCT_FROM_DATABASE=GDT 7543RN/7643RN + +pci:v00001119d0000016E* + ID_PRODUCT_FROM_DATABASE=GDT 7553RN/7653RN + +pci:v00001119d0000016F* + ID_PRODUCT_FROM_DATABASE=GDT 7563RN/7663RN + +pci:v00001119d000001D6* + ID_PRODUCT_FROM_DATABASE=GDT 4x13RZ + +pci:v00001119d000001D7* + ID_PRODUCT_FROM_DATABASE=GDT 4x23RZ + +pci:v00001119d000001F6* + ID_PRODUCT_FROM_DATABASE=GDT 8x13RZ + +pci:v00001119d000001F7* + ID_PRODUCT_FROM_DATABASE=GDT 8x23RZ + +pci:v00001119d000001FC* + ID_PRODUCT_FROM_DATABASE=GDT 8x33RZ + +pci:v00001119d000001FD* + ID_PRODUCT_FROM_DATABASE=GDT 8x43RZ + +pci:v00001119d000001FE* + ID_PRODUCT_FROM_DATABASE=GDT 8x53RZ + +pci:v00001119d000001FF* + ID_PRODUCT_FROM_DATABASE=GDT 8x63RZ + +pci:v00001119d00000210* + ID_PRODUCT_FROM_DATABASE=GDT 6519RD/6619RD + +pci:v00001119d00000211* + ID_PRODUCT_FROM_DATABASE=GDT 6529RD/6629RD + +pci:v00001119d00000260* + ID_PRODUCT_FROM_DATABASE=GDT 7519RN/7619RN + +pci:v00001119d00000261* + ID_PRODUCT_FROM_DATABASE=GDT 7529RN/7629RN + +pci:v00001119d000002FF* + ID_PRODUCT_FROM_DATABASE=GDT MAXRP + +pci:v00001119d00000300* + ID_PRODUCT_FROM_DATABASE=GDT NEWRX + +pci:v00001119d00000301* + ID_PRODUCT_FROM_DATABASE=GDT NEWRX2 + +pci:v0000111A* + ID_VENDOR_FROM_DATABASE=Efficient Networks, Inc + +pci:v0000111Ad00000000* + ID_PRODUCT_FROM_DATABASE=155P-MF1 (FPGA) + +pci:v0000111Ad00000002* + ID_PRODUCT_FROM_DATABASE=155P-MF1 (ASIC) + +pci:v0000111Ad00000003* + ID_PRODUCT_FROM_DATABASE=ENI-25P ATM + +pci:v0000111Ad00000003sv0000111Asd00000000* + ID_PRODUCT_FROM_DATABASE=ENI-25p Miniport ATM Adapter + +pci:v0000111Ad00000005* + ID_PRODUCT_FROM_DATABASE=SpeedStream (LANAI) + +pci:v0000111Ad00000005sv0000111Asd00000001* + ID_PRODUCT_FROM_DATABASE=ENI-3010 ATM + +pci:v0000111Ad00000005sv0000111Asd00000009* + ID_PRODUCT_FROM_DATABASE=ENI-3060 ADSL (VPI=0) + +pci:v0000111Ad00000005sv0000111Asd00000101* + ID_PRODUCT_FROM_DATABASE=ENI-3010 ATM + +pci:v0000111Ad00000005sv0000111Asd00000109* + ID_PRODUCT_FROM_DATABASE=ENI-3060CO ADSL (VPI=0) + +pci:v0000111Ad00000005sv0000111Asd00000809* + ID_PRODUCT_FROM_DATABASE=ENI-3060 ADSL (VPI=0 or 8) + +pci:v0000111Ad00000005sv0000111Asd00000909* + ID_PRODUCT_FROM_DATABASE=ENI-3060CO ADSL (VPI=0 or 8) + +pci:v0000111Ad00000005sv0000111Asd00000A09* + ID_PRODUCT_FROM_DATABASE=ENI-3060 ADSL (VPI=<0..15>) + +pci:v0000111Ad00000007* + ID_PRODUCT_FROM_DATABASE=SpeedStream ADSL + +pci:v0000111Ad00000007sv0000111Asd00001001* + ID_PRODUCT_FROM_DATABASE=ENI-3061 ADSL [ASIC] + +pci:v0000111Ad00001020* + ID_PRODUCT_FROM_DATABASE=SpeedStream PCI 10/100 Network Card + +pci:v0000111Ad00001203* + ID_PRODUCT_FROM_DATABASE=SpeedStream 1023 Wireless PCI Adapter + +pci:v0000111B* + ID_VENDOR_FROM_DATABASE=Teledyne Electronic Systems + +pci:v0000111C* + ID_VENDOR_FROM_DATABASE=Tricord Systems Inc. + +pci:v0000111Cd00000001* + ID_PRODUCT_FROM_DATABASE=Powerbis Bridge + +pci:v0000111D* + ID_VENDOR_FROM_DATABASE=Integrated Device Technology, Inc. + +pci:v0000111Dd00000001* + ID_PRODUCT_FROM_DATABASE=IDT77201/77211 155Mbps ATM SAR Controller [NICStAR] + +pci:v0000111Dd00000003* + ID_PRODUCT_FROM_DATABASE=IDT77222/77252 155Mbps ATM MICRO ABR SAR Controller + +pci:v0000111Dd00000004* + ID_PRODUCT_FROM_DATABASE=IDT77V252 155Mbps ATM MICRO ABR SAR Controller + +pci:v0000111Dd00000005* + ID_PRODUCT_FROM_DATABASE=IDT77V222 155Mbps ATM MICRO ABR SAR Controller + +pci:v0000111Dd00008018* + ID_PRODUCT_FROM_DATABASE=PES12N3A PCI Express Switch + +pci:v0000111Dd0000801C* + ID_PRODUCT_FROM_DATABASE=PES24N3A PCI Express Switch + +pci:v0000111Dd00008028* + ID_PRODUCT_FROM_DATABASE=PES4T4 PCI Express Switch + +pci:v0000111Dd0000802B* + ID_PRODUCT_FROM_DATABASE=PES8T5A PCI Express Switch + +pci:v0000111Dd0000802C* + ID_PRODUCT_FROM_DATABASE=PES16T4 PCI Express Switch + +pci:v0000111Dd0000802D* + ID_PRODUCT_FROM_DATABASE=PES16T7 PCI Express Switch + +pci:v0000111Dd0000802E* + ID_PRODUCT_FROM_DATABASE=PES24T6 PCI Express Switch + +pci:v0000111Dd0000802F* + ID_PRODUCT_FROM_DATABASE=PES32T8 PCI Express Switch + +pci:v0000111Dd00008032* + ID_PRODUCT_FROM_DATABASE=PES48T12 PCI Express Switch + +pci:v0000111Dd00008034* + ID_PRODUCT_FROM_DATABASE=PES16/22/34H16 PCI Express Switch + +pci:v0000111Dd00008035* + ID_PRODUCT_FROM_DATABASE=PES32H8 PCI Express Switch + +pci:v0000111Dd00008036* + ID_PRODUCT_FROM_DATABASE=PES48H12 PCI Express Switch + +pci:v0000111Dd00008037* + ID_PRODUCT_FROM_DATABASE=PES64H16 PCI Express Switch + +pci:v0000111Dd00008039* + ID_PRODUCT_FROM_DATABASE=PES3T3 PCI Express Switch + +pci:v0000111Dd0000803A* + ID_PRODUCT_FROM_DATABASE=PES4T4 PCI Express Switch + +pci:v0000111Dd0000803C* + ID_PRODUCT_FROM_DATABASE=PES5T5 PCI Express Switch + +pci:v0000111Dd0000803D* + ID_PRODUCT_FROM_DATABASE=PES6T5 PCI Express Switch + +pci:v0000111Dd00008048* + ID_PRODUCT_FROM_DATABASE=PES8NT2 PCI Express Switch + +pci:v0000111Dd00008049* + ID_PRODUCT_FROM_DATABASE=PES8NT2 PCI Express Switch + +pci:v0000111Dd0000804A* + ID_PRODUCT_FROM_DATABASE=PES8NT2 PCI Express Internal NTB + +pci:v0000111Dd0000804B* + ID_PRODUCT_FROM_DATABASE=PES8NT2 PCI Express External NTB + +pci:v0000111Dd0000804C* + ID_PRODUCT_FROM_DATABASE=PES16NT2 PCI Express Switch + +pci:v0000111Dd0000804D* + ID_PRODUCT_FROM_DATABASE=PES16NT2 PCI Express Switch + +pci:v0000111Dd0000804E* + ID_PRODUCT_FROM_DATABASE=PES16NT2 PCI Express Internal NTB + +pci:v0000111Dd0000804F* + ID_PRODUCT_FROM_DATABASE=PES16NT2 PCI Express External NTB + +pci:v0000111Dd00008058* + ID_PRODUCT_FROM_DATABASE=PES12NT3 PCI Express Switch + +pci:v0000111Dd00008059* + ID_PRODUCT_FROM_DATABASE=PES12NT3 PCI Express Switch + +pci:v0000111Dd0000805A* + ID_PRODUCT_FROM_DATABASE=PES12NT3 PCI Express Internal NTB + +pci:v0000111Dd0000805B* + ID_PRODUCT_FROM_DATABASE=PES12NT3 PCI Express External NTB + +pci:v0000111Dd0000805C* + ID_PRODUCT_FROM_DATABASE=PES24NT3 PCI Express Switch + +pci:v0000111Dd0000805D* + ID_PRODUCT_FROM_DATABASE=PES24NT3 PCI Express Switch + +pci:v0000111Dd0000805E* + ID_PRODUCT_FROM_DATABASE=PES24NT3 PCI Express Internal NTB + +pci:v0000111Dd0000805F* + ID_PRODUCT_FROM_DATABASE=PES24NT3 PCI Express External NTB + +pci:v0000111Dd00008060* + ID_PRODUCT_FROM_DATABASE=PES16T4G2 PCI Express Gen2 Switch + +pci:v0000111Dd00008061* + ID_PRODUCT_FROM_DATABASE=PES12T3G2 PCI Express Gen2 Switch + +pci:v0000111Dd00008068* + ID_PRODUCT_FROM_DATABASE=PES6T6G2 PCI Express Gen2 Switch + +pci:v0000111Dd0000806A* + ID_PRODUCT_FROM_DATABASE=PES24T3G2 PCI Express Gen2 Switch + +pci:v0000111Dd0000806Asv000014C1sd0000000C* + ID_PRODUCT_FROM_DATABASE=10G-PCIE2-8B2 + +pci:v0000111Dd0000806C* + ID_PRODUCT_FROM_DATABASE=PES16T4A/4T4G2 PCI Express Gen2 Switch + +pci:v0000111Dd0000806E* + ID_PRODUCT_FROM_DATABASE=PES24T6G2 PCI Express Gen2 Switch + +pci:v0000111Dd0000806F* + ID_PRODUCT_FROM_DATABASE=HIO524G2 PCI Express Gen2 Switch + +pci:v0000111E* + ID_VENDOR_FROM_DATABASE=Eldec + +pci:v0000111F* + ID_VENDOR_FROM_DATABASE=Precision Digital Images + +pci:v0000111Fd00004A47* + ID_PRODUCT_FROM_DATABASE=Precision MX Video engine interface + +pci:v0000111Fd00005243* + ID_PRODUCT_FROM_DATABASE=Frame capture bus interface + +pci:v00001120* + ID_VENDOR_FROM_DATABASE=EMC Corporation + +pci:v00001121* + ID_VENDOR_FROM_DATABASE=Zilog + +pci:v00001122* + ID_VENDOR_FROM_DATABASE=Multi-tech Systems, Inc. + +pci:v00001123* + ID_VENDOR_FROM_DATABASE=Excellent Design, Inc. + +pci:v00001124* + ID_VENDOR_FROM_DATABASE=Leutron Vision AG + +pci:v00001124d00002581* + ID_PRODUCT_FROM_DATABASE=Picport Monochrome + +pci:v00001125* + ID_VENDOR_FROM_DATABASE=Eurocore + +pci:v00001126* + ID_VENDOR_FROM_DATABASE=Vigra + +pci:v00001127* + ID_VENDOR_FROM_DATABASE=FORE Systems Inc + +pci:v00001127d00000200* + ID_PRODUCT_FROM_DATABASE=ForeRunner PCA-200 ATM + +pci:v00001127d00000210* + ID_PRODUCT_FROM_DATABASE=PCA-200PC + +pci:v00001127d00000250* + ID_PRODUCT_FROM_DATABASE=ATM + +pci:v00001127d00000300* + ID_PRODUCT_FROM_DATABASE=ForeRunner PCA-200EPC ATM + +pci:v00001127d00000310* + ID_PRODUCT_FROM_DATABASE=ATM + +pci:v00001127d00000400* + ID_PRODUCT_FROM_DATABASE=ForeRunnerHE ATM Adapter + +pci:v00001127d00000400sv00001127sd00000400* + ID_PRODUCT_FROM_DATABASE=ForeRunnerHE ATM + +pci:v00001129* + ID_VENDOR_FROM_DATABASE=Firmworks + +pci:v0000112A* + ID_VENDOR_FROM_DATABASE=Hermes Electronics Company, Ltd. + +pci:v0000112B* + ID_VENDOR_FROM_DATABASE=Linotype - Hell AG + +pci:v0000112C* + ID_VENDOR_FROM_DATABASE=Zenith Data Systems + +pci:v0000112D* + ID_VENDOR_FROM_DATABASE=Ravicad + +pci:v0000112E* + ID_VENDOR_FROM_DATABASE=Infomedia Microelectronics Inc. + +pci:v0000112F* + ID_VENDOR_FROM_DATABASE=Dalsa Inc. + +pci:v0000112Fd00000000* + ID_PRODUCT_FROM_DATABASE=MVC IC-PCI + +pci:v0000112Fd00000001* + ID_PRODUCT_FROM_DATABASE=MVC IM-PCI Video frame grabber/processor + +pci:v0000112Fd00000008* + ID_PRODUCT_FROM_DATABASE=PC-CamLink PCI framegrabber + +pci:v00001130* + ID_VENDOR_FROM_DATABASE=Computervision + +pci:v00001131* + ID_VENDOR_FROM_DATABASE=Philips Semiconductors + +pci:v00001131d00001561* + ID_PRODUCT_FROM_DATABASE=USB 1.1 Host Controller + +pci:v00001131d00001561sv00001775sd0000C200* + ID_PRODUCT_FROM_DATABASE=C2K onboard USB 1.1 host controller + +pci:v00001131d00001562* + ID_PRODUCT_FROM_DATABASE=USB 2.0 Host Controller + +pci:v00001131d00001562sv00001775sd0000C200* + ID_PRODUCT_FROM_DATABASE=C2K onboard USB 2.0 host controller + +pci:v00001131d00003400* + ID_PRODUCT_FROM_DATABASE=SmartPCI56(UCB1500) 56K Modem + +pci:v00001131d00005400* + ID_PRODUCT_FROM_DATABASE=TriMedia TM1000/1100 + +pci:v00001131d00005400sv000012CAsd00000000* + ID_PRODUCT_FROM_DATABASE=BlueICE + +pci:v00001131d00005402* + ID_PRODUCT_FROM_DATABASE=TriMedia TM1300 + +pci:v00001131d00005402sv00001244sd00000F00* + ID_PRODUCT_FROM_DATABASE=Fritz!Card DSL + +pci:v00001131d00005402sv000015EBsd00001300* + ID_PRODUCT_FROM_DATABASE=DT1300 + +pci:v00001131d00005402sv000015EBsd00001302* + ID_PRODUCT_FROM_DATABASE=DT1302 + +pci:v00001131d00005402sv000015EBsd00001304* + ID_PRODUCT_FROM_DATABASE=DT1304 + +pci:v00001131d00005402sv000015EBsd00001305* + ID_PRODUCT_FROM_DATABASE=DT1305 + +pci:v00001131d00005402sv000015EBsd00001306* + ID_PRODUCT_FROM_DATABASE=PMCDT1306 + +pci:v00001131d00005402sv000015EBsd00001308* + ID_PRODUCT_FROM_DATABASE=DT1308 + +pci:v00001131d00005402sv000015EBsd00001331* + ID_PRODUCT_FROM_DATABASE=DT1301 with SAA7121 + +pci:v00001131d00005402sv000015EBsd00001337* + ID_PRODUCT_FROM_DATABASE=DT1301 with SAA7127 + +pci:v00001131d00005402sv000015EBsd00002D3D* + ID_PRODUCT_FROM_DATABASE=X3D + +pci:v00001131d00005402sv000015EBsd00007022* + ID_PRODUCT_FROM_DATABASE=PTM1300 + +pci:v00001131d00005405* + ID_PRODUCT_FROM_DATABASE=TriMedia TM1500 + +pci:v00001131d00005405sv00001136sd00000005* + ID_PRODUCT_FROM_DATABASE=LCP-1500 + +pci:v00001131d00005406* + ID_PRODUCT_FROM_DATABASE=TriMedia TM1700 + +pci:v00001131d0000540B* + ID_PRODUCT_FROM_DATABASE=PNX1005 Media Processor + +pci:v00001131d0000540Bsv00001131sd00000020* + ID_PRODUCT_FROM_DATABASE=PNXLite PCI Demo Board + +pci:v00001131d00007130* + ID_PRODUCT_FROM_DATABASE=SAA7130 Video Broadcast Decoder + +pci:v00001131d00007130sv00000000sd00004016* + ID_PRODUCT_FROM_DATABASE=Behold TV 401 + +pci:v00001131d00007130sv00000000sd00004051* + ID_PRODUCT_FROM_DATABASE=Behold TV 405 FM + +pci:v00001131d00007130sv00000000sd00005051* + ID_PRODUCT_FROM_DATABASE=Behold TV 505 RDS + +pci:v00001131d00007130sv00000000sd0000505B* + ID_PRODUCT_FROM_DATABASE=Behold TV 505 RDS + +pci:v00001131d00007130sv0000102Bsd000048D0* + ID_PRODUCT_FROM_DATABASE=Matrox CronosPlus + +pci:v00001131d00007130sv00001048sd0000226B* + ID_PRODUCT_FROM_DATABASE=ELSA EX-VISION 300TV + +pci:v00001131d00007130sv0000107Dsd00006655* + ID_PRODUCT_FROM_DATABASE=WinFast DTV1000S + +pci:v00001131d00007130sv00001131sd00000000* + ID_PRODUCT_FROM_DATABASE=SAA7130-based TV tuner card + +pci:v00001131d00007130sv00001131sd00002001* + ID_PRODUCT_FROM_DATABASE=10MOONS PCI TV CAPTURE CARD + +pci:v00001131d00007130sv00001131sd00002005* + ID_PRODUCT_FROM_DATABASE=Techcom (India) TV Tuner Card (SSD-TV-670) + +pci:v00001131d00007130sv00001458sd00009006* + ID_PRODUCT_FROM_DATABASE=GT-PS700 DVB-S tuner + +pci:v00001131d00007130sv00001461sd0000050C* + ID_PRODUCT_FROM_DATABASE=Nagase Sangyo TransGear 3000TV + +pci:v00001131d00007130sv00001461sd000010FF* + ID_PRODUCT_FROM_DATABASE=AVerMedia DVD EZMaker + +pci:v00001131d00007130sv00001461sd00002108* + ID_PRODUCT_FROM_DATABASE=AverMedia AverTV/305 + +pci:v00001131d00007130sv00001461sd00002115* + ID_PRODUCT_FROM_DATABASE=AverMedia AverTV Studio 305 + +pci:v00001131d00007130sv0000153Bsd00001152* + ID_PRODUCT_FROM_DATABASE=Terratec Cinergy 200 TV + +pci:v00001131d00007130sv0000185Bsd0000C100* + ID_PRODUCT_FROM_DATABASE=Compro VideoMate TV PVR/FM + +pci:v00001131d00007130sv0000185Bsd0000C901* + ID_PRODUCT_FROM_DATABASE=Videomate DVB-T200 + +pci:v00001131d00007130sv00005168sd00000138* + ID_PRODUCT_FROM_DATABASE=LifeView FlyVIDEO2000 + +pci:v00001131d00007130sv00005ACEsd00005010* + ID_PRODUCT_FROM_DATABASE=Behold TV 501 + +pci:v00001131d00007130sv00005ACEsd00005050* + ID_PRODUCT_FROM_DATABASE=Behold TV 505 FM + +pci:v00001131d00007133* + ID_PRODUCT_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder + +pci:v00001131d00007133sv00000000sd00004091* + ID_PRODUCT_FROM_DATABASE=Beholder BeholdTV 409 FM + +pci:v00001131d00007133sv00000000sd00005071* + ID_PRODUCT_FROM_DATABASE=Behold TV 507 RDS + +pci:v00001131d00007133sv00000000sd0000507B* + ID_PRODUCT_FROM_DATABASE=Behold TV 507 RDS + +pci:v00001131d00007133sv00000000sd00005201* + ID_PRODUCT_FROM_DATABASE=Behold TV Columbus + +pci:v00001131d00007133sv00000070sd00006701* + ID_PRODUCT_FROM_DATABASE=WinTV HVR-1110 + +pci:v00001131d00007133sv00001019sd00004CB5* + ID_PRODUCT_FROM_DATABASE=Elitegroup ECS TVP3XP FM1236 Tuner Card (NTSC,FM) + +pci:v00001131d00007133sv00001043sd00000210* + ID_PRODUCT_FROM_DATABASE=FlyTV mini Asus Digimatrix + +pci:v00001131d00007133sv00001043sd00004843* + ID_PRODUCT_FROM_DATABASE=ASUS TV-FM 7133 + +pci:v00001131d00007133sv00001043sd00004845* + ID_PRODUCT_FROM_DATABASE=TV-FM 7135 + +pci:v00001131d00007133sv00001043sd00004862* + ID_PRODUCT_FROM_DATABASE=P7131 Dual + +pci:v00001131d00007133sv00001043sd00004876* + ID_PRODUCT_FROM_DATABASE=My Cinema-P7131 Hybrid + +pci:v00001131d00007133sv00001131sd00000000* + ID_PRODUCT_FROM_DATABASE=SAA713x-based TV tuner card + +pci:v00001131d00007133sv00001131sd00002001* + ID_PRODUCT_FROM_DATABASE=Proteus Pro [philips reference design] + +pci:v00001131d00007133sv00001131sd00002018* + ID_PRODUCT_FROM_DATABASE=Tiger reference design + +pci:v00001131d00007133sv00001131sd00004EE9* + ID_PRODUCT_FROM_DATABASE=MonsterTV Mobile + +pci:v00001131d00007133sv00001131sd00007133* + ID_PRODUCT_FROM_DATABASE=Pinnacle PCTV 301i + +pci:v00001131d00007133sv000011BDsd0000002B* + ID_PRODUCT_FROM_DATABASE=PCTV Stereo + +pci:v00001131d00007133sv000011BDsd0000002E* + ID_PRODUCT_FROM_DATABASE=PCTV 110i (saa7133) + +pci:v00001131d00007133sv000012ABsd00000800* + ID_PRODUCT_FROM_DATABASE=PURPLE TV + +pci:v00001131d00007133sv000013C2sd00002804* + ID_PRODUCT_FROM_DATABASE=Technotrend Budget T-3000 Hybrid + +pci:v00001131d00007133sv00001421sd00000335* + ID_PRODUCT_FROM_DATABASE=Instant TV DVB-T Cardbus + +pci:v00001131d00007133sv00001421sd00001370* + ID_PRODUCT_FROM_DATABASE=Instant TV (saa7135) + +pci:v00001131d00007133sv00001435sd00007330* + ID_PRODUCT_FROM_DATABASE=VFG7330 + +pci:v00001131d00007133sv00001435sd00007350* + ID_PRODUCT_FROM_DATABASE=VFG7350 + +pci:v00001131d00007133sv00001458sd00009002* + ID_PRODUCT_FROM_DATABASE=GT-PTV-TAF-RH DVB-T/Analog TV/FM tuner + +pci:v00001131d00007133sv00001458sd00009003* + ID_PRODUCT_FROM_DATABASE=GT-PTV-AF-RH Analog TV/FM tuner + +pci:v00001131d00007133sv00001458sd00009004* + ID_PRODUCT_FROM_DATABASE=GT-P8000 DVB-T/Analog TV/FM tuner + +pci:v00001131d00007133sv00001458sd00009005* + ID_PRODUCT_FROM_DATABASE=GT-P6000 Analog TV/FM tuner + +pci:v00001131d00007133sv00001458sd00009008* + ID_PRODUCT_FROM_DATABASE=GT-P5100 Analog TV tuner + +pci:v00001131d00007133sv00001461sd00001044* + ID_PRODUCT_FROM_DATABASE=AVerTVHD MCE A180 + +pci:v00001131d00007133sv00001461sd00004836* + ID_PRODUCT_FROM_DATABASE=M10D Hybrid DVBT + +pci:v00001131d00007133sv00001461sd0000861E* + ID_PRODUCT_FROM_DATABASE=M105 PAL/SECAM/NTSC/FM Tuner + +pci:v00001131d00007133sv00001461sd0000A14B* + ID_PRODUCT_FROM_DATABASE=AVerTV Studio 509 + +pci:v00001131d00007133sv00001461sd0000A836* + ID_PRODUCT_FROM_DATABASE=M115 DVB-T, PAL/SECAM/NTSC Tuner + +pci:v00001131d00007133sv00001461sd0000F01D* + ID_PRODUCT_FROM_DATABASE=DVB-T Super 007 + +pci:v00001131d00007133sv00001461sd0000F31F* + ID_PRODUCT_FROM_DATABASE=Avermedia AVerTV GO 007 FM + +pci:v00001131d00007133sv00001461sd0000F936* + ID_PRODUCT_FROM_DATABASE=Hybrid+FM PCI (rev A16D) + +pci:v00001131d00007133sv00001462sd00006231* + ID_PRODUCT_FROM_DATABASE=TV@nywhere Plus + +pci:v00001131d00007133sv00001489sd00000214* + ID_PRODUCT_FROM_DATABASE=LifeView FlyTV Platinum FM + +pci:v00001131d00007133sv000014C0sd00001212* + ID_PRODUCT_FROM_DATABASE=LifeView FlyTV Platinum Mini2 + +pci:v00001131d00007133sv0000153Bsd00001160* + ID_PRODUCT_FROM_DATABASE=Cinergy 250 PCI TV + +pci:v00001131d00007133sv0000153Bsd00001162* + ID_PRODUCT_FROM_DATABASE=Terratec Cinergy 400 mobile + +pci:v00001131d00007133sv000017DEsd00007350* + ID_PRODUCT_FROM_DATABASE=ATSC 110 Digital / Analog HDTV Tuner + +pci:v00001131d00007133sv000017DEsd00007352* + ID_PRODUCT_FROM_DATABASE=ATSC 115 Digital / Analog HDTV Tuner + +pci:v00001131d00007133sv0000185Bsd0000C100* + ID_PRODUCT_FROM_DATABASE=VideoMate TV + +pci:v00001131d00007133sv0000185Bsd0000C900* + ID_PRODUCT_FROM_DATABASE=VideoMate T750 + +pci:v00001131d00007133sv00005168sd00000306* + ID_PRODUCT_FROM_DATABASE=LifeView FlyDVB-T DUO + +pci:v00001131d00007133sv00005168sd00000319* + ID_PRODUCT_FROM_DATABASE=LifeView FlyDVB Trio + +pci:v00001131d00007133sv00005168sd00000502* + ID_PRODUCT_FROM_DATABASE=LifeView FlyDVB-T Duo CardBus + +pci:v00001131d00007133sv00005168sd00000520* + ID_PRODUCT_FROM_DATABASE=LifeView FlyDVB Trio CardBus + +pci:v00001131d00007133sv00005168sd00001502* + ID_PRODUCT_FROM_DATABASE=LifeView FlyTV CardBus + +pci:v00001131d00007133sv00005168sd00002502* + ID_PRODUCT_FROM_DATABASE=LifeView FlyDVB-T CardBus + +pci:v00001131d00007133sv00005168sd00002520* + ID_PRODUCT_FROM_DATABASE=LifeView FlyDVB-S Duo CardBus + +pci:v00001131d00007133sv00005168sd00003502* + ID_PRODUCT_FROM_DATABASE=LifeView FlyDVB-T Hybrid CardBus + +pci:v00001131d00007133sv00005168sd00003520* + ID_PRODUCT_FROM_DATABASE=LifeView FlyDVB Trio N CardBus + +pci:v00001131d00007133sv00005ACEsd00005030* + ID_PRODUCT_FROM_DATABASE=Behold TV 503 FM + +pci:v00001131d00007133sv00005ACEsd00005090* + ID_PRODUCT_FROM_DATABASE=Behold TV 509 FM + +pci:v00001131d00007133sv00005ACEsd00006090* + ID_PRODUCT_FROM_DATABASE=Behold TV 609 FM + +pci:v00001131d00007133sv00005ACEsd00006091* + ID_PRODUCT_FROM_DATABASE=Behold TV 609 FM + +pci:v00001131d00007133sv00005ACEsd00006092* + ID_PRODUCT_FROM_DATABASE=Behold TV 609 RDS + +pci:v00001131d00007133sv00005ACEsd00006093* + ID_PRODUCT_FROM_DATABASE=Behold TV 609 RDS + +pci:v00001131d00007133sv00005ACEsd00006190* + ID_PRODUCT_FROM_DATABASE=Behold TV M6 + +pci:v00001131d00007133sv00005ACEsd00006191* + ID_PRODUCT_FROM_DATABASE=Behold TV M63 + +pci:v00001131d00007133sv00005ACEsd00006193* + ID_PRODUCT_FROM_DATABASE=Behold TV M6 Extra + +pci:v00001131d00007133sv00005ACEsd00006290* + ID_PRODUCT_FROM_DATABASE=Behold TV H6 + +pci:v00001131d00007133sv00005ACEsd00007090* + ID_PRODUCT_FROM_DATABASE=Behold TV A7 + +pci:v00001131d00007133sv00005ACEsd00007190* + ID_PRODUCT_FROM_DATABASE=Behold TV H7 + +pci:v00001131d00007133sv00005ACEsd00007595* + ID_PRODUCT_FROM_DATABASE=Behold TV X7 + +pci:v00001131d00007134* + ID_PRODUCT_FROM_DATABASE=SAA7134/SAA7135HL Video Broadcast Decoder + +pci:v00001131d00007134sv00000000sd00004036* + ID_PRODUCT_FROM_DATABASE=Behold TV 403 + +pci:v00001131d00007134sv00000000sd00004037* + ID_PRODUCT_FROM_DATABASE=Behold TV 403 FM + +pci:v00001131d00007134sv00000000sd00004071* + ID_PRODUCT_FROM_DATABASE=Behold TV 407 FM + +pci:v00001131d00007134sv00001019sd00004CB4* + ID_PRODUCT_FROM_DATABASE=Elitegroup ECS TVP3XP FM1216 Tuner Card(PAL-BG,FM) + +pci:v00001131d00007134sv00001043sd00000210* + ID_PRODUCT_FROM_DATABASE=Digimatrix TV + +pci:v00001131d00007134sv00001043sd00004840* + ID_PRODUCT_FROM_DATABASE=ASUS TV-FM 7134 + +pci:v00001131d00007134sv00001043sd00004842* + ID_PRODUCT_FROM_DATABASE=TV-FM 7134 + +pci:v00001131d00007134sv00001131sd00000000* + ID_PRODUCT_FROM_DATABASE=SAA713x-based TV tuner card + +pci:v00001131d00007134sv00001131sd00002004* + ID_PRODUCT_FROM_DATABASE=EUROPA V3 reference design + +pci:v00001131d00007134sv00001131sd00004E85* + ID_PRODUCT_FROM_DATABASE=SKNet Monster TV + +pci:v00001131d00007134sv00001131sd00006752* + ID_PRODUCT_FROM_DATABASE=EMPRESS + +pci:v00001131d00007134sv000011BDsd0000002B* + ID_PRODUCT_FROM_DATABASE=PCTV Stereo + +pci:v00001131d00007134sv000011BDsd0000002D* + ID_PRODUCT_FROM_DATABASE=PCTV 300i DVB-T + PAL + +pci:v00001131d00007134sv00001461sd00002C00* + ID_PRODUCT_FROM_DATABASE=AverTV Hybrid+FM PCI + +pci:v00001131d00007134sv00001461sd00009715* + ID_PRODUCT_FROM_DATABASE=AVerTV Studio 307 + +pci:v00001131d00007134sv00001461sd0000A70A* + ID_PRODUCT_FROM_DATABASE=Avermedia AVerTV 307 + +pci:v00001131d00007134sv00001461sd0000A70B* + ID_PRODUCT_FROM_DATABASE=AverMedia M156 / Medion 2819 + +pci:v00001131d00007134sv00001461sd0000D6EE* + ID_PRODUCT_FROM_DATABASE=Cardbus TV/Radio (E500) + +pci:v00001131d00007134sv00001471sd0000B7E9* + ID_PRODUCT_FROM_DATABASE=AVerTV Cardbus plus + +pci:v00001131d00007134sv0000153Bsd00001142* + ID_PRODUCT_FROM_DATABASE=Terratec Cinergy 400 TV + +pci:v00001131d00007134sv0000153Bsd00001143* + ID_PRODUCT_FROM_DATABASE=Terratec Cinergy 600 TV + +pci:v00001131d00007134sv0000153Bsd00001158* + ID_PRODUCT_FROM_DATABASE=Terratec Cinergy 600 TV MK3 + +pci:v00001131d00007134sv00001540sd00009524* + ID_PRODUCT_FROM_DATABASE=ProVideo PV952 + +pci:v00001131d00007134sv000016BEsd00000003* + ID_PRODUCT_FROM_DATABASE=Medion 7134 + +pci:v00001131d00007134sv0000185Bsd0000C200* + ID_PRODUCT_FROM_DATABASE=Compro VideoMate Gold+ Pal + +pci:v00001131d00007134sv0000185Bsd0000C900* + ID_PRODUCT_FROM_DATABASE=Videomate DVB-T300 + +pci:v00001131d00007134sv00001894sd0000A006* + ID_PRODUCT_FROM_DATABASE=KNC One TV-Station DVR + +pci:v00001131d00007134sv00001894sd0000FE01* + ID_PRODUCT_FROM_DATABASE=KNC One TV-Station RDS / Typhoon TV Tuner RDS + +pci:v00001131d00007134sv00005168sd00000138* + ID_PRODUCT_FROM_DATABASE=FLY TV PRIME 34FM + +pci:v00001131d00007134sv00005ACEsd00005070* + ID_PRODUCT_FROM_DATABASE=Behold TV 507 FM + +pci:v00001131d00007134sv00005ACEsd00006070* + ID_PRODUCT_FROM_DATABASE=Behold TV 607 FM + +pci:v00001131d00007134sv00005ACEsd00006071* + ID_PRODUCT_FROM_DATABASE=Behold TV 607 FM + +pci:v00001131d00007134sv00005ACEsd00006072* + ID_PRODUCT_FROM_DATABASE=Behold TV 607 RDS + +pci:v00001131d00007134sv00005ACEsd00006073* + ID_PRODUCT_FROM_DATABASE=Behold TV 607 RDS + +pci:v00001131d00007145* + ID_PRODUCT_FROM_DATABASE=SAA7145 + +pci:v00001131d00007146* + ID_PRODUCT_FROM_DATABASE=SAA7146 + +pci:v00001131d00007146sv0000110Asd00000000* + ID_PRODUCT_FROM_DATABASE=Fujitsu/Siemens DVB-C card rev1.5 + +pci:v00001131d00007146sv0000110Asd0000FFFF* + ID_PRODUCT_FROM_DATABASE=Fujitsu/Siemens DVB-C card rev1.5 + +pci:v00001131d00007146sv00001124sd00002581* + ID_PRODUCT_FROM_DATABASE=Leutron Vision PicPort + +pci:v00001131d00007146sv00001131sd00004F56* + ID_PRODUCT_FROM_DATABASE=KNC1 DVB-S Budget + +pci:v00001131d00007146sv00001131sd00004F60* + ID_PRODUCT_FROM_DATABASE=Fujitsu-Siemens Activy DVB-S Budget Rev AL + +pci:v00001131d00007146sv00001131sd00004F61* + ID_PRODUCT_FROM_DATABASE=Activy DVB-S Budget Rev GR + +pci:v00001131d00007146sv00001131sd00005F61* + ID_PRODUCT_FROM_DATABASE=Activy DVB-T Budget + +pci:v00001131d00007146sv0000114Bsd00002003* + ID_PRODUCT_FROM_DATABASE=DVRaptor Video Edit/Capture Card + +pci:v00001131d00007146sv000011BDsd00000006* + ID_PRODUCT_FROM_DATABASE=DV500 Overlay + +pci:v00001131d00007146sv000011BDsd0000000A* + ID_PRODUCT_FROM_DATABASE=DV500 Overlay + +pci:v00001131d00007146sv000011BDsd0000000F* + ID_PRODUCT_FROM_DATABASE=DV500 Overlay + +pci:v00001131d00007146sv000013C2sd00000000* + ID_PRODUCT_FROM_DATABASE=Siemens/Technotrend/Hauppauge DVB card rev1.3 or rev1.5 + +pci:v00001131d00007146sv000013C2sd00000001* + ID_PRODUCT_FROM_DATABASE=Technotrend/Hauppauge DVB card rev1.3 or rev1.6 + +pci:v00001131d00007146sv000013C2sd00000002* + ID_PRODUCT_FROM_DATABASE=Technotrend/Hauppauge DVB card rev2.1 + +pci:v00001131d00007146sv000013C2sd00000003* + ID_PRODUCT_FROM_DATABASE=Technotrend/Hauppauge DVB card rev2.1 + +pci:v00001131d00007146sv000013C2sd00000004* + ID_PRODUCT_FROM_DATABASE=Technotrend/Hauppauge DVB card rev2.1 + +pci:v00001131d00007146sv000013C2sd00000006* + ID_PRODUCT_FROM_DATABASE=Technotrend/Hauppauge DVB card rev1.3 or rev1.6 + +pci:v00001131d00007146sv000013C2sd00000008* + ID_PRODUCT_FROM_DATABASE=Technotrend/Hauppauge DVB-T + +pci:v00001131d00007146sv000013C2sd0000000A* + ID_PRODUCT_FROM_DATABASE=Octal/Technotrend DVB-C for iTV + +pci:v00001131d00007146sv000013C2sd0000000E* + ID_PRODUCT_FROM_DATABASE=Technotrend/Hauppauge DVB card rev2.3 + +pci:v00001131d00007146sv000013C2sd00001003* + ID_PRODUCT_FROM_DATABASE=Technotrend-Budget/Hauppauge WinTV-NOVA-S DVB card + +pci:v00001131d00007146sv000013C2sd00001004* + ID_PRODUCT_FROM_DATABASE=Technotrend-Budget/Hauppauge WinTV-NOVA-C DVB card + +pci:v00001131d00007146sv000013C2sd00001005* + ID_PRODUCT_FROM_DATABASE=Technotrend-Budget/Hauppauge WinTV-NOVA-T DVB card + +pci:v00001131d00007146sv000013C2sd0000100C* + ID_PRODUCT_FROM_DATABASE=Technotrend-Budget/Hauppauge WinTV-NOVA-CI DVB card + +pci:v00001131d00007146sv000013C2sd0000100F* + ID_PRODUCT_FROM_DATABASE=Technotrend-Budget/Hauppauge WinTV-NOVA-CI DVB card + +pci:v00001131d00007146sv000013C2sd00001010* + ID_PRODUCT_FROM_DATABASE=DVB C-1500 + +pci:v00001131d00007146sv000013C2sd00001011* + ID_PRODUCT_FROM_DATABASE=Technotrend-Budget/Hauppauge WinTV-NOVA-T DVB card + +pci:v00001131d00007146sv000013C2sd00001012* + ID_PRODUCT_FROM_DATABASE=DVB T-1500 + +pci:v00001131d00007146sv000013C2sd00001013* + ID_PRODUCT_FROM_DATABASE=SATELCO Multimedia DVB + +pci:v00001131d00007146sv000013C2sd00001016* + ID_PRODUCT_FROM_DATABASE=WinTV-NOVA-SE DVB card + +pci:v00001131d00007146sv000013C2sd00001018* + ID_PRODUCT_FROM_DATABASE=DVB S-1401 + +pci:v00001131d00007146sv000013C2sd00001019* + ID_PRODUCT_FROM_DATABASE=S2-3200 + +pci:v00001131d00007146sv000013C2sd00001102* + ID_PRODUCT_FROM_DATABASE=Technotrend/Hauppauge DVB card rev2.1 + +pci:v00001131d00007146sv0000153Bsd00001155* + ID_PRODUCT_FROM_DATABASE=Cinergy 1200 DVB-S + +pci:v00001131d00007146sv0000153Bsd00001156* + ID_PRODUCT_FROM_DATABASE=Terratec Cynergy 1200C + +pci:v00001131d00007146sv0000153Bsd00001157* + ID_PRODUCT_FROM_DATABASE=Cinergy 1200 DVB-T + +pci:v00001131d00007146sv00001894sd00000020* + ID_PRODUCT_FROM_DATABASE=KNC One DVB-C V1.0 + +pci:v00001131d00007146sv00001894sd00000023* + ID_PRODUCT_FROM_DATABASE=TVStation DVB-C plus + +pci:v00001131d00007160* + ID_PRODUCT_FROM_DATABASE=SAA7160 + +pci:v00001131d00007160sv00001458sd00009009* + ID_PRODUCT_FROM_DATABASE=E8000 DVB-T/Analog TV/FM tuner + +pci:v00001131d00007162* + ID_PRODUCT_FROM_DATABASE=SAA7162 + +pci:v00001131d00007162sv000011BDsd00000101* + ID_PRODUCT_FROM_DATABASE=Pinnacle PCTV 7010iX TV Card + +pci:v00001131d00007164* + ID_PRODUCT_FROM_DATABASE=SAA7164 + +pci:v00001131d00007164sv00000070sd00008800* + ID_PRODUCT_FROM_DATABASE=WinTV HVR-2250 + +pci:v00001131d00007164sv00000070sd00008810* + ID_PRODUCT_FROM_DATABASE=WinTV HVR-2250 + +pci:v00001131d00007164sv00000070sd00008851* + ID_PRODUCT_FROM_DATABASE=WinTV HVR-2250 + +pci:v00001131d00007164sv00000070sd00008853* + ID_PRODUCT_FROM_DATABASE=WinTV HVR-2250 + +pci:v00001131d00007164sv00000070sd00008880* + ID_PRODUCT_FROM_DATABASE=WinTV HVR-2250 + +pci:v00001131d00007164sv00000070sd00008891* + ID_PRODUCT_FROM_DATABASE=WinTV HVR-2250 + +pci:v00001131d00007164sv00000070sd000088A0* + ID_PRODUCT_FROM_DATABASE=WinTV HVR-2250 + +pci:v00001131d00007164sv00000070sd000088A1* + ID_PRODUCT_FROM_DATABASE=WinTV HVR-2250 + +pci:v00001131d00007164sv00000070sd00008900* + ID_PRODUCT_FROM_DATABASE=WinTV HVR-2200 + +pci:v00001131d00007164sv00000070sd00008901* + ID_PRODUCT_FROM_DATABASE=WinTV HVR-2200 + +pci:v00001131d00007164sv00000070sd00008940* + ID_PRODUCT_FROM_DATABASE=WinTV HVR-2200 (submodel 89619) + +pci:v00001131d00007164sv00000070sd00008951* + ID_PRODUCT_FROM_DATABASE=WinTV HVR-2200 + +pci:v00001131d00007164sv00000070sd00008953* + ID_PRODUCT_FROM_DATABASE=WinTV HVR-2200 + +pci:v00001131d00007164sv00000070sd00008980* + ID_PRODUCT_FROM_DATABASE=WinTV HVR-2200 + +pci:v00001131d00007164sv00000070sd00008991* + ID_PRODUCT_FROM_DATABASE=WinTV HVR-2200 + +pci:v00001131d00007164sv00000070sd00008993* + ID_PRODUCT_FROM_DATABASE=WinTV HVR-2200 + +pci:v00001131d00007164sv00000070sd000089A0* + ID_PRODUCT_FROM_DATABASE=WinTV HVR-2200 + +pci:v00001131d00007164sv00000070sd000089A1* + ID_PRODUCT_FROM_DATABASE=WinTV HVR-2200 + +pci:v00001131d00007231* + ID_PRODUCT_FROM_DATABASE=SAA7231 + +pci:v00001131d00007231sv00005ACEsd00008000* + ID_PRODUCT_FROM_DATABASE=Behold TV H8 + +pci:v00001131d00007231sv00005ACEsd00008100* + ID_PRODUCT_FROM_DATABASE=Behold TV A8 + +pci:v00001131d00009730* + ID_PRODUCT_FROM_DATABASE=SAA9730 Integrated Multimedia and Peripheral Controller + +pci:v00001131d00009730sv00001131sd00000000* + ID_PRODUCT_FROM_DATABASE=Integrated Multimedia and Peripheral Controller + +pci:v00001132* + ID_VENDOR_FROM_DATABASE=Mitel Corp. + +pci:v00001133* + ID_VENDOR_FROM_DATABASE=Dialogic Corporation + +pci:v00001133d00007701* + ID_PRODUCT_FROM_DATABASE=Eiconcard C90 + +pci:v00001133d00007711* + ID_PRODUCT_FROM_DATABASE=Eiconcard C91 + +pci:v00001133d00007901* + ID_PRODUCT_FROM_DATABASE=EiconCard S90 + +pci:v00001133d00007902* + ID_PRODUCT_FROM_DATABASE=EiconCard S90 + +pci:v00001133d00007911* + ID_PRODUCT_FROM_DATABASE=EiconCard S91 + +pci:v00001133d00007912* + ID_PRODUCT_FROM_DATABASE=EiconCard S91 + +pci:v00001133d00007921* + ID_PRODUCT_FROM_DATABASE=Eiconcard S92 + +pci:v00001133d00007941* + ID_PRODUCT_FROM_DATABASE=EiconCard S94 + +pci:v00001133d00007942* + ID_PRODUCT_FROM_DATABASE=EiconCard S94 + +pci:v00001133d00007943* + ID_PRODUCT_FROM_DATABASE=EiconCard S94 + +pci:v00001133d00007944* + ID_PRODUCT_FROM_DATABASE=EiconCard S94 + +pci:v00001133d00007945* + ID_PRODUCT_FROM_DATABASE=Eiconcard S94 + +pci:v00001133d00007948* + ID_PRODUCT_FROM_DATABASE=Eiconcard S94 64bit/66MHz + +pci:v00001133d00009711* + ID_PRODUCT_FROM_DATABASE=Eiconcard S91 V2 + +pci:v00001133d00009911* + ID_PRODUCT_FROM_DATABASE=Eiconcard S91 V2 + +pci:v00001133d00009941* + ID_PRODUCT_FROM_DATABASE=Eiconcard S94 V2 + +pci:v00001133d00009A41* + ID_PRODUCT_FROM_DATABASE=Eiconcard S94 PCIe + +pci:v00001133d0000B921* + ID_PRODUCT_FROM_DATABASE=EiconCard P92 + +pci:v00001133d0000B922* + ID_PRODUCT_FROM_DATABASE=EiconCard P92 + +pci:v00001133d0000B923* + ID_PRODUCT_FROM_DATABASE=EiconCard P92 + +pci:v00001133d0000E001* + ID_PRODUCT_FROM_DATABASE=Diva Pro 2.0 S/T + +pci:v00001133d0000E002* + ID_PRODUCT_FROM_DATABASE=Diva 2.0 S/T PCI + +pci:v00001133d0000E003* + ID_PRODUCT_FROM_DATABASE=Diva Pro 2.0 U + +pci:v00001133d0000E004* + ID_PRODUCT_FROM_DATABASE=Diva 2.0 U PCI + +pci:v00001133d0000E005* + ID_PRODUCT_FROM_DATABASE=Diva 2.01 S/T PCI + +pci:v00001133d0000E006* + ID_PRODUCT_FROM_DATABASE=Diva CT S/T PCI + +pci:v00001133d0000E007* + ID_PRODUCT_FROM_DATABASE=Diva CT U PCI + +pci:v00001133d0000E008* + ID_PRODUCT_FROM_DATABASE=Diva CT Lite S/T PCI + +pci:v00001133d0000E009* + ID_PRODUCT_FROM_DATABASE=Diva CT Lite U PCI + +pci:v00001133d0000E00A* + ID_PRODUCT_FROM_DATABASE=Diva ISDN+V.90 PCI + +pci:v00001133d0000E00B* + ID_PRODUCT_FROM_DATABASE=Diva ISDN PCI 2.02 + +pci:v00001133d0000E00C* + ID_PRODUCT_FROM_DATABASE=Diva 2.02 PCI U + +pci:v00001133d0000E00D* + ID_PRODUCT_FROM_DATABASE=Diva Pro 3.0 PCI + +pci:v00001133d0000E00E* + ID_PRODUCT_FROM_DATABASE=Diva ISDN+CT S/T PCI Rev 2 + +pci:v00001133d0000E010* + ID_PRODUCT_FROM_DATABASE=Diva Server BRI-2M PCI + +pci:v00001133d0000E010sv0000110Asd00000021* + ID_PRODUCT_FROM_DATABASE=Fujitsu Siemens ISDN S0 + +pci:v00001133d0000E011* + ID_PRODUCT_FROM_DATABASE=Diva Server BRI S/T Rev 2 + +pci:v00001133d0000E012* + ID_PRODUCT_FROM_DATABASE=Diva Server 4BRI-8M PCI + +pci:v00001133d0000E013* + ID_PRODUCT_FROM_DATABASE=4BRI + +pci:v00001133d0000E013sv00001133sd00001300* + ID_PRODUCT_FROM_DATABASE=Diva V-4BRI-8 PCI v2 + +pci:v00001133d0000E013sv00001133sd0000E013* + ID_PRODUCT_FROM_DATABASE=Diva 4BRI-8 PCI v2 + +pci:v00001133d0000E014* + ID_PRODUCT_FROM_DATABASE=Diva Server PRI-30M PCI + +pci:v00001133d0000E015* + ID_PRODUCT_FROM_DATABASE=Diva PRI PCI v2 + +pci:v00001133d0000E016* + ID_PRODUCT_FROM_DATABASE=Diva Server Voice 4BRI PCI + +pci:v00001133d0000E017* + ID_PRODUCT_FROM_DATABASE=Diva Server Voice 4BRI Rev 2 + +pci:v00001133d0000E017sv00001133sd0000E017* + ID_PRODUCT_FROM_DATABASE=Diva Server Voice 4BRI-8M 2.0 PCI + +pci:v00001133d0000E018* + ID_PRODUCT_FROM_DATABASE=BRI + +pci:v00001133d0000E018sv00001133sd00001800* + ID_PRODUCT_FROM_DATABASE=Diva V-BRI-2 PCI v2 + +pci:v00001133d0000E018sv00001133sd0000E018* + ID_PRODUCT_FROM_DATABASE=Diva BRI-2 PCI v2 + +pci:v00001133d0000E019* + ID_PRODUCT_FROM_DATABASE=Diva Server Voice PRI Rev 2 + +pci:v00001133d0000E019sv00001133sd0000E019* + ID_PRODUCT_FROM_DATABASE=Diva Server Voice PRI 2.0 PCI + +pci:v00001133d0000E01A* + ID_PRODUCT_FROM_DATABASE=Diva BRI-2FX PCI v2 + +pci:v00001133d0000E01B* + ID_PRODUCT_FROM_DATABASE=Diva Server Voice BRI-2M 2.0 PCI + +pci:v00001133d0000E01Bsv00001133sd0000E01B* + ID_PRODUCT_FROM_DATABASE=Diva Server Voice BRI-2M 2.0 PCI + +pci:v00001133d0000E01C* + ID_PRODUCT_FROM_DATABASE=PRI + +pci:v00001133d0000E01Csv00001133sd00001C01* + ID_PRODUCT_FROM_DATABASE=Diva PRI/E1/T1-8 PCI v3 + +pci:v00001133d0000E01Csv00001133sd00001C02* + ID_PRODUCT_FROM_DATABASE=Diva PRI/T1-24 PCI(e) v3 + +pci:v00001133d0000E01Csv00001133sd00001C03* + ID_PRODUCT_FROM_DATABASE=Diva PRI/E1-30 PCI(e) v3 + +pci:v00001133d0000E01Csv00001133sd00001C04* + ID_PRODUCT_FROM_DATABASE=Diva PRI/E1/T1-CTI PCI(e) v3 + +pci:v00001133d0000E01Csv00001133sd00001C05* + ID_PRODUCT_FROM_DATABASE=Diva V-PRI/T1-24 PCI(e) v3 + +pci:v00001133d0000E01Csv00001133sd00001C06* + ID_PRODUCT_FROM_DATABASE=Diva V-PRI/E1-30 PCI(e) v3 + +pci:v00001133d0000E01Csv00001133sd00001C07* + ID_PRODUCT_FROM_DATABASE=Diva Server PRI/E1/T1-8 Cornet NQ + +pci:v00001133d0000E01Csv00001133sd00001C08* + ID_PRODUCT_FROM_DATABASE=Diva Server PRI/T1-24 Cornet NQ + +pci:v00001133d0000E01Csv00001133sd00001C09* + ID_PRODUCT_FROM_DATABASE=Diva Server PRI/E1-30 Cornet NQ + +pci:v00001133d0000E01Csv00001133sd00001C0A* + ID_PRODUCT_FROM_DATABASE=Diva Server PRI/E1/T1 Cornet NQ + +pci:v00001133d0000E01Csv00001133sd00001C0B* + ID_PRODUCT_FROM_DATABASE=Diva Server V-PRI/T1-24 Cornet NQ + +pci:v00001133d0000E01Csv00001133sd00001C0C* + ID_PRODUCT_FROM_DATABASE=Diva Server V-PRI/E1-30 Cornet NQ + +pci:v00001133d0000E01E* + ID_PRODUCT_FROM_DATABASE=2PRI + +pci:v00001133d0000E01Esv00001133sd00001E01* + ID_PRODUCT_FROM_DATABASE=Diva 2PRI/E1/T1-60 PCI v1 + +pci:v00001133d0000E01Esv00001133sd0000E01E* + ID_PRODUCT_FROM_DATABASE=Diva V-2PRI/E1/T1-60 PCI v1 + +pci:v00001133d0000E020* + ID_PRODUCT_FROM_DATABASE=4PRI + +pci:v00001133d0000E020sv00001133sd00002001* + ID_PRODUCT_FROM_DATABASE=Diva 4PRI/E1/T1-120 PCI v1 + +pci:v00001133d0000E020sv00001133sd0000E020* + ID_PRODUCT_FROM_DATABASE=Diva V-4PRI/E1/T1-120 PCI v1 + +pci:v00001133d0000E022* + ID_PRODUCT_FROM_DATABASE=Analog-2 + +pci:v00001133d0000E022sv00001133sd00002200* + ID_PRODUCT_FROM_DATABASE=Diva V-Analog-2 PCI v1 + +pci:v00001133d0000E022sv00001133sd0000E022* + ID_PRODUCT_FROM_DATABASE=Diva Analog-2 PCI v1 + +pci:v00001133d0000E024* + ID_PRODUCT_FROM_DATABASE=Analog-4 + +pci:v00001133d0000E024sv00001133sd00002400* + ID_PRODUCT_FROM_DATABASE=Diva V-Analog-4 PCI v1 + +pci:v00001133d0000E024sv00001133sd0000E024* + ID_PRODUCT_FROM_DATABASE=Diva Analog-4 PCI v1 + +pci:v00001133d0000E028* + ID_PRODUCT_FROM_DATABASE=Analog-8 + +pci:v00001133d0000E028sv00001133sd00002800* + ID_PRODUCT_FROM_DATABASE=Diva V-Analog-8 PCI v1 + +pci:v00001133d0000E028sv00001133sd0000E028* + ID_PRODUCT_FROM_DATABASE=Diva Analog-8 PCI v1 + +pci:v00001133d0000E02A* + ID_PRODUCT_FROM_DATABASE=Diva IPM-300 PCI v1 + +pci:v00001133d0000E02C* + ID_PRODUCT_FROM_DATABASE=Diva IPM-600 PCI v1 + +pci:v00001133d0000E02E* + ID_PRODUCT_FROM_DATABASE=4BRI + +pci:v00001133d0000E02Esv00001133sd00002E01* + ID_PRODUCT_FROM_DATABASE=Diva V-4BRI-8 PCIe v2 + +pci:v00001133d0000E02Esv00001133sd0000E02E* + ID_PRODUCT_FROM_DATABASE=Diva 4BRI-8 PCIe v2 + +pci:v00001133d0000E032* + ID_PRODUCT_FROM_DATABASE=BRI + +pci:v00001133d0000E032sv00001133sd00003201* + ID_PRODUCT_FROM_DATABASE=Diva V-BRI-2 PCIe v2 + +pci:v00001133d0000E032sv00001133sd0000E032* + ID_PRODUCT_FROM_DATABASE=Diva BRI-2 PCIe v2 + +pci:v00001133d0000E034* + ID_PRODUCT_FROM_DATABASE=Diva BRI-CTI PCI v2 + +pci:v00001134* + ID_VENDOR_FROM_DATABASE=Mercury Computer Systems + +pci:v00001134d00000001* + ID_PRODUCT_FROM_DATABASE=Raceway Bridge + +pci:v00001134d00000002* + ID_PRODUCT_FROM_DATABASE=Dual PCI to RapidIO Bridge + +pci:v00001134d0000000B* + ID_PRODUCT_FROM_DATABASE=POET Serial RapidIO Bridge + +pci:v00001134d0000000D* + ID_PRODUCT_FROM_DATABASE=POET PSDMS Device + +pci:v00001135* + ID_VENDOR_FROM_DATABASE=Fuji Xerox Co Ltd + +pci:v00001135d00000001* + ID_PRODUCT_FROM_DATABASE=Printer controller + +pci:v00001136* + ID_VENDOR_FROM_DATABASE=Momentum Data Systems + +pci:v00001136d00000002* + ID_PRODUCT_FROM_DATABASE=PCI-JTAG + +pci:v00001137* + ID_VENDOR_FROM_DATABASE=Cisco Systems Inc + +pci:v00001137d00000023* + ID_PRODUCT_FROM_DATABASE=VIC 81 PCIe Upstream Port + +pci:v00001137d00000040* + ID_PRODUCT_FROM_DATABASE=VIC PCIe Upstream Port + +pci:v00001137d00000041* + ID_PRODUCT_FROM_DATABASE=VIC PCIe Downstream Port + +pci:v00001137d00000042* + ID_PRODUCT_FROM_DATABASE=VIC Management Controller + +pci:v00001137d00000042sv00001137sd00000047* + ID_PRODUCT_FROM_DATABASE=VIC P81E PCIe Management Controller + +pci:v00001137d00000043* + ID_PRODUCT_FROM_DATABASE=VIC Ethernet NIC + +pci:v00001137d00000043sv00001137sd00000047* + ID_PRODUCT_FROM_DATABASE=VIC P81E PCIe Ethernet NIC + +pci:v00001137d00000043sv00001137sd00000048* + ID_PRODUCT_FROM_DATABASE=VIC M81KR Mezzanine Ethernet NIC + +pci:v00001137d00000043sv00001137sd0000004F* + ID_PRODUCT_FROM_DATABASE=VIC 1280 Mezzanine Ethernet NIC + +pci:v00001137d00000043sv00001137sd00000084* + ID_PRODUCT_FROM_DATABASE=VIC 1240 MLOM Ethernet NIC + +pci:v00001137d00000043sv00001137sd00000085* + ID_PRODUCT_FROM_DATABASE=VIC 1225 PCIe Ethernet NIC + +pci:v00001137d00000044* + ID_PRODUCT_FROM_DATABASE=VIC Ethernet NIC Dynamic + +pci:v00001137d00000044sv00001137sd00000047* + ID_PRODUCT_FROM_DATABASE=VIC P81E PCIe Ethernet NIC Dynamic + +pci:v00001137d00000044sv00001137sd00000048* + ID_PRODUCT_FROM_DATABASE=VIC M81KR Mezzanine Ethernet NIC Dynamic + +pci:v00001137d00000044sv00001137sd0000004F* + ID_PRODUCT_FROM_DATABASE=VIC 1280 Mezzanine Ethernet NIC Dynamic + +pci:v00001137d00000044sv00001137sd00000084* + ID_PRODUCT_FROM_DATABASE=VIC 1240 MLOM Ethernet NIC Dynamic + +pci:v00001137d00000044sv00001137sd00000085* + ID_PRODUCT_FROM_DATABASE=VIC 1225 PCIe Ethernet NIC Dynamic + +pci:v00001137d00000045* + ID_PRODUCT_FROM_DATABASE=VIC FCoE HBA + +pci:v00001137d00000045sv00001137sd00000047* + ID_PRODUCT_FROM_DATABASE=VIC P81E PCIe FCoE HBA + +pci:v00001137d00000045sv00001137sd00000048* + ID_PRODUCT_FROM_DATABASE=VIC M81KR Mezzanine FCoE HBA + +pci:v00001137d00000045sv00001137sd0000004F* + ID_PRODUCT_FROM_DATABASE=VIC 1280 Mezzanine FCoE HBA + +pci:v00001137d0000004E* + ID_PRODUCT_FROM_DATABASE=VIC 82 PCIe Upstream Port + +pci:v00001138* + ID_VENDOR_FROM_DATABASE=Ziatech Corporation + +pci:v00001138d00008905* + ID_PRODUCT_FROM_DATABASE=8905 [STD 32 Bridge] + +pci:v00001139* + ID_VENDOR_FROM_DATABASE=Dynamic Pictures, Inc + +pci:v00001139d00000001* + ID_PRODUCT_FROM_DATABASE=VGA Compatable 3D Graphics + +pci:v0000113A* + ID_VENDOR_FROM_DATABASE=FWB Inc + +pci:v0000113B* + ID_VENDOR_FROM_DATABASE=Network Computing Devices + +pci:v0000113C* + ID_VENDOR_FROM_DATABASE=Cyclone Microsystems, Inc. + +pci:v0000113Cd00000000* + ID_PRODUCT_FROM_DATABASE=PCI-9060 i960 Bridge + +pci:v0000113Cd00000001* + ID_PRODUCT_FROM_DATABASE=PCI-SDK [PCI i960 Evaluation Platform] + +pci:v0000113Cd00000911* + ID_PRODUCT_FROM_DATABASE=PCI-911 [i960Jx-based Intelligent I/O Controller] + +pci:v0000113Cd00000912* + ID_PRODUCT_FROM_DATABASE=PCI-912 [i960CF-based Intelligent I/O Controller] + +pci:v0000113Cd00000913* + ID_PRODUCT_FROM_DATABASE=PCI-913 + +pci:v0000113Cd00000914* + ID_PRODUCT_FROM_DATABASE=PCI-914 [I/O Controller w/ secondary PCI bus] + +pci:v0000113D* + ID_VENDOR_FROM_DATABASE=Leading Edge Products Inc + +pci:v0000113E* + ID_VENDOR_FROM_DATABASE=Sanyo Electric Co - Computer Engineering Dept + +pci:v0000113F* + ID_VENDOR_FROM_DATABASE=Equinox Systems, Inc. + +pci:v0000113Fd00000808* + ID_PRODUCT_FROM_DATABASE=SST-64P Adapter + +pci:v0000113Fd00001010* + ID_PRODUCT_FROM_DATABASE=SST-128P Adapter + +pci:v0000113Fd000080C0* + ID_PRODUCT_FROM_DATABASE=SST-16P DB Adapter + +pci:v0000113Fd000080C4* + ID_PRODUCT_FROM_DATABASE=SST-16P RJ Adapter + +pci:v0000113Fd000080C8* + ID_PRODUCT_FROM_DATABASE=SST-16P Adapter + +pci:v0000113Fd00008888* + ID_PRODUCT_FROM_DATABASE=SST-4P Adapter + +pci:v0000113Fd00009090* + ID_PRODUCT_FROM_DATABASE=SST-8P Adapter + +pci:v00001140* + ID_VENDOR_FROM_DATABASE=Intervoice Inc + +pci:v00001141* + ID_VENDOR_FROM_DATABASE=Crest Microsystem Inc + +pci:v00001142* + ID_VENDOR_FROM_DATABASE=Alliance Semiconductor Corporation + +pci:v00001142d00003210* + ID_PRODUCT_FROM_DATABASE=AP6410 + +pci:v00001142d00006422* + ID_PRODUCT_FROM_DATABASE=ProVideo 6422 + +pci:v00001142d00006424* + ID_PRODUCT_FROM_DATABASE=ProVideo 6424 + +pci:v00001142d00006425* + ID_PRODUCT_FROM_DATABASE=ProMotion AT25 + +pci:v00001142d0000643D* + ID_PRODUCT_FROM_DATABASE=ProMotion AT3D + +pci:v00001143* + ID_VENDOR_FROM_DATABASE=NetPower, Inc + +pci:v00001144* + ID_VENDOR_FROM_DATABASE=Cincinnati Milacron + +pci:v00001144d00000001* + ID_PRODUCT_FROM_DATABASE=Noservo controller + +pci:v00001145* + ID_VENDOR_FROM_DATABASE=Workbit Corporation + +pci:v00001145d00008007* + ID_PRODUCT_FROM_DATABASE=NinjaSCSI-32 Workbit + +pci:v00001145d0000F007* + ID_PRODUCT_FROM_DATABASE=NinjaSCSI-32 KME + +pci:v00001145d0000F010* + ID_PRODUCT_FROM_DATABASE=NinjaSCSI-32 Workbit + +pci:v00001145d0000F012* + ID_PRODUCT_FROM_DATABASE=NinjaSCSI-32 Logitec + +pci:v00001145d0000F013* + ID_PRODUCT_FROM_DATABASE=NinjaSCSI-32 Logitec + +pci:v00001145d0000F015* + ID_PRODUCT_FROM_DATABASE=NinjaSCSI-32 Melco + +pci:v00001145d0000F020* + ID_PRODUCT_FROM_DATABASE=NinjaSCSI-32 Sony PCGA-DVD51 + +pci:v00001145d0000F021* + ID_PRODUCT_FROM_DATABASE=NinjaPATA-32 Delkin Cardbus UDMA + +pci:v00001145d0000F024* + ID_PRODUCT_FROM_DATABASE=NinjaPATA-32 Delkin Cardbus UDMA + +pci:v00001145d0000F103* + ID_PRODUCT_FROM_DATABASE=NinjaPATA-32 Delkin Cardbus UDMA + +pci:v00001146* + ID_VENDOR_FROM_DATABASE=Force Computers + +pci:v00001147* + ID_VENDOR_FROM_DATABASE=Interface Corp + +pci:v00001148* + ID_VENDOR_FROM_DATABASE=SysKonnect + +pci:v00001148d00004000* + ID_PRODUCT_FROM_DATABASE=FDDI Adapter + +pci:v00001148d00004000sv00000E11sd0000B03B* + ID_PRODUCT_FROM_DATABASE=Netelligent 100 FDDI DAS Fibre SC + +pci:v00001148d00004000sv00000E11sd0000B03C* + ID_PRODUCT_FROM_DATABASE=Netelligent 100 FDDI SAS Fibre SC + +pci:v00001148d00004000sv00000E11sd0000B03D* + ID_PRODUCT_FROM_DATABASE=Netelligent 100 FDDI DAS UTP + +pci:v00001148d00004000sv00000E11sd0000B03E* + ID_PRODUCT_FROM_DATABASE=Netelligent 100 FDDI SAS UTP + +pci:v00001148d00004000sv00000E11sd0000B03F* + ID_PRODUCT_FROM_DATABASE=Netelligent 100 FDDI SAS Fibre MIC + +pci:v00001148d00004000sv00001148sd00005521* + ID_PRODUCT_FROM_DATABASE=FDDI SK-5521 (SK-NET FDDI-UP) + +pci:v00001148d00004000sv00001148sd00005522* + ID_PRODUCT_FROM_DATABASE=FDDI SK-5522 (SK-NET FDDI-UP DAS) + +pci:v00001148d00004000sv00001148sd00005541* + ID_PRODUCT_FROM_DATABASE=FDDI SK-5541 (SK-NET FDDI-FP) + +pci:v00001148d00004000sv00001148sd00005543* + ID_PRODUCT_FROM_DATABASE=FDDI SK-5543 (SK-NET FDDI-LP) + +pci:v00001148d00004000sv00001148sd00005544* + ID_PRODUCT_FROM_DATABASE=FDDI SK-5544 (SK-NET FDDI-LP DAS) + +pci:v00001148d00004000sv00001148sd00005821* + ID_PRODUCT_FROM_DATABASE=FDDI SK-5821 (SK-NET FDDI-UP64) + +pci:v00001148d00004000sv00001148sd00005822* + ID_PRODUCT_FROM_DATABASE=FDDI SK-5822 (SK-NET FDDI-UP64 DAS) + +pci:v00001148d00004000sv00001148sd00005841* + ID_PRODUCT_FROM_DATABASE=FDDI SK-5841 (SK-NET FDDI-FP64) + +pci:v00001148d00004000sv00001148sd00005843* + ID_PRODUCT_FROM_DATABASE=FDDI SK-5843 (SK-NET FDDI-LP64) + +pci:v00001148d00004000sv00001148sd00005844* + ID_PRODUCT_FROM_DATABASE=FDDI SK-5844 (SK-NET FDDI-LP64 DAS) + +pci:v00001148d00004200* + ID_PRODUCT_FROM_DATABASE=Token Ring adapter + +pci:v00001148d00004300* + ID_PRODUCT_FROM_DATABASE=SK-9872 Gigabit Ethernet Server Adapter (SK-NET GE-ZX dual link) + +pci:v00001148d00004300sv00001148sd00009821* + ID_PRODUCT_FROM_DATABASE=SK-9821 Gigabit Ethernet Server Adapter (SK-NET GE-T) + +pci:v00001148d00004300sv00001148sd00009822* + ID_PRODUCT_FROM_DATABASE=SK-9822 Gigabit Ethernet Server Adapter (SK-NET GE-T dual link) + +pci:v00001148d00004300sv00001148sd00009841* + ID_PRODUCT_FROM_DATABASE=SK-9841 Gigabit Ethernet Server Adapter (SK-NET GE-LX) + +pci:v00001148d00004300sv00001148sd00009842* + ID_PRODUCT_FROM_DATABASE=SK-9842 Gigabit Ethernet Server Adapter (SK-NET GE-LX dual link) + +pci:v00001148d00004300sv00001148sd00009843* + ID_PRODUCT_FROM_DATABASE=SK-9843 Gigabit Ethernet Server Adapter (SK-NET GE-SX) + +pci:v00001148d00004300sv00001148sd00009844* + ID_PRODUCT_FROM_DATABASE=SK-9844 Gigabit Ethernet Server Adapter (SK-NET GE-SX dual link) + +pci:v00001148d00004300sv00001148sd00009861* + ID_PRODUCT_FROM_DATABASE=SK-9861 Gigabit Ethernet Server Adapter (SK-NET GE-SX Volition) + +pci:v00001148d00004300sv00001148sd00009862* + ID_PRODUCT_FROM_DATABASE=SK-9862 Gigabit Ethernet Server Adapter (SK-NET GE-SX Volition dual link) + +pci:v00001148d00004300sv00001148sd00009871* + ID_PRODUCT_FROM_DATABASE=SK-9871 Gigabit Ethernet Server Adapter (SK-NET GE-ZX) + +pci:v00001148d00004300sv00001148sd00009872* + ID_PRODUCT_FROM_DATABASE=SK-9872 Gigabit Ethernet Server Adapter (SK-NET GE-ZX dual link) + +pci:v00001148d00004300sv00001259sd00002970* + ID_PRODUCT_FROM_DATABASE=AT-2970SX Gigabit Ethernet Adapter + +pci:v00001148d00004300sv00001259sd00002971* + ID_PRODUCT_FROM_DATABASE=AT-2970LX Gigabit Ethernet Adapter + +pci:v00001148d00004300sv00001259sd00002972* + ID_PRODUCT_FROM_DATABASE=AT-2970TX Gigabit Ethernet Adapter + +pci:v00001148d00004300sv00001259sd00002973* + ID_PRODUCT_FROM_DATABASE=AT-2971SX Gigabit Ethernet Adapter + +pci:v00001148d00004300sv00001259sd00002974* + ID_PRODUCT_FROM_DATABASE=AT-2971T Gigabit Ethernet Adapter + +pci:v00001148d00004300sv00001259sd00002975* + ID_PRODUCT_FROM_DATABASE=AT-2970SX/2SC Gigabit Ethernet Adapter + +pci:v00001148d00004300sv00001259sd00002976* + ID_PRODUCT_FROM_DATABASE=AT-2970LX/2SC Gigabit Ethernet Adapter + +pci:v00001148d00004300sv00001259sd00002977* + ID_PRODUCT_FROM_DATABASE=AT-2970TX/2TX Gigabit Ethernet Adapter + +pci:v00001148d00004320* + ID_PRODUCT_FROM_DATABASE=SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter, PCI64, Fiber ZX/SC + +pci:v00001148d00004320sv00001148sd00000121* + ID_PRODUCT_FROM_DATABASE=Marvell RDK-8001 Adapter + +pci:v00001148d00004320sv00001148sd00000221* + ID_PRODUCT_FROM_DATABASE=Marvell RDK-8002 Adapter + +pci:v00001148d00004320sv00001148sd00000321* + ID_PRODUCT_FROM_DATABASE=Marvell RDK-8003 Adapter + +pci:v00001148d00004320sv00001148sd00000421* + ID_PRODUCT_FROM_DATABASE=Marvell RDK-8004 Adapter + +pci:v00001148d00004320sv00001148sd00000621* + ID_PRODUCT_FROM_DATABASE=Marvell RDK-8006 Adapter + +pci:v00001148d00004320sv00001148sd00000721* + ID_PRODUCT_FROM_DATABASE=Marvell RDK-8007 Adapter + +pci:v00001148d00004320sv00001148sd00000821* + ID_PRODUCT_FROM_DATABASE=Marvell RDK-8008 Adapter + +pci:v00001148d00004320sv00001148sd00000921* + ID_PRODUCT_FROM_DATABASE=Marvell RDK-8009 Adapter + +pci:v00001148d00004320sv00001148sd00001121* + ID_PRODUCT_FROM_DATABASE=Marvell RDK-8011 Adapter + +pci:v00001148d00004320sv00001148sd00001221* + ID_PRODUCT_FROM_DATABASE=Marvell RDK-8012 Adapter + +pci:v00001148d00004320sv00001148sd00003221* + ID_PRODUCT_FROM_DATABASE=SK-9521 V2.0 10/100/1000Base-T Adapter + +pci:v00001148d00004320sv00001148sd00005021* + ID_PRODUCT_FROM_DATABASE=SK-9821 V2.0 Gigabit Ethernet 10/100/1000Base-T Adapter + +pci:v00001148d00004320sv00001148sd00005041* + ID_PRODUCT_FROM_DATABASE=SK-9841 V2.0 Gigabit Ethernet 1000Base-LX Adapter + +pci:v00001148d00004320sv00001148sd00005043* + ID_PRODUCT_FROM_DATABASE=SK-9843 V2.0 Gigabit Ethernet 1000Base-SX Adapter + +pci:v00001148d00004320sv00001148sd00005051* + ID_PRODUCT_FROM_DATABASE=SK-9851 V2.0 Gigabit Ethernet 1000Base-SX Adapter + +pci:v00001148d00004320sv00001148sd00005061* + ID_PRODUCT_FROM_DATABASE=SK-9861 V2.0 Gigabit Ethernet 1000Base-SX Adapter + +pci:v00001148d00004320sv00001148sd00005071* + ID_PRODUCT_FROM_DATABASE=SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter + +pci:v00001148d00004320sv00001148sd00009521* + ID_PRODUCT_FROM_DATABASE=SK-9521 10/100/1000Base-T Adapter + +pci:v00001148d00004400* + ID_PRODUCT_FROM_DATABASE=SK-9Dxx Gigabit Ethernet Adapter + +pci:v00001148d00004500* + ID_PRODUCT_FROM_DATABASE=SK-9Mxx Gigabit Ethernet Adapter + +pci:v00001148d00009000* + ID_PRODUCT_FROM_DATABASE=SK-9S21 10/100/1000Base-T Server Adapter, PCI-X, Copper RJ-45 + +pci:v00001148d00009843* + ID_PRODUCT_FROM_DATABASE=[Fujitsu] Gigabit Ethernet + +pci:v00001148d00009E00* + ID_PRODUCT_FROM_DATABASE=SK-9E21D 10/100/1000Base-T Adapter, Copper RJ-45 + +pci:v00001148d00009E00sv00001148sd00002100* + ID_PRODUCT_FROM_DATABASE=SK-9E21 Server Adapter + +pci:v00001148d00009E00sv00001148sd000021D0* + ID_PRODUCT_FROM_DATABASE=SK-9E21D 10/100/1000Base-T Adapter + +pci:v00001148d00009E00sv00001148sd00002200* + ID_PRODUCT_FROM_DATABASE=SK-9E22 Server Adapter + +pci:v00001148d00009E00sv00001148sd00008100* + ID_PRODUCT_FROM_DATABASE=SK-9E81 Server Adapter + +pci:v00001148d00009E00sv00001148sd00008200* + ID_PRODUCT_FROM_DATABASE=SK-9E82 Server Adapter + +pci:v00001148d00009E00sv00001148sd00009100* + ID_PRODUCT_FROM_DATABASE=SK-9E91 Server Adapter + +pci:v00001148d00009E00sv00001148sd00009200* + ID_PRODUCT_FROM_DATABASE=SK-9E92 Server Adapter + +pci:v00001148d00009E01* + ID_PRODUCT_FROM_DATABASE=SK-9E21M 10/100/1000Base-T Adapter + +pci:v00001149* + ID_VENDOR_FROM_DATABASE=Win System Corporation + +pci:v0000114A* + ID_VENDOR_FROM_DATABASE=VMIC + +pci:v0000114Ad00005565* + ID_PRODUCT_FROM_DATABASE=GE-IP PCI5565,PMC5565 Reflective Memory Node + +pci:v0000114Ad00005579* + ID_PRODUCT_FROM_DATABASE=VMIPCI-5579 (Reflective Memory Card) + +pci:v0000114Ad00005587* + ID_PRODUCT_FROM_DATABASE=VMIPCI-5587 (Reflective Memory Card) + +pci:v0000114Ad00006504* + ID_PRODUCT_FROM_DATABASE=VMIC PCI 7755 FPGA + +pci:v0000114Ad00007587* + ID_PRODUCT_FROM_DATABASE=VMIVME-7587 + +pci:v0000114B* + ID_VENDOR_FROM_DATABASE=Canopus Co., Ltd + +pci:v0000114C* + ID_VENDOR_FROM_DATABASE=Annabooks + +pci:v0000114D* + ID_VENDOR_FROM_DATABASE=IC Corporation + +pci:v0000114E* + ID_VENDOR_FROM_DATABASE=Nikon Systems Inc + +pci:v0000114F* + ID_VENDOR_FROM_DATABASE=Digi International + +pci:v0000114Fd00000002* + ID_PRODUCT_FROM_DATABASE=AccelePort EPC + +pci:v0000114Fd00000003* + ID_PRODUCT_FROM_DATABASE=RightSwitch SE-6 + +pci:v0000114Fd00000004* + ID_PRODUCT_FROM_DATABASE=AccelePort Xem + +pci:v0000114Fd00000005* + ID_PRODUCT_FROM_DATABASE=AccelePort Xr + +pci:v0000114Fd00000006* + ID_PRODUCT_FROM_DATABASE=AccelePort Xr,C/X + +pci:v0000114Fd00000009* + ID_PRODUCT_FROM_DATABASE=AccelePort Xr/J + +pci:v0000114Fd0000000A* + ID_PRODUCT_FROM_DATABASE=AccelePort EPC/J + +pci:v0000114Fd0000000C* + ID_PRODUCT_FROM_DATABASE=DataFirePRIme T1 (1-port) + +pci:v0000114Fd0000000D* + ID_PRODUCT_FROM_DATABASE=SyncPort 2-Port (x.25/FR) + +pci:v0000114Fd00000011* + ID_PRODUCT_FROM_DATABASE=AccelePort 8r EIA-232 (IBM) + +pci:v0000114Fd00000012* + ID_PRODUCT_FROM_DATABASE=AccelePort 8r EIA-422 + +pci:v0000114Fd00000013* + ID_PRODUCT_FROM_DATABASE=AccelePort Xr + +pci:v0000114Fd00000014* + ID_PRODUCT_FROM_DATABASE=AccelePort 8r EIA-422 + +pci:v0000114Fd00000015* + ID_PRODUCT_FROM_DATABASE=AccelePort Xem + +pci:v0000114Fd00000016* + ID_PRODUCT_FROM_DATABASE=AccelePort EPC/X + +pci:v0000114Fd00000017* + ID_PRODUCT_FROM_DATABASE=AccelePort C/X + +pci:v0000114Fd0000001A* + ID_PRODUCT_FROM_DATABASE=DataFirePRIme E1 (1-port) + +pci:v0000114Fd0000001B* + ID_PRODUCT_FROM_DATABASE=AccelePort C/X (IBM) + +pci:v0000114Fd0000001C* + ID_PRODUCT_FROM_DATABASE=AccelePort Xr (SAIP) + +pci:v0000114Fd0000001D* + ID_PRODUCT_FROM_DATABASE=DataFire RAS T1/E1/PRI + +pci:v0000114Fd0000001Dsv0000114Fsd00000050* + ID_PRODUCT_FROM_DATABASE=DataFire RAS E1 Adapter + +pci:v0000114Fd0000001Dsv0000114Fsd00000051* + ID_PRODUCT_FROM_DATABASE=DataFire RAS Dual E1 Adapter + +pci:v0000114Fd0000001Dsv0000114Fsd00000052* + ID_PRODUCT_FROM_DATABASE=DataFire RAS T1 Adapter + +pci:v0000114Fd0000001Dsv0000114Fsd00000053* + ID_PRODUCT_FROM_DATABASE=DataFire RAS Dual T1 Adapter + +pci:v0000114Fd00000023* + ID_PRODUCT_FROM_DATABASE=AccelePort RAS + +pci:v0000114Fd00000024* + ID_PRODUCT_FROM_DATABASE=DataFire RAS B4 ST/U + +pci:v0000114Fd00000024sv0000114Fsd00000030* + ID_PRODUCT_FROM_DATABASE=DataFire RAS BRI U Adapter + +pci:v0000114Fd00000024sv0000114Fsd00000031* + ID_PRODUCT_FROM_DATABASE=DataFire RAS BRI S/T Adapter + +pci:v0000114Fd00000026* + ID_PRODUCT_FROM_DATABASE=AccelePort 4r 920 + +pci:v0000114Fd00000027* + ID_PRODUCT_FROM_DATABASE=AccelePort Xr 920 + +pci:v0000114Fd00000028* + ID_PRODUCT_FROM_DATABASE=ClassicBoard 4 + +pci:v0000114Fd00000029* + ID_PRODUCT_FROM_DATABASE=ClassicBoard 8 + +pci:v0000114Fd00000034* + ID_PRODUCT_FROM_DATABASE=AccelePort 2r 920 + +pci:v0000114Fd00000035* + ID_PRODUCT_FROM_DATABASE=DataFire DSP T1/E1/PRI cPCI + +pci:v0000114Fd00000040* + ID_PRODUCT_FROM_DATABASE=AccelePort Xp + +pci:v0000114Fd00000040sv0000114Fsd00000042* + ID_PRODUCT_FROM_DATABASE=AccelePort 2p PCI + +pci:v0000114Fd00000040sv0000114Fsd00000043* + ID_PRODUCT_FROM_DATABASE=AccelePort 4p PCI + +pci:v0000114Fd00000040sv0000114Fsd00000044* + ID_PRODUCT_FROM_DATABASE=AccelePort 8p PCI + +pci:v0000114Fd00000040sv0000114Fsd00000045* + ID_PRODUCT_FROM_DATABASE=AccelePort 16p PCI + +pci:v0000114Fd00000040sv0000114Fsd0000004E* + ID_PRODUCT_FROM_DATABASE=AccelePort 32p PCI + +pci:v0000114Fd00000042* + ID_PRODUCT_FROM_DATABASE=AccelePort 2p + +pci:v0000114Fd00000043* + ID_PRODUCT_FROM_DATABASE=AccelePort 4p + +pci:v0000114Fd00000044* + ID_PRODUCT_FROM_DATABASE=AccelePort 8p + +pci:v0000114Fd00000045* + ID_PRODUCT_FROM_DATABASE=AccelePort 16p + +pci:v0000114Fd0000004E* + ID_PRODUCT_FROM_DATABASE=AccelePort 32p + +pci:v0000114Fd00000070* + ID_PRODUCT_FROM_DATABASE=Datafire Micro V IOM2 (Europe) + +pci:v0000114Fd00000071* + ID_PRODUCT_FROM_DATABASE=Datafire Micro V (Europe) + +pci:v0000114Fd00000072* + ID_PRODUCT_FROM_DATABASE=Datafire Micro V IOM2 (North America) + +pci:v0000114Fd00000073* + ID_PRODUCT_FROM_DATABASE=Datafire Micro V (North America) + +pci:v0000114Fd000000B0* + ID_PRODUCT_FROM_DATABASE=Digi Neo 4 + +pci:v0000114Fd000000B1* + ID_PRODUCT_FROM_DATABASE=Digi Neo 8 + +pci:v0000114Fd000000C8* + ID_PRODUCT_FROM_DATABASE=Digi Neo 2 DB9 + +pci:v0000114Fd000000C9* + ID_PRODUCT_FROM_DATABASE=Digi Neo 2 DB9 PRI + +pci:v0000114Fd000000CA* + ID_PRODUCT_FROM_DATABASE=Digi Neo 2 RJ45 + +pci:v0000114Fd000000CB* + ID_PRODUCT_FROM_DATABASE=Digi Neo 2 RJ45 PRI + +pci:v0000114Fd000000CC* + ID_PRODUCT_FROM_DATABASE=Digi Neo 1 422 + +pci:v0000114Fd000000CD* + ID_PRODUCT_FROM_DATABASE=Digi Neo 1 422 485 + +pci:v0000114Fd000000CE* + ID_PRODUCT_FROM_DATABASE=Digi Neo 2 422 485 + +pci:v0000114Fd000000D0* + ID_PRODUCT_FROM_DATABASE=ClassicBoard 4 422 + +pci:v0000114Fd000000D1* + ID_PRODUCT_FROM_DATABASE=ClassicBoard 8 422 + +pci:v0000114Fd000000F1* + ID_PRODUCT_FROM_DATABASE=Digi Neo PCI-E 4 port + +pci:v0000114Fd000000F4* + ID_PRODUCT_FROM_DATABASE=Digi Neo 4 (IBM version) + +pci:v0000114Fd00006001* + ID_PRODUCT_FROM_DATABASE=Avanstar + +pci:v00001150* + ID_VENDOR_FROM_DATABASE=Thinking Machines Corp + +pci:v00001151* + ID_VENDOR_FROM_DATABASE=JAE Electronics Inc. + +pci:v00001152* + ID_VENDOR_FROM_DATABASE=Megatek + +pci:v00001153* + ID_VENDOR_FROM_DATABASE=Land Win Electronic Corp + +pci:v00001154* + ID_VENDOR_FROM_DATABASE=Melco Inc + +pci:v00001155* + ID_VENDOR_FROM_DATABASE=Pine Technology Ltd + +pci:v00001156* + ID_VENDOR_FROM_DATABASE=Periscope Engineering + +pci:v00001157* + ID_VENDOR_FROM_DATABASE=Avsys Corporation + +pci:v00001158* + ID_VENDOR_FROM_DATABASE=Voarx R & D Inc + +pci:v00001158d00003011* + ID_PRODUCT_FROM_DATABASE=Tokenet/vg 1001/10m anylan + +pci:v00001158d00009050* + ID_PRODUCT_FROM_DATABASE=Lanfleet/Truevalue + +pci:v00001158d00009051* + ID_PRODUCT_FROM_DATABASE=Lanfleet/Truevalue + +pci:v00001159* + ID_VENDOR_FROM_DATABASE=Mutech Corp + +pci:v00001159d00000001* + ID_PRODUCT_FROM_DATABASE=MV-1000 + +pci:v00001159d00000002* + ID_PRODUCT_FROM_DATABASE=MV-1500 + +pci:v0000115A* + ID_VENDOR_FROM_DATABASE=Harlequin Ltd + +pci:v0000115B* + ID_VENDOR_FROM_DATABASE=Parallax Graphics + +pci:v0000115C* + ID_VENDOR_FROM_DATABASE=Photron Ltd. + +pci:v0000115D* + ID_VENDOR_FROM_DATABASE=Xircom + +pci:v0000115Dd00000003* + ID_PRODUCT_FROM_DATABASE=Cardbus Ethernet 10/100 + +pci:v0000115Dd00000003sv00001014sd00000181* + ID_PRODUCT_FROM_DATABASE=10/100 EtherJet Cardbus Adapter + +pci:v0000115Dd00000003sv00001014sd00001181* + ID_PRODUCT_FROM_DATABASE=10/100 EtherJet Cardbus Adapter + +pci:v0000115Dd00000003sv00001014sd00008181* + ID_PRODUCT_FROM_DATABASE=10/100 EtherJet Cardbus Adapter + +pci:v0000115Dd00000003sv00001014sd00009181* + ID_PRODUCT_FROM_DATABASE=10/100 EtherJet Cardbus Adapter + +pci:v0000115Dd00000003sv0000115Dsd00000181* + ID_PRODUCT_FROM_DATABASE=Cardbus Ethernet 10/100 + +pci:v0000115Dd00000003sv0000115Dsd00000182* + ID_PRODUCT_FROM_DATABASE=RealPort2 CardBus Ethernet 10/100 (R2BE-100) + +pci:v0000115Dd00000003sv0000115Dsd00001181* + ID_PRODUCT_FROM_DATABASE=Cardbus Ethernet 10/100 + +pci:v0000115Dd00000003sv00001179sd00000181* + ID_PRODUCT_FROM_DATABASE=Cardbus Ethernet 10/100 + +pci:v0000115Dd00000003sv00008086sd00008181* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 Mobile CardBus 32 Adapter + +pci:v0000115Dd00000003sv00008086sd00009181* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 Mobile CardBus 32 Adapter + +pci:v0000115Dd00000005* + ID_PRODUCT_FROM_DATABASE=Cardbus Ethernet 10/100 + +pci:v0000115Dd00000005sv00001014sd00000182* + ID_PRODUCT_FROM_DATABASE=10/100 EtherJet Cardbus Adapter + +pci:v0000115Dd00000005sv00001014sd00001182* + ID_PRODUCT_FROM_DATABASE=10/100 EtherJet Cardbus Adapter + +pci:v0000115Dd00000005sv0000115Dsd00000182* + ID_PRODUCT_FROM_DATABASE=Cardbus Ethernet 10/100 + +pci:v0000115Dd00000005sv0000115Dsd00001182* + ID_PRODUCT_FROM_DATABASE=Cardbus Ethernet 10/100 + +pci:v0000115Dd00000007* + ID_PRODUCT_FROM_DATABASE=Cardbus Ethernet 10/100 + +pci:v0000115Dd00000007sv00001014sd00000182* + ID_PRODUCT_FROM_DATABASE=10/100 EtherJet Cardbus Adapter + +pci:v0000115Dd00000007sv00001014sd00001182* + ID_PRODUCT_FROM_DATABASE=10/100 EtherJet Cardbus Adapter + +pci:v0000115Dd00000007sv0000115Dsd00000182* + ID_PRODUCT_FROM_DATABASE=Cardbus Ethernet 10/100 + +pci:v0000115Dd00000007sv0000115Dsd00001182* + ID_PRODUCT_FROM_DATABASE=Cardbus Ethernet 10/100 + +pci:v0000115Dd0000000B* + ID_PRODUCT_FROM_DATABASE=Cardbus Ethernet 10/100 + +pci:v0000115Dd0000000Bsv00001014sd00000183* + ID_PRODUCT_FROM_DATABASE=10/100 EtherJet Cardbus Adapter + +pci:v0000115Dd0000000Bsv0000115Dsd00000183* + ID_PRODUCT_FROM_DATABASE=Cardbus Ethernet 10/100 + +pci:v0000115Dd0000000C* + ID_PRODUCT_FROM_DATABASE=Mini-PCI V.90 56k Modem + +pci:v0000115Dd0000000F* + ID_PRODUCT_FROM_DATABASE=Cardbus Ethernet 10/100 + +pci:v0000115Dd0000000Fsv00001014sd00000183* + ID_PRODUCT_FROM_DATABASE=10/100 EtherJet Cardbus Adapter + +pci:v0000115Dd0000000Fsv0000115Dsd00000183* + ID_PRODUCT_FROM_DATABASE=Cardbus Ethernet 10/100 + +pci:v0000115Dd000000D4* + ID_PRODUCT_FROM_DATABASE=Mini-PCI K56Flex Modem + +pci:v0000115Dd00000101* + ID_PRODUCT_FROM_DATABASE=Cardbus 56k modem + +pci:v0000115Dd00000101sv0000115Dsd00001081* + ID_PRODUCT_FROM_DATABASE=Cardbus 56k Modem + +pci:v0000115Dd00000103* + ID_PRODUCT_FROM_DATABASE=Cardbus Ethernet + 56k Modem + +pci:v0000115Dd00000103sv00001014sd00009181* + ID_PRODUCT_FROM_DATABASE=Cardbus 56k Modem + +pci:v0000115Dd00000103sv00001115sd00001181* + ID_PRODUCT_FROM_DATABASE=Cardbus Ethernet 100 + 56k Modem + +pci:v0000115Dd00000103sv0000115Dsd00001181* + ID_PRODUCT_FROM_DATABASE=CBEM56G-100 Ethernet + 56k Modem + +pci:v0000115Dd00000103sv00008086sd00009181* + ID_PRODUCT_FROM_DATABASE=PRO/100 LAN + Modem56 CardBus + +pci:v0000115E* + ID_VENDOR_FROM_DATABASE=Peer Protocols Inc + +pci:v0000115F* + ID_VENDOR_FROM_DATABASE=Maxtor Corporation + +pci:v00001160* + ID_VENDOR_FROM_DATABASE=Megasoft Inc + +pci:v00001161* + ID_VENDOR_FROM_DATABASE=PFU Limited + +pci:v00001162* + ID_VENDOR_FROM_DATABASE=OA Laboratory Co Ltd + +pci:v00001163* + ID_VENDOR_FROM_DATABASE=Rendition + +pci:v00001163d00000001* + ID_PRODUCT_FROM_DATABASE=Verite 1000 + +pci:v00001163d00002000* + ID_PRODUCT_FROM_DATABASE=Verite V2000/V2100/V2200 + +pci:v00001163d00002000sv00001092sd00002000* + ID_PRODUCT_FROM_DATABASE=Stealth II S220 + +pci:v00001164* + ID_VENDOR_FROM_DATABASE=Advanced Peripherals Technologies + +pci:v00001165* + ID_VENDOR_FROM_DATABASE=Imagraph Corporation + +pci:v00001165d00000001* + ID_PRODUCT_FROM_DATABASE=Motion TPEG Recorder/Player with audio + +pci:v00001166* + ID_VENDOR_FROM_DATABASE=Broadcom + +pci:v00001166d00000000* + ID_PRODUCT_FROM_DATABASE=CMIC-LE + +pci:v00001166d00000005* + ID_PRODUCT_FROM_DATABASE=CNB20-LE Host Bridge + +pci:v00001166d00000006* + ID_PRODUCT_FROM_DATABASE=CNB20HE Host Bridge + +pci:v00001166d00000007* + ID_PRODUCT_FROM_DATABASE=CNB20-LE Host Bridge + +pci:v00001166d00000008* + ID_PRODUCT_FROM_DATABASE=CNB20HE Host Bridge + +pci:v00001166d00000009* + ID_PRODUCT_FROM_DATABASE=CNB20LE Host Bridge + +pci:v00001166d00000010* + ID_PRODUCT_FROM_DATABASE=CIOB30 + +pci:v00001166d00000011* + ID_PRODUCT_FROM_DATABASE=CMIC-HE + +pci:v00001166d00000012* + ID_PRODUCT_FROM_DATABASE=CMIC-WS Host Bridge (GC-LE chipset) + +pci:v00001166d00000013* + ID_PRODUCT_FROM_DATABASE=CNB20-HE Host Bridge + +pci:v00001166d00000014* + ID_PRODUCT_FROM_DATABASE=CMIC-LE Host Bridge (GC-LE chipset) + +pci:v00001166d00000015* + ID_PRODUCT_FROM_DATABASE=CMIC-GC Host Bridge + +pci:v00001166d00000016* + ID_PRODUCT_FROM_DATABASE=CMIC-GC Host Bridge + +pci:v00001166d00000017* + ID_PRODUCT_FROM_DATABASE=GCNB-LE Host Bridge + +pci:v00001166d00000031* + ID_PRODUCT_FROM_DATABASE=HT1100 HPX0 HT Host Bridge + +pci:v00001166d00000036* + ID_PRODUCT_FROM_DATABASE=BCM5785 [HT1000] PCI/PCI-X Bridge + +pci:v00001166d00000101* + ID_PRODUCT_FROM_DATABASE=CIOB-X2 PCI-X I/O Bridge + +pci:v00001166d00000103* + ID_PRODUCT_FROM_DATABASE=EPB PCI-Express to PCI-X Bridge + +pci:v00001166d00000104* + ID_PRODUCT_FROM_DATABASE=BCM5785 [HT1000] PCI/PCI-X Bridge + +pci:v00001166d00000110* + ID_PRODUCT_FROM_DATABASE=CIOB-E I/O Bridge with Gigabit Ethernet + +pci:v00001166d00000130* + ID_PRODUCT_FROM_DATABASE=BCM5780 [HT2000] PCI-X bridge + +pci:v00001166d00000132* + ID_PRODUCT_FROM_DATABASE=BCM5780 [HT2000] PCI-Express Bridge + +pci:v00001166d00000132sv00001166sd00000132* + ID_PRODUCT_FROM_DATABASE=HT2000 PCI-Express bridge + +pci:v00001166d00000140* + ID_PRODUCT_FROM_DATABASE=HT2100 PCI-Express Bridge + +pci:v00001166d00000141* + ID_PRODUCT_FROM_DATABASE=HT2100 PCI-Express Bridge + +pci:v00001166d00000142* + ID_PRODUCT_FROM_DATABASE=HT2100 PCI-Express Bridge + +pci:v00001166d00000144* + ID_PRODUCT_FROM_DATABASE=HT2100 PCI-Express Bridge + +pci:v00001166d00000200* + ID_PRODUCT_FROM_DATABASE=OSB4 South Bridge + +pci:v00001166d00000201* + ID_PRODUCT_FROM_DATABASE=CSB5 South Bridge + +pci:v00001166d00000201sv00004C53sd00001080* + ID_PRODUCT_FROM_DATABASE=CT8 mainboard + +pci:v00001166d00000203* + ID_PRODUCT_FROM_DATABASE=CSB6 South Bridge + +pci:v00001166d00000203sv00001734sd00001012* + ID_PRODUCT_FROM_DATABASE=PRIMERGY RX/TX series + +pci:v00001166d00000205* + ID_PRODUCT_FROM_DATABASE=BCM5785 [HT1000] Legacy South Bridge + +pci:v00001166d00000211* + ID_PRODUCT_FROM_DATABASE=OSB4 IDE Controller + +pci:v00001166d00000212* + ID_PRODUCT_FROM_DATABASE=CSB5 IDE Controller + +pci:v00001166d00000212sv00001028sd0000014A* + ID_PRODUCT_FROM_DATABASE=PowerEdge 1750 + +pci:v00001166d00000212sv00001028sd0000810B* + ID_PRODUCT_FROM_DATABASE=PowerEdge 1650/2550 + +pci:v00001166d00000212sv00004C53sd00001080* + ID_PRODUCT_FROM_DATABASE=CT8 mainboard + +pci:v00001166d00000213* + ID_PRODUCT_FROM_DATABASE=CSB6 RAID/IDE Controller + +pci:v00001166d00000213sv00001028sd00004134* + ID_PRODUCT_FROM_DATABASE=PowerEdge 600SC + +pci:v00001166d00000213sv00001028sd0000C134* + ID_PRODUCT_FROM_DATABASE=Poweredge SC600 + +pci:v00001166d00000213sv00001734sd00001012* + ID_PRODUCT_FROM_DATABASE=PRIMERGY RX/TX series onboard IDE + +pci:v00001166d00000214* + ID_PRODUCT_FROM_DATABASE=BCM5785 [HT1000] IDE + +pci:v00001166d00000214sv00001028sd00000205* + ID_PRODUCT_FROM_DATABASE=PowerEdge 2970 HT1000 IDE + +pci:v00001166d00000217* + ID_PRODUCT_FROM_DATABASE=CSB6 IDE Controller + +pci:v00001166d00000217sv00001028sd00004134* + ID_PRODUCT_FROM_DATABASE=Poweredge SC600 + +pci:v00001166d0000021B* + ID_PRODUCT_FROM_DATABASE=HT1100 HD Audio + +pci:v00001166d00000220* + ID_PRODUCT_FROM_DATABASE=OSB4/CSB5 OHCI USB Controller + +pci:v00001166d00000220sv00004C53sd00001080* + ID_PRODUCT_FROM_DATABASE=CT8 mainboard + +pci:v00001166d00000221* + ID_PRODUCT_FROM_DATABASE=CSB6 OHCI USB Controller + +pci:v00001166d00000221sv00001734sd00001012* + ID_PRODUCT_FROM_DATABASE=PRIMERGY RX/TX series onboard OHCI + +pci:v00001166d00000223* + ID_PRODUCT_FROM_DATABASE=BCM5785 [HT1000] USB + +pci:v00001166d00000223sv00001028sd00000205* + ID_PRODUCT_FROM_DATABASE=PowerEdge 2970 HT1000 USB Controller + +pci:v00001166d00000223sv00001028sd0000020B* + ID_PRODUCT_FROM_DATABASE=PowerEdge T605 HT1000 USB Controller + +pci:v00001166d00000225* + ID_PRODUCT_FROM_DATABASE=CSB5 LPC bridge + +pci:v00001166d00000227* + ID_PRODUCT_FROM_DATABASE=GCLE-2 Host Bridge + +pci:v00001166d00000227sv00001734sd00001012* + ID_PRODUCT_FROM_DATABASE=PRIMERGY RX/TX series + +pci:v00001166d00000230* + ID_PRODUCT_FROM_DATABASE=CSB5 LPC bridge + +pci:v00001166d00000230sv00004C53sd00001080* + ID_PRODUCT_FROM_DATABASE=CT8 mainboard + +pci:v00001166d00000234* + ID_PRODUCT_FROM_DATABASE=BCM5785 [HT1000] LPC + +pci:v00001166d00000234sv00001028sd00000205* + ID_PRODUCT_FROM_DATABASE=PowerEdge 2970 HT1000 LPC + +pci:v00001166d00000234sv00001028sd0000020B* + ID_PRODUCT_FROM_DATABASE=PowerEdge T605 HT1000 LPC + +pci:v00001166d00000235* + ID_PRODUCT_FROM_DATABASE=BCM5785 [HT1000] XIOAPIC0-2 + +pci:v00001166d00000238* + ID_PRODUCT_FROM_DATABASE=BCM5785 [HT1000] WDTimer + +pci:v00001166d00000240* + ID_PRODUCT_FROM_DATABASE=K2 SATA + +pci:v00001166d00000241* + ID_PRODUCT_FROM_DATABASE=RAIDCore RC4000 + +pci:v00001166d00000242* + ID_PRODUCT_FROM_DATABASE=RAIDCore BC4000 + +pci:v00001166d0000024A* + ID_PRODUCT_FROM_DATABASE=BCM5785 [HT1000] SATA (Native SATA Mode) + +pci:v00001166d0000024Asv00001028sd0000020B* + ID_PRODUCT_FROM_DATABASE=PowerEdge T605 onboard SATA Controller + +pci:v00001166d0000024B* + ID_PRODUCT_FROM_DATABASE=BCM5785 [HT1000] SATA (PATA/IDE Mode) + +pci:v00001166d0000024Bsv00001028sd00000205* + ID_PRODUCT_FROM_DATABASE=PowerEdge 2970 HT1000 SATA controller + +pci:v00001166d00000406* + ID_PRODUCT_FROM_DATABASE=HT1100 PCI-X Bridge + +pci:v00001166d00000408* + ID_PRODUCT_FROM_DATABASE=HT1100 Legacy Device + +pci:v00001166d0000040A* + ID_PRODUCT_FROM_DATABASE=HT1100 ISA-LPC Bridge + +pci:v00001166d0000040Asv00001028sd00000223* + ID_PRODUCT_FROM_DATABASE=PowerEdge R905 HT1100 ISA-LPC Bridge + +pci:v00001166d00000410* + ID_PRODUCT_FROM_DATABASE=HT1100 SATA Controller (Native SATA Mode) + +pci:v00001166d00000411* + ID_PRODUCT_FROM_DATABASE=HT1100 SATA Controller (PATA / IDE Mode) + +pci:v00001166d00000412* + ID_PRODUCT_FROM_DATABASE=HT1100 USB OHCI Controller + +pci:v00001166d00000414* + ID_PRODUCT_FROM_DATABASE=HT1100 USB EHCI Controller + +pci:v00001166d00000416* + ID_PRODUCT_FROM_DATABASE=HT1100 USB EHCI Controller (with Debug Port) + +pci:v00001166d00000420* + ID_PRODUCT_FROM_DATABASE=HT1100 PCI-Express Bridge + +pci:v00001166d00000421* + ID_PRODUCT_FROM_DATABASE=HT1100 SAS/SATA Controller + +pci:v00001166d00000422* + ID_PRODUCT_FROM_DATABASE=HT1100 PCI-Express Bridge + +pci:v00001167* + ID_VENDOR_FROM_DATABASE=Mutoh Industries Inc + +pci:v00001168* + ID_VENDOR_FROM_DATABASE=Thine Electronics Inc + +pci:v00001169* + ID_VENDOR_FROM_DATABASE=Centre for Development of Advanced Computing + +pci:v0000116A* + ID_VENDOR_FROM_DATABASE=Luminex Software, Inc. + +pci:v0000116Ad00006100* + ID_PRODUCT_FROM_DATABASE=Bus/Tag Channel + +pci:v0000116Ad00006800* + ID_PRODUCT_FROM_DATABASE=Escon Channel + +pci:v0000116Ad00007100* + ID_PRODUCT_FROM_DATABASE=Bus/Tag Channel + +pci:v0000116Ad00007800* + ID_PRODUCT_FROM_DATABASE=Escon Channel + +pci:v0000116B* + ID_VENDOR_FROM_DATABASE=Connectware Inc + +pci:v0000116C* + ID_VENDOR_FROM_DATABASE=Intelligent Resources Integrated Systems + +pci:v0000116D* + ID_VENDOR_FROM_DATABASE=Martin-Marietta + +pci:v0000116E* + ID_VENDOR_FROM_DATABASE=Electronics for Imaging + +pci:v0000116F* + ID_VENDOR_FROM_DATABASE=Workstation Technology + +pci:v00001170* + ID_VENDOR_FROM_DATABASE=Inventec Corporation + +pci:v00001171* + ID_VENDOR_FROM_DATABASE=Loughborough Sound Images Plc + +pci:v00001172* + ID_VENDOR_FROM_DATABASE=Altera Corporation + +pci:v00001173* + ID_VENDOR_FROM_DATABASE=Adobe Systems, Inc + +pci:v00001174* + ID_VENDOR_FROM_DATABASE=Bridgeport Machines + +pci:v00001175* + ID_VENDOR_FROM_DATABASE=Mitron Computer Inc. + +pci:v00001176* + ID_VENDOR_FROM_DATABASE=SBE Incorporated + +pci:v00001177* + ID_VENDOR_FROM_DATABASE=Silicon Engineering + +pci:v00001178* + ID_VENDOR_FROM_DATABASE=Alfa, Inc. + +pci:v00001178d0000AFA1* + ID_PRODUCT_FROM_DATABASE=Fast Ethernet Adapter + +pci:v00001179* + ID_VENDOR_FROM_DATABASE=Toshiba America Info Systems + +pci:v00001179d00000102* + ID_PRODUCT_FROM_DATABASE=Extended IDE Controller + +pci:v00001179d00000103* + ID_PRODUCT_FROM_DATABASE=EX-IDE Type-B + +pci:v00001179d00000404* + ID_PRODUCT_FROM_DATABASE=DVD Decoder card + +pci:v00001179d00000406* + ID_PRODUCT_FROM_DATABASE=Tecra Video Capture device + +pci:v00001179d00000407* + ID_PRODUCT_FROM_DATABASE=DVD Decoder card (Version 2) + +pci:v00001179d00000601* + ID_PRODUCT_FROM_DATABASE=CPU to PCI bridge + +pci:v00001179d00000601sv00001179sd00000001* + ID_PRODUCT_FROM_DATABASE=Satellite Pro + +pci:v00001179d00000602* + ID_PRODUCT_FROM_DATABASE=PCI to ISA bridge + +pci:v00001179d00000603* + ID_PRODUCT_FROM_DATABASE=ToPIC95 PCI to CardBus Bridge for Notebooks + +pci:v00001179d00000604* + ID_PRODUCT_FROM_DATABASE=PCI-Docking Host bridge + +pci:v00001179d0000060A* + ID_PRODUCT_FROM_DATABASE=ToPIC95 + +pci:v00001179d0000060Asv00001179sd00000001* + ID_PRODUCT_FROM_DATABASE=Satellite Pro + +pci:v00001179d0000060F* + ID_PRODUCT_FROM_DATABASE=ToPIC97 + +pci:v00001179d0000060Fsv00001179sd00000001* + ID_PRODUCT_FROM_DATABASE=Satellite 4010 + +pci:v00001179d00000617* + ID_PRODUCT_FROM_DATABASE=ToPIC100 PCI to Cardbus Bridge with ZV Support + +pci:v00001179d00000618* + ID_PRODUCT_FROM_DATABASE=CPU to PCI and PCI to ISA bridge + +pci:v00001179d00000701* + ID_PRODUCT_FROM_DATABASE=FIR Port Type-O + +pci:v00001179d00000804* + ID_PRODUCT_FROM_DATABASE=TC6371AF SmartMedia Controller + +pci:v00001179d00000805* + ID_PRODUCT_FROM_DATABASE=SD TypA Controller + +pci:v00001179d00000D01* + ID_PRODUCT_FROM_DATABASE=FIR Port Type-DO + +pci:v00001179d00000D01sv00001179sd00000001* + ID_PRODUCT_FROM_DATABASE=FIR Port Type-DO + +pci:v0000117A* + ID_VENDOR_FROM_DATABASE=A-Trend Technology + +pci:v0000117B* + ID_VENDOR_FROM_DATABASE=L G Electronics, Inc. + +pci:v0000117C* + ID_VENDOR_FROM_DATABASE=ATTO Technology, Inc. + +pci:v0000117Cd0000002C* + ID_PRODUCT_FROM_DATABASE=SAS RAID Adapter + +pci:v0000117Cd00000030* + ID_PRODUCT_FROM_DATABASE=Ultra320 SCSI Host Adapter + +pci:v0000117Cd00000030sv0000117Csd00008013* + ID_PRODUCT_FROM_DATABASE=ExpressPCI UL4D + +pci:v0000117Cd00000030sv0000117Csd00008014* + ID_PRODUCT_FROM_DATABASE=ExpressPCI UL4S + +pci:v0000117Cd00000030sv0000117Csd00008027* + ID_PRODUCT_FROM_DATABASE=ExpressPCI UL5D + +pci:v0000117Cd00000030sv0000117Csd0000802F* + ID_PRODUCT_FROM_DATABASE=ExpressPCI UL5D Low Profile + +pci:v0000117Cd00000033* + ID_PRODUCT_FROM_DATABASE=SAS Adapter + +pci:v0000117D* + ID_VENDOR_FROM_DATABASE=Becton & Dickinson + +pci:v0000117E* + ID_VENDOR_FROM_DATABASE=T/R Systems + +pci:v0000117F* + ID_VENDOR_FROM_DATABASE=Integrated Circuit Systems + +pci:v00001180* + ID_VENDOR_FROM_DATABASE=Ricoh Co Ltd + +pci:v00001180d00000465* + ID_PRODUCT_FROM_DATABASE=RL5c465 + +pci:v00001180d00000466* + ID_PRODUCT_FROM_DATABASE=RL5c466 + +pci:v00001180d00000475* + ID_PRODUCT_FROM_DATABASE=RL5c475 + +pci:v00001180d00000475sv0000144Dsd0000C006* + ID_PRODUCT_FROM_DATABASE=vpr Matrix 170B4 CardBus bridge + +pci:v00001180d00000476* + ID_PRODUCT_FROM_DATABASE=RL5c476 II + +pci:v00001180d00000476sv00001014sd00000185* + ID_PRODUCT_FROM_DATABASE=ThinkPad A/T/X Series + +pci:v00001180d00000476sv00001014sd0000056C* + ID_PRODUCT_FROM_DATABASE=ThinkPad Z60t + +pci:v00001180d00000476sv00001028sd0000014F* + ID_PRODUCT_FROM_DATABASE=Latitude X300 laptop + +pci:v00001180d00000476sv00001028sd00000188* + ID_PRODUCT_FROM_DATABASE=Inspiron 6000 laptop + +pci:v00001180d00000476sv0000103Csd000030C0* + ID_PRODUCT_FROM_DATABASE=Compaq 6710b + +pci:v00001180d00000476sv0000103Csd000030C1* + ID_PRODUCT_FROM_DATABASE=Compaq 6910p + +pci:v00001180d00000476sv00001043sd00001237* + ID_PRODUCT_FROM_DATABASE=A6J-Q008 + +pci:v00001180d00000476sv00001043sd00001967* + ID_PRODUCT_FROM_DATABASE=V6800V + +pci:v00001180d00000476sv00001043sd00001987* + ID_PRODUCT_FROM_DATABASE=Asus A4K and Z81K notebooks, possibly others ( mid-2005 machines ) + +pci:v00001180d00000476sv0000104Dsd000080DF* + ID_PRODUCT_FROM_DATABASE=Vaio PCG-FX403 + +pci:v00001180d00000476sv0000104Dsd000080E7* + ID_PRODUCT_FROM_DATABASE=VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP + +pci:v00001180d00000476sv0000104Dsd0000814E* + ID_PRODUCT_FROM_DATABASE=VAIO GRZ390Z + +pci:v00001180d00000476sv000010F7sd00008338* + ID_PRODUCT_FROM_DATABASE=Panasonic CF-Y5 laptop + +pci:v00001180d00000476sv0000144Dsd0000C005* + ID_PRODUCT_FROM_DATABASE=X10 Laptop + +pci:v00001180d00000476sv0000144Dsd0000C00C* + ID_PRODUCT_FROM_DATABASE=P30/P35 notebook + +pci:v00001180d00000476sv000014EFsd00000220* + ID_PRODUCT_FROM_DATABASE=PCD-RP-220S + +pci:v00001180d00000476sv000017AAsd0000201C* + ID_PRODUCT_FROM_DATABASE=ThinkPad X60s + +pci:v00001180d00000476sv000017AAsd000020C4* + ID_PRODUCT_FROM_DATABASE=ThinkPad T61 + +pci:v00001180d00000477* + ID_PRODUCT_FROM_DATABASE=RL5c477 + +pci:v00001180d00000478* + ID_PRODUCT_FROM_DATABASE=RL5c478 + +pci:v00001180d00000478sv00001014sd00000184* + ID_PRODUCT_FROM_DATABASE=ThinkPad A30p + +pci:v00001180d00000511* + ID_PRODUCT_FROM_DATABASE=R5C511 + +pci:v00001180d00000522* + ID_PRODUCT_FROM_DATABASE=R5C522 IEEE 1394 Controller + +pci:v00001180d00000522sv00001014sd000001CF* + ID_PRODUCT_FROM_DATABASE=ThinkPad A30p + +pci:v00001180d00000522sv00001043sd00001967* + ID_PRODUCT_FROM_DATABASE=V6800V + +pci:v00001180d00000551* + ID_PRODUCT_FROM_DATABASE=R5C551 IEEE 1394 Controller + +pci:v00001180d00000551sv0000144Dsd0000C006* + ID_PRODUCT_FROM_DATABASE=vpr Matrix 170B4 + +pci:v00001180d00000552* + ID_PRODUCT_FROM_DATABASE=R5C552 IEEE 1394 Controller + +pci:v00001180d00000552sv00001014sd00000511* + ID_PRODUCT_FROM_DATABASE=ThinkPad A/T/X Series + +pci:v00001180d00000552sv00001028sd0000014F* + ID_PRODUCT_FROM_DATABASE=Latitude X300 laptop + +pci:v00001180d00000552sv00001028sd00000188* + ID_PRODUCT_FROM_DATABASE=Inspiron 6000 laptop + +pci:v00001180d00000552sv00001043sd00001237* + ID_PRODUCT_FROM_DATABASE=A6J-Q008 + +pci:v00001180d00000552sv0000144Dsd0000C005* + ID_PRODUCT_FROM_DATABASE=X10 Laptop + +pci:v00001180d00000552sv0000144Dsd0000C00C* + ID_PRODUCT_FROM_DATABASE=P30/P35 notebook + +pci:v00001180d00000552sv000017AAsd0000201E* + ID_PRODUCT_FROM_DATABASE=ThinkPad X60s + +pci:v00001180d00000554* + ID_PRODUCT_FROM_DATABASE=R5C554 + +pci:v00001180d00000575* + ID_PRODUCT_FROM_DATABASE=R5C575 SD Bus Host Adapter + +pci:v00001180d00000576* + ID_PRODUCT_FROM_DATABASE=R5C576 SD Bus Host Adapter + +pci:v00001180d00000592* + ID_PRODUCT_FROM_DATABASE=R5C592 Memory Stick Bus Host Adapter + +pci:v00001180d00000592sv00001025sd00000121* + ID_PRODUCT_FROM_DATABASE=Aspire 5920G + +pci:v00001180d00000592sv00001028sd000001D7* + ID_PRODUCT_FROM_DATABASE=XPS M1210 + +pci:v00001180d00000592sv00001028sd000001F3* + ID_PRODUCT_FROM_DATABASE=Inspiron 1420 + +pci:v00001180d00000592sv0000103Csd000030B5* + ID_PRODUCT_FROM_DATABASE=Presario V3242AU + +pci:v00001180d00000592sv0000103Csd000030B7* + ID_PRODUCT_FROM_DATABASE=Presario V6133CL + +pci:v00001180d00000592sv0000103Csd000030CC* + ID_PRODUCT_FROM_DATABASE=Pavilion dv6700 + +pci:v00001180d00000592sv00001043sd00001237* + ID_PRODUCT_FROM_DATABASE=A6J-Q008 + +pci:v00001180d00000592sv00001043sd00001967* + ID_PRODUCT_FROM_DATABASE=V6800V + +pci:v00001180d00000592sv0000144Dsd0000C018* + ID_PRODUCT_FROM_DATABASE=X20 IV + +pci:v00001180d00000592sv000017AAsd000020CA* + ID_PRODUCT_FROM_DATABASE=ThinkPad T61 + +pci:v00001180d00000811* + ID_PRODUCT_FROM_DATABASE=R5C811 + +pci:v00001180d00000822* + ID_PRODUCT_FROM_DATABASE=R5C822 SD/SDIO/MMC/MS/MSPro Host Adapter + +pci:v00001180d00000822sv00001014sd00000556* + ID_PRODUCT_FROM_DATABASE=ThinkPad X60s / Z60t + +pci:v00001180d00000822sv00001014sd00000598* + ID_PRODUCT_FROM_DATABASE=ThinkPad Z60m + +pci:v00001180d00000822sv00001025sd00000121* + ID_PRODUCT_FROM_DATABASE=Aspire 5920G + +pci:v00001180d00000822sv00001028sd00000188* + ID_PRODUCT_FROM_DATABASE=Inspiron 6000 laptop + +pci:v00001180d00000822sv00001028sd000001A2* + ID_PRODUCT_FROM_DATABASE=Inspiron 9200 + +pci:v00001180d00000822sv00001028sd000001D7* + ID_PRODUCT_FROM_DATABASE=XPS M1210 + +pci:v00001180d00000822sv00001028sd000001F3* + ID_PRODUCT_FROM_DATABASE=Inspiron 1420 + +pci:v00001180d00000822sv0000103Csd000003B5* + ID_PRODUCT_FROM_DATABASE=Presario V3242AU + +pci:v00001180d00000822sv0000103Csd000030B7* + ID_PRODUCT_FROM_DATABASE=Presario V6133CL + +pci:v00001180d00000822sv0000103Csd000030C1* + ID_PRODUCT_FROM_DATABASE=Compaq 6910p + +pci:v00001180d00000822sv0000103Csd000030CC* + ID_PRODUCT_FROM_DATABASE=Pavilion dv6700 + +pci:v00001180d00000822sv00001043sd00001237* + ID_PRODUCT_FROM_DATABASE=A6J-Q008 + +pci:v00001180d00000822sv00001043sd00001967* + ID_PRODUCT_FROM_DATABASE=ASUS V6800V + +pci:v00001180d00000822sv000010F7sd00008338* + ID_PRODUCT_FROM_DATABASE=Panasonic CF-Y5 laptop + +pci:v00001180d00000822sv0000144Dsd0000C018* + ID_PRODUCT_FROM_DATABASE=X20 IV + +pci:v00001180d00000822sv000017AAsd0000201D* + ID_PRODUCT_FROM_DATABASE=ThinkPad X60s + +pci:v00001180d00000822sv000017AAsd000020C7* + ID_PRODUCT_FROM_DATABASE=ThinkPad T61 + +pci:v00001180d00000832* + ID_PRODUCT_FROM_DATABASE=R5C832 IEEE 1394 Controller + +pci:v00001180d00000832sv00001025sd00000121* + ID_PRODUCT_FROM_DATABASE=Aspire 5920G + +pci:v00001180d00000832sv00001028sd000001D7* + ID_PRODUCT_FROM_DATABASE=XPS M1210 + +pci:v00001180d00000832sv00001028sd000001F3* + ID_PRODUCT_FROM_DATABASE=Inspiron 1420 + +pci:v00001180d00000832sv0000103Csd000030B5* + ID_PRODUCT_FROM_DATABASE=Presario V3242AU + +pci:v00001180d00000832sv0000103Csd000030B7* + ID_PRODUCT_FROM_DATABASE=Presario V6133CL + +pci:v00001180d00000832sv0000103Csd000030C1* + ID_PRODUCT_FROM_DATABASE=Compaq 6910p + +pci:v00001180d00000832sv0000103Csd000030CC* + ID_PRODUCT_FROM_DATABASE=Pavilion dv6700 + +pci:v00001180d00000841* + ID_PRODUCT_FROM_DATABASE=R5C841 CardBus/SD/SDIO/MMC/MS/MSPro/xD/IEEE1394 + +pci:v00001180d00000843* + ID_PRODUCT_FROM_DATABASE=R5C843 MMC Host Controller + +pci:v00001180d00000843sv00001025sd00000121* + ID_PRODUCT_FROM_DATABASE=Aspire 5920G + +pci:v00001180d00000843sv00001028sd000001D7* + ID_PRODUCT_FROM_DATABASE=XPS M1210 + +pci:v00001180d00000843sv00001028sd000001F3* + ID_PRODUCT_FROM_DATABASE=Inspiron 1420 + +pci:v00001180d00000843sv00001028sd000001F5* + ID_PRODUCT_FROM_DATABASE=Dell Inspiron 1501 + +pci:v00001180d00000843sv00001028sd0000024F* + ID_PRODUCT_FROM_DATABASE=Dell Latitude e6500 + +pci:v00001180d00000843sv0000103Csd000003B5* + ID_PRODUCT_FROM_DATABASE=Presario V3242AU + +pci:v00001180d00000843sv0000103Csd000030B7* + ID_PRODUCT_FROM_DATABASE=Presario V6133CL + +pci:v00001180d00000843sv00001183sd00000843* + ID_PRODUCT_FROM_DATABASE=Alienware Aurora m9700 + +pci:v00001180d00000852* + ID_PRODUCT_FROM_DATABASE=xD-Picture Card Controller + +pci:v00001180d00000852sv00001025sd00000121* + ID_PRODUCT_FROM_DATABASE=Aspire 5920G + +pci:v00001180d00000852sv00001028sd000001F3* + ID_PRODUCT_FROM_DATABASE=Inspiron 1420 + +pci:v00001180d00000852sv0000103Csd000030B5* + ID_PRODUCT_FROM_DATABASE=Presario V3242AU + +pci:v00001180d00000852sv0000103Csd000030B7* + ID_PRODUCT_FROM_DATABASE=Presario V6133CL + +pci:v00001180d00000852sv0000103Csd000030CC* + ID_PRODUCT_FROM_DATABASE=Pavilion dv6700 + +pci:v00001180d00000852sv00001043sd00001967* + ID_PRODUCT_FROM_DATABASE=V6800V + +pci:v00001180d00000852sv00001180sd00000852* + ID_PRODUCT_FROM_DATABASE=Pavilion 2410us + +pci:v00001180d00000852sv00001324sd000010CF* + ID_PRODUCT_FROM_DATABASE=P7120 + +pci:v00001180d0000E230* + ID_PRODUCT_FROM_DATABASE=R5U2xx (R5U230 / R5U231 / R5U241) [Memory Stick Host Controller] + +pci:v00001180d0000E476* + ID_PRODUCT_FROM_DATABASE=CardBus bridge + +pci:v00001180d0000E476sv00001028sd0000040A* + ID_PRODUCT_FROM_DATABASE=Latitude E6410 + +pci:v00001180d0000E476sv00001028sd0000040B* + ID_PRODUCT_FROM_DATABASE=Latitude E6510 + +pci:v00001180d0000E822* + ID_PRODUCT_FROM_DATABASE=MMC/SD Host Controller + +pci:v00001180d0000E822sv00001028sd0000040A* + ID_PRODUCT_FROM_DATABASE=Latitude E6410 + +pci:v00001180d0000E822sv00001028sd0000040B* + ID_PRODUCT_FROM_DATABASE=Latitude E6510 + +pci:v00001180d0000E823* + ID_PRODUCT_FROM_DATABASE=PCIe SDXC/MMC Host Controller + +pci:v00001180d0000E832* + ID_PRODUCT_FROM_DATABASE=R5C832 PCIe IEEE 1394 Controller + +pci:v00001180d0000E832sv00001028sd0000040A* + ID_PRODUCT_FROM_DATABASE=Latitude E6410 + +pci:v00001180d0000E832sv00001028sd0000040B* + ID_PRODUCT_FROM_DATABASE=Latitude E6510 + +pci:v00001180d0000E852* + ID_PRODUCT_FROM_DATABASE=PCIe xD-Picture Card Controller + +pci:v00001181* + ID_VENDOR_FROM_DATABASE=Telmatics International + +pci:v00001183* + ID_VENDOR_FROM_DATABASE=Fujikura Ltd + +pci:v00001184* + ID_VENDOR_FROM_DATABASE=Forks Inc + +pci:v00001185* + ID_VENDOR_FROM_DATABASE=Dataworld International Ltd + +pci:v00001186* + ID_VENDOR_FROM_DATABASE=D-Link System Inc + +pci:v00001186d00000100* + ID_PRODUCT_FROM_DATABASE=DC21041 + +pci:v00001186d00001002* + ID_PRODUCT_FROM_DATABASE=DL10050 Sundance Ethernet + +pci:v00001186d00001002sv00001186sd00001002* + ID_PRODUCT_FROM_DATABASE=DFE-550TX/FX + +pci:v00001186d00001002sv00001186sd00001012* + ID_PRODUCT_FROM_DATABASE=DFE-580TX + +pci:v00001186d00001025* + ID_PRODUCT_FROM_DATABASE=AirPlus Xtreme G DWL-G650 Adapter + +pci:v00001186d00001026* + ID_PRODUCT_FROM_DATABASE=AirXpert DWL-AG650 Wireless Cardbus Adapter + +pci:v00001186d00001043* + ID_PRODUCT_FROM_DATABASE=AirXpert DWL-AG650 Wireless Cardbus Adapter + +pci:v00001186d00001300* + ID_PRODUCT_FROM_DATABASE=RTL8139 Ethernet + +pci:v00001186d00001300sv00001186sd00001300* + ID_PRODUCT_FROM_DATABASE=DFE-538TX 10/100 Ethernet Adapter + +pci:v00001186d00001300sv00001186sd00001301* + ID_PRODUCT_FROM_DATABASE=DFE-530TX+ 10/100 Ethernet Adapter + +pci:v00001186d00001300sv00001186sd00001303* + ID_PRODUCT_FROM_DATABASE=DFE-528TX 10/100 Fast Ethernet PCI Adapter + +pci:v00001186d00001340* + ID_PRODUCT_FROM_DATABASE=DFE-690TXD CardBus PC Card + +pci:v00001186d00001405* + ID_PRODUCT_FROM_DATABASE=DFE-520TX Fast Ethernet PCI Adapter + +pci:v00001186d00001540* + ID_PRODUCT_FROM_DATABASE=DFE-680TX + +pci:v00001186d00001541* + ID_PRODUCT_FROM_DATABASE=DFE-680TXD CardBus PC Card + +pci:v00001186d00001561* + ID_PRODUCT_FROM_DATABASE=DRP-32TXD Cardbus PC Card + +pci:v00001186d00003300* + ID_PRODUCT_FROM_DATABASE=DWL-510 / DWL-610 802.11b [Realtek RTL8180L] + +pci:v00001186d00003300sv00001186sd00003300* + ID_PRODUCT_FROM_DATABASE=DWL-610 Wireless Cardbus Adapter + +pci:v00001186d00003300sv00001186sd00003301* + ID_PRODUCT_FROM_DATABASE=DWL-510 Wireless PCI Adapter + +pci:v00001186d00003A03* + ID_PRODUCT_FROM_DATABASE=AirPro DWL-A650 Wireless Cardbus Adapter(rev.B) + +pci:v00001186d00003A04* + ID_PRODUCT_FROM_DATABASE=AirPro DWL-AB650 Multimode Wireless Cardbus Adapter + +pci:v00001186d00003A05* + ID_PRODUCT_FROM_DATABASE=AirPro DWL-AB520 Multimode Wireless PCI Adapter + +pci:v00001186d00003A07* + ID_PRODUCT_FROM_DATABASE=AirXpert DWL-AG650 Wireless Cardbus Adapter + +pci:v00001186d00003A08* + ID_PRODUCT_FROM_DATABASE=AirXpert DWL-AG520 Wireless PCI Adapter + +pci:v00001186d00003A10* + ID_PRODUCT_FROM_DATABASE=AirXpert DWL-AG650 Wireless Cardbus Adapter(rev.B) + +pci:v00001186d00003A11* + ID_PRODUCT_FROM_DATABASE=AirXpert DWL-AG520 Wireless PCI Adapter(rev.B) + +pci:v00001186d00003A12* + ID_PRODUCT_FROM_DATABASE=AirPlus DWL-G650 Wireless Cardbus Adapter(rev.C) + +pci:v00001186d00003A63* + ID_PRODUCT_FROM_DATABASE=AirXpert DWL-AG660 Wireless Cardbus Adapter + +pci:v00001186d00003A70* + ID_PRODUCT_FROM_DATABASE=DWA-556 Xtreme N PCI Express Desktop Adapter + +pci:v00001186d00003C00* + ID_PRODUCT_FROM_DATABASE=D-link DWL-G650X + +pci:v00001186d00003C09* + ID_PRODUCT_FROM_DATABASE=AirPlus G DWL-G510 + +pci:v00001186d00004000* + ID_PRODUCT_FROM_DATABASE=DL2000-based Gigabit Ethernet + +pci:v00001186d00004001* + ID_PRODUCT_FROM_DATABASE=DGE-550SX PCI-X Gigabit Ethernet Adapter + +pci:v00001186d00004300* + ID_PRODUCT_FROM_DATABASE=DGE-528T Gigabit Ethernet Adapter + +pci:v00001186d00004300sv00001186sd00004B10* + ID_PRODUCT_FROM_DATABASE=DGE-560T PCI Express (x1) Gigabit Ethernet Adapter + +pci:v00001186d00004302* + ID_PRODUCT_FROM_DATABASE=DGE-530T Gigabit Ethernet Adapter (rev.C1) [Realtek RTL8169] + +pci:v00001186d00004800* + ID_PRODUCT_FROM_DATABASE=DGE-530T Gigabit Ethernet Adapter (rev 11) + +pci:v00001186d00004B00* + ID_PRODUCT_FROM_DATABASE=DGE-560T PCI Express Gigabit Ethernet Adapter + +pci:v00001186d00004B01* + ID_PRODUCT_FROM_DATABASE=DGE-530T Gigabit Ethernet Adapter (rev 11) + +pci:v00001186d00004B02* + ID_PRODUCT_FROM_DATABASE=DGE-560SX PCI Express Gigabit Ethernet Adapter + +pci:v00001186d00004B03* + ID_PRODUCT_FROM_DATABASE=DGE-550T Gigabit Ethernet Adapter V.B1 + +pci:v00001186d00004C00* + ID_PRODUCT_FROM_DATABASE=Gigabit Ethernet Adapter + +pci:v00001186d00004C00sv00001186sd00004C00* + ID_PRODUCT_FROM_DATABASE=DGE-530T Gigabit Ethernet Adapter + +pci:v00001186d00008400* + ID_PRODUCT_FROM_DATABASE=D-Link DWL-650+ CardBus PC Card + +pci:v00001187* + ID_VENDOR_FROM_DATABASE=Advanced Technology Laboratories, Inc. + +pci:v00001188* + ID_VENDOR_FROM_DATABASE=Shima Seiki Manufacturing Ltd. + +pci:v00001189* + ID_VENDOR_FROM_DATABASE=Matsushita Electronics Co Ltd + +pci:v0000118A* + ID_VENDOR_FROM_DATABASE=Hilevel Technology + +pci:v0000118B* + ID_VENDOR_FROM_DATABASE=Hypertec Pty Limited + +pci:v0000118C* + ID_VENDOR_FROM_DATABASE=Corollary, Inc + +pci:v0000118Cd00000014* + ID_PRODUCT_FROM_DATABASE=PCIB [C-bus II to PCI bus host bridge chip] + +pci:v0000118Cd00001117* + ID_PRODUCT_FROM_DATABASE=Intel 8-way XEON Profusion Chipset [Cache Coherency Filter] + +pci:v0000118D* + ID_VENDOR_FROM_DATABASE=BitFlow Inc + +pci:v0000118Dd00000001* + ID_PRODUCT_FROM_DATABASE=Raptor-PCI framegrabber + +pci:v0000118Dd00000012* + ID_PRODUCT_FROM_DATABASE=Model 12 Road Runner Frame Grabber + +pci:v0000118Dd00000014* + ID_PRODUCT_FROM_DATABASE=Model 14 Road Runner Frame Grabber + +pci:v0000118Dd00000024* + ID_PRODUCT_FROM_DATABASE=Model 24 Road Runner Frame Grabber + +pci:v0000118Dd00000044* + ID_PRODUCT_FROM_DATABASE=Model 44 Road Runner Frame Grabber + +pci:v0000118Dd00000112* + ID_PRODUCT_FROM_DATABASE=Model 12 Road Runner Frame Grabber + +pci:v0000118Dd00000114* + ID_PRODUCT_FROM_DATABASE=Model 14 Road Runner Frame Grabber + +pci:v0000118Dd00000124* + ID_PRODUCT_FROM_DATABASE=Model 24 Road Runner Frame Grabber + +pci:v0000118Dd00000144* + ID_PRODUCT_FROM_DATABASE=Model 44 Road Runner Frame Grabber + +pci:v0000118Dd00000212* + ID_PRODUCT_FROM_DATABASE=Model 12 Road Runner Frame Grabber + +pci:v0000118Dd00000214* + ID_PRODUCT_FROM_DATABASE=Model 14 Road Runner Frame Grabber + +pci:v0000118Dd00000224* + ID_PRODUCT_FROM_DATABASE=Model 24 Road Runner Frame Grabber + +pci:v0000118Dd00000244* + ID_PRODUCT_FROM_DATABASE=Model 44 Road Runner Frame Grabber + +pci:v0000118Dd00000312* + ID_PRODUCT_FROM_DATABASE=Model 12 Road Runner Frame Grabber + +pci:v0000118Dd00000314* + ID_PRODUCT_FROM_DATABASE=Model 14 Road Runner Frame Grabber + +pci:v0000118Dd00000324* + ID_PRODUCT_FROM_DATABASE=Model 24 Road Runner Frame Grabber + +pci:v0000118Dd00000344* + ID_PRODUCT_FROM_DATABASE=Model 44 Road Runner Frame Grabber + +pci:v0000118E* + ID_VENDOR_FROM_DATABASE=Hermstedt GmbH + +pci:v0000118F* + ID_VENDOR_FROM_DATABASE=Green Logic + +pci:v00001190* + ID_VENDOR_FROM_DATABASE=Tripace + +pci:v00001190d0000C731* + ID_PRODUCT_FROM_DATABASE=TP-910/920/940 PCI Ultra(Wide) SCSI Adapter + +pci:v00001191* + ID_VENDOR_FROM_DATABASE=Artop Electronic Corp + +pci:v00001191d00000003* + ID_PRODUCT_FROM_DATABASE=SCSI Cache Host Adapter + +pci:v00001191d00000004* + ID_PRODUCT_FROM_DATABASE=ATP8400 + +pci:v00001191d00000005* + ID_PRODUCT_FROM_DATABASE=ATP850UF + +pci:v00001191d00000006* + ID_PRODUCT_FROM_DATABASE=ATP860 NO-BIOS + +pci:v00001191d00000007* + ID_PRODUCT_FROM_DATABASE=ATP860 + +pci:v00001191d00000008* + ID_PRODUCT_FROM_DATABASE=ATP865 NO-ROM + +pci:v00001191d00000009* + ID_PRODUCT_FROM_DATABASE=ATP865 + +pci:v00001191d0000000A* + ID_PRODUCT_FROM_DATABASE=ATP867-A + +pci:v00001191d0000000B* + ID_PRODUCT_FROM_DATABASE=ATP867-B + +pci:v00001191d0000000D* + ID_PRODUCT_FROM_DATABASE=ATP8620 + +pci:v00001191d0000000E* + ID_PRODUCT_FROM_DATABASE=ATP8620 + +pci:v00001191d00008002* + ID_PRODUCT_FROM_DATABASE=AEC6710 SCSI-2 Host Adapter + +pci:v00001191d00008010* + ID_PRODUCT_FROM_DATABASE=AEC6712UW SCSI + +pci:v00001191d00008020* + ID_PRODUCT_FROM_DATABASE=AEC6712U SCSI + +pci:v00001191d00008030* + ID_PRODUCT_FROM_DATABASE=AEC6712S SCSI + +pci:v00001191d00008040* + ID_PRODUCT_FROM_DATABASE=AEC6712D SCSI + +pci:v00001191d00008050* + ID_PRODUCT_FROM_DATABASE=AEC6712SUW SCSI + +pci:v00001191d00008060* + ID_PRODUCT_FROM_DATABASE=AEC6712 SCSI + +pci:v00001191d00008080* + ID_PRODUCT_FROM_DATABASE=AEC67160 SCSI + +pci:v00001191d00008081* + ID_PRODUCT_FROM_DATABASE=AEC67160S SCSI + +pci:v00001191d0000808A* + ID_PRODUCT_FROM_DATABASE=AEC67162 2-ch. LVD SCSI + +pci:v00001192* + ID_VENDOR_FROM_DATABASE=Densan Company Ltd + +pci:v00001193* + ID_VENDOR_FROM_DATABASE=Zeitnet Inc. + +pci:v00001193d00000001* + ID_PRODUCT_FROM_DATABASE=1221 + +pci:v00001193d00000002* + ID_PRODUCT_FROM_DATABASE=1225 + +pci:v00001194* + ID_VENDOR_FROM_DATABASE=Toucan Technology + +pci:v00001195* + ID_VENDOR_FROM_DATABASE=Ratoc System Inc + +pci:v00001196* + ID_VENDOR_FROM_DATABASE=Hytec Electronics Ltd + +pci:v00001197* + ID_VENDOR_FROM_DATABASE=Gage Applied Sciences, Inc. + +pci:v00001197d0000010C* + ID_PRODUCT_FROM_DATABASE=CompuScope 82G 8bit 2GS/s Analog Input Card + +pci:v00001198* + ID_VENDOR_FROM_DATABASE=Lambda Systems Inc + +pci:v00001199* + ID_VENDOR_FROM_DATABASE=Attachmate Corporation + +pci:v00001199d00000101* + ID_PRODUCT_FROM_DATABASE=Advanced ISCA/PCI Adapter + +pci:v00001199d00006832* + ID_PRODUCT_FROM_DATABASE=Sierra Wireless MC8780 Device + +pci:v0000119A* + ID_VENDOR_FROM_DATABASE=Mind Share, Inc. + +pci:v0000119B* + ID_VENDOR_FROM_DATABASE=Omega Micro Inc. + +pci:v0000119Bd00001221* + ID_PRODUCT_FROM_DATABASE=82C092G + +pci:v0000119C* + ID_VENDOR_FROM_DATABASE=Information Technology Inst. + +pci:v0000119D* + ID_VENDOR_FROM_DATABASE=Bug, Inc. Sapporo Japan + +pci:v0000119E* + ID_VENDOR_FROM_DATABASE=Fujitsu Microelectronics Ltd. + +pci:v0000119Ed00000001* + ID_PRODUCT_FROM_DATABASE=FireStream 155 + +pci:v0000119Ed00000003* + ID_PRODUCT_FROM_DATABASE=FireStream 50 + +pci:v0000119F* + ID_VENDOR_FROM_DATABASE=Bull HN Information Systems + +pci:v000011A0* + ID_VENDOR_FROM_DATABASE=Convex Computer Corporation + +pci:v000011A1* + ID_VENDOR_FROM_DATABASE=Hamamatsu Photonics K.K. + +pci:v000011A2* + ID_VENDOR_FROM_DATABASE=Sierra Research and Technology + +pci:v000011A3* + ID_VENDOR_FROM_DATABASE=Deuretzbacher GmbH & Co. Eng. KG + +pci:v000011A4* + ID_VENDOR_FROM_DATABASE=Barco Graphics NV + +pci:v000011A5* + ID_VENDOR_FROM_DATABASE=Microunity Systems Eng. Inc + +pci:v000011A6* + ID_VENDOR_FROM_DATABASE=Pure Data Ltd. + +pci:v000011A7* + ID_VENDOR_FROM_DATABASE=Power Computing Corp. + +pci:v000011A8* + ID_VENDOR_FROM_DATABASE=Systech Corp. + +pci:v000011A9* + ID_VENDOR_FROM_DATABASE=InnoSys Inc. + +pci:v000011A9d00004240* + ID_PRODUCT_FROM_DATABASE=AMCC S933Q Intelligent Serial Card + +pci:v000011AA* + ID_VENDOR_FROM_DATABASE=Actel + +pci:v000011AB* + ID_VENDOR_FROM_DATABASE=Marvell Technology Group Ltd. + +pci:v000011ABd00000146* + ID_PRODUCT_FROM_DATABASE=GT-64010/64010A System Controller + +pci:v000011ABd00000F53* + ID_PRODUCT_FROM_DATABASE=88E6318 Link Street network controller + +pci:v000011ABd000011AB* + ID_PRODUCT_FROM_DATABASE=MV88SE614x SATA II PCI-E controller + +pci:v000011ABd0000138F* + ID_PRODUCT_FROM_DATABASE=W8300 802.11 Adapter (rev 07) + +pci:v000011ABd00001FA6* + ID_PRODUCT_FROM_DATABASE=Marvell W8300 802.11 Adapter + +pci:v000011ABd00001FA6sv00001186sd00003B08* + ID_PRODUCT_FROM_DATABASE=AirPlus G DWL-G630 Wireless Cardbus Adapter (rev.A1) + +pci:v000011ABd00001FA7* + ID_PRODUCT_FROM_DATABASE=88W8310 and 88W8000G [Libertas] 802.11g client chipset + +pci:v000011ABd00001FAA* + ID_PRODUCT_FROM_DATABASE=88w8335 [Libertas] 802.11b/g Wireless + +pci:v000011ABd00001FAAsv00001385sd00004E00* + ID_PRODUCT_FROM_DATABASE=WG511v2 54 Mbps Wireless PC Card + +pci:v000011ABd00001FAAsv00001385sd00006B00* + ID_PRODUCT_FROM_DATABASE=WG311v3 802.11g Wireless PCI Adapter + +pci:v000011ABd00001FAAsv00001737sd00000040* + ID_PRODUCT_FROM_DATABASE=WPC54G v5 802.11g Wireless-G Notebook Adapter + +pci:v000011ABd00002211* + ID_PRODUCT_FROM_DATABASE=88SB2211 PCI Express to PCI Bridge + +pci:v000011ABd00002A01* + ID_PRODUCT_FROM_DATABASE=88W8335 [Libertas] 802.11b/g Wireless + +pci:v000011ABd00002A02* + ID_PRODUCT_FROM_DATABASE=88W8361 [TopDog] 802.11n Wireless + +pci:v000011ABd00002A02sv000007D1sd00003B02* + ID_PRODUCT_FROM_DATABASE=DIR-615 rev. A1 Mini PCI Wireless Module + +pci:v000011ABd00002A02sv00001385sd00007C01* + ID_PRODUCT_FROM_DATABASE=WN511T RangeMax Next 300 Mbps Wireless Notebook Adapter + +pci:v000011ABd00002A02sv00001385sd00007E00* + ID_PRODUCT_FROM_DATABASE=WN311T RangeMax Next 300 Mbps Wireless PCI Adapter + +pci:v000011ABd00002A02sv00001799sd0000801B* + ID_PRODUCT_FROM_DATABASE=F5D8011 v2 802.11n N1 Wireless Notebook Card + +pci:v000011ABd00002A08* + ID_PRODUCT_FROM_DATABASE=88W8362e [TopDog] 802.11a/b/g/n Wireless + +pci:v000011ABd00002A0A* + ID_PRODUCT_FROM_DATABASE=88W8363 [TopDog] 802.11n Wireless + +pci:v000011ABd00002A0C* + ID_PRODUCT_FROM_DATABASE=88W8363 [TopDog] 802.11n Wireless + +pci:v000011ABd00002A24* + ID_PRODUCT_FROM_DATABASE=88W8363 [TopDog] 802.11n Wireless + +pci:v000011ABd00002A2B* + ID_PRODUCT_FROM_DATABASE=88W8687 [TopDog] 802.11b/g Wireless + +pci:v000011ABd00002A30* + ID_PRODUCT_FROM_DATABASE=88W8687 [TopDog] 802.11b/g Wireless + +pci:v000011ABd00002A40* + ID_PRODUCT_FROM_DATABASE=88W8366 [TopDog] 802.11n Wireless + +pci:v000011ABd00002A43* + ID_PRODUCT_FROM_DATABASE=88W8366 [TopDog] 802.11n Wireless + +pci:v000011ABd00004101* + ID_PRODUCT_FROM_DATABASE=OLPC Cafe Controller Secure Digital Controller + +pci:v000011ABd00004320* + ID_PRODUCT_FROM_DATABASE=88E8001 Gigabit Ethernet Controller + +pci:v000011ABd00004320sv00001019sd00000F38* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8001 Gigabit Ethernet Controller (ECS) + +pci:v000011ABd00004320sv00001019sd00008001* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8001 Gigabit Ethernet Controller (ECS) + +pci:v000011ABd00004320sv00001043sd0000173C* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8001 Gigabit Ethernet Controller (Asus) + +pci:v000011ABd00004320sv00001043sd0000811A* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8001 Gigabit Ethernet Controller (Asus) + +pci:v000011ABd00004320sv0000105Bsd00000C19* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8001 Gigabit Ethernet Controller (Foxconn) + +pci:v000011ABd00004320sv000010B8sd0000B452* + ID_PRODUCT_FROM_DATABASE=EZ Card 1000 (SMC9452TXV.2) + +pci:v000011ABd00004320sv000011ABsd00000121* + ID_PRODUCT_FROM_DATABASE=Marvell RDK-8001 + +pci:v000011ABd00004320sv000011ABsd00000321* + ID_PRODUCT_FROM_DATABASE=Marvell RDK-8003 + +pci:v000011ABd00004320sv000011ABsd00001021* + ID_PRODUCT_FROM_DATABASE=Marvell RDK-8010 + +pci:v000011ABd00004320sv000011ABsd00004320* + ID_PRODUCT_FROM_DATABASE=Marvell Yukon Gigabit Ethernet 10/100/1000Baset-T Constroller (Asus) + +pci:v000011ABd00004320sv000011ABsd00005021* + ID_PRODUCT_FROM_DATABASE=Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Controller (64 bit) + +pci:v000011ABd00004320sv000011ABsd00009521* + ID_PRODUCT_FROM_DATABASE=Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Controller (32 bit) + +pci:v000011ABd00004320sv00001458sd0000E000* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8001 Gigabit Ethernet Controller (Gigabyte) + +pci:v000011ABd00004320sv0000147Bsd00001406* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8001 Gigabit Ethernet Controller (Abit) + +pci:v000011ABd00004320sv000015D4sd00000047* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8001 Gigabit Ethernet Controller (Iwill) + +pci:v000011ABd00004320sv00001695sd00009025* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8001 Gigabit Ethernet Controller (Epox) + +pci:v000011ABd00004320sv000017F2sd00001C03* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8001 Gigabit Ethernet Controller (Albatron) + +pci:v000011ABd00004320sv0000270Fsd00002803* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8001 Gigabit Ethernet Controller (Chaintech) + +pci:v000011ABd00004340* + ID_PRODUCT_FROM_DATABASE=88E8021 PCI-X IPMI Gigabit Ethernet Controller + +pci:v000011ABd00004341* + ID_PRODUCT_FROM_DATABASE=88E8022 PCI-X IPMI Gigabit Ethernet Controller + +pci:v000011ABd00004342* + ID_PRODUCT_FROM_DATABASE=88E8061 PCI-E IPMI Gigabit Ethernet Controller + +pci:v000011ABd00004343* + ID_PRODUCT_FROM_DATABASE=88E8062 PCI-E IPMI Gigabit Ethernet Controller + +pci:v000011ABd00004344* + ID_PRODUCT_FROM_DATABASE=88E8021 PCI-X IPMI Gigabit Ethernet Controller + +pci:v000011ABd00004345* + ID_PRODUCT_FROM_DATABASE=88E8022 PCI-X IPMI Gigabit Ethernet Controller + +pci:v000011ABd00004346* + ID_PRODUCT_FROM_DATABASE=88E8061 PCI-E IPMI Gigabit Ethernet Controller + +pci:v000011ABd00004347* + ID_PRODUCT_FROM_DATABASE=88E8062 PCI-E IPMI Gigabit Ethernet Controller + +pci:v000011ABd00004347sv00004C53sd000010D0* + ID_PRODUCT_FROM_DATABASE=Telum ASLP10 PrAMC Gigabit Ethernet + +pci:v000011ABd00004350* + ID_PRODUCT_FROM_DATABASE=88E8035 PCI-E Fast Ethernet Controller + +pci:v000011ABd00004350sv00001179sd00000001* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8035 Fast Ethernet Controller (Toshiba) + +pci:v000011ABd00004350sv000011ABsd00003521* + ID_PRODUCT_FROM_DATABASE=Marvell RDK-8035 + +pci:v000011ABd00004350sv00001854sd0000000D* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8035 Fast Ethernet Controller (LGE) + +pci:v000011ABd00004350sv00001854sd0000000E* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8035 Fast Ethernet Controller (LGE) + +pci:v000011ABd00004350sv00001854sd0000000F* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8035 Fast Ethernet Controller (LGE) + +pci:v000011ABd00004350sv00001854sd00000011* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8035 Fast Ethernet Controller (LGE) + +pci:v000011ABd00004350sv00001854sd00000012* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8035 Fast Ethernet Controller (LGE) + +pci:v000011ABd00004350sv00001854sd00000016* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8035 Fast Ethernet Controller (LGE) + +pci:v000011ABd00004350sv00001854sd00000017* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8035 Fast Ethernet Controller (LGE) + +pci:v000011ABd00004350sv00001854sd00000018* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8035 Fast Ethernet Controller (LGE) + +pci:v000011ABd00004350sv00001854sd00000019* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8035 Fast Ethernet Controller (LGE) + +pci:v000011ABd00004350sv00001854sd0000001C* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8035 Fast Ethernet Controller (LGE) + +pci:v000011ABd00004350sv00001854sd0000001E* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8035 Fast Ethernet Controller (LGE) + +pci:v000011ABd00004350sv00001854sd00000020* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8035 Fast Ethernet Controller (LGE) + +pci:v000011ABd00004351* + ID_PRODUCT_FROM_DATABASE=88E8036 PCI-E Fast Ethernet Controller + +pci:v000011ABd00004351sv0000107Bsd00004009* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8036 Fast Ethernet Controller (Wistron) + +pci:v000011ABd00004351sv000010F7sd00008338* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8036 Fast Ethernet Controller (Panasonic) + +pci:v000011ABd00004351sv00001179sd00000001* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8036 Fast Ethernet Controller (Toshiba) + +pci:v000011ABd00004351sv00001179sd0000FF00* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8036 Fast Ethernet Controller (Compal) + +pci:v000011ABd00004351sv00001179sd0000FF10* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8036 Fast Ethernet Controller (Inventec) + +pci:v000011ABd00004351sv000011ABsd00003621* + ID_PRODUCT_FROM_DATABASE=Marvell RDK-8036 + +pci:v000011ABd00004351sv000013D1sd0000AC12* + ID_PRODUCT_FROM_DATABASE=Abocom EFE3K - 10/100 Ethernet Expresscard + +pci:v000011ABd00004351sv0000161Fsd0000203D* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8036 Fast Ethernet Controller (Arima) + +pci:v000011ABd00004351sv00001854sd0000000D* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8036 Fast Ethernet Controller (LGE) + +pci:v000011ABd00004351sv00001854sd0000000E* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8036 Fast Ethernet Controller (LGE) + +pci:v000011ABd00004351sv00001854sd0000000F* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8036 Fast Ethernet Controller (LGE) + +pci:v000011ABd00004351sv00001854sd00000011* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8036 Fast Ethernet Controller (LGE) + +pci:v000011ABd00004351sv00001854sd00000012* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8036 Fast Ethernet Controller (LGE) + +pci:v000011ABd00004351sv00001854sd00000016* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8036 Fast Ethernet Controller (LGE) + +pci:v000011ABd00004351sv00001854sd00000017* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8036 Fast Ethernet Controller (LGE) + +pci:v000011ABd00004351sv00001854sd00000018* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8036 Fast Ethernet Controller (LGE) + +pci:v000011ABd00004351sv00001854sd00000019* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8036 Fast Ethernet Controller (LGE) + +pci:v000011ABd00004351sv00001854sd0000001C* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8036 Fast Ethernet Controller (LGE) + +pci:v000011ABd00004351sv00001854sd0000001E* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8036 Fast Ethernet Controller (LGE) + +pci:v000011ABd00004351sv00001854sd00000020* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8036 Fast Ethernet Controller (LGE) + +pci:v000011ABd00004352* + ID_PRODUCT_FROM_DATABASE=88E8038 PCI-E Fast Ethernet Controller + +pci:v000011ABd00004353* + ID_PRODUCT_FROM_DATABASE=88E8039 PCI-E Fast Ethernet Controller + +pci:v000011ABd00004353sv0000104Dsd0000902D* + ID_PRODUCT_FROM_DATABASE=VAIO VGN-NR120E + +pci:v000011ABd00004354* + ID_PRODUCT_FROM_DATABASE=88E8040 PCI-E Fast Ethernet Controller + +pci:v000011ABd00004354sv0000144Dsd0000C072* + ID_PRODUCT_FROM_DATABASE=Notebook N150P + +pci:v000011ABd00004355* + ID_PRODUCT_FROM_DATABASE=88E8040T PCI-E Fast Ethernet Controller + +pci:v000011ABd00004355sv00001179sd0000FF50* + ID_PRODUCT_FROM_DATABASE=Satellite P305D-S8995E + +pci:v000011ABd00004356* + ID_PRODUCT_FROM_DATABASE=88EC033 PCI-E Fast Ethernet Controller + +pci:v000011ABd00004357* + ID_PRODUCT_FROM_DATABASE=88E8042 PCI-E Fast Ethernet Controller + +pci:v000011ABd0000435A* + ID_PRODUCT_FROM_DATABASE=88E8048 PCI-E Fast Ethernet Controller + +pci:v000011ABd00004360* + ID_PRODUCT_FROM_DATABASE=88E8052 PCI-E ASF Gigabit Ethernet Controller + +pci:v000011ABd00004360sv00001043sd00008134* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8052 Gigabit Ethernet Controller (Asus) + +pci:v000011ABd00004360sv0000107Bsd00004009* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8052 Gigabit Ethernet Controller (Wistron) + +pci:v000011ABd00004360sv000011ABsd00005221* + ID_PRODUCT_FROM_DATABASE=Marvell RDK-8052 + +pci:v000011ABd00004360sv00001458sd0000E000* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8052 Gigabit Ethernet Controller (Gigabyte) + +pci:v000011ABd00004360sv00001462sd0000052C* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8052 Gigabit Ethernet Controller (MSI) + +pci:v000011ABd00004360sv00001849sd00008052* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8052 Gigabit Ethernet Controller (ASRock) + +pci:v000011ABd00004360sv0000A0A0sd00000509* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8052 Gigabit Ethernet Controller (Aopen) + +pci:v000011ABd00004361* + ID_PRODUCT_FROM_DATABASE=88E8050 PCI-E ASF Gigabit Ethernet Controller + +pci:v000011ABd00004361sv0000107Bsd00003015* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8050 Gigabit Ethernet Controller (Gateway) + +pci:v000011ABd00004361sv000011ABsd00005021* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8050 Gigabit Ethernet Controller (Intel) + +pci:v000011ABd00004361sv00008086sd00003063* + ID_PRODUCT_FROM_DATABASE=D925XCVLK mainboard + +pci:v000011ABd00004361sv00008086sd00003439* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8050 Gigabit Ethernet Controller (Intel) + +pci:v000011ABd00004362* + ID_PRODUCT_FROM_DATABASE=88E8053 PCI-E Gigabit Ethernet Controller + +pci:v000011ABd00004362sv0000103Csd00002A0D* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (Asus) + +pci:v000011ABd00004362sv00001043sd00008142* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet controller PCIe (Asus) + +pci:v000011ABd00004362sv0000109Fsd00003197* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (Trigem) + +pci:v000011ABd00004362sv000010F7sd00008338* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (Panasonic) + +pci:v000011ABd00004362sv000010FDsd0000A430* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (SOYO) + +pci:v000011ABd00004362sv00001179sd00000001* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (Toshiba) + +pci:v000011ABd00004362sv00001179sd0000FF00* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (Compal) + +pci:v000011ABd00004362sv00001179sd0000FF10* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (Inventec) + +pci:v000011ABd00004362sv000011ABsd00005321* + ID_PRODUCT_FROM_DATABASE=Marvell RDK-8053 + +pci:v000011ABd00004362sv00001297sd0000C240* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (Shuttle) + +pci:v000011ABd00004362sv00001297sd0000C241* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (Shuttle) + +pci:v000011ABd00004362sv00001297sd0000C242* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (Shuttle) + +pci:v000011ABd00004362sv00001297sd0000C243* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (Shuttle) + +pci:v000011ABd00004362sv00001297sd0000C244* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (Shuttle) + +pci:v000011ABd00004362sv000013D1sd0000AC11* + ID_PRODUCT_FROM_DATABASE=EGE5K - Giga Ethernet Expresscard + +pci:v000011ABd00004362sv00001458sd0000E000* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (Gigabyte) + +pci:v000011ABd00004362sv00001462sd0000058C* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (MSI) + +pci:v000011ABd00004362sv000014C0sd00000012* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (Compal) + +pci:v000011ABd00004362sv00001558sd000004A0* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (Clevo) + +pci:v000011ABd00004362sv000015BDsd00001003* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (DFI) + +pci:v000011ABd00004362sv0000161Fsd0000203C* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (Arima) + +pci:v000011ABd00004362sv0000161Fsd0000203D* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (Arima) + +pci:v000011ABd00004362sv00001695sd00009029* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (Epox) + +pci:v000011ABd00004362sv000017F2sd00002C08* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (Albatron) + +pci:v000011ABd00004362sv000017FFsd00000585* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (Quanta) + +pci:v000011ABd00004362sv00001849sd00008053* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (ASRock) + +pci:v000011ABd00004362sv00001854sd0000000B* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (LGE) + +pci:v000011ABd00004362sv00001854sd0000000C* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (LGE) + +pci:v000011ABd00004362sv00001854sd00000010* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (LGE) + +pci:v000011ABd00004362sv00001854sd00000013* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (LGE) + +pci:v000011ABd00004362sv00001854sd00000014* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (LGE) + +pci:v000011ABd00004362sv00001854sd00000015* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (LGE) + +pci:v000011ABd00004362sv00001854sd0000001A* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (LGE) + +pci:v000011ABd00004362sv00001854sd0000001B* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (LGE) + +pci:v000011ABd00004362sv00001854sd0000001D* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (LGE) + +pci:v000011ABd00004362sv00001854sd0000001F* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (LGE) + +pci:v000011ABd00004362sv00001854sd00000021* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (LGE) + +pci:v000011ABd00004362sv00001854sd00000022* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (LGE) + +pci:v000011ABd00004362sv0000270Fsd00002801* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (Chaintech) + +pci:v000011ABd00004362sv0000A0A0sd00000506* + ID_PRODUCT_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (Aopen) + +pci:v000011ABd00004363* + ID_PRODUCT_FROM_DATABASE=88E8055 PCI-E Gigabit Ethernet Controller + +pci:v000011ABd00004364* + ID_PRODUCT_FROM_DATABASE=88E8056 PCI-E Gigabit Ethernet Controller + +pci:v000011ABd00004364sv000011BAsd000000BA* + ID_PRODUCT_FROM_DATABASE=8056 Gigabit Ethernet Controller + +pci:v000011ABd00004365* + ID_PRODUCT_FROM_DATABASE=88E8070 based Ethernet Controller + +pci:v000011ABd00004366* + ID_PRODUCT_FROM_DATABASE=88EC036 PCI-E Gigabit Ethernet Controller + +pci:v000011ABd00004367* + ID_PRODUCT_FROM_DATABASE=88EC032 Ethernet Controller + +pci:v000011ABd00004368* + ID_PRODUCT_FROM_DATABASE=88EC034 Ethernet Controller + +pci:v000011ABd00004369* + ID_PRODUCT_FROM_DATABASE=88EC042 Ethernet Controller + +pci:v000011ABd0000436A* + ID_PRODUCT_FROM_DATABASE=88E8058 PCI-E Gigabit Ethernet Controller + +pci:v000011ABd0000436Asv000011ABsd000000BA* + ID_PRODUCT_FROM_DATABASE=Imac 8,1 Wired Ethernet Adapter + +pci:v000011ABd0000436B* + ID_PRODUCT_FROM_DATABASE=88E8071 PCI-E Gigabit Ethernet Controller + +pci:v000011ABd0000436C* + ID_PRODUCT_FROM_DATABASE=88E8072 PCI-E Gigabit Ethernet Controller + +pci:v000011ABd0000436D* + ID_PRODUCT_FROM_DATABASE=88E8055 PCI-E Gigabit Ethernet Controller + +pci:v000011ABd00004370* + ID_PRODUCT_FROM_DATABASE=88E8075 PCI-E Gigabit Ethernet Controller + +pci:v000011ABd00004380* + ID_PRODUCT_FROM_DATABASE=88E8057 PCI-E Gigabit Ethernet Controller + +pci:v000011ABd00004381* + ID_PRODUCT_FROM_DATABASE=Yukon Optima 88E8059 [PCIe Gigabit Ethernet Controller with AVB] + +pci:v000011ABd00004611* + ID_PRODUCT_FROM_DATABASE=GT-64115 System Controller + +pci:v000011ABd00004620* + ID_PRODUCT_FROM_DATABASE=GT-64120/64120A/64121A System Controller + +pci:v000011ABd00004801* + ID_PRODUCT_FROM_DATABASE=GT-48001 + +pci:v000011ABd00005005* + ID_PRODUCT_FROM_DATABASE=Belkin F5D5005 Gigabit Desktop Network PCI Card + +pci:v000011ABd00005040* + ID_PRODUCT_FROM_DATABASE=MV88SX5040 4-port SATA I PCI-X Controller + +pci:v000011ABd00005041* + ID_PRODUCT_FROM_DATABASE=MV88SX5041 4-port SATA I PCI-X Controller + +pci:v000011ABd00005080* + ID_PRODUCT_FROM_DATABASE=MV88SX5080 8-port SATA I PCI-X Controller + +pci:v000011ABd00005081* + ID_PRODUCT_FROM_DATABASE=MV88SX5081 8-port SATA I PCI-X Controller + +pci:v000011ABd00005181* + ID_PRODUCT_FROM_DATABASE=88f5181 [Orion-1] ARM SoC + +pci:v000011ABd00005182* + ID_PRODUCT_FROM_DATABASE=88f5182 [Orion-NAS] ARM SoC + +pci:v000011ABd00005281* + ID_PRODUCT_FROM_DATABASE=88f5281 [Orion-2] ARM SoC + +pci:v000011ABd00006041* + ID_PRODUCT_FROM_DATABASE=MV88SX6041 4-port SATA II PCI-X Controller + +pci:v000011ABd00006042* + ID_PRODUCT_FROM_DATABASE=88SX6042 PCI-X 4-Port SATA-II + +pci:v000011ABd00006081* + ID_PRODUCT_FROM_DATABASE=MV88SX6081 8-port SATA II PCI-X Controller + +pci:v000011ABd00006101* + ID_PRODUCT_FROM_DATABASE=88SE6101/6102 single-port PATA133 interface + +pci:v000011ABd00006111* + ID_PRODUCT_FROM_DATABASE=88SE6111 1-port PATA133(IDE) and 1-port SATA II Controllers + +pci:v000011ABd00006121* + ID_PRODUCT_FROM_DATABASE=88SE6121 SATA II / PATA Controller + +pci:v000011ABd00006141* + ID_PRODUCT_FROM_DATABASE=88SE614x SATA II PCI-E controller + +pci:v000011ABd00006145* + ID_PRODUCT_FROM_DATABASE=88SE6145 SATA II PCI-E controller + +pci:v000011ABd00006180* + ID_PRODUCT_FROM_DATABASE=88F6180 [Kirkwood] ARM SoC + +pci:v000011ABd00006192* + ID_PRODUCT_FROM_DATABASE=88F6190/6192 [Kirkwood] ARM SoC + +pci:v000011ABd00006281* + ID_PRODUCT_FROM_DATABASE=88F6281 [Kirkwood] ARM SoC + +pci:v000011ABd00006381* + ID_PRODUCT_FROM_DATABASE=MV78xx0 [Discovery Innovation] ARM SoC + +pci:v000011ABd00006440* + ID_PRODUCT_FROM_DATABASE=88SE6440 SAS/SATA PCIe controller + +pci:v000011ABd00006450* + ID_PRODUCT_FROM_DATABASE=64560 System Controller + +pci:v000011ABd00006460* + ID_PRODUCT_FROM_DATABASE=MV64360/64361/64362 System Controller + +pci:v000011ABd00006480* + ID_PRODUCT_FROM_DATABASE=MV64460/64461/64462 System Controller + +pci:v000011ABd00006480sv00001775sd0000C200* + ID_PRODUCT_FROM_DATABASE=C2K CompactPCI single board computer + +pci:v000011ABd00006485* + ID_PRODUCT_FROM_DATABASE=MV64460/64461/64462 System Controller, Revision B + +pci:v000011ABd00007042* + ID_PRODUCT_FROM_DATABASE=88SX7042 PCI-e 4-port SATA-II + +pci:v000011ABd00007042sv000016B8sd0000434B* + ID_PRODUCT_FROM_DATABASE=Tempo SATA E4P + +pci:v000011ABd00007810* + ID_PRODUCT_FROM_DATABASE=MV78100 [Discovery Innovation] ARM SoC + +pci:v000011ABd00007820* + ID_PRODUCT_FROM_DATABASE=MV78200 [Discovery Innovation] ARM SoC + +pci:v000011ABd0000F003* + ID_PRODUCT_FROM_DATABASE=GT-64010 Primary Image Piranha Image Generator + +pci:v000011AC* + ID_VENDOR_FROM_DATABASE=Canon Information Systems Research Aust. + +pci:v000011AD* + ID_VENDOR_FROM_DATABASE=Lite-On Communications Inc + +pci:v000011ADd00000002* + ID_PRODUCT_FROM_DATABASE=LNE100TX + +pci:v000011ADd00000002sv000011ADsd00000002* + ID_PRODUCT_FROM_DATABASE=LNE100TX + +pci:v000011ADd00000002sv000011ADsd00000003* + ID_PRODUCT_FROM_DATABASE=LNE100TX + +pci:v000011ADd00000002sv000011ADsd0000F003* + ID_PRODUCT_FROM_DATABASE=LNE100TX + +pci:v000011ADd00000002sv000011ADsd0000FFFF* + ID_PRODUCT_FROM_DATABASE=LNE100TX + +pci:v000011ADd00000002sv00001385sd0000F004* + ID_PRODUCT_FROM_DATABASE=FA310TX + +pci:v000011ADd00000002sv00002646sd0000F002* + ID_PRODUCT_FROM_DATABASE=KNE110TX EtheRx Fast Ethernet + +pci:v000011ADd0000C115* + ID_PRODUCT_FROM_DATABASE=LNE100TX [Linksys EtherFast 10/100] + +pci:v000011ADd0000C115sv000011ADsd0000C001* + ID_PRODUCT_FROM_DATABASE=LNE100TX [ver 2.0] + +pci:v000011ADd0000C115sv00002646sd0000000B* + ID_PRODUCT_FROM_DATABASE=KNE111TX + +pci:v000011AE* + ID_VENDOR_FROM_DATABASE=Aztech System Ltd + +pci:v000011AF* + ID_VENDOR_FROM_DATABASE=Avid Technology Inc. + +pci:v000011AFd00000001* + ID_PRODUCT_FROM_DATABASE=Cinema + +pci:v000011AFd0000EE40* + ID_PRODUCT_FROM_DATABASE=Digidesign Audiomedia III + +pci:v000011B0* + ID_VENDOR_FROM_DATABASE=V3 Semiconductor Inc. + +pci:v000011B0d00000002* + ID_PRODUCT_FROM_DATABASE=V300PSC + +pci:v000011B0d00000292* + ID_PRODUCT_FROM_DATABASE=V292PBC [Am29030/40 Bridge] + +pci:v000011B0d00000960* + ID_PRODUCT_FROM_DATABASE=V96xPBC + +pci:v000011B0d0000C960* + ID_PRODUCT_FROM_DATABASE=V96DPC + +pci:v000011B1* + ID_VENDOR_FROM_DATABASE=Apricot Computers + +pci:v000011B2* + ID_VENDOR_FROM_DATABASE=Eastman Kodak + +pci:v000011B3* + ID_VENDOR_FROM_DATABASE=Barr Systems Inc. + +pci:v000011B4* + ID_VENDOR_FROM_DATABASE=Leitch Technology International + +pci:v000011B5* + ID_VENDOR_FROM_DATABASE=Radstone Technology Plc + +pci:v000011B6* + ID_VENDOR_FROM_DATABASE=United Video Corp + +pci:v000011B7* + ID_VENDOR_FROM_DATABASE=Motorola + +pci:v000011B8* + ID_VENDOR_FROM_DATABASE=XPoint Technologies, Inc + +pci:v000011B8d00000001* + ID_PRODUCT_FROM_DATABASE=Quad PeerMaster + +pci:v000011B9* + ID_VENDOR_FROM_DATABASE=Pathlight Technology Inc. + +pci:v000011B9d0000C0ED* + ID_PRODUCT_FROM_DATABASE=SSA Controller + +pci:v000011BA* + ID_VENDOR_FROM_DATABASE=Videotron Corp + +pci:v000011BB* + ID_VENDOR_FROM_DATABASE=Pyramid Technology + +pci:v000011BC* + ID_VENDOR_FROM_DATABASE=Network Peripherals Inc + +pci:v000011BCd00000001* + ID_PRODUCT_FROM_DATABASE=NP-PCI + +pci:v000011BD* + ID_VENDOR_FROM_DATABASE=Pinnacle Systems Inc. + +pci:v000011BDd0000002E* + ID_PRODUCT_FROM_DATABASE=PCTV 40i + +pci:v000011BDd00000040* + ID_PRODUCT_FROM_DATABASE=Royal TS Function 1 + +pci:v000011BDd00000040sv000011BDsd00000044* + ID_PRODUCT_FROM_DATABASE=PCTV 2000i Dual DVB-T Pro PCI Tuner 1 + +pci:v000011BDd00000040sv000011BDsd00000045* + ID_PRODUCT_FROM_DATABASE=PCTV Dual Sat Pro PCI 4000i Tuner 1 + +pci:v000011BDd00000041* + ID_PRODUCT_FROM_DATABASE=RoyalTS Function 2 + +pci:v000011BDd00000041sv000011BDsd00000044* + ID_PRODUCT_FROM_DATABASE=PCTV 2000i Dual DVB-T Pro PCI Tuner 2 + +pci:v000011BDd00000041sv000011BDsd00000045* + ID_PRODUCT_FROM_DATABASE=PCTV Dual Sat Pro PCI 4000i Tuner 2 + +pci:v000011BDd00000042* + ID_PRODUCT_FROM_DATABASE=Royal TS Function 3 + +pci:v000011BDd00000042sv000011BDsd00000044* + ID_PRODUCT_FROM_DATABASE=PCTV 2000i Dual DVB-T Pro PCI Common + +pci:v000011BDd00000042sv000011BDsd00000045* + ID_PRODUCT_FROM_DATABASE=PCTV Dual Sat Pro PCI 4000i Common + +pci:v000011BDd00000051* + ID_PRODUCT_FROM_DATABASE=PCTV HD 800i + +pci:v000011BDd0000BEDE* + ID_PRODUCT_FROM_DATABASE=AV/DV Studio Capture Card + +pci:v000011BE* + ID_VENDOR_FROM_DATABASE=International Microcircuits Inc + +pci:v000011BF* + ID_VENDOR_FROM_DATABASE=Astrodesign, Inc. + +pci:v000011C0* + ID_VENDOR_FROM_DATABASE=Hewlett Packard + +pci:v000011C1* + ID_VENDOR_FROM_DATABASE=LSI Corporation + +pci:v000011C1d00000440* + ID_PRODUCT_FROM_DATABASE=56k WinModem + +pci:v000011C1d00000440sv00001033sd00008015* + ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+Dsvd + +pci:v000011C1d00000440sv00001033sd00008047* + ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+Dsvd + +pci:v000011C1d00000440sv00001033sd0000804F* + ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+Dsvd + +pci:v000011C1d00000440sv000010CFsd0000102C* + ID_PRODUCT_FROM_DATABASE=LB LT Modem V.90 56k + +pci:v000011C1d00000440sv000010CFsd0000104A* + ID_PRODUCT_FROM_DATABASE=BIBLO LT Modem 56k + +pci:v000011C1d00000440sv000010CFsd0000105F* + ID_PRODUCT_FROM_DATABASE=LB2 LT Modem V.90 56k + +pci:v000011C1d00000440sv00001179sd00000001* + ID_PRODUCT_FROM_DATABASE=Internal V.90 Modem + +pci:v000011C1d00000440sv000011C1sd00000440* + ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+Dsvd + +pci:v000011C1d00000440sv0000122Dsd00004101* + ID_PRODUCT_FROM_DATABASE=MDP7800-U Modem + +pci:v000011C1d00000440sv0000122Dsd00004102* + ID_PRODUCT_FROM_DATABASE=MDP7800SP-U Modem + +pci:v000011C1d00000440sv000013E0sd00000040* + ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+Dsvd + +pci:v000011C1d00000440sv000013E0sd00000440* + ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+Dsvd + +pci:v000011C1d00000440sv000013E0sd00000441* + ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+Dsvd + +pci:v000011C1d00000440sv000013E0sd00000450* + ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+Dsvd + +pci:v000011C1d00000440sv000013E0sd0000F100* + ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+Dsvd + +pci:v000011C1d00000440sv000013E0sd0000F101* + ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+Dsvd + +pci:v000011C1d00000440sv0000144Dsd00002101* + ID_PRODUCT_FROM_DATABASE=LT56PV Modem + +pci:v000011C1d00000440sv0000149Fsd00000440* + ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+Dsvd + +pci:v000011C1d00000441* + ID_PRODUCT_FROM_DATABASE=56k WinModem + +pci:v000011C1d00000441sv00001033sd0000804D* + ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax + +pci:v000011C1d00000441sv00001033sd00008065* + ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax + +pci:v000011C1d00000441sv00001092sd00000440* + ID_PRODUCT_FROM_DATABASE=Supra 56i + +pci:v000011C1d00000441sv00001179sd00000001* + ID_PRODUCT_FROM_DATABASE=Internal V.90 Modem + +pci:v000011C1d00000441sv000011C1sd00000440* + ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax + +pci:v000011C1d00000441sv000011C1sd00000441* + ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax + +pci:v000011C1d00000441sv0000122Dsd00004100* + ID_PRODUCT_FROM_DATABASE=MDP7800-U Modem + +pci:v000011C1d00000441sv000013E0sd00000040* + ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax + +pci:v000011C1d00000441sv000013E0sd00000100* + ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax + +pci:v000011C1d00000441sv000013E0sd00000410* + ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax + +pci:v000011C1d00000441sv000013E0sd00000420* + ID_PRODUCT_FROM_DATABASE=TelePath Internet 56k WinModem + +pci:v000011C1d00000441sv000013E0sd00000440* + ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax + +pci:v000011C1d00000441sv000013E0sd00000443* + ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax + +pci:v000011C1d00000441sv000013E0sd0000F102* + ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax + +pci:v000011C1d00000441sv00001416sd00009804* + ID_PRODUCT_FROM_DATABASE=CommWave 56k Modem + +pci:v000011C1d00000441sv0000141Dsd00000440* + ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax + +pci:v000011C1d00000441sv0000144Fsd00000441* + ID_PRODUCT_FROM_DATABASE=Lucent 56k V.90 DF Modem + +pci:v000011C1d00000441sv0000144Fsd00000449* + ID_PRODUCT_FROM_DATABASE=Lucent 56k V.90 DF Modem + +pci:v000011C1d00000441sv0000144Fsd0000110D* + ID_PRODUCT_FROM_DATABASE=Lucent Win Modem + +pci:v000011C1d00000441sv00001468sd00000441* + ID_PRODUCT_FROM_DATABASE=Presario 56k V.90 DF Modem + +pci:v000011C1d00000441sv00001668sd00000440* + ID_PRODUCT_FROM_DATABASE=Lucent Win Modem + +pci:v000011C1d00000442* + ID_PRODUCT_FROM_DATABASE=56k WinModem + +pci:v000011C1d00000442sv000011C1sd00000440* + ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd + +pci:v000011C1d00000442sv000011C1sd00000442* + ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd + +pci:v000011C1d00000442sv000013E0sd00000412* + ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd + +pci:v000011C1d00000442sv000013E0sd00000442* + ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd + +pci:v000011C1d00000442sv000013FCsd00002471* + ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd + +pci:v000011C1d00000442sv0000144Dsd00002104* + ID_PRODUCT_FROM_DATABASE=LT56PT Modem + +pci:v000011C1d00000442sv0000144Fsd00001104* + ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd + +pci:v000011C1d00000442sv0000149Fsd00000440* + ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd + +pci:v000011C1d00000442sv00001668sd00000440* + ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd + +pci:v000011C1d00000443* + ID_PRODUCT_FROM_DATABASE=LT WinModem + +pci:v000011C1d00000444* + ID_PRODUCT_FROM_DATABASE=LT WinModem + +pci:v000011C1d00000445* + ID_PRODUCT_FROM_DATABASE=LT WinModem + +pci:v000011C1d00000445sv00008086sd00002203* + ID_PRODUCT_FROM_DATABASE=PRO/100+ MiniPCI (probably an Ambit U98.003.C.00 combo card) + +pci:v000011C1d00000445sv00008086sd00002204* + ID_PRODUCT_FROM_DATABASE=PRO/100+ MiniPCI on Armada E500 + +pci:v000011C1d00000446* + ID_PRODUCT_FROM_DATABASE=LT WinModem + +pci:v000011C1d00000447* + ID_PRODUCT_FROM_DATABASE=LT WinModem + +pci:v000011C1d00000448* + ID_PRODUCT_FROM_DATABASE=WinModem 56k + +pci:v000011C1d00000448sv00001014sd00000131* + ID_PRODUCT_FROM_DATABASE=Lucent Win Modem + +pci:v000011C1d00000448sv00001033sd00008066* + ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+Dsvd + +pci:v000011C1d00000448sv000013E0sd00000030* + ID_PRODUCT_FROM_DATABASE=56k Voice Modem + +pci:v000011C1d00000448sv000013E0sd00000040* + ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+Dsvd + +pci:v000011C1d00000448sv00001668sd00002400* + ID_PRODUCT_FROM_DATABASE=LT WinModem 56k (MiniPCI Ethernet+Modem) + +pci:v000011C1d00000449* + ID_PRODUCT_FROM_DATABASE=L56xM+S [Mars-2] WinModem 56k + +pci:v000011C1d00000449sv00000E11sd0000B14D* + ID_PRODUCT_FROM_DATABASE=56k V.90 Modem + +pci:v000011C1d00000449sv00001014sd0000018C* + ID_PRODUCT_FROM_DATABASE=ThinkPad 600X + +pci:v000011C1d00000449sv000013E0sd00000020* + ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax + +pci:v000011C1d00000449sv000013E0sd00000041* + ID_PRODUCT_FROM_DATABASE=TelePath Internet 56k WinModem + +pci:v000011C1d00000449sv00001436sd00000440* + ID_PRODUCT_FROM_DATABASE=Lucent Win Modem + +pci:v000011C1d00000449sv0000144Fsd00000449* + ID_PRODUCT_FROM_DATABASE=Lucent 56k V.90 DFi Modem + +pci:v000011C1d00000449sv00001468sd00000410* + ID_PRODUCT_FROM_DATABASE=IBM ThinkPad T23 + +pci:v000011C1d00000449sv00001468sd00000440* + ID_PRODUCT_FROM_DATABASE=Lucent Win Modem + +pci:v000011C1d00000449sv00001468sd00000449* + ID_PRODUCT_FROM_DATABASE=Presario 56k V.90 DFi Modem + +pci:v000011C1d0000044A* + ID_PRODUCT_FROM_DATABASE=F-1156IV WinModem (V90, 56KFlex) + +pci:v000011C1d0000044Asv000010CFsd00001072* + ID_PRODUCT_FROM_DATABASE=LB Global LT Modem + +pci:v000011C1d0000044Asv000013E0sd00000012* + ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd + +pci:v000011C1d0000044Asv000013E0sd00000042* + ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd + +pci:v000011C1d0000044Asv0000144Fsd00001005* + ID_PRODUCT_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd + +pci:v000011C1d0000044B* + ID_PRODUCT_FROM_DATABASE=LT WinModem + +pci:v000011C1d0000044C* + ID_PRODUCT_FROM_DATABASE=LT WinModem + +pci:v000011C1d0000044D* + ID_PRODUCT_FROM_DATABASE=LT WinModem + +pci:v000011C1d0000044E* + ID_PRODUCT_FROM_DATABASE=LT WinModem + +pci:v000011C1d0000044F* + ID_PRODUCT_FROM_DATABASE=V90 WildWire Modem + +pci:v000011C1d00000450* + ID_PRODUCT_FROM_DATABASE=LT WinModem + +pci:v000011C1d00000450sv00001033sd000080A8* + ID_PRODUCT_FROM_DATABASE=Versa Note Vxi + +pci:v000011C1d00000450sv0000144Fsd00004005* + ID_PRODUCT_FROM_DATABASE=Magnia SG20 + +pci:v000011C1d00000450sv00001468sd00000450* + ID_PRODUCT_FROM_DATABASE=Evo N600c + +pci:v000011C1d00000451* + ID_PRODUCT_FROM_DATABASE=LT WinModem + +pci:v000011C1d00000452* + ID_PRODUCT_FROM_DATABASE=LT WinModem + +pci:v000011C1d00000453* + ID_PRODUCT_FROM_DATABASE=LT WinModem + +pci:v000011C1d00000454* + ID_PRODUCT_FROM_DATABASE=LT WinModem + +pci:v000011C1d00000455* + ID_PRODUCT_FROM_DATABASE=LT WinModem + +pci:v000011C1d00000456* + ID_PRODUCT_FROM_DATABASE=LT WinModem + +pci:v000011C1d00000457* + ID_PRODUCT_FROM_DATABASE=LT WinModem + +pci:v000011C1d00000458* + ID_PRODUCT_FROM_DATABASE=LT WinModem + +pci:v000011C1d00000459* + ID_PRODUCT_FROM_DATABASE=LT WinModem + +pci:v000011C1d0000045A* + ID_PRODUCT_FROM_DATABASE=LT WinModem + +pci:v000011C1d0000045C* + ID_PRODUCT_FROM_DATABASE=LT WinModem + +pci:v000011C1d00000461* + ID_PRODUCT_FROM_DATABASE=V90 WildWire Modem + +pci:v000011C1d00000462* + ID_PRODUCT_FROM_DATABASE=V90 WildWire Modem + +pci:v000011C1d00000480* + ID_PRODUCT_FROM_DATABASE=Venus Modem (V90, 56KFlex) + +pci:v000011C1d0000048C* + ID_PRODUCT_FROM_DATABASE=V.92 56K WinModem + +pci:v000011C1d0000048F* + ID_PRODUCT_FROM_DATABASE=V.92 56k WinModem + +pci:v000011C1d00000620* + ID_PRODUCT_FROM_DATABASE=Lucent V.92 Data/Fax Modem + +pci:v000011C1d00001040* + ID_PRODUCT_FROM_DATABASE=HDA softmodem + +pci:v000011C1d00002600* + ID_PRODUCT_FROM_DATABASE=StarPro26XX family (SP2601, SP2603, SP2612) DSP + +pci:v000011C1d00003026* + ID_PRODUCT_FROM_DATABASE=HDA Modem + +pci:v000011C1d00005400* + ID_PRODUCT_FROM_DATABASE=OR3TP12 FPSC + +pci:v000011C1d00005656* + ID_PRODUCT_FROM_DATABASE=Venus Modem + +pci:v000011C1d00005801* + ID_PRODUCT_FROM_DATABASE=USB + +pci:v000011C1d00005802* + ID_PRODUCT_FROM_DATABASE=USS-312 USB Controller + +pci:v000011C1d00005803* + ID_PRODUCT_FROM_DATABASE=USS-344S USB Controller + +pci:v000011C1d00005811* + ID_PRODUCT_FROM_DATABASE=FW322/323 [TrueFire] 1394a Controller + +pci:v000011C1d00005811sv0000103Csd00002A34* + ID_PRODUCT_FROM_DATABASE=Pavilion a1677c + +pci:v000011C1d00005811sv0000103Csd00002A9E* + ID_PRODUCT_FROM_DATABASE=Pavilion p6310f + +pci:v000011C1d00005811sv00001043sd00008294* + ID_PRODUCT_FROM_DATABASE=LSI FW322/323 IEEE 1394a FireWire Controller + +pci:v000011C1d00005811sv00008086sd0000524C* + ID_PRODUCT_FROM_DATABASE=D865PERL mainboard + +pci:v000011C1d00005811sv0000DEADsd00000800* + ID_PRODUCT_FROM_DATABASE=FireWire Host Bus Adapter + +pci:v000011C1d00005901* + ID_PRODUCT_FROM_DATABASE=FW643 [TrueFire] PCIe 1394b Controller + +pci:v000011C1d00005901sv000011C1sd00005900* + ID_PRODUCT_FROM_DATABASE=FW643 [TrueFire] PCIe 1394b Controller + +pci:v000011C1d00005901sv00001443sd00000643* + ID_PRODUCT_FROM_DATABASE=FireBoard800-e V.2 + +pci:v000011C1d00005901sv00001546sd00000643* + ID_PRODUCT_FROM_DATABASE=FWB-PCIE1X2x + +pci:v000011C1d00005903* + ID_PRODUCT_FROM_DATABASE=FW533 [TrueFire] PCIe 1394a Controller + +pci:v000011C1d00008110* + ID_PRODUCT_FROM_DATABASE=T8110 H.100/H.110 TDM switch + +pci:v000011C1d00008110sv000012D9sd0000000C* + ID_PRODUCT_FROM_DATABASE=E1/T1 PMXc cPCI carrier card + +pci:v000011C1d0000AB10* + ID_PRODUCT_FROM_DATABASE=WL60010 Wireless LAN MAC + +pci:v000011C1d0000AB11* + ID_PRODUCT_FROM_DATABASE=WL60040 Multimode Wireles LAN MAC + +pci:v000011C1d0000AB11sv000011C1sd0000AB12* + ID_PRODUCT_FROM_DATABASE=WaveLAN 11abg Cardbus card (Model 1102) + +pci:v000011C1d0000AB11sv000011C1sd0000AB13* + ID_PRODUCT_FROM_DATABASE=WaveLAN 11abg MiniPCI card (Model 0512) + +pci:v000011C1d0000AB11sv000011C1sd0000AB15* + ID_PRODUCT_FROM_DATABASE=WaveLAN 11abg Cardbus card (Model 1106) + +pci:v000011C1d0000AB11sv000011C1sd0000AB16* + ID_PRODUCT_FROM_DATABASE=WaveLAN 11abg MiniPCI card (Model 0516) + +pci:v000011C1d0000AB20* + ID_PRODUCT_FROM_DATABASE=ORiNOCO PCI Adapter + +pci:v000011C1d0000AB21* + ID_PRODUCT_FROM_DATABASE=Agere Wireless PCI Adapter + +pci:v000011C1d0000AB30* + ID_PRODUCT_FROM_DATABASE=Hermes2 Mini-PCI WaveLAN a/b/g + +pci:v000011C1d0000AB30sv000014CDsd00002012* + ID_PRODUCT_FROM_DATABASE=Hermes2 Mini-PCI WaveLAN a/b/g + +pci:v000011C1d0000ED00* + ID_PRODUCT_FROM_DATABASE=ET-131x PCI-E Ethernet Controller + +pci:v000011C1d0000ED01* + ID_PRODUCT_FROM_DATABASE=ET-131x PCI-E Ethernet Controller + +pci:v000011C2* + ID_VENDOR_FROM_DATABASE=Sand Microelectronics + +pci:v000011C3* + ID_VENDOR_FROM_DATABASE=NEC Corporation + +pci:v000011C4* + ID_VENDOR_FROM_DATABASE=Document Technologies, Inc + +pci:v000011C5* + ID_VENDOR_FROM_DATABASE=Shiva Corporation + +pci:v000011C6* + ID_VENDOR_FROM_DATABASE=Dainippon Screen Mfg. Co. Ltd + +pci:v000011C7* + ID_VENDOR_FROM_DATABASE=D.C.M. Data Systems + +pci:v000011C8* + ID_VENDOR_FROM_DATABASE=Dolphin Interconnect Solutions AS + +pci:v000011C8d00000658* + ID_PRODUCT_FROM_DATABASE=PSB32 SCI-Adapter D31x + +pci:v000011C8d0000D665* + ID_PRODUCT_FROM_DATABASE=PSB64 SCI-Adapter D32x + +pci:v000011C8d0000D667* + ID_PRODUCT_FROM_DATABASE=PSB66 SCI-Adapter D33x + +pci:v000011C9* + ID_VENDOR_FROM_DATABASE=Magma + +pci:v000011C9d00000010* + ID_PRODUCT_FROM_DATABASE=16-line serial port w/- DMA + +pci:v000011C9d00000011* + ID_PRODUCT_FROM_DATABASE=4-line serial port w/- DMA + +pci:v000011CA* + ID_VENDOR_FROM_DATABASE=LSI Systems, Inc + +pci:v000011CB* + ID_VENDOR_FROM_DATABASE=Specialix Research Ltd. + +pci:v000011CBd00002000* + ID_PRODUCT_FROM_DATABASE=PCI_9050 + +pci:v000011CBd00002000sv000011CBsd00000200* + ID_PRODUCT_FROM_DATABASE=SX + +pci:v000011CBd00002000sv000011CBsd0000B008* + ID_PRODUCT_FROM_DATABASE=I/O8+ + +pci:v000011CBd00004000* + ID_PRODUCT_FROM_DATABASE=SUPI_1 + +pci:v000011CBd00008000* + ID_PRODUCT_FROM_DATABASE=T225 + +pci:v000011CC* + ID_VENDOR_FROM_DATABASE=Michels & Kleberhoff Computer GmbH + +pci:v000011CD* + ID_VENDOR_FROM_DATABASE=HAL Computer Systems, Inc. + +pci:v000011CE* + ID_VENDOR_FROM_DATABASE=Netaccess + +pci:v000011CF* + ID_VENDOR_FROM_DATABASE=Pioneer Electronic Corporation + +pci:v000011D0* + ID_VENDOR_FROM_DATABASE=Lockheed Martin Federal Systems-Manassas + +pci:v000011D1* + ID_VENDOR_FROM_DATABASE=Auravision + +pci:v000011D1d000001F7* + ID_PRODUCT_FROM_DATABASE=VxP524 + +pci:v000011D1d000001F9* + ID_PRODUCT_FROM_DATABASE=VxP951 + +pci:v000011D2* + ID_VENDOR_FROM_DATABASE=Intercom Inc. + +pci:v000011D3* + ID_VENDOR_FROM_DATABASE=Trancell Systems Inc + +pci:v000011D4* + ID_VENDOR_FROM_DATABASE=Analog Devices + +pci:v000011D4d00000078* + ID_PRODUCT_FROM_DATABASE=AD1986HD sound chip + +pci:v000011D4d00001535* + ID_PRODUCT_FROM_DATABASE=Blackfin BF535 processor + +pci:v000011D4d00001805* + ID_PRODUCT_FROM_DATABASE=SM56 PCI modem + +pci:v000011D4d00001889* + ID_PRODUCT_FROM_DATABASE=AD1889 sound chip + +pci:v000011D4d0000194A* + ID_PRODUCT_FROM_DATABASE=AD1984A sound chip + +pci:v000011D4d00001981* + ID_PRODUCT_FROM_DATABASE=AD1981HD sound chip + +pci:v000011D4d00001983* + ID_PRODUCT_FROM_DATABASE=AD1983HD sound chip + +pci:v000011D4d00001984* + ID_PRODUCT_FROM_DATABASE=AD1984HD sound chip + +pci:v000011D4d00001984sv000017AAsd000020BB* + ID_PRODUCT_FROM_DATABASE=T61p Notebook + +pci:v000011D4d00001986* + ID_PRODUCT_FROM_DATABASE=AD1986A sound chip + +pci:v000011D4d00001986sv000011D4sd00001986* + ID_PRODUCT_FROM_DATABASE=Lenovo N100 B9G + +pci:v000011D4d0000198B* + ID_PRODUCT_FROM_DATABASE=AD1988B Sound Chip + +pci:v000011D4d00005340* + ID_PRODUCT_FROM_DATABASE=AD1881 sound chip + +pci:v000011D5* + ID_VENDOR_FROM_DATABASE=Ikon Corporation + +pci:v000011D5d00000115* + ID_PRODUCT_FROM_DATABASE=10115 + +pci:v000011D5d00000117* + ID_PRODUCT_FROM_DATABASE=10117 + +pci:v000011D6* + ID_VENDOR_FROM_DATABASE=Tekelec Telecom + +pci:v000011D7* + ID_VENDOR_FROM_DATABASE=Trenton Technology, Inc. + +pci:v000011D8* + ID_VENDOR_FROM_DATABASE=Image Technologies Development + +pci:v000011D9* + ID_VENDOR_FROM_DATABASE=TEC Corporation + +pci:v000011DA* + ID_VENDOR_FROM_DATABASE=Novell + +pci:v000011DB* + ID_VENDOR_FROM_DATABASE=Sega Enterprises Ltd + +pci:v000011DC* + ID_VENDOR_FROM_DATABASE=Questra Corporation + +pci:v000011DD* + ID_VENDOR_FROM_DATABASE=Crosfield Electronics Limited + +pci:v000011DE* + ID_VENDOR_FROM_DATABASE=Zoran Corporation + +pci:v000011DEd00006017* + ID_PRODUCT_FROM_DATABASE=miroVIDEO DC30 + +pci:v000011DEd00006057* + ID_PRODUCT_FROM_DATABASE=ZR36057PQC Video cutting chipset + +pci:v000011DEd00006057sv00001031sd00007EFE* + ID_PRODUCT_FROM_DATABASE=DC10 Plus + +pci:v000011DEd00006057sv00001031sd0000FC00* + ID_PRODUCT_FROM_DATABASE=MiroVIDEO DC50, Motion JPEG Capture/CODEC Board + +pci:v000011DEd00006057sv000012F8sd00008A02* + ID_PRODUCT_FROM_DATABASE=Tekram Video Kit + +pci:v000011DEd00006057sv000013CAsd00004231* + ID_PRODUCT_FROM_DATABASE=JPEG/TV Card + +pci:v000011DEd00006120* + ID_PRODUCT_FROM_DATABASE=ZR36120 + +pci:v000011DEd00006120sv00001328sd0000F001* + ID_PRODUCT_FROM_DATABASE=Cinemaster C DVD Decoder + +pci:v000011DEd00006120sv000013C2sd00000000* + ID_PRODUCT_FROM_DATABASE=MediaFocus Satellite TV Card + +pci:v000011DEd00006120sv00001DE1sd00009FFF* + ID_PRODUCT_FROM_DATABASE=Video Kit C210 + +pci:v000011DF* + ID_VENDOR_FROM_DATABASE=New Wave PDG + +pci:v000011E0* + ID_VENDOR_FROM_DATABASE=Cray Communications A/S + +pci:v000011E1* + ID_VENDOR_FROM_DATABASE=GEC Plessey Semi Inc. + +pci:v000011E2* + ID_VENDOR_FROM_DATABASE=Samsung Information Systems America + +pci:v000011E3* + ID_VENDOR_FROM_DATABASE=Quicklogic Corporation + +pci:v000011E3d00000001* + ID_PRODUCT_FROM_DATABASE=COM-ON-AIR Dosch&Amand DECT + +pci:v000011E3d00000560* + ID_PRODUCT_FROM_DATABASE=QL5064 Companion Design Demo Board + +pci:v000011E3d00005030* + ID_PRODUCT_FROM_DATABASE=PC Watchdog + +pci:v000011E3d00008417* + ID_PRODUCT_FROM_DATABASE=QL5064 [QuickPCI] PCI v2.2 bridge for SMT417 Dual TMS320C6416T PMC Module + +pci:v000011E4* + ID_VENDOR_FROM_DATABASE=Second Wave Inc + +pci:v000011E5* + ID_VENDOR_FROM_DATABASE=IIX Consulting + +pci:v000011E6* + ID_VENDOR_FROM_DATABASE=Mitsui-Zosen System Research + +pci:v000011E7* + ID_VENDOR_FROM_DATABASE=Toshiba America, Elec. Company + +pci:v000011E8* + ID_VENDOR_FROM_DATABASE=Digital Processing Systems Inc. + +pci:v000011E9* + ID_VENDOR_FROM_DATABASE=Highwater Designs Ltd. + +pci:v000011EA* + ID_VENDOR_FROM_DATABASE=Elsag Bailey + +pci:v000011EB* + ID_VENDOR_FROM_DATABASE=Formation Inc. + +pci:v000011EC* + ID_VENDOR_FROM_DATABASE=Coreco Inc + +pci:v000011ECd0000000D* + ID_PRODUCT_FROM_DATABASE=Oculus-F/64P + +pci:v000011ECd00001800* + ID_PRODUCT_FROM_DATABASE=Cobra/C6 + +pci:v000011ED* + ID_VENDOR_FROM_DATABASE=Mediamatics + +pci:v000011EE* + ID_VENDOR_FROM_DATABASE=Dome Imaging Systems Inc + +pci:v000011EF* + ID_VENDOR_FROM_DATABASE=Nicolet Technologies B.V. + +pci:v000011F0* + ID_VENDOR_FROM_DATABASE=Compu-Shack + +pci:v000011F0d00004231* + ID_PRODUCT_FROM_DATABASE=FDDI + +pci:v000011F0d00004232* + ID_PRODUCT_FROM_DATABASE=FASTline UTP Quattro + +pci:v000011F0d00004233* + ID_PRODUCT_FROM_DATABASE=FASTline FO + +pci:v000011F0d00004234* + ID_PRODUCT_FROM_DATABASE=FASTline UTP + +pci:v000011F0d00004235* + ID_PRODUCT_FROM_DATABASE=FASTline-II UTP + +pci:v000011F0d00004236* + ID_PRODUCT_FROM_DATABASE=FASTline-II FO + +pci:v000011F0d00004731* + ID_PRODUCT_FROM_DATABASE=GIGAline + +pci:v000011F1* + ID_VENDOR_FROM_DATABASE=Symbios Logic Inc + +pci:v000011F2* + ID_VENDOR_FROM_DATABASE=Picture Tel Japan K.K. + +pci:v000011F3* + ID_VENDOR_FROM_DATABASE=Keithley Metrabyte + +pci:v000011F3d00000011* + ID_PRODUCT_FROM_DATABASE=KPCI-PIO24 + +pci:v000011F4* + ID_VENDOR_FROM_DATABASE=Kinetic Systems Corporation + +pci:v000011F4d00002915* + ID_PRODUCT_FROM_DATABASE=CAMAC controller + +pci:v000011F5* + ID_VENDOR_FROM_DATABASE=Computing Devices International + +pci:v000011F6* + ID_VENDOR_FROM_DATABASE=Compex + +pci:v000011F6d00000112* + ID_PRODUCT_FROM_DATABASE=ENet100VG4 + +pci:v000011F6d00000113* + ID_PRODUCT_FROM_DATABASE=FreedomLine 100 + +pci:v000011F6d00001401* + ID_PRODUCT_FROM_DATABASE=ReadyLink 2000 + +pci:v000011F6d00002011* + ID_PRODUCT_FROM_DATABASE=RL100-ATX 10/100 + +pci:v000011F6d00002011sv000011F6sd00002011* + ID_PRODUCT_FROM_DATABASE=RL100-ATX + +pci:v000011F6d00002201* + ID_PRODUCT_FROM_DATABASE=ReadyLink 100TX (Winbond W89C840) + +pci:v000011F6d00002201sv000011F6sd00002011* + ID_PRODUCT_FROM_DATABASE=ReadyLink 100TX + +pci:v000011F6d00009881* + ID_PRODUCT_FROM_DATABASE=RL100TX Fast Ethernet + +pci:v000011F7* + ID_VENDOR_FROM_DATABASE=Scientific Atlanta + +pci:v000011F8* + ID_VENDOR_FROM_DATABASE=PMC-Sierra Inc. + +pci:v000011F8d00005220* + ID_PRODUCT_FROM_DATABASE=BR522x [PMC-Sierra maxRAID SAS Controller] + +pci:v000011F8d00007364* + ID_PRODUCT_FROM_DATABASE=PM7364 [FREEDM - 32 Frame Engine & Datalink Mgr] + +pci:v000011F8d00007375* + ID_PRODUCT_FROM_DATABASE=PM7375 [LASAR-155 ATM SAR] + +pci:v000011F8d00007384* + ID_PRODUCT_FROM_DATABASE=PM7384 [FREEDM - 84P672 Frm Engine & Datalink Mgr] + +pci:v000011F8d00008000* + ID_PRODUCT_FROM_DATABASE=PM8000 [SPC - SAS Protocol Controller] + +pci:v000011F9* + ID_VENDOR_FROM_DATABASE=I-Cube Inc + +pci:v000011FA* + ID_VENDOR_FROM_DATABASE=Kasan Electronics Company, Ltd. + +pci:v000011FB* + ID_VENDOR_FROM_DATABASE=Datel Inc + +pci:v000011FC* + ID_VENDOR_FROM_DATABASE=Silicon Magic + +pci:v000011FD* + ID_VENDOR_FROM_DATABASE=High Street Consultants + +pci:v000011FE* + ID_VENDOR_FROM_DATABASE=Comtrol Corporation + +pci:v000011FEd00000001* + ID_PRODUCT_FROM_DATABASE=RocketPort 32 port w/external I/F + +pci:v000011FEd00000002* + ID_PRODUCT_FROM_DATABASE=RocketPort 8 port w/external I/F + +pci:v000011FEd00000003* + ID_PRODUCT_FROM_DATABASE=RocketPort 16 port w/external I/F + +pci:v000011FEd00000004* + ID_PRODUCT_FROM_DATABASE=RocketPort 4 port w/quad cable + +pci:v000011FEd00000005* + ID_PRODUCT_FROM_DATABASE=RocketPort 8 port w/octa cable + +pci:v000011FEd00000006* + ID_PRODUCT_FROM_DATABASE=RocketPort 8 port w/RJ11 connectors + +pci:v000011FEd00000007* + ID_PRODUCT_FROM_DATABASE=RocketPort 4 port w/RJ11 connectors + +pci:v000011FEd00000008* + ID_PRODUCT_FROM_DATABASE=RocketPort 8 port w/ DB78 SNI (Siemens) connector + +pci:v000011FEd00000009* + ID_PRODUCT_FROM_DATABASE=RocketPort 16 port w/ DB78 SNI (Siemens) connector + +pci:v000011FEd0000000A* + ID_PRODUCT_FROM_DATABASE=RocketPort Plus 4 port + +pci:v000011FEd0000000B* + ID_PRODUCT_FROM_DATABASE=RocketPort Plus 8 port + +pci:v000011FEd0000000C* + ID_PRODUCT_FROM_DATABASE=RocketModem 6 port + +pci:v000011FEd0000000D* + ID_PRODUCT_FROM_DATABASE=RocketModem 4-port + +pci:v000011FEd0000000E* + ID_PRODUCT_FROM_DATABASE=RocketPort Plus 2 port RS232 + +pci:v000011FEd0000000F* + ID_PRODUCT_FROM_DATABASE=RocketPort Plus 2 port RS422 + +pci:v000011FEd00000040* + ID_PRODUCT_FROM_DATABASE=RocketPort Infinity Octa, 8port, RJ45 + +pci:v000011FEd00000041* + ID_PRODUCT_FROM_DATABASE=RocketPort Infinity 32port, External Interface + +pci:v000011FEd00000042* + ID_PRODUCT_FROM_DATABASE=RocketPort Infinity 8port, External Interface + +pci:v000011FEd00000043* + ID_PRODUCT_FROM_DATABASE=RocketPort Infinity 16port, External Interface + +pci:v000011FEd00000044* + ID_PRODUCT_FROM_DATABASE=RocketPort Infinity Quad, 4port, DB + +pci:v000011FEd00000045* + ID_PRODUCT_FROM_DATABASE=RocketPort Infinity Octa, 8port, DB + +pci:v000011FEd00000047* + ID_PRODUCT_FROM_DATABASE=RocketPort Infinity 4port, RJ45 + +pci:v000011FEd0000004F* + ID_PRODUCT_FROM_DATABASE=RocketPort Infinity 2port, SMPTE + +pci:v000011FEd00000052* + ID_PRODUCT_FROM_DATABASE=RocketPort Infinity Octa, 8port, SMPTE + +pci:v000011FEd00000801* + ID_PRODUCT_FROM_DATABASE=RocketPort UPCI 32 port w/external I/F + +pci:v000011FEd00000802* + ID_PRODUCT_FROM_DATABASE=RocketPort UPCI 8 port w/external I/F + +pci:v000011FEd00000803* + ID_PRODUCT_FROM_DATABASE=RocketPort UPCI 16 port w/external I/F + +pci:v000011FEd00000805* + ID_PRODUCT_FROM_DATABASE=RocketPort UPCI 8 port w/octa cable + +pci:v000011FEd0000080C* + ID_PRODUCT_FROM_DATABASE=RocketModem III 8 port + +pci:v000011FEd0000080D* + ID_PRODUCT_FROM_DATABASE=RocketModem III 4 port + +pci:v000011FEd00000810* + ID_PRODUCT_FROM_DATABASE=RocketPort UPCI Plus 4 port RS232 + +pci:v000011FEd00000811* + ID_PRODUCT_FROM_DATABASE=RocketPort UPCI Plus 8 port RS232 + +pci:v000011FEd00000812* + ID_PRODUCT_FROM_DATABASE=RocketPort UPCI Plus 8 port RS422 + +pci:v000011FEd00000903* + ID_PRODUCT_FROM_DATABASE=RocketPort Compact PCI 16 port w/external I/F + +pci:v000011FEd00008015* + ID_PRODUCT_FROM_DATABASE=RocketPort 4-port UART 16954 + +pci:v000011FF* + ID_VENDOR_FROM_DATABASE=Scion Corporation + +pci:v000011FFd00000003* + ID_PRODUCT_FROM_DATABASE=AG-5 + +pci:v00001200* + ID_VENDOR_FROM_DATABASE=CSS Corporation + +pci:v00001201* + ID_VENDOR_FROM_DATABASE=Vista Controls Corp + +pci:v00001202* + ID_VENDOR_FROM_DATABASE=Network General Corp. + +pci:v00001202d00004300* + ID_PRODUCT_FROM_DATABASE=Gigabit Ethernet Adapter + +pci:v00001202d00004300sv00001202sd00009841* + ID_PRODUCT_FROM_DATABASE=SK-9841 LX + +pci:v00001202d00004300sv00001202sd00009842* + ID_PRODUCT_FROM_DATABASE=SK-9841 LX dual link + +pci:v00001202d00004300sv00001202sd00009843* + ID_PRODUCT_FROM_DATABASE=SK-9843 SX + +pci:v00001202d00004300sv00001202sd00009844* + ID_PRODUCT_FROM_DATABASE=SK-9843 SX dual link + +pci:v00001203* + ID_VENDOR_FROM_DATABASE=Bayer Corporation, Agfa Division + +pci:v00001204* + ID_VENDOR_FROM_DATABASE=Lattice Semiconductor Corporation + +pci:v00001205* + ID_VENDOR_FROM_DATABASE=Array Corporation + +pci:v00001206* + ID_VENDOR_FROM_DATABASE=Amdahl Corporation + +pci:v00001208* + ID_VENDOR_FROM_DATABASE=Parsytec GmbH + +pci:v00001208d00004853* + ID_PRODUCT_FROM_DATABASE=HS-Link Device + +pci:v00001209* + ID_VENDOR_FROM_DATABASE=SCI Systems Inc + +pci:v0000120A* + ID_VENDOR_FROM_DATABASE=Synaptel + +pci:v0000120B* + ID_VENDOR_FROM_DATABASE=Adaptive Solutions + +pci:v0000120C* + ID_VENDOR_FROM_DATABASE=Technical Corp. + +pci:v0000120D* + ID_VENDOR_FROM_DATABASE=Compression Labs, Inc. + +pci:v0000120E* + ID_VENDOR_FROM_DATABASE=Cyclades Corporation + +pci:v0000120Ed00000100* + ID_PRODUCT_FROM_DATABASE=Cyclom-Y below first megabyte + +pci:v0000120Ed00000101* + ID_PRODUCT_FROM_DATABASE=Cyclom-Y above first megabyte + +pci:v0000120Ed00000102* + ID_PRODUCT_FROM_DATABASE=Cyclom-4Y below first megabyte + +pci:v0000120Ed00000103* + ID_PRODUCT_FROM_DATABASE=Cyclom-4Y above first megabyte + +pci:v0000120Ed00000104* + ID_PRODUCT_FROM_DATABASE=Cyclom-8Y below first megabyte + +pci:v0000120Ed00000105* + ID_PRODUCT_FROM_DATABASE=Cyclom-8Y above first megabyte + +pci:v0000120Ed00000200* + ID_PRODUCT_FROM_DATABASE=Cyclades-Z below first megabyte + +pci:v0000120Ed00000201* + ID_PRODUCT_FROM_DATABASE=Cyclades-Z above first megabyte + +pci:v0000120Ed00000300* + ID_PRODUCT_FROM_DATABASE=PC300/RSV or /X21 (2 ports) + +pci:v0000120Ed00000301* + ID_PRODUCT_FROM_DATABASE=PC300/RSV or /X21 (1 port) + +pci:v0000120Ed00000310* + ID_PRODUCT_FROM_DATABASE=PC300/TE (2 ports) + +pci:v0000120Ed00000311* + ID_PRODUCT_FROM_DATABASE=PC300/TE (1 port) + +pci:v0000120Ed00000320* + ID_PRODUCT_FROM_DATABASE=PC300/TE-M (2 ports) + +pci:v0000120Ed00000321* + ID_PRODUCT_FROM_DATABASE=PC300/TE-M (1 port) + +pci:v0000120Ed00000400* + ID_PRODUCT_FROM_DATABASE=PC400 + +pci:v0000120F* + ID_VENDOR_FROM_DATABASE=Essential Communications + +pci:v0000120Fd00000001* + ID_PRODUCT_FROM_DATABASE=Roadrunner serial HIPPI + +pci:v00001210* + ID_VENDOR_FROM_DATABASE=Hyperparallel Technologies + +pci:v00001211* + ID_VENDOR_FROM_DATABASE=Braintech Inc + +pci:v00001212* + ID_VENDOR_FROM_DATABASE=Kingston Technology Corp. + +pci:v00001213* + ID_VENDOR_FROM_DATABASE=Applied Intelligent Systems, Inc. + +pci:v00001214* + ID_VENDOR_FROM_DATABASE=Performance Technologies, Inc. + +pci:v00001215* + ID_VENDOR_FROM_DATABASE=Interware Co., Ltd + +pci:v00001216* + ID_VENDOR_FROM_DATABASE=Purup Prepress A/S + +pci:v00001217* + ID_VENDOR_FROM_DATABASE=O2 Micro, Inc. + +pci:v00001217d000000F7* + ID_PRODUCT_FROM_DATABASE=Firewire (IEEE 1394) + +pci:v00001217d000000F7sv00001179sd0000FF50* + ID_PRODUCT_FROM_DATABASE=Satellite P305D-S8995E + +pci:v00001217d000010F7* + ID_PRODUCT_FROM_DATABASE=1394 OHCI Compliant Host Controller + +pci:v00001217d000011F7* + ID_PRODUCT_FROM_DATABASE=OZ600 1394a-2000 Controller + +pci:v00001217d000013F7* + ID_PRODUCT_FROM_DATABASE=1394 OHCI Compliant Host Controller + +pci:v00001217d00006729* + ID_PRODUCT_FROM_DATABASE=OZ6729 + +pci:v00001217d0000673A* + ID_PRODUCT_FROM_DATABASE=OZ6730 + +pci:v00001217d00006832* + ID_PRODUCT_FROM_DATABASE=OZ6832/6833 CardBus Controller + +pci:v00001217d00006836* + ID_PRODUCT_FROM_DATABASE=OZ6836/6860 CardBus Controller + +pci:v00001217d00006872* + ID_PRODUCT_FROM_DATABASE=OZ6812 CardBus Controller + +pci:v00001217d00006925* + ID_PRODUCT_FROM_DATABASE=OZ6922 CardBus Controller + +pci:v00001217d00006933* + ID_PRODUCT_FROM_DATABASE=OZ6933/711E1 CardBus/SmartCardBus Controller + +pci:v00001217d00006933sv00001025sd00001016* + ID_PRODUCT_FROM_DATABASE=Travelmate 612 TX + +pci:v00001217d00006972* + ID_PRODUCT_FROM_DATABASE=OZ601/6912/711E0 CardBus/SmartCardBus Controller + +pci:v00001217d00006972sv00001014sd0000020C* + ID_PRODUCT_FROM_DATABASE=ThinkPad R30 + +pci:v00001217d00006972sv00001028sd00000152* + ID_PRODUCT_FROM_DATABASE=Latitude D500 + +pci:v00001217d00006972sv00001179sd00000001* + ID_PRODUCT_FROM_DATABASE=Magnia Z310 + +pci:v00001217d00007110* + ID_PRODUCT_FROM_DATABASE=OZ711Mx 4-in-1 MemoryCardBus Accelerator + +pci:v00001217d00007110sv0000103Csd0000088C* + ID_PRODUCT_FROM_DATABASE=NC8000 laptop + +pci:v00001217d00007110sv0000103Csd00000890* + ID_PRODUCT_FROM_DATABASE=NC6000 laptop + +pci:v00001217d00007110sv00001734sd0000106C* + ID_PRODUCT_FROM_DATABASE=Amilo A1645 + +pci:v00001217d00007112* + ID_PRODUCT_FROM_DATABASE=OZ711EC1/M1 SmartCardBus/MemoryCardBus Controller + +pci:v00001217d00007113* + ID_PRODUCT_FROM_DATABASE=OZ711EC1 SmartCardBus Controller + +pci:v00001217d00007113sv00001025sd00000035* + ID_PRODUCT_FROM_DATABASE=TravelMate 660 + +pci:v00001217d00007114* + ID_PRODUCT_FROM_DATABASE=OZ711M1/MC1 4-in-1 MemoryCardBus Controller + +pci:v00001217d00007120* + ID_PRODUCT_FROM_DATABASE=Integrated MMC/SD Controller + +pci:v00001217d00007120sv00001179sd0000FF50* + ID_PRODUCT_FROM_DATABASE=Satellite P305D-S8995E + +pci:v00001217d00007130* + ID_PRODUCT_FROM_DATABASE=Integrated MS/xD Controller + +pci:v00001217d00007130sv00001179sd0000FF50* + ID_PRODUCT_FROM_DATABASE=Satellite P305D-S8995E + +pci:v00001217d00007134* + ID_PRODUCT_FROM_DATABASE=OZ711MP1/MS1 MemoryCardBus Controller + +pci:v00001217d00007135* + ID_PRODUCT_FROM_DATABASE=Cardbus bridge + +pci:v00001217d00007136* + ID_PRODUCT_FROM_DATABASE=OZ711SP1 Memory CardBus Controller + +pci:v00001217d000071E2* + ID_PRODUCT_FROM_DATABASE=OZ711E2 SmartCardBus Controller + +pci:v00001217d00007212* + ID_PRODUCT_FROM_DATABASE=OZ711M2 4-in-1 MemoryCardBus Controller + +pci:v00001217d00007213* + ID_PRODUCT_FROM_DATABASE=OZ6933E CardBus Controller + +pci:v00001217d00007223* + ID_PRODUCT_FROM_DATABASE=OZ711M3/MC3 4-in-1 MemoryCardBus Controller + +pci:v00001217d00007223sv0000103Csd0000088C* + ID_PRODUCT_FROM_DATABASE=NC8000 laptop + +pci:v00001217d00007223sv0000103Csd00000890* + ID_PRODUCT_FROM_DATABASE=NC6000 laptop + +pci:v00001217d00007223sv000010CFsd000011C4* + ID_PRODUCT_FROM_DATABASE=Lifebook P5020D Laptop + +pci:v00001217d00007233* + ID_PRODUCT_FROM_DATABASE=OZ711MP3/MS3 4-in-1 MemoryCardBus Controller + +pci:v00001217d00008120* + ID_PRODUCT_FROM_DATABASE=Integrated MMC/SD Controller + +pci:v00001217d00008130* + ID_PRODUCT_FROM_DATABASE=Integrated MS/MSPRO/xD Controller + +pci:v00001217d00008321* + ID_PRODUCT_FROM_DATABASE=Integrated MMC/SD controller + +pci:v00001217d00008331* + ID_PRODUCT_FROM_DATABASE=O2 Flash Memory Card + +pci:v00001218* + ID_VENDOR_FROM_DATABASE=Hybricon Corp. + +pci:v00001219* + ID_VENDOR_FROM_DATABASE=First Virtual Corporation + +pci:v0000121A* + ID_VENDOR_FROM_DATABASE=3Dfx Interactive, Inc. + +pci:v0000121Ad00000001* + ID_PRODUCT_FROM_DATABASE=Voodoo + +pci:v0000121Ad00000002* + ID_PRODUCT_FROM_DATABASE=Voodoo 2 + +pci:v0000121Ad00000003* + ID_PRODUCT_FROM_DATABASE=Voodoo Banshee + +pci:v0000121Ad00000003sv00001092sd00000003* + ID_PRODUCT_FROM_DATABASE=Monster Fusion + +pci:v0000121Ad00000003sv00001092sd00004000* + ID_PRODUCT_FROM_DATABASE=Monster Fusion + +pci:v0000121Ad00000003sv00001092sd00004002* + ID_PRODUCT_FROM_DATABASE=Monster Fusion + +pci:v0000121Ad00000003sv00001092sd00004801* + ID_PRODUCT_FROM_DATABASE=Monster Fusion AGP + +pci:v0000121Ad00000003sv00001092sd00004803* + ID_PRODUCT_FROM_DATABASE=Monster Fusion AGP + +pci:v0000121Ad00000003sv00001092sd00008030* + ID_PRODUCT_FROM_DATABASE=Monster Fusion + +pci:v0000121Ad00000003sv00001092sd00008035* + ID_PRODUCT_FROM_DATABASE=Monster Fusion AGP + +pci:v0000121Ad00000003sv000010B0sd00000001* + ID_PRODUCT_FROM_DATABASE=Dragon 4000 + +pci:v0000121Ad00000003sv00001102sd00001017* + ID_PRODUCT_FROM_DATABASE=3D Blaster Banshee PCI (CT6760) + +pci:v0000121Ad00000003sv00001102sd00001018* + ID_PRODUCT_FROM_DATABASE=3D Blaster Banshee VE + +pci:v0000121Ad00000003sv0000121Asd00000001* + ID_PRODUCT_FROM_DATABASE=Voodoo Banshee AGP + +pci:v0000121Ad00000003sv0000121Asd00000003* + ID_PRODUCT_FROM_DATABASE=Voodoo Banshee AGP SGRAM + +pci:v0000121Ad00000003sv0000121Asd00000004* + ID_PRODUCT_FROM_DATABASE=Voodoo Banshee + +pci:v0000121Ad00000003sv0000139Csd00000016* + ID_PRODUCT_FROM_DATABASE=Raven + +pci:v0000121Ad00000003sv0000139Csd00000017* + ID_PRODUCT_FROM_DATABASE=Raven + +pci:v0000121Ad00000003sv000014AFsd00000002* + ID_PRODUCT_FROM_DATABASE=Maxi Gamer Phoenix + +pci:v0000121Ad00000004* + ID_PRODUCT_FROM_DATABASE=Voodoo Banshee [Velocity 100] + +pci:v0000121Ad00000005* + ID_PRODUCT_FROM_DATABASE=Voodoo 3 + +pci:v0000121Ad00000005sv0000121Asd00000004* + ID_PRODUCT_FROM_DATABASE=Voodoo3 AGP + +pci:v0000121Ad00000005sv0000121Asd00000030* + ID_PRODUCT_FROM_DATABASE=Voodoo3 AGP + +pci:v0000121Ad00000005sv0000121Asd00000031* + ID_PRODUCT_FROM_DATABASE=Voodoo3 AGP + +pci:v0000121Ad00000005sv0000121Asd00000034* + ID_PRODUCT_FROM_DATABASE=Voodoo3 AGP + +pci:v0000121Ad00000005sv0000121Asd00000036* + ID_PRODUCT_FROM_DATABASE=Voodoo3 2000 PCI + +pci:v0000121Ad00000005sv0000121Asd00000037* + ID_PRODUCT_FROM_DATABASE=Voodoo3 AGP + +pci:v0000121Ad00000005sv0000121Asd00000038* + ID_PRODUCT_FROM_DATABASE=Voodoo3 AGP + +pci:v0000121Ad00000005sv0000121Asd0000003A* + ID_PRODUCT_FROM_DATABASE=Voodoo3 AGP + +pci:v0000121Ad00000005sv0000121Asd00000044* + ID_PRODUCT_FROM_DATABASE=Voodoo3 + +pci:v0000121Ad00000005sv0000121Asd0000004B* + ID_PRODUCT_FROM_DATABASE=Velocity 100 + +pci:v0000121Ad00000005sv0000121Asd0000004C* + ID_PRODUCT_FROM_DATABASE=Velocity 200 + +pci:v0000121Ad00000005sv0000121Asd0000004D* + ID_PRODUCT_FROM_DATABASE=Voodoo3 AGP + +pci:v0000121Ad00000005sv0000121Asd0000004E* + ID_PRODUCT_FROM_DATABASE=Voodoo3 AGP + +pci:v0000121Ad00000005sv0000121Asd00000051* + ID_PRODUCT_FROM_DATABASE=Voodoo3 AGP + +pci:v0000121Ad00000005sv0000121Asd00000052* + ID_PRODUCT_FROM_DATABASE=Voodoo3 AGP + +pci:v0000121Ad00000005sv0000121Asd00000057* + ID_PRODUCT_FROM_DATABASE=Voodoo3 3000 PCI + +pci:v0000121Ad00000005sv0000121Asd00000060* + ID_PRODUCT_FROM_DATABASE=Voodoo3 3500 TV (NTSC) + +pci:v0000121Ad00000005sv0000121Asd00000061* + ID_PRODUCT_FROM_DATABASE=Voodoo3 3500 TV (PAL) + +pci:v0000121Ad00000005sv0000121Asd00000062* + ID_PRODUCT_FROM_DATABASE=Voodoo3 3500 TV (SECAM) + +pci:v0000121Ad00000009* + ID_PRODUCT_FROM_DATABASE=Voodoo 4 / Voodoo 5 + +pci:v0000121Ad00000009sv0000121Asd00000003* + ID_PRODUCT_FROM_DATABASE=Voodoo5 PCI 5500 + +pci:v0000121Ad00000009sv0000121Asd00000009* + ID_PRODUCT_FROM_DATABASE=Voodoo5 AGP 5500/6000 + +pci:v0000121Ad00000057* + ID_PRODUCT_FROM_DATABASE=Voodoo 3/3000 [Avenger] + +pci:v0000121B* + ID_VENDOR_FROM_DATABASE=Advanced Telecommunications Modules + +pci:v0000121C* + ID_VENDOR_FROM_DATABASE=Nippon Texaco., Ltd + +pci:v0000121D* + ID_VENDOR_FROM_DATABASE=LiPPERT ADLINK Technology GmbH + +pci:v0000121E* + ID_VENDOR_FROM_DATABASE=CSPI + +pci:v0000121Ed00000201* + ID_PRODUCT_FROM_DATABASE=Myrinet 2000 Scalable Cluster Interconnect + +pci:v0000121F* + ID_VENDOR_FROM_DATABASE=Arcus Technology, Inc. + +pci:v00001220* + ID_VENDOR_FROM_DATABASE=Ariel Corporation + +pci:v00001220d00001220* + ID_PRODUCT_FROM_DATABASE=AMCC 5933 TMS320C80 DSP/Imaging board + +pci:v00001221* + ID_VENDOR_FROM_DATABASE=Contec Co., Ltd + +pci:v00001221d00009172* + ID_PRODUCT_FROM_DATABASE=PO-64L(PCI)H [Isolated Digital Output Board for PCI] + +pci:v00001221d000091A2* + ID_PRODUCT_FROM_DATABASE=PO-32L(PCI)H [Isolated Digital Output Board for PCI] + +pci:v00001221d000091C3* + ID_PRODUCT_FROM_DATABASE=DA16-16(LPCI)L [Un-insulated highly precise analog output board for Low Profile PCI] + +pci:v00001221d0000B152* + ID_PRODUCT_FROM_DATABASE=DIO-96D2-LPCI + +pci:v00001221d0000C103* + ID_PRODUCT_FROM_DATABASE=ADA16-32/2(PCI)F [High-Speed Analog I/O Board for PCI] + +pci:v00001222* + ID_VENDOR_FROM_DATABASE=Ancor Communications, Inc. + +pci:v00001223* + ID_VENDOR_FROM_DATABASE=Artesyn Communication Products + +pci:v00001223d00000003* + ID_PRODUCT_FROM_DATABASE=PM/Link + +pci:v00001223d00000004* + ID_PRODUCT_FROM_DATABASE=PM/T1 + +pci:v00001223d00000005* + ID_PRODUCT_FROM_DATABASE=PM/E1 + +pci:v00001223d00000008* + ID_PRODUCT_FROM_DATABASE=PM/SLS + +pci:v00001223d00000009* + ID_PRODUCT_FROM_DATABASE=BajaSpan Resource Target + +pci:v00001223d0000000A* + ID_PRODUCT_FROM_DATABASE=BajaSpan Section 0 + +pci:v00001223d0000000B* + ID_PRODUCT_FROM_DATABASE=BajaSpan Section 1 + +pci:v00001223d0000000C* + ID_PRODUCT_FROM_DATABASE=BajaSpan Section 2 + +pci:v00001223d0000000D* + ID_PRODUCT_FROM_DATABASE=BajaSpan Section 3 + +pci:v00001223d0000000E* + ID_PRODUCT_FROM_DATABASE=PM/PPC + +pci:v00001224* + ID_VENDOR_FROM_DATABASE=Interactive Images + +pci:v00001225* + ID_VENDOR_FROM_DATABASE=Power I/O, Inc. + +pci:v00001227* + ID_VENDOR_FROM_DATABASE=Tech-Source + +pci:v00001227d00000006* + ID_PRODUCT_FROM_DATABASE=Raptor GFX 8P + +pci:v00001227d00000023* + ID_PRODUCT_FROM_DATABASE=Raptor GFX [1100T] + +pci:v00001227d00000045* + ID_PRODUCT_FROM_DATABASE=Raptor 4000-L [Linux version] + +pci:v00001227d0000004A* + ID_PRODUCT_FROM_DATABASE=Raptor 4000-LR-L [Linux version] + +pci:v00001228* + ID_VENDOR_FROM_DATABASE=Norsk Elektro Optikk A/S + +pci:v00001229* + ID_VENDOR_FROM_DATABASE=Data Kinesis Inc. + +pci:v0000122A* + ID_VENDOR_FROM_DATABASE=Integrated Telecom + +pci:v0000122B* + ID_VENDOR_FROM_DATABASE=LG Industrial Systems Co., Ltd + +pci:v0000122C* + ID_VENDOR_FROM_DATABASE=Sican GmbH + +pci:v0000122D* + ID_VENDOR_FROM_DATABASE=Aztech System Ltd + +pci:v0000122Dd00001206* + ID_PRODUCT_FROM_DATABASE=368DSP + +pci:v0000122Dd00001400* + ID_PRODUCT_FROM_DATABASE=Trident PCI288-Q3DII (NX) + +pci:v0000122Dd000050DC* + ID_PRODUCT_FROM_DATABASE=3328 Audio + +pci:v0000122Dd000050DCsv0000122Dsd00000001* + ID_PRODUCT_FROM_DATABASE=3328 Audio + +pci:v0000122Dd000080DA* + ID_PRODUCT_FROM_DATABASE=3328 Audio + +pci:v0000122Dd000080DAsv0000122Dsd00000001* + ID_PRODUCT_FROM_DATABASE=3328 Audio + +pci:v0000122E* + ID_VENDOR_FROM_DATABASE=Xyratex + +pci:v0000122Ed00007722* + ID_PRODUCT_FROM_DATABASE=Napatech XL1 + +pci:v0000122Ed00007724* + ID_PRODUCT_FROM_DATABASE=Napatech XL2/XA + +pci:v0000122Ed00007729* + ID_PRODUCT_FROM_DATABASE=Napatech XD + +pci:v0000122F* + ID_VENDOR_FROM_DATABASE=Andrew Corporation + +pci:v00001230* + ID_VENDOR_FROM_DATABASE=Fishcamp Engineering + +pci:v00001231* + ID_VENDOR_FROM_DATABASE=Woodward McCoach, Inc. + +pci:v00001231d000004E1* + ID_PRODUCT_FROM_DATABASE=Desktop PCI Telephony 4 + +pci:v00001231d000005E1* + ID_PRODUCT_FROM_DATABASE=Desktop PCI Telephony 5/6 + +pci:v00001231d00000D00* + ID_PRODUCT_FROM_DATABASE=LightParser + +pci:v00001231d00000D02* + ID_PRODUCT_FROM_DATABASE=LightParser 2 + +pci:v00001231d00000D13* + ID_PRODUCT_FROM_DATABASE=Desktop PCI L1/L3 Telephony + +pci:v00001232* + ID_VENDOR_FROM_DATABASE=GPT Limited + +pci:v00001233* + ID_VENDOR_FROM_DATABASE=Bus-Tech, Inc. + +pci:v00001235* + ID_VENDOR_FROM_DATABASE=Risq Modular Systems, Inc. + +pci:v00001236* + ID_VENDOR_FROM_DATABASE=Sigma Designs Corporation + +pci:v00001236d00000000* + ID_PRODUCT_FROM_DATABASE=RealMagic64/GX + +pci:v00001236d00006401* + ID_PRODUCT_FROM_DATABASE=REALmagic 64/GX (SD 6425) + +pci:v00001237* + ID_VENDOR_FROM_DATABASE=Alta Technology Corporation + +pci:v00001238* + ID_VENDOR_FROM_DATABASE=Adtran + +pci:v00001239* + ID_VENDOR_FROM_DATABASE=3DO Company + +pci:v0000123A* + ID_VENDOR_FROM_DATABASE=Visicom Laboratories, Inc. + +pci:v0000123B* + ID_VENDOR_FROM_DATABASE=Seeq Technology, Inc. + +pci:v0000123C* + ID_VENDOR_FROM_DATABASE=Century Systems, Inc. + +pci:v0000123D* + ID_VENDOR_FROM_DATABASE=Engineering Design Team, Inc. + +pci:v0000123Dd00000000* + ID_PRODUCT_FROM_DATABASE=EasyConnect 8/32 + +pci:v0000123Dd00000002* + ID_PRODUCT_FROM_DATABASE=EasyConnect 8/64 + +pci:v0000123Dd00000003* + ID_PRODUCT_FROM_DATABASE=EasyIO + +pci:v0000123E* + ID_VENDOR_FROM_DATABASE=Simutech, Inc. + +pci:v0000123F* + ID_VENDOR_FROM_DATABASE=C-Cube Microsystems + +pci:v0000123Fd000000E4* + ID_PRODUCT_FROM_DATABASE=MPEG + +pci:v0000123Fd00008120* + ID_PRODUCT_FROM_DATABASE=E4? + +pci:v0000123Fd00008120sv000011BDsd00000006* + ID_PRODUCT_FROM_DATABASE=DV500 E4 + +pci:v0000123Fd00008120sv000011BDsd0000000A* + ID_PRODUCT_FROM_DATABASE=DV500 E4 + +pci:v0000123Fd00008120sv000011BDsd0000000F* + ID_PRODUCT_FROM_DATABASE=DV500 E4 + +pci:v0000123Fd00008120sv00001809sd00000016* + ID_PRODUCT_FROM_DATABASE=Emuzed MAUI-III PCI PVR FM TV + +pci:v0000123Fd00008888* + ID_PRODUCT_FROM_DATABASE=Cinemaster C 3.0 DVD Decoder + +pci:v0000123Fd00008888sv00001002sd00000001* + ID_PRODUCT_FROM_DATABASE=Cinemaster C 3.0 DVD Decoder + +pci:v0000123Fd00008888sv00001002sd00000002* + ID_PRODUCT_FROM_DATABASE=Cinemaster C 3.0 DVD Decoder + +pci:v0000123Fd00008888sv00001328sd00000001* + ID_PRODUCT_FROM_DATABASE=Cinemaster C 3.0 DVD Decoder + +pci:v00001240* + ID_VENDOR_FROM_DATABASE=Marathon Technologies Corp. + +pci:v00001241* + ID_VENDOR_FROM_DATABASE=DSC Communications + +pci:v00001242* + ID_VENDOR_FROM_DATABASE=JNI Corporation + +pci:v00001242d00001560* + ID_PRODUCT_FROM_DATABASE=JNIC-1560 PCI-X Fibre Channel Controller + +pci:v00001242d00001560sv00001242sd00006562* + ID_PRODUCT_FROM_DATABASE=FCX2-6562 Dual Channel PCI-X Fibre Channel Adapter + +pci:v00001242d00001560sv00001242sd0000656A* + ID_PRODUCT_FROM_DATABASE=FCX-6562 PCI-X Fibre Channel Adapter + +pci:v00001242d00004643* + ID_PRODUCT_FROM_DATABASE=FCI-1063 Fibre Channel Adapter + +pci:v00001242d00006562* + ID_PRODUCT_FROM_DATABASE=FCX2-6562 Dual Channel PCI-X Fibre Channel Adapter + +pci:v00001242d0000656A* + ID_PRODUCT_FROM_DATABASE=FCX-6562 PCI-X Fibre Channel Adapter + +pci:v00001243* + ID_VENDOR_FROM_DATABASE=Delphax + +pci:v00001244* + ID_VENDOR_FROM_DATABASE=AVM GmbH + +pci:v00001244d00000700* + ID_PRODUCT_FROM_DATABASE=B1 ISDN + +pci:v00001244d00000800* + ID_PRODUCT_FROM_DATABASE=C4 ISDN + +pci:v00001244d00000A00* + ID_PRODUCT_FROM_DATABASE=A1 ISDN [Fritz] + +pci:v00001244d00000A00sv00001244sd00000A00* + ID_PRODUCT_FROM_DATABASE=FRITZ!Card ISDN Controller + +pci:v00001244d00000E00* + ID_PRODUCT_FROM_DATABASE=Fritz!PCI v2.0 ISDN + +pci:v00001244d00001100* + ID_PRODUCT_FROM_DATABASE=C2 ISDN + +pci:v00001244d00001200* + ID_PRODUCT_FROM_DATABASE=T1 ISDN + +pci:v00001244d00002700* + ID_PRODUCT_FROM_DATABASE=Fritz!Card DSL SL + +pci:v00001244d00002900* + ID_PRODUCT_FROM_DATABASE=Fritz!Card DSL v2.0 + +pci:v00001245* + ID_VENDOR_FROM_DATABASE=A.P.D., S.A. + +pci:v00001246* + ID_VENDOR_FROM_DATABASE=Dipix Technologies, Inc. + +pci:v00001247* + ID_VENDOR_FROM_DATABASE=Xylon Research, Inc. + +pci:v00001248* + ID_VENDOR_FROM_DATABASE=Central Data Corporation + +pci:v00001249* + ID_VENDOR_FROM_DATABASE=Samsung Electronics Co., Ltd. + +pci:v0000124A* + ID_VENDOR_FROM_DATABASE=AEG Electrocom GmbH + +pci:v0000124B* + ID_VENDOR_FROM_DATABASE=SBS/Greenspring Modular I/O + +pci:v0000124Bd00000040* + ID_PRODUCT_FROM_DATABASE=PCI-40A or cPCI-200 Quad IndustryPack carrier + +pci:v0000124Bd00000040sv0000124Bsd00009080* + ID_PRODUCT_FROM_DATABASE=PCI9080 Bridge + +pci:v0000124C* + ID_VENDOR_FROM_DATABASE=Solitron Technologies, Inc. + +pci:v0000124D* + ID_VENDOR_FROM_DATABASE=Stallion Technologies, Inc. + +pci:v0000124Dd00000000* + ID_PRODUCT_FROM_DATABASE=EasyConnection 8/32 + +pci:v0000124Dd00000002* + ID_PRODUCT_FROM_DATABASE=EasyConnection 8/64 + +pci:v0000124Dd00000003* + ID_PRODUCT_FROM_DATABASE=EasyIO + +pci:v0000124Dd00000004* + ID_PRODUCT_FROM_DATABASE=EasyConnection/RA + +pci:v0000124E* + ID_VENDOR_FROM_DATABASE=Cylink + +pci:v0000124F* + ID_VENDOR_FROM_DATABASE=Infortrend Technology, Inc. + +pci:v0000124Fd00000041* + ID_PRODUCT_FROM_DATABASE=IFT-2000 Series RAID Controller + +pci:v00001250* + ID_VENDOR_FROM_DATABASE=Hitachi Microcomputer System Ltd + +pci:v00001251* + ID_VENDOR_FROM_DATABASE=VLSI Solutions Oy + +pci:v00001253* + ID_VENDOR_FROM_DATABASE=Guzik Technical Enterprises + +pci:v00001254* + ID_VENDOR_FROM_DATABASE=Linear Systems Ltd. + +pci:v00001254d00000065* + ID_PRODUCT_FROM_DATABASE=DVB Master FD + +pci:v00001254d0000007C* + ID_PRODUCT_FROM_DATABASE=DVB Master Quad/o + +pci:v00001255* + ID_VENDOR_FROM_DATABASE=Optibase Ltd + +pci:v00001255d00001110* + ID_PRODUCT_FROM_DATABASE=MPEG Forge + +pci:v00001255d00001210* + ID_PRODUCT_FROM_DATABASE=MPEG Fusion + +pci:v00001255d00002110* + ID_PRODUCT_FROM_DATABASE=VideoPlex + +pci:v00001255d00002120* + ID_PRODUCT_FROM_DATABASE=VideoPlex CC + +pci:v00001255d00002130* + ID_PRODUCT_FROM_DATABASE=VideoQuest + +pci:v00001256* + ID_VENDOR_FROM_DATABASE=Perceptive Solutions, Inc. + +pci:v00001256d00004201* + ID_PRODUCT_FROM_DATABASE=PCI-2220I + +pci:v00001256d00004401* + ID_PRODUCT_FROM_DATABASE=PCI-2240I + +pci:v00001256d00005201* + ID_PRODUCT_FROM_DATABASE=PCI-2000 + +pci:v00001257* + ID_VENDOR_FROM_DATABASE=Vertex Networks, Inc. + +pci:v00001258* + ID_VENDOR_FROM_DATABASE=Gilbarco, Inc. + +pci:v00001259* + ID_VENDOR_FROM_DATABASE=Allied Telesis + +pci:v00001259d00002560* + ID_PRODUCT_FROM_DATABASE=AT-2560 Fast Ethernet Adapter (i82557B) + +pci:v00001259d00002801* + ID_PRODUCT_FROM_DATABASE=AT-2801FX (RTL-8139) + +pci:v00001259d0000A117* + ID_PRODUCT_FROM_DATABASE=RTL81xx Fast Ethernet + +pci:v00001259d0000A11E* + ID_PRODUCT_FROM_DATABASE=RTL81xx Fast Ethernet + +pci:v00001259d0000A120* + ID_PRODUCT_FROM_DATABASE=21x4x DEC-Tulip compatible 10/100 Ethernet + +pci:v0000125A* + ID_VENDOR_FROM_DATABASE=ABB Power Systems + +pci:v0000125B* + ID_VENDOR_FROM_DATABASE=Asix Electronics Corporation + +pci:v0000125Bd00001400* + ID_PRODUCT_FROM_DATABASE=AX88141 Fast Ethernet Controller + +pci:v0000125Bd00001400sv00001186sd00001100* + ID_PRODUCT_FROM_DATABASE=AX8814X Based PCI Fast Ethernet Adapter + +pci:v0000125C* + ID_VENDOR_FROM_DATABASE=Aurora Technologies, Inc. + +pci:v0000125Cd00000101* + ID_PRODUCT_FROM_DATABASE=Saturn 4520P + +pci:v0000125Cd00000640* + ID_PRODUCT_FROM_DATABASE=Aries 16000P + +pci:v0000125D* + ID_VENDOR_FROM_DATABASE=ESS Technology + +pci:v0000125Dd00000000* + ID_PRODUCT_FROM_DATABASE=ES336H Fax Modem (Early Model) + +pci:v0000125Dd00001948* + ID_PRODUCT_FROM_DATABASE=ES1948 Maestro-1 + +pci:v0000125Dd00001968* + ID_PRODUCT_FROM_DATABASE=ES1968 Maestro 2 + +pci:v0000125Dd00001968sv00001028sd00000085* + ID_PRODUCT_FROM_DATABASE=ES1968 Maestro-2 PCI + +pci:v0000125Dd00001968sv00001033sd00008051* + ID_PRODUCT_FROM_DATABASE=ES1968 Maestro-2 Audiodrive + +pci:v0000125Dd00001969* + ID_PRODUCT_FROM_DATABASE=ES1938/ES1946/ES1969 Solo-1 Audiodrive + +pci:v0000125Dd00001969sv00001014sd00000166* + ID_PRODUCT_FROM_DATABASE=ES1969 SOLO-1 AudioDrive on IBM Aptiva Mainboard + +pci:v0000125Dd00001969sv0000125Dsd00008888* + ID_PRODUCT_FROM_DATABASE=Solo-1 Audio Adapter + +pci:v0000125Dd00001969sv0000153Bsd0000111B* + ID_PRODUCT_FROM_DATABASE=Terratec 128i PCI + +pci:v0000125Dd00001978* + ID_PRODUCT_FROM_DATABASE=ES1978 Maestro 2E + +pci:v0000125Dd00001978sv00000E11sd0000B112* + ID_PRODUCT_FROM_DATABASE=Armada M700/E500 + +pci:v0000125Dd00001978sv00001033sd0000803C* + ID_PRODUCT_FROM_DATABASE=ES1978 Maestro-2E Audiodrive + +pci:v0000125Dd00001978sv00001033sd00008058* + ID_PRODUCT_FROM_DATABASE=ES1978 Maestro-2E Audiodrive + +pci:v0000125Dd00001978sv00001092sd00004000* + ID_PRODUCT_FROM_DATABASE=Monster Sound MX400 + +pci:v0000125Dd00001978sv00001179sd00000001* + ID_PRODUCT_FROM_DATABASE=ES1978 Maestro-2E Audiodrive + +pci:v0000125Dd00001988* + ID_PRODUCT_FROM_DATABASE=ES1988 Allegro-1 + +pci:v0000125Dd00001988sv00000E11sd00000098* + ID_PRODUCT_FROM_DATABASE=Evo N600c + +pci:v0000125Dd00001988sv00001092sd00004100* + ID_PRODUCT_FROM_DATABASE=Sonic Impact S100 + +pci:v0000125Dd00001988sv0000125Dsd00000431* + ID_PRODUCT_FROM_DATABASE=Allegro AudioDrive + +pci:v0000125Dd00001988sv0000125Dsd00001988* + ID_PRODUCT_FROM_DATABASE=ESS Allegro-1 Audiodrive + +pci:v0000125Dd00001988sv0000125Dsd00001998* + ID_PRODUCT_FROM_DATABASE=Allegro AudioDrive + +pci:v0000125Dd00001988sv0000125Dsd00001999* + ID_PRODUCT_FROM_DATABASE=Allegro-1 AudioDrive + +pci:v0000125Dd00001989* + ID_PRODUCT_FROM_DATABASE=ESS Modem + +pci:v0000125Dd00001989sv0000125Dsd00001989* + ID_PRODUCT_FROM_DATABASE=ESS Modem + +pci:v0000125Dd00001998* + ID_PRODUCT_FROM_DATABASE=ES1983S Maestro-3i PCI Audio Accelerator + +pci:v0000125Dd00001998sv00001028sd000000B1* + ID_PRODUCT_FROM_DATABASE=Latitude C600 + +pci:v0000125Dd00001998sv00001028sd000000E6* + ID_PRODUCT_FROM_DATABASE=ES1983S Maestro-3i (Dell Inspiron 8100) + +pci:v0000125Dd00001999* + ID_PRODUCT_FROM_DATABASE=ES1983S Maestro-3i PCI Modem Accelerator + +pci:v0000125Dd0000199A* + ID_PRODUCT_FROM_DATABASE=ES1983S Maestro-3i PCI Audio Accelerator + +pci:v0000125Dd0000199B* + ID_PRODUCT_FROM_DATABASE=ES1983S Maestro-3i PCI Modem Accelerator + +pci:v0000125Dd00002808* + ID_PRODUCT_FROM_DATABASE=ES336H Fax Modem (Later Model) + +pci:v0000125Dd00002838* + ID_PRODUCT_FROM_DATABASE=ES2838/2839 SuperLink Modem + +pci:v0000125Dd00002898* + ID_PRODUCT_FROM_DATABASE=ES2898 Modem + +pci:v0000125Dd00002898sv0000125Dsd00000424* + ID_PRODUCT_FROM_DATABASE=ES56-PI Data Fax Modem + +pci:v0000125Dd00002898sv0000125Dsd00000425* + ID_PRODUCT_FROM_DATABASE=ES56T-PI Data Fax Modem + +pci:v0000125Dd00002898sv0000125Dsd00000426* + ID_PRODUCT_FROM_DATABASE=ES56V-PI Data Fax Modem + +pci:v0000125Dd00002898sv0000125Dsd00000427* + ID_PRODUCT_FROM_DATABASE=VW-PI Data Fax Modem + +pci:v0000125Dd00002898sv0000125Dsd00000428* + ID_PRODUCT_FROM_DATABASE=ES56ST-PI Data Fax Modem + +pci:v0000125Dd00002898sv0000125Dsd00000429* + ID_PRODUCT_FROM_DATABASE=ES56SV-PI Data Fax Modem + +pci:v0000125Dd00002898sv0000147Asd0000C001* + ID_PRODUCT_FROM_DATABASE=ES56-PI Data Fax Modem + +pci:v0000125Dd00002898sv0000148Dsd00001030* + ID_PRODUCT_FROM_DATABASE=HCF WV-PI56 [ESS ES56-PI Data Fax Modem] + +pci:v0000125Dd00002898sv000014FEsd00000428* + ID_PRODUCT_FROM_DATABASE=ES56-PI Data Fax Modem + +pci:v0000125Dd00002898sv000014FEsd00000429* + ID_PRODUCT_FROM_DATABASE=ES56-PI Data Fax Modem + +pci:v0000125E* + ID_VENDOR_FROM_DATABASE=Specialvideo Engineering SRL + +pci:v0000125F* + ID_VENDOR_FROM_DATABASE=Concurrent Technologies, Inc. + +pci:v00001260* + ID_VENDOR_FROM_DATABASE=Intersil Corporation + +pci:v00001260d00003872* + ID_PRODUCT_FROM_DATABASE=ISL3872 [Prism 3] + +pci:v00001260d00003872sv00001468sd00000202* + ID_PRODUCT_FROM_DATABASE=LAN-Express IEEE 802.11b Wireless LAN + +pci:v00001260d00003873* + ID_PRODUCT_FROM_DATABASE=ISL3874 [Prism 2.5]/ISL3872 [Prism 3] + +pci:v00001260d00003873sv000010CFsd00001169* + ID_PRODUCT_FROM_DATABASE=MBH7WM01-8734 802.11b Wireless Mini PCI Card [ISL3874] + +pci:v00001260d00003873sv00001186sd00003501* + ID_PRODUCT_FROM_DATABASE=DWL-520 Wireless PCI Adapter (rev A or B) [ISL3874] + +pci:v00001260d00003873sv00001186sd00003700* + ID_PRODUCT_FROM_DATABASE=DWL-520 Wireless PCI Adapter (rev E1) [ISL3872] + +pci:v00001260d00003873sv00001385sd00004105* + ID_PRODUCT_FROM_DATABASE=MA311 802.11b wireless adapter [ISL3874] + +pci:v00001260d00003873sv00001668sd00000414* + ID_PRODUCT_FROM_DATABASE=HWP01170-01 802.11b PCI Wireless Adapter + +pci:v00001260d00003873sv000016A5sd00001601* + ID_PRODUCT_FROM_DATABASE=AIR.mate PC-400 PCI Wireless LAN Adapter + +pci:v00001260d00003873sv00001737sd00003874* + ID_PRODUCT_FROM_DATABASE=WMP11 v1 802.11b Wireless-B PCI Adapter [ISL3874] + +pci:v00001260d00003873sv00004033sd00007033* + ID_PRODUCT_FROM_DATABASE=PCW200 802.11b Wireless PCI Adapter [ISL3874] + +pci:v00001260d00003873sv00008086sd00002510* + ID_PRODUCT_FROM_DATABASE=M3AWEB Wireless 802.11b MiniPCI Adapter + +pci:v00001260d00003873sv00008086sd00002513* + ID_PRODUCT_FROM_DATABASE=Wireless 802.11b MiniPCI Adapter + +pci:v00001260d00003877* + ID_PRODUCT_FROM_DATABASE=ISL3877 [Prism Indigo] + +pci:v00001260d00003886* + ID_PRODUCT_FROM_DATABASE=ISL3886 [Prism Javelin/Prism Xbow] + +pci:v00001260d00003886sv000017CFsd00000037* + ID_PRODUCT_FROM_DATABASE=XG-901 and clones Wireless Adapter + +pci:v00001260d00003890* + ID_PRODUCT_FROM_DATABASE=ISL3890 [Prism GT/Prism Duette]/ISL3886 [Prism Javelin/Prism Xbow] + +pci:v00001260d00003890sv000010B8sd00002802* + ID_PRODUCT_FROM_DATABASE=SMC2802W V1 Wireless PCI Adapter [ISL3890] + +pci:v00001260d00003890sv000010B8sd00002835* + ID_PRODUCT_FROM_DATABASE=SMC2835W Wireless Cardbus Adapter + +pci:v00001260d00003890sv000010B8sd0000A835* + ID_PRODUCT_FROM_DATABASE=SMC2835W V2 Wireless Cardbus Adapter + +pci:v00001260d00003890sv00001113sd00004203* + ID_PRODUCT_FROM_DATABASE=WN4201B + +pci:v00001260d00003890sv00001113sd00008201* + ID_PRODUCT_FROM_DATABASE=T-Com T-Sinus 154pcicard Wireless PCI Adapter + +pci:v00001260d00003890sv00001113sd0000B301* + ID_PRODUCT_FROM_DATABASE=T-Sinus 154card Cardbus + +pci:v00001260d00003890sv00001113sd0000EE03* + ID_PRODUCT_FROM_DATABASE=SMC2802W V2 Wireless PCI Adapter [ISL3886] + +pci:v00001260d00003890sv00001113sd0000EE08* + ID_PRODUCT_FROM_DATABASE=SMC2835W V3 EU Wireless Cardbus Adapter + +pci:v00001260d00003890sv00001186sd00003202* + ID_PRODUCT_FROM_DATABASE=DWL-G650 A1 Wireless Adapter + +pci:v00001260d00003890sv00001259sd0000C104* + ID_PRODUCT_FROM_DATABASE=CG-WLCB54GT Wireless Adapter + +pci:v00001260d00003890sv00001260sd00000000* + ID_PRODUCT_FROM_DATABASE=WG511 v1 54 Mbps Wireless PC Card + +pci:v00001260d00003890sv00001385sd00004800* + ID_PRODUCT_FROM_DATABASE=WG511 v2/v3 54 Mbps Wireless PC Card + +pci:v00001260d00003890sv000016A5sd00001605* + ID_PRODUCT_FROM_DATABASE=ALLNET ALL0271 Wireless PCI Adapter + +pci:v00001260d00003890sv000017CFsd00000014* + ID_PRODUCT_FROM_DATABASE=XG-600 and clones Wireless Adapter + +pci:v00001260d00003890sv000017CFsd00000020* + ID_PRODUCT_FROM_DATABASE=XG-900 and clones Wireless Adapter + +pci:v00001260d00003890sv0000187Esd00003403* + ID_PRODUCT_FROM_DATABASE=G-110 802.11g Wireless Cardbus Adapter + +pci:v00001260d00008130* + ID_PRODUCT_FROM_DATABASE=HMP8130 NTSC/PAL Video Decoder + +pci:v00001260d00008131* + ID_PRODUCT_FROM_DATABASE=HMP8131 NTSC/PAL Video Decoder + +pci:v00001260d0000FFFF* + ID_PRODUCT_FROM_DATABASE=ISL3886IK + +pci:v00001260d0000FFFFsv00001260sd00000000* + ID_PRODUCT_FROM_DATABASE=Senao 3054MP+ (J) mini-PCI WLAN 802.11g adapter + +pci:v00001261* + ID_VENDOR_FROM_DATABASE=Matsushita-Kotobuki Electronics Industries, Ltd. + +pci:v00001262* + ID_VENDOR_FROM_DATABASE=ES Computer Company, Ltd. + +pci:v00001263* + ID_VENDOR_FROM_DATABASE=Sonic Solutions + +pci:v00001264* + ID_VENDOR_FROM_DATABASE=Aval Nagasaki Corporation + +pci:v00001265* + ID_VENDOR_FROM_DATABASE=Casio Computer Co., Ltd. + +pci:v00001266* + ID_VENDOR_FROM_DATABASE=Microdyne Corporation + +pci:v00001266d00000001* + ID_PRODUCT_FROM_DATABASE=NE10/100 Adapter (i82557B) + +pci:v00001266d00001910* + ID_PRODUCT_FROM_DATABASE=NE2000Plus (RT8029) Ethernet Adapter + +pci:v00001266d00001910sv00001266sd00001910* + ID_PRODUCT_FROM_DATABASE=NE2000Plus Ethernet Adapter + +pci:v00001267* + ID_VENDOR_FROM_DATABASE=S. A. Telecommunications + +pci:v00001267d00005352* + ID_PRODUCT_FROM_DATABASE=PCR2101 + +pci:v00001267d00005A4B* + ID_PRODUCT_FROM_DATABASE=Telsat Turbo + +pci:v00001268* + ID_VENDOR_FROM_DATABASE=Tektronix + +pci:v00001269* + ID_VENDOR_FROM_DATABASE=Thomson-CSF/TTM + +pci:v0000126A* + ID_VENDOR_FROM_DATABASE=Lexmark International, Inc. + +pci:v0000126B* + ID_VENDOR_FROM_DATABASE=Adax, Inc. + +pci:v0000126C* + ID_VENDOR_FROM_DATABASE=Northern Telecom + +pci:v0000126Cd00001211* + ID_PRODUCT_FROM_DATABASE=10/100BaseTX [RTL81xx] + +pci:v0000126Cd0000126C* + ID_PRODUCT_FROM_DATABASE=802.11b Wireless Ethernet Adapter + +pci:v0000126D* + ID_VENDOR_FROM_DATABASE=Splash Technology, Inc. + +pci:v0000126E* + ID_VENDOR_FROM_DATABASE=Sumitomo Metal Industries, Ltd. + +pci:v0000126F* + ID_VENDOR_FROM_DATABASE=Silicon Motion, Inc. + +pci:v0000126Fd00000501* + ID_PRODUCT_FROM_DATABASE=SM501 VoyagerGX Rev. AA + +pci:v0000126Fd00000510* + ID_PRODUCT_FROM_DATABASE=SM501 VoyagerGX Rev. B + +pci:v0000126Fd00000710* + ID_PRODUCT_FROM_DATABASE=SM710 LynxEM + +pci:v0000126Fd00000712* + ID_PRODUCT_FROM_DATABASE=SM712 LynxEM+ + +pci:v0000126Fd00000720* + ID_PRODUCT_FROM_DATABASE=SM720 Lynx3DM + +pci:v0000126Fd00000730* + ID_PRODUCT_FROM_DATABASE=SM731 Cougar3DR + +pci:v0000126Fd00000810* + ID_PRODUCT_FROM_DATABASE=SM810 LynxE + +pci:v0000126Fd00000811* + ID_PRODUCT_FROM_DATABASE=SM811 LynxE + +pci:v0000126Fd00000820* + ID_PRODUCT_FROM_DATABASE=SM820 Lynx3D + +pci:v0000126Fd00000910* + ID_PRODUCT_FROM_DATABASE=SM910 + +pci:v00001270* + ID_VENDOR_FROM_DATABASE=Olympus Optical Co., Ltd. + +pci:v00001271* + ID_VENDOR_FROM_DATABASE=GW Instruments + +pci:v00001272* + ID_VENDOR_FROM_DATABASE=Telematics International + +pci:v00001273* + ID_VENDOR_FROM_DATABASE=Hughes Network Systems + +pci:v00001273d00000002* + ID_PRODUCT_FROM_DATABASE=DirecPC + +pci:v00001274* + ID_VENDOR_FROM_DATABASE=Ensoniq + +pci:v00001274d00001171* + ID_PRODUCT_FROM_DATABASE=ES1373 [AudioPCI] (also Creative Labs CT5803) + +pci:v00001274d00001371* + ID_PRODUCT_FROM_DATABASE=ES1371 [AudioPCI-97] + +pci:v00001274d00001371sv00000E11sd00000024* + ID_PRODUCT_FROM_DATABASE=AudioPCI on Motherboard Compaq Deskpro + +pci:v00001274d00001371sv00000E11sd0000B1A7* + ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI + +pci:v00001274d00001371sv00001033sd000080AC* + ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI + +pci:v00001274d00001371sv00001042sd00001854* + ID_PRODUCT_FROM_DATABASE=Tazer + +pci:v00001274d00001371sv0000107Bsd00008054* + ID_PRODUCT_FROM_DATABASE=Tabor2 + +pci:v00001274d00001371sv00001274sd00001371* + ID_PRODUCT_FROM_DATABASE=Creative Sound Blaster AudioPCI64V, AudioPCI128 + +pci:v00001274d00001371sv00001274sd00008001* + ID_PRODUCT_FROM_DATABASE=CT4751 board + +pci:v00001274d00001371sv00001462sd00006470* + ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard MS-6147 1.1A + +pci:v00001274d00001371sv00001462sd00006560* + ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard MS-6156 1.10 + +pci:v00001274d00001371sv00001462sd00006630* + ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard MS-6163BX 1.0A + +pci:v00001274d00001371sv00001462sd00006631* + ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard MS-6163VIA 1.0A + +pci:v00001274d00001371sv00001462sd00006632* + ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard MS-6163BX 2.0A + +pci:v00001274d00001371sv00001462sd00006633* + ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard MS-6163VIA 2.0A + +pci:v00001274d00001371sv00001462sd00006820* + ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard MS-6182 1.00 + +pci:v00001274d00001371sv00001462sd00006822* + ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard MS-6182 1.00A + +pci:v00001274d00001371sv00001462sd00006830* + ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard MS-6183 1.00 + +pci:v00001274d00001371sv00001462sd00006880* + ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard MS-6188 1.00 + +pci:v00001274d00001371sv00001462sd00006900* + ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard MS-6190 1.00 + +pci:v00001274d00001371sv00001462sd00006910* + ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard MS-6191 + +pci:v00001274d00001371sv00001462sd00006930* + ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard MS-6193 + +pci:v00001274d00001371sv00001462sd00006990* + ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard MS-6199BX 2.0A + +pci:v00001274d00001371sv00001462sd00006991* + ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard MS-6199VIA 2.0A + +pci:v00001274d00001371sv000014A4sd00002077* + ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard KR639 + +pci:v00001274d00001371sv000014A4sd00002105* + ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard MR800 + +pci:v00001274d00001371sv000014A4sd00002107* + ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard MR801 + +pci:v00001274d00001371sv000014A4sd00002172* + ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard DR739 + +pci:v00001274d00001371sv00001509sd00009902* + ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard KW11 + +pci:v00001274d00001371sv00001509sd00009903* + ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard KW31 + +pci:v00001274d00001371sv00001509sd00009904* + ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard KA11 + +pci:v00001274d00001371sv00001509sd00009905* + ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard KC13 + +pci:v00001274d00001371sv0000152Dsd00008801* + ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard CP810E + +pci:v00001274d00001371sv0000152Dsd00008802* + ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard CP810 + +pci:v00001274d00001371sv0000152Dsd00008803* + ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard P3810E + +pci:v00001274d00001371sv0000152Dsd00008804* + ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard P3810-S + +pci:v00001274d00001371sv0000152Dsd00008805* + ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard P3820-S + +pci:v00001274d00001371sv0000270Fsd00002001* + ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard 6CTR + +pci:v00001274d00001371sv0000270Fsd00002200* + ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard 6WTX + +pci:v00001274d00001371sv0000270Fsd00003000* + ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard 6WSV + +pci:v00001274d00001371sv0000270Fsd00003100* + ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard 6WIV2 + +pci:v00001274d00001371sv0000270Fsd00003102* + ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard 6WIV + +pci:v00001274d00001371sv0000270Fsd00007060* + ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard 6ASA2 + +pci:v00001274d00001371sv00008086sd00004249* + ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard BI440ZX + +pci:v00001274d00001371sv00008086sd0000424C* + ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard BL440ZX + +pci:v00001274d00001371sv00008086sd0000425A* + ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard BZ440ZX + +pci:v00001274d00001371sv00008086sd00004341* + ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard Cayman + +pci:v00001274d00001371sv00008086sd00004343* + ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard Cape Cod + +pci:v00001274d00001371sv00008086sd00004541* + ID_PRODUCT_FROM_DATABASE=D815EEA Motherboard + +pci:v00001274d00001371sv00008086sd00004649* + ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard Fire Island + +pci:v00001274d00001371sv00008086sd0000464A* + ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard FJ440ZX + +pci:v00001274d00001371sv00008086sd00004D4F* + ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard Montreal + +pci:v00001274d00001371sv00008086sd00004F43* + ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard OC440LX + +pci:v00001274d00001371sv00008086sd00005243* + ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard RC440BX + +pci:v00001274d00001371sv00008086sd00005352* + ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard SunRiver + +pci:v00001274d00001371sv00008086sd00005643* + ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard Vancouver + +pci:v00001274d00001371sv00008086sd00005753* + ID_PRODUCT_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard WS440BX + +pci:v00001274d00005000* + ID_PRODUCT_FROM_DATABASE=ES1370 [AudioPCI] + +pci:v00001274d00005880* + ID_PRODUCT_FROM_DATABASE=5880B [AudioPCI] + +pci:v00001274d00005880sv00001274sd00002000* + ID_PRODUCT_FROM_DATABASE=Creative Sound Blaster AudioPCI128 + +pci:v00001274d00005880sv00001274sd00002003* + ID_PRODUCT_FROM_DATABASE=Creative SoundBlaster AudioPCI 128 + +pci:v00001274d00005880sv00001274sd00005880* + ID_PRODUCT_FROM_DATABASE=Creative Sound Blaster AudioPCI128 + +pci:v00001274d00005880sv00001274sd00008001* + ID_PRODUCT_FROM_DATABASE=Sound Blaster 16PCI 4.1ch + +pci:v00001274d00005880sv00001458sd0000A000* + ID_PRODUCT_FROM_DATABASE=5880 AudioPCI On Motherboard 6OXET + +pci:v00001274d00005880sv00001462sd00006880* + ID_PRODUCT_FROM_DATABASE=5880 AudioPCI On Motherboard MS-6188 1.00 + +pci:v00001274d00005880sv0000270Fsd00002001* + ID_PRODUCT_FROM_DATABASE=5880 AudioPCI On Motherboard 6CTR + +pci:v00001274d00005880sv0000270Fsd00002200* + ID_PRODUCT_FROM_DATABASE=5880 AudioPCI On Motherboard 6WTX + +pci:v00001274d00005880sv0000270Fsd00007040* + ID_PRODUCT_FROM_DATABASE=5880 AudioPCI On Motherboard 6ATA4 + +pci:v00001274d00008001* + ID_PRODUCT_FROM_DATABASE=CT5880 [AudioPCI] + +pci:v00001274d00008002* + ID_PRODUCT_FROM_DATABASE=5880A [AudioPCI] + +pci:v00001275* + ID_VENDOR_FROM_DATABASE=Network Appliance Corporation + +pci:v00001276* + ID_VENDOR_FROM_DATABASE=Switched Network Technologies, Inc. + +pci:v00001277* + ID_VENDOR_FROM_DATABASE=Comstream + +pci:v00001278* + ID_VENDOR_FROM_DATABASE=Transtech Parallel Systems Ltd. + +pci:v00001278d00000701* + ID_PRODUCT_FROM_DATABASE=TPE3/TM3 PowerPC Node + +pci:v00001278d00000710* + ID_PRODUCT_FROM_DATABASE=TPE5 PowerPC PCI board + +pci:v00001278d00001100* + ID_PRODUCT_FROM_DATABASE=PMC-FPGA02 + +pci:v00001278d00001101* + ID_PRODUCT_FROM_DATABASE=TS-C43 card with 4 ADSP-TS101 processors + +pci:v00001279* + ID_VENDOR_FROM_DATABASE=Transmeta Corporation + +pci:v00001279d00000060* + ID_PRODUCT_FROM_DATABASE=TM8000 Northbridge + +pci:v00001279d00000061* + ID_PRODUCT_FROM_DATABASE=TM8000 AGP bridge + +pci:v00001279d00000295* + ID_PRODUCT_FROM_DATABASE=Northbridge + +pci:v00001279d00000395* + ID_PRODUCT_FROM_DATABASE=LongRun Northbridge + +pci:v00001279d00000396* + ID_PRODUCT_FROM_DATABASE=SDRAM controller + +pci:v00001279d00000397* + ID_PRODUCT_FROM_DATABASE=BIOS scratchpad + +pci:v0000127A* + ID_VENDOR_FROM_DATABASE=Rockwell International + +pci:v0000127Ad00001002* + ID_PRODUCT_FROM_DATABASE=HCF 56k Data/Fax Modem + +pci:v0000127Ad00001002sv00001092sd0000094C* + ID_PRODUCT_FROM_DATABASE=SupraExpress 56i PRO [Diamond SUP2380] + +pci:v0000127Ad00001002sv0000122Dsd00004002* + ID_PRODUCT_FROM_DATABASE=HPG / MDP3858-U + +pci:v0000127Ad00001002sv0000122Dsd00004005* + ID_PRODUCT_FROM_DATABASE=MDP3858-E + +pci:v0000127Ad00001002sv0000122Dsd00004007* + ID_PRODUCT_FROM_DATABASE=MDP3858-A/-NZ + +pci:v0000127Ad00001002sv0000122Dsd00004012* + ID_PRODUCT_FROM_DATABASE=MDP3858-SA + +pci:v0000127Ad00001002sv0000122Dsd00004017* + ID_PRODUCT_FROM_DATABASE=MDP3858-W + +pci:v0000127Ad00001002sv0000122Dsd00004018* + ID_PRODUCT_FROM_DATABASE=MDP3858-W + +pci:v0000127Ad00001002sv0000127Asd00001002* + ID_PRODUCT_FROM_DATABASE=Rockwell 56K D/F HCF Modem + +pci:v0000127Ad00001003* + ID_PRODUCT_FROM_DATABASE=HCF 56k Data/Fax Modem + +pci:v0000127Ad00001003sv00000E11sd0000B0BC* + ID_PRODUCT_FROM_DATABASE=229-DF Zephyr + +pci:v0000127Ad00001003sv00000E11sd0000B114* + ID_PRODUCT_FROM_DATABASE=229-DF Cheetah + +pci:v0000127Ad00001003sv00001033sd0000802B* + ID_PRODUCT_FROM_DATABASE=229-DF + +pci:v0000127Ad00001003sv000013DFsd00001003* + ID_PRODUCT_FROM_DATABASE=PCI56RX Modem + +pci:v0000127Ad00001003sv000013E0sd00000117* + ID_PRODUCT_FROM_DATABASE=IBM + +pci:v0000127Ad00001003sv000013E0sd00000147* + ID_PRODUCT_FROM_DATABASE=IBM F-1156IV+/R3 Spain V.90 Modem + +pci:v0000127Ad00001003sv000013E0sd00000197* + ID_PRODUCT_FROM_DATABASE=IBM + +pci:v0000127Ad00001003sv000013E0sd000001C7* + ID_PRODUCT_FROM_DATABASE=IBM F-1156IV+/R3 WW V.90 Modem + +pci:v0000127Ad00001003sv000013E0sd000001F7* + ID_PRODUCT_FROM_DATABASE=IBM + +pci:v0000127Ad00001003sv00001436sd00001003* + ID_PRODUCT_FROM_DATABASE=IBM + +pci:v0000127Ad00001003sv00001436sd00001103* + ID_PRODUCT_FROM_DATABASE=IBM 5614PM3G V.90 Modem + +pci:v0000127Ad00001003sv00001436sd00001602* + ID_PRODUCT_FROM_DATABASE=Compaq 229-DF Ducati + +pci:v0000127Ad00001004* + ID_PRODUCT_FROM_DATABASE=HCF 56k Data/Fax/Voice Modem + +pci:v0000127Ad00001004sv00001048sd00001500* + ID_PRODUCT_FROM_DATABASE=MicroLink 56k Modem + +pci:v0000127Ad00001004sv000010CFsd00001059* + ID_PRODUCT_FROM_DATABASE=Fujitsu 229-DFRT + +pci:v0000127Ad00001005* + ID_PRODUCT_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem + +pci:v0000127Ad00001005sv00001005sd0000127A* + ID_PRODUCT_FROM_DATABASE=AOpen FM56-P + +pci:v0000127Ad00001005sv00001033sd00008029* + ID_PRODUCT_FROM_DATABASE=229-DFSV + +pci:v0000127Ad00001005sv00001033sd00008054* + ID_PRODUCT_FROM_DATABASE=Modem + +pci:v0000127Ad00001005sv000010CFsd0000103C* + ID_PRODUCT_FROM_DATABASE=Fujitsu + +pci:v0000127Ad00001005sv000010CFsd00001055* + ID_PRODUCT_FROM_DATABASE=Fujitsu 229-DFSV + +pci:v0000127Ad00001005sv000010CFsd00001056* + ID_PRODUCT_FROM_DATABASE=Fujitsu 229-DFSV + +pci:v0000127Ad00001005sv0000122Dsd00004003* + ID_PRODUCT_FROM_DATABASE=MDP3858SP-U + +pci:v0000127Ad00001005sv0000122Dsd00004006* + ID_PRODUCT_FROM_DATABASE=Packard Bell MDP3858V-E + +pci:v0000127Ad00001005sv0000122Dsd00004008* + ID_PRODUCT_FROM_DATABASE=MDP3858SP-A/SP-NZ + +pci:v0000127Ad00001005sv0000122Dsd00004009* + ID_PRODUCT_FROM_DATABASE=MDP3858SP-E + +pci:v0000127Ad00001005sv0000122Dsd00004010* + ID_PRODUCT_FROM_DATABASE=MDP3858V-U + +pci:v0000127Ad00001005sv0000122Dsd00004011* + ID_PRODUCT_FROM_DATABASE=MDP3858SP-SA + +pci:v0000127Ad00001005sv0000122Dsd00004013* + ID_PRODUCT_FROM_DATABASE=MDP3858V-A/V-NZ + +pci:v0000127Ad00001005sv0000122Dsd00004015* + ID_PRODUCT_FROM_DATABASE=MDP3858SP-W + +pci:v0000127Ad00001005sv0000122Dsd00004016* + ID_PRODUCT_FROM_DATABASE=MDP3858V-W + +pci:v0000127Ad00001005sv0000122Dsd00004019* + ID_PRODUCT_FROM_DATABASE=MDP3858V-SA + +pci:v0000127Ad00001005sv000013DFsd00001005* + ID_PRODUCT_FROM_DATABASE=PCI56RVP Modem + +pci:v0000127Ad00001005sv000013E0sd00000187* + ID_PRODUCT_FROM_DATABASE=IBM + +pci:v0000127Ad00001005sv000013E0sd000001A7* + ID_PRODUCT_FROM_DATABASE=IBM + +pci:v0000127Ad00001005sv000013E0sd000001B7* + ID_PRODUCT_FROM_DATABASE=IBM DF-1156IV+/R3 Spain V.90 Modem + +pci:v0000127Ad00001005sv000013E0sd000001D7* + ID_PRODUCT_FROM_DATABASE=IBM DF-1156IV+/R3 WW V.90 Modem + +pci:v0000127Ad00001005sv00001436sd00001005* + ID_PRODUCT_FROM_DATABASE=IBM + +pci:v0000127Ad00001005sv00001436sd00001105* + ID_PRODUCT_FROM_DATABASE=IBM + +pci:v0000127Ad00001005sv00001437sd00001105* + ID_PRODUCT_FROM_DATABASE=IBM 5614PS3G V.90 Modem + +pci:v0000127Ad00001022* + ID_PRODUCT_FROM_DATABASE=HCF 56k Modem + +pci:v0000127Ad00001022sv00001436sd00001303* + ID_PRODUCT_FROM_DATABASE=M3-5614PM3G V.90 Modem + +pci:v0000127Ad00001023* + ID_PRODUCT_FROM_DATABASE=HCF 56k Data/Fax Modem + +pci:v0000127Ad00001023sv0000122Dsd00004020* + ID_PRODUCT_FROM_DATABASE=Packard Bell MDP3858-WE + +pci:v0000127Ad00001023sv0000122Dsd00004023* + ID_PRODUCT_FROM_DATABASE=MDP3858-UE + +pci:v0000127Ad00001023sv000013E0sd00000247* + ID_PRODUCT_FROM_DATABASE=IBM F-1156IV+/R6 Spain V.90 Modem + +pci:v0000127Ad00001023sv000013E0sd00000297* + ID_PRODUCT_FROM_DATABASE=IBM + +pci:v0000127Ad00001023sv000013E0sd000002C7* + ID_PRODUCT_FROM_DATABASE=IBM F-1156IV+/R6 WW V.90 Modem + +pci:v0000127Ad00001023sv00001436sd00001203* + ID_PRODUCT_FROM_DATABASE=IBM + +pci:v0000127Ad00001023sv00001436sd00001303* + ID_PRODUCT_FROM_DATABASE=IBM + +pci:v0000127Ad00001024* + ID_PRODUCT_FROM_DATABASE=HCF 56k Data/Fax/Voice Modem + +pci:v0000127Ad00001025* + ID_PRODUCT_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem + +pci:v0000127Ad00001025sv000010CFsd0000106A* + ID_PRODUCT_FROM_DATABASE=Fujitsu 235-DFSV + +pci:v0000127Ad00001025sv0000122Dsd00004021* + ID_PRODUCT_FROM_DATABASE=Packard Bell MDP3858V-WE + +pci:v0000127Ad00001025sv0000122Dsd00004022* + ID_PRODUCT_FROM_DATABASE=MDP3858SP-WE + +pci:v0000127Ad00001025sv0000122Dsd00004024* + ID_PRODUCT_FROM_DATABASE=MDP3858V-UE + +pci:v0000127Ad00001025sv0000122Dsd00004025* + ID_PRODUCT_FROM_DATABASE=MDP3858SP-UE + +pci:v0000127Ad00001026* + ID_PRODUCT_FROM_DATABASE=HCF 56k PCI Speakerphone Modem + +pci:v0000127Ad00001032* + ID_PRODUCT_FROM_DATABASE=HCF 56k Modem + +pci:v0000127Ad00001033* + ID_PRODUCT_FROM_DATABASE=HCF 56k Modem + +pci:v0000127Ad00001034* + ID_PRODUCT_FROM_DATABASE=HCF 56k Modem + +pci:v0000127Ad00001035* + ID_PRODUCT_FROM_DATABASE=HCF 56k PCI Speakerphone Modem + +pci:v0000127Ad00001036* + ID_PRODUCT_FROM_DATABASE=HCF 56k Modem + +pci:v0000127Ad00001085* + ID_PRODUCT_FROM_DATABASE=HCF 56k Volcano PCI Modem + +pci:v0000127Ad00002004* + ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice/Spkp (w/Handset) Modem + +pci:v0000127Ad00002005* + ID_PRODUCT_FROM_DATABASE=HCF 56k Data/Fax Modem + +pci:v0000127Ad00002005sv0000104Dsd00008044* + ID_PRODUCT_FROM_DATABASE=229-DFSV + +pci:v0000127Ad00002005sv0000104Dsd00008045* + ID_PRODUCT_FROM_DATABASE=229-DFSV + +pci:v0000127Ad00002005sv0000104Dsd00008055* + ID_PRODUCT_FROM_DATABASE=PBE/Aztech 235W-DFSV + +pci:v0000127Ad00002005sv0000104Dsd00008056* + ID_PRODUCT_FROM_DATABASE=235-DFSV + +pci:v0000127Ad00002005sv0000104Dsd0000805A* + ID_PRODUCT_FROM_DATABASE=Modem + +pci:v0000127Ad00002005sv0000104Dsd0000805F* + ID_PRODUCT_FROM_DATABASE=Modem + +pci:v0000127Ad00002005sv0000104Dsd00008074* + ID_PRODUCT_FROM_DATABASE=Modem + +pci:v0000127Ad00002013* + ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax Modem + +pci:v0000127Ad00002013sv00001179sd00000001* + ID_PRODUCT_FROM_DATABASE=Modem + +pci:v0000127Ad00002013sv00001179sd0000FF00* + ID_PRODUCT_FROM_DATABASE=Modem + +pci:v0000127Ad00002014* + ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice Modem + +pci:v0000127Ad00002014sv000010CFsd00001057* + ID_PRODUCT_FROM_DATABASE=Fujitsu Citicorp III + +pci:v0000127Ad00002014sv0000122Dsd00004050* + ID_PRODUCT_FROM_DATABASE=MSP3880-U + +pci:v0000127Ad00002014sv0000122Dsd00004055* + ID_PRODUCT_FROM_DATABASE=MSP3880-W + +pci:v0000127Ad00002015* + ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice/Spkp (w/Handset) Modem + +pci:v0000127Ad00002015sv000010CFsd00001063* + ID_PRODUCT_FROM_DATABASE=Fujitsu + +pci:v0000127Ad00002015sv000010CFsd00001064* + ID_PRODUCT_FROM_DATABASE=Fujitsu + +pci:v0000127Ad00002015sv00001468sd00002015* + ID_PRODUCT_FROM_DATABASE=Fujitsu + +pci:v0000127Ad00002016* + ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice/Spkp Modem + +pci:v0000127Ad00002016sv0000122Dsd00004051* + ID_PRODUCT_FROM_DATABASE=MSP3880V-W + +pci:v0000127Ad00002016sv0000122Dsd00004052* + ID_PRODUCT_FROM_DATABASE=MSP3880SP-W + +pci:v0000127Ad00002016sv0000122Dsd00004054* + ID_PRODUCT_FROM_DATABASE=MSP3880V-U + +pci:v0000127Ad00002016sv0000122Dsd00004056* + ID_PRODUCT_FROM_DATABASE=MSP3880SP-U + +pci:v0000127Ad00002016sv0000122Dsd00004057* + ID_PRODUCT_FROM_DATABASE=MSP3880SP-A + +pci:v0000127Ad00004311* + ID_PRODUCT_FROM_DATABASE=Riptide HSF 56k PCI Modem + +pci:v0000127Ad00004311sv0000127Asd00004311* + ID_PRODUCT_FROM_DATABASE=Ring Modular? Riptide HSF RT HP Dom + +pci:v0000127Ad00004311sv000013E0sd00000210* + ID_PRODUCT_FROM_DATABASE=HP-GVC + +pci:v0000127Ad00004320* + ID_PRODUCT_FROM_DATABASE=Riptide PCI Audio Controller + +pci:v0000127Ad00004320sv00001235sd00004320* + ID_PRODUCT_FROM_DATABASE=Riptide PCI Audio Controller + +pci:v0000127Ad00004321* + ID_PRODUCT_FROM_DATABASE=Riptide HCF 56k PCI Modem + +pci:v0000127Ad00004321sv00001235sd00004321* + ID_PRODUCT_FROM_DATABASE=Hewlett Packard DF + +pci:v0000127Ad00004321sv00001235sd00004324* + ID_PRODUCT_FROM_DATABASE=Hewlett Packard DF + +pci:v0000127Ad00004321sv000013E0sd00000210* + ID_PRODUCT_FROM_DATABASE=Hewlett Packard DF + +pci:v0000127Ad00004321sv0000144Dsd00002321* + ID_PRODUCT_FROM_DATABASE=Riptide + +pci:v0000127Ad00004322* + ID_PRODUCT_FROM_DATABASE=Riptide PCI Game Controller + +pci:v0000127Ad00004322sv00001235sd00004322* + ID_PRODUCT_FROM_DATABASE=Riptide PCI Game Controller + +pci:v0000127Ad00008234* + ID_PRODUCT_FROM_DATABASE=RapidFire 616X ATM155 Adapter + +pci:v0000127Ad00008234sv0000108Dsd00000022* + ID_PRODUCT_FROM_DATABASE=RapidFire 616X ATM155 Adapter + +pci:v0000127Ad00008234sv0000108Dsd00000027* + ID_PRODUCT_FROM_DATABASE=RapidFire 616X ATM155 Adapter + +pci:v0000127B* + ID_VENDOR_FROM_DATABASE=Pixera Corporation + +pci:v0000127C* + ID_VENDOR_FROM_DATABASE=Crosspoint Solutions, Inc. + +pci:v0000127D* + ID_VENDOR_FROM_DATABASE=Vela Research + +pci:v0000127E* + ID_VENDOR_FROM_DATABASE=Winnov, L.P. + +pci:v0000127Ed00000010* + ID_PRODUCT_FROM_DATABASE=Videum 1000 Plus + +pci:v0000127F* + ID_VENDOR_FROM_DATABASE=Fujifilm + +pci:v00001280* + ID_VENDOR_FROM_DATABASE=Photoscript Group Ltd. + +pci:v00001281* + ID_VENDOR_FROM_DATABASE=Yokogawa Electric Corporation + +pci:v00001282* + ID_VENDOR_FROM_DATABASE=Davicom Semiconductor, Inc. + +pci:v00001282d00006585* + ID_PRODUCT_FROM_DATABASE=DM562P V90 Modem + +pci:v00001282d00009009* + ID_PRODUCT_FROM_DATABASE=Ethernet 100/10 MBit + +pci:v00001282d00009100* + ID_PRODUCT_FROM_DATABASE=21x4x DEC-Tulip compatible 10/100 Ethernet + +pci:v00001282d00009102* + ID_PRODUCT_FROM_DATABASE=21x4x DEC-Tulip compatible 10/100 Ethernet + +pci:v00001282d00009102sv00000291sd00008212* + ID_PRODUCT_FROM_DATABASE=DM9102A (DM9102AE, SM9102AF) Ethernet 100/10 MBit + +pci:v00001282d00009132* + ID_PRODUCT_FROM_DATABASE=Ethernet 100/10 MBit + +pci:v00001283* + ID_VENDOR_FROM_DATABASE=Integrated Technology Express, Inc. + +pci:v00001283d0000673A* + ID_PRODUCT_FROM_DATABASE=IT8330G + +pci:v00001283d00008152* + ID_PRODUCT_FROM_DATABASE=IT8152F/G Advanced RISC-to-PCI Companion Chip + +pci:v00001283d00008211* + ID_PRODUCT_FROM_DATABASE=ITE 8211F Single Channel UDMA 133 + +pci:v00001283d00008211sv00001043sd00008138* + ID_PRODUCT_FROM_DATABASE=P5GD1-VW Mainboard + +pci:v00001283d00008212* + ID_PRODUCT_FROM_DATABASE=IT8212 Dual channel ATA RAID controller + +pci:v00001283d00008212sv00001283sd00000001* + ID_PRODUCT_FROM_DATABASE=IT/ITE8212 Dual channel ATA RAID controller + +pci:v00001283d00008213* + ID_PRODUCT_FROM_DATABASE=IT8213 IDE Controller + +pci:v00001283d00008213sv00001458sd0000B000* + ID_PRODUCT_FROM_DATABASE=GA-EG45M-DS2H Mainboard + +pci:v00001283d00008330* + ID_PRODUCT_FROM_DATABASE=IT8330G + +pci:v00001283d00008872* + ID_PRODUCT_FROM_DATABASE=IT8874F PCI Dual Serial Port Controller + +pci:v00001283d00008888* + ID_PRODUCT_FROM_DATABASE=IT8888F/G PCI to ISA Bridge with SMB [Golden Gate] + +pci:v00001283d00008889* + ID_PRODUCT_FROM_DATABASE=IT8889F PCI to ISA Bridge + +pci:v00001283d0000E886* + ID_PRODUCT_FROM_DATABASE=IT8330G + +pci:v00001284* + ID_VENDOR_FROM_DATABASE=Sahara Networks, Inc. + +pci:v00001285* + ID_VENDOR_FROM_DATABASE=Platform Technologies, Inc. + +pci:v00001285d00000100* + ID_PRODUCT_FROM_DATABASE=AGOGO sound chip (aka ESS Maestro 1) + +pci:v00001286* + ID_VENDOR_FROM_DATABASE=Mazet GmbH + +pci:v00001287* + ID_VENDOR_FROM_DATABASE=M-Pact, Inc. + +pci:v00001287d0000001E* + ID_PRODUCT_FROM_DATABASE=LS220D DVD Decoder + +pci:v00001287d0000001F* + ID_PRODUCT_FROM_DATABASE=LS220C DVD Decoder + +pci:v00001288* + ID_VENDOR_FROM_DATABASE=Timestep Corporation + +pci:v00001289* + ID_VENDOR_FROM_DATABASE=AVC Technology, Inc. + +pci:v0000128A* + ID_VENDOR_FROM_DATABASE=Asante Technologies, Inc. + +pci:v0000128B* + ID_VENDOR_FROM_DATABASE=Transwitch Corporation + +pci:v0000128C* + ID_VENDOR_FROM_DATABASE=Retix Corporation + +pci:v0000128D* + ID_VENDOR_FROM_DATABASE=G2 Networks, Inc. + +pci:v0000128Dd00000021* + ID_PRODUCT_FROM_DATABASE=ATM155 Adapter + +pci:v0000128E* + ID_VENDOR_FROM_DATABASE=Hoontech Corporation/Samho Multi Tech Ltd. + +pci:v0000128Ed00000008* + ID_PRODUCT_FROM_DATABASE=ST128 WSS/SB + +pci:v0000128Ed00000009* + ID_PRODUCT_FROM_DATABASE=ST128 SAM9407 + +pci:v0000128Ed0000000A* + ID_PRODUCT_FROM_DATABASE=ST128 Game Port + +pci:v0000128Ed0000000B* + ID_PRODUCT_FROM_DATABASE=ST128 MPU Port + +pci:v0000128Ed0000000C* + ID_PRODUCT_FROM_DATABASE=ST128 Ctrl Port + +pci:v0000128F* + ID_VENDOR_FROM_DATABASE=Tateno Dennou, Inc. + +pci:v00001290* + ID_VENDOR_FROM_DATABASE=Sord Computer Corporation + +pci:v00001291* + ID_VENDOR_FROM_DATABASE=NCS Computer Italia + +pci:v00001292* + ID_VENDOR_FROM_DATABASE=Tritech Microelectronics Inc + +pci:v00001292d0000FC02* + ID_PRODUCT_FROM_DATABASE=Pyramid3D TR25202 + +pci:v00001293* + ID_VENDOR_FROM_DATABASE=Media Reality Technology + +pci:v00001294* + ID_VENDOR_FROM_DATABASE=Rhetorex, Inc. + +pci:v00001295* + ID_VENDOR_FROM_DATABASE=Imagenation Corporation + +pci:v00001295d00000800* + ID_PRODUCT_FROM_DATABASE=PXR800 + +pci:v00001295d00001000* + ID_PRODUCT_FROM_DATABASE=PXD1000 + +pci:v00001296* + ID_VENDOR_FROM_DATABASE=Kofax Image Products + +pci:v00001297* + ID_VENDOR_FROM_DATABASE=Holco Enterprise Co, Ltd/Shuttle Computer + +pci:v00001298* + ID_VENDOR_FROM_DATABASE=Spellcaster Telecommunications Inc. + +pci:v00001299* + ID_VENDOR_FROM_DATABASE=Knowledge Technology Lab. + +pci:v0000129A* + ID_VENDOR_FROM_DATABASE=VMetro, inc. + +pci:v0000129Ad00000615* + ID_PRODUCT_FROM_DATABASE=PBT-615 PCI-X Bus Analyzer + +pci:v0000129Ad00001100* + ID_PRODUCT_FROM_DATABASE=PMC-FPGA05 + +pci:v0000129Ad00001106* + ID_PRODUCT_FROM_DATABASE=XMC-FPGA05F, PCI interface + +pci:v0000129Ad00001107* + ID_PRODUCT_FROM_DATABASE=XMC-FPGA05F, PCIe interface + +pci:v0000129Ad00001108* + ID_PRODUCT_FROM_DATABASE=XMC-FPGA05D, PCI interface + +pci:v0000129Ad00001109* + ID_PRODUCT_FROM_DATABASE=XMC-FPGA05D, PCIe interface + +pci:v0000129B* + ID_VENDOR_FROM_DATABASE=Image Access + +pci:v0000129C* + ID_VENDOR_FROM_DATABASE=Jaycor + +pci:v0000129D* + ID_VENDOR_FROM_DATABASE=Compcore Multimedia, Inc. + +pci:v0000129E* + ID_VENDOR_FROM_DATABASE=Victor Company of Japan, Ltd. + +pci:v0000129F* + ID_VENDOR_FROM_DATABASE=OEC Medical Systems, Inc. + +pci:v000012A0* + ID_VENDOR_FROM_DATABASE=Allen-Bradley Company + +pci:v000012A1* + ID_VENDOR_FROM_DATABASE=Simpact Associates, Inc. + +pci:v000012A2* + ID_VENDOR_FROM_DATABASE=Newgen Systems Corporation + +pci:v000012A3* + ID_VENDOR_FROM_DATABASE=Lucent Technologies + +pci:v000012A3d00008105* + ID_PRODUCT_FROM_DATABASE=T8105 H100 Digital Switch + +pci:v000012A4* + ID_VENDOR_FROM_DATABASE=NTT Electronics Technology Company + +pci:v000012A5* + ID_VENDOR_FROM_DATABASE=Vision Dynamics Ltd. + +pci:v000012A6* + ID_VENDOR_FROM_DATABASE=Scalable Networks, Inc. + +pci:v000012A7* + ID_VENDOR_FROM_DATABASE=AMO GmbH + +pci:v000012A8* + ID_VENDOR_FROM_DATABASE=News Datacom + +pci:v000012A9* + ID_VENDOR_FROM_DATABASE=Xiotech Corporation + +pci:v000012AA* + ID_VENDOR_FROM_DATABASE=SDL Communications, Inc. + +pci:v000012AB* + ID_VENDOR_FROM_DATABASE=Yuan Yuan Enterprise Co., Ltd. + +pci:v000012ABd00000000* + ID_PRODUCT_FROM_DATABASE=MPG160/Kuroutoshikou ITVC15-STVLP + +pci:v000012ABd00000002* + ID_PRODUCT_FROM_DATABASE=AU8830 [Vortex2] Based Sound Card With A3D Support + +pci:v000012ABd00000003* + ID_PRODUCT_FROM_DATABASE=T507 (DVB-T) TV tuner/capture device + +pci:v000012ABd00002300* + ID_PRODUCT_FROM_DATABASE=Club-3D Zap TV2100 + +pci:v000012ABd00003000* + ID_PRODUCT_FROM_DATABASE=MPG-200C PCI DVD Decoder Card + +pci:v000012ABd00004789* + ID_PRODUCT_FROM_DATABASE=MPC788 MiniPCI Hybrid TV Tuner + +pci:v000012ABd0000FFF3* + ID_PRODUCT_FROM_DATABASE=MPG600/Kuroutoshikou ITVC16-STVLP + +pci:v000012ABd0000FFFF* + ID_PRODUCT_FROM_DATABASE=MPG600/Kuroutoshikou ITVC16-STVLP + +pci:v000012AC* + ID_VENDOR_FROM_DATABASE=Measurex Corporation + +pci:v000012AD* + ID_VENDOR_FROM_DATABASE=Multidata GmbH + +pci:v000012AE* + ID_VENDOR_FROM_DATABASE=Alteon Networks Inc. + +pci:v000012AEd00000001* + ID_PRODUCT_FROM_DATABASE=AceNIC Gigabit Ethernet + +pci:v000012AEd00000001sv00001014sd00000104* + ID_PRODUCT_FROM_DATABASE=Gigabit Ethernet-SX PCI Adapter + +pci:v000012AEd00000001sv000012AEsd00000001* + ID_PRODUCT_FROM_DATABASE=Gigabit Ethernet-SX (Universal) + +pci:v000012AEd00000001sv00001410sd00000104* + ID_PRODUCT_FROM_DATABASE=Gigabit Ethernet-SX PCI Adapter + +pci:v000012AEd00000002* + ID_PRODUCT_FROM_DATABASE=AceNIC Gigabit Ethernet (Copper) + +pci:v000012AEd00000002sv000010A9sd00008002* + ID_PRODUCT_FROM_DATABASE=Acenic Gigabit Ethernet + +pci:v000012AEd00000002sv000012AEsd00000002* + ID_PRODUCT_FROM_DATABASE=Gigabit Ethernet-T (3C986-T) + +pci:v000012AEd000000FA* + ID_PRODUCT_FROM_DATABASE=Farallon PN9100-T Gigabit Ethernet + +pci:v000012AF* + ID_VENDOR_FROM_DATABASE=TDK USA Corp + +pci:v000012B0* + ID_VENDOR_FROM_DATABASE=Jorge Scientific Corp + +pci:v000012B1* + ID_VENDOR_FROM_DATABASE=GammaLink + +pci:v000012B2* + ID_VENDOR_FROM_DATABASE=General Signal Networks + +pci:v000012B3* + ID_VENDOR_FROM_DATABASE=Inter-Face Co Ltd + +pci:v000012B4* + ID_VENDOR_FROM_DATABASE=FutureTel Inc + +pci:v000012B5* + ID_VENDOR_FROM_DATABASE=Granite Systems Inc. + +pci:v000012B6* + ID_VENDOR_FROM_DATABASE=Natural Microsystems + +pci:v000012B7* + ID_VENDOR_FROM_DATABASE=Cognex Modular Vision Systems Div. - Acumen Inc. + +pci:v000012B8* + ID_VENDOR_FROM_DATABASE=Korg + +pci:v000012B9* + ID_VENDOR_FROM_DATABASE=3Com Corp, Modem Division + +pci:v000012B9d00001006* + ID_PRODUCT_FROM_DATABASE=WinModem + +pci:v000012B9d00001006sv000012B9sd0000005C* + ID_PRODUCT_FROM_DATABASE=USR 56k Internal Voice WinModem (Model 3472) + +pci:v000012B9d00001006sv000012B9sd0000005E* + ID_PRODUCT_FROM_DATABASE=USR 56k Internal WinModem (Models 662975) + +pci:v000012B9d00001006sv000012B9sd00000062* + ID_PRODUCT_FROM_DATABASE=USR 56k Internal Voice WinModem (Model 662978) + +pci:v000012B9d00001006sv000012B9sd00000068* + ID_PRODUCT_FROM_DATABASE=USR 56k Internal Voice WinModem (Model 5690) + +pci:v000012B9d00001006sv000012B9sd0000007A* + ID_PRODUCT_FROM_DATABASE=USR 56k Internal Voice WinModem (Model 662974) + +pci:v000012B9d00001006sv000012B9sd0000007F* + ID_PRODUCT_FROM_DATABASE=USR 56k Internal WinModem (Models 5698, 5699) + +pci:v000012B9d00001006sv000012B9sd00000080* + ID_PRODUCT_FROM_DATABASE=USR 56k Internal WinModem (Models 2975, 3528) + +pci:v000012B9d00001006sv000012B9sd00000081* + ID_PRODUCT_FROM_DATABASE=USR 56k Internal Voice WinModem (Models 2974, 3529) + +pci:v000012B9d00001006sv000012B9sd00000091* + ID_PRODUCT_FROM_DATABASE=USR 56k Internal Voice WinModem (Model 2978) + +pci:v000012B9d00001007* + ID_PRODUCT_FROM_DATABASE=USR 56k Internal WinModem + +pci:v000012B9d00001007sv000012B9sd000000A3* + ID_PRODUCT_FROM_DATABASE=USR 56k Internal WinModem (Model 3595) + +pci:v000012B9d00001007sv000012B9sd000000C4* + ID_PRODUCT_FROM_DATABASE=U.S. Robotics V.92 Voice Faxmodem (2884A/B/C) + +pci:v000012B9d00001008* + ID_PRODUCT_FROM_DATABASE=56K FaxModem Model 5610 + +pci:v000012B9d00001008sv000012B9sd000000A2* + ID_PRODUCT_FROM_DATABASE=USR 56k Internal FAX Modem (Model 2977) + +pci:v000012B9d00001008sv000012B9sd000000AA* + ID_PRODUCT_FROM_DATABASE=USR 56k Internal Voice Modem (Model 2976) + +pci:v000012B9d00001008sv000012B9sd000000AB* + ID_PRODUCT_FROM_DATABASE=USR 56k Internal Voice Modem (Model 5609) + +pci:v000012B9d00001008sv000012B9sd000000AC* + ID_PRODUCT_FROM_DATABASE=USR 56k Internal Voice Modem (Model 3298) + +pci:v000012B9d00001008sv000012B9sd000000AD* + ID_PRODUCT_FROM_DATABASE=USR 56k Internal FAX Modem (Model 5610) + +pci:v000012B9d00001008sv000012B9sd000000D3* + ID_PRODUCT_FROM_DATABASE=USR 56K Internal V92 FAX Modem (Model 5610) + +pci:v000012B9d00001008sv000012B9sd0000BABA* + ID_PRODUCT_FROM_DATABASE=USR 56K Internal Voice Modem 3CP3298-DEL (Model 5601) [Hawk] + +pci:v000012BA* + ID_VENDOR_FROM_DATABASE=BittWare, Inc. + +pci:v000012BB* + ID_VENDOR_FROM_DATABASE=Nippon Unisoft Corporation + +pci:v000012BC* + ID_VENDOR_FROM_DATABASE=Array Microsystems + +pci:v000012BD* + ID_VENDOR_FROM_DATABASE=Computerm Corp. + +pci:v000012BE* + ID_VENDOR_FROM_DATABASE=Anchor Chips Inc. + +pci:v000012BEd00003041* + ID_PRODUCT_FROM_DATABASE=AN3041Q CO-MEM + +pci:v000012BEd00003042* + ID_PRODUCT_FROM_DATABASE=AN3042Q CO-MEM Lite + +pci:v000012BEd00003042sv000012BEsd00003042* + ID_PRODUCT_FROM_DATABASE=Anchor Chips Lite Evaluation Board + +pci:v000012BF* + ID_VENDOR_FROM_DATABASE=Fujifilm Microdevices + +pci:v000012C0* + ID_VENDOR_FROM_DATABASE=Infimed + +pci:v000012C1* + ID_VENDOR_FROM_DATABASE=GMM Research Corp + +pci:v000012C2* + ID_VENDOR_FROM_DATABASE=Mentec Limited + +pci:v000012C3* + ID_VENDOR_FROM_DATABASE=Holtek Microelectronics Inc + +pci:v000012C3d00000058* + ID_PRODUCT_FROM_DATABASE=PCI NE2K Ethernet + +pci:v000012C3d00005598* + ID_PRODUCT_FROM_DATABASE=PCI NE2K Ethernet + +pci:v000012C4* + ID_VENDOR_FROM_DATABASE=Connect Tech Inc + +pci:v000012C4d00000001* + ID_PRODUCT_FROM_DATABASE=Blue HEAT/PCI 8 (RS232/CL/RJ11) + +pci:v000012C4d00000002* + ID_PRODUCT_FROM_DATABASE=Blue HEAT/PCI 4 (RS232) + +pci:v000012C4d00000003* + ID_PRODUCT_FROM_DATABASE=Blue HEAT/PCI 2 (RS232) + +pci:v000012C4d00000004* + ID_PRODUCT_FROM_DATABASE=Blue HEAT/PCI 8 (UNIV, RS485) + +pci:v000012C4d00000005* + ID_PRODUCT_FROM_DATABASE=Blue HEAT/PCI 4+4/6+2 (UNIV, RS232/485) + +pci:v000012C4d00000006* + ID_PRODUCT_FROM_DATABASE=Blue HEAT/PCI 4 (OPTO, RS485) + +pci:v000012C4d00000007* + ID_PRODUCT_FROM_DATABASE=Blue HEAT/PCI 2+2 (RS232/485) + +pci:v000012C4d00000008* + ID_PRODUCT_FROM_DATABASE=Blue HEAT/PCI 2 (OPTO, Tx, RS485) + +pci:v000012C4d00000009* + ID_PRODUCT_FROM_DATABASE=Blue HEAT/PCI 2+6 (RS232/485) + +pci:v000012C4d0000000A* + ID_PRODUCT_FROM_DATABASE=Blue HEAT/PCI 8 (Tx, RS485) + +pci:v000012C4d0000000B* + ID_PRODUCT_FROM_DATABASE=Blue HEAT/PCI 4 (Tx, RS485) + +pci:v000012C4d0000000C* + ID_PRODUCT_FROM_DATABASE=Blue HEAT/PCI 2 (20 MHz, RS485) + +pci:v000012C4d0000000D* + ID_PRODUCT_FROM_DATABASE=Blue HEAT/PCI 2 PTM + +pci:v000012C4d00000100* + ID_PRODUCT_FROM_DATABASE=NT960/PCI + +pci:v000012C4d00000201* + ID_PRODUCT_FROM_DATABASE=cPCI Titan - 2 Port + +pci:v000012C4d00000202* + ID_PRODUCT_FROM_DATABASE=cPCI Titan - 4 Port + +pci:v000012C4d00000300* + ID_PRODUCT_FROM_DATABASE=CTI PCI UART 2 (RS232) + +pci:v000012C4d00000301* + ID_PRODUCT_FROM_DATABASE=CTI PCI UART 4 (RS232) + +pci:v000012C4d00000302* + ID_PRODUCT_FROM_DATABASE=CTI PCI UART 8 (RS232) + +pci:v000012C4d00000310* + ID_PRODUCT_FROM_DATABASE=CTI PCI UART 1+1 (RS232/485) + +pci:v000012C4d00000311* + ID_PRODUCT_FROM_DATABASE=CTI PCI UART 2+2 (RS232/485) + +pci:v000012C4d00000312* + ID_PRODUCT_FROM_DATABASE=CTI PCI UART 4+4 (RS232/485) + +pci:v000012C4d00000320* + ID_PRODUCT_FROM_DATABASE=CTI PCI UART 2 + +pci:v000012C4d00000321* + ID_PRODUCT_FROM_DATABASE=CTI PCI UART 4 + +pci:v000012C4d00000322* + ID_PRODUCT_FROM_DATABASE=CTI PCI UART 8 + +pci:v000012C4d00000330* + ID_PRODUCT_FROM_DATABASE=CTI PCI UART 2 (RS485) + +pci:v000012C4d00000331* + ID_PRODUCT_FROM_DATABASE=CTI PCI UART 4 (RS485) + +pci:v000012C4d00000332* + ID_PRODUCT_FROM_DATABASE=CTI PCI UART 8 (RS485) + +pci:v000012C5* + ID_VENDOR_FROM_DATABASE=Picture Elements Incorporated + +pci:v000012C5d0000007E* + ID_PRODUCT_FROM_DATABASE=Imaging/Scanning Subsystem Engine + +pci:v000012C5d0000007F* + ID_PRODUCT_FROM_DATABASE=Imaging/Scanning Subsystem Engine + +pci:v000012C5d00000081* + ID_PRODUCT_FROM_DATABASE=PCIVST [Grayscale Thresholding Engine] + +pci:v000012C5d00000085* + ID_PRODUCT_FROM_DATABASE=Video Simulator/Sender + +pci:v000012C5d00000086* + ID_PRODUCT_FROM_DATABASE=THR2 Multi-scale Thresholder + +pci:v000012C6* + ID_VENDOR_FROM_DATABASE=Mitani Corporation + +pci:v000012C7* + ID_VENDOR_FROM_DATABASE=Dialogic Corp + +pci:v000012C7d00000546* + ID_PRODUCT_FROM_DATABASE=Springware D/120JCT-LS + +pci:v000012C7d00000647* + ID_PRODUCT_FROM_DATABASE=Springware D/240JCT-T1 + +pci:v000012C7d00000676* + ID_PRODUCT_FROM_DATABASE=Springware D/41JCT-LS + +pci:v000012C7d00000685* + ID_PRODUCT_FROM_DATABASE=Springware D/480JCT-2T1 + +pci:v000012C8* + ID_VENDOR_FROM_DATABASE=G Force Co, Ltd + +pci:v000012C9* + ID_VENDOR_FROM_DATABASE=Gigi Operations + +pci:v000012CA* + ID_VENDOR_FROM_DATABASE=Integrated Computing Engines + +pci:v000012CB* + ID_VENDOR_FROM_DATABASE=Antex Electronics Corporation + +pci:v000012CBd00000027* + ID_PRODUCT_FROM_DATABASE=SC4 (StudioCard) + +pci:v000012CBd0000002E* + ID_PRODUCT_FROM_DATABASE=StudioCard 2000 + +pci:v000012CC* + ID_VENDOR_FROM_DATABASE=Pluto Technologies International + +pci:v000012CD* + ID_VENDOR_FROM_DATABASE=Aims Lab + +pci:v000012CE* + ID_VENDOR_FROM_DATABASE=Netspeed Inc. + +pci:v000012CF* + ID_VENDOR_FROM_DATABASE=Prophet Systems, Inc. + +pci:v000012D0* + ID_VENDOR_FROM_DATABASE=GDE Systems, Inc. + +pci:v000012D1* + ID_VENDOR_FROM_DATABASE=PSITech + +pci:v000012D2* + ID_VENDOR_FROM_DATABASE=NVidia / SGS Thomson (Joint Venture) + +pci:v000012D2d00000008* + ID_PRODUCT_FROM_DATABASE=NV1 + +pci:v000012D2d00000009* + ID_PRODUCT_FROM_DATABASE=DAC64 + +pci:v000012D2d00000018* + ID_PRODUCT_FROM_DATABASE=Riva128 + +pci:v000012D2d00000018sv00001048sd00000C10* + ID_PRODUCT_FROM_DATABASE=VICTORY Erazor + +pci:v000012D2d00000018sv0000107Bsd00008030* + ID_PRODUCT_FROM_DATABASE=STB Velocity 128 + +pci:v000012D2d00000018sv00001092sd00000350* + ID_PRODUCT_FROM_DATABASE=Viper V330 + +pci:v000012D2d00000018sv00001092sd00001092* + ID_PRODUCT_FROM_DATABASE=Viper V330 + +pci:v000012D2d00000018sv000010B4sd00001B1B* + ID_PRODUCT_FROM_DATABASE=STB Velocity 128 + +pci:v000012D2d00000018sv000010B4sd00001B1D* + ID_PRODUCT_FROM_DATABASE=STB Velocity 128 + +pci:v000012D2d00000018sv000010B4sd00001B1E* + ID_PRODUCT_FROM_DATABASE=STB Velocity 128, PAL TV-Out + +pci:v000012D2d00000018sv000010B4sd00001B20* + ID_PRODUCT_FROM_DATABASE=STB Velocity 128 Sapphire + +pci:v000012D2d00000018sv000010B4sd00001B21* + ID_PRODUCT_FROM_DATABASE=STB Velocity 128 + +pci:v000012D2d00000018sv000010B4sd00001B22* + ID_PRODUCT_FROM_DATABASE=STB Velocity 128 AGP, NTSC TV-Out + +pci:v000012D2d00000018sv000010B4sd00001B23* + ID_PRODUCT_FROM_DATABASE=STB Velocity 128 AGP, PAL TV-Out + +pci:v000012D2d00000018sv000010B4sd00001B27* + ID_PRODUCT_FROM_DATABASE=STB Velocity 128 DVD + +pci:v000012D2d00000018sv000010B4sd00001B88* + ID_PRODUCT_FROM_DATABASE=MVP Pro 128 + +pci:v000012D2d00000018sv000010B4sd0000222A* + ID_PRODUCT_FROM_DATABASE=STB Velocity 128 AGP + +pci:v000012D2d00000018sv000010B4sd00002230* + ID_PRODUCT_FROM_DATABASE=STB Velocity 128 + +pci:v000012D2d00000018sv000010B4sd00002232* + ID_PRODUCT_FROM_DATABASE=STB Velocity 128 + +pci:v000012D2d00000018sv000010B4sd00002235* + ID_PRODUCT_FROM_DATABASE=STB Velocity 128 AGP + +pci:v000012D2d00000018sv00002A15sd000054A3* + ID_PRODUCT_FROM_DATABASE=3DVision-SAGP / 3DexPlorer 3000 + +pci:v000012D2d00000019* + ID_PRODUCT_FROM_DATABASE=Riva128ZX + +pci:v000012D2d00000020* + ID_PRODUCT_FROM_DATABASE=TNT + +pci:v000012D2d00000028* + ID_PRODUCT_FROM_DATABASE=TNT2 + +pci:v000012D2d00000029* + ID_PRODUCT_FROM_DATABASE=UTNT2 + +pci:v000012D2d0000002C* + ID_PRODUCT_FROM_DATABASE=VTNT2 + +pci:v000012D2d000000A0* + ID_PRODUCT_FROM_DATABASE=ITNT2 + +pci:v000012D3* + ID_VENDOR_FROM_DATABASE=Vingmed Sound A/S + +pci:v000012D4* + ID_VENDOR_FROM_DATABASE=Ulticom (Formerly DGM&S) + +pci:v000012D4d00000200* + ID_PRODUCT_FROM_DATABASE=T1 Card + +pci:v000012D5* + ID_VENDOR_FROM_DATABASE=Equator Technologies Inc + +pci:v000012D5d00000003* + ID_PRODUCT_FROM_DATABASE=BSP16 + +pci:v000012D5d00001000* + ID_PRODUCT_FROM_DATABASE=BSP15 + +pci:v000012D6* + ID_VENDOR_FROM_DATABASE=Analogic Corp + +pci:v000012D7* + ID_VENDOR_FROM_DATABASE=Biotronic SRL + +pci:v000012D8* + ID_VENDOR_FROM_DATABASE=Pericom Semiconductor + +pci:v000012D8d000001A7* + ID_PRODUCT_FROM_DATABASE=PI7C21P100 PCI to PCI Bridge + +pci:v000012D8d0000400A* + ID_PRODUCT_FROM_DATABASE=PI7C9X442SL PCI Express Bridge Port + +pci:v000012D8d0000400E* + ID_PRODUCT_FROM_DATABASE=PI7C9X442SL USB OHCI Controller + +pci:v000012D8d0000400F* + ID_PRODUCT_FROM_DATABASE=PI7C9X442SL USB EHCI Controller + +pci:v000012D8d000071E2* + ID_PRODUCT_FROM_DATABASE=PI7C7300A/PI7C7300D PCI-to-PCI Bridge + +pci:v000012D8d000071E3* + ID_PRODUCT_FROM_DATABASE=PI7C7300A/PI7C7300D PCI-to-PCI Bridge (Secondary Bus 2) + +pci:v000012D8d00008140* + ID_PRODUCT_FROM_DATABASE=PI7C8140A PCI-to-PCI Bridge + +pci:v000012D8d00008148* + ID_PRODUCT_FROM_DATABASE=PI7C8148A/PI7C8148B PCI-to-PCI Bridge + +pci:v000012D8d00008150* + ID_PRODUCT_FROM_DATABASE=PCI to PCI Bridge + +pci:v000012D8d00008152* + ID_PRODUCT_FROM_DATABASE=PI7C8152A/PI7C8152B/PI7C8152BI PCI-to-PCI Bridge + +pci:v000012D8d00008154* + ID_PRODUCT_FROM_DATABASE=PI7C8154A/PI7C8154B/PI7C8154BI PCI-to-PCI Bridge + +pci:v000012D8d0000E110* + ID_PRODUCT_FROM_DATABASE=PI7C9X110 PCI Express to PCI bridge + +pci:v000012D8d0000E110sv00001775sd000011CC* + ID_PRODUCT_FROM_DATABASE=CC11/CL11 CompactPCI Bridge + +pci:v000012D8d0000E130* + ID_PRODUCT_FROM_DATABASE=PCI Express to PCI-XPI7C9X130 PCI-X Bridge + +pci:v000012D9* + ID_VENDOR_FROM_DATABASE=Aculab PLC + +pci:v000012D9d00000002* + ID_PRODUCT_FROM_DATABASE=PCI Prosody + +pci:v000012D9d00000004* + ID_PRODUCT_FROM_DATABASE=cPCI Prosody + +pci:v000012D9d00000005* + ID_PRODUCT_FROM_DATABASE=Aculab E1/T1 PCI card + +pci:v000012D9d00001078* + ID_PRODUCT_FROM_DATABASE=Prosody X class e1000 device + +pci:v000012D9d00001078sv000012D9sd0000000D* + ID_PRODUCT_FROM_DATABASE=Prosody X PCI + +pci:v000012D9d00001078sv000012D9sd0000000E* + ID_PRODUCT_FROM_DATABASE=Prosody X cPCI + +pci:v000012DA* + ID_VENDOR_FROM_DATABASE=True Time Inc. + +pci:v000012DB* + ID_VENDOR_FROM_DATABASE=Annapolis Micro Systems, Inc + +pci:v000012DC* + ID_VENDOR_FROM_DATABASE=Symicron Computer Communication Ltd. + +pci:v000012DD* + ID_VENDOR_FROM_DATABASE=Management Graphics + +pci:v000012DE* + ID_VENDOR_FROM_DATABASE=Rainbow Technologies + +pci:v000012DEd00000200* + ID_PRODUCT_FROM_DATABASE=CryptoSwift CS200 + +pci:v000012DF* + ID_VENDOR_FROM_DATABASE=SBS Technologies Inc + +pci:v000012E0* + ID_VENDOR_FROM_DATABASE=Chase Research + +pci:v000012E0d00000010* + ID_PRODUCT_FROM_DATABASE=ST16C654 Quad UART + +pci:v000012E0d00000020* + ID_PRODUCT_FROM_DATABASE=ST16C654 Quad UART + +pci:v000012E0d00000030* + ID_PRODUCT_FROM_DATABASE=ST16C654 Quad UART + +pci:v000012E1* + ID_VENDOR_FROM_DATABASE=Nintendo Co, Ltd + +pci:v000012E2* + ID_VENDOR_FROM_DATABASE=Datum Inc. Bancomm-Timing Division + +pci:v000012E3* + ID_VENDOR_FROM_DATABASE=Imation Corp - Medical Imaging Systems + +pci:v000012E4* + ID_VENDOR_FROM_DATABASE=Brooktrout Technology Inc + +pci:v000012E5* + ID_VENDOR_FROM_DATABASE=Apex Semiconductor Inc + +pci:v000012E6* + ID_VENDOR_FROM_DATABASE=Cirel Systems + +pci:v000012E7* + ID_VENDOR_FROM_DATABASE=Sunsgroup Corporation + +pci:v000012E8* + ID_VENDOR_FROM_DATABASE=Crisc Corp + +pci:v000012E9* + ID_VENDOR_FROM_DATABASE=GE Spacenet + +pci:v000012EA* + ID_VENDOR_FROM_DATABASE=Zuken + +pci:v000012EB* + ID_VENDOR_FROM_DATABASE=Aureal Semiconductor + +pci:v000012EBd00000001* + ID_PRODUCT_FROM_DATABASE=Vortex 1 + +pci:v000012EBd00000001sv0000104Dsd00008036* + ID_PRODUCT_FROM_DATABASE=AU8820 Vortex Digital Audio Processor + +pci:v000012EBd00000001sv00001092sd00002000* + ID_PRODUCT_FROM_DATABASE=Sonic Impact A3D + +pci:v000012EBd00000001sv00001092sd00002100* + ID_PRODUCT_FROM_DATABASE=Sonic Impact A3D + +pci:v000012EBd00000001sv00001092sd00002110* + ID_PRODUCT_FROM_DATABASE=Sonic Impact A3D + +pci:v000012EBd00000001sv00001092sd00002200* + ID_PRODUCT_FROM_DATABASE=Sonic Impact A3D + +pci:v000012EBd00000001sv0000122Dsd00001002* + ID_PRODUCT_FROM_DATABASE=AU8820 Vortex Digital Audio Processor + +pci:v000012EBd00000001sv000012EBsd00000001* + ID_PRODUCT_FROM_DATABASE=AU8820 Vortex Digital Audio Processor + +pci:v000012EBd00000001sv00005053sd00003355* + ID_PRODUCT_FROM_DATABASE=Montego + +pci:v000012EBd00000002* + ID_PRODUCT_FROM_DATABASE=Vortex 2 + +pci:v000012EBd00000002sv0000104Dsd00008049* + ID_PRODUCT_FROM_DATABASE=AU8830 Vortex 3D Digital Audio Processor + +pci:v000012EBd00000002sv0000104Dsd0000807B* + ID_PRODUCT_FROM_DATABASE=AU8830 Vortex 3D Digital Audio Processor + +pci:v000012EBd00000002sv00001092sd00003000* + ID_PRODUCT_FROM_DATABASE=Monster Sound II + +pci:v000012EBd00000002sv00001092sd00003001* + ID_PRODUCT_FROM_DATABASE=Monster Sound II + +pci:v000012EBd00000002sv00001092sd00003002* + ID_PRODUCT_FROM_DATABASE=Monster Sound II + +pci:v000012EBd00000002sv00001092sd00003003* + ID_PRODUCT_FROM_DATABASE=Monster Sound II + +pci:v000012EBd00000002sv00001092sd00003004* + ID_PRODUCT_FROM_DATABASE=Monster Sound II + +pci:v000012EBd00000002sv000012EBsd00000002* + ID_PRODUCT_FROM_DATABASE=AU8830 Vortex 3D Digital Audio Processor + +pci:v000012EBd00000002sv000012EBsd00000088* + ID_PRODUCT_FROM_DATABASE=AU8830 Vortex 3D Digital Audio Processor + +pci:v000012EBd00000002sv0000144Dsd00003510* + ID_PRODUCT_FROM_DATABASE=AU8830 Vortex 3D Digital Audio Processor + +pci:v000012EBd00000002sv00005053sd00003356* + ID_PRODUCT_FROM_DATABASE=Montego II + +pci:v000012EBd00000003* + ID_PRODUCT_FROM_DATABASE=AU8810 Vortex Digital Audio Processor + +pci:v000012EBd00000003sv0000104Dsd00008049* + ID_PRODUCT_FROM_DATABASE=AU8810 Vortex Digital Audio Processor + +pci:v000012EBd00000003sv0000104Dsd00008077* + ID_PRODUCT_FROM_DATABASE=AU8810 Vortex Digital Audio Processor + +pci:v000012EBd00000003sv0000109Fsd00001000* + ID_PRODUCT_FROM_DATABASE=AU8810 Vortex Digital Audio Processor + +pci:v000012EBd00000003sv000012EBsd00000003* + ID_PRODUCT_FROM_DATABASE=AU8810 Vortex Digital Audio Processor + +pci:v000012EBd00000003sv00001462sd00006780* + ID_PRODUCT_FROM_DATABASE=AU8810 Vortex Digital Audio Processor + +pci:v000012EBd00000003sv000014A4sd00002073* + ID_PRODUCT_FROM_DATABASE=AU8810 Vortex Digital Audio Processor + +pci:v000012EBd00000003sv000014A4sd00002091* + ID_PRODUCT_FROM_DATABASE=AU8810 Vortex Digital Audio Processor + +pci:v000012EBd00000003sv000014A4sd00002104* + ID_PRODUCT_FROM_DATABASE=AU8810 Vortex Digital Audio Processor + +pci:v000012EBd00000003sv000014A4sd00002106* + ID_PRODUCT_FROM_DATABASE=AU8810 Vortex Digital Audio Processor + +pci:v000012EBd00008803* + ID_PRODUCT_FROM_DATABASE=Vortex 56k Software Modem + +pci:v000012EBd00008803sv000012EBsd00008803* + ID_PRODUCT_FROM_DATABASE=Vortex 56k Software Modem + +pci:v000012EC* + ID_VENDOR_FROM_DATABASE=3A International, Inc. + +pci:v000012ED* + ID_VENDOR_FROM_DATABASE=Optivision Inc. + +pci:v000012EE* + ID_VENDOR_FROM_DATABASE=Orange Micro + +pci:v000012EF* + ID_VENDOR_FROM_DATABASE=Vienna Systems + +pci:v000012F0* + ID_VENDOR_FROM_DATABASE=Pentek + +pci:v000012F1* + ID_VENDOR_FROM_DATABASE=Sorenson Vision Inc + +pci:v000012F2* + ID_VENDOR_FROM_DATABASE=Gammagraphx, Inc. + +pci:v000012F3* + ID_VENDOR_FROM_DATABASE=Radstone Technology + +pci:v000012F4* + ID_VENDOR_FROM_DATABASE=Megatel + +pci:v000012F5* + ID_VENDOR_FROM_DATABASE=Forks + +pci:v000012F6* + ID_VENDOR_FROM_DATABASE=Dawson France + +pci:v000012F7* + ID_VENDOR_FROM_DATABASE=Cognex + +pci:v000012F8* + ID_VENDOR_FROM_DATABASE=Electronic Design GmbH + +pci:v000012F8d00000002* + ID_PRODUCT_FROM_DATABASE=VideoMaker + +pci:v000012F9* + ID_VENDOR_FROM_DATABASE=Four Fold Ltd + +pci:v000012FB* + ID_VENDOR_FROM_DATABASE=Spectrum Signal Processing + +pci:v000012FBd00000001* + ID_PRODUCT_FROM_DATABASE=PMC-MAI + +pci:v000012FBd000000F5* + ID_PRODUCT_FROM_DATABASE=F5 Dakar + +pci:v000012FBd000002AD* + ID_PRODUCT_FROM_DATABASE=PMC-2MAI + +pci:v000012FBd00002ADC* + ID_PRODUCT_FROM_DATABASE=ePMC-2ADC + +pci:v000012FBd00003100* + ID_PRODUCT_FROM_DATABASE=PRO-3100 + +pci:v000012FBd00003500* + ID_PRODUCT_FROM_DATABASE=PRO-3500 + +pci:v000012FBd00004D4F* + ID_PRODUCT_FROM_DATABASE=Modena + +pci:v000012FBd00008120* + ID_PRODUCT_FROM_DATABASE=ePMC-8120 + +pci:v000012FBd0000DA62* + ID_PRODUCT_FROM_DATABASE=Daytona C6201 PCI (Hurricane) + +pci:v000012FBd0000DB62* + ID_PRODUCT_FROM_DATABASE=Ingliston XBIF + +pci:v000012FBd0000DC62* + ID_PRODUCT_FROM_DATABASE=Ingliston PLX9054 + +pci:v000012FBd0000DD62* + ID_PRODUCT_FROM_DATABASE=Ingliston JTAG/ISP + +pci:v000012FBd0000EDDC* + ID_PRODUCT_FROM_DATABASE=ePMC-MSDDC + +pci:v000012FBd0000FA01* + ID_PRODUCT_FROM_DATABASE=ePMC-FPGA + +pci:v000012FC* + ID_VENDOR_FROM_DATABASE=Capital Equipment Corp + +pci:v000012FD* + ID_VENDOR_FROM_DATABASE=I2S + +pci:v000012FE* + ID_VENDOR_FROM_DATABASE=ESD Electronic System Design GmbH + +pci:v000012FF* + ID_VENDOR_FROM_DATABASE=Lexicon + +pci:v00001300* + ID_VENDOR_FROM_DATABASE=Harman International Industries Inc + +pci:v00001302* + ID_VENDOR_FROM_DATABASE=Computer Sciences Corp + +pci:v00001303* + ID_VENDOR_FROM_DATABASE=Innovative Integration + +pci:v00001303d00000030* + ID_PRODUCT_FROM_DATABASE=X3-SDF 4-channel XMC acquisition board + +pci:v00001304* + ID_VENDOR_FROM_DATABASE=Juniper Networks + +pci:v00001305* + ID_VENDOR_FROM_DATABASE=Netphone, Inc + +pci:v00001306* + ID_VENDOR_FROM_DATABASE=Duet Technologies + +pci:v00001307* + ID_VENDOR_FROM_DATABASE=Measurement Computing + +pci:v00001307d00000001* + ID_PRODUCT_FROM_DATABASE=PCI-DAS1602/16 + +pci:v00001307d0000000B* + ID_PRODUCT_FROM_DATABASE=PCI-DIO48H + +pci:v00001307d0000000C* + ID_PRODUCT_FROM_DATABASE=PCI-PDISO8 + +pci:v00001307d0000000D* + ID_PRODUCT_FROM_DATABASE=PCI-PDISO16 + +pci:v00001307d0000000F* + ID_PRODUCT_FROM_DATABASE=PCI-DAS1200 + +pci:v00001307d00000010* + ID_PRODUCT_FROM_DATABASE=PCI-DAS1602/12 + +pci:v00001307d00000014* + ID_PRODUCT_FROM_DATABASE=PCI-DIO24H + +pci:v00001307d00000015* + ID_PRODUCT_FROM_DATABASE=PCI-DIO24H/CTR3 + +pci:v00001307d00000016* + ID_PRODUCT_FROM_DATABASE=PCI-DIO48H/CTR15 + +pci:v00001307d00000017* + ID_PRODUCT_FROM_DATABASE=PCI-DIO96H + +pci:v00001307d00000018* + ID_PRODUCT_FROM_DATABASE=PCI-CTR05 + +pci:v00001307d00000019* + ID_PRODUCT_FROM_DATABASE=PCI-DAS1200/JR + +pci:v00001307d0000001A* + ID_PRODUCT_FROM_DATABASE=PCI-DAS1001 + +pci:v00001307d0000001B* + ID_PRODUCT_FROM_DATABASE=PCI-DAS1002 + +pci:v00001307d0000001C* + ID_PRODUCT_FROM_DATABASE=PCI-DAS1602JR/16 + +pci:v00001307d0000001D* + ID_PRODUCT_FROM_DATABASE=PCI-DAS6402/16 + +pci:v00001307d0000001E* + ID_PRODUCT_FROM_DATABASE=PCI-DAS6402/12 + +pci:v00001307d0000001F* + ID_PRODUCT_FROM_DATABASE=PCI-DAS16/M1 + +pci:v00001307d00000020* + ID_PRODUCT_FROM_DATABASE=PCI-DDA02/12 + +pci:v00001307d00000021* + ID_PRODUCT_FROM_DATABASE=PCI-DDA04/12 + +pci:v00001307d00000022* + ID_PRODUCT_FROM_DATABASE=PCI-DDA08/12 + +pci:v00001307d00000023* + ID_PRODUCT_FROM_DATABASE=PCI-DDA02/16 + +pci:v00001307d00000024* + ID_PRODUCT_FROM_DATABASE=PCI-DDA04/16 + +pci:v00001307d00000025* + ID_PRODUCT_FROM_DATABASE=PCI-DDA08/16 + +pci:v00001307d00000026* + ID_PRODUCT_FROM_DATABASE=PCI-DAC04/12-HS + +pci:v00001307d00000027* + ID_PRODUCT_FROM_DATABASE=PCI-DAC04/16-HS + +pci:v00001307d00000028* + ID_PRODUCT_FROM_DATABASE=PCI-DIO24 + +pci:v00001307d00000029* + ID_PRODUCT_FROM_DATABASE=PCI-DAS08 + +pci:v00001307d0000002C* + ID_PRODUCT_FROM_DATABASE=PCI-INT32 + +pci:v00001307d00000033* + ID_PRODUCT_FROM_DATABASE=PCI-DUAL-AC5 + +pci:v00001307d00000034* + ID_PRODUCT_FROM_DATABASE=PCI-DAS-TC + +pci:v00001307d00000035* + ID_PRODUCT_FROM_DATABASE=PCI-DAS64/M1/16 + +pci:v00001307d00000036* + ID_PRODUCT_FROM_DATABASE=PCI-DAS64/M2/16 + +pci:v00001307d00000037* + ID_PRODUCT_FROM_DATABASE=PCI-DAS64/M3/16 + +pci:v00001307d0000004C* + ID_PRODUCT_FROM_DATABASE=PCI-DAS1000 + +pci:v00001307d0000004D* + ID_PRODUCT_FROM_DATABASE=PCI-QUAD04 + +pci:v00001307d00000052* + ID_PRODUCT_FROM_DATABASE=PCI-DAS4020/12 + +pci:v00001307d00000053* + ID_PRODUCT_FROM_DATABASE=PCIM-DDA06/16 + +pci:v00001307d00000054* + ID_PRODUCT_FROM_DATABASE=PCI-DIO96 + +pci:v00001307d0000005D* + ID_PRODUCT_FROM_DATABASE=PCI-DAS6023 + +pci:v00001307d0000005E* + ID_PRODUCT_FROM_DATABASE=PCI-DAS6025 + +pci:v00001307d0000005F* + ID_PRODUCT_FROM_DATABASE=PCI-DAS6030 + +pci:v00001307d00000060* + ID_PRODUCT_FROM_DATABASE=PCI-DAS6031 + +pci:v00001307d00000061* + ID_PRODUCT_FROM_DATABASE=PCI-DAS6032 + +pci:v00001307d00000062* + ID_PRODUCT_FROM_DATABASE=PCI-DAS6033 + +pci:v00001307d00000063* + ID_PRODUCT_FROM_DATABASE=PCI-DAS6034 + +pci:v00001307d00000064* + ID_PRODUCT_FROM_DATABASE=PCI-DAS6035 + +pci:v00001307d00000065* + ID_PRODUCT_FROM_DATABASE=PCI-DAS6040 + +pci:v00001307d00000066* + ID_PRODUCT_FROM_DATABASE=PCI-DAS6052 + +pci:v00001307d00000067* + ID_PRODUCT_FROM_DATABASE=PCI-DAS6070 + +pci:v00001307d00000068* + ID_PRODUCT_FROM_DATABASE=PCI-DAS6071 + +pci:v00001307d0000006F* + ID_PRODUCT_FROM_DATABASE=PCI-DAS6036 + +pci:v00001307d00000070* + ID_PRODUCT_FROM_DATABASE=PCI-DAC6702 + +pci:v00001307d00000078* + ID_PRODUCT_FROM_DATABASE=PCI-DAS6013 + +pci:v00001307d00000079* + ID_PRODUCT_FROM_DATABASE=PCI-DAS6014 + +pci:v00001307d00000115* + ID_PRODUCT_FROM_DATABASE=PCIe-DAS1602/16 + +pci:v00001308* + ID_VENDOR_FROM_DATABASE=Jato Technologies Inc. + +pci:v00001308d00000001* + ID_PRODUCT_FROM_DATABASE=NetCelerator Adapter + +pci:v00001308d00000001sv00001308sd00000001* + ID_PRODUCT_FROM_DATABASE=NetCelerator Adapter + +pci:v00001309* + ID_VENDOR_FROM_DATABASE=AB Semiconductor Ltd + +pci:v0000130A* + ID_VENDOR_FROM_DATABASE=Mitsubishi Electric Microcomputer + +pci:v0000130B* + ID_VENDOR_FROM_DATABASE=Colorgraphic Communications Corp + +pci:v0000130C* + ID_VENDOR_FROM_DATABASE=Ambex Technologies, Inc + +pci:v0000130D* + ID_VENDOR_FROM_DATABASE=Accelerix Inc + +pci:v0000130E* + ID_VENDOR_FROM_DATABASE=Yamatake-Honeywell Co. Ltd + +pci:v0000130F* + ID_VENDOR_FROM_DATABASE=Advanet Inc + +pci:v00001310* + ID_VENDOR_FROM_DATABASE=Gespac + +pci:v00001311* + ID_VENDOR_FROM_DATABASE=Videoserver, Inc + +pci:v00001312* + ID_VENDOR_FROM_DATABASE=Acuity Imaging, Inc + +pci:v00001313* + ID_VENDOR_FROM_DATABASE=Yaskawa Electric Co. + +pci:v00001315* + ID_VENDOR_FROM_DATABASE=Wavesat + +pci:v00001316* + ID_VENDOR_FROM_DATABASE=Teradyne Inc + +pci:v00001317* + ID_VENDOR_FROM_DATABASE=ADMtek + +pci:v00001317d00000981* + ID_PRODUCT_FROM_DATABASE=21x4x DEC-Tulip compatible 10/100 Ethernet + +pci:v00001317d00000985* + ID_PRODUCT_FROM_DATABASE=NC100 Network Everywhere Fast Ethernet 10/100 + +pci:v00001317d00000985sv00001734sd0000100C* + ID_PRODUCT_FROM_DATABASE=Scenic N300 ADMtek AN983 10/100 Mbps PCI Adapter + +pci:v00001317d00001985* + ID_PRODUCT_FROM_DATABASE=21x4x DEC-Tulip compatible 10/100 Ethernet + +pci:v00001317d00001985sv00001385sd0000511A* + ID_PRODUCT_FROM_DATABASE=FA511 + +pci:v00001317d00001985sv00001395sd00002103* + ID_PRODUCT_FROM_DATABASE=CB100-EZ (4-LED version) + +pci:v00001317d00002850* + ID_PRODUCT_FROM_DATABASE=HSP MicroModem 56 + +pci:v00001317d00005120* + ID_PRODUCT_FROM_DATABASE=ADM5120 OpenGate System-on-Chip + +pci:v00001317d00008201* + ID_PRODUCT_FROM_DATABASE=ADM8211 802.11b Wireless Interface + +pci:v00001317d00008201sv000010B8sd00002635* + ID_PRODUCT_FROM_DATABASE=SMC2635W v1 802.11b Wireless Cardbus Adapter + +pci:v00001317d00008201sv00001317sd00008201* + ID_PRODUCT_FROM_DATABASE=SMC2635W v2 802.11b Wireless Cardbus Adapter + +pci:v00001317d00008211* + ID_PRODUCT_FROM_DATABASE=ADM8211 802.11b Wireless Interface + +pci:v00001317d00009511* + ID_PRODUCT_FROM_DATABASE=21x4x DEC-Tulip compatible 10/100 Ethernet + +pci:v00001318* + ID_VENDOR_FROM_DATABASE=Packet Engines Inc. + +pci:v00001318d00000911* + ID_PRODUCT_FROM_DATABASE=GNIC-II PCI Gigabit Ethernet [Hamachi] + +pci:v00001319* + ID_VENDOR_FROM_DATABASE=Fortemedia, Inc + +pci:v00001319d00000801* + ID_PRODUCT_FROM_DATABASE=Xwave QS3000A [FM801] + +pci:v00001319d00000801sv00001319sd00001319* + ID_PRODUCT_FROM_DATABASE=FM801 PCI Audio + +pci:v00001319d00000802* + ID_PRODUCT_FROM_DATABASE=Xwave QS3000A [FM801 game port] + +pci:v00001319d00000802sv00001319sd00001319* + ID_PRODUCT_FROM_DATABASE=FM801 PCI Joystick + +pci:v00001319d00001000* + ID_PRODUCT_FROM_DATABASE=FM801 PCI Audio + +pci:v00001319d00001001* + ID_PRODUCT_FROM_DATABASE=FM801 PCI Joystick + +pci:v0000131A* + ID_VENDOR_FROM_DATABASE=Finisar Corp. + +pci:v0000131C* + ID_VENDOR_FROM_DATABASE=Nippon Electro-Sensory Devices Corp + +pci:v0000131D* + ID_VENDOR_FROM_DATABASE=Sysmic, Inc. + +pci:v0000131E* + ID_VENDOR_FROM_DATABASE=Xinex Networks Inc + +pci:v0000131F* + ID_VENDOR_FROM_DATABASE=Siig Inc + +pci:v0000131Fd00001000* + ID_PRODUCT_FROM_DATABASE=CyberSerial (1-port) 16550 + +pci:v0000131Fd00001001* + ID_PRODUCT_FROM_DATABASE=CyberSerial (1-port) 16650 + +pci:v0000131Fd00001002* + ID_PRODUCT_FROM_DATABASE=CyberSerial (1-port) 16850 + +pci:v0000131Fd00001010* + ID_PRODUCT_FROM_DATABASE=Duet 1S(16550)+1P + +pci:v0000131Fd00001011* + ID_PRODUCT_FROM_DATABASE=Duet 1S(16650)+1P + +pci:v0000131Fd00001012* + ID_PRODUCT_FROM_DATABASE=Duet 1S(16850)+1P + +pci:v0000131Fd00001020* + ID_PRODUCT_FROM_DATABASE=CyberParallel (1-port) + +pci:v0000131Fd00001021* + ID_PRODUCT_FROM_DATABASE=CyberParallel (2-port) + +pci:v0000131Fd00001030* + ID_PRODUCT_FROM_DATABASE=CyberSerial (2-port) 16550 + +pci:v0000131Fd00001031* + ID_PRODUCT_FROM_DATABASE=CyberSerial (2-port) 16650 + +pci:v0000131Fd00001032* + ID_PRODUCT_FROM_DATABASE=CyberSerial (2-port) 16850 + +pci:v0000131Fd00001034* + ID_PRODUCT_FROM_DATABASE=Trio 2S(16550)+1P + +pci:v0000131Fd00001035* + ID_PRODUCT_FROM_DATABASE=Trio 2S(16650)+1P + +pci:v0000131Fd00001036* + ID_PRODUCT_FROM_DATABASE=Trio 2S(16850)+1P + +pci:v0000131Fd00001050* + ID_PRODUCT_FROM_DATABASE=CyberSerial (4-port) 16550 + +pci:v0000131Fd00001051* + ID_PRODUCT_FROM_DATABASE=CyberSerial (4-port) 16650 + +pci:v0000131Fd00001052* + ID_PRODUCT_FROM_DATABASE=CyberSerial (4-port) 16850 + +pci:v0000131Fd00002000* + ID_PRODUCT_FROM_DATABASE=CyberSerial (1-port) 16550 + +pci:v0000131Fd00002001* + ID_PRODUCT_FROM_DATABASE=CyberSerial (1-port) 16650 + +pci:v0000131Fd00002002* + ID_PRODUCT_FROM_DATABASE=CyberSerial (1-port) 16850 + +pci:v0000131Fd00002010* + ID_PRODUCT_FROM_DATABASE=Duet 1S(16550)+1P + +pci:v0000131Fd00002011* + ID_PRODUCT_FROM_DATABASE=Duet 1S(16650)+1P + +pci:v0000131Fd00002012* + ID_PRODUCT_FROM_DATABASE=Duet 1S(16850)+1P + +pci:v0000131Fd00002020* + ID_PRODUCT_FROM_DATABASE=CyberParallel (1-port) + +pci:v0000131Fd00002021* + ID_PRODUCT_FROM_DATABASE=CyberParallel (2-port) + +pci:v0000131Fd00002030* + ID_PRODUCT_FROM_DATABASE=CyberSerial (2-port) 16550 + +pci:v0000131Fd00002030sv0000131Fsd00002030* + ID_PRODUCT_FROM_DATABASE=PCI Serial Card + +pci:v0000131Fd00002031* + ID_PRODUCT_FROM_DATABASE=CyberSerial (2-port) 16650 + +pci:v0000131Fd00002032* + ID_PRODUCT_FROM_DATABASE=CyberSerial (2-port) 16850 + +pci:v0000131Fd00002040* + ID_PRODUCT_FROM_DATABASE=Trio 1S(16550)+2P + +pci:v0000131Fd00002041* + ID_PRODUCT_FROM_DATABASE=Trio 1S(16650)+2P + +pci:v0000131Fd00002042* + ID_PRODUCT_FROM_DATABASE=Trio 1S(16850)+2P + +pci:v0000131Fd00002050* + ID_PRODUCT_FROM_DATABASE=CyberSerial (4-port) 16550 + +pci:v0000131Fd00002051* + ID_PRODUCT_FROM_DATABASE=CyberSerial (4-port) 16650 + +pci:v0000131Fd00002052* + ID_PRODUCT_FROM_DATABASE=CyberSerial (4-port) 16850 + +pci:v0000131Fd00002060* + ID_PRODUCT_FROM_DATABASE=Trio 2S(16550)+1P + +pci:v0000131Fd00002061* + ID_PRODUCT_FROM_DATABASE=Trio 2S(16650)+1P + +pci:v0000131Fd00002062* + ID_PRODUCT_FROM_DATABASE=Trio 2S(16850)+1P + +pci:v0000131Fd00002081* + ID_PRODUCT_FROM_DATABASE=CyberSerial (8-port) ST16654 + +pci:v00001320* + ID_VENDOR_FROM_DATABASE=Crypto AG + +pci:v00001321* + ID_VENDOR_FROM_DATABASE=Arcobel Graphics BV + +pci:v00001322* + ID_VENDOR_FROM_DATABASE=MTT Co., Ltd + +pci:v00001323* + ID_VENDOR_FROM_DATABASE=Dome Inc + +pci:v00001324* + ID_VENDOR_FROM_DATABASE=Sphere Communications + +pci:v00001325* + ID_VENDOR_FROM_DATABASE=Salix Technologies, Inc + +pci:v00001326* + ID_VENDOR_FROM_DATABASE=Seachange international + +pci:v00001327* + ID_VENDOR_FROM_DATABASE=Voss scientific + +pci:v00001328* + ID_VENDOR_FROM_DATABASE=quadrant international + +pci:v00001329* + ID_VENDOR_FROM_DATABASE=Productivity Enhancement + +pci:v0000132A* + ID_VENDOR_FROM_DATABASE=Microcom Inc. + +pci:v0000132B* + ID_VENDOR_FROM_DATABASE=Broadband Technologies + +pci:v0000132C* + ID_VENDOR_FROM_DATABASE=Micrel Inc + +pci:v0000132D* + ID_VENDOR_FROM_DATABASE=Integrated Silicon Solution, Inc. + +pci:v00001330* + ID_VENDOR_FROM_DATABASE=MMC Networks + +pci:v00001331* + ID_VENDOR_FROM_DATABASE=RadiSys Corporation + +pci:v00001331d00000030* + ID_PRODUCT_FROM_DATABASE=ENP-2611 + +pci:v00001331d00008200* + ID_PRODUCT_FROM_DATABASE=82600 Host Bridge + +pci:v00001331d00008201* + ID_PRODUCT_FROM_DATABASE=82600 IDE + +pci:v00001331d00008202* + ID_PRODUCT_FROM_DATABASE=82600 USB + +pci:v00001331d00008210* + ID_PRODUCT_FROM_DATABASE=82600 PCI Bridge + +pci:v00001332* + ID_VENDOR_FROM_DATABASE=Micro Memory + +pci:v00001332d00005415* + ID_PRODUCT_FROM_DATABASE=MM-5415CN PCI Memory Module with Battery Backup + +pci:v00001332d00005425* + ID_PRODUCT_FROM_DATABASE=MM-5425CN PCI 64/66 Memory Module with Battery Backup + +pci:v00001332d00006140* + ID_PRODUCT_FROM_DATABASE=MM-6140D + +pci:v00001334* + ID_VENDOR_FROM_DATABASE=Redcreek Communications, Inc + +pci:v00001335* + ID_VENDOR_FROM_DATABASE=Videomail, Inc + +pci:v00001337* + ID_VENDOR_FROM_DATABASE=Third Planet Publishing + +pci:v00001338* + ID_VENDOR_FROM_DATABASE=BT Electronics + +pci:v0000133A* + ID_VENDOR_FROM_DATABASE=Vtel Corp + +pci:v0000133B* + ID_VENDOR_FROM_DATABASE=Softcom Microsystems + +pci:v0000133C* + ID_VENDOR_FROM_DATABASE=Holontech Corp + +pci:v0000133D* + ID_VENDOR_FROM_DATABASE=SS Technologies + +pci:v0000133E* + ID_VENDOR_FROM_DATABASE=Virtual Computer Corp + +pci:v0000133F* + ID_VENDOR_FROM_DATABASE=SCM Microsystems + +pci:v00001340* + ID_VENDOR_FROM_DATABASE=Atalla Corp + +pci:v00001341* + ID_VENDOR_FROM_DATABASE=Kyoto Microcomputer Co + +pci:v00001342* + ID_VENDOR_FROM_DATABASE=Promax Systems Inc + +pci:v00001343* + ID_VENDOR_FROM_DATABASE=Phylon Communications Inc + +pci:v00001344* + ID_VENDOR_FROM_DATABASE=Micron Technology Inc + +pci:v00001344d00005150* + ID_PRODUCT_FROM_DATABASE=RealSSD P320h + +pci:v00001344d00005151* + ID_PRODUCT_FROM_DATABASE=RealSSD P320m + +pci:v00001344d00005152* + ID_PRODUCT_FROM_DATABASE=RealSSD P320s + +pci:v00001344d00005153* + ID_PRODUCT_FROM_DATABASE=RealSSD P325m + +pci:v00001344d00005160* + ID_PRODUCT_FROM_DATABASE=RealSSD P420h + +pci:v00001344d00005161* + ID_PRODUCT_FROM_DATABASE=RealSSD P420m + +pci:v00001344d00005163* + ID_PRODUCT_FROM_DATABASE=RealSSD P425m + +pci:v00001345* + ID_VENDOR_FROM_DATABASE=Arescom Inc + +pci:v00001347* + ID_VENDOR_FROM_DATABASE=Odetics + +pci:v00001349* + ID_VENDOR_FROM_DATABASE=Sumitomo Electric Industries, Ltd. + +pci:v0000134A* + ID_VENDOR_FROM_DATABASE=DTC Technology Corp. + +pci:v0000134Ad00000001* + ID_PRODUCT_FROM_DATABASE=Domex 536 + +pci:v0000134Ad00000002* + ID_PRODUCT_FROM_DATABASE=Domex DMX3194UP SCSI Adapter + +pci:v0000134B* + ID_VENDOR_FROM_DATABASE=ARK Research Corp. + +pci:v0000134C* + ID_VENDOR_FROM_DATABASE=Chori Joho System Co. Ltd + +pci:v0000134D* + ID_VENDOR_FROM_DATABASE=PCTel Inc + +pci:v0000134Dd00002189* + ID_PRODUCT_FROM_DATABASE=HSP56 MicroModem + +pci:v0000134Dd00002486* + ID_PRODUCT_FROM_DATABASE=2304WT V.92 MDC Modem + +pci:v0000134Dd00007890* + ID_PRODUCT_FROM_DATABASE=HSP MicroModem 56 + +pci:v0000134Dd00007890sv0000134Dsd00000001* + ID_PRODUCT_FROM_DATABASE=PCT789 adapter + +pci:v0000134Dd00007891* + ID_PRODUCT_FROM_DATABASE=HSP MicroModem 56 + +pci:v0000134Dd00007891sv0000134Dsd00000001* + ID_PRODUCT_FROM_DATABASE=HSP MicroModem 56 + +pci:v0000134Dd00007892* + ID_PRODUCT_FROM_DATABASE=HSP MicroModem 56 + +pci:v0000134Dd00007893* + ID_PRODUCT_FROM_DATABASE=HSP MicroModem 56 + +pci:v0000134Dd00007894* + ID_PRODUCT_FROM_DATABASE=HSP MicroModem 56 + +pci:v0000134Dd00007895* + ID_PRODUCT_FROM_DATABASE=HSP MicroModem 56 + +pci:v0000134Dd00007896* + ID_PRODUCT_FROM_DATABASE=HSP MicroModem 56 + +pci:v0000134Dd00007897* + ID_PRODUCT_FROM_DATABASE=HSP MicroModem 56 + +pci:v0000134E* + ID_VENDOR_FROM_DATABASE=CSTI + +pci:v0000134F* + ID_VENDOR_FROM_DATABASE=Algo System Co Ltd + +pci:v00001350* + ID_VENDOR_FROM_DATABASE=Systec Co. Ltd + +pci:v00001351* + ID_VENDOR_FROM_DATABASE=Sonix Inc + +pci:v00001353* + ID_VENDOR_FROM_DATABASE=Vierling Communication SAS + +pci:v00001353d00000002* + ID_PRODUCT_FROM_DATABASE=Proserver + +pci:v00001353d00000003* + ID_PRODUCT_FROM_DATABASE=PCI-FUT + +pci:v00001353d00000004* + ID_PRODUCT_FROM_DATABASE=PCI-S0 + +pci:v00001353d00000005* + ID_PRODUCT_FROM_DATABASE=PCI-FUT-S0 + +pci:v00001354* + ID_VENDOR_FROM_DATABASE=Dwave System Inc + +pci:v00001355* + ID_VENDOR_FROM_DATABASE=Kratos Analytical Ltd + +pci:v00001356* + ID_VENDOR_FROM_DATABASE=The Logical Co + +pci:v00001359* + ID_VENDOR_FROM_DATABASE=Prisa Networks + +pci:v0000135A* + ID_VENDOR_FROM_DATABASE=Brain Boxes + +pci:v0000135Ad00000A61* + ID_PRODUCT_FROM_DATABASE=UC-324 [VELOCITY RS422/485] + +pci:v0000135B* + ID_VENDOR_FROM_DATABASE=Giganet Inc + +pci:v0000135C* + ID_VENDOR_FROM_DATABASE=Quatech Inc + +pci:v0000135Cd00000010* + ID_PRODUCT_FROM_DATABASE=QSC-100 + +pci:v0000135Cd00000020* + ID_PRODUCT_FROM_DATABASE=DSC-100 + +pci:v0000135Cd00000030* + ID_PRODUCT_FROM_DATABASE=DSC-200/300 + +pci:v0000135Cd00000040* + ID_PRODUCT_FROM_DATABASE=QSC-200/300 + +pci:v0000135Cd00000050* + ID_PRODUCT_FROM_DATABASE=ESC-100D + +pci:v0000135Cd00000060* + ID_PRODUCT_FROM_DATABASE=ESC-100M + +pci:v0000135Cd000000F0* + ID_PRODUCT_FROM_DATABASE=MPAC-100 Syncronous Serial Card (Zilog 85230) + +pci:v0000135Cd00000170* + ID_PRODUCT_FROM_DATABASE=QSCLP-100 + +pci:v0000135Cd00000180* + ID_PRODUCT_FROM_DATABASE=DSCLP-100 + +pci:v0000135Cd00000190* + ID_PRODUCT_FROM_DATABASE=SSCLP-100 + +pci:v0000135Cd000001A0* + ID_PRODUCT_FROM_DATABASE=QSCLP-200/300 + +pci:v0000135Cd000001B0* + ID_PRODUCT_FROM_DATABASE=DSCLP-200/300 + +pci:v0000135Cd000001C0* + ID_PRODUCT_FROM_DATABASE=SSCLP-200/300 + +pci:v0000135Cd00000258* + ID_PRODUCT_FROM_DATABASE=DSPSX-200/300 + +pci:v0000135D* + ID_VENDOR_FROM_DATABASE=ABB Network Partner AB + +pci:v0000135E* + ID_VENDOR_FROM_DATABASE=Sealevel Systems Inc + +pci:v0000135Ed00005101* + ID_PRODUCT_FROM_DATABASE=Route 56.PCI - Multi-Protocol Serial Interface (Zilog Z16C32) + +pci:v0000135Ed00007101* + ID_PRODUCT_FROM_DATABASE=Single Port RS-232/422/485/530 + +pci:v0000135Ed00007201* + ID_PRODUCT_FROM_DATABASE=Dual Port RS-232/422/485 Interface + +pci:v0000135Ed00007202* + ID_PRODUCT_FROM_DATABASE=Dual Port RS-232 Interface + +pci:v0000135Ed00007401* + ID_PRODUCT_FROM_DATABASE=Four Port RS-232 Interface + +pci:v0000135Ed00007402* + ID_PRODUCT_FROM_DATABASE=Four Port RS-422/485 Interface + +pci:v0000135Ed00007801* + ID_PRODUCT_FROM_DATABASE=Eight Port RS-232 Interface + +pci:v0000135Ed00007804* + ID_PRODUCT_FROM_DATABASE=Eight Port RS-232/422/485 Interface + +pci:v0000135Ed00008001* + ID_PRODUCT_FROM_DATABASE=8001 Digital I/O Adapter + +pci:v0000135F* + ID_VENDOR_FROM_DATABASE=I-Data International A-S + +pci:v00001360* + ID_VENDOR_FROM_DATABASE=Meinberg Funkuhren + +pci:v00001360d00000101* + ID_PRODUCT_FROM_DATABASE=PCI32 DCF77 Radio Clock + +pci:v00001360d00000102* + ID_PRODUCT_FROM_DATABASE=PCI509 DCF77 Radio Clock + +pci:v00001360d00000103* + ID_PRODUCT_FROM_DATABASE=PCI510 DCF77 Radio Clock + +pci:v00001360d00000104* + ID_PRODUCT_FROM_DATABASE=PCI511 DCF77 Radio Clock + +pci:v00001360d00000105* + ID_PRODUCT_FROM_DATABASE=PEX511 DCF77 Radio Clock (PCI Express) + +pci:v00001360d00000106* + ID_PRODUCT_FROM_DATABASE=PZF180PEX High Precision DCF77 Radio Clock (PCI Express) + +pci:v00001360d00000201* + ID_PRODUCT_FROM_DATABASE=GPS167PCI GPS Receiver + +pci:v00001360d00000202* + ID_PRODUCT_FROM_DATABASE=GPS168PCI GPS Receiver + +pci:v00001360d00000203* + ID_PRODUCT_FROM_DATABASE=GPS169PCI GPS Receiver + +pci:v00001360d00000204* + ID_PRODUCT_FROM_DATABASE=GPS170PCI GPS Receiver + +pci:v00001360d00000205* + ID_PRODUCT_FROM_DATABASE=GPS170PEX GPS Receiver (PCI Express) + +pci:v00001360d00000206* + ID_PRODUCT_FROM_DATABASE=GPS180PEX GPS Receiver (PCI Express) + +pci:v00001360d00000301* + ID_PRODUCT_FROM_DATABASE=TCR510PCI IRIG Timecode Reader + +pci:v00001360d00000302* + ID_PRODUCT_FROM_DATABASE=TCR167PCI IRIG Timecode Reader + +pci:v00001360d00000303* + ID_PRODUCT_FROM_DATABASE=TCR511PCI IRIG Timecode Reader + +pci:v00001360d00000304* + ID_PRODUCT_FROM_DATABASE=TCR511PEX IRIG Timecode Reader (PCI Express) + +pci:v00001360d00000305* + ID_PRODUCT_FROM_DATABASE=TCR170PEX IRIG Timecode Reader (PCI Express) + +pci:v00001360d00000306* + ID_PRODUCT_FROM_DATABASE=TCR180PEX IRIG Timecode Reader (PCI Express) + +pci:v00001360d00000501* + ID_PRODUCT_FROM_DATABASE=PTP270PEX PTP/IEEE1588 slave card (PCI Express) + +pci:v00001360d00000601* + ID_PRODUCT_FROM_DATABASE=FRC511PEX Free Running Clock (PCI Express) + +pci:v00001361* + ID_VENDOR_FROM_DATABASE=Soliton Systems K.K. + +pci:v00001362* + ID_VENDOR_FROM_DATABASE=Fujifacom Corporation + +pci:v00001363* + ID_VENDOR_FROM_DATABASE=Phoenix Technology Ltd + +pci:v00001364* + ID_VENDOR_FROM_DATABASE=ATM Communications Inc + +pci:v00001365* + ID_VENDOR_FROM_DATABASE=Hypercope GmbH + +pci:v00001366* + ID_VENDOR_FROM_DATABASE=Teijin Seiki Co. Ltd + +pci:v00001367* + ID_VENDOR_FROM_DATABASE=Hitachi Zosen Corporation + +pci:v00001368* + ID_VENDOR_FROM_DATABASE=Skyware Corporation + +pci:v00001369* + ID_VENDOR_FROM_DATABASE=Digigram + +pci:v0000136A* + ID_VENDOR_FROM_DATABASE=High Soft Tech + +pci:v0000136Ad00000004* + ID_PRODUCT_FROM_DATABASE=HST Saphir VII mini PCI + +pci:v0000136Ad00000007* + ID_PRODUCT_FROM_DATABASE=HST Saphir III E MultiLink 4 + +pci:v0000136Ad00000008* + ID_PRODUCT_FROM_DATABASE=HST Saphir III E MultiLink 8 + +pci:v0000136Ad0000000A* + ID_PRODUCT_FROM_DATABASE=HST Saphir III E MultiLink 2 + +pci:v0000136B* + ID_VENDOR_FROM_DATABASE=Kawasaki Steel Corporation + +pci:v0000136Bd0000FF01* + ID_PRODUCT_FROM_DATABASE=KL5A72002 Motion JPEG + +pci:v0000136C* + ID_VENDOR_FROM_DATABASE=Adtek System Science Co Ltd + +pci:v0000136D* + ID_VENDOR_FROM_DATABASE=Gigalabs Inc + +pci:v0000136F* + ID_VENDOR_FROM_DATABASE=Applied Magic Inc + +pci:v00001370* + ID_VENDOR_FROM_DATABASE=ATL Products + +pci:v00001371* + ID_VENDOR_FROM_DATABASE=CNet Technology Inc + +pci:v00001371d0000434E* + ID_PRODUCT_FROM_DATABASE=GigaCard Network Adapter + +pci:v00001371d0000434Esv00001371sd0000434E* + ID_PRODUCT_FROM_DATABASE=N-Way PCI-Bus Giga-Card 1000/100/10Mbps(L) + +pci:v00001373* + ID_VENDOR_FROM_DATABASE=Silicon Vision Inc + +pci:v00001374* + ID_VENDOR_FROM_DATABASE=Silicom Ltd. + +pci:v00001374d00000024* + ID_PRODUCT_FROM_DATABASE=Silicom Dual port Giga Ethernet BGE Bypass Server Adapter + +pci:v00001374d00000025* + ID_PRODUCT_FROM_DATABASE=Silicom Quad port Giga Ethernet BGE Bypass Server Adapter + +pci:v00001374d00000026* + ID_PRODUCT_FROM_DATABASE=Silicom Dual port Fiber Giga Ethernet 546 Bypass Server Adapter + +pci:v00001374d00000027* + ID_PRODUCT_FROM_DATABASE=Silicom Dual port Fiber LX Giga Ethernet 546 Bypass Server Adapter + +pci:v00001374d00000029* + ID_PRODUCT_FROM_DATABASE=Silicom Dual port Copper Giga Ethernet 546GB Bypass Server Adapter + +pci:v00001374d0000002A* + ID_PRODUCT_FROM_DATABASE=Silicom Dual port Fiber Giga Ethernet 546 TAP/Bypass Server Adapter + +pci:v00001374d0000002B* + ID_PRODUCT_FROM_DATABASE=Silicom Dual port Copper Fast Ethernet 546 TAP/Bypass Server Adapter (PXE2TBI) + +pci:v00001374d0000002C* + ID_PRODUCT_FROM_DATABASE=Silicom Quad port Copper Giga Ethernet 546GB Bypass Server Adapter (PXG4BPI) + +pci:v00001374d0000002D* + ID_PRODUCT_FROM_DATABASE=Silicom Quad port Fiber-SX Giga Ethernet 546GB Bypass Server Adapter (PXG4BPFI) + +pci:v00001374d0000002E* + ID_PRODUCT_FROM_DATABASE=Silicom Quad port Fiber-LX Giga Ethernet 546GB Bypass Server Adapter (PXG4BPFI-LX) + +pci:v00001374d0000002F* + ID_PRODUCT_FROM_DATABASE=Silicom Dual port Fiber-SX Giga Ethernet 546GB Low profile Bypass Server Adapter (PXG2BPFIL) + +pci:v00001374d00000030* + ID_PRODUCT_FROM_DATABASE=Silicom Dual port Fiber-LX Giga Ethernet 546GB Low profile Bypass Server Adapter + +pci:v00001374d00000031* + ID_PRODUCT_FROM_DATABASE=Silicom Quad port Copper Giga Ethernet PCI-E Bypass Server Adapter + +pci:v00001374d00000032* + ID_PRODUCT_FROM_DATABASE=Silicom Dual port Copper Fast Ethernet 546 TAP/Bypass Server Adapter + +pci:v00001374d00000034* + ID_PRODUCT_FROM_DATABASE=Silicom Dual port Copper Giga Ethernet PCI-E BGE Bypass Server Adapter + +pci:v00001374d00000035* + ID_PRODUCT_FROM_DATABASE=Silicom Quad port Copper Giga Ethernet PCI-E BGE Bypass Server Adapter + +pci:v00001374d00000036* + ID_PRODUCT_FROM_DATABASE=Silicom Dual port Fiber Giga Ethernet PCI-E BGE Bypass Server Adapter + +pci:v00001374d00000037* + ID_PRODUCT_FROM_DATABASE=Silicom Dual port Copper Ethernet PCI-E Intel based Bypass Server Adapter + +pci:v00001374d00000038* + ID_PRODUCT_FROM_DATABASE=Silicom Quad port Copper Ethernet PCI-E Intel based Bypass Server Adapter + +pci:v00001374d00000039* + ID_PRODUCT_FROM_DATABASE=Silicom Dual port Fiber-SX Ethernet PCI-E Intel based Bypass Server Adapter + +pci:v00001374d0000003A* + ID_PRODUCT_FROM_DATABASE=Silicom Dual port Fiber-LX Ethernet PCI-E Intel based Bypass Server Adapter + +pci:v00001374d0000003B* + ID_PRODUCT_FROM_DATABASE=Silicom Dual port Fiber Ethernet PMC Intel based Bypass Server Adapter (PMCX2BPFI) + +pci:v00001374d0000003C* + ID_PRODUCT_FROM_DATABASE=Silicom Dual port Copper Ethernet PCI-X BGE based Bypass Server Adapter (PXG2BPRB) + +pci:v00001374d0000003D* + ID_PRODUCT_FROM_DATABASE=2-port Copper GBE Bypass with Caviume 1010 PCI-X + +pci:v00001374d0000003E* + ID_PRODUCT_FROM_DATABASE=Silicom Dual port Fiber Giga Ethernet PCI-E 571 TAP/Bypass Server Adapter (PEG2TBFI) + +pci:v00001374d0000003F* + ID_PRODUCT_FROM_DATABASE=Silicom Dual port Copper Giga Ethernet PCI-X 546 TAP/Bypass Server Adapter (PXG2TBI) + +pci:v00001374d00000040* + ID_PRODUCT_FROM_DATABASE=Silicom Quad port Fiber-SX Giga Ethernet 571 Bypass Server Adapter (PEG4BPFI) + +pci:v00001374d00000042* + ID_PRODUCT_FROM_DATABASE=4-port Copper GBE PMC-X Bypass + +pci:v00001374d00000043* + ID_PRODUCT_FROM_DATABASE=Silicom Quad port Fiber-SX Giga Ethernet 546 Bypass Server Adapter (PXG4BPFID) + +pci:v00001374d00000045* + ID_PRODUCT_FROM_DATABASE=Silicom 6 port Copper Giga Ethernet 546 Bypass Server Adapter (PXG6BPI) + +pci:v00001374d00000046* + ID_PRODUCT_FROM_DATABASE=4-port bypass PCI-E w disconnect low profile + +pci:v00001374d00000047* + ID_PRODUCT_FROM_DATABASE=Silicom Dual port Fiber-SX Giga Ethernet 571 Bypass Disconnect Server Adapter (PEG2BPFID) + +pci:v00001374d0000004A* + ID_PRODUCT_FROM_DATABASE=Silicom Quad port Fiber-LX Giga Ethernet 571 Bypass Server Adapter (PEG4BPFI-LX) + +pci:v00001374d0000004D* + ID_PRODUCT_FROM_DATABASE=Dual port Copper Giga Ethernet PCI-E Bypass Server Adapter + +pci:v00001374d00000401* + ID_PRODUCT_FROM_DATABASE=Gigabit Ethernet ExpressModule Bypass Server Adapter + +pci:v00001374d00000420* + ID_PRODUCT_FROM_DATABASE=Gigabit Ethernet ExpressModule Bypass Server Adapter + +pci:v00001374d00000460* + ID_PRODUCT_FROM_DATABASE=Gigabit Ethernet Express Module Bypass Server Adapter + +pci:v00001374d00000461* + ID_PRODUCT_FROM_DATABASE=Gigabit Ethernet ExpressModule Bypass Server Adapter + +pci:v00001374d00000462* + ID_PRODUCT_FROM_DATABASE=Gigabit Ethernet ExpressModule Bypass Server Adapter + +pci:v00001374d00000470* + ID_PRODUCT_FROM_DATABASE=Octal-port Copper Gigabit Ethernet Express Module Bypass Server Adapter + +pci:v00001374d00000482* + ID_PRODUCT_FROM_DATABASE=Dual-port Fiber (SR) 10 Gigabit Ethernet ExpressModule Bypass Server Adapter + +pci:v00001374d00000483* + ID_PRODUCT_FROM_DATABASE=Dual-port Fiber (LR) 10 Gigabit Ethernet ExpressModule Bypass Server Adapter + +pci:v00001375* + ID_VENDOR_FROM_DATABASE=Argosystems Inc + +pci:v00001376* + ID_VENDOR_FROM_DATABASE=LMC + +pci:v00001377* + ID_VENDOR_FROM_DATABASE=Electronic Equipment Production & Distribution GmbH + +pci:v00001378* + ID_VENDOR_FROM_DATABASE=Telemann Co. Ltd + +pci:v00001379* + ID_VENDOR_FROM_DATABASE=Asahi Kasei Microsystems Co Ltd + +pci:v0000137A* + ID_VENDOR_FROM_DATABASE=Mark of the Unicorn Inc + +pci:v0000137Ad00000001* + ID_PRODUCT_FROM_DATABASE=PCI-324 Audiowire Interface + +pci:v0000137B* + ID_VENDOR_FROM_DATABASE=PPT Vision + +pci:v0000137C* + ID_VENDOR_FROM_DATABASE=Iwatsu Electric Co Ltd + +pci:v0000137D* + ID_VENDOR_FROM_DATABASE=Dynachip Corporation + +pci:v0000137E* + ID_VENDOR_FROM_DATABASE=Patriot Scientific Corporation + +pci:v0000137F* + ID_VENDOR_FROM_DATABASE=Japan Satellite Systems Inc + +pci:v00001380* + ID_VENDOR_FROM_DATABASE=Sanritz Automation Co Ltd + +pci:v00001381* + ID_VENDOR_FROM_DATABASE=Brains Co. Ltd + +pci:v00001382* + ID_VENDOR_FROM_DATABASE=Marian - Electronic & Software + +pci:v00001382d00000001* + ID_PRODUCT_FROM_DATABASE=ARC88 audio recording card + +pci:v00001382d00002008* + ID_PRODUCT_FROM_DATABASE=Prodif 96 Pro sound system + +pci:v00001382d00002048* + ID_PRODUCT_FROM_DATABASE=Prodif Plus sound system + +pci:v00001382d00002088* + ID_PRODUCT_FROM_DATABASE=Marc 8 Midi sound system + +pci:v00001382d000020C8* + ID_PRODUCT_FROM_DATABASE=Marc A sound system + +pci:v00001382d00004008* + ID_PRODUCT_FROM_DATABASE=Marc 2 sound system + +pci:v00001382d00004010* + ID_PRODUCT_FROM_DATABASE=Marc 2 Pro sound system + +pci:v00001382d00004048* + ID_PRODUCT_FROM_DATABASE=Marc 4 MIDI sound system + +pci:v00001382d00004088* + ID_PRODUCT_FROM_DATABASE=Marc 4 Digi sound system + +pci:v00001382d00004248* + ID_PRODUCT_FROM_DATABASE=Marc X sound system + +pci:v00001382d00004424* + ID_PRODUCT_FROM_DATABASE=TRACE D4 Sound System + +pci:v00001383* + ID_VENDOR_FROM_DATABASE=Controlnet Inc + +pci:v00001384* + ID_VENDOR_FROM_DATABASE=Reality Simulation Systems Inc + +pci:v00001385* + ID_VENDOR_FROM_DATABASE=Netgear + +pci:v00001385d0000006B* + ID_PRODUCT_FROM_DATABASE=WA301 802.11b Wireless PCI Adapter + +pci:v00001385d00004100* + ID_PRODUCT_FROM_DATABASE=MA301 802.11b Wireless PCI Adapter + +pci:v00001385d00004105* + ID_PRODUCT_FROM_DATABASE=MA311 802.11b Wireless PCI Adapter + +pci:v00001385d00004400* + ID_PRODUCT_FROM_DATABASE=WAG511 802.11a/b/g Dual Band Wireless PC Card + +pci:v00001385d00004600* + ID_PRODUCT_FROM_DATABASE=WAG511 802.11a/b/g Dual Band Wireless PC Card + +pci:v00001385d00004601* + ID_PRODUCT_FROM_DATABASE=WAG511 802.11a/b/g Dual Band Wireless PC Card + +pci:v00001385d00004610* + ID_PRODUCT_FROM_DATABASE=WAG511 802.11a/b/g Dual Band Wireless PC Card + +pci:v00001385d00004A00* + ID_PRODUCT_FROM_DATABASE=WAG311 802.11a/g Wireless PCI Adapter + +pci:v00001385d00005200* + ID_PRODUCT_FROM_DATABASE=GA511 Gigabit PC Card + +pci:v00001385d0000620A* + ID_PRODUCT_FROM_DATABASE=GA620 Gigabit Ethernet + +pci:v00001385d0000630A* + ID_PRODUCT_FROM_DATABASE=GA630 Gigabit Ethernet + +pci:v00001385d00006D00* + ID_PRODUCT_FROM_DATABASE=WPNT511 RangeMax 240 Mbps Wireless PC Card + +pci:v00001385d00007B00* + ID_PRODUCT_FROM_DATABASE=WN511B RangeMax Next 270 Mbps Wireless PC Card + +pci:v00001385d00007C00* + ID_PRODUCT_FROM_DATABASE=WN511T RangeMax Next 300 Mbps Wireless PC Card + +pci:v00001385d0000F004* + ID_PRODUCT_FROM_DATABASE=FA310TX + +pci:v00001385d0000F312* + ID_PRODUCT_FROM_DATABASE=FA312 REV-A1 Fast Ethernet PCI Adapter + +pci:v00001386* + ID_VENDOR_FROM_DATABASE=Video Domain Technologies + +pci:v00001387* + ID_VENDOR_FROM_DATABASE=Systran Corp + +pci:v00001388* + ID_VENDOR_FROM_DATABASE=Hitachi Information Technology Co Ltd + +pci:v00001389* + ID_VENDOR_FROM_DATABASE=Applicom International + +pci:v00001389d00000001* + ID_PRODUCT_FROM_DATABASE=PCI1500PFB [Intelligent fieldbus adaptor] + +pci:v0000138A* + ID_VENDOR_FROM_DATABASE=Fusion Micromedia Corp + +pci:v0000138Ad0000003D* + ID_PRODUCT_FROM_DATABASE=VFS491 Validity Sensor + +pci:v0000138B* + ID_VENDOR_FROM_DATABASE=Tokimec Inc + +pci:v0000138C* + ID_VENDOR_FROM_DATABASE=Silicon Reality + +pci:v0000138D* + ID_VENDOR_FROM_DATABASE=Future Techno Designs pte Ltd + +pci:v0000138E* + ID_VENDOR_FROM_DATABASE=Basler GmbH + +pci:v0000138F* + ID_VENDOR_FROM_DATABASE=Patapsco Designs Inc + +pci:v00001390* + ID_VENDOR_FROM_DATABASE=Concept Development Inc + +pci:v00001391* + ID_VENDOR_FROM_DATABASE=Development Concepts Inc + +pci:v00001392* + ID_VENDOR_FROM_DATABASE=Medialight Inc + +pci:v00001393* + ID_VENDOR_FROM_DATABASE=Moxa Technologies Co Ltd + +pci:v00001393d00000001* + ID_PRODUCT_FROM_DATABASE=UC7000 Serial + +pci:v00001393d00001020* + ID_PRODUCT_FROM_DATABASE=CP102 (2-port RS-232 PCI) + +pci:v00001393d00001021* + ID_PRODUCT_FROM_DATABASE=CP102UL (2-port RS-232 Universal PCI) + +pci:v00001393d00001022* + ID_PRODUCT_FROM_DATABASE=CP102U (2-port RS-232 Universal PCI) + +pci:v00001393d00001023* + ID_PRODUCT_FROM_DATABASE=CP-102UF + +pci:v00001393d00001024* + ID_PRODUCT_FROM_DATABASE=CP-102E (2-port RS-232 Smart PCI Express Serial Board) + +pci:v00001393d00001025* + ID_PRODUCT_FROM_DATABASE=CP-102EL (2-port RS-232 Smart PCI Express Serial Board) + +pci:v00001393d00001040* + ID_PRODUCT_FROM_DATABASE=Smartio C104H/PCI + +pci:v00001393d00001041* + ID_PRODUCT_FROM_DATABASE=CP104U (4-port RS-232 Universal PCI) + +pci:v00001393d00001042* + ID_PRODUCT_FROM_DATABASE=CP104JU (4-port RS-232 Universal PCI) + +pci:v00001393d00001043* + ID_PRODUCT_FROM_DATABASE=CP104EL (4-port RS-232 Smart PCI Express) + +pci:v00001393d00001044* + ID_PRODUCT_FROM_DATABASE=POS104UL (4-port RS-232 Universal PCI) + +pci:v00001393d00001045* + ID_PRODUCT_FROM_DATABASE=CP-104EL-A (4-port RS-232 PCI Express Serial Board) + +pci:v00001393d00001080* + ID_PRODUCT_FROM_DATABASE=CB108 (8-port RS-232 PC/104-plus Module) + +pci:v00001393d00001140* + ID_PRODUCT_FROM_DATABASE=CT-114 series + +pci:v00001393d00001141* + ID_PRODUCT_FROM_DATABASE=Industrio CP-114 + +pci:v00001393d00001142* + ID_PRODUCT_FROM_DATABASE=CB114 (4-port RS-232/422/485 PC/104-plus Module) + +pci:v00001393d00001143* + ID_PRODUCT_FROM_DATABASE=CP-114UL (4-port RS-232/422/485 Smart Universal PCI Serial Board) + +pci:v00001393d00001144* + ID_PRODUCT_FROM_DATABASE=CP-114EL (4-port RS-232/422/485 Smart PCI Express Serial Board) + +pci:v00001393d00001180* + ID_PRODUCT_FROM_DATABASE=CP118U (8-port RS-232/422/485 Smart Universal PCI) + +pci:v00001393d00001181* + ID_PRODUCT_FROM_DATABASE=CP118EL (8-port RS-232/422/485 Smart PCI Express) + +pci:v00001393d00001182* + ID_PRODUCT_FROM_DATABASE=CP-118EL-A (8-port RS-232/422/485 PCI Express Serial Board) + +pci:v00001393d00001320* + ID_PRODUCT_FROM_DATABASE=CP132 (2-port RS-422/485 PCI) + +pci:v00001393d00001321* + ID_PRODUCT_FROM_DATABASE=CP132U (2-Port RS-422/485 Universal PCI) + +pci:v00001393d00001322* + ID_PRODUCT_FROM_DATABASE=CP-132EL (2-port RS-422/485 Smart PCI Express Serial Board) + +pci:v00001393d00001340* + ID_PRODUCT_FROM_DATABASE=CP134U (4-Port RS-422/485 Universal PCI) + +pci:v00001393d00001341* + ID_PRODUCT_FROM_DATABASE=CB134I (4-port RS-422/485 PC/104-plus Module) + +pci:v00001393d00001380* + ID_PRODUCT_FROM_DATABASE=CP138U (8-port RS-232/422/485 Smart Universal PCI) + +pci:v00001393d00001680* + ID_PRODUCT_FROM_DATABASE=Smartio C168H/PCI + +pci:v00001393d00001681* + ID_PRODUCT_FROM_DATABASE=CP-168U V2 Smart Serial Board (8-port RS-232) + +pci:v00001393d00001682* + ID_PRODUCT_FROM_DATABASE=CP168EL (8-port RS-232 Smart PCI Express) + +pci:v00001393d00001683* + ID_PRODUCT_FROM_DATABASE=CP-168EL-A (8-port RS-232 PCI Express Serial Board) + +pci:v00001393d00002040* + ID_PRODUCT_FROM_DATABASE=Intellio CP-204J + +pci:v00001393d00002180* + ID_PRODUCT_FROM_DATABASE=Intellio C218 Turbo PCI + +pci:v00001393d00003200* + ID_PRODUCT_FROM_DATABASE=Intellio C320 Turbo PCI + +pci:v00001394* + ID_VENDOR_FROM_DATABASE=Level One Communications + +pci:v00001394d00000001* + ID_PRODUCT_FROM_DATABASE=LXT1001 Gigabit Ethernet + +pci:v00001394d00000001sv00001186sd00004800* + ID_PRODUCT_FROM_DATABASE=DGE-500SX + +pci:v00001394d00000001sv00001394sd00000001* + ID_PRODUCT_FROM_DATABASE=NetCelerator Adapter + +pci:v00001395* + ID_VENDOR_FROM_DATABASE=Ambicom Inc + +pci:v00001396* + ID_VENDOR_FROM_DATABASE=Cipher Systems Inc + +pci:v00001397* + ID_VENDOR_FROM_DATABASE=Cologne Chip Designs GmbH + +pci:v00001397d000008B4* + ID_PRODUCT_FROM_DATABASE=ISDN network Controller [HFC-4S] + +pci:v00001397d000008B4sv00001397sd0000B520* + ID_PRODUCT_FROM_DATABASE=HFC-4S [IOB4ST] + +pci:v00001397d000008B4sv00001397sd0000B540* + ID_PRODUCT_FROM_DATABASE=HFC-4S [Swyx 4xS0 SX2 QuadBri] + +pci:v00001397d000008B4sv00001397sd0000B550* + ID_PRODUCT_FROM_DATABASE=HFC-4S [Junghanns quadBRI] + +pci:v00001397d000008B4sv00001397sd0000B556* + ID_PRODUCT_FROM_DATABASE=HFC-4S [Junghanns DuoDBRI] + +pci:v00001397d000008B4sv00001397sd0000E888* + ID_PRODUCT_FROM_DATABASE=HFC-4S [OpenVox B200P / B400P] + +pci:v00001397d000016B8* + ID_PRODUCT_FROM_DATABASE=ISDN network Controller [HFC-8S] + +pci:v00001397d000016B8sv00001397sd0000B562* + ID_PRODUCT_FROM_DATABASE=HFC-8S [IOB8ST] + +pci:v00001397d00002BD0* + ID_PRODUCT_FROM_DATABASE=ISDN network controller [HFC-PCI] + +pci:v00001397d00002BD0sv00000675sd00001704* + ID_PRODUCT_FROM_DATABASE=ISDN Adapter (PCI Bus, D, C) + +pci:v00001397d00002BD0sv00000675sd00001708* + ID_PRODUCT_FROM_DATABASE=ISDN Adapter (PCI Bus, D, C, ACPI) + +pci:v00001397d00002BD0sv00001397sd00002BD0* + ID_PRODUCT_FROM_DATABASE=ISDN Board + +pci:v00001397d00002BD0sv0000E4BFsd00001000* + ID_PRODUCT_FROM_DATABASE=CI1-1-Harp + +pci:v00001397d000030B1* + ID_PRODUCT_FROM_DATABASE=ISDN network Controller [HFC-E1] + +pci:v00001397d0000B700* + ID_PRODUCT_FROM_DATABASE=ISDN network controller PrimuX S0 [HFC-PCI] + +pci:v00001397d0000F001* + ID_PRODUCT_FROM_DATABASE=GSM Network Controller [HFC-4GSM] + +pci:v00001398* + ID_VENDOR_FROM_DATABASE=Clarion co. Ltd + +pci:v00001399* + ID_VENDOR_FROM_DATABASE=Rios systems Co Ltd + +pci:v0000139A* + ID_VENDOR_FROM_DATABASE=Alacritech Inc + +pci:v0000139Ad00000001* + ID_PRODUCT_FROM_DATABASE=Quad Port 10/100 Server Accelerator + +pci:v0000139Ad00000003* + ID_PRODUCT_FROM_DATABASE=Single Port 10/100 Server Accelerator + +pci:v0000139Ad00000005* + ID_PRODUCT_FROM_DATABASE=Single Port Gigabit Server Accelerator + +pci:v0000139B* + ID_VENDOR_FROM_DATABASE=Mediasonic Multimedia Systems Ltd + +pci:v0000139C* + ID_VENDOR_FROM_DATABASE=Quantum 3d Inc + +pci:v0000139D* + ID_VENDOR_FROM_DATABASE=EPL limited + +pci:v0000139E* + ID_VENDOR_FROM_DATABASE=Media4 + +pci:v0000139F* + ID_VENDOR_FROM_DATABASE=Aethra s.r.l. + +pci:v000013A0* + ID_VENDOR_FROM_DATABASE=Crystal Group Inc + +pci:v000013A1* + ID_VENDOR_FROM_DATABASE=Kawasaki Heavy Industries Ltd + +pci:v000013A2* + ID_VENDOR_FROM_DATABASE=Ositech Communications Inc + +pci:v000013A3* + ID_VENDOR_FROM_DATABASE=Hifn Inc. + +pci:v000013A3d00000005* + ID_PRODUCT_FROM_DATABASE=7751 Security Processor + +pci:v000013A3d00000006* + ID_PRODUCT_FROM_DATABASE=6500 Public Key Processor + +pci:v000013A3d00000007* + ID_PRODUCT_FROM_DATABASE=7811 Security Processor + +pci:v000013A3d00000012* + ID_PRODUCT_FROM_DATABASE=7951 Security Processor + +pci:v000013A3d00000014* + ID_PRODUCT_FROM_DATABASE=78XX Security Processor + +pci:v000013A3d00000016* + ID_PRODUCT_FROM_DATABASE=8065 Security Processor + +pci:v000013A3d00000017* + ID_PRODUCT_FROM_DATABASE=8165 Security Processor + +pci:v000013A3d00000018* + ID_PRODUCT_FROM_DATABASE=8154 Security Processor + +pci:v000013A3d0000001D* + ID_PRODUCT_FROM_DATABASE=7956 Security Processor + +pci:v000013A3d0000001F* + ID_PRODUCT_FROM_DATABASE=7855 Security Processor + +pci:v000013A3d00000020* + ID_PRODUCT_FROM_DATABASE=7955 Security Processor + +pci:v000013A3d00000026* + ID_PRODUCT_FROM_DATABASE=8155 Security Processor + +pci:v000013A3d0000002E* + ID_PRODUCT_FROM_DATABASE=9630 Compression Processor + +pci:v000013A3d0000002F* + ID_PRODUCT_FROM_DATABASE=9725 Compression and Security Processor + +pci:v000013A3d0000002Fsv000013A3sd00001600* + ID_PRODUCT_FROM_DATABASE=DR1600 Acceleration Card + +pci:v000013A3d0000002Fsv000013A3sd00001605* + ID_PRODUCT_FROM_DATABASE=DR1605 Acceleration Card + +pci:v000013A3d0000002Fsv000013A3sd00001610* + ID_PRODUCT_FROM_DATABASE=DR1610 Acceleration Card + +pci:v000013A3d0000002Fsv000013A3sd00001615* + ID_PRODUCT_FROM_DATABASE=DR1615 Acceleration Card + +pci:v000013A3d0000002Fsv000013A3sd00001620* + ID_PRODUCT_FROM_DATABASE=DR1620 Acceleration Card + +pci:v000013A3d0000002Fsv000013A3sd00001625* + ID_PRODUCT_FROM_DATABASE=DR1625 Acceleration Card + +pci:v000013A3d00000033* + ID_PRODUCT_FROM_DATABASE=8201 Acceleration Processor + +pci:v000013A3d00000033sv000013A3sd00000036* + ID_PRODUCT_FROM_DATABASE=DX1710 Acceleration Card + +pci:v000013A3d00000034* + ID_PRODUCT_FROM_DATABASE=8202 Acceleration Processor + +pci:v000013A3d00000034sv000013A3sd00000036* + ID_PRODUCT_FROM_DATABASE=DX1720 Acceleration Card + +pci:v000013A3d00000035* + ID_PRODUCT_FROM_DATABASE=8203 Acceleration Processor + +pci:v000013A3d00000035sv000013A3sd00000036* + ID_PRODUCT_FROM_DATABASE=DX1730 Acceleration Card + +pci:v000013A3d00000037* + ID_PRODUCT_FROM_DATABASE=8204 Acceleration Processor + +pci:v000013A3d00000037sv000013A3sd00000036* + ID_PRODUCT_FROM_DATABASE=DX1740 Acceleration Card + +pci:v000013A4* + ID_VENDOR_FROM_DATABASE=Rascom Inc + +pci:v000013A5* + ID_VENDOR_FROM_DATABASE=Audio Digital Imaging Inc + +pci:v000013A6* + ID_VENDOR_FROM_DATABASE=Videonics Inc + +pci:v000013A7* + ID_VENDOR_FROM_DATABASE=Teles AG + +pci:v000013A8* + ID_VENDOR_FROM_DATABASE=Exar Corp. + +pci:v000013A8d00000152* + ID_PRODUCT_FROM_DATABASE=XR17C/D152 Dual PCI UART + +pci:v000013A8d00000154* + ID_PRODUCT_FROM_DATABASE=XR17C154 Quad UART + +pci:v000013A8d00000158* + ID_PRODUCT_FROM_DATABASE=XR17C158 Octal UART + +pci:v000013A8d00000252* + ID_PRODUCT_FROM_DATABASE=XR17V252 Dual UART PCI controller + +pci:v000013A8d00000254* + ID_PRODUCT_FROM_DATABASE=XR17V254 Quad UART PCI controller + +pci:v000013A8d00000258* + ID_PRODUCT_FROM_DATABASE=XR17V258 Octal UART PCI controller + +pci:v000013A9* + ID_VENDOR_FROM_DATABASE=Siemens Medical Systems, Ultrasound Group + +pci:v000013AA* + ID_VENDOR_FROM_DATABASE=Broadband Networks Inc + +pci:v000013AB* + ID_VENDOR_FROM_DATABASE=Arcom Control Systems Ltd + +pci:v000013AC* + ID_VENDOR_FROM_DATABASE=Motion Media Technology Ltd + +pci:v000013AD* + ID_VENDOR_FROM_DATABASE=Nexus Inc + +pci:v000013AE* + ID_VENDOR_FROM_DATABASE=ALD Technology Ltd + +pci:v000013AF* + ID_VENDOR_FROM_DATABASE=T.Sqware + +pci:v000013B0* + ID_VENDOR_FROM_DATABASE=Maxspeed Corp + +pci:v000013B1* + ID_VENDOR_FROM_DATABASE=Tamura corporation + +pci:v000013B2* + ID_VENDOR_FROM_DATABASE=Techno Chips Co. Ltd + +pci:v000013B3* + ID_VENDOR_FROM_DATABASE=Lanart Corporation + +pci:v000013B4* + ID_VENDOR_FROM_DATABASE=Wellbean Co Inc + +pci:v000013B5* + ID_VENDOR_FROM_DATABASE=ARM + +pci:v000013B6* + ID_VENDOR_FROM_DATABASE=Dlog GmbH + +pci:v000013B7* + ID_VENDOR_FROM_DATABASE=Logic Devices Inc + +pci:v000013B8* + ID_VENDOR_FROM_DATABASE=Nokia Telecommunications oy + +pci:v000013B9* + ID_VENDOR_FROM_DATABASE=Elecom Co Ltd + +pci:v000013BA* + ID_VENDOR_FROM_DATABASE=Oxford Instruments + +pci:v000013BB* + ID_VENDOR_FROM_DATABASE=Sanyo Technosound Co Ltd + +pci:v000013BC* + ID_VENDOR_FROM_DATABASE=Bitran Corporation + +pci:v000013BD* + ID_VENDOR_FROM_DATABASE=Sharp corporation + +pci:v000013BE* + ID_VENDOR_FROM_DATABASE=Miroku Jyoho Service Co. Ltd + +pci:v000013BF* + ID_VENDOR_FROM_DATABASE=Sharewave Inc + +pci:v000013C0* + ID_VENDOR_FROM_DATABASE=Microgate Corporation + +pci:v000013C0d00000010* + ID_PRODUCT_FROM_DATABASE=SyncLink Adapter v1 + +pci:v000013C0d00000020* + ID_PRODUCT_FROM_DATABASE=SyncLink SCC Adapter + +pci:v000013C0d00000030* + ID_PRODUCT_FROM_DATABASE=SyncLink Multiport Adapter + +pci:v000013C0d00000070* + ID_PRODUCT_FROM_DATABASE=SyncLink GT Adapter + +pci:v000013C0d00000080* + ID_PRODUCT_FROM_DATABASE=SyncLink GT4 Adapter + +pci:v000013C0d000000A0* + ID_PRODUCT_FROM_DATABASE=SyncLink GT2 Adapter + +pci:v000013C0d00000210* + ID_PRODUCT_FROM_DATABASE=SyncLink Adapter v2 + +pci:v000013C1* + ID_VENDOR_FROM_DATABASE=3ware Inc + +pci:v000013C1d00001000* + ID_PRODUCT_FROM_DATABASE=5xxx/6xxx-series PATA-RAID + +pci:v000013C1d00001001* + ID_PRODUCT_FROM_DATABASE=7xxx/8xxx-series PATA/SATA-RAID + +pci:v000013C1d00001001sv000013C1sd00001001* + ID_PRODUCT_FROM_DATABASE=7xxx/8xxx-series PATA/SATA-RAID + +pci:v000013C1d00001002* + ID_PRODUCT_FROM_DATABASE=9xxx-series SATA-RAID + +pci:v000013C1d00001003* + ID_PRODUCT_FROM_DATABASE=9550SX SATA-II RAID PCI-X + +pci:v000013C1d00001004* + ID_PRODUCT_FROM_DATABASE=9650SE SATA-II RAID PCIe + +pci:v000013C1d00001005* + ID_PRODUCT_FROM_DATABASE=9690SA SAS/SATA-II RAID PCIe + +pci:v000013C1d00001010* + ID_PRODUCT_FROM_DATABASE=9750 SAS2/SATA-II RAID PCIe + +pci:v000013C2* + ID_VENDOR_FROM_DATABASE=Technotrend Systemtechnik GmbH + +pci:v000013C2d0000000E* + ID_PRODUCT_FROM_DATABASE=Technotrend/Hauppauge DVB card rev2.3 + +pci:v000013C2d00001019* + ID_PRODUCT_FROM_DATABASE=TTechnoTrend-budget DVB S2-3200 + +pci:v000013C3* + ID_VENDOR_FROM_DATABASE=Janz Computer AG + +pci:v000013C4* + ID_VENDOR_FROM_DATABASE=Phase Metrics + +pci:v000013C5* + ID_VENDOR_FROM_DATABASE=Alphi Technology Corp + +pci:v000013C6* + ID_VENDOR_FROM_DATABASE=Condor Engineering Inc + +pci:v000013C6d00000520* + ID_PRODUCT_FROM_DATABASE=CEI-520 A429 Card + +pci:v000013C6d00000620* + ID_PRODUCT_FROM_DATABASE=CEI-620 A429 Card + +pci:v000013C6d00000820* + ID_PRODUCT_FROM_DATABASE=CEI-820 A429 Card + +pci:v000013C6d00000830* + ID_PRODUCT_FROM_DATABASE=CEI-830 A429 Card + +pci:v000013C6d00001004* + ID_PRODUCT_FROM_DATABASE=P-SER Multi-channel PMC to RS-485/422/232 adapter + +pci:v000013C7* + ID_VENDOR_FROM_DATABASE=Blue Chip Technology Ltd + +pci:v000013C7d00000ADC* + ID_PRODUCT_FROM_DATABASE=PCI-ADC + +pci:v000013C7d00000B10* + ID_PRODUCT_FROM_DATABASE=PCI-PIO + +pci:v000013C7d00000D10* + ID_PRODUCT_FROM_DATABASE=PCI-DIO + +pci:v000013C7d0000524C* + ID_PRODUCT_FROM_DATABASE=PCI-RLY + +pci:v000013C7d00005744* + ID_PRODUCT_FROM_DATABASE=PCI-WDT + +pci:v000013C8* + ID_VENDOR_FROM_DATABASE=Apptech Inc + +pci:v000013C9* + ID_VENDOR_FROM_DATABASE=Eaton Corporation + +pci:v000013CA* + ID_VENDOR_FROM_DATABASE=Iomega Corporation + +pci:v000013CB* + ID_VENDOR_FROM_DATABASE=Yano Electric Co Ltd + +pci:v000013CC* + ID_VENDOR_FROM_DATABASE=Metheus Corporation + +pci:v000013CD* + ID_VENDOR_FROM_DATABASE=Compatible Systems Corporation + +pci:v000013CE* + ID_VENDOR_FROM_DATABASE=Cocom A/S + +pci:v000013CF* + ID_VENDOR_FROM_DATABASE=Studio Audio & Video Ltd + +pci:v000013D0* + ID_VENDOR_FROM_DATABASE=Techsan Electronics Co Ltd + +pci:v000013D0d00002103* + ID_PRODUCT_FROM_DATABASE=B2C2 FlexCopII DVB chip / Technisat SkyStar2 DVB card + +pci:v000013D0d00002104* + ID_PRODUCT_FROM_DATABASE=B2C2 FlexCopIII DVB chip / Technisat SkyStar2 DVB card (rev 01) + +pci:v000013D0d00002200* + ID_PRODUCT_FROM_DATABASE=B2C2 FlexCopIII DVB chip / Technisat SkyStar2 DVB card + +pci:v000013D1* + ID_VENDOR_FROM_DATABASE=Abocom Systems Inc + +pci:v000013D1d0000AB02* + ID_PRODUCT_FROM_DATABASE=ADMtek Centaur-C rev 17 [D-Link DFE-680TX] CardBus Fast Ethernet Adapter + +pci:v000013D1d0000AB03* + ID_PRODUCT_FROM_DATABASE=21x4x DEC-Tulip compatible 10/100 Ethernet + +pci:v000013D1d0000AB06* + ID_PRODUCT_FROM_DATABASE=RTL8139 [FE2000VX] CardBus Fast Ethernet Attached Port Adapter + +pci:v000013D1d0000AB08* + ID_PRODUCT_FROM_DATABASE=21x4x DEC-Tulip compatible 10/100 Ethernet + +pci:v000013D2* + ID_VENDOR_FROM_DATABASE=Shark Multimedia Inc + +pci:v000013D4* + ID_VENDOR_FROM_DATABASE=Graphics Microsystems Inc + +pci:v000013D5* + ID_VENDOR_FROM_DATABASE=Media 100 Inc + +pci:v000013D6* + ID_VENDOR_FROM_DATABASE=K.I. Technology Co Ltd + +pci:v000013D7* + ID_VENDOR_FROM_DATABASE=Toshiba Engineering Corporation + +pci:v000013D8* + ID_VENDOR_FROM_DATABASE=Phobos corporation + +pci:v000013D9* + ID_VENDOR_FROM_DATABASE=Apex PC Solutions Inc + +pci:v000013DA* + ID_VENDOR_FROM_DATABASE=Intresource Systems pte Ltd + +pci:v000013DB* + ID_VENDOR_FROM_DATABASE=Janich & Klass Computertechnik GmbH + +pci:v000013DC* + ID_VENDOR_FROM_DATABASE=Netboost Corporation + +pci:v000013DD* + ID_VENDOR_FROM_DATABASE=Multimedia Bundle Inc + +pci:v000013DE* + ID_VENDOR_FROM_DATABASE=ABB Robotics Products AB + +pci:v000013DF* + ID_VENDOR_FROM_DATABASE=E-Tech Inc + +pci:v000013DFd00000001* + ID_PRODUCT_FROM_DATABASE=PCI56RVP Modem + +pci:v000013DFd00000001sv000013DFsd00000001* + ID_PRODUCT_FROM_DATABASE=PCI56RVP Modem + +pci:v000013E0* + ID_VENDOR_FROM_DATABASE=GVC Corporation + +pci:v000013E1* + ID_VENDOR_FROM_DATABASE=Silicom Multimedia Systems Inc + +pci:v000013E2* + ID_VENDOR_FROM_DATABASE=Dynamics Research Corporation + +pci:v000013E3* + ID_VENDOR_FROM_DATABASE=Nest Inc + +pci:v000013E4* + ID_VENDOR_FROM_DATABASE=Calculex Inc + +pci:v000013E5* + ID_VENDOR_FROM_DATABASE=Telesoft Design Ltd + +pci:v000013E6* + ID_VENDOR_FROM_DATABASE=Argosy research Inc + +pci:v000013E7* + ID_VENDOR_FROM_DATABASE=NAC Incorporated + +pci:v000013E8* + ID_VENDOR_FROM_DATABASE=Chip Express Corporation + +pci:v000013E9* + ID_VENDOR_FROM_DATABASE=Intraserver Technology Inc + +pci:v000013EA* + ID_VENDOR_FROM_DATABASE=Dallas Semiconductor + +pci:v000013EB* + ID_VENDOR_FROM_DATABASE=Hauppauge Computer Works Inc + +pci:v000013EC* + ID_VENDOR_FROM_DATABASE=Zydacron Inc + +pci:v000013ECd0000000A* + ID_PRODUCT_FROM_DATABASE=NPC-RC01 Remote control receiver + +pci:v000013ED* + ID_VENDOR_FROM_DATABASE=Raytheion E-Systems + +pci:v000013EE* + ID_VENDOR_FROM_DATABASE=Hayes Microcomputer Products Inc + +pci:v000013EF* + ID_VENDOR_FROM_DATABASE=Coppercom Inc + +pci:v000013F0* + ID_VENDOR_FROM_DATABASE=Sundance Technology Inc / IC Plus Corp + +pci:v000013F0d00000200* + ID_PRODUCT_FROM_DATABASE=IC Plus IP100A Integrated 10/100 Ethernet MAC + PHY + +pci:v000013F0d00000200sv00001043sd00008213* + ID_PRODUCT_FROM_DATABASE=NX1001 + +pci:v000013F0d00000201* + ID_PRODUCT_FROM_DATABASE=ST201 Sundance Ethernet + +pci:v000013F0d00001021* + ID_PRODUCT_FROM_DATABASE=TC902x Gigabit Ethernet + +pci:v000013F0d00001023* + ID_PRODUCT_FROM_DATABASE=IP1000 Family Gigabit Ethernet + +pci:v000013F0d00001023sv00001043sd00008180* + ID_PRODUCT_FROM_DATABASE=NX1101 + +pci:v000013F1* + ID_VENDOR_FROM_DATABASE=Oce' - Technologies B.V. + +pci:v000013F2* + ID_VENDOR_FROM_DATABASE=Ford Microelectronics Inc + +pci:v000013F3* + ID_VENDOR_FROM_DATABASE=Mcdata Corporation + +pci:v000013F4* + ID_VENDOR_FROM_DATABASE=Troika Networks, Inc. + +pci:v000013F4d00001401* + ID_PRODUCT_FROM_DATABASE=Zentai Fibre Channel Adapter + +pci:v000013F5* + ID_VENDOR_FROM_DATABASE=Kansai Electric Co. Ltd + +pci:v000013F6* + ID_VENDOR_FROM_DATABASE=C-Media Electronics Inc + +pci:v000013F6d00000011* + ID_PRODUCT_FROM_DATABASE=CMI8738 + +pci:v000013F6d00000100* + ID_PRODUCT_FROM_DATABASE=CM8338A + +pci:v000013F6d00000100sv000013F6sd0000FFFF* + ID_PRODUCT_FROM_DATABASE=CMI8338/C3DX PCI Audio Device + +pci:v000013F6d00000101* + ID_PRODUCT_FROM_DATABASE=CM8338B + +pci:v000013F6d00000101sv000013F6sd00000101* + ID_PRODUCT_FROM_DATABASE=CMI8338-031 PCI Audio Device + +pci:v000013F6d00000111* + ID_PRODUCT_FROM_DATABASE=CMI8738/CMI8768 PCI Audio + +pci:v000013F6d00000111sv00001019sd00000970* + ID_PRODUCT_FROM_DATABASE=P6STP-FL motherboard + +pci:v000013F6d00000111sv00001043sd00008035* + ID_PRODUCT_FROM_DATABASE=CUSI-FX motherboard + +pci:v000013F6d00000111sv00001043sd00008077* + ID_PRODUCT_FROM_DATABASE=CMI8738 6-channel audio controller + +pci:v000013F6d00000111sv00001043sd000080E2* + ID_PRODUCT_FROM_DATABASE=CMI8738 6ch-MX + +pci:v000013F6d00000111sv000013F6sd00000111* + ID_PRODUCT_FROM_DATABASE=CMI8738/C3DX PCI Audio Device + +pci:v000013F6d00000111sv000013F6sd00009761* + ID_PRODUCT_FROM_DATABASE=Theatron Agrippa + +pci:v000013F6d00000111sv0000153Bsd00001144* + ID_PRODUCT_FROM_DATABASE=Aureon 5.1 + +pci:v000013F6d00000111sv0000153Bsd00001170* + ID_PRODUCT_FROM_DATABASE=Aureon 7.1 + +pci:v000013F6d00000111sv00001681sd0000A000* + ID_PRODUCT_FROM_DATABASE=Gamesurround MUSE XL + +pci:v000013F6d00000111sv000017ABsd00000604* + ID_PRODUCT_FROM_DATABASE=PSC604 Dynamic Edge + +pci:v000013F6d00000111sv000017ABsd00000605* + ID_PRODUCT_FROM_DATABASE=PSC605 Sonic Edge + +pci:v000013F6d00000111sv000017ABsd00007777* + ID_PRODUCT_FROM_DATABASE=PSC605 Sonic Edge + +pci:v000013F6d00000111sv0000270Fsd00001103* + ID_PRODUCT_FROM_DATABASE=CT-7NJS Ultra motherboard + +pci:v000013F6d00000111sv0000270Fsd0000F462* + ID_PRODUCT_FROM_DATABASE=7NJL1 motherboard + +pci:v000013F6d00000111sv0000584Dsd00003731* + ID_PRODUCT_FROM_DATABASE=Digital X-Mystique + +pci:v000013F6d00000111sv0000584Dsd00003741* + ID_PRODUCT_FROM_DATABASE=X-Plosion 7.1 + +pci:v000013F6d00000111sv0000584Dsd00003751* + ID_PRODUCT_FROM_DATABASE=X-Raider 7.1 + +pci:v000013F6d00000111sv0000584Dsd00003761* + ID_PRODUCT_FROM_DATABASE=X-Mystique 7.1 LP + +pci:v000013F6d00000111sv0000584Dsd00003771* + ID_PRODUCT_FROM_DATABASE=X-Mystique 7.1 LP Value + +pci:v000013F6d00000111sv00007284sd00008384* + ID_PRODUCT_FROM_DATABASE=Striker 7.1 + +pci:v000013F6d00000211* + ID_PRODUCT_FROM_DATABASE=CM8738 + +pci:v000013F6d00005011* + ID_PRODUCT_FROM_DATABASE=CM8888 [Oxygen Express] + +pci:v000013F6d00005011sv000013F6sd00005011* + ID_PRODUCT_FROM_DATABASE=HDA Controller + +pci:v000013F6d00008788* + ID_PRODUCT_FROM_DATABASE=CMI8788 [Oxygen HD Audio] + +pci:v000013F6d00008788sv00001043sd00008269* + ID_PRODUCT_FROM_DATABASE=Virtuoso 200 (Xonar D2) + +pci:v000013F6d00008788sv00001043sd00008275* + ID_PRODUCT_FROM_DATABASE=Virtuoso 100 (Xonar DX) + +pci:v000013F6d00008788sv00001043sd000082B7* + ID_PRODUCT_FROM_DATABASE=Virtuoso 200 (Xonar D2X) + +pci:v000013F6d00008788sv00001043sd00008314* + ID_PRODUCT_FROM_DATABASE=Virtuoso 200 (Xonar HDAV1.3) + +pci:v000013F6d00008788sv00001043sd00008327* + ID_PRODUCT_FROM_DATABASE=Virtuoso 100 (Xonar DX) + +pci:v000013F6d00008788sv00001043sd0000834F* + ID_PRODUCT_FROM_DATABASE=Virtuoso 100 (Xonar D1) + +pci:v000013F6d00008788sv00001043sd0000835C* + ID_PRODUCT_FROM_DATABASE=Virtuoso 100 (Xonar Essence STX) + +pci:v000013F6d00008788sv00001043sd0000835D* + ID_PRODUCT_FROM_DATABASE=Virtuoso 100 (Xonar ST) + +pci:v000013F6d00008788sv00001043sd0000835E* + ID_PRODUCT_FROM_DATABASE=Virtuoso 200 (Xonar HDAV1.3 Slim) + +pci:v000013F6d00008788sv00001043sd0000838E* + ID_PRODUCT_FROM_DATABASE=Virtuoso 66 (Xonar DS) + +pci:v000013F6d00008788sv00001043sd00008428* + ID_PRODUCT_FROM_DATABASE=Virtuoso 100 (Xonar Xense) + +pci:v000013F6d00008788sv00001043sd00008467* + ID_PRODUCT_FROM_DATABASE=CMI8786 (Xonar DG) + +pci:v000013F6d00008788sv000013F6sd00008782* + ID_PRODUCT_FROM_DATABASE=PCI 2.0 HD Audio + +pci:v000013F6d00008788sv000013F6sd0000FFFF* + ID_PRODUCT_FROM_DATABASE=CMI8787-HG2PCI + +pci:v000013F6d00008788sv000014C3sd00001710* + ID_PRODUCT_FROM_DATABASE=HiFier Fantasia + +pci:v000013F6d00008788sv000014C3sd00001711* + ID_PRODUCT_FROM_DATABASE=HiFier Serenade + +pci:v000013F6d00008788sv00001A58sd00000910* + ID_PRODUCT_FROM_DATABASE=Barracuda AC-1 + +pci:v000013F6d00008788sv0000415Asd00005431* + ID_PRODUCT_FROM_DATABASE=X-Meridian 7.1 + +pci:v000013F6d00008788sv00005431sd0000017A* + ID_PRODUCT_FROM_DATABASE=X-Meridian 7.1 2G + +pci:v000013F6d00008788sv0000584Dsd00003781* + ID_PRODUCT_FROM_DATABASE=HDA X-Purity 7.1 Platinum + +pci:v000013F6d00008788sv00007284sd00009761* + ID_PRODUCT_FROM_DATABASE=CLARO + +pci:v000013F6d00008788sv00007284sd00009781* + ID_PRODUCT_FROM_DATABASE=CLARO halo + +pci:v000013F6d00008788sv00007284sd00009783* + ID_PRODUCT_FROM_DATABASE=eCLARO + +pci:v000013F6d00008788sv00007284sd00009787* + ID_PRODUCT_FROM_DATABASE=CLARO II + +pci:v000013F6d00009880* + ID_PRODUCT_FROM_DATABASE=CM9880 + +pci:v000013F7* + ID_VENDOR_FROM_DATABASE=Wildfire Communications + +pci:v000013F8* + ID_VENDOR_FROM_DATABASE=Ad Lib Multimedia Inc + +pci:v000013F9* + ID_VENDOR_FROM_DATABASE=NTT Advanced Technology Corp. + +pci:v000013FA* + ID_VENDOR_FROM_DATABASE=Pentland Systems Ltd + +pci:v000013FB* + ID_VENDOR_FROM_DATABASE=Aydin Corp + +pci:v000013FC* + ID_VENDOR_FROM_DATABASE=Computer Peripherals International + +pci:v000013FD* + ID_VENDOR_FROM_DATABASE=Micro Science Inc + +pci:v000013FE* + ID_VENDOR_FROM_DATABASE=Advantech Co. Ltd + +pci:v000013FEd00001240* + ID_PRODUCT_FROM_DATABASE=PCI-1240 4-channel stepper motor controller card + +pci:v000013FEd00001600* + ID_PRODUCT_FROM_DATABASE=PCI-16xx series PCI multiport serial board (function 0) + +pci:v000013FEd00001600sv00001601sd00000002* + ID_PRODUCT_FROM_DATABASE=PCI-1601 2-port unisolated RS-422/485 + +pci:v000013FEd00001600sv00001602sd00000002* + ID_PRODUCT_FROM_DATABASE=PCI-1602 2-port isolated RS-422/485 + +pci:v000013FEd00001600sv00001612sd00000004* + ID_PRODUCT_FROM_DATABASE=PCI-1612 4-port RS-232/422/485 + +pci:v000013FEd00001603* + ID_PRODUCT_FROM_DATABASE=PCI-1603 2-port isolated RS-232/current loop + +pci:v000013FEd00001604* + ID_PRODUCT_FROM_DATABASE=PCI-1604 2-port RS-232 + +pci:v000013FEd000016FF* + ID_PRODUCT_FROM_DATABASE=PCI-16xx series PCI multiport serial board (function 1: RX/TX steering CPLD) + +pci:v000013FEd000016FFsv00001601sd00000000* + ID_PRODUCT_FROM_DATABASE=PCI-1601 2-port unisolated RS-422/485 PCI communications card + +pci:v000013FEd000016FFsv00001602sd00000000* + ID_PRODUCT_FROM_DATABASE=PCI-1602 2-port isolated RS-422/485 + +pci:v000013FEd000016FFsv00001612sd00000000* + ID_PRODUCT_FROM_DATABASE=PCI-1612 4-port RS-232/422/485 + +pci:v000013FEd00001711* + ID_PRODUCT_FROM_DATABASE=PCI-1711 16-channel data acquisition card 12-bit, 100kS/s + +pci:v000013FEd00001733* + ID_PRODUCT_FROM_DATABASE=PCI-1733 32-channel isolated digital input card + +pci:v000013FEd00001752* + ID_PRODUCT_FROM_DATABASE=PCI-1752 + +pci:v000013FEd00001754* + ID_PRODUCT_FROM_DATABASE=PCI-1754 + +pci:v000013FEd00001756* + ID_PRODUCT_FROM_DATABASE=PCI-1756 + +pci:v000013FF* + ID_VENDOR_FROM_DATABASE=Silicon Spice Inc + +pci:v00001400* + ID_VENDOR_FROM_DATABASE=Artx Inc + +pci:v00001400d00001401* + ID_PRODUCT_FROM_DATABASE=9432 TX + +pci:v00001401* + ID_VENDOR_FROM_DATABASE=CR-Systems A/S + +pci:v00001402* + ID_VENDOR_FROM_DATABASE=Meilhaus Electronic GmbH + +pci:v00001402d00000630* + ID_PRODUCT_FROM_DATABASE=ME-630 + +pci:v00001402d00000940* + ID_PRODUCT_FROM_DATABASE=ME-94 + +pci:v00001402d00000950* + ID_PRODUCT_FROM_DATABASE=ME-95 + +pci:v00001402d00000960* + ID_PRODUCT_FROM_DATABASE=ME-96 + +pci:v00001402d00001000* + ID_PRODUCT_FROM_DATABASE=ME-1000 + +pci:v00001402d0000100A* + ID_PRODUCT_FROM_DATABASE=ME-1000 + +pci:v00001402d0000100B* + ID_PRODUCT_FROM_DATABASE=ME-1000 + +pci:v00001402d00001400* + ID_PRODUCT_FROM_DATABASE=ME-1400 + +pci:v00001402d0000140A* + ID_PRODUCT_FROM_DATABASE=ME-1400A + +pci:v00001402d0000140B* + ID_PRODUCT_FROM_DATABASE=ME-1400B + +pci:v00001402d0000140C* + ID_PRODUCT_FROM_DATABASE=ME-1400C + +pci:v00001402d0000140D* + ID_PRODUCT_FROM_DATABASE=ME-1400D + +pci:v00001402d0000140E* + ID_PRODUCT_FROM_DATABASE=ME-1400E + +pci:v00001402d000014EA* + ID_PRODUCT_FROM_DATABASE=ME-1400EA + +pci:v00001402d000014EB* + ID_PRODUCT_FROM_DATABASE=ME-1400EB + +pci:v00001402d00001604* + ID_PRODUCT_FROM_DATABASE=ME-1600/4U + +pci:v00001402d00001608* + ID_PRODUCT_FROM_DATABASE=ME-1600/8U + +pci:v00001402d0000160C* + ID_PRODUCT_FROM_DATABASE=ME-1600/12U + +pci:v00001402d0000160F* + ID_PRODUCT_FROM_DATABASE=ME-1600/16U + +pci:v00001402d0000168F* + ID_PRODUCT_FROM_DATABASE=ME-1600/16U8I + +pci:v00001402d00004610* + ID_PRODUCT_FROM_DATABASE=ME-4610 + +pci:v00001402d00004650* + ID_PRODUCT_FROM_DATABASE=ME-4650 + +pci:v00001402d00004660* + ID_PRODUCT_FROM_DATABASE=ME-4660 + +pci:v00001402d00004661* + ID_PRODUCT_FROM_DATABASE=ME-4660I + +pci:v00001402d00004662* + ID_PRODUCT_FROM_DATABASE=ME-4660 + +pci:v00001402d00004663* + ID_PRODUCT_FROM_DATABASE=ME-4660I + +pci:v00001402d00004670* + ID_PRODUCT_FROM_DATABASE=ME-4670 + +pci:v00001402d00004671* + ID_PRODUCT_FROM_DATABASE=ME-4670I + +pci:v00001402d00004672* + ID_PRODUCT_FROM_DATABASE=ME-4670S + +pci:v00001402d00004673* + ID_PRODUCT_FROM_DATABASE=ME-4670IS + +pci:v00001402d00004680* + ID_PRODUCT_FROM_DATABASE=ME-4680 + +pci:v00001402d00004681* + ID_PRODUCT_FROM_DATABASE=ME-4680I + +pci:v00001402d00004682* + ID_PRODUCT_FROM_DATABASE=ME-4680S + +pci:v00001402d00004683* + ID_PRODUCT_FROM_DATABASE=ME-4680IS + +pci:v00001402d00006004* + ID_PRODUCT_FROM_DATABASE=ME-6000/4 + +pci:v00001402d00006008* + ID_PRODUCT_FROM_DATABASE=ME-6000/8 + +pci:v00001402d0000600F* + ID_PRODUCT_FROM_DATABASE=ME-6000/16 + +pci:v00001402d00006014* + ID_PRODUCT_FROM_DATABASE=ME-6000I/4 + +pci:v00001402d00006018* + ID_PRODUCT_FROM_DATABASE=ME-6000I/8 + +pci:v00001402d0000601F* + ID_PRODUCT_FROM_DATABASE=ME-6000I/16 + +pci:v00001402d00006034* + ID_PRODUCT_FROM_DATABASE=ME-6000ISLE/4 + +pci:v00001402d00006038* + ID_PRODUCT_FROM_DATABASE=ME-6000ISLE/8 + +pci:v00001402d0000603F* + ID_PRODUCT_FROM_DATABASE=ME-6000ISLE/16 + +pci:v00001402d00006044* + ID_PRODUCT_FROM_DATABASE=ME-6000/4/DIO + +pci:v00001402d00006048* + ID_PRODUCT_FROM_DATABASE=ME-6000/8/DIO + +pci:v00001402d0000604F* + ID_PRODUCT_FROM_DATABASE=ME-6000/16/DIO + +pci:v00001402d00006054* + ID_PRODUCT_FROM_DATABASE=ME-6000I/4/DIO + +pci:v00001402d00006058* + ID_PRODUCT_FROM_DATABASE=ME-6000I/8/DIO + +pci:v00001402d0000605F* + ID_PRODUCT_FROM_DATABASE=ME-6000I/16/DIO + +pci:v00001402d00006074* + ID_PRODUCT_FROM_DATABASE=ME-6000ISLE/4/DIO + +pci:v00001402d00006078* + ID_PRODUCT_FROM_DATABASE=ME-6000ISLE/8/DIO + +pci:v00001402d0000607F* + ID_PRODUCT_FROM_DATABASE=ME-6000ISLE/16/DIO + +pci:v00001402d00006104* + ID_PRODUCT_FROM_DATABASE=ME-6100/4 + +pci:v00001402d00006108* + ID_PRODUCT_FROM_DATABASE=ME-6100/8 + +pci:v00001402d0000610F* + ID_PRODUCT_FROM_DATABASE=ME-6100/16 + +pci:v00001402d00006114* + ID_PRODUCT_FROM_DATABASE=ME-6100I/4 + +pci:v00001402d00006118* + ID_PRODUCT_FROM_DATABASE=ME-6100I/8 + +pci:v00001402d0000611F* + ID_PRODUCT_FROM_DATABASE=ME-6100I/16 + +pci:v00001402d00006134* + ID_PRODUCT_FROM_DATABASE=ME-6100ISLE/4 + +pci:v00001402d00006138* + ID_PRODUCT_FROM_DATABASE=ME-6100ISLE/8 + +pci:v00001402d0000613F* + ID_PRODUCT_FROM_DATABASE=ME-6100ISLE/16 + +pci:v00001402d00006144* + ID_PRODUCT_FROM_DATABASE=ME-6100/4/DIO + +pci:v00001402d00006148* + ID_PRODUCT_FROM_DATABASE=ME-6100/8/DIO + +pci:v00001402d0000614F* + ID_PRODUCT_FROM_DATABASE=ME-6100/16/DIO + +pci:v00001402d00006154* + ID_PRODUCT_FROM_DATABASE=ME-6100I/4/DIO + +pci:v00001402d00006158* + ID_PRODUCT_FROM_DATABASE=ME-6100I/8/DIO + +pci:v00001402d0000615F* + ID_PRODUCT_FROM_DATABASE=ME-6100I/16/DIO + +pci:v00001402d00006174* + ID_PRODUCT_FROM_DATABASE=ME-6100ISLE/4/DIO + +pci:v00001402d00006178* + ID_PRODUCT_FROM_DATABASE=ME-6100ISLE/8/DIO + +pci:v00001402d0000617F* + ID_PRODUCT_FROM_DATABASE=ME-6100ISLE/16/DIO + +pci:v00001402d00006259* + ID_PRODUCT_FROM_DATABASE=ME-6200I/9/DIO + +pci:v00001402d00006359* + ID_PRODUCT_FROM_DATABASE=ME-6300I/9/DIO + +pci:v00001402d0000810A* + ID_PRODUCT_FROM_DATABASE=ME-8100A + +pci:v00001402d0000810B* + ID_PRODUCT_FROM_DATABASE=ME-8100B + +pci:v00001402d0000820A* + ID_PRODUCT_FROM_DATABASE=ME-8200A + +pci:v00001402d0000820B* + ID_PRODUCT_FROM_DATABASE=ME-8200B + +pci:v00001403* + ID_VENDOR_FROM_DATABASE=Ascor Inc + +pci:v00001404* + ID_VENDOR_FROM_DATABASE=Fundamental Software Inc + +pci:v00001405* + ID_VENDOR_FROM_DATABASE=Excalibur Systems Inc + +pci:v00001406* + ID_VENDOR_FROM_DATABASE=Oce' Printing Systems GmbH + +pci:v00001407* + ID_VENDOR_FROM_DATABASE=Lava Computer mfg Inc + +pci:v00001407d00000100* + ID_PRODUCT_FROM_DATABASE=Lava Dual Serial + +pci:v00001407d00000101* + ID_PRODUCT_FROM_DATABASE=Lava Quatro A + +pci:v00001407d00000102* + ID_PRODUCT_FROM_DATABASE=Lava Quatro B + +pci:v00001407d00000110* + ID_PRODUCT_FROM_DATABASE=Lava DSerial-PCI Port A + +pci:v00001407d00000111* + ID_PRODUCT_FROM_DATABASE=Lava DSerial-PCI Port B + +pci:v00001407d00000120* + ID_PRODUCT_FROM_DATABASE=Quattro-PCI A + +pci:v00001407d00000121* + ID_PRODUCT_FROM_DATABASE=Quattro-PCI B + +pci:v00001407d00000180* + ID_PRODUCT_FROM_DATABASE=Lava Octo A + +pci:v00001407d00000181* + ID_PRODUCT_FROM_DATABASE=Lava Octo B + +pci:v00001407d00000200* + ID_PRODUCT_FROM_DATABASE=Lava Port Plus + +pci:v00001407d00000201* + ID_PRODUCT_FROM_DATABASE=Lava Quad A + +pci:v00001407d00000202* + ID_PRODUCT_FROM_DATABASE=Lava Quad B + +pci:v00001407d00000220* + ID_PRODUCT_FROM_DATABASE=Lava Quattro PCI Ports A/B + +pci:v00001407d00000221* + ID_PRODUCT_FROM_DATABASE=Lava Quattro PCI Ports C/D + +pci:v00001407d00000400* + ID_PRODUCT_FROM_DATABASE=Lava 8255-PIO-PCI + +pci:v00001407d00000500* + ID_PRODUCT_FROM_DATABASE=Lava Single Serial + +pci:v00001407d00000520* + ID_PRODUCT_FROM_DATABASE=Lava RS422-SS-PCI + +pci:v00001407d00000600* + ID_PRODUCT_FROM_DATABASE=Lava Port 650 + +pci:v00001407d00008000* + ID_PRODUCT_FROM_DATABASE=Lava Parallel + +pci:v00001407d00008001* + ID_PRODUCT_FROM_DATABASE=Dual parallel port controller A + +pci:v00001407d00008002* + ID_PRODUCT_FROM_DATABASE=Lava Dual Parallel port A + +pci:v00001407d00008003* + ID_PRODUCT_FROM_DATABASE=Lava Dual Parallel port B + +pci:v00001407d00008800* + ID_PRODUCT_FROM_DATABASE=BOCA Research IOPPAR + +pci:v00001408* + ID_VENDOR_FROM_DATABASE=Aloka Co. Ltd + +pci:v00001409* + ID_VENDOR_FROM_DATABASE=Timedia Technology Co Ltd + +pci:v00001409d00007168* + ID_PRODUCT_FROM_DATABASE=PCI2S550 (Dual 16550 UART) + +pci:v00001409d00007168sv00001409sd00000002* + ID_PRODUCT_FROM_DATABASE=SER4036A3V (2x RS232 port) + +pci:v00001409d00007168sv00001409sd00004027* + ID_PRODUCT_FROM_DATABASE=SER4027A (1x RS232 port) + +pci:v00001409d00007168sv00001409sd00004037* + ID_PRODUCT_FROM_DATABASE=SER4037A (2x RS232 port) + +pci:v00001409d00007168sv00001409sd00004056* + ID_PRODUCT_FROM_DATABASE=SER4056A (4x RS232) + +pci:v00001409d00007168sv00001409sd00005027* + ID_PRODUCT_FROM_DATABASE=SER4027D + +pci:v00001409d00007168sv00001409sd00005037* + ID_PRODUCT_FROM_DATABASE=SER4037D (2x RS232 port) + +pci:v00001409d00007168sv00001409sd00005066* + ID_PRODUCT_FROM_DATABASE=SER4066R (8x RS232) + +pci:v00001409d00007168sv00001409sd00006056* + ID_PRODUCT_FROM_DATABASE=SER4056D (4x RS232 port) + +pci:v00001409d00007268* + ID_PRODUCT_FROM_DATABASE=SUN1888 (Dual IEEE1284 parallel port) + +pci:v00001409d00007268sv00001409sd00000103* + ID_PRODUCT_FROM_DATABASE=PAR4008A + +pci:v00001409d00007268sv00001409sd00000104* + ID_PRODUCT_FROM_DATABASE=PAR4018A + +pci:v0000140A* + ID_VENDOR_FROM_DATABASE=DSP Research Inc + +pci:v0000140B* + ID_VENDOR_FROM_DATABASE=GE Intelligent Platforms + +pci:v0000140C* + ID_VENDOR_FROM_DATABASE=Elmic Systems Inc + +pci:v0000140D* + ID_VENDOR_FROM_DATABASE=Matsushita Electric Works Ltd + +pci:v0000140E* + ID_VENDOR_FROM_DATABASE=Goepel Electronic GmbH + +pci:v0000140F* + ID_VENDOR_FROM_DATABASE=Salient Systems Corp + +pci:v00001410* + ID_VENDOR_FROM_DATABASE=Midas lab Inc + +pci:v00001411* + ID_VENDOR_FROM_DATABASE=Ikos Systems Inc + +pci:v00001412* + ID_VENDOR_FROM_DATABASE=VIA Technologies Inc. + +pci:v00001412d00001712* + ID_PRODUCT_FROM_DATABASE=ICE1712 [Envy24] PCI Multi-Channel I/O Controller + +pci:v00001412d00001712sv00001412sd00001712* + ID_PRODUCT_FROM_DATABASE=Hoontech ST Audio DSP 24 + +pci:v00001412d00001712sv00001412sd00003632* + ID_PRODUCT_FROM_DATABASE=M-Audio Delta Audiophile 192 + +pci:v00001412d00001712sv00001412sd0000D630* + ID_PRODUCT_FROM_DATABASE=M-Audio Delta 1010 + +pci:v00001412d00001712sv00001412sd0000D631* + ID_PRODUCT_FROM_DATABASE=M-Audio Delta DiO + +pci:v00001412d00001712sv00001412sd0000D632* + ID_PRODUCT_FROM_DATABASE=M-Audio Delta 66 + +pci:v00001412d00001712sv00001412sd0000D633* + ID_PRODUCT_FROM_DATABASE=M-Audio Delta 44 + +pci:v00001412d00001712sv00001412sd0000D634* + ID_PRODUCT_FROM_DATABASE=M-Audio Delta Audiophile 2496 + +pci:v00001412d00001712sv00001412sd0000D635* + ID_PRODUCT_FROM_DATABASE=M-Audio Delta TDIF + +pci:v00001412d00001712sv00001412sd0000D637* + ID_PRODUCT_FROM_DATABASE=M-Audio Delta RBUS + +pci:v00001412d00001712sv00001412sd0000D638* + ID_PRODUCT_FROM_DATABASE=M-Audio Delta 410 + +pci:v00001412d00001712sv00001412sd0000D63B* + ID_PRODUCT_FROM_DATABASE=M-Audio Delta 1010LT + +pci:v00001412d00001712sv00001412sd0000D63C* + ID_PRODUCT_FROM_DATABASE=Digigram VX442 + +pci:v00001412d00001712sv00001416sd00001712* + ID_PRODUCT_FROM_DATABASE=Hoontech ST Audio DSP 24 Media 7.1 + +pci:v00001412d00001712sv0000153Bsd00001115* + ID_PRODUCT_FROM_DATABASE=EWS88 MT + +pci:v00001412d00001712sv0000153Bsd00001125* + ID_PRODUCT_FROM_DATABASE=EWS88 MT (Master) + +pci:v00001412d00001712sv0000153Bsd0000112B* + ID_PRODUCT_FROM_DATABASE=EWS88 D + +pci:v00001412d00001712sv0000153Bsd0000112C* + ID_PRODUCT_FROM_DATABASE=EWS88 D (Master) + +pci:v00001412d00001712sv0000153Bsd00001130* + ID_PRODUCT_FROM_DATABASE=EWX 24/96 + +pci:v00001412d00001712sv0000153Bsd00001138* + ID_PRODUCT_FROM_DATABASE=DMX 6fire 24/96 + +pci:v00001412d00001712sv0000153Bsd00001151* + ID_PRODUCT_FROM_DATABASE=PHASE88 + +pci:v00001412d00001712sv000016CEsd00001040* + ID_PRODUCT_FROM_DATABASE=Edirol DA-2496 + +pci:v00001412d00001724* + ID_PRODUCT_FROM_DATABASE=VT1720/24 [Envy24PT/HT] PCI Multi-Channel Audio Controller + +pci:v00001412d00001724sv000010B0sd00000200* + ID_PRODUCT_FROM_DATABASE=Hollywood@Home 7.1 + +pci:v00001412d00001724sv00001412sd00001724* + ID_PRODUCT_FROM_DATABASE=Albatron PX865PE 7.1 + +pci:v00001412d00001724sv00001412sd00003630* + ID_PRODUCT_FROM_DATABASE=M-Audio Revolution 7.1 + +pci:v00001412d00001724sv00001412sd00003631* + ID_PRODUCT_FROM_DATABASE=M-Audio Revolution 5.1 + +pci:v00001412d00001724sv0000153Bsd00001145* + ID_PRODUCT_FROM_DATABASE=Aureon 7.1 Space + +pci:v00001412d00001724sv0000153Bsd00001147* + ID_PRODUCT_FROM_DATABASE=Aureon 5.1 Sky + +pci:v00001412d00001724sv0000153Bsd00001150* + ID_PRODUCT_FROM_DATABASE=PHASE 22 + +pci:v00001412d00001724sv0000153Bsd00001153* + ID_PRODUCT_FROM_DATABASE=Aureon 7.1 Universe + +pci:v00001412d00001724sv000017ABsd00001906* + ID_PRODUCT_FROM_DATABASE=PSC 724 [Ultimate Edge] + +pci:v00001412d00001724sv0000270Fsd0000F641* + ID_PRODUCT_FROM_DATABASE=ZNF3-150 + +pci:v00001412d00001724sv0000270Fsd0000F645* + ID_PRODUCT_FROM_DATABASE=ZNF3-250 + +pci:v00001412d00001724sv00003130sd00004154* + ID_PRODUCT_FROM_DATABASE=MAYA 44 MKII + +pci:v00001413* + ID_VENDOR_FROM_DATABASE=Addonics + +pci:v00001414* + ID_VENDOR_FROM_DATABASE=Microsoft Corporation + +pci:v00001414d00000001* + ID_PRODUCT_FROM_DATABASE=MN-120 (ADMtek Centaur-C based) + +pci:v00001414d00000002* + ID_PRODUCT_FROM_DATABASE=MN-130 (ADMtek Centaur-P based) + +pci:v00001414d00005353* + ID_PRODUCT_FROM_DATABASE=Hyper-V virtual VGA + +pci:v00001414d00005801* + ID_PRODUCT_FROM_DATABASE=XMA Decoder (Xenon) + +pci:v00001414d00005802* + ID_PRODUCT_FROM_DATABASE=SATA Controller - CdRom (Xenon) + +pci:v00001414d00005803* + ID_PRODUCT_FROM_DATABASE=SATA Controller - Disk (Xenon) + +pci:v00001414d00005804* + ID_PRODUCT_FROM_DATABASE=OHCI Controller 0 (Xenon) + +pci:v00001414d00005805* + ID_PRODUCT_FROM_DATABASE=EHCI Controller 0 (Xenon) + +pci:v00001414d00005806* + ID_PRODUCT_FROM_DATABASE=OHCI Controller 1 (Xenon) + +pci:v00001414d00005807* + ID_PRODUCT_FROM_DATABASE=EHCI Controller 1 (Xenon) + +pci:v00001414d0000580A* + ID_PRODUCT_FROM_DATABASE=Fast Ethernet Adapter (Xenon) + +pci:v00001414d0000580B* + ID_PRODUCT_FROM_DATABASE=Secure Flash Controller (Xenon) + +pci:v00001414d0000580D* + ID_PRODUCT_FROM_DATABASE=System Management Controller (Xenon) + +pci:v00001414d00005811* + ID_PRODUCT_FROM_DATABASE=Xenos GPU (Xenon) + +pci:v00001415* + ID_VENDOR_FROM_DATABASE=Oxford Semiconductor Ltd + +pci:v00001415d00008401* + ID_PRODUCT_FROM_DATABASE=OX9162 Mode 1 (8-bit bus) + +pci:v00001415d00008403* + ID_PRODUCT_FROM_DATABASE=OX9162 Mode 0 (parallel port) + +pci:v00001415d00009500* + ID_PRODUCT_FROM_DATABASE=OX16PCI954 (Quad 16950 UART) function 0 (Disabled) + +pci:v00001415d00009501* + ID_PRODUCT_FROM_DATABASE=OX16PCI954 (Quad 16950 UART) function 0 (Uart) + +pci:v00001415d00009501sv000012C4sd00000201* + ID_PRODUCT_FROM_DATABASE=Titan/cPCI (2 port) + +pci:v00001415d00009501sv000012C4sd00000202* + ID_PRODUCT_FROM_DATABASE=Titan/cPCI (4 port) + +pci:v00001415d00009501sv000012C4sd00000203* + ID_PRODUCT_FROM_DATABASE=Titan/cPCI (8 port) + +pci:v00001415d00009501sv000012C4sd00000210* + ID_PRODUCT_FROM_DATABASE=Titan/104-Plus (8 port, p1-4) + +pci:v00001415d00009501sv0000131Fsd00002050* + ID_PRODUCT_FROM_DATABASE=CyberPro (4-port) + +pci:v00001415d00009501sv0000131Fsd00002051* + ID_PRODUCT_FROM_DATABASE=CyberSerial 4S Plus + +pci:v00001415d00009501sv000015EDsd00002000* + ID_PRODUCT_FROM_DATABASE=MCCR Serial p0-3 of 8 + +pci:v00001415d00009501sv000015EDsd00002001* + ID_PRODUCT_FROM_DATABASE=MCCR Serial p0-3 of 16 + +pci:v00001415d00009505* + ID_PRODUCT_FROM_DATABASE=OXuPCI952 (Dual 16C950 UART) + +pci:v00001415d0000950A* + ID_PRODUCT_FROM_DATABASE=EXSYS EX-41092 Dual 16950 Serial adapter + +pci:v00001415d0000950B* + ID_PRODUCT_FROM_DATABASE=OXCB950 Cardbus 16950 UART + +pci:v00001415d00009510* + ID_PRODUCT_FROM_DATABASE=OX16PCI954 (Quad 16950 UART) function 1 (Disabled) + +pci:v00001415d00009510sv000012C4sd00000200* + ID_PRODUCT_FROM_DATABASE=Titan/cPCI (Unused) + +pci:v00001415d00009511* + ID_PRODUCT_FROM_DATABASE=OX16PCI954 (Quad 16950 UART) function 1 (8bit bus) + +pci:v00001415d00009511sv000012C4sd00000211* + ID_PRODUCT_FROM_DATABASE=Titan/104-Plus (8 port, p5-8) + +pci:v00001415d00009511sv000015EDsd00002000* + ID_PRODUCT_FROM_DATABASE=MCCR Serial p4-7 of 8 + +pci:v00001415d00009511sv000015EDsd00002001* + ID_PRODUCT_FROM_DATABASE=MCCR Serial p4-15 of 16 + +pci:v00001415d00009512* + ID_PRODUCT_FROM_DATABASE=OX16PCI954 (Quad 16950 UART) function 1 (32bit bus) + +pci:v00001415d00009513* + ID_PRODUCT_FROM_DATABASE=OX16PCI954 (Quad 16950 UART) function 1 (parallel port) + +pci:v00001415d00009521* + ID_PRODUCT_FROM_DATABASE=OX16PCI952 (Dual 16950 UART) + +pci:v00001415d00009523* + ID_PRODUCT_FROM_DATABASE=OX16PCI952 Integrated Parallel Port + +pci:v00001415d0000C158* + ID_PRODUCT_FROM_DATABASE=OXPCIe952 Dual 16C950 UART + +pci:v00001415d0000C158sv0000E4BFsd0000C504* + ID_PRODUCT_FROM_DATABASE=CP4-SCAT Wireless Technologies Carrier Board + +pci:v00001415d0000C158sv0000E4BFsd0000D551* + ID_PRODUCT_FROM_DATABASE=DU1-MUSTANG Dual-Port RS-485 Interface + +pci:v00001415d0000C308* + ID_PRODUCT_FROM_DATABASE=EX-44016 16-port serial + +pci:v00001416* + ID_VENDOR_FROM_DATABASE=Multiwave Innovation pte Ltd + +pci:v00001417* + ID_VENDOR_FROM_DATABASE=Convergenet Technologies Inc + +pci:v00001418* + ID_VENDOR_FROM_DATABASE=Kyushu electronics systems Inc + +pci:v00001419* + ID_VENDOR_FROM_DATABASE=Excel Switching Corp + +pci:v0000141A* + ID_VENDOR_FROM_DATABASE=Apache Micro Peripherals Inc + +pci:v0000141B* + ID_VENDOR_FROM_DATABASE=Zoom Telephonics Inc + +pci:v0000141D* + ID_VENDOR_FROM_DATABASE=Digitan Systems Inc + +pci:v0000141E* + ID_VENDOR_FROM_DATABASE=Fanuc Ltd + +pci:v0000141F* + ID_VENDOR_FROM_DATABASE=Visiontech Ltd + +pci:v00001420* + ID_VENDOR_FROM_DATABASE=Psion Dacom plc + +pci:v00001420d00008002* + ID_PRODUCT_FROM_DATABASE=Gold Card NetGlobal 56k+10/100Mb CardBus (Ethernet part) + +pci:v00001420d00008003* + ID_PRODUCT_FROM_DATABASE=Gold Card NetGlobal 56k+10/100Mb CardBus (Modem part) + +pci:v00001421* + ID_VENDOR_FROM_DATABASE=Ads Technologies Inc + +pci:v00001422* + ID_VENDOR_FROM_DATABASE=Ygrec Systems Co Ltd + +pci:v00001423* + ID_VENDOR_FROM_DATABASE=Custom Technology Corp. + +pci:v00001424* + ID_VENDOR_FROM_DATABASE=Videoserver Connections + +pci:v00001425* + ID_VENDOR_FROM_DATABASE=Chelsio Communications Inc + +pci:v00001425d0000000B* + ID_PRODUCT_FROM_DATABASE=T210 Protocol Engine + +pci:v00001425d0000000C* + ID_PRODUCT_FROM_DATABASE=T204 Protocol Engine + +pci:v00001425d00000022* + ID_PRODUCT_FROM_DATABASE=10GbE Ethernet Adapter + +pci:v00001425d00000030* + ID_PRODUCT_FROM_DATABASE=T310 10GbE Single Port Adapter + +pci:v00001425d00000030sv0000103Csd0000705E* + ID_PRODUCT_FROM_DATABASE=PCIe 10GBase-SR [AD386A] + +pci:v00001425d00000031* + ID_PRODUCT_FROM_DATABASE=T320 10GbE Dual Port Adapter + +pci:v00001425d00000032* + ID_PRODUCT_FROM_DATABASE=T302 1GbE Dual Port Adapter + +pci:v00001425d00000033* + ID_PRODUCT_FROM_DATABASE=T304 1GbE Quad Port Adapter + +pci:v00001425d00000034* + ID_PRODUCT_FROM_DATABASE=B320 10GbE Dual Port Adapter + +pci:v00001425d00000035* + ID_PRODUCT_FROM_DATABASE=S310-CR 10GbE Single Port Adapter + +pci:v00001425d00000036* + ID_PRODUCT_FROM_DATABASE=S320-LP-CR 10GbE Dual Port Adapter + +pci:v00001425d00000037* + ID_PRODUCT_FROM_DATABASE=N320-G2-CR 10GbE Dual Port Adapter + +pci:v00001425d00004001* + ID_PRODUCT_FROM_DATABASE=T420-CR Unified Wire Ethernet Controller + +pci:v00001425d00004002* + ID_PRODUCT_FROM_DATABASE=T422-CR Unified Wire Ethernet Controller + +pci:v00001425d00004003* + ID_PRODUCT_FROM_DATABASE=T440-CR Unified Wire Ethernet Controller + +pci:v00001425d00004004* + ID_PRODUCT_FROM_DATABASE=T420-BCH Unified Wire Ethernet Controller + +pci:v00001425d00004005* + ID_PRODUCT_FROM_DATABASE=T440-BCH Unified Wire Ethernet Controller + +pci:v00001425d00004006* + ID_PRODUCT_FROM_DATABASE=T440-CH Unified Wire Ethernet Controller + +pci:v00001425d00004007* + ID_PRODUCT_FROM_DATABASE=T420-SO Unified Wire Ethernet Controller + +pci:v00001425d00004008* + ID_PRODUCT_FROM_DATABASE=T420-CX Unified Wire Ethernet Controller + +pci:v00001425d00004009* + ID_PRODUCT_FROM_DATABASE=T420-BT Unified Wire Ethernet Controller + +pci:v00001425d0000400A* + ID_PRODUCT_FROM_DATABASE=T404-BT Unified Wire Ethernet Controller + +pci:v00001425d0000400B* + ID_PRODUCT_FROM_DATABASE=B420-SR Unified Wire Ethernet Controller + +pci:v00001425d0000400C* + ID_PRODUCT_FROM_DATABASE=B404-BT Unified Wire Ethernet Controller + +pci:v00001425d0000400D* + ID_PRODUCT_FROM_DATABASE=T480 Unified Wire Ethernet Controller + +pci:v00001425d0000400E* + ID_PRODUCT_FROM_DATABASE=T440-LP-CR Unified Wire Ethernet Controller + +pci:v00001425d00004401* + ID_PRODUCT_FROM_DATABASE=T420-CR Unified Wire Ethernet Controller + +pci:v00001425d00004402* + ID_PRODUCT_FROM_DATABASE=T422-CR Unified Wire Ethernet Controller + +pci:v00001425d00004403* + ID_PRODUCT_FROM_DATABASE=T440-CR Unified Wire Ethernet Controller + +pci:v00001425d00004404* + ID_PRODUCT_FROM_DATABASE=T420-BCH Unified Wire Ethernet Controller + +pci:v00001425d00004405* + ID_PRODUCT_FROM_DATABASE=T440-BCH Unified Wire Ethernet Controller + +pci:v00001425d00004406* + ID_PRODUCT_FROM_DATABASE=T440-CH Unified Wire Ethernet Controller + +pci:v00001425d00004407* + ID_PRODUCT_FROM_DATABASE=T420-SO Unified Wire Ethernet Controller + +pci:v00001425d00004408* + ID_PRODUCT_FROM_DATABASE=T420-CX Unified Wire Ethernet Controller + +pci:v00001425d00004409* + ID_PRODUCT_FROM_DATABASE=T420-BT Unified Wire Ethernet Controller + +pci:v00001425d0000440A* + ID_PRODUCT_FROM_DATABASE=T404-BT Unified Wire Ethernet Controller + +pci:v00001425d0000440B* + ID_PRODUCT_FROM_DATABASE=B420-SR Unified Wire Ethernet Controller + +pci:v00001425d0000440C* + ID_PRODUCT_FROM_DATABASE=B404-BT Unified Wire Ethernet Controller + +pci:v00001425d0000440D* + ID_PRODUCT_FROM_DATABASE=T480 Unified Wire Ethernet Controller + +pci:v00001425d0000440E* + ID_PRODUCT_FROM_DATABASE=T440-LP-CR Unified Wire Ethernet Controller + +pci:v00001425d00004501* + ID_PRODUCT_FROM_DATABASE=T420-CR Unified Wire Storage Controller + +pci:v00001425d00004502* + ID_PRODUCT_FROM_DATABASE=T422-CR Unified Wire Storage Controller + +pci:v00001425d00004503* + ID_PRODUCT_FROM_DATABASE=T440-CR Unified Wire Storage Controller + +pci:v00001425d00004504* + ID_PRODUCT_FROM_DATABASE=T420-BCH Unified Wire Storage Controller + +pci:v00001425d00004505* + ID_PRODUCT_FROM_DATABASE=T440-BCH Unified Wire Storage Controller + +pci:v00001425d00004506* + ID_PRODUCT_FROM_DATABASE=T440-CH Unified Wire Storage Controller + +pci:v00001425d00004507* + ID_PRODUCT_FROM_DATABASE=T420-SO Unified Wire Storage Controller + +pci:v00001425d00004508* + ID_PRODUCT_FROM_DATABASE=T420-CX Unified Wire Storage Controller + +pci:v00001425d00004509* + ID_PRODUCT_FROM_DATABASE=T420-BT Unified Wire Storage Controller + +pci:v00001425d0000450A* + ID_PRODUCT_FROM_DATABASE=T404-BT Unified Wire Storage Controller + +pci:v00001425d0000450B* + ID_PRODUCT_FROM_DATABASE=B420-SR Unified Wire Ethernet Controller + +pci:v00001425d0000450C* + ID_PRODUCT_FROM_DATABASE=B404-BT Unified Wire Ethernet Controller + +pci:v00001425d0000450D* + ID_PRODUCT_FROM_DATABASE=T480 Unified Wire Storage Controller + +pci:v00001425d0000450E* + ID_PRODUCT_FROM_DATABASE=T440-LP-CR Unified Wire Storage Controller + +pci:v00001425d00004601* + ID_PRODUCT_FROM_DATABASE=T420-CR Unified Wire Storage Controller + +pci:v00001425d00004602* + ID_PRODUCT_FROM_DATABASE=T422-CR Unified Wire Storage Controller + +pci:v00001425d00004603* + ID_PRODUCT_FROM_DATABASE=T440-CR Unified Wire Storage Controller + +pci:v00001425d00004604* + ID_PRODUCT_FROM_DATABASE=T420-BCH Unified Wire Storage Controller + +pci:v00001425d00004605* + ID_PRODUCT_FROM_DATABASE=T440-BCH Unified Wire Storage Controller + +pci:v00001425d00004606* + ID_PRODUCT_FROM_DATABASE=T440-CH Unified Wire Storage Controller + +pci:v00001425d00004607* + ID_PRODUCT_FROM_DATABASE=T420-SO Unified Wire Storage Controller + +pci:v00001425d00004608* + ID_PRODUCT_FROM_DATABASE=T420-CX Unified Wire Storage Controller + +pci:v00001425d00004609* + ID_PRODUCT_FROM_DATABASE=T420-BT Unified Wire Storage Controller + +pci:v00001425d0000460A* + ID_PRODUCT_FROM_DATABASE=T404-BT Unified Wire Storage Controller + +pci:v00001425d0000460B* + ID_PRODUCT_FROM_DATABASE=B420-SR Unified Wire Ethernet Controller + +pci:v00001425d0000460C* + ID_PRODUCT_FROM_DATABASE=B404-BT Unified Wire Ethernet Controller + +pci:v00001425d0000460D* + ID_PRODUCT_FROM_DATABASE=T480 Unified Wire Storage Controller + +pci:v00001425d0000460E* + ID_PRODUCT_FROM_DATABASE=T440-LP-CR Unified Wire Storage Controller + +pci:v00001425d00004701* + ID_PRODUCT_FROM_DATABASE=T420-CR Unified Wire Ethernet Controller + +pci:v00001425d00004702* + ID_PRODUCT_FROM_DATABASE=T422-CR Unified Wire Ethernet Controller + +pci:v00001425d00004703* + ID_PRODUCT_FROM_DATABASE=T440-CR Unified Wire Ethernet Controller + +pci:v00001425d00004704* + ID_PRODUCT_FROM_DATABASE=T420-BCH Unified Wire Ethernet Controller + +pci:v00001425d00004705* + ID_PRODUCT_FROM_DATABASE=T440-BCH Unified Wire Ethernet Controller + +pci:v00001425d00004706* + ID_PRODUCT_FROM_DATABASE=T440-CH Unified Wire Ethernet Controller + +pci:v00001425d00004707* + ID_PRODUCT_FROM_DATABASE=T420-SO Unified Wire Ethernet Controller + +pci:v00001425d00004708* + ID_PRODUCT_FROM_DATABASE=T420-CX Unified Wire Ethernet Controller + +pci:v00001425d00004709* + ID_PRODUCT_FROM_DATABASE=T420-BT Unified Wire Ethernet Controller + +pci:v00001425d0000470A* + ID_PRODUCT_FROM_DATABASE=T404-BT Unified Wire Ethernet Controller + +pci:v00001425d0000470B* + ID_PRODUCT_FROM_DATABASE=B420-SR Unified Wire Ethernet Controller + +pci:v00001425d0000470C* + ID_PRODUCT_FROM_DATABASE=B404-BT Unified Wire Ethernet Controller + +pci:v00001425d0000470D* + ID_PRODUCT_FROM_DATABASE=T480 Unified Wire Ethernet Controller + +pci:v00001425d0000470E* + ID_PRODUCT_FROM_DATABASE=T440-LP-CR Unified Wire Ethernet Controller + +pci:v00001425d00004801* + ID_PRODUCT_FROM_DATABASE=T420-CR Unified Wire Ethernet Controller + +pci:v00001425d00004802* + ID_PRODUCT_FROM_DATABASE=T422-CR Unified Wire Ethernet Controller + +pci:v00001425d00004803* + ID_PRODUCT_FROM_DATABASE=T440-CR Unified Wire Ethernet Controller + +pci:v00001425d00004804* + ID_PRODUCT_FROM_DATABASE=T420-BCH Unified Wire Ethernet Controller + +pci:v00001425d00004805* + ID_PRODUCT_FROM_DATABASE=T440-BCH Unified Wire Ethernet Controller + +pci:v00001425d00004806* + ID_PRODUCT_FROM_DATABASE=T440-CH Unified Wire Ethernet Controller + +pci:v00001425d00004807* + ID_PRODUCT_FROM_DATABASE=T420-SO Unified Wire Ethernet Controller + +pci:v00001425d00004808* + ID_PRODUCT_FROM_DATABASE=T420-CX Unified Wire Ethernet Controller + +pci:v00001425d00004809* + ID_PRODUCT_FROM_DATABASE=T420-BT Unified Wire Ethernet Controller + +pci:v00001425d0000480A* + ID_PRODUCT_FROM_DATABASE=T404-BT Unified Wire Ethernet Controller + +pci:v00001425d0000480B* + ID_PRODUCT_FROM_DATABASE=B420-SR Unified Wire Ethernet Controller + +pci:v00001425d0000480C* + ID_PRODUCT_FROM_DATABASE=B404-BT Unified Wire Ethernet Controller + +pci:v00001425d0000480D* + ID_PRODUCT_FROM_DATABASE=T480 Unified Wire Ethernet Controller + +pci:v00001425d0000480E* + ID_PRODUCT_FROM_DATABASE=T440-LP-CR Unified Wire Ethernet Controller + +pci:v00001425d0000A000* + ID_PRODUCT_FROM_DATABASE=PE10K Unified Wire Ethernet Controller + +pci:v00001426* + ID_VENDOR_FROM_DATABASE=Storage Technology Corp. + +pci:v00001427* + ID_VENDOR_FROM_DATABASE=Better On-Line Solutions + +pci:v00001428* + ID_VENDOR_FROM_DATABASE=Edec Co Ltd + +pci:v00001429* + ID_VENDOR_FROM_DATABASE=Unex Technology Corp. + +pci:v0000142A* + ID_VENDOR_FROM_DATABASE=Kingmax Technology Inc + +pci:v0000142B* + ID_VENDOR_FROM_DATABASE=Radiolan + +pci:v0000142C* + ID_VENDOR_FROM_DATABASE=Minton Optic Industry Co Ltd + +pci:v0000142D* + ID_VENDOR_FROM_DATABASE=Pix stream Inc + +pci:v0000142E* + ID_VENDOR_FROM_DATABASE=Vitec Multimedia + +pci:v0000142Ed00004020* + ID_PRODUCT_FROM_DATABASE=VM2-2 [Video Maker 2] MPEG1/2 Encoder + +pci:v0000142Ed00004337* + ID_PRODUCT_FROM_DATABASE=VM2-2-C7 [Video Maker 2 rev. C7] MPEG1/2 Encoder + +pci:v0000142F* + ID_VENDOR_FROM_DATABASE=Radicom Research Inc + +pci:v00001430* + ID_VENDOR_FROM_DATABASE=ITT Aerospace/Communications Division + +pci:v00001431* + ID_VENDOR_FROM_DATABASE=Gilat Satellite Networks + +pci:v00001432* + ID_VENDOR_FROM_DATABASE=Edimax Computer Co. + +pci:v00001432d00009130* + ID_PRODUCT_FROM_DATABASE=RTL81xx Fast Ethernet + +pci:v00001433* + ID_VENDOR_FROM_DATABASE=Eltec Elektronik GmbH + +pci:v00001435* + ID_VENDOR_FROM_DATABASE=RTD Embedded Technologies, Inc. + +pci:v00001435d00004520* + ID_PRODUCT_FROM_DATABASE=PCI4520 + +pci:v00001435d00006020* + ID_PRODUCT_FROM_DATABASE=SPM6020 + +pci:v00001435d00006030* + ID_PRODUCT_FROM_DATABASE=SPM6030 + +pci:v00001435d00006420* + ID_PRODUCT_FROM_DATABASE=SPM186420 + +pci:v00001435d00006430* + ID_PRODUCT_FROM_DATABASE=SPM176430 + +pci:v00001435d00006431* + ID_PRODUCT_FROM_DATABASE=SPM176431 + +pci:v00001435d00007520* + ID_PRODUCT_FROM_DATABASE=DM7520 + +pci:v00001435d00007540* + ID_PRODUCT_FROM_DATABASE=SDM7540 + +pci:v00001435d00007820* + ID_PRODUCT_FROM_DATABASE=DM7820 + +pci:v00001436* + ID_VENDOR_FROM_DATABASE=CIS Technology Inc + +pci:v00001437* + ID_VENDOR_FROM_DATABASE=Nissin Inc Co + +pci:v00001438* + ID_VENDOR_FROM_DATABASE=Atmel-dream + +pci:v00001439* + ID_VENDOR_FROM_DATABASE=Outsource Engineering & Mfg. Inc + +pci:v0000143A* + ID_VENDOR_FROM_DATABASE=Stargate Solutions Inc + +pci:v0000143B* + ID_VENDOR_FROM_DATABASE=Canon Research Center, America + +pci:v0000143C* + ID_VENDOR_FROM_DATABASE=Amlogic Inc + +pci:v0000143D* + ID_VENDOR_FROM_DATABASE=Tamarack Microelectronics Inc + +pci:v0000143E* + ID_VENDOR_FROM_DATABASE=Jones Futurex Inc + +pci:v0000143F* + ID_VENDOR_FROM_DATABASE=Lightwell Co Ltd - Zax Division + +pci:v00001440* + ID_VENDOR_FROM_DATABASE=ALGOL Corp. + +pci:v00001441* + ID_VENDOR_FROM_DATABASE=AGIE Ltd + +pci:v00001442* + ID_VENDOR_FROM_DATABASE=Phoenix Contact GmbH & Co. + +pci:v00001443* + ID_VENDOR_FROM_DATABASE=Unibrain S.A. + +pci:v00001444* + ID_VENDOR_FROM_DATABASE=TRW + +pci:v00001445* + ID_VENDOR_FROM_DATABASE=Logical DO Ltd + +pci:v00001446* + ID_VENDOR_FROM_DATABASE=Graphin Co Ltd + +pci:v00001447* + ID_VENDOR_FROM_DATABASE=AIM GmBH + +pci:v00001448* + ID_VENDOR_FROM_DATABASE=Alesis Studio Electronics + +pci:v00001449* + ID_VENDOR_FROM_DATABASE=TUT Systems Inc + +pci:v0000144A* + ID_VENDOR_FROM_DATABASE=Adlink Technology + +pci:v0000144Ad00006208* + ID_PRODUCT_FROM_DATABASE=PCI-6208V + +pci:v0000144Ad00007250* + ID_PRODUCT_FROM_DATABASE=PCI-7250 + +pci:v0000144Ad00007296* + ID_PRODUCT_FROM_DATABASE=PCI-7296 + +pci:v0000144Ad00007432* + ID_PRODUCT_FROM_DATABASE=PCI-7432 + +pci:v0000144Ad00007433* + ID_PRODUCT_FROM_DATABASE=PCI-7433 + +pci:v0000144Ad00007434* + ID_PRODUCT_FROM_DATABASE=PCI-7434 + +pci:v0000144Ad00007841* + ID_PRODUCT_FROM_DATABASE=PCI-7841 + +pci:v0000144Ad00008133* + ID_PRODUCT_FROM_DATABASE=PCI-8133 + +pci:v0000144Ad00008164* + ID_PRODUCT_FROM_DATABASE=PCI-8164 + +pci:v0000144Ad00008554* + ID_PRODUCT_FROM_DATABASE=PCI-8554 + +pci:v0000144Ad00009111* + ID_PRODUCT_FROM_DATABASE=PCI-9111 + +pci:v0000144Ad00009113* + ID_PRODUCT_FROM_DATABASE=PCI-9113 + +pci:v0000144Ad00009114* + ID_PRODUCT_FROM_DATABASE=PCI-9114 + +pci:v0000144B* + ID_VENDOR_FROM_DATABASE=Verint Systems Inc. + +pci:v0000144C* + ID_VENDOR_FROM_DATABASE=Catalina Research Inc + +pci:v0000144D* + ID_VENDOR_FROM_DATABASE=Samsung Electronics Co Ltd + +pci:v0000144Dd0000C00C* + ID_PRODUCT_FROM_DATABASE=P35 laptop + +pci:v0000144Dd0000C511* + ID_PRODUCT_FROM_DATABASE=R20 Laptop + +pci:v0000144E* + ID_VENDOR_FROM_DATABASE=OLITEC + +pci:v0000144F* + ID_VENDOR_FROM_DATABASE=Askey Computer Corp. + +pci:v00001450* + ID_VENDOR_FROM_DATABASE=Octave Communications Ind. + +pci:v00001451* + ID_VENDOR_FROM_DATABASE=SP3D Chip Design GmBH + +pci:v00001453* + ID_VENDOR_FROM_DATABASE=MYCOM Inc + +pci:v00001454* + ID_VENDOR_FROM_DATABASE=Altiga Networks + +pci:v00001455* + ID_VENDOR_FROM_DATABASE=Logic Plus Plus Inc + +pci:v00001456* + ID_VENDOR_FROM_DATABASE=Advanced Hardware Architectures + +pci:v00001457* + ID_VENDOR_FROM_DATABASE=Nuera Communications Inc + +pci:v00001458* + ID_VENDOR_FROM_DATABASE=Giga-byte Technology + +pci:v00001458d00009001* + ID_PRODUCT_FROM_DATABASE=GC-PTV-TAF Hybrid TV card + +pci:v00001458d0000E911* + ID_PRODUCT_FROM_DATABASE=GN-WIAG02 + +pci:v00001459* + ID_VENDOR_FROM_DATABASE=DOOIN Electronics + +pci:v0000145A* + ID_VENDOR_FROM_DATABASE=Escalate Networks Inc + +pci:v0000145B* + ID_VENDOR_FROM_DATABASE=PRAIM SRL + +pci:v0000145C* + ID_VENDOR_FROM_DATABASE=Cryptek + +pci:v0000145D* + ID_VENDOR_FROM_DATABASE=Gallant Computer Inc + +pci:v0000145E* + ID_VENDOR_FROM_DATABASE=Aashima Technology B.V. + +pci:v0000145F* + ID_VENDOR_FROM_DATABASE=Baldor Electric Company + +pci:v0000145Fd00000001* + ID_PRODUCT_FROM_DATABASE=NextMove PCI + +pci:v00001460* + ID_VENDOR_FROM_DATABASE=DYNARC INC + +pci:v00001461* + ID_VENDOR_FROM_DATABASE=Avermedia Technologies Inc + +pci:v00001461d0000A3CE* + ID_PRODUCT_FROM_DATABASE=M179 + +pci:v00001461d0000A3CF* + ID_PRODUCT_FROM_DATABASE=M179 + +pci:v00001461d0000A836* + ID_PRODUCT_FROM_DATABASE=M115 DVB-T, PAL/SECAM/NTSC Tuner + +pci:v00001461d0000E836* + ID_PRODUCT_FROM_DATABASE=M115S Hybrid Analog/DVB PAL/SECAM/NTSC Tuner + +pci:v00001461d0000F436* + ID_PRODUCT_FROM_DATABASE=AVerTV Hybrid+FM + +pci:v00001462* + ID_VENDOR_FROM_DATABASE=Micro-Star International Co., Ltd. + +pci:v00001462d00005501* + ID_PRODUCT_FROM_DATABASE=nVidia NV15DDR [GeForce2 Ti] + +pci:v00001462d00006819* + ID_PRODUCT_FROM_DATABASE=Broadcom Corporation BCM4306 802.11b/g Wireless LAN Controller [MSI CB54G] + +pci:v00001462d00006825* + ID_PRODUCT_FROM_DATABASE=PCI Card wireless 11g [PC54G] + +pci:v00001462d00006834* + ID_PRODUCT_FROM_DATABASE=RaLink RT2500 802.11g [PC54G2] + +pci:v00001462d00007125* + ID_PRODUCT_FROM_DATABASE=MS-7125 [K8N Neo4 Platinum] + +pci:v00001462d00007235* + ID_PRODUCT_FROM_DATABASE=P965 Neo MS-7235 mainboard + +pci:v00001462d00007242* + ID_PRODUCT_FROM_DATABASE=K9AGM RS485 Motherboard + +pci:v00001462d00007250* + ID_PRODUCT_FROM_DATABASE=MS-7250 Motherboard [K9N Platinum SLI/non-SLI] + +pci:v00001462d00007327* + ID_PRODUCT_FROM_DATABASE=K9AGM2-FIH Motherboard + +pci:v00001462d00007650* + ID_PRODUCT_FROM_DATABASE=Hetis 865GV-E (MS-7065) + +pci:v00001462d00008725* + ID_PRODUCT_FROM_DATABASE=NVIDIA NV25 [GeForce4 Ti 4600] VGA Adapter + +pci:v00001462d00009000* + ID_PRODUCT_FROM_DATABASE=NVIDIA NV28 [GeForce4 Ti 4800] VGA Adapter + +pci:v00001462d00009110* + ID_PRODUCT_FROM_DATABASE=GeFORCE FX5200 + +pci:v00001462d00009119* + ID_PRODUCT_FROM_DATABASE=NVIDIA NV31 [GeForce FX 5600XT] VGA Adapter + +pci:v00001462d00009123* + ID_PRODUCT_FROM_DATABASE=NVIDIA NV31 [GeForce FX 5600] FX5600-VTDR128 [MS-8912] + +pci:v00001462d00009510* + ID_PRODUCT_FROM_DATABASE=Radeon 9600XT + +pci:v00001462d00009511* + ID_PRODUCT_FROM_DATABASE=Radeon 9600XT + +pci:v00001462d00009591* + ID_PRODUCT_FROM_DATABASE=nVidia Corporation NV36 [GeForce FX 5700LE] + +pci:v00001462d0000B834* + ID_PRODUCT_FROM_DATABASE=Wireless 11g Turbo G PCI card [MSI PC60G] + +pci:v00001463* + ID_VENDOR_FROM_DATABASE=Fast Corporation + +pci:v00001464* + ID_VENDOR_FROM_DATABASE=Interactive Circuits & Systems Ltd + +pci:v00001465* + ID_VENDOR_FROM_DATABASE=GN NETTEST Telecom DIV. + +pci:v00001466* + ID_VENDOR_FROM_DATABASE=Designpro Inc. + +pci:v00001467* + ID_VENDOR_FROM_DATABASE=DIGICOM SPA + +pci:v00001468* + ID_VENDOR_FROM_DATABASE=AMBIT Microsystem Corp. + +pci:v00001469* + ID_VENDOR_FROM_DATABASE=Cleveland Motion Controls + +pci:v0000146A* + ID_VENDOR_FROM_DATABASE=IFR + +pci:v0000146B* + ID_VENDOR_FROM_DATABASE=Parascan Technologies Ltd + +pci:v0000146C* + ID_VENDOR_FROM_DATABASE=Ruby Tech Corp. + +pci:v0000146Cd00001430* + ID_PRODUCT_FROM_DATABASE=FE-1430TX Fast Ethernet PCI Adapter + +pci:v0000146D* + ID_VENDOR_FROM_DATABASE=Tachyon, INC. + +pci:v0000146E* + ID_VENDOR_FROM_DATABASE=Williams Electronics Games, Inc. + +pci:v0000146F* + ID_VENDOR_FROM_DATABASE=Multi Dimensional Consulting Inc + +pci:v00001470* + ID_VENDOR_FROM_DATABASE=Bay Networks + +pci:v00001471* + ID_VENDOR_FROM_DATABASE=Integrated Telecom Express Inc + +pci:v00001472* + ID_VENDOR_FROM_DATABASE=DAIKIN Industries, Ltd + +pci:v00001473* + ID_VENDOR_FROM_DATABASE=ZAPEX Technologies Inc + +pci:v00001474* + ID_VENDOR_FROM_DATABASE=Doug Carson & Associates + +pci:v00001475* + ID_VENDOR_FROM_DATABASE=PICAZO Communications + +pci:v00001476* + ID_VENDOR_FROM_DATABASE=MORTARA Instrument Inc + +pci:v00001477* + ID_VENDOR_FROM_DATABASE=Net Insight + +pci:v00001478* + ID_VENDOR_FROM_DATABASE=DIATREND Corporation + +pci:v00001479* + ID_VENDOR_FROM_DATABASE=TORAY Industries Inc + +pci:v0000147A* + ID_VENDOR_FROM_DATABASE=FORMOSA Industrial Computing + +pci:v0000147B* + ID_VENDOR_FROM_DATABASE=ABIT Computer Corp. + +pci:v0000147Bd00001084* + ID_PRODUCT_FROM_DATABASE=IP35 [Dark Raider] + +pci:v0000147C* + ID_VENDOR_FROM_DATABASE=AWARE, Inc. + +pci:v0000147D* + ID_VENDOR_FROM_DATABASE=Interworks Computer Products + +pci:v0000147E* + ID_VENDOR_FROM_DATABASE=Matsushita Graphic Communication Systems, Inc. + +pci:v0000147F* + ID_VENDOR_FROM_DATABASE=NIHON UNISYS, Ltd. + +pci:v00001480* + ID_VENDOR_FROM_DATABASE=SCII Telecom + +pci:v00001481* + ID_VENDOR_FROM_DATABASE=BIOPAC Systems Inc + +pci:v00001482* + ID_VENDOR_FROM_DATABASE=ISYTEC - Integrierte Systemtechnik GmBH + +pci:v00001482d00000001* + ID_PRODUCT_FROM_DATABASE=PCI-16 Host Interface for ITC-16 + +pci:v00001483* + ID_VENDOR_FROM_DATABASE=LABWAY Corporation + +pci:v00001484* + ID_VENDOR_FROM_DATABASE=Logic Corporation + +pci:v00001485* + ID_VENDOR_FROM_DATABASE=ERMA - Electronic GmBH + +pci:v00001486* + ID_VENDOR_FROM_DATABASE=L3 Communications Telemetry & Instrumentation + +pci:v00001487* + ID_VENDOR_FROM_DATABASE=MARQUETTE Medical Systems + +pci:v00001488* + ID_VENDOR_FROM_DATABASE=KONTRON Electronik GmBH + +pci:v00001489* + ID_VENDOR_FROM_DATABASE=KYE Systems Corporation + +pci:v0000148A* + ID_VENDOR_FROM_DATABASE=OPTO + +pci:v0000148B* + ID_VENDOR_FROM_DATABASE=INNOMEDIALOGIC Inc. + +pci:v0000148C* + ID_VENDOR_FROM_DATABASE=C.P. Technology Co. Ltd + +pci:v0000148D* + ID_VENDOR_FROM_DATABASE=DIGICOM Systems, Inc. + +pci:v0000148Dd00001003* + ID_PRODUCT_FROM_DATABASE=HCF 56k Data/Fax Modem + +pci:v0000148E* + ID_VENDOR_FROM_DATABASE=OSI Plus Corporation + +pci:v0000148F* + ID_VENDOR_FROM_DATABASE=Plant Equipment, Inc. + +pci:v00001490* + ID_VENDOR_FROM_DATABASE=Stone Microsystems PTY Ltd. + +pci:v00001491* + ID_VENDOR_FROM_DATABASE=ZEAL Corporation + +pci:v00001492* + ID_VENDOR_FROM_DATABASE=Time Logic Corporation + +pci:v00001493* + ID_VENDOR_FROM_DATABASE=MAKER Communications + +pci:v00001494* + ID_VENDOR_FROM_DATABASE=WINTOP Technology, Inc. + +pci:v00001495* + ID_VENDOR_FROM_DATABASE=TOKAI Communications Industry Co. Ltd + +pci:v00001496* + ID_VENDOR_FROM_DATABASE=JOYTECH Computer Co., Ltd. + +pci:v00001497* + ID_VENDOR_FROM_DATABASE=SMA Regelsysteme GmBH + +pci:v00001497d00001497* + ID_PRODUCT_FROM_DATABASE=SMA Technologie AG + +pci:v00001498* + ID_VENDOR_FROM_DATABASE=TEWS Technologies GmbH + +pci:v00001498d00000330* + ID_PRODUCT_FROM_DATABASE=TPMC816 2 Channel CAN bus controller. + +pci:v00001498d0000035D* + ID_PRODUCT_FROM_DATABASE=TPMC861 4-Channel Isolated Serial Interface RS422/RS485 + +pci:v00001498d00000385* + ID_PRODUCT_FROM_DATABASE=TPMC901 Extended CAN bus with 2/4/6 CAN controller + +pci:v00001498d000021CC* + ID_PRODUCT_FROM_DATABASE=TCP460 CompactPCI 16 Channel Serial Interface RS232/RS422 + +pci:v00001498d000021CD* + ID_PRODUCT_FROM_DATABASE=TCP461 CompactPCI 8 Channel Serial Interface RS232/RS422 + +pci:v00001498d00003064* + ID_PRODUCT_FROM_DATABASE=TPCI100 (2 Slot IndustryPack PCI Carrier) + +pci:v00001498d000030C8* + ID_PRODUCT_FROM_DATABASE=TPCI200 + +pci:v00001499* + ID_VENDOR_FROM_DATABASE=EMTEC CO., Ltd + +pci:v0000149A* + ID_VENDOR_FROM_DATABASE=ANDOR Technology Ltd + +pci:v0000149B* + ID_VENDOR_FROM_DATABASE=SEIKO Instruments Inc + +pci:v0000149C* + ID_VENDOR_FROM_DATABASE=OVISLINK Corp. + +pci:v0000149D* + ID_VENDOR_FROM_DATABASE=NEWTEK Inc + +pci:v0000149Dd00000001* + ID_PRODUCT_FROM_DATABASE=Video Toaster for PC + +pci:v0000149E* + ID_VENDOR_FROM_DATABASE=Mapletree Networks Inc. + +pci:v0000149F* + ID_VENDOR_FROM_DATABASE=LECTRON Co Ltd + +pci:v000014A0* + ID_VENDOR_FROM_DATABASE=SOFTING GmBH + +pci:v000014A1* + ID_VENDOR_FROM_DATABASE=Systembase Co Ltd + +pci:v000014A2* + ID_VENDOR_FROM_DATABASE=Millennium Engineering Inc + +pci:v000014A3* + ID_VENDOR_FROM_DATABASE=Maverick Networks + +pci:v000014A4* + ID_VENDOR_FROM_DATABASE=Broadcom Corporation (Wrong ID) + +pci:v000014A4d00004318* + ID_PRODUCT_FROM_DATABASE=BCM4318 [AirForce One 54g] 802.11g Wireless LAN Controller + +pci:v000014A5* + ID_VENDOR_FROM_DATABASE=XIONICS Document Technologies Inc + +pci:v000014A6* + ID_VENDOR_FROM_DATABASE=INOVA Computers GmBH & Co KG + +pci:v000014A7* + ID_VENDOR_FROM_DATABASE=MYTHOS Systems Inc + +pci:v000014A8* + ID_VENDOR_FROM_DATABASE=FEATRON Technologies Corporation + +pci:v000014A9* + ID_VENDOR_FROM_DATABASE=HIVERTEC Inc + +pci:v000014AA* + ID_VENDOR_FROM_DATABASE=Advanced MOS Technology Inc + +pci:v000014AB* + ID_VENDOR_FROM_DATABASE=Mentor Graphics Corp. + +pci:v000014AC* + ID_VENDOR_FROM_DATABASE=Novaweb Technologies Inc + +pci:v000014AD* + ID_VENDOR_FROM_DATABASE=Time Space Radio AB + +pci:v000014AE* + ID_VENDOR_FROM_DATABASE=CTI, Inc + +pci:v000014AF* + ID_VENDOR_FROM_DATABASE=Guillemot Corporation + +pci:v000014AFd00007102* + ID_PRODUCT_FROM_DATABASE=3D Prophet II MX + +pci:v000014B0* + ID_VENDOR_FROM_DATABASE=BST Communication Technology Ltd + +pci:v000014B1* + ID_VENDOR_FROM_DATABASE=Nextcom K.K. + +pci:v000014B2* + ID_VENDOR_FROM_DATABASE=ENNOVATE Networks Inc + +pci:v000014B3* + ID_VENDOR_FROM_DATABASE=XPEED Inc + +pci:v000014B3d00000000* + ID_PRODUCT_FROM_DATABASE=DSL NIC + +pci:v000014B4* + ID_VENDOR_FROM_DATABASE=PHILIPS Business Electronics B.V. + +pci:v000014B5* + ID_VENDOR_FROM_DATABASE=Creamware GmBH + +pci:v000014B5d00000200* + ID_PRODUCT_FROM_DATABASE=Scope + +pci:v000014B5d00000300* + ID_PRODUCT_FROM_DATABASE=Pulsar + +pci:v000014B5d00000400* + ID_PRODUCT_FROM_DATABASE=PulsarSRB + +pci:v000014B5d00000600* + ID_PRODUCT_FROM_DATABASE=Pulsar2 + +pci:v000014B5d00000800* + ID_PRODUCT_FROM_DATABASE=DSP-Board + +pci:v000014B5d00000900* + ID_PRODUCT_FROM_DATABASE=DSP-Board + +pci:v000014B5d00000A00* + ID_PRODUCT_FROM_DATABASE=DSP-Board + +pci:v000014B5d00000B00* + ID_PRODUCT_FROM_DATABASE=DSP-Board + +pci:v000014B6* + ID_VENDOR_FROM_DATABASE=Quantum Data Corp. + +pci:v000014B7* + ID_VENDOR_FROM_DATABASE=PROXIM Inc + +pci:v000014B7d00000001* + ID_PRODUCT_FROM_DATABASE=Symphony 4110 + +pci:v000014B8* + ID_VENDOR_FROM_DATABASE=Techsoft Technology Co Ltd + +pci:v000014B9* + ID_VENDOR_FROM_DATABASE=Cisco Aironet Wireless Communications + +pci:v000014B9d00000001* + ID_PRODUCT_FROM_DATABASE=PC4800 + +pci:v000014B9d00000340* + ID_PRODUCT_FROM_DATABASE=PC4800 + +pci:v000014B9d00000350* + ID_PRODUCT_FROM_DATABASE=350 series 802.11b Wireless LAN Adapter + +pci:v000014B9d00004500* + ID_PRODUCT_FROM_DATABASE=PC4500 + +pci:v000014B9d00004800* + ID_PRODUCT_FROM_DATABASE=Cisco Aironet 340 802.11b Wireless LAN Adapter/Aironet PC4800 + +pci:v000014B9d0000A504* + ID_PRODUCT_FROM_DATABASE=Cisco Aironet Wireless 802.11b + +pci:v000014B9d0000A505* + ID_PRODUCT_FROM_DATABASE=Cisco Aironet CB20a 802.11a Wireless LAN Adapter + +pci:v000014B9d0000A506* + ID_PRODUCT_FROM_DATABASE=Cisco Aironet Mini PCI b/g + +pci:v000014BA* + ID_VENDOR_FROM_DATABASE=INTERNIX Inc. + +pci:v000014BAd00000600* + ID_PRODUCT_FROM_DATABASE=ARC-PCI/22 + +pci:v000014BB* + ID_VENDOR_FROM_DATABASE=SEMTECH Corporation + +pci:v000014BC* + ID_VENDOR_FROM_DATABASE=Globespan Semiconductor Inc. + +pci:v000014BCd0000D002* + ID_PRODUCT_FROM_DATABASE=Pulsar [PCI ADSL Card] + +pci:v000014BCd0000D00F* + ID_PRODUCT_FROM_DATABASE=Pulsar [PCI ADSL Card] + +pci:v000014BD* + ID_VENDOR_FROM_DATABASE=CARDIO Control N.V. + +pci:v000014BE* + ID_VENDOR_FROM_DATABASE=L3 Communications + +pci:v000014BF* + ID_VENDOR_FROM_DATABASE=SPIDER Communications Inc. + +pci:v000014C0* + ID_VENDOR_FROM_DATABASE=COMPAL Electronics Inc + +pci:v000014C1* + ID_VENDOR_FROM_DATABASE=MYRICOM Inc. + +pci:v000014C1d00000008* + ID_PRODUCT_FROM_DATABASE=Myri-10G Dual-Protocol NIC + +pci:v000014C1d00000008sv000014C1sd00000008* + ID_PRODUCT_FROM_DATABASE=10G-PCIE-8A + +pci:v000014C1d00000008sv000014C1sd00000009* + ID_PRODUCT_FROM_DATABASE=10G-PCIE-8A (MSI-X firmware) + +pci:v000014C1d00000008sv000014C1sd0000000A* + ID_PRODUCT_FROM_DATABASE=10G-PCIE-8B + +pci:v000014C1d00008043* + ID_PRODUCT_FROM_DATABASE=Myrinet 2000 Scalable Cluster Interconnect + +pci:v000014C1d00008043sv0000103Csd00001240* + ID_PRODUCT_FROM_DATABASE=Myrinet M2L-PCI64/2-3.0 LANai 7.4 (HP OEM) + +pci:v000014C2* + ID_VENDOR_FROM_DATABASE=DTK Computer + +pci:v000014C3* + ID_VENDOR_FROM_DATABASE=MEDIATEK Corp. + +pci:v000014C4* + ID_VENDOR_FROM_DATABASE=IWASAKI Information Systems Co Ltd + +pci:v000014C5* + ID_VENDOR_FROM_DATABASE=Automation Products AB + +pci:v000014C6* + ID_VENDOR_FROM_DATABASE=Data Race Inc + +pci:v000014C7* + ID_VENDOR_FROM_DATABASE=Modular Technology Holdings Ltd + +pci:v000014C8* + ID_VENDOR_FROM_DATABASE=Turbocomm Tech. Inc. + +pci:v000014C9* + ID_VENDOR_FROM_DATABASE=ODIN Telesystems Inc + +pci:v000014CA* + ID_VENDOR_FROM_DATABASE=PE Logic Corp. + +pci:v000014CB* + ID_VENDOR_FROM_DATABASE=Billionton Systems Inc + +pci:v000014CC* + ID_VENDOR_FROM_DATABASE=NAKAYO Telecommunications Inc + +pci:v000014CD* + ID_VENDOR_FROM_DATABASE=Universal Scientific Ind. + +pci:v000014CE* + ID_VENDOR_FROM_DATABASE=Whistle Communications + +pci:v000014CF* + ID_VENDOR_FROM_DATABASE=TEK Microsystems Inc. + +pci:v000014D0* + ID_VENDOR_FROM_DATABASE=Ericsson Axe R & D + +pci:v000014D1* + ID_VENDOR_FROM_DATABASE=Computer Hi-Tech Co Ltd + +pci:v000014D2* + ID_VENDOR_FROM_DATABASE=Titan Electronics Inc + +pci:v000014D2d00008001* + ID_PRODUCT_FROM_DATABASE=VScom 010L 1 port parallel adaptor + +pci:v000014D2d00008002* + ID_PRODUCT_FROM_DATABASE=VScom 020L 2 port parallel adaptor + +pci:v000014D2d00008010* + ID_PRODUCT_FROM_DATABASE=VScom 100L 1 port serial adaptor + +pci:v000014D2d00008011* + ID_PRODUCT_FROM_DATABASE=VScom 110L 1 port serial and 1 port parallel adaptor + +pci:v000014D2d00008020* + ID_PRODUCT_FROM_DATABASE=VScom 200L 1 or 2 port serial adaptor + +pci:v000014D2d00008021* + ID_PRODUCT_FROM_DATABASE=VScom 210L 2 port serial and 1 port parallel adaptor + +pci:v000014D2d00008028* + ID_PRODUCT_FROM_DATABASE=VScom 200I/200I-SI 2-port serial adapter + +pci:v000014D2d00008040* + ID_PRODUCT_FROM_DATABASE=VScom 400L 4 port serial adaptor + +pci:v000014D2d00008043* + ID_PRODUCT_FROM_DATABASE=VScom 430L 4-port serial and 3-port parallel adapter + +pci:v000014D2d00008048* + ID_PRODUCT_FROM_DATABASE=VScom 400I 4-port serial adapter + +pci:v000014D2d00008080* + ID_PRODUCT_FROM_DATABASE=VScom 800L 8 port serial adaptor + +pci:v000014D2d00008088* + ID_PRODUCT_FROM_DATABASE=VScom 800I 8-port serial adapter + +pci:v000014D2d0000A000* + ID_PRODUCT_FROM_DATABASE=VScom 010H 1 port parallel adaptor + +pci:v000014D2d0000A001* + ID_PRODUCT_FROM_DATABASE=VScom 100H 1 port serial adaptor + +pci:v000014D2d0000A003* + ID_PRODUCT_FROM_DATABASE=VScom 400H 4 port serial adaptor + +pci:v000014D2d0000A004* + ID_PRODUCT_FROM_DATABASE=VScom 400HF1 4 port serial adaptor + +pci:v000014D2d0000A005* + ID_PRODUCT_FROM_DATABASE=VScom 200H 2 port serial adaptor + +pci:v000014D2d0000A007* + ID_PRODUCT_FROM_DATABASE=VScom PCI800EH (PCIe) 8-port serial adapter Port 1-4 + +pci:v000014D2d0000A008* + ID_PRODUCT_FROM_DATABASE=VScom PCI800EH (PCIe) 8-port serial adapter Port 5-8 + +pci:v000014D2d0000A009* + ID_PRODUCT_FROM_DATABASE=VScom PCI400EH (PCIe) 4-port serial adapter + +pci:v000014D2d0000E001* + ID_PRODUCT_FROM_DATABASE=VScom 010HV2 1 port parallel adaptor + +pci:v000014D2d0000E010* + ID_PRODUCT_FROM_DATABASE=VScom 100HV2 1 port serial adaptor + +pci:v000014D2d0000E020* + ID_PRODUCT_FROM_DATABASE=VScom 200HV2 2 port serial adaptor + +pci:v000014D3* + ID_VENDOR_FROM_DATABASE=CIRTECH (UK) Ltd + +pci:v000014D4* + ID_VENDOR_FROM_DATABASE=Panacom Technology Corp + +pci:v000014D5* + ID_VENDOR_FROM_DATABASE=Nitsuko Corporation + +pci:v000014D6* + ID_VENDOR_FROM_DATABASE=Accusys Inc + +pci:v000014D6d00006101* + ID_PRODUCT_FROM_DATABASE=ACS-61xxx, PCIe to SAS/SATA RAID HBA + +pci:v000014D6d00006201* + ID_PRODUCT_FROM_DATABASE=ACS-62xxx, External PCIe to SAS/SATA RAID controller + +pci:v000014D7* + ID_VENDOR_FROM_DATABASE=Hirakawa Hewtech Corp + +pci:v000014D8* + ID_VENDOR_FROM_DATABASE=HOPF Elektronik GmBH + +pci:v000014D9* + ID_VENDOR_FROM_DATABASE=Alliance Semiconductor Corporation + +pci:v000014D9d00000010* + ID_PRODUCT_FROM_DATABASE=AP1011/SP1011 HyperTransport-PCI Bridge [Sturgeon] + +pci:v000014D9d00009000* + ID_PRODUCT_FROM_DATABASE=AS90L10204/10208 HyperTransport to PCI-X Bridge + +pci:v000014DA* + ID_VENDOR_FROM_DATABASE=National Aerospace Laboratories + +pci:v000014DB* + ID_VENDOR_FROM_DATABASE=AFAVLAB Technology Inc + +pci:v000014DBd00002120* + ID_PRODUCT_FROM_DATABASE=TK9902 + +pci:v000014DBd00002182* + ID_PRODUCT_FROM_DATABASE=AFAVLAB Technology Inc. 8-port serial card + +pci:v000014DC* + ID_VENDOR_FROM_DATABASE=Amplicon Liveline Ltd + +pci:v000014DCd00000000* + ID_PRODUCT_FROM_DATABASE=PCI230 + +pci:v000014DCd00000001* + ID_PRODUCT_FROM_DATABASE=PCI242 + +pci:v000014DCd00000002* + ID_PRODUCT_FROM_DATABASE=PCI244 + +pci:v000014DCd00000003* + ID_PRODUCT_FROM_DATABASE=PCI247 + +pci:v000014DCd00000004* + ID_PRODUCT_FROM_DATABASE=PCI248 + +pci:v000014DCd00000005* + ID_PRODUCT_FROM_DATABASE=PCI249 + +pci:v000014DCd00000006* + ID_PRODUCT_FROM_DATABASE=PCI260 + +pci:v000014DCd00000007* + ID_PRODUCT_FROM_DATABASE=PCI224 + +pci:v000014DCd00000008* + ID_PRODUCT_FROM_DATABASE=PCI234 + +pci:v000014DCd00000009* + ID_PRODUCT_FROM_DATABASE=PCI236 + +pci:v000014DCd0000000A* + ID_PRODUCT_FROM_DATABASE=PCI272 + +pci:v000014DCd0000000B* + ID_PRODUCT_FROM_DATABASE=PCI215 + +pci:v000014DD* + ID_VENDOR_FROM_DATABASE=Boulder Design Labs Inc + +pci:v000014DE* + ID_VENDOR_FROM_DATABASE=Applied Integration Corporation + +pci:v000014DF* + ID_VENDOR_FROM_DATABASE=ASIC Communications Corp + +pci:v000014E1* + ID_VENDOR_FROM_DATABASE=INVERTEX + +pci:v000014E2* + ID_VENDOR_FROM_DATABASE=INFOLIBRIA + +pci:v000014E3* + ID_VENDOR_FROM_DATABASE=AMTELCO + +pci:v000014E4* + ID_VENDOR_FROM_DATABASE=Broadcom Corporation + +pci:v000014E4d00000576* + ID_PRODUCT_FROM_DATABASE=BCM43224 802.11a/b/g/n + +pci:v000014E4d00000800* + ID_PRODUCT_FROM_DATABASE=Sentry5 Chipcommon I/O Controller + +pci:v000014E4d00000804* + ID_PRODUCT_FROM_DATABASE=Sentry5 PCI Bridge + +pci:v000014E4d00000805* + ID_PRODUCT_FROM_DATABASE=Sentry5 MIPS32 CPU + +pci:v000014E4d00000806* + ID_PRODUCT_FROM_DATABASE=Sentry5 Ethernet Controller + +pci:v000014E4d0000080B* + ID_PRODUCT_FROM_DATABASE=Sentry5 Crypto Accelerator + +pci:v000014E4d0000080F* + ID_PRODUCT_FROM_DATABASE=Sentry5 DDR/SDR RAM Controller + +pci:v000014E4d00000811* + ID_PRODUCT_FROM_DATABASE=Sentry5 External Interface Core + +pci:v000014E4d00000816* + ID_PRODUCT_FROM_DATABASE=BCM3302 Sentry5 MIPS32 CPU + +pci:v000014E4d00001600* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5752 Gigabit Ethernet PCI Express + +pci:v000014E4d00001600sv00001028sd000001C1* + ID_PRODUCT_FROM_DATABASE=Precision 490 + +pci:v000014E4d00001600sv00001028sd000001C2* + ID_PRODUCT_FROM_DATABASE=Latitude D620 + +pci:v000014E4d00001600sv0000103Csd00003015* + ID_PRODUCT_FROM_DATABASE=PCIe LAN on Motherboard + +pci:v000014E4d00001600sv0000107Bsd00005048* + ID_PRODUCT_FROM_DATABASE=E4500 Onboard + +pci:v000014E4d00001600sv00001259sd00002705* + ID_PRODUCT_FROM_DATABASE=AT-2711FX + +pci:v000014E4d00001601* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5752M Gigabit Ethernet PCI Express + +pci:v000014E4d00001612* + ID_PRODUCT_FROM_DATABASE=BCM70012 Video Decoder [Crystal HD] + +pci:v000014E4d00001615* + ID_PRODUCT_FROM_DATABASE=BCM70015 Video Decoder [Crystal HD] + +pci:v000014E4d00001639* + ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM5709 Gigabit Ethernet + +pci:v000014E4d00001639sv00001028sd00000235* + ID_PRODUCT_FROM_DATABASE=PowerEdge R710 BCM5709 Gigabit Ethernet + +pci:v000014E4d00001639sv00001028sd00000236* + ID_PRODUCT_FROM_DATABASE=PowerEdge R610 BCM5709 Gigabit Ethernet + +pci:v000014E4d00001639sv00001028sd00000237* + ID_PRODUCT_FROM_DATABASE=PowerEdge T610 BCM5709 Gigabit Ethernet + +pci:v000014E4d00001639sv0000103Csd00007055* + ID_PRODUCT_FROM_DATABASE=NC382i Integrated Multi-port PCI Express Gigabit Server Adapter + +pci:v000014E4d00001639sv0000103Csd00007059* + ID_PRODUCT_FROM_DATABASE=NC382T PCI Express Dual Port Multifunction Gigabit Server Adapter + +pci:v000014E4d00001639sv000010A9sd00008027* + ID_PRODUCT_FROM_DATABASE=Quad port Gigabit Ethernet Controller + +pci:v000014E4d0000163A* + ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM5709S Gigabit Ethernet + +pci:v000014E4d0000163Asv00001028sd0000027B* + ID_PRODUCT_FROM_DATABASE=PowerEdge M805 Broadcom NetXtreme II BCM5709S + +pci:v000014E4d0000163Asv00001028sd0000029C* + ID_PRODUCT_FROM_DATABASE=PowerEdge M710 BCM5709S Gigabit Ethernet + +pci:v000014E4d0000163Asv0000103Csd0000171D* + ID_PRODUCT_FROM_DATABASE=NC382m Dual Port 1GbE Multifunction BL-c Adapter + +pci:v000014E4d0000163Asv0000103Csd00007056* + ID_PRODUCT_FROM_DATABASE=NC382i Integrated Quad Port PCI Express Gigabit Server Adapter + +pci:v000014E4d0000163B* + ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM5716 Gigabit Ethernet + +pci:v000014E4d0000163Bsv00001028sd0000028C* + ID_PRODUCT_FROM_DATABASE=PowerEdge R410 BCM5716 Gigabit Ethernet + +pci:v000014E4d0000163Bsv00001028sd0000028D* + ID_PRODUCT_FROM_DATABASE=PowerEdge T410 BCM5716 Gigabit Ethernet + +pci:v000014E4d0000163Bsv00001028sd000002F1* + ID_PRODUCT_FROM_DATABASE=PowerEdge R510 BCM5716 Gigabit Ethernet + +pci:v000014E4d0000163C* + ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM5716S Gigabit Ethernet + +pci:v000014E4d0000163D* + ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM57811 10-Gigabit Ethernet + +pci:v000014E4d0000163E* + ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM57811 10 Gigabit Ethernet Multi Function + +pci:v000014E4d0000163F* + ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM57811 10-Gigabit Ethernet Virtual Function + +pci:v000014E4d00001641* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM57787 Gigabit Ethernet PCIe + +pci:v000014E4d00001642* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM57764 Gigabit Ethernet PCIe + +pci:v000014E4d00001643* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5725 Gigabit Ethernet PCIe + +pci:v000014E4d00001644* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5700 Gigabit Ethernet + +pci:v000014E4d00001644sv00001014sd00000277* + ID_PRODUCT_FROM_DATABASE=Broadcom Vigil B5700 1000Base-T + +pci:v000014E4d00001644sv00001028sd000000D1* + ID_PRODUCT_FROM_DATABASE=Broadcom BCM5700 + +pci:v000014E4d00001644sv00001028sd00000106* + ID_PRODUCT_FROM_DATABASE=Broadcom BCM5700 + +pci:v000014E4d00001644sv00001028sd00000109* + ID_PRODUCT_FROM_DATABASE=Broadcom BCM5700 1000Base-T + +pci:v000014E4d00001644sv00001028sd0000010A* + ID_PRODUCT_FROM_DATABASE=Broadcom BCM5700 1000BaseTX + +pci:v000014E4d00001644sv000010B7sd00001000* + ID_PRODUCT_FROM_DATABASE=3C996-T 1000Base-T + +pci:v000014E4d00001644sv000010B7sd00001001* + ID_PRODUCT_FROM_DATABASE=3C996B-T 1000Base-T + +pci:v000014E4d00001644sv000010B7sd00001002* + ID_PRODUCT_FROM_DATABASE=3C996C-T 1000Base-T + +pci:v000014E4d00001644sv000010B7sd00001003* + ID_PRODUCT_FROM_DATABASE=3C997-T 1000Base-T Dual Port + +pci:v000014E4d00001644sv000010B7sd00001004* + ID_PRODUCT_FROM_DATABASE=3C996-SX 1000Base-SX + +pci:v000014E4d00001644sv000010B7sd00001005* + ID_PRODUCT_FROM_DATABASE=3C997-SX 1000Base-SX Dual Port + +pci:v000014E4d00001644sv000010B7sd00001008* + ID_PRODUCT_FROM_DATABASE=3C942 Gigabit LOM (31X31) + +pci:v000014E4d00001644sv000014E4sd00000002* + ID_PRODUCT_FROM_DATABASE=NetXtreme 1000Base-SX + +pci:v000014E4d00001644sv000014E4sd00000003* + ID_PRODUCT_FROM_DATABASE=NetXtreme 1000Base-SX + +pci:v000014E4d00001644sv000014E4sd00000004* + ID_PRODUCT_FROM_DATABASE=NetXtreme 1000Base-T + +pci:v000014E4d00001644sv000014E4sd00001028* + ID_PRODUCT_FROM_DATABASE=NetXtreme 1000BaseTX + +pci:v000014E4d00001644sv000014E4sd00001644* + ID_PRODUCT_FROM_DATABASE=BCM5700 1000Base-T + +pci:v000014E4d00001645* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5701 Gigabit Ethernet + +pci:v000014E4d00001645sv00000E11sd0000007C* + ID_PRODUCT_FROM_DATABASE=NC7770 Gigabit Server Adapter (PCI-X, 10/100/1000-T) + +pci:v000014E4d00001645sv00000E11sd0000007D* + ID_PRODUCT_FROM_DATABASE=NC6770 Gigabit Server Adapter (PCI-X, 1000-SX) + +pci:v000014E4d00001645sv00000E11sd00000085* + ID_PRODUCT_FROM_DATABASE=NC7780 Gigabit Server Adapter (embedded, WOL) + +pci:v000014E4d00001645sv00000E11sd00000099* + ID_PRODUCT_FROM_DATABASE=NC7780 Gigabit Server Adapter (embedded, WOL) + +pci:v000014E4d00001645sv00000E11sd0000009A* + ID_PRODUCT_FROM_DATABASE=NC7770 Gigabit Server Adapter (PCI-X, 10/100/1000-T) + +pci:v000014E4d00001645sv00000E11sd000000C1* + ID_PRODUCT_FROM_DATABASE=NC6770 Gigabit Server Adapter (PCI-X, 1000-SX) + +pci:v000014E4d00001645sv00001028sd00000121* + ID_PRODUCT_FROM_DATABASE=Broadcom BCM5701 1000Base-T + +pci:v000014E4d00001645sv0000103Csd0000128A* + ID_PRODUCT_FROM_DATABASE=BCM5701 1000Base-T (HP, OEM 3COM) + +pci:v000014E4d00001645sv0000103Csd0000128B* + ID_PRODUCT_FROM_DATABASE=1000Base-SX (PCI) [A7073A] + +pci:v000014E4d00001645sv0000103Csd000012A4* + ID_PRODUCT_FROM_DATABASE=Core Lan 1000Base-T + +pci:v000014E4d00001645sv0000103Csd000012C1* + ID_PRODUCT_FROM_DATABASE=IOX Core Lan 1000Base-T [A7109AX] + +pci:v000014E4d00001645sv0000103Csd00001300* + ID_PRODUCT_FROM_DATABASE=Core LAN/SCSI Combo [A6794A] + +pci:v000014E4d00001645sv000010A9sd00008010* + ID_PRODUCT_FROM_DATABASE=IO9/IO10 Gigabit Ethernet (Copper) + +pci:v000014E4d00001645sv000010A9sd00008011* + ID_PRODUCT_FROM_DATABASE=Gigabit Ethernet (Copper) + +pci:v000014E4d00001645sv000010A9sd00008012* + ID_PRODUCT_FROM_DATABASE=Gigabit Ethernet (Fiber) + +pci:v000014E4d00001645sv000010B7sd00001004* + ID_PRODUCT_FROM_DATABASE=3C996-SX 1000Base-SX + +pci:v000014E4d00001645sv000010B7sd00001006* + ID_PRODUCT_FROM_DATABASE=3C996B-T 1000Base-T + +pci:v000014E4d00001645sv000010B7sd00001007* + ID_PRODUCT_FROM_DATABASE=3C1000-T 1000Base-T + +pci:v000014E4d00001645sv000010B7sd00001008* + ID_PRODUCT_FROM_DATABASE=3C940-BR01 1000Base-T + +pci:v000014E4d00001645sv000014E4sd00000001* + ID_PRODUCT_FROM_DATABASE=BCM5701 1000Base-T + +pci:v000014E4d00001645sv000014E4sd00000005* + ID_PRODUCT_FROM_DATABASE=BCM5701 1000Base-T + +pci:v000014E4d00001645sv000014E4sd00000006* + ID_PRODUCT_FROM_DATABASE=BCM5701 1000Base-T + +pci:v000014E4d00001645sv000014E4sd00000007* + ID_PRODUCT_FROM_DATABASE=BCM5701 1000Base-SX + +pci:v000014E4d00001645sv000014E4sd00000008* + ID_PRODUCT_FROM_DATABASE=BCM5701 1000Base-T + +pci:v000014E4d00001645sv000014E4sd00001645* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5701 Gigabit Ethernet + +pci:v000014E4d00001645sv000014E4sd00008008* + ID_PRODUCT_FROM_DATABASE=BCM5701 1000Base-T + +pci:v000014E4d00001646* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5702 Gigabit Ethernet + +pci:v000014E4d00001646sv00000E11sd000000BB* + ID_PRODUCT_FROM_DATABASE=NC7760 1000BaseTX + +pci:v000014E4d00001646sv00001028sd00000126* + ID_PRODUCT_FROM_DATABASE=Broadcom BCM5702 1000BaseTX + +pci:v000014E4d00001646sv000014E4sd00008009* + ID_PRODUCT_FROM_DATABASE=BCM5702 1000BaseTX + +pci:v000014E4d00001647* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5703 Gigabit Ethernet + +pci:v000014E4d00001647sv00000E11sd00000099* + ID_PRODUCT_FROM_DATABASE=NC7780 1000BaseTX + +pci:v000014E4d00001647sv00000E11sd0000009A* + ID_PRODUCT_FROM_DATABASE=NC7770 1000BaseTX + +pci:v000014E4d00001647sv000010A9sd00008010* + ID_PRODUCT_FROM_DATABASE=SGI IO9 Gigabit Ethernet (Copper) + +pci:v000014E4d00001647sv000014E4sd00000009* + ID_PRODUCT_FROM_DATABASE=BCM5703 1000BaseTX + +pci:v000014E4d00001647sv000014E4sd0000000A* + ID_PRODUCT_FROM_DATABASE=BCM5703 1000BaseSX + +pci:v000014E4d00001647sv000014E4sd0000000B* + ID_PRODUCT_FROM_DATABASE=BCM5703 1000BaseTX + +pci:v000014E4d00001647sv000014E4sd00008009* + ID_PRODUCT_FROM_DATABASE=BCM5703 1000BaseTX + +pci:v000014E4d00001647sv000014E4sd0000800A* + ID_PRODUCT_FROM_DATABASE=BCM5703 1000BaseTX + +pci:v000014E4d00001648* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5704 Gigabit Ethernet + +pci:v000014E4d00001648sv00000E11sd000000CF* + ID_PRODUCT_FROM_DATABASE=NC7772 Gigabit Server Adapter (PCI-X, 10,100,1000-T) + +pci:v000014E4d00001648sv00000E11sd000000D0* + ID_PRODUCT_FROM_DATABASE=NC7782 Gigabit Server Adapter (PCI-X, 10,100,1000-T) + +pci:v000014E4d00001648sv00000E11sd000000D1* + ID_PRODUCT_FROM_DATABASE=NC7783 Gigabit Server Adapter (PCI-X, 10,100,1000-T) + +pci:v000014E4d00001648sv00001028sd0000014A* + ID_PRODUCT_FROM_DATABASE=PowerEdge 1750 + +pci:v000014E4d00001648sv00001028sd00000170* + ID_PRODUCT_FROM_DATABASE=PowerEdge 6850 Broadcom NetXtreme BCM5704 + +pci:v000014E4d00001648sv0000103Csd0000310F* + ID_PRODUCT_FROM_DATABASE=NC7782 Gigabit Server Adapter (PCI-X, 10,100,1000-T) + +pci:v000014E4d00001648sv000010A9sd00008013* + ID_PRODUCT_FROM_DATABASE=Dual Port Gigabit Ethernet (PCI-X,Copper) + +pci:v000014E4d00001648sv000010A9sd00008018* + ID_PRODUCT_FROM_DATABASE=Dual Port Gigabit Ethernet (A330) + +pci:v000014E4d00001648sv000010A9sd0000801A* + ID_PRODUCT_FROM_DATABASE=Dual Port Gigabit Ethernet (IA-blade) + +pci:v000014E4d00001648sv000010A9sd0000801B* + ID_PRODUCT_FROM_DATABASE=Quad Port Gigabit Ethernet (PCI-E,Copper) + +pci:v000014E4d00001648sv000010B7sd00002000* + ID_PRODUCT_FROM_DATABASE=3C998-T Dual Port 10/100/1000 PCI-X + +pci:v000014E4d00001648sv000010B7sd00003000* + ID_PRODUCT_FROM_DATABASE=3C999-T Quad Port 10/100/1000 PCI-X + +pci:v000014E4d00001648sv00001166sd00001648* + ID_PRODUCT_FROM_DATABASE=NetXtreme CIOB-E 1000Base-T + +pci:v000014E4d00001648sv00001734sd0000100B* + ID_PRODUCT_FROM_DATABASE=PRIMERGY RX/TX series onboard LAN + +pci:v000014E4d00001649* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5704S_2 Gigabit Ethernet + +pci:v000014E4d0000164A* + ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM5706 Gigabit Ethernet + +pci:v000014E4d0000164Asv0000103Csd00001709* + ID_PRODUCT_FROM_DATABASE=NC371i Integrated PCI-X Multifunction Gigabit Server Adapter + +pci:v000014E4d0000164Asv0000103Csd00003070* + ID_PRODUCT_FROM_DATABASE=NC380T PCI Express Dual Port Multifunction Gigabit Server Adapter + +pci:v000014E4d0000164Asv0000103Csd00003101* + ID_PRODUCT_FROM_DATABASE=NC370T MultifuNCtion Gigabit Server Adapter + +pci:v000014E4d0000164Asv0000103Csd00003106* + ID_PRODUCT_FROM_DATABASE=NC370i Multifunction Gigabit Server Adapter + +pci:v000014E4d0000164C* + ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM5708 Gigabit Ethernet + +pci:v000014E4d0000164Csv00001028sd000001F0* + ID_PRODUCT_FROM_DATABASE=PowerEdge R900 Broadcom NetXtreme II BCM5708 + +pci:v000014E4d0000164Csv00001028sd00000205* + ID_PRODUCT_FROM_DATABASE=PowerEdge 2970 Broadcom NetXtreme II BCM5708 + +pci:v000014E4d0000164Csv00001028sd0000020B* + ID_PRODUCT_FROM_DATABASE=PowerEdge T605 Broadcom NetXtreme II BCM5708 + +pci:v000014E4d0000164Csv00001028sd00000221* + ID_PRODUCT_FROM_DATABASE=PowerEdge R805 Broadcom NetXtreme II BCM5708 + +pci:v000014E4d0000164Csv00001028sd00000223* + ID_PRODUCT_FROM_DATABASE=PowerEdge R905 Broadcom NetXtreme II BCM5708 + +pci:v000014E4d0000164Csv00001028sd00001F12* + ID_PRODUCT_FROM_DATABASE=PowerEdge R805/R905 Broadcom NetXtreme II BCM5708 + +pci:v000014E4d0000164Csv0000103Csd00007037* + ID_PRODUCT_FROM_DATABASE=NC373T PCI Express Multifunction Gigabit Server Adapter + +pci:v000014E4d0000164Csv0000103Csd00007038* + ID_PRODUCT_FROM_DATABASE=NC373i Integrated Multifunction Gigabit Server Adapter + +pci:v000014E4d0000164Csv0000103Csd00007045* + ID_PRODUCT_FROM_DATABASE=NC374m PCI Express Dual Port Multifunction Gigabit Server Adapter + +pci:v000014E4d0000164D* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5702FE Gigabit Ethernet + +pci:v000014E4d0000164E* + ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM57710 10-Gigabit PCIe [Everest] + +pci:v000014E4d0000164Esv0000103Csd0000171C* + ID_PRODUCT_FROM_DATABASE=NC532m Dual Port 10GbE Multifunction BL-C Adapter + +pci:v000014E4d0000164Esv0000103Csd00007058* + ID_PRODUCT_FROM_DATABASE=NC532i Dual Port 10GbE Multifunction BL-C Adapter + +pci:v000014E4d0000164F* + ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM57711 10-Gigabit PCIe + +pci:v000014E4d00001650* + ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM57711E 10-Gigabit PCIe + +pci:v000014E4d00001650sv0000103Csd0000171C* + ID_PRODUCT_FROM_DATABASE=NC532m Dual Port 10GbE Multifunction BL-C Adapter + +pci:v000014E4d00001650sv0000103Csd00007058* + ID_PRODUCT_FROM_DATABASE=NC532i Dual Port 10GbE Multifunction BL-C Adapter + +pci:v000014E4d00001653* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5705 Gigabit Ethernet + +pci:v000014E4d00001653sv00000E11sd000000E3* + ID_PRODUCT_FROM_DATABASE=NC7761 Gigabit Server Adapter + +pci:v000014E4d00001654* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5705_2 Gigabit Ethernet + +pci:v000014E4d00001654sv00000E11sd000000E3* + ID_PRODUCT_FROM_DATABASE=NC7761 Gigabit Server Adapter + +pci:v000014E4d00001654sv0000103Csd00003100* + ID_PRODUCT_FROM_DATABASE=NC1020 ProLiant Gigabit Server Adapter 32 PCI + +pci:v000014E4d00001654sv0000103Csd00003226* + ID_PRODUCT_FROM_DATABASE=NC150T 4-port Gigabit Combo Switch & Adapter + +pci:v000014E4d00001655* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5717 Gigabit Ethernet PCIe + +pci:v000014E4d00001656* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5718 Gigabit Ethernet PCIe + +pci:v000014E4d00001657* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5719 Gigabit Ethernet PCIe + +pci:v000014E4d00001659* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5721 Gigabit Ethernet PCI Express + +pci:v000014E4d00001659sv00001014sd000002C6* + ID_PRODUCT_FROM_DATABASE=eServer xSeries server mainboard + +pci:v000014E4d00001659sv00001028sd000001E6* + ID_PRODUCT_FROM_DATABASE=PowerEdge 860 + +pci:v000014E4d00001659sv00001028sd0000023C* + ID_PRODUCT_FROM_DATABASE=PowerEdge R200 Broadcom NetXtreme BCM5721 + +pci:v000014E4d00001659sv0000103Csd0000170B* + ID_PRODUCT_FROM_DATABASE=NC320m PCI Express Dual Port Gigabit Server Adapter + +pci:v000014E4d00001659sv0000103Csd00007031* + ID_PRODUCT_FROM_DATABASE=NC320T PCIe Gigabit Server Adapter + +pci:v000014E4d00001659sv0000103Csd00007032* + ID_PRODUCT_FROM_DATABASE=NC320i PCIe Gigabit Server Adapter + +pci:v000014E4d00001659sv00001734sd00001061* + ID_PRODUCT_FROM_DATABASE=PRIMERGY RX/TX S2 series onboard LAN + +pci:v000014E4d0000165A* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5722 Gigabit Ethernet PCI Express + +pci:v000014E4d0000165Asv00001014sd00000378* + ID_PRODUCT_FROM_DATABASE=IBM System x3350 (Machine type 4192) + +pci:v000014E4d0000165Asv00001028sd0000020F* + ID_PRODUCT_FROM_DATABASE=PowerEdge R300 Broadcom NetXtreme 5722 + +pci:v000014E4d0000165Asv00001028sd00000210* + ID_PRODUCT_FROM_DATABASE=PowerEdge T300 Broadcom NetXtreme 5722 + +pci:v000014E4d0000165Asv00001028sd00000225* + ID_PRODUCT_FROM_DATABASE=PowerEdge T105 Broadcom NetXtreme 5722 + +pci:v000014E4d0000165Asv0000103Csd00007051* + ID_PRODUCT_FROM_DATABASE=NC105i PCIe Gigabit Server Adapter + +pci:v000014E4d0000165Asv0000103Csd00007052* + ID_PRODUCT_FROM_DATABASE=NC105T PCIe Gigabit Server Adapter + +pci:v000014E4d0000165B* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5723 Gigabit Ethernet PCIe + +pci:v000014E4d0000165Bsv0000103Csd0000705D* + ID_PRODUCT_FROM_DATABASE=NC107i Integrated PCI Express Gigabit Server Adapter + +pci:v000014E4d0000165C* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5724 Gigabit Ethernet PCIe + +pci:v000014E4d0000165D* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5705M Gigabit Ethernet + +pci:v000014E4d0000165Dsv00001028sd0000865D* + ID_PRODUCT_FROM_DATABASE=Latitude D400 + +pci:v000014E4d0000165Dsv000014E4sd0000165D* + ID_PRODUCT_FROM_DATABASE=Dell Latitude D600 + +pci:v000014E4d0000165E* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5705M_2 Gigabit Ethernet + +pci:v000014E4d0000165Esv0000103Csd0000088C* + ID_PRODUCT_FROM_DATABASE=NC8000 laptop + +pci:v000014E4d0000165Esv0000103Csd00000890* + ID_PRODUCT_FROM_DATABASE=NC6000 laptop + +pci:v000014E4d0000165Esv0000103Csd0000099C* + ID_PRODUCT_FROM_DATABASE=NX6110/NC6120 + +pci:v000014E4d0000165Esv000010CFsd00001279* + ID_PRODUCT_FROM_DATABASE=LifeBook E8010D + +pci:v000014E4d0000165F* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5720 Gigabit Ethernet PCIe + +pci:v000014E4d00001662* + ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM57712 10 Gigabit Ethernet + +pci:v000014E4d00001663* + ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM57712 10 Gigabit Ethernet Multi Function + +pci:v000014E4d00001665* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5717 Gigabit Ethernet PCIe + +pci:v000014E4d00001668* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5714 Gigabit Ethernet + +pci:v000014E4d00001668sv0000103Csd00007039* + ID_PRODUCT_FROM_DATABASE=NC324i PCIe Dual Port Gigabit Server Adapter + +pci:v000014E4d00001669* + ID_PRODUCT_FROM_DATABASE=NetXtreme 5714S Gigabit Ethernet + +pci:v000014E4d0000166A* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5780 Gigabit Ethernet + +pci:v000014E4d0000166Asv0000103Csd00007035* + ID_PRODUCT_FROM_DATABASE=NC325i Integrated Dual port PCIe Express Gigabit Server Adapter + +pci:v000014E4d0000166B* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5780S Gigabit Ethernet + +pci:v000014E4d0000166E* + ID_PRODUCT_FROM_DATABASE=570x 10/100 Integrated Controller + +pci:v000014E4d0000166F* + ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM57712 10 Gigabit Ethernet Virtual Function + +pci:v000014E4d00001672* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5754M Gigabit Ethernet PCI Express + +pci:v000014E4d00001673* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5755M Gigabit Ethernet PCI Express + +pci:v000014E4d00001674* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5756ME Gigabit Ethernet PCI Express + +pci:v000014E4d00001677* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5751 Gigabit Ethernet PCI Express + +pci:v000014E4d00001677sv00001028sd00000176* + ID_PRODUCT_FROM_DATABASE=Dimension XPS Gen 4 + +pci:v000014E4d00001677sv00001028sd00000177* + ID_PRODUCT_FROM_DATABASE=Dimension 8400 + +pci:v000014E4d00001677sv00001028sd00000179* + ID_PRODUCT_FROM_DATABASE=Optiplex GX280 + +pci:v000014E4d00001677sv00001028sd00000182* + ID_PRODUCT_FROM_DATABASE=Latitude D610 + +pci:v000014E4d00001677sv00001028sd00000187* + ID_PRODUCT_FROM_DATABASE=Precision M70 + +pci:v000014E4d00001677sv00001028sd000001A8* + ID_PRODUCT_FROM_DATABASE=Precision 380 + +pci:v000014E4d00001677sv00001028sd000001AD* + ID_PRODUCT_FROM_DATABASE=OptiPlex GX620 + +pci:v000014E4d00001677sv0000103Csd00003006* + ID_PRODUCT_FROM_DATABASE=DC7100 SFF(DX878AV) + +pci:v000014E4d00001677sv00001462sd0000028C* + ID_PRODUCT_FROM_DATABASE=915P/G Neo2 + +pci:v000014E4d00001677sv00001734sd0000105D* + ID_PRODUCT_FROM_DATABASE=Scenic W620 + +pci:v000014E4d00001678* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5715 Gigabit Ethernet + +pci:v000014E4d00001678sv0000103Csd0000703E* + ID_PRODUCT_FROM_DATABASE=NC326i PCIe Dual Port Gigabit Server Adapter + +pci:v000014E4d00001679* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5715S Gigabit Ethernet + +pci:v000014E4d00001679sv0000103Csd00001707* + ID_PRODUCT_FROM_DATABASE=NC326m PCIe Dual Port Adapter + +pci:v000014E4d00001679sv0000103Csd0000170C* + ID_PRODUCT_FROM_DATABASE=NC325m PCIe Quad Port Adapter + +pci:v000014E4d00001679sv0000103Csd0000703C* + ID_PRODUCT_FROM_DATABASE=NC326i PCIe Dual Port Gigabit Server Adapter + +pci:v000014E4d0000167A* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5754 Gigabit Ethernet PCI Express + +pci:v000014E4d0000167Asv00001028sd000001DA* + ID_PRODUCT_FROM_DATABASE=OptiPlex 745 + +pci:v000014E4d0000167Asv00001028sd000001DE* + ID_PRODUCT_FROM_DATABASE=Precision 390 + +pci:v000014E4d0000167Asv00001028sd000001DF* + ID_PRODUCT_FROM_DATABASE=PowerEdge SC440 + +pci:v000014E4d0000167Asv00001028sd00000214* + ID_PRODUCT_FROM_DATABASE=Precision T3400 + +pci:v000014E4d0000167Asv00001028sd0000021E* + ID_PRODUCT_FROM_DATABASE=Precision T5400 + +pci:v000014E4d0000167B* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5755 Gigabit Ethernet PCI Express + +pci:v000014E4d0000167Bsv0000103Csd0000280A* + ID_PRODUCT_FROM_DATABASE=DC5750 Microtower + +pci:v000014E4d0000167D* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5751M Gigabit Ethernet PCI Express + +pci:v000014E4d0000167Dsv00001014sd00000577* + ID_PRODUCT_FROM_DATABASE=ThinkPad Z60t + +pci:v000014E4d0000167Dsv0000103Csd00000934* + ID_PRODUCT_FROM_DATABASE=HP nx8220 + +pci:v000014E4d0000167Dsv0000103Csd00000940* + ID_PRODUCT_FROM_DATABASE=HP Compaq nw8240 Mobile Workstation + +pci:v000014E4d0000167Dsv000017AAsd00002081* + ID_PRODUCT_FROM_DATABASE=ThinkPad R60e + +pci:v000014E4d0000167E* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5751F Fast Ethernet PCI Express + +pci:v000014E4d0000167F* + ID_PRODUCT_FROM_DATABASE=NetLink BCM5787F Fast Ethernet PCI Express + +pci:v000014E4d00001680* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5761e Gigabit Ethernet PCIe + +pci:v000014E4d00001681* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5761 Gigabit Ethernet PCIe + +pci:v000014E4d00001682* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM57762 Gigabit Ethernet PCIe + +pci:v000014E4d00001683* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM57767 Gigabit Ethernet PCIe + +pci:v000014E4d00001684* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5764M Gigabit Ethernet PCIe + +pci:v000014E4d00001685* + ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM57500S Gigabit Ethernet + +pci:v000014E4d00001686* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM57766 Gigabit Ethernet PCIe + +pci:v000014E4d00001687* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5762 Gigabit Ethernet PCIe + +pci:v000014E4d00001688* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5761 10/100/1000BASE-T Ethernet + +pci:v000014E4d00001688sv00001259sd00002708* + ID_PRODUCT_FROM_DATABASE=AT-2712 FX + +pci:v000014E4d0000168A* + ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM57800 1/10 Gigabit Ethernet + +pci:v000014E4d0000168Asv00001028sd00001F5C* + ID_PRODUCT_FROM_DATABASE=BCM57800 10-Gigabit Ethernet + +pci:v000014E4d0000168Asv00001028sd00001F5D* + ID_PRODUCT_FROM_DATABASE=BCM57800 10-Gigabit Ethernet + +pci:v000014E4d0000168Asv00001028sd00001F67* + ID_PRODUCT_FROM_DATABASE=BCM57800 1-Gigabit Ethernet + +pci:v000014E4d0000168Asv00001028sd00001F68* + ID_PRODUCT_FROM_DATABASE=BCM57800 1-Gigabit Ethernet + +pci:v000014E4d0000168D* + ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM57840 10/20 Gigabit Ethernet + +pci:v000014E4d0000168E* + ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM57810 10 Gigabit Ethernet + +pci:v000014E4d0000168Esv0000103Csd00001798* + ID_PRODUCT_FROM_DATABASE=Flex-10 10Gb 2-port 530FLB Adapter [Meru] + +pci:v000014E4d00001690* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM57760 Gigabit Ethernet PCIe + +pci:v000014E4d00001691* + ID_PRODUCT_FROM_DATABASE=NetLink BCM57788 Gigabit Ethernet PCIe + +pci:v000014E4d00001691sv00001028sd000004AA* + ID_PRODUCT_FROM_DATABASE=XPS 8300 + +pci:v000014E4d00001692* + ID_PRODUCT_FROM_DATABASE=NetLink BCM57780 Gigabit Ethernet PCIe + +pci:v000014E4d00001692sv00001025sd0000033D* + ID_PRODUCT_FROM_DATABASE=Aspire 7740G + +pci:v000014E4d00001693* + ID_PRODUCT_FROM_DATABASE=NetLink BCM5787M Gigabit Ethernet PCI Express + +pci:v000014E4d00001693sv00001025sd00000121* + ID_PRODUCT_FROM_DATABASE=Aspire 5920G + +pci:v000014E4d00001693sv0000103Csd000030C0* + ID_PRODUCT_FROM_DATABASE=6710b + +pci:v000014E4d00001694* + ID_PRODUCT_FROM_DATABASE=NetLink BCM57790 Gigabit Ethernet PCIe + +pci:v000014E4d00001696* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5782 Gigabit Ethernet + +pci:v000014E4d00001696sv0000103Csd000012BC* + ID_PRODUCT_FROM_DATABASE=d530 CMT (DG746A) + +pci:v000014E4d00001696sv000014E4sd0000000D* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5782 1000Base-T + +pci:v000014E4d00001698* + ID_PRODUCT_FROM_DATABASE=NetLink BCM5784M Gigabit Ethernet PCIe + +pci:v000014E4d00001699* + ID_PRODUCT_FROM_DATABASE=NetLink BCM5785 Gigabit Ethernet + +pci:v000014E4d0000169A* + ID_PRODUCT_FROM_DATABASE=NetLink BCM5786 Gigabit Ethernet PCI Express + +pci:v000014E4d0000169B* + ID_PRODUCT_FROM_DATABASE=NetLink BCM5787 Gigabit Ethernet PCI Express + +pci:v000014E4d0000169C* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5788 Gigabit Ethernet + +pci:v000014E4d0000169Csv0000103Csd0000308B* + ID_PRODUCT_FROM_DATABASE=MX6125 + +pci:v000014E4d0000169Csv0000103Csd000030A1* + ID_PRODUCT_FROM_DATABASE=NC2400 + +pci:v000014E4d0000169Csv0000144Dsd0000C018* + ID_PRODUCT_FROM_DATABASE=X20 + +pci:v000014E4d0000169Csv00001462sd0000590C* + ID_PRODUCT_FROM_DATABASE=KT6 Delta-FIS2R (MS-6590) + +pci:v000014E4d0000169D* + ID_PRODUCT_FROM_DATABASE=NetLink BCM5789 Gigabit Ethernet PCI Express + +pci:v000014E4d000016A0* + ID_PRODUCT_FROM_DATABASE=NetLink BCM5785 Fast Ethernet + +pci:v000014E4d000016A1* + ID_PRODUCT_FROM_DATABASE=BCM57840 NetXtreme II 10 Gigabit Ethernet + +pci:v000014E4d000016A2* + ID_PRODUCT_FROM_DATABASE=BCM57840 NetXtreme II 10/20-Gigabit Ethernet + +pci:v000014E4d000016A4* + ID_PRODUCT_FROM_DATABASE=BCM57840 NetXtreme II Ethernet Multi Function + +pci:v000014E4d000016A5* + ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM57800 1/10 Gigabit Ethernet Multi Function + +pci:v000014E4d000016A5sv00001028sd00001F5C* + ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM57800 10-Gigabit Ethernet Multi Function + +pci:v000014E4d000016A5sv00001028sd00001F5D* + ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM57800 10-Gigabit Ethernet Multi Function + +pci:v000014E4d000016A5sv00001028sd00001F67* + ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM57800 1-Gigabit Ethernet Multi Function + +pci:v000014E4d000016A5sv00001028sd00001F68* + ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM57800 1-Gigabit Ethernet Multi Function + +pci:v000014E4d000016A6* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5702X Gigabit Ethernet + +pci:v000014E4d000016A6sv00000E11sd000000BB* + ID_PRODUCT_FROM_DATABASE=NC7760 Gigabit Server Adapter (PCI-X, 10/100/1000-T) + +pci:v000014E4d000016A6sv00001028sd00000126* + ID_PRODUCT_FROM_DATABASE=BCM5702 1000Base-T + +pci:v000014E4d000016A6sv000014E4sd0000000C* + ID_PRODUCT_FROM_DATABASE=BCM5702 1000Base-T + +pci:v000014E4d000016A6sv000014E4sd00008009* + ID_PRODUCT_FROM_DATABASE=BCM5702 1000Base-T + +pci:v000014E4d000016A7* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5703X Gigabit Ethernet + +pci:v000014E4d000016A7sv00000E11sd000000CA* + ID_PRODUCT_FROM_DATABASE=NC7771 Gigabit Server Adapter (PCI-X, 10,100,1000-T) + +pci:v000014E4d000016A7sv00000E11sd000000CB* + ID_PRODUCT_FROM_DATABASE=NC7781 Gigabit Server Adapter (PCI-X, 10,100,1000-T) + +pci:v000014E4d000016A7sv00001014sd0000026F* + ID_PRODUCT_FROM_DATABASE=eServer xSeries server mainboard + +pci:v000014E4d000016A7sv000014E4sd00000009* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5703 1000Base-T + +pci:v000014E4d000016A7sv000014E4sd0000000A* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5703 1000Base-SX + +pci:v000014E4d000016A7sv000014E4sd0000000B* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5703 1000Base-T + +pci:v000014E4d000016A7sv000014E4sd0000800A* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5703 1000Base-T + +pci:v000014E4d000016A8* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5704S Gigabit Ethernet + +pci:v000014E4d000016A8sv0000103Csd0000132B* + ID_PRODUCT_FROM_DATABASE=PCI-X 1000Mbps Dual-port Built-in + +pci:v000014E4d000016A8sv000010A9sd00008014* + ID_PRODUCT_FROM_DATABASE=Dual Port Gigabit Ethernet (PCI-X,Fiber) + +pci:v000014E4d000016A8sv000010A9sd0000801C* + ID_PRODUCT_FROM_DATABASE=Quad Port Gigabit Ethernet (PCI-E,Fiber) + +pci:v000014E4d000016A8sv000010B7sd00002001* + ID_PRODUCT_FROM_DATABASE=3C998-SX Dual Port 1000-SX PCI-X + +pci:v000014E4d000016A9* + ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM57800 1/10 Gigabit Ethernet Virtual Function + +pci:v000014E4d000016A9sv00001028sd00001F5C* + ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM57800 10-Gigabit Ethernet Virtual Function + +pci:v000014E4d000016A9sv00001028sd00001F5D* + ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM57800 10-Gigabit Ethernet Virtual Function + +pci:v000014E4d000016A9sv00001028sd00001F67* + ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM57800 1-Gigabit Ethernet Virtual Function + +pci:v000014E4d000016A9sv00001028sd00001F68* + ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM57800 1-Gigabit Ethernet Virtual Function + +pci:v000014E4d000016AA* + ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM5706S Gigabit Ethernet + +pci:v000014E4d000016AAsv0000103Csd00003102* + ID_PRODUCT_FROM_DATABASE=NC370F MultifuNCtion Gigabit Server Adapter + +pci:v000014E4d000016AAsv0000103Csd0000310C* + ID_PRODUCT_FROM_DATABASE=NC370i Multifunction Gigabit Server Adapter + +pci:v000014E4d000016AB* + ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM57840 10/20 Gigabit Ethernet Multi Function + +pci:v000014E4d000016AC* + ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM5708S Gigabit Ethernet + +pci:v000014E4d000016ACsv00001014sd00000304* + ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM5708S Gigabit Ethernet + +pci:v000014E4d000016ACsv00001028sd000001BB* + ID_PRODUCT_FROM_DATABASE=PowerEdge 1955 Broadcom NetXtreme II BCM5708S + +pci:v000014E4d000016ACsv00001028sd0000020C* + ID_PRODUCT_FROM_DATABASE=PowerEdge M605 Broadcom NetXtreme II BCM5708S + +pci:v000014E4d000016ACsv0000103Csd00001706* + ID_PRODUCT_FROM_DATABASE=NC373m Multifunction Gigabit Server Adapter + +pci:v000014E4d000016ACsv0000103Csd00007038* + ID_PRODUCT_FROM_DATABASE=NC373i PCI Express Multifunction Gigabit Server Adapter + +pci:v000014E4d000016ACsv0000103Csd0000703B* + ID_PRODUCT_FROM_DATABASE=NC373i Integrated Multifunction Gigabit Server Adapter + +pci:v000014E4d000016ACsv0000103Csd0000703D* + ID_PRODUCT_FROM_DATABASE=NC373F PCI Express Multifunction Gigabit Server Adapter + +pci:v000014E4d000016AD* + ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM57840 10/20 Gigabit Ethernet Virtual Function + +pci:v000014E4d000016AE* + ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM57810 10 Gigabit Ethernet Multi Function + +pci:v000014E4d000016AF* + ID_PRODUCT_FROM_DATABASE=NetXtreme II BCM57810 10 Gigabit Ethernet Virtual Function + +pci:v000014E4d000016B0* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM57761 Gigabit Ethernet PCIe + +pci:v000014E4d000016B1* + ID_PRODUCT_FROM_DATABASE=NetLink BCM57781 Gigabit Ethernet PCIe + +pci:v000014E4d000016B2* + ID_PRODUCT_FROM_DATABASE=NetLink BCM57791 Gigabit Ethernet PCIe + +pci:v000014E4d000016B3* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM57786 Gigabit Ethernet PCIe + +pci:v000014E4d000016B4* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM57765 Gigabit Ethernet PCIe + +pci:v000014E4d000016B5* + ID_PRODUCT_FROM_DATABASE=NetLink BCM57785 Gigabit Ethernet PCIe + +pci:v000014E4d000016B6* + ID_PRODUCT_FROM_DATABASE=NetLink BCM57795 Gigabit Ethernet PCIe + +pci:v000014E4d000016B7* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM57782 Gigabit Ethernet PCIe + +pci:v000014E4d000016BC* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM57765 Memory Card Reader + +pci:v000014E4d000016C6* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5702A3 Gigabit Ethernet + +pci:v000014E4d000016C6sv000010B7sd00001100* + ID_PRODUCT_FROM_DATABASE=3C1000B-T 10/100/1000 PCI + +pci:v000014E4d000016C6sv000014E4sd0000000C* + ID_PRODUCT_FROM_DATABASE=BCM5702 1000Base-T + +pci:v000014E4d000016C6sv000014E4sd00008009* + ID_PRODUCT_FROM_DATABASE=BCM5702 1000Base-T + +pci:v000014E4d000016C7* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5703 Gigabit Ethernet + +pci:v000014E4d000016C7sv00000E11sd000000CA* + ID_PRODUCT_FROM_DATABASE=NC7771 Gigabit Server Adapter (PCI-X, 10,100,1000-T) + +pci:v000014E4d000016C7sv00000E11sd000000CB* + ID_PRODUCT_FROM_DATABASE=NC7781 Gigabit Server Adapter (PCI-X, 10,100,1000-T) + +pci:v000014E4d000016C7sv0000103Csd000012C3* + ID_PRODUCT_FROM_DATABASE=Combo FC/GigE-SX [A9782A] + +pci:v000014E4d000016C7sv0000103Csd000012CA* + ID_PRODUCT_FROM_DATABASE=Combo FC/GigE-T [A9784A] + +pci:v000014E4d000016C7sv0000103Csd00001321* + ID_PRODUCT_FROM_DATABASE=Core I/O LAN/SCSI Combo [AB314A] + +pci:v000014E4d000016C7sv000014E4sd00000009* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5703 1000Base-T + +pci:v000014E4d000016C7sv000014E4sd0000000A* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5703 1000Base-SX + +pci:v000014E4d000016DD* + ID_PRODUCT_FROM_DATABASE=NetLink BCM5781 Gigabit Ethernet PCI Express + +pci:v000014E4d000016F7* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5753 Gigabit Ethernet PCI Express + +pci:v000014E4d000016FD* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5753M Gigabit Ethernet PCI Express + +pci:v000014E4d000016FDsv0000103Csd0000309F* + ID_PRODUCT_FROM_DATABASE=Compaq nx9420 Notebook + +pci:v000014E4d000016FDsv0000103Csd000030A3* + ID_PRODUCT_FROM_DATABASE=Compaq nw8440 + +pci:v000014E4d000016FE* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5753F Fast Ethernet PCI Express + +pci:v000014E4d0000170C* + ID_PRODUCT_FROM_DATABASE=BCM4401-B0 100Base-TX + +pci:v000014E4d0000170Csv00001028sd00000188* + ID_PRODUCT_FROM_DATABASE=Inspiron 6000 laptop + +pci:v000014E4d0000170Csv00001028sd0000018D* + ID_PRODUCT_FROM_DATABASE=Inspiron 700m/710m + +pci:v000014E4d0000170Csv00001028sd00000196* + ID_PRODUCT_FROM_DATABASE=Inspiron 5160 + +pci:v000014E4d0000170Csv00001028sd000001AF* + ID_PRODUCT_FROM_DATABASE=Inspiron 6400 + +pci:v000014E4d0000170Csv00001028sd000001CD* + ID_PRODUCT_FROM_DATABASE=Inspiron 9400 Laptop + +pci:v000014E4d0000170Csv00001028sd000001D7* + ID_PRODUCT_FROM_DATABASE=XPS M1210 + +pci:v000014E4d0000170Csv00001028sd000001D8* + ID_PRODUCT_FROM_DATABASE=Inspiron E1405 + +pci:v000014E4d0000170Csv0000103Csd0000099C* + ID_PRODUCT_FROM_DATABASE=NX6110/NC6120 + +pci:v000014E4d0000170Csv0000103Csd000030A2* + ID_PRODUCT_FROM_DATABASE=NX7300 laptop + +pci:v000014E4d0000170Csv000014E4sd0000170C* + ID_PRODUCT_FROM_DATABASE=HP Compaq 6720t Mobile Thin Client + +pci:v000014E4d0000170D* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5901 100Base-TX + +pci:v000014E4d0000170Dsv00001014sd00000545* + ID_PRODUCT_FROM_DATABASE=ThinkPad R40e + +pci:v000014E4d0000170E* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5901 100Base-TX + +pci:v000014E4d00001712* + ID_PRODUCT_FROM_DATABASE=NetLink BCM5906 Fast Ethernet PCI Express + +pci:v000014E4d00001713* + ID_PRODUCT_FROM_DATABASE=NetLink BCM5906M Fast Ethernet PCI Express + +pci:v000014E4d00001713sv00001028sd000001F3* + ID_PRODUCT_FROM_DATABASE=Inspiron 1420 + +pci:v000014E4d00001713sv00001028sd00000209* + ID_PRODUCT_FROM_DATABASE=XPS M1330 + +pci:v000014E4d00001713sv0000103Csd000030C0* + ID_PRODUCT_FROM_DATABASE=Compaq 6710b + +pci:v000014E4d00001713sv000017AAsd00003A23* + ID_PRODUCT_FROM_DATABASE=IdeaPad S10e + +pci:v000014E4d00003352* + ID_PRODUCT_FROM_DATABASE=BCM3352 + +pci:v000014E4d00003360* + ID_PRODUCT_FROM_DATABASE=BCM3360 + +pci:v000014E4d00004210* + ID_PRODUCT_FROM_DATABASE=BCM4210 iLine10 HomePNA 2.0 + +pci:v000014E4d00004211* + ID_PRODUCT_FROM_DATABASE=BCM4211 iLine10 HomePNA 2.0 + V.90 56k modem + +pci:v000014E4d00004212* + ID_PRODUCT_FROM_DATABASE=BCM4212 v.90 56k modem + +pci:v000014E4d00004220* + ID_PRODUCT_FROM_DATABASE=802-11b/g Wireless PCI controller, packaged as a Linksys WPC54G ver 1.2 PCMCIA card + +pci:v000014E4d00004222* + ID_PRODUCT_FROM_DATABASE=NetXtreme BCM5753M Gigabit Ethernet PCI Express + +pci:v000014E4d00004301* + ID_PRODUCT_FROM_DATABASE=BCM4301 802.11b Wireless LAN Controller + +pci:v000014E4d00004301sv00001028sd00000407* + ID_PRODUCT_FROM_DATABASE=TrueMobile 1180 Onboard WLAN + +pci:v000014E4d00004301sv00001043sd00000120* + ID_PRODUCT_FROM_DATABASE=WL-103b Wireless LAN PC Card + +pci:v000014E4d00004301sv000016A5sd00001602* + ID_PRODUCT_FROM_DATABASE=B-300 802.11b Wireless CardBus Adapter + +pci:v000014E4d00004301sv00001737sd00004301* + ID_PRODUCT_FROM_DATABASE=WMP11 v2.7 802.11b Wireless-B PCI Adapter + +pci:v000014E4d00004305* + ID_PRODUCT_FROM_DATABASE=BCM4307 V.90 56k Modem + +pci:v000014E4d00004306* + ID_PRODUCT_FROM_DATABASE=BCM4306 802.11bg Wireless LAN controller + +pci:v000014E4d00004307* + ID_PRODUCT_FROM_DATABASE=BCM4306 802.11bg Wireless LAN Controller + +pci:v000014E4d00004310* + ID_PRODUCT_FROM_DATABASE=BCM4310 Chipcommon I/OController + +pci:v000014E4d00004311* + ID_PRODUCT_FROM_DATABASE=BCM4311 802.11b/g WLAN + +pci:v000014E4d00004311sv00001028sd00000007* + ID_PRODUCT_FROM_DATABASE=Wireless 1390 WLAN Mini-Card + +pci:v000014E4d00004311sv00001028sd00000008* + ID_PRODUCT_FROM_DATABASE=Wireless 1390 WLAN ExpressCard + +pci:v000014E4d00004311sv0000103Csd00001363* + ID_PRODUCT_FROM_DATABASE=BCM4311 802.11b/g Wireless LAN Controller + +pci:v000014E4d00004311sv0000103Csd00001364* + ID_PRODUCT_FROM_DATABASE=BCM4311 802.11b/g Wireless LAN Controller + +pci:v000014E4d00004311sv0000103Csd00001365* + ID_PRODUCT_FROM_DATABASE=BCM4311 802.11b/g Wireless LAN Controller + +pci:v000014E4d00004311sv0000103Csd00001374* + ID_PRODUCT_FROM_DATABASE=BCM4311 802.11b/g Wireless LAN Controller + +pci:v000014E4d00004311sv0000103Csd00001375* + ID_PRODUCT_FROM_DATABASE=BCM4311 802.11b/g Wireless LAN Controller + +pci:v000014E4d00004311sv0000103Csd00001376* + ID_PRODUCT_FROM_DATABASE=BCM4311 802.11b/g Wireless LAN Controller + +pci:v000014E4d00004311sv0000103Csd00001377* + ID_PRODUCT_FROM_DATABASE=BCM4311 802.11b/g Wireless LAN Controller + +pci:v000014E4d00004311sv0000103Csd0000137F* + ID_PRODUCT_FROM_DATABASE=BCM4322 802.11a/b/g/n Wireless LAN Controller + +pci:v000014E4d00004311sv0000103Csd00001380* + ID_PRODUCT_FROM_DATABASE=BCM4322 802.11a/b/g/n Wireless LAN Controller + +pci:v000014E4d00004311sv000014E4sd00004311* + ID_PRODUCT_FROM_DATABASE=BCM94311MCG + +pci:v000014E4d00004312* + ID_PRODUCT_FROM_DATABASE=BCM4311 802.11a/b/g + +pci:v000014E4d00004312sv00001028sd00000007* + ID_PRODUCT_FROM_DATABASE=Wireless 1490 Dual Band WLAN Mini-Card + +pci:v000014E4d00004312sv00001028sd00000008* + ID_PRODUCT_FROM_DATABASE=Wireless 1490 Dual Band WLAN ExpressCard + +pci:v000014E4d00004312sv0000103Csd0000135A* + ID_PRODUCT_FROM_DATABASE=Broadcom 802.11a/b/g WLAN + +pci:v000014E4d00004312sv0000103Csd0000135F* + ID_PRODUCT_FROM_DATABASE=Broadcom 802.11a/b/g WLAN + +pci:v000014E4d00004312sv0000103Csd00001360* + ID_PRODUCT_FROM_DATABASE=Broadcom 802.11a/b/g WLAN + +pci:v000014E4d00004312sv0000103Csd00001361* + ID_PRODUCT_FROM_DATABASE=Broadcom 802.11a/b/g WLAN + +pci:v000014E4d00004312sv0000103Csd00001362* + ID_PRODUCT_FROM_DATABASE=Broadcom 802.11a/b/g WLAN + +pci:v000014E4d00004312sv0000103Csd00001370* + ID_PRODUCT_FROM_DATABASE=Broadcom 802.11a/b/g WLAN + +pci:v000014E4d00004312sv0000103Csd00001371* + ID_PRODUCT_FROM_DATABASE=Broadcom 802.11a/b/g WLAN + +pci:v000014E4d00004312sv0000103Csd00001372* + ID_PRODUCT_FROM_DATABASE=Broadcom 802.11a/b/g WLAN + +pci:v000014E4d00004312sv0000103Csd00001373* + ID_PRODUCT_FROM_DATABASE=Broadcom 802.11a/b/g WLAN + +pci:v000014E4d00004312sv0000103Csd000030B5* + ID_PRODUCT_FROM_DATABASE=Presario V3242AU + +pci:v000014E4d00004312sv00001371sd0000103C* + ID_PRODUCT_FROM_DATABASE=Broadcom 802.11 Multiband-netwerkadapter(6715s) + +pci:v000014E4d00004313* + ID_PRODUCT_FROM_DATABASE=BCM4311 802.11a + +pci:v000014E4d00004315* + ID_PRODUCT_FROM_DATABASE=BCM4312 802.11b/g LP-PHY + +pci:v000014E4d00004315sv00001028sd0000000B* + ID_PRODUCT_FROM_DATABASE=Wireless 1395 WLAN Mini-Card + +pci:v000014E4d00004315sv00001028sd0000000C* + ID_PRODUCT_FROM_DATABASE=Wireless 1397 WLAN Mini-Card + +pci:v000014E4d00004315sv0000103Csd0000137C* + ID_PRODUCT_FROM_DATABASE=BCM4312 802.11b/g Wireless LAN Controller + +pci:v000014E4d00004315sv0000103Csd0000137D* + ID_PRODUCT_FROM_DATABASE=BCM4312 802.11b/g Wireless LAN Controller + +pci:v000014E4d00004315sv0000103Csd00001507* + ID_PRODUCT_FROM_DATABASE=U98Z049.00 Wireless Mini PCIe Card + +pci:v000014E4d00004315sv0000105Bsd0000E003* + ID_PRODUCT_FROM_DATABASE=T77H030.00 Wireless Mini PCIe Card + +pci:v000014E4d00004315sv0000105Bsd0000E01B* + ID_PRODUCT_FROM_DATABASE=T77H106.00 Wireless Half-size Mini PCIe Card + +pci:v000014E4d00004318* + ID_PRODUCT_FROM_DATABASE=BCM4318 [AirForce One 54g] 802.11g Wireless LAN Controller + +pci:v000014E4d00004318sv00001028sd00000005* + ID_PRODUCT_FROM_DATABASE=Wireless 1370 WLAN Mini-PCI Card + +pci:v000014E4d00004318sv00001028sd00000006* + ID_PRODUCT_FROM_DATABASE=Wireless 1370 WLAN PC Card + +pci:v000014E4d00004318sv0000103Csd00001355* + ID_PRODUCT_FROM_DATABASE=Broadcom 802.11b/g WLAN + +pci:v000014E4d00004318sv0000103Csd00001356* + ID_PRODUCT_FROM_DATABASE=Broadcom 802.11b/g WLAN + +pci:v000014E4d00004318sv0000103Csd00001357* + ID_PRODUCT_FROM_DATABASE=Broadcom 802.11b/g WLAN + +pci:v000014E4d00004318sv00001043sd0000100F* + ID_PRODUCT_FROM_DATABASE=WL-138G v2 / WL-138gE / WL-100gE + +pci:v000014E4d00004318sv00001043sd0000120F* + ID_PRODUCT_FROM_DATABASE=A6U notebook embedded card + +pci:v000014E4d00004318sv00001154sd00000355* + ID_PRODUCT_FROM_DATABASE=Buffalo WLI2-PCI-G54S High Speed Mode Wireless Adapter + +pci:v000014E4d00004318sv00001468sd00000311* + ID_PRODUCT_FROM_DATABASE=Aspire 3022WLMi, 5024WLMi, 5020 + +pci:v000014E4d00004318sv00001468sd00000312* + ID_PRODUCT_FROM_DATABASE=TravelMate 2410 + +pci:v000014E4d00004318sv000014E4sd00000449* + ID_PRODUCT_FROM_DATABASE=Gateway 7510GX + +pci:v000014E4d00004318sv000016ECsd00000119* + ID_PRODUCT_FROM_DATABASE=U.S.Robotics Wireless MAXg PC Card + +pci:v000014E4d00004318sv00001737sd00000042* + ID_PRODUCT_FROM_DATABASE=WMP54GS v1.1 802.11g Wireless-G PCI Adapter with SpeedBooster + +pci:v000014E4d00004318sv00001737sd00000048* + ID_PRODUCT_FROM_DATABASE=WPC54G v3 802.11g Wireless-G Notebook Adapter + +pci:v000014E4d00004318sv00001737sd00000049* + ID_PRODUCT_FROM_DATABASE=WPC54GS v2 802.11g Wireless-G Notebook Adapter with SpeedBooster + +pci:v000014E4d00004318sv00001799sd00007000* + ID_PRODUCT_FROM_DATABASE=F5D7000 v4000 Wireless G Desktop Card + +pci:v000014E4d00004318sv00001799sd00007001* + ID_PRODUCT_FROM_DATABASE=F5D7001 v2000 Wireless G Plus Desktop Card + +pci:v000014E4d00004318sv00001799sd00007010* + ID_PRODUCT_FROM_DATABASE=F5D7010 v4000 Wireless G Notebook Card + +pci:v000014E4d00004318sv00001799sd00007011* + ID_PRODUCT_FROM_DATABASE=F5D7011 v2000 High-Speed Mode Wireless G Notebook Card + +pci:v000014E4d00004319* + ID_PRODUCT_FROM_DATABASE=BCM4318 [AirForce 54g] 802.11a/b/g PCI Express Transceiver + +pci:v000014E4d00004319sv00001028sd00000005* + ID_PRODUCT_FROM_DATABASE=Wireless 1470 Dual Band WLAN Mini-PCI Card + +pci:v000014E4d00004319sv00001028sd00000006* + ID_PRODUCT_FROM_DATABASE=Wireless 1470 Dual Band WLAN PC Card + +pci:v000014E4d00004319sv0000103Csd00001358* + ID_PRODUCT_FROM_DATABASE=Broadcom 802.11a/b/g WLAN + +pci:v000014E4d00004319sv0000103Csd00001359* + ID_PRODUCT_FROM_DATABASE=Broadcom 802.11a/b/g WLAN + +pci:v000014E4d00004319sv0000103Csd0000135A* + ID_PRODUCT_FROM_DATABASE=Broadcom 802.11a/b/g WLAN + +pci:v000014E4d00004320* + ID_PRODUCT_FROM_DATABASE=BCM4306 802.11b/g Wireless LAN Controller + +pci:v000014E4d00004320sv00001028sd00000001* + ID_PRODUCT_FROM_DATABASE=TrueMobile 1300 WLAN Mini-PCI Card + +pci:v000014E4d00004320sv00001028sd00000002* + ID_PRODUCT_FROM_DATABASE=TrueMobile 1300 WLAN PC Card + +pci:v000014E4d00004320sv00001028sd00000003* + ID_PRODUCT_FROM_DATABASE=Wireless 1350 WLAN Mini-PCI Card + +pci:v000014E4d00004320sv00001028sd00000004* + ID_PRODUCT_FROM_DATABASE=Wireless 1350 WLAN PC Card + +pci:v000014E4d00004320sv0000103Csd000012F4* + ID_PRODUCT_FROM_DATABASE=Broadcom 802.11b/g WLAN + +pci:v000014E4d00004320sv0000103Csd000012F8* + ID_PRODUCT_FROM_DATABASE=Broadcom 802.11b/g WLAN + +pci:v000014E4d00004320sv0000103Csd000012FA* + ID_PRODUCT_FROM_DATABASE=Broadcom 802.11b/g WLAN + +pci:v000014E4d00004320sv0000103Csd000012FB* + ID_PRODUCT_FROM_DATABASE=Broadcom 802.11b/g WLAN + +pci:v000014E4d00004320sv00001043sd0000100F* + ID_PRODUCT_FROM_DATABASE=WL-100G + +pci:v000014E4d00004320sv00001057sd00007025* + ID_PRODUCT_FROM_DATABASE=WN825G + +pci:v000014E4d00004320sv0000106Bsd0000004E* + ID_PRODUCT_FROM_DATABASE=AirPort Extreme + +pci:v000014E4d00004320sv00001154sd00000330* + ID_PRODUCT_FROM_DATABASE=Buffalo WLI2-PCI-G54S High Speed Mode Wireless Desktop Adapter + +pci:v000014E4d00004320sv0000144Fsd00007050* + ID_PRODUCT_FROM_DATABASE=eMachines M6805 802.11g Built-in Wireless + +pci:v000014E4d00004320sv0000144Fsd00007051* + ID_PRODUCT_FROM_DATABASE=Sonnet Aria Extreme PCI + +pci:v000014E4d00004320sv00001737sd00000013* + ID_PRODUCT_FROM_DATABASE=WMP54G v1 802.11g PCI Adapter + +pci:v000014E4d00004320sv00001737sd00000014* + ID_PRODUCT_FROM_DATABASE=WMP54G v2 802.11g PCI Adapter + +pci:v000014E4d00004320sv00001737sd00000015* + ID_PRODUCT_FROM_DATABASE=WMP54GS v1.0 802.11g Wireless-G PCI Adapter with SpeedBooster + +pci:v000014E4d00004320sv00001737sd00004320* + ID_PRODUCT_FROM_DATABASE=WPC54G v1 / WPC54GS v1 802.11g Wireless-G Notebook Adapter + +pci:v000014E4d00004320sv00001799sd00007000* + ID_PRODUCT_FROM_DATABASE=F5D7000 v1000 Wireless G Desktop Card + +pci:v000014E4d00004320sv00001799sd00007001* + ID_PRODUCT_FROM_DATABASE=F5D7001 v1000 Wireless G Plus Desktop Card + +pci:v000014E4d00004320sv00001799sd00007010* + ID_PRODUCT_FROM_DATABASE=F5D7010 v1000 Wireless G Notebook Card + +pci:v000014E4d00004320sv00001799sd00007011* + ID_PRODUCT_FROM_DATABASE=F5D7011 v1000 High-Speed Mode Wireless G Notebook Card + +pci:v000014E4d00004320sv0000185Fsd00001220* + ID_PRODUCT_FROM_DATABASE=TravelMate 290E WLAN Mini-PCI Card + +pci:v000014E4d00004321* + ID_PRODUCT_FROM_DATABASE=BCM4321 802.11a Wireless Network Controller + +pci:v000014E4d00004322* + ID_PRODUCT_FROM_DATABASE=BCM4322 802.11bgn Wireless Network Controller + +pci:v000014E4d00004324* + ID_PRODUCT_FROM_DATABASE=BCM4306 802.11a/b/g + +pci:v000014E4d00004324sv00001028sd00000001* + ID_PRODUCT_FROM_DATABASE=Truemobile 1400 + +pci:v000014E4d00004324sv00001028sd00000002* + ID_PRODUCT_FROM_DATABASE=TrueMobile 1400 Dual Band WLAN PC Card + +pci:v000014E4d00004324sv00001028sd00000003* + ID_PRODUCT_FROM_DATABASE=Truemobile 1450 MiniPCI + +pci:v000014E4d00004324sv00001028sd00000004* + ID_PRODUCT_FROM_DATABASE=Wireless 1450 Dual Band WLAN PC Card + +pci:v000014E4d00004324sv0000103Csd000012F9* + ID_PRODUCT_FROM_DATABASE=Broadcom 802.11a/b/g WLAN + +pci:v000014E4d00004324sv0000103Csd000012FC* + ID_PRODUCT_FROM_DATABASE=Broadcom 802.11a/b/g WLAN + +pci:v000014E4d00004325* + ID_PRODUCT_FROM_DATABASE=BCM4306 802.11bg Wireless Network Controller + +pci:v000014E4d00004325sv00001414sd00000003* + ID_PRODUCT_FROM_DATABASE=Wireless Notebook Adapter MN-720 + +pci:v000014E4d00004325sv00001414sd00000004* + ID_PRODUCT_FROM_DATABASE=Wireless PCI Adapter MN-730 + +pci:v000014E4d00004326* + ID_PRODUCT_FROM_DATABASE=BCM4307 Chipcommon I/O Controller? + +pci:v000014E4d00004328* + ID_PRODUCT_FROM_DATABASE=BCM4321 802.11a/b/g/n + +pci:v000014E4d00004328sv00001028sd00000009* + ID_PRODUCT_FROM_DATABASE=Wireless 1500 Draft 802.11n WLAN Mini-Card + +pci:v000014E4d00004328sv00001028sd0000000A* + ID_PRODUCT_FROM_DATABASE=Wireless 1500 Draft 802.11n WLAN Mini-card + +pci:v000014E4d00004328sv0000103Csd00001366* + ID_PRODUCT_FROM_DATABASE=BCM4321 802.11a/b/g/n Wireless LAN Controller + +pci:v000014E4d00004328sv0000103Csd00001367* + ID_PRODUCT_FROM_DATABASE=BCM4321 802.11a/b/g/n Wireless LAN Controller + +pci:v000014E4d00004328sv0000103Csd00001368* + ID_PRODUCT_FROM_DATABASE=BCM4321 802.11a/b/g/n Wireless LAN Controller + +pci:v000014E4d00004328sv0000103Csd00001369* + ID_PRODUCT_FROM_DATABASE=BCM4321 802.11a/b/g/n Wireless LAN Controller + +pci:v000014E4d00004328sv000014E4sd00004328* + ID_PRODUCT_FROM_DATABASE=BCM4328 802.11a/b/g/n + +pci:v000014E4d00004328sv00001737sd00000066* + ID_PRODUCT_FROM_DATABASE=WPC600N v1 802.11a/b/g/n Wireless-N CardBus Adapter + +pci:v000014E4d00004328sv00001737sd00000068* + ID_PRODUCT_FROM_DATABASE=WEC600N v1 802.11a/b/g/n Wireless-N ExpressCard + +pci:v000014E4d00004329* + ID_PRODUCT_FROM_DATABASE=BCM4321 802.11b/g/n + +pci:v000014E4d00004329sv00001385sd00007B00* + ID_PRODUCT_FROM_DATABASE=WN511B RangeMax NEXT Wireless Notebook Adapter + +pci:v000014E4d00004329sv00001385sd00007D00* + ID_PRODUCT_FROM_DATABASE=WN311B RangeMax Next 270 Mbps Wireless PCI Adapter + +pci:v000014E4d00004329sv00001737sd00000058* + ID_PRODUCT_FROM_DATABASE=WPC300N v1 Wireless-N Notebook Adapter + +pci:v000014E4d0000432A* + ID_PRODUCT_FROM_DATABASE=BCM4321 802.11an Wireless Network Controller + +pci:v000014E4d0000432B* + ID_PRODUCT_FROM_DATABASE=BCM4322 802.11a/b/g/n Wireless LAN Controller + +pci:v000014E4d0000432Bsv00001028sd0000000D* + ID_PRODUCT_FROM_DATABASE=Wireless 1510 Wireless-N WLAN Mini-Card + +pci:v000014E4d0000432Bsv0000106Bsd0000008E* + ID_PRODUCT_FROM_DATABASE=AirPort Extreme + +pci:v000014E4d0000432C* + ID_PRODUCT_FROM_DATABASE=BCM4322 802.11b/g/n + +pci:v000014E4d0000432Csv00001799sd0000D311* + ID_PRODUCT_FROM_DATABASE=Dynex DX-NNBX 802.11n WLAN Cardbus Card + +pci:v000014E4d0000432D* + ID_PRODUCT_FROM_DATABASE=BCM4322 802.11an Wireless Network Controller + +pci:v000014E4d00004331* + ID_PRODUCT_FROM_DATABASE=BCM4331 802.11a/b/g/n + +pci:v000014E4d00004331sv0000106Bsd000000D6* + ID_PRODUCT_FROM_DATABASE=AirPort Extreme + +pci:v000014E4d00004333* + ID_PRODUCT_FROM_DATABASE=Serial (EDGE/GPRS modem part of Option GT Combo Edge) + +pci:v000014E4d00004344* + ID_PRODUCT_FROM_DATABASE=EDGE/GPRS data and 802.11b/g combo cardbus [GC89] + +pci:v000014E4d00004353* + ID_PRODUCT_FROM_DATABASE=BCM43224 802.11a/b/g/n + +pci:v000014E4d00004353sv00001028sd0000000E* + ID_PRODUCT_FROM_DATABASE=Wireless 1520 Half-size Mini PCIe Card + +pci:v000014E4d00004353sv0000103Csd00001509* + ID_PRODUCT_FROM_DATABASE=WMIB-275N Half-size Mini PCIe Card + +pci:v000014E4d00004357* + ID_PRODUCT_FROM_DATABASE=BCM43225 802.11b/g/n + +pci:v000014E4d00004357sv0000105Bsd0000E021* + ID_PRODUCT_FROM_DATABASE=T77H103.00 Wireless Half-size Mini PCIe Card + +pci:v000014E4d00004358* + ID_PRODUCT_FROM_DATABASE=BCM43227 802.11b/g/n + +pci:v000014E4d00004359* + ID_PRODUCT_FROM_DATABASE=BCM43228 802.11a/b/g/n + +pci:v000014E4d00004359sv00001028sd00000011* + ID_PRODUCT_FROM_DATABASE=Wireless 1530 Half-size Mini PCIe Card + +pci:v000014E4d00004359sv0000103Csd0000182C* + ID_PRODUCT_FROM_DATABASE=BCM943228HM4L 802.11a/b/g/n 2x2 Wi-Fi Adapter + +pci:v000014E4d00004365* + ID_PRODUCT_FROM_DATABASE=BCM43142 802.11b/g/n + +pci:v000014E4d00004365sv00001028sd00000016* + ID_PRODUCT_FROM_DATABASE=Wireless 1704 802.11n + BT 4.0 + +pci:v000014E4d00004401* + ID_PRODUCT_FROM_DATABASE=BCM4401 100Base-T + +pci:v000014E4d00004401sv00001025sd00000035* + ID_PRODUCT_FROM_DATABASE=TravelMate 660 + +pci:v000014E4d00004401sv0000103Csd000008B0* + ID_PRODUCT_FROM_DATABASE=tc1100 tablet + +pci:v000014E4d00004401sv00001043sd000080A8* + ID_PRODUCT_FROM_DATABASE=A7V8X motherboard + +pci:v000014E4d00004402* + ID_PRODUCT_FROM_DATABASE=BCM4402 Integrated 10/100BaseT + +pci:v000014E4d00004403* + ID_PRODUCT_FROM_DATABASE=BCM4402 V.90 56k Modem + +pci:v000014E4d00004410* + ID_PRODUCT_FROM_DATABASE=BCM4413 iLine32 HomePNA 2.0 + +pci:v000014E4d00004411* + ID_PRODUCT_FROM_DATABASE=BCM4413 V.90 56k modem + +pci:v000014E4d00004412* + ID_PRODUCT_FROM_DATABASE=BCM4412 10/100BaseT + +pci:v000014E4d00004430* + ID_PRODUCT_FROM_DATABASE=BCM44xx CardBus iLine32 HomePNA 2.0 + +pci:v000014E4d00004432* + ID_PRODUCT_FROM_DATABASE=BCM4432 CardBus 10/100BaseT + +pci:v000014E4d00004610* + ID_PRODUCT_FROM_DATABASE=BCM4610 Sentry5 PCI to SB Bridge + +pci:v000014E4d00004611* + ID_PRODUCT_FROM_DATABASE=BCM4610 Sentry5 iLine32 HomePNA 1.0 + +pci:v000014E4d00004612* + ID_PRODUCT_FROM_DATABASE=BCM4610 Sentry5 V.90 56k Modem + +pci:v000014E4d00004613* + ID_PRODUCT_FROM_DATABASE=BCM4610 Sentry5 Ethernet Controller + +pci:v000014E4d00004614* + ID_PRODUCT_FROM_DATABASE=BCM4610 Sentry5 External Interface + +pci:v000014E4d00004615* + ID_PRODUCT_FROM_DATABASE=BCM4610 Sentry5 USB Controller + +pci:v000014E4d00004704* + ID_PRODUCT_FROM_DATABASE=BCM4704 PCI to SB Bridge + +pci:v000014E4d00004705* + ID_PRODUCT_FROM_DATABASE=BCM4704 Sentry5 802.11b Wireless LAN Controller + +pci:v000014E4d00004706* + ID_PRODUCT_FROM_DATABASE=BCM4704 Sentry5 Ethernet Controller + +pci:v000014E4d00004707* + ID_PRODUCT_FROM_DATABASE=BCM4704 Sentry5 USB Controller + +pci:v000014E4d00004708* + ID_PRODUCT_FROM_DATABASE=BCM4704 Crypto Accelerator + +pci:v000014E4d00004710* + ID_PRODUCT_FROM_DATABASE=BCM4710 Sentry5 PCI to SB Bridge + +pci:v000014E4d00004711* + ID_PRODUCT_FROM_DATABASE=BCM47xx Sentry5 iLine32 HomePNA 2.0 + +pci:v000014E4d00004712* + ID_PRODUCT_FROM_DATABASE=BCM47xx V.92 56k modem + +pci:v000014E4d00004713* + ID_PRODUCT_FROM_DATABASE=Sentry5 Ethernet Controller + +pci:v000014E4d00004714* + ID_PRODUCT_FROM_DATABASE=BCM47xx Sentry5 External Interface + +pci:v000014E4d00004715* + ID_PRODUCT_FROM_DATABASE=Sentry5 USB Controller + +pci:v000014E4d00004716* + ID_PRODUCT_FROM_DATABASE=BCM47xx Sentry5 USB Host Controller + +pci:v000014E4d00004717* + ID_PRODUCT_FROM_DATABASE=BCM47xx Sentry5 USB Device Controller + +pci:v000014E4d00004718* + ID_PRODUCT_FROM_DATABASE=Sentry5 Crypto Accelerator + +pci:v000014E4d00004719* + ID_PRODUCT_FROM_DATABASE=BCM47xx/53xx RoboSwitch Core + +pci:v000014E4d00004720* + ID_PRODUCT_FROM_DATABASE=BCM4712 MIPS CPU + +pci:v000014E4d00004727* + ID_PRODUCT_FROM_DATABASE=BCM4313 802.11b/g/n Wireless LAN Controller + +pci:v000014E4d00004727sv00001028sd00000010* + ID_PRODUCT_FROM_DATABASE=Inspiron M5010 / XPS 8300 + +pci:v000014E4d00005365* + ID_PRODUCT_FROM_DATABASE=BCM5365P Sentry5 Host Bridge + +pci:v000014E4d00005600* + ID_PRODUCT_FROM_DATABASE=BCM5600 StrataSwitch 24+2 Ethernet Switch Controller + +pci:v000014E4d00005605* + ID_PRODUCT_FROM_DATABASE=BCM5605 StrataSwitch 24+2 Ethernet Switch Controller + +pci:v000014E4d00005615* + ID_PRODUCT_FROM_DATABASE=BCM5615 StrataSwitch 24+2 Ethernet Switch Controller + +pci:v000014E4d00005625* + ID_PRODUCT_FROM_DATABASE=BCM5625 StrataSwitch 24+2 Ethernet Switch Controller + +pci:v000014E4d00005645* + ID_PRODUCT_FROM_DATABASE=BCM5645 StrataSwitch 24+2 Ethernet Switch Controller + +pci:v000014E4d00005670* + ID_PRODUCT_FROM_DATABASE=BCM5670 8-Port 10GE Ethernet Switch Fabric + +pci:v000014E4d00005680* + ID_PRODUCT_FROM_DATABASE=BCM5680 G-Switch 8 Port Gigabit Ethernet Switch Controller + +pci:v000014E4d00005690* + ID_PRODUCT_FROM_DATABASE=BCM5690 12-port Multi-Layer Gigabit Ethernet Switch + +pci:v000014E4d00005691* + ID_PRODUCT_FROM_DATABASE=BCM5691 GE/10GE 8+2 Gigabit Ethernet Switch Controller + +pci:v000014E4d00005692* + ID_PRODUCT_FROM_DATABASE=BCM5692 12-port Multi-Layer Gigabit Ethernet Switch + +pci:v000014E4d00005695* + ID_PRODUCT_FROM_DATABASE=BCM5695 12-port + HiGig Multi-Layer Gigabit Ethernet Switch + +pci:v000014E4d00005698* + ID_PRODUCT_FROM_DATABASE=BCM5698 12-port Multi-Layer Gigabit Ethernet Switch + +pci:v000014E4d00005820* + ID_PRODUCT_FROM_DATABASE=BCM5820 Crypto Accelerator + +pci:v000014E4d00005821* + ID_PRODUCT_FROM_DATABASE=BCM5821 Crypto Accelerator + +pci:v000014E4d00005822* + ID_PRODUCT_FROM_DATABASE=BCM5822 Crypto Accelerator + +pci:v000014E4d00005823* + ID_PRODUCT_FROM_DATABASE=BCM5823 Crypto Accelerator + +pci:v000014E4d00005824* + ID_PRODUCT_FROM_DATABASE=BCM5824 Crypto Accelerator + +pci:v000014E4d00005840* + ID_PRODUCT_FROM_DATABASE=BCM5840 Crypto Accelerator + +pci:v000014E4d00005841* + ID_PRODUCT_FROM_DATABASE=BCM5841 Crypto Accelerator + +pci:v000014E4d00005850* + ID_PRODUCT_FROM_DATABASE=BCM5850 Crypto Accelerator + +pci:v000014E4d0000B800* + ID_PRODUCT_FROM_DATABASE=BCM56800 StrataXGS 10GE Switch Controller + +pci:v000014E5* + ID_VENDOR_FROM_DATABASE=Pixelfusion Ltd + +pci:v000014E6* + ID_VENDOR_FROM_DATABASE=SHINING Technology Inc + +pci:v000014E7* + ID_VENDOR_FROM_DATABASE=3CX + +pci:v000014E8* + ID_VENDOR_FROM_DATABASE=RAYCER Inc + +pci:v000014E9* + ID_VENDOR_FROM_DATABASE=GARNETS System CO Ltd + +pci:v000014EA* + ID_VENDOR_FROM_DATABASE=Planex Communications, Inc + +pci:v000014EAd0000AB06* + ID_PRODUCT_FROM_DATABASE=FNW-3603-TX CardBus Fast Ethernet + +pci:v000014EAd0000AB07* + ID_PRODUCT_FROM_DATABASE=RTL81xx RealTek Ethernet + +pci:v000014EAd0000AB08* + ID_PRODUCT_FROM_DATABASE=FNW-3602-TX CardBus Fast Ethernet + +pci:v000014EB* + ID_VENDOR_FROM_DATABASE=SEIKO EPSON Corp + +pci:v000014EC* + ID_VENDOR_FROM_DATABASE=Agilent Technologies + +pci:v000014ECd00000000* + ID_PRODUCT_FROM_DATABASE=Aciris Digitizer (malformed ID) + +pci:v000014ED* + ID_VENDOR_FROM_DATABASE=DATAKINETICS Ltd + +pci:v000014EE* + ID_VENDOR_FROM_DATABASE=MASPRO KENKOH Corp + +pci:v000014EF* + ID_VENDOR_FROM_DATABASE=CARRY Computer ENG. CO Ltd + +pci:v000014F0* + ID_VENDOR_FROM_DATABASE=CANON RESEACH CENTRE FRANCE + +pci:v000014F1* + ID_VENDOR_FROM_DATABASE=Conexant Systems, Inc. + +pci:v000014F1d00001002* + ID_PRODUCT_FROM_DATABASE=HCF 56k Modem + +pci:v000014F1d00001003* + ID_PRODUCT_FROM_DATABASE=HCF 56k Modem + +pci:v000014F1d00001004* + ID_PRODUCT_FROM_DATABASE=HCF 56k Modem + +pci:v000014F1d00001005* + ID_PRODUCT_FROM_DATABASE=HCF 56k Modem + +pci:v000014F1d00001006* + ID_PRODUCT_FROM_DATABASE=HCF 56k Modem + +pci:v000014F1d00001022* + ID_PRODUCT_FROM_DATABASE=HCF 56k Modem + +pci:v000014F1d00001023* + ID_PRODUCT_FROM_DATABASE=HCF 56k Modem + +pci:v000014F1d00001024* + ID_PRODUCT_FROM_DATABASE=HCF 56k Modem + +pci:v000014F1d00001025* + ID_PRODUCT_FROM_DATABASE=HCF 56k Modem + +pci:v000014F1d00001026* + ID_PRODUCT_FROM_DATABASE=HCF 56k Modem + +pci:v000014F1d00001032* + ID_PRODUCT_FROM_DATABASE=HCF 56k Modem + +pci:v000014F1d00001033* + ID_PRODUCT_FROM_DATABASE=HCF 56k Data/Fax Modem + +pci:v000014F1d00001033sv00001033sd00008077* + ID_PRODUCT_FROM_DATABASE=NEC + +pci:v000014F1d00001033sv0000122Dsd00004027* + ID_PRODUCT_FROM_DATABASE=Dell Zeus - MDP3880-W(B) Data Fax Modem + +pci:v000014F1d00001033sv0000122Dsd00004030* + ID_PRODUCT_FROM_DATABASE=Dell Mercury - MDP3880-U(B) Data Fax Modem + +pci:v000014F1d00001033sv0000122Dsd00004034* + ID_PRODUCT_FROM_DATABASE=Dell Thor - MDP3880-W(U) Data Fax Modem + +pci:v000014F1d00001033sv000013E0sd0000020D* + ID_PRODUCT_FROM_DATABASE=Dell Copper + +pci:v000014F1d00001033sv000013E0sd0000020E* + ID_PRODUCT_FROM_DATABASE=Dell Silver + +pci:v000014F1d00001033sv000013E0sd00000261* + ID_PRODUCT_FROM_DATABASE=IBM + +pci:v000014F1d00001033sv000013E0sd00000290* + ID_PRODUCT_FROM_DATABASE=Compaq Goldwing + +pci:v000014F1d00001033sv000013E0sd000002A0* + ID_PRODUCT_FROM_DATABASE=IBM + +pci:v000014F1d00001033sv000013E0sd000002B0* + ID_PRODUCT_FROM_DATABASE=IBM + +pci:v000014F1d00001033sv000013E0sd000002C0* + ID_PRODUCT_FROM_DATABASE=Compaq Scooter + +pci:v000014F1d00001033sv000013E0sd000002D0* + ID_PRODUCT_FROM_DATABASE=IBM + +pci:v000014F1d00001033sv0000144Fsd00001500* + ID_PRODUCT_FROM_DATABASE=IBM P85-DF (1) + +pci:v000014F1d00001033sv0000144Fsd00001501* + ID_PRODUCT_FROM_DATABASE=IBM P85-DF (2) + +pci:v000014F1d00001033sv0000144Fsd0000150A* + ID_PRODUCT_FROM_DATABASE=IBM P85-DF (3) + +pci:v000014F1d00001033sv0000144Fsd0000150B* + ID_PRODUCT_FROM_DATABASE=IBM P85-DF Low Profile (1) + +pci:v000014F1d00001033sv0000144Fsd00001510* + ID_PRODUCT_FROM_DATABASE=IBM P85-DF Low Profile (2) + +pci:v000014F1d00001034* + ID_PRODUCT_FROM_DATABASE=HCF 56k Data/Fax/Voice Modem + +pci:v000014F1d00001035* + ID_PRODUCT_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem + +pci:v000014F1d00001035sv000010CFsd00001098* + ID_PRODUCT_FROM_DATABASE=Fujitsu P85-DFSV + +pci:v000014F1d00001036* + ID_PRODUCT_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp Modem + +pci:v000014F1d00001036sv0000104Dsd00008067* + ID_PRODUCT_FROM_DATABASE=HCF 56k Modem + +pci:v000014F1d00001036sv0000122Dsd00004029* + ID_PRODUCT_FROM_DATABASE=MDP3880SP-W + +pci:v000014F1d00001036sv0000122Dsd00004031* + ID_PRODUCT_FROM_DATABASE=MDP3880SP-U + +pci:v000014F1d00001036sv000013E0sd00000209* + ID_PRODUCT_FROM_DATABASE=Dell Titanium + +pci:v000014F1d00001036sv000013E0sd0000020A* + ID_PRODUCT_FROM_DATABASE=Dell Graphite + +pci:v000014F1d00001036sv000013E0sd00000260* + ID_PRODUCT_FROM_DATABASE=Gateway Red Owl + +pci:v000014F1d00001036sv000013E0sd00000270* + ID_PRODUCT_FROM_DATABASE=Gateway White Horse + +pci:v000014F1d00001052* + ID_PRODUCT_FROM_DATABASE=HCF 56k Data/Fax Modem (Worldwide) + +pci:v000014F1d00001053* + ID_PRODUCT_FROM_DATABASE=HCF 56k Data/Fax Modem (Worldwide) + +pci:v000014F1d00001054* + ID_PRODUCT_FROM_DATABASE=HCF 56k Data/Fax/Voice Modem (Worldwide) + +pci:v000014F1d00001055* + ID_PRODUCT_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (Worldwide) + +pci:v000014F1d00001056* + ID_PRODUCT_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp Modem (Worldwide) + +pci:v000014F1d00001057* + ID_PRODUCT_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp Modem (Worldwide) + +pci:v000014F1d00001059* + ID_PRODUCT_FROM_DATABASE=HCF 56k Data/Fax/Voice Modem (Worldwide) + +pci:v000014F1d00001063* + ID_PRODUCT_FROM_DATABASE=HCF 56k Data/Fax Modem + +pci:v000014F1d00001064* + ID_PRODUCT_FROM_DATABASE=HCF 56k Data/Fax/Voice Modem + +pci:v000014F1d00001065* + ID_PRODUCT_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem + +pci:v000014F1d00001066* + ID_PRODUCT_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp Modem + +pci:v000014F1d00001066sv0000122Dsd00004033* + ID_PRODUCT_FROM_DATABASE=Dell Athena - MDP3900V-U + +pci:v000014F1d00001085* + ID_PRODUCT_FROM_DATABASE=HCF V90 56k Data/Fax/Voice/Spkp PCI Modem + +pci:v000014F1d000010B6* + ID_PRODUCT_FROM_DATABASE=CX06834-11 HCF V.92 56k Data/Fax/Voice/Spkp Modem + +pci:v000014F1d00001433* + ID_PRODUCT_FROM_DATABASE=HCF 56k Data/Fax Modem + +pci:v000014F1d00001434* + ID_PRODUCT_FROM_DATABASE=HCF 56k Data/Fax/Voice Modem + +pci:v000014F1d00001435* + ID_PRODUCT_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem + +pci:v000014F1d00001436* + ID_PRODUCT_FROM_DATABASE=HCF 56k Data/Fax Modem + +pci:v000014F1d00001453* + ID_PRODUCT_FROM_DATABASE=HCF 56k Data/Fax Modem + +pci:v000014F1d00001453sv000013E0sd00000240* + ID_PRODUCT_FROM_DATABASE=IBM + +pci:v000014F1d00001453sv000013E0sd00000250* + ID_PRODUCT_FROM_DATABASE=IBM + +pci:v000014F1d00001453sv0000144Fsd00001502* + ID_PRODUCT_FROM_DATABASE=IBM P95-DF (1) + +pci:v000014F1d00001453sv0000144Fsd00001503* + ID_PRODUCT_FROM_DATABASE=IBM P95-DF (2) + +pci:v000014F1d00001454* + ID_PRODUCT_FROM_DATABASE=HCF 56k Data/Fax/Voice Modem + +pci:v000014F1d00001455* + ID_PRODUCT_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem + +pci:v000014F1d00001456* + ID_PRODUCT_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp Modem + +pci:v000014F1d00001456sv0000122Dsd00004035* + ID_PRODUCT_FROM_DATABASE=Dell Europa - MDP3900V-W + +pci:v000014F1d00001456sv0000122Dsd00004302* + ID_PRODUCT_FROM_DATABASE=Dell MP3930V-W(C) MiniPCI + +pci:v000014F1d00001610* + ID_PRODUCT_FROM_DATABASE=ADSL AccessRunner PCI Arbitration Device + +pci:v000014F1d00001611* + ID_PRODUCT_FROM_DATABASE=AccessRunner PCI ADSL Interface Device + +pci:v000014F1d00001620* + ID_PRODUCT_FROM_DATABASE=AccessRunner V2 PCI ADSL Arbitration Device + +pci:v000014F1d00001621* + ID_PRODUCT_FROM_DATABASE=AccessRunner V2 PCI ADSL Interface Device + +pci:v000014F1d00001622* + ID_PRODUCT_FROM_DATABASE=AccessRunner V2 PCI ADSL Yukon WAN Adapter + +pci:v000014F1d00001803* + ID_PRODUCT_FROM_DATABASE=HCF 56k Modem + +pci:v000014F1d00001803sv00000E11sd00000023* + ID_PRODUCT_FROM_DATABASE=623-LAN Grizzly + +pci:v000014F1d00001803sv00000E11sd00000043* + ID_PRODUCT_FROM_DATABASE=623-LAN Yogi + +pci:v000014F1d00001811* + ID_PRODUCT_FROM_DATABASE=MiniPCI Network Adapter + +pci:v000014F1d00001815* + ID_PRODUCT_FROM_DATABASE=HCF 56k Modem + +pci:v000014F1d00001815sv00000E11sd00000022* + ID_PRODUCT_FROM_DATABASE=Grizzly + +pci:v000014F1d00001815sv00000E11sd00000042* + ID_PRODUCT_FROM_DATABASE=Yogi + +pci:v000014F1d00002003* + ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax Modem + +pci:v000014F1d00002004* + ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice Modem + +pci:v000014F1d00002005* + ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice/Spkp (w/Handset) Modem + +pci:v000014F1d00002006* + ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice/Spkp Modem + +pci:v000014F1d00002013* + ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax Modem + +pci:v000014F1d00002013sv00000E11sd0000B195* + ID_PRODUCT_FROM_DATABASE=Bear + +pci:v000014F1d00002013sv00000E11sd0000B196* + ID_PRODUCT_FROM_DATABASE=Seminole 1 + +pci:v000014F1d00002013sv00000E11sd0000B1BE* + ID_PRODUCT_FROM_DATABASE=Seminole 2 + +pci:v000014F1d00002013sv00001025sd00008013* + ID_PRODUCT_FROM_DATABASE=Acer + +pci:v000014F1d00002013sv00001033sd0000809D* + ID_PRODUCT_FROM_DATABASE=NEC + +pci:v000014F1d00002013sv00001033sd000080BC* + ID_PRODUCT_FROM_DATABASE=NEC + +pci:v000014F1d00002013sv0000155Dsd00006793* + ID_PRODUCT_FROM_DATABASE=HP + +pci:v000014F1d00002013sv0000155Dsd00008850* + ID_PRODUCT_FROM_DATABASE=E Machines + +pci:v000014F1d00002014* + ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice Modem + +pci:v000014F1d00002015* + ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice/Spkp (w/Handset) Modem + +pci:v000014F1d00002016* + ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice/Spkp Modem + +pci:v000014F1d00002043* + ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax Modem (WorldW SmartDAA) + +pci:v000014F1d00002044* + ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice Modem (WorldW SmartDAA) + +pci:v000014F1d00002045* + ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (WorldW SmartDAA) + +pci:v000014F1d00002045sv000014F1sd00002045* + ID_PRODUCT_FROM_DATABASE=Generic SoftK56 + +pci:v000014F1d00002046* + ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice/Spkp Modem (WorldW SmartDAA) + +pci:v000014F1d00002063* + ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax Modem (SmartDAA) + +pci:v000014F1d00002064* + ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice Modem (SmartDAA) + +pci:v000014F1d00002065* + ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (SmartDAA) + +pci:v000014F1d00002066* + ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice/Spkp Modem (SmartDAA) + +pci:v000014F1d00002093* + ID_PRODUCT_FROM_DATABASE=HSF 56k Modem + +pci:v000014F1d00002093sv0000155Dsd00002F07* + ID_PRODUCT_FROM_DATABASE=Legend + +pci:v000014F1d00002143* + ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Cell Modem (Mob WorldW SmartDAA) + +pci:v000014F1d00002144* + ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice/Cell Modem (Mob WorldW SmartDAA) + +pci:v000014F1d00002145* + ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice/Spkp (w/HS)/Cell Modem (Mob WorldW SmartDAA) + +pci:v000014F1d00002146* + ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice/Spkp/Cell Modem (Mob WorldW SmartDAA) + +pci:v000014F1d00002163* + ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Cell Modem (Mob SmartDAA) + +pci:v000014F1d00002164* + ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice/Cell Modem (Mob SmartDAA) + +pci:v000014F1d00002165* + ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice/Spkp (w/HS)/Cell Modem (Mob SmartDAA) + +pci:v000014F1d00002166* + ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice/Spkp/Cell Modem (Mob SmartDAA) + +pci:v000014F1d00002343* + ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax CardBus Modem (Mob WorldW SmartDAA) + +pci:v000014F1d00002344* + ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice CardBus Modem (Mob WorldW SmartDAA) + +pci:v000014F1d00002345* + ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice/Spkp (w/HS) CardBus Modem (Mob WorldW SmartDAA) + +pci:v000014F1d00002346* + ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice/Spkp CardBus Modem (Mob WorldW SmartDAA) + +pci:v000014F1d00002363* + ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax CardBus Modem (Mob SmartDAA) + +pci:v000014F1d00002364* + ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice CardBus Modem (Mob SmartDAA) + +pci:v000014F1d00002365* + ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice/Spkp (w/HS) CardBus Modem (Mob SmartDAA) + +pci:v000014F1d00002366* + ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice/Spkp CardBus Modem (Mob SmartDAA) + +pci:v000014F1d00002443* + ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax Modem (Mob WorldW SmartDAA) + +pci:v000014F1d00002443sv0000104Dsd00008075* + ID_PRODUCT_FROM_DATABASE=Modem + +pci:v000014F1d00002443sv0000104Dsd00008083* + ID_PRODUCT_FROM_DATABASE=Modem + +pci:v000014F1d00002443sv0000104Dsd00008097* + ID_PRODUCT_FROM_DATABASE=Modem + +pci:v000014F1d00002444* + ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice Modem (Mob WorldW SmartDAA) + +pci:v000014F1d00002445* + ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice/Spkp (w/HS) Modem (Mob WorldW SmartDAA) + +pci:v000014F1d00002446* + ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice/Spkp Modem (Mob WorldW SmartDAA) + +pci:v000014F1d00002463* + ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax Modem (Mob SmartDAA) + +pci:v000014F1d00002464* + ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice Modem (Mob SmartDAA) + +pci:v000014F1d00002465* + ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice/Spkp (w/HS) Modem (Mob SmartDAA) + +pci:v000014F1d00002466* + ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax/Voice/Spkp Modem (Mob SmartDAA) + +pci:v000014F1d00002BFA* + ID_PRODUCT_FROM_DATABASE=D110 HDAudio Soft Data Fax Modem with SmartCP + +pci:v000014F1d00002BFAsv00001025sd00000009* + ID_PRODUCT_FROM_DATABASE=Aspire 5622WLMi + +pci:v000014F1d00002F00* + ID_PRODUCT_FROM_DATABASE=HSF 56k HSFi Modem + +pci:v000014F1d00002F00sv000013E0sd00008D84* + ID_PRODUCT_FROM_DATABASE=IBM HSFi V.90 + +pci:v000014F1d00002F00sv000013E0sd00008D85* + ID_PRODUCT_FROM_DATABASE=Compaq Stinger + +pci:v000014F1d00002F00sv000014F1sd00002004* + ID_PRODUCT_FROM_DATABASE=Dynalink 56PMi + +pci:v000014F1d00002F02* + ID_PRODUCT_FROM_DATABASE=HSF 56k HSFi Data/Fax + +pci:v000014F1d00002F11* + ID_PRODUCT_FROM_DATABASE=HSF 56k HSFi Modem + +pci:v000014F1d00002F20* + ID_PRODUCT_FROM_DATABASE=HSF 56k Data/Fax Modem + +pci:v000014F1d00002F20sv000014F1sd0000200C* + ID_PRODUCT_FROM_DATABASE=Soft Data Fax Modem with SmartCP + +pci:v000014F1d00002F20sv000014F1sd0000200F* + ID_PRODUCT_FROM_DATABASE=Dimension 3000 + +pci:v000014F1d00002F30* + ID_PRODUCT_FROM_DATABASE=SoftV92 SpeakerPhone SoftRing Modem with SmartSP + +pci:v000014F1d00002F30sv000014F1sd00002014* + ID_PRODUCT_FROM_DATABASE=Devolo MikroLink 56K Modem PCI + +pci:v000014F1d00002F50* + ID_PRODUCT_FROM_DATABASE=Conexant SoftK56 Data/Fax Modem + +pci:v000014F1d00005045* + ID_PRODUCT_FROM_DATABASE=CX20549 (Venice) + +pci:v000014F1d00005047* + ID_PRODUCT_FROM_DATABASE=High Definition Audio [Waikiki] + +pci:v000014F1d00005051* + ID_PRODUCT_FROM_DATABASE=High Definition Audio (HERMOSA) + +pci:v000014F1d00005B7A* + ID_PRODUCT_FROM_DATABASE=CX23418 Single-Chip MPEG-2 Encoder with Integrated Analog Video/Broadcast Audio Decoder + +pci:v000014F1d00005B7Asv00000070sd00007444* + ID_PRODUCT_FROM_DATABASE=WinTV HVR-1600 + +pci:v000014F1d00005B7Asv00005854sd00003343* + ID_PRODUCT_FROM_DATABASE=GoTView PCI DVD3 Hybrid + +pci:v000014F1d00008200* + ID_PRODUCT_FROM_DATABASE=CX25850 + +pci:v000014F1d00008234* + ID_PRODUCT_FROM_DATABASE=RS8234 ATM SAR Controller [ServiceSAR Plus] + +pci:v000014F1d00008800* + ID_PRODUCT_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder + +pci:v000014F1d00008800sv00000070sd00002801* + ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV 28xxx (Roslyn) models + +pci:v000014F1d00008800sv00000070sd00003401* + ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV 34xxx models + +pci:v000014F1d00008800sv00000070sd00006902* + ID_PRODUCT_FROM_DATABASE=WinTV HVR-4000-HD + +pci:v000014F1d00008800sv00000070sd00007801* + ID_PRODUCT_FROM_DATABASE=WinTV HVR-1800 MCE + +pci:v000014F1d00008800sv00000070sd00009001* + ID_PRODUCT_FROM_DATABASE=Nova-T DVB-T + +pci:v000014F1d00008800sv00000070sd00009200* + ID_PRODUCT_FROM_DATABASE=Nova-SE2 DVB-S + +pci:v000014F1d00008800sv00000070sd00009202* + ID_PRODUCT_FROM_DATABASE=Nova-S-Plus DVB-S + +pci:v000014F1d00008800sv00000070sd00009402* + ID_PRODUCT_FROM_DATABASE=WinTV-HVR1100 DVB-T/Hybrid + +pci:v000014F1d00008800sv00000070sd00009600* + ID_PRODUCT_FROM_DATABASE=WinTV 88x Video + +pci:v000014F1d00008800sv00000070sd00009802* + ID_PRODUCT_FROM_DATABASE=WinTV-HVR1100 DVB-T/Hybrid (Low Profile) + +pci:v000014F1d00008800sv00001002sd000000F8* + ID_PRODUCT_FROM_DATABASE=ATI TV Wonder Pro + +pci:v000014F1d00008800sv00001002sd0000A101* + ID_PRODUCT_FROM_DATABASE=HDTV Wonder + +pci:v000014F1d00008800sv00001043sd00004823* + ID_PRODUCT_FROM_DATABASE=ASUS PVR-416 + +pci:v000014F1d00008800sv0000107Dsd00006611* + ID_PRODUCT_FROM_DATABASE=Winfast TV 2000XP Expert + +pci:v000014F1d00008800sv0000107Dsd00006613* + ID_PRODUCT_FROM_DATABASE=Leadtek Winfast 2000XP Expert + +pci:v000014F1d00008800sv0000107Dsd00006620* + ID_PRODUCT_FROM_DATABASE=Leadtek Winfast DV2000 + +pci:v000014F1d00008800sv0000107Dsd0000663C* + ID_PRODUCT_FROM_DATABASE=Leadtek PVR 2000 + +pci:v000014F1d00008800sv0000107Dsd0000665F* + ID_PRODUCT_FROM_DATABASE=WinFast DTV1000-T + +pci:v000014F1d00008800sv000010FCsd0000D003* + ID_PRODUCT_FROM_DATABASE=IODATA GV-VCP3/PCI + +pci:v000014F1d00008800sv000010FCsd0000D035* + ID_PRODUCT_FROM_DATABASE=IODATA GV/BCTV7E + +pci:v000014F1d00008800sv00001421sd00000334* + ID_PRODUCT_FROM_DATABASE=Instant TV DVB-T PCI + +pci:v000014F1d00008800sv00001461sd0000000A* + ID_PRODUCT_FROM_DATABASE=AVerTV 303 (M126) + +pci:v000014F1d00008800sv00001461sd0000000B* + ID_PRODUCT_FROM_DATABASE=AverTV Studio 303 (M126) + +pci:v000014F1d00008800sv00001461sd00008011* + ID_PRODUCT_FROM_DATABASE=UltraTV Media Center PCI 550 + +pci:v000014F1d00008800sv00001462sd00008606* + ID_PRODUCT_FROM_DATABASE=MSI TV-@nywhere Master + +pci:v000014F1d00008800sv000014C7sd00000107* + ID_PRODUCT_FROM_DATABASE=GDI Black Gold + +pci:v000014F1d00008800sv000014F1sd00000187* + ID_PRODUCT_FROM_DATABASE=Conexant DVB-T reference design + +pci:v000014F1d00008800sv000014F1sd00000342* + ID_PRODUCT_FROM_DATABASE=Digital-Logic MICROSPACE Entertainment Center (MEC) + +pci:v000014F1d00008800sv0000153Bsd00001166* + ID_PRODUCT_FROM_DATABASE=Cinergy 1400 DVB-T + +pci:v000014F1d00008800sv00001540sd00002580* + ID_PRODUCT_FROM_DATABASE=Provideo PV259 + +pci:v000014F1d00008800sv00001554sd00004811* + ID_PRODUCT_FROM_DATABASE=PixelView + +pci:v000014F1d00008800sv00001554sd00004813* + ID_PRODUCT_FROM_DATABASE=Club 3D ZAP1000 MCE Edition + +pci:v000014F1d00008800sv000017DEsd000008A1* + ID_PRODUCT_FROM_DATABASE=KWorld/VStream XPert DVB-T with cx22702 + +pci:v000014F1d00008800sv000017DEsd000008A6* + ID_PRODUCT_FROM_DATABASE=KWorld/VStream XPert DVB-T + +pci:v000014F1d00008800sv000017DEsd000008B2* + ID_PRODUCT_FROM_DATABASE=KWorld DVB-S 100 + +pci:v000014F1d00008800sv000017DEsd0000A8A6* + ID_PRODUCT_FROM_DATABASE=digitalnow DNTV Live! DVB-T + +pci:v000014F1d00008800sv00001822sd00000025* + ID_PRODUCT_FROM_DATABASE=digitalnow DNTV Live! DVB-T Pro + +pci:v000014F1d00008800sv0000185Bsd0000E000* + ID_PRODUCT_FROM_DATABASE=VideoMate X500 + +pci:v000014F1d00008800sv000018ACsd0000D500* + ID_PRODUCT_FROM_DATABASE=FusionHDTV 5 Gold + +pci:v000014F1d00008800sv000018ACsd0000D810* + ID_PRODUCT_FROM_DATABASE=FusionHDTV 3 Gold-Q + +pci:v000014F1d00008800sv000018ACsd0000D820* + ID_PRODUCT_FROM_DATABASE=FusionHDTV 3 Gold-T + +pci:v000014F1d00008800sv000018ACsd0000DB00* + ID_PRODUCT_FROM_DATABASE=FusionHDTV DVB-T1 + +pci:v000014F1d00008800sv000018ACsd0000DB11* + ID_PRODUCT_FROM_DATABASE=FusionHDTV DVB-T Plus + +pci:v000014F1d00008800sv000018ACsd0000DB50* + ID_PRODUCT_FROM_DATABASE=FusionHDTV DVB-T Dual Digital + +pci:v000014F1d00008800sv00005654sd00002388* + ID_PRODUCT_FROM_DATABASE=GoTView PCI Hybrid TV Tuner Card + +pci:v000014F1d00008800sv00007063sd00003000* + ID_PRODUCT_FROM_DATABASE=pcHDTV HD3000 HDTV + +pci:v000014F1d00008800sv00007063sd00005500* + ID_PRODUCT_FROM_DATABASE=pcHDTV HD-5500 + +pci:v000014F1d00008801* + ID_PRODUCT_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder [Audio Port] + +pci:v000014F1d00008801sv00000070sd00002801* + ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV 28xxx (Roslyn) models + +pci:v000014F1d00008801sv0000185Bsd0000E000* + ID_PRODUCT_FROM_DATABASE=VideoMate X500 + +pci:v000014F1d00008801sv00005654sd00002388* + ID_PRODUCT_FROM_DATABASE=GoTView PCI Hybrid Audio AVStream Device + +pci:v000014F1d00008801sv00007063sd00005500* + ID_PRODUCT_FROM_DATABASE=pcHDTV HD-5500 + +pci:v000014F1d00008802* + ID_PRODUCT_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder [MPEG Port] + +pci:v000014F1d00008802sv00000070sd00002801* + ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV 28xxx (Roslyn) models + +pci:v000014F1d00008802sv00000070sd00006902* + ID_PRODUCT_FROM_DATABASE=WinTV HVR-4000-HD + +pci:v000014F1d00008802sv00000070sd00009002* + ID_PRODUCT_FROM_DATABASE=Nova-T DVB-T Model 909 + +pci:v000014F1d00008802sv00000070sd00009402* + ID_PRODUCT_FROM_DATABASE=WinTV-HVR1100 DVB-T/Hybrid + +pci:v000014F1d00008802sv00000070sd00009600* + ID_PRODUCT_FROM_DATABASE=WinTV 88x MPEG Encoder + +pci:v000014F1d00008802sv00001043sd00004823* + ID_PRODUCT_FROM_DATABASE=ASUS PVR-416 + +pci:v000014F1d00008802sv0000107Dsd0000663C* + ID_PRODUCT_FROM_DATABASE=Leadtek PVR 2000 + +pci:v000014F1d00008802sv0000107Dsd0000665F* + ID_PRODUCT_FROM_DATABASE=WinFast DTV1000-T + +pci:v000014F1d00008802sv000014F1sd00000187* + ID_PRODUCT_FROM_DATABASE=Conexant DVB-T reference design + +pci:v000014F1d00008802sv000017DEsd000008A1* + ID_PRODUCT_FROM_DATABASE=XPert DVB-T PCI BDA DVBT 23880 Transport Stream Capture + +pci:v000014F1d00008802sv000017DEsd000008A6* + ID_PRODUCT_FROM_DATABASE=KWorld/VStream XPert DVB-T + +pci:v000014F1d00008802sv000018ACsd0000D500* + ID_PRODUCT_FROM_DATABASE=DViCO FusionHDTV5 Gold + +pci:v000014F1d00008802sv000018ACsd0000D810* + ID_PRODUCT_FROM_DATABASE=DViCO FusionHDTV3 Gold-Q + +pci:v000014F1d00008802sv000018ACsd0000D820* + ID_PRODUCT_FROM_DATABASE=DViCO FusionHDTV3 Gold-T + +pci:v000014F1d00008802sv000018ACsd0000DB00* + ID_PRODUCT_FROM_DATABASE=DVICO FusionHDTV DVB-T1 + +pci:v000014F1d00008802sv000018ACsd0000DB10* + ID_PRODUCT_FROM_DATABASE=DVICO FusionHDTV DVB-T Plus + +pci:v000014F1d00008802sv00005654sd00002388* + ID_PRODUCT_FROM_DATABASE=GoTView PCI Hybrid TS Capture Device + +pci:v000014F1d00008802sv00007063sd00003000* + ID_PRODUCT_FROM_DATABASE=pcHDTV HD3000 HDTV + +pci:v000014F1d00008802sv00007063sd00005500* + ID_PRODUCT_FROM_DATABASE=pcHDTV HD-5500 + +pci:v000014F1d00008804* + ID_PRODUCT_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder [IR Port] + +pci:v000014F1d00008804sv00000070sd00006902* + ID_PRODUCT_FROM_DATABASE=WinTV HVR-4000-HD + +pci:v000014F1d00008804sv00000070sd00009002* + ID_PRODUCT_FROM_DATABASE=Nova-T DVB-T Model 909 + +pci:v000014F1d00008804sv00000070sd00009402* + ID_PRODUCT_FROM_DATABASE=WinTV-HVR1100 DVB-T/Hybrid + +pci:v000014F1d00008804sv00007063sd00005500* + ID_PRODUCT_FROM_DATABASE=pcHDTV HD-5500 + +pci:v000014F1d00008811* + ID_PRODUCT_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder [Audio Port] + +pci:v000014F1d00008811sv00000070sd00003401* + ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV 34xxx models + +pci:v000014F1d00008811sv00000070sd00006902* + ID_PRODUCT_FROM_DATABASE=WinTV HVR-4000-HD + +pci:v000014F1d00008811sv00000070sd00009402* + ID_PRODUCT_FROM_DATABASE=WinTV-HVR1100 DVB-T/Hybrid + +pci:v000014F1d00008811sv00000070sd00009600* + ID_PRODUCT_FROM_DATABASE=WinTV 88x Audio + +pci:v000014F1d00008811sv00001462sd00008606* + ID_PRODUCT_FROM_DATABASE=MSI TV-@nywhere Master + +pci:v000014F1d00008811sv000018ACsd0000D500* + ID_PRODUCT_FROM_DATABASE=DViCO FusionHDTV5 Gold + +pci:v000014F1d00008811sv000018ACsd0000D810* + ID_PRODUCT_FROM_DATABASE=DViCO FusionHDTV3 Gold-Q + +pci:v000014F1d00008811sv000018ACsd0000D820* + ID_PRODUCT_FROM_DATABASE=DViCO FusionHDTV3 Gold-T + +pci:v000014F1d00008811sv000018ACsd0000DB00* + ID_PRODUCT_FROM_DATABASE=DVICO FusionHDTV DVB-T1 + +pci:v000014F1d00008811sv00005654sd00002388* + ID_PRODUCT_FROM_DATABASE=GoTView PCI Hybrid Audio Capture Device + +pci:v000014F1d00008852* + ID_PRODUCT_FROM_DATABASE=CX23885 PCI Video and Audio Decoder + +pci:v000014F1d00008852sv00000070sd00008010* + ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV HVR-1400 ExpressCard + +pci:v000014F1d00008852sv00001461sd0000C039* + ID_PRODUCT_FROM_DATABASE=AVerTV Hybrid Express (A577) + +pci:v000014F1d00008852sv0000153Bsd0000117E* + ID_PRODUCT_FROM_DATABASE=Cinergy T PCIe Dual + +pci:v000014F1d00008852sv000018ACsd0000DB78* + ID_PRODUCT_FROM_DATABASE=FusionHDTV DVB-T Dual Express + +pci:v000014F1d00008880* + ID_PRODUCT_FROM_DATABASE=CX23887/8 PCIe Broadcast Audio and Video Decoder with 3D Comb + +pci:v000014F1d00008880sv00000070sd0000C108* + ID_PRODUCT_FROM_DATABASE=WinTV-HVR-4400-HD model 1278 + +pci:v000014F1d00008880sv00005654sd00002389* + ID_PRODUCT_FROM_DATABASE=GoTView X5 DVD Hybrid PCI-E + +pci:v000014F1d00008880sv00005654sd00002390* + ID_PRODUCT_FROM_DATABASE=GoTView X5 3D HYBRID PCI-E + +pci:v000014F2* + ID_VENDOR_FROM_DATABASE=MOBILITY Electronics + +pci:v000014F2d00000120* + ID_PRODUCT_FROM_DATABASE=EV1000 bridge + +pci:v000014F2d00000121* + ID_PRODUCT_FROM_DATABASE=EV1000 Parallel port + +pci:v000014F2d00000122* + ID_PRODUCT_FROM_DATABASE=EV1000 Serial port + +pci:v000014F2d00000123* + ID_PRODUCT_FROM_DATABASE=EV1000 Keyboard controller + +pci:v000014F2d00000124* + ID_PRODUCT_FROM_DATABASE=EV1000 Mouse controller + +pci:v000014F3* + ID_VENDOR_FROM_DATABASE=BroadLogic + +pci:v000014F3d00002030* + ID_PRODUCT_FROM_DATABASE=2030 DVB-S Satellite Receiver + +pci:v000014F3d00002035* + ID_PRODUCT_FROM_DATABASE=2035 DVB-S Satellite Receiver + +pci:v000014F3d00002050* + ID_PRODUCT_FROM_DATABASE=2050 DVB-T Terrestrial (Cable) Receiver + +pci:v000014F3d00002060* + ID_PRODUCT_FROM_DATABASE=2060 ATSC Terrestrial (Cable) Receiver + +pci:v000014F4* + ID_VENDOR_FROM_DATABASE=TOKYO Electronic Industry CO Ltd + +pci:v000014F5* + ID_VENDOR_FROM_DATABASE=SOPAC Ltd + +pci:v000014F6* + ID_VENDOR_FROM_DATABASE=COYOTE Technologies LLC + +pci:v000014F7* + ID_VENDOR_FROM_DATABASE=WOLF Technology Inc + +pci:v000014F8* + ID_VENDOR_FROM_DATABASE=AUDIOCODES Inc + +pci:v000014F8d00002077* + ID_PRODUCT_FROM_DATABASE=TP-240 dual span E1 VoIP PCI card + +pci:v000014F9* + ID_VENDOR_FROM_DATABASE=AG COMMUNICATIONS + +pci:v000014FA* + ID_VENDOR_FROM_DATABASE=WANDEL & GOLTERMANN + +pci:v000014FB* + ID_VENDOR_FROM_DATABASE=TRANSAS MARINE (UK) Ltd + +pci:v000014FC* + ID_VENDOR_FROM_DATABASE=Quadrics Ltd + +pci:v000014FCd00000000* + ID_PRODUCT_FROM_DATABASE=QsNet Elan3 Network Adapter + +pci:v000014FCd00000001* + ID_PRODUCT_FROM_DATABASE=QsNetII Elan4 Network Adapter + +pci:v000014FCd00000002* + ID_PRODUCT_FROM_DATABASE=QsNetIII Elan5 Network Adapter + +pci:v000014FD* + ID_VENDOR_FROM_DATABASE=JAPAN Computer Industry Inc + +pci:v000014FE* + ID_VENDOR_FROM_DATABASE=ARCHTEK TELECOM Corp + +pci:v000014FF* + ID_VENDOR_FROM_DATABASE=TWINHEAD INTERNATIONAL Corp + +pci:v00001500* + ID_VENDOR_FROM_DATABASE=DELTA Electronics, Inc + +pci:v00001500d00001360* + ID_PRODUCT_FROM_DATABASE=RTL81xx RealTek Ethernet + +pci:v00001501* + ID_VENDOR_FROM_DATABASE=BANKSOFT CANADA Ltd + +pci:v00001502* + ID_VENDOR_FROM_DATABASE=MITSUBISHI ELECTRIC LOGISTICS SUPPORT Co Ltd + +pci:v00001503* + ID_VENDOR_FROM_DATABASE=KAWASAKI LSI USA Inc + +pci:v00001504* + ID_VENDOR_FROM_DATABASE=KAISER Electronics + +pci:v00001505* + ID_VENDOR_FROM_DATABASE=ITA INGENIEURBURO FUR TESTAUFGABEN GmbH + +pci:v00001506* + ID_VENDOR_FROM_DATABASE=CHAMELEON Systems Inc + +pci:v00001507* + ID_VENDOR_FROM_DATABASE=Motorola ?? / HTEC + +pci:v00001507d00000001* + ID_PRODUCT_FROM_DATABASE=MPC105 [Eagle] + +pci:v00001507d00000002* + ID_PRODUCT_FROM_DATABASE=MPC106 [Grackle] + +pci:v00001507d00000003* + ID_PRODUCT_FROM_DATABASE=MPC8240 [Kahlua] + +pci:v00001507d00000100* + ID_PRODUCT_FROM_DATABASE=MC145575 [HFC-PCI] + +pci:v00001507d00000431* + ID_PRODUCT_FROM_DATABASE=KTI829c 100VG + +pci:v00001507d00004801* + ID_PRODUCT_FROM_DATABASE=Raven + +pci:v00001507d00004802* + ID_PRODUCT_FROM_DATABASE=Falcon + +pci:v00001507d00004803* + ID_PRODUCT_FROM_DATABASE=Hawk + +pci:v00001507d00004806* + ID_PRODUCT_FROM_DATABASE=CPX8216 + +pci:v00001508* + ID_VENDOR_FROM_DATABASE=HONDA CONNECTORS/MHOTRONICS Inc + +pci:v00001509* + ID_VENDOR_FROM_DATABASE=FIRST INTERNATIONAL Computer Inc + +pci:v0000150A* + ID_VENDOR_FROM_DATABASE=FORVUS RESEARCH Inc + +pci:v0000150B* + ID_VENDOR_FROM_DATABASE=YAMASHITA Systems Corp + +pci:v0000150C* + ID_VENDOR_FROM_DATABASE=KYOPAL CO Ltd + +pci:v0000150D* + ID_VENDOR_FROM_DATABASE=WARPSPPED Inc + +pci:v0000150E* + ID_VENDOR_FROM_DATABASE=C-PORT Corp + +pci:v0000150F* + ID_VENDOR_FROM_DATABASE=INTEC GmbH + +pci:v00001510* + ID_VENDOR_FROM_DATABASE=BEHAVIOR TECH Computer Corp + +pci:v00001511* + ID_VENDOR_FROM_DATABASE=CENTILLIUM Technology Corp + +pci:v00001512* + ID_VENDOR_FROM_DATABASE=ROSUN Technologies Inc + +pci:v00001513* + ID_VENDOR_FROM_DATABASE=Raychem + +pci:v00001514* + ID_VENDOR_FROM_DATABASE=TFL LAN Inc + +pci:v00001515* + ID_VENDOR_FROM_DATABASE=Advent design + +pci:v00001516* + ID_VENDOR_FROM_DATABASE=MYSON Technology Inc + +pci:v00001516d00000800* + ID_PRODUCT_FROM_DATABASE=MTD-8xx 100/10M Ethernet PCI Adapter + +pci:v00001516d00000803* + ID_PRODUCT_FROM_DATABASE=SURECOM EP-320X-S 100/10M Ethernet PCI Adapter + +pci:v00001516d00000803sv00001320sd000010BD* + ID_PRODUCT_FROM_DATABASE=SURECOM EP-320X-S 100/10M Ethernet PCI Adapter + +pci:v00001516d00000891* + ID_PRODUCT_FROM_DATABASE=MTD-8xx 100/10M Ethernet PCI Adapter + +pci:v00001517* + ID_VENDOR_FROM_DATABASE=ECHOTEK Corp + +pci:v00001518* + ID_VENDOR_FROM_DATABASE=Kontron Modular Computers GmbH + +pci:v00001519* + ID_VENDOR_FROM_DATABASE=TELEFON AKTIEBOLAGET LM Ericsson + +pci:v0000151A* + ID_VENDOR_FROM_DATABASE=Globetek + +pci:v0000151Ad00001002* + ID_PRODUCT_FROM_DATABASE=PCI-1002 + +pci:v0000151Ad00001004* + ID_PRODUCT_FROM_DATABASE=PCI-1004 + +pci:v0000151Ad00001008* + ID_PRODUCT_FROM_DATABASE=PCI-1008 + +pci:v0000151B* + ID_VENDOR_FROM_DATABASE=COMBOX Ltd + +pci:v0000151C* + ID_VENDOR_FROM_DATABASE=DIGITAL AUDIO LABS Inc + +pci:v0000151Cd00000003* + ID_PRODUCT_FROM_DATABASE=Prodif T 2496 + +pci:v0000151Cd00004000* + ID_PRODUCT_FROM_DATABASE=Prodif 88 + +pci:v0000151D* + ID_VENDOR_FROM_DATABASE=Fujitsu Computer Products Of America + +pci:v0000151E* + ID_VENDOR_FROM_DATABASE=MATRIX Corp + +pci:v0000151F* + ID_VENDOR_FROM_DATABASE=TOPIC SEMICONDUCTOR Corp + +pci:v0000151Fd00000000* + ID_PRODUCT_FROM_DATABASE=TP560 Data/Fax/Voice 56k modem + +pci:v00001520* + ID_VENDOR_FROM_DATABASE=CHAPLET System Inc + +pci:v00001521* + ID_VENDOR_FROM_DATABASE=BELL Corp + +pci:v00001522* + ID_VENDOR_FROM_DATABASE=MainPine Ltd + +pci:v00001522d00000100* + ID_PRODUCT_FROM_DATABASE=PCI <-> IOBus Bridge + +pci:v00001522d00000100sv00001522sd00000200* + ID_PRODUCT_FROM_DATABASE=RockForceDUO 2 Port V.92/V.44 Data/Fax/Voice Modem + +pci:v00001522d00000100sv00001522sd00000300* + ID_PRODUCT_FROM_DATABASE=RockForceQUATRO 4 Port V.92/V.44 Data/Fax/Voice Modem + +pci:v00001522d00000100sv00001522sd00000400* + ID_PRODUCT_FROM_DATABASE=RockForceDUO+ 2 Port V.92/V.44 Data/Fax/Voice Modem + +pci:v00001522d00000100sv00001522sd00000500* + ID_PRODUCT_FROM_DATABASE=RockForceQUATRO+ 4 Port V.92/V.44 Data/Fax/Voice Modem + +pci:v00001522d00000100sv00001522sd00000600* + ID_PRODUCT_FROM_DATABASE=RockForce+ 2 Port V.90 Data/Fax/Voice Modem + +pci:v00001522d00000100sv00001522sd00000700* + ID_PRODUCT_FROM_DATABASE=RockForce+ 4 Port V.90 Data/Fax/Voice Modem + +pci:v00001522d00000100sv00001522sd00000800* + ID_PRODUCT_FROM_DATABASE=RockForceOCTO+ 8 Port V.92/V.44 Data/Fax/Voice Modem + +pci:v00001522d00000100sv00001522sd00000C00* + ID_PRODUCT_FROM_DATABASE=RockForceDUO+ 2 Port V.92/V.44 Data, V.34 Super-G3 Fax, Voice Modem + +pci:v00001522d00000100sv00001522sd00000D00* + ID_PRODUCT_FROM_DATABASE=RockForceQUATRO+ 4 Port V.92/V.44 Data, V.34 Super-G3 Fax, Voice Modem + +pci:v00001522d00000100sv00001522sd00001D00* + ID_PRODUCT_FROM_DATABASE=RockForceOCTO+ 8 Port V.92/V.44 Data, V.34 Super-G3 Fax, Voice Modem + +pci:v00001522d00000100sv00001522sd00002000* + ID_PRODUCT_FROM_DATABASE=RockForceD1 1 Port V.90 Data Modem + +pci:v00001522d00000100sv00001522sd00002100* + ID_PRODUCT_FROM_DATABASE=RockForceF1 1 Port V.34 Super-G3 Fax Modem + +pci:v00001522d00000100sv00001522sd00002200* + ID_PRODUCT_FROM_DATABASE=RockForceD2 2 Port V.90 Data Modem + +pci:v00001522d00000100sv00001522sd00002300* + ID_PRODUCT_FROM_DATABASE=RockForceF2 2 Port V.34 Super-G3 Fax Modem + +pci:v00001522d00000100sv00001522sd00002400* + ID_PRODUCT_FROM_DATABASE=RockForceD4 4 Port V.90 Data Modem + +pci:v00001522d00000100sv00001522sd00002500* + ID_PRODUCT_FROM_DATABASE=RockForceF4 4 Port V.34 Super-G3 Fax Modem + +pci:v00001522d00000100sv00001522sd00002600* + ID_PRODUCT_FROM_DATABASE=RockForceD8 8 Port V.90 Data Modem + +pci:v00001522d00000100sv00001522sd00002700* + ID_PRODUCT_FROM_DATABASE=RockForceF8 8 Port V.34 Super-G3 Fax Modem + +pci:v00001522d00000100sv00001522sd00003000* + ID_PRODUCT_FROM_DATABASE=IQ Express D1 - 1 Port V.92 Data Modem + +pci:v00001522d00000100sv00001522sd00003100* + ID_PRODUCT_FROM_DATABASE=IQ Express F1 - 1 Port V.34 Super-G3 Fax Modem + +pci:v00001522d00000100sv00001522sd00003200* + ID_PRODUCT_FROM_DATABASE=IQ Express D2 - 2 Port V.92 Data Modem + +pci:v00001522d00000100sv00001522sd00003300* + ID_PRODUCT_FROM_DATABASE=IQ Express F2 - 2 Port V.34 Super-G3 Fax Modem + +pci:v00001522d00000100sv00001522sd00003400* + ID_PRODUCT_FROM_DATABASE=IQ Express D4 - 4 Port V.92 Data Modem + +pci:v00001522d00000100sv00001522sd00003500* + ID_PRODUCT_FROM_DATABASE=IQ Express F4 - 4 Port V.34 Super-G3 Fax Modem + +pci:v00001522d00000100sv00001522sd00003C00* + ID_PRODUCT_FROM_DATABASE=IQ Express D8 - 8 Port V.92 Data Modem + +pci:v00001522d00000100sv00001522sd00003D00* + ID_PRODUCT_FROM_DATABASE=IQ Express F8 - 8 Port V.34 Super-G3 Fax Modem + +pci:v00001522d00004000* + ID_PRODUCT_FROM_DATABASE=PCI Express UART + +pci:v00001522d00004000sv00001522sd00004001* + ID_PRODUCT_FROM_DATABASE=IQ Express 1-port V.34 Super-G3 Fax + +pci:v00001522d00004000sv00001522sd00004002* + ID_PRODUCT_FROM_DATABASE=IQ Express 2-port V.34 Super-G3 Fax + +pci:v00001522d00004000sv00001522sd00004004* + ID_PRODUCT_FROM_DATABASE=IQ Express 4-port V.34 Super-G3 Fax + +pci:v00001522d00004000sv00001522sd00004008* + ID_PRODUCT_FROM_DATABASE=IQ Express 8-port V.34 Super-G3 Fax + +pci:v00001522d00004000sv00001522sd00004100* + ID_PRODUCT_FROM_DATABASE=IQ Express SideBand + +pci:v00001523* + ID_VENDOR_FROM_DATABASE=MUSIC Semiconductors + +pci:v00001524* + ID_VENDOR_FROM_DATABASE=ENE Technology Inc + +pci:v00001524d00000510* + ID_PRODUCT_FROM_DATABASE=CB710 Memory Card Reader Controller + +pci:v00001524d00000510sv0000103Csd0000006A* + ID_PRODUCT_FROM_DATABASE=NX9500 + +pci:v00001524d00000520* + ID_PRODUCT_FROM_DATABASE=FLASH memory: ENE Technology Inc: + +pci:v00001524d00000530* + ID_PRODUCT_FROM_DATABASE=ENE PCI Memory Stick Card Reader Controller + +pci:v00001524d00000550* + ID_PRODUCT_FROM_DATABASE=ENE PCI Secure Digital Card Reader Controller + +pci:v00001524d00000551* + ID_PRODUCT_FROM_DATABASE=SD/MMC Card Reader Controller + +pci:v00001524d00000610* + ID_PRODUCT_FROM_DATABASE=PCI Smart Card Reader Controller + +pci:v00001524d00000720* + ID_PRODUCT_FROM_DATABASE=Memory Stick Card Reader Controller + +pci:v00001524d00000730* + ID_PRODUCT_FROM_DATABASE=ENE PCI Memory Stick Card Reader Controller + +pci:v00001524d00000750* + ID_PRODUCT_FROM_DATABASE=ENE PCI SmartMedia / xD Card Reader Controller + +pci:v00001524d00000751* + ID_PRODUCT_FROM_DATABASE=ENE PCI Secure Digital / MMC Card Reader Controller + +pci:v00001524d00001211* + ID_PRODUCT_FROM_DATABASE=CB1211 Cardbus Controller + +pci:v00001524d00001225* + ID_PRODUCT_FROM_DATABASE=CB1225 Cardbus Controller + +pci:v00001524d00001410* + ID_PRODUCT_FROM_DATABASE=CB1410 Cardbus Controller + +pci:v00001524d00001410sv00001025sd0000003C* + ID_PRODUCT_FROM_DATABASE=CL50 motherboard + +pci:v00001524d00001410sv00001025sd0000005A* + ID_PRODUCT_FROM_DATABASE=TravelMate 290 + +pci:v00001524d00001411* + ID_PRODUCT_FROM_DATABASE=CB-710/2/4 Cardbus Controller + +pci:v00001524d00001411sv0000103Csd0000006A* + ID_PRODUCT_FROM_DATABASE=NX9500 + +pci:v00001524d00001412* + ID_PRODUCT_FROM_DATABASE=CB-712/4 Cardbus Controller + +pci:v00001524d00001420* + ID_PRODUCT_FROM_DATABASE=CB1420 Cardbus Controller + +pci:v00001524d00001421* + ID_PRODUCT_FROM_DATABASE=CB-720/2/4 Cardbus Controller + +pci:v00001524d00001422* + ID_PRODUCT_FROM_DATABASE=CB-722/4 Cardbus Controller + +pci:v00001525* + ID_VENDOR_FROM_DATABASE=IMPACT Technologies + +pci:v00001526* + ID_VENDOR_FROM_DATABASE=ISS, Inc + +pci:v00001527* + ID_VENDOR_FROM_DATABASE=SOLECTRON + +pci:v00001528* + ID_VENDOR_FROM_DATABASE=ACKSYS + +pci:v00001529* + ID_VENDOR_FROM_DATABASE=AMERICAN MICROSystems Inc + +pci:v0000152A* + ID_VENDOR_FROM_DATABASE=QUICKTURN DESIGN Systems + +pci:v0000152B* + ID_VENDOR_FROM_DATABASE=FLYTECH Technology CO Ltd + +pci:v0000152C* + ID_VENDOR_FROM_DATABASE=MACRAIGOR Systems LLC + +pci:v0000152D* + ID_VENDOR_FROM_DATABASE=QUANTA Computer Inc + +pci:v0000152E* + ID_VENDOR_FROM_DATABASE=MELEC Inc + +pci:v0000152F* + ID_VENDOR_FROM_DATABASE=PHILIPS - CRYPTO + +pci:v00001530* + ID_VENDOR_FROM_DATABASE=ACQIS Technology Inc + +pci:v00001531* + ID_VENDOR_FROM_DATABASE=CHRYON Corp + +pci:v00001532* + ID_VENDOR_FROM_DATABASE=ECHELON Corp + +pci:v00001532d00000020* + ID_PRODUCT_FROM_DATABASE=LonWorks PCLTA-20 PCI LonTalk Adapter + +pci:v00001533* + ID_VENDOR_FROM_DATABASE=BALTIMORE + +pci:v00001534* + ID_VENDOR_FROM_DATABASE=ROAD Corp + +pci:v00001535* + ID_VENDOR_FROM_DATABASE=EVERGREEN Technologies Inc + +pci:v00001536* + ID_VENDOR_FROM_DATABASE=ACTIS Computer + +pci:v00001537* + ID_VENDOR_FROM_DATABASE=DATALEX COMMUNCATIONS + +pci:v00001538* + ID_VENDOR_FROM_DATABASE=ARALION Inc + +pci:v00001538d00000303* + ID_PRODUCT_FROM_DATABASE=ARS106S Ultra ATA 133/100/66 Host Controller + +pci:v00001539* + ID_VENDOR_FROM_DATABASE=ATELIER INFORMATIQUES et ELECTRONIQUE ETUDES S.A. + +pci:v0000153A* + ID_VENDOR_FROM_DATABASE=ONO SOKKI + +pci:v0000153B* + ID_VENDOR_FROM_DATABASE=TERRATEC Electronic GmbH + +pci:v0000153Bd00001144* + ID_PRODUCT_FROM_DATABASE=Aureon 5.1 + +pci:v0000153Bd00001147* + ID_PRODUCT_FROM_DATABASE=Aureon 5.1 Sky + +pci:v0000153Bd00001158* + ID_PRODUCT_FROM_DATABASE=Philips Semiconductors SAA7134 (rev 01) [Terratec Cinergy 600 TV] + +pci:v0000153C* + ID_VENDOR_FROM_DATABASE=ANTAL Electronic + +pci:v0000153D* + ID_VENDOR_FROM_DATABASE=FILANET Corp + +pci:v0000153E* + ID_VENDOR_FROM_DATABASE=TECHWELL Inc + +pci:v0000153F* + ID_VENDOR_FROM_DATABASE=MIPS Technologies, Inc. + +pci:v0000153Fd00000001* + ID_PRODUCT_FROM_DATABASE=SOC-it 101 System Controller + +pci:v00001540* + ID_VENDOR_FROM_DATABASE=PROVIDEO MULTIMEDIA Co Ltd + +pci:v00001541* + ID_VENDOR_FROM_DATABASE=MACHONE Communications + +pci:v00001542* + ID_VENDOR_FROM_DATABASE=Concurrent Computer Corporation + +pci:v00001542d00009260* + ID_PRODUCT_FROM_DATABASE=RCIM-II Real-Time Clock & Interrupt Module + +pci:v00001543* + ID_VENDOR_FROM_DATABASE=SILICON Laboratories + +pci:v00001543d00003052* + ID_PRODUCT_FROM_DATABASE=Intel 537 [Winmodem] + +pci:v00001543d00003155* + ID_PRODUCT_FROM_DATABASE=Motorola SM56 Speakerphone Modem + +pci:v00001543d00004C22* + ID_PRODUCT_FROM_DATABASE=Si3036 MC'97 DAA + +pci:v00001544* + ID_VENDOR_FROM_DATABASE=DCM DATA Systems + +pci:v00001545* + ID_VENDOR_FROM_DATABASE=VISIONTEK + +pci:v00001546* + ID_VENDOR_FROM_DATABASE=IOI Technology Corp + +pci:v00001547* + ID_VENDOR_FROM_DATABASE=MITUTOYO Corp + +pci:v00001548* + ID_VENDOR_FROM_DATABASE=JET PROPULSION Laboratory + +pci:v00001549* + ID_VENDOR_FROM_DATABASE=INTERCONNECT Systems Solutions + +pci:v0000154A* + ID_VENDOR_FROM_DATABASE=MAX Technologies Inc + +pci:v0000154B* + ID_VENDOR_FROM_DATABASE=COMPUTEX Co Ltd + +pci:v0000154C* + ID_VENDOR_FROM_DATABASE=VISUAL Technology Inc + +pci:v0000154D* + ID_VENDOR_FROM_DATABASE=PAN INTERNATIONAL Industrial Corp + +pci:v0000154E* + ID_VENDOR_FROM_DATABASE=SERVOTEST Ltd + +pci:v0000154F* + ID_VENDOR_FROM_DATABASE=STRATABEAM Technology + +pci:v00001550* + ID_VENDOR_FROM_DATABASE=OPEN NETWORK Co Ltd + +pci:v00001551* + ID_VENDOR_FROM_DATABASE=SMART Electronic DEVELOPMENT GmBH + +pci:v00001552* + ID_VENDOR_FROM_DATABASE=RACAL AIRTECH Ltd + +pci:v00001553* + ID_VENDOR_FROM_DATABASE=CHICONY Electronics Co Ltd + +pci:v00001554* + ID_VENDOR_FROM_DATABASE=PROLINK Microsystems Corp + +pci:v00001555* + ID_VENDOR_FROM_DATABASE=GESYTEC GmBH + +pci:v00001556* + ID_VENDOR_FROM_DATABASE=PLD APPLICATIONS + +pci:v00001557* + ID_VENDOR_FROM_DATABASE=MEDIASTAR Co Ltd + +pci:v00001558* + ID_VENDOR_FROM_DATABASE=CLEVO/KAPOK Computer + +pci:v00001559* + ID_VENDOR_FROM_DATABASE=SI LOGIC Ltd + +pci:v0000155A* + ID_VENDOR_FROM_DATABASE=INNOMEDIA Inc + +pci:v0000155B* + ID_VENDOR_FROM_DATABASE=PROTAC INTERNATIONAL Corp + +pci:v0000155C* + ID_VENDOR_FROM_DATABASE=Cemax-Icon Inc + +pci:v0000155D* + ID_VENDOR_FROM_DATABASE=Mac System Co Ltd + +pci:v0000155E* + ID_VENDOR_FROM_DATABASE=LP Elektronik GmbH + +pci:v0000155F* + ID_VENDOR_FROM_DATABASE=Perle Systems Ltd + +pci:v00001560* + ID_VENDOR_FROM_DATABASE=Terayon Communications Systems + +pci:v00001561* + ID_VENDOR_FROM_DATABASE=Viewgraphics Inc + +pci:v00001562* + ID_VENDOR_FROM_DATABASE=Symbol Technologies + +pci:v00001563* + ID_VENDOR_FROM_DATABASE=A-Trend Technology Co Ltd + +pci:v00001564* + ID_VENDOR_FROM_DATABASE=Yamakatsu Electronics Industry Co Ltd + +pci:v00001565* + ID_VENDOR_FROM_DATABASE=Biostar Microtech Int'l Corp + +pci:v00001566* + ID_VENDOR_FROM_DATABASE=Ardent Technologies Inc + +pci:v00001567* + ID_VENDOR_FROM_DATABASE=Jungsoft + +pci:v00001568* + ID_VENDOR_FROM_DATABASE=DDK Electronics Inc + +pci:v00001569* + ID_VENDOR_FROM_DATABASE=Palit Microsystems Inc. + +pci:v0000156A* + ID_VENDOR_FROM_DATABASE=Avtec Systems + +pci:v0000156B* + ID_VENDOR_FROM_DATABASE=2wire Inc + +pci:v0000156C* + ID_VENDOR_FROM_DATABASE=Vidac Electronics GmbH + +pci:v0000156D* + ID_VENDOR_FROM_DATABASE=Alpha-Top Corp + +pci:v0000156E* + ID_VENDOR_FROM_DATABASE=Alfa Inc + +pci:v0000156F* + ID_VENDOR_FROM_DATABASE=M-Systems Flash Disk Pioneers Ltd + +pci:v00001570* + ID_VENDOR_FROM_DATABASE=Lecroy Corp + +pci:v00001571* + ID_VENDOR_FROM_DATABASE=Contemporary Controls + +pci:v00001571d0000A001* + ID_PRODUCT_FROM_DATABASE=CCSI PCI20-485 ARCnet + +pci:v00001571d0000A002* + ID_PRODUCT_FROM_DATABASE=CCSI PCI20-485D ARCnet + +pci:v00001571d0000A003* + ID_PRODUCT_FROM_DATABASE=CCSI PCI20-485X ARCnet + +pci:v00001571d0000A004* + ID_PRODUCT_FROM_DATABASE=CCSI PCI20-CXB ARCnet + +pci:v00001571d0000A005* + ID_PRODUCT_FROM_DATABASE=CCSI PCI20-CXS ARCnet + +pci:v00001571d0000A006* + ID_PRODUCT_FROM_DATABASE=CCSI PCI20-FOG-SMA ARCnet + +pci:v00001571d0000A007* + ID_PRODUCT_FROM_DATABASE=CCSI PCI20-FOG-ST ARCnet + +pci:v00001571d0000A008* + ID_PRODUCT_FROM_DATABASE=CCSI PCI20-TB5 ARCnet + +pci:v00001571d0000A009* + ID_PRODUCT_FROM_DATABASE=CCSI PCI20-5-485 5Mbit ARCnet + +pci:v00001571d0000A00A* + ID_PRODUCT_FROM_DATABASE=CCSI PCI20-5-485D 5Mbit ARCnet + +pci:v00001571d0000A00B* + ID_PRODUCT_FROM_DATABASE=CCSI PCI20-5-485X 5Mbit ARCnet + +pci:v00001571d0000A00C* + ID_PRODUCT_FROM_DATABASE=CCSI PCI20-5-FOG-ST 5Mbit ARCnet + +pci:v00001571d0000A00D* + ID_PRODUCT_FROM_DATABASE=CCSI PCI20-5-FOG-SMA 5Mbit ARCnet + +pci:v00001571d0000A201* + ID_PRODUCT_FROM_DATABASE=CCSI PCI22-485 10Mbit ARCnet + +pci:v00001571d0000A202* + ID_PRODUCT_FROM_DATABASE=CCSI PCI22-485D 10Mbit ARCnet + +pci:v00001571d0000A203* + ID_PRODUCT_FROM_DATABASE=CCSI PCI22-485X 10Mbit ARCnet + +pci:v00001571d0000A204* + ID_PRODUCT_FROM_DATABASE=CCSI PCI22-CHB 10Mbit ARCnet + +pci:v00001571d0000A205* + ID_PRODUCT_FROM_DATABASE=CCSI PCI22-FOG_ST 10Mbit ARCnet + +pci:v00001571d0000A206* + ID_PRODUCT_FROM_DATABASE=CCSI PCI22-THB 10Mbit ARCnet + +pci:v00001572* + ID_VENDOR_FROM_DATABASE=Otis Elevator Company + +pci:v00001573* + ID_VENDOR_FROM_DATABASE=Lattice - Vantis + +pci:v00001574* + ID_VENDOR_FROM_DATABASE=Fairchild Semiconductor + +pci:v00001575* + ID_VENDOR_FROM_DATABASE=Voltaire Advanced Data Security Ltd + +pci:v00001576* + ID_VENDOR_FROM_DATABASE=Viewcast COM + +pci:v00001578* + ID_VENDOR_FROM_DATABASE=HITT + +pci:v00001578d00004D34* + ID_PRODUCT_FROM_DATABASE=VPMK4 [Video Processor Mk IV] + +pci:v00001578d00005615* + ID_PRODUCT_FROM_DATABASE=VPMK3 [Video Processor Mk III] + +pci:v00001579* + ID_VENDOR_FROM_DATABASE=Dual Technology Corp + +pci:v0000157A* + ID_VENDOR_FROM_DATABASE=Japan Elecronics Ind Inc + +pci:v0000157B* + ID_VENDOR_FROM_DATABASE=Star Multimedia Corp + +pci:v0000157C* + ID_VENDOR_FROM_DATABASE=Eurosoft (UK) + +pci:v0000157Cd00008001* + ID_PRODUCT_FROM_DATABASE=Fix2000 PCI Y2K Compliance Card + +pci:v0000157D* + ID_VENDOR_FROM_DATABASE=Gemflex Networks + +pci:v0000157E* + ID_VENDOR_FROM_DATABASE=Transition Networks + +pci:v0000157F* + ID_VENDOR_FROM_DATABASE=PX Instruments Technology Ltd + +pci:v00001580* + ID_VENDOR_FROM_DATABASE=Primex Aerospace Co + +pci:v00001581* + ID_VENDOR_FROM_DATABASE=SEH Computertechnik GmbH + +pci:v00001582* + ID_VENDOR_FROM_DATABASE=Cytec Corp + +pci:v00001583* + ID_VENDOR_FROM_DATABASE=Inet Technologies Inc + +pci:v00001584* + ID_VENDOR_FROM_DATABASE=Uniwill Computer Corp + +pci:v00001585* + ID_VENDOR_FROM_DATABASE=Logitron + +pci:v00001586* + ID_VENDOR_FROM_DATABASE=Lancast Inc + +pci:v00001587* + ID_VENDOR_FROM_DATABASE=Konica Corp + +pci:v00001588* + ID_VENDOR_FROM_DATABASE=Solidum Systems Corp + +pci:v00001589* + ID_VENDOR_FROM_DATABASE=Atlantek Microsystems Pty Ltd + +pci:v00001589d00000008* + ID_PRODUCT_FROM_DATABASE=Leutron Vision PicPortExpress CL + +pci:v00001589d00000009* + ID_PRODUCT_FROM_DATABASE=Leutron Vision PicPortExpress CL Stereo + +pci:v0000158A* + ID_VENDOR_FROM_DATABASE=Digalog Systems Inc + +pci:v0000158B* + ID_VENDOR_FROM_DATABASE=Allied Data Technologies + +pci:v0000158C* + ID_VENDOR_FROM_DATABASE=Hitachi Semiconductor & Devices Sales Co Ltd + +pci:v0000158D* + ID_VENDOR_FROM_DATABASE=Point Multimedia Systems + +pci:v0000158E* + ID_VENDOR_FROM_DATABASE=Lara Technology Inc + +pci:v0000158F* + ID_VENDOR_FROM_DATABASE=Ditect Coop + +pci:v00001590* + ID_VENDOR_FROM_DATABASE=Hewlett-Packard Company + +pci:v00001590d00000001* + ID_PRODUCT_FROM_DATABASE=Eagle Cluster Manager + +pci:v00001590d00000002* + ID_PRODUCT_FROM_DATABASE=Osprey Cluster Manager + +pci:v00001590d00000003* + ID_PRODUCT_FROM_DATABASE=Harrier Cluster Manager + +pci:v00001590d0000A01D* + ID_PRODUCT_FROM_DATABASE=FC044X Fibre Channel HBA + +pci:v00001591* + ID_VENDOR_FROM_DATABASE=ARN + +pci:v00001592* + ID_VENDOR_FROM_DATABASE=Syba Tech Ltd + +pci:v00001592d00000781* + ID_PRODUCT_FROM_DATABASE=Multi-IO Card + +pci:v00001592d00000782* + ID_PRODUCT_FROM_DATABASE=Parallel Port Card 2xEPP + +pci:v00001592d00000783* + ID_PRODUCT_FROM_DATABASE=Multi-IO Card + +pci:v00001592d00000785* + ID_PRODUCT_FROM_DATABASE=Multi-IO Card + +pci:v00001592d00000786* + ID_PRODUCT_FROM_DATABASE=Multi-IO Card + +pci:v00001592d00000787* + ID_PRODUCT_FROM_DATABASE=Multi-IO Card + +pci:v00001592d00000788* + ID_PRODUCT_FROM_DATABASE=Multi-IO Card + +pci:v00001592d0000078A* + ID_PRODUCT_FROM_DATABASE=Multi-IO Card + +pci:v00001593* + ID_VENDOR_FROM_DATABASE=Bops Inc + +pci:v00001594* + ID_VENDOR_FROM_DATABASE=Netgame Ltd + +pci:v00001595* + ID_VENDOR_FROM_DATABASE=Diva Systems Corp + +pci:v00001596* + ID_VENDOR_FROM_DATABASE=Folsom Research Inc + +pci:v00001597* + ID_VENDOR_FROM_DATABASE=Memec Design Services + +pci:v00001598* + ID_VENDOR_FROM_DATABASE=Granite Microsystems + +pci:v00001599* + ID_VENDOR_FROM_DATABASE=Delta Electronics Inc + +pci:v0000159A* + ID_VENDOR_FROM_DATABASE=General Instrument + +pci:v0000159B* + ID_VENDOR_FROM_DATABASE=Faraday Technology Corp + +pci:v0000159C* + ID_VENDOR_FROM_DATABASE=Stratus Computer Systems + +pci:v0000159D* + ID_VENDOR_FROM_DATABASE=Ningbo Harrison Electronics Co Ltd + +pci:v0000159E* + ID_VENDOR_FROM_DATABASE=A-Max Technology Co Ltd + +pci:v0000159F* + ID_VENDOR_FROM_DATABASE=Galea Network Security + +pci:v000015A0* + ID_VENDOR_FROM_DATABASE=Compumaster SRL + +pci:v000015A1* + ID_VENDOR_FROM_DATABASE=Geocast Network Systems + +pci:v000015A2* + ID_VENDOR_FROM_DATABASE=Catalyst Enterprises Inc + +pci:v000015A2d00000001* + ID_PRODUCT_FROM_DATABASE=TA700 PCI Bus Analyzer/Exerciser + +pci:v000015A3* + ID_VENDOR_FROM_DATABASE=Italtel + +pci:v000015A4* + ID_VENDOR_FROM_DATABASE=X-Net OY + +pci:v000015A5* + ID_VENDOR_FROM_DATABASE=Toyota Macs Inc + +pci:v000015A6* + ID_VENDOR_FROM_DATABASE=Sunlight Ultrasound Technologies Ltd + +pci:v000015A7* + ID_VENDOR_FROM_DATABASE=SSE Telecom Inc + +pci:v000015A8* + ID_VENDOR_FROM_DATABASE=Shanghai Communications Technologies Center + +pci:v000015AA* + ID_VENDOR_FROM_DATABASE=Moreton Bay + +pci:v000015AB* + ID_VENDOR_FROM_DATABASE=Bluesteel Networks Inc + +pci:v000015AC* + ID_VENDOR_FROM_DATABASE=North Atlantic Instruments + +pci:v000015AD* + ID_VENDOR_FROM_DATABASE=VMware + +pci:v000015ADd00000405* + ID_PRODUCT_FROM_DATABASE=SVGA II Adapter + +pci:v000015ADd00000710* + ID_PRODUCT_FROM_DATABASE=SVGA Adapter + +pci:v000015ADd00000720* + ID_PRODUCT_FROM_DATABASE=VMXNET Ethernet Controller + +pci:v000015ADd00000740* + ID_PRODUCT_FROM_DATABASE=Virtual Machine Communication Interface + +pci:v000015ADd00000770* + ID_PRODUCT_FROM_DATABASE=USB2 EHCI Controller + +pci:v000015ADd00000774* + ID_PRODUCT_FROM_DATABASE=USB1.1 UHCI Controller + +pci:v000015ADd00000790* + ID_PRODUCT_FROM_DATABASE=PCI bridge + +pci:v000015ADd000007A0* + ID_PRODUCT_FROM_DATABASE=PCI Express Root Port + +pci:v000015ADd000007B0* + ID_PRODUCT_FROM_DATABASE=VMXNET3 Ethernet Controller + +pci:v000015ADd000007C0* + ID_PRODUCT_FROM_DATABASE=PVSCSI SCSI Controller + +pci:v000015ADd00000801* + ID_PRODUCT_FROM_DATABASE=Virtual Machine Interface + +pci:v000015ADd00000801sv000015ADsd00000800* + ID_PRODUCT_FROM_DATABASE=Hypervisor ROM Interface + +pci:v000015ADd00001977* + ID_PRODUCT_FROM_DATABASE=HD Audio Controller + +pci:v000015AE* + ID_VENDOR_FROM_DATABASE=Amersham Pharmacia Biotech + +pci:v000015B0* + ID_VENDOR_FROM_DATABASE=Zoltrix International Ltd + +pci:v000015B1* + ID_VENDOR_FROM_DATABASE=Source Technology Inc + +pci:v000015B2* + ID_VENDOR_FROM_DATABASE=Mosaid Technologies Inc + +pci:v000015B3* + ID_VENDOR_FROM_DATABASE=Mellanox Technologies + +pci:v000015B3d00000191* + ID_PRODUCT_FROM_DATABASE=MT25408 [ConnectX IB Flash Recovery] + +pci:v000015B3d000001F6* + ID_PRODUCT_FROM_DATABASE=MT27500 Family [ConnectX-3 Flash Recovery] + +pci:v000015B3d000001FF* + ID_PRODUCT_FROM_DATABASE=MT27600 Family [Connect-IB Flash Recovery] + +pci:v000015B3d00001002* + ID_PRODUCT_FROM_DATABASE=MT25400 Family [ConnectX-2 Virtual Function] + +pci:v000015B3d00001003* + ID_PRODUCT_FROM_DATABASE=MT27500 Family [ConnectX-3] + +pci:v000015B3d00001004* + ID_PRODUCT_FROM_DATABASE=MT27500 Family [ConnectX-3 Virtual Function] + +pci:v000015B3d00001005* + ID_PRODUCT_FROM_DATABASE=MT27510 Family + +pci:v000015B3d00001006* + ID_PRODUCT_FROM_DATABASE=MT27511 Family + +pci:v000015B3d00001007* + ID_PRODUCT_FROM_DATABASE=MT27520 Family + +pci:v000015B3d00001008* + ID_PRODUCT_FROM_DATABASE=MT27521 Family + +pci:v000015B3d00001009* + ID_PRODUCT_FROM_DATABASE=MT27530 Family + +pci:v000015B3d0000100A* + ID_PRODUCT_FROM_DATABASE=MT27531 Family + +pci:v000015B3d0000100B* + ID_PRODUCT_FROM_DATABASE=MT27540 Family + +pci:v000015B3d0000100C* + ID_PRODUCT_FROM_DATABASE=MT27541 Family + +pci:v000015B3d0000100D* + ID_PRODUCT_FROM_DATABASE=MT27550 Family + +pci:v000015B3d0000100E* + ID_PRODUCT_FROM_DATABASE=MT27551 Family + +pci:v000015B3d0000100F* + ID_PRODUCT_FROM_DATABASE=MT27560 Family + +pci:v000015B3d00001010* + ID_PRODUCT_FROM_DATABASE=MT27561 Family + +pci:v000015B3d00001011* + ID_PRODUCT_FROM_DATABASE=MT27600 [Connect-IB] + +pci:v000015B3d00001012* + ID_PRODUCT_FROM_DATABASE=MT27600 Family [Connect-IB Virtual Function] + +pci:v000015B3d00001013* + ID_PRODUCT_FROM_DATABASE=MT27620 Family + +pci:v000015B3d00001014* + ID_PRODUCT_FROM_DATABASE=MT27621 Family + +pci:v000015B3d00001015* + ID_PRODUCT_FROM_DATABASE=MT27630 Family + +pci:v000015B3d00001016* + ID_PRODUCT_FROM_DATABASE=MT27631 Family + +pci:v000015B3d00005274* + ID_PRODUCT_FROM_DATABASE=MT21108 InfiniBridge + +pci:v000015B3d00005A44* + ID_PRODUCT_FROM_DATABASE=MT23108 InfiniHost + +pci:v000015B3d00005A45* + ID_PRODUCT_FROM_DATABASE=MT23108 [Infinihost HCA Flash Recovery] + +pci:v000015B3d00005A46* + ID_PRODUCT_FROM_DATABASE=MT23108 PCI Bridge + +pci:v000015B3d00005E8C* + ID_PRODUCT_FROM_DATABASE=MT24204 [InfiniHost III Lx HCA] + +pci:v000015B3d00005E8D* + ID_PRODUCT_FROM_DATABASE=MT25204 [InfiniHost III Lx HCA Flash Recovery] + +pci:v000015B3d00006274* + ID_PRODUCT_FROM_DATABASE=MT25204 [InfiniHost III Lx HCA] + +pci:v000015B3d00006278* + ID_PRODUCT_FROM_DATABASE=MT25208 InfiniHost III Ex (Tavor compatibility mode) + +pci:v000015B3d00006279* + ID_PRODUCT_FROM_DATABASE=MT25208 [InfiniHost III Ex HCA Flash Recovery] + +pci:v000015B3d00006282* + ID_PRODUCT_FROM_DATABASE=MT25208 [InfiniHost III Ex] + +pci:v000015B3d00006340* + ID_PRODUCT_FROM_DATABASE=MT25408 [ConnectX VPI - IB SDR / 10GigE] + +pci:v000015B3d0000634A* + ID_PRODUCT_FROM_DATABASE=MT25418 [ConnectX VPI PCIe 2.0 2.5GT/s - IB DDR / 10GigE] + +pci:v000015B3d00006368* + ID_PRODUCT_FROM_DATABASE=MT25448 [ConnectX EN 10GigE, PCIe 2.0 2.5GT/s] + +pci:v000015B3d00006372* + ID_PRODUCT_FROM_DATABASE=MT25408 [ConnectX EN 10GigE 10GBaseT, PCIe 2.0 2.5GT/s] + +pci:v000015B3d00006732* + ID_PRODUCT_FROM_DATABASE=MT26418 [ConnectX VPI PCIe 2.0 5GT/s - IB DDR / 10GigE] + +pci:v000015B3d0000673C* + ID_PRODUCT_FROM_DATABASE=MT26428 [ConnectX VPI PCIe 2.0 5GT/s - IB QDR / 10GigE] + +pci:v000015B3d00006746* + ID_PRODUCT_FROM_DATABASE=MT26438 [ConnectX VPI PCIe 2.0 5GT/s - IB QDR / 10GigE Virtualization+] + +pci:v000015B3d00006746sv0000103Csd00001781* + ID_PRODUCT_FROM_DATABASE=NC543i 1-port 4x QDR IB/Flex-10 10Gb Adapter + +pci:v000015B3d00006746sv0000103Csd00003349* + ID_PRODUCT_FROM_DATABASE=NC543i 2-port 4xQDR IB/10Gb Adapter + +pci:v000015B3d00006750* + ID_PRODUCT_FROM_DATABASE=MT26448 [ConnectX EN 10GigE, PCIe 2.0 5GT/s] + +pci:v000015B3d0000675A* + ID_PRODUCT_FROM_DATABASE=MT25408 [ConnectX EN 10GigE 10GBaseT, PCIe Gen2 5GT/s] + +pci:v000015B3d00006764* + ID_PRODUCT_FROM_DATABASE=MT26468 [ConnectX EN 10GigE, PCIe 2.0 5GT/s Virtualization+] + +pci:v000015B3d00006764sv0000103Csd00003313* + ID_PRODUCT_FROM_DATABASE=HP NC542m Dual Port Flex-10 10GbE BLc Adapter + +pci:v000015B3d0000676E* + ID_PRODUCT_FROM_DATABASE=MT26478 [ConnectX EN 40GigE, PCIe 2.0 5GT/s] + +pci:v000015B3d00006778* + ID_PRODUCT_FROM_DATABASE=MT26488 [ConnectX VPI PCIe 2.0 5GT/s - IB DDR / 10GigE Virtualization+] + +pci:v000015B4* + ID_VENDOR_FROM_DATABASE=CCI/TRIAD + +pci:v000015B5* + ID_VENDOR_FROM_DATABASE=Cimetrics Inc + +pci:v000015B6* + ID_VENDOR_FROM_DATABASE=Texas Memory Systems Inc + +pci:v000015B6d00000001* + ID_PRODUCT_FROM_DATABASE=XP15 DSP Accelerator + +pci:v000015B6d00000002* + ID_PRODUCT_FROM_DATABASE=XP30 DSP Accelerator + +pci:v000015B6d00000003* + ID_PRODUCT_FROM_DATABASE=XP00 Data Acquisition Device + +pci:v000015B6d00000004* + ID_PRODUCT_FROM_DATABASE=XP35 DSP Accelerator + +pci:v000015B6d00000007* + ID_PRODUCT_FROM_DATABASE=XP100 DSP Accelerator [XP100-T0] + +pci:v000015B6d00000008* + ID_PRODUCT_FROM_DATABASE=XP100 DSP Accelerator [XP100-T1] + +pci:v000015B6d00000009* + ID_PRODUCT_FROM_DATABASE=XP100 DSP Accelerator [XP100-E0] + +pci:v000015B6d0000000A* + ID_PRODUCT_FROM_DATABASE=XP100 DSP Accelerator [XP100-E1] + +pci:v000015B6d0000000E* + ID_PRODUCT_FROM_DATABASE=XP100 DSP Accelerator [XP100-0] + +pci:v000015B6d0000000F* + ID_PRODUCT_FROM_DATABASE=XP100 DSP Accelerator [XP100-1] + +pci:v000015B6d00000010* + ID_PRODUCT_FROM_DATABASE=XP100 DSP Accelerator [XP100-P0] + +pci:v000015B6d00000011* + ID_PRODUCT_FROM_DATABASE=XP100 DSP Accelerator [XP100-P1] + +pci:v000015B6d00000012* + ID_PRODUCT_FROM_DATABASE=XP100 DSP Accelerator [XP100-P2] + +pci:v000015B6d00000013* + ID_PRODUCT_FROM_DATABASE=XP100 DSP Accelerator [XP100-P3] + +pci:v000015B6d00000014* + ID_PRODUCT_FROM_DATABASE=RamSan Flash SSD + +pci:v000015B6d00000015* + ID_PRODUCT_FROM_DATABASE=ZBox + +pci:v000015B7* + ID_VENDOR_FROM_DATABASE=Sandisk Corp + +pci:v000015B8* + ID_VENDOR_FROM_DATABASE=ADDI-DATA GmbH + +pci:v000015B8d00001001* + ID_PRODUCT_FROM_DATABASE=APCI1516 SP controller (16 digi outputs) + +pci:v000015B8d00001003* + ID_PRODUCT_FROM_DATABASE=APCI1032 SP controller (32 digi inputs w/ opto coupler) + +pci:v000015B8d00001004* + ID_PRODUCT_FROM_DATABASE=APCI2032 SP controller (32 digi outputs) + +pci:v000015B8d00001005* + ID_PRODUCT_FROM_DATABASE=APCI2200 SP controller (8/16 digi outputs (relay)) + +pci:v000015B8d00001006* + ID_PRODUCT_FROM_DATABASE=APCI1564 SP controller (32 digi ins, 32 digi outs) + +pci:v000015B8d0000100A* + ID_PRODUCT_FROM_DATABASE=APCI1696 SP controller (96 TTL I/Os) + +pci:v000015B8d00003001* + ID_PRODUCT_FROM_DATABASE=APCI3501 SP controller (analog output board) + +pci:v000015B8d0000300F* + ID_PRODUCT_FROM_DATABASE=APCI3600 Noise and vibration measurement board + +pci:v000015B8d00007001* + ID_PRODUCT_FROM_DATABASE=APCI7420 2-port Serial Controller + +pci:v000015B8d00007002* + ID_PRODUCT_FROM_DATABASE=APCI7300 Serial Controller + +pci:v000015B9* + ID_VENDOR_FROM_DATABASE=Maestro Digital Communications + +pci:v000015BA* + ID_VENDOR_FROM_DATABASE=Impacct Technology Corp + +pci:v000015BB* + ID_VENDOR_FROM_DATABASE=Portwell Inc + +pci:v000015BC* + ID_VENDOR_FROM_DATABASE=Agilent Technologies + +pci:v000015BCd00000100* + ID_PRODUCT_FROM_DATABASE=HPFC-5600 Tachyon DX2+ FC + +pci:v000015BCd00000103* + ID_PRODUCT_FROM_DATABASE=QX4 PCI Express quad 4-gigabit Fibre Channel controller + +pci:v000015BCd00000105* + ID_PRODUCT_FROM_DATABASE=Celerity FC-42XS Fibre Channel Adapter + +pci:v000015BCd00000105sv0000117Csd00000022* + ID_PRODUCT_FROM_DATABASE=Celerity FC-42XS Fibre Channel Adapter + +pci:v000015BCd00001100* + ID_PRODUCT_FROM_DATABASE=E8001-66442 PCI Express CIC + +pci:v000015BCd00002922* + ID_PRODUCT_FROM_DATABASE=64 Bit, 133MHz PCI-X Exerciser & Protocol Checker + +pci:v000015BCd00002928* + ID_PRODUCT_FROM_DATABASE=64 Bit, 66MHz PCI Exerciser & Analyzer + +pci:v000015BCd00002929* + ID_PRODUCT_FROM_DATABASE=64 Bit, 133MHz PCI-X Analyzer & Exerciser + +pci:v000015BD* + ID_VENDOR_FROM_DATABASE=DFI Inc + +pci:v000015BE* + ID_VENDOR_FROM_DATABASE=Sola Electronics + +pci:v000015BF* + ID_VENDOR_FROM_DATABASE=High Tech Computer Corp (HTC) + +pci:v000015C0* + ID_VENDOR_FROM_DATABASE=BVM Ltd + +pci:v000015C1* + ID_VENDOR_FROM_DATABASE=Quantel + +pci:v000015C2* + ID_VENDOR_FROM_DATABASE=Newer Technology Inc + +pci:v000015C3* + ID_VENDOR_FROM_DATABASE=Taiwan Mycomp Co Ltd + +pci:v000015C4* + ID_VENDOR_FROM_DATABASE=EVSX Inc + +pci:v000015C5* + ID_VENDOR_FROM_DATABASE=Procomp Informatics Ltd + +pci:v000015C5d00008010* + ID_PRODUCT_FROM_DATABASE=1394b - 1394 Firewire 3-Port Host Adapter Card + +pci:v000015C6* + ID_VENDOR_FROM_DATABASE=Technical University of Budapest + +pci:v000015C7* + ID_VENDOR_FROM_DATABASE=Tateyama System Laboratory Co Ltd + +pci:v000015C7d00000349* + ID_PRODUCT_FROM_DATABASE=Tateyama C-PCI PLC/NC card Rev.01A + +pci:v000015C8* + ID_VENDOR_FROM_DATABASE=Penta Media Co Ltd + +pci:v000015C9* + ID_VENDOR_FROM_DATABASE=Serome Technology Inc + +pci:v000015CA* + ID_VENDOR_FROM_DATABASE=Bitboys OY + +pci:v000015CB* + ID_VENDOR_FROM_DATABASE=AG Electronics Ltd + +pci:v000015CC* + ID_VENDOR_FROM_DATABASE=Hotrail Inc + +pci:v000015CD* + ID_VENDOR_FROM_DATABASE=Dreamtech Co Ltd + +pci:v000015CE* + ID_VENDOR_FROM_DATABASE=Genrad Inc + +pci:v000015CF* + ID_VENDOR_FROM_DATABASE=Hilscher GmbH + +pci:v000015D1* + ID_VENDOR_FROM_DATABASE=Infineon Technologies AG + +pci:v000015D2* + ID_VENDOR_FROM_DATABASE=FIC (First International Computer Inc) + +pci:v000015D3* + ID_VENDOR_FROM_DATABASE=NDS Technologies Israel Ltd + +pci:v000015D4* + ID_VENDOR_FROM_DATABASE=Iwill Corp + +pci:v000015D5* + ID_VENDOR_FROM_DATABASE=Tatung Co + +pci:v000015D6* + ID_VENDOR_FROM_DATABASE=Entridia Corp + +pci:v000015D7* + ID_VENDOR_FROM_DATABASE=Rockwell-Collins Inc + +pci:v000015D8* + ID_VENDOR_FROM_DATABASE=Cybernetics Technology Co Ltd + +pci:v000015D9* + ID_VENDOR_FROM_DATABASE=Super Micro Computer Inc + +pci:v000015DA* + ID_VENDOR_FROM_DATABASE=Cyberfirm Inc + +pci:v000015DB* + ID_VENDOR_FROM_DATABASE=Applied Computing Systems Inc + +pci:v000015DC* + ID_VENDOR_FROM_DATABASE=Litronic Inc + +pci:v000015DCd00000001* + ID_PRODUCT_FROM_DATABASE=Argus 300 PCI Cryptography Module + +pci:v000015DD* + ID_VENDOR_FROM_DATABASE=Sigmatel Inc + +pci:v000015DE* + ID_VENDOR_FROM_DATABASE=Malleable Technologies Inc + +pci:v000015DF* + ID_VENDOR_FROM_DATABASE=Infinilink Corp + +pci:v000015E0* + ID_VENDOR_FROM_DATABASE=Cacheflow Inc + +pci:v000015E1* + ID_VENDOR_FROM_DATABASE=Voice Technologies Group Inc + +pci:v000015E2* + ID_VENDOR_FROM_DATABASE=Quicknet Technologies Inc + +pci:v000015E2d00000500* + ID_PRODUCT_FROM_DATABASE=PhoneJack-PCI + +pci:v000015E3* + ID_VENDOR_FROM_DATABASE=Networth Technologies Inc + +pci:v000015E4* + ID_VENDOR_FROM_DATABASE=VSN Systemen BV + +pci:v000015E5* + ID_VENDOR_FROM_DATABASE=Valley technologies Inc + +pci:v000015E6* + ID_VENDOR_FROM_DATABASE=Agere Inc + +pci:v000015E7* + ID_VENDOR_FROM_DATABASE=Get Engineering Corp + +pci:v000015E8* + ID_VENDOR_FROM_DATABASE=National Datacomm Corp + +pci:v000015E8d00000130* + ID_PRODUCT_FROM_DATABASE=Wireless PCI Card + +pci:v000015E8d00000131* + ID_PRODUCT_FROM_DATABASE=NCP130A2 Wireless NIC + +pci:v000015E9* + ID_VENDOR_FROM_DATABASE=Pacific Digital Corp + +pci:v000015E9d00001841* + ID_PRODUCT_FROM_DATABASE=ADMA-100 DiscStaQ ATA Controller + +pci:v000015EA* + ID_VENDOR_FROM_DATABASE=Tokyo Denshi Sekei K.K. + +pci:v000015EB* + ID_VENDOR_FROM_DATABASE=DResearch Digital Media Systems GmbH + +pci:v000015EC* + ID_VENDOR_FROM_DATABASE=Beckhoff GmbH + +pci:v000015ECd00003101* + ID_PRODUCT_FROM_DATABASE=FC3101 Profibus DP 1 Channel PCI + +pci:v000015ECd00005102* + ID_PRODUCT_FROM_DATABASE=FC5102 + +pci:v000015ED* + ID_VENDOR_FROM_DATABASE=Macrolink Inc + +pci:v000015EE* + ID_VENDOR_FROM_DATABASE=In Win Development Inc + +pci:v000015EF* + ID_VENDOR_FROM_DATABASE=Intelligent Paradigm Inc + +pci:v000015F0* + ID_VENDOR_FROM_DATABASE=B-Tree Systems Inc + +pci:v000015F1* + ID_VENDOR_FROM_DATABASE=Times N Systems Inc + +pci:v000015F2* + ID_VENDOR_FROM_DATABASE=Diagnostic Instruments Inc + +pci:v000015F3* + ID_VENDOR_FROM_DATABASE=Digitmedia Corp + +pci:v000015F4* + ID_VENDOR_FROM_DATABASE=Valuesoft + +pci:v000015F5* + ID_VENDOR_FROM_DATABASE=Power Micro Research + +pci:v000015F6* + ID_VENDOR_FROM_DATABASE=Extreme Packet Device Inc + +pci:v000015F7* + ID_VENDOR_FROM_DATABASE=Banctec + +pci:v000015F8* + ID_VENDOR_FROM_DATABASE=Koga Electronics Co + +pci:v000015F9* + ID_VENDOR_FROM_DATABASE=Zenith Electronics Corp + +pci:v000015FA* + ID_VENDOR_FROM_DATABASE=J.P. Axzam Corp + +pci:v000015FB* + ID_VENDOR_FROM_DATABASE=Zilog Inc + +pci:v000015FC* + ID_VENDOR_FROM_DATABASE=Techsan Electronics Co Ltd + +pci:v000015FD* + ID_VENDOR_FROM_DATABASE=N-CUBED.NET + +pci:v000015FE* + ID_VENDOR_FROM_DATABASE=Kinpo Electronics Inc + +pci:v000015FF* + ID_VENDOR_FROM_DATABASE=Fastpoint Technologies Inc + +pci:v00001600* + ID_VENDOR_FROM_DATABASE=Northrop Grumman - Canada Ltd + +pci:v00001601* + ID_VENDOR_FROM_DATABASE=Tenta Technology + +pci:v00001602* + ID_VENDOR_FROM_DATABASE=Prosys-tec Inc + +pci:v00001603* + ID_VENDOR_FROM_DATABASE=Nokia Wireless Communications + +pci:v00001604* + ID_VENDOR_FROM_DATABASE=Central System Research Co Ltd + +pci:v00001605* + ID_VENDOR_FROM_DATABASE=Pairgain Technologies + +pci:v00001606* + ID_VENDOR_FROM_DATABASE=Europop AG + +pci:v00001607* + ID_VENDOR_FROM_DATABASE=Lava Semiconductor Manufacturing Inc + +pci:v00001608* + ID_VENDOR_FROM_DATABASE=Automated Wagering International + +pci:v00001609* + ID_VENDOR_FROM_DATABASE=Scimetric Instruments Inc + +pci:v00001612* + ID_VENDOR_FROM_DATABASE=Telesynergy Research Inc. + +pci:v00001618* + ID_VENDOR_FROM_DATABASE=Stone Ridge Technology + +pci:v00001618d00000001* + ID_PRODUCT_FROM_DATABASE=RDX 11 + +pci:v00001618d00000002* + ID_PRODUCT_FROM_DATABASE=HFT-01 + +pci:v00001618d00000400* + ID_PRODUCT_FROM_DATABASE=FarSync T2P (2 port X.21/V.35/V.24) + +pci:v00001618d00000440* + ID_PRODUCT_FROM_DATABASE=FarSync T4P (4 port X.21/V.35/V.24) + +pci:v00001618d00000610* + ID_PRODUCT_FROM_DATABASE=FarSync T1U (1 port X.21/V.35/V.24) + +pci:v00001618d00000620* + ID_PRODUCT_FROM_DATABASE=FarSync T2U (2 port X.21/V.35/V.24) + +pci:v00001618d00000640* + ID_PRODUCT_FROM_DATABASE=FarSync T4U (4 port X.21/V.35/V.24) + +pci:v00001618d00001610* + ID_PRODUCT_FROM_DATABASE=FarSync TE1 (T1,E1) + +pci:v00001618d00002610* + ID_PRODUCT_FROM_DATABASE=FarSync DSL-S1 (SHDSL) + +pci:v00001618d00003640* + ID_PRODUCT_FROM_DATABASE=FarSync T4E (4-port X.21/V.35/V.24) + +pci:v00001618d00004620* + ID_PRODUCT_FROM_DATABASE=FarSync T2Ue PCI Express (2-port X.21/V.35/V.24) + +pci:v00001618d00004640* + ID_PRODUCT_FROM_DATABASE=FarSync T4Ue PCI Express (4-port X.21/V.35/V.24) + +pci:v00001619* + ID_VENDOR_FROM_DATABASE=FarSite Communications Ltd + +pci:v00001619d00000400* + ID_PRODUCT_FROM_DATABASE=FarSync T2P (2 port X.21/V.35/V.24) + +pci:v00001619d00000440* + ID_PRODUCT_FROM_DATABASE=FarSync T4P (4 port X.21/V.35/V.24) + +pci:v00001619d00000610* + ID_PRODUCT_FROM_DATABASE=FarSync T1U (1 port X.21/V.35/V.24) + +pci:v00001619d00000620* + ID_PRODUCT_FROM_DATABASE=FarSync T2U (2 port X.21/V.35/V.24) + +pci:v00001619d00000640* + ID_PRODUCT_FROM_DATABASE=FarSync T4U (4 port X.21/V.35/V.24) + +pci:v00001619d00001610* + ID_PRODUCT_FROM_DATABASE=FarSync TE1 (T1,E1) + +pci:v00001619d00002610* + ID_PRODUCT_FROM_DATABASE=FarSync DSL-S1 (SHDSL) + +pci:v00001619d00003640* + ID_PRODUCT_FROM_DATABASE=FarSync T4E (4-port X.21/V.35/V.24) + +pci:v00001619d00004620* + ID_PRODUCT_FROM_DATABASE=FarSync T2Ue PCI Express (2-port X.21/V.35/V.24) + +pci:v00001619d00004640* + ID_PRODUCT_FROM_DATABASE=FarSync T4Ue PCI Express (4-port X.21/V.35/V.24) + +pci:v0000161F* + ID_VENDOR_FROM_DATABASE=Rioworks + +pci:v00001626* + ID_VENDOR_FROM_DATABASE=TDK Semiconductor Corp. + +pci:v00001626d00008410* + ID_PRODUCT_FROM_DATABASE=RTL81xx Fast Ethernet + +pci:v00001629* + ID_VENDOR_FROM_DATABASE=Kongsberg Spacetec AS + +pci:v00001629d00001003* + ID_PRODUCT_FROM_DATABASE=Format synchronizer v3.0 + +pci:v00001629d00001006* + ID_PRODUCT_FROM_DATABASE=Format synchronizer, model 10500 + +pci:v00001629d00001007* + ID_PRODUCT_FROM_DATABASE=Format synchronizer, model 21000 + +pci:v00001629d00002002* + ID_PRODUCT_FROM_DATABASE=Fast Universal Data Output + +pci:v00001631* + ID_VENDOR_FROM_DATABASE=Packard Bell B.V. + +pci:v00001638* + ID_VENDOR_FROM_DATABASE=Standard Microsystems Corp [SMC] + +pci:v00001638d00001100* + ID_PRODUCT_FROM_DATABASE=SMC2602W EZConnect / Addtron AWA-100 / Eumitcom PCI WL11000 + +pci:v0000163C* + ID_VENDOR_FROM_DATABASE=Smart Link Ltd. + +pci:v0000163Cd00003052* + ID_PRODUCT_FROM_DATABASE=SmartLink SmartPCI562 56K Modem + +pci:v0000163Cd00005449* + ID_PRODUCT_FROM_DATABASE=SmartPCI561 Modem + +pci:v00001641* + ID_VENDOR_FROM_DATABASE=MKNet Corp. + +pci:v00001657* + ID_VENDOR_FROM_DATABASE=Brocade Communications Systems, Inc. + +pci:v00001657d00000013* + ID_PRODUCT_FROM_DATABASE=425/825/42B/82B 4Gbps/8Gbps PCIe dual port FC HBA + +pci:v00001657d00000013sv0000103Csd00001742* + ID_PRODUCT_FROM_DATABASE=HP 82B 8Gbps dual port FC HBA + +pci:v00001657d00000013sv0000103Csd00001744* + ID_PRODUCT_FROM_DATABASE=HP 42B 4Gbps dual port FC HBA + +pci:v00001657d00000013sv00001657sd00000014* + ID_PRODUCT_FROM_DATABASE=425/825 4Gbps/8Gbps PCIe dual port FC HBA + +pci:v00001657d00000014* + ID_PRODUCT_FROM_DATABASE=1010/1020/1007/1741 10Gbps CNA + +pci:v00001657d00000014sv00001657sd00000014* + ID_PRODUCT_FROM_DATABASE=1010/1020/1007/1741 10Gbps CNA - FCOE + +pci:v00001657d00000014sv00001657sd00000015* + ID_PRODUCT_FROM_DATABASE=1010/1020/1007/1741 10Gbps CNA - LL + +pci:v00001657d00000017* + ID_PRODUCT_FROM_DATABASE=415/815/41B/81B 4Gbps/8Gbps PCIe single port FC HBA + +pci:v00001657d00000017sv0000103Csd00001741* + ID_PRODUCT_FROM_DATABASE=HP 41B 4Gbps single port FC HBA + +pci:v00001657d00000017sv0000103Csd00001743* + ID_PRODUCT_FROM_DATABASE=HP 81B 8Gbps single port FC HBA + +pci:v00001657d00000017sv00001657sd00000014* + ID_PRODUCT_FROM_DATABASE=415/815 4Gbps/8Gbps single port PCIe FC HBA + +pci:v00001657d00000021* + ID_PRODUCT_FROM_DATABASE=804 8Gbps FC HBA for HP Bladesystem c-class + +pci:v00001657d00000022* + ID_PRODUCT_FROM_DATABASE=1867/1860: 16Gbps/10Gbps Fabric Adapter + +pci:v00001657d00000022sv00001657sd00000022* + ID_PRODUCT_FROM_DATABASE=10Gbps CNA - FCOE + +pci:v00001657d00000022sv00001657sd00000023* + ID_PRODUCT_FROM_DATABASE=10Gbps CNA - LL + +pci:v00001657d00000022sv00001657sd00000024* + ID_PRODUCT_FROM_DATABASE=16Gbps FC HBA + +pci:v00001657d00000646* + ID_PRODUCT_FROM_DATABASE=400 4Gbps PCIe FC HBA + +pci:v0000165A* + ID_VENDOR_FROM_DATABASE=Epix Inc + +pci:v0000165Ad0000C100* + ID_PRODUCT_FROM_DATABASE=PIXCI(R) CL1 Camera Link Video Capture Board [custom QL5232] + +pci:v0000165Ad0000D200* + ID_PRODUCT_FROM_DATABASE=PIXCI(R) D2X Digital Video Capture Board [custom QL5232] + +pci:v0000165Ad0000D300* + ID_PRODUCT_FROM_DATABASE=PIXCI(R) D3X Digital Video Capture Board [custom QL5232] + +pci:v0000165D* + ID_VENDOR_FROM_DATABASE=Hsing Tech. Enterprise Co., Ltd. + +pci:v0000165F* + ID_VENDOR_FROM_DATABASE=Linux Media Labs, LLC + +pci:v0000165Fd00001020* + ID_PRODUCT_FROM_DATABASE=LMLM4 MPEG-4 encoder + +pci:v00001661* + ID_VENDOR_FROM_DATABASE=Worldspace Corp. + +pci:v00001668* + ID_VENDOR_FROM_DATABASE=Actiontec Electronics Inc + +pci:v00001668d00000100* + ID_PRODUCT_FROM_DATABASE=Mini-PCI bridge + +pci:v0000166D* + ID_VENDOR_FROM_DATABASE=Broadcom Corporation + +pci:v0000166Dd00000001* + ID_PRODUCT_FROM_DATABASE=SiByte BCM1125/1125H/1250 System-on-a-Chip PCI + +pci:v0000166Dd00000002* + ID_PRODUCT_FROM_DATABASE=SiByte BCM1125H/1250 System-on-a-Chip HyperTransport + +pci:v0000166Dd00000012* + ID_PRODUCT_FROM_DATABASE=SiByte BCM1280/BCM1480 System-on-a-Chip PCI-X + +pci:v0000166Dd00000014* + ID_PRODUCT_FROM_DATABASE=Sibyte BCM1280/BCM1480 System-on-a-Chip HyperTransport + +pci:v00001677* + ID_VENDOR_FROM_DATABASE=Bernecker + Rainer + +pci:v00001677d0000104E* + ID_PRODUCT_FROM_DATABASE=5LS172.6 B&R Dual CAN Interface Card + +pci:v00001677d000012D7* + ID_PRODUCT_FROM_DATABASE=5LS172.61 B&R Dual CAN Interface Card + +pci:v00001677d000020AD* + ID_PRODUCT_FROM_DATABASE=5ACPCI.MFIO-K01 Profibus DP / K-Feldbus / COM + +pci:v00001678* + ID_VENDOR_FROM_DATABASE=NetEffect + +pci:v00001678d00000100* + ID_PRODUCT_FROM_DATABASE=NE020 10Gb Accelerated Ethernet Adapter (iWARP RNIC) + +pci:v00001679* + ID_VENDOR_FROM_DATABASE=Tokyo Electron Device Ltd. + +pci:v00001679d00003000* + ID_PRODUCT_FROM_DATABASE=SD Standard host controller [Ellen] + +pci:v0000167B* + ID_VENDOR_FROM_DATABASE=ZyDAS Technology Corp. + +pci:v0000167Bd00002102* + ID_PRODUCT_FROM_DATABASE=ZyDAS ZD1202 + +pci:v0000167Bd00002102sv0000187Esd00003406* + ID_PRODUCT_FROM_DATABASE=ZyAIR B-122 CardBus 11Mbs Wireless LAN Card + +pci:v0000167Bd00002102sv0000187Esd00003407* + ID_PRODUCT_FROM_DATABASE=ZyAIR B-320 802.11b Wireless PCI Adapter + +pci:v0000167Bd00002116* + ID_PRODUCT_FROM_DATABASE=ZD1212B Wireless Adapter + +pci:v0000167D* + ID_VENDOR_FROM_DATABASE=Samsung Electro-Mechanics Co., Ltd. + +pci:v0000167Dd0000A000* + ID_PRODUCT_FROM_DATABASE=MagicLAN SWL-2210P 802.11b [Intersil ISL3874] + +pci:v0000167E* + ID_VENDOR_FROM_DATABASE=ONNTO Corp. + +pci:v00001681* + ID_VENDOR_FROM_DATABASE=Hercules + +pci:v00001682* + ID_VENDOR_FROM_DATABASE=XFX Pine Group Inc. + +pci:v00001688* + ID_VENDOR_FROM_DATABASE=CastleNet Technology Inc. + +pci:v00001688d00001170* + ID_PRODUCT_FROM_DATABASE=WLAN 802.11b card + +pci:v0000168C* + ID_VENDOR_FROM_DATABASE=Atheros Communications Inc. + +pci:v0000168Cd00000007* + ID_PRODUCT_FROM_DATABASE=AR5210 Wireless Network Adapter [AR5000 802.11a] + +pci:v0000168Cd00000007sv00001737sd00000007* + ID_PRODUCT_FROM_DATABASE=WPC54A Wireless PC Card + +pci:v0000168Cd00000007sv00001B47sd00000100* + ID_PRODUCT_FROM_DATABASE=Harmony 8450CN Wireless CardBus Module + +pci:v0000168Cd00000007sv00001B47sd00000110* + ID_PRODUCT_FROM_DATABASE=Skyline 4030 / Harmony 8450 802.11a Wireless CardBus Adapter + +pci:v0000168Cd00000007sv00008086sd00002501* + ID_PRODUCT_FROM_DATABASE=PRO/Wireless 5000 LAN PCI Adapter Module + +pci:v0000168Cd00000011* + ID_PRODUCT_FROM_DATABASE=AR5211 Wireless Network Adapter [AR5001A 802.11a] + +pci:v0000168Cd00000012* + ID_PRODUCT_FROM_DATABASE=AR5211 Wireless Network Adapter [AR5001X 802.11ab] + +pci:v0000168Cd00000012sv0000126Csd00008031* + ID_PRODUCT_FROM_DATABASE=2201 Mobile Adapter + +pci:v0000168Cd00000012sv00001385sd00004400* + ID_PRODUCT_FROM_DATABASE=WAB501 802.11ab Wireless CardBus Card + +pci:v0000168Cd00000012sv00001B47sd0000AA00* + ID_PRODUCT_FROM_DATABASE=8460 802.11ab Wireless CardBus Adapter + +pci:v0000168Cd00000013* + ID_PRODUCT_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter + +pci:v0000168Cd00000013sv00000308sd00003402* + ID_PRODUCT_FROM_DATABASE=AG-100 802.11ag Wireless Cardbus Adapter + +pci:v0000168Cd00000013sv00000308sd00003405* + ID_PRODUCT_FROM_DATABASE=G-102 v2 802.11g Wireless Cardbus Adapter + +pci:v0000168Cd00000013sv00000308sd00003408* + ID_PRODUCT_FROM_DATABASE=G-170S 802.11g Wireless CardBus Adapter + +pci:v0000168Cd00000013sv00000E11sd000000E5* + ID_PRODUCT_FROM_DATABASE=NC6000/NC8000 laptop + +pci:v0000168Cd00000013sv000010B7sd00006002* + ID_PRODUCT_FROM_DATABASE=3CRWE154A72 802.11abg Cardbus Adapter + +pci:v0000168Cd00000013sv00001113sd0000D301* + ID_PRODUCT_FROM_DATABASE=Philips CPWNA100 Wireless CardBus adapter + +pci:v0000168Cd00000013sv00001113sd0000EE23* + ID_PRODUCT_FROM_DATABASE=SMCWPCIT-G 108Mbps Wireless PCI adapter + +pci:v0000168Cd00000013sv00001154sd0000033B* + ID_PRODUCT_FROM_DATABASE=Buffalo WLI-CB-AMG54 + +pci:v0000168Cd00000013sv00001154sd0000034E* + ID_PRODUCT_FROM_DATABASE=Buffalo WLI-CB-AG108HP 802.11abg Cardbus Adapter + +pci:v0000168Cd00000013sv00001186sd00003202* + ID_PRODUCT_FROM_DATABASE=DWL-G650 (Rev B3,B5) Wireless cardbus adapter + +pci:v0000168Cd00000013sv00001186sd00003203* + ID_PRODUCT_FROM_DATABASE=AirPlus DWL-G520 Wireless PCI Adapter (rev. A) + +pci:v0000168Cd00000013sv00001186sd00003A12* + ID_PRODUCT_FROM_DATABASE=D-Link AirPlus DWL-G650 Wireless Cardbus Adapter(rev.C) + +pci:v0000168Cd00000013sv00001186sd00003A13* + ID_PRODUCT_FROM_DATABASE=AirPlus DWL-G520 Wireless PCI Adapter (rev. B) + +pci:v0000168Cd00000013sv00001186sd00003A14* + ID_PRODUCT_FROM_DATABASE=AirPremier AG DWL-AG530 Wireless PCI Adapter (rev.A) + +pci:v0000168Cd00000013sv00001186sd00003A17* + ID_PRODUCT_FROM_DATABASE=D-Link AirPremier DWL-G680 Wireless Cardbus Adapter + +pci:v0000168Cd00000013sv00001186sd00003A18* + ID_PRODUCT_FROM_DATABASE=D-Link AirPremier DWL-G550 Wireless PCI Adapter + +pci:v0000168Cd00000013sv00001186sd00003A1A* + ID_PRODUCT_FROM_DATABASE=WNA-2330 802.11bg Wireless CardBus Adapter + +pci:v0000168Cd00000013sv00001186sd00003A63* + ID_PRODUCT_FROM_DATABASE=D-Link AirPremier DWL-AG660 Wireless Cardbus Adapter + +pci:v0000168Cd00000013sv00001186sd00003A93* + ID_PRODUCT_FROM_DATABASE=Conceptronic C54I Wireless 801.11g PCI card + +pci:v0000168Cd00000013sv00001186sd00003A94* + ID_PRODUCT_FROM_DATABASE=Conceptronic C54C 802.11g Wireless Cardbus Adapter + +pci:v0000168Cd00000013sv00001186sd00003AB0* + ID_PRODUCT_FROM_DATABASE=Allnet ALL0281 Wireless PCI Card + +pci:v0000168Cd00000013sv00001385sd00004900* + ID_PRODUCT_FROM_DATABASE=WG311v1 802.11g Wireless PCI Adapter + +pci:v0000168Cd00000013sv00001385sd00004B00* + ID_PRODUCT_FROM_DATABASE=WG511T 108 Mbps Wireless PC Card (rev.A/B) + +pci:v0000168Cd00000013sv00001385sd00004D00* + ID_PRODUCT_FROM_DATABASE=WG311T 108 Mbps Wireless PCI Adapter (rev.A2) + +pci:v0000168Cd00000013sv00001385sd00004F00* + ID_PRODUCT_FROM_DATABASE=WG511U Double 108 Mbps Wireless PC Card + +pci:v0000168Cd00000013sv00001385sd00005A00* + ID_PRODUCT_FROM_DATABASE=WG311T 108 Mbps Wireless PCI Adapter (rev.A3) + +pci:v0000168Cd00000013sv00001385sd00005B00* + ID_PRODUCT_FROM_DATABASE=WG511T 108 Mbps Wireless PC Card (rev.C) + +pci:v0000168Cd00000013sv00001385sd00005D00* + ID_PRODUCT_FROM_DATABASE=WPN511 RangeMax Wireless PC Card + +pci:v0000168Cd00000013sv00001458sd0000E911* + ID_PRODUCT_FROM_DATABASE=Gigabyte GN-WIAG02 + +pci:v0000168Cd00000013sv00001468sd00000403* + ID_PRODUCT_FROM_DATABASE=U10H014 802.11g Cardbus Adapter + +pci:v0000168Cd00000013sv00001468sd00000408* + ID_PRODUCT_FROM_DATABASE=ThinkPad 11b/g Wireless LAN Mini PCI Adapter + +pci:v0000168Cd00000013sv000014B7sd00000A10* + ID_PRODUCT_FROM_DATABASE=8480-WD 802.11abg Cardbus Adapter + +pci:v0000168Cd00000013sv000014B7sd00000A60* + ID_PRODUCT_FROM_DATABASE=8482-WD ORiNOCO 11a/b/g Wireless PCI Adapter + +pci:v0000168Cd00000013sv000014B7sd0000AA30* + ID_PRODUCT_FROM_DATABASE=8800-FC 802.11bg Cardbus Adapter + +pci:v0000168Cd00000013sv000014B7sd0000AA40* + ID_PRODUCT_FROM_DATABASE=8470-WD 802.11bg Cardbus Adapter + +pci:v0000168Cd00000013sv000014B9sd0000CB21* + ID_PRODUCT_FROM_DATABASE=CB21 802.11a/b/g Cardbus Adapter + +pci:v0000168Cd00000013sv00001668sd00001026* + ID_PRODUCT_FROM_DATABASE=IBM HighRate 11 a/b/g Wireless CardBus Adapter + +pci:v0000168Cd00000013sv0000168Csd00000013* + ID_PRODUCT_FROM_DATABASE=AirPlus XtremeG DWL-G650 Wireless PCMCIA Adapter + +pci:v0000168Cd00000013sv0000168Csd00001025* + ID_PRODUCT_FROM_DATABASE=DWL-G650B2 Wireless CardBus Adapter + +pci:v0000168Cd00000013sv0000168Csd00001027* + ID_PRODUCT_FROM_DATABASE=Engenius NL-3054CB ARIES b/g CardBus Adapter + +pci:v0000168Cd00000013sv0000168Csd00001042* + ID_PRODUCT_FROM_DATABASE=Ubiquiti Networks SuperRange a/b/g Cardbus Adapter + +pci:v0000168Cd00000013sv0000168Csd00001051* + ID_PRODUCT_FROM_DATABASE=EZ Connect g 802.11g 108Mbps Wireless PCI Adapter + +pci:v0000168Cd00000013sv0000168Csd00002026* + ID_PRODUCT_FROM_DATABASE=Netgate 5354MP ARIES a(108Mb turbo)/b/g MiniPCI Adapter + +pci:v0000168Cd00000013sv0000168Csd00002027* + ID_PRODUCT_FROM_DATABASE=D-Link AirPlus DWL-G520 Wireless PCI Adapter (rev. A) + +pci:v0000168Cd00000013sv0000168Csd00002041* + ID_PRODUCT_FROM_DATABASE=Engenius 5354MP Plus ARIES2 b/g MiniPCI Adapter + +pci:v0000168Cd00000013sv0000168Csd00002042* + ID_PRODUCT_FROM_DATABASE=Engenius 5354MP Plus ARIES2 a/b/g MiniPCI Adapter + +pci:v0000168Cd00000013sv0000168Csd00002051* + ID_PRODUCT_FROM_DATABASE=TRENDnet TEW-443PI Wireless PCI Adapter + +pci:v0000168Cd00000013sv000016A5sd0000160A* + ID_PRODUCT_FROM_DATABASE=BWP712 802.11bg Wireless CardBus Adapter + +pci:v0000168Cd00000013sv000016ABsd00007302* + ID_PRODUCT_FROM_DATABASE=Trust Speedshare Turbo Pro Wireless PCI Adapter + +pci:v0000168Cd00000013sv00001737sd00000017* + ID_PRODUCT_FROM_DATABASE=WPC55AG + +pci:v0000168Cd00000013sv00001737sd00000026* + ID_PRODUCT_FROM_DATABASE=WMP55AG v1.1 + +pci:v0000168Cd00000013sv00001737sd00000035* + ID_PRODUCT_FROM_DATABASE=WPC55AG v1.2 802.11abg Cardbus Adapter + +pci:v0000168Cd00000013sv00001737sd00000036* + ID_PRODUCT_FROM_DATABASE=WMP55AG v1.2 802.11abg PCI Adapter + +pci:v0000168Cd00000013sv00001799sd00003000* + ID_PRODUCT_FROM_DATABASE=F6D3000 Dual-Band Wireless A+G Desktop Card + +pci:v0000168Cd00000013sv00001799sd00003010* + ID_PRODUCT_FROM_DATABASE=F6D3010 Dual-Band Wireless A+G Notebook Card + +pci:v0000168Cd00000013sv000017CFsd00000042* + ID_PRODUCT_FROM_DATABASE=Z-COMAX Highpower XG-622H (400mw) 802.11b/g mini-PCI Adapter + +pci:v0000168Cd00000013sv0000185Fsd00001012* + ID_PRODUCT_FROM_DATABASE=CM9 Wireless a/b/g MiniPCI Adapter + +pci:v0000168Cd00000013sv0000185Fsd00002012* + ID_PRODUCT_FROM_DATABASE=Wistron NeWeb WLAN a+b+g model CB9 + +pci:v0000168Cd00000013sv0000A727sd00006801* + ID_PRODUCT_FROM_DATABASE=3CRXJK10075 OfficeConnect Wireless 108Mbps 11g XJACK PC Card + +pci:v0000168Cd0000001A* + ID_PRODUCT_FROM_DATABASE=AR2413/AR2414 Wireless Network Adapter [AR5005G(S) 802.11bg] + +pci:v0000168Cd0000001Asv00001052sd0000168C* + ID_PRODUCT_FROM_DATABASE=Sweex Wireless Lan PC Card 54Mbps + +pci:v0000168Cd0000001Asv00001113sd0000EE20* + ID_PRODUCT_FROM_DATABASE=SMC Wireless CardBus Adapter 802.11g (SMCWCB-G EU) + +pci:v0000168Cd0000001Asv00001113sd0000EE24* + ID_PRODUCT_FROM_DATABASE=SMC Wireless PCI Card WPCI-G + +pci:v0000168Cd0000001Asv00001186sd00003A15* + ID_PRODUCT_FROM_DATABASE=AirPlus G DWL-G630 Wireless Cardbus Adapter (rev.D1) + +pci:v0000168Cd0000001Asv00001186sd00003A16* + ID_PRODUCT_FROM_DATABASE=AirPlus G DWL-G510 Wireless PCI Adapter(rev.B) + +pci:v0000168Cd0000001Asv00001186sd00003A1C* + ID_PRODUCT_FROM_DATABASE=WNA-1330 Notebook Adapter + +pci:v0000168Cd0000001Asv00001186sd00003A1D* + ID_PRODUCT_FROM_DATABASE=WDA-1320 Desktop Adapter + +pci:v0000168Cd0000001Asv00001186sd00003A23* + ID_PRODUCT_FROM_DATABASE=AirPlus G DWL-G520+A Wireless PCI Adapter + +pci:v0000168Cd0000001Asv00001186sd00003A24* + ID_PRODUCT_FROM_DATABASE=AirPlus G DWL-G650+A Wireless Cardbus Adapter + +pci:v0000168Cd0000001Asv00001186sd00003B08* + ID_PRODUCT_FROM_DATABASE=AirPlus G DWL-G630 Wireless Cardbus Adapter (rev.C1) + +pci:v0000168Cd0000001Asv0000168Csd0000001A* + ID_PRODUCT_FROM_DATABASE=Belkin FD7000 + +pci:v0000168Cd0000001Asv0000168Csd00001052* + ID_PRODUCT_FROM_DATABASE=TP-Link TL-WN510G Wireless CardBus Adapter + +pci:v0000168Cd0000001Asv0000168Csd00002052* + ID_PRODUCT_FROM_DATABASE=Compex Wireless 802.11 b/g MiniPCI Adapter, Rev A1 [WLM54G] + +pci:v0000168Cd0000001Asv000016ECsd00000122* + ID_PRODUCT_FROM_DATABASE=Wireless PCI Adapter Model 5418 + +pci:v0000168Cd0000001Asv00001737sd00000053* + ID_PRODUCT_FROM_DATABASE=WPC54G v7 802.11g Wireless-G Notebook Adapter + +pci:v0000168Cd0000001Asv00001799sd0000700C* + ID_PRODUCT_FROM_DATABASE=F5D7000 v5000 Wireless G Desktop Card + +pci:v0000168Cd0000001Asv00001799sd0000701D* + ID_PRODUCT_FROM_DATABASE=F5D7010 v5000 Wireless G Notebook Card + +pci:v0000168Cd0000001Asv000017F9sd00000008* + ID_PRODUCT_FROM_DATABASE=DX-WGNBC 802.11bg Wireless CardBus Adapter + +pci:v0000168Cd0000001Asv000017F9sd00000018* + ID_PRODUCT_FROM_DATABASE=DX-WGDTC 802.11bg Wireless PCI Adapter + +pci:v0000168Cd0000001B* + ID_PRODUCT_FROM_DATABASE=AR5413/AR5414 Wireless Network Adapter [AR5006X(S) 802.11abg] + +pci:v0000168Cd0000001Bsv00000777sd00003002* + ID_PRODUCT_FROM_DATABASE=XR2 802.11g Wireless Mini PCI Adapter + +pci:v0000168Cd0000001Bsv00000777sd00003005* + ID_PRODUCT_FROM_DATABASE=XR5 802.11a Wireless Mini PCI Adapter + +pci:v0000168Cd0000001Bsv00000777sd00003009* + ID_PRODUCT_FROM_DATABASE=XR9 900MHz Wireless Mini PCI Adapter + +pci:v0000168Cd0000001Bsv00001154sd0000034E* + ID_PRODUCT_FROM_DATABASE=WLI-CB-AG108HP 802.11abg Wireless CardBus Adapter + +pci:v0000168Cd0000001Bsv00001186sd00003A19* + ID_PRODUCT_FROM_DATABASE=D-Link AirPremier AG DWL-AG660 Wireless Cardbus Adapter + +pci:v0000168Cd0000001Bsv00001186sd00003A22* + ID_PRODUCT_FROM_DATABASE=AirPremier AG DWL-AG530 Wireless PCI Adapter (rev.B) + +pci:v0000168Cd0000001Bsv000011ADsd00005001* + ID_PRODUCT_FROM_DATABASE=WN5301A 802.11bg Wireless PCI Adapter + +pci:v0000168Cd0000001Bsv00001458sd0000E901* + ID_PRODUCT_FROM_DATABASE=GN-WI01HT Wireless a/b/g MiniPCI Adapter + +pci:v0000168Cd0000001Bsv0000168Csd0000001B* + ID_PRODUCT_FROM_DATABASE=Wireless LAN PCI LiteOn + +pci:v0000168Cd0000001Bsv0000168Csd00001062* + ID_PRODUCT_FROM_DATABASE=IPN-W100CB 802.11abg Wireless CardBus Adapter + +pci:v0000168Cd0000001Bsv0000168Csd00002062* + ID_PRODUCT_FROM_DATABASE=EnGenius EMP-8602 (400mw) or Compex WLM54AG (SuperAG) + +pci:v0000168Cd0000001Bsv0000168Csd00002063* + ID_PRODUCT_FROM_DATABASE=EnGenius EMP-8602 (400mw) or Compex WLM54AG + +pci:v0000168Cd0000001Bsv000017F9sd0000000B* + ID_PRODUCT_FROM_DATABASE=WL-711A 802.11abg Wireless CardBus Adapter + +pci:v0000168Cd0000001Bsv000017F9sd0000000C* + ID_PRODUCT_FROM_DATABASE=WPIA-112AG 802.11abg Wireless PCI Adapter + +pci:v0000168Cd0000001Bsv000017F9sd0000000D* + ID_PRODUCT_FROM_DATABASE=PC-686X 802.11abg Wireless Mini PCI Adapter + +pci:v0000168Cd0000001Bsv0000185Fsd00001600* + ID_PRODUCT_FROM_DATABASE=DCMA-82 High Power WLAN 802.11a/b/g mini-PCI Module (Super A/G, eXtended Range, 400mW) + +pci:v0000168Cd0000001Bsv00001948sd00003ABA* + ID_PRODUCT_FROM_DATABASE=RBTBJ-AW 802.11abg Wireless Cardbus Adapter + +pci:v0000168Cd0000001Bsv0000A727sd00006804* + ID_PRODUCT_FROM_DATABASE=Wireless 11a/b/g PC Card with XJACK(r) Antenna + +pci:v0000168Cd0000001C* + ID_PRODUCT_FROM_DATABASE=AR242x / AR542x Wireless Network Adapter (PCI-Express) + +pci:v0000168Cd0000001Csv00000777sd00003006* + ID_PRODUCT_FROM_DATABASE=SRX 802.11abg Wireless ExpressCard Adapter + +pci:v0000168Cd0000001Csv0000103Csd0000137A* + ID_PRODUCT_FROM_DATABASE=AR5BXB63 (Foxconn) 802.11bg Mini PCIe NIC + +pci:v0000168Cd0000001Csv0000106Bsd00000086* + ID_PRODUCT_FROM_DATABASE=AR5BXB6 802.11abg Wireless Mini PCIe Card + +pci:v0000168Cd0000001Csv0000144Fsd00007106* + ID_PRODUCT_FROM_DATABASE=WLL3140 (Toshiba PA3501U-1MPC) 802.11bg Wireless Mini PCIe Card + +pci:v0000168Cd0000001Csv0000144Fsd00007128* + ID_PRODUCT_FROM_DATABASE=WLL3141 (Toshiba PA3613U-1MPC) 802.11bg Wireless Mini PCIe Card + +pci:v0000168Cd0000001Csv00001468sd00000428* + ID_PRODUCT_FROM_DATABASE=AR5BXB63 802.11bg NIC + +pci:v0000168Cd0000001Csv00001468sd0000042A* + ID_PRODUCT_FROM_DATABASE=AR5007EG 802.11bg NIC + +pci:v0000168Cd0000001Csv0000147Bsd00001033* + ID_PRODUCT_FROM_DATABASE=AirPace Wi-Fi + +pci:v0000168Cd0000001Csv0000168Csd0000001C* + ID_PRODUCT_FROM_DATABASE=AR242x 802.11abg NIC (PCI Express) + +pci:v0000168Cd0000001Csv0000168Csd00003061* + ID_PRODUCT_FROM_DATABASE=AR5006EGS 802.11bg NIC (2.4GHz, PCI Express) + +pci:v0000168Cd0000001Csv0000168Csd00003062* + ID_PRODUCT_FROM_DATABASE=AR5006EXS 802.11abg NIC (2.4/5.0GHz, PCI Express) + +pci:v0000168Cd0000001Csv0000168Csd00003063* + ID_PRODUCT_FROM_DATABASE=AR5006EX 802.11abg NIC (2.4/5.0GHz, PCI Express) + +pci:v0000168Cd0000001Csv0000168Csd00003065* + ID_PRODUCT_FROM_DATABASE=AR5006EG 802.11bg NIC (2.4GHz, PCI Express) + +pci:v0000168Cd0000001Csv0000168Csd00003067* + ID_PRODUCT_FROM_DATABASE=AR242x 802.11abg Wireless PCI Express Adapter (rev 01) + +pci:v0000168Cd0000001Csv00001A3Bsd00001026* + ID_PRODUCT_FROM_DATABASE=AW-GE780 802.11bg Wireless Mini PCIe Card + +pci:v0000168Cd0000001D* + ID_PRODUCT_FROM_DATABASE=AR2417 Wireless Network Adapter [AR5007G 802.11bg] + +pci:v0000168Cd0000001Dsv00001799sd0000720B* + ID_PRODUCT_FROM_DATABASE=F5D7000 v8000 Wireless G Desktop Card + +pci:v0000168Cd0000001Dsv00001799sd0000721B* + ID_PRODUCT_FROM_DATABASE=F5D7010 v8000 Wireless G Notebook Card + +pci:v0000168Cd00000020* + ID_PRODUCT_FROM_DATABASE=AR5513 802.11abg Wireless NIC + +pci:v0000168Cd00000020sv00000308sd00003407* + ID_PRODUCT_FROM_DATABASE=M-102 802.11g Wireless Cardbus Adapter + +pci:v0000168Cd00000020sv00001186sd00003A67* + ID_PRODUCT_FROM_DATABASE=DWL-G650M Super G MIMO Wireless Notebook Adapter + +pci:v0000168Cd00000020sv00001186sd00003A68* + ID_PRODUCT_FROM_DATABASE=DWL-G520M Wireless 108G MIMO Desktop Adapter + +pci:v0000168Cd00000020sv0000187Esd0000340E* + ID_PRODUCT_FROM_DATABASE=M-302 802.11g Wireless PCI Adapter + +pci:v0000168Cd00000020sv00001976sd00002003* + ID_PRODUCT_FROM_DATABASE=TEW-601PC 802.11g Wireless CardBus Adapter + +pci:v0000168Cd00000023* + ID_PRODUCT_FROM_DATABASE=AR5416 Wireless Network Adapter [AR5008 802.11(a)bgn] + +pci:v0000168Cd00000023sv00000308sd0000340B* + ID_PRODUCT_FROM_DATABASE=NWD-170N 802.11bgn Wireless CardBus Adapter + +pci:v0000168Cd00000023sv00001154sd00000365* + ID_PRODUCT_FROM_DATABASE=Buffalo WLP-CB-AG300 802.11abgn Cardbus Adapter + +pci:v0000168Cd00000023sv00001154sd00000367* + ID_PRODUCT_FROM_DATABASE=WLI-CB-AG301N 802.11abgn Wireless CardBus Adapter + +pci:v0000168Cd00000023sv00001186sd00003A6A* + ID_PRODUCT_FROM_DATABASE=DWA-642 802.11n RangeBooster N CardBus Adapter + +pci:v0000168Cd00000023sv00001186sd00003A6B* + ID_PRODUCT_FROM_DATABASE=DWA-547 802.11n RangeBooster N 650 DeskTop Adapter + +pci:v0000168Cd00000023sv00001186sd00003A6D* + ID_PRODUCT_FROM_DATABASE=DWA-552 802.11n Xtreme N Desktop Adapter (rev A1) + +pci:v0000168Cd00000023sv00001186sd00003A76* + ID_PRODUCT_FROM_DATABASE=DWA-645 802.11n RangeBooster N 650 Notebook Adapter (rev A1) + +pci:v0000168Cd00000023sv00001737sd00000059* + ID_PRODUCT_FROM_DATABASE=WPC300N v2 Wireless-N Notebook Adapter + +pci:v0000168Cd00000023sv00001737sd00000069* + ID_PRODUCT_FROM_DATABASE=WPC100 v1 802.11n RangePlus Wireless Notebook Adapter + +pci:v0000168Cd00000023sv00001737sd00000072* + ID_PRODUCT_FROM_DATABASE=WMP110 v1 802.11n RangePlus Wireless PCI Adapter + +pci:v0000168Cd00000023sv00001799sd00008011* + ID_PRODUCT_FROM_DATABASE=F5D8011 v1 802.11n N1 Wireless Notebook Card + +pci:v0000168Cd00000023sv0000187Esd00003411* + ID_PRODUCT_FROM_DATABASE=NWD-370N 802.11n Wireless PCI Adapter + +pci:v0000168Cd00000023sv00001976sd00002008* + ID_PRODUCT_FROM_DATABASE=TEW-621PC 802.11bgn Wireless CardBus Adapter + +pci:v0000168Cd00000024* + ID_PRODUCT_FROM_DATABASE=AR5418 Wireless Network Adapter [AR5008E 802.11(a)bgn] (PCI-Express) + +pci:v0000168Cd00000024sv0000106Bsd00000087* + ID_PRODUCT_FROM_DATABASE=AR5BXB72 802.11abgn Mini PCIe Card [AR5008E-3NX] + +pci:v0000168Cd00000027* + ID_PRODUCT_FROM_DATABASE=AR9160 Wireless Network Adapter [AR9001 802.11(a)bgn] + +pci:v0000168Cd00000027sv00000777sd00004082* + ID_PRODUCT_FROM_DATABASE=SR71-A 802.11abgn Wireless Mini PCI Adapter + +pci:v0000168Cd00000029* + ID_PRODUCT_FROM_DATABASE=AR922X Wireless Network Adapter + +pci:v0000168Cd00000029sv00000777sd00004005* + ID_PRODUCT_FROM_DATABASE=SR71-15 802.11an Mini PCI Adapter + +pci:v0000168Cd00000029sv00001186sd00003A7A* + ID_PRODUCT_FROM_DATABASE=DWA-552 802.11n Xtreme N Desktop Adapter (rev A2) + +pci:v0000168Cd0000002A* + ID_PRODUCT_FROM_DATABASE=AR928X Wireless Network Adapter (PCI-Express) + +pci:v0000168Cd0000002Asv00000777sd00004F05* + ID_PRODUCT_FROM_DATABASE=SR71-X 802.11abgn Wireless ExpressCard Adapter [AR9280] + +pci:v0000168Cd0000002Asv0000103Csd00003041* + ID_PRODUCT_FROM_DATABASE=AR5BHB92-H 802.11abgn Wireless Half-size Mini PCIe Card [AR9280] + +pci:v0000168Cd0000002Asv0000105Bsd0000E006* + ID_PRODUCT_FROM_DATABASE=T77H053.00 802.11bgn Wireless Mini PCIe Card [AR9281] + +pci:v0000168Cd0000002Asv0000105Bsd0000E01F* + ID_PRODUCT_FROM_DATABASE=T77H047.31 802.11bgn Wireless Half-size Mini PCIe Card [AR9283] + +pci:v0000168Cd0000002Asv000011ADsd00006600* + ID_PRODUCT_FROM_DATABASE=WN6600A 802.11bgn Wireless Mini PCIe Card [AR9281] + +pci:v0000168Cd0000002Asv0000144Fsd00007141* + ID_PRODUCT_FROM_DATABASE=WLL6080 802.11bgn Wireless Mini PCIe Card [AR9281] + +pci:v0000168Cd0000002Asv0000168Csd00000203* + ID_PRODUCT_FROM_DATABASE=DW1525 802.11abgn WLAN PCIe Card [AR9280] + +pci:v0000168Cd0000002Asv00001A32sd00000303* + ID_PRODUCT_FROM_DATABASE=EM303 802.11bgn Wireless Mini PCIe Card [AR9281] + +pci:v0000168Cd0000002Asv00001A32sd00000306* + ID_PRODUCT_FROM_DATABASE=EM306 802.11bgn Wireless Half-size Mini PCIe Card [AR9283] + +pci:v0000168Cd0000002Asv00001A3Bsd00001067* + ID_PRODUCT_FROM_DATABASE=AW-NE771 802.11bgn Wireless Mini PCIe Card [AR9281] + +pci:v0000168Cd0000002Asv00001A3Bsd00001081* + ID_PRODUCT_FROM_DATABASE=AW-NE773 802.11abgn Wireless Half-size Mini PCIe Card [AR9280] + +pci:v0000168Cd0000002B* + ID_PRODUCT_FROM_DATABASE=AR9285 Wireless Network Adapter (PCI-Express) + +pci:v0000168Cd0000002Bsv00001028sd00000204* + ID_PRODUCT_FROM_DATABASE=Wireless 1502 802.11bgn Half-size Mini PCIe Card + +pci:v0000168Cd0000002Bsv00001028sd00000205* + ID_PRODUCT_FROM_DATABASE=Wireless 1702 802.11bgn Half-size Mini PCIe Card [AR9002WB-1NGCD] + +pci:v0000168Cd0000002Bsv0000103Csd0000303F* + ID_PRODUCT_FROM_DATABASE=U98Z062.10 802.11bgn Wireless Half-size Mini PCIe Card + +pci:v0000168Cd0000002Bsv0000103Csd00003040* + ID_PRODUCT_FROM_DATABASE=U98Z062.12 802.11bgn Wireless Half-size Mini PCIe Card + +pci:v0000168Cd0000002Bsv0000105Bsd0000E017* + ID_PRODUCT_FROM_DATABASE=T77H126.00 802.11bgn Wireless Half-size Mini PCIe Card + +pci:v0000168Cd0000002Bsv00001113sd0000E811* + ID_PRODUCT_FROM_DATABASE=WN7811A (Toshiba PA3722U-1MPC) 802.11bgn Wireless Half-size Mini PCIe Card + +pci:v0000168Cd0000002Bsv0000185Fsd000030AF* + ID_PRODUCT_FROM_DATABASE=DNXA-95 802.11bgn Wireless Half-size Mini PCIe Card + +pci:v0000168Cd0000002Bsv00001931sd00000023* + ID_PRODUCT_FROM_DATABASE=Option GTM67x PCIe WiFi Adapter + +pci:v0000168Cd0000002Bsv00001A3Bsd00001089* + ID_PRODUCT_FROM_DATABASE=AW-NE785 / AW-NE785H 802.11bgn Wireless Full or Half-size Mini PCIe Card + +pci:v0000168Cd0000002Bsv00001A3Bsd00002C37* + ID_PRODUCT_FROM_DATABASE=AW-NB037H 802.11bgn Wireless Half-size Mini PCIe Card [AR9002WB-1NGCD] + +pci:v0000168Cd0000002Bsv00001B9Asd00000401* + ID_PRODUCT_FROM_DATABASE=XW204E 802.11bgn Wireless Half-size Mini PCIe Card + +pci:v0000168Cd0000002Bsv00001B9Asd00000C03* + ID_PRODUCT_FROM_DATABASE=WB214E 802.11bgn Wireless Half-size Mini PCIe Card [AR9002WB-1NGCD] + +pci:v0000168Cd0000002C* + ID_PRODUCT_FROM_DATABASE=AR2427 802.11bg Wireless Network Adapter (PCI-Express) + +pci:v0000168Cd0000002D* + ID_PRODUCT_FROM_DATABASE=AR9227 Wireless Network Adapter + +pci:v0000168Cd0000002E* + ID_PRODUCT_FROM_DATABASE=AR9287 Wireless Network Adapter (PCI-Express) + +pci:v0000168Cd00000030* + ID_PRODUCT_FROM_DATABASE=AR9300 Wireless LAN adaptor + +pci:v0000168Cd00000030sv0000103Csd00001627* + ID_PRODUCT_FROM_DATABASE=AR9380/HB112 802.11abgn 3×3 Wi-Fi Adapter + +pci:v0000168Cd00000030sv00001A56sd00002000* + ID_PRODUCT_FROM_DATABASE=Killer Wireless-N 1102 Half-size Mini PCIe Card [AR9382] + +pci:v0000168Cd00000030sv00001A56sd00002001* + ID_PRODUCT_FROM_DATABASE=Killer Wireless-N 1103 Half-size Mini PCIe Card [AR9380] + +pci:v0000168Cd00000032* + ID_PRODUCT_FROM_DATABASE=AR9485 Wireless Network Adapter + +pci:v0000168Cd00000032sv0000103Csd00001838* + ID_PRODUCT_FROM_DATABASE=AR9485/HB125 802.11bgn 1×1 Wi-Fi Adapter + +pci:v0000168Cd00000033* + ID_PRODUCT_FROM_DATABASE=AR9580 Wireless Network Adapter + +pci:v0000168Cd00000034* + ID_PRODUCT_FROM_DATABASE=AR9462 Wireless Network Adapter + +pci:v0000168Cd00000036* + ID_PRODUCT_FROM_DATABASE=AR9565 Wireless Network Adapter + +pci:v0000168Cd00000207* + ID_PRODUCT_FROM_DATABASE=AR5210 Wireless Network Adapter [AR5000 802.11a] + +pci:v0000168Cd00001014* + ID_PRODUCT_FROM_DATABASE=AR5212 802.11abg NIC + +pci:v0000168Cd00001014sv00001014sd0000058A* + ID_PRODUCT_FROM_DATABASE=ThinkPad 11a/b/g Wireless LAN Mini Express Adapter (AR5BXB6) + +pci:v0000168Cd00009013* + ID_PRODUCT_FROM_DATABASE=AR5002X Wireless Network Adapter + +pci:v0000168Cd0000FF19* + ID_PRODUCT_FROM_DATABASE=AR5006X Wireless Network Adapter + +pci:v0000168Cd0000FF1C* + ID_PRODUCT_FROM_DATABASE=AR5008 Wireless Network Adapter + +pci:v0000168Cd0000FF1D* + ID_PRODUCT_FROM_DATABASE=AR5008 Wireless Network Adapter + +pci:v00001695* + ID_VENDOR_FROM_DATABASE=EPoX Computer Co., Ltd. + +pci:v0000169C* + ID_VENDOR_FROM_DATABASE=Netcell Corporation + +pci:v0000169Cd00000044* + ID_PRODUCT_FROM_DATABASE=Revolution Storage Processing Card + +pci:v0000169D* + ID_VENDOR_FROM_DATABASE=Club-3D VB (Wrong ID) + +pci:v000016A5* + ID_VENDOR_FROM_DATABASE=Tekram Technology Co.,Ltd. + +pci:v000016AB* + ID_VENDOR_FROM_DATABASE=Global Sun Technology Inc + +pci:v000016ABd00001100* + ID_PRODUCT_FROM_DATABASE=GL24110P + +pci:v000016ABd00001101* + ID_PRODUCT_FROM_DATABASE=PLX9052 PCMCIA-to-PCI Wireless LAN + +pci:v000016ABd00001102* + ID_PRODUCT_FROM_DATABASE=PCMCIA-to-PCI Wireless Network Bridge + +pci:v000016ABd00008501* + ID_PRODUCT_FROM_DATABASE=WL-8305 Wireless LAN PCI Adapter + +pci:v000016AE* + ID_VENDOR_FROM_DATABASE=SafeNet Inc + +pci:v000016AEd00000001* + ID_PRODUCT_FROM_DATABASE=SafeXcel 1140 + +pci:v000016AEd0000000A* + ID_PRODUCT_FROM_DATABASE=SafeXcel 1841 + +pci:v000016AEd00001141* + ID_PRODUCT_FROM_DATABASE=SafeXcel 1141 + +pci:v000016AEd00001841* + ID_PRODUCT_FROM_DATABASE=SafeXcel 1842 + +pci:v000016AF* + ID_VENDOR_FROM_DATABASE=SparkLAN Communications, Inc. + +pci:v000016B4* + ID_VENDOR_FROM_DATABASE=Aspex Semiconductor Ltd + +pci:v000016B8* + ID_VENDOR_FROM_DATABASE=Sonnet Technologies, Inc. + +pci:v000016BE* + ID_VENDOR_FROM_DATABASE=Creatix Polymedia GmbH + +pci:v000016C6* + ID_VENDOR_FROM_DATABASE=Micrel-Kendin + +pci:v000016C6d00008695* + ID_PRODUCT_FROM_DATABASE=Centaur KS8695 ARM processor + +pci:v000016C6d00008842* + ID_PRODUCT_FROM_DATABASE=KSZ8842-PMQL 2-Port Ethernet Switch + +pci:v000016C8* + ID_VENDOR_FROM_DATABASE=Octasic Inc. + +pci:v000016C9* + ID_VENDOR_FROM_DATABASE=EONIC B.V. The Netherlands + +pci:v000016CA* + ID_VENDOR_FROM_DATABASE=CENATEK Inc + +pci:v000016CAd00000001* + ID_PRODUCT_FROM_DATABASE=Rocket Drive DL + +pci:v000016CD* + ID_VENDOR_FROM_DATABASE=Advantech Co. Ltd + +pci:v000016CDd00000101* + ID_PRODUCT_FROM_DATABASE=DirectPCI SRAM for DPX-11x series + +pci:v000016CDd00000102* + ID_PRODUCT_FROM_DATABASE=DirectPCI SRAM for DPX-S/C/E-series + +pci:v000016CDd00000103* + ID_PRODUCT_FROM_DATABASE=DirectPCI ROM for DPX-11x series + +pci:v000016CDd00000104* + ID_PRODUCT_FROM_DATABASE=DirectPCI ROM for DPX-S/C/E-series + +pci:v000016CDd00000105* + ID_PRODUCT_FROM_DATABASE=DirectPCI I/O for DPX-114/DPX-115 + +pci:v000016CDd00000106* + ID_PRODUCT_FROM_DATABASE=DirectPCI I/O for DPX-116 + +pci:v000016CDd00000107* + ID_PRODUCT_FROM_DATABASE=DirectPCI I/O for DPX-116U + +pci:v000016CDd00000108* + ID_PRODUCT_FROM_DATABASE=DirectPCI I/O for DPX-117 + +pci:v000016CDd00000109* + ID_PRODUCT_FROM_DATABASE=DirectPCI I/O for DPX-112 + +pci:v000016CDd0000010A* + ID_PRODUCT_FROM_DATABASE=DirectPCI I/O for DPX-C/E-series + +pci:v000016CDd0000010B* + ID_PRODUCT_FROM_DATABASE=DirectPCI I/O for DPX-S series + +pci:v000016CE* + ID_VENDOR_FROM_DATABASE=Roland Corp. + +pci:v000016D5* + ID_VENDOR_FROM_DATABASE=Acromag, Inc. + +pci:v000016D5d00000504* + ID_PRODUCT_FROM_DATABASE=PMC-DX504 Reconfigurable FPGA with LVDS I/O + +pci:v000016D5d00000520* + ID_PRODUCT_FROM_DATABASE=PMC520 Serial Communication, 232 Octal + +pci:v000016D5d00000521* + ID_PRODUCT_FROM_DATABASE=PMC521 Serial Communication, 422/485 Octal + +pci:v000016D5d00001020* + ID_PRODUCT_FROM_DATABASE=PMC-AX1020 Reconfigurable FPGA with A/D & D/A + +pci:v000016D5d00001065* + ID_PRODUCT_FROM_DATABASE=PMC-AX1065 Reconfigurable FPGA with A/D & D/A + +pci:v000016D5d00002004* + ID_PRODUCT_FROM_DATABASE=PMC-DX2004 Reconfigurable FPGA with LVDS I/O + +pci:v000016D5d00002020* + ID_PRODUCT_FROM_DATABASE=PMC-AX2020 Reconfigurable FPGA with A/D & D/A + +pci:v000016D5d00002065* + ID_PRODUCT_FROM_DATABASE=PMC-AX2065 Reconfigurable FPGA with A/D & D/A + +pci:v000016D5d00003020* + ID_PRODUCT_FROM_DATABASE=PMC-AX3020 Reconfigurable FPGA with A/D & D/A + +pci:v000016D5d00003065* + ID_PRODUCT_FROM_DATABASE=PMC-AX3065 Reconfigurable FPGA with A/D & D/A + +pci:v000016D5d00004243* + ID_PRODUCT_FROM_DATABASE=PMC424, APC424, AcPC424 Digital I/O and Counter Timer Module + +pci:v000016D5d00004248* + ID_PRODUCT_FROM_DATABASE=PMC464, APC464, AcPC464 Digital I/O and Counter Timer Module + +pci:v000016D5d0000424B* + ID_PRODUCT_FROM_DATABASE=PMC-DX2002 Reconfigurable FPGA with Differential I/O + +pci:v000016D5d00004253* + ID_PRODUCT_FROM_DATABASE=PMC-DX503 Reconfigurable FPGA with TTL and Differential I/O + +pci:v000016D5d00004312* + ID_PRODUCT_FROM_DATABASE=PMC-CX1002 Reconfigurable Conduction-Cooled FPGA Virtex-II with Differential I/O + +pci:v000016D5d00004313* + ID_PRODUCT_FROM_DATABASE=PMC-CX1003 Reconfigurable Conduction-Cooled FPGA Virtex-II with CMOS and Differential I/O + +pci:v000016D5d00004322* + ID_PRODUCT_FROM_DATABASE=PMC-CX2002 Reconfigurable Conduction-Cooled FPGA Virtex-II with Differential I/O + +pci:v000016D5d00004323* + ID_PRODUCT_FROM_DATABASE=PMC-CX2003 Reconfigurable Conduction-Cooled FPGA Virtex-II with CMOS and Differential I/O + +pci:v000016D5d00004350* + ID_PRODUCT_FROM_DATABASE=PMC-DX501 Reconfigurable Digital I/O Module + +pci:v000016D5d00004353* + ID_PRODUCT_FROM_DATABASE=PMC-DX2003 Reconfigurable FPGA with TTL and Differential I/O + +pci:v000016D5d00004357* + ID_PRODUCT_FROM_DATABASE=PMC-DX502 Reconfigurable Differential I/O Module + +pci:v000016D5d00004457* + ID_PRODUCT_FROM_DATABASE=PMC730, APC730, AcPC730 Multifunction Module + +pci:v000016D5d0000464D* + ID_PRODUCT_FROM_DATABASE=PMC408 32-Channel Digital Input/Output Module + +pci:v000016D5d00004850* + ID_PRODUCT_FROM_DATABASE=PMC220-16 12-Bit Analog Output Module + +pci:v000016D5d00004A42* + ID_PRODUCT_FROM_DATABASE=PMC483, APC483, AcPC483 Counter Timer Module + +pci:v000016D5d00004A50* + ID_PRODUCT_FROM_DATABASE=PMC484, APC484, AcPC484 Counter Timer Module + +pci:v000016D5d00004A56* + ID_PRODUCT_FROM_DATABASE=PMC230 16-Bit Analog Output Module + +pci:v000016D5d00004B47* + ID_PRODUCT_FROM_DATABASE=PMC330, APC330, AcPC330 Analog Input Module, 16-bit A/D + +pci:v000016D5d00004C40* + ID_PRODUCT_FROM_DATABASE=PMC-LX40 Reconfigurable Virtex-4 FPGA with plug-in I/O + +pci:v000016D5d00004C60* + ID_PRODUCT_FROM_DATABASE=PMC-LX60 Reconfigurable Virtex-4 FPGA with plug-in I/O + +pci:v000016D5d00004D4D* + ID_PRODUCT_FROM_DATABASE=PMC341, APC341, AcPC341 Analog Input Module, Simultaneous Sample & Hold + +pci:v000016D5d00004D4E* + ID_PRODUCT_FROM_DATABASE=PMC482, APC482, AcPC482 Counter Timer Board + +pci:v000016D5d0000524D* + ID_PRODUCT_FROM_DATABASE=PMC-DX2001 Reconfigurable FPGA with TTL I/O + +pci:v000016D5d00005335* + ID_PRODUCT_FROM_DATABASE=PMC-SX35 Reconfigurable Virtex-4 FPGA with plug-in I/O + +pci:v000016D5d00005456* + ID_PRODUCT_FROM_DATABASE=PMC470 48-Channel Digital Input/Output Module + +pci:v000016D5d00005601* + ID_PRODUCT_FROM_DATABASE=PMC-VLX85 Reconfigurable Virtex-5 FPGA with plug-in I/O + +pci:v000016D5d00005602* + ID_PRODUCT_FROM_DATABASE=PMC-VLX110 Reconfigurable Virtex-5 FPGA with plug-in I/O + +pci:v000016D5d00005603* + ID_PRODUCT_FROM_DATABASE=PMC-VSX95 Reconfigurable Virtex-5 FPGA with plug-in I/O + +pci:v000016D5d00005604* + ID_PRODUCT_FROM_DATABASE=PMC-VLX155 Reconfigurable Virtex-5 FPGA with plug-in I/O + +pci:v000016D5d00005605* + ID_PRODUCT_FROM_DATABASE=PMC-VFX70 Reconfigurable Virtex-5 FPGA with plug-in I/O + +pci:v000016D5d00005606* + ID_PRODUCT_FROM_DATABASE=PMC-VLX155-1M Reconfigurable Virtex-5 FPGA with plug-in I/O + +pci:v000016D5d00005701* + ID_PRODUCT_FROM_DATABASE=PMC-SLX150: Reconfigurable Spartan-6 FPGA with plug-in I/O + +pci:v000016D5d00005702* + ID_PRODUCT_FROM_DATABASE=PMC-SLX150-1M: Reconfigurable Spartan-6 FPGA with plug-in I/O + +pci:v000016D5d00005801* + ID_PRODUCT_FROM_DATABASE=XMC-VLX85 Reconfigurable Virtex-5 FPGA with plug-in I/O + +pci:v000016D5d00005802* + ID_PRODUCT_FROM_DATABASE=XMC-VLX110 Reconfigurable Virtex-5 FPGA with plug-in I/O + +pci:v000016D5d00005803* + ID_PRODUCT_FROM_DATABASE=XMC-VSX95 Reconfigurable Virtex-5 FPGA with plug-in I/O + +pci:v000016D5d00005804* + ID_PRODUCT_FROM_DATABASE=XMC-VLX155 Reconfigurable Virtex-5 FPGA with plug-in I/O + +pci:v000016D5d00005807* + ID_PRODUCT_FROM_DATABASE=XMC-SLX150: Reconfigurable Spartan-6 FPGA with plug-in I/O + +pci:v000016D5d00005808* + ID_PRODUCT_FROM_DATABASE=XMC-SLX150-1M: Reconfigurable Spartan-6 FPGA with plug-in I/O + +pci:v000016D5d00005901* + ID_PRODUCT_FROM_DATABASE=APCe8650 PCI Express IndustryPack Carrier Card + +pci:v000016D5d00006301* + ID_PRODUCT_FROM_DATABASE=XMC Module with user-configurable Virtex-6 FPGA, 240k logic cells, SFP front I/O + +pci:v000016D5d00006302* + ID_PRODUCT_FROM_DATABASE=XMC Module with user-configurable Virtex-6 FPGA, 365k logic cells, SFP front I/O + +pci:v000016D5d00006303* + ID_PRODUCT_FROM_DATABASE=XMC Module with user-configurable Virtex-6 FPGA, 240k logic cells, no front I/O + +pci:v000016D5d00006304* + ID_PRODUCT_FROM_DATABASE=XMC Module with user-configurable Virtex-6 FPGA, 365k logic cells, no front I/O + +pci:v000016DA* + ID_VENDOR_FROM_DATABASE=Advantech Co., Ltd. + +pci:v000016DAd00000011* + ID_PRODUCT_FROM_DATABASE=INES GPIB-PCI + +pci:v000016DF* + ID_VENDOR_FROM_DATABASE=PIKA Technologies Inc. + +pci:v000016E2* + ID_VENDOR_FROM_DATABASE=Geotest-MTS + +pci:v000016E3* + ID_VENDOR_FROM_DATABASE=European Space Agency + +pci:v000016E3d00001E0F* + ID_PRODUCT_FROM_DATABASE=LEON2FT Processor + +pci:v000016E5* + ID_VENDOR_FROM_DATABASE=Intellon Corp. + +pci:v000016E5d00006000* + ID_PRODUCT_FROM_DATABASE=INT6000 Ethernet-to-Powerline Bridge [HomePlug AV] + +pci:v000016E5d00006300* + ID_PRODUCT_FROM_DATABASE=INT6300 Ethernet-to-Powerline Bridge [HomePlug AV] + +pci:v000016EC* + ID_VENDOR_FROM_DATABASE=U.S. Robotics + +pci:v000016ECd000000ED* + ID_PRODUCT_FROM_DATABASE=USR997900 + +pci:v000016ECd00000116* + ID_PRODUCT_FROM_DATABASE=USR997902 10/100/1000 Mbps PCI Network Card + +pci:v000016ECd00002F00* + ID_PRODUCT_FROM_DATABASE=USR5660A (USR265660A, USR5660A-BP) 56K PCI Faxmodem + +pci:v000016ECd00003685* + ID_PRODUCT_FROM_DATABASE=Wireless Access PCI Adapter Model 022415 + +pci:v000016ECd00004320* + ID_PRODUCT_FROM_DATABASE=USR997904 10/100/1000 64-bit NIC (Marvell Yukon) + +pci:v000016ECd0000AB06* + ID_PRODUCT_FROM_DATABASE=USR997901A 10/100 Cardbus NIC + +pci:v000016ED* + ID_VENDOR_FROM_DATABASE=Sycron N. V. + +pci:v000016EDd00001001* + ID_PRODUCT_FROM_DATABASE=UMIO communication card + +pci:v000016F3* + ID_VENDOR_FROM_DATABASE=Jetway Information Co., Ltd. + +pci:v000016F4* + ID_VENDOR_FROM_DATABASE=Vweb Corp + +pci:v000016F4d00008000* + ID_PRODUCT_FROM_DATABASE=VW2010 + +pci:v000016F6* + ID_VENDOR_FROM_DATABASE=VideoTele.com, Inc. + +pci:v00001702* + ID_VENDOR_FROM_DATABASE=Internet Machines Corporation (IMC) + +pci:v00001705* + ID_VENDOR_FROM_DATABASE=Digital First, Inc. + +pci:v0000170B* + ID_VENDOR_FROM_DATABASE=NetOctave + +pci:v0000170Bd00000100* + ID_PRODUCT_FROM_DATABASE=NSP2000-SSL crypto accelerator + +pci:v0000170C* + ID_VENDOR_FROM_DATABASE=YottaYotta Inc. + +pci:v00001719* + ID_VENDOR_FROM_DATABASE=EZChip Technologies + +pci:v00001725* + ID_VENDOR_FROM_DATABASE=Vitesse Semiconductor + +pci:v00001725d00007174* + ID_PRODUCT_FROM_DATABASE=VSC7174 PCI/PCI-X Serial ATA Host Bus Controller + +pci:v0000172A* + ID_VENDOR_FROM_DATABASE=Accelerated Encryption + +pci:v0000172Ad000013C8* + ID_PRODUCT_FROM_DATABASE=AEP SureWare Runner 1000V3 + +pci:v00001734* + ID_VENDOR_FROM_DATABASE=Fujitsu Technology Solutions + +pci:v00001734d00001078* + ID_PRODUCT_FROM_DATABASE=Amilo Pro v2010 + +pci:v00001734d00001085* + ID_PRODUCT_FROM_DATABASE=Celsius M450 + +pci:v00001734d00001098* + ID_PRODUCT_FROM_DATABASE=Amilo L 1310G + +pci:v00001735* + ID_VENDOR_FROM_DATABASE=Aten International Co. Ltd. + +pci:v00001737* + ID_VENDOR_FROM_DATABASE=Linksys + +pci:v00001737d00000029* + ID_PRODUCT_FROM_DATABASE=WPG54G ver. 4 PCI Card + +pci:v00001737d00001032* + ID_PRODUCT_FROM_DATABASE=Gigabit Network Adapter + +pci:v00001737d00001032sv00001737sd00000015* + ID_PRODUCT_FROM_DATABASE=EG1032 v2 Instant Gigabit Network Adapter + +pci:v00001737d00001032sv00001737sd00000024* + ID_PRODUCT_FROM_DATABASE=EG1032 v3 Instant Gigabit Network Adapter + +pci:v00001737d00001064* + ID_PRODUCT_FROM_DATABASE=Gigabit Network Adapter + +pci:v00001737d00001064sv00001737sd00000016* + ID_PRODUCT_FROM_DATABASE=EG1064 v2 Instant Gigabit Network Adapter + +pci:v00001737d0000AB08* + ID_PRODUCT_FROM_DATABASE=21x4x DEC-Tulip compatible 10/100 Ethernet + +pci:v00001737d0000AB09* + ID_PRODUCT_FROM_DATABASE=21x4x DEC-Tulip compatible 10/100 Ethernet + +pci:v0000173B* + ID_VENDOR_FROM_DATABASE=Altima (nee Broadcom) + +pci:v0000173Bd000003E8* + ID_PRODUCT_FROM_DATABASE=AC1000 Gigabit Ethernet + +pci:v0000173Bd000003E9* + ID_PRODUCT_FROM_DATABASE=AC1001 Gigabit Ethernet + +pci:v0000173Bd000003EA* + ID_PRODUCT_FROM_DATABASE=AC9100 Gigabit Ethernet + +pci:v0000173Bd000003EAsv0000173Bsd00000001* + ID_PRODUCT_FROM_DATABASE=AC1002 + +pci:v0000173Bd000003EB* + ID_PRODUCT_FROM_DATABASE=AC1003 Gigabit Ethernet + +pci:v00001743* + ID_VENDOR_FROM_DATABASE=Peppercon AG + +pci:v00001743d00008139* + ID_PRODUCT_FROM_DATABASE=ROL/F-100 Fast Ethernet Adapter with ROL + +pci:v00001745* + ID_VENDOR_FROM_DATABASE=ViXS Systems, Inc. + +pci:v00001745d00002020* + ID_PRODUCT_FROM_DATABASE=XCode II Series + +pci:v00001745d00002100* + ID_PRODUCT_FROM_DATABASE=XCode 2100 Series + +pci:v00001749* + ID_VENDOR_FROM_DATABASE=RLX Technologies + +pci:v0000174B* + ID_VENDOR_FROM_DATABASE=PC Partner Limited + +pci:v0000174D* + ID_VENDOR_FROM_DATABASE=WellX Telecom SA + +pci:v0000175C* + ID_VENDOR_FROM_DATABASE=AudioScience Inc + +pci:v0000175E* + ID_VENDOR_FROM_DATABASE=Sanera Systems, Inc. + +pci:v00001760* + ID_VENDOR_FROM_DATABASE=TEDIA spol. s r. o. + +pci:v00001771* + ID_VENDOR_FROM_DATABASE=InnoVISION Multimedia Ltd. + +pci:v00001775* + ID_VENDOR_FROM_DATABASE=GE Intelligent Platforms + +pci:v0000177D* + ID_VENDOR_FROM_DATABASE=Cavium Networks + +pci:v0000177Dd00000001* + ID_PRODUCT_FROM_DATABASE=Nitrox XL N1 + +pci:v0000177Dd00000003* + ID_PRODUCT_FROM_DATABASE=Nitrox XL N1 Lite + +pci:v0000177Dd00000004* + ID_PRODUCT_FROM_DATABASE=Octeon (and older) FIPS + +pci:v0000177Dd00000005* + ID_PRODUCT_FROM_DATABASE=Octeon CN38XX Network Processor Pass 3.x + +pci:v0000177Dd00000006* + ID_PRODUCT_FROM_DATABASE=RoHS + +pci:v0000177Dd00000010* + ID_PRODUCT_FROM_DATABASE=Nitrox XL NPX + +pci:v0000177Dd00000020* + ID_PRODUCT_FROM_DATABASE=Octeon CN31XX Network Processor + +pci:v0000177Dd00000030* + ID_PRODUCT_FROM_DATABASE=Octeon CN30XX Network Processor + +pci:v0000177Dd00000040* + ID_PRODUCT_FROM_DATABASE=Octeon CN58XX Network Processor + +pci:v0000177Dd00000050* + ID_PRODUCT_FROM_DATABASE=Octeon CN57XX Network Processor (CN54XX/CN55XX/CN56XX) + +pci:v0000177Dd00000070* + ID_PRODUCT_FROM_DATABASE=Octeon CN50XX Network Processor + +pci:v0000177Dd00000080* + ID_PRODUCT_FROM_DATABASE=Octeon CN52XX Network Processor + +pci:v0000177Dd00000090* + ID_PRODUCT_FROM_DATABASE=Octeon II CN63XX Network Processor + +pci:v0000177Dd00000091* + ID_PRODUCT_FROM_DATABASE=Octeon II CN68XX Network Processor + +pci:v0000177Dd00000092* + ID_PRODUCT_FROM_DATABASE=Octeon II CN65XX Network Processor + +pci:v0000177Dd00000093* + ID_PRODUCT_FROM_DATABASE=Octeon II CN61XX Network Processor + +pci:v00001787* + ID_VENDOR_FROM_DATABASE=Hightech Information System Ltd. + +pci:v00001789* + ID_VENDOR_FROM_DATABASE=Ennyah Technologies Corp. + +pci:v00001796* + ID_VENDOR_FROM_DATABASE=Research Centre Juelich + +pci:v00001796d00000001* + ID_PRODUCT_FROM_DATABASE=SIS1100 [Gigabit link] + +pci:v00001796d00000002* + ID_PRODUCT_FROM_DATABASE=HOTlink + +pci:v00001796d00000003* + ID_PRODUCT_FROM_DATABASE=Counter Timer + +pci:v00001796d00000004* + ID_PRODUCT_FROM_DATABASE=CAMAC Controller + +pci:v00001796d00000005* + ID_PRODUCT_FROM_DATABASE=PROFIBUS + +pci:v00001796d00000006* + ID_PRODUCT_FROM_DATABASE=AMCC HOTlink + +pci:v00001796d0000000D* + ID_PRODUCT_FROM_DATABASE=Synchronisation Slave + +pci:v00001796d0000000E* + ID_PRODUCT_FROM_DATABASE=SIS1100-eCMC + +pci:v00001796d0000000F* + ID_PRODUCT_FROM_DATABASE=TDC (GPX) + +pci:v00001796d00000010* + ID_PRODUCT_FROM_DATABASE=PCIe Counter Timer + +pci:v00001796d00000011* + ID_PRODUCT_FROM_DATABASE=SIS1100-e single link + +pci:v00001796d00000012* + ID_PRODUCT_FROM_DATABASE=SIS1100-e quad link + +pci:v00001797* + ID_VENDOR_FROM_DATABASE=Techwell Inc. + +pci:v00001797d00006801* + ID_PRODUCT_FROM_DATABASE=TW6802 multimedia video card + +pci:v00001797d00006802* + ID_PRODUCT_FROM_DATABASE=TW6802 multimedia other device + +pci:v00001797d00006810* + ID_PRODUCT_FROM_DATABASE=TW6816 multimedia video controller + +pci:v00001797d00006811* + ID_PRODUCT_FROM_DATABASE=TW6816 multimedia video controller + +pci:v00001797d00006812* + ID_PRODUCT_FROM_DATABASE=TW6816 multimedia video controller + +pci:v00001797d00006813* + ID_PRODUCT_FROM_DATABASE=TW6816 multimedia video controller + +pci:v00001799* + ID_VENDOR_FROM_DATABASE=Belkin + +pci:v00001799d00006001* + ID_PRODUCT_FROM_DATABASE=F5D6001 Wireless PCI Card [Realtek RTL8180] + +pci:v00001799d00006020* + ID_PRODUCT_FROM_DATABASE=F5D6020 v3000 Wireless PCMCIA Card [Realtek RTL8180] + +pci:v00001799d00006060* + ID_PRODUCT_FROM_DATABASE=F5D6060 Wireless PDA Card + +pci:v00001799d0000700F* + ID_PRODUCT_FROM_DATABASE=F5D7000 v7000 Wireless G Desktop Card [Realtek RTL8185] + +pci:v00001799d0000701F* + ID_PRODUCT_FROM_DATABASE=F5D7010 v7000 Wireless G Notebook Card [Realtek RTL8185] + +pci:v0000179A* + ID_VENDOR_FROM_DATABASE=id Quantique + +pci:v0000179Ad00000001* + ID_PRODUCT_FROM_DATABASE=Quantis PCI 16Mbps + +pci:v0000179C* + ID_VENDOR_FROM_DATABASE=Data Patterns + +pci:v0000179Cd00000557* + ID_PRODUCT_FROM_DATABASE=DP-PCI-557 [PCI 1553B] + +pci:v0000179Cd00000566* + ID_PRODUCT_FROM_DATABASE=DP-PCI-566 [Intelligent PCI 1553B] + +pci:v0000179Cd00001152* + ID_PRODUCT_FROM_DATABASE=DP-cPCI-1152 (8-channel Isolated ADC Module) + +pci:v0000179Cd00005031* + ID_PRODUCT_FROM_DATABASE=DP-CPCI-5031-Synchro Module + +pci:v0000179Cd00005112* + ID_PRODUCT_FROM_DATABASE=DP-cPCI-5112 [MM-Carrier] + +pci:v0000179Cd00005121* + ID_PRODUCT_FROM_DATABASE=DP-CPCI-5121-IP Carrier + +pci:v0000179Cd00005211* + ID_PRODUCT_FROM_DATABASE=DP-CPCI-5211-IP Carrier + +pci:v0000179Cd00005679* + ID_PRODUCT_FROM_DATABASE=AGE Display Module + +pci:v000017A0* + ID_VENDOR_FROM_DATABASE=Genesys Logic, Inc + +pci:v000017A0d00007163* + ID_PRODUCT_FROM_DATABASE=GL9701 PCIe to PCI Bridge + +pci:v000017A0d00008083* + ID_PRODUCT_FROM_DATABASE=GL880 USB 1.1 UHCI controller + +pci:v000017A0d00008084* + ID_PRODUCT_FROM_DATABASE=GL880 USB 2.0 EHCI controller + +pci:v000017AA* + ID_VENDOR_FROM_DATABASE=Lenovo + +pci:v000017AB* + ID_VENDOR_FROM_DATABASE=Phillips Components + +pci:v000017AF* + ID_VENDOR_FROM_DATABASE=Hightech Information System Ltd. + +pci:v000017B3* + ID_VENDOR_FROM_DATABASE=Hawking Technologies + +pci:v000017B3d0000AB08* + ID_PRODUCT_FROM_DATABASE=PN672TX 10/100 Ethernet + +pci:v000017B4* + ID_VENDOR_FROM_DATABASE=Indra Networks, Inc. + +pci:v000017B4d00000011* + ID_PRODUCT_FROM_DATABASE=WebEnhance 100 GZIP Compression Card + +pci:v000017B4d00000012* + ID_PRODUCT_FROM_DATABASE=WebEnhance 200 GZIP Compression Card + +pci:v000017B4d00000015* + ID_PRODUCT_FROM_DATABASE=WebEnhance 300 GZIP Compression Card + +pci:v000017B4d00000016* + ID_PRODUCT_FROM_DATABASE=StorCompress 300 GZIP Compression Card + +pci:v000017B4d00000017* + ID_PRODUCT_FROM_DATABASE=StorSecure 300 GZIP Compression and AES Encryption Card + +pci:v000017C0* + ID_VENDOR_FROM_DATABASE=Wistron Corp. + +pci:v000017C2* + ID_VENDOR_FROM_DATABASE=Newisys, Inc. + +pci:v000017CB* + ID_VENDOR_FROM_DATABASE=Airgo Networks Inc + +pci:v000017CBd00000001* + ID_PRODUCT_FROM_DATABASE=AGN100 802.11 a/b/g True MIMO Wireless Card + +pci:v000017CBd00000001sv00001385sd00005C00* + ID_PRODUCT_FROM_DATABASE=WGM511 Pre-N 802.11g Wireless CardBus Adapter + +pci:v000017CBd00000001sv00001737sd00000045* + ID_PRODUCT_FROM_DATABASE=WMP54GX v1 802.11g Wireless-G PCI Adapter with SRX + +pci:v000017CBd00000002* + ID_PRODUCT_FROM_DATABASE=AGN300 802.11 a/b/g True MIMO Wireless Card + +pci:v000017CBd00000002sv00001385sd00006D00* + ID_PRODUCT_FROM_DATABASE=WPNT511 RangeMax 240 Mbps Wireless CardBus Adapter + +pci:v000017CBd00000002sv00001737sd00000054* + ID_PRODUCT_FROM_DATABASE=WPC54GX4 v1 802.11g Wireless-G Notebook Adapter with SRX400 + +pci:v000017CC* + ID_VENDOR_FROM_DATABASE=NetChip Technology, Inc + +pci:v000017CCd00002280* + ID_PRODUCT_FROM_DATABASE=USB 2.0 + +pci:v000017CF* + ID_VENDOR_FROM_DATABASE=Z-Com, Inc. + +pci:v000017D3* + ID_VENDOR_FROM_DATABASE=Areca Technology Corp. + +pci:v000017D3d00001110* + ID_PRODUCT_FROM_DATABASE=ARC-1110 4-Port PCI-X to SATA RAID Controller + +pci:v000017D3d00001120* + ID_PRODUCT_FROM_DATABASE=ARC-1120 8-Port PCI-X to SATA RAID Controller + +pci:v000017D3d00001130* + ID_PRODUCT_FROM_DATABASE=ARC-1130 12-Port PCI-X to SATA RAID Controller + +pci:v000017D3d00001160* + ID_PRODUCT_FROM_DATABASE=ARC-1160 16-Port PCI-X to SATA RAID Controller + +pci:v000017D3d00001170* + ID_PRODUCT_FROM_DATABASE=ARC-1170 24-Port PCI-X to SATA RAID Controller + +pci:v000017D3d00001201* + ID_PRODUCT_FROM_DATABASE=ARC-1200 2-Port PCI-Express to SATA II RAID Controller + +pci:v000017D3d00001210* + ID_PRODUCT_FROM_DATABASE=ARC-1210 4-Port PCI-Express to SATA RAID Controller + +pci:v000017D3d00001220* + ID_PRODUCT_FROM_DATABASE=ARC-1220 8-Port PCI-Express to SATA RAID Controller + +pci:v000017D3d00001222* + ID_PRODUCT_FROM_DATABASE=ARC-1222 8-Port PCI-Express to SAS/SATA II RAID Controller + +pci:v000017D3d00001230* + ID_PRODUCT_FROM_DATABASE=ARC-1230 12-Port PCI-Express to SATA RAID Controller + +pci:v000017D3d00001260* + ID_PRODUCT_FROM_DATABASE=ARC-1260 16-Port PCI-Express to SATA RAID Controller + +pci:v000017D3d00001280* + ID_PRODUCT_FROM_DATABASE=ARC-1280/1280ML 24-Port PCI-Express to SATA II RAID Controller + +pci:v000017D3d00001280sv000017D3sd00001221* + ID_PRODUCT_FROM_DATABASE=ARC-1221 8-Port PCI-Express to SATA RAID Controller + +pci:v000017D3d00001300* + ID_PRODUCT_FROM_DATABASE=ARC-1300ix-16 16-Port PCI-Express to SAS Non-RAID Host Adapter + +pci:v000017D3d00001680* + ID_PRODUCT_FROM_DATABASE=ARC-1680 8 port PCIe/PCI-X to SAS/SATA II RAID Controller + +pci:v000017D3d00001680sv000017D3sd00001212* + ID_PRODUCT_FROM_DATABASE=ARC-1212 4-Port PCIe to SAS/SATA II RAID Controller + +pci:v000017D3d00001880* + ID_PRODUCT_FROM_DATABASE=ARC-1880 8/12 port PCIe/PCI-X to SAS/SATA II RAID Controller + +pci:v000017D5* + ID_VENDOR_FROM_DATABASE=Exar Corp. + +pci:v000017D5d00005731* + ID_PRODUCT_FROM_DATABASE=Xframe 10-Gigabit Ethernet PCI-X + +pci:v000017D5d00005732* + ID_PRODUCT_FROM_DATABASE=Xframe II 10-Gigabit Ethernet PCI-X 2.0 + +pci:v000017D5d00005831* + ID_PRODUCT_FROM_DATABASE=Xframe 10-Gigabit Ethernet PCI-X + +pci:v000017D5d00005831sv0000103Csd000012D5* + ID_PRODUCT_FROM_DATABASE=PCI-X 133MHz 10GbE SR Fiber + +pci:v000017D5d00005831sv000010A9sd00008020* + ID_PRODUCT_FROM_DATABASE=Single Port 10-Gigabit Ethernet (PCI-X, Fiber) + +pci:v000017D5d00005831sv000010A9sd00008024* + ID_PRODUCT_FROM_DATABASE=Single Port 10-Gigabit Ethernet (PCI-X, Fiber) + +pci:v000017D5d00005832* + ID_PRODUCT_FROM_DATABASE=Xframe II 10-Gigabit Ethernet PCI-X 2.0 + +pci:v000017D5d00005832sv0000103Csd00001337* + ID_PRODUCT_FROM_DATABASE=PCI-X 266MHz 10GigE SR [AD385A] + +pci:v000017D5d00005832sv000010A9sd00008021* + ID_PRODUCT_FROM_DATABASE=Single Port 10-Gigabit Ethernet II (PCI-X, Fiber) + +pci:v000017D5d00005832sv000017D5sd00006020* + ID_PRODUCT_FROM_DATABASE=Xframe II SR + +pci:v000017D5d00005832sv000017D5sd00006021* + ID_PRODUCT_FROM_DATABASE=Xframe II SR, Low Profile + +pci:v000017D5d00005832sv000017D5sd00006022* + ID_PRODUCT_FROM_DATABASE=Xframe E SR + +pci:v000017D5d00005832sv000017D5sd00006420* + ID_PRODUCT_FROM_DATABASE=Xframe II LR + +pci:v000017D5d00005832sv000017D5sd00006421* + ID_PRODUCT_FROM_DATABASE=Xframe II LR, Low Profile + +pci:v000017D5d00005832sv000017D5sd00006422* + ID_PRODUCT_FROM_DATABASE=Xframe E LR + +pci:v000017D5d00005832sv000017D5sd00006C20* + ID_PRODUCT_FROM_DATABASE=Xframe II CX4 + +pci:v000017D5d00005832sv000017D5sd00006C21* + ID_PRODUCT_FROM_DATABASE=Xframe II CX4, Low Profile + +pci:v000017D5d00005832sv000017D5sd00006C22* + ID_PRODUCT_FROM_DATABASE=Xframe E CX4 + +pci:v000017D5d00005833* + ID_PRODUCT_FROM_DATABASE=X3100 Series 10 Gigabit Ethernet PCIe + +pci:v000017D5d00005833sv000017D5sd00006030* + ID_PRODUCT_FROM_DATABASE=X3110 Single Port SR + +pci:v000017D5d00005833sv000017D5sd00006031* + ID_PRODUCT_FROM_DATABASE=X3120 Dual Port SR + +pci:v000017D5d00005833sv000017D5sd00006430* + ID_PRODUCT_FROM_DATABASE=X3110 Single Port LR + +pci:v000017D5d00005833sv000017D5sd00006431* + ID_PRODUCT_FROM_DATABASE=X3120 Dual Port LR + +pci:v000017D5d00005833sv000017D5sd00007030* + ID_PRODUCT_FROM_DATABASE=X3110 Single Port LRM + +pci:v000017D5d00005833sv000017D5sd00007031* + ID_PRODUCT_FROM_DATABASE=X3120 Dual Port LRM + +pci:v000017D5d00005833sv000017D5sd00007430* + ID_PRODUCT_FROM_DATABASE=X3110 Single Port 10GBase-T + +pci:v000017D5d00005833sv000017D5sd00007431* + ID_PRODUCT_FROM_DATABASE=X3120 Dual Port 10GBase-T + +pci:v000017D5d00005833sv000017D5sd00007830* + ID_PRODUCT_FROM_DATABASE=X3110 Single Port 10GBase-CR + +pci:v000017D5d00005833sv000017D5sd00007831* + ID_PRODUCT_FROM_DATABASE=X3120 Dual Port 10GBase-CR + +pci:v000017DB* + ID_VENDOR_FROM_DATABASE=Cray Inc + +pci:v000017DBd00000101* + ID_PRODUCT_FROM_DATABASE=XT Series [Seastar] 3D Toroidal Router + +pci:v000017DE* + ID_VENDOR_FROM_DATABASE=KWorld Computer Co. Ltd. + +pci:v000017E4* + ID_VENDOR_FROM_DATABASE=Sectra AB + +pci:v000017E4d00000001* + ID_PRODUCT_FROM_DATABASE=KK671 Cardbus encryption board + +pci:v000017E4d00000002* + ID_PRODUCT_FROM_DATABASE=KK672 Cardbus encryption board + +pci:v000017E6* + ID_VENDOR_FROM_DATABASE=Entropic Communications Inc. + +pci:v000017E6d00000010* + ID_PRODUCT_FROM_DATABASE=EN2010 [c.Link] MoCA Network Controller (Coax, PCI interface) + +pci:v000017E6d00000011* + ID_PRODUCT_FROM_DATABASE=EN2010 [c.Link] MoCA Network Controller (Coax, MPEG interface) + +pci:v000017E6d00000021* + ID_PRODUCT_FROM_DATABASE=EN2210 [c.Link] MoCA Network Controller (Coax) + +pci:v000017E6d00000025* + ID_PRODUCT_FROM_DATABASE=EN2510 [c.Link] MoCA Network Controller (Coax, PCIe interface) + +pci:v000017E6d00000027* + ID_PRODUCT_FROM_DATABASE=EN2710 [c.Link] MoCA 2.0 Network Controller (Coax, PCIe interface) + +pci:v000017EE* + ID_VENDOR_FROM_DATABASE=Connect Components Ltd + +pci:v000017F2* + ID_VENDOR_FROM_DATABASE=Albatron Corp. + +pci:v000017F3* + ID_VENDOR_FROM_DATABASE=RDC Semiconductor, Inc. + +pci:v000017F3d00001010* + ID_PRODUCT_FROM_DATABASE=R1010 IDE Controller + +pci:v000017F3d00006020* + ID_PRODUCT_FROM_DATABASE=R6020 North Bridge + +pci:v000017F3d00006021* + ID_PRODUCT_FROM_DATABASE=R6021 Host Bridge + +pci:v000017F3d00006030* + ID_PRODUCT_FROM_DATABASE=R6030 ISA Bridge + +pci:v000017F3d00006031* + ID_PRODUCT_FROM_DATABASE=R6031 ISA Bridge + +pci:v000017F3d00006040* + ID_PRODUCT_FROM_DATABASE=R6040 MAC Controller + +pci:v000017F3d00006060* + ID_PRODUCT_FROM_DATABASE=R6060 USB 1.1 Controller + +pci:v000017F3d00006061* + ID_PRODUCT_FROM_DATABASE=R6061 USB 2.0 Controller + +pci:v000017F7* + ID_VENDOR_FROM_DATABASE=Topdek Semiconductor Inc. + +pci:v000017F9* + ID_VENDOR_FROM_DATABASE=Gemtek Technology Co., Ltd + +pci:v000017FC* + ID_VENDOR_FROM_DATABASE=IOGEAR, Inc. + +pci:v000017FE* + ID_VENDOR_FROM_DATABASE=InProComm Inc. + +pci:v000017FEd00002120* + ID_PRODUCT_FROM_DATABASE=IPN 2120 802.11b + +pci:v000017FEd00002120sv00001737sd00000020* + ID_PRODUCT_FROM_DATABASE=WMP11 v4 802.11b Wireless-B PCI Adapter + +pci:v000017FEd00002220* + ID_PRODUCT_FROM_DATABASE=IPN 2220 802.11g + +pci:v000017FEd00002220sv00001468sd00000305* + ID_PRODUCT_FROM_DATABASE=T60N871 802.11g Mini PCI Wireless Adapter + +pci:v000017FEd00002220sv00001737sd00000029* + ID_PRODUCT_FROM_DATABASE=WPC54G v4 802.11g Wireless-G Notebook Adapter + +pci:v000017FF* + ID_VENDOR_FROM_DATABASE=Benq Corporation + +pci:v00001803* + ID_VENDOR_FROM_DATABASE=ProdaSafe GmbH + +pci:v00001805* + ID_VENDOR_FROM_DATABASE=Euresys S.A. + +pci:v00001809* + ID_VENDOR_FROM_DATABASE=Lumanate, Inc. + +pci:v00001813* + ID_VENDOR_FROM_DATABASE=Ambient Technologies Inc + +pci:v00001813d00004000* + ID_PRODUCT_FROM_DATABASE=HaM controllerless modem + +pci:v00001813d00004000sv000016BEsd00000001* + ID_PRODUCT_FROM_DATABASE=V9x HAM Data Fax Modem + +pci:v00001813d00004100* + ID_PRODUCT_FROM_DATABASE=HaM plus Data Fax Modem + +pci:v00001813d00004100sv000016BEsd00000002* + ID_PRODUCT_FROM_DATABASE=V9x HAM 1394 + +pci:v00001814* + ID_VENDOR_FROM_DATABASE=Ralink corp. + +pci:v00001814d00000101* + ID_PRODUCT_FROM_DATABASE=Wireless PCI Adapter RT2400 / RT2460 + +pci:v00001814d00000101sv00001043sd00000127* + ID_PRODUCT_FROM_DATABASE=WiFi-b add-on Card + +pci:v00001814d00000101sv00001371sd00000010* + ID_PRODUCT_FROM_DATABASE=Minitar MNW2BPCI Wireless PCI Card + +pci:v00001814d00000101sv00001462sd00006828* + ID_PRODUCT_FROM_DATABASE=PC11B2 (MS-6828) Wireless 11b PCI Card + +pci:v00001814d00000200* + ID_PRODUCT_FROM_DATABASE=RT2500 802.11g PCI [PC54G2] + +pci:v00001814d00000201* + ID_PRODUCT_FROM_DATABASE=RT2500 Wireless 802.11bg + +pci:v00001814d00000201sv00001043sd0000130F* + ID_PRODUCT_FROM_DATABASE=WL-130g + +pci:v00001814d00000201sv00001186sd00003C00* + ID_PRODUCT_FROM_DATABASE=DWL-G650X Wireless 11g CardBus Adapter + +pci:v00001814d00000201sv00001371sd0000001E* + ID_PRODUCT_FROM_DATABASE=CWC-854 Wireless-G CardBus Adapter + +pci:v00001814d00000201sv00001371sd0000001F* + ID_PRODUCT_FROM_DATABASE=CWM-854 Wireless-G Mini PCI Adapter + +pci:v00001814d00000201sv00001371sd00000020* + ID_PRODUCT_FROM_DATABASE=CWP-854 Wireless-G PCI Adapter + +pci:v00001814d00000201sv00001458sd0000E381* + ID_PRODUCT_FROM_DATABASE=GN-WMKG 802.11b/g Wireless CardBus Adapter + +pci:v00001814d00000201sv00001458sd0000E931* + ID_PRODUCT_FROM_DATABASE=GN-WIKG 802.11b/g mini-PCI Adapter + +pci:v00001814d00000201sv00001462sd00006833* + ID_PRODUCT_FROM_DATABASE=Unknown 802.11g mini-PCI Adapter + +pci:v00001814d00000201sv00001462sd00006835* + ID_PRODUCT_FROM_DATABASE=Wireless 11G CardBus CB54G2 + +pci:v00001814d00000201sv00001737sd00000032* + ID_PRODUCT_FROM_DATABASE=WMP54G v4.0 PCI Adapter + +pci:v00001814d00000201sv00001799sd0000700A* + ID_PRODUCT_FROM_DATABASE=F5D7000 v2000/v3000 Wireless G Desktop Card + +pci:v00001814d00000201sv00001799sd0000701A* + ID_PRODUCT_FROM_DATABASE=F5D7010 v2000/v3000 Wireless G Notebook Card + +pci:v00001814d00000201sv00001814sd00002560* + ID_PRODUCT_FROM_DATABASE=RT2500 Wireless 802.11bg + +pci:v00001814d00000201sv0000182Dsd00009073* + ID_PRODUCT_FROM_DATABASE=WL-115 Wireless Network PCI Adapter + +pci:v00001814d00000201sv0000185Fsd000022A0* + ID_PRODUCT_FROM_DATABASE=CN-WF513 Wireless Cardbus Adapter + +pci:v00001814d00000201sv000018EBsd00005312* + ID_PRODUCT_FROM_DATABASE=WL531P IEEE 802.11g PCI Card-EU + +pci:v00001814d00000201sv00001948sd00003C00* + ID_PRODUCT_FROM_DATABASE=C54RC v1 Wireless 11g CardBus Adapter + +pci:v00001814d00000201sv00001948sd00003C01* + ID_PRODUCT_FROM_DATABASE=C54Ri v1 Wireless 11g PCI Adapter + +pci:v00001814d00000300* + ID_PRODUCT_FROM_DATABASE=Wireless Adapter Canyon CN-WF511 + +pci:v00001814d00000301* + ID_PRODUCT_FROM_DATABASE=RT2561/RT61 802.11g PCI + +pci:v00001814d00000301sv00001186sd00003C08* + ID_PRODUCT_FROM_DATABASE=AirPlus G DWL-G630 Wireless Cardbus Adapter (rev.E1) + +pci:v00001814d00000301sv00001186sd00003C09* + ID_PRODUCT_FROM_DATABASE=DWL-G510 Rev C + +pci:v00001814d00000301sv000013D1sd0000ABE3* + ID_PRODUCT_FROM_DATABASE=miniPCI Pluscom 802.11 a/b/g + +pci:v00001814d00000301sv00001458sd0000E933* + ID_PRODUCT_FROM_DATABASE=GN-WI01GS + +pci:v00001814d00000301sv00001458sd0000E934* + ID_PRODUCT_FROM_DATABASE=GN-WP01GS + +pci:v00001814d00000301sv00001737sd00000055* + ID_PRODUCT_FROM_DATABASE=WMP54G v4.1 + +pci:v00001814d00000301sv00001799sd0000700E* + ID_PRODUCT_FROM_DATABASE=F5D7000 v6000 Wireless G Desktop Card + +pci:v00001814d00000301sv00001799sd0000701E* + ID_PRODUCT_FROM_DATABASE=F5D7010 v6000 Wireless G Notebook Card + +pci:v00001814d00000301sv000017F9sd00000012* + ID_PRODUCT_FROM_DATABASE=AWLC3026T 802.11g Wireless CardBus Adapter + +pci:v00001814d00000301sv00001814sd00002561* + ID_PRODUCT_FROM_DATABASE=EW-7108PCg/EW-7128g + +pci:v00001814d00000302* + ID_PRODUCT_FROM_DATABASE=RT2561/RT61 rev B 802.11g + +pci:v00001814d00000302sv00001186sd00003A71* + ID_PRODUCT_FROM_DATABASE=DWA-510 Wireless G Desktop Adapter + +pci:v00001814d00000302sv00001186sd00003C08* + ID_PRODUCT_FROM_DATABASE=AirPlus G DWL-G630 Wireless Cardbus Adapter (rev.E2) + +pci:v00001814d00000302sv00001186sd00003C09* + ID_PRODUCT_FROM_DATABASE=AirPlus G DWL-G510 Wireless Network Adapter (Rev.C) + +pci:v00001814d00000302sv00001462sd0000B834* + ID_PRODUCT_FROM_DATABASE=PC54G3 Wireless 11g PCI Card + +pci:v00001814d00000302sv00001948sd00003C23* + ID_PRODUCT_FROM_DATABASE=C54RC v2 Wireless 11g CardBus Adapter + +pci:v00001814d00000302sv00001948sd00003C24* + ID_PRODUCT_FROM_DATABASE=C54Ri v2 Wireless 11g PCI Adapter + +pci:v00001814d00000401* + ID_PRODUCT_FROM_DATABASE=RT2600 802.11 MIMO + +pci:v00001814d00000401sv00001737sd00000052* + ID_PRODUCT_FROM_DATABASE=WPC54GR v1 802.11g Wireless-G Notebook Adapter with RangeBooster + +pci:v00001814d00000401sv000017F9sd00000011* + ID_PRODUCT_FROM_DATABASE=WPCR-137G 802.11bg Wireless CardBus Adapter + +pci:v00001814d00000401sv000017F9sd00000016* + ID_PRODUCT_FROM_DATABASE=WPIR-119GH 802.11bg Wireless Desktop Adapter + +pci:v00001814d00000601* + ID_PRODUCT_FROM_DATABASE=RT2800 802.11n PCI + +pci:v00001814d00000601sv00001799sd0000801C* + ID_PRODUCT_FROM_DATABASE=F5D8011 v3 802.11n N1 Wireless Notebook Card + +pci:v00001814d00000601sv0000187Esd00003412* + ID_PRODUCT_FROM_DATABASE=NWD-310N 802.11n Wireless PCI Adapter + +pci:v00001814d00000681* + ID_PRODUCT_FROM_DATABASE=RT2890 Wireless 802.11n PCIe + +pci:v00001814d00000681sv00001458sd0000E939* + ID_PRODUCT_FROM_DATABASE=GN-WS30N-RH 802.11bgn Mini PCIe Card + +pci:v00001814d00000701* + ID_PRODUCT_FROM_DATABASE=RT2760 Wireless 802.11n 1T/2R + +pci:v00001814d00000701sv00001737sd00000074* + ID_PRODUCT_FROM_DATABASE=WMP110 v2 802.11n RangePlus Wireless PCI Adapter + +pci:v00001814d00000781* + ID_PRODUCT_FROM_DATABASE=RT2790 Wireless 802.11n 1T/2R PCIe + +pci:v00001814d00003060* + ID_PRODUCT_FROM_DATABASE=RT3060 Wireless 802.11n 1T/1R + +pci:v00001814d00003060sv00001186sd00003C04* + ID_PRODUCT_FROM_DATABASE=DWA-525 Wireless N 150 Desktop Adapter (rev.A1) + +pci:v00001814d00003062* + ID_PRODUCT_FROM_DATABASE=RT3062 Wireless 802.11n 2T/2R + +pci:v00001814d00003090* + ID_PRODUCT_FROM_DATABASE=RT3090 Wireless 802.11n 1T/1R PCIe + +pci:v00001814d00003090sv000013BDsd00001057* + ID_PRODUCT_FROM_DATABASE=GN-WS32L-RH Half-size Mini PCIe Card + +pci:v00001814d00003091* + ID_PRODUCT_FROM_DATABASE=RT3091 Wireless 802.11n 1T/2R PCIe + +pci:v00001814d00003092* + ID_PRODUCT_FROM_DATABASE=RT3092 Wireless 802.11n 2T/2R PCIe + +pci:v00001814d00003290* + ID_PRODUCT_FROM_DATABASE=RT3290 Wireless 802.11n 1T/1R PCIe + +pci:v00001814d00003298* + ID_PRODUCT_FROM_DATABASE=RT3290 Bluetooth + +pci:v00001814d00003592* + ID_PRODUCT_FROM_DATABASE=RT3592 Wireless 802.11abgn 2T/2R PCIe + +pci:v00001814d00005360* + ID_PRODUCT_FROM_DATABASE=RT5360 Wireless 802.11n 1T/1R + +pci:v00001814d00005360sv00001186sd00003C05* + ID_PRODUCT_FROM_DATABASE=DWA-525 Wireless N 150 Desktop Adapter (rev.A2) + +pci:v00001814d00005360sv000020F4sd0000703A* + ID_PRODUCT_FROM_DATABASE=TEW-703PI N150 Wireless PCI Adapter + +pci:v00001814d00005390* + ID_PRODUCT_FROM_DATABASE=RT5390 Wireless 802.11n 1T/1R PCIe + +pci:v00001814d00005390sv0000103Csd00001636* + ID_PRODUCT_FROM_DATABASE=U98Z077.00 Half-size Mini PCIe Card + +pci:v00001814d0000539F* + ID_PRODUCT_FROM_DATABASE=RT5390 [802.11 b/g/n 1T1R G-band PCI Express Single Chip] + +pci:v00001814d0000539Fsv0000103Csd00001637* + ID_PRODUCT_FROM_DATABASE=Pavilion DM1Z-3000 PCIe wireless card + +pci:v00001814d0000E932* + ID_PRODUCT_FROM_DATABASE=RT2560F 802.11 b/g PCI + +pci:v00001815* + ID_VENDOR_FROM_DATABASE=Devolo AG + +pci:v00001820* + ID_VENDOR_FROM_DATABASE=InfiniCon Systems Inc. + +pci:v00001822* + ID_VENDOR_FROM_DATABASE=Twinhan Technology Co. Ltd + +pci:v00001822d00004E35* + ID_PRODUCT_FROM_DATABASE=Mantis DTV PCI Bridge Controller [Ver 1.0] + +pci:v0000182D* + ID_VENDOR_FROM_DATABASE=SiteCom Europe BV + +pci:v0000182Dd00003069* + ID_PRODUCT_FROM_DATABASE=ISDN PCI DC-105V2 + +pci:v0000182Dd00009790* + ID_PRODUCT_FROM_DATABASE=WL-121 Wireless Network Adapter 100g+ [Ver.3] + +pci:v0000182E* + ID_VENDOR_FROM_DATABASE=Raza Microelectronics, Inc. + +pci:v0000182Ed00000008* + ID_PRODUCT_FROM_DATABASE=XLR516 Processor + +pci:v0000182F* + ID_VENDOR_FROM_DATABASE=Broadcom + +pci:v0000182Fd0000000B* + ID_PRODUCT_FROM_DATABASE=BCM5785 [HT1000] SATA (RAID Mode) + +pci:v00001830* + ID_VENDOR_FROM_DATABASE=Credence Systems Corporation + +pci:v0000183B* + ID_VENDOR_FROM_DATABASE=MikroM GmbH + +pci:v0000183Bd000008A7* + ID_PRODUCT_FROM_DATABASE=MVC100 DVI + +pci:v0000183Bd000008A8* + ID_PRODUCT_FROM_DATABASE=MVC101 SDI + +pci:v0000183Bd000008A9* + ID_PRODUCT_FROM_DATABASE=MVC102 DVI+Audio + +pci:v0000183Bd000008B0* + ID_PRODUCT_FROM_DATABASE=MVC200-DC + +pci:v00001846* + ID_VENDOR_FROM_DATABASE=Alcatel-Lucent + +pci:v00001849* + ID_VENDOR_FROM_DATABASE=ASRock Incorporation + +pci:v0000184A* + ID_VENDOR_FROM_DATABASE=Thales Computers + +pci:v0000184Ad00001100* + ID_PRODUCT_FROM_DATABASE=MAX II cPLD + +pci:v00001851* + ID_VENDOR_FROM_DATABASE=Microtune, Inc. + +pci:v00001852* + ID_VENDOR_FROM_DATABASE=Anritsu Corp. + +pci:v00001853* + ID_VENDOR_FROM_DATABASE=SMSC Automotive Infotainment System Group + +pci:v00001854* + ID_VENDOR_FROM_DATABASE=LG Electronics, Inc. + +pci:v0000185B* + ID_VENDOR_FROM_DATABASE=Compro Technology, Inc. + +pci:v0000185Bd00001489* + ID_PRODUCT_FROM_DATABASE=VideoMate Vista T100 + +pci:v0000185F* + ID_VENDOR_FROM_DATABASE=Wistron NeWeb Corp. + +pci:v00001864* + ID_VENDOR_FROM_DATABASE=SilverBack + +pci:v00001864d00002110* + ID_PRODUCT_FROM_DATABASE=ISNAP 2110 + +pci:v00001867* + ID_VENDOR_FROM_DATABASE=Topspin Communications + +pci:v00001867d00005A44* + ID_PRODUCT_FROM_DATABASE=MT23108 InfiniHost HCA + +pci:v00001867d00005A45* + ID_PRODUCT_FROM_DATABASE=MT23108 InfiniHost HCA flash recovery + +pci:v00001867d00005A46* + ID_PRODUCT_FROM_DATABASE=MT23108 InfiniHost HCA bridge + +pci:v00001867d00006278* + ID_PRODUCT_FROM_DATABASE=MT25208 InfiniHost III Ex (Tavor compatibility mode) + +pci:v00001867d00006282* + ID_PRODUCT_FROM_DATABASE=MT25208 InfiniHost III Ex + +pci:v0000186C* + ID_VENDOR_FROM_DATABASE=Humusoft, s.r.o. + +pci:v0000186Cd00000612* + ID_PRODUCT_FROM_DATABASE=AD612 Data Acquisition Device + +pci:v0000186Cd00000614* + ID_PRODUCT_FROM_DATABASE=MF614 Multifunction I/O Card + +pci:v0000186Cd00000622* + ID_PRODUCT_FROM_DATABASE=AD622 Data Acquisition Device + +pci:v0000186Cd00000624* + ID_PRODUCT_FROM_DATABASE=MF624 Multifunction I/O Card + +pci:v0000186Cd00000625* + ID_PRODUCT_FROM_DATABASE=MF625 3-phase Motor Driver + +pci:v0000186F* + ID_VENDOR_FROM_DATABASE=WiNRADiO Communications + +pci:v00001876* + ID_VENDOR_FROM_DATABASE=L-3 Communications + +pci:v00001876d0000A101* + ID_PRODUCT_FROM_DATABASE=VigraWATCH PCI + +pci:v00001876d0000A102* + ID_PRODUCT_FROM_DATABASE=VigraWATCH PMC + +pci:v00001876d0000A103* + ID_PRODUCT_FROM_DATABASE=Vigra I/O + +pci:v0000187E* + ID_VENDOR_FROM_DATABASE=ZyXEL Communication Corporation + +pci:v0000187Ed00003403* + ID_PRODUCT_FROM_DATABASE=ZyAir G-110 802.11g + +pci:v0000187Ed0000340E* + ID_PRODUCT_FROM_DATABASE=M-302 802.11g XtremeMIMO + +pci:v00001885* + ID_VENDOR_FROM_DATABASE=Avvida Systems Inc. + +pci:v00001888* + ID_VENDOR_FROM_DATABASE=Varisys Ltd + +pci:v00001888d00000301* + ID_PRODUCT_FROM_DATABASE=VMFX1 FPGA PMC module + +pci:v00001888d00000601* + ID_PRODUCT_FROM_DATABASE=VSM2 dual PMC carrier + +pci:v00001888d00000710* + ID_PRODUCT_FROM_DATABASE=VS14x series PowerPC PCI board + +pci:v00001888d00000720* + ID_PRODUCT_FROM_DATABASE=VS24x series PowerPC PCI board + +pci:v0000188A* + ID_VENDOR_FROM_DATABASE=Ample Communications, Inc + +pci:v00001890* + ID_VENDOR_FROM_DATABASE=Egenera, Inc. + +pci:v00001894* + ID_VENDOR_FROM_DATABASE=KNC One + +pci:v00001896* + ID_VENDOR_FROM_DATABASE=B&B Electronics Manufacturing Company, Inc. + +pci:v00001896d00004202* + ID_PRODUCT_FROM_DATABASE=MIport 3PCIU2 2-port Serial + +pci:v00001896d00004204* + ID_PRODUCT_FROM_DATABASE=MIport 3PCIU4 4-port Serial + +pci:v00001896d00004208* + ID_PRODUCT_FROM_DATABASE=MIport 3PCIU8 8-port Serial + +pci:v00001896d00004211* + ID_PRODUCT_FROM_DATABASE=MIport 3PCIOU1 1-port Isolated Serial + +pci:v00001896d00004212* + ID_PRODUCT_FROM_DATABASE=MIport 3PCIOU2 2-port Isolated Serial + +pci:v00001896d00004214* + ID_PRODUCT_FROM_DATABASE=MIport 3PCIOU4 4-port Isolated Serial + +pci:v00001896d0000BB10* + ID_PRODUCT_FROM_DATABASE=3PCI2 2-Port Serial + +pci:v00001896d0000BB11* + ID_PRODUCT_FROM_DATABASE=3PCIO1 1-Port Isolated Serial + +pci:v00001897* + ID_VENDOR_FROM_DATABASE=AMtek + +pci:v000018A1* + ID_VENDOR_FROM_DATABASE=Astute Networks Inc. + +pci:v000018A2* + ID_VENDOR_FROM_DATABASE=Stretch Inc. + +pci:v000018A2d00000002* + ID_PRODUCT_FROM_DATABASE=VRC6016 16-Channel PCIe DVR Card + +pci:v000018A3* + ID_VENDOR_FROM_DATABASE=AT&T + +pci:v000018AC* + ID_VENDOR_FROM_DATABASE=DViCO Corporation + +pci:v000018ACd0000D500* + ID_PRODUCT_FROM_DATABASE=FusionHDTV 5 + +pci:v000018ACd0000D800* + ID_PRODUCT_FROM_DATABASE=FusionHDTV 3 Gold + +pci:v000018ACd0000D810* + ID_PRODUCT_FROM_DATABASE=FusionHDTV 3 Gold-Q + +pci:v000018ACd0000D820* + ID_PRODUCT_FROM_DATABASE=FusionHDTV 3 Gold-T + +pci:v000018ACd0000DB30* + ID_PRODUCT_FROM_DATABASE=FusionHDTV DVB-T Pro + +pci:v000018ACd0000DB40* + ID_PRODUCT_FROM_DATABASE=FusionHDTV DVB-T Hybrid + +pci:v000018ACd0000DB78* + ID_PRODUCT_FROM_DATABASE=FusionHDTV DVB-T Dual Express + +pci:v000018B8* + ID_VENDOR_FROM_DATABASE=Ammasso + +pci:v000018B8d0000B001* + ID_PRODUCT_FROM_DATABASE=AMSO 1100 iWARP/RDMA Gigabit Ethernet Coprocessor + +pci:v000018BC* + ID_VENDOR_FROM_DATABASE=Info-Tek Corp. + +pci:v000018C3* + ID_VENDOR_FROM_DATABASE=Micronas Semiconductor Holding AG + +pci:v000018C3d00000720* + ID_PRODUCT_FROM_DATABASE=nGene PCI-Express Multimedia Controller + +pci:v000018C3d00000720sv000007CAsd0000032E* + ID_PRODUCT_FROM_DATABASE=Hybrid M779 PCI-E + +pci:v000018C8* + ID_VENDOR_FROM_DATABASE=Cray Inc + +pci:v000018C9* + ID_VENDOR_FROM_DATABASE=ARVOO Engineering BV + +pci:v000018CA* + ID_VENDOR_FROM_DATABASE=XGI Technology Inc. (eXtreme Graphics Innovation) + +pci:v000018CAd00000020* + ID_PRODUCT_FROM_DATABASE=Z7/Z9 (XG20 core) + +pci:v000018CAd00000021* + ID_PRODUCT_FROM_DATABASE=Z9s/Z9m (XG21 core) + +pci:v000018CAd00000027* + ID_PRODUCT_FROM_DATABASE=Z11/Z11M + +pci:v000018CAd00000040* + ID_PRODUCT_FROM_DATABASE=Volari V3XT/V5/V8 + +pci:v000018CAd00000047* + ID_PRODUCT_FROM_DATABASE=Volari 8300 (chip: XP10, codename: XG47) + +pci:v000018D2* + ID_VENDOR_FROM_DATABASE=Sitecom Europe BV (Wrong ID) + +pci:v000018D2d00003069* + ID_PRODUCT_FROM_DATABASE=DC-105v2 ISDN controller + +pci:v000018D8* + ID_VENDOR_FROM_DATABASE=Dialogue Technology Corp. + +pci:v000018DD* + ID_VENDOR_FROM_DATABASE=Artimi Inc + +pci:v000018DDd00004C6F* + ID_PRODUCT_FROM_DATABASE=Artimi RTMI-100 UWB adapter + +pci:v000018E6* + ID_VENDOR_FROM_DATABASE=MPL AG + +pci:v000018E6d00000001* + ID_PRODUCT_FROM_DATABASE=OSCI [Octal Serial Communication Interface] + +pci:v000018EB* + ID_VENDOR_FROM_DATABASE=Advance Multimedia Internet Technology, Inc. + +pci:v000018EC* + ID_VENDOR_FROM_DATABASE=Cesnet, z.s.p.o. + +pci:v000018ECd00006D05* + ID_PRODUCT_FROM_DATABASE=ML555 + +pci:v000018ECd00006D05sv000018ECsd00000100* + ID_PRODUCT_FROM_DATABASE=NIC (ethernet interfaces) + +pci:v000018ECd00006D05sv000018ECsd00000200* + ID_PRODUCT_FROM_DATABASE=NIC (szedata2) 4x1G + +pci:v000018ECd00006D05sv000018ECsd00000201* + ID_PRODUCT_FROM_DATABASE=NIC (szedata2) 2x10G + +pci:v000018ECd00006D05sv000018ECsd00000300* + ID_PRODUCT_FROM_DATABASE=NIFIC (szedata2) 4x1G + +pci:v000018ECd00006D05sv000018ECsd00000302* + ID_PRODUCT_FROM_DATABASE=NIFIC (szedata2) 2x10G + +pci:v000018ECd00006D05sv000018ECsd00004200* + ID_PRODUCT_FROM_DATABASE=Flexible FlowMon (szedata2) 1x10G + +pci:v000018ECd00006D05sv000018ECsd0000FF00* + ID_PRODUCT_FROM_DATABASE=Testing design + +pci:v000018ECd00006D05sv000018ECsd0000FF01* + ID_PRODUCT_FROM_DATABASE=Boot design + +pci:v000018ECd0000C006* + ID_PRODUCT_FROM_DATABASE=COMBO6 + +pci:v000018ECd0000C006sv000018ECsd0000D001* + ID_PRODUCT_FROM_DATABASE=COMBO-4MTX + +pci:v000018ECd0000C006sv000018ECsd0000D002* + ID_PRODUCT_FROM_DATABASE=COMBO-4SFP + +pci:v000018ECd0000C006sv000018ECsd0000D003* + ID_PRODUCT_FROM_DATABASE=COMBO-4SFPRO + +pci:v000018ECd0000C006sv000018ECsd0000D004* + ID_PRODUCT_FROM_DATABASE=COMBO-2XFP + +pci:v000018ECd0000C032* + ID_PRODUCT_FROM_DATABASE=COMBO-LXT110 + +pci:v000018ECd0000C032sv000018ECsd00000100* + ID_PRODUCT_FROM_DATABASE=NIC (ethernet interfaces) + +pci:v000018ECd0000C032sv000018ECsd00000200* + ID_PRODUCT_FROM_DATABASE=NIC (szedata2) 4x1G + +pci:v000018ECd0000C032sv000018ECsd00000201* + ID_PRODUCT_FROM_DATABASE=NIC (szedata2) 2x10G + +pci:v000018ECd0000C032sv000018ECsd00000300* + ID_PRODUCT_FROM_DATABASE=NIFIC (szedata2) 4x1G + +pci:v000018ECd0000C032sv000018ECsd00000302* + ID_PRODUCT_FROM_DATABASE=NIFIC (szedata2) 2x10G + +pci:v000018ECd0000C032sv000018ECsd00004200* + ID_PRODUCT_FROM_DATABASE=Flexible FlowMon (szedata2) 1x10G + +pci:v000018ECd0000C032sv000018ECsd0000FF00* + ID_PRODUCT_FROM_DATABASE=Testing design + +pci:v000018ECd0000C032sv000018ECsd0000FF01* + ID_PRODUCT_FROM_DATABASE=Boot design + +pci:v000018ECd0000C045* + ID_PRODUCT_FROM_DATABASE=COMBO6E + +pci:v000018ECd0000C050* + ID_PRODUCT_FROM_DATABASE=COMBO-PTM + +pci:v000018ECd0000C058* + ID_PRODUCT_FROM_DATABASE=COMBO6X + +pci:v000018ECd0000C058sv000018ECsd0000D001* + ID_PRODUCT_FROM_DATABASE=COMBO-4MTX + +pci:v000018ECd0000C058sv000018ECsd0000D002* + ID_PRODUCT_FROM_DATABASE=COMBO-4SFP + +pci:v000018ECd0000C058sv000018ECsd0000D003* + ID_PRODUCT_FROM_DATABASE=COMBO-4SFPRO + +pci:v000018ECd0000C058sv000018ECsd0000D004* + ID_PRODUCT_FROM_DATABASE=COMBO-2XFP + +pci:v000018ECd0000C132* + ID_PRODUCT_FROM_DATABASE=COMBO-LXT155 + +pci:v000018ECd0000C132sv000018ECsd00000100* + ID_PRODUCT_FROM_DATABASE=NIC (ethernet interfaces) + +pci:v000018ECd0000C132sv000018ECsd00000200* + ID_PRODUCT_FROM_DATABASE=NIC (szedata2) 4x1G + +pci:v000018ECd0000C132sv000018ECsd00000201* + ID_PRODUCT_FROM_DATABASE=NIC (szedata2) 2x10G + +pci:v000018ECd0000C132sv000018ECsd00000300* + ID_PRODUCT_FROM_DATABASE=NIFIC (szedata2) 4x1G + +pci:v000018ECd0000C132sv000018ECsd00000302* + ID_PRODUCT_FROM_DATABASE=NIFIC (szedata2) 2x10G + +pci:v000018ECd0000C132sv000018ECsd00004200* + ID_PRODUCT_FROM_DATABASE=Flexible FlowMon (szedata2) 1x10G + +pci:v000018ECd0000C132sv000018ECsd0000FF00* + ID_PRODUCT_FROM_DATABASE=Testing design + +pci:v000018ECd0000C132sv000018ECsd0000FF01* + ID_PRODUCT_FROM_DATABASE=Boot design + +pci:v000018ECd0000C232* + ID_PRODUCT_FROM_DATABASE=COMBO-FXT100 + +pci:v000018ECd0000C232sv000018ECsd00000100* + ID_PRODUCT_FROM_DATABASE=NIC (ethernet interfaces) + +pci:v000018ECd0000C232sv000018ECsd00000200* + ID_PRODUCT_FROM_DATABASE=NIC (szedata2) 4x1G + +pci:v000018ECd0000C232sv000018ECsd00000201* + ID_PRODUCT_FROM_DATABASE=NIC (szedata2) 2x10G + +pci:v000018ECd0000C232sv000018ECsd00000300* + ID_PRODUCT_FROM_DATABASE=NIFIC (szedata2) 4x1G + +pci:v000018ECd0000C232sv000018ECsd00000302* + ID_PRODUCT_FROM_DATABASE=NIFIC (szedata2) 2x10G + +pci:v000018ECd0000C232sv000018ECsd00004200* + ID_PRODUCT_FROM_DATABASE=Flexible FlowMon (szedata2) 1x10G + +pci:v000018ECd0000C232sv000018ECsd0000FF00* + ID_PRODUCT_FROM_DATABASE=Testing design + +pci:v000018ECd0000C232sv000018ECsd0000FF01* + ID_PRODUCT_FROM_DATABASE=Boot design + +pci:v000018EE* + ID_VENDOR_FROM_DATABASE=Chenming Mold Ind. Corp. + +pci:v000018F1* + ID_VENDOR_FROM_DATABASE=Spectrum GmbH + +pci:v000018F4* + ID_VENDOR_FROM_DATABASE=Napatech A/S + +pci:v000018F4d00000031* + ID_PRODUCT_FROM_DATABASE=NT20X Network Adapter + +pci:v000018F4d00000051* + ID_PRODUCT_FROM_DATABASE=NT20X Capture Card + +pci:v000018F4d00000061* + ID_PRODUCT_FROM_DATABASE=NT20E Capture Card + +pci:v000018F4d00000064* + ID_PRODUCT_FROM_DATABASE=NT20E Inline Card + +pci:v000018F4d00000071* + ID_PRODUCT_FROM_DATABASE=NT4E Capture Card + +pci:v000018F4d00000074* + ID_PRODUCT_FROM_DATABASE=NT4E Inline Card + +pci:v000018F4d00000081* + ID_PRODUCT_FROM_DATABASE=NT4E 4-port Expansion Card + +pci:v000018F4d00000091* + ID_PRODUCT_FROM_DATABASE=NT20X Capture Card [New Rev] + +pci:v000018F4d000000A1* + ID_PRODUCT_FROM_DATABASE=NT4E-STD Capture Card + +pci:v000018F4d000000A4* + ID_PRODUCT_FROM_DATABASE=NT4E-STD Inline Card + +pci:v000018F4d000000B1* + ID_PRODUCT_FROM_DATABASE=NTBPE Optical Bypass Adapter + +pci:v000018F4d000000C5* + ID_PRODUCT_FROM_DATABASE=NT20E2 Network Adapter 2x10Gb + +pci:v000018F4d000000D5* + ID_PRODUCT_FROM_DATABASE=NT40E2-4 Network Adapter 4x10Gb + +pci:v000018F4d000000E5* + ID_PRODUCT_FROM_DATABASE=NT40E2-1 Network Adapter 1x40Gb + +pci:v000018F4d000000F5* + ID_PRODUCT_FROM_DATABASE=NT4E2-4T-BP Network Adapter 4x1Gb with Electrical Bypass + +pci:v000018F6* + ID_VENDOR_FROM_DATABASE=NextIO + +pci:v000018F6d00001000* + ID_PRODUCT_FROM_DATABASE=[Nexsis] Switch Virtual P2P PCIe Bridge + +pci:v000018F6d00001050* + ID_PRODUCT_FROM_DATABASE=[Nexsis] Switch Virtual P2P PCI Bridge + +pci:v000018F6d00002000* + ID_PRODUCT_FROM_DATABASE=[Nexsis] Switch Integrated Mgmt. Endpoint + +pci:v000018F7* + ID_VENDOR_FROM_DATABASE=Commtech, Inc. + +pci:v000018F7d00000001* + ID_PRODUCT_FROM_DATABASE=ESCC-PCI-335 Serial PCI Adapter [Fastcom] + +pci:v000018F7d00000002* + ID_PRODUCT_FROM_DATABASE=422/4-PCI-335 Serial PCI Adapter [Fastcom] + +pci:v000018F7d00000003* + ID_PRODUCT_FROM_DATABASE=232/4-1M-PCI Serial PCI Adapter [Fastcom] + +pci:v000018F7d00000004* + ID_PRODUCT_FROM_DATABASE=422/2-PCI-335 Serial PCI Adapter [Fastcom] + +pci:v000018F7d00000005* + ID_PRODUCT_FROM_DATABASE=IGESCC-PCI-ISO/1 Serial PCI Adapter [Fastcom] + +pci:v000018F7d0000000A* + ID_PRODUCT_FROM_DATABASE=232/4-PCI-335 Serial PCI Adapter [Fastcom] + +pci:v000018F7d0000000B* + ID_PRODUCT_FROM_DATABASE=232/8-PCI-335 Serial PCI Adapter [Fastcom] + +pci:v000018F7d0000000F* + ID_PRODUCT_FROM_DATABASE=FSCC Serial PCI Adapter [Fastcom] + +pci:v000018F7d00000010* + ID_PRODUCT_FROM_DATABASE=GSCC Serial PCI Adapter [Fastcom] + +pci:v000018F7d00000011* + ID_PRODUCT_FROM_DATABASE=QSSB Serial PCI Adapter [Fastcom] + +pci:v000018F7d00000014* + ID_PRODUCT_FROM_DATABASE=SuperFSCC Serial PCI Adapter [Fastcom] + +pci:v000018F7d00000015* + ID_PRODUCT_FROM_DATABASE=SuperFSCC-104 Serial PCI/104+ Adapter [Fastcom] + +pci:v000018F7d00000016* + ID_PRODUCT_FROM_DATABASE=FSCC-232 RS-232 Serial PCI Adapter [Fastcom] + +pci:v000018F7d00000017* + ID_PRODUCT_FROM_DATABASE=SuperFSCC-104-NOUART Serial PCI/104+ Adapter [Fastcom] + +pci:v000018F7d00000018* + ID_PRODUCT_FROM_DATABASE=SuperFSCC/4 Serial PCI Adapter [Fastcom] + +pci:v000018F7d00000019* + ID_PRODUCT_FROM_DATABASE=SuperFSCC Serial PCI Adapter [Fastcom] + +pci:v000018F7d0000001A* + ID_PRODUCT_FROM_DATABASE=SuperFSCC-104-LVDS Serial PC/104+ Adapter [Fastcom] + +pci:v000018F7d0000001B* + ID_PRODUCT_FROM_DATABASE=FSCC/4 Serial PCI Adapter [Fastcom] + +pci:v000018F7d0000001C* + ID_PRODUCT_FROM_DATABASE=SuperFSCC/4-LVDS Serial PCI Adapter [Fastcom] + +pci:v000018F7d00000020* + ID_PRODUCT_FROM_DATABASE=422/4-PCIe Serial PCIe Adapter [Fastcom] + +pci:v000018F7d00000021* + ID_PRODUCT_FROM_DATABASE=422/8-PCIe Serial PCIe Adapter [Fastcom] + +pci:v000018FB* + ID_VENDOR_FROM_DATABASE=Resilience Corporation + +pci:v00001904* + ID_VENDOR_FROM_DATABASE=Hangzhou Silan Microelectronics Co., Ltd. + +pci:v00001904d00002031* + ID_PRODUCT_FROM_DATABASE=SC92031 PCI Fast Ethernet Adapter + +pci:v00001904d00008139* + ID_PRODUCT_FROM_DATABASE=RTL8139D [Realtek] PCI 10/100BaseTX ethernet adaptor + +pci:v00001905* + ID_VENDOR_FROM_DATABASE=Micronas USA, Inc. + +pci:v00001912* + ID_VENDOR_FROM_DATABASE=Renesas Technology Corp. + +pci:v00001912d00000002* + ID_PRODUCT_FROM_DATABASE=SH7780 PCI Controller (PCIC) + +pci:v00001912d00000011* + ID_PRODUCT_FROM_DATABASE=SH7757 PCIe End-Point [PBI] + +pci:v00001912d00000012* + ID_PRODUCT_FROM_DATABASE=SH7757 PCIe-PCI Bridge [PPB] + +pci:v00001912d00000013* + ID_PRODUCT_FROM_DATABASE=SH7757 PCIe Switch [PS] + +pci:v00001912d00000014* + ID_PRODUCT_FROM_DATABASE=uPD720201 USB 3.0 Host Controller + +pci:v00001919* + ID_VENDOR_FROM_DATABASE=Soltek Computer Inc. + +pci:v00001923* + ID_VENDOR_FROM_DATABASE=Sangoma Technologies Corp. + +pci:v00001923d00000040* + ID_PRODUCT_FROM_DATABASE=A200/Remora FXO/FXS Analog AFT card + +pci:v00001923d00000100* + ID_PRODUCT_FROM_DATABASE=A104d QUAD T1/E1 AFT card + +pci:v00001923d00000300* + ID_PRODUCT_FROM_DATABASE=A101 single-port T1/E1 + +pci:v00001923d00000400* + ID_PRODUCT_FROM_DATABASE=A104u Quad T1/E1 AFT + +pci:v00001924* + ID_VENDOR_FROM_DATABASE=Solarflare Communications + +pci:v00001924d00000703* + ID_PRODUCT_FROM_DATABASE=SFC4000 rev A net [Solarstorm] + +pci:v00001924d00000703sv000010B8sd00000102* + ID_PRODUCT_FROM_DATABASE=SMC10GPCIe-10BT (A2) [TigerCard] + +pci:v00001924d00000703sv000010B8sd00000103* + ID_PRODUCT_FROM_DATABASE=SMC10GPCIe-10BT (A3) [TigerCard] + +pci:v00001924d00000703sv000010B8sd00000201* + ID_PRODUCT_FROM_DATABASE=SMC10GPCIe-XFP (A1) [TigerCard] + +pci:v00001924d00000703sv00001924sd00000101* + ID_PRODUCT_FROM_DATABASE=SFE4001-A1 + +pci:v00001924d00000703sv00001924sd00000102* + ID_PRODUCT_FROM_DATABASE=SFE4001-A2 + +pci:v00001924d00000703sv00001924sd00000103* + ID_PRODUCT_FROM_DATABASE=SFE4001-A3 + +pci:v00001924d00000703sv00001924sd00000201* + ID_PRODUCT_FROM_DATABASE=SFE4002-A1 + +pci:v00001924d00000703sv00001924sd00000301* + ID_PRODUCT_FROM_DATABASE=SFE4003-A1 + +pci:v00001924d00000703sv00001924sd00000302* + ID_PRODUCT_FROM_DATABASE=SFE4003-A2 + +pci:v00001924d00000703sv00001924sd00000303* + ID_PRODUCT_FROM_DATABASE=SFE4003-A3 + +pci:v00001924d00000703sv00001924sd00000304* + ID_PRODUCT_FROM_DATABASE=SFE4003-A4 + +pci:v00001924d00000703sv00001924sd00000500* + ID_PRODUCT_FROM_DATABASE=SFE4005-A0 + +pci:v00001924d00000710* + ID_PRODUCT_FROM_DATABASE=SFC4000 rev B [Solarstorm] + +pci:v00001924d00000710sv000010B8sd00000103* + ID_PRODUCT_FROM_DATABASE=SMC10GPCIe-10BT (A3) [TigerCard] + +pci:v00001924d00000710sv000010B8sd00000201* + ID_PRODUCT_FROM_DATABASE=SMC10GPCIe-XFP (A1) [TigerCard] + +pci:v00001924d00000710sv00001924sd00000102* + ID_PRODUCT_FROM_DATABASE=SFE4001-A2 + +pci:v00001924d00000710sv00001924sd00000103* + ID_PRODUCT_FROM_DATABASE=SFE4001-A3 + +pci:v00001924d00000710sv00001924sd00000201* + ID_PRODUCT_FROM_DATABASE=SFE4002-A1 + +pci:v00001924d00000710sv00001924sd00000302* + ID_PRODUCT_FROM_DATABASE=SFE4003-A2 + +pci:v00001924d00000710sv00001924sd00000303* + ID_PRODUCT_FROM_DATABASE=SFE4003-A3 + +pci:v00001924d00000710sv00001924sd00000304* + ID_PRODUCT_FROM_DATABASE=SFE4003-A4 + +pci:v00001924d00000710sv00001924sd00000500* + ID_PRODUCT_FROM_DATABASE=SFE4005-A0 + +pci:v00001924d00000710sv00001924sd00005102* + ID_PRODUCT_FROM_DATABASE=SFN4111T-A2 + +pci:v00001924d00000710sv00001924sd00005103* + ID_PRODUCT_FROM_DATABASE=SFN4111T-R3 + +pci:v00001924d00000710sv00001924sd00005104* + ID_PRODUCT_FROM_DATABASE=SFN4111T-R4 + +pci:v00001924d00000710sv00001924sd00005105* + ID_PRODUCT_FROM_DATABASE=SFN4111T-R5 + +pci:v00001924d00000710sv00001924sd00005201* + ID_PRODUCT_FROM_DATABASE=SFN4112F-R1 + +pci:v00001924d00000710sv00001924sd00005202* + ID_PRODUCT_FROM_DATABASE=SFN4112F-R2 + +pci:v00001924d00000803* + ID_PRODUCT_FROM_DATABASE=SFC9020 [Solarstorm] + +pci:v00001924d00000803sv00001924sd00001201* + ID_PRODUCT_FROM_DATABASE=SFA6902F-R1 SFP+ AOE Adapter + +pci:v00001924d00000803sv00001924sd00006200* + ID_PRODUCT_FROM_DATABASE=SFN5122F-R0 + +pci:v00001924d00000803sv00001924sd00006201* + ID_PRODUCT_FROM_DATABASE=SFN5122F-R1 + +pci:v00001924d00000803sv00001924sd00006202* + ID_PRODUCT_FROM_DATABASE=SFN5122F-R2 + +pci:v00001924d00000803sv00001924sd00006204* + ID_PRODUCT_FROM_DATABASE=SFN5122F-R4 + +pci:v00001924d00000803sv00001924sd00006205* + ID_PRODUCT_FROM_DATABASE=SFN5122F-R5 + +pci:v00001924d00000803sv00001924sd00006206* + ID_PRODUCT_FROM_DATABASE=SFN5122F-R6 + +pci:v00001924d00000803sv00001924sd00006207* + ID_PRODUCT_FROM_DATABASE=SFN5122F-R7 + +pci:v00001924d00000803sv00001924sd00006210* + ID_PRODUCT_FROM_DATABASE=SFN5322F-R0 + +pci:v00001924d00000803sv00001924sd00006211* + ID_PRODUCT_FROM_DATABASE=SFN5322F-R1 + +pci:v00001924d00000803sv00001924sd00006217* + ID_PRODUCT_FROM_DATABASE=SFN5322F-R7 + +pci:v00001924d00000803sv00001924sd00006227* + ID_PRODUCT_FROM_DATABASE=SFN6122F-R7 + +pci:v00001924d00000803sv00001924sd00006237* + ID_PRODUCT_FROM_DATABASE=SFN6322F-R7 + +pci:v00001924d00000803sv00001924sd00006501* + ID_PRODUCT_FROM_DATABASE=SFN5802K-R1 + +pci:v00001924d00000803sv00001924sd00006511* + ID_PRODUCT_FROM_DATABASE=SFN5814H-R1 + +pci:v00001924d00000803sv00001924sd00006521* + ID_PRODUCT_FROM_DATABASE=SFN5812H-R1 + +pci:v00001924d00000803sv00001924sd00006562* + ID_PRODUCT_FROM_DATABASE=SFN6832F-R2 SFP+ Mezzanine Adapter + +pci:v00001924d00000803sv00001924sd00006A05* + ID_PRODUCT_FROM_DATABASE=SFN5112F-R5 + +pci:v00001924d00000803sv00001924sd00006A06* + ID_PRODUCT_FROM_DATABASE=SFN5112F-R6 + +pci:v00001924d00000803sv00001924sd00007206* + ID_PRODUCT_FROM_DATABASE=SFN5162F-R6 + +pci:v00001924d00000803sv00001924sd00007207* + ID_PRODUCT_FROM_DATABASE=SFN5162F-R7 + +pci:v00001924d00000803sv00001924sd00007A06* + ID_PRODUCT_FROM_DATABASE=SFN5152F-R6 + +pci:v00001924d00000803sv00001924sd00007A07* + ID_PRODUCT_FROM_DATABASE=SFN5152F-R7 + +pci:v00001924d00000813* + ID_PRODUCT_FROM_DATABASE=SFL9021 [Solarstorm] + +pci:v00001924d00000813sv00001924sd00006100* + ID_PRODUCT_FROM_DATABASE=SFN5121T-R0 + +pci:v00001924d00000813sv00001924sd00006102* + ID_PRODUCT_FROM_DATABASE=SFN5121T-R2 + +pci:v00001924d00000813sv00001924sd00006103* + ID_PRODUCT_FROM_DATABASE=SFN5121T-R3 + +pci:v00001924d00000813sv00001924sd00006104* + ID_PRODUCT_FROM_DATABASE=SFN5121T-R4 + +pci:v00001924d00000813sv00001924sd00006902* + ID_PRODUCT_FROM_DATABASE=SFN5111T-R2 + +pci:v00001924d00000813sv00001924sd00006904* + ID_PRODUCT_FROM_DATABASE=SFN5111T-R4 + +pci:v00001924d00000813sv00001924sd00007104* + ID_PRODUCT_FROM_DATABASE=SFN5161T-R4 + +pci:v00001924d00000813sv00001924sd00007904* + ID_PRODUCT_FROM_DATABASE=SFN5151T-R4 + +pci:v00001924d00001803* + ID_PRODUCT_FROM_DATABASE=SFC9020 Virtual Function [Solarstorm] + +pci:v00001924d00001813* + ID_PRODUCT_FROM_DATABASE=SFL9021 Virtual Function [Solarstorm] + +pci:v00001924d00006703* + ID_PRODUCT_FROM_DATABASE=SFC4000 rev A iSCSI/Onload [Solarstorm] + +pci:v00001924d00006703sv000010B8sd00000102* + ID_PRODUCT_FROM_DATABASE=SMC10GPCIe-10BT (A2) [TigerCard] + +pci:v00001924d00006703sv000010B8sd00000103* + ID_PRODUCT_FROM_DATABASE=SMC10GPCIe-10BT (A3) [TigerCard] + +pci:v00001924d00006703sv000010B8sd00000201* + ID_PRODUCT_FROM_DATABASE=SMC10GPCIe-XFP (A1) [TigerCard] + +pci:v00001924d00006703sv00001924sd00000101* + ID_PRODUCT_FROM_DATABASE=SFE4001-A1 + +pci:v00001924d00006703sv00001924sd00000102* + ID_PRODUCT_FROM_DATABASE=SFE4001-A2 + +pci:v00001924d00006703sv00001924sd00000103* + ID_PRODUCT_FROM_DATABASE=SFE4001-A3 + +pci:v00001924d00006703sv00001924sd00000201* + ID_PRODUCT_FROM_DATABASE=SFE4002-A1 + +pci:v00001924d00006703sv00001924sd00000301* + ID_PRODUCT_FROM_DATABASE=SFE4003-A1 + +pci:v00001924d00006703sv00001924sd00000302* + ID_PRODUCT_FROM_DATABASE=SFE4003-A2 + +pci:v00001924d00006703sv00001924sd00000303* + ID_PRODUCT_FROM_DATABASE=SFE4003-A3 + +pci:v00001924d00006703sv00001924sd00000304* + ID_PRODUCT_FROM_DATABASE=SFE4003-A4 + +pci:v00001924d00006703sv00001924sd00000500* + ID_PRODUCT_FROM_DATABASE=SFE4005-A0 + +pci:v00001924d0000C101* + ID_PRODUCT_FROM_DATABASE=EF1-21022T [EtherFabric] + +pci:v0000192A* + ID_VENDOR_FROM_DATABASE=BiTMICRO Networks Inc. + +pci:v0000192E* + ID_VENDOR_FROM_DATABASE=TransDimension + +pci:v00001931* + ID_VENDOR_FROM_DATABASE=Option N.V. + +pci:v00001931d0000000C* + ID_PRODUCT_FROM_DATABASE=Qualcomm MSM6275 UMTS chip + +pci:v00001932* + ID_VENDOR_FROM_DATABASE=DiBcom + +pci:v0000193C* + ID_VENDOR_FROM_DATABASE=MAXIM Integrated Products + +pci:v0000193F* + ID_VENDOR_FROM_DATABASE=Comtech AHA Corp. + +pci:v0000193Fd00000001* + ID_PRODUCT_FROM_DATABASE=AHA36x-PCIX + +pci:v0000193Fd00000360* + ID_PRODUCT_FROM_DATABASE=AHA360-PCIe + +pci:v0000193Fd00000363* + ID_PRODUCT_FROM_DATABASE=AHA363-PCIe + +pci:v0000193Fd00000364* + ID_PRODUCT_FROM_DATABASE=AHA364-PCIe + +pci:v0000193Fd00000367* + ID_PRODUCT_FROM_DATABASE=AHA367-PCIe + +pci:v0000193Fd00000370* + ID_PRODUCT_FROM_DATABASE=AHA370-PCIe + +pci:v00001942* + ID_VENDOR_FROM_DATABASE=ClearSpeed Technology plc + +pci:v00001942d0000E511* + ID_PRODUCT_FROM_DATABASE=Advance X620 accelerator card + +pci:v00001942d0000E521* + ID_PRODUCT_FROM_DATABASE=Advance e620 accelerator card + +pci:v00001947* + ID_VENDOR_FROM_DATABASE=C-guys, Inc. + +pci:v00001947d00004743* + ID_PRODUCT_FROM_DATABASE=CG200 Dual SD/SDIO Host controller device + +pci:v00001948* + ID_VENDOR_FROM_DATABASE=Alpha Networks Inc. + +pci:v0000194A* + ID_VENDOR_FROM_DATABASE=DapTechnology B.V. + +pci:v0000194Ad00001111* + ID_PRODUCT_FROM_DATABASE=FireSpy3850 + +pci:v0000194Ad00001112* + ID_PRODUCT_FROM_DATABASE=FireSpy450b + +pci:v0000194Ad00001113* + ID_PRODUCT_FROM_DATABASE=FireSpy450bT + +pci:v0000194Ad00001114* + ID_PRODUCT_FROM_DATABASE=FireSpy850 + +pci:v0000194Ad00001115* + ID_PRODUCT_FROM_DATABASE=FireSpy850bT + +pci:v0000194Ad00001200* + ID_PRODUCT_FROM_DATABASE=FireTrac 3460bT + +pci:v0000194Ad00001201* + ID_PRODUCT_FROM_DATABASE=FireTrac 3460bT (fallback firmware) + +pci:v0000194Ad00001202* + ID_PRODUCT_FROM_DATABASE=FireTrac 3460bT + +pci:v0000194Ad00001203* + ID_PRODUCT_FROM_DATABASE=FireTrac 3460bT (fallback firmware) + +pci:v00001954* + ID_VENDOR_FROM_DATABASE=One Stop Systems, Inc. + +pci:v00001957* + ID_VENDOR_FROM_DATABASE=Freescale Semiconductor Inc + +pci:v00001957d00000012* + ID_PRODUCT_FROM_DATABASE=MPC8548E + +pci:v00001957d00000013* + ID_PRODUCT_FROM_DATABASE=MPC8548 + +pci:v00001957d00000014* + ID_PRODUCT_FROM_DATABASE=MPC8543E + +pci:v00001957d00000015* + ID_PRODUCT_FROM_DATABASE=MPC8543 + +pci:v00001957d00000018* + ID_PRODUCT_FROM_DATABASE=MPC8547E + +pci:v00001957d00000019* + ID_PRODUCT_FROM_DATABASE=MPC8545E + +pci:v00001957d0000001A* + ID_PRODUCT_FROM_DATABASE=MPC8545 + +pci:v00001957d00000020* + ID_PRODUCT_FROM_DATABASE=MPC8568E + +pci:v00001957d00000021* + ID_PRODUCT_FROM_DATABASE=MPC8568 + +pci:v00001957d00000022* + ID_PRODUCT_FROM_DATABASE=MPC8567E + +pci:v00001957d00000023* + ID_PRODUCT_FROM_DATABASE=MPC8567 + +pci:v00001957d00000030* + ID_PRODUCT_FROM_DATABASE=MPC8533E + +pci:v00001957d00000031* + ID_PRODUCT_FROM_DATABASE=MPC8533 + +pci:v00001957d00000032* + ID_PRODUCT_FROM_DATABASE=MPC8544E + +pci:v00001957d00000033* + ID_PRODUCT_FROM_DATABASE=MPC8544 + +pci:v00001957d00000040* + ID_PRODUCT_FROM_DATABASE=MPC8572E + +pci:v00001957d00000041* + ID_PRODUCT_FROM_DATABASE=MPC8572 + +pci:v00001957d00000050* + ID_PRODUCT_FROM_DATABASE=MPC8536E + +pci:v00001957d00000051* + ID_PRODUCT_FROM_DATABASE=MPC8536 + +pci:v00001957d00000052* + ID_PRODUCT_FROM_DATABASE=MPC8535E + +pci:v00001957d00000053* + ID_PRODUCT_FROM_DATABASE=MPC8535 + +pci:v00001957d00000060* + ID_PRODUCT_FROM_DATABASE=MPC8569 + +pci:v00001957d00000061* + ID_PRODUCT_FROM_DATABASE=MPC8569E + +pci:v00001957d00000070* + ID_PRODUCT_FROM_DATABASE=P2020E + +pci:v00001957d00000071* + ID_PRODUCT_FROM_DATABASE=P2020 + +pci:v00001957d00000078* + ID_PRODUCT_FROM_DATABASE=P2010E + +pci:v00001957d00000079* + ID_PRODUCT_FROM_DATABASE=P2010 + +pci:v00001957d00000080* + ID_PRODUCT_FROM_DATABASE=MPC8349E + +pci:v00001957d00000081* + ID_PRODUCT_FROM_DATABASE=MPC8349 + +pci:v00001957d00000082* + ID_PRODUCT_FROM_DATABASE=MPC8347E TBGA + +pci:v00001957d00000083* + ID_PRODUCT_FROM_DATABASE=MPC8347 TBGA + +pci:v00001957d00000084* + ID_PRODUCT_FROM_DATABASE=MPC8347E PBGA + +pci:v00001957d00000085* + ID_PRODUCT_FROM_DATABASE=MPC8347 PBGA + +pci:v00001957d00000086* + ID_PRODUCT_FROM_DATABASE=MPC8343E + +pci:v00001957d00000087* + ID_PRODUCT_FROM_DATABASE=MPC8343 + +pci:v00001957d000000B4* + ID_PRODUCT_FROM_DATABASE=MPC8315E + +pci:v00001957d000000C2* + ID_PRODUCT_FROM_DATABASE=MPC8379E + +pci:v00001957d000000C3* + ID_PRODUCT_FROM_DATABASE=MPC8379 + +pci:v00001957d000000C4* + ID_PRODUCT_FROM_DATABASE=MPC8378E + +pci:v00001957d000000C5* + ID_PRODUCT_FROM_DATABASE=MPC8378 + +pci:v00001957d000000C6* + ID_PRODUCT_FROM_DATABASE=MPC8377E + +pci:v00001957d000000C7* + ID_PRODUCT_FROM_DATABASE=MPC8377 + +pci:v00001957d00000100* + ID_PRODUCT_FROM_DATABASE=P1020E + +pci:v00001957d00000101* + ID_PRODUCT_FROM_DATABASE=P1020 + +pci:v00001957d00000102* + ID_PRODUCT_FROM_DATABASE=P1021E + +pci:v00001957d00000103* + ID_PRODUCT_FROM_DATABASE=P1021 + +pci:v00001957d00000108* + ID_PRODUCT_FROM_DATABASE=P1011E + +pci:v00001957d00000109* + ID_PRODUCT_FROM_DATABASE=P1011 + +pci:v00001957d0000010A* + ID_PRODUCT_FROM_DATABASE=P1012E + +pci:v00001957d0000010B* + ID_PRODUCT_FROM_DATABASE=P1012 + +pci:v00001957d00000110* + ID_PRODUCT_FROM_DATABASE=P1022E + +pci:v00001957d00000111* + ID_PRODUCT_FROM_DATABASE=P1022 + +pci:v00001957d00000111sv00001C7Fsd00005200* + ID_PRODUCT_FROM_DATABASE=EB5200 + +pci:v00001957d00000118* + ID_PRODUCT_FROM_DATABASE=P1013E + +pci:v00001957d00000119* + ID_PRODUCT_FROM_DATABASE=P1013 + +pci:v00001957d00000128* + ID_PRODUCT_FROM_DATABASE=P1010 + +pci:v00001957d00000400* + ID_PRODUCT_FROM_DATABASE=P4080E + +pci:v00001957d00000401* + ID_PRODUCT_FROM_DATABASE=P4080 + +pci:v00001957d00000408* + ID_PRODUCT_FROM_DATABASE=P4040E + +pci:v00001957d00000409* + ID_PRODUCT_FROM_DATABASE=P4040 + +pci:v00001957d0000580C* + ID_PRODUCT_FROM_DATABASE=MPC5121e + +pci:v00001957d00007010* + ID_PRODUCT_FROM_DATABASE=MPC8641 PCI Host Bridge + +pci:v00001957d00007011* + ID_PRODUCT_FROM_DATABASE=MPC8641D PCI Host Bridge + +pci:v00001957d00007018* + ID_PRODUCT_FROM_DATABASE=MPC8610 + +pci:v00001958* + ID_VENDOR_FROM_DATABASE=Faster Technology, LLC. + +pci:v00001959* + ID_VENDOR_FROM_DATABASE=PA Semi, Inc + +pci:v00001959d0000A000* + ID_PRODUCT_FROM_DATABASE=PA6T Core + +pci:v00001959d0000A001* + ID_PRODUCT_FROM_DATABASE=PWRficient Host Bridge + +pci:v00001959d0000A002* + ID_PRODUCT_FROM_DATABASE=PWRficient PCI-Express Port + +pci:v00001959d0000A003* + ID_PRODUCT_FROM_DATABASE=PWRficient SMBus Controller + +pci:v00001959d0000A004* + ID_PRODUCT_FROM_DATABASE=PWRficient 16550 UART + +pci:v00001959d0000A005* + ID_PRODUCT_FROM_DATABASE=PWRficient Gigabit Ethernet + +pci:v00001959d0000A006* + ID_PRODUCT_FROM_DATABASE=PWRficient 10-Gigabit Ethernet + +pci:v00001959d0000A007* + ID_PRODUCT_FROM_DATABASE=PWRficient DMA Controller + +pci:v00001959d0000A008* + ID_PRODUCT_FROM_DATABASE=PWRficient LPC/Localbus Interface + +pci:v00001959d0000A009* + ID_PRODUCT_FROM_DATABASE=PWRficient L2 Cache + +pci:v00001959d0000A00A* + ID_PRODUCT_FROM_DATABASE=PWRficient DDR2 Memory Controller + +pci:v00001959d0000A00B* + ID_PRODUCT_FROM_DATABASE=PWRficient SERDES + +pci:v00001959d0000A00C* + ID_PRODUCT_FROM_DATABASE=PWRficient System/Debug Controller + +pci:v00001959d0000A00D* + ID_PRODUCT_FROM_DATABASE=PWRficient PCI-Express Internal Endpoint + +pci:v00001966* + ID_VENDOR_FROM_DATABASE=Orad Hi-Tec Systems + +pci:v00001966d00001975* + ID_PRODUCT_FROM_DATABASE=DVG64 family + +pci:v00001966d00001977* + ID_PRODUCT_FROM_DATABASE=DVG128 family + +pci:v00001969* + ID_VENDOR_FROM_DATABASE=Atheros Communications Inc. + +pci:v00001969d00001026* + ID_PRODUCT_FROM_DATABASE=AR8121/AR8113/AR8114 Gigabit or Fast Ethernet + +pci:v00001969d00001026sv00001043sd00008304* + ID_PRODUCT_FROM_DATABASE=P5KPL-CM Motherboard + +pci:v00001969d00001048* + ID_PRODUCT_FROM_DATABASE=Attansic L1 Gigabit Ethernet + +pci:v00001969d00001048sv00001043sd00008226* + ID_PRODUCT_FROM_DATABASE=P5KPL-VM Motherboard + +pci:v00001969d00001062* + ID_PRODUCT_FROM_DATABASE=AR8132 Fast Ethernet + +pci:v00001969d00001063* + ID_PRODUCT_FROM_DATABASE=AR8131 Gigabit Ethernet + +pci:v00001969d00001063sv00001458sd0000E000* + ID_PRODUCT_FROM_DATABASE=GA-G31M-ES2L Motherboard + +pci:v00001969d00001066* + ID_PRODUCT_FROM_DATABASE=Attansic L2c Gigabit Ethernet + +pci:v00001969d00001067* + ID_PRODUCT_FROM_DATABASE=Attansic L1c Gigabit Ethernet + +pci:v00001969d00001073* + ID_PRODUCT_FROM_DATABASE=AR8151 v1.0 Gigabit Ethernet + +pci:v00001969d00001083* + ID_PRODUCT_FROM_DATABASE=AR8151 v2.0 Gigabit Ethernet + +pci:v00001969d00001090* + ID_PRODUCT_FROM_DATABASE=AR8162 Fast Ethernet + +pci:v00001969d00001091* + ID_PRODUCT_FROM_DATABASE=AR8161 Gigabit Ethernet + +pci:v00001969d00001091sv00001043sd00001477* + ID_PRODUCT_FROM_DATABASE=N56VZ + +pci:v00001969d00002048* + ID_PRODUCT_FROM_DATABASE=Attansic L2 Fast Ethernet + +pci:v00001969d00002060* + ID_PRODUCT_FROM_DATABASE=AR8152 v1.1 Fast Ethernet + +pci:v00001969d00002062* + ID_PRODUCT_FROM_DATABASE=AR8152 v2.0 Fast Ethernet + +pci:v0000196A* + ID_VENDOR_FROM_DATABASE=Sensory Networks Inc. + +pci:v0000196Ad00000101* + ID_PRODUCT_FROM_DATABASE=NodalCore C-1000 Content Classification Accelerator + +pci:v0000196Ad00000102* + ID_PRODUCT_FROM_DATABASE=NodalCore C-2000 Content Classification Accelerator + +pci:v0000196Ad00000105* + ID_PRODUCT_FROM_DATABASE=NodalCore C-3000 Content Classification Accelerator + +pci:v0000196D* + ID_VENDOR_FROM_DATABASE=Club-3D BV + +pci:v00001971* + ID_VENDOR_FROM_DATABASE=AGEIA Technologies, Inc. + +pci:v00001971d00001011* + ID_PRODUCT_FROM_DATABASE=Physics Processing Unit [PhysX] + +pci:v00001971d00001011sv00001043sd00000001* + ID_PRODUCT_FROM_DATABASE=PhysX P1 + +pci:v00001974* + ID_VENDOR_FROM_DATABASE=Eberspaecher Electronics + +pci:v00001976* + ID_VENDOR_FROM_DATABASE=TRENDnet + +pci:v00001977* + ID_VENDOR_FROM_DATABASE=Parsec + +pci:v0000197B* + ID_VENDOR_FROM_DATABASE=JMicron Technology Corp. + +pci:v0000197Bd00000250* + ID_PRODUCT_FROM_DATABASE=JMC250 PCI Express Gigabit Ethernet Controller + +pci:v0000197Bd00000260* + ID_PRODUCT_FROM_DATABASE=JMC260 PCI Express Fast Ethernet Controller + +pci:v0000197Bd00000368* + ID_PRODUCT_FROM_DATABASE=JMB368 IDE controller + +pci:v0000197Bd00002360* + ID_PRODUCT_FROM_DATABASE=JMB360 AHCI Controller + +pci:v0000197Bd00002361* + ID_PRODUCT_FROM_DATABASE=JMB361 AHCI/IDE + +pci:v0000197Bd00002361sv00001462sd00007235* + ID_PRODUCT_FROM_DATABASE=P965 Neo MS-7235 mainboard + +pci:v0000197Bd00002362* + ID_PRODUCT_FROM_DATABASE=JMB362 SATA Controller + +pci:v0000197Bd00002362sv00001043sd00008460* + ID_PRODUCT_FROM_DATABASE=P8P67 Deluxe Motherboard + +pci:v0000197Bd00002363* + ID_PRODUCT_FROM_DATABASE=JMB363 SATA/IDE Controller + +pci:v0000197Bd00002363sv00001043sd000081E4* + ID_PRODUCT_FROM_DATABASE=P5B [JMB363] + +pci:v0000197Bd00002363sv00001458sd0000B000* + ID_PRODUCT_FROM_DATABASE=GA-EP45-DS5 Motherboard + +pci:v0000197Bd00002363sv00001849sd00002363* + ID_PRODUCT_FROM_DATABASE=Motherboard (one of many) + +pci:v0000197Bd00002364* + ID_PRODUCT_FROM_DATABASE=JMB364 AHCI Controller + +pci:v0000197Bd00002365* + ID_PRODUCT_FROM_DATABASE=JMB365 AHCI/IDE + +pci:v0000197Bd00002366* + ID_PRODUCT_FROM_DATABASE=JMB366 AHCI/IDE + +pci:v0000197Bd00002368* + ID_PRODUCT_FROM_DATABASE=JMB368 IDE controller + +pci:v0000197Bd00002369* + ID_PRODUCT_FROM_DATABASE=JMB369 Serial ATA Controller + +pci:v0000197Bd00002380* + ID_PRODUCT_FROM_DATABASE=IEEE 1394 Host Controller + +pci:v0000197Bd00002381* + ID_PRODUCT_FROM_DATABASE=Standard SD Host Controller + +pci:v0000197Bd00002382* + ID_PRODUCT_FROM_DATABASE=SD/MMC Host Controller + +pci:v0000197Bd00002383* + ID_PRODUCT_FROM_DATABASE=MS Host Controller + +pci:v0000197Bd00002384* + ID_PRODUCT_FROM_DATABASE=xD Host Controller + +pci:v0000197Bd00002386* + ID_PRODUCT_FROM_DATABASE=Standard SD Host Controller + +pci:v0000197Bd00002387* + ID_PRODUCT_FROM_DATABASE=SD/MMC Host Controller + +pci:v0000197Bd00002388* + ID_PRODUCT_FROM_DATABASE=MS Host Controller + +pci:v0000197Bd00002389* + ID_PRODUCT_FROM_DATABASE=xD Host Controller + +pci:v0000197Bd00002391* + ID_PRODUCT_FROM_DATABASE=Standard SD Host Controller + +pci:v0000197Bd00002392* + ID_PRODUCT_FROM_DATABASE=SD/MMC Host Controller + +pci:v0000197Bd00002393* + ID_PRODUCT_FROM_DATABASE=MS Host Controller + +pci:v0000197Bd00002394* + ID_PRODUCT_FROM_DATABASE=xD Host Controller + +pci:v00001982* + ID_VENDOR_FROM_DATABASE=Distant Early Warning Communications Inc + +pci:v00001982d00001600* + ID_PRODUCT_FROM_DATABASE=OX16C954 HOST-A + +pci:v00001982d000016FF* + ID_PRODUCT_FROM_DATABASE=OX16C954 HOST-B + +pci:v00001989* + ID_VENDOR_FROM_DATABASE=Montilio Inc. + +pci:v00001989d00000001* + ID_PRODUCT_FROM_DATABASE=RapidFile Bridge + +pci:v00001989d00008001* + ID_PRODUCT_FROM_DATABASE=RapidFile + +pci:v0000198A* + ID_VENDOR_FROM_DATABASE=Nallatech Ltd. + +pci:v00001993* + ID_VENDOR_FROM_DATABASE=Innominate Security Technologies AG + +pci:v00001999* + ID_VENDOR_FROM_DATABASE=A-Logics + +pci:v00001999d0000A900* + ID_PRODUCT_FROM_DATABASE=AM-7209 Video Processor + +pci:v0000199A* + ID_VENDOR_FROM_DATABASE=Pulse-LINK, Inc. + +pci:v0000199D* + ID_VENDOR_FROM_DATABASE=Xsigo Systems + +pci:v0000199Dd00008209* + ID_PRODUCT_FROM_DATABASE=Virtual NIC Device + +pci:v0000199Dd0000890A* + ID_PRODUCT_FROM_DATABASE=Virtual HBA Device + +pci:v0000199F* + ID_VENDOR_FROM_DATABASE=Auvitek + +pci:v0000199Fd00008501* + ID_PRODUCT_FROM_DATABASE=AU85X1 PCI REV1.1 + +pci:v0000199Fd00008521* + ID_PRODUCT_FROM_DATABASE=AU8521 TV card + +pci:v000019A2* + ID_VENDOR_FROM_DATABASE=Emulex Corporation + +pci:v000019A2d00000200* + ID_PRODUCT_FROM_DATABASE=BladeEngine 10Gb PCI-E iSCSI adapter + +pci:v000019A2d00000201* + ID_PRODUCT_FROM_DATABASE=BladeEngine 10Gb PCIe Network Adapter + +pci:v000019A2d00000211* + ID_PRODUCT_FROM_DATABASE=BladeEngine2 10Gb Gen2 PCIe Network Adapter + +pci:v000019A2d00000212* + ID_PRODUCT_FROM_DATABASE=BladeEngine2 10Gb Gen2 PCIe iSCSI Adapter + +pci:v000019A2d00000221* + ID_PRODUCT_FROM_DATABASE=BladeEngine3 10Gb Gen2 PCIe Network Adapter + +pci:v000019A2d00000222* + ID_PRODUCT_FROM_DATABASE=BladeEngine3 10Gb Gen2 PCIe iSCSI Adapter + +pci:v000019A2d00000700* + ID_PRODUCT_FROM_DATABASE=OneConnect 10Gb NIC + +pci:v000019A2d00000700sv0000103Csd00001747* + ID_PRODUCT_FROM_DATABASE=NC550SFP DualPort 10GbE Server Adapter + +pci:v000019A2d00000700sv0000103Csd00001749* + ID_PRODUCT_FROM_DATABASE=NC550SFP Dual Port Server Adapter + +pci:v000019A2d00000700sv0000103Csd0000174A* + ID_PRODUCT_FROM_DATABASE=NC551m Dual Port FlexFabric 10Gb Adapter + +pci:v000019A2d00000700sv0000103Csd0000174B* + ID_PRODUCT_FROM_DATABASE=StorageWorks NC550 DualPort Converged Network Adapter + +pci:v000019A2d00000700sv0000103Csd00003314* + ID_PRODUCT_FROM_DATABASE=NC551i Dual Port FlexFabric 10Gb Adapter + +pci:v000019A2d00000702* + ID_PRODUCT_FROM_DATABASE=OneConnect 10Gb iSCSI Initiator + +pci:v000019A2d00000704* + ID_PRODUCT_FROM_DATABASE=OneConnect 10Gb FCoE Initiator + +pci:v000019A2d00000710* + ID_PRODUCT_FROM_DATABASE=OneConnect 10Gb NIC (be3) + +pci:v000019A2d00000710sv0000103Csd00003315* + ID_PRODUCT_FROM_DATABASE=NC553i 10Gb 2-port FlexFabric Converged Network Adapter + +pci:v000019A2d00000710sv0000103Csd00003340* + ID_PRODUCT_FROM_DATABASE=NC552SFP 2-port 10Gb Server Adapter + +pci:v000019A2d00000710sv0000103Csd00003341* + ID_PRODUCT_FROM_DATABASE=NC552m 10Gb 2-port FlexFabric Converged Network Adapter + +pci:v000019A2d00000710sv0000103Csd00003345* + ID_PRODUCT_FROM_DATABASE=NC553m 10Gb 2-port FlexFabric Converged Network Adapter + +pci:v000019A2d00000712* + ID_PRODUCT_FROM_DATABASE=OneConnect 10Gb iSCSI Initiator (be3) + +pci:v000019A2d00000714* + ID_PRODUCT_FROM_DATABASE=OneConnect 10Gb FCoE Initiator (be3) + +pci:v000019A2d00000714sv0000103Csd00003315* + ID_PRODUCT_FROM_DATABASE=NC553i 10Gb 2-port FlexFabric Converged Network Adapter + +pci:v000019A8* + ID_VENDOR_FROM_DATABASE=DAQDATA GmbH + +pci:v000019AC* + ID_VENDOR_FROM_DATABASE=Kasten Chase Applied Research + +pci:v000019ACd00000001* + ID_PRODUCT_FROM_DATABASE=ACA2400 Crypto Accelerator + +pci:v000019AE* + ID_VENDOR_FROM_DATABASE=Progeny Systems Corporation + +pci:v000019AEd00000520* + ID_PRODUCT_FROM_DATABASE=4135 HFT Interface Controller + +pci:v000019AEd00000521* + ID_PRODUCT_FROM_DATABASE=Decimator + +pci:v000019C1* + ID_VENDOR_FROM_DATABASE=Exegy Inc. + +pci:v000019D1* + ID_VENDOR_FROM_DATABASE=Motorola Expedience + +pci:v000019D4* + ID_VENDOR_FROM_DATABASE=Quixant Limited + +pci:v000019DA* + ID_VENDOR_FROM_DATABASE=ZOTAC International (MCO) Ltd. + +pci:v000019DE* + ID_VENDOR_FROM_DATABASE=Pico Computing + +pci:v000019E2* + ID_VENDOR_FROM_DATABASE=Vector Informatik GmbH + +pci:v000019E3* + ID_VENDOR_FROM_DATABASE=DDRdrive LLC + +pci:v000019E3d00005801* + ID_PRODUCT_FROM_DATABASE=DDRdrive X1 + +pci:v000019E3d00005808* + ID_PRODUCT_FROM_DATABASE=DDRdrive X8 + +pci:v000019E3d0000DD52* + ID_PRODUCT_FROM_DATABASE=DDRdrive X1-30 + +pci:v000019E7* + ID_VENDOR_FROM_DATABASE=NET (Network Equipment Technologies) + +pci:v000019E7d00001001* + ID_PRODUCT_FROM_DATABASE=STIX DSP Card + +pci:v000019E7d00001002* + ID_PRODUCT_FROM_DATABASE=STIX - 1 Port T1/E1 Card + +pci:v000019E7d00001003* + ID_PRODUCT_FROM_DATABASE=STIX - 2 Port T1/E1 Card + +pci:v000019E7d00001004* + ID_PRODUCT_FROM_DATABASE=STIX - 4 Port T1/E1 Card + +pci:v000019E7d00001005* + ID_PRODUCT_FROM_DATABASE=STIX - 4 Port FXS Card + +pci:v000019EE* + ID_VENDOR_FROM_DATABASE=Netronome Systems, Inc. + +pci:v000019F1* + ID_VENDOR_FROM_DATABASE=BFG Tech + +pci:v000019FF* + ID_VENDOR_FROM_DATABASE=Eclipse Electronic Systems, Inc. + +pci:v00001A03* + ID_VENDOR_FROM_DATABASE=ASPEED Technology, Inc. + +pci:v00001A03d00001150* + ID_PRODUCT_FROM_DATABASE=AST1150 PCI-to-PCI Bridge + +pci:v00001A03d00002000* + ID_PRODUCT_FROM_DATABASE=ASPEED Graphics Family + +pci:v00001A07* + ID_VENDOR_FROM_DATABASE=Kvaser AB + +pci:v00001A07d00000006* + ID_PRODUCT_FROM_DATABASE=CAN interface PC104+ HS/HS + +pci:v00001A07d00000007* + ID_PRODUCT_FROM_DATABASE=CAN interface PCIcanx II HS or HS/HS + +pci:v00001A07d00000008* + ID_PRODUCT_FROM_DATABASE=CAN interface PCIEcan HS or HS/HS + +pci:v00001A07d00000009* + ID_PRODUCT_FROM_DATABASE=CAN interface PCI104 HS/HS + +pci:v00001A08* + ID_VENDOR_FROM_DATABASE=Sierra semiconductor + +pci:v00001A08d00000000* + ID_PRODUCT_FROM_DATABASE=SC15064 + +pci:v00001A0E* + ID_VENDOR_FROM_DATABASE=DekTec Digital Video B.V. + +pci:v00001A17* + ID_VENDOR_FROM_DATABASE=Force10 Networks, Inc. + +pci:v00001A17d00008002* + ID_PRODUCT_FROM_DATABASE=PB-10GE-2P 10GbE Security Card + +pci:v00001A1D* + ID_VENDOR_FROM_DATABASE=GFaI e.V. + +pci:v00001A1Dd00001A17* + ID_PRODUCT_FROM_DATABASE=Meta Networks MTP-1G IDPS NIC + +pci:v00001A1E* + ID_VENDOR_FROM_DATABASE=3Leaf Systems, Inc. + +pci:v00001A22* + ID_VENDOR_FROM_DATABASE=Ambric Inc. + +pci:v00001A29* + ID_VENDOR_FROM_DATABASE=Fortinet, Inc. + +pci:v00001A2B* + ID_VENDOR_FROM_DATABASE=Ascom AG + +pci:v00001A2Bd00000000* + ID_PRODUCT_FROM_DATABASE=GESP v1.2 + +pci:v00001A2Bd00000001* + ID_PRODUCT_FROM_DATABASE=GESP v1.3 + +pci:v00001A2Bd00000002* + ID_PRODUCT_FROM_DATABASE=ECOMP v1.3 + +pci:v00001A2Bd00000005* + ID_PRODUCT_FROM_DATABASE=ETP v1.4 + +pci:v00001A2Bd0000000A* + ID_PRODUCT_FROM_DATABASE=ETP-104 v1.1 + +pci:v00001A2Bd0000000E* + ID_PRODUCT_FROM_DATABASE=DSLP-104 v1.1 + +pci:v00001A32* + ID_VENDOR_FROM_DATABASE=Quanta Microsystems, Inc + +pci:v00001A3B* + ID_VENDOR_FROM_DATABASE=AzureWave + +pci:v00001A3Bd00001112* + ID_PRODUCT_FROM_DATABASE=AR9285 Wireless Network Adapter (PCI-Express) + +pci:v00001A41* + ID_VENDOR_FROM_DATABASE=Tilera Corp. + +pci:v00001A41d00000001* + ID_PRODUCT_FROM_DATABASE=TILE64 processor + +pci:v00001A41d00000002* + ID_PRODUCT_FROM_DATABASE=TILEPro processor + +pci:v00001A41d00000200* + ID_PRODUCT_FROM_DATABASE=TILE-Gx36 processor + +pci:v00001A4A* + ID_VENDOR_FROM_DATABASE=SLAC National Accelerator Lab PPA-REG + +pci:v00001A4Ad00001000* + ID_PRODUCT_FROM_DATABASE=MCOR Power Supply Controller + +pci:v00001A4Ad00001010* + ID_PRODUCT_FROM_DATABASE=AMC EVR - Stockholm Timing Board + +pci:v00001A4Ad00002000* + ID_PRODUCT_FROM_DATABASE=PGPCard - 4 Lane + +pci:v00001A4Ad00002010* + ID_PRODUCT_FROM_DATABASE=PCI-Express EVR + +pci:v00001A51* + ID_VENDOR_FROM_DATABASE=Hectronic AB + +pci:v00001A55* + ID_VENDOR_FROM_DATABASE=Rohde & Schwarz DVS GmbH + +pci:v00001A55d00000010* + ID_PRODUCT_FROM_DATABASE=SDStationOEM + +pci:v00001A55d00000011* + ID_PRODUCT_FROM_DATABASE=SDStationOEM II + +pci:v00001A55d00000020* + ID_PRODUCT_FROM_DATABASE=Centaurus + +pci:v00001A55d00000021* + ID_PRODUCT_FROM_DATABASE=Centaurus II + +pci:v00001A55d00000022* + ID_PRODUCT_FROM_DATABASE=Centaurus II LT + +pci:v00001A55d00000030* + ID_PRODUCT_FROM_DATABASE=CLIPSTER-VPU 1.x (Hugo) + +pci:v00001A55d00000040* + ID_PRODUCT_FROM_DATABASE=Hydra Cinema (JPEG) + +pci:v00001A55d00000050* + ID_PRODUCT_FROM_DATABASE=CLIPSTER-VPU 2.x (DigiLab) + +pci:v00001A55d00000060* + ID_PRODUCT_FROM_DATABASE=CLIPSTER-DCI 2.x (HydraX) + +pci:v00001A55d00000061* + ID_PRODUCT_FROM_DATABASE=Atomix + +pci:v00001A55d00000062* + ID_PRODUCT_FROM_DATABASE=Atomix LT + +pci:v00001A55d00000063* + ID_PRODUCT_FROM_DATABASE=Atomix HDMI + +pci:v00001A55d00000064* + ID_PRODUCT_FROM_DATABASE=Atomix STAN + +pci:v00001A55d00000065* + ID_PRODUCT_FROM_DATABASE=Atomix HDMI STAN + +pci:v00001A55d00000070* + ID_PRODUCT_FROM_DATABASE=RED Rocket + +pci:v00001A55d00000090* + ID_PRODUCT_FROM_DATABASE=CinePlay + +pci:v00001A56* + ID_VENDOR_FROM_DATABASE=Bigfoot Networks, Inc. + +pci:v00001A57* + ID_VENDOR_FROM_DATABASE=Highly Reliable Systems + +pci:v00001A58* + ID_VENDOR_FROM_DATABASE=Razer USA Ltd. + +pci:v00001A5D* + ID_VENDOR_FROM_DATABASE=Celoxica + +pci:v00001A5E* + ID_VENDOR_FROM_DATABASE=Aprius Inc. + +pci:v00001A5F* + ID_VENDOR_FROM_DATABASE=System TALKS Inc. + +pci:v00001A68* + ID_VENDOR_FROM_DATABASE=VirtenSys Limited + +pci:v00001A71* + ID_VENDOR_FROM_DATABASE=XenSource, Inc. + +pci:v00001A73* + ID_VENDOR_FROM_DATABASE=Violin Memory, Inc + +pci:v00001A73d00000001* + ID_PRODUCT_FROM_DATABASE=Mozart [Memory Appliance 1010] + +pci:v00001A76* + ID_VENDOR_FROM_DATABASE=Wavesat + +pci:v00001A77* + ID_VENDOR_FROM_DATABASE=Lightfleet Corporation + +pci:v00001A78* + ID_VENDOR_FROM_DATABASE=Virident Systems Inc. + +pci:v00001A78d00000031* + ID_PRODUCT_FROM_DATABASE=Virident FlashMAX Drive + +pci:v00001A78d00000031sv00001A78sd00000034* + ID_PRODUCT_FROM_DATABASE=FlashMAX PCIe SSD [rev 3] + +pci:v00001A78d00000031sv00001A78sd00000037* + ID_PRODUCT_FROM_DATABASE=FlashMAX PCIe SSD [rev 3D] + +pci:v00001A78d00000031sv00001A78sd00000038* + ID_PRODUCT_FROM_DATABASE=FlashMAX PCIe SSD [rev 4] + +pci:v00001A78d00000031sv00001A78sd00000039* + ID_PRODUCT_FROM_DATABASE=FlashMAX PCIe SSD [rev 4D] + +pci:v00001A78d00000040* + ID_PRODUCT_FROM_DATABASE=FlashMAX II + +pci:v00001A84* + ID_VENDOR_FROM_DATABASE=Commex Technologies + +pci:v00001A84d00000001* + ID_PRODUCT_FROM_DATABASE=Vulcan SP HT6210 10-Gigabit Ethernet (rev 02) + +pci:v00001A88* + ID_VENDOR_FROM_DATABASE=MEN Mikro Elektronik + +pci:v00001A88d00004D45* + ID_PRODUCT_FROM_DATABASE=Multifunction IP core + +pci:v00001A8C* + ID_VENDOR_FROM_DATABASE=Verigy Pte. Ltd. + +pci:v00001A8Cd00001100* + ID_PRODUCT_FROM_DATABASE=E8001-66443 PCI Express CIC + +pci:v00001A8E* + ID_VENDOR_FROM_DATABASE=DRS Technologies + +pci:v00001A8Ed00002090* + ID_PRODUCT_FROM_DATABASE=Model 2090 PCI Express + +pci:v00001AA8* + ID_VENDOR_FROM_DATABASE=Ciprico, Inc. + +pci:v00001AA8d00000009* + ID_PRODUCT_FROM_DATABASE=RAIDCore Controller + +pci:v00001AA8d0000000A* + ID_PRODUCT_FROM_DATABASE=RAIDCore Controller + +pci:v00001AAE* + ID_VENDOR_FROM_DATABASE=Global Velocity, Inc. + +pci:v00001AB6* + ID_VENDOR_FROM_DATABASE=CalDigit, Inc. + +pci:v00001AB6d00006201* + ID_PRODUCT_FROM_DATABASE=RAID Card + +pci:v00001AB8* + ID_VENDOR_FROM_DATABASE=Parallels, Inc. + +pci:v00001AB8d00004000* + ID_PRODUCT_FROM_DATABASE=Virtual Machine Communication Interface + +pci:v00001AB8d00004005* + ID_PRODUCT_FROM_DATABASE=Accelerated Virtual Video Adapter + +pci:v00001AB8d00004006* + ID_PRODUCT_FROM_DATABASE=Memory Ballooning Controller + +pci:v00001AB9* + ID_VENDOR_FROM_DATABASE=Espia Srl + +pci:v00001ACC* + ID_VENDOR_FROM_DATABASE=Point of View B.V + +pci:v00001AD7* + ID_VENDOR_FROM_DATABASE=Spectracom Corporation + +pci:v00001AD7d00008000* + ID_PRODUCT_FROM_DATABASE=TSync-PCIe Time Code Processor + +pci:v00001AD7d00009100* + ID_PRODUCT_FROM_DATABASE=TPRO-PCI-66U Timecode Reader/Generator + +pci:v00001ADE* + ID_VENDOR_FROM_DATABASE=Spin Master Ltd. + +pci:v00001ADEd00001501* + ID_PRODUCT_FROM_DATABASE=Swipetech barcode scanner + +pci:v00001AE0* + ID_VENDOR_FROM_DATABASE=Google, Inc. + +pci:v00001AE7* + ID_VENDOR_FROM_DATABASE=First Wise Media GmbH + +pci:v00001AE7d00000520* + ID_PRODUCT_FROM_DATABASE=HFC-S PCI A [X-TENSIONS XC-520] + +pci:v00001AE8* + ID_VENDOR_FROM_DATABASE=Silicon Software GmbH + +pci:v00001AE8d00000A40* + ID_PRODUCT_FROM_DATABASE=microEnable IV-BASE x1 + +pci:v00001AE8d00000A41* + ID_PRODUCT_FROM_DATABASE=microEnable IV-FULL x1 + +pci:v00001AE8d00000A44* + ID_PRODUCT_FROM_DATABASE=microEnable IV-FULL x4 + +pci:v00001AE8d00000E44* + ID_PRODUCT_FROM_DATABASE=microEnable IV-GigE x4 + +pci:v00001AEC* + ID_VENDOR_FROM_DATABASE=Wolfson Microelectronics + +pci:v00001AED* + ID_VENDOR_FROM_DATABASE=Fusion-io + +pci:v00001AEDd00001003* + ID_PRODUCT_FROM_DATABASE=ioDimm3 (v1.2) + +pci:v00001AEDd00001005* + ID_PRODUCT_FROM_DATABASE=ioDimm3 + +pci:v00001AEDd00001005sv00001014sd000003C3* + ID_PRODUCT_FROM_DATABASE=High IOPS SSD PCIe Adapter + +pci:v00001AEDd00001005sv0000103Csd0000176F* + ID_PRODUCT_FROM_DATABASE=1.28TB MLC PCIe ioDrive Duo + +pci:v00001AEDd00001005sv0000103Csd00001770* + ID_PRODUCT_FROM_DATABASE=5.2TB MLC PCIe ioDrive Octal + +pci:v00001AEDd00001005sv0000103Csd0000178B* + ID_PRODUCT_FROM_DATABASE=160GB SLC PCIe ioDrive + +pci:v00001AEDd00001005sv0000103Csd0000178C* + ID_PRODUCT_FROM_DATABASE=320GB MLC PCIe ioDrive + +pci:v00001AEDd00001005sv0000103Csd0000178D* + ID_PRODUCT_FROM_DATABASE=320GB SLC PCIe ioDrive Duo + +pci:v00001AEDd00001005sv0000103Csd0000178E* + ID_PRODUCT_FROM_DATABASE=640GB MLC PCIe ioDrive Duo + +pci:v00001AEDd00001006* + ID_PRODUCT_FROM_DATABASE=ioXtreme + +pci:v00001AEDd00001007* + ID_PRODUCT_FROM_DATABASE=ioXtreme Pro + +pci:v00001AEDd00001008* + ID_PRODUCT_FROM_DATABASE=ioXtreme-2 + +pci:v00001AEDd00002001* + ID_PRODUCT_FROM_DATABASE=ioDrive2 + +pci:v00001AEE* + ID_VENDOR_FROM_DATABASE=Caustic Graphics Inc. + +pci:v00001AF4* + ID_VENDOR_FROM_DATABASE=Red Hat, Inc + +pci:v00001AF4d00001000* + ID_PRODUCT_FROM_DATABASE=Virtio network device + +pci:v00001AF4d00001001* + ID_PRODUCT_FROM_DATABASE=Virtio block device + +pci:v00001AF4d00001002* + ID_PRODUCT_FROM_DATABASE=Virtio memory balloon + +pci:v00001AF4d00001003* + ID_PRODUCT_FROM_DATABASE=Virtio console + +pci:v00001AF5* + ID_VENDOR_FROM_DATABASE=Netezza Corp. + +pci:v00001AFA* + ID_VENDOR_FROM_DATABASE=J & W Electronics Co., Ltd. + +pci:v00001B03* + ID_VENDOR_FROM_DATABASE=Magnum Semiconductor, Inc, + +pci:v00001B03d00006100* + ID_PRODUCT_FROM_DATABASE=DXT/DXTPro Multiformat Broadcast HD/SD Encoder/Decoder/Transcoder + +pci:v00001B08* + ID_VENDOR_FROM_DATABASE=MSC Vertriebs GmbH + +pci:v00001B13* + ID_VENDOR_FROM_DATABASE=Jaton Corp + +pci:v00001B1A* + ID_VENDOR_FROM_DATABASE=K&F Computing Research Co. + +pci:v00001B1Ad00000E70* + ID_PRODUCT_FROM_DATABASE=GRAPE + +pci:v00001B21* + ID_VENDOR_FROM_DATABASE=ASMedia Technology Inc. + +pci:v00001B21d00000611* + ID_PRODUCT_FROM_DATABASE=ASM1061 SATA IDE Controller + +pci:v00001B21d00000612* + ID_PRODUCT_FROM_DATABASE=ASM1062 Serial ATA Controller + +pci:v00001B21d00001042* + ID_PRODUCT_FROM_DATABASE=ASM1042 SuperSpeed USB Host Controller + +pci:v00001B21d00001080* + ID_PRODUCT_FROM_DATABASE=ASM1083/1085 PCIe to PCI Bridge + +pci:v00001B36* + ID_VENDOR_FROM_DATABASE=Red Hat, Inc. + +pci:v00001B37* + ID_VENDOR_FROM_DATABASE=Signal Processing Devices Sweden AB + +pci:v00001B37d00000014* + ID_PRODUCT_FROM_DATABASE=ADQ412 + +pci:v00001B3A* + ID_VENDOR_FROM_DATABASE=Westar Display Technologies + +pci:v00001B3Ad00007589* + ID_PRODUCT_FROM_DATABASE=HRED J2000 - JPEG 2000 Video Codec Device + +pci:v00001B3E* + ID_VENDOR_FROM_DATABASE=Teradata Corp. + +pci:v00001B3Ed00001FA8* + ID_PRODUCT_FROM_DATABASE=BYNET BIC2SE/X + +pci:v00001B3Ed00001FA8sv00001B3Esd000000A3* + ID_PRODUCT_FROM_DATABASE=BYNET BIC2SX + +pci:v00001B3Ed00001FA8sv00001B3Esd000000C3* + ID_PRODUCT_FROM_DATABASE=BYNET BIC2SE + +pci:v00001B40* + ID_VENDOR_FROM_DATABASE=Schooner Information Technology, Inc. + +pci:v00001B47* + ID_VENDOR_FROM_DATABASE=Numascale AS + +pci:v00001B47d00000601* + ID_PRODUCT_FROM_DATABASE=NumaChip N601 + +pci:v00001B47d00000602* + ID_PRODUCT_FROM_DATABASE=NumaChip N602 + +pci:v00001B4B* + ID_VENDOR_FROM_DATABASE=Marvell Technology Group Ltd. + +pci:v00001B4Bd00000640* + ID_PRODUCT_FROM_DATABASE=88SE9128 SATA III 6Gb/s RAID Controller + +pci:v00001B4Bd00009120* + ID_PRODUCT_FROM_DATABASE=88SE9120 SATA 6Gb/s Controller + +pci:v00001B4Bd00009123* + ID_PRODUCT_FROM_DATABASE=88SE9123 PCIe SATA 6.0 Gb/s controller + +pci:v00001B4Bd00009125* + ID_PRODUCT_FROM_DATABASE=88SE9125 PCIe SATA 6.0 Gb/s controller + +pci:v00001B4Bd00009128* + ID_PRODUCT_FROM_DATABASE=88SE9128 PCIe SATA 6 Gb/s RAID controller + +pci:v00001B4Bd00009130* + ID_PRODUCT_FROM_DATABASE=88SE9128 PCIe SATA 6 Gb/s RAID controller with HyperDuo + +pci:v00001B4Bd00009130sv00001043sd00008438* + ID_PRODUCT_FROM_DATABASE=P8P67 Deluxe Motherboard + +pci:v00001B4Bd00009172* + ID_PRODUCT_FROM_DATABASE=88SE9172 SATA 6Gb/s Controller + +pci:v00001B4Bd0000917A* + ID_PRODUCT_FROM_DATABASE=88SE9172 SATA III 6Gb/s RAID Controller + +pci:v00001B4Bd00009192* + ID_PRODUCT_FROM_DATABASE=88SE9172 SATA III 6Gb/s RAID Controller + +pci:v00001B4Bd000091A0* + ID_PRODUCT_FROM_DATABASE=88SE91A0 SATA 6Gb/s Controller + +pci:v00001B4Bd000091A4* + ID_PRODUCT_FROM_DATABASE=88SE9128 IDE Controller + +pci:v00001B4Bd00009230* + ID_PRODUCT_FROM_DATABASE=88SE9230 PCIe SATA 6Gb/s Controller + +pci:v00001B4Bd00009480* + ID_PRODUCT_FROM_DATABASE=88SE9480 SAS/SATA 6Gb/s RAID controller + +pci:v00001B55* + ID_VENDOR_FROM_DATABASE=NetUP Inc. + +pci:v00001B55d00002A2C* + ID_PRODUCT_FROM_DATABASE=Dual DVB-S2-CI card + +pci:v00001B55d0000E2E4* + ID_PRODUCT_FROM_DATABASE=Dual DVB-T/C-CI RF card + +pci:v00001B55d0000E5F4* + ID_PRODUCT_FROM_DATABASE=MPEG2 and H264 Encoder-Transcoder + +pci:v00001B55d0000F1C4* + ID_PRODUCT_FROM_DATABASE=Dual ASI-RX/TX-CI card + +pci:v00001B6F* + ID_VENDOR_FROM_DATABASE=Etron Technology, Inc. + +pci:v00001B6Fd00007023* + ID_PRODUCT_FROM_DATABASE=EJ168 USB 3.0 Host Controller + +pci:v00001B6Fd00007052* + ID_PRODUCT_FROM_DATABASE=EJ188/EJ198 USB 3.0 Host Controller + +pci:v00001B73* + ID_VENDOR_FROM_DATABASE=Fresco Logic + +pci:v00001B73d00001000* + ID_PRODUCT_FROM_DATABASE=FL1000G USB 3.0 Host Controller + +pci:v00001B73d00001000sv00001D5Csd00001000* + ID_PRODUCT_FROM_DATABASE=Anker USB 3.0 Express Card + +pci:v00001B73d00001009* + ID_PRODUCT_FROM_DATABASE=FL1009 USB 3.0 Host Controller + +pci:v00001B74* + ID_VENDOR_FROM_DATABASE=OpenVox Communication Co. Ltd. + +pci:v00001B74d00000115* + ID_PRODUCT_FROM_DATABASE=D115P/D115E Single-port E1/T1 card + +pci:v00001B74d0000D130* + ID_PRODUCT_FROM_DATABASE=D130P/D130E Single-port E1/T1 card (3rd GEN) + +pci:v00001B74d0000D210* + ID_PRODUCT_FROM_DATABASE=D210P/D210E Dual-port E1/T1 card(2nd generation) + +pci:v00001B74d0000D230* + ID_PRODUCT_FROM_DATABASE=D230 Dual-port E1/T1 card (2nd generation) + +pci:v00001B74d0000D410* + ID_PRODUCT_FROM_DATABASE=D410/430 Quad-port E1/T1 card + +pci:v00001B74d0000D430* + ID_PRODUCT_FROM_DATABASE=D410/430 Quad-port E1/T1 card + +pci:v00001B85* + ID_VENDOR_FROM_DATABASE=OCZ Technology Group, Inc. + +pci:v00001B85d00001041* + ID_PRODUCT_FROM_DATABASE=RevoDrive 3 X2 PCI-Express SSD 240 GB (Marvell Controller) + +pci:v00001B96* + ID_VENDOR_FROM_DATABASE=Western Digital + +pci:v00001B9A* + ID_VENDOR_FROM_DATABASE=XAVi Technologies Corp. + +pci:v00001BAD* + ID_VENDOR_FROM_DATABASE=ReFLEX CES + +pci:v00001BB0* + ID_VENDOR_FROM_DATABASE=SimpliVity Corporation + +pci:v00001BB0d00000002* + ID_PRODUCT_FROM_DATABASE=OmniCube Accelerator OA-3000 + +pci:v00001BB3* + ID_VENDOR_FROM_DATABASE=Bluecherry + +pci:v00001BB3d00004304* + ID_PRODUCT_FROM_DATABASE=BC-04120A MPEG4 4 port video encoder / decoder + +pci:v00001BB3d00004309* + ID_PRODUCT_FROM_DATABASE=BC-08240A MPEG4 4 port video encoder / decoder + +pci:v00001BB3d00004310* + ID_PRODUCT_FROM_DATABASE=BC-16480A MPEG4 16 port video encoder / decoder + +pci:v00001BB3d00004E04* + ID_PRODUCT_FROM_DATABASE=BC-04120A 4 port MPEG4 video encoder / decoder + +pci:v00001BB3d00004E09* + ID_PRODUCT_FROM_DATABASE=BC-08240A 8 port MPEG4 video encoder / decoder + +pci:v00001BB3d00004E10* + ID_PRODUCT_FROM_DATABASE=BC-16480A 16 port MPEG4 video encoder / decoder + +pci:v00001BB3d00005304* + ID_PRODUCT_FROM_DATABASE=BC-H04120A 4 port H.264 video and audio encoder / decoder + +pci:v00001BB3d00005308* + ID_PRODUCT_FROM_DATABASE=BC-H08240A 8 port H.264 video and audio encoder / decoder + +pci:v00001BB3d00005310* + ID_PRODUCT_FROM_DATABASE=BC-H16480A 16 port H.264 video and audio encoder / decoder + +pci:v00001BB5* + ID_VENDOR_FROM_DATABASE=Quantenna Communications, Inc. + +pci:v00001BBF* + ID_VENDOR_FROM_DATABASE=Maxeler Technologies Ltd. + +pci:v00001BBFd00000003* + ID_PRODUCT_FROM_DATABASE=MAX3 + +pci:v00001BBFd00000004* + ID_PRODUCT_FROM_DATABASE=MAX4 + +pci:v00001BF4* + ID_VENDOR_FROM_DATABASE=VTI Instruments Corporation + +pci:v00001C1C* + ID_VENDOR_FROM_DATABASE=Symphony + +pci:v00001C1Cd00000001* + ID_PRODUCT_FROM_DATABASE=82C101 + +pci:v00001C2C* + ID_VENDOR_FROM_DATABASE=Fiberblaze + +pci:v00001C32* + ID_VENDOR_FROM_DATABASE=Highland Technology, Inc. + +pci:v00001C3B* + ID_VENDOR_FROM_DATABASE=Accensus, LLC + +pci:v00001C3Bd00000200* + ID_PRODUCT_FROM_DATABASE=Telas2 + +pci:v00001C44* + ID_VENDOR_FROM_DATABASE=Enmotus Inc + +pci:v00001C44d00008000* + ID_PRODUCT_FROM_DATABASE=8000 Storage IO Controller + +pci:v00001C7F* + ID_VENDOR_FROM_DATABASE=Elektrobit Austria GmbH + +pci:v00001C7Fd00005100* + ID_PRODUCT_FROM_DATABASE=EB5100 + +pci:v00001C8A* + ID_VENDOR_FROM_DATABASE=TSF5 Corporation + +pci:v00001D44* + ID_VENDOR_FROM_DATABASE=DPT + +pci:v00001D44d0000A400* + ID_PRODUCT_FROM_DATABASE=PM2x24/PM3224 + +pci:v00001D5C* + ID_VENDOR_FROM_DATABASE=Fantasia Trading LLC + +pci:v00001DE1* + ID_VENDOR_FROM_DATABASE=Tekram Technology Co.,Ltd. + +pci:v00001DE1d00000391* + ID_PRODUCT_FROM_DATABASE=TRM-S1040 + +pci:v00001DE1d00002020* + ID_PRODUCT_FROM_DATABASE=DC-390 + +pci:v00001DE1d0000690C* + ID_PRODUCT_FROM_DATABASE=690c + +pci:v00001DE1d0000DC29* + ID_PRODUCT_FROM_DATABASE=DC290 + +pci:v00001FC0* + ID_VENDOR_FROM_DATABASE=Ascom (Finland) Oy + +pci:v00001FC0d00000300* + ID_PRODUCT_FROM_DATABASE=E2200 Dual E1/Rawpipe Card + +pci:v00001FC0d00000301* + ID_PRODUCT_FROM_DATABASE=C5400 SHDSL/E1 Card + +pci:v00001FC1* + ID_VENDOR_FROM_DATABASE=QLogic, Corp. + +pci:v00001FC1d0000000D* + ID_PRODUCT_FROM_DATABASE=IBA6110 InfiniBand HCA + +pci:v00001FC1d00000010* + ID_PRODUCT_FROM_DATABASE=IBA6120 InfiniBand HCA + +pci:v00001FC9* + ID_VENDOR_FROM_DATABASE=Tehuti Networks Ltd. + +pci:v00001FC9d00003009* + ID_PRODUCT_FROM_DATABASE=10-Giga TOE SmartNIC + +pci:v00001FC9d00003010* + ID_PRODUCT_FROM_DATABASE=10-Giga TOE SmartNIC + +pci:v00001FC9d00003010sv00000000sd00003002* + ID_PRODUCT_FROM_DATABASE=10-Giga TOE Single Port XFP SmartNIC + +pci:v00001FC9d00003010sv00000000sd00003004* + ID_PRODUCT_FROM_DATABASE=10-Giga TOE Single Port SFP+ SmartNIC + +pci:v00001FC9d00003010sv00000000sd00003008* + ID_PRODUCT_FROM_DATABASE=10-Giga TOE Single Port CX4 SmartNIC + +pci:v00001FC9d00003014* + ID_PRODUCT_FROM_DATABASE=10-Giga TOE SmartNIC 2-Port + +pci:v00001FC9d00003014sv00000000sd00003003* + ID_PRODUCT_FROM_DATABASE=10-Giga TOE Dual Port XFP Low Profile SmartNIC + +pci:v00001FC9d00003014sv00000000sd00003005* + ID_PRODUCT_FROM_DATABASE=10-Giga TOE Dual Port SFP+ Low Profile SmartNIC + +pci:v00001FC9d00003014sv00000000sd00003014* + ID_PRODUCT_FROM_DATABASE=10-Giga TOE Dual Port CX4 Low Profile SmartNIC + +pci:v00001FC9d00003110* + ID_PRODUCT_FROM_DATABASE=10-Giga TOE Single Port SmartNIC + +pci:v00001FC9d00003110sv00000000sd00003004* + ID_PRODUCT_FROM_DATABASE=10-Giga TOE Single Port SFP+ SmartNIC + +pci:v00001FC9d00003114* + ID_PRODUCT_FROM_DATABASE=10-Giga TOE Dual Port Low Profile SmartNIC + +pci:v00001FC9d00003114sv00000000sd00003005* + ID_PRODUCT_FROM_DATABASE=10-Giga TOE Dual Port SFP+ Low Profile SmartNIC + +pci:v00001FC9d00003114sv00000000sd00003011* + ID_PRODUCT_FROM_DATABASE=10-Giga TOE Dual Port SFP+/CX4 Low Profile SmartNIC + +pci:v00001FC9d00003114sv00000000sd00003012* + ID_PRODUCT_FROM_DATABASE=10-Giga TOE Dual Port CX4/SFP+ Low Profile SmartNIC + +pci:v00001FC9d00003114sv00000000sd00003014* + ID_PRODUCT_FROM_DATABASE=10-Giga TOE Dual Port CX4 Low Profile SmartNIC + +pci:v00001FC9d00003310* + ID_PRODUCT_FROM_DATABASE=10-Giga TOE SFP+ Single Port SmartNIC + +pci:v00001FC9d00003310sv00000000sd00003004* + ID_PRODUCT_FROM_DATABASE=10-Giga TOE Single Port SFP+ SmartNIC + +pci:v00001FC9d00003314* + ID_PRODUCT_FROM_DATABASE=10-Giga TOE Dual Port Low Profile SmartNIC + +pci:v00001FC9d00003314sv00000000sd00003005* + ID_PRODUCT_FROM_DATABASE=10-Giga TOE Dual Port SFP+ Low Profile SmartNIC + +pci:v00001FC9d00003314sv00000000sd00003011* + ID_PRODUCT_FROM_DATABASE=10-Giga TOE Dual Port SFP+/CX4 Low Profile SmartNIC + +pci:v00001FC9d00003314sv00000000sd00003012* + ID_PRODUCT_FROM_DATABASE=10-Giga TOE Dual Port CX4/SFP+ Low Profile SmartNIC + +pci:v00001FC9d00003314sv00000000sd00003014* + ID_PRODUCT_FROM_DATABASE=10-Giga TOE Dual Port CX4 Low Profile SmartNIC + +pci:v00001FCE* + ID_VENDOR_FROM_DATABASE=Cognio Inc. + +pci:v00001FCEd00000001* + ID_PRODUCT_FROM_DATABASE=Spectrum Analyzer PC Card (SAgE) + +pci:v00001FD4* + ID_VENDOR_FROM_DATABASE=SUNIX Co., Ltd. + +pci:v00001FD4d00000001* + ID_PRODUCT_FROM_DATABASE=Matrix multiport serial adapter + +pci:v00001FD4d00001999* + ID_PRODUCT_FROM_DATABASE=Multiport serial controller + +pci:v00002000* + ID_VENDOR_FROM_DATABASE=Smart Link Ltd. + +pci:v00002000d00002800* + ID_PRODUCT_FROM_DATABASE=SmartPCI2800 V.92 PCI Soft DFT + +pci:v00002001* + ID_VENDOR_FROM_DATABASE=Temporal Research Ltd + +pci:v00002003* + ID_VENDOR_FROM_DATABASE=Smart Link Ltd. + +pci:v00002003d00008800* + ID_PRODUCT_FROM_DATABASE=LM-I56N + +pci:v00002004* + ID_VENDOR_FROM_DATABASE=Smart Link Ltd. + +pci:v000020F4* + ID_VENDOR_FROM_DATABASE=TRENDnet + +pci:v00002116* + ID_VENDOR_FROM_DATABASE=ZyDAS Technology Corp. + +pci:v000021C3* + ID_VENDOR_FROM_DATABASE=21st Century Computer Corp. + +pci:v000022B8* + ID_VENDOR_FROM_DATABASE=Motorola, Inc. + +pci:v00002304* + ID_VENDOR_FROM_DATABASE=Colorgraphic Communications Corp. + +pci:v00002348* + ID_VENDOR_FROM_DATABASE=Racore + +pci:v00002348d00002010* + ID_PRODUCT_FROM_DATABASE=8142 100VG/AnyLAN + +pci:v00002646* + ID_VENDOR_FROM_DATABASE=Kingston Technologies + +pci:v0000270B* + ID_VENDOR_FROM_DATABASE=Xantel Corporation + +pci:v0000270F* + ID_VENDOR_FROM_DATABASE=Chaintech Computer Co. Ltd + +pci:v00002711* + ID_VENDOR_FROM_DATABASE=AVID Technology Inc. + +pci:v000029B4* + ID_VENDOR_FROM_DATABASE=82q35 Express MEI Controller + +pci:v00002A15* + ID_VENDOR_FROM_DATABASE=3D Vision(???) + +pci:v00003000* + ID_VENDOR_FROM_DATABASE=Hansol Electronics Inc. + +pci:v00003020* + ID_VENDOR_FROM_DATABASE=LSI SAS2 9211-8i + +pci:v00003080* + ID_VENDOR_FROM_DATABASE=LSI SAS2 9200-8e + +pci:v00003142* + ID_VENDOR_FROM_DATABASE=Post Impression Systems. + +pci:v00003388* + ID_VENDOR_FROM_DATABASE=Hint Corp + +pci:v00003388d00000013* + ID_PRODUCT_FROM_DATABASE=HiNT HC4 PCI to ISDN bridge, Multimedia audio controller + +pci:v00003388d00000014* + ID_PRODUCT_FROM_DATABASE=HiNT HC4 PCI to ISDN bridge, Network controller + +pci:v00003388d00000020* + ID_PRODUCT_FROM_DATABASE=HB6 Universal PCI-PCI bridge (transparent mode) + +pci:v00003388d00000021* + ID_PRODUCT_FROM_DATABASE=HB6 Universal PCI-PCI bridge (non-transparent mode) + +pci:v00003388d00000021sv00001775sd0000C200* + ID_PRODUCT_FROM_DATABASE=C2K CompactPCI interface bridge + +pci:v00003388d00000021sv00001775sd0000CE90* + ID_PRODUCT_FROM_DATABASE=CE9 + +pci:v00003388d00000021sv00004C53sd00001050* + ID_PRODUCT_FROM_DATABASE=CT7 mainboard + +pci:v00003388d00000021sv00004C53sd00001080* + ID_PRODUCT_FROM_DATABASE=CT8 mainboard + +pci:v00003388d00000021sv00004C53sd00001090* + ID_PRODUCT_FROM_DATABASE=Cx9 mainboard + +pci:v00003388d00000021sv00004C53sd000010A0* + ID_PRODUCT_FROM_DATABASE=CA3/CR3 mainboard + +pci:v00003388d00000021sv00004C53sd00003010* + ID_PRODUCT_FROM_DATABASE=PPCI mezzanine (32-bit PMC) + +pci:v00003388d00000021sv00004C53sd00003011* + ID_PRODUCT_FROM_DATABASE=PPCI mezzanine (64-bit PMC) + +pci:v00003388d00000021sv00004C53sd00004000* + ID_PRODUCT_FROM_DATABASE=PMCCARR1 carrier board + +pci:v00003388d00000022* + ID_PRODUCT_FROM_DATABASE=HiNT HB4 PCI-PCI Bridge (PCI6150) + +pci:v00003388d00000026* + ID_PRODUCT_FROM_DATABASE=HB2 PCI-PCI Bridge + +pci:v00003388d00001018* + ID_PRODUCT_FROM_DATABASE=Audiotrak INCA88 + +pci:v00003388d00001019* + ID_PRODUCT_FROM_DATABASE=Miditrak 2120 + +pci:v00003388d0000101A* + ID_PRODUCT_FROM_DATABASE=E.Band [AudioTrak Inca88] + +pci:v00003388d0000101B* + ID_PRODUCT_FROM_DATABASE=E.Band [AudioTrak Inca88] + +pci:v00003388d00008011* + ID_PRODUCT_FROM_DATABASE=VXPro II Chipset + +pci:v00003388d00008011sv00003388sd00008011* + ID_PRODUCT_FROM_DATABASE=VXPro II Chipset CPU to PCI Bridge + +pci:v00003388d00008012* + ID_PRODUCT_FROM_DATABASE=VXPro II Chipset + +pci:v00003388d00008012sv00003388sd00008012* + ID_PRODUCT_FROM_DATABASE=VXPro II Chipset PCI to ISA Bridge + +pci:v00003388d00008013* + ID_PRODUCT_FROM_DATABASE=VXPro II IDE + +pci:v00003388d00008013sv00003388sd00008013* + ID_PRODUCT_FROM_DATABASE=VXPro II Chipset EIDE Controller + +pci:v00003388d0000A103* + ID_PRODUCT_FROM_DATABASE=Blackmagic Design DeckLink HD Pro + +pci:v00003411* + ID_VENDOR_FROM_DATABASE=Quantum Designs (H.K.) Inc + +pci:v00003442* + ID_VENDOR_FROM_DATABASE=Bihl+Wiedemann GmbH + +pci:v00003442d00001783* + ID_PRODUCT_FROM_DATABASE=AS-i 3.0 cPCI Master + +pci:v00003442d00001922* + ID_PRODUCT_FROM_DATABASE=AS-i 3.0 PCI Master + +pci:v00003475* + ID_VENDOR_FROM_DATABASE=Arastra Inc. + +pci:v00003513* + ID_VENDOR_FROM_DATABASE=ARCOM Control Systems Ltd + +pci:v000037D9* + ID_VENDOR_FROM_DATABASE=ITD Firm ltd. + +pci:v000037D9d00001138* + ID_PRODUCT_FROM_DATABASE=SCHD-PH-8 Phase detector + +pci:v00003842* + ID_VENDOR_FROM_DATABASE=eVga.com. Corp. + +pci:v000038EF* + ID_VENDOR_FROM_DATABASE=4Links + +pci:v00003D3D* + ID_VENDOR_FROM_DATABASE=3DLabs + +pci:v00003D3Dd00000001* + ID_PRODUCT_FROM_DATABASE=GLINT 300SX + +pci:v00003D3Dd00000002* + ID_PRODUCT_FROM_DATABASE=GLINT 500TX + +pci:v00003D3Dd00000002sv00000000sd00000000* + ID_PRODUCT_FROM_DATABASE=GLoria L + +pci:v00003D3Dd00000003* + ID_PRODUCT_FROM_DATABASE=GLINT Delta + +pci:v00003D3Dd00000003sv00000000sd00000000* + ID_PRODUCT_FROM_DATABASE=GLoria XL + +pci:v00003D3Dd00000004* + ID_PRODUCT_FROM_DATABASE=Permedia + +pci:v00003D3Dd00000005* + ID_PRODUCT_FROM_DATABASE=Permedia + +pci:v00003D3Dd00000006* + ID_PRODUCT_FROM_DATABASE=GLINT MX + +pci:v00003D3Dd00000006sv00000000sd00000000* + ID_PRODUCT_FROM_DATABASE=GLoria XL + +pci:v00003D3Dd00000006sv00001048sd00000A42* + ID_PRODUCT_FROM_DATABASE=GLoria XXL + +pci:v00003D3Dd00000007* + ID_PRODUCT_FROM_DATABASE=3D Extreme + +pci:v00003D3Dd00000008* + ID_PRODUCT_FROM_DATABASE=GLINT Gamma G1 + +pci:v00003D3Dd00000008sv00001048sd00000A42* + ID_PRODUCT_FROM_DATABASE=GLoria XXL + +pci:v00003D3Dd00000009* + ID_PRODUCT_FROM_DATABASE=Permedia II 2D+3D + +pci:v00003D3Dd00000009sv00001040sd00000011* + ID_PRODUCT_FROM_DATABASE=AccelStar II + +pci:v00003D3Dd00000009sv00001048sd00000A42* + ID_PRODUCT_FROM_DATABASE=GLoria XXL + +pci:v00003D3Dd00000009sv000013E9sd00001000* + ID_PRODUCT_FROM_DATABASE=6221L-4U + +pci:v00003D3Dd00000009sv00003D3Dsd00000100* + ID_PRODUCT_FROM_DATABASE=AccelStar II 3D Accelerator + +pci:v00003D3Dd00000009sv00003D3Dsd00000111* + ID_PRODUCT_FROM_DATABASE=Permedia 3:16 + +pci:v00003D3Dd00000009sv00003D3Dsd00000114* + ID_PRODUCT_FROM_DATABASE=Santa Ana + +pci:v00003D3Dd00000009sv00003D3Dsd00000116* + ID_PRODUCT_FROM_DATABASE=Oxygen GVX1 + +pci:v00003D3Dd00000009sv00003D3Dsd00000119* + ID_PRODUCT_FROM_DATABASE=Scirocco + +pci:v00003D3Dd00000009sv00003D3Dsd00000120* + ID_PRODUCT_FROM_DATABASE=Santa Ana PCL + +pci:v00003D3Dd00000009sv00003D3Dsd00000125* + ID_PRODUCT_FROM_DATABASE=Oxygen VX1 + +pci:v00003D3Dd00000009sv00003D3Dsd00000127* + ID_PRODUCT_FROM_DATABASE=Permedia3 Create! + +pci:v00003D3Dd0000000A* + ID_PRODUCT_FROM_DATABASE=GLINT R3 + +pci:v00003D3Dd0000000Asv00003D3Dsd00000121* + ID_PRODUCT_FROM_DATABASE=Oxygen VX1 + +pci:v00003D3Dd0000000C* + ID_PRODUCT_FROM_DATABASE=GLINT R3 [Oxygen VX1] + +pci:v00003D3Dd0000000Csv00003D3Dsd00000144* + ID_PRODUCT_FROM_DATABASE=Oxygen VX1-4X AGP [Permedia 4] + +pci:v00003D3Dd0000000D* + ID_PRODUCT_FROM_DATABASE=GLint R4 rev A + +pci:v00003D3Dd0000000E* + ID_PRODUCT_FROM_DATABASE=GLINT Gamma G2 + +pci:v00003D3Dd00000011* + ID_PRODUCT_FROM_DATABASE=GLint R4 rev B + +pci:v00003D3Dd00000012* + ID_PRODUCT_FROM_DATABASE=GLint R5 rev A + +pci:v00003D3Dd00000013* + ID_PRODUCT_FROM_DATABASE=GLint R5 rev B + +pci:v00003D3Dd00000020* + ID_PRODUCT_FROM_DATABASE=VP10 visual processor + +pci:v00003D3Dd00000022* + ID_PRODUCT_FROM_DATABASE=VP10 visual processor + +pci:v00003D3Dd00000024* + ID_PRODUCT_FROM_DATABASE=VP9 visual processor + +pci:v00003D3Dd0000002C* + ID_PRODUCT_FROM_DATABASE=Wildcat Realizm 100/200 + +pci:v00003D3Dd00000030* + ID_PRODUCT_FROM_DATABASE=Wildcat Realizm 800 + +pci:v00003D3Dd00000032* + ID_PRODUCT_FROM_DATABASE=Wildcat Realizm 500 + +pci:v00003D3Dd00000100* + ID_PRODUCT_FROM_DATABASE=Permedia II 2D+3D + +pci:v00003D3Dd000007A1* + ID_PRODUCT_FROM_DATABASE=Wildcat III 6210 + +pci:v00003D3Dd000007A2* + ID_PRODUCT_FROM_DATABASE=Sun XVR-500 Graphics Accelerator + +pci:v00003D3Dd000007A3* + ID_PRODUCT_FROM_DATABASE=Wildcat IV 7210 + +pci:v00003D3Dd00001004* + ID_PRODUCT_FROM_DATABASE=Permedia + +pci:v00003D3Dd00003D04* + ID_PRODUCT_FROM_DATABASE=Permedia + +pci:v00003D3Dd0000FFFF* + ID_PRODUCT_FROM_DATABASE=Glint VGA + +pci:v00004005* + ID_VENDOR_FROM_DATABASE=Avance Logic Inc. + +pci:v00004005d00000300* + ID_PRODUCT_FROM_DATABASE=ALS300 PCI Audio Device + +pci:v00004005d00000308* + ID_PRODUCT_FROM_DATABASE=ALS300+ PCI Audio Device + +pci:v00004005d00000309* + ID_PRODUCT_FROM_DATABASE=PCI Input Controller + +pci:v00004005d00001064* + ID_PRODUCT_FROM_DATABASE=ALG-2064 + +pci:v00004005d00002064* + ID_PRODUCT_FROM_DATABASE=ALG-2064i + +pci:v00004005d00002128* + ID_PRODUCT_FROM_DATABASE=ALG-2364A GUI Accelerator + +pci:v00004005d00002301* + ID_PRODUCT_FROM_DATABASE=ALG-2301 + +pci:v00004005d00002302* + ID_PRODUCT_FROM_DATABASE=ALG-2302 + +pci:v00004005d00002303* + ID_PRODUCT_FROM_DATABASE=AVG-2302 GUI Accelerator + +pci:v00004005d00002364* + ID_PRODUCT_FROM_DATABASE=ALG-2364A + +pci:v00004005d00002464* + ID_PRODUCT_FROM_DATABASE=ALG-2464 + +pci:v00004005d00002501* + ID_PRODUCT_FROM_DATABASE=ALG-2564A/25128A + +pci:v00004005d00004000* + ID_PRODUCT_FROM_DATABASE=ALS4000 Audio Chipset + +pci:v00004005d00004000sv00004005sd00004000* + ID_PRODUCT_FROM_DATABASE=ALS4000 Audio Chipset + +pci:v00004005d00004710* + ID_PRODUCT_FROM_DATABASE=ALC200/200P + +pci:v00004033* + ID_VENDOR_FROM_DATABASE=Addtron Technology Co, Inc. + +pci:v00004033d00001360* + ID_PRODUCT_FROM_DATABASE=RTL8139 Ethernet + +pci:v00004040* + ID_VENDOR_FROM_DATABASE=NetXen Incorporated + +pci:v00004040d00000001* + ID_PRODUCT_FROM_DATABASE=NXB-10GXSR 10-Gigabit Ethernet PCIe Adapter with SR-XFP optical interface + +pci:v00004040d00000001sv0000103Csd00007047* + ID_PRODUCT_FROM_DATABASE=NC510F PCIe 10-Gigabit Server Adapter + +pci:v00004040d00000002* + ID_PRODUCT_FROM_DATABASE=NXB-10GCX4 10-Gigabit Ethernet PCIe Adapter with CX4 copper interface + +pci:v00004040d00000002sv0000103Csd00007048* + ID_PRODUCT_FROM_DATABASE=NC510c PCIe 10-Gigabit Server Adapter + +pci:v00004040d00000003* + ID_PRODUCT_FROM_DATABASE=NXB-4GCU Quad Gigabit Ethernet PCIe Adapter with 1000-BASE-T interface + +pci:v00004040d00000004* + ID_PRODUCT_FROM_DATABASE=BladeCenter-H 10-Gigabit Ethernet High Speed Daughter Card + +pci:v00004040d00000005* + ID_PRODUCT_FROM_DATABASE=NetXen Dual Port 10GbE Multifunction Adapter for c-Class + +pci:v00004040d00000005sv0000103Csd0000170E* + ID_PRODUCT_FROM_DATABASE=NC512m Dual Port 10GbE Multifunction BL-C Adapter + +pci:v00004040d00000024* + ID_PRODUCT_FROM_DATABASE=XG Mgmt + +pci:v00004040d00000025* + ID_PRODUCT_FROM_DATABASE=XG Mgmt + +pci:v00004040d00000100* + ID_PRODUCT_FROM_DATABASE=NX3031 Multifunction 1/10-Gigabit Server Adapter + +pci:v00004040d00000100sv0000103Csd0000171B* + ID_PRODUCT_FROM_DATABASE=NC522m Dual Port 10GbE Multifunction BL-c Adapter + +pci:v00004040d00000100sv0000103Csd00001740* + ID_PRODUCT_FROM_DATABASE=NC375T PCI Express Quad Port Gigabit Server Adapter + +pci:v00004040d00000100sv0000103Csd00003251* + ID_PRODUCT_FROM_DATABASE=NC375i 1G w/NC524SFP 10G Module + +pci:v00004040d00000100sv0000103Csd0000705A* + ID_PRODUCT_FROM_DATABASE=NC375i Integrated Quad Port Multifunction Gigabit Server Adapter + +pci:v00004040d00000100sv0000103Csd0000705B* + ID_PRODUCT_FROM_DATABASE=NC522SFP Dual Port 10GbE Server Adapter + +pci:v00004040d00000100sv0000152Dsd0000896B* + ID_PRODUCT_FROM_DATABASE=TG20 Dual Port 10GbE Server/Storage Adapter + +pci:v00004040d00000100sv00004040sd00000124* + ID_PRODUCT_FROM_DATABASE=NX3031 Quad Port Gigabit Server Adapter + +pci:v00004040d00000100sv00004040sd00000126* + ID_PRODUCT_FROM_DATABASE=Dual Port SFP+ 10GbE Server Adapter + +pci:v00004143* + ID_VENDOR_FROM_DATABASE=Digital Equipment Corp + +pci:v00004144* + ID_VENDOR_FROM_DATABASE=Alpha Data + +pci:v00004144d00000044* + ID_PRODUCT_FROM_DATABASE=ADM-XRCIIPro + +pci:v00004150* + ID_VENDOR_FROM_DATABASE=ONA Electroerosion + +pci:v00004150d00000001* + ID_PRODUCT_FROM_DATABASE=PCI32TLITE FILSTRUP1 PCI to VME Bridge Controller + +pci:v00004150d00000006* + ID_PRODUCT_FROM_DATABASE=PCI32TLITE UART 16550 Opencores + +pci:v00004150d00000007* + ID_PRODUCT_FROM_DATABASE=PCI32TLITE CAN Controller Opencores + +pci:v0000415A* + ID_VENDOR_FROM_DATABASE=Auzentech, Inc. + +pci:v0000416C* + ID_VENDOR_FROM_DATABASE=Aladdin Knowledge Systems + +pci:v0000416Cd00000100* + ID_PRODUCT_FROM_DATABASE=AladdinCARD + +pci:v0000416Cd00000200* + ID_PRODUCT_FROM_DATABASE=CPC + +pci:v00004321* + ID_VENDOR_FROM_DATABASE=Tata Power Strategic Electronics Division + +pci:v0000434E* + ID_VENDOR_FROM_DATABASE=CAST Navigation LLC + +pci:v00004444* + ID_VENDOR_FROM_DATABASE=Internext Compression Inc + +pci:v00004444d00000016* + ID_PRODUCT_FROM_DATABASE=iTVC16 (CX23416) Video Decoder + +pci:v00004444d00000016sv00000070sd00000003* + ID_PRODUCT_FROM_DATABASE=WinTV PVR 250 + +pci:v00004444d00000016sv00000070sd00000009* + ID_PRODUCT_FROM_DATABASE=WinTV PVR 150 + +pci:v00004444d00000016sv00000070sd00000801* + ID_PRODUCT_FROM_DATABASE=WinTV PVR 150 + +pci:v00004444d00000016sv00000070sd00000807* + ID_PRODUCT_FROM_DATABASE=WinTV PVR 150 + +pci:v00004444d00000016sv00000070sd00004001* + ID_PRODUCT_FROM_DATABASE=WinTV PVR 250 + +pci:v00004444d00000016sv00000070sd00004009* + ID_PRODUCT_FROM_DATABASE=WinTV PVR 250 + +pci:v00004444d00000016sv00000070sd00004801* + ID_PRODUCT_FROM_DATABASE=WinTV PVR 250 + +pci:v00004444d00000016sv00000070sd00004803* + ID_PRODUCT_FROM_DATABASE=WinTV PVR 250 + +pci:v00004444d00000016sv00000070sd00008003* + ID_PRODUCT_FROM_DATABASE=WinTV PVR 150 + +pci:v00004444d00000016sv00000070sd00008801* + ID_PRODUCT_FROM_DATABASE=WinTV PVR 150 + +pci:v00004444d00000016sv00000070sd0000C801* + ID_PRODUCT_FROM_DATABASE=WinTV PVR 150 + +pci:v00004444d00000016sv00000070sd0000E807* + ID_PRODUCT_FROM_DATABASE=WinTV PVR 500 (1st unit) + +pci:v00004444d00000016sv00000070sd0000E817* + ID_PRODUCT_FROM_DATABASE=WinTV PVR 500 (2nd unit) + +pci:v00004444d00000016sv00000070sd0000FF92* + ID_PRODUCT_FROM_DATABASE=WiNTV PVR-550 + +pci:v00004444d00000016sv00000270sd00000801* + ID_PRODUCT_FROM_DATABASE=WinTV PVR 150 + +pci:v00004444d00000016sv0000104Dsd0000013D* + ID_PRODUCT_FROM_DATABASE=ENX-26 TV Encoder + +pci:v00004444d00000016sv000010FCsd0000D038* + ID_PRODUCT_FROM_DATABASE=GV-MVP/RX2W (1st unit) + +pci:v00004444d00000016sv000010FCsd0000D039* + ID_PRODUCT_FROM_DATABASE=GV-MVP/RX2W (2nd unit) + +pci:v00004444d00000016sv000012ABsd0000FFF3* + ID_PRODUCT_FROM_DATABASE=MPG600 + +pci:v00004444d00000016sv000012ABsd0000FFFF* + ID_PRODUCT_FROM_DATABASE=MPG600 + +pci:v00004444d00000016sv00001461sd0000C00A* + ID_PRODUCT_FROM_DATABASE=M113 PCI Analog TV (PAL/SECAM, Philips FQ1216MK3 tuner) + +pci:v00004444d00000016sv00001461sd0000C00B* + ID_PRODUCT_FROM_DATABASE=M113 PCI Analog TV (PAL/SECAM+FM, Philips FM1216MK3 tuner) + +pci:v00004444d00000016sv00001461sd0000C00C* + ID_PRODUCT_FROM_DATABASE=M113 PCI Analog TV (NTSC, JAPAN version, Philips FI1286MK2 tuner) + +pci:v00004444d00000016sv00001461sd0000C010* + ID_PRODUCT_FROM_DATABASE=M113 PCI Analog TV (NTSC, Philips FI1236MK3 tuner) + +pci:v00004444d00000016sv00001461sd0000C011* + ID_PRODUCT_FROM_DATABASE=M113 PCI Analog TV (NTSC+FM, Philips FM1236MK3 tuner) + +pci:v00004444d00000016sv00001461sd0000C018* + ID_PRODUCT_FROM_DATABASE=M113 PCI Analog TV (NTSC, Philips FQ1236MK5 tuner) + +pci:v00004444d00000016sv00001461sd0000C019* + ID_PRODUCT_FROM_DATABASE=UltraTV 1500 MCE, a.k.a. M113 PCI Analog TV (NTSC+FM, Philips FQ1236MK5 tuner) + +pci:v00004444d00000016sv00001461sd0000C01A* + ID_PRODUCT_FROM_DATABASE=M113 PCI Analog TV (PAL/SECAM, Philips FQ1216MK5 tuner) + +pci:v00004444d00000016sv00001461sd0000C01B* + ID_PRODUCT_FROM_DATABASE=M113 PCI Analog TV (PAL/SECAM+FM, Philips FM1216MK5 tuner) + +pci:v00004444d00000016sv00001461sd0000C030* + ID_PRODUCT_FROM_DATABASE=M113 PCI Analog TV (NTSC-J, Partsnic tuner) + +pci:v00004444d00000016sv00001461sd0000C031* + ID_PRODUCT_FROM_DATABASE=M113 PCI Analog TV (NTSC-J+FM, Partsnic tuner) + +pci:v00004444d00000016sv00001461sd0000C032* + ID_PRODUCT_FROM_DATABASE=M113 PCI Analog TV (PAL/SECAM, Partsnic tuner) + +pci:v00004444d00000016sv00001461sd0000C033* + ID_PRODUCT_FROM_DATABASE=M113 PCI Analog TV (PAL/SECAM+FM, Partsnic tuner) + +pci:v00004444d00000016sv00001461sd0000C034* + ID_PRODUCT_FROM_DATABASE=M113 PCI Analog TV (NTSC, Partsnic tuner) + +pci:v00004444d00000016sv00001461sd0000C035* + ID_PRODUCT_FROM_DATABASE=M113 PCI Analog TV (NTSC+FM, Partsnic tuner) + +pci:v00004444d00000016sv00001461sd0000C03F* + ID_PRODUCT_FROM_DATABASE=C115 PCI video capture card (no tuner) + +pci:v00004444d00000016sv00001461sd0000C136* + ID_PRODUCT_FROM_DATABASE=M104 mini-PCI Analog TV + +pci:v00004444d00000016sv00001461sd0000C20A* + ID_PRODUCT_FROM_DATABASE=M755 AVerTV Video Capture (PAL/SECAM, Philips FQ1216MK3 tuner) + +pci:v00004444d00000016sv00001461sd0000C218* + ID_PRODUCT_FROM_DATABASE=M755 AVerTV Video Capture (NTSC, Philips FQ1236MK5 tuner) + +pci:v00004444d00000016sv00001461sd0000C219* + ID_PRODUCT_FROM_DATABASE=M755 AVerTV Video Capture (NTSC+FM, Philips FQ1236MK5 tuner) + +pci:v00004444d00000016sv00001461sd0000C21A* + ID_PRODUCT_FROM_DATABASE=M755 AVerTV Video Capture (PAL/SECAM, Philips FQ1216MK5 tuner) + +pci:v00004444d00000016sv00001461sd0000C21B* + ID_PRODUCT_FROM_DATABASE=M755 AVerTV Video Capture (PAL/SECAM+FM, Philips FM1216MK5 tuner) + +pci:v00004444d00000016sv00001461sd0000C230* + ID_PRODUCT_FROM_DATABASE=M755 AVerTV Video Capture (NTSC-J, Partsnic tuner) + +pci:v00004444d00000016sv00001461sd0000C231* + ID_PRODUCT_FROM_DATABASE=M755 AVerTV Video Capture (NTSC-J+FM, Partsnic tuner) + +pci:v00004444d00000016sv00001461sd0000C232* + ID_PRODUCT_FROM_DATABASE=M755 AVerTV Video Capture (PAL/SECAM, Partsnic tuner) + +pci:v00004444d00000016sv00001461sd0000C233* + ID_PRODUCT_FROM_DATABASE=M755 AVerTV Video Capture (PAL/SECAM+FM, Partsnic tuner) + +pci:v00004444d00000016sv00001461sd0000C234* + ID_PRODUCT_FROM_DATABASE=M755 AVerTV Video Capture (NTSC, Partsnic tuner) + +pci:v00004444d00000016sv00001461sd0000C235* + ID_PRODUCT_FROM_DATABASE=M755 AVerTV Video Capture (NTSC+FM, Partsnic tuner) + +pci:v00004444d00000016sv00001461sd0000C337* + ID_PRODUCT_FROM_DATABASE=E106 AVerMedia AVerTV Video Capture + +pci:v00004444d00000016sv00001461sd0000C439* + ID_PRODUCT_FROM_DATABASE=M116 AVerMedia AVerTV MCE 116 Plus (NTSC/PAL/SECAM+FM+REMOTE, Xceive 2028 tuner) + +pci:v00004444d00000016sv00001461sd0000C5FF* + ID_PRODUCT_FROM_DATABASE=C755 AVerTV Video Capture card (no tuner) + +pci:v00004444d00000016sv00001461sd0000C6FF* + ID_PRODUCT_FROM_DATABASE=C115 PCI video capture card (no tuner) + +pci:v00004444d00000016sv00001461sd0000C739* + ID_PRODUCT_FROM_DATABASE=M785 AVerMedia PCI Analog TV (NTSC/PAL/SECAM+FM, Xceive 2028 tuner) + +pci:v00004444d00000016sv00009005sd00000092* + ID_PRODUCT_FROM_DATABASE=VideOh! AVC-2010 + +pci:v00004444d00000016sv00009005sd00000093* + ID_PRODUCT_FROM_DATABASE=VideOh! AVC-2410 + +pci:v00004444d00000803* + ID_PRODUCT_FROM_DATABASE=iTVC15 (CX23415) Video Decoder + +pci:v00004444d00000803sv00000070sd00004000* + ID_PRODUCT_FROM_DATABASE=WinTV PVR-350 + +pci:v00004444d00000803sv00000070sd00004001* + ID_PRODUCT_FROM_DATABASE=WinTV PVR-250 + +pci:v00004444d00000803sv00000070sd00004800* + ID_PRODUCT_FROM_DATABASE=WinTV PVR-350 (V1) + +pci:v00004444d00000803sv000012ABsd00000000* + ID_PRODUCT_FROM_DATABASE=MPG160 + +pci:v00004444d00000803sv00001461sd0000A3CE* + ID_PRODUCT_FROM_DATABASE=M179 + +pci:v00004444d00000803sv00001461sd0000A3CF* + ID_PRODUCT_FROM_DATABASE=M179 + +pci:v00004468* + ID_VENDOR_FROM_DATABASE=Bridgeport machines + +pci:v00004594* + ID_VENDOR_FROM_DATABASE=Cogetec Informatique Inc + +pci:v000045FB* + ID_VENDOR_FROM_DATABASE=Baldor Electric Company + +pci:v00004624* + ID_VENDOR_FROM_DATABASE=Budker Institute of Nuclear Physics + +pci:v00004624d0000ADC1* + ID_PRODUCT_FROM_DATABASE=ADC200ME High speed ADC + +pci:v00004624d0000DE01* + ID_PRODUCT_FROM_DATABASE=DL200ME High resolution delay line PCI based card + +pci:v00004624d0000DE02* + ID_PRODUCT_FROM_DATABASE=DL200ME Middle resolution delay line PCI based card + +pci:v00004680* + ID_VENDOR_FROM_DATABASE=Umax Computer Corp + +pci:v00004843* + ID_VENDOR_FROM_DATABASE=Hercules Computer Technology Inc + +pci:v00004916* + ID_VENDOR_FROM_DATABASE=RedCreek Communications Inc + +pci:v00004916d00001960* + ID_PRODUCT_FROM_DATABASE=RedCreek PCI adapter + +pci:v00004943* + ID_VENDOR_FROM_DATABASE=Growth Networks + +pci:v0000494F* + ID_VENDOR_FROM_DATABASE=ACCES I/O Products, Inc. + +pci:v0000494Fd00000520* + ID_PRODUCT_FROM_DATABASE=PCI-IDO-48 + +pci:v0000494Fd00000920* + ID_PRODUCT_FROM_DATABASE=PCI-IDI-48 + +pci:v0000494Fd00000C50* + ID_PRODUCT_FROM_DATABASE=PCI-DIO-24H + +pci:v0000494Fd00000C51* + ID_PRODUCT_FROM_DATABASE=PCI-DIO-24D + +pci:v0000494Fd00000C60* + ID_PRODUCT_FROM_DATABASE=PCI-DIO-48(H) + +pci:v0000494Fd00000C68* + ID_PRODUCT_FROM_DATABASE=PCI-DIO-72 + +pci:v0000494Fd00000C70* + ID_PRODUCT_FROM_DATABASE=PCI-DIO-96 + +pci:v0000494Fd00000C78* + ID_PRODUCT_FROM_DATABASE=PCI-DIO-120 + +pci:v0000494Fd00000DC8* + ID_PRODUCT_FROM_DATABASE=PCI-IDIO-16 + +pci:v0000494Fd00000E50* + ID_PRODUCT_FROM_DATABASE=PCI-DIO-24S + +pci:v0000494Fd00000E51* + ID_PRODUCT_FROM_DATABASE=PCI-DIO-24H(C) + +pci:v0000494Fd00000E52* + ID_PRODUCT_FROM_DATABASE=PCI-DIO-24D(C) + +pci:v0000494Fd00000E60* + ID_PRODUCT_FROM_DATABASE=PCI-DIO-48S(H) + +pci:v0000494Fd00000E61* + ID_PRODUCT_FROM_DATABASE=P104-DIO-24S + +pci:v0000494Fd00000F00* + ID_PRODUCT_FROM_DATABASE=PCI-IIRO-8 + +pci:v0000494Fd00000F01* + ID_PRODUCT_FROM_DATABASE=LPCI-IIRO-8 + +pci:v0000494Fd00000F08* + ID_PRODUCT_FROM_DATABASE=PCI-IIRO-16 + +pci:v0000494Fd00001050* + ID_PRODUCT_FROM_DATABASE=PCI-422/485-2 + +pci:v0000494Fd00001058* + ID_PRODUCT_FROM_DATABASE=PCI-COM422/4 + +pci:v0000494Fd00001059* + ID_PRODUCT_FROM_DATABASE=PCI-COM485/4 + +pci:v0000494Fd00001068* + ID_PRODUCT_FROM_DATABASE=PCI-COM422/8 + +pci:v0000494Fd00001069* + ID_PRODUCT_FROM_DATABASE=PCI-COM485/8 + +pci:v0000494Fd00001088* + ID_PRODUCT_FROM_DATABASE=PCI-COM232/1 + +pci:v0000494Fd00001090* + ID_PRODUCT_FROM_DATABASE=PCI-COM232/2 + +pci:v0000494Fd000010A8* + ID_PRODUCT_FROM_DATABASE=P104-COM232-8 + +pci:v0000494Fd000010C9* + ID_PRODUCT_FROM_DATABASE=PCI-COM-1S + +pci:v0000494Fd000010D0* + ID_PRODUCT_FROM_DATABASE=PCI-COM2S + +pci:v0000494Fd000010E8* + ID_PRODUCT_FROM_DATABASE=PCI-COM-8SM + +pci:v0000494Fd00001148* + ID_PRODUCT_FROM_DATABASE=PCI-ICM-1S + +pci:v0000494Fd00001150* + ID_PRODUCT_FROM_DATABASE=PCI-ICM-2S + +pci:v0000494Fd00001158* + ID_PRODUCT_FROM_DATABASE=PCI-ICM422/4 + +pci:v0000494Fd00001159* + ID_PRODUCT_FROM_DATABASE=PCI-ICM485/4 + +pci:v0000494Fd00001250* + ID_PRODUCT_FROM_DATABASE=PCI-WDG-2S + +pci:v0000494Fd000012D0* + ID_PRODUCT_FROM_DATABASE=PCI-WDG-IMPAC + +pci:v0000494Fd000022C0* + ID_PRODUCT_FROM_DATABASE=PCI-WDG-CSM + +pci:v0000494Fd00002C50* + ID_PRODUCT_FROM_DATABASE=PCI-DIO-96CT + +pci:v0000494Fd00002C58* + ID_PRODUCT_FROM_DATABASE=PCI-DIO-96C3 + +pci:v0000494Fd00005ED0* + ID_PRODUCT_FROM_DATABASE=PCI-DAC + +pci:v0000494Fd00006C90* + ID_PRODUCT_FROM_DATABASE=PCI-DA12-2 + +pci:v0000494Fd00006C98* + ID_PRODUCT_FROM_DATABASE=PCI-DA12-4 + +pci:v0000494Fd00006CA0* + ID_PRODUCT_FROM_DATABASE=PCI-DA12-6 + +pci:v0000494Fd00006CA8* + ID_PRODUCT_FROM_DATABASE=PCI-DA12-8 + +pci:v0000494Fd00006CA9* + ID_PRODUCT_FROM_DATABASE=PCI-DA12-8V + +pci:v0000494Fd00006CB0* + ID_PRODUCT_FROM_DATABASE=PCI-DA12-16 + +pci:v0000494Fd00006CB1* + ID_PRODUCT_FROM_DATABASE=PCI-DA12-16V + +pci:v0000494Fd00008EF0* + ID_PRODUCT_FROM_DATABASE=P104-FAS16-16 + +pci:v0000494Fd0000ACA8* + ID_PRODUCT_FROM_DATABASE=PCI-AI12-16 + +pci:v0000494Fd0000ACA9* + ID_PRODUCT_FROM_DATABASE=PCI-AI12-16A + +pci:v0000494Fd0000ECA8* + ID_PRODUCT_FROM_DATABASE=PCI-AIO12-16 + +pci:v0000494Fd0000ECA9* + ID_PRODUCT_FROM_DATABASE=PCI-A12-16 + +pci:v0000494Fd0000ECAA* + ID_PRODUCT_FROM_DATABASE=PCI-A12-16A + +pci:v0000494Fd0000ECE8* + ID_PRODUCT_FROM_DATABASE=PCI-A16-16 + +pci:v00004978* + ID_VENDOR_FROM_DATABASE=Axil Computer Inc + +pci:v00004A14* + ID_VENDOR_FROM_DATABASE=NetVin + +pci:v00004A14d00005000* + ID_PRODUCT_FROM_DATABASE=NV5000SC + +pci:v00004A14d00005000sv00004A14sd00005000* + ID_PRODUCT_FROM_DATABASE=RT8029-Based Ethernet Adapter + +pci:v00004B10* + ID_VENDOR_FROM_DATABASE=Buslogic Inc. + +pci:v00004C48* + ID_VENDOR_FROM_DATABASE=LUNG HWA Electronics + +pci:v00004C53* + ID_VENDOR_FROM_DATABASE=SBS Technologies + +pci:v00004C53d00000000* + ID_PRODUCT_FROM_DATABASE=PLUSTEST device + +pci:v00004C53d00000000sv00004C53sd00003000* + ID_PRODUCT_FROM_DATABASE=PLUSTEST card (PC104+) + +pci:v00004C53d00000000sv00004C53sd00003001* + ID_PRODUCT_FROM_DATABASE=PLUSTEST card (PMC) + +pci:v00004C53d00000001* + ID_PRODUCT_FROM_DATABASE=PLUSTEST-MM device + +pci:v00004C53d00000001sv00004C53sd00003002* + ID_PRODUCT_FROM_DATABASE=PLUSTEST-MM card (PMC) + +pci:v00004CA1* + ID_VENDOR_FROM_DATABASE=Seanix Technology Inc + +pci:v00004D51* + ID_VENDOR_FROM_DATABASE=MediaQ Inc. + +pci:v00004D51d00000200* + ID_PRODUCT_FROM_DATABASE=MQ-200 + +pci:v00004D54* + ID_VENDOR_FROM_DATABASE=Microtechnica Co Ltd + +pci:v00004D56* + ID_VENDOR_FROM_DATABASE=MATRIX VISION GmbH + +pci:v00004D56d00000000* + ID_PRODUCT_FROM_DATABASE=[mvHYPERION-CLe/CLb] CameraLink PCI Express x1 Frame Grabber + +pci:v00004D56d00000001* + ID_PRODUCT_FROM_DATABASE=[mvHYPERION-CLf/CLm] CameraLink PCI Express x4 Frame Grabber + +pci:v00004D56d00000010* + ID_PRODUCT_FROM_DATABASE=[mvHYPERION-16R16/-32R16] 16 Video Channel PCI Express x4 Frame Grabber + +pci:v00004D56d00000020* + ID_PRODUCT_FROM_DATABASE=[mvHYPERION-HD-SDI] HD-SDI PCI Express x4 Frame Grabber + +pci:v00004D56d00000030* + ID_PRODUCT_FROM_DATABASE=[mvHYPERION-HD-SDI-Merger] HD-SDI PCI Express x4 Frame Grabber + +pci:v00004DDC* + ID_VENDOR_FROM_DATABASE=ILC Data Device Corp + +pci:v00004DDCd00000100* + ID_PRODUCT_FROM_DATABASE=DD-42924I5-300 (ARINC 429 Data Bus) + +pci:v00004DDCd00000801* + ID_PRODUCT_FROM_DATABASE=BU-65570I1 MIL-STD-1553 Test and Simulation + +pci:v00004DDCd00000802* + ID_PRODUCT_FROM_DATABASE=BU-65570I2 MIL-STD-1553 Test and Simulation + +pci:v00004DDCd00000811* + ID_PRODUCT_FROM_DATABASE=BU-65572I1 MIL-STD-1553 Test and Simulation + +pci:v00004DDCd00000812* + ID_PRODUCT_FROM_DATABASE=BU-65572I2 MIL-STD-1553 Test and Simulation + +pci:v00004DDCd00000881* + ID_PRODUCT_FROM_DATABASE=BU-65570T1 MIL-STD-1553 Test and Simulation + +pci:v00004DDCd00000882* + ID_PRODUCT_FROM_DATABASE=BU-65570T2 MIL-STD-1553 Test and Simulation + +pci:v00004DDCd00000891* + ID_PRODUCT_FROM_DATABASE=BU-65572T1 MIL-STD-1553 Test and Simulation + +pci:v00004DDCd00000892* + ID_PRODUCT_FROM_DATABASE=BU-65572T2 MIL-STD-1553 Test and Simulation + +pci:v00004DDCd00000901* + ID_PRODUCT_FROM_DATABASE=BU-65565C1 MIL-STD-1553 Data Bus + +pci:v00004DDCd00000902* + ID_PRODUCT_FROM_DATABASE=BU-65565C2 MIL-STD-1553 Data Bus + +pci:v00004DDCd00000903* + ID_PRODUCT_FROM_DATABASE=BU-65565C3 MIL-STD-1553 Data Bus + +pci:v00004DDCd00000904* + ID_PRODUCT_FROM_DATABASE=BU-65565C4 MIL-STD-1553 Data Bus + +pci:v00004DDCd00000B01* + ID_PRODUCT_FROM_DATABASE=BU-65569I1 MIL-STD-1553 Data Bus + +pci:v00004DDCd00000B02* + ID_PRODUCT_FROM_DATABASE=BU-65569I2 MIL-STD-1553 Data Bus + +pci:v00004DDCd00000B03* + ID_PRODUCT_FROM_DATABASE=BU-65569I3 MIL-STD-1553 Data Bus + +pci:v00004DDCd00000B04* + ID_PRODUCT_FROM_DATABASE=BU-65569I4 MIL-STD-1553 Data Bus + +pci:v00005045* + ID_VENDOR_FROM_DATABASE=University of Toronto + +pci:v00005045d00004243* + ID_PRODUCT_FROM_DATABASE=BLASTbus PCI Interface Card v1 + +pci:v00005046* + ID_VENDOR_FROM_DATABASE=GemTek Technology Corporation + +pci:v00005046d00001001* + ID_PRODUCT_FROM_DATABASE=PCI Radio + +pci:v00005053* + ID_VENDOR_FROM_DATABASE=Voyetra Technologies + +pci:v00005053d00002010* + ID_PRODUCT_FROM_DATABASE=Daytona Audio Adapter + +pci:v000050B2* + ID_VENDOR_FROM_DATABASE=TerraTec Electronic GmbH + +pci:v000050B2d00001111* + ID_PRODUCT_FROM_DATABASE=Terratec XLerate + +pci:v00005136* + ID_VENDOR_FROM_DATABASE=S S Technologies + +pci:v00005143* + ID_VENDOR_FROM_DATABASE=Qualcomm Inc + +pci:v00005145* + ID_VENDOR_FROM_DATABASE=Ensoniq (Old) + +pci:v00005145d00003031* + ID_PRODUCT_FROM_DATABASE=Concert AudioPCI + +pci:v00005168* + ID_VENDOR_FROM_DATABASE=Animation Technologies Inc. + +pci:v00005168d00000300* + ID_PRODUCT_FROM_DATABASE=FlyDVB-S + +pci:v00005168d00000301* + ID_PRODUCT_FROM_DATABASE=FlyDVB-T + +pci:v00005301* + ID_VENDOR_FROM_DATABASE=Alliance Semiconductor Corp. + +pci:v00005301d00000001* + ID_PRODUCT_FROM_DATABASE=ProMotion aT3D + +pci:v00005333* + ID_VENDOR_FROM_DATABASE=S3 Inc. + +pci:v00005333d00000551* + ID_PRODUCT_FROM_DATABASE=Plato/PX (system) + +pci:v00005333d00005631* + ID_PRODUCT_FROM_DATABASE=86c325 [ViRGE] + +pci:v00005333d00008800* + ID_PRODUCT_FROM_DATABASE=86c866 [Vision 866] + +pci:v00005333d00008801* + ID_PRODUCT_FROM_DATABASE=86c964 [Vision 964] + +pci:v00005333d00008810* + ID_PRODUCT_FROM_DATABASE=86c764_0 [Trio 32 vers 0] + +pci:v00005333d00008811* + ID_PRODUCT_FROM_DATABASE=86c764/765 [Trio32/64/64V+] + +pci:v00005333d00008812* + ID_PRODUCT_FROM_DATABASE=86cM65 [Aurora64V+] + +pci:v00005333d00008813* + ID_PRODUCT_FROM_DATABASE=86c764_3 [Trio 32/64 vers 3] + +pci:v00005333d00008814* + ID_PRODUCT_FROM_DATABASE=86c767 [Trio 64UV+] + +pci:v00005333d00008815* + ID_PRODUCT_FROM_DATABASE=86cM65 [Aurora 128] + +pci:v00005333d0000883D* + ID_PRODUCT_FROM_DATABASE=86c988 [ViRGE/VX] + +pci:v00005333d00008870* + ID_PRODUCT_FROM_DATABASE=FireGL + +pci:v00005333d00008880* + ID_PRODUCT_FROM_DATABASE=86c868 [Vision 868 VRAM] vers 0 + +pci:v00005333d00008881* + ID_PRODUCT_FROM_DATABASE=86c868 [Vision 868 VRAM] vers 1 + +pci:v00005333d00008882* + ID_PRODUCT_FROM_DATABASE=86c868 [Vision 868 VRAM] vers 2 + +pci:v00005333d00008883* + ID_PRODUCT_FROM_DATABASE=86c868 [Vision 868 VRAM] vers 3 + +pci:v00005333d000088B0* + ID_PRODUCT_FROM_DATABASE=86c928 [Vision 928 VRAM] vers 0 + +pci:v00005333d000088B1* + ID_PRODUCT_FROM_DATABASE=86c928 [Vision 928 VRAM] vers 1 + +pci:v00005333d000088B2* + ID_PRODUCT_FROM_DATABASE=86c928 [Vision 928 VRAM] vers 2 + +pci:v00005333d000088B3* + ID_PRODUCT_FROM_DATABASE=86c928 [Vision 928 VRAM] vers 3 + +pci:v00005333d000088C0* + ID_PRODUCT_FROM_DATABASE=86c864 [Vision 864 DRAM] vers 0 + +pci:v00005333d000088C1* + ID_PRODUCT_FROM_DATABASE=86c864 [Vision 864 DRAM] vers 1 + +pci:v00005333d000088C2* + ID_PRODUCT_FROM_DATABASE=86c864 [Vision 864-P DRAM] vers 2 + +pci:v00005333d000088C3* + ID_PRODUCT_FROM_DATABASE=86c864 [Vision 864-P DRAM] vers 3 + +pci:v00005333d000088D0* + ID_PRODUCT_FROM_DATABASE=86c964 [Vision 964 VRAM] vers 0 + +pci:v00005333d000088D1* + ID_PRODUCT_FROM_DATABASE=86c964 [Vision 964 VRAM] vers 1 + +pci:v00005333d000088D2* + ID_PRODUCT_FROM_DATABASE=86c964 [Vision 964-P VRAM] vers 2 + +pci:v00005333d000088D3* + ID_PRODUCT_FROM_DATABASE=86c964 [Vision 964-P VRAM] vers 3 + +pci:v00005333d000088F0* + ID_PRODUCT_FROM_DATABASE=86c968 [Vision 968 VRAM] rev 0 + +pci:v00005333d000088F1* + ID_PRODUCT_FROM_DATABASE=86c968 [Vision 968 VRAM] rev 1 + +pci:v00005333d000088F2* + ID_PRODUCT_FROM_DATABASE=86c968 [Vision 968 VRAM] rev 2 + +pci:v00005333d000088F3* + ID_PRODUCT_FROM_DATABASE=86c968 [Vision 968 VRAM] rev 3 + +pci:v00005333d00008900* + ID_PRODUCT_FROM_DATABASE=86c755 [Trio 64V2/DX] + +pci:v00005333d00008900sv00005333sd00008900* + ID_PRODUCT_FROM_DATABASE=86C775 Trio64V2/DX + +pci:v00005333d00008901* + ID_PRODUCT_FROM_DATABASE=86c775/86c785 [Trio 64V2/DX or /GX] + +pci:v00005333d00008901sv00005333sd00008901* + ID_PRODUCT_FROM_DATABASE=86C775 Trio64V2/DX, 86C785 Trio64V2/GX + +pci:v00005333d00008902* + ID_PRODUCT_FROM_DATABASE=Plato/PX + +pci:v00005333d00008903* + ID_PRODUCT_FROM_DATABASE=Trio 3D business multimedia + +pci:v00005333d00008904* + ID_PRODUCT_FROM_DATABASE=86c365, 86c366 [Trio 3D] + +pci:v00005333d00008904sv00001014sd000000DB* + ID_PRODUCT_FROM_DATABASE=Integrated Trio3D + +pci:v00005333d00008904sv00004843sd0000314A* + ID_PRODUCT_FROM_DATABASE=Terminator 128/3D GLH + +pci:v00005333d00008904sv00005333sd00008904* + ID_PRODUCT_FROM_DATABASE=86C365 Trio3D AGP + +pci:v00005333d00008905* + ID_PRODUCT_FROM_DATABASE=Trio 64V+ family + +pci:v00005333d00008906* + ID_PRODUCT_FROM_DATABASE=Trio 64V+ family + +pci:v00005333d00008907* + ID_PRODUCT_FROM_DATABASE=Trio 64V+ family + +pci:v00005333d00008908* + ID_PRODUCT_FROM_DATABASE=Trio 64V+ family + +pci:v00005333d00008909* + ID_PRODUCT_FROM_DATABASE=Trio 64V+ family + +pci:v00005333d0000890A* + ID_PRODUCT_FROM_DATABASE=Trio 64V+ family + +pci:v00005333d0000890B* + ID_PRODUCT_FROM_DATABASE=Trio 64V+ family + +pci:v00005333d0000890C* + ID_PRODUCT_FROM_DATABASE=Trio 64V+ family + +pci:v00005333d0000890D* + ID_PRODUCT_FROM_DATABASE=Trio 64V+ family + +pci:v00005333d0000890E* + ID_PRODUCT_FROM_DATABASE=Trio 64V+ family + +pci:v00005333d0000890F* + ID_PRODUCT_FROM_DATABASE=Trio 64V+ family + +pci:v00005333d00008A01* + ID_PRODUCT_FROM_DATABASE=86c375 [ViRGE/DX] or 86c385 [ViRGE/GX] + +pci:v00005333d00008A01sv00000E11sd0000B032* + ID_PRODUCT_FROM_DATABASE=ViRGE/GX + +pci:v00005333d00008A01sv000010B4sd00001617* + ID_PRODUCT_FROM_DATABASE=Nitro 3D + +pci:v00005333d00008A01sv000010B4sd00001717* + ID_PRODUCT_FROM_DATABASE=Nitro 3D + +pci:v00005333d00008A01sv00005333sd00008A01* + ID_PRODUCT_FROM_DATABASE=ViRGE/DX + +pci:v00005333d00008A10* + ID_PRODUCT_FROM_DATABASE=ViRGE/GX2 + +pci:v00005333d00008A10sv00001092sd00008A10* + ID_PRODUCT_FROM_DATABASE=Stealth 3D 4000 + +pci:v00005333d00008A13* + ID_PRODUCT_FROM_DATABASE=86c360 [Trio 3D/1X], 86c362, 86c368 [Trio 3D/2X] + +pci:v00005333d00008A13sv00005333sd00008A13* + ID_PRODUCT_FROM_DATABASE=Trio3D/2X + +pci:v00005333d00008A20* + ID_PRODUCT_FROM_DATABASE=86c794 [Savage 3D] + +pci:v00005333d00008A20sv00005333sd00008A20* + ID_PRODUCT_FROM_DATABASE=86C391 Savage3D + +pci:v00005333d00008A21* + ID_PRODUCT_FROM_DATABASE=86c390 [Savage 3D/MV] + +pci:v00005333d00008A21sv00005333sd00008A21* + ID_PRODUCT_FROM_DATABASE=86C390 Savage3D/MV + +pci:v00005333d00008A22* + ID_PRODUCT_FROM_DATABASE=Savage 4 + +pci:v00005333d00008A22sv00001033sd00008068* + ID_PRODUCT_FROM_DATABASE=Savage 4 + +pci:v00005333d00008A22sv00001033sd00008069* + ID_PRODUCT_FROM_DATABASE=Savage 4 + +pci:v00005333d00008A22sv00001033sd00008110* + ID_PRODUCT_FROM_DATABASE=Savage 4 LT + +pci:v00005333d00008A22sv0000105Dsd00000018* + ID_PRODUCT_FROM_DATABASE=SR9 8Mb SDRAM + +pci:v00005333d00008A22sv0000105Dsd0000002A* + ID_PRODUCT_FROM_DATABASE=SR9 Pro 16Mb SDRAM + +pci:v00005333d00008A22sv0000105Dsd0000003A* + ID_PRODUCT_FROM_DATABASE=SR9 Pro 32Mb SDRAM + +pci:v00005333d00008A22sv0000105Dsd0000092F* + ID_PRODUCT_FROM_DATABASE=SR9 Pro+ 16Mb SGRAM + +pci:v00005333d00008A22sv00001092sd00004207* + ID_PRODUCT_FROM_DATABASE=Stealth III S540 + +pci:v00005333d00008A22sv00001092sd00004800* + ID_PRODUCT_FROM_DATABASE=Stealth III S540 + +pci:v00005333d00008A22sv00001092sd00004807* + ID_PRODUCT_FROM_DATABASE=SpeedStar A90 + +pci:v00005333d00008A22sv00001092sd00004808* + ID_PRODUCT_FROM_DATABASE=Stealth III S540 + +pci:v00005333d00008A22sv00001092sd00004809* + ID_PRODUCT_FROM_DATABASE=Stealth III S540 + +pci:v00005333d00008A22sv00001092sd0000480E* + ID_PRODUCT_FROM_DATABASE=Stealth III S540 + +pci:v00005333d00008A22sv00001092sd00004904* + ID_PRODUCT_FROM_DATABASE=Stealth III S520 + +pci:v00005333d00008A22sv00001092sd00004905* + ID_PRODUCT_FROM_DATABASE=SpeedStar A200 + +pci:v00005333d00008A22sv00001092sd00004A09* + ID_PRODUCT_FROM_DATABASE=Stealth III S540 + +pci:v00005333d00008A22sv00001092sd00004A0B* + ID_PRODUCT_FROM_DATABASE=Stealth III S540 Xtreme + +pci:v00005333d00008A22sv00001092sd00004A0F* + ID_PRODUCT_FROM_DATABASE=Stealth III S540 + +pci:v00005333d00008A22sv00001092sd00004E01* + ID_PRODUCT_FROM_DATABASE=Stealth III S540 + +pci:v00005333d00008A22sv00001102sd0000101D* + ID_PRODUCT_FROM_DATABASE=3d Blaster Savage 4 + +pci:v00005333d00008A22sv00001102sd0000101E* + ID_PRODUCT_FROM_DATABASE=3d Blaster Savage 4 + +pci:v00005333d00008A22sv00005333sd00008100* + ID_PRODUCT_FROM_DATABASE=86C394-397 Savage4 SDRAM 100 + +pci:v00005333d00008A22sv00005333sd00008110* + ID_PRODUCT_FROM_DATABASE=86C394-397 Savage4 SDRAM 110 + +pci:v00005333d00008A22sv00005333sd00008125* + ID_PRODUCT_FROM_DATABASE=86C394-397 Savage4 SDRAM 125 + +pci:v00005333d00008A22sv00005333sd00008143* + ID_PRODUCT_FROM_DATABASE=86C394-397 Savage4 SDRAM 143 + +pci:v00005333d00008A22sv00005333sd00008A22* + ID_PRODUCT_FROM_DATABASE=86C394-397 Savage4 + +pci:v00005333d00008A22sv00005333sd00008A2E* + ID_PRODUCT_FROM_DATABASE=86C394-397 Savage4 32bit + +pci:v00005333d00008A22sv00005333sd00009125* + ID_PRODUCT_FROM_DATABASE=86C394-397 Savage4 SGRAM 125 + +pci:v00005333d00008A22sv00005333sd00009143* + ID_PRODUCT_FROM_DATABASE=86C394-397 Savage4 SGRAM 143 + +pci:v00005333d00008A23* + ID_PRODUCT_FROM_DATABASE=Savage 4 + +pci:v00005333d00008A25* + ID_PRODUCT_FROM_DATABASE=ProSavage PM133 + +pci:v00005333d00008A25sv00000303sd00000303* + ID_PRODUCT_FROM_DATABASE=D9840-60001 [Brio BA410 Motherboard] + +pci:v00005333d00008A26* + ID_PRODUCT_FROM_DATABASE=ProSavage KM133 + +pci:v00005333d00008C00* + ID_PRODUCT_FROM_DATABASE=ViRGE/M3 + +pci:v00005333d00008C01* + ID_PRODUCT_FROM_DATABASE=ViRGE/MX + +pci:v00005333d00008C01sv00001179sd00000001* + ID_PRODUCT_FROM_DATABASE=ViRGE/MX + +pci:v00005333d00008C02* + ID_PRODUCT_FROM_DATABASE=ViRGE/MX+ + +pci:v00005333d00008C03* + ID_PRODUCT_FROM_DATABASE=ViRGE/MX+MV + +pci:v00005333d00008C10* + ID_PRODUCT_FROM_DATABASE=86C270-294 Savage/MX-MV + +pci:v00005333d00008C11* + ID_PRODUCT_FROM_DATABASE=82C270-294 Savage/MX + +pci:v00005333d00008C12* + ID_PRODUCT_FROM_DATABASE=86C270-294 Savage/IX-MV + +pci:v00005333d00008C12sv00001014sd0000017F* + ID_PRODUCT_FROM_DATABASE=ThinkPad T20/T22 + +pci:v00005333d00008C12sv00001179sd00000001* + ID_PRODUCT_FROM_DATABASE=86C584 SuperSavage/IXC Toshiba + +pci:v00005333d00008C13* + ID_PRODUCT_FROM_DATABASE=86C270-294 Savage/IX + +pci:v00005333d00008C13sv00001179sd00000001* + ID_PRODUCT_FROM_DATABASE=Magnia Z310 + +pci:v00005333d00008C22* + ID_PRODUCT_FROM_DATABASE=SuperSavage MX/128 + +pci:v00005333d00008C24* + ID_PRODUCT_FROM_DATABASE=SuperSavage MX/64 + +pci:v00005333d00008C26* + ID_PRODUCT_FROM_DATABASE=SuperSavage MX/64C + +pci:v00005333d00008C2A* + ID_PRODUCT_FROM_DATABASE=SuperSavage IX/128 SDR + +pci:v00005333d00008C2B* + ID_PRODUCT_FROM_DATABASE=SuperSavage IX/128 DDR + +pci:v00005333d00008C2C* + ID_PRODUCT_FROM_DATABASE=SuperSavage IX/64 SDR + +pci:v00005333d00008C2D* + ID_PRODUCT_FROM_DATABASE=SuperSavage IX/64 DDR + +pci:v00005333d00008C2E* + ID_PRODUCT_FROM_DATABASE=SuperSavage IX/C SDR + +pci:v00005333d00008C2Esv00001014sd000001FC* + ID_PRODUCT_FROM_DATABASE=ThinkPad T23 + +pci:v00005333d00008C2F* + ID_PRODUCT_FROM_DATABASE=SuperSavage IX/C DDR + +pci:v00005333d00008D01* + ID_PRODUCT_FROM_DATABASE=86C380 [ProSavageDDR K4M266] + +pci:v00005333d00008D02* + ID_PRODUCT_FROM_DATABASE=VT8636A [ProSavage KN133] AGP4X VGA Controller (TwisterK) + +pci:v00005333d00008D03* + ID_PRODUCT_FROM_DATABASE=VT8751 [ProSavageDDR P4M266] + +pci:v00005333d00008D04* + ID_PRODUCT_FROM_DATABASE=VT8375 [ProSavage8 KM266/KL266] + +pci:v00005333d00008E40* + ID_PRODUCT_FROM_DATABASE=2300E Graphics Processor + +pci:v00005333d00008E48* + ID_PRODUCT_FROM_DATABASE=Chrome S27 PCIE + +pci:v00005333d00008E48sv00005333sd00000130* + ID_PRODUCT_FROM_DATABASE=Chrome S27 256M DDR2 + +pci:v00005333d00009102* + ID_PRODUCT_FROM_DATABASE=86C410 Savage 2000 + +pci:v00005333d00009102sv00001092sd00005932* + ID_PRODUCT_FROM_DATABASE=Viper II Z200 + +pci:v00005333d00009102sv00001092sd00005934* + ID_PRODUCT_FROM_DATABASE=Viper II Z200 + +pci:v00005333d00009102sv00001092sd00005952* + ID_PRODUCT_FROM_DATABASE=Viper II Z200 + +pci:v00005333d00009102sv00001092sd00005954* + ID_PRODUCT_FROM_DATABASE=Viper II Z200 + +pci:v00005333d00009102sv00001092sd00005A35* + ID_PRODUCT_FROM_DATABASE=Viper II Z200 + +pci:v00005333d00009102sv00001092sd00005A37* + ID_PRODUCT_FROM_DATABASE=Viper II Z200 + +pci:v00005333d00009102sv00001092sd00005A55* + ID_PRODUCT_FROM_DATABASE=Viper II Z200 + +pci:v00005333d00009102sv00001092sd00005A57* + ID_PRODUCT_FROM_DATABASE=Viper II Z200 + +pci:v00005333d0000CA00* + ID_PRODUCT_FROM_DATABASE=SonicVibes + +pci:v00005431* + ID_VENDOR_FROM_DATABASE=AuzenTech, Inc. + +pci:v0000544C* + ID_VENDOR_FROM_DATABASE=Teralogic Inc + +pci:v0000544Cd00000350* + ID_PRODUCT_FROM_DATABASE=TL880-based HDTV/ATSC tuner + +pci:v00005452* + ID_VENDOR_FROM_DATABASE=SCANLAB AG + +pci:v00005452d00003443* + ID_PRODUCT_FROM_DATABASE=RTC4 + +pci:v00005455* + ID_VENDOR_FROM_DATABASE=Technische University Berlin + +pci:v00005455d00004458* + ID_PRODUCT_FROM_DATABASE=S5933 + +pci:v00005456* + ID_VENDOR_FROM_DATABASE=GoTView + +pci:v00005519* + ID_VENDOR_FROM_DATABASE=Cnet Technologies, Inc. + +pci:v00005544* + ID_VENDOR_FROM_DATABASE=Dunord Technologies + +pci:v00005544d00000001* + ID_PRODUCT_FROM_DATABASE=I-30xx Scanner Interface + +pci:v00005555* + ID_VENDOR_FROM_DATABASE=Genroco, Inc + +pci:v00005555d00000003* + ID_PRODUCT_FROM_DATABASE=TURBOstor HFP-832 [HiPPI NIC] + +pci:v00005646* + ID_VENDOR_FROM_DATABASE=Vector Fabrics BV + +pci:v00005654* + ID_VENDOR_FROM_DATABASE=VoiceTronix Pty Ltd + +pci:v00005700* + ID_VENDOR_FROM_DATABASE=Netpower + +pci:v0000584D* + ID_VENDOR_FROM_DATABASE=AuzenTech Co., Ltd. + +pci:v00005851* + ID_VENDOR_FROM_DATABASE=Exacq Technologies + +pci:v00005853* + ID_VENDOR_FROM_DATABASE=XenSource, Inc. + +pci:v00005853d00000001* + ID_PRODUCT_FROM_DATABASE=Xen Platform Device + +pci:v00005853d0000C110* + ID_PRODUCT_FROM_DATABASE=Virtualized HID + +pci:v00005853d0000C147* + ID_PRODUCT_FROM_DATABASE=Virtualized Graphics Device + +pci:v00005854* + ID_VENDOR_FROM_DATABASE=GoTView + +pci:v00005ACE* + ID_VENDOR_FROM_DATABASE=Beholder International Ltd. + +pci:v0000631C* + ID_VENDOR_FROM_DATABASE=SmartInfra Ltd + +pci:v0000631Cd00001652* + ID_PRODUCT_FROM_DATABASE=PXI-1652 Signal Generator + +pci:v0000631Cd00002504* + ID_PRODUCT_FROM_DATABASE=PXI-2504 Signal Interrogator + +pci:v00006356* + ID_VENDOR_FROM_DATABASE=UltraStor + +pci:v00006374* + ID_VENDOR_FROM_DATABASE=c't Magazin fuer Computertechnik + +pci:v00006374d00006773* + ID_PRODUCT_FROM_DATABASE=GPPCI + +pci:v00006409* + ID_VENDOR_FROM_DATABASE=Logitec Corp. + +pci:v00006549* + ID_VENDOR_FROM_DATABASE=Teradici Corp. + +pci:v00006549d00001200* + ID_PRODUCT_FROM_DATABASE=TERA1200 PC-over-IP Host + +pci:v00006666* + ID_VENDOR_FROM_DATABASE=Decision Computer International Co. + +pci:v00006666d00000001* + ID_PRODUCT_FROM_DATABASE=PCCOM4 + +pci:v00006666d00000002* + ID_PRODUCT_FROM_DATABASE=PCCOM8 + +pci:v00006666d00000004* + ID_PRODUCT_FROM_DATABASE=PCCOM2 + +pci:v00006666d00000101* + ID_PRODUCT_FROM_DATABASE=PCI 8255/8254 I/O Card + +pci:v00006666d00000200* + ID_PRODUCT_FROM_DATABASE=12-bit AD/DA Card + +pci:v00006666d00000201* + ID_PRODUCT_FROM_DATABASE=14-bit AD/DA Card + +pci:v00006666d00001011* + ID_PRODUCT_FROM_DATABASE=Industrial Card + +pci:v00006666d00001021* + ID_PRODUCT_FROM_DATABASE=8 photo couple 8 relay Card + +pci:v00006666d00001022* + ID_PRODUCT_FROM_DATABASE=4 photo couple 4 relay Card + +pci:v00006666d00001025* + ID_PRODUCT_FROM_DATABASE=16 photo couple 16 relay Card + +pci:v00006666d00004000* + ID_PRODUCT_FROM_DATABASE=WatchDog Card + +pci:v00006900* + ID_VENDOR_FROM_DATABASE=Red Hat, Inc. + +pci:v00007063* + ID_VENDOR_FROM_DATABASE=pcHDTV + +pci:v00007063d00002000* + ID_PRODUCT_FROM_DATABASE=HD-2000 + +pci:v00007063d00003000* + ID_PRODUCT_FROM_DATABASE=HD-3000 + +pci:v00007063d00005500* + ID_PRODUCT_FROM_DATABASE=HD5500 HDTV + +pci:v00007284* + ID_VENDOR_FROM_DATABASE=HT OMEGA Inc. + +pci:v00007604* + ID_VENDOR_FROM_DATABASE=O.N. Electronic Co Ltd. + +pci:v00007BDE* + ID_VENDOR_FROM_DATABASE=MIDAC Corporation + +pci:v00007FED* + ID_VENDOR_FROM_DATABASE=PowerTV + +pci:v00008008* + ID_VENDOR_FROM_DATABASE=Quancom Electronic GmbH + +pci:v00008008d00000010* + ID_PRODUCT_FROM_DATABASE=WDOG1 [PCI-Watchdog 1] + +pci:v00008008d00000011* + ID_PRODUCT_FROM_DATABASE=PWDOG2 [PCI-Watchdog 2] + +pci:v00008008d00000015* + ID_PRODUCT_FROM_DATABASE=Clock77/PCI & Clock77/PCIe (DCF-77 receiver) + +pci:v0000807D* + ID_VENDOR_FROM_DATABASE=Asustek Computer, Inc. + +pci:v00008086* + ID_VENDOR_FROM_DATABASE=Intel Corporation + +pci:v00008086d00000007* + ID_PRODUCT_FROM_DATABASE=82379AB + +pci:v00008086d00000008* + ID_PRODUCT_FROM_DATABASE=Extended Express System Support Controller + +pci:v00008086d00000039* + ID_PRODUCT_FROM_DATABASE=21145 Fast Ethernet + +pci:v00008086d00000040* + ID_PRODUCT_FROM_DATABASE=Core Processor DRAM Controller + +pci:v00008086d00000041* + ID_PRODUCT_FROM_DATABASE=Core Processor PCI Express x16 Root Port + +pci:v00008086d00000042* + ID_PRODUCT_FROM_DATABASE=Core Processor Integrated Graphics Controller + +pci:v00008086d00000043* + ID_PRODUCT_FROM_DATABASE=Core Processor Secondary PCI Express Root Port + +pci:v00008086d00000044* + ID_PRODUCT_FROM_DATABASE=Core Processor DRAM Controller + +pci:v00008086d00000044sv00001025sd00000347* + ID_PRODUCT_FROM_DATABASE=Aspire 7740G + +pci:v00008086d00000044sv0000E4BFsd000050C1* + ID_PRODUCT_FROM_DATABASE=PC1-GROOVE + +pci:v00008086d00000045* + ID_PRODUCT_FROM_DATABASE=Core Processor PCI Express x16 Root Port + +pci:v00008086d00000046* + ID_PRODUCT_FROM_DATABASE=Core Processor Integrated Graphics Controller + +pci:v00008086d00000046sv0000E4BFsd000050C1* + ID_PRODUCT_FROM_DATABASE=PC1-GROOVE + +pci:v00008086d00000047* + ID_PRODUCT_FROM_DATABASE=Core Processor Secondary PCI Express Root Port + +pci:v00008086d00000048* + ID_PRODUCT_FROM_DATABASE=Core Processor DRAM Controller + +pci:v00008086d00000049* + ID_PRODUCT_FROM_DATABASE=Core Processor PCI Express x16 Root Port + +pci:v00008086d0000004A* + ID_PRODUCT_FROM_DATABASE=Core Processor Integrated Graphics Controller + +pci:v00008086d0000004B* + ID_PRODUCT_FROM_DATABASE=Core Processor Secondary PCI Express Root Port + +pci:v00008086d00000050* + ID_PRODUCT_FROM_DATABASE=Core Processor Thermal Management Controller + +pci:v00008086d00000069* + ID_PRODUCT_FROM_DATABASE=Core Processor DRAM Controller + +pci:v00008086d00000082* + ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6205 [Taylor Peak] + +pci:v00008086d00000082sv00008086sd00001301* + ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6205 AGN + +pci:v00008086d00000082sv00008086sd00001306* + ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6205 ABG + +pci:v00008086d00000082sv00008086sd00001307* + ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6205 BG + +pci:v00008086d00000082sv00008086sd00001321* + ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6205 AGN + +pci:v00008086d00000082sv00008086sd00001326* + ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6205 ABG + +pci:v00008086d00000083* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 1000 [Condor Peak] + +pci:v00008086d00000083sv00008086sd00001205* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 1000 BGN + +pci:v00008086d00000083sv00008086sd00001206* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 1000 BG + +pci:v00008086d00000083sv00008086sd00001225* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 1000 BGN + +pci:v00008086d00000083sv00008086sd00001226* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 1000 BG + +pci:v00008086d00000083sv00008086sd00001305* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 1000 BGN + +pci:v00008086d00000083sv00008086sd00001306* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 1000 BG + +pci:v00008086d00000083sv00008086sd00001325* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 1000 BGN + +pci:v00008086d00000083sv00008086sd00001326* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 1000 BG + +pci:v00008086d00000084* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 1000 [Condor Peak] + +pci:v00008086d00000084sv00008086sd00001215* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 1000 BGN + +pci:v00008086d00000084sv00008086sd00001216* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 1000 BG + +pci:v00008086d00000084sv00008086sd00001315* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 1000 BGN + +pci:v00008086d00000084sv00008086sd00001316* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 1000 BG + +pci:v00008086d00000085* + ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6205 [Taylor Peak] + +pci:v00008086d00000085sv00008086sd00001311* + ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6205 AGN + +pci:v00008086d00000085sv00008086sd00001316* + ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6205 ABG + +pci:v00008086d00000087* + ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N + WiMAX 6250 [Kilmer Peak] + +pci:v00008086d00000087sv00008086sd00001301* + ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N + WiMAX 6250 2x2 AGN + +pci:v00008086d00000087sv00008086sd00001306* + ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N + WiMAX 6250 2x2 ABG + +pci:v00008086d00000087sv00008086sd00001321* + ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N + WiMAX 6250 2x2 AGN + +pci:v00008086d00000087sv00008086sd00001326* + ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N + WiMAX 6250 2x2 ABG + +pci:v00008086d00000089* + ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N + WiMAX 6250 [Kilmer Peak] + +pci:v00008086d00000089sv00008086sd00001311* + ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N + WiMAX 6250 2x2 AGN + +pci:v00008086d00000089sv00008086sd00001316* + ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N + WiMAX 6250 2x2 ABG + +pci:v00008086d0000008A* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 1030 [Rainbow Peak] + +pci:v00008086d0000008Asv00008086sd00005305* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 1030 BGN + +pci:v00008086d0000008Asv00008086sd00005307* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 1030 BG + +pci:v00008086d0000008Asv00008086sd00005325* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 1030 BGN + +pci:v00008086d0000008Asv00008086sd00005327* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 1030 BG + +pci:v00008086d0000008B* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 1030 [Rainbow Peak] + +pci:v00008086d0000008Bsv00008086sd00005315* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 1030 BGN + +pci:v00008086d0000008Bsv00008086sd00005317* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 1030 BG + +pci:v00008086d00000090* + ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6230 [Rainbow Peak] + +pci:v00008086d00000090sv00008086sd00005211* + ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6230 AGN + +pci:v00008086d00000090sv00008086sd00005215* + ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6230 BGN + +pci:v00008086d00000090sv00008086sd00005216* + ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6230 ABG + +pci:v00008086d00000091* + ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6230 [Rainbow Peak] + +pci:v00008086d00000091sv00008086sd00005201* + ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6230 AGN + +pci:v00008086d00000091sv00008086sd00005205* + ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6230 BGN + +pci:v00008086d00000091sv00008086sd00005206* + ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6230 ABG + +pci:v00008086d00000091sv00008086sd00005207* + ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6230 BG + +pci:v00008086d00000091sv00008086sd00005221* + ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6230 AGN + +pci:v00008086d00000091sv00008086sd00005225* + ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6230 BGN + +pci:v00008086d00000091sv00008086sd00005226* + ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6230 ABG + +pci:v00008086d00000100* + ID_PRODUCT_FROM_DATABASE=2nd Generation Core Processor Family DRAM Controller + +pci:v00008086d00000100sv00001028sd000004AA* + ID_PRODUCT_FROM_DATABASE=XPS 8300 + +pci:v00008086d00000100sv00001043sd0000844D* + ID_PRODUCT_FROM_DATABASE=P8P67 Deluxe Motherboard + +pci:v00008086d00000101* + ID_PRODUCT_FROM_DATABASE=Xeon E3-1200/2nd Generation Core Processor Family PCI Express Root Port + +pci:v00008086d00000101sv00001028sd000004B2* + ID_PRODUCT_FROM_DATABASE=Vostro 3350 + +pci:v00008086d00000101sv0000106Bsd000000DC* + ID_PRODUCT_FROM_DATABASE=MacBookPro8,2 [Core i7, 15", 2011] + +pci:v00008086d00000102* + ID_PRODUCT_FROM_DATABASE=2nd Generation Core Processor Family Integrated Graphics Controller + +pci:v00008086d00000104* + ID_PRODUCT_FROM_DATABASE=2nd Generation Core Processor Family DRAM Controller + +pci:v00008086d00000104sv00001028sd000004B2* + ID_PRODUCT_FROM_DATABASE=Vostro 3350 + +pci:v00008086d00000104sv00001028sd000004DA* + ID_PRODUCT_FROM_DATABASE=Vostro 3750 + +pci:v00008086d00000104sv0000106Bsd000000DC* + ID_PRODUCT_FROM_DATABASE=MacBookPro8,2 [Core i7, 15", 2011] + +pci:v00008086d00000105* + ID_PRODUCT_FROM_DATABASE=Xeon E3-1200/2nd Generation Core Processor Family PCI Express Root Port + +pci:v00008086d00000105sv0000106Bsd000000DC* + ID_PRODUCT_FROM_DATABASE=MacBookPro8,2 [Core i7, 15", 2011] + +pci:v00008086d00000106* + ID_PRODUCT_FROM_DATABASE=2nd Generation Core Processor Family Integrated Graphics Controller + +pci:v00008086d00000108* + ID_PRODUCT_FROM_DATABASE=Xeon E3-1200 Processor Family DRAM Controller + +pci:v00008086d00000109* + ID_PRODUCT_FROM_DATABASE=Xeon E3-1200/2nd Generation Core Processor Family PCI Express Root Port + +pci:v00008086d0000010A* + ID_PRODUCT_FROM_DATABASE=Xeon E3-1200 Processor Family Integrated Graphics Controller + +pci:v00008086d0000010B* + ID_PRODUCT_FROM_DATABASE=Xeon E3-1200/2nd Generation Core Processor Family Integrated Graphics Controller + +pci:v00008086d0000010C* + ID_PRODUCT_FROM_DATABASE=Xeon E3-1200/2nd Generation Core Processor Family DRAM Controller + +pci:v00008086d0000010D* + ID_PRODUCT_FROM_DATABASE=Xeon E3-1200/2nd Generation Core Processor Family PCI Express Root Port + +pci:v00008086d0000010E* + ID_PRODUCT_FROM_DATABASE=Xeon E3-1200/2nd Generation Core Processor Family Integrated Graphics Controller + +pci:v00008086d00000112* + ID_PRODUCT_FROM_DATABASE=2nd Generation Core Processor Family Integrated Graphics Controller + +pci:v00008086d00000116* + ID_PRODUCT_FROM_DATABASE=2nd Generation Core Processor Family Integrated Graphics Controller + +pci:v00008086d00000116sv00001028sd000004DA* + ID_PRODUCT_FROM_DATABASE=Vostro 3750 + +pci:v00008086d00000122* + ID_PRODUCT_FROM_DATABASE=2nd Generation Core Processor Family Integrated Graphics Controller + +pci:v00008086d00000126* + ID_PRODUCT_FROM_DATABASE=2nd Generation Core Processor Family Integrated Graphics Controller + +pci:v00008086d00000126sv00001028sd000004CC* + ID_PRODUCT_FROM_DATABASE=Vostro 3350 + +pci:v00008086d00000150* + ID_PRODUCT_FROM_DATABASE=Xeon E3-1200 v2/3rd Gen Core processor DRAM Controller + +pci:v00008086d00000151* + ID_PRODUCT_FROM_DATABASE=Xeon E3-1200 v2/3rd Gen Core processor PCI Express Root Port + +pci:v00008086d00000151sv00001043sd00001477* + ID_PRODUCT_FROM_DATABASE=N56VZ + +pci:v00008086d00000152* + ID_PRODUCT_FROM_DATABASE=Xeon E3-1200 v2/3rd Gen Core processor Graphics Controller + +pci:v00008086d00000153* + ID_PRODUCT_FROM_DATABASE=3rd Gen Core Processor Thermal Subsystem + +pci:v00008086d00000153sv00001043sd00001517* + ID_PRODUCT_FROM_DATABASE=Zenbook Prime UX31A + +pci:v00008086d00000154* + ID_PRODUCT_FROM_DATABASE=3rd Gen Core processor DRAM Controller + +pci:v00008086d00000154sv00001043sd00001477* + ID_PRODUCT_FROM_DATABASE=N56VZ + +pci:v00008086d00000154sv00001043sd00001517* + ID_PRODUCT_FROM_DATABASE=Zenbook Prime UX31A + +pci:v00008086d00000155* + ID_PRODUCT_FROM_DATABASE=Xeon E3-1200 v2/3rd Gen Core processor PCI Express Root Port + +pci:v00008086d00000156* + ID_PRODUCT_FROM_DATABASE=3rd Gen Core processor Graphics Controller + +pci:v00008086d00000158* + ID_PRODUCT_FROM_DATABASE=Xeon E3-1200 v2/Ivy Bridge DRAM Controller + +pci:v00008086d00000159* + ID_PRODUCT_FROM_DATABASE=Xeon E3-1200 v2/3rd Gen Core processor PCI Express Root Port + +pci:v00008086d0000015A* + ID_PRODUCT_FROM_DATABASE=Xeon E3-1200 v2/Ivy Bridge Graphics Controller + +pci:v00008086d0000015C* + ID_PRODUCT_FROM_DATABASE=Xeon E3-1200 v2/3rd Gen Core processor DRAM Controller + +pci:v00008086d0000015D* + ID_PRODUCT_FROM_DATABASE=Xeon E3-1200 v2/3rd Gen Core processor PCI Express Root Port + +pci:v00008086d0000015E* + ID_PRODUCT_FROM_DATABASE=Xeon E3-1200 v2/3rd Gen Core processor Graphics Controller + +pci:v00008086d00000162* + ID_PRODUCT_FROM_DATABASE=Xeon E3-1200 v2/3rd Gen Core processor Graphics Controller + +pci:v00008086d00000166* + ID_PRODUCT_FROM_DATABASE=3rd Gen Core processor Graphics Controller + +pci:v00008086d00000166sv00001043sd00001517* + ID_PRODUCT_FROM_DATABASE=Zenbook Prime UX31A + +pci:v00008086d00000166sv00001043sd00002103* + ID_PRODUCT_FROM_DATABASE=N56VZ + +pci:v00008086d0000016A* + ID_PRODUCT_FROM_DATABASE=Xeon E3-1200 v2/3rd Gen Core processor Graphics Controller + +pci:v00008086d00000172* + ID_PRODUCT_FROM_DATABASE=Xeon E3-1200 v2/3rd Gen Core processor Graphics Controller + +pci:v00008086d00000176* + ID_PRODUCT_FROM_DATABASE=3rd Gen Core processor Graphics Controller + +pci:v00008086d00000309* + ID_PRODUCT_FROM_DATABASE=80303 I/O Processor PCI-to-PCI Bridge + +pci:v00008086d0000030D* + ID_PRODUCT_FROM_DATABASE=80312 I/O Companion Chip PCI-to-PCI Bridge + +pci:v00008086d00000326* + ID_PRODUCT_FROM_DATABASE=6700/6702PXH I/OxAPIC Interrupt Controller A + +pci:v00008086d00000326sv0000103Csd00003208* + ID_PRODUCT_FROM_DATABASE=ProLiant DL140 G2 + +pci:v00008086d00000326sv00001775sd00001100* + ID_PRODUCT_FROM_DATABASE=CR11/VR11 Single Board Computer + +pci:v00008086d00000327* + ID_PRODUCT_FROM_DATABASE=6700PXH I/OxAPIC Interrupt Controller B + +pci:v00008086d00000327sv0000103Csd00003208* + ID_PRODUCT_FROM_DATABASE=ProLiant DL140 G2 + +pci:v00008086d00000327sv00001775sd00001100* + ID_PRODUCT_FROM_DATABASE=CR11/VR11 Single Board Computer + +pci:v00008086d00000329* + ID_PRODUCT_FROM_DATABASE=6700PXH PCI Express-to-PCI Bridge A + +pci:v00008086d0000032A* + ID_PRODUCT_FROM_DATABASE=6700PXH PCI Express-to-PCI Bridge B + +pci:v00008086d0000032C* + ID_PRODUCT_FROM_DATABASE=6702PXH PCI Express-to-PCI Bridge A + +pci:v00008086d00000330* + ID_PRODUCT_FROM_DATABASE=80332 [Dobson] I/O processor (A-Segment Bridge) + +pci:v00008086d00000331* + ID_PRODUCT_FROM_DATABASE=80332 [Dobson] I/O processor (A-Segment IOAPIC) + +pci:v00008086d00000332* + ID_PRODUCT_FROM_DATABASE=80332 [Dobson] I/O processor (B-Segment Bridge) + +pci:v00008086d00000333* + ID_PRODUCT_FROM_DATABASE=80332 [Dobson] I/O processor (B-Segment IOAPIC) + +pci:v00008086d00000334* + ID_PRODUCT_FROM_DATABASE=80332 [Dobson] I/O processor (ATU) + +pci:v00008086d00000335* + ID_PRODUCT_FROM_DATABASE=80331 [Lindsay] I/O processor (PCI-X Bridge) + +pci:v00008086d00000336* + ID_PRODUCT_FROM_DATABASE=80331 [Lindsay] I/O processor (ATU) + +pci:v00008086d00000340* + ID_PRODUCT_FROM_DATABASE=41210 [Lanai] Serial to Parallel PCI Bridge (A-Segment Bridge) + +pci:v00008086d00000341* + ID_PRODUCT_FROM_DATABASE=41210 [Lanai] Serial to Parallel PCI Bridge (B-Segment Bridge) + +pci:v00008086d00000370* + ID_PRODUCT_FROM_DATABASE=80333 Segment-A PCI Express-to-PCI Express Bridge + +pci:v00008086d00000371* + ID_PRODUCT_FROM_DATABASE=80333 A-Bus IOAPIC + +pci:v00008086d00000372* + ID_PRODUCT_FROM_DATABASE=80333 Segment-B PCI Express-to-PCI Express Bridge + +pci:v00008086d00000373* + ID_PRODUCT_FROM_DATABASE=80333 B-Bus IOAPIC + +pci:v00008086d00000374* + ID_PRODUCT_FROM_DATABASE=80333 Address Translation Unit + +pci:v00008086d00000402* + ID_PRODUCT_FROM_DATABASE=Haswell Integrated Graphics Controller + +pci:v00008086d00000406* + ID_PRODUCT_FROM_DATABASE=Haswell Integrated Graphics Controller + +pci:v00008086d0000040A* + ID_PRODUCT_FROM_DATABASE=Haswell Integrated Graphics Controller + +pci:v00008086d00000412* + ID_PRODUCT_FROM_DATABASE=Haswell Integrated Graphics Controller + +pci:v00008086d00000416* + ID_PRODUCT_FROM_DATABASE=Haswell Integrated Graphics Controller + +pci:v00008086d0000041A* + ID_PRODUCT_FROM_DATABASE=Haswell Integrated Graphics Controller + +pci:v00008086d00000436* + ID_PRODUCT_FROM_DATABASE=DH8900CC Null Device + +pci:v00008086d00000438* + ID_PRODUCT_FROM_DATABASE=DH8900CC Series Gigabit Network Connection + +pci:v00008086d0000043A* + ID_PRODUCT_FROM_DATABASE=DH8900CC Series Gigabit Fiber Network Connection + +pci:v00008086d0000043C* + ID_PRODUCT_FROM_DATABASE=DH8900CC Series Gigabit Backplane Network Connection + +pci:v00008086d00000440* + ID_PRODUCT_FROM_DATABASE=DH8900CC Series Gigabit SFP Network Connection + +pci:v00008086d00000482* + ID_PRODUCT_FROM_DATABASE=82375EB/SB PCI to EISA Bridge + +pci:v00008086d00000483* + ID_PRODUCT_FROM_DATABASE=82424TX/ZX [Saturn] CPU to PCI bridge + +pci:v00008086d00000484* + ID_PRODUCT_FROM_DATABASE=82378ZB/IB, 82379AB (SIO, SIO.A) PCI to ISA Bridge + +pci:v00008086d00000486* + ID_PRODUCT_FROM_DATABASE=82425EX/ZX [Aries] PCIset with ISA bridge + +pci:v00008086d000004A3* + ID_PRODUCT_FROM_DATABASE=82434LX/NX [Mercury/Neptune] Processor to PCI bridge + +pci:v00008086d000004D0* + ID_PRODUCT_FROM_DATABASE=82437FX [Triton FX] + +pci:v00008086d00000500* + ID_PRODUCT_FROM_DATABASE=E8870 Processor bus control + +pci:v00008086d00000501* + ID_PRODUCT_FROM_DATABASE=E8870 Memory controller + +pci:v00008086d00000502* + ID_PRODUCT_FROM_DATABASE=E8870 Scalability Port 0 + +pci:v00008086d00000503* + ID_PRODUCT_FROM_DATABASE=E8870 Scalability Port 1 + +pci:v00008086d00000510* + ID_PRODUCT_FROM_DATABASE=E8870IO Hub Interface Port 0 registers (8-bit compatibility port) + +pci:v00008086d00000511* + ID_PRODUCT_FROM_DATABASE=E8870IO Hub Interface Port 1 registers + +pci:v00008086d00000512* + ID_PRODUCT_FROM_DATABASE=E8870IO Hub Interface Port 2 registers + +pci:v00008086d00000513* + ID_PRODUCT_FROM_DATABASE=E8870IO Hub Interface Port 3 registers + +pci:v00008086d00000514* + ID_PRODUCT_FROM_DATABASE=E8870IO Hub Interface Port 4 registers + +pci:v00008086d00000515* + ID_PRODUCT_FROM_DATABASE=E8870IO General SIOH registers + +pci:v00008086d00000516* + ID_PRODUCT_FROM_DATABASE=E8870IO RAS registers + +pci:v00008086d00000530* + ID_PRODUCT_FROM_DATABASE=E8870SP Scalability Port 0 registers + +pci:v00008086d00000531* + ID_PRODUCT_FROM_DATABASE=E8870SP Scalability Port 1 registers + +pci:v00008086d00000532* + ID_PRODUCT_FROM_DATABASE=E8870SP Scalability Port 2 registers + +pci:v00008086d00000533* + ID_PRODUCT_FROM_DATABASE=E8870SP Scalability Port 3 registers + +pci:v00008086d00000534* + ID_PRODUCT_FROM_DATABASE=E8870SP Scalability Port 4 registers + +pci:v00008086d00000535* + ID_PRODUCT_FROM_DATABASE=E8870SP Scalability Port 5 registers + +pci:v00008086d00000536* + ID_PRODUCT_FROM_DATABASE=E8870SP Interleave registers 0 and 1 + +pci:v00008086d00000537* + ID_PRODUCT_FROM_DATABASE=E8870SP Interleave registers 2 and 3 + +pci:v00008086d00000600* + ID_PRODUCT_FROM_DATABASE=RAID Controller + +pci:v00008086d00000600sv00008086sd00000136* + ID_PRODUCT_FROM_DATABASE=SRCU31L + +pci:v00008086d00000600sv00008086sd000001AF* + ID_PRODUCT_FROM_DATABASE=SRCZCR + +pci:v00008086d00000600sv00008086sd000001C1* + ID_PRODUCT_FROM_DATABASE=ICP Vortex GDT8546RZ + +pci:v00008086d00000600sv00008086sd000001F7* + ID_PRODUCT_FROM_DATABASE=SCRU32 + +pci:v00008086d0000061F* + ID_PRODUCT_FROM_DATABASE=80303 I/O Processor + +pci:v00008086d00000700* + ID_PRODUCT_FROM_DATABASE=CE Media Processor A/V Bridge + +pci:v00008086d00000701* + ID_PRODUCT_FROM_DATABASE=CE Media Processor NAND Flash Controller + +pci:v00008086d00000703* + ID_PRODUCT_FROM_DATABASE=CE Media Processor Media Control Unit 1 + +pci:v00008086d00000704* + ID_PRODUCT_FROM_DATABASE=CE Media Processor Video Capture Interface + +pci:v00008086d00000707* + ID_PRODUCT_FROM_DATABASE=CE Media Processor SPI Slave + +pci:v00008086d00000708* + ID_PRODUCT_FROM_DATABASE=CE Media Processor 4100 + +pci:v00008086d00000800* + ID_PRODUCT_FROM_DATABASE=Moorestown SPI Ctrl 0 + +pci:v00008086d00000801* + ID_PRODUCT_FROM_DATABASE=Moorestown SPI Ctrl 1 + +pci:v00008086d00000802* + ID_PRODUCT_FROM_DATABASE=Moorestown I2C 0 + +pci:v00008086d00000803* + ID_PRODUCT_FROM_DATABASE=Moorestown I2C 1 + +pci:v00008086d00000804* + ID_PRODUCT_FROM_DATABASE=Moorestown I2C 2 + +pci:v00008086d00000805* + ID_PRODUCT_FROM_DATABASE=Moorestown Keyboard Ctrl + +pci:v00008086d00000806* + ID_PRODUCT_FROM_DATABASE=Moorestown USB Ctrl + +pci:v00008086d00000807* + ID_PRODUCT_FROM_DATABASE=Moorestown SD Host Ctrl 0 + +pci:v00008086d00000808* + ID_PRODUCT_FROM_DATABASE=Moorestown SD Host Ctrl 1 + +pci:v00008086d00000809* + ID_PRODUCT_FROM_DATABASE=Moorestown NAND Ctrl + +pci:v00008086d0000080A* + ID_PRODUCT_FROM_DATABASE=Moorestown Audio Ctrl + +pci:v00008086d0000080B* + ID_PRODUCT_FROM_DATABASE=Moorestown ISP + +pci:v00008086d0000080C* + ID_PRODUCT_FROM_DATABASE=Moorestown Security Controller + +pci:v00008086d0000080D* + ID_PRODUCT_FROM_DATABASE=Moorestown External Displays + +pci:v00008086d0000080E* + ID_PRODUCT_FROM_DATABASE=Moorestown SCU IPC + +pci:v00008086d0000080F* + ID_PRODUCT_FROM_DATABASE=Moorestown GPIO Controller + +pci:v00008086d00000810* + ID_PRODUCT_FROM_DATABASE=Moorestown Power Management Unit + +pci:v00008086d00000811* + ID_PRODUCT_FROM_DATABASE=Moorestown OTG Ctrl + +pci:v00008086d00000812* + ID_PRODUCT_FROM_DATABASE=Moorestown SPI Ctrl 2 + +pci:v00008086d00000813* + ID_PRODUCT_FROM_DATABASE=Moorestown SC DMA + +pci:v00008086d00000814* + ID_PRODUCT_FROM_DATABASE=Moorestown LPE DMA + +pci:v00008086d00000815* + ID_PRODUCT_FROM_DATABASE=Moorestown SSP0 + +pci:v00008086d00000885* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N + WiMAX 6150 + +pci:v00008086d00000885sv00008086sd00001305* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N + WiMAX 6150 BGN + +pci:v00008086d00000885sv00008086sd00001307* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N + WiMAX 6150 BG + +pci:v00008086d00000885sv00008086sd00001325* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N + WiMAX 6150 BGN + +pci:v00008086d00000885sv00008086sd00001327* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N + WiMAX 6150 BG + +pci:v00008086d00000886* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N + WiMAX 6150 + +pci:v00008086d00000886sv00008086sd00001315* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N + WiMAX 6150 BGN + +pci:v00008086d00000886sv00008086sd00001317* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N + WiMAX 6150 BG + +pci:v00008086d00000887* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 2230 + +pci:v00008086d00000887sv00008086sd00004062* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 2230 BGN + +pci:v00008086d00000887sv00008086sd00004462* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 2230 BGN + +pci:v00008086d00000888* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 2230 + +pci:v00008086d00000888sv00008086sd00004262* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 2230 BGN + +pci:v00008086d0000088E* + ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6235 + +pci:v00008086d0000088Esv00008086sd00004060* + ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6235 AGN + +pci:v00008086d0000088Esv00008086sd00004460* + ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6235 AGN + +pci:v00008086d0000088F* + ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6235 + +pci:v00008086d0000088Fsv00008086sd00004260* + ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6235 AGN + +pci:v00008086d00000890* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 2200 + +pci:v00008086d00000890sv00008086sd00004022* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 2200 BGN + +pci:v00008086d00000890sv00008086sd00004422* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 2200 BGN + +pci:v00008086d00000890sv00008086sd00004822* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 2200 BGN + +pci:v00008086d00000891* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 2200 + +pci:v00008086d00000891sv00008086sd00004222* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 2200 BGN + +pci:v00008086d00000892* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 135 + +pci:v00008086d00000892sv00008086sd00000062* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 135 BGN + +pci:v00008086d00000892sv00008086sd00000462* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 135 BGN + +pci:v00008086d00000893* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 135 + +pci:v00008086d00000893sv00008086sd00000262* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 135 BGN + +pci:v00008086d00000894* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 105 + +pci:v00008086d00000894sv00008086sd00000022* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 105 BGN + +pci:v00008086d00000894sv00008086sd00000422* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 105 BGN + +pci:v00008086d00000894sv00008086sd00000822* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 105 BGN + +pci:v00008086d00000895* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 105 + +pci:v00008086d00000895sv00008086sd00000222* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 105 BGN + +pci:v00008086d00000896* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 130 + +pci:v00008086d00000896sv00008086sd00005005* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 130 BGN + +pci:v00008086d00000896sv00008086sd00005007* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 130 BG + +pci:v00008086d00000896sv00008086sd00005025* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 130 BGN + +pci:v00008086d00000896sv00008086sd00005027* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 130 BG + +pci:v00008086d00000897* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 130 + +pci:v00008086d00000897sv00008086sd00005015* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 130 BGN + +pci:v00008086d00000897sv00008086sd00005017* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 130 BG + +pci:v00008086d000008AE* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 100 + +pci:v00008086d000008AEsv00008086sd00001005* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 100 BGN + +pci:v00008086d000008AEsv00008086sd00001007* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 100 BG + +pci:v00008086d000008AEsv00008086sd00001025* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 100 BGN + +pci:v00008086d000008AEsv00008086sd00001027* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 100 BG + +pci:v00008086d000008AF* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 100 + +pci:v00008086d000008AFsv00008086sd00001015* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 100 BGN + +pci:v00008086d000008AFsv00008086sd00001017* + ID_PRODUCT_FROM_DATABASE=Centrino Wireless-N 100 BG + +pci:v00008086d00000960* + ID_PRODUCT_FROM_DATABASE=80960RP (i960RP) Microprocessor/Bridge + +pci:v00008086d00000962* + ID_PRODUCT_FROM_DATABASE=80960RM (i960RM) Bridge + +pci:v00008086d00000964* + ID_PRODUCT_FROM_DATABASE=80960RP (i960RP) Microprocessor/Bridge + +pci:v00008086d00000A04* + ID_PRODUCT_FROM_DATABASE=Haswell-ULT DRAM Controller + +pci:v00008086d00000A06* + ID_PRODUCT_FROM_DATABASE=Haswell-ULT Integrated Graphics Controller + +pci:v00008086d00000A16* + ID_PRODUCT_FROM_DATABASE=Haswell-ULT Integrated Graphics Controller + +pci:v00008086d00000A22* + ID_PRODUCT_FROM_DATABASE=Haswell-ULT Integrated Graphics Controller + +pci:v00008086d00000A26* + ID_PRODUCT_FROM_DATABASE=Haswell-ULT Integrated Graphics Controller + +pci:v00008086d00000A2A* + ID_PRODUCT_FROM_DATABASE=Haswell-ULT Integrated Graphics Controller + +pci:v00008086d00000BE0* + ID_PRODUCT_FROM_DATABASE=Atom Processor D2xxx/N2xxx Integrated Graphics Controller + +pci:v00008086d00000BE1* + ID_PRODUCT_FROM_DATABASE=Atom Processor D2xxx/N2xxx Integrated Graphics Controller + +pci:v00008086d00000BE2* + ID_PRODUCT_FROM_DATABASE=Atom Processor D2xxx/N2xxx Integrated Graphics Controller + +pci:v00008086d00000BE3* + ID_PRODUCT_FROM_DATABASE=Atom Processor D2xxx/N2xxx Integrated Graphics Controller + +pci:v00008086d00000BE4* + ID_PRODUCT_FROM_DATABASE=Atom Processor D2xxx/N2xxx Integrated Graphics Controller + +pci:v00008086d00000BE5* + ID_PRODUCT_FROM_DATABASE=Atom Processor D2xxx/N2xxx Integrated Graphics Controller + +pci:v00008086d00000BE6* + ID_PRODUCT_FROM_DATABASE=Atom Processor D2xxx/N2xxx Integrated Graphics Controller + +pci:v00008086d00000BE7* + ID_PRODUCT_FROM_DATABASE=Atom Processor D2xxx/N2xxx Integrated Graphics Controller + +pci:v00008086d00000BE8* + ID_PRODUCT_FROM_DATABASE=Atom Processor D2xxx/N2xxx Integrated Graphics Controller + +pci:v00008086d00000BE9* + ID_PRODUCT_FROM_DATABASE=Atom Processor D2xxx/N2xxx Integrated Graphics Controller + +pci:v00008086d00000BEA* + ID_PRODUCT_FROM_DATABASE=Atom Processor D2xxx/N2xxx Integrated Graphics Controller + +pci:v00008086d00000BEB* + ID_PRODUCT_FROM_DATABASE=Atom Processor D2xxx/N2xxx Integrated Graphics Controller + +pci:v00008086d00000BEC* + ID_PRODUCT_FROM_DATABASE=Atom Processor D2xxx/N2xxx Integrated Graphics Controller + +pci:v00008086d00000BED* + ID_PRODUCT_FROM_DATABASE=Atom Processor D2xxx/N2xxx Integrated Graphics Controller + +pci:v00008086d00000BEE* + ID_PRODUCT_FROM_DATABASE=Atom Processor D2xxx/N2xxx Integrated Graphics Controller + +pci:v00008086d00000BEF* + ID_PRODUCT_FROM_DATABASE=Atom Processor D2xxx/N2xxx Integrated Graphics Controller + +pci:v00008086d00000BF0* + ID_PRODUCT_FROM_DATABASE=Atom Processor D2xxx/N2xxx DRAM Controller + +pci:v00008086d00000BF1* + ID_PRODUCT_FROM_DATABASE=Atom Processor D2xxx/N2xxx DRAM Controller + +pci:v00008086d00000BF2* + ID_PRODUCT_FROM_DATABASE=Atom Processor D2xxx/N2xxx DRAM Controller + +pci:v00008086d00000BF3* + ID_PRODUCT_FROM_DATABASE=Atom Processor D2xxx/N2xxx DRAM Controller + +pci:v00008086d00000BF4* + ID_PRODUCT_FROM_DATABASE=Atom Processor D2xxx/N2xxx DRAM Controller + +pci:v00008086d00000BF5* + ID_PRODUCT_FROM_DATABASE=Atom Processor D2xxx/N2xxx DRAM Controller + +pci:v00008086d00000BF6* + ID_PRODUCT_FROM_DATABASE=Atom Processor D2xxx/N2xxx DRAM Controller + +pci:v00008086d00000BF7* + ID_PRODUCT_FROM_DATABASE=Atom Processor D2xxx/N2xxx DRAM Controller + +pci:v00008086d00000C00* + ID_PRODUCT_FROM_DATABASE=Haswell DRAM Controller + +pci:v00008086d00000C01* + ID_PRODUCT_FROM_DATABASE=Haswell PCI Express x16 Controller + +pci:v00008086d00000C04* + ID_PRODUCT_FROM_DATABASE=Haswell DRAM Controller + +pci:v00008086d00000C05* + ID_PRODUCT_FROM_DATABASE=Haswell PCI Express x8 Controller + +pci:v00008086d00000C08* + ID_PRODUCT_FROM_DATABASE=Haswell DRAM Controller + +pci:v00008086d00000C09* + ID_PRODUCT_FROM_DATABASE=Haswell PCI Express x4 Controller + +pci:v00008086d00000C0C* + ID_PRODUCT_FROM_DATABASE=Haswell HD Audio Controller + +pci:v00008086d00000C46* + ID_PRODUCT_FROM_DATABASE=Centerton PCI Express Root Port 1 + +pci:v00008086d00000C47* + ID_PRODUCT_FROM_DATABASE=Centerton PCI Express Root Port 2 + +pci:v00008086d00000C48* + ID_PRODUCT_FROM_DATABASE=Centerton PCI Express Root Port 3 + +pci:v00008086d00000C49* + ID_PRODUCT_FROM_DATABASE=Centerton PCI Express Root Port 4 + +pci:v00008086d00000C4E* + ID_PRODUCT_FROM_DATABASE=Centerton NTB Primary + +pci:v00008086d00000C54* + ID_PRODUCT_FROM_DATABASE=Centerton Internal Management + +pci:v00008086d00000C59* + ID_PRODUCT_FROM_DATABASE=Centerton SMBus 2.0 Controller 0 + +pci:v00008086d00000C5A* + ID_PRODUCT_FROM_DATABASE=Centerton SMBus 2.0 Controller 1 + +pci:v00008086d00000C5F* + ID_PRODUCT_FROM_DATABASE=Centerton UART + +pci:v00008086d00000C60* + ID_PRODUCT_FROM_DATABASE=Centerton Integrated Legacy Bus + +pci:v00008086d00000C70* + ID_PRODUCT_FROM_DATABASE=Centerton Internal Fabric + +pci:v00008086d00000C71* + ID_PRODUCT_FROM_DATABASE=Centerton Internal Fabric + +pci:v00008086d00000C72* + ID_PRODUCT_FROM_DATABASE=Centerton Internal Fabric + +pci:v00008086d00000C73* + ID_PRODUCT_FROM_DATABASE=Centerton Internal Fabric + +pci:v00008086d00000C74* + ID_PRODUCT_FROM_DATABASE=Centerton Internal Fabric + +pci:v00008086d00000C75* + ID_PRODUCT_FROM_DATABASE=Centerton Internal Fabric + +pci:v00008086d00000C76* + ID_PRODUCT_FROM_DATABASE=Centerton Internal Fabric + +pci:v00008086d00000C77* + ID_PRODUCT_FROM_DATABASE=Centerton Internal Fabric + +pci:v00008086d00000C78* + ID_PRODUCT_FROM_DATABASE=Centerton Internal Fabric + +pci:v00008086d00000C79* + ID_PRODUCT_FROM_DATABASE=Centerton Internal Fabric + +pci:v00008086d00000C7A* + ID_PRODUCT_FROM_DATABASE=Centerton Internal Fabric + +pci:v00008086d00000C7B* + ID_PRODUCT_FROM_DATABASE=Centerton Internal Fabric + +pci:v00008086d00000C7C* + ID_PRODUCT_FROM_DATABASE=Centerton Internal Fabric + +pci:v00008086d00000C7D* + ID_PRODUCT_FROM_DATABASE=Centerton Internal Fabric + +pci:v00008086d00000C7E* + ID_PRODUCT_FROM_DATABASE=Centerton Internal Fabric + +pci:v00008086d00000C7F* + ID_PRODUCT_FROM_DATABASE=Centerton Internal Fabric + +pci:v00008086d00000D00* + ID_PRODUCT_FROM_DATABASE=Crystal Well DRAM Controller + +pci:v00008086d00000D01* + ID_PRODUCT_FROM_DATABASE=Crystal Well PCI Express x16 Controller + +pci:v00008086d00000D04* + ID_PRODUCT_FROM_DATABASE=Crystal Well DRAM Controller + +pci:v00008086d00000D05* + ID_PRODUCT_FROM_DATABASE=Crystal Well PCI Express x8 Controller + +pci:v00008086d00000D09* + ID_PRODUCT_FROM_DATABASE=Crystal Well PCI Express x4 Controller + +pci:v00008086d00000D0C* + ID_PRODUCT_FROM_DATABASE=Crystal Well HD Audio Controller + +pci:v00008086d00000D16* + ID_PRODUCT_FROM_DATABASE=Crystal Well Integrated Graphics Controller + +pci:v00008086d00000D26* + ID_PRODUCT_FROM_DATABASE=Crystal Well Integrated Graphics Controller + +pci:v00008086d00000D36* + ID_PRODUCT_FROM_DATABASE=Crystal Well Integrated Graphics Controller + +pci:v00008086d00000E00* + ID_PRODUCT_FROM_DATABASE=Ivytown DMI2 + +pci:v00008086d00000E01* + ID_PRODUCT_FROM_DATABASE=Ivytown PCI Express Root Port in DMI2 Mode + +pci:v00008086d00000E02* + ID_PRODUCT_FROM_DATABASE=Ivytown PCI Express Root Port 1a + +pci:v00008086d00000E03* + ID_PRODUCT_FROM_DATABASE=Ivytown PCI Express Root Port 1b + +pci:v00008086d00000E04* + ID_PRODUCT_FROM_DATABASE=Ivytown PCI Express Root Port 2a + +pci:v00008086d00000E05* + ID_PRODUCT_FROM_DATABASE=Ivytown PCI Express Root Port 2b + +pci:v00008086d00000E06* + ID_PRODUCT_FROM_DATABASE=Ivytown PCI Express Root Port 2c + +pci:v00008086d00000E07* + ID_PRODUCT_FROM_DATABASE=Ivytown PCI Express Root Port 2d + +pci:v00008086d00000E08* + ID_PRODUCT_FROM_DATABASE=Ivytown PCI Express Root Port 3a + +pci:v00008086d00000E09* + ID_PRODUCT_FROM_DATABASE=Ivytown PCI Express Root Port 3b + +pci:v00008086d00000E0A* + ID_PRODUCT_FROM_DATABASE=Ivytown PCI Express Root Port 3c + +pci:v00008086d00000E0B* + ID_PRODUCT_FROM_DATABASE=Ivytown PCI Express Root Port 3d + +pci:v00008086d00000E1C* + ID_PRODUCT_FROM_DATABASE=Ivytown Debug and Error Injection Related Registers + +pci:v00008086d00000E1D* + ID_PRODUCT_FROM_DATABASE=Ivytown R2PCIe + +pci:v00008086d00000E1E* + ID_PRODUCT_FROM_DATABASE=Ivytown Semaphore and Scratchpad Configuration Registers + +pci:v00008086d00000E1F* + ID_PRODUCT_FROM_DATABASE=Ivytown Semaphore and Scratchpad Configuration Registers + +pci:v00008086d00000E20* + ID_PRODUCT_FROM_DATABASE=Ivytown Crystal Beach DMA Channel 0 + +pci:v00008086d00000E21* + ID_PRODUCT_FROM_DATABASE=Ivytown Crystal Beach DMA Channel 1 + +pci:v00008086d00000E22* + ID_PRODUCT_FROM_DATABASE=Ivytown Crystal Beach DMA Channel 2 + +pci:v00008086d00000E23* + ID_PRODUCT_FROM_DATABASE=Ivytown Crystal Beach DMA Channel 3 + +pci:v00008086d00000E24* + ID_PRODUCT_FROM_DATABASE=Ivytown Crystal Beach DMA Channel 4 + +pci:v00008086d00000E25* + ID_PRODUCT_FROM_DATABASE=Ivytown Crystal Beach DMA Channel 5 + +pci:v00008086d00000E26* + ID_PRODUCT_FROM_DATABASE=Ivytown Crystal Beach DMA Channel 6 + +pci:v00008086d00000E27* + ID_PRODUCT_FROM_DATABASE=Ivytown Crystal Beach DMA Channel 7 + +pci:v00008086d00000E28* + ID_PRODUCT_FROM_DATABASE=Ivytown VTd/Memory Map/Misc + +pci:v00008086d00000E29* + ID_PRODUCT_FROM_DATABASE=Ivytown Memory Hotplug + +pci:v00008086d00000E2A* + ID_PRODUCT_FROM_DATABASE=Ivytown IIO RAS + +pci:v00008086d00000E2C* + ID_PRODUCT_FROM_DATABASE=Ivytown IOAPIC + +pci:v00008086d00000E2E* + ID_PRODUCT_FROM_DATABASE=Ivytown CBDMA + +pci:v00008086d00000E2F* + ID_PRODUCT_FROM_DATABASE=Ivytown CBDMA + +pci:v00008086d00000E30* + ID_PRODUCT_FROM_DATABASE=Ivytown Home Agent 0 + +pci:v00008086d00000E32* + ID_PRODUCT_FROM_DATABASE=Ivytown QPI Link 0 + +pci:v00008086d00000E33* + ID_PRODUCT_FROM_DATABASE=Ivytown QPI Link 1 + +pci:v00008086d00000E34* + ID_PRODUCT_FROM_DATABASE=Ivytown PCI Express Ring Performance Monitoring + +pci:v00008086d00000E36* + ID_PRODUCT_FROM_DATABASE=Ivytown QPI Ring Performance Ring Monitoring + +pci:v00008086d00000E37* + ID_PRODUCT_FROM_DATABASE=Ivytown QPI Ring Performance Ring Monitoring + +pci:v00008086d00000E38* + ID_PRODUCT_FROM_DATABASE=Ivytown Home Agent 1 + +pci:v00008086d00000E3A* + ID_PRODUCT_FROM_DATABASE=Ivytown QPI Link 2 + +pci:v00008086d00000E3E* + ID_PRODUCT_FROM_DATABASE=Ivytown QPI Ring Performance Ring Monitoring + +pci:v00008086d00000E3F* + ID_PRODUCT_FROM_DATABASE=Ivytown QPI Ring Performance Ring Monitoring + +pci:v00008086d00000E40* + ID_PRODUCT_FROM_DATABASE=Ivytown QPI Link 2 + +pci:v00008086d00000E41* + ID_PRODUCT_FROM_DATABASE=Ivytown QPI Ring Registers + +pci:v00008086d00000E43* + ID_PRODUCT_FROM_DATABASE=Ivytown QPI Link Reut 2 + +pci:v00008086d00000E44* + ID_PRODUCT_FROM_DATABASE=Ivytown QPI Link Reut 2 + +pci:v00008086d00000E60* + ID_PRODUCT_FROM_DATABASE=Ivytown Home Agent 1 + +pci:v00008086d00000E68* + ID_PRODUCT_FROM_DATABASE=Ivytown Integrated Memory Controller 1 Target Address/Thermal Registers + +pci:v00008086d00000E6A* + ID_PRODUCT_FROM_DATABASE=Ivytown Integrated Memory Controller 1 Channel Target Address Decoder Registers + +pci:v00008086d00000E6B* + ID_PRODUCT_FROM_DATABASE=Ivytown Integrated Memory Controller 1 Channel Target Address Decoder Registers + +pci:v00008086d00000E6C* + ID_PRODUCT_FROM_DATABASE=Ivytown Integrated Memory Controller 1 Channel Target Address Decoder Registers + +pci:v00008086d00000E6D* + ID_PRODUCT_FROM_DATABASE=Ivytown Integrated Memory Controller 1 Channel Target Address Decoder Registers + +pci:v00008086d00000E71* + ID_PRODUCT_FROM_DATABASE=Ivytown Integrated Memory Controller 0 RAS Registers + +pci:v00008086d00000E79* + ID_PRODUCT_FROM_DATABASE=Ivytown Integrated Memory Controller 1 RAS Registers + +pci:v00008086d00000E80* + ID_PRODUCT_FROM_DATABASE=Ivytown QPI Link 0 + +pci:v00008086d00000E81* + ID_PRODUCT_FROM_DATABASE=Ivytown QPI Ring Registers + +pci:v00008086d00000E83* + ID_PRODUCT_FROM_DATABASE=Ivytown QPI Link Reut 0 + +pci:v00008086d00000E84* + ID_PRODUCT_FROM_DATABASE=Ivytown QPI Link Reut 0 + +pci:v00008086d00000E90* + ID_PRODUCT_FROM_DATABASE=Ivytown QPI Link 1 + +pci:v00008086d00000E93* + ID_PRODUCT_FROM_DATABASE=Ivytown QPI Link 1 + +pci:v00008086d00000E94* + ID_PRODUCT_FROM_DATABASE=Ivytown QPI Link Reut 1 + +pci:v00008086d00000EA0* + ID_PRODUCT_FROM_DATABASE=Ivytown Home Agent 0 + +pci:v00008086d00000EA8* + ID_PRODUCT_FROM_DATABASE=Ivytown Integrated Memory Controller 0 Target Address/Thermal Registers + +pci:v00008086d00000EAA* + ID_PRODUCT_FROM_DATABASE=Ivytown Integrated Memory Controller 0 Channel Target Address Decoder Registers + +pci:v00008086d00000EAB* + ID_PRODUCT_FROM_DATABASE=Ivytown Integrated Memory Controller 0 Channel Target Address Decoder Registers + +pci:v00008086d00000EAC* + ID_PRODUCT_FROM_DATABASE=Ivytown Integrated Memory Controller 0 Channel Target Address Decoder Registers + +pci:v00008086d00000EAD* + ID_PRODUCT_FROM_DATABASE=Ivytown Integrated Memory Controller 0 Channel Target Address Decoder Registers + +pci:v00008086d00000EB0* + ID_PRODUCT_FROM_DATABASE=Ivytown Integrated Memory Controller 1 Channel 0-3 Thermal Control 0 + +pci:v00008086d00000EB1* + ID_PRODUCT_FROM_DATABASE=Ivytown Integrated Memory Controller 1 Channel 0-3 Thermal Control 1 + +pci:v00008086d00000EB2* + ID_PRODUCT_FROM_DATABASE=Ivytown Integrated Memory Controller 1 Channel 0-3 ERROR Registers 0 + +pci:v00008086d00000EB3* + ID_PRODUCT_FROM_DATABASE=Ivytown Integrated Memory Controller 1 Channel 0-3 ERROR Registers 1 + +pci:v00008086d00000EB4* + ID_PRODUCT_FROM_DATABASE=Ivytown Integrated Memory Controller 1 Channel 0-3 Thermal Control 2 + +pci:v00008086d00000EB5* + ID_PRODUCT_FROM_DATABASE=Ivytown Integrated Memory Controller 1 Channel 0-3 Thermal Control 3 + +pci:v00008086d00000EB7* + ID_PRODUCT_FROM_DATABASE=Ivytown Integrated Memory Controller 1 Channel 0-3 ERROR Registers 2 + +pci:v00008086d00000EC0* + ID_PRODUCT_FROM_DATABASE=Ivytown Power Control Unit 0 + +pci:v00008086d00000EC1* + ID_PRODUCT_FROM_DATABASE=Ivytown Power Control Unit 1 + +pci:v00008086d00000EC2* + ID_PRODUCT_FROM_DATABASE=Ivytown Power Control Unit 2 + +pci:v00008086d00000EC3* + ID_PRODUCT_FROM_DATABASE=Ivytown Power Control Unit 3 + +pci:v00008086d00000EC4* + ID_PRODUCT_FROM_DATABASE=Ivytown Power Control Unit 4 + +pci:v00008086d00000EC8* + ID_PRODUCT_FROM_DATABASE=Ivytown System Address Decoder + +pci:v00008086d00000EC9* + ID_PRODUCT_FROM_DATABASE=Ivytown Broadcast Registers + +pci:v00008086d00000ECA* + ID_PRODUCT_FROM_DATABASE=Ivytown Broadcast Registers + +pci:v00008086d00000ED8* + ID_PRODUCT_FROM_DATABASE=Ivytown DDRIO + +pci:v00008086d00000ED9* + ID_PRODUCT_FROM_DATABASE=Ivytown DDRIO + +pci:v00008086d00000EDC* + ID_PRODUCT_FROM_DATABASE=Ivytown DDRIO + +pci:v00008086d00000EDD* + ID_PRODUCT_FROM_DATABASE=Ivytown DDRIO + +pci:v00008086d00000EDE* + ID_PRODUCT_FROM_DATABASE=Ivytown DDRIO + +pci:v00008086d00000EDF* + ID_PRODUCT_FROM_DATABASE=Ivytown DDRIO + +pci:v00008086d00000EE0* + ID_PRODUCT_FROM_DATABASE=Ivytown Unicast Registers + +pci:v00008086d00000EE1* + ID_PRODUCT_FROM_DATABASE=Ivytown Unicast Registers + +pci:v00008086d00000EE2* + ID_PRODUCT_FROM_DATABASE=Ivytown Unicast Registers + +pci:v00008086d00000EE3* + ID_PRODUCT_FROM_DATABASE=Ivytown Unicast Registers + +pci:v00008086d00000EE4* + ID_PRODUCT_FROM_DATABASE=Ivytown Unicast Registers + +pci:v00008086d00000EE5* + ID_PRODUCT_FROM_DATABASE=Ivytown Unicast Registers + +pci:v00008086d00000EE6* + ID_PRODUCT_FROM_DATABASE=Ivytown Unicast Registers + +pci:v00008086d00000EE7* + ID_PRODUCT_FROM_DATABASE=Ivytown Unicast Registers + +pci:v00008086d00000EE8* + ID_PRODUCT_FROM_DATABASE=Ivytown Unicast Registers + +pci:v00008086d00000EE9* + ID_PRODUCT_FROM_DATABASE=Ivytown Unicast Registers + +pci:v00008086d00000EEA* + ID_PRODUCT_FROM_DATABASE=Ivytown Unicast Registers + +pci:v00008086d00000EEB* + ID_PRODUCT_FROM_DATABASE=Ivytown Unicast Registers + +pci:v00008086d00000EEC* + ID_PRODUCT_FROM_DATABASE=Ivytown Unicast Registers + +pci:v00008086d00000EED* + ID_PRODUCT_FROM_DATABASE=Ivytown Unicast Registers + +pci:v00008086d00000EEE* + ID_PRODUCT_FROM_DATABASE=Ivytown Unicast Registers + +pci:v00008086d00000EF0* + ID_PRODUCT_FROM_DATABASE=Ivytown Integrated Memory Controller 0 Channel 0-3 Thermal Control 0 + +pci:v00008086d00000EF1* + ID_PRODUCT_FROM_DATABASE=Ivytown Integrated Memory Controller 0 Channel 0-3 Thermal Control 1 + +pci:v00008086d00000EF2* + ID_PRODUCT_FROM_DATABASE=Ivytown Integrated Memory Controller 0 Channel 0-3 ERROR Registers 0 + +pci:v00008086d00000EF3* + ID_PRODUCT_FROM_DATABASE=Ivytown Integrated Memory Controller 0 Channel 0-3 ERROR Registers 2 + +pci:v00008086d00000EF4* + ID_PRODUCT_FROM_DATABASE=Ivytown Integrated Memory Controller 0 Channel 0-3 Thermal Control 2 + +pci:v00008086d00000EF5* + ID_PRODUCT_FROM_DATABASE=Ivytown Integrated Memory Controller 0 Channel 0-3 Thermal Control 3 + +pci:v00008086d00000EF7* + ID_PRODUCT_FROM_DATABASE=Ivytown Integrated Memory Controller 0 Channel 0-3 ERROR Registers 3 + +pci:v00008086d00000EF8* + ID_PRODUCT_FROM_DATABASE=Ivytown DDRIO + +pci:v00008086d00000EF9* + ID_PRODUCT_FROM_DATABASE=Ivytown DDRIO + +pci:v00008086d00000EFA* + ID_PRODUCT_FROM_DATABASE=Ivytown DDRIO + +pci:v00008086d00000EFB* + ID_PRODUCT_FROM_DATABASE=Ivytown DDRIO + +pci:v00008086d00000EFC* + ID_PRODUCT_FROM_DATABASE=Ivytown DDRIO + +pci:v00008086d00000EFD* + ID_PRODUCT_FROM_DATABASE=Ivytown DDRIO + +pci:v00008086d00000F00* + ID_PRODUCT_FROM_DATABASE=ValleyView SSA-CUnit + +pci:v00008086d00000F01* + ID_PRODUCT_FROM_DATABASE=ValleyView SSA-CUnit + +pci:v00008086d00000F02* + ID_PRODUCT_FROM_DATABASE=ValleyView SSA-CUnit + +pci:v00008086d00000F03* + ID_PRODUCT_FROM_DATABASE=ValleyView SSA-CUnit + +pci:v00008086d00000F04* + ID_PRODUCT_FROM_DATABASE=ValleyView High Definition Audio Controller + +pci:v00008086d00000F05* + ID_PRODUCT_FROM_DATABASE=ValleyView High Definition Audio Controller + +pci:v00008086d00000F06* + ID_PRODUCT_FROM_DATABASE=ValleyView LPIO1 DMA Controller + +pci:v00008086d00000F07* + ID_PRODUCT_FROM_DATABASE=ValleyView LPIO1 DMA Controller + +pci:v00008086d00000F08* + ID_PRODUCT_FROM_DATABASE=ValleyView LPIO1 PWM Controller + +pci:v00008086d00000F09* + ID_PRODUCT_FROM_DATABASE=ValleyView LPIO1 PWM Controller + +pci:v00008086d00000F0A* + ID_PRODUCT_FROM_DATABASE=ValleyView LPIO1 HSUART Controller #1 + +pci:v00008086d00000F0B* + ID_PRODUCT_FROM_DATABASE=ValleyView LPIO1 HSUART Controller #1 + +pci:v00008086d00000F0C* + ID_PRODUCT_FROM_DATABASE=ValleyView LPIO1 HSUART Controller #2 + +pci:v00008086d00000F0D* + ID_PRODUCT_FROM_DATABASE=ValleyView LPIO1 HSUART Controller #2 + +pci:v00008086d00000F0E* + ID_PRODUCT_FROM_DATABASE=ValleyView LPIO1 SPI Controller + +pci:v00008086d00000F0F* + ID_PRODUCT_FROM_DATABASE=ValleyView LPIO1 SPI Controller + +pci:v00008086d00000F10* + ID_PRODUCT_FROM_DATABASE=ValleyView LPIO1 Controller + +pci:v00008086d00000F11* + ID_PRODUCT_FROM_DATABASE=ValleyView LPIO1 Controller + +pci:v00008086d00000F12* + ID_PRODUCT_FROM_DATABASE=ValleyView SMBus Controller + +pci:v00008086d00000F13* + ID_PRODUCT_FROM_DATABASE=ValleyView SMBus Controller + +pci:v00008086d00000F14* + ID_PRODUCT_FROM_DATABASE=ValleyView SDIO Controller + +pci:v00008086d00000F15* + ID_PRODUCT_FROM_DATABASE=ValleyView SDIO Controller + +pci:v00008086d00000F16* + ID_PRODUCT_FROM_DATABASE=ValleyView SDIO Controller + +pci:v00008086d00000F17* + ID_PRODUCT_FROM_DATABASE=ValleyView SDIO Controller + +pci:v00008086d00000F18* + ID_PRODUCT_FROM_DATABASE=ValleyView SEC + +pci:v00008086d00000F19* + ID_PRODUCT_FROM_DATABASE=ValleyView SEC + +pci:v00008086d00000F1A* + ID_PRODUCT_FROM_DATABASE=ValleyView SEC + +pci:v00008086d00000F1B* + ID_PRODUCT_FROM_DATABASE=ValleyView SEC + +pci:v00008086d00000F1C* + ID_PRODUCT_FROM_DATABASE=ValleyView Power Control Unit + +pci:v00008086d00000F1D* + ID_PRODUCT_FROM_DATABASE=ValleyView Power Control Unit + +pci:v00008086d00000F1E* + ID_PRODUCT_FROM_DATABASE=ValleyView Power Control Unit + +pci:v00008086d00000F1F* + ID_PRODUCT_FROM_DATABASE=ValleyView Power Control Unit + +pci:v00008086d00000F20* + ID_PRODUCT_FROM_DATABASE=ValleyView 4-Port SATA Storage Controller + +pci:v00008086d00000F21* + ID_PRODUCT_FROM_DATABASE=ValleyView 4-Port SATA Storage Controller + +pci:v00008086d00000F22* + ID_PRODUCT_FROM_DATABASE=ValleyView 6-Port SATA AHCI Controller + +pci:v00008086d00000F23* + ID_PRODUCT_FROM_DATABASE=ValleyView 6-Port SATA AHCI Controller + +pci:v00008086d00000F24* + ID_PRODUCT_FROM_DATABASE=ValleyView SATA RAID Storage Controller + +pci:v00008086d00000F25* + ID_PRODUCT_FROM_DATABASE=ValleyView SATA RAID Storage Controller + +pci:v00008086d00000F26* + ID_PRODUCT_FROM_DATABASE=ValleyView 2-Port SATA Storage Controller + +pci:v00008086d00000F27* + ID_PRODUCT_FROM_DATABASE=ValleyView 2-Port SATA Storage Controller + +pci:v00008086d00000F28* + ID_PRODUCT_FROM_DATABASE=ValleyView LPE Audio Controller + +pci:v00008086d00000F29* + ID_PRODUCT_FROM_DATABASE=ValleyView LPE Audio Controller + +pci:v00008086d00000F2A* + ID_PRODUCT_FROM_DATABASE=ValleyView LPE Audio Controller + +pci:v00008086d00000F2B* + ID_PRODUCT_FROM_DATABASE=ValleyView LPE Audio Controller + +pci:v00008086d00000F2E* + ID_PRODUCT_FROM_DATABASE=ValleyView SATA RAID Storage Controller + +pci:v00008086d00000F2F* + ID_PRODUCT_FROM_DATABASE=ValleyView SATA RAID Storage Controller + +pci:v00008086d00000F30* + ID_PRODUCT_FROM_DATABASE=ValleyView Gen7 + +pci:v00008086d00000F31* + ID_PRODUCT_FROM_DATABASE=ValleyView Gen7 + +pci:v00008086d00000F32* + ID_PRODUCT_FROM_DATABASE=ValleyView Gen7 + +pci:v00008086d00000F33* + ID_PRODUCT_FROM_DATABASE=ValleyView Gen7 + +pci:v00008086d00000F34* + ID_PRODUCT_FROM_DATABASE=ValleyView USB Enhanced Host Controller + +pci:v00008086d00000F35* + ID_PRODUCT_FROM_DATABASE=ValleyView USB xHCI Host Controller + +pci:v00008086d00000F36* + ID_PRODUCT_FROM_DATABASE=ValleyView USB xHCI Host Controller + +pci:v00008086d00000F37* + ID_PRODUCT_FROM_DATABASE=ValleyView OTG + +pci:v00008086d00000F38* + ID_PRODUCT_FROM_DATABASE=ValleyView ISP + +pci:v00008086d00000F39* + ID_PRODUCT_FROM_DATABASE=ValleyView ISP + +pci:v00008086d00000F3A* + ID_PRODUCT_FROM_DATABASE=ValleyView ISP + +pci:v00008086d00000F3B* + ID_PRODUCT_FROM_DATABASE=ValleyView ISP + +pci:v00008086d00000F3C* + ID_PRODUCT_FROM_DATABASE=ValleyView ISP + +pci:v00008086d00000F3D* + ID_PRODUCT_FROM_DATABASE=ValleyView ISP + +pci:v00008086d00000F3E* + ID_PRODUCT_FROM_DATABASE=ValleyView ISP + +pci:v00008086d00000F3F* + ID_PRODUCT_FROM_DATABASE=ValleyView ISP + +pci:v00008086d00000F40* + ID_PRODUCT_FROM_DATABASE=ValleyView LPIO2 DMA Controller + +pci:v00008086d00000F41* + ID_PRODUCT_FROM_DATABASE=ValleyView LPIO2 I2C Controller #1 + +pci:v00008086d00000F42* + ID_PRODUCT_FROM_DATABASE=ValleyView LPIO2 I2C Controller #2 + +pci:v00008086d00000F43* + ID_PRODUCT_FROM_DATABASE=ValleyView LPIO2 I2C Controller #3 + +pci:v00008086d00000F44* + ID_PRODUCT_FROM_DATABASE=ValleyView LPIO2 I2C Controller #4 + +pci:v00008086d00000F45* + ID_PRODUCT_FROM_DATABASE=ValleyView LPIO2 I2C Controller #5 + +pci:v00008086d00000F46* + ID_PRODUCT_FROM_DATABASE=ValleyView LPIO2 I2C Controller #6 + +pci:v00008086d00000F47* + ID_PRODUCT_FROM_DATABASE=ValleyView LPIO2 I2C Controller #7 + +pci:v00008086d00000F48* + ID_PRODUCT_FROM_DATABASE=ValleyView PCI Express Root Port + +pci:v00008086d00000F49* + ID_PRODUCT_FROM_DATABASE=ValleyView PCI Express Root Port + +pci:v00008086d00000F4A* + ID_PRODUCT_FROM_DATABASE=ValleyView PCI Express Root Port + +pci:v00008086d00000F4B* + ID_PRODUCT_FROM_DATABASE=ValleyView PCI Express Root Port + +pci:v00008086d00000F4C* + ID_PRODUCT_FROM_DATABASE=ValleyView PCI Express Root Port + +pci:v00008086d00000F4D* + ID_PRODUCT_FROM_DATABASE=ValleyView PCI Express Root Port + +pci:v00008086d00000F4E* + ID_PRODUCT_FROM_DATABASE=ValleyView PCI Express Root Port + +pci:v00008086d00000F4F* + ID_PRODUCT_FROM_DATABASE=ValleyView PCI Express Root Port + +pci:v00008086d00000F50* + ID_PRODUCT_FROM_DATABASE=ValleyView MIPI-HSI Controller + +pci:v00008086d00001000* + ID_PRODUCT_FROM_DATABASE=82542 Gigabit Ethernet Controller (Fiber) + +pci:v00008086d00001000sv00000E11sd0000B0DF* + ID_PRODUCT_FROM_DATABASE=NC6132 Gigabit Ethernet Adapter (1000-SX) + +pci:v00008086d00001000sv00000E11sd0000B0E0* + ID_PRODUCT_FROM_DATABASE=NC6133 Gigabit Ethernet Adapter (1000-LX) + +pci:v00008086d00001000sv00000E11sd0000B123* + ID_PRODUCT_FROM_DATABASE=NC6134 Gigabit Ethernet Adapter (1000-LX) + +pci:v00008086d00001000sv00001014sd00000119* + ID_PRODUCT_FROM_DATABASE=Netfinity Gigabit Ethernet SX Adapter + +pci:v00008086d00001000sv00008086sd00001000* + ID_PRODUCT_FROM_DATABASE=PRO/1000 Gigabit Server Adapter + +pci:v00008086d00001001* + ID_PRODUCT_FROM_DATABASE=82543GC Gigabit Ethernet Controller (Fiber) + +pci:v00008086d00001001sv00000E11sd0000004A* + ID_PRODUCT_FROM_DATABASE=NC6136 Gigabit Server Adapter + +pci:v00008086d00001001sv00001014sd000001EA* + ID_PRODUCT_FROM_DATABASE=Netfinity Gigabit Ethernet SX Adapter + +pci:v00008086d00001001sv00008086sd00001002* + ID_PRODUCT_FROM_DATABASE=PRO/1000 F Server Adapter + +pci:v00008086d00001001sv00008086sd00001003* + ID_PRODUCT_FROM_DATABASE=PRO/1000 F Server Adapter + +pci:v00008086d00001002* + ID_PRODUCT_FROM_DATABASE=Pro 100 LAN+Modem 56 Cardbus II + +pci:v00008086d00001002sv00008086sd0000200E* + ID_PRODUCT_FROM_DATABASE=Pro 100 LAN+Modem 56 Cardbus II + +pci:v00008086d00001002sv00008086sd00002013* + ID_PRODUCT_FROM_DATABASE=Pro 100 SR Mobile Combo Adapter + +pci:v00008086d00001002sv00008086sd00002017* + ID_PRODUCT_FROM_DATABASE=Pro 100 S Combo Mobile Adapter + +pci:v00008086d00001004* + ID_PRODUCT_FROM_DATABASE=82543GC Gigabit Ethernet Controller (Copper) + +pci:v00008086d00001004sv00000E11sd00000049* + ID_PRODUCT_FROM_DATABASE=NC7132 Gigabit Upgrade Module + +pci:v00008086d00001004sv00000E11sd0000B1A4* + ID_PRODUCT_FROM_DATABASE=NC7131 Gigabit Server Adapter + +pci:v00008086d00001004sv00001014sd000010F2* + ID_PRODUCT_FROM_DATABASE=Gigabit Ethernet Server Adapter + +pci:v00008086d00001004sv00008086sd00001004* + ID_PRODUCT_FROM_DATABASE=PRO/1000 T Server Adapter + +pci:v00008086d00001004sv00008086sd00002004* + ID_PRODUCT_FROM_DATABASE=PRO/1000 T Server Adapter + +pci:v00008086d00001008* + ID_PRODUCT_FROM_DATABASE=82544EI Gigabit Ethernet Controller (Copper) + +pci:v00008086d00001008sv00001014sd00000269* + ID_PRODUCT_FROM_DATABASE=iSeries 1000/100/10 Ethernet Adapter + +pci:v00008086d00001008sv00001028sd0000011B* + ID_PRODUCT_FROM_DATABASE=PowerEdge 1650/2550 + +pci:v00008086d00001008sv00001028sd0000011C* + ID_PRODUCT_FROM_DATABASE=PRO/1000 XT Network Connection + +pci:v00008086d00001008sv00008086sd00001107* + ID_PRODUCT_FROM_DATABASE=PRO/1000 XT Server Adapter + +pci:v00008086d00001008sv00008086sd00002107* + ID_PRODUCT_FROM_DATABASE=PRO/1000 XT Server Adapter + +pci:v00008086d00001008sv00008086sd00002110* + ID_PRODUCT_FROM_DATABASE=PRO/1000 XT Desktop Adapter + +pci:v00008086d00001008sv00008086sd00003108* + ID_PRODUCT_FROM_DATABASE=PRO/1000 XT Network Connection + +pci:v00008086d00001009* + ID_PRODUCT_FROM_DATABASE=82544EI Gigabit Ethernet Controller (Fiber) + +pci:v00008086d00001009sv00001014sd00000268* + ID_PRODUCT_FROM_DATABASE=iSeries Gigabit Ethernet Adapter + +pci:v00008086d00001009sv00008086sd00001109* + ID_PRODUCT_FROM_DATABASE=PRO/1000 XF Server Adapter + +pci:v00008086d00001009sv00008086sd00002109* + ID_PRODUCT_FROM_DATABASE=PRO/1000 XF Server Adapter + +pci:v00008086d0000100A* + ID_PRODUCT_FROM_DATABASE=82540EM Gigabit Ethernet Controller + +pci:v00008086d0000100C* + ID_PRODUCT_FROM_DATABASE=82544GC Gigabit Ethernet Controller (Copper) + +pci:v00008086d0000100Csv00008086sd00001112* + ID_PRODUCT_FROM_DATABASE=PRO/1000 T Desktop Adapter + +pci:v00008086d0000100Csv00008086sd00002112* + ID_PRODUCT_FROM_DATABASE=PRO/1000 T Desktop Adapter + +pci:v00008086d0000100D* + ID_PRODUCT_FROM_DATABASE=82544GC Gigabit Ethernet Controller (LOM) + +pci:v00008086d0000100Dsv00001028sd00000123* + ID_PRODUCT_FROM_DATABASE=PRO/1000 XT Network Connection + +pci:v00008086d0000100Dsv00001079sd0000891F* + ID_PRODUCT_FROM_DATABASE=82544GC Based Network Connection + +pci:v00008086d0000100Dsv00004C53sd00001080* + ID_PRODUCT_FROM_DATABASE=CT8 mainboard + +pci:v00008086d0000100Dsv00008086sd0000110D* + ID_PRODUCT_FROM_DATABASE=82544GC Based Network Connection + +pci:v00008086d0000100E* + ID_PRODUCT_FROM_DATABASE=82540EM Gigabit Ethernet Controller + +pci:v00008086d0000100Esv00001014sd00000265* + ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Network Connection + +pci:v00008086d0000100Esv00001014sd00000267* + ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Network Connection + +pci:v00008086d0000100Esv00001014sd0000026A* + ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Network Connection + +pci:v00008086d0000100Esv00001028sd0000002E* + ID_PRODUCT_FROM_DATABASE=Optiplex GX260 + +pci:v00008086d0000100Esv00001028sd00000134* + ID_PRODUCT_FROM_DATABASE=PowerEdge 600SC + +pci:v00008086d0000100Esv00001028sd00000151* + ID_PRODUCT_FROM_DATABASE=Optiplex GX270 + +pci:v00008086d0000100Esv0000107Bsd00008920* + ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Desktop Adapter + +pci:v00008086d0000100Esv00008086sd0000001E* + ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Desktop Adapter + +pci:v00008086d0000100Esv00008086sd0000002E* + ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Desktop Adapter + +pci:v00008086d0000100Esv00008086sd00001376* + ID_PRODUCT_FROM_DATABASE=PRO/1000 GT Desktop Adapter + +pci:v00008086d0000100Esv00008086sd00001476* + ID_PRODUCT_FROM_DATABASE=PRO/1000 GT Desktop Adapter + +pci:v00008086d0000100F* + ID_PRODUCT_FROM_DATABASE=82545EM Gigabit Ethernet Controller (Copper) + +pci:v00008086d0000100Fsv00001014sd00000269* + ID_PRODUCT_FROM_DATABASE=iSeries 1000/100/10 Ethernet Adapter + +pci:v00008086d0000100Fsv00001014sd0000028E* + ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Network Connection + +pci:v00008086d0000100Fsv000015ADsd00000750* + ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Single Port Adapter + +pci:v00008086d0000100Fsv00008086sd00001000* + ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Network Connection + +pci:v00008086d0000100Fsv00008086sd00001001* + ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Server Adapter + +pci:v00008086d00001010* + ID_PRODUCT_FROM_DATABASE=82546EB Gigabit Ethernet Controller (Copper) + +pci:v00008086d00001010sv00000E11sd000000DB* + ID_PRODUCT_FROM_DATABASE=NC7170 Gigabit Server Adapter + +pci:v00008086d00001010sv00001014sd0000027C* + ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Dual Port Network Adapter + +pci:v00008086d00001010sv000015ADsd00000760* + ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Dual Port Adapter + +pci:v00008086d00001010sv000018FBsd00007872* + ID_PRODUCT_FROM_DATABASE=RESlink-X + +pci:v00008086d00001010sv00001FC1sd00000026* + ID_PRODUCT_FROM_DATABASE=Niagara 2260 Bypass Card + +pci:v00008086d00001010sv00004C53sd00001080* + ID_PRODUCT_FROM_DATABASE=CT8 mainboard + +pci:v00008086d00001010sv00004C53sd000010A0* + ID_PRODUCT_FROM_DATABASE=CA3/CR3 mainboard + +pci:v00008086d00001010sv00008086sd00001011* + ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Dual Port Server Adapter + +pci:v00008086d00001010sv00008086sd00001012* + ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Dual Port Server Adapter + +pci:v00008086d00001010sv00008086sd0000101A* + ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Dual Port Network Connection + +pci:v00008086d00001010sv00008086sd00003424* + ID_PRODUCT_FROM_DATABASE=SE7501HG2 Mainboard + +pci:v00008086d00001011* + ID_PRODUCT_FROM_DATABASE=82545EM Gigabit Ethernet Controller (Fiber) + +pci:v00008086d00001011sv00001014sd00000268* + ID_PRODUCT_FROM_DATABASE=iSeries Gigabit Ethernet Adapter + +pci:v00008086d00001011sv00008086sd00001002* + ID_PRODUCT_FROM_DATABASE=PRO/1000 MF Server Adapter + +pci:v00008086d00001011sv00008086sd00001003* + ID_PRODUCT_FROM_DATABASE=PRO/1000 MF Server Adapter (LX) + +pci:v00008086d00001012* + ID_PRODUCT_FROM_DATABASE=82546EB Gigabit Ethernet Controller (Fiber) + +pci:v00008086d00001012sv00000E11sd000000DC* + ID_PRODUCT_FROM_DATABASE=NC6170 Gigabit Server Adapter + +pci:v00008086d00001012sv00008086sd00001012* + ID_PRODUCT_FROM_DATABASE=PRO/1000 MF Dual Port Server Adapter + +pci:v00008086d00001013* + ID_PRODUCT_FROM_DATABASE=82541EI Gigabit Ethernet Controller + +pci:v00008086d00001013sv00008086sd00000013* + ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Network Connection + +pci:v00008086d00001013sv00008086sd00001013* + ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Network Connection + +pci:v00008086d00001013sv00008086sd00001113* + ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Desktop Adapter + +pci:v00008086d00001014* + ID_PRODUCT_FROM_DATABASE=82541ER Gigabit Ethernet Controller + +pci:v00008086d00001014sv00008086sd00000014* + ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Desktop Connection + +pci:v00008086d00001014sv00008086sd00001014* + ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Network Connection + +pci:v00008086d00001015* + ID_PRODUCT_FROM_DATABASE=82540EM Gigabit Ethernet Controller (LOM) + +pci:v00008086d00001015sv00008086sd00001015* + ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Mobile Connection + +pci:v00008086d00001016* + ID_PRODUCT_FROM_DATABASE=82540EP Gigabit Ethernet Controller (Mobile) + +pci:v00008086d00001016sv00001014sd0000052C* + ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Mobile Connection + +pci:v00008086d00001016sv00001179sd00000001* + ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Mobile Connection + +pci:v00008086d00001016sv00008086sd00001016* + ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Mobile Connection + +pci:v00008086d00001017* + ID_PRODUCT_FROM_DATABASE=82540EP Gigabit Ethernet Controller + +pci:v00008086d00001017sv00008086sd00001017* + ID_PRODUCT_FROM_DATABASE=PR0/1000 MT Desktop Connection + +pci:v00008086d00001018* + ID_PRODUCT_FROM_DATABASE=82541EI Gigabit Ethernet Controller + +pci:v00008086d00001018sv00008086sd00001018* + ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Mobile Connection + +pci:v00008086d00001019* + ID_PRODUCT_FROM_DATABASE=82547EI Gigabit Ethernet Controller + +pci:v00008086d00001019sv00001458sd00001019* + ID_PRODUCT_FROM_DATABASE=GA-8IPE1000 Pro2 motherboard (865PE) + +pci:v00008086d00001019sv00001458sd0000E000* + ID_PRODUCT_FROM_DATABASE=Intel Gigabit Ethernet (Kenai II) + +pci:v00008086d00001019sv00008086sd00001019* + ID_PRODUCT_FROM_DATABASE=PRO/1000 CT Desktop Connection + +pci:v00008086d00001019sv00008086sd0000301F* + ID_PRODUCT_FROM_DATABASE=D865PERL mainboard + +pci:v00008086d00001019sv00008086sd00003025* + ID_PRODUCT_FROM_DATABASE=D875PBZ motherboard + +pci:v00008086d00001019sv00008086sd0000302C* + ID_PRODUCT_FROM_DATABASE=Intel 82865G Mainboard (D865GBF) + +pci:v00008086d00001019sv00008086sd00003427* + ID_PRODUCT_FROM_DATABASE=S875WP1-E mainboard + +pci:v00008086d0000101A* + ID_PRODUCT_FROM_DATABASE=82547EI Gigabit Ethernet Controller (Mobile) + +pci:v00008086d0000101Asv00008086sd0000101A* + ID_PRODUCT_FROM_DATABASE=PRO/1000 CT Mobile Connection + +pci:v00008086d0000101D* + ID_PRODUCT_FROM_DATABASE=82546EB Gigabit Ethernet Controller + +pci:v00008086d0000101Dsv00008086sd00001000* + ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Quad Port Server Adapter + +pci:v00008086d0000101E* + ID_PRODUCT_FROM_DATABASE=82540EP Gigabit Ethernet Controller (Mobile) + +pci:v00008086d0000101Esv00001014sd00000549* + ID_PRODUCT_FROM_DATABASE=Thinkpad + +pci:v00008086d0000101Esv00001179sd00000001* + ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Mobile Connection + +pci:v00008086d0000101Esv00008086sd0000101E* + ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Mobile Connection + +pci:v00008086d00001026* + ID_PRODUCT_FROM_DATABASE=82545GM Gigabit Ethernet Controller + +pci:v00008086d00001026sv00001028sd00000169* + ID_PRODUCT_FROM_DATABASE=Precision 470 + +pci:v00008086d00001026sv00008086sd00001000* + ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Server Connection + +pci:v00008086d00001026sv00008086sd00001001* + ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Server Adapter + +pci:v00008086d00001026sv00008086sd00001002* + ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Server Adapter + +pci:v00008086d00001026sv00008086sd00001003* + ID_PRODUCT_FROM_DATABASE=PRO/1000 GT Server Adapter + +pci:v00008086d00001026sv00008086sd00001026* + ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Server Connection + +pci:v00008086d00001027* + ID_PRODUCT_FROM_DATABASE=82545GM Gigabit Ethernet Controller + +pci:v00008086d00001027sv0000103Csd00003103* + ID_PRODUCT_FROM_DATABASE=NC310F PCI-X Gigabit Server Adapter + +pci:v00008086d00001027sv00008086sd00001001* + ID_PRODUCT_FROM_DATABASE=PRO/1000 MF Server Adapter(LX) + +pci:v00008086d00001027sv00008086sd00001002* + ID_PRODUCT_FROM_DATABASE=PRO/1000 MF Server Adapter(LX) + +pci:v00008086d00001027sv00008086sd00001003* + ID_PRODUCT_FROM_DATABASE=PRO/1000 MF Server Adapter(LX) + +pci:v00008086d00001027sv00008086sd00001027* + ID_PRODUCT_FROM_DATABASE=PRO/1000 MF Server Adapter + +pci:v00008086d00001028* + ID_PRODUCT_FROM_DATABASE=82545GM Gigabit Ethernet Controller + +pci:v00008086d00001028sv00008086sd00001028* + ID_PRODUCT_FROM_DATABASE=PRO/1000 MB Server Connection + +pci:v00008086d00001029* + ID_PRODUCT_FROM_DATABASE=82559 Ethernet Controller + +pci:v00008086d00001030* + ID_PRODUCT_FROM_DATABASE=82559 InBusiness 10/100 + +pci:v00008086d00001031* + ID_PRODUCT_FROM_DATABASE=82801CAM (ICH3) PRO/100 VE (LOM) Ethernet Controller + +pci:v00008086d00001031sv00001014sd00000209* + ID_PRODUCT_FROM_DATABASE=ThinkPad A/T/X Series + +pci:v00008086d00001031sv0000104Dsd000080E7* + ID_PRODUCT_FROM_DATABASE=Vaio PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP + +pci:v00008086d00001031sv0000104Dsd0000813C* + ID_PRODUCT_FROM_DATABASE=Vaio PCG-GRV616G + +pci:v00008086d00001031sv0000107Bsd00005350* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 VE + +pci:v00008086d00001031sv00001179sd00000001* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 VE + +pci:v00008086d00001031sv0000144Dsd0000C000* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 VE + +pci:v00008086d00001031sv0000144Dsd0000C001* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 VE + +pci:v00008086d00001031sv0000144Dsd0000C003* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 VE + +pci:v00008086d00001031sv0000144Dsd0000C006* + ID_PRODUCT_FROM_DATABASE=vpr Matrix 170B4 + +pci:v00008086d00001032* + ID_PRODUCT_FROM_DATABASE=82801CAM (ICH3) PRO/100 VE Ethernet Controller + +pci:v00008086d00001033* + ID_PRODUCT_FROM_DATABASE=82801CAM (ICH3) PRO/100 VM (LOM) Ethernet Controller + +pci:v00008086d00001034* + ID_PRODUCT_FROM_DATABASE=82801CAM (ICH3) PRO/100 VM Ethernet Controller + +pci:v00008086d00001035* + ID_PRODUCT_FROM_DATABASE=82801CAM (ICH3)/82562EH (LOM) Ethernet Controller + +pci:v00008086d00001036* + ID_PRODUCT_FROM_DATABASE=82801CAM (ICH3) 82562EH Ethernet Controller + +pci:v00008086d00001037* + ID_PRODUCT_FROM_DATABASE=82801CAM (ICH3) Chipset Ethernet Controller + +pci:v00008086d00001038* + ID_PRODUCT_FROM_DATABASE=82801CAM (ICH3) PRO/100 VM (KM) Ethernet Controller + +pci:v00008086d00001038sv00000E11sd00000098* + ID_PRODUCT_FROM_DATABASE=Evo N600c + +pci:v00008086d00001039* + ID_PRODUCT_FROM_DATABASE=82801DB PRO/100 VE (LOM) Ethernet Controller + +pci:v00008086d00001039sv00001014sd00000267* + ID_PRODUCT_FROM_DATABASE=NetVista A30p + +pci:v00008086d00001039sv0000114Asd00000582* + ID_PRODUCT_FROM_DATABASE=PC8 onboard ethernet ETH1 + +pci:v00008086d0000103A* + ID_PRODUCT_FROM_DATABASE=82801DB PRO/100 VE (CNR) Ethernet Controller + +pci:v00008086d0000103B* + ID_PRODUCT_FROM_DATABASE=82801DB PRO/100 VM (LOM) Ethernet Controller + +pci:v00008086d0000103C* + ID_PRODUCT_FROM_DATABASE=82801DB PRO/100 VM (CNR) Ethernet Controller + +pci:v00008086d0000103D* + ID_PRODUCT_FROM_DATABASE=82801DB PRO/100 VE (MOB) Ethernet Controller + +pci:v00008086d0000103Dsv00001014sd00000522* + ID_PRODUCT_FROM_DATABASE=ThinkPad R40 + +pci:v00008086d0000103Dsv00001028sd00002002* + ID_PRODUCT_FROM_DATABASE=Latitude D500 + +pci:v00008086d0000103Dsv00008086sd0000103D* + ID_PRODUCT_FROM_DATABASE=82562EZ 10/100 Ethernet Controller + +pci:v00008086d0000103E* + ID_PRODUCT_FROM_DATABASE=82801DB PRO/100 VM (MOB) Ethernet Controller + +pci:v00008086d00001040* + ID_PRODUCT_FROM_DATABASE=536EP Data Fax Modem + +pci:v00008086d00001040sv000016BEsd00001040* + ID_PRODUCT_FROM_DATABASE=V.9X DSP Data Fax Modem + +pci:v00008086d00001043* + ID_PRODUCT_FROM_DATABASE=PRO/Wireless LAN 2100 3B Mini PCI Adapter + +pci:v00008086d00001043sv0000103Csd000008B0* + ID_PRODUCT_FROM_DATABASE=tc1100 tablet + +pci:v00008086d00001043sv00008086sd00002522* + ID_PRODUCT_FROM_DATABASE=Samsung X10/P30 integrated WLAN + +pci:v00008086d00001043sv00008086sd00002527* + ID_PRODUCT_FROM_DATABASE=MIM2000/Centrino + +pci:v00008086d00001043sv00008086sd00002561* + ID_PRODUCT_FROM_DATABASE=Dell Latitude D800 + +pci:v00008086d00001043sv00008086sd00002581* + ID_PRODUCT_FROM_DATABASE=Toshiba Satellite M10 + +pci:v00008086d00001048* + ID_PRODUCT_FROM_DATABASE=82597EX 10GbE Ethernet Controller + +pci:v00008086d00001048sv00008086sd0000A01F* + ID_PRODUCT_FROM_DATABASE=PRO/10GbE LR Server Adapter + +pci:v00008086d00001048sv00008086sd0000A11F* + ID_PRODUCT_FROM_DATABASE=PRO/10GbE LR Server Adapter + +pci:v00008086d00001049* + ID_PRODUCT_FROM_DATABASE=82566MM Gigabit Network Connection + +pci:v00008086d00001049sv0000103Csd000030C1* + ID_PRODUCT_FROM_DATABASE=Compaq 6910p + +pci:v00008086d00001049sv000017AAsd000020B9* + ID_PRODUCT_FROM_DATABASE=ThinkPad T61 + +pci:v00008086d0000104A* + ID_PRODUCT_FROM_DATABASE=82566DM Gigabit Network Connection + +pci:v00008086d0000104B* + ID_PRODUCT_FROM_DATABASE=82566DC Gigabit Network Connection + +pci:v00008086d0000104C* + ID_PRODUCT_FROM_DATABASE=82562V 10/100 Network Connection + +pci:v00008086d0000104D* + ID_PRODUCT_FROM_DATABASE=82566MC Gigabit Network Connection + +pci:v00008086d00001050* + ID_PRODUCT_FROM_DATABASE=82562EZ 10/100 Ethernet Controller + +pci:v00008086d00001050sv00001028sd0000019D* + ID_PRODUCT_FROM_DATABASE=Dimension 3000 + +pci:v00008086d00001050sv00001462sd0000728C* + ID_PRODUCT_FROM_DATABASE=865PE Neo2 (MS-6728) + +pci:v00008086d00001050sv00001462sd0000758C* + ID_PRODUCT_FROM_DATABASE=MS-6758 (875P Neo) + +pci:v00008086d00001050sv00008086sd00003020* + ID_PRODUCT_FROM_DATABASE=D865PERL mainboard + +pci:v00008086d00001050sv00008086sd0000302F* + ID_PRODUCT_FROM_DATABASE=Desktop Board D865GBF + +pci:v00008086d00001050sv00008086sd00003427* + ID_PRODUCT_FROM_DATABASE=S875WP1-E mainboard + +pci:v00008086d00001051* + ID_PRODUCT_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) integrated LAN Controller + +pci:v00008086d00001052* + ID_PRODUCT_FROM_DATABASE=PRO/100 VM Network Connection + +pci:v00008086d00001053* + ID_PRODUCT_FROM_DATABASE=PRO/100 VM Network Connection + +pci:v00008086d00001054* + ID_PRODUCT_FROM_DATABASE=PRO/100 VE Network Connection + +pci:v00008086d00001055* + ID_PRODUCT_FROM_DATABASE=PRO/100 VM Network Connection + +pci:v00008086d00001056* + ID_PRODUCT_FROM_DATABASE=PRO/100 VE Network Connection + +pci:v00008086d00001057* + ID_PRODUCT_FROM_DATABASE=PRO/100 VE Network Connection + +pci:v00008086d00001059* + ID_PRODUCT_FROM_DATABASE=82551QM Ethernet Controller + +pci:v00008086d0000105B* + ID_PRODUCT_FROM_DATABASE=82546GB Gigabit Ethernet Controller (Copper) + +pci:v00008086d0000105E* + ID_PRODUCT_FROM_DATABASE=82571EB Gigabit Ethernet Controller + +pci:v00008086d0000105Esv0000103Csd00007044* + ID_PRODUCT_FROM_DATABASE=NC360T PCI Express Dual Port Gigabit Server Adapter + +pci:v00008086d0000105Esv0000103Csd0000704E* + ID_PRODUCT_FROM_DATABASE=Dual Port 1000Base-T (PCIe) [AD337A] + +pci:v00008086d0000105Esv00001775sd00001100* + ID_PRODUCT_FROM_DATABASE=CR11/VR11 Single Board Computer + +pci:v00008086d0000105Esv00001775sd00006003* + ID_PRODUCT_FROM_DATABASE=Telum GE-QT + +pci:v00008086d0000105Esv00008086sd0000005E* + ID_PRODUCT_FROM_DATABASE=PRO/1000 PT Dual Port Server Connection + +pci:v00008086d0000105Esv00008086sd0000105E* + ID_PRODUCT_FROM_DATABASE=PRO/1000 PT Dual Port Network Connection + +pci:v00008086d0000105Esv00008086sd000010D5* + ID_PRODUCT_FROM_DATABASE=82571PT Gigabit PT Quad Port Server ExpressModule + +pci:v00008086d0000105Esv00008086sd0000115E* + ID_PRODUCT_FROM_DATABASE=PRO/1000 PT Dual Port Server Adapter + +pci:v00008086d0000105Esv00008086sd0000125E* + ID_PRODUCT_FROM_DATABASE=PRO/1000 PT Dual Port Server Adapter + +pci:v00008086d0000105Esv00008086sd0000135E* + ID_PRODUCT_FROM_DATABASE=PRO/1000 PT Dual Port Server Adapter + +pci:v00008086d0000105F* + ID_PRODUCT_FROM_DATABASE=82571EB Gigabit Ethernet Controller + +pci:v00008086d0000105Fsv0000103Csd0000704F* + ID_PRODUCT_FROM_DATABASE=Dual Port 1000Base-SX (PCIe) [AD338A] + +pci:v00008086d0000105Fsv00008086sd0000005A* + ID_PRODUCT_FROM_DATABASE=PRO/1000 PF Dual Port Server Adapter + +pci:v00008086d0000105Fsv00008086sd0000115F* + ID_PRODUCT_FROM_DATABASE=PRO/1000 PF Dual Port Server Adapter + +pci:v00008086d0000105Fsv00008086sd0000125F* + ID_PRODUCT_FROM_DATABASE=PRO/1000 PF Dual Port Server Adapter + +pci:v00008086d0000105Fsv00008086sd0000135F* + ID_PRODUCT_FROM_DATABASE=PRO/1000 PF Dual Port Server Adapter + +pci:v00008086d00001060* + ID_PRODUCT_FROM_DATABASE=82571EB Gigabit Ethernet Controller + +pci:v00008086d00001060sv00008086sd00000060* + ID_PRODUCT_FROM_DATABASE=PRO/1000 PB Dual Port Server Connection + +pci:v00008086d00001060sv00008086sd00001060* + ID_PRODUCT_FROM_DATABASE=PRO/1000 PB Dual Port Server Connection + +pci:v00008086d00001064* + ID_PRODUCT_FROM_DATABASE=82562ET/EZ/GT/GZ - PRO/100 VE (LOM) Ethernet Controller + +pci:v00008086d00001064sv00001043sd000080F8* + ID_PRODUCT_FROM_DATABASE=P5GD1-VW Mainboard + +pci:v00008086d00001065* + ID_PRODUCT_FROM_DATABASE=82562ET/EZ/GT/GZ - PRO/100 VE Ethernet Controller + +pci:v00008086d00001066* + ID_PRODUCT_FROM_DATABASE=82562 EM/EX/GX - PRO/100 VM (LOM) Ethernet Controller + +pci:v00008086d00001067* + ID_PRODUCT_FROM_DATABASE=82562 EM/EX/GX - PRO/100 VM Ethernet Controller + +pci:v00008086d00001068* + ID_PRODUCT_FROM_DATABASE=82562ET/EZ/GT/GZ - PRO/100 VE (LOM) Ethernet Controller Mobile + +pci:v00008086d00001069* + ID_PRODUCT_FROM_DATABASE=82562EM/EX/GX - PRO/100 VM (LOM) Ethernet Controller Mobile + +pci:v00008086d0000106A* + ID_PRODUCT_FROM_DATABASE=82562G - PRO/100 VE (LOM) Ethernet Controller + +pci:v00008086d0000106B* + ID_PRODUCT_FROM_DATABASE=82562G - PRO/100 VE Ethernet Controller Mobile + +pci:v00008086d00001075* + ID_PRODUCT_FROM_DATABASE=82547GI Gigabit Ethernet Controller + +pci:v00008086d00001075sv00001028sd00000165* + ID_PRODUCT_FROM_DATABASE=PowerEdge 750 + +pci:v00008086d00001075sv00008086sd00000075* + ID_PRODUCT_FROM_DATABASE=PRO/1000 CT Network Connection + +pci:v00008086d00001075sv00008086sd00001075* + ID_PRODUCT_FROM_DATABASE=PRO/1000 CT Network Connection + +pci:v00008086d00001076* + ID_PRODUCT_FROM_DATABASE=82541GI Gigabit Ethernet Controller + +pci:v00008086d00001076sv00001028sd00000165* + ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Network Connection + +pci:v00008086d00001076sv00001028sd0000016D* + ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Network Connection + +pci:v00008086d00001076sv00001028sd0000019A* + ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Network Connection + +pci:v00008086d00001076sv00001028sd0000106D* + ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Network Connection + +pci:v00008086d00001076sv00008086sd00000076* + ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Network Connection + +pci:v00008086d00001076sv00008086sd00001076* + ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Network Connection + +pci:v00008086d00001076sv00008086sd00001176* + ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Desktop Adapter + +pci:v00008086d00001076sv00008086sd00001276* + ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Network Adapter + +pci:v00008086d00001077* + ID_PRODUCT_FROM_DATABASE=82541GI Gigabit Ethernet Controller + +pci:v00008086d00001077sv00001179sd00000001* + ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Mobile Connection + +pci:v00008086d00001077sv00008086sd00000077* + ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Mobile Connection + +pci:v00008086d00001077sv00008086sd00001077* + ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Mobile Connection + +pci:v00008086d00001078* + ID_PRODUCT_FROM_DATABASE=82541ER Gigabit Ethernet Controller + +pci:v00008086d00001078sv00008086sd00001078* + ID_PRODUCT_FROM_DATABASE=82541ER-based Network Connection + +pci:v00008086d00001079* + ID_PRODUCT_FROM_DATABASE=82546GB Gigabit Ethernet Controller + +pci:v00008086d00001079sv0000103Csd000012A6* + ID_PRODUCT_FROM_DATABASE=Dual Port 1000Base-T [A9900A] + +pci:v00008086d00001079sv0000103Csd000012CF* + ID_PRODUCT_FROM_DATABASE=Core Dual Port 1000Base-T [AB352A] + +pci:v00008086d00001079sv00001775sd000010D0* + ID_PRODUCT_FROM_DATABASE=V5D Single Board Computer Gigabit Ethernet + +pci:v00008086d00001079sv00001775sd0000CE90* + ID_PRODUCT_FROM_DATABASE=CE9 + +pci:v00008086d00001079sv00001FC1sd00000027* + ID_PRODUCT_FROM_DATABASE=Niagara 2261 Failover NIC + +pci:v00008086d00001079sv00004C53sd00001090* + ID_PRODUCT_FROM_DATABASE=Cx9 / Vx9 mainboard + +pci:v00008086d00001079sv00004C53sd000010B0* + ID_PRODUCT_FROM_DATABASE=CL9 mainboard + +pci:v00008086d00001079sv00008086sd00000079* + ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Dual Port Network Connection + +pci:v00008086d00001079sv00008086sd00001079* + ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Dual Port Network Connection + +pci:v00008086d00001079sv00008086sd00001179* + ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Dual Port Server Adapter + +pci:v00008086d00001079sv00008086sd0000117A* + ID_PRODUCT_FROM_DATABASE=PRO/1000 MT Dual Port Server Adapter + +pci:v00008086d0000107A* + ID_PRODUCT_FROM_DATABASE=82546GB Gigabit Ethernet Controller + +pci:v00008086d0000107Asv0000103Csd000012A8* + ID_PRODUCT_FROM_DATABASE=Dual Port 1000base-SX [A9899A] + +pci:v00008086d0000107Asv00008086sd0000107A* + ID_PRODUCT_FROM_DATABASE=PRO/1000 MF Dual Port Server Adapter + +pci:v00008086d0000107Asv00008086sd0000127A* + ID_PRODUCT_FROM_DATABASE=PRO/1000 MF Dual Port Server Adapter + +pci:v00008086d0000107B* + ID_PRODUCT_FROM_DATABASE=82546GB Gigabit Ethernet Controller + +pci:v00008086d0000107Bsv00008086sd0000007B* + ID_PRODUCT_FROM_DATABASE=PRO/1000 MB Dual Port Server Connection + +pci:v00008086d0000107Bsv00008086sd0000107B* + ID_PRODUCT_FROM_DATABASE=PRO/1000 MB Dual Port Server Connection + +pci:v00008086d0000107C* + ID_PRODUCT_FROM_DATABASE=82541PI Gigabit Ethernet Controller + +pci:v00008086d0000107Csv00008086sd00001376* + ID_PRODUCT_FROM_DATABASE=PRO/1000 GT Desktop Adapter + +pci:v00008086d0000107Csv00008086sd00001476* + ID_PRODUCT_FROM_DATABASE=PRO/1000 GT Desktop Adapter + +pci:v00008086d0000107D* + ID_PRODUCT_FROM_DATABASE=82572EI Gigabit Ethernet Controller (Copper) + +pci:v00008086d0000107Dsv00008086sd00001082* + ID_PRODUCT_FROM_DATABASE=PRO/1000 PT Server Adapter + +pci:v00008086d0000107Dsv00008086sd00001084* + ID_PRODUCT_FROM_DATABASE=PRO/1000 PT Server Adapter + +pci:v00008086d0000107Dsv00008086sd00001092* + ID_PRODUCT_FROM_DATABASE=PRO/1000 PT Server Adapter + +pci:v00008086d0000107E* + ID_PRODUCT_FROM_DATABASE=82572EI Gigabit Ethernet Controller (Fiber) + +pci:v00008086d0000107Esv00008086sd00001084* + ID_PRODUCT_FROM_DATABASE=PRO/1000 PF Server Adapter + +pci:v00008086d0000107Esv00008086sd00001085* + ID_PRODUCT_FROM_DATABASE=PRO/1000 PF Server Adapter + +pci:v00008086d0000107Esv00008086sd00001094* + ID_PRODUCT_FROM_DATABASE=PRO/1000 PF Server Adapter + +pci:v00008086d0000107F* + ID_PRODUCT_FROM_DATABASE=82572EI Gigabit Ethernet Controller + +pci:v00008086d00001080* + ID_PRODUCT_FROM_DATABASE=FA82537EP 56K V.92 Data/Fax Modem PCI + +pci:v00008086d00001081* + ID_PRODUCT_FROM_DATABASE=631xESB/632xESB LAN Controller Copper + +pci:v00008086d00001082* + ID_PRODUCT_FROM_DATABASE=631xESB/632xESB LAN Controller fiber + +pci:v00008086d00001083* + ID_PRODUCT_FROM_DATABASE=631xESB/632xESB LAN Controller SERDES + +pci:v00008086d00001084* + ID_PRODUCT_FROM_DATABASE=631xESB/632xESB IDE Redirection + +pci:v00008086d00001085* + ID_PRODUCT_FROM_DATABASE=631xESB/632xESB Serial Port Redirection + +pci:v00008086d00001086* + ID_PRODUCT_FROM_DATABASE=631xESB/632xESB IPMI/KCS0 + +pci:v00008086d00001087* + ID_PRODUCT_FROM_DATABASE=631xESB/632xESB UHCI Redirection + +pci:v00008086d00001089* + ID_PRODUCT_FROM_DATABASE=631xESB/632xESB BT + +pci:v00008086d0000108A* + ID_PRODUCT_FROM_DATABASE=82546GB Gigabit Ethernet Controller + +pci:v00008086d0000108Asv00008086sd0000108A* + ID_PRODUCT_FROM_DATABASE=PRO/1000 P Dual Port Server Adapter + +pci:v00008086d0000108Asv00008086sd0000118A* + ID_PRODUCT_FROM_DATABASE=PRO/1000 P Dual Port Server Adapter + +pci:v00008086d0000108B* + ID_PRODUCT_FROM_DATABASE=82573V Gigabit Ethernet Controller (Copper) + +pci:v00008086d0000108Bsv00001462sd0000176C* + ID_PRODUCT_FROM_DATABASE=on board on MSI 945P - NEO (MS-7176) + +pci:v00008086d0000108C* + ID_PRODUCT_FROM_DATABASE=82573E Gigabit Ethernet Controller (Copper) + +pci:v00008086d0000108E* + ID_PRODUCT_FROM_DATABASE=82573E KCS (Active Management) + +pci:v00008086d0000108F* + ID_PRODUCT_FROM_DATABASE=Active Management Technology - SOL + +pci:v00008086d00001091* + ID_PRODUCT_FROM_DATABASE=PRO/100 VM Network Connection + +pci:v00008086d00001092* + ID_PRODUCT_FROM_DATABASE=PRO/100 VE Network Connection + +pci:v00008086d00001093* + ID_PRODUCT_FROM_DATABASE=PRO/100 VM Network Connection + +pci:v00008086d00001094* + ID_PRODUCT_FROM_DATABASE=PRO/100 VE Network Connection + +pci:v00008086d00001095* + ID_PRODUCT_FROM_DATABASE=PRO/100 VE Network Connection + +pci:v00008086d00001096* + ID_PRODUCT_FROM_DATABASE=80003ES2LAN Gigabit Ethernet Controller (Copper) + +pci:v00008086d00001096sv000015D9sd00008680* + ID_PRODUCT_FROM_DATABASE=X7DVL-E-O motherboard + +pci:v00008086d00001096sv00008086sd00003476* + ID_PRODUCT_FROM_DATABASE=Intel S5000PSLSATA Server Board + +pci:v00008086d00001097* + ID_PRODUCT_FROM_DATABASE=631xESB/632xESB DPT LAN Controller (Fiber) + +pci:v00008086d00001098* + ID_PRODUCT_FROM_DATABASE=80003ES2LAN Gigabit Ethernet Controller (Serdes) + +pci:v00008086d00001099* + ID_PRODUCT_FROM_DATABASE=82546GB Gigabit Ethernet Controller (Copper) + +pci:v00008086d00001099sv00008086sd00001099* + ID_PRODUCT_FROM_DATABASE=PRO/1000 GT Quad Port Server Adapter + +pci:v00008086d0000109A* + ID_PRODUCT_FROM_DATABASE=82573L Gigabit Ethernet Controller + +pci:v00008086d0000109Asv00001179sd0000FF10* + ID_PRODUCT_FROM_DATABASE=PRO/1000 PL + +pci:v00008086d0000109Asv000017AAsd00002001* + ID_PRODUCT_FROM_DATABASE=ThinkPad T60 + +pci:v00008086d0000109Asv000017AAsd0000207E* + ID_PRODUCT_FROM_DATABASE=ThinkPad X60s + +pci:v00008086d0000109Asv00008086sd0000109A* + ID_PRODUCT_FROM_DATABASE=PRO/1000 PL Network Connection + +pci:v00008086d0000109Asv00008086sd0000309C* + ID_PRODUCT_FROM_DATABASE=Desktop Board D945GTP + +pci:v00008086d0000109Asv00008086sd000030A5* + ID_PRODUCT_FROM_DATABASE=Desktop Board D975XBX + +pci:v00008086d0000109B* + ID_PRODUCT_FROM_DATABASE=82546GB PRO/1000 GF Quad Port Server Adapter + +pci:v00008086d0000109E* + ID_PRODUCT_FROM_DATABASE=82597EX 10GbE Ethernet Controller + +pci:v00008086d0000109Esv00008086sd0000A01F* + ID_PRODUCT_FROM_DATABASE=PRO/10GbE CX4 Server Adapter + +pci:v00008086d0000109Esv00008086sd0000A11F* + ID_PRODUCT_FROM_DATABASE=PRO/10GbE CX4 Server Adapter + +pci:v00008086d000010A0* + ID_PRODUCT_FROM_DATABASE=82571EB PRO/1000 AT Quad Port Bypass Adapter + +pci:v00008086d000010A1* + ID_PRODUCT_FROM_DATABASE=82571EB PRO/1000 AF Quad Port Bypass Adapter + +pci:v00008086d000010A4* + ID_PRODUCT_FROM_DATABASE=82571EB Gigabit Ethernet Controller + +pci:v00008086d000010A4sv00008086sd000010A4* + ID_PRODUCT_FROM_DATABASE=PRO/1000 PT Quad Port Server Adapter + +pci:v00008086d000010A4sv00008086sd000011A4* + ID_PRODUCT_FROM_DATABASE=PRO/1000 PT Quad Port Server Adapter + +pci:v00008086d000010A5* + ID_PRODUCT_FROM_DATABASE=82571EB Gigabit Ethernet Controller (Fiber) + +pci:v00008086d000010A5sv00008086sd000010A5* + ID_PRODUCT_FROM_DATABASE=PRO/1000 PF Quad Port Server Adapter + +pci:v00008086d000010A5sv00008086sd000010A6* + ID_PRODUCT_FROM_DATABASE=PRO/1000 PF Quad Port Server Adapter + +pci:v00008086d000010A6* + ID_PRODUCT_FROM_DATABASE=82599EB 10-Gigabit Dummy Function + +pci:v00008086d000010A7* + ID_PRODUCT_FROM_DATABASE=82575EB Gigabit Network Connection + +pci:v00008086d000010A7sv00008086sd000010A8* + ID_PRODUCT_FROM_DATABASE=82575EB Gigabit Riser Card + +pci:v00008086d000010A9* + ID_PRODUCT_FROM_DATABASE=82575EB Gigabit Backplane Connection + +pci:v00008086d000010B0* + ID_PRODUCT_FROM_DATABASE=82573L PRO/1000 PL Network Connection + +pci:v00008086d000010B2* + ID_PRODUCT_FROM_DATABASE=82573V PRO/1000 PM Network Connection + +pci:v00008086d000010B3* + ID_PRODUCT_FROM_DATABASE=82573E PRO/1000 PM Network Connection + +pci:v00008086d000010B4* + ID_PRODUCT_FROM_DATABASE=82573L PRO/1000 PL Network Connection + +pci:v00008086d000010B5* + ID_PRODUCT_FROM_DATABASE=82546GB Gigabit Ethernet Controller (Copper) + +pci:v00008086d000010B5sv0000103Csd00003109* + ID_PRODUCT_FROM_DATABASE=NC340T PCI-X Quad-port Gigabit Server Adapter + +pci:v00008086d000010B5sv00008086sd00001099* + ID_PRODUCT_FROM_DATABASE=PRO/1000 GT Quad Port Server Adapter + +pci:v00008086d000010B5sv00008086sd00001199* + ID_PRODUCT_FROM_DATABASE=PRO/1000 GT Quad Port Server Adapter + +pci:v00008086d000010B6* + ID_PRODUCT_FROM_DATABASE=82598 10GbE PCI-Express Ethernet Controller + +pci:v00008086d000010B9* + ID_PRODUCT_FROM_DATABASE=82572EI Gigabit Ethernet Controller (Copper) + +pci:v00008086d000010B9sv0000103Csd0000704A* + ID_PRODUCT_FROM_DATABASE=HP 110T PCIe Gigabit Server Adapter + +pci:v00008086d000010B9sv00008086sd00001083* + ID_PRODUCT_FROM_DATABASE=PRO/1000 PT Desktop Adapter + +pci:v00008086d000010B9sv00008086sd00001093* + ID_PRODUCT_FROM_DATABASE=PRO/1000 PT Desktop Adapter + +pci:v00008086d000010BA* + ID_PRODUCT_FROM_DATABASE=80003ES2LAN Gigabit Ethernet Controller (Copper) + +pci:v00008086d000010BB* + ID_PRODUCT_FROM_DATABASE=80003ES2LAN Gigabit Ethernet Controller (Serdes) + +pci:v00008086d000010BC* + ID_PRODUCT_FROM_DATABASE=82571EB Gigabit Ethernet Controller (Copper) + +pci:v00008086d000010BCsv0000103Csd0000704B* + ID_PRODUCT_FROM_DATABASE=NC364T PCI Express Quad Port Gigabit Server Adapter + +pci:v00008086d000010BCsv0000108Esd000011BC* + ID_PRODUCT_FROM_DATABASE=x4 PCI-Express Quad Gigabit Ethernet UTP Low Profile Adapter + +pci:v00008086d000010BCsv00008086sd000010BC* + ID_PRODUCT_FROM_DATABASE=PRO/1000 PT Quad Port LP Server Adapter + +pci:v00008086d000010BCsv00008086sd000011BC* + ID_PRODUCT_FROM_DATABASE=PRO/1000 PT Quad Port LP Server Adapter + +pci:v00008086d000010BD* + ID_PRODUCT_FROM_DATABASE=82566DM-2 Gigabit Network Connection + +pci:v00008086d000010BDsv00001028sd00000211* + ID_PRODUCT_FROM_DATABASE=OptiPlex 755 + +pci:v00008086d000010BF* + ID_PRODUCT_FROM_DATABASE=82567LF Gigabit Network Connection + +pci:v00008086d000010C0* + ID_PRODUCT_FROM_DATABASE=82562V-2 10/100 Network Connection + +pci:v00008086d000010C0sv00001028sd0000020D* + ID_PRODUCT_FROM_DATABASE=Inspiron 530 + +pci:v00008086d000010C2* + ID_PRODUCT_FROM_DATABASE=82562G-2 10/100 Network Connection + +pci:v00008086d000010C3* + ID_PRODUCT_FROM_DATABASE=82562GT-2 10/100 Network Connection + +pci:v00008086d000010C4* + ID_PRODUCT_FROM_DATABASE=82562GT 10/100 Network Connection + +pci:v00008086d000010C5* + ID_PRODUCT_FROM_DATABASE=82562G 10/100 Network Connection + +pci:v00008086d000010C6* + ID_PRODUCT_FROM_DATABASE=82598EB 10-Gigabit AF Dual Port Network Connection + +pci:v00008086d000010C6sv00008086sd0000A05F* + ID_PRODUCT_FROM_DATABASE=10-Gigabit XF SR Dual Port Server Adapter + +pci:v00008086d000010C6sv00008086sd0000A15F* + ID_PRODUCT_FROM_DATABASE=10-Gigabit XF SR Dual Port Server Adapter + +pci:v00008086d000010C7* + ID_PRODUCT_FROM_DATABASE=82598EB 10-Gigabit AF Network Connection + +pci:v00008086d000010C7sv00001014sd0000037F* + ID_PRODUCT_FROM_DATABASE=10-Gigabit XF SR Server Adapter + +pci:v00008086d000010C7sv00001014sd00000380* + ID_PRODUCT_FROM_DATABASE=10-Gigabit XF LR Server Adapter + +pci:v00008086d000010C7sv00008086sd0000A05F* + ID_PRODUCT_FROM_DATABASE=10-Gigabit XF SR Server Adapter + +pci:v00008086d000010C7sv00008086sd0000A15F* + ID_PRODUCT_FROM_DATABASE=10-Gigabit XF SR Server Adapter + +pci:v00008086d000010C7sv00008086sd0000A16F* + ID_PRODUCT_FROM_DATABASE=10-Gigabit XF SR Server Adapter + +pci:v00008086d000010C8* + ID_PRODUCT_FROM_DATABASE=82598EB 10-Gigabit AT Network Connection + +pci:v00008086d000010C8sv00008086sd0000A10C* + ID_PRODUCT_FROM_DATABASE=10-Gigabit AT Server Adapter + +pci:v00008086d000010C8sv00008086sd0000A11C* + ID_PRODUCT_FROM_DATABASE=10-Gigabit AT Server Adapter + +pci:v00008086d000010C8sv00008086sd0000A12C* + ID_PRODUCT_FROM_DATABASE=10-Gigabit AT Server Adapter + +pci:v00008086d000010C9* + ID_PRODUCT_FROM_DATABASE=82576 Gigabit Network Connection + +pci:v00008086d000010C9sv0000103Csd000031EF* + ID_PRODUCT_FROM_DATABASE=NC362i Integrated Dual port Gigabit Server Adapter + +pci:v00008086d000010C9sv0000103Csd0000323F* + ID_PRODUCT_FROM_DATABASE=NC362i Integrated Dual port Gigabit Server Adapter + +pci:v00008086d000010C9sv000010A9sd00008028* + ID_PRODUCT_FROM_DATABASE=UV-BaseIO dual-port GbE + +pci:v00008086d000010C9sv000013A3sd00000037* + ID_PRODUCT_FROM_DATABASE=DS4100 Secure Multi-Gigabit Server Adapter with Compression + +pci:v00008086d000010C9sv000015D9sd0000A811* + ID_PRODUCT_FROM_DATABASE=H8DGU + +pci:v00008086d000010C9sv00008086sd0000A01C* + ID_PRODUCT_FROM_DATABASE=Gigabit ET Dual Port Server Adapter + +pci:v00008086d000010C9sv00008086sd0000A03C* + ID_PRODUCT_FROM_DATABASE=Gigabit ET Dual Port Server Adapter + +pci:v00008086d000010C9sv00008086sd0000A04C* + ID_PRODUCT_FROM_DATABASE=Gigabit ET Dual Port Server Adapter + +pci:v00008086d000010CA* + ID_PRODUCT_FROM_DATABASE=82576 Virtual Function + +pci:v00008086d000010CB* + ID_PRODUCT_FROM_DATABASE=82567V Gigabit Network Connection + +pci:v00008086d000010CC* + ID_PRODUCT_FROM_DATABASE=82567LM-2 Gigabit Network Connection + +pci:v00008086d000010CD* + ID_PRODUCT_FROM_DATABASE=82567LF-2 Gigabit Network Connection + +pci:v00008086d000010CE* + ID_PRODUCT_FROM_DATABASE=82567V-2 Gigabit Network Connection + +pci:v00008086d000010D3* + ID_PRODUCT_FROM_DATABASE=82574L Gigabit Network Connection + +pci:v00008086d000010D3sv0000103Csd00003250* + ID_PRODUCT_FROM_DATABASE=NC112T PCI Express single Port Gigabit Server Adapter + +pci:v00008086d000010D3sv000010A9sd00008029* + ID_PRODUCT_FROM_DATABASE=Prism XL Single Port Gigabit Ethernet + +pci:v00008086d000010D3sv00008086sd00000001* + ID_PRODUCT_FROM_DATABASE=Gigabit CT2 Desktop Adapter + +pci:v00008086d000010D3sv00008086sd0000A01F* + ID_PRODUCT_FROM_DATABASE=Gigabit CT Desktop Adapter + +pci:v00008086d000010D3sv0000E4BFsd000050C1* + ID_PRODUCT_FROM_DATABASE=PC1-GROOVE + +pci:v00008086d000010D3sv0000E4BFsd000050C2* + ID_PRODUCT_FROM_DATABASE=PC2-LIMBO + +pci:v00008086d000010D4* + ID_PRODUCT_FROM_DATABASE=Matrox Concord GE (customized Intel 82574) + +pci:v00008086d000010D5* + ID_PRODUCT_FROM_DATABASE=82571PT Gigabit PT Quad Port Server ExpressModule + +pci:v00008086d000010D6* + ID_PRODUCT_FROM_DATABASE=82575GB Gigabit Network Connection + +pci:v00008086d000010D6sv00008086sd000010D6* + ID_PRODUCT_FROM_DATABASE=Gigabit VT Quad Port Server Adapter + +pci:v00008086d000010D6sv00008086sd0000145A* + ID_PRODUCT_FROM_DATABASE=Gigabit VT Quad Port Server Adapter + +pci:v00008086d000010D6sv00008086sd0000147A* + ID_PRODUCT_FROM_DATABASE=Gigabit VT Quad Port Server Adapter + +pci:v00008086d000010D8* + ID_PRODUCT_FROM_DATABASE=82599EB 10 Gigabit Unprogrammed + +pci:v00008086d000010D9* + ID_PRODUCT_FROM_DATABASE=82571EB Dual Port Gigabit Mezzanine Adapter + +pci:v00008086d000010D9sv0000103Csd00001716* + ID_PRODUCT_FROM_DATABASE=NC360m Dual Port 1GbE BL-c Adapter + +pci:v00008086d000010DA* + ID_PRODUCT_FROM_DATABASE=82571EB Quad Port Gigabit Mezzanine Adapter + +pci:v00008086d000010DAsv0000103Csd00001717* + ID_PRODUCT_FROM_DATABASE=NC364m Quad Port 1GbE BL-c Adapter + +pci:v00008086d000010DB* + ID_PRODUCT_FROM_DATABASE=82598EB 10-Gigabit Dual Port Network Connection + +pci:v00008086d000010DD* + ID_PRODUCT_FROM_DATABASE=82598EB 10-Gigabit AT CX4 Network Connection + +pci:v00008086d000010DE* + ID_PRODUCT_FROM_DATABASE=82567LM-3 Gigabit Network Connection + +pci:v00008086d000010DF* + ID_PRODUCT_FROM_DATABASE=82567LF-3 Gigabit Network Connection + +pci:v00008086d000010E1* + ID_PRODUCT_FROM_DATABASE=82598EB 10-Gigabit AF Dual Port Network Connection + +pci:v00008086d000010E1sv00008086sd0000A15F* + ID_PRODUCT_FROM_DATABASE=10-Gigabit SR Dual Port Express Module + +pci:v00008086d000010E2* + ID_PRODUCT_FROM_DATABASE=82575GB Gigabit Network Connection + +pci:v00008086d000010E2sv00008086sd000010E2* + ID_PRODUCT_FROM_DATABASE=Gigabit VT Quad Port Server Adapter + +pci:v00008086d000010E5* + ID_PRODUCT_FROM_DATABASE=82567LM-4 Gigabit Network Connection + +pci:v00008086d000010E6* + ID_PRODUCT_FROM_DATABASE=82576 Gigabit Network Connection + +pci:v00008086d000010E6sv00008086sd0000A01F* + ID_PRODUCT_FROM_DATABASE=Gigabit EF Dual Port Server Adapter + +pci:v00008086d000010E6sv00008086sd0000A02F* + ID_PRODUCT_FROM_DATABASE=Gigabit EF Dual Port Server Adapter + +pci:v00008086d000010E7* + ID_PRODUCT_FROM_DATABASE=82576 Gigabit Network Connection + +pci:v00008086d000010E7sv0000103Csd000031FF* + ID_PRODUCT_FROM_DATABASE=NC362i Integrated Dual Port BL-c Gigabit Server Adapter + +pci:v00008086d000010E8* + ID_PRODUCT_FROM_DATABASE=82576 Gigabit Network Connection + +pci:v00008086d000010E8sv00008086sd0000A02B* + ID_PRODUCT_FROM_DATABASE=Gigabit ET Quad Port Server Adapter + +pci:v00008086d000010E8sv00008086sd0000A02C* + ID_PRODUCT_FROM_DATABASE=Gigabit ET Quad Port Server Adapter + +pci:v00008086d000010EA* + ID_PRODUCT_FROM_DATABASE=82577LM Gigabit Network Connection + +pci:v00008086d000010EAsv00001028sd0000040A* + ID_PRODUCT_FROM_DATABASE=Latitude E6410 + +pci:v00008086d000010EAsv00001028sd0000040B* + ID_PRODUCT_FROM_DATABASE=Latitude E6510 + +pci:v00008086d000010EAsv0000E4BFsd000050C1* + ID_PRODUCT_FROM_DATABASE=PC1-GROOVE + +pci:v00008086d000010EB* + ID_PRODUCT_FROM_DATABASE=82577LC Gigabit Network Connection + +pci:v00008086d000010EC* + ID_PRODUCT_FROM_DATABASE=82598EB 10-Gigabit AT CX4 Network Connection + +pci:v00008086d000010ECsv00008086sd0000A01F* + ID_PRODUCT_FROM_DATABASE=10-Gigabit CX4 Dual Port Server Adapter + +pci:v00008086d000010ECsv00008086sd0000A11F* + ID_PRODUCT_FROM_DATABASE=10-Gigabit CX4 Dual Port Server Adapter + +pci:v00008086d000010ED* + ID_PRODUCT_FROM_DATABASE=82599 Ethernet Controller Virtual Function + +pci:v00008086d000010EF* + ID_PRODUCT_FROM_DATABASE=82578DM Gigabit Network Connection + +pci:v00008086d000010EFsv00001028sd000002DA* + ID_PRODUCT_FROM_DATABASE=OptiPlex 980 + +pci:v00008086d000010F0* + ID_PRODUCT_FROM_DATABASE=82578DC Gigabit Network Connection + +pci:v00008086d000010F1* + ID_PRODUCT_FROM_DATABASE=82598EB 10-Gigabit AF Dual Port Network Connection + +pci:v00008086d000010F1sv00008086sd0000A20F* + ID_PRODUCT_FROM_DATABASE=10-Gigabit AF DA Dual Port Server Adapter + +pci:v00008086d000010F1sv00008086sd0000A21F* + ID_PRODUCT_FROM_DATABASE=10-Gigabit AF DA Dual Port Server Adapter + +pci:v00008086d000010F4* + ID_PRODUCT_FROM_DATABASE=82598EB 10-Gigabit AF Network Connection + +pci:v00008086d000010F4sv00008086sd0000106F* + ID_PRODUCT_FROM_DATABASE=10-Gigabit XF LR Server Adapter + +pci:v00008086d000010F4sv00008086sd0000A06F* + ID_PRODUCT_FROM_DATABASE=10-Gigabit XF LR Server Adapter + +pci:v00008086d000010F5* + ID_PRODUCT_FROM_DATABASE=82567LM Gigabit Network Connection + +pci:v00008086d000010F6* + ID_PRODUCT_FROM_DATABASE=82574L Gigabit Network Connection + +pci:v00008086d000010F7* + ID_PRODUCT_FROM_DATABASE=82599EB 10-Gigabit KX4 Network Connection + +pci:v00008086d000010F7sv0000108Esd00007B12* + ID_PRODUCT_FROM_DATABASE=Sun Dual 10GbE PCIe 2.0 FEM + +pci:v00008086d000010F7sv00008086sd0000000D* + ID_PRODUCT_FROM_DATABASE=Ethernet Mezzanine Adapter X520-KX4-2 + +pci:v00008086d000010F8* + ID_PRODUCT_FROM_DATABASE=82599EB 10 Gigabit Dual Port Backplane Connection + +pci:v00008086d000010F8sv00001028sd00001F63* + ID_PRODUCT_FROM_DATABASE=10GbE 2P X520k bNDC + +pci:v00008086d000010F8sv0000103Csd000017D2* + ID_PRODUCT_FROM_DATABASE=Ethernet 10Gb 2-port 560M Adapter + +pci:v00008086d000010F8sv0000103Csd000018D0* + ID_PRODUCT_FROM_DATABASE=Ethernet 10Gb 2-port 560FLB Adapter + +pci:v00008086d000010F8sv00008086sd0000000C* + ID_PRODUCT_FROM_DATABASE=Ethernet X520 10GbE Dual Port KX4-KR Mezz + +pci:v00008086d000010F9* + ID_PRODUCT_FROM_DATABASE=82599EB 10 Gigabit CX4 Dual Port Network Connection + +pci:v00008086d000010FB* + ID_PRODUCT_FROM_DATABASE=82599EB 10-Gigabit SFI/SFP+ Network Connection + +pci:v00008086d000010FBsv00001028sd00001F72* + ID_PRODUCT_FROM_DATABASE=Ethernet 10G 4P X520/I350 rNDC + +pci:v00008086d000010FBsv0000103Csd000017D0* + ID_PRODUCT_FROM_DATABASE=Ethernet 10Gb 2-port 560FLR-SFP+ Adapter + +pci:v00008086d000010FBsv0000103Csd000017D2* + ID_PRODUCT_FROM_DATABASE=Ethernet 10Gb 2-port 560M Adapter + +pci:v00008086d000010FBsv0000103Csd000017D3* + ID_PRODUCT_FROM_DATABASE=Ethernet 10Gb 2-port 560SFP+ Adapter + +pci:v00008086d000010FBsv0000108Esd00007B11* + ID_PRODUCT_FROM_DATABASE=Ethernet Server Adapter X520-2 + +pci:v00008086d000010FBsv00001734sd000011A9* + ID_PRODUCT_FROM_DATABASE=10 Gigabit Dual Port Network Connection + +pci:v00008086d000010FBsv00008086sd00000002* + ID_PRODUCT_FROM_DATABASE=Ethernet Server Adapter X520-DA2 + +pci:v00008086d000010FBsv00008086sd00000003* + ID_PRODUCT_FROM_DATABASE=Ethernet Server Adapter X520-2 + +pci:v00008086d000010FBsv00008086sd00000006* + ID_PRODUCT_FROM_DATABASE=Ethernet Server Adapter X520-1 + +pci:v00008086d000010FBsv00008086sd0000000A* + ID_PRODUCT_FROM_DATABASE=Ethernet Server Adapter X520-1 + +pci:v00008086d000010FBsv00008086sd0000000C* + ID_PRODUCT_FROM_DATABASE=Ethernet Server Adapter X520-2 + +pci:v00008086d000010FBsv00008086sd00007A11* + ID_PRODUCT_FROM_DATABASE=Ethernet Server Adapter X520-2 + +pci:v00008086d000010FBsv00008086sd00007A12* + ID_PRODUCT_FROM_DATABASE=Ethernet Server Adapter X520-2 + +pci:v00008086d000010FC* + ID_PRODUCT_FROM_DATABASE=82599EB 10-Gigabit XAUI/BX4 Network Connection + +pci:v00008086d000010FE* + ID_PRODUCT_FROM_DATABASE=82552 10/100 Network Connection + +pci:v00008086d00001107* + ID_PRODUCT_FROM_DATABASE=PRO/1000 MF Server Adapter (LX) + +pci:v00008086d00001130* + ID_PRODUCT_FROM_DATABASE=82815 815 Chipset Host Bridge and Memory Controller Hub + +pci:v00008086d00001130sv00001025sd00001016* + ID_PRODUCT_FROM_DATABASE=Travelmate 612 TX + +pci:v00008086d00001130sv00001043sd00008027* + ID_PRODUCT_FROM_DATABASE=TUSL2-C Mainboard + +pci:v00008086d00001130sv0000104Dsd000080DF* + ID_PRODUCT_FROM_DATABASE=Vaio PCG-FX403 + +pci:v00008086d00001130sv00008086sd00004532* + ID_PRODUCT_FROM_DATABASE=D815EEA2 mainboard + +pci:v00008086d00001130sv00008086sd00004557* + ID_PRODUCT_FROM_DATABASE=D815EGEW Mainboard + +pci:v00008086d00001131* + ID_PRODUCT_FROM_DATABASE=82815 815 Chipset AGP Bridge + +pci:v00008086d00001132* + ID_PRODUCT_FROM_DATABASE=82815 Chipset Graphics Controller (CGC) + +pci:v00008086d00001132sv00001025sd00001016* + ID_PRODUCT_FROM_DATABASE=Travelmate 612 TX + +pci:v00008086d00001132sv0000103Csd00002001* + ID_PRODUCT_FROM_DATABASE=e-pc 40 + +pci:v00008086d00001132sv0000104Dsd000080DF* + ID_PRODUCT_FROM_DATABASE=Vaio PCG-FX403 + +pci:v00008086d00001132sv00008086sd00004532* + ID_PRODUCT_FROM_DATABASE=D815EEA2 Mainboard + +pci:v00008086d00001132sv00008086sd00004541* + ID_PRODUCT_FROM_DATABASE=D815EEA Motherboard + +pci:v00008086d00001132sv00008086sd00004557* + ID_PRODUCT_FROM_DATABASE=D815EGEW Mainboard + +pci:v00008086d00001161* + ID_PRODUCT_FROM_DATABASE=82806AA PCI64 Hub Advanced Programmable Interrupt Controller + +pci:v00008086d00001161sv00008086sd00001161* + ID_PRODUCT_FROM_DATABASE=82806AA PCI64 Hub APIC + +pci:v00008086d00001162* + ID_PRODUCT_FROM_DATABASE=Xscale 80200 Big Endian Companion Chip + +pci:v00008086d00001200* + ID_PRODUCT_FROM_DATABASE=IXP1200 Network Processor + +pci:v00008086d00001200sv0000172Asd00000000* + ID_PRODUCT_FROM_DATABASE=AEP SSL Accelerator + +pci:v00008086d00001209* + ID_PRODUCT_FROM_DATABASE=8255xER/82551IT Fast Ethernet Controller + +pci:v00008086d00001209sv0000140Bsd00000610* + ID_PRODUCT_FROM_DATABASE=PMC610 quad Ethernet board + +pci:v00008086d00001209sv00004C53sd00001050* + ID_PRODUCT_FROM_DATABASE=CT7 mainboard + +pci:v00008086d00001209sv00004C53sd00001051* + ID_PRODUCT_FROM_DATABASE=CE7 mainboard + +pci:v00008086d00001209sv00004C53sd00001070* + ID_PRODUCT_FROM_DATABASE=PC6 mainboard + +pci:v00008086d00001221* + ID_PRODUCT_FROM_DATABASE=82092AA PCI to PCMCIA Bridge + +pci:v00008086d00001222* + ID_PRODUCT_FROM_DATABASE=82092AA IDE Controller + +pci:v00008086d00001223* + ID_PRODUCT_FROM_DATABASE=SAA7116 + +pci:v00008086d00001225* + ID_PRODUCT_FROM_DATABASE=82452KX/GX [Orion] + +pci:v00008086d00001226* + ID_PRODUCT_FROM_DATABASE=82596 PRO/10 PCI + +pci:v00008086d00001227* + ID_PRODUCT_FROM_DATABASE=82865 EtherExpress PRO/100A + +pci:v00008086d00001228* + ID_PRODUCT_FROM_DATABASE=82556 EtherExpress PRO/100 Smart + +pci:v00008086d00001229* + ID_PRODUCT_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 + +pci:v00008086d00001229sv00000E11sd00003001* + ID_PRODUCT_FROM_DATABASE=82559 Fast Ethernet LOM with Alert on LAN* + +pci:v00008086d00001229sv00000E11sd00003002* + ID_PRODUCT_FROM_DATABASE=82559 Fast Ethernet LOM with Alert on LAN* + +pci:v00008086d00001229sv00000E11sd00003003* + ID_PRODUCT_FROM_DATABASE=82559 Fast Ethernet LOM with Alert on LAN* + +pci:v00008086d00001229sv00000E11sd00003004* + ID_PRODUCT_FROM_DATABASE=82559 Fast Ethernet LOM with Alert on LAN* + +pci:v00008086d00001229sv00000E11sd00003005* + ID_PRODUCT_FROM_DATABASE=82559 Fast Ethernet LOM with Alert on LAN* + +pci:v00008086d00001229sv00000E11sd00003006* + ID_PRODUCT_FROM_DATABASE=82559 Fast Ethernet LOM with Alert on LAN* + +pci:v00008086d00001229sv00000E11sd00003007* + ID_PRODUCT_FROM_DATABASE=82559 Fast Ethernet LOM with Alert on LAN* + +pci:v00008086d00001229sv00000E11sd0000B01E* + ID_PRODUCT_FROM_DATABASE=NC3120 Fast Ethernet NIC + +pci:v00008086d00001229sv00000E11sd0000B01F* + ID_PRODUCT_FROM_DATABASE=NC3122 Fast Ethernet NIC (dual port) + +pci:v00008086d00001229sv00000E11sd0000B02F* + ID_PRODUCT_FROM_DATABASE=NC1120 Ethernet NIC + +pci:v00008086d00001229sv00000E11sd0000B04A* + ID_PRODUCT_FROM_DATABASE=Netelligent 10/100TX NIC with Wake on LAN + +pci:v00008086d00001229sv00000E11sd0000B0C6* + ID_PRODUCT_FROM_DATABASE=NC3161 Fast Ethernet NIC (embedded, WOL) + +pci:v00008086d00001229sv00000E11sd0000B0C7* + ID_PRODUCT_FROM_DATABASE=NC3160 Fast Ethernet NIC (embedded) + +pci:v00008086d00001229sv00000E11sd0000B0D7* + ID_PRODUCT_FROM_DATABASE=NC3121 Fast Ethernet NIC (WOL) + +pci:v00008086d00001229sv00000E11sd0000B0DD* + ID_PRODUCT_FROM_DATABASE=NC3131 Fast Ethernet NIC (dual port) + +pci:v00008086d00001229sv00000E11sd0000B0DE* + ID_PRODUCT_FROM_DATABASE=NC3132 Fast Ethernet Module (dual port) + +pci:v00008086d00001229sv00000E11sd0000B0E1* + ID_PRODUCT_FROM_DATABASE=NC3133 Fast Ethernet Module (100-FX) + +pci:v00008086d00001229sv00000E11sd0000B134* + ID_PRODUCT_FROM_DATABASE=NC3163 Fast Ethernet NIC (embedded, WOL) + +pci:v00008086d00001229sv00000E11sd0000B13C* + ID_PRODUCT_FROM_DATABASE=NC3162 Fast Ethernet NIC (embedded) + +pci:v00008086d00001229sv00000E11sd0000B144* + ID_PRODUCT_FROM_DATABASE=NC3123 Fast Ethernet NIC (WOL) + +pci:v00008086d00001229sv00000E11sd0000B163* + ID_PRODUCT_FROM_DATABASE=NC3134 Fast Ethernet NIC (dual port) + +pci:v00008086d00001229sv00000E11sd0000B164* + ID_PRODUCT_FROM_DATABASE=NC3135 Fast Ethernet Upgrade Module (dual port) + +pci:v00008086d00001229sv00000E11sd0000B1A4* + ID_PRODUCT_FROM_DATABASE=NC7131 Gigabit Server Adapter + +pci:v00008086d00001229sv00001014sd0000005C* + ID_PRODUCT_FROM_DATABASE=82558B Ethernet Pro 10/100 + +pci:v00008086d00001229sv00001014sd000001BC* + ID_PRODUCT_FROM_DATABASE=82559 Fast Ethernet LAN On Motherboard + +pci:v00008086d00001229sv00001014sd000001F1* + ID_PRODUCT_FROM_DATABASE=10/100 Ethernet Server Adapter + +pci:v00008086d00001229sv00001014sd000001F2* + ID_PRODUCT_FROM_DATABASE=10/100 Ethernet Server Adapter + +pci:v00008086d00001229sv00001014sd00000207* + ID_PRODUCT_FROM_DATABASE=Ethernet Pro/100 S + +pci:v00008086d00001229sv00001014sd00000232* + ID_PRODUCT_FROM_DATABASE=10/100 Dual Port Server Adapter + +pci:v00008086d00001229sv00001014sd0000023A* + ID_PRODUCT_FROM_DATABASE=ThinkPad R30 + +pci:v00008086d00001229sv00001014sd0000105C* + ID_PRODUCT_FROM_DATABASE=Netfinity 10/100 + +pci:v00008086d00001229sv00001014sd00002205* + ID_PRODUCT_FROM_DATABASE=ThinkPad A22p + +pci:v00008086d00001229sv00001014sd0000305C* + ID_PRODUCT_FROM_DATABASE=10/100 EtherJet Management Adapter + +pci:v00008086d00001229sv00001014sd0000405C* + ID_PRODUCT_FROM_DATABASE=10/100 EtherJet Adapter with Alert on LAN + +pci:v00008086d00001229sv00001014sd0000505C* + ID_PRODUCT_FROM_DATABASE=10/100 EtherJet Secure Management Adapter + +pci:v00008086d00001229sv00001014sd0000605C* + ID_PRODUCT_FROM_DATABASE=10/100 EtherJet Secure Management Adapter + +pci:v00008086d00001229sv00001014sd0000705C* + ID_PRODUCT_FROM_DATABASE=10/100 Netfinity 10/100 Ethernet Security Adapter + +pci:v00008086d00001229sv00001014sd0000805C* + ID_PRODUCT_FROM_DATABASE=10/100 Netfinity 10/100 Ethernet Security Adapter + +pci:v00008086d00001229sv00001028sd0000009B* + ID_PRODUCT_FROM_DATABASE=10/100 Ethernet Server Adapter + +pci:v00008086d00001229sv00001028sd000000CE* + ID_PRODUCT_FROM_DATABASE=10/100 Ethernet Server Adapter + +pci:v00008086d00001229sv00001033sd00008000* + ID_PRODUCT_FROM_DATABASE=PC-9821X-B06 + +pci:v00008086d00001229sv00001033sd00008016* + ID_PRODUCT_FROM_DATABASE=PK-UG-X006 + +pci:v00008086d00001229sv00001033sd0000801F* + ID_PRODUCT_FROM_DATABASE=PK-UG-X006 + +pci:v00008086d00001229sv00001033sd00008026* + ID_PRODUCT_FROM_DATABASE=PK-UG-X006 + +pci:v00008086d00001229sv00001033sd00008063* + ID_PRODUCT_FROM_DATABASE=82559-based Fast Ethernet Adapter + +pci:v00008086d00001229sv00001033sd00008064* + ID_PRODUCT_FROM_DATABASE=82559-based Fast Ethernet Adapter + +pci:v00008086d00001229sv0000103Csd000010C0* + ID_PRODUCT_FROM_DATABASE=NetServer 10/100TX + +pci:v00008086d00001229sv0000103Csd000010C3* + ID_PRODUCT_FROM_DATABASE=NetServer 10/100TX + +pci:v00008086d00001229sv0000103Csd000010CA* + ID_PRODUCT_FROM_DATABASE=NetServer 10/100TX + +pci:v00008086d00001229sv0000103Csd000010CB* + ID_PRODUCT_FROM_DATABASE=NetServer 10/100TX + +pci:v00008086d00001229sv0000103Csd000010E3* + ID_PRODUCT_FROM_DATABASE=NetServer 10/100TX + +pci:v00008086d00001229sv0000103Csd000010E4* + ID_PRODUCT_FROM_DATABASE=NetServer 10/100TX + +pci:v00008086d00001229sv0000103Csd00001200* + ID_PRODUCT_FROM_DATABASE=NetServer 10/100TX + +pci:v00008086d00001229sv0000108Esd000010CF* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100(B) + +pci:v00008086d00001229sv000010C3sd00001100* + ID_PRODUCT_FROM_DATABASE=SmartEther100 SC1100 + +pci:v00008086d00001229sv000010CFsd00001115* + ID_PRODUCT_FROM_DATABASE=8255x-based Ethernet Adapter (10/100) + +pci:v00008086d00001229sv000010CFsd00001143* + ID_PRODUCT_FROM_DATABASE=8255x-based Ethernet Adapter (10/100) + +pci:v00008086d00001229sv0000110Asd0000008B* + ID_PRODUCT_FROM_DATABASE=82551QM Fast Ethernet Multifuction PCI/CardBus Controller + +pci:v00008086d00001229sv0000114Asd00000582* + ID_PRODUCT_FROM_DATABASE=PC8 onboard ethernet ETH2 + +pci:v00008086d00001229sv00001179sd00000001* + ID_PRODUCT_FROM_DATABASE=8255x-based Ethernet Adapter (10/100) + +pci:v00008086d00001229sv00001179sd00000002* + ID_PRODUCT_FROM_DATABASE=PCI FastEther LAN on Docker + +pci:v00008086d00001229sv00001179sd00000003* + ID_PRODUCT_FROM_DATABASE=8255x-based Fast Ethernet + +pci:v00008086d00001229sv00001259sd00002560* + ID_PRODUCT_FROM_DATABASE=AT-2560 100 + +pci:v00008086d00001229sv00001259sd00002561* + ID_PRODUCT_FROM_DATABASE=AT-2560 100 FX Ethernet Adapter + +pci:v00008086d00001229sv00001266sd00000001* + ID_PRODUCT_FROM_DATABASE=NE10/100 Adapter + +pci:v00008086d00001229sv000013E9sd00001000* + ID_PRODUCT_FROM_DATABASE=6221L-4U + +pci:v00008086d00001229sv0000144Dsd00002501* + ID_PRODUCT_FROM_DATABASE=SEM-2000 MiniPCI LAN Adapter + +pci:v00008086d00001229sv0000144Dsd00002502* + ID_PRODUCT_FROM_DATABASE=SEM-2100IL MiniPCI LAN Adapter + +pci:v00008086d00001229sv00001668sd00001100* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100B (TX) (MiniPCI Ethernet+Modem) + +pci:v00008086d00001229sv00001775sd00001100* + ID_PRODUCT_FROM_DATABASE=CR11/VR11 Single Board Computer + +pci:v00008086d00001229sv00001775sd0000CE90* + ID_PRODUCT_FROM_DATABASE=CE9 + +pci:v00008086d00001229sv00004C53sd00001080* + ID_PRODUCT_FROM_DATABASE=CT8 mainboard + +pci:v00008086d00001229sv00004C53sd000010E0* + ID_PRODUCT_FROM_DATABASE=PSL09 PrPMC + +pci:v00008086d00001229sv00008086sd00000001* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100B (TX) + +pci:v00008086d00001229sv00008086sd00000002* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100B (T4) + +pci:v00008086d00001229sv00008086sd00000003* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/10+ + +pci:v00008086d00001229sv00008086sd00000004* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 WfM + +pci:v00008086d00001229sv00008086sd00000005* + ID_PRODUCT_FROM_DATABASE=82557 10/100 + +pci:v00008086d00001229sv00008086sd00000006* + ID_PRODUCT_FROM_DATABASE=82557 10/100 with Wake on LAN + +pci:v00008086d00001229sv00008086sd00000007* + ID_PRODUCT_FROM_DATABASE=82558 10/100 Adapter + +pci:v00008086d00001229sv00008086sd00000008* + ID_PRODUCT_FROM_DATABASE=82558 10/100 with Wake on LAN + +pci:v00008086d00001229sv00008086sd00000009* + ID_PRODUCT_FROM_DATABASE=82558B PRO/100+ PCI (TP) + +pci:v00008086d00001229sv00008086sd0000000A* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100+ Management Adapter + +pci:v00008086d00001229sv00008086sd0000000B* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100+ + +pci:v00008086d00001229sv00008086sd0000000C* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100+ Management Adapter + +pci:v00008086d00001229sv00008086sd0000000D* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100+ Alert On LAN II* Adapter + +pci:v00008086d00001229sv00008086sd0000000E* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100+ Management Adapter with Alert On LAN* + +pci:v00008086d00001229sv00008086sd0000000F* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 Desktop Adapter + +pci:v00008086d00001229sv00008086sd00000010* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 S Management Adapter + +pci:v00008086d00001229sv00008086sd00000011* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 S Management Adapter + +pci:v00008086d00001229sv00008086sd00000012* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 S Advanced Management Adapter (D) + +pci:v00008086d00001229sv00008086sd00000013* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 S Advanced Management Adapter (E) + +pci:v00008086d00001229sv00008086sd00000030* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 Management Adapter with Alert On LAN* GC + +pci:v00008086d00001229sv00008086sd00000031* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 Desktop Adapter + +pci:v00008086d00001229sv00008086sd00000040* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 S Desktop Adapter + +pci:v00008086d00001229sv00008086sd00000041* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 S Desktop Adapter + +pci:v00008086d00001229sv00008086sd00000042* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 Desktop Adapter + +pci:v00008086d00001229sv00008086sd00000050* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 S Desktop Adapter + +pci:v00008086d00001229sv00008086sd00001009* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100+ Server Adapter + +pci:v00008086d00001229sv00008086sd0000100C* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100+ Server Adapter (PILA8470B) + +pci:v00008086d00001229sv00008086sd00001012* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 S Server Adapter (D) + +pci:v00008086d00001229sv00008086sd00001013* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 S Server Adapter (E) + +pci:v00008086d00001229sv00008086sd00001015* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 S Dual Port Server Adapter + +pci:v00008086d00001229sv00008086sd00001017* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100+ Dual Port Server Adapter + +pci:v00008086d00001229sv00008086sd00001030* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100+ Management Adapter with Alert On LAN* G Server + +pci:v00008086d00001229sv00008086sd00001040* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 S Server Adapter + +pci:v00008086d00001229sv00008086sd00001041* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 S Server Adapter + +pci:v00008086d00001229sv00008086sd00001042* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 Server Adapter + +pci:v00008086d00001229sv00008086sd00001050* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 S Server Adapter + +pci:v00008086d00001229sv00008086sd00001051* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 Server Adapter + +pci:v00008086d00001229sv00008086sd00001052* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 Server Adapter + +pci:v00008086d00001229sv00008086sd000010F0* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100+ Dual Port Adapter + +pci:v00008086d00001229sv00008086sd00001229* + ID_PRODUCT_FROM_DATABASE=82557/8/9 [Ethernet Pro 100] + +pci:v00008086d00001229sv00008086sd00002009* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 S Mobile Adapter + +pci:v00008086d00001229sv00008086sd0000200D* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 Cardbus + +pci:v00008086d00001229sv00008086sd0000200E* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 LAN+V90 Cardbus Modem + +pci:v00008086d00001229sv00008086sd0000200F* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 SR Mobile Adapter + +pci:v00008086d00001229sv00008086sd00002010* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 S Mobile Combo Adapter + +pci:v00008086d00001229sv00008086sd00002013* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 SR Mobile Combo Adapter + +pci:v00008086d00001229sv00008086sd00002016* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 S Mobile Adapter + +pci:v00008086d00001229sv00008086sd00002017* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 S Combo Mobile Adapter + +pci:v00008086d00001229sv00008086sd00002018* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 SR Mobile Adapter + +pci:v00008086d00001229sv00008086sd00002019* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 SR Combo Mobile Adapter + +pci:v00008086d00001229sv00008086sd00002101* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 P Mobile Adapter + +pci:v00008086d00001229sv00008086sd00002102* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 SP Mobile Adapter + +pci:v00008086d00001229sv00008086sd00002103* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 SP Mobile Adapter + +pci:v00008086d00001229sv00008086sd00002104* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 SP Mobile Adapter + +pci:v00008086d00001229sv00008086sd00002105* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 SP Mobile Adapter + +pci:v00008086d00001229sv00008086sd00002106* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 P Mobile Adapter + +pci:v00008086d00001229sv00008086sd00002107* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 Network Connection + +pci:v00008086d00001229sv00008086sd00002108* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 Network Connection + +pci:v00008086d00001229sv00008086sd00002200* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 P Mobile Combo Adapter + +pci:v00008086d00001229sv00008086sd00002201* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 P Mobile Combo Adapter + +pci:v00008086d00001229sv00008086sd00002202* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 SP Mobile Combo Adapter + +pci:v00008086d00001229sv00008086sd00002203* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100+ MiniPCI + +pci:v00008086d00001229sv00008086sd00002204* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100+ MiniPCI + +pci:v00008086d00001229sv00008086sd00002205* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 SP Mobile Combo Adapter + +pci:v00008086d00001229sv00008086sd00002206* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 SP Mobile Combo Adapter + +pci:v00008086d00001229sv00008086sd00002207* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 SP Mobile Combo Adapter + +pci:v00008086d00001229sv00008086sd00002208* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 P Mobile Combo Adapter + +pci:v00008086d00001229sv00008086sd00002402* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100+ MiniPCI + +pci:v00008086d00001229sv00008086sd00002407* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100+ MiniPCI + +pci:v00008086d00001229sv00008086sd00002408* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100+ MiniPCI + +pci:v00008086d00001229sv00008086sd00002409* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100+ MiniPCI + +pci:v00008086d00001229sv00008086sd0000240F* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100+ MiniPCI + +pci:v00008086d00001229sv00008086sd00002410* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100+ MiniPCI + +pci:v00008086d00001229sv00008086sd00002411* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100+ MiniPCI + +pci:v00008086d00001229sv00008086sd00002412* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100+ MiniPCI + +pci:v00008086d00001229sv00008086sd00002413* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100+ MiniPCI + +pci:v00008086d00001229sv00008086sd00003000* + ID_PRODUCT_FROM_DATABASE=82559 Fast Ethernet LAN on Motherboard + +pci:v00008086d00001229sv00008086sd00003001* + ID_PRODUCT_FROM_DATABASE=82559 Fast Ethernet LOM with Basic Alert on LAN* + +pci:v00008086d00001229sv00008086sd00003002* + ID_PRODUCT_FROM_DATABASE=82559 Fast Ethernet LOM with Alert on LAN II* + +pci:v00008086d00001229sv00008086sd00003006* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 S Network Connection + +pci:v00008086d00001229sv00008086sd00003007* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 S Network Connection + +pci:v00008086d00001229sv00008086sd00003008* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 Network Connection + +pci:v00008086d00001229sv00008086sd00003010* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 S Network Connection + +pci:v00008086d00001229sv00008086sd00003011* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 S Network Connection + +pci:v00008086d00001229sv00008086sd00003012* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 Network Connection + +pci:v00008086d00001229sv00008086sd0000301A* + ID_PRODUCT_FROM_DATABASE=S845WD1-E mainboard + +pci:v00008086d00001229sv00008086sd00003411* + ID_PRODUCT_FROM_DATABASE=SDS2 Mainboard + +pci:v00008086d0000122D* + ID_PRODUCT_FROM_DATABASE=430FX - 82437FX TSC [Triton I] + +pci:v00008086d0000122E* + ID_PRODUCT_FROM_DATABASE=82371FB PIIX ISA [Triton I] + +pci:v00008086d00001230* + ID_PRODUCT_FROM_DATABASE=82371FB PIIX IDE [Triton I] + +pci:v00008086d00001231* + ID_PRODUCT_FROM_DATABASE=DSVD Modem + +pci:v00008086d00001234* + ID_PRODUCT_FROM_DATABASE=430MX - 82371MX Mobile PCI I/O IDE Xcelerator (MPIIX) + +pci:v00008086d00001235* + ID_PRODUCT_FROM_DATABASE=430MX - 82437MX Mob. System Ctrlr (MTSC) & 82438MX Data Path (MTDP) + +pci:v00008086d00001237* + ID_PRODUCT_FROM_DATABASE=440FX - 82441FX PMC [Natoma] + +pci:v00008086d00001237sv00001AF4sd00001100* + ID_PRODUCT_FROM_DATABASE=Qemu virtual machine + +pci:v00008086d00001239* + ID_PRODUCT_FROM_DATABASE=82371FB PIIX IDE Interface + +pci:v00008086d0000123B* + ID_PRODUCT_FROM_DATABASE=82380PB PCI to PCI Docking Bridge + +pci:v00008086d0000123C* + ID_PRODUCT_FROM_DATABASE=82380AB (MISA) Mobile PCI-to-ISA Bridge + +pci:v00008086d0000123D* + ID_PRODUCT_FROM_DATABASE=683053 Programmable Interrupt Device + +pci:v00008086d0000123E* + ID_PRODUCT_FROM_DATABASE=82466GX (IHPC) Integrated Hot-Plug Controller (hidden mode) + +pci:v00008086d0000123F* + ID_PRODUCT_FROM_DATABASE=82466GX Integrated Hot-Plug Controller (IHPC) + +pci:v00008086d00001240* + ID_PRODUCT_FROM_DATABASE=82752 (752) AGP Graphics Accelerator + +pci:v00008086d0000124B* + ID_PRODUCT_FROM_DATABASE=82380FB (MPCI2) Mobile Docking Controller + +pci:v00008086d00001250* + ID_PRODUCT_FROM_DATABASE=430HX - 82439HX TXC [Triton II] + +pci:v00008086d00001360* + ID_PRODUCT_FROM_DATABASE=82806AA PCI64 Hub PCI Bridge + +pci:v00008086d00001361* + ID_PRODUCT_FROM_DATABASE=82806AA PCI64 Hub Controller (HRes) + +pci:v00008086d00001361sv00008086sd00001361* + ID_PRODUCT_FROM_DATABASE=82806AA PCI64 Hub Controller (HRes) + +pci:v00008086d00001361sv00008086sd00008000* + ID_PRODUCT_FROM_DATABASE=82806AA PCI64 Hub Controller (HRes) + +pci:v00008086d00001460* + ID_PRODUCT_FROM_DATABASE=82870P2 P64H2 Hub PCI Bridge + +pci:v00008086d00001461* + ID_PRODUCT_FROM_DATABASE=82870P2 P64H2 I/OxAPIC + +pci:v00008086d00001461sv000015D9sd00003480* + ID_PRODUCT_FROM_DATABASE=P4DP6 + +pci:v00008086d00001461sv00004C53sd00001090* + ID_PRODUCT_FROM_DATABASE=Cx9/Vx9 mainboard + +pci:v00008086d00001462* + ID_PRODUCT_FROM_DATABASE=82870P2 P64H2 Hot Plug Controller + +pci:v00008086d00001501* + ID_PRODUCT_FROM_DATABASE=82567V-3 Gigabit Network Connection + +pci:v00008086d00001502* + ID_PRODUCT_FROM_DATABASE=82579LM Gigabit Network Connection + +pci:v00008086d00001503* + ID_PRODUCT_FROM_DATABASE=82579V Gigabit Network Connection + +pci:v00008086d00001503sv00001043sd0000849C* + ID_PRODUCT_FROM_DATABASE=P8P67 Deluxe Motherboard + +pci:v00008086d00001507* + ID_PRODUCT_FROM_DATABASE=82599EB 10 Gigabit Network Connection + +pci:v00008086d00001508* + ID_PRODUCT_FROM_DATABASE=82598EB Gigabit BX Network Connection + +pci:v00008086d0000150A* + ID_PRODUCT_FROM_DATABASE=82576NS Gigabit Network Connection + +pci:v00008086d0000150B* + ID_PRODUCT_FROM_DATABASE=82598EB 10-Gigabit AT2 Server Adapter + +pci:v00008086d0000150Bsv00008086sd0000A10C* + ID_PRODUCT_FROM_DATABASE=82598EB 10-Gigabit AT2 Server Adapter + +pci:v00008086d0000150Bsv00008086sd0000A11C* + ID_PRODUCT_FROM_DATABASE=82598EB 10-Gigabit AT2 Server Adapter + +pci:v00008086d0000150Bsv00008086sd0000A12C* + ID_PRODUCT_FROM_DATABASE=82598EB 10-Gigabit AT2 Server Adapter + +pci:v00008086d0000150C* + ID_PRODUCT_FROM_DATABASE=82583V Gigabit Network Connection + +pci:v00008086d0000150D* + ID_PRODUCT_FROM_DATABASE=82576 Gigabit Backplane Connection + +pci:v00008086d0000150Dsv00008086sd0000A10C* + ID_PRODUCT_FROM_DATABASE=Gigabit ET Quad Port Mezzanine Card + +pci:v00008086d0000150E* + ID_PRODUCT_FROM_DATABASE=82580 Gigabit Network Connection + +pci:v00008086d0000150Esv0000103Csd00001780* + ID_PRODUCT_FROM_DATABASE=NC365T 4-port Ethernet Server Adapter + +pci:v00008086d0000150Esv00008086sd000012A1* + ID_PRODUCT_FROM_DATABASE=Ethernet Server Adapter I340-T4 + +pci:v00008086d0000150Esv00008086sd000012A2* + ID_PRODUCT_FROM_DATABASE=Ethernet Server Adapter I340-T4 + +pci:v00008086d0000150F* + ID_PRODUCT_FROM_DATABASE=82580 Gigabit Fiber Network Connection + +pci:v00008086d00001510* + ID_PRODUCT_FROM_DATABASE=82580 Gigabit Backplane Connection + +pci:v00008086d00001511* + ID_PRODUCT_FROM_DATABASE=82580 Gigabit SFP Connection + +pci:v00008086d00001514* + ID_PRODUCT_FROM_DATABASE=82599EB 10 Gigabit KX4 Network Connection + +pci:v00008086d00001514sv00008086sd0000000B* + ID_PRODUCT_FROM_DATABASE=Ethernet X520 10GbE Dual Port KX4 Mezz + +pci:v00008086d00001515* + ID_PRODUCT_FROM_DATABASE=X540 Ethernet Controller Virtual Function + +pci:v00008086d00001516* + ID_PRODUCT_FROM_DATABASE=82580 Gigabit Network Connection + +pci:v00008086d00001516sv00008086sd000012B1* + ID_PRODUCT_FROM_DATABASE=Ethernet Server Adapter I340-T2 + +pci:v00008086d00001516sv00008086sd000012B2* + ID_PRODUCT_FROM_DATABASE=Ethernet Server Adapter I340-T2 + +pci:v00008086d00001517* + ID_PRODUCT_FROM_DATABASE=82599ES 10 Gigabit Network Connection + +pci:v00008086d00001517sv00001137sd0000006A* + ID_PRODUCT_FROM_DATABASE=UCS CNA M61KR-I Intel Converged Network Adapter + +pci:v00008086d00001518* + ID_PRODUCT_FROM_DATABASE=82576NS SerDes Gigabit Network Connection + +pci:v00008086d0000151C* + ID_PRODUCT_FROM_DATABASE=82599EB 10 Gigabit TN Network Connection + +pci:v00008086d0000151Csv0000108Esd00007B13* + ID_PRODUCT_FROM_DATABASE=Dual 10GBASE-T LP + +pci:v00008086d00001520* + ID_PRODUCT_FROM_DATABASE=I350 Ethernet Controller Virtual Function + +pci:v00008086d00001521* + ID_PRODUCT_FROM_DATABASE=I350 Gigabit Network Connection + +pci:v00008086d00001521sv00001028sd00001F60* + ID_PRODUCT_FROM_DATABASE=Intel GbE 4P I350crNDC + +pci:v00008086d00001521sv00001028sd00001F62* + ID_PRODUCT_FROM_DATABASE=Intel GbE 2P I350crNDC + +pci:v00008086d00001521sv0000103Csd0000337F* + ID_PRODUCT_FROM_DATABASE=Ethernet 1Gb 2-port 361i Adapter + +pci:v00008086d00001521sv0000103Csd00003380* + ID_PRODUCT_FROM_DATABASE=Ethernet 1Gb 4-port 366i Adapter + +pci:v00008086d00001521sv0000103Csd0000339E* + ID_PRODUCT_FROM_DATABASE=Ethernet 1Gb 2-port 361T Adapter + +pci:v00008086d00001521sv0000108Esd00007B16* + ID_PRODUCT_FROM_DATABASE=Quad Port GbE PCIe 2.0 ExpressModule, UTP + +pci:v00008086d00001521sv0000108Esd00007B18* + ID_PRODUCT_FROM_DATABASE=Quad Port GbE PCIe 2.0 Low Profile Adapter, UTP + +pci:v00008086d00001521sv000010A9sd0000802A* + ID_PRODUCT_FROM_DATABASE=UV2-BaseIO dual-port GbE + +pci:v00008086d00001521sv00008086sd00000001* + ID_PRODUCT_FROM_DATABASE=Ethernet Server Adapter I350-T4 + +pci:v00008086d00001521sv00008086sd00000002* + ID_PRODUCT_FROM_DATABASE=Ethernet Server Adapter I350-T2 + +pci:v00008086d00001521sv00008086sd000000A1* + ID_PRODUCT_FROM_DATABASE=Ethernet Server Adapter I350-T4 + +pci:v00008086d00001521sv00008086sd000000A2* + ID_PRODUCT_FROM_DATABASE=Ethernet Server Adapter I350-T2 + +pci:v00008086d00001521sv00008086sd00005001* + ID_PRODUCT_FROM_DATABASE=Ethernet Server Adapter I350-T4 + +pci:v00008086d00001521sv00008086sd00005002* + ID_PRODUCT_FROM_DATABASE=Ethernet Server Adapter I350-T2 + +pci:v00008086d00001522* + ID_PRODUCT_FROM_DATABASE=I350 Gigabit Fiber Network Connection + +pci:v00008086d00001522sv0000108Esd00007B17* + ID_PRODUCT_FROM_DATABASE=Quad Port GbE PCIe 2.0 ExpressModule, MMF + +pci:v00008086d00001522sv0000108Esd00007B19* + ID_PRODUCT_FROM_DATABASE=Dual Port GbE PCIe 2.0 Low Profile Adapter, MMF + +pci:v00008086d00001522sv00008086sd00000002* + ID_PRODUCT_FROM_DATABASE=Ethernet Server Adapter I350-T2 + +pci:v00008086d00001522sv00008086sd00000003* + ID_PRODUCT_FROM_DATABASE=Ethernet Server Adapter I350-F4 + +pci:v00008086d00001522sv00008086sd00000004* + ID_PRODUCT_FROM_DATABASE=Ethernet Server Adapter I350-F2 + +pci:v00008086d00001522sv00008086sd000000A3* + ID_PRODUCT_FROM_DATABASE=Ethernet Server Adapter I350-F4 + +pci:v00008086d00001522sv00008086sd000000A4* + ID_PRODUCT_FROM_DATABASE=Ethernet Server Adapter I350-F2 + +pci:v00008086d00001523* + ID_PRODUCT_FROM_DATABASE=I350 Gigabit Backplane Connection + +pci:v00008086d00001523sv0000103Csd00001784* + ID_PRODUCT_FROM_DATABASE=Ethernet 1Gb 2-port 361FLB Adapter + +pci:v00008086d00001523sv0000103Csd000018D1* + ID_PRODUCT_FROM_DATABASE=Ethernet 1Gb 2-port 361FLB Adapter + +pci:v00008086d00001523sv0000103Csd0000339F* + ID_PRODUCT_FROM_DATABASE=Ethernet 1Gb 4-port 366M Adapter + +pci:v00008086d00001523sv00008086sd00001F52* + ID_PRODUCT_FROM_DATABASE=1GbE 4P I350 Mezz + +pci:v00008086d00001524* + ID_PRODUCT_FROM_DATABASE=I350 Gigabit Connection + +pci:v00008086d00001525* + ID_PRODUCT_FROM_DATABASE=82567V-4 Gigabit Network Connection + +pci:v00008086d00001526* + ID_PRODUCT_FROM_DATABASE=82576 Gigabit Network Connection + +pci:v00008086d00001526sv00008086sd0000A05C* + ID_PRODUCT_FROM_DATABASE=Gigabit ET2 Quad Port Server Adapter + +pci:v00008086d00001526sv00008086sd0000A06C* + ID_PRODUCT_FROM_DATABASE=Gigabit ET2 Quad Port Server Adapter + +pci:v00008086d00001527* + ID_PRODUCT_FROM_DATABASE=82580 Gigabit Fiber Network Connection + +pci:v00008086d00001527sv00008086sd00000001* + ID_PRODUCT_FROM_DATABASE=Ethernet Server Adapter I340-F4 + +pci:v00008086d00001527sv00008086sd00000002* + ID_PRODUCT_FROM_DATABASE=Ethernet Server Adapter I340-F4 + +pci:v00008086d00001528* + ID_PRODUCT_FROM_DATABASE=Ethernet Controller 10-Gigabit X540-AT2 + +pci:v00008086d00001528sv00001028sd00001F61* + ID_PRODUCT_FROM_DATABASE=Ethernet 10G 4P X540/I350 rNDC + +pci:v00008086d00001528sv0000103Csd0000192D* + ID_PRODUCT_FROM_DATABASE=561FLR-T 2-port 10Gb Ethernet Adapter + +pci:v00008086d00001528sv0000108Esd00007B14* + ID_PRODUCT_FROM_DATABASE=Sun Dual Port 10 GbE PCIe 2.0 ExpressModule, Base-T + +pci:v00008086d00001528sv0000108Esd00007B15* + ID_PRODUCT_FROM_DATABASE=Sun Dual Port 10 GbE PCIe 2.0 Low Profile Adapter, Base-T + +pci:v00008086d00001528sv00001137sd000000BF* + ID_PRODUCT_FROM_DATABASE=Ethernet Converged Network Adapter X540-T2 + +pci:v00008086d00001528sv00008086sd00000001* + ID_PRODUCT_FROM_DATABASE=Ethernet Converged Network Adapter X540-T2 + +pci:v00008086d00001528sv00008086sd00000002* + ID_PRODUCT_FROM_DATABASE=Ethernet Converged Network Adapter X540-T1 + +pci:v00008086d00001528sv00008086sd0000001A* + ID_PRODUCT_FROM_DATABASE=Ethernet Converged Network Adapter X540-T2 + +pci:v00008086d00001528sv00008086sd000000A2* + ID_PRODUCT_FROM_DATABASE=Ethernet Converged Network Adapter X540-T1 + +pci:v00008086d00001528sv00008086sd00001F61* + ID_PRODUCT_FROM_DATABASE=Ethernet 10G 4P X540/I350 rNDC + +pci:v00008086d00001528sv00008086sd00005003* + ID_PRODUCT_FROM_DATABASE=Ethernet 10G 2P X540-t Adapter + +pci:v00008086d00001529* + ID_PRODUCT_FROM_DATABASE=82599 10 Gigabit Dual Port Backplane Connection with FCoE + +pci:v00008086d0000152A* + ID_PRODUCT_FROM_DATABASE=82599 10 Gigabit Dual port Network Connection with FCoE + +pci:v00008086d00001533* + ID_PRODUCT_FROM_DATABASE=I210 Gigabit Network Connection + +pci:v00008086d00001533sv0000103Csd00000003* + ID_PRODUCT_FROM_DATABASE=Ethernet Server Adapter I210-T1 + +pci:v00008086d00001533sv00008086sd00000001* + ID_PRODUCT_FROM_DATABASE=Ethernet Server Adapter I210-T1 + +pci:v00008086d00001533sv00008086sd00000002* + ID_PRODUCT_FROM_DATABASE=Ethernet Server Adapter I210-T1 + +pci:v00008086d00001534* + ID_PRODUCT_FROM_DATABASE=I210 Gigabit Network Connection + +pci:v00008086d00001536* + ID_PRODUCT_FROM_DATABASE=I210 Gigabit Fiber Network Connection + +pci:v00008086d00001537* + ID_PRODUCT_FROM_DATABASE=I210 Gigabit Backplane Connection + +pci:v00008086d00001538* + ID_PRODUCT_FROM_DATABASE=I210 Gigabit Network Connection + +pci:v00008086d00001539* + ID_PRODUCT_FROM_DATABASE=I211 Gigabit Network Connection + +pci:v00008086d0000153A* + ID_PRODUCT_FROM_DATABASE=Ethernet Connection I217-LM + +pci:v00008086d0000153B* + ID_PRODUCT_FROM_DATABASE=Ethernet Connection I217-V + +pci:v00008086d00001547* + ID_PRODUCT_FROM_DATABASE=DSL3510 Thunderbolt Port [Cactus Ridge] + +pci:v00008086d00001549* + ID_PRODUCT_FROM_DATABASE=DSL3510 Thunderbolt Controller [Cactus Ridge] + +pci:v00008086d0000154A* + ID_PRODUCT_FROM_DATABASE=Ethernet Server Adapter X520-4 + +pci:v00008086d0000154Asv00008086sd0000011A* + ID_PRODUCT_FROM_DATABASE=Ethernet Converged Network Adapter X520-4 + +pci:v00008086d0000154Asv00008086sd0000011B* + ID_PRODUCT_FROM_DATABASE=Ethernet Converged Network Adapter X520-4 + +pci:v00008086d0000154Asv00008086sd0000011C* + ID_PRODUCT_FROM_DATABASE=Ethernet Converged Network Adapter X520-4 + +pci:v00008086d0000154D* + ID_PRODUCT_FROM_DATABASE=82599EB 10-Gigabit SFP+ Network Connection + +pci:v00008086d0000154Dsv00008086sd00007B11* + ID_PRODUCT_FROM_DATABASE=10GbE 2P X520 Adapter + +pci:v00008086d00001557* + ID_PRODUCT_FROM_DATABASE=82599 10 Gigabit Network Connection + +pci:v00008086d00001559* + ID_PRODUCT_FROM_DATABASE=Ethernet Connection I218-V + +pci:v00008086d0000155A* + ID_PRODUCT_FROM_DATABASE=Ethernet Connection I218-LM + +pci:v00008086d00001560* + ID_PRODUCT_FROM_DATABASE=Ethernet Controller X540-AT1 + +pci:v00008086d00001960* + ID_PRODUCT_FROM_DATABASE=80960RP (i960RP) Microprocessor + +pci:v00008086d00001960sv0000101Esd00000431* + ID_PRODUCT_FROM_DATABASE=MegaRAID 431 RAID Controller + +pci:v00008086d00001960sv0000101Esd00000438* + ID_PRODUCT_FROM_DATABASE=MegaRAID 438 Ultra2 LVD RAID Controller + +pci:v00008086d00001960sv0000101Esd00000466* + ID_PRODUCT_FROM_DATABASE=MegaRAID 466 Express Plus RAID Controller + +pci:v00008086d00001960sv0000101Esd00000467* + ID_PRODUCT_FROM_DATABASE=MegaRAID 467 Enterprise 1500 RAID Controller + +pci:v00008086d00001960sv0000101Esd00000490* + ID_PRODUCT_FROM_DATABASE=MegaRAID 490 Express 300 RAID Controller + +pci:v00008086d00001960sv0000101Esd00000762* + ID_PRODUCT_FROM_DATABASE=MegaRAID 762 Express RAID Controller + +pci:v00008086d00001960sv0000101Esd000009A0* + ID_PRODUCT_FROM_DATABASE=PowerEdge Expandable RAID Controller 2/SC + +pci:v00008086d00001960sv00001028sd00000467* + ID_PRODUCT_FROM_DATABASE=PowerEdge Expandable RAID Controller 2/DC + +pci:v00008086d00001960sv00001028sd00001111* + ID_PRODUCT_FROM_DATABASE=PowerEdge Expandable RAID Controller 2/SC + +pci:v00008086d00001960sv0000103Csd000003A2* + ID_PRODUCT_FROM_DATABASE=MegaRAID + +pci:v00008086d00001960sv0000103Csd000010C6* + ID_PRODUCT_FROM_DATABASE=MegaRAID 438, NetRAID-3Si + +pci:v00008086d00001960sv0000103Csd000010C7* + ID_PRODUCT_FROM_DATABASE=MegaRAID T5, Integrated NetRAID + +pci:v00008086d00001960sv0000103Csd000010CC* + ID_PRODUCT_FROM_DATABASE=MegaRAID, Integrated NetRAID + +pci:v00008086d00001960sv0000103Csd000010CD* + ID_PRODUCT_FROM_DATABASE=NetRAID-1Si + +pci:v00008086d00001960sv0000105Asd00000000* + ID_PRODUCT_FROM_DATABASE=SuperTrak + +pci:v00008086d00001960sv0000105Asd00002168* + ID_PRODUCT_FROM_DATABASE=SuperTrak Pro + +pci:v00008086d00001960sv0000105Asd00005168* + ID_PRODUCT_FROM_DATABASE=SuperTrak66/100 + +pci:v00008086d00001960sv00001111sd00001111* + ID_PRODUCT_FROM_DATABASE=MegaRAID 466, PowerEdge Expandable RAID Controller 2/SC + +pci:v00008086d00001960sv00001111sd00001112* + ID_PRODUCT_FROM_DATABASE=PowerEdge Expandable RAID Controller 2/SC + +pci:v00008086d00001960sv0000113Csd000003A2* + ID_PRODUCT_FROM_DATABASE=MegaRAID + +pci:v00008086d00001960sv0000E4BFsd00001010* + ID_PRODUCT_FROM_DATABASE=CG1-RADIO + +pci:v00008086d00001960sv0000E4BFsd00001020* + ID_PRODUCT_FROM_DATABASE=CU2-QUARTET + +pci:v00008086d00001960sv0000E4BFsd00001040* + ID_PRODUCT_FROM_DATABASE=CU1-CHORUS + +pci:v00008086d00001960sv0000E4BFsd00003100* + ID_PRODUCT_FROM_DATABASE=CX1-BAND + +pci:v00008086d00001962* + ID_PRODUCT_FROM_DATABASE=80960RM (i960RM) Microprocessor + +pci:v00008086d00001962sv0000105Asd00000000* + ID_PRODUCT_FROM_DATABASE=SuperTrak SX6000 I2O CPU + +pci:v00008086d00001A21* + ID_PRODUCT_FROM_DATABASE=82840 840 [Carmel] Chipset Host Bridge (Hub A) + +pci:v00008086d00001A23* + ID_PRODUCT_FROM_DATABASE=82840 840 [Carmel] Chipset AGP Bridge + +pci:v00008086d00001A24* + ID_PRODUCT_FROM_DATABASE=82840 840 [Carmel] Chipset PCI Bridge (Hub B) + +pci:v00008086d00001A30* + ID_PRODUCT_FROM_DATABASE=82845 845 [Brookdale] Chipset Host Bridge + +pci:v00008086d00001A30sv00001028sd0000010E* + ID_PRODUCT_FROM_DATABASE=Optiplex GX240 + +pci:v00008086d00001A30sv000015D9sd00003280* + ID_PRODUCT_FROM_DATABASE=Supermicro P4SBE Mainboard + +pci:v00008086d00001A31* + ID_PRODUCT_FROM_DATABASE=82845 845 [Brookdale] Chipset AGP Bridge + +pci:v00008086d00001A38* + ID_PRODUCT_FROM_DATABASE=5000 Series Chipset DMA Engine + +pci:v00008086d00001A38sv000015D9sd00008680* + ID_PRODUCT_FROM_DATABASE=X7DVL-E-O motherboard + +pci:v00008086d00001A38sv00008086sd00003476* + ID_PRODUCT_FROM_DATABASE=Intel S5000PSLSATA Server Board + +pci:v00008086d00001A48* + ID_PRODUCT_FROM_DATABASE=82597EX 10GbE Ethernet Controller + +pci:v00008086d00001A48sv00008086sd0000A01F* + ID_PRODUCT_FROM_DATABASE=PRO/10GbE SR Server Adapter + +pci:v00008086d00001A48sv00008086sd0000A11F* + ID_PRODUCT_FROM_DATABASE=PRO/10GbE SR Server Adapter + +pci:v00008086d00001B48* + ID_PRODUCT_FROM_DATABASE=82597EX 10GbE Ethernet Controller + +pci:v00008086d00001B48sv00008086sd0000A01F* + ID_PRODUCT_FROM_DATABASE=PRO/10GbE LR Server Adapter + +pci:v00008086d00001B48sv00008086sd0000A11F* + ID_PRODUCT_FROM_DATABASE=PRO/10GbE LR Server Adapter + +pci:v00008086d00001C00* + ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family 4 port SATA IDE Controller + +pci:v00008086d00001C01* + ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family 4 port SATA IDE Controller + +pci:v00008086d00001C02* + ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family SATA AHCI Controller + +pci:v00008086d00001C02sv00001028sd000004AA* + ID_PRODUCT_FROM_DATABASE=XPS 8300 + +pci:v00008086d00001C02sv00001043sd0000844D* + ID_PRODUCT_FROM_DATABASE=P8P67 Deluxe Motherboard + +pci:v00008086d00001C03* + ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family 6 port SATA AHCI Controller + +pci:v00008086d00001C03sv00001028sd000004B2* + ID_PRODUCT_FROM_DATABASE=Vostro 3350 + +pci:v00008086d00001C03sv00001028sd000004DA* + ID_PRODUCT_FROM_DATABASE=Vostro 3750 + +pci:v00008086d00001C03sv00008086sd00007270* + ID_PRODUCT_FROM_DATABASE=Apple MacBookPro8,2 [Core i7, 15", 2011] + +pci:v00008086d00001C04* + ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family SATA RAID Controller + +pci:v00008086d00001C05* + ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family SATA RAID Controller + +pci:v00008086d00001C08* + ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family 2 port SATA IDE Controller + +pci:v00008086d00001C09* + ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family 2 port SATA IDE Controller + +pci:v00008086d00001C10* + ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family PCI Express Root Port 1 + +pci:v00008086d00001C10sv00001028sd000004DA* + ID_PRODUCT_FROM_DATABASE=Vostro 3750 + +pci:v00008086d00001C10sv00008086sd00007270* + ID_PRODUCT_FROM_DATABASE=Apple MacBookPro8,2 [Core i7, 15", 2011] + +pci:v00008086d00001C12* + ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family PCI Express Root Port 2 + +pci:v00008086d00001C12sv00008086sd00007270* + ID_PRODUCT_FROM_DATABASE=Apple MacBookPro8,2 [Core i7, 15", 2011] + +pci:v00008086d00001C14* + ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family PCI Express Root Port 3 + +pci:v00008086d00001C14sv00001028sd000004DA* + ID_PRODUCT_FROM_DATABASE=Vostro 3750 + +pci:v00008086d00001C14sv00008086sd00007270* + ID_PRODUCT_FROM_DATABASE=Apple MacBookPro8,2 [Core i7, 15", 2011] + +pci:v00008086d00001C16* + ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family PCI Express Root Port 4 + +pci:v00008086d00001C18* + ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family PCI Express Root Port 5 + +pci:v00008086d00001C18sv00001028sd000004DA* + ID_PRODUCT_FROM_DATABASE=Vostro 3750 + +pci:v00008086d00001C1A* + ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family PCI Express Root Port 6 + +pci:v00008086d00001C1Asv00001028sd000004DA* + ID_PRODUCT_FROM_DATABASE=Vostro 3750 + +pci:v00008086d00001C1C* + ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family PCI Express Root Port 7 + +pci:v00008086d00001C1E* + ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family PCI Express Root Port 8 + +pci:v00008086d00001C20* + ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family High Definition Audio Controller + +pci:v00008086d00001C20sv00001028sd00000490* + ID_PRODUCT_FROM_DATABASE=Alienware M17x R3 + +pci:v00008086d00001C20sv00001028sd000004AA* + ID_PRODUCT_FROM_DATABASE=XPS 8300 + +pci:v00008086d00001C20sv00001028sd000004B2* + ID_PRODUCT_FROM_DATABASE=Vostro 3350 + +pci:v00008086d00001C20sv00001028sd000004DA* + ID_PRODUCT_FROM_DATABASE=Vostro 3750 + +pci:v00008086d00001C20sv00001043sd00008418* + ID_PRODUCT_FROM_DATABASE=P8P67 Deluxe Motherboard + +pci:v00008086d00001C20sv00008086sd00002008* + ID_PRODUCT_FROM_DATABASE=DQ67SW board + +pci:v00008086d00001C20sv00008086sd00007270* + ID_PRODUCT_FROM_DATABASE=Apple MacBookPro8,2 [Core i7, 15", 2011] + +pci:v00008086d00001C22* + ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family SMBus Controller + +pci:v00008086d00001C22sv00001028sd000004AA* + ID_PRODUCT_FROM_DATABASE=XPS 8300 + +pci:v00008086d00001C22sv00001028sd000004B2* + ID_PRODUCT_FROM_DATABASE=Vostro 3350 + +pci:v00008086d00001C22sv00001028sd000004DA* + ID_PRODUCT_FROM_DATABASE=Vostro 3750 + +pci:v00008086d00001C22sv00001043sd0000844D* + ID_PRODUCT_FROM_DATABASE=P8P67 Deluxe Motherboard + +pci:v00008086d00001C22sv00008086sd00007270* + ID_PRODUCT_FROM_DATABASE=Apple MacBookPro8,2 [Core i7, 15", 2011] + +pci:v00008086d00001C24* + ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family Thermal Management Controller + +pci:v00008086d00001C25* + ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family DMI to PCI Bridge + +pci:v00008086d00001C26* + ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family USB Enhanced Host Controller #1 + +pci:v00008086d00001C26sv00001028sd000004AA* + ID_PRODUCT_FROM_DATABASE=XPS 8300 + +pci:v00008086d00001C26sv00001028sd000004B2* + ID_PRODUCT_FROM_DATABASE=Vostro 3350 + +pci:v00008086d00001C26sv00001028sd000004DA* + ID_PRODUCT_FROM_DATABASE=Vostro 3750 + +pci:v00008086d00001C26sv00001043sd0000844D* + ID_PRODUCT_FROM_DATABASE=P8P67 Deluxe Motherboard + +pci:v00008086d00001C26sv00008086sd00007270* + ID_PRODUCT_FROM_DATABASE=Apple MacBookPro8,2 [Core i7, 15", 2011] + +pci:v00008086d00001C27* + ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family USB Universal Host Controller #1 + +pci:v00008086d00001C27sv00008086sd00007270* + ID_PRODUCT_FROM_DATABASE=Apple MacBookPro8,2 [Core i7, 15", 2011] + +pci:v00008086d00001C2C* + ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family USB Universal Host Controller #5 + +pci:v00008086d00001C2Csv00008086sd00007270* + ID_PRODUCT_FROM_DATABASE=Apple MacBookPro8,2 [Core i7, 15", 2011] + +pci:v00008086d00001C2D* + ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family USB Enhanced Host Controller #2 + +pci:v00008086d00001C2Dsv00001028sd000004AA* + ID_PRODUCT_FROM_DATABASE=XPS 8300 + +pci:v00008086d00001C2Dsv00001028sd000004B2* + ID_PRODUCT_FROM_DATABASE=Vostro 3350 + +pci:v00008086d00001C2Dsv00001028sd000004DA* + ID_PRODUCT_FROM_DATABASE=Vostro 3750 + +pci:v00008086d00001C2Dsv00001043sd0000844D* + ID_PRODUCT_FROM_DATABASE=P8P67 Deluxe Motherboard + +pci:v00008086d00001C2Dsv00008086sd00007270* + ID_PRODUCT_FROM_DATABASE=Apple MacBookPro8,2 [Core i7, 15", 2011] + +pci:v00008086d00001C33* + ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family LAN Controller + +pci:v00008086d00001C35* + ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family VECI Controller + +pci:v00008086d00001C3A* + ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family MEI Controller #1 + +pci:v00008086d00001C3Asv00001028sd000004AA* + ID_PRODUCT_FROM_DATABASE=XPS 8300 + +pci:v00008086d00001C3Asv00001028sd000004B2* + ID_PRODUCT_FROM_DATABASE=Vostro 3350 + +pci:v00008086d00001C3Asv00001028sd000004DA* + ID_PRODUCT_FROM_DATABASE=Vostro 3750 + +pci:v00008086d00001C3Asv00001043sd0000844D* + ID_PRODUCT_FROM_DATABASE=P8P67 Deluxe Motherboard + +pci:v00008086d00001C3Asv00008086sd00007270* + ID_PRODUCT_FROM_DATABASE=Apple MacBookPro8,2 [Core i7, 15", 2011] + +pci:v00008086d00001C3B* + ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family MEI Controller #2 + +pci:v00008086d00001C3C* + ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family IDE-r Controller + +pci:v00008086d00001C3D* + ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family KT Controller + +pci:v00008086d00001C40* + ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family LPC Controller + +pci:v00008086d00001C41* + ID_PRODUCT_FROM_DATABASE=Mobile SFF 6 Series Chipset Family LPC Controller + +pci:v00008086d00001C42* + ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family LPC Controller + +pci:v00008086d00001C43* + ID_PRODUCT_FROM_DATABASE=Mobile 6 Series Chipset Family LPC Controller + +pci:v00008086d00001C44* + ID_PRODUCT_FROM_DATABASE=Z68 Express Chipset Family LPC Controller + +pci:v00008086d00001C45* + ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family LPC Controller + +pci:v00008086d00001C46* + ID_PRODUCT_FROM_DATABASE=P67 Express Chipset Family LPC Controller + +pci:v00008086d00001C46sv00001043sd0000844D* + ID_PRODUCT_FROM_DATABASE=P8P67 Deluxe Motherboard + +pci:v00008086d00001C47* + ID_PRODUCT_FROM_DATABASE=UM67 Express Chipset Family LPC Controller + +pci:v00008086d00001C48* + ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family LPC Controller + +pci:v00008086d00001C49* + ID_PRODUCT_FROM_DATABASE=HM65 Express Chipset Family LPC Controller + +pci:v00008086d00001C49sv00008086sd00007270* + ID_PRODUCT_FROM_DATABASE=Apple MacBookPro8,2 [Core i7, 15", 2011] + +pci:v00008086d00001C4A* + ID_PRODUCT_FROM_DATABASE=H67 Express Chipset Family LPC Controller + +pci:v00008086d00001C4Asv00001028sd000004AA* + ID_PRODUCT_FROM_DATABASE=XPS 8300 + +pci:v00008086d00001C4B* + ID_PRODUCT_FROM_DATABASE=HM67 Express Chipset Family LPC Controller + +pci:v00008086d00001C4Bsv00001028sd000004B2* + ID_PRODUCT_FROM_DATABASE=Vostro 3350 + +pci:v00008086d00001C4Bsv00001028sd000004DA* + ID_PRODUCT_FROM_DATABASE=Vostro 3750 + +pci:v00008086d00001C4C* + ID_PRODUCT_FROM_DATABASE=Q65 Express Chipset Family LPC Controller + +pci:v00008086d00001C4D* + ID_PRODUCT_FROM_DATABASE=QS67 Express Chipset Family LPC Controller + +pci:v00008086d00001C4E* + ID_PRODUCT_FROM_DATABASE=Q67 Express Chipset Family LPC Controller + +pci:v00008086d00001C4F* + ID_PRODUCT_FROM_DATABASE=QM67 Express Chipset Family LPC Controller + +pci:v00008086d00001C50* + ID_PRODUCT_FROM_DATABASE=B65 Express Chipset Family LPC Controller + +pci:v00008086d00001C51* + ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family LPC Controller + +pci:v00008086d00001C52* + ID_PRODUCT_FROM_DATABASE=C202 Chipset Family LPC Controller + +pci:v00008086d00001C53* + ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family LPC Controller + +pci:v00008086d00001C54* + ID_PRODUCT_FROM_DATABASE=C204 Chipset Family LPC Controller + +pci:v00008086d00001C55* + ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family LPC Controller + +pci:v00008086d00001C56* + ID_PRODUCT_FROM_DATABASE=C206 Chipset Family LPC Controller + +pci:v00008086d00001C57* + ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family LPC Controller + +pci:v00008086d00001C58* + ID_PRODUCT_FROM_DATABASE=Upgraded B65 Express Chipset Family LPC Controller + +pci:v00008086d00001C59* + ID_PRODUCT_FROM_DATABASE=Upgraded HM67 Express Chipset Family LPC Controller + +pci:v00008086d00001C5A* + ID_PRODUCT_FROM_DATABASE=Upgraded Q67 Express Chipset Family LPC Controller + +pci:v00008086d00001C5B* + ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family LPC Controller + +pci:v00008086d00001C5C* + ID_PRODUCT_FROM_DATABASE=H61 Express Chipset Family LPC Controller + +pci:v00008086d00001C5D* + ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family LPC Controller + +pci:v00008086d00001C5E* + ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family LPC Controller + +pci:v00008086d00001C5F* + ID_PRODUCT_FROM_DATABASE=6 Series/C200 Series Chipset Family LPC Controller + +pci:v00008086d00001D00* + ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset 4-Port SATA IDE Controller + +pci:v00008086d00001D02* + ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset 6-Port SATA AHCI Controller + +pci:v00008086d00001D04* + ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset SATA RAID Controller + +pci:v00008086d00001D06* + ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset SATA Premium RAID Controller + +pci:v00008086d00001D08* + ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset 2-Port SATA IDE Controller + +pci:v00008086d00001D10* + ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset PCI Express Root Port 1 + +pci:v00008086d00001D11* + ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset PCI Express Root Port 1 + +pci:v00008086d00001D12* + ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset PCI Express Root Port 2 + +pci:v00008086d00001D13* + ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset PCI Express Root Port 2 + +pci:v00008086d00001D14* + ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset PCI Express Root Port 3 + +pci:v00008086d00001D15* + ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset PCI Express Root Port 3 + +pci:v00008086d00001D16* + ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset PCI Express Root Port 4 + +pci:v00008086d00001D17* + ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset PCI Express Root Port 4 + +pci:v00008086d00001D18* + ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset PCI Express Root Port 5 + +pci:v00008086d00001D19* + ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset PCI Express Root Port 5 + +pci:v00008086d00001D1A* + ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset PCI Express Root Port 6 + +pci:v00008086d00001D1B* + ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset PCI Express Root Port 6 + +pci:v00008086d00001D1C* + ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset PCI Express Root Port 7 + +pci:v00008086d00001D1D* + ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset PCI Express Root Port 7 + +pci:v00008086d00001D1E* + ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset PCI Express Root Port 8 + +pci:v00008086d00001D1F* + ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset PCI Express Root Port 8 + +pci:v00008086d00001D20* + ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset High Definition Audio Controller + +pci:v00008086d00001D22* + ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset SMBus Host Controller + +pci:v00008086d00001D24* + ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset Thermal Management Controller + +pci:v00008086d00001D25* + ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset DMI to PCI Bridge + +pci:v00008086d00001D26* + ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset USB2 Enhanced Host Controller #1 + +pci:v00008086d00001D2D* + ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset USB2 Enhanced Host Controller #2 + +pci:v00008086d00001D33* + ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset LAN Controller + +pci:v00008086d00001D35* + ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset VECI Controller + +pci:v00008086d00001D3A* + ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset MEI Controller #1 + +pci:v00008086d00001D3B* + ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset MEI Controller #2 + +pci:v00008086d00001D3C* + ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset IDE-r Controller + +pci:v00008086d00001D3D* + ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset KT Controller + +pci:v00008086d00001D3E* + ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset PCI Express Virtual Root Port + +pci:v00008086d00001D3F* + ID_PRODUCT_FROM_DATABASE=C608/C606/X79 series chipset PCI Express Virtual Switch Port + +pci:v00008086d00001D40* + ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset LPC Controller + +pci:v00008086d00001D41* + ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset LPC Controller + +pci:v00008086d00001D50* + ID_PRODUCT_FROM_DATABASE=C608 chipset Dual 4-Port SATA/SAS Storage Control Unit + +pci:v00008086d00001D54* + ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset Dual 4-Port SATA/SAS Storage Control Unit + +pci:v00008086d00001D55* + ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset 4-Port SATA/SAS Storage Control Unit + +pci:v00008086d00001D58* + ID_PRODUCT_FROM_DATABASE=C606 chipset Dual 4-Port SATA/SAS Storage Control Unit + +pci:v00008086d00001D59* + ID_PRODUCT_FROM_DATABASE=C604/X79 series chipset 4-Port SATA/SAS Storage Control Unit + +pci:v00008086d00001D5A* + ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset Dual 4-Port SATA Storage Control Unit + +pci:v00008086d00001D5B* + ID_PRODUCT_FROM_DATABASE=C602 chipset 4-Port SATA Storage Control Unit + +pci:v00008086d00001D5C* + ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset Dual 4-Port SATA/SAS Storage Control Unit + +pci:v00008086d00001D5D* + ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset 4-Port SATA/SAS Storage Control Unit + +pci:v00008086d00001D5E* + ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset Dual 4-Port SATA Storage Control Unit + +pci:v00008086d00001D5F* + ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset 4-Port SATA Storage Control Unit + +pci:v00008086d00001D60* + ID_PRODUCT_FROM_DATABASE=C608 chipset Dual 4-Port SATA/SAS Storage Control Unit + +pci:v00008086d00001D64* + ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset Dual 4-Port SATA/SAS Storage Control Unit + +pci:v00008086d00001D65* + ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset 4-Port SATA/SAS Storage Control Unit + +pci:v00008086d00001D68* + ID_PRODUCT_FROM_DATABASE=C606 chipset Dual 4-Port SATA/SAS Storage Control Unit + +pci:v00008086d00001D69* + ID_PRODUCT_FROM_DATABASE=C604/X79 series chipset 4-Port SATA/SAS Storage Control Unit + +pci:v00008086d00001D6A* + ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset Dual 4-Port SATA Storage Control Unit + +pci:v00008086d00001D6B* + ID_PRODUCT_FROM_DATABASE=C602 chipset 4-Port SATA Storage Control Unit + +pci:v00008086d00001D6C* + ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset Dual 4-Port SATA/SAS Storage Control Unit + +pci:v00008086d00001D6D* + ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset 4-Port SATA/SAS Storage Control Unit + +pci:v00008086d00001D6E* + ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset Dual 4-Port SATA Storage Control Unit + +pci:v00008086d00001D6F* + ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset 4-Port SATA Storage Control Unit + +pci:v00008086d00001D70* + ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset SMBus Controller 0 + +pci:v00008086d00001D71* + ID_PRODUCT_FROM_DATABASE=C608/C606/X79 series chipset SMBus Controller 1 + +pci:v00008086d00001D72* + ID_PRODUCT_FROM_DATABASE=C608 chipset SMBus Controller 2 + +pci:v00008086d00001D74* + ID_PRODUCT_FROM_DATABASE=C608/C606/X79 series chipset PCI Express Upstream Port + +pci:v00008086d00001D76* + ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset Multi-Function Glue + +pci:v00008086d00001E00* + ID_PRODUCT_FROM_DATABASE=7 Series/C210 Series Chipset Family 4-port SATA Controller [IDE mode] + +pci:v00008086d00001E01* + ID_PRODUCT_FROM_DATABASE=7 Series Chipset Family 4-port SATA Controller [IDE mode] + +pci:v00008086d00001E02* + ID_PRODUCT_FROM_DATABASE=7 Series/C210 Series Chipset Family 6-port SATA Controller [AHCI mode] + +pci:v00008086d00001E03* + ID_PRODUCT_FROM_DATABASE=7 Series Chipset Family 6-port SATA Controller [AHCI mode] + +pci:v00008086d00001E03sv00001043sd00001477* + ID_PRODUCT_FROM_DATABASE=N56VZ + +pci:v00008086d00001E03sv00001043sd00001517* + ID_PRODUCT_FROM_DATABASE=Zenbook Prime UX31A + +pci:v00008086d00001E04* + ID_PRODUCT_FROM_DATABASE=7 Series/C210 Series Chipset Family SATA Controller [RAID mode] + +pci:v00008086d00001E05* + ID_PRODUCT_FROM_DATABASE=7 Series Chipset SATA Controller [RAID mode] + +pci:v00008086d00001E06* + ID_PRODUCT_FROM_DATABASE=7 Series/C210 Series Chipset Family SATA Controller [RAID mode] + +pci:v00008086d00001E07* + ID_PRODUCT_FROM_DATABASE=7 Series Chipset Family SATA Controller [RAID mode] + +pci:v00008086d00001E08* + ID_PRODUCT_FROM_DATABASE=7 Series/C210 Series Chipset Family 2-port SATA Controller [IDE mode] + +pci:v00008086d00001E09* + ID_PRODUCT_FROM_DATABASE=7 Series Chipset Family 2-port SATA Controller [IDE mode] + +pci:v00008086d00001E0E* + ID_PRODUCT_FROM_DATABASE=7 Series/C210 Series Chipset Family SATA Controller [RAID mode] + +pci:v00008086d00001E10* + ID_PRODUCT_FROM_DATABASE=7 Series/C210 Series Chipset Family PCI Express Root Port 1 + +pci:v00008086d00001E10sv00001043sd00001477* + ID_PRODUCT_FROM_DATABASE=N56VZ + +pci:v00008086d00001E10sv00001043sd00001517* + ID_PRODUCT_FROM_DATABASE=Zenbook Prime UX31A + +pci:v00008086d00001E12* + ID_PRODUCT_FROM_DATABASE=7 Series/C210 Series Chipset Family PCI Express Root Port 2 + +pci:v00008086d00001E12sv00001043sd00001477* + ID_PRODUCT_FROM_DATABASE=N56VZ + +pci:v00008086d00001E12sv00001043sd00001517* + ID_PRODUCT_FROM_DATABASE=Zenbook Prime UX31A + +pci:v00008086d00001E14* + ID_PRODUCT_FROM_DATABASE=7 Series/C210 Series Chipset Family PCI Express Root Port 3 + +pci:v00008086d00001E16* + ID_PRODUCT_FROM_DATABASE=7 Series/C210 Series Chipset Family PCI Express Root Port 4 + +pci:v00008086d00001E16sv00001043sd00001477* + ID_PRODUCT_FROM_DATABASE=N56VZ + +pci:v00008086d00001E18* + ID_PRODUCT_FROM_DATABASE=7 Series/C210 Series Chipset Family PCI Express Root Port 5 + +pci:v00008086d00001E1A* + ID_PRODUCT_FROM_DATABASE=7 Series/C210 Series Chipset Family PCI Express Root Port 6 + +pci:v00008086d00001E1C* + ID_PRODUCT_FROM_DATABASE=7 Series/C210 Series Chipset Family PCI Express Root Port 7 + +pci:v00008086d00001E1E* + ID_PRODUCT_FROM_DATABASE=7 Series/C210 Series Chipset Family PCI Express Root Port 8 + +pci:v00008086d00001E20* + ID_PRODUCT_FROM_DATABASE=7 Series/C210 Series Chipset Family High Definition Audio Controller + +pci:v00008086d00001E20sv00001043sd00001477* + ID_PRODUCT_FROM_DATABASE=N56VZ + +pci:v00008086d00001E20sv00001043sd00001517* + ID_PRODUCT_FROM_DATABASE=Zenbook Prime UX31A + +pci:v00008086d00001E22* + ID_PRODUCT_FROM_DATABASE=7 Series/C210 Series Chipset Family SMBus Controller + +pci:v00008086d00001E22sv00001043sd00001477* + ID_PRODUCT_FROM_DATABASE=N56VZ + +pci:v00008086d00001E22sv00001043sd00001517* + ID_PRODUCT_FROM_DATABASE=Zenbook Prime UX31A + +pci:v00008086d00001E24* + ID_PRODUCT_FROM_DATABASE=7 Series/C210 Series Chipset Family Thermal Management Controller + +pci:v00008086d00001E24sv00001043sd00001517* + ID_PRODUCT_FROM_DATABASE=Zenbook Prime UX31A + +pci:v00008086d00001E25* + ID_PRODUCT_FROM_DATABASE=7 Series/C210 Series Chipset Family DMI to PCI Bridge + +pci:v00008086d00001E26* + ID_PRODUCT_FROM_DATABASE=7 Series/C210 Series Chipset Family USB Enhanced Host Controller #1 + +pci:v00008086d00001E26sv00001043sd00001477* + ID_PRODUCT_FROM_DATABASE=N56VZ + +pci:v00008086d00001E26sv00001043sd00001517* + ID_PRODUCT_FROM_DATABASE=Zenbook Prime UX31A + +pci:v00008086d00001E2D* + ID_PRODUCT_FROM_DATABASE=7 Series/C210 Series Chipset Family USB Enhanced Host Controller #2 + +pci:v00008086d00001E2Dsv00001043sd00001477* + ID_PRODUCT_FROM_DATABASE=N56VZ + +pci:v00008086d00001E2Dsv00001043sd00001517* + ID_PRODUCT_FROM_DATABASE=Zenbook Prime UX31A + +pci:v00008086d00001E31* + ID_PRODUCT_FROM_DATABASE=7 Series/C210 Series Chipset Family USB xHCI Host Controller + +pci:v00008086d00001E31sv00001043sd00001477* + ID_PRODUCT_FROM_DATABASE=N56VZ + +pci:v00008086d00001E31sv00001043sd00001517* + ID_PRODUCT_FROM_DATABASE=Zenbook Prime UX31A + +pci:v00008086d00001E33* + ID_PRODUCT_FROM_DATABASE=7 Series/C210 Series Chipset Family LAN Controller + +pci:v00008086d00001E3A* + ID_PRODUCT_FROM_DATABASE=7 Series/C210 Series Chipset Family MEI Controller #1 + +pci:v00008086d00001E3Asv00001043sd00001477* + ID_PRODUCT_FROM_DATABASE=N56VZ + +pci:v00008086d00001E3Asv00001043sd00001517* + ID_PRODUCT_FROM_DATABASE=Zenbook Prime UX31A + +pci:v00008086d00001E3B* + ID_PRODUCT_FROM_DATABASE=7 Series/C210 Series Chipset Family MEI Controller #2 + +pci:v00008086d00001E3C* + ID_PRODUCT_FROM_DATABASE=7 Series/C210 Series Chipset Family IDE-r Controller + +pci:v00008086d00001E3D* + ID_PRODUCT_FROM_DATABASE=7 Series/C210 Series Chipset Family KT Controller + +pci:v00008086d00001E41* + ID_PRODUCT_FROM_DATABASE=7 Series Chipset Family LPC Controller + +pci:v00008086d00001E42* + ID_PRODUCT_FROM_DATABASE=7 Series Chipset Family LPC Controller + +pci:v00008086d00001E43* + ID_PRODUCT_FROM_DATABASE=7 Series Chipset Family LPC Controller + +pci:v00008086d00001E44* + ID_PRODUCT_FROM_DATABASE=Z77 Express Chipset LPC Controller + +pci:v00008086d00001E45* + ID_PRODUCT_FROM_DATABASE=7 Series Chipset Family LPC Controller + +pci:v00008086d00001E46* + ID_PRODUCT_FROM_DATABASE=Z75 Express Chipset LPC Controller + +pci:v00008086d00001E47* + ID_PRODUCT_FROM_DATABASE=Q77 Express Chipset LPC Controller + +pci:v00008086d00001E48* + ID_PRODUCT_FROM_DATABASE=Q75 Express Chipset LPC Controller + +pci:v00008086d00001E49* + ID_PRODUCT_FROM_DATABASE=B75 Express Chipset LPC Controller + +pci:v00008086d00001E4A* + ID_PRODUCT_FROM_DATABASE=H77 Express Chipset LPC Controller + +pci:v00008086d00001E4B* + ID_PRODUCT_FROM_DATABASE=7 Series Chipset Family LPC Controller + +pci:v00008086d00001E4C* + ID_PRODUCT_FROM_DATABASE=7 Series Chipset Family LPC Controller + +pci:v00008086d00001E4D* + ID_PRODUCT_FROM_DATABASE=7 Series Chipset Family LPC Controller + +pci:v00008086d00001E4E* + ID_PRODUCT_FROM_DATABASE=7 Series Chipset Family LPC Controller + +pci:v00008086d00001E4F* + ID_PRODUCT_FROM_DATABASE=7 Series Chipset Family LPC Controller + +pci:v00008086d00001E50* + ID_PRODUCT_FROM_DATABASE=7 Series Chipset Family LPC Controller + +pci:v00008086d00001E51* + ID_PRODUCT_FROM_DATABASE=7 Series Chipset Family LPC Controller + +pci:v00008086d00001E52* + ID_PRODUCT_FROM_DATABASE=7 Series Chipset Family LPC Controller + +pci:v00008086d00001E53* + ID_PRODUCT_FROM_DATABASE=C216 Series Chipset LPC Controller + +pci:v00008086d00001E54* + ID_PRODUCT_FROM_DATABASE=7 Series Chipset Family LPC Controller + +pci:v00008086d00001E55* + ID_PRODUCT_FROM_DATABASE=QM77 Express Chipset LPC Controller + +pci:v00008086d00001E56* + ID_PRODUCT_FROM_DATABASE=QS77 Express Chipset LPC Controller + +pci:v00008086d00001E57* + ID_PRODUCT_FROM_DATABASE=HM77 Express Chipset LPC Controller + +pci:v00008086d00001E58* + ID_PRODUCT_FROM_DATABASE=UM77 Express Chipset LPC Controller + +pci:v00008086d00001E59* + ID_PRODUCT_FROM_DATABASE=HM76 Express Chipset LPC Controller + +pci:v00008086d00001E59sv00001043sd00001477* + ID_PRODUCT_FROM_DATABASE=N56VZ + +pci:v00008086d00001E59sv00001043sd00001517* + ID_PRODUCT_FROM_DATABASE=Zenbook Prime UX31A + +pci:v00008086d00001E5A* + ID_PRODUCT_FROM_DATABASE=7 Series Chipset Family LPC Controller + +pci:v00008086d00001E5B* + ID_PRODUCT_FROM_DATABASE=UM77 Express Chipset LPC Controller + +pci:v00008086d00001E5C* + ID_PRODUCT_FROM_DATABASE=7 Series Chipset Family LPC Controller + +pci:v00008086d00001E5D* + ID_PRODUCT_FROM_DATABASE=HM75 Express Chipset LPC Controller + +pci:v00008086d00001E5E* + ID_PRODUCT_FROM_DATABASE=7 Series Chipset Family LPC Controller + +pci:v00008086d00001E5F* + ID_PRODUCT_FROM_DATABASE=7 Series Chipset Family LPC Controller + +pci:v00008086d00002310* + ID_PRODUCT_FROM_DATABASE=DH89xxCC LPC Controller + +pci:v00008086d00002323* + ID_PRODUCT_FROM_DATABASE=DH89xxCC 4 Port SATA AHCI Controller + +pci:v00008086d00002330* + ID_PRODUCT_FROM_DATABASE=DH89xxCC SMBus Controller + +pci:v00008086d00002331* + ID_PRODUCT_FROM_DATABASE=DH89xxCC Chap Counter + +pci:v00008086d00002332* + ID_PRODUCT_FROM_DATABASE=DH89xxCC Thermal Subsystem + +pci:v00008086d00002334* + ID_PRODUCT_FROM_DATABASE=DH89xxCC USB2 Enhanced Host Controller #1 + +pci:v00008086d00002335* + ID_PRODUCT_FROM_DATABASE=DH89xxCC USB2 Enhanced Host Controller #1 + +pci:v00008086d00002342* + ID_PRODUCT_FROM_DATABASE=DH89xxCC PCI Express Root Port #1 + +pci:v00008086d00002343* + ID_PRODUCT_FROM_DATABASE=DH89xxCC PCI Express Root Port #1 + +pci:v00008086d00002344* + ID_PRODUCT_FROM_DATABASE=DH89xxCC PCI Express Root Port #2 + +pci:v00008086d00002345* + ID_PRODUCT_FROM_DATABASE=DH89xxCC PCI Express Root Port #2 + +pci:v00008086d00002346* + ID_PRODUCT_FROM_DATABASE=DH89xxCC PCI Express Root Port #3 + +pci:v00008086d00002347* + ID_PRODUCT_FROM_DATABASE=DH89xxCC PCI Express Root Port #3 + +pci:v00008086d00002348* + ID_PRODUCT_FROM_DATABASE=DH89xxCC PCI Express Root Port #4 + +pci:v00008086d00002349* + ID_PRODUCT_FROM_DATABASE=DH89xxCC PCI Express Root Port #4 + +pci:v00008086d00002360* + ID_PRODUCT_FROM_DATABASE=DH89xxCC Watchdog Timer + +pci:v00008086d00002364* + ID_PRODUCT_FROM_DATABASE=DH89xxCC MEI 0 + +pci:v00008086d00002365* + ID_PRODUCT_FROM_DATABASE=DH89xxCC MEI 1 + +pci:v00008086d00002410* + ID_PRODUCT_FROM_DATABASE=82801AA ISA Bridge (LPC) + +pci:v00008086d00002411* + ID_PRODUCT_FROM_DATABASE=82801AA IDE Controller + +pci:v00008086d00002412* + ID_PRODUCT_FROM_DATABASE=82801AA USB Controller + +pci:v00008086d00002413* + ID_PRODUCT_FROM_DATABASE=82801AA SMBus Controller + +pci:v00008086d00002415* + ID_PRODUCT_FROM_DATABASE=82801AA AC'97 Audio Controller + +pci:v00008086d00002415sv00001028sd00000095* + ID_PRODUCT_FROM_DATABASE=Precision Workstation 220 Integrated Digital Audio + +pci:v00008086d00002415sv00001028sd000000B4* + ID_PRODUCT_FROM_DATABASE=OptiPlex GX110 + +pci:v00008086d00002415sv0000110Asd00000051* + ID_PRODUCT_FROM_DATABASE=Activy 2xx + +pci:v00008086d00002415sv000011D4sd00000040* + ID_PRODUCT_FROM_DATABASE=SoundMAX Integrated Digital Audio + +pci:v00008086d00002415sv000011D4sd00000048* + ID_PRODUCT_FROM_DATABASE=SoundMAX Integrated Digital Audio + +pci:v00008086d00002415sv000011D4sd00005340* + ID_PRODUCT_FROM_DATABASE=SoundMAX Integrated Digital Audio + +pci:v00008086d00002415sv00001734sd00001025* + ID_PRODUCT_FROM_DATABASE=Activy 3xx + +pci:v00008086d00002416* + ID_PRODUCT_FROM_DATABASE=82801AA AC'97 Modem Controller + +pci:v00008086d00002418* + ID_PRODUCT_FROM_DATABASE=82801AA PCI Bridge + +pci:v00008086d00002420* + ID_PRODUCT_FROM_DATABASE=82801AB ISA Bridge (LPC) + +pci:v00008086d00002421* + ID_PRODUCT_FROM_DATABASE=82801AB IDE Controller + +pci:v00008086d00002422* + ID_PRODUCT_FROM_DATABASE=82801AB USB Controller + +pci:v00008086d00002423* + ID_PRODUCT_FROM_DATABASE=82801AB SMBus Controller + +pci:v00008086d00002425* + ID_PRODUCT_FROM_DATABASE=82801AB AC'97 Audio Controller + +pci:v00008086d00002425sv000011D4sd00000040* + ID_PRODUCT_FROM_DATABASE=SoundMAX Integrated Digital Audio + +pci:v00008086d00002425sv000011D4sd00000048* + ID_PRODUCT_FROM_DATABASE=SoundMAX Integrated Digital Audio + +pci:v00008086d00002426* + ID_PRODUCT_FROM_DATABASE=82801AB AC'97 Modem Controller + +pci:v00008086d00002428* + ID_PRODUCT_FROM_DATABASE=82801AB PCI Bridge + +pci:v00008086d00002440* + ID_PRODUCT_FROM_DATABASE=82801BA ISA Bridge (LPC) + +pci:v00008086d00002440sv00008086sd00005744* + ID_PRODUCT_FROM_DATABASE=S845WD1-E + +pci:v00008086d00002442* + ID_PRODUCT_FROM_DATABASE=82801BA/BAM USB Controller #1 + +pci:v00008086d00002442sv00001014sd000001C6* + ID_PRODUCT_FROM_DATABASE=Netvista A40/A40p + +pci:v00008086d00002442sv00001025sd00001016* + ID_PRODUCT_FROM_DATABASE=Travelmate 612 TX + +pci:v00008086d00002442sv00001028sd000000C7* + ID_PRODUCT_FROM_DATABASE=Dimension 8100 + +pci:v00008086d00002442sv00001028sd000000D8* + ID_PRODUCT_FROM_DATABASE=Precision 530 + +pci:v00008086d00002442sv00001028sd0000010E* + ID_PRODUCT_FROM_DATABASE=Optiplex GX240 + +pci:v00008086d00002442sv0000103Csd0000126F* + ID_PRODUCT_FROM_DATABASE=e-pc 40 + +pci:v00008086d00002442sv00001043sd00008027* + ID_PRODUCT_FROM_DATABASE=TUSL2-C Mainboard + +pci:v00008086d00002442sv0000104Dsd000080DF* + ID_PRODUCT_FROM_DATABASE=Vaio PCG-FX403 + +pci:v00008086d00002442sv0000147Bsd00000507* + ID_PRODUCT_FROM_DATABASE=TH7II-RAID + +pci:v00008086d00002442sv00008086sd00004532* + ID_PRODUCT_FROM_DATABASE=D815EEA2 mainboard + +pci:v00008086d00002442sv00008086sd00004557* + ID_PRODUCT_FROM_DATABASE=D815EGEW Mainboard + +pci:v00008086d00002442sv00008086sd00005744* + ID_PRODUCT_FROM_DATABASE=S845WD1-E mainboard + +pci:v00008086d00002443* + ID_PRODUCT_FROM_DATABASE=82801BA/BAM SMBus Controller + +pci:v00008086d00002443sv00001014sd000001C6* + ID_PRODUCT_FROM_DATABASE=Netvista A40/A40p + +pci:v00008086d00002443sv00001025sd00001016* + ID_PRODUCT_FROM_DATABASE=Travelmate 612 TX + +pci:v00008086d00002443sv00001028sd000000C7* + ID_PRODUCT_FROM_DATABASE=Dimension 8100 + +pci:v00008086d00002443sv00001028sd000000D8* + ID_PRODUCT_FROM_DATABASE=Precision 530 + +pci:v00008086d00002443sv00001028sd0000010E* + ID_PRODUCT_FROM_DATABASE=Optiplex GX240 + +pci:v00008086d00002443sv0000103Csd0000126F* + ID_PRODUCT_FROM_DATABASE=e-pc 40 + +pci:v00008086d00002443sv00001043sd00008027* + ID_PRODUCT_FROM_DATABASE=TUSL2-C Mainboard + +pci:v00008086d00002443sv0000104Dsd000080DF* + ID_PRODUCT_FROM_DATABASE=Vaio PCG-FX403 + +pci:v00008086d00002443sv0000147Bsd00000507* + ID_PRODUCT_FROM_DATABASE=TH7II-RAID + +pci:v00008086d00002443sv000015D9sd00003280* + ID_PRODUCT_FROM_DATABASE=Supermicro P4SBE Mainboard + +pci:v00008086d00002443sv00008086sd00004532* + ID_PRODUCT_FROM_DATABASE=D815EEA2 mainboard + +pci:v00008086d00002443sv00008086sd00004557* + ID_PRODUCT_FROM_DATABASE=D815EGEW Mainboard + +pci:v00008086d00002443sv00008086sd00005744* + ID_PRODUCT_FROM_DATABASE=S845WD1-E mainboard + +pci:v00008086d00002444* + ID_PRODUCT_FROM_DATABASE=82801BA/BAM USB Controller #1 + +pci:v00008086d00002444sv00001025sd00001016* + ID_PRODUCT_FROM_DATABASE=Travelmate 612 TX + +pci:v00008086d00002444sv00001028sd000000C7* + ID_PRODUCT_FROM_DATABASE=Dimension 8100 + +pci:v00008086d00002444sv00001028sd000000D8* + ID_PRODUCT_FROM_DATABASE=Precision 530 + +pci:v00008086d00002444sv00001028sd0000010E* + ID_PRODUCT_FROM_DATABASE=Optiplex GX240 + +pci:v00008086d00002444sv0000103Csd0000126F* + ID_PRODUCT_FROM_DATABASE=e-pc 40 + +pci:v00008086d00002444sv00001043sd00008027* + ID_PRODUCT_FROM_DATABASE=TUSL2-C Mainboard + +pci:v00008086d00002444sv0000104Dsd000080DF* + ID_PRODUCT_FROM_DATABASE=Vaio PCG-FX403 + +pci:v00008086d00002444sv0000147Bsd00000507* + ID_PRODUCT_FROM_DATABASE=TH7II-RAID + +pci:v00008086d00002444sv00008086sd00004532* + ID_PRODUCT_FROM_DATABASE=D815EEA2 mainboard + +pci:v00008086d00002444sv00008086sd00005744* + ID_PRODUCT_FROM_DATABASE=S845WD1-E mainboard + +pci:v00008086d00002445* + ID_PRODUCT_FROM_DATABASE=82801BA/BAM AC'97 Audio Controller + +pci:v00008086d00002445sv00000E11sd0000000B* + ID_PRODUCT_FROM_DATABASE=Compaq Deskpro EN Audio + +pci:v00008086d00002445sv00000E11sd00000088* + ID_PRODUCT_FROM_DATABASE=Evo D500 + +pci:v00008086d00002445sv00001014sd000001C6* + ID_PRODUCT_FROM_DATABASE=Netvista A40/A40p + +pci:v00008086d00002445sv00001025sd00001016* + ID_PRODUCT_FROM_DATABASE=Travelmate 612 TX + +pci:v00008086d00002445sv00001028sd000000D8* + ID_PRODUCT_FROM_DATABASE=Precision 530 + +pci:v00008086d00002445sv0000103Csd0000126F* + ID_PRODUCT_FROM_DATABASE=e-pc 40 + +pci:v00008086d00002445sv0000104Dsd000080DF* + ID_PRODUCT_FROM_DATABASE=Vaio PCG-FX403 + +pci:v00008086d00002445sv00001462sd00003370* + ID_PRODUCT_FROM_DATABASE=STAC9721 AC + +pci:v00008086d00002445sv0000147Bsd00000507* + ID_PRODUCT_FROM_DATABASE=TH7II-RAID + +pci:v00008086d00002445sv00008086sd00004557* + ID_PRODUCT_FROM_DATABASE=D815EGEW Mainboard + +pci:v00008086d00002446* + ID_PRODUCT_FROM_DATABASE=82801BA/BAM AC'97 Modem Controller + +pci:v00008086d00002446sv00001025sd00001016* + ID_PRODUCT_FROM_DATABASE=Travelmate 612 TX + +pci:v00008086d00002446sv0000104Dsd000080DF* + ID_PRODUCT_FROM_DATABASE=Vaio PCG-FX403 + +pci:v00008086d00002448* + ID_PRODUCT_FROM_DATABASE=82801 Mobile PCI Bridge + +pci:v00008086d00002448sv00001028sd0000040B* + ID_PRODUCT_FROM_DATABASE=Latitude E6510 + +pci:v00008086d00002448sv0000103Csd00000934* + ID_PRODUCT_FROM_DATABASE=HP Compaq nw8240 Mobile Workstation + +pci:v00008086d00002448sv0000103Csd0000099C* + ID_PRODUCT_FROM_DATABASE=NX6110/NC6120 + +pci:v00008086d00002448sv0000103Csd0000309F* + ID_PRODUCT_FROM_DATABASE=Compaq nx9420 Notebook + +pci:v00008086d00002448sv0000103Csd000030A3* + ID_PRODUCT_FROM_DATABASE=Compaq nw8440 + +pci:v00008086d00002448sv0000103Csd000030C1* + ID_PRODUCT_FROM_DATABASE=Compaq 6910p + +pci:v00008086d00002448sv0000104Dsd0000902D* + ID_PRODUCT_FROM_DATABASE=VAIO VGN-NR120E + +pci:v00008086d00002448sv0000144Dsd0000C00C* + ID_PRODUCT_FROM_DATABASE=P30 notebook + +pci:v00008086d00002448sv0000144Dsd0000C072* + ID_PRODUCT_FROM_DATABASE=Notebook N150P + +pci:v00008086d00002448sv00001734sd00001055* + ID_PRODUCT_FROM_DATABASE=Amilo M1420 + +pci:v00008086d00002448sv000017AAsd000020AE* + ID_PRODUCT_FROM_DATABASE=ThinkPad T61 + +pci:v00008086d00002448sv0000E4BFsd0000CC47* + ID_PRODUCT_FROM_DATABASE=CCG-RUMBA + +pci:v00008086d00002449* + ID_PRODUCT_FROM_DATABASE=82801BA/BAM/CA/CAM Ethernet Controller + +pci:v00008086d00002449sv00000E11sd00000012* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 VM + +pci:v00008086d00002449sv00000E11sd00000091* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 VE + +pci:v00008086d00002449sv00001014sd000001CE* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 VE + +pci:v00008086d00002449sv00001014sd000001DC* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 VE + +pci:v00008086d00002449sv00001014sd000001EB* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 VE + +pci:v00008086d00002449sv00001014sd000001EC* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 VE + +pci:v00008086d00002449sv00001014sd00000202* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 VE + +pci:v00008086d00002449sv00001014sd00000205* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 VE + +pci:v00008086d00002449sv00001014sd00000217* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 VE + +pci:v00008086d00002449sv00001014sd00000234* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 VE + +pci:v00008086d00002449sv00001014sd0000023D* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 VE + +pci:v00008086d00002449sv00001014sd00000244* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 VE + +pci:v00008086d00002449sv00001014sd00000245* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 VE + +pci:v00008086d00002449sv00001014sd00000265* + ID_PRODUCT_FROM_DATABASE=PRO/100 VE Desktop Connection + +pci:v00008086d00002449sv00001014sd00000267* + ID_PRODUCT_FROM_DATABASE=PRO/100 VE Desktop Connection + +pci:v00008086d00002449sv00001014sd0000026A* + ID_PRODUCT_FROM_DATABASE=PRO/100 VE Desktop Connection + +pci:v00008086d00002449sv0000109Fsd0000315D* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 VE + +pci:v00008086d00002449sv0000109Fsd00003181* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 VE + +pci:v00008086d00002449sv00001179sd0000FF01* + ID_PRODUCT_FROM_DATABASE=PRO/100 VE Network Connection + +pci:v00008086d00002449sv00001186sd00007801* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 VE + +pci:v00008086d00002449sv0000144Dsd00002602* + ID_PRODUCT_FROM_DATABASE=HomePNA 1M CNR + +pci:v00008086d00002449sv00008086sd00003010* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 VE + +pci:v00008086d00002449sv00008086sd00003011* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 VM + +pci:v00008086d00002449sv00008086sd00003012* + ID_PRODUCT_FROM_DATABASE=82562EH based Phoneline + +pci:v00008086d00002449sv00008086sd00003013* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 VE + +pci:v00008086d00002449sv00008086sd00003014* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 VM + +pci:v00008086d00002449sv00008086sd00003015* + ID_PRODUCT_FROM_DATABASE=82562EH based Phoneline + +pci:v00008086d00002449sv00008086sd00003016* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 P Mobile Combo + +pci:v00008086d00002449sv00008086sd00003017* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 P Mobile + +pci:v00008086d00002449sv00008086sd00003018* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 + +pci:v00008086d0000244A* + ID_PRODUCT_FROM_DATABASE=82801BAM IDE U100 Controller + +pci:v00008086d0000244Asv00001025sd00001016* + ID_PRODUCT_FROM_DATABASE=Travelmate 612TX + +pci:v00008086d0000244Asv0000104Dsd000080DF* + ID_PRODUCT_FROM_DATABASE=Vaio PCG-FX403 + +pci:v00008086d0000244B* + ID_PRODUCT_FROM_DATABASE=82801BA IDE U100 Controller + +pci:v00008086d0000244Bsv00001014sd000001C6* + ID_PRODUCT_FROM_DATABASE=Netvista A40/A40p + +pci:v00008086d0000244Bsv00001028sd000000C7* + ID_PRODUCT_FROM_DATABASE=Dimension 8100 + +pci:v00008086d0000244Bsv00001028sd000000D8* + ID_PRODUCT_FROM_DATABASE=Precision 530 + +pci:v00008086d0000244Bsv00001028sd0000010E* + ID_PRODUCT_FROM_DATABASE=Optiplex GX240 + +pci:v00008086d0000244Bsv0000103Csd0000126F* + ID_PRODUCT_FROM_DATABASE=e-pc 40 + +pci:v00008086d0000244Bsv00001043sd00008027* + ID_PRODUCT_FROM_DATABASE=TUSL2-C Mainboard + +pci:v00008086d0000244Bsv0000147Bsd00000507* + ID_PRODUCT_FROM_DATABASE=TH7II-RAID + +pci:v00008086d0000244Bsv000015D9sd00003280* + ID_PRODUCT_FROM_DATABASE=Supermicro P4SBE Mainboard + +pci:v00008086d0000244Bsv00008086sd00004532* + ID_PRODUCT_FROM_DATABASE=D815EEA2 mainboard + +pci:v00008086d0000244Bsv00008086sd00004557* + ID_PRODUCT_FROM_DATABASE=D815EGEW Mainboard + +pci:v00008086d0000244Bsv00008086sd00005744* + ID_PRODUCT_FROM_DATABASE=S845WD1-E mainboard + +pci:v00008086d0000244C* + ID_PRODUCT_FROM_DATABASE=82801BAM ISA Bridge (LPC) + +pci:v00008086d0000244E* + ID_PRODUCT_FROM_DATABASE=82801 PCI Bridge + +pci:v00008086d0000244Esv00001014sd00000267* + ID_PRODUCT_FROM_DATABASE=NetVista A30p + +pci:v00008086d0000244Esv00001028sd0000020D* + ID_PRODUCT_FROM_DATABASE=Inspiron 530 + +pci:v00008086d0000244Esv00001028sd00000211* + ID_PRODUCT_FROM_DATABASE=Optiplex 755 + +pci:v00008086d0000244Esv00001028sd000002DA* + ID_PRODUCT_FROM_DATABASE=OptiPlex 980 + +pci:v00008086d0000244Esv0000103Csd00002A3B* + ID_PRODUCT_FROM_DATABASE=Pavilion A1512X + +pci:v00008086d0000244Esv0000103Csd000031FE* + ID_PRODUCT_FROM_DATABASE=ProLiant DL140 G3 + +pci:v00008086d0000244Esv0000103Csd0000330B* + ID_PRODUCT_FROM_DATABASE=ProLiant ML150 G6 Server + +pci:v00008086d0000244Esv00001458sd00005000* + ID_PRODUCT_FROM_DATABASE=GA-EP45-DS5 Motherboard + +pci:v00008086d0000244Esv00001775sd000011CC* + ID_PRODUCT_FROM_DATABASE=CC11/CL11 + +pci:v00008086d00002450* + ID_PRODUCT_FROM_DATABASE=82801E ISA Bridge (LPC) + +pci:v00008086d00002452* + ID_PRODUCT_FROM_DATABASE=82801E USB Controller + +pci:v00008086d00002453* + ID_PRODUCT_FROM_DATABASE=82801E SMBus Controller + +pci:v00008086d00002459* + ID_PRODUCT_FROM_DATABASE=82801E Ethernet Controller 0 + +pci:v00008086d0000245B* + ID_PRODUCT_FROM_DATABASE=82801E IDE U100 Controller + +pci:v00008086d0000245D* + ID_PRODUCT_FROM_DATABASE=82801E Ethernet Controller 1 + +pci:v00008086d0000245E* + ID_PRODUCT_FROM_DATABASE=82801E PCI Bridge + +pci:v00008086d00002480* + ID_PRODUCT_FROM_DATABASE=82801CA LPC Interface Controller + +pci:v00008086d00002482* + ID_PRODUCT_FROM_DATABASE=82801CA/CAM USB Controller #1 + +pci:v00008086d00002482sv00000E11sd00000030* + ID_PRODUCT_FROM_DATABASE=Evo N600c + +pci:v00008086d00002482sv00001014sd00000220* + ID_PRODUCT_FROM_DATABASE=ThinkPad A/T/X Series + +pci:v00008086d00002482sv0000104Dsd000080E7* + ID_PRODUCT_FROM_DATABASE=VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP + +pci:v00008086d00002482sv000015D9sd00003480* + ID_PRODUCT_FROM_DATABASE=P4DP6 + +pci:v00008086d00002482sv00008086sd00001958* + ID_PRODUCT_FROM_DATABASE=vpr Matrix 170B4 + +pci:v00008086d00002482sv00008086sd00003424* + ID_PRODUCT_FROM_DATABASE=SE7501HG2 Mainboard + +pci:v00008086d00002482sv00008086sd00004541* + ID_PRODUCT_FROM_DATABASE=Latitude C640 + +pci:v00008086d00002483* + ID_PRODUCT_FROM_DATABASE=82801CA/CAM SMBus Controller + +pci:v00008086d00002483sv00001014sd00000220* + ID_PRODUCT_FROM_DATABASE=ThinkPad A/T/X Series + +pci:v00008086d00002483sv0000104Dsd000080E7* + ID_PRODUCT_FROM_DATABASE=VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP + +pci:v00008086d00002483sv000015D9sd00003480* + ID_PRODUCT_FROM_DATABASE=P4DP6 + +pci:v00008086d00002483sv00008086sd00001958* + ID_PRODUCT_FROM_DATABASE=vpr Matrix 170B4 + +pci:v00008086d00002484* + ID_PRODUCT_FROM_DATABASE=82801CA/CAM USB Controller #2 + +pci:v00008086d00002484sv00000E11sd00000030* + ID_PRODUCT_FROM_DATABASE=Evo N600c + +pci:v00008086d00002484sv00001014sd00000220* + ID_PRODUCT_FROM_DATABASE=ThinkPad A/T/X Series + +pci:v00008086d00002484sv0000104Dsd000080E7* + ID_PRODUCT_FROM_DATABASE=VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP + +pci:v00008086d00002484sv000015D9sd00003480* + ID_PRODUCT_FROM_DATABASE=P4DP6 + +pci:v00008086d00002484sv00008086sd00001958* + ID_PRODUCT_FROM_DATABASE=vpr Matrix 170B4 + +pci:v00008086d00002485* + ID_PRODUCT_FROM_DATABASE=82801CA/CAM AC'97 Audio Controller + +pci:v00008086d00002485sv00001013sd00005959* + ID_PRODUCT_FROM_DATABASE=Crystal WMD Audio Codec + +pci:v00008086d00002485sv00001014sd00000222* + ID_PRODUCT_FROM_DATABASE=ThinkPad A30/A30p/T23 + +pci:v00008086d00002485sv00001014sd00000508* + ID_PRODUCT_FROM_DATABASE=ThinkPad T30 + +pci:v00008086d00002485sv00001014sd0000051C* + ID_PRODUCT_FROM_DATABASE=ThinkPad A/T/X Series + +pci:v00008086d00002485sv00001043sd00001583* + ID_PRODUCT_FROM_DATABASE=L3C (SPDIF) + +pci:v00008086d00002485sv00001043sd00001623* + ID_PRODUCT_FROM_DATABASE=L2B (no SPDIF) + +pci:v00008086d00002485sv00001043sd00001643* + ID_PRODUCT_FROM_DATABASE=L3F + +pci:v00008086d00002485sv0000104Dsd000080E7* + ID_PRODUCT_FROM_DATABASE=VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP + +pci:v00008086d00002485sv0000144Dsd0000C006* + ID_PRODUCT_FROM_DATABASE=vpr Matrix 170B4 + +pci:v00008086d00002486* + ID_PRODUCT_FROM_DATABASE=82801CA/CAM AC'97 Modem Controller + +pci:v00008086d00002486sv00001014sd00000223* + ID_PRODUCT_FROM_DATABASE=ThinkPad A/T/X Series + +pci:v00008086d00002486sv00001014sd00000503* + ID_PRODUCT_FROM_DATABASE=ThinkPad R31 + +pci:v00008086d00002486sv00001014sd0000051A* + ID_PRODUCT_FROM_DATABASE=ThinkPad A/T/X Series + +pci:v00008086d00002486sv0000101Fsd00001025* + ID_PRODUCT_FROM_DATABASE=620 Series + +pci:v00008086d00002486sv00001043sd00001496* + ID_PRODUCT_FROM_DATABASE=PCtel HSP56 MR + +pci:v00008086d00002486sv0000104Dsd000080E7* + ID_PRODUCT_FROM_DATABASE=VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP + +pci:v00008086d00002486sv0000134Dsd00004C21* + ID_PRODUCT_FROM_DATABASE=Dell Inspiron 2100 internal modem + +pci:v00008086d00002486sv0000144Dsd00002115* + ID_PRODUCT_FROM_DATABASE=vpr Matrix 170B4 internal modem + +pci:v00008086d00002486sv000014F1sd00005421* + ID_PRODUCT_FROM_DATABASE=MD56ORD V.92 MDC Modem + +pci:v00008086d00002487* + ID_PRODUCT_FROM_DATABASE=82801CA/CAM USB Controller #3 + +pci:v00008086d00002487sv00000E11sd00000030* + ID_PRODUCT_FROM_DATABASE=Evo N600c + +pci:v00008086d00002487sv00001014sd00000220* + ID_PRODUCT_FROM_DATABASE=ThinkPad A/T/X Series + +pci:v00008086d00002487sv0000104Dsd000080E7* + ID_PRODUCT_FROM_DATABASE=VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP + +pci:v00008086d00002487sv000015D9sd00003480* + ID_PRODUCT_FROM_DATABASE=P4DP6 + +pci:v00008086d00002487sv00008086sd00001958* + ID_PRODUCT_FROM_DATABASE=vpr Matrix 170B4 + +pci:v00008086d0000248A* + ID_PRODUCT_FROM_DATABASE=82801CAM IDE U100 Controller + +pci:v00008086d0000248Asv00000E11sd00000030* + ID_PRODUCT_FROM_DATABASE=Evo N600c + +pci:v00008086d0000248Asv00001014sd00000220* + ID_PRODUCT_FROM_DATABASE=ThinkPad A/T/X Series + +pci:v00008086d0000248Asv0000104Dsd000080E7* + ID_PRODUCT_FROM_DATABASE=VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP + +pci:v00008086d0000248Asv00008086sd00001958* + ID_PRODUCT_FROM_DATABASE=vpr Matrix 170B4 + +pci:v00008086d0000248Asv00008086sd00004541* + ID_PRODUCT_FROM_DATABASE=Latitude C640 + +pci:v00008086d0000248B* + ID_PRODUCT_FROM_DATABASE=82801CA Ultra ATA Storage Controller + +pci:v00008086d0000248Bsv000015D9sd00003480* + ID_PRODUCT_FROM_DATABASE=P4DP6 + +pci:v00008086d0000248C* + ID_PRODUCT_FROM_DATABASE=82801CAM ISA Bridge (LPC) + +pci:v00008086d000024C0* + ID_PRODUCT_FROM_DATABASE=82801DB/DBL (ICH4/ICH4-L) LPC Interface Bridge + +pci:v00008086d000024C0sv00001014sd00000267* + ID_PRODUCT_FROM_DATABASE=NetVista A30p + +pci:v00008086d000024C0sv00001462sd00005800* + ID_PRODUCT_FROM_DATABASE=845PE Max (MS-6580) + +pci:v00008086d000024C1* + ID_PRODUCT_FROM_DATABASE=82801DBL (ICH4-L) IDE Controller + +pci:v00008086d000024C2* + ID_PRODUCT_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #1 + +pci:v00008086d000024C2sv00001014sd00000267* + ID_PRODUCT_FROM_DATABASE=NetVista A30p + +pci:v00008086d000024C2sv00001014sd0000052D* + ID_PRODUCT_FROM_DATABASE=ThinkPad + +pci:v00008086d000024C2sv00001025sd0000005A* + ID_PRODUCT_FROM_DATABASE=TravelMate 290 + +pci:v00008086d000024C2sv00001028sd00000126* + ID_PRODUCT_FROM_DATABASE=Optiplex GX260 + +pci:v00008086d000024C2sv00001028sd00000163* + ID_PRODUCT_FROM_DATABASE=Latitude D505 + +pci:v00008086d000024C2sv00001028sd0000018D* + ID_PRODUCT_FROM_DATABASE=Inspiron 700m/710m + +pci:v00008086d000024C2sv00001028sd00000196* + ID_PRODUCT_FROM_DATABASE=Inspiron 5160 + +pci:v00008086d000024C2sv0000103Csd0000088C* + ID_PRODUCT_FROM_DATABASE=NC8000 laptop + +pci:v00008086d000024C2sv0000103Csd00000890* + ID_PRODUCT_FROM_DATABASE=NC6000 laptop + +pci:v00008086d000024C2sv0000103Csd000008B0* + ID_PRODUCT_FROM_DATABASE=tc1100 tablet + +pci:v00008086d000024C2sv00001043sd00008089* + ID_PRODUCT_FROM_DATABASE=P4B533 + +pci:v00008086d000024C2sv00001071sd00008160* + ID_PRODUCT_FROM_DATABASE=MIM2000 + +pci:v00008086d000024C2sv0000114Asd00000582* + ID_PRODUCT_FROM_DATABASE=PC8 onboard USB 1.x + +pci:v00008086d000024C2sv0000144Dsd0000C005* + ID_PRODUCT_FROM_DATABASE=X10 Laptop + +pci:v00008086d000024C2sv0000144Dsd0000C00C* + ID_PRODUCT_FROM_DATABASE=P30/P35 notebook + +pci:v00008086d000024C2sv00001462sd00005800* + ID_PRODUCT_FROM_DATABASE=845PE Max (MS-6580) + +pci:v00008086d000024C2sv00001509sd00002990* + ID_PRODUCT_FROM_DATABASE=Averatec 5110H laptop + +pci:v00008086d000024C2sv00001734sd00001004* + ID_PRODUCT_FROM_DATABASE=D1451 Mainboard (SCENIC N300, i845GV) + +pci:v00008086d000024C2sv00001734sd00001055* + ID_PRODUCT_FROM_DATABASE=Amilo M1420 + +pci:v00008086d000024C2sv00004C53sd00001090* + ID_PRODUCT_FROM_DATABASE=Cx9 / Vx9 mainboard + +pci:v00008086d000024C2sv00008086sd000024C2* + ID_PRODUCT_FROM_DATABASE=Latitude X300 + +pci:v00008086d000024C2sv00008086sd00004541* + ID_PRODUCT_FROM_DATABASE=Latitude D400/D500 + +pci:v00008086d000024C2sv0000E4BFsd00000CC9* + ID_PRODUCT_FROM_DATABASE=CC9-SAMBA + +pci:v00008086d000024C2sv0000E4BFsd00000CD2* + ID_PRODUCT_FROM_DATABASE=CD2-BEBOP + +pci:v00008086d000024C3* + ID_PRODUCT_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) SMBus Controller + +pci:v00008086d000024C3sv00001014sd00000267* + ID_PRODUCT_FROM_DATABASE=NetVista A30p + +pci:v00008086d000024C3sv00001014sd0000052D* + ID_PRODUCT_FROM_DATABASE=ThinkPad + +pci:v00008086d000024C3sv00001025sd0000005A* + ID_PRODUCT_FROM_DATABASE=TravelMate 290 + +pci:v00008086d000024C3sv00001028sd00000126* + ID_PRODUCT_FROM_DATABASE=Optiplex GX260 + +pci:v00008086d000024C3sv00001028sd0000014F* + ID_PRODUCT_FROM_DATABASE=Latitude X300 + +pci:v00008086d000024C3sv00001028sd0000018D* + ID_PRODUCT_FROM_DATABASE=Inspiron 700m/710m + +pci:v00008086d000024C3sv0000103Csd0000088C* + ID_PRODUCT_FROM_DATABASE=NC8000 laptop + +pci:v00008086d000024C3sv0000103Csd00000890* + ID_PRODUCT_FROM_DATABASE=NC6000 laptop + +pci:v00008086d000024C3sv0000103Csd000008B0* + ID_PRODUCT_FROM_DATABASE=tc1100 tablet + +pci:v00008086d000024C3sv00001071sd00008160* + ID_PRODUCT_FROM_DATABASE=MIM2000 + +pci:v00008086d000024C3sv0000114Asd00000582* + ID_PRODUCT_FROM_DATABASE=PC8 onboard SMbus + +pci:v00008086d000024C3sv0000144Dsd0000C005* + ID_PRODUCT_FROM_DATABASE=X10 Laptop + +pci:v00008086d000024C3sv0000144Dsd0000C00C* + ID_PRODUCT_FROM_DATABASE=P30/P35 notebook + +pci:v00008086d000024C3sv00001458sd000024C2* + ID_PRODUCT_FROM_DATABASE=GA-8PE667 Ultra + +pci:v00008086d000024C3sv00001462sd00005800* + ID_PRODUCT_FROM_DATABASE=845PE Max (MS-6580) + +pci:v00008086d000024C3sv00001734sd00001004* + ID_PRODUCT_FROM_DATABASE=D1451 Mainboard (SCENIC N300, i845GV) + +pci:v00008086d000024C3sv00001734sd00001055* + ID_PRODUCT_FROM_DATABASE=Amilo M1420 + +pci:v00008086d000024C3sv00004C53sd00001090* + ID_PRODUCT_FROM_DATABASE=Cx9 / Vx9 mainboard + +pci:v00008086d000024C3sv0000E4BFsd00000CC9* + ID_PRODUCT_FROM_DATABASE=CC9-SAMBA + +pci:v00008086d000024C3sv0000E4BFsd00000CD2* + ID_PRODUCT_FROM_DATABASE=CD2-BEBOP + +pci:v00008086d000024C4* + ID_PRODUCT_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #2 + +pci:v00008086d000024C4sv00001014sd00000267* + ID_PRODUCT_FROM_DATABASE=NetVista A30p + +pci:v00008086d000024C4sv00001014sd0000052D* + ID_PRODUCT_FROM_DATABASE=ThinkPad + +pci:v00008086d000024C4sv00001025sd0000005A* + ID_PRODUCT_FROM_DATABASE=TravelMate 290 + +pci:v00008086d000024C4sv00001028sd00000126* + ID_PRODUCT_FROM_DATABASE=Optiplex GX260 + +pci:v00008086d000024C4sv00001028sd00000163* + ID_PRODUCT_FROM_DATABASE=Latitude D505 + +pci:v00008086d000024C4sv00001028sd0000018D* + ID_PRODUCT_FROM_DATABASE=Inspiron 700m/710m + +pci:v00008086d000024C4sv00001028sd00000196* + ID_PRODUCT_FROM_DATABASE=Inspiron 5160 + +pci:v00008086d000024C4sv0000103Csd0000088C* + ID_PRODUCT_FROM_DATABASE=NC8000 laptop + +pci:v00008086d000024C4sv0000103Csd00000890* + ID_PRODUCT_FROM_DATABASE=NC6000 laptop + +pci:v00008086d000024C4sv0000103Csd000008B0* + ID_PRODUCT_FROM_DATABASE=tc1100 tablet + +pci:v00008086d000024C4sv00001043sd00008089* + ID_PRODUCT_FROM_DATABASE=P4B533 + +pci:v00008086d000024C4sv00001071sd00008160* + ID_PRODUCT_FROM_DATABASE=MIM2000 + +pci:v00008086d000024C4sv0000144Dsd0000C00C* + ID_PRODUCT_FROM_DATABASE=P30/P35 notebook + +pci:v00008086d000024C4sv00001462sd00005800* + ID_PRODUCT_FROM_DATABASE=845PE Max (MS-6580) + +pci:v00008086d000024C4sv00001509sd00002990* + ID_PRODUCT_FROM_DATABASE=Averatec 5110H + +pci:v00008086d000024C4sv00001734sd00001004* + ID_PRODUCT_FROM_DATABASE=D1451 Mainboard (SCENIC N300, i845GV) + +pci:v00008086d000024C4sv00004C53sd00001090* + ID_PRODUCT_FROM_DATABASE=Cx9 / Vx9 mainboard + +pci:v00008086d000024C4sv00008086sd000024C2* + ID_PRODUCT_FROM_DATABASE=Latitude X300 + +pci:v00008086d000024C4sv00008086sd00004541* + ID_PRODUCT_FROM_DATABASE=Latitude D400/D500 + +pci:v00008086d000024C4sv0000E4BFsd00000CC9* + ID_PRODUCT_FROM_DATABASE=CC9-SAMBA + +pci:v00008086d000024C4sv0000E4BFsd00000CD2* + ID_PRODUCT_FROM_DATABASE=CD2-BEBOP + +pci:v00008086d000024C5* + ID_PRODUCT_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) AC'97 Audio Controller + +pci:v00008086d000024C5sv00000E11sd000000B8* + ID_PRODUCT_FROM_DATABASE=Analog Devices Inc. codec [SoundMAX] + +pci:v00008086d000024C5sv00001014sd00000267* + ID_PRODUCT_FROM_DATABASE=NetVista A30p + +pci:v00008086d000024C5sv00001014sd00000537* + ID_PRODUCT_FROM_DATABASE=ThinkPad T41 + +pci:v00008086d000024C5sv00001014sd0000055F* + ID_PRODUCT_FROM_DATABASE=Thinkpad R50e model 1634 + +pci:v00008086d000024C5sv00001025sd0000005A* + ID_PRODUCT_FROM_DATABASE=TravelMate 290 + +pci:v00008086d000024C5sv00001028sd00000139* + ID_PRODUCT_FROM_DATABASE=Latitude D400 + +pci:v00008086d000024C5sv00001028sd0000014F* + ID_PRODUCT_FROM_DATABASE=Latitude X300 + +pci:v00008086d000024C5sv00001028sd00000152* + ID_PRODUCT_FROM_DATABASE=Latitude D500 + +pci:v00008086d000024C5sv00001028sd00000163* + ID_PRODUCT_FROM_DATABASE=Latitude D505 + +pci:v00008086d000024C5sv00001028sd0000018D* + ID_PRODUCT_FROM_DATABASE=Inspiron 700m/710m [SigmaTel STAC9750,51] + +pci:v00008086d000024C5sv00001028sd00000196* + ID_PRODUCT_FROM_DATABASE=Inspiron 5160 + +pci:v00008086d000024C5sv0000103Csd0000088C* + ID_PRODUCT_FROM_DATABASE=NC8000 laptop + +pci:v00008086d000024C5sv0000103Csd00000890* + ID_PRODUCT_FROM_DATABASE=NC6000 laptop + +pci:v00008086d000024C5sv0000103Csd000008B0* + ID_PRODUCT_FROM_DATABASE=tc1100 tablet + +pci:v00008086d000024C5sv00001043sd00001713* + ID_PRODUCT_FROM_DATABASE=M6800N + +pci:v00008086d000024C5sv00001043sd000080B0* + ID_PRODUCT_FROM_DATABASE=P4B533 + +pci:v00008086d000024C5sv00001071sd00008160* + ID_PRODUCT_FROM_DATABASE=MIM2000 + +pci:v00008086d000024C5sv00001179sd00000201* + ID_PRODUCT_FROM_DATABASE=Toshiba Tecra M1 + +pci:v00008086d000024C5sv0000144Dsd0000C005* + ID_PRODUCT_FROM_DATABASE=X10 Laptop + +pci:v00008086d000024C5sv0000144Dsd0000C00C* + ID_PRODUCT_FROM_DATABASE=P30/P35 notebook + +pci:v00008086d000024C5sv00001458sd0000A002* + ID_PRODUCT_FROM_DATABASE=GA-8PE667 Ultra + +pci:v00008086d000024C5sv00001462sd00005800* + ID_PRODUCT_FROM_DATABASE=845PE Max (MS-6580) + +pci:v00008086d000024C5sv00001734sd00001005* + ID_PRODUCT_FROM_DATABASE=D1451 (SCENIC N300, i845GV) Sigmatel STAC9750T + +pci:v00008086d000024C5sv00001734sd00001055* + ID_PRODUCT_FROM_DATABASE=Amilo M1420 + +pci:v00008086d000024C5sv00008086sd000024C5* + ID_PRODUCT_FROM_DATABASE=Dell Dimension 2400 + +pci:v00008086d000024C6* + ID_PRODUCT_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) AC'97 Modem Controller + +pci:v00008086d000024C6sv00001014sd00000524* + ID_PRODUCT_FROM_DATABASE=ThinkPad T41 + +pci:v00008086d000024C6sv00001014sd00000525* + ID_PRODUCT_FROM_DATABASE=ThinkPad + +pci:v00008086d000024C6sv00001014sd00000559* + ID_PRODUCT_FROM_DATABASE=ThinkPad R50e + +pci:v00008086d000024C6sv00001025sd0000003C* + ID_PRODUCT_FROM_DATABASE=Aspire 2001WLCi (Compal CL50 motherboard) implementation + +pci:v00008086d000024C6sv00001025sd0000005A* + ID_PRODUCT_FROM_DATABASE=TravelMate 290 + +pci:v00008086d000024C6sv00001028sd00000196* + ID_PRODUCT_FROM_DATABASE=Inspiron 5160 + +pci:v00008086d000024C6sv0000103Csd0000088C* + ID_PRODUCT_FROM_DATABASE=NC8000 laptop + +pci:v00008086d000024C6sv0000103Csd00000890* + ID_PRODUCT_FROM_DATABASE=NC6000 laptop + +pci:v00008086d000024C6sv0000103Csd000008B0* + ID_PRODUCT_FROM_DATABASE=tc1100 tablet + +pci:v00008086d000024C6sv00001043sd00001826* + ID_PRODUCT_FROM_DATABASE=M6800N + +pci:v00008086d000024C6sv00001071sd00008160* + ID_PRODUCT_FROM_DATABASE=MIM2000 + +pci:v00008086d000024C6sv0000134Dsd00004C21* + ID_PRODUCT_FROM_DATABASE=Latitude D500 + +pci:v00008086d000024C6sv0000144Dsd00002115* + ID_PRODUCT_FROM_DATABASE=X10 Laptop + +pci:v00008086d000024C6sv0000144Dsd0000C00C* + ID_PRODUCT_FROM_DATABASE=P30/P35 notebook + +pci:v00008086d000024C6sv000014F1sd00005422* + ID_PRODUCT_FROM_DATABASE=D480 MDC V.9x Modem + +pci:v00008086d000024C7* + ID_PRODUCT_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #3 + +pci:v00008086d000024C7sv00001014sd00000267* + ID_PRODUCT_FROM_DATABASE=NetVista A30p + +pci:v00008086d000024C7sv00001014sd0000052D* + ID_PRODUCT_FROM_DATABASE=ThinkPad + +pci:v00008086d000024C7sv00001025sd0000005A* + ID_PRODUCT_FROM_DATABASE=TravelMate 290 + +pci:v00008086d000024C7sv00001028sd00000126* + ID_PRODUCT_FROM_DATABASE=Optiplex GX260 + +pci:v00008086d000024C7sv00001028sd00000163* + ID_PRODUCT_FROM_DATABASE=Latitude D505 + +pci:v00008086d000024C7sv00001028sd0000018D* + ID_PRODUCT_FROM_DATABASE=Inspiron 700m/710m + +pci:v00008086d000024C7sv00001028sd00000196* + ID_PRODUCT_FROM_DATABASE=Inspiron 5160 + +pci:v00008086d000024C7sv0000103Csd0000088C* + ID_PRODUCT_FROM_DATABASE=NC8000 laptop + +pci:v00008086d000024C7sv0000103Csd00000890* + ID_PRODUCT_FROM_DATABASE=NC6000 laptop + +pci:v00008086d000024C7sv0000103Csd000008B0* + ID_PRODUCT_FROM_DATABASE=tc1100 tablet + +pci:v00008086d000024C7sv00001043sd00008089* + ID_PRODUCT_FROM_DATABASE=P4B533 + +pci:v00008086d000024C7sv00001071sd00008160* + ID_PRODUCT_FROM_DATABASE=MIM2000 + +pci:v00008086d000024C7sv0000144Dsd0000C00C* + ID_PRODUCT_FROM_DATABASE=P30/P35 notebook + +pci:v00008086d000024C7sv00001462sd00005800* + ID_PRODUCT_FROM_DATABASE=845PE Max (MS-6580) + +pci:v00008086d000024C7sv00001509sd00002990* + ID_PRODUCT_FROM_DATABASE=Averatec 5110H + +pci:v00008086d000024C7sv00001734sd00001004* + ID_PRODUCT_FROM_DATABASE=D1451 Mainboard (SCENIC N300, i845GV) + +pci:v00008086d000024C7sv00004C53sd00001090* + ID_PRODUCT_FROM_DATABASE=Cx9 / Vx9 mainboard + +pci:v00008086d000024C7sv00008086sd000024C2* + ID_PRODUCT_FROM_DATABASE=Latitude X300 + +pci:v00008086d000024C7sv00008086sd00004541* + ID_PRODUCT_FROM_DATABASE=Latitude D400/D500 + +pci:v00008086d000024C7sv0000E4BFsd00000CC9* + ID_PRODUCT_FROM_DATABASE=CC9-SAMBA + +pci:v00008086d000024C7sv0000E4BFsd00000CD2* + ID_PRODUCT_FROM_DATABASE=CD2-BEBOP + +pci:v00008086d000024CA* + ID_PRODUCT_FROM_DATABASE=82801DBM (ICH4-M) IDE Controller + +pci:v00008086d000024CAsv00001014sd0000052D* + ID_PRODUCT_FROM_DATABASE=ThinkPad + +pci:v00008086d000024CAsv00001025sd0000005A* + ID_PRODUCT_FROM_DATABASE=TravelMate 290 + +pci:v00008086d000024CAsv00001028sd0000014F* + ID_PRODUCT_FROM_DATABASE=Latitude X300 + +pci:v00008086d000024CAsv00001028sd00000163* + ID_PRODUCT_FROM_DATABASE=Latitude D505 + +pci:v00008086d000024CAsv00001028sd0000018D* + ID_PRODUCT_FROM_DATABASE=Inspiron 700m/710m + +pci:v00008086d000024CAsv00001028sd00000196* + ID_PRODUCT_FROM_DATABASE=Inspiron 5160 + +pci:v00008086d000024CAsv0000103Csd0000088C* + ID_PRODUCT_FROM_DATABASE=NC8000 laptop + +pci:v00008086d000024CAsv0000103Csd00000890* + ID_PRODUCT_FROM_DATABASE=NC6000 laptop + +pci:v00008086d000024CAsv0000103Csd000008B0* + ID_PRODUCT_FROM_DATABASE=tc1100 tablet + +pci:v00008086d000024CAsv00001071sd00008160* + ID_PRODUCT_FROM_DATABASE=MIM2000 + +pci:v00008086d000024CAsv0000144Dsd0000C005* + ID_PRODUCT_FROM_DATABASE=X10 Laptop + +pci:v00008086d000024CAsv0000144Dsd0000C00C* + ID_PRODUCT_FROM_DATABASE=P30/P35 notebook + +pci:v00008086d000024CAsv00001734sd00001055* + ID_PRODUCT_FROM_DATABASE=Amilo M1420 + +pci:v00008086d000024CAsv00008086sd00004541* + ID_PRODUCT_FROM_DATABASE=Latitude D400/D500 + +pci:v00008086d000024CB* + ID_PRODUCT_FROM_DATABASE=82801DB (ICH4) IDE Controller + +pci:v00008086d000024CBsv00001014sd00000267* + ID_PRODUCT_FROM_DATABASE=NetVista A30p + +pci:v00008086d000024CBsv00001028sd00000126* + ID_PRODUCT_FROM_DATABASE=Optiplex GX260 + +pci:v00008086d000024CBsv00001043sd00008089* + ID_PRODUCT_FROM_DATABASE=P4B533 + +pci:v00008086d000024CBsv0000114Asd00000582* + ID_PRODUCT_FROM_DATABASE=PC8 onboard IDE + +pci:v00008086d000024CBsv00001458sd000024C2* + ID_PRODUCT_FROM_DATABASE=GA-8PE667 Ultra + +pci:v00008086d000024CBsv00001462sd00005800* + ID_PRODUCT_FROM_DATABASE=845PE Max (MS-6580) + +pci:v00008086d000024CBsv00001734sd00001004* + ID_PRODUCT_FROM_DATABASE=D1451 Mainboard (SCENIC N300, i845GV) + +pci:v00008086d000024CBsv00004C53sd00001090* + ID_PRODUCT_FROM_DATABASE=Cx9 / Vx9 mainboard + +pci:v00008086d000024CBsv0000E4BFsd00000CC9* + ID_PRODUCT_FROM_DATABASE=CC9-SAMBA + +pci:v00008086d000024CBsv0000E4BFsd00000CD2* + ID_PRODUCT_FROM_DATABASE=CD2-BEBOP + +pci:v00008086d000024CC* + ID_PRODUCT_FROM_DATABASE=82801DBM (ICH4-M) LPC Interface Bridge + +pci:v00008086d000024CCsv0000144Dsd0000C00C* + ID_PRODUCT_FROM_DATABASE=P30 notebook + +pci:v00008086d000024CCsv00001734sd00001055* + ID_PRODUCT_FROM_DATABASE=Amilo M1420 + +pci:v00008086d000024CD* + ID_PRODUCT_FROM_DATABASE=82801DB/DBM (ICH4/ICH4-M) USB2 EHCI Controller + +pci:v00008086d000024CDsv00001014sd00000267* + ID_PRODUCT_FROM_DATABASE=NetVista A30p + +pci:v00008086d000024CDsv00001014sd0000052E* + ID_PRODUCT_FROM_DATABASE=ThinkPad + +pci:v00008086d000024CDsv00001025sd0000005A* + ID_PRODUCT_FROM_DATABASE=TravelMate 290 + +pci:v00008086d000024CDsv00001028sd0000011D* + ID_PRODUCT_FROM_DATABASE=Latitude D600 + +pci:v00008086d000024CDsv00001028sd00000126* + ID_PRODUCT_FROM_DATABASE=Optiplex GX260 + +pci:v00008086d000024CDsv00001028sd00000139* + ID_PRODUCT_FROM_DATABASE=Latitude D400 + +pci:v00008086d000024CDsv00001028sd00000152* + ID_PRODUCT_FROM_DATABASE=Latitude D500 + +pci:v00008086d000024CDsv00001028sd00000163* + ID_PRODUCT_FROM_DATABASE=Latitude D505 + +pci:v00008086d000024CDsv00001028sd0000018D* + ID_PRODUCT_FROM_DATABASE=Inspiron 700m/710m + +pci:v00008086d000024CDsv00001028sd00000196* + ID_PRODUCT_FROM_DATABASE=Inspiron 5160 + +pci:v00008086d000024CDsv0000103Csd0000088C* + ID_PRODUCT_FROM_DATABASE=NC8000 laptop + +pci:v00008086d000024CDsv0000103Csd00000890* + ID_PRODUCT_FROM_DATABASE=NC6000 laptop + +pci:v00008086d000024CDsv0000103Csd000008B0* + ID_PRODUCT_FROM_DATABASE=tc1100 tablet + +pci:v00008086d000024CDsv00001043sd00008089* + ID_PRODUCT_FROM_DATABASE=P4B533 + +pci:v00008086d000024CDsv00001071sd00008160* + ID_PRODUCT_FROM_DATABASE=MIM2000 + +pci:v00008086d000024CDsv0000114Asd00000582* + ID_PRODUCT_FROM_DATABASE=PC8 onboard USB 2.0 + +pci:v00008086d000024CDsv00001179sd0000FF00* + ID_PRODUCT_FROM_DATABASE=Satellite 2430 + +pci:v00008086d000024CDsv0000144Dsd0000C005* + ID_PRODUCT_FROM_DATABASE=X10 Laptop + +pci:v00008086d000024CDsv0000144Dsd0000C00C* + ID_PRODUCT_FROM_DATABASE=P30/P35 notebook + +pci:v00008086d000024CDsv00001462sd00003981* + ID_PRODUCT_FROM_DATABASE=845PE Max (MS-6580) + +pci:v00008086d000024CDsv00001509sd00001968* + ID_PRODUCT_FROM_DATABASE=Averatec 5110H + +pci:v00008086d000024CDsv00001734sd00001004* + ID_PRODUCT_FROM_DATABASE=D1451 Mainboard (SCENIC N300, i845GV) + +pci:v00008086d000024CDsv00001734sd00001055* + ID_PRODUCT_FROM_DATABASE=Amilo M1420 + +pci:v00008086d000024CDsv00004C53sd00001090* + ID_PRODUCT_FROM_DATABASE=Cx9 / Vx9 mainboard + +pci:v00008086d000024CDsv00008086sd000024C2* + ID_PRODUCT_FROM_DATABASE=Latitude X300 + +pci:v00008086d000024CDsv0000E4BFsd00000CC9* + ID_PRODUCT_FROM_DATABASE=CC9-SAMBA + +pci:v00008086d000024CDsv0000E4BFsd00000CD2* + ID_PRODUCT_FROM_DATABASE=CD2-BEBOP + +pci:v00008086d000024D0* + ID_PRODUCT_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) LPC Interface Bridge + +pci:v00008086d000024D1* + ID_PRODUCT_FROM_DATABASE=82801EB (ICH5) SATA Controller + +pci:v00008086d000024D1sv00001028sd00000169* + ID_PRODUCT_FROM_DATABASE=Precision 470 + +pci:v00008086d000024D1sv00001028sd0000019A* + ID_PRODUCT_FROM_DATABASE=PowerEdge SC1425 + +pci:v00008086d000024D1sv0000103Csd000012BC* + ID_PRODUCT_FROM_DATABASE=d530 CMT (DG746A) + +pci:v00008086d000024D1sv0000103Csd00003208* + ID_PRODUCT_FROM_DATABASE=ProLiant DL140 G2 + +pci:v00008086d000024D1sv00001043sd000080A6* + ID_PRODUCT_FROM_DATABASE=P4P800 series motherboard + +pci:v00008086d000024D1sv00001458sd000024D1* + ID_PRODUCT_FROM_DATABASE=GA-8IPE1000 Pro2 motherboard (865PE) + +pci:v00008086d000024D1sv00001462sd00007280* + ID_PRODUCT_FROM_DATABASE=865PE Neo2 (MS-6728) + +pci:v00008086d000024D1sv00001462sd00007650* + ID_PRODUCT_FROM_DATABASE=Hetis 865GV-E (MS-7065) + +pci:v00008086d000024D1sv00001565sd00005200* + ID_PRODUCT_FROM_DATABASE=P4TSV Motherboard (865G) + +pci:v00008086d000024D1sv000015D9sd00004580* + ID_PRODUCT_FROM_DATABASE=P4SCE Mainboard + +pci:v00008086d000024D1sv00008086sd00003427* + ID_PRODUCT_FROM_DATABASE=S875WP1-E mainboard + +pci:v00008086d000024D1sv00008086sd00004246* + ID_PRODUCT_FROM_DATABASE=Desktop Board D865GBF + +pci:v00008086d000024D1sv00008086sd00004C43* + ID_PRODUCT_FROM_DATABASE=Desktop Board D865GLC + +pci:v00008086d000024D1sv00008086sd0000524C* + ID_PRODUCT_FROM_DATABASE=D865PERL mainboard + +pci:v00008086d000024D2* + ID_PRODUCT_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #1 + +pci:v00008086d000024D2sv00001014sd000002DD* + ID_PRODUCT_FROM_DATABASE=eServer xSeries server mainboard + +pci:v00008086d000024D2sv00001014sd000002ED* + ID_PRODUCT_FROM_DATABASE=eServer xSeries server mainboard + +pci:v00008086d000024D2sv00001028sd00000169* + ID_PRODUCT_FROM_DATABASE=Precision 470 + +pci:v00008086d000024D2sv00001028sd0000016C* + ID_PRODUCT_FROM_DATABASE=PowerEdge 1850 onboard UHCI + +pci:v00008086d000024D2sv00001028sd0000016D* + ID_PRODUCT_FROM_DATABASE=PowerEdge 2850 onboard UHCI + +pci:v00008086d000024D2sv00001028sd00000170* + ID_PRODUCT_FROM_DATABASE=PowerEdge 6850 onboard UHCI + +pci:v00008086d000024D2sv00001028sd00000183* + ID_PRODUCT_FROM_DATABASE=PowerEdge 1800 + +pci:v00008086d000024D2sv00001028sd0000019A* + ID_PRODUCT_FROM_DATABASE=PowerEdge SC1425 + +pci:v00008086d000024D2sv0000103Csd0000006A* + ID_PRODUCT_FROM_DATABASE=NX9500 + +pci:v00008086d000024D2sv0000103Csd000012BC* + ID_PRODUCT_FROM_DATABASE=d530 CMT (DG746A) + +pci:v00008086d000024D2sv0000103Csd00003208* + ID_PRODUCT_FROM_DATABASE=ProLiant DL140 G2 + +pci:v00008086d000024D2sv00001043sd000080A6* + ID_PRODUCT_FROM_DATABASE=P4P800/P5P800 series motherboard + +pci:v00008086d000024D2sv00001458sd000024D2* + ID_PRODUCT_FROM_DATABASE=GA-8IPE1000/8KNXP motherboard + +pci:v00008086d000024D2sv00001462sd00007280* + ID_PRODUCT_FROM_DATABASE=865PE Neo2 (MS-6728) + +pci:v00008086d000024D2sv00001565sd00003101* + ID_PRODUCT_FROM_DATABASE=P4TSV Motherboard (865G) + +pci:v00008086d000024D2sv000015D9sd00004580* + ID_PRODUCT_FROM_DATABASE=P4SCE Mainboard + +pci:v00008086d000024D2sv00001734sd0000101C* + ID_PRODUCT_FROM_DATABASE=PRIMERGY RX/TX series onboard UHCI + +pci:v00008086d000024D2sv00008086sd00003427* + ID_PRODUCT_FROM_DATABASE=S875WP1-E mainboard + +pci:v00008086d000024D2sv00008086sd00004246* + ID_PRODUCT_FROM_DATABASE=Desktop Board D865GBF + +pci:v00008086d000024D2sv00008086sd00004C43* + ID_PRODUCT_FROM_DATABASE=Desktop Board D865GLC + +pci:v00008086d000024D2sv00008086sd0000524C* + ID_PRODUCT_FROM_DATABASE=D865PERL mainboard + +pci:v00008086d000024D3* + ID_PRODUCT_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) SMBus Controller + +pci:v00008086d000024D3sv00001014sd000002DD* + ID_PRODUCT_FROM_DATABASE=eServer xSeries server mainboard + +pci:v00008086d000024D3sv00001014sd000002ED* + ID_PRODUCT_FROM_DATABASE=eServer xSeries server mainboard + +pci:v00008086d000024D3sv00001028sd00000156* + ID_PRODUCT_FROM_DATABASE=Precision 360 + +pci:v00008086d000024D3sv00001028sd00000169* + ID_PRODUCT_FROM_DATABASE=Precision 470 + +pci:v00008086d000024D3sv0000103Csd000012BC* + ID_PRODUCT_FROM_DATABASE=d330 uT + +pci:v00008086d000024D3sv0000103Csd00003208* + ID_PRODUCT_FROM_DATABASE=ProLiant DL140 G2 + +pci:v00008086d000024D3sv00001043sd000080A6* + ID_PRODUCT_FROM_DATABASE=P4P800/P5P800 series motherboard + +pci:v00008086d000024D3sv00001458sd000024D2* + ID_PRODUCT_FROM_DATABASE=GA-8IPE1000 Pro2 motherboard (865PE) + +pci:v00008086d000024D3sv00001462sd00007280* + ID_PRODUCT_FROM_DATABASE=865PE Neo2 (MS-6728) + +pci:v00008086d000024D3sv00001462sd00007650* + ID_PRODUCT_FROM_DATABASE=Hetis 865GV-E (MS-7065) + +pci:v00008086d000024D3sv00001565sd00003101* + ID_PRODUCT_FROM_DATABASE=P4TSV Motherboard (865G) + +pci:v00008086d000024D3sv000015D9sd00004580* + ID_PRODUCT_FROM_DATABASE=P4SCE Mainboard + +pci:v00008086d000024D3sv00001734sd0000101C* + ID_PRODUCT_FROM_DATABASE=PRIMERGY RX/TX S2 series SMBus + +pci:v00008086d000024D3sv00008086sd00003427* + ID_PRODUCT_FROM_DATABASE=S875WP1-E mainboard + +pci:v00008086d000024D3sv00008086sd00004246* + ID_PRODUCT_FROM_DATABASE=Desktop Board D865GBF + +pci:v00008086d000024D3sv00008086sd00004C43* + ID_PRODUCT_FROM_DATABASE=Desktop Board D865GLC + +pci:v00008086d000024D3sv00008086sd0000524C* + ID_PRODUCT_FROM_DATABASE=D865PERL mainboard + +pci:v00008086d000024D4* + ID_PRODUCT_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #2 + +pci:v00008086d000024D4sv00001014sd000002DD* + ID_PRODUCT_FROM_DATABASE=eServer xSeries server mainboard + +pci:v00008086d000024D4sv00001014sd000002ED* + ID_PRODUCT_FROM_DATABASE=eServer xSeries server mainboard + +pci:v00008086d000024D4sv00001028sd00000169* + ID_PRODUCT_FROM_DATABASE=Precision 470 + +pci:v00008086d000024D4sv00001028sd0000016C* + ID_PRODUCT_FROM_DATABASE=PowerEdge 1850 onboard UHCI + +pci:v00008086d000024D4sv00001028sd0000016D* + ID_PRODUCT_FROM_DATABASE=PowerEdge 2850 onboard UHCI + +pci:v00008086d000024D4sv00001028sd00000170* + ID_PRODUCT_FROM_DATABASE=PowerEdge 6850 onboard UHCI + +pci:v00008086d000024D4sv00001028sd00000183* + ID_PRODUCT_FROM_DATABASE=PowerEdge 1800 + +pci:v00008086d000024D4sv00001028sd0000019A* + ID_PRODUCT_FROM_DATABASE=PowerEdge SC1425 + +pci:v00008086d000024D4sv0000103Csd0000006A* + ID_PRODUCT_FROM_DATABASE=NX9500 + +pci:v00008086d000024D4sv0000103Csd000012BC* + ID_PRODUCT_FROM_DATABASE=d530 CMT (DG746A) + +pci:v00008086d000024D4sv0000103Csd00003208* + ID_PRODUCT_FROM_DATABASE=ProLiant DL140 G2 + +pci:v00008086d000024D4sv00001043sd000080A6* + ID_PRODUCT_FROM_DATABASE=P4P800/P5P800 series motherboard + +pci:v00008086d000024D4sv00001458sd000024D2* + ID_PRODUCT_FROM_DATABASE=GA-8IPE1000 Pro2 motherboard (865PE) + +pci:v00008086d000024D4sv00001462sd00007280* + ID_PRODUCT_FROM_DATABASE=865PE Neo2 (MS-6728) + +pci:v00008086d000024D4sv00001462sd00007650* + ID_PRODUCT_FROM_DATABASE=Hetis 865GV-E (MS-7065) + +pci:v00008086d000024D4sv00001565sd00003101* + ID_PRODUCT_FROM_DATABASE=P4TSV Motherboard (865G) + +pci:v00008086d000024D4sv000015D9sd00004580* + ID_PRODUCT_FROM_DATABASE=P4SCE Mainboard + +pci:v00008086d000024D4sv00001734sd0000101C* + ID_PRODUCT_FROM_DATABASE=PRIMERGY RX/TX S2 series onboard UHCI + +pci:v00008086d000024D4sv00008086sd00003427* + ID_PRODUCT_FROM_DATABASE=S875WP1-E mainboard + +pci:v00008086d000024D4sv00008086sd00004246* + ID_PRODUCT_FROM_DATABASE=Desktop Board D865GBF + +pci:v00008086d000024D4sv00008086sd00004C43* + ID_PRODUCT_FROM_DATABASE=Desktop Board D865GLC + +pci:v00008086d000024D4sv00008086sd0000524C* + ID_PRODUCT_FROM_DATABASE=D865PERL mainboard + +pci:v00008086d000024D5* + ID_PRODUCT_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) AC'97 Audio Controller + +pci:v00008086d000024D5sv0000100Asd0000147B* + ID_PRODUCT_FROM_DATABASE=Abit IS7-E motherboard + +pci:v00008086d000024D5sv00001028sd00000169* + ID_PRODUCT_FROM_DATABASE=Precision 470 + +pci:v00008086d000024D5sv0000103Csd0000006A* + ID_PRODUCT_FROM_DATABASE=NX9500 + +pci:v00008086d000024D5sv0000103Csd000012BC* + ID_PRODUCT_FROM_DATABASE=d330 uT + +pci:v00008086d000024D5sv00001043sd000080F3* + ID_PRODUCT_FROM_DATABASE=P4P800 series motherboard + +pci:v00008086d000024D5sv00001043sd0000810F* + ID_PRODUCT_FROM_DATABASE=P5P800-MX Mainboard + +pci:v00008086d000024D5sv00001458sd0000A002* + ID_PRODUCT_FROM_DATABASE=GA-8IPE1000/8KNXP motherboard + +pci:v00008086d000024D5sv00001462sd00000080* + ID_PRODUCT_FROM_DATABASE=865PE Neo2-V (MS-6788) Mainboard + +pci:v00008086d000024D5sv00001462sd00007280* + ID_PRODUCT_FROM_DATABASE=865PE Neo2 (MS-6728) + +pci:v00008086d000024D5sv00001462sd00007650* + ID_PRODUCT_FROM_DATABASE=Hetis 865GV-E (MS-7065) + +pci:v00008086d000024D5sv00008086sd0000A000* + ID_PRODUCT_FROM_DATABASE=D865PERL mainboard + +pci:v00008086d000024D5sv00008086sd0000E000* + ID_PRODUCT_FROM_DATABASE=D865PERL mainboard + +pci:v00008086d000024D5sv00008086sd0000E001* + ID_PRODUCT_FROM_DATABASE=Desktop Board D865GBF + +pci:v00008086d000024D5sv00008086sd0000E002* + ID_PRODUCT_FROM_DATABASE=SoundMax Intergrated Digital Audio + +pci:v00008086d000024D6* + ID_PRODUCT_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) AC'97 Modem Controller + +pci:v00008086d000024D6sv0000103Csd0000006A* + ID_PRODUCT_FROM_DATABASE=NX9500 + +pci:v00008086d000024D7* + ID_PRODUCT_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #3 + +pci:v00008086d000024D7sv00001014sd000002ED* + ID_PRODUCT_FROM_DATABASE=xSeries server mainboard + +pci:v00008086d000024D7sv00001028sd00000169* + ID_PRODUCT_FROM_DATABASE=Precision 470 + +pci:v00008086d000024D7sv00001028sd0000016C* + ID_PRODUCT_FROM_DATABASE=PowerEdge 1850 onboard UHCI + +pci:v00008086d000024D7sv00001028sd0000016D* + ID_PRODUCT_FROM_DATABASE=PowerEdge 2850 onboard UHCI + +pci:v00008086d000024D7sv00001028sd00000170* + ID_PRODUCT_FROM_DATABASE=PowerEdge 6850 onboard UHCI + +pci:v00008086d000024D7sv00001028sd00000183* + ID_PRODUCT_FROM_DATABASE=PowerEdge 1800 + +pci:v00008086d000024D7sv0000103Csd0000006A* + ID_PRODUCT_FROM_DATABASE=NX9500 + +pci:v00008086d000024D7sv0000103Csd000012BC* + ID_PRODUCT_FROM_DATABASE=d530 CMT (DG746A) + +pci:v00008086d000024D7sv00001043sd000080A6* + ID_PRODUCT_FROM_DATABASE=P4P800/P5P800 series motherboard + +pci:v00008086d000024D7sv00001458sd000024D2* + ID_PRODUCT_FROM_DATABASE=GA-8IPE1000 Pro2 motherboard (865PE) + +pci:v00008086d000024D7sv00001462sd00007280* + ID_PRODUCT_FROM_DATABASE=865PE Neo2 (MS-6728) + +pci:v00008086d000024D7sv00001462sd00007650* + ID_PRODUCT_FROM_DATABASE=Hetis 865GV-E (MS-7065) + +pci:v00008086d000024D7sv00001565sd00003101* + ID_PRODUCT_FROM_DATABASE=P4TSV Motherboard (865G) + +pci:v00008086d000024D7sv000015D9sd00004580* + ID_PRODUCT_FROM_DATABASE=P4SCE Mainboard + +pci:v00008086d000024D7sv00001734sd0000101C* + ID_PRODUCT_FROM_DATABASE=PRIMERGY RX/TX S2 series onboard UHCI + +pci:v00008086d000024D7sv00008086sd00003427* + ID_PRODUCT_FROM_DATABASE=S875WP1-E mainboard + +pci:v00008086d000024D7sv00008086sd00004246* + ID_PRODUCT_FROM_DATABASE=Desktop Board D865GBF + +pci:v00008086d000024D7sv00008086sd00004C43* + ID_PRODUCT_FROM_DATABASE=Desktop Board D865GLC + +pci:v00008086d000024D7sv00008086sd0000524C* + ID_PRODUCT_FROM_DATABASE=D865PERL mainboard + +pci:v00008086d000024DB* + ID_PRODUCT_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) IDE Controller + +pci:v00008086d000024DBsv00001014sd000002DD* + ID_PRODUCT_FROM_DATABASE=eServer xSeries server mainboard + +pci:v00008086d000024DBsv00001014sd000002ED* + ID_PRODUCT_FROM_DATABASE=eServer xSeries server mainboard + +pci:v00008086d000024DBsv00001028sd00000169* + ID_PRODUCT_FROM_DATABASE=Precision 470 + +pci:v00008086d000024DBsv00001028sd0000016C* + ID_PRODUCT_FROM_DATABASE=PowerEdge 1850 IDE Controller + +pci:v00008086d000024DBsv00001028sd0000016D* + ID_PRODUCT_FROM_DATABASE=PowerEdge 2850 IDE Controller + +pci:v00008086d000024DBsv00001028sd00000170* + ID_PRODUCT_FROM_DATABASE=PowerEdge 6850 IDE Controller + +pci:v00008086d000024DBsv00001028sd0000019A* + ID_PRODUCT_FROM_DATABASE=PowerEdge SC1425 + +pci:v00008086d000024DBsv0000103Csd0000006A* + ID_PRODUCT_FROM_DATABASE=NX9500 + +pci:v00008086d000024DBsv0000103Csd000012BC* + ID_PRODUCT_FROM_DATABASE=d530 CMT (DG746A) + +pci:v00008086d000024DBsv00001043sd000080A6* + ID_PRODUCT_FROM_DATABASE=P4P800/P5P800 series motherboard + +pci:v00008086d000024DBsv00001458sd000024D2* + ID_PRODUCT_FROM_DATABASE=GA-8IPE1000 Pro2 motherboard (865PE) + +pci:v00008086d000024DBsv00001462sd00007280* + ID_PRODUCT_FROM_DATABASE=865PE Neo2 (MS-6728) + +pci:v00008086d000024DBsv00001462sd00007580* + ID_PRODUCT_FROM_DATABASE=MSI 875P + +pci:v00008086d000024DBsv00001462sd00007650* + ID_PRODUCT_FROM_DATABASE=Hetis 865GV-E (MS-7065) + +pci:v00008086d000024DBsv00001565sd00003101* + ID_PRODUCT_FROM_DATABASE=P4TSV Motherboard (865G) + +pci:v00008086d000024DBsv000015D9sd00004580* + ID_PRODUCT_FROM_DATABASE=P4SCE Mainboard + +pci:v00008086d000024DBsv00001734sd0000101C* + ID_PRODUCT_FROM_DATABASE=PRIMERGY RX/TX S2 series onboard IDE + +pci:v00008086d000024DBsv00008086sd000024DB* + ID_PRODUCT_FROM_DATABASE=P4C800 Mainboard + +pci:v00008086d000024DBsv00008086sd00003427* + ID_PRODUCT_FROM_DATABASE=S875WP1-E mainboard + +pci:v00008086d000024DBsv00008086sd00004246* + ID_PRODUCT_FROM_DATABASE=Desktop Board D865GBF + +pci:v00008086d000024DBsv00008086sd00004C43* + ID_PRODUCT_FROM_DATABASE=Desktop Board D865GLC + +pci:v00008086d000024DBsv00008086sd0000524C* + ID_PRODUCT_FROM_DATABASE=D865PERL mainboard + +pci:v00008086d000024DC* + ID_PRODUCT_FROM_DATABASE=82801EB (ICH5) LPC Interface Bridge + +pci:v00008086d000024DD* + ID_PRODUCT_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB2 EHCI Controller + +pci:v00008086d000024DDsv00001014sd000002DD* + ID_PRODUCT_FROM_DATABASE=eServer xSeries server mainboard + +pci:v00008086d000024DDsv00001014sd000002ED* + ID_PRODUCT_FROM_DATABASE=eServer xSeries server mainboard + +pci:v00008086d000024DDsv00001028sd00000169* + ID_PRODUCT_FROM_DATABASE=Precision 470 + +pci:v00008086d000024DDsv00001028sd0000016C* + ID_PRODUCT_FROM_DATABASE=PowerEdge 1850 onboard EHCI + +pci:v00008086d000024DDsv00001028sd0000016D* + ID_PRODUCT_FROM_DATABASE=PowerEdge 2850 onboard EHCI + +pci:v00008086d000024DDsv00001028sd00000170* + ID_PRODUCT_FROM_DATABASE=PowerEdge 6850 onboard EHCI + +pci:v00008086d000024DDsv00001028sd00000183* + ID_PRODUCT_FROM_DATABASE=PowerEdge 1800 + +pci:v00008086d000024DDsv00001028sd0000019A* + ID_PRODUCT_FROM_DATABASE=PowerEdge SC1425 + +pci:v00008086d000024DDsv0000103Csd0000006A* + ID_PRODUCT_FROM_DATABASE=NX9500 + +pci:v00008086d000024DDsv0000103Csd000012BC* + ID_PRODUCT_FROM_DATABASE=d530 CMT (DG746A) + +pci:v00008086d000024DDsv0000103Csd00003208* + ID_PRODUCT_FROM_DATABASE=ProLiant DL140 G2 + +pci:v00008086d000024DDsv00001043sd000080A6* + ID_PRODUCT_FROM_DATABASE=P4P800/P5P800 series motherboard + +pci:v00008086d000024DDsv00001458sd00005006* + ID_PRODUCT_FROM_DATABASE=GA-8IPE1000 Pro2 motherboard (865PE) + +pci:v00008086d000024DDsv00001462sd00007280* + ID_PRODUCT_FROM_DATABASE=865PE Neo2 (MS-6728) + +pci:v00008086d000024DDsv00001462sd00007650* + ID_PRODUCT_FROM_DATABASE=Hetis 865GV-E (MS-7065) + +pci:v00008086d000024DDsv00008086sd00003427* + ID_PRODUCT_FROM_DATABASE=S875WP1-E mainboard + +pci:v00008086d000024DDsv00008086sd00004246* + ID_PRODUCT_FROM_DATABASE=Desktop Board D865GBF + +pci:v00008086d000024DDsv00008086sd00004C43* + ID_PRODUCT_FROM_DATABASE=Desktop Board D865GLC + +pci:v00008086d000024DDsv00008086sd0000524C* + ID_PRODUCT_FROM_DATABASE=D865PERL mainboard + +pci:v00008086d000024DE* + ID_PRODUCT_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #4 + +pci:v00008086d000024DEsv00001014sd000002ED* + ID_PRODUCT_FROM_DATABASE=xSeries server mainboard + +pci:v00008086d000024DEsv00001028sd00000169* + ID_PRODUCT_FROM_DATABASE=Precision 470 + +pci:v00008086d000024DEsv00001043sd000080A6* + ID_PRODUCT_FROM_DATABASE=P4P800/P5P800 series motherboard + +pci:v00008086d000024DEsv00001458sd000024D2* + ID_PRODUCT_FROM_DATABASE=GA-8IPE1000 Pro2 motherboard (865PE) + +pci:v00008086d000024DEsv00001462sd00007280* + ID_PRODUCT_FROM_DATABASE=865PE Neo2 (MS-6728) + +pci:v00008086d000024DEsv00001462sd00007650* + ID_PRODUCT_FROM_DATABASE=Hetis 865GV-E (MS-7065) + +pci:v00008086d000024DEsv00001565sd00003101* + ID_PRODUCT_FROM_DATABASE=P4TSV Motherboard (865G) + +pci:v00008086d000024DEsv000015D9sd00004580* + ID_PRODUCT_FROM_DATABASE=P4SCE Mainboard + +pci:v00008086d000024DEsv00001734sd0000101C* + ID_PRODUCT_FROM_DATABASE=PRIMERGY RX/TX S2 series onboard UHCI + +pci:v00008086d000024DEsv00008086sd00003427* + ID_PRODUCT_FROM_DATABASE=S875WP1-E mainboard + +pci:v00008086d000024DEsv00008086sd00004246* + ID_PRODUCT_FROM_DATABASE=Desktop Board D865GBF + +pci:v00008086d000024DEsv00008086sd00004C43* + ID_PRODUCT_FROM_DATABASE=Desktop Board D865GLC + +pci:v00008086d000024DEsv00008086sd0000524C* + ID_PRODUCT_FROM_DATABASE=D865PERL mainboard + +pci:v00008086d000024DF* + ID_PRODUCT_FROM_DATABASE=82801ER (ICH5R) SATA Controller + +pci:v00008086d00002500* + ID_PRODUCT_FROM_DATABASE=82820 820 (Camino) Chipset Host Bridge (MCH) + +pci:v00008086d00002500sv00001028sd00000095* + ID_PRODUCT_FROM_DATABASE=Precision Workstation 220 Chipset + +pci:v00008086d00002500sv00001043sd0000801C* + ID_PRODUCT_FROM_DATABASE=P3C-2000 system chipset + +pci:v00008086d00002501* + ID_PRODUCT_FROM_DATABASE=82820 820 (Camino) Chipset Host Bridge (MCH) + +pci:v00008086d00002501sv00001043sd0000801C* + ID_PRODUCT_FROM_DATABASE=P3C-2000 system chipset + +pci:v00008086d0000250B* + ID_PRODUCT_FROM_DATABASE=82820 820 (Camino) Chipset Host Bridge + +pci:v00008086d0000250F* + ID_PRODUCT_FROM_DATABASE=82820 820 (Camino) Chipset AGP Bridge + +pci:v00008086d00002520* + ID_PRODUCT_FROM_DATABASE=82805AA MTH Memory Translator Hub + +pci:v00008086d00002521* + ID_PRODUCT_FROM_DATABASE=82804AA MRH-S Memory Repeater Hub for SDRAM + +pci:v00008086d00002530* + ID_PRODUCT_FROM_DATABASE=82850 850 (Tehama) Chipset Host Bridge (MCH) + +pci:v00008086d00002530sv00001028sd000000C7* + ID_PRODUCT_FROM_DATABASE=Dimension 8100 + +pci:v00008086d00002530sv0000147Bsd00000507* + ID_PRODUCT_FROM_DATABASE=TH7II-RAID + +pci:v00008086d00002531* + ID_PRODUCT_FROM_DATABASE=82860 860 (Wombat) Chipset Host Bridge (MCH) + +pci:v00008086d00002531sv00001028sd000000D8* + ID_PRODUCT_FROM_DATABASE=Precision 530 + +pci:v00008086d00002532* + ID_PRODUCT_FROM_DATABASE=82850 850 (Tehama) Chipset AGP Bridge + +pci:v00008086d00002533* + ID_PRODUCT_FROM_DATABASE=82860 860 (Wombat) Chipset AGP Bridge + +pci:v00008086d00002534* + ID_PRODUCT_FROM_DATABASE=82860 860 (Wombat) Chipset PCI Bridge + +pci:v00008086d00002540* + ID_PRODUCT_FROM_DATABASE=E7500 Memory Controller Hub + +pci:v00008086d00002540sv000015D9sd00003480* + ID_PRODUCT_FROM_DATABASE=P4DP6 + +pci:v00008086d00002541* + ID_PRODUCT_FROM_DATABASE=E7500/E7501 Host RASUM Controller + +pci:v00008086d00002541sv000015D9sd00003480* + ID_PRODUCT_FROM_DATABASE=P4DP6 + +pci:v00008086d00002541sv00004C53sd00001090* + ID_PRODUCT_FROM_DATABASE=Cx9 / Vx9 mainboard + +pci:v00008086d00002541sv00008086sd00003424* + ID_PRODUCT_FROM_DATABASE=SE7501HG2 Mainboard + +pci:v00008086d00002543* + ID_PRODUCT_FROM_DATABASE=E7500/E7501 Hub Interface B PCI-to-PCI Bridge + +pci:v00008086d00002544* + ID_PRODUCT_FROM_DATABASE=E7500/E7501 Hub Interface B RASUM Controller + +pci:v00008086d00002544sv00004C53sd00001090* + ID_PRODUCT_FROM_DATABASE=Cx9 / Vx9 mainboard + +pci:v00008086d00002545* + ID_PRODUCT_FROM_DATABASE=E7500/E7501 Hub Interface C PCI-to-PCI Bridge + +pci:v00008086d00002546* + ID_PRODUCT_FROM_DATABASE=E7500/E7501 Hub Interface C RASUM Controller + +pci:v00008086d00002547* + ID_PRODUCT_FROM_DATABASE=E7500/E7501 Hub Interface D PCI-to-PCI Bridge + +pci:v00008086d00002548* + ID_PRODUCT_FROM_DATABASE=E7500/E7501 Hub Interface D RASUM Controller + +pci:v00008086d0000254C* + ID_PRODUCT_FROM_DATABASE=E7501 Memory Controller Hub + +pci:v00008086d0000254Csv00004C53sd00001090* + ID_PRODUCT_FROM_DATABASE=Cx9 / Vx9 mainboard + +pci:v00008086d0000254Csv00008086sd00003424* + ID_PRODUCT_FROM_DATABASE=SE7501HG2 Mainboard + +pci:v00008086d00002550* + ID_PRODUCT_FROM_DATABASE=E7505 Memory Controller Hub + +pci:v00008086d00002551* + ID_PRODUCT_FROM_DATABASE=E7505/E7205 Series RAS Controller + +pci:v00008086d00002552* + ID_PRODUCT_FROM_DATABASE=E7505/E7205 PCI-to-AGP Bridge + +pci:v00008086d00002553* + ID_PRODUCT_FROM_DATABASE=E7505 Hub Interface B PCI-to-PCI Bridge + +pci:v00008086d00002554* + ID_PRODUCT_FROM_DATABASE=E7505 Hub Interface B PCI-to-PCI Bridge RAS Controller + +pci:v00008086d0000255D* + ID_PRODUCT_FROM_DATABASE=E7205 Memory Controller Hub + +pci:v00008086d00002560* + ID_PRODUCT_FROM_DATABASE=82845G/GL[Brookdale-G]/GE/PE DRAM Controller/Host-Hub Interface + +pci:v00008086d00002560sv00001028sd00000126* + ID_PRODUCT_FROM_DATABASE=Optiplex GX260 + +pci:v00008086d00002560sv00001458sd00002560* + ID_PRODUCT_FROM_DATABASE=GA-8PE667 Ultra + +pci:v00008086d00002560sv00001462sd00005800* + ID_PRODUCT_FROM_DATABASE=845PE Max (MS-6580) + +pci:v00008086d00002561* + ID_PRODUCT_FROM_DATABASE=82845G/GL[Brookdale-G]/GE/PE Host-to-AGP Bridge + +pci:v00008086d00002562* + ID_PRODUCT_FROM_DATABASE=82845G/GL[Brookdale-G]/GE Chipset Integrated Graphics Device + +pci:v00008086d00002562sv00000E11sd000000B9* + ID_PRODUCT_FROM_DATABASE=Evo D510 SFF + +pci:v00008086d00002562sv00001014sd00000267* + ID_PRODUCT_FROM_DATABASE=NetVista A30p + +pci:v00008086d00002562sv00001734sd00001003* + ID_PRODUCT_FROM_DATABASE=D1521 Mainboard (Fujitsu-Siemens) + +pci:v00008086d00002562sv00001734sd00001004* + ID_PRODUCT_FROM_DATABASE=D1451 Mainboard (SCENIC N300, i845GV) + +pci:v00008086d00002570* + ID_PRODUCT_FROM_DATABASE=82865G/PE/P DRAM Controller/Host-Hub Interface + +pci:v00008086d00002570sv0000103Csd0000006A* + ID_PRODUCT_FROM_DATABASE=NX9500 + +pci:v00008086d00002570sv0000103Csd000012BC* + ID_PRODUCT_FROM_DATABASE=d330 uT + +pci:v00008086d00002570sv00001043sd000080F2* + ID_PRODUCT_FROM_DATABASE=P4P800/P5P800 series motherboard + +pci:v00008086d00002570sv00001458sd00002570* + ID_PRODUCT_FROM_DATABASE=GA-8IPE1000 Pro2 motherboard (865PE) + +pci:v00008086d00002571* + ID_PRODUCT_FROM_DATABASE=82865G/PE/P AGP Bridge + +pci:v00008086d00002572* + ID_PRODUCT_FROM_DATABASE=82865G Integrated Graphics Controller + +pci:v00008086d00002572sv00001028sd0000019D* + ID_PRODUCT_FROM_DATABASE=Dimension 3000 + +pci:v00008086d00002572sv0000103Csd000012BC* + ID_PRODUCT_FROM_DATABASE=D530 sff(dc578av) + +pci:v00008086d00002572sv00001043sd000080A5* + ID_PRODUCT_FROM_DATABASE=P5P800-MX Mainboard + +pci:v00008086d00002572sv00001462sd00007650* + ID_PRODUCT_FROM_DATABASE=Hetis 865GV-E (MS-7065) + +pci:v00008086d00002572sv00001734sd0000101B* + ID_PRODUCT_FROM_DATABASE=Fujitsu-Siemens Scenic E300 i865GV + +pci:v00008086d00002572sv00008086sd00004246* + ID_PRODUCT_FROM_DATABASE=Desktop Board D865GBF + +pci:v00008086d00002572sv00008086sd00004C43* + ID_PRODUCT_FROM_DATABASE=Desktop Board D865GLC + +pci:v00008086d00002573* + ID_PRODUCT_FROM_DATABASE=82865G/PE/P PCI to CSA Bridge + +pci:v00008086d00002576* + ID_PRODUCT_FROM_DATABASE=82865G/PE/P Processor to I/O Memory Interface + +pci:v00008086d00002578* + ID_PRODUCT_FROM_DATABASE=82875P/E7210 Memory Controller Hub + +pci:v00008086d00002578sv00001458sd00002578* + ID_PRODUCT_FROM_DATABASE=GA-8KNXP motherboard (875P) + +pci:v00008086d00002578sv00001462sd00007580* + ID_PRODUCT_FROM_DATABASE=MS-6758 (875P Neo) + +pci:v00008086d00002578sv000015D9sd00004580* + ID_PRODUCT_FROM_DATABASE=P4SCE Motherboard + +pci:v00008086d00002579* + ID_PRODUCT_FROM_DATABASE=82875P Processor to AGP Controller + +pci:v00008086d0000257B* + ID_PRODUCT_FROM_DATABASE=82875P/E7210 Processor to PCI to CSA Bridge + +pci:v00008086d0000257E* + ID_PRODUCT_FROM_DATABASE=82875P/E7210 Processor to I/O Memory Interface + +pci:v00008086d00002580* + ID_PRODUCT_FROM_DATABASE=82915G/P/GV/GL/PL/910GL Memory Controller Hub + +pci:v00008086d00002580sv00001458sd00002580* + ID_PRODUCT_FROM_DATABASE=GA-8I915ME-G Mainboard + +pci:v00008086d00002580sv00001462sd00007028* + ID_PRODUCT_FROM_DATABASE=915P/G Neo2 + +pci:v00008086d00002580sv00001734sd0000105B* + ID_PRODUCT_FROM_DATABASE=Scenic W620 + +pci:v00008086d00002581* + ID_PRODUCT_FROM_DATABASE=82915G/P/GV/GL/PL/910GL PCI Express Root Port + +pci:v00008086d00002582* + ID_PRODUCT_FROM_DATABASE=82915G/GV/910GL Integrated Graphics Controller + +pci:v00008086d00002582sv00001028sd00001079* + ID_PRODUCT_FROM_DATABASE=Optiplex GX280 + +pci:v00008086d00002582sv0000103Csd00003006* + ID_PRODUCT_FROM_DATABASE=DC7100 SFF(DX878AV) + +pci:v00008086d00002582sv00001043sd00002582* + ID_PRODUCT_FROM_DATABASE=P5GD1-VW Mainboard + +pci:v00008086d00002582sv00001458sd00002582* + ID_PRODUCT_FROM_DATABASE=GA-8I915ME-G Mainboard + +pci:v00008086d00002582sv00001734sd0000105B* + ID_PRODUCT_FROM_DATABASE=Scenic W620 + +pci:v00008086d00002582sv00001849sd00002582* + ID_PRODUCT_FROM_DATABASE=ASRock P4Dual-915GL + +pci:v00008086d00002584* + ID_PRODUCT_FROM_DATABASE=82925X/XE Memory Controller Hub + +pci:v00008086d00002584sv00001028sd00000177* + ID_PRODUCT_FROM_DATABASE=Dimension 8400 + +pci:v00008086d00002585* + ID_PRODUCT_FROM_DATABASE=82925X/XE PCI Express Root Port + +pci:v00008086d00002588* + ID_PRODUCT_FROM_DATABASE=E7220/E7221 Memory Controller Hub + +pci:v00008086d00002589* + ID_PRODUCT_FROM_DATABASE=E7220/E7221 PCI Express Root Port + +pci:v00008086d0000258A* + ID_PRODUCT_FROM_DATABASE=E7221 Integrated Graphics Controller + +pci:v00008086d00002590* + ID_PRODUCT_FROM_DATABASE=Mobile 915GM/PM/GMS/910GML Express Processor to DRAM Controller + +pci:v00008086d00002590sv00001014sd00000575* + ID_PRODUCT_FROM_DATABASE=ThinkPad Z60t + +pci:v00008086d00002590sv00001028sd00000182* + ID_PRODUCT_FROM_DATABASE=Dell Latitude C610 + +pci:v00008086d00002590sv0000103Csd00000934* + ID_PRODUCT_FROM_DATABASE=Compaq nw8240/nx8220 + +pci:v00008086d00002590sv0000103Csd0000099C* + ID_PRODUCT_FROM_DATABASE=NX6110/NC6120 + +pci:v00008086d00002590sv0000104Dsd000081B7* + ID_PRODUCT_FROM_DATABASE=Vaio VGN-S3XP + +pci:v00008086d00002590sv0000A304sd000081B7* + ID_PRODUCT_FROM_DATABASE=Vaio VGN-S3XP + +pci:v00008086d00002590sv0000E4BFsd00000CCD* + ID_PRODUCT_FROM_DATABASE=CCD-CALYPSO + +pci:v00008086d00002590sv0000E4BFsd00000CD3* + ID_PRODUCT_FROM_DATABASE=CD3-JIVE + +pci:v00008086d00002590sv0000E4BFsd000058B1* + ID_PRODUCT_FROM_DATABASE=XB1 + +pci:v00008086d00002591* + ID_PRODUCT_FROM_DATABASE=Mobile 915GM/PM Express PCI Express Root Port + +pci:v00008086d00002591sv0000103Csd00000934* + ID_PRODUCT_FROM_DATABASE=HP Compaq nw8240 Mobile Workstation + +pci:v00008086d00002592* + ID_PRODUCT_FROM_DATABASE=Mobile 915GM/GMS/910GML Express Graphics Controller + +pci:v00008086d00002592sv0000103Csd0000099C* + ID_PRODUCT_FROM_DATABASE=NX6110/NC6120 + +pci:v00008086d00002592sv0000103Csd0000308A* + ID_PRODUCT_FROM_DATABASE=NC6220 + +pci:v00008086d00002592sv00001043sd00001881* + ID_PRODUCT_FROM_DATABASE=GMA 900 915GM Integrated Graphics + +pci:v00008086d00002592sv0000E4BFsd00000CCD* + ID_PRODUCT_FROM_DATABASE=CCD-CALYPSO + +pci:v00008086d00002592sv0000E4BFsd00000CD3* + ID_PRODUCT_FROM_DATABASE=CD3-JIVE + +pci:v00008086d00002592sv0000E4BFsd000058B1* + ID_PRODUCT_FROM_DATABASE=XB1 + +pci:v00008086d000025A1* + ID_PRODUCT_FROM_DATABASE=6300ESB LPC Interface Controller + +pci:v00008086d000025A2* + ID_PRODUCT_FROM_DATABASE=6300ESB PATA Storage Controller + +pci:v00008086d000025A2sv00001775sd000010D0* + ID_PRODUCT_FROM_DATABASE=V5D Single Board Computer IDE + +pci:v00008086d000025A2sv00001775sd00001100* + ID_PRODUCT_FROM_DATABASE=CR11/VR11 Single Board Computer + +pci:v00008086d000025A2sv00001775sd0000CE90* + ID_PRODUCT_FROM_DATABASE=CE9 + +pci:v00008086d000025A2sv00004C53sd000010B0* + ID_PRODUCT_FROM_DATABASE=CL9 mainboard + +pci:v00008086d000025A2sv00004C53sd000010E0* + ID_PRODUCT_FROM_DATABASE=PSL09 PrPMC + +pci:v00008086d000025A3* + ID_PRODUCT_FROM_DATABASE=6300ESB SATA Storage Controller + +pci:v00008086d000025A3sv00001775sd00001100* + ID_PRODUCT_FROM_DATABASE=CR11/VR11 Single Board Computer + +pci:v00008086d000025A3sv00001775sd0000CE90* + ID_PRODUCT_FROM_DATABASE=CE9 + +pci:v00008086d000025A3sv00004C53sd000010B0* + ID_PRODUCT_FROM_DATABASE=CL9 mainboard + +pci:v00008086d000025A3sv00004C53sd000010D0* + ID_PRODUCT_FROM_DATABASE=Telum ASLP10 Processor AMC + +pci:v00008086d000025A3sv00004C53sd000010E0* + ID_PRODUCT_FROM_DATABASE=PSL09 PrPMC + +pci:v00008086d000025A4* + ID_PRODUCT_FROM_DATABASE=6300ESB SMBus Controller + +pci:v00008086d000025A4sv00001775sd000010D0* + ID_PRODUCT_FROM_DATABASE=V5D Single Board Computer + +pci:v00008086d000025A4sv00001775sd00001100* + ID_PRODUCT_FROM_DATABASE=CR11/VR11 Single Board Computer + +pci:v00008086d000025A4sv00001775sd0000CE90* + ID_PRODUCT_FROM_DATABASE=CE9 + +pci:v00008086d000025A4sv00004C53sd000010B0* + ID_PRODUCT_FROM_DATABASE=CL9 mainboard + +pci:v00008086d000025A4sv00004C53sd000010D0* + ID_PRODUCT_FROM_DATABASE=Telum ASLP10 Processor AMC + +pci:v00008086d000025A4sv00004C53sd000010E0* + ID_PRODUCT_FROM_DATABASE=PSL09 PrPMC + +pci:v00008086d000025A6* + ID_PRODUCT_FROM_DATABASE=6300ESB AC'97 Audio Controller + +pci:v00008086d000025A6sv00001775sd00001100* + ID_PRODUCT_FROM_DATABASE=CR11/VR11 Single Board Computer + +pci:v00008086d000025A6sv00001775sd0000CE90* + ID_PRODUCT_FROM_DATABASE=CE9 + +pci:v00008086d000025A6sv00004C53sd000010B0* + ID_PRODUCT_FROM_DATABASE=CL9 mainboard + +pci:v00008086d000025A7* + ID_PRODUCT_FROM_DATABASE=6300ESB AC'97 Modem Controller + +pci:v00008086d000025A9* + ID_PRODUCT_FROM_DATABASE=6300ESB USB Universal Host Controller + +pci:v00008086d000025A9sv00001775sd000010D0* + ID_PRODUCT_FROM_DATABASE=V5D Single Board Computer USB + +pci:v00008086d000025A9sv00001775sd00001100* + ID_PRODUCT_FROM_DATABASE=CR11/VR11 Single Board Computer + +pci:v00008086d000025A9sv00001775sd0000CE90* + ID_PRODUCT_FROM_DATABASE=CE9 + +pci:v00008086d000025A9sv00004C53sd000010B0* + ID_PRODUCT_FROM_DATABASE=CL9 mainboard + +pci:v00008086d000025A9sv00004C53sd000010D0* + ID_PRODUCT_FROM_DATABASE=Telum ASLP10 Processor AMC + +pci:v00008086d000025A9sv00004C53sd000010E0* + ID_PRODUCT_FROM_DATABASE=PSL09 PrPMC + +pci:v00008086d000025AA* + ID_PRODUCT_FROM_DATABASE=6300ESB USB Universal Host Controller + +pci:v00008086d000025AAsv00001775sd00001100* + ID_PRODUCT_FROM_DATABASE=CR11/VR11 Single Board Computer + +pci:v00008086d000025AAsv00001775sd0000CE90* + ID_PRODUCT_FROM_DATABASE=CE9 + +pci:v00008086d000025AAsv00004C53sd000010B0* + ID_PRODUCT_FROM_DATABASE=CL9 mainboard + +pci:v00008086d000025AAsv00004C53sd000010D0* + ID_PRODUCT_FROM_DATABASE=Telum ASLP10 Processor AMC + +pci:v00008086d000025AAsv00004C53sd000010E0* + ID_PRODUCT_FROM_DATABASE=PSL09 PrPMC + +pci:v00008086d000025AB* + ID_PRODUCT_FROM_DATABASE=6300ESB Watchdog Timer + +pci:v00008086d000025ABsv00001775sd000010D0* + ID_PRODUCT_FROM_DATABASE=V5D Single Board Computer + +pci:v00008086d000025ABsv00001775sd00001100* + ID_PRODUCT_FROM_DATABASE=CR11/VR11 Single Board Computer + +pci:v00008086d000025ABsv00001775sd0000CE90* + ID_PRODUCT_FROM_DATABASE=CE9 + +pci:v00008086d000025ABsv00004C53sd000010B0* + ID_PRODUCT_FROM_DATABASE=CL9 mainboard + +pci:v00008086d000025ABsv00004C53sd000010D0* + ID_PRODUCT_FROM_DATABASE=Telum ASLP10 Processor AMC + +pci:v00008086d000025ABsv00004C53sd000010E0* + ID_PRODUCT_FROM_DATABASE=PSL09 PrPMC + +pci:v00008086d000025AC* + ID_PRODUCT_FROM_DATABASE=6300ESB I/O Advanced Programmable Interrupt Controller + +pci:v00008086d000025ACsv00001775sd000010D0* + ID_PRODUCT_FROM_DATABASE=V5D Single Board Computer + +pci:v00008086d000025ACsv00001775sd00001100* + ID_PRODUCT_FROM_DATABASE=CR11/VR11 Single Board Computer + +pci:v00008086d000025ACsv00001775sd0000CE90* + ID_PRODUCT_FROM_DATABASE=CE9 + +pci:v00008086d000025ACsv00004C53sd000010B0* + ID_PRODUCT_FROM_DATABASE=CL9 mainboard + +pci:v00008086d000025ACsv00004C53sd000010D0* + ID_PRODUCT_FROM_DATABASE=Telum ASLP10 Processor AMC + +pci:v00008086d000025ACsv00004C53sd000010E0* + ID_PRODUCT_FROM_DATABASE=PSL09 PrPMC + +pci:v00008086d000025AD* + ID_PRODUCT_FROM_DATABASE=6300ESB USB2 Enhanced Host Controller + +pci:v00008086d000025ADsv00001775sd000010D0* + ID_PRODUCT_FROM_DATABASE=V5D Single Board Computer USB 2.0 + +pci:v00008086d000025ADsv00001775sd00001100* + ID_PRODUCT_FROM_DATABASE=CR11/VR11 Single Board Computer + +pci:v00008086d000025ADsv00001775sd0000CE90* + ID_PRODUCT_FROM_DATABASE=CE9 + +pci:v00008086d000025ADsv00004C53sd000010B0* + ID_PRODUCT_FROM_DATABASE=CL9 mainboard + +pci:v00008086d000025ADsv00004C53sd000010D0* + ID_PRODUCT_FROM_DATABASE=Telum ASLP10 Processor AMC + +pci:v00008086d000025ADsv00004C53sd000010E0* + ID_PRODUCT_FROM_DATABASE=PSL09 PrPMC + +pci:v00008086d000025AE* + ID_PRODUCT_FROM_DATABASE=6300ESB 64-bit PCI-X Bridge + +pci:v00008086d000025B0* + ID_PRODUCT_FROM_DATABASE=6300ESB SATA RAID Controller + +pci:v00008086d000025B0sv00001775sd00001100* + ID_PRODUCT_FROM_DATABASE=CR11/VR11 Single Board Computer + +pci:v00008086d000025B0sv00004C53sd000010D0* + ID_PRODUCT_FROM_DATABASE=Telum ASLP10 Processor AMC + +pci:v00008086d000025B0sv00004C53sd000010E0* + ID_PRODUCT_FROM_DATABASE=PSL09 PrPMC + +pci:v00008086d000025C0* + ID_PRODUCT_FROM_DATABASE=5000X Chipset Memory Controller Hub + +pci:v00008086d000025D0* + ID_PRODUCT_FROM_DATABASE=5000Z Chipset Memory Controller Hub + +pci:v00008086d000025D4* + ID_PRODUCT_FROM_DATABASE=5000V Chipset Memory Controller Hub + +pci:v00008086d000025D4sv000015D9sd00008680* + ID_PRODUCT_FROM_DATABASE=X7DVL-E-O motherboard + +pci:v00008086d000025D8* + ID_PRODUCT_FROM_DATABASE=5000P Chipset Memory Controller Hub + +pci:v00008086d000025D8sv00008086sd00003476* + ID_PRODUCT_FROM_DATABASE=Intel S5000PSLSATA Server Board + +pci:v00008086d000025E2* + ID_PRODUCT_FROM_DATABASE=5000 Series Chipset PCI Express x4 Port 2 + +pci:v00008086d000025E3* + ID_PRODUCT_FROM_DATABASE=5000 Series Chipset PCI Express x4 Port 3 + +pci:v00008086d000025E4* + ID_PRODUCT_FROM_DATABASE=5000 Series Chipset PCI Express x4 Port 4 + +pci:v00008086d000025E5* + ID_PRODUCT_FROM_DATABASE=5000 Series Chipset PCI Express x4 Port 5 + +pci:v00008086d000025E6* + ID_PRODUCT_FROM_DATABASE=5000 Series Chipset PCI Express x4 Port 6 + +pci:v00008086d000025E7* + ID_PRODUCT_FROM_DATABASE=5000 Series Chipset PCI Express x4 Port 7 + +pci:v00008086d000025F0* + ID_PRODUCT_FROM_DATABASE=5000 Series Chipset FSB Registers + +pci:v00008086d000025F0sv00001028sd000001BB* + ID_PRODUCT_FROM_DATABASE=PowerEdge 1955 FSB Registers + +pci:v00008086d000025F0sv0000103Csd000031FD* + ID_PRODUCT_FROM_DATABASE=ProLiant DL140 G3 + +pci:v00008086d000025F0sv000015D9sd00008680* + ID_PRODUCT_FROM_DATABASE=X7DVL-E-O motherboard + +pci:v00008086d000025F0sv00008086sd00003476* + ID_PRODUCT_FROM_DATABASE=Intel S5000PSLSATA Server Board + +pci:v00008086d000025F1* + ID_PRODUCT_FROM_DATABASE=5000 Series Chipset Reserved Registers + +pci:v00008086d000025F1sv0000103Csd000031FD* + ID_PRODUCT_FROM_DATABASE=ProLiant DL140 G3 + +pci:v00008086d000025F1sv000015D9sd00008680* + ID_PRODUCT_FROM_DATABASE=X7DVL-E-O motherboard + +pci:v00008086d000025F1sv00008086sd00003476* + ID_PRODUCT_FROM_DATABASE=Intel S5000PSLSATA Server Board + +pci:v00008086d000025F3* + ID_PRODUCT_FROM_DATABASE=5000 Series Chipset Reserved Registers + +pci:v00008086d000025F3sv0000103Csd000031FD* + ID_PRODUCT_FROM_DATABASE=ProLiant DL140 G3 + +pci:v00008086d000025F3sv000015D9sd00008680* + ID_PRODUCT_FROM_DATABASE=X7DVL-E-O motherboard + +pci:v00008086d000025F3sv00008086sd00003476* + ID_PRODUCT_FROM_DATABASE=Intel S5000PSLSATA Server Board + +pci:v00008086d000025F5* + ID_PRODUCT_FROM_DATABASE=5000 Series Chipset FBD Registers + +pci:v00008086d000025F5sv0000103Csd000031FD* + ID_PRODUCT_FROM_DATABASE=ProLiant DL140 G3 + +pci:v00008086d000025F5sv000015D9sd00008680* + ID_PRODUCT_FROM_DATABASE=X7DVL-E-O motherboard + +pci:v00008086d000025F5sv00008086sd00003476* + ID_PRODUCT_FROM_DATABASE=Intel S5000PSLSATA Server Board + +pci:v00008086d000025F6* + ID_PRODUCT_FROM_DATABASE=5000 Series Chipset FBD Registers + +pci:v00008086d000025F6sv0000103Csd000031FD* + ID_PRODUCT_FROM_DATABASE=ProLiant DL140 G3 + +pci:v00008086d000025F6sv000015D9sd00008680* + ID_PRODUCT_FROM_DATABASE=X7DVL-E-O motherboard + +pci:v00008086d000025F6sv00008086sd00003476* + ID_PRODUCT_FROM_DATABASE=Intel S5000PSLSATA Server Board + +pci:v00008086d000025F7* + ID_PRODUCT_FROM_DATABASE=5000 Series Chipset PCI Express x8 Port 2-3 + +pci:v00008086d000025F8* + ID_PRODUCT_FROM_DATABASE=5000 Series Chipset PCI Express x8 Port 4-5 + +pci:v00008086d000025F9* + ID_PRODUCT_FROM_DATABASE=5000 Series Chipset PCI Express x8 Port 6-7 + +pci:v00008086d000025FA* + ID_PRODUCT_FROM_DATABASE=5000X Chipset PCI Express x16 Port 4-7 + +pci:v00008086d00002600* + ID_PRODUCT_FROM_DATABASE=E8500/E8501 Hub Interface 1.5 + +pci:v00008086d00002600sv00001028sd00000170* + ID_PRODUCT_FROM_DATABASE=PowerEdge 6850 Hub Interface + +pci:v00008086d00002601* + ID_PRODUCT_FROM_DATABASE=E8500/E8501 PCI Express x4 Port D + +pci:v00008086d00002602* + ID_PRODUCT_FROM_DATABASE=E8500/E8501 PCI Express x4 Port C0 + +pci:v00008086d00002603* + ID_PRODUCT_FROM_DATABASE=E8500/E8501 PCI Express x4 Port C1 + +pci:v00008086d00002604* + ID_PRODUCT_FROM_DATABASE=E8500/E8501 PCI Express x4 Port B0 + +pci:v00008086d00002605* + ID_PRODUCT_FROM_DATABASE=E8500/E8501 PCI Express x4 Port B1 + +pci:v00008086d00002606* + ID_PRODUCT_FROM_DATABASE=E8500/E8501 PCI Express x4 Port A0 + +pci:v00008086d00002607* + ID_PRODUCT_FROM_DATABASE=E8500/E8501 PCI Express x4 Port A1 + +pci:v00008086d00002608* + ID_PRODUCT_FROM_DATABASE=E8500/E8501 PCI Express x8 Port C + +pci:v00008086d00002609* + ID_PRODUCT_FROM_DATABASE=E8500/E8501 PCI Express x8 Port B + +pci:v00008086d0000260A* + ID_PRODUCT_FROM_DATABASE=E8500/E8501 PCI Express x8 Port A + +pci:v00008086d0000260C* + ID_PRODUCT_FROM_DATABASE=E8500/E8501 IMI Registers + +pci:v00008086d00002610* + ID_PRODUCT_FROM_DATABASE=E8500/E8501 FSB Registers + +pci:v00008086d00002611* + ID_PRODUCT_FROM_DATABASE=E8500/E8501 Address Mapping Registers + +pci:v00008086d00002612* + ID_PRODUCT_FROM_DATABASE=E8500/E8501 RAS Registers + +pci:v00008086d00002613* + ID_PRODUCT_FROM_DATABASE=E8500/E8501 Reserved Registers + +pci:v00008086d00002614* + ID_PRODUCT_FROM_DATABASE=E8500/E8501 Reserved Registers + +pci:v00008086d00002615* + ID_PRODUCT_FROM_DATABASE=E8500/E8501 Miscellaneous Registers + +pci:v00008086d00002617* + ID_PRODUCT_FROM_DATABASE=E8500/E8501 Reserved Registers + +pci:v00008086d00002618* + ID_PRODUCT_FROM_DATABASE=E8500/E8501 Reserved Registers + +pci:v00008086d00002619* + ID_PRODUCT_FROM_DATABASE=E8500/E8501 Reserved Registers + +pci:v00008086d0000261A* + ID_PRODUCT_FROM_DATABASE=E8500/E8501 Reserved Registers + +pci:v00008086d0000261B* + ID_PRODUCT_FROM_DATABASE=E8500/E8501 Reserved Registers + +pci:v00008086d0000261C* + ID_PRODUCT_FROM_DATABASE=E8500/E8501 Reserved Registers + +pci:v00008086d0000261D* + ID_PRODUCT_FROM_DATABASE=E8500/E8501 Reserved Registers + +pci:v00008086d0000261E* + ID_PRODUCT_FROM_DATABASE=E8500/E8501 Reserved Registers + +pci:v00008086d00002620* + ID_PRODUCT_FROM_DATABASE=E8500/E8501 eXternal Memory Bridge + +pci:v00008086d00002620sv00001028sd00000170* + ID_PRODUCT_FROM_DATABASE=PowerEdge 6850 Memory Bridge + +pci:v00008086d00002621* + ID_PRODUCT_FROM_DATABASE=E8500/E8501 XMB Miscellaneous Registers + +pci:v00008086d00002621sv00001028sd00000170* + ID_PRODUCT_FROM_DATABASE=PowerEdge 6850 XMB Registers + +pci:v00008086d00002622* + ID_PRODUCT_FROM_DATABASE=E8500/E8501 XMB Memory Interleaving Registers + +pci:v00008086d00002622sv00001028sd00000170* + ID_PRODUCT_FROM_DATABASE=PowerEdge 6850 Memory Interleaving Registers + +pci:v00008086d00002623* + ID_PRODUCT_FROM_DATABASE=E8500/E8501 XMB DDR Initialization and Calibration + +pci:v00008086d00002623sv00001028sd00000170* + ID_PRODUCT_FROM_DATABASE=PowerEdge 6850 DDR Initialization and Calibration + +pci:v00008086d00002624* + ID_PRODUCT_FROM_DATABASE=E8500/E8501 XMB Reserved Registers + +pci:v00008086d00002624sv00001028sd00000170* + ID_PRODUCT_FROM_DATABASE=PowerEdge 6850 Reserved Registers + +pci:v00008086d00002625* + ID_PRODUCT_FROM_DATABASE=E8500/E8501 XMB Reserved Registers + +pci:v00008086d00002625sv00001028sd00000170* + ID_PRODUCT_FROM_DATABASE=PowerEdge 6850 Reserved Registers + +pci:v00008086d00002626* + ID_PRODUCT_FROM_DATABASE=E8500/E8501 XMB Reserved Registers + +pci:v00008086d00002626sv00001028sd00000170* + ID_PRODUCT_FROM_DATABASE=PowerEdge 6850 Reserved Registers + +pci:v00008086d00002627* + ID_PRODUCT_FROM_DATABASE=E8500/E8501 XMB Reserved Registers + +pci:v00008086d00002627sv00001028sd00000170* + ID_PRODUCT_FROM_DATABASE=PowerEdge 6850 Reserved Registers + +pci:v00008086d00002640* + ID_PRODUCT_FROM_DATABASE=82801FB/FR (ICH6/ICH6R) LPC Interface Bridge + +pci:v00008086d00002640sv00001462sd00007028* + ID_PRODUCT_FROM_DATABASE=915P/G Neo2 + +pci:v00008086d00002640sv00001734sd0000105C* + ID_PRODUCT_FROM_DATABASE=Scenic W620 + +pci:v00008086d00002640sv0000E4BFsd00000CCD* + ID_PRODUCT_FROM_DATABASE=CCD-CALYPSO + +pci:v00008086d00002640sv0000E4BFsd00000CD3* + ID_PRODUCT_FROM_DATABASE=CD3-JIVE + +pci:v00008086d00002640sv0000E4BFsd000058B1* + ID_PRODUCT_FROM_DATABASE=XB1 + +pci:v00008086d00002641* + ID_PRODUCT_FROM_DATABASE=82801FBM (ICH6M) LPC Interface Bridge + +pci:v00008086d00002641sv0000103Csd00000934* + ID_PRODUCT_FROM_DATABASE=Compaq nw8240/nx8220 + +pci:v00008086d00002641sv0000103Csd0000099C* + ID_PRODUCT_FROM_DATABASE=NX6110/NC6120 + +pci:v00008086d00002642* + ID_PRODUCT_FROM_DATABASE=82801FW/FRW (ICH6W/ICH6RW) LPC Interface Bridge + +pci:v00008086d00002651* + ID_PRODUCT_FROM_DATABASE=82801FB/FW (ICH6/ICH6W) SATA Controller + +pci:v00008086d00002651sv00001028sd00000179* + ID_PRODUCT_FROM_DATABASE=Optiplex GX280 + +pci:v00008086d00002651sv00001043sd00002601* + ID_PRODUCT_FROM_DATABASE=P5GD1-VW Mainboard + +pci:v00008086d00002651sv00001734sd0000105C* + ID_PRODUCT_FROM_DATABASE=Scenic W620 + +pci:v00008086d00002651sv00008086sd00004147* + ID_PRODUCT_FROM_DATABASE=D915GAG Motherboard + +pci:v00008086d00002651sv0000E4BFsd00000CCD* + ID_PRODUCT_FROM_DATABASE=CCD-CALYPSO + +pci:v00008086d00002651sv0000E4BFsd00000CD3* + ID_PRODUCT_FROM_DATABASE=CD3-JIVE + +pci:v00008086d00002651sv0000E4BFsd000058B1* + ID_PRODUCT_FROM_DATABASE=XB1 + +pci:v00008086d00002652* + ID_PRODUCT_FROM_DATABASE=82801FR/FRW (ICH6R/ICH6RW) SATA Controller + +pci:v00008086d00002652sv00001028sd00000177* + ID_PRODUCT_FROM_DATABASE=Dimension 8400 + +pci:v00008086d00002652sv00001462sd00007028* + ID_PRODUCT_FROM_DATABASE=915P/G Neo2 + +pci:v00008086d00002653* + ID_PRODUCT_FROM_DATABASE=82801FBM (ICH6M) SATA Controller + +pci:v00008086d00002658* + ID_PRODUCT_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #1 + +pci:v00008086d00002658sv00001028sd00000177* + ID_PRODUCT_FROM_DATABASE=Dimension 8400 + +pci:v00008086d00002658sv00001028sd00000179* + ID_PRODUCT_FROM_DATABASE=Optiplex GX280 + +pci:v00008086d00002658sv0000103Csd00000934* + ID_PRODUCT_FROM_DATABASE=Compaq nw8240/nx8220 + +pci:v00008086d00002658sv0000103Csd0000099C* + ID_PRODUCT_FROM_DATABASE=NX6110/NC6120 + +pci:v00008086d00002658sv00001043sd000080A6* + ID_PRODUCT_FROM_DATABASE=P5GD1-VW Mainboard + +pci:v00008086d00002658sv00001458sd00002558* + ID_PRODUCT_FROM_DATABASE=GA-8I915ME-G Mainboard + +pci:v00008086d00002658sv00001462sd00007028* + ID_PRODUCT_FROM_DATABASE=915P/G Neo2 + +pci:v00008086d00002658sv00001734sd0000105C* + ID_PRODUCT_FROM_DATABASE=Scenic W620 + +pci:v00008086d00002658sv0000E4BFsd00000CCD* + ID_PRODUCT_FROM_DATABASE=CCD-CALYPSO + +pci:v00008086d00002658sv0000E4BFsd00000CD3* + ID_PRODUCT_FROM_DATABASE=CD3-JIVE + +pci:v00008086d00002658sv0000E4BFsd000058B1* + ID_PRODUCT_FROM_DATABASE=XB1 + +pci:v00008086d00002659* + ID_PRODUCT_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #2 + +pci:v00008086d00002659sv00001028sd00000177* + ID_PRODUCT_FROM_DATABASE=Dimension 8400 + +pci:v00008086d00002659sv00001028sd00000179* + ID_PRODUCT_FROM_DATABASE=Optiplex GX280 + +pci:v00008086d00002659sv0000103Csd00000934* + ID_PRODUCT_FROM_DATABASE=Compaq nw8240/nx8220 + +pci:v00008086d00002659sv0000103Csd0000099C* + ID_PRODUCT_FROM_DATABASE=NX6110/NC6120 + +pci:v00008086d00002659sv00001043sd000080A6* + ID_PRODUCT_FROM_DATABASE=P5GD1-VW Mainboard + +pci:v00008086d00002659sv00001458sd00002659* + ID_PRODUCT_FROM_DATABASE=GA-8I915ME-G Mainboard + +pci:v00008086d00002659sv00001462sd00007028* + ID_PRODUCT_FROM_DATABASE=915P/G Neo2 + +pci:v00008086d00002659sv00001734sd0000105C* + ID_PRODUCT_FROM_DATABASE=Scenic W620 + +pci:v00008086d00002659sv0000E4BFsd00000CCD* + ID_PRODUCT_FROM_DATABASE=CCD-CALYPSO + +pci:v00008086d00002659sv0000E4BFsd00000CD3* + ID_PRODUCT_FROM_DATABASE=CD3-JIVE + +pci:v00008086d00002659sv0000E4BFsd000058B1* + ID_PRODUCT_FROM_DATABASE=XB1 + +pci:v00008086d0000265A* + ID_PRODUCT_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #3 + +pci:v00008086d0000265Asv00001028sd00000177* + ID_PRODUCT_FROM_DATABASE=Dimension 8400 + +pci:v00008086d0000265Asv00001028sd00000179* + ID_PRODUCT_FROM_DATABASE=Optiplex GX280 + +pci:v00008086d0000265Asv0000103Csd00000934* + ID_PRODUCT_FROM_DATABASE=Compaq nw8240/nx8220 + +pci:v00008086d0000265Asv0000103Csd0000099C* + ID_PRODUCT_FROM_DATABASE=NX6110/NC6120 + +pci:v00008086d0000265Asv00001043sd000080A6* + ID_PRODUCT_FROM_DATABASE=P5GD1-VW Mainboard + +pci:v00008086d0000265Asv00001458sd0000265A* + ID_PRODUCT_FROM_DATABASE=GA-8I915ME-G Mainboard + +pci:v00008086d0000265Asv00001462sd00007028* + ID_PRODUCT_FROM_DATABASE=915P/G Neo2 + +pci:v00008086d0000265Asv00001734sd0000105C* + ID_PRODUCT_FROM_DATABASE=Scenic W620 + +pci:v00008086d0000265Asv0000E4BFsd00000CCD* + ID_PRODUCT_FROM_DATABASE=CCD-CALYPSO + +pci:v00008086d0000265Asv0000E4BFsd00000CD3* + ID_PRODUCT_FROM_DATABASE=CD3-JIVE + +pci:v00008086d0000265Asv0000E4BFsd000058B1* + ID_PRODUCT_FROM_DATABASE=XB1 + +pci:v00008086d0000265B* + ID_PRODUCT_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #4 + +pci:v00008086d0000265Bsv00001028sd00000177* + ID_PRODUCT_FROM_DATABASE=Dimension 8400 + +pci:v00008086d0000265Bsv00001028sd00000179* + ID_PRODUCT_FROM_DATABASE=Optiplex GX280 + +pci:v00008086d0000265Bsv0000103Csd0000099C* + ID_PRODUCT_FROM_DATABASE=NX6110/NC6120 + +pci:v00008086d0000265Bsv00001043sd000080A6* + ID_PRODUCT_FROM_DATABASE=P5GD1-VW Mainboard + +pci:v00008086d0000265Bsv00001458sd0000265A* + ID_PRODUCT_FROM_DATABASE=GA-8I915ME-G Mainboard + +pci:v00008086d0000265Bsv00001462sd00007028* + ID_PRODUCT_FROM_DATABASE=915P/G Neo2 + +pci:v00008086d0000265Bsv00001734sd0000105C* + ID_PRODUCT_FROM_DATABASE=Scenic W620 + +pci:v00008086d0000265Bsv0000E4BFsd00000CCD* + ID_PRODUCT_FROM_DATABASE=CCD-CALYPSO + +pci:v00008086d0000265Bsv0000E4BFsd00000CD3* + ID_PRODUCT_FROM_DATABASE=CD3-JIVE + +pci:v00008086d0000265Bsv0000E4BFsd000058B1* + ID_PRODUCT_FROM_DATABASE=XB1 + +pci:v00008086d0000265C* + ID_PRODUCT_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB2 EHCI Controller + +pci:v00008086d0000265Csv00001028sd00000177* + ID_PRODUCT_FROM_DATABASE=Dimension 8400 + +pci:v00008086d0000265Csv00001028sd00000179* + ID_PRODUCT_FROM_DATABASE=Optiplex GX280 + +pci:v00008086d0000265Csv0000103Csd00000934* + ID_PRODUCT_FROM_DATABASE=Compaq nw8240/nx8220 + +pci:v00008086d0000265Csv0000103Csd0000099C* + ID_PRODUCT_FROM_DATABASE=NX6110/NC6120 + +pci:v00008086d0000265Csv00001043sd000080A6* + ID_PRODUCT_FROM_DATABASE=P5GD1-VW Mainboard + +pci:v00008086d0000265Csv00001458sd00005006* + ID_PRODUCT_FROM_DATABASE=GA-8I915ME-G Mainboard + +pci:v00008086d0000265Csv00001462sd00007028* + ID_PRODUCT_FROM_DATABASE=915P/G Neo2 + +pci:v00008086d0000265Csv00001734sd0000105C* + ID_PRODUCT_FROM_DATABASE=Scenic W620 + +pci:v00008086d0000265Csv00008086sd0000265C* + ID_PRODUCT_FROM_DATABASE=Dimension 3100 + +pci:v00008086d0000265Csv0000E4BFsd00000CCD* + ID_PRODUCT_FROM_DATABASE=CCD-CALYPSO + +pci:v00008086d0000265Csv0000E4BFsd00000CD3* + ID_PRODUCT_FROM_DATABASE=CD3-JIVE + +pci:v00008086d0000265Csv0000E4BFsd000058B1* + ID_PRODUCT_FROM_DATABASE=XB1 + +pci:v00008086d00002660* + ID_PRODUCT_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) PCI Express Port 1 + +pci:v00008086d00002660sv0000103Csd00000934* + ID_PRODUCT_FROM_DATABASE=HP Compaq nw8240 Mobile Workstation + +pci:v00008086d00002660sv0000103Csd0000099C* + ID_PRODUCT_FROM_DATABASE=NX6110/NC6120 + +pci:v00008086d00002660sv0000E4BFsd00000CCD* + ID_PRODUCT_FROM_DATABASE=CCD-CALYPSO + +pci:v00008086d00002660sv0000E4BFsd00000CD3* + ID_PRODUCT_FROM_DATABASE=CD3-JIVE + +pci:v00008086d00002660sv0000E4BFsd000058B1* + ID_PRODUCT_FROM_DATABASE=XB1 + +pci:v00008086d00002662* + ID_PRODUCT_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) PCI Express Port 2 + +pci:v00008086d00002662sv0000103Csd00000934* + ID_PRODUCT_FROM_DATABASE=HP Compaq nw8240 Mobile Workstation + +pci:v00008086d00002662sv0000E4BFsd00000CCD* + ID_PRODUCT_FROM_DATABASE=CCD-CALYPSO + +pci:v00008086d00002662sv0000E4BFsd00000CD3* + ID_PRODUCT_FROM_DATABASE=CD3-JIVE + +pci:v00008086d00002662sv0000E4BFsd000058B1* + ID_PRODUCT_FROM_DATABASE=XB1 + +pci:v00008086d00002664* + ID_PRODUCT_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) PCI Express Port 3 + +pci:v00008086d00002664sv0000E4BFsd00000CCD* + ID_PRODUCT_FROM_DATABASE=CCD-CALYPSO + +pci:v00008086d00002664sv0000E4BFsd00000CD3* + ID_PRODUCT_FROM_DATABASE=CD3-JIVE + +pci:v00008086d00002664sv0000E4BFsd000058B1* + ID_PRODUCT_FROM_DATABASE=XB1 + +pci:v00008086d00002666* + ID_PRODUCT_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) PCI Express Port 4 + +pci:v00008086d00002666sv0000E4BFsd00000CCD* + ID_PRODUCT_FROM_DATABASE=CCD-CALYPSO + +pci:v00008086d00002666sv0000E4BFsd00000CD3* + ID_PRODUCT_FROM_DATABASE=CD3-JIVE + +pci:v00008086d00002666sv0000E4BFsd000058B1* + ID_PRODUCT_FROM_DATABASE=XB1 + +pci:v00008086d00002668* + ID_PRODUCT_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) High Definition Audio Controller + +pci:v00008086d00002668sv00001014sd000005B7* + ID_PRODUCT_FROM_DATABASE=ThinkPad Z60t + +pci:v00008086d00002668sv0000103Csd00002A09* + ID_PRODUCT_FROM_DATABASE=PufferM-UL8E + +pci:v00008086d00002668sv00001043sd00001173* + ID_PRODUCT_FROM_DATABASE=Asus A6VC + +pci:v00008086d00002668sv00001043sd0000814E* + ID_PRODUCT_FROM_DATABASE=P5GD1-VW Mainboard + +pci:v00008086d00002668sv00001462sd00007028* + ID_PRODUCT_FROM_DATABASE=915P/G Neo2 + +pci:v00008086d0000266A* + ID_PRODUCT_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) SMBus Controller + +pci:v00008086d0000266Asv00001028sd00000177* + ID_PRODUCT_FROM_DATABASE=Dimension 8400 + +pci:v00008086d0000266Asv00001028sd00000179* + ID_PRODUCT_FROM_DATABASE=Optiplex GX280 + +pci:v00008086d0000266Asv00001043sd000080A6* + ID_PRODUCT_FROM_DATABASE=P5GD1-VW Mainboard + +pci:v00008086d0000266Asv00001458sd0000266A* + ID_PRODUCT_FROM_DATABASE=GA-8I915ME-G Mainboard + +pci:v00008086d0000266Asv00001462sd00007028* + ID_PRODUCT_FROM_DATABASE=915P/G Neo2 + +pci:v00008086d0000266Asv00001734sd0000105C* + ID_PRODUCT_FROM_DATABASE=Scenic W620 + +pci:v00008086d0000266Asv0000E4BFsd00000CCD* + ID_PRODUCT_FROM_DATABASE=CCD-CALYPSO + +pci:v00008086d0000266Asv0000E4BFsd00000CD3* + ID_PRODUCT_FROM_DATABASE=CD3-JIVE + +pci:v00008086d0000266Asv0000E4BFsd000058B1* + ID_PRODUCT_FROM_DATABASE=XB1 + +pci:v00008086d0000266C* + ID_PRODUCT_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) LAN Controller + +pci:v00008086d0000266D* + ID_PRODUCT_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) AC'97 Modem Controller + +pci:v00008086d0000266Dsv00001025sd0000006A* + ID_PRODUCT_FROM_DATABASE=Conexant AC'97 CoDec (in Acer TravelMate 2410 serie laptop) + +pci:v00008086d0000266Dsv0000103Csd00000934* + ID_PRODUCT_FROM_DATABASE=Compaq nw8240/nx8220 + +pci:v00008086d0000266Dsv0000103Csd0000099C* + ID_PRODUCT_FROM_DATABASE=NX6110/NC6120 + +pci:v00008086d0000266E* + ID_PRODUCT_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) AC'97 Audio Controller + +pci:v00008086d0000266Esv00001025sd0000006A* + ID_PRODUCT_FROM_DATABASE=Realtek ALC 655 codec (in Acer TravelMate 2410 serie laptop) + +pci:v00008086d0000266Esv00001028sd00000177* + ID_PRODUCT_FROM_DATABASE=Dimension 8400 + +pci:v00008086d0000266Esv00001028sd00000179* + ID_PRODUCT_FROM_DATABASE=Optiplex GX280 + +pci:v00008086d0000266Esv00001028sd00000182* + ID_PRODUCT_FROM_DATABASE=Latitude D610 Laptop + +pci:v00008086d0000266Esv00001028sd00000187* + ID_PRODUCT_FROM_DATABASE=Dell Precision M70 Laptop + +pci:v00008086d0000266Esv00001028sd00000188* + ID_PRODUCT_FROM_DATABASE=Inspiron 6000 laptop + +pci:v00008086d0000266Esv0000103Csd00000934* + ID_PRODUCT_FROM_DATABASE=Compaq nw8240/nx8220 + +pci:v00008086d0000266Esv0000103Csd00000944* + ID_PRODUCT_FROM_DATABASE=Compaq NC6220 + +pci:v00008086d0000266Esv0000103Csd0000099C* + ID_PRODUCT_FROM_DATABASE=NX6110/NC6120 + +pci:v00008086d0000266Esv0000103Csd00003006* + ID_PRODUCT_FROM_DATABASE=DC7100 SFF(DX878AV) + +pci:v00008086d0000266Esv00001458sd0000A002* + ID_PRODUCT_FROM_DATABASE=GA-8I915ME-G Mainboard + +pci:v00008086d0000266Esv0000152Dsd00000745* + ID_PRODUCT_FROM_DATABASE=Packard Bell A8550 Laptop + +pci:v00008086d0000266Esv00001734sd0000105A* + ID_PRODUCT_FROM_DATABASE=Scenic W620 + +pci:v00008086d0000266F* + ID_PRODUCT_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) IDE Controller + +pci:v00008086d0000266Fsv00001028sd00000177* + ID_PRODUCT_FROM_DATABASE=Dimension 8400 + +pci:v00008086d0000266Fsv0000103Csd00000934* + ID_PRODUCT_FROM_DATABASE=Compaq nw8240/nx8220 + +pci:v00008086d0000266Fsv0000103Csd0000099C* + ID_PRODUCT_FROM_DATABASE=NX6110/NC6120 + +pci:v00008086d0000266Fsv00001043sd000080A6* + ID_PRODUCT_FROM_DATABASE=P5GD1-VW Mainboard + +pci:v00008086d0000266Fsv00001458sd0000266F* + ID_PRODUCT_FROM_DATABASE=GA-8I915ME-G Mainboard + +pci:v00008086d0000266Fsv00001462sd00007028* + ID_PRODUCT_FROM_DATABASE=915P/G Neo2 + +pci:v00008086d0000266Fsv00001734sd0000105C* + ID_PRODUCT_FROM_DATABASE=Scenic W620 + +pci:v00008086d0000266Fsv0000E4BFsd00000CCD* + ID_PRODUCT_FROM_DATABASE=CCD-CALYPSO + +pci:v00008086d0000266Fsv0000E4BFsd00000CD3* + ID_PRODUCT_FROM_DATABASE=CD3-JIVE + +pci:v00008086d0000266Fsv0000E4BFsd000058B1* + ID_PRODUCT_FROM_DATABASE=XB1 + +pci:v00008086d00002670* + ID_PRODUCT_FROM_DATABASE=631xESB/632xESB/3100 Chipset LPC Interface Controller + +pci:v00008086d00002670sv0000103Csd000031FE* + ID_PRODUCT_FROM_DATABASE=ProLiant DL140 G3 + +pci:v00008086d00002670sv000015D9sd00008680* + ID_PRODUCT_FROM_DATABASE=X7DVL-E-O motherboard + +pci:v00008086d00002670sv00008086sd00003476* + ID_PRODUCT_FROM_DATABASE=Intel S5000PSLSATA Server Board + +pci:v00008086d00002680* + ID_PRODUCT_FROM_DATABASE=631xESB/632xESB/3100 Chipset SATA IDE Controller + +pci:v00008086d00002681* + ID_PRODUCT_FROM_DATABASE=631xESB/632xESB SATA AHCI Controller + +pci:v00008086d00002681sv0000103Csd000031FE* + ID_PRODUCT_FROM_DATABASE=ProLiant DL140 G3 + +pci:v00008086d00002681sv000015D9sd00008680* + ID_PRODUCT_FROM_DATABASE=X7DVL-E-O motherboard + +pci:v00008086d00002681sv00008086sd00003476* + ID_PRODUCT_FROM_DATABASE=Intel S5000PSLSATA Server Board + +pci:v00008086d00002682* + ID_PRODUCT_FROM_DATABASE=631xESB/632xESB SATA RAID Controller + +pci:v00008086d00002682sv0000103Csd000031FE* + ID_PRODUCT_FROM_DATABASE=Adaptec Serial ATA HostRAID + +pci:v00008086d00002683* + ID_PRODUCT_FROM_DATABASE=631xESB/632xESB SATA RAID Controller + +pci:v00008086d00002688* + ID_PRODUCT_FROM_DATABASE=631xESB/632xESB/3100 Chipset UHCI USB Controller #1 + +pci:v00008086d00002688sv00001028sd000001BB* + ID_PRODUCT_FROM_DATABASE=PowerEdge 1955 onboard USB + +pci:v00008086d00002688sv00001028sd000001F0* + ID_PRODUCT_FROM_DATABASE=PowerEdge R900 onboard USB + +pci:v00008086d00002688sv0000103Csd000031FE* + ID_PRODUCT_FROM_DATABASE=ProLiant DL140 G3 + +pci:v00008086d00002688sv000015D9sd00008680* + ID_PRODUCT_FROM_DATABASE=X7DVL-E-O motherboard + +pci:v00008086d00002688sv00008086sd00003476* + ID_PRODUCT_FROM_DATABASE=Intel S5000PSLSATA Server Board + +pci:v00008086d00002689* + ID_PRODUCT_FROM_DATABASE=631xESB/632xESB/3100 Chipset UHCI USB Controller #2 + +pci:v00008086d00002689sv00001028sd000001BB* + ID_PRODUCT_FROM_DATABASE=PowerEdge 1955 onboard USB + +pci:v00008086d00002689sv00001028sd000001F0* + ID_PRODUCT_FROM_DATABASE=PowerEdge R900 onboard USB + +pci:v00008086d00002689sv0000103Csd000031FE* + ID_PRODUCT_FROM_DATABASE=ProLiant DL140 G3 + +pci:v00008086d00002689sv000015D9sd00008680* + ID_PRODUCT_FROM_DATABASE=X7DVL-E-O motherboard + +pci:v00008086d00002689sv00008086sd00003476* + ID_PRODUCT_FROM_DATABASE=Intel S5000PSLSATA Server Board + +pci:v00008086d0000268A* + ID_PRODUCT_FROM_DATABASE=631xESB/632xESB/3100 Chipset UHCI USB Controller #3 + +pci:v00008086d0000268Asv00001028sd000001F0* + ID_PRODUCT_FROM_DATABASE=PowerEdge R900 onboard USB + +pci:v00008086d0000268Asv0000103Csd000031FE* + ID_PRODUCT_FROM_DATABASE=ProLiant DL140 G3 + +pci:v00008086d0000268Asv000015D9sd00008680* + ID_PRODUCT_FROM_DATABASE=X7DVL-E-O motherboard + +pci:v00008086d0000268Asv00008086sd00003476* + ID_PRODUCT_FROM_DATABASE=Intel S5000PSLSATA Server Board + +pci:v00008086d0000268B* + ID_PRODUCT_FROM_DATABASE=631xESB/632xESB/3100 Chipset UHCI USB Controller #4 + +pci:v00008086d0000268Bsv00001028sd000001F0* + ID_PRODUCT_FROM_DATABASE=PowerEdge R900 onboard USB + +pci:v00008086d0000268Bsv000015D9sd00008680* + ID_PRODUCT_FROM_DATABASE=X7DVL-E-O motherboard + +pci:v00008086d0000268Bsv00008086sd00003476* + ID_PRODUCT_FROM_DATABASE=Intel S5000PSLSATA Server Board + +pci:v00008086d0000268C* + ID_PRODUCT_FROM_DATABASE=631xESB/632xESB/3100 Chipset EHCI USB2 Controller + +pci:v00008086d0000268Csv00001028sd000001BB* + ID_PRODUCT_FROM_DATABASE=PowerEdge 1955 onboard USB + +pci:v00008086d0000268Csv00001028sd000001F0* + ID_PRODUCT_FROM_DATABASE=PowerEdge R900 onboard USB + +pci:v00008086d0000268Csv0000103Csd000031FE* + ID_PRODUCT_FROM_DATABASE=ProLiant DL140 G3 + +pci:v00008086d0000268Csv000015D9sd00008680* + ID_PRODUCT_FROM_DATABASE=X7DVL-E-O motherboard + +pci:v00008086d0000268Csv00008086sd00003476* + ID_PRODUCT_FROM_DATABASE=Intel S5000PSLSATA Server Board + +pci:v00008086d00002690* + ID_PRODUCT_FROM_DATABASE=631xESB/632xESB/3100 Chipset PCI Express Root Port 1 + +pci:v00008086d00002690sv0000103Csd000031FE* + ID_PRODUCT_FROM_DATABASE=ProLiant DL140 G3 + +pci:v00008086d00002692* + ID_PRODUCT_FROM_DATABASE=631xESB/632xESB/3100 Chipset PCI Express Root Port 2 + +pci:v00008086d00002692sv0000103Csd000031FE* + ID_PRODUCT_FROM_DATABASE=ProLiant DL140 G3 + +pci:v00008086d00002694* + ID_PRODUCT_FROM_DATABASE=631xESB/632xESB/3100 Chipset PCI Express Root Port 3 + +pci:v00008086d00002696* + ID_PRODUCT_FROM_DATABASE=631xESB/632xESB/3100 Chipset PCI Express Root Port 4 + +pci:v00008086d00002698* + ID_PRODUCT_FROM_DATABASE=631xESB/632xESB AC '97 Audio Controller + +pci:v00008086d00002699* + ID_PRODUCT_FROM_DATABASE=631xESB/632xESB AC '97 Modem Controller + +pci:v00008086d0000269A* + ID_PRODUCT_FROM_DATABASE=631xESB/632xESB High Definition Audio Controller + +pci:v00008086d0000269B* + ID_PRODUCT_FROM_DATABASE=631xESB/632xESB/3100 Chipset SMBus Controller + +pci:v00008086d0000269Bsv0000103Csd000031FE* + ID_PRODUCT_FROM_DATABASE=ProLiant DL140 G3 + +pci:v00008086d0000269Bsv000015D9sd00008680* + ID_PRODUCT_FROM_DATABASE=X7DVL-E-O motherboard + +pci:v00008086d0000269Bsv00008086sd00003476* + ID_PRODUCT_FROM_DATABASE=Intel S5000PSLSATA Server Board + +pci:v00008086d0000269E* + ID_PRODUCT_FROM_DATABASE=631xESB/632xESB IDE Controller + +pci:v00008086d0000269Esv0000103Csd000031FE* + ID_PRODUCT_FROM_DATABASE=ProLiant DL140 G3 + +pci:v00008086d0000269Esv000015D9sd00008680* + ID_PRODUCT_FROM_DATABASE=X7DVL-E-O motherboard + +pci:v00008086d00002770* + ID_PRODUCT_FROM_DATABASE=82945G/GZ/P/PL Memory Controller Hub + +pci:v00008086d00002770sv00001028sd000001AD* + ID_PRODUCT_FROM_DATABASE=OptiPlex GX620 + +pci:v00008086d00002770sv0000103Csd00002A3B* + ID_PRODUCT_FROM_DATABASE=Pavilion A1512X + +pci:v00008086d00002770sv00001043sd0000817A* + ID_PRODUCT_FROM_DATABASE=P5LD2-VM Mainboard + +pci:v00008086d00002770sv0000107Bsd00005048* + ID_PRODUCT_FROM_DATABASE=E4500 + +pci:v00008086d00002770sv00008086sd0000544E* + ID_PRODUCT_FROM_DATABASE=DeskTop Board D945GTP + +pci:v00008086d00002771* + ID_PRODUCT_FROM_DATABASE=82945G/GZ/P/PL PCI Express Root Port + +pci:v00008086d00002772* + ID_PRODUCT_FROM_DATABASE=82945G/GZ Integrated Graphics Controller + +pci:v00008086d00002772sv0000103Csd00002A3B* + ID_PRODUCT_FROM_DATABASE=Pavilion A1512X + +pci:v00008086d00002772sv00008086sd0000544E* + ID_PRODUCT_FROM_DATABASE=DeskTop Board D945GTP + +pci:v00008086d00002772sv00008086sd0000D605* + ID_PRODUCT_FROM_DATABASE=Intel Desktop Board D945GCCR + +pci:v00008086d00002774* + ID_PRODUCT_FROM_DATABASE=82955X Memory Controller Hub + +pci:v00008086d00002775* + ID_PRODUCT_FROM_DATABASE=82955X PCI Express Root Port + +pci:v00008086d00002776* + ID_PRODUCT_FROM_DATABASE=82945G/GZ Integrated Graphics Controller + +pci:v00008086d00002778* + ID_PRODUCT_FROM_DATABASE=E7230/3000/3010 Memory Controller Hub + +pci:v00008086d00002778sv00001028sd000001DF* + ID_PRODUCT_FROM_DATABASE=PowerEdge SC440 + +pci:v00008086d00002778sv00001028sd000001E6* + ID_PRODUCT_FROM_DATABASE=PowerEdge 860 + +pci:v00008086d00002779* + ID_PRODUCT_FROM_DATABASE=E7230/3000/3010 PCI Express Root Port + +pci:v00008086d0000277A* + ID_PRODUCT_FROM_DATABASE=82975X/3010 PCI Express Root Port + +pci:v00008086d0000277C* + ID_PRODUCT_FROM_DATABASE=82975X Memory Controller Hub + +pci:v00008086d0000277Csv00001043sd00008178* + ID_PRODUCT_FROM_DATABASE=P5WDG2 WS Professional motherboard + +pci:v00008086d0000277D* + ID_PRODUCT_FROM_DATABASE=82975X PCI Express Root Port + +pci:v00008086d00002782* + ID_PRODUCT_FROM_DATABASE=82915G Integrated Graphics Controller + +pci:v00008086d00002782sv00001043sd00002582* + ID_PRODUCT_FROM_DATABASE=P5GD1-VW Mainboard + +pci:v00008086d00002782sv00001734sd0000105B* + ID_PRODUCT_FROM_DATABASE=Scenic W620 + +pci:v00008086d00002792* + ID_PRODUCT_FROM_DATABASE=Mobile 915GM/GMS/910GML Express Graphics Controller + +pci:v00008086d00002792sv0000103Csd0000099C* + ID_PRODUCT_FROM_DATABASE=NX6110/NC6120 + +pci:v00008086d00002792sv00001043sd00001881* + ID_PRODUCT_FROM_DATABASE=GMA 900 915GM Integrated Graphics + +pci:v00008086d00002792sv0000E4BFsd00000CCD* + ID_PRODUCT_FROM_DATABASE=CCD-CALYPSO + +pci:v00008086d00002792sv0000E4BFsd00000CD3* + ID_PRODUCT_FROM_DATABASE=CD3-JIVE + +pci:v00008086d00002792sv0000E4BFsd000058B1* + ID_PRODUCT_FROM_DATABASE=XB1 + +pci:v00008086d000027A0* + ID_PRODUCT_FROM_DATABASE=Mobile 945GM/PM/GMS, 943/940GML and 945GT Express Memory Controller Hub + +pci:v00008086d000027A0sv00001025sd0000006C* + ID_PRODUCT_FROM_DATABASE=9814 WKMI + +pci:v00008086d000027A0sv00001028sd000001D7* + ID_PRODUCT_FROM_DATABASE=XPS M1210 + +pci:v00008086d000027A0sv0000103Csd0000309F* + ID_PRODUCT_FROM_DATABASE=Compaq nx9420 Notebook + +pci:v00008086d000027A0sv0000103Csd000030A1* + ID_PRODUCT_FROM_DATABASE=NC2400 + +pci:v00008086d000027A0sv0000103Csd000030A3* + ID_PRODUCT_FROM_DATABASE=Compaq nw8440 + +pci:v00008086d000027A0sv00001043sd00001237* + ID_PRODUCT_FROM_DATABASE=A6J-Q008 + +pci:v00008086d000027A0sv000017AAsd00002015* + ID_PRODUCT_FROM_DATABASE=ThinkPad T60 + +pci:v00008086d000027A0sv000017AAsd00002017* + ID_PRODUCT_FROM_DATABASE=ThinkPad T60/R60 series + +pci:v00008086d000027A1* + ID_PRODUCT_FROM_DATABASE=Mobile 945GM/PM/GMS, 943/940GML and 945GT Express PCI Express Root Port + +pci:v00008086d000027A1sv0000103Csd0000309F* + ID_PRODUCT_FROM_DATABASE=Compaq nx9420 Notebook + +pci:v00008086d000027A1sv0000103Csd000030A3* + ID_PRODUCT_FROM_DATABASE=Compaq nw8440 + +pci:v00008086d000027A2* + ID_PRODUCT_FROM_DATABASE=Mobile 945GM/GMS, 943/940GML Express Integrated Graphics Controller + +pci:v00008086d000027A2sv0000103Csd000030A1* + ID_PRODUCT_FROM_DATABASE=NC2400 + +pci:v00008086d000027A2sv000017AAsd0000201A* + ID_PRODUCT_FROM_DATABASE=ThinkPad T60/R60 series + +pci:v00008086d000027A2sv00009902sd00001584* + ID_PRODUCT_FROM_DATABASE=CCE MPL-D10H120F + +pci:v00008086d000027A6* + ID_PRODUCT_FROM_DATABASE=Mobile 945GM/GMS/GME, 943/940GML Express Integrated Graphics Controller + +pci:v00008086d000027A6sv0000103Csd000030A1* + ID_PRODUCT_FROM_DATABASE=NC2400 + +pci:v00008086d000027A6sv00001775sd000011CC* + ID_PRODUCT_FROM_DATABASE=CC11/CL11 integrated graphics (secondary) + +pci:v00008086d000027A6sv000017AAsd0000201A* + ID_PRODUCT_FROM_DATABASE=ThinkPad T60/R60 series + +pci:v00008086d000027AC* + ID_PRODUCT_FROM_DATABASE=Mobile 945GSE Express Memory Controller Hub + +pci:v00008086d000027ACsv00001775sd000011CC* + ID_PRODUCT_FROM_DATABASE=CC11/CL11 + +pci:v00008086d000027AD* + ID_PRODUCT_FROM_DATABASE=Mobile 945GSE Express PCI Express Root Port + +pci:v00008086d000027AE* + ID_PRODUCT_FROM_DATABASE=Mobile 945GSE Express Integrated Graphics Controller + +pci:v00008086d000027AEsv00001775sd000011CC* + ID_PRODUCT_FROM_DATABASE=CC11/CL11 integrated graphics (primary) + +pci:v00008086d000027B0* + ID_PRODUCT_FROM_DATABASE=82801GH (ICH7DH) LPC Interface Bridge + +pci:v00008086d000027B0sv0000103Csd00002A3B* + ID_PRODUCT_FROM_DATABASE=Pavilion A1512X + +pci:v00008086d000027B0sv00008086sd0000544E* + ID_PRODUCT_FROM_DATABASE=DeskTop Board D945GTP + +pci:v00008086d000027B8* + ID_PRODUCT_FROM_DATABASE=82801GB/GR (ICH7 Family) LPC Interface Bridge + +pci:v00008086d000027B8sv00001028sd000001E6* + ID_PRODUCT_FROM_DATABASE=PowerEdge 860 + +pci:v00008086d000027B8sv00001043sd00008179* + ID_PRODUCT_FROM_DATABASE=P5KPL-VM Motherboard + +pci:v00008086d000027B8sv0000107Bsd00005048* + ID_PRODUCT_FROM_DATABASE=E4500 + +pci:v00008086d000027B8sv00001775sd000011CC* + ID_PRODUCT_FROM_DATABASE=CC11/CL11 + +pci:v00008086d000027B8sv00008086sd0000544E* + ID_PRODUCT_FROM_DATABASE=DeskTop Board D945GTP + +pci:v00008086d000027B9* + ID_PRODUCT_FROM_DATABASE=82801GBM (ICH7-M) LPC Interface Bridge + +pci:v00008086d000027B9sv00001028sd000001D7* + ID_PRODUCT_FROM_DATABASE=XPS M1210 + +pci:v00008086d000027B9sv0000103Csd0000309F* + ID_PRODUCT_FROM_DATABASE=Compaq nx9420 Notebook + +pci:v00008086d000027B9sv0000103Csd000030A1* + ID_PRODUCT_FROM_DATABASE=NC2400 + +pci:v00008086d000027B9sv0000103Csd000030A3* + ID_PRODUCT_FROM_DATABASE=Compaq nw8440 + +pci:v00008086d000027B9sv000010F7sd00008338* + ID_PRODUCT_FROM_DATABASE=Panasonic CF-Y5 laptop + +pci:v00008086d000027B9sv000017AAsd00002009* + ID_PRODUCT_FROM_DATABASE=ThinkPad T60/R60 series + +pci:v00008086d000027BC* + ID_PRODUCT_FROM_DATABASE=NM10 Family LPC Controller + +pci:v00008086d000027BCsv0000144Dsd0000C072* + ID_PRODUCT_FROM_DATABASE=Notebook N150P + +pci:v00008086d000027BCsv00008086sd00004F4D* + ID_PRODUCT_FROM_DATABASE=DeskTop Board D510MO + +pci:v00008086d000027BD* + ID_PRODUCT_FROM_DATABASE=82801GHM (ICH7-M DH) LPC Interface Bridge + +pci:v00008086d000027BDsv00001025sd0000006C* + ID_PRODUCT_FROM_DATABASE=9814 WKMI + +pci:v00008086d000027C0* + ID_PRODUCT_FROM_DATABASE=NM10/ICH7 Family SATA Controller [IDE mode] + +pci:v00008086d000027C0sv00001028sd000001AD* + ID_PRODUCT_FROM_DATABASE=OptiPlex GX620 + +pci:v00008086d000027C0sv00001028sd000001DF* + ID_PRODUCT_FROM_DATABASE=PowerEdge SC440 + +pci:v00008086d000027C0sv00001028sd000001E6* + ID_PRODUCT_FROM_DATABASE=PowerEdge 860 + +pci:v00008086d000027C0sv00001043sd00008179* + ID_PRODUCT_FROM_DATABASE=P5KPL-VM Motherboard + +pci:v00008086d000027C0sv0000107Bsd00005048* + ID_PRODUCT_FROM_DATABASE=E4500 + +pci:v00008086d000027C0sv00001462sd00002310* + ID_PRODUCT_FROM_DATABASE=MSI Hetis 945 + +pci:v00008086d000027C0sv00001462sd00007236* + ID_PRODUCT_FROM_DATABASE=945P Neo3-F Rev. 2.2 motherboard + +pci:v00008086d000027C0sv00001775sd000011CC* + ID_PRODUCT_FROM_DATABASE=CC11/CL11 + +pci:v00008086d000027C0sv00008086sd0000544E* + ID_PRODUCT_FROM_DATABASE=DeskTop Board D945GTP + +pci:v00008086d000027C1* + ID_PRODUCT_FROM_DATABASE=NM10/ICH7 Family SATA Controller [AHCI mode] + +pci:v00008086d000027C1sv00001028sd000001DF* + ID_PRODUCT_FROM_DATABASE=PowerEdge SC440 + +pci:v00008086d000027C1sv0000103Csd00002A3B* + ID_PRODUCT_FROM_DATABASE=Pavilion A1512X + +pci:v00008086d000027C1sv0000144Dsd0000C072* + ID_PRODUCT_FROM_DATABASE=Notebook N150P + +pci:v00008086d000027C1sv00001775sd000011CC* + ID_PRODUCT_FROM_DATABASE=CC11/CL11 + +pci:v00008086d000027C1sv00008086sd00004F4D* + ID_PRODUCT_FROM_DATABASE=DeskTop Board D510MO + +pci:v00008086d000027C1sv00008086sd00005842* + ID_PRODUCT_FROM_DATABASE=DeskTop Board D975XBX + +pci:v00008086d000027C3* + ID_PRODUCT_FROM_DATABASE=82801GR/GDH (ICH7R/ICH7DH) SATA Controller [RAID mode] + +pci:v00008086d000027C3sv00001775sd000011CC* + ID_PRODUCT_FROM_DATABASE=CC11/CL11 + +pci:v00008086d000027C3sv00008086sd0000544E* + ID_PRODUCT_FROM_DATABASE=DeskTop Board D945GTP + +pci:v00008086d000027C4* + ID_PRODUCT_FROM_DATABASE=82801GBM/GHM (ICH7-M Family) SATA Controller [IDE mode] + +pci:v00008086d000027C4sv00001025sd0000006C* + ID_PRODUCT_FROM_DATABASE=9814 WKMI + +pci:v00008086d000027C4sv00001028sd000001D7* + ID_PRODUCT_FROM_DATABASE=XPS M1210 + +pci:v00008086d000027C4sv000017AAsd0000200E* + ID_PRODUCT_FROM_DATABASE=Thinkpad T60 model 2007 + +pci:v00008086d000027C5* + ID_PRODUCT_FROM_DATABASE=82801GBM/GHM (ICH7-M Family) SATA Controller [AHCI mode] + +pci:v00008086d000027C5sv0000103Csd0000309F* + ID_PRODUCT_FROM_DATABASE=Compaq nx9420 Notebook + +pci:v00008086d000027C5sv0000103Csd000030A3* + ID_PRODUCT_FROM_DATABASE=Compaq nw8440 + +pci:v00008086d000027C5sv000017AAsd0000200D* + ID_PRODUCT_FROM_DATABASE=ThinkPad T60/R60 series + +pci:v00008086d000027C6* + ID_PRODUCT_FROM_DATABASE=82801GHM (ICH7-M DH) SATA Controller [RAID mode] + +pci:v00008086d000027C8* + ID_PRODUCT_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #1 + +pci:v00008086d000027C8sv00001025sd0000006C* + ID_PRODUCT_FROM_DATABASE=9814 WKMI + +pci:v00008086d000027C8sv00001028sd000001AD* + ID_PRODUCT_FROM_DATABASE=OptiPlex GX620 + +pci:v00008086d000027C8sv00001028sd000001D7* + ID_PRODUCT_FROM_DATABASE=XPS M1210 + +pci:v00008086d000027C8sv00001028sd000001DF* + ID_PRODUCT_FROM_DATABASE=PowerEdge SC440 + +pci:v00008086d000027C8sv00001028sd000001E6* + ID_PRODUCT_FROM_DATABASE=PowerEdge 860 + +pci:v00008086d000027C8sv0000103Csd00002A3B* + ID_PRODUCT_FROM_DATABASE=Pavilion A1512X + +pci:v00008086d000027C8sv0000103Csd0000309F* + ID_PRODUCT_FROM_DATABASE=Compaq nx9420 Notebook + +pci:v00008086d000027C8sv0000103Csd000030A1* + ID_PRODUCT_FROM_DATABASE=NC2400 + +pci:v00008086d000027C8sv0000103Csd000030A3* + ID_PRODUCT_FROM_DATABASE=Compaq nw8440 + +pci:v00008086d000027C8sv00001043sd00001237* + ID_PRODUCT_FROM_DATABASE=A6J-Q008 + +pci:v00008086d000027C8sv00001043sd00008179* + ID_PRODUCT_FROM_DATABASE=P5KPL-VM,P5LD2-VM Mainboard + +pci:v00008086d000027C8sv0000107Bsd00005048* + ID_PRODUCT_FROM_DATABASE=E4500 + +pci:v00008086d000027C8sv0000144Dsd0000C072* + ID_PRODUCT_FROM_DATABASE=Notebook N150P + +pci:v00008086d000027C8sv00001775sd000011CC* + ID_PRODUCT_FROM_DATABASE=CC11/CL11 + +pci:v00008086d000027C8sv000017AAsd0000200A* + ID_PRODUCT_FROM_DATABASE=ThinkPad T60/R60 series + +pci:v00008086d000027C8sv00008086sd00004F4D* + ID_PRODUCT_FROM_DATABASE=DeskTop Board D510MO + +pci:v00008086d000027C8sv00008086sd0000544E* + ID_PRODUCT_FROM_DATABASE=DeskTop Board D945GTP + +pci:v00008086d000027C9* + ID_PRODUCT_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #2 + +pci:v00008086d000027C9sv00001025sd0000006C* + ID_PRODUCT_FROM_DATABASE=9814 WKMI + +pci:v00008086d000027C9sv00001028sd000001AD* + ID_PRODUCT_FROM_DATABASE=OptiPlex GX620 + +pci:v00008086d000027C9sv00001028sd000001D7* + ID_PRODUCT_FROM_DATABASE=XPS M1210 + +pci:v00008086d000027C9sv00001028sd000001DF* + ID_PRODUCT_FROM_DATABASE=PowerEdge SC440 + +pci:v00008086d000027C9sv00001028sd000001E6* + ID_PRODUCT_FROM_DATABASE=PowerEdge 860 + +pci:v00008086d000027C9sv0000103Csd00002A3B* + ID_PRODUCT_FROM_DATABASE=Pavilion A1512X + +pci:v00008086d000027C9sv0000103Csd0000309F* + ID_PRODUCT_FROM_DATABASE=Compaq nx9420 Notebook + +pci:v00008086d000027C9sv0000103Csd000030A1* + ID_PRODUCT_FROM_DATABASE=NC2400 + +pci:v00008086d000027C9sv0000103Csd000030A3* + ID_PRODUCT_FROM_DATABASE=Compaq nw8440 + +pci:v00008086d000027C9sv00001043sd00001237* + ID_PRODUCT_FROM_DATABASE=A6J-Q008 + +pci:v00008086d000027C9sv00001043sd00008179* + ID_PRODUCT_FROM_DATABASE=P5KPL-VM,P5LD2-VM Mainboard + +pci:v00008086d000027C9sv0000107Bsd00005048* + ID_PRODUCT_FROM_DATABASE=E4500 + +pci:v00008086d000027C9sv0000144Dsd0000C072* + ID_PRODUCT_FROM_DATABASE=Notebook N150P + +pci:v00008086d000027C9sv00001775sd000011CC* + ID_PRODUCT_FROM_DATABASE=CC11/CL11 + +pci:v00008086d000027C9sv000017AAsd0000200A* + ID_PRODUCT_FROM_DATABASE=ThinkPad T60/R60 series + +pci:v00008086d000027C9sv00008086sd00004F4D* + ID_PRODUCT_FROM_DATABASE=DeskTop Board D510MO + +pci:v00008086d000027C9sv00008086sd0000544E* + ID_PRODUCT_FROM_DATABASE=DeskTop Board D945GTP + +pci:v00008086d000027CA* + ID_PRODUCT_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #3 + +pci:v00008086d000027CAsv00001025sd0000006C* + ID_PRODUCT_FROM_DATABASE=9814 WKMI + +pci:v00008086d000027CAsv00001028sd000001AD* + ID_PRODUCT_FROM_DATABASE=OptiPlex GX620 + +pci:v00008086d000027CAsv00001028sd000001D7* + ID_PRODUCT_FROM_DATABASE=XPS M1210 + +pci:v00008086d000027CAsv00001028sd000001DF* + ID_PRODUCT_FROM_DATABASE=PowerEdge SC440 + +pci:v00008086d000027CAsv00001028sd000001E6* + ID_PRODUCT_FROM_DATABASE=PowerEdge 860 + +pci:v00008086d000027CAsv0000103Csd00002A3B* + ID_PRODUCT_FROM_DATABASE=Pavilion A1512X + +pci:v00008086d000027CAsv0000103Csd0000309F* + ID_PRODUCT_FROM_DATABASE=Compaq nx9420 Notebook + +pci:v00008086d000027CAsv0000103Csd000030A1* + ID_PRODUCT_FROM_DATABASE=NC2400 + +pci:v00008086d000027CAsv0000103Csd000030A3* + ID_PRODUCT_FROM_DATABASE=Compaq nw8440 + +pci:v00008086d000027CAsv00001043sd00001237* + ID_PRODUCT_FROM_DATABASE=A6J-Q008 + +pci:v00008086d000027CAsv00001043sd00008179* + ID_PRODUCT_FROM_DATABASE=P5KPL-VM,P5LD2-VM Mainboard + +pci:v00008086d000027CAsv0000107Bsd00005048* + ID_PRODUCT_FROM_DATABASE=E4500 + +pci:v00008086d000027CAsv0000144Dsd0000C072* + ID_PRODUCT_FROM_DATABASE=Notebook N150P + +pci:v00008086d000027CAsv00001775sd000011CC* + ID_PRODUCT_FROM_DATABASE=CC11/CL11 + +pci:v00008086d000027CAsv000017AAsd0000200A* + ID_PRODUCT_FROM_DATABASE=ThinkPad T60/R60 series + +pci:v00008086d000027CAsv00008086sd00004F4D* + ID_PRODUCT_FROM_DATABASE=DeskTop Board D510MO + +pci:v00008086d000027CAsv00008086sd0000544E* + ID_PRODUCT_FROM_DATABASE=DeskTop Board D945GTP + +pci:v00008086d000027CB* + ID_PRODUCT_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #4 + +pci:v00008086d000027CBsv00001025sd0000006C* + ID_PRODUCT_FROM_DATABASE=9814 WKMI + +pci:v00008086d000027CBsv00001028sd000001AD* + ID_PRODUCT_FROM_DATABASE=OptiPlex GX620 + +pci:v00008086d000027CBsv00001028sd000001D7* + ID_PRODUCT_FROM_DATABASE=XPS M1210 + +pci:v00008086d000027CBsv00001028sd000001DF* + ID_PRODUCT_FROM_DATABASE=PowerEdge SC440 + +pci:v00008086d000027CBsv0000103Csd00002A3B* + ID_PRODUCT_FROM_DATABASE=Pavilion A1512X + +pci:v00008086d000027CBsv0000103Csd0000309F* + ID_PRODUCT_FROM_DATABASE=Compaq nx9420 Notebook + +pci:v00008086d000027CBsv0000103Csd000030A1* + ID_PRODUCT_FROM_DATABASE=NC2400 + +pci:v00008086d000027CBsv0000103Csd000030A3* + ID_PRODUCT_FROM_DATABASE=Compaq nw8440 + +pci:v00008086d000027CBsv00001043sd00001237* + ID_PRODUCT_FROM_DATABASE=A6J-Q008 + +pci:v00008086d000027CBsv00001043sd00008179* + ID_PRODUCT_FROM_DATABASE=P5KPL-VM,P5LD2-VM Mainboard + +pci:v00008086d000027CBsv0000107Bsd00005048* + ID_PRODUCT_FROM_DATABASE=E4500 + +pci:v00008086d000027CBsv0000144Dsd0000C072* + ID_PRODUCT_FROM_DATABASE=Notebook N150P + +pci:v00008086d000027CBsv00001775sd000011CC* + ID_PRODUCT_FROM_DATABASE=CC11/CL11 + +pci:v00008086d000027CBsv000017AAsd0000200A* + ID_PRODUCT_FROM_DATABASE=ThinkPad T60/R60 series + +pci:v00008086d000027CBsv00008086sd00004F4D* + ID_PRODUCT_FROM_DATABASE=DeskTop Board D510MO + +pci:v00008086d000027CBsv00008086sd0000544E* + ID_PRODUCT_FROM_DATABASE=DeskTop Board D945GTP + +pci:v00008086d000027CC* + ID_PRODUCT_FROM_DATABASE=NM10/ICH7 Family USB2 EHCI Controller + +pci:v00008086d000027CCsv00001025sd0000006C* + ID_PRODUCT_FROM_DATABASE=9814 WKMI + +pci:v00008086d000027CCsv00001028sd000001AD* + ID_PRODUCT_FROM_DATABASE=OptiPlex GX620 + +pci:v00008086d000027CCsv00001028sd000001D7* + ID_PRODUCT_FROM_DATABASE=XPS M1210 + +pci:v00008086d000027CCsv00001028sd000001DF* + ID_PRODUCT_FROM_DATABASE=PowerEdge SC440 + +pci:v00008086d000027CCsv00001028sd000001E6* + ID_PRODUCT_FROM_DATABASE=PowerEdge 860 + +pci:v00008086d000027CCsv0000103Csd00002A3B* + ID_PRODUCT_FROM_DATABASE=Pavilion A1512X + +pci:v00008086d000027CCsv0000103Csd0000309F* + ID_PRODUCT_FROM_DATABASE=Compaq nx9420 Notebook + +pci:v00008086d000027CCsv0000103Csd000030A1* + ID_PRODUCT_FROM_DATABASE=NC2400 + +pci:v00008086d000027CCsv0000103Csd000030A3* + ID_PRODUCT_FROM_DATABASE=Compaq nw8440 + +pci:v00008086d000027CCsv00001043sd00001237* + ID_PRODUCT_FROM_DATABASE=A6J-Q008 + +pci:v00008086d000027CCsv00001043sd00008179* + ID_PRODUCT_FROM_DATABASE=P5KPL-VM,P5LD2-VM Mainboard + +pci:v00008086d000027CCsv0000144Dsd0000C072* + ID_PRODUCT_FROM_DATABASE=Notebook N150P + +pci:v00008086d000027CCsv00001775sd000011CC* + ID_PRODUCT_FROM_DATABASE=CC11/CL11 + +pci:v00008086d000027CCsv000017AAsd0000200B* + ID_PRODUCT_FROM_DATABASE=ThinkPad T60/R60 series + +pci:v00008086d000027CCsv00008086sd00004F4D* + ID_PRODUCT_FROM_DATABASE=DeskTop Board D510MO + +pci:v00008086d000027CCsv00008086sd0000544E* + ID_PRODUCT_FROM_DATABASE=DeskTop Board D945GTP + +pci:v00008086d000027D0* + ID_PRODUCT_FROM_DATABASE=NM10/ICH7 Family PCI Express Port 1 + +pci:v00008086d000027D0sv0000103Csd0000309F* + ID_PRODUCT_FROM_DATABASE=Compaq nx9420 Notebook + +pci:v00008086d000027D0sv0000103Csd000030A3* + ID_PRODUCT_FROM_DATABASE=Compaq nw8440 + +pci:v00008086d000027D0sv0000144Dsd0000C072* + ID_PRODUCT_FROM_DATABASE=Notebook N150P + +pci:v00008086d000027D0sv00001775sd000011CC* + ID_PRODUCT_FROM_DATABASE=CC11/CL11 + +pci:v00008086d000027D2* + ID_PRODUCT_FROM_DATABASE=NM10/ICH7 Family PCI Express Port 2 + +pci:v00008086d000027D2sv0000103Csd0000309F* + ID_PRODUCT_FROM_DATABASE=Compaq nx9420 Notebook + +pci:v00008086d000027D2sv0000103Csd000030A3* + ID_PRODUCT_FROM_DATABASE=Compaq nw8440 + +pci:v00008086d000027D2sv0000144Dsd0000C072* + ID_PRODUCT_FROM_DATABASE=Notebook N150P + +pci:v00008086d000027D2sv00001775sd000011CC* + ID_PRODUCT_FROM_DATABASE=CC11/CL11 + +pci:v00008086d000027D4* + ID_PRODUCT_FROM_DATABASE=NM10/ICH7 Family PCI Express Port 3 + +pci:v00008086d000027D4sv0000144Dsd0000C072* + ID_PRODUCT_FROM_DATABASE=Notebook N150P + +pci:v00008086d000027D4sv00001775sd000011CC* + ID_PRODUCT_FROM_DATABASE=CC11/CL11 + +pci:v00008086d000027D6* + ID_PRODUCT_FROM_DATABASE=NM10/ICH7 Family PCI Express Port 4 + +pci:v00008086d000027D6sv0000103Csd000030A3* + ID_PRODUCT_FROM_DATABASE=Compaq nw8440 + +pci:v00008086d000027D6sv0000144Dsd0000C072* + ID_PRODUCT_FROM_DATABASE=Notebook N150P + +pci:v00008086d000027D6sv00001775sd000011CC* + ID_PRODUCT_FROM_DATABASE=CC11/CL11 + +pci:v00008086d000027D8* + ID_PRODUCT_FROM_DATABASE=NM10/ICH7 Family High Definition Audio Controller + +pci:v00008086d000027D8sv00001025sd0000006C* + ID_PRODUCT_FROM_DATABASE=9814 WKMI + +pci:v00008086d000027D8sv00001028sd000001D7* + ID_PRODUCT_FROM_DATABASE=XPS M1210 + +pci:v00008086d000027D8sv0000103Csd00002A3B* + ID_PRODUCT_FROM_DATABASE=Pavilion A1512X + +pci:v00008086d000027D8sv0000103Csd0000309F* + ID_PRODUCT_FROM_DATABASE=Compaq nx9420 Notebook + +pci:v00008086d000027D8sv0000103Csd000030A1* + ID_PRODUCT_FROM_DATABASE=NC2400 + +pci:v00008086d000027D8sv0000103Csd000030A3* + ID_PRODUCT_FROM_DATABASE=Compaq nw8440 + +pci:v00008086d000027D8sv00001043sd00001123* + ID_PRODUCT_FROM_DATABASE=A6J-Q008 + +pci:v00008086d000027D8sv00001043sd000013C4* + ID_PRODUCT_FROM_DATABASE=Asus G2P + +pci:v00008086d000027D8sv00001043sd0000817F* + ID_PRODUCT_FROM_DATABASE=P5LD2-VM Mainboard (Realtek ALC 882 codec) + +pci:v00008086d000027D8sv00001043sd00008290* + ID_PRODUCT_FROM_DATABASE=P5KPL-VM Motherboard + +pci:v00008086d000027D8sv00001043sd000082EA* + ID_PRODUCT_FROM_DATABASE=P5KPL-CM Motherboard + +pci:v00008086d000027D8sv0000107Bsd00005048* + ID_PRODUCT_FROM_DATABASE=E4500 + +pci:v00008086d000027D8sv000010F7sd00008338* + ID_PRODUCT_FROM_DATABASE=Panasonic CF-Y5 laptop + +pci:v00008086d000027D8sv00001179sd0000FF10* + ID_PRODUCT_FROM_DATABASE=Toshiba Satellite A100-796 audio (Realtek ALC861) + +pci:v00008086d000027D8sv00001179sd0000FF31* + ID_PRODUCT_FROM_DATABASE=AC97 Data Fax SoftModem with SmartCP + +pci:v00008086d000027D8sv00001447sd00001043* + ID_PRODUCT_FROM_DATABASE=Asus A8JP (Analog Devices AD1986A) + +pci:v00008086d000027D8sv0000144Dsd0000C072* + ID_PRODUCT_FROM_DATABASE=Notebook N150P + +pci:v00008086d000027D8sv00001458sd0000A102* + ID_PRODUCT_FROM_DATABASE=GA-8I945PG-RH Mainboard + +pci:v00008086d000027D8sv0000152Dsd00000753* + ID_PRODUCT_FROM_DATABASE=Softmodem + +pci:v00008086d000027D8sv00001734sd000010AD* + ID_PRODUCT_FROM_DATABASE=Conexant softmodem SmartCP + +pci:v00008086d000027D8sv000017AAsd00002010* + ID_PRODUCT_FROM_DATABASE=ThinkPad T60/R60 series + +pci:v00008086d000027D8sv000017AAsd00003802* + ID_PRODUCT_FROM_DATABASE=Lenovo 3000 C200 audio [Realtek ALC861VD] + +pci:v00008086d000027D8sv00008086sd00001112* + ID_PRODUCT_FROM_DATABASE=DeskTop Board D945GTP + +pci:v00008086d000027D8sv00008086sd000027D8* + ID_PRODUCT_FROM_DATABASE=DeskTop Board D945GTP + +pci:v00008086d000027D8sv00008086sd0000D618* + ID_PRODUCT_FROM_DATABASE=DeskTop Board D510MO + +pci:v00008086d000027D8sv00008384sd00007680* + ID_PRODUCT_FROM_DATABASE=STAC9221 HD Audio Codec + +pci:v00008086d000027DA* + ID_PRODUCT_FROM_DATABASE=NM10/ICH7 Family SMBus Controller + +pci:v00008086d000027DAsv00001025sd0000006C* + ID_PRODUCT_FROM_DATABASE=9814 WKMI + +pci:v00008086d000027DAsv00001028sd000001AD* + ID_PRODUCT_FROM_DATABASE=OptiPlex GX620 + +pci:v00008086d000027DAsv00001028sd000001D7* + ID_PRODUCT_FROM_DATABASE=XPS M1210 + +pci:v00008086d000027DAsv00001028sd000001DF* + ID_PRODUCT_FROM_DATABASE=PowerEdge SC440 + +pci:v00008086d000027DAsv00001028sd000001E6* + ID_PRODUCT_FROM_DATABASE=PowerEdge 860 + +pci:v00008086d000027DAsv0000103Csd00002A3B* + ID_PRODUCT_FROM_DATABASE=Pavilion A1512X + +pci:v00008086d000027DAsv00001043sd00008179* + ID_PRODUCT_FROM_DATABASE=P5KPL-VM Motherboard + +pci:v00008086d000027DAsv000010F7sd00008338* + ID_PRODUCT_FROM_DATABASE=Panasonic CF-Y5 laptop + +pci:v00008086d000027DAsv0000144Dsd0000C072* + ID_PRODUCT_FROM_DATABASE=Notebook N150P + +pci:v00008086d000027DAsv00001458sd00005001* + ID_PRODUCT_FROM_DATABASE=GA-8I945PG-RH Mainboard + +pci:v00008086d000027DAsv00001775sd000011CC* + ID_PRODUCT_FROM_DATABASE=CC11/CL11 + +pci:v00008086d000027DAsv000017AAsd0000200F* + ID_PRODUCT_FROM_DATABASE=ThinkPad T60/R60 series + +pci:v00008086d000027DAsv00008086sd00004F4D* + ID_PRODUCT_FROM_DATABASE=DeskTop Board D510MO + +pci:v00008086d000027DAsv00008086sd0000544E* + ID_PRODUCT_FROM_DATABASE=DeskTop Board D945GTP + +pci:v00008086d000027DAsv00008086sd00005842* + ID_PRODUCT_FROM_DATABASE=DeskTop Board D975XBX + +pci:v00008086d000027DC* + ID_PRODUCT_FROM_DATABASE=NM10/ICH7 Family LAN Controller + +pci:v00008086d000027DCsv0000103Csd00002A3B* + ID_PRODUCT_FROM_DATABASE=Pavilion A1512X + +pci:v00008086d000027DCsv00008086sd0000308D* + ID_PRODUCT_FROM_DATABASE=DeskTop Board D945GTP + +pci:v00008086d000027DD* + ID_PRODUCT_FROM_DATABASE=82801G (ICH7 Family) AC'97 Modem Controller + +pci:v00008086d000027DE* + ID_PRODUCT_FROM_DATABASE=82801G (ICH7 Family) AC'97 Audio Controller + +pci:v00008086d000027DEsv00001028sd000001AD* + ID_PRODUCT_FROM_DATABASE=OptiPlex GX620 + +pci:v00008086d000027DEsv00001462sd00007267* + ID_PRODUCT_FROM_DATABASE=Realtek ALC883 Audio Controller + +pci:v00008086d000027DEsv00001775sd000011CC* + ID_PRODUCT_FROM_DATABASE=CC11 integrated audio (AD1981BL codec) + +pci:v00008086d000027DF* + ID_PRODUCT_FROM_DATABASE=82801G (ICH7 Family) IDE Controller + +pci:v00008086d000027DFsv00001028sd000001DF* + ID_PRODUCT_FROM_DATABASE=PowerEdge SC440 + +pci:v00008086d000027DFsv00001028sd000001E6* + ID_PRODUCT_FROM_DATABASE=PowerEdge 860 + +pci:v00008086d000027DFsv0000103Csd00002A3B* + ID_PRODUCT_FROM_DATABASE=Pavilion A1512X + +pci:v00008086d000027DFsv0000103Csd0000309F* + ID_PRODUCT_FROM_DATABASE=Compaq nx9420 Notebook + +pci:v00008086d000027DFsv0000103Csd000030A1* + ID_PRODUCT_FROM_DATABASE=NC2400 + +pci:v00008086d000027DFsv0000103Csd000030A3* + ID_PRODUCT_FROM_DATABASE=Compaq nw8440 + +pci:v00008086d000027DFsv00001043sd00001237* + ID_PRODUCT_FROM_DATABASE=A6J-Q008 + +pci:v00008086d000027DFsv00001043sd00008179* + ID_PRODUCT_FROM_DATABASE=P5KPL-VM Motherboard + +pci:v00008086d000027DFsv0000107Bsd00005048* + ID_PRODUCT_FROM_DATABASE=E4500 + +pci:v00008086d000027DFsv000010F7sd00008338* + ID_PRODUCT_FROM_DATABASE=Panasonic CF-Y5 laptop + +pci:v00008086d000027DFsv00001775sd000011CC* + ID_PRODUCT_FROM_DATABASE=CC11/CL11 + +pci:v00008086d000027DFsv000017AAsd0000200C* + ID_PRODUCT_FROM_DATABASE=ThinkPad T60/R60 series + +pci:v00008086d000027DFsv00008086sd0000544E* + ID_PRODUCT_FROM_DATABASE=DeskTop Board D945GTP + +pci:v00008086d000027E0* + ID_PRODUCT_FROM_DATABASE=82801GR/GH/GHM (ICH7 Family) PCI Express Port 5 + +pci:v00008086d000027E0sv00001775sd000011CC* + ID_PRODUCT_FROM_DATABASE=CC11/CL11 + +pci:v00008086d000027E2* + ID_PRODUCT_FROM_DATABASE=82801GR/GH/GHM (ICH7 Family) PCI Express Port 6 + +pci:v00008086d000027E2sv00001775sd000011CC* + ID_PRODUCT_FROM_DATABASE=CC11/CL11 + +pci:v00008086d00002802* + ID_PRODUCT_FROM_DATABASE=82GL40 [Cantiga] High Definition Audio HDMI Service + +pci:v00008086d00002810* + ID_PRODUCT_FROM_DATABASE=82801HB/HR (ICH8/R) LPC Interface Controller + +pci:v00008086d00002810sv00001043sd000081EC* + ID_PRODUCT_FROM_DATABASE=P5B + +pci:v00008086d00002811* + ID_PRODUCT_FROM_DATABASE=82801HEM (ICH8M-E) LPC Interface Controller + +pci:v00008086d00002811sv0000103Csd000030C1* + ID_PRODUCT_FROM_DATABASE=Compaq 6910p + +pci:v00008086d00002811sv000017AAsd000020B6* + ID_PRODUCT_FROM_DATABASE=T61 + +pci:v00008086d00002811sv0000E4BFsd0000CC47* + ID_PRODUCT_FROM_DATABASE=CCG-RUMBA + +pci:v00008086d00002812* + ID_PRODUCT_FROM_DATABASE=82801HH (ICH8DH) LPC Interface Controller + +pci:v00008086d00002814* + ID_PRODUCT_FROM_DATABASE=82801HO (ICH8DO) LPC Interface Controller + +pci:v00008086d00002815* + ID_PRODUCT_FROM_DATABASE=82801HM (ICH8M) LPC Interface Controller + +pci:v00008086d00002815sv00001025sd00000121* + ID_PRODUCT_FROM_DATABASE=Aspire 5920G + +pci:v00008086d00002815sv00001028sd000001F3* + ID_PRODUCT_FROM_DATABASE=Inspiron 1420 + +pci:v00008086d00002815sv0000103Csd000030C0* + ID_PRODUCT_FROM_DATABASE=Compaq 6710b + +pci:v00008086d00002815sv0000103Csd000030CC* + ID_PRODUCT_FROM_DATABASE=Pavilion dv6700 + +pci:v00008086d00002815sv0000103Csd000030D9* + ID_PRODUCT_FROM_DATABASE=Presario C700 + +pci:v00008086d00002815sv0000104Dsd00009005* + ID_PRODUCT_FROM_DATABASE=Vaio VGN-FZ260E + +pci:v00008086d00002815sv0000104Dsd0000902D* + ID_PRODUCT_FROM_DATABASE=VAIO VGN-NR120E + +pci:v00008086d00002820* + ID_PRODUCT_FROM_DATABASE=82801H (ICH8 Family) 4 port SATA Controller [IDE mode] + +pci:v00008086d00002820sv00001028sd000001DA* + ID_PRODUCT_FROM_DATABASE=OptiPlex 745 + +pci:v00008086d00002820sv00001462sd00007235* + ID_PRODUCT_FROM_DATABASE=P965 Neo MS-7235 mainboard + +pci:v00008086d00002821* + ID_PRODUCT_FROM_DATABASE=82801HR/HO/HH (ICH8R/DO/DH) 6 port SATA Controller [AHCI mode] + +pci:v00008086d00002822* + ID_PRODUCT_FROM_DATABASE=82801 SATA Controller [RAID mode] + +pci:v00008086d00002822sv00001028sd0000020D* + ID_PRODUCT_FROM_DATABASE=Inspiron 530 + +pci:v00008086d00002823* + ID_PRODUCT_FROM_DATABASE=Wellsburg sSATA RAID Controller + +pci:v00008086d00002824* + ID_PRODUCT_FROM_DATABASE=82801HB (ICH8) 4 port SATA Controller [AHCI mode] + +pci:v00008086d00002824sv00001043sd000081EC* + ID_PRODUCT_FROM_DATABASE=P5B + +pci:v00008086d00002825* + ID_PRODUCT_FROM_DATABASE=82801HR/HO/HH (ICH8R/DO/DH) 2 port SATA Controller [IDE mode] + +pci:v00008086d00002825sv00001028sd000001DA* + ID_PRODUCT_FROM_DATABASE=OptiPlex 745 + +pci:v00008086d00002825sv00001462sd00007235* + ID_PRODUCT_FROM_DATABASE=P965 Neo MS-7235 mainboard + +pci:v00008086d00002826* + ID_PRODUCT_FROM_DATABASE=C600/X79 series chipset SATA RAID Controller + +pci:v00008086d00002827* + ID_PRODUCT_FROM_DATABASE=Wellsburg sSATA RAID Controller + +pci:v00008086d00002828* + ID_PRODUCT_FROM_DATABASE=82801HM/HEM (ICH8M/ICH8M-E) SATA Controller [IDE mode] + +pci:v00008086d00002828sv00001028sd000001F3* + ID_PRODUCT_FROM_DATABASE=Inspiron 1420 + +pci:v00008086d00002828sv0000103Csd000030C0* + ID_PRODUCT_FROM_DATABASE=Compaq 6710b + +pci:v00008086d00002828sv0000E4BFsd0000CC47* + ID_PRODUCT_FROM_DATABASE=CCG-RUMBA + +pci:v00008086d00002829* + ID_PRODUCT_FROM_DATABASE=82801HM/HEM (ICH8M/ICH8M-E) SATA Controller [AHCI mode] + +pci:v00008086d00002829sv00001025sd00000121* + ID_PRODUCT_FROM_DATABASE=Aspire 5920G + +pci:v00008086d00002829sv0000103Csd000030C0* + ID_PRODUCT_FROM_DATABASE=Compaq 6710b + +pci:v00008086d00002829sv0000103Csd000030C1* + ID_PRODUCT_FROM_DATABASE=Compaq 6910p + +pci:v00008086d00002829sv0000103Csd000030CC* + ID_PRODUCT_FROM_DATABASE=Pavilion dv6700 + +pci:v00008086d00002829sv0000103Csd000030D9* + ID_PRODUCT_FROM_DATABASE=Presario C700 + +pci:v00008086d00002829sv0000104Dsd00009005* + ID_PRODUCT_FROM_DATABASE=Vaio VGN-FZ260E + +pci:v00008086d00002829sv0000104Dsd0000902D* + ID_PRODUCT_FROM_DATABASE=VAIO VGN-NR120E + +pci:v00008086d00002829sv000017AAsd000020A7* + ID_PRODUCT_FROM_DATABASE=ThinkPad T61 + +pci:v00008086d00002829sv0000E4BFsd0000CC47* + ID_PRODUCT_FROM_DATABASE=CCG-RUMBA + +pci:v00008086d0000282A* + ID_PRODUCT_FROM_DATABASE=82801 Mobile SATA Controller [RAID mode] + +pci:v00008086d0000282Asv00001028sd0000040B* + ID_PRODUCT_FROM_DATABASE=Latitude E6510 + +pci:v00008086d0000282Asv0000E4BFsd000050C1* + ID_PRODUCT_FROM_DATABASE=PC1-GROOVE + +pci:v00008086d00002830* + ID_PRODUCT_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #1 + +pci:v00008086d00002830sv00001025sd00000121* + ID_PRODUCT_FROM_DATABASE=Acer Aspire 5920G + +pci:v00008086d00002830sv00001028sd000001DA* + ID_PRODUCT_FROM_DATABASE=OptiPlex 745 + +pci:v00008086d00002830sv00001028sd000001F3* + ID_PRODUCT_FROM_DATABASE=Inspiron 1420 + +pci:v00008086d00002830sv0000103Csd000030C0* + ID_PRODUCT_FROM_DATABASE=Compaq 6710b + +pci:v00008086d00002830sv0000103Csd000030C1* + ID_PRODUCT_FROM_DATABASE=Compaq 6910p + +pci:v00008086d00002830sv0000103Csd000030CC* + ID_PRODUCT_FROM_DATABASE=Pavilion dv6700 + +pci:v00008086d00002830sv0000103Csd000030D9* + ID_PRODUCT_FROM_DATABASE=Presario C700 + +pci:v00008086d00002830sv00001043sd000081EC* + ID_PRODUCT_FROM_DATABASE=P5B + +pci:v00008086d00002830sv0000104Dsd00009005* + ID_PRODUCT_FROM_DATABASE=Vaio VGN-FZ260E + +pci:v00008086d00002830sv0000104Dsd0000902D* + ID_PRODUCT_FROM_DATABASE=VAIO VGN-NR120E + +pci:v00008086d00002830sv00001462sd00007235* + ID_PRODUCT_FROM_DATABASE=P965 Neo MS-7235 mainboard + +pci:v00008086d00002830sv000017AAsd000020AA* + ID_PRODUCT_FROM_DATABASE=ThinkPad T61 + +pci:v00008086d00002830sv0000E4BFsd0000CC47* + ID_PRODUCT_FROM_DATABASE=CCG-RUMBA + +pci:v00008086d00002831* + ID_PRODUCT_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #2 + +pci:v00008086d00002831sv00001025sd00000121* + ID_PRODUCT_FROM_DATABASE=Aspire 5920G + +pci:v00008086d00002831sv00001028sd000001DA* + ID_PRODUCT_FROM_DATABASE=OptiPlex 745 + +pci:v00008086d00002831sv00001028sd000001F3* + ID_PRODUCT_FROM_DATABASE=Inspiron 1420 + +pci:v00008086d00002831sv0000103Csd000030C0* + ID_PRODUCT_FROM_DATABASE=Compaq 6710b + +pci:v00008086d00002831sv0000103Csd000030C1* + ID_PRODUCT_FROM_DATABASE=Compaq 6910p + +pci:v00008086d00002831sv0000103Csd000030CC* + ID_PRODUCT_FROM_DATABASE=Pavilion dv6700 + +pci:v00008086d00002831sv0000103Csd000030D9* + ID_PRODUCT_FROM_DATABASE=Presario C700 + +pci:v00008086d00002831sv00001043sd000081EC* + ID_PRODUCT_FROM_DATABASE=P5B + +pci:v00008086d00002831sv0000104Dsd00009005* + ID_PRODUCT_FROM_DATABASE=Vaio VGN-FZ260E + +pci:v00008086d00002831sv0000104Dsd0000902D* + ID_PRODUCT_FROM_DATABASE=VAIO VGN-NR120E + +pci:v00008086d00002831sv00001462sd00007235* + ID_PRODUCT_FROM_DATABASE=P965 Neo MS-7235 mainboard + +pci:v00008086d00002831sv000017AAsd000020AA* + ID_PRODUCT_FROM_DATABASE=ThinkPad T61 + +pci:v00008086d00002831sv0000E4BFsd0000CC47* + ID_PRODUCT_FROM_DATABASE=CCG-RUMBA + +pci:v00008086d00002832* + ID_PRODUCT_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #3 + +pci:v00008086d00002832sv00001025sd00000121* + ID_PRODUCT_FROM_DATABASE=Aspire 5920G + +pci:v00008086d00002832sv00001028sd000001DA* + ID_PRODUCT_FROM_DATABASE=OptiPlex 745 + +pci:v00008086d00002832sv00001028sd000001F3* + ID_PRODUCT_FROM_DATABASE=Inspiron 1420 + +pci:v00008086d00002832sv0000103Csd000030C0* + ID_PRODUCT_FROM_DATABASE=Compaq 6710b + +pci:v00008086d00002832sv0000103Csd000030C1* + ID_PRODUCT_FROM_DATABASE=Compaq 6910p + +pci:v00008086d00002832sv0000103Csd000030CC* + ID_PRODUCT_FROM_DATABASE=Pavilion dv6700 + +pci:v00008086d00002832sv0000103Csd000030D9* + ID_PRODUCT_FROM_DATABASE=Presario C700 + +pci:v00008086d00002832sv00001043sd000081EC* + ID_PRODUCT_FROM_DATABASE=P5B + +pci:v00008086d00002832sv0000104Dsd00009005* + ID_PRODUCT_FROM_DATABASE=Vaio VGN-FZ260E + +pci:v00008086d00002832sv0000104Dsd0000902D* + ID_PRODUCT_FROM_DATABASE=VAIO VGN-NR120E + +pci:v00008086d00002832sv000017AAsd000020AA* + ID_PRODUCT_FROM_DATABASE=ThinkPad T61 + +pci:v00008086d00002832sv0000E4BFsd0000CC47* + ID_PRODUCT_FROM_DATABASE=CCG-RUMBA + +pci:v00008086d00002833* + ID_PRODUCT_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #4 + +pci:v00008086d00002833sv00001043sd000081EC* + ID_PRODUCT_FROM_DATABASE=P5B + +pci:v00008086d00002834* + ID_PRODUCT_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #4 + +pci:v00008086d00002834sv00001025sd00000121* + ID_PRODUCT_FROM_DATABASE=Aspire 5920G + +pci:v00008086d00002834sv00001028sd000001DA* + ID_PRODUCT_FROM_DATABASE=OptiPlex 745 + +pci:v00008086d00002834sv00001028sd000001F3* + ID_PRODUCT_FROM_DATABASE=Inspiron 1420 + +pci:v00008086d00002834sv0000103Csd000030C0* + ID_PRODUCT_FROM_DATABASE=Compaq 6710b + +pci:v00008086d00002834sv0000103Csd000030C1* + ID_PRODUCT_FROM_DATABASE=Compaq 6910p + +pci:v00008086d00002834sv0000103Csd000030CC* + ID_PRODUCT_FROM_DATABASE=Pavilion dv6700 + +pci:v00008086d00002834sv00001043sd000081EC* + ID_PRODUCT_FROM_DATABASE=P5B + +pci:v00008086d00002834sv0000104Dsd00009005* + ID_PRODUCT_FROM_DATABASE=Vaio VGN-FZ260E + +pci:v00008086d00002834sv0000104Dsd0000902D* + ID_PRODUCT_FROM_DATABASE=VAIO VGN-NR120E + +pci:v00008086d00002834sv00001462sd00007235* + ID_PRODUCT_FROM_DATABASE=P965 Neo MS-7235 mainboard + +pci:v00008086d00002834sv000017AAsd000020AA* + ID_PRODUCT_FROM_DATABASE=ThinkPad T61 + +pci:v00008086d00002834sv0000E4BFsd0000CC47* + ID_PRODUCT_FROM_DATABASE=CCG-RUMBA + +pci:v00008086d00002835* + ID_PRODUCT_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #5 + +pci:v00008086d00002835sv00001025sd00000121* + ID_PRODUCT_FROM_DATABASE=Acer Aspire 5920G + +pci:v00008086d00002835sv00001028sd000001DA* + ID_PRODUCT_FROM_DATABASE=OptiPlex 745 + +pci:v00008086d00002835sv00001028sd000001F3* + ID_PRODUCT_FROM_DATABASE=Inspiron 1420 + +pci:v00008086d00002835sv0000103Csd000030C0* + ID_PRODUCT_FROM_DATABASE=Compaq 6710b + +pci:v00008086d00002835sv0000103Csd000030C1* + ID_PRODUCT_FROM_DATABASE=Compaq 6910p + +pci:v00008086d00002835sv0000103Csd000030CC* + ID_PRODUCT_FROM_DATABASE=Pavilion dv6700 + +pci:v00008086d00002835sv00001043sd000081EC* + ID_PRODUCT_FROM_DATABASE=P5B + +pci:v00008086d00002835sv0000104Dsd00009005* + ID_PRODUCT_FROM_DATABASE=Vaio VGN-FZ260E + +pci:v00008086d00002835sv0000104Dsd0000902D* + ID_PRODUCT_FROM_DATABASE=VAIO VGN-NR120E + +pci:v00008086d00002835sv000017AAsd000020AA* + ID_PRODUCT_FROM_DATABASE=ThinkPad T60 + +pci:v00008086d00002835sv0000E4BFsd0000CC47* + ID_PRODUCT_FROM_DATABASE=CCG-RUMBA + +pci:v00008086d00002836* + ID_PRODUCT_FROM_DATABASE=82801H (ICH8 Family) USB2 EHCI Controller #1 + +pci:v00008086d00002836sv00001025sd00000121* + ID_PRODUCT_FROM_DATABASE=Aspire 5920G + +pci:v00008086d00002836sv00001028sd000001DA* + ID_PRODUCT_FROM_DATABASE=OptiPlex 745 + +pci:v00008086d00002836sv00001028sd000001F3* + ID_PRODUCT_FROM_DATABASE=Inspiron 1420 + +pci:v00008086d00002836sv0000103Csd000030C0* + ID_PRODUCT_FROM_DATABASE=Compaq 6710b + +pci:v00008086d00002836sv0000103Csd000030C1* + ID_PRODUCT_FROM_DATABASE=Compaq 6910p + +pci:v00008086d00002836sv0000103Csd000030CC* + ID_PRODUCT_FROM_DATABASE=Pavilion dv6700 + +pci:v00008086d00002836sv0000103Csd000030D9* + ID_PRODUCT_FROM_DATABASE=Presario C700 + +pci:v00008086d00002836sv00001043sd000081EC* + ID_PRODUCT_FROM_DATABASE=P5B + +pci:v00008086d00002836sv0000104Dsd00009005* + ID_PRODUCT_FROM_DATABASE=Vaio VGN-FZ260E + +pci:v00008086d00002836sv0000104Dsd0000902D* + ID_PRODUCT_FROM_DATABASE=VAIO VGN-NR120E + +pci:v00008086d00002836sv00001462sd00007235* + ID_PRODUCT_FROM_DATABASE=P965 Neo MS-7235 mainboard + +pci:v00008086d00002836sv000017AAsd000020AB* + ID_PRODUCT_FROM_DATABASE=ThinkPad T61 + +pci:v00008086d00002836sv0000E4BFsd0000CC47* + ID_PRODUCT_FROM_DATABASE=CCG-RUMBA + +pci:v00008086d0000283A* + ID_PRODUCT_FROM_DATABASE=82801H (ICH8 Family) USB2 EHCI Controller #2 + +pci:v00008086d0000283Asv00001025sd00000121* + ID_PRODUCT_FROM_DATABASE=Acer Aspire 5920G + +pci:v00008086d0000283Asv00001028sd000001DA* + ID_PRODUCT_FROM_DATABASE=OptiPlex 745 + +pci:v00008086d0000283Asv00001028sd000001F3* + ID_PRODUCT_FROM_DATABASE=Inspiron 1420 + +pci:v00008086d0000283Asv0000103Csd000030C0* + ID_PRODUCT_FROM_DATABASE=Compaq 6710b + +pci:v00008086d0000283Asv0000103Csd000030C1* + ID_PRODUCT_FROM_DATABASE=Compaq 6910p + +pci:v00008086d0000283Asv0000103Csd000030CC* + ID_PRODUCT_FROM_DATABASE=Pavilion dv6700 + +pci:v00008086d0000283Asv00001043sd000081EC* + ID_PRODUCT_FROM_DATABASE=P5B + +pci:v00008086d0000283Asv0000104Dsd00009005* + ID_PRODUCT_FROM_DATABASE=Vaio VGN-FZ260E + +pci:v00008086d0000283Asv0000104Dsd0000902D* + ID_PRODUCT_FROM_DATABASE=VAIO VGN-NR120E + +pci:v00008086d0000283Asv000017AAsd000020AB* + ID_PRODUCT_FROM_DATABASE=ThinkPad T61 + +pci:v00008086d0000283Asv0000E4BFsd0000CC47* + ID_PRODUCT_FROM_DATABASE=CCG-RUMBA + +pci:v00008086d0000283E* + ID_PRODUCT_FROM_DATABASE=82801H (ICH8 Family) SMBus Controller + +pci:v00008086d0000283Esv00001025sd00000121* + ID_PRODUCT_FROM_DATABASE=Aspire 5920G + +pci:v00008086d0000283Esv00001028sd000001DA* + ID_PRODUCT_FROM_DATABASE=OptiPlex 745 + +pci:v00008086d0000283Esv00001028sd000001F3* + ID_PRODUCT_FROM_DATABASE=Inspiron 1420 + +pci:v00008086d0000283Esv0000103Csd000030D9* + ID_PRODUCT_FROM_DATABASE=Presario C700 + +pci:v00008086d0000283Esv00001043sd000081EC* + ID_PRODUCT_FROM_DATABASE=P5B + +pci:v00008086d0000283Esv0000104Dsd00009005* + ID_PRODUCT_FROM_DATABASE=Vaio VGN-FZ260E + +pci:v00008086d0000283Esv0000104Dsd00009008* + ID_PRODUCT_FROM_DATABASE=Vaio VGN-SZ79SN_C + +pci:v00008086d0000283Esv0000104Dsd0000902D* + ID_PRODUCT_FROM_DATABASE=VAIO VGN-NR120E + +pci:v00008086d0000283Esv00001462sd00007235* + ID_PRODUCT_FROM_DATABASE=P965 Neo MS-7235 mainboard + +pci:v00008086d0000283Esv000017AAsd000020A9* + ID_PRODUCT_FROM_DATABASE=ThinkPad T61 + +pci:v00008086d0000283Esv0000E4BFsd0000CC47* + ID_PRODUCT_FROM_DATABASE=CCG-RUMBA + +pci:v00008086d0000283F* + ID_PRODUCT_FROM_DATABASE=82801H (ICH8 Family) PCI Express Port 1 + +pci:v00008086d0000283Fsv00001028sd000001DA* + ID_PRODUCT_FROM_DATABASE=OptiPlex 745 + +pci:v00008086d0000283Fsv0000103Csd000030C1* + ID_PRODUCT_FROM_DATABASE=Compaq 6910p + +pci:v00008086d0000283Fsv0000104Dsd0000902D* + ID_PRODUCT_FROM_DATABASE=VAIO VGN-NR120E + +pci:v00008086d0000283Fsv000017AAsd000020AD* + ID_PRODUCT_FROM_DATABASE=ThinkPad T61 + +pci:v00008086d00002841* + ID_PRODUCT_FROM_DATABASE=82801H (ICH8 Family) PCI Express Port 2 + +pci:v00008086d00002841sv0000103Csd000030C1* + ID_PRODUCT_FROM_DATABASE=Compaq 6910p + +pci:v00008086d00002841sv0000104Dsd0000902D* + ID_PRODUCT_FROM_DATABASE=VAIO VGN-NR120E + +pci:v00008086d00002841sv000017AAsd000020AD* + ID_PRODUCT_FROM_DATABASE=ThinkPad T61 + +pci:v00008086d00002843* + ID_PRODUCT_FROM_DATABASE=82801H (ICH8 Family) PCI Express Port 3 + +pci:v00008086d00002843sv0000104Dsd0000902D* + ID_PRODUCT_FROM_DATABASE=VAIO VGN-NR120E + +pci:v00008086d00002843sv000017AAsd000020AD* + ID_PRODUCT_FROM_DATABASE=ThinkPad T61 + +pci:v00008086d00002845* + ID_PRODUCT_FROM_DATABASE=82801H (ICH8 Family) PCI Express Port 4 + +pci:v00008086d00002845sv000017AAsd000020AD* + ID_PRODUCT_FROM_DATABASE=ThinkPad T61 + +pci:v00008086d00002847* + ID_PRODUCT_FROM_DATABASE=82801H (ICH8 Family) PCI Express Port 5 + +pci:v00008086d00002847sv00001028sd000001DA* + ID_PRODUCT_FROM_DATABASE=OptiPlex 745 + +pci:v00008086d00002847sv0000103Csd000030C1* + ID_PRODUCT_FROM_DATABASE=Compaq 6910p + +pci:v00008086d00002847sv000017AAsd000020AD* + ID_PRODUCT_FROM_DATABASE=ThinkPad T61 + +pci:v00008086d00002849* + ID_PRODUCT_FROM_DATABASE=82801H (ICH8 Family) PCI Express Port 6 + +pci:v00008086d0000284B* + ID_PRODUCT_FROM_DATABASE=82801H (ICH8 Family) HD Audio Controller + +pci:v00008086d0000284Bsv00001025sd0000011F* + ID_PRODUCT_FROM_DATABASE=Realtek ALC268 audio codec + +pci:v00008086d0000284Bsv00001025sd00000121* + ID_PRODUCT_FROM_DATABASE=Aspire 5920G + +pci:v00008086d0000284Bsv00001025sd00000145* + ID_PRODUCT_FROM_DATABASE=Realtek ALC889 (Aspire 8920G w. Dolby Theather) + +pci:v00008086d0000284Bsv00001028sd000001DA* + ID_PRODUCT_FROM_DATABASE=OptiPlex 745 + +pci:v00008086d0000284Bsv00001028sd000001F3* + ID_PRODUCT_FROM_DATABASE=Inspiron 1420 + +pci:v00008086d0000284Bsv00001028sd000001F9* + ID_PRODUCT_FROM_DATABASE=Dell Latitude D630 + +pci:v00008086d0000284Bsv00001028sd000001FF* + ID_PRODUCT_FROM_DATABASE=Dell Precision M4300 + +pci:v00008086d0000284Bsv00001028sd00000256* + ID_PRODUCT_FROM_DATABASE=Studio 1735 + +pci:v00008086d0000284Bsv0000103Csd00002802* + ID_PRODUCT_FROM_DATABASE=HP Compaq dc7700p + +pci:v00008086d0000284Bsv0000103Csd000030C0* + ID_PRODUCT_FROM_DATABASE=Compaq 6710b + +pci:v00008086d0000284Bsv0000103Csd000030C1* + ID_PRODUCT_FROM_DATABASE=Compaq 6910p + +pci:v00008086d0000284Bsv0000103Csd000030CC* + ID_PRODUCT_FROM_DATABASE=Pavilion dv6700 + +pci:v00008086d0000284Bsv00001043sd00001339* + ID_PRODUCT_FROM_DATABASE=Asus M51S series + +pci:v00008086d0000284Bsv00001043sd000081EC* + ID_PRODUCT_FROM_DATABASE=P5B + +pci:v00008086d0000284Bsv0000104Dsd00009005* + ID_PRODUCT_FROM_DATABASE=Vaio VGN-FZ260E + +pci:v00008086d0000284Bsv0000104Dsd00009008* + ID_PRODUCT_FROM_DATABASE=Vaio VGN-SZ79SN_C + +pci:v00008086d0000284Bsv0000104Dsd00009016* + ID_PRODUCT_FROM_DATABASE=Sony VAIO VGN-AR51M + +pci:v00008086d0000284Bsv0000104Dsd0000902D* + ID_PRODUCT_FROM_DATABASE=VAIO VGN-NR120E + +pci:v00008086d0000284Bsv000014F1sd00005051* + ID_PRODUCT_FROM_DATABASE=Presario C700 + +pci:v00008086d0000284Bsv000017AAsd000020AC* + ID_PRODUCT_FROM_DATABASE=ThinkPad T61 + +pci:v00008086d0000284Bsv00008384sd00007616* + ID_PRODUCT_FROM_DATABASE=Dell Vostro 1400 + +pci:v00008086d0000284Bsv0000E4BFsd0000CC47* + ID_PRODUCT_FROM_DATABASE=CCG-RUMBA + +pci:v00008086d0000284F* + ID_PRODUCT_FROM_DATABASE=82801H (ICH8 Family) Thermal Reporting Device + +pci:v00008086d00002850* + ID_PRODUCT_FROM_DATABASE=82801HM/HEM (ICH8M/ICH8M-E) IDE Controller + +pci:v00008086d00002850sv00001025sd00000121* + ID_PRODUCT_FROM_DATABASE=Aspire 5920G + +pci:v00008086d00002850sv00001028sd000001F3* + ID_PRODUCT_FROM_DATABASE=Inspiron 1420 + +pci:v00008086d00002850sv0000103Csd000030C0* + ID_PRODUCT_FROM_DATABASE=Compaq 6710b + +pci:v00008086d00002850sv0000103Csd000030C1* + ID_PRODUCT_FROM_DATABASE=Compaq 6910p + +pci:v00008086d00002850sv0000103Csd000030CC* + ID_PRODUCT_FROM_DATABASE=Pavilion dv6700 + +pci:v00008086d00002850sv0000103Csd000030D9* + ID_PRODUCT_FROM_DATABASE=Presario C700 + +pci:v00008086d00002850sv0000104Dsd00009005* + ID_PRODUCT_FROM_DATABASE=Vaio VGN-FZ260E + +pci:v00008086d00002850sv0000104Dsd0000902D* + ID_PRODUCT_FROM_DATABASE=VAIO VGN-NR120E + +pci:v00008086d00002850sv000017AAsd000020A6* + ID_PRODUCT_FROM_DATABASE=ThinkPad T61 + +pci:v00008086d00002850sv0000E4BFsd0000CC47* + ID_PRODUCT_FROM_DATABASE=CCG-RUMBA + +pci:v00008086d00002912* + ID_PRODUCT_FROM_DATABASE=82801IH (ICH9DH) LPC Interface Controller + +pci:v00008086d00002914* + ID_PRODUCT_FROM_DATABASE=82801IO (ICH9DO) LPC Interface Controller + +pci:v00008086d00002914sv00001028sd00000211* + ID_PRODUCT_FROM_DATABASE=Optiplex 755 + +pci:v00008086d00002916* + ID_PRODUCT_FROM_DATABASE=82801IR (ICH9R) LPC Interface Controller + +pci:v00008086d00002916sv00001028sd0000020D* + ID_PRODUCT_FROM_DATABASE=Inspiron 530 + +pci:v00008086d00002916sv00008086sd00005044* + ID_PRODUCT_FROM_DATABASE=Desktop Board DP35DP + +pci:v00008086d00002917* + ID_PRODUCT_FROM_DATABASE=ICH9M-E LPC Interface Controller + +pci:v00008086d00002917sv0000E4BFsd0000CC4D* + ID_PRODUCT_FROM_DATABASE=CCM-BOOGIE + +pci:v00008086d00002918* + ID_PRODUCT_FROM_DATABASE=82801IB (ICH9) LPC Interface Controller + +pci:v00008086d00002918sv00001028sd00000236* + ID_PRODUCT_FROM_DATABASE=PowerEdge R610 82801IB (ICH9) LPC Interface Controller + +pci:v00008086d00002918sv00001462sd00007360* + ID_PRODUCT_FROM_DATABASE=G33/P35 Neo + +pci:v00008086d00002919* + ID_PRODUCT_FROM_DATABASE=ICH9M LPC Interface Controller + +pci:v00008086d00002920* + ID_PRODUCT_FROM_DATABASE=82801IR/IO/IH (ICH9R/DO/DH) 4 port SATA Controller [IDE mode] + +pci:v00008086d00002920sv00001028sd0000020D* + ID_PRODUCT_FROM_DATABASE=Inspiron 530 + +pci:v00008086d00002920sv00001028sd0000020F* + ID_PRODUCT_FROM_DATABASE=PowerEdge R300 onboard SATA Controller + +pci:v00008086d00002920sv00001028sd00000210* + ID_PRODUCT_FROM_DATABASE=PowerEdge T300 onboard SATA Controller + +pci:v00008086d00002920sv00001028sd00000211* + ID_PRODUCT_FROM_DATABASE=Optiplex 755 + +pci:v00008086d00002920sv00001028sd0000023C* + ID_PRODUCT_FROM_DATABASE=PowerEdge R200 onboard SATA Controller + +pci:v00008086d00002921* + ID_PRODUCT_FROM_DATABASE=82801IB (ICH9) 2 port SATA Controller [IDE mode] + +pci:v00008086d00002921sv00001028sd00000235* + ID_PRODUCT_FROM_DATABASE=PowerEdge R710 SATA IDE Controller + +pci:v00008086d00002921sv00001028sd00000236* + ID_PRODUCT_FROM_DATABASE=PowerEdge R610 SATA IDE Controller + +pci:v00008086d00002921sv00001028sd00000237* + ID_PRODUCT_FROM_DATABASE=PowerEdge T610 SATA IDE Controller + +pci:v00008086d00002921sv00001462sd00007360* + ID_PRODUCT_FROM_DATABASE=G33/P35 Neo + +pci:v00008086d00002922* + ID_PRODUCT_FROM_DATABASE=82801IR/IO/IH (ICH9R/DO/DH) 6 port SATA Controller [AHCI mode] + +pci:v00008086d00002922sv00008086sd00005044* + ID_PRODUCT_FROM_DATABASE=Desktop Board DP35DP + +pci:v00008086d00002923* + ID_PRODUCT_FROM_DATABASE=82801IB (ICH9) 4 port SATA Controller [AHCI mode] + +pci:v00008086d00002925* + ID_PRODUCT_FROM_DATABASE=82801IR/IO (ICH9R/DO) SATA Controller [RAID mode] + +pci:v00008086d00002925sv00001734sd000010E0* + ID_PRODUCT_FROM_DATABASE=System Board D2542 + +pci:v00008086d00002925sv00008086sd00002925* + ID_PRODUCT_FROM_DATABASE=System Board D2542 + +pci:v00008086d00002926* + ID_PRODUCT_FROM_DATABASE=82801I (ICH9 Family) 2 port SATA Controller [IDE mode] + +pci:v00008086d00002926sv00001028sd0000020D* + ID_PRODUCT_FROM_DATABASE=Inspiron 530 + +pci:v00008086d00002926sv00001028sd0000020F* + ID_PRODUCT_FROM_DATABASE=PowerEdge R300 onboard SATA Controller + +pci:v00008086d00002926sv00001028sd00000210* + ID_PRODUCT_FROM_DATABASE=PowerEdge T300 onboard SATA Controller + +pci:v00008086d00002926sv00001028sd00000211* + ID_PRODUCT_FROM_DATABASE=Optiplex 755 + +pci:v00008086d00002926sv00001462sd00007360* + ID_PRODUCT_FROM_DATABASE=G33/P35 Neo + +pci:v00008086d00002928* + ID_PRODUCT_FROM_DATABASE=82801IBM/IEM (ICH9M/ICH9M-E) 2 port SATA Controller [IDE mode] + +pci:v00008086d00002929* + ID_PRODUCT_FROM_DATABASE=82801IBM/IEM (ICH9M/ICH9M-E) 4 port SATA Controller [AHCI mode] + +pci:v00008086d00002929sv0000103Csd00003628* + ID_PRODUCT_FROM_DATABASE=dv6-1190en + +pci:v00008086d00002929sv0000E4BFsd0000CC4D* + ID_PRODUCT_FROM_DATABASE=CCM-BOOGIE + +pci:v00008086d0000292C* + ID_PRODUCT_FROM_DATABASE=82801IEM (ICH9M-E) SATA Controller [RAID mode] + +pci:v00008086d0000292D* + ID_PRODUCT_FROM_DATABASE=82801IBM/IEM (ICH9M/ICH9M-E) 2 port SATA Controller [IDE mode] + +pci:v00008086d0000292Dsv0000E4BFsd0000CC4D* + ID_PRODUCT_FROM_DATABASE=CCM-BOOGIE + +pci:v00008086d00002930* + ID_PRODUCT_FROM_DATABASE=82801I (ICH9 Family) SMBus Controller + +pci:v00008086d00002930sv00001028sd0000020D* + ID_PRODUCT_FROM_DATABASE=Inspiron 530 + +pci:v00008086d00002930sv00001028sd00000211* + ID_PRODUCT_FROM_DATABASE=Optiplex 755 + +pci:v00008086d00002930sv0000103Csd00003628* + ID_PRODUCT_FROM_DATABASE=dv6-1190en + +pci:v00008086d00002930sv00001462sd00007360* + ID_PRODUCT_FROM_DATABASE=G33/P35 Neo + +pci:v00008086d00002930sv00008086sd00005044* + ID_PRODUCT_FROM_DATABASE=Desktop Board DP35DP + +pci:v00008086d00002930sv0000E4BFsd0000CC4D* + ID_PRODUCT_FROM_DATABASE=CCM-BOOGIE + +pci:v00008086d00002932* + ID_PRODUCT_FROM_DATABASE=82801I (ICH9 Family) Thermal Subsystem + +pci:v00008086d00002932sv0000103Csd00003628* + ID_PRODUCT_FROM_DATABASE=dv6-1190en + +pci:v00008086d00002934* + ID_PRODUCT_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #1 + +pci:v00008086d00002934sv00001028sd0000020D* + ID_PRODUCT_FROM_DATABASE=Inspiron 530 + +pci:v00008086d00002934sv00001028sd0000020F* + ID_PRODUCT_FROM_DATABASE=PowerEdge R300 onboard UHCI + +pci:v00008086d00002934sv00001028sd00000210* + ID_PRODUCT_FROM_DATABASE=PowerEdge T300 onboard UHCI + +pci:v00008086d00002934sv00001028sd00000211* + ID_PRODUCT_FROM_DATABASE=Optiplex 755 + +pci:v00008086d00002934sv00001028sd00000235* + ID_PRODUCT_FROM_DATABASE=PowerEdge R710 USB UHCI Controller + +pci:v00008086d00002934sv00001028sd00000236* + ID_PRODUCT_FROM_DATABASE=PowerEdge R610 USB UHCI Controller + +pci:v00008086d00002934sv00001028sd00000237* + ID_PRODUCT_FROM_DATABASE=PowerEdge T610 USB UHCI Controller + +pci:v00008086d00002934sv00001028sd0000023C* + ID_PRODUCT_FROM_DATABASE=PowerEdge R200 onboard UHCI + +pci:v00008086d00002934sv00001028sd00000287* + ID_PRODUCT_FROM_DATABASE=PowerEdge M610 onboard UHCI + +pci:v00008086d00002934sv00001028sd0000029C* + ID_PRODUCT_FROM_DATABASE=PowerEdge M710 USB UHCI Controller + +pci:v00008086d00002934sv00001028sd00002011* + ID_PRODUCT_FROM_DATABASE=Optiplex 755 + +pci:v00008086d00002934sv00001462sd00007360* + ID_PRODUCT_FROM_DATABASE=G33/P35 Neo + +pci:v00008086d00002934sv00008086sd00005044* + ID_PRODUCT_FROM_DATABASE=Desktop Board DP35DP + +pci:v00008086d00002934sv0000E4BFsd0000CC4D* + ID_PRODUCT_FROM_DATABASE=CCM-BOOGIE + +pci:v00008086d00002935* + ID_PRODUCT_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #2 + +pci:v00008086d00002935sv00001028sd0000020D* + ID_PRODUCT_FROM_DATABASE=Inspiron 530 + +pci:v00008086d00002935sv00001028sd0000020F* + ID_PRODUCT_FROM_DATABASE=PowerEdge R300 onboard UHCI + +pci:v00008086d00002935sv00001028sd00000210* + ID_PRODUCT_FROM_DATABASE=PowerEdge T300 onboard UHCI + +pci:v00008086d00002935sv00001028sd00000211* + ID_PRODUCT_FROM_DATABASE=Optiplex 755 + +pci:v00008086d00002935sv00001028sd00000235* + ID_PRODUCT_FROM_DATABASE=PowerEdge R710 USB UHCI Controller + +pci:v00008086d00002935sv00001028sd00000236* + ID_PRODUCT_FROM_DATABASE=PowerEdge R610 USB UHCI Controller + +pci:v00008086d00002935sv00001028sd00000237* + ID_PRODUCT_FROM_DATABASE=PowerEdge T610 USB UHCI Controller + +pci:v00008086d00002935sv00001028sd0000023C* + ID_PRODUCT_FROM_DATABASE=PowerEdge R200 onboard UHCI + +pci:v00008086d00002935sv00001028sd00000287* + ID_PRODUCT_FROM_DATABASE=PowerEdge M610 onboard UHCI + +pci:v00008086d00002935sv00001028sd0000029C* + ID_PRODUCT_FROM_DATABASE=PowerEdge M710 USB UHCI Controller + +pci:v00008086d00002935sv00001462sd00007360* + ID_PRODUCT_FROM_DATABASE=G33/P35 Neo + +pci:v00008086d00002935sv00008086sd00005044* + ID_PRODUCT_FROM_DATABASE=Desktop Board DP35DP + +pci:v00008086d00002935sv0000E4BFsd0000CC4D* + ID_PRODUCT_FROM_DATABASE=CCM-BOOGIE + +pci:v00008086d00002936* + ID_PRODUCT_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #3 + +pci:v00008086d00002936sv00001028sd0000020D* + ID_PRODUCT_FROM_DATABASE=Inspiron 530 + +pci:v00008086d00002936sv00001028sd0000020F* + ID_PRODUCT_FROM_DATABASE=PowerEdge R300 onboard UHCI + +pci:v00008086d00002936sv00001028sd00000210* + ID_PRODUCT_FROM_DATABASE=PowerEdge T300 onboard UHCI + +pci:v00008086d00002936sv00001028sd00000211* + ID_PRODUCT_FROM_DATABASE=Optiplex 755 + +pci:v00008086d00002936sv00001028sd00000237* + ID_PRODUCT_FROM_DATABASE=PowerEdge T610 USB UHCI Controller + +pci:v00008086d00002936sv00001028sd0000023C* + ID_PRODUCT_FROM_DATABASE=PowerEdge R200 onboard UHCI + +pci:v00008086d00002936sv00001028sd00000287* + ID_PRODUCT_FROM_DATABASE=PowerEdge M610 onboard UHCI + +pci:v00008086d00002936sv00001028sd0000029C* + ID_PRODUCT_FROM_DATABASE=PowerEdge M710 USB UHCI Controller + +pci:v00008086d00002936sv00001462sd00007360* + ID_PRODUCT_FROM_DATABASE=G33/P35 Neo + +pci:v00008086d00002936sv00008086sd00005044* + ID_PRODUCT_FROM_DATABASE=Desktop Board DP35DP + +pci:v00008086d00002936sv0000E4BFsd0000CC4D* + ID_PRODUCT_FROM_DATABASE=CCM-BOOGIE + +pci:v00008086d00002937* + ID_PRODUCT_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #4 + +pci:v00008086d00002937sv00001028sd0000020D* + ID_PRODUCT_FROM_DATABASE=Inspiron 530 + +pci:v00008086d00002937sv00001028sd00000211* + ID_PRODUCT_FROM_DATABASE=Optiplex 755 + +pci:v00008086d00002937sv00001028sd00000235* + ID_PRODUCT_FROM_DATABASE=PowerEdge R710 USB UHCI Controller + +pci:v00008086d00002937sv00001028sd00000236* + ID_PRODUCT_FROM_DATABASE=PowerEdge R610 USB UHCI Controller + +pci:v00008086d00002937sv00001028sd00000237* + ID_PRODUCT_FROM_DATABASE=PowerEdge T610 USB UHCI Controller + +pci:v00008086d00002937sv00001028sd00000287* + ID_PRODUCT_FROM_DATABASE=PowerEdge M610 onboard UHCI + +pci:v00008086d00002937sv00001028sd0000029C* + ID_PRODUCT_FROM_DATABASE=PowerEdge M710 USB UHCI Controller + +pci:v00008086d00002937sv00001028sd00002011* + ID_PRODUCT_FROM_DATABASE=Optiplex 755 + +pci:v00008086d00002937sv00001462sd00007360* + ID_PRODUCT_FROM_DATABASE=G33/P35 Neo + +pci:v00008086d00002937sv00008086sd00002937* + ID_PRODUCT_FROM_DATABASE=Optiplex 755 + +pci:v00008086d00002937sv00008086sd00002942* + ID_PRODUCT_FROM_DATABASE=828011 (ICH9 Family ) USB UHCI Controller + +pci:v00008086d00002937sv00008086sd00005044* + ID_PRODUCT_FROM_DATABASE=Desktop Board DP35DP + +pci:v00008086d00002937sv0000E4BFsd0000CC4D* + ID_PRODUCT_FROM_DATABASE=CCM-BOOGIE + +pci:v00008086d00002938* + ID_PRODUCT_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #5 + +pci:v00008086d00002938sv00001028sd0000020D* + ID_PRODUCT_FROM_DATABASE=Inspiron 530 + +pci:v00008086d00002938sv00001028sd00000211* + ID_PRODUCT_FROM_DATABASE=Optiplex 755 + +pci:v00008086d00002938sv00001028sd00000235* + ID_PRODUCT_FROM_DATABASE=PowerEdge R710 USB UHCI Controller + +pci:v00008086d00002938sv00001028sd00000236* + ID_PRODUCT_FROM_DATABASE=PowerEdge R610 USB UHCI Controller + +pci:v00008086d00002938sv00001028sd00000237* + ID_PRODUCT_FROM_DATABASE=PowerEdge T610 USB UHCI Controller + +pci:v00008086d00002938sv00001028sd00000287* + ID_PRODUCT_FROM_DATABASE=PowerEdge M610 onboard UHCI + +pci:v00008086d00002938sv00001028sd0000029C* + ID_PRODUCT_FROM_DATABASE=PowerEdge M710 USB UHCI Controller + +pci:v00008086d00002938sv00001462sd00007360* + ID_PRODUCT_FROM_DATABASE=G33/P35 Neo + +pci:v00008086d00002938sv00008086sd00002938* + ID_PRODUCT_FROM_DATABASE=Optiplex 755 + +pci:v00008086d00002938sv00008086sd00005044* + ID_PRODUCT_FROM_DATABASE=Desktop Board DP35DP + +pci:v00008086d00002938sv0000E4BFsd0000CC4D* + ID_PRODUCT_FROM_DATABASE=CCM-BOOGIE + +pci:v00008086d00002939* + ID_PRODUCT_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #6 + +pci:v00008086d00002939sv00001028sd0000020D* + ID_PRODUCT_FROM_DATABASE=Inspiron 530 + +pci:v00008086d00002939sv00001028sd00000210* + ID_PRODUCT_FROM_DATABASE=PowerEdge T300 onboard UHCI + +pci:v00008086d00002939sv00001028sd00000237* + ID_PRODUCT_FROM_DATABASE=PowerEdge T610 USB UHCI Controller + +pci:v00008086d00002939sv00001462sd00007360* + ID_PRODUCT_FROM_DATABASE=G33/P35 Neo + +pci:v00008086d00002939sv00008086sd00005044* + ID_PRODUCT_FROM_DATABASE=Desktop Board DP35DP + +pci:v00008086d00002939sv0000E4BFsd0000CC4D* + ID_PRODUCT_FROM_DATABASE=CCM-BOOGIE + +pci:v00008086d0000293A* + ID_PRODUCT_FROM_DATABASE=82801I (ICH9 Family) USB2 EHCI Controller #1 + +pci:v00008086d0000293Asv00001028sd0000020D* + ID_PRODUCT_FROM_DATABASE=Inspiron 530 + +pci:v00008086d0000293Asv00001028sd0000020F* + ID_PRODUCT_FROM_DATABASE=PowerEdge R300 onboard EHCI + +pci:v00008086d0000293Asv00001028sd00000210* + ID_PRODUCT_FROM_DATABASE=PowerEdge T300 onboard EHCI + +pci:v00008086d0000293Asv00001028sd00000211* + ID_PRODUCT_FROM_DATABASE=Optiplex 755 + +pci:v00008086d0000293Asv00001028sd00000235* + ID_PRODUCT_FROM_DATABASE=PowerEdge R710 USB EHCI Controller + +pci:v00008086d0000293Asv00001028sd00000236* + ID_PRODUCT_FROM_DATABASE=PowerEdge R610 USB EHCI Controller + +pci:v00008086d0000293Asv00001028sd00000237* + ID_PRODUCT_FROM_DATABASE=PowerEdge T610 USB EHCI Controller + +pci:v00008086d0000293Asv00001028sd0000023C* + ID_PRODUCT_FROM_DATABASE=PowerEdge R200 onboard EHCI + +pci:v00008086d0000293Asv00001028sd00000287* + ID_PRODUCT_FROM_DATABASE=PowerEdge M610 onboard EHCI + +pci:v00008086d0000293Asv00001028sd0000029C* + ID_PRODUCT_FROM_DATABASE=PowerEdge M710 USB EHCI Controller + +pci:v00008086d0000293Asv00001462sd00007360* + ID_PRODUCT_FROM_DATABASE=G33/P35 Neo + +pci:v00008086d0000293Asv00008086sd00005044* + ID_PRODUCT_FROM_DATABASE=Desktop Board DP35DP + +pci:v00008086d0000293Asv0000E4BFsd0000CC4D* + ID_PRODUCT_FROM_DATABASE=CCM-BOOGIE + +pci:v00008086d0000293C* + ID_PRODUCT_FROM_DATABASE=82801I (ICH9 Family) USB2 EHCI Controller #2 + +pci:v00008086d0000293Csv00001028sd0000020D* + ID_PRODUCT_FROM_DATABASE=Inspiron 530 + +pci:v00008086d0000293Csv00001028sd00000211* + ID_PRODUCT_FROM_DATABASE=Optiplex 755 + +pci:v00008086d0000293Csv00001028sd00000235* + ID_PRODUCT_FROM_DATABASE=PowerEdge R710 USB EHCI Controller + +pci:v00008086d0000293Csv00001028sd00000236* + ID_PRODUCT_FROM_DATABASE=PowerEdge R610 USB EHCI Controller + +pci:v00008086d0000293Csv00001028sd00000237* + ID_PRODUCT_FROM_DATABASE=PowerEdge T610 USB EHCI Controller + +pci:v00008086d0000293Csv00001028sd00000287* + ID_PRODUCT_FROM_DATABASE=PowerEdge M610 onboard EHCI + +pci:v00008086d0000293Csv00001028sd0000029C* + ID_PRODUCT_FROM_DATABASE=PowerEdge M710 USB EHCI Controller + +pci:v00008086d0000293Csv00001462sd00007360* + ID_PRODUCT_FROM_DATABASE=G33/P35 Neo + +pci:v00008086d0000293Csv00008086sd0000293C* + ID_PRODUCT_FROM_DATABASE=Optiplex 755 + +pci:v00008086d0000293Csv00008086sd00005044* + ID_PRODUCT_FROM_DATABASE=Desktop Board DP35DP + +pci:v00008086d0000293Csv0000E4BFsd0000CC4D* + ID_PRODUCT_FROM_DATABASE=CCM-BOOGIE + +pci:v00008086d0000293E* + ID_PRODUCT_FROM_DATABASE=82801I (ICH9 Family) HD Audio Controller + +pci:v00008086d0000293Esv00001028sd0000020D* + ID_PRODUCT_FROM_DATABASE=Inspiron 530 + +pci:v00008086d0000293Esv00001028sd00000211* + ID_PRODUCT_FROM_DATABASE=Optiplex 755 + +pci:v00008086d0000293Esv0000103Csd00003628* + ID_PRODUCT_FROM_DATABASE=dv6-1190en + +pci:v00008086d0000293Esv00001462sd00007360* + ID_PRODUCT_FROM_DATABASE=G33/P35 Neo + +pci:v00008086d0000293Esv00008086sd0000293E* + ID_PRODUCT_FROM_DATABASE=Optiplex 755 + +pci:v00008086d0000293Esv00008086sd00002940* + ID_PRODUCT_FROM_DATABASE=Optiplex 755 + +pci:v00008086d0000293Esv0000E4BFsd0000CC4D* + ID_PRODUCT_FROM_DATABASE=CCM-BOOGIE + +pci:v00008086d00002940* + ID_PRODUCT_FROM_DATABASE=82801I (ICH9 Family) PCI Express Port 1 + +pci:v00008086d00002940sv00001028sd0000020D* + ID_PRODUCT_FROM_DATABASE=Inspiron 530 + +pci:v00008086d00002940sv00001028sd00000211* + ID_PRODUCT_FROM_DATABASE=Optiplex 755 + +pci:v00008086d00002940sv00008086sd00002940* + ID_PRODUCT_FROM_DATABASE=Optiplex 755 + +pci:v00008086d00002942* + ID_PRODUCT_FROM_DATABASE=82801I (ICH9 Family) PCI Express Port 2 + +pci:v00008086d00002942sv00001028sd0000020D* + ID_PRODUCT_FROM_DATABASE=Inspiron 530 + +pci:v00008086d00002944* + ID_PRODUCT_FROM_DATABASE=82801I (ICH9 Family) PCI Express Port 3 + +pci:v00008086d00002944sv00001028sd0000020D* + ID_PRODUCT_FROM_DATABASE=Inspiron 530 + +pci:v00008086d00002946* + ID_PRODUCT_FROM_DATABASE=82801I (ICH9 Family) PCI Express Port 4 + +pci:v00008086d00002946sv00001028sd0000020D* + ID_PRODUCT_FROM_DATABASE=Inspiron 530 + +pci:v00008086d00002948* + ID_PRODUCT_FROM_DATABASE=82801I (ICH9 Family) PCI Express Port 5 + +pci:v00008086d00002948sv00001028sd0000020D* + ID_PRODUCT_FROM_DATABASE=Inspiron 530 + +pci:v00008086d0000294A* + ID_PRODUCT_FROM_DATABASE=82801I (ICH9 Family) PCI Express Port 6 + +pci:v00008086d0000294Asv00001028sd0000020D* + ID_PRODUCT_FROM_DATABASE=Inspiron 530 + +pci:v00008086d0000294C* + ID_PRODUCT_FROM_DATABASE=82566DC-2 Gigabit Network Connection + +pci:v00008086d0000294Csv000017AAsd0000302E* + ID_PRODUCT_FROM_DATABASE=82566DM-2 Gigabit Network Connection + +pci:v00008086d00002970* + ID_PRODUCT_FROM_DATABASE=82946GZ/PL/GL Memory Controller Hub + +pci:v00008086d00002971* + ID_PRODUCT_FROM_DATABASE=82946GZ/PL/GL PCI Express Root Port + +pci:v00008086d00002972* + ID_PRODUCT_FROM_DATABASE=82946GZ/GL Integrated Graphics Controller + +pci:v00008086d00002973* + ID_PRODUCT_FROM_DATABASE=82946GZ/GL Integrated Graphics Controller + +pci:v00008086d00002974* + ID_PRODUCT_FROM_DATABASE=82946GZ/GL HECI Controller + +pci:v00008086d00002975* + ID_PRODUCT_FROM_DATABASE=82946GZ/GL HECI Controller + +pci:v00008086d00002976* + ID_PRODUCT_FROM_DATABASE=82946GZ/GL PT IDER Controller + +pci:v00008086d00002977* + ID_PRODUCT_FROM_DATABASE=82946GZ/GL KT Controller + +pci:v00008086d00002980* + ID_PRODUCT_FROM_DATABASE=82G35 Express DRAM Controller + +pci:v00008086d00002981* + ID_PRODUCT_FROM_DATABASE=82G35 Express PCI Express Root Port + +pci:v00008086d00002982* + ID_PRODUCT_FROM_DATABASE=82G35 Express Integrated Graphics Controller + +pci:v00008086d00002983* + ID_PRODUCT_FROM_DATABASE=82G35 Express Integrated Graphics Controller + +pci:v00008086d00002984* + ID_PRODUCT_FROM_DATABASE=82G35 Express HECI Controller + +pci:v00008086d00002990* + ID_PRODUCT_FROM_DATABASE=82Q963/Q965 Memory Controller Hub + +pci:v00008086d00002990sv00001028sd000001DA* + ID_PRODUCT_FROM_DATABASE=OptiPlex 745 + +pci:v00008086d00002991* + ID_PRODUCT_FROM_DATABASE=82Q963/Q965 PCI Express Root Port + +pci:v00008086d00002992* + ID_PRODUCT_FROM_DATABASE=82Q963/Q965 Integrated Graphics Controller + +pci:v00008086d00002993* + ID_PRODUCT_FROM_DATABASE=82Q963/Q965 Integrated Graphics Controller + +pci:v00008086d00002994* + ID_PRODUCT_FROM_DATABASE=82Q963/Q965 HECI Controller + +pci:v00008086d00002995* + ID_PRODUCT_FROM_DATABASE=82Q963/Q965 HECI Controller + +pci:v00008086d00002996* + ID_PRODUCT_FROM_DATABASE=82Q963/Q965 PT IDER Controller + +pci:v00008086d00002997* + ID_PRODUCT_FROM_DATABASE=82Q963/Q965 KT Controller + +pci:v00008086d000029A0* + ID_PRODUCT_FROM_DATABASE=82P965/G965 Memory Controller Hub + +pci:v00008086d000029A0sv00001043sd000081EA* + ID_PRODUCT_FROM_DATABASE=P5B + +pci:v00008086d000029A0sv00001462sd00007276* + ID_PRODUCT_FROM_DATABASE=MS-7276 [G965MDH] + +pci:v00008086d000029A1* + ID_PRODUCT_FROM_DATABASE=82P965/G965 PCI Express Root Port + +pci:v00008086d000029A2* + ID_PRODUCT_FROM_DATABASE=82G965 Integrated Graphics Controller + +pci:v00008086d000029A2sv00001462sd00007276* + ID_PRODUCT_FROM_DATABASE=MS-7276 [G965MDH] + +pci:v00008086d000029A3* + ID_PRODUCT_FROM_DATABASE=82G965 Integrated Graphics Controller + +pci:v00008086d000029A4* + ID_PRODUCT_FROM_DATABASE=82P965/G965 HECI Controller + +pci:v00008086d000029A5* + ID_PRODUCT_FROM_DATABASE=82P965/G965 HECI Controller + +pci:v00008086d000029A6* + ID_PRODUCT_FROM_DATABASE=82P965/G965 PT IDER Controller + +pci:v00008086d000029A7* + ID_PRODUCT_FROM_DATABASE=82P965/G965 KT Controller + +pci:v00008086d000029B0* + ID_PRODUCT_FROM_DATABASE=82Q35 Express DRAM Controller + +pci:v00008086d000029B0sv00001028sd00000211* + ID_PRODUCT_FROM_DATABASE=OptiPlex 755 + +pci:v00008086d000029B1* + ID_PRODUCT_FROM_DATABASE=82Q35 Express PCI Express Root Port + +pci:v00008086d000029B1sv00001028sd00000211* + ID_PRODUCT_FROM_DATABASE=OptiPlex 755 + +pci:v00008086d000029B2* + ID_PRODUCT_FROM_DATABASE=82Q35 Express Integrated Graphics Controller + +pci:v00008086d000029B2sv00001028sd00000211* + ID_PRODUCT_FROM_DATABASE=OptiPlex 755 + +pci:v00008086d000029B3* + ID_PRODUCT_FROM_DATABASE=82Q35 Express Integrated Graphics Controller + +pci:v00008086d000029B3sv00001028sd00000211* + ID_PRODUCT_FROM_DATABASE=OptiPlex 755 + +pci:v00008086d000029B4* + ID_PRODUCT_FROM_DATABASE=82Q35 Express MEI Controller + +pci:v00008086d000029B4sv00001028sd00000211* + ID_PRODUCT_FROM_DATABASE=OptiPlex 755 + +pci:v00008086d000029B5* + ID_PRODUCT_FROM_DATABASE=82Q35 Express MEI Controller + +pci:v00008086d000029B6* + ID_PRODUCT_FROM_DATABASE=82Q35 Express PT IDER Controller + +pci:v00008086d000029B6sv00001028sd00000211* + ID_PRODUCT_FROM_DATABASE=OptiPlex 755 + +pci:v00008086d000029B7* + ID_PRODUCT_FROM_DATABASE=82Q35 Express Serial KT Controller + +pci:v00008086d000029B7sv00001028sd00000211* + ID_PRODUCT_FROM_DATABASE=OptiPlex 755 + +pci:v00008086d000029C0* + ID_PRODUCT_FROM_DATABASE=82G33/G31/P35/P31 Express DRAM Controller + +pci:v00008086d000029C0sv00001028sd0000020D* + ID_PRODUCT_FROM_DATABASE=Inspiron 530 + +pci:v00008086d000029C0sv00001043sd000082B0* + ID_PRODUCT_FROM_DATABASE=P5KPL-VM Motherboard + +pci:v00008086d000029C0sv00001462sd00007360* + ID_PRODUCT_FROM_DATABASE=G33/P35 Neo + +pci:v00008086d000029C0sv00008086sd00005044* + ID_PRODUCT_FROM_DATABASE=Desktop Board DP35DP + +pci:v00008086d000029C1* + ID_PRODUCT_FROM_DATABASE=82G33/G31/P35/P31 Express PCI Express Root Port + +pci:v00008086d000029C1sv00001028sd0000020D* + ID_PRODUCT_FROM_DATABASE=Inspiron 530 + +pci:v00008086d000029C2* + ID_PRODUCT_FROM_DATABASE=82G33/G31 Express Integrated Graphics Controller + +pci:v00008086d000029C2sv00001028sd0000020D* + ID_PRODUCT_FROM_DATABASE=Inspiron 530 + +pci:v00008086d000029C2sv00001043sd000082B0* + ID_PRODUCT_FROM_DATABASE=P5KPL-VM Motherboard + +pci:v00008086d000029C3* + ID_PRODUCT_FROM_DATABASE=82G33/G31 Express Integrated Graphics Controller + +pci:v00008086d000029C3sv00001028sd0000020D* + ID_PRODUCT_FROM_DATABASE=Inspiron 530 + +pci:v00008086d000029C3sv00001043sd000082B0* + ID_PRODUCT_FROM_DATABASE=P5KPL-VM Motherboard + +pci:v00008086d000029C4* + ID_PRODUCT_FROM_DATABASE=82G33/G31/P35/P31 Express MEI Controller + +pci:v00008086d000029C4sv00008086sd00005044* + ID_PRODUCT_FROM_DATABASE=Desktop Board DP35DP + +pci:v00008086d000029C5* + ID_PRODUCT_FROM_DATABASE=82G33/G31/P35/P31 Express MEI Controller + +pci:v00008086d000029C6* + ID_PRODUCT_FROM_DATABASE=82G33/G31/P35/P31 Express PT IDER Controller + +pci:v00008086d000029C7* + ID_PRODUCT_FROM_DATABASE=82G33/G31/P35/P31 Express Serial KT Controller + +pci:v00008086d000029CF* + ID_PRODUCT_FROM_DATABASE=Virtual HECI Controller + +pci:v00008086d000029D0* + ID_PRODUCT_FROM_DATABASE=82Q33 Express DRAM Controller + +pci:v00008086d000029D1* + ID_PRODUCT_FROM_DATABASE=82Q33 Express PCI Express Root Port + +pci:v00008086d000029D2* + ID_PRODUCT_FROM_DATABASE=82Q33 Express Integrated Graphics Controller + +pci:v00008086d000029D3* + ID_PRODUCT_FROM_DATABASE=82Q33 Express Integrated Graphics Controller + +pci:v00008086d000029D4* + ID_PRODUCT_FROM_DATABASE=82Q33 Express MEI Controller + +pci:v00008086d000029D5* + ID_PRODUCT_FROM_DATABASE=82Q33 Express MEI Controller + +pci:v00008086d000029D6* + ID_PRODUCT_FROM_DATABASE=82Q33 Express PT IDER Controller + +pci:v00008086d000029D7* + ID_PRODUCT_FROM_DATABASE=82Q33 Express Serial KT Controller + +pci:v00008086d000029E0* + ID_PRODUCT_FROM_DATABASE=82X38/X48 Express DRAM Controller + +pci:v00008086d000029E1* + ID_PRODUCT_FROM_DATABASE=82X38/X48 Express Host-Primary PCI Express Bridge + +pci:v00008086d000029E4* + ID_PRODUCT_FROM_DATABASE=82X38/X48 Express MEI Controller + +pci:v00008086d000029E5* + ID_PRODUCT_FROM_DATABASE=82X38/X48 Express MEI Controller + +pci:v00008086d000029E6* + ID_PRODUCT_FROM_DATABASE=82X38/X48 Express PT IDER Controller + +pci:v00008086d000029E7* + ID_PRODUCT_FROM_DATABASE=82X38/X48 Express Serial KT Controller + +pci:v00008086d000029E9* + ID_PRODUCT_FROM_DATABASE=82X38/X48 Express Host-Secondary PCI Express Bridge + +pci:v00008086d000029F0* + ID_PRODUCT_FROM_DATABASE=3200/3210 Chipset DRAM Controller + +pci:v00008086d000029F1* + ID_PRODUCT_FROM_DATABASE=3200/3210 Chipset Host-Primary PCI Express Bridge + +pci:v00008086d000029F4* + ID_PRODUCT_FROM_DATABASE=3200/3210 Chipset MEI Controller + +pci:v00008086d000029F5* + ID_PRODUCT_FROM_DATABASE=3200/3210 Chipset MEI Controller + +pci:v00008086d000029F6* + ID_PRODUCT_FROM_DATABASE=3200/3210 Chipset PT IDER Controller + +pci:v00008086d000029F7* + ID_PRODUCT_FROM_DATABASE=3200/3210 Chipset Serial KT Controller + +pci:v00008086d000029F9* + ID_PRODUCT_FROM_DATABASE=3210 Chipset Host-Secondary PCI Express Bridge + +pci:v00008086d00002A00* + ID_PRODUCT_FROM_DATABASE=Mobile PM965/GM965/GL960 Memory Controller Hub + +pci:v00008086d00002A00sv00001025sd00000121* + ID_PRODUCT_FROM_DATABASE=Acer Aspire 5920G + +pci:v00008086d00002A00sv00001028sd000001F3* + ID_PRODUCT_FROM_DATABASE=Inspiron 1420 + +pci:v00008086d00002A00sv0000103Csd000030C0* + ID_PRODUCT_FROM_DATABASE=Compaq 6710b + +pci:v00008086d00002A00sv0000103Csd000030C1* + ID_PRODUCT_FROM_DATABASE=Compaq 6910p + +pci:v00008086d00002A00sv0000103Csd000030CC* + ID_PRODUCT_FROM_DATABASE=Pavilion dv6700 + +pci:v00008086d00002A00sv0000103Csd000030D9* + ID_PRODUCT_FROM_DATABASE=Presario C700 + +pci:v00008086d00002A00sv0000104Dsd00009005* + ID_PRODUCT_FROM_DATABASE=Vaio VGN-FZ260E + +pci:v00008086d00002A00sv0000104Dsd0000902D* + ID_PRODUCT_FROM_DATABASE=VAIO VGN-NR120E + +pci:v00008086d00002A00sv000017AAsd000020B1* + ID_PRODUCT_FROM_DATABASE=ThinkPad T61 + +pci:v00008086d00002A00sv000017AAsd000020B3* + ID_PRODUCT_FROM_DATABASE=T61 + +pci:v00008086d00002A00sv0000E4BFsd0000CC47* + ID_PRODUCT_FROM_DATABASE=CCG-RUMBA + +pci:v00008086d00002A01* + ID_PRODUCT_FROM_DATABASE=Mobile PM965/GM965/GL960 PCI Express Root Port + +pci:v00008086d00002A02* + ID_PRODUCT_FROM_DATABASE=Mobile GM965/GL960 Integrated Graphics Controller (primary) + +pci:v00008086d00002A02sv00001028sd000001F3* + ID_PRODUCT_FROM_DATABASE=Inspiron 1420 + +pci:v00008086d00002A02sv00001028sd000001F9* + ID_PRODUCT_FROM_DATABASE=Latitude D630 + +pci:v00008086d00002A02sv0000103Csd000030C0* + ID_PRODUCT_FROM_DATABASE=Compaq 6710b + +pci:v00008086d00002A02sv0000103Csd000030D9* + ID_PRODUCT_FROM_DATABASE=Presario C700 + +pci:v00008086d00002A02sv0000104Dsd0000902D* + ID_PRODUCT_FROM_DATABASE=VAIO VGN-NR120E + +pci:v00008086d00002A02sv000017AAsd000020B5* + ID_PRODUCT_FROM_DATABASE=T61 + +pci:v00008086d00002A02sv0000E4BFsd0000CC47* + ID_PRODUCT_FROM_DATABASE=CCG-RUMBA + +pci:v00008086d00002A03* + ID_PRODUCT_FROM_DATABASE=Mobile GM965/GL960 Integrated Graphics Controller (secondary) + +pci:v00008086d00002A03sv00001028sd000001F3* + ID_PRODUCT_FROM_DATABASE=Dell Inspiron 1420 + +pci:v00008086d00002A03sv0000103Csd000030C0* + ID_PRODUCT_FROM_DATABASE=Compaq 6710b + +pci:v00008086d00002A03sv0000103Csd000030D9* + ID_PRODUCT_FROM_DATABASE=Presario C700 + +pci:v00008086d00002A03sv0000104Dsd0000902D* + ID_PRODUCT_FROM_DATABASE=VAIO VGN-NR120E + +pci:v00008086d00002A03sv000017AAsd000020B5* + ID_PRODUCT_FROM_DATABASE=T61 + +pci:v00008086d00002A03sv0000E4BFsd0000CC47* + ID_PRODUCT_FROM_DATABASE=CCG-RUMBA + +pci:v00008086d00002A04* + ID_PRODUCT_FROM_DATABASE=Mobile PM965/GM965 MEI Controller + +pci:v00008086d00002A04sv0000103Csd000030C1* + ID_PRODUCT_FROM_DATABASE=Compaq 6910p + +pci:v00008086d00002A05* + ID_PRODUCT_FROM_DATABASE=Mobile PM965/GM965 MEI Controller + +pci:v00008086d00002A06* + ID_PRODUCT_FROM_DATABASE=Mobile PM965/GM965 PT IDER Controller + +pci:v00008086d00002A06sv0000103Csd000030C1* + ID_PRODUCT_FROM_DATABASE=Compaq 6910p + +pci:v00008086d00002A07* + ID_PRODUCT_FROM_DATABASE=Mobile PM965/GM965 KT Controller + +pci:v00008086d00002A07sv0000103Csd000030C1* + ID_PRODUCT_FROM_DATABASE=Compaq 6910p + +pci:v00008086d00002A10* + ID_PRODUCT_FROM_DATABASE=Mobile GME965/GLE960 Memory Controller Hub + +pci:v00008086d00002A10sv0000E4BFsd0000CC47* + ID_PRODUCT_FROM_DATABASE=CCG-RUMBA + +pci:v00008086d00002A11* + ID_PRODUCT_FROM_DATABASE=Mobile GME965/GLE960 PCI Express Root Port + +pci:v00008086d00002A12* + ID_PRODUCT_FROM_DATABASE=Mobile GME965/GLE960 Integrated Graphics Controller + +pci:v00008086d00002A12sv0000E4BFsd0000CC47* + ID_PRODUCT_FROM_DATABASE=CCG-RUMBA + +pci:v00008086d00002A13* + ID_PRODUCT_FROM_DATABASE=Mobile GME965/GLE960 Integrated Graphics Controller + +pci:v00008086d00002A13sv0000E4BFsd0000CC47* + ID_PRODUCT_FROM_DATABASE=CCG-RUMBA + +pci:v00008086d00002A14* + ID_PRODUCT_FROM_DATABASE=Mobile GME965/GLE960 MEI Controller + +pci:v00008086d00002A15* + ID_PRODUCT_FROM_DATABASE=Mobile GME965/GLE960 MEI Controller + +pci:v00008086d00002A16* + ID_PRODUCT_FROM_DATABASE=Mobile GME965/GLE960 PT IDER Controller + +pci:v00008086d00002A17* + ID_PRODUCT_FROM_DATABASE=Mobile GME965/GLE960 KT Controller + +pci:v00008086d00002A40* + ID_PRODUCT_FROM_DATABASE=Mobile 4 Series Chipset Memory Controller Hub + +pci:v00008086d00002A40sv0000E4BFsd0000CC4D* + ID_PRODUCT_FROM_DATABASE=CCM-BOOGIE + +pci:v00008086d00002A41* + ID_PRODUCT_FROM_DATABASE=Mobile 4 Series Chipset PCI Express Graphics Port + +pci:v00008086d00002A41sv0000E4BFsd0000CC4D* + ID_PRODUCT_FROM_DATABASE=CCM-BOOGIE + +pci:v00008086d00002A42* + ID_PRODUCT_FROM_DATABASE=Mobile 4 Series Chipset Integrated Graphics Controller + +pci:v00008086d00002A42sv0000E4BFsd0000CC4D* + ID_PRODUCT_FROM_DATABASE=CCM-BOOGIE + +pci:v00008086d00002A43* + ID_PRODUCT_FROM_DATABASE=Mobile 4 Series Chipset Integrated Graphics Controller + +pci:v00008086d00002A43sv0000E4BFsd0000CC4D* + ID_PRODUCT_FROM_DATABASE=CCM-BOOGIE + +pci:v00008086d00002A44* + ID_PRODUCT_FROM_DATABASE=Mobile 4 Series Chipset MEI Controller + +pci:v00008086d00002A45* + ID_PRODUCT_FROM_DATABASE=Mobile 4 Series Chipset MEI Controller + +pci:v00008086d00002A46* + ID_PRODUCT_FROM_DATABASE=Mobile 4 Series Chipset PT IDER Controller + +pci:v00008086d00002A47* + ID_PRODUCT_FROM_DATABASE=Mobile 4 Series Chipset AMT SOL Redirection + +pci:v00008086d00002A50* + ID_PRODUCT_FROM_DATABASE=Cantiga MEI Controller + +pci:v00008086d00002A51* + ID_PRODUCT_FROM_DATABASE=Cantiga MEI Controller + +pci:v00008086d00002A52* + ID_PRODUCT_FROM_DATABASE=Cantiga PT IDER Controller + +pci:v00008086d00002A53* + ID_PRODUCT_FROM_DATABASE=Cantiga AMT SOL Redirection + +pci:v00008086d00002B00* + ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family System Configuration Controller 1 + +pci:v00008086d00002B02* + ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family System Configuration Controller 2 + +pci:v00008086d00002B04* + ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family Power Controller + +pci:v00008086d00002B08* + ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family Caching Agent 0 + +pci:v00008086d00002B0C* + ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family Caching Agent 1 + +pci:v00008086d00002B10* + ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family QPI Home Agent 0 + +pci:v00008086d00002B13* + ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family Memory Controller 0c + +pci:v00008086d00002B14* + ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family Memory Controller 0a + +pci:v00008086d00002B16* + ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family Memory Controller 0b + +pci:v00008086d00002B18* + ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family QPI Home Agent 1 + +pci:v00008086d00002B1B* + ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family Memory Controller 1c + +pci:v00008086d00002B1C* + ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family Memory Controller 1a + +pci:v00008086d00002B1E* + ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family Memory Controller 1b + +pci:v00008086d00002B20* + ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family Last Level Cache Coherence Engine 0 + +pci:v00008086d00002B22* + ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family System Configuration Controller 3 + +pci:v00008086d00002B24* + ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family Last Level Cache Coherence Engine 1 + +pci:v00008086d00002B28* + ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family Last Level Cache Coherence Engine 2 + +pci:v00008086d00002B2A* + ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family System Configuration Controller 4 + +pci:v00008086d00002B2C* + ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family Last Level Cache Coherence Engine 3 + +pci:v00008086d00002B30* + ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family Last Level Cache Coherence Engine 4 + +pci:v00008086d00002B34* + ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family Last Level Cache Coherence Engine 5 + +pci:v00008086d00002B38* + ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family Last Level Cache Coherence Engine 6 + +pci:v00008086d00002B3C* + ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family Last Level Cache Coherence Engine 7 + +pci:v00008086d00002B40* + ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family QPI Router Port 0-1 + +pci:v00008086d00002B42* + ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family QPI Router Port 2-3 + +pci:v00008086d00002B44* + ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family QPI Router Port 4-5 + +pci:v00008086d00002B46* + ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family QPI Router Port 6-7 + +pci:v00008086d00002B48* + ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family Test and Debug 0 + +pci:v00008086d00002B4C* + ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family Test and Debug 1 + +pci:v00008086d00002B50* + ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family QPI Physical Port 0: REUT control/status + +pci:v00008086d00002B52* + ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family QPI Physical Port 0: Misc. control/status + +pci:v00008086d00002B54* + ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family QPI Physical Port 1: REUT control/status + +pci:v00008086d00002B56* + ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family QPI Physical Port 1: Misc. control/status + +pci:v00008086d00002B58* + ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family QPI Physical Port 2: REUT control/status + +pci:v00008086d00002B5A* + ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family QPI Physical Port 2: Misc. control/status + +pci:v00008086d00002B5C* + ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family QPI Physical Port 3: REUT control/status + +pci:v00008086d00002B5E* + ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family QPI Physical Port 3: Misc. control/status + +pci:v00008086d00002B60* + ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family SMI Physical Port 0: REUT control/status + +pci:v00008086d00002B62* + ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family SMI Physical Port 0: Misc control/status + +pci:v00008086d00002B64* + ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family SMI Physical Port 1: REUT control/status + +pci:v00008086d00002B66* + ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family SMI Physical Port 1: Misc control/status + +pci:v00008086d00002B68* + ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family Last Level Cache Coherence Engine 8 + +pci:v00008086d00002B6C* + ID_PRODUCT_FROM_DATABASE=Xeon Processor E7 Product Family Last Level Cache Coherence Engine 9 + +pci:v00008086d00002C01* + ID_PRODUCT_FROM_DATABASE=Xeon 5500/Core i7 QuickPath Architecture System Address Decoder + +pci:v00008086d00002C10* + ID_PRODUCT_FROM_DATABASE=Xeon 5500/Core i7 QPI Link 0 + +pci:v00008086d00002C11* + ID_PRODUCT_FROM_DATABASE=Xeon 5500/Core i7 QPI Physical 0 + +pci:v00008086d00002C14* + ID_PRODUCT_FROM_DATABASE=Xeon 5500/Core i7 QPI Link 1 + +pci:v00008086d00002C15* + ID_PRODUCT_FROM_DATABASE=Xeon 5500/Core i7 QPI Physical 1 + +pci:v00008086d00002C18* + ID_PRODUCT_FROM_DATABASE=Xeon 5500/Core i7 Integrated Memory Controller + +pci:v00008086d00002C19* + ID_PRODUCT_FROM_DATABASE=Xeon 5500/Core i7 Integrated Memory Controller Target Address Decoder + +pci:v00008086d00002C1A* + ID_PRODUCT_FROM_DATABASE=Xeon 5500/Core i7 Integrated Memory Controller RAS Registers + +pci:v00008086d00002C1C* + ID_PRODUCT_FROM_DATABASE=Xeon 5500/Core i7 Integrated Memory Controller Test Registers + +pci:v00008086d00002C20* + ID_PRODUCT_FROM_DATABASE=Xeon 5500/Core i7 Integrated Memory Controller Channel 0 Control Registers + +pci:v00008086d00002C21* + ID_PRODUCT_FROM_DATABASE=Xeon 5500/Core i7 Integrated Memory Controller Channel 0 Address Registers + +pci:v00008086d00002C22* + ID_PRODUCT_FROM_DATABASE=Xeon 5500/Core i7 Integrated Memory Controller Channel 0 Rank Registers + +pci:v00008086d00002C23* + ID_PRODUCT_FROM_DATABASE=Xeon 5500/Core i7 Integrated Memory Controller Channel 0 Thermal Control Registers + +pci:v00008086d00002C28* + ID_PRODUCT_FROM_DATABASE=Xeon 5500/Core i7 Integrated Memory Controller Channel 1 Control Registers + +pci:v00008086d00002C29* + ID_PRODUCT_FROM_DATABASE=Xeon 5500/Core i7 Integrated Memory Controller Channel 1 Address Registers + +pci:v00008086d00002C2A* + ID_PRODUCT_FROM_DATABASE=Xeon 5500/Core i7 Integrated Memory Controller Channel 1 Rank Registers + +pci:v00008086d00002C2B* + ID_PRODUCT_FROM_DATABASE=Xeon 5500/Core i7 Integrated Memory Controller Channel 1 Thermal Control Registers + +pci:v00008086d00002C30* + ID_PRODUCT_FROM_DATABASE=Xeon 5500/Core i7 Integrated Memory Controller Channel 2 Control Registers + +pci:v00008086d00002C31* + ID_PRODUCT_FROM_DATABASE=Xeon 5500/Core i7 Integrated Memory Controller Channel 2 Address Registers + +pci:v00008086d00002C32* + ID_PRODUCT_FROM_DATABASE=Xeon 5500/Core i7 Integrated Memory Controller Channel 2 Rank Registers + +pci:v00008086d00002C33* + ID_PRODUCT_FROM_DATABASE=Xeon 5500/Core i7 Integrated Memory Controller Channel 2 Thermal Control Registers + +pci:v00008086d00002C40* + ID_PRODUCT_FROM_DATABASE=Xeon 5500/Core i7 QuickPath Architecture Generic Non-Core Registers + +pci:v00008086d00002C41* + ID_PRODUCT_FROM_DATABASE=Xeon 5500/Core i7 QuickPath Architecture Generic Non-Core Registers + +pci:v00008086d00002C50* + ID_PRODUCT_FROM_DATABASE=Core Processor QuickPath Architecture Generic Non-Core Registers + +pci:v00008086d00002C51* + ID_PRODUCT_FROM_DATABASE=Core Processor QuickPath Architecture Generic Non-Core Registers + +pci:v00008086d00002C52* + ID_PRODUCT_FROM_DATABASE=Core Processor QuickPath Architecture Generic Non-Core Registers + +pci:v00008086d00002C53* + ID_PRODUCT_FROM_DATABASE=Core Processor QuickPath Architecture Generic Non-Core Registers + +pci:v00008086d00002C54* + ID_PRODUCT_FROM_DATABASE=Core Processor QuickPath Architecture Generic Non-Core Registers + +pci:v00008086d00002C55* + ID_PRODUCT_FROM_DATABASE=Core Processor QuickPath Architecture Generic Non-Core Registers + +pci:v00008086d00002C56* + ID_PRODUCT_FROM_DATABASE=Core Processor QuickPath Architecture Generic Non-Core Registers + +pci:v00008086d00002C57* + ID_PRODUCT_FROM_DATABASE=Core Processor QuickPath Architecture Generic Non-Core Registers + +pci:v00008086d00002C58* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 QPI Generic Non-core Registers + +pci:v00008086d00002C59* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 QPI Generic Non-core Registers + +pci:v00008086d00002C5A* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 QPI Generic Non-core Registers + +pci:v00008086d00002C5B* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 QPI Generic Non-core Registers + +pci:v00008086d00002C5C* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 QPI Generic Non-core Registers + +pci:v00008086d00002C5D* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 QPI Generic Non-core Registers + +pci:v00008086d00002C5E* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 QPI Generic Non-core Registers + +pci:v00008086d00002C5F* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 QPI Generic Non-core Registers + +pci:v00008086d00002C61* + ID_PRODUCT_FROM_DATABASE=Core Processor QuickPath Architecture Generic Non-core Registers + +pci:v00008086d00002C62* + ID_PRODUCT_FROM_DATABASE=Core Processor QuickPath Architecture Generic Non-core Registers + +pci:v00008086d00002C70* + ID_PRODUCT_FROM_DATABASE=Xeon 5600 Series QuickPath Architecture Generic Non-core Registers + +pci:v00008086d00002C81* + ID_PRODUCT_FROM_DATABASE=Core Processor QuickPath Architecture System Address Decoder + +pci:v00008086d00002C90* + ID_PRODUCT_FROM_DATABASE=Core Processor QPI Link 0 + +pci:v00008086d00002C91* + ID_PRODUCT_FROM_DATABASE=Core Processor QPI Physical 0 + +pci:v00008086d00002C98* + ID_PRODUCT_FROM_DATABASE=Core Processor Integrated Memory Controller + +pci:v00008086d00002C99* + ID_PRODUCT_FROM_DATABASE=Core Processor Integrated Memory Controller Target Address Decoder + +pci:v00008086d00002C9A* + ID_PRODUCT_FROM_DATABASE=Core Processor Integrated Memory Controller Test Registers + +pci:v00008086d00002C9C* + ID_PRODUCT_FROM_DATABASE=Core Processor Integrated Memory Controller Test Registers + +pci:v00008086d00002CA0* + ID_PRODUCT_FROM_DATABASE=Core Processor Integrated Memory Controller Channel 0 Control Registers + +pci:v00008086d00002CA1* + ID_PRODUCT_FROM_DATABASE=Core Processor Integrated Memory Controller Channel 0 Address Registers + +pci:v00008086d00002CA2* + ID_PRODUCT_FROM_DATABASE=Core Processor Integrated Memory Controller Channel 0 Rank Registers + +pci:v00008086d00002CA3* + ID_PRODUCT_FROM_DATABASE=Core Processor Integrated Memory Controller Channel 0 Thermal Control Registers + +pci:v00008086d00002CA8* + ID_PRODUCT_FROM_DATABASE=Core Processor Integrated Memory Controller Channel 1 Control Registers + +pci:v00008086d00002CA9* + ID_PRODUCT_FROM_DATABASE=Core Processor Integrated Memory Controller Channel 1 Address Registers + +pci:v00008086d00002CAA* + ID_PRODUCT_FROM_DATABASE=Core Processor Integrated Memory Controller Channel 1 Rank Registers + +pci:v00008086d00002CAB* + ID_PRODUCT_FROM_DATABASE=Core Processor Integrated Memory Controller Channel 1 Thermal Control Registers + +pci:v00008086d00002CC1* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 QPI System Address Decoder + +pci:v00008086d00002CD0* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 QPI Link 0 + +pci:v00008086d00002CD1* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 QPI Physical 0 + +pci:v00008086d00002CD4* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 QPI Link 1 + +pci:v00008086d00002CD5* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 QPI Physical 1 + +pci:v00008086d00002CD8* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 Integrated Memory Controller Registers + +pci:v00008086d00002CD9* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 Integrated Memory Controller Target Address Decoder + +pci:v00008086d00002CDA* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 Integrated Memory Controller RAS Registers + +pci:v00008086d00002CDC* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 Integrated Memory Controller Test Registers + +pci:v00008086d00002CE0* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 Integrated Memory Controller Channel 0 Control + +pci:v00008086d00002CE1* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 Integrated Memory Controller Channel 0 Address + +pci:v00008086d00002CE2* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 Integrated Memory Controller Channel 0 Rank + +pci:v00008086d00002CE3* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 Integrated Memory Controller Channel 0 Thermal Control + +pci:v00008086d00002CE8* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 Integrated Memory Controller Channel 1 Control + +pci:v00008086d00002CE9* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 Integrated Memory Controller Channel 1 Address + +pci:v00008086d00002CEA* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 Integrated Memory Controller Channel 1 Rank + +pci:v00008086d00002CEB* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 Integrated Memory Controller Channel 1 Thermal Control + +pci:v00008086d00002CF0* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 Integrated Memory Controller Channel 2 Control + +pci:v00008086d00002CF1* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 Integrated Memory Controller Channel 2 Address + +pci:v00008086d00002CF2* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 Integrated Memory Controller Channel 2 Rank + +pci:v00008086d00002CF3* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 Integrated Memory Controller Channel 2 Thermal Control + +pci:v00008086d00002D01* + ID_PRODUCT_FROM_DATABASE=Core Processor QuickPath Architecture System Address Decoder + +pci:v00008086d00002D10* + ID_PRODUCT_FROM_DATABASE=Core Processor QPI Link 0 + +pci:v00008086d00002D11* + ID_PRODUCT_FROM_DATABASE=Core Processor QPI Physical 0 + +pci:v00008086d00002D12* + ID_PRODUCT_FROM_DATABASE=Core Processor Reserved + +pci:v00008086d00002D13* + ID_PRODUCT_FROM_DATABASE=Core Processor Reserved + +pci:v00008086d00002D81* + ID_PRODUCT_FROM_DATABASE=Xeon 5600 Series QuickPath Architecture System Address Decoder + +pci:v00008086d00002D90* + ID_PRODUCT_FROM_DATABASE=Xeon 5600 Series QPI Link 0 + +pci:v00008086d00002D91* + ID_PRODUCT_FROM_DATABASE=Xeon 5600 Series QPI Physical 0 + +pci:v00008086d00002D92* + ID_PRODUCT_FROM_DATABASE=Xeon 5600 Series Mirror Port Link 0 + +pci:v00008086d00002D93* + ID_PRODUCT_FROM_DATABASE=Xeon 5600 Series Mirror Port Link 1 + +pci:v00008086d00002D94* + ID_PRODUCT_FROM_DATABASE=Xeon 5600 Series QPI Link 1 + +pci:v00008086d00002D95* + ID_PRODUCT_FROM_DATABASE=Xeon 5600 Series QPI Physical 1 + +pci:v00008086d00002D98* + ID_PRODUCT_FROM_DATABASE=Xeon 5600 Series Integrated Memory Controller Registers + +pci:v00008086d00002D99* + ID_PRODUCT_FROM_DATABASE=Xeon 5600 Series Integrated Memory Controller Target Address Decoder + +pci:v00008086d00002D9A* + ID_PRODUCT_FROM_DATABASE=Xeon 5600 Series Integrated Memory Controller RAS Registers + +pci:v00008086d00002D9C* + ID_PRODUCT_FROM_DATABASE=Xeon 5600 Series Integrated Memory Controller Test Registers + +pci:v00008086d00002DA0* + ID_PRODUCT_FROM_DATABASE=Xeon 5600 Series Integrated Memory Controller Channel 0 Control + +pci:v00008086d00002DA1* + ID_PRODUCT_FROM_DATABASE=Xeon 5600 Series Integrated Memory Controller Channel 0 Address + +pci:v00008086d00002DA2* + ID_PRODUCT_FROM_DATABASE=Xeon 5600 Series Integrated Memory Controller Channel 0 Rank + +pci:v00008086d00002DA3* + ID_PRODUCT_FROM_DATABASE=Xeon 5600 Series Integrated Memory Controller Channel 0 Thermal Control + +pci:v00008086d00002DA8* + ID_PRODUCT_FROM_DATABASE=Xeon 5600 Series Integrated Memory Controller Channel 1 Control + +pci:v00008086d00002DA9* + ID_PRODUCT_FROM_DATABASE=Xeon 5600 Series Integrated Memory Controller Channel 1 Address + +pci:v00008086d00002DAA* + ID_PRODUCT_FROM_DATABASE=Xeon 5600 Series Integrated Memory Controller Channel 1 Rank + +pci:v00008086d00002DAB* + ID_PRODUCT_FROM_DATABASE=Xeon 5600 Series Integrated Memory Controller Channel 1 Thermal Control + +pci:v00008086d00002DB0* + ID_PRODUCT_FROM_DATABASE=Xeon 5600 Series Integrated Memory Controller Channel 2 Control + +pci:v00008086d00002DB1* + ID_PRODUCT_FROM_DATABASE=Xeon 5600 Series Integrated Memory Controller Channel 2 Address + +pci:v00008086d00002DB2* + ID_PRODUCT_FROM_DATABASE=Xeon 5600 Series Integrated Memory Controller Channel 2 Rank + +pci:v00008086d00002DB3* + ID_PRODUCT_FROM_DATABASE=Xeon 5600 Series Integrated Memory Controller Channel 2 Thermal Control + +pci:v00008086d00002E00* + ID_PRODUCT_FROM_DATABASE=4 Series Chipset DRAM Controller + +pci:v00008086d00002E01* + ID_PRODUCT_FROM_DATABASE=4 Series Chipset PCI Express Root Port + +pci:v00008086d00002E02* + ID_PRODUCT_FROM_DATABASE=4 Series Chipset Integrated Graphics Controller + +pci:v00008086d00002E03* + ID_PRODUCT_FROM_DATABASE=4 Series Chipset Integrated Graphics Controller + +pci:v00008086d00002E04* + ID_PRODUCT_FROM_DATABASE=4 Series Chipset HECI Controller + +pci:v00008086d00002E05* + ID_PRODUCT_FROM_DATABASE=4 Series Chipset HECI Controller + +pci:v00008086d00002E06* + ID_PRODUCT_FROM_DATABASE=4 Series Chipset PT IDER Controller + +pci:v00008086d00002E07* + ID_PRODUCT_FROM_DATABASE=4 Series Chipset Serial KT Controller + +pci:v00008086d00002E10* + ID_PRODUCT_FROM_DATABASE=4 Series Chipset DRAM Controller + +pci:v00008086d00002E11* + ID_PRODUCT_FROM_DATABASE=4 Series Chipset PCI Express Root Port + +pci:v00008086d00002E12* + ID_PRODUCT_FROM_DATABASE=4 Series Chipset Integrated Graphics Controller + +pci:v00008086d00002E13* + ID_PRODUCT_FROM_DATABASE=4 Series Chipset Integrated Graphics Controller + +pci:v00008086d00002E14* + ID_PRODUCT_FROM_DATABASE=4 Series Chipset HECI Controller + +pci:v00008086d00002E15* + ID_PRODUCT_FROM_DATABASE=4 Series Chipset HECI Controller + +pci:v00008086d00002E16* + ID_PRODUCT_FROM_DATABASE=4 Series Chipset PT IDER Controller + +pci:v00008086d00002E17* + ID_PRODUCT_FROM_DATABASE=4 Series Chipset Serial KT Controller + +pci:v00008086d00002E20* + ID_PRODUCT_FROM_DATABASE=4 Series Chipset DRAM Controller + +pci:v00008086d00002E20sv00001043sd000082D3* + ID_PRODUCT_FROM_DATABASE=P5Q Deluxe Motherboard + +pci:v00008086d00002E20sv00001458sd00005000* + ID_PRODUCT_FROM_DATABASE=GA-EP45-DS5/GA-EG45M-DS2H Motherboard + +pci:v00008086d00002E21* + ID_PRODUCT_FROM_DATABASE=4 Series Chipset PCI Express Root Port + +pci:v00008086d00002E21sv00001043sd000082D3* + ID_PRODUCT_FROM_DATABASE=P5Q Deluxe Motherboard + +pci:v00008086d00002E21sv00001458sd00005000* + ID_PRODUCT_FROM_DATABASE=GA-EP45-DS5 Motherboard + +pci:v00008086d00002E22* + ID_PRODUCT_FROM_DATABASE=4 Series Chipset Integrated Graphics Controller + +pci:v00008086d00002E22sv00001458sd0000D000* + ID_PRODUCT_FROM_DATABASE=GA-EG45M-DS2H Mainboard + +pci:v00008086d00002E23* + ID_PRODUCT_FROM_DATABASE=4 Series Chipset Integrated Graphics Controller + +pci:v00008086d00002E23sv00001458sd0000D000* + ID_PRODUCT_FROM_DATABASE=GA-EG45M-DS2H Mainboard + +pci:v00008086d00002E24* + ID_PRODUCT_FROM_DATABASE=4 Series Chipset HECI Controller + +pci:v00008086d00002E25* + ID_PRODUCT_FROM_DATABASE=4 Series Chipset HECI Controller + +pci:v00008086d00002E26* + ID_PRODUCT_FROM_DATABASE=4 Series Chipset PT IDER Controller + +pci:v00008086d00002E27* + ID_PRODUCT_FROM_DATABASE=4 Series Chipset Serial KT Controller + +pci:v00008086d00002E29* + ID_PRODUCT_FROM_DATABASE=4 Series Chipset PCI Express Root Port + +pci:v00008086d00002E30* + ID_PRODUCT_FROM_DATABASE=4 Series Chipset DRAM Controller + +pci:v00008086d00002E31* + ID_PRODUCT_FROM_DATABASE=4 Series Chipset PCI Express Root Port + +pci:v00008086d00002E32* + ID_PRODUCT_FROM_DATABASE=4 Series Chipset Integrated Graphics Controller + +pci:v00008086d00002E33* + ID_PRODUCT_FROM_DATABASE=4 Series Chipset Integrated Graphics Controller + +pci:v00008086d00002E34* + ID_PRODUCT_FROM_DATABASE=4 Series Chipset HECI Controller + +pci:v00008086d00002E35* + ID_PRODUCT_FROM_DATABASE=4 Series Chipset HECI Controller + +pci:v00008086d00002E36* + ID_PRODUCT_FROM_DATABASE=4 Series Chipset PT IDER Controller + +pci:v00008086d00002E37* + ID_PRODUCT_FROM_DATABASE=4 Series Chipset Serial KT Controller + +pci:v00008086d00002E40* + ID_PRODUCT_FROM_DATABASE=4 Series Chipset DRAM Controller + +pci:v00008086d00002E41* + ID_PRODUCT_FROM_DATABASE=4 Series Chipset PCI Express Root Port + +pci:v00008086d00002E42* + ID_PRODUCT_FROM_DATABASE=4 Series Chipset Integrated Graphics Controller + +pci:v00008086d00002E43* + ID_PRODUCT_FROM_DATABASE=4 Series Chipset Integrated Graphics Controller + +pci:v00008086d00002E44* + ID_PRODUCT_FROM_DATABASE=4 Series Chipset HECI Controller + +pci:v00008086d00002E45* + ID_PRODUCT_FROM_DATABASE=4 Series Chipset HECI Controller + +pci:v00008086d00002E46* + ID_PRODUCT_FROM_DATABASE=4 Series Chipset PT IDER Controller + +pci:v00008086d00002E47* + ID_PRODUCT_FROM_DATABASE=4 Series Chipset Serial KT Controller + +pci:v00008086d00002E50* + ID_PRODUCT_FROM_DATABASE=CE Media Processor CE3100 + +pci:v00008086d00002E52* + ID_PRODUCT_FROM_DATABASE=CE Media Processor Clock and Reset Controller + +pci:v00008086d00002E58* + ID_PRODUCT_FROM_DATABASE=CE Media Processor Interrupt Controller + +pci:v00008086d00002E5A* + ID_PRODUCT_FROM_DATABASE=CE Media Processor CE3100 A/V Bridge + +pci:v00008086d00002E5B* + ID_PRODUCT_FROM_DATABASE=Graphics Media Accelerator 500 Graphics + +pci:v00008086d00002E5C* + ID_PRODUCT_FROM_DATABASE=CE Media Processor Video Decoder + +pci:v00008086d00002E5D* + ID_PRODUCT_FROM_DATABASE=CE Media Processor Transport Stream Interface + +pci:v00008086d00002E5E* + ID_PRODUCT_FROM_DATABASE=CE Media Processor Transport Stream Processor 0 + +pci:v00008086d00002E5F* + ID_PRODUCT_FROM_DATABASE=CE Media Processor Audio DSP + +pci:v00008086d00002E60* + ID_PRODUCT_FROM_DATABASE=CE Media Processor Audio Interfaces + +pci:v00008086d00002E61* + ID_PRODUCT_FROM_DATABASE=CE Media Processor Video Display Controller + +pci:v00008086d00002E62* + ID_PRODUCT_FROM_DATABASE=CE Media Processor Video Processing Unit + +pci:v00008086d00002E63* + ID_PRODUCT_FROM_DATABASE=CE Media Processor HDMI Tx Interface + +pci:v00008086d00002E65* + ID_PRODUCT_FROM_DATABASE=CE Media Processor Expansion Bus Interface + +pci:v00008086d00002E66* + ID_PRODUCT_FROM_DATABASE=CE Media Processor UART + +pci:v00008086d00002E67* + ID_PRODUCT_FROM_DATABASE=CE Media Processor General Purpose I/Os + +pci:v00008086d00002E68* + ID_PRODUCT_FROM_DATABASE=CE Media Processor I2C Interface + +pci:v00008086d00002E69* + ID_PRODUCT_FROM_DATABASE=CE Media Processor Smart Card Interface + +pci:v00008086d00002E6A* + ID_PRODUCT_FROM_DATABASE=CE Media Processor SPI Master Interface + +pci:v00008086d00002E6E* + ID_PRODUCT_FROM_DATABASE=CE Media Processor Gigabit Ethernet Controller + +pci:v00008086d00002E6F* + ID_PRODUCT_FROM_DATABASE=CE Media Processor Media Timing Unit + +pci:v00008086d00002E70* + ID_PRODUCT_FROM_DATABASE=CE Media Processor USB + +pci:v00008086d00002E71* + ID_PRODUCT_FROM_DATABASE=CE Media Processor SATA + +pci:v00008086d00002E73* + ID_PRODUCT_FROM_DATABASE=CE Media Processor CE3100 PCI Express + +pci:v00008086d00002E90* + ID_PRODUCT_FROM_DATABASE=4 Series Chipset DRAM Controller + +pci:v00008086d00002E91* + ID_PRODUCT_FROM_DATABASE=4 Series Chipset PCI Express Root Port + +pci:v00008086d00002E92* + ID_PRODUCT_FROM_DATABASE=4 Series Chipset Integrated Graphics Controller + +pci:v00008086d00002E93* + ID_PRODUCT_FROM_DATABASE=4 Series Chipset Integrated Graphics Controller + +pci:v00008086d00002E94* + ID_PRODUCT_FROM_DATABASE=4 Series Chipset HECI Controller + +pci:v00008086d00002E95* + ID_PRODUCT_FROM_DATABASE=4 Series Chipset HECI Controller + +pci:v00008086d00002E96* + ID_PRODUCT_FROM_DATABASE=4 Series Chipset PT IDER Controller + +pci:v00008086d00003200* + ID_PRODUCT_FROM_DATABASE=GD31244 PCI-X SATA HBA + +pci:v00008086d00003200sv00001775sd0000C200* + ID_PRODUCT_FROM_DATABASE=C2K onboard SATA host bus adapter + +pci:v00008086d00003310* + ID_PRODUCT_FROM_DATABASE=IOP348 I/O Processor + +pci:v00008086d00003310sv00001054sd00003030* + ID_PRODUCT_FROM_DATABASE=HRA380 Hitachi RAID Adapter to PCIe + +pci:v00008086d00003310sv00001054sd00003034* + ID_PRODUCT_FROM_DATABASE=HRA381 Hitachi RAID Adapter to PCIe + +pci:v00008086d00003313* + ID_PRODUCT_FROM_DATABASE=IOP348 I/O Processor (SL8e) in IOC Mode SAS/SATA + +pci:v00008086d0000331B* + ID_PRODUCT_FROM_DATABASE=IOP348 I/O Processor (SL8x) in IOC Mode SAS/SATA + +pci:v00008086d00003331* + ID_PRODUCT_FROM_DATABASE=IOC340 I/O Controller (VV8e) SAS/SATA + +pci:v00008086d00003339* + ID_PRODUCT_FROM_DATABASE=IOC340 I/O Controller (VV8x) SAS/SATA + +pci:v00008086d00003340* + ID_PRODUCT_FROM_DATABASE=82855PM Processor to I/O Controller + +pci:v00008086d00003340sv00001014sd00000529* + ID_PRODUCT_FROM_DATABASE=Thinkpad T40 series + +pci:v00008086d00003340sv00001025sd0000005A* + ID_PRODUCT_FROM_DATABASE=TravelMate 290 + +pci:v00008086d00003340sv0000103Csd0000088C* + ID_PRODUCT_FROM_DATABASE=NC8000 laptop + +pci:v00008086d00003340sv0000103Csd00000890* + ID_PRODUCT_FROM_DATABASE=NC6000 laptop + +pci:v00008086d00003340sv0000103Csd000008B0* + ID_PRODUCT_FROM_DATABASE=tc1100 tablet + +pci:v00008086d00003340sv0000144Dsd0000C005* + ID_PRODUCT_FROM_DATABASE=X10 Laptop + +pci:v00008086d00003340sv0000144Dsd0000C00C* + ID_PRODUCT_FROM_DATABASE=P30/P35 notebook + +pci:v00008086d00003341* + ID_PRODUCT_FROM_DATABASE=82855PM Processor to AGP Controller + +pci:v00008086d00003341sv0000144Dsd0000C00C* + ID_PRODUCT_FROM_DATABASE=P30 notebook + +pci:v00008086d00003363* + ID_PRODUCT_FROM_DATABASE=IOC340 I/O Controller in IOC Mode SAS/SATA + +pci:v00008086d00003382* + ID_PRODUCT_FROM_DATABASE=81342 [Chevelon] I/O Processor (ATUe) + +pci:v00008086d000033C3* + ID_PRODUCT_FROM_DATABASE=IOP348 I/O Processor (SL8De) in IOC Mode SAS/SATA + +pci:v00008086d000033CB* + ID_PRODUCT_FROM_DATABASE=IOP348 I/O Processor (SL8Dx) in IOC Mode SAS/SATA + +pci:v00008086d00003400* + ID_PRODUCT_FROM_DATABASE=5520/5500/X58 I/O Hub to ESI Port + +pci:v00008086d00003401* + ID_PRODUCT_FROM_DATABASE=5520/5500/X58 I/O Hub to ESI Port + +pci:v00008086d00003402* + ID_PRODUCT_FROM_DATABASE=5520/5500/X58 I/O Hub to ESI Port + +pci:v00008086d00003403* + ID_PRODUCT_FROM_DATABASE=5500 I/O Hub to ESI Port + +pci:v00008086d00003403sv00001028sd00000236* + ID_PRODUCT_FROM_DATABASE=PowerEdge R610 I/O Hub to ESI Port + +pci:v00008086d00003403sv00001028sd00000287* + ID_PRODUCT_FROM_DATABASE=PowerEdge M610 I/O Hub to ESI Port + +pci:v00008086d00003403sv00001028sd0000028C* + ID_PRODUCT_FROM_DATABASE=PowerEdge R410 I/O Hub to ESI Port + +pci:v00008086d00003403sv00001028sd0000028D* + ID_PRODUCT_FROM_DATABASE=PowerEdge T410 I/O Hub to ESI Port + +pci:v00008086d00003403sv0000103Csd0000330B* + ID_PRODUCT_FROM_DATABASE=ProLiant ML150 G6 Server + +pci:v00008086d00003404* + ID_PRODUCT_FROM_DATABASE=5520/5500/X58 I/O Hub to ESI Port + +pci:v00008086d00003405* + ID_PRODUCT_FROM_DATABASE=5520/5500/X58 I/O Hub to ESI Port + +pci:v00008086d00003406* + ID_PRODUCT_FROM_DATABASE=5520 I/O Hub to ESI Port + +pci:v00008086d00003406sv0000103Csd0000330B* + ID_PRODUCT_FROM_DATABASE=ProLiant G6 series + +pci:v00008086d00003407* + ID_PRODUCT_FROM_DATABASE=5520/5500/X58 I/O Hub to ESI Port + +pci:v00008086d00003408* + ID_PRODUCT_FROM_DATABASE=5520/5500/X58 I/O Hub PCI Express Root Port 1 + +pci:v00008086d00003408sv0000103Csd0000330B* + ID_PRODUCT_FROM_DATABASE=ProLiant G6 series + +pci:v00008086d00003409* + ID_PRODUCT_FROM_DATABASE=5520/5500/X58 I/O Hub PCI Express Root Port 2 + +pci:v00008086d0000340A* + ID_PRODUCT_FROM_DATABASE=5520/5500/X58 I/O Hub PCI Express Root Port 3 + +pci:v00008086d0000340Asv0000103Csd0000330B* + ID_PRODUCT_FROM_DATABASE=ProLiant ML150 G6 Server + +pci:v00008086d0000340B* + ID_PRODUCT_FROM_DATABASE=5520/X58 I/O Hub PCI Express Root Port 4 + +pci:v00008086d0000340C* + ID_PRODUCT_FROM_DATABASE=5520/X58 I/O Hub PCI Express Root Port 5 + +pci:v00008086d0000340D* + ID_PRODUCT_FROM_DATABASE=5520/X58 I/O Hub PCI Express Root Port 6 + +pci:v00008086d0000340E* + ID_PRODUCT_FROM_DATABASE=5520/5500/X58 I/O Hub PCI Express Root Port 7 + +pci:v00008086d0000340Esv0000103Csd0000330B* + ID_PRODUCT_FROM_DATABASE=ProLiant ML150 G6 Server + +pci:v00008086d0000340F* + ID_PRODUCT_FROM_DATABASE=5520/5500/X58 I/O Hub PCI Express Root Port 8 + +pci:v00008086d00003410* + ID_PRODUCT_FROM_DATABASE=7500/5520/5500/X58 I/O Hub PCI Express Root Port 9 + +pci:v00008086d00003411* + ID_PRODUCT_FROM_DATABASE=7500/5520/5500/X58 I/O Hub PCI Express Root Port 10 + +pci:v00008086d00003418* + ID_PRODUCT_FROM_DATABASE=7500/5520/5500/X58 Physical Layer Port 0 + +pci:v00008086d00003419* + ID_PRODUCT_FROM_DATABASE=7500/5520/5500 Physical Layer Port 1 + +pci:v00008086d00003420* + ID_PRODUCT_FROM_DATABASE=7500/5520/5500/X58 I/O Hub PCI Express Root Port 0 + +pci:v00008086d00003421* + ID_PRODUCT_FROM_DATABASE=7500/5520/5500/X58 I/O Hub PCI Express Root Port 0 + +pci:v00008086d00003422* + ID_PRODUCT_FROM_DATABASE=7500/5520/5500/X58 I/O Hub GPIO and Scratch Pad Registers + +pci:v00008086d00003422sv0000103Csd0000330B* + ID_PRODUCT_FROM_DATABASE=ProLiant G6 series + +pci:v00008086d00003423* + ID_PRODUCT_FROM_DATABASE=7500/5520/5500/X58 I/O Hub Control Status and RAS Registers + +pci:v00008086d00003423sv0000103Csd0000330B* + ID_PRODUCT_FROM_DATABASE=ProLiant G6 series + +pci:v00008086d00003425* + ID_PRODUCT_FROM_DATABASE=7500/5520/5500/X58 Physical and Link Layer Registers Port 0 + +pci:v00008086d00003426* + ID_PRODUCT_FROM_DATABASE=7500/5520/5500/X58 Routing and Protocol Layer Registers Port 0 + +pci:v00008086d00003427* + ID_PRODUCT_FROM_DATABASE=7500/5520/5500 Physical and Link Layer Registers Port 1 + +pci:v00008086d00003428* + ID_PRODUCT_FROM_DATABASE=7500/5520/5500 Routing & Protocol Layer Register Port 1 + +pci:v00008086d00003429* + ID_PRODUCT_FROM_DATABASE=5520/5500/X58 Chipset QuickData Technology Device + +pci:v00008086d0000342A* + ID_PRODUCT_FROM_DATABASE=5520/5500/X58 Chipset QuickData Technology Device + +pci:v00008086d0000342B* + ID_PRODUCT_FROM_DATABASE=5520/5500/X58 Chipset QuickData Technology Device + +pci:v00008086d0000342C* + ID_PRODUCT_FROM_DATABASE=5520/5500/X58 Chipset QuickData Technology Device + +pci:v00008086d0000342D* + ID_PRODUCT_FROM_DATABASE=7500/5520/5500/X58 I/O Hub I/OxAPIC Interrupt Controller + +pci:v00008086d0000342E* + ID_PRODUCT_FROM_DATABASE=7500/5520/5500/X58 I/O Hub System Management Registers + +pci:v00008086d0000342Esv0000103Csd0000330B* + ID_PRODUCT_FROM_DATABASE=ProLiant G6 series + +pci:v00008086d0000342F* + ID_PRODUCT_FROM_DATABASE=7500/5520/5500/X58 Trusted Execution Technology Registers + +pci:v00008086d00003430* + ID_PRODUCT_FROM_DATABASE=5520/5500/X58 Chipset QuickData Technology Device + +pci:v00008086d00003431* + ID_PRODUCT_FROM_DATABASE=5520/5500/X58 Chipset QuickData Technology Device + +pci:v00008086d00003432* + ID_PRODUCT_FROM_DATABASE=5520/5500/X58 Chipset QuickData Technology Device + +pci:v00008086d00003433* + ID_PRODUCT_FROM_DATABASE=5520/5500/X58 Chipset QuickData Technology Device + +pci:v00008086d00003438* + ID_PRODUCT_FROM_DATABASE=7500/5520/5500/X58 I/O Hub Throttle Registers + +pci:v00008086d00003500* + ID_PRODUCT_FROM_DATABASE=6311ESB/6321ESB PCI Express Upstream Port + +pci:v00008086d00003500sv0000103Csd000031FE* + ID_PRODUCT_FROM_DATABASE=ProLiant DL140 G3 + +pci:v00008086d00003501* + ID_PRODUCT_FROM_DATABASE=6310ESB PCI Express Upstream Port + +pci:v00008086d00003504* + ID_PRODUCT_FROM_DATABASE=6311ESB/6321ESB I/OxAPIC Interrupt Controller + +pci:v00008086d00003505* + ID_PRODUCT_FROM_DATABASE=6310ESB I/OxAPIC Interrupt Controller + +pci:v00008086d0000350C* + ID_PRODUCT_FROM_DATABASE=6311ESB/6321ESB PCI Express to PCI-X Bridge + +pci:v00008086d0000350Csv0000103Csd000031FE* + ID_PRODUCT_FROM_DATABASE=ProLiant DL140 G3 + +pci:v00008086d0000350D* + ID_PRODUCT_FROM_DATABASE=6310ESB PCI Express to PCI-X Bridge + +pci:v00008086d00003510* + ID_PRODUCT_FROM_DATABASE=6311ESB/6321ESB PCI Express Downstream Port E1 + +pci:v00008086d00003510sv0000103Csd000031FE* + ID_PRODUCT_FROM_DATABASE=ProLiant DL140 G3 + +pci:v00008086d00003511* + ID_PRODUCT_FROM_DATABASE=6310ESB PCI Express Downstream Port E1 + +pci:v00008086d00003514* + ID_PRODUCT_FROM_DATABASE=6311ESB/6321ESB PCI Express Downstream Port E2 + +pci:v00008086d00003515* + ID_PRODUCT_FROM_DATABASE=6310ESB PCI Express Downstream Port E2 + +pci:v00008086d00003518* + ID_PRODUCT_FROM_DATABASE=6311ESB/6321ESB PCI Express Downstream Port E3 + +pci:v00008086d00003519* + ID_PRODUCT_FROM_DATABASE=6310ESB PCI Express Downstream Port E3 + +pci:v00008086d00003575* + ID_PRODUCT_FROM_DATABASE=82830M/MG/MP Host Bridge + +pci:v00008086d00003575sv00000E11sd00000030* + ID_PRODUCT_FROM_DATABASE=Evo N600c + +pci:v00008086d00003575sv00001014sd0000021D* + ID_PRODUCT_FROM_DATABASE=ThinkPad A/T/X Series + +pci:v00008086d00003575sv0000104Dsd000080E7* + ID_PRODUCT_FROM_DATABASE=VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP + +pci:v00008086d00003576* + ID_PRODUCT_FROM_DATABASE=82830M/MP AGP Bridge + +pci:v00008086d00003577* + ID_PRODUCT_FROM_DATABASE=82830M/MG Integrated Graphics Controller + +pci:v00008086d00003577sv00001014sd00000513* + ID_PRODUCT_FROM_DATABASE=ThinkPad A/T/X Series + +pci:v00008086d00003578* + ID_PRODUCT_FROM_DATABASE=82830M/MG/MP Host Bridge + +pci:v00008086d00003580* + ID_PRODUCT_FROM_DATABASE=82852/82855 GM/GME/PM/GMV Processor to I/O Controller + +pci:v00008086d00003580sv00001014sd0000055C* + ID_PRODUCT_FROM_DATABASE=ThinkPad R50e + +pci:v00008086d00003580sv00001028sd00000139* + ID_PRODUCT_FROM_DATABASE=Latitude D400 + +pci:v00008086d00003580sv00001028sd0000014F* + ID_PRODUCT_FROM_DATABASE=Latitude X300 + +pci:v00008086d00003580sv00001028sd00000152* + ID_PRODUCT_FROM_DATABASE=Latitude D500 + +pci:v00008086d00003580sv00001028sd00000163* + ID_PRODUCT_FROM_DATABASE=Latitude D505 + +pci:v00008086d00003580sv00001028sd0000018D* + ID_PRODUCT_FROM_DATABASE=Inspiron 700m/710m + +pci:v00008086d00003580sv00001028sd00000196* + ID_PRODUCT_FROM_DATABASE=Inspiron 5160 + +pci:v00008086d00003580sv0000114Asd00000582* + ID_PRODUCT_FROM_DATABASE=PC8 + +pci:v00008086d00003580sv00001734sd00001055* + ID_PRODUCT_FROM_DATABASE=Amilo M1420 + +pci:v00008086d00003580sv00001775sd000010D0* + ID_PRODUCT_FROM_DATABASE=V5D Single Board Computer + +pci:v00008086d00003580sv00001775sd0000CE90* + ID_PRODUCT_FROM_DATABASE=CE9 + +pci:v00008086d00003580sv00004C53sd000010B0* + ID_PRODUCT_FROM_DATABASE=CL9 mainboard + +pci:v00008086d00003580sv00004C53sd000010E0* + ID_PRODUCT_FROM_DATABASE=PSL09 PrPMC + +pci:v00008086d00003580sv0000E4BFsd00000CC9* + ID_PRODUCT_FROM_DATABASE=CC9-SAMBA + +pci:v00008086d00003580sv0000E4BFsd00000CD2* + ID_PRODUCT_FROM_DATABASE=CD2-BEBOP + +pci:v00008086d00003581* + ID_PRODUCT_FROM_DATABASE=82852/82855 GM/GME/PM/GMV Processor to AGP Controller + +pci:v00008086d00003581sv00001734sd00001055* + ID_PRODUCT_FROM_DATABASE=Amilo M1420 + +pci:v00008086d00003582* + ID_PRODUCT_FROM_DATABASE=82852/855GM Integrated Graphics Device + +pci:v00008086d00003582sv00001014sd00000562* + ID_PRODUCT_FROM_DATABASE=ThinkPad R50e + +pci:v00008086d00003582sv00001028sd00000139* + ID_PRODUCT_FROM_DATABASE=Latitude D400 + +pci:v00008086d00003582sv00001028sd0000014F* + ID_PRODUCT_FROM_DATABASE=Latitude X300 + +pci:v00008086d00003582sv00001028sd00000152* + ID_PRODUCT_FROM_DATABASE=Latitude D500 + +pci:v00008086d00003582sv00001028sd00000163* + ID_PRODUCT_FROM_DATABASE=Latitude D505 + +pci:v00008086d00003582sv00001028sd0000018D* + ID_PRODUCT_FROM_DATABASE=Inspiron 700m/710m + +pci:v00008086d00003582sv0000114Asd00000582* + ID_PRODUCT_FROM_DATABASE=PC8 integrated graphics + +pci:v00008086d00003582sv00001775sd000010D0* + ID_PRODUCT_FROM_DATABASE=V5D Single Board Computer VGA + +pci:v00008086d00003582sv00001775sd0000CE90* + ID_PRODUCT_FROM_DATABASE=CE9 + +pci:v00008086d00003582sv00004C53sd000010B0* + ID_PRODUCT_FROM_DATABASE=CL9 mainboard + +pci:v00008086d00003582sv00004C53sd000010E0* + ID_PRODUCT_FROM_DATABASE=PSL09 PrPMC + +pci:v00008086d00003582sv0000E4BFsd00000CC9* + ID_PRODUCT_FROM_DATABASE=CC9-SAMBA + +pci:v00008086d00003582sv0000E4BFsd00000CD2* + ID_PRODUCT_FROM_DATABASE=CD2-BEBOP + +pci:v00008086d00003584* + ID_PRODUCT_FROM_DATABASE=82852/82855 GM/GME/PM/GMV Processor to I/O Controller + +pci:v00008086d00003584sv00001014sd0000055D* + ID_PRODUCT_FROM_DATABASE=ThinkPad R50e + +pci:v00008086d00003584sv00001028sd00000139* + ID_PRODUCT_FROM_DATABASE=Latitude D400 + +pci:v00008086d00003584sv00001028sd0000014F* + ID_PRODUCT_FROM_DATABASE=Latitude X300 + +pci:v00008086d00003584sv00001028sd00000152* + ID_PRODUCT_FROM_DATABASE=Latitude D500 + +pci:v00008086d00003584sv00001028sd00000163* + ID_PRODUCT_FROM_DATABASE=Latitude D505 + +pci:v00008086d00003584sv00001028sd0000018D* + ID_PRODUCT_FROM_DATABASE=Inspiron 700m/710m + +pci:v00008086d00003584sv00001028sd00000196* + ID_PRODUCT_FROM_DATABASE=Inspiron 5160 + +pci:v00008086d00003584sv0000114Asd00000582* + ID_PRODUCT_FROM_DATABASE=PC8 + +pci:v00008086d00003584sv00001734sd00001055* + ID_PRODUCT_FROM_DATABASE=Amilo M1420 + +pci:v00008086d00003584sv00001775sd000010D0* + ID_PRODUCT_FROM_DATABASE=V5D Single Board Computer + +pci:v00008086d00003584sv00001775sd0000CE90* + ID_PRODUCT_FROM_DATABASE=CE9 + +pci:v00008086d00003584sv00004C53sd000010B0* + ID_PRODUCT_FROM_DATABASE=CL9 mainboard + +pci:v00008086d00003584sv00004C53sd000010E0* + ID_PRODUCT_FROM_DATABASE=PSL09 PrPMC + +pci:v00008086d00003585* + ID_PRODUCT_FROM_DATABASE=82852/82855 GM/GME/PM/GMV Processor to I/O Controller + +pci:v00008086d00003585sv00001014sd0000055E* + ID_PRODUCT_FROM_DATABASE=ThinkPad R50e + +pci:v00008086d00003585sv00001028sd00000139* + ID_PRODUCT_FROM_DATABASE=Latitude D400 + +pci:v00008086d00003585sv00001028sd0000014F* + ID_PRODUCT_FROM_DATABASE=Latitude X300 + +pci:v00008086d00003585sv00001028sd00000152* + ID_PRODUCT_FROM_DATABASE=Latitude D500 + +pci:v00008086d00003585sv00001028sd00000163* + ID_PRODUCT_FROM_DATABASE=Latitude D505 + +pci:v00008086d00003585sv00001028sd0000018D* + ID_PRODUCT_FROM_DATABASE=Inspiron 700m/710m + +pci:v00008086d00003585sv00001028sd00000196* + ID_PRODUCT_FROM_DATABASE=Inspiron 5160 + +pci:v00008086d00003585sv0000114Asd00000582* + ID_PRODUCT_FROM_DATABASE=PC8 + +pci:v00008086d00003585sv00001734sd00001055* + ID_PRODUCT_FROM_DATABASE=Amilo M1420 + +pci:v00008086d00003585sv00001775sd000010D0* + ID_PRODUCT_FROM_DATABASE=V5D Single Board Computer + +pci:v00008086d00003585sv00001775sd0000CE90* + ID_PRODUCT_FROM_DATABASE=CE9 + +pci:v00008086d00003585sv00004C53sd000010B0* + ID_PRODUCT_FROM_DATABASE=CL9 mainboard + +pci:v00008086d00003585sv00004C53sd000010E0* + ID_PRODUCT_FROM_DATABASE=PSL09 PrPMC + +pci:v00008086d0000358C* + ID_PRODUCT_FROM_DATABASE=82854 GMCH + +pci:v00008086d0000358E* + ID_PRODUCT_FROM_DATABASE=82854 GMCH Integrated Graphics Device + +pci:v00008086d00003590* + ID_PRODUCT_FROM_DATABASE=E7520 Memory Controller Hub + +pci:v00008086d00003590sv00001014sd000002DD* + ID_PRODUCT_FROM_DATABASE=eServer xSeries server mainboard + +pci:v00008086d00003590sv00001028sd0000016C* + ID_PRODUCT_FROM_DATABASE=PowerEdge 1850 Memory Controller Hub + +pci:v00008086d00003590sv00001028sd0000016D* + ID_PRODUCT_FROM_DATABASE=PowerEdge 2850 Memory Controller Hub + +pci:v00008086d00003590sv00001028sd0000019A* + ID_PRODUCT_FROM_DATABASE=PowerEdge SC1425 + +pci:v00008086d00003590sv00001734sd0000103E* + ID_PRODUCT_FROM_DATABASE=PRIMERGY RX/TX S2 series + +pci:v00008086d00003590sv00001775sd00001100* + ID_PRODUCT_FROM_DATABASE=CR11/VR11 Single Board Computer + +pci:v00008086d00003590sv00004C53sd000010D0* + ID_PRODUCT_FROM_DATABASE=Telum ASLP10 Processor AMC + +pci:v00008086d00003591* + ID_PRODUCT_FROM_DATABASE=E7525/E7520 Error Reporting Registers + +pci:v00008086d00003591sv00001014sd000002DD* + ID_PRODUCT_FROM_DATABASE=eServer xSeries server mainboard + +pci:v00008086d00003591sv00001028sd00000169* + ID_PRODUCT_FROM_DATABASE=Precision 470 + +pci:v00008086d00003591sv0000103Csd00003208* + ID_PRODUCT_FROM_DATABASE=ProLiant DL140 G2 + +pci:v00008086d00003591sv00004C53sd000010D0* + ID_PRODUCT_FROM_DATABASE=Telum ASLP10 Processor AMC + +pci:v00008086d00003592* + ID_PRODUCT_FROM_DATABASE=E7320 Memory Controller Hub + +pci:v00008086d00003593* + ID_PRODUCT_FROM_DATABASE=E7320 Error Reporting Registers + +pci:v00008086d00003594* + ID_PRODUCT_FROM_DATABASE=E7520 DMA Controller + +pci:v00008086d00003594sv00001775sd00001100* + ID_PRODUCT_FROM_DATABASE=CR11/VR11 Single Board Computer + +pci:v00008086d00003594sv00004C53sd000010D0* + ID_PRODUCT_FROM_DATABASE=Telum ASLP10 Processor AMC + +pci:v00008086d00003595* + ID_PRODUCT_FROM_DATABASE=E7525/E7520/E7320 PCI Express Port A + +pci:v00008086d00003595sv00001775sd00001100* + ID_PRODUCT_FROM_DATABASE=CR11/VR11 Single Board Computer + +pci:v00008086d00003596* + ID_PRODUCT_FROM_DATABASE=E7525/E7520/E7320 PCI Express Port A1 + +pci:v00008086d00003597* + ID_PRODUCT_FROM_DATABASE=E7525/E7520 PCI Express Port B + +pci:v00008086d00003597sv00001775sd00001100* + ID_PRODUCT_FROM_DATABASE=CR11/VR11 Single Board Computer + +pci:v00008086d00003598* + ID_PRODUCT_FROM_DATABASE=E7520 PCI Express Port B1 + +pci:v00008086d00003598sv00001775sd00001100* + ID_PRODUCT_FROM_DATABASE=CR11/VR11 Single Board Computer + +pci:v00008086d00003599* + ID_PRODUCT_FROM_DATABASE=E7520 PCI Express Port C + +pci:v00008086d00003599sv00001775sd00001100* + ID_PRODUCT_FROM_DATABASE=CR11/VR11 Single Board Computer + +pci:v00008086d0000359A* + ID_PRODUCT_FROM_DATABASE=E7520 PCI Express Port C1 + +pci:v00008086d0000359B* + ID_PRODUCT_FROM_DATABASE=E7525/E7520/E7320 Extended Configuration Registers + +pci:v00008086d0000359Bsv00001014sd000002DD* + ID_PRODUCT_FROM_DATABASE=eServer xSeries server mainboard + +pci:v00008086d0000359E* + ID_PRODUCT_FROM_DATABASE=E7525 Memory Controller Hub + +pci:v00008086d0000359Esv00001028sd00000169* + ID_PRODUCT_FROM_DATABASE=Precision 470 + +pci:v00008086d000035B0* + ID_PRODUCT_FROM_DATABASE=3100 Chipset Memory I/O Controller Hub + +pci:v00008086d000035B1* + ID_PRODUCT_FROM_DATABASE=3100 DRAM Controller Error Reporting Registers + +pci:v00008086d000035B5* + ID_PRODUCT_FROM_DATABASE=3100 Chipset Enhanced DMA Controller + +pci:v00008086d000035B6* + ID_PRODUCT_FROM_DATABASE=3100 Chipset PCI Express Port A + +pci:v00008086d000035B7* + ID_PRODUCT_FROM_DATABASE=3100 Chipset PCI Express Port A1 + +pci:v00008086d000035C8* + ID_PRODUCT_FROM_DATABASE=3100 Extended Configuration Test Overflow Registers + +pci:v00008086d00003600* + ID_PRODUCT_FROM_DATABASE=7300 Chipset Memory Controller Hub + +pci:v00008086d00003604* + ID_PRODUCT_FROM_DATABASE=7300 Chipset PCI Express Port 1 + +pci:v00008086d00003605* + ID_PRODUCT_FROM_DATABASE=7300 Chipset PCI Express Port 2 + +pci:v00008086d00003606* + ID_PRODUCT_FROM_DATABASE=7300 Chipset PCI Express Port 3 + +pci:v00008086d00003607* + ID_PRODUCT_FROM_DATABASE=7300 Chipset PCI Express Port 4 + +pci:v00008086d00003608* + ID_PRODUCT_FROM_DATABASE=7300 Chipset PCI Express Port 5 + +pci:v00008086d00003609* + ID_PRODUCT_FROM_DATABASE=7300 Chipset PCI Express Port 6 + +pci:v00008086d0000360A* + ID_PRODUCT_FROM_DATABASE=7300 Chipset PCI Express Port 7 + +pci:v00008086d0000360B* + ID_PRODUCT_FROM_DATABASE=7300 Chipset QuickData Technology Device + +pci:v00008086d0000360C* + ID_PRODUCT_FROM_DATABASE=7300 Chipset FSB Registers + +pci:v00008086d0000360Csv00001028sd000001F0* + ID_PRODUCT_FROM_DATABASE=PowerEdge R900 7300 Chipset FSB Registers + +pci:v00008086d0000360D* + ID_PRODUCT_FROM_DATABASE=7300 Chipset Snoop Filter Registers + +pci:v00008086d0000360E* + ID_PRODUCT_FROM_DATABASE=7300 Chipset Debug and Miscellaneous Registers + +pci:v00008086d0000360F* + ID_PRODUCT_FROM_DATABASE=7300 Chipset FBD Branch 0 Registers + +pci:v00008086d00003610* + ID_PRODUCT_FROM_DATABASE=7300 Chipset FBD Branch 1 Registers + +pci:v00008086d00003700* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 DMI + +pci:v00008086d00003701* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 DMI + +pci:v00008086d00003702* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 DMI + +pci:v00008086d00003703* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 DMI + +pci:v00008086d00003704* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 DMI + +pci:v00008086d00003705* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 DMI + +pci:v00008086d00003706* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 DMI + +pci:v00008086d00003707* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 DMI + +pci:v00008086d00003708* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 DMI + +pci:v00008086d00003709* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 DMI + +pci:v00008086d0000370A* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 DMI + +pci:v00008086d0000370B* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 DMI + +pci:v00008086d0000370C* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 DMI + +pci:v00008086d0000370D* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 DMI + +pci:v00008086d0000370E* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 DMI + +pci:v00008086d0000370F* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 DMI + +pci:v00008086d00003710* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 CB3 DMA + +pci:v00008086d00003711* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 CB3 DMA + +pci:v00008086d00003712* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 CB3 DMA + +pci:v00008086d00003713* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 CB3 DMA + +pci:v00008086d00003714* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 CB3 DMA + +pci:v00008086d00003715* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 CB3 DMA + +pci:v00008086d00003716* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 CB3 DMA + +pci:v00008086d00003717* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 CB3 DMA + +pci:v00008086d00003718* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 CB3 DMA + +pci:v00008086d00003719* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 CB3 DMA + +pci:v00008086d0000371A* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 QPI Link + +pci:v00008086d0000371B* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 QPI Routing and Protocol + +pci:v00008086d0000371D* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 QPI Routing and Protocol + +pci:v00008086d00003720* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 PCI Express Root Port 0 + +pci:v00008086d00003721* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 PCI Express Root Port 1 + +pci:v00008086d00003722* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 PCI Express Root Port 2 + +pci:v00008086d00003723* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 PCI Express Root Port 3 + +pci:v00008086d00003724* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 PCI Express Root Port 4 + +pci:v00008086d00003725* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 NTB Primary + +pci:v00008086d00003726* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 NTB Primary + +pci:v00008086d00003727* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 NTB Secondary + +pci:v00008086d00003728* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 Core + +pci:v00008086d00003729* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 Core + +pci:v00008086d0000372A* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 Core + +pci:v00008086d0000372B* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 Core + +pci:v00008086d0000372C* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 Reserved + +pci:v00008086d0000373F* + ID_PRODUCT_FROM_DATABASE=Xeon C5500/C3500 IOxAPIC + +pci:v00008086d00003A00* + ID_PRODUCT_FROM_DATABASE=82801JD/DO (ICH10 Family) 4-port SATA IDE Controller + +pci:v00008086d00003A02* + ID_PRODUCT_FROM_DATABASE=82801JD/DO (ICH10 Family) SATA AHCI Controller + +pci:v00008086d00003A05* + ID_PRODUCT_FROM_DATABASE=82801JD/DO (ICH10 Family) SATA RAID Controller + +pci:v00008086d00003A06* + ID_PRODUCT_FROM_DATABASE=82801JD/DO (ICH10 Family) 2-port SATA IDE Controller + +pci:v00008086d00003A14* + ID_PRODUCT_FROM_DATABASE=82801JDO (ICH10DO) LPC Interface Controller + +pci:v00008086d00003A16* + ID_PRODUCT_FROM_DATABASE=82801JIR (ICH10R) LPC Interface Controller + +pci:v00008086d00003A16sv00001028sd0000028C* + ID_PRODUCT_FROM_DATABASE=PowerEdge R410 LPC Interface Controller + +pci:v00008086d00003A16sv00001028sd0000028D* + ID_PRODUCT_FROM_DATABASE=PowerEdge T410 LPC Interface Controller + +pci:v00008086d00003A16sv0000103Csd0000330B* + ID_PRODUCT_FROM_DATABASE=ProLiant G6 series + +pci:v00008086d00003A16sv00001043sd000082D4* + ID_PRODUCT_FROM_DATABASE=P5Q Deluxe Motherboard + +pci:v00008086d00003A16sv00001458sd00005001* + ID_PRODUCT_FROM_DATABASE=GA-EP45-DS5 Motherboard + +pci:v00008086d00003A18* + ID_PRODUCT_FROM_DATABASE=82801JIB (ICH10) LPC Interface Controller + +pci:v00008086d00003A1A* + ID_PRODUCT_FROM_DATABASE=82801JD (ICH10D) LPC Interface Controller + +pci:v00008086d00003A20* + ID_PRODUCT_FROM_DATABASE=82801JI (ICH10 Family) 4 port SATA IDE Controller #1 + +pci:v00008086d00003A20sv00001028sd0000028C* + ID_PRODUCT_FROM_DATABASE=PowerEdge R410 SATA IDE Controller + +pci:v00008086d00003A20sv00001028sd0000028D* + ID_PRODUCT_FROM_DATABASE=PowerEdge T410 SATA IDE Controller + +pci:v00008086d00003A22* + ID_PRODUCT_FROM_DATABASE=82801JI (ICH10 Family) SATA AHCI Controller + +pci:v00008086d00003A22sv0000103Csd0000330B* + ID_PRODUCT_FROM_DATABASE=ProLiant G6 series + +pci:v00008086d00003A22sv00001043sd000082D4* + ID_PRODUCT_FROM_DATABASE=P5Q Deluxe Motherboard + +pci:v00008086d00003A22sv00001458sd0000B005* + ID_PRODUCT_FROM_DATABASE=GA-EP45-DS5/GA-EG45M-DS2H Motherboard + +pci:v00008086d00003A25* + ID_PRODUCT_FROM_DATABASE=82801JIR (ICH10R) SATA RAID Controller + +pci:v00008086d00003A25sv00001028sd0000028C* + ID_PRODUCT_FROM_DATABASE=PERC S100 Controller (PE R410) + +pci:v00008086d00003A25sv00001028sd0000028D* + ID_PRODUCT_FROM_DATABASE=PERC S100 Controller (PE T410) + +pci:v00008086d00003A25sv00001028sd000002F1* + ID_PRODUCT_FROM_DATABASE=PERC S100 Controller (PE R510) + +pci:v00008086d00003A26* + ID_PRODUCT_FROM_DATABASE=82801JI (ICH10 Family) 2 port SATA IDE Controller #2 + +pci:v00008086d00003A26sv00001028sd0000028C* + ID_PRODUCT_FROM_DATABASE=PowerEdge R410 SATA IDE Controller + +pci:v00008086d00003A26sv00001028sd0000028D* + ID_PRODUCT_FROM_DATABASE=PowerEdge T410 SATA IDE Controller + +pci:v00008086d00003A30* + ID_PRODUCT_FROM_DATABASE=82801JI (ICH10 Family) SMBus Controller + +pci:v00008086d00003A30sv00001043sd000082D4* + ID_PRODUCT_FROM_DATABASE=P5Q Deluxe Motherboard + +pci:v00008086d00003A30sv00001458sd00005001* + ID_PRODUCT_FROM_DATABASE=GA-EP45-DS5/GA-EG45M-DS2H Motherboard + +pci:v00008086d00003A32* + ID_PRODUCT_FROM_DATABASE=82801JI (ICH10 Family) Thermal Subsystem + +pci:v00008086d00003A34* + ID_PRODUCT_FROM_DATABASE=82801JI (ICH10 Family) USB UHCI Controller #1 + +pci:v00008086d00003A34sv00001028sd0000028C* + ID_PRODUCT_FROM_DATABASE=PowerEdge R410 USB UHCI Controller + +pci:v00008086d00003A34sv00001028sd0000028D* + ID_PRODUCT_FROM_DATABASE=PowerEdge T410 USB UHCI Controller + +pci:v00008086d00003A34sv0000103Csd0000330B* + ID_PRODUCT_FROM_DATABASE=ProLiant G6 series + +pci:v00008086d00003A34sv00001043sd000082D4* + ID_PRODUCT_FROM_DATABASE=P5Q Deluxe Motherboard + +pci:v00008086d00003A34sv00001458sd00005004* + ID_PRODUCT_FROM_DATABASE=GA-EP45-DS5 Motherboard + +pci:v00008086d00003A35* + ID_PRODUCT_FROM_DATABASE=82801JI (ICH10 Family) USB UHCI Controller #2 + +pci:v00008086d00003A35sv00001028sd0000028C* + ID_PRODUCT_FROM_DATABASE=PowerEdge R410 USB UHCI Controller + +pci:v00008086d00003A35sv00001028sd0000028D* + ID_PRODUCT_FROM_DATABASE=PowerEdge T410 USB UHCI Controller + +pci:v00008086d00003A35sv0000103Csd0000330B* + ID_PRODUCT_FROM_DATABASE=ProLiant G6 series + +pci:v00008086d00003A35sv00001043sd000082D4* + ID_PRODUCT_FROM_DATABASE=P5Q Deluxe Motherboard + +pci:v00008086d00003A35sv00001458sd00005004* + ID_PRODUCT_FROM_DATABASE=GA-EP45-DS5 Motherboard + +pci:v00008086d00003A36* + ID_PRODUCT_FROM_DATABASE=82801JI (ICH10 Family) USB UHCI Controller #3 + +pci:v00008086d00003A36sv00001028sd0000028C* + ID_PRODUCT_FROM_DATABASE=PowerEdge R410 USB UHCI Controller + +pci:v00008086d00003A36sv00001028sd0000028D* + ID_PRODUCT_FROM_DATABASE=PowerEdge T410 USB UHCI Controller + +pci:v00008086d00003A36sv0000103Csd0000330B* + ID_PRODUCT_FROM_DATABASE=ProLiant G6 series + +pci:v00008086d00003A36sv00001043sd000082D4* + ID_PRODUCT_FROM_DATABASE=P5Q Deluxe Motherboard + +pci:v00008086d00003A36sv00001458sd00005004* + ID_PRODUCT_FROM_DATABASE=GA-EP45-DS5 Motherboard + +pci:v00008086d00003A37* + ID_PRODUCT_FROM_DATABASE=82801JI (ICH10 Family) USB UHCI Controller #4 + +pci:v00008086d00003A37sv00001028sd0000028C* + ID_PRODUCT_FROM_DATABASE=PowerEdge R410 USB UHCI Controller + +pci:v00008086d00003A37sv00001028sd0000028D* + ID_PRODUCT_FROM_DATABASE=PowerEdge T410 USB UHCI Controller + +pci:v00008086d00003A37sv0000103Csd0000330B* + ID_PRODUCT_FROM_DATABASE=ProLiant G6 series + +pci:v00008086d00003A37sv00001043sd000082D4* + ID_PRODUCT_FROM_DATABASE=P5Q Deluxe Motherboard + +pci:v00008086d00003A37sv00001458sd00005004* + ID_PRODUCT_FROM_DATABASE=GA-EP45-DS5/GA-EG45M-DS2H Motherboard + +pci:v00008086d00003A38* + ID_PRODUCT_FROM_DATABASE=82801JI (ICH10 Family) USB UHCI Controller #5 + +pci:v00008086d00003A38sv00001028sd0000028C* + ID_PRODUCT_FROM_DATABASE=PowerEdge R410 USB UHCI Controller + +pci:v00008086d00003A38sv00001028sd0000028D* + ID_PRODUCT_FROM_DATABASE=PowerEdge T410 USB UHCI Controller + +pci:v00008086d00003A38sv0000103Csd0000330B* + ID_PRODUCT_FROM_DATABASE=ProLiant ML150 G6 Server + +pci:v00008086d00003A38sv00001043sd000082D4* + ID_PRODUCT_FROM_DATABASE=P5Q Deluxe Motherboard + +pci:v00008086d00003A38sv00001458sd00005004* + ID_PRODUCT_FROM_DATABASE=GA-EP45-DS5/GA-EG45M-DS2H Motherboard + +pci:v00008086d00003A39* + ID_PRODUCT_FROM_DATABASE=82801JI (ICH10 Family) USB UHCI Controller #6 + +pci:v00008086d00003A39sv00001028sd0000028C* + ID_PRODUCT_FROM_DATABASE=PowerEdge R410 USB UHCI Controller + +pci:v00008086d00003A39sv00001028sd0000028D* + ID_PRODUCT_FROM_DATABASE=PowerEdge T410 USB UHCI Controller + +pci:v00008086d00003A39sv0000103Csd0000330B* + ID_PRODUCT_FROM_DATABASE=ProLiant ML150 G6 Server + +pci:v00008086d00003A39sv00001043sd000082D4* + ID_PRODUCT_FROM_DATABASE=P5Q Deluxe Motherboard + +pci:v00008086d00003A39sv00001458sd00005004* + ID_PRODUCT_FROM_DATABASE=GA-EP45-DS5/GA-EG45M-DS2H Motherboard + +pci:v00008086d00003A3A* + ID_PRODUCT_FROM_DATABASE=82801JI (ICH10 Family) USB2 EHCI Controller #1 + +pci:v00008086d00003A3Asv00001028sd0000028C* + ID_PRODUCT_FROM_DATABASE=PowerEdge R410 USB EHCI Controller + +pci:v00008086d00003A3Asv00001028sd0000028D* + ID_PRODUCT_FROM_DATABASE=PowerEdge T410 USB EHCI Controller + +pci:v00008086d00003A3Asv0000103Csd0000330B* + ID_PRODUCT_FROM_DATABASE=ProLiant G6 series + +pci:v00008086d00003A3Asv00001043sd000082D4* + ID_PRODUCT_FROM_DATABASE=P5Q Deluxe Motherboard + +pci:v00008086d00003A3Asv00001458sd00005006* + ID_PRODUCT_FROM_DATABASE=GA-EP45-DS5 Motherboard + +pci:v00008086d00003A3C* + ID_PRODUCT_FROM_DATABASE=82801JI (ICH10 Family) USB2 EHCI Controller #2 + +pci:v00008086d00003A3Csv00001028sd0000028C* + ID_PRODUCT_FROM_DATABASE=PowerEdge R410 USB EHCI Controller + +pci:v00008086d00003A3Csv00001028sd0000028D* + ID_PRODUCT_FROM_DATABASE=PowerEdge T410 USB EHCI Controller + +pci:v00008086d00003A3Csv0000103Csd0000330B* + ID_PRODUCT_FROM_DATABASE=ProLiant G6 series + +pci:v00008086d00003A3Csv00001043sd000082D4* + ID_PRODUCT_FROM_DATABASE=P5Q Deluxe Motherboard + +pci:v00008086d00003A3Csv00001458sd00005006* + ID_PRODUCT_FROM_DATABASE=GA-EP45-DS5 Motherboard + +pci:v00008086d00003A3E* + ID_PRODUCT_FROM_DATABASE=82801JI (ICH10 Family) HD Audio Controller + +pci:v00008086d00003A3Esv00001043sd00008311* + ID_PRODUCT_FROM_DATABASE=P5Q Deluxe Motherboard + +pci:v00008086d00003A3Esv00001458sd0000A002* + ID_PRODUCT_FROM_DATABASE=GA-EP45-UD3R Motherboard + +pci:v00008086d00003A3Esv00001458sd0000A102* + ID_PRODUCT_FROM_DATABASE=GA-EP45-DS5/GA-EG45M-DS2H Motherboard + +pci:v00008086d00003A40* + ID_PRODUCT_FROM_DATABASE=82801JI (ICH10 Family) PCI Express Root Port 1 + +pci:v00008086d00003A40sv00001028sd0000028C* + ID_PRODUCT_FROM_DATABASE=PowerEdge R410 PCI Express Port 1 + +pci:v00008086d00003A40sv00001028sd0000028D* + ID_PRODUCT_FROM_DATABASE=PowerEdge T410 PCI Express Port 1 + +pci:v00008086d00003A40sv0000103Csd0000330B* + ID_PRODUCT_FROM_DATABASE=ProLiant ML150 G6 Server + +pci:v00008086d00003A40sv00001043sd000082D4* + ID_PRODUCT_FROM_DATABASE=P5Q Deluxe Motherboard + +pci:v00008086d00003A40sv00001043sd000082EA* + ID_PRODUCT_FROM_DATABASE=P6T DeLuxe Motherboard + +pci:v00008086d00003A40sv00001458sd00005001* + ID_PRODUCT_FROM_DATABASE=GA-EP45-DS5/GA-EG45M-DS2H Motherboard + +pci:v00008086d00003A42* + ID_PRODUCT_FROM_DATABASE=82801JI (ICH10 Family) PCI Express Port 2 + +pci:v00008086d00003A44* + ID_PRODUCT_FROM_DATABASE=82801JI (ICH10 Family) PCI Express Root Port 3 + +pci:v00008086d00003A44sv00001043sd000082EA* + ID_PRODUCT_FROM_DATABASE=P6T DeLuxe Motherboard + +pci:v00008086d00003A46* + ID_PRODUCT_FROM_DATABASE=82801JI (ICH10 Family) PCI Express Root Port 4 + +pci:v00008086d00003A46sv00001043sd000082EA* + ID_PRODUCT_FROM_DATABASE=P6T DeLuxe Motherboard + +pci:v00008086d00003A46sv00001458sd00005001* + ID_PRODUCT_FROM_DATABASE=GA-EP45-DS5 Motherboard + +pci:v00008086d00003A48* + ID_PRODUCT_FROM_DATABASE=82801JI (ICH10 Family) PCI Express Root Port 5 + +pci:v00008086d00003A48sv0000103Csd0000330B* + ID_PRODUCT_FROM_DATABASE=ProLiant ML150 G6 Server + +pci:v00008086d00003A48sv00001043sd000082EA* + ID_PRODUCT_FROM_DATABASE=P6T Deluxe Motherboard + +pci:v00008086d00003A48sv00001458sd00005001* + ID_PRODUCT_FROM_DATABASE=GA-EP45-DS5 Motherboard + +pci:v00008086d00003A4A* + ID_PRODUCT_FROM_DATABASE=82801JI (ICH10 Family) PCI Express Root Port 6 + +pci:v00008086d00003A4Asv0000103Csd0000330B* + ID_PRODUCT_FROM_DATABASE=ProLiant ML150 G6 Server + +pci:v00008086d00003A4Asv00001043sd000082D4* + ID_PRODUCT_FROM_DATABASE=P5Q Deluxe Motherboard + +pci:v00008086d00003A4Asv00001043sd000082EA* + ID_PRODUCT_FROM_DATABASE=P6T DeLuxe Motherboard + +pci:v00008086d00003A4Asv00001458sd00005001* + ID_PRODUCT_FROM_DATABASE=GA-EP45-DS5/GA-EG45M-DS2H Motherboard + +pci:v00008086d00003A4C* + ID_PRODUCT_FROM_DATABASE=82801JI (ICH10 Family) Gigabit Ethernet Controller + +pci:v00008086d00003A51* + ID_PRODUCT_FROM_DATABASE=82801JDO (ICH10DO) VECI Controller + +pci:v00008086d00003A55* + ID_PRODUCT_FROM_DATABASE=82801JD/DO (ICH10 Family) Virtual SATA Controller + +pci:v00008086d00003A60* + ID_PRODUCT_FROM_DATABASE=82801JD/DO (ICH10 Family) SMBus Controller + +pci:v00008086d00003A62* + ID_PRODUCT_FROM_DATABASE=82801JD/DO (ICH10 Family) Thermal Subsystem + +pci:v00008086d00003A64* + ID_PRODUCT_FROM_DATABASE=82801JD/DO (ICH10 Family) USB UHCI Controller #1 + +pci:v00008086d00003A65* + ID_PRODUCT_FROM_DATABASE=82801JD/DO (ICH10 Family) USB UHCI Controller #2 + +pci:v00008086d00003A66* + ID_PRODUCT_FROM_DATABASE=82801JD/DO (ICH10 Family) USB UHCI Controller #3 + +pci:v00008086d00003A67* + ID_PRODUCT_FROM_DATABASE=82801JD/DO (ICH10 Family) USB UHCI Controller #4 + +pci:v00008086d00003A68* + ID_PRODUCT_FROM_DATABASE=82801JD/DO (ICH10 Family) USB UHCI Controller #5 + +pci:v00008086d00003A69* + ID_PRODUCT_FROM_DATABASE=82801JD/DO (ICH10 Family) USB UHCI Controller #6 + +pci:v00008086d00003A6A* + ID_PRODUCT_FROM_DATABASE=82801JD/DO (ICH10 Family) USB2 EHCI Controller #1 + +pci:v00008086d00003A6C* + ID_PRODUCT_FROM_DATABASE=82801JD/DO (ICH10 Family) USB2 EHCI Controller #2 + +pci:v00008086d00003A6E* + ID_PRODUCT_FROM_DATABASE=82801JD/DO (ICH10 Family) HD Audio Controller + +pci:v00008086d00003A70* + ID_PRODUCT_FROM_DATABASE=82801JD/DO (ICH10 Family) PCI Express Port 1 + +pci:v00008086d00003A72* + ID_PRODUCT_FROM_DATABASE=82801JD/DO (ICH10 Family) PCI Express Port 2 + +pci:v00008086d00003A74* + ID_PRODUCT_FROM_DATABASE=82801JD/DO (ICH10 Family) PCI Express Port 3 + +pci:v00008086d00003A76* + ID_PRODUCT_FROM_DATABASE=82801JD/DO (ICH10 Family) PCI Express Port 4 + +pci:v00008086d00003A78* + ID_PRODUCT_FROM_DATABASE=82801JD/DO (ICH10 Family) PCI Express Port 5 + +pci:v00008086d00003A7A* + ID_PRODUCT_FROM_DATABASE=82801JD/DO (ICH10 Family) PCI Express Port 6 + +pci:v00008086d00003A7C* + ID_PRODUCT_FROM_DATABASE=82801JD/DO (ICH10 Family) Gigabit Ethernet Controller + +pci:v00008086d00003B00* + ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset LPC Interface Controller + +pci:v00008086d00003B01* + ID_PRODUCT_FROM_DATABASE=Mobile 5 Series Chipset LPC Interface Controller + +pci:v00008086d00003B02* + ID_PRODUCT_FROM_DATABASE=5 Series Chipset LPC Interface Controller + +pci:v00008086d00003B03* + ID_PRODUCT_FROM_DATABASE=Mobile 5 Series Chipset LPC Interface Controller + +pci:v00008086d00003B04* + ID_PRODUCT_FROM_DATABASE=5 Series Chipset LPC Interface Controller + +pci:v00008086d00003B05* + ID_PRODUCT_FROM_DATABASE=Mobile 5 Series Chipset LPC Interface Controller + +pci:v00008086d00003B06* + ID_PRODUCT_FROM_DATABASE=5 Series Chipset LPC Interface Controller + +pci:v00008086d00003B07* + ID_PRODUCT_FROM_DATABASE=Mobile 5 Series Chipset LPC Interface Controller + +pci:v00008086d00003B07sv00001028sd0000040B* + ID_PRODUCT_FROM_DATABASE=Latitude E6510 + +pci:v00008086d00003B07sv0000E4BFsd000050C1* + ID_PRODUCT_FROM_DATABASE=PC1-GROOVE + +pci:v00008086d00003B08* + ID_PRODUCT_FROM_DATABASE=5 Series Chipset LPC Interface Controller + +pci:v00008086d00003B09* + ID_PRODUCT_FROM_DATABASE=Mobile 5 Series Chipset LPC Interface Controller + +pci:v00008086d00003B09sv00001025sd00000347* + ID_PRODUCT_FROM_DATABASE=Aspire 7740G + +pci:v00008086d00003B0A* + ID_PRODUCT_FROM_DATABASE=5 Series Chipset LPC Interface Controller + +pci:v00008086d00003B0Asv00001028sd000002DA* + ID_PRODUCT_FROM_DATABASE=OptiPlex 980 + +pci:v00008086d00003B0B* + ID_PRODUCT_FROM_DATABASE=Mobile 5 Series Chipset LPC Interface Controller + +pci:v00008086d00003B0C* + ID_PRODUCT_FROM_DATABASE=5 Series Chipset LPC Interface Controller + +pci:v00008086d00003B0D* + ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset LPC Interface Controller + +pci:v00008086d00003B0E* + ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset LPC Interface Controller + +pci:v00008086d00003B0F* + ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset LPC Interface Controller + +pci:v00008086d00003B10* + ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset LPC Interface Controller + +pci:v00008086d00003B11* + ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset LPC Interface Controller + +pci:v00008086d00003B12* + ID_PRODUCT_FROM_DATABASE=3400 Series Chipset LPC Interface Controller + +pci:v00008086d00003B13* + ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset LPC Interface Controller + +pci:v00008086d00003B14* + ID_PRODUCT_FROM_DATABASE=3400 Series Chipset LPC Interface Controller + +pci:v00008086d00003B15* + ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset LPC Interface Controller + +pci:v00008086d00003B16* + ID_PRODUCT_FROM_DATABASE=3400 Series Chipset LPC Interface Controller + +pci:v00008086d00003B17* + ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset LPC Interface Controller + +pci:v00008086d00003B18* + ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset LPC Interface Controller + +pci:v00008086d00003B19* + ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset LPC Interface Controller + +pci:v00008086d00003B1A* + ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset LPC Interface Controller + +pci:v00008086d00003B1B* + ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset LPC Interface Controller + +pci:v00008086d00003B1C* + ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset LPC Interface Controller + +pci:v00008086d00003B1D* + ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset LPC Interface Controller + +pci:v00008086d00003B1E* + ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset LPC Interface Controller + +pci:v00008086d00003B1F* + ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset LPC Interface Controller + +pci:v00008086d00003B20* + ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset 4 port SATA IDE Controller + +pci:v00008086d00003B21* + ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset 2 port SATA IDE Controller + +pci:v00008086d00003B22* + ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset 6 port SATA AHCI Controller + +pci:v00008086d00003B22sv00001028sd000002DA* + ID_PRODUCT_FROM_DATABASE=OptiPlex 980 + +pci:v00008086d00003B23* + ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset 4 port SATA AHCI Controller + +pci:v00008086d00003B25* + ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset SATA RAID Controller + +pci:v00008086d00003B26* + ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset 2 port SATA IDE Controller + +pci:v00008086d00003B28* + ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset 4 port SATA IDE Controller + +pci:v00008086d00003B29* + ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset 4 port SATA AHCI Controller + +pci:v00008086d00003B29sv00001025sd00000347* + ID_PRODUCT_FROM_DATABASE=Aspire 7740G + +pci:v00008086d00003B2C* + ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset SATA RAID Controller + +pci:v00008086d00003B2D* + ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset 2 port SATA IDE Controller + +pci:v00008086d00003B2Dsv0000E4BFsd000050C1* + ID_PRODUCT_FROM_DATABASE=PC1-GROOVE + +pci:v00008086d00003B2E* + ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset 4 port SATA IDE Controller + +pci:v00008086d00003B2Esv0000E4BFsd000050C1* + ID_PRODUCT_FROM_DATABASE=PC1-GROOVE + +pci:v00008086d00003B2F* + ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset 6 port SATA AHCI Controller + +pci:v00008086d00003B2Fsv00001028sd0000040B* + ID_PRODUCT_FROM_DATABASE=Latitude E6510 + +pci:v00008086d00003B2Fsv0000E4BFsd000050C1* + ID_PRODUCT_FROM_DATABASE=PC1-GROOVE + +pci:v00008086d00003B30* + ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset SMBus Controller + +pci:v00008086d00003B30sv00001025sd00000347* + ID_PRODUCT_FROM_DATABASE=Aspire 7740G + +pci:v00008086d00003B30sv00001028sd000002DA* + ID_PRODUCT_FROM_DATABASE=OptiPlex 980 + +pci:v00008086d00003B30sv00001028sd0000040B* + ID_PRODUCT_FROM_DATABASE=Latitude E6510 + +pci:v00008086d00003B30sv0000E4BFsd000050C1* + ID_PRODUCT_FROM_DATABASE=PC1-GROOVE + +pci:v00008086d00003B32* + ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset Thermal Subsystem + +pci:v00008086d00003B32sv00001025sd00000347* + ID_PRODUCT_FROM_DATABASE=Aspire 7740G + +pci:v00008086d00003B34* + ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset USB2 Enhanced Host Controller + +pci:v00008086d00003B34sv00001025sd00000347* + ID_PRODUCT_FROM_DATABASE=Aspire 7740G + +pci:v00008086d00003B34sv00001028sd000002DA* + ID_PRODUCT_FROM_DATABASE=OptiPlex 980 + +pci:v00008086d00003B34sv00001028sd0000040B* + ID_PRODUCT_FROM_DATABASE=Latitude E6510 + +pci:v00008086d00003B34sv0000E4BFsd000050C1* + ID_PRODUCT_FROM_DATABASE=PC1-GROOVE + +pci:v00008086d00003B36* + ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset USB Universal Host Controller + +pci:v00008086d00003B37* + ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset USB Universal Host Controller + +pci:v00008086d00003B38* + ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset USB Universal Host Controller + +pci:v00008086d00003B39* + ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset USB Universal Host Controller + +pci:v00008086d00003B3A* + ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset USB Universal Host Controller + +pci:v00008086d00003B3B* + ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset USB Universal Host Controller + +pci:v00008086d00003B3C* + ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset USB2 Enhanced Host Controller + +pci:v00008086d00003B3Csv00001025sd00000347* + ID_PRODUCT_FROM_DATABASE=Aspire 7740G + +pci:v00008086d00003B3Csv00001028sd000002DA* + ID_PRODUCT_FROM_DATABASE=OptiPlex 980 + +pci:v00008086d00003B3Csv00001028sd0000040B* + ID_PRODUCT_FROM_DATABASE=Latitude E6510 + +pci:v00008086d00003B3Csv0000E4BFsd000050C1* + ID_PRODUCT_FROM_DATABASE=PC1-GROOVE + +pci:v00008086d00003B3E* + ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset USB Universal Host Controller + +pci:v00008086d00003B3F* + ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset USB Universal Host Controller + +pci:v00008086d00003B40* + ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset USB Universal Host Controller + +pci:v00008086d00003B41* + ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset LAN Controller + +pci:v00008086d00003B42* + ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset PCI Express Root Port 1 + +pci:v00008086d00003B42sv00001028sd000002DA* + ID_PRODUCT_FROM_DATABASE=OptiPlex 980 + +pci:v00008086d00003B42sv00001028sd0000040B* + ID_PRODUCT_FROM_DATABASE=Latitude E6510 + +pci:v00008086d00003B44* + ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset PCI Express Root Port 2 + +pci:v00008086d00003B44sv00001028sd0000040B* + ID_PRODUCT_FROM_DATABASE=Latitude E6510 + +pci:v00008086d00003B46* + ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset PCI Express Root Port 3 + +pci:v00008086d00003B46sv00001028sd0000040B* + ID_PRODUCT_FROM_DATABASE=Latitude E6510 + +pci:v00008086d00003B48* + ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset PCI Express Root Port 4 + +pci:v00008086d00003B48sv00001028sd0000040B* + ID_PRODUCT_FROM_DATABASE=Latitude E6510 + +pci:v00008086d00003B4A* + ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset PCI Express Root Port 5 + +pci:v00008086d00003B4Asv00001028sd000002DA* + ID_PRODUCT_FROM_DATABASE=OptiPlex 980 + +pci:v00008086d00003B4C* + ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset PCI Express Root Port 6 + +pci:v00008086d00003B4E* + ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset PCI Express Root Port 7 + +pci:v00008086d00003B50* + ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset PCI Express Root Port 8 + +pci:v00008086d00003B53* + ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset VECI Controller + +pci:v00008086d00003B56* + ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset High Definition Audio + +pci:v00008086d00003B56sv00001025sd00000347* + ID_PRODUCT_FROM_DATABASE=Aspire 7740G + +pci:v00008086d00003B56sv00001028sd000002DA* + ID_PRODUCT_FROM_DATABASE=OptiPlex 980 + +pci:v00008086d00003B56sv00001028sd0000040B* + ID_PRODUCT_FROM_DATABASE=Latitude E6510 + +pci:v00008086d00003B56sv0000E4BFsd000050C1* + ID_PRODUCT_FROM_DATABASE=PC1-GROOVE + +pci:v00008086d00003B57* + ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset High Definition Audio + +pci:v00008086d00003B64* + ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset HECI Controller + +pci:v00008086d00003B64sv00001025sd00000347* + ID_PRODUCT_FROM_DATABASE=Aspire 7740G + +pci:v00008086d00003B64sv0000E4BFsd000050C1* + ID_PRODUCT_FROM_DATABASE=PC1-GROOVE + +pci:v00008086d00003B65* + ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset HECI Controller + +pci:v00008086d00003B66* + ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset PT IDER Controller + +pci:v00008086d00003B67* + ID_PRODUCT_FROM_DATABASE=5 Series/3400 Series Chipset KT Controller + +pci:v00008086d00003B67sv0000E4BFsd000050C1* + ID_PRODUCT_FROM_DATABASE=PC1-GROOVE + +pci:v00008086d00003C00* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 DMI2 + +pci:v00008086d00003C01* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 DMI2 in PCI Express Mode + +pci:v00008086d00003C02* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 IIO PCI Express Root Port 1a + +pci:v00008086d00003C03* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 IIO PCI Express Root Port 1b + +pci:v00008086d00003C04* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 IIO PCI Express Root Port 2a + +pci:v00008086d00003C05* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 IIO PCI Express Root Port 2b + +pci:v00008086d00003C06* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 IIO PCI Express Root Port 2c + +pci:v00008086d00003C07* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 IIO PCI Express Root Port 2d + +pci:v00008086d00003C08* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 IIO PCI Express Root Port 3a in PCI Express Mode + +pci:v00008086d00003C09* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 IIO PCI Express Root Port 3b + +pci:v00008086d00003C0A* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 IIO PCI Express Root Port 3c + +pci:v00008086d00003C0B* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 IIO PCI Express Root Port 3d + +pci:v00008086d00003C0D* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Non-Transparent Bridge + +pci:v00008086d00003C0E* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Non-Transparent Bridge + +pci:v00008086d00003C0F* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Non-Transparent Bridge + +pci:v00008086d00003C20* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 DMA Channel 0 + +pci:v00008086d00003C21* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 DMA Channel 1 + +pci:v00008086d00003C22* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 DMA Channel 2 + +pci:v00008086d00003C23* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 DMA Channel 3 + +pci:v00008086d00003C24* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 DMA Channel 4 + +pci:v00008086d00003C25* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 DMA Channel 5 + +pci:v00008086d00003C26* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 DMA Channel 6 + +pci:v00008086d00003C27* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 DMA Channel 7 + +pci:v00008086d00003C28* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Address Map, VTd_Misc, System Management + +pci:v00008086d00003C2A* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Control Status and Global Errors + +pci:v00008086d00003C2C* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 I/O APIC + +pci:v00008086d00003C2E* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 DMA + +pci:v00008086d00003C2F* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 DMA + +pci:v00008086d00003C40* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 IIO Switch and IRP Performance Monitor + +pci:v00008086d00003C43* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Ring to PCI Express Performance Monitor + +pci:v00008086d00003C44* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Ring to QuickPath Interconnect Link 0 Performance Monitor + +pci:v00008086d00003C45* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Ring to QuickPath Interconnect Link 1 Performance Monitor + +pci:v00008086d00003C46* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Processor Home Agent Performance Monitoring + +pci:v00008086d00003C71* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Integrated Memory Controller RAS Registers + +pci:v00008086d00003C80* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 QPI Link 0 + +pci:v00008086d00003C83* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 QPI Link Reut 0 + +pci:v00008086d00003C84* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 QPI Link Reut 0 + +pci:v00008086d00003C90* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 QPI Link 1 + +pci:v00008086d00003C93* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 QPI Link Reut 1 + +pci:v00008086d00003C94* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 QPI Link Reut 1 + +pci:v00008086d00003CA0* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Processor Home Agent + +pci:v00008086d00003CA8* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Integrated Memory Controller Registers + +pci:v00008086d00003CAA* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Integrated Memory Controller Target Address Decoder 0 + +pci:v00008086d00003CAB* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Integrated Memory Controller Target Address Decoder 1 + +pci:v00008086d00003CAC* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Integrated Memory Controller Target Address Decoder 2 + +pci:v00008086d00003CAD* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Integrated Memory Controller Target Address Decoder 3 + +pci:v00008086d00003CAE* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Integrated Memory Controller Target Address Decoder 4 + +pci:v00008086d00003CB0* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Integrated Memory Controller Channel 0-3 Thermal Control 0 + +pci:v00008086d00003CB1* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Integrated Memory Controller Channel 0-3 Thermal Control 1 + +pci:v00008086d00003CB2* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Integrated Memory Controller ERROR Registers 0 + +pci:v00008086d00003CB3* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Integrated Memory Controller ERROR Registers 1 + +pci:v00008086d00003CB4* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Integrated Memory Controller Channel 0-3 Thermal Control 2 + +pci:v00008086d00003CB5* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Integrated Memory Controller Channel 0-3 Thermal Control 3 + +pci:v00008086d00003CB6* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Integrated Memory Controller ERROR Registers 2 + +pci:v00008086d00003CB7* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Integrated Memory Controller ERROR Registers 3 + +pci:v00008086d00003CB8* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 DDRIO + +pci:v00008086d00003CC0* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Power Control Unit 0 + +pci:v00008086d00003CC1* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Power Control Unit 1 + +pci:v00008086d00003CC2* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Power Control Unit 2 + +pci:v00008086d00003CD0* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Power Control Unit 3 + +pci:v00008086d00003CE0* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Interrupt Control Registers + +pci:v00008086d00003CE3* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Semaphore and Scratchpad Configuration Registers + +pci:v00008086d00003CE4* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 R2PCIe + +pci:v00008086d00003CE6* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 QuickPath Interconnect Agent Ring Registers + +pci:v00008086d00003CE8* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Unicast Register 0 + +pci:v00008086d00003CE9* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Unicast Register 5 + +pci:v00008086d00003CEA* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Unicast Register 1 + +pci:v00008086d00003CEB* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Unicast Register 6 + +pci:v00008086d00003CEC* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Unicast Register 3 + +pci:v00008086d00003CED* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Unicast Register 7 + +pci:v00008086d00003CEE* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Unicast Register 4 + +pci:v00008086d00003CEF* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Unicast Register 8 + +pci:v00008086d00003CF4* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Integrated Memory Controller System Address Decoder 0 + +pci:v00008086d00003CF5* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 Integrated Memory Controller System Address Decoder 1 + +pci:v00008086d00003CF6* + ID_PRODUCT_FROM_DATABASE=Xeon E5/Core i7 System Address Decoder + +pci:v00008086d00004000* + ID_PRODUCT_FROM_DATABASE=5400 Chipset Memory Controller Hub + +pci:v00008086d00004001* + ID_PRODUCT_FROM_DATABASE=5400 Chipset Memory Controller Hub + +pci:v00008086d00004003* + ID_PRODUCT_FROM_DATABASE=5400 Chipset Memory Controller Hub + +pci:v00008086d00004021* + ID_PRODUCT_FROM_DATABASE=5400 Chipset PCI Express Port 1 + +pci:v00008086d00004022* + ID_PRODUCT_FROM_DATABASE=5400 Chipset PCI Express Port 2 + +pci:v00008086d00004023* + ID_PRODUCT_FROM_DATABASE=5400 Chipset PCI Express Port 3 + +pci:v00008086d00004024* + ID_PRODUCT_FROM_DATABASE=5400 Chipset PCI Express Port 4 + +pci:v00008086d00004025* + ID_PRODUCT_FROM_DATABASE=5400 Chipset PCI Express Port 5 + +pci:v00008086d00004026* + ID_PRODUCT_FROM_DATABASE=5400 Chipset PCI Express Port 6 + +pci:v00008086d00004027* + ID_PRODUCT_FROM_DATABASE=5400 Chipset PCI Express Port 7 + +pci:v00008086d00004028* + ID_PRODUCT_FROM_DATABASE=5400 Chipset PCI Express Port 8 + +pci:v00008086d00004029* + ID_PRODUCT_FROM_DATABASE=5400 Chipset PCI Express Port 9 + +pci:v00008086d0000402D* + ID_PRODUCT_FROM_DATABASE=5400 Chipset IBIST Registers + +pci:v00008086d0000402E* + ID_PRODUCT_FROM_DATABASE=5400 Chipset IBIST Registers + +pci:v00008086d0000402F* + ID_PRODUCT_FROM_DATABASE=5400 Chipset QuickData Technology Device + +pci:v00008086d00004030* + ID_PRODUCT_FROM_DATABASE=5400 Chipset FSB Registers + +pci:v00008086d00004031* + ID_PRODUCT_FROM_DATABASE=5400 Chipset CE/SF Registers + +pci:v00008086d00004032* + ID_PRODUCT_FROM_DATABASE=5400 Chipset IOxAPIC + +pci:v00008086d00004035* + ID_PRODUCT_FROM_DATABASE=5400 Chipset FBD Registers + +pci:v00008086d00004036* + ID_PRODUCT_FROM_DATABASE=5400 Chipset FBD Registers + +pci:v00008086d00004100* + ID_PRODUCT_FROM_DATABASE=Moorestown Graphics and Video + +pci:v00008086d00004108* + ID_PRODUCT_FROM_DATABASE=Atom Processor E6xx Integrated Graphics Controller + +pci:v00008086d00004109* + ID_PRODUCT_FROM_DATABASE=Atom Processor E6xx Integrated Graphics Controller + +pci:v00008086d0000410A* + ID_PRODUCT_FROM_DATABASE=Atom Processor E6xx Integrated Graphics Controller + +pci:v00008086d0000410B* + ID_PRODUCT_FROM_DATABASE=Atom Processor E6xx Integrated Graphics Controller + +pci:v00008086d0000410C* + ID_PRODUCT_FROM_DATABASE=Atom Processor E6xx Integrated Graphics Controller + +pci:v00008086d0000410D* + ID_PRODUCT_FROM_DATABASE=Atom Processor E6xx Integrated Graphics Controller + +pci:v00008086d0000410E* + ID_PRODUCT_FROM_DATABASE=Atom Processor E6xx Integrated Graphics Controller + +pci:v00008086d0000410F* + ID_PRODUCT_FROM_DATABASE=Atom Processor E6xx Integrated Graphics Controller + +pci:v00008086d00004114* + ID_PRODUCT_FROM_DATABASE=Atom Processor E6xx PCI Host Bridge #1 + +pci:v00008086d00004115* + ID_PRODUCT_FROM_DATABASE=Atom Processor E6xx PCI Host Bridge #2 + +pci:v00008086d00004116* + ID_PRODUCT_FROM_DATABASE=Atom Processor E6xx PCI Host Bridge #3 + +pci:v00008086d00004117* + ID_PRODUCT_FROM_DATABASE=Atom Processor E6xx PCI Host Bridge #4 + +pci:v00008086d00004220* + ID_PRODUCT_FROM_DATABASE=PRO/Wireless 2200BG [Calexico2] Network Connection + +pci:v00008086d00004220sv0000103Csd00000934* + ID_PRODUCT_FROM_DATABASE=Compaq nw8240/nx8220 + +pci:v00008086d00004220sv0000103Csd000012F6* + ID_PRODUCT_FROM_DATABASE=nc6120/nx8220/nw8240 + +pci:v00008086d00004220sv00008086sd00002712* + ID_PRODUCT_FROM_DATABASE=IBM ThinkPad R50e + +pci:v00008086d00004220sv00008086sd00002721* + ID_PRODUCT_FROM_DATABASE=Dell B130 laptop integrated WLAN + +pci:v00008086d00004220sv00008086sd00002722* + ID_PRODUCT_FROM_DATABASE=Dell Latitude D600 + +pci:v00008086d00004220sv00008086sd00002731* + ID_PRODUCT_FROM_DATABASE=Samsung P35 integrated WLAN + +pci:v00008086d00004222* + ID_PRODUCT_FROM_DATABASE=PRO/Wireless 3945ABG [Golan] Network Connection + +pci:v00008086d00004222sv0000103Csd0000135C* + ID_PRODUCT_FROM_DATABASE=PRO/Wireless 3945ABG [Golan] Network Connection + +pci:v00008086d00004222sv00008086sd00001000* + ID_PRODUCT_FROM_DATABASE=PRO/Wireless 3945ABG Network Connection + +pci:v00008086d00004222sv00008086sd00001001* + ID_PRODUCT_FROM_DATABASE=PRO/Wireless 3945ABG Network Connection + +pci:v00008086d00004222sv00008086sd00001005* + ID_PRODUCT_FROM_DATABASE=PRO/Wireless 3945BG Network Connection + +pci:v00008086d00004222sv00008086sd00001034* + ID_PRODUCT_FROM_DATABASE=PRO/Wireless 3945BG Network Connection + +pci:v00008086d00004222sv00008086sd00001044* + ID_PRODUCT_FROM_DATABASE=PRO/Wireless 3945BG Network Connection + +pci:v00008086d00004222sv00008086sd00001C00* + ID_PRODUCT_FROM_DATABASE=PRO/Wireless 3945ABG Network Connection + +pci:v00008086d00004223* + ID_PRODUCT_FROM_DATABASE=PRO/Wireless 2915ABG [Calexico2] Network Connection + +pci:v00008086d00004223sv00001000sd00008086* + ID_PRODUCT_FROM_DATABASE=mPCI 3B Americas/Europe ZZA + +pci:v00008086d00004223sv00001001sd00008086* + ID_PRODUCT_FROM_DATABASE=mPCI 3B Europe ZZE + +pci:v00008086d00004223sv00001002sd00008086* + ID_PRODUCT_FROM_DATABASE=mPCI 3B Japan ZZJ + +pci:v00008086d00004223sv00001003sd00008086* + ID_PRODUCT_FROM_DATABASE=mPCI 3B High-Band ZZH + +pci:v00008086d00004223sv00001351sd0000103C* + ID_PRODUCT_FROM_DATABASE=Compaq NC6220 + +pci:v00008086d00004224* + ID_PRODUCT_FROM_DATABASE=PRO/Wireless 2915ABG [Calexico2] Network Connection + +pci:v00008086d00004227* + ID_PRODUCT_FROM_DATABASE=PRO/Wireless 3945ABG [Golan] Network Connection + +pci:v00008086d00004227sv00008086sd00001011* + ID_PRODUCT_FROM_DATABASE=ThinkPad R60e/X60s + +pci:v00008086d00004227sv00008086sd00001014* + ID_PRODUCT_FROM_DATABASE=PRO/Wireless 3945BG Network Connection + +pci:v00008086d00004229* + ID_PRODUCT_FROM_DATABASE=PRO/Wireless 4965 AG or AGN [Kedron] Network Connection + +pci:v00008086d00004229sv00008086sd00001100* + ID_PRODUCT_FROM_DATABASE=Vaio VGN-SZ79SN_C + +pci:v00008086d00004229sv00008086sd00001101* + ID_PRODUCT_FROM_DATABASE=PRO/Wireless 4965 AG or AGN + +pci:v00008086d0000422B* + ID_PRODUCT_FROM_DATABASE=Centrino Ultimate-N 6300 + +pci:v00008086d0000422Bsv00008086sd00001101* + ID_PRODUCT_FROM_DATABASE=Centrino Ultimate-N 6300 3x3 AGN + +pci:v00008086d0000422Bsv00008086sd00001121* + ID_PRODUCT_FROM_DATABASE=Centrino Ultimate-N 6300 3x3 AGN + +pci:v00008086d0000422C* + ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6200 + +pci:v00008086d0000422Csv00008086sd00001301* + ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6200 2x2 AGN + +pci:v00008086d0000422Csv00008086sd00001306* + ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6200 2x2 ABG + +pci:v00008086d0000422Csv00008086sd00001307* + ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6200 2x2 BG + +pci:v00008086d0000422Csv00008086sd00001321* + ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6200 2x2 AGN + +pci:v00008086d0000422Csv00008086sd00001326* + ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6200 2x2 ABG + +pci:v00008086d00004230* + ID_PRODUCT_FROM_DATABASE=PRO/Wireless 4965 AG or AGN [Kedron] Network Connection + +pci:v00008086d00004230sv00008086sd00001110* + ID_PRODUCT_FROM_DATABASE=Lenovo ThinkPad T51 + +pci:v00008086d00004230sv00008086sd00001111* + ID_PRODUCT_FROM_DATABASE=Lenovo ThinkPad T61 + +pci:v00008086d00004232* + ID_PRODUCT_FROM_DATABASE=WiFi Link 5100 + +pci:v00008086d00004232sv00008086sd00001201* + ID_PRODUCT_FROM_DATABASE=WiFi Link 5100 AGN + +pci:v00008086d00004232sv00008086sd00001204* + ID_PRODUCT_FROM_DATABASE=WiFi Link 5100 AGN + +pci:v00008086d00004232sv00008086sd00001205* + ID_PRODUCT_FROM_DATABASE=WiFi Link 5100 BGN + +pci:v00008086d00004232sv00008086sd00001206* + ID_PRODUCT_FROM_DATABASE=WiFi Link 5100 ABG + +pci:v00008086d00004232sv00008086sd00001221* + ID_PRODUCT_FROM_DATABASE=WiFi Link 5100 AGN + +pci:v00008086d00004232sv00008086sd00001224* + ID_PRODUCT_FROM_DATABASE=WiFi Link 5100 AGN + +pci:v00008086d00004232sv00008086sd00001225* + ID_PRODUCT_FROM_DATABASE=WiFi Link 5100 BGN + +pci:v00008086d00004232sv00008086sd00001226* + ID_PRODUCT_FROM_DATABASE=WiFi Link 5100 ABG + +pci:v00008086d00004232sv00008086sd00001301* + ID_PRODUCT_FROM_DATABASE=WiFi Link 5100 AGN + +pci:v00008086d00004232sv00008086sd00001304* + ID_PRODUCT_FROM_DATABASE=WiFi Link 5100 AGN + +pci:v00008086d00004232sv00008086sd00001305* + ID_PRODUCT_FROM_DATABASE=WiFi Link 5100 BGN + +pci:v00008086d00004232sv00008086sd00001306* + ID_PRODUCT_FROM_DATABASE=WiFi Link 5100 ABG + +pci:v00008086d00004232sv00008086sd00001321* + ID_PRODUCT_FROM_DATABASE=WiFi Link 5100 AGN + +pci:v00008086d00004232sv00008086sd00001324* + ID_PRODUCT_FROM_DATABASE=WiFi Link 5100 AGN + +pci:v00008086d00004232sv00008086sd00001325* + ID_PRODUCT_FROM_DATABASE=WiFi Link 5100 BGN + +pci:v00008086d00004232sv00008086sd00001326* + ID_PRODUCT_FROM_DATABASE=WiFi Link 5100 ABG + +pci:v00008086d00004235* + ID_PRODUCT_FROM_DATABASE=Ultimate N WiFi Link 5300 + +pci:v00008086d00004236* + ID_PRODUCT_FROM_DATABASE=Ultimate N WiFi Link 5300 + +pci:v00008086d00004237* + ID_PRODUCT_FROM_DATABASE=PRO/Wireless 5100 AGN [Shiloh] Network Connection + +pci:v00008086d00004237sv00008086sd00001211* + ID_PRODUCT_FROM_DATABASE=WiFi Link 5100 AGN + +pci:v00008086d00004237sv00008086sd00001214* + ID_PRODUCT_FROM_DATABASE=WiFi Link 5100 AGN + +pci:v00008086d00004237sv00008086sd00001215* + ID_PRODUCT_FROM_DATABASE=WiFi Link 5100 BGN + +pci:v00008086d00004237sv00008086sd00001216* + ID_PRODUCT_FROM_DATABASE=WiFi Link 5100 ABG + +pci:v00008086d00004237sv00008086sd00001311* + ID_PRODUCT_FROM_DATABASE=WiFi Link 5100 AGN + +pci:v00008086d00004237sv00008086sd00001314* + ID_PRODUCT_FROM_DATABASE=WiFi Link 5100 AGN + +pci:v00008086d00004237sv00008086sd00001315* + ID_PRODUCT_FROM_DATABASE=WiFi Link 5100 BGN + +pci:v00008086d00004237sv00008086sd00001316* + ID_PRODUCT_FROM_DATABASE=WiFi Link 5100 ABG + +pci:v00008086d00004238* + ID_PRODUCT_FROM_DATABASE=Centrino Ultimate-N 6300 + +pci:v00008086d00004238sv00008086sd00001111* + ID_PRODUCT_FROM_DATABASE=Centrino Ultimate-N 6300 3x3 AGN + +pci:v00008086d00004239* + ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6200 + +pci:v00008086d00004239sv00008086sd00001311* + ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6200 2x2 AGN + +pci:v00008086d00004239sv00008086sd00001316* + ID_PRODUCT_FROM_DATABASE=Centrino Advanced-N 6200 2x2 ABG + +pci:v00008086d0000423A* + ID_PRODUCT_FROM_DATABASE=PRO/Wireless 5350 AGN [Echo Peak] Network Connection + +pci:v00008086d0000423B* + ID_PRODUCT_FROM_DATABASE=PRO/Wireless 5350 AGN [Echo Peak] Network Connection + +pci:v00008086d0000423C* + ID_PRODUCT_FROM_DATABASE=WiMAX/WiFi Link 5150 + +pci:v00008086d0000423Csv00008086sd00001201* + ID_PRODUCT_FROM_DATABASE=WiMAX/WiFi Link 5150 AGN + +pci:v00008086d0000423Csv00008086sd00001206* + ID_PRODUCT_FROM_DATABASE=WiMAX/WiFi Link 5150 ABG + +pci:v00008086d0000423Csv00008086sd00001221* + ID_PRODUCT_FROM_DATABASE=WiMAX/WiFi Link 5150 AGN + +pci:v00008086d0000423Csv00008086sd00001301* + ID_PRODUCT_FROM_DATABASE=WiMAX/WiFi Link 5150 AGN + +pci:v00008086d0000423Csv00008086sd00001306* + ID_PRODUCT_FROM_DATABASE=WiMAX/WiFi Link 5150 ABG + +pci:v00008086d0000423Csv00008086sd00001321* + ID_PRODUCT_FROM_DATABASE=WiMAX/WiFi Link 5150 AGN + +pci:v00008086d0000423D* + ID_PRODUCT_FROM_DATABASE=WiMAX/WiFi Link 5150 + +pci:v00008086d0000423Dsv00008086sd00001211* + ID_PRODUCT_FROM_DATABASE=WiMAX/WiFi Link 5150 AGN + +pci:v00008086d0000423Dsv00008086sd00001216* + ID_PRODUCT_FROM_DATABASE=WiMAX/WiFi Link 5150 ABG + +pci:v00008086d0000423Dsv00008086sd00001311* + ID_PRODUCT_FROM_DATABASE=WiMAX/WiFi Link 5150 AGN + +pci:v00008086d0000423Dsv00008086sd00001316* + ID_PRODUCT_FROM_DATABASE=WiMAX/WiFi Link 5150 ABG + +pci:v00008086d0000444E* + ID_PRODUCT_FROM_DATABASE=Turbo Memory Controller + +pci:v00008086d00005001* + ID_PRODUCT_FROM_DATABASE=LE80578 + +pci:v00008086d00005002* + ID_PRODUCT_FROM_DATABASE=LE80578 Graphics Processor Unit + +pci:v00008086d00005009* + ID_PRODUCT_FROM_DATABASE=LE80578 Video Display Controller + +pci:v00008086d0000500D* + ID_PRODUCT_FROM_DATABASE=LE80578 Expansion Bus + +pci:v00008086d0000500E* + ID_PRODUCT_FROM_DATABASE=LE80578 UART Controller + +pci:v00008086d0000500F* + ID_PRODUCT_FROM_DATABASE=LE80578 General Purpose IO + +pci:v00008086d00005010* + ID_PRODUCT_FROM_DATABASE=LE80578 I2C Controller + +pci:v00008086d00005012* + ID_PRODUCT_FROM_DATABASE=LE80578 Serial Peripheral Interface Bus + +pci:v00008086d00005020* + ID_PRODUCT_FROM_DATABASE=EP80579 Memory Controller Hub + +pci:v00008086d00005021* + ID_PRODUCT_FROM_DATABASE=EP80579 DRAM Error Reporting Registers + +pci:v00008086d00005023* + ID_PRODUCT_FROM_DATABASE=EP80579 EDMA Controller + +pci:v00008086d00005024* + ID_PRODUCT_FROM_DATABASE=EP80579 PCI Express Port PEA0 + +pci:v00008086d00005025* + ID_PRODUCT_FROM_DATABASE=EP80579 PCI Express Port PEA1 + +pci:v00008086d00005028* + ID_PRODUCT_FROM_DATABASE=EP80579 S-ATA IDE + +pci:v00008086d00005029* + ID_PRODUCT_FROM_DATABASE=EP80579 S-ATA AHCI + +pci:v00008086d0000502A* + ID_PRODUCT_FROM_DATABASE=EP80579 S-ATA Reserved + +pci:v00008086d0000502B* + ID_PRODUCT_FROM_DATABASE=EP80579 S-ATA Reserved + +pci:v00008086d0000502C* + ID_PRODUCT_FROM_DATABASE=EP80579 Integrated Processor ASU + +pci:v00008086d0000502D* + ID_PRODUCT_FROM_DATABASE=EP80579 Integrated Processor with QuickAssist ASU + +pci:v00008086d0000502E* + ID_PRODUCT_FROM_DATABASE=EP80579 Reserved + +pci:v00008086d0000502F* + ID_PRODUCT_FROM_DATABASE=EP80579 Reserved + +pci:v00008086d00005030* + ID_PRODUCT_FROM_DATABASE=EP80579 Reserved + +pci:v00008086d00005031* + ID_PRODUCT_FROM_DATABASE=EP80579 LPC Bus + +pci:v00008086d00005032* + ID_PRODUCT_FROM_DATABASE=EP80579 SMBus Controller + +pci:v00008086d00005033* + ID_PRODUCT_FROM_DATABASE=EP80579 USB 1.1 Controller + +pci:v00008086d00005035* + ID_PRODUCT_FROM_DATABASE=EP80579 USB 2.0 Controller + +pci:v00008086d00005037* + ID_PRODUCT_FROM_DATABASE=EP80579 PCI-PCI Bridge (transparent mode) + +pci:v00008086d00005039* + ID_PRODUCT_FROM_DATABASE=EP80579 Controller Area Network (CAN) interface #1 + +pci:v00008086d0000503A* + ID_PRODUCT_FROM_DATABASE=EP80579 Controller Area Network (CAN) interface #2 + +pci:v00008086d0000503B* + ID_PRODUCT_FROM_DATABASE=EP80579 Synchronous Serial Port (SPP) + +pci:v00008086d0000503C* + ID_PRODUCT_FROM_DATABASE=EP80579 IEEE 1588 Hardware Assist + +pci:v00008086d0000503D* + ID_PRODUCT_FROM_DATABASE=EP80579 Local Expansion Bus + +pci:v00008086d0000503E* + ID_PRODUCT_FROM_DATABASE=EP80579 Global Control Unit (GCU) + +pci:v00008086d0000503F* + ID_PRODUCT_FROM_DATABASE=EP80579 Reserved + +pci:v00008086d00005040* + ID_PRODUCT_FROM_DATABASE=EP80579 Integrated Processor Gigabit Ethernet MAC + +pci:v00008086d00005041* + ID_PRODUCT_FROM_DATABASE=EP80579 Integrated Processor with QuickAssist Gigabit Ethernet MAC + +pci:v00008086d00005042* + ID_PRODUCT_FROM_DATABASE=EP80579 Reserved + +pci:v00008086d00005043* + ID_PRODUCT_FROM_DATABASE=EP80579 Reserved + +pci:v00008086d00005044* + ID_PRODUCT_FROM_DATABASE=EP80579 Integrated Processor Gigabit Ethernet MAC + +pci:v00008086d00005045* + ID_PRODUCT_FROM_DATABASE=EP80579 Integrated Processor with QuickAssist Gigabit Ethernet MAC + +pci:v00008086d00005046* + ID_PRODUCT_FROM_DATABASE=EP80579 Reserved + +pci:v00008086d00005047* + ID_PRODUCT_FROM_DATABASE=EP80579 Reserved + +pci:v00008086d00005048* + ID_PRODUCT_FROM_DATABASE=EP80579 Integrated Processor Gigabit Ethernet MAC + +pci:v00008086d00005049* + ID_PRODUCT_FROM_DATABASE=EP80579 Integrated Processor with QuickAssist Gigabit Ethernet MAC + +pci:v00008086d0000504A* + ID_PRODUCT_FROM_DATABASE=EP80579 Reserved + +pci:v00008086d0000504B* + ID_PRODUCT_FROM_DATABASE=EP80579 Reserved + +pci:v00008086d0000504C* + ID_PRODUCT_FROM_DATABASE=EP80579 Integrated Processor with QuickAssist TDM + +pci:v00008086d00005200* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 Intelligent Server + +pci:v00008086d00005201* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 Intelligent Server + +pci:v00008086d00005201sv00008086sd00000001* + ID_PRODUCT_FROM_DATABASE=EtherExpress PRO/100 Server Ethernet Adapter + +pci:v00008086d0000530D* + ID_PRODUCT_FROM_DATABASE=80310 (IOP) IO Processor + +pci:v00008086d000065C0* + ID_PRODUCT_FROM_DATABASE=5100 Chipset Memory Controller Hub + +pci:v00008086d000065E2* + ID_PRODUCT_FROM_DATABASE=5100 Chipset PCI Express x4 Port 2 + +pci:v00008086d000065E3* + ID_PRODUCT_FROM_DATABASE=5100 Chipset PCI Express x4 Port 3 + +pci:v00008086d000065E4* + ID_PRODUCT_FROM_DATABASE=5100 Chipset PCI Express x4 Port 4 + +pci:v00008086d000065E5* + ID_PRODUCT_FROM_DATABASE=5100 Chipset PCI Express x4 Port 5 + +pci:v00008086d000065E6* + ID_PRODUCT_FROM_DATABASE=5100 Chipset PCI Express x4 Port 6 + +pci:v00008086d000065E7* + ID_PRODUCT_FROM_DATABASE=5100 Chipset PCI Express x4 Port 7 + +pci:v00008086d000065F0* + ID_PRODUCT_FROM_DATABASE=5100 Chipset FSB Registers + +pci:v00008086d000065F0sv00001028sd0000020F* + ID_PRODUCT_FROM_DATABASE=PowerEdge R300 + +pci:v00008086d000065F0sv00001028sd00000210* + ID_PRODUCT_FROM_DATABASE=PowerEdge T300 + +pci:v00008086d000065F1* + ID_PRODUCT_FROM_DATABASE=5100 Chipset Reserved Registers + +pci:v00008086d000065F1sv00001028sd00000210* + ID_PRODUCT_FROM_DATABASE=PowerEdge T300 + +pci:v00008086d000065F3* + ID_PRODUCT_FROM_DATABASE=5100 Chipset Reserved Registers + +pci:v00008086d000065F5* + ID_PRODUCT_FROM_DATABASE=5100 Chipset DDR Channel 0 Registers + +pci:v00008086d000065F6* + ID_PRODUCT_FROM_DATABASE=5100 Chipset DDR Channel 1 Registers + +pci:v00008086d000065F7* + ID_PRODUCT_FROM_DATABASE=5100 Chipset PCI Express x8 Port 2-3 + +pci:v00008086d000065F8* + ID_PRODUCT_FROM_DATABASE=5100 Chipset PCI Express x8 Port 4-5 + +pci:v00008086d000065F9* + ID_PRODUCT_FROM_DATABASE=5100 Chipset PCI Express x8 Port 6-7 + +pci:v00008086d000065FA* + ID_PRODUCT_FROM_DATABASE=5100 Chipset PCI Express x16 Port 4-7 + +pci:v00008086d000065FF* + ID_PRODUCT_FROM_DATABASE=5100 Chipset DMA Engine + +pci:v00008086d00007000* + ID_PRODUCT_FROM_DATABASE=82371SB PIIX3 ISA [Natoma/Triton II] + +pci:v00008086d00007000sv00001AF4sd00001100* + ID_PRODUCT_FROM_DATABASE=Qemu virtual machine + +pci:v00008086d00007010* + ID_PRODUCT_FROM_DATABASE=82371SB PIIX3 IDE [Natoma/Triton II] + +pci:v00008086d00007010sv00001AF4sd00001100* + ID_PRODUCT_FROM_DATABASE=Qemu virtual machine + +pci:v00008086d00007020* + ID_PRODUCT_FROM_DATABASE=82371SB PIIX3 USB [Natoma/Triton II] + +pci:v00008086d00007020sv00001AF4sd00001100* + ID_PRODUCT_FROM_DATABASE=Qemu virtual machine + +pci:v00008086d00007030* + ID_PRODUCT_FROM_DATABASE=430VX - 82437VX TVX [Triton VX] + +pci:v00008086d00007050* + ID_PRODUCT_FROM_DATABASE=Intercast Video Capture Card + +pci:v00008086d00007051* + ID_PRODUCT_FROM_DATABASE=PB 642365-003 (Business Video Conferencing Card) + +pci:v00008086d00007100* + ID_PRODUCT_FROM_DATABASE=430TX - 82439TX MTXC + +pci:v00008086d00007110* + ID_PRODUCT_FROM_DATABASE=82371AB/EB/MB PIIX4 ISA + +pci:v00008086d00007110sv000015ADsd00001976* + ID_PRODUCT_FROM_DATABASE=Virtual Machine Chipset + +pci:v00008086d00007111* + ID_PRODUCT_FROM_DATABASE=82371AB/EB/MB PIIX4 IDE + +pci:v00008086d00007111sv000015ADsd00001976* + ID_PRODUCT_FROM_DATABASE=Virtual Machine Chipset + +pci:v00008086d00007112* + ID_PRODUCT_FROM_DATABASE=82371AB/EB/MB PIIX4 USB + +pci:v00008086d00007112sv000015ADsd00001976* + ID_PRODUCT_FROM_DATABASE=Virtual Machine Chipset + +pci:v00008086d00007113* + ID_PRODUCT_FROM_DATABASE=82371AB/EB/MB PIIX4 ACPI + +pci:v00008086d00007113sv000015ADsd00001976* + ID_PRODUCT_FROM_DATABASE=Virtual Machine Chipset + +pci:v00008086d00007113sv00001AF4sd00001100* + ID_PRODUCT_FROM_DATABASE=Qemu virtual machine + +pci:v00008086d00007120* + ID_PRODUCT_FROM_DATABASE=82810 GMCH (Graphics Memory Controller Hub) + +pci:v00008086d00007120sv00004C53sd00001040* + ID_PRODUCT_FROM_DATABASE=CL7 mainboard + +pci:v00008086d00007120sv00004C53sd00001060* + ID_PRODUCT_FROM_DATABASE=PC7 mainboard + +pci:v00008086d00007121* + ID_PRODUCT_FROM_DATABASE=82810 (CGC) Chipset Graphics Controller + +pci:v00008086d00007121sv00004C53sd00001040* + ID_PRODUCT_FROM_DATABASE=CL7 mainboard + +pci:v00008086d00007121sv00004C53sd00001060* + ID_PRODUCT_FROM_DATABASE=PC7 mainboard + +pci:v00008086d00007121sv00008086sd00004341* + ID_PRODUCT_FROM_DATABASE=Cayman (CA810) Mainboard + +pci:v00008086d00007122* + ID_PRODUCT_FROM_DATABASE=82810 DC-100 (GMCH) Graphics Memory Controller Hub + +pci:v00008086d00007123* + ID_PRODUCT_FROM_DATABASE=82810 DC-100 (CGC) Chipset Graphics Controller + +pci:v00008086d00007124* + ID_PRODUCT_FROM_DATABASE=82810E DC-133 (GMCH) Graphics Memory Controller Hub + +pci:v00008086d00007124sv00001028sd000000B4* + ID_PRODUCT_FROM_DATABASE=OptiPlex GX110 + +pci:v00008086d00007125* + ID_PRODUCT_FROM_DATABASE=82810E DC-133 (CGC) Chipset Graphics Controller + +pci:v00008086d00007125sv00001028sd000000B4* + ID_PRODUCT_FROM_DATABASE=OptiPlex GX110 + +pci:v00008086d00007126* + ID_PRODUCT_FROM_DATABASE=82810 DC-133 System and Graphics Controller + +pci:v00008086d00007128* + ID_PRODUCT_FROM_DATABASE=82810-M DC-100 System and Graphics Controller + +pci:v00008086d0000712A* + ID_PRODUCT_FROM_DATABASE=82810-M DC-133 System and Graphics Controller + +pci:v00008086d00007180* + ID_PRODUCT_FROM_DATABASE=440LX/EX - 82443LX/EX Host bridge + +pci:v00008086d00007181* + ID_PRODUCT_FROM_DATABASE=440LX/EX - 82443LX/EX AGP bridge + +pci:v00008086d00007190* + ID_PRODUCT_FROM_DATABASE=440BX/ZX/DX - 82443BX/ZX/DX Host bridge + +pci:v00008086d00007190sv00000E11sd00000500* + ID_PRODUCT_FROM_DATABASE=Armada 1750 Laptop System Chipset + +pci:v00008086d00007190sv00000E11sd0000B110* + ID_PRODUCT_FROM_DATABASE=Armada M700/E500 + +pci:v00008086d00007190sv00001028sd0000008E* + ID_PRODUCT_FROM_DATABASE=PowerEdge 1300 mainboard + +pci:v00008086d00007190sv00001043sd0000803B* + ID_PRODUCT_FROM_DATABASE=CUBX-L/E Mainboard + +pci:v00008086d00007190sv00001179sd00000001* + ID_PRODUCT_FROM_DATABASE=Toshiba Tecra 8100 Laptop System Chipset + +pci:v00008086d00007190sv000015ADsd00001976* + ID_PRODUCT_FROM_DATABASE=Virtual Machine Chipset + +pci:v00008086d00007190sv00004C53sd00001050* + ID_PRODUCT_FROM_DATABASE=CT7 mainboard + +pci:v00008086d00007190sv00004C53sd00001051* + ID_PRODUCT_FROM_DATABASE=CE7 mainboard + +pci:v00008086d00007191* + ID_PRODUCT_FROM_DATABASE=440BX/ZX/DX - 82443BX/ZX/DX AGP bridge + +pci:v00008086d00007191sv00001028sd0000008E* + ID_PRODUCT_FROM_DATABASE=PowerEdge 1300 mainboard + +pci:v00008086d00007192* + ID_PRODUCT_FROM_DATABASE=440BX/ZX/DX - 82443BX/ZX/DX Host bridge (AGP disabled) + +pci:v00008086d00007192sv00000E11sd00000460* + ID_PRODUCT_FROM_DATABASE=Armada 1700 Laptop System Chipset + +pci:v00008086d00007192sv00001179sd00000001* + ID_PRODUCT_FROM_DATABASE=Satellite 4010 + +pci:v00008086d00007192sv00004C53sd00001000* + ID_PRODUCT_FROM_DATABASE=CC7/CR7/CP7/VC7/VP7/VR7 mainboard + +pci:v00008086d00007192sv00008086sd00007190* + ID_PRODUCT_FROM_DATABASE=Dell PowerEdge 350 + +pci:v00008086d00007194* + ID_PRODUCT_FROM_DATABASE=82440MX Host Bridge + +pci:v00008086d00007194sv00001033sd00000000* + ID_PRODUCT_FROM_DATABASE=Versa Note Vxi + +pci:v00008086d00007194sv00004C53sd000010A0* + ID_PRODUCT_FROM_DATABASE=CA3/CR3 mainboard + +pci:v00008086d00007195* + ID_PRODUCT_FROM_DATABASE=82440MX AC'97 Audio Controller + +pci:v00008086d00007195sv00001033sd000080CC* + ID_PRODUCT_FROM_DATABASE=Versa Note VXi + +pci:v00008086d00007195sv000010CFsd00001099* + ID_PRODUCT_FROM_DATABASE=QSound_SigmaTel Stac97 PCI Audio + +pci:v00008086d00007195sv000011D4sd00000040* + ID_PRODUCT_FROM_DATABASE=SoundMAX Integrated Digital Audio + +pci:v00008086d00007195sv000011D4sd00000048* + ID_PRODUCT_FROM_DATABASE=SoundMAX Integrated Digital Audio + +pci:v00008086d00007196* + ID_PRODUCT_FROM_DATABASE=82440MX AC'97 Modem Controller + +pci:v00008086d00007198* + ID_PRODUCT_FROM_DATABASE=82440MX ISA Bridge + +pci:v00008086d00007199* + ID_PRODUCT_FROM_DATABASE=82440MX EIDE Controller + +pci:v00008086d0000719A* + ID_PRODUCT_FROM_DATABASE=82440MX USB Universal Host Controller + +pci:v00008086d0000719B* + ID_PRODUCT_FROM_DATABASE=82440MX Power Management Controller + +pci:v00008086d000071A0* + ID_PRODUCT_FROM_DATABASE=440GX - 82443GX Host bridge + +pci:v00008086d000071A0sv00004C53sd00001050* + ID_PRODUCT_FROM_DATABASE=CT7 mainboard + +pci:v00008086d000071A0sv00004C53sd00001051* + ID_PRODUCT_FROM_DATABASE=CE7 mainboard + +pci:v00008086d000071A1* + ID_PRODUCT_FROM_DATABASE=440GX - 82443GX AGP bridge + +pci:v00008086d000071A2* + ID_PRODUCT_FROM_DATABASE=440GX - 82443GX Host bridge (AGP disabled) + +pci:v00008086d000071A2sv00004C53sd00001000* + ID_PRODUCT_FROM_DATABASE=CC7/CR7/CP7/VC7/VP7/VR7 mainboard + +pci:v00008086d00007600* + ID_PRODUCT_FROM_DATABASE=82372FB PIIX5 ISA + +pci:v00008086d00007601* + ID_PRODUCT_FROM_DATABASE=82372FB PIIX5 IDE + +pci:v00008086d00007602* + ID_PRODUCT_FROM_DATABASE=82372FB PIIX5 USB + +pci:v00008086d00007603* + ID_PRODUCT_FROM_DATABASE=82372FB PIIX5 SMBus + +pci:v00008086d00007800* + ID_PRODUCT_FROM_DATABASE=82740 (i740) AGP Graphics Accelerator + +pci:v00008086d00007800sv0000003Dsd00000008* + ID_PRODUCT_FROM_DATABASE=Starfighter AGP + +pci:v00008086d00007800sv0000003Dsd0000000B* + ID_PRODUCT_FROM_DATABASE=Starfighter AGP + +pci:v00008086d00007800sv00001092sd00000100* + ID_PRODUCT_FROM_DATABASE=Stealth II G460 + +pci:v00008086d00007800sv000010B4sd0000201A* + ID_PRODUCT_FROM_DATABASE=Lightspeed 740 + +pci:v00008086d00007800sv000010B4sd0000202F* + ID_PRODUCT_FROM_DATABASE=Lightspeed 740 + +pci:v00008086d00007800sv00008086sd00000000* + ID_PRODUCT_FROM_DATABASE=Terminator 2x/i + +pci:v00008086d00007800sv00008086sd00000100* + ID_PRODUCT_FROM_DATABASE=Intel740 Graphics Accelerator + +pci:v00008086d00008002* + ID_PRODUCT_FROM_DATABASE=Trusted Execution Technology Registers + +pci:v00008086d00008003* + ID_PRODUCT_FROM_DATABASE=Trusted Execution Technology Registers + +pci:v00008086d00008100* + ID_PRODUCT_FROM_DATABASE=System Controller Hub (SCH Poulsbo) + +pci:v00008086d00008108* + ID_PRODUCT_FROM_DATABASE=System Controller Hub (SCH Poulsbo) Graphics Controller + +pci:v00008086d00008110* + ID_PRODUCT_FROM_DATABASE=System Controller Hub (SCH Poulsbo) PCI Express Port 1 + +pci:v00008086d00008112* + ID_PRODUCT_FROM_DATABASE=System Controller Hub (SCH Poulsbo) PCI Express Port 2 + +pci:v00008086d00008114* + ID_PRODUCT_FROM_DATABASE=System Controller Hub (SCH Poulsbo) USB UHCI #1 + +pci:v00008086d00008115* + ID_PRODUCT_FROM_DATABASE=System Controller Hub (SCH Poulsbo) USB UHCI #2 + +pci:v00008086d00008116* + ID_PRODUCT_FROM_DATABASE=System Controller Hub (SCH Poulsbo) USB UHCI #3 + +pci:v00008086d00008117* + ID_PRODUCT_FROM_DATABASE=System Controller Hub (SCH Poulsbo) USB EHCI #1 + +pci:v00008086d00008118* + ID_PRODUCT_FROM_DATABASE=System Controller Hub (SCH Poulsbo) USB Client Controller + +pci:v00008086d00008119* + ID_PRODUCT_FROM_DATABASE=System Controller Hub (SCH Poulsbo) LPC Bridge + +pci:v00008086d0000811A* + ID_PRODUCT_FROM_DATABASE=System Controller Hub (SCH Poulsbo) IDE Controller + +pci:v00008086d0000811B* + ID_PRODUCT_FROM_DATABASE=System Controller Hub (SCH Poulsbo) HD Audio Controller + +pci:v00008086d0000811C* + ID_PRODUCT_FROM_DATABASE=System Controller Hub (SCH Poulsbo) SDIO Controller #1 + +pci:v00008086d0000811D* + ID_PRODUCT_FROM_DATABASE=System Controller Hub (SCH Poulsbo) SDIO Controller #2 + +pci:v00008086d0000811E* + ID_PRODUCT_FROM_DATABASE=System Controller Hub (SCH Poulsbo) SDIO Controller #3 + +pci:v00008086d00008180* + ID_PRODUCT_FROM_DATABASE=Atom Processor E6xx PCI Express Port 3 + +pci:v00008086d00008181* + ID_PRODUCT_FROM_DATABASE=Atom Processor E6xx PCI Express Port 4 + +pci:v00008086d00008182* + ID_PRODUCT_FROM_DATABASE=Atom Processor E6xx Integrated Graphics Controller + +pci:v00008086d00008183* + ID_PRODUCT_FROM_DATABASE=Atom Processor E6xx Configuration Unit + +pci:v00008086d00008184* + ID_PRODUCT_FROM_DATABASE=Atom Processor E6xx PCI Express Port 1 + +pci:v00008086d00008185* + ID_PRODUCT_FROM_DATABASE=Atom Processor E6xx PCI Express Port 2 + +pci:v00008086d00008186* + ID_PRODUCT_FROM_DATABASE=Atom Processor E6xx LPC Bridge + +pci:v00008086d0000821C* + ID_PRODUCT_FROM_DATABASE=Wellsburg PCI Express Root Port #7 + +pci:v00008086d0000821D* + ID_PRODUCT_FROM_DATABASE=Wellsburg PCI Express Root Port #7 + +pci:v00008086d000084C4* + ID_PRODUCT_FROM_DATABASE=450KX/GX [Orion] - 82454KX/GX PCI bridge + +pci:v00008086d000084C5* + ID_PRODUCT_FROM_DATABASE=450KX/GX [Orion] - 82453KX/GX Memory controller + +pci:v00008086d000084CA* + ID_PRODUCT_FROM_DATABASE=450NX - 82451NX Memory & I/O Controller + +pci:v00008086d000084CB* + ID_PRODUCT_FROM_DATABASE=450NX - 82454NX/84460GX PCI Expander Bridge + +pci:v00008086d000084E0* + ID_PRODUCT_FROM_DATABASE=460GX - 84460GX System Address Controller (SAC) + +pci:v00008086d000084E1* + ID_PRODUCT_FROM_DATABASE=460GX - 84460GX System Data Controller (SDC) + +pci:v00008086d000084E2* + ID_PRODUCT_FROM_DATABASE=460GX - 84460GX AGP Bridge (GXB function 2) + +pci:v00008086d000084E3* + ID_PRODUCT_FROM_DATABASE=460GX - 84460GX Memory Address Controller (MAC) + +pci:v00008086d000084E4* + ID_PRODUCT_FROM_DATABASE=460GX - 84460GX Memory Data Controller (MDC) + +pci:v00008086d000084E6* + ID_PRODUCT_FROM_DATABASE=460GX - 82466GX Wide and fast PCI eXpander Bridge (WXB) + +pci:v00008086d000084EA* + ID_PRODUCT_FROM_DATABASE=460GX - 84460GX AGP Bridge (GXB function 1) + +pci:v00008086d00008500* + ID_PRODUCT_FROM_DATABASE=IXP4XX Network Processor (IXP420/421/422/425/IXC1100) + +pci:v00008086d00008500sv00001993sd00000DED* + ID_PRODUCT_FROM_DATABASE=mGuard-PCI AV#2 + +pci:v00008086d00008500sv00001993sd00000DEE* + ID_PRODUCT_FROM_DATABASE=mGuard-PCI AV#1 + +pci:v00008086d00008500sv00001993sd00000DEF* + ID_PRODUCT_FROM_DATABASE=mGuard-PCI AV#0 + +pci:v00008086d00008800* + ID_PRODUCT_FROM_DATABASE=Platform Controller Hub EG20T PCI Express Port + +pci:v00008086d00008801* + ID_PRODUCT_FROM_DATABASE=Platform Controller Hub EG20T Packet Hub + +pci:v00008086d00008802* + ID_PRODUCT_FROM_DATABASE=Platform Controller Hub EG20T Gigabit Ethernet Controller + +pci:v00008086d00008803* + ID_PRODUCT_FROM_DATABASE=Platform Controller Hub EG20T General Purpose IO Controller + +pci:v00008086d00008804* + ID_PRODUCT_FROM_DATABASE=Platform Controller Hub EG20T USB OHCI Controller #4 + +pci:v00008086d00008805* + ID_PRODUCT_FROM_DATABASE=Platform Controller Hub EG20T USB OHCI Controller #5 + +pci:v00008086d00008806* + ID_PRODUCT_FROM_DATABASE=Platform Controller Hub EG20T USB OHCI Controller #6 + +pci:v00008086d00008807* + ID_PRODUCT_FROM_DATABASE=Platform Controller Hub EG20T USB2 EHCI Controller #2 + +pci:v00008086d00008808* + ID_PRODUCT_FROM_DATABASE=Platform Controller Hub EG20T USB Client Controller + +pci:v00008086d00008809* + ID_PRODUCT_FROM_DATABASE=Platform Controller Hub EG20T SDIO Controller #1 + +pci:v00008086d0000880A* + ID_PRODUCT_FROM_DATABASE=Platform Controller Hub EG20T SDIO Controller #2 + +pci:v00008086d0000880B* + ID_PRODUCT_FROM_DATABASE=Platform Controller Hub EG20T SATA AHCI Controller + +pci:v00008086d0000880C* + ID_PRODUCT_FROM_DATABASE=Platform Controller Hub EG20T USB OHCI Controller #1 + +pci:v00008086d0000880D* + ID_PRODUCT_FROM_DATABASE=Platform Controller Hub EG20T USB OHCI Controller #2 + +pci:v00008086d0000880E* + ID_PRODUCT_FROM_DATABASE=Platform Controller Hub EG20T USB OHCI Controller #3 + +pci:v00008086d0000880F* + ID_PRODUCT_FROM_DATABASE=Platform Controller Hub EG20T USB2 EHCI Controller #1 + +pci:v00008086d00008810* + ID_PRODUCT_FROM_DATABASE=Platform Controller Hub EG20T DMA Controller #1 + +pci:v00008086d00008811* + ID_PRODUCT_FROM_DATABASE=Platform Controller Hub EG20T UART Controller 0 + +pci:v00008086d00008812* + ID_PRODUCT_FROM_DATABASE=Platform Controller Hub EG20T UART Controller 1 + +pci:v00008086d00008813* + ID_PRODUCT_FROM_DATABASE=Platform Controller Hub EG20T UART Controller 2 + +pci:v00008086d00008814* + ID_PRODUCT_FROM_DATABASE=Platform Controller Hub EG20T UART Controller 3 + +pci:v00008086d00008815* + ID_PRODUCT_FROM_DATABASE=Platform Controller Hub EG20T DMA Controller #2 + +pci:v00008086d00008816* + ID_PRODUCT_FROM_DATABASE=Platform Controller Hub EG20T Serial Peripheral Interface Bus + +pci:v00008086d00008817* + ID_PRODUCT_FROM_DATABASE=Platform Controller Hub EG20T I2C Controller + +pci:v00008086d00008818* + ID_PRODUCT_FROM_DATABASE=Platform Controller Hub EG20T Controller Area Network (CAN) Controller + +pci:v00008086d00008819* + ID_PRODUCT_FROM_DATABASE=Platform Controller Hub EG20T IEEE 1588 Hardware Assist + +pci:v00008086d00008C00* + ID_PRODUCT_FROM_DATABASE=Lynx Point 4-port SATA Controller 1 [IDE mode] + +pci:v00008086d00008C01* + ID_PRODUCT_FROM_DATABASE=Lynx Point 4-port SATA Controller 1 [IDE mode] + +pci:v00008086d00008C02* + ID_PRODUCT_FROM_DATABASE=Lynx Point 6-port SATA Controller 1 [AHCI mode] + +pci:v00008086d00008C03* + ID_PRODUCT_FROM_DATABASE=Lynx Point 6-port SATA Controller 1 [AHCI mode] + +pci:v00008086d00008C04* + ID_PRODUCT_FROM_DATABASE=Lynx Point SATA Controller 1 [RAID mode] + +pci:v00008086d00008C05* + ID_PRODUCT_FROM_DATABASE=Lynx Point SATA Controller 1 [RAID mode] + +pci:v00008086d00008C06* + ID_PRODUCT_FROM_DATABASE=Lynx Point SATA Controller 1 [RAID mode] + +pci:v00008086d00008C07* + ID_PRODUCT_FROM_DATABASE=Lynx Point SATA Controller 1 [RAID mode] + +pci:v00008086d00008C08* + ID_PRODUCT_FROM_DATABASE=Lynx Point 2-port SATA Controller 2 [IDE mode] + +pci:v00008086d00008C09* + ID_PRODUCT_FROM_DATABASE=Lynx Point 2-port SATA Controller 2 [IDE mode] + +pci:v00008086d00008C0E* + ID_PRODUCT_FROM_DATABASE=Lynx Point SATA Controller 1 [RAID mode] + +pci:v00008086d00008C0F* + ID_PRODUCT_FROM_DATABASE=Lynx Point SATA Controller 1 [RAID mode] + +pci:v00008086d00008C10* + ID_PRODUCT_FROM_DATABASE=Lynx Point PCI Express Root Port #1 + +pci:v00008086d00008C11* + ID_PRODUCT_FROM_DATABASE=Lynx Point PCI Express Root Port #1 + +pci:v00008086d00008C12* + ID_PRODUCT_FROM_DATABASE=Lynx Point PCI Express Root Port #2 + +pci:v00008086d00008C13* + ID_PRODUCT_FROM_DATABASE=Lynx Point PCI Express Root Port #2 + +pci:v00008086d00008C14* + ID_PRODUCT_FROM_DATABASE=Lynx Point PCI Express Root Port #3 + +pci:v00008086d00008C15* + ID_PRODUCT_FROM_DATABASE=Lynx Point PCI Express Root Port #3 + +pci:v00008086d00008C16* + ID_PRODUCT_FROM_DATABASE=Lynx Point PCI Express Root Port #4 + +pci:v00008086d00008C17* + ID_PRODUCT_FROM_DATABASE=Lynx Point PCI Express Root Port #4 + +pci:v00008086d00008C18* + ID_PRODUCT_FROM_DATABASE=Lynx Point PCI Express Root Port #5 + +pci:v00008086d00008C19* + ID_PRODUCT_FROM_DATABASE=Lynx Point PCI Express Root Port #5 + +pci:v00008086d00008C1A* + ID_PRODUCT_FROM_DATABASE=Lynx Point PCI Express Root Port #6 + +pci:v00008086d00008C1B* + ID_PRODUCT_FROM_DATABASE=Lynx Point PCI Express Root Port #6 + +pci:v00008086d00008C1C* + ID_PRODUCT_FROM_DATABASE=Lynx Point PCI Express Root Port #7 + +pci:v00008086d00008C1D* + ID_PRODUCT_FROM_DATABASE=Lynx Point PCI Express Root Port #7 + +pci:v00008086d00008C1E* + ID_PRODUCT_FROM_DATABASE=Lynx Point PCI Express Root Port #8 + +pci:v00008086d00008C1F* + ID_PRODUCT_FROM_DATABASE=Lynx Point PCI Express Root Port #8 + +pci:v00008086d00008C20* + ID_PRODUCT_FROM_DATABASE=Lynx Point High Definition Audio Controller + +pci:v00008086d00008C21* + ID_PRODUCT_FROM_DATABASE=Lynx Point High Definition Audio Controller + +pci:v00008086d00008C22* + ID_PRODUCT_FROM_DATABASE=Lynx Point SMBus Controller + +pci:v00008086d00008C23* + ID_PRODUCT_FROM_DATABASE=Lynx Point CHAP Counters + +pci:v00008086d00008C24* + ID_PRODUCT_FROM_DATABASE=Lynx Point Thermal Management Controller + +pci:v00008086d00008C26* + ID_PRODUCT_FROM_DATABASE=Lynx Point USB Enhanced Host Controller #1 + +pci:v00008086d00008C2D* + ID_PRODUCT_FROM_DATABASE=Lynx Point USB Enhanced Host Controller #2 + +pci:v00008086d00008C31* + ID_PRODUCT_FROM_DATABASE=Lynx Point USB xHCI Host Controller + +pci:v00008086d00008C33* + ID_PRODUCT_FROM_DATABASE=Lynx Point LAN Controller + +pci:v00008086d00008C34* + ID_PRODUCT_FROM_DATABASE=Lynx Point NAND Controller + +pci:v00008086d00008C3A* + ID_PRODUCT_FROM_DATABASE=Lynx Point MEI Controller #1 + +pci:v00008086d00008C3B* + ID_PRODUCT_FROM_DATABASE=Lynx Point MEI Controller #2 + +pci:v00008086d00008C3C* + ID_PRODUCT_FROM_DATABASE=Lynx Point IDE-r Controller + +pci:v00008086d00008C3D* + ID_PRODUCT_FROM_DATABASE=Lynx Point KT Controller + +pci:v00008086d00008C40* + ID_PRODUCT_FROM_DATABASE=Lynx Point LPC Controller + +pci:v00008086d00008C41* + ID_PRODUCT_FROM_DATABASE=Lynx Point LPC Controller + +pci:v00008086d00008C42* + ID_PRODUCT_FROM_DATABASE=Lynx Point LPC Controller + +pci:v00008086d00008C43* + ID_PRODUCT_FROM_DATABASE=Lynx Point LPC Controller + +pci:v00008086d00008C44* + ID_PRODUCT_FROM_DATABASE=Lynx Point LPC Controller + +pci:v00008086d00008C45* + ID_PRODUCT_FROM_DATABASE=Lynx Point LPC Controller + +pci:v00008086d00008C46* + ID_PRODUCT_FROM_DATABASE=Lynx Point LPC Controller + +pci:v00008086d00008C47* + ID_PRODUCT_FROM_DATABASE=Lynx Point LPC Controller + +pci:v00008086d00008C48* + ID_PRODUCT_FROM_DATABASE=Lynx Point LPC Controller + +pci:v00008086d00008C49* + ID_PRODUCT_FROM_DATABASE=Lynx Point LPC Controller + +pci:v00008086d00008C4A* + ID_PRODUCT_FROM_DATABASE=Lynx Point LPC Controller + +pci:v00008086d00008C4B* + ID_PRODUCT_FROM_DATABASE=Lynx Point LPC Controller + +pci:v00008086d00008C4C* + ID_PRODUCT_FROM_DATABASE=Lynx Point LPC Controller + +pci:v00008086d00008C4D* + ID_PRODUCT_FROM_DATABASE=Lynx Point LPC Controller + +pci:v00008086d00008C4E* + ID_PRODUCT_FROM_DATABASE=Lynx Point LPC Controller + +pci:v00008086d00008C4F* + ID_PRODUCT_FROM_DATABASE=Lynx Point LPC Controller + +pci:v00008086d00008C50* + ID_PRODUCT_FROM_DATABASE=Lynx Point LPC Controller + +pci:v00008086d00008C51* + ID_PRODUCT_FROM_DATABASE=Lynx Point LPC Controller + +pci:v00008086d00008C52* + ID_PRODUCT_FROM_DATABASE=Lynx Point LPC Controller + +pci:v00008086d00008C53* + ID_PRODUCT_FROM_DATABASE=Lynx Point LPC Controller + +pci:v00008086d00008C54* + ID_PRODUCT_FROM_DATABASE=Lynx Point LPC Controller + +pci:v00008086d00008C55* + ID_PRODUCT_FROM_DATABASE=Lynx Point LPC Controller + +pci:v00008086d00008C56* + ID_PRODUCT_FROM_DATABASE=Lynx Point LPC Controller + +pci:v00008086d00008C57* + ID_PRODUCT_FROM_DATABASE=Lynx Point LPC Controller + +pci:v00008086d00008C58* + ID_PRODUCT_FROM_DATABASE=Lynx Point LPC Controller + +pci:v00008086d00008C59* + ID_PRODUCT_FROM_DATABASE=Lynx Point LPC Controller + +pci:v00008086d00008C5A* + ID_PRODUCT_FROM_DATABASE=Lynx Point LPC Controller + +pci:v00008086d00008C5B* + ID_PRODUCT_FROM_DATABASE=Lynx Point LPC Controller + +pci:v00008086d00008C5C* + ID_PRODUCT_FROM_DATABASE=Lynx Point LPC Controller + +pci:v00008086d00008C5D* + ID_PRODUCT_FROM_DATABASE=Lynx Point LPC Controller + +pci:v00008086d00008C5E* + ID_PRODUCT_FROM_DATABASE=Lynx Point LPC Controller + +pci:v00008086d00008C5F* + ID_PRODUCT_FROM_DATABASE=Lynx Point LPC Controller + +pci:v00008086d00008D00* + ID_PRODUCT_FROM_DATABASE=Wellsburg 4-port SATA Controller [IDE mode] + +pci:v00008086d00008D02* + ID_PRODUCT_FROM_DATABASE=Wellsburg 6-Port SATA Controller [AHCI mode] + +pci:v00008086d00008D04* + ID_PRODUCT_FROM_DATABASE=Wellsburg SATA Controller [RAID mode] + +pci:v00008086d00008D06* + ID_PRODUCT_FROM_DATABASE=Wellsburg SATA Controller [RAID mode] + +pci:v00008086d00008D08* + ID_PRODUCT_FROM_DATABASE=Wellsburg 2-port SATA Controller [IDE mode] + +pci:v00008086d00008D0E* + ID_PRODUCT_FROM_DATABASE=Wellsburg SATA Controller [RAID mode] + +pci:v00008086d00008D10* + ID_PRODUCT_FROM_DATABASE=Wellsburg PCI Express Root Port #1 + +pci:v00008086d00008D11* + ID_PRODUCT_FROM_DATABASE=Wellsburg PCI Express Root Port #1 + +pci:v00008086d00008D12* + ID_PRODUCT_FROM_DATABASE=Wellsburg PCI Express Root Port #2 + +pci:v00008086d00008D13* + ID_PRODUCT_FROM_DATABASE=Wellsburg PCI Express Root Port #2 + +pci:v00008086d00008D14* + ID_PRODUCT_FROM_DATABASE=Wellsburg PCI Express Root Port #3 + +pci:v00008086d00008D15* + ID_PRODUCT_FROM_DATABASE=Wellsburg PCI Express Root Port #3 + +pci:v00008086d00008D16* + ID_PRODUCT_FROM_DATABASE=Wellsburg PCI Express Root Port #4 + +pci:v00008086d00008D17* + ID_PRODUCT_FROM_DATABASE=Wellsburg PCI Express Root Port #4 + +pci:v00008086d00008D18* + ID_PRODUCT_FROM_DATABASE=Wellsburg PCI Express Root Port #5 + +pci:v00008086d00008D19* + ID_PRODUCT_FROM_DATABASE=Wellsburg PCI Express Root Port #5 + +pci:v00008086d00008D1A* + ID_PRODUCT_FROM_DATABASE=Wellsburg PCI Express Root Port #6 + +pci:v00008086d00008D1E* + ID_PRODUCT_FROM_DATABASE=Wellsburg PCI Express Root Port #8 + +pci:v00008086d00008D1F* + ID_PRODUCT_FROM_DATABASE=Wellsburg PCI Express Root Port #8 + +pci:v00008086d00008D20* + ID_PRODUCT_FROM_DATABASE=Wellsburg HD Audio Controller + +pci:v00008086d00008D21* + ID_PRODUCT_FROM_DATABASE=Wellsburg HD Audio Controller + +pci:v00008086d00008D22* + ID_PRODUCT_FROM_DATABASE=Wellsburg SMBus Controller + +pci:v00008086d00008D24* + ID_PRODUCT_FROM_DATABASE=Wellsburg Thermal Subsystem + +pci:v00008086d00008D26* + ID_PRODUCT_FROM_DATABASE=Wellsburg USB Enhanced Host Controller #1 + +pci:v00008086d00008D2D* + ID_PRODUCT_FROM_DATABASE=Wellsburg USB Enhanced Host Controller #2 + +pci:v00008086d00008D31* + ID_PRODUCT_FROM_DATABASE=Wellsburg USB xHCI Host Controller + +pci:v00008086d00008D33* + ID_PRODUCT_FROM_DATABASE=Wellsburg LAN Controller + +pci:v00008086d00008D34* + ID_PRODUCT_FROM_DATABASE=Wellsburg NAND Controller + +pci:v00008086d00008D3A* + ID_PRODUCT_FROM_DATABASE=Wellsburg MEI Controller #1 + +pci:v00008086d00008D3B* + ID_PRODUCT_FROM_DATABASE=Wellsburg MEI Controller #2 + +pci:v00008086d00008D3C* + ID_PRODUCT_FROM_DATABASE=Wellsburg IDE-r Controller + +pci:v00008086d00008D3D* + ID_PRODUCT_FROM_DATABASE=Wellsburg KT Controller + +pci:v00008086d00008D40* + ID_PRODUCT_FROM_DATABASE=Wellsburg LPC Controller + +pci:v00008086d00008D41* + ID_PRODUCT_FROM_DATABASE=Wellsburg LPC Controller + +pci:v00008086d00008D42* + ID_PRODUCT_FROM_DATABASE=Wellsburg LPC Controller + +pci:v00008086d00008D43* + ID_PRODUCT_FROM_DATABASE=Wellsburg LPC Controller + +pci:v00008086d00008D44* + ID_PRODUCT_FROM_DATABASE=Wellsburg LPC Controller + +pci:v00008086d00008D45* + ID_PRODUCT_FROM_DATABASE=Wellsburg LPC Controller + +pci:v00008086d00008D46* + ID_PRODUCT_FROM_DATABASE=Wellsburg LPC Controller + +pci:v00008086d00008D47* + ID_PRODUCT_FROM_DATABASE=Wellsburg LPC Controller + +pci:v00008086d00008D48* + ID_PRODUCT_FROM_DATABASE=Wellsburg LPC Controller + +pci:v00008086d00008D49* + ID_PRODUCT_FROM_DATABASE=Wellsburg LPC Controller + +pci:v00008086d00008D4A* + ID_PRODUCT_FROM_DATABASE=Wellsburg LPC Controller + +pci:v00008086d00008D4B* + ID_PRODUCT_FROM_DATABASE=Wellsburg LPC Controller + +pci:v00008086d00008D4C* + ID_PRODUCT_FROM_DATABASE=Wellsburg LPC Controller + +pci:v00008086d00008D4D* + ID_PRODUCT_FROM_DATABASE=Wellsburg LPC Controller + +pci:v00008086d00008D4E* + ID_PRODUCT_FROM_DATABASE=Wellsburg LPC Controller + +pci:v00008086d00008D4F* + ID_PRODUCT_FROM_DATABASE=Wellsburg LPC Controller + +pci:v00008086d00008D60* + ID_PRODUCT_FROM_DATABASE=Wellsburg sSATA Controller [IDE mode] + +pci:v00008086d00008D62* + ID_PRODUCT_FROM_DATABASE=Wellsburg sSATA Controller [AHCI mode] + +pci:v00008086d00008D64* + ID_PRODUCT_FROM_DATABASE=Wellsburg sSATA Controller [RAID mode] + +pci:v00008086d00008D66* + ID_PRODUCT_FROM_DATABASE=Wellsburg sSATA Controller [RAID mode] + +pci:v00008086d00008D68* + ID_PRODUCT_FROM_DATABASE=Wellsburg sSATA Controller [IDE mode] + +pci:v00008086d00008D6E* + ID_PRODUCT_FROM_DATABASE=Wellsburg sSATA Controller [RAID mode] + +pci:v00008086d00008D7C* + ID_PRODUCT_FROM_DATABASE=Wellsburg SPSR + +pci:v00008086d00008D7D* + ID_PRODUCT_FROM_DATABASE=Wellsburg MS SMBus 0 + +pci:v00008086d00008D7E* + ID_PRODUCT_FROM_DATABASE=Wellsburg MS SMBus 1 + +pci:v00008086d00008D7F* + ID_PRODUCT_FROM_DATABASE=Wellsburg MS SMBus 2 + +pci:v00008086d00009000* + ID_PRODUCT_FROM_DATABASE=IXP2000 Family Network Processor + +pci:v00008086d00009001* + ID_PRODUCT_FROM_DATABASE=IXP2400 Network Processor + +pci:v00008086d00009002* + ID_PRODUCT_FROM_DATABASE=IXP2300 Network Processor + +pci:v00008086d00009004* + ID_PRODUCT_FROM_DATABASE=IXP2800 Network Processor + +pci:v00008086d00009621* + ID_PRODUCT_FROM_DATABASE=Integrated RAID + +pci:v00008086d00009622* + ID_PRODUCT_FROM_DATABASE=Integrated RAID + +pci:v00008086d00009641* + ID_PRODUCT_FROM_DATABASE=Integrated RAID + +pci:v00008086d000096A1* + ID_PRODUCT_FROM_DATABASE=Integrated RAID + +pci:v00008086d00009C00* + ID_PRODUCT_FROM_DATABASE=Lynx Point-LP SATA Controller 1 [IDE mode] + +pci:v00008086d00009C01* + ID_PRODUCT_FROM_DATABASE=Lynx Point-LP SATA Controller 1 [IDE mode] + +pci:v00008086d00009C02* + ID_PRODUCT_FROM_DATABASE=Lynx Point-LP SATA Controller 1 [AHCI mode] + +pci:v00008086d00009C03* + ID_PRODUCT_FROM_DATABASE=Lynx Point-LP SATA Controller 1 [AHCI mode] + +pci:v00008086d00009C04* + ID_PRODUCT_FROM_DATABASE=Lynx Point-LP SATA Controller 1 [RAID mode] + +pci:v00008086d00009C05* + ID_PRODUCT_FROM_DATABASE=Lynx Point-LP SATA Controller 1 [RAID mode] + +pci:v00008086d00009C06* + ID_PRODUCT_FROM_DATABASE=Lynx Point-LP SATA Controller 1 [RAID mode] + +pci:v00008086d00009C07* + ID_PRODUCT_FROM_DATABASE=Lynx Point-LP SATA Controller 1 [RAID mode] + +pci:v00008086d00009C08* + ID_PRODUCT_FROM_DATABASE=Lynx Point-LP SATA Controller 2 [IDE mode] + +pci:v00008086d00009C09* + ID_PRODUCT_FROM_DATABASE=Lynx Point-LP SATA Controller 2 [IDE mode] + +pci:v00008086d00009C0A* + ID_PRODUCT_FROM_DATABASE=LynxPoint-LP SATA Controller [Reserved] + +pci:v00008086d00009C0B* + ID_PRODUCT_FROM_DATABASE=LynxPoint-LP SATA Controller [Reserved] + +pci:v00008086d00009C0C* + ID_PRODUCT_FROM_DATABASE=LynxPoint-LP SATA Controller [Reserved] + +pci:v00008086d00009C0D* + ID_PRODUCT_FROM_DATABASE=LynxPoint-LP SATA Controller [Reserved] + +pci:v00008086d00009C0E* + ID_PRODUCT_FROM_DATABASE=Lynx Point-LP SATA Controller 1 [RAID mode] + +pci:v00008086d00009C0F* + ID_PRODUCT_FROM_DATABASE=Lynx Point-LP SATA Controller 1 [RAID mode] + +pci:v00008086d00009C10* + ID_PRODUCT_FROM_DATABASE=Lynx Point-LP PCI Express Root Port 1 + +pci:v00008086d00009C11* + ID_PRODUCT_FROM_DATABASE=Lynx Point-LP PCI Express Root Port 1 + +pci:v00008086d00009C12* + ID_PRODUCT_FROM_DATABASE=Lynx Point-LP PCI Express Root Port 2 + +pci:v00008086d00009C13* + ID_PRODUCT_FROM_DATABASE=Lynx Point-LP PCI Express Root Port 2 + +pci:v00008086d00009C14* + ID_PRODUCT_FROM_DATABASE=Lynx Point-LP PCI Express Root Port 3 + +pci:v00008086d00009C15* + ID_PRODUCT_FROM_DATABASE=Lynx Point-LP PCI Express Root Port 3 + +pci:v00008086d00009C16* + ID_PRODUCT_FROM_DATABASE=Lynx Point-LP PCI Express Root Port 4 + +pci:v00008086d00009C17* + ID_PRODUCT_FROM_DATABASE=Lynx Point-LP PCI Express Root Port 4 + +pci:v00008086d00009C18* + ID_PRODUCT_FROM_DATABASE=Lynx Point-LP PCI Express Root Port 5 + +pci:v00008086d00009C19* + ID_PRODUCT_FROM_DATABASE=Lynx Point-LP PCI Express Root Port 5 + +pci:v00008086d00009C1A* + ID_PRODUCT_FROM_DATABASE=Lynx Point-LP PCI Express Root Port 6 + +pci:v00008086d00009C1B* + ID_PRODUCT_FROM_DATABASE=Lynx Point-LP PCI Express Root Port 6 + +pci:v00008086d00009C20* + ID_PRODUCT_FROM_DATABASE=Lynx Point-LP HD Audio Controller + +pci:v00008086d00009C21* + ID_PRODUCT_FROM_DATABASE=Lynx Point-LP HD Audio Controller + +pci:v00008086d00009C22* + ID_PRODUCT_FROM_DATABASE=Lynx Point-LP SMBus Controller + +pci:v00008086d00009C23* + ID_PRODUCT_FROM_DATABASE=Lynx Point-LP CHAP Counters + +pci:v00008086d00009C24* + ID_PRODUCT_FROM_DATABASE=Lynx Point-LP Thermal + +pci:v00008086d00009C26* + ID_PRODUCT_FROM_DATABASE=Lynx Point-LP USB EHCI #1 + +pci:v00008086d00009C31* + ID_PRODUCT_FROM_DATABASE=Lynx Point-LP USB xHCI HC + +pci:v00008086d00009C35* + ID_PRODUCT_FROM_DATABASE=Lynx Point-LP SDIO Controller + +pci:v00008086d00009C36* + ID_PRODUCT_FROM_DATABASE=Lynx Point-LP Audio DSP Controller + +pci:v00008086d00009C3A* + ID_PRODUCT_FROM_DATABASE=Lynx Point-LP HECI #0 + +pci:v00008086d00009C3B* + ID_PRODUCT_FROM_DATABASE=Lynx Point-LP HECI #1 + +pci:v00008086d00009C3C* + ID_PRODUCT_FROM_DATABASE=Lynx Point-LP HECI IDER + +pci:v00008086d00009C3D* + ID_PRODUCT_FROM_DATABASE=Lynx Point-LP HECI KT + +pci:v00008086d00009C40* + ID_PRODUCT_FROM_DATABASE=Lynx Point-LP LPC Controller + +pci:v00008086d00009C41* + ID_PRODUCT_FROM_DATABASE=Lynx Point-LP LPC Controller + +pci:v00008086d00009C42* + ID_PRODUCT_FROM_DATABASE=Lynx Point-LP LPC Controller + +pci:v00008086d00009C43* + ID_PRODUCT_FROM_DATABASE=Lynx Point-LP LPC Controller + +pci:v00008086d00009C44* + ID_PRODUCT_FROM_DATABASE=Lynx Point-LP LPC Controller + +pci:v00008086d00009C45* + ID_PRODUCT_FROM_DATABASE=Lynx Point-LP LPC Controller + +pci:v00008086d00009C46* + ID_PRODUCT_FROM_DATABASE=Lynx Point-LP LPC Controller + +pci:v00008086d00009C47* + ID_PRODUCT_FROM_DATABASE=Lynx Point-LP LPC Controller + +pci:v00008086d00009C60* + ID_PRODUCT_FROM_DATABASE=Lynx Point-LP Low Power Sub-System DMA + +pci:v00008086d00009C61* + ID_PRODUCT_FROM_DATABASE=Lynx Point-LP I2C Controller #0 + +pci:v00008086d00009C62* + ID_PRODUCT_FROM_DATABASE=Lynx Point-LP I2C Controller #1 + +pci:v00008086d00009C63* + ID_PRODUCT_FROM_DATABASE=Lynx Point-LP UART Controller #0 + +pci:v00008086d00009C64* + ID_PRODUCT_FROM_DATABASE=Lynx Point-LP UART Controller #1 + +pci:v00008086d00009C65* + ID_PRODUCT_FROM_DATABASE=Lynx Point-LP SPI Controller #0 + +pci:v00008086d00009C66* + ID_PRODUCT_FROM_DATABASE=Lynx Point-LP SPI Controller #1 + +pci:v00008086d0000A000* + ID_PRODUCT_FROM_DATABASE=Atom Processor D4xx/D5xx/N4xx/N5xx DMI Bridge + +pci:v00008086d0000A000sv00008086sd00004F4D* + ID_PRODUCT_FROM_DATABASE=DeskTop Board D510MO + +pci:v00008086d0000A001* + ID_PRODUCT_FROM_DATABASE=Atom Processor D4xx/D5xx/N4xx/N5xx Integrated Graphics Controller + +pci:v00008086d0000A001sv00008086sd00004F4D* + ID_PRODUCT_FROM_DATABASE=DeskTop Board D510MO + +pci:v00008086d0000A002* + ID_PRODUCT_FROM_DATABASE=Atom Processor D4xx/D5xx/N4xx/N5xx Integrated Graphics Controller + +pci:v00008086d0000A003* + ID_PRODUCT_FROM_DATABASE=Atom Processor D4xx/D5xx/N4xx/N5xx CHAPS counter + +pci:v00008086d0000A010* + ID_PRODUCT_FROM_DATABASE=Atom Processor D4xx/D5xx/N4xx/N5xx DMI Bridge + +pci:v00008086d0000A010sv0000144Dsd0000C072* + ID_PRODUCT_FROM_DATABASE=Notebook N150P + +pci:v00008086d0000A011* + ID_PRODUCT_FROM_DATABASE=Atom Processor D4xx/D5xx/N4xx/N5xx Integrated Graphics Controller + +pci:v00008086d0000A011sv0000144Dsd0000C072* + ID_PRODUCT_FROM_DATABASE=Notebook N150P + +pci:v00008086d0000A012* + ID_PRODUCT_FROM_DATABASE=Atom Processor D4xx/D5xx/N4xx/N5xx Integrated Graphics Controller + +pci:v00008086d0000A012sv0000144Dsd0000C072* + ID_PRODUCT_FROM_DATABASE=Notebook N150P + +pci:v00008086d0000A013* + ID_PRODUCT_FROM_DATABASE=Atom Processor D4xx/D5xx/N4xx/N5xx CHAPS counter + +pci:v00008086d0000A620* + ID_PRODUCT_FROM_DATABASE=6400/6402 Advanced Memory Buffer (AMB) + +pci:v00008086d0000B152* + ID_PRODUCT_FROM_DATABASE=21152 PCI-to-PCI Bridge + +pci:v00008086d0000B152sv00008086sd0000B152* + ID_PRODUCT_FROM_DATABASE=21152 PCI-to-PCI Bridge + +pci:v00008086d0000B154* + ID_PRODUCT_FROM_DATABASE=21154 PCI-to-PCI Bridge + +pci:v00008086d0000B555* + ID_PRODUCT_FROM_DATABASE=21555 Non transparent PCI-to-PCI Bridge + +pci:v00008086d0000B555sv000012C7sd00005005* + ID_PRODUCT_FROM_DATABASE=SS7HD PCI Adaptor Card + +pci:v00008086d0000B555sv000012C7sd00005006* + ID_PRODUCT_FROM_DATABASE=SS7HDC cPCI Adaptor Card + +pci:v00008086d0000B555sv000012D9sd0000000A* + ID_PRODUCT_FROM_DATABASE=PCI VoIP Gateway + +pci:v00008086d0000B555sv00004C53sd00001050* + ID_PRODUCT_FROM_DATABASE=CT7 mainboard + +pci:v00008086d0000B555sv00004C53sd00001051* + ID_PRODUCT_FROM_DATABASE=CE7 mainboard + +pci:v00008086d0000B555sv0000E4BFsd00001000* + ID_PRODUCT_FROM_DATABASE=CC8-1-BLUES + +pci:v00008086d0000D130* + ID_PRODUCT_FROM_DATABASE=Core Processor DMI + +pci:v00008086d0000D131* + ID_PRODUCT_FROM_DATABASE=Core Processor DMI + +pci:v00008086d0000D131sv00001028sd000002DA* + ID_PRODUCT_FROM_DATABASE=OptiPlex 980 + +pci:v00008086d0000D132* + ID_PRODUCT_FROM_DATABASE=Core Processor DMI + +pci:v00008086d0000D132sv00001028sd0000040B* + ID_PRODUCT_FROM_DATABASE=Latitude E6510 + +pci:v00008086d0000D133* + ID_PRODUCT_FROM_DATABASE=Core Processor DMI + +pci:v00008086d0000D134* + ID_PRODUCT_FROM_DATABASE=Core Processor DMI + +pci:v00008086d0000D135* + ID_PRODUCT_FROM_DATABASE=Core Processor DMI + +pci:v00008086d0000D136* + ID_PRODUCT_FROM_DATABASE=Core Processor DMI + +pci:v00008086d0000D137* + ID_PRODUCT_FROM_DATABASE=Core Processor DMI + +pci:v00008086d0000D138* + ID_PRODUCT_FROM_DATABASE=Core Processor PCI Express Root Port 1 + +pci:v00008086d0000D138sv00001028sd000002DA* + ID_PRODUCT_FROM_DATABASE=OptiPlex 980 + +pci:v00008086d0000D138sv00001028sd0000040B* + ID_PRODUCT_FROM_DATABASE=Latitude E6510 + +pci:v00008086d0000D139* + ID_PRODUCT_FROM_DATABASE=Core Processor PCI Express Root Port 2 + +pci:v00008086d0000D13A* + ID_PRODUCT_FROM_DATABASE=Core Processor PCI Express Root Port 3 + +pci:v00008086d0000D13B* + ID_PRODUCT_FROM_DATABASE=Core Processor PCI Express Root Port 4 + +pci:v00008086d0000D150* + ID_PRODUCT_FROM_DATABASE=Core Processor QPI Link + +pci:v00008086d0000D151* + ID_PRODUCT_FROM_DATABASE=Core Processor QPI Routing and Protocol Registers + +pci:v00008086d0000D155* + ID_PRODUCT_FROM_DATABASE=Core Processor System Management Registers + +pci:v00008086d0000D156* + ID_PRODUCT_FROM_DATABASE=Core Processor Semaphore and Scratchpad Registers + +pci:v00008086d0000D157* + ID_PRODUCT_FROM_DATABASE=Core Processor System Control and Status Registers + +pci:v00008086d0000D158* + ID_PRODUCT_FROM_DATABASE=Core Processor Miscellaneous Registers + +pci:v000080EE* + ID_VENDOR_FROM_DATABASE=InnoTek Systemberatung GmbH + +pci:v000080EEd0000BEEF* + ID_PRODUCT_FROM_DATABASE=VirtualBox Graphics Adapter + +pci:v000080EEd0000CAFE* + ID_PRODUCT_FROM_DATABASE=VirtualBox Guest Service + +pci:v00008322* + ID_VENDOR_FROM_DATABASE=Sodick America Corp. + +pci:v00008384* + ID_VENDOR_FROM_DATABASE=SigmaTel + +pci:v00008384d00007618* + ID_PRODUCT_FROM_DATABASE=High Definition Audio Codec + +pci:v00008384d00007634* + ID_PRODUCT_FROM_DATABASE=9250 HD Audio Codec + +pci:v00008384d00007662* + ID_PRODUCT_FROM_DATABASE=High Definition Audio Codec + +pci:v00008384d00007662sv0000104Dsd00001E00* + ID_PRODUCT_FROM_DATABASE=High Definition Audio Codec [STAC9872AK] + +pci:v00008384d00007664* + ID_PRODUCT_FROM_DATABASE=High Definition Audio Codec + +pci:v00008384d00007670* + ID_PRODUCT_FROM_DATABASE=9770 High Definition Audio + +pci:v00008384d00007672* + ID_PRODUCT_FROM_DATABASE=9772 High Definition Audio + +pci:v00008384d00007682* + ID_PRODUCT_FROM_DATABASE=IDT High Definition Audio Codec + +pci:v00008384d00007690* + ID_PRODUCT_FROM_DATABASE=9200 HD Audio Codec + +pci:v00008384d00007690sv00001028sd000001C1* + ID_PRODUCT_FROM_DATABASE=Precision 490 + +pci:v00008401* + ID_VENDOR_FROM_DATABASE=TRENDware International Inc. + +pci:v00008686* + ID_VENDOR_FROM_DATABASE=ScaleMP + +pci:v00008686d00001010* + ID_PRODUCT_FROM_DATABASE=vSMPowered system controller [vSMP CTL] + +pci:v00008800* + ID_VENDOR_FROM_DATABASE=Trigem Computer Inc. + +pci:v00008800d00002008* + ID_PRODUCT_FROM_DATABASE=Video assistent component + +pci:v00008866* + ID_VENDOR_FROM_DATABASE=T-Square Design Inc. + +pci:v00008888* + ID_VENDOR_FROM_DATABASE=Silicon Magic + +pci:v00008912* + ID_VENDOR_FROM_DATABASE=TRX + +pci:v00008C4A* + ID_VENDOR_FROM_DATABASE=Winbond + +pci:v00008C4Ad00001980* + ID_PRODUCT_FROM_DATABASE=W89C940 misprogrammed [ne2k] + +pci:v00008E0E* + ID_VENDOR_FROM_DATABASE=Computone Corporation + +pci:v00008E2E* + ID_VENDOR_FROM_DATABASE=KTI + +pci:v00008E2Ed00003000* + ID_PRODUCT_FROM_DATABASE=ET32P2 + +pci:v00009004* + ID_VENDOR_FROM_DATABASE=Adaptec + +pci:v00009004d00000078* + ID_PRODUCT_FROM_DATABASE=AHA-2940U_CN + +pci:v00009004d00001078* + ID_PRODUCT_FROM_DATABASE=AIC-7810 + +pci:v00009004d00001160* + ID_PRODUCT_FROM_DATABASE=AIC-1160 [Family Fibre Channel Adapter] + +pci:v00009004d00002178* + ID_PRODUCT_FROM_DATABASE=AIC-7821 + +pci:v00009004d00003860* + ID_PRODUCT_FROM_DATABASE=AHA-2930CU + +pci:v00009004d00003B78* + ID_PRODUCT_FROM_DATABASE=AHA-4844W/4844UW + +pci:v00009004d00005075* + ID_PRODUCT_FROM_DATABASE=AIC-755x + +pci:v00009004d00005078* + ID_PRODUCT_FROM_DATABASE=AIC-7850 + +pci:v00009004d00005078sv00009004sd00007850* + ID_PRODUCT_FROM_DATABASE=AHA-2904/Integrated AIC-7850 + +pci:v00009004d00005175* + ID_PRODUCT_FROM_DATABASE=AIC-755x + +pci:v00009004d00005178* + ID_PRODUCT_FROM_DATABASE=AIC-7851 + +pci:v00009004d00005275* + ID_PRODUCT_FROM_DATABASE=AIC-755x + +pci:v00009004d00005278* + ID_PRODUCT_FROM_DATABASE=AIC-7852 + +pci:v00009004d00005375* + ID_PRODUCT_FROM_DATABASE=AIC-755x + +pci:v00009004d00005378* + ID_PRODUCT_FROM_DATABASE=AIC-7850 + +pci:v00009004d00005475* + ID_PRODUCT_FROM_DATABASE=AIC-755x + +pci:v00009004d00005478* + ID_PRODUCT_FROM_DATABASE=AIC-7850 + +pci:v00009004d00005575* + ID_PRODUCT_FROM_DATABASE=AVA-2930 + +pci:v00009004d00005578* + ID_PRODUCT_FROM_DATABASE=AIC-7855 + +pci:v00009004d00005647* + ID_PRODUCT_FROM_DATABASE=ANA-7711 TCP Offload Engine + +pci:v00009004d00005647sv00009004sd00007710* + ID_PRODUCT_FROM_DATABASE=ANA-7711F TCP Offload Engine - Optical + +pci:v00009004d00005647sv00009004sd00007711* + ID_PRODUCT_FROM_DATABASE=ANA-7711LP TCP Offload Engine - Copper + +pci:v00009004d00005675* + ID_PRODUCT_FROM_DATABASE=AIC-755x + +pci:v00009004d00005678* + ID_PRODUCT_FROM_DATABASE=AIC-7856 + +pci:v00009004d00005775* + ID_PRODUCT_FROM_DATABASE=AIC-755x + +pci:v00009004d00005778* + ID_PRODUCT_FROM_DATABASE=AIC-7850 + +pci:v00009004d00005800* + ID_PRODUCT_FROM_DATABASE=AIC-5800 + +pci:v00009004d00005900* + ID_PRODUCT_FROM_DATABASE=ANA-5910/5930/5940 ATM155 & 25 LAN Adapter + +pci:v00009004d00005905* + ID_PRODUCT_FROM_DATABASE=ANA-5910A/5930A/5940A ATM Adapter + +pci:v00009004d00006038* + ID_PRODUCT_FROM_DATABASE=AIC-3860 + +pci:v00009004d00006075* + ID_PRODUCT_FROM_DATABASE=AIC-1480 / APA-1480 + +pci:v00009004d00006075sv00009004sd00007560* + ID_PRODUCT_FROM_DATABASE=AIC-1480 / APA-1480 Cardbus + +pci:v00009004d00006078* + ID_PRODUCT_FROM_DATABASE=AIC-7860 + +pci:v00009004d00006178* + ID_PRODUCT_FROM_DATABASE=AIC-7861 + +pci:v00009004d00006178sv00009004sd00007861* + ID_PRODUCT_FROM_DATABASE=AHA-2940AU Single + +pci:v00009004d00006278* + ID_PRODUCT_FROM_DATABASE=AIC-7860 + +pci:v00009004d00006378* + ID_PRODUCT_FROM_DATABASE=AIC-7860 + +pci:v00009004d00006478* + ID_PRODUCT_FROM_DATABASE=AIC-786x + +pci:v00009004d00006578* + ID_PRODUCT_FROM_DATABASE=AIC-786x + +pci:v00009004d00006678* + ID_PRODUCT_FROM_DATABASE=AIC-786x + +pci:v00009004d00006778* + ID_PRODUCT_FROM_DATABASE=AIC-786x + +pci:v00009004d00006915* + ID_PRODUCT_FROM_DATABASE=ANA620xx/ANA69011A + +pci:v00009004d00006915sv00009004sd00000008* + ID_PRODUCT_FROM_DATABASE=ANA69011A/TX 10/100 + +pci:v00009004d00006915sv00009004sd00000009* + ID_PRODUCT_FROM_DATABASE=ANA69011A/TX 10/100 + +pci:v00009004d00006915sv00009004sd00000010* + ID_PRODUCT_FROM_DATABASE=ANA62022 2-port 10/100 + +pci:v00009004d00006915sv00009004sd00000018* + ID_PRODUCT_FROM_DATABASE=ANA62044 4-port 10/100 + +pci:v00009004d00006915sv00009004sd00000019* + ID_PRODUCT_FROM_DATABASE=ANA62044 4-port 10/100 + +pci:v00009004d00006915sv00009004sd00000020* + ID_PRODUCT_FROM_DATABASE=ANA62022 2-port 10/100 + +pci:v00009004d00006915sv00009004sd00000028* + ID_PRODUCT_FROM_DATABASE=ANA69011A/TX 10/100 + +pci:v00009004d00006915sv00009004sd00008008* + ID_PRODUCT_FROM_DATABASE=ANA69011A/TX 64 bit 10/100 + +pci:v00009004d00006915sv00009004sd00008009* + ID_PRODUCT_FROM_DATABASE=ANA69011A/TX 64 bit 10/100 + +pci:v00009004d00006915sv00009004sd00008010* + ID_PRODUCT_FROM_DATABASE=ANA62022 2-port 64 bit 10/100 + +pci:v00009004d00006915sv00009004sd00008018* + ID_PRODUCT_FROM_DATABASE=ANA62044 4-port 64 bit 10/100 + +pci:v00009004d00006915sv00009004sd00008019* + ID_PRODUCT_FROM_DATABASE=ANA62044 4-port 64 bit 10/100 + +pci:v00009004d00006915sv00009004sd00008020* + ID_PRODUCT_FROM_DATABASE=ANA62022 2-port 64 bit 10/100 + +pci:v00009004d00006915sv00009004sd00008028* + ID_PRODUCT_FROM_DATABASE=ANA69011A/TX 64 bit 10/100 + +pci:v00009004d00007078* + ID_PRODUCT_FROM_DATABASE=AHA-294x / AIC-7870 + +pci:v00009004d00007178* + ID_PRODUCT_FROM_DATABASE=AHA-2940/2940W / AIC-7871 + +pci:v00009004d00007278* + ID_PRODUCT_FROM_DATABASE=AHA-3940/3940W / AIC-7872 + +pci:v00009004d00007378* + ID_PRODUCT_FROM_DATABASE=AHA-3985 / AIC-7873 + +pci:v00009004d00007478* + ID_PRODUCT_FROM_DATABASE=AHA-2944/2944W / AIC-7874 + +pci:v00009004d00007578* + ID_PRODUCT_FROM_DATABASE=AHA-3944/3944W / AIC-7875 + +pci:v00009004d00007678* + ID_PRODUCT_FROM_DATABASE=AHA-4944W/UW / AIC-7876 + +pci:v00009004d00007710* + ID_PRODUCT_FROM_DATABASE=ANA-7711F Network Accelerator Card (NAC) - Optical + +pci:v00009004d00007711* + ID_PRODUCT_FROM_DATABASE=ANA-7711C Network Accelerator Card (NAC) - Copper + +pci:v00009004d00007778* + ID_PRODUCT_FROM_DATABASE=AIC-787x + +pci:v00009004d00007810* + ID_PRODUCT_FROM_DATABASE=AIC-7810 + +pci:v00009004d00007815* + ID_PRODUCT_FROM_DATABASE=AIC-7815 RAID+Memory Controller IC + +pci:v00009004d00007815sv00009004sd00007815* + ID_PRODUCT_FROM_DATABASE=ARO-1130U2 RAID Controller + +pci:v00009004d00007815sv00009004sd00007840* + ID_PRODUCT_FROM_DATABASE=AIC-7815 RAID+Memory Controller IC + +pci:v00009004d00007850* + ID_PRODUCT_FROM_DATABASE=AIC-7850 + +pci:v00009004d00007855* + ID_PRODUCT_FROM_DATABASE=AHA-2930 + +pci:v00009004d00007860* + ID_PRODUCT_FROM_DATABASE=AIC-7860 + +pci:v00009004d00007870* + ID_PRODUCT_FROM_DATABASE=AIC-7870 + +pci:v00009004d00007871* + ID_PRODUCT_FROM_DATABASE=AHA-2940 + +pci:v00009004d00007872* + ID_PRODUCT_FROM_DATABASE=AHA-3940 + +pci:v00009004d00007873* + ID_PRODUCT_FROM_DATABASE=AHA-3980 + +pci:v00009004d00007874* + ID_PRODUCT_FROM_DATABASE=AHA-2944 + +pci:v00009004d00007880* + ID_PRODUCT_FROM_DATABASE=AIC-7880P + +pci:v00009004d00007890* + ID_PRODUCT_FROM_DATABASE=AIC-7890 + +pci:v00009004d00007891* + ID_PRODUCT_FROM_DATABASE=AIC-789x + +pci:v00009004d00007892* + ID_PRODUCT_FROM_DATABASE=AIC-789x + +pci:v00009004d00007893* + ID_PRODUCT_FROM_DATABASE=AIC-789x + +pci:v00009004d00007894* + ID_PRODUCT_FROM_DATABASE=AIC-789x + +pci:v00009004d00007895* + ID_PRODUCT_FROM_DATABASE=AHA-2940U/UW / AHA-39xx / AIC-7895 + +pci:v00009004d00007895sv00009004sd00007890* + ID_PRODUCT_FROM_DATABASE=AHA-2940U/2940UW Dual AHA-394xAU/AUW/AUWD AIC-7895B + +pci:v00009004d00007895sv00009004sd00007891* + ID_PRODUCT_FROM_DATABASE=AHA-2940U/2940UW Dual + +pci:v00009004d00007895sv00009004sd00007892* + ID_PRODUCT_FROM_DATABASE=AHA-3940AU/AUW/AUWD/UWD + +pci:v00009004d00007895sv00009004sd00007894* + ID_PRODUCT_FROM_DATABASE=AHA-3944AUWD + +pci:v00009004d00007895sv00009004sd00007895* + ID_PRODUCT_FROM_DATABASE=AHA-2940U/2940UW Dual AHA-394xAU/AUW/AUWD AIC-7895B + +pci:v00009004d00007895sv00009004sd00007896* + ID_PRODUCT_FROM_DATABASE=AHA-2940U/2940UW Dual AHA-394xAU/AUW/AUWD AIC-7895B + +pci:v00009004d00007895sv00009004sd00007897* + ID_PRODUCT_FROM_DATABASE=AHA-2940U/2940UW Dual AHA-394xAU/AUW/AUWD AIC-7895B + +pci:v00009004d00007896* + ID_PRODUCT_FROM_DATABASE=AIC-789x + +pci:v00009004d00007897* + ID_PRODUCT_FROM_DATABASE=AIC-789x + +pci:v00009004d00008078* + ID_PRODUCT_FROM_DATABASE=AIC-7880U + +pci:v00009004d00008078sv00009004sd00007880* + ID_PRODUCT_FROM_DATABASE=AIC-7880P Ultra/Ultra Wide SCSI Chipset + +pci:v00009004d00008178* + ID_PRODUCT_FROM_DATABASE=AHA-2940U/UW/D / AIC-7881U + +pci:v00009004d00008178sv00009004sd00007881* + ID_PRODUCT_FROM_DATABASE=AHA-2940UW SCSI Host Adapter + +pci:v00009004d00008278* + ID_PRODUCT_FROM_DATABASE=AHA-3940U/UW/UWD / AIC-7882U + +pci:v00009004d00008378* + ID_PRODUCT_FROM_DATABASE=AHA-3940U/UW / AIC-7883U + +pci:v00009004d00008478* + ID_PRODUCT_FROM_DATABASE=AHA-2944UW / AIC-7884U + +pci:v00009004d00008578* + ID_PRODUCT_FROM_DATABASE=AHA-3944U/UWD / AIC-7885 + +pci:v00009004d00008678* + ID_PRODUCT_FROM_DATABASE=AHA-4944UW / AIC-7886 + +pci:v00009004d00008778* + ID_PRODUCT_FROM_DATABASE=AHA-2940UW Pro / AIC-788x + +pci:v00009004d00008778sv00009004sd00007887* + ID_PRODUCT_FROM_DATABASE=2940UW Pro Ultra-Wide SCSI Controller + +pci:v00009004d00008878* + ID_PRODUCT_FROM_DATABASE=AHA-2930UW / AIC-7888 + +pci:v00009004d00008878sv00009004sd00007888* + ID_PRODUCT_FROM_DATABASE=AHA-2930UW SCSI Controller + +pci:v00009004d00008B78* + ID_PRODUCT_FROM_DATABASE=ABA-1030 + +pci:v00009004d0000EC78* + ID_PRODUCT_FROM_DATABASE=AHA-4944W/UW + +pci:v00009005* + ID_VENDOR_FROM_DATABASE=Adaptec + +pci:v00009005d00000010* + ID_PRODUCT_FROM_DATABASE=AHA-2940U2/U2W + +pci:v00009005d00000010sv00009005sd00002180* + ID_PRODUCT_FROM_DATABASE=AHA-2940U2 SCSI Controller + +pci:v00009005d00000010sv00009005sd00008100* + ID_PRODUCT_FROM_DATABASE=AHA-2940U2B SCSI Controller + +pci:v00009005d00000010sv00009005sd0000A100* + ID_PRODUCT_FROM_DATABASE=AHA-2940U2B SCSI Controller + +pci:v00009005d00000010sv00009005sd0000A180* + ID_PRODUCT_FROM_DATABASE=AHA-2940U2W SCSI Controller + +pci:v00009005d00000010sv00009005sd0000E100* + ID_PRODUCT_FROM_DATABASE=AHA-2950U2B SCSI Controller + +pci:v00009005d00000011* + ID_PRODUCT_FROM_DATABASE=AHA-2930U2 + +pci:v00009005d00000013* + ID_PRODUCT_FROM_DATABASE=78902 + +pci:v00009005d00000013sv00009005sd00000003* + ID_PRODUCT_FROM_DATABASE=AAA-131U2 Array1000 1 Channel RAID Controller + +pci:v00009005d00000013sv00009005sd0000000F* + ID_PRODUCT_FROM_DATABASE=AIC7890_ARO + +pci:v00009005d0000001F* + ID_PRODUCT_FROM_DATABASE=AHA-2940U2/U2W / 7890/7891 + +pci:v00009005d0000001Fsv00009005sd0000000F* + ID_PRODUCT_FROM_DATABASE=2940U2W SCSI Controller + +pci:v00009005d0000001Fsv00009005sd0000A180* + ID_PRODUCT_FROM_DATABASE=2940U2W SCSI Controller + +pci:v00009005d00000020* + ID_PRODUCT_FROM_DATABASE=AIC-7890 + +pci:v00009005d0000002F* + ID_PRODUCT_FROM_DATABASE=AIC-7890 + +pci:v00009005d00000030* + ID_PRODUCT_FROM_DATABASE=AIC-7890 + +pci:v00009005d0000003F* + ID_PRODUCT_FROM_DATABASE=AIC-7890 + +pci:v00009005d00000050* + ID_PRODUCT_FROM_DATABASE=AHA-3940U2x/395U2x + +pci:v00009005d00000050sv00009005sd0000F500* + ID_PRODUCT_FROM_DATABASE=AHA-3950U2B + +pci:v00009005d00000050sv00009005sd0000FFFF* + ID_PRODUCT_FROM_DATABASE=AHA-3950U2B + +pci:v00009005d00000051* + ID_PRODUCT_FROM_DATABASE=AHA-3950U2D + +pci:v00009005d00000051sv00009005sd0000B500* + ID_PRODUCT_FROM_DATABASE=AHA-3950U2D + +pci:v00009005d00000053* + ID_PRODUCT_FROM_DATABASE=AIC-7896 SCSI Controller + +pci:v00009005d00000053sv00009005sd0000FFFF* + ID_PRODUCT_FROM_DATABASE=AIC-7896 SCSI Controller mainboard implementation + +pci:v00009005d0000005F* + ID_PRODUCT_FROM_DATABASE=AIC-7896U2/7897U2 + +pci:v00009005d00000080* + ID_PRODUCT_FROM_DATABASE=AIC-7892A U160/m + +pci:v00009005d00000080sv00000E11sd0000E2A0* + ID_PRODUCT_FROM_DATABASE=Compaq 64-Bit/66MHz Wide Ultra3 SCSI Adapter + +pci:v00009005d00000080sv00009005sd00006220* + ID_PRODUCT_FROM_DATABASE=AHA-29160C + +pci:v00009005d00000080sv00009005sd000062A0* + ID_PRODUCT_FROM_DATABASE=29160N Ultra160 SCSI Controller + +pci:v00009005d00000080sv00009005sd0000E220* + ID_PRODUCT_FROM_DATABASE=29160LP Low Profile Ultra160 SCSI Controller + +pci:v00009005d00000080sv00009005sd0000E2A0* + ID_PRODUCT_FROM_DATABASE=29160 Ultra160 SCSI Controller + +pci:v00009005d00000081* + ID_PRODUCT_FROM_DATABASE=AIC-7892B U160/m + +pci:v00009005d00000081sv00009005sd000062A1* + ID_PRODUCT_FROM_DATABASE=19160 Ultra160 SCSI Controller + +pci:v00009005d00000083* + ID_PRODUCT_FROM_DATABASE=AIC-7892D U160/m + +pci:v00009005d0000008F* + ID_PRODUCT_FROM_DATABASE=AIC-7892P U160/m + +pci:v00009005d0000008Fsv00001179sd00000001* + ID_PRODUCT_FROM_DATABASE=Magnia Z310 + +pci:v00009005d0000008Fsv000015D9sd00009005* + ID_PRODUCT_FROM_DATABASE=Onboard SCSI Host Adapter + +pci:v00009005d00000092* + ID_PRODUCT_FROM_DATABASE=AVC-2010 [VideoH!] + +pci:v00009005d00000093* + ID_PRODUCT_FROM_DATABASE=AVC-2410 [VideoH!] + +pci:v00009005d000000C0* + ID_PRODUCT_FROM_DATABASE=AHA-3960D / AIC-7899A U160/m + +pci:v00009005d000000C0sv00000E11sd0000F620* + ID_PRODUCT_FROM_DATABASE=Compaq 64-Bit/66MHz Dual Channel Wide Ultra3 SCSI Adapter + +pci:v00009005d000000C0sv00009005sd0000F620* + ID_PRODUCT_FROM_DATABASE=AHA-3960D U160/m + +pci:v00009005d000000C1* + ID_PRODUCT_FROM_DATABASE=AIC-7899B U160/m + +pci:v00009005d000000C3* + ID_PRODUCT_FROM_DATABASE=AIC-7899D U160/m + +pci:v00009005d000000C5* + ID_PRODUCT_FROM_DATABASE=RAID subsystem HBA + +pci:v00009005d000000C5sv00001028sd000000C5* + ID_PRODUCT_FROM_DATABASE=PowerEdge 2400,2500,2550,4400 + +pci:v00009005d000000CF* + ID_PRODUCT_FROM_DATABASE=AIC-7899P U160/m + +pci:v00009005d000000CFsv00001028sd000000CE* + ID_PRODUCT_FROM_DATABASE=PowerEdge 1400 + +pci:v00009005d000000CFsv00001028sd000000D1* + ID_PRODUCT_FROM_DATABASE=PowerEdge 2550 + +pci:v00009005d000000CFsv00001028sd000000D9* + ID_PRODUCT_FROM_DATABASE=PowerEdge 2500 + +pci:v00009005d000000CFsv000010F1sd00002462* + ID_PRODUCT_FROM_DATABASE=Thunder K7 S2462 + +pci:v00009005d000000CFsv000015D9sd00009005* + ID_PRODUCT_FROM_DATABASE=Onboard SCSI Host Adapter + +pci:v00009005d000000CFsv00008086sd00003411* + ID_PRODUCT_FROM_DATABASE=SDS2 Mainboard + +pci:v00009005d00000241* + ID_PRODUCT_FROM_DATABASE=Serial ATA II RAID 1420SA + +pci:v00009005d00000242* + ID_PRODUCT_FROM_DATABASE=Serial ATA II RAID 1220SA + +pci:v00009005d00000243* + ID_PRODUCT_FROM_DATABASE=Serial ATA II RAID 1430SA + +pci:v00009005d00000244* + ID_PRODUCT_FROM_DATABASE=eSATA II RAID 1225SA + +pci:v00009005d00000250* + ID_PRODUCT_FROM_DATABASE=ServeRAID Controller + +pci:v00009005d00000250sv00001014sd00000279* + ID_PRODUCT_FROM_DATABASE=ServeRAID 6M + +pci:v00009005d00000250sv00001014sd0000028C* + ID_PRODUCT_FROM_DATABASE=ServeRAID 6i/6i+ + +pci:v00009005d00000250sv00001014sd0000028E* + ID_PRODUCT_FROM_DATABASE=ServeRAID 7k + +pci:v00009005d00000279* + ID_PRODUCT_FROM_DATABASE=ServeRAID 6M + +pci:v00009005d00000283* + ID_PRODUCT_FROM_DATABASE=AAC-RAID + +pci:v00009005d00000283sv00009005sd00000283* + ID_PRODUCT_FROM_DATABASE=Catapult + +pci:v00009005d00000284* + ID_PRODUCT_FROM_DATABASE=AAC-RAID + +pci:v00009005d00000284sv00009005sd00000284* + ID_PRODUCT_FROM_DATABASE=Tomcat + +pci:v00009005d00000285* + ID_PRODUCT_FROM_DATABASE=AAC-RAID + +pci:v00009005d00000285sv00000E11sd00000295* + ID_PRODUCT_FROM_DATABASE=SATA 6Ch (Bearcat) + +pci:v00009005d00000285sv00001014sd000002F2* + ID_PRODUCT_FROM_DATABASE=ServeRAID 8i + +pci:v00009005d00000285sv00001028sd00000287* + ID_PRODUCT_FROM_DATABASE=PowerEdge Expandable RAID Controller 320/DC + +pci:v00009005d00000285sv00001028sd00000291* + ID_PRODUCT_FROM_DATABASE=CERC SATA RAID 2 PCI SATA 6ch (DellCorsair) + +pci:v00009005d00000285sv0000103Csd00003227* + ID_PRODUCT_FROM_DATABASE=AAR-2610SA + +pci:v00009005d00000285sv0000108Esd00000286* + ID_PRODUCT_FROM_DATABASE=STK RAID INT + +pci:v00009005d00000285sv0000108Esd00000287* + ID_PRODUCT_FROM_DATABASE=STK RAID EXT + +pci:v00009005d00000285sv0000108Esd00007AAC* + ID_PRODUCT_FROM_DATABASE=STK RAID REM + +pci:v00009005d00000285sv0000108Esd00007AAE* + ID_PRODUCT_FROM_DATABASE=STK RAID EX + +pci:v00009005d00000285sv000015D9sd000002B5* + ID_PRODUCT_FROM_DATABASE=SMC AOC-USAS-S4i + +pci:v00009005d00000285sv000015D9sd000002B6* + ID_PRODUCT_FROM_DATABASE=SMC AOC-USAS-S8i + +pci:v00009005d00000285sv000015D9sd000002C9* + ID_PRODUCT_FROM_DATABASE=SMC AOC-USAS-S4iR + +pci:v00009005d00000285sv000015D9sd000002CA* + ID_PRODUCT_FROM_DATABASE=SMC AOC-USAS-S8iR + +pci:v00009005d00000285sv000015D9sd000002D2* + ID_PRODUCT_FROM_DATABASE=SMC AOC-USAS-S8i-LP + +pci:v00009005d00000285sv000015D9sd000002D3* + ID_PRODUCT_FROM_DATABASE=SMC AOC-USAS-S8iR-LP + +pci:v00009005d00000285sv000017AAsd00000286* + ID_PRODUCT_FROM_DATABASE=Legend S220 (Legend Crusader) + +pci:v00009005d00000285sv000017AAsd00000287* + ID_PRODUCT_FROM_DATABASE=Legend S230 (Legend Vulcan) + +pci:v00009005d00000285sv00009005sd00000285* + ID_PRODUCT_FROM_DATABASE=2200S (Vulcan) + +pci:v00009005d00000285sv00009005sd00000286* + ID_PRODUCT_FROM_DATABASE=2120S (Crusader) + +pci:v00009005d00000285sv00009005sd00000287* + ID_PRODUCT_FROM_DATABASE=2200S (Vulcan-2m) + +pci:v00009005d00000285sv00009005sd00000288* + ID_PRODUCT_FROM_DATABASE=3230S (Harrier) + +pci:v00009005d00000285sv00009005sd00000289* + ID_PRODUCT_FROM_DATABASE=3240S (Tornado) + +pci:v00009005d00000285sv00009005sd0000028A* + ID_PRODUCT_FROM_DATABASE=ASR-2020ZCR + +pci:v00009005d00000285sv00009005sd0000028B* + ID_PRODUCT_FROM_DATABASE=ASR-2025ZCR (Terminator) + +pci:v00009005d00000285sv00009005sd0000028E* + ID_PRODUCT_FROM_DATABASE=ASR-2020SA (Skyhawk) + +pci:v00009005d00000285sv00009005sd0000028F* + ID_PRODUCT_FROM_DATABASE=ASR-2025SA + +pci:v00009005d00000285sv00009005sd00000290* + ID_PRODUCT_FROM_DATABASE=AAR-2410SA PCI SATA 4ch (Jaguar II) + +pci:v00009005d00000285sv00009005sd00000292* + ID_PRODUCT_FROM_DATABASE=AAR-2810SA PCI SATA 8ch (Corsair-8) + +pci:v00009005d00000285sv00009005sd00000293* + ID_PRODUCT_FROM_DATABASE=AAR-21610SA PCI SATA 16ch (Corsair-16) + +pci:v00009005d00000285sv00009005sd00000294* + ID_PRODUCT_FROM_DATABASE=ESD SO-DIMM PCI-X SATA ZCR (Prowler) + +pci:v00009005d00000285sv00009005sd00000296* + ID_PRODUCT_FROM_DATABASE=ASR-2240S + +pci:v00009005d00000285sv00009005sd00000297* + ID_PRODUCT_FROM_DATABASE=ASR-4005SAS + +pci:v00009005d00000285sv00009005sd00000298* + ID_PRODUCT_FROM_DATABASE=ASR-4000 + +pci:v00009005d00000285sv00009005sd00000299* + ID_PRODUCT_FROM_DATABASE=ASR-4800SAS + +pci:v00009005d00000285sv00009005sd0000029A* + ID_PRODUCT_FROM_DATABASE=4805SAS + +pci:v00009005d00000285sv00009005sd000002A4* + ID_PRODUCT_FROM_DATABASE=ICP ICP9085LI + +pci:v00009005d00000285sv00009005sd000002A5* + ID_PRODUCT_FROM_DATABASE=ICP ICP5085BR + +pci:v00009005d00000285sv00009005sd000002B5* + ID_PRODUCT_FROM_DATABASE=ASR5800 + +pci:v00009005d00000285sv00009005sd000002B6* + ID_PRODUCT_FROM_DATABASE=ASR5805 + +pci:v00009005d00000285sv00009005sd000002B7* + ID_PRODUCT_FROM_DATABASE=ASR5808 + +pci:v00009005d00000285sv00009005sd000002B8* + ID_PRODUCT_FROM_DATABASE=ICP5445SL + +pci:v00009005d00000285sv00009005sd000002B9* + ID_PRODUCT_FROM_DATABASE=ICP5085SL + +pci:v00009005d00000285sv00009005sd000002BA* + ID_PRODUCT_FROM_DATABASE=ICP5805SL + +pci:v00009005d00000285sv00009005sd000002BB* + ID_PRODUCT_FROM_DATABASE=3405 + +pci:v00009005d00000285sv00009005sd000002BC* + ID_PRODUCT_FROM_DATABASE=3805 + +pci:v00009005d00000285sv00009005sd000002BD* + ID_PRODUCT_FROM_DATABASE=31205 + +pci:v00009005d00000285sv00009005sd000002BE* + ID_PRODUCT_FROM_DATABASE=31605 + +pci:v00009005d00000285sv00009005sd000002BF* + ID_PRODUCT_FROM_DATABASE=ICP ICP5045BL + +pci:v00009005d00000285sv00009005sd000002C0* + ID_PRODUCT_FROM_DATABASE=ICP ICP5085BL + +pci:v00009005d00000285sv00009005sd000002C1* + ID_PRODUCT_FROM_DATABASE=ICP ICP5125BR + +pci:v00009005d00000285sv00009005sd000002C2* + ID_PRODUCT_FROM_DATABASE=ICP ICP5165BR + +pci:v00009005d00000285sv00009005sd000002C3* + ID_PRODUCT_FROM_DATABASE=51205 + +pci:v00009005d00000285sv00009005sd000002C4* + ID_PRODUCT_FROM_DATABASE=51605 + +pci:v00009005d00000285sv00009005sd000002C5* + ID_PRODUCT_FROM_DATABASE=ICP ICP5125SL + +pci:v00009005d00000285sv00009005sd000002C6* + ID_PRODUCT_FROM_DATABASE=ICP ICP5165SL + +pci:v00009005d00000285sv00009005sd000002C7* + ID_PRODUCT_FROM_DATABASE=3085 + +pci:v00009005d00000285sv00009005sd000002C8* + ID_PRODUCT_FROM_DATABASE=ICP5805BL + +pci:v00009005d00000285sv00009005sd000002CE* + ID_PRODUCT_FROM_DATABASE=51245 + +pci:v00009005d00000285sv00009005sd000002CF* + ID_PRODUCT_FROM_DATABASE=51645 + +pci:v00009005d00000285sv00009005sd000002D0* + ID_PRODUCT_FROM_DATABASE=52445 + +pci:v00009005d00000285sv00009005sd000002D1* + ID_PRODUCT_FROM_DATABASE=5405 + +pci:v00009005d00000285sv00009005sd000002D4* + ID_PRODUCT_FROM_DATABASE=ASR-2045 + +pci:v00009005d00000285sv00009005sd000002D5* + ID_PRODUCT_FROM_DATABASE=ASR-2405 + +pci:v00009005d00000285sv00009005sd000002D6* + ID_PRODUCT_FROM_DATABASE=ASR-2445 + +pci:v00009005d00000285sv00009005sd000002D7* + ID_PRODUCT_FROM_DATABASE=ASR-2805 + +pci:v00009005d00000285sv00009005sd000002D8* + ID_PRODUCT_FROM_DATABASE=5405G + +pci:v00009005d00000285sv00009005sd000002D9* + ID_PRODUCT_FROM_DATABASE=5445G + +pci:v00009005d00000285sv00009005sd000002DA* + ID_PRODUCT_FROM_DATABASE=5805G + +pci:v00009005d00000285sv00009005sd000002DB* + ID_PRODUCT_FROM_DATABASE=5085G + +pci:v00009005d00000285sv00009005sd000002DC* + ID_PRODUCT_FROM_DATABASE=51245G + +pci:v00009005d00000285sv00009005sd000002DD* + ID_PRODUCT_FROM_DATABASE=51645G + +pci:v00009005d00000285sv00009005sd000002DE* + ID_PRODUCT_FROM_DATABASE=52445G + +pci:v00009005d00000285sv00009005sd000002DF* + ID_PRODUCT_FROM_DATABASE=ASR-2045G + +pci:v00009005d00000285sv00009005sd000002E0* + ID_PRODUCT_FROM_DATABASE=ASR-2405G + +pci:v00009005d00000285sv00009005sd000002E1* + ID_PRODUCT_FROM_DATABASE=ASR-2445G + +pci:v00009005d00000285sv00009005sd000002E2* + ID_PRODUCT_FROM_DATABASE=ASR-2805G + +pci:v00009005d00000286* + ID_PRODUCT_FROM_DATABASE=AAC-RAID (Rocket) + +pci:v00009005d00000286sv00001014sd0000034D* + ID_PRODUCT_FROM_DATABASE=8s + +pci:v00009005d00000286sv00001014sd00009540* + ID_PRODUCT_FROM_DATABASE=ServeRAID 8k/8k-l4 + +pci:v00009005d00000286sv00001014sd00009580* + ID_PRODUCT_FROM_DATABASE=ServeRAID 8k/8k-l8 + +pci:v00009005d00000286sv00009005sd0000028C* + ID_PRODUCT_FROM_DATABASE=ASR-2230S + ASR-2230SLP PCI-X (Lancer) + +pci:v00009005d00000286sv00009005sd0000028D* + ID_PRODUCT_FROM_DATABASE=ASR-2130S + +pci:v00009005d00000286sv00009005sd0000029B* + ID_PRODUCT_FROM_DATABASE=ASR-2820SA + +pci:v00009005d00000286sv00009005sd0000029C* + ID_PRODUCT_FROM_DATABASE=ASR-2620SA + +pci:v00009005d00000286sv00009005sd0000029D* + ID_PRODUCT_FROM_DATABASE=ASR-2420SA + +pci:v00009005d00000286sv00009005sd0000029E* + ID_PRODUCT_FROM_DATABASE=ICP ICP9024R0 + +pci:v00009005d00000286sv00009005sd0000029F* + ID_PRODUCT_FROM_DATABASE=ICP ICP9014R0 + +pci:v00009005d00000286sv00009005sd000002A0* + ID_PRODUCT_FROM_DATABASE=ICP ICP9047MA + +pci:v00009005d00000286sv00009005sd000002A1* + ID_PRODUCT_FROM_DATABASE=ICP ICP9087MA + +pci:v00009005d00000286sv00009005sd000002A2* + ID_PRODUCT_FROM_DATABASE=3800 + +pci:v00009005d00000286sv00009005sd000002A3* + ID_PRODUCT_FROM_DATABASE=ICP ICP5445AU + +pci:v00009005d00000286sv00009005sd000002A4* + ID_PRODUCT_FROM_DATABASE=ICP ICP9085LI + +pci:v00009005d00000286sv00009005sd000002A5* + ID_PRODUCT_FROM_DATABASE=ICP ICP5085BR + +pci:v00009005d00000286sv00009005sd000002A6* + ID_PRODUCT_FROM_DATABASE=ICP9067MA + +pci:v00009005d00000286sv00009005sd000002A7* + ID_PRODUCT_FROM_DATABASE=3805 + +pci:v00009005d00000286sv00009005sd000002A8* + ID_PRODUCT_FROM_DATABASE=3400 + +pci:v00009005d00000286sv00009005sd000002A9* + ID_PRODUCT_FROM_DATABASE=ICP ICP5085AU + +pci:v00009005d00000286sv00009005sd000002AA* + ID_PRODUCT_FROM_DATABASE=ICP ICP5045AU + +pci:v00009005d00000286sv00009005sd000002AC* + ID_PRODUCT_FROM_DATABASE=1800 + +pci:v00009005d00000286sv00009005sd000002B3* + ID_PRODUCT_FROM_DATABASE=2400 + +pci:v00009005d00000286sv00009005sd000002B4* + ID_PRODUCT_FROM_DATABASE=ICP ICP5045AL + +pci:v00009005d00000286sv00009005sd00000800* + ID_PRODUCT_FROM_DATABASE=Callisto + +pci:v00009005d0000028B* + ID_PRODUCT_FROM_DATABASE=Series 6 - 6G SAS/PCIe 2 + +pci:v00009005d0000028Bsv00009005sd00000200* + ID_PRODUCT_FROM_DATABASE=Series 6 Entry Level - ASR-6405E - 4 internal 6G SAS ports + +pci:v00009005d0000028Bsv00009005sd00000201* + ID_PRODUCT_FROM_DATABASE=Series 6 Entry Level - ASR-6805E - 8 internal 6G SAS ports + +pci:v00009005d0000028Bsv00009005sd00000300* + ID_PRODUCT_FROM_DATABASE=Series 6 - ASR-6405 - 4 internal 6G SAS ports + +pci:v00009005d0000028Bsv00009005sd00000301* + ID_PRODUCT_FROM_DATABASE=Series 6 - ASR-6805 - 8 internal 6G SAS ports + +pci:v00009005d0000028Bsv00009005sd00000302* + ID_PRODUCT_FROM_DATABASE=Series 6 - ASR-6445 - 4 internal and 4 external 6G SAS ports + +pci:v00009005d0000028Bsv00009005sd00000310* + ID_PRODUCT_FROM_DATABASE=Series 6 Connectors on Top - ASR-6405T - 4 internal 6G SAS ports + +pci:v00009005d0000028Bsv00009005sd00000311* + ID_PRODUCT_FROM_DATABASE=Series 6 Connectors on Top - ASR-6805T - 8 internal 6G SAS + +pci:v00009005d0000028Bsv00009005sd00000400* + ID_PRODUCT_FROM_DATABASE=Series 6 - ASR-61205 - 12 internal 6G SAS ports + +pci:v00009005d0000028Bsv00009005sd00000401* + ID_PRODUCT_FROM_DATABASE=Series 6 - ASR-61605 - 16 internal 6G SAS ports + +pci:v00009005d0000028Bsv00009005sd00000403* + ID_PRODUCT_FROM_DATABASE=Series 6 - ASR-62405 - 24 internal 6G SAS ports + +pci:v00009005d0000028C* + ID_PRODUCT_FROM_DATABASE=Series 7 6G SAS/PCIe 3 + +pci:v00009005d0000028Csv00009005sd00000500* + ID_PRODUCT_FROM_DATABASE=Series 7 - ASR-7805 - 8 internal 6G SAS Port/PCIe 3.0 + +pci:v00009005d0000028Csv00009005sd00000501* + ID_PRODUCT_FROM_DATABASE=Series 7 - ASR-71605 - 16 internal 6G SAS Port/PCIe 3.0 + +pci:v00009005d0000028Csv00009005sd00000502* + ID_PRODUCT_FROM_DATABASE=Series 7 - ASR-71685 - 16 internal 8 external 6G SAS Port/PCIe 3.0 + +pci:v00009005d0000028Csv00009005sd00000503* + ID_PRODUCT_FROM_DATABASE=Series 7 - ASR-72405 - 24 internal 0 external 6G SAS Port/PCIe 3.0 + +pci:v00009005d0000028Csv00009005sd00000504* + ID_PRODUCT_FROM_DATABASE=Series 7 - ASR-7885 - 8 internal 8 external 6G SAS Port/PCIe 3.0 + +pci:v00009005d0000028Csv00009005sd00000505* + ID_PRODUCT_FROM_DATABASE=Series 7 Entry Level - ASR-71685E - 16 internal 8 external 6G SAS Port/PCIe 3.0 + +pci:v00009005d0000028Csv00009005sd00000506* + ID_PRODUCT_FROM_DATABASE=Series 7 Entry Level - ASR-72405E - 24 internal 0 external 6G SAS Port/PCIe 3.0 + +pci:v00009005d0000028D* + ID_PRODUCT_FROM_DATABASE=Series 8 12G SAS/PCIe 3 + +pci:v00009005d0000028Dsv00009005sd00000550* + ID_PRODUCT_FROM_DATABASE=Series 8 - ASR-82405 - 24 internal 0 external 12G SAS Port/PCIe 3.0 + +pci:v00009005d0000028Dsv00009005sd00000551* + ID_PRODUCT_FROM_DATABASE=Series 8 - ASR-81605 - 16 internal 0 external 12G SAS Port/PCIe 3.0 + +pci:v00009005d0000028Dsv00009005sd00000552* + ID_PRODUCT_FROM_DATABASE=Series 8 - ASR-8805 - 8 internal 0 external 12G SAS Port/PCIe 3.0 + +pci:v00009005d0000028Dsv00009005sd00000553* + ID_PRODUCT_FROM_DATABASE=Series 8 - ASR-8085 - 0 internal 8 external 12G SAS Port/PCIe 3.0 + +pci:v00009005d0000028Dsv00009005sd00000554* + ID_PRODUCT_FROM_DATABASE=Series 8 - ASR-8885 - 8 internal 8 external 12G SAS Port/PCIe 3.0 + +pci:v00009005d00000410* + ID_PRODUCT_FROM_DATABASE=AIC-9410W SAS (Razor HBA RAID) + +pci:v00009005d00000410sv00009005sd00000410* + ID_PRODUCT_FROM_DATABASE=ASC-48300(Spirit RAID) + +pci:v00009005d00000410sv00009005sd00000411* + ID_PRODUCT_FROM_DATABASE=ASC-58300 (Oakmont RAID) + +pci:v00009005d00000412* + ID_PRODUCT_FROM_DATABASE=AIC-9410W SAS (Razor HBA non-RAID) + +pci:v00009005d00000412sv00009005sd00000412* + ID_PRODUCT_FROM_DATABASE=ASC-48300 (Spirit non-RAID) + +pci:v00009005d00000412sv00009005sd00000413* + ID_PRODUCT_FROM_DATABASE=ASC-58300 (Oakmont non-RAID) + +pci:v00009005d00000415* + ID_PRODUCT_FROM_DATABASE=ASC-58300 SAS (Razor-External HBA RAID) + +pci:v00009005d00000416* + ID_PRODUCT_FROM_DATABASE=ASC-58300 SAS (Razor-External HBA non-RAID) + +pci:v00009005d0000041E* + ID_PRODUCT_FROM_DATABASE=AIC-9410W SAS (Razor ASIC non-RAID) + +pci:v00009005d0000041F* + ID_PRODUCT_FROM_DATABASE=AIC-9410W SAS (Razor ASIC RAID) + +pci:v00009005d0000041Fsv00009005sd0000041F* + ID_PRODUCT_FROM_DATABASE=AIC-9410W SAS (Razor ASIC RAID) + +pci:v00009005d0000042F* + ID_PRODUCT_FROM_DATABASE=VSC7250/7251 SAS (Aurora ASIC non-RAID) + +pci:v00009005d00000430* + ID_PRODUCT_FROM_DATABASE=AIC-9405W SAS (Razor-Lite HBA RAID) + +pci:v00009005d00000430sv00009005sd00000430* + ID_PRODUCT_FROM_DATABASE=ASC-44300 (Spirit-Lite RAID) + +pci:v00009005d00000432* + ID_PRODUCT_FROM_DATABASE=AIC-9405W SAS (Razor-Lite HBA non-RAID) + +pci:v00009005d00000432sv00009005sd00000432* + ID_PRODUCT_FROM_DATABASE=ASC-44300 (Spirit-Lite non-RAID) + +pci:v00009005d0000043E* + ID_PRODUCT_FROM_DATABASE=AIC-9405W SAS (Razor-Lite ASIC non-RAID) + +pci:v00009005d0000043F* + ID_PRODUCT_FROM_DATABASE=AIC-9405W SAS (Razor-Lite ASIC RAID) + +pci:v00009005d00000450* + ID_PRODUCT_FROM_DATABASE=ASC-1405 Unified Serial HBA + +pci:v00009005d00000500* + ID_PRODUCT_FROM_DATABASE=Obsidian chipset SCSI controller + +pci:v00009005d00000500sv00001014sd000002C1* + ID_PRODUCT_FROM_DATABASE=PCI-X DDR 3Gb SAS Adapter (572A/572C) + +pci:v00009005d00000500sv00001014sd000002C2* + ID_PRODUCT_FROM_DATABASE=PCI-X DDR 3Gb SAS RAID Adapter (572B/572D) + +pci:v00009005d00000503* + ID_PRODUCT_FROM_DATABASE=Scamp chipset SCSI controller + +pci:v00009005d00000503sv00001014sd000002BF* + ID_PRODUCT_FROM_DATABASE=Quad Channel PCI-X DDR U320 SCSI RAID Adapter (571E) + +pci:v00009005d00000503sv00001014sd000002C3* + ID_PRODUCT_FROM_DATABASE=PCI-X DDR 3Gb SAS RAID Adapter (572F) + +pci:v00009005d00000503sv00001014sd000002D5* + ID_PRODUCT_FROM_DATABASE=Quad Channel PCI-X DDR U320 SCSI RAID Adapter (571F) + +pci:v00009005d00000910* + ID_PRODUCT_FROM_DATABASE=AUA-3100B + +pci:v00009005d0000091E* + ID_PRODUCT_FROM_DATABASE=AUA-3100B + +pci:v00009005d00008000* + ID_PRODUCT_FROM_DATABASE=ASC-29320A U320 + +pci:v00009005d0000800F* + ID_PRODUCT_FROM_DATABASE=AIC-7901 U320 + +pci:v00009005d00008010* + ID_PRODUCT_FROM_DATABASE=ASC-39320 U320 + +pci:v00009005d00008011* + ID_PRODUCT_FROM_DATABASE=ASC-39320D + +pci:v00009005d00008011sv00000E11sd000000AC* + ID_PRODUCT_FROM_DATABASE=ASC-39320D U320 + +pci:v00009005d00008011sv00009005sd00000041* + ID_PRODUCT_FROM_DATABASE=ASC-39320D U320 + +pci:v00009005d00008012* + ID_PRODUCT_FROM_DATABASE=ASC-29320 U320 + +pci:v00009005d00008013* + ID_PRODUCT_FROM_DATABASE=ASC-29320B U320 + +pci:v00009005d00008014* + ID_PRODUCT_FROM_DATABASE=ASC-29320LP U320 + +pci:v00009005d00008015* + ID_PRODUCT_FROM_DATABASE=ASC-39320B U320 + +pci:v00009005d00008016* + ID_PRODUCT_FROM_DATABASE=ASC-39320A U320 + +pci:v00009005d00008017* + ID_PRODUCT_FROM_DATABASE=ASC-29320ALP U320 + +pci:v00009005d00008017sv00009005sd00000044* + ID_PRODUCT_FROM_DATABASE=ASC-29320ALP PCIx U320 + +pci:v00009005d00008017sv00009005sd00000045* + ID_PRODUCT_FROM_DATABASE=ASC-29320LPE PCIe U320 + +pci:v00009005d0000801C* + ID_PRODUCT_FROM_DATABASE=ASC-39320D U320 + +pci:v00009005d0000801D* + ID_PRODUCT_FROM_DATABASE=AIC-7902B U320 + +pci:v00009005d0000801Dsv00001014sd000002CC* + ID_PRODUCT_FROM_DATABASE=ServeRAID 7e + +pci:v00009005d0000801E* + ID_PRODUCT_FROM_DATABASE=AIC-7901A U320 + +pci:v00009005d0000801F* + ID_PRODUCT_FROM_DATABASE=AIC-7902 U320 + +pci:v00009005d0000801Fsv00001734sd00001011* + ID_PRODUCT_FROM_DATABASE=PRIMERGY RX300 onboard SCSI + +pci:v00009005d00008080* + ID_PRODUCT_FROM_DATABASE=ASC-29320A U320 w/HostRAID + +pci:v00009005d0000808F* + ID_PRODUCT_FROM_DATABASE=AIC-7901 U320 w/HostRAID + +pci:v00009005d00008090* + ID_PRODUCT_FROM_DATABASE=ASC-39320 U320 w/HostRAID + +pci:v00009005d00008091* + ID_PRODUCT_FROM_DATABASE=ASC-39320D U320 w/HostRAID + +pci:v00009005d00008092* + ID_PRODUCT_FROM_DATABASE=ASC-29320 U320 w/HostRAID + +pci:v00009005d00008093* + ID_PRODUCT_FROM_DATABASE=ASC-29320B U320 w/HostRAID + +pci:v00009005d00008094* + ID_PRODUCT_FROM_DATABASE=ASC-29320LP U320 w/HostRAID + +pci:v00009005d00008095* + ID_PRODUCT_FROM_DATABASE=ASC-39320(B) U320 w/HostRAID + +pci:v00009005d00008096* + ID_PRODUCT_FROM_DATABASE=ASC-39320A U320 w/HostRAID + +pci:v00009005d00008097* + ID_PRODUCT_FROM_DATABASE=ASC-29320ALP U320 w/HostRAID + +pci:v00009005d0000809C* + ID_PRODUCT_FROM_DATABASE=ASC-39320D(B) U320 w/HostRAID + +pci:v00009005d0000809D* + ID_PRODUCT_FROM_DATABASE=AIC-7902(B) U320 w/HostRAID + +pci:v00009005d0000809Dsv00001014sd000002CC* + ID_PRODUCT_FROM_DATABASE=ServeRAID 7e + +pci:v00009005d0000809E* + ID_PRODUCT_FROM_DATABASE=AIC-7901A U320 w/HostRAID + +pci:v00009005d0000809F* + ID_PRODUCT_FROM_DATABASE=AIC-7902 U320 w/HostRAID + +pci:v0000907F* + ID_VENDOR_FROM_DATABASE=Atronics + +pci:v0000907Fd00002015* + ID_PRODUCT_FROM_DATABASE=IDE-2015PL + +pci:v0000919A* + ID_VENDOR_FROM_DATABASE=Gigapixel Corp + +pci:v00009412* + ID_VENDOR_FROM_DATABASE=Holtek + +pci:v00009412d00006565* + ID_PRODUCT_FROM_DATABASE=6565 + +pci:v00009618* + ID_VENDOR_FROM_DATABASE=JusonTech Corporation + +pci:v00009618d00000001* + ID_PRODUCT_FROM_DATABASE=JusonTech Gigabit Ethernet Controller + +pci:v00009699* + ID_VENDOR_FROM_DATABASE=Omni Media Technology Inc + +pci:v00009699d00006565* + ID_PRODUCT_FROM_DATABASE=6565 + +pci:v00009710* + ID_VENDOR_FROM_DATABASE=NetMos Technology + +pci:v00009710d00009250* + ID_PRODUCT_FROM_DATABASE=PCI-to-PCI bridge [MCS9250] + +pci:v00009710d00009805* + ID_PRODUCT_FROM_DATABASE=PCI 1 port parallel adapter + +pci:v00009710d00009815* + ID_PRODUCT_FROM_DATABASE=PCI 9815 Multi-I/O Controller + +pci:v00009710d00009815sv00001000sd00000020* + ID_PRODUCT_FROM_DATABASE=2P0S (2 port parallel adaptor) + +pci:v00009710d00009820* + ID_PRODUCT_FROM_DATABASE=PCI 9820 Multi-I/O Controller + +pci:v00009710d00009835* + ID_PRODUCT_FROM_DATABASE=PCI 9835 Multi-I/O Controller + +pci:v00009710d00009835sv00001000sd00000002* + ID_PRODUCT_FROM_DATABASE=2S (16C550 UART) + +pci:v00009710d00009835sv00001000sd00000012* + ID_PRODUCT_FROM_DATABASE=1P2S + +pci:v00009710d00009845* + ID_PRODUCT_FROM_DATABASE=PCI 9845 Multi-I/O Controller + +pci:v00009710d00009845sv00001000sd00000004* + ID_PRODUCT_FROM_DATABASE=0P4S (4 port 16550A serial card) + +pci:v00009710d00009845sv00001000sd00000006* + ID_PRODUCT_FROM_DATABASE=0P6S (6 port 16550a serial card) + +pci:v00009710d00009845sv00001000sd00000014* + ID_PRODUCT_FROM_DATABASE=1P4S (1 Parallel / 4 16550A Serial Port Adapter) + +pci:v00009710d00009855* + ID_PRODUCT_FROM_DATABASE=PCI 9855 Multi-I/O Controller + +pci:v00009710d00009855sv00001000sd00000014* + ID_PRODUCT_FROM_DATABASE=1P4S + +pci:v00009710d00009855sv00001000sd00000022* + ID_PRODUCT_FROM_DATABASE=2P2S (2 Parallel / 2 16550A Serial Port Adapter) + +pci:v00009710d00009865* + ID_PRODUCT_FROM_DATABASE=PCI 9865 Multi-I/O Controller + +pci:v00009710d00009901* + ID_PRODUCT_FROM_DATABASE=PCIe 9901 Multi-I/O Controller + +pci:v00009710d00009904* + ID_PRODUCT_FROM_DATABASE=4-Port PCIe Serial Adapter + +pci:v00009710d00009912* + ID_PRODUCT_FROM_DATABASE=PCIe 9912 Multi-I/O Controller + +pci:v00009710d00009922* + ID_PRODUCT_FROM_DATABASE=PCIe 9922 Multi-I/O Controller + +pci:v00009710d00009990* + ID_PRODUCT_FROM_DATABASE=MCS9990 PCIe to 4‐Port USB 2.0 Host Controller + +pci:v00009902* + ID_VENDOR_FROM_DATABASE=Stargen Inc. + +pci:v00009902d00000001* + ID_PRODUCT_FROM_DATABASE=SG2010 PCI over Starfabric Bridge + +pci:v00009902d00000002* + ID_PRODUCT_FROM_DATABASE=SG2010 PCI to Starfabric Gateway + +pci:v00009902d00000003* + ID_PRODUCT_FROM_DATABASE=SG1010 Starfabric Switch and PCI Bridge + +pci:v0000A0A0* + ID_VENDOR_FROM_DATABASE=AOPEN Inc. + +pci:v0000A0F1* + ID_VENDOR_FROM_DATABASE=UNISYS Corporation + +pci:v0000A200* + ID_VENDOR_FROM_DATABASE=NEC Corporation + +pci:v0000A259* + ID_VENDOR_FROM_DATABASE=Hewlett Packard + +pci:v0000A25B* + ID_VENDOR_FROM_DATABASE=Hewlett Packard GmbH PL24-MKT + +pci:v0000A304* + ID_VENDOR_FROM_DATABASE=Sony + +pci:v0000A727* + ID_VENDOR_FROM_DATABASE=3Com Corporation + +pci:v0000A727d00000013* + ID_PRODUCT_FROM_DATABASE=3CRPAG175 Wireless PC Card + +pci:v0000A727d00006803* + ID_PRODUCT_FROM_DATABASE=3CRDAG675B Wireless 11a/b/g Adapter + +pci:v0000AA42* + ID_VENDOR_FROM_DATABASE=Scitex Digital Video + +pci:v0000AA55* + ID_VENDOR_FROM_DATABASE=Ncomputing X300 PCI-Engine + +pci:v0000AAAA* + ID_VENDOR_FROM_DATABASE=Adnaco Technology Inc. + +pci:v0000AAAAd00000001* + ID_PRODUCT_FROM_DATABASE=H1 PCIe over fiber optic host controller + +pci:v0000AAAAd00000002* + ID_PRODUCT_FROM_DATABASE=R1BP1 PCIe over fiber optic expansion chassis + +pci:v0000ABCD* + ID_VENDOR_FROM_DATABASE=Vadatech Inc. + +pci:v0000AC1E* + ID_VENDOR_FROM_DATABASE=Digital Receiver Technology Inc + +pci:v0000AC3D* + ID_VENDOR_FROM_DATABASE=Actuality Systems + +pci:v0000AD00* + ID_VENDOR_FROM_DATABASE=Alta Data Technologies LLC + +pci:v0000AECB* + ID_VENDOR_FROM_DATABASE=Adrienne Electronics Corporation + +pci:v0000AECBd00006250* + ID_PRODUCT_FROM_DATABASE=VITC/LTC Timecode Reader card [PCI-VLTC/RDR] + +pci:v0000AFFE* + ID_VENDOR_FROM_DATABASE=Sirrix AG security technologies + +pci:v0000AFFEd000001E1* + ID_PRODUCT_FROM_DATABASE=PCI1E1 1-port ISDN E1 interface + +pci:v0000AFFEd000002E1* + ID_PRODUCT_FROM_DATABASE=PCI2E1 2-port ISDN E1 interface + +pci:v0000AFFEd0000450E* + ID_PRODUCT_FROM_DATABASE=PCI4S0EC 4-port ISDN S0 interface + +pci:v0000AFFEd0000DEAD* + ID_PRODUCT_FROM_DATABASE=Sirrix.PCI4S0 4-port ISDN S0 interface + +pci:v0000B100* + ID_VENDOR_FROM_DATABASE=OpenVox Communication Co. Ltd. + +pci:v0000B10B* + ID_VENDOR_FROM_DATABASE=Uakron PCI Project + +pci:v0000B1B3* + ID_VENDOR_FROM_DATABASE=Shiva Europe Limited + +pci:v0000B1D9* + ID_VENDOR_FROM_DATABASE=ATCOM Technology co., LTD. + +pci:v0000BD11* + ID_VENDOR_FROM_DATABASE=Pinnacle Systems, Inc. (Wrong ID) + +pci:v0000BDBD* + ID_VENDOR_FROM_DATABASE=Blackmagic Design + +pci:v0000BDBDd0000A11B* + ID_PRODUCT_FROM_DATABASE=DeckLink SDI + +pci:v0000C001* + ID_VENDOR_FROM_DATABASE=TSI Telsys + +pci:v0000C0A9* + ID_VENDOR_FROM_DATABASE=Micron/Crucial Technology + +pci:v0000C0DE* + ID_VENDOR_FROM_DATABASE=Motorola + +pci:v0000C0FE* + ID_VENDOR_FROM_DATABASE=Motion Engineering, Inc. + +pci:v0000CA50* + ID_VENDOR_FROM_DATABASE=Varian Australia Pty Ltd + +pci:v0000CACE* + ID_VENDOR_FROM_DATABASE=CACE Technologies, Inc. + +pci:v0000CACEd00000001* + ID_PRODUCT_FROM_DATABASE=TurboCap Port A + +pci:v0000CACEd00000002* + ID_PRODUCT_FROM_DATABASE=TurboCap Port B + +pci:v0000CACEd00000023* + ID_PRODUCT_FROM_DATABASE=AirPcap N + +pci:v0000CAFE* + ID_VENDOR_FROM_DATABASE=Chrysalis-ITS + +pci:v0000CAFEd00000003* + ID_PRODUCT_FROM_DATABASE=Luna K3 Hardware Security Module + +pci:v0000CAFEd00000006* + ID_PRODUCT_FROM_DATABASE=Luna PCI-e 3000 Hardware Security Module + +pci:v0000CCCC* + ID_VENDOR_FROM_DATABASE=Catapult Communications + +pci:v0000CCEC* + ID_VENDOR_FROM_DATABASE=Curtiss-Wright Controls Embedded Computing + +pci:v0000CDDD* + ID_VENDOR_FROM_DATABASE=Tyzx, Inc. + +pci:v0000CDDDd00000101* + ID_PRODUCT_FROM_DATABASE=DeepSea 1 High Speed Stereo Vision Frame Grabber + +pci:v0000CDDDd00000200* + ID_PRODUCT_FROM_DATABASE=DeepSea 2 High Speed Stereo Vision Frame Grabber + +pci:v0000CEBA* + ID_VENDOR_FROM_DATABASE=KEBA AG + +pci:v0000D161* + ID_VENDOR_FROM_DATABASE=Digium, Inc. + +pci:v0000D161d00000120* + ID_PRODUCT_FROM_DATABASE=Wildcard TE120P single-span T1/E1/J1 card + +pci:v0000D161d00000205* + ID_PRODUCT_FROM_DATABASE=Wildcard TE205P/TE207P dual-span T1/E1/J1 card 5.0V + +pci:v0000D161d00000210* + ID_PRODUCT_FROM_DATABASE=Wildcard TE210P/TE212P dual-span T1/E1/J1 card 3.3V + +pci:v0000D161d00000220* + ID_PRODUCT_FROM_DATABASE=Wildcard TE220 dual-span T1/E1/J1 card 3.3V (PCI-Express) + +pci:v0000D161d00000405* + ID_PRODUCT_FROM_DATABASE=Wildcard TE405P/TE407P quad-span T1/E1/J1 card 5.0V + +pci:v0000D161d00000410* + ID_PRODUCT_FROM_DATABASE=Wildcard TE410P/TE412P quad-span T1/E1/J1 card 3.3V + +pci:v0000D161d00000420* + ID_PRODUCT_FROM_DATABASE=Wildcard TE420P quad-span T1/E1/J1 card 3.3V (PCI-Express) + +pci:v0000D161d00000800* + ID_PRODUCT_FROM_DATABASE=Wildcard TDM800P 8-port analog card + +pci:v0000D161d00001205* + ID_PRODUCT_FROM_DATABASE=Wildcard TE205P/TE207P dual-span T1/E1/J1 card 5.0V (u1) + +pci:v0000D161d00001220* + ID_PRODUCT_FROM_DATABASE=Wildcard TE220 dual-span T1/E1/J1 card 3.3V (PCI-Express) (5th gen) + +pci:v0000D161d00001405* + ID_PRODUCT_FROM_DATABASE=Wildcard TE405P/TE407P quad-span T1/E1/J1 card 5.0V (u1) + +pci:v0000D161d00001420* + ID_PRODUCT_FROM_DATABASE=Wildcard TE420 quad-span T1/E1/J1 card 3.3V (PCI-Express) (5th gen) + +pci:v0000D161d00002400* + ID_PRODUCT_FROM_DATABASE=Wildcard TDM2400P 24-port analog card + +pci:v0000D161d00003400* + ID_PRODUCT_FROM_DATABASE=Wildcard TC400P transcoder base card + +pci:v0000D161d00008000* + ID_PRODUCT_FROM_DATABASE=Wildcard TE121 single-span T1/E1/J1 card (PCI-Express) + +pci:v0000D161d00008001* + ID_PRODUCT_FROM_DATABASE=Wildcard TE122 single-span T1/E1/J1 card + +pci:v0000D161d00008002* + ID_PRODUCT_FROM_DATABASE=Wildcard AEX800 8-port analog card (PCI-Express) + +pci:v0000D161d00008003* + ID_PRODUCT_FROM_DATABASE=Wildcard AEX2400 24-port analog card (PCI-Express) + +pci:v0000D161d00008004* + ID_PRODUCT_FROM_DATABASE=Wildcard TCE400P transcoder base card + +pci:v0000D161d00008005* + ID_PRODUCT_FROM_DATABASE=Wildcard TDM410 4-port analog card + +pci:v0000D161d00008006* + ID_PRODUCT_FROM_DATABASE=Wildcard AEX410 4-port analog card (PCI-Express) + +pci:v0000D161d00008007* + ID_PRODUCT_FROM_DATABASE=Hx8 Series 8-port Base Card + +pci:v0000D161d00008008* + ID_PRODUCT_FROM_DATABASE=Hx8 Series 8-port Base Card (PCI-Express) + +pci:v0000D161d0000B410* + ID_PRODUCT_FROM_DATABASE=Wildcard B410 quad-BRI card + +pci:v0000D4D4* + ID_VENDOR_FROM_DATABASE=Dy4 Systems Inc + +pci:v0000D4D4d00000601* + ID_PRODUCT_FROM_DATABASE=PCI Mezzanine Card + +pci:v0000D531* + ID_VENDOR_FROM_DATABASE=I+ME ACTIA GmbH + +pci:v0000D84D* + ID_VENDOR_FROM_DATABASE=Exsys + +pci:v0000DADA* + ID_VENDOR_FROM_DATABASE=Datapath Limited + +pci:v0000DB10* + ID_VENDOR_FROM_DATABASE=Diablo Technologies + +pci:v0000DCBA* + ID_VENDOR_FROM_DATABASE=Dynamic Engineering + +pci:v0000DCBAd00000046* + ID_PRODUCT_FROM_DATABASE=PCIeAlteraCycloneIV + +pci:v0000DCBAd00000047* + ID_PRODUCT_FROM_DATABASE=VPX-RCB + +pci:v0000DCBAd00000048* + ID_PRODUCT_FROM_DATABASE=PMC-Biserial-III-BAE9 + +pci:v0000DD01* + ID_VENDOR_FROM_DATABASE=Digital Devices GmbH + +pci:v0000DD01d00000003* + ID_PRODUCT_FROM_DATABASE=Octopus LE DVB adapter + +pci:v0000DEAD* + ID_VENDOR_FROM_DATABASE=Indigita Corporation + +pci:v0000DEAF* + ID_VENDOR_FROM_DATABASE=Middle Digital Inc. + +pci:v0000DEAFd00009050* + ID_PRODUCT_FROM_DATABASE=PC Weasel Virtual VGA + +pci:v0000DEAFd00009051* + ID_PRODUCT_FROM_DATABASE=PC Weasel Serial Port + +pci:v0000DEAFd00009052* + ID_PRODUCT_FROM_DATABASE=PC Weasel Watchdog Timer + +pci:v0000DEDA* + ID_VENDOR_FROM_DATABASE=SoftHard Technology Ltd. + +pci:v0000E000* + ID_VENDOR_FROM_DATABASE=Winbond + +pci:v0000E000d0000E000* + ID_PRODUCT_FROM_DATABASE=W89C940 + +pci:v0000E159* + ID_VENDOR_FROM_DATABASE=Tiger Jet Network Inc. + +pci:v0000E159d00000001* + ID_PRODUCT_FROM_DATABASE=Tiger3XX Modem/ISDN interface + +pci:v0000E159d00000001sv00000059sd00000001* + ID_PRODUCT_FROM_DATABASE=128k ISDN-S/T Adapter + +pci:v0000E159d00000001sv00000059sd00000003* + ID_PRODUCT_FROM_DATABASE=128k ISDN-U Adapter + +pci:v0000E159d00000001sv000000A7sd00000001* + ID_PRODUCT_FROM_DATABASE=TELES.S0/PCI 2.x ISDN Adapter + +pci:v0000E159d00000001sv00008086sd00000003* + ID_PRODUCT_FROM_DATABASE=Digium X100P/X101P analogue PSTN FXO interface + +pci:v0000E159d00000001sv0000B100sd00000003* + ID_PRODUCT_FROM_DATABASE=OpenVox A400P 4-port analog card + +pci:v0000E159d00000001sv0000B1D9sd00000003* + ID_PRODUCT_FROM_DATABASE=AX400P 4-port analog card + +pci:v0000E159d00000002* + ID_PRODUCT_FROM_DATABASE=Tiger100APC ISDN chipset + +pci:v0000E1C5* + ID_VENDOR_FROM_DATABASE=Elcus + +pci:v0000E4BF* + ID_VENDOR_FROM_DATABASE=EKF Elektronik GmbH + +pci:v0000E4BFd00000CCD* + ID_PRODUCT_FROM_DATABASE=CCD-CALYPSO + +pci:v0000E4BFd00000CD1* + ID_PRODUCT_FROM_DATABASE=CD1-OPERA + +pci:v0000E4BFd00000CD2* + ID_PRODUCT_FROM_DATABASE=CD2-BEBOP + +pci:v0000E4BFd00000CD3* + ID_PRODUCT_FROM_DATABASE=CD3-JIVE + +pci:v0000E4BFd000050C1* + ID_PRODUCT_FROM_DATABASE=PC1-GROOVE + +pci:v0000E4BFd000050C2* + ID_PRODUCT_FROM_DATABASE=PC2-LIMBO + +pci:v0000E4BFd000053C1* + ID_PRODUCT_FROM_DATABASE=SC1-ALLEGRO + +pci:v0000E4BFd0000CC47* + ID_PRODUCT_FROM_DATABASE=CCG-RUMBA + +pci:v0000E4BFd0000CC4D* + ID_PRODUCT_FROM_DATABASE=CCM-BOOGIE + +pci:v0000E55E* + ID_VENDOR_FROM_DATABASE=Essence Technology, Inc. + +pci:v0000EA01* + ID_VENDOR_FROM_DATABASE=Eagle Technology + +pci:v0000EA01d0000000A* + ID_PRODUCT_FROM_DATABASE=PCI-773 Temperature Card + +pci:v0000EA01d00000032* + ID_PRODUCT_FROM_DATABASE=PCI-730 & PC104P-30 Card + +pci:v0000EA01d0000003E* + ID_PRODUCT_FROM_DATABASE=PCI-762 Opto-Isolator Card + +pci:v0000EA01d00000041* + ID_PRODUCT_FROM_DATABASE=PCI-763 Reed Relay Card + +pci:v0000EA01d00000043* + ID_PRODUCT_FROM_DATABASE=PCI-769 Opto-Isolator Reed Relay Combo Card + +pci:v0000EA01d00000046* + ID_PRODUCT_FROM_DATABASE=PCI-766 Analog Output Card + +pci:v0000EA01d00000052* + ID_PRODUCT_FROM_DATABASE=PCI-703 Analog I/O Card + +pci:v0000EA01d00000800* + ID_PRODUCT_FROM_DATABASE=PCI-800 Digital I/O Card + +pci:v0000EA60* + ID_VENDOR_FROM_DATABASE=RME + +pci:v0000EA60d00009896* + ID_PRODUCT_FROM_DATABASE=Digi32 + +pci:v0000EA60d00009897* + ID_PRODUCT_FROM_DATABASE=Digi32 Pro + +pci:v0000EA60d00009898* + ID_PRODUCT_FROM_DATABASE=Digi32/8 + +pci:v0000EABB* + ID_VENDOR_FROM_DATABASE=Aashima Technology B.V. + +pci:v0000EACE* + ID_VENDOR_FROM_DATABASE=Endace Measurement Systems, Ltd + +pci:v0000EACEd00003100* + ID_PRODUCT_FROM_DATABASE=DAG 3.10 OC-3/OC-12 + +pci:v0000EACEd00003200* + ID_PRODUCT_FROM_DATABASE=DAG 3.2x OC-3/OC-12 + +pci:v0000EACEd0000320E* + ID_PRODUCT_FROM_DATABASE=DAG 3.2E Fast Ethernet + +pci:v0000EACEd0000340E* + ID_PRODUCT_FROM_DATABASE=DAG 3.4E Fast Ethernet + +pci:v0000EACEd0000341E* + ID_PRODUCT_FROM_DATABASE=DAG 3.41E Fast Ethernet + +pci:v0000EACEd00003500* + ID_PRODUCT_FROM_DATABASE=DAG 3.5 OC-3/OC-12 + +pci:v0000EACEd0000351C* + ID_PRODUCT_FROM_DATABASE=DAG 3.5ECM Fast Ethernet + +pci:v0000EACEd0000360D* + ID_PRODUCT_FROM_DATABASE=DAG 3.6D DS3 + +pci:v0000EACEd0000360E* + ID_PRODUCT_FROM_DATABASE=DAG 3.6E Fast Ethernet + +pci:v0000EACEd0000368E* + ID_PRODUCT_FROM_DATABASE=DAG 3.6E Gig Ethernet + +pci:v0000EACEd00003707* + ID_PRODUCT_FROM_DATABASE=DAG 3.7T T1/E1/J1 + +pci:v0000EACEd0000370D* + ID_PRODUCT_FROM_DATABASE=DAG 3.7D DS3/E3 + +pci:v0000EACEd0000378E* + ID_PRODUCT_FROM_DATABASE=DAG 3.7G Gig Ethernet + +pci:v0000EACEd00003800* + ID_PRODUCT_FROM_DATABASE=DAG 3.8S OC-3/OC-12 + +pci:v0000EACEd00004100* + ID_PRODUCT_FROM_DATABASE=DAG 4.10 OC-48 + +pci:v0000EACEd00004110* + ID_PRODUCT_FROM_DATABASE=DAG 4.11 OC-48 + +pci:v0000EACEd00004220* + ID_PRODUCT_FROM_DATABASE=DAG 4.2 OC-48 + +pci:v0000EACEd0000422E* + ID_PRODUCT_FROM_DATABASE=DAG 4.2GE Gig Ethernet + +pci:v0000EACEd00004230* + ID_PRODUCT_FROM_DATABASE=DAG 4.2S OC-48 + +pci:v0000EACEd0000423E* + ID_PRODUCT_FROM_DATABASE=DAG 4.2GE Gig Ethernet + +pci:v0000EACEd00004300* + ID_PRODUCT_FROM_DATABASE=DAG 4.3S OC-48 + +pci:v0000EACEd0000430E* + ID_PRODUCT_FROM_DATABASE=DAG 4.3GE Gig Ethernet + +pci:v0000EACEd0000452E* + ID_PRODUCT_FROM_DATABASE=DAG 4.5G2 Gig Ethernet + +pci:v0000EACEd0000454E* + ID_PRODUCT_FROM_DATABASE=DAG 4.5G4 Gig Ethernet + +pci:v0000EACEd000045B8* + ID_PRODUCT_FROM_DATABASE=DAG 4.5Z8 Gig Ethernet + +pci:v0000EACEd000045BE* + ID_PRODUCT_FROM_DATABASE=DAG 4.5Z2 Gig Ethernet + +pci:v0000EACEd0000520E* + ID_PRODUCT_FROM_DATABASE=DAG 5.2X 10G Ethernet + +pci:v0000EACEd0000521A* + ID_PRODUCT_FROM_DATABASE=DAG 5.2SXA 10G Ethernet/OC-192 + +pci:v0000EACEd00005400* + ID_PRODUCT_FROM_DATABASE=DAG 5.4S-12 OC-3/OC-12 + +pci:v0000EACEd00005401* + ID_PRODUCT_FROM_DATABASE=DAG 5.4SG-48 Gig Ethernet/OC-3/OC-12/OC-48 + +pci:v0000EACEd0000540A* + ID_PRODUCT_FROM_DATABASE=DAG 5.4GA Gig Ethernet + +pci:v0000EACEd0000541A* + ID_PRODUCT_FROM_DATABASE=DAG 5.4SA-12 OC-3/OC-12 + +pci:v0000EACEd0000542A* + ID_PRODUCT_FROM_DATABASE=DAG 5.4SGA-48 Gig Ethernet/OC-3/OC-12/OC-48 + +pci:v0000EACEd00006000* + ID_PRODUCT_FROM_DATABASE=DAG 6.0SE 10G Ethernet/OC-192 + +pci:v0000EACEd00006100* + ID_PRODUCT_FROM_DATABASE=DAG 6.1SE 10G Ethernet/OC-192 + +pci:v0000EACEd00006200* + ID_PRODUCT_FROM_DATABASE=DAG 6.2SE 10G Ethernet/OC-192 + +pci:v0000EACEd00007100* + ID_PRODUCT_FROM_DATABASE=DAG 7.1S OC-3/OC-12 + +pci:v0000EACEd00007400* + ID_PRODUCT_FROM_DATABASE=DAG 7.4S OC-3/OC-12 + +pci:v0000EACEd00007401* + ID_PRODUCT_FROM_DATABASE=DAG 7.4S48 OC-48 + +pci:v0000EACEd0000752E* + ID_PRODUCT_FROM_DATABASE=DAG 7.5G2 Gig Ethernet + +pci:v0000EACEd0000754E* + ID_PRODUCT_FROM_DATABASE=DAG 7.5G4 Gig Ethernet + +pci:v0000EACEd00008100* + ID_PRODUCT_FROM_DATABASE=DAG 8.1X 10G Ethernet + +pci:v0000EACEd00008101* + ID_PRODUCT_FROM_DATABASE=DAG 8.1SX 10G Ethernet/OC-192 + +pci:v0000EACEd00008102* + ID_PRODUCT_FROM_DATABASE=DAG 8.1X 10G Ethernet + +pci:v0000EACEd0000820E* + ID_PRODUCT_FROM_DATABASE=DAG 8.2X 10G Ethernet + +pci:v0000EACEd0000820F* + ID_PRODUCT_FROM_DATABASE=DAG 8.2X 10G Ethernet (2nd bus) + +pci:v0000EACEd00008400* + ID_PRODUCT_FROM_DATABASE=DAG 8.4I Infiniband x4 SDR + +pci:v0000EACEd00008500* + ID_PRODUCT_FROM_DATABASE=DAG 8.5I Infiniband x4 DDR + +pci:v0000EACEd0000920E* + ID_PRODUCT_FROM_DATABASE=DAG 9.2X2 10G Ethernet + +pci:v0000EC80* + ID_VENDOR_FROM_DATABASE=Belkin Corporation + +pci:v0000EC80d0000EC00* + ID_PRODUCT_FROM_DATABASE=F5D6000 + +pci:v0000ECC0* + ID_VENDOR_FROM_DATABASE=Echo Digital Audio Corporation + +pci:v0000EDD8* + ID_VENDOR_FROM_DATABASE=ARK Logic Inc + +pci:v0000EDD8d0000A091* + ID_PRODUCT_FROM_DATABASE=1000PV [Stingray] + +pci:v0000EDD8d0000A099* + ID_PRODUCT_FROM_DATABASE=2000PV [Stingray] + +pci:v0000EDD8d0000A0A1* + ID_PRODUCT_FROM_DATABASE=2000MT + +pci:v0000EDD8d0000A0A9* + ID_PRODUCT_FROM_DATABASE=2000MI + +pci:v0000F043* + ID_VENDOR_FROM_DATABASE=ASUSTeK Computer Inc. (Wrong ID) + +pci:v0000F05B* + ID_VENDOR_FROM_DATABASE=Foxconn International, Inc. (Wrong ID) + +pci:v0000F1D0* + ID_VENDOR_FROM_DATABASE=AJA Video + +pci:v0000F1D0d0000C0FE* + ID_PRODUCT_FROM_DATABASE=Xena HS/HD-R + +pci:v0000F1D0d0000C0FF* + ID_PRODUCT_FROM_DATABASE=Kona/Xena 2 + +pci:v0000F1D0d0000CAFE* + ID_PRODUCT_FROM_DATABASE=Kona SD + +pci:v0000F1D0d0000CFEE* + ID_PRODUCT_FROM_DATABASE=Xena LS/SD-22-DA/SD-DA + +pci:v0000F1D0d0000DCAF* + ID_PRODUCT_FROM_DATABASE=Kona HD + +pci:v0000F1D0d0000DFEE* + ID_PRODUCT_FROM_DATABASE=Xena HD-DA + +pci:v0000F1D0d0000EFAC* + ID_PRODUCT_FROM_DATABASE=Xena SD-MM/SD-22-MM + +pci:v0000F1D0d0000FACD* + ID_PRODUCT_FROM_DATABASE=Xena HD-MM + +pci:v0000F5F5* + ID_VENDOR_FROM_DATABASE=F5 Networks, Inc. + +pci:v0000F849* + ID_VENDOR_FROM_DATABASE=ASRock Incorporation (Wrong ID) + +pci:v0000FA57* + ID_VENDOR_FROM_DATABASE=Interagon AS + +pci:v0000FA57d00000001* + ID_PRODUCT_FROM_DATABASE=PMC [Pattern Matching Chip] + +pci:v0000FAB7* + ID_VENDOR_FROM_DATABASE=Fabric7 Systems, Inc. + +pci:v0000FEBD* + ID_VENDOR_FROM_DATABASE=Ultraview Corp. + +pci:v0000FEDA* + ID_VENDOR_FROM_DATABASE=Broadcom Inc + +pci:v0000FEDAd0000A0FA* + ID_PRODUCT_FROM_DATABASE=BCM4210 iLine10 HomePNA 2.0 + +pci:v0000FEDAd0000A10E* + ID_PRODUCT_FROM_DATABASE=BCM4230 iLine10 HomePNA 2.0 + +pci:v0000FEDE* + ID_VENDOR_FROM_DATABASE=Fedetec Inc. + +pci:v0000FEDEd00000003* + ID_PRODUCT_FROM_DATABASE=TABIC PCI v3 + +pci:v0000FFEE* + ID_VENDOR_FROM_DATABASE=FNK Tech + +pci:v0000FFFD* + ID_VENDOR_FROM_DATABASE=XenSource, Inc. + +pci:v0000FFFDd00000101* + ID_PRODUCT_FROM_DATABASE=PCI Event Channel Controller + +pci:v0000FFFE* + ID_VENDOR_FROM_DATABASE=VMWare Inc (temporary ID) + +pci:v0000FFFEd00000710* + ID_PRODUCT_FROM_DATABASE=Virtual SVGA + +pci:v0000FFFF* + ID_VENDOR_FROM_DATABASE=Illegal Vendor ID diff --git a/hwdb/20-usb-classes.hwdb b/hwdb/20-usb-classes.hwdb new file mode 100644 index 000000000..3294d8a81 --- /dev/null +++ b/hwdb/20-usb-classes.hwdb @@ -0,0 +1,339 @@ +# This file is part of systemd. +# +# Data imported from: http://www.linux-usb.org/usb.ids + +usb:v*p*d*dc01* + ID_USB_CLASS_FROM_DATABASE=Audio + +usb:v*p*d*dc01dsc01* + ID_USB_SUBCLASS_FROM_DATABASE=Control Device + +usb:v*p*d*dc01dsc02* + ID_USB_SUBCLASS_FROM_DATABASE=Streaming + +usb:v*p*d*dc01dsc03* + ID_USB_SUBCLASS_FROM_DATABASE=MIDI Streaming + +usb:v*p*d*dc02* + ID_USB_CLASS_FROM_DATABASE=Communications + +usb:v*p*d*dc02dsc01* + ID_USB_SUBCLASS_FROM_DATABASE=Direct Line + +usb:v*p*d*dc02dsc02* + ID_USB_SUBCLASS_FROM_DATABASE=Abstract (modem) + +usb:v*p*d*dc02dsc02dp01* + ID_USB_PROTOCOL_FROM_DATABASE=AT-commands (v.25ter) + +usb:v*p*d*dc02dsc02dp02* + ID_USB_PROTOCOL_FROM_DATABASE=AT-commands (PCCA101) + +usb:v*p*d*dc02dsc02dp03* + ID_USB_PROTOCOL_FROM_DATABASE=AT-commands (PCCA101 + wakeup) + +usb:v*p*d*dc02dsc02dp04* + ID_USB_PROTOCOL_FROM_DATABASE=AT-commands (GSM) + +usb:v*p*d*dc02dsc02dp05* + ID_USB_PROTOCOL_FROM_DATABASE=AT-commands (3G) + +usb:v*p*d*dc02dsc02dp06* + ID_USB_PROTOCOL_FROM_DATABASE=AT-commands (CDMA) + +usb:v*p*d*dc02dsc02dpFE* + ID_USB_PROTOCOL_FROM_DATABASE=Defined by command set descriptor + +usb:v*p*d*dc02dsc02dpFF* + ID_USB_PROTOCOL_FROM_DATABASE=Vendor Specific (MSFT RNDIS?) + +usb:v*p*d*dc02dsc03* + ID_USB_SUBCLASS_FROM_DATABASE=Telephone + +usb:v*p*d*dc02dsc04* + ID_USB_SUBCLASS_FROM_DATABASE=Multi-Channel + +usb:v*p*d*dc02dsc05* + ID_USB_SUBCLASS_FROM_DATABASE=CAPI Control + +usb:v*p*d*dc02dsc06* + ID_USB_SUBCLASS_FROM_DATABASE=Ethernet Networking + +usb:v*p*d*dc02dsc07* + ID_USB_SUBCLASS_FROM_DATABASE=ATM Networking + +usb:v*p*d*dc02dsc08* + ID_USB_SUBCLASS_FROM_DATABASE=Wireless Handset Control + +usb:v*p*d*dc02dsc09* + ID_USB_SUBCLASS_FROM_DATABASE=Device Management + +usb:v*p*d*dc02dsc0A* + ID_USB_SUBCLASS_FROM_DATABASE=Mobile Direct Line + +usb:v*p*d*dc02dsc0B* + ID_USB_SUBCLASS_FROM_DATABASE=OBEX + +usb:v*p*d*dc02dsc0C* + ID_USB_SUBCLASS_FROM_DATABASE=Ethernet Emulation + +usb:v*p*d*dc02dsc0Cdp07* + ID_USB_PROTOCOL_FROM_DATABASE=Ethernet Emulation (EEM) + +usb:v*p*d*dc03* + ID_USB_CLASS_FROM_DATABASE=Human Interface Device + +usb:v*p*d*dc03dsc00dp01* + ID_USB_PROTOCOL_FROM_DATABASE=Keyboard + +usb:v*p*d*dc03dsc00dp02* + ID_USB_PROTOCOL_FROM_DATABASE=Mouse + +usb:v*p*d*dc03dsc01* + ID_USB_SUBCLASS_FROM_DATABASE=Boot Interface Subclass + +usb:v*p*d*dc03dsc01dp01* + ID_USB_PROTOCOL_FROM_DATABASE=Keyboard + +usb:v*p*d*dc03dsc01dp02* + ID_USB_PROTOCOL_FROM_DATABASE=Mouse + +usb:v*p*d*dc05* + ID_USB_CLASS_FROM_DATABASE=Physical Interface Device + +usb:v*p*d*dc06* + ID_USB_CLASS_FROM_DATABASE=Imaging + +usb:v*p*d*dc06dsc01* + ID_USB_SUBCLASS_FROM_DATABASE=Still Image Capture + +usb:v*p*d*dc06dsc01dp01* + ID_USB_PROTOCOL_FROM_DATABASE=Picture Transfer Protocol (PIMA 15470) + +usb:v*p*d*dc07* + ID_USB_CLASS_FROM_DATABASE=Printer + +usb:v*p*d*dc07dsc01* + ID_USB_SUBCLASS_FROM_DATABASE=Printer + +usb:v*p*d*dc07dsc01dp00* + ID_USB_PROTOCOL_FROM_DATABASE=Reserved/Undefined + +usb:v*p*d*dc07dsc01dp01* + ID_USB_PROTOCOL_FROM_DATABASE=Unidirectional + +usb:v*p*d*dc07dsc01dp02* + ID_USB_PROTOCOL_FROM_DATABASE=Bidirectional + +usb:v*p*d*dc07dsc01dp03* + ID_USB_PROTOCOL_FROM_DATABASE=IEEE 1284.4 compatible bidirectional + +usb:v*p*d*dc07dsc01dpFF* + ID_USB_PROTOCOL_FROM_DATABASE=Vendor Specific + +usb:v*p*d*dc08* + ID_USB_CLASS_FROM_DATABASE=Mass Storage + +usb:v*p*d*dc08dsc01* + ID_USB_SUBCLASS_FROM_DATABASE=RBC (typically Flash) + +usb:v*p*d*dc08dsc01dp00* + ID_USB_PROTOCOL_FROM_DATABASE=Control/Bulk/Interrupt + +usb:v*p*d*dc08dsc01dp01* + ID_USB_PROTOCOL_FROM_DATABASE=Control/Bulk + +usb:v*p*d*dc08dsc01dp50* + ID_USB_PROTOCOL_FROM_DATABASE=Bulk-Only + +usb:v*p*d*dc08dsc02* + ID_USB_SUBCLASS_FROM_DATABASE=SFF-8020i, MMC-2 (ATAPI) + +usb:v*p*d*dc08dsc03* + ID_USB_SUBCLASS_FROM_DATABASE=QIC-157 + +usb:v*p*d*dc08dsc04* + ID_USB_SUBCLASS_FROM_DATABASE=Floppy (UFI) + +usb:v*p*d*dc08dsc04dp00* + ID_USB_PROTOCOL_FROM_DATABASE=Control/Bulk/Interrupt + +usb:v*p*d*dc08dsc04dp01* + ID_USB_PROTOCOL_FROM_DATABASE=Control/Bulk + +usb:v*p*d*dc08dsc04dp50* + ID_USB_PROTOCOL_FROM_DATABASE=Bulk-Only + +usb:v*p*d*dc08dsc05* + ID_USB_SUBCLASS_FROM_DATABASE=SFF-8070i + +usb:v*p*d*dc08dsc06* + ID_USB_SUBCLASS_FROM_DATABASE=SCSI + +usb:v*p*d*dc08dsc06dp00* + ID_USB_PROTOCOL_FROM_DATABASE=Control/Bulk/Interrupt + +usb:v*p*d*dc08dsc06dp01* + ID_USB_PROTOCOL_FROM_DATABASE=Control/Bulk + +usb:v*p*d*dc08dsc06dp50* + ID_USB_PROTOCOL_FROM_DATABASE=Bulk-Only + +usb:v*p*d*dc09* + ID_USB_CLASS_FROM_DATABASE=Hub + +usb:v*p*d*dc09dsc00dp00* + ID_USB_PROTOCOL_FROM_DATABASE=Full speed (or root) hub + +usb:v*p*d*dc09dsc00dp01* + ID_USB_PROTOCOL_FROM_DATABASE=Single TT + +usb:v*p*d*dc09dsc00dp02* + ID_USB_PROTOCOL_FROM_DATABASE=TT per port + +usb:v*p*d*dc0A* + ID_USB_CLASS_FROM_DATABASE=CDC Data + +usb:v*p*d*dc0Adsc00dp30* + ID_USB_PROTOCOL_FROM_DATABASE=I.430 ISDN BRI + +usb:v*p*d*dc0Adsc00dp31* + ID_USB_PROTOCOL_FROM_DATABASE=HDLC + +usb:v*p*d*dc0Adsc00dp32* + ID_USB_PROTOCOL_FROM_DATABASE=Transparent + +usb:v*p*d*dc0Adsc00dp50* + ID_USB_PROTOCOL_FROM_DATABASE=Q.921M + +usb:v*p*d*dc0Adsc00dp51* + ID_USB_PROTOCOL_FROM_DATABASE=Q.921 + +usb:v*p*d*dc0Adsc00dp52* + ID_USB_PROTOCOL_FROM_DATABASE=Q.921TM + +usb:v*p*d*dc0Adsc00dp90* + ID_USB_PROTOCOL_FROM_DATABASE=V.42bis + +usb:v*p*d*dc0Adsc00dp91* + ID_USB_PROTOCOL_FROM_DATABASE=Q.932 EuroISDN + +usb:v*p*d*dc0Adsc00dp92* + ID_USB_PROTOCOL_FROM_DATABASE=V.120 V.24 rate ISDN + +usb:v*p*d*dc0Adsc00dp93* + ID_USB_PROTOCOL_FROM_DATABASE=CAPI 2.0 + +usb:v*p*d*dc0Adsc00dpFD* + ID_USB_PROTOCOL_FROM_DATABASE=Host Based Driver + +usb:v*p*d*dc0Adsc00dpFE* + ID_USB_PROTOCOL_FROM_DATABASE=CDC PUF + +usb:v*p*d*dc0Adsc00dpFF* + ID_USB_PROTOCOL_FROM_DATABASE=Vendor specific + +usb:v*p*d*dc0B* + ID_USB_CLASS_FROM_DATABASE=Chip/SmartCard + +usb:v*p*d*dc0D* + ID_USB_CLASS_FROM_DATABASE=Content Security + +usb:v*p*d*dc0E* + ID_USB_CLASS_FROM_DATABASE=Video + +usb:v*p*d*dc0Edsc01* + ID_USB_SUBCLASS_FROM_DATABASE=Video Control + +usb:v*p*d*dc0Edsc02* + ID_USB_SUBCLASS_FROM_DATABASE=Video Streaming + +usb:v*p*d*dc0Edsc03* + ID_USB_SUBCLASS_FROM_DATABASE=Video Interface Collection + +usb:v*p*d*dc58* + ID_USB_CLASS_FROM_DATABASE=Xbox + +usb:v*p*d*dc58dsc42* + ID_USB_SUBCLASS_FROM_DATABASE=Controller + +usb:v*p*d*dcDC* + ID_USB_CLASS_FROM_DATABASE=Diagnostic + +usb:v*p*d*dcDCdsc01* + ID_USB_SUBCLASS_FROM_DATABASE=Reprogrammable Diagnostics + +usb:v*p*d*dcDCdsc01dp01* + ID_USB_PROTOCOL_FROM_DATABASE=USB2 Compliance + +usb:v*p*d*dcE0* + ID_USB_CLASS_FROM_DATABASE=Wireless + +usb:v*p*d*dcE0dsc01* + ID_USB_SUBCLASS_FROM_DATABASE=Radio Frequency + +usb:v*p*d*dcE0dsc01dp01* + ID_USB_PROTOCOL_FROM_DATABASE=Bluetooth + +usb:v*p*d*dcE0dsc01dp02* + ID_USB_PROTOCOL_FROM_DATABASE=Ultra WideBand Radio Control + +usb:v*p*d*dcE0dsc01dp03* + ID_USB_PROTOCOL_FROM_DATABASE=RNDIS + +usb:v*p*d*dcE0dsc02* + ID_USB_SUBCLASS_FROM_DATABASE=Wireless USB Wire Adapter + +usb:v*p*d*dcE0dsc02dp01* + ID_USB_PROTOCOL_FROM_DATABASE=Host Wire Adapter Control/Data Streaming + +usb:v*p*d*dcE0dsc02dp02* + ID_USB_PROTOCOL_FROM_DATABASE=Device Wire Adapter Control/Data Streaming + +usb:v*p*d*dcE0dsc02dp03* + ID_USB_PROTOCOL_FROM_DATABASE=Device Wire Adapter Isochronous Streaming + +usb:v*p*d*dcEF* + ID_USB_CLASS_FROM_DATABASE=Miscellaneous Device + +usb:v*p*d*dcEFdsc01dp01* + ID_USB_PROTOCOL_FROM_DATABASE=Microsoft ActiveSync + +usb:v*p*d*dcEFdsc01dp02* + ID_USB_PROTOCOL_FROM_DATABASE=Palm Sync + +usb:v*p*d*dcEFdsc02dp01* + ID_USB_PROTOCOL_FROM_DATABASE=Interface Association + +usb:v*p*d*dcEFdsc02dp02* + ID_USB_PROTOCOL_FROM_DATABASE=Wire Adapter Multifunction Peripheral + +usb:v*p*d*dcEFdsc03dp01* + ID_USB_PROTOCOL_FROM_DATABASE=Cable Based Association + +usb:v*p*d*dcFE* + ID_USB_CLASS_FROM_DATABASE=Application Specific Interface + +usb:v*p*d*dcFEdsc01* + ID_USB_SUBCLASS_FROM_DATABASE=Device Firmware Update + +usb:v*p*d*dcFEdsc02* + ID_USB_SUBCLASS_FROM_DATABASE=IRDA Bridge + +usb:v*p*d*dcFEdsc03* + ID_USB_SUBCLASS_FROM_DATABASE=Test and Measurement + +usb:v*p*d*dcFEdsc03dp01* + ID_USB_PROTOCOL_FROM_DATABASE=TMC + +usb:v*p*d*dcFEdsc03dp02* + ID_USB_PROTOCOL_FROM_DATABASE=USB488 + +usb:v*p*d*dcFF* + ID_USB_CLASS_FROM_DATABASE=Vendor Specific Class + +usb:v*p*d*dcFFdscFF* + ID_USB_SUBCLASS_FROM_DATABASE=Vendor Specific Subclass + +usb:v*p*d*dcFFdscFFdpFF* + ID_USB_PROTOCOL_FROM_DATABASE=Vendor Specific Protocol diff --git a/hwdb/20-usb-vendor-product.hwdb b/hwdb/20-usb-vendor-product.hwdb new file mode 100644 index 000000000..a9b5a7e5a --- /dev/null +++ b/hwdb/20-usb-vendor-product.hwdb @@ -0,0 +1,48138 @@ +# This file is part of systemd. +# +# Data imported from: http://www.linux-usb.org/usb.ids + +usb:v0001* + ID_VENDOR_FROM_DATABASE=Fry's Electronics + +usb:v0001p142B* + ID_PRODUCT_FROM_DATABASE=Arbiter Systems, Inc. + +usb:v0001p7778* + ID_PRODUCT_FROM_DATABASE=Counterfeit flash drive [Kingston] + +usb:v0002* + ID_VENDOR_FROM_DATABASE=Ingram + +usb:v0003* + ID_VENDOR_FROM_DATABASE=Club Mac + +usb:v0004* + ID_VENDOR_FROM_DATABASE=Nebraska Furniture Mart + +usb:v0053* + ID_VENDOR_FROM_DATABASE=Planex + +usb:v0053p5301* + ID_PRODUCT_FROM_DATABASE=GW-US54ZGL 802.11bg + +usb:v0079* + ID_VENDOR_FROM_DATABASE=DragonRise Inc. + +usb:v0079p0006* + ID_PRODUCT_FROM_DATABASE=Generic USB Joystick + +usb:v0079p0011* + ID_PRODUCT_FROM_DATABASE=Gamepad + +usb:v0105* + ID_VENDOR_FROM_DATABASE=Trust International B.V. + +usb:v0105p145F* + ID_PRODUCT_FROM_DATABASE=NW-3100 802.11b/g 54Mbps Wireless Network Adapter [zd1211] + +usb:v0145* + ID_VENDOR_FROM_DATABASE=Unknown + +usb:v0145p0112* + ID_PRODUCT_FROM_DATABASE=Card Reader + +usb:v0204* + ID_VENDOR_FROM_DATABASE=Chipsbank Microelectronics Co., Ltd + +usb:v0204p6025* + ID_PRODUCT_FROM_DATABASE=CBM2080 Flash drive controller + +usb:v0204p6026* + ID_PRODUCT_FROM_DATABASE=CBM1180 Flash drive controller + +usb:v0218* + ID_VENDOR_FROM_DATABASE=Hangzhou Worlde + +usb:v0218p0301* + ID_PRODUCT_FROM_DATABASE=MIDI Port + +usb:v02AD* + ID_VENDOR_FROM_DATABASE=HUMAX Co., Ltd. + +usb:v02ADp138C* + ID_PRODUCT_FROM_DATABASE=PVR Mass Storage + +usb:v0300* + ID_VENDOR_FROM_DATABASE=MM300 eBook Reader + +usb:v0324* + ID_VENDOR_FROM_DATABASE=OCZ Technology Inc + +usb:v0324pBC06* + ID_PRODUCT_FROM_DATABASE=OCZ ATV USB 2.0 Flash Drive + +usb:v0324pBC08* + ID_PRODUCT_FROM_DATABASE=OCZ Rally2/ATV USB 2.0 Flash Drive + +usb:v0325* + ID_VENDOR_FROM_DATABASE=OCZ Technology Inc + +usb:v0325pAC02* + ID_PRODUCT_FROM_DATABASE=ATV Turbo / Rally2 Dual Channel USB 2.0 Flash Drive + +usb:v0386* + ID_VENDOR_FROM_DATABASE=LTS + +usb:v0386p0001* + ID_PRODUCT_FROM_DATABASE=PSX for USB Converter + +usb:v03DA* + ID_VENDOR_FROM_DATABASE=Bernd Walter Computer Technology + +usb:v03DAp0002* + ID_PRODUCT_FROM_DATABASE=HD44780 LCD interface + +usb:v03E8* + ID_VENDOR_FROM_DATABASE=EndPoints, Inc. + +usb:v03E8p0004* + ID_PRODUCT_FROM_DATABASE=SE401 Webcam + +usb:v03E8p0008* + ID_PRODUCT_FROM_DATABASE=101 Ethernet [klsi] + +usb:v03E8p0015* + ID_PRODUCT_FROM_DATABASE=ATAPI Enclosure + +usb:v03E8p2123* + ID_PRODUCT_FROM_DATABASE=SiPix StyleCam Deluxe + +usb:v03E8p8004* + ID_PRODUCT_FROM_DATABASE=Aox 99001 + +usb:v03E9* + ID_VENDOR_FROM_DATABASE=Thesys Microelectronics + +usb:v03EA* + ID_VENDOR_FROM_DATABASE=Data Broadcasting Corp. + +usb:v03EB* + ID_VENDOR_FROM_DATABASE=Atmel Corp. + +usb:v03EBp0902* + ID_PRODUCT_FROM_DATABASE=4-Port Hub + +usb:v03EBp2002* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v03EBp2015* + ID_PRODUCT_FROM_DATABASE=at90usbkey sample firmware (HID keyboard) + +usb:v03EBp2018* + ID_PRODUCT_FROM_DATABASE=at90usbkey sample firmware (CDC ACM) + +usb:v03EBp2019* + ID_PRODUCT_FROM_DATABASE=stk525 sample firmware (microphone) + +usb:v03EBp201C* + ID_PRODUCT_FROM_DATABASE=at90usbkey sample firmware (HID mouse) + +usb:v03EBp201D* + ID_PRODUCT_FROM_DATABASE=at90usbkey sample firmware (HID generic) + +usb:v03EBp2022* + ID_PRODUCT_FROM_DATABASE=at90usbkey sample firmware (composite device) + +usb:v03EBp2040* + ID_PRODUCT_FROM_DATABASE=LUFA Test PID + +usb:v03EBp2041* + ID_PRODUCT_FROM_DATABASE=LUFA Mouse Demo Application + +usb:v03EBp2042* + ID_PRODUCT_FROM_DATABASE=LUFA Keyboard Demo Application + +usb:v03EBp2043* + ID_PRODUCT_FROM_DATABASE=LUFA Joystick Demo Application + +usb:v03EBp2044* + ID_PRODUCT_FROM_DATABASE=LUFA CDC Demo Application + +usb:v03EBp2045* + ID_PRODUCT_FROM_DATABASE=LUFA Mass Storage Demo Application + +usb:v03EBp2046* + ID_PRODUCT_FROM_DATABASE=LUFA Audio Output Demo Application + +usb:v03EBp2047* + ID_PRODUCT_FROM_DATABASE=LUFA Audio Input Demo Application + +usb:v03EBp2048* + ID_PRODUCT_FROM_DATABASE=LUFA MIDI Demo Application + +usb:v03EBp2049* + ID_PRODUCT_FROM_DATABASE=Stripe Snoop Magnetic Stripe Reader + +usb:v03EBp204A* + ID_PRODUCT_FROM_DATABASE=LUFA CDC Class Bootloader + +usb:v03EBp204B* + ID_PRODUCT_FROM_DATABASE=LUFA USB to Serial Adapter Project + +usb:v03EBp204C* + ID_PRODUCT_FROM_DATABASE=LUFA RNDIS Demo Application + +usb:v03EBp204D* + ID_PRODUCT_FROM_DATABASE=LUFA Combined Mouse and Keyboard Demo Application + +usb:v03EBp204E* + ID_PRODUCT_FROM_DATABASE=LUFA Dual CDC Demo Application + +usb:v03EBp204F* + ID_PRODUCT_FROM_DATABASE=LUFA Generic HID Demo Application + +usb:v03EBp2060* + ID_PRODUCT_FROM_DATABASE=Benito Programmer Project + +usb:v03EBp2061* + ID_PRODUCT_FROM_DATABASE=LUFA Combined Mass Storage and Keyboard Demo Application + +usb:v03EBp2062* + ID_PRODUCT_FROM_DATABASE=LUFA Combined CDC and Mouse Demo Application + +usb:v03EBp2063* + ID_PRODUCT_FROM_DATABASE=LUFA Datalogger Device + +usb:v03EBp2064* + ID_PRODUCT_FROM_DATABASE=Interfaceless Control-Only LUFA Devices + +usb:v03EBp2065* + ID_PRODUCT_FROM_DATABASE=LUFA Test and Measurement Demo Application + +usb:v03EBp2066* + ID_PRODUCT_FROM_DATABASE=LUFA Multiple Report HID Demo + +usb:v03EBp2068* + ID_PRODUCT_FROM_DATABASE=LUFA Virtual Serial/Mass Storage Demo + +usb:v03EBp2069* + ID_PRODUCT_FROM_DATABASE=LUFA Webserver Project + +usb:v03EBp2103* + ID_PRODUCT_FROM_DATABASE=JTAG ICE mkII + +usb:v03EBp2104* + ID_PRODUCT_FROM_DATABASE=AVR ISP mkII + +usb:v03EBp2105* + ID_PRODUCT_FROM_DATABASE=AVRONE! + +usb:v03EBp2106* + ID_PRODUCT_FROM_DATABASE=STK600 development board + +usb:v03EBp2107* + ID_PRODUCT_FROM_DATABASE=AVR Dragon + +usb:v03EBp2109* + ID_PRODUCT_FROM_DATABASE=STK541 ZigBee Development Board + +usb:v03EBp210D* + ID_PRODUCT_FROM_DATABASE=XPLAIN evaluation kit (CDC ACM) + +usb:v03EBp2122* + ID_PRODUCT_FROM_DATABASE=XMEGA-A1 Explained evaluation kit + +usb:v03EBp2310* + ID_PRODUCT_FROM_DATABASE=EVK11xx evaluation board + +usb:v03EBp2FE4* + ID_PRODUCT_FROM_DATABASE=ATxmega32A4U DFU bootloader + +usb:v03EBp2FFB* + ID_PRODUCT_FROM_DATABASE=at90usb AVR DFU bootloader + +usb:v03EBp2FFD* + ID_PRODUCT_FROM_DATABASE=at89c5130/c5131 DFU bootloader + +usb:v03EBp2FFF* + ID_PRODUCT_FROM_DATABASE=at89c5132/c51snd1c DFU bootloader + +usb:v03EBp3301* + ID_PRODUCT_FROM_DATABASE=at43301 4-Port Hub + +usb:v03EBp3312* + ID_PRODUCT_FROM_DATABASE=4-Port Hub + +usb:v03EBp4102* + ID_PRODUCT_FROM_DATABASE=AirVast W-Buddie WN210 + +usb:v03EBp5601* + ID_PRODUCT_FROM_DATABASE=at76c510 Prism-II 802.11b Access Point + +usb:v03EBp5603* + ID_PRODUCT_FROM_DATABASE=Cisco 7920 WiFi IP Phone + +usb:v03EBp6119* + ID_PRODUCT_FROM_DATABASE=AT91SAM CDC Demo Application + +usb:v03EBp6124* + ID_PRODUCT_FROM_DATABASE=at91sam SAMBA bootloader + +usb:v03EBp6127* + ID_PRODUCT_FROM_DATABASE=AT91SAM HID Keyboard Demo Application + +usb:v03EBp6129* + ID_PRODUCT_FROM_DATABASE=AT91SAM Mass Storage Demo Application + +usb:v03EBp6200* + ID_PRODUCT_FROM_DATABASE=AT91SAM HID Mouse Demo Application + +usb:v03EBp7603* + ID_PRODUCT_FROM_DATABASE=D-Link DWL-120 802.11b Wireless Adapter [Atmel at76c503a] + +usb:v03EBp7604* + ID_PRODUCT_FROM_DATABASE=at76c503a 802.11b Adapter + +usb:v03EBp7605* + ID_PRODUCT_FROM_DATABASE=at76c503a 802.11b Adapter + +usb:v03EBp7606* + ID_PRODUCT_FROM_DATABASE=at76c505 802.11b Adapter + +usb:v03EBp7611* + ID_PRODUCT_FROM_DATABASE=at76c510 rfmd2948 802.11b Access Point + +usb:v03EBp7613* + ID_PRODUCT_FROM_DATABASE=WL-1130 USB + +usb:v03EBp7614* + ID_PRODUCT_FROM_DATABASE=AT76c505a Wireless Adapter + +usb:v03EBp7615* + ID_PRODUCT_FROM_DATABASE=AT76C505AMX Wireless Adapter + +usb:v03EBp7617* + ID_PRODUCT_FROM_DATABASE=AT76C505AS Wireless Adapter + +usb:v03EBp7800* + ID_PRODUCT_FROM_DATABASE=Mini Album + +usb:v03EBpFF07* + ID_PRODUCT_FROM_DATABASE=Tux Droid fish dongle + +usb:v03EC* + ID_VENDOR_FROM_DATABASE=Iwatsu America, Inc. + +usb:v03ED* + ID_VENDOR_FROM_DATABASE=Mitel Corp. + +usb:v03EE* + ID_VENDOR_FROM_DATABASE=Mitsumi + +usb:v03EEp0000* + ID_PRODUCT_FROM_DATABASE=CD-R/RW Drive + +usb:v03EEp2501* + ID_PRODUCT_FROM_DATABASE=eHome Infrared Receiver + +usb:v03EEp2502* + ID_PRODUCT_FROM_DATABASE=eHome Infrared Receiver + +usb:v03EEp5609* + ID_PRODUCT_FROM_DATABASE=Japanese Keyboard + +usb:v03EEp641F* + ID_PRODUCT_FROM_DATABASE=WIF-0402C Bluetooth Adapter + +usb:v03EEp6438* + ID_PRODUCT_FROM_DATABASE=Bluetooth Device + +usb:v03EEp6440* + ID_PRODUCT_FROM_DATABASE=WML-C52APR Bluetooth Adapter + +usb:v03EEp6901* + ID_PRODUCT_FROM_DATABASE=SmartDisk FDD + +usb:v03EEp6902* + ID_PRODUCT_FROM_DATABASE=Floppy Disk Drive + +usb:v03EEp7500* + ID_PRODUCT_FROM_DATABASE=CD-R/RW + +usb:v03EEpFFFF* + ID_PRODUCT_FROM_DATABASE=Dongle with BlueCore in DFU mode + +usb:v03F0* + ID_VENDOR_FROM_DATABASE=Hewlett-Packard + +usb:v03F0p0004* + ID_PRODUCT_FROM_DATABASE=DeskJet 895c + +usb:v03F0p0011* + ID_PRODUCT_FROM_DATABASE=OfficeJet G55 + +usb:v03F0p0012* + ID_PRODUCT_FROM_DATABASE=DeskJet 1125C Printer Port + +usb:v03F0p0024* + ID_PRODUCT_FROM_DATABASE=KU-0316 Keyboard + +usb:v03F0p002A* + ID_PRODUCT_FROM_DATABASE=LaserJet P1102 + +usb:v03F0p0101* + ID_PRODUCT_FROM_DATABASE=ScanJet 4100c + +usb:v03F0p0102* + ID_PRODUCT_FROM_DATABASE=PhotoSmart S20 + +usb:v03F0p0104* + ID_PRODUCT_FROM_DATABASE=DeskJet 880c/970c + +usb:v03F0p0105* + ID_PRODUCT_FROM_DATABASE=ScanJet 4200c + +usb:v03F0p0107* + ID_PRODUCT_FROM_DATABASE=CD-Writer Plus + +usb:v03F0p010C* + ID_PRODUCT_FROM_DATABASE=Multimedia Keyboard Hub + +usb:v03F0p0111* + ID_PRODUCT_FROM_DATABASE=G55xi Printer/Scanner/Copier + +usb:v03F0p0117* + ID_PRODUCT_FROM_DATABASE=LaserJet 3200 + +usb:v03F0p011C* + ID_PRODUCT_FROM_DATABASE=hn210w 802.11b Adapter + +usb:v03F0p011D* + ID_PRODUCT_FROM_DATABASE=Bluetooth 1.2 Interface [Broadcom BCM2035] + +usb:v03F0p0121* + ID_PRODUCT_FROM_DATABASE=HP49g+ Calculator + +usb:v03F0p0122* + ID_PRODUCT_FROM_DATABASE=HID Internet Keyboard + +usb:v03F0p0201* + ID_PRODUCT_FROM_DATABASE=ScanJet 6200c + +usb:v03F0p0202* + ID_PRODUCT_FROM_DATABASE=PhotoSmart S20 + +usb:v03F0p0204* + ID_PRODUCT_FROM_DATABASE=DeskJet 815c + +usb:v03F0p0205* + ID_PRODUCT_FROM_DATABASE=ScanJet 3300c + +usb:v03F0p0207* + ID_PRODUCT_FROM_DATABASE=CD-Writer Plus 8200e + +usb:v03F0p020C* + ID_PRODUCT_FROM_DATABASE=Multimedia Keyboard + +usb:v03F0p0211* + ID_PRODUCT_FROM_DATABASE=OfficeJet G85 + +usb:v03F0p0212* + ID_PRODUCT_FROM_DATABASE=DeskJet 1220C + +usb:v03F0p0217* + ID_PRODUCT_FROM_DATABASE=LaserJet 2200 + +usb:v03F0p0218* + ID_PRODUCT_FROM_DATABASE=APOLLO P2500/2600 + +usb:v03F0p0304* + ID_PRODUCT_FROM_DATABASE=DeskJet 810c/812c + +usb:v03F0p0305* + ID_PRODUCT_FROM_DATABASE=ScanJet 4300c + +usb:v03F0p0307* + ID_PRODUCT_FROM_DATABASE=CD-Writer+ CD-4e + +usb:v03F0p0311* + ID_PRODUCT_FROM_DATABASE=OfficeJet G85xi + +usb:v03F0p0312* + ID_PRODUCT_FROM_DATABASE=Color Inkjet CP1700 + +usb:v03F0p0314* + ID_PRODUCT_FROM_DATABASE=designjet 30/130 series + +usb:v03F0p0317* + ID_PRODUCT_FROM_DATABASE=LaserJet 1200 + +usb:v03F0p0324* + ID_PRODUCT_FROM_DATABASE=SK-2885 keyboard + +usb:v03F0p0401* + ID_PRODUCT_FROM_DATABASE=ScanJet 5200c + +usb:v03F0p0404* + ID_PRODUCT_FROM_DATABASE=DeskJet 830c/832c + +usb:v03F0p0405* + ID_PRODUCT_FROM_DATABASE=ScanJet 3400cse + +usb:v03F0p0411* + ID_PRODUCT_FROM_DATABASE=OfficeJet G95 + +usb:v03F0p0412* + ID_PRODUCT_FROM_DATABASE=Printing Support + +usb:v03F0p0417* + ID_PRODUCT_FROM_DATABASE=LaserJet 1200 series + +usb:v03F0p0423* + ID_PRODUCT_FROM_DATABASE=HS-COMBO Cardreader + +usb:v03F0p0504* + ID_PRODUCT_FROM_DATABASE=DeskJet 885c + +usb:v03F0p0505* + ID_PRODUCT_FROM_DATABASE=ScanJet 2100c + +usb:v03F0p0507* + ID_PRODUCT_FROM_DATABASE=DVD+RW + +usb:v03F0p050C* + ID_PRODUCT_FROM_DATABASE=5219 Wireless Keyboard + +usb:v03F0p0511* + ID_PRODUCT_FROM_DATABASE=OfficeJet K60 + +usb:v03F0p0512* + ID_PRODUCT_FROM_DATABASE=DeckJet 450 + +usb:v03F0p0517* + ID_PRODUCT_FROM_DATABASE=LaserJet 1000 + +usb:v03F0p051D* + ID_PRODUCT_FROM_DATABASE=Bluetooth Interface + +usb:v03F0p0601* + ID_PRODUCT_FROM_DATABASE=ScanJet 6300c + +usb:v03F0p0604* + ID_PRODUCT_FROM_DATABASE=DeskJet 840c + +usb:v03F0p0605* + ID_PRODUCT_FROM_DATABASE=ScanJet 2200c + +usb:v03F0p0611* + ID_PRODUCT_FROM_DATABASE=OfficeJet K60xi + +usb:v03F0p0612* + ID_PRODUCT_FROM_DATABASE=business inkjet 3000 + +usb:v03F0p0624* + ID_PRODUCT_FROM_DATABASE=Bluetooth Dongle + +usb:v03F0p0701* + ID_PRODUCT_FROM_DATABASE=ScanJet 5300c/5370c + +usb:v03F0p0704* + ID_PRODUCT_FROM_DATABASE=DeskJet 825c + +usb:v03F0p0705* + ID_PRODUCT_FROM_DATABASE=ScanJet 4400c + +usb:v03F0p0711* + ID_PRODUCT_FROM_DATABASE=OfficeJet K80 + +usb:v03F0p0712* + ID_PRODUCT_FROM_DATABASE=DeskJet 1180c + +usb:v03F0p0714* + ID_PRODUCT_FROM_DATABASE=Printing Support + +usb:v03F0p0801* + ID_PRODUCT_FROM_DATABASE=ScanJet 7400c + +usb:v03F0p0804* + ID_PRODUCT_FROM_DATABASE=DeskJet 816c + +usb:v03F0p0805* + ID_PRODUCT_FROM_DATABASE=HP4470C + +usb:v03F0p0811* + ID_PRODUCT_FROM_DATABASE=OfficeJet K80xi + +usb:v03F0p0817* + ID_PRODUCT_FROM_DATABASE=LaserJet 3300 + +usb:v03F0p0901* + ID_PRODUCT_FROM_DATABASE=ScanJet 2300c + +usb:v03F0p0904* + ID_PRODUCT_FROM_DATABASE=DeskJet 845c + +usb:v03F0p0912* + ID_PRODUCT_FROM_DATABASE=Printing Support + +usb:v03F0p0917* + ID_PRODUCT_FROM_DATABASE=LaserJet 3330 + +usb:v03F0p0924* + ID_PRODUCT_FROM_DATABASE=Modular Smartcard Keyboard + +usb:v03F0p0A01* + ID_PRODUCT_FROM_DATABASE=ScanJet 2400c + +usb:v03F0p0A17* + ID_PRODUCT_FROM_DATABASE=color LaserJet 3700 + +usb:v03F0p0B01* + ID_PRODUCT_FROM_DATABASE=ScanJet 82x0C + +usb:v03F0p0B0C* + ID_PRODUCT_FROM_DATABASE=Wireless Keyboard and Optical Mouse receiver + +usb:v03F0p0B17* + ID_PRODUCT_FROM_DATABASE=LaserJet 2300d + +usb:v03F0p0C17* + ID_PRODUCT_FROM_DATABASE=LaserJet 1010 + +usb:v03F0p0C24* + ID_PRODUCT_FROM_DATABASE=Bluetooth Dongle + +usb:v03F0p0D12* + ID_PRODUCT_FROM_DATABASE=OfficeJet 9100 series + +usb:v03F0p0D17* + ID_PRODUCT_FROM_DATABASE=LaserJet 1012 + +usb:v03F0p0E17* + ID_PRODUCT_FROM_DATABASE=LaserJet 1015 + +usb:v03F0p0F0C* + ID_PRODUCT_FROM_DATABASE=Wireless Keyboard and Optical Mouse receiver + +usb:v03F0p0F11* + ID_PRODUCT_FROM_DATABASE=OfficeJet V40 + +usb:v03F0p0F12* + ID_PRODUCT_FROM_DATABASE=Printing Support + +usb:v03F0p0F17* + ID_PRODUCT_FROM_DATABASE=LaserJet 1150 + +usb:v03F0p1001* + ID_PRODUCT_FROM_DATABASE=Photo Scanner 1000 + +usb:v03F0p1002* + ID_PRODUCT_FROM_DATABASE=PhotoSmart 140 series + +usb:v03F0p1004* + ID_PRODUCT_FROM_DATABASE=DeskJet 970c/970cse + +usb:v03F0p1005* + ID_PRODUCT_FROM_DATABASE=ScanJet 5400c + +usb:v03F0p1011* + ID_PRODUCT_FROM_DATABASE=OfficeJet V40xi + +usb:v03F0p1016* + ID_PRODUCT_FROM_DATABASE=Jornada 548 / iPAQ HW6515 Pocket PC + +usb:v03F0p1017* + ID_PRODUCT_FROM_DATABASE=LaserJet 1300 + +usb:v03F0p1024* + ID_PRODUCT_FROM_DATABASE=Smart Card Keyboard + +usb:v03F0p1027* + ID_PRODUCT_FROM_DATABASE=Virtual keyboard and mouse + +usb:v03F0p1102* + ID_PRODUCT_FROM_DATABASE=PhotoSmart 240 series + +usb:v03F0p1104* + ID_PRODUCT_FROM_DATABASE=DeskJet 959c + +usb:v03F0p1105* + ID_PRODUCT_FROM_DATABASE=ScanJet 5470c/5490c + +usb:v03F0p1111* + ID_PRODUCT_FROM_DATABASE=OfficeJet v60 + +usb:v03F0p1116* + ID_PRODUCT_FROM_DATABASE=Jornada 568 Pocket PC + +usb:v03F0p1117* + ID_PRODUCT_FROM_DATABASE=LaserJet 1300n + +usb:v03F0p1151* + ID_PRODUCT_FROM_DATABASE=PSC-750xi Printer/Scanner/Copier + +usb:v03F0p1202* + ID_PRODUCT_FROM_DATABASE=PhotoSmart 320 series + +usb:v03F0p1204* + ID_PRODUCT_FROM_DATABASE=DeskJet 930c + +usb:v03F0p1205* + ID_PRODUCT_FROM_DATABASE=ScanJet 4500C/5550C + +usb:v03F0p1211* + ID_PRODUCT_FROM_DATABASE=OfficeJet v60xi + +usb:v03F0p1217* + ID_PRODUCT_FROM_DATABASE=LaserJet 2300L + +usb:v03F0p1302* + ID_PRODUCT_FROM_DATABASE=PhotoSmart 370 series + +usb:v03F0p1305* + ID_PRODUCT_FROM_DATABASE=ScanJet 4570c + +usb:v03F0p1311* + ID_PRODUCT_FROM_DATABASE=OfficeJet V30 + +usb:v03F0p1312* + ID_PRODUCT_FROM_DATABASE=DeskJet 460 + +usb:v03F0p1317* + ID_PRODUCT_FROM_DATABASE=LaserJet 1005 + +usb:v03F0p1327* + ID_PRODUCT_FROM_DATABASE=iLO Virtual Hub + +usb:v03F0p1405* + ID_PRODUCT_FROM_DATABASE=ScanJet 3670 + +usb:v03F0p1411* + ID_PRODUCT_FROM_DATABASE=PSC 750 + +usb:v03F0p1424* + ID_PRODUCT_FROM_DATABASE=f2105 Monitor Hub + +usb:v03F0p1502* + ID_PRODUCT_FROM_DATABASE=PhotoSmart 420 series + +usb:v03F0p1504* + ID_PRODUCT_FROM_DATABASE=DeskJet 920c + +usb:v03F0p150C* + ID_PRODUCT_FROM_DATABASE=Mood Lighting (Microchip Technology Inc.) + +usb:v03F0p1511* + ID_PRODUCT_FROM_DATABASE=PSC 750xi + +usb:v03F0p1512* + ID_PRODUCT_FROM_DATABASE=Printing Support + +usb:v03F0p1517* + ID_PRODUCT_FROM_DATABASE=color LaserJet 3500 + +usb:v03F0p1524* + ID_PRODUCT_FROM_DATABASE=Smart Card Keyboard - KR + +usb:v03F0p1602* + ID_PRODUCT_FROM_DATABASE=PhotoSmart 330 series + +usb:v03F0p1604* + ID_PRODUCT_FROM_DATABASE=DeskJet 940c + +usb:v03F0p1605* + ID_PRODUCT_FROM_DATABASE=ScanJet 5530C PhotoSmart + +usb:v03F0p1611* + ID_PRODUCT_FROM_DATABASE=psc 780 + +usb:v03F0p1617* + ID_PRODUCT_FROM_DATABASE=LaserJet 3015 + +usb:v03F0p161D* + ID_PRODUCT_FROM_DATABASE=Wireless Rechargeable Optical Mouse (HID) + +usb:v03F0p1624* + ID_PRODUCT_FROM_DATABASE=Smart Card Keyboard - JP + +usb:v03F0p1702* + ID_PRODUCT_FROM_DATABASE=PhotoSmart 380 series + +usb:v03F0p1704* + ID_PRODUCT_FROM_DATABASE=DeskJet 948C + +usb:v03F0p1705* + ID_PRODUCT_FROM_DATABASE=ScanJet 5590 + +usb:v03F0p1711* + ID_PRODUCT_FROM_DATABASE=psc 780xi + +usb:v03F0p1712* + ID_PRODUCT_FROM_DATABASE=Printing Support + +usb:v03F0p1717* + ID_PRODUCT_FROM_DATABASE=LaserJet 3020 + +usb:v03F0p171D* + ID_PRODUCT_FROM_DATABASE=Bluetooth 2.0 Interface [Broadcom BCM2045] + +usb:v03F0p1801* + ID_PRODUCT_FROM_DATABASE=Inkjet P-2000U + +usb:v03F0p1802* + ID_PRODUCT_FROM_DATABASE=PhotoSmart 470 series + +usb:v03F0p1804* + ID_PRODUCT_FROM_DATABASE=DeskJet 916C + +usb:v03F0p1805* + ID_PRODUCT_FROM_DATABASE=ScanJet 7650 + +usb:v03F0p1811* + ID_PRODUCT_FROM_DATABASE=PSC 720 + +usb:v03F0p1812* + ID_PRODUCT_FROM_DATABASE=OfficeJet Pro K550 + +usb:v03F0p1817* + ID_PRODUCT_FROM_DATABASE=LaserJet 3030 + +usb:v03F0p181D* + ID_PRODUCT_FROM_DATABASE=Bluetooth 2.0 Interface + +usb:v03F0p1902* + ID_PRODUCT_FROM_DATABASE=PhotoSmart A430 series + +usb:v03F0p1904* + ID_PRODUCT_FROM_DATABASE=DeskJet 3820 + +usb:v03F0p1911* + ID_PRODUCT_FROM_DATABASE=OfficeJet V45 + +usb:v03F0p1917* + ID_PRODUCT_FROM_DATABASE=LaserJet 3380 + +usb:v03F0p1A02* + ID_PRODUCT_FROM_DATABASE=PhotoSmart A510 series + +usb:v03F0p1A11* + ID_PRODUCT_FROM_DATABASE=OfficeJet 5100 series + +usb:v03F0p1A17* + ID_PRODUCT_FROM_DATABASE=color LaserJet 4650 + +usb:v03F0p1B02* + ID_PRODUCT_FROM_DATABASE=PhotoSmart A610 series + +usb:v03F0p1B04* + ID_PRODUCT_FROM_DATABASE=DeskJet 3810 + +usb:v03F0p1B05* + ID_PRODUCT_FROM_DATABASE=ScanJet 4850C/4890C + +usb:v03F0p1B07* + ID_PRODUCT_FROM_DATABASE=Premium Starter Webcam + +usb:v03F0p1C02* + ID_PRODUCT_FROM_DATABASE=PhotoSmart A710 series + +usb:v03F0p1C17* + ID_PRODUCT_FROM_DATABASE=Color LaserJet 2550l + +usb:v03F0p1D02* + ID_PRODUCT_FROM_DATABASE=PhotoSmart A310 series + +usb:v03F0p1D17* + ID_PRODUCT_FROM_DATABASE=LaserJet 1320 + +usb:v03F0p1E02* + ID_PRODUCT_FROM_DATABASE=PhotoSmart A320 Printer series + +usb:v03F0p1E11* + ID_PRODUCT_FROM_DATABASE=PSC-950 + +usb:v03F0p1E17* + ID_PRODUCT_FROM_DATABASE=LaserJet 1160 series + +usb:v03F0p1F02* + ID_PRODUCT_FROM_DATABASE=PhotoSmart A440 Printer series + +usb:v03F0p1F11* + ID_PRODUCT_FROM_DATABASE=PSC 920 + +usb:v03F0p1F12* + ID_PRODUCT_FROM_DATABASE=OfficeJet Pro K5300 + +usb:v03F0p1F17* + ID_PRODUCT_FROM_DATABASE=color LaserJet 5550 + +usb:v03F0p1F1D* + ID_PRODUCT_FROM_DATABASE=un2400 Gobi Wireless Modem + +usb:v03F0p2001* + ID_PRODUCT_FROM_DATABASE=Floppy + +usb:v03F0p2002* + ID_PRODUCT_FROM_DATABASE=Hub + +usb:v03F0p2004* + ID_PRODUCT_FROM_DATABASE=DeskJet 640c + +usb:v03F0p2005* + ID_PRODUCT_FROM_DATABASE=ScanJet 3570c + +usb:v03F0p2012* + ID_PRODUCT_FROM_DATABASE=OfficeJet Pro K5400 + +usb:v03F0p201D* + ID_PRODUCT_FROM_DATABASE=un2400 Gobi Wireless Modem (QDL mode) + +usb:v03F0p2102* + ID_PRODUCT_FROM_DATABASE=PhotoSmart 7345 + +usb:v03F0p2104* + ID_PRODUCT_FROM_DATABASE=DeskJet 630c + +usb:v03F0p2112* + ID_PRODUCT_FROM_DATABASE=OfficeJet Pro L7500 + +usb:v03F0p211D* + ID_PRODUCT_FROM_DATABASE=Sierra MC5725 [ev2210] + +usb:v03F0p2202* + ID_PRODUCT_FROM_DATABASE=PhotoSmart 7600 series + +usb:v03F0p2205* + ID_PRODUCT_FROM_DATABASE=ScanJet 3500c + +usb:v03F0p2212* + ID_PRODUCT_FROM_DATABASE=OfficeJet Pro L7600 + +usb:v03F0p2217* + ID_PRODUCT_FROM_DATABASE=color LaserJet 9500 MFP + +usb:v03F0p2302* + ID_PRODUCT_FROM_DATABASE=PhotoSmart 7600 series + +usb:v03F0p2304* + ID_PRODUCT_FROM_DATABASE=DeskJet 656c + +usb:v03F0p2305* + ID_PRODUCT_FROM_DATABASE=ScanJet 3970c + +usb:v03F0p2311* + ID_PRODUCT_FROM_DATABASE=OfficeJet d series + +usb:v03F0p2312* + ID_PRODUCT_FROM_DATABASE=OfficeJet Pro L7700 + +usb:v03F0p2317* + ID_PRODUCT_FROM_DATABASE=LaserJet 4350 + +usb:v03F0p231D* + ID_PRODUCT_FROM_DATABASE=4 GB Flash Drive + +usb:v03F0p2402* + ID_PRODUCT_FROM_DATABASE=PhotoSmart 7700 series + +usb:v03F0p2404* + ID_PRODUCT_FROM_DATABASE=Deskjet F2280 series + +usb:v03F0p2405* + ID_PRODUCT_FROM_DATABASE=ScanJet 4070 PhotoSmart + +usb:v03F0p2417* + ID_PRODUCT_FROM_DATABASE=LaserJet 4250 + +usb:v03F0p241D* + ID_PRODUCT_FROM_DATABASE=Gobi 2000 Wireless Modem (QDL mode) + +usb:v03F0p2424* + ID_PRODUCT_FROM_DATABASE=LP1965 19" Monitor Hub + +usb:v03F0p2502* + ID_PRODUCT_FROM_DATABASE=PhotoSmart 7700 series + +usb:v03F0p2504* + ID_PRODUCT_FROM_DATABASE=DeskJet F4200 series + +usb:v03F0p2505* + ID_PRODUCT_FROM_DATABASE=ScanJet 3770 + +usb:v03F0p2512* + ID_PRODUCT_FROM_DATABASE=OfficeJet Pro L7300 + +usb:v03F0p2517* + ID_PRODUCT_FROM_DATABASE=LaserJet 2410 + +usb:v03F0p251D* + ID_PRODUCT_FROM_DATABASE=Gobi 2000 Wireless Modem + +usb:v03F0p2524* + ID_PRODUCT_FROM_DATABASE=LP3065 30" Monitor Hub + +usb:v03F0p2602* + ID_PRODUCT_FROM_DATABASE=PhotoSmart A520 series + +usb:v03F0p2605* + ID_PRODUCT_FROM_DATABASE=ScanJet 3800c + +usb:v03F0p2611* + ID_PRODUCT_FROM_DATABASE=OfficeJet 7100 series + +usb:v03F0p2617* + ID_PRODUCT_FROM_DATABASE=Color LaserJet 2820 series + +usb:v03F0p2624* + ID_PRODUCT_FROM_DATABASE=Pole Display (HP522 2 x 20 Line Display) + +usb:v03F0p2702* + ID_PRODUCT_FROM_DATABASE=PhotoSmart A620 series + +usb:v03F0p2704* + ID_PRODUCT_FROM_DATABASE=DeskJet 915 + +usb:v03F0p2717* + ID_PRODUCT_FROM_DATABASE=Color LaserJet 2830 + +usb:v03F0p2811* + ID_PRODUCT_FROM_DATABASE=PSC-2100 + +usb:v03F0p2817* + ID_PRODUCT_FROM_DATABASE=Color LaserJet 2840 + +usb:v03F0p2902* + ID_PRODUCT_FROM_DATABASE=PhotoSmart A820 series + +usb:v03F0p2911* + ID_PRODUCT_FROM_DATABASE=PSC 2200 + +usb:v03F0p2917* + ID_PRODUCT_FROM_DATABASE=LaserJet 2420 + +usb:v03F0p2A11* + ID_PRODUCT_FROM_DATABASE=PSC 2150 series + +usb:v03F0p2A17* + ID_PRODUCT_FROM_DATABASE=LaserJet 2430 + +usb:v03F0p2B11* + ID_PRODUCT_FROM_DATABASE=PSC 2170 series + +usb:v03F0p2B17* + ID_PRODUCT_FROM_DATABASE=LaserJet 1020 + +usb:v03F0p2C12* + ID_PRODUCT_FROM_DATABASE=Officejet J4680 + +usb:v03F0p2C17* + ID_PRODUCT_FROM_DATABASE=LaserJet 1022 + +usb:v03F0p2C24* + ID_PRODUCT_FROM_DATABASE=Logitech M-UAL-96 Mouse + +usb:v03F0p2D05* + ID_PRODUCT_FROM_DATABASE=Scanjet 7000 + +usb:v03F0p2D11* + ID_PRODUCT_FROM_DATABASE=OfficeJet 6110 + +usb:v03F0p2D17* + ID_PRODUCT_FROM_DATABASE=Printing Support + +usb:v03F0p2E11* + ID_PRODUCT_FROM_DATABASE=PSC 1000 + +usb:v03F0p2E17* + ID_PRODUCT_FROM_DATABASE=LaserJet 2600n + +usb:v03F0p2E24* + ID_PRODUCT_FROM_DATABASE=LP2275w Monitor Hub + +usb:v03F0p2F11* + ID_PRODUCT_FROM_DATABASE=PSC 1200 + +usb:v03F0p2F17* + ID_PRODUCT_FROM_DATABASE=EWS 2605dn + +usb:v03F0p2F24* + ID_PRODUCT_FROM_DATABASE=LP2475w Monitor Hub + +usb:v03F0p3002* + ID_PRODUCT_FROM_DATABASE=PhotoSmart P1000 + +usb:v03F0p3004* + ID_PRODUCT_FROM_DATABASE=DeskJet 980c + +usb:v03F0p3005* + ID_PRODUCT_FROM_DATABASE=ScanJet 4670v + +usb:v03F0p3011* + ID_PRODUCT_FROM_DATABASE=PSC 1100 series + +usb:v03F0p3017* + ID_PRODUCT_FROM_DATABASE=Printing Support + +usb:v03F0p3102* + ID_PRODUCT_FROM_DATABASE=PhotoSmart P1100 Printer w/ Card Reader + +usb:v03F0p3104* + ID_PRODUCT_FROM_DATABASE=DeskJet 960c + +usb:v03F0p3111* + ID_PRODUCT_FROM_DATABASE=OfficeJet 4100 series + +usb:v03F0p3117* + ID_PRODUCT_FROM_DATABASE=EWS 2605dtn + +usb:v03F0p311D* + ID_PRODUCT_FROM_DATABASE=Atheros AR9285 Malbec Bluetooth Adapter + +usb:v03F0p3202* + ID_PRODUCT_FROM_DATABASE=PhotoSmart 1215 + +usb:v03F0p3207* + ID_PRODUCT_FROM_DATABASE=4 GB flash drive + +usb:v03F0p3211* + ID_PRODUCT_FROM_DATABASE=OfficeJet 4105 series + +usb:v03F0p3217* + ID_PRODUCT_FROM_DATABASE=LaserJet 3050 + +usb:v03F0p3302* + ID_PRODUCT_FROM_DATABASE=PhotoSmart 1218 + +usb:v03F0p3304* + ID_PRODUCT_FROM_DATABASE=DeskJet 990c + +usb:v03F0p3312* + ID_PRODUCT_FROM_DATABASE=OfficeJet J6410 + +usb:v03F0p3317* + ID_PRODUCT_FROM_DATABASE=LaserJet 3052 + +usb:v03F0p3402* + ID_PRODUCT_FROM_DATABASE=PhotoSmart 1115 + +usb:v03F0p3404* + ID_PRODUCT_FROM_DATABASE=DeskJet 6122 + +usb:v03F0p3417* + ID_PRODUCT_FROM_DATABASE=LaserJet 3055 + +usb:v03F0p3502* + ID_PRODUCT_FROM_DATABASE=PhotoSmart 230 + +usb:v03F0p3504* + ID_PRODUCT_FROM_DATABASE=DeskJet 6127c + +usb:v03F0p3511* + ID_PRODUCT_FROM_DATABASE=PSC 2300 + +usb:v03F0p3517* + ID_PRODUCT_FROM_DATABASE=LaserJet 3390 + +usb:v03F0p3602* + ID_PRODUCT_FROM_DATABASE=PhotoSmart 1315 + +usb:v03F0p3611* + ID_PRODUCT_FROM_DATABASE=PSC 2410 PhotoSmart + +usb:v03F0p3617* + ID_PRODUCT_FROM_DATABASE=Color LaserJet 2605 + +usb:v03F0p3711* + ID_PRODUCT_FROM_DATABASE=PSC 2500 + +usb:v03F0p3717* + ID_PRODUCT_FROM_DATABASE=EWS UPD + +usb:v03F0p3724* + ID_PRODUCT_FROM_DATABASE=Webcam + +usb:v03F0p3802* + ID_PRODUCT_FROM_DATABASE=PhotoSmart 100 + +usb:v03F0p3807* + ID_PRODUCT_FROM_DATABASE=c485w Flash Drive + +usb:v03F0p3817* + ID_PRODUCT_FROM_DATABASE=LaserJet P2015 series + +usb:v03F0p3902* + ID_PRODUCT_FROM_DATABASE=PhotoSmart 130 + +usb:v03F0p3A02* + ID_PRODUCT_FROM_DATABASE=PhotoSmart 7150 + +usb:v03F0p3A11* + ID_PRODUCT_FROM_DATABASE=OfficeJet 5500 series + +usb:v03F0p3A17* + ID_PRODUCT_FROM_DATABASE=Printing Support + +usb:v03F0p3B02* + ID_PRODUCT_FROM_DATABASE=PhotoSmart 7150~ + +usb:v03F0p3B11* + ID_PRODUCT_FROM_DATABASE=PSC 1300 series + +usb:v03F0p3B17* + ID_PRODUCT_FROM_DATABASE=LaserJet M1005 MFP + +usb:v03F0p3C02* + ID_PRODUCT_FROM_DATABASE=PhotoSmart 7350 + +usb:v03F0p3C11* + ID_PRODUCT_FROM_DATABASE=PSC 1358 + +usb:v03F0p3C17* + ID_PRODUCT_FROM_DATABASE=EWS UPD + +usb:v03F0p3D02* + ID_PRODUCT_FROM_DATABASE=PhotoSmart 7350~ + +usb:v03F0p3D11* + ID_PRODUCT_FROM_DATABASE=OfficeJet 4215 + +usb:v03F0p3D17* + ID_PRODUCT_FROM_DATABASE=LaserJet P1005 + +usb:v03F0p3E02* + ID_PRODUCT_FROM_DATABASE=PhotoSmart 7550 + +usb:v03F0p3E17* + ID_PRODUCT_FROM_DATABASE=LaserJet P1006 + +usb:v03F0p3F02* + ID_PRODUCT_FROM_DATABASE=PhotoSmart 7550~ + +usb:v03F0p3F11* + ID_PRODUCT_FROM_DATABASE=PSC-1315/PSC-1317 + +usb:v03F0p4002* + ID_PRODUCT_FROM_DATABASE=PhotoSmart 635/715/720/735/935 (storage) + +usb:v03F0p4004* + ID_PRODUCT_FROM_DATABASE=cp1160 + +usb:v03F0p4102* + ID_PRODUCT_FROM_DATABASE=PhotoSmart 618 + +usb:v03F0p4105* + ID_PRODUCT_FROM_DATABASE=ScanJet 4370 + +usb:v03F0p4111* + ID_PRODUCT_FROM_DATABASE=OfficeJet 7200 series + +usb:v03F0p4117* + ID_PRODUCT_FROM_DATABASE=LaserJet 1018 + +usb:v03F0p4202* + ID_PRODUCT_FROM_DATABASE=PhotoSmart 812 + +usb:v03F0p4205* + ID_PRODUCT_FROM_DATABASE=ScanJet G3010 + +usb:v03F0p4211* + ID_PRODUCT_FROM_DATABASE=OfficeJet 7300 series + +usb:v03F0p4217* + ID_PRODUCT_FROM_DATABASE=EWS CM1015 + +usb:v03F0p4302* + ID_PRODUCT_FROM_DATABASE=PhotoSmart 850 (ptp) + +usb:v03F0p4305* + ID_PRODUCT_FROM_DATABASE=ScanJet G3110 + +usb:v03F0p4311* + ID_PRODUCT_FROM_DATABASE=OfficeJet 7400 series + +usb:v03F0p4317* + ID_PRODUCT_FROM_DATABASE=Color LaserJet CM1017 + +usb:v03F0p4402* + ID_PRODUCT_FROM_DATABASE=PhotoSmart 935 (ptp) + +usb:v03F0p4417* + ID_PRODUCT_FROM_DATABASE=EWS UPD + +usb:v03F0p4502* + ID_PRODUCT_FROM_DATABASE=PhotoSmart 945 (PTP mode) + +usb:v03F0p4505* + ID_PRODUCT_FROM_DATABASE=ScanJet G4010 + +usb:v03F0p4511* + ID_PRODUCT_FROM_DATABASE=PhotoSmart 2600 + +usb:v03F0p4512* + ID_PRODUCT_FROM_DATABASE=E709n [Officejet 6500 Wireless] + +usb:v03F0p4517* + ID_PRODUCT_FROM_DATABASE=EWS UPD + +usb:v03F0p4605* + ID_PRODUCT_FROM_DATABASE=ScanJet G4050 + +usb:v03F0p4611* + ID_PRODUCT_FROM_DATABASE=PhotoSmart 2700 + +usb:v03F0p4717* + ID_PRODUCT_FROM_DATABASE=Color LaserJet CP1215 + +usb:v03F0p4811* + ID_PRODUCT_FROM_DATABASE=PSC 1600 + +usb:v03F0p4911* + ID_PRODUCT_FROM_DATABASE=PSC 2350 + +usb:v03F0p4B11* + ID_PRODUCT_FROM_DATABASE=OfficeJet 6200 + +usb:v03F0p4C11* + ID_PRODUCT_FROM_DATABASE=PSC 1500 series + +usb:v03F0p4C17* + ID_PRODUCT_FROM_DATABASE=EWS UPD + +usb:v03F0p4D11* + ID_PRODUCT_FROM_DATABASE=PSC 1400 + +usb:v03F0p4D17* + ID_PRODUCT_FROM_DATABASE=EWS UPD + +usb:v03F0p4E11* + ID_PRODUCT_FROM_DATABASE=PhotoSmart 2570 series + +usb:v03F0p4F11* + ID_PRODUCT_FROM_DATABASE=OfficeJet 5600 (USBHUB) + +usb:v03F0p4F17* + ID_PRODUCT_FROM_DATABASE=Color LaserJet CM1312 MFP + +usb:v03F0p5004* + ID_PRODUCT_FROM_DATABASE=DeskJet 995c + +usb:v03F0p5011* + ID_PRODUCT_FROM_DATABASE=PhotoSmart 3100 series + +usb:v03F0p5017* + ID_PRODUCT_FROM_DATABASE=EWS UPD + +usb:v03F0p5111* + ID_PRODUCT_FROM_DATABASE=PhotoSmart 3200 series + +usb:v03F0p5211* + ID_PRODUCT_FROM_DATABASE=PhotoSmart 3300 series + +usb:v03F0p5311* + ID_PRODUCT_FROM_DATABASE=OfficeJet 6300 + +usb:v03F0p5312* + ID_PRODUCT_FROM_DATABASE=Officejet Pro 8500A + +usb:v03F0p5411* + ID_PRODUCT_FROM_DATABASE=OfficeJet 4300 + +usb:v03F0p5511* + ID_PRODUCT_FROM_DATABASE=DeskJet F300 series + +usb:v03F0p5611* + ID_PRODUCT_FROM_DATABASE=PhotoSmart C3180 + +usb:v03F0p5617* + ID_PRODUCT_FROM_DATABASE=LaserJet M1120 MFP + +usb:v03F0p5711* + ID_PRODUCT_FROM_DATABASE=PhotoSmart C4100 series + +usb:v03F0p5717* + ID_PRODUCT_FROM_DATABASE=LaserJet M1120n MFP + +usb:v03F0p5811* + ID_PRODUCT_FROM_DATABASE=PhotoSmart C5100 series + +usb:v03F0p5817* + ID_PRODUCT_FROM_DATABASE=LaserJet M1319f MFP + +usb:v03F0p5911* + ID_PRODUCT_FROM_DATABASE=PhotoSmart C6180 + +usb:v03F0p5A11* + ID_PRODUCT_FROM_DATABASE=PhotoSmart C7100 series + +usb:v03F0p5B11* + ID_PRODUCT_FROM_DATABASE=OfficeJet J2100 series + +usb:v03F0p5C11* + ID_PRODUCT_FROM_DATABASE=PhotoSmart C4200 Printer series + +usb:v03F0p5C17* + ID_PRODUCT_FROM_DATABASE=LaserJet P2055 series + +usb:v03F0p5D11* + ID_PRODUCT_FROM_DATABASE=PhotoSmart C5200 series + +usb:v03F0p5E11* + ID_PRODUCT_FROM_DATABASE=PhotoSmart D7400 series + +usb:v03F0p6004* + ID_PRODUCT_FROM_DATABASE=DeskJet 5550 + +usb:v03F0p6102* + ID_PRODUCT_FROM_DATABASE=Hewlett Packard Digital Camera + +usb:v03F0p6104* + ID_PRODUCT_FROM_DATABASE=DeskJet 5650c + +usb:v03F0p6117* + ID_PRODUCT_FROM_DATABASE=color LaserJet 3550 + +usb:v03F0p6202* + ID_PRODUCT_FROM_DATABASE=PhotoSmart 215 + +usb:v03F0p6204* + ID_PRODUCT_FROM_DATABASE=DeskJet 5150c + +usb:v03F0p6217* + ID_PRODUCT_FROM_DATABASE=Color LaserJet 4700 + +usb:v03F0p6302* + ID_PRODUCT_FROM_DATABASE=PhotoSmart 318/612 + +usb:v03F0p6317* + ID_PRODUCT_FROM_DATABASE=Color LaserJet 4730mfp + +usb:v03F0p6402* + ID_PRODUCT_FROM_DATABASE=PhotoSmart 715 (ptp) + +usb:v03F0p6411* + ID_PRODUCT_FROM_DATABASE=PhotoSmart C8100 series + +usb:v03F0p6417* + ID_PRODUCT_FROM_DATABASE=LaserJet 5200 + +usb:v03F0p6502* + ID_PRODUCT_FROM_DATABASE=PhotoSmart 120 (ptp) + +usb:v03F0p6511* + ID_PRODUCT_FROM_DATABASE=PhotoSmart C7200 series + +usb:v03F0p6602* + ID_PRODUCT_FROM_DATABASE=PhotoSmart 320 + +usb:v03F0p6611* + ID_PRODUCT_FROM_DATABASE=PhotoSmart C4380 series + +usb:v03F0p6617* + ID_PRODUCT_FROM_DATABASE=LaserJet 5200L + +usb:v03F0p6702* + ID_PRODUCT_FROM_DATABASE=PhotoSmart 720 (ptp) + +usb:v03F0p6717* + ID_PRODUCT_FROM_DATABASE=Color LaserJet 3000 + +usb:v03F0p6802* + ID_PRODUCT_FROM_DATABASE=PhotoSmart 620 (ptp) + +usb:v03F0p6811* + ID_PRODUCT_FROM_DATABASE=PhotoSmart D5300 series + +usb:v03F0p6817* + ID_PRODUCT_FROM_DATABASE=Color LaserJet 3800 + +usb:v03F0p6911* + ID_PRODUCT_FROM_DATABASE=PhotoSmart D7200 series + +usb:v03F0p6917* + ID_PRODUCT_FROM_DATABASE=Color LaserJet 3600 + +usb:v03F0p6A02* + ID_PRODUCT_FROM_DATABASE=PhotoSmart 735 (ptp) + +usb:v03F0p6A11* + ID_PRODUCT_FROM_DATABASE=PhotoSmart C6200 series + +usb:v03F0p6A17* + ID_PRODUCT_FROM_DATABASE=LaserJet 4240 + +usb:v03F0p6B02* + ID_PRODUCT_FROM_DATABASE=PhotoSmart R707 (PTP mode) + +usb:v03F0p6B11* + ID_PRODUCT_FROM_DATABASE=Photosmart C4500 series + +usb:v03F0p6C17* + ID_PRODUCT_FROM_DATABASE=Color LaserJet 4610 + +usb:v03F0p6F17* + ID_PRODUCT_FROM_DATABASE=Color LaserJet CP6015 series + +usb:v03F0p7004* + ID_PRODUCT_FROM_DATABASE=DeskJet 3320c + +usb:v03F0p7102* + ID_PRODUCT_FROM_DATABASE=PhotoSmart 635 (PTP mode) + +usb:v03F0p7104* + ID_PRODUCT_FROM_DATABASE=DeskJet 3420c + +usb:v03F0p7117* + ID_PRODUCT_FROM_DATABASE=CM8060 Color MFP with Edgeline Technology + +usb:v03F0p7202* + ID_PRODUCT_FROM_DATABASE=PhotoSmart 43x (ptp) + +usb:v03F0p7204* + ID_PRODUCT_FROM_DATABASE=DeskJet 36xx + +usb:v03F0p7217* + ID_PRODUCT_FROM_DATABASE=LaserJet M5035 MFP + +usb:v03F0p7302* + ID_PRODUCT_FROM_DATABASE=PhotoSmart M307 (PTP mode) + +usb:v03F0p7304* + ID_PRODUCT_FROM_DATABASE=DeskJet 35xx + +usb:v03F0p7311* + ID_PRODUCT_FROM_DATABASE=Photosmart Premium C309 + +usb:v03F0p7317* + ID_PRODUCT_FROM_DATABASE=LaserJet P3005 + +usb:v03F0p7404* + ID_PRODUCT_FROM_DATABASE=Printing Support + +usb:v03F0p7417* + ID_PRODUCT_FROM_DATABASE=LaserJet M4345 MFP + +usb:v03F0p7504* + ID_PRODUCT_FROM_DATABASE=Printing Support + +usb:v03F0p7517* + ID_PRODUCT_FROM_DATABASE=LaserJet M3035 MFP + +usb:v03F0p7604* + ID_PRODUCT_FROM_DATABASE=DeskJet 3940 + +usb:v03F0p7611* + ID_PRODUCT_FROM_DATABASE=DeskJet F2492 All-in-One + +usb:v03F0p7617* + ID_PRODUCT_FROM_DATABASE=LaserJet P3004 + +usb:v03F0p7702* + ID_PRODUCT_FROM_DATABASE=PhotoSmart R817 (PTP mode) + +usb:v03F0p7704* + ID_PRODUCT_FROM_DATABASE=DeskJet D4100 + +usb:v03F0p7717* + ID_PRODUCT_FROM_DATABASE=CM8050 Color MFP with Edgeline Technology + +usb:v03F0p7804* + ID_PRODUCT_FROM_DATABASE=DeskJet D1360 + +usb:v03F0p7817* + ID_PRODUCT_FROM_DATABASE=Color LaserJet CP3505 + +usb:v03F0p7917* + ID_PRODUCT_FROM_DATABASE=LaserJet M5025 MFP + +usb:v03F0p7A02* + ID_PRODUCT_FROM_DATABASE=PhotoSmart M415 (PTP mode) + +usb:v03F0p7A04* + ID_PRODUCT_FROM_DATABASE=DeskJet D2460 + +usb:v03F0p7A17* + ID_PRODUCT_FROM_DATABASE=LaserJet M3027 MFP + +usb:v03F0p7B02* + ID_PRODUCT_FROM_DATABASE=PhotoSmart M23 (PTP mode) + +usb:v03F0p7B17* + ID_PRODUCT_FROM_DATABASE=Color LaserJet CP4005 + +usb:v03F0p7C17* + ID_PRODUCT_FROM_DATABASE=Color LaserJet CM6040 series + +usb:v03F0p7D04* + ID_PRODUCT_FROM_DATABASE=DeskJet F2100 Printer series + +usb:v03F0p7D17* + ID_PRODUCT_FROM_DATABASE=Color LaserJet CM4730 MFP + +usb:v03F0p7E04* + ID_PRODUCT_FROM_DATABASE=DeskJet F4100 Printer series + +usb:v03F0p8017* + ID_PRODUCT_FROM_DATABASE=LaserJet P4515 + +usb:v03F0p8104* + ID_PRODUCT_FROM_DATABASE=Printing Support + +usb:v03F0p8117* + ID_PRODUCT_FROM_DATABASE=LaserJet P4015 + +usb:v03F0p811C* + ID_PRODUCT_FROM_DATABASE=Ethernet HN210E + +usb:v03F0p8204* + ID_PRODUCT_FROM_DATABASE=Printing Support + +usb:v03F0p8207* + ID_PRODUCT_FROM_DATABASE=FHA-3510 2.4GHz Wireless Optical Mobile Mouse + +usb:v03F0p8217* + ID_PRODUCT_FROM_DATABASE=LaserJet P4014 + +usb:v03F0p8317* + ID_PRODUCT_FROM_DATABASE=LaserJet M9050 MFP + +usb:v03F0p8404* + ID_PRODUCT_FROM_DATABASE=DeskJet 6800 series + +usb:v03F0p8417* + ID_PRODUCT_FROM_DATABASE=LaserJet M9040 MFP + +usb:v03F0p8504* + ID_PRODUCT_FROM_DATABASE=DeskJet 6600 series + +usb:v03F0p8604* + ID_PRODUCT_FROM_DATABASE=DeskJet 5440 + +usb:v03F0p8704* + ID_PRODUCT_FROM_DATABASE=DeskJet 5940 + +usb:v03F0p8711* + ID_PRODUCT_FROM_DATABASE=Deskjet 2050 J510 + +usb:v03F0p8804* + ID_PRODUCT_FROM_DATABASE=DeskJet 6980 series + +usb:v03F0p8904* + ID_PRODUCT_FROM_DATABASE=DeskJet 6940 series + +usb:v03F0p8C07* + ID_PRODUCT_FROM_DATABASE=Digital Stereo Headset + +usb:v03F0p8C11* + ID_PRODUCT_FROM_DATABASE=Deskjet F4500 series + +usb:v03F0p9002* + ID_PRODUCT_FROM_DATABASE=PhotoSmart M437 + +usb:v03F0p9102* + ID_PRODUCT_FROM_DATABASE=PhotoSmart M537 + +usb:v03F0p9302* + ID_PRODUCT_FROM_DATABASE=PhotoSmart R930 series + +usb:v03F0p9402* + ID_PRODUCT_FROM_DATABASE=PhotoSmart R837 + +usb:v03F0p9502* + ID_PRODUCT_FROM_DATABASE=PhotoSmart R840 series + +usb:v03F0p9602* + ID_PRODUCT_FROM_DATABASE=PhotoSmart M730 series + +usb:v03F0p9702* + ID_PRODUCT_FROM_DATABASE=PhotoSmart R740 series + +usb:v03F0p9802* + ID_PRODUCT_FROM_DATABASE=PhotoSmart Mz60 series + +usb:v03F0p9902* + ID_PRODUCT_FROM_DATABASE=PhotoSmart M630 series + +usb:v03F0p9A02* + ID_PRODUCT_FROM_DATABASE=PhotoSmart E330 series + +usb:v03F0p9B02* + ID_PRODUCT_FROM_DATABASE=PhotoSmart M540 series + +usb:v03F0p9C02* + ID_PRODUCT_FROM_DATABASE=PhotoSmart M440 series + +usb:v03F0pA004* + ID_PRODUCT_FROM_DATABASE=DeskJet 5850c + +usb:v03F0pA011* + ID_PRODUCT_FROM_DATABASE=Deskjet 3050A + +usb:v03F0pB002* + ID_PRODUCT_FROM_DATABASE=PhotoSmart 7200 series + +usb:v03F0pB102* + ID_PRODUCT_FROM_DATABASE=PhotoSmart 7200 series + +usb:v03F0pB107* + ID_PRODUCT_FROM_DATABASE=v255w/c310w Flash Drive + +usb:v03F0pB116* + ID_PRODUCT_FROM_DATABASE=Webcam + +usb:v03F0pB202* + ID_PRODUCT_FROM_DATABASE=PhotoSmart 7600 series + +usb:v03F0pB302* + ID_PRODUCT_FROM_DATABASE=PhotoSmart 7600 series + +usb:v03F0pB402* + ID_PRODUCT_FROM_DATABASE=PhotoSmart 7700 series + +usb:v03F0pB502* + ID_PRODUCT_FROM_DATABASE=PhotoSmart 7700 series + +usb:v03F0pB602* + ID_PRODUCT_FROM_DATABASE=PhotoSmart 7900 series + +usb:v03F0pB702* + ID_PRODUCT_FROM_DATABASE=PhotoSmart 7900 series + +usb:v03F0pB802* + ID_PRODUCT_FROM_DATABASE=PhotoSmart 7400 series + +usb:v03F0pB902* + ID_PRODUCT_FROM_DATABASE=PhotoSmart 7800 series + +usb:v03F0pBA02* + ID_PRODUCT_FROM_DATABASE=PhotoSmart 8100 series + +usb:v03F0pBB02* + ID_PRODUCT_FROM_DATABASE=PhotoSmart 8400 series + +usb:v03F0pBC02* + ID_PRODUCT_FROM_DATABASE=PhotoSmart 8700 series + +usb:v03F0pBD02* + ID_PRODUCT_FROM_DATABASE=PhotoSmart Pro B9100 series + +usb:v03F0pBEF4* + ID_PRODUCT_FROM_DATABASE=NEC Picty760 + +usb:v03F0pC002* + ID_PRODUCT_FROM_DATABASE=PhotoSmart 7800 series + +usb:v03F0pC102* + ID_PRODUCT_FROM_DATABASE=PhotoSmart 8000 series + +usb:v03F0pC202* + ID_PRODUCT_FROM_DATABASE=PhotoSmart 8200 series + +usb:v03F0pC302* + ID_PRODUCT_FROM_DATABASE=DeskJet D2300 + +usb:v03F0pC402* + ID_PRODUCT_FROM_DATABASE=PhotoSmart D5100 series + +usb:v03F0pC502* + ID_PRODUCT_FROM_DATABASE=PhotoSmart D6100 series + +usb:v03F0pC602* + ID_PRODUCT_FROM_DATABASE=PhotoSmart D7100 series + +usb:v03F0pC702* + ID_PRODUCT_FROM_DATABASE=PhotoSmart D7300 series + +usb:v03F0pC802* + ID_PRODUCT_FROM_DATABASE=PhotoSmart D5060 Printer + +usb:v03F0pD104* + ID_PRODUCT_FROM_DATABASE=Bluetooth Dongle + +usb:v03F0pEFBE* + ID_PRODUCT_FROM_DATABASE=NEC Picty900 + +usb:v03F0pF0BE* + ID_PRODUCT_FROM_DATABASE=NEC Picty920 + +usb:v03F0pF1BE* + ID_PRODUCT_FROM_DATABASE=NEC Picty800 + +usb:v03F1* + ID_VENDOR_FROM_DATABASE=Genoa Technology + +usb:v03F2* + ID_VENDOR_FROM_DATABASE=Oak Technology, Inc. + +usb:v03F3* + ID_VENDOR_FROM_DATABASE=Adaptec, Inc. + +usb:v03F3p0020* + ID_PRODUCT_FROM_DATABASE=AWN-8020 WLAN [Intersil PRISM 2.5] + +usb:v03F3p0080* + ID_PRODUCT_FROM_DATABASE=AVC-1100 Audio Capture + +usb:v03F3p0083* + ID_PRODUCT_FROM_DATABASE=AVC-2200 Device + +usb:v03F3p0087* + ID_PRODUCT_FROM_DATABASE=AVC-2210 Loader + +usb:v03F3p0088* + ID_PRODUCT_FROM_DATABASE=AVC-2210 Device + +usb:v03F3p008B* + ID_PRODUCT_FROM_DATABASE=AVC-2310 Loader + +usb:v03F3p008C* + ID_PRODUCT_FROM_DATABASE=AVC-2310 Device + +usb:v03F3p0094* + ID_PRODUCT_FROM_DATABASE=eHome Infrared Receiver + +usb:v03F3p009B* + ID_PRODUCT_FROM_DATABASE=AVC-1410 GameBridge TV NTSC + +usb:v03F3p2000* + ID_PRODUCT_FROM_DATABASE=USBXchange + +usb:v03F3p2001* + ID_PRODUCT_FROM_DATABASE=USBXchange Adapter + +usb:v03F3p2002* + ID_PRODUCT_FROM_DATABASE=USB2-Xchange + +usb:v03F3p2003* + ID_PRODUCT_FROM_DATABASE=USB2-Xchange Adapter + +usb:v03F3p4000* + ID_PRODUCT_FROM_DATABASE=4-port hub + +usb:v03F3pADCC* + ID_PRODUCT_FROM_DATABASE=Composite Device Support + +usb:v03F4* + ID_VENDOR_FROM_DATABASE=Diebold, Inc. + +usb:v03F5* + ID_VENDOR_FROM_DATABASE=Siemens Electromechanical + +usb:v03F8* + ID_VENDOR_FROM_DATABASE=Epson Imaging Technology Center + +usb:v03F9* + ID_VENDOR_FROM_DATABASE=KeyTronic Corp. + +usb:v03F9p0100* + ID_PRODUCT_FROM_DATABASE=KT-2001 Keyboard + +usb:v03F9p0101* + ID_PRODUCT_FROM_DATABASE=Keyboard + +usb:v03F9p0102* + ID_PRODUCT_FROM_DATABASE=Keyboard Mouse + +usb:v03FB* + ID_VENDOR_FROM_DATABASE=OPTi, Inc. + +usb:v03FC* + ID_VENDOR_FROM_DATABASE=Elitegroup Computer Systems + +usb:v03FD* + ID_VENDOR_FROM_DATABASE=Xilinx, Inc. + +usb:v03FE* + ID_VENDOR_FROM_DATABASE=Farallon Comunications + +usb:v0400* + ID_VENDOR_FROM_DATABASE=National Semiconductor Corp. + +usb:v0400p05DC* + ID_PRODUCT_FROM_DATABASE=Rigol Technologies DS1000USB Oscilloscope + +usb:v0400p0807* + ID_PRODUCT_FROM_DATABASE=Bluetooth Dongle + +usb:v0400p080A* + ID_PRODUCT_FROM_DATABASE=Bluetooth Device + +usb:v0400p09C4* + ID_PRODUCT_FROM_DATABASE=Rigol Technologies DG1022 Arbitrary Waveform Generator + +usb:v0400p1000* + ID_PRODUCT_FROM_DATABASE=Mustek BearPaw 1200 Scanner + +usb:v0400p1001* + ID_PRODUCT_FROM_DATABASE=Mustek BearPaw 2400 Scanner + +usb:v0400p1237* + ID_PRODUCT_FROM_DATABASE=Hub + +usb:v0400pA000* + ID_PRODUCT_FROM_DATABASE=Smart Display Reference Device + +usb:v0400pC359* + ID_PRODUCT_FROM_DATABASE=Logitech Harmony (Boot loader mode) + +usb:v0400pC35B* + ID_PRODUCT_FROM_DATABASE=Printing Support + +usb:v0400pC55D* + ID_PRODUCT_FROM_DATABASE=Rigol Technologies DS5000USB Oscilloscope + +usb:v0401* + ID_VENDOR_FROM_DATABASE=National Registry, Inc. + +usb:v0402* + ID_VENDOR_FROM_DATABASE=ALi Corp. + +usb:v0402p5462* + ID_PRODUCT_FROM_DATABASE=M5462 IDE Controller + +usb:v0402p5602* + ID_PRODUCT_FROM_DATABASE=M5602 Video Camera Controller + +usb:v0402p5603* + ID_PRODUCT_FROM_DATABASE=M5603 Video Camera Controller + +usb:v0402p5606* + ID_PRODUCT_FROM_DATABASE=M5606 Video Camera Controller [UVC] + +usb:v0402p5621* + ID_PRODUCT_FROM_DATABASE=M5621 High-Speed IDE Controller + +usb:v0402p5623* + ID_PRODUCT_FROM_DATABASE=M5623 Scanner Controller + +usb:v0402p5627* + ID_PRODUCT_FROM_DATABASE=Welland ME-740PS USB2 3.5" Power Saving Enclosure + +usb:v0402p5632* + ID_PRODUCT_FROM_DATABASE=M5632 Host-to-Host Link + +usb:v0402p5635* + ID_PRODUCT_FROM_DATABASE=M5635 Flash Card Reader + +usb:v0402p5636* + ID_PRODUCT_FROM_DATABASE=USB 2.0 Storage Device + +usb:v0402p5637* + ID_PRODUCT_FROM_DATABASE=M5637 IDE Controller + +usb:v0402p5661* + ID_PRODUCT_FROM_DATABASE=M5661 MP3 player + +usb:v0402p5667* + ID_PRODUCT_FROM_DATABASE=M5667 MP3 player + +usb:v0402p9665* + ID_PRODUCT_FROM_DATABASE=Gateway Webcam + +usb:v0403* + ID_VENDOR_FROM_DATABASE=Future Technology Devices International, Ltd + +usb:v0403p0000* + ID_PRODUCT_FROM_DATABASE=H4SMK 7 Port Hub + +usb:v0403p0232* + ID_PRODUCT_FROM_DATABASE=Serial Converter + +usb:v0403p1060* + ID_PRODUCT_FROM_DATABASE=JTAG adapter + +usb:v0403p6001* + ID_PRODUCT_FROM_DATABASE=FT232 USB-Serial (UART) IC + +usb:v0403p6002* + ID_PRODUCT_FROM_DATABASE=Lumel PD12 + +usb:v0403p6007* + ID_PRODUCT_FROM_DATABASE=Serial Converter + +usb:v0403p6008* + ID_PRODUCT_FROM_DATABASE=Serial Converter + +usb:v0403p6009* + ID_PRODUCT_FROM_DATABASE=Serial Converter + +usb:v0403p6010* + ID_PRODUCT_FROM_DATABASE=FT2232C Dual USB-UART/FIFO IC + +usb:v0403p6011* + ID_PRODUCT_FROM_DATABASE=FT4232H Quad HS USB-UART/FIFO IC + +usb:v0403p6014* + ID_PRODUCT_FROM_DATABASE=FT232H Single HS USB-UART/FIFO IC + +usb:v0403p6015* + ID_PRODUCT_FROM_DATABASE=Bridge(I2C/SPI/UART/FIFO) + +usb:v0403p8040* + ID_PRODUCT_FROM_DATABASE=4 Port Hub + +usb:v0403p8070* + ID_PRODUCT_FROM_DATABASE=7 Port Hub + +usb:v0403p8370* + ID_PRODUCT_FROM_DATABASE=7 Port Hub + +usb:v0403p8371* + ID_PRODUCT_FROM_DATABASE=PS/2 Keyboard And Mouse + +usb:v0403p8372* + ID_PRODUCT_FROM_DATABASE=FT8U100AX Serial Port + +usb:v0403p8A28* + ID_PRODUCT_FROM_DATABASE=Rainforest Automation ZigBee Controller + +usb:v0403p8A98* + ID_PRODUCT_FROM_DATABASE=TIAO Multi-Protocol Adapter + +usb:v0403p9E90* + ID_PRODUCT_FROM_DATABASE=Marvell OpenRD Base/Client + +usb:v0403p9F80* + ID_PRODUCT_FROM_DATABASE=Ewert Energy Systems CANdapter + +usb:v0403pA6D0* + ID_PRODUCT_FROM_DATABASE=Texas Instruments XDS100v2 JTAG / BeagleBone A3 + +usb:v0403pA951* + ID_PRODUCT_FROM_DATABASE=HCP HIT GSM/GPRS modem [Cinterion MC55i] + +usb:v0403pABB8* + ID_PRODUCT_FROM_DATABASE=Lego Mindstorms NXTCam + +usb:v0403pB810* + ID_PRODUCT_FROM_DATABASE=US Interface Navigator (CAT and 2nd PTT lines) + +usb:v0403pB811* + ID_PRODUCT_FROM_DATABASE=US Interface Navigator (WKEY and FSK lines) + +usb:v0403pB812* + ID_PRODUCT_FROM_DATABASE=US Interface Navigator (RS232 and CONFIG lines) + +usb:v0403pB9B0* + ID_PRODUCT_FROM_DATABASE=Fujitsu SK-16FX-100PMC V1.1 + +usb:v0403pBAF8* + ID_PRODUCT_FROM_DATABASE=Amontec JTAGkey - Open On-Chip Debugger + +usb:v0403pBCD8* + ID_PRODUCT_FROM_DATABASE=Stellaris Development Board + +usb:v0403pBCD9* + ID_PRODUCT_FROM_DATABASE=Stellaris Evaluation Board + +usb:v0403pBCDA* + ID_PRODUCT_FROM_DATABASE=Stellaris ICDI Board + +usb:v0403pBDC8* + ID_PRODUCT_FROM_DATABASE=Egnite GmbH - JTAG/RS-232 adapter + +usb:v0403pBFD8* + ID_PRODUCT_FROM_DATABASE=OpenDCC + +usb:v0403pBFD9* + ID_PRODUCT_FROM_DATABASE=OpenDCC (Sniffer) + +usb:v0403pBFDA* + ID_PRODUCT_FROM_DATABASE=OpenDCC (Throttle) + +usb:v0403pBFDB* + ID_PRODUCT_FROM_DATABASE=OpenDCC (Gateway) + +usb:v0403pBFDC* + ID_PRODUCT_FROM_DATABASE=OpenDCC (GBM) + +usb:v0403pC630* + ID_PRODUCT_FROM_DATABASE=lcd2usb interface + +usb:v0403pC631* + ID_PRODUCT_FROM_DATABASE=i2c-tiny-usb interface + +usb:v0403pC632* + ID_PRODUCT_FROM_DATABASE=xu1541 c64 floppy drive interface + +usb:v0403pC633* + ID_PRODUCT_FROM_DATABASE=TinyCrypt dongle + +usb:v0403pC634* + ID_PRODUCT_FROM_DATABASE=glcd2usb interface + +usb:v0403pC7D0* + ID_PRODUCT_FROM_DATABASE=RR-CirKits LocoBuffer-USB + +usb:v0403pC8B8* + ID_PRODUCT_FROM_DATABASE=Alpermann+Velte MTD TCU + +usb:v0403pC8B9* + ID_PRODUCT_FROM_DATABASE=Alpermann+Velte MTD TCU 1HE + +usb:v0403pC8BA* + ID_PRODUCT_FROM_DATABASE=Alpermann+Velte Rubidium H1 + +usb:v0403pC8BB* + ID_PRODUCT_FROM_DATABASE=Alpermann+Velte Rubidium H3 + +usb:v0403pC8BC* + ID_PRODUCT_FROM_DATABASE=Alpermann+Velte Rubidium S1 + +usb:v0403pC8BD* + ID_PRODUCT_FROM_DATABASE=Alpermann+Velte Rubidium T1 + +usb:v0403pC8BE* + ID_PRODUCT_FROM_DATABASE=Alpermann+Velte Rubidium D1 + +usb:v0403pCC48* + ID_PRODUCT_FROM_DATABASE=Tactrix OpenPort 1.3 Mitsubishi + +usb:v0403pCC49* + ID_PRODUCT_FROM_DATABASE=Tactrix OpenPort 1.3 Subaru + +usb:v0403pCC4A* + ID_PRODUCT_FROM_DATABASE=Tactrix OpenPort 1.3 Universal + +usb:v0403pCFF8* + ID_PRODUCT_FROM_DATABASE=Distortec JTAG-lock-pick + +usb:v0403pD010* + ID_PRODUCT_FROM_DATABASE=SCS PTC-IIusb + +usb:v0403pD011* + ID_PRODUCT_FROM_DATABASE=SCS Position-Tracker/TNC + +usb:v0403pD012* + ID_PRODUCT_FROM_DATABASE=SCS DRAGON 1 + +usb:v0403pD013* + ID_PRODUCT_FROM_DATABASE=SCS DRAGON 1 + +usb:v0403pD578* + ID_PRODUCT_FROM_DATABASE=Accesio USB-COM-4SM + +usb:v0403pD6F8* + ID_PRODUCT_FROM_DATABASE=UNI Black BOX + +usb:v0403pD738* + ID_PRODUCT_FROM_DATABASE=Propox JTAGcable II + +usb:v0403pD739* + ID_PRODUCT_FROM_DATABASE=Propox ISPcable III + +usb:v0403pD9A9* + ID_PRODUCT_FROM_DATABASE=Actisense USG-1 NMEA Serial Gateway + +usb:v0403pD9AA* + ID_PRODUCT_FROM_DATABASE=Actisense NGT-1 NMEA2000 PC Interface + +usb:v0403pE0D0* + ID_PRODUCT_FROM_DATABASE=Total Phase Aardvark I2C/SPI Host Adapter + +usb:v0403pE521* + ID_PRODUCT_FROM_DATABASE=EVER Sinline XL Series UPS + +usb:v0403pE6C8* + ID_PRODUCT_FROM_DATABASE=PYRAMID Computer GmbH LCD + +usb:v0403pE700* + ID_PRODUCT_FROM_DATABASE=Elster Unicom III Optical Probe + +usb:v0403pE729* + ID_PRODUCT_FROM_DATABASE=Segway Robotic Mobility Platforms 200 + +usb:v0403pE888* + ID_PRODUCT_FROM_DATABASE=Expert ISDN Control USB + +usb:v0403pE889* + ID_PRODUCT_FROM_DATABASE=USB-RS232 OptoBridge + +usb:v0403pE88A* + ID_PRODUCT_FROM_DATABASE=Expert mouseCLOCK USB II + +usb:v0403pE88B* + ID_PRODUCT_FROM_DATABASE=Precision Clock MSF USB + +usb:v0403pE88C* + ID_PRODUCT_FROM_DATABASE=Expert mouseCLOCK USB II HBG + +usb:v0403pEA90* + ID_PRODUCT_FROM_DATABASE=Eclo 1-Wire Adapter + +usb:v0403pED71* + ID_PRODUCT_FROM_DATABASE=HAMEG HO870 Serial Port + +usb:v0403pED72* + ID_PRODUCT_FROM_DATABASE=HAMEG HO720 Serial Port + +usb:v0403pED73* + ID_PRODUCT_FROM_DATABASE=HAMEG HO730 Serial Port + +usb:v0403pED74* + ID_PRODUCT_FROM_DATABASE=HAMEG HO820 Serial Port + +usb:v0403pEF10* + ID_PRODUCT_FROM_DATABASE=FT1245BL + +usb:v0403pF070* + ID_PRODUCT_FROM_DATABASE=Serial Converter 422/485 [Vardaan VEUSB422R3] + +usb:v0403pF1A0* + ID_PRODUCT_FROM_DATABASE=Asix PRESTO Programmer + +usb:v0403pF208* + ID_PRODUCT_FROM_DATABASE=Papenmeier Braille-Display + +usb:v0403pF3C0* + ID_PRODUCT_FROM_DATABASE=4N-GALAXY Serial Converter + +usb:v0403pF608* + ID_PRODUCT_FROM_DATABASE=CTI USB-485-Mini + +usb:v0403pF60B* + ID_PRODUCT_FROM_DATABASE=CTI USB-Nano-485 + +usb:v0403pF680* + ID_PRODUCT_FROM_DATABASE=Suunto Sports Instrument + +usb:v0403pF758* + ID_PRODUCT_FROM_DATABASE=GW Instek GDS-8x0 Oscilloscope + +usb:v0403pF7C0* + ID_PRODUCT_FROM_DATABASE=ZeitControl Cardsystems TagTracer MIFARE + +usb:v0403pF850* + ID_PRODUCT_FROM_DATABASE=USB-UIRT (Universal Infrared Receiver+Transmitter) + +usb:v0403pF918* + ID_PRODUCT_FROM_DATABASE=Ant8 Logic Probe + +usb:v0403pFA00* + ID_PRODUCT_FROM_DATABASE=Matrix Orbital USB Serial + +usb:v0403pFA01* + ID_PRODUCT_FROM_DATABASE=Matrix Orbital MX2 or MX3 + +usb:v0403pFA02* + ID_PRODUCT_FROM_DATABASE=Matrix Orbital MX4 or MX5 + +usb:v0403pFA03* + ID_PRODUCT_FROM_DATABASE=Matrix Orbital VK/LK202 Family + +usb:v0403pFA04* + ID_PRODUCT_FROM_DATABASE=Matrix Orbital VK/LK204 Family + +usb:v0403pFC08* + ID_PRODUCT_FROM_DATABASE=Crystalfontz CFA-632 USB LCD + +usb:v0403pFC09* + ID_PRODUCT_FROM_DATABASE=Crystalfontz CFA-634 USB LCD + +usb:v0403pFC0B* + ID_PRODUCT_FROM_DATABASE=Crystalfontz CFA-633 USB LCD + +usb:v0403pFC0C* + ID_PRODUCT_FROM_DATABASE=Crystalfontz CFA-631 USB LCD + +usb:v0403pFC0D* + ID_PRODUCT_FROM_DATABASE=Crystalfontz CFA-635 USB LCD + +usb:v0403pFC82* + ID_PRODUCT_FROM_DATABASE=SEMC DSS-20/DSS-25 SyncStation + +usb:v0403pFD48* + ID_PRODUCT_FROM_DATABASE=ShipModul MiniPlex-4xUSB NMEA Multiplexer + +usb:v0403pFD49* + ID_PRODUCT_FROM_DATABASE=ShipModul MiniPlex-4xUSB-AIS NMEA Multiplexer + +usb:v0403pFF08* + ID_PRODUCT_FROM_DATABASE=ToolHouse LoopBack Adapter + +usb:v0403pFF18* + ID_PRODUCT_FROM_DATABASE=ScienceScope Logbook ML + +usb:v0403pFF19* + ID_PRODUCT_FROM_DATABASE=Logbook Bus + +usb:v0403pFF1A* + ID_PRODUCT_FROM_DATABASE=Logbook Bus + +usb:v0403pFF1B* + ID_PRODUCT_FROM_DATABASE=Logbook Bus + +usb:v0403pFF1C* + ID_PRODUCT_FROM_DATABASE=ScienceScope Logbook LS + +usb:v0403pFF1D* + ID_PRODUCT_FROM_DATABASE=ScienceScope Logbook HS + +usb:v0403pFF1E* + ID_PRODUCT_FROM_DATABASE=Logbook Bus + +usb:v0403pFF1F* + ID_PRODUCT_FROM_DATABASE=Logbook Bus + +usb:v0404* + ID_VENDOR_FROM_DATABASE=NCR Corp. + +usb:v0404p0202* + ID_PRODUCT_FROM_DATABASE=78XX Scanner + +usb:v0404p0203* + ID_PRODUCT_FROM_DATABASE=78XX Scanner - Embedded System + +usb:v0404p0310* + ID_PRODUCT_FROM_DATABASE=K590 Printer, Self-Service + +usb:v0404p0311* + ID_PRODUCT_FROM_DATABASE=7167 Printer, Receipt/Slip + +usb:v0404p0312* + ID_PRODUCT_FROM_DATABASE=7197 Printer Receipt + +usb:v0404p0320* + ID_PRODUCT_FROM_DATABASE=5932-USB Keyboard + +usb:v0404p0321* + ID_PRODUCT_FROM_DATABASE=5953-USB Dynakey + +usb:v0404p0322* + ID_PRODUCT_FROM_DATABASE=5932-USB Enhanced Keyboard + +usb:v0404p0323* + ID_PRODUCT_FROM_DATABASE=5932-USB Enhanced Keyboard, Flash-Recovery/Download + +usb:v0404p0324* + ID_PRODUCT_FROM_DATABASE=5953-USB Enhanced Dynakey + +usb:v0404p0325* + ID_PRODUCT_FROM_DATABASE=5953-USB Enhanced Dynakey Flash-Recovery/Download + +usb:v0404p0328* + ID_PRODUCT_FROM_DATABASE=K016: USB-MSR ISO 3-track MSR: POS Standard (See HID pages) + +usb:v0404p0329* + ID_PRODUCT_FROM_DATABASE=K018: USB-MSR JIS 2-Track MSR: POS Standard + +usb:v0404p032A* + ID_PRODUCT_FROM_DATABASE=K016: USB-MSR ISO 3-Track MSR: HID Keyboard Mode + +usb:v0404p032B* + ID_PRODUCT_FROM_DATABASE=K016/K018: USB-MSR Flash-Recovery/Download + +usb:v0405* + ID_VENDOR_FROM_DATABASE=Synopsys, Inc. + +usb:v0406* + ID_VENDOR_FROM_DATABASE=Fujitsu-ICL Computers + +usb:v0407* + ID_VENDOR_FROM_DATABASE=Fujitsu Personal Systems, Inc. + +usb:v0408* + ID_VENDOR_FROM_DATABASE=Quanta Computer, Inc. + +usb:v0408p0103* + ID_PRODUCT_FROM_DATABASE=FV TouchCam N1 (Audio) + +usb:v0408p030C* + ID_PRODUCT_FROM_DATABASE=HP Webcam + +usb:v0408p03B2* + ID_PRODUCT_FROM_DATABASE=HP Webcam + +usb:v0408p1030* + ID_PRODUCT_FROM_DATABASE=FV TouchCam N1 (Video) + +usb:v0408p3000* + ID_PRODUCT_FROM_DATABASE=Optical dual-touch panel + +usb:v0408p3001* + ID_PRODUCT_FROM_DATABASE=Optical Touch Screen + +usb:v0409* + ID_VENDOR_FROM_DATABASE=NEC Corp. + +usb:v0409p0011* + ID_PRODUCT_FROM_DATABASE=PC98 Series Layout Keyboard Mouse + +usb:v0409p0012* + ID_PRODUCT_FROM_DATABASE=ATerm IT75DSU ISDN TA + +usb:v0409p0014* + ID_PRODUCT_FROM_DATABASE=Japanese Keyboard + +usb:v0409p0019* + ID_PRODUCT_FROM_DATABASE=109 Japanese Keyboard with Bus-Powered Hub + +usb:v0409p001A* + ID_PRODUCT_FROM_DATABASE=PC98 Series Layout Keyboard with Bus-Powered Hub + +usb:v0409p0025* + ID_PRODUCT_FROM_DATABASE=Mini Keyboard with Bus-Powered Hub + +usb:v0409p0027* + ID_PRODUCT_FROM_DATABASE=MultiSync Monitor + +usb:v0409p002C* + ID_PRODUCT_FROM_DATABASE=Clik!-USB Drive + +usb:v0409p0034* + ID_PRODUCT_FROM_DATABASE=109 Japanese Keyboard with One-touch start buttons + +usb:v0409p003F* + ID_PRODUCT_FROM_DATABASE=Wireless Keyboard with One-touch start buttons + +usb:v0409p0040* + ID_PRODUCT_FROM_DATABASE=Floppy + +usb:v0409p004E* + ID_PRODUCT_FROM_DATABASE=SuperScript 1400 Series + +usb:v0409p004F* + ID_PRODUCT_FROM_DATABASE=Wireless Keyboard with One-touch start buttons + +usb:v0409p0050* + ID_PRODUCT_FROM_DATABASE=7-port hub + +usb:v0409p0058* + ID_PRODUCT_FROM_DATABASE=HighSpeed Hub + +usb:v0409p0059* + ID_PRODUCT_FROM_DATABASE=HighSpeed Hub + +usb:v0409p005A* + ID_PRODUCT_FROM_DATABASE=HighSpeed Hub + +usb:v0409p006A* + ID_PRODUCT_FROM_DATABASE=Conceptronic USB Harddisk Box + +usb:v0409p007D* + ID_PRODUCT_FROM_DATABASE=MINICUBE2 + +usb:v0409p007E* + ID_PRODUCT_FROM_DATABASE=PG-FP5 Flash Memory Programmer + +usb:v0409p0081* + ID_PRODUCT_FROM_DATABASE=SuperScript 1400 Series + +usb:v0409p0082* + ID_PRODUCT_FROM_DATABASE=SuperScript 1400 Series + +usb:v0409p0094* + ID_PRODUCT_FROM_DATABASE=Japanese Keyboard with One-touch start buttons + +usb:v0409p0095* + ID_PRODUCT_FROM_DATABASE=Japanese Keyboard + +usb:v0409p00A9* + ID_PRODUCT_FROM_DATABASE=AtermIT21L 128K Support Standard + +usb:v0409p00AA* + ID_PRODUCT_FROM_DATABASE=AtermITX72 128K Support Standard + +usb:v0409p00AB* + ID_PRODUCT_FROM_DATABASE=AtermITX62 128K Support Standard + +usb:v0409p00AC* + ID_PRODUCT_FROM_DATABASE=AtermIT42 128K Support Standard + +usb:v0409p00AE* + ID_PRODUCT_FROM_DATABASE=INSMATEV70G-MAX Standard + +usb:v0409p00AF* + ID_PRODUCT_FROM_DATABASE=AtermITX70 128K Support Standard + +usb:v0409p00B0* + ID_PRODUCT_FROM_DATABASE=AtermITX80 128K Support Standard + +usb:v0409p00B2* + ID_PRODUCT_FROM_DATABASE=AtermITX80D 128K Support Standard + +usb:v0409p00C0* + ID_PRODUCT_FROM_DATABASE=Wireless Remocon + +usb:v0409p00F7* + ID_PRODUCT_FROM_DATABASE=Smart Display PK-SD10 + +usb:v0409p011D* + ID_PRODUCT_FROM_DATABASE=e228 Mobile Phone + +usb:v0409p0203* + ID_PRODUCT_FROM_DATABASE=HID Audio Controls + +usb:v0409p021D* + ID_PRODUCT_FROM_DATABASE=Aterm WL54SU2 802.11g Wireless Adapter [Atheros AR5523] + +usb:v0409p0248* + ID_PRODUCT_FROM_DATABASE=Aterm PA-WL54GU + +usb:v0409p0249* + ID_PRODUCT_FROM_DATABASE=Aterm WL300NU-G + +usb:v0409p02B4* + ID_PRODUCT_FROM_DATABASE=Aterm WL300NU-AG + +usb:v0409p02B6* + ID_PRODUCT_FROM_DATABASE=Aterm WL300NU-GS 802.11n Wireless Adapter + +usb:v0409p0300* + ID_PRODUCT_FROM_DATABASE=LifeTouch Note + +usb:v0409p0301* + ID_PRODUCT_FROM_DATABASE=LifeTouch Note (debug mode) + +usb:v0409p55AA* + ID_PRODUCT_FROM_DATABASE=Hub + +usb:v0409p55AB* + ID_PRODUCT_FROM_DATABASE=Hub [iMac/iTouch kbd] + +usb:v0409p8010* + ID_PRODUCT_FROM_DATABASE=Intellibase Hub + +usb:v0409p8011* + ID_PRODUCT_FROM_DATABASE=Intellibase Hub + +usb:v0409pEFBE* + ID_PRODUCT_FROM_DATABASE=P!cty 900 [HP DJ] + +usb:v0409pF0BE* + ID_PRODUCT_FROM_DATABASE=P!cty 920 [HP DJ 812c] + +usb:v040A* + ID_VENDOR_FROM_DATABASE=Kodak Co. + +usb:v040Ap0001* + ID_PRODUCT_FROM_DATABASE=DVC-323 + +usb:v040Ap0002* + ID_PRODUCT_FROM_DATABASE=DVC-325 + +usb:v040Ap0100* + ID_PRODUCT_FROM_DATABASE=DC-220 + +usb:v040Ap0110* + ID_PRODUCT_FROM_DATABASE=DC-260 + +usb:v040Ap0111* + ID_PRODUCT_FROM_DATABASE=DC-265 + +usb:v040Ap0112* + ID_PRODUCT_FROM_DATABASE=DC-290 + +usb:v040Ap0120* + ID_PRODUCT_FROM_DATABASE=DC-240 + +usb:v040Ap0121* + ID_PRODUCT_FROM_DATABASE=DC-240 (PTP firmware) + +usb:v040Ap0130* + ID_PRODUCT_FROM_DATABASE=DC-280 + +usb:v040Ap0131* + ID_PRODUCT_FROM_DATABASE=DC-5000 + +usb:v040Ap0132* + ID_PRODUCT_FROM_DATABASE=DC-3400 + +usb:v040Ap0140* + ID_PRODUCT_FROM_DATABASE=DC-4800 + +usb:v040Ap0160* + ID_PRODUCT_FROM_DATABASE=DC4800 + +usb:v040Ap0170* + ID_PRODUCT_FROM_DATABASE=DX3900 + +usb:v040Ap0200* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v040Ap0300* + ID_PRODUCT_FROM_DATABASE=EZ-200 + +usb:v040Ap0400* + ID_PRODUCT_FROM_DATABASE=MC3 + +usb:v040Ap0402* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v040Ap0403* + ID_PRODUCT_FROM_DATABASE=Z7590 + +usb:v040Ap0500* + ID_PRODUCT_FROM_DATABASE=DX3500 + +usb:v040Ap0510* + ID_PRODUCT_FROM_DATABASE=DX3600 + +usb:v040Ap0525* + ID_PRODUCT_FROM_DATABASE=DX3215 + +usb:v040Ap0530* + ID_PRODUCT_FROM_DATABASE=DX3700 + +usb:v040Ap0535* + ID_PRODUCT_FROM_DATABASE=EasyShare CX4230 Camera + +usb:v040Ap0540* + ID_PRODUCT_FROM_DATABASE=LS420 + +usb:v040Ap0550* + ID_PRODUCT_FROM_DATABASE=DX4900 + +usb:v040Ap0555* + ID_PRODUCT_FROM_DATABASE=DX4330 + +usb:v040Ap0560* + ID_PRODUCT_FROM_DATABASE=CX4200 + +usb:v040Ap0565* + ID_PRODUCT_FROM_DATABASE=CX4210 + +usb:v040Ap0566* + ID_PRODUCT_FROM_DATABASE=CX4300 + +usb:v040Ap0567* + ID_PRODUCT_FROM_DATABASE=LS753 + +usb:v040Ap0568* + ID_PRODUCT_FROM_DATABASE=LS443 + +usb:v040Ap0569* + ID_PRODUCT_FROM_DATABASE=LS663 + +usb:v040Ap0570* + ID_PRODUCT_FROM_DATABASE=DX6340 + +usb:v040Ap0571* + ID_PRODUCT_FROM_DATABASE=CX6330 + +usb:v040Ap0572* + ID_PRODUCT_FROM_DATABASE=DX6440 + +usb:v040Ap0573* + ID_PRODUCT_FROM_DATABASE=CX6230 + +usb:v040Ap0574* + ID_PRODUCT_FROM_DATABASE=CX6200 + +usb:v040Ap0575* + ID_PRODUCT_FROM_DATABASE=DX6490 + +usb:v040Ap0576* + ID_PRODUCT_FROM_DATABASE=DX4530 + +usb:v040Ap0577* + ID_PRODUCT_FROM_DATABASE=DX7630 + +usb:v040Ap0578* + ID_PRODUCT_FROM_DATABASE=CX7300/CX7310 + +usb:v040Ap0579* + ID_PRODUCT_FROM_DATABASE=CX7220 + +usb:v040Ap057A* + ID_PRODUCT_FROM_DATABASE=CX7330 + +usb:v040Ap057B* + ID_PRODUCT_FROM_DATABASE=CX7430 + +usb:v040Ap057C* + ID_PRODUCT_FROM_DATABASE=CX7530 + +usb:v040Ap057D* + ID_PRODUCT_FROM_DATABASE=DX7440 + +usb:v040Ap057E* + ID_PRODUCT_FROM_DATABASE=C300 + +usb:v040Ap057F* + ID_PRODUCT_FROM_DATABASE=DX7590 + +usb:v040Ap0580* + ID_PRODUCT_FROM_DATABASE=Z730 + +usb:v040Ap0581* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v040Ap0582* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v040Ap0583* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v040Ap0584* + ID_PRODUCT_FROM_DATABASE=CX6445 + +usb:v040Ap0585* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v040Ap0586* + ID_PRODUCT_FROM_DATABASE=CX7525 + +usb:v040Ap0587* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v040Ap0588* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v040Ap0589* + ID_PRODUCT_FROM_DATABASE=EasyShare C360 + +usb:v040Ap058A* + ID_PRODUCT_FROM_DATABASE=C310 + +usb:v040Ap058B* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v040Ap058C* + ID_PRODUCT_FROM_DATABASE=C330 + +usb:v040Ap058D* + ID_PRODUCT_FROM_DATABASE=C340 + +usb:v040Ap058E* + ID_PRODUCT_FROM_DATABASE=V530 + +usb:v040Ap058F* + ID_PRODUCT_FROM_DATABASE=V550 + +usb:v040Ap0590* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v040Ap0591* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v040Ap0592* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v040Ap0593* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v040Ap0594* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v040Ap0595* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v040Ap0596* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v040Ap0597* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v040Ap0598* + ID_PRODUCT_FROM_DATABASE=EASYSHARE M1033 digital camera + +usb:v040Ap0599* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v040Ap059A* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v040Ap059B* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v040Ap059C* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v040Ap059D* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v040Ap059E* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v040Ap059F* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v040Ap05A0* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v040Ap05A1* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v040Ap05A2* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v040Ap05A3* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v040Ap05A4* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v040Ap05A5* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v040Ap05A6* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v040Ap05A7* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v040Ap05A8* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v040Ap05A9* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v040Ap05AA* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v040Ap05AB* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v040Ap05AC* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v040Ap05AD* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v040Ap05AE* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v040Ap05AF* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v040Ap05B0* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v040Ap05B1* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v040Ap05B2* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v040Ap05B3* + ID_PRODUCT_FROM_DATABASE=EasyShare Z710 Camera + +usb:v040Ap05B4* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v040Ap05B5* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v040Ap05B6* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v040Ap05B7* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v040Ap05B8* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v040Ap05B9* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v040Ap05BA* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v040Ap05BB* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v040Ap05BC* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v040Ap05BD* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v040Ap05BE* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v040Ap05BF* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v040Ap05C0* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v040Ap05C1* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v040Ap05C2* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v040Ap05C3* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v040Ap05C4* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v040Ap05C5* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v040Ap05C8* + ID_PRODUCT_FROM_DATABASE=EASYSHARE Z1485 IS Digital Camera + +usb:v040Ap05D3* + ID_PRODUCT_FROM_DATABASE=EasyShare M320 Camera + +usb:v040Ap05D4* + ID_PRODUCT_FROM_DATABASE=EasyShare C180 Digital Camera + +usb:v040Ap1001* + ID_PRODUCT_FROM_DATABASE=EasyShare SV811 Digital Picture Frame + +usb:v040Ap4000* + ID_PRODUCT_FROM_DATABASE=InkJet Color Printer + +usb:v040Ap4056* + ID_PRODUCT_FROM_DATABASE=ESP 7200 Series AiO + +usb:v040Ap4109* + ID_PRODUCT_FROM_DATABASE=EasyShare Printer Dock Series 3 + +usb:v040Ap410D* + ID_PRODUCT_FROM_DATABASE=EasyShare G600 Printer Dock + +usb:v040Ap5010* + ID_PRODUCT_FROM_DATABASE=Wireless Adapter + +usb:v040Ap5012* + ID_PRODUCT_FROM_DATABASE=DBT-220 Bluetooth Adapter + +usb:v040Ap6001* + ID_PRODUCT_FROM_DATABASE=i30 + +usb:v040Ap6002* + ID_PRODUCT_FROM_DATABASE=i40 + +usb:v040Ap6003* + ID_PRODUCT_FROM_DATABASE=i50 + +usb:v040Ap6004* + ID_PRODUCT_FROM_DATABASE=i60 + +usb:v040Ap6005* + ID_PRODUCT_FROM_DATABASE=i80 + +usb:v040B* + ID_VENDOR_FROM_DATABASE=Weltrend Semiconductor + +usb:v040Bp6510* + ID_PRODUCT_FROM_DATABASE=Weltrend Bar Code Reader + +usb:v040Bp6520* + ID_PRODUCT_FROM_DATABASE=XBOX Xploder + +usb:v040Bp6533* + ID_PRODUCT_FROM_DATABASE=Speed-Link Competition Pro + +usb:v040Bp6543* + ID_PRODUCT_FROM_DATABASE=Manhattan Magnetic Card Strip Reader + +usb:v040C* + ID_VENDOR_FROM_DATABASE=VTech Computers, Ltd + +usb:v040D* + ID_VENDOR_FROM_DATABASE=VIA Technologies, Inc. + +usb:v040Dp3184* + ID_PRODUCT_FROM_DATABASE=VNT VT6656 USB-802.11 Wireless LAN Adapter + +usb:v040Dp6205* + ID_PRODUCT_FROM_DATABASE=USB 2.0 Card Reader + +usb:v040E* + ID_VENDOR_FROM_DATABASE=MCCI + +usb:v040F* + ID_VENDOR_FROM_DATABASE=Echo Speech Corp. + +usb:v0411* + ID_VENDOR_FROM_DATABASE=BUFFALO INC. (formerly MelCo., Inc.) + +usb:v0411p0001* + ID_PRODUCT_FROM_DATABASE=LUA-TX Ethernet [pegasus] + +usb:v0411p0005* + ID_PRODUCT_FROM_DATABASE=LUA-TX Ethernet + +usb:v0411p0006* + ID_PRODUCT_FROM_DATABASE=WLI-USB-L11 Wireless LAN Adapter + +usb:v0411p0009* + ID_PRODUCT_FROM_DATABASE=LUA2-TX Ethernet + +usb:v0411p000B* + ID_PRODUCT_FROM_DATABASE=WLI-USB-L11G-WR Wireless LAN Adapter + +usb:v0411p000D* + ID_PRODUCT_FROM_DATABASE=WLI-USB-L11G Wireless LAN Adapter + +usb:v0411p0012* + ID_PRODUCT_FROM_DATABASE=LUA-KTX Ethernet + +usb:v0411p0013* + ID_PRODUCT_FROM_DATABASE=USB2-IDE Adapter + +usb:v0411p0016* + ID_PRODUCT_FROM_DATABASE=WLI-USB-S11 802.11b Adapter + +usb:v0411p0018* + ID_PRODUCT_FROM_DATABASE=USB2-IDE Adapter + +usb:v0411p001C* + ID_PRODUCT_FROM_DATABASE=USB-IDE Bridge: DUB-PxxG + +usb:v0411p0027* + ID_PRODUCT_FROM_DATABASE=WLI-USB-KS11G 802.11b Adapter + +usb:v0411p002A* + ID_PRODUCT_FROM_DATABASE=SMSC USB97C202 "HD-HB300V2-EU" + +usb:v0411p003D* + ID_PRODUCT_FROM_DATABASE=LUA-U2-KTX Ethernet + +usb:v0411p0044* + ID_PRODUCT_FROM_DATABASE=WLI-USB-KB11 Wireless LAN Adapter + +usb:v0411p004B* + ID_PRODUCT_FROM_DATABASE=WLI-USB-G54 802.11g Adapter [Broadcom 4320 USB] + +usb:v0411p004D* + ID_PRODUCT_FROM_DATABASE=WLI-USB-B11 Wireless LAN Adapter + +usb:v0411p0050* + ID_PRODUCT_FROM_DATABASE=WLI2-USB2-G54 Wireless LAN Adapter + +usb:v0411p005E* + ID_PRODUCT_FROM_DATABASE=WLI-U2-KG54-YB WLAN + +usb:v0411p0065* + ID_PRODUCT_FROM_DATABASE=Python2 WDM Encoder + +usb:v0411p0066* + ID_PRODUCT_FROM_DATABASE=WLI-U2-KG54 WLAN + +usb:v0411p0067* + ID_PRODUCT_FROM_DATABASE=WLI-U2-KG54-AI WLAN + +usb:v0411p006E* + ID_PRODUCT_FROM_DATABASE=LUA-U2-GT 10/100/1000 Ethernet Adapter + +usb:v0411p0089* + ID_PRODUCT_FROM_DATABASE=RUF-C/U2 Flash Drive + +usb:v0411p008B* + ID_PRODUCT_FROM_DATABASE=Nintendo Wi-Fi + +usb:v0411p0091* + ID_PRODUCT_FROM_DATABASE=WLI-U2-KAMG54 Wireless LAN Adapter + +usb:v0411p0092* + ID_PRODUCT_FROM_DATABASE=WLI-U2-KAMG54 Bootloader + +usb:v0411p0097* + ID_PRODUCT_FROM_DATABASE=WLI-U2-KG54-BB + +usb:v0411p00A9* + ID_PRODUCT_FROM_DATABASE=WLI-U2-AMG54HP Wireless LAN Adapter + +usb:v0411p00AA* + ID_PRODUCT_FROM_DATABASE=WLI-U2-AMG54HP Bootloader + +usb:v0411p00B3* + ID_PRODUCT_FROM_DATABASE=PC-OP-RS1 RemoteStation + +usb:v0411p00BC* + ID_PRODUCT_FROM_DATABASE=WLI-U2-KG125S 802.11g Adapter [Broadcom 4320 USB] + +usb:v0411p00CA* + ID_PRODUCT_FROM_DATABASE=802.11n Network Adapter + +usb:v0411p00CB* + ID_PRODUCT_FROM_DATABASE=WLI-U2-G300N 802.11n Adapter + +usb:v0411p00D8* + ID_PRODUCT_FROM_DATABASE=WLI-U2-SG54HP + +usb:v0411p00D9* + ID_PRODUCT_FROM_DATABASE=WLI-U2-G54HP + +usb:v0411p00DA* + ID_PRODUCT_FROM_DATABASE=WLI-U2-KG54L 802.11bg [ZyDAS ZD1211B] + +usb:v0411p00DB* + ID_PRODUCT_FROM_DATABASE=External Hard Drive HD-PF32OU2 [Buffalo Ministation] + +usb:v0411p00E8* + ID_PRODUCT_FROM_DATABASE=WLI-UC-G300N Wireless LAN Adapter [Ralink RT2870] + +usb:v0411p012E* + ID_PRODUCT_FROM_DATABASE=WLI-UC-AG300N Wireless LAN Adapter + +usb:v0411p0148* + ID_PRODUCT_FROM_DATABASE=WLI-UC-G300HP Wireless LAN Adapter + +usb:v0411p0150* + ID_PRODUCT_FROM_DATABASE=WLP-UC-AG300 Wireless LAN Adapter + +usb:v0411p0157* + ID_PRODUCT_FROM_DATABASE=External Hard Drive HD-PEU2 + +usb:v0411p0158* + ID_PRODUCT_FROM_DATABASE=WLI-UC-GNHP Wireless LAN Adapter + +usb:v0411p015D* + ID_PRODUCT_FROM_DATABASE=WLI-UC-GN Wireless LAN Adapter [Ralink RT3070] + +usb:v0411p016F* + ID_PRODUCT_FROM_DATABASE=WLI-UC-G301N Wireless LAN Adapter [Ralink RT3072] + +usb:v0411p017F* + ID_PRODUCT_FROM_DATABASE=Sony UWA-BR100 802.11abgn Wireless Adapter [Atheros AR7010+AR9280] + +usb:v0411p019E* + ID_PRODUCT_FROM_DATABASE=WLI-UC-GNP Wireless LAN Adapter + +usb:v0411p01A1* + ID_PRODUCT_FROM_DATABASE=MiniStation Metro + +usb:v0411p01A2* + ID_PRODUCT_FROM_DATABASE=WLI-UC-GNM Wireless LAN Adapter [Ralink RT8070] + +usb:v0411p01DC* + ID_PRODUCT_FROM_DATABASE=Ultra-Slim Portable DVD Writer (DVSM-PC58U2V) + +usb:v0411p01DE* + ID_PRODUCT_FROM_DATABASE=External Hard Drive HD-PCTU3 [Buffalo MiniStation] + +usb:v0411p01EE* + ID_PRODUCT_FROM_DATABASE=WLI-UC-GNM2 Wireless LAN Adapter [Ralink RT3070] + +usb:v0411p01F1* + ID_PRODUCT_FROM_DATABASE=SATA Adapter [HD-LBU3] + +usb:v0411p01FD* + ID_PRODUCT_FROM_DATABASE=WLI-UC-G450 Wireless LAN Adapter + +usb:v0412* + ID_VENDOR_FROM_DATABASE=Award Software International + +usb:v0413* + ID_VENDOR_FROM_DATABASE=Leadtek Research, Inc. + +usb:v0413p1310* + ID_PRODUCT_FROM_DATABASE=WinFast TV - NTSC + FM + +usb:v0413p1311* + ID_PRODUCT_FROM_DATABASE=WinFast TV - NTSC + MTS + FM + +usb:v0413p1312* + ID_PRODUCT_FROM_DATABASE=WinFast TV - PAL BG + FM + +usb:v0413p1313* + ID_PRODUCT_FROM_DATABASE=WinFast TV - PAL BG+TXT + FM + +usb:v0413p1314* + ID_PRODUCT_FROM_DATABASE=WinFast TV Audio - PHP PAL I + +usb:v0413p1315* + ID_PRODUCT_FROM_DATABASE=WinFast TV Audio - PHP PAL I+TXT + +usb:v0413p1316* + ID_PRODUCT_FROM_DATABASE=WinFast TV Audio - PHP PAL DK + +usb:v0413p1317* + ID_PRODUCT_FROM_DATABASE=WinFast TV Audio - PHP PAL DK+TXT + +usb:v0413p1318* + ID_PRODUCT_FROM_DATABASE=WinFast TV - PAL I/DK + FM + +usb:v0413p1319* + ID_PRODUCT_FROM_DATABASE=WinFast TV - PAL N + FM + +usb:v0413p131A* + ID_PRODUCT_FROM_DATABASE=WinFast TV Audio - PHP SECAM LL + +usb:v0413p131B* + ID_PRODUCT_FROM_DATABASE=WinFast TV Audio - PHP SECAM LL+TXT + +usb:v0413p131C* + ID_PRODUCT_FROM_DATABASE=WinFast TV Audio - PHP SECAM DK + +usb:v0413p131D* + ID_PRODUCT_FROM_DATABASE=WinFast TV - SECAM DK + TXT + FM + +usb:v0413p131E* + ID_PRODUCT_FROM_DATABASE=WinFast TV - NTSC Japan + FM + +usb:v0413p1320* + ID_PRODUCT_FROM_DATABASE=WinFast TV - NTSC + +usb:v0413p1321* + ID_PRODUCT_FROM_DATABASE=WinFast TV - NTSC + MTS + +usb:v0413p1322* + ID_PRODUCT_FROM_DATABASE=WinFast TV - PAL BG + +usb:v0413p1323* + ID_PRODUCT_FROM_DATABASE=WinFast TV - PAL BG+TXT + +usb:v0413p1324* + ID_PRODUCT_FROM_DATABASE=WinFast TV Audio - PHP PAL I + +usb:v0413p1325* + ID_PRODUCT_FROM_DATABASE=WinFast TV Audio - PHP PAL I+TXT + +usb:v0413p1326* + ID_PRODUCT_FROM_DATABASE=WinFast TV Audio - PHP PAL DK + +usb:v0413p1327* + ID_PRODUCT_FROM_DATABASE=WinFast TV Audio - PHP PAL DK+TXT + +usb:v0413p1328* + ID_PRODUCT_FROM_DATABASE=WinFast TV - PAL I/DK + +usb:v0413p1329* + ID_PRODUCT_FROM_DATABASE=WinFast TV - PAL N + +usb:v0413p132A* + ID_PRODUCT_FROM_DATABASE=WinFast TV Audio - PHP SECAM LL + +usb:v0413p132B* + ID_PRODUCT_FROM_DATABASE=WinFast TV Audio - PHP SECAM LL+TXT + +usb:v0413p132C* + ID_PRODUCT_FROM_DATABASE=WinFast TV Audio - PHP SECAM DK + +usb:v0413p132D* + ID_PRODUCT_FROM_DATABASE=WinFast TV - SECAM DK + TXT + +usb:v0413p132E* + ID_PRODUCT_FROM_DATABASE=WinFast TV - NTSC Japan + +usb:v0413p6023* + ID_PRODUCT_FROM_DATABASE=EMP Audio Device + +usb:v0413p6024* + ID_PRODUCT_FROM_DATABASE=WinFast PalmTop/Novo TV Video + +usb:v0413p6025* + ID_PRODUCT_FROM_DATABASE=WinFast DTV Dongle (cold state) + +usb:v0413p6026* + ID_PRODUCT_FROM_DATABASE=WinFast DTV Dongle (warm state) + +usb:v0413p6029* + ID_PRODUCT_FROM_DATABASE=WinFast DTV Dongle Gold + +usb:v0413p6125* + ID_PRODUCT_FROM_DATABASE=WinFast DTV Dongle + +usb:v0413p6126* + ID_PRODUCT_FROM_DATABASE=WinFast DTV Dongle BDA Driver + +usb:v0413p6A03* + ID_PRODUCT_FROM_DATABASE=RTL2832 [WinFast DTV Dongle Mini] + +usb:v0413p6F00* + ID_PRODUCT_FROM_DATABASE=WinFast DTV Dongle (STK7700P based) + +usb:v0414* + ID_VENDOR_FROM_DATABASE=Giga-Byte Technology Co., Ltd + +usb:v0416* + ID_VENDOR_FROM_DATABASE=Winbond Electronics Corp. + +usb:v0416p0035* + ID_PRODUCT_FROM_DATABASE=W89C35 802.11bg WLAN Adapter + +usb:v0416p0101* + ID_PRODUCT_FROM_DATABASE=Hub + +usb:v0416p0961* + ID_PRODUCT_FROM_DATABASE=AVL Flash Card Reader + +usb:v0416p3810* + ID_PRODUCT_FROM_DATABASE=Smart Card Controller + +usb:v0416p3811* + ID_PRODUCT_FROM_DATABASE=Generic Controller - Single interface + +usb:v0416p3812* + ID_PRODUCT_FROM_DATABASE=Smart Card Controller_2Interface + +usb:v0416p3813* + ID_PRODUCT_FROM_DATABASE=Panel Display + +usb:v0416p5518* + ID_PRODUCT_FROM_DATABASE=4-Port Hub + +usb:v0416p551A* + ID_PRODUCT_FROM_DATABASE=PC Sync Keypad + +usb:v0416p551B* + ID_PRODUCT_FROM_DATABASE=PC Async Keypad + +usb:v0416p551C* + ID_PRODUCT_FROM_DATABASE=Sync Tenkey + +usb:v0416p551D* + ID_PRODUCT_FROM_DATABASE=Async Tenkey + +usb:v0416p551E* + ID_PRODUCT_FROM_DATABASE=Keyboard + +usb:v0416p551F* + ID_PRODUCT_FROM_DATABASE=Keyboard w/ Sys and Media + +usb:v0416p5521* + ID_PRODUCT_FROM_DATABASE=Keyboard + +usb:v0416p6481* + ID_PRODUCT_FROM_DATABASE=16-bit Scanner + +usb:v0416p7721* + ID_PRODUCT_FROM_DATABASE=Memory Stick Reader/Writer + +usb:v0416p7722* + ID_PRODUCT_FROM_DATABASE=Memory Stick Reader/Writer + +usb:v0416p7723* + ID_PRODUCT_FROM_DATABASE=SD Card Reader + +usb:v0417* + ID_VENDOR_FROM_DATABASE=Symbios Logic + +usb:v0418* + ID_VENDOR_FROM_DATABASE=AST Research + +usb:v0419* + ID_VENDOR_FROM_DATABASE=Samsung Info. Systems America, Inc. + +usb:v0419p0001* + ID_PRODUCT_FROM_DATABASE=IrDA Remote Controller / Creative Cordless Mouse + +usb:v0419p0600* + ID_PRODUCT_FROM_DATABASE=Desktop Wireless 6000 + +usb:v0419p3001* + ID_PRODUCT_FROM_DATABASE=Xerox P1202 Laser Printer + +usb:v0419p3003* + ID_PRODUCT_FROM_DATABASE=Olivetti PG L12L + +usb:v0419p3201* + ID_PRODUCT_FROM_DATABASE=Docuprint P8ex + +usb:v0419p3404* + ID_PRODUCT_FROM_DATABASE=SCX-5x12 series + +usb:v0419p3406* + ID_PRODUCT_FROM_DATABASE=MFP 830 series + +usb:v0419p3407* + ID_PRODUCT_FROM_DATABASE=ML-912 + +usb:v0419p3601* + ID_PRODUCT_FROM_DATABASE=InkJet Color Printer + +usb:v0419p3602* + ID_PRODUCT_FROM_DATABASE=InkJet Color Printer + +usb:v0419p4602* + ID_PRODUCT_FROM_DATABASE=Remote NDIS Network Device + +usb:v0419p8001* + ID_PRODUCT_FROM_DATABASE=Hub + +usb:v0419p8002* + ID_PRODUCT_FROM_DATABASE=SyncMaster HID Monitor Control + +usb:v0419pAA03* + ID_PRODUCT_FROM_DATABASE=SDAS-3 MP3 Player + +usb:v041A* + ID_VENDOR_FROM_DATABASE=Phoenix Technologies, Ltd + +usb:v041B* + ID_VENDOR_FROM_DATABASE=d'TV + +usb:v041D* + ID_VENDOR_FROM_DATABASE=S3, Inc. + +usb:v041E* + ID_VENDOR_FROM_DATABASE=Creative Technology, Ltd + +usb:v041Ep1002* + ID_PRODUCT_FROM_DATABASE=Nomad II + +usb:v041Ep1003* + ID_PRODUCT_FROM_DATABASE=Blaster GamePad Cobra + +usb:v041Ep1050* + ID_PRODUCT_FROM_DATABASE=GamePad Cobra + +usb:v041Ep1053* + ID_PRODUCT_FROM_DATABASE=Mouse Gamer HD7600L + +usb:v041Ep200C* + ID_PRODUCT_FROM_DATABASE=MuVo V100 + +usb:v041Ep2020* + ID_PRODUCT_FROM_DATABASE=Zen X-Fi 2 + +usb:v041Ep2029* + ID_PRODUCT_FROM_DATABASE=ZiiO + +usb:v041Ep2801* + ID_PRODUCT_FROM_DATABASE=Prodikeys PC-MIDI multifunction keyboard + +usb:v041Ep3000* + ID_PRODUCT_FROM_DATABASE=SoundBlaster Extigy + +usb:v041Ep3002* + ID_PRODUCT_FROM_DATABASE=SB External Composite Device + +usb:v041Ep3010* + ID_PRODUCT_FROM_DATABASE=SoundBlaster MP3+ + +usb:v041Ep3014* + ID_PRODUCT_FROM_DATABASE=SB External Composite Device + +usb:v041Ep3015* + ID_PRODUCT_FROM_DATABASE=Sound Blaster Digital Music LX + +usb:v041Ep3020* + ID_PRODUCT_FROM_DATABASE=SoundBlaster Audigy 2 NX + +usb:v041Ep3030* + ID_PRODUCT_FROM_DATABASE=SB External Composite Device + +usb:v041Ep3040* + ID_PRODUCT_FROM_DATABASE=SoundBlaster Live! 24-bit External SB0490 + +usb:v041Ep3060* + ID_PRODUCT_FROM_DATABASE=Sound Blaster Audigy 2 ZS External + +usb:v041Ep3061* + ID_PRODUCT_FROM_DATABASE=SoundBlaster Audigy 2 ZS Video Editor + +usb:v041Ep3090* + ID_PRODUCT_FROM_DATABASE=Sound Blaster Digital Music SX + +usb:v041Ep30D3* + ID_PRODUCT_FROM_DATABASE=Sound Blaster Play! + +usb:v041Ep3121* + ID_PRODUCT_FROM_DATABASE=WoW tap chat + +usb:v041Ep3F00* + ID_PRODUCT_FROM_DATABASE=E-Mu Xboard 25 MIDI Controller + +usb:v041Ep3F02* + ID_PRODUCT_FROM_DATABASE=E-Mu 0202 + +usb:v041Ep3F04* + ID_PRODUCT_FROM_DATABASE=E-Mu 0404 + +usb:v041Ep3F07* + ID_PRODUCT_FROM_DATABASE=E-Mu Xmidi 1x1 + +usb:v041Ep4003* + ID_PRODUCT_FROM_DATABASE=VideoBlaster Webcam Go Plus [W9967CF] + +usb:v041Ep4004* + ID_PRODUCT_FROM_DATABASE=Nomad II MG + +usb:v041Ep4005* + ID_PRODUCT_FROM_DATABASE=Webcam Blaster Go ES + +usb:v041Ep4007* + ID_PRODUCT_FROM_DATABASE=Go Mini + +usb:v041Ep400A* + ID_PRODUCT_FROM_DATABASE=PC-Cam 300 + +usb:v041Ep400B* + ID_PRODUCT_FROM_DATABASE=PC-Cam 600 + +usb:v041Ep400C* + ID_PRODUCT_FROM_DATABASE=Webcam 5 [pwc] + +usb:v041Ep400D* + ID_PRODUCT_FROM_DATABASE=Webcam PD1001 + +usb:v041Ep400F* + ID_PRODUCT_FROM_DATABASE=PC-CAM 550 (Composite) + +usb:v041Ep4011* + ID_PRODUCT_FROM_DATABASE=Webcam PRO eX + +usb:v041Ep4012* + ID_PRODUCT_FROM_DATABASE=PC-CAM350 + +usb:v041Ep4013* + ID_PRODUCT_FROM_DATABASE=PC-Cam 750 + +usb:v041Ep4015* + ID_PRODUCT_FROM_DATABASE=CardCam Value + +usb:v041Ep4016* + ID_PRODUCT_FROM_DATABASE=CardCam + +usb:v041Ep4017* + ID_PRODUCT_FROM_DATABASE=Webcam Mobile [PD1090] + +usb:v041Ep4018* + ID_PRODUCT_FROM_DATABASE=Webcam Vista [PD1100] + +usb:v041Ep4019* + ID_PRODUCT_FROM_DATABASE=Audio Device + +usb:v041Ep401A* + ID_PRODUCT_FROM_DATABASE=Webcam Vista [PD1100] + +usb:v041Ep401C* + ID_PRODUCT_FROM_DATABASE=Webcam NX [PD1110] + +usb:v041Ep401D* + ID_PRODUCT_FROM_DATABASE=Webcam NX Ultra + +usb:v041Ep401E* + ID_PRODUCT_FROM_DATABASE=Webcam NX Pro + +usb:v041Ep401F* + ID_PRODUCT_FROM_DATABASE=Webcam Notebook [PD1171] + +usb:v041Ep4020* + ID_PRODUCT_FROM_DATABASE=Webcam NX + +usb:v041Ep4021* + ID_PRODUCT_FROM_DATABASE=Webcam NX Ultra + +usb:v041Ep4022* + ID_PRODUCT_FROM_DATABASE=Webcam NX Pro + +usb:v041Ep4028* + ID_PRODUCT_FROM_DATABASE=Vista Plus cam [VF0090] + +usb:v041Ep4029* + ID_PRODUCT_FROM_DATABASE=Webcam Live! + +usb:v041Ep402F* + ID_PRODUCT_FROM_DATABASE=DC-CAM 3000Z + +usb:v041Ep4034* + ID_PRODUCT_FROM_DATABASE=Webcam Instant + +usb:v041Ep4035* + ID_PRODUCT_FROM_DATABASE=Webcam Instant + +usb:v041Ep4036* + ID_PRODUCT_FROM_DATABASE=Webcam Live!/Live! Pro + +usb:v041Ep4037* + ID_PRODUCT_FROM_DATABASE=Webcam Live! + +usb:v041Ep4038* + ID_PRODUCT_FROM_DATABASE=ORITE CCD Webcam [PC370R] + +usb:v041Ep4039* + ID_PRODUCT_FROM_DATABASE=Webcam Live! Effects + +usb:v041Ep403A* + ID_PRODUCT_FROM_DATABASE=Webcam NX Pro 2 + +usb:v041Ep403B* + ID_PRODUCT_FROM_DATABASE=Creative Webcam Vista [VF0010] + +usb:v041Ep403C* + ID_PRODUCT_FROM_DATABASE=Webcam Live! Ultra + +usb:v041Ep403D* + ID_PRODUCT_FROM_DATABASE=Webcam Notebook Ultra + +usb:v041Ep403E* + ID_PRODUCT_FROM_DATABASE=Webcam Vista Plus + +usb:v041Ep4041* + ID_PRODUCT_FROM_DATABASE=Webcam Live! Motion + +usb:v041Ep4043* + ID_PRODUCT_FROM_DATABASE=Vibra Plus Webcam + +usb:v041Ep4045* + ID_PRODUCT_FROM_DATABASE=Live! Cam Voice + +usb:v041Ep4049* + ID_PRODUCT_FROM_DATABASE=Live! Cam Voice + +usb:v041Ep4051* + ID_PRODUCT_FROM_DATABASE=Live! Cam Notebook Pro [VF0250] + +usb:v041Ep4052* + ID_PRODUCT_FROM_DATABASE=Live! Cam Vista IM + +usb:v041Ep4053* + ID_PRODUCT_FROM_DATABASE=Live! Cam Video IM + +usb:v041Ep4054* + ID_PRODUCT_FROM_DATABASE=Live! Cam Video IM + +usb:v041Ep4055* + ID_PRODUCT_FROM_DATABASE=Live! Cam Video IM Pro + +usb:v041Ep4056* + ID_PRODUCT_FROM_DATABASE=Live! Cam Video IM Pro + +usb:v041Ep4057* + ID_PRODUCT_FROM_DATABASE=Live! Cam Optia + +usb:v041Ep4058* + ID_PRODUCT_FROM_DATABASE=Live! Cam Optia AF + +usb:v041Ep4061* + ID_PRODUCT_FROM_DATABASE=Live! Cam Notebook Pro [VF0400] + +usb:v041Ep4063* + ID_PRODUCT_FROM_DATABASE=Live! Cam Video IM Pro + +usb:v041Ep4068* + ID_PRODUCT_FROM_DATABASE=Live! Cam Notebook [VF0470] + +usb:v041Ep406C* + ID_PRODUCT_FROM_DATABASE=Live! Cam Sync [VF0520] + +usb:v041Ep4083* + ID_PRODUCT_FROM_DATABASE=Live! Cam Socialize [VF0640] + +usb:v041Ep4087* + ID_PRODUCT_FROM_DATABASE=Live! Cam Socialize HD 1080 [VF0680] + +usb:v041Ep4088* + ID_PRODUCT_FROM_DATABASE=Live! Cam Chat HD [VF0700] + +usb:v041Ep4100* + ID_PRODUCT_FROM_DATABASE=Nomad Jukebox 2 + +usb:v041Ep4101* + ID_PRODUCT_FROM_DATABASE=Nomad Jukebox 3 + +usb:v041Ep4102* + ID_PRODUCT_FROM_DATABASE=NOMAD MuVo^2 + +usb:v041Ep4106* + ID_PRODUCT_FROM_DATABASE=Nomad MuVo + +usb:v041Ep4107* + ID_PRODUCT_FROM_DATABASE=NOMAD MuVo + +usb:v041Ep4108* + ID_PRODUCT_FROM_DATABASE=Nomad Jukebox Zen + +usb:v041Ep4109* + ID_PRODUCT_FROM_DATABASE=Nomad Jukebox Zen NX + +usb:v041Ep410B* + ID_PRODUCT_FROM_DATABASE=Nomad Jukebox Zen USB 2.0 + +usb:v041Ep410C* + ID_PRODUCT_FROM_DATABASE=Nomad MuVo NX + +usb:v041Ep410F* + ID_PRODUCT_FROM_DATABASE=NOMAD MuVo^2 (Flash) + +usb:v041Ep4110* + ID_PRODUCT_FROM_DATABASE=Nomad Jukebox Zen Xtra + +usb:v041Ep4111* + ID_PRODUCT_FROM_DATABASE=Dell Digital Jukebox + +usb:v041Ep4116* + ID_PRODUCT_FROM_DATABASE=MuVo^2 + +usb:v041Ep4117* + ID_PRODUCT_FROM_DATABASE=Nomad MuVo TX + +usb:v041Ep411B* + ID_PRODUCT_FROM_DATABASE=Zen Touch + +usb:v041Ep411C* + ID_PRODUCT_FROM_DATABASE=Nomad MuVo USB 2.0 + +usb:v041Ep411D* + ID_PRODUCT_FROM_DATABASE=Zen + +usb:v041Ep411E* + ID_PRODUCT_FROM_DATABASE=Zen Micro + +usb:v041Ep4120* + ID_PRODUCT_FROM_DATABASE=Nomad MuVo TX FM + +usb:v041Ep4123* + ID_PRODUCT_FROM_DATABASE=Zen Portable Media Center + +usb:v041Ep4124* + ID_PRODUCT_FROM_DATABASE=MuVo^2 FM (uHDD) + +usb:v041Ep4126* + ID_PRODUCT_FROM_DATABASE=Dell DJ (2nd gen) + +usb:v041Ep4127* + ID_PRODUCT_FROM_DATABASE=Dell DJ + +usb:v041Ep4128* + ID_PRODUCT_FROM_DATABASE=NOMAD Jukebox Zen Xtra (mtp) + +usb:v041Ep412B* + ID_PRODUCT_FROM_DATABASE=MuVo N200 with FM radio + +usb:v041Ep412F* + ID_PRODUCT_FROM_DATABASE=Dell Digital Jukebox 2.Gen + +usb:v041Ep4130* + ID_PRODUCT_FROM_DATABASE=Zen Micro (mtp) + +usb:v041Ep4131* + ID_PRODUCT_FROM_DATABASE=Zen Touch (mtp) + +usb:v041Ep4133* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v041Ep4134* + ID_PRODUCT_FROM_DATABASE=Zen Neeon + +usb:v041Ep4136* + ID_PRODUCT_FROM_DATABASE=Zen Sleek + +usb:v041Ep4137* + ID_PRODUCT_FROM_DATABASE=Zen Sleek (mtp) + +usb:v041Ep4139* + ID_PRODUCT_FROM_DATABASE=Zen Nano Plus + +usb:v041Ep413C* + ID_PRODUCT_FROM_DATABASE=Zen MicroPhoto + +usb:v041Ep4150* + ID_PRODUCT_FROM_DATABASE=Zen V (MTP) + +usb:v041Ep4151* + ID_PRODUCT_FROM_DATABASE=Zen Vision:M (mtp) + +usb:v041Ep4152* + ID_PRODUCT_FROM_DATABASE=Zen V Plus + +usb:v041Ep4153* + ID_PRODUCT_FROM_DATABASE=Zen Vision W + +usb:v041Ep4154* + ID_PRODUCT_FROM_DATABASE=Zen Stone + +usb:v041Ep4155* + ID_PRODUCT_FROM_DATABASE=Zen Stone plus + +usb:v041Ep4157* + ID_PRODUCT_FROM_DATABASE=Zen (MTP) + +usb:v041Ep500F* + ID_PRODUCT_FROM_DATABASE=Broadband Blaster 8012U-V + +usb:v041Ep5015* + ID_PRODUCT_FROM_DATABASE=TECOM Bluetooth Device + +usb:v041EpFFFF* + ID_PRODUCT_FROM_DATABASE=Webcam Live! Ultra + +usb:v041F* + ID_VENDOR_FROM_DATABASE=LCS Telegraphics + +usb:v0420* + ID_VENDOR_FROM_DATABASE=Chips and Technologies + +usb:v0420p1307* + ID_PRODUCT_FROM_DATABASE=Celly SIM Card Reader + +usb:v0421* + ID_VENDOR_FROM_DATABASE=Nokia Mobile Phones + +usb:v0421p0001* + ID_PRODUCT_FROM_DATABASE=E61i (PC Suite mode) + +usb:v0421p0018* + ID_PRODUCT_FROM_DATABASE=6288 GSM Smartphone + +usb:v0421p0019* + ID_PRODUCT_FROM_DATABASE=6288 GSM Smartphone (imaging mode) + +usb:v0421p001A* + ID_PRODUCT_FROM_DATABASE=6288 GSM Smartphone (file transfer mode) + +usb:v0421p0024* + ID_PRODUCT_FROM_DATABASE=5610 XpressMusic (Storage mode) + +usb:v0421p0025* + ID_PRODUCT_FROM_DATABASE=5610 XpressMusic (PC Suite mode) + +usb:v0421p0028* + ID_PRODUCT_FROM_DATABASE=5610 XpressMusic (Imaging mode) + +usb:v0421p002D* + ID_PRODUCT_FROM_DATABASE=6120 Phone (Mass storage mode) + +usb:v0421p002E* + ID_PRODUCT_FROM_DATABASE=6120 Phone (Media-Player mode) + +usb:v0421p002F* + ID_PRODUCT_FROM_DATABASE=6120 Phone (PC-Suite mode) + +usb:v0421p0042* + ID_PRODUCT_FROM_DATABASE=E51 (PC Suite mode) + +usb:v0421p0064* + ID_PRODUCT_FROM_DATABASE=3109c GSM Phone + +usb:v0421p006B* + ID_PRODUCT_FROM_DATABASE=5310 Xpress Music (PC Suite mode) + +usb:v0421p006C* + ID_PRODUCT_FROM_DATABASE=5310 Xpress music (Storage mode) + +usb:v0421p006D* + ID_PRODUCT_FROM_DATABASE=N95 (Storage mode) + +usb:v0421p006E* + ID_PRODUCT_FROM_DATABASE=N95 (Multimedia mode) + +usb:v0421p006F* + ID_PRODUCT_FROM_DATABASE=N95 (Printing mode) + +usb:v0421p0070* + ID_PRODUCT_FROM_DATABASE=N95 (PC Suite mode) + +usb:v0421p0096* + ID_PRODUCT_FROM_DATABASE=N810 Internet Tablet + +usb:v0421p00AA* + ID_PRODUCT_FROM_DATABASE=E71 (Mass storage mode) + +usb:v0421p00AB* + ID_PRODUCT_FROM_DATABASE=E71 (PC Suite mode) + +usb:v0421p00E4* + ID_PRODUCT_FROM_DATABASE=E71 (Media transfer mode) + +usb:v0421p0103* + ID_PRODUCT_FROM_DATABASE=ADL Flashing Engine AVALON Parent + +usb:v0421p0104* + ID_PRODUCT_FROM_DATABASE=ADL Re-Flashing Engine Parent + +usb:v0421p0105* + ID_PRODUCT_FROM_DATABASE=Nokia Firmware Upgrade Mode + +usb:v0421p0106* + ID_PRODUCT_FROM_DATABASE=ROM Parent + +usb:v0421p0154* + ID_PRODUCT_FROM_DATABASE=5800 XpressMusic (PC Suite mode) + +usb:v0421p0155* + ID_PRODUCT_FROM_DATABASE=5800 XpressMusic (Multimedia mode) + +usb:v0421p0156* + ID_PRODUCT_FROM_DATABASE=5800 XpressMusic (Storage mode) + +usb:v0421p0157* + ID_PRODUCT_FROM_DATABASE=5800 XpressMusic (Imaging mode) + +usb:v0421p0199* + ID_PRODUCT_FROM_DATABASE=6700 Classic (msc) + +usb:v0421p019A* + ID_PRODUCT_FROM_DATABASE=6700 Classic (PC Suite) + +usb:v0421p019B* + ID_PRODUCT_FROM_DATABASE=6700 Classic (mtp) + +usb:v0421p01B0* + ID_PRODUCT_FROM_DATABASE=6303 classic Phone (PC Suite mode) + +usb:v0421p01B1* + ID_PRODUCT_FROM_DATABASE=6303 classic Phone (Mass storage mode) + +usb:v0421p01B2* + ID_PRODUCT_FROM_DATABASE=6303 classic Phone (Printing and media mode) + +usb:v0421p01C7* + ID_PRODUCT_FROM_DATABASE=N900 (Storage Mode) + +usb:v0421p01C8* + ID_PRODUCT_FROM_DATABASE=N900 (PC-Suite Mode) + +usb:v0421p0228* + ID_PRODUCT_FROM_DATABASE=5530 XpressMusic + +usb:v0421p023A* + ID_PRODUCT_FROM_DATABASE=6730 Classic + +usb:v0421p026A* + ID_PRODUCT_FROM_DATABASE=N97 (mass storage) + +usb:v0421p026B* + ID_PRODUCT_FROM_DATABASE=N97 (Multimedia) + +usb:v0421p026C* + ID_PRODUCT_FROM_DATABASE=N97 (PC Suite) + +usb:v0421p026D* + ID_PRODUCT_FROM_DATABASE=N97 (Pictures) + +usb:v0421p0295* + ID_PRODUCT_FROM_DATABASE=660i/6600i Slide Phone (Mass Storage) + +usb:v0421p0297* + ID_PRODUCT_FROM_DATABASE=660i/6600i Slide Phone (Still Image) + +usb:v0421p02E1* + ID_PRODUCT_FROM_DATABASE=5230 (Storage mode) + +usb:v0421p02E2* + ID_PRODUCT_FROM_DATABASE=5230 (Multimedia mode) + +usb:v0421p02E3* + ID_PRODUCT_FROM_DATABASE=5230 (PC-Suite mode) + +usb:v0421p02E4* + ID_PRODUCT_FROM_DATABASE=5230 (Imaging mode) + +usb:v0421p0360* + ID_PRODUCT_FROM_DATABASE=C1-01 Ovi Suite Mode + +usb:v0421p03A4* + ID_PRODUCT_FROM_DATABASE=C5 (Storage mode) + +usb:v0421p03C0* + ID_PRODUCT_FROM_DATABASE=C7-00 + +usb:v0421p03D1* + ID_PRODUCT_FROM_DATABASE=N950 + +usb:v0421p0400* + ID_PRODUCT_FROM_DATABASE=7600 Phone Parent + +usb:v0421p0401* + ID_PRODUCT_FROM_DATABASE=6650 GSM Phone + +usb:v0421p0402* + ID_PRODUCT_FROM_DATABASE=6255 Phone Parent + +usb:v0421p0404* + ID_PRODUCT_FROM_DATABASE=5510 + +usb:v0421p0405* + ID_PRODUCT_FROM_DATABASE=9500 GSM Communicator + +usb:v0421p0407* + ID_PRODUCT_FROM_DATABASE=Music Player HDR-1(tm) + +usb:v0421p040B* + ID_PRODUCT_FROM_DATABASE=N-Gage GSM Phone + +usb:v0421p040D* + ID_PRODUCT_FROM_DATABASE=6620 Phone Parent + +usb:v0421p040E* + ID_PRODUCT_FROM_DATABASE=6651 Phone Parent + +usb:v0421p040F* + ID_PRODUCT_FROM_DATABASE=6230 GSM Phone + +usb:v0421p0410* + ID_PRODUCT_FROM_DATABASE=6630 Imaging Smartphone + +usb:v0421p0411* + ID_PRODUCT_FROM_DATABASE=7610 Phone Parent + +usb:v0421p0413* + ID_PRODUCT_FROM_DATABASE=6260 Phone Parent + +usb:v0421p0414* + ID_PRODUCT_FROM_DATABASE=7370 + +usb:v0421p0415* + ID_PRODUCT_FROM_DATABASE=9300 GSM Smartphone + +usb:v0421p0416* + ID_PRODUCT_FROM_DATABASE=6170 Phone Parent + +usb:v0421p0417* + ID_PRODUCT_FROM_DATABASE=7270 Phone Parent + +usb:v0421p0418* + ID_PRODUCT_FROM_DATABASE=E70 (PC Suite mode) + +usb:v0421p0419* + ID_PRODUCT_FROM_DATABASE=E60 (PC Suite mode) + +usb:v0421p041A* + ID_PRODUCT_FROM_DATABASE=9500 GSM Communicator (RNDIS) + +usb:v0421p041B* + ID_PRODUCT_FROM_DATABASE=9300 GSM Smartphone (RNDIS) + +usb:v0421p041C* + ID_PRODUCT_FROM_DATABASE=7710 Phone Parent + +usb:v0421p041D* + ID_PRODUCT_FROM_DATABASE=6670 Phone Parent + +usb:v0421p041E* + ID_PRODUCT_FROM_DATABASE=6680 + +usb:v0421p041F* + ID_PRODUCT_FROM_DATABASE=6235 Phone Parent + +usb:v0421p0421* + ID_PRODUCT_FROM_DATABASE=3230 Phone Parent + +usb:v0421p0422* + ID_PRODUCT_FROM_DATABASE=6681 Phone Parent + +usb:v0421p0423* + ID_PRODUCT_FROM_DATABASE=6682 Phone Parent + +usb:v0421p0428* + ID_PRODUCT_FROM_DATABASE=6230i Modem + +usb:v0421p0429* + ID_PRODUCT_FROM_DATABASE=6230i MultiMedia Card + +usb:v0421p0431* + ID_PRODUCT_FROM_DATABASE=770 Internet Tablet + +usb:v0421p0432* + ID_PRODUCT_FROM_DATABASE=N90 Phone Parent + +usb:v0421p0435* + ID_PRODUCT_FROM_DATABASE=E70 (IP Passthrough/RNDIS mode) + +usb:v0421p0436* + ID_PRODUCT_FROM_DATABASE=E60 (IP Passthrough/RNDIS mode) + +usb:v0421p0437* + ID_PRODUCT_FROM_DATABASE=6265 Phone Parent + +usb:v0421p043A* + ID_PRODUCT_FROM_DATABASE=N70 USB Phone Parent + +usb:v0421p043B* + ID_PRODUCT_FROM_DATABASE=3155 Phone Parent + +usb:v0421p043C* + ID_PRODUCT_FROM_DATABASE=6155 Phone Parent + +usb:v0421p043D* + ID_PRODUCT_FROM_DATABASE=6270 Phone Parent + +usb:v0421p0443* + ID_PRODUCT_FROM_DATABASE=N70 Phone Parent + +usb:v0421p0444* + ID_PRODUCT_FROM_DATABASE=N91 + +usb:v0421p044C* + ID_PRODUCT_FROM_DATABASE=NM850iG Phone Parent + +usb:v0421p044D* + ID_PRODUCT_FROM_DATABASE=E61 (PC Suite mode) + +usb:v0421p044E* + ID_PRODUCT_FROM_DATABASE=E61 (Data Exchange mode) + +usb:v0421p044F* + ID_PRODUCT_FROM_DATABASE=E61 (IP Passthrough/RNDIS mode) + +usb:v0421p0453* + ID_PRODUCT_FROM_DATABASE=9300 Phone Parent + +usb:v0421p0456* + ID_PRODUCT_FROM_DATABASE=6111 Phone Parent + +usb:v0421p0457* + ID_PRODUCT_FROM_DATABASE=6111 Phone (Printing mode) + +usb:v0421p045A* + ID_PRODUCT_FROM_DATABASE=6280 Phone Parent + +usb:v0421p045D* + ID_PRODUCT_FROM_DATABASE=6282 Phone Parent + +usb:v0421p046E* + ID_PRODUCT_FROM_DATABASE=6110 Navigator + +usb:v0421p0471* + ID_PRODUCT_FROM_DATABASE=6110 Navigator + +usb:v0421p0485* + ID_PRODUCT_FROM_DATABASE=MTP Device + +usb:v0421p04B9* + ID_PRODUCT_FROM_DATABASE=5300 + +usb:v0421p04C3* + ID_PRODUCT_FROM_DATABASE=N800 Internet Tablet + +usb:v0421p04CE* + ID_PRODUCT_FROM_DATABASE=E90 Communicator (PC Suite mode) + +usb:v0421p04CF* + ID_PRODUCT_FROM_DATABASE=E90 Communicator (Storage mode) + +usb:v0421p04F0* + ID_PRODUCT_FROM_DATABASE=Nokia N95 (PC Suite mode) + +usb:v0421p04F9* + ID_PRODUCT_FROM_DATABASE=6300 (PC Suite mode) + +usb:v0421p0508* + ID_PRODUCT_FROM_DATABASE=E65 (PC Suite mode) + +usb:v0421p0509* + ID_PRODUCT_FROM_DATABASE=E65 (Storage mode) + +usb:v0421p0518* + ID_PRODUCT_FROM_DATABASE=N9 Phone + +usb:v0421p0600* + ID_PRODUCT_FROM_DATABASE=Digital Pen SU-1B + +usb:v0421p0610* + ID_PRODUCT_FROM_DATABASE=CS-15 (Internet Stick 3G modem) + +usb:v0421p0800* + ID_PRODUCT_FROM_DATABASE=Connectivity Cable DKU-5 + +usb:v0421p0801* + ID_PRODUCT_FROM_DATABASE=Data Cable DKU-6 + +usb:v0421p0802* + ID_PRODUCT_FROM_DATABASE=CA-42 Phone Parent + +usb:v0422* + ID_VENDOR_FROM_DATABASE=ADI Systems, Inc. + +usb:v0423* + ID_VENDOR_FROM_DATABASE=Computer Access Technology Corp. + +usb:v0423p000A* + ID_PRODUCT_FROM_DATABASE=NetMate Ethernet + +usb:v0423p000C* + ID_PRODUCT_FROM_DATABASE=NetMate2 Ethernet + +usb:v0423p000D* + ID_PRODUCT_FROM_DATABASE=USB Chief Analyzer + +usb:v0423p0100* + ID_PRODUCT_FROM_DATABASE=Generic Universal Protocol Analyzer + +usb:v0423p0101* + ID_PRODUCT_FROM_DATABASE=UPA USBTracer + +usb:v0423p0200* + ID_PRODUCT_FROM_DATABASE=Generic 10K Universal Protocol Analyzer + +usb:v0423p020A* + ID_PRODUCT_FROM_DATABASE=PETracer ML + +usb:v0423p0300* + ID_PRODUCT_FROM_DATABASE=Generic Universal Protocol Analyzer + +usb:v0423p0301* + ID_PRODUCT_FROM_DATABASE=2500H Tracer Trainer + +usb:v0423p030A* + ID_PRODUCT_FROM_DATABASE=PETracer x1 + +usb:v0423p1237* + ID_PRODUCT_FROM_DATABASE=Andromeda Hub + +usb:v0424* + ID_VENDOR_FROM_DATABASE=Standard Microsystems Corp. + +usb:v0424p0001* + ID_PRODUCT_FROM_DATABASE=Integrated Hub + +usb:v0424p0ACD* + ID_PRODUCT_FROM_DATABASE=Sitecom Internal Multi Memory reader/writer MD-005 + +usb:v0424p0FDC* + ID_PRODUCT_FROM_DATABASE=Floppy + +usb:v0424p10CD* + ID_PRODUCT_FROM_DATABASE=Sitecom Internal Multi Memory reader/writer MD-005 + +usb:v0424p2020* + ID_PRODUCT_FROM_DATABASE=USB Hub + +usb:v0424p20CD* + ID_PRODUCT_FROM_DATABASE=Sitecom Internal Multi Memory reader/writer MD-005 + +usb:v0424p20FC* + ID_PRODUCT_FROM_DATABASE=6-in-1 Card Reader + +usb:v0424p2228* + ID_PRODUCT_FROM_DATABASE=9-in-2 Card Reader + +usb:v0424p223A* + ID_PRODUCT_FROM_DATABASE=8-in-1 Card Reader + +usb:v0424p2503* + ID_PRODUCT_FROM_DATABASE=USB 2.0 Hub + +usb:v0424p2504* + ID_PRODUCT_FROM_DATABASE=USB 2.0 Hub + +usb:v0424p2512* + ID_PRODUCT_FROM_DATABASE=USB 2.0 Hub + +usb:v0424p2513* + ID_PRODUCT_FROM_DATABASE=2.0 Hub + +usb:v0424p2514* + ID_PRODUCT_FROM_DATABASE=USB 2.0 Hub + +usb:v0424p2517* + ID_PRODUCT_FROM_DATABASE=Hub + +usb:v0424p2524* + ID_PRODUCT_FROM_DATABASE=USB MultiSwitch Hub + +usb:v0424p2602* + ID_PRODUCT_FROM_DATABASE=USB 2.0 Hub + +usb:v0424p2640* + ID_PRODUCT_FROM_DATABASE=USB 2.0 Hub + +usb:v0424p4060* + ID_PRODUCT_FROM_DATABASE=Ultra Fast Media Reader + +usb:v0424p4064* + ID_PRODUCT_FROM_DATABASE=Ultra Fast Media Reader + +usb:v0424p9512* + ID_PRODUCT_FROM_DATABASE=LAN9500 Ethernet 10/100 Adapter + +usb:v0424pA700* + ID_PRODUCT_FROM_DATABASE=2 Port Hub + +usb:v0425* + ID_VENDOR_FROM_DATABASE=Motorola Semiconductors HK, Ltd + +usb:v0425p0101* + ID_PRODUCT_FROM_DATABASE=G-Tech Wireless Mouse & Keyboard + +usb:v0425pF102* + ID_PRODUCT_FROM_DATABASE=G-Tech U+P Wireless Mouse + +usb:v0426* + ID_VENDOR_FROM_DATABASE=Integrated Device Technology, Inc. + +usb:v0426p0426* + ID_PRODUCT_FROM_DATABASE=WDM Driver + +usb:v0427* + ID_VENDOR_FROM_DATABASE=Motorola Electronics Taiwan, Ltd + +usb:v0428* + ID_VENDOR_FROM_DATABASE=Advanced Gravis Computer Tech, Ltd + +usb:v0428p4001* + ID_PRODUCT_FROM_DATABASE=GamePad Pro + +usb:v0429* + ID_VENDOR_FROM_DATABASE=Cirrus Logic + +usb:v042A* + ID_VENDOR_FROM_DATABASE=Ericsson Austrian, AG + +usb:v042B* + ID_VENDOR_FROM_DATABASE=Intel Corp. + +usb:v042Bp9316* + ID_PRODUCT_FROM_DATABASE=8x931Hx Customer Hub + +usb:v042C* + ID_VENDOR_FROM_DATABASE=Innovative Semiconductors, Inc. + +usb:v042D* + ID_VENDOR_FROM_DATABASE=Micronics + +usb:v042E* + ID_VENDOR_FROM_DATABASE=Acer, Inc. + +usb:v042Ep0380* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v042F* + ID_VENDOR_FROM_DATABASE=Molex, Inc. + +usb:v0430* + ID_VENDOR_FROM_DATABASE=Sun Microsystems, Inc. + +usb:v0430p0002* + ID_PRODUCT_FROM_DATABASE=109 Keyboard + +usb:v0430p0005* + ID_PRODUCT_FROM_DATABASE=Type 6 Keyboard + +usb:v0430p000A* + ID_PRODUCT_FROM_DATABASE=109 Japanese Keyboard + +usb:v0430p000B* + ID_PRODUCT_FROM_DATABASE=109 Japanese Keyboard + +usb:v0430p0082* + ID_PRODUCT_FROM_DATABASE=109 Japanese Keyboard + +usb:v0430p0083* + ID_PRODUCT_FROM_DATABASE=109 Japanese Keyboard + +usb:v0430p00A2* + ID_PRODUCT_FROM_DATABASE=Type 7 Keyboard + +usb:v0430p0100* + ID_PRODUCT_FROM_DATABASE=3-button Mouse + +usb:v0430p100E* + ID_PRODUCT_FROM_DATABASE=24.1" LCD Monitor v4 / FID-638 Mouse + +usb:v0430p36BA* + ID_PRODUCT_FROM_DATABASE=Bus Powered Hub + +usb:v0430pA101* + ID_PRODUCT_FROM_DATABASE=remote key/mouse for P3 chip + +usb:v0430pA102* + ID_PRODUCT_FROM_DATABASE=remote key/mouse/storage for P3 chip + +usb:v0430pA103* + ID_PRODUCT_FROM_DATABASE=remote storage for P3 chip + +usb:v0430pA4A2* + ID_PRODUCT_FROM_DATABASE=Ethernet (RNDIS and CDC ethernet) + +usb:v0430pCDAB* + ID_PRODUCT_FROM_DATABASE=Raritan KVM dongle + +usb:v0431* + ID_VENDOR_FROM_DATABASE=Itac Systems, Inc. + +usb:v0431p0100* + ID_PRODUCT_FROM_DATABASE=Mouse-Trak 3-button Track Ball + +usb:v0432* + ID_VENDOR_FROM_DATABASE=Unisys Corp. + +usb:v0433* + ID_VENDOR_FROM_DATABASE=Alps Electric, Inc. + +usb:v0433p1101* + ID_PRODUCT_FROM_DATABASE=IBM Game Controller + +usb:v0433pABAB* + ID_PRODUCT_FROM_DATABASE=Keyboard + +usb:v0434* + ID_VENDOR_FROM_DATABASE=Samsung Info. Systems America, Inc. + +usb:v0435* + ID_VENDOR_FROM_DATABASE=Hyundai Electronics America + +usb:v0436* + ID_VENDOR_FROM_DATABASE=Taugagreining HF + +usb:v0436p0005* + ID_PRODUCT_FROM_DATABASE=CameraMate (DPCM_USB) + +usb:v0437* + ID_VENDOR_FROM_DATABASE=Framatome Connectors USA + +usb:v0438* + ID_VENDOR_FROM_DATABASE=Advanced Micro Devices, Inc. + +usb:v0439* + ID_VENDOR_FROM_DATABASE=Voice Technologies Group + +usb:v043D* + ID_VENDOR_FROM_DATABASE=Lexmark International, Inc. + +usb:v043Dp0001* + ID_PRODUCT_FROM_DATABASE=Laser Printer + +usb:v043Dp0002* + ID_PRODUCT_FROM_DATABASE=Optra E310 Printer + +usb:v043Dp0003* + ID_PRODUCT_FROM_DATABASE=Laser Printer + +usb:v043Dp0004* + ID_PRODUCT_FROM_DATABASE=Laser Printer + +usb:v043Dp0005* + ID_PRODUCT_FROM_DATABASE=Laser Printer + +usb:v043Dp0006* + ID_PRODUCT_FROM_DATABASE=Laser Printer + +usb:v043Dp0007* + ID_PRODUCT_FROM_DATABASE=Laser Printer + +usb:v043Dp0008* + ID_PRODUCT_FROM_DATABASE=Inkjet Color Printer + +usb:v043Dp0009* + ID_PRODUCT_FROM_DATABASE=Optra S2450 Printer + +usb:v043Dp000A* + ID_PRODUCT_FROM_DATABASE=Laser Printer + +usb:v043Dp000B* + ID_PRODUCT_FROM_DATABASE=Inkjet Color Printer + +usb:v043Dp000C* + ID_PRODUCT_FROM_DATABASE=Optra E312 Printer + +usb:v043Dp000D* + ID_PRODUCT_FROM_DATABASE=Laser Printer + +usb:v043Dp000E* + ID_PRODUCT_FROM_DATABASE=Laser Printer + +usb:v043Dp000F* + ID_PRODUCT_FROM_DATABASE=Laser Printer + +usb:v043Dp0010* + ID_PRODUCT_FROM_DATABASE=Laser Printer + +usb:v043Dp0011* + ID_PRODUCT_FROM_DATABASE=Laser Printer + +usb:v043Dp0012* + ID_PRODUCT_FROM_DATABASE=Inkjet Color Printer + +usb:v043Dp0013* + ID_PRODUCT_FROM_DATABASE=Inkjet Color Printer + +usb:v043Dp0014* + ID_PRODUCT_FROM_DATABASE=InkJet Color Printer + +usb:v043Dp0015* + ID_PRODUCT_FROM_DATABASE=InkJet Color Printer + +usb:v043Dp0016* + ID_PRODUCT_FROM_DATABASE=Z12 Color Jetprinter + +usb:v043Dp0017* + ID_PRODUCT_FROM_DATABASE=Z32 printer + +usb:v043Dp0018* + ID_PRODUCT_FROM_DATABASE=Z52 Printer + +usb:v043Dp0019* + ID_PRODUCT_FROM_DATABASE=Forms Printer + +usb:v043Dp001A* + ID_PRODUCT_FROM_DATABASE=Z65 Printer + +usb:v043Dp001B* + ID_PRODUCT_FROM_DATABASE=InkJet Photo Printer + +usb:v043Dp001C* + ID_PRODUCT_FROM_DATABASE=Kodak Personal Picture Maker 200 Printer + +usb:v043Dp001D* + ID_PRODUCT_FROM_DATABASE=InkJet Color Printer + +usb:v043Dp001E* + ID_PRODUCT_FROM_DATABASE=InkJet Photo Printer + +usb:v043Dp001F* + ID_PRODUCT_FROM_DATABASE=Kodak Personal Picture Maker 200 Card Reader + +usb:v043Dp0020* + ID_PRODUCT_FROM_DATABASE=Z51 Printer + +usb:v043Dp0021* + ID_PRODUCT_FROM_DATABASE=Z33 Printer + +usb:v043Dp0022* + ID_PRODUCT_FROM_DATABASE=InkJet Color Printer + +usb:v043Dp0023* + ID_PRODUCT_FROM_DATABASE=Laser Printer + +usb:v043Dp0024* + ID_PRODUCT_FROM_DATABASE=Laser Printer + +usb:v043Dp0025* + ID_PRODUCT_FROM_DATABASE=InkJet Color Printer + +usb:v043Dp0026* + ID_PRODUCT_FROM_DATABASE=InkJet Color Printer + +usb:v043Dp0027* + ID_PRODUCT_FROM_DATABASE=InkJet Color Printer + +usb:v043Dp0028* + ID_PRODUCT_FROM_DATABASE=InkJet Color Printer + +usb:v043Dp0029* + ID_PRODUCT_FROM_DATABASE=Scan Print Copy + +usb:v043Dp002A* + ID_PRODUCT_FROM_DATABASE=Scan Print Copy + +usb:v043Dp002B* + ID_PRODUCT_FROM_DATABASE=Scan Print Copy + +usb:v043Dp002C* + ID_PRODUCT_FROM_DATABASE=Scan Print Copy + +usb:v043Dp002D* + ID_PRODUCT_FROM_DATABASE=X70/X73 Scan/Print/Copy + +usb:v043Dp002E* + ID_PRODUCT_FROM_DATABASE=Scan Print Copy + +usb:v043Dp002F* + ID_PRODUCT_FROM_DATABASE=Scan Print Copy + +usb:v043Dp0030* + ID_PRODUCT_FROM_DATABASE=Scan Print Copy + +usb:v043Dp0031* + ID_PRODUCT_FROM_DATABASE=Scan Print Copy + +usb:v043Dp0032* + ID_PRODUCT_FROM_DATABASE=Scan Print Copy + +usb:v043Dp0033* + ID_PRODUCT_FROM_DATABASE=Scan Print Copy + +usb:v043Dp0034* + ID_PRODUCT_FROM_DATABASE=Scan Print Copy + +usb:v043Dp0035* + ID_PRODUCT_FROM_DATABASE=Scan Print Copy + +usb:v043Dp0036* + ID_PRODUCT_FROM_DATABASE=Scan Print Copy + +usb:v043Dp0037* + ID_PRODUCT_FROM_DATABASE=Scan Print Copy + +usb:v043Dp0038* + ID_PRODUCT_FROM_DATABASE=Scan Print Copy + +usb:v043Dp0039* + ID_PRODUCT_FROM_DATABASE=Scan Print Copy + +usb:v043Dp003A* + ID_PRODUCT_FROM_DATABASE=Scan Print Copy + +usb:v043Dp003B* + ID_PRODUCT_FROM_DATABASE=Scan Print Copy + +usb:v043Dp003C* + ID_PRODUCT_FROM_DATABASE=Scan Print Copy + +usb:v043Dp003D* + ID_PRODUCT_FROM_DATABASE=X83 Scan/Print/Copy + +usb:v043Dp003E* + ID_PRODUCT_FROM_DATABASE=Scan Print Copy + +usb:v043Dp003F* + ID_PRODUCT_FROM_DATABASE=Scan Print Copy + +usb:v043Dp0040* + ID_PRODUCT_FROM_DATABASE=Scan Print Copy + +usb:v043Dp0041* + ID_PRODUCT_FROM_DATABASE=Scan Print Copy + +usb:v043Dp0042* + ID_PRODUCT_FROM_DATABASE=Scan Print Copy + +usb:v043Dp0043* + ID_PRODUCT_FROM_DATABASE=Scan Print Copy + +usb:v043Dp0044* + ID_PRODUCT_FROM_DATABASE=Scan Print Copy + +usb:v043Dp0045* + ID_PRODUCT_FROM_DATABASE=Scan Print Copy + +usb:v043Dp0046* + ID_PRODUCT_FROM_DATABASE=Scan Print Copy + +usb:v043Dp0047* + ID_PRODUCT_FROM_DATABASE=Scan Print Copy + +usb:v043Dp0048* + ID_PRODUCT_FROM_DATABASE=Scan Print Copy + +usb:v043Dp0049* + ID_PRODUCT_FROM_DATABASE=Scan Print Copy + +usb:v043Dp004A* + ID_PRODUCT_FROM_DATABASE=Scan Print Copy + +usb:v043Dp004B* + ID_PRODUCT_FROM_DATABASE=Scan Print Copy + +usb:v043Dp004C* + ID_PRODUCT_FROM_DATABASE=Scan Print Copy + +usb:v043Dp004D* + ID_PRODUCT_FROM_DATABASE=Laser Printer + +usb:v043Dp004E* + ID_PRODUCT_FROM_DATABASE=Laser Printer + +usb:v043Dp004F* + ID_PRODUCT_FROM_DATABASE=InkJet Color Printer + +usb:v043Dp0050* + ID_PRODUCT_FROM_DATABASE=InkJet Color Printer + +usb:v043Dp0051* + ID_PRODUCT_FROM_DATABASE=Laser Printer + +usb:v043Dp0052* + ID_PRODUCT_FROM_DATABASE=Laser Printer + +usb:v043Dp0053* + ID_PRODUCT_FROM_DATABASE=InkJet Color Printer + +usb:v043Dp0054* + ID_PRODUCT_FROM_DATABASE=InkJet Color Printer + +usb:v043Dp0057* + ID_PRODUCT_FROM_DATABASE=Z35 Printer + +usb:v043Dp0058* + ID_PRODUCT_FROM_DATABASE=Laser Printer + +usb:v043Dp005A* + ID_PRODUCT_FROM_DATABASE=X63 + +usb:v043Dp005C* + ID_PRODUCT_FROM_DATABASE=InkJet Color Printer + +usb:v043Dp0060* + ID_PRODUCT_FROM_DATABASE=X74/X75 Scanner + +usb:v043Dp0061* + ID_PRODUCT_FROM_DATABASE=X74 Hub + +usb:v043Dp0065* + ID_PRODUCT_FROM_DATABASE=X5130 + +usb:v043Dp0069* + ID_PRODUCT_FROM_DATABASE=X74/X75 Printer + +usb:v043Dp006D* + ID_PRODUCT_FROM_DATABASE=X125 + +usb:v043Dp006E* + ID_PRODUCT_FROM_DATABASE=C510 + +usb:v043Dp0072* + ID_PRODUCT_FROM_DATABASE=X6170 Printer + +usb:v043Dp0073* + ID_PRODUCT_FROM_DATABASE=InkJet Color Printer + +usb:v043Dp0078* + ID_PRODUCT_FROM_DATABASE=InkJet Color Printer + +usb:v043Dp0079* + ID_PRODUCT_FROM_DATABASE=InkJet Color Printer + +usb:v043Dp007A* + ID_PRODUCT_FROM_DATABASE=Generic Hub + +usb:v043Dp007B* + ID_PRODUCT_FROM_DATABASE=InkJet Color Printer + +usb:v043Dp007C* + ID_PRODUCT_FROM_DATABASE=X1110/X1130/X1140/X1150/X1170/X1180/X1185 + +usb:v043Dp007D* + ID_PRODUCT_FROM_DATABASE=Photo 3150 + +usb:v043Dp008A* + ID_PRODUCT_FROM_DATABASE=4200 series + +usb:v043Dp008B* + ID_PRODUCT_FROM_DATABASE=InkJet Color Printer + +usb:v043Dp008C* + ID_PRODUCT_FROM_DATABASE=to CF/SM/SD/MS Card Reader + +usb:v043Dp008E* + ID_PRODUCT_FROM_DATABASE=InkJet Color Printer + +usb:v043Dp008F* + ID_PRODUCT_FROM_DATABASE=X422 + +usb:v043Dp0093* + ID_PRODUCT_FROM_DATABASE=X5250 + +usb:v043Dp0095* + ID_PRODUCT_FROM_DATABASE=E220 Printer + +usb:v043Dp0096* + ID_PRODUCT_FROM_DATABASE=2200 series + +usb:v043Dp0097* + ID_PRODUCT_FROM_DATABASE=P6250 + +usb:v043Dp0098* + ID_PRODUCT_FROM_DATABASE=7100 series + +usb:v043Dp009E* + ID_PRODUCT_FROM_DATABASE=P910 series Human Interface Device + +usb:v043Dp009F* + ID_PRODUCT_FROM_DATABASE=InkJet Color Printer + +usb:v043Dp00A9* + ID_PRODUCT_FROM_DATABASE=IBM Infoprint 1410 MFP + +usb:v043Dp00AB* + ID_PRODUCT_FROM_DATABASE=InkJet Color Printer + +usb:v043Dp00B2* + ID_PRODUCT_FROM_DATABASE=3300 series + +usb:v043Dp00B8* + ID_PRODUCT_FROM_DATABASE=7300 series + +usb:v043Dp00B9* + ID_PRODUCT_FROM_DATABASE=8300 series + +usb:v043Dp00BA* + ID_PRODUCT_FROM_DATABASE=InkJet Color Printer + +usb:v043Dp00BB* + ID_PRODUCT_FROM_DATABASE=2300 series + +usb:v043Dp00BD* + ID_PRODUCT_FROM_DATABASE=Printing Support + +usb:v043Dp00BE* + ID_PRODUCT_FROM_DATABASE=Printing Support + +usb:v043Dp00BF* + ID_PRODUCT_FROM_DATABASE=Printing Support + +usb:v043Dp00C0* + ID_PRODUCT_FROM_DATABASE=6300 series + +usb:v043Dp00C1* + ID_PRODUCT_FROM_DATABASE=4300 series + +usb:v043Dp00C7* + ID_PRODUCT_FROM_DATABASE=Printing Support + +usb:v043Dp00C8* + ID_PRODUCT_FROM_DATABASE=Printing Support + +usb:v043Dp00C9* + ID_PRODUCT_FROM_DATABASE=Printing Support + +usb:v043Dp00CB* + ID_PRODUCT_FROM_DATABASE=Printing Support + +usb:v043Dp00CC* + ID_PRODUCT_FROM_DATABASE=E120(n) + +usb:v043Dp00D0* + ID_PRODUCT_FROM_DATABASE=9300 series + +usb:v043Dp00D3* + ID_PRODUCT_FROM_DATABASE=X340 Scanner + +usb:v043Dp00D4* + ID_PRODUCT_FROM_DATABASE=X342n Scanner + +usb:v043Dp00D5* + ID_PRODUCT_FROM_DATABASE=Printing Support + +usb:v043Dp00D6* + ID_PRODUCT_FROM_DATABASE=X340 Scanner + +usb:v043Dp00E8* + ID_PRODUCT_FROM_DATABASE=X642e + +usb:v043Dp00E9* + ID_PRODUCT_FROM_DATABASE=2400 series + +usb:v043Dp00F6* + ID_PRODUCT_FROM_DATABASE=3400 series + +usb:v043Dp00F7* + ID_PRODUCT_FROM_DATABASE=InkJet Color Printer + +usb:v043Dp00FF* + ID_PRODUCT_FROM_DATABASE=InkJet Color Printer + +usb:v043Dp010B* + ID_PRODUCT_FROM_DATABASE=2500 series + +usb:v043Dp010D* + ID_PRODUCT_FROM_DATABASE=3500-4500 series + +usb:v043Dp010F* + ID_PRODUCT_FROM_DATABASE=6500 series + +usb:v043Dp0142* + ID_PRODUCT_FROM_DATABASE=X3650 (Printer, Scanner, Copier) + +usb:v043Dp4303* + ID_PRODUCT_FROM_DATABASE=Xerox WorkCentre Pro 412 + +usb:v043E* + ID_VENDOR_FROM_DATABASE=LG Electronics USA, Inc. + +usb:v043Ep3001* + ID_PRODUCT_FROM_DATABASE=AN-WF100 802.11abgn Wireless Adapter [Broadcom BCM4323] + +usb:v043Ep42BD* + ID_PRODUCT_FROM_DATABASE=Flatron 795FT Plus Monitor + +usb:v043Ep4A4D* + ID_PRODUCT_FROM_DATABASE=Flatron 915FT Plus Monitor + +usb:v043Ep7001* + ID_PRODUCT_FROM_DATABASE=MF-PD100 Soul Digital MP3 Player + +usb:v043Ep7013* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v043Ep8484* + ID_PRODUCT_FROM_DATABASE=LPC-U30 Webcam II + +usb:v043Ep8585* + ID_PRODUCT_FROM_DATABASE=LPC-UC35 Webcam + +usb:v043Ep8888* + ID_PRODUCT_FROM_DATABASE=Electronics VCS Camera II(LPC-U20) + +usb:v043Ep9800* + ID_PRODUCT_FROM_DATABASE=Remote Control Receiver_iMON + +usb:v043Ep9803* + ID_PRODUCT_FROM_DATABASE=eHome Infrared Receiver + +usb:v043Ep9804* + ID_PRODUCT_FROM_DATABASE=DMB Receiver Control + +usb:v043Ep9C01* + ID_PRODUCT_FROM_DATABASE=LGE Sync + +usb:v043F* + ID_VENDOR_FROM_DATABASE=RadiSys Corp. + +usb:v0440* + ID_VENDOR_FROM_DATABASE=Eizo Nanao Corp. + +usb:v0441* + ID_VENDOR_FROM_DATABASE=Winbond Systems Lab. + +usb:v0441p1456* + ID_PRODUCT_FROM_DATABASE=Hub + +usb:v0442* + ID_VENDOR_FROM_DATABASE=Ericsson, Inc. + +usb:v0442pABBA* + ID_PRODUCT_FROM_DATABASE=Bluetooth Device + +usb:v0443* + ID_VENDOR_FROM_DATABASE=Gateway, Inc. + +usb:v0443p000E* + ID_PRODUCT_FROM_DATABASE=Multimedia Keyboard + +usb:v0443p002E* + ID_PRODUCT_FROM_DATABASE=Millennium Keyboard + +usb:v0445* + ID_VENDOR_FROM_DATABASE=Lucent Technologies, Inc. + +usb:v0446* + ID_VENDOR_FROM_DATABASE=NMB Technologies Corp. + +usb:v0446p6781* + ID_PRODUCT_FROM_DATABASE=Keyboard with PS/2 Mouse Port + +usb:v0446p6782* + ID_PRODUCT_FROM_DATABASE=Keyboard + +usb:v0447* + ID_VENDOR_FROM_DATABASE=Momentum Microsystems + +usb:v044A* + ID_VENDOR_FROM_DATABASE=Shamrock Tech. Co., Ltd + +usb:v044B* + ID_VENDOR_FROM_DATABASE=WSI + +usb:v044C* + ID_VENDOR_FROM_DATABASE=CCL/ITRI + +usb:v044D* + ID_VENDOR_FROM_DATABASE=Siemens Nixdorf AG + +usb:v044E* + ID_VENDOR_FROM_DATABASE=Alps Electric Co., Ltd + +usb:v044Ep1104* + ID_PRODUCT_FROM_DATABASE=Japanese Keyboard + +usb:v044Ep2002* + ID_PRODUCT_FROM_DATABASE=MD-5500 Printer + +usb:v044Ep2014* + ID_PRODUCT_FROM_DATABASE=Bluetooth Device + +usb:v044Ep3001* + ID_PRODUCT_FROM_DATABASE=UGTZ4 Bluetooth + +usb:v044Ep3002* + ID_PRODUCT_FROM_DATABASE=Bluetooth Device + +usb:v044Ep3003* + ID_PRODUCT_FROM_DATABASE=Bluetooth Device + +usb:v044Ep3004* + ID_PRODUCT_FROM_DATABASE=Bluetooth Adapter + +usb:v044Ep3005* + ID_PRODUCT_FROM_DATABASE=Integrated Bluetooth Device + +usb:v044Ep3006* + ID_PRODUCT_FROM_DATABASE=Bluetooth Adapter + +usb:v044Ep3007* + ID_PRODUCT_FROM_DATABASE=Bluetooth Controller (ALPS/UGX) + +usb:v044Ep300C* + ID_PRODUCT_FROM_DATABASE=Bluetooth Controller (ALPS/UGPZ6) + +usb:v044Ep300D* + ID_PRODUCT_FROM_DATABASE=Bluetooth Controller (ALPS/UGPZ6) + +usb:v044Ep3010* + ID_PRODUCT_FROM_DATABASE=Bluetooth Adapter + +usb:v044Ep3017* + ID_PRODUCT_FROM_DATABASE=BCM2046 Bluetooth Device + +usb:v044EpFFFF* + ID_PRODUCT_FROM_DATABASE=Compaq Bluetooth Multiport Module + +usb:v044F* + ID_VENDOR_FROM_DATABASE=ThrustMaster, Inc. + +usb:v044Fp0400* + ID_PRODUCT_FROM_DATABASE=HOTAS Cougar + +usb:v044FpA003* + ID_PRODUCT_FROM_DATABASE=Rage 3D Game Pad + +usb:v044FpA01B* + ID_PRODUCT_FROM_DATABASE=PK-GP301 Driving Wheel + +usb:v044FpA0A0* + ID_PRODUCT_FROM_DATABASE=Top Gun Joystick + +usb:v044FpA0A1* + ID_PRODUCT_FROM_DATABASE=Top Gun Joystick (rev2) + +usb:v044FpA0A3* + ID_PRODUCT_FROM_DATABASE=Fusion Digital GamePad + +usb:v044FpA201* + ID_PRODUCT_FROM_DATABASE=PK-GP201 PlayStick + +usb:v044FpB10A* + ID_PRODUCT_FROM_DATABASE=T.16000M Joystick + +usb:v044FpB203* + ID_PRODUCT_FROM_DATABASE=360 Modena Pro Wheel + +usb:v044FpB300* + ID_PRODUCT_FROM_DATABASE=Firestorm Dual Power + +usb:v044FpB304* + ID_PRODUCT_FROM_DATABASE=Firestorm Dual Power + +usb:v044FpB307* + ID_PRODUCT_FROM_DATABASE=vibrating Upad + +usb:v044FpB30B* + ID_PRODUCT_FROM_DATABASE=Wireless VibrationPad + +usb:v044FpB315* + ID_PRODUCT_FROM_DATABASE=Firestorm Dual Analog 3 + +usb:v044FpB323* + ID_PRODUCT_FROM_DATABASE=Dual Trigger 3-in-1 (PC Mode) + +usb:v044FpB324* + ID_PRODUCT_FROM_DATABASE=Dual Trigger 3-in-1 (PS3 Mode) + +usb:v044FpB603* + ID_PRODUCT_FROM_DATABASE=force feedback Wheel + +usb:v044FpB605* + ID_PRODUCT_FROM_DATABASE=force feedback Racing Wheel + +usb:v044FpB651* + ID_PRODUCT_FROM_DATABASE=Ferrari GT Rumble Force Wheel + +usb:v044FpB653* + ID_PRODUCT_FROM_DATABASE=RGT Force Feedback Clutch Racing Wheel + +usb:v044FpB654* + ID_PRODUCT_FROM_DATABASE=Ferrari GT Force Feedback Wheel + +usb:v044FpB700* + ID_PRODUCT_FROM_DATABASE=Tacticalboard + +usb:v0450* + ID_VENDOR_FROM_DATABASE=DFI, Inc. + +usb:v0451* + ID_VENDOR_FROM_DATABASE=Texas Instruments, Inc. + +usb:v0451p1234* + ID_PRODUCT_FROM_DATABASE=Bluetooth Device + +usb:v0451p1428* + ID_PRODUCT_FROM_DATABASE=Hub + +usb:v0451p1446* + ID_PRODUCT_FROM_DATABASE=TUSB2040/2070 Hub + +usb:v0451p16A6* + ID_PRODUCT_FROM_DATABASE=BM-USBD1 BlueRobin RF heart rate sensor receiver + +usb:v0451p2036* + ID_PRODUCT_FROM_DATABASE=TUSB2036 Hub + +usb:v0451p2046* + ID_PRODUCT_FROM_DATABASE=TUSB2046 Hub + +usb:v0451p2077* + ID_PRODUCT_FROM_DATABASE=TUSB2077 Hub + +usb:v0451p3410* + ID_PRODUCT_FROM_DATABASE=TUSB3410 Microcontroller + +usb:v0451p3F00* + ID_PRODUCT_FROM_DATABASE=OMAP1610 + +usb:v0451p3F02* + ID_PRODUCT_FROM_DATABASE=SMC WSKP100 Wi-Fi Phone + +usb:v0451p5409* + ID_PRODUCT_FROM_DATABASE=Frontier Labs NEX IA+ Digital Audio Player + +usb:v0451p6000* + ID_PRODUCT_FROM_DATABASE=AU5 ADSL Modem (pre-reenum) + +usb:v0451p6001* + ID_PRODUCT_FROM_DATABASE=AU5 ADSL Modem + +usb:v0451p6060* + ID_PRODUCT_FROM_DATABASE=RNDIS/BeWAN ADSL2+ + +usb:v0451p6070* + ID_PRODUCT_FROM_DATABASE=RNDIS/BeWAN ADSL2+ + +usb:v0451p625F* + ID_PRODUCT_FROM_DATABASE=TUSB6250 ATA Bridge + +usb:v0451p8042* + ID_PRODUCT_FROM_DATABASE=Hub + +usb:v0451pDBC0* + ID_PRODUCT_FROM_DATABASE=Device Bay Controller + +usb:v0451pE001* + ID_PRODUCT_FROM_DATABASE=GraphLink + +usb:v0451pE003* + ID_PRODUCT_FROM_DATABASE=TI-84 Plus Calculator + +usb:v0451pE004* + ID_PRODUCT_FROM_DATABASE=TI-89 Titanium Calculator + +usb:v0451pE008* + ID_PRODUCT_FROM_DATABASE=TI-84 Plus Silver Calculator + +usb:v0451pF430* + ID_PRODUCT_FROM_DATABASE=MSP-FET430UIF JTAG Tool + +usb:v0451pF432* + ID_PRODUCT_FROM_DATABASE=eZ430 Development Tool + +usb:v0451pFFFF* + ID_PRODUCT_FROM_DATABASE=Bluetooth Device + +usb:v0452* + ID_VENDOR_FROM_DATABASE=Mitsubishi Electronics America, Inc. + +usb:v0452p0021* + ID_PRODUCT_FROM_DATABASE=HID Monitor Controls + +usb:v0452p0050* + ID_PRODUCT_FROM_DATABASE=Diamond Pro 900u CRT Monitor + +usb:v0452p0051* + ID_PRODUCT_FROM_DATABASE=Integrated Hub + +usb:v0453* + ID_VENDOR_FROM_DATABASE=CMD Technology + +usb:v0453p6781* + ID_PRODUCT_FROM_DATABASE=NMB Keyboard + +usb:v0453p6783* + ID_PRODUCT_FROM_DATABASE=Chicony Composite Keyboard + +usb:v0454* + ID_VENDOR_FROM_DATABASE=Vobis Microcomputer AG + +usb:v0455* + ID_VENDOR_FROM_DATABASE=Telematics International, Inc. + +usb:v0456* + ID_VENDOR_FROM_DATABASE=Analog Devices, Inc. + +usb:v0456pF000* + ID_PRODUCT_FROM_DATABASE=FT2232 JTAG ICE [gnICE] + +usb:v0456pF001* + ID_PRODUCT_FROM_DATABASE=FT2232H Hi-Speed JTAG ICE [gnICE+] + +usb:v0457* + ID_VENDOR_FROM_DATABASE=Silicon Integrated Systems Corp. + +usb:v0457p0150* + ID_PRODUCT_FROM_DATABASE=Super Talent 1GB Flash Drive + +usb:v0457p0151* + ID_PRODUCT_FROM_DATABASE=Super Flash 1GB / GXT 64MB Flash Drive + +usb:v0457p0162* + ID_PRODUCT_FROM_DATABASE=SiS162 usb Wireless LAN Adapter + +usb:v0457p0163* + ID_PRODUCT_FROM_DATABASE=802.11 Wireless LAN Adapter + +usb:v0457p5401* + ID_PRODUCT_FROM_DATABASE=Wireless Adapter RO80211GS-USB + +usb:v0458* + ID_VENDOR_FROM_DATABASE=KYE Systems Corp. (Mouse Systems) + +usb:v0458p0001* + ID_PRODUCT_FROM_DATABASE=Mouse + +usb:v0458p0002* + ID_PRODUCT_FROM_DATABASE=Genius NetMouse Pro + +usb:v0458p0003* + ID_PRODUCT_FROM_DATABASE=Genius NetScroll+ + +usb:v0458p0006* + ID_PRODUCT_FROM_DATABASE=Easy Mouse+ + +usb:v0458p000B* + ID_PRODUCT_FROM_DATABASE=NetMouse Wheel(P+U) + +usb:v0458p000C* + ID_PRODUCT_FROM_DATABASE=TACOMA Fingerprint V1.06.01 + +usb:v0458p000E* + ID_PRODUCT_FROM_DATABASE=VideoCAM Web + +usb:v0458p0013* + ID_PRODUCT_FROM_DATABASE=TACOMA Fingerprint Mouse V1.06.01 + +usb:v0458p001A* + ID_PRODUCT_FROM_DATABASE=Genius WebScroll+ + +usb:v0458p0036* + ID_PRODUCT_FROM_DATABASE=Pocket Mouse LE + +usb:v0458p0039* + ID_PRODUCT_FROM_DATABASE=NetScroll+ Superior + +usb:v0458p003A* + ID_PRODUCT_FROM_DATABASE=NetScroll+ Mini Traveler / Genius NetScroll 120 + +usb:v0458p004C* + ID_PRODUCT_FROM_DATABASE=Slimstar Pro Keyboard + +usb:v0458p0056* + ID_PRODUCT_FROM_DATABASE=Ergo 300 Mouse + +usb:v0458p0057* + ID_PRODUCT_FROM_DATABASE=Enhanced Gaming Device + +usb:v0458p0059* + ID_PRODUCT_FROM_DATABASE=Enhanced Laser Device + +usb:v0458p005A* + ID_PRODUCT_FROM_DATABASE=Enhanced Device + +usb:v0458p005B* + ID_PRODUCT_FROM_DATABASE=Enhanced Device + +usb:v0458p005C* + ID_PRODUCT_FROM_DATABASE=Enhanced Laser Gaming Device + +usb:v0458p005D* + ID_PRODUCT_FROM_DATABASE=Enhanced Device + +usb:v0458p0061* + ID_PRODUCT_FROM_DATABASE=Bluetooth Dongle + +usb:v0458p0066* + ID_PRODUCT_FROM_DATABASE=Genius Traveler 1000 Wireless Mouse + +usb:v0458p0072* + ID_PRODUCT_FROM_DATABASE=Navigator 335 + +usb:v0458p0083* + ID_PRODUCT_FROM_DATABASE=Bluetooth Dongle + +usb:v0458p0087* + ID_PRODUCT_FROM_DATABASE=Ergo 525V Laser Mouse + +usb:v0458p0100* + ID_PRODUCT_FROM_DATABASE=EasyPen Tablet + +usb:v0458p0101* + ID_PRODUCT_FROM_DATABASE=CueCat + +usb:v0458p011B* + ID_PRODUCT_FROM_DATABASE=NetScroll T220 + +usb:v0458p1001* + ID_PRODUCT_FROM_DATABASE=Joystick + +usb:v0458p1002* + ID_PRODUCT_FROM_DATABASE=Game Pad + +usb:v0458p1003* + ID_PRODUCT_FROM_DATABASE=Genius VideoCam + +usb:v0458p1004* + ID_PRODUCT_FROM_DATABASE=Flight2000 F-23 Joystick + +usb:v0458p100A* + ID_PRODUCT_FROM_DATABASE=Aashima Technology Trust Sight Fighter Vibration Feedback Joystick + +usb:v0458p2001* + ID_PRODUCT_FROM_DATABASE=ColorPage-Vivid Pro Scanner + +usb:v0458p2004* + ID_PRODUCT_FROM_DATABASE=ColorPage-HR6 V1 Scanner + +usb:v0458p2005* + ID_PRODUCT_FROM_DATABASE=ColorPage-HR6/Vivid3 + +usb:v0458p2007* + ID_PRODUCT_FROM_DATABASE=ColorPage-HR6 V2 Scanner + +usb:v0458p2008* + ID_PRODUCT_FROM_DATABASE=ColorPage-HR6 V2 Scanner + +usb:v0458p2009* + ID_PRODUCT_FROM_DATABASE=ColorPage-HR6A Scanner + +usb:v0458p2011* + ID_PRODUCT_FROM_DATABASE=ColorPage-Vivid3x Scanner + +usb:v0458p2012* + ID_PRODUCT_FROM_DATABASE=Plustek Scanner + +usb:v0458p2013* + ID_PRODUCT_FROM_DATABASE=ColorPage-HR7 Scanner + +usb:v0458p2014* + ID_PRODUCT_FROM_DATABASE=ColorPage-Vivid4 + +usb:v0458p2015* + ID_PRODUCT_FROM_DATABASE=ColorPage-HR7LE Scanner + +usb:v0458p2016* + ID_PRODUCT_FROM_DATABASE=ColorPage-HR6X Scanner + +usb:v0458p2017* + ID_PRODUCT_FROM_DATABASE=ColorPage-Vivid3xe + +usb:v0458p2018* + ID_PRODUCT_FROM_DATABASE=ColorPage-HR7X + +usb:v0458p2019* + ID_PRODUCT_FROM_DATABASE=ColorPage-HR6X Slim + +usb:v0458p201A* + ID_PRODUCT_FROM_DATABASE=ColorPage-Vivid4xe + +usb:v0458p201B* + ID_PRODUCT_FROM_DATABASE=ColorPage-Vivid4x + +usb:v0458p201C* + ID_PRODUCT_FROM_DATABASE=ColorPage-HR8 + +usb:v0458p201D* + ID_PRODUCT_FROM_DATABASE=ColorPage-Vivid 1200 X + +usb:v0458p201E* + ID_PRODUCT_FROM_DATABASE=ColorPage-Slim 1200 + +usb:v0458p201F* + ID_PRODUCT_FROM_DATABASE=ColorPage-Vivid 1200 XE + +usb:v0458p2020* + ID_PRODUCT_FROM_DATABASE=ColorPage-Slim 1200 USB2 + +usb:v0458p2021* + ID_PRODUCT_FROM_DATABASE=ColorPage-SF600 + +usb:v0458p3017* + ID_PRODUCT_FROM_DATABASE=SPEED WHEEL 3 Vibration + +usb:v0458p3018* + ID_PRODUCT_FROM_DATABASE=Wireless 2.4Ghz Game Pad + +usb:v0458p3019* + ID_PRODUCT_FROM_DATABASE=10-Button USB Joystick with Vibration + +usb:v0458p301A* + ID_PRODUCT_FROM_DATABASE=MaxFire G-12U Vibration + +usb:v0458p301D* + ID_PRODUCT_FROM_DATABASE=Genius MaxFire MiniPad + +usb:v0458p400F* + ID_PRODUCT_FROM_DATABASE=Genius TVGo DVB-T02Q MCE + +usb:v0458p4012* + ID_PRODUCT_FROM_DATABASE=TVGo DVB-T03 [AF9015] + +usb:v0458p5003* + ID_PRODUCT_FROM_DATABASE=G-pen 560 Tablet + +usb:v0458p5004* + ID_PRODUCT_FROM_DATABASE=G-pen Tablet + +usb:v0458p6001* + ID_PRODUCT_FROM_DATABASE=GF3000F Ethernet Adapter + +usb:v0458p7004* + ID_PRODUCT_FROM_DATABASE=VideoCAM Express V2 + +usb:v0458p7006* + ID_PRODUCT_FROM_DATABASE=Dsc 1.3 Smart Camera Device + +usb:v0458p7007* + ID_PRODUCT_FROM_DATABASE=VideoCAM Web + +usb:v0458p7009* + ID_PRODUCT_FROM_DATABASE=G-Shot G312 Still Camera Device + +usb:v0458p700C* + ID_PRODUCT_FROM_DATABASE=VideoCAM Web V3 + +usb:v0458p700D* + ID_PRODUCT_FROM_DATABASE=G-Shot G511 Composite Device + +usb:v0458p700F* + ID_PRODUCT_FROM_DATABASE=VideoCAM Web + +usb:v0458p7012* + ID_PRODUCT_FROM_DATABASE=WebCAM USB2.0 + +usb:v0458p7014* + ID_PRODUCT_FROM_DATABASE=VideoCAM Live V3 + +usb:v0458p701C* + ID_PRODUCT_FROM_DATABASE=G-Shot G512 Still Camera + +usb:v0458p7020* + ID_PRODUCT_FROM_DATABASE=Sim 321C + +usb:v0458p7025* + ID_PRODUCT_FROM_DATABASE=Eye 311Q Camera + +usb:v0458p7029* + ID_PRODUCT_FROM_DATABASE=Genius Look 320s (SN9C201 + HV7131R) + +usb:v0458p702F* + ID_PRODUCT_FROM_DATABASE=Genius Slim 322 + +usb:v0458p7035* + ID_PRODUCT_FROM_DATABASE=i-Look 325T Camera + +usb:v0458p7045* + ID_PRODUCT_FROM_DATABASE=Genius Look 1320 V2 + +usb:v0458p704C* + ID_PRODUCT_FROM_DATABASE=Genius i-Look 1321 + +usb:v0458p704D* + ID_PRODUCT_FROM_DATABASE=Slim 1322AF + +usb:v0458p7055* + ID_PRODUCT_FROM_DATABASE=Slim 2020AF camera + +usb:v0458p705A* + ID_PRODUCT_FROM_DATABASE=Asus USB2.0 Webcam + +usb:v0458p705C* + ID_PRODUCT_FROM_DATABASE=Genius iSlim 1300AF + +usb:v0458p7079* + ID_PRODUCT_FROM_DATABASE=FaceCam 2025R + +usb:v0458p707F* + ID_PRODUCT_FROM_DATABASE=TVGo DVB-T03 [RTL2832] + +usb:v0459* + ID_VENDOR_FROM_DATABASE=Adobe Systems, Inc. + +usb:v045A* + ID_VENDOR_FROM_DATABASE=SONICblue, Inc. + +usb:v045Ap07DA* + ID_PRODUCT_FROM_DATABASE=Supra Express 56K modem + +usb:v045Ap0B4A* + ID_PRODUCT_FROM_DATABASE=SupraMax 2890 56K Modem [Lucent Atlas] + +usb:v045Ap0B68* + ID_PRODUCT_FROM_DATABASE=SupraMax 56K Modem + +usb:v045Ap5001* + ID_PRODUCT_FROM_DATABASE=Rio 600 MP3 Player + +usb:v045Ap5002* + ID_PRODUCT_FROM_DATABASE=Rio 800 MP3 Player + +usb:v045Ap5003* + ID_PRODUCT_FROM_DATABASE=Nike Psa/Play MP3 Player + +usb:v045Ap5005* + ID_PRODUCT_FROM_DATABASE=Rio S10 MP3 Player + +usb:v045Ap5006* + ID_PRODUCT_FROM_DATABASE=Rio S50 MP3 Player + +usb:v045Ap5007* + ID_PRODUCT_FROM_DATABASE=Rio S35 MP3 Player + +usb:v045Ap5008* + ID_PRODUCT_FROM_DATABASE=Rio 900 MP3 Player + +usb:v045Ap5009* + ID_PRODUCT_FROM_DATABASE=Rio S30 MP3 Player + +usb:v045Ap500D* + ID_PRODUCT_FROM_DATABASE=Fuse MP3 Player + +usb:v045Ap500E* + ID_PRODUCT_FROM_DATABASE=Chiba MP3 Player + +usb:v045Ap500F* + ID_PRODUCT_FROM_DATABASE=Cali MP3 Player + +usb:v045Ap5010* + ID_PRODUCT_FROM_DATABASE=Rio S11 MP3 Player + +usb:v045Ap501C* + ID_PRODUCT_FROM_DATABASE=Virgin MPF-1000 + +usb:v045Ap501D* + ID_PRODUCT_FROM_DATABASE=Rio Fuse + +usb:v045Ap501E* + ID_PRODUCT_FROM_DATABASE=Rio Chiba + +usb:v045Ap501F* + ID_PRODUCT_FROM_DATABASE=Rio Cali + +usb:v045Ap503F* + ID_PRODUCT_FROM_DATABASE=Cali256 MP3 Player + +usb:v045Ap5202* + ID_PRODUCT_FROM_DATABASE=Rio Riot MP3 Player + +usb:v045Ap5210* + ID_PRODUCT_FROM_DATABASE=Rio Karma Music Player + +usb:v045Ap5220* + ID_PRODUCT_FROM_DATABASE=Rio Nitrus MP3 Player + +usb:v045Ap5221* + ID_PRODUCT_FROM_DATABASE=Rio Eigen + +usb:v045B* + ID_VENDOR_FROM_DATABASE=Hitachi, Ltd + +usb:v045Bp0053* + ID_PRODUCT_FROM_DATABASE=RX610 RX-Stick + +usb:v045D* + ID_VENDOR_FROM_DATABASE=Nortel Networks, Ltd + +usb:v045E* + ID_VENDOR_FROM_DATABASE=Microsoft Corp. + +usb:v045Ep0007* + ID_PRODUCT_FROM_DATABASE=SideWinder Game Pad + +usb:v045Ep0008* + ID_PRODUCT_FROM_DATABASE=SideWinder Precision Pro + +usb:v045Ep0009* + ID_PRODUCT_FROM_DATABASE=IntelliMouse + +usb:v045Ep000B* + ID_PRODUCT_FROM_DATABASE=Natural Keyboard Elite + +usb:v045Ep000E* + ID_PRODUCT_FROM_DATABASE=SideWinder® Freestyle Pro + +usb:v045Ep0014* + ID_PRODUCT_FROM_DATABASE=Digital Sound System 80 + +usb:v045Ep001A* + ID_PRODUCT_FROM_DATABASE=SideWinder Precision Racing Wheel + +usb:v045Ep001B* + ID_PRODUCT_FROM_DATABASE=SideWinder Force Feedback 2 Joystick + +usb:v045Ep001C* + ID_PRODUCT_FROM_DATABASE=Internet Keyboard Pro + +usb:v045Ep001D* + ID_PRODUCT_FROM_DATABASE=Natural Keyboard Pro + +usb:v045Ep001E* + ID_PRODUCT_FROM_DATABASE=IntelliMouse Explorer + +usb:v045Ep0023* + ID_PRODUCT_FROM_DATABASE=Trackball Optical + +usb:v045Ep0024* + ID_PRODUCT_FROM_DATABASE=Trackball Explorer + +usb:v045Ep0025* + ID_PRODUCT_FROM_DATABASE=IntelliEye Mouse + +usb:v045Ep0026* + ID_PRODUCT_FROM_DATABASE=SideWinder GamePad Pro + +usb:v045Ep0027* + ID_PRODUCT_FROM_DATABASE=SideWinder PnP GamePad + +usb:v045Ep0028* + ID_PRODUCT_FROM_DATABASE=SideWinder Dual Strike + +usb:v045Ep0029* + ID_PRODUCT_FROM_DATABASE=IntelliMouse Optical + +usb:v045Ep002B* + ID_PRODUCT_FROM_DATABASE=Internet Keyboard Pro + +usb:v045Ep002D* + ID_PRODUCT_FROM_DATABASE=Internet Keyboard + +usb:v045Ep002F* + ID_PRODUCT_FROM_DATABASE=Integrated Hub + +usb:v045Ep0033* + ID_PRODUCT_FROM_DATABASE=Sidewinder Strategic Commander + +usb:v045Ep0034* + ID_PRODUCT_FROM_DATABASE=SideWinder Force Feedback Wheel + +usb:v045Ep0038* + ID_PRODUCT_FROM_DATABASE=SideWinder Precision 2 + +usb:v045Ep0039* + ID_PRODUCT_FROM_DATABASE=IntelliMouse Optical + +usb:v045Ep003B* + ID_PRODUCT_FROM_DATABASE=SideWinder Game Voice + +usb:v045Ep003C* + ID_PRODUCT_FROM_DATABASE=SideWinder Joystick + +usb:v045Ep0040* + ID_PRODUCT_FROM_DATABASE=Wheel Mouse Optical + +usb:v045Ep0047* + ID_PRODUCT_FROM_DATABASE=IntelliMouse Explorer 3.0 + +usb:v045Ep0048* + ID_PRODUCT_FROM_DATABASE=Office Keyboard 1.0A + +usb:v045Ep0053* + ID_PRODUCT_FROM_DATABASE=Optical Mouse + +usb:v045Ep0059* + ID_PRODUCT_FROM_DATABASE=Wireless IntelliMouse Explorer + +usb:v045Ep005C* + ID_PRODUCT_FROM_DATABASE=Office Keyboard (106/109) + +usb:v045Ep005F* + ID_PRODUCT_FROM_DATABASE=Wireless MultiMedia Keyboard + +usb:v045Ep0061* + ID_PRODUCT_FROM_DATABASE=Wireless MultiMedia Keyboard (106/109) + +usb:v045Ep0063* + ID_PRODUCT_FROM_DATABASE=Wireless Natural MultiMedia Keyboard + +usb:v045Ep0065* + ID_PRODUCT_FROM_DATABASE=Wireless Natural MultiMedia Keyboard (106/109) + +usb:v045Ep006A* + ID_PRODUCT_FROM_DATABASE=Wireless Optical Mouse (IntelliPoint) + +usb:v045Ep006D* + ID_PRODUCT_FROM_DATABASE=eHome Remote Control Keyboard keys + +usb:v045Ep006E* + ID_PRODUCT_FROM_DATABASE=MN-510 802.11b Wireless Adapter [Intersil ISL3873B] + +usb:v045Ep006F* + ID_PRODUCT_FROM_DATABASE=Smart Display Reference Device + +usb:v045Ep0070* + ID_PRODUCT_FROM_DATABASE=Wireless MultiMedia Keyboard + +usb:v045Ep0071* + ID_PRODUCT_FROM_DATABASE=Wireless MultiMedia Keyboard (106/109) + +usb:v045Ep0072* + ID_PRODUCT_FROM_DATABASE=Wireless Natural MultiMedia Keyboard + +usb:v045Ep0073* + ID_PRODUCT_FROM_DATABASE=Wireless Natural MultiMedia Keyboard (106/109) + +usb:v045Ep0079* + ID_PRODUCT_FROM_DATABASE=IXI Ogo CT-17 handheld device + +usb:v045Ep007A* + ID_PRODUCT_FROM_DATABASE=10/100 USB NIC + +usb:v045Ep007D* + ID_PRODUCT_FROM_DATABASE=Notebook Optical Mouse + +usb:v045Ep007E* + ID_PRODUCT_FROM_DATABASE=Wireless Transceiver for Bluetooth + +usb:v045Ep0080* + ID_PRODUCT_FROM_DATABASE=Digital Media Pro Keyboard + +usb:v045Ep0083* + ID_PRODUCT_FROM_DATABASE=Basic Optical Mouse + +usb:v045Ep0084* + ID_PRODUCT_FROM_DATABASE=Basic Optical Mouse + +usb:v045Ep008A* + ID_PRODUCT_FROM_DATABASE=Wireless Keyboard and Mouse + +usb:v045Ep008B* + ID_PRODUCT_FROM_DATABASE=Dual Receiver Wireless Mouse (IntelliPoint) + +usb:v045Ep008C* + ID_PRODUCT_FROM_DATABASE=Wireless Intellimouse Explorer 2.0 + +usb:v045Ep0095* + ID_PRODUCT_FROM_DATABASE=IntelliMouse Explorer 4.0 (IntelliPoint) + +usb:v045Ep009C* + ID_PRODUCT_FROM_DATABASE=Wireless Transceiver for Bluetooth 2.0 + +usb:v045Ep009D* + ID_PRODUCT_FROM_DATABASE=Wireless Optical Desktop 3.0 + +usb:v045Ep00A0* + ID_PRODUCT_FROM_DATABASE=eHome Infrared Receiver + +usb:v045Ep00A4* + ID_PRODUCT_FROM_DATABASE=Compact Optical Mouse, model 1016 + +usb:v045Ep00B0* + ID_PRODUCT_FROM_DATABASE=Digital Media Pro Keyboard + +usb:v045Ep00B4* + ID_PRODUCT_FROM_DATABASE=Digital Media Keyboard 1.0A + +usb:v045Ep00B9* + ID_PRODUCT_FROM_DATABASE=Wireless Optical Mouse 3.0 + +usb:v045Ep00BB* + ID_PRODUCT_FROM_DATABASE=Fingerprint Reader + +usb:v045Ep00BC* + ID_PRODUCT_FROM_DATABASE=Fingerprint Reader + +usb:v045Ep00BD* + ID_PRODUCT_FROM_DATABASE=Fingerprint Reader + +usb:v045Ep00C2* + ID_PRODUCT_FROM_DATABASE=MN-710 802.11g Wireless Adapter [Intersil ISL3886] + +usb:v045Ep00C9* + ID_PRODUCT_FROM_DATABASE=MTP Device + +usb:v045Ep00CA* + ID_PRODUCT_FROM_DATABASE=Fingerprint Reader + +usb:v045Ep00CB* + ID_PRODUCT_FROM_DATABASE=Basic Optical Mouse v2.0 + +usb:v045Ep00CE* + ID_PRODUCT_FROM_DATABASE=Generic PPC Flash device + +usb:v045Ep00D1* + ID_PRODUCT_FROM_DATABASE=Optical Mouse with Tilt Wheel + +usb:v045Ep00DA* + ID_PRODUCT_FROM_DATABASE=eHome Infrared Receiver + +usb:v045Ep00DB* + ID_PRODUCT_FROM_DATABASE=Natural Ergonomic Keyboard 4000 V1.0 + +usb:v045Ep00DD* + ID_PRODUCT_FROM_DATABASE=Comfort Curve Keyboard 2000 V1.0 + +usb:v045Ep00E1* + ID_PRODUCT_FROM_DATABASE=Wireless Laser Mouse 6000 Reciever + +usb:v045Ep00F4* + ID_PRODUCT_FROM_DATABASE=LifeCam VX-6000 (SN9C20x + OV9650) + +usb:v045Ep00F5* + ID_PRODUCT_FROM_DATABASE=LifeCam VX-3000 + +usb:v045Ep00F6* + ID_PRODUCT_FROM_DATABASE=Comfort Optical Mouse 1000 + +usb:v045Ep00F7* + ID_PRODUCT_FROM_DATABASE=LifeCam VX-1000 + +usb:v045Ep00F8* + ID_PRODUCT_FROM_DATABASE=LifeCam NX-6000 + +usb:v045Ep00F9* + ID_PRODUCT_FROM_DATABASE=Wireless Desktop Receiver 3.1 + +usb:v045Ep0202* + ID_PRODUCT_FROM_DATABASE=Xbox Controller + +usb:v045Ep0280* + ID_PRODUCT_FROM_DATABASE=XBox Device + +usb:v045Ep0283* + ID_PRODUCT_FROM_DATABASE=Xbox Communicator + +usb:v045Ep0284* + ID_PRODUCT_FROM_DATABASE=Xbox DVD Playback Kit + +usb:v045Ep0285* + ID_PRODUCT_FROM_DATABASE=Xbox Controller S + +usb:v045Ep0288* + ID_PRODUCT_FROM_DATABASE=Xbox Controller S Hub + +usb:v045Ep0289* + ID_PRODUCT_FROM_DATABASE=Xbox Controller S + +usb:v045Ep028B* + ID_PRODUCT_FROM_DATABASE=Xbox360 DVD Emulator + +usb:v045Ep028D* + ID_PRODUCT_FROM_DATABASE=Xbox360 Memory Unit 64MB + +usb:v045Ep028E* + ID_PRODUCT_FROM_DATABASE=Xbox360 Controller + +usb:v045Ep028F* + ID_PRODUCT_FROM_DATABASE=Xbox360 Wireless Controller + +usb:v045Ep0290* + ID_PRODUCT_FROM_DATABASE=Xbox360 Performance Pipe (PIX) + +usb:v045Ep0291* + ID_PRODUCT_FROM_DATABASE=Xbox 360 Wireless Receiver for Windows + +usb:v045Ep0292* + ID_PRODUCT_FROM_DATABASE=Xbox360 Wireless Networking Adapter + +usb:v045Ep029C* + ID_PRODUCT_FROM_DATABASE=Xbox360 HD-DVD Drive + +usb:v045Ep029D* + ID_PRODUCT_FROM_DATABASE=Xbox360 HD-DVD Drive + +usb:v045Ep029E* + ID_PRODUCT_FROM_DATABASE=Xbox360 HD-DVD Memory Unit + +usb:v045Ep02A0* + ID_PRODUCT_FROM_DATABASE=Xbox360 Big Button IR + +usb:v045Ep02A8* + ID_PRODUCT_FROM_DATABASE=Xbox360 Wireless N Networking Adapter [Atheros AR7010+AR9280] + +usb:v045Ep02AD* + ID_PRODUCT_FROM_DATABASE=Xbox NUI Audio + +usb:v045Ep02AE* + ID_PRODUCT_FROM_DATABASE=Xbox NUI Camera + +usb:v045Ep02B0* + ID_PRODUCT_FROM_DATABASE=Xbox NUI Motor + +usb:v045Ep0400* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2002 + +usb:v045Ep0401* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2002 + +usb:v045Ep0402* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2002 + +usb:v045Ep0403* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2002 + +usb:v045Ep0404* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2002 + +usb:v045Ep0405* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2002 + +usb:v045Ep0406* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2002 + +usb:v045Ep0407* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2002 + +usb:v045Ep0408* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2002 + +usb:v045Ep0409* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2002 + +usb:v045Ep040A* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2002 + +usb:v045Ep040B* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2002 + +usb:v045Ep040C* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2002 + +usb:v045Ep040D* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2002 + +usb:v045Ep040E* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2002 + +usb:v045Ep040F* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2002 + +usb:v045Ep0410* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2002 + +usb:v045Ep0411* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2002 + +usb:v045Ep0412* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2002 + +usb:v045Ep0413* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2002 + +usb:v045Ep0414* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2002 + +usb:v045Ep0415* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2002 + +usb:v045Ep0416* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2002 + +usb:v045Ep0417* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2002 + +usb:v045Ep0432* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep0433* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep0434* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep0435* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep0436* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep0437* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep0438* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep0439* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep043A* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep043B* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep043C* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep043D* + ID_PRODUCT_FROM_DATABASE=Becker Traffic Assist Highspeed 7934 + +usb:v045Ep043E* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep043F* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep0440* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep0441* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep0442* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep0443* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep0444* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep0445* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep0446* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep0447* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep0448* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep0449* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep044A* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep044B* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep044C* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep044D* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep044E* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep044F* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep0450* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep0451* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep0452* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep0453* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep0454* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep0455* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep0456* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep0457* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep0458* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep0459* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep045A* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep045B* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep045C* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep045D* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep045E* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep045F* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep0460* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep0461* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep0462* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep0463* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep0464* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep0465* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep0466* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep0467* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep0468* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep0469* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep046A* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep046B* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep046C* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep046D* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep046E* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep046F* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep0470* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep0471* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep0472* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep0473* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep0474* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep0475* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep0476* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep0477* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep0478* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep0479* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep047A* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep047B* + ID_PRODUCT_FROM_DATABASE=Windows Powered Pocket PC 2003 + +usb:v045Ep04C8* + ID_PRODUCT_FROM_DATABASE=Windows Powered Smartphone 2002 + +usb:v045Ep04C9* + ID_PRODUCT_FROM_DATABASE=Windows Powered Smartphone 2002 + +usb:v045Ep04CA* + ID_PRODUCT_FROM_DATABASE=Windows Powered Smartphone 2002 + +usb:v045Ep04CB* + ID_PRODUCT_FROM_DATABASE=Windows Powered Smartphone 2002 + +usb:v045Ep04CC* + ID_PRODUCT_FROM_DATABASE=Windows Powered Smartphone 2002 + +usb:v045Ep04CD* + ID_PRODUCT_FROM_DATABASE=Windows Powered Smartphone 2002 + +usb:v045Ep04CE* + ID_PRODUCT_FROM_DATABASE=Windows Powered Smartphone 2002 + +usb:v045Ep04D7* + ID_PRODUCT_FROM_DATABASE=Windows Powered Smartphone 2003 + +usb:v045Ep04D8* + ID_PRODUCT_FROM_DATABASE=Windows Powered Smartphone 2003 + +usb:v045Ep04D9* + ID_PRODUCT_FROM_DATABASE=Windows Powered Smartphone 2003 + +usb:v045Ep04DA* + ID_PRODUCT_FROM_DATABASE=Windows Powered Smartphone 2003 + +usb:v045Ep04DB* + ID_PRODUCT_FROM_DATABASE=Windows Powered Smartphone 2003 + +usb:v045Ep04DC* + ID_PRODUCT_FROM_DATABASE=Windows Powered Smartphone 2003 + +usb:v045Ep04DD* + ID_PRODUCT_FROM_DATABASE=Windows Powered Smartphone 2003 + +usb:v045Ep04DE* + ID_PRODUCT_FROM_DATABASE=Windows Powered Smartphone 2003 + +usb:v045Ep04DF* + ID_PRODUCT_FROM_DATABASE=Windows Powered Smartphone 2003 + +usb:v045Ep04E0* + ID_PRODUCT_FROM_DATABASE=Windows Powered Smartphone 2003 + +usb:v045Ep04E1* + ID_PRODUCT_FROM_DATABASE=Windows Powered Smartphone 2003 + +usb:v045Ep04E2* + ID_PRODUCT_FROM_DATABASE=Windows Powered Smartphone 2003 + +usb:v045Ep04E3* + ID_PRODUCT_FROM_DATABASE=Windows Powered Smartphone 2003 + +usb:v045Ep04E4* + ID_PRODUCT_FROM_DATABASE=Windows Powered Smartphone 2003 + +usb:v045Ep04E5* + ID_PRODUCT_FROM_DATABASE=Windows Powered Smartphone 2003 + +usb:v045Ep04E6* + ID_PRODUCT_FROM_DATABASE=Windows Powered Smartphone 2003 + +usb:v045Ep04E7* + ID_PRODUCT_FROM_DATABASE=Windows Powered Smartphone 2003 + +usb:v045Ep04E8* + ID_PRODUCT_FROM_DATABASE=Windows Powered Smartphone 2003 + +usb:v045Ep04E9* + ID_PRODUCT_FROM_DATABASE=Windows Powered Smartphone 2003 + +usb:v045Ep04EA* + ID_PRODUCT_FROM_DATABASE=Windows Powered Smartphone 2003 + +usb:v045Ep04EC* + ID_PRODUCT_FROM_DATABASE=Windows Phone (Zune) + +usb:v045Ep063E* + ID_PRODUCT_FROM_DATABASE=Zune HD Media Player + +usb:v045Ep0640* + ID_PRODUCT_FROM_DATABASE=KIN Phone + +usb:v045Ep0641* + ID_PRODUCT_FROM_DATABASE=KIN Phone + +usb:v045Ep0642* + ID_PRODUCT_FROM_DATABASE=KIN Phone + +usb:v045Ep0707* + ID_PRODUCT_FROM_DATABASE=Wireless Laser Mouse 8000 + +usb:v045Ep0708* + ID_PRODUCT_FROM_DATABASE=Transceiver v 3.0 for Bluetooth + +usb:v045Ep070A* + ID_PRODUCT_FROM_DATABASE=Charon Bluetooth Dongle (DFU) + +usb:v045Ep0710* + ID_PRODUCT_FROM_DATABASE=Zune Media Player + +usb:v045Ep0713* + ID_PRODUCT_FROM_DATABASE=Wireless Presenter Mouse 8000 + +usb:v045Ep0719* + ID_PRODUCT_FROM_DATABASE=Xbox 360 Wireless Adapter + +usb:v045Ep071F* + ID_PRODUCT_FROM_DATABASE=Mouse/Keyboard 2.4GHz Transceiver V2.0 + +usb:v045Ep0721* + ID_PRODUCT_FROM_DATABASE=LifeCam NX-3000 (UVC-compliant) + +usb:v045Ep0723* + ID_PRODUCT_FROM_DATABASE=LifeCam VX-7000 (UVC-compliant) + +usb:v045Ep0724* + ID_PRODUCT_FROM_DATABASE=SideWinder Mouse + +usb:v045Ep0730* + ID_PRODUCT_FROM_DATABASE=Digital Media Keyboard 3000 + +usb:v045Ep0734* + ID_PRODUCT_FROM_DATABASE=Wireless Optical Desktop 700 + +usb:v045Ep0736* + ID_PRODUCT_FROM_DATABASE=Sidewinder X5 Mouse + +usb:v045Ep0737* + ID_PRODUCT_FROM_DATABASE=Compact Optical Mouse 500 + +usb:v045Ep0745* + ID_PRODUCT_FROM_DATABASE=Nano Transceiver v1.0 for Bluetooth + +usb:v045Ep0750* + ID_PRODUCT_FROM_DATABASE=Wired Keyboard 600 + +usb:v045Ep0752* + ID_PRODUCT_FROM_DATABASE=Wired Keyboard 400 + +usb:v045Ep075D* + ID_PRODUCT_FROM_DATABASE=LifeCam Cinema + +usb:v045Ep0766* + ID_PRODUCT_FROM_DATABASE=LifeCam VX-800 + +usb:v045Ep0768* + ID_PRODUCT_FROM_DATABASE=Sidewinder X4 + +usb:v045Ep076D* + ID_PRODUCT_FROM_DATABASE=LifeCam HD-5000 + +usb:v045Ep0772* + ID_PRODUCT_FROM_DATABASE=LifeCam Studio + +usb:v045Ep0779* + ID_PRODUCT_FROM_DATABASE=LifeCam HD-3000 + +usb:v045Ep930A* + ID_PRODUCT_FROM_DATABASE=ISOUSB.SYS Intel 82930 Isochronous IO Test Board + +usb:v045EpFFF8* + ID_PRODUCT_FROM_DATABASE=Keyboard + +usb:v045EpFFFF* + ID_PRODUCT_FROM_DATABASE=Windows CE Mass Storage + +usb:v0460* + ID_VENDOR_FROM_DATABASE=Ace Cad Enterprise Co., Ltd + +usb:v0460p0004* + ID_PRODUCT_FROM_DATABASE=Tablet (5x3.75) + +usb:v0460p0006* + ID_PRODUCT_FROM_DATABASE=LCD Tablet (12x9) + +usb:v0460p0008* + ID_PRODUCT_FROM_DATABASE=Tablet (3x2.25) + +usb:v0461* + ID_VENDOR_FROM_DATABASE=Primax Electronics, Ltd + +usb:v0461p0010* + ID_PRODUCT_FROM_DATABASE=HP Keyboard + +usb:v0461p0300* + ID_PRODUCT_FROM_DATABASE=G2-300 Scanner + +usb:v0461p0301* + ID_PRODUCT_FROM_DATABASE=G2E-300 Scanner + +usb:v0461p0302* + ID_PRODUCT_FROM_DATABASE=G2-300 #2 Scanner + +usb:v0461p0303* + ID_PRODUCT_FROM_DATABASE=G2E-300 #2 Scanner + +usb:v0461p0340* + ID_PRODUCT_FROM_DATABASE=Colorado 9600 Scanner + +usb:v0461p0341* + ID_PRODUCT_FROM_DATABASE=Colorado 600u Scanner + +usb:v0461p0345* + ID_PRODUCT_FROM_DATABASE=Visioneer 6200 Scanner + +usb:v0461p0346* + ID_PRODUCT_FROM_DATABASE=Memorex Maxx 6136u Scanner + +usb:v0461p0347* + ID_PRODUCT_FROM_DATABASE=Primascan Colorado 2600u/Visioneer 4400 Scanner + +usb:v0461p0360* + ID_PRODUCT_FROM_DATABASE=Colorado 19200 Scanner + +usb:v0461p0361* + ID_PRODUCT_FROM_DATABASE=Colorado 1200u Scanner + +usb:v0461p0363* + ID_PRODUCT_FROM_DATABASE=VistaScan Astra 3600(ENG) + +usb:v0461p0364* + ID_PRODUCT_FROM_DATABASE=LG Electronics Scanworks 600U Scanner + +usb:v0461p0365* + ID_PRODUCT_FROM_DATABASE=VistaScan Astra 3600(ENG) + +usb:v0461p0366* + ID_PRODUCT_FROM_DATABASE=6400 + +usb:v0461p0367* + ID_PRODUCT_FROM_DATABASE=VistaScan Astra 3600(ENG) + +usb:v0461p0371* + ID_PRODUCT_FROM_DATABASE=Visioneer Onetouch 8920 Scanner + +usb:v0461p0374* + ID_PRODUCT_FROM_DATABASE=UMAX Astra 2500 + +usb:v0461p0375* + ID_PRODUCT_FROM_DATABASE=VistaScan Astra 3600(ENG) + +usb:v0461p0377* + ID_PRODUCT_FROM_DATABASE=Medion MD 5345 Scanner + +usb:v0461p0378* + ID_PRODUCT_FROM_DATABASE=VistaScan Astra 3600(ENG) + +usb:v0461p037B* + ID_PRODUCT_FROM_DATABASE=Medion MD 6190 Scanner + +usb:v0461p037C* + ID_PRODUCT_FROM_DATABASE=VistaScan Astra 3600(ENG) + +usb:v0461p0380* + ID_PRODUCT_FROM_DATABASE=G2-600 Scanner + +usb:v0461p0381* + ID_PRODUCT_FROM_DATABASE=ReadyScan 636i Scanner + +usb:v0461p0382* + ID_PRODUCT_FROM_DATABASE=G2-600 #2 Scanner + +usb:v0461p0383* + ID_PRODUCT_FROM_DATABASE=G2E-600 Scanner + +usb:v0461p038A* + ID_PRODUCT_FROM_DATABASE=UMAX Astra 3000/3600 + +usb:v0461p038B* + ID_PRODUCT_FROM_DATABASE=Xerox 2400 Onetouch + +usb:v0461p038C* + ID_PRODUCT_FROM_DATABASE=UMAX Astra 4100 + +usb:v0461p0392* + ID_PRODUCT_FROM_DATABASE=Medion/Lifetec/Tevion/Cytron MD 6190 + +usb:v0461p03A8* + ID_PRODUCT_FROM_DATABASE=9420M + +usb:v0461p0813* + ID_PRODUCT_FROM_DATABASE=IBM UltraPort Camera + +usb:v0461p0815* + ID_PRODUCT_FROM_DATABASE=Micro Innovations IC200 Webcam + +usb:v0461p0819* + ID_PRODUCT_FROM_DATABASE=Fujifilm IX-30 Camera [webcam mode] + +usb:v0461p081A* + ID_PRODUCT_FROM_DATABASE=Fujifilm IX-30 Camera [storage mode] + +usb:v0461p081C* + ID_PRODUCT_FROM_DATABASE=Elitegroup ECS-C11 Camera + +usb:v0461p081D* + ID_PRODUCT_FROM_DATABASE=Elitegroup ECS-C11 Storage + +usb:v0461p0A00* + ID_PRODUCT_FROM_DATABASE=Micro Innovations Web Cam 320 + +usb:v0461p4D01* + ID_PRODUCT_FROM_DATABASE=Comfort Keyboard + +usb:v0461p4D02* + ID_PRODUCT_FROM_DATABASE=Mouse-in-a-Box + +usb:v0461p4D03* + ID_PRODUCT_FROM_DATABASE=Kensington Mouse-in-a-box + +usb:v0461p4D04* + ID_PRODUCT_FROM_DATABASE=Mouse + +usb:v0461p4D06* + ID_PRODUCT_FROM_DATABASE=Balless Mouse (HID) + +usb:v0461p4D0F* + ID_PRODUCT_FROM_DATABASE=HP Optical Mouse + +usb:v0461p4D15* + ID_PRODUCT_FROM_DATABASE=Dell Optical Mouse + +usb:v0461p4D17* + ID_PRODUCT_FROM_DATABASE=Optical Mouse + +usb:v0461p4D20* + ID_PRODUCT_FROM_DATABASE=HP Optical Mouse + +usb:v0461p4D2A* + ID_PRODUCT_FROM_DATABASE=PoPo Elixir Mouse (HID) + +usb:v0461p4D2B* + ID_PRODUCT_FROM_DATABASE=Wireless Laser Mini Mouse (HID) + +usb:v0461p4D2C* + ID_PRODUCT_FROM_DATABASE=PoPo Mini Pointer Mouse (HID) + +usb:v0461p4D2E* + ID_PRODUCT_FROM_DATABASE=Optical Mobile Mouse (HID) + +usb:v0461p4D51* + ID_PRODUCT_FROM_DATABASE=0Y357C PMX-MMOCZUL (B) [Dell Laser Mouse] + +usb:v0461p4D75* + ID_PRODUCT_FROM_DATABASE=Rocketfish RF-FLBTAD Bluetooth Adapter + +usb:v0461p4D81* + ID_PRODUCT_FROM_DATABASE=Dell N889 Optical Mouse + +usb:v0461p4DE7* + ID_PRODUCT_FROM_DATABASE=webcam + +usb:v0463* + ID_VENDOR_FROM_DATABASE=MGE UPS Systems + +usb:v0463p0001* + ID_PRODUCT_FROM_DATABASE=UPS + +usb:v0463pFFFF* + ID_PRODUCT_FROM_DATABASE=UPS + +usb:v0464* + ID_VENDOR_FROM_DATABASE=AMP/Tycoelectronics Corp. + +usb:v0467* + ID_VENDOR_FROM_DATABASE=AT&T Paradyne + +usb:v0468* + ID_VENDOR_FROM_DATABASE=Wieson Technologies Co., Ltd + +usb:v046A* + ID_VENDOR_FROM_DATABASE=Cherry GmbH + +usb:v046Ap0001* + ID_PRODUCT_FROM_DATABASE=My3000 Keyboard + +usb:v046Ap0003* + ID_PRODUCT_FROM_DATABASE=My3000 Hub + +usb:v046Ap0004* + ID_PRODUCT_FROM_DATABASE=CyBoard Keyboard + +usb:v046Ap0005* + ID_PRODUCT_FROM_DATABASE=XX33 SmartCard Reader Keyboard + +usb:v046Ap0008* + ID_PRODUCT_FROM_DATABASE=Wireless Keyboard and Mouse + +usb:v046Ap0010* + ID_PRODUCT_FROM_DATABASE=SmartBoard XX44 + +usb:v046Ap0011* + ID_PRODUCT_FROM_DATABASE=G83 (RS 6000) Keyboard + +usb:v046Ap0021* + ID_PRODUCT_FROM_DATABASE=CyMotion Expert Combo + +usb:v046Ap0023* + ID_PRODUCT_FROM_DATABASE=CyMotion Master Linux Keyboard G230 + +usb:v046Ap0027* + ID_PRODUCT_FROM_DATABASE=CyMotion Master Solar Keyboard + +usb:v046Ap002A* + ID_PRODUCT_FROM_DATABASE=Wireless Mouse & Keyboard + +usb:v046Ap002D* + ID_PRODUCT_FROM_DATABASE=SmartTerminal XX44 + +usb:v046Ap003E* + ID_PRODUCT_FROM_DATABASE=SmartTerminal ST-2xxx + +usb:v046Ap0080* + ID_PRODUCT_FROM_DATABASE=eHealth Terminal ST 1503 + +usb:v046Ap0081* + ID_PRODUCT_FROM_DATABASE=eHealth Keyboard G87 1504 + +usb:v046Ap0106* + ID_PRODUCT_FROM_DATABASE=R-300 Wireless Mouse Receiver + +usb:v046B* + ID_VENDOR_FROM_DATABASE=American Megatrends, Inc. + +usb:v046Bp0001* + ID_PRODUCT_FROM_DATABASE=Keyboard + +usb:v046Bp0101* + ID_PRODUCT_FROM_DATABASE=PS/2 Keyboard, Mouse & Joystick Ports + +usb:v046Bp0301* + ID_PRODUCT_FROM_DATABASE=USB 1.0 Hub + +usb:v046Bp0500* + ID_PRODUCT_FROM_DATABASE=Serial & Parallel Ports + +usb:v046BpFF10* + ID_PRODUCT_FROM_DATABASE=Virtual Keyboard and Mouse + +usb:v046C* + ID_VENDOR_FROM_DATABASE=Toshiba Corp., Digital Media Equipment + +usb:v046D* + ID_VENDOR_FROM_DATABASE=Logitech, Inc. + +usb:v046Dp0082* + ID_PRODUCT_FROM_DATABASE=Acer Aspire 5672 Webcam + +usb:v046Dp0200* + ID_PRODUCT_FROM_DATABASE=WingMan Extreme Joystick + +usb:v046Dp0203* + ID_PRODUCT_FROM_DATABASE=M2452 Keyboard + +usb:v046Dp0301* + ID_PRODUCT_FROM_DATABASE=M4848 Mouse + +usb:v046Dp0401* + ID_PRODUCT_FROM_DATABASE=HP PageScan + +usb:v046Dp0402* + ID_PRODUCT_FROM_DATABASE=NEC PageScan + +usb:v046Dp040F* + ID_PRODUCT_FROM_DATABASE=Logitech/Storm PageScan + +usb:v046Dp0430* + ID_PRODUCT_FROM_DATABASE=Mic (Cordless) + +usb:v046Dp0801* + ID_PRODUCT_FROM_DATABASE=QuickCam Home + +usb:v046Dp0802* + ID_PRODUCT_FROM_DATABASE=Webcam C200 + +usb:v046Dp0804* + ID_PRODUCT_FROM_DATABASE=Webcam C250 + +usb:v046Dp0805* + ID_PRODUCT_FROM_DATABASE=Webcam C300 + +usb:v046Dp0807* + ID_PRODUCT_FROM_DATABASE=Webcam B500 + +usb:v046Dp0808* + ID_PRODUCT_FROM_DATABASE=Webcam C600 + +usb:v046Dp0809* + ID_PRODUCT_FROM_DATABASE=Webcam Pro 9000 + +usb:v046Dp080A* + ID_PRODUCT_FROM_DATABASE=Portable Webcam C905 + +usb:v046Dp080F* + ID_PRODUCT_FROM_DATABASE=Webcam C120 + +usb:v046Dp0810* + ID_PRODUCT_FROM_DATABASE=QuickCam Pro + +usb:v046Dp0819* + ID_PRODUCT_FROM_DATABASE=Webcam C210 + +usb:v046Dp081B* + ID_PRODUCT_FROM_DATABASE=Webcam C310 + +usb:v046Dp081D* + ID_PRODUCT_FROM_DATABASE=HD Webcam C510 + +usb:v046Dp0820* + ID_PRODUCT_FROM_DATABASE=QuickCam VC + +usb:v046Dp0821* + ID_PRODUCT_FROM_DATABASE=HD Webcam C910 + +usb:v046Dp0825* + ID_PRODUCT_FROM_DATABASE=Webcam C270 + +usb:v046Dp0828* + ID_PRODUCT_FROM_DATABASE=HD Webcam B990 + +usb:v046Dp082D* + ID_PRODUCT_FROM_DATABASE=HD Pro Webcam C920 + +usb:v046Dp0830* + ID_PRODUCT_FROM_DATABASE=QuickClip + +usb:v046Dp0840* + ID_PRODUCT_FROM_DATABASE=QuickCam Express + +usb:v046Dp0850* + ID_PRODUCT_FROM_DATABASE=QuickCam Web + +usb:v046Dp0870* + ID_PRODUCT_FROM_DATABASE=QuickCam Express + +usb:v046Dp0890* + ID_PRODUCT_FROM_DATABASE=QuickCam Traveler + +usb:v046Dp0892* + ID_PRODUCT_FROM_DATABASE=OrbiCam + +usb:v046Dp0894* + ID_PRODUCT_FROM_DATABASE=CrystalCam + +usb:v046Dp0895* + ID_PRODUCT_FROM_DATABASE=QuickCam for Dell Notebooks + +usb:v046Dp0896* + ID_PRODUCT_FROM_DATABASE=OrbiCam + +usb:v046Dp0897* + ID_PRODUCT_FROM_DATABASE=QuickCam for Dell Notebooks + +usb:v046Dp0899* + ID_PRODUCT_FROM_DATABASE=QuickCam for Dell Notebooks + +usb:v046Dp089D* + ID_PRODUCT_FROM_DATABASE=QuickCam E2500 series + +usb:v046Dp08A0* + ID_PRODUCT_FROM_DATABASE=QuickCam IM + +usb:v046Dp08A1* + ID_PRODUCT_FROM_DATABASE=QuickCam IM with sound + +usb:v046Dp08A2* + ID_PRODUCT_FROM_DATABASE=Labtec Webcam Pro + +usb:v046Dp08A3* + ID_PRODUCT_FROM_DATABASE=QuickCam QuickCam Chat + +usb:v046Dp08A6* + ID_PRODUCT_FROM_DATABASE=QuickCam IM + +usb:v046Dp08A7* + ID_PRODUCT_FROM_DATABASE=QuickCam Image + +usb:v046Dp08A9* + ID_PRODUCT_FROM_DATABASE=Notebook Deluxe + +usb:v046Dp08AA* + ID_PRODUCT_FROM_DATABASE=Labtec Notebooks + +usb:v046Dp08AC* + ID_PRODUCT_FROM_DATABASE=QuickCam Cool + +usb:v046Dp08AD* + ID_PRODUCT_FROM_DATABASE=QuickCam Communicate STX + +usb:v046Dp08AE* + ID_PRODUCT_FROM_DATABASE=QuickCam for Notebooks + +usb:v046Dp08AF* + ID_PRODUCT_FROM_DATABASE=QuickCam Easy/Cool + +usb:v046Dp08B0* + ID_PRODUCT_FROM_DATABASE=QuickCam 3000 Pro [pwc] + +usb:v046Dp08B1* + ID_PRODUCT_FROM_DATABASE=QuickCam Notebook Pro + +usb:v046Dp08B2* + ID_PRODUCT_FROM_DATABASE=QuickCam Pro 4000 + +usb:v046Dp08B3* + ID_PRODUCT_FROM_DATABASE=QuickCam Zoom + +usb:v046Dp08B4* + ID_PRODUCT_FROM_DATABASE=QuickCam Zoom + +usb:v046Dp08B5* + ID_PRODUCT_FROM_DATABASE=QuickCam Sphere + +usb:v046Dp08B9* + ID_PRODUCT_FROM_DATABASE=QuickCam IM + +usb:v046Dp08BD* + ID_PRODUCT_FROM_DATABASE=Microphone (Pro 4000) + +usb:v046Dp08C0* + ID_PRODUCT_FROM_DATABASE=QuickCam Pro 3000 + +usb:v046Dp08C1* + ID_PRODUCT_FROM_DATABASE=QuickCam Fusion + +usb:v046Dp08C2* + ID_PRODUCT_FROM_DATABASE=QuickCam PTZ + +usb:v046Dp08C3* + ID_PRODUCT_FROM_DATABASE=Camera (Notebooks Pro) + +usb:v046Dp08C5* + ID_PRODUCT_FROM_DATABASE=QuickCam Pro 5000 + +usb:v046Dp08C6* + ID_PRODUCT_FROM_DATABASE=QuickCam for DELL Notebooks + +usb:v046Dp08C7* + ID_PRODUCT_FROM_DATABASE=QuickCam OEM Cisco VT Camera II + +usb:v046Dp08C9* + ID_PRODUCT_FROM_DATABASE=QuickCam Ultra Vision + +usb:v046Dp08CA* + ID_PRODUCT_FROM_DATABASE=Mic (Fusion) + +usb:v046Dp08CB* + ID_PRODUCT_FROM_DATABASE=Mic (Notebooks Pro) + +usb:v046Dp08CC* + ID_PRODUCT_FROM_DATABASE=Mic (PTZ) + +usb:v046Dp08CE* + ID_PRODUCT_FROM_DATABASE=QuickCam Pro 5000 + +usb:v046Dp08CF* + ID_PRODUCT_FROM_DATABASE=QuickCam UpdateMe + +usb:v046Dp08D0* + ID_PRODUCT_FROM_DATABASE=QuickCam Express + +usb:v046Dp08D7* + ID_PRODUCT_FROM_DATABASE=QuickCam Communicate STX + +usb:v046Dp08D8* + ID_PRODUCT_FROM_DATABASE=QuickCam for Notebook Deluxe + +usb:v046Dp08D9* + ID_PRODUCT_FROM_DATABASE=QuickCam IM/Connect + +usb:v046Dp08DA* + ID_PRODUCT_FROM_DATABASE=QuickCam Messanger + +usb:v046Dp08DD* + ID_PRODUCT_FROM_DATABASE=QuickCam for Notebooks + +usb:v046Dp08E0* + ID_PRODUCT_FROM_DATABASE=QuickCam Express + +usb:v046Dp08E1* + ID_PRODUCT_FROM_DATABASE=Labtec Webcam + +usb:v046Dp08F0* + ID_PRODUCT_FROM_DATABASE=QuickCam Messenger + +usb:v046Dp08F1* + ID_PRODUCT_FROM_DATABASE=QuickCam Express + +usb:v046Dp08F2* + ID_PRODUCT_FROM_DATABASE=Microphone (Messenger) + +usb:v046Dp08F3* + ID_PRODUCT_FROM_DATABASE=QuickCam Express + +usb:v046Dp08F4* + ID_PRODUCT_FROM_DATABASE=Labtec Webcam + +usb:v046Dp08F5* + ID_PRODUCT_FROM_DATABASE=QuickCam Messenger Communicate + +usb:v046Dp08F6* + ID_PRODUCT_FROM_DATABASE=QuickCam Messenger Plus + +usb:v046Dp0900* + ID_PRODUCT_FROM_DATABASE=ClickSmart 310 + +usb:v046Dp0901* + ID_PRODUCT_FROM_DATABASE=ClickSmart 510 + +usb:v046Dp0903* + ID_PRODUCT_FROM_DATABASE=ClickSmart 820 + +usb:v046Dp0905* + ID_PRODUCT_FROM_DATABASE=ClickSmart 820 + +usb:v046Dp0910* + ID_PRODUCT_FROM_DATABASE=QuickCam Cordless + +usb:v046Dp0920* + ID_PRODUCT_FROM_DATABASE=QuickCam Express + +usb:v046Dp0921* + ID_PRODUCT_FROM_DATABASE=Labtec Webcam + +usb:v046Dp0922* + ID_PRODUCT_FROM_DATABASE=QuickCam Live + +usb:v046Dp0928* + ID_PRODUCT_FROM_DATABASE=QuickCam Express + +usb:v046Dp0929* + ID_PRODUCT_FROM_DATABASE=Labtec Webcam Pro + +usb:v046Dp092A* + ID_PRODUCT_FROM_DATABASE=QuickCam for Notebooks + +usb:v046Dp092B* + ID_PRODUCT_FROM_DATABASE=Labtec Webcam Plus + +usb:v046Dp092C* + ID_PRODUCT_FROM_DATABASE=QuickCam Chat + +usb:v046Dp092D* + ID_PRODUCT_FROM_DATABASE=QuickCam Express / Go + +usb:v046Dp092E* + ID_PRODUCT_FROM_DATABASE=QuickCam Chat + +usb:v046Dp092F* + ID_PRODUCT_FROM_DATABASE=QuickCam Express Plus + +usb:v046Dp0950* + ID_PRODUCT_FROM_DATABASE=Pocket Camera + +usb:v046Dp0960* + ID_PRODUCT_FROM_DATABASE=ClickSmart 420 + +usb:v046Dp0970* + ID_PRODUCT_FROM_DATABASE=Pocket750 + +usb:v046Dp0990* + ID_PRODUCT_FROM_DATABASE=QuickCam Pro 9000 + +usb:v046Dp0991* + ID_PRODUCT_FROM_DATABASE=QuickCam Pro for Notebooks + +usb:v046Dp0992* + ID_PRODUCT_FROM_DATABASE=QuickCam Communicate Deluxe + +usb:v046Dp0994* + ID_PRODUCT_FROM_DATABASE=QuickCam Orbit/Sphere AF + +usb:v046Dp09A1* + ID_PRODUCT_FROM_DATABASE=QuickCam Communicate MP/S5500 + +usb:v046Dp09A2* + ID_PRODUCT_FROM_DATABASE=QuickCam Communicate Deluxe/S7500 + +usb:v046Dp09A4* + ID_PRODUCT_FROM_DATABASE=QuickCam E 3500 + +usb:v046Dp09A5* + ID_PRODUCT_FROM_DATABASE=Quickcam 3000 For Business + +usb:v046Dp09A6* + ID_PRODUCT_FROM_DATABASE=QuickCam Vision Pro + +usb:v046Dp09B0* + ID_PRODUCT_FROM_DATABASE=Acer OrbiCam + +usb:v046Dp09B2* + ID_PRODUCT_FROM_DATABASE=Fujitsu Webcam + +usb:v046Dp09C0* + ID_PRODUCT_FROM_DATABASE=QuickCam for Dell Notebooks Mic + +usb:v046Dp09C1* + ID_PRODUCT_FROM_DATABASE=QuickCam Deluxe for Notebooks + +usb:v046Dp0A01* + ID_PRODUCT_FROM_DATABASE=USB Headset + +usb:v046Dp0A02* + ID_PRODUCT_FROM_DATABASE=Premium Stereo USB Headset 350 + +usb:v046Dp0A03* + ID_PRODUCT_FROM_DATABASE=Logitech USB Microphone + +usb:v046Dp0A04* + ID_PRODUCT_FROM_DATABASE=V20 portable speakers (USB powered) + +usb:v046Dp0A07* + ID_PRODUCT_FROM_DATABASE=Z-10 Speakers + +usb:v046Dp0A0B* + ID_PRODUCT_FROM_DATABASE=ClearChat Pro USB + +usb:v046Dp0A0C* + ID_PRODUCT_FROM_DATABASE=Clear Chat Comfort USB Headset + +usb:v046Dp0A13* + ID_PRODUCT_FROM_DATABASE=Z-5 Speakers + +usb:v046Dp0A17* + ID_PRODUCT_FROM_DATABASE=G330 Headset + +usb:v046Dp0B02* + ID_PRODUCT_FROM_DATABASE=C-UV35 [Bluetooth Mini-Receiver] (HID proxy mode) + +usb:v046Dp8801* + ID_PRODUCT_FROM_DATABASE=Video Camera + +usb:v046DpB305* + ID_PRODUCT_FROM_DATABASE=BT Mini-Receiver + +usb:v046DpBFE4* + ID_PRODUCT_FROM_DATABASE=Premium Optical Wheel Mouse + +usb:v046DpC000* + ID_PRODUCT_FROM_DATABASE=N43 [Pilot Mouse] + +usb:v046DpC001* + ID_PRODUCT_FROM_DATABASE=N48/M-BB48 [FirstMouse Plus] + +usb:v046DpC002* + ID_PRODUCT_FROM_DATABASE=M-BA47 [MouseMan Plus] + +usb:v046DpC003* + ID_PRODUCT_FROM_DATABASE=MouseMan + +usb:v046DpC004* + ID_PRODUCT_FROM_DATABASE=WingMan Gaming Mouse + +usb:v046DpC005* + ID_PRODUCT_FROM_DATABASE=WingMan Gaming Wheel Mouse + +usb:v046DpC00B* + ID_PRODUCT_FROM_DATABASE=MouseMan Wheel + +usb:v046DpC00C* + ID_PRODUCT_FROM_DATABASE=Optical Wheel Mouse + +usb:v046DpC00D* + ID_PRODUCT_FROM_DATABASE=MouseMan Wheel+ + +usb:v046DpC00E* + ID_PRODUCT_FROM_DATABASE=M-BJ58/M-BJ69 Optical Wheel Mouse + +usb:v046DpC00F* + ID_PRODUCT_FROM_DATABASE=MouseMan Traveler/Mobile + +usb:v046DpC011* + ID_PRODUCT_FROM_DATABASE=Optical MouseMan + +usb:v046DpC012* + ID_PRODUCT_FROM_DATABASE=Mouseman Dual Optical + +usb:v046DpC014* + ID_PRODUCT_FROM_DATABASE=Corded Workstation Mouse + +usb:v046DpC015* + ID_PRODUCT_FROM_DATABASE=Corded Workstation Mouse + +usb:v046DpC016* + ID_PRODUCT_FROM_DATABASE=Optical Wheel Mouse + +usb:v046DpC018* + ID_PRODUCT_FROM_DATABASE=Optical Wheel Mouse + +usb:v046DpC019* + ID_PRODUCT_FROM_DATABASE=Optical Tilt Wheel Mouse + +usb:v046DpC01A* + ID_PRODUCT_FROM_DATABASE=M-BQ85 Optical Wheel Mouse + +usb:v046DpC01B* + ID_PRODUCT_FROM_DATABASE=MX310 Optical Mouse + +usb:v046DpC01C* + ID_PRODUCT_FROM_DATABASE=Optical Mouse + +usb:v046DpC01D* + ID_PRODUCT_FROM_DATABASE=MX510 Optical Mouse + +usb:v046DpC01E* + ID_PRODUCT_FROM_DATABASE=MX518 Optical Mouse + +usb:v046DpC024* + ID_PRODUCT_FROM_DATABASE=MX300 Optical Mouse + +usb:v046DpC025* + ID_PRODUCT_FROM_DATABASE=MX500 Optical Mouse + +usb:v046DpC030* + ID_PRODUCT_FROM_DATABASE=iFeel Mouse + +usb:v046DpC031* + ID_PRODUCT_FROM_DATABASE=iFeel Mouse+ + +usb:v046DpC032* + ID_PRODUCT_FROM_DATABASE=MouseMan iFeel + +usb:v046DpC033* + ID_PRODUCT_FROM_DATABASE=iFeel MouseMan+ + +usb:v046DpC034* + ID_PRODUCT_FROM_DATABASE=MouseMan Optical + +usb:v046DpC035* + ID_PRODUCT_FROM_DATABASE=Mouse + +usb:v046DpC036* + ID_PRODUCT_FROM_DATABASE=Mouse + +usb:v046DpC037* + ID_PRODUCT_FROM_DATABASE=Mouse + +usb:v046DpC038* + ID_PRODUCT_FROM_DATABASE=Mouse + +usb:v046DpC03D* + ID_PRODUCT_FROM_DATABASE=M-BT96a Pilot Optical Mouse + +usb:v046DpC03E* + ID_PRODUCT_FROM_DATABASE=Premium Optical Wheel Mouse (M-BT58) + +usb:v046DpC03F* + ID_PRODUCT_FROM_DATABASE=M-BT85 [UltraX Optical Mouse] + +usb:v046DpC040* + ID_PRODUCT_FROM_DATABASE=Corded Tilt-Wheel Mouse + +usb:v046DpC041* + ID_PRODUCT_FROM_DATABASE=G5 Laser Mouse + +usb:v046DpC042* + ID_PRODUCT_FROM_DATABASE=G3 Laser Mouse + +usb:v046DpC043* + ID_PRODUCT_FROM_DATABASE=MX320/MX400 Laser Mouse + +usb:v046DpC044* + ID_PRODUCT_FROM_DATABASE=LX3 Optical Mouse + +usb:v046DpC045* + ID_PRODUCT_FROM_DATABASE=Optical Mouse + +usb:v046DpC046* + ID_PRODUCT_FROM_DATABASE=RX1000 Laser Mouse + +usb:v046DpC047* + ID_PRODUCT_FROM_DATABASE=Laser Mouse M-UAL120 + +usb:v046DpC048* + ID_PRODUCT_FROM_DATABASE=G9 Laser Mouse + +usb:v046DpC049* + ID_PRODUCT_FROM_DATABASE=G5 Laser Mouse + +usb:v046DpC050* + ID_PRODUCT_FROM_DATABASE=RX 250 Optical Mouse + +usb:v046DpC051* + ID_PRODUCT_FROM_DATABASE=G3 (MX518) Optical Mouse + +usb:v046DpC053* + ID_PRODUCT_FROM_DATABASE=Laser Mouse + +usb:v046DpC054* + ID_PRODUCT_FROM_DATABASE=Bluetooth mini-receiver + +usb:v046DpC058* + ID_PRODUCT_FROM_DATABASE=M115 Mouse + +usb:v046DpC05A* + ID_PRODUCT_FROM_DATABASE=M90/M100 Optical Mouse + +usb:v046DpC05B* + ID_PRODUCT_FROM_DATABASE=M-U0004 810-001317 [B110 Optical USB Mouse] + +usb:v046DpC05D* + ID_PRODUCT_FROM_DATABASE=Optical Mouse + +usb:v046DpC05F* + ID_PRODUCT_FROM_DATABASE=M115 Optical Mouse + +usb:v046DpC061* + ID_PRODUCT_FROM_DATABASE=RX1500 Laser Mouse + +usb:v046DpC062* + ID_PRODUCT_FROM_DATABASE=M-UAS144 [LS1 Laser Mouse] + +usb:v046DpC063* + ID_PRODUCT_FROM_DATABASE=DELL Laser Mouse + +usb:v046DpC068* + ID_PRODUCT_FROM_DATABASE=G500 Laser Mouse + +usb:v046DpC069* + ID_PRODUCT_FROM_DATABASE=M500 Laser Mouse + +usb:v046DpC06A* + ID_PRODUCT_FROM_DATABASE=USB Optical Mouse + +usb:v046DpC06B* + ID_PRODUCT_FROM_DATABASE=G700 Wireless Gaming Mouse + +usb:v046DpC06C* + ID_PRODUCT_FROM_DATABASE=Optical Mouse + +usb:v046DpC101* + ID_PRODUCT_FROM_DATABASE=UltraX Media Remote + +usb:v046DpC110* + ID_PRODUCT_FROM_DATABASE=Harmony 885 Remote + +usb:v046DpC111* + ID_PRODUCT_FROM_DATABASE=Harmony 525 Remote + +usb:v046DpC11F* + ID_PRODUCT_FROM_DATABASE=Harmony 900 Remote + +usb:v046DpC122* + ID_PRODUCT_FROM_DATABASE=Harmony 700 Remote + +usb:v046DpC201* + ID_PRODUCT_FROM_DATABASE=WingMan Extreme Joystick with Throttle + +usb:v046DpC202* + ID_PRODUCT_FROM_DATABASE=WingMan Formula + +usb:v046DpC207* + ID_PRODUCT_FROM_DATABASE=WingMan Extreme Digital 3D + +usb:v046DpC208* + ID_PRODUCT_FROM_DATABASE=WingMan Gamepad Extreme + +usb:v046DpC209* + ID_PRODUCT_FROM_DATABASE=WingMan Gamepad + +usb:v046DpC20A* + ID_PRODUCT_FROM_DATABASE=WingMan RumblePad + +usb:v046DpC20B* + ID_PRODUCT_FROM_DATABASE=WingMan Action Pad + +usb:v046DpC20C* + ID_PRODUCT_FROM_DATABASE=WingMan Precision + +usb:v046DpC20D* + ID_PRODUCT_FROM_DATABASE=WingMan Attack 2 + +usb:v046DpC20E* + ID_PRODUCT_FROM_DATABASE=WingMan Formula GP + +usb:v046DpC211* + ID_PRODUCT_FROM_DATABASE=iTouch Cordless Reciever + +usb:v046DpC212* + ID_PRODUCT_FROM_DATABASE=WingMan Extreme Digital 3D + +usb:v046DpC213* + ID_PRODUCT_FROM_DATABASE=J-UH16 (Freedom 2.4 Cordless Joystick) + +usb:v046DpC214* + ID_PRODUCT_FROM_DATABASE=ATK3 (Attack III Joystick) + +usb:v046DpC215* + ID_PRODUCT_FROM_DATABASE=Extreme 3D Pro + +usb:v046DpC216* + ID_PRODUCT_FROM_DATABASE=Dual Action Gamepad + +usb:v046DpC218* + ID_PRODUCT_FROM_DATABASE=Logitech RumblePad 2 USB + +usb:v046DpC219* + ID_PRODUCT_FROM_DATABASE=Cordless RumblePad 2 + +usb:v046DpC21A* + ID_PRODUCT_FROM_DATABASE=Precision Gamepad + +usb:v046DpC21C* + ID_PRODUCT_FROM_DATABASE=G13 Advanced Gameboard + +usb:v046DpC21D* + ID_PRODUCT_FROM_DATABASE=F310 Gamepad [XInput Mode] + +usb:v046DpC21E* + ID_PRODUCT_FROM_DATABASE=F510 Gamepad [XInput Mode] + +usb:v046DpC21F* + ID_PRODUCT_FROM_DATABASE=F710 Wireless Gamepad [XInput Mode] + +usb:v046DpC221* + ID_PRODUCT_FROM_DATABASE=G11/G15 Keyboard / Keyboard + +usb:v046DpC222* + ID_PRODUCT_FROM_DATABASE=G15 Keyboard / LCD + +usb:v046DpC223* + ID_PRODUCT_FROM_DATABASE=G11/G15 Keyboard / USB Hub + +usb:v046DpC225* + ID_PRODUCT_FROM_DATABASE=G11/G15 Keyboard / G keys + +usb:v046DpC226* + ID_PRODUCT_FROM_DATABASE=G15 Refresh Keyboard + +usb:v046DpC227* + ID_PRODUCT_FROM_DATABASE=G15 Refresh Keyboard + +usb:v046DpC22A* + ID_PRODUCT_FROM_DATABASE=Gaming Keyboard G110 + +usb:v046DpC22B* + ID_PRODUCT_FROM_DATABASE=Gaming Keyboard G110 G-keys + +usb:v046DpC22D* + ID_PRODUCT_FROM_DATABASE=G510 Gaming Keyboard + +usb:v046DpC22E* + ID_PRODUCT_FROM_DATABASE=G510 Gaming Keyboard onboard audio + +usb:v046DpC246* + ID_PRODUCT_FROM_DATABASE=Gaming Mouse G300 + +usb:v046DpC281* + ID_PRODUCT_FROM_DATABASE=WingMan Force + +usb:v046DpC283* + ID_PRODUCT_FROM_DATABASE=WingMan Force 3D + +usb:v046DpC285* + ID_PRODUCT_FROM_DATABASE=WingMan Strike Force 3D + +usb:v046DpC286* + ID_PRODUCT_FROM_DATABASE=Force 3D Pro + +usb:v046DpC287* + ID_PRODUCT_FROM_DATABASE=Flight System G940 + +usb:v046DpC291* + ID_PRODUCT_FROM_DATABASE=WingMan Formula Force + +usb:v046DpC293* + ID_PRODUCT_FROM_DATABASE=WingMan Formula Force GP + +usb:v046DpC294* + ID_PRODUCT_FROM_DATABASE=Driving Force + +usb:v046DpC295* + ID_PRODUCT_FROM_DATABASE=Momo Force Steering Wheel + +usb:v046DpC298* + ID_PRODUCT_FROM_DATABASE=Driving Force Pro + +usb:v046DpC299* + ID_PRODUCT_FROM_DATABASE=G25 Racing Wheel + +usb:v046DpC29B* + ID_PRODUCT_FROM_DATABASE=G27 Racing Wheel + +usb:v046DpC29C* + ID_PRODUCT_FROM_DATABASE=Speed Force Wireless Wheel for Wii + +usb:v046DpC2A0* + ID_PRODUCT_FROM_DATABASE=Wingman Force Feedback Mouse + +usb:v046DpC2A1* + ID_PRODUCT_FROM_DATABASE=WingMan Force Feedback Mouse + +usb:v046DpC301* + ID_PRODUCT_FROM_DATABASE=iTouch Keyboard + +usb:v046DpC302* + ID_PRODUCT_FROM_DATABASE=iTouch Pro Keyboard + +usb:v046DpC303* + ID_PRODUCT_FROM_DATABASE=iTouch Keyboard + +usb:v046DpC305* + ID_PRODUCT_FROM_DATABASE=Internet Keyboard + +usb:v046DpC307* + ID_PRODUCT_FROM_DATABASE=Internet Keyboard + +usb:v046DpC308* + ID_PRODUCT_FROM_DATABASE=Internet Navigator Keyboard + +usb:v046DpC309* + ID_PRODUCT_FROM_DATABASE=Internet Keyboard + +usb:v046DpC30A* + ID_PRODUCT_FROM_DATABASE=iTouch Composite + +usb:v046DpC30B* + ID_PRODUCT_FROM_DATABASE=NetPlay Keyboard + +usb:v046DpC30C* + ID_PRODUCT_FROM_DATABASE=Internet Keys (X) + +usb:v046DpC30D* + ID_PRODUCT_FROM_DATABASE=Internet Keys + +usb:v046DpC30E* + ID_PRODUCT_FROM_DATABASE=UltraX Keyboard (Y-BL49) + +usb:v046DpC30F* + ID_PRODUCT_FROM_DATABASE=Logicool HID-Compliant Keyboard (106 key) + +usb:v046DpC311* + ID_PRODUCT_FROM_DATABASE=Y-UF49 [Internet Pro Keyboard] + +usb:v046DpC312* + ID_PRODUCT_FROM_DATABASE=DeLuxe 250 Keyboard + +usb:v046DpC313* + ID_PRODUCT_FROM_DATABASE=Internet 350 Keyboard + +usb:v046DpC315* + ID_PRODUCT_FROM_DATABASE=Classic New Touch Keyboard + +usb:v046DpC316* + ID_PRODUCT_FROM_DATABASE=HID-Compliant Keyboard + +usb:v046DpC317* + ID_PRODUCT_FROM_DATABASE=Wave Corded Keyboard + +usb:v046DpC318* + ID_PRODUCT_FROM_DATABASE=Illuminated Keyboard + +usb:v046DpC31A* + ID_PRODUCT_FROM_DATABASE=Comfort Wave 450 + +usb:v046DpC31B* + ID_PRODUCT_FROM_DATABASE=Compact Keyboard K300 + +usb:v046DpC31C* + ID_PRODUCT_FROM_DATABASE=Keyboard K120 for Business + +usb:v046DpC31D* + ID_PRODUCT_FROM_DATABASE=Media Keyboard K200 + +usb:v046DpC401* + ID_PRODUCT_FROM_DATABASE=TrackMan Marble Wheel + +usb:v046DpC402* + ID_PRODUCT_FROM_DATABASE=Marble Mouse (2-button) + +usb:v046DpC403* + ID_PRODUCT_FROM_DATABASE=Turbo TrackMan Marble FX + +usb:v046DpC404* + ID_PRODUCT_FROM_DATABASE=TrackMan Wheel + +usb:v046DpC408* + ID_PRODUCT_FROM_DATABASE=Marble Mouse (4-button) + +usb:v046DpC501* + ID_PRODUCT_FROM_DATABASE=Cordless Mouse Receiver + +usb:v046DpC502* + ID_PRODUCT_FROM_DATABASE=Cordless Mouse & iTouch Keys + +usb:v046DpC503* + ID_PRODUCT_FROM_DATABASE=Cordless Mouse+Keyboard Receiver + +usb:v046DpC504* + ID_PRODUCT_FROM_DATABASE=Cordless Mouse+Keyboard Receiver + +usb:v046DpC505* + ID_PRODUCT_FROM_DATABASE=Cordless Mouse+Keyboard Receiver + +usb:v046DpC506* + ID_PRODUCT_FROM_DATABASE=MX700 Cordless Mouse Receiver + +usb:v046DpC508* + ID_PRODUCT_FROM_DATABASE=Cordless Trackball + +usb:v046DpC509* + ID_PRODUCT_FROM_DATABASE=Cordless Keyboard & Mouse + +usb:v046DpC50A* + ID_PRODUCT_FROM_DATABASE=Cordless Mouse + +usb:v046DpC50B* + ID_PRODUCT_FROM_DATABASE=Cordless Desktop Optical + +usb:v046DpC50C* + ID_PRODUCT_FROM_DATABASE=Cordless Desktop S510 + +usb:v046DpC50D* + ID_PRODUCT_FROM_DATABASE=Cordless Mouse + +usb:v046DpC50E* + ID_PRODUCT_FROM_DATABASE=Cordless Mouse Receiver + +usb:v046DpC510* + ID_PRODUCT_FROM_DATABASE=Cordless Mouse + +usb:v046DpC512* + ID_PRODUCT_FROM_DATABASE=LX-700 Cordless Desktop Receiver + +usb:v046DpC513* + ID_PRODUCT_FROM_DATABASE=MX3000 Cordless Desktop Receiver + +usb:v046DpC514* + ID_PRODUCT_FROM_DATABASE=Cordless Mouse + +usb:v046DpC515* + ID_PRODUCT_FROM_DATABASE=Cordless 2.4 GHz Presenter Presentation remote control + +usb:v046DpC517* + ID_PRODUCT_FROM_DATABASE=LX710 Cordless Desktop Laser + +usb:v046DpC518* + ID_PRODUCT_FROM_DATABASE=MX610 Laser Cordless Mouse + +usb:v046DpC51A* + ID_PRODUCT_FROM_DATABASE=MX Revolution/G7 Cordless Mouse + +usb:v046DpC51B* + ID_PRODUCT_FROM_DATABASE=V220 Cordless Optical Mouse for Notebooks + +usb:v046DpC521* + ID_PRODUCT_FROM_DATABASE=Cordless Mouse Receiver + +usb:v046DpC525* + ID_PRODUCT_FROM_DATABASE=MX Revolution Cordless Mouse + +usb:v046DpC526* + ID_PRODUCT_FROM_DATABASE=Nano Receiver + +usb:v046DpC529* + ID_PRODUCT_FROM_DATABASE=diNovo Keyboard for notebooks + +usb:v046DpC52B* + ID_PRODUCT_FROM_DATABASE=Unifying Receiver + +usb:v046DpC52F* + ID_PRODUCT_FROM_DATABASE=Wireless Mouse M305 + +usb:v046DpC623* + ID_PRODUCT_FROM_DATABASE=3Dconnexion Space Traveller 3D Mouse + +usb:v046DpC625* + ID_PRODUCT_FROM_DATABASE=3Dconnexion Space Pilot 3D Mouse + +usb:v046DpC626* + ID_PRODUCT_FROM_DATABASE=3Dconnexion Space Navigator 3D Mouse + +usb:v046DpC627* + ID_PRODUCT_FROM_DATABASE=3Dconnexion Space Explorer 3D Mouse + +usb:v046DpC702* + ID_PRODUCT_FROM_DATABASE=Cordless Presenter + +usb:v046DpC703* + ID_PRODUCT_FROM_DATABASE=Elite Keyboard Y-RP20 + Mouse MX900 (Bluetooth) + +usb:v046DpC704* + ID_PRODUCT_FROM_DATABASE=diNovo Wireless Desktop + +usb:v046DpC705* + ID_PRODUCT_FROM_DATABASE=MX900 Bluetooth Wireless Hub (C-UJ16A) + +usb:v046DpC707* + ID_PRODUCT_FROM_DATABASE=Bluetooth wireless hub + +usb:v046DpC708* + ID_PRODUCT_FROM_DATABASE=Bluetooth wireless hub + +usb:v046DpC709* + ID_PRODUCT_FROM_DATABASE=BT Mini-Receiver (HCI mode) + +usb:v046DpC70A* + ID_PRODUCT_FROM_DATABASE=MX5000 Cordless Desktop + +usb:v046DpC70B* + ID_PRODUCT_FROM_DATABASE=BT Mini-Receiver (HID proxy mode) + +usb:v046DpC70C* + ID_PRODUCT_FROM_DATABASE=BT Mini-Receiver (HID proxy mode) + +usb:v046DpC70D* + ID_PRODUCT_FROM_DATABASE=Bluetooth wireless hub + +usb:v046DpC70E* + ID_PRODUCT_FROM_DATABASE=MX1000 Bluetooth Laser Mouse + +usb:v046DpC70F* + ID_PRODUCT_FROM_DATABASE=Bluetooth wireless hub + +usb:v046DpC712* + ID_PRODUCT_FROM_DATABASE=Bluetooth wireless hub + +usb:v046DpC714* + ID_PRODUCT_FROM_DATABASE=diNovo Edge Keyboard + +usb:v046DpC715* + ID_PRODUCT_FROM_DATABASE=Bluetooth wireless hub + +usb:v046DpC71A* + ID_PRODUCT_FROM_DATABASE=Bluetooth wireless hub + +usb:v046DpC71D* + ID_PRODUCT_FROM_DATABASE=Bluetooth wireless hub + +usb:v046DpC71F* + ID_PRODUCT_FROM_DATABASE=diNovo Mini Wireless Keyboard + +usb:v046DpC720* + ID_PRODUCT_FROM_DATABASE=Bluetooth wireless hub + +usb:v046DpCA03* + ID_PRODUCT_FROM_DATABASE=MOMO Racing + +usb:v046DpCA04* + ID_PRODUCT_FROM_DATABASE=Formula Vibration Feedback Wheel + +usb:v046DpCAB1* + ID_PRODUCT_FROM_DATABASE=Cordless Keyboard for Wii HID Receiver + +usb:v046DpD001* + ID_PRODUCT_FROM_DATABASE=QuickCam Pro + +usb:v046E* + ID_VENDOR_FROM_DATABASE=Behavior Tech. Computer Corp. + +usb:v046Ep0100* + ID_PRODUCT_FROM_DATABASE=Keyboard + +usb:v046Ep3001* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v046Ep3002* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v046Ep3003* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v046Ep3005* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v046Ep3008* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v046Ep5250* + ID_PRODUCT_FROM_DATABASE=KeyMaestro Multimedia Keyboard + +usb:v046Ep5273* + ID_PRODUCT_FROM_DATABASE=KeyMaestro Multimedia Keyboard + +usb:v046Ep52E6* + ID_PRODUCT_FROM_DATABASE=Cordless Mouse + +usb:v046Ep5308* + ID_PRODUCT_FROM_DATABASE=KeyMaestro Keyboard + +usb:v046Ep5408* + ID_PRODUCT_FROM_DATABASE=KeyMaestro Multimedia Keyboard/Hub + +usb:v046Ep5500* + ID_PRODUCT_FROM_DATABASE=Portable Keyboard 86+9 keys (Model 6100C US) + +usb:v046Ep5720* + ID_PRODUCT_FROM_DATABASE=Smart Card Reader + +usb:v046Ep6782* + ID_PRODUCT_FROM_DATABASE=BTC 7932 mouse+keyboard + +usb:v046F* + ID_VENDOR_FROM_DATABASE=Crystal Semiconductor + +usb:v0471* + ID_VENDOR_FROM_DATABASE=Philips (or NXP) + +usb:v0471p0101* + ID_PRODUCT_FROM_DATABASE=DSS350 Digital Speaker System + +usb:v0471p0104* + ID_PRODUCT_FROM_DATABASE=DSS330 Digital Speaker System [uda1321] + +usb:v0471p0105* + ID_PRODUCT_FROM_DATABASE=UDA1321 + +usb:v0471p014F* + ID_PRODUCT_FROM_DATABASE=GoGear SA9200 + +usb:v0471p0160* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v0471p0161* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v0471p0163* + ID_PRODUCT_FROM_DATABASE=GoGear SA1100 + +usb:v0471p0164* + ID_PRODUCT_FROM_DATABASE=GoGear SA1110/02 + +usb:v0471p0165* + ID_PRODUCT_FROM_DATABASE=GoGear SA1330 + +usb:v0471p0201* + ID_PRODUCT_FROM_DATABASE=Hub + +usb:v0471p0222* + ID_PRODUCT_FROM_DATABASE=Creative Nomad Jukebox + +usb:v0471p0302* + ID_PRODUCT_FROM_DATABASE=PCA645VC Webcam [pwc] + +usb:v0471p0303* + ID_PRODUCT_FROM_DATABASE=PCA646VC Webcam [pwc] + +usb:v0471p0304* + ID_PRODUCT_FROM_DATABASE=Askey VC010 Webcam [pwc] + +usb:v0471p0307* + ID_PRODUCT_FROM_DATABASE=PCVC675K Webcam [pwc] + +usb:v0471p0308* + ID_PRODUCT_FROM_DATABASE=PCVC680K Webcam [pwc] + +usb:v0471p030B* + ID_PRODUCT_FROM_DATABASE=PC VGA Camera (Vesta Fun) + +usb:v0471p030C* + ID_PRODUCT_FROM_DATABASE=PCVC690K Webcam [pwc] + +usb:v0471p0310* + ID_PRODUCT_FROM_DATABASE=PCVC730K Webcam [pwc] + +usb:v0471p0311* + ID_PRODUCT_FROM_DATABASE=PCVC740K ToUcam Pro [pwc] + +usb:v0471p0312* + ID_PRODUCT_FROM_DATABASE=PCVC750K Webcam [pwc] + +usb:v0471p0314* + ID_PRODUCT_FROM_DATABASE=DMVC 1000K + +usb:v0471p0316* + ID_PRODUCT_FROM_DATABASE=DMVC 2000K Video Capture + +usb:v0471p0321* + ID_PRODUCT_FROM_DATABASE=FunCam + +usb:v0471p0322* + ID_PRODUCT_FROM_DATABASE=DMVC1300K PC Camera + +usb:v0471p0325* + ID_PRODUCT_FROM_DATABASE=SPC 200NC PC Camera + +usb:v0471p0326* + ID_PRODUCT_FROM_DATABASE=SPC 300NC PC Camera + +usb:v0471p0327* + ID_PRODUCT_FROM_DATABASE=Webcam SPC 6000 NC (Webcam w/ mic) + +usb:v0471p0328* + ID_PRODUCT_FROM_DATABASE=SPC 700NC PC Camera + +usb:v0471p0329* + ID_PRODUCT_FROM_DATABASE=SPC 900NC PC Camera / ORITE CCD Webcam(PC370R) + +usb:v0471p032D* + ID_PRODUCT_FROM_DATABASE=SPC 210NC PC Camera + +usb:v0471p032E* + ID_PRODUCT_FROM_DATABASE=SPC 315NC PC Camera + +usb:v0471p0330* + ID_PRODUCT_FROM_DATABASE=SPC 710NC PC Camera + +usb:v0471p0331* + ID_PRODUCT_FROM_DATABASE=SPC 1300NC PC Camera + +usb:v0471p0332* + ID_PRODUCT_FROM_DATABASE=SPC 1000NC PC Camera + +usb:v0471p0333* + ID_PRODUCT_FROM_DATABASE=SPC 620NC PC Camera + +usb:v0471p0334* + ID_PRODUCT_FROM_DATABASE=SPC 520/525NC PC Camera + +usb:v0471p0401* + ID_PRODUCT_FROM_DATABASE=Semiconductors CICT Keyboard + +usb:v0471p0402* + ID_PRODUCT_FROM_DATABASE=PS/2 Mouse on Semiconductors CICT Keyboard + +usb:v0471p0406* + ID_PRODUCT_FROM_DATABASE=15 inch Detachable Monitor + +usb:v0471p0407* + ID_PRODUCT_FROM_DATABASE=10 inch Mobile Monitor + +usb:v0471p0408* + ID_PRODUCT_FROM_DATABASE=SG3WA1/74 802.11b WLAN Adapter [Atmel AT76C503A] + +usb:v0471p0471* + ID_PRODUCT_FROM_DATABASE=Digital Speaker System + +usb:v0471p0601* + ID_PRODUCT_FROM_DATABASE=OVU1020 IR Dongle (Kbd+Mouse) + +usb:v0471p0602* + ID_PRODUCT_FROM_DATABASE=ATI Remote Wonder II Input Device + +usb:v0471p0603* + ID_PRODUCT_FROM_DATABASE=ATI Remote Wonder II Controller + +usb:v0471p0608* + ID_PRODUCT_FROM_DATABASE=eHome Infrared Receiver + +usb:v0471p060A* + ID_PRODUCT_FROM_DATABASE=TSU9600 Remote Control + +usb:v0471p060C* + ID_PRODUCT_FROM_DATABASE=Consumer Infrared Transceiver (HP) + +usb:v0471p060D* + ID_PRODUCT_FROM_DATABASE=Consumer Infrared Transceiver (SRM5100) + +usb:v0471p060E* + ID_PRODUCT_FROM_DATABASE=RF Dongle + +usb:v0471p060F* + ID_PRODUCT_FROM_DATABASE=Consumer Infrared Transceiver + +usb:v0471p0613* + ID_PRODUCT_FROM_DATABASE=Infrared Transceiver + +usb:v0471p0617* + ID_PRODUCT_FROM_DATABASE=IEEE802.15.4 RF Dongle + +usb:v0471p0619* + ID_PRODUCT_FROM_DATABASE=TSU9400 Remote Control + +usb:v0471p0666* + ID_PRODUCT_FROM_DATABASE=Hantek DDS-3005 Arbitrary Waveform Generator + +usb:v0471p0700* + ID_PRODUCT_FROM_DATABASE=Semiconductors CICT Hub + +usb:v0471p0701* + ID_PRODUCT_FROM_DATABASE=150P1 TFT Display + +usb:v0471p0809* + ID_PRODUCT_FROM_DATABASE=AVNET Bluetooth Device + +usb:v0471p0811* + ID_PRODUCT_FROM_DATABASE=JR24 CDRW + +usb:v0471p0814* + ID_PRODUCT_FROM_DATABASE=DCCX38/P data cable + +usb:v0471p0815* + ID_PRODUCT_FROM_DATABASE=eHome Infrared Receiver + +usb:v0471p0844* + ID_PRODUCT_FROM_DATABASE=SA2111/02 1GB Flash Audio Player + +usb:v0471p084A* + ID_PRODUCT_FROM_DATABASE=GoGear SA3125 + +usb:v0471p084E* + ID_PRODUCT_FROM_DATABASE=GoGear SA60xx (mtp) + +usb:v0471p0888* + ID_PRODUCT_FROM_DATABASE=Hantek DDS-3005 Arbitrary Waveform Generator + +usb:v0471p1103* + ID_PRODUCT_FROM_DATABASE=Digital Speaker System + +usb:v0471p1120* + ID_PRODUCT_FROM_DATABASE=Creative Rhomba MP3 player + +usb:v0471p1125* + ID_PRODUCT_FROM_DATABASE=Nike psa[128max Player + +usb:v0471p1137* + ID_PRODUCT_FROM_DATABASE=HDD065 MP3 player + +usb:v0471p1201* + ID_PRODUCT_FROM_DATABASE=Arima Bluetooth Device + +usb:v0471p1230* + ID_PRODUCT_FROM_DATABASE=Wireless Adapter 11g + +usb:v0471p1232* + ID_PRODUCT_FROM_DATABASE=SNU6500 Wireless Adapter + +usb:v0471p1233* + ID_PRODUCT_FROM_DATABASE=Wireless Adapter Bootloader Download + +usb:v0471p1236* + ID_PRODUCT_FROM_DATABASE=SNU5600 802.11bg + +usb:v0471p1237* + ID_PRODUCT_FROM_DATABASE=TalkTalk SNU5630NS/05 802.11bg + +usb:v0471p1552* + ID_PRODUCT_FROM_DATABASE=ISP 1581 Hi-Speed USB MPEG2 Encoder Reference Kit + +usb:v0471p1801* + ID_PRODUCT_FROM_DATABASE=Diva MP3 player + +usb:v0471p200A* + ID_PRODUCT_FROM_DATABASE=Wireless Network Adapter + +usb:v0471p200F* + ID_PRODUCT_FROM_DATABASE=802.11n Wireless Adapter + +usb:v0471p2021* + ID_PRODUCT_FROM_DATABASE=SDE3273FC/97 2.5" SATA HDD Enclosure [INIC-1608L] + +usb:v0471p2022* + ID_PRODUCT_FROM_DATABASE=GoGear SA52XX + +usb:v0471p2034* + ID_PRODUCT_FROM_DATABASE=Webcam SPC530NC + +usb:v0471p2036* + ID_PRODUCT_FROM_DATABASE=Webcam SPC1030NC + +usb:v0471p203F* + ID_PRODUCT_FROM_DATABASE=TSU9200 Remote Control + +usb:v0471p2046* + ID_PRODUCT_FROM_DATABASE=TSU9800 Remote Control + +usb:v0471p204E* + ID_PRODUCT_FROM_DATABASE=GoGear RaGa (SA1942/02) + +usb:v0471p205E* + ID_PRODUCT_FROM_DATABASE=TSU9300 Remote Control + +usb:v0471p206C* + ID_PRODUCT_FROM_DATABASE=MCE IR Receiver - Spinel plusf0r ASUS + +usb:v0471p2070* + ID_PRODUCT_FROM_DATABASE=GoGear Mix + +usb:v0471p2076* + ID_PRODUCT_FROM_DATABASE=GoGear Aria + +usb:v0471p2079* + ID_PRODUCT_FROM_DATABASE=GoGear Opus + +usb:v0471p2088* + ID_PRODUCT_FROM_DATABASE=MCE IR Receiver with ALS- Spinel plus for ASUS + +usb:v0471p209E* + ID_PRODUCT_FROM_DATABASE=PTA01 Wireless Adapter + +usb:v0471p20B6* + ID_PRODUCT_FROM_DATABASE=GoGear Vibe + +usb:v0471p20D0* + ID_PRODUCT_FROM_DATABASE=SPZ2000 Webcam [PixArt PAC7332] + +usb:v0471p20E3* + ID_PRODUCT_FROM_DATABASE=GoGear Raga + +usb:v0471p262C* + ID_PRODUCT_FROM_DATABASE=SPC230NC Webcam + +usb:v0471p485D* + ID_PRODUCT_FROM_DATABASE=Senselock SenseIV v2.x + +usb:v0471pDF55* + ID_PRODUCT_FROM_DATABASE=LPCXpresso LPC-Link + +usb:v0472* + ID_VENDOR_FROM_DATABASE=Chicony Electronics Co., Ltd + +usb:v0472p0065* + ID_PRODUCT_FROM_DATABASE=PFU-65 Keyboard [Chicony] + +usb:v0472pB086* + ID_PRODUCT_FROM_DATABASE=Asus USB2.0 Webcam + +usb:v0472pB091* + ID_PRODUCT_FROM_DATABASE=Webcam + +usb:v0473* + ID_VENDOR_FROM_DATABASE=Sanyo Information Business Co., Ltd + +usb:v0474* + ID_VENDOR_FROM_DATABASE=Sanyo Electric Co., Ltd + +usb:v0474p0110* + ID_PRODUCT_FROM_DATABASE=Digital Voice Recorder R200 + +usb:v0474p0217* + ID_PRODUCT_FROM_DATABASE=Xacti J2 + +usb:v0474p022F* + ID_PRODUCT_FROM_DATABASE=C5 Digital Media Camera (mass storage mode) + +usb:v0474p0230* + ID_PRODUCT_FROM_DATABASE=C5 Digital Media Camera (PictBridge mode) + +usb:v0474p0231* + ID_PRODUCT_FROM_DATABASE=C5 Digital Media Camera (PC control mode) + +usb:v0474p0401* + ID_PRODUCT_FROM_DATABASE=Optical Drive + +usb:v0474p0701* + ID_PRODUCT_FROM_DATABASE=SCP-4900 Cellphone + +usb:v0474p071F* + ID_PRODUCT_FROM_DATABASE=Usb Com Port Enumerator + +usb:v0474p0722* + ID_PRODUCT_FROM_DATABASE=W33SA Camera + +usb:v0475* + ID_VENDOR_FROM_DATABASE=Relisys/Teco Information System + +usb:v0475p0100* + ID_PRODUCT_FROM_DATABASE=NEC Petiscan + +usb:v0475p0103* + ID_PRODUCT_FROM_DATABASE=Eclipse 1200U/Episode + +usb:v0475p0210* + ID_PRODUCT_FROM_DATABASE=Scorpio Ultra 3 + +usb:v0476* + ID_VENDOR_FROM_DATABASE=AESP + +usb:v0477* + ID_VENDOR_FROM_DATABASE=Seagate Technology, Inc. + +usb:v0478* + ID_VENDOR_FROM_DATABASE=Connectix Corp. + +usb:v0478p0001* + ID_PRODUCT_FROM_DATABASE=QuickCam + +usb:v0478p0002* + ID_PRODUCT_FROM_DATABASE=QuickClip + +usb:v0478p0003* + ID_PRODUCT_FROM_DATABASE=QuickCam Pro + +usb:v0479* + ID_VENDOR_FROM_DATABASE=Advanced Peripheral Laboratories + +usb:v047A* + ID_VENDOR_FROM_DATABASE=Semtech Corp. + +usb:v047Ap0004* + ID_PRODUCT_FROM_DATABASE=ScreenCoder UR7HCTS2-USB + +usb:v047B* + ID_VENDOR_FROM_DATABASE=Silitek Corp. + +usb:v047Bp0001* + ID_PRODUCT_FROM_DATABASE=Keyboard + +usb:v047Bp0002* + ID_PRODUCT_FROM_DATABASE=Keyboard and Mouse + +usb:v047Bp0011* + ID_PRODUCT_FROM_DATABASE=SK-1688U Keyboard + +usb:v047Bp00F9* + ID_PRODUCT_FROM_DATABASE=SK-1789u Keyboard + +usb:v047Bp0101* + ID_PRODUCT_FROM_DATABASE=BlueTooth Keyboard and Mouse + +usb:v047Bp020B* + ID_PRODUCT_FROM_DATABASE=SK-3105 SmartCard Reader + +usb:v047Bp050E* + ID_PRODUCT_FROM_DATABASE=Internet Compact Keyboard + +usb:v047Bp1000* + ID_PRODUCT_FROM_DATABASE=Trust Office Scan USB 19200 + +usb:v047Bp1002* + ID_PRODUCT_FROM_DATABASE=HP ScanJet 4300c Parallel Port + +usb:v047C* + ID_VENDOR_FROM_DATABASE=Dell Computer Corp. + +usb:v047D* + ID_VENDOR_FROM_DATABASE=Kensington + +usb:v047Dp1001* + ID_PRODUCT_FROM_DATABASE=Mouse*in*a*Box + +usb:v047Dp1002* + ID_PRODUCT_FROM_DATABASE=Expert Mouse Pro + +usb:v047Dp1003* + ID_PRODUCT_FROM_DATABASE=Orbit TrackBall + +usb:v047Dp1004* + ID_PRODUCT_FROM_DATABASE=MouseWorks + +usb:v047Dp1005* + ID_PRODUCT_FROM_DATABASE=TurboBall + +usb:v047Dp1006* + ID_PRODUCT_FROM_DATABASE=TurboRing + +usb:v047Dp1009* + ID_PRODUCT_FROM_DATABASE=Orbit TrackBall for Mac + +usb:v047Dp1012* + ID_PRODUCT_FROM_DATABASE=PocketMouse + +usb:v047Dp1013* + ID_PRODUCT_FROM_DATABASE=Mouse*in*a*Box Optical Pro + +usb:v047Dp1014* + ID_PRODUCT_FROM_DATABASE=Expert Mouse Pro Wireless + +usb:v047Dp1015* + ID_PRODUCT_FROM_DATABASE=Expert Mouse + +usb:v047Dp1016* + ID_PRODUCT_FROM_DATABASE=ADB/USB Orbit + +usb:v047Dp1018* + ID_PRODUCT_FROM_DATABASE=Studio Mouse + +usb:v047Dp101D* + ID_PRODUCT_FROM_DATABASE=Mouse*in*a*Box Optical Pro + +usb:v047Dp101E* + ID_PRODUCT_FROM_DATABASE=Studio Mouse Wireless + +usb:v047Dp101F* + ID_PRODUCT_FROM_DATABASE=PocketMouse Pro + +usb:v047Dp1020* + ID_PRODUCT_FROM_DATABASE=Expert Mouse Trackball + +usb:v047Dp1021* + ID_PRODUCT_FROM_DATABASE=Expert Mouse Wireless + +usb:v047Dp1022* + ID_PRODUCT_FROM_DATABASE=Orbit Optical + +usb:v047Dp1023* + ID_PRODUCT_FROM_DATABASE=Pocket Mouse Pro Wireless + +usb:v047Dp1024* + ID_PRODUCT_FROM_DATABASE=PocketMouse + +usb:v047Dp1025* + ID_PRODUCT_FROM_DATABASE=Mouse*in*a*Box Optical Elite Wireless + +usb:v047Dp1026* + ID_PRODUCT_FROM_DATABASE=Pocket Mouse Pro + +usb:v047Dp1027* + ID_PRODUCT_FROM_DATABASE=StudioMouse + +usb:v047Dp1028* + ID_PRODUCT_FROM_DATABASE=StudioMouse Wireless + +usb:v047Dp1029* + ID_PRODUCT_FROM_DATABASE=Mouse*in*a*Box Optical Elite + +usb:v047Dp102A* + ID_PRODUCT_FROM_DATABASE=Mouse*in*a*Box Optical + +usb:v047Dp102B* + ID_PRODUCT_FROM_DATABASE=PocketMouse + +usb:v047Dp102C* + ID_PRODUCT_FROM_DATABASE=Iridio + +usb:v047Dp102D* + ID_PRODUCT_FROM_DATABASE=Pilot Optical + +usb:v047Dp102E* + ID_PRODUCT_FROM_DATABASE=Pilot Optical Pro + +usb:v047Dp102F* + ID_PRODUCT_FROM_DATABASE=Pilot Optical Pro Wireless + +usb:v047Dp1042* + ID_PRODUCT_FROM_DATABASE=Ci25m Notebook Optical Mouse [Diamond Eye Precision] + +usb:v047Dp1043* + ID_PRODUCT_FROM_DATABASE=Ci65m Wireless Notebook Optical Mouse + +usb:v047Dp104A* + ID_PRODUCT_FROM_DATABASE=PilotMouse Mini Retractable + +usb:v047Dp105D* + ID_PRODUCT_FROM_DATABASE=PocketMouse Bluetooth + +usb:v047Dp105E* + ID_PRODUCT_FROM_DATABASE=Bluetooth EDR Dongle + +usb:v047Dp1061* + ID_PRODUCT_FROM_DATABASE=PocketMouse Grip + +usb:v047Dp1062* + ID_PRODUCT_FROM_DATABASE=PocketMouse Max + +usb:v047Dp1063* + ID_PRODUCT_FROM_DATABASE=PocketMouse Max Wireless + +usb:v047Dp1064* + ID_PRODUCT_FROM_DATABASE=PocketMouse 2.0 Wireless + +usb:v047Dp1065* + ID_PRODUCT_FROM_DATABASE=PocketMouse 2.0 + +usb:v047Dp1066* + ID_PRODUCT_FROM_DATABASE=PocketMouse Max Glow + +usb:v047Dp1067* + ID_PRODUCT_FROM_DATABASE=ValueMouse + +usb:v047Dp1068* + ID_PRODUCT_FROM_DATABASE=ValueOpt White + +usb:v047Dp1069* + ID_PRODUCT_FROM_DATABASE=ValueOpt Black + +usb:v047Dp106A* + ID_PRODUCT_FROM_DATABASE=PilotMouse Laser Wireless Mini + +usb:v047Dp106B* + ID_PRODUCT_FROM_DATABASE=PilotMouse Laser - 3 Button + +usb:v047Dp106C* + ID_PRODUCT_FROM_DATABASE=PilotMouse Laser - Gaming + +usb:v047Dp106D* + ID_PRODUCT_FROM_DATABASE=PilotMouse Laser - Wired + +usb:v047Dp106E* + ID_PRODUCT_FROM_DATABASE=PilotMouse Micro Laser + +usb:v047Dp1070* + ID_PRODUCT_FROM_DATABASE=ValueOpt Travel + +usb:v047Dp1071* + ID_PRODUCT_FROM_DATABASE=ValueOpt RF TX + +usb:v047Dp1072* + ID_PRODUCT_FROM_DATABASE=PocketMouse Colour + +usb:v047Dp1073* + ID_PRODUCT_FROM_DATABASE=PilotMouse Laser - 6 Button + +usb:v047Dp1074* + ID_PRODUCT_FROM_DATABASE=PilotMouse Laser Wireless Mini + +usb:v047Dp1075* + ID_PRODUCT_FROM_DATABASE=SlimBlade Presenter Media Mouse + +usb:v047Dp1076* + ID_PRODUCT_FROM_DATABASE=SlimBlade Media Mouse + +usb:v047Dp1077* + ID_PRODUCT_FROM_DATABASE=SlimBlade Presenter Mouse + +usb:v047Dp1152* + ID_PRODUCT_FROM_DATABASE=Bluetooth EDR Dongle + +usb:v047Dp2002* + ID_PRODUCT_FROM_DATABASE=Optical Elite Wireless + +usb:v047Dp2010* + ID_PRODUCT_FROM_DATABASE=Wireless Presentation Remote + +usb:v047Dp2012* + ID_PRODUCT_FROM_DATABASE=Wireless Presenter with Laser Pointer + +usb:v047Dp2021* + ID_PRODUCT_FROM_DATABASE=PilotBoard Wireless + +usb:v047Dp2030* + ID_PRODUCT_FROM_DATABASE=PilotBoard Wireless + +usb:v047Dp2034* + ID_PRODUCT_FROM_DATABASE=SlimBlade Media Notebook Set + +usb:v047Dp2041* + ID_PRODUCT_FROM_DATABASE=SlimBlade Trackball + +usb:v047Dp2048* + ID_PRODUCT_FROM_DATABASE=Orbit Trackball with Scroll Ring + +usb:v047Dp4003* + ID_PRODUCT_FROM_DATABASE=Gravis Xterminator Digital Gamepad + +usb:v047Dp4005* + ID_PRODUCT_FROM_DATABASE=Gravis Eliminator GamePad Pro + +usb:v047Dp4006* + ID_PRODUCT_FROM_DATABASE=Gravis Eliminator AfterShock + +usb:v047Dp4007* + ID_PRODUCT_FROM_DATABASE=Gravis Xterminator Force + +usb:v047Dp4008* + ID_PRODUCT_FROM_DATABASE=Gravis Destroyer TiltPad + +usb:v047Dp5001* + ID_PRODUCT_FROM_DATABASE=Cabo I Camera + +usb:v047Dp5002* + ID_PRODUCT_FROM_DATABASE=VideoCam CABO II + +usb:v047Dp5003* + ID_PRODUCT_FROM_DATABASE=VideoCam + +usb:v047E* + ID_VENDOR_FROM_DATABASE=Agere Systems, Inc. (Lucent) + +usb:v047Ep0300* + ID_PRODUCT_FROM_DATABASE=ORiNOCO Card + +usb:v047Ep1001* + ID_PRODUCT_FROM_DATABASE=USS720 Parallel Port + +usb:v047Ep2892* + ID_PRODUCT_FROM_DATABASE=Systems Soft Modem + +usb:v047EpBAD1* + ID_PRODUCT_FROM_DATABASE=Lucent 56k Modem + +usb:v047EpF101* + ID_PRODUCT_FROM_DATABASE=Atlas Modem + +usb:v047F* + ID_VENDOR_FROM_DATABASE=Plantronics, Inc. + +usb:v047Fp0101* + ID_PRODUCT_FROM_DATABASE=Bulk Driver + +usb:v047Fp0301* + ID_PRODUCT_FROM_DATABASE=Bulk Driver + +usb:v047Fp0411* + ID_PRODUCT_FROM_DATABASE=Savi Office Base Station + +usb:v047Fp0CA1* + ID_PRODUCT_FROM_DATABASE=USB DSP v4 Audio Interface + +usb:v047Fp4254* + ID_PRODUCT_FROM_DATABASE=BUA-100 Bluetooth Adapter + +usb:v047FpAC01* + ID_PRODUCT_FROM_DATABASE=Savi 7xx + +usb:v047FpAD01* + ID_PRODUCT_FROM_DATABASE=GameCom 777 5.1 Headset + +usb:v0480* + ID_VENDOR_FROM_DATABASE=Toshiba America Info. Systems, Inc. + +usb:v0480p0001* + ID_PRODUCT_FROM_DATABASE=InTouch Module + +usb:v0480p0004* + ID_PRODUCT_FROM_DATABASE=InTouch Module + +usb:v0480p0011* + ID_PRODUCT_FROM_DATABASE=InTouch Module + +usb:v0480p0014* + ID_PRODUCT_FROM_DATABASE=InTouch Module + +usb:v0480pA007* + ID_PRODUCT_FROM_DATABASE=External Disk USB 3.0 + +usb:v0481* + ID_VENDOR_FROM_DATABASE=Zenith Data Systems + +usb:v0482* + ID_VENDOR_FROM_DATABASE=Kyocera Corp. + +usb:v0482p000E* + ID_PRODUCT_FROM_DATABASE=FS-1020D Printer + +usb:v0482p0100* + ID_PRODUCT_FROM_DATABASE=Finecam S3x + +usb:v0482p0101* + ID_PRODUCT_FROM_DATABASE=Finecam S4 + +usb:v0482p0103* + ID_PRODUCT_FROM_DATABASE=Finecam S5 + +usb:v0482p0105* + ID_PRODUCT_FROM_DATABASE=Finecam L3 + +usb:v0482p0106* + ID_PRODUCT_FROM_DATABASE=Finecam + +usb:v0482p0107* + ID_PRODUCT_FROM_DATABASE=Digital Camera Device + +usb:v0482p0108* + ID_PRODUCT_FROM_DATABASE=Digital Camera Device + +usb:v0482p0203* + ID_PRODUCT_FROM_DATABASE=AH-K3001V + +usb:v0482p0204* + ID_PRODUCT_FROM_DATABASE=iBurst Terminal + +usb:v0483* + ID_VENDOR_FROM_DATABASE=SGS Thomson Microelectronics + +usb:v0483p0137* + ID_PRODUCT_FROM_DATABASE=BeWAN ADSL USB ST (blue or green) + +usb:v0483p0138* + ID_PRODUCT_FROM_DATABASE=Unicorn II (ST70138B + MTC-20174TQ chipset) + +usb:v0483p1307* + ID_PRODUCT_FROM_DATABASE=Cytronix 6in1 Card Reader + +usb:v0483p163D* + ID_PRODUCT_FROM_DATABASE=Cool Icam Digi-MP3 + +usb:v0483p2015* + ID_PRODUCT_FROM_DATABASE=TouchChip® Fingerprint Reader + +usb:v0483p2016* + ID_PRODUCT_FROM_DATABASE=Fingerprint Reader + +usb:v0483p2017* + ID_PRODUCT_FROM_DATABASE=Biometric Smart Card Reader + +usb:v0483p2018* + ID_PRODUCT_FROM_DATABASE=BioSimKey + +usb:v0483p2302* + ID_PRODUCT_FROM_DATABASE=Portable Flash Device (PFD) + +usb:v0483p3744* + ID_PRODUCT_FROM_DATABASE=STLINK Pseudo disk + +usb:v0483p3747* + ID_PRODUCT_FROM_DATABASE=ST Micro Connect Lite + +usb:v0483p3748* + ID_PRODUCT_FROM_DATABASE=ST-LINK/V2 + +usb:v0483p4810* + ID_PRODUCT_FROM_DATABASE=ISDN adapter + +usb:v0483p481D* + ID_PRODUCT_FROM_DATABASE=BT Digital Access adapter + +usb:v0483p5000* + ID_PRODUCT_FROM_DATABASE=ST Micro/Ergenic ERG BT-002 Bluetooth Adapter + +usb:v0483p5001* + ID_PRODUCT_FROM_DATABASE=ST Micro Bluetooth Device + +usb:v0483p5710* + ID_PRODUCT_FROM_DATABASE=Joystick in FS Mode + +usb:v0483p5721* + ID_PRODUCT_FROM_DATABASE=Hantek DDS-3X25 Arbitrary Waveform Generator + +usb:v0483p7270* + ID_PRODUCT_FROM_DATABASE=ST Micro Serial Bridge + +usb:v0483p7554* + ID_PRODUCT_FROM_DATABASE=56k SoftModem + +usb:v0483pDF11* + ID_PRODUCT_FROM_DATABASE=STM Device in DFU Mode + +usb:v0483pFF10* + ID_PRODUCT_FROM_DATABASE=Swann ST56 Modem + +usb:v0484* + ID_VENDOR_FROM_DATABASE=Specialix + +usb:v0485* + ID_VENDOR_FROM_DATABASE=Nokia Monitors + +usb:v0486* + ID_VENDOR_FROM_DATABASE=ASUS Computers, Inc. + +usb:v0486p0185* + ID_PRODUCT_FROM_DATABASE=EeePC T91MT HID Touch Panel + +usb:v0487* + ID_VENDOR_FROM_DATABASE=Stewart Connector + +usb:v0488* + ID_VENDOR_FROM_DATABASE=Cirque Corp. + +usb:v0489* + ID_VENDOR_FROM_DATABASE=Foxconn / Hon Hai + +usb:v0489p0502* + ID_PRODUCT_FROM_DATABASE=SmartMedia Card Reader Firmware Loader + +usb:v0489p0503* + ID_PRODUCT_FROM_DATABASE=SmartMedia Card Reader + +usb:v0489pD00C* + ID_PRODUCT_FROM_DATABASE=Rollei Compactline (Storage Mode) + +usb:v0489pD00E* + ID_PRODUCT_FROM_DATABASE=Rollei Compactline (Video Mode) + +usb:v0489pE000* + ID_PRODUCT_FROM_DATABASE=T-Com TC 300 + +usb:v0489pE003* + ID_PRODUCT_FROM_DATABASE=Pirelli DP-L10 + +usb:v0489pE00D* + ID_PRODUCT_FROM_DATABASE=Broadcom Bluetooth 2.1 Device + +usb:v0489pE00F* + ID_PRODUCT_FROM_DATABASE=Foxconn T77H114 BCM2070 [Single-Chip Bluetooth 2.1 + EDR Adapter] + +usb:v0489pE016* + ID_PRODUCT_FROM_DATABASE=Ubee PXU1900 WiMAX Adapter [Beceem BCSM250] + +usb:v0489pE02C* + ID_PRODUCT_FROM_DATABASE=Atheros AR5BBU12 Bluetooth Device + +usb:v048A* + ID_VENDOR_FROM_DATABASE=S-MOS Systems, Inc. + +usb:v048C* + ID_VENDOR_FROM_DATABASE=Alps Electric Ireland, Ltd + +usb:v048D* + ID_VENDOR_FROM_DATABASE=Integrated Technology Express, Inc. + +usb:v048Dp1165* + ID_PRODUCT_FROM_DATABASE=IT1165 Flash Controller + +usb:v048Dp1336* + ID_PRODUCT_FROM_DATABASE=SD/MMC Cardreader + +usb:v048Dp1345* + ID_PRODUCT_FROM_DATABASE=Multi Cardreader + +usb:v048Dp9006* + ID_PRODUCT_FROM_DATABASE=IT9135 BDA Afatech DVB-T HDTV Dongle + +usb:v048Dp9009* + ID_PRODUCT_FROM_DATABASE=Zolid HD DVD Maker + +usb:v048Dp9135* + ID_PRODUCT_FROM_DATABASE=Zolid Mini DVB-T Stick + +usb:v048F* + ID_VENDOR_FROM_DATABASE=Eicon Tech. + +usb:v0490* + ID_VENDOR_FROM_DATABASE=United Microelectronics Corp. + +usb:v0491* + ID_VENDOR_FROM_DATABASE=Capetronic + +usb:v0491p0003* + ID_PRODUCT_FROM_DATABASE=Taxan Monitor Control + +usb:v0492* + ID_VENDOR_FROM_DATABASE=Samsung SemiConductor, Inc. + +usb:v0492p0140* + ID_PRODUCT_FROM_DATABASE=MP3 player + +usb:v0492p0141* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v0493* + ID_VENDOR_FROM_DATABASE=MAG Technology Co., Ltd + +usb:v0495* + ID_VENDOR_FROM_DATABASE=ESS Technology, Inc. + +usb:v0496* + ID_VENDOR_FROM_DATABASE=Micron Electronics + +usb:v0497* + ID_VENDOR_FROM_DATABASE=Smile International + +usb:v0497pC001* + ID_PRODUCT_FROM_DATABASE=Camera Device + +usb:v0498* + ID_VENDOR_FROM_DATABASE=Capetronic (Kaohsiung) Corp. + +usb:v0499* + ID_VENDOR_FROM_DATABASE=Yamaha Corp. + +usb:v0499p1000* + ID_PRODUCT_FROM_DATABASE=UX256 MIDI I/F + +usb:v0499p1001* + ID_PRODUCT_FROM_DATABASE=MU1000 + +usb:v0499p1002* + ID_PRODUCT_FROM_DATABASE=MU2000 + +usb:v0499p1003* + ID_PRODUCT_FROM_DATABASE=MU500 + +usb:v0499p1004* + ID_PRODUCT_FROM_DATABASE=UW500 + +usb:v0499p1005* + ID_PRODUCT_FROM_DATABASE=MOTIF6 + +usb:v0499p1006* + ID_PRODUCT_FROM_DATABASE=MOTIF7 + +usb:v0499p1007* + ID_PRODUCT_FROM_DATABASE=MOTIF8 + +usb:v0499p1008* + ID_PRODUCT_FROM_DATABASE=UX96 MIDI I/F + +usb:v0499p1009* + ID_PRODUCT_FROM_DATABASE=UX16 MIDI I/F + +usb:v0499p100A* + ID_PRODUCT_FROM_DATABASE=EOS BX + +usb:v0499p100C* + ID_PRODUCT_FROM_DATABASE=UC-MX + +usb:v0499p100D* + ID_PRODUCT_FROM_DATABASE=UC-KX + +usb:v0499p100E* + ID_PRODUCT_FROM_DATABASE=S08 + +usb:v0499p100F* + ID_PRODUCT_FROM_DATABASE=CLP-150 + +usb:v0499p1010* + ID_PRODUCT_FROM_DATABASE=CLP-170 + +usb:v0499p1011* + ID_PRODUCT_FROM_DATABASE=P-250 + +usb:v0499p1012* + ID_PRODUCT_FROM_DATABASE=TYROS + +usb:v0499p1013* + ID_PRODUCT_FROM_DATABASE=PF-500 + +usb:v0499p1014* + ID_PRODUCT_FROM_DATABASE=S90 + +usb:v0499p1015* + ID_PRODUCT_FROM_DATABASE=MOTIF-R + +usb:v0499p1016* + ID_PRODUCT_FROM_DATABASE=MDP-5 + +usb:v0499p1017* + ID_PRODUCT_FROM_DATABASE=CVP-204 + +usb:v0499p1018* + ID_PRODUCT_FROM_DATABASE=CVP-206 + +usb:v0499p1019* + ID_PRODUCT_FROM_DATABASE=CVP-208 + +usb:v0499p101A* + ID_PRODUCT_FROM_DATABASE=CVP-210 + +usb:v0499p101B* + ID_PRODUCT_FROM_DATABASE=PSR-1100 + +usb:v0499p101C* + ID_PRODUCT_FROM_DATABASE=PSR-2100 + +usb:v0499p101D* + ID_PRODUCT_FROM_DATABASE=CLP-175 + +usb:v0499p101E* + ID_PRODUCT_FROM_DATABASE=PSR-K1 + +usb:v0499p101F* + ID_PRODUCT_FROM_DATABASE=EZ-J24 + +usb:v0499p1020* + ID_PRODUCT_FROM_DATABASE=EZ-250i + +usb:v0499p1021* + ID_PRODUCT_FROM_DATABASE=MOTIF ES 6 + +usb:v0499p1022* + ID_PRODUCT_FROM_DATABASE=MOTIF ES 7 + +usb:v0499p1023* + ID_PRODUCT_FROM_DATABASE=MOTIF ES 8 + +usb:v0499p1024* + ID_PRODUCT_FROM_DATABASE=CVP-301 + +usb:v0499p1025* + ID_PRODUCT_FROM_DATABASE=CVP-303 + +usb:v0499p1026* + ID_PRODUCT_FROM_DATABASE=CVP-305 + +usb:v0499p1027* + ID_PRODUCT_FROM_DATABASE=CVP-307 + +usb:v0499p1028* + ID_PRODUCT_FROM_DATABASE=CVP-309 + +usb:v0499p1029* + ID_PRODUCT_FROM_DATABASE=CVP-309GP + +usb:v0499p102A* + ID_PRODUCT_FROM_DATABASE=PSR-1500 + +usb:v0499p102B* + ID_PRODUCT_FROM_DATABASE=PSR-3000 + +usb:v0499p102E* + ID_PRODUCT_FROM_DATABASE=ELS-01/01C + +usb:v0499p1030* + ID_PRODUCT_FROM_DATABASE=PSR-295/293 + +usb:v0499p1031* + ID_PRODUCT_FROM_DATABASE=DGX-205/203 + +usb:v0499p1032* + ID_PRODUCT_FROM_DATABASE=DGX-305 + +usb:v0499p1033* + ID_PRODUCT_FROM_DATABASE=DGX-505 + +usb:v0499p1037* + ID_PRODUCT_FROM_DATABASE=PSR-E403 + +usb:v0499p103C* + ID_PRODUCT_FROM_DATABASE=MOTIF-RACK ES + +usb:v0499p1054* + ID_PRODUCT_FROM_DATABASE=S90XS Keyboard/Music Synthesizer + +usb:v0499p2000* + ID_PRODUCT_FROM_DATABASE=DGP-7 + +usb:v0499p2001* + ID_PRODUCT_FROM_DATABASE=DGP-5 + +usb:v0499p3001* + ID_PRODUCT_FROM_DATABASE=YST-MS55D USB Speaker + +usb:v0499p3003* + ID_PRODUCT_FROM_DATABASE=YST-M45D USB Speaker + +usb:v0499p4000* + ID_PRODUCT_FROM_DATABASE=NetVolante RTA54i Broadband&ISDN Router + +usb:v0499p4001* + ID_PRODUCT_FROM_DATABASE=NetVolante RTW65b Broadband Wireless Router + +usb:v0499p4002* + ID_PRODUCT_FROM_DATABASE=NetVolante RTW65i Broadband&ISDN Wireless Router + +usb:v0499p4004* + ID_PRODUCT_FROM_DATABASE=NetVolante RTA55i Broadband VoIP Router + +usb:v0499p5000* + ID_PRODUCT_FROM_DATABASE=CS1D + +usb:v0499p5001* + ID_PRODUCT_FROM_DATABASE=DSP1D + +usb:v0499p5002* + ID_PRODUCT_FROM_DATABASE=DME32 + +usb:v0499p5003* + ID_PRODUCT_FROM_DATABASE=DM2000 + +usb:v0499p5004* + ID_PRODUCT_FROM_DATABASE=02R96 + +usb:v0499p5005* + ID_PRODUCT_FROM_DATABASE=ACU16-C + +usb:v0499p5006* + ID_PRODUCT_FROM_DATABASE=NHB32-C + +usb:v0499p5007* + ID_PRODUCT_FROM_DATABASE=DM1000 + +usb:v0499p5008* + ID_PRODUCT_FROM_DATABASE=01V96 + +usb:v0499p5009* + ID_PRODUCT_FROM_DATABASE=SPX2000 + +usb:v0499p500A* + ID_PRODUCT_FROM_DATABASE=PM5D + +usb:v0499p500B* + ID_PRODUCT_FROM_DATABASE=DME64N + +usb:v0499p500C* + ID_PRODUCT_FROM_DATABASE=DME24N + +usb:v0499p6001* + ID_PRODUCT_FROM_DATABASE=CRW2200UX Lightspeed 2 External CD-RW Drive + +usb:v0499p7000* + ID_PRODUCT_FROM_DATABASE=DTX + +usb:v0499p7010* + ID_PRODUCT_FROM_DATABASE=UB99 + +usb:v049A* + ID_VENDOR_FROM_DATABASE=Gandalf Technologies, Ltd + +usb:v049B* + ID_VENDOR_FROM_DATABASE=Curtis Computer Products + +usb:v049C* + ID_VENDOR_FROM_DATABASE=Acer Advanced Labs, Inc. + +usb:v049Cp0002* + ID_PRODUCT_FROM_DATABASE=Keyboard (???) + +usb:v049D* + ID_VENDOR_FROM_DATABASE=VLSI Technology + +usb:v049F* + ID_VENDOR_FROM_DATABASE=Compaq Computer Corp. + +usb:v049Fp0002* + ID_PRODUCT_FROM_DATABASE=InkJet Color Printer + +usb:v049Fp0003* + ID_PRODUCT_FROM_DATABASE=iPAQ PocketPC + +usb:v049Fp000E* + ID_PRODUCT_FROM_DATABASE=Internet Keyboard + +usb:v049Fp0012* + ID_PRODUCT_FROM_DATABASE=InkJet Color Printer + +usb:v049Fp0018* + ID_PRODUCT_FROM_DATABASE=PA-1/PA-2 MP3 Player + +usb:v049Fp0019* + ID_PRODUCT_FROM_DATABASE=InkJet Color Printer + +usb:v049Fp001A* + ID_PRODUCT_FROM_DATABASE=S4 100 Scanner + +usb:v049Fp001E* + ID_PRODUCT_FROM_DATABASE=IJ650 Inkjet Printer + +usb:v049Fp001F* + ID_PRODUCT_FROM_DATABASE=WL215 Adapter + +usb:v049Fp0021* + ID_PRODUCT_FROM_DATABASE=S200 Scanner + +usb:v049Fp0027* + ID_PRODUCT_FROM_DATABASE=Bluetooth Multiport Module by Compaq + +usb:v049Fp002A* + ID_PRODUCT_FROM_DATABASE=1400P Inkjet Printer + +usb:v049Fp002B* + ID_PRODUCT_FROM_DATABASE=A3000 + +usb:v049Fp002C* + ID_PRODUCT_FROM_DATABASE=Lexmark X125 + +usb:v049Fp0032* + ID_PRODUCT_FROM_DATABASE=802.11b Adapter [ipaq h5400] + +usb:v049Fp0033* + ID_PRODUCT_FROM_DATABASE=Wireless LAN MultiPort W100 [Intersil PRISM 2.5] + +usb:v049Fp0036* + ID_PRODUCT_FROM_DATABASE=Bluetooth Multiport Module + +usb:v049Fp0051* + ID_PRODUCT_FROM_DATABASE=KU-0133 Easy Access Interner Keyboard + +usb:v049Fp0076* + ID_PRODUCT_FROM_DATABASE=Wireless LAN MultiPort W200 + +usb:v049Fp0080* + ID_PRODUCT_FROM_DATABASE=GPRS Multiport + +usb:v049Fp0086* + ID_PRODUCT_FROM_DATABASE=Bluetooth Device + +usb:v049Fp504A* + ID_PRODUCT_FROM_DATABASE=Personal Jukebox PJB100 + +usb:v049Fp505A* + ID_PRODUCT_FROM_DATABASE=Linux-USB "CDC Subset" Device, or Itsy (experimental) + +usb:v049Fp8511* + ID_PRODUCT_FROM_DATABASE=iPAQ Networking 10/100 Ethernet [pegasus2] + +usb:v04A0* + ID_VENDOR_FROM_DATABASE=Digital Equipment Corp. + +usb:v04A1* + ID_VENDOR_FROM_DATABASE=SystemSoft Corp. + +usb:v04A1pFFF0* + ID_PRODUCT_FROM_DATABASE=Telex Composite Device + +usb:v04A2* + ID_VENDOR_FROM_DATABASE=FirePower Systems + +usb:v04A3* + ID_VENDOR_FROM_DATABASE=Trident Microsystems, Inc. + +usb:v04A4* + ID_VENDOR_FROM_DATABASE=Hitachi, Ltd + +usb:v04A4p0004* + ID_PRODUCT_FROM_DATABASE=DVD-CAM DZ-MV100A Camcorder + +usb:v04A4p001E* + ID_PRODUCT_FROM_DATABASE=DVDCAM USB HS Interface + +usb:v04A5* + ID_VENDOR_FROM_DATABASE=Acer Peripherals Inc. (now BenQ Corp.) + +usb:v04A5p0001* + ID_PRODUCT_FROM_DATABASE=Keyboard + +usb:v04A5p0002* + ID_PRODUCT_FROM_DATABASE=API Ergo K/B + +usb:v04A5p0003* + ID_PRODUCT_FROM_DATABASE=API Generic K/B Mouse + +usb:v04A5p12A6* + ID_PRODUCT_FROM_DATABASE=AcerScan C310U + +usb:v04A5p1A20* + ID_PRODUCT_FROM_DATABASE=Prisa 310U + +usb:v04A5p1A2A* + ID_PRODUCT_FROM_DATABASE=Prisa 620U + +usb:v04A5p2022* + ID_PRODUCT_FROM_DATABASE=Prisa 320U/340U + +usb:v04A5p2040* + ID_PRODUCT_FROM_DATABASE=Prisa 620UT + +usb:v04A5p205E* + ID_PRODUCT_FROM_DATABASE=ScanPrisa 640BU + +usb:v04A5p2060* + ID_PRODUCT_FROM_DATABASE=Prisa 620U+/640U + +usb:v04A5p207E* + ID_PRODUCT_FROM_DATABASE=Prisa 640BU + +usb:v04A5p209E* + ID_PRODUCT_FROM_DATABASE=ScanPrisa 640BT + +usb:v04A5p20AE* + ID_PRODUCT_FROM_DATABASE=S2W 3000U + +usb:v04A5p20B0* + ID_PRODUCT_FROM_DATABASE=S2W 3300U/4300U + +usb:v04A5p20BE* + ID_PRODUCT_FROM_DATABASE=Prisa 640BT + +usb:v04A5p20C0* + ID_PRODUCT_FROM_DATABASE=Prisa 1240UT + +usb:v04A5p20DE* + ID_PRODUCT_FROM_DATABASE=S2W 4300U+ + +usb:v04A5p20F8* + ID_PRODUCT_FROM_DATABASE=Benq 5000 + +usb:v04A5p20FC* + ID_PRODUCT_FROM_DATABASE=Benq 5000 + +usb:v04A5p20FE* + ID_PRODUCT_FROM_DATABASE=SW2 5300U + +usb:v04A5p2137* + ID_PRODUCT_FROM_DATABASE=Benq 5150/5250 + +usb:v04A5p2202* + ID_PRODUCT_FROM_DATABASE=Benq 7400UT + +usb:v04A5p2311* + ID_PRODUCT_FROM_DATABASE=Benq 5560 + +usb:v04A5p3003* + ID_PRODUCT_FROM_DATABASE=Benq Webcam + +usb:v04A5p3008* + ID_PRODUCT_FROM_DATABASE=Benq 1500 + +usb:v04A5p300A* + ID_PRODUCT_FROM_DATABASE=Benq 3410 + +usb:v04A5p300C* + ID_PRODUCT_FROM_DATABASE=Benq 1016 + +usb:v04A5p3019* + ID_PRODUCT_FROM_DATABASE=Benq DC C40 + +usb:v04A5p4000* + ID_PRODUCT_FROM_DATABASE=P30 Composite Device + +usb:v04A5p4013* + ID_PRODUCT_FROM_DATABASE=BenQ-Siemens EF82/SL91 + +usb:v04A5p4044* + ID_PRODUCT_FROM_DATABASE=BenQ-Siemens SF71 + +usb:v04A5p4045* + ID_PRODUCT_FROM_DATABASE=BenQ-Siemens E81 + +usb:v04A5p4048* + ID_PRODUCT_FROM_DATABASE=BenQ M7 + +usb:v04A5p6001* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v04A5p6002* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v04A5p6003* + ID_PRODUCT_FROM_DATABASE=ATA/ATAPI Adapter + +usb:v04A5p6004* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v04A5p6005* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v04A5p6006* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v04A5p6007* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v04A5p6008* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v04A5p6009* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v04A5p600A* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v04A5p600B* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v04A5p600C* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v04A5p600D* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v04A5p600E* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v04A5p600F* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v04A5p6010* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v04A5p6011* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v04A5p6012* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v04A5p6013* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v04A5p6014* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v04A5p6015* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v04A5p6125* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v04A5p6180* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v04A5p6200* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v04A5p7500* + ID_PRODUCT_FROM_DATABASE=Hi-Speed Mass Storage Device + +usb:v04A5p9000* + ID_PRODUCT_FROM_DATABASE=AWL300 Wireless Adapter + +usb:v04A5p9001* + ID_PRODUCT_FROM_DATABASE=AWL400 Wireless Adapter + +usb:v04A5p9213* + ID_PRODUCT_FROM_DATABASE=Kbd Hub + +usb:v04A6* + ID_VENDOR_FROM_DATABASE=Nokia Display Products + +usb:v04A6p00B9* + ID_PRODUCT_FROM_DATABASE=Audio + +usb:v04A6p0180* + ID_PRODUCT_FROM_DATABASE=Hub Type P + +usb:v04A6p0181* + ID_PRODUCT_FROM_DATABASE=HID Monitor Controls + +usb:v04A7* + ID_VENDOR_FROM_DATABASE=Visioneer + +usb:v04A7p0100* + ID_PRODUCT_FROM_DATABASE=StrobePro + +usb:v04A7p0101* + ID_PRODUCT_FROM_DATABASE=Strobe Pro Scanner (1.01) + +usb:v04A7p0102* + ID_PRODUCT_FROM_DATABASE=StrobePro Scanner + +usb:v04A7p0211* + ID_PRODUCT_FROM_DATABASE=OneTouch 7600 Scanner + +usb:v04A7p0221* + ID_PRODUCT_FROM_DATABASE=OneTouch 5300 Scanner + +usb:v04A7p0223* + ID_PRODUCT_FROM_DATABASE=OneTouch 8200 + +usb:v04A7p0224* + ID_PRODUCT_FROM_DATABASE=OneTouch 4800 USB/Microtek Scanport 3000 + +usb:v04A7p0225* + ID_PRODUCT_FROM_DATABASE=VistaScan Astra 3600(ENG) + +usb:v04A7p0226* + ID_PRODUCT_FROM_DATABASE=OneTouch 5300 USB + +usb:v04A7p0229* + ID_PRODUCT_FROM_DATABASE=OneTouch 7100 + +usb:v04A7p022A* + ID_PRODUCT_FROM_DATABASE=OneTouch 6600 + +usb:v04A7p022C* + ID_PRODUCT_FROM_DATABASE=OneTouch 9000/9020 + +usb:v04A7p0231* + ID_PRODUCT_FROM_DATABASE=6100 Scanner + +usb:v04A7p0311* + ID_PRODUCT_FROM_DATABASE=6200 EPP/USB Scanner + +usb:v04A7p0321* + ID_PRODUCT_FROM_DATABASE=OneTouch 8100 EPP/USB Scanner + +usb:v04A7p0331* + ID_PRODUCT_FROM_DATABASE=OneTouch 8600 EPP/USB Scanner + +usb:v04A7p0341* + ID_PRODUCT_FROM_DATABASE=6400 + +usb:v04A7p0361* + ID_PRODUCT_FROM_DATABASE=VistaScan Astra 3600(ENG) + +usb:v04A7p0362* + ID_PRODUCT_FROM_DATABASE=OneTouch 9320 + +usb:v04A7p0371* + ID_PRODUCT_FROM_DATABASE=OneTouch 8700/8920 + +usb:v04A7p0380* + ID_PRODUCT_FROM_DATABASE=OneTouch 7700 + +usb:v04A7p0382* + ID_PRODUCT_FROM_DATABASE=Photo Port 7700 + +usb:v04A7p0390* + ID_PRODUCT_FROM_DATABASE=9650 + +usb:v04A7p03A0* + ID_PRODUCT_FROM_DATABASE=Xerox 4800 One Touch + +usb:v04A7p0410* + ID_PRODUCT_FROM_DATABASE=OneTouch Pro 8800/8820 + +usb:v04A7p0421* + ID_PRODUCT_FROM_DATABASE=9450 USB + +usb:v04A7p0423* + ID_PRODUCT_FROM_DATABASE=9750 Scanner + +usb:v04A7p0424* + ID_PRODUCT_FROM_DATABASE=Strobe XP 450 + +usb:v04A7p0425* + ID_PRODUCT_FROM_DATABASE=Strobe XP 100 + +usb:v04A7p0426* + ID_PRODUCT_FROM_DATABASE=Strobe XP 200 + +usb:v04A7p0427* + ID_PRODUCT_FROM_DATABASE=Strobe XP 100 + +usb:v04A7p0444* + ID_PRODUCT_FROM_DATABASE=OneTouch 7300 + +usb:v04A7p0445* + ID_PRODUCT_FROM_DATABASE=CardReader 100 + +usb:v04A7p0446* + ID_PRODUCT_FROM_DATABASE=Xerox DocuMate 510 + +usb:v04A7p0447* + ID_PRODUCT_FROM_DATABASE=XEROX DocuMate 520 + +usb:v04A7p0448* + ID_PRODUCT_FROM_DATABASE=XEROX DocuMate 250 + +usb:v04A7p0449* + ID_PRODUCT_FROM_DATABASE=Xerox DocuMate 252 + +usb:v04A7p044A* + ID_PRODUCT_FROM_DATABASE=Xerox 6400 + +usb:v04A7p044C* + ID_PRODUCT_FROM_DATABASE=Xerox DocuMate 262 + +usb:v04A7p0474* + ID_PRODUCT_FROM_DATABASE=Strobe XP 300 + +usb:v04A7p0475* + ID_PRODUCT_FROM_DATABASE=Xerox DocuMate 272 + +usb:v04A7p0478* + ID_PRODUCT_FROM_DATABASE=Strobe XP 220 + +usb:v04A7p0479* + ID_PRODUCT_FROM_DATABASE=Strobe XP 470 + +usb:v04A7p047A* + ID_PRODUCT_FROM_DATABASE=9450 + +usb:v04A7p047B* + ID_PRODUCT_FROM_DATABASE=9650 + +usb:v04A7p047D* + ID_PRODUCT_FROM_DATABASE=9420 + +usb:v04A7p0480* + ID_PRODUCT_FROM_DATABASE=9520 + +usb:v04A7p048F* + ID_PRODUCT_FROM_DATABASE=Strobe XP 470 + +usb:v04A7p0491* + ID_PRODUCT_FROM_DATABASE=Strobe XP 450 + +usb:v04A7p0493* + ID_PRODUCT_FROM_DATABASE=9750 + +usb:v04A7p0494* + ID_PRODUCT_FROM_DATABASE=Strobe XP 120 + +usb:v04A7p0497* + ID_PRODUCT_FROM_DATABASE=Patriot 430 + +usb:v04A7p0498* + ID_PRODUCT_FROM_DATABASE=Patriot 680 + +usb:v04A7p0499* + ID_PRODUCT_FROM_DATABASE=Patriot 780 + +usb:v04A7p049B* + ID_PRODUCT_FROM_DATABASE=Strobe XP 100 + +usb:v04A7p04A0* + ID_PRODUCT_FROM_DATABASE=7400 + +usb:v04A7p04AC* + ID_PRODUCT_FROM_DATABASE=Xerox Travel Scanner 100 + +usb:v04A8* + ID_VENDOR_FROM_DATABASE=Multivideo Labs, Inc. + +usb:v04A8p0101* + ID_PRODUCT_FROM_DATABASE=Hub + +usb:v04A8p0303* + ID_PRODUCT_FROM_DATABASE=Peripheral Switch + +usb:v04A8p0404* + ID_PRODUCT_FROM_DATABASE=Peripheral Switch + +usb:v04A9* + ID_VENDOR_FROM_DATABASE=Canon, Inc. + +usb:v04A9p1005* + ID_PRODUCT_FROM_DATABASE=BJ Printer Hub + +usb:v04A9p1035* + ID_PRODUCT_FROM_DATABASE=PD Printer Storage + +usb:v04A9p1050* + ID_PRODUCT_FROM_DATABASE=BJC-8200 + +usb:v04A9p1051* + ID_PRODUCT_FROM_DATABASE=BJC-3000 Color Printer + +usb:v04A9p1052* + ID_PRODUCT_FROM_DATABASE=BJC-6100 + +usb:v04A9p1053* + ID_PRODUCT_FROM_DATABASE=BJC-6200 + +usb:v04A9p1054* + ID_PRODUCT_FROM_DATABASE=BJC-6500 + +usb:v04A9p1055* + ID_PRODUCT_FROM_DATABASE=BJC-85 + +usb:v04A9p1056* + ID_PRODUCT_FROM_DATABASE=BJC-2110 Color Printer + +usb:v04A9p1057* + ID_PRODUCT_FROM_DATABASE=LR1 + +usb:v04A9p105A* + ID_PRODUCT_FROM_DATABASE=BJC-55 + +usb:v04A9p105B* + ID_PRODUCT_FROM_DATABASE=S600 Printer + +usb:v04A9p105C* + ID_PRODUCT_FROM_DATABASE=S400 + +usb:v04A9p105D* + ID_PRODUCT_FROM_DATABASE=S450 Printer + +usb:v04A9p105E* + ID_PRODUCT_FROM_DATABASE=S800 + +usb:v04A9p1062* + ID_PRODUCT_FROM_DATABASE=S500 Printer + +usb:v04A9p1063* + ID_PRODUCT_FROM_DATABASE=S4500 + +usb:v04A9p1064* + ID_PRODUCT_FROM_DATABASE=S300 Printer + +usb:v04A9p1065* + ID_PRODUCT_FROM_DATABASE=S100 + +usb:v04A9p1066* + ID_PRODUCT_FROM_DATABASE=S630 + +usb:v04A9p1067* + ID_PRODUCT_FROM_DATABASE=S900 + +usb:v04A9p1068* + ID_PRODUCT_FROM_DATABASE=S9000 + +usb:v04A9p1069* + ID_PRODUCT_FROM_DATABASE=S820 + +usb:v04A9p106A* + ID_PRODUCT_FROM_DATABASE=S200 Printer + +usb:v04A9p106B* + ID_PRODUCT_FROM_DATABASE=S520 Printer + +usb:v04A9p106D* + ID_PRODUCT_FROM_DATABASE=S750 Printer + +usb:v04A9p106E* + ID_PRODUCT_FROM_DATABASE=S820D + +usb:v04A9p1070* + ID_PRODUCT_FROM_DATABASE=S530D + +usb:v04A9p1072* + ID_PRODUCT_FROM_DATABASE=I850 Printer + +usb:v04A9p1073* + ID_PRODUCT_FROM_DATABASE=I550 Printer + +usb:v04A9p1074* + ID_PRODUCT_FROM_DATABASE=S330 Printer + +usb:v04A9p1076* + ID_PRODUCT_FROM_DATABASE=i70 + +usb:v04A9p1077* + ID_PRODUCT_FROM_DATABASE=i950 + +usb:v04A9p107A* + ID_PRODUCT_FROM_DATABASE=S830D + +usb:v04A9p107B* + ID_PRODUCT_FROM_DATABASE=i320 + +usb:v04A9p107C* + ID_PRODUCT_FROM_DATABASE=i470D + +usb:v04A9p107D* + ID_PRODUCT_FROM_DATABASE=i9100 + +usb:v04A9p107E* + ID_PRODUCT_FROM_DATABASE=i450 + +usb:v04A9p107F* + ID_PRODUCT_FROM_DATABASE=i860 + +usb:v04A9p1082* + ID_PRODUCT_FROM_DATABASE=i350 + +usb:v04A9p1084* + ID_PRODUCT_FROM_DATABASE=i250 + +usb:v04A9p1085* + ID_PRODUCT_FROM_DATABASE=i255 + +usb:v04A9p1086* + ID_PRODUCT_FROM_DATABASE=i560 + +usb:v04A9p1088* + ID_PRODUCT_FROM_DATABASE=i965 + +usb:v04A9p108A* + ID_PRODUCT_FROM_DATABASE=i455 + +usb:v04A9p108B* + ID_PRODUCT_FROM_DATABASE=i900D + +usb:v04A9p108C* + ID_PRODUCT_FROM_DATABASE=i475D + +usb:v04A9p108D* + ID_PRODUCT_FROM_DATABASE=PIXMA iP2000 + +usb:v04A9p108F* + ID_PRODUCT_FROM_DATABASE=i80 + +usb:v04A9p1090* + ID_PRODUCT_FROM_DATABASE=i9900 Photo Printer + +usb:v04A9p1091* + ID_PRODUCT_FROM_DATABASE=PIXMA iP1500 + +usb:v04A9p1093* + ID_PRODUCT_FROM_DATABASE=PIXMA iP4000 + +usb:v04A9p1094* + ID_PRODUCT_FROM_DATABASE=PIXMA iP3000x Printer + +usb:v04A9p1095* + ID_PRODUCT_FROM_DATABASE=PIXMA iP6000D + +usb:v04A9p1097* + ID_PRODUCT_FROM_DATABASE=PIXMA iP5000 + +usb:v04A9p1098* + ID_PRODUCT_FROM_DATABASE=PIXMA iP1000 + +usb:v04A9p1099* + ID_PRODUCT_FROM_DATABASE=PIXMA iP8500 + +usb:v04A9p109C* + ID_PRODUCT_FROM_DATABASE=PIXMA iP4000R + +usb:v04A9p109D* + ID_PRODUCT_FROM_DATABASE=iP90 + +usb:v04A9p10A0* + ID_PRODUCT_FROM_DATABASE=PIXMA iP1600 Printer + +usb:v04A9p10A2* + ID_PRODUCT_FROM_DATABASE=iP4200 + +usb:v04A9p10A4* + ID_PRODUCT_FROM_DATABASE=iP5200R + +usb:v04A9p10A5* + ID_PRODUCT_FROM_DATABASE=iP5200 + +usb:v04A9p10A7* + ID_PRODUCT_FROM_DATABASE=iP6210D + +usb:v04A9p10A8* + ID_PRODUCT_FROM_DATABASE=iP6220D + +usb:v04A9p10A9* + ID_PRODUCT_FROM_DATABASE=iP6600D + +usb:v04A9p10B6* + ID_PRODUCT_FROM_DATABASE=PIXMA iP4300 Printer + +usb:v04A9p10C2* + ID_PRODUCT_FROM_DATABASE=PIXMA iP1800 Printer + +usb:v04A9p10C4* + ID_PRODUCT_FROM_DATABASE=Pixma iP4500 Printer + +usb:v04A9p1404* + ID_PRODUCT_FROM_DATABASE=W6400PG + +usb:v04A9p1405* + ID_PRODUCT_FROM_DATABASE=W8400PG + +usb:v04A9p150F* + ID_PRODUCT_FROM_DATABASE=BIJ2350 PCL + +usb:v04A9p1510* + ID_PRODUCT_FROM_DATABASE=BIJ1350 PCL + +usb:v04A9p1512* + ID_PRODUCT_FROM_DATABASE=BIJ1350D PCL + +usb:v04A9p1601* + ID_PRODUCT_FROM_DATABASE=DR-2080C Scanner + +usb:v04A9p1607* + ID_PRODUCT_FROM_DATABASE=DR-6080 Scanner + +usb:v04A9p1700* + ID_PRODUCT_FROM_DATABASE=PIXMA MP110 Scanner + +usb:v04A9p1701* + ID_PRODUCT_FROM_DATABASE=PIXMA MP130 Scanner + +usb:v04A9p1702* + ID_PRODUCT_FROM_DATABASE=MP410 Composite + +usb:v04A9p1703* + ID_PRODUCT_FROM_DATABASE=MP430 Composite + +usb:v04A9p1704* + ID_PRODUCT_FROM_DATABASE=MP330 Composite + +usb:v04A9p1706* + ID_PRODUCT_FROM_DATABASE=PIXMA MP750 Scanner + +usb:v04A9p1707* + ID_PRODUCT_FROM_DATABASE=PIXMA MP780 Scanner + +usb:v04A9p1708* + ID_PRODUCT_FROM_DATABASE=PIXMA MP760 Scanner + +usb:v04A9p1709* + ID_PRODUCT_FROM_DATABASE=PIXMA MP150 Scanner + +usb:v04A9p170A* + ID_PRODUCT_FROM_DATABASE=PIXMA MP170 Scanner + +usb:v04A9p170B* + ID_PRODUCT_FROM_DATABASE=PIXMA MP450 Scanner + +usb:v04A9p170C* + ID_PRODUCT_FROM_DATABASE=PIXMA MP500 Scanner + +usb:v04A9p170D* + ID_PRODUCT_FROM_DATABASE=PIXMA MP800 Scanner + +usb:v04A9p170E* + ID_PRODUCT_FROM_DATABASE=MP800R + +usb:v04A9p1710* + ID_PRODUCT_FROM_DATABASE=MP950 + +usb:v04A9p1712* + ID_PRODUCT_FROM_DATABASE=MP530 + +usb:v04A9p1713* + ID_PRODUCT_FROM_DATABASE=PIXMA MP830 Scanner + +usb:v04A9p1714* + ID_PRODUCT_FROM_DATABASE=MP160 + +usb:v04A9p1715* + ID_PRODUCT_FROM_DATABASE=MP180 Storage + +usb:v04A9p1716* + ID_PRODUCT_FROM_DATABASE=MP460 Composite + +usb:v04A9p1717* + ID_PRODUCT_FROM_DATABASE=MP510 + +usb:v04A9p1718* + ID_PRODUCT_FROM_DATABASE=MP600 Storage + +usb:v04A9p171A* + ID_PRODUCT_FROM_DATABASE=MP810 Storage + +usb:v04A9p171B* + ID_PRODUCT_FROM_DATABASE=MP960 + +usb:v04A9p1721* + ID_PRODUCT_FROM_DATABASE=MP210 ser + +usb:v04A9p1723* + ID_PRODUCT_FROM_DATABASE=MP470 ser + +usb:v04A9p1725* + ID_PRODUCT_FROM_DATABASE=MP610 ser + +usb:v04A9p1726* + ID_PRODUCT_FROM_DATABASE=MP970 ser + +usb:v04A9p1727* + ID_PRODUCT_FROM_DATABASE=MX300 ser + +usb:v04A9p1728* + ID_PRODUCT_FROM_DATABASE=MX310 ser + +usb:v04A9p1729* + ID_PRODUCT_FROM_DATABASE=MX700 ser + +usb:v04A9p172B* + ID_PRODUCT_FROM_DATABASE=MP140 ser + +usb:v04A9p173E* + ID_PRODUCT_FROM_DATABASE=MP560 + +usb:v04A9p173F* + ID_PRODUCT_FROM_DATABASE=Pixma MP640 Multifunction device + +usb:v04A9p1748* + ID_PRODUCT_FROM_DATABASE=Pixma MG5150 + +usb:v04A9p174D* + ID_PRODUCT_FROM_DATABASE=MX360 ser + +usb:v04A9p1900* + ID_PRODUCT_FROM_DATABASE=CanoScan LiDE 90 + +usb:v04A9p1901* + ID_PRODUCT_FROM_DATABASE=CanoScan 8800F + +usb:v04A9p1904* + ID_PRODUCT_FROM_DATABASE=CanoScan LiDE 100 + +usb:v04A9p1905* + ID_PRODUCT_FROM_DATABASE=CanoScan LiDE 200 + +usb:v04A9p1906* + ID_PRODUCT_FROM_DATABASE=CanoScan 5600F + +usb:v04A9p1907* + ID_PRODUCT_FROM_DATABASE=CanoScan LiDE 700F + +usb:v04A9p1909* + ID_PRODUCT_FROM_DATABASE=CanoScan LiDE 110 + +usb:v04A9p190A* + ID_PRODUCT_FROM_DATABASE=CanoScan LiDE 210 + +usb:v04A9p2200* + ID_PRODUCT_FROM_DATABASE=CanoScan LiDE 25 + +usb:v04A9p2201* + ID_PRODUCT_FROM_DATABASE=CanoScan FB320U + +usb:v04A9p2202* + ID_PRODUCT_FROM_DATABASE=CanoScan FB620U + +usb:v04A9p2204* + ID_PRODUCT_FROM_DATABASE=CanoScan FB630U + +usb:v04A9p2205* + ID_PRODUCT_FROM_DATABASE=CanoScan FB1210U + +usb:v04A9p2206* + ID_PRODUCT_FROM_DATABASE=CanoScan N650U/N656U + +usb:v04A9p2207* + ID_PRODUCT_FROM_DATABASE=CanoScan 1220U + +usb:v04A9p2208* + ID_PRODUCT_FROM_DATABASE=CanoScan D660U + +usb:v04A9p220A* + ID_PRODUCT_FROM_DATABASE=CanoScan D2400UF + +usb:v04A9p220B* + ID_PRODUCT_FROM_DATABASE=CanoScan D646U + +usb:v04A9p220C* + ID_PRODUCT_FROM_DATABASE=CanoScan D1250U2 + +usb:v04A9p220D* + ID_PRODUCT_FROM_DATABASE=CanoScan N670U/N676U/LiDE 20 + +usb:v04A9p220E* + ID_PRODUCT_FROM_DATABASE=CanoScan N1240U/LiDE 30 + +usb:v04A9p220F* + ID_PRODUCT_FROM_DATABASE=CanoScan 8000F + +usb:v04A9p2210* + ID_PRODUCT_FROM_DATABASE=CanoScan 9900F + +usb:v04A9p2212* + ID_PRODUCT_FROM_DATABASE=CanoScan 5000F + +usb:v04A9p2213* + ID_PRODUCT_FROM_DATABASE=CanoScan LiDE 50/LiDE 35/LiDE 40 + +usb:v04A9p2214* + ID_PRODUCT_FROM_DATABASE=CanoScan LiDE 80 + +usb:v04A9p2215* + ID_PRODUCT_FROM_DATABASE=CanoScan 3000/3000F/3000ex + +usb:v04A9p2216* + ID_PRODUCT_FROM_DATABASE=CanoScan 3200F + +usb:v04A9p2217* + ID_PRODUCT_FROM_DATABASE=CanoScan 5200F + +usb:v04A9p2219* + ID_PRODUCT_FROM_DATABASE=CanoScan 9950F + +usb:v04A9p221B* + ID_PRODUCT_FROM_DATABASE=CanoScan 4200F + +usb:v04A9p221C* + ID_PRODUCT_FROM_DATABASE=CanoScan LiDE 60 + +usb:v04A9p221E* + ID_PRODUCT_FROM_DATABASE=CanoScan 8400F + +usb:v04A9p221F* + ID_PRODUCT_FROM_DATABASE=CanoScan LiDE 500F + +usb:v04A9p2220* + ID_PRODUCT_FROM_DATABASE=CanoScan LIDE 25 + +usb:v04A9p2224* + ID_PRODUCT_FROM_DATABASE=CanoScan LiDE 600F + +usb:v04A9p2225* + ID_PRODUCT_FROM_DATABASE=CanoScan LiDE 70 + +usb:v04A9p2228* + ID_PRODUCT_FROM_DATABASE=CanoScan 4400F + +usb:v04A9p2602* + ID_PRODUCT_FROM_DATABASE=MultiPASS C555 + +usb:v04A9p2603* + ID_PRODUCT_FROM_DATABASE=MultiPASS C755 + +usb:v04A9p260A* + ID_PRODUCT_FROM_DATABASE=CAPT Printer + +usb:v04A9p260E* + ID_PRODUCT_FROM_DATABASE=LBP-2000 + +usb:v04A9p2610* + ID_PRODUCT_FROM_DATABASE=MPC600F + +usb:v04A9p2611* + ID_PRODUCT_FROM_DATABASE=SmartBase MPC400 + +usb:v04A9p2612* + ID_PRODUCT_FROM_DATABASE=MultiPASS C855 + +usb:v04A9p2617* + ID_PRODUCT_FROM_DATABASE=CAPT Printer + +usb:v04A9p261A* + ID_PRODUCT_FROM_DATABASE=iR1600 + +usb:v04A9p261B* + ID_PRODUCT_FROM_DATABASE=iR1610 + +usb:v04A9p261C* + ID_PRODUCT_FROM_DATABASE=iC2300 + +usb:v04A9p261F* + ID_PRODUCT_FROM_DATABASE=MPC200 Printer + +usb:v04A9p2621* + ID_PRODUCT_FROM_DATABASE=iR2000 + +usb:v04A9p2622* + ID_PRODUCT_FROM_DATABASE=iR2010 + +usb:v04A9p2623* + ID_PRODUCT_FROM_DATABASE=FAX-B180C + +usb:v04A9p2629* + ID_PRODUCT_FROM_DATABASE=FAXPHONE L75 + +usb:v04A9p262B* + ID_PRODUCT_FROM_DATABASE=LaserShot LBP-1120 Printer + +usb:v04A9p262D* + ID_PRODUCT_FROM_DATABASE=iR C3200 + +usb:v04A9p262F* + ID_PRODUCT_FROM_DATABASE=MultiPASS MP730 + +usb:v04A9p2630* + ID_PRODUCT_FROM_DATABASE=MultiPASS MP700 + +usb:v04A9p2631* + ID_PRODUCT_FROM_DATABASE=LASER CLASS 700 + +usb:v04A9p2632* + ID_PRODUCT_FROM_DATABASE=FAX-L2000 + +usb:v04A9p2635* + ID_PRODUCT_FROM_DATABASE=MPC190 + +usb:v04A9p2637* + ID_PRODUCT_FROM_DATABASE=iR C6800 + +usb:v04A9p2638* + ID_PRODUCT_FROM_DATABASE=iR C3100 + +usb:v04A9p263C* + ID_PRODUCT_FROM_DATABASE=Smartbase MP360 + +usb:v04A9p263D* + ID_PRODUCT_FROM_DATABASE=MP370 + +usb:v04A9p263E* + ID_PRODUCT_FROM_DATABASE=MP390 FAX + +usb:v04A9p263F* + ID_PRODUCT_FROM_DATABASE=MP375 + +usb:v04A9p2646* + ID_PRODUCT_FROM_DATABASE=MF5530 Scanner Device V1.9.1 + +usb:v04A9p2647* + ID_PRODUCT_FROM_DATABASE=MF5550 Composite + +usb:v04A9p264D* + ID_PRODUCT_FROM_DATABASE=PIXMA MP710 + +usb:v04A9p264E* + ID_PRODUCT_FROM_DATABASE=MF5630 + +usb:v04A9p264F* + ID_PRODUCT_FROM_DATABASE=MF5650 (FAX) + +usb:v04A9p2650* + ID_PRODUCT_FROM_DATABASE=iR 6800C EUR + +usb:v04A9p2651* + ID_PRODUCT_FROM_DATABASE=iR 3100C EUR + +usb:v04A9p2655* + ID_PRODUCT_FROM_DATABASE=FP-L170/MF350/L380/L398 + +usb:v04A9p2659* + ID_PRODUCT_FROM_DATABASE=MF8100 + +usb:v04A9p265B* + ID_PRODUCT_FROM_DATABASE=CAPT Printer + +usb:v04A9p265C* + ID_PRODUCT_FROM_DATABASE=iR C3220 + +usb:v04A9p265D* + ID_PRODUCT_FROM_DATABASE=MF5730 + +usb:v04A9p265E* + ID_PRODUCT_FROM_DATABASE=MF5750 + +usb:v04A9p265F* + ID_PRODUCT_FROM_DATABASE=MF5770 + +usb:v04A9p2660* + ID_PRODUCT_FROM_DATABASE=MF3110 + +usb:v04A9p2663* + ID_PRODUCT_FROM_DATABASE=iR3570/iR4570 + +usb:v04A9p2664* + ID_PRODUCT_FROM_DATABASE=iR2270/iR2870 + +usb:v04A9p2665* + ID_PRODUCT_FROM_DATABASE=iR C2620 + +usb:v04A9p2666* + ID_PRODUCT_FROM_DATABASE=iR C5800 + +usb:v04A9p2667* + ID_PRODUCT_FROM_DATABASE=iR85PLUS + +usb:v04A9p2669* + ID_PRODUCT_FROM_DATABASE=iR105PLUS + +usb:v04A9p266A* + ID_PRODUCT_FROM_DATABASE=CAPT Device + +usb:v04A9p266B* + ID_PRODUCT_FROM_DATABASE=iR8070 + +usb:v04A9p266C* + ID_PRODUCT_FROM_DATABASE=iR9070 + +usb:v04A9p266D* + ID_PRODUCT_FROM_DATABASE=iR 5800C EUR + +usb:v04A9p266E* + ID_PRODUCT_FROM_DATABASE=CAPT Device + +usb:v04A9p266F* + ID_PRODUCT_FROM_DATABASE=iR2230 + +usb:v04A9p2670* + ID_PRODUCT_FROM_DATABASE=iR3530 + +usb:v04A9p2671* + ID_PRODUCT_FROM_DATABASE=iR5570/iR6570 + +usb:v04A9p2672* + ID_PRODUCT_FROM_DATABASE=iR C3170 + +usb:v04A9p2673* + ID_PRODUCT_FROM_DATABASE=iR 3170C EUR + +usb:v04A9p2674* + ID_PRODUCT_FROM_DATABASE=L120 + +usb:v04A9p2675* + ID_PRODUCT_FROM_DATABASE=iR2830 + +usb:v04A9p2676* + ID_PRODUCT_FROM_DATABASE=CAPT Device + +usb:v04A9p2677* + ID_PRODUCT_FROM_DATABASE=iR C2570 + +usb:v04A9p2678* + ID_PRODUCT_FROM_DATABASE=iR 2570C EUR + +usb:v04A9p2679* + ID_PRODUCT_FROM_DATABASE=CAPT Device + +usb:v04A9p267A* + ID_PRODUCT_FROM_DATABASE=iR2016 + +usb:v04A9p267B* + ID_PRODUCT_FROM_DATABASE=iR2020 + +usb:v04A9p267D* + ID_PRODUCT_FROM_DATABASE=MF7100 series + +usb:v04A9p2684* + ID_PRODUCT_FROM_DATABASE=MF3200 series + +usb:v04A9p2686* + ID_PRODUCT_FROM_DATABASE=MF6500 series + +usb:v04A9p2687* + ID_PRODUCT_FROM_DATABASE=iR4530 + +usb:v04A9p2688* + ID_PRODUCT_FROM_DATABASE=LBP3460 + +usb:v04A9p268C* + ID_PRODUCT_FROM_DATABASE=iR C6870 + +usb:v04A9p268D* + ID_PRODUCT_FROM_DATABASE=iR 6870C EUR + +usb:v04A9p268E* + ID_PRODUCT_FROM_DATABASE=iR C5870 + +usb:v04A9p268F* + ID_PRODUCT_FROM_DATABASE=iR 5870C EUR + +usb:v04A9p2691* + ID_PRODUCT_FROM_DATABASE=iR7105 + +usb:v04A9p26A3* + ID_PRODUCT_FROM_DATABASE=MF4100 series + +usb:v04A9p26B0* + ID_PRODUCT_FROM_DATABASE=MF4600 series + +usb:v04A9p26B4* + ID_PRODUCT_FROM_DATABASE=MF4010 series + +usb:v04A9p26B5* + ID_PRODUCT_FROM_DATABASE=MF4200 series + +usb:v04A9p2737* + ID_PRODUCT_FROM_DATABASE=MF4410 + +usb:v04A9p3041* + ID_PRODUCT_FROM_DATABASE=PowerShot S10 + +usb:v04A9p3042* + ID_PRODUCT_FROM_DATABASE=CanoScan FS4000US Film Scanner + +usb:v04A9p3043* + ID_PRODUCT_FROM_DATABASE=PowerShot S20 + +usb:v04A9p3044* + ID_PRODUCT_FROM_DATABASE=EOS D30 + +usb:v04A9p3045* + ID_PRODUCT_FROM_DATABASE=PowerShot S100 + +usb:v04A9p3046* + ID_PRODUCT_FROM_DATABASE=IXY Digital + +usb:v04A9p3047* + ID_PRODUCT_FROM_DATABASE=Digital IXUS + +usb:v04A9p3048* + ID_PRODUCT_FROM_DATABASE=PowerShot G1 + +usb:v04A9p3049* + ID_PRODUCT_FROM_DATABASE=PowerShot Pro90 IS + +usb:v04A9p304A* + ID_PRODUCT_FROM_DATABASE=CP-10 + +usb:v04A9p304B* + ID_PRODUCT_FROM_DATABASE=IXY Digital 300 + +usb:v04A9p304C* + ID_PRODUCT_FROM_DATABASE=PowerShot S300 + +usb:v04A9p304D* + ID_PRODUCT_FROM_DATABASE=Digital IXUS 300 + +usb:v04A9p304E* + ID_PRODUCT_FROM_DATABASE=PowerShot A20 + +usb:v04A9p304F* + ID_PRODUCT_FROM_DATABASE=PowerShot A10 + +usb:v04A9p3050* + ID_PRODUCT_FROM_DATABASE=PowerShot unknown 1 + +usb:v04A9p3051* + ID_PRODUCT_FROM_DATABASE=PowerShot S110 + +usb:v04A9p3052* + ID_PRODUCT_FROM_DATABASE=Digital IXUS V + +usb:v04A9p3055* + ID_PRODUCT_FROM_DATABASE=PowerShot G2 + +usb:v04A9p3056* + ID_PRODUCT_FROM_DATABASE=PowerShot S40 + +usb:v04A9p3057* + ID_PRODUCT_FROM_DATABASE=PowerShot S30 + +usb:v04A9p3058* + ID_PRODUCT_FROM_DATABASE=PowerShot A40 + +usb:v04A9p3059* + ID_PRODUCT_FROM_DATABASE=PowerShot A30 + +usb:v04A9p305B* + ID_PRODUCT_FROM_DATABASE=ZR45MC Digital Camcorder + +usb:v04A9p305C* + ID_PRODUCT_FROM_DATABASE=PowerShot unknown 2 + +usb:v04A9p3060* + ID_PRODUCT_FROM_DATABASE=EOS D60 + +usb:v04A9p3061* + ID_PRODUCT_FROM_DATABASE=PowerShot A100 + +usb:v04A9p3062* + ID_PRODUCT_FROM_DATABASE=PowerShot A200 + +usb:v04A9p3063* + ID_PRODUCT_FROM_DATABASE=CP-100 + +usb:v04A9p3065* + ID_PRODUCT_FROM_DATABASE=PowerShot S200 + +usb:v04A9p3066* + ID_PRODUCT_FROM_DATABASE=Digital IXUS 330 + +usb:v04A9p3067* + ID_PRODUCT_FROM_DATABASE=MV550i Digital Video Camera + +usb:v04A9p3069* + ID_PRODUCT_FROM_DATABASE=PowerShot G3 + +usb:v04A9p306A* + ID_PRODUCT_FROM_DATABASE=Digital unknown 3 + +usb:v04A9p306B* + ID_PRODUCT_FROM_DATABASE=MVX2i Digital Video Camera + +usb:v04A9p306C* + ID_PRODUCT_FROM_DATABASE=PowerShot S45 + +usb:v04A9p306D* + ID_PRODUCT_FROM_DATABASE=PowerShot S45 PtP Mode + +usb:v04A9p306E* + ID_PRODUCT_FROM_DATABASE=PowerShot G3 (normal mode) + +usb:v04A9p306F* + ID_PRODUCT_FROM_DATABASE=PowerShot G3 (ptp) + +usb:v04A9p3070* + ID_PRODUCT_FROM_DATABASE=PowerShot S230 + +usb:v04A9p3071* + ID_PRODUCT_FROM_DATABASE=PowerShot S230 (ptp) + +usb:v04A9p3072* + ID_PRODUCT_FROM_DATABASE=PowerShot SD100 / Digital IXUS II (ptp) + +usb:v04A9p3073* + ID_PRODUCT_FROM_DATABASE=PowerShot A70 (ptp) + +usb:v04A9p3074* + ID_PRODUCT_FROM_DATABASE=PowerShot A60 (ptp) + +usb:v04A9p3075* + ID_PRODUCT_FROM_DATABASE=IXUS 400 Camera + +usb:v04A9p3076* + ID_PRODUCT_FROM_DATABASE=PowerShot A300 + +usb:v04A9p3077* + ID_PRODUCT_FROM_DATABASE=PowerShot S50 + +usb:v04A9p3078* + ID_PRODUCT_FROM_DATABASE=ZR70MC Digital Camcorder + +usb:v04A9p307A* + ID_PRODUCT_FROM_DATABASE=MV650i (normal mode) + +usb:v04A9p307B* + ID_PRODUCT_FROM_DATABASE=MV630i Digital Video Camera + +usb:v04A9p307C* + ID_PRODUCT_FROM_DATABASE=MV630i (normal mode) + +usb:v04A9p307D* + ID_PRODUCT_FROM_DATABASE=CP-300 + +usb:v04A9p307F* + ID_PRODUCT_FROM_DATABASE=Optura 20 + +usb:v04A9p3080* + ID_PRODUCT_FROM_DATABASE=MVX150i (normal mode) / Optura 20 (normal mode) + +usb:v04A9p3081* + ID_PRODUCT_FROM_DATABASE=Optura 10 + +usb:v04A9p3082* + ID_PRODUCT_FROM_DATABASE=MVX100i / Optura 10 + +usb:v04A9p3083* + ID_PRODUCT_FROM_DATABASE=EOS 10D + +usb:v04A9p3084* + ID_PRODUCT_FROM_DATABASE=EOS 300D / EOS Digital Rebel + +usb:v04A9p3085* + ID_PRODUCT_FROM_DATABASE=PowerShot G5 + +usb:v04A9p3087* + ID_PRODUCT_FROM_DATABASE=Elura 50 (PTP mode) + +usb:v04A9p3088* + ID_PRODUCT_FROM_DATABASE=Elura 50 (normal mode) + +usb:v04A9p308D* + ID_PRODUCT_FROM_DATABASE=MVX3i + +usb:v04A9p308E* + ID_PRODUCT_FROM_DATABASE=FV M1 (normal mode) / MVX 3i (normal mode) / Optura Xi (normal mode) + +usb:v04A9p3093* + ID_PRODUCT_FROM_DATABASE=Optura 300 + +usb:v04A9p3096* + ID_PRODUCT_FROM_DATABASE=IXY DV M2 (normal mode) / MVX 10i (normal mode) + +usb:v04A9p3099* + ID_PRODUCT_FROM_DATABASE=EOS 300D (ptp) + +usb:v04A9p309A* + ID_PRODUCT_FROM_DATABASE=PowerShot A80 + +usb:v04A9p309B* + ID_PRODUCT_FROM_DATABASE=Digital IXUS (ptp) + +usb:v04A9p309C* + ID_PRODUCT_FROM_DATABASE=PowerShot S1 IS + +usb:v04A9p309D* + ID_PRODUCT_FROM_DATABASE=Powershot Pro 1 + +usb:v04A9p309F* + ID_PRODUCT_FROM_DATABASE=Camera + +usb:v04A9p30A0* + ID_PRODUCT_FROM_DATABASE=Camera + +usb:v04A9p30A1* + ID_PRODUCT_FROM_DATABASE=Camera + +usb:v04A9p30A2* + ID_PRODUCT_FROM_DATABASE=Camera + +usb:v04A9p30A8* + ID_PRODUCT_FROM_DATABASE=Elura 60E/Optura 40 (ptp) + +usb:v04A9p30A9* + ID_PRODUCT_FROM_DATABASE=MVX25i (normal mode) / Optura 40 (normal mode) + +usb:v04A9p30B1* + ID_PRODUCT_FROM_DATABASE=PowerShot S70 (normal mode) / PowerShot S70 (PTP mode) + +usb:v04A9p30B2* + ID_PRODUCT_FROM_DATABASE=PowerShot S60 (normal mode) / PowerShot S60 (PTP mode) + +usb:v04A9p30B3* + ID_PRODUCT_FROM_DATABASE=PowerShot G6 (normal mode) / PowerShot G6 (PTP mode) + +usb:v04A9p30B4* + ID_PRODUCT_FROM_DATABASE=PowerShot S500 + +usb:v04A9p30B5* + ID_PRODUCT_FROM_DATABASE=PowerShot A75 + +usb:v04A9p30B6* + ID_PRODUCT_FROM_DATABASE=Digital IXUS II2 / Digital IXUS II2 (PTP mode) / PowerShot SD110 (PTP mode) / PowerShot SD110 Digital ELPH + +usb:v04A9p30B7* + ID_PRODUCT_FROM_DATABASE=PowerShot A400 / PowerShot A400 (PTP mode) + +usb:v04A9p30B8* + ID_PRODUCT_FROM_DATABASE=PowerShot A310 / PowerShot A310 (PTP mode) + +usb:v04A9p30B9* + ID_PRODUCT_FROM_DATABASE=Powershot A85 + +usb:v04A9p30BA* + ID_PRODUCT_FROM_DATABASE=PowerShot S410 Digital Elph + +usb:v04A9p30BB* + ID_PRODUCT_FROM_DATABASE=PowerShot A95 + +usb:v04A9p30BD* + ID_PRODUCT_FROM_DATABASE=CP-220 + +usb:v04A9p30BE* + ID_PRODUCT_FROM_DATABASE=CP-330 + +usb:v04A9p30BF* + ID_PRODUCT_FROM_DATABASE=Digital IXUS 40 + +usb:v04A9p30C0* + ID_PRODUCT_FROM_DATABASE=Digital IXUS 30 (PTP mode) / PowerShot SD200 (PTP mode) + +usb:v04A9p30C1* + ID_PRODUCT_FROM_DATABASE=Digital IXUS 50 (normal mode) / IXY Digital 55 (normal mode) / PowerShot A520 (PTP mode) / PowerShot SD400 (normal mode) + +usb:v04A9p30C2* + ID_PRODUCT_FROM_DATABASE=PowerShot A510 (normal mode) / PowerShot A510 (PTP mode) + +usb:v04A9p30C4* + ID_PRODUCT_FROM_DATABASE=Digital IXUS i5 (normal mode) / IXY Digital L2 (normal mode) / PowerShot SD20 (normal mode) + +usb:v04A9p30EA* + ID_PRODUCT_FROM_DATABASE=EOS 1D Mark II (PTP mode) + +usb:v04A9p30EB* + ID_PRODUCT_FROM_DATABASE=EOS 20D + +usb:v04A9p30EC* + ID_PRODUCT_FROM_DATABASE=EOS 20D (ptp) + +usb:v04A9p30EE* + ID_PRODUCT_FROM_DATABASE=EOS 350D + +usb:v04A9p30EF* + ID_PRODUCT_FROM_DATABASE=EOS 350D (ptp) + +usb:v04A9p30F0* + ID_PRODUCT_FROM_DATABASE=PowerShot S2 IS (PTP mode) + +usb:v04A9p30F2* + ID_PRODUCT_FROM_DATABASE=Digital IXUS 700 (normal mode) / Digital IXUS 700 (PTP mode) / IXY Digital 600 (normal mode) / PowerShot SD500 (normal mode) / PowerShot SD500 (PTP mode) + +usb:v04A9p30F4* + ID_PRODUCT_FROM_DATABASE=PowerShot SD30 / Ixus iZoom / IXY DIGITAL L3 + +usb:v04A9p30F5* + ID_PRODUCT_FROM_DATABASE=SELPHY CP500 + +usb:v04A9p30F6* + ID_PRODUCT_FROM_DATABASE=SELPHY CP400 + +usb:v04A9p30F8* + ID_PRODUCT_FROM_DATABASE=Powershot A430 + +usb:v04A9p30F9* + ID_PRODUCT_FROM_DATABASE=PowerShot A410 (PTP mode) + +usb:v04A9p30FA* + ID_PRODUCT_FROM_DATABASE=PowerShot S80 + +usb:v04A9p30FC* + ID_PRODUCT_FROM_DATABASE=PowerShot A620 (PTP mode) + +usb:v04A9p30FD* + ID_PRODUCT_FROM_DATABASE=PowerShot A610 (normal mode)/PowerShot A610 (PTP mode) + +usb:v04A9p30FE* + ID_PRODUCT_FROM_DATABASE=Digital IXUS 65 (PTP mode)/PowerShot SD630 (PTP mode) + +usb:v04A9p30FF* + ID_PRODUCT_FROM_DATABASE=Digital IXUS 55 (PTP mode)/PowerShot SD450 (PTP mode) + +usb:v04A9p3100* + ID_PRODUCT_FROM_DATABASE=PowerShot TX1 + +usb:v04A9p310B* + ID_PRODUCT_FROM_DATABASE=SELPHY CP600 + +usb:v04A9p310E* + ID_PRODUCT_FROM_DATABASE=Digital IXUS 50 (PTP mode) + +usb:v04A9p3110* + ID_PRODUCT_FROM_DATABASE=EOS Digital Rebel XTi + +usb:v04A9p3116* + ID_PRODUCT_FROM_DATABASE=Digital IXUS 750 / PowerShot SD550 (PTP mode) + +usb:v04A9p3117* + ID_PRODUCT_FROM_DATABASE=PowerShot A700 + +usb:v04A9p3119* + ID_PRODUCT_FROM_DATABASE=PowerShot SD700 IS / Digital IXUS 800 IS / IXY Digital 800 IS + +usb:v04A9p311B* + ID_PRODUCT_FROM_DATABASE=PowerShot A540 + +usb:v04A9p3127* + ID_PRODUCT_FROM_DATABASE=SELPHY CP710 + +usb:v04A9p3128* + ID_PRODUCT_FROM_DATABASE=SELPHY CP510 + +usb:v04A9p312D* + ID_PRODUCT_FROM_DATABASE=Elura 100 + +usb:v04A9p3138* + ID_PRODUCT_FROM_DATABASE=PowerShot A710 IS + +usb:v04A9p3141* + ID_PRODUCT_FROM_DATABASE=SELPHY ES1 + +usb:v04A9p3142* + ID_PRODUCT_FROM_DATABASE=SELPHY CP730 + +usb:v04A9p3143* + ID_PRODUCT_FROM_DATABASE=SELPHY CP720 + +usb:v04A9p3147* + ID_PRODUCT_FROM_DATABASE=EOS 1Ds Mark III + +usb:v04A9p314F* + ID_PRODUCT_FROM_DATABASE=Powershot SD1000 + +usb:v04A9p3155* + ID_PRODUCT_FROM_DATABASE=PowerShot A450 + +usb:v04A9p315A* + ID_PRODUCT_FROM_DATABASE=PowerShot G9 + +usb:v04A9p315D* + ID_PRODUCT_FROM_DATABASE=PowerShot A720 + +usb:v04A9p3160* + ID_PRODUCT_FROM_DATABASE=Digital IXUS 860 IS + +usb:v04A9p3170* + ID_PRODUCT_FROM_DATABASE=SELPHY CP750 + +usb:v04A9p3171* + ID_PRODUCT_FROM_DATABASE=SELPHY CP740 + +usb:v04A9p3175* + ID_PRODUCT_FROM_DATABASE=IXY Digital 25 IS + +usb:v04A9p3176* + ID_PRODUCT_FROM_DATABASE=PowerShot A590 + +usb:v04A9p317A* + ID_PRODUCT_FROM_DATABASE=PC1267 [Powershot A470] + +usb:v04A9p3184* + ID_PRODUCT_FROM_DATABASE=Digital IXUS 80 IS (PTP mode) + +usb:v04A9p3185* + ID_PRODUCT_FROM_DATABASE=SELPHY ES2 + +usb:v04A9p3192* + ID_PRODUCT_FROM_DATABASE=PowerShot SX110 IS + +usb:v04A9p319A* + ID_PRODUCT_FROM_DATABASE=EOS 7D + +usb:v04A9p31AA* + ID_PRODUCT_FROM_DATABASE=SELPHY CP770 + +usb:v04A9p31AB* + ID_PRODUCT_FROM_DATABASE=SELPHY CP760 + +usb:v04A9p31AD* + ID_PRODUCT_FROM_DATABASE=PowerShot E1 + +usb:v04A9p31B0* + ID_PRODUCT_FROM_DATABASE=SELPHY ES30 + +usb:v04A9p31BC* + ID_PRODUCT_FROM_DATABASE=PowerShot D10 + +usb:v04A9p31BF* + ID_PRODUCT_FROM_DATABASE=PowerShot A480 + +usb:v04A9p31C0* + ID_PRODUCT_FROM_DATABASE=PowerShot SX200 IS + +usb:v04A9p31DD* + ID_PRODUCT_FROM_DATABASE=SELPHY CP780 + +usb:v04A9p31E5* + ID_PRODUCT_FROM_DATABASE=Digital IXUS 200 IS + +usb:v04A9p31EE* + ID_PRODUCT_FROM_DATABASE=SELPHY ES40 + +usb:v04A9p31EF* + ID_PRODUCT_FROM_DATABASE=PowerShot A495 + +usb:v04A9p31F1* + ID_PRODUCT_FROM_DATABASE=PowerShot A3100 IS / PowerShot A3150 IS + +usb:v04A9p31F2* + ID_PRODUCT_FROM_DATABASE=PowerShot A3000 IS + +usb:v04A9p31F3* + ID_PRODUCT_FROM_DATABASE=PowerShot Digital ELPH SD1400 IS + +usb:v04A9p31F4* + ID_PRODUCT_FROM_DATABASE=PowerShot SD1300 IS / IXUS 105 + +usb:v04A9p31F5* + ID_PRODUCT_FROM_DATABASE=Powershot SD3500 IS / IXUS 210 IS + +usb:v04A9p31F6* + ID_PRODUCT_FROM_DATABASE=PowerShot SX210 IS + +usb:v04A9p31F7* + ID_PRODUCT_FROM_DATABASE=Powershot SD4000 IS / IXUS 300 HS / IXY 30S + +usb:v04A9p31F8* + ID_PRODUCT_FROM_DATABASE=Powershot SD4500 IS / IXUS 1000 HS / IXY 50S + +usb:v04A9p31FF* + ID_PRODUCT_FROM_DATABASE=Digital IXUS 55 + +usb:v04A9p3209* + ID_PRODUCT_FROM_DATABASE=Vixia HF S21 A + +usb:v04A9p3210* + ID_PRODUCT_FROM_DATABASE=Powershot SX30 IS + +usb:v04A9p3211* + ID_PRODUCT_FROM_DATABASE=PowerShot SX130 IS + +usb:v04A9p3212* + ID_PRODUCT_FROM_DATABASE=Powershot S95 + +usb:v04A9p3214* + ID_PRODUCT_FROM_DATABASE=SELPHY CP800 + +usb:v04A9p3218* + ID_PRODUCT_FROM_DATABASE=EOS 600D / Rebel T3i (ptp) + +usb:v04A9p3223* + ID_PRODUCT_FROM_DATABASE=PowerShot A3300 IS + +usb:v04A9p3224* + ID_PRODUCT_FROM_DATABASE=PowerShot A3200 IS + +usb:v04A9p3226* + ID_PRODUCT_FROM_DATABASE=PowerShow A800 + +usb:v04A9p3228* + ID_PRODUCT_FROM_DATABASE=PowerShot SX230 HS + +usb:v04A9p3229* + ID_PRODUCT_FROM_DATABASE=IXUS 220 HS + +usb:v04A9p322A* + ID_PRODUCT_FROM_DATABASE=PowerShot A2200 + +usb:v04A9p322B* + ID_PRODUCT_FROM_DATABASE=Powershot A1200 + +usb:v04A9p3233* + ID_PRODUCT_FROM_DATABASE=PowerShot G1 X + +usb:v04A9p3234* + ID_PRODUCT_FROM_DATABASE=PowerShot SX150 IS + +usb:v04A9p3236* + ID_PRODUCT_FROM_DATABASE=PowerShot S100 + +usb:v04A9p3238* + ID_PRODUCT_FROM_DATABASE=PowerShot SX40 HS + +usb:v04A9p323F* + ID_PRODUCT_FROM_DATABASE=PowerShot A810 + +usb:v04A9p3243* + ID_PRODUCT_FROM_DATABASE=PowerShot A4000 IS + +usb:v04A9p3244* + ID_PRODUCT_FROM_DATABASE=PowerShot SX260 HS + +usb:v04A9p3245* + ID_PRODUCT_FROM_DATABASE=PowerShot SX240 HS + +usb:v04A9p3247* + ID_PRODUCT_FROM_DATABASE=PowerShot ELPH 520 HS + +usb:v04A9p3248* + ID_PRODUCT_FROM_DATABASE=PowerShot A3400 IS + +usb:v04A9p3249* + ID_PRODUCT_FROM_DATABASE=PowerShot A2400 IS + +usb:v04A9p324A* + ID_PRODUCT_FROM_DATABASE=PowerShot A2300 + +usb:v04A9p3255* + ID_PRODUCT_FROM_DATABASE=SELPHY CP900 + +usb:v04A9p3256* + ID_PRODUCT_FROM_DATABASE=SELPHY CP810 + +usb:v04A9p3259* + ID_PRODUCT_FROM_DATABASE=PowerShot SX50 HS + +usb:v04A9p325A* + ID_PRODUCT_FROM_DATABASE=PowerShot SX160 IS + +usb:v04AA* + ID_VENDOR_FROM_DATABASE=DaeWoo Telecom, Ltd + +usb:v04AB* + ID_VENDOR_FROM_DATABASE=Chromatic Research + +usb:v04AC* + ID_VENDOR_FROM_DATABASE=Micro Audiometrics Corp. + +usb:v04AD* + ID_VENDOR_FROM_DATABASE=Dooin Electronics + +usb:v04ADp2501* + ID_PRODUCT_FROM_DATABASE=Bluetooth Device + +usb:v04AF* + ID_VENDOR_FROM_DATABASE=Winnov L.P. + +usb:v04B0* + ID_VENDOR_FROM_DATABASE=Nikon Corp. + +usb:v04B0p0102* + ID_PRODUCT_FROM_DATABASE=Coolpix 990 + +usb:v04B0p0103* + ID_PRODUCT_FROM_DATABASE=Coolpix 880 + +usb:v04B0p0104* + ID_PRODUCT_FROM_DATABASE=Coolpix 995 + +usb:v04B0p0106* + ID_PRODUCT_FROM_DATABASE=Coolpix 775 + +usb:v04B0p0107* + ID_PRODUCT_FROM_DATABASE=Coolpix 5000 + +usb:v04B0p0108* + ID_PRODUCT_FROM_DATABASE=Coolpix 2500 + +usb:v04B0p0109* + ID_PRODUCT_FROM_DATABASE=Coolpix 2500 (ptp) + +usb:v04B0p010A* + ID_PRODUCT_FROM_DATABASE=Coolpix 4500 + +usb:v04B0p010B* + ID_PRODUCT_FROM_DATABASE=Coolpix 4500 (ptp) + +usb:v04B0p010D* + ID_PRODUCT_FROM_DATABASE=Coolpix 5700 (ptp) + +usb:v04B0p010E* + ID_PRODUCT_FROM_DATABASE=Coolpix 4300 (storage) + +usb:v04B0p010F* + ID_PRODUCT_FROM_DATABASE=Coolpix 4300 (ptp) + +usb:v04B0p0110* + ID_PRODUCT_FROM_DATABASE=Coolpix 3500 (Sierra Mode) + +usb:v04B0p0111* + ID_PRODUCT_FROM_DATABASE=Coolpix 3500 (ptp) + +usb:v04B0p0112* + ID_PRODUCT_FROM_DATABASE=Coolpix 885 (ptp) + +usb:v04B0p0113* + ID_PRODUCT_FROM_DATABASE=Coolpix 5000 (ptp) + +usb:v04B0p0114* + ID_PRODUCT_FROM_DATABASE=Coolpix 3100 (storage) + +usb:v04B0p0115* + ID_PRODUCT_FROM_DATABASE=Coolpix 3100 (ptp) + +usb:v04B0p0117* + ID_PRODUCT_FROM_DATABASE=Coolpix 2100 (ptp) + +usb:v04B0p0119* + ID_PRODUCT_FROM_DATABASE=Coolpix 5400 (ptp) + +usb:v04B0p011D* + ID_PRODUCT_FROM_DATABASE=Coolpix 3700 (ptp) + +usb:v04B0p0121* + ID_PRODUCT_FROM_DATABASE=Coolpix 3200 (ptp) + +usb:v04B0p0122* + ID_PRODUCT_FROM_DATABASE=Coolpix 2200 (ptp) + +usb:v04B0p0124* + ID_PRODUCT_FROM_DATABASE=Coolpix 8400 (mass storage mode) + +usb:v04B0p0125* + ID_PRODUCT_FROM_DATABASE=Coolpix 8400 (ptp) + +usb:v04B0p0126* + ID_PRODUCT_FROM_DATABASE=Coolpix 8800 + +usb:v04B0p0129* + ID_PRODUCT_FROM_DATABASE=Coolpix 4800 (ptp) + +usb:v04B0p012C* + ID_PRODUCT_FROM_DATABASE=Coolpix 4100 (storage) + +usb:v04B0p012D* + ID_PRODUCT_FROM_DATABASE=Coolpix 4100 (ptp) + +usb:v04B0p012E* + ID_PRODUCT_FROM_DATABASE=Coolpix 5600 (ptp) + +usb:v04B0p0130* + ID_PRODUCT_FROM_DATABASE=Coolpix 4600 (ptp) + +usb:v04B0p0135* + ID_PRODUCT_FROM_DATABASE=Coolpix 5900 (ptp) + +usb:v04B0p0136* + ID_PRODUCT_FROM_DATABASE=Coolpix 7900 (storage) + +usb:v04B0p0137* + ID_PRODUCT_FROM_DATABASE=Coolpix 7900 (ptp) + +usb:v04B0p013A* + ID_PRODUCT_FROM_DATABASE=Coolpix 100 (storage) + +usb:v04B0p013B* + ID_PRODUCT_FROM_DATABASE=Coolpix 100 (ptp) + +usb:v04B0p0141* + ID_PRODUCT_FROM_DATABASE=Coolpix P2 (storage) + +usb:v04B0p0142* + ID_PRODUCT_FROM_DATABASE=Coolpix P2 (ptp) + +usb:v04B0p0163* + ID_PRODUCT_FROM_DATABASE=Coolpix P5100 (ptp) + +usb:v04B0p0169* + ID_PRODUCT_FROM_DATABASE=Coolpix P50 (ptp) + +usb:v04B0p0202* + ID_PRODUCT_FROM_DATABASE=Coolpix SQ (ptp) + +usb:v04B0p0203* + ID_PRODUCT_FROM_DATABASE=Coolpix 4200 (mass storage mode) + +usb:v04B0p0204* + ID_PRODUCT_FROM_DATABASE=Coolpix 4200 (ptp) + +usb:v04B0p0205* + ID_PRODUCT_FROM_DATABASE=Coolpix 5200 (storage) + +usb:v04B0p0206* + ID_PRODUCT_FROM_DATABASE=Coolpix 5200 (ptp) + +usb:v04B0p0301* + ID_PRODUCT_FROM_DATABASE=Coolpix 2000 (storage) + +usb:v04B0p0302* + ID_PRODUCT_FROM_DATABASE=Coolpix 2000 (ptp) + +usb:v04B0p0317* + ID_PRODUCT_FROM_DATABASE=Coolpix L20 (ptp) + +usb:v04B0p0402* + ID_PRODUCT_FROM_DATABASE=DSC D100 (ptp) + +usb:v04B0p0403* + ID_PRODUCT_FROM_DATABASE=D2H (mass storage mode) + +usb:v04B0p0404* + ID_PRODUCT_FROM_DATABASE=D2H SLR (ptp) + +usb:v04B0p0405* + ID_PRODUCT_FROM_DATABASE=D70 (mass storage mode) + +usb:v04B0p0406* + ID_PRODUCT_FROM_DATABASE=DSC D70 (ptp) + +usb:v04B0p0408* + ID_PRODUCT_FROM_DATABASE=D2X SLR (ptp) + +usb:v04B0p0409* + ID_PRODUCT_FROM_DATABASE=D50 digital camera + +usb:v04B0p040A* + ID_PRODUCT_FROM_DATABASE=D50 (ptp) + +usb:v04B0p040C* + ID_PRODUCT_FROM_DATABASE=D2Hs + +usb:v04B0p040E* + ID_PRODUCT_FROM_DATABASE=DSC D70s (ptp) + +usb:v04B0p040F* + ID_PRODUCT_FROM_DATABASE=D200 (mass storage mode) + +usb:v04B0p0410* + ID_PRODUCT_FROM_DATABASE=D200 (ptp) + +usb:v04B0p0413* + ID_PRODUCT_FROM_DATABASE=D40 (mass storage mode) + +usb:v04B0p041E* + ID_PRODUCT_FROM_DATABASE=D60 digital camera (mass storage mode) + +usb:v04B0p0422* + ID_PRODUCT_FROM_DATABASE=D700 (ptp) + +usb:v04B0p0425* + ID_PRODUCT_FROM_DATABASE=D300S + +usb:v04B0p042A* + ID_PRODUCT_FROM_DATABASE=D800 (ptp) + +usb:v04B0p0F03* + ID_PRODUCT_FROM_DATABASE=PD-10 Wireless Printer Adapter + +usb:v04B0p4000* + ID_PRODUCT_FROM_DATABASE=Coolscan LS 40 ED + +usb:v04B0p4001* + ID_PRODUCT_FROM_DATABASE=LS 50 ED/Coolscan V ED + +usb:v04B0p4002* + ID_PRODUCT_FROM_DATABASE=Super Coolscan LS-5000 ED + +usb:v04B1* + ID_VENDOR_FROM_DATABASE=Pan International + +usb:v04B3* + ID_VENDOR_FROM_DATABASE=IBM Corp. + +usb:v04B3p3003* + ID_PRODUCT_FROM_DATABASE=Rapid Access III Keyboard + +usb:v04B3p3004* + ID_PRODUCT_FROM_DATABASE=Media Access Pro Keyboard + +usb:v04B3p300A* + ID_PRODUCT_FROM_DATABASE=Rapid Access IIIe Keyboard + +usb:v04B3p3016* + ID_PRODUCT_FROM_DATABASE=UltraNav Keyboard Hub + +usb:v04B3p3018* + ID_PRODUCT_FROM_DATABASE=UltraNav Keyboard + +usb:v04B3p301B* + ID_PRODUCT_FROM_DATABASE=SK-8815 Keyboard + +usb:v04B3p301C* + ID_PRODUCT_FROM_DATABASE=Enhanced Performance Keyboard + +usb:v04B3p3020* + ID_PRODUCT_FROM_DATABASE=Enhanced Performance Keyboard + +usb:v04B3p3025* + ID_PRODUCT_FROM_DATABASE=NetVista Full Width Keyboard + +usb:v04B3p3100* + ID_PRODUCT_FROM_DATABASE=NetVista Mouse + +usb:v04B3p3103* + ID_PRODUCT_FROM_DATABASE=ScrollPoint Pro Mouse + +usb:v04B3p3104* + ID_PRODUCT_FROM_DATABASE=ScrollPoint Wireless Mouse + +usb:v04B3p3105* + ID_PRODUCT_FROM_DATABASE=ScrollPoint Optical (HID) + +usb:v04B3p3107* + ID_PRODUCT_FROM_DATABASE=ThinkPad 800dpi Optical Travel Mouse + +usb:v04B3p3108* + ID_PRODUCT_FROM_DATABASE=800dpi Optical Mouse w/ Scroll Point + +usb:v04B3p3109* + ID_PRODUCT_FROM_DATABASE=Optical ScrollPoint Pro Mouse + +usb:v04B3p310B* + ID_PRODUCT_FROM_DATABASE=Red Wheel Mouse + +usb:v04B3p310C* + ID_PRODUCT_FROM_DATABASE=Wheel Mouse + +usb:v04B3p4427* + ID_PRODUCT_FROM_DATABASE=Portable CD ROM + +usb:v04B3p4482* + ID_PRODUCT_FROM_DATABASE=Serial Converter + +usb:v04B3p4485* + ID_PRODUCT_FROM_DATABASE=Serial Converter + +usb:v04B3p4525* + ID_PRODUCT_FROM_DATABASE=Double sided CRT + +usb:v04B3p4535* + ID_PRODUCT_FROM_DATABASE=4610 Suremark Printer + +usb:v04B3p4550* + ID_PRODUCT_FROM_DATABASE=NVRAM (128 KB) + +usb:v04B3p4554* + ID_PRODUCT_FROM_DATABASE=Cash Drawer + +usb:v04B3p4580* + ID_PRODUCT_FROM_DATABASE=Hub w/ NVRAM + +usb:v04B3p4581* + ID_PRODUCT_FROM_DATABASE=4800-2xx Hub w/ Cash Drawer + +usb:v04B3p4604* + ID_PRODUCT_FROM_DATABASE=Keyboard w/ Card Reader + +usb:v04B3p4671* + ID_PRODUCT_FROM_DATABASE=4820 LCD w/ MSR/KB + +usb:v04B4* + ID_VENDOR_FROM_DATABASE=Cypress Semiconductor Corp. + +usb:v04B4p0001* + ID_PRODUCT_FROM_DATABASE=Mouse + +usb:v04B4p0002* + ID_PRODUCT_FROM_DATABASE=CY7C63x0x Thermometer + +usb:v04B4p0033* + ID_PRODUCT_FROM_DATABASE=Mouse + +usb:v04B4p0100* + ID_PRODUCT_FROM_DATABASE=Cino FuzzyScan F760-B + +usb:v04B4p0101* + ID_PRODUCT_FROM_DATABASE=Keyboard/Hub + +usb:v04B4p0102* + ID_PRODUCT_FROM_DATABASE=Keyboard with APM + +usb:v04B4p0130* + ID_PRODUCT_FROM_DATABASE=MyIRC Remote Receiver + +usb:v04B4p0306* + ID_PRODUCT_FROM_DATABASE=Telephone Receiver + +usb:v04B4p0407* + ID_PRODUCT_FROM_DATABASE=Optical Skype Mouse + +usb:v04B4p0BAD* + ID_PRODUCT_FROM_DATABASE=MetaGeek Wi-Spy + +usb:v04B4p1002* + ID_PRODUCT_FROM_DATABASE=CY7C63001 R100 FM Radio + +usb:v04B4p1006* + ID_PRODUCT_FROM_DATABASE=Human Interface Device + +usb:v04B4p2050* + ID_PRODUCT_FROM_DATABASE=hub + +usb:v04B4p2830* + ID_PRODUCT_FROM_DATABASE=Opera1 DVB-S (cold state) + +usb:v04B4p4381* + ID_PRODUCT_FROM_DATABASE=SCAPS USC-1 Scanner Controller + +usb:v04B4p4611* + ID_PRODUCT_FROM_DATABASE=Storage Adapter FX2 (CY) + +usb:v04B4p4616* + ID_PRODUCT_FROM_DATABASE=Flash Disk (TPP) + +usb:v04B4p5201* + ID_PRODUCT_FROM_DATABASE=Combi Keyboard-Hub (Hub) + +usb:v04B4p5202* + ID_PRODUCT_FROM_DATABASE=Combi Keyboard-Hub (Keyboard) + +usb:v04B4p5500* + ID_PRODUCT_FROM_DATABASE=HID->COM RS232 Adapter + +usb:v04B4p5A9B* + ID_PRODUCT_FROM_DATABASE=Dacal CD/DVD Library D-101/DC-300/DC-016RW + +usb:v04B4p6370* + ID_PRODUCT_FROM_DATABASE=ViewMate Desktop Mouse CC2201 + +usb:v04B4p6560* + ID_PRODUCT_FROM_DATABASE=CY7C65640 USB-2.0 "TetraHub" + +usb:v04B4p6830* + ID_PRODUCT_FROM_DATABASE=CY7C68300A EZ-USB AT2 USB 2.0 to ATA/ATAPI + +usb:v04B4p6831* + ID_PRODUCT_FROM_DATABASE=Storage Adapter ISD-300LP (CY) + +usb:v04B4p7417* + ID_PRODUCT_FROM_DATABASE=Wireless PC Lock/Ultra Mouse + +usb:v04B4p8329* + ID_PRODUCT_FROM_DATABASE=USB To keyboard/Mouse Converter + +usb:v04B4p8613* + ID_PRODUCT_FROM_DATABASE=CY7C68013 EZ-USB FX2 USB 2.0 Development Kit + +usb:v04B4p8614* + ID_PRODUCT_FROM_DATABASE=DTV-DVB UDST7020BDA DVB-S Box(DVBS for MCE2005) + +usb:v04B4p861F* + ID_PRODUCT_FROM_DATABASE=Anysee E30 USB 2.0 DVB-T Receiver + +usb:v04B4pBCA1* + ID_PRODUCT_FROM_DATABASE=Barcode Reader + +usb:v04B4pCC04* + ID_PRODUCT_FROM_DATABASE=Centor USB RACIA-ALVAR USB PORT + +usb:v04B4pCC06* + ID_PRODUCT_FROM_DATABASE=Centor-P RACIA-ALVAR USB PORT + +usb:v04B4pD5D5* + ID_PRODUCT_FROM_DATABASE=CY7C63x0x Zoltrix Z-Boxer GamePad + +usb:v04B4pDE61* + ID_PRODUCT_FROM_DATABASE=Barcode Reader + +usb:v04B4pDE64* + ID_PRODUCT_FROM_DATABASE=Barcode Reader + +usb:v04B4pF000* + ID_PRODUCT_FROM_DATABASE=CY30700 Licorice evaluation board + +usb:v04B4pF111* + ID_PRODUCT_FROM_DATABASE=CY8CKIT-002 PSoC MiniProg3 Rev A Program and debug kit + +usb:v04B4pF115* + ID_PRODUCT_FROM_DATABASE=PSoC FirstTouch Programmer + +usb:v04B5* + ID_VENDOR_FROM_DATABASE=ROHM LSI Systems USA, LLC + +usb:v04B5p3064* + ID_PRODUCT_FROM_DATABASE=Hantek DSO-3064 + +usb:v04B6* + ID_VENDOR_FROM_DATABASE=Hint Corp. + +usb:v04B7* + ID_VENDOR_FROM_DATABASE=Compal Electronics, Inc. + +usb:v04B8* + ID_VENDOR_FROM_DATABASE=Seiko Epson Corp. + +usb:v04B8p0001* + ID_PRODUCT_FROM_DATABASE=Stylus Color 740 / Photo 750 + +usb:v04B8p0002* + ID_PRODUCT_FROM_DATABASE=ISD Smart Cable for Mac + +usb:v04B8p0003* + ID_PRODUCT_FROM_DATABASE=ISD Smart Cable + +usb:v04B8p0004* + ID_PRODUCT_FROM_DATABASE=Printer + +usb:v04B8p0005* + ID_PRODUCT_FROM_DATABASE=Printer + +usb:v04B8p0006* + ID_PRODUCT_FROM_DATABASE=Printer + +usb:v04B8p0007* + ID_PRODUCT_FROM_DATABASE=Printer + +usb:v04B8p0101* + ID_PRODUCT_FROM_DATABASE=GT-7000U [Perfection 636] + +usb:v04B8p0102* + ID_PRODUCT_FROM_DATABASE=GT-2200 + +usb:v04B8p0103* + ID_PRODUCT_FROM_DATABASE=GT-6600U [Perfection 610] + +usb:v04B8p0104* + ID_PRODUCT_FROM_DATABASE=GT-7600UF [Perfection 1200U/1200U Photo] + +usb:v04B8p0105* + ID_PRODUCT_FROM_DATABASE=Stylus Scan 2000 + +usb:v04B8p0106* + ID_PRODUCT_FROM_DATABASE=Stylus Scan 2500 + +usb:v04B8p0107* + ID_PRODUCT_FROM_DATABASE=ES-2000 [Expression 1600U] + +usb:v04B8p0108* + ID_PRODUCT_FROM_DATABASE=CC-700 + +usb:v04B8p0109* + ID_PRODUCT_FROM_DATABASE=ES-8500 [Expression 1640 XL] + +usb:v04B8p010A* + ID_PRODUCT_FROM_DATABASE=GT-8700/GT-8700F [Perfection 1640SU/1640SU PHOTO] + +usb:v04B8p010B* + ID_PRODUCT_FROM_DATABASE=GT-7700U [Perfection 1240U] + +usb:v04B8p010C* + ID_PRODUCT_FROM_DATABASE=GT-6700U [Perfection 640] + +usb:v04B8p010D* + ID_PRODUCT_FROM_DATABASE=CC-500L + +usb:v04B8p010E* + ID_PRODUCT_FROM_DATABASE=ES-2200 [Perfection 1680] + +usb:v04B8p010F* + ID_PRODUCT_FROM_DATABASE=GT-7200U [Perfection 1250/1250 PHOTO] + +usb:v04B8p0110* + ID_PRODUCT_FROM_DATABASE=GT-8200U/GT-8200UF [Perfection 1650/1650 PHOTO] + +usb:v04B8p0112* + ID_PRODUCT_FROM_DATABASE=GT-9700F [Perfection 2450 PHOTO] + +usb:v04B8p0114* + ID_PRODUCT_FROM_DATABASE=Perfection 660 + +usb:v04B8p0116* + ID_PRODUCT_FROM_DATABASE=GT-9400UF [Perfection 3170] + +usb:v04B8p0118* + ID_PRODUCT_FROM_DATABASE=GT-F600 [Perfection 4180] + +usb:v04B8p0119* + ID_PRODUCT_FROM_DATABASE=GT-X750 [Perfection 4490 Photo] + +usb:v04B8p011A* + ID_PRODUCT_FROM_DATABASE=CC-550L [1000 ICS] + +usb:v04B8p011B* + ID_PRODUCT_FROM_DATABASE=GT-9300UF [Perfection 2400 PHOTO] + +usb:v04B8p011C* + ID_PRODUCT_FROM_DATABASE=GT-9800F [Perfection 3200] + +usb:v04B8p011D* + ID_PRODUCT_FROM_DATABASE=GT-7300U [Perfection 1260/1260 PHOTO] + +usb:v04B8p011E* + ID_PRODUCT_FROM_DATABASE=GT-8300UF [Perfection 1660 PHOTO] + +usb:v04B8p011F* + ID_PRODUCT_FROM_DATABASE=GT-8400UF [Perfection 1670/1670 PHOTO] + +usb:v04B8p0120* + ID_PRODUCT_FROM_DATABASE=GT-7400U [Perfection 1270] + +usb:v04B8p0121* + ID_PRODUCT_FROM_DATABASE=GT-F500/GT-F550 [Perfection 2480/2580 PHOTO] + +usb:v04B8p0122* + ID_PRODUCT_FROM_DATABASE=GT-F520/GT-F570 [Perfection 3590 PHOTO] + +usb:v04B8p0126* + ID_PRODUCT_FROM_DATABASE=ES-7000H [GT-15000] + +usb:v04B8p0128* + ID_PRODUCT_FROM_DATABASE=GT-X700 [Perfection 4870] + +usb:v04B8p0129* + ID_PRODUCT_FROM_DATABASE=ES-10000G [Expression 10000XL] + +usb:v04B8p012A* + ID_PRODUCT_FROM_DATABASE=GT-X800 [Perfection 4990 PHOTO] + +usb:v04B8p012B* + ID_PRODUCT_FROM_DATABASE=ES-H300 [GT-2500] + +usb:v04B8p012C* + ID_PRODUCT_FROM_DATABASE=GT-X900 [Perfection V700/V750 Photo] + +usb:v04B8p012D* + ID_PRODUCT_FROM_DATABASE=GT-F650 [GT-S600/Perfection V10/V100] + +usb:v04B8p012E* + ID_PRODUCT_FROM_DATABASE=GT-F670 [Perfection V200 Photo] + +usb:v04B8p012F* + ID_PRODUCT_FROM_DATABASE=GT-F700 [Perfection V350] + +usb:v04B8p0130* + ID_PRODUCT_FROM_DATABASE=GT-X770 [Perfection V500] + +usb:v04B8p0131* + ID_PRODUCT_FROM_DATABASE=GT-F720 [GT-S620/Perfection V30/V300 Photo] + +usb:v04B8p0133* + ID_PRODUCT_FROM_DATABASE=GT-1500 [GT-D1000] + +usb:v04B8p0135* + ID_PRODUCT_FROM_DATABASE=GT-X970 + +usb:v04B8p0136* + ID_PRODUCT_FROM_DATABASE=ES-D400 [GT-S80] + +usb:v04B8p0137* + ID_PRODUCT_FROM_DATABASE=ES-D200 [GT-S50] + +usb:v04B8p0138* + ID_PRODUCT_FROM_DATABASE=ES-H7200 [GT-20000] + +usb:v04B8p013A* + ID_PRODUCT_FROM_DATABASE=GT-X820 [Perfection V600 Photo] + +usb:v04B8p0142* + ID_PRODUCT_FROM_DATABASE=GT-F730 [GT-S630/Perfection V33/V330 Photo] + +usb:v04B8p0143* + ID_PRODUCT_FROM_DATABASE=GT-S55 + +usb:v04B8p0144* + ID_PRODUCT_FROM_DATABASE=GT-S85 + +usb:v04B8p0202* + ID_PRODUCT_FROM_DATABASE=Receipt Printer M129C + +usb:v04B8p0401* + ID_PRODUCT_FROM_DATABASE=CP 800 Digital Camera + +usb:v04B8p0402* + ID_PRODUCT_FROM_DATABASE=PhotoPC 850z + +usb:v04B8p0403* + ID_PRODUCT_FROM_DATABASE=PhotoPC 3000z + +usb:v04B8p0509* + ID_PRODUCT_FROM_DATABASE=JVC PIX-MC10 + +usb:v04B8p0601* + ID_PRODUCT_FROM_DATABASE=Stylus Photo 875DC Card Reader + +usb:v04B8p0602* + ID_PRODUCT_FROM_DATABASE=Stylus Photo 895 Card Reader + +usb:v04B8p0801* + ID_PRODUCT_FROM_DATABASE=CC-600PX [Stylus CX5200/CX5400/CX6600] + +usb:v04B8p0802* + ID_PRODUCT_FROM_DATABASE=CC-570L [Stylus CX3100/CX3200] + +usb:v04B8p0803* + ID_PRODUCT_FROM_DATABASE=Printer (Composite Device) + +usb:v04B8p0804* + ID_PRODUCT_FROM_DATABASE=Storage Device + +usb:v04B8p0805* + ID_PRODUCT_FROM_DATABASE=Stylus CX6300/CX6400 + +usb:v04B8p0806* + ID_PRODUCT_FROM_DATABASE=PM-A850 [Stylus Photo RX600/610] + +usb:v04B8p0807* + ID_PRODUCT_FROM_DATABASE=Stylus Photo RX500/510 + +usb:v04B8p0808* + ID_PRODUCT_FROM_DATABASE=Stylus CX5200/CX5300/CX5400 + +usb:v04B8p0809* + ID_PRODUCT_FROM_DATABASE=Storage Device + +usb:v04B8p080A* + ID_PRODUCT_FROM_DATABASE=F-3200 + +usb:v04B8p080C* + ID_PRODUCT_FROM_DATABASE=ME100 [Stylus CX1500] + +usb:v04B8p080D* + ID_PRODUCT_FROM_DATABASE=Stylus CX4500/4600 + +usb:v04B8p080E* + ID_PRODUCT_FROM_DATABASE=PX-A550 [CX-3500/3600/3650 MFP] + +usb:v04B8p080F* + ID_PRODUCT_FROM_DATABASE=Stylus Photo RX420/RX425/RX430 + +usb:v04B8p0810* + ID_PRODUCT_FROM_DATABASE=PM-A900 [Stylus Photo RX700] + +usb:v04B8p0811* + ID_PRODUCT_FROM_DATABASE=PM-A870 [Stylus Photo RX620/RX630] + +usb:v04B8p0812* + ID_PRODUCT_FROM_DATABASE=MFP Composite Device + +usb:v04B8p0813* + ID_PRODUCT_FROM_DATABASE=Stylus CX6500/6600 + +usb:v04B8p0814* + ID_PRODUCT_FROM_DATABASE=PM-A700 + +usb:v04B8p0815* + ID_PRODUCT_FROM_DATABASE=LP-A500 [AcuLaser CX1] + +usb:v04B8p0816* + ID_PRODUCT_FROM_DATABASE=Printer (Composite Device) + +usb:v04B8p0817* + ID_PRODUCT_FROM_DATABASE=LP-M5500/LP-M5500F + +usb:v04B8p0818* + ID_PRODUCT_FROM_DATABASE=Stylus CX3700/CX3800/DX3800 + +usb:v04B8p0819* + ID_PRODUCT_FROM_DATABASE=PX-A650 [Stylus CX4700/CX4800/DX4800/DX4850] + +usb:v04B8p081A* + ID_PRODUCT_FROM_DATABASE=PM-A750 [Stylus Photo RX520/RX530] + +usb:v04B8p081B* + ID_PRODUCT_FROM_DATABASE=MFP Composite Device + +usb:v04B8p081C* + ID_PRODUCT_FROM_DATABASE=PM-A890 [Stylus Photo RX640/RX650] + +usb:v04B8p081D* + ID_PRODUCT_FROM_DATABASE=PM-A950 + +usb:v04B8p081E* + ID_PRODUCT_FROM_DATABASE=MFP Composite Device + +usb:v04B8p081F* + ID_PRODUCT_FROM_DATABASE=Stylus CX7700/7800 + +usb:v04B8p0820* + ID_PRODUCT_FROM_DATABASE=Stylus CX4100/CX4200/DX4200 + +usb:v04B8p0821* + ID_PRODUCT_FROM_DATABASE=Stylus CX5700F/CX5800F + +usb:v04B8p0822* + ID_PRODUCT_FROM_DATABASE=Storage Device + +usb:v04B8p0823* + ID_PRODUCT_FROM_DATABASE=MFP Composite Device + +usb:v04B8p0824* + ID_PRODUCT_FROM_DATABASE=Storage Device + +usb:v04B8p0825* + ID_PRODUCT_FROM_DATABASE=MFP Composite Device + +usb:v04B8p0826* + ID_PRODUCT_FROM_DATABASE=Storage Device + +usb:v04B8p0827* + ID_PRODUCT_FROM_DATABASE=PM-A820 [Stylus Photo RX560/RX580/RX585/RX590] + +usb:v04B8p0828* + ID_PRODUCT_FROM_DATABASE=PM-A970 + +usb:v04B8p0829* + ID_PRODUCT_FROM_DATABASE=PM-T990 + +usb:v04B8p082A* + ID_PRODUCT_FROM_DATABASE=PM-A920 + +usb:v04B8p082B* + ID_PRODUCT_FROM_DATABASE=Stylus CX5900/CX5000/DX5000/DX5050 + +usb:v04B8p082C* + ID_PRODUCT_FROM_DATABASE=Storage Device + +usb:v04B8p082D* + ID_PRODUCT_FROM_DATABASE=Storage Device + +usb:v04B8p082E* + ID_PRODUCT_FROM_DATABASE=PX-A720 [Stylus CX5900/CX6000/DX6000] + +usb:v04B8p082F* + ID_PRODUCT_FROM_DATABASE=PX-A620 [Stylus CX3900/DX4000/DX4050] + +usb:v04B8p0830* + ID_PRODUCT_FROM_DATABASE=ME 200 [Stylus CX2800/CX2900] + +usb:v04B8p0831* + ID_PRODUCT_FROM_DATABASE=Stylus CX6900F/CX7000F/DX7000F + +usb:v04B8p0832* + ID_PRODUCT_FROM_DATABASE=MFP Composite Device + +usb:v04B8p0833* + ID_PRODUCT_FROM_DATABASE=LP-M5600 + +usb:v04B8p0834* + ID_PRODUCT_FROM_DATABASE=LP-M6000 + +usb:v04B8p0835* + ID_PRODUCT_FROM_DATABASE=AcuLaser CX21 + +usb:v04B8p0836* + ID_PRODUCT_FROM_DATABASE=PM-T960 + +usb:v04B8p0837* + ID_PRODUCT_FROM_DATABASE=PM-A940 [Stylus Photo RX680/RX685/RX690] + +usb:v04B8p0838* + ID_PRODUCT_FROM_DATABASE=PX-A640 [CX7300/CX7400/DX7400] + +usb:v04B8p0839* + ID_PRODUCT_FROM_DATABASE=PX-A740 [CX8300/CX8400/DX8400] + +usb:v04B8p083A* + ID_PRODUCT_FROM_DATABASE=PX-FA700 [CX9300F/CX9400Fax/DX9400F] + +usb:v04B8p083B* + ID_PRODUCT_FROM_DATABASE=MFP Composite Device + +usb:v04B8p083C* + ID_PRODUCT_FROM_DATABASE=PM-A840S [Stylus Photo RX595/RX610] + +usb:v04B8p083D* + ID_PRODUCT_FROM_DATABASE=MFP Composite Device + +usb:v04B8p083E* + ID_PRODUCT_FROM_DATABASE=MFP Composite Device + +usb:v04B8p083F* + ID_PRODUCT_FROM_DATABASE=Stylus CX4300/CX4400/CX5500/CX5600/DX4400/DX4450 + +usb:v04B8p0841* + ID_PRODUCT_FROM_DATABASE=PX-401A [ME 300/Stylus NX100] + +usb:v04B8p0843* + ID_PRODUCT_FROM_DATABASE=LP-M5000 + +usb:v04B8p0844* + ID_PRODUCT_FROM_DATABASE=EP-901A/EP-901F [Artisan 800/Stylus Photo PX800FW] + +usb:v04B8p0846* + ID_PRODUCT_FROM_DATABASE=EP-801A [Artisan 700/Stylus Photo PX700W/TX700W] + +usb:v04B8p0847* + ID_PRODUCT_FROM_DATABASE=PX-601F [ME Office 700FW/Stylus Office BX600FW/TX600FW] + +usb:v04B8p0848* + ID_PRODUCT_FROM_DATABASE=ME Office 600F/Stylus Office BX300F/TX300F + +usb:v04B8p0849* + ID_PRODUCT_FROM_DATABASE=Stylus SX205 + +usb:v04B8p084A* + ID_PRODUCT_FROM_DATABASE=PX-501A [Stylus NX400] + +usb:v04B8p084D* + ID_PRODUCT_FROM_DATABASE=PX-402A [Stylus SX115/Stylus NX110 Series] + +usb:v04B8p084F* + ID_PRODUCT_FROM_DATABASE=ME OFFICE 510 + +usb:v04B8p0850* + ID_PRODUCT_FROM_DATABASE=EP-702A [Stylus Photo PX650/TX650 Series] + +usb:v04B8p0851* + ID_PRODUCT_FROM_DATABASE=Stylus SX410 + +usb:v04B8p0852* + ID_PRODUCT_FROM_DATABASE=EP-802A [Artisan 710 Series/Stylus Photo PX710W/TX720W Series] + +usb:v04B8p0853* + ID_PRODUCT_FROM_DATABASE=EP-902A [Artisan 810 Series/Stylus Photo PX810FW Series] + +usb:v04B8p0854* + ID_PRODUCT_FROM_DATABASE=ME OFFICE 650FN Series/Stylus Office BX310FN/TX520FN Series + +usb:v04B8p0855* + ID_PRODUCT_FROM_DATABASE=PX-602F [Stylus Office BX610FW/TX620FW Series] + +usb:v04B8p0856* + ID_PRODUCT_FROM_DATABASE=PX-502A [Stylus SX515W] + +usb:v04B8p085C* + ID_PRODUCT_FROM_DATABASE=ME 320/330 Series [Stylus SX125] + +usb:v04B8p085D* + ID_PRODUCT_FROM_DATABASE=PX-603F [ME OFFICE 960FWD Series/Stylus Office BX625FWD/TX620FWD Series] + +usb:v04B8p085E* + ID_PRODUCT_FROM_DATABASE=PX-503A [ME OFFICE 900WD Series/Stylus Office BX525WD] + +usb:v04B8p085F* + ID_PRODUCT_FROM_DATABASE=Stylus Office BX320FW/TX525FW Series + +usb:v04B8p0860* + ID_PRODUCT_FROM_DATABASE=EP-903A/EP-903F [Artisan 835/Stylus Photo PX820FWD Series] + +usb:v04B8p0861* + ID_PRODUCT_FROM_DATABASE=EP-803A/EP-803AW [Artisan 725/Stylus Photo PX720WD/TX720WD Series] + +usb:v04B8p0862* + ID_PRODUCT_FROM_DATABASE=EP-703A [Stylus Photo PX660 Series] + +usb:v04B8p0863* + ID_PRODUCT_FROM_DATABASE=ME OFFICE 620F Series/Stylus Office BX305F/BX305FW/TX320F + +usb:v04B8p0864* + ID_PRODUCT_FROM_DATABASE=ME OFFICE 560W Series + +usb:v04B8p0865* + ID_PRODUCT_FROM_DATABASE=ME OFFICE 520 Series + +usb:v04B8p0866* + ID_PRODUCT_FROM_DATABASE=AcuLaser MX20DN/MX20DNF/MX21DNF + +usb:v04B8p0869* + ID_PRODUCT_FROM_DATABASE=PX-1600F + +usb:v04B8p086A* + ID_PRODUCT_FROM_DATABASE=PX-673F [Stylus Office BX925FWD] + +usb:v04B8p0870* + ID_PRODUCT_FROM_DATABASE=Stylus Office BX305FW Plus + +usb:v04B8p0871* + ID_PRODUCT_FROM_DATABASE=K200 Series + +usb:v04B8p0872* + ID_PRODUCT_FROM_DATABASE=K300 Series + +usb:v04B8p0873* + ID_PRODUCT_FROM_DATABASE=L200 Series + +usb:v04B8p0878* + ID_PRODUCT_FROM_DATABASE=EP-704A + +usb:v04B8p0879* + ID_PRODUCT_FROM_DATABASE=EP-904A/EP-904F [Artisan 837/Stylus Photo PX830FWD Series] + +usb:v04B8p087B* + ID_PRODUCT_FROM_DATABASE=EP-804A/EP-804AR/EP-804AW [Stylus Photo PX730WD/Artisan 730 Series] + +usb:v04B8p087C* + ID_PRODUCT_FROM_DATABASE=PX-1700F + +usb:v04B8p087D* + ID_PRODUCT_FROM_DATABASE=PX-B750F + +usb:v04B8p087F* + ID_PRODUCT_FROM_DATABASE=PX-403A + +usb:v04B8p0880* + ID_PRODUCT_FROM_DATABASE=PX-434A [Stylus NX330 Series] + +usb:v04B8p0881* + ID_PRODUCT_FROM_DATABASE=PX-404A [ME OFFICE 535] + +usb:v04B8p0883* + ID_PRODUCT_FROM_DATABASE=ME 340 Series/Stylus NX130 Series + +usb:v04B8p0884* + ID_PRODUCT_FROM_DATABASE=Stylus NX430W Series + +usb:v04B8p0885* + ID_PRODUCT_FROM_DATABASE=Stylus NX230 Series + +usb:v04B8p088F* + ID_PRODUCT_FROM_DATABASE=Stylus Office BX635FWD + +usb:v04B8p0890* + ID_PRODUCT_FROM_DATABASE=ME OFFICE 940FW Series/Stylus Office BX630FW Series + +usb:v04B8p0891* + ID_PRODUCT_FROM_DATABASE=Stylus Office BX535WD + +usb:v04B8p0892* + ID_PRODUCT_FROM_DATABASE=Stylus Office BX935FWD + +usb:v04B8p0893* + ID_PRODUCT_FROM_DATABASE=EP-774A + +usb:v04B9* + ID_VENDOR_FROM_DATABASE=Rainbow Technologies, Inc. + +usb:v04B9p0300* + ID_PRODUCT_FROM_DATABASE=SafeNet USB SuperPro/UltraPro + +usb:v04B9p1000* + ID_PRODUCT_FROM_DATABASE=iKey 1000 Token + +usb:v04B9p1001* + ID_PRODUCT_FROM_DATABASE=iKey 1200 Token + +usb:v04B9p1002* + ID_PRODUCT_FROM_DATABASE=iKey Token + +usb:v04B9p1003* + ID_PRODUCT_FROM_DATABASE=iKey Token + +usb:v04B9p1004* + ID_PRODUCT_FROM_DATABASE=iKey Token + +usb:v04B9p1005* + ID_PRODUCT_FROM_DATABASE=iKey Token + +usb:v04B9p1006* + ID_PRODUCT_FROM_DATABASE=iKey Token + +usb:v04B9p1200* + ID_PRODUCT_FROM_DATABASE=iKey 2000 Token + +usb:v04B9p1201* + ID_PRODUCT_FROM_DATABASE=iKey Token + +usb:v04B9p1202* + ID_PRODUCT_FROM_DATABASE=iKey 2032 Token + +usb:v04B9p1203* + ID_PRODUCT_FROM_DATABASE=iKey Token + +usb:v04B9p1204* + ID_PRODUCT_FROM_DATABASE=iKey Token + +usb:v04B9p1205* + ID_PRODUCT_FROM_DATABASE=iKey Token + +usb:v04B9p1206* + ID_PRODUCT_FROM_DATABASE=iKey 4000 Token + +usb:v04B9p1300* + ID_PRODUCT_FROM_DATABASE=iKey 3000 Token + +usb:v04B9p1301* + ID_PRODUCT_FROM_DATABASE=iKey 3000 + +usb:v04B9p1302* + ID_PRODUCT_FROM_DATABASE=iKey Token + +usb:v04B9p1303* + ID_PRODUCT_FROM_DATABASE=iKey Token + +usb:v04B9p1304* + ID_PRODUCT_FROM_DATABASE=iKey Token + +usb:v04B9p1305* + ID_PRODUCT_FROM_DATABASE=iKey Token + +usb:v04B9p1306* + ID_PRODUCT_FROM_DATABASE=iKey Token + +usb:v04BA* + ID_VENDOR_FROM_DATABASE=Toucan Systems, Ltd + +usb:v04BB* + ID_VENDOR_FROM_DATABASE=I-O Data Device, Inc. + +usb:v04BBp0101* + ID_PRODUCT_FROM_DATABASE=USB2-IDE/ATAPI Bridge Adapter + +usb:v04BBp0201* + ID_PRODUCT_FROM_DATABASE=USB2-IDE/ATAPI Bridge Adapter + +usb:v04BBp0204* + ID_PRODUCT_FROM_DATABASE=DVD Multi-plus unit iU-CD2 + +usb:v04BBp0206* + ID_PRODUCT_FROM_DATABASE=DVD Multi-plus unit DVR-UEH8 + +usb:v04BBp0301* + ID_PRODUCT_FROM_DATABASE=Storage Device + +usb:v04BBp0314* + ID_PRODUCT_FROM_DATABASE=USB-SSMRW SD-card + +usb:v04BBp0319* + ID_PRODUCT_FROM_DATABASE=USB2-IDE/ATAPI Bridge Adapter + +usb:v04BBp031A* + ID_PRODUCT_FROM_DATABASE=USB2-IDE/ATAPI Bridge Adapter + +usb:v04BBp031B* + ID_PRODUCT_FROM_DATABASE=USB2-IDE/ATAPI Bridge Adapter + +usb:v04BBp031E* + ID_PRODUCT_FROM_DATABASE=USB-SDRW SD-card + +usb:v04BBp0502* + ID_PRODUCT_FROM_DATABASE=Nogatech Live! (BT) + +usb:v04BBp0528* + ID_PRODUCT_FROM_DATABASE=GV-USB Video Capture + +usb:v04BBp0901* + ID_PRODUCT_FROM_DATABASE=USB ETT + +usb:v04BBp0904* + ID_PRODUCT_FROM_DATABASE=ET/TX Ethernet [pegasus] + +usb:v04BBp0913* + ID_PRODUCT_FROM_DATABASE=ET/TX-S Ethernet [pegasus2] + +usb:v04BBp0919* + ID_PRODUCT_FROM_DATABASE=USB WN-B11 + +usb:v04BBp0922* + ID_PRODUCT_FROM_DATABASE=IOData AirPort WN-B11/USBS 802.11b + +usb:v04BBp0930* + ID_PRODUCT_FROM_DATABASE=ETG-US2 + +usb:v04BBp0937* + ID_PRODUCT_FROM_DATABASE=WN-WAG/USL Wireless LAN Adapter + +usb:v04BBp0938* + ID_PRODUCT_FROM_DATABASE=WN-G54/USL Wireless LAN Adapter + +usb:v04BBp093B* + ID_PRODUCT_FROM_DATABASE=WN-GDN/USB + +usb:v04BBp093F* + ID_PRODUCT_FROM_DATABASE=WNGDNUS2 802.11n + +usb:v04BBp0944* + ID_PRODUCT_FROM_DATABASE=WHG-AGDN/US Wireless LAN Adapter + +usb:v04BBp0945* + ID_PRODUCT_FROM_DATABASE=WN-GDN/US3 Wireless LAN Adapter + +usb:v04BBp0947* + ID_PRODUCT_FROM_DATABASE=WN-G150U Wireless LAN Adapter + +usb:v04BBp0948* + ID_PRODUCT_FROM_DATABASE=WN-G300U Wireless LAN Adapter + +usb:v04BBp0A03* + ID_PRODUCT_FROM_DATABASE=Serial USB-RSAQ1 + +usb:v04BBp0A07* + ID_PRODUCT_FROM_DATABASE=USB2-iCN Adapter + +usb:v04BBp0A08* + ID_PRODUCT_FROM_DATABASE=USB2-iCN Adapter + +usb:v04BBp0C01* + ID_PRODUCT_FROM_DATABASE=FM-10 Pro Disk + +usb:v04BD* + ID_VENDOR_FROM_DATABASE=Toshiba Electronics Taiwan Corp. + +usb:v04BE* + ID_VENDOR_FROM_DATABASE=Telia Research AB + +usb:v04BF* + ID_VENDOR_FROM_DATABASE=TDK Corp. + +usb:v04BFp0100* + ID_PRODUCT_FROM_DATABASE=MediaReader CF + +usb:v04BFp0115* + ID_PRODUCT_FROM_DATABASE=USB-PDC Adapter UPA9664 + +usb:v04BFp0116* + ID_PRODUCT_FROM_DATABASE=USB-cdmaOne Adapter UCA1464 + +usb:v04BFp0117* + ID_PRODUCT_FROM_DATABASE=USB-PHS Adapter UHA6400 + +usb:v04BFp0118* + ID_PRODUCT_FROM_DATABASE=USB-PHS Adapter UPA6400 + +usb:v04BFp0135* + ID_PRODUCT_FROM_DATABASE=MediaReader Dual + +usb:v04BFp0202* + ID_PRODUCT_FROM_DATABASE=73S1121F Smart Card Reader- + +usb:v04BFp0309* + ID_PRODUCT_FROM_DATABASE=Bluetooth USB dongle + +usb:v04BFp030A* + ID_PRODUCT_FROM_DATABASE=IBM Bluetooth Ultraport Module + +usb:v04BFp030B* + ID_PRODUCT_FROM_DATABASE=Bluetooth Device + +usb:v04BFp030C* + ID_PRODUCT_FROM_DATABASE=Ultraport Bluetooth Device + +usb:v04BFp0310* + ID_PRODUCT_FROM_DATABASE=Integrated Bluetooth + +usb:v04BFp0311* + ID_PRODUCT_FROM_DATABASE=Integrated Bluetooth Device + +usb:v04BFp0317* + ID_PRODUCT_FROM_DATABASE=Bluetooth UltraPort Module from IBM + +usb:v04BFp0318* + ID_PRODUCT_FROM_DATABASE=IBM Integrated Bluetooth + +usb:v04BFp0319* + ID_PRODUCT_FROM_DATABASE=Bluetooth Adapter + +usb:v04BFp0320* + ID_PRODUCT_FROM_DATABASE=Bluetooth Adapter + +usb:v04BFp0321* + ID_PRODUCT_FROM_DATABASE=Bluetooth Device + +usb:v04BFp0A28* + ID_PRODUCT_FROM_DATABASE=INDI AV-IN Device + +usb:v04C1* + ID_VENDOR_FROM_DATABASE=U.S. Robotics (3Com) + +usb:v04C1p0020* + ID_PRODUCT_FROM_DATABASE=56K Voice Pro + +usb:v04C1p0022* + ID_PRODUCT_FROM_DATABASE=56K Voice Pro + +usb:v04C1p007E* + ID_PRODUCT_FROM_DATABASE=ISDN TA + +usb:v04C1p0082* + ID_PRODUCT_FROM_DATABASE=OfficeConnect Analog Modem + +usb:v04C1p008F* + ID_PRODUCT_FROM_DATABASE=Pro ISDN TA + +usb:v04C1p0097* + ID_PRODUCT_FROM_DATABASE=OfficeConnect Analog + +usb:v04C1p009D* + ID_PRODUCT_FROM_DATABASE=HomeConnect Webcam [vicam] + +usb:v04C1p00A9* + ID_PRODUCT_FROM_DATABASE=ISDN Pro TA-U + +usb:v04C1p00B9* + ID_PRODUCT_FROM_DATABASE=HomeConnect IDSL Modem + +usb:v04C1p3021* + ID_PRODUCT_FROM_DATABASE=56k Voice FaxModem Pro + +usb:v04C2* + ID_VENDOR_FROM_DATABASE=Methode Electronics Far East PTE, Ltd + +usb:v04C3* + ID_VENDOR_FROM_DATABASE=Maxi Switch, Inc. + +usb:v04C3p1102* + ID_PRODUCT_FROM_DATABASE=Mouse + +usb:v04C3p2102* + ID_PRODUCT_FROM_DATABASE=Mouse + +usb:v04C4* + ID_VENDOR_FROM_DATABASE=Lockheed Martin Energy Research + +usb:v04C5* + ID_VENDOR_FROM_DATABASE=Fujitsu, Ltd + +usb:v04C5p1029* + ID_PRODUCT_FROM_DATABASE=fi-4010c Scanner + +usb:v04C5p1033* + ID_PRODUCT_FROM_DATABASE=fi-4110CU + +usb:v04C5p1041* + ID_PRODUCT_FROM_DATABASE=fi-4120c Scanner + +usb:v04C5p1042* + ID_PRODUCT_FROM_DATABASE=fi-4220c Scanner + +usb:v04C5p105B* + ID_PRODUCT_FROM_DATABASE=AH-F401U Air H device + +usb:v04C5p1096* + ID_PRODUCT_FROM_DATABASE=fi-5110EOX + +usb:v04C5p1097* + ID_PRODUCT_FROM_DATABASE=fi-5110C + +usb:v04C5p10AE* + ID_PRODUCT_FROM_DATABASE=fi-4120C2 + +usb:v04C5p10AF* + ID_PRODUCT_FROM_DATABASE=fi-4220C2 + +usb:v04C5p10E0* + ID_PRODUCT_FROM_DATABASE=fi-5120c Scanner + +usb:v04C5p10E1* + ID_PRODUCT_FROM_DATABASE=fi-5220C + +usb:v04C5p10E7* + ID_PRODUCT_FROM_DATABASE=fi-5900C + +usb:v04C5p10FE* + ID_PRODUCT_FROM_DATABASE=S500 + +usb:v04C5p1150* + ID_PRODUCT_FROM_DATABASE=fi-6230 + +usb:v04C6* + ID_VENDOR_FROM_DATABASE=Toshiba America Electronic Components + +usb:v04C7* + ID_VENDOR_FROM_DATABASE=Micro Macro Technologies + +usb:v04C8* + ID_VENDOR_FROM_DATABASE=Konica Corp. + +usb:v04C8p0720* + ID_PRODUCT_FROM_DATABASE=Digital Color Camera + +usb:v04C8p0721* + ID_PRODUCT_FROM_DATABASE=e-miniD Camera + +usb:v04C8p0722* + ID_PRODUCT_FROM_DATABASE=e-mini + +usb:v04C8p0723* + ID_PRODUCT_FROM_DATABASE=KD-200Z Camera + +usb:v04C8p0726* + ID_PRODUCT_FROM_DATABASE=KD-310Z Camera + +usb:v04C8p0728* + ID_PRODUCT_FROM_DATABASE=Revio C2 Mass Storage Device + +usb:v04C8p0729* + ID_PRODUCT_FROM_DATABASE=Revio C2 Digital Camera + +usb:v04C8p072C* + ID_PRODUCT_FROM_DATABASE=Revio KD20M + +usb:v04C8p072D* + ID_PRODUCT_FROM_DATABASE=Revio KD410Z + +usb:v04CA* + ID_VENDOR_FROM_DATABASE=Lite-On Technology Corp. + +usb:v04CAp1766* + ID_PRODUCT_FROM_DATABASE=HID Monitor Controls + +usb:v04CAp9304* + ID_PRODUCT_FROM_DATABASE=Hub + +usb:v04CApF01C* + ID_PRODUCT_FROM_DATABASE=TT1280DA DVB-T TV Tuner + +usb:v04CB* + ID_VENDOR_FROM_DATABASE=Fuji Photo Film Co., Ltd + +usb:v04CBp0100* + ID_PRODUCT_FROM_DATABASE=FinePix 30i/40i/50i, A101/201, 1300/2200, 1400/2400/2600/2800/4500/4700/4800/4900/6800/6900 Zoom + +usb:v04CBp0103* + ID_PRODUCT_FROM_DATABASE=FinePix NX-500/NX-700 printer + +usb:v04CBp0104* + ID_PRODUCT_FROM_DATABASE=FinePix A101, 2600/2800/4800/6800 Zoom (PC CAM) + +usb:v04CBp0108* + ID_PRODUCT_FROM_DATABASE=FinePix F601 Zoom (DSC) + +usb:v04CBp0109* + ID_PRODUCT_FROM_DATABASE=FinePix F601 Zoom (PC CAM) + +usb:v04CBp010A* + ID_PRODUCT_FROM_DATABASE=FinePix S602 (Pro) Zoom (DSC) + +usb:v04CBp010B* + ID_PRODUCT_FROM_DATABASE=FinePix S602 (Pro) Zoom (PC CAM) + +usb:v04CBp010D* + ID_PRODUCT_FROM_DATABASE=FinePix Digital Camera 020531 + +usb:v04CBp010E* + ID_PRODUCT_FROM_DATABASE=FinePix F402 Zoom (DSC) + +usb:v04CBp010F* + ID_PRODUCT_FROM_DATABASE=FinePix F402 Zoom (PC CAM) + +usb:v04CBp0110* + ID_PRODUCT_FROM_DATABASE=FinePix M603 Zoom (DSC) + +usb:v04CBp0111* + ID_PRODUCT_FROM_DATABASE=FinePix M603 Zoom (PC CAM) + +usb:v04CBp0112* + ID_PRODUCT_FROM_DATABASE=FinePix A202, A200 Zoom (DSC) + +usb:v04CBp0113* + ID_PRODUCT_FROM_DATABASE=FinePix A202, A200 Zoom (PC CAM) + +usb:v04CBp0114* + ID_PRODUCT_FROM_DATABASE=FinePix F401 Zoom (DSC) + +usb:v04CBp0115* + ID_PRODUCT_FROM_DATABASE=FinePix F401 Zoom (PC CAM) + +usb:v04CBp0116* + ID_PRODUCT_FROM_DATABASE=FinePix A203 Zoom (DSC) + +usb:v04CBp0117* + ID_PRODUCT_FROM_DATABASE=FinePix A203 Zoom (PC CAM) + +usb:v04CBp0118* + ID_PRODUCT_FROM_DATABASE=FinePix A303 Zoom (DSC) + +usb:v04CBp0119* + ID_PRODUCT_FROM_DATABASE=FinePix A303 Zoom (PC CAM) + +usb:v04CBp011A* + ID_PRODUCT_FROM_DATABASE=FinePix S304/3800 Zoom (DSC) + +usb:v04CBp011B* + ID_PRODUCT_FROM_DATABASE=FinePix S304/3800 Zoom (PC CAM) + +usb:v04CBp011C* + ID_PRODUCT_FROM_DATABASE=FinePix A204/2650 Zoom (DSC) + +usb:v04CBp011D* + ID_PRODUCT_FROM_DATABASE=FinePix A204/2650 Zoom (PC CAM) + +usb:v04CBp0120* + ID_PRODUCT_FROM_DATABASE=FinePix F700 Zoom (DSC) + +usb:v04CBp0121* + ID_PRODUCT_FROM_DATABASE=FinePix F700 Zoom (PC CAM) + +usb:v04CBp0122* + ID_PRODUCT_FROM_DATABASE=FinePix F410 Zoom (DSC) + +usb:v04CBp0123* + ID_PRODUCT_FROM_DATABASE=FinePix F410 Zoom (PC CAM) + +usb:v04CBp0124* + ID_PRODUCT_FROM_DATABASE=FinePix A310 Zoom (DSC) + +usb:v04CBp0125* + ID_PRODUCT_FROM_DATABASE=FinePix A310 Zoom (PC CAM) + +usb:v04CBp0126* + ID_PRODUCT_FROM_DATABASE=FinePix A210 Zoom (DSC) + +usb:v04CBp0127* + ID_PRODUCT_FROM_DATABASE=FinePix A210 Zoom (PC CAM) + +usb:v04CBp0128* + ID_PRODUCT_FROM_DATABASE=FinePix A205(S) Zoom (DSC) + +usb:v04CBp0129* + ID_PRODUCT_FROM_DATABASE=FinePix A205(S) Zoom (PC CAM) + +usb:v04CBp012A* + ID_PRODUCT_FROM_DATABASE=FinePix F610 Zoom (DSC) + +usb:v04CBp012B* + ID_PRODUCT_FROM_DATABASE=FinePix Digital Camera 030513 + +usb:v04CBp012C* + ID_PRODUCT_FROM_DATABASE=FinePix S7000 Zoom (DSC) + +usb:v04CBp012D* + ID_PRODUCT_FROM_DATABASE=FinePix S7000 Zoom (PC CAM) + +usb:v04CBp012F* + ID_PRODUCT_FROM_DATABASE=FinePix Digital Camera 030731 + +usb:v04CBp0130* + ID_PRODUCT_FROM_DATABASE=FinePix S5000 Zoom (DSC) + +usb:v04CBp0131* + ID_PRODUCT_FROM_DATABASE=FinePix S5000 Zoom (PC CAM) + +usb:v04CBp013B* + ID_PRODUCT_FROM_DATABASE=FinePix Digital Camera 030722 + +usb:v04CBp013C* + ID_PRODUCT_FROM_DATABASE=FinePix S3000 Zoom (DSC) + +usb:v04CBp013D* + ID_PRODUCT_FROM_DATABASE=FinePix S3000 Zoom (PC CAM) + +usb:v04CBp013E* + ID_PRODUCT_FROM_DATABASE=FinePix F420 Zoom (DSC) + +usb:v04CBp013F* + ID_PRODUCT_FROM_DATABASE=FinePix F420 Zoom (PC CAM) + +usb:v04CBp0142* + ID_PRODUCT_FROM_DATABASE=FinePix S7000 Zoom (PTP) + +usb:v04CBp0148* + ID_PRODUCT_FROM_DATABASE=FinePix A330 Zoom (DSC) + +usb:v04CBp0149* + ID_PRODUCT_FROM_DATABASE=FinePix A330 Zoom (UVC) + +usb:v04CBp014A* + ID_PRODUCT_FROM_DATABASE=FinePix A330 Zoom (PTP) + +usb:v04CBp014B* + ID_PRODUCT_FROM_DATABASE=FinePix A340 Zoom (DSC) + +usb:v04CBp014C* + ID_PRODUCT_FROM_DATABASE=FinePix A340 Zoom (UVC) + +usb:v04CBp0159* + ID_PRODUCT_FROM_DATABASE=FinePix F710 Zoom (DSC) + +usb:v04CBp0165* + ID_PRODUCT_FROM_DATABASE=FinePix S3500 Zoom (DSC) + +usb:v04CBp0168* + ID_PRODUCT_FROM_DATABASE=FinePix E500 Zoom (DSC) + +usb:v04CBp0169* + ID_PRODUCT_FROM_DATABASE=FinePix E500 Zoom (UVC) + +usb:v04CBp016B* + ID_PRODUCT_FROM_DATABASE=FinePix E510 Zoom (DSC) + +usb:v04CBp016C* + ID_PRODUCT_FROM_DATABASE=FinePix E510 Zoom (PC CAM) + +usb:v04CBp016E* + ID_PRODUCT_FROM_DATABASE=FinePix S5500 Zoom (DSC) + +usb:v04CBp016F* + ID_PRODUCT_FROM_DATABASE=FinePix S5500 Zoom (UVC) + +usb:v04CBp0171* + ID_PRODUCT_FROM_DATABASE=FinePix E550 Zoom (DSC) + +usb:v04CBp0172* + ID_PRODUCT_FROM_DATABASE=FinePix E550 Zoom (UVC) + +usb:v04CBp0177* + ID_PRODUCT_FROM_DATABASE=FinePix F10 (DSC) + +usb:v04CBp0179* + ID_PRODUCT_FROM_DATABASE=Finepix F10 (PTP) + +usb:v04CBp0186* + ID_PRODUCT_FROM_DATABASE=FinePix S5200/S5600 Zoom (DSC) + +usb:v04CBp0188* + ID_PRODUCT_FROM_DATABASE=FinePix S5200/S5600 Zoom (PTP) + +usb:v04CBp018E* + ID_PRODUCT_FROM_DATABASE=FinePix S9500 Zoom (DSC) + +usb:v04CBp018F* + ID_PRODUCT_FROM_DATABASE=FinePix S9500 Zoom (PTP) + +usb:v04CBp0192* + ID_PRODUCT_FROM_DATABASE=FinePix E900 Zoom (DSC) + +usb:v04CBp0193* + ID_PRODUCT_FROM_DATABASE=FinePix E900 Zoom (PTP) + +usb:v04CBp019B* + ID_PRODUCT_FROM_DATABASE=FinePix F30 (PTP) + +usb:v04CBp01AF* + ID_PRODUCT_FROM_DATABASE=FinePix A700 (PTP) + +usb:v04CBp01BF* + ID_PRODUCT_FROM_DATABASE=FinePix F6000fd/S6500fd Zoom (PTP) + +usb:v04CBp01C0* + ID_PRODUCT_FROM_DATABASE=FinePix F20 (PTP) + +usb:v04CBp01C1* + ID_PRODUCT_FROM_DATABASE=FinePix F31fd (PTP) + +usb:v04CBp01C4* + ID_PRODUCT_FROM_DATABASE=FinePix S5700 Zoom (PTP) + +usb:v04CBp01C5* + ID_PRODUCT_FROM_DATABASE=FinePix F40fd (PTP) + +usb:v04CBp01C6* + ID_PRODUCT_FROM_DATABASE=FinePix A820 Zoom (PTP) + +usb:v04CBp01D2* + ID_PRODUCT_FROM_DATABASE=FinePix A800 Zoom (PTP) + +usb:v04CBp01D3* + ID_PRODUCT_FROM_DATABASE=FinePix A920 (PTP) + +usb:v04CBp01D4* + ID_PRODUCT_FROM_DATABASE=FinePix F50fd (PTP) + +usb:v04CBp01D5* + ID_PRODUCT_FROM_DATABASE=FinePix F47 (PTP) + +usb:v04CBp01F7* + ID_PRODUCT_FROM_DATABASE=FinePix J250 (PTP) + +usb:v04CBp01FD* + ID_PRODUCT_FROM_DATABASE=A160 + +usb:v04CBp023E* + ID_PRODUCT_FROM_DATABASE=FinePix AX300 + +usb:v04CBp0240* + ID_PRODUCT_FROM_DATABASE=FinePix S2950 Digital Camera + +usb:v04CBp0241* + ID_PRODUCT_FROM_DATABASE=FinePix S3200 Digital Camera + +usb:v04CC* + ID_VENDOR_FROM_DATABASE=ST-Ericsson + +usb:v04CCp1122* + ID_PRODUCT_FROM_DATABASE=Hub + +usb:v04CCp1520* + ID_PRODUCT_FROM_DATABASE=USB 2.0 Hub (Avocent KVM) + +usb:v04CCp1521* + ID_PRODUCT_FROM_DATABASE=USB 2.0 Hub + +usb:v04CCp1A62* + ID_PRODUCT_FROM_DATABASE=GW Instek GSP-830 Spectrum Analyzer (HID) + +usb:v04CCp2323* + ID_PRODUCT_FROM_DATABASE=Ux500 serial debug port + +usb:v04CCp2533* + ID_PRODUCT_FROM_DATABASE=NFC device (PN533) + +usb:v04CCp8116* + ID_PRODUCT_FROM_DATABASE=Camera + +usb:v04CD* + ID_VENDOR_FROM_DATABASE=Tatung Co. Of America + +usb:v04CE* + ID_VENDOR_FROM_DATABASE=ScanLogic Corp. + +usb:v04CEp0002* + ID_PRODUCT_FROM_DATABASE=SL11R-IDE IDE Bridge + +usb:v04CEp0100* + ID_PRODUCT_FROM_DATABASE=USB2PRN Printer Class + +usb:v04CEp0300* + ID_PRODUCT_FROM_DATABASE=Phantom 336CX - C3 scanner + +usb:v04CEp04CE* + ID_PRODUCT_FROM_DATABASE=SL11DEMO, VID: 0x4ce, PID: 0x4ce + +usb:v04CEp07D1* + ID_PRODUCT_FROM_DATABASE=SL11R, VID: 0x4ce, PID: 0x07D1 + +usb:v04CF* + ID_VENDOR_FROM_DATABASE=Myson Century, Inc. + +usb:v04CFp0022* + ID_PRODUCT_FROM_DATABASE=OCZ Alchemy Series Elixir II Keyboard + +usb:v04CFp0800* + ID_PRODUCT_FROM_DATABASE=MTP800 Mass Storage Device + +usb:v04CFp8810* + ID_PRODUCT_FROM_DATABASE=CS8810 Mass Storage Device + +usb:v04CFp8811* + ID_PRODUCT_FROM_DATABASE=CS8811 Mass Storage Device + +usb:v04CFp8813* + ID_PRODUCT_FROM_DATABASE=CS8813 Mass Storage Device + +usb:v04CFp8818* + ID_PRODUCT_FROM_DATABASE=USB2.0 to ATAPI Bridge Controller + +usb:v04CFp8819* + ID_PRODUCT_FROM_DATABASE=USB 2.0 SD/MMC Reader + +usb:v04CFp9920* + ID_PRODUCT_FROM_DATABASE=CS8819A2-114 Mass Storage Device + +usb:v04D0* + ID_VENDOR_FROM_DATABASE=Digi International + +usb:v04D1* + ID_VENDOR_FROM_DATABASE=ITT Canon + +usb:v04D2* + ID_VENDOR_FROM_DATABASE=Altec Lansing Technologies + +usb:v04D2p0070* + ID_PRODUCT_FROM_DATABASE=ADA70 Speakers + +usb:v04D2p0305* + ID_PRODUCT_FROM_DATABASE=Non-Compliant Audio Device + +usb:v04D2p0311* + ID_PRODUCT_FROM_DATABASE=ADA-310 Speakers + +usb:v04D2p2060* + ID_PRODUCT_FROM_DATABASE=Claritel-i750 - vp + +usb:v04D2pFF05* + ID_PRODUCT_FROM_DATABASE=ADA-305 Speakers + +usb:v04D2pFF47* + ID_PRODUCT_FROM_DATABASE=Lansing HID Audio Controls + +usb:v04D2pFF49* + ID_PRODUCT_FROM_DATABASE=Lansing HID Audio Controls + +usb:v04D3* + ID_VENDOR_FROM_DATABASE=VidUS, Inc. + +usb:v04D4* + ID_VENDOR_FROM_DATABASE=LSI Logic, Inc. + +usb:v04D5* + ID_VENDOR_FROM_DATABASE=Forte Technologies, Inc. + +usb:v04D6* + ID_VENDOR_FROM_DATABASE=Mentor Graphics + +usb:v04D7* + ID_VENDOR_FROM_DATABASE=Oki Semiconductor + +usb:v04D7p1BE4* + ID_PRODUCT_FROM_DATABASE=Bluetooth Device + +usb:v04D8* + ID_VENDOR_FROM_DATABASE=Microchip Technology, Inc. + +usb:v04D8p0002* + ID_PRODUCT_FROM_DATABASE=PicoLCD 20x2 + +usb:v04D8p0003* + ID_PRODUCT_FROM_DATABASE=PICkit 2 Microcontroller Programmer + +usb:v04D8p000A* + ID_PRODUCT_FROM_DATABASE=CDC RS-232 Emulation Demo + +usb:v04D8p000B* + ID_PRODUCT_FROM_DATABASE=PIC18F2550 (32K Flashable 10 Channel, 10 Bit A/D USB Microcontroller) + +usb:v04D8p0032* + ID_PRODUCT_FROM_DATABASE=PICkit1 + +usb:v04D8p0033* + ID_PRODUCT_FROM_DATABASE=PICkit2 + +usb:v04D8p0036* + ID_PRODUCT_FROM_DATABASE=PICkit Serial Analyzer + +usb:v04D8p00E0* + ID_PRODUCT_FROM_DATABASE=PIC32 Starter Board + +usb:v04D8p0A04* + ID_PRODUCT_FROM_DATABASE=AGP LIN Serial Analyzer + +usb:v04D8p8000* + ID_PRODUCT_FROM_DATABASE=In-Circuit Debugger + +usb:v04D8p8001* + ID_PRODUCT_FROM_DATABASE=ICD2 in-circuit debugger + +usb:v04D8p8101* + ID_PRODUCT_FROM_DATABASE=PIC24F Starter Kit + +usb:v04D8p8107* + ID_PRODUCT_FROM_DATABASE=Microstick II + +usb:v04D8p900A* + ID_PRODUCT_FROM_DATABASE=PICkit3 + +usb:v04D8pC001* + ID_PRODUCT_FROM_DATABASE=PicoLCD 20x4 + +usb:v04D8pF8DA* + ID_PRODUCT_FROM_DATABASE=Hughski Ltd. ColorHug + +usb:v04D8pFBBA* + ID_PRODUCT_FROM_DATABASE=DiscFerret Magnetic Disc Analyser (bootloader mode) + +usb:v04D8pFBBB* + ID_PRODUCT_FROM_DATABASE=DiscFerret Magnetic Disc Analyser (active mode) + +usb:v04D8pFC92* + ID_PRODUCT_FROM_DATABASE=Open Bench Logic Sniffer + +usb:v04D8pFFEF* + ID_PRODUCT_FROM_DATABASE=PICoPLC [APStech] + +usb:v04D9* + ID_VENDOR_FROM_DATABASE=Holtek Semiconductor, Inc. + +usb:v04D9p0022* + ID_PRODUCT_FROM_DATABASE=Portable Keyboard + +usb:v04D9p048E* + ID_PRODUCT_FROM_DATABASE=Optical Mouse + +usb:v04D9p0499* + ID_PRODUCT_FROM_DATABASE=Optical Mouse + +usb:v04D9p1203* + ID_PRODUCT_FROM_DATABASE=Keyboard + +usb:v04D9p1400* + ID_PRODUCT_FROM_DATABASE=PS/2 keyboard + mouse controller + +usb:v04D9p1503* + ID_PRODUCT_FROM_DATABASE=Shortboard Lefty + +usb:v04D9p1603* + ID_PRODUCT_FROM_DATABASE=Keyboard + +usb:v04D9p2013* + ID_PRODUCT_FROM_DATABASE=Keyboard [Das Keyboard] + +usb:v04D9p2221* + ID_PRODUCT_FROM_DATABASE=Keyboard + +usb:v04D9pA055* + ID_PRODUCT_FROM_DATABASE=Keyboard + +usb:v04DA* + ID_VENDOR_FROM_DATABASE=Panasonic (Matsushita) + +usb:v04DAp0901* + ID_PRODUCT_FROM_DATABASE=LS-120 Camera + +usb:v04DAp0912* + ID_PRODUCT_FROM_DATABASE=SDR-S10 + +usb:v04DAp0B01* + ID_PRODUCT_FROM_DATABASE=CD-R/RW Drive + +usb:v04DAp0B03* + ID_PRODUCT_FROM_DATABASE=SuperDisk 240MB + +usb:v04DAp0D01* + ID_PRODUCT_FROM_DATABASE=CD-R Drive KXL-840AN + +usb:v04DAp0D09* + ID_PRODUCT_FROM_DATABASE=CD-R Drive KXL-RW32AN + +usb:v04DAp0D0A* + ID_PRODUCT_FROM_DATABASE=CD-R Drive KXL-CB20AN + +usb:v04DAp0D0D* + ID_PRODUCT_FROM_DATABASE=CDRCB03 + +usb:v04DAp0D0E* + ID_PRODUCT_FROM_DATABASE=DVD-ROM & CD-R/RW + +usb:v04DAp0F40* + ID_PRODUCT_FROM_DATABASE=Printer + +usb:v04DAp104D* + ID_PRODUCT_FROM_DATABASE=Elite Panaboard UB-T880 (HID) + +usb:v04DAp104E* + ID_PRODUCT_FROM_DATABASE=Elite Panaboard Pen Adaptor (HID) + +usb:v04DAp1500* + ID_PRODUCT_FROM_DATABASE=MFSUSB Driver + +usb:v04DAp1800* + ID_PRODUCT_FROM_DATABASE=DY-WL10 802.11abgn Adapter [Broadcom BCM4323] + +usb:v04DAp1B00* + ID_PRODUCT_FROM_DATABASE=MultiMediaCard + +usb:v04DAp2121* + ID_PRODUCT_FROM_DATABASE=EB-VS6 + +usb:v04DAp2316* + ID_PRODUCT_FROM_DATABASE=DVC Mass Storage Device + +usb:v04DAp2317* + ID_PRODUCT_FROM_DATABASE=DVC USB-SERIAL Driver for WinXP + +usb:v04DAp2318* + ID_PRODUCT_FROM_DATABASE=NV-GS11/230/250 (webcam mode) + +usb:v04DAp2319* + ID_PRODUCT_FROM_DATABASE=NV-GS15 (webcam mode) + +usb:v04DAp231A* + ID_PRODUCT_FROM_DATABASE=NV-GS11/230/250 (DV mode) + +usb:v04DAp231D* + ID_PRODUCT_FROM_DATABASE=DVC Web Camera Device + +usb:v04DAp231E* + ID_PRODUCT_FROM_DATABASE=DVC DV Stream Device + +usb:v04DAp2372* + ID_PRODUCT_FROM_DATABASE=Lumix Camera + +usb:v04DAp2374* + ID_PRODUCT_FROM_DATABASE=DMC-FZ18/FZ20 + +usb:v04DAp2451* + ID_PRODUCT_FROM_DATABASE=HDC-SD9 + +usb:v04DAp2497* + ID_PRODUCT_FROM_DATABASE=HDC-TM700 + +usb:v04DAp250C* + ID_PRODUCT_FROM_DATABASE=Gobi Wireless Modem (QDL mode) + +usb:v04DAp250D* + ID_PRODUCT_FROM_DATABASE=Gobi Wireless Modem + +usb:v04DAp3904* + ID_PRODUCT_FROM_DATABASE=N5HBZ0000055 802.11abgn Wireless Adapter [Atheros AR7010+AR9280] + +usb:v04DAp3C04* + ID_PRODUCT_FROM_DATABASE=JT-P100MR-20 [ePassport Reader] + +usb:v04DB* + ID_VENDOR_FROM_DATABASE=Hypertec Pty, Ltd + +usb:v04DC* + ID_VENDOR_FROM_DATABASE=Huan Hsin Holdings, Ltd + +usb:v04DD* + ID_VENDOR_FROM_DATABASE=Sharp Corp. + +usb:v04DDp13A6* + ID_PRODUCT_FROM_DATABASE=MFC2000 + +usb:v04DDp6006* + ID_PRODUCT_FROM_DATABASE=AL-1216 + +usb:v04DDp6007* + ID_PRODUCT_FROM_DATABASE=AL-1045 + +usb:v04DDp6008* + ID_PRODUCT_FROM_DATABASE=AL-1255 + +usb:v04DDp6009* + ID_PRODUCT_FROM_DATABASE=AL-1530CS + +usb:v04DDp600A* + ID_PRODUCT_FROM_DATABASE=AL-1540CS + +usb:v04DDp600B* + ID_PRODUCT_FROM_DATABASE=AL-1456 + +usb:v04DDp600C* + ID_PRODUCT_FROM_DATABASE=AL-1555 + +usb:v04DDp600D* + ID_PRODUCT_FROM_DATABASE=AL-1225 + +usb:v04DDp600E* + ID_PRODUCT_FROM_DATABASE=AL-1551CS + +usb:v04DDp600F* + ID_PRODUCT_FROM_DATABASE=AR-122E + +usb:v04DDp6010* + ID_PRODUCT_FROM_DATABASE=AR-152E + +usb:v04DDp6011* + ID_PRODUCT_FROM_DATABASE=AR-157E + +usb:v04DDp6012* + ID_PRODUCT_FROM_DATABASE=SN-1045 + +usb:v04DDp6013* + ID_PRODUCT_FROM_DATABASE=SN-1255 + +usb:v04DDp6014* + ID_PRODUCT_FROM_DATABASE=SN-1456 + +usb:v04DDp6015* + ID_PRODUCT_FROM_DATABASE=SN-1555 + +usb:v04DDp6016* + ID_PRODUCT_FROM_DATABASE=AR-153E + +usb:v04DDp6017* + ID_PRODUCT_FROM_DATABASE=AR-122E N + +usb:v04DDp6018* + ID_PRODUCT_FROM_DATABASE=AR-153E N + +usb:v04DDp6019* + ID_PRODUCT_FROM_DATABASE=AR-152E N + +usb:v04DDp601A* + ID_PRODUCT_FROM_DATABASE=AR-157E N + +usb:v04DDp601B* + ID_PRODUCT_FROM_DATABASE=AL-1217 + +usb:v04DDp601C* + ID_PRODUCT_FROM_DATABASE=AL-1226 + +usb:v04DDp601D* + ID_PRODUCT_FROM_DATABASE=AR-123E + +usb:v04DDp6021* + ID_PRODUCT_FROM_DATABASE=IS01 + +usb:v04DDp7002* + ID_PRODUCT_FROM_DATABASE=DVC Ver.1.0 + +usb:v04DDp7004* + ID_PRODUCT_FROM_DATABASE=VE-CG40U Digital Still Camera + +usb:v04DDp7005* + ID_PRODUCT_FROM_DATABASE=VE-CG30 Digital Still Camera + +usb:v04DDp7007* + ID_PRODUCT_FROM_DATABASE=VL-Z7S Digital Camcorder + +usb:v04DDp8004* + ID_PRODUCT_FROM_DATABASE=Zaurus SL-5000D/SL-5500 PDA + +usb:v04DDp8005* + ID_PRODUCT_FROM_DATABASE=Zaurus A-300 + +usb:v04DDp8006* + ID_PRODUCT_FROM_DATABASE=Zaurus SL-B500/SL-5600 PDA + +usb:v04DDp8007* + ID_PRODUCT_FROM_DATABASE=Zaurus C-700 PDA + +usb:v04DDp9009* + ID_PRODUCT_FROM_DATABASE=AR-M160 + +usb:v04DDp9014* + ID_PRODUCT_FROM_DATABASE=IM-DR80 Portable NetMD Player + +usb:v04DDp9031* + ID_PRODUCT_FROM_DATABASE=Zaurus C-750/C-760/C-860/SL-C3000 PDA + +usb:v04DDp9032* + ID_PRODUCT_FROM_DATABASE=Zaurus SL-6000 + +usb:v04DDp903A* + ID_PRODUCT_FROM_DATABASE=GSM GPRS + +usb:v04DDp9050* + ID_PRODUCT_FROM_DATABASE=Zaurus C-860 PDA + +usb:v04DDp9056* + ID_PRODUCT_FROM_DATABASE=Viewcam Z + +usb:v04DDp9073* + ID_PRODUCT_FROM_DATABASE=AM-900 + +usb:v04DDp9074* + ID_PRODUCT_FROM_DATABASE=GSM GPRS + +usb:v04DDp90A9* + ID_PRODUCT_FROM_DATABASE=Sharp Composite + +usb:v04DDp90D0* + ID_PRODUCT_FROM_DATABASE=USB-to-Serial Comm. Port + +usb:v04DDp90F2* + ID_PRODUCT_FROM_DATABASE=Sharp 3G GSM USB Control + +usb:v04DDp9120* + ID_PRODUCT_FROM_DATABASE=WS004SH + +usb:v04DDp9122* + ID_PRODUCT_FROM_DATABASE=WS007SH + +usb:v04DDp9123* + ID_PRODUCT_FROM_DATABASE=W-ZERO3 ES Smartphone + +usb:v04DDp91A3* + ID_PRODUCT_FROM_DATABASE=922SH Internet Machine + +usb:v04DDp939A* + ID_PRODUCT_FROM_DATABASE=IS03 + +usb:v04DE* + ID_VENDOR_FROM_DATABASE=MindShare, Inc. + +usb:v04DF* + ID_VENDOR_FROM_DATABASE=Interlink Electronics + +usb:v04E1* + ID_VENDOR_FROM_DATABASE=Iiyama North America, Inc. + +usb:v04E1p0201* + ID_PRODUCT_FROM_DATABASE=Monitor Hub + +usb:v04E2* + ID_VENDOR_FROM_DATABASE=Exar Corp. + +usb:v04E3* + ID_VENDOR_FROM_DATABASE=Zilog, Inc. + +usb:v04E4* + ID_VENDOR_FROM_DATABASE=ACC Microelectronics + +usb:v04E5* + ID_VENDOR_FROM_DATABASE=Promise Technology + +usb:v04E6* + ID_VENDOR_FROM_DATABASE=SCM Microsystems, Inc. + +usb:v04E6p0001* + ID_PRODUCT_FROM_DATABASE=E-USB ATA Bridge + +usb:v04E6p0002* + ID_PRODUCT_FROM_DATABASE=eUSCSI SCSI Bridge + +usb:v04E6p0003* + ID_PRODUCT_FROM_DATABASE=eUSB SmartMedia Card Reader + +usb:v04E6p0005* + ID_PRODUCT_FROM_DATABASE=eUSB SmartMedia/CompactFlash Card Reader + +usb:v04E6p0006* + ID_PRODUCT_FROM_DATABASE=eUSB SmartMedia Card Reader + +usb:v04E6p0007* + ID_PRODUCT_FROM_DATABASE=Hifd + +usb:v04E6p0009* + ID_PRODUCT_FROM_DATABASE=eUSB ATA/ATAPI Adapter + +usb:v04E6p000A* + ID_PRODUCT_FROM_DATABASE=eUSB CompactFlash Adapter + +usb:v04E6p000B* + ID_PRODUCT_FROM_DATABASE=eUSCSI Bridge + +usb:v04E6p000C* + ID_PRODUCT_FROM_DATABASE=eUSCSI Bridge + +usb:v04E6p000D* + ID_PRODUCT_FROM_DATABASE=Dazzle MS + +usb:v04E6p0012* + ID_PRODUCT_FROM_DATABASE=Dazzle SD/MMC + +usb:v04E6p0101* + ID_PRODUCT_FROM_DATABASE=eUSB ATA Bridge (Sony Spressa USB CDRW) + +usb:v04E6p0311* + ID_PRODUCT_FROM_DATABASE=Dazzle DM-CF + +usb:v04E6p0312* + ID_PRODUCT_FROM_DATABASE=Dazzle DM-SD/MMC + +usb:v04E6p0313* + ID_PRODUCT_FROM_DATABASE=Dazzle SM + +usb:v04E6p0314* + ID_PRODUCT_FROM_DATABASE=Dazzle MS + +usb:v04E6p0322* + ID_PRODUCT_FROM_DATABASE=e-Film Reader-5 + +usb:v04E6p0325* + ID_PRODUCT_FROM_DATABASE=eUSB ORCA Quad Reader + +usb:v04E6p0327* + ID_PRODUCT_FROM_DATABASE=Digital Media Reader + +usb:v04E6p03FE* + ID_PRODUCT_FROM_DATABASE=DMHS2 DFU Adapter + +usb:v04E6p0406* + ID_PRODUCT_FROM_DATABASE=eUSB SmartDM Reader + +usb:v04E6p04E6* + ID_PRODUCT_FROM_DATABASE=eUSB DFU Adapter + +usb:v04E6p04E7* + ID_PRODUCT_FROM_DATABASE=STCII DFU Adapter + +usb:v04E6p04E8* + ID_PRODUCT_FROM_DATABASE=eUSBDM DFU Adapter + +usb:v04E6p04E9* + ID_PRODUCT_FROM_DATABASE=DM-E DFU Adapter + +usb:v04E6p0500* + ID_PRODUCT_FROM_DATABASE=Veridicom 5thSense Fingerprint Sensor and eUSB SmartCard + +usb:v04E6p0701* + ID_PRODUCT_FROM_DATABASE=DCS200 Loader Device + +usb:v04E6p0702* + ID_PRODUCT_FROM_DATABASE=DVD Creation Station 200 + +usb:v04E6p0703* + ID_PRODUCT_FROM_DATABASE=DVC100 Loader Device + +usb:v04E6p0704* + ID_PRODUCT_FROM_DATABASE=Digital Video Creator 100 + +usb:v04E6p1001* + ID_PRODUCT_FROM_DATABASE=SCR300 Smart Card Reader + +usb:v04E6p1010* + ID_PRODUCT_FROM_DATABASE=USBAT-2 CompactFlash Card Reader + +usb:v04E6p1014* + ID_PRODUCT_FROM_DATABASE=e-Film Reader-3 + +usb:v04E6p1020* + ID_PRODUCT_FROM_DATABASE=USBAT ATA/ATAPI Adapter + +usb:v04E6p2007* + ID_PRODUCT_FROM_DATABASE=RSA SecurID ComboReader + +usb:v04E6p2009* + ID_PRODUCT_FROM_DATABASE=Citibank Smart Card Reader + +usb:v04E6p200A* + ID_PRODUCT_FROM_DATABASE=Reflex v.2 Smart Card Reader + +usb:v04E6p200D* + ID_PRODUCT_FROM_DATABASE=STR391 Reader + +usb:v04E6p5111* + ID_PRODUCT_FROM_DATABASE=SCR331-DI SmartCard Reader + +usb:v04E6p5113* + ID_PRODUCT_FROM_DATABASE=SCR333 SmartCard Reader + +usb:v04E6p5114* + ID_PRODUCT_FROM_DATABASE=SCR331-DI SmartCard Reader + +usb:v04E6p5115* + ID_PRODUCT_FROM_DATABASE=SCR335 SmartCard Reader + +usb:v04E6p5116* + ID_PRODUCT_FROM_DATABASE=SCR331-LC1 / SCR3310 SmartCard Reader + +usb:v04E6p5117* + ID_PRODUCT_FROM_DATABASE=SCR3320 - Smart Card Reader + +usb:v04E6p5118* + ID_PRODUCT_FROM_DATABASE=Expresscard SIM Card Reader + +usb:v04E6p5119* + ID_PRODUCT_FROM_DATABASE=SCR3340 - ExpressCard54 Smart Card Reader + +usb:v04E6p511B* + ID_PRODUCT_FROM_DATABASE=SmartCard Reader + +usb:v04E6p511D* + ID_PRODUCT_FROM_DATABASE=SCR3311 Smart Card Reader + +usb:v04E6p5120* + ID_PRODUCT_FROM_DATABASE=SCR331-DI SmartCard Reader + +usb:v04E6p5121* + ID_PRODUCT_FROM_DATABASE=SDI010 Smart Card Reader + +usb:v04E6p5151* + ID_PRODUCT_FROM_DATABASE=SCR338 Keyboard Smart Card Reader + +usb:v04E6p5292* + ID_PRODUCT_FROM_DATABASE=SCL011 RFID reader + +usb:v04E6p5410* + ID_PRODUCT_FROM_DATABASE=SCR35xx Smart Card Reader + +usb:v04E6pE000* + ID_PRODUCT_FROM_DATABASE=SCRx31 Reader + +usb:v04E6pE001* + ID_PRODUCT_FROM_DATABASE=SCR331 SmartCard Reader + +usb:v04E6pE003* + ID_PRODUCT_FROM_DATABASE=SPR532 PinPad SmartCard Reader + +usb:v04E7* + ID_VENDOR_FROM_DATABASE=Elo TouchSystems + +usb:v04E7p0001* + ID_PRODUCT_FROM_DATABASE=TouchScreen + +usb:v04E7p0002* + ID_PRODUCT_FROM_DATABASE=Touchmonitor Interface 2600 Rev 2 + +usb:v04E7p0004* + ID_PRODUCT_FROM_DATABASE=4000U CarrollTouch® Touchmonitor Interface + +usb:v04E7p0007* + ID_PRODUCT_FROM_DATABASE=2500U IntelliTouch® Touchmonitor Interface + +usb:v04E7p0008* + ID_PRODUCT_FROM_DATABASE=3000U AccuTouch® Touchmonitor Interface + +usb:v04E7p0009* + ID_PRODUCT_FROM_DATABASE=4000U CarrollTouch® Touchmonitor Interface + +usb:v04E7p0020* + ID_PRODUCT_FROM_DATABASE=Touchscreen Interface (2700) + +usb:v04E7p0021* + ID_PRODUCT_FROM_DATABASE=Touchmonitor Interface + +usb:v04E7p0030* + ID_PRODUCT_FROM_DATABASE=4500U CarrollTouch® Touchmonitor Interface + +usb:v04E7p0032* + ID_PRODUCT_FROM_DATABASE=Touchmonitor Interface + +usb:v04E7p0033* + ID_PRODUCT_FROM_DATABASE=Touchmonitor Interface + +usb:v04E7p0041* + ID_PRODUCT_FROM_DATABASE=5010 Surface Capacitive Touchmonitor Interface + +usb:v04E7p0042* + ID_PRODUCT_FROM_DATABASE=Touchmonitor Interface + +usb:v04E7p0050* + ID_PRODUCT_FROM_DATABASE=2216 AccuTouch® Touchmonitor Interface + +usb:v04E7p0071* + ID_PRODUCT_FROM_DATABASE=Touchmonitor Interface + +usb:v04E7p0072* + ID_PRODUCT_FROM_DATABASE=Touchmonitor Interface + +usb:v04E7p0081* + ID_PRODUCT_FROM_DATABASE=Touchmonitor Interface + +usb:v04E7p0082* + ID_PRODUCT_FROM_DATABASE=Touchmonitor Interface + +usb:v04E7p00FF* + ID_PRODUCT_FROM_DATABASE=Touchmonitor Interface + +usb:v04E8* + ID_VENDOR_FROM_DATABASE=Samsung Electronics Co., Ltd + +usb:v04E8p0100* + ID_PRODUCT_FROM_DATABASE=Kingston Flash Drive (128MB) + +usb:v04E8p0110* + ID_PRODUCT_FROM_DATABASE=Connect3D Flash Drive + +usb:v04E8p0111* + ID_PRODUCT_FROM_DATABASE=Connect3D Flash Drive + +usb:v04E8p1003* + ID_PRODUCT_FROM_DATABASE=MP3 Player and Recorder + +usb:v04E8p1006* + ID_PRODUCT_FROM_DATABASE=SDC-200Z + +usb:v04E8p130C* + ID_PRODUCT_FROM_DATABASE=NX100 + +usb:v04E8p1F06* + ID_PRODUCT_FROM_DATABASE=HX-MU064DA portable harddisk + +usb:v04E8p2018* + ID_PRODUCT_FROM_DATABASE=WIS09ABGN LinkStick Wireless LAN Adapter + +usb:v04E8p2035* + ID_PRODUCT_FROM_DATABASE=Digital Photo Frame Mass Storage + +usb:v04E8p2036* + ID_PRODUCT_FROM_DATABASE=Digital Photo Frame Mini Monitor + +usb:v04E8p3004* + ID_PRODUCT_FROM_DATABASE=ML-4600 + +usb:v04E8p3005* + ID_PRODUCT_FROM_DATABASE=Docuprint P1210 + +usb:v04E8p3008* + ID_PRODUCT_FROM_DATABASE=ML-6060 laser printer + +usb:v04E8p300C* + ID_PRODUCT_FROM_DATABASE=ML-1210 Printer + +usb:v04E8p300E* + ID_PRODUCT_FROM_DATABASE=Laser Printer + +usb:v04E8p3104* + ID_PRODUCT_FROM_DATABASE=ML-3550N + +usb:v04E8p3210* + ID_PRODUCT_FROM_DATABASE=ML-5200A Laser Printer + +usb:v04E8p3226* + ID_PRODUCT_FROM_DATABASE=Laser Printer + +usb:v04E8p3228* + ID_PRODUCT_FROM_DATABASE=Laser Printer + +usb:v04E8p322A* + ID_PRODUCT_FROM_DATABASE=Laser Printer + +usb:v04E8p322C* + ID_PRODUCT_FROM_DATABASE=Laser Printer + +usb:v04E8p3230* + ID_PRODUCT_FROM_DATABASE=ML-1440 + +usb:v04E8p3232* + ID_PRODUCT_FROM_DATABASE=Laser Printer + +usb:v04E8p3236* + ID_PRODUCT_FROM_DATABASE=ML-1450 + +usb:v04E8p3238* + ID_PRODUCT_FROM_DATABASE=ML-1430 + +usb:v04E8p323A* + ID_PRODUCT_FROM_DATABASE=ML-1710 Printer + +usb:v04E8p323B* + ID_PRODUCT_FROM_DATABASE=Phaser 3130 + +usb:v04E8p323C* + ID_PRODUCT_FROM_DATABASE=Laser Printer + +usb:v04E8p323D* + ID_PRODUCT_FROM_DATABASE=Phaser 3120 + +usb:v04E8p323E* + ID_PRODUCT_FROM_DATABASE=Laser Printer + +usb:v04E8p3240* + ID_PRODUCT_FROM_DATABASE=Laser Printer + +usb:v04E8p3242* + ID_PRODUCT_FROM_DATABASE=ML-1510 Laser Printer + +usb:v04E8p3248* + ID_PRODUCT_FROM_DATABASE=Color Laser Printer + +usb:v04E8p324A* + ID_PRODUCT_FROM_DATABASE=Laser Printer + +usb:v04E8p324C* + ID_PRODUCT_FROM_DATABASE=ML-1740 Printer + +usb:v04E8p324D* + ID_PRODUCT_FROM_DATABASE=Phaser 3121 + +usb:v04E8p3256* + ID_PRODUCT_FROM_DATABASE=ML-1520 Laser Printer + +usb:v04E8p325B* + ID_PRODUCT_FROM_DATABASE=Xerox Phaser 3117 Laser Printer + +usb:v04E8p325F* + ID_PRODUCT_FROM_DATABASE=Phaser 3425 Laser Printer + +usb:v04E8p3260* + ID_PRODUCT_FROM_DATABASE=CLP-510 Color Laser Printer + +usb:v04E8p3268* + ID_PRODUCT_FROM_DATABASE=ML-1610 Mono Laser Printer + +usb:v04E8p326C* + ID_PRODUCT_FROM_DATABASE=ML-2010P Mono Laser Printer + +usb:v04E8p3276* + ID_PRODUCT_FROM_DATABASE=ML-3050/ML-3051 Laser Printer + +usb:v04E8p328E* + ID_PRODUCT_FROM_DATABASE=CLP-310 Color Laser Printer + +usb:v04E8p3292* + ID_PRODUCT_FROM_DATABASE=ML-1640 Series Laser Printer + +usb:v04E8p3296* + ID_PRODUCT_FROM_DATABASE=ML-2580N Mono Laser Printer + +usb:v04E8p3297* + ID_PRODUCT_FROM_DATABASE=ML-191x/ML-252x Laser Printer + +usb:v04E8p330C* + ID_PRODUCT_FROM_DATABASE=ML-1865 + +usb:v04E8p3310* + ID_PRODUCT_FROM_DATABASE=ML-331x Series Laser Printer + +usb:v04E8p3315* + ID_PRODUCT_FROM_DATABASE=ML-2540 Series Laser Printer + +usb:v04E8p3409* + ID_PRODUCT_FROM_DATABASE=SCX-4216F Scanner + +usb:v04E8p340C* + ID_PRODUCT_FROM_DATABASE=SCX-5x15 series + +usb:v04E8p340D* + ID_PRODUCT_FROM_DATABASE=SCX-6x20 series + +usb:v04E8p340E* + ID_PRODUCT_FROM_DATABASE=MFP 560 series + +usb:v04E8p340F* + ID_PRODUCT_FROM_DATABASE=Printing Support + +usb:v04E8p3412* + ID_PRODUCT_FROM_DATABASE=SCX-4x20 series + +usb:v04E8p3413* + ID_PRODUCT_FROM_DATABASE=SCX-4100 Scanner + +usb:v04E8p3415* + ID_PRODUCT_FROM_DATABASE=Composite Device + +usb:v04E8p3419* + ID_PRODUCT_FROM_DATABASE=Composite Device + +usb:v04E8p341A* + ID_PRODUCT_FROM_DATABASE=Printing Support + +usb:v04E8p341B* + ID_PRODUCT_FROM_DATABASE=SCX-4200 series + +usb:v04E8p341C* + ID_PRODUCT_FROM_DATABASE=Composite Device + +usb:v04E8p341D* + ID_PRODUCT_FROM_DATABASE=Composite Device + +usb:v04E8p341F* + ID_PRODUCT_FROM_DATABASE=Composite Device + +usb:v04E8p3420* + ID_PRODUCT_FROM_DATABASE=Composite Device + +usb:v04E8p3426* + ID_PRODUCT_FROM_DATABASE=SCX-4500 Laser Printer + +usb:v04E8p3605* + ID_PRODUCT_FROM_DATABASE=InkJet Color Printer + +usb:v04E8p3606* + ID_PRODUCT_FROM_DATABASE=InkJet Color Printer + +usb:v04E8p3609* + ID_PRODUCT_FROM_DATABASE=InkJet Color Printer + +usb:v04E8p3902* + ID_PRODUCT_FROM_DATABASE=InkJet Color Printer + +usb:v04E8p3903* + ID_PRODUCT_FROM_DATABASE=Xerox WorkCentre XK50cx + +usb:v04E8p390F* + ID_PRODUCT_FROM_DATABASE=InkJet Color Printer + +usb:v04E8p3911* + ID_PRODUCT_FROM_DATABASE=SCX-1020 series + +usb:v04E8p4005* + ID_PRODUCT_FROM_DATABASE=GT-S8000 Jet (msc) + +usb:v04E8p4F1F* + ID_PRODUCT_FROM_DATABASE=GT-S8000 Jet (mtp) + +usb:v04E8p5000* + ID_PRODUCT_FROM_DATABASE=YP-MF series + +usb:v04E8p5001* + ID_PRODUCT_FROM_DATABASE=YP-100 + +usb:v04E8p5002* + ID_PRODUCT_FROM_DATABASE=YP-30 + +usb:v04E8p5003* + ID_PRODUCT_FROM_DATABASE=YP-700 + +usb:v04E8p5004* + ID_PRODUCT_FROM_DATABASE=YP-30 + +usb:v04E8p5005* + ID_PRODUCT_FROM_DATABASE=YP-300 + +usb:v04E8p5006* + ID_PRODUCT_FROM_DATABASE=YP-750 + +usb:v04E8p500D* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v04E8p5010* + ID_PRODUCT_FROM_DATABASE=Yepp YP-35 + +usb:v04E8p5011* + ID_PRODUCT_FROM_DATABASE=YP-780 + +usb:v04E8p5013* + ID_PRODUCT_FROM_DATABASE=YP-60 + +usb:v04E8p5015* + ID_PRODUCT_FROM_DATABASE=yepp upgrade + +usb:v04E8p501B* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v04E8p5021* + ID_PRODUCT_FROM_DATABASE=Yepp YP-ST5 + +usb:v04E8p5026* + ID_PRODUCT_FROM_DATABASE=YP-MT6V + +usb:v04E8p5027* + ID_PRODUCT_FROM_DATABASE=YP-T7 + +usb:v04E8p502B* + ID_PRODUCT_FROM_DATABASE=YP-F1 + +usb:v04E8p5032* + ID_PRODUCT_FROM_DATABASE=YP-J70 + +usb:v04E8p503B* + ID_PRODUCT_FROM_DATABASE=YP-U1 MP3 Player + +usb:v04E8p503D* + ID_PRODUCT_FROM_DATABASE=YP-T7F + +usb:v04E8p5041* + ID_PRODUCT_FROM_DATABASE=YP-Z5 + +usb:v04E8p5050* + ID_PRODUCT_FROM_DATABASE=YP-U2 MP3 Player + +usb:v04E8p5051* + ID_PRODUCT_FROM_DATABASE=YP-F2R + +usb:v04E8p5055* + ID_PRODUCT_FROM_DATABASE=YP-T9 + +usb:v04E8p507D* + ID_PRODUCT_FROM_DATABASE=YP-U3 (mtp) + +usb:v04E8p507F* + ID_PRODUCT_FROM_DATABASE=YP-T9J + +usb:v04E8p5080* + ID_PRODUCT_FROM_DATABASE=Yepp YP-K3 (msc) + +usb:v04E8p5081* + ID_PRODUCT_FROM_DATABASE=Yepp YP-K3 (mtp) + +usb:v04E8p5082* + ID_PRODUCT_FROM_DATABASE=YP-P2 (msc) + +usb:v04E8p5083* + ID_PRODUCT_FROM_DATABASE=YP-P2 (mtp) + +usb:v04E8p508A* + ID_PRODUCT_FROM_DATABASE=YP-T10 + +usb:v04E8p508B* + ID_PRODUCT_FROM_DATABASE=YP-S5 MP3 Player + +usb:v04E8p508C* + ID_PRODUCT_FROM_DATABASE=YP-S5 + +usb:v04E8p5090* + ID_PRODUCT_FROM_DATABASE=YP-S3 (msc) + +usb:v04E8p5091* + ID_PRODUCT_FROM_DATABASE=YP-S3 (mtp) + +usb:v04E8p5092* + ID_PRODUCT_FROM_DATABASE=YP-U4 (msc) + +usb:v04E8p5093* + ID_PRODUCT_FROM_DATABASE=YP-U4 (mtp) + +usb:v04E8p5095* + ID_PRODUCT_FROM_DATABASE=YP-S2 + +usb:v04E8p510F* + ID_PRODUCT_FROM_DATABASE=YP-R1 + +usb:v04E8p5119* + ID_PRODUCT_FROM_DATABASE=Yepp YP-P3 + +usb:v04E8p511C* + ID_PRODUCT_FROM_DATABASE=YP-Q2 + +usb:v04E8p5121* + ID_PRODUCT_FROM_DATABASE=YP-U5 + +usb:v04E8p5123* + ID_PRODUCT_FROM_DATABASE=Yepp YP-M1 + +usb:v04E8p5A00* + ID_PRODUCT_FROM_DATABASE=YP-NEU + +usb:v04E8p5A01* + ID_PRODUCT_FROM_DATABASE=YP-NDU + +usb:v04E8p5A03* + ID_PRODUCT_FROM_DATABASE=Yepp MP3 Player + +usb:v04E8p5A04* + ID_PRODUCT_FROM_DATABASE=YP-800 + +usb:v04E8p5A08* + ID_PRODUCT_FROM_DATABASE=YP-90 + +usb:v04E8p5A0F* + ID_PRODUCT_FROM_DATABASE=Meizu M6 MiniPlayer + +usb:v04E8p5B01* + ID_PRODUCT_FROM_DATABASE=Memory Stick Reader/Writer + +usb:v04E8p5B02* + ID_PRODUCT_FROM_DATABASE=Memory Stick Reader/Writer + +usb:v04E8p5B03* + ID_PRODUCT_FROM_DATABASE=Memory Stick Reader/Writer + +usb:v04E8p5B04* + ID_PRODUCT_FROM_DATABASE=Memory Stick Reader/Writer + +usb:v04E8p5B05* + ID_PRODUCT_FROM_DATABASE=Memory Stick Reader/Writer + +usb:v04E8p5B11* + ID_PRODUCT_FROM_DATABASE=SEW-2001u Card + +usb:v04E8p5F00* + ID_PRODUCT_FROM_DATABASE=NEXiO Sync + +usb:v04E8p5F01* + ID_PRODUCT_FROM_DATABASE=NEXiO Sync + +usb:v04E8p5F02* + ID_PRODUCT_FROM_DATABASE=NEXiO Sync + +usb:v04E8p5F03* + ID_PRODUCT_FROM_DATABASE=NEXiO Sync + +usb:v04E8p5F04* + ID_PRODUCT_FROM_DATABASE=NEXiO Sync + +usb:v04E8p5F05* + ID_PRODUCT_FROM_DATABASE=STORY Station 1TB + +usb:v04E8p6032* + ID_PRODUCT_FROM_DATABASE=G2 Portable hard drive + +usb:v04E8p60B3* + ID_PRODUCT_FROM_DATABASE=M2 Portable Hard Drive + +usb:v04E8p60C4* + ID_PRODUCT_FROM_DATABASE=M2 Portable Hard Drive USB 3.0 + +usb:v04E8p6601* + ID_PRODUCT_FROM_DATABASE=Mobile Phone + +usb:v04E8p6602* + ID_PRODUCT_FROM_DATABASE=Galaxy + +usb:v04E8p6603* + ID_PRODUCT_FROM_DATABASE=Galaxy + +usb:v04E8p6611* + ID_PRODUCT_FROM_DATABASE=MITs Sync + +usb:v04E8p6613* + ID_PRODUCT_FROM_DATABASE=MITs Sync + +usb:v04E8p6615* + ID_PRODUCT_FROM_DATABASE=MITs Sync + +usb:v04E8p6617* + ID_PRODUCT_FROM_DATABASE=MITs Sync + +usb:v04E8p6619* + ID_PRODUCT_FROM_DATABASE=MITs Sync + +usb:v04E8p661B* + ID_PRODUCT_FROM_DATABASE=MITs Sync + +usb:v04E8p661E* + ID_PRODUCT_FROM_DATABASE=Handheld + +usb:v04E8p6620* + ID_PRODUCT_FROM_DATABASE=Handheld + +usb:v04E8p6622* + ID_PRODUCT_FROM_DATABASE=Handheld + +usb:v04E8p6624* + ID_PRODUCT_FROM_DATABASE=Handheld + +usb:v04E8p662E* + ID_PRODUCT_FROM_DATABASE=MITs Sync + +usb:v04E8p6630* + ID_PRODUCT_FROM_DATABASE=MITs Sync + +usb:v04E8p6632* + ID_PRODUCT_FROM_DATABASE=MITs Sync + +usb:v04E8p663E* + ID_PRODUCT_FROM_DATABASE=D900e Phone + +usb:v04E8p663F* + ID_PRODUCT_FROM_DATABASE=SGH-E720/SGH-E840 + +usb:v04E8p6640* + ID_PRODUCT_FROM_DATABASE=Usb Modem Enumerator + +usb:v04E8p6702* + ID_PRODUCT_FROM_DATABASE=X830 + +usb:v04E8p6708* + ID_PRODUCT_FROM_DATABASE=U600 Phone + +usb:v04E8p6709* + ID_PRODUCT_FROM_DATABASE=U600 + +usb:v04E8p6734* + ID_PRODUCT_FROM_DATABASE=Juke + +usb:v04E8p6759* + ID_PRODUCT_FROM_DATABASE=D900e Media Player + +usb:v04E8p675A* + ID_PRODUCT_FROM_DATABASE=D900e Mass Storage + +usb:v04E8p675B* + ID_PRODUCT_FROM_DATABASE=D900e Camera + +usb:v04E8p6772* + ID_PRODUCT_FROM_DATABASE=Standalone LTE device (Trial) + +usb:v04E8p6795* + ID_PRODUCT_FROM_DATABASE=S5230 + +usb:v04E8p6802* + ID_PRODUCT_FROM_DATABASE=Standalone HSPA device + +usb:v04E8p6806* + ID_PRODUCT_FROM_DATABASE=Composite LTE device (Trial) + +usb:v04E8p6807* + ID_PRODUCT_FROM_DATABASE=Composite HSPA device + +usb:v04E8p681C* + ID_PRODUCT_FROM_DATABASE=Galaxy Portal/Spica/S + +usb:v04E8p681D* + ID_PRODUCT_FROM_DATABASE=Galaxy Portal/Spica Android Phone + +usb:v04E8p684E* + ID_PRODUCT_FROM_DATABASE=Wave (GT-S8500) + +usb:v04E8p685B* + ID_PRODUCT_FROM_DATABASE=GT-I9100 Phone [Galaxy S II] (mass storage mode) + +usb:v04E8p685C* + ID_PRODUCT_FROM_DATABASE=GT-I9250 Phone [Galaxy Nexus] + +usb:v04E8p685E* + ID_PRODUCT_FROM_DATABASE=GT-I9100 Phone [Galaxy S II] (USB Debugging mode) + +usb:v04E8p6860* + ID_PRODUCT_FROM_DATABASE=GT-I9100 Phone [Galaxy S II], GT-I9300 Phone [Galaxy S III], GT-P7500 [Galaxy Tab 10.1] + +usb:v04E8p6865* + ID_PRODUCT_FROM_DATABASE=GT-I9300 Phone [Galaxy S III] (PTP mode) + +usb:v04E8p6866* + ID_PRODUCT_FROM_DATABASE=GT-I9300 Phone [Galaxy S III] (debugging mode) + +usb:v04E8p6875* + ID_PRODUCT_FROM_DATABASE=GT-B3710 Standalone LTE device (Commercial) + +usb:v04E8p6876* + ID_PRODUCT_FROM_DATABASE=GT-B3710 LTE Modem + +usb:v04E8p6877* + ID_PRODUCT_FROM_DATABASE=Galaxy S + +usb:v04E8p6888* + ID_PRODUCT_FROM_DATABASE=GT-B3730 Composite LTE device (Commercial) + +usb:v04E8p6889* + ID_PRODUCT_FROM_DATABASE=GT-B3730 Composite LTE device (Commercial) + +usb:v04E8p689A* + ID_PRODUCT_FROM_DATABASE=LTE Storage Driver [CMC2xx] + +usb:v04E8p689E* + ID_PRODUCT_FROM_DATABASE=GT-S5670 [Galaxy Fit] + +usb:v04E8p68AA* + ID_PRODUCT_FROM_DATABASE=Reality + +usb:v04E8p7011* + ID_PRODUCT_FROM_DATABASE=SEW-2003U Card + +usb:v04E8p7021* + ID_PRODUCT_FROM_DATABASE=Bluetooth Device + +usb:v04E8p7061* + ID_PRODUCT_FROM_DATABASE=eHome Infrared Receiver + +usb:v04E8p7080* + ID_PRODUCT_FROM_DATABASE=Anycall SCH-W580 + +usb:v04E8p7081* + ID_PRODUCT_FROM_DATABASE=Human Interface Device + +usb:v04E8p8001* + ID_PRODUCT_FROM_DATABASE=Handheld + +usb:v04E8pE020* + ID_PRODUCT_FROM_DATABASE=SERI E02 SCOM 6200 UMTS Phone + +usb:v04E8pE021* + ID_PRODUCT_FROM_DATABASE=SERI E02 SCOM 6200 Virtual UARTs + +usb:v04E8pE022* + ID_PRODUCT_FROM_DATABASE=SERI E02 SCOM 6200 Flash Load Disk + +usb:v04E8pFF30* + ID_PRODUCT_FROM_DATABASE=SG_iMON + +usb:v04E9* + ID_VENDOR_FROM_DATABASE=PC-Tel, Inc. + +usb:v04EA* + ID_VENDOR_FROM_DATABASE=Brooktree Corp. + +usb:v04EB* + ID_VENDOR_FROM_DATABASE=Northstar Systems, Inc. + +usb:v04EBpE004* + ID_PRODUCT_FROM_DATABASE=eHome Infrared Transceiver + +usb:v04EC* + ID_VENDOR_FROM_DATABASE=Tokyo Electron Device, Ltd + +usb:v04ED* + ID_VENDOR_FROM_DATABASE=Annabooks + +usb:v04EF* + ID_VENDOR_FROM_DATABASE=Pacific Electronic International, Inc. + +usb:v04F0* + ID_VENDOR_FROM_DATABASE=Daewoo Electronics Co., Ltd + +usb:v04F1* + ID_VENDOR_FROM_DATABASE=Victor Company of Japan, Ltd + +usb:v04F1p0001* + ID_PRODUCT_FROM_DATABASE=GC-QX3 Digital Still Camera + +usb:v04F1p0004* + ID_PRODUCT_FROM_DATABASE=GR-DVL815U Digital Video Camera + +usb:v04F1p0006* + ID_PRODUCT_FROM_DATABASE=DV Camera Storage + +usb:v04F1p0008* + ID_PRODUCT_FROM_DATABASE=GZ-MG30AA/MC500E Digital Video Camera + +usb:v04F1p0009* + ID_PRODUCT_FROM_DATABASE=GR-DX25EK Digital Video Camera + +usb:v04F1p000A* + ID_PRODUCT_FROM_DATABASE=GR-D72 Digital Video Camera + +usb:v04F1p1001* + ID_PRODUCT_FROM_DATABASE=GC-A50 Camera Device + +usb:v04F1p3008* + ID_PRODUCT_FROM_DATABASE=MP-PRX1 Ethernet + +usb:v04F1p3009* + ID_PRODUCT_FROM_DATABASE=MP-XP7250 WLAN Adapter + +usb:v04F2* + ID_VENDOR_FROM_DATABASE=Chicony Electronics Co., Ltd + +usb:v04F2p0001* + ID_PRODUCT_FROM_DATABASE=KU-8933 Keyboard + +usb:v04F2p0002* + ID_PRODUCT_FROM_DATABASE=NT68P81 Keyboard + +usb:v04F2p0110* + ID_PRODUCT_FROM_DATABASE=KU-2971 Keyboard + +usb:v04F2p0111* + ID_PRODUCT_FROM_DATABASE=KU-9908 Keyboard + +usb:v04F2p0112* + ID_PRODUCT_FROM_DATABASE=KU-8933 Keyboard with PS/2 Mouse port + +usb:v04F2p0116* + ID_PRODUCT_FROM_DATABASE=KU-2971/KU-0325 Keyboard + +usb:v04F2p0200* + ID_PRODUCT_FROM_DATABASE=KBR-0108 + +usb:v04F2p0201* + ID_PRODUCT_FROM_DATABASE=Gaming Keyboard KPD0250 + +usb:v04F2p0220* + ID_PRODUCT_FROM_DATABASE=Wireless HID Receiver + +usb:v04F2p0402* + ID_PRODUCT_FROM_DATABASE=Genius LuxeMate i200 Keyboard + +usb:v04F2p0403* + ID_PRODUCT_FROM_DATABASE=KU-0420 keyboard + +usb:v04F2p0418* + ID_PRODUCT_FROM_DATABASE=KU-0418 Tactical Pad + +usb:v04F2p0760* + ID_PRODUCT_FROM_DATABASE=Acer KU-0760 Keyboard + +usb:v04F2p0841* + ID_PRODUCT_FROM_DATABASE=HP Multimedia Keyboard + +usb:v04F2p0860* + ID_PRODUCT_FROM_DATABASE=2.4G Multimedia Wireless Kit + +usb:v04F2pA001* + ID_PRODUCT_FROM_DATABASE=E-Video DC-100 Camera + +usb:v04F2pA120* + ID_PRODUCT_FROM_DATABASE=ORITE CCD Webcam(PC370R) + +usb:v04F2pA121* + ID_PRODUCT_FROM_DATABASE=ORITE CCD Webcam(PC370R) + +usb:v04F2pA122* + ID_PRODUCT_FROM_DATABASE=ORITE CCD Webcam(PC370R) + +usb:v04F2pA123* + ID_PRODUCT_FROM_DATABASE=ORITE CCD Webcam(PC370R) + +usb:v04F2pA124* + ID_PRODUCT_FROM_DATABASE=ORITE CCD Webcam(PC370R) + +usb:v04F2pA128* + ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C202 + OV7663 + EEPROM) + +usb:v04F2pA133* + ID_PRODUCT_FROM_DATABASE=Gateway Webcam + +usb:v04F2pA136* + ID_PRODUCT_FROM_DATABASE=LabTec Webcam 5500 + +usb:v04F2pA204* + ID_PRODUCT_FROM_DATABASE=DSC WIA Device (1300) + +usb:v04F2pA208* + ID_PRODUCT_FROM_DATABASE=DSC WIA Device (2320) + +usb:v04F2pA209* + ID_PRODUCT_FROM_DATABASE=Labtec DC-2320 + +usb:v04F2pA20A* + ID_PRODUCT_FROM_DATABASE=DSC WIA Device (3310) + +usb:v04F2pA20C* + ID_PRODUCT_FROM_DATABASE=DSC WIA Device (3320) + +usb:v04F2pA210* + ID_PRODUCT_FROM_DATABASE=Audio Device + +usb:v04F2pB008* + ID_PRODUCT_FROM_DATABASE=USB 2.0 Camera + +usb:v04F2pB009* + ID_PRODUCT_FROM_DATABASE=Integrated Camera + +usb:v04F2pB010* + ID_PRODUCT_FROM_DATABASE=Integrated Camera + +usb:v04F2pB012* + ID_PRODUCT_FROM_DATABASE=1.3 MPixel UVC Webcam + +usb:v04F2pB013* + ID_PRODUCT_FROM_DATABASE=USB 2.0 Camera + +usb:v04F2pB015* + ID_PRODUCT_FROM_DATABASE=VGA 24fps UVC Webcam + +usb:v04F2pB016* + ID_PRODUCT_FROM_DATABASE=VGA 30fps UVC Webcam + +usb:v04F2pB018* + ID_PRODUCT_FROM_DATABASE=2M UVC Webcam + +usb:v04F2pB021* + ID_PRODUCT_FROM_DATABASE=ViewSonic 1.3M, USB2.0 Webcam + +usb:v04F2pB022* + ID_PRODUCT_FROM_DATABASE=Gateway USB 2.0 Webcam + +usb:v04F2pB023* + ID_PRODUCT_FROM_DATABASE=Gateway USB 2.0 Webcam + +usb:v04F2pB024* + ID_PRODUCT_FROM_DATABASE=USB 2.0 Webcam + +usb:v04F2pB025* + ID_PRODUCT_FROM_DATABASE=Camera + +usb:v04F2pB027* + ID_PRODUCT_FROM_DATABASE=Gateway USB 2.0 Webcam + +usb:v04F2pB028* + ID_PRODUCT_FROM_DATABASE=VGA UVC Webcam + +usb:v04F2pB029* + ID_PRODUCT_FROM_DATABASE=1.3M UVC Webcam + +usb:v04F2pB036* + ID_PRODUCT_FROM_DATABASE=Asus Integrated 0.3M UVC Webcam + +usb:v04F2pB044* + ID_PRODUCT_FROM_DATABASE=Acer CrystalEye Webcam + +usb:v04F2pB057* + ID_PRODUCT_FROM_DATABASE=integrated USB webcam + +usb:v04F2pB059* + ID_PRODUCT_FROM_DATABASE=CKF7037 HP webcam + +usb:v04F2pB071* + ID_PRODUCT_FROM_DATABASE=2.0M UVC Webcam / CNF7129 + +usb:v04F2pB091* + ID_PRODUCT_FROM_DATABASE=Webcam + +usb:v04F2pB104* + ID_PRODUCT_FROM_DATABASE=CNF7069 Webcam + +usb:v04F2pB107* + ID_PRODUCT_FROM_DATABASE=CNF7070 Webcam + +usb:v04F2pB14C* + ID_PRODUCT_FROM_DATABASE=CNF8050 Webcam + +usb:v04F2pB175* + ID_PRODUCT_FROM_DATABASE=4-Port Hub + +usb:v04F2pB1AA* + ID_PRODUCT_FROM_DATABASE=Webcam-101 + +usb:v04F2pB1B4* + ID_PRODUCT_FROM_DATABASE=Lenovo Integrated Camera + +usb:v04F2pB1B9* + ID_PRODUCT_FROM_DATABASE=Asus Integrated Webcam + +usb:v04F2pB1CF* + ID_PRODUCT_FROM_DATABASE=Lenovo Integrated Camera + +usb:v04F2pB1D6* + ID_PRODUCT_FROM_DATABASE=CNF9055 Toshiba Webcam + +usb:v04F2pB217* + ID_PRODUCT_FROM_DATABASE=Lenovo Integrated Camera (0.3MP) + +usb:v04F2pB221* + ID_PRODUCT_FROM_DATABASE=integrated camera + +usb:v04F2pB230* + ID_PRODUCT_FROM_DATABASE=Integrated HP HD Webcam + +usb:v04F2pB257* + ID_PRODUCT_FROM_DATABASE=Lenovo Integrated Camera + +usb:v04F2pB26B* + ID_PRODUCT_FROM_DATABASE=Sony Visual Communication Camera + +usb:v04F2pB272* + ID_PRODUCT_FROM_DATABASE=Lenovo EasyCamera + +usb:v04F2pB2B0* + ID_PRODUCT_FROM_DATABASE=Camera + +usb:v04F2pB2B9* + ID_PRODUCT_FROM_DATABASE=Lenovo Integrated Camera UVC + +usb:v04F2pB2EA* + ID_PRODUCT_FROM_DATABASE=Integrated Camera [ThinkPad] + +usb:v04F2pB330* + ID_PRODUCT_FROM_DATABASE=Asus 720p CMOS webcam + +usb:v04F3* + ID_VENDOR_FROM_DATABASE=Elan Microelectronics Corp. + +usb:v04F3p0103* + ID_PRODUCT_FROM_DATABASE=ActiveJet K-2024 Multimedia Keyboard + +usb:v04F3p01A4* + ID_PRODUCT_FROM_DATABASE=Wireless Keyboard + +usb:v04F3p0210* + ID_PRODUCT_FROM_DATABASE=AM-400 Hama Optical Mouse + +usb:v04F3p0212* + ID_PRODUCT_FROM_DATABASE=Laser Mouse + +usb:v04F3p0214* + ID_PRODUCT_FROM_DATABASE=Lynx M9 Optical Mouse + +usb:v04F3p0230* + ID_PRODUCT_FROM_DATABASE=3D Optical Mouse + +usb:v04F3p0232* + ID_PRODUCT_FROM_DATABASE=Mouse + +usb:v04F3p02F4* + ID_PRODUCT_FROM_DATABASE=2.4G Cordless Mouse + +usb:v04F3p04A0* + ID_PRODUCT_FROM_DATABASE=Dream Cheeky Stress/Panic Button + +usb:v04F4* + ID_VENDOR_FROM_DATABASE=Harting Elektronik, Inc. + +usb:v04F5* + ID_VENDOR_FROM_DATABASE=Fujitsu-ICL Systems, Inc. + +usb:v04F6* + ID_VENDOR_FROM_DATABASE=Norand Corp. + +usb:v04F7* + ID_VENDOR_FROM_DATABASE=Newnex Technology Corp. + +usb:v04F8* + ID_VENDOR_FROM_DATABASE=FuturePlus Systems + +usb:v04F9* + ID_VENDOR_FROM_DATABASE=Brother Industries, Ltd + +usb:v04F9p0002* + ID_PRODUCT_FROM_DATABASE=HL-1050 Laser Printer + +usb:v04F9p0005* + ID_PRODUCT_FROM_DATABASE=Printer + +usb:v04F9p0006* + ID_PRODUCT_FROM_DATABASE=HL-1240 Laser Printer + +usb:v04F9p0007* + ID_PRODUCT_FROM_DATABASE=HL-1250 Laser Printer + +usb:v04F9p0008* + ID_PRODUCT_FROM_DATABASE=HL-1270 Laser Printer + +usb:v04F9p0009* + ID_PRODUCT_FROM_DATABASE=Printer + +usb:v04F9p000A* + ID_PRODUCT_FROM_DATABASE=P2500 series + +usb:v04F9p000B* + ID_PRODUCT_FROM_DATABASE=Printer + +usb:v04F9p000C* + ID_PRODUCT_FROM_DATABASE=Printer + +usb:v04F9p000D* + ID_PRODUCT_FROM_DATABASE=HL-1440 Laser Printer + +usb:v04F9p000E* + ID_PRODUCT_FROM_DATABASE=HL-1450 series + +usb:v04F9p000F* + ID_PRODUCT_FROM_DATABASE=HL-1470N series + +usb:v04F9p0010* + ID_PRODUCT_FROM_DATABASE=Printer + +usb:v04F9p0011* + ID_PRODUCT_FROM_DATABASE=Printer + +usb:v04F9p0012* + ID_PRODUCT_FROM_DATABASE=Printer + +usb:v04F9p0013* + ID_PRODUCT_FROM_DATABASE=Printer + +usb:v04F9p0014* + ID_PRODUCT_FROM_DATABASE=Printer + +usb:v04F9p0015* + ID_PRODUCT_FROM_DATABASE=Printer + +usb:v04F9p0016* + ID_PRODUCT_FROM_DATABASE=Printer + +usb:v04F9p0017* + ID_PRODUCT_FROM_DATABASE=Printer + +usb:v04F9p0018* + ID_PRODUCT_FROM_DATABASE=Printer + +usb:v04F9p001A* + ID_PRODUCT_FROM_DATABASE=HL-1430 Laser Printer + +usb:v04F9p001C* + ID_PRODUCT_FROM_DATABASE=Printer + +usb:v04F9p001E* + ID_PRODUCT_FROM_DATABASE=Printer + +usb:v04F9p0020* + ID_PRODUCT_FROM_DATABASE=HL-5130 series + +usb:v04F9p0021* + ID_PRODUCT_FROM_DATABASE=HL-5140 series + +usb:v04F9p0022* + ID_PRODUCT_FROM_DATABASE=HL-5150D series + +usb:v04F9p0023* + ID_PRODUCT_FROM_DATABASE=HL-5170DN series + +usb:v04F9p0024* + ID_PRODUCT_FROM_DATABASE=Printer + +usb:v04F9p0025* + ID_PRODUCT_FROM_DATABASE=Printer + +usb:v04F9p0027* + ID_PRODUCT_FROM_DATABASE=HL-2030 Laser Printer + +usb:v04F9p0028* + ID_PRODUCT_FROM_DATABASE=Printer + +usb:v04F9p0029* + ID_PRODUCT_FROM_DATABASE=Printer + +usb:v04F9p002A* + ID_PRODUCT_FROM_DATABASE=HL-52x0 series + +usb:v04F9p002B* + ID_PRODUCT_FROM_DATABASE=HL-5250DN Printer + +usb:v04F9p002C* + ID_PRODUCT_FROM_DATABASE=Printer + +usb:v04F9p002D* + ID_PRODUCT_FROM_DATABASE=Printer + +usb:v04F9p0039* + ID_PRODUCT_FROM_DATABASE=HL-5340 series + +usb:v04F9p0100* + ID_PRODUCT_FROM_DATABASE=MFC8600/9650 series + +usb:v04F9p0101* + ID_PRODUCT_FROM_DATABASE=MFC9600/9870 series + +usb:v04F9p0102* + ID_PRODUCT_FROM_DATABASE=MFC9750/1200 series + +usb:v04F9p0104* + ID_PRODUCT_FROM_DATABASE=MFC-8300J + +usb:v04F9p0105* + ID_PRODUCT_FROM_DATABASE=MFC-9600J + +usb:v04F9p0106* + ID_PRODUCT_FROM_DATABASE=MFC-7300C + +usb:v04F9p0107* + ID_PRODUCT_FROM_DATABASE=MFC-7400C + +usb:v04F9p0108* + ID_PRODUCT_FROM_DATABASE=MFC-9200C + +usb:v04F9p0109* + ID_PRODUCT_FROM_DATABASE=MFC-830 + +usb:v04F9p010A* + ID_PRODUCT_FROM_DATABASE=MFC-840 + +usb:v04F9p010B* + ID_PRODUCT_FROM_DATABASE=MFC-860 + +usb:v04F9p010C* + ID_PRODUCT_FROM_DATABASE=MFC-7400J + +usb:v04F9p010D* + ID_PRODUCT_FROM_DATABASE=MFC-9200J + +usb:v04F9p010E* + ID_PRODUCT_FROM_DATABASE=MFC3100C Scanner + +usb:v04F9p010F* + ID_PRODUCT_FROM_DATABASE=MFC 5100C + +usb:v04F9p0110* + ID_PRODUCT_FROM_DATABASE=MFC4800 Scanner + +usb:v04F9p0111* + ID_PRODUCT_FROM_DATABASE=MFC 6800 + +usb:v04F9p0112* + ID_PRODUCT_FROM_DATABASE=DCP1000 Port(FaxModem) + +usb:v04F9p0113* + ID_PRODUCT_FROM_DATABASE=MFC-8500 + +usb:v04F9p0114* + ID_PRODUCT_FROM_DATABASE=MFC9700 Port(FaxModem) + +usb:v04F9p0115* + ID_PRODUCT_FROM_DATABASE=MFC9800 Scanner + +usb:v04F9p0116* + ID_PRODUCT_FROM_DATABASE=DCP1400 Scanner + +usb:v04F9p0119* + ID_PRODUCT_FROM_DATABASE=MFC-9660 + +usb:v04F9p011B* + ID_PRODUCT_FROM_DATABASE=MFC-9880 + +usb:v04F9p011C* + ID_PRODUCT_FROM_DATABASE=MFC-9760 + +usb:v04F9p011D* + ID_PRODUCT_FROM_DATABASE=MFC-9070 + +usb:v04F9p011E* + ID_PRODUCT_FROM_DATABASE=MFC-9180 + +usb:v04F9p011F* + ID_PRODUCT_FROM_DATABASE=MFC-9160 + +usb:v04F9p0120* + ID_PRODUCT_FROM_DATABASE=MFC580 Port(FaxModem) + +usb:v04F9p0121* + ID_PRODUCT_FROM_DATABASE=MFC-590 + +usb:v04F9p0122* + ID_PRODUCT_FROM_DATABASE=MFC-5100J + +usb:v04F9p0129* + ID_PRODUCT_FROM_DATABASE=Imagistics 2500 (MFC-8640D clone) + +usb:v04F9p012F* + ID_PRODUCT_FROM_DATABASE=FAX-4750e + +usb:v04F9p0132* + ID_PRODUCT_FROM_DATABASE=MFC-5200C RemovableDisk + +usb:v04F9p0135* + ID_PRODUCT_FROM_DATABASE=MFC-100 Scanner + +usb:v04F9p0136* + ID_PRODUCT_FROM_DATABASE=MFC-150CL Scanner + +usb:v04F9p013C* + ID_PRODUCT_FROM_DATABASE=MFC-890 Port + +usb:v04F9p013D* + ID_PRODUCT_FROM_DATABASE=MFC-5200J Printer + +usb:v04F9p013E* + ID_PRODUCT_FROM_DATABASE=MFC-4420C RemovableDisk + +usb:v04F9p013F* + ID_PRODUCT_FROM_DATABASE=MFC-4820C RemovableDisk + +usb:v04F9p0140* + ID_PRODUCT_FROM_DATABASE=DCP-8020 + +usb:v04F9p0141* + ID_PRODUCT_FROM_DATABASE=DCP-8025D + +usb:v04F9p0142* + ID_PRODUCT_FROM_DATABASE=MFC-8420 + +usb:v04F9p0143* + ID_PRODUCT_FROM_DATABASE=MFC-8820D + +usb:v04F9p0144* + ID_PRODUCT_FROM_DATABASE=DCP-4020C RemovableDisk + +usb:v04F9p0146* + ID_PRODUCT_FROM_DATABASE=MFC-3220C + +usb:v04F9p0147* + ID_PRODUCT_FROM_DATABASE=FAX-1820C Printer + +usb:v04F9p0148* + ID_PRODUCT_FROM_DATABASE=MFC-3320CN Printer + +usb:v04F9p0149* + ID_PRODUCT_FROM_DATABASE=FAX-1920CN Printer + +usb:v04F9p014A* + ID_PRODUCT_FROM_DATABASE=MFC-3420C + +usb:v04F9p014B* + ID_PRODUCT_FROM_DATABASE=MFC-3820CN + +usb:v04F9p014D* + ID_PRODUCT_FROM_DATABASE=FAX-1815C Printer + +usb:v04F9p014E* + ID_PRODUCT_FROM_DATABASE=MFC-8820J + +usb:v04F9p0150* + ID_PRODUCT_FROM_DATABASE=MFC-8220 Port(FaxModem) + +usb:v04F9p0151* + ID_PRODUCT_FROM_DATABASE=MFC-8210J + +usb:v04F9p0157* + ID_PRODUCT_FROM_DATABASE=MFC-3420J Printer + +usb:v04F9p0158* + ID_PRODUCT_FROM_DATABASE=MFC-3820JN Port(FaxModem) + +usb:v04F9p015D* + ID_PRODUCT_FROM_DATABASE=MFC Composite Device + +usb:v04F9p015E* + ID_PRODUCT_FROM_DATABASE=DCP-8045D + +usb:v04F9p015F* + ID_PRODUCT_FROM_DATABASE=MFC-8440 + +usb:v04F9p0160* + ID_PRODUCT_FROM_DATABASE=MFC-8840D + +usb:v04F9p0161* + ID_PRODUCT_FROM_DATABASE=MFC-210C + +usb:v04F9p0162* + ID_PRODUCT_FROM_DATABASE=MFC-420CN Remote Setup Port + +usb:v04F9p0163* + ID_PRODUCT_FROM_DATABASE=MFC-410CN RemovableDisk + +usb:v04F9p0165* + ID_PRODUCT_FROM_DATABASE=MFC-620CN + +usb:v04F9p0166* + ID_PRODUCT_FROM_DATABASE=MFC-610CLN RemovableDisk + +usb:v04F9p0168* + ID_PRODUCT_FROM_DATABASE=MFC-620CLN + +usb:v04F9p0169* + ID_PRODUCT_FROM_DATABASE=DCP-110C RemovableDisk + +usb:v04F9p016B* + ID_PRODUCT_FROM_DATABASE=DCP-310CN RemovableDisk + +usb:v04F9p016C* + ID_PRODUCT_FROM_DATABASE=FAX-2440C Printer + +usb:v04F9p016D* + ID_PRODUCT_FROM_DATABASE=MFC-5440CN + +usb:v04F9p016E* + ID_PRODUCT_FROM_DATABASE=MFC-5840CN Remote Setup Port + +usb:v04F9p0170* + ID_PRODUCT_FROM_DATABASE=FAX-1840C Printer + +usb:v04F9p0171* + ID_PRODUCT_FROM_DATABASE=FAX-1835C Printer + +usb:v04F9p0172* + ID_PRODUCT_FROM_DATABASE=FAX-1940CN Printer + +usb:v04F9p0173* + ID_PRODUCT_FROM_DATABASE=MFC-3240C Remote Setup Port + +usb:v04F9p0174* + ID_PRODUCT_FROM_DATABASE=MFC-3340CN RemovableDisk + +usb:v04F9p017B* + ID_PRODUCT_FROM_DATABASE=Imagistics sx2100 + +usb:v04F9p0180* + ID_PRODUCT_FROM_DATABASE=MFC-7420 + +usb:v04F9p0181* + ID_PRODUCT_FROM_DATABASE=MFC-7820N Port(FaxModem) + +usb:v04F9p0182* + ID_PRODUCT_FROM_DATABASE=Composite Device + +usb:v04F9p0183* + ID_PRODUCT_FROM_DATABASE=DCP-7020 + +usb:v04F9p0184* + ID_PRODUCT_FROM_DATABASE=DCP-7025 Printer + +usb:v04F9p0185* + ID_PRODUCT_FROM_DATABASE=MFC-7220 Printer + +usb:v04F9p0186* + ID_PRODUCT_FROM_DATABASE=Composite Device + +usb:v04F9p0187* + ID_PRODUCT_FROM_DATABASE=FAX-2820 Printer + +usb:v04F9p0188* + ID_PRODUCT_FROM_DATABASE=FAX-2920 Printer + +usb:v04F9p018A* + ID_PRODUCT_FROM_DATABASE=MFC-9420CN + +usb:v04F9p018C* + ID_PRODUCT_FROM_DATABASE=DCP-115C + +usb:v04F9p018D* + ID_PRODUCT_FROM_DATABASE=DCP-116C + +usb:v04F9p018E* + ID_PRODUCT_FROM_DATABASE=DCP-117C + +usb:v04F9p018F* + ID_PRODUCT_FROM_DATABASE=DCP-118C + +usb:v04F9p0190* + ID_PRODUCT_FROM_DATABASE=DCP-120C + +usb:v04F9p0191* + ID_PRODUCT_FROM_DATABASE=DCP-315CN + +usb:v04F9p0192* + ID_PRODUCT_FROM_DATABASE=DCP-340CW + +usb:v04F9p0193* + ID_PRODUCT_FROM_DATABASE=MFC-215C + +usb:v04F9p0194* + ID_PRODUCT_FROM_DATABASE=MFC-425CN + +usb:v04F9p0195* + ID_PRODUCT_FROM_DATABASE=MFC-820CW Remote Setup Port + +usb:v04F9p0196* + ID_PRODUCT_FROM_DATABASE=MFC-820CN Remote Setup Port + +usb:v04F9p0197* + ID_PRODUCT_FROM_DATABASE=MFC-640CW + +usb:v04F9p019A* + ID_PRODUCT_FROM_DATABASE=MFC-840CLN Remote Setup Port + +usb:v04F9p01A2* + ID_PRODUCT_FROM_DATABASE=MFC-8640D + +usb:v04F9p01A3* + ID_PRODUCT_FROM_DATABASE=Composite Device + +usb:v04F9p01A4* + ID_PRODUCT_FROM_DATABASE=DCP-8065DN Printer + +usb:v04F9p01A5* + ID_PRODUCT_FROM_DATABASE=MFC-8460N Port(FaxModem) + +usb:v04F9p01A6* + ID_PRODUCT_FROM_DATABASE=MFC-8860DN Port(FaxModem) + +usb:v04F9p01A7* + ID_PRODUCT_FROM_DATABASE=MFC-8870DW Printer + +usb:v04F9p01A8* + ID_PRODUCT_FROM_DATABASE=DCP-130C + +usb:v04F9p01A9* + ID_PRODUCT_FROM_DATABASE=DCP-330C + +usb:v04F9p01AA* + ID_PRODUCT_FROM_DATABASE=DCP-540CN + +usb:v04F9p01AB* + ID_PRODUCT_FROM_DATABASE=MFC-240C + +usb:v04F9p01AE* + ID_PRODUCT_FROM_DATABASE=DCP-750CW RemovableDisk + +usb:v04F9p01AF* + ID_PRODUCT_FROM_DATABASE=MFC-440CN + +usb:v04F9p01B0* + ID_PRODUCT_FROM_DATABASE=MFC-660CN + +usb:v04F9p01B1* + ID_PRODUCT_FROM_DATABASE=MFC-665CW Remote Setup Port + +usb:v04F9p01B2* + ID_PRODUCT_FROM_DATABASE=MFC-845CW Remote Setup Port + +usb:v04F9p01B4* + ID_PRODUCT_FROM_DATABASE=MFC-460CN Remote Setup Port + +usb:v04F9p01B5* + ID_PRODUCT_FROM_DATABASE=MFC-630CD + +usb:v04F9p01B6* + ID_PRODUCT_FROM_DATABASE=MFC-850CDN + +usb:v04F9p01B7* + ID_PRODUCT_FROM_DATABASE=MFC-5460CN Remote Setup Port + +usb:v04F9p01B8* + ID_PRODUCT_FROM_DATABASE=MFC-5860CN + +usb:v04F9p01BA* + ID_PRODUCT_FROM_DATABASE=MFC-3360C + +usb:v04F9p01BD* + ID_PRODUCT_FROM_DATABASE=MFC-8660DN + +usb:v04F9p01BE* + ID_PRODUCT_FROM_DATABASE=DCP-750CN RemovableDisk + +usb:v04F9p01BF* + ID_PRODUCT_FROM_DATABASE=MFC-860CDN Remote Setup Port + +usb:v04F9p01C0* + ID_PRODUCT_FROM_DATABASE=DCP-128C + +usb:v04F9p01C1* + ID_PRODUCT_FROM_DATABASE=DCP-129C + +usb:v04F9p01C2* + ID_PRODUCT_FROM_DATABASE=DCP-131C + +usb:v04F9p01C3* + ID_PRODUCT_FROM_DATABASE=DCP-329C + +usb:v04F9p01C4* + ID_PRODUCT_FROM_DATABASE=DCP-331C + +usb:v04F9p01C5* + ID_PRODUCT_FROM_DATABASE=MFC-239C + +usb:v04F9p01CA* + ID_PRODUCT_FROM_DATABASE=MFC-9440CN Remote Setup Port + +usb:v04F9p01CE* + ID_PRODUCT_FROM_DATABASE=DCP-135C + +usb:v04F9p01CF* + ID_PRODUCT_FROM_DATABASE=DCP-150C + +usb:v04F9p01D0* + ID_PRODUCT_FROM_DATABASE=DCP-350C + +usb:v04F9p01D1* + ID_PRODUCT_FROM_DATABASE=DCP-560CN + +usb:v04F9p01D4* + ID_PRODUCT_FROM_DATABASE=MFC-230C + +usb:v04F9p01D5* + ID_PRODUCT_FROM_DATABASE=MFC-235C + +usb:v04F9p01D6* + ID_PRODUCT_FROM_DATABASE=MFC-260C + +usb:v04F9p01DF* + ID_PRODUCT_FROM_DATABASE=DCP-155C + +usb:v04F9p01E0* + ID_PRODUCT_FROM_DATABASE=MFC-265C + +usb:v04F9p01E1* + ID_PRODUCT_FROM_DATABASE=DCP-153C + +usb:v04F9p01E2* + ID_PRODUCT_FROM_DATABASE=DCP-157C + +usb:v04F9p01E3* + ID_PRODUCT_FROM_DATABASE=DCP-353C + +usb:v04F9p01E4* + ID_PRODUCT_FROM_DATABASE=DCP-357C + +usb:v04F9p01E7* + ID_PRODUCT_FROM_DATABASE=MFC-7340 + +usb:v04F9p01E9* + ID_PRODUCT_FROM_DATABASE=DCP-7040 + +usb:v04F9p01EA* + ID_PRODUCT_FROM_DATABASE=DCP-7030 + +usb:v04F9p01EB* + ID_PRODUCT_FROM_DATABASE=MFC-7320 + +usb:v04F9p01F4* + ID_PRODUCT_FROM_DATABASE=MFC-5890CN + +usb:v04F9p0223* + ID_PRODUCT_FROM_DATABASE=DCP-365CN + +usb:v04F9p0248* + ID_PRODUCT_FROM_DATABASE=DCP-7055 scanner/printer + +usb:v04F9p1000* + ID_PRODUCT_FROM_DATABASE=Printer + +usb:v04F9p1002* + ID_PRODUCT_FROM_DATABASE=Printer + +usb:v04F9p2002* + ID_PRODUCT_FROM_DATABASE=PTUSB Printing + +usb:v04F9p2004* + ID_PRODUCT_FROM_DATABASE=PT-2300/2310 p-Touch Laber Printer + +usb:v04F9p2015* + ID_PRODUCT_FROM_DATABASE=QL-500 P-touch label printer + +usb:v04F9p2016* + ID_PRODUCT_FROM_DATABASE=QL-550 P-touch label printer + +usb:v04F9p201A* + ID_PRODUCT_FROM_DATABASE=PT-18R P-touch label printer + +usb:v04F9p201B* + ID_PRODUCT_FROM_DATABASE=QL-650TD P-Touch Label Printer + +usb:v04F9p2027* + ID_PRODUCT_FROM_DATABASE=QL-560 P-Touch Label Printer + +usb:v04F9p2100* + ID_PRODUCT_FROM_DATABASE=Card Reader Writer + +usb:v04FA* + ID_VENDOR_FROM_DATABASE=Dallas Semiconductor + +usb:v04FAp2490* + ID_PRODUCT_FROM_DATABASE=DS1490F 2-in-1 Fob, 1-Wire adapter + +usb:v04FAp4201* + ID_PRODUCT_FROM_DATABASE=DS4201 Audio DAC + +usb:v04FB* + ID_VENDOR_FROM_DATABASE=Biostar Microtech International Corp. + +usb:v04FC* + ID_VENDOR_FROM_DATABASE=Sunplus Technology Co., Ltd + +usb:v04FCp0003* + ID_PRODUCT_FROM_DATABASE=CM1092 / Wintech CM-5098 Optical Mouse + +usb:v04FCp0005* + ID_PRODUCT_FROM_DATABASE=USB OpticalWheel Mouse + +usb:v04FCp0013* + ID_PRODUCT_FROM_DATABASE=ViewMate Desktop Mouse CC2201 + +usb:v04FCp0015* + ID_PRODUCT_FROM_DATABASE=ViewMate Desktop Mouse CC2201 + +usb:v04FCp00D3* + ID_PRODUCT_FROM_DATABASE=00052486 / Laser Mouse M1052 [hama] + +usb:v04FCp0171* + ID_PRODUCT_FROM_DATABASE=SPCA1527A/SPCA1528 SD card camera (Mass Storage mode) + +usb:v04FCp0232* + ID_PRODUCT_FROM_DATABASE=Fingerprint + +usb:v04FCp0538* + ID_PRODUCT_FROM_DATABASE=Wireless Optical Mouse 2.4G [Bright] + +usb:v04FCp0561* + ID_PRODUCT_FROM_DATABASE=Flexcam 100 + +usb:v04FCp05D8* + ID_PRODUCT_FROM_DATABASE=Wireless keyboard/mouse + +usb:v04FCp0C15* + ID_PRODUCT_FROM_DATABASE=SPIF215A SATA bridge + +usb:v04FCp0C25* + ID_PRODUCT_FROM_DATABASE=SATALink SPIF225A + +usb:v04FCp1528* + ID_PRODUCT_FROM_DATABASE=SPCA1527A/SPCA1528 SD card camera (webcam mode) + +usb:v04FCp1533* + ID_PRODUCT_FROM_DATABASE=Mass Storage + +usb:v04FCp2080* + ID_PRODUCT_FROM_DATABASE=ASUS Webcam + +usb:v04FCp500C* + ID_PRODUCT_FROM_DATABASE=CA500C Digital Camera + +usb:v04FCp504A* + ID_PRODUCT_FROM_DATABASE=Aiptek Mini PenCam 1.3 + +usb:v04FCp504B* + ID_PRODUCT_FROM_DATABASE=Aiptek Mega PockerCam 1.3/Maxell MaxPocket LE 1.3 + +usb:v04FCp5330* + ID_PRODUCT_FROM_DATABASE=Digitrex 2110 + +usb:v04FCp5331* + ID_PRODUCT_FROM_DATABASE=Vivitar Vivicam 10 + +usb:v04FCp5360* + ID_PRODUCT_FROM_DATABASE=Sunplus Generic Digital Camera + +usb:v04FCp5720* + ID_PRODUCT_FROM_DATABASE=Card Reader Driver + +usb:v04FCp7333* + ID_PRODUCT_FROM_DATABASE=Finet Technology Palmpix DC-85 + +usb:v04FCp757A* + ID_PRODUCT_FROM_DATABASE=Aiptek, MP315 MP3 Player + +usb:v04FCpFFFF* + ID_PRODUCT_FROM_DATABASE=PureDigital Ritz Disposable + +usb:v04FD* + ID_VENDOR_FROM_DATABASE=Soliton Systems, K.K. + +usb:v04FDp0003* + ID_PRODUCT_FROM_DATABASE=Smart Card Reader II + +usb:v04FE* + ID_VENDOR_FROM_DATABASE=PFU, Ltd + +usb:v04FF* + ID_VENDOR_FROM_DATABASE=E-CMOS Corp. + +usb:v0500* + ID_VENDOR_FROM_DATABASE=Siam United Hi-Tech + +usb:v0500p0001* + ID_PRODUCT_FROM_DATABASE=DART Keyboard Mouse + +usb:v0500p0002* + ID_PRODUCT_FROM_DATABASE=DART-2 Keyboard + +usb:v0501* + ID_VENDOR_FROM_DATABASE=Fujikura DDK, Ltd + +usb:v0502* + ID_VENDOR_FROM_DATABASE=Acer, Inc. + +usb:v0502p0001* + ID_PRODUCT_FROM_DATABASE=Handheld + +usb:v0502p0736* + ID_PRODUCT_FROM_DATABASE=Handheld + +usb:v0502p15B1* + ID_PRODUCT_FROM_DATABASE=PDA n311 + +usb:v0502p1631* + ID_PRODUCT_FROM_DATABASE=c10 Series + +usb:v0502p1632* + ID_PRODUCT_FROM_DATABASE=c20 Series + +usb:v0502p16E1* + ID_PRODUCT_FROM_DATABASE=n10 Handheld Sync + +usb:v0502p16E2* + ID_PRODUCT_FROM_DATABASE=n20 Pocket PC Sync + +usb:v0502p16E3* + ID_PRODUCT_FROM_DATABASE=n30 Handheld Sync + +usb:v0502p3202* + ID_PRODUCT_FROM_DATABASE=Liquid + +usb:v0502p3203* + ID_PRODUCT_FROM_DATABASE=Liquid (Debug mode) + +usb:v0502p3317* + ID_PRODUCT_FROM_DATABASE=Liquid + +usb:v0502p3325* + ID_PRODUCT_FROM_DATABASE=Iconia tablet A500 + +usb:v0502p3341* + ID_PRODUCT_FROM_DATABASE=Iconia tablet A500 + +usb:v0502pD001* + ID_PRODUCT_FROM_DATABASE=Divio NW801/DVC-V6+ Digital Camera + +usb:v0503* + ID_VENDOR_FROM_DATABASE=Hitachi America, Ltd + +usb:v0504* + ID_VENDOR_FROM_DATABASE=Hayes Microcomputer Products + +usb:v0506* + ID_VENDOR_FROM_DATABASE=3Com Corp. + +usb:v0506p009D* + ID_PRODUCT_FROM_DATABASE=HomeConnect Camera + +usb:v0506p00A0* + ID_PRODUCT_FROM_DATABASE=3CREB96 Bluetooth Adapter + +usb:v0506p00A1* + ID_PRODUCT_FROM_DATABASE=Bluetooth Device + +usb:v0506p00A2* + ID_PRODUCT_FROM_DATABASE=Bluetooth Device + +usb:v0506p00DF* + ID_PRODUCT_FROM_DATABASE=3Com Home Connect lite + +usb:v0506p0100* + ID_PRODUCT_FROM_DATABASE=HomeConnect ADSL Modem Driver + +usb:v0506p03E8* + ID_PRODUCT_FROM_DATABASE=3C19250 Ethernet [klsi] + +usb:v0506p0A01* + ID_PRODUCT_FROM_DATABASE=3CRSHEW696 Wireless Adapter + +usb:v0506p0A11* + ID_PRODUCT_FROM_DATABASE=3CRWE254G72 802.11g Adapter + +usb:v0506p11F8* + ID_PRODUCT_FROM_DATABASE=HomeConnect 3C460 + +usb:v0506p2922* + ID_PRODUCT_FROM_DATABASE=HomeConnect Cable Modem External with + +usb:v0506p3021* + ID_PRODUCT_FROM_DATABASE=U.S.Robotics 56000 Voice FaxModem Pro + +usb:v0506p4601* + ID_PRODUCT_FROM_DATABASE=3C460B 10/100 Ethernet Adapter + +usb:v0506pF002* + ID_PRODUCT_FROM_DATABASE=3CP4218 ADSL Modem (pre-init) + +usb:v0506pF003* + ID_PRODUCT_FROM_DATABASE=3CP4218 ADSL Modem + +usb:v0506pF100* + ID_PRODUCT_FROM_DATABASE=3CP4218 ADSL Modem (pre-init) + +usb:v0507* + ID_VENDOR_FROM_DATABASE=Hosiden Corp. + +usb:v0507p0011* + ID_PRODUCT_FROM_DATABASE=Konami ParaParaParadise Controller + +usb:v0508* + ID_VENDOR_FROM_DATABASE=Clarion Co., Ltd + +usb:v0509* + ID_VENDOR_FROM_DATABASE=Aztech Systems, Ltd + +usb:v0509p0801* + ID_PRODUCT_FROM_DATABASE=ADSL Modem + +usb:v0509p0802* + ID_PRODUCT_FROM_DATABASE=ADSL Modem (RFC1483) + +usb:v0509p0806* + ID_PRODUCT_FROM_DATABASE=DSL Modem + +usb:v0509p080F* + ID_PRODUCT_FROM_DATABASE=Binatone ADSL500 Modem Network Interface + +usb:v0509p0812* + ID_PRODUCT_FROM_DATABASE=Pirelli ADSL Modem Network Interface + +usb:v050A* + ID_VENDOR_FROM_DATABASE=Cinch Connectors + +usb:v050B* + ID_VENDOR_FROM_DATABASE=Cable System International + +usb:v050C* + ID_VENDOR_FROM_DATABASE=InnoMedia, Inc. + +usb:v050D* + ID_VENDOR_FROM_DATABASE=Belkin Components + +usb:v050Dp0004* + ID_PRODUCT_FROM_DATABASE=Direct Connect + +usb:v050Dp0012* + ID_PRODUCT_FROM_DATABASE=F8T012 Bluetooth Adapter + +usb:v050Dp0013* + ID_PRODUCT_FROM_DATABASE=F8T013 Bluetooth Adapter + +usb:v050Dp0017* + ID_PRODUCT_FROM_DATABASE=B8T017 Bluetooth+EDR 2.1 + +usb:v050Dp003A* + ID_PRODUCT_FROM_DATABASE=Universal Media Reader + +usb:v050Dp0050* + ID_PRODUCT_FROM_DATABASE=F5D6050 802.11b Wireless Adapter v2000 [Atmel at76c503a] + +usb:v050Dp0081* + ID_PRODUCT_FROM_DATABASE=F8T001v2 Bluetooth + +usb:v050Dp0083* + ID_PRODUCT_FROM_DATABASE=Bluetooth Device + +usb:v050Dp0084* + ID_PRODUCT_FROM_DATABASE=F8T003v2 Bluetooth + +usb:v050Dp0102* + ID_PRODUCT_FROM_DATABASE=Flip KVM + +usb:v050Dp0103* + ID_PRODUCT_FROM_DATABASE=F5U103 Serial Adapter [etek] + +usb:v050Dp0106* + ID_PRODUCT_FROM_DATABASE=VideoBus II Adapter, Video + +usb:v050Dp0108* + ID_PRODUCT_FROM_DATABASE=F1DE108B KVM + +usb:v050Dp0109* + ID_PRODUCT_FROM_DATABASE=F5U109/F5U409 PDA Adapter + +usb:v050Dp0115* + ID_PRODUCT_FROM_DATABASE=SCSI Adapter + +usb:v050Dp0119* + ID_PRODUCT_FROM_DATABASE=F5U120-PC Dual PS/2 Ports / F5U118-UNV ADB Adapter + +usb:v050Dp0121* + ID_PRODUCT_FROM_DATABASE=F5D5050 100Mbps Ethernet + +usb:v050Dp0122* + ID_PRODUCT_FROM_DATABASE=Ethernet Adapter + +usb:v050Dp0131* + ID_PRODUCT_FROM_DATABASE=Bluetooth Device with trace filter + +usb:v050Dp016A* + ID_PRODUCT_FROM_DATABASE=Bluetooth Mini Dongle + +usb:v050Dp0200* + ID_PRODUCT_FROM_DATABASE=Nostromo SpeedPad n52te Gaming Keyboard + +usb:v050Dp0201* + ID_PRODUCT_FROM_DATABASE=Peripheral Switch + +usb:v050Dp0208* + ID_PRODUCT_FROM_DATABASE=USBView II Video Adapter [nt1004] + +usb:v050Dp0210* + ID_PRODUCT_FROM_DATABASE=F5U228 Hi-Speed USB 2.0 DVD Creator + +usb:v050Dp0211* + ID_PRODUCT_FROM_DATABASE=F5U211 USB 2.0 15-in-1 Media Reader & Writer + +usb:v050Dp0224* + ID_PRODUCT_FROM_DATABASE=F5U224 USB 2.0 4-Port Hub + +usb:v050Dp0234* + ID_PRODUCT_FROM_DATABASE=F5U234 USB 2.0 4-Port Hub + +usb:v050Dp0237* + ID_PRODUCT_FROM_DATABASE=F5U237 USB 2.0 7-Port Hub + +usb:v050Dp0240* + ID_PRODUCT_FROM_DATABASE=F5U240 USB 2.0 CF Card Reader + +usb:v050Dp0249* + ID_PRODUCT_FROM_DATABASE=USB 2 Flash Media Device + +usb:v050Dp0257* + ID_PRODUCT_FROM_DATABASE=F5U257 Serial + +usb:v050Dp0304* + ID_PRODUCT_FROM_DATABASE=FSU304 USB 2.0 - 4 Ports Hub + +usb:v050Dp0307* + ID_PRODUCT_FROM_DATABASE=USB 2.0 - 7 ports Hub [FSU307] + +usb:v050Dp0409* + ID_PRODUCT_FROM_DATABASE=F5U409 Serial + +usb:v050Dp0551* + ID_PRODUCT_FROM_DATABASE=F6C550-AVR UPS + +usb:v050Dp0706* + ID_PRODUCT_FROM_DATABASE=2-N-1 USB 2.0 7-Port Hub (Lower half) + +usb:v050Dp0802* + ID_PRODUCT_FROM_DATABASE=Nostromo n40 Gamepad + +usb:v050Dp0803* + ID_PRODUCT_FROM_DATABASE=Nostromo 1745 GamePad + +usb:v050Dp0805* + ID_PRODUCT_FROM_DATABASE=Nostromo N50 GamePad + +usb:v050Dp0815* + ID_PRODUCT_FROM_DATABASE=Nostromo n52 HID SpeedPad Mouse Wheel + +usb:v050Dp0826* + ID_PRODUCT_FROM_DATABASE=ErgoFit Wireless Optical Mouse (HID) + +usb:v050Dp0980* + ID_PRODUCT_FROM_DATABASE=HID UPS Battery + +usb:v050Dp1004* + ID_PRODUCT_FROM_DATABASE=F9L1004 802.11n Surf N300 XR Wireless Adapter [Realtek RTL8192CU] + +usb:v050Dp1102* + ID_PRODUCT_FROM_DATABASE=F7D1102 N150/Surf Micro Wireless Adapter v1000 [Realtek RTL8188CUS] + +usb:v050Dp1103* + ID_PRODUCT_FROM_DATABASE=F9L1103 N750 DB 802.11abgn 2x3:3 [Ralink RT3573] + +usb:v050Dp11F2* + ID_PRODUCT_FROM_DATABASE=ISY Wireless Micro Adapter IWL 2000 [RTL8188CUS] + +usb:v050Dp1202* + ID_PRODUCT_FROM_DATABASE=F5U120-PC Parallel Printer Port + +usb:v050Dp1203* + ID_PRODUCT_FROM_DATABASE=F5U120-PC Serial Port + +usb:v050Dp2103* + ID_PRODUCT_FROM_DATABASE=F7D2102 802.11n N300 Micro Wireless Adapter v3000 [Realtek RTL8192CU] + +usb:v050Dp258A* + ID_PRODUCT_FROM_DATABASE=F5U258 Host to Host cable + +usb:v050Dp3101* + ID_PRODUCT_FROM_DATABASE=F1DF102U/F1DG102U Flip Hub + +usb:v050Dp3201* + ID_PRODUCT_FROM_DATABASE=F1DF102U/F1DG102U Flip KVM + +usb:v050Dp4050* + ID_PRODUCT_FROM_DATABASE=ZD1211B + +usb:v050Dp5055* + ID_PRODUCT_FROM_DATABASE=F5D5055 Gigabit Network Adapter [AX88xxx] + +usb:v050Dp6050* + ID_PRODUCT_FROM_DATABASE=F6D6050 802.11abgn Wireless Adapter [Broadcom BCM4323] + +usb:v050Dp6051* + ID_PRODUCT_FROM_DATABASE=F5D6051 802.11b Wireless Network Adapter [ZyDAS ZD1201] + +usb:v050Dp615A* + ID_PRODUCT_FROM_DATABASE=F7D4101 / F9L1101 802.11abgn Wireless Adapter [Broadcom BCM4323] + +usb:v050Dp7050* + ID_PRODUCT_FROM_DATABASE=F5D7050 Wireless G Adapter v1000/v2000 [Intersil ISL3887] + +usb:v050Dp7051* + ID_PRODUCT_FROM_DATABASE=F5D7051 802.11g Adapter v1000 [Broadcom 4320 USB] + +usb:v050Dp705A* + ID_PRODUCT_FROM_DATABASE=F5D7050 Wireless G Adapter v3000 [Ralink RT2571W] + +usb:v050Dp705B* + ID_PRODUCT_FROM_DATABASE=Wireless G Adapter + +usb:v050Dp705C* + ID_PRODUCT_FROM_DATABASE=F5D7050 Wireless G Adapter v4000 [Zydas ZD1211B] + +usb:v050Dp705E* + ID_PRODUCT_FROM_DATABASE=F5D7050 Wireless G Adapter v5000 [Realtek RTL8187B] + +usb:v050Dp706A* + ID_PRODUCT_FROM_DATABASE=2-N-1 7-Port Hub (Upper half) + +usb:v050Dp8053* + ID_PRODUCT_FROM_DATABASE=F5D8053 N Wireless USB Adapter v1000/v4000 [Ralink RT2870] + +usb:v050Dp805C* + ID_PRODUCT_FROM_DATABASE=F5D8053 N Wireless Adapter v3000 [Ralink RT2870] + +usb:v050Dp805E* + ID_PRODUCT_FROM_DATABASE=F5D8053 N Wireless USB Adapter v5000 [Realtek RTL8192U] + +usb:v050Dp815C* + ID_PRODUCT_FROM_DATABASE=F5D8053 N Wireless USB Adapter v3000 [Ralink RT2870] + +usb:v050Dp815F* + ID_PRODUCT_FROM_DATABASE=F5D8053 N Wireless USB Adapter v6000 [Realtek RTL8192SU] + +usb:v050Dp825A* + ID_PRODUCT_FROM_DATABASE=F5D8055 N+ Wireless Adapter v1000 [Ralink RT2870] + +usb:v050Dp825B* + ID_PRODUCT_FROM_DATABASE=F5D8055 N+ Wireless Adapter v2000 [Ralink RT3072] + +usb:v050Dp845A* + ID_PRODUCT_FROM_DATABASE=F7D2101 802.11n Surf & Share Wireless Adapter v1000 [Realtek RTL8192SU] + +usb:v050Dp905B* + ID_PRODUCT_FROM_DATABASE=F5D9050 Wireless G+ MIMO Network Adapter v3000 [Ralink RT2573] + +usb:v050Dp905C* + ID_PRODUCT_FROM_DATABASE=F5D9050 Wireless G+ MIMO Network Adapter v4000 [Ralink RT2573] + +usb:v050Dp935A* + ID_PRODUCT_FROM_DATABASE=F6D4050 N150 Enhanced Wireless Network Adapter v1000 [Ralink RT3070] + +usb:v050Dp935B* + ID_PRODUCT_FROM_DATABASE=F6D4050 N150 Enhanced Wireless Network Adapter v2000 [Ralink RT3070] + +usb:v050Dp945A* + ID_PRODUCT_FROM_DATABASE=F7D1101 v1 Basic Wireless Adapter [Realtek RTL8188SU] + +usb:v050Dp945B* + ID_PRODUCT_FROM_DATABASE=F7D1101 v2 Basic Wireless Adapter [Ralink RT3370] + +usb:v050DpD321* + ID_PRODUCT_FROM_DATABASE=Dynex DX-NUSB 802.11bgn Wireless Adapter [Broadcom BCM43231] + +usb:v050E* + ID_VENDOR_FROM_DATABASE=Neon Technology, Inc. + +usb:v050F* + ID_VENDOR_FROM_DATABASE=KC Technology, Inc. + +usb:v050Fp0001* + ID_PRODUCT_FROM_DATABASE=Hub + +usb:v050Fp0003* + ID_PRODUCT_FROM_DATABASE=KC82C160S Hub + +usb:v050Fp0180* + ID_PRODUCT_FROM_DATABASE=KC-180 IrDA Dongle + +usb:v050Fp0190* + ID_PRODUCT_FROM_DATABASE=KC2190 USB Host-to-Host cable + +usb:v0510* + ID_VENDOR_FROM_DATABASE=Sejin Electron, Inc. + +usb:v0510p0001* + ID_PRODUCT_FROM_DATABASE=Keyboard + +usb:v0510p1000* + ID_PRODUCT_FROM_DATABASE=Keyboard with PS/2 Mouse Port + +usb:v0510pE001* + ID_PRODUCT_FROM_DATABASE=Mouse + +usb:v0511* + ID_VENDOR_FROM_DATABASE=N'Able (DataBook) Technologies, Inc. + +usb:v0511p002B* + ID_PRODUCT_FROM_DATABASE=AOC DVB + +usb:v0512* + ID_VENDOR_FROM_DATABASE=Hualon Microelectronics Corp. + +usb:v0513* + ID_VENDOR_FROM_DATABASE=digital-X, Inc. + +usb:v0514* + ID_VENDOR_FROM_DATABASE=FCI Electronics + +usb:v0515* + ID_VENDOR_FROM_DATABASE=ACTC + +usb:v0516* + ID_VENDOR_FROM_DATABASE=Longwell Electronics + +usb:v0517* + ID_VENDOR_FROM_DATABASE=Butterfly Communications + +usb:v0518* + ID_VENDOR_FROM_DATABASE=EzKEY Corp. + +usb:v0518p0001* + ID_PRODUCT_FROM_DATABASE=USB to PS2 Adaptor v1.09 + +usb:v0518p0002* + ID_PRODUCT_FROM_DATABASE=EZ-9900C Keyboard + +usb:v0519* + ID_VENDOR_FROM_DATABASE=Star Micronics Co., Ltd + +usb:v0519p0003* + ID_PRODUCT_FROM_DATABASE=TSP100ECO/TSP100II + +usb:v0519pC002* + ID_PRODUCT_FROM_DATABASE=Xlive Bluetooth XBM-100S MP3 Player + +usb:v051A* + ID_VENDOR_FROM_DATABASE=WYSE Technology + +usb:v051ApA005* + ID_PRODUCT_FROM_DATABASE=Smart Display Version 9973 + +usb:v051B* + ID_VENDOR_FROM_DATABASE=Silicon Graphics + +usb:v051C* + ID_VENDOR_FROM_DATABASE=Shuttle, Inc. + +usb:v051Cp0005* + ID_PRODUCT_FROM_DATABASE=VFD Module + +usb:v051CpC001* + ID_PRODUCT_FROM_DATABASE=eHome Infrared Receiver + +usb:v051CpC002* + ID_PRODUCT_FROM_DATABASE=eHome Infrared Receiver + +usb:v051D* + ID_VENDOR_FROM_DATABASE=American Power Conversion + +usb:v051Dp0001* + ID_PRODUCT_FROM_DATABASE=UPS + +usb:v051Dp0002* + ID_PRODUCT_FROM_DATABASE=Uninterruptible Power Supply + +usb:v051Dp0003* + ID_PRODUCT_FROM_DATABASE=UPS + +usb:v051E* + ID_VENDOR_FROM_DATABASE=Scientific Atlanta, Inc. + +usb:v051F* + ID_VENDOR_FROM_DATABASE=IO Systems (Elite Electronics), Inc. + +usb:v0520* + ID_VENDOR_FROM_DATABASE=Taiwan Semiconductor Manufacturing Co. + +usb:v0521* + ID_VENDOR_FROM_DATABASE=Airborn Connectors + +usb:v0522* + ID_VENDOR_FROM_DATABASE=Advanced Connectek, Inc. + +usb:v0523* + ID_VENDOR_FROM_DATABASE=ATEN GmbH + +usb:v0524* + ID_VENDOR_FROM_DATABASE=Sola Electronics + +usb:v0525* + ID_VENDOR_FROM_DATABASE=Netchip Technology, Inc. + +usb:v0525p100D* + ID_PRODUCT_FROM_DATABASE=RFMD Bluetooth Device + +usb:v0525p1080* + ID_PRODUCT_FROM_DATABASE=NET1080 USB-USB Bridge + +usb:v0525p1200* + ID_PRODUCT_FROM_DATABASE=SSDC Adapter II + +usb:v0525p1265* + ID_PRODUCT_FROM_DATABASE=File-backed Storage Gadget + +usb:v0525pA0F0* + ID_PRODUCT_FROM_DATABASE=Cambridge Electronic Devices Power1401 mk 2 + +usb:v0525pA140* + ID_PRODUCT_FROM_DATABASE=USB Clik! 40 + +usb:v0525pA141* + ID_PRODUCT_FROM_DATABASE=(OME) PocketZip 40 MP3 Player Driver + +usb:v0525pA220* + ID_PRODUCT_FROM_DATABASE=GVC Bluetooth Wireless Adapter + +usb:v0525pA4A0* + ID_PRODUCT_FROM_DATABASE=Linux-USB "Gadget Zero" + +usb:v0525pA4A1* + ID_PRODUCT_FROM_DATABASE=Linux-USB Ethernet Gadget + +usb:v0525pA4A2* + ID_PRODUCT_FROM_DATABASE=Linux-USB Ethernet/RNDIS Gadget + +usb:v0525pA4A3* + ID_PRODUCT_FROM_DATABASE=Linux-USB user-mode isochronous source/sink + +usb:v0525pA4A4* + ID_PRODUCT_FROM_DATABASE=Linux-USB user-mode bulk source/sink + +usb:v0525pA4A5* + ID_PRODUCT_FROM_DATABASE=Linux-USB File Storage Gadget + +usb:v0525pA4A6* + ID_PRODUCT_FROM_DATABASE=Linux-USB Serial Gadget + +usb:v0525pA4A7* + ID_PRODUCT_FROM_DATABASE=Linux-USB Serial Gadget (CDC ACM mode) + +usb:v0525pA4A8* + ID_PRODUCT_FROM_DATABASE=Linux-USB Printer Gadget + +usb:v0525pA4A9* + ID_PRODUCT_FROM_DATABASE=Linux-USB OBEX Gadget + +usb:v0525pA4AA* + ID_PRODUCT_FROM_DATABASE=Linux-USB CDC Composite Gadge (Ethernet and ACM) + +usb:v0526* + ID_VENDOR_FROM_DATABASE=Temic MHS S.A. + +usb:v0527* + ID_VENDOR_FROM_DATABASE=ALTRA + +usb:v0528* + ID_VENDOR_FROM_DATABASE=ATI Technologies, Inc. + +usb:v0528p7561* + ID_PRODUCT_FROM_DATABASE=TV Wonder + +usb:v0528p7562* + ID_PRODUCT_FROM_DATABASE=TV Wonder, Edition (FN5) + +usb:v0528p7563* + ID_PRODUCT_FROM_DATABASE=TV Wonder, Edition (FI) + +usb:v0528p7564* + ID_PRODUCT_FROM_DATABASE=TV Wonder, Edition (FQ) + +usb:v0528p7565* + ID_PRODUCT_FROM_DATABASE=TV Wonder, Edition (NTSC+) + +usb:v0528p7566* + ID_PRODUCT_FROM_DATABASE=TV Wonder, Edition (FN5) + +usb:v0528p7567* + ID_PRODUCT_FROM_DATABASE=TV Wonder, Edition (FI) + +usb:v0528p7568* + ID_PRODUCT_FROM_DATABASE=TV Wonder, Edition (FQ) + +usb:v0528p7569* + ID_PRODUCT_FROM_DATABASE=Live! Pro (A) + +usb:v0528p756A* + ID_PRODUCT_FROM_DATABASE=Live! Pro Audio (O) + +usb:v0529* + ID_VENDOR_FROM_DATABASE=Aladdin Knowledge Systems + +usb:v0529p0001* + ID_PRODUCT_FROM_DATABASE=HASP v0.06 + +usb:v0529p030B* + ID_PRODUCT_FROM_DATABASE=eToken R1 v3.1.3.x + +usb:v0529p0313* + ID_PRODUCT_FROM_DATABASE=eToken R1 v3.2.3.x + +usb:v0529p031B* + ID_PRODUCT_FROM_DATABASE=eToken R1 v3.3.3.x + +usb:v0529p0323* + ID_PRODUCT_FROM_DATABASE=eToken R1 v3.4.3.x + +usb:v0529p0412* + ID_PRODUCT_FROM_DATABASE=eToken R2 v2.2.4.x + +usb:v0529p041A* + ID_PRODUCT_FROM_DATABASE=eToken R2 v2.2.4.x + +usb:v0529p0422* + ID_PRODUCT_FROM_DATABASE=eToken R2 v2.4.4.x + +usb:v0529p042A* + ID_PRODUCT_FROM_DATABASE=eToken R2 v2.5.4.x + +usb:v0529p050C* + ID_PRODUCT_FROM_DATABASE=eToken Pro v4.1.5.x + +usb:v0529p0514* + ID_PRODUCT_FROM_DATABASE=eToken Pro v4.2.5.4 + +usb:v0529p0600* + ID_PRODUCT_FROM_DATABASE=eToken Pro 64k (4.2) + +usb:v0529p0620* + ID_PRODUCT_FROM_DATABASE=Token JC + +usb:v052A* + ID_VENDOR_FROM_DATABASE=Crescent Heart Software + +usb:v052B* + ID_VENDOR_FROM_DATABASE=Tekom Technologies, Inc. + +usb:v052Bp0102* + ID_PRODUCT_FROM_DATABASE=Ca508A HP1020 Camera v.1.3.1.6 + +usb:v052Bp0801* + ID_PRODUCT_FROM_DATABASE=Yakumo MegaImage 37 + +usb:v052Bp1512* + ID_PRODUCT_FROM_DATABASE=Yakumo MegaImage IV + +usb:v052Bp1513* + ID_PRODUCT_FROM_DATABASE=Aosta CX100 Webcam + +usb:v052Bp1514* + ID_PRODUCT_FROM_DATABASE=Aosta CX100 Webcam Storage + +usb:v052Bp1905* + ID_PRODUCT_FROM_DATABASE=Yakumo MegaImage 47 + +usb:v052Bp1911* + ID_PRODUCT_FROM_DATABASE=Yakumo MegaImage 47 SL + +usb:v052Bp2202* + ID_PRODUCT_FROM_DATABASE=WDM Still Image Capture + +usb:v052Bp2203* + ID_PRODUCT_FROM_DATABASE=Sound Vision Stream Driver + +usb:v052Bp3A06* + ID_PRODUCT_FROM_DATABASE=DigiLife DDV-5120A + +usb:v052BpD001* + ID_PRODUCT_FROM_DATABASE=P35U Camera Capture + +usb:v052C* + ID_VENDOR_FROM_DATABASE=Canon Information Systems, Inc. + +usb:v052D* + ID_VENDOR_FROM_DATABASE=Avid Electronics Corp. + +usb:v052E* + ID_VENDOR_FROM_DATABASE=Standard Microsystems Corp. + +usb:v052F* + ID_VENDOR_FROM_DATABASE=Unicore Software, Inc. + +usb:v0530* + ID_VENDOR_FROM_DATABASE=American Microsystems, Inc. + +usb:v0531* + ID_VENDOR_FROM_DATABASE=Wacom Technology Corp. + +usb:v0532* + ID_VENDOR_FROM_DATABASE=Systech Corp. + +usb:v0533* + ID_VENDOR_FROM_DATABASE=Alcatel Mobile Phones + +usb:v0534* + ID_VENDOR_FROM_DATABASE=Motorola, Inc. + +usb:v0535* + ID_VENDOR_FROM_DATABASE=LIH TZU Electric Co., Ltd + +usb:v0536* + ID_VENDOR_FROM_DATABASE=Hand Held Products (Welch Allyn, Inc.) + +usb:v0536p01A0* + ID_PRODUCT_FROM_DATABASE=PDT + +usb:v0537* + ID_VENDOR_FROM_DATABASE=Inventec Corp. + +usb:v0538* + ID_VENDOR_FROM_DATABASE=Caldera International, Inc. (SCO) + +usb:v0539* + ID_VENDOR_FROM_DATABASE=Shyh Shiun Terminals Co., Ltd + +usb:v053A* + ID_VENDOR_FROM_DATABASE=PrehKeyTec GmbH + +usb:v053Ap0B00* + ID_PRODUCT_FROM_DATABASE=Hub + +usb:v053B* + ID_VENDOR_FROM_DATABASE=Global Village Communication + +usb:v053C* + ID_VENDOR_FROM_DATABASE=Institut of Microelectronic & Mechatronic Systems + +usb:v053D* + ID_VENDOR_FROM_DATABASE=Silicon Architect + +usb:v053E* + ID_VENDOR_FROM_DATABASE=Mobility Electronics + +usb:v053F* + ID_VENDOR_FROM_DATABASE=Synopsys, Inc. + +usb:v0540* + ID_VENDOR_FROM_DATABASE=UniAccess AB + +usb:v0540p0101* + ID_PRODUCT_FROM_DATABASE=Panache Surf ISDN TA + +usb:v0541* + ID_VENDOR_FROM_DATABASE=Sirf Technology, Inc. + +usb:v0543* + ID_VENDOR_FROM_DATABASE=ViewSonic Corp. + +usb:v0543p00FE* + ID_PRODUCT_FROM_DATABASE=G773 Monitor Hub + +usb:v0543p00FF* + ID_PRODUCT_FROM_DATABASE=P815 Monitor Hub + +usb:v0543p0BF2* + ID_PRODUCT_FROM_DATABASE=airpanel V150 Wireless Smart Display + +usb:v0543p0BF3* + ID_PRODUCT_FROM_DATABASE=airpanel V110 Wireless Smart Display + +usb:v0543p0ED9* + ID_PRODUCT_FROM_DATABASE=Color Pocket PC V35 + +usb:v0543p0F01* + ID_PRODUCT_FROM_DATABASE=airsync Wi-Fi Wireless Adapter + +usb:v0543p1527* + ID_PRODUCT_FROM_DATABASE=Color Pocket PC V36 + +usb:v0543p1529* + ID_PRODUCT_FROM_DATABASE=Color Pocket PC V37 + +usb:v0543p152B* + ID_PRODUCT_FROM_DATABASE=Color Pocket PC V38 + +usb:v0543p152E* + ID_PRODUCT_FROM_DATABASE=Pocket PC + +usb:v0543p1921* + ID_PRODUCT_FROM_DATABASE=Communicator Pocket PC + +usb:v0543p1922* + ID_PRODUCT_FROM_DATABASE=Smartphone + +usb:v0543p1923* + ID_PRODUCT_FROM_DATABASE=Pocket PC V30 + +usb:v0543p1A11* + ID_PRODUCT_FROM_DATABASE=Wireless 802.11g Adapter + +usb:v0543p1E60* + ID_PRODUCT_FROM_DATABASE=TA310 - ATSC/NTSC/PAL Driver(PCM4) + +usb:v0543p4153* + ID_PRODUCT_FROM_DATABASE=ViewSonic G773 Control (?) + +usb:v0544* + ID_VENDOR_FROM_DATABASE=Cristie Electronics, Ltd + +usb:v0545* + ID_VENDOR_FROM_DATABASE=Xirlink, Inc. + +usb:v0545p7333* + ID_PRODUCT_FROM_DATABASE=Trution Web Camera + +usb:v0545p8002* + ID_PRODUCT_FROM_DATABASE=IBM NetCamera + +usb:v0545p8009* + ID_PRODUCT_FROM_DATABASE=Veo PC Camera + +usb:v0545p800C* + ID_PRODUCT_FROM_DATABASE=Veo Stingray + +usb:v0545p800D* + ID_PRODUCT_FROM_DATABASE=Veo PC Camera + +usb:v0545p8080* + ID_PRODUCT_FROM_DATABASE=IBM C-It Webcam + +usb:v0545p808A* + ID_PRODUCT_FROM_DATABASE=Veo PC Camera + +usb:v0545p808B* + ID_PRODUCT_FROM_DATABASE=Veo Stingray + +usb:v0545p808D* + ID_PRODUCT_FROM_DATABASE=Veo PC Camera + +usb:v0545p810A* + ID_PRODUCT_FROM_DATABASE=Veo Advanced Connect Webcam + +usb:v0545p810B* + ID_PRODUCT_FROM_DATABASE=Veo PC Camera + +usb:v0545p810C* + ID_PRODUCT_FROM_DATABASE=Veo PC Camera + +usb:v0545p8135* + ID_PRODUCT_FROM_DATABASE=Veo Mobile/Advanced Web Camera + +usb:v0545p813A* + ID_PRODUCT_FROM_DATABASE=Veo PC Camera + +usb:v0545p813B* + ID_PRODUCT_FROM_DATABASE=Veo PC Camera + +usb:v0545p813C* + ID_PRODUCT_FROM_DATABASE=Veo Mobile/Advanced Web Camera + +usb:v0545p8333* + ID_PRODUCT_FROM_DATABASE=Veo Stingray/Connect Web Camera + +usb:v0545p888C* + ID_PRODUCT_FROM_DATABASE=eVision 123 digital camera + +usb:v0545p888D* + ID_PRODUCT_FROM_DATABASE=eVision 123 digital camera + +usb:v0546* + ID_VENDOR_FROM_DATABASE=Polaroid Corp. + +usb:v0546p0DAF* + ID_PRODUCT_FROM_DATABASE=PDC 2300Z + +usb:v0546p1BED* + ID_PRODUCT_FROM_DATABASE=PDC 1320 Camera + +usb:v0546p3097* + ID_PRODUCT_FROM_DATABASE=PDC 310 + +usb:v0546p3155* + ID_PRODUCT_FROM_DATABASE=PDC 3070 Camera + +usb:v0546p3187* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v0546p3191* + ID_PRODUCT_FROM_DATABASE=Ion 80 Camera + +usb:v0546p3273* + ID_PRODUCT_FROM_DATABASE=PDC 2030 Camera + +usb:v0546p3304* + ID_PRODUCT_FROM_DATABASE=a500 Digital Camera + +usb:v0546pDCCF* + ID_PRODUCT_FROM_DATABASE=Sound Vision Stream Driver + +usb:v0547* + ID_VENDOR_FROM_DATABASE=Anchor Chips, Inc. + +usb:v0547p0001* + ID_PRODUCT_FROM_DATABASE=ICSI Bluetooth Device + +usb:v0547p1002* + ID_PRODUCT_FROM_DATABASE=Python2 WDM Encoder + +usb:v0547p1006* + ID_PRODUCT_FROM_DATABASE=Hantek DSO-2100 UF + +usb:v0547p2131* + ID_PRODUCT_FROM_DATABASE=AN2131 EZUSB Microcontroller + +usb:v0547p2235* + ID_PRODUCT_FROM_DATABASE=AN2235 EZUSB-FX Microcontroller + +usb:v0547p2710* + ID_PRODUCT_FROM_DATABASE=EZ-Link Loader (EZLNKLDR.SYS) + +usb:v0547p2720* + ID_PRODUCT_FROM_DATABASE=AN2720 USB-USB Bridge + +usb:v0547p2727* + ID_PRODUCT_FROM_DATABASE=Xircom PGUNET USB-USB Bridge + +usb:v0547p2750* + ID_PRODUCT_FROM_DATABASE=EZ-Link (EZLNKUSB.SYS) + +usb:v0547p2810* + ID_PRODUCT_FROM_DATABASE=Cypress ATAPI Bridge + +usb:v0547p7777* + ID_PRODUCT_FROM_DATABASE=Bluetooth Device + +usb:v0547p9999* + ID_PRODUCT_FROM_DATABASE=AN2131 uninitialized (?) + +usb:v0548* + ID_VENDOR_FROM_DATABASE=Tyan Computer Corp. + +usb:v0548p1005* + ID_PRODUCT_FROM_DATABASE=EZ Cart II GameBoy Flash Programmer + +usb:v0549* + ID_VENDOR_FROM_DATABASE=Pixera Corp. + +usb:v054A* + ID_VENDOR_FROM_DATABASE=Fujitsu Microelectronics, Inc. + +usb:v054B* + ID_VENDOR_FROM_DATABASE=New Media Corp. + +usb:v054C* + ID_VENDOR_FROM_DATABASE=Sony Corp. + +usb:v054Cp0001* + ID_PRODUCT_FROM_DATABASE=HUB + +usb:v054Cp0002* + ID_PRODUCT_FROM_DATABASE=Standard HUB + +usb:v054Cp0010* + ID_PRODUCT_FROM_DATABASE=DSC-S30/S70/S75/F505V/F505/FD92/W1 Cybershot/Mavica Digital Camera + +usb:v054Cp0014* + ID_PRODUCT_FROM_DATABASE=Nogatech USBVision (SY) + +usb:v054Cp0022* + ID_PRODUCT_FROM_DATABASE=Storage Adapter V2 (TPP) + +usb:v054Cp0023* + ID_PRODUCT_FROM_DATABASE=CD Writer + +usb:v054Cp0024* + ID_PRODUCT_FROM_DATABASE=Mavica CD-1000 Camera + +usb:v054Cp0025* + ID_PRODUCT_FROM_DATABASE=NW-MS7 Walkman MemoryStick Reader + +usb:v054Cp002B* + ID_PRODUCT_FROM_DATABASE=Portable USB Harddrive V2 + +usb:v054Cp002C* + ID_PRODUCT_FROM_DATABASE=USB Floppy Disk Drive + +usb:v054Cp002D* + ID_PRODUCT_FROM_DATABASE=MSAC-US1 MemoryStick Reader + +usb:v054Cp002E* + ID_PRODUCT_FROM_DATABASE=HandyCam MemoryStick Reader + +usb:v054Cp0030* + ID_PRODUCT_FROM_DATABASE=Storage Adapter V2 (TPP) + +usb:v054Cp0032* + ID_PRODUCT_FROM_DATABASE=MemoryStick MSC-U01 Reader + +usb:v054Cp0035* + ID_PRODUCT_FROM_DATABASE=Network Walkman (E) + +usb:v054Cp0036* + ID_PRODUCT_FROM_DATABASE=Net MD + +usb:v054Cp0037* + ID_PRODUCT_FROM_DATABASE=MG Memory Stick Reader/Writer + +usb:v054Cp0038* + ID_PRODUCT_FROM_DATABASE=Clie PEG-S300/D PalmOS PDA + +usb:v054Cp0039* + ID_PRODUCT_FROM_DATABASE=Network Walkman (MS) + +usb:v054Cp003C* + ID_PRODUCT_FROM_DATABASE=VAIO-MX LCD Control + +usb:v054Cp0045* + ID_PRODUCT_FROM_DATABASE=Digital Imaging Video + +usb:v054Cp0046* + ID_PRODUCT_FROM_DATABASE=Network Walkman + +usb:v054Cp004A* + ID_PRODUCT_FROM_DATABASE=Memory Stick Hi-Fi System + +usb:v054Cp004B* + ID_PRODUCT_FROM_DATABASE=Memory Stick Reader/Writer + +usb:v054Cp004E* + ID_PRODUCT_FROM_DATABASE=DSC-xxx (ptp) + +usb:v054Cp0056* + ID_PRODUCT_FROM_DATABASE=MG Memory Stick Reader/Writer + +usb:v054Cp0058* + ID_PRODUCT_FROM_DATABASE=Clie PEG-N7x0C PalmOS PDA Mass Storage + +usb:v054Cp0066* + ID_PRODUCT_FROM_DATABASE=Clie PEG-N7x0C/PEG-T425 PalmOS PDA Serial + +usb:v054Cp0067* + ID_PRODUCT_FROM_DATABASE=CMR-PC3 Webcam + +usb:v054Cp0069* + ID_PRODUCT_FROM_DATABASE=Memorystick MSC-U03 Reader + +usb:v054Cp006C* + ID_PRODUCT_FROM_DATABASE=FeliCa S310 [PaSoRi] + +usb:v054Cp006D* + ID_PRODUCT_FROM_DATABASE=Clie PEG-T425 PDA Mass Storage + +usb:v054Cp006F* + ID_PRODUCT_FROM_DATABASE=Network Walkman (EV) + +usb:v054Cp0073* + ID_PRODUCT_FROM_DATABASE=Storage CRX1750U + +usb:v054Cp0075* + ID_PRODUCT_FROM_DATABASE=Net MD + +usb:v054Cp0076* + ID_PRODUCT_FROM_DATABASE=Storage Adapter ACR-U20 + +usb:v054Cp007C* + ID_PRODUCT_FROM_DATABASE=Net MD + +usb:v054Cp007F* + ID_PRODUCT_FROM_DATABASE=IC Recorder (MS) + +usb:v054Cp0080* + ID_PRODUCT_FROM_DATABASE=Net MD + +usb:v054Cp0081* + ID_PRODUCT_FROM_DATABASE=Net MD + +usb:v054Cp0084* + ID_PRODUCT_FROM_DATABASE=Net MD + +usb:v054Cp0085* + ID_PRODUCT_FROM_DATABASE=Net MD + +usb:v054Cp0086* + ID_PRODUCT_FROM_DATABASE=Net MD + +usb:v054Cp008B* + ID_PRODUCT_FROM_DATABASE=Micro Vault 64M Mass Storage + +usb:v054Cp0095* + ID_PRODUCT_FROM_DATABASE=Clie s360 + +usb:v054Cp0099* + ID_PRODUCT_FROM_DATABASE=Clie NR70 PDA Mass Storage + +usb:v054Cp009A* + ID_PRODUCT_FROM_DATABASE=Clie NR70 PDA Serial + +usb:v054Cp00AB* + ID_PRODUCT_FROM_DATABASE=Visual Communication Camera (PCGA-UVC10) + +usb:v054Cp00AF* + ID_PRODUCT_FROM_DATABASE=DPP-EX Series Digital Photo Printer + +usb:v054Cp00BF* + ID_PRODUCT_FROM_DATABASE=IC Recorder (S) + +usb:v054Cp00C0* + ID_PRODUCT_FROM_DATABASE=Handycam DCR-30 + +usb:v054Cp00C6* + ID_PRODUCT_FROM_DATABASE=Net MD + +usb:v054Cp00C7* + ID_PRODUCT_FROM_DATABASE=Net MD + +usb:v054Cp00C8* + ID_PRODUCT_FROM_DATABASE=MZ-N710 Minidisc Walkman + +usb:v054Cp00C9* + ID_PRODUCT_FROM_DATABASE=Net MD + +usb:v054Cp00CA* + ID_PRODUCT_FROM_DATABASE=MZ-DN430 Minidisc Walkman + +usb:v054Cp00CB* + ID_PRODUCT_FROM_DATABASE=MSAC-US20 Memory Stick Reader + +usb:v054Cp00DA* + ID_PRODUCT_FROM_DATABASE=Clie nx60 + +usb:v054Cp00E8* + ID_PRODUCT_FROM_DATABASE=Network Walkman (MS) + +usb:v054Cp00E9* + ID_PRODUCT_FROM_DATABASE=Handheld + +usb:v054Cp00EB* + ID_PRODUCT_FROM_DATABASE=Net MD + +usb:v054Cp0101* + ID_PRODUCT_FROM_DATABASE=Net MD + +usb:v054Cp0103* + ID_PRODUCT_FROM_DATABASE=IC Recorder (ST) + +usb:v054Cp0105* + ID_PRODUCT_FROM_DATABASE=Micro Vault Hub + +usb:v054Cp0107* + ID_PRODUCT_FROM_DATABASE=VCC-U01 Visual Communication Camera + +usb:v054Cp0110* + ID_PRODUCT_FROM_DATABASE=Digital Imaging Video + +usb:v054Cp0113* + ID_PRODUCT_FROM_DATABASE=Net MD + +usb:v054Cp0116* + ID_PRODUCT_FROM_DATABASE=IC Recorder (P) + +usb:v054Cp0144* + ID_PRODUCT_FROM_DATABASE=Clie PEG-TH55 PDA + +usb:v054Cp0147* + ID_PRODUCT_FROM_DATABASE=Visual Communication Camera (PCGA-UVC11) + +usb:v054Cp014C* + ID_PRODUCT_FROM_DATABASE=Aiwa AM-NX9 Net MD Music Recorder MDLP + +usb:v054Cp014D* + ID_PRODUCT_FROM_DATABASE=Memory Stick Reader/Writer + +usb:v054Cp0154* + ID_PRODUCT_FROM_DATABASE=Eyetoy Audio Device + +usb:v054Cp015F* + ID_PRODUCT_FROM_DATABASE=IC Recorder (BM) + +usb:v054Cp0169* + ID_PRODUCT_FROM_DATABASE=Clie PEG-TJ35 PDA Serial + +usb:v054Cp016A* + ID_PRODUCT_FROM_DATABASE=Clie PEG-TJ35 PDA Mass Storage + +usb:v054Cp016B* + ID_PRODUCT_FROM_DATABASE=Mobile HDD + +usb:v054Cp016D* + ID_PRODUCT_FROM_DATABASE=IC Recorder (SX) + +usb:v054Cp016E* + ID_PRODUCT_FROM_DATABASE=DPP-EX50 Digital Photo Printer + +usb:v054Cp0171* + ID_PRODUCT_FROM_DATABASE=Fingerprint Sensor 3500 + +usb:v054Cp017E* + ID_PRODUCT_FROM_DATABASE=Net MD + +usb:v054Cp017F* + ID_PRODUCT_FROM_DATABASE=Hi-MD WALKMAN + +usb:v054Cp0180* + ID_PRODUCT_FROM_DATABASE=Net MD + +usb:v054Cp0181* + ID_PRODUCT_FROM_DATABASE=Hi-MD WALKMAN + +usb:v054Cp0182* + ID_PRODUCT_FROM_DATABASE=Net MD + +usb:v054Cp0183* + ID_PRODUCT_FROM_DATABASE=Hi-MD WALKMAN + +usb:v054Cp0184* + ID_PRODUCT_FROM_DATABASE=Net MD + +usb:v054Cp0185* + ID_PRODUCT_FROM_DATABASE=Hi-MD WALKMAN + +usb:v054Cp0186* + ID_PRODUCT_FROM_DATABASE=Net MD + +usb:v054Cp0187* + ID_PRODUCT_FROM_DATABASE=Hi-MD MZ-NH600 WALKMAN + +usb:v054Cp0188* + ID_PRODUCT_FROM_DATABASE=Net MD + +usb:v054Cp018A* + ID_PRODUCT_FROM_DATABASE=Net MD + +usb:v054Cp018B* + ID_PRODUCT_FROM_DATABASE=Hi-MD SOUND GATE + +usb:v054Cp019E* + ID_PRODUCT_FROM_DATABASE=Micro Vault 1.0G Mass Storage + +usb:v054Cp01AD* + ID_PRODUCT_FROM_DATABASE=ATRAC HDD PA + +usb:v054Cp01BB* + ID_PRODUCT_FROM_DATABASE=FeliCa S320 [PaSoRi] + +usb:v054Cp01BD* + ID_PRODUCT_FROM_DATABASE=MRW62E Multi-Card Reader/Writer + +usb:v054Cp01C3* + ID_PRODUCT_FROM_DATABASE=NW-E55 Network Walkman + +usb:v054Cp01C6* + ID_PRODUCT_FROM_DATABASE=MEMORY P-AUDIO + +usb:v054Cp01C7* + ID_PRODUCT_FROM_DATABASE=Printing Support + +usb:v054Cp01C8* + ID_PRODUCT_FROM_DATABASE=PSP Type A + +usb:v054Cp01C9* + ID_PRODUCT_FROM_DATABASE=PSP Type B + +usb:v054Cp01D0* + ID_PRODUCT_FROM_DATABASE=DVD+RW External Drive DRU-700A + +usb:v054Cp01D5* + ID_PRODUCT_FROM_DATABASE=IC RECORDER + +usb:v054Cp01DE* + ID_PRODUCT_FROM_DATABASE=VRD-VC10 [Video Capture] + +usb:v054Cp01E9* + ID_PRODUCT_FROM_DATABASE=Net MD + +usb:v054Cp01EA* + ID_PRODUCT_FROM_DATABASE=Hi-MD WALKMAN + +usb:v054Cp01EE* + ID_PRODUCT_FROM_DATABASE=IC RECORDER + +usb:v054Cp01FA* + ID_PRODUCT_FROM_DATABASE=IC Recorder (P) + +usb:v054Cp01FB* + ID_PRODUCT_FROM_DATABASE=NW-E405 Network Walkman + +usb:v054Cp020F* + ID_PRODUCT_FROM_DATABASE=Device + +usb:v054Cp0210* + ID_PRODUCT_FROM_DATABASE=ATRAC HDD PA + +usb:v054Cp0219* + ID_PRODUCT_FROM_DATABASE=Net MD + +usb:v054Cp021A* + ID_PRODUCT_FROM_DATABASE=Hi-MD WALKMAN + +usb:v054Cp021B* + ID_PRODUCT_FROM_DATABASE=Net MD + +usb:v054Cp021C* + ID_PRODUCT_FROM_DATABASE=Hi-MD WALKMAN + +usb:v054Cp021D* + ID_PRODUCT_FROM_DATABASE=Net MD + +usb:v054Cp0227* + ID_PRODUCT_FROM_DATABASE=Printing Support + +usb:v054Cp022C* + ID_PRODUCT_FROM_DATABASE=Net MD + +usb:v054Cp022D* + ID_PRODUCT_FROM_DATABASE=Hi-MD AUDIO + +usb:v054Cp0233* + ID_PRODUCT_FROM_DATABASE=ATRAC HDD PA + +usb:v054Cp0236* + ID_PRODUCT_FROM_DATABASE=Mobile HDD + +usb:v054Cp023B* + ID_PRODUCT_FROM_DATABASE=DVD+RW External Drive DRU-800UL + +usb:v054Cp023C* + ID_PRODUCT_FROM_DATABASE=Net MD + +usb:v054Cp023D* + ID_PRODUCT_FROM_DATABASE=Hi-MD WALKMAN + +usb:v054Cp0243* + ID_PRODUCT_FROM_DATABASE=MicroVault Flash Drive + +usb:v054Cp024B* + ID_PRODUCT_FROM_DATABASE=Vaio VGX Mouse + +usb:v054Cp0257* + ID_PRODUCT_FROM_DATABASE=IFU-WLM2 USB Wireless LAN Module (Wireless Mode) + +usb:v054Cp0258* + ID_PRODUCT_FROM_DATABASE=IFU-WLM2 USB Wireless LAN Module (Memory Mode) + +usb:v054Cp0259* + ID_PRODUCT_FROM_DATABASE=IC RECORDER + +usb:v054Cp0267* + ID_PRODUCT_FROM_DATABASE=Tachikoma Device + +usb:v054Cp0268* + ID_PRODUCT_FROM_DATABASE=Batoh Device / PlayStation 3 Controller + +usb:v054Cp0269* + ID_PRODUCT_FROM_DATABASE=HDD WALKMAN + +usb:v054Cp026A* + ID_PRODUCT_FROM_DATABASE=HDD WALKMAN + +usb:v054Cp0271* + ID_PRODUCT_FROM_DATABASE=IC Recorder (P) + +usb:v054Cp027C* + ID_PRODUCT_FROM_DATABASE=NETWORK WALKMAN + +usb:v054Cp027E* + ID_PRODUCT_FROM_DATABASE=SONY Communicator + +usb:v054Cp027F* + ID_PRODUCT_FROM_DATABASE=IC RECORDER + +usb:v054Cp0286* + ID_PRODUCT_FROM_DATABASE=Net MD + +usb:v054Cp0287* + ID_PRODUCT_FROM_DATABASE=Hi-MD WALKMAN + +usb:v054Cp0290* + ID_PRODUCT_FROM_DATABASE=VGP-UVC100 Visual Communication Camera + +usb:v054Cp029B* + ID_PRODUCT_FROM_DATABASE=PRS-500 eBook reader + +usb:v054Cp02A5* + ID_PRODUCT_FROM_DATABASE=MicroVault Flash Drive + +usb:v054Cp02AF* + ID_PRODUCT_FROM_DATABASE=Handycam DCR-DVD306E + +usb:v054Cp02C4* + ID_PRODUCT_FROM_DATABASE=Device + +usb:v054Cp02D1* + ID_PRODUCT_FROM_DATABASE=DVD RW + +usb:v054Cp02D2* + ID_PRODUCT_FROM_DATABASE=PSP Slim + +usb:v054Cp02E1* + ID_PRODUCT_FROM_DATABASE=FeliCa S330 [PaSoRi] + +usb:v054Cp02EA* + ID_PRODUCT_FROM_DATABASE=PlayStation 3 Memory Card Adaptor + +usb:v054Cp02F9* + ID_PRODUCT_FROM_DATABASE=DSC-H9 + +usb:v054Cp0317* + ID_PRODUCT_FROM_DATABASE=WALKMAN + +usb:v054Cp031A* + ID_PRODUCT_FROM_DATABASE=Walkman NWD-B103F + +usb:v054Cp031E* + ID_PRODUCT_FROM_DATABASE=PRS-300/PRS-505 eBook reader + +usb:v054Cp0325* + ID_PRODUCT_FROM_DATABASE=NWZ-A818 + +usb:v054Cp033E* + ID_PRODUCT_FROM_DATABASE=DSC-W120/W290 + +usb:v054Cp0346* + ID_PRODUCT_FROM_DATABASE=Handycam DCR-SR55E + +usb:v054Cp0348* + ID_PRODUCT_FROM_DATABASE=HandyCam HDR-TG3E + +usb:v054Cp035B* + ID_PRODUCT_FROM_DATABASE=Walkman NWZ-A828 + +usb:v054Cp035C* + ID_PRODUCT_FROM_DATABASE=NWZ-A726/A728/A729 + +usb:v054Cp0382* + ID_PRODUCT_FROM_DATABASE=Memory Stick PRO-HG Duo Adaptor (MSAC-UAH1) + +usb:v054Cp0385* + ID_PRODUCT_FROM_DATABASE=Walkman NWZ-E436F + +usb:v054Cp0387* + ID_PRODUCT_FROM_DATABASE=IC Recorder (P) + +usb:v054Cp03BC* + ID_PRODUCT_FROM_DATABASE=Webbie HD - MHS-CM1 + +usb:v054Cp03D3* + ID_PRODUCT_FROM_DATABASE=DR-BT100CX + +usb:v054Cp03D5* + ID_PRODUCT_FROM_DATABASE=PlayStation Move motion controller + +usb:v054Cp03FC* + ID_PRODUCT_FROM_DATABASE=WALKMAN [NWZ-E345] + +usb:v054Cp03FD* + ID_PRODUCT_FROM_DATABASE=Walkman NWZ-E443 + +usb:v054Cp042F* + ID_PRODUCT_FROM_DATABASE=PlayStation Move navigation controller + +usb:v054Cp0440* + ID_PRODUCT_FROM_DATABASE=DSC-H55 + +usb:v054Cp0485* + ID_PRODUCT_FROM_DATABASE=MHS-PM5 HD camcorder + +usb:v054Cp04CB* + ID_PRODUCT_FROM_DATABASE=WALKMAN NWZ-E354 + +usb:v054Cp1000* + ID_PRODUCT_FROM_DATABASE=Wireless Buzz! Receiver + +usb:v054D* + ID_VENDOR_FROM_DATABASE=Try Corp. + +usb:v054E* + ID_VENDOR_FROM_DATABASE=Proside Corp. + +usb:v054F* + ID_VENDOR_FROM_DATABASE=WYSE Technology Taiwan + +usb:v0550* + ID_VENDOR_FROM_DATABASE=Fuji Xerox Co., Ltd + +usb:v0550p0002* + ID_PRODUCT_FROM_DATABASE=InkJet Color Printer + +usb:v0550p0004* + ID_PRODUCT_FROM_DATABASE=InkJet Color Printer + +usb:v0550p0005* + ID_PRODUCT_FROM_DATABASE=InkJet Color Printer + +usb:v0551* + ID_VENDOR_FROM_DATABASE=CompuTrend Systems, Inc. + +usb:v0552* + ID_VENDOR_FROM_DATABASE=Philips Monitors + +usb:v0553* + ID_VENDOR_FROM_DATABASE=STMicroelectronics Imaging Division (VLSI Vision) + +usb:v0553p0001* + ID_PRODUCT_FROM_DATABASE=TerraCAM + +usb:v0553p0002* + ID_PRODUCT_FROM_DATABASE=CPiA Webcam + +usb:v0553p0100* + ID_PRODUCT_FROM_DATABASE=STV0672 Camera + +usb:v0553p0140* + ID_PRODUCT_FROM_DATABASE=Video Camera + +usb:v0553p0150* + ID_PRODUCT_FROM_DATABASE=CDE CAM 100 + +usb:v0553p0151* + ID_PRODUCT_FROM_DATABASE=Digital Blue QX5 Microscope + +usb:v0553p0200* + ID_PRODUCT_FROM_DATABASE=Dual-mode Camera0 + +usb:v0553p0201* + ID_PRODUCT_FROM_DATABASE=Dual-mode Camera1 + +usb:v0553p0202* + ID_PRODUCT_FROM_DATABASE=Aiptek PenCam 1 + +usb:v0553p0674* + ID_PRODUCT_FROM_DATABASE=Multi-mode Camera + +usb:v0553p0679* + ID_PRODUCT_FROM_DATABASE=NMS Video Camera (Webcam) + +usb:v0553p1002* + ID_PRODUCT_FROM_DATABASE=Che-ez! Splash + +usb:v0554* + ID_VENDOR_FROM_DATABASE=Dictaphone Corp. + +usb:v0555* + ID_VENDOR_FROM_DATABASE=ANAM S&T Co., Ltd + +usb:v0556* + ID_VENDOR_FROM_DATABASE=Asahi Kasei Microsystems Co., Ltd + +usb:v0556p0001* + ID_PRODUCT_FROM_DATABASE=AK5370 I/F A/D Converter + +usb:v0557* + ID_VENDOR_FROM_DATABASE=ATEN International Co., Ltd + +usb:v0557p2001* + ID_PRODUCT_FROM_DATABASE=UC-1284 Printer Port + +usb:v0557p2002* + ID_PRODUCT_FROM_DATABASE=10Mbps Ethernet [klsi] + +usb:v0557p2004* + ID_PRODUCT_FROM_DATABASE=UC-100KM PS/2 Mouse and Keyboard adapter + +usb:v0557p2006* + ID_PRODUCT_FROM_DATABASE=UC-1284B Printer Port + +usb:v0557p2007* + ID_PRODUCT_FROM_DATABASE=UC-110T 100Mbps Ethernet [pegasus] + +usb:v0557p2008* + ID_PRODUCT_FROM_DATABASE=UC-232A Serial Port [pl2303] + +usb:v0557p2009* + ID_PRODUCT_FROM_DATABASE=UC-210T Ethernet + +usb:v0557p2011* + ID_PRODUCT_FROM_DATABASE=UC-2324 4xSerial Ports [mos7840] + +usb:v0557p2202* + ID_PRODUCT_FROM_DATABASE=CS124U Miniview II KVM Switch + +usb:v0557p2213* + ID_PRODUCT_FROM_DATABASE=CS682 2-Port USB 2.0 DVI KVM Switch + +usb:v0557p2221* + ID_PRODUCT_FROM_DATABASE=Winbond Hermon + +usb:v0557p2404* + ID_PRODUCT_FROM_DATABASE=4-port switch + +usb:v0557p2600* + ID_PRODUCT_FROM_DATABASE=IDE Bridge + +usb:v0557p2701* + ID_PRODUCT_FROM_DATABASE=CE700A KVM Extender + +usb:v0557p4000* + ID_PRODUCT_FROM_DATABASE=DSB-650 10Mbps Ethernet [klsi] + +usb:v0557p7000* + ID_PRODUCT_FROM_DATABASE=Hub + +usb:v0557p7820* + ID_PRODUCT_FROM_DATABASE=UC-2322 2xSerial Ports [mos7820] + +usb:v0558* + ID_VENDOR_FROM_DATABASE=Truevision, Inc. + +usb:v0558p1009* + ID_PRODUCT_FROM_DATABASE=GW Instek GDS-1000 Oscilloscope + +usb:v0558p100A* + ID_PRODUCT_FROM_DATABASE=GW Instek GDS-1000A Oscilloscope + +usb:v0558p2009* + ID_PRODUCT_FROM_DATABASE=GW Instek GDS-2000 Oscilloscope + +usb:v0559* + ID_VENDOR_FROM_DATABASE=Cadence Design Systems, Inc. + +usb:v055A* + ID_VENDOR_FROM_DATABASE=Kenwood USA + +usb:v055B* + ID_VENDOR_FROM_DATABASE=KnowledgeTek, Inc. + +usb:v055C* + ID_VENDOR_FROM_DATABASE=Proton Electronic Ind. + +usb:v055D* + ID_VENDOR_FROM_DATABASE=Samsung Electro-Mechanics Co. + +usb:v055Dp0001* + ID_PRODUCT_FROM_DATABASE=Keyboard + +usb:v055Dp0BB1* + ID_PRODUCT_FROM_DATABASE=Bluetooth Device + +usb:v055Dp1030* + ID_PRODUCT_FROM_DATABASE=Optical Wheel Mouse (OMS3CB/OMGB30) + +usb:v055Dp1031* + ID_PRODUCT_FROM_DATABASE=Optical Wheel Mouse (OMA3CB/OMGI30) + +usb:v055Dp1040* + ID_PRODUCT_FROM_DATABASE=Mouse HID Device + +usb:v055Dp1050* + ID_PRODUCT_FROM_DATABASE=E-Mail Optical Wheel Mouse (OMS3CE) + +usb:v055Dp1080* + ID_PRODUCT_FROM_DATABASE=Optical Wheel Mouse (OMS3CH) + +usb:v055Dp2020* + ID_PRODUCT_FROM_DATABASE=Floppy Disk Drive + +usb:v055Dp6780* + ID_PRODUCT_FROM_DATABASE=Keyboard V1 + +usb:v055Dp6781* + ID_PRODUCT_FROM_DATABASE=Keyboard Mouse + +usb:v055Dp8001* + ID_PRODUCT_FROM_DATABASE=E.M. Hub + +usb:v055Dp9000* + ID_PRODUCT_FROM_DATABASE=AnyCam [pwc] + +usb:v055Dp9001* + ID_PRODUCT_FROM_DATABASE=MPC-C30 AnyCam Premium for Notebooks [pwc] + +usb:v055DpA000* + ID_PRODUCT_FROM_DATABASE=SWL-2100U + +usb:v055DpA010* + ID_PRODUCT_FROM_DATABASE=WLAN Adapter(SWL-2300) + +usb:v055DpA011* + ID_PRODUCT_FROM_DATABASE=Boot Device + +usb:v055DpA012* + ID_PRODUCT_FROM_DATABASE=WLAN Adapter(SWL-2300) + +usb:v055DpA013* + ID_PRODUCT_FROM_DATABASE=WLAN Adapter(SWL-2350) + +usb:v055DpA230* + ID_PRODUCT_FROM_DATABASE=Boot Device + +usb:v055DpB000* + ID_PRODUCT_FROM_DATABASE=11Mbps WLAN Mini Adapter + +usb:v055DpB230* + ID_PRODUCT_FROM_DATABASE=Netopia 802.11b WLAN Adapter + +usb:v055DpB231* + ID_PRODUCT_FROM_DATABASE=LG Wireless LAN 11b Adapter + +usb:v055E* + ID_VENDOR_FROM_DATABASE=CTX Opto-Electronics Corp. + +usb:v055F* + ID_VENDOR_FROM_DATABASE=Mustek Systems, Inc. + +usb:v055Fp0001* + ID_PRODUCT_FROM_DATABASE=ScanExpress 1200 CU + +usb:v055Fp0002* + ID_PRODUCT_FROM_DATABASE=ScanExpress 600 CU + +usb:v055Fp0003* + ID_PRODUCT_FROM_DATABASE=ScanExpress 1200 USB + +usb:v055Fp0006* + ID_PRODUCT_FROM_DATABASE=ScanExpress 1200 UB + +usb:v055Fp0007* + ID_PRODUCT_FROM_DATABASE=ScanExpress 1200 USB Plus + +usb:v055Fp0008* + ID_PRODUCT_FROM_DATABASE=ScanExpress 1200 CU Plus + +usb:v055Fp0010* + ID_PRODUCT_FROM_DATABASE=BearPaw 1200F + +usb:v055Fp0210* + ID_PRODUCT_FROM_DATABASE=ScanExpress A3 USB + +usb:v055Fp0218* + ID_PRODUCT_FROM_DATABASE=BearPaw 2400 TA + +usb:v055Fp0219* + ID_PRODUCT_FROM_DATABASE=BearPaw 2400 TA Plus + +usb:v055Fp021A* + ID_PRODUCT_FROM_DATABASE=BearPaw 2448 TA Plus + +usb:v055Fp021B* + ID_PRODUCT_FROM_DATABASE=BearPaw 1200 CU Plus + +usb:v055Fp021C* + ID_PRODUCT_FROM_DATABASE=BearPaw 1200 CU Plus + +usb:v055Fp021D* + ID_PRODUCT_FROM_DATABASE=BearPaw 2400 CU Plus + +usb:v055Fp021E* + ID_PRODUCT_FROM_DATABASE=BearPaw 1200 TA/CS + +usb:v055Fp021F* + ID_PRODUCT_FROM_DATABASE=SNAPSCAN e22 + +usb:v055Fp0400* + ID_PRODUCT_FROM_DATABASE=BearPaw 2400 TA Pro + +usb:v055Fp0401* + ID_PRODUCT_FROM_DATABASE=P 3600 A3 Pro + +usb:v055Fp0408* + ID_PRODUCT_FROM_DATABASE=BearPaw 2448 CU Pro + +usb:v055Fp0409* + ID_PRODUCT_FROM_DATABASE=BearPaw 2448 TA Pro + +usb:v055Fp040B* + ID_PRODUCT_FROM_DATABASE=ScanExpress A3 USB 1200 PRO + +usb:v055Fp0873* + ID_PRODUCT_FROM_DATABASE=ScanExpress 600 USB + +usb:v055Fp1000* + ID_PRODUCT_FROM_DATABASE=BearPaw 4800 TA Pro + +usb:v055FpA350* + ID_PRODUCT_FROM_DATABASE=gSmart 350 Camera + +usb:v055FpA800* + ID_PRODUCT_FROM_DATABASE=MDC 800 Camera + +usb:v055FpB500* + ID_PRODUCT_FROM_DATABASE=MDC 3000 Camera + +usb:v055FpC005* + ID_PRODUCT_FROM_DATABASE=PC CAM 300A + +usb:v055FpC200* + ID_PRODUCT_FROM_DATABASE=gSmart 300 + +usb:v055FpC211* + ID_PRODUCT_FROM_DATABASE=Kowa Bs888e Microcamera + +usb:v055FpC220* + ID_PRODUCT_FROM_DATABASE=gSmart mini + +usb:v055FpC230* + ID_PRODUCT_FROM_DATABASE=Digicam 330K + +usb:v055FpC232* + ID_PRODUCT_FROM_DATABASE=MDC3500 Camera + +usb:v055FpC360* + ID_PRODUCT_FROM_DATABASE=DV 4000 Camera + +usb:v055FpC420* + ID_PRODUCT_FROM_DATABASE=gSmart mini 2 Camera + +usb:v055FpC430* + ID_PRODUCT_FROM_DATABASE=gSmart LCD 2 Camera + +usb:v055FpC440* + ID_PRODUCT_FROM_DATABASE=DV 3000 Camera + +usb:v055FpC520* + ID_PRODUCT_FROM_DATABASE=gSmart mini 3 Camera + +usb:v055FpC530* + ID_PRODUCT_FROM_DATABASE=gSmart LCD 2 Camera + +usb:v055FpC540* + ID_PRODUCT_FROM_DATABASE=gSmart D30 Camera + +usb:v055FpC630* + ID_PRODUCT_FROM_DATABASE=MDC 4000 Camera + +usb:v055FpC631* + ID_PRODUCT_FROM_DATABASE=MDC 4000 Camera + +usb:v055FpC650* + ID_PRODUCT_FROM_DATABASE=MDC 5500Z Camera + +usb:v055FpD001* + ID_PRODUCT_FROM_DATABASE=WCam 300 + +usb:v055FpD003* + ID_PRODUCT_FROM_DATABASE=WCam 300A + +usb:v055FpD004* + ID_PRODUCT_FROM_DATABASE=WCam 300AN + +usb:v0560* + ID_VENDOR_FROM_DATABASE=Interface Corp. + +usb:v0561* + ID_VENDOR_FROM_DATABASE=Oasis Design, Inc. + +usb:v0562* + ID_VENDOR_FROM_DATABASE=Telex Communications, Inc. + +usb:v0562p0001* + ID_PRODUCT_FROM_DATABASE=Enhanced Microphone + +usb:v0562p0002* + ID_PRODUCT_FROM_DATABASE=Telex Microphone + +usb:v0563* + ID_VENDOR_FROM_DATABASE=Immersion Corp. + +usb:v0564* + ID_VENDOR_FROM_DATABASE=Kodak Digital Product Center, Japan Ltd. (formerly Chinon Industries Inc.) + +usb:v0565* + ID_VENDOR_FROM_DATABASE=Peracom Networks, Inc. + +usb:v0565p0001* + ID_PRODUCT_FROM_DATABASE=Serial Port [etek] + +usb:v0565p0002* + ID_PRODUCT_FROM_DATABASE=Enet Ethernet [klsi] + +usb:v0565p0003* + ID_PRODUCT_FROM_DATABASE=@Home Networks Ethernet [klsi] + +usb:v0565p0005* + ID_PRODUCT_FROM_DATABASE=Enet2 Ethernet [klsi] + +usb:v0565p0041* + ID_PRODUCT_FROM_DATABASE=Peracom Remote NDIS Ethernet Adapter + +usb:v0566* + ID_VENDOR_FROM_DATABASE=Monterey International Corp. + +usb:v0566p0110* + ID_PRODUCT_FROM_DATABASE=ViewMate Desktop Mouse CC2201 + +usb:v0566p1001* + ID_PRODUCT_FROM_DATABASE=ViewMate Desktop Mouse CC2201 + +usb:v0566p1002* + ID_PRODUCT_FROM_DATABASE=ViewMate Desktop Mouse CC2201 + +usb:v0566p1003* + ID_PRODUCT_FROM_DATABASE=ViewMate Desktop Mouse CC2201 + +usb:v0566p1004* + ID_PRODUCT_FROM_DATABASE=ViewMate Desktop Mouse CC2201 + +usb:v0566p1005* + ID_PRODUCT_FROM_DATABASE=ViewMate Desktop Mouse CC2201 + +usb:v0566p1006* + ID_PRODUCT_FROM_DATABASE=ViewMate Desktop Mouse CC2201 + +usb:v0566p1007* + ID_PRODUCT_FROM_DATABASE=ViewMate Desktop Mouse CC2201 + +usb:v0566p2800* + ID_PRODUCT_FROM_DATABASE=MIC K/B + +usb:v0566p2801* + ID_PRODUCT_FROM_DATABASE=MIC K/B Mouse + +usb:v0566p2802* + ID_PRODUCT_FROM_DATABASE=Kbd Hub + +usb:v0566p3004* + ID_PRODUCT_FROM_DATABASE=Genius KB-29E + +usb:v0566p3107* + ID_PRODUCT_FROM_DATABASE=Keyboard + +usb:v0567* + ID_VENDOR_FROM_DATABASE=Xyratex International, Ltd + +usb:v0568* + ID_VENDOR_FROM_DATABASE=Quartz Ingenierie + +usb:v0569* + ID_VENDOR_FROM_DATABASE=SegaSoft + +usb:v056A* + ID_VENDOR_FROM_DATABASE=Wacom Co., Ltd + +usb:v056Ap0000* + ID_PRODUCT_FROM_DATABASE=PenPartner + +usb:v056Ap0001* + ID_PRODUCT_FROM_DATABASE=PenPartner 4x5 + +usb:v056Ap0002* + ID_PRODUCT_FROM_DATABASE=PenPartner 6x8 + +usb:v056Ap0003* + ID_PRODUCT_FROM_DATABASE=Cintiq Partner + +usb:v056Ap0010* + ID_PRODUCT_FROM_DATABASE=Graphire + +usb:v056Ap0011* + ID_PRODUCT_FROM_DATABASE=Graphire 2 4x5 + +usb:v056Ap0012* + ID_PRODUCT_FROM_DATABASE=Graphire 2 5x7 + +usb:v056Ap0013* + ID_PRODUCT_FROM_DATABASE=Graphire 3 4x5 + +usb:v056Ap0014* + ID_PRODUCT_FROM_DATABASE=Graphire 3 6x8 + +usb:v056Ap0015* + ID_PRODUCT_FROM_DATABASE=Graphire 4 4x5 + +usb:v056Ap0016* + ID_PRODUCT_FROM_DATABASE=Graphire 4 6x8 + +usb:v056Ap0017* + ID_PRODUCT_FROM_DATABASE=CTE-450 [Bamboo Fun] + +usb:v056Ap0018* + ID_PRODUCT_FROM_DATABASE=Bamboo Fun 6x8 + +usb:v056Ap0019* + ID_PRODUCT_FROM_DATABASE=Bamboo One Medium + +usb:v056Ap0020* + ID_PRODUCT_FROM_DATABASE=Intuos 4x5 + +usb:v056Ap0021* + ID_PRODUCT_FROM_DATABASE=Intuos 6x8 + +usb:v056Ap0022* + ID_PRODUCT_FROM_DATABASE=Intuos 9x12 + +usb:v056Ap0023* + ID_PRODUCT_FROM_DATABASE=Intuos 12x12 + +usb:v056Ap0024* + ID_PRODUCT_FROM_DATABASE=Intuos 12x18 + +usb:v056Ap0026* + ID_PRODUCT_FROM_DATABASE=Intuos5 touch S + +usb:v056Ap0027* + ID_PRODUCT_FROM_DATABASE=Intuos5 touch M + +usb:v056Ap0028* + ID_PRODUCT_FROM_DATABASE=Intuos5 touch L + +usb:v056Ap0029* + ID_PRODUCT_FROM_DATABASE=Intuos5 S + +usb:v056Ap002A* + ID_PRODUCT_FROM_DATABASE=Intuos5 M + +usb:v056Ap0030* + ID_PRODUCT_FROM_DATABASE=PL400 + +usb:v056Ap0031* + ID_PRODUCT_FROM_DATABASE=PL500 + +usb:v056Ap0032* + ID_PRODUCT_FROM_DATABASE=PL600 + +usb:v056Ap0033* + ID_PRODUCT_FROM_DATABASE=PL600SX + +usb:v056Ap0034* + ID_PRODUCT_FROM_DATABASE=PL550 + +usb:v056Ap0035* + ID_PRODUCT_FROM_DATABASE=PL800 + +usb:v056Ap0037* + ID_PRODUCT_FROM_DATABASE=PL700 + +usb:v056Ap0038* + ID_PRODUCT_FROM_DATABASE=PL510 + +usb:v056Ap0039* + ID_PRODUCT_FROM_DATABASE=DTU-710 + +usb:v056Ap003F* + ID_PRODUCT_FROM_DATABASE=Cintiq 21UX (DTZ-2100) + +usb:v056Ap0041* + ID_PRODUCT_FROM_DATABASE=Intuos2 4x5 + +usb:v056Ap0042* + ID_PRODUCT_FROM_DATABASE=Intuos2 6x8 + +usb:v056Ap0043* + ID_PRODUCT_FROM_DATABASE=Intuos2 9x12 + +usb:v056Ap0044* + ID_PRODUCT_FROM_DATABASE=Intuos2 12x12 + +usb:v056Ap0045* + ID_PRODUCT_FROM_DATABASE=Intuos2 12x18 + +usb:v056Ap0047* + ID_PRODUCT_FROM_DATABASE=Intuos2 6x8 + +usb:v056Ap0060* + ID_PRODUCT_FROM_DATABASE=Volito + +usb:v056Ap0061* + ID_PRODUCT_FROM_DATABASE=PenStation2 + +usb:v056Ap0062* + ID_PRODUCT_FROM_DATABASE=Volito2 4x5 + +usb:v056Ap0063* + ID_PRODUCT_FROM_DATABASE=Volito2 2x3 + +usb:v056Ap0064* + ID_PRODUCT_FROM_DATABASE=PenPartner2 + +usb:v056Ap0065* + ID_PRODUCT_FROM_DATABASE=Bamboo + +usb:v056Ap0069* + ID_PRODUCT_FROM_DATABASE=Bamboo One + +usb:v056Ap0081* + ID_PRODUCT_FROM_DATABASE=Graphire Wireless 6x8 + +usb:v056Ap0090* + ID_PRODUCT_FROM_DATABASE=TPC90 + +usb:v056Ap0093* + ID_PRODUCT_FROM_DATABASE=TPC93 + +usb:v056Ap009A* + ID_PRODUCT_FROM_DATABASE=TPC9A + +usb:v056Ap00B0* + ID_PRODUCT_FROM_DATABASE=Intuos3 4x5 + +usb:v056Ap00B1* + ID_PRODUCT_FROM_DATABASE=Intuos3 6x18 + +usb:v056Ap00B2* + ID_PRODUCT_FROM_DATABASE=Intuos3 9x12 + +usb:v056Ap00B3* + ID_PRODUCT_FROM_DATABASE=Intuos3 12x12 + +usb:v056Ap00B4* + ID_PRODUCT_FROM_DATABASE=Intuos3 12x19 + +usb:v056Ap00B5* + ID_PRODUCT_FROM_DATABASE=Intuos3 6x11 (PTZ-631W) + +usb:v056Ap00B7* + ID_PRODUCT_FROM_DATABASE=Intuos3 4x6 + +usb:v056Ap00B8* + ID_PRODUCT_FROM_DATABASE=Intuos4 4x6 + +usb:v056Ap00B9* + ID_PRODUCT_FROM_DATABASE=Intuos4 6x9 + +usb:v056Ap00BA* + ID_PRODUCT_FROM_DATABASE=Intuos4 8x13 + +usb:v056Ap00BB* + ID_PRODUCT_FROM_DATABASE=Intuos4 12x19 + +usb:v056Ap00C0* + ID_PRODUCT_FROM_DATABASE=DTF-521 + +usb:v056Ap00C4* + ID_PRODUCT_FROM_DATABASE=DTF-720 + +usb:v056Ap00C5* + ID_PRODUCT_FROM_DATABASE=Cintiq 20WSX + +usb:v056Ap00C6* + ID_PRODUCT_FROM_DATABASE=Cintiq 12WX + +usb:v056Ap00C7* + ID_PRODUCT_FROM_DATABASE=DTU-1931 + +usb:v056Ap00CC* + ID_PRODUCT_FROM_DATABASE=Cintiq 21UX (DTK-2100) + +usb:v056Ap00D1* + ID_PRODUCT_FROM_DATABASE=Bamboo Pen & Touch (CTH-460-DE) + +usb:v056Ap00D3* + ID_PRODUCT_FROM_DATABASE=Bamboo Fun (CTH-661) + +usb:v056Ap00D6* + ID_PRODUCT_FROM_DATABASE=Bamboo Pen & Touch (CTH-460) + +usb:v056Ap00DB* + ID_PRODUCT_FROM_DATABASE=Bamboo Fun (CTH-661SE-NL) + +usb:v056Ap00DD* + ID_PRODUCT_FROM_DATABASE=Bamboo Pen (CTL-470) + +usb:v056Ap00F6* + ID_PRODUCT_FROM_DATABASE=Cintiq 24HD touch (DTH-2400) touchscreen + +usb:v056Ap00F8* + ID_PRODUCT_FROM_DATABASE=Cintiq 24HD touch (DTH-2400) tablet + +usb:v056Ap0400* + ID_PRODUCT_FROM_DATABASE=PenPartner 4x5 + +usb:v056Ap4850* + ID_PRODUCT_FROM_DATABASE=PenPartner 6x8 + +usb:v056B* + ID_VENDOR_FROM_DATABASE=Decicon, Inc. + +usb:v056C* + ID_VENDOR_FROM_DATABASE=eTEK Labs + +usb:v056Cp0006* + ID_PRODUCT_FROM_DATABASE=KwikLink Host-Host Connector + +usb:v056Cp8007* + ID_PRODUCT_FROM_DATABASE=Kwik232 Serial Port + +usb:v056Cp8100* + ID_PRODUCT_FROM_DATABASE=KwikLink Host-Host Connector + +usb:v056Cp8101* + ID_PRODUCT_FROM_DATABASE=KwikLink USB-USB Bridge + +usb:v056D* + ID_VENDOR_FROM_DATABASE=EIZO Corp. + +usb:v056Dp0000* + ID_PRODUCT_FROM_DATABASE=Hub + +usb:v056Dp0001* + ID_PRODUCT_FROM_DATABASE=Monitor + +usb:v056Dp0002* + ID_PRODUCT_FROM_DATABASE=HID Monitor Controls + +usb:v056Dp0003* + ID_PRODUCT_FROM_DATABASE=Device Bay Controller + +usb:v056E* + ID_VENDOR_FROM_DATABASE=Elecom Co., Ltd + +usb:v056Ep0002* + ID_PRODUCT_FROM_DATABASE=29UO Mouse + +usb:v056Ep0072* + ID_PRODUCT_FROM_DATABASE=Mouse + +usb:v056Ep200C* + ID_PRODUCT_FROM_DATABASE=LD-USB/TX + +usb:v056Ep4002* + ID_PRODUCT_FROM_DATABASE=Laneed 100Mbps Ethernet LD-USB/TX [pegasus] + +usb:v056Ep4005* + ID_PRODUCT_FROM_DATABASE=LD-USBL/TX + +usb:v056Ep400B* + ID_PRODUCT_FROM_DATABASE=LD-USB/TX + +usb:v056Ep4010* + ID_PRODUCT_FROM_DATABASE=LD-USB20 + +usb:v056Ep5003* + ID_PRODUCT_FROM_DATABASE=UC-SGT + +usb:v056Ep5004* + ID_PRODUCT_FROM_DATABASE=UC-SGT + +usb:v056Ep6008* + ID_PRODUCT_FROM_DATABASE=Flash Disk + +usb:v056EpABC1* + ID_PRODUCT_FROM_DATABASE=LD-USB/TX + +usb:v056F* + ID_VENDOR_FROM_DATABASE=Korea Data Systems Co., Ltd + +usb:v056FpCD00* + ID_PRODUCT_FROM_DATABASE=CDM-751 CD organizer + +usb:v0570* + ID_VENDOR_FROM_DATABASE=Epson America + +usb:v0571* + ID_VENDOR_FROM_DATABASE=Interex, Inc. + +usb:v0571p0002* + ID_PRODUCT_FROM_DATABASE=echoFX InterView Lite + +usb:v0572* + ID_VENDOR_FROM_DATABASE=Conexant Systems (Rockwell), Inc. + +usb:v0572p0001* + ID_PRODUCT_FROM_DATABASE=Ezcam II Webcam + +usb:v0572p0002* + ID_PRODUCT_FROM_DATABASE=Ezcam II Webcam + +usb:v0572p0040* + ID_PRODUCT_FROM_DATABASE=Wondereye CP-115 Webcam + +usb:v0572p0041* + ID_PRODUCT_FROM_DATABASE=Webcam Notebook + +usb:v0572p0042* + ID_PRODUCT_FROM_DATABASE=Webcam Notebook + +usb:v0572p1232* + ID_PRODUCT_FROM_DATABASE=V.90 modem + +usb:v0572p1234* + ID_PRODUCT_FROM_DATABASE=Typhoon Redfun Modem V90 56k + +usb:v0572p1252* + ID_PRODUCT_FROM_DATABASE=HCF V90 Data Fax Voice Modem + +usb:v0572p1253* + ID_PRODUCT_FROM_DATABASE=Zoom V.92 Faxmodem + +usb:v0572p1300* + ID_PRODUCT_FROM_DATABASE=SoftK56 Data Fax Voice CARP + +usb:v0572p1301* + ID_PRODUCT_FROM_DATABASE=Modem Enumerator + +usb:v0572p1328* + ID_PRODUCT_FROM_DATABASE=TrendNet TFM-561 modem + +usb:v0572p2000* + ID_PRODUCT_FROM_DATABASE=SoftGate 802.11 Adapter + +usb:v0572p2002* + ID_PRODUCT_FROM_DATABASE=SoftGate 802.11 Adapter + +usb:v0572p262A* + ID_PRODUCT_FROM_DATABASE=tm5600 Video & Audio Grabber Capture + +usb:v0572p8390* + ID_PRODUCT_FROM_DATABASE=WinFast PalmTop/Novo TV Video + +usb:v0572p8392* + ID_PRODUCT_FROM_DATABASE=WinFast PalmTop/Novo TV Video + +usb:v0572pCAFE* + ID_PRODUCT_FROM_DATABASE=AccessRunner ADSL Modem + +usb:v0572pCB00* + ID_PRODUCT_FROM_DATABASE=ADSL Modem + +usb:v0572pCB01* + ID_PRODUCT_FROM_DATABASE=ADSL Modem + +usb:v0572pCB06* + ID_PRODUCT_FROM_DATABASE=StarModem Network Interface + +usb:v0573* + ID_VENDOR_FROM_DATABASE=Zoran Co. Personal Media Division (Nogatech) + +usb:v0573p0003* + ID_PRODUCT_FROM_DATABASE=USBGear USBG-V1 + +usb:v0573p0400* + ID_PRODUCT_FROM_DATABASE=D-Link V100 + +usb:v0573p0600* + ID_PRODUCT_FROM_DATABASE=Dazzle USBVision (1006) + +usb:v0573p1300* + ID_PRODUCT_FROM_DATABASE=leadtek USBVision (1006) + +usb:v0573p2000* + ID_PRODUCT_FROM_DATABASE=X10 va10a Wireless Camera + +usb:v0573p2001* + ID_PRODUCT_FROM_DATABASE=Dazzle EmMe (2001) + +usb:v0573p2101* + ID_PRODUCT_FROM_DATABASE=Zoran Co. PMD (Nogatech) AV-grabber Manhattan + +usb:v0573p2D00* + ID_PRODUCT_FROM_DATABASE=Osprey 50 + +usb:v0573p2D01* + ID_PRODUCT_FROM_DATABASE=Hauppauge USB-Live Model 600 + +usb:v0573p3000* + ID_PRODUCT_FROM_DATABASE=Dazzle MicroCam (NTSC) + +usb:v0573p3001* + ID_PRODUCT_FROM_DATABASE=Dazzle MicroCam (PAL) + +usb:v0573p4000* + ID_PRODUCT_FROM_DATABASE=Nogatech TV! (NTSC) + +usb:v0573p4001* + ID_PRODUCT_FROM_DATABASE=Nogatech TV! (PAL) + +usb:v0573p4002* + ID_PRODUCT_FROM_DATABASE=Nogatech TV! (PAL-I-) + +usb:v0573p4003* + ID_PRODUCT_FROM_DATABASE=Nogatech TV! (MF-) + +usb:v0573p4008* + ID_PRODUCT_FROM_DATABASE=Nogatech TV! (NTSC) (T) + +usb:v0573p4009* + ID_PRODUCT_FROM_DATABASE=Nogatech TV! (PAL) (T) + +usb:v0573p4010* + ID_PRODUCT_FROM_DATABASE=Nogatech TV! (NTSC) (A) + +usb:v0573p4100* + ID_PRODUCT_FROM_DATABASE=USB-TV FM (NTSC) + +usb:v0573p4110* + ID_PRODUCT_FROM_DATABASE=PNY USB-TV (NTSC) FM + +usb:v0573p4400* + ID_PRODUCT_FROM_DATABASE=Nogatech TV! Pro (NTSC) + +usb:v0573p4401* + ID_PRODUCT_FROM_DATABASE=Nogatech TV! Pro (PAL) + +usb:v0573p4450* + ID_PRODUCT_FROM_DATABASE=PixelView PlayTv-USB PRO (PAL) FM + +usb:v0573p4451* + ID_PRODUCT_FROM_DATABASE=Nogatech TV! Pro (PAL+) + +usb:v0573p4452* + ID_PRODUCT_FROM_DATABASE=Nogatech TV! Pro (PAL-I+) + +usb:v0573p4500* + ID_PRODUCT_FROM_DATABASE=Nogatech TV! Pro (NTSC) + +usb:v0573p4501* + ID_PRODUCT_FROM_DATABASE=Nogatech TV! Pro (PAL) + +usb:v0573p4550* + ID_PRODUCT_FROM_DATABASE=ZTV ZT-721 2.4GHz A/V Receiver + +usb:v0573p4551* + ID_PRODUCT_FROM_DATABASE=Dazzle TV! Pro Audio (P+) + +usb:v0573p4D00* + ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV-USB USA + +usb:v0573p4D01* + ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV-USB + +usb:v0573p4D02* + ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV-USB UK + +usb:v0573p4D03* + ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV-USB France + +usb:v0573p4D04* + ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV (PAL D/K) + +usb:v0573p4D10* + ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV-USB with FM USA radio + +usb:v0573p4D11* + ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV-USB (PAL) with FM radio + +usb:v0573p4D12* + ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV-USB UK with FM Radio + +usb:v0573p4D14* + ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV (PAL D/K FM) + +usb:v0573p4D20* + ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV-USB II (PAL) with FM radio + +usb:v0573p4D21* + ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV-USB II (PAL) + +usb:v0573p4D22* + ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV-USB II (PAL) Model 566 + +usb:v0573p4D23* + ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV-USB France 4D23 + +usb:v0573p4D24* + ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV Pro (PAL D/K) + +usb:v0573p4D25* + ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV-USB Model 40209 rev B234 + +usb:v0573p4D26* + ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV-USB Model 40209 rev B243 + +usb:v0573p4D27* + ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV-USB Model 40204 Rev B281 + +usb:v0573p4D28* + ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV-USB Model 40204 rev B283 + +usb:v0573p4D29* + ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV-USB Model 40205 rev B298 + +usb:v0573p4D2A* + ID_PRODUCT_FROM_DATABASE=Hauppague WinTV-USB Model 602 Rev B285 + +usb:v0573p4D2B* + ID_PRODUCT_FROM_DATABASE=Hauppague WinTV-USB Model 602 Rev B282 + +usb:v0573p4D2C* + ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV Pro (PAL/SECAM) + +usb:v0573p4D30* + ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV-USB FM Model 40211 Rev B123 + +usb:v0573p4D31* + ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV-USB III (PAL) with FM radio Model 568 + +usb:v0573p4D32* + ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV-USB III (PAL) FM Model 573 + +usb:v0573p4D34* + ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV Pro (PAL D/K FM) + +usb:v0573p4D35* + ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV-USB III (PAL) FM Model 597 + +usb:v0573p4D36* + ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV Pro (PAL B/G FM) + +usb:v0573p4D37* + ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV-USB Model 40219 rev E189 + +usb:v0573p4D38* + ID_PRODUCT_FROM_DATABASE=Hauppauge WinTV Pro (NTSC FM) + +usb:v0574* + ID_VENDOR_FROM_DATABASE=City University of Hong Kong + +usb:v0575* + ID_VENDOR_FROM_DATABASE=Philips Creative Display Solutions + +usb:v0576* + ID_VENDOR_FROM_DATABASE=BAFO/Quality Computer Accessories + +usb:v0577* + ID_VENDOR_FROM_DATABASE=ELSA + +usb:v0578* + ID_VENDOR_FROM_DATABASE=Intrinsix Corp. + +usb:v0579* + ID_VENDOR_FROM_DATABASE=GVC Corp. + +usb:v057A* + ID_VENDOR_FROM_DATABASE=Samsung Electronics America + +usb:v057B* + ID_VENDOR_FROM_DATABASE=Y-E Data, Inc. + +usb:v057Bp0000* + ID_PRODUCT_FROM_DATABASE=FlashBuster-U Floppy + +usb:v057Bp0001* + ID_PRODUCT_FROM_DATABASE=Tri-Media Reader Floppy + +usb:v057Bp0006* + ID_PRODUCT_FROM_DATABASE=Tri-Media Reader Card Reader + +usb:v057Bp0010* + ID_PRODUCT_FROM_DATABASE=Memory Stick Reader Writer + +usb:v057Bp0020* + ID_PRODUCT_FROM_DATABASE=HEXA Media Drive 6-in-1 Card Reader Writer + +usb:v057Bp0030* + ID_PRODUCT_FROM_DATABASE=Memory Card Viewer (TV) + +usb:v057C* + ID_VENDOR_FROM_DATABASE=AVM GmbH + +usb:v057Cp0B00* + ID_PRODUCT_FROM_DATABASE=ISDN-Controller B1 Family + +usb:v057Cp0C00* + ID_PRODUCT_FROM_DATABASE=ISDN-Controller FRITZ!Card + +usb:v057Cp1000* + ID_PRODUCT_FROM_DATABASE=ISDN-Controller FRITZ!Card v2.0 + +usb:v057Cp1900* + ID_PRODUCT_FROM_DATABASE=ISDN-Controller FRITZ!Card v2.1 + +usb:v057Cp2000* + ID_PRODUCT_FROM_DATABASE=ISDN-Connector FRITZ!X + +usb:v057Cp2200* + ID_PRODUCT_FROM_DATABASE=BlueFRITZ! + +usb:v057Cp2300* + ID_PRODUCT_FROM_DATABASE=Teledat X130 DSL + +usb:v057Cp2800* + ID_PRODUCT_FROM_DATABASE=ISDN-Connector TA + +usb:v057Cp3200* + ID_PRODUCT_FROM_DATABASE=Teledat X130 DSL + +usb:v057Cp3500* + ID_PRODUCT_FROM_DATABASE=FRITZ!Card DSL SL + +usb:v057Cp3701* + ID_PRODUCT_FROM_DATABASE=FRITZ!Box SL + +usb:v057Cp3702* + ID_PRODUCT_FROM_DATABASE=FRITZ!Box + +usb:v057Cp3800* + ID_PRODUCT_FROM_DATABASE=BlueFRITZ! Bluetooth Stick + +usb:v057Cp3A00* + ID_PRODUCT_FROM_DATABASE=FRITZ!Box Fon + +usb:v057Cp3C00* + ID_PRODUCT_FROM_DATABASE=FRITZ!Box WLAN + +usb:v057Cp3D00* + ID_PRODUCT_FROM_DATABASE=Fritz!Box + +usb:v057Cp3E01* + ID_PRODUCT_FROM_DATABASE=FRITZ!Box (Annex A) + +usb:v057Cp4001* + ID_PRODUCT_FROM_DATABASE=FRITZ!Box Fon (Annex A) + +usb:v057Cp4101* + ID_PRODUCT_FROM_DATABASE=FRITZ!Box WLAN (Annex A) + +usb:v057Cp4201* + ID_PRODUCT_FROM_DATABASE=FRITZ!Box Fon WLAN (Annex A) + +usb:v057Cp4601* + ID_PRODUCT_FROM_DATABASE=Eumex 5520PC (WinXP/2000) + +usb:v057Cp4602* + ID_PRODUCT_FROM_DATABASE=Eumex 400 (WinXP/2000) + +usb:v057Cp4701* + ID_PRODUCT_FROM_DATABASE=AVM FRITZ!Box Fon ata + +usb:v057Cp5401* + ID_PRODUCT_FROM_DATABASE=Eumex 300 IP + +usb:v057Cp5601* + ID_PRODUCT_FROM_DATABASE=AVM Fritz!WLAN [Texas Instruments TNETW1450] + +usb:v057Cp6201* + ID_PRODUCT_FROM_DATABASE=AVM Fritz!WLAN v1.1 [Texas Instruments TNETW1450] + +usb:v057Cp62FF* + ID_PRODUCT_FROM_DATABASE=AVM Fritz!WLAN USB (in CD-ROM-mode) + +usb:v057Cp8401* + ID_PRODUCT_FROM_DATABASE=Fritz!WLAN N [Atheros AR9001U] + +usb:v057Cp8402* + ID_PRODUCT_FROM_DATABASE=Fritz!WLAN N 2.4 [Atheros AR9001U] + +usb:v057Cp8403* + ID_PRODUCT_FROM_DATABASE=Fritz!WLAN N v2 [Atheros AR9271] + +usb:v057Cp84FF* + ID_PRODUCT_FROM_DATABASE=AVM Fritz!WLAN USB N (in CD-ROM-mode) + +usb:v057D* + ID_VENDOR_FROM_DATABASE=Shark Multimedia, Inc. + +usb:v057E* + ID_VENDOR_FROM_DATABASE=Nintendo Co., Ltd + +usb:v057Ep0305* + ID_PRODUCT_FROM_DATABASE=Broadcom BCM2045A Bluetooth Radio [Nintendo Wii] + +usb:v057Ep0306* + ID_PRODUCT_FROM_DATABASE=Wii Remote Controller RVL-003 + +usb:v057F* + ID_VENDOR_FROM_DATABASE=QuickShot, Ltd + +usb:v057Fp6238* + ID_PRODUCT_FROM_DATABASE=USB StrikePad + +usb:v0580* + ID_VENDOR_FROM_DATABASE=Denron, Inc. + +usb:v0581* + ID_VENDOR_FROM_DATABASE=Racal Data Group + +usb:v0582* + ID_VENDOR_FROM_DATABASE=Roland Corp. + +usb:v0582p0000* + ID_PRODUCT_FROM_DATABASE=UA-100 + +usb:v0582p0002* + ID_PRODUCT_FROM_DATABASE=UM-4/MPU-64 MIDI Interface + +usb:v0582p0003* + ID_PRODUCT_FROM_DATABASE=SoundCanvas SC-8850 + +usb:v0582p0004* + ID_PRODUCT_FROM_DATABASE=U-8 + +usb:v0582p0005* + ID_PRODUCT_FROM_DATABASE=Edirol UM-2 MIDI Adapter + +usb:v0582p0007* + ID_PRODUCT_FROM_DATABASE=SoundCanvas SC-8820 + +usb:v0582p0008* + ID_PRODUCT_FROM_DATABASE=PC-300 + +usb:v0582p0009* + ID_PRODUCT_FROM_DATABASE=Edirol UM-1SX MIDI Adapter + +usb:v0582p000B* + ID_PRODUCT_FROM_DATABASE=SK-500 + +usb:v0582p000C* + ID_PRODUCT_FROM_DATABASE=SC-D70 + +usb:v0582p0010* + ID_PRODUCT_FROM_DATABASE=EDIROL UA-5 + +usb:v0582p0011* + ID_PRODUCT_FROM_DATABASE=Edirol UA-5 Sound Capture + +usb:v0582p0012* + ID_PRODUCT_FROM_DATABASE=XV-5050 + +usb:v0582p0013* + ID_PRODUCT_FROM_DATABASE=XV-5050 + +usb:v0582p0014* + ID_PRODUCT_FROM_DATABASE=EDIROL UM-880 MIDI I/F (native) + +usb:v0582p0015* + ID_PRODUCT_FROM_DATABASE=EDIROL UM-880 MIDI I/F (generic) + +usb:v0582p0016* + ID_PRODUCT_FROM_DATABASE=EDIROL SD-90 + +usb:v0582p0017* + ID_PRODUCT_FROM_DATABASE=EDIROL SD-90 + +usb:v0582p0018* + ID_PRODUCT_FROM_DATABASE=UA-1A + +usb:v0582p001B* + ID_PRODUCT_FROM_DATABASE=MMP-2 + +usb:v0582p001C* + ID_PRODUCT_FROM_DATABASE=MMP-2 + +usb:v0582p001D* + ID_PRODUCT_FROM_DATABASE=V-SYNTH + +usb:v0582p001E* + ID_PRODUCT_FROM_DATABASE=V-SYNTH + +usb:v0582p0023* + ID_PRODUCT_FROM_DATABASE=EDIROL UM-550 + +usb:v0582p0024* + ID_PRODUCT_FROM_DATABASE=EDIROL UM-550 + +usb:v0582p0025* + ID_PRODUCT_FROM_DATABASE=EDIROL UA-20 + +usb:v0582p0026* + ID_PRODUCT_FROM_DATABASE=EDIROL UA-20 + +usb:v0582p0027* + ID_PRODUCT_FROM_DATABASE=EDIROL SD-20 + +usb:v0582p0028* + ID_PRODUCT_FROM_DATABASE=EDIROL SD-20 + +usb:v0582p0029* + ID_PRODUCT_FROM_DATABASE=EDIROL SD-80 + +usb:v0582p002A* + ID_PRODUCT_FROM_DATABASE=EDIROL SD-80 + +usb:v0582p002B* + ID_PRODUCT_FROM_DATABASE=EDIROL UA-700 + +usb:v0582p002C* + ID_PRODUCT_FROM_DATABASE=EDIROL UA-700 + +usb:v0582p002D* + ID_PRODUCT_FROM_DATABASE=XV-2020 Synthesizer + +usb:v0582p002E* + ID_PRODUCT_FROM_DATABASE=XV-2020 Synthesizer + +usb:v0582p002F* + ID_PRODUCT_FROM_DATABASE=VariOS + +usb:v0582p0030* + ID_PRODUCT_FROM_DATABASE=VariOS + +usb:v0582p0033* + ID_PRODUCT_FROM_DATABASE=EDIROL PCR + +usb:v0582p0034* + ID_PRODUCT_FROM_DATABASE=EDIROL PCR + +usb:v0582p0037* + ID_PRODUCT_FROM_DATABASE=Digital Piano + +usb:v0582p0038* + ID_PRODUCT_FROM_DATABASE=Digital Piano + +usb:v0582p003B* + ID_PRODUCT_FROM_DATABASE=BOSS GS-10 + +usb:v0582p003C* + ID_PRODUCT_FROM_DATABASE=BOSS GS-10 + +usb:v0582p0040* + ID_PRODUCT_FROM_DATABASE=GI-20 + +usb:v0582p0041* + ID_PRODUCT_FROM_DATABASE=GI-20 + +usb:v0582p0042* + ID_PRODUCT_FROM_DATABASE=RS-70 + +usb:v0582p0043* + ID_PRODUCT_FROM_DATABASE=RS-70 + +usb:v0582p0044* + ID_PRODUCT_FROM_DATABASE=EDIROL UA-1000 + +usb:v0582p0047* + ID_PRODUCT_FROM_DATABASE=EDIROL UR-80 WAVE + +usb:v0582p0048* + ID_PRODUCT_FROM_DATABASE=EDIROL UR-80 MIDI + +usb:v0582p0049* + ID_PRODUCT_FROM_DATABASE=EDIROL UR-80 WAVE + +usb:v0582p004A* + ID_PRODUCT_FROM_DATABASE=EDIROL UR-80 MIDI + +usb:v0582p004B* + ID_PRODUCT_FROM_DATABASE=EDIROL M-100FX + +usb:v0582p004C* + ID_PRODUCT_FROM_DATABASE=EDIROL PCR-A WAVE + +usb:v0582p004D* + ID_PRODUCT_FROM_DATABASE=EDIROL PCR-A MIDI + +usb:v0582p004E* + ID_PRODUCT_FROM_DATABASE=EDIROL PCR-A WAVE + +usb:v0582p004F* + ID_PRODUCT_FROM_DATABASE=EDIROL PCR-A MIDI + +usb:v0582p0050* + ID_PRODUCT_FROM_DATABASE=EDIROL UA-3FX + +usb:v0582p0052* + ID_PRODUCT_FROM_DATABASE=EDIROL UM-1SX + +usb:v0582p0054* + ID_PRODUCT_FROM_DATABASE=Digital Piano + +usb:v0582p0060* + ID_PRODUCT_FROM_DATABASE=EXR Series + +usb:v0582p0064* + ID_PRODUCT_FROM_DATABASE=EDIROL PCR-1 WAVE + +usb:v0582p0065* + ID_PRODUCT_FROM_DATABASE=EDIROL PCR-1 MIDI + +usb:v0582p0066* + ID_PRODUCT_FROM_DATABASE=EDIROL PCR-1 WAVE + +usb:v0582p0067* + ID_PRODUCT_FROM_DATABASE=EDIROL PCR-1 MIDI + +usb:v0582p006A* + ID_PRODUCT_FROM_DATABASE=SP-606 + +usb:v0582p006B* + ID_PRODUCT_FROM_DATABASE=SP-606 + +usb:v0582p006D* + ID_PRODUCT_FROM_DATABASE=FANTOM-X + +usb:v0582p006E* + ID_PRODUCT_FROM_DATABASE=FANTOM-X + +usb:v0582p0073* + ID_PRODUCT_FROM_DATABASE=EDIROL UA-25 + +usb:v0582p0074* + ID_PRODUCT_FROM_DATABASE=EDIROL UA-25 + +usb:v0582p0075* + ID_PRODUCT_FROM_DATABASE=BOSS DR-880 + +usb:v0582p0076* + ID_PRODUCT_FROM_DATABASE=BOSS DR-880 + +usb:v0582p007A* + ID_PRODUCT_FROM_DATABASE=RD + +usb:v0582p007B* + ID_PRODUCT_FROM_DATABASE=RD + +usb:v0582p007D* + ID_PRODUCT_FROM_DATABASE=EDIROL UA-101 + +usb:v0582p0080* + ID_PRODUCT_FROM_DATABASE=G-70 + +usb:v0582p0081* + ID_PRODUCT_FROM_DATABASE=G-70 + +usb:v0582p008B* + ID_PRODUCT_FROM_DATABASE=EDIROL PC-50 + +usb:v0582p008C* + ID_PRODUCT_FROM_DATABASE=EDIROL PC-50 + +usb:v0582p008D* + ID_PRODUCT_FROM_DATABASE=EDIROL UA-101 USB1 + +usb:v0582p0092* + ID_PRODUCT_FROM_DATABASE=EDIROL PC-80 WAVE + +usb:v0582p0093* + ID_PRODUCT_FROM_DATABASE=EDIROL PC-80 MIDI + +usb:v0582p0096* + ID_PRODUCT_FROM_DATABASE=EDIROL UA-1EX + +usb:v0582p009A* + ID_PRODUCT_FROM_DATABASE=EDIROL UM-3EX + +usb:v0582p009D* + ID_PRODUCT_FROM_DATABASE=EDIROL UM-1 + +usb:v0582p00A2* + ID_PRODUCT_FROM_DATABASE=Digital Piano + +usb:v0582p00A3* + ID_PRODUCT_FROM_DATABASE=EDIROL UA-4FX + +usb:v0582p00A6* + ID_PRODUCT_FROM_DATABASE=Juno-G + +usb:v0582p00AD* + ID_PRODUCT_FROM_DATABASE=SH-201 + +usb:v0582p00B2* + ID_PRODUCT_FROM_DATABASE=VG-99 + +usb:v0582p00B3* + ID_PRODUCT_FROM_DATABASE=VG-99 + +usb:v0582p00C4* + ID_PRODUCT_FROM_DATABASE=EDIROL M-16DX + +usb:v0582p00DB* + ID_PRODUCT_FROM_DATABASE=BOSS GT-10 Guitar Effects Processor + +usb:v0582p00DE* + ID_PRODUCT_FROM_DATABASE=Fantom-G7 + +usb:v0582p00E6* + ID_PRODUCT_FROM_DATABASE=EDIROL UA-25EX (Advanced mode) + +usb:v0582p00E7* + ID_PRODUCT_FROM_DATABASE=EDIROL UA-25EX + +usb:v0582p010F* + ID_PRODUCT_FROM_DATABASE=A-PRO + +usb:v0582p0110* + ID_PRODUCT_FROM_DATABASE=A-PRO + +usb:v0582p0505* + ID_PRODUCT_FROM_DATABASE=EDIROL UA-101 + +usb:v0583* + ID_VENDOR_FROM_DATABASE=Padix Co., Ltd (Rockfire) + +usb:v0583p0001* + ID_PRODUCT_FROM_DATABASE=4 Axis 12 button +POV + +usb:v0583p0002* + ID_PRODUCT_FROM_DATABASE=4 Axis 12 button +POV + +usb:v0583p2030* + ID_PRODUCT_FROM_DATABASE=RM-203 USB Nest [mode 1] + +usb:v0583p2031* + ID_PRODUCT_FROM_DATABASE=RM-203 USB Nest [mode 2] + +usb:v0583p2032* + ID_PRODUCT_FROM_DATABASE=RM-203 USB Nest [mode 3] + +usb:v0583p2033* + ID_PRODUCT_FROM_DATABASE=RM-203 USB Nest [mode 4] + +usb:v0583p2050* + ID_PRODUCT_FROM_DATABASE=PX-205 PSX Bridge + +usb:v0583p205F* + ID_PRODUCT_FROM_DATABASE=PSX/USB converter + +usb:v0583p206F* + ID_PRODUCT_FROM_DATABASE=USB, 2-axis 8-button gamepad + +usb:v0583p3050* + ID_PRODUCT_FROM_DATABASE=QF-305u Gamepad + +usb:v0583p3379* + ID_PRODUCT_FROM_DATABASE=Rockfire X-Force + +usb:v0583p337F* + ID_PRODUCT_FROM_DATABASE=Rockfire USB RacingStar Vibra + +usb:v0583p509F* + ID_PRODUCT_FROM_DATABASE=USB,4-Axis,12-Button with POV + +usb:v0583p5259* + ID_PRODUCT_FROM_DATABASE=Rockfire USB SkyShuttle Vibra + +usb:v0583p525F* + ID_PRODUCT_FROM_DATABASE=USB Vibration Pad + +usb:v0583p5308* + ID_PRODUCT_FROM_DATABASE=USB Wireless VibrationPad + +usb:v0583p5359* + ID_PRODUCT_FROM_DATABASE=Rockfire USB SkyShuttle Pro + +usb:v0583p535F* + ID_PRODUCT_FROM_DATABASE=USB,real VibrationPad + +usb:v0583p5659* + ID_PRODUCT_FROM_DATABASE=Rockfire USB SkyShuttle Vibra + +usb:v0583p565F* + ID_PRODUCT_FROM_DATABASE=USB VibrationPad + +usb:v0583p6009* + ID_PRODUCT_FROM_DATABASE=Revenger + +usb:v0583p600F* + ID_PRODUCT_FROM_DATABASE=USB,GameBoard II + +usb:v0583p6258* + ID_PRODUCT_FROM_DATABASE=USB, 4-axis, 6-button joystick w/view finder + +usb:v0583p6889* + ID_PRODUCT_FROM_DATABASE=Windstorm Pro + +usb:v0583p688F* + ID_PRODUCT_FROM_DATABASE=QF-688uv Windstorm Pro Joystick + +usb:v0583p7070* + ID_PRODUCT_FROM_DATABASE=QF-707u Bazooka Joystick + +usb:v0583pA000* + ID_PRODUCT_FROM_DATABASE=MaxFire G-08XU Gamepad + +usb:v0583pA015* + ID_PRODUCT_FROM_DATABASE=4-Axis,16-Button with POV + +usb:v0583pA019* + ID_PRODUCT_FROM_DATABASE=USB, Vibration ,4-axis, 8-button joystick w/view finder + +usb:v0583pA020* + ID_PRODUCT_FROM_DATABASE=USB,4-Axis,10-Button with POV + +usb:v0583pA021* + ID_PRODUCT_FROM_DATABASE=USB,4-Axis,12-Button with POV + +usb:v0583pA022* + ID_PRODUCT_FROM_DATABASE=USB,4-Axis,14-Button with POV + +usb:v0583pA023* + ID_PRODUCT_FROM_DATABASE=USB,4-Axis,16-Button with POV + +usb:v0583pA024* + ID_PRODUCT_FROM_DATABASE=4axis,12button vibrition audio gamepad + +usb:v0583pA025* + ID_PRODUCT_FROM_DATABASE=4axis,12button vibrition audio gamepad + +usb:v0583pA130* + ID_PRODUCT_FROM_DATABASE=USB Wireless 2.4GHz Gamepad + +usb:v0583pA131* + ID_PRODUCT_FROM_DATABASE=USB Wireless 2.4GHz Joystick + +usb:v0583pA132* + ID_PRODUCT_FROM_DATABASE=USB Wireless 2.4GHz Wheelpad + +usb:v0583pA133* + ID_PRODUCT_FROM_DATABASE=USB Wireless 2.4GHz Wheel&Gamepad + +usb:v0583pA202* + ID_PRODUCT_FROM_DATABASE=ForceFeedbackWheel + +usb:v0583pA209* + ID_PRODUCT_FROM_DATABASE=MetalStrike FF + +usb:v0583pB000* + ID_PRODUCT_FROM_DATABASE=USB,4-Axis,12-Button with POV + +usb:v0583pB001* + ID_PRODUCT_FROM_DATABASE=USB,4-Axis,12-Button with POV + +usb:v0583pB002* + ID_PRODUCT_FROM_DATABASE=Vibration,12-Button USB Wheel + +usb:v0583pB005* + ID_PRODUCT_FROM_DATABASE=USB,12-Button Wheel + +usb:v0583pB008* + ID_PRODUCT_FROM_DATABASE=USB Wireless 2.4GHz Wheel + +usb:v0583pB009* + ID_PRODUCT_FROM_DATABASE=USB,12-Button Wheel + +usb:v0583pB00A* + ID_PRODUCT_FROM_DATABASE=PSX/USB converter + +usb:v0583pB00B* + ID_PRODUCT_FROM_DATABASE=PSX/USB converter + +usb:v0583pB00C* + ID_PRODUCT_FROM_DATABASE=PSX/USB converter + +usb:v0583pB00D* + ID_PRODUCT_FROM_DATABASE=PSX/USB converter + +usb:v0583pB00E* + ID_PRODUCT_FROM_DATABASE=4-Axis,12-Button with POV + +usb:v0583pB00F* + ID_PRODUCT_FROM_DATABASE=USB,5-Axis,10-Button with POV + +usb:v0583pB010* + ID_PRODUCT_FROM_DATABASE=MetalStrike Pro + +usb:v0583pB012* + ID_PRODUCT_FROM_DATABASE=Wireless MetalStrike + +usb:v0583pB013* + ID_PRODUCT_FROM_DATABASE=USB,Wiress 2.4GHZ Joystick + +usb:v0583pB016* + ID_PRODUCT_FROM_DATABASE=USB,5-Axis,10-Button with POV + +usb:v0583pB018* + ID_PRODUCT_FROM_DATABASE=TW6 Wheel + +usb:v0583pFF60* + ID_PRODUCT_FROM_DATABASE=USB Wireless VibrationPad + +usb:v0584* + ID_VENDOR_FROM_DATABASE=RATOC System, Inc. + +usb:v0584p0008* + ID_PRODUCT_FROM_DATABASE=Fujifilm MemoryCard ReaderWriter + +usb:v0584p0220* + ID_PRODUCT_FROM_DATABASE=U2SCX SCSI Converter + +usb:v0584pB000* + ID_PRODUCT_FROM_DATABASE=REX-USB60 + +usb:v0584pB020* + ID_PRODUCT_FROM_DATABASE=REX-USB60F + +usb:v0585* + ID_VENDOR_FROM_DATABASE=FlashPoint Technology, Inc. + +usb:v0585p0001* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v0585p0002* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v0585p0003* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v0585p0004* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v0585p0005* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v0585p0006* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v0585p0007* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v0585p0008* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v0585p0009* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v0585p000A* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v0585p000B* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v0585p000C* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v0585p000D* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v0585p000E* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v0585p000F* + ID_PRODUCT_FROM_DATABASE=Digital Camera + +usb:v0586* + ID_VENDOR_FROM_DATABASE=ZyXEL Communications Corp. + +usb:v0586p0025* + ID_PRODUCT_FROM_DATABASE=802.11b/g/n USB Wireless Network Adapter + +usb:v0586p0102* + ID_PRODUCT_FROM_DATABASE=omni.net II ISDN TA + +usb:v0586p1000* + ID_PRODUCT_FROM_DATABASE=Omni NET Modem / ISDN TA + +usb:v0586p1500* + ID_PRODUCT_FROM_DATABASE=Omni 56K Plus + +usb:v0586p2011* + ID_PRODUCT_FROM_DATABASE=Scorpion-980N keyboard + +usb:v0586p3304* + ID_PRODUCT_FROM_DATABASE=LAN Modem + +usb:v0586p3309* + ID_PRODUCT_FROM_DATABASE=ADSL Modem Prestige 600 series + +usb:v0586p330A* + ID_PRODUCT_FROM_DATABASE=ADSL Modem Interface + +usb:v0586p330E* + ID_PRODUCT_FROM_DATABASE=USB Broadband ADSL Modem Rev 1.10 + +usb:v0586p3400* + ID_PRODUCT_FROM_DATABASE=ZyAIR B-220 IEEE 802.11b Adapter + +usb:v0586p3401* + ID_PRODUCT_FROM_DATABASE=ZyAIR G-220 802.11bg + +usb:v0586p3402* + ID_PRODUCT_FROM_DATABASE=ZyAIR G-220F 802.11bg + +usb:v0586p3403* + ID_PRODUCT_FROM_DATABASE=AG-200 802.11abg Wireless Adapter [Atheros AR5523] + +usb:v0586p3407* + ID_PRODUCT_FROM_DATABASE=G-200 v2 802.11bg + +usb:v0586p3408* + ID_PRODUCT_FROM_DATABASE=G-260 802.11bg + +usb:v0586p3409* + ID_PRODUCT_FROM_DATABASE=AG-225H 802.11bg + +usb:v0586p340A* + ID_PRODUCT_FROM_DATABASE=M-202 802.11bg + +usb:v0586p340C* + ID_PRODUCT_FROM_DATABASE=G-270S 802.11bg Wireless Adapter [Atheros AR5523] + +usb:v0586p340F* + ID_PRODUCT_FROM_DATABASE=G-220 v2 802.11bg + +usb:v0586p3410* + ID_PRODUCT_FROM_DATABASE=ZyAIR G-202 802.11bg + +usb:v0586p3412* + ID_PRODUCT_FROM_DATABASE=802.11bg + +usb:v0586p3413* + ID_PRODUCT_FROM_DATABASE=ZyAIR AG-225H v2 802.11bg + +usb:v0586p3415* + ID_PRODUCT_FROM_DATABASE=G-210H 802.11g Wireless Adapter + +usb:v0586p3416* + ID_PRODUCT_FROM_DATABASE=NWD-210N 802.11b/g/n-draft wireless adapter + +usb:v0586p3417* + ID_PRODUCT_FROM_DATABASE=NWD271N 802.11n Wireless Adapter [Atheros AR9001U-(2)NG] + +usb:v0586p3418* + ID_PRODUCT_FROM_DATABASE=NWD211AN 802.11abgn Wireless Adapter [Ralink RT2870] + +usb:v0586p3419* + ID_PRODUCT_FROM_DATABASE=G-220 v3 802.11bg Wireless Adapter [ZyDAS ZD1211B] + +usb:v0586p341A* + ID_PRODUCT_FROM_DATABASE=NWD-270N Wireless N-lite USB Adapter + +usb:v0586p341E* + ID_PRODUCT_FROM_DATABASE=NWD2105 802.11bgn Wireless Adapter [Ralink RT3070] + +usb:v0586p341F* + ID_PRODUCT_FROM_DATABASE=NWD2205 802.11n Wireless N Adapter [Realtek RTL8192CU] + +usb:v0586p343E* + ID_PRODUCT_FROM_DATABASE=N220 802.11bgn Wireless Adapter + +usb:v0587* + ID_VENDOR_FROM_DATABASE=America Kotobuki Electronics Industries, Inc. + +usb:v0588* + ID_VENDOR_FROM_DATABASE=Sapien Design + +usb:v0589* + ID_VENDOR_FROM_DATABASE=Victron + +usb:v058A* + ID_VENDOR_FROM_DATABASE=Nohau Corp. + +usb:v058B* + ID_VENDOR_FROM_DATABASE=Infineon Technologies + +usb:v058Bp001C* + ID_PRODUCT_FROM_DATABASE=Flash Drive + +usb:v058C* + ID_VENDOR_FROM_DATABASE=In Focus Systems + +usb:v058Cp0007* + ID_PRODUCT_FROM_DATABASE=Flash + +usb:v058Cp0008* + ID_PRODUCT_FROM_DATABASE=LP130 + +usb:v058Cp000A* + ID_PRODUCT_FROM_DATABASE=LP530 + +usb:v058Cp0010* + ID_PRODUCT_FROM_DATABASE=Projector + +usb:v058Cp0011* + ID_PRODUCT_FROM_DATABASE=Projector + +usb:v058Cp0012* + ID_PRODUCT_FROM_DATABASE=Projector + +usb:v058Cp0013* + ID_PRODUCT_FROM_DATABASE=Projector + +usb:v058Cp0014* + ID_PRODUCT_FROM_DATABASE=Projector + +usb:v058Cp0015* + ID_PRODUCT_FROM_DATABASE=Projector + +usb:v058Cp0016* + ID_PRODUCT_FROM_DATABASE=Projector + +usb:v058Cp0017* + ID_PRODUCT_FROM_DATABASE=Projector + +usb:v058Cp0018* + ID_PRODUCT_FROM_DATABASE=Projector + +usb:v058Cp0019* + ID_PRODUCT_FROM_DATABASE=Projector + +usb:v058Cp001A* + ID_PRODUCT_FROM_DATABASE=Projector + +usb:v058Cp001B* + ID_PRODUCT_FROM_DATABASE=Projector + +usb:v058Cp001C* + ID_PRODUCT_FROM_DATABASE=Projector + +usb:v058Cp001D* + ID_PRODUCT_FROM_DATABASE=Projector + +usb:v058Cp001E* + ID_PRODUCT_FROM_DATABASE=Projector + +usb:v058Cp001F* + ID_PRODUCT_FROM_DATABASE=Projector + +usb:v058CpFFE5* + ID_PRODUCT_FROM_DATABASE=IN34 Projector + +usb:v058D* + ID_VENDOR_FROM_DATABASE=Micrel Semiconductor + +usb:v058E* + ID_VENDOR_FROM_DATABASE=Tripath Technology, Inc. + +usb:v058F* + ID_VENDOR_FROM_DATABASE=Alcor Micro Corp. + +usb:v058Fp1234* + ID_PRODUCT_FROM_DATABASE=Flash Drive + +usb:v058Fp2412* + ID_PRODUCT_FROM_DATABASE=SCard R/W CSR-145 + +usb:v058Fp2802* + ID_PRODUCT_FROM_DATABASE=Monterey Keyboard + +usb:v058Fp5492* + ID_PRODUCT_FROM_DATABASE=Hub + +usb:v058Fp6232* + ID_PRODUCT_FROM_DATABASE=Hi-Speed 16-in-1 Flash Card Reader/Writer + +usb:v058Fp6254* + ID_PRODUCT_FROM_DATABASE=USB Hub + +usb:v058Fp6331* + ID_PRODUCT_FROM_DATABASE=SD/MMC/MS Card Reader + +usb:v058Fp6332* + ID_PRODUCT_FROM_DATABASE=Multi-Function Card Reader + +usb:v058Fp6335* + ID_PRODUCT_FROM_DATABASE=SD/MMC Card Reader + +usb:v058Fp6360* + ID_PRODUCT_FROM_DATABASE=Multimedia Card Reader + +usb:v058Fp6361* + ID_PRODUCT_FROM_DATABASE=Multimedia Card Reader + +usb:v058Fp6362* + ID_PRODUCT_FROM_DATABASE=Flash Card Reader/Writer + +usb:v058Fp6364* + ID_PRODUCT_FROM_DATABASE=AU6477 Card Reader Controller + +usb:v058Fp6366* + ID_PRODUCT_FROM_DATABASE=Multi Flash Reader + +usb:v058Fp6377* + ID_PRODUCT_FROM_DATABASE=Multimedia Card Reader + +usb:v058Fp6386* + ID_PRODUCT_FROM_DATABASE=Memory Card + +usb:v058Fp6387* + ID_PRODUCT_FROM_DATABASE=Flash Drive + +usb:v058Fp6390* + ID_PRODUCT_FROM_DATABASE=USB 2.0-IDE bridge + +usb:v058Fp9213* + ID_PRODUCT_FROM_DATABASE=MacAlly Kbd Hub + +usb:v058Fp9215* + ID_PRODUCT_FROM_DATABASE=AU9814 Hub + +usb:v058Fp9254* + ID_PRODUCT_FROM_DATABASE=Hub + +usb:v058Fp9310* + ID_PRODUCT_FROM_DATABASE=Mass Storage (UID4/5A & UID7A) + +usb:v058Fp9320* + ID_PRODUCT_FROM_DATABASE=Micro Storage Driver for Win98 + +usb:v058Fp9321* + ID_PRODUCT_FROM_DATABASE=Micro Storage Driver for Win98 + +usb:v058Fp9330* + ID_PRODUCT_FROM_DATABASE=SD Reader + +usb:v058Fp9331* + ID_PRODUCT_FROM_DATABASE=Micro Storage Driver for Win98 + +usb:v058Fp9340* + ID_PRODUCT_FROM_DATABASE=Delkin eFilm Reader-32 + +usb:v058Fp9350* + ID_PRODUCT_FROM_DATABASE=Delkin eFilm Reader-32 + +usb:v058Fp9360* + ID_PRODUCT_FROM_DATABASE=8-in-1 Media Card Reader + +usb:v058Fp9361* + ID_PRODUCT_FROM_DATABASE=Multimedia Card Reader + +usb:v058Fp9368* + ID_PRODUCT_FROM_DATABASE=Multimedia Card Reader + +usb:v058Fp9380* + ID_PRODUCT_FROM_DATABASE=Flash Drive + +usb:v058Fp9382* + ID_PRODUCT_FROM_DATABASE=Acer/Sweex Flash drive + +usb:v058Fp9384* + ID_PRODUCT_FROM_DATABASE=qdi U2Disk T209M + +usb:v058Fp9410* + ID_PRODUCT_FROM_DATABASE=Keyboard + +usb:v058Fp9472* + ID_PRODUCT_FROM_DATABASE=Keyboard Hub + +usb:v058Fp9510* + ID_PRODUCT_FROM_DATABASE=ChunghwaTL USB02 Smartcard Reader + +usb:v058Fp9520* + ID_PRODUCT_FROM_DATABASE=EMV Certified Smart Card Reader + +usb:v058Fp9720* + ID_PRODUCT_FROM_DATABASE=USB-Serial Adapter + +usb:v058FpA014* + ID_PRODUCT_FROM_DATABASE=Asus Integrated Webcam + +usb:v0590* + ID_VENDOR_FROM_DATABASE=Omron Corp. + +usb:v0590p0004* + ID_PRODUCT_FROM_DATABASE=Cable Modem + +usb:v0590p000B* + ID_PRODUCT_FROM_DATABASE=MR56SVS + +usb:v0590p0028* + ID_PRODUCT_FROM_DATABASE=HJ-720IT Pedometer / Blood Pressure Monitor HEM-7080IT-E + +usb:v0591* + ID_VENDOR_FROM_DATABASE=Questra Consulting + +usb:v0592* + ID_VENDOR_FROM_DATABASE=Powerware Corp. + +usb:v0592p0002* + ID_PRODUCT_FROM_DATABASE=UPS (X-Slot) + +usb:v0593* + ID_VENDOR_FROM_DATABASE=Incite + +usb:v0594* + ID_VENDOR_FROM_DATABASE=Princeton Graphic Systems + +usb:v0595* + ID_VENDOR_FROM_DATABASE=Zoran Microelectronics, Ltd + +usb:v0595p1001* + ID_PRODUCT_FROM_DATABASE=Digitrex DSC-1300/DSC-2100 (mass storage mode) + +usb:v0595p2002* + ID_PRODUCT_FROM_DATABASE=DIGITAL STILL CAMERA 6M 4X + +usb:v0595p4343* + ID_PRODUCT_FROM_DATABASE=Digital Camera EX-20 DSC + +usb:v0596* + ID_VENDOR_FROM_DATABASE=MicroTouch Systems, Inc. + +usb:v0596p0001* + ID_PRODUCT_FROM_DATABASE=Touchscreen + +usb:v0596p0002* + ID_PRODUCT_FROM_DATABASE=Touch Screen Controller + +usb:v0596p0500* + ID_PRODUCT_FROM_DATABASE=PCT Multitouch HID Controller + +usb:v0597* + ID_VENDOR_FROM_DATABASE=Trisignal Communications + +usb:v0598* + ID_VENDOR_FROM_DATABASE=Niigata Canotec Co., Inc. + +usb:v0599* + ID_VENDOR_FROM_DATABASE=Brilliance Semiconductor, Inc. + +usb:v059A* + ID_VENDOR_FROM_DATABASE=Spectrum Signal Processing, Inc. + +usb:v059B* + ID_VENDOR_FROM_DATABASE=Iomega Corp. + +usb:v059Bp0001* + ID_PRODUCT_FROM_DATABASE=Zip 100 (Type 1) + +usb:v059Bp000B* + ID_PRODUCT_FROM_DATABASE=Zip 100 (Type 2) + +usb:v059Bp0021* + ID_PRODUCT_FROM_DATABASE=Win98 Disk Controller + +usb:v059Bp0030* + ID_PRODUCT_FROM_DATABASE=Zip 250 (Ver 1) + +usb:v059Bp0031* + ID_PRODUCT_FROM_DATABASE=Zip 100 (Type 3) + +usb:v059Bp0032* + ID_PRODUCT_FROM_DATABASE=Zip 250 (Ver 2) + +usb:v059Bp0034* + ID_PRODUCT_FROM_DATABASE=Zip 100 Driver + +usb:v059Bp0037* + ID_PRODUCT_FROM_DATABASE=Zip 750 MB + +usb:v059Bp0040* + ID_PRODUCT_FROM_DATABASE=SCSI Bridge + +usb:v059Bp0042* + ID_PRODUCT_FROM_DATABASE=Rev 70 GB + +usb:v059Bp0050* + ID_PRODUCT_FROM_DATABASE=Zip CD 650 Writer + +usb:v059Bp0053* + ID_PRODUCT_FROM_DATABASE=CDRW55292EXT CD-RW External Drive + +usb:v059Bp0056* + ID_PRODUCT_FROM_DATABASE=External CD-RW Drive Enclosure + +usb:v059Bp0057* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v059Bp005D* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v059Bp005F* + ID_PRODUCT_FROM_DATABASE=CDRW64892EXT3-C CD-RW 52x24x52x External Drive + +usb:v059Bp0060* + ID_PRODUCT_FROM_DATABASE=PCMCIA PocketZip Dock + +usb:v059Bp0061* + ID_PRODUCT_FROM_DATABASE=Varo PocketZip 40 MP3 Player + +usb:v059Bp006D* + ID_PRODUCT_FROM_DATABASE=HipZip MP3 Player + +usb:v059Bp007C* + ID_PRODUCT_FROM_DATABASE=Ultra Max USB/1394 + +usb:v059Bp007D* + ID_PRODUCT_FROM_DATABASE=HTC42606 0G9AT00 [Iomega HDD] + +usb:v059Bp007E* + ID_PRODUCT_FROM_DATABASE=Mini 256MB/512MB Flash Drive [IOM2D5] + +usb:v059Bp00DB* + ID_PRODUCT_FROM_DATABASE=FotoShow Zip 250 Driver + +usb:v059Bp0150* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v059Bp015D* + ID_PRODUCT_FROM_DATABASE=Super DVD Writer + +usb:v059Bp0173* + ID_PRODUCT_FROM_DATABASE=Hi-Speed USB-to-IDE Bridge Controller + +usb:v059Bp0174* + ID_PRODUCT_FROM_DATABASE=Hi-Speed USB-to-IDE Bridge Controller + +usb:v059Bp0176* + ID_PRODUCT_FROM_DATABASE=Hi-Speed USB-to-IDE Bridge Controller + +usb:v059Bp0177* + ID_PRODUCT_FROM_DATABASE=Hi-Speed USB-to-IDE Bridge Controller + +usb:v059Bp0178* + ID_PRODUCT_FROM_DATABASE=Hi-Speed USB-to-IDE Bridge Controller + +usb:v059Bp0179* + ID_PRODUCT_FROM_DATABASE=Hi-Speed USB-to-IDE Bridge Controller + +usb:v059Bp017A* + ID_PRODUCT_FROM_DATABASE=HDD + +usb:v059Bp017B* + ID_PRODUCT_FROM_DATABASE=HDD/1394A + +usb:v059Bp017C* + ID_PRODUCT_FROM_DATABASE=HDD/1394B + +usb:v059Bp0251* + ID_PRODUCT_FROM_DATABASE=Optical + +usb:v059Bp0252* + ID_PRODUCT_FROM_DATABASE=Optical + +usb:v059Bp0278* + ID_PRODUCT_FROM_DATABASE=LDHD-UPS [Professional Desktop Hard Drive eSATA / USB2.0] + +usb:v059Bp027A* + ID_PRODUCT_FROM_DATABASE=LPHD250-U [Portable Hard Drive Silver Series 250 Go] + +usb:v059Bp0470* + ID_PRODUCT_FROM_DATABASE=Prestige Portable Hard Drive + +usb:v059Bp047A* + ID_PRODUCT_FROM_DATABASE=Select Portable Hard Drive + +usb:v059Bp0571* + ID_PRODUCT_FROM_DATABASE=Prestige Portable Hard Drive + +usb:v059Bp0579* + ID_PRODUCT_FROM_DATABASE=eGo Portable Hard Drive + +usb:v059Bp1052* + ID_PRODUCT_FROM_DATABASE=DVD+RW External Drive + +usb:v059C* + ID_VENDOR_FROM_DATABASE=A-Trend Technology Co., Ltd + +usb:v059D* + ID_VENDOR_FROM_DATABASE=Advanced Input Devices + +usb:v059E* + ID_VENDOR_FROM_DATABASE=Intelligent Instrumentation + +usb:v059F* + ID_VENDOR_FROM_DATABASE=LaCie, Ltd + +usb:v059Fp0201* + ID_PRODUCT_FROM_DATABASE=StudioDrive USB2 + +usb:v059Fp0202* + ID_PRODUCT_FROM_DATABASE=StudioDrive USB2 + +usb:v059Fp0203* + ID_PRODUCT_FROM_DATABASE=StudioDrive USB2 + +usb:v059Fp0211* + ID_PRODUCT_FROM_DATABASE=PocketDrive + +usb:v059Fp0212* + ID_PRODUCT_FROM_DATABASE=PocketDrive + +usb:v059Fp0213* + ID_PRODUCT_FROM_DATABASE=PocketDrive USB2 + +usb:v059Fp0323* + ID_PRODUCT_FROM_DATABASE=LaCie d2 Drive USB2 + +usb:v059Fp0421* + ID_PRODUCT_FROM_DATABASE=Big Disk G465 + +usb:v059Fp0641* + ID_PRODUCT_FROM_DATABASE=Mobile Hard Drive + +usb:v059Fp1010* + ID_PRODUCT_FROM_DATABASE=Desktop Hard Drive + +usb:v059Fp1019* + ID_PRODUCT_FROM_DATABASE=Desktop Hard Drive + +usb:v059Fp1021* + ID_PRODUCT_FROM_DATABASE=Little Disk + +usb:v059Fp1027* + ID_PRODUCT_FROM_DATABASE=iamaKey V2 + +usb:v059Fp102A* + ID_PRODUCT_FROM_DATABASE=Rikiki Hard Drive + +usb:v059Fp1049* + ID_PRODUCT_FROM_DATABASE=rikiki Harddrive + +usb:v059Fp1052* + ID_PRODUCT_FROM_DATABASE=P'9220 Mobile Drive + +usb:v059FpA601* + ID_PRODUCT_FROM_DATABASE=HardDrive + +usb:v059FpA602* + ID_PRODUCT_FROM_DATABASE=CD R/W + +usb:v05A0* + ID_VENDOR_FROM_DATABASE=Vetronix Corp. + +usb:v05A1* + ID_VENDOR_FROM_DATABASE=USC Corp. + +usb:v05A2* + ID_VENDOR_FROM_DATABASE=Fuji Film Microdevices Co., Ltd + +usb:v05A3* + ID_VENDOR_FROM_DATABASE=ARC International + +usb:v05A3p8388* + ID_PRODUCT_FROM_DATABASE=Marvell 88W8388 802.11a/b/g WLAN + +usb:v05A4* + ID_VENDOR_FROM_DATABASE=Ortek Technology, Inc. + +usb:v05A4p1000* + ID_PRODUCT_FROM_DATABASE=WKB-1000S Wireless Ergo Keyboard with Touchpad + +usb:v05A4p2000* + ID_PRODUCT_FROM_DATABASE=WKB-2000 Wireless Keyboard with Touchpad + +usb:v05A4p9720* + ID_PRODUCT_FROM_DATABASE=Keyboard Mouse + +usb:v05A4p9722* + ID_PRODUCT_FROM_DATABASE=Keyboard + +usb:v05A4p9731* + ID_PRODUCT_FROM_DATABASE=MCK-600W/MCK-800USB Keyboard + +usb:v05A4p9783* + ID_PRODUCT_FROM_DATABASE=Wireless Keypad + +usb:v05A5* + ID_VENDOR_FROM_DATABASE=Sampo Technology Corp. + +usb:v05A6* + ID_VENDOR_FROM_DATABASE=Cisco Systems, Inc. + +usb:v05A6p0001* + ID_PRODUCT_FROM_DATABASE=CVA124 Cable Voice Adapter (WDM) + +usb:v05A6p0002* + ID_PRODUCT_FROM_DATABASE=CVA122 Cable Voice Adapter (WDM) + +usb:v05A6p0003* + ID_PRODUCT_FROM_DATABASE=CVA124E Cable Voice Adapter (WDM) + +usb:v05A6p0004* + ID_PRODUCT_FROM_DATABASE=CVA122E Cable Voice Adapter (WDM) + +usb:v05A7* + ID_VENDOR_FROM_DATABASE=Bose Corp. + +usb:v05A8* + ID_VENDOR_FROM_DATABASE=Spacetec IMC Corp. + +usb:v05A9* + ID_VENDOR_FROM_DATABASE=OmniVision Technologies, Inc. + +usb:v05A9p0511* + ID_PRODUCT_FROM_DATABASE=OV511 Webcam + +usb:v05A9p0518* + ID_PRODUCT_FROM_DATABASE=OV518 Webcam + +usb:v05A9p0519* + ID_PRODUCT_FROM_DATABASE=OV519 Microphone + +usb:v05A9p1550* + ID_PRODUCT_FROM_DATABASE=VEHO Filmscanner + +usb:v05A9p2640* + ID_PRODUCT_FROM_DATABASE=OV2640 Webcam + +usb:v05A9p2643* + ID_PRODUCT_FROM_DATABASE=Monitor Webcam + +usb:v05A9p264B* + ID_PRODUCT_FROM_DATABASE=Monitor Webcam + +usb:v05A9p2800* + ID_PRODUCT_FROM_DATABASE=SuperCAM + +usb:v05A9p4519* + ID_PRODUCT_FROM_DATABASE=Webcam Classic + +usb:v05A9p7670* + ID_PRODUCT_FROM_DATABASE=OV7670 Webcam + +usb:v05A9p8519* + ID_PRODUCT_FROM_DATABASE=OV519 Webcam + +usb:v05A9pA511* + ID_PRODUCT_FROM_DATABASE=OV511+ Webcam + +usb:v05A9pA518* + ID_PRODUCT_FROM_DATABASE=D-Link DSB-C310 Webcam + +usb:v05AA* + ID_VENDOR_FROM_DATABASE=Utilux South China, Ltd + +usb:v05AB* + ID_VENDOR_FROM_DATABASE=In-System Design + +usb:v05ABp0002* + ID_PRODUCT_FROM_DATABASE=Parallel Port + +usb:v05ABp0030* + ID_PRODUCT_FROM_DATABASE=Storage Adapter V2 (TPP) + +usb:v05ABp0031* + ID_PRODUCT_FROM_DATABASE=ATA Bridge + +usb:v05ABp0060* + ID_PRODUCT_FROM_DATABASE=USB 2.0 ATA Bridge + +usb:v05ABp0061* + ID_PRODUCT_FROM_DATABASE=Storage Adapter V3 (TPP-I) + +usb:v05ABp0101* + ID_PRODUCT_FROM_DATABASE=Storage Adapter (TPP) + +usb:v05ABp0130* + ID_PRODUCT_FROM_DATABASE=Compact Flash and Microdrive Reader (TPP) + +usb:v05ABp0200* + ID_PRODUCT_FROM_DATABASE=USS725 ATA Bridge + +usb:v05ABp0201* + ID_PRODUCT_FROM_DATABASE=Storage Adapter (TPP) + +usb:v05ABp0202* + ID_PRODUCT_FROM_DATABASE=ATA Bridge + +usb:v05ABp0300* + ID_PRODUCT_FROM_DATABASE=Portable Hard Drive (TPP) + +usb:v05ABp0301* + ID_PRODUCT_FROM_DATABASE=Portable Hard Drive V2 + +usb:v05ABp0350* + ID_PRODUCT_FROM_DATABASE=Portable Hard Drive (TPP) + +usb:v05ABp0351* + ID_PRODUCT_FROM_DATABASE=Portable Hard Drive V2 + +usb:v05ABp081A* + ID_PRODUCT_FROM_DATABASE=ATA Bridge + +usb:v05ABp0CDA* + ID_PRODUCT_FROM_DATABASE=ATA Bridge for CD-R/RW + +usb:v05ABp1001* + ID_PRODUCT_FROM_DATABASE=BAYI Printer Class Support + +usb:v05ABp5700* + ID_PRODUCT_FROM_DATABASE=Storage Adapter V2 (TPP) + +usb:v05ABp5701* + ID_PRODUCT_FROM_DATABASE=USB Storage Adapter V2 + +usb:v05ABp5901* + ID_PRODUCT_FROM_DATABASE=Smart Board (TPP) + +usb:v05ABp5A01* + ID_PRODUCT_FROM_DATABASE=ATI Storage Adapter (TPP) + +usb:v05ABp5D01* + ID_PRODUCT_FROM_DATABASE=DataBook Adapter (TPP) + +usb:v05AC* + ID_VENDOR_FROM_DATABASE=Apple, Inc. + +usb:v05ACp0201* + ID_PRODUCT_FROM_DATABASE=USB Keyboard [Alps or Logitech, M2452] + +usb:v05ACp0202* + ID_PRODUCT_FROM_DATABASE=Keyboard [ALPS] + +usb:v05ACp0205* + ID_PRODUCT_FROM_DATABASE=Extended Keyboard [Mitsumi] + +usb:v05ACp0206* + ID_PRODUCT_FROM_DATABASE=Extended Keyboard [Mitsumi] + +usb:v05ACp020B* + ID_PRODUCT_FROM_DATABASE=Pro Keyboard [Mitsumi, A1048/US layout] + +usb:v05ACp020C* + ID_PRODUCT_FROM_DATABASE=Extended Keyboard [Mitsumi] + +usb:v05ACp020D* + ID_PRODUCT_FROM_DATABASE=Pro Keyboard [Mitsumi, A1048/JIS layout] + +usb:v05ACp020E* + ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (ANSI) + +usb:v05ACp020F* + ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (ISO) + +usb:v05ACp0214* + ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (ANSI) + +usb:v05ACp0215* + ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (ISO) + +usb:v05ACp0216* + ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (JIS) + +usb:v05ACp0217* + ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (ANSI) + +usb:v05ACp0218* + ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (ISO) + +usb:v05ACp0219* + ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (JIS) + +usb:v05ACp021A* + ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (ANSI) + +usb:v05ACp021B* + ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (ISO) + +usb:v05ACp021C* + ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (JIS) + +usb:v05ACp021D* + ID_PRODUCT_FROM_DATABASE=Aluminum Mini Keyboard (ANSI) + +usb:v05ACp021E* + ID_PRODUCT_FROM_DATABASE=Aluminum Mini Keyboard (ISO) + +usb:v05ACp021F* + ID_PRODUCT_FROM_DATABASE=Aluminum Mini Keyboard (JIS) + +usb:v05ACp0220* + ID_PRODUCT_FROM_DATABASE=Aluminum Keyboard (ANSI) + +usb:v05ACp0221* + ID_PRODUCT_FROM_DATABASE=Aluminum Keyboard (ISO) + +usb:v05ACp0222* + ID_PRODUCT_FROM_DATABASE=Aluminum Keyboard (JIS) + +usb:v05ACp0223* + ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (ANSI) + +usb:v05ACp0224* + ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (ISO) + +usb:v05ACp0225* + ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (JIS) + +usb:v05ACp0229* + ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (MacBook Pro) (ANSI) + +usb:v05ACp022A* + ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (MacBook Pro) (ISO) + +usb:v05ACp022B* + ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (MacBook Pro) (JIS) + +usb:v05ACp0230* + ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (MacBook Pro 4,1) (ANSI) + +usb:v05ACp0231* + ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (MacBook Pro 4,1) (ISO) + +usb:v05ACp0232* + ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (MacBook Pro 4,1) (JIS) + +usb:v05ACp0236* + ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (ANSI) + +usb:v05ACp0237* + ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (ISO) + +usb:v05ACp0238* + ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (JIS) + +usb:v05ACp023F* + ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (ANSI) + +usb:v05ACp0240* + ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (ISO) + +usb:v05ACp0241* + ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (JIS) + +usb:v05ACp0242* + ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (ANSI) + +usb:v05ACp0243* + ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (ISO) + +usb:v05ACp0244* + ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (JIS) + +usb:v05ACp0245* + ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (ANSI) + +usb:v05ACp0246* + ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (ISO) + +usb:v05ACp0247* + ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (JIS) + +usb:v05ACp024D* + ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (MacBook Air) (ISO) + +usb:v05ACp0250* + ID_PRODUCT_FROM_DATABASE=Aluminium Keyboard (ISO) + +usb:v05ACp0252* + ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (ANSI) + +usb:v05ACp0253* + ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (ISO) + +usb:v05ACp0254* + ID_PRODUCT_FROM_DATABASE=Internal Keyboard/Trackpad (JIS) + +usb:v05ACp0301* + ID_PRODUCT_FROM_DATABASE=USB Mouse [Mitsumi, M4848] + +usb:v05ACp0302* + ID_PRODUCT_FROM_DATABASE=Optical Mouse [Fujitsu] + +usb:v05ACp0304* + ID_PRODUCT_FROM_DATABASE=Optical USB Mouse [Mitsumi] + +usb:v05ACp0306* + ID_PRODUCT_FROM_DATABASE=Optical USB Mouse [Fujitsu] + +usb:v05ACp030A* + ID_PRODUCT_FROM_DATABASE=Internal Trackpad + +usb:v05ACp030B* + ID_PRODUCT_FROM_DATABASE=Internal Trackpad + +usb:v05ACp030D* + ID_PRODUCT_FROM_DATABASE=Magic Mouse + +usb:v05ACp030E* + ID_PRODUCT_FROM_DATABASE=MC380Z/A [Magic Trackpad] + +usb:v05ACp1000* + ID_PRODUCT_FROM_DATABASE=Bluetooth HCI MacBookPro (HID mode) + +usb:v05ACp1001* + ID_PRODUCT_FROM_DATABASE=Keyboard Hub [ALPS] + +usb:v05ACp1002* + ID_PRODUCT_FROM_DATABASE=Extended Keyboard Hub [Mitsumi] + +usb:v05ACp1003* + ID_PRODUCT_FROM_DATABASE=Hub in Pro Keyboard [Mitsumi, A1048] + +usb:v05ACp1006* + ID_PRODUCT_FROM_DATABASE=Hub in Aluminum Keyboard + +usb:v05ACp1101* + ID_PRODUCT_FROM_DATABASE=Speakers + +usb:v05ACp1105* + ID_PRODUCT_FROM_DATABASE=Audio in LED Cinema Display + +usb:v05ACp1107* + ID_PRODUCT_FROM_DATABASE=Thunderbolt Display Audio + +usb:v05ACp1201* + ID_PRODUCT_FROM_DATABASE=3G iPod + +usb:v05ACp1202* + ID_PRODUCT_FROM_DATABASE=iPod 2G + +usb:v05ACp1203* + ID_PRODUCT_FROM_DATABASE=iPod 4.Gen Grayscale 40G + +usb:v05ACp1204* + ID_PRODUCT_FROM_DATABASE=iPod [Photo] + +usb:v05ACp1205* + ID_PRODUCT_FROM_DATABASE=iPod Mini 1.Gen/2.Gen + +usb:v05ACp1206* + ID_PRODUCT_FROM_DATABASE=iPod '06' + +usb:v05ACp1207* + ID_PRODUCT_FROM_DATABASE=iPod '07' + +usb:v05ACp1208* + ID_PRODUCT_FROM_DATABASE=iPod '08' + +usb:v05ACp1209* + ID_PRODUCT_FROM_DATABASE=iPod Video + +usb:v05ACp120A* + ID_PRODUCT_FROM_DATABASE=iPod Nano + +usb:v05ACp1223* + ID_PRODUCT_FROM_DATABASE=iPod Classic/Nano 3.Gen (DFU mode) + +usb:v05ACp1224* + ID_PRODUCT_FROM_DATABASE=iPod Nano 3.Gen (DFU mode) + +usb:v05ACp1225* + ID_PRODUCT_FROM_DATABASE=iPod Nano 4.Gen (DFU mode) + +usb:v05ACp1227* + ID_PRODUCT_FROM_DATABASE=Mobile Device (DFU Mode) + +usb:v05ACp1231* + ID_PRODUCT_FROM_DATABASE=iPod Nano 5.Gen (DFU mode) + +usb:v05ACp1240* + ID_PRODUCT_FROM_DATABASE=iPod Nano 2.Gen (DFU mode) + +usb:v05ACp1242* + ID_PRODUCT_FROM_DATABASE=iPod Nano 3.Gen (WTF mode) + +usb:v05ACp1243* + ID_PRODUCT_FROM_DATABASE=iPod Nano 4.Gen (WTF mode) + +usb:v05ACp1245* + ID_PRODUCT_FROM_DATABASE=iPod Classic 3.Gen (WTF mode) + +usb:v05ACp1246* + ID_PRODUCT_FROM_DATABASE=iPod Nano 5.Gen (WTF mode) + +usb:v05ACp1255* + ID_PRODUCT_FROM_DATABASE=iPod Nano 4.Gen (DFU mode) + +usb:v05ACp1260* + ID_PRODUCT_FROM_DATABASE=iPod Nano 2.Gen + +usb:v05ACp1261* + ID_PRODUCT_FROM_DATABASE=iPod Classic + +usb:v05ACp1262* + ID_PRODUCT_FROM_DATABASE=iPod Nano 3.Gen + +usb:v05ACp1263* + ID_PRODUCT_FROM_DATABASE=iPod Nano 4.Gen + +usb:v05ACp1265* + ID_PRODUCT_FROM_DATABASE=iPod Nano 5.Gen + +usb:v05ACp1266* + ID_PRODUCT_FROM_DATABASE=iPod Nano 6.Gen + +usb:v05ACp1281* + ID_PRODUCT_FROM_DATABASE=Apple Mobile Device [Recovery Mode] + +usb:v05ACp1290* + ID_PRODUCT_FROM_DATABASE=iPhone + +usb:v05ACp1291* + ID_PRODUCT_FROM_DATABASE=iPod Touch 1.Gen + +usb:v05ACp1292* + ID_PRODUCT_FROM_DATABASE=iPhone 3G + +usb:v05ACp1293* + ID_PRODUCT_FROM_DATABASE=iPod Touch 2.Gen + +usb:v05ACp1294* + ID_PRODUCT_FROM_DATABASE=iPhone 3GS + +usb:v05ACp1296* + ID_PRODUCT_FROM_DATABASE=iPod Touch 3.Gen (8GB) + +usb:v05ACp1297* + ID_PRODUCT_FROM_DATABASE=iPhone 4 + +usb:v05ACp1299* + ID_PRODUCT_FROM_DATABASE=iPod Touch 3.Gen + +usb:v05ACp129A* + ID_PRODUCT_FROM_DATABASE=iPad + +usb:v05ACp129E* + ID_PRODUCT_FROM_DATABASE=iPod Touch 4.Gen + +usb:v05ACp129F* + ID_PRODUCT_FROM_DATABASE=iPad 2 + +usb:v05ACp12A0* + ID_PRODUCT_FROM_DATABASE=iPhone 4S + +usb:v05ACp12A2* + ID_PRODUCT_FROM_DATABASE=iPad 2 (3G; 64GB) + +usb:v05ACp12A9* + ID_PRODUCT_FROM_DATABASE=iPad 2 + +usb:v05ACp12AA* + ID_PRODUCT_FROM_DATABASE=iPod Touch 5.Gen [A1421] + +usb:v05ACp1300* + ID_PRODUCT_FROM_DATABASE=iPod Shuffle + +usb:v05ACp1301* + ID_PRODUCT_FROM_DATABASE=iPod Shuffle 2.Gen + +usb:v05ACp1302* + ID_PRODUCT_FROM_DATABASE=iPod Shuffle 3.Gen + +usb:v05ACp1303* + ID_PRODUCT_FROM_DATABASE=iPod Shuffle 4.Gen + +usb:v05ACp1401* + ID_PRODUCT_FROM_DATABASE=Modem + +usb:v05ACp1402* + ID_PRODUCT_FROM_DATABASE=Ethernet Adapter [A1277] + +usb:v05ACp8202* + ID_PRODUCT_FROM_DATABASE=HCF V.90 Data/Fax Modem + +usb:v05ACp8203* + ID_PRODUCT_FROM_DATABASE=Bluetooth HCI + +usb:v05ACp8204* + ID_PRODUCT_FROM_DATABASE=Built-in Bluetooth 2.0+EDR HCI + +usb:v05ACp8205* + ID_PRODUCT_FROM_DATABASE=Bluetooth HCI + +usb:v05ACp8206* + ID_PRODUCT_FROM_DATABASE=Bluetooth HCI + +usb:v05ACp820A* + ID_PRODUCT_FROM_DATABASE=Bluetooth HID Keyboard + +usb:v05ACp820B* + ID_PRODUCT_FROM_DATABASE=Bluetooth HID Mouse + +usb:v05ACp820F* + ID_PRODUCT_FROM_DATABASE=Bluetooth HCI + +usb:v05ACp8213* + ID_PRODUCT_FROM_DATABASE=Bluetooth Host Controller + +usb:v05ACp8215* + ID_PRODUCT_FROM_DATABASE=Built-in Bluetooth 2.0+EDR HCI + +usb:v05ACp8216* + ID_PRODUCT_FROM_DATABASE=Bluetooth USB Host Controller + +usb:v05ACp8217* + ID_PRODUCT_FROM_DATABASE=Bluetooth USB Host Controller + +usb:v05ACp8218* + ID_PRODUCT_FROM_DATABASE=Bluetooth Host Controller + +usb:v05ACp821A* + ID_PRODUCT_FROM_DATABASE=Bluetooth Host Controller + +usb:v05ACp821F* + ID_PRODUCT_FROM_DATABASE=Built-in Bluetooth 2.0+EDR HCI + +usb:v05ACp8240* + ID_PRODUCT_FROM_DATABASE=Built-in IR Receiver + +usb:v05ACp8241* + ID_PRODUCT_FROM_DATABASE=Built-in IR Receiver + +usb:v05ACp8242* + ID_PRODUCT_FROM_DATABASE=Built-in IR Receiver + +usb:v05ACp8300* + ID_PRODUCT_FROM_DATABASE=Built-in iSight (no firmware loaded) + +usb:v05ACp8403* + ID_PRODUCT_FROM_DATABASE=Internal Memory Card Reader + +usb:v05ACp8404* + ID_PRODUCT_FROM_DATABASE=Internal Memory Card Reader + +usb:v05ACp8501* + ID_PRODUCT_FROM_DATABASE=Built-in iSight [Micron] + +usb:v05ACp8502* + ID_PRODUCT_FROM_DATABASE=Built-in iSight + +usb:v05ACp8505* + ID_PRODUCT_FROM_DATABASE=Built-in iSight + +usb:v05ACp8507* + ID_PRODUCT_FROM_DATABASE=Built-in iSight + +usb:v05ACp8508* + ID_PRODUCT_FROM_DATABASE=iSight in LED Cinema Display + +usb:v05ACp8509* + ID_PRODUCT_FROM_DATABASE=FaceTime HD Camera + +usb:v05ACp850A* + ID_PRODUCT_FROM_DATABASE=FaceTime Camera + +usb:v05ACp911C* + ID_PRODUCT_FROM_DATABASE=Hub in A1082 [Cinema HD Display 23"] + +usb:v05ACp912F* + ID_PRODUCT_FROM_DATABASE=Hub in 30" Cinema Display + +usb:v05ACp9215* + ID_PRODUCT_FROM_DATABASE=Studio Display 15" + +usb:v05ACp9217* + ID_PRODUCT_FROM_DATABASE=Studio Display 17" + +usb:v05ACp9218* + ID_PRODUCT_FROM_DATABASE=Cinema Display 23" + +usb:v05ACp9219* + ID_PRODUCT_FROM_DATABASE=Cinema Display 20" + +usb:v05ACp921C* + ID_PRODUCT_FROM_DATABASE=A1082 [Cinema HD Display 23"] + +usb:v05ACp921E* + ID_PRODUCT_FROM_DATABASE=Cinema Display 24" + +usb:v05ACp9221* + ID_PRODUCT_FROM_DATABASE=30" Cinema Display + +usb:v05ACp9226* + ID_PRODUCT_FROM_DATABASE=LED Cinema Display + +usb:v05ACp9227* + ID_PRODUCT_FROM_DATABASE=Thunderbolt Display + +usb:v05ACp9232* + ID_PRODUCT_FROM_DATABASE=Cinema HD Display 30" + +usb:v05ACpFFFF* + ID_PRODUCT_FROM_DATABASE=Bluetooth in DFU mode - Driver + +usb:v05AD* + ID_VENDOR_FROM_DATABASE=Y.C. Cable U.S.A., Inc. + +usb:v05AE* + ID_VENDOR_FROM_DATABASE=Synopsys, Inc. + +usb:v05AF* + ID_VENDOR_FROM_DATABASE=Jing-Mold Enterprise Co., Ltd + +usb:v05AFp0806* + ID_PRODUCT_FROM_DATABASE=HP SK806A Keyboard + +usb:v05AFp0809* + ID_PRODUCT_FROM_DATABASE=Wireless Keyboard and Mouse + +usb:v05AFp0821* + ID_PRODUCT_FROM_DATABASE=IDE to + +usb:v05AFp3062* + ID_PRODUCT_FROM_DATABASE=Cordless Keyboard + +usb:v05AFp9167* + ID_PRODUCT_FROM_DATABASE=KB 9151B - 678 + +usb:v05AFp9267* + ID_PRODUCT_FROM_DATABASE=KB 9251B - 678 Mouse + +usb:v05B0* + ID_VENDOR_FROM_DATABASE=Fountain Technologies, Inc. + +usb:v05B1* + ID_VENDOR_FROM_DATABASE=First International Computer, Inc. + +usb:v05B1p1389* + ID_PRODUCT_FROM_DATABASE=Bluetooth Wireless Adapter + +usb:v05B4* + ID_VENDOR_FROM_DATABASE=LG Semicon Co., Ltd + +usb:v05B4p4857* + ID_PRODUCT_FROM_DATABASE=M-Any DAH-210 + +usb:v05B4p6001* + ID_PRODUCT_FROM_DATABASE=Digisette DUO-MP3 AR-100 + +usb:v05B5* + ID_VENDOR_FROM_DATABASE=Dialogic Corp. + +usb:v05B6* + ID_VENDOR_FROM_DATABASE=Proxima Corp. + +usb:v05B7* + ID_VENDOR_FROM_DATABASE=Medianix Semiconductor, Inc. + +usb:v05B8* + ID_VENDOR_FROM_DATABASE=Agiler, Inc. + +usb:v05B8p3002* + ID_PRODUCT_FROM_DATABASE=Scroll Mouse + +usb:v05B9* + ID_VENDOR_FROM_DATABASE=Philips Research Laboratories + +usb:v05BA* + ID_VENDOR_FROM_DATABASE=DigitalPersona, Inc. + +usb:v05BAp0007* + ID_PRODUCT_FROM_DATABASE=Fingerprint Reader + +usb:v05BAp0008* + ID_PRODUCT_FROM_DATABASE=Fingerprint Reader + +usb:v05BAp000A* + ID_PRODUCT_FROM_DATABASE=Fingerprint Reader + +usb:v05BB* + ID_VENDOR_FROM_DATABASE=Grey Cell Systems + +usb:v05BC* + ID_VENDOR_FROM_DATABASE=3G Green Green Globe Co., Ltd + +usb:v05BCp0004* + ID_PRODUCT_FROM_DATABASE=Trackball + +usb:v05BD* + ID_VENDOR_FROM_DATABASE=RAFI GmbH & Co. KG + +usb:v05BE* + ID_VENDOR_FROM_DATABASE=Tyco Electronics (Raychem) + +usb:v05BF* + ID_VENDOR_FROM_DATABASE=S & S Research + +usb:v05C0* + ID_VENDOR_FROM_DATABASE=Keil Software + +usb:v05C1* + ID_VENDOR_FROM_DATABASE=Kawasaki Microelectronics, Inc. + +usb:v05C2* + ID_VENDOR_FROM_DATABASE=Media Phonics (Suisse) S.A. + +usb:v05C5* + ID_VENDOR_FROM_DATABASE=Digi International, Inc. + +usb:v05C5p0002* + ID_PRODUCT_FROM_DATABASE=AccelePort USB 2 + +usb:v05C5p0004* + ID_PRODUCT_FROM_DATABASE=AccelePort USB 4 + +usb:v05C5p0008* + ID_PRODUCT_FROM_DATABASE=AccelePort USB 8 + +usb:v05C6* + ID_VENDOR_FROM_DATABASE=Qualcomm, Inc. + +usb:v05C6p0114* + ID_PRODUCT_FROM_DATABASE=Select RW-200 CDMA Wireless Modem + +usb:v05C6p1000* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v05C6p3100* + ID_PRODUCT_FROM_DATABASE=CDMA Wireless Modem/Phone + +usb:v05C6p3196* + ID_PRODUCT_FROM_DATABASE=CDMA Wireless Modem + +usb:v05C6p3197* + ID_PRODUCT_FROM_DATABASE=CDMA Wireless Modem/Phone + +usb:v05C6p6000* + ID_PRODUCT_FROM_DATABASE=Siemens SG75 + +usb:v05C6p6503* + ID_PRODUCT_FROM_DATABASE=AnyData APE-540H + +usb:v05C6p6613* + ID_PRODUCT_FROM_DATABASE=Onda H600/N501HS ZTE MF330 + +usb:v05C6p9000* + ID_PRODUCT_FROM_DATABASE=SIMCom SIM5218 modem + +usb:v05C6p9001* + ID_PRODUCT_FROM_DATABASE=Gobi Wireless Modem + +usb:v05C6p9002* + ID_PRODUCT_FROM_DATABASE=Gobi Wireless Modem + +usb:v05C6p9008* + ID_PRODUCT_FROM_DATABASE=Gobi Wireless Modem (QDL mode) + +usb:v05C6p9018* + ID_PRODUCT_FROM_DATABASE=Qualcomm HSUSB Device + +usb:v05C6p9025* + ID_PRODUCT_FROM_DATABASE=Qualcomm HSUSB Device + +usb:v05C6p9201* + ID_PRODUCT_FROM_DATABASE=Gobi Wireless Modem (QDL mode) + +usb:v05C6p9202* + ID_PRODUCT_FROM_DATABASE=Gobi Wireless Modem + +usb:v05C6p9203* + ID_PRODUCT_FROM_DATABASE=Gobi Wireless Modem + +usb:v05C6p9211* + ID_PRODUCT_FROM_DATABASE=Acer Gobi Wireless Modem (QDL mode) + +usb:v05C6p9212* + ID_PRODUCT_FROM_DATABASE=Acer Gobi Wireless Modem + +usb:v05C6p9214* + ID_PRODUCT_FROM_DATABASE=Acer Gobi 2000 Wireless Modem (QDL mode) + +usb:v05C6p9215* + ID_PRODUCT_FROM_DATABASE=Acer Gobi 2000 Wireless Modem + +usb:v05C6p9221* + ID_PRODUCT_FROM_DATABASE=Gobi Wireless Modem (QDL mode) + +usb:v05C6p9222* + ID_PRODUCT_FROM_DATABASE=Gobi Wireless Modem + +usb:v05C6p9224* + ID_PRODUCT_FROM_DATABASE=Sony Gobi 2000 Wireless Modem (QDL mode) + +usb:v05C6p9225* + ID_PRODUCT_FROM_DATABASE=Sony Gobi 2000 Wireless Modem + +usb:v05C6p9231* + ID_PRODUCT_FROM_DATABASE=Gobi Wireless Modem (QDL mode) + +usb:v05C6p9234* + ID_PRODUCT_FROM_DATABASE=Top Global Gobi 2000 Wireless Modem (QDL mode) + +usb:v05C6p9235* + ID_PRODUCT_FROM_DATABASE=Top Global Gobi 2000 Wireless Modem + +usb:v05C6p9244* + ID_PRODUCT_FROM_DATABASE=Samsung Gobi 2000 Wireless Modem (QDL mode) + +usb:v05C6p9245* + ID_PRODUCT_FROM_DATABASE=Samsung Gobi 2000 Wireless Modem + +usb:v05C6p9264* + ID_PRODUCT_FROM_DATABASE=Asus Gobi 2000 Wireless Modem (QDL mode) + +usb:v05C6p9265* + ID_PRODUCT_FROM_DATABASE=Asus Gobi 2000 Wireless Modem + +usb:v05C6p9274* + ID_PRODUCT_FROM_DATABASE=iRex Technologies Gobi 2000 Wireless Modem (QDL mode) + +usb:v05C6p9275* + ID_PRODUCT_FROM_DATABASE=iRex Technologies Gobi 2000 Wireless Modem + +usb:v05C7* + ID_VENDOR_FROM_DATABASE=Qtronix Corp. + +usb:v05C7p0113* + ID_PRODUCT_FROM_DATABASE=PC Line Mouse + +usb:v05C7p1001* + ID_PRODUCT_FROM_DATABASE=Lynx Mouse + +usb:v05C7p2001* + ID_PRODUCT_FROM_DATABASE=Keyboard + +usb:v05C7p2011* + ID_PRODUCT_FROM_DATABASE=SCorpius Keyboard + +usb:v05C7p6001* + ID_PRODUCT_FROM_DATABASE=Ten-Keypad + +usb:v05C8* + ID_VENDOR_FROM_DATABASE=Cheng Uei Precision Industry Co., Ltd (Foxlink) + +usb:v05C8p0103* + ID_PRODUCT_FROM_DATABASE=FO13FF-65 PC-CAM + +usb:v05C8p021A* + ID_PRODUCT_FROM_DATABASE=HP Webcam + +usb:v05C8p0318* + ID_PRODUCT_FROM_DATABASE=Webcam + +usb:v05C8p0403* + ID_PRODUCT_FROM_DATABASE=Webcam + +usb:v05C9* + ID_VENDOR_FROM_DATABASE=Semtech Corp. + +usb:v05CA* + ID_VENDOR_FROM_DATABASE=Ricoh Co., Ltd + +usb:v05CAp0101* + ID_PRODUCT_FROM_DATABASE=RDC-5300 Camera + +usb:v05CAp0325* + ID_PRODUCT_FROM_DATABASE=Caplio GX (ptp) + +usb:v05CAp032D* + ID_PRODUCT_FROM_DATABASE=Caplio GX 8 (ptp) + +usb:v05CAp032F* + ID_PRODUCT_FROM_DATABASE=Caplio R3 (ptp) + +usb:v05CAp03A1* + ID_PRODUCT_FROM_DATABASE=IS200e + +usb:v05CAp0403* + ID_PRODUCT_FROM_DATABASE=Printing Support + +usb:v05CAp0405* + ID_PRODUCT_FROM_DATABASE=Type 101 + +usb:v05CAp0406* + ID_PRODUCT_FROM_DATABASE=Type 102 + +usb:v05CAp1803* + ID_PRODUCT_FROM_DATABASE=V5 camera [R5U870] + +usb:v05CAp1810* + ID_PRODUCT_FROM_DATABASE=Pavilion Webcam [R5U870] + +usb:v05CAp1812* + ID_PRODUCT_FROM_DATABASE=Pavilion Webcam + +usb:v05CAp1814* + ID_PRODUCT_FROM_DATABASE=HD Webcam + +usb:v05CAp1820* + ID_PRODUCT_FROM_DATABASE=Integrated Webcam + +usb:v05CAp1830* + ID_PRODUCT_FROM_DATABASE=Visual Communication Camera VGP-VCC2 [R5U870] + +usb:v05CAp1832* + ID_PRODUCT_FROM_DATABASE=Visual Communication Camera VGP-VCC3 [R5U870] + +usb:v05CAp1833* + ID_PRODUCT_FROM_DATABASE=Visual Communication Camera VGP-VCC2 [R5U870] + +usb:v05CAp1834* + ID_PRODUCT_FROM_DATABASE=Visual Communication Camera VGP-VCC2 [R5U870] + +usb:v05CAp1835* + ID_PRODUCT_FROM_DATABASE=Visual Communication Camera VGP-VCC5 [R5U870] + +usb:v05CAp1836* + ID_PRODUCT_FROM_DATABASE=Visual Communication Camera VGP-VCC4 [R5U870] + +usb:v05CAp1837* + ID_PRODUCT_FROM_DATABASE=Visual Communication Camera VGP-VCC4 [R5U870] + +usb:v05CAp1839* + ID_PRODUCT_FROM_DATABASE=Visual Communication Camera VGP-VCC6 [R5U870] + +usb:v05CAp183A* + ID_PRODUCT_FROM_DATABASE=Visual Communication Camera VGP-VCC7 [R5U870] + +usb:v05CAp183B* + ID_PRODUCT_FROM_DATABASE=Visual Communication Camera VGP-VCC8 [R5U870] + +usb:v05CAp183D* + ID_PRODUCT_FROM_DATABASE=Sony Vaio Integrated Webcam + +usb:v05CAp183E* + ID_PRODUCT_FROM_DATABASE=Visual Communication Camera VGP-VCC9 [R5U870] + +usb:v05CAp1841* + ID_PRODUCT_FROM_DATABASE=Fujitsu F01/ Lifebook U810 [R5U870] + +usb:v05CAp1870* + ID_PRODUCT_FROM_DATABASE=Webcam 1000 + +usb:v05CAp18B0* + ID_PRODUCT_FROM_DATABASE=Sony Vaio Integrated Webcam + +usb:v05CAp18B1* + ID_PRODUCT_FROM_DATABASE=Sony Vaio Integrated Webcam + +usb:v05CAp18B3* + ID_PRODUCT_FROM_DATABASE=Sony Vaio Integrated Webcam + +usb:v05CAp18B5* + ID_PRODUCT_FROM_DATABASE=Sony Vaio Integrated Webcam + +usb:v05CAp2201* + ID_PRODUCT_FROM_DATABASE=RDC-7 Camera + +usb:v05CAp2202* + ID_PRODUCT_FROM_DATABASE=Caplio RR30 + +usb:v05CAp2203* + ID_PRODUCT_FROM_DATABASE=Caplio 300G + +usb:v05CAp2204* + ID_PRODUCT_FROM_DATABASE=Caplio G3 + +usb:v05CAp2205* + ID_PRODUCT_FROM_DATABASE=Caplio RR30 / Medion MD 6126 Camera + +usb:v05CAp2206* + ID_PRODUCT_FROM_DATABASE=Konica DG-3Z + +usb:v05CAp2207* + ID_PRODUCT_FROM_DATABASE=Caplio Pro G3 + +usb:v05CAp2208* + ID_PRODUCT_FROM_DATABASE=Caplio G4 + +usb:v05CAp2209* + ID_PRODUCT_FROM_DATABASE=Caplio 400G wide + +usb:v05CAp220A* + ID_PRODUCT_FROM_DATABASE=KONICA MINOLTA DG-4Wide + +usb:v05CAp220B* + ID_PRODUCT_FROM_DATABASE=Caplio RX + +usb:v05CAp220C* + ID_PRODUCT_FROM_DATABASE=Caplio GX + +usb:v05CAp220D* + ID_PRODUCT_FROM_DATABASE=Caplio R1/RZ1 + +usb:v05CAp220E* + ID_PRODUCT_FROM_DATABASE=Sea & Sea 5000G + +usb:v05CAp220F* + ID_PRODUCT_FROM_DATABASE=Rollei dr5 / Rollei dr5 (PTP mode) + +usb:v05CAp2211* + ID_PRODUCT_FROM_DATABASE=Caplio R1S + +usb:v05CAp2212* + ID_PRODUCT_FROM_DATABASE=Caplio R1v Camera + +usb:v05CAp2213* + ID_PRODUCT_FROM_DATABASE=Caplio R2 + +usb:v05CAp2214* + ID_PRODUCT_FROM_DATABASE=Caplio GX 8 + +usb:v05CAp2215* + ID_PRODUCT_FROM_DATABASE=DSC 725 + +usb:v05CAp2216* + ID_PRODUCT_FROM_DATABASE=Caplio R3 + +usb:v05CAp2222* + ID_PRODUCT_FROM_DATABASE=RDC-i500 + +usb:v05CB* + ID_VENDOR_FROM_DATABASE=PowerVision Technologies, Inc. + +usb:v05CBp1483* + ID_PRODUCT_FROM_DATABASE=PV8630 interface (scanners, webcams) + +usb:v05CC* + ID_VENDOR_FROM_DATABASE=ELSA AG + +usb:v05CCp2100* + ID_PRODUCT_FROM_DATABASE=MicroLink ISDN Office + +usb:v05CCp2219* + ID_PRODUCT_FROM_DATABASE=MicroLink ISDN + +usb:v05CCp2265* + ID_PRODUCT_FROM_DATABASE=MicroLink 56k + +usb:v05CCp2267* + ID_PRODUCT_FROM_DATABASE=MicroLink 56k (V.250) + +usb:v05CCp2280* + ID_PRODUCT_FROM_DATABASE=MicroLink 56k Fun + +usb:v05CCp3000* + ID_PRODUCT_FROM_DATABASE=Micolink USB2Ethernet [pegasus] + +usb:v05CCp3100* + ID_PRODUCT_FROM_DATABASE=AirLancer USB-11 + +usb:v05CCp3363* + ID_PRODUCT_FROM_DATABASE=MicroLink ADSL Fun + +usb:v05CD* + ID_VENDOR_FROM_DATABASE=Silicom, Ltd + +usb:v05CE* + ID_VENDOR_FROM_DATABASE=sci-worx GmbH + +usb:v05CF* + ID_VENDOR_FROM_DATABASE=Sung Forn Co., Ltd + +usb:v05D0* + ID_VENDOR_FROM_DATABASE=GE Medical Systems Lunar + +usb:v05D1* + ID_VENDOR_FROM_DATABASE=Brainboxes, Ltd + +usb:v05D1p0003* + ID_PRODUCT_FROM_DATABASE=Bluetooth Adapter BL-554 + +usb:v05D2* + ID_VENDOR_FROM_DATABASE=Wave Systems Corp. + +usb:v05D3* + ID_VENDOR_FROM_DATABASE=Tohoku Ricoh Co., Ltd + +usb:v05D5* + ID_VENDOR_FROM_DATABASE=Super Gate Technology Co., Ltd + +usb:v05D6* + ID_VENDOR_FROM_DATABASE=Philips Semiconductors, CICT + +usb:v05D7* + ID_VENDOR_FROM_DATABASE=Thomas & Betts Corp. + +usb:v05D7p0099* + ID_PRODUCT_FROM_DATABASE=10Mbps Ethernet [klsi] + +usb:v05D8* + ID_VENDOR_FROM_DATABASE=Ultima Electronics Corp. + +usb:v05D8p4001* + ID_PRODUCT_FROM_DATABASE=Artec Ultima 2000 + +usb:v05D8p4002* + ID_PRODUCT_FROM_DATABASE=Artec Ultima 2000 (GT6801 based)/Lifetec LT9385/ScanMagic 1200 UB Plus Scanner + +usb:v05D8p4003* + ID_PRODUCT_FROM_DATABASE=Artec E+ 48U + +usb:v05D8p4004* + ID_PRODUCT_FROM_DATABASE=Artec E+ Pro + +usb:v05D8p4005* + ID_PRODUCT_FROM_DATABASE=MEM48U + +usb:v05D8p4006* + ID_PRODUCT_FROM_DATABASE=TRUST EASY WEBSCAN 19200 + +usb:v05D8p4007* + ID_PRODUCT_FROM_DATABASE=TRUST 240H EASY WEBSCAN GOLD + +usb:v05D8p4008* + ID_PRODUCT_FROM_DATABASE=Trust Easy Webscan 19200 + +usb:v05D8p4009* + ID_PRODUCT_FROM_DATABASE=Umax Astraslim + +usb:v05D8p4013* + ID_PRODUCT_FROM_DATABASE=IT Scan 1200 + +usb:v05D8p8105* + ID_PRODUCT_FROM_DATABASE=Artec T1 USB TVBOX (cold) + +usb:v05D8p8106* + ID_PRODUCT_FROM_DATABASE=Artec T1 USB TVBOX (warm) + +usb:v05D8p8107* + ID_PRODUCT_FROM_DATABASE=Artec T1 USB TVBOX with AN2235 (cold) + +usb:v05D8p8108* + ID_PRODUCT_FROM_DATABASE=Artec T1 USB TVBOX with AN2235 (warm) + +usb:v05D8p8109* + ID_PRODUCT_FROM_DATABASE=Artec T1 USB2.0 TVBOX (cold + +usb:v05D9* + ID_VENDOR_FROM_DATABASE=Axiohm Transaction Solutions + +usb:v05D9pA225* + ID_PRODUCT_FROM_DATABASE=A225 Printer + +usb:v05D9pA758* + ID_PRODUCT_FROM_DATABASE=A758 Printer + +usb:v05D9pA794* + ID_PRODUCT_FROM_DATABASE=A794 Printer + +usb:v05DA* + ID_VENDOR_FROM_DATABASE=Microtek International, Inc. + +usb:v05DAp0091* + ID_PRODUCT_FROM_DATABASE=ScanMaker X6u + +usb:v05DAp0093* + ID_PRODUCT_FROM_DATABASE=ScanMaker V6USL + +usb:v05DAp0094* + ID_PRODUCT_FROM_DATABASE=Phantom 336CX/C3 + +usb:v05DAp0099* + ID_PRODUCT_FROM_DATABASE=ScanMaker X6/X6U + +usb:v05DAp009A* + ID_PRODUCT_FROM_DATABASE=Phantom C6 + +usb:v05DAp00A0* + ID_PRODUCT_FROM_DATABASE=Phantom 336CX/C3 (#2) + +usb:v05DAp00A3* + ID_PRODUCT_FROM_DATABASE=ScanMaker V6USL + +usb:v05DAp00AC* + ID_PRODUCT_FROM_DATABASE=ScanMaker V6UL + +usb:v05DAp00B6* + ID_PRODUCT_FROM_DATABASE=ScanMaker V6UPL + +usb:v05DAp00EF* + ID_PRODUCT_FROM_DATABASE=ScanMaker V6UPL + +usb:v05DAp1006* + ID_PRODUCT_FROM_DATABASE=Jenoptik JD350 entrance + +usb:v05DAp1011* + ID_PRODUCT_FROM_DATABASE=NHJ Che-ez! Kiss Digital Camera + +usb:v05DAp1018* + ID_PRODUCT_FROM_DATABASE=Digital Dream Enigma 1.3 + +usb:v05DAp1020* + ID_PRODUCT_FROM_DATABASE=Digital Dream l'espion xtra + +usb:v05DAp1025* + ID_PRODUCT_FROM_DATABASE=Take-it Still Camera Device + +usb:v05DAp1026* + ID_PRODUCT_FROM_DATABASE=Take-it + +usb:v05DAp1043* + ID_PRODUCT_FROM_DATABASE=Take-It 1300 DSC Bulk Driver + +usb:v05DAp1045* + ID_PRODUCT_FROM_DATABASE=Take-it D1 + +usb:v05DAp1047* + ID_PRODUCT_FROM_DATABASE=Take-it Camera Composite Device + +usb:v05DAp1048* + ID_PRODUCT_FROM_DATABASE=Take-it Q3 + +usb:v05DAp1049* + ID_PRODUCT_FROM_DATABASE=3M Still Camera Device + +usb:v05DAp1051* + ID_PRODUCT_FROM_DATABASE=Camcorder Series + +usb:v05DAp1052* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v05DAp1053* + ID_PRODUCT_FROM_DATABASE=Take-it DV Composite Device + +usb:v05DAp1054* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v05DAp1055* + ID_PRODUCT_FROM_DATABASE=Digital Camera Series(536) + +usb:v05DAp1056* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v05DAp1057* + ID_PRODUCT_FROM_DATABASE=Take-it DSC Camera Device(536) + +usb:v05DAp1058* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v05DAp1059* + ID_PRODUCT_FROM_DATABASE=Camcorder DSC Series + +usb:v05DAp1060* + ID_PRODUCT_FROM_DATABASE=Microtek Take-it MV500 + +usb:v05DAp2007* + ID_PRODUCT_FROM_DATABASE=ArtixScan DI 1210 + +usb:v05DAp200C* + ID_PRODUCT_FROM_DATABASE=1394_USB2 Scanner + +usb:v05DAp200E* + ID_PRODUCT_FROM_DATABASE=ArtixScan DI 810 + +usb:v05DAp2017* + ID_PRODUCT_FROM_DATABASE=UF ICE Scanner + +usb:v05DAp201C* + ID_PRODUCT_FROM_DATABASE=4800 Scanner + +usb:v05DAp201D* + ID_PRODUCT_FROM_DATABASE=ArtixScan DI 1610 + +usb:v05DAp201F* + ID_PRODUCT_FROM_DATABASE=4800 Scanner-ICE + +usb:v05DAp202E* + ID_PRODUCT_FROM_DATABASE=ArtixScan DI 2020 + +usb:v05DAp208B* + ID_PRODUCT_FROM_DATABASE=ScanMaker 6800 + +usb:v05DAp208F* + ID_PRODUCT_FROM_DATABASE=ArtixScan DI 2010 + +usb:v05DAp209E* + ID_PRODUCT_FROM_DATABASE=ScanMaker 4700LP + +usb:v05DAp20A7* + ID_PRODUCT_FROM_DATABASE=ScanMaker 5600 + +usb:v05DAp20B0* + ID_PRODUCT_FROM_DATABASE=ScanMaker X12USL + +usb:v05DAp20B1* + ID_PRODUCT_FROM_DATABASE=ScanMaker 8700 + +usb:v05DAp20B4* + ID_PRODUCT_FROM_DATABASE=ScanMaker 4700 + +usb:v05DAp20BD* + ID_PRODUCT_FROM_DATABASE=ScanMaker 5700 + +usb:v05DAp20C9* + ID_PRODUCT_FROM_DATABASE=ScanMaker 6700 + +usb:v05DAp20D2* + ID_PRODUCT_FROM_DATABASE=Microtek ArtixScan 1800f + +usb:v05DAp20D6* + ID_PRODUCT_FROM_DATABASE=PS4000 + +usb:v05DAp20DE* + ID_PRODUCT_FROM_DATABASE=ScanMaker 9800XL + +usb:v05DAp20E0* + ID_PRODUCT_FROM_DATABASE=ScanMaker 9700XL + +usb:v05DAp20ED* + ID_PRODUCT_FROM_DATABASE=ScanMaker 4700 + +usb:v05DAp20EE* + ID_PRODUCT_FROM_DATABASE=Micortek ScanMaker X12USL + +usb:v05DAp3008* + ID_PRODUCT_FROM_DATABASE=Scanner + +usb:v05DAp300A* + ID_PRODUCT_FROM_DATABASE=4800 ICE Scanner + +usb:v05DAp300B* + ID_PRODUCT_FROM_DATABASE=4800 Scanner + +usb:v05DAp300F* + ID_PRODUCT_FROM_DATABASE=MiniScan C5 + +usb:v05DAp3020* + ID_PRODUCT_FROM_DATABASE=4800dpi Scanner + +usb:v05DAp3021* + ID_PRODUCT_FROM_DATABASE=1200dpi Scanner + +usb:v05DAp3022* + ID_PRODUCT_FROM_DATABASE=Scanner 4800dpi + +usb:v05DAp3023* + ID_PRODUCT_FROM_DATABASE=USB1200II Scanner + +usb:v05DAp30C1* + ID_PRODUCT_FROM_DATABASE=USB600 Scanner + +usb:v05DAp30CE* + ID_PRODUCT_FROM_DATABASE=ScanMaker 3800 + +usb:v05DAp30CF* + ID_PRODUCT_FROM_DATABASE=ScanMaker 4800 + +usb:v05DAp30D4* + ID_PRODUCT_FROM_DATABASE=USB1200 Scanner + +usb:v05DAp30D8* + ID_PRODUCT_FROM_DATABASE=Scanner + +usb:v05DAp30D9* + ID_PRODUCT_FROM_DATABASE=USB2400 Scanner + +usb:v05DAp30E4* + ID_PRODUCT_FROM_DATABASE=ScanMaker 4100 + +usb:v05DAp30E5* + ID_PRODUCT_FROM_DATABASE=USB3200 Scanner + +usb:v05DAp30E6* + ID_PRODUCT_FROM_DATABASE=ScanMaker i320 + +usb:v05DAp40B3* + ID_PRODUCT_FROM_DATABASE=ScanMaker 3600 + +usb:v05DAp40B8* + ID_PRODUCT_FROM_DATABASE=ScanMaker 3700 + +usb:v05DAp40C7* + ID_PRODUCT_FROM_DATABASE=ScanMaker 4600 + +usb:v05DAp40CA* + ID_PRODUCT_FROM_DATABASE=ScanMaker 3600 + +usb:v05DAp40CB* + ID_PRODUCT_FROM_DATABASE=ScanMaker 3700 + +usb:v05DAp40DD* + ID_PRODUCT_FROM_DATABASE=ScanMaker 3750i + +usb:v05DAp40FF* + ID_PRODUCT_FROM_DATABASE=ScanMaker 3600 + +usb:v05DAp5003* + ID_PRODUCT_FROM_DATABASE=Goya + +usb:v05DAp5013* + ID_PRODUCT_FROM_DATABASE=3200 Scanner + +usb:v05DAp80A3* + ID_PRODUCT_FROM_DATABASE=ScanMaker V6USL (#2) + +usb:v05DAp80AC* + ID_PRODUCT_FROM_DATABASE=ScanMaker V6UL/SpicyU + +usb:v05DB* + ID_VENDOR_FROM_DATABASE=Sun Corp. (Suntac?) + +usb:v05DBp0003* + ID_PRODUCT_FROM_DATABASE=SUNTAC U-Cable type D2 + +usb:v05DBp0005* + ID_PRODUCT_FROM_DATABASE=SUNTAC U-Cable type P1 + +usb:v05DBp0009* + ID_PRODUCT_FROM_DATABASE=SUNTAC Slipper U + +usb:v05DBp000A* + ID_PRODUCT_FROM_DATABASE=SUNTAC Ir-Trinity + +usb:v05DBp000B* + ID_PRODUCT_FROM_DATABASE=SUNTAC U-Cable type A3 + +usb:v05DBp0011* + ID_PRODUCT_FROM_DATABASE=SUNTAC U-Cable type A4 + +usb:v05DC* + ID_VENDOR_FROM_DATABASE=Lexar Media, Inc. + +usb:v05DCp0001* + ID_PRODUCT_FROM_DATABASE=jumpSHOT CompactFlash Reader + +usb:v05DCp0002* + ID_PRODUCT_FROM_DATABASE=JumpShot + +usb:v05DCp0003* + ID_PRODUCT_FROM_DATABASE=JumpShot + +usb:v05DCp0080* + ID_PRODUCT_FROM_DATABASE=Jumpdrive Secure 64MB + +usb:v05DCp0081* + ID_PRODUCT_FROM_DATABASE=RBC Compact Flash Drive + +usb:v05DCp00A7* + ID_PRODUCT_FROM_DATABASE=JumpDrive Impact + +usb:v05DCp0100* + ID_PRODUCT_FROM_DATABASE=JumpDrive PRO + +usb:v05DCp0200* + ID_PRODUCT_FROM_DATABASE=JumpDrive 2.0 Pro + +usb:v05DCp0300* + ID_PRODUCT_FROM_DATABASE=Jumpdrive Geysr + +usb:v05DCp0301* + ID_PRODUCT_FROM_DATABASE=JumpDrive Classic + +usb:v05DCp0302* + ID_PRODUCT_FROM_DATABASE=JD Micro + +usb:v05DCp0303* + ID_PRODUCT_FROM_DATABASE=JD Micro Pro + +usb:v05DCp0304* + ID_PRODUCT_FROM_DATABASE=JD Secure II + +usb:v05DCp0310* + ID_PRODUCT_FROM_DATABASE=JumpDrive + +usb:v05DCp0311* + ID_PRODUCT_FROM_DATABASE=JumpDrive Classic + +usb:v05DCp0312* + ID_PRODUCT_FROM_DATABASE=JD Micro + +usb:v05DCp0313* + ID_PRODUCT_FROM_DATABASE=JD Micro Pro + +usb:v05DCp0320* + ID_PRODUCT_FROM_DATABASE=JumpDrive + +usb:v05DCp0321* + ID_PRODUCT_FROM_DATABASE=JD Micro + +usb:v05DCp0322* + ID_PRODUCT_FROM_DATABASE=JD Micro Pro + +usb:v05DCp0323* + ID_PRODUCT_FROM_DATABASE=UFC + +usb:v05DCp0330* + ID_PRODUCT_FROM_DATABASE=JumpDrive Expression + +usb:v05DCp0340* + ID_PRODUCT_FROM_DATABASE=JumpDrive TAD + +usb:v05DCp0350* + ID_PRODUCT_FROM_DATABASE=Express Card + +usb:v05DCp0400* + ID_PRODUCT_FROM_DATABASE=UFDC + +usb:v05DCp0401* + ID_PRODUCT_FROM_DATABASE=UFDC + +usb:v05DCp0403* + ID_PRODUCT_FROM_DATABASE=Locked B Device + +usb:v05DCp0405* + ID_PRODUCT_FROM_DATABASE=Locked C Device + +usb:v05DCp0407* + ID_PRODUCT_FROM_DATABASE=Locked D Device + +usb:v05DCp0409* + ID_PRODUCT_FROM_DATABASE=Locked E Device + +usb:v05DCp040B* + ID_PRODUCT_FROM_DATABASE=Locked F Device + +usb:v05DCp040D* + ID_PRODUCT_FROM_DATABASE=Locked G Device + +usb:v05DCp040F* + ID_PRODUCT_FROM_DATABASE=Locked H Device + +usb:v05DCp0410* + ID_PRODUCT_FROM_DATABASE=JumpDrive + +usb:v05DCp0411* + ID_PRODUCT_FROM_DATABASE=JumpDrive + +usb:v05DCp0413* + ID_PRODUCT_FROM_DATABASE=Locked J Device + +usb:v05DCp0415* + ID_PRODUCT_FROM_DATABASE=Locked K Device + +usb:v05DCp0417* + ID_PRODUCT_FROM_DATABASE=Locked L Device + +usb:v05DCp0419* + ID_PRODUCT_FROM_DATABASE=Locked M Device + +usb:v05DCp041B* + ID_PRODUCT_FROM_DATABASE=Locked N Device + +usb:v05DCp041D* + ID_PRODUCT_FROM_DATABASE=Locked O Device + +usb:v05DCp041F* + ID_PRODUCT_FROM_DATABASE=Locked P Device + +usb:v05DCp0420* + ID_PRODUCT_FROM_DATABASE=JumpDrive + +usb:v05DCp0421* + ID_PRODUCT_FROM_DATABASE=JumpDrive + +usb:v05DCp0423* + ID_PRODUCT_FROM_DATABASE=Locked R Device + +usb:v05DCp0425* + ID_PRODUCT_FROM_DATABASE=Locked S Device + +usb:v05DCp0427* + ID_PRODUCT_FROM_DATABASE=Locked T Device + +usb:v05DCp0429* + ID_PRODUCT_FROM_DATABASE=Locked U Device + +usb:v05DCp042B* + ID_PRODUCT_FROM_DATABASE=Locked V Device + +usb:v05DCp042D* + ID_PRODUCT_FROM_DATABASE=Locked W Device + +usb:v05DCp042F* + ID_PRODUCT_FROM_DATABASE=Locked X Device + +usb:v05DCp0431* + ID_PRODUCT_FROM_DATABASE=Locked Y Device + +usb:v05DCp0433* + ID_PRODUCT_FROM_DATABASE=Locked Z Device + +usb:v05DCp4D02* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v05DCp4D12* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v05DCp4D30* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v05DCpA300* + ID_PRODUCT_FROM_DATABASE=JumpDrive2 + +usb:v05DCpA400* + ID_PRODUCT_FROM_DATABASE=JumpDrive trade; Pro 40-501 + +usb:v05DCpA410* + ID_PRODUCT_FROM_DATABASE=JumpDrive 128MB/256MB + +usb:v05DCpA411* + ID_PRODUCT_FROM_DATABASE=JumpDrive Traveler + +usb:v05DCpA420* + ID_PRODUCT_FROM_DATABASE=JumpDrive Pro + +usb:v05DCpA421* + ID_PRODUCT_FROM_DATABASE=JumpDrive Pro II + +usb:v05DCpA422* + ID_PRODUCT_FROM_DATABASE=JumpDrive Micro Pro + +usb:v05DCpA430* + ID_PRODUCT_FROM_DATABASE=JumpDrive Secure + +usb:v05DCpA431* + ID_PRODUCT_FROM_DATABASE=JumpDrive Secure II + +usb:v05DCpA432* + ID_PRODUCT_FROM_DATABASE=JumpDrive Classic + +usb:v05DCpA440* + ID_PRODUCT_FROM_DATABASE=JumpDrive Lightning + +usb:v05DCpA450* + ID_PRODUCT_FROM_DATABASE=JumpDrive TouchGuard + +usb:v05DCpA460* + ID_PRODUCT_FROM_DATABASE=JD Mercury + +usb:v05DCpA501* + ID_PRODUCT_FROM_DATABASE=JumpDrive Classic + +usb:v05DCpA510* + ID_PRODUCT_FROM_DATABASE=JumpDrive Sport + +usb:v05DCpA530* + ID_PRODUCT_FROM_DATABASE=JumpDrive Expression + +usb:v05DCpA531* + ID_PRODUCT_FROM_DATABASE=JumpDrive Secure II + +usb:v05DCpA560* + ID_PRODUCT_FROM_DATABASE=JumpDrive FireFly + +usb:v05DCpA701* + ID_PRODUCT_FROM_DATABASE=JumpDrive FireFly + +usb:v05DCpA731* + ID_PRODUCT_FROM_DATABASE=JumpDrive FireFly + +usb:v05DCpA790* + ID_PRODUCT_FROM_DATABASE=JumpDrive 2GB + +usb:v05DCpA811* + ID_PRODUCT_FROM_DATABASE=16GB Gizmo! + +usb:v05DCpA813* + ID_PRODUCT_FROM_DATABASE=16gB flash thumb drive + +usb:v05DCpB002* + ID_PRODUCT_FROM_DATABASE=USB CF Reader + +usb:v05DCpB018* + ID_PRODUCT_FROM_DATABASE=Multi-Card Reader + +usb:v05DCpB047* + ID_PRODUCT_FROM_DATABASE=SDHC Reader [RW047-7000] + +usb:v05DD* + ID_VENDOR_FROM_DATABASE=Delta Electronics, Inc. + +usb:v05DDpFF31* + ID_PRODUCT_FROM_DATABASE=AWU-120 + +usb:v05DDpFF32* + ID_PRODUCT_FROM_DATABASE=FriendlyNET AeroLAN AL2011 + +usb:v05DDpFF35* + ID_PRODUCT_FROM_DATABASE=PCW 100 - Wireless 802.11b Adapter + +usb:v05DDpFF91* + ID_PRODUCT_FROM_DATABASE=2Wire PC Port Phoneline 10Mbps Adapter + +usb:v05DF* + ID_VENDOR_FROM_DATABASE=Silicon Vision, Inc. + +usb:v05E0* + ID_VENDOR_FROM_DATABASE=Symbol Technologies + +usb:v05E0p0700* + ID_PRODUCT_FROM_DATABASE=Bar Code Scanner (CS1504) + +usb:v05E0p0800* + ID_PRODUCT_FROM_DATABASE=Spectrum24 Wireless LAN Adapter + +usb:v05E0p1200* + ID_PRODUCT_FROM_DATABASE=Bar Code Scanner + +usb:v05E0p1900* + ID_PRODUCT_FROM_DATABASE=SNAPI Imaging Device + +usb:v05E0p2000* + ID_PRODUCT_FROM_DATABASE=MC3090 Rugged Mobile Computer + +usb:v05E0p200D* + ID_PRODUCT_FROM_DATABASE=MC70 Rugged Mobile Computer + +usb:v05E1* + ID_VENDOR_FROM_DATABASE=Syntek Semiconductor Co., Ltd + +usb:v05E1p0100* + ID_PRODUCT_FROM_DATABASE=802.11g + Bluetooth Wireless Adapter + +usb:v05E1p0408* + ID_PRODUCT_FROM_DATABASE=STK1160 Video Capture Device + +usb:v05E1p0500* + ID_PRODUCT_FROM_DATABASE=DC-112X Webcam + +usb:v05E1p0501* + ID_PRODUCT_FROM_DATABASE=DC-1125 Webcam + +usb:v05E1p0890* + ID_PRODUCT_FROM_DATABASE=STK011 Camera + +usb:v05E1p0892* + ID_PRODUCT_FROM_DATABASE=STK013 Camera + +usb:v05E1p0895* + ID_PRODUCT_FROM_DATABASE=STK016 Camera + +usb:v05E1p0896* + ID_PRODUCT_FROM_DATABASE=STK017 Camera + +usb:v05E2* + ID_VENDOR_FROM_DATABASE=ElecVision, Inc. + +usb:v05E3* + ID_VENDOR_FROM_DATABASE=Genesys Logic, Inc. + +usb:v05E3p000A* + ID_PRODUCT_FROM_DATABASE=Keyboard with PS/2 Port + +usb:v05E3p000B* + ID_PRODUCT_FROM_DATABASE=Mouse + +usb:v05E3p0100* + ID_PRODUCT_FROM_DATABASE=Nintendo Game Boy Advance SP + +usb:v05E3p0120* + ID_PRODUCT_FROM_DATABASE=Pacific Image Electronics PrimeFilm 1800u slide/negative scanner + +usb:v05E3p0131* + ID_PRODUCT_FROM_DATABASE=CF/SM Reader/Writer + +usb:v05E3p0142* + ID_PRODUCT_FROM_DATABASE=Multiple Slides Scanner-3600 + +usb:v05E3p0143* + ID_PRODUCT_FROM_DATABASE=Multiple Frames Film Scanner-36series + +usb:v05E3p0180* + ID_PRODUCT_FROM_DATABASE=Plustek Scanner + +usb:v05E3p0182* + ID_PRODUCT_FROM_DATABASE=Wize Media 1000 + +usb:v05E3p0189* + ID_PRODUCT_FROM_DATABASE=ScanJet 4600 series + +usb:v05E3p018A* + ID_PRODUCT_FROM_DATABASE=Xerox 6400 + +usb:v05E3p0300* + ID_PRODUCT_FROM_DATABASE=GLUSB98PT Parallel Port + +usb:v05E3p0301* + ID_PRODUCT_FROM_DATABASE=USB2LPT Cable Release2 + +usb:v05E3p0406* + ID_PRODUCT_FROM_DATABASE=Hub + +usb:v05E3p0501* + ID_PRODUCT_FROM_DATABASE=GL620USB Host-Host interface + +usb:v05E3p0502* + ID_PRODUCT_FROM_DATABASE=GL620USB-A GeneLink USB-USB Bridge + +usb:v05E3p0503* + ID_PRODUCT_FROM_DATABASE=Webcam + +usb:v05E3p0504* + ID_PRODUCT_FROM_DATABASE=HID Keyboard Filter + +usb:v05E3p0604* + ID_PRODUCT_FROM_DATABASE=USB 1.1 Hub + +usb:v05E3p0605* + ID_PRODUCT_FROM_DATABASE=USB 2.0 Hub + +usb:v05E3p0606* + ID_PRODUCT_FROM_DATABASE=USB 2.0 Hub / D-Link DUB-H4 USB 2.0 Hub + +usb:v05E3p0607* + ID_PRODUCT_FROM_DATABASE=Logitech G110 Hub + +usb:v05E3p0608* + ID_PRODUCT_FROM_DATABASE=USB-2.0 4-Port HUB + +usb:v05E3p0610* + ID_PRODUCT_FROM_DATABASE=4-port hub + +usb:v05E3p0660* + ID_PRODUCT_FROM_DATABASE=USB 2.0 Hub + +usb:v05E3p0700* + ID_PRODUCT_FROM_DATABASE=SIIG US2256 CompactFlash Card Reader + +usb:v05E3p0701* + ID_PRODUCT_FROM_DATABASE=USB 2.0 IDE Adapter + +usb:v05E3p0702* + ID_PRODUCT_FROM_DATABASE=USB 2.0 IDE Adapter [GL811E] + +usb:v05E3p0703* + ID_PRODUCT_FROM_DATABASE=Card Reader + +usb:v05E3p0704* + ID_PRODUCT_FROM_DATABASE=Card Reader + +usb:v05E3p0705* + ID_PRODUCT_FROM_DATABASE=Card Reader + +usb:v05E3p0706* + ID_PRODUCT_FROM_DATABASE=Card Reader + +usb:v05E3p0707* + ID_PRODUCT_FROM_DATABASE=Card Reader + +usb:v05E3p0708* + ID_PRODUCT_FROM_DATABASE=Card Reader + +usb:v05E3p0709* + ID_PRODUCT_FROM_DATABASE=Card Reader + +usb:v05E3p070A* + ID_PRODUCT_FROM_DATABASE=Pen Flash + +usb:v05E3p070B* + ID_PRODUCT_FROM_DATABASE=DMHS1B Rev 3 DFU Adapter + +usb:v05E3p070E* + ID_PRODUCT_FROM_DATABASE=USB 2.0 Card Reader + +usb:v05E3p070F* + ID_PRODUCT_FROM_DATABASE=Pen Flash + +usb:v05E3p0710* + ID_PRODUCT_FROM_DATABASE=USB 2.0 33-in-1 Card Reader + +usb:v05E3p0711* + ID_PRODUCT_FROM_DATABASE=Card Reader + +usb:v05E3p0712* + ID_PRODUCT_FROM_DATABASE=Delkin Mass Storage Device + +usb:v05E3p0715* + ID_PRODUCT_FROM_DATABASE=USB 2.0 microSD Reader + +usb:v05E3p0716* + ID_PRODUCT_FROM_DATABASE=USB 2.0 Multislot Card Reader/Writer + +usb:v05E3p0717* + ID_PRODUCT_FROM_DATABASE=All-in-1 Card Reader + +usb:v05E3p0718* + ID_PRODUCT_FROM_DATABASE=IDE/SATA Adapter + +usb:v05E3p0719* + ID_PRODUCT_FROM_DATABASE=SATA adapter + +usb:v05E3p0723* + ID_PRODUCT_FROM_DATABASE=GL827L SD/MMC/MS Flash Card Reader + +usb:v05E3p0726* + ID_PRODUCT_FROM_DATABASE=SD Card Reader + +usb:v05E3p0727* + ID_PRODUCT_FROM_DATABASE=microSD Reader/Writer + +usb:v05E3p0736* + ID_PRODUCT_FROM_DATABASE=microSD Reader/Writer + +usb:v05E3p0760* + ID_PRODUCT_FROM_DATABASE=USB 2.0 Card Reader/Writer + +usb:v05E3p0761* + ID_PRODUCT_FROM_DATABASE=Genesys Mass Storage Device + +usb:v05E3p0780* + ID_PRODUCT_FROM_DATABASE=USBFS DFU Adapter + +usb:v05E3p07A0* + ID_PRODUCT_FROM_DATABASE=Pen Flash + +usb:v05E3p0880* + ID_PRODUCT_FROM_DATABASE=Wasp (SL-6612) + +usb:v05E3p0927* + ID_PRODUCT_FROM_DATABASE=Card Reader + +usb:v05E3p1205* + ID_PRODUCT_FROM_DATABASE=Afilias Optical Mouse H3003 / Trust Optical USB MultiColour Mouse MI-2330 + +usb:v05E3pA700* + ID_PRODUCT_FROM_DATABASE=Pen Flash + +usb:v05E3pF102* + ID_PRODUCT_FROM_DATABASE=VX7012 TV Box + +usb:v05E3pF103* + ID_PRODUCT_FROM_DATABASE=VX7012 TV Box + +usb:v05E3pF104* + ID_PRODUCT_FROM_DATABASE=VX7012 TV Box + +usb:v05E3pFD21* + ID_PRODUCT_FROM_DATABASE=3M TL20 Temperature Logger + +usb:v05E3pFE00* + ID_PRODUCT_FROM_DATABASE=Razer Mouse + +usb:v05E4* + ID_VENDOR_FROM_DATABASE=Red Wing Corp. + +usb:v05E5* + ID_VENDOR_FROM_DATABASE=Fuji Electric Co., Ltd + +usb:v05E6* + ID_VENDOR_FROM_DATABASE=Keithley Instruments + +usb:v05E8* + ID_VENDOR_FROM_DATABASE=ICC, Inc. + +usb:v05E9* + ID_VENDOR_FROM_DATABASE=Kawasaki LSI + +usb:v05E9p0008* + ID_PRODUCT_FROM_DATABASE=KL5KUSB101B Ethernet [klsi] + +usb:v05E9p0009* + ID_PRODUCT_FROM_DATABASE=Sony 10Mbps Ethernet [pegasus] + +usb:v05E9p000C* + ID_PRODUCT_FROM_DATABASE=USB-to-RS-232 + +usb:v05E9p000D* + ID_PRODUCT_FROM_DATABASE=USB-to-RS-232 + +usb:v05E9p0014* + ID_PRODUCT_FROM_DATABASE=RS-232 J104 + +usb:v05E9p0040* + ID_PRODUCT_FROM_DATABASE=Ethernet Adapter + +usb:v05E9p2008* + ID_PRODUCT_FROM_DATABASE=Ethernet Adapter + +usb:v05EB* + ID_VENDOR_FROM_DATABASE=FFC, Ltd + +usb:v05EC* + ID_VENDOR_FROM_DATABASE=COM21, Inc. + +usb:v05EE* + ID_VENDOR_FROM_DATABASE=Cytechinfo Inc. + +usb:v05EF* + ID_VENDOR_FROM_DATABASE=AVB, Inc. [anko?] + +usb:v05EFp020A* + ID_PRODUCT_FROM_DATABASE=Top Shot Pegasus Joystick + +usb:v05EFp8884* + ID_PRODUCT_FROM_DATABASE=Mag Turbo Force Wheel + +usb:v05EFp8888* + ID_PRODUCT_FROM_DATABASE=Top Shot Force Feedback Racing Wheel + +usb:v05F0* + ID_VENDOR_FROM_DATABASE=Canopus Co., Ltd + +usb:v05F0p0101* + ID_PRODUCT_FROM_DATABASE=DA-Port DAC + +usb:v05F1* + ID_VENDOR_FROM_DATABASE=Compass Communications + +usb:v05F2* + ID_VENDOR_FROM_DATABASE=Dexin Corp., Ltd + +usb:v05F2p0010* + ID_PRODUCT_FROM_DATABASE=AQ Mouse + +usb:v05F3* + ID_VENDOR_FROM_DATABASE=PI Engineering, Inc. + +usb:v05F3p0007* + ID_PRODUCT_FROM_DATABASE=Kinesis Advantage PRO MPC/USB Keyboard + +usb:v05F3p0081* + ID_PRODUCT_FROM_DATABASE=Kinesis Integrated Hub + +usb:v05F3p00FF* + ID_PRODUCT_FROM_DATABASE=VEC Footpedal + +usb:v05F3p020B* + ID_PRODUCT_FROM_DATABASE=PS2 Adapter + +usb:v05F3p0232* + ID_PRODUCT_FROM_DATABASE=X-Keys Switch Interface, Programming Mode + +usb:v05F3p0261* + ID_PRODUCT_FROM_DATABASE=X-Keys Switch Interface, SPLAT Mode + +usb:v05F3p0264* + ID_PRODUCT_FROM_DATABASE=X-Keys Switch Interface, Composite Mode + +usb:v05F5* + ID_VENDOR_FROM_DATABASE=Unixtar Technology, Inc. + +usb:v05F6* + ID_VENDOR_FROM_DATABASE=AOC International + +usb:v05F7* + ID_VENDOR_FROM_DATABASE=RFC Distribution(s) PTE, Ltd + +usb:v05F9* + ID_VENDOR_FROM_DATABASE=PSC Scanning, Inc. + +usb:v05F9p1104* + ID_PRODUCT_FROM_DATABASE=Magellan 2200VS + +usb:v05F9p2206* + ID_PRODUCT_FROM_DATABASE=Gryphon Barcode Scanner + +usb:v05F9p2602* + ID_PRODUCT_FROM_DATABASE=Datalogic Magellan 1100i Barcode Scanner + +usb:v05FA* + ID_VENDOR_FROM_DATABASE=Siemens Telecommunications Systems, Ltd + +usb:v05FAp3301* + ID_PRODUCT_FROM_DATABASE=Keyboard with PS/2 Mouse Port + +usb:v05FAp3302* + ID_PRODUCT_FROM_DATABASE=Keyboard + +usb:v05FAp3303* + ID_PRODUCT_FROM_DATABASE=Keyboard with PS/2 Mouse Port + +usb:v05FC* + ID_VENDOR_FROM_DATABASE=Harman Multimedia + +usb:v05FCp7849* + ID_PRODUCT_FROM_DATABASE=Harman/Kardon SoundSticks + +usb:v05FD* + ID_VENDOR_FROM_DATABASE=InterAct, Inc. + +usb:v05FDp0239* + ID_PRODUCT_FROM_DATABASE=SV-239 HammerHead Digital + +usb:v05FDp0251* + ID_PRODUCT_FROM_DATABASE=Raider Pro + +usb:v05FDp0253* + ID_PRODUCT_FROM_DATABASE=ProPad 8 Digital + +usb:v05FDp0286* + ID_PRODUCT_FROM_DATABASE=SV-286 Cyclone Digital + +usb:v05FDp107A* + ID_PRODUCT_FROM_DATABASE=PowerPad Pro X-Box pad + +usb:v05FDp262A* + ID_PRODUCT_FROM_DATABASE=3dfx HammerHead FX + +usb:v05FDp262F* + ID_PRODUCT_FROM_DATABASE=HammerHead Fx + +usb:v05FDpDAAE* + ID_PRODUCT_FROM_DATABASE=Game Shark + +usb:v05FE* + ID_VENDOR_FROM_DATABASE=Chic Technology Corp. + +usb:v05FEp0001* + ID_PRODUCT_FROM_DATABASE=Mouse + +usb:v05FEp0003* + ID_PRODUCT_FROM_DATABASE=Cypress USB Mouse + +usb:v05FEp0005* + ID_PRODUCT_FROM_DATABASE=Viewmaster 4D Browser Mouse + +usb:v05FEp0007* + ID_PRODUCT_FROM_DATABASE=Twinhead Mouse + +usb:v05FEp0009* + ID_PRODUCT_FROM_DATABASE=Inland Pro 4500/5000 Mouse + +usb:v05FEp0011* + ID_PRODUCT_FROM_DATABASE=Browser Mouse + +usb:v05FEp0014* + ID_PRODUCT_FROM_DATABASE=Gamepad + +usb:v05FEp1010* + ID_PRODUCT_FROM_DATABASE=Optical Wireless + +usb:v05FF* + ID_VENDOR_FROM_DATABASE=LeCroy Corp. + +usb:v0600* + ID_VENDOR_FROM_DATABASE=Barco Display Systems + +usb:v0601* + ID_VENDOR_FROM_DATABASE=Jazz Hipster Corp. + +usb:v0601p0003* + ID_PRODUCT_FROM_DATABASE=Internet Security Co., Ltd. SecureKey + +usb:v0602* + ID_VENDOR_FROM_DATABASE=Vista Imaging, Inc. + +usb:v0602p1001* + ID_PRODUCT_FROM_DATABASE=ViCam Webcam + +usb:v0603* + ID_VENDOR_FROM_DATABASE=Novatek Microelectronics Corp. + +usb:v0603p00F1* + ID_PRODUCT_FROM_DATABASE=Keyboard + +usb:v0603p6871* + ID_PRODUCT_FROM_DATABASE=Mouse + +usb:v0604* + ID_VENDOR_FROM_DATABASE=Jean Co., Ltd + +usb:v0605* + ID_VENDOR_FROM_DATABASE=Anchor C&C Co., Ltd + +usb:v0606* + ID_VENDOR_FROM_DATABASE=Royal Information Electronics Co., Ltd + +usb:v0607* + ID_VENDOR_FROM_DATABASE=Bridge Information Co., Ltd + +usb:v0608* + ID_VENDOR_FROM_DATABASE=Genrad Ads + +usb:v0609* + ID_VENDOR_FROM_DATABASE=SMK Manufacturing, Inc. + +usb:v0609p031D* + ID_PRODUCT_FROM_DATABASE=eHome Infrared Receiver + +usb:v0609p0322* + ID_PRODUCT_FROM_DATABASE=eHome Infrared Receiver + +usb:v0609p0334* + ID_PRODUCT_FROM_DATABASE=eHome Infrared Receiver + +usb:v0609pFF12* + ID_PRODUCT_FROM_DATABASE=SMK Bluetooth Device + +usb:v060A* + ID_VENDOR_FROM_DATABASE=Worthington Data Solutions, Inc. + +usb:v060B* + ID_VENDOR_FROM_DATABASE=Solid Year + +usb:v060Bp0001* + ID_PRODUCT_FROM_DATABASE=MacAlly Keyboard + +usb:v060Bp0230* + ID_PRODUCT_FROM_DATABASE=KSK-8003 UX Keyboard + +usb:v060Bp1006* + ID_PRODUCT_FROM_DATABASE=Japanese Keyboard - 260U + +usb:v060Bp2101* + ID_PRODUCT_FROM_DATABASE=Keyboard + +usb:v060Bp2231* + ID_PRODUCT_FROM_DATABASE=KSK-6001 UELX Keyboard + +usb:v060Bp2270* + ID_PRODUCT_FROM_DATABASE=Gigabyte K8100 Aivia Gaming Keyboard + +usb:v060Bp5811* + ID_PRODUCT_FROM_DATABASE=ACK-571U Wireless Keyboard + +usb:v060Bp5903* + ID_PRODUCT_FROM_DATABASE=Japanese Keyboard - 595U + +usb:v060Bp6001* + ID_PRODUCT_FROM_DATABASE=SolidTek USB 2p HUB + +usb:v060Bp6002* + ID_PRODUCT_FROM_DATABASE=SolidTek USB Keyboard + +usb:v060Bp6003* + ID_PRODUCT_FROM_DATABASE=Japanese Keyboard - 600HM + +usb:v060Bp6231* + ID_PRODUCT_FROM_DATABASE=Thermaltake eSPORTS Meka Keyboard + +usb:v060Bp8007* + ID_PRODUCT_FROM_DATABASE=P-W1G1F12 VER:1 [Macally MegaCam] + +usb:v060BpA001* + ID_PRODUCT_FROM_DATABASE=Maxwell Compact Pc PM3 + +usb:v060C* + ID_VENDOR_FROM_DATABASE=EEH Datalink GmbH + +usb:v060D* + ID_VENDOR_FROM_DATABASE=Auctor Corp. + +usb:v060E* + ID_VENDOR_FROM_DATABASE=Transmonde Technologies, Inc. + +usb:v060F* + ID_VENDOR_FROM_DATABASE=Joinsoon Electronics Mfg. Co., Ltd + +usb:v0610* + ID_VENDOR_FROM_DATABASE=Costar Electronics, Inc. + +usb:v0611* + ID_VENDOR_FROM_DATABASE=Totoku Electric Co., Ltd + +usb:v0613* + ID_VENDOR_FROM_DATABASE=TransAct Technologies, Inc. + +usb:v0614* + ID_VENDOR_FROM_DATABASE=Bio-Rad Laboratories + +usb:v0615* + ID_VENDOR_FROM_DATABASE=Quabbin Wire & Cable Co., Inc. + +usb:v0616* + ID_VENDOR_FROM_DATABASE=Future Techno Designs PVT, Ltd + +usb:v0617* + ID_VENDOR_FROM_DATABASE=Swiss Federal Insitute of Technology + +usb:v0618* + ID_VENDOR_FROM_DATABASE=MacAlly + +usb:v0618p0101* + ID_PRODUCT_FROM_DATABASE=Mouse + +usb:v0619* + ID_VENDOR_FROM_DATABASE=Seiko Instruments, Inc. + +usb:v0619p0101* + ID_PRODUCT_FROM_DATABASE=SLP-100 Driver + +usb:v0619p0102* + ID_PRODUCT_FROM_DATABASE=SLP-200 Driver + +usb:v0619p0103* + ID_PRODUCT_FROM_DATABASE=SLP-100N Driver + +usb:v0619p0104* + ID_PRODUCT_FROM_DATABASE=SLP-200N Driver + +usb:v0619p0105* + ID_PRODUCT_FROM_DATABASE=SLP-240 Driver + +usb:v0619p0501* + ID_PRODUCT_FROM_DATABASE=SLP-440 Driver + +usb:v0619p0502* + ID_PRODUCT_FROM_DATABASE=SLP-450 Driver + +usb:v061A* + ID_VENDOR_FROM_DATABASE=Veridicom International, Inc. + +usb:v061Ap0110* + ID_PRODUCT_FROM_DATABASE=5thSense Fingerprint Sensor + +usb:v061Ap0200* + ID_PRODUCT_FROM_DATABASE=FPS200 Fingerprint Sensor + +usb:v061Ap8200* + ID_PRODUCT_FROM_DATABASE=VKI-A Fingerprint Sensor/Flash Storage (dumb) + +usb:v061Ap9200* + ID_PRODUCT_FROM_DATABASE=VKI-B Fingerprint Sensor/Flash Storage (smart) + +usb:v061B* + ID_VENDOR_FROM_DATABASE=Promptus Communications, Inc. + +usb:v061C* + ID_VENDOR_FROM_DATABASE=Act Labs, Ltd + +usb:v061D* + ID_VENDOR_FROM_DATABASE=Quatech, Inc. + +usb:v061DpC020* + ID_PRODUCT_FROM_DATABASE=SSU-100 + +usb:v061E* + ID_VENDOR_FROM_DATABASE=Nissei Electric Co. + +usb:v061Ep0001* + ID_PRODUCT_FROM_DATABASE=nissei 128DE-USB - + +usb:v061Ep0010* + ID_PRODUCT_FROM_DATABASE=nissei 128DE-PNA - + +usb:v0620* + ID_VENDOR_FROM_DATABASE=Alaris, Inc. + +usb:v0620p0004* + ID_PRODUCT_FROM_DATABASE=QuickVideo weeCam + +usb:v0620p0007* + ID_PRODUCT_FROM_DATABASE=QuickVideo weeCam + +usb:v0620p000A* + ID_PRODUCT_FROM_DATABASE=QuickVideo weeCam + +usb:v0620p000B* + ID_PRODUCT_FROM_DATABASE=QuickVideo weeCam + +usb:v0621* + ID_VENDOR_FROM_DATABASE=ODU-Steckverbindungssysteme GmbH & Co. KG + +usb:v0622* + ID_VENDOR_FROM_DATABASE=Iotech, Inc. + +usb:v0623* + ID_VENDOR_FROM_DATABASE=Littelfuse, Inc. + +usb:v0624* + ID_VENDOR_FROM_DATABASE=Avocent Corp. + +usb:v0624p0294* + ID_PRODUCT_FROM_DATABASE=Dell 03R874 KVM dongle + +usb:v0624p0402* + ID_PRODUCT_FROM_DATABASE=Cisco Virtual Keyboard and Mouse + +usb:v0624p0403* + ID_PRODUCT_FROM_DATABASE=Cisco Virtual Mass Storage + +usb:v0625* + ID_VENDOR_FROM_DATABASE=TiMedia Technology Co., Ltd + +usb:v0626* + ID_VENDOR_FROM_DATABASE=Nippon Systems Development Co., Ltd + +usb:v0627* + ID_VENDOR_FROM_DATABASE=Adomax Technology Co., Ltd + +usb:v0628* + ID_VENDOR_FROM_DATABASE=Tasking Software, Inc. + +usb:v0629* + ID_VENDOR_FROM_DATABASE=Zida Technologies, Ltd + +usb:v062A* + ID_VENDOR_FROM_DATABASE=Creative Labs + +usb:v062Ap0000* + ID_PRODUCT_FROM_DATABASE=Optical mouse + +usb:v062Ap0001* + ID_PRODUCT_FROM_DATABASE=Notebook Optical Mouse + +usb:v062Ap0102* + ID_PRODUCT_FROM_DATABASE=Wireless Keyboard/Mouse Combo [MK1152WC] + +usb:v062Ap0201* + ID_PRODUCT_FROM_DATABASE=Defender Office Keyboard (K7310) S Zodiak KM-9010 + +usb:v062Ap0252* + ID_PRODUCT_FROM_DATABASE=Emerge Uni-retractable Laser Mouse + +usb:v062Ap3286* + ID_PRODUCT_FROM_DATABASE=Nano Receiver [Sandstrom Laser Mouse SMWLL11] + +usb:v062Ap6301* + ID_PRODUCT_FROM_DATABASE=Trust Wireless Optical Mouse MI-4150K + +usb:v062Ap9003* + ID_PRODUCT_FROM_DATABASE=VoIP Conference Hub (A16GH) + +usb:v062Ap9004* + ID_PRODUCT_FROM_DATABASE=USR9602 USB Internet Mini Phone + +usb:v062B* + ID_VENDOR_FROM_DATABASE=Greatlink Electronics Taiwan, Ltd + +usb:v062C* + ID_VENDOR_FROM_DATABASE=Institute for Information Industry + +usb:v062D* + ID_VENDOR_FROM_DATABASE=Taiwan Tai-Hao Enterprises Co., Ltd + +usb:v062E* + ID_VENDOR_FROM_DATABASE=Mainsuper Enterprises Co., Ltd + +usb:v062F* + ID_VENDOR_FROM_DATABASE=Sin Sheng Terminal & Machine, Inc. + +usb:v0631* + ID_VENDOR_FROM_DATABASE=JUJO Electronics Corp. + +usb:v0633* + ID_VENDOR_FROM_DATABASE=Cyrix Corp. + +usb:v0634* + ID_VENDOR_FROM_DATABASE=Micron Technology, Inc. + +usb:v0634p0655* + ID_PRODUCT_FROM_DATABASE=Embedded Mass Storage Drive [RealSSD] + +usb:v0635* + ID_VENDOR_FROM_DATABASE=Methode Electronics, Inc. + +usb:v0636* + ID_VENDOR_FROM_DATABASE=Sierra Imaging, Inc. + +usb:v0636p0003* + ID_PRODUCT_FROM_DATABASE=Vivicam 35Xx + +usb:v0638* + ID_VENDOR_FROM_DATABASE=Avision, Inc. + +usb:v0638p0268* + ID_PRODUCT_FROM_DATABASE=iVina 1200U Scanner + +usb:v0638p026A* + ID_PRODUCT_FROM_DATABASE=Minolta Dimage Scan Dual II AF-2820U (2886) + +usb:v0638p0A10* + ID_PRODUCT_FROM_DATABASE=iVina FB1600/UMAX Astra 4500 + +usb:v0638p0A13* + ID_PRODUCT_FROM_DATABASE=AV600U + +usb:v0638p0A15* + ID_PRODUCT_FROM_DATABASE=Konica Minolta SC-110 + +usb:v0638p0A16* + ID_PRODUCT_FROM_DATABASE=Konica Minolta SC-215 + +usb:v0638p0A30* + ID_PRODUCT_FROM_DATABASE=UMAX Astra 6700 Scanner + +usb:v0638p0A41* + ID_PRODUCT_FROM_DATABASE=Avision AM3000/MF3000 Series + +usb:v0638p0F01* + ID_PRODUCT_FROM_DATABASE=fi-4010CU + +usb:v0638p4004* + ID_PRODUCT_FROM_DATABASE=Minolta Dimage Scan Elite II AF-2920 (2888) + +usb:v0639* + ID_VENDOR_FROM_DATABASE=Chrontel, Inc. + +usb:v063A* + ID_VENDOR_FROM_DATABASE=Techwin Corp. + +usb:v063B* + ID_VENDOR_FROM_DATABASE=Taugagreining HF + +usb:v063C* + ID_VENDOR_FROM_DATABASE=Yamaichi Electronics Co., Ltd (Sakura) + +usb:v063D* + ID_VENDOR_FROM_DATABASE=Fong Kai Industrial Co., Ltd + +usb:v063E* + ID_VENDOR_FROM_DATABASE=RealMedia Technology, Inc. + +usb:v063F* + ID_VENDOR_FROM_DATABASE=New Technology Cable, Ltd + +usb:v0640* + ID_VENDOR_FROM_DATABASE=Hitex Development Tools + +usb:v0640p0026* + ID_PRODUCT_FROM_DATABASE=LPC-Stick + +usb:v0641* + ID_VENDOR_FROM_DATABASE=Woods Industries, Inc. + +usb:v0642* + ID_VENDOR_FROM_DATABASE=VIA Medical Corp. + +usb:v0644* + ID_VENDOR_FROM_DATABASE=TEAC Corp. + +usb:v0644p0000* + ID_PRODUCT_FROM_DATABASE=Floppy + +usb:v0644p0200* + ID_PRODUCT_FROM_DATABASE=All-In-One Multi-Card Reader CA200/B/S + +usb:v0644p1000* + ID_PRODUCT_FROM_DATABASE=CD-ROM Drive + +usb:v0644p800D* + ID_PRODUCT_FROM_DATABASE=TASCAM Portastudio DP-01FX + +usb:v0644p800E* + ID_PRODUCT_FROM_DATABASE=TASCAM US-122L + +usb:v0644p8021* + ID_PRODUCT_FROM_DATABASE=TASCAM US-122mkII + +usb:v0644pD001* + ID_PRODUCT_FROM_DATABASE=CD-R/RW Unit + +usb:v0644pD002* + ID_PRODUCT_FROM_DATABASE=CD-R/RW Unit + +usb:v0644pD010* + ID_PRODUCT_FROM_DATABASE=CD-RW/DVD Unit + +usb:v0645* + ID_VENDOR_FROM_DATABASE=Who? Vision Systems, Inc. + +usb:v0646* + ID_VENDOR_FROM_DATABASE=UMAX + +usb:v0647* + ID_VENDOR_FROM_DATABASE=Acton Research Corp. + +usb:v0647p0100* + ID_PRODUCT_FROM_DATABASE=ARC SpectraPro UV/VIS/IR Monochromator/Spectrograph + +usb:v0647p0101* + ID_PRODUCT_FROM_DATABASE=ARC AM-VM Mono Airpath/Vacuum Monochromator/Spectrograph + +usb:v0647p0102* + ID_PRODUCT_FROM_DATABASE=ARC Inspectrum Mono + +usb:v0647p0103* + ID_PRODUCT_FROM_DATABASE=ARC Filterwheel + +usb:v0647p03E9* + ID_PRODUCT_FROM_DATABASE=Inspectrum 128x1024 F VIS Spectrograph + +usb:v0647p03EA* + ID_PRODUCT_FROM_DATABASE=Inspectrum 256x1024 F VIS Spectrograph + +usb:v0647p03EB* + ID_PRODUCT_FROM_DATABASE=Inspectrum 128x1024 B VIS Spectrograph + +usb:v0647p03EC* + ID_PRODUCT_FROM_DATABASE=Inspectrum 256x1024 B VIS Spectrograph + +usb:v0648* + ID_VENDOR_FROM_DATABASE=Inside Out Networks + +usb:v0649* + ID_VENDOR_FROM_DATABASE=Weli Science Co., Ltd + +usb:v064B* + ID_VENDOR_FROM_DATABASE=Analog Devices, Inc. (White Mountain DSP) + +usb:v064Bp0165* + ID_PRODUCT_FROM_DATABASE=Blackfin 535 [ADZS HPUSB ICE] + +usb:v064C* + ID_VENDOR_FROM_DATABASE=Ji-Haw Industrial Co., Ltd + +usb:v064D* + ID_VENDOR_FROM_DATABASE=TriTech Microelectronics, Ltd + +usb:v064E* + ID_VENDOR_FROM_DATABASE=Suyin Corp. + +usb:v064EpA100* + ID_PRODUCT_FROM_DATABASE=Acer OrbiCam + +usb:v064EpA101* + ID_PRODUCT_FROM_DATABASE=Acer CrystalEye Webcam + +usb:v064EpA102* + ID_PRODUCT_FROM_DATABASE=Acer/Lenovo Webcam [CN0316] + +usb:v064EpA103* + ID_PRODUCT_FROM_DATABASE=Acer/HP Integrated Webcam [CN0314] + +usb:v064EpA110* + ID_PRODUCT_FROM_DATABASE=HP Webcam + +usb:v064EpA114* + ID_PRODUCT_FROM_DATABASE=Lemote Webcam + +usb:v064EpA136* + ID_PRODUCT_FROM_DATABASE=Asus Integrated Webcam [CN031B] + +usb:v064EpA219* + ID_PRODUCT_FROM_DATABASE=1.3M WebCam (notebook emachines E730, Acer sub-brand) + +usb:v064EpC107* + ID_PRODUCT_FROM_DATABASE=HP webcam [dv6-1190en] + +usb:v064EpD101* + ID_PRODUCT_FROM_DATABASE=Acer CrystalEye Webcam + +usb:v064EpE201* + ID_PRODUCT_FROM_DATABASE=Lenovo Integrated Webcam + +usb:v064EpE203* + ID_PRODUCT_FROM_DATABASE=Lenovo Integrated Webcam + +usb:v064EpF102* + ID_PRODUCT_FROM_DATABASE=Lenovo Integrated Webcam [R5U877] + +usb:v064EpF103* + ID_PRODUCT_FROM_DATABASE=Lenovo Integrated Webcam [R5U877] + +usb:v064F* + ID_VENDOR_FROM_DATABASE=WIBU-Systems AG + +usb:v064Fp03E9* + ID_PRODUCT_FROM_DATABASE=CmStick (article no. 1001) + +usb:v064Fp03F2* + ID_PRODUCT_FROM_DATABASE=CmStick/M (article no. 1010) + +usb:v064Fp03F3* + ID_PRODUCT_FROM_DATABASE=CmStick/M (article no. 1011) + +usb:v064Fp0BD7* + ID_PRODUCT_FROM_DATABASE=BOX/U + +usb:v064Fp0BD8* + ID_PRODUCT_FROM_DATABASE=BOX/RU + +usb:v0650* + ID_VENDOR_FROM_DATABASE=Dynapro Systems + +usb:v0651* + ID_VENDOR_FROM_DATABASE=Likom Technology Sdn. Bhd. + +usb:v0652* + ID_VENDOR_FROM_DATABASE=Stargate Solutions, Inc. + +usb:v0653* + ID_VENDOR_FROM_DATABASE=CNF, Inc. + +usb:v0654* + ID_VENDOR_FROM_DATABASE=Granite Microsystems, Inc. + +usb:v0654p0005* + ID_PRODUCT_FROM_DATABASE=Device Bay Controller + +usb:v0654p0006* + ID_PRODUCT_FROM_DATABASE=Hub + +usb:v0654p0007* + ID_PRODUCT_FROM_DATABASE=Device Bay Controller + +usb:v0654p0016* + ID_PRODUCT_FROM_DATABASE=Hub + +usb:v0655* + ID_VENDOR_FROM_DATABASE=Space Shuttle Hi-Tech Co., Ltd + +usb:v0656* + ID_VENDOR_FROM_DATABASE=Glory Mark Electronic, Ltd + +usb:v0657* + ID_VENDOR_FROM_DATABASE=Tekcon Electronics Corp. + +usb:v0658* + ID_VENDOR_FROM_DATABASE=Sigma Designs, Inc. + +usb:v0659* + ID_VENDOR_FROM_DATABASE=Aethra + +usb:v065A* + ID_VENDOR_FROM_DATABASE=Optoelectronics Co., Ltd + +usb:v065Ap0001* + ID_PRODUCT_FROM_DATABASE=Barcode scanner + +usb:v065B* + ID_VENDOR_FROM_DATABASE=Tracewell Systems + +usb:v065E* + ID_VENDOR_FROM_DATABASE=Silicon Graphics + +usb:v065F* + ID_VENDOR_FROM_DATABASE=Good Way Technology Co., Ltd & GWC technology Inc. + +usb:v0660* + ID_VENDOR_FROM_DATABASE=TSAY-E (BVI) International, Inc. + +usb:v0661* + ID_VENDOR_FROM_DATABASE=Hamamatsu Photonics K.K. + +usb:v0662* + ID_VENDOR_FROM_DATABASE=Kansai Electric Co., Ltd + +usb:v0663* + ID_VENDOR_FROM_DATABASE=Topmax Electronic Co., Ltd + +usb:v0663p0103* + ID_PRODUCT_FROM_DATABASE=CobraPad + +usb:v0664* + ID_VENDOR_FROM_DATABASE=ET&T Technology Co., Ltd. + +usb:v0664p0301* + ID_PRODUCT_FROM_DATABASE=Groovy Technology Corp. GTouch Touch Screen + +usb:v0664p0302* + ID_PRODUCT_FROM_DATABASE=Groovy Technology Corp. GTouch Touch Screen + +usb:v0664p0303* + ID_PRODUCT_FROM_DATABASE=Groovy Technology Corp. GTouch Touch Screen + +usb:v0664p0304* + ID_PRODUCT_FROM_DATABASE=Groovy Technology Corp. GTouch Touch Screen + +usb:v0664p0305* + ID_PRODUCT_FROM_DATABASE=Groovy Technology Corp. GTouch Touch Screen + +usb:v0664p0306* + ID_PRODUCT_FROM_DATABASE=Groovy Technology Corp. GTouch Touch Screen + +usb:v0664p0307* + ID_PRODUCT_FROM_DATABASE=Groovy Technology Corp. GTouch Touch Screen + +usb:v0664p0309* + ID_PRODUCT_FROM_DATABASE=Groovy Technology Corp. GTouch Touch Screen + +usb:v0665* + ID_VENDOR_FROM_DATABASE=Cypress Semiconductor + +usb:v0665p5161* + ID_PRODUCT_FROM_DATABASE=USB to Serial + +usb:v0667* + ID_VENDOR_FROM_DATABASE=Aiwa Co., Ltd + +usb:v0667p0FA1* + ID_PRODUCT_FROM_DATABASE=TD-U8000 Tape Drive + +usb:v0668* + ID_VENDOR_FROM_DATABASE=WordWand + +usb:v0669* + ID_VENDOR_FROM_DATABASE=Oce' Printing Systems GmbH + +usb:v066A* + ID_VENDOR_FROM_DATABASE=Total Technologies, Ltd + +usb:v066B* + ID_VENDOR_FROM_DATABASE=Linksys, Inc. + +usb:v066Bp0105* + ID_PRODUCT_FROM_DATABASE=SCM eUSB SmartMedia Card Reader + +usb:v066Bp010A* + ID_PRODUCT_FROM_DATABASE=Melco MCR-U2 SmartMedia / CompactFlash Reader + +usb:v066Bp200C* + ID_PRODUCT_FROM_DATABASE=USB10TX + +usb:v066Bp2202* + ID_PRODUCT_FROM_DATABASE=USB10TX Ethernet [pegasus] + +usb:v066Bp2203* + ID_PRODUCT_FROM_DATABASE=USB100TX Ethernet [pegasus] + +usb:v066Bp2204* + ID_PRODUCT_FROM_DATABASE=USB100TX HomePNA Ethernet [pegasus] + +usb:v066Bp2206* + ID_PRODUCT_FROM_DATABASE=USB Ethernet [pegasus] + +usb:v066Bp2207* + ID_PRODUCT_FROM_DATABASE=HomeLink Phoneline 10M Network Adapter + +usb:v066Bp2211* + ID_PRODUCT_FROM_DATABASE=WUSB11 802.11b Adapter + +usb:v066Bp2212* + ID_PRODUCT_FROM_DATABASE=WUSB11v2.5 802.11b Adapter + +usb:v066Bp2213* + ID_PRODUCT_FROM_DATABASE=WUSB12v1.1 802.11b Adapter + +usb:v066Bp2219* + ID_PRODUCT_FROM_DATABASE=Instant Wireless Network Adapter + +usb:v066Bp400B* + ID_PRODUCT_FROM_DATABASE=USB10TX + +usb:v066D* + ID_VENDOR_FROM_DATABASE=Entrega, Inc. + +usb:v066E* + ID_VENDOR_FROM_DATABASE=Acer Semiconductor America, Inc. + +usb:v066F* + ID_VENDOR_FROM_DATABASE=SigmaTel, Inc. + +usb:v066Fp003B* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp003E* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp003F* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp0040* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp0041* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp0042* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp0043* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp004B* + ID_PRODUCT_FROM_DATABASE=A-Max PA11 MP3 Player + +usb:v066Fp3400* + ID_PRODUCT_FROM_DATABASE=STMP3400 D-Major MP3 Player + +usb:v066Fp3410* + ID_PRODUCT_FROM_DATABASE=STMP3410 D-Major MP3 Player + +usb:v066Fp3500* + ID_PRODUCT_FROM_DATABASE=Player Recovery Device + +usb:v066Fp3780* + ID_PRODUCT_FROM_DATABASE=STMP3780/i.MX23 SystemOnChip in RecoveryMode + +usb:v066Fp4200* + ID_PRODUCT_FROM_DATABASE=STIr4200 IrDA Bridge + +usb:v066Fp4210* + ID_PRODUCT_FROM_DATABASE=STIr4210 IrDA Bridge + +usb:v066Fp8000* + ID_PRODUCT_FROM_DATABASE=MSCN MP3 Player + +usb:v066Fp8001* + ID_PRODUCT_FROM_DATABASE=SigmaTel MSCN Audio Player + +usb:v066Fp8004* + ID_PRODUCT_FROM_DATABASE=MSCNMMC MP3 Player + +usb:v066Fp8008* + ID_PRODUCT_FROM_DATABASE=i-Bead 100 MP3 Player + +usb:v066Fp8020* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp8034* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp8036* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp8038* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp8056* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp8060* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp8066* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp807E* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp8092* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp8096* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp809A* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp80AA* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp80AC* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp80B8* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp80BA* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp80BC* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp80BF* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp80C5* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp80C8* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp80CA* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp80CC* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp8104* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp8106* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp8108* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp810A* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp810C* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp8122* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp8124* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp8126* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp8128* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp8134* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp8136* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp8138* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp813A* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp813E* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp8140* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp8142* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp8144* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp8146* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp8148* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp814C* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp8201* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp8202* + ID_PRODUCT_FROM_DATABASE=Jens of Sweden / I-BEAD 150M/150H MP3 player + +usb:v066Fp8203* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp8204* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp8205* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp8206* + ID_PRODUCT_FROM_DATABASE=Digital MP3 Music Player + +usb:v066Fp8207* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp8208* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp8209* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp820A* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp820B* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp820C* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp820D* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp820E* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp820F* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp8210* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp8211* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp8212* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp8213* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp8214* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp8215* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp8216* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp8217* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp8218* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp8219* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp821A* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp821B* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp821C* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp821D* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp821E* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp821F* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp8220* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp8221* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp8222* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp8223* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp8224* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp8225* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp8226* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp8227* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp8228* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp8229* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp8230* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp829C* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp82E0* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp8320* + ID_PRODUCT_FROM_DATABASE=TrekStor i.Beat fun + +usb:v066Fp835D* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp9000* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp9001* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v066Fp9002* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v0670* + ID_VENDOR_FROM_DATABASE=Sequel Imaging + +usb:v0670p0001* + ID_PRODUCT_FROM_DATABASE=Calibrator + +usb:v0670p0005* + ID_PRODUCT_FROM_DATABASE=Enable Cable + +usb:v0672* + ID_VENDOR_FROM_DATABASE=Labtec, Inc. + +usb:v0672p1041* + ID_PRODUCT_FROM_DATABASE=LCS1040 Speaker System + +usb:v0672p5000* + ID_PRODUCT_FROM_DATABASE=SpaceBall 4000 FLX + +usb:v0673* + ID_VENDOR_FROM_DATABASE=HCL + +usb:v0673p5000* + ID_PRODUCT_FROM_DATABASE=Keyboard + +usb:v0674* + ID_VENDOR_FROM_DATABASE=Key Mouse Electronic Enterprise Co., Ltd + +usb:v0675* + ID_VENDOR_FROM_DATABASE=DrayTek Corp. + +usb:v0675p0110* + ID_PRODUCT_FROM_DATABASE=Vigor 128 ISDN TA + +usb:v0675p0530* + ID_PRODUCT_FROM_DATABASE=Vigor530 IEEE 802.11G Adapter (ISL3880+NET2280) + +usb:v0675p0550* + ID_PRODUCT_FROM_DATABASE=Vigor550 + +usb:v0675p1688* + ID_PRODUCT_FROM_DATABASE=miniVigor 128 ISDN TA + +usb:v0675p6694* + ID_PRODUCT_FROM_DATABASE=USB ISDN TA + +usb:v0676* + ID_VENDOR_FROM_DATABASE=Teles AG + +usb:v0677* + ID_VENDOR_FROM_DATABASE=Aiwa Co., Ltd + +usb:v0677p07D5* + ID_PRODUCT_FROM_DATABASE=TM-ED1285(USB) + +usb:v0677p0FA1* + ID_PRODUCT_FROM_DATABASE=TD-U8000 Tape Drive + +usb:v0678* + ID_VENDOR_FROM_DATABASE=ACard Technology Corp. + +usb:v067B* + ID_VENDOR_FROM_DATABASE=Prolific Technology, Inc. + +usb:v067Bp0000* + ID_PRODUCT_FROM_DATABASE=PL2301 USB-USB Bridge + +usb:v067Bp0001* + ID_PRODUCT_FROM_DATABASE=PL2302 USB-USB Bridge + +usb:v067Bp0307* + ID_PRODUCT_FROM_DATABASE=Motorola Serial Adapter + +usb:v067Bp04BB* + ID_PRODUCT_FROM_DATABASE=PL2303 Serial (IODATA USB-RSAQ2) + +usb:v067Bp0610* + ID_PRODUCT_FROM_DATABASE=Onext EG210U MODEM + +usb:v067Bp0611* + ID_PRODUCT_FROM_DATABASE=AlDiga AL-11U Quad-band GSM/GPRS/EDGE modem + +usb:v067Bp2303* + ID_PRODUCT_FROM_DATABASE=PL2303 Serial Port + +usb:v067Bp2305* + ID_PRODUCT_FROM_DATABASE=PL2305 Parallel Port + +usb:v067Bp2306* + ID_PRODUCT_FROM_DATABASE=Raylink Bridge Controller + +usb:v067Bp2307* + ID_PRODUCT_FROM_DATABASE=PL2307 USB-ATAPI4 Bridge + +usb:v067Bp2313* + ID_PRODUCT_FROM_DATABASE=FITEL PHS U Cable Adaptor + +usb:v067Bp2315* + ID_PRODUCT_FROM_DATABASE=Flash Disk Embedded Hub + +usb:v067Bp2316* + ID_PRODUCT_FROM_DATABASE=Flash Disk Security Device + +usb:v067Bp2317* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v067Bp2501* + ID_PRODUCT_FROM_DATABASE=PL2501 USB-USB Bridge (USB 2.0) + +usb:v067Bp2506* + ID_PRODUCT_FROM_DATABASE=Kaser 8gB micro hard drive + +usb:v067Bp2507* + ID_PRODUCT_FROM_DATABASE=PL2507 Hi-speed USB to IDE bridge controller + +usb:v067Bp2515* + ID_PRODUCT_FROM_DATABASE=Flash Disk Embedded Hub + +usb:v067Bp2517* + ID_PRODUCT_FROM_DATABASE=Flash Disk Mass Storage Device + +usb:v067Bp2528* + ID_PRODUCT_FROM_DATABASE=Storage device (8gB thumb drive) + +usb:v067Bp25A1* + ID_PRODUCT_FROM_DATABASE=PL25A1 Host-Host Bridge + +usb:v067Bp3400* + ID_PRODUCT_FROM_DATABASE=Hi-Speed Flash Disk with TruePrint AES3400 + +usb:v067Bp3500* + ID_PRODUCT_FROM_DATABASE=Hi-Speed Flash Disk with TruePrint AES3500 + +usb:v067Bp3507* + ID_PRODUCT_FROM_DATABASE=PL3507 ATAPI6 Bridge + +usb:v067BpAAA0* + ID_PRODUCT_FROM_DATABASE=Prolific Pharos + +usb:v067BpAAA2* + ID_PRODUCT_FROM_DATABASE=PL2303 Serial Adapter (IODATA USB-RSAQ3) + +usb:v067C* + ID_VENDOR_FROM_DATABASE=Efficient Networks, Inc. + +usb:v067Cp1001* + ID_PRODUCT_FROM_DATABASE=Siemens SpeedStream 100MBps Ethernet + +usb:v067Cp1022* + ID_PRODUCT_FROM_DATABASE=Siemens SpeedStream 1022 802.11b Adapter + +usb:v067Cp1023* + ID_PRODUCT_FROM_DATABASE=SpeedStream Wireless + +usb:v067Cp4020* + ID_PRODUCT_FROM_DATABASE=SpeedStream 4020 ATM/ADSL Installer + +usb:v067Cp4031* + ID_PRODUCT_FROM_DATABASE=Efficient ADSL Modem + +usb:v067Cp4032* + ID_PRODUCT_FROM_DATABASE=SpeedStream 4031 ATM/ADSL Installer + +usb:v067Cp4033* + ID_PRODUCT_FROM_DATABASE=SpeedStream 4031 ATM/ADSL Installer + +usb:v067Cp4060* + ID_PRODUCT_FROM_DATABASE=Alcatel Speedstream 4060 ADSL Modem + +usb:v067Cp4062* + ID_PRODUCT_FROM_DATABASE=Efficient Networks 4060 Loader + +usb:v067Cp5667* + ID_PRODUCT_FROM_DATABASE=Efficient Networks Virtual Bus for ADSL Modem + +usb:v067CpC031* + ID_PRODUCT_FROM_DATABASE=SpeedStream 4031 ATM/ADSL Installer + +usb:v067CpC032* + ID_PRODUCT_FROM_DATABASE=SpeedStream 4031 ATM/ADSL Installer + +usb:v067CpC033* + ID_PRODUCT_FROM_DATABASE=SpeedStream 4031 ATM/ADSL Installer + +usb:v067CpC060* + ID_PRODUCT_FROM_DATABASE=SpeedStream 4060 Miniport ATM/ADSL Adapter + +usb:v067CpD667* + ID_PRODUCT_FROM_DATABASE=Efficient Networks Virtual Bus for ADSL Modem + +usb:v067CpE240* + ID_PRODUCT_FROM_DATABASE=Speedstream Ethernet Adapter E240 + +usb:v067CpE540* + ID_PRODUCT_FROM_DATABASE=Speedstream Ethernet Adapter E240 + +usb:v067D* + ID_VENDOR_FROM_DATABASE=Hohner Corp. + +usb:v067E* + ID_VENDOR_FROM_DATABASE=Intermec Technologies Corp. + +usb:v067Ep0801* + ID_PRODUCT_FROM_DATABASE=HID Keyboard, Barcode scanner + +usb:v067Ep0803* + ID_PRODUCT_FROM_DATABASE=VCP, Barcode scanner + +usb:v067Ep0805* + ID_PRODUCT_FROM_DATABASE=VCP + UVC, Barcode scanner + +usb:v067Ep1001* + ID_PRODUCT_FROM_DATABASE=Mobile Computer + +usb:v067F* + ID_VENDOR_FROM_DATABASE=Virata, Ltd + +usb:v067Fp4552* + ID_PRODUCT_FROM_DATABASE=DSL-200 ADSL Modem + +usb:v067Fp6542* + ID_PRODUCT_FROM_DATABASE=DSL Modem + +usb:v067Fp6549* + ID_PRODUCT_FROM_DATABASE=DSL Modem + +usb:v067Fp7541* + ID_PRODUCT_FROM_DATABASE=DSL Modem + +usb:v0680* + ID_VENDOR_FROM_DATABASE=Realtek Semiconductor Corp., CPP Div. (Avance Logic) + +usb:v0680p0002* + ID_PRODUCT_FROM_DATABASE=Arowana Optical Wheel Mouse MSOP-01 + +usb:v0681* + ID_VENDOR_FROM_DATABASE=Siemens Information and Communication Products + +usb:v0681p0001* + ID_PRODUCT_FROM_DATABASE=Dect Base + +usb:v0681p0002* + ID_PRODUCT_FROM_DATABASE=Gigaset 3075 Passive ISDN + +usb:v0681p0005* + ID_PRODUCT_FROM_DATABASE=ID-Mouse with Fingerprint Reader + +usb:v0681p0012* + ID_PRODUCT_FROM_DATABASE=I-Gate 802.11b Adapter + +usb:v0681p001B* + ID_PRODUCT_FROM_DATABASE=WLL013 + +usb:v0681p001D* + ID_PRODUCT_FROM_DATABASE=Hipath 1000 + +usb:v0681p0022* + ID_PRODUCT_FROM_DATABASE=Gigaset SX353 ISDN + +usb:v0681p0026* + ID_PRODUCT_FROM_DATABASE=DECT Data - Gigaset M34 + +usb:v0681p002B* + ID_PRODUCT_FROM_DATABASE=A-100-I ADSL Modem + +usb:v0681p002E* + ID_PRODUCT_FROM_DATABASE=ADSL Router_S-141 + +usb:v0681p0034* + ID_PRODUCT_FROM_DATABASE=GSM module MC35/ES75 USB Modem + +usb:v0681p3C06* + ID_PRODUCT_FROM_DATABASE=54g USB Network Adapter + +usb:v0682* + ID_VENDOR_FROM_DATABASE=Victor Company of Japan, Ltd + +usb:v0684* + ID_VENDOR_FROM_DATABASE=Actiontec Electronics, Inc. + +usb:v0685* + ID_VENDOR_FROM_DATABASE=ZD Incorporated + +usb:v0685p7000* + ID_PRODUCT_FROM_DATABASE=HSDPA Modem + +usb:v0686* + ID_VENDOR_FROM_DATABASE=Minolta Co., Ltd + +usb:v0686p2001* + ID_PRODUCT_FROM_DATABASE=PagePro 4110W + +usb:v0686p2004* + ID_PRODUCT_FROM_DATABASE=PagePro 1200W + +usb:v0686p2005* + ID_PRODUCT_FROM_DATABASE=Magicolor 2300 DL + +usb:v0686p3001* + ID_PRODUCT_FROM_DATABASE=PagePro 4100 + +usb:v0686p3005* + ID_PRODUCT_FROM_DATABASE=PagePro 1250E + +usb:v0686p3006* + ID_PRODUCT_FROM_DATABASE=PagePro 1250W + +usb:v0686p3009* + ID_PRODUCT_FROM_DATABASE=Magicolor 2300W + +usb:v0686p300B* + ID_PRODUCT_FROM_DATABASE=PagePro 1350W + +usb:v0686p300C* + ID_PRODUCT_FROM_DATABASE=PagePro 1300W + +usb:v0686p302E* + ID_PRODUCT_FROM_DATABASE=Develop D 1650iD PCL + +usb:v0686p3034* + ID_PRODUCT_FROM_DATABASE=Develop D 2050iD PCL + +usb:v0686p4001* + ID_PRODUCT_FROM_DATABASE=Dimage 2300 + +usb:v0686p4003* + ID_PRODUCT_FROM_DATABASE=Dimage 2330 Zoom Camera + +usb:v0686p4004* + ID_PRODUCT_FROM_DATABASE=Dimage Scan Elite II AF-2920 (2888) + +usb:v0686p4005* + ID_PRODUCT_FROM_DATABASE=Minolta DiMAGE E201 Mass Storage Device + +usb:v0686p4006* + ID_PRODUCT_FROM_DATABASE=Dimage 7 Camera + +usb:v0686p4007* + ID_PRODUCT_FROM_DATABASE=Dimage S304 Camera + +usb:v0686p4008* + ID_PRODUCT_FROM_DATABASE=Dimage 5 Camera + +usb:v0686p4009* + ID_PRODUCT_FROM_DATABASE=Dimage X Camera + +usb:v0686p400A* + ID_PRODUCT_FROM_DATABASE=Dimage S404 Camera + +usb:v0686p400B* + ID_PRODUCT_FROM_DATABASE=Dimage 7i Camera + +usb:v0686p400C* + ID_PRODUCT_FROM_DATABASE=Dimage F100 Camera + +usb:v0686p400D* + ID_PRODUCT_FROM_DATABASE=Dimage Scan Dual III AF-2840 (2889) + +usb:v0686p400E* + ID_PRODUCT_FROM_DATABASE=Dimage Scan Elite 5400 (2890) + +usb:v0686p400F* + ID_PRODUCT_FROM_DATABASE=Dimage 7Hi Camera + +usb:v0686p4010* + ID_PRODUCT_FROM_DATABASE=Dimage Xi Camera + +usb:v0686p4011* + ID_PRODUCT_FROM_DATABASE=Dimage F300 Camera + +usb:v0686p4012* + ID_PRODUCT_FROM_DATABASE=Dimage F200 Camera + +usb:v0686p4014* + ID_PRODUCT_FROM_DATABASE=Dimage S414 Camera + +usb:v0686p4015* + ID_PRODUCT_FROM_DATABASE=Dimage XT Camera [storage] + +usb:v0686p4016* + ID_PRODUCT_FROM_DATABASE=Dimage XT Camera [remote mode] + +usb:v0686p4017* + ID_PRODUCT_FROM_DATABASE=Dimage E223 + +usb:v0686p4018* + ID_PRODUCT_FROM_DATABASE=Dimage Z1 Camera + +usb:v0686p4019* + ID_PRODUCT_FROM_DATABASE=Dimage A1 Camera [remote mode] + +usb:v0686p401A* + ID_PRODUCT_FROM_DATABASE=Dimage A1 Camera [storage] + +usb:v0686p401C* + ID_PRODUCT_FROM_DATABASE=Dimage X20 Camera + +usb:v0686p401E* + ID_PRODUCT_FROM_DATABASE=Dimage E323 Camera + +usb:v068A* + ID_VENDOR_FROM_DATABASE=Pertech, Inc. + +usb:v068B* + ID_VENDOR_FROM_DATABASE=Potrans International, Inc. + +usb:v068E* + ID_VENDOR_FROM_DATABASE=CH Products, Inc. + +usb:v068Ep00D3* + ID_PRODUCT_FROM_DATABASE=OEM 3 axis 5 button joystick + +usb:v068Ep00E2* + ID_PRODUCT_FROM_DATABASE=HFX OEM Joystick + +usb:v068Ep00F1* + ID_PRODUCT_FROM_DATABASE=Pro Throttle + +usb:v068Ep00F2* + ID_PRODUCT_FROM_DATABASE=Flight Sim Pedals + +usb:v068Ep00F3* + ID_PRODUCT_FROM_DATABASE=Fighterstick + +usb:v068Ep00F4* + ID_PRODUCT_FROM_DATABASE=Combatstick + +usb:v068Ep00FA* + ID_PRODUCT_FROM_DATABASE=Flight Sim Pedals + +usb:v068Ep00FF* + ID_PRODUCT_FROM_DATABASE=Flight Sim Yoke + +usb:v068Ep0500* + ID_PRODUCT_FROM_DATABASE=GameStick 3D + +usb:v068Ep0501* + ID_PRODUCT_FROM_DATABASE=CH Pro Pedals + +usb:v068Ep0504* + ID_PRODUCT_FROM_DATABASE=F-16 Combat Stick + +usb:v0690* + ID_VENDOR_FROM_DATABASE=Golden Bridge Electech, Inc. + +usb:v0693* + ID_VENDOR_FROM_DATABASE=Hagiwara Sys-Com Co., Ltd + +usb:v0693p0002* + ID_PRODUCT_FROM_DATABASE=FlashGate SmartMedia Card Reader + +usb:v0693p0003* + ID_PRODUCT_FROM_DATABASE=FlashGate CompactFlash Card Reader + +usb:v0693p0005* + ID_PRODUCT_FROM_DATABASE=FlashGate + +usb:v0693p0006* + ID_PRODUCT_FROM_DATABASE=SM PCCard R/W and SPD + +usb:v0693p0007* + ID_PRODUCT_FROM_DATABASE=FlashGate ME (Authenticated) + +usb:v0693p000A* + ID_PRODUCT_FROM_DATABASE=SDCard/MMC Reader/Writer + +usb:v0694* + ID_VENDOR_FROM_DATABASE=Lego Group + +usb:v0694p0001* + ID_PRODUCT_FROM_DATABASE=Mindstorms Tower + +usb:v0694p0002* + ID_PRODUCT_FROM_DATABASE=Mindstorms NXT + +usb:v0698* + ID_VENDOR_FROM_DATABASE=Chuntex (CTX) + +usb:v0698p1786* + ID_PRODUCT_FROM_DATABASE=1300ex Monitor + +usb:v0698p2003* + ID_PRODUCT_FROM_DATABASE=CTX M730V built in Camera + +usb:v0698p9999* + ID_PRODUCT_FROM_DATABASE=VLxxxx Monitor+Hub + +usb:v0699* + ID_VENDOR_FROM_DATABASE=Tektronix, Inc. + +usb:v069A* + ID_VENDOR_FROM_DATABASE=Askey Computer Corp. + +usb:v069Ap0001* + ID_PRODUCT_FROM_DATABASE=VC010 Webcam [pwc] + +usb:v069Ap0303* + ID_PRODUCT_FROM_DATABASE=Cable Modem + +usb:v069Ap0311* + ID_PRODUCT_FROM_DATABASE=ADSL Router Remote NDIS Device + +usb:v069Ap0318* + ID_PRODUCT_FROM_DATABASE=Remote NDIS Device + +usb:v069Ap0319* + ID_PRODUCT_FROM_DATABASE=220V Remote NDIS Device + +usb:v069Ap0320* + ID_PRODUCT_FROM_DATABASE=IEEE 802.11b Wireless LAN Card + +usb:v069Ap0321* + ID_PRODUCT_FROM_DATABASE=Dynalink WLL013 / Compex WLU11A 802.11b Adapter + +usb:v069Ap0402* + ID_PRODUCT_FROM_DATABASE=Scientific Atlanta WebSTAR 100 & 200 series Cable Modem + +usb:v069Ap0811* + ID_PRODUCT_FROM_DATABASE=BT Virtual Bus for Helium + +usb:v069Ap0821* + ID_PRODUCT_FROM_DATABASE=BT Voyager 1010 802.11b Adapter + +usb:v069Ap4402* + ID_PRODUCT_FROM_DATABASE=Scientific Atlanta WebSTAR 2000 series Cable Modem + +usb:v069Ap4403* + ID_PRODUCT_FROM_DATABASE=Scientific Atlanta WebSTAR 300 series Cable Modem + +usb:v069Ap4501* + ID_PRODUCT_FROM_DATABASE=Scientific-Atlanta WebSTAR 2000 series Cable Modem + +usb:v069B* + ID_VENDOR_FROM_DATABASE=Thomson, Inc. + +usb:v069Bp0704* + ID_PRODUCT_FROM_DATABASE=DCM245 Cable Modem + +usb:v069Bp0705* + ID_PRODUCT_FROM_DATABASE=THG540K Cable Modem + +usb:v069Bp0709* + ID_PRODUCT_FROM_DATABASE=Lyra PDP2424 + +usb:v069Bp070C* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v069Bp070D* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v069Bp070E* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v069Bp070F* + ID_PRODUCT_FROM_DATABASE=RCA Lyra RD1071 MP3 Player + +usb:v069Bp0731* + ID_PRODUCT_FROM_DATABASE=Lyra M200E256 + +usb:v069Bp0761* + ID_PRODUCT_FROM_DATABASE=RCA H100A + +usb:v069Bp0778* + ID_PRODUCT_FROM_DATABASE=PEARL USB Device + +usb:v069Bp2220* + ID_PRODUCT_FROM_DATABASE=RCA Kazoo RD1000 MP3 Player + +usb:v069Bp300A* + ID_PRODUCT_FROM_DATABASE=RCA Lyra MP3 Player + +usb:v069Bp3012* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v069Bp3013* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v069Bp5557* + ID_PRODUCT_FROM_DATABASE=RCA CDS6300 + +usb:v069D* + ID_VENDOR_FROM_DATABASE=Hughes Network Systems (HNS) + +usb:v069Dp0001* + ID_PRODUCT_FROM_DATABASE=Satellite Receiver Device + +usb:v069Dp0002* + ID_PRODUCT_FROM_DATABASE=Satellite Device + +usb:v069E* + ID_VENDOR_FROM_DATABASE=Welcat Inc. + +usb:v069Ep0005* + ID_PRODUCT_FROM_DATABASE=Marx CryptoBox v1.2 + +usb:v069F* + ID_VENDOR_FROM_DATABASE=Allied Data Technologies BV + +usb:v069Fp0010* + ID_PRODUCT_FROM_DATABASE=Tornado Speakerphone FaxModem 56.0 + +usb:v069Fp0011* + ID_PRODUCT_FROM_DATABASE=Tornado Speakerphone FaxModem 56.0 + +usb:v069Fp1000* + ID_PRODUCT_FROM_DATABASE=ADT VvBus for CopperJet + +usb:v069Fp1004* + ID_PRODUCT_FROM_DATABASE=CopperJet 821 RouterPlus + +usb:v06A2* + ID_VENDOR_FROM_DATABASE=Topro Technology, Inc. + +usb:v06A2p0033* + ID_PRODUCT_FROM_DATABASE=USB Mouse + +usb:v06A3* + ID_VENDOR_FROM_DATABASE=Saitek PLC + +usb:v06A3p0006* + ID_PRODUCT_FROM_DATABASE=Cyborg Gold Joystick + +usb:v06A3p0109* + ID_PRODUCT_FROM_DATABASE=P880 Pad + +usb:v06A3p0160* + ID_PRODUCT_FROM_DATABASE=ST290 Pro + +usb:v06A3p0200* + ID_PRODUCT_FROM_DATABASE=Xbox Adrenalin Hub + +usb:v06A3p0241* + ID_PRODUCT_FROM_DATABASE=Xbox Adrenalin Gamepad + +usb:v06A3p0255* + ID_PRODUCT_FROM_DATABASE=X52 Flight Controller + +usb:v06A3p040B* + ID_PRODUCT_FROM_DATABASE=P990 Dual Analog Pad + +usb:v06A3p040C* + ID_PRODUCT_FROM_DATABASE=P2900 Wireless Pad + +usb:v06A3p0422* + ID_PRODUCT_FROM_DATABASE=ST90 Joystick + +usb:v06A3p0460* + ID_PRODUCT_FROM_DATABASE=ST290 Pro Flight Stick + +usb:v06A3p0463* + ID_PRODUCT_FROM_DATABASE=ST290 + +usb:v06A3p0464* + ID_PRODUCT_FROM_DATABASE=Cyborg Evo + +usb:v06A3p0471* + ID_PRODUCT_FROM_DATABASE=Cyborg Graphite Stick + +usb:v06A3p0501* + ID_PRODUCT_FROM_DATABASE=R100 Sports Wheel + +usb:v06A3p0502* + ID_PRODUCT_FROM_DATABASE=ST200 Stick + +usb:v06A3p0506* + ID_PRODUCT_FROM_DATABASE=R220 Digital Wheel + +usb:v06A3p051E* + ID_PRODUCT_FROM_DATABASE=Cyborg Digital II Stick + +usb:v06A3p052D* + ID_PRODUCT_FROM_DATABASE=P750 Gamepad + +usb:v06A3p053C* + ID_PRODUCT_FROM_DATABASE=X45 Flight Controller + +usb:v06A3p053F* + ID_PRODUCT_FROM_DATABASE=X36F Flightstick + +usb:v06A3p056C* + ID_PRODUCT_FROM_DATABASE=P2000 Tilt Pad + +usb:v06A3p056F* + ID_PRODUCT_FROM_DATABASE=P2000 Tilt Pad + +usb:v06A3p05D2* + ID_PRODUCT_FROM_DATABASE=PC Dash 2 + +usb:v06A3p075C* + ID_PRODUCT_FROM_DATABASE=X52 Flight Controller + +usb:v06A3p0762* + ID_PRODUCT_FROM_DATABASE=Saitek X52 Pro Flight Control System + +usb:v06A3p0763* + ID_PRODUCT_FROM_DATABASE=Pro Flight Rudder Pedals + +usb:v06A3p0764* + ID_PRODUCT_FROM_DATABASE=Flight Pro Combat Rudder + +usb:v06A3p0805* + ID_PRODUCT_FROM_DATABASE=R440 Force Wheel + +usb:v06A3p0B4E* + ID_PRODUCT_FROM_DATABASE=Pro Flight Backlit Information Panel + +usb:v06A3p0BAC* + ID_PRODUCT_FROM_DATABASE=Pro Flight Yoke + +usb:v06A3p0C2D* + ID_PRODUCT_FROM_DATABASE=Pro Flight Quadrant + +usb:v06A3p0D05* + ID_PRODUCT_FROM_DATABASE=Pro Flight Radio Panel + +usb:v06A3p0D06* + ID_PRODUCT_FROM_DATABASE=Flight Pro Multi Panel + +usb:v06A3p0D67* + ID_PRODUCT_FROM_DATABASE=Pro Flight Switch Panel + +usb:v06A3p1003* + ID_PRODUCT_FROM_DATABASE=GM2 Action Pad + +usb:v06A3p1009* + ID_PRODUCT_FROM_DATABASE=Action Pad + +usb:v06A3p100A* + ID_PRODUCT_FROM_DATABASE=SP550 Pad and Joystick Combo + +usb:v06A3p100B* + ID_PRODUCT_FROM_DATABASE=SP550 Pad + +usb:v06A3p1509* + ID_PRODUCT_FROM_DATABASE=P3000 Wireless Pad + +usb:v06A3p1589* + ID_PRODUCT_FROM_DATABASE=P3000 Wireless Pad + +usb:v06A3p2541* + ID_PRODUCT_FROM_DATABASE=X45 Flight Controller + +usb:v06A3p3509* + ID_PRODUCT_FROM_DATABASE=P3000 RF GamePad + +usb:v06A3p353E* + ID_PRODUCT_FROM_DATABASE=Cyborg Evo Wireless + +usb:v06A3p3589* + ID_PRODUCT_FROM_DATABASE=P3000 Wireless Pad + +usb:v06A3p35BE* + ID_PRODUCT_FROM_DATABASE=Cyborg Evo + +usb:v06A3p5509* + ID_PRODUCT_FROM_DATABASE=P3000 Wireless Pad + +usb:v06A3p712C* + ID_PRODUCT_FROM_DATABASE=Pro Flight Yoke integrated hub + +usb:v06A3p8000* + ID_PRODUCT_FROM_DATABASE=Gamers' Keyboard + +usb:v06A3p801E* + ID_PRODUCT_FROM_DATABASE=Cyborg 3D Digital Stick II + +usb:v06A3p8020* + ID_PRODUCT_FROM_DATABASE=Eclipse Keyboard + +usb:v06A3p8021* + ID_PRODUCT_FROM_DATABASE=Eclipse II Keyboard + +usb:v06A3p802D* + ID_PRODUCT_FROM_DATABASE=P750 Pad + +usb:v06A3p803F* + ID_PRODUCT_FROM_DATABASE=X36 Flight Controller + +usb:v06A3p806F* + ID_PRODUCT_FROM_DATABASE=P2000 Tilt Pad + +usb:v06A3p80C0* + ID_PRODUCT_FROM_DATABASE=Pro Gamer Command Unit + +usb:v06A3p80C1* + ID_PRODUCT_FROM_DATABASE=Cyborg Command Pad Unit + +usb:v06A3pA2AE* + ID_PRODUCT_FROM_DATABASE=Pro Flight Instrument Panel + +usb:v06A3pA502* + ID_PRODUCT_FROM_DATABASE=Gaming Mouse + +usb:v06A3pF518* + ID_PRODUCT_FROM_DATABASE=P3200 Rumble Force Game Pad + +usb:v06A3pFF04* + ID_PRODUCT_FROM_DATABASE=R440 Force Wheel + +usb:v06A3pFF0C* + ID_PRODUCT_FROM_DATABASE=Cyborg Force Rumble Pad + +usb:v06A3pFF0D* + ID_PRODUCT_FROM_DATABASE=P2600 Rumble Force Pad + +usb:v06A3pFF12* + ID_PRODUCT_FROM_DATABASE=Cyborg 3D Force Stick + +usb:v06A3pFF17* + ID_PRODUCT_FROM_DATABASE=ST 330 Rumble Force Stick + +usb:v06A3pFF52* + ID_PRODUCT_FROM_DATABASE=Cyborg 3D Rumble Force Joystick + +usb:v06A3pFFB5* + ID_PRODUCT_FROM_DATABASE=Cyborg Evo Force Joystick + +usb:v06A4* + ID_VENDOR_FROM_DATABASE=Xiamen Doowell Electron Co., Ltd + +usb:v06A5* + ID_VENDOR_FROM_DATABASE=Divio + +usb:v06A5p0000* + ID_PRODUCT_FROM_DATABASE=Typhoon Webcam 100k [nw8000] + +usb:v06A5pD001* + ID_PRODUCT_FROM_DATABASE=ProLink DS3303u Webcam + +usb:v06A5pD800* + ID_PRODUCT_FROM_DATABASE=Chicony TwinkleCam + +usb:v06A5pD820* + ID_PRODUCT_FROM_DATABASE=Wize Media 1000 + +usb:v06A7* + ID_VENDOR_FROM_DATABASE=MicroStore, Inc. + +usb:v06A8* + ID_VENDOR_FROM_DATABASE=Topaz Systems, Inc. + +usb:v06A8p0042* + ID_PRODUCT_FROM_DATABASE=SignatureGem 1X5 Pad + +usb:v06A8p0043* + ID_PRODUCT_FROM_DATABASE=SignatureGem 1X5-HID Pad + +usb:v06A9* + ID_VENDOR_FROM_DATABASE=Westell + +usb:v06A9p0005* + ID_PRODUCT_FROM_DATABASE=WireSpeed Dual Connect Modem + +usb:v06A9p0006* + ID_PRODUCT_FROM_DATABASE=WireSpeed Dual Connect Modem + +usb:v06A9p000A* + ID_PRODUCT_FROM_DATABASE=WireSpeed Dual Connect Modem + +usb:v06A9p000B* + ID_PRODUCT_FROM_DATABASE=WireSpeed Dual Connect Modem + +usb:v06A9p000E* + ID_PRODUCT_FROM_DATABASE=A90-211WG-01 802.11g Adapter [Intersil ISL3887] + +usb:v06AA* + ID_VENDOR_FROM_DATABASE=Sysgration, Ltd + +usb:v06AC* + ID_VENDOR_FROM_DATABASE=Fujitsu Laboratories of America, Inc. + +usb:v06AD* + ID_VENDOR_FROM_DATABASE=Greatland Electronics Taiwan, Ltd + +usb:v06AE* + ID_VENDOR_FROM_DATABASE=Professional Multimedia Testing Centre + +usb:v06AF* + ID_VENDOR_FROM_DATABASE=Harting, Inc. of North America + +usb:v06B8* + ID_VENDOR_FROM_DATABASE=Pixela Corp. + +usb:v06B9* + ID_VENDOR_FROM_DATABASE=Alcatel Telecom + +usb:v06B9p0120* + ID_PRODUCT_FROM_DATABASE=SpeedTouch 120g 802.11g Wireless Adapter [Intersil ISL3886] + +usb:v06B9p0121* + ID_PRODUCT_FROM_DATABASE=SpeedTouch 121g Wireless Dongle + +usb:v06B9p2001* + ID_PRODUCT_FROM_DATABASE=SPEED TOUCH Card + +usb:v06B9p4061* + ID_PRODUCT_FROM_DATABASE=SpeedTouch ISDN or ADSL Modem + +usb:v06B9p4062* + ID_PRODUCT_FROM_DATABASE=SpeedTouch ISDN or ADSL router + +usb:v06B9pA5A5* + ID_PRODUCT_FROM_DATABASE=DynaMiTe Modem + +usb:v06BA* + ID_VENDOR_FROM_DATABASE=Smooth Cord & Connector Co., Ltd + +usb:v06BB* + ID_VENDOR_FROM_DATABASE=EDA, Inc. + +usb:v06BC* + ID_VENDOR_FROM_DATABASE=Oki Data Corp. + +usb:v06BCp000B* + ID_PRODUCT_FROM_DATABASE=Okipage 14ex Printer + +usb:v06BCp0027* + ID_PRODUCT_FROM_DATABASE=Okipage 14e + +usb:v06BCp0A91* + ID_PRODUCT_FROM_DATABASE=B2500MFP (printer+scanner) + +usb:v06BCp3801* + ID_PRODUCT_FROM_DATABASE=B6100 Laser Printer + +usb:v06BD* + ID_VENDOR_FROM_DATABASE=AGFA-Gevaert NV + +usb:v06BDp0001* + ID_PRODUCT_FROM_DATABASE=SnapScan 1212U + +usb:v06BDp0002* + ID_PRODUCT_FROM_DATABASE=SnapScan 1236U + +usb:v06BDp0100* + ID_PRODUCT_FROM_DATABASE=SnapScan Touch + +usb:v06BDp0101* + ID_PRODUCT_FROM_DATABASE=SNAPSCAN ELITE + +usb:v06BDp0200* + ID_PRODUCT_FROM_DATABASE=ScanMaker 8700 + +usb:v06BDp02BF* + ID_PRODUCT_FROM_DATABASE=DUOSCAN f40 + +usb:v06BDp0400* + ID_PRODUCT_FROM_DATABASE=CL30 + +usb:v06BDp0401* + ID_PRODUCT_FROM_DATABASE=Mass Storage + +usb:v06BDp0403* + ID_PRODUCT_FROM_DATABASE=ePhoto CL18 Camera + +usb:v06BDp0404* + ID_PRODUCT_FROM_DATABASE=ePhoto CL20 Camera + +usb:v06BDp2061* + ID_PRODUCT_FROM_DATABASE=SnapScan 1212U (?) + +usb:v06BDp208D* + ID_PRODUCT_FROM_DATABASE=Snapscan e40 + +usb:v06BDp208F* + ID_PRODUCT_FROM_DATABASE=SnapScan e50 + +usb:v06BDp2091* + ID_PRODUCT_FROM_DATABASE=SnapScan e20 + +usb:v06BDp2093* + ID_PRODUCT_FROM_DATABASE=SnapScan e10 + +usb:v06BDp2095* + ID_PRODUCT_FROM_DATABASE=SnapScan e25 + +usb:v06BDp2097* + ID_PRODUCT_FROM_DATABASE=SnapScan e26 + +usb:v06BDp20FD* + ID_PRODUCT_FROM_DATABASE=SnapScan e52 + +usb:v06BDp20FF* + ID_PRODUCT_FROM_DATABASE=SnapScan e42 + +usb:v06BE* + ID_VENDOR_FROM_DATABASE=AME Optimedia Technology Co., Ltd + +usb:v06BEp0800* + ID_PRODUCT_FROM_DATABASE=Optimedia Camera + +usb:v06BEp1005* + ID_PRODUCT_FROM_DATABASE=Dazzle DPVM! (1005) + +usb:v06BEpD001* + ID_PRODUCT_FROM_DATABASE=P35U Camera Capture + +usb:v06BF* + ID_VENDOR_FROM_DATABASE=Leoco Corp. + +usb:v06C2* + ID_VENDOR_FROM_DATABASE=Phidgets Inc. (formerly GLAB) + +usb:v06C2p0030* + ID_PRODUCT_FROM_DATABASE=PhidgetRFID + +usb:v06C2p0038* + ID_PRODUCT_FROM_DATABASE=4-Motor PhidgetServo v3.0 + +usb:v06C2p0039* + ID_PRODUCT_FROM_DATABASE=1-Motor PhidgetServo v3.0 + +usb:v06C2p003A* + ID_PRODUCT_FROM_DATABASE=8-Motor PhidgetAvancedServo + +usb:v06C2p0040* + ID_PRODUCT_FROM_DATABASE=PhidgetInterface Kit 0-0-4 + +usb:v06C2p0044* + ID_PRODUCT_FROM_DATABASE=PhidgetInterface Kit 0-16-16 + +usb:v06C2p0045* + ID_PRODUCT_FROM_DATABASE=PhidgetInterface Kit 8-8-8 + +usb:v06C2p0048* + ID_PRODUCT_FROM_DATABASE=PhidgetStepper (Under Development) + +usb:v06C2p0049* + ID_PRODUCT_FROM_DATABASE=PhidgetTextLED Ver 1.0 + +usb:v06C2p004A* + ID_PRODUCT_FROM_DATABASE=PhidgetLED Ver 1.0 + +usb:v06C2p004B* + ID_PRODUCT_FROM_DATABASE=PhidgetEncoder Ver 1.0 + +usb:v06C2p0051* + ID_PRODUCT_FROM_DATABASE=PhidgetInterface Kit 0-5-7 (Custom) + +usb:v06C2p0052* + ID_PRODUCT_FROM_DATABASE=PhidgetTextLCD + +usb:v06C2p0053* + ID_PRODUCT_FROM_DATABASE=PhidgetInterfaceKit 0-8-8 + +usb:v06C2p0058* + ID_PRODUCT_FROM_DATABASE=PhidgetMotorControl Ver 1.0 + +usb:v06C2p0070* + ID_PRODUCT_FROM_DATABASE=PhidgetTemperatureSensor Ver 1.0 + +usb:v06C2p0071* + ID_PRODUCT_FROM_DATABASE=PhidgetAccelerometer Ver 1.0 + +usb:v06C2p0072* + ID_PRODUCT_FROM_DATABASE=PhidgetWeightSensor Ver 1.0 + +usb:v06C2p0073* + ID_PRODUCT_FROM_DATABASE=PhidgetHumiditySensor + +usb:v06C2p0074* + ID_PRODUCT_FROM_DATABASE=PhidgetPHSensor + +usb:v06C2p0075* + ID_PRODUCT_FROM_DATABASE=PhidgetGyroscope + +usb:v06C4* + ID_VENDOR_FROM_DATABASE=Bizlink International Corp. + +usb:v06C5* + ID_VENDOR_FROM_DATABASE=Hagenuk, GmbH + +usb:v06C6* + ID_VENDOR_FROM_DATABASE=Infowave Software, Inc. + +usb:v06C8* + ID_VENDOR_FROM_DATABASE=SIIG, Inc. + +usb:v06C9* + ID_VENDOR_FROM_DATABASE=Taxan (Europe), Ltd + +usb:v06C9p0005* + ID_PRODUCT_FROM_DATABASE=Monitor Control + +usb:v06C9p0007* + ID_PRODUCT_FROM_DATABASE=Monitor Control + +usb:v06C9p0009* + ID_PRODUCT_FROM_DATABASE=Monitor Control + +usb:v06CA* + ID_VENDOR_FROM_DATABASE=Newer Technology, Inc. + +usb:v06CB* + ID_VENDOR_FROM_DATABASE=Synaptics, Inc. + +usb:v06CBp0001* + ID_PRODUCT_FROM_DATABASE=TouchPad + +usb:v06CBp0002* + ID_PRODUCT_FROM_DATABASE=Integrated TouchPad + +usb:v06CBp0003* + ID_PRODUCT_FROM_DATABASE=cPad + +usb:v06CBp0005* + ID_PRODUCT_FROM_DATABASE=Touchpad/FPS + +usb:v06CBp0006* + ID_PRODUCT_FROM_DATABASE=TouchScreen + +usb:v06CBp0007* + ID_PRODUCT_FROM_DATABASE=USB Styk + +usb:v06CBp0008* + ID_PRODUCT_FROM_DATABASE=WheelPad + +usb:v06CBp0009* + ID_PRODUCT_FROM_DATABASE=Composite TouchPad and TrackPoint + +usb:v06CBp000E* + ID_PRODUCT_FROM_DATABASE=HID Device + +usb:v06CBp0010* + ID_PRODUCT_FROM_DATABASE=Wireless TouchPad + +usb:v06CBp0013* + ID_PRODUCT_FROM_DATABASE=DisplayPad + +usb:v06CC* + ID_VENDOR_FROM_DATABASE=Terayon Communication Systems + +usb:v06CCp0101* + ID_PRODUCT_FROM_DATABASE=Cable Modem + +usb:v06CCp0102* + ID_PRODUCT_FROM_DATABASE=Cable Modem + +usb:v06CCp0103* + ID_PRODUCT_FROM_DATABASE=Cable Modem + +usb:v06CCp0104* + ID_PRODUCT_FROM_DATABASE=Cable Modem + +usb:v06CCp0304* + ID_PRODUCT_FROM_DATABASE=Cable Modem + +usb:v06CD* + ID_VENDOR_FROM_DATABASE=Keyspan + +usb:v06CDp0101* + ID_PRODUCT_FROM_DATABASE=USA-28 PDA [no firmware] + +usb:v06CDp0102* + ID_PRODUCT_FROM_DATABASE=USA-28X PDA [no firmware] + +usb:v06CDp0103* + ID_PRODUCT_FROM_DATABASE=USA-19 PDA [no firmware] + +usb:v06CDp0104* + ID_PRODUCT_FROM_DATABASE=PDA [prerenum] + +usb:v06CDp0105* + ID_PRODUCT_FROM_DATABASE=USA-18X PDA [no firmware] + +usb:v06CDp0106* + ID_PRODUCT_FROM_DATABASE=USA-19W PDA [no firmware] + +usb:v06CDp0107* + ID_PRODUCT_FROM_DATABASE=USA-19 PDA + +usb:v06CDp0108* + ID_PRODUCT_FROM_DATABASE=USA-19W PDA + +usb:v06CDp0109* + ID_PRODUCT_FROM_DATABASE=USA-49W serial adapter [no firmware] + +usb:v06CDp010A* + ID_PRODUCT_FROM_DATABASE=USA-49W serial adapter + +usb:v06CDp010B* + ID_PRODUCT_FROM_DATABASE=USA-19Qi serial adapter [no firmware] + +usb:v06CDp010C* + ID_PRODUCT_FROM_DATABASE=USA-19Qi serial adapter + +usb:v06CDp010D* + ID_PRODUCT_FROM_DATABASE=USA-19Q serial Adapter (no firmware) + +usb:v06CDp010E* + ID_PRODUCT_FROM_DATABASE=USA-19Q serial Adapter + +usb:v06CDp010F* + ID_PRODUCT_FROM_DATABASE=USA-28 PDA + +usb:v06CDp0110* + ID_PRODUCT_FROM_DATABASE=USA-28Xb PDA + +usb:v06CDp0111* + ID_PRODUCT_FROM_DATABASE=USA-18 serial Adapter + +usb:v06CDp0112* + ID_PRODUCT_FROM_DATABASE=USA-18X PDA + +usb:v06CDp0113* + ID_PRODUCT_FROM_DATABASE=USA-28Xb PDA [no firmware] + +usb:v06CDp0114* + ID_PRODUCT_FROM_DATABASE=USA-28Xa PDA [no firmware] + +usb:v06CDp0115* + ID_PRODUCT_FROM_DATABASE=USA-28Xa PDA + +usb:v06CDp0116* + ID_PRODUCT_FROM_DATABASE=USA-18XA serial Adapter (no firmware) + +usb:v06CDp0117* + ID_PRODUCT_FROM_DATABASE=USA-18XA serial Adapter + +usb:v06CDp0118* + ID_PRODUCT_FROM_DATABASE=USA-19QW PDA [no firmware] + +usb:v06CDp0119* + ID_PRODUCT_FROM_DATABASE=USA-19QW PDA + +usb:v06CDp011A* + ID_PRODUCT_FROM_DATABASE=USA-49Wlc serial adapter [no firmware] + +usb:v06CDp011B* + ID_PRODUCT_FROM_DATABASE=MPR Serial Preloader (MPRQI) + +usb:v06CDp011C* + ID_PRODUCT_FROM_DATABASE=MPR Serial (MPRQI) + +usb:v06CDp011D* + ID_PRODUCT_FROM_DATABASE=MPR Serial Preloader (MPRQ) + +usb:v06CDp011E* + ID_PRODUCT_FROM_DATABASE=MPR Serial (MPRQ) + +usb:v06CDp0121* + ID_PRODUCT_FROM_DATABASE=USA-19hs serial adapter + +usb:v06CDp012A* + ID_PRODUCT_FROM_DATABASE=USA-49Wlc serial adapter + +usb:v06CDp0201* + ID_PRODUCT_FROM_DATABASE=UIA-10 Digital Media Remote [Cypress AN2131SC] + +usb:v06CDp0202* + ID_PRODUCT_FROM_DATABASE=UIA-11 Digital Media Remote + +usb:v06CE* + ID_VENDOR_FROM_DATABASE=Contec + +usb:v06CEp8311* + ID_PRODUCT_FROM_DATABASE=COM-1(USB)H + +usb:v06CF* + ID_VENDOR_FROM_DATABASE=SpheronVR AG + +usb:v06CFp1010* + ID_PRODUCT_FROM_DATABASE=PanoCam 10 + +usb:v06CFp1012* + ID_PRODUCT_FROM_DATABASE=PanoCam 12/12X + +usb:v06D0* + ID_VENDOR_FROM_DATABASE=LapLink, Inc. + +usb:v06D0p0622* + ID_PRODUCT_FROM_DATABASE=LapLink Gold USB-USB Bridge [net1080] + +usb:v06D1* + ID_VENDOR_FROM_DATABASE=Daewoo Electronics Co., Ltd + +usb:v06D3* + ID_VENDOR_FROM_DATABASE=Mitsubishi Electric Corp. + +usb:v06D3p0380* + ID_PRODUCT_FROM_DATABASE=CP8000D Port + +usb:v06D3p0381* + ID_PRODUCT_FROM_DATABASE=CP770D Port + +usb:v06D3p0385* + ID_PRODUCT_FROM_DATABASE=CP900D Port + +usb:v06D3p0387* + ID_PRODUCT_FROM_DATABASE=CP980D Port + +usb:v06D3p038B* + ID_PRODUCT_FROM_DATABASE=CP3020D Port + +usb:v06D3p038C* + ID_PRODUCT_FROM_DATABASE=CP900DW(ID) Port + +usb:v06D3p0393* + ID_PRODUCT_FROM_DATABASE=CP9500D/DW Port + +usb:v06D3p0394* + ID_PRODUCT_FROM_DATABASE=CP9000D/DW Port + +usb:v06D3p03A1* + ID_PRODUCT_FROM_DATABASE=CP9550D/DW Port + +usb:v06D4* + ID_VENDOR_FROM_DATABASE=Cisco Systems + +usb:v06D5* + ID_VENDOR_FROM_DATABASE=Toshiba + +usb:v06D5p4000* + ID_PRODUCT_FROM_DATABASE=Japanese Keyboard + +usb:v06D6* + ID_VENDOR_FROM_DATABASE=Aashima Technology B.V. + +usb:v06D6p0025* + ID_PRODUCT_FROM_DATABASE=Gamepad + +usb:v06D6p0026* + ID_PRODUCT_FROM_DATABASE=Predator TH 400 Gamepad + +usb:v06D6p002D* + ID_PRODUCT_FROM_DATABASE=Trust PowerC@m 350FT + +usb:v06D6p002E* + ID_PRODUCT_FROM_DATABASE=Trust PowerC@m 350FS + +usb:v06D6p0030* + ID_PRODUCT_FROM_DATABASE=Trust 710 LCD POWERC@M ZOOM - MSD + +usb:v06D6p0031* + ID_PRODUCT_FROM_DATABASE=Trust 610/710 LCD POWERC@M ZOOM + +usb:v06D6p003A* + ID_PRODUCT_FROM_DATABASE=Trust PowerC@m 770Z (mass storage mode) + +usb:v06D6p003B* + ID_PRODUCT_FROM_DATABASE=Trust PowerC@m 770Z (webcam mode) + +usb:v06D6p003C* + ID_PRODUCT_FROM_DATABASE=Trust 910z PowerC@m + +usb:v06D6p003F* + ID_PRODUCT_FROM_DATABASE=Trust 735S POWERC@M ZOOM, WDM DSC Bulk Driver + +usb:v06D6p0050* + ID_PRODUCT_FROM_DATABASE=Trust 738AV LCD PV Digital Camera + +usb:v06D6p0062* + ID_PRODUCT_FROM_DATABASE=TRUST 782AV LCD P. V. Video Capture + +usb:v06D6p0066* + ID_PRODUCT_FROM_DATABASE=TRUST Digital PCTV and Movie Editor + +usb:v06D6p0067* + ID_PRODUCT_FROM_DATABASE=Trust 350FS POWERC@M FLASH + +usb:v06D6p006B* + ID_PRODUCT_FROM_DATABASE=TRUST AUDIO VIDEO EDITOR + +usb:v06D7* + ID_VENDOR_FROM_DATABASE=Network Computing Devices (NCD) + +usb:v06D8* + ID_VENDOR_FROM_DATABASE=Technical Marketing Research, Inc. + +usb:v06DA* + ID_VENDOR_FROM_DATABASE=Phoenixtec Power Co., Ltd + +usb:v06DAp0002* + ID_PRODUCT_FROM_DATABASE=UPS + +usb:v06DAp0003* + ID_PRODUCT_FROM_DATABASE=1300VA UPS + +usb:v06DB* + ID_VENDOR_FROM_DATABASE=Paradyne + +usb:v06DC* + ID_VENDOR_FROM_DATABASE=Foxlink Image Technology Co., Ltd + +usb:v06DCp0012* + ID_PRODUCT_FROM_DATABASE=Scan 1200c Scanner + +usb:v06DCp0014* + ID_PRODUCT_FROM_DATABASE=Prolink Winscan Pro 2448U + +usb:v06DE* + ID_VENDOR_FROM_DATABASE=Heisei Electronics Co., Ltd + +usb:v06E0* + ID_VENDOR_FROM_DATABASE=Multi-Tech Systems, Inc. + +usb:v06E0pF101* + ID_PRODUCT_FROM_DATABASE=MT5634ZBA-USB MultiModemUSB (old firmware) + +usb:v06E0pF103* + ID_PRODUCT_FROM_DATABASE=MT5634MU MultiMobileUSB + +usb:v06E0pF104* + ID_PRODUCT_FROM_DATABASE=MT5634ZBA-USB MultiModemUSB (new firmware) + +usb:v06E0pF107* + ID_PRODUCT_FROM_DATABASE=MT5634ZBA-USB-V92 MultiModemUSB + +usb:v06E1* + ID_VENDOR_FROM_DATABASE=ADS Technologies, Inc. + +usb:v06E1p0008* + ID_PRODUCT_FROM_DATABASE=UBS-10BT Ethernet [klsi] + +usb:v06E1p0009* + ID_PRODUCT_FROM_DATABASE=UBS-10BT Ethernet + +usb:v06E1p0833* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v06E1pA155* + ID_PRODUCT_FROM_DATABASE=FM Radio Receiver/Instant FM Music (RDX-155-EF) + +usb:v06E1pA160* + ID_PRODUCT_FROM_DATABASE=Instant Video-To-Go RDX-160 (no firmware) + +usb:v06E1pA161* + ID_PRODUCT_FROM_DATABASE=Instant Video-To-Go RDX-160 + +usb:v06E1pA190* + ID_PRODUCT_FROM_DATABASE=Instand VCD Capture + +usb:v06E1pA191* + ID_PRODUCT_FROM_DATABASE=Instant VideoXpress + +usb:v06E1pA337* + ID_PRODUCT_FROM_DATABASE=Mini DigitalTV + +usb:v06E1pA701* + ID_PRODUCT_FROM_DATABASE=DVD Xpress + +usb:v06E1pA708* + ID_PRODUCT_FROM_DATABASE=saa7114H video input card (Instant VideoMPX) + +usb:v06E1pB337* + ID_PRODUCT_FROM_DATABASE=Mini DigitalTV + +usb:v06E1pB701* + ID_PRODUCT_FROM_DATABASE=DVD Xpress B + +usb:v06E4* + ID_VENDOR_FROM_DATABASE=Alcatel Microelectronics + +usb:v06E6* + ID_VENDOR_FROM_DATABASE=Tiger Jet Network, Inc. + +usb:v06E6p0200* + ID_PRODUCT_FROM_DATABASE=Internet Phone + +usb:v06E6p0201* + ID_PRODUCT_FROM_DATABASE=Internet Phone + +usb:v06E6p0202* + ID_PRODUCT_FROM_DATABASE=Composite Device + +usb:v06E6p0203* + ID_PRODUCT_FROM_DATABASE=Internet Phone + +usb:v06E6p0210* + ID_PRODUCT_FROM_DATABASE=Composite Device + +usb:v06E6p0211* + ID_PRODUCT_FROM_DATABASE=Internet Phone + +usb:v06E6p0212* + ID_PRODUCT_FROM_DATABASE=Internet Phone + +usb:v06E6p031C* + ID_PRODUCT_FROM_DATABASE=Internet Phone + +usb:v06E6p031D* + ID_PRODUCT_FROM_DATABASE=Internet Phone + +usb:v06E6p031E* + ID_PRODUCT_FROM_DATABASE=Internet Phone + +usb:v06E6p3200* + ID_PRODUCT_FROM_DATABASE=Composite Device + +usb:v06E6p3201* + ID_PRODUCT_FROM_DATABASE=Internet Phone + +usb:v06E6p3202* + ID_PRODUCT_FROM_DATABASE=Composite Device + +usb:v06E6p3203* + ID_PRODUCT_FROM_DATABASE=Composite Device + +usb:v06E6p7200* + ID_PRODUCT_FROM_DATABASE=Composite Device + +usb:v06E6p7210* + ID_PRODUCT_FROM_DATABASE=Composite Device + +usb:v06E6p7250* + ID_PRODUCT_FROM_DATABASE=Composite Device + +usb:v06E6p825C* + ID_PRODUCT_FROM_DATABASE=Internet Phone + +usb:v06E6p831C* + ID_PRODUCT_FROM_DATABASE=Internet Phone + +usb:v06E6p831D* + ID_PRODUCT_FROM_DATABASE=Composite Device + +usb:v06E6p831E* + ID_PRODUCT_FROM_DATABASE=Composite Device + +usb:v06E6pB200* + ID_PRODUCT_FROM_DATABASE=Composite Device + +usb:v06E6pB201* + ID_PRODUCT_FROM_DATABASE=Composite Device + +usb:v06E6pB202* + ID_PRODUCT_FROM_DATABASE=Internet Phone + +usb:v06E6pB210* + ID_PRODUCT_FROM_DATABASE=Internet Phone + +usb:v06E6pB211* + ID_PRODUCT_FROM_DATABASE=Composite Device + +usb:v06E6pB212* + ID_PRODUCT_FROM_DATABASE=Composite Device + +usb:v06E6pB250* + ID_PRODUCT_FROM_DATABASE=Composite Device + +usb:v06E6pB251* + ID_PRODUCT_FROM_DATABASE=Internet Phone + +usb:v06E6pB252* + ID_PRODUCT_FROM_DATABASE=Internet Phone + +usb:v06E6pC200* + ID_PRODUCT_FROM_DATABASE=Internet Phone + +usb:v06E6pC201* + ID_PRODUCT_FROM_DATABASE=Internet Phone + +usb:v06E6pC202* + ID_PRODUCT_FROM_DATABASE=Composite Device + +usb:v06E6pC203* + ID_PRODUCT_FROM_DATABASE=Internet Phone + +usb:v06E6pC210* + ID_PRODUCT_FROM_DATABASE=Personal PhoneGateway + +usb:v06E6pC211* + ID_PRODUCT_FROM_DATABASE=Personal PhoneGateway + +usb:v06E6pC212* + ID_PRODUCT_FROM_DATABASE=Personal PhoneGateway + +usb:v06E6pC213* + ID_PRODUCT_FROM_DATABASE=PPG Device + +usb:v06E6pC25C* + ID_PRODUCT_FROM_DATABASE=Composite Device + +usb:v06E6pC290* + ID_PRODUCT_FROM_DATABASE=PPG Device + +usb:v06E6pC291* + ID_PRODUCT_FROM_DATABASE=PPG Device + +usb:v06E6pC292* + ID_PRODUCT_FROM_DATABASE=PPG Device + +usb:v06E6pC293* + ID_PRODUCT_FROM_DATABASE=Personal PhoneGateway + +usb:v06E6pC31C* + ID_PRODUCT_FROM_DATABASE=Composite Device + +usb:v06E6pC39C* + ID_PRODUCT_FROM_DATABASE=Personal PhoneGateway + +usb:v06E6pC39D* + ID_PRODUCT_FROM_DATABASE=PPG Device + +usb:v06E6pC39E* + ID_PRODUCT_FROM_DATABASE=PPG Device + +usb:v06E6pC39F* + ID_PRODUCT_FROM_DATABASE=PPG Device + +usb:v06E6pC700* + ID_PRODUCT_FROM_DATABASE=Internet Phone + +usb:v06E6pC701* + ID_PRODUCT_FROM_DATABASE=Internet Phone + +usb:v06E6pC702* + ID_PRODUCT_FROM_DATABASE=Composite Device + +usb:v06E6pC703* + ID_PRODUCT_FROM_DATABASE=Internet Phone + +usb:v06E6pC710* + ID_PRODUCT_FROM_DATABASE=VoIP Combo Device + +usb:v06E6pC711* + ID_PRODUCT_FROM_DATABASE=VoIP Combo + +usb:v06E6pC712* + ID_PRODUCT_FROM_DATABASE=VoIP Combo Device + +usb:v06E6pC713* + ID_PRODUCT_FROM_DATABASE=VoIP Combo Device + +usb:v06E6pCF00* + ID_PRODUCT_FROM_DATABASE=Composite Device + +usb:v06E6pCF01* + ID_PRODUCT_FROM_DATABASE=Internet Phone + +usb:v06E6pCF02* + ID_PRODUCT_FROM_DATABASE=Internet Phone + +usb:v06E6pCF03* + ID_PRODUCT_FROM_DATABASE=Composite Device + +usb:v06E6pD210* + ID_PRODUCT_FROM_DATABASE=Personal PhoneGateway + +usb:v06E6pD211* + ID_PRODUCT_FROM_DATABASE=PPG Device + +usb:v06E6pD212* + ID_PRODUCT_FROM_DATABASE=PPG Device + +usb:v06E6pD213* + ID_PRODUCT_FROM_DATABASE=Personal PhoneGateway + +usb:v06E6pD700* + ID_PRODUCT_FROM_DATABASE=Composite Device + +usb:v06E6pD701* + ID_PRODUCT_FROM_DATABASE=Composite Device + +usb:v06E6pD702* + ID_PRODUCT_FROM_DATABASE=Internet Phone + +usb:v06E6pD703* + ID_PRODUCT_FROM_DATABASE=Composite Device + +usb:v06E6pD710* + ID_PRODUCT_FROM_DATABASE=VoIP Combo + +usb:v06E6pD711* + ID_PRODUCT_FROM_DATABASE=VoIP Combo Device + +usb:v06E6pD712* + ID_PRODUCT_FROM_DATABASE=VoIP Combo + +usb:v06E6pD713* + ID_PRODUCT_FROM_DATABASE=VoIP Combo + +usb:v06E6pDF00* + ID_PRODUCT_FROM_DATABASE=Composite Device + +usb:v06E6pDF01* + ID_PRODUCT_FROM_DATABASE=Composite Device + +usb:v06E6pDF02* + ID_PRODUCT_FROM_DATABASE=Internet Phone + +usb:v06E6pDF03* + ID_PRODUCT_FROM_DATABASE=Internet Phone + +usb:v06E6pF200* + ID_PRODUCT_FROM_DATABASE=Internet Phone + +usb:v06E6pF201* + ID_PRODUCT_FROM_DATABASE=Internet Phone + +usb:v06E6pF202* + ID_PRODUCT_FROM_DATABASE=Composite Device + +usb:v06E6pF203* + ID_PRODUCT_FROM_DATABASE=Composite Device + +usb:v06E6pF210* + ID_PRODUCT_FROM_DATABASE=Internet Phone + +usb:v06E6pF250* + ID_PRODUCT_FROM_DATABASE=Composite Device + +usb:v06E6pF252* + ID_PRODUCT_FROM_DATABASE=Internet Phone + +usb:v06E6pF310* + ID_PRODUCT_FROM_DATABASE=Internet Phone + +usb:v06E6pF350* + ID_PRODUCT_FROM_DATABASE=Composite Device + +usb:v06EA* + ID_VENDOR_FROM_DATABASE=Sirius Technologies + +usb:v06EAp0001* + ID_PRODUCT_FROM_DATABASE=NetCom Roadster II 56k + +usb:v06EAp0002* + ID_PRODUCT_FROM_DATABASE=Roadster II 56k + +usb:v06EB* + ID_VENDOR_FROM_DATABASE=PC Expert Tech. Co., Ltd + +usb:v06EF* + ID_VENDOR_FROM_DATABASE=I.A.C. Geometrische Ingenieurs B.V. + +usb:v06F0* + ID_VENDOR_FROM_DATABASE=T.N.C Industrial Co., Ltd + +usb:v06F0pDE01* + ID_PRODUCT_FROM_DATABASE=DualCam Video Camera + +usb:v06F0pDE02* + ID_PRODUCT_FROM_DATABASE=DualCam Still Camera + +usb:v06F1* + ID_VENDOR_FROM_DATABASE=Opcode Systems, Inc. + +usb:v06F1pA011* + ID_PRODUCT_FROM_DATABASE=SonicPort + +usb:v06F1pA021* + ID_PRODUCT_FROM_DATABASE=SonicPort Optical + +usb:v06F2* + ID_VENDOR_FROM_DATABASE=Emine Technology Co. + +usb:v06F2p0011* + ID_PRODUCT_FROM_DATABASE=KVM Switch Keyboard + +usb:v06F6* + ID_VENDOR_FROM_DATABASE=Wintrend Technology Co., Ltd + +usb:v06F7* + ID_VENDOR_FROM_DATABASE=Wailly Technology Ltd + +usb:v06F7p0003* + ID_PRODUCT_FROM_DATABASE=USB->Din 4 Adaptor + +usb:v06F8* + ID_VENDOR_FROM_DATABASE=Guillemot Corp. + +usb:v06F8p3002* + ID_PRODUCT_FROM_DATABASE=Hercules Blog Webcam + +usb:v06F8p3004* + ID_PRODUCT_FROM_DATABASE=Hercules Classic Silver + +usb:v06F8p3005* + ID_PRODUCT_FROM_DATABASE=Hercules Dualpix Exchange + +usb:v06F8p3007* + ID_PRODUCT_FROM_DATABASE=Hercules Dualpix Chat and Show + +usb:v06F8p3020* + ID_PRODUCT_FROM_DATABASE=Hercules Webcam EC300 + +usb:v06F8pA300* + ID_PRODUCT_FROM_DATABASE=Dual Analog Leader GamePad + +usb:v06F8pB000* + ID_PRODUCT_FROM_DATABASE=Hercules DJ Console + +usb:v06F8pC000* + ID_PRODUCT_FROM_DATABASE=Hercules Muse Pocket + +usb:v06F8pD002* + ID_PRODUCT_FROM_DATABASE=Hercules DJ Console + +usb:v06F8pE000* + ID_PRODUCT_FROM_DATABASE=HWGUSB2-54 WLAN + +usb:v06F8pE010* + ID_PRODUCT_FROM_DATABASE=HWGUSB2-54-LB + +usb:v06F8pE020* + ID_PRODUCT_FROM_DATABASE=HWGUSB2-54V2-AP + +usb:v06F8pE031* + ID_PRODUCT_FROM_DATABASE=Hercules HWNUm-300 Wireless N mini [Realtek RTL8191SU] + +usb:v06F8pE032* + ID_PRODUCT_FROM_DATABASE=HWGUm-54 [Hercules Wireless G Ultra Mini Key] + +usb:v06F8pE033* + ID_PRODUCT_FROM_DATABASE=Hercules HWNUp-150 802.11n Wireless N Pico [Realtek RTL8188CUS] + +usb:v06F9* + ID_VENDOR_FROM_DATABASE=ASYST electronic d.o.o. + +usb:v06FA* + ID_VENDOR_FROM_DATABASE=HSD S.r.L + +usb:v06FC* + ID_VENDOR_FROM_DATABASE=Motorola Semiconductor Products Sector + +usb:v06FD* + ID_VENDOR_FROM_DATABASE=Boston Acoustics + +usb:v06FDp0101* + ID_PRODUCT_FROM_DATABASE=Audio Device + +usb:v06FDp0102* + ID_PRODUCT_FROM_DATABASE=Audio Device + +usb:v06FDp0201* + ID_PRODUCT_FROM_DATABASE=2-piece Audio Device + +usb:v06FE* + ID_VENDOR_FROM_DATABASE=Gallant Computer, Inc. + +usb:v0701* + ID_VENDOR_FROM_DATABASE=Supercomal Wire & Cable SDN. BHD. + +usb:v0703* + ID_VENDOR_FROM_DATABASE=Bvtech Industry, Inc. + +usb:v0705* + ID_VENDOR_FROM_DATABASE=NKK Corp. + +usb:v0706* + ID_VENDOR_FROM_DATABASE=Ariel Corp. + +usb:v0707* + ID_VENDOR_FROM_DATABASE=Standard Microsystems Corp. + +usb:v0707p0100* + ID_PRODUCT_FROM_DATABASE=2202 Ethernet [klsi] + +usb:v0707p0200* + ID_PRODUCT_FROM_DATABASE=2202 Ethernet [pegasus] + +usb:v0707p0201* + ID_PRODUCT_FROM_DATABASE=EZ Connect USB Ethernet + +usb:v0707pEE04* + ID_PRODUCT_FROM_DATABASE=SMCWUSB32 802.11b Wireless LAN Card + +usb:v0707pEE06* + ID_PRODUCT_FROM_DATABASE=SMC2862W-G v1 EZ Connect 802.11g Adapter [Intersil ISL3886] + +usb:v0707pEE13* + ID_PRODUCT_FROM_DATABASE=SMC2862W-G v2 EZ Connect 802.11g Adapter [Intersil ISL3887] + +usb:v0708* + ID_VENDOR_FROM_DATABASE=Putercom Co., Ltd + +usb:v0708p047E* + ID_PRODUCT_FROM_DATABASE=USB-1284 BRIDGE + +usb:v0709* + ID_VENDOR_FROM_DATABASE=Silicon Systems, Ltd (SSL) + +usb:v070A* + ID_VENDOR_FROM_DATABASE=Oki Electric Industry Co., Ltd + +usb:v070Ap4002* + ID_PRODUCT_FROM_DATABASE=Bluetooth Device + +usb:v070Ap4003* + ID_PRODUCT_FROM_DATABASE=Bluetooth Device + +usb:v070D* + ID_VENDOR_FROM_DATABASE=Comoss Electronic Co., Ltd + +usb:v070E* + ID_VENDOR_FROM_DATABASE=Excel Cell Electronic Co., Ltd + +usb:v0710* + ID_VENDOR_FROM_DATABASE=Connect Tech, Inc. + +usb:v0710p0001* + ID_PRODUCT_FROM_DATABASE=WhiteHeat (fake ID) + +usb:v0710p8001* + ID_PRODUCT_FROM_DATABASE=WhiteHeat + +usb:v0711* + ID_VENDOR_FROM_DATABASE=Magic Control Technology Corp. + +usb:v0711p0100* + ID_PRODUCT_FROM_DATABASE=Hub + +usb:v0711p0180* + ID_PRODUCT_FROM_DATABASE=IRXpress Infrared Device + +usb:v0711p0181* + ID_PRODUCT_FROM_DATABASE=IRXpress Infrared Device + +usb:v0711p0200* + ID_PRODUCT_FROM_DATABASE=BAY-3U1S1P Serial Port + +usb:v0711p0210* + ID_PRODUCT_FROM_DATABASE=MCT1S Serial Port + +usb:v0711p0230* + ID_PRODUCT_FROM_DATABASE=MCT-232 Serial Port + +usb:v0711p0231* + ID_PRODUCT_FROM_DATABASE=PS/2 Mouse Port + +usb:v0711p0232* + ID_PRODUCT_FROM_DATABASE=Serial On Port + +usb:v0711p0240* + ID_PRODUCT_FROM_DATABASE=PS/2 to USB Converter + +usb:v0711p0300* + ID_PRODUCT_FROM_DATABASE=BAY-3U1S1P Parallel Port + +usb:v0711p0302* + ID_PRODUCT_FROM_DATABASE=Parallel Port + +usb:v0711p0900* + ID_PRODUCT_FROM_DATABASE=SVGA Adapter + +usb:v0711p5001* + ID_PRODUCT_FROM_DATABASE=Trigger UV-002BD[Startech USBVGAE] + +usb:v0711p5100* + ID_PRODUCT_FROM_DATABASE=Magic Control Technology Corp. (USB2VGA dongle) + +usb:v0713* + ID_VENDOR_FROM_DATABASE=Interval Research Corp. + +usb:v0714* + ID_VENDOR_FROM_DATABASE=NewMotion, Inc. + +usb:v0714p0003* + ID_PRODUCT_FROM_DATABASE=ADB to USB convertor + +usb:v0717* + ID_VENDOR_FROM_DATABASE=ZNK Corp. + +usb:v0718* + ID_VENDOR_FROM_DATABASE=Imation Corp. + +usb:v0718p0002* + ID_PRODUCT_FROM_DATABASE=SuperDisk 120MB + +usb:v0718p0003* + ID_PRODUCT_FROM_DATABASE=SuperDisk 120MB (Authenticated) + +usb:v0718p0060* + ID_PRODUCT_FROM_DATABASE=Flash Drive + +usb:v0718p0061* + ID_PRODUCT_FROM_DATABASE=Flash Drive + +usb:v0718p0062* + ID_PRODUCT_FROM_DATABASE=Flash Drive + +usb:v0718p0063* + ID_PRODUCT_FROM_DATABASE=Swivel Flash Drive + +usb:v0718p0064* + ID_PRODUCT_FROM_DATABASE=Flash Drive + +usb:v0718p0065* + ID_PRODUCT_FROM_DATABASE=Flash Drive + +usb:v0718p0066* + ID_PRODUCT_FROM_DATABASE=Flash Drive + +usb:v0718p0067* + ID_PRODUCT_FROM_DATABASE=Flash Drive + +usb:v0718p0068* + ID_PRODUCT_FROM_DATABASE=Flash Drive + +usb:v0718p0084* + ID_PRODUCT_FROM_DATABASE=Flash Drive Mini + +usb:v0718p043C* + ID_PRODUCT_FROM_DATABASE=Flash drive 16GB [Nano Pro] + +usb:v0718p0582* + ID_PRODUCT_FROM_DATABASE=Revo Flash Drive + +usb:v0718p1120* + ID_PRODUCT_FROM_DATABASE=RDX External dock (redbud) + +usb:v0718pD000* + ID_PRODUCT_FROM_DATABASE=Disc Stakka CD/DVD Manager + +usb:v0719* + ID_VENDOR_FROM_DATABASE=Tremon Enterprises Co., Ltd + +usb:v071B* + ID_VENDOR_FROM_DATABASE=Domain Technologies, Inc. + +usb:v071Bp0002* + ID_PRODUCT_FROM_DATABASE=DTI-56362-USB Digital Interface Unit + +usb:v071Bp0101* + ID_PRODUCT_FROM_DATABASE=Audio4-USB DSP Data Acquisition Unit + +usb:v071Bp0201* + ID_PRODUCT_FROM_DATABASE=Audio4-5410 DSP Data Acquisition Unit + +usb:v071Bp0301* + ID_PRODUCT_FROM_DATABASE=SB-USB JTAG Emulator + +usb:v071Bp3203* + ID_PRODUCT_FROM_DATABASE=Rockchip Media Player + +usb:v071Bp32BB* + ID_PRODUCT_FROM_DATABASE=Music Mediatouch + +usb:v071C* + ID_VENDOR_FROM_DATABASE=Xionics Document Technologies, Inc. + +usb:v071D* + ID_VENDOR_FROM_DATABASE=Eicon Networks Corp. + +usb:v071Dp1000* + ID_PRODUCT_FROM_DATABASE=Diva ISDN TA + +usb:v071Dp1003* + ID_PRODUCT_FROM_DATABASE=Diva + +usb:v071Dp2000* + ID_PRODUCT_FROM_DATABASE=Teledat Surf + +usb:v071E* + ID_VENDOR_FROM_DATABASE=Ariston Technologies + +usb:v0723* + ID_VENDOR_FROM_DATABASE=Centillium Communications Corp. + +usb:v0723p0002* + ID_PRODUCT_FROM_DATABASE=Palladia 300/400 Adsl Modem + +usb:v0726* + ID_VENDOR_FROM_DATABASE=Vanguard International Semiconductor-America + +usb:v0729* + ID_VENDOR_FROM_DATABASE=Amitm + +usb:v0729p1000* + ID_PRODUCT_FROM_DATABASE=USC-1000 Serial Port + +usb:v072E* + ID_VENDOR_FROM_DATABASE=Sunix Co., Ltd + +usb:v072F* + ID_VENDOR_FROM_DATABASE=Advanced Card Systems, Ltd + +usb:v072Fp0001* + ID_PRODUCT_FROM_DATABASE=AC1030-based SmartCard Reader + +usb:v072Fp0008* + ID_PRODUCT_FROM_DATABASE=ACR 80 Smart Card Reader + +usb:v072Fp1000* + ID_PRODUCT_FROM_DATABASE=PLDT Drive + +usb:v072Fp1001* + ID_PRODUCT_FROM_DATABASE=PLDT Drive + +usb:v072Fp8002* + ID_PRODUCT_FROM_DATABASE=AET63 BioTRUSTKey + +usb:v072Fp8003* + ID_PRODUCT_FROM_DATABASE=ACR120 + +usb:v072Fp8103* + ID_PRODUCT_FROM_DATABASE=ACR120 + +usb:v072Fp9000* + ID_PRODUCT_FROM_DATABASE=ACR38 AC1038-based Smart Card Reader + +usb:v072Fp90CC* + ID_PRODUCT_FROM_DATABASE=ACR38 SmartCard Reader + +usb:v072Fp90CF* + ID_PRODUCT_FROM_DATABASE=ACR38 SAM Smart Card Reader + +usb:v072Fp90D0* + ID_PRODUCT_FROM_DATABASE=PertoSmart EMV - Card Reader + +usb:v0731* + ID_VENDOR_FROM_DATABASE=Susteen, Inc. + +usb:v0731p0528* + ID_PRODUCT_FROM_DATABASE=SonyEricsson DCU-11 Cable + +usb:v0732* + ID_VENDOR_FROM_DATABASE=Goldfull Electronics & Telecommunications Corp. + +usb:v0733* + ID_VENDOR_FROM_DATABASE=ViewQuest Technologies, Inc. + +usb:v0733p0101* + ID_PRODUCT_FROM_DATABASE=Digital Video Camera + +usb:v0733p0110* + ID_PRODUCT_FROM_DATABASE=VQ110 Video Camera + +usb:v0733p0401* + ID_PRODUCT_FROM_DATABASE=CS330 Webcam + +usb:v0733p0402* + ID_PRODUCT_FROM_DATABASE=M-318B Webcam + +usb:v0733p0430* + ID_PRODUCT_FROM_DATABASE=Intel Pro Share Webcam + +usb:v0733p0630* + ID_PRODUCT_FROM_DATABASE=VQ630 Dual Mode Digital Camera(Bulk) + +usb:v0733p0631* + ID_PRODUCT_FROM_DATABASE=Hercules Dualpix + +usb:v0733p0780* + ID_PRODUCT_FROM_DATABASE=Smart Cam Deluxe(composite) + +usb:v0733p1310* + ID_PRODUCT_FROM_DATABASE=Epsilon 1.3/Jenoptik JD C1.3/UMAX AstraPix 470 + +usb:v0733p1311* + ID_PRODUCT_FROM_DATABASE=Digital Dream Epsilon 1.3 + +usb:v0733p1314* + ID_PRODUCT_FROM_DATABASE=Mercury 2.1MEG Deluxe Classic Cam + +usb:v0733p2211* + ID_PRODUCT_FROM_DATABASE=Jenoptik jdc 21 LCD Camera + +usb:v0733p2221* + ID_PRODUCT_FROM_DATABASE=Mercury Digital Pro 3.1p + +usb:v0733p3261* + ID_PRODUCT_FROM_DATABASE=Concord 3045 spca536a Camera + +usb:v0733p3281* + ID_PRODUCT_FROM_DATABASE=Cyberpix S550V + +usb:v0734* + ID_VENDOR_FROM_DATABASE=Lasat Communications A/S + +usb:v0734p0001* + ID_PRODUCT_FROM_DATABASE=560V Modem + +usb:v0734p0002* + ID_PRODUCT_FROM_DATABASE=Lasat 560V Modem + +usb:v0734p043A* + ID_PRODUCT_FROM_DATABASE=DVS Audio + +usb:v0734p043B* + ID_PRODUCT_FROM_DATABASE=3DeMon USB Capture + +usb:v0735* + ID_VENDOR_FROM_DATABASE=Asuscom Network + +usb:v0735p2100* + ID_PRODUCT_FROM_DATABASE=ISDN Adapter + +usb:v0735p2101* + ID_PRODUCT_FROM_DATABASE=ISDN Adapter + +usb:v0735p6694* + ID_PRODUCT_FROM_DATABASE=ISDNlink 128K + +usb:v0735pC541* + ID_PRODUCT_FROM_DATABASE=ISDN TA 280 + +usb:v0736* + ID_VENDOR_FROM_DATABASE=Lorom Industrial Co., Ltd + +usb:v0738* + ID_VENDOR_FROM_DATABASE=Mad Catz, Inc. + +usb:v0738p4507* + ID_PRODUCT_FROM_DATABASE=XBox Device + +usb:v0738p4516* + ID_PRODUCT_FROM_DATABASE=XBox Device + +usb:v0738p4520* + ID_PRODUCT_FROM_DATABASE=XBox Device + +usb:v0738p4526* + ID_PRODUCT_FROM_DATABASE=XBox Device + +usb:v0738p4536* + ID_PRODUCT_FROM_DATABASE=XBox Device + +usb:v0738p4540* + ID_PRODUCT_FROM_DATABASE=XBox Device + +usb:v0738p4556* + ID_PRODUCT_FROM_DATABASE=XBox Device + +usb:v0738p4566* + ID_PRODUCT_FROM_DATABASE=XBox Device + +usb:v0738p4576* + ID_PRODUCT_FROM_DATABASE=XBox Device + +usb:v0738p4586* + ID_PRODUCT_FROM_DATABASE=XBox Device + +usb:v0738p4588* + ID_PRODUCT_FROM_DATABASE=XBox Device + +usb:v0738p8818* + ID_PRODUCT_FROM_DATABASE=Street Fighter IV Arcade FightStick (PS3) + +usb:v073A* + ID_VENDOR_FROM_DATABASE=Chaplet Systems, Inc. + +usb:v073Ap2230* + ID_PRODUCT_FROM_DATABASE=infrared dongle for remote + +usb:v073B* + ID_VENDOR_FROM_DATABASE=Suncom Technologies + +usb:v073C* + ID_VENDOR_FROM_DATABASE=Industrial Electronic Engineers, Inc. + +usb:v073Cp0305* + ID_PRODUCT_FROM_DATABASE=Pole Display (PC305-3415 2 x 20 Line Display) + +usb:v073Cp0322* + ID_PRODUCT_FROM_DATABASE=Pole Display (PC322-3415 2 x 20 Line Display) + +usb:v073Cp0324* + ID_PRODUCT_FROM_DATABASE=Pole Display (LB324-USB 4 x 20 Line Display) + +usb:v073Cp0330* + ID_PRODUCT_FROM_DATABASE=Pole Display (P330-3415 2 x 20 Line Display) + +usb:v073Cp0424* + ID_PRODUCT_FROM_DATABASE=Pole Display (SP324-4415 4 x 20 Line Display) + +usb:v073Cp0450* + ID_PRODUCT_FROM_DATABASE=Pole Display (L450-USB Graphic Line Display) + +usb:v073Cp0505* + ID_PRODUCT_FROM_DATABASE=Pole Display (SPC505-3415 2 x 20 Line Display) + +usb:v073Cp0522* + ID_PRODUCT_FROM_DATABASE=Pole Display (SPC522-3415 2 x 20 Line Display) + +usb:v073Cp0624* + ID_PRODUCT_FROM_DATABASE=Pole Display (SP324-3415 4 x 20 Line Display) + +usb:v073D* + ID_VENDOR_FROM_DATABASE=Eutron S.p.a. + +usb:v073Dp0005* + ID_PRODUCT_FROM_DATABASE=Crypto Token + +usb:v073Dp0007* + ID_PRODUCT_FROM_DATABASE=CryptoIdentity CCID + +usb:v073Dp0025* + ID_PRODUCT_FROM_DATABASE=SmartKey 3 + +usb:v073Dp0C00* + ID_PRODUCT_FROM_DATABASE=Pocket Reader + +usb:v073Dp0D00* + ID_PRODUCT_FROM_DATABASE=StarSign Bio Token 3.0 EU + +usb:v073E* + ID_VENDOR_FROM_DATABASE=NEC, Inc. + +usb:v073Ep0301* + ID_PRODUCT_FROM_DATABASE=Game Pad + +usb:v0745* + ID_VENDOR_FROM_DATABASE=Syntech Information Co., Ltd + +usb:v0746* + ID_VENDOR_FROM_DATABASE=Onkyo Corp. + +usb:v0746p5500* + ID_PRODUCT_FROM_DATABASE=SE-U55 Audio Device + +usb:v0747* + ID_VENDOR_FROM_DATABASE=Labway Corp. + +usb:v0748* + ID_VENDOR_FROM_DATABASE=Strong Man Enterprise Co., Ltd + +usb:v0749* + ID_VENDOR_FROM_DATABASE=EVer Electronics Corp. + +usb:v074A* + ID_VENDOR_FROM_DATABASE=Ming Fortune Industry Co., Ltd + +usb:v074B* + ID_VENDOR_FROM_DATABASE=Polestar Tech. Corp. + +usb:v074C* + ID_VENDOR_FROM_DATABASE=C-C-C Group PLC + +usb:v074D* + ID_VENDOR_FROM_DATABASE=Micronas GmbH + +usb:v074Dp3553* + ID_PRODUCT_FROM_DATABASE=Composite USB-Device + +usb:v074Dp3554* + ID_PRODUCT_FROM_DATABASE=Composite USB-Device + +usb:v074Dp3556* + ID_PRODUCT_FROM_DATABASE=Composite USB-Device + +usb:v074E* + ID_VENDOR_FROM_DATABASE=Digital Stream Corp. + +usb:v074Ep0001* + ID_PRODUCT_FROM_DATABASE=PS/2 Adapter + +usb:v074Ep0002* + ID_PRODUCT_FROM_DATABASE=PS/2 Adapter + +usb:v0755* + ID_VENDOR_FROM_DATABASE=Aureal Semiconductor + +usb:v0757* + ID_VENDOR_FROM_DATABASE=Network Technologies, Inc. + +usb:v075B* + ID_VENDOR_FROM_DATABASE=Sophisticated Circuits, Inc. + +usb:v075Bp0001* + ID_PRODUCT_FROM_DATABASE=Kick-off! Watchdog + +usb:v0763* + ID_VENDOR_FROM_DATABASE=Midiman + +usb:v0763p0115* + ID_PRODUCT_FROM_DATABASE=O2 / KeyRig 25 + +usb:v0763p0117* + ID_PRODUCT_FROM_DATABASE=Trigger Finger + +usb:v0763p0119* + ID_PRODUCT_FROM_DATABASE=MidAir + +usb:v0763p0150* + ID_PRODUCT_FROM_DATABASE=M-Audio Uno + +usb:v0763p0160* + ID_PRODUCT_FROM_DATABASE=M-Audio 1x1 + +usb:v0763p0192* + ID_PRODUCT_FROM_DATABASE=M-Audio Keystation 88es + +usb:v0763p0193* + ID_PRODUCT_FROM_DATABASE=ProKeys 88 + +usb:v0763p0194* + ID_PRODUCT_FROM_DATABASE=ProKeys 88sx + +usb:v0763p0195* + ID_PRODUCT_FROM_DATABASE=Oxygen 8 v2 + +usb:v0763p0196* + ID_PRODUCT_FROM_DATABASE=Oxygen 49 + +usb:v0763p0197* + ID_PRODUCT_FROM_DATABASE=Oxygen 61 + +usb:v0763p0198* + ID_PRODUCT_FROM_DATABASE=Axiom 25 + +usb:v0763p0199* + ID_PRODUCT_FROM_DATABASE=Axiom 49 + +usb:v0763p019A* + ID_PRODUCT_FROM_DATABASE=Axiom 61 + +usb:v0763p019B* + ID_PRODUCT_FROM_DATABASE=KeyRig 49 + +usb:v0763p019C* + ID_PRODUCT_FROM_DATABASE=KeyStudio + +usb:v0763p1001* + ID_PRODUCT_FROM_DATABASE=MidiSport 2x2 + +usb:v0763p1002* + ID_PRODUCT_FROM_DATABASE=MidiSport 2x2 + +usb:v0763p1003* + ID_PRODUCT_FROM_DATABASE=MidiSport 2x2 + +usb:v0763p1010* + ID_PRODUCT_FROM_DATABASE=MidiSport 1x1 + +usb:v0763p1011* + ID_PRODUCT_FROM_DATABASE=MidiSport 1x1 + +usb:v0763p1014* + ID_PRODUCT_FROM_DATABASE=M-Audio Keystation Loader + +usb:v0763p1015* + ID_PRODUCT_FROM_DATABASE=M-Audio Keystation + +usb:v0763p1020* + ID_PRODUCT_FROM_DATABASE=Midisport 4x4 + +usb:v0763p1021* + ID_PRODUCT_FROM_DATABASE=MidiSport 4x4 + +usb:v0763p1030* + ID_PRODUCT_FROM_DATABASE=Midisport 8x8 + +usb:v0763p1031* + ID_PRODUCT_FROM_DATABASE=MidiSport 8x8/s Loader + +usb:v0763p1033* + ID_PRODUCT_FROM_DATABASE=MidiSport 8x8/s + +usb:v0763p1040* + ID_PRODUCT_FROM_DATABASE=M-Audio MidiSport 2x4 Loader + +usb:v0763p1041* + ID_PRODUCT_FROM_DATABASE=M-Audio MidiSport 2x4 + +usb:v0763p1110* + ID_PRODUCT_FROM_DATABASE=MidiSport 1x1 + +usb:v0763p2001* + ID_PRODUCT_FROM_DATABASE=M Audio Quattro + +usb:v0763p2002* + ID_PRODUCT_FROM_DATABASE=M Audio Duo + +usb:v0763p2003* + ID_PRODUCT_FROM_DATABASE=M Audio AudioPhile + +usb:v0763p2004* + ID_PRODUCT_FROM_DATABASE=M-Audio MobilePre + +usb:v0763p2006* + ID_PRODUCT_FROM_DATABASE=M-Audio Transit + +usb:v0763p2007* + ID_PRODUCT_FROM_DATABASE=M-Audio Sonica Theater + +usb:v0763p2008* + ID_PRODUCT_FROM_DATABASE=M-Audio Ozone + +usb:v0763p200D* + ID_PRODUCT_FROM_DATABASE=M-Audio OmniStudio + +usb:v0763p200F* + ID_PRODUCT_FROM_DATABASE=M-Audio MobilePre + +usb:v0763p2010* + ID_PRODUCT_FROM_DATABASE=M-Audio Fast Track + +usb:v0763p2012* + ID_PRODUCT_FROM_DATABASE=M-Audio Fast Track Pro + +usb:v0763p2013* + ID_PRODUCT_FROM_DATABASE=M-Audio JamLab + +usb:v0763p2015* + ID_PRODUCT_FROM_DATABASE=M-Audio RunTime DFU + +usb:v0763p2016* + ID_PRODUCT_FROM_DATABASE=M-Audio RunTime DFU + +usb:v0763p2019* + ID_PRODUCT_FROM_DATABASE=M-Audio Ozone Academic + +usb:v0763p201A* + ID_PRODUCT_FROM_DATABASE=M-Audio Micro + +usb:v0763p201B* + ID_PRODUCT_FROM_DATABASE=M-Audio RunTime DFU + +usb:v0763p201D* + ID_PRODUCT_FROM_DATABASE=M-Audio Producer + +usb:v0763p2024* + ID_PRODUCT_FROM_DATABASE=M-Audio Fast Track MKII + +usb:v0763p2080* + ID_PRODUCT_FROM_DATABASE=M-Audio RunTime DFU + +usb:v0763p2081* + ID_PRODUCT_FROM_DATABASE=M-Audio RunTime DFU / Fast Track Ultra 8R + +usb:v0763p2803* + ID_PRODUCT_FROM_DATABASE=M-Audio Audiophile DFU + +usb:v0763p2804* + ID_PRODUCT_FROM_DATABASE=M-Audio MobilePre DFU + +usb:v0763p2806* + ID_PRODUCT_FROM_DATABASE=M-Audio Transit DFU + +usb:v0763p2815* + ID_PRODUCT_FROM_DATABASE=M-Audio DFU + +usb:v0763p2816* + ID_PRODUCT_FROM_DATABASE=M-Audio DFU + +usb:v0763p281B* + ID_PRODUCT_FROM_DATABASE=M-Audio DFU + +usb:v0763p2880* + ID_PRODUCT_FROM_DATABASE=M-Audio DFU + +usb:v0763p2881* + ID_PRODUCT_FROM_DATABASE=M-Audio DFU + +usb:v0764* + ID_VENDOR_FROM_DATABASE=Cyber Power System, Inc. + +usb:v0764p0005* + ID_PRODUCT_FROM_DATABASE=Cyber Power UPS + +usb:v0764p0501* + ID_PRODUCT_FROM_DATABASE=CP1500 AVR UPS + +usb:v0765* + ID_VENDOR_FROM_DATABASE=X-Rite, Inc. + +usb:v0765p5001* + ID_PRODUCT_FROM_DATABASE=Huey PRO Colorimeter + +usb:v0765pD094* + ID_PRODUCT_FROM_DATABASE=X-Rite DTP94 [Quato Silver Haze Pro] + +usb:v0766* + ID_VENDOR_FROM_DATABASE=Jess-Link Products Co., Ltd + +usb:v0766p001B* + ID_PRODUCT_FROM_DATABASE=Packard Bell Go + +usb:v0766p0204* + ID_PRODUCT_FROM_DATABASE=TopSpeed Cyberlink Remote Control + +usb:v0767* + ID_VENDOR_FROM_DATABASE=Tokheim Corp. + +usb:v0768* + ID_VENDOR_FROM_DATABASE=Camtel Technology Corp. + +usb:v0768p0006* + ID_PRODUCT_FROM_DATABASE=Camtel Technology USB TV Genie Pro FM Model TVB330 + +usb:v0768p0023* + ID_PRODUCT_FROM_DATABASE=eHome Infrared Receiver + +usb:v0769* + ID_VENDOR_FROM_DATABASE=Surecom Technology Corp. + +usb:v0769p11F2* + ID_PRODUCT_FROM_DATABASE=EP-9001-g 802.11g 54M WLAN Adapter + +usb:v0769p11F3* + ID_PRODUCT_FROM_DATABASE=RT2570 + +usb:v0769p11F7* + ID_PRODUCT_FROM_DATABASE=802.11g 54M WLAN Adapter + +usb:v0769p31F3* + ID_PRODUCT_FROM_DATABASE=RT2573 + +usb:v076A* + ID_VENDOR_FROM_DATABASE=Smart Technology Enablers, Inc. + +usb:v076B* + ID_VENDOR_FROM_DATABASE=OmniKey AG + +usb:v076Bp0596* + ID_PRODUCT_FROM_DATABASE=CardMan 2020 + +usb:v076Bp1021* + ID_PRODUCT_FROM_DATABASE=CardMan 1021 + +usb:v076Bp1221* + ID_PRODUCT_FROM_DATABASE=CardMan 1221 + +usb:v076Bp1784* + ID_PRODUCT_FROM_DATABASE=CardMan 6020 + +usb:v076Bp3021* + ID_PRODUCT_FROM_DATABASE=CardMan 3121 + +usb:v076Bp3610* + ID_PRODUCT_FROM_DATABASE=CardMan 3620 + +usb:v076Bp3621* + ID_PRODUCT_FROM_DATABASE=CardMan 3621 + +usb:v076Bp3821* + ID_PRODUCT_FROM_DATABASE=CardMan 3821 + +usb:v076Bp4321* + ID_PRODUCT_FROM_DATABASE=CardMan 4321 + +usb:v076Bp5121* + ID_PRODUCT_FROM_DATABASE=CardMan 5121 + +usb:v076Bp5125* + ID_PRODUCT_FROM_DATABASE=CardMan 5125 + +usb:v076Bp6622* + ID_PRODUCT_FROM_DATABASE=CardMan 6121 + +usb:v076BpA011* + ID_PRODUCT_FROM_DATABASE=CCID Smart Card Reader Keyboard + +usb:v076BpA021* + ID_PRODUCT_FROM_DATABASE=CCID Smart Card Reader + +usb:v076BpA022* + ID_PRODUCT_FROM_DATABASE=CardMan Smart@Link + +usb:v076BpC000* + ID_PRODUCT_FROM_DATABASE=CardMan 3x21 CS + +usb:v076BpC001* + ID_PRODUCT_FROM_DATABASE=CardMan 5121 CS + +usb:v076C* + ID_VENDOR_FROM_DATABASE=Partner Tech + +usb:v076D* + ID_VENDOR_FROM_DATABASE=Denso Corp. + +usb:v076E* + ID_VENDOR_FROM_DATABASE=Kuan Tech Enterprise Co., Ltd + +usb:v076F* + ID_VENDOR_FROM_DATABASE=Jhen Vei Electronic Co., Ltd + +usb:v0770* + ID_VENDOR_FROM_DATABASE=Welch Allyn, Inc - Medical Division + +usb:v0771* + ID_VENDOR_FROM_DATABASE=Observator Instruments BV + +usb:v0771p4455* + ID_PRODUCT_FROM_DATABASE=OMC45III + +usb:v0771pAE0F* + ID_PRODUCT_FROM_DATABASE=OMC45III + +usb:v0772* + ID_VENDOR_FROM_DATABASE=Your data Our Care + +usb:v0774* + ID_VENDOR_FROM_DATABASE=AmTRAN Technology Co., Ltd + +usb:v0775* + ID_VENDOR_FROM_DATABASE=Longshine Electronics Corp. + +usb:v0776* + ID_VENDOR_FROM_DATABASE=Inalways Corp. + +usb:v0777* + ID_VENDOR_FROM_DATABASE=Comda Enterprise Corp. + +usb:v0778* + ID_VENDOR_FROM_DATABASE=Volex, Inc. + +usb:v0779* + ID_VENDOR_FROM_DATABASE=Fairchild Semiconductor + +usb:v077A* + ID_VENDOR_FROM_DATABASE=Sankyo Seiki Mfg. Co., Ltd + +usb:v077B* + ID_VENDOR_FROM_DATABASE=Linksys + +usb:v077Bp08BE* + ID_PRODUCT_FROM_DATABASE=BEFCMU10 v4 Cable Modem + +usb:v077Bp2219* + ID_PRODUCT_FROM_DATABASE=WUSB11 V2.6 802.11b Adapter + +usb:v077Bp2226* + ID_PRODUCT_FROM_DATABASE=USB200M 100baseTX Adapter + +usb:v077Bp2227* + ID_PRODUCT_FROM_DATABASE=Network Everywhere NWU11B + +usb:v077C* + ID_VENDOR_FROM_DATABASE=Forward Electronics Co., Ltd + +usb:v077Cp0005* + ID_PRODUCT_FROM_DATABASE=NEC Keyboard + +usb:v077D* + ID_VENDOR_FROM_DATABASE=Griffin Technology + +usb:v077Dp0223* + ID_PRODUCT_FROM_DATABASE=IMic Audio In/Out + +usb:v077Dp0405* + ID_PRODUCT_FROM_DATABASE=iMate, ADB Adapter + +usb:v077Dp0410* + ID_PRODUCT_FROM_DATABASE=PowerMate + +usb:v077Dp041A* + ID_PRODUCT_FROM_DATABASE=PowerWave + +usb:v077Dp04AA* + ID_PRODUCT_FROM_DATABASE=SoundKnob + +usb:v077Dp07AF* + ID_PRODUCT_FROM_DATABASE=iMic + +usb:v077Dp1016* + ID_PRODUCT_FROM_DATABASE=AirClick + +usb:v077Dp627A* + ID_PRODUCT_FROM_DATABASE=Radio SHARK + +usb:v077F* + ID_VENDOR_FROM_DATABASE=Well Excellent & Most Corp. + +usb:v0780* + ID_VENDOR_FROM_DATABASE=Sagem Monetel GmbH + +usb:v0780p1202* + ID_PRODUCT_FROM_DATABASE=ORGA 900 Smart Card Terminal Virtual Com Port + +usb:v0780p1302* + ID_PRODUCT_FROM_DATABASE=ORGA 6000 Smart Card Terminal Virtual Com Port + +usb:v0780p1303* + ID_PRODUCT_FROM_DATABASE=ORGA 6000 Smart Card Terminal USB RNDIS + +usb:v0780pDF55* + ID_PRODUCT_FROM_DATABASE=ORGA 900/6000 Smart Card Terminal DFU + +usb:v0781* + ID_VENDOR_FROM_DATABASE=SanDisk Corp. + +usb:v0781p0001* + ID_PRODUCT_FROM_DATABASE=SDDR-05a ImageMate CompactFlash Reader + +usb:v0781p0002* + ID_PRODUCT_FROM_DATABASE=SDDR-31 ImageMate II CompactFlash Reader + +usb:v0781p0005* + ID_PRODUCT_FROM_DATABASE=SDDR-05b (CF II) ImageMate CompactFlash Reader + +usb:v0781p0100* + ID_PRODUCT_FROM_DATABASE=ImageMate SDDR-12 + +usb:v0781p0200* + ID_PRODUCT_FROM_DATABASE=SDDR-09 (SSFDC) ImageMate SmartMedia Reader [eusb] + +usb:v0781p0400* + ID_PRODUCT_FROM_DATABASE=SecureMate SD/MMC Reader + +usb:v0781p0621* + ID_PRODUCT_FROM_DATABASE=SDDR-86 Imagemate 6-in-1 Reader + +usb:v0781p0720* + ID_PRODUCT_FROM_DATABASE=Sansa C200 series in recovery mode + +usb:v0781p0729* + ID_PRODUCT_FROM_DATABASE=Sansa E200 series in recovery mode + +usb:v0781p0810* + ID_PRODUCT_FROM_DATABASE=SDDR-75 ImageMate CF-SM Reader + +usb:v0781p0830* + ID_PRODUCT_FROM_DATABASE=ImageMate CF/MMC/SD Reader + +usb:v0781p1234* + ID_PRODUCT_FROM_DATABASE=Cruzer Mini Flash Drive + +usb:v0781p5150* + ID_PRODUCT_FROM_DATABASE=SDCZ2 Cruzer Mini Flash Drive (thin) + +usb:v0781p5151* + ID_PRODUCT_FROM_DATABASE=Cruzer Micro Flash Drive + +usb:v0781p5153* + ID_PRODUCT_FROM_DATABASE=Cruzer Flash Drive + +usb:v0781p5204* + ID_PRODUCT_FROM_DATABASE=Cruzer Crossfire + +usb:v0781p5402* + ID_PRODUCT_FROM_DATABASE=U3 Cruzer Micro + +usb:v0781p5406* + ID_PRODUCT_FROM_DATABASE=Cruzer Micro U3 + +usb:v0781p5408* + ID_PRODUCT_FROM_DATABASE=Cruzer Titanium U3 + +usb:v0781p540E* + ID_PRODUCT_FROM_DATABASE=Cruzer Contour Flash Drive + +usb:v0781p5530* + ID_PRODUCT_FROM_DATABASE=Cruzer + +usb:v0781p5567* + ID_PRODUCT_FROM_DATABASE=Cruzer Blade + +usb:v0781p5571* + ID_PRODUCT_FROM_DATABASE=Cruzer Fit + +usb:v0781p5E10* + ID_PRODUCT_FROM_DATABASE=Encrypted + +usb:v0781p6100* + ID_PRODUCT_FROM_DATABASE=Ultra II SD Plus 2GB + +usb:v0781p7100* + ID_PRODUCT_FROM_DATABASE=Cruzer Mini + +usb:v0781p7101* + ID_PRODUCT_FROM_DATABASE=Pen Flash + +usb:v0781p7102* + ID_PRODUCT_FROM_DATABASE=Cruzer Mini + +usb:v0781p7103* + ID_PRODUCT_FROM_DATABASE=Cruzer Mini + +usb:v0781p7104* + ID_PRODUCT_FROM_DATABASE=Cruzer Micro Mini 256MB Flash Drive + +usb:v0781p7105* + ID_PRODUCT_FROM_DATABASE=Cruzer Mini + +usb:v0781p7106* + ID_PRODUCT_FROM_DATABASE=Cruzer Mini + +usb:v0781p7112* + ID_PRODUCT_FROM_DATABASE=Cruzer Micro 128MB Flash Drive + +usb:v0781p7113* + ID_PRODUCT_FROM_DATABASE=Cruzer Micro 256MB Flash Drive + +usb:v0781p7114* + ID_PRODUCT_FROM_DATABASE=Cruzer Mini + +usb:v0781p7115* + ID_PRODUCT_FROM_DATABASE=Cruzer Mini + +usb:v0781p7301* + ID_PRODUCT_FROM_DATABASE=Sansa e100 series (mtp) + +usb:v0781p7302* + ID_PRODUCT_FROM_DATABASE=Sansa e100 series (msc) + +usb:v0781p7400* + ID_PRODUCT_FROM_DATABASE=Sansa M200 series (mtp) + +usb:v0781p7401* + ID_PRODUCT_FROM_DATABASE=Sansa M200 series (msc) + +usb:v0781p7420* + ID_PRODUCT_FROM_DATABASE=Sansa E200 series (mtp) + +usb:v0781p7421* + ID_PRODUCT_FROM_DATABASE=Sansa E200 Series (msc) + +usb:v0781p7422* + ID_PRODUCT_FROM_DATABASE=Sansa E200 series v2 (mtp) + +usb:v0781p7423* + ID_PRODUCT_FROM_DATABASE=Sansa E200 series v2 (msc) + +usb:v0781p7430* + ID_PRODUCT_FROM_DATABASE=Sansa M200 series + +usb:v0781p7431* + ID_PRODUCT_FROM_DATABASE=Sansa M200 series V4 (msc) + +usb:v0781p7432* + ID_PRODUCT_FROM_DATABASE=Sansa Clip (mtp) + +usb:v0781p7433* + ID_PRODUCT_FROM_DATABASE=Sansa Clip (msc) + +usb:v0781p7434* + ID_PRODUCT_FROM_DATABASE=Sansa Clip V2 (mtp) + +usb:v0781p7435* + ID_PRODUCT_FROM_DATABASE=Sansa Clip V2 (msc) + +usb:v0781p7450* + ID_PRODUCT_FROM_DATABASE=Sansa C250 + +usb:v0781p7451* + ID_PRODUCT_FROM_DATABASE=Sansa C240 + +usb:v0781p7460* + ID_PRODUCT_FROM_DATABASE=Sansa Express + +usb:v0781p7480* + ID_PRODUCT_FROM_DATABASE=Sansa Connect + +usb:v0781p7481* + ID_PRODUCT_FROM_DATABASE=Sansa Connect (in recovery mode) + +usb:v0781p74B0* + ID_PRODUCT_FROM_DATABASE=Sansa View (msc) + +usb:v0781p74B1* + ID_PRODUCT_FROM_DATABASE=Sansa View (mtp) + +usb:v0781p74C0* + ID_PRODUCT_FROM_DATABASE=Sansa Fuze (mtp) + +usb:v0781p74C1* + ID_PRODUCT_FROM_DATABASE=Sansa Fuze (msc) + +usb:v0781p74C2* + ID_PRODUCT_FROM_DATABASE=Sansa Fuze V2 (mtp) + +usb:v0781p74C3* + ID_PRODUCT_FROM_DATABASE=Sansa Fuze V2 (msc) + +usb:v0781p74D0* + ID_PRODUCT_FROM_DATABASE=Sansa Clip+ (mtp) + +usb:v0781p74D1* + ID_PRODUCT_FROM_DATABASE=Sansa Clip+ (msc) + +usb:v0781p8181* + ID_PRODUCT_FROM_DATABASE=Pen Flash + +usb:v0781p8183* + ID_PRODUCT_FROM_DATABASE=Hi-Speed Mass Storage Device + +usb:v0781p8185* + ID_PRODUCT_FROM_DATABASE=SDCZ2 Cruzer Mini Flash Drive (older, thick) + +usb:v0781p8888* + ID_PRODUCT_FROM_DATABASE=Card Reader + +usb:v0781p8889* + ID_PRODUCT_FROM_DATABASE=SDDR-88 Imagemate 8-in-1 Reader + +usb:v0781p8919* + ID_PRODUCT_FROM_DATABASE=Card Reader + +usb:v0781p8989* + ID_PRODUCT_FROM_DATABASE=ImageMate 12-in-1 Reader + +usb:v0781p9191* + ID_PRODUCT_FROM_DATABASE=ImageMate CF + +usb:v0781p9219* + ID_PRODUCT_FROM_DATABASE=Card Reader + +usb:v0781p9292* + ID_PRODUCT_FROM_DATABASE=ImageMate CF Reader/Writer + +usb:v0781p9393* + ID_PRODUCT_FROM_DATABASE=ImageMate SD-MMC + +usb:v0781p9595* + ID_PRODUCT_FROM_DATABASE=ImageMate xD-SM + +usb:v0781p9797* + ID_PRODUCT_FROM_DATABASE=ImageMate MS-PRO + +usb:v0781p9919* + ID_PRODUCT_FROM_DATABASE=Card Reader + +usb:v0781p9999* + ID_PRODUCT_FROM_DATABASE=SDDR-99 5-in-1 Reader + +usb:v0781pA7C1* + ID_PRODUCT_FROM_DATABASE=Storage device (SD card reader) + +usb:v0781pA7E8* + ID_PRODUCT_FROM_DATABASE=SDDR-113 MicroMate SDHC Reader + +usb:v0781pB2B3* + ID_PRODUCT_FROM_DATABASE=SDDR-103 MobileMate SD+ Reader + +usb:v0781pB4B5* + ID_PRODUCT_FROM_DATABASE=SDDR-89 V4 ImageMate 12-in-1 Reader + +usb:v0782* + ID_VENDOR_FROM_DATABASE=Trackerball + +usb:v0783* + ID_VENDOR_FROM_DATABASE=C3PO + +usb:v0783p0003* + ID_PRODUCT_FROM_DATABASE=LTC31 SmartCard Reader + +usb:v0783p0006* + ID_PRODUCT_FROM_DATABASE=LTC31v2 + +usb:v0783p0009* + ID_PRODUCT_FROM_DATABASE=KBR36 + +usb:v0783p0010* + ID_PRODUCT_FROM_DATABASE=LTC32 + +usb:v0784* + ID_VENDOR_FROM_DATABASE=Vivitar, Inc. + +usb:v0784p0100* + ID_PRODUCT_FROM_DATABASE=Vivicam 2655 + +usb:v0784p1310* + ID_PRODUCT_FROM_DATABASE=Vivicam 3305 + +usb:v0784p1688* + ID_PRODUCT_FROM_DATABASE=Vivicam 3665 + +usb:v0784p1689* + ID_PRODUCT_FROM_DATABASE=Gateway DC-M42/Labtec DC-505/Vivitar Vivicam 3705 + +usb:v0784p2620* + ID_PRODUCT_FROM_DATABASE=AOL Photocam Plus + +usb:v0784p2888* + ID_PRODUCT_FROM_DATABASE=Polaroid DC700 + +usb:v0784p3330* + ID_PRODUCT_FROM_DATABASE=Nytec ND-3200 Camera + +usb:v0784p4300* + ID_PRODUCT_FROM_DATABASE=Traveler D1 + +usb:v0784p5260* + ID_PRODUCT_FROM_DATABASE=Werlisa Sport PX 100 / JVC GC-A33 Camera + +usb:v0784p5300* + ID_PRODUCT_FROM_DATABASE=Pretec dc530 + +usb:v0785* + ID_VENDOR_FROM_DATABASE=NTT-ME + +usb:v0785p0001* + ID_PRODUCT_FROM_DATABASE=MN128mini-V ISDN TA + +usb:v0785p0003* + ID_PRODUCT_FROM_DATABASE=MN128mini-J ISDN TA + +usb:v0789* + ID_VENDOR_FROM_DATABASE=Logitec Corp. + +usb:v0789p0026* + ID_PRODUCT_FROM_DATABASE=LHD Device + +usb:v0789p0033* + ID_PRODUCT_FROM_DATABASE=DVD Multi-plus unit LDR-H443SU2 + +usb:v0789p0063* + ID_PRODUCT_FROM_DATABASE=LDR Device + +usb:v0789p0064* + ID_PRODUCT_FROM_DATABASE=LDR-R Device + +usb:v0789p00B3* + ID_PRODUCT_FROM_DATABASE=DVD Multi-plus unit LDR-H443U2 + +usb:v0789p0105* + ID_PRODUCT_FROM_DATABASE=LAN-TX/U1H2 10/100 Ethernet Adapter [pegasus II] + +usb:v0789p010C* + ID_PRODUCT_FROM_DATABASE=Realtek RTL8187 Wireless 802.11g 54Mbps Network Adapter + +usb:v0789p0160* + ID_PRODUCT_FROM_DATABASE=LAN-GTJ/U2A + +usb:v0789p0162* + ID_PRODUCT_FROM_DATABASE=LAN-WN22/U2 Wireless LAN Adapter + +usb:v0789p0163* + ID_PRODUCT_FROM_DATABASE=LAN-WN12/U2 Wireless LAN Adapter + +usb:v0789p0164* + ID_PRODUCT_FROM_DATABASE=LAN-W150/U2M Wireless LAN Adapter + +usb:v0789p0166* + ID_PRODUCT_FROM_DATABASE=LAN-W300N/U2 Wireless LAN Adapter + +usb:v0789p0168* + ID_PRODUCT_FROM_DATABASE=LAN-W150N/U2 Wireless LAN Adapter + +usb:v0789p0170* + ID_PRODUCT_FROM_DATABASE=LAN-W300AN/U2 Wireless LAN Adapter + +usb:v078B* + ID_VENDOR_FROM_DATABASE=Happ Controls, Inc. + +usb:v078Bp0010* + ID_PRODUCT_FROM_DATABASE=Driving UGCI + +usb:v078Bp0020* + ID_PRODUCT_FROM_DATABASE=Flying UGCI + +usb:v078Bp0030* + ID_PRODUCT_FROM_DATABASE=Fighting UGCI + +usb:v078C* + ID_VENDOR_FROM_DATABASE=GTCO/CalComp + +usb:v078Cp0090* + ID_PRODUCT_FROM_DATABASE=Tablet Adapter + +usb:v078Cp0100* + ID_PRODUCT_FROM_DATABASE=Tablet Adapter + +usb:v078Cp0200* + ID_PRODUCT_FROM_DATABASE=Tablet Adapter + +usb:v078Cp0300* + ID_PRODUCT_FROM_DATABASE=Tablet Adapter + +usb:v078Cp0400* + ID_PRODUCT_FROM_DATABASE=Digitizer (Whiteboard) + +usb:v078E* + ID_VENDOR_FROM_DATABASE=Brincom, Inc. + +usb:v0790* + ID_VENDOR_FROM_DATABASE=Pro-Image Manufacturing Co., Ltd + +usb:v0791* + ID_VENDOR_FROM_DATABASE=Copartner Wire and Cable Mfg. Corp. + +usb:v0792* + ID_VENDOR_FROM_DATABASE=Axis Communications AB + +usb:v0793* + ID_VENDOR_FROM_DATABASE=Wha Yu Industrial Co., Ltd + +usb:v0794* + ID_VENDOR_FROM_DATABASE=ABL Electronics Corp. + +usb:v0795* + ID_VENDOR_FROM_DATABASE=RealChip, Inc. + +usb:v0796* + ID_VENDOR_FROM_DATABASE=Certicom Corp. + +usb:v0797* + ID_VENDOR_FROM_DATABASE=Grandtech Semiconductor Corp. + +usb:v0797p6801* + ID_PRODUCT_FROM_DATABASE=Flatbed Scanner + +usb:v0797p6802* + ID_PRODUCT_FROM_DATABASE=InkJet Color Printer + +usb:v0797p8001* + ID_PRODUCT_FROM_DATABASE=SmartCam + +usb:v0797p801A* + ID_PRODUCT_FROM_DATABASE=Typhoon StyloCam + +usb:v0797p801C* + ID_PRODUCT_FROM_DATABASE=Meade Binoculars/Camera + +usb:v0797p8901* + ID_PRODUCT_FROM_DATABASE=ScanHex SX-35a + +usb:v0797p8909* + ID_PRODUCT_FROM_DATABASE=ScanHex SX-35b + +usb:v0797p8911* + ID_PRODUCT_FROM_DATABASE=ScanHex SX-35c + +usb:v0798* + ID_VENDOR_FROM_DATABASE=Optelec + +usb:v0798p0001* + ID_PRODUCT_FROM_DATABASE=Braille Voyager + +usb:v0799* + ID_VENDOR_FROM_DATABASE=Altera + +usb:v0799p7651* + ID_PRODUCT_FROM_DATABASE=Programming Unit + +usb:v079B* + ID_VENDOR_FROM_DATABASE=Sagem + +usb:v079Bp0027* + ID_PRODUCT_FROM_DATABASE=USB-Serial Controller + +usb:v079Bp002F* + ID_PRODUCT_FROM_DATABASE=Mobile + +usb:v079Bp0030* + ID_PRODUCT_FROM_DATABASE=Mobile Communication Device + +usb:v079Bp0042* + ID_PRODUCT_FROM_DATABASE=Mobile + +usb:v079Bp004A* + ID_PRODUCT_FROM_DATABASE=XG-760A 802.11bg + +usb:v079Bp004B* + ID_PRODUCT_FROM_DATABASE=Wi-Fi 11g adapter + +usb:v079Bp0056* + ID_PRODUCT_FROM_DATABASE=Agfa AP1100 Photo Printer + +usb:v079Bp005D* + ID_PRODUCT_FROM_DATABASE=Mobile Mass Storage + +usb:v079Bp0062* + ID_PRODUCT_FROM_DATABASE=XG-76NA 802.11bg + +usb:v079Bp0078* + ID_PRODUCT_FROM_DATABASE=Laser Pro Monochrome MFP + +usb:v079D* + ID_VENDOR_FROM_DATABASE=Alfadata Computer Corp. + +usb:v079Dp0201* + ID_PRODUCT_FROM_DATABASE=GamePort Adapter + +usb:v07A1* + ID_VENDOR_FROM_DATABASE=Digicom S.p.A. + +usb:v07A1pD952* + ID_PRODUCT_FROM_DATABASE=Palladio USB V.92 Modem + +usb:v07A2* + ID_VENDOR_FROM_DATABASE=National Technical Systems + +usb:v07A3* + ID_VENDOR_FROM_DATABASE=Onnto Corp. + +usb:v07A4* + ID_VENDOR_FROM_DATABASE=Be, Inc. + +usb:v07A6* + ID_VENDOR_FROM_DATABASE=ADMtek, Inc. + +usb:v07A6p07C2* + ID_PRODUCT_FROM_DATABASE=AN986A Ethernet + +usb:v07A6p0986* + ID_PRODUCT_FROM_DATABASE=AN986 Pegasus Ethernet + +usb:v07A6p8266* + ID_PRODUCT_FROM_DATABASE=Infineon WildCard-USB Wireless LAN Adapter + +usb:v07A6p8511* + ID_PRODUCT_FROM_DATABASE=ADM8511 Pegasus II Ethernet + +usb:v07A6p8513* + ID_PRODUCT_FROM_DATABASE=AN8513 Ethernet + +usb:v07A6p8515* + ID_PRODUCT_FROM_DATABASE=AN8515 Ethernet + +usb:v07AA* + ID_VENDOR_FROM_DATABASE=Corega K.K. + +usb:v07AAp0001* + ID_PRODUCT_FROM_DATABASE=Ether USB-T Ethernet [klsi] + +usb:v07AAp0004* + ID_PRODUCT_FROM_DATABASE=FEther USB-TX Ethernet [pegasus] + +usb:v07AAp000C* + ID_PRODUCT_FROM_DATABASE=WirelessLAN USB-11 + +usb:v07AAp000D* + ID_PRODUCT_FROM_DATABASE=FEther USB-TXS + +usb:v07AAp0011* + ID_PRODUCT_FROM_DATABASE=Wireless LAN USB-11 mini + +usb:v07AAp0012* + ID_PRODUCT_FROM_DATABASE=Stick-11 802.11b Adapter + +usb:v07AAp0017* + ID_PRODUCT_FROM_DATABASE=FEther USB2-TX + +usb:v07AAp0018* + ID_PRODUCT_FROM_DATABASE=Wireless LAN USB-11 mini 2 + +usb:v07AAp001A* + ID_PRODUCT_FROM_DATABASE=ULUSB-11 Key + +usb:v07AAp001C* + ID_PRODUCT_FROM_DATABASE=CG-WLUSB2GTST 802.11g Wireless Adapter [Intersil ISL3887] + +usb:v07AAp002E* + ID_PRODUCT_FROM_DATABASE=CG-WLUSB2GPX [Ralink RT2571W] + +usb:v07AAp002F* + ID_PRODUCT_FROM_DATABASE=CG-WLUSB2GNL + +usb:v07AAp0031* + ID_PRODUCT_FROM_DATABASE=CG-WLUSB2GS 802.11bg [Atheros AR5523] + +usb:v07AAp003C* + ID_PRODUCT_FROM_DATABASE=CG-WLUSB2GNL + +usb:v07AAp003F* + ID_PRODUCT_FROM_DATABASE=CG-WLUSB300AGN + +usb:v07AAp0041* + ID_PRODUCT_FROM_DATABASE=CG-WLUSB300GNS + +usb:v07AAp0042* + ID_PRODUCT_FROM_DATABASE=CG-WLUSB300GNM + +usb:v07AAp0043* + ID_PRODUCT_FROM_DATABASE=CG-WLUSB300N rev A2 [Realtek RTL8192U] + +usb:v07AAp0047* + ID_PRODUCT_FROM_DATABASE=CG-WLUSBNM + +usb:v07AAp0051* + ID_PRODUCT_FROM_DATABASE=CG-WLUSB300NM + +usb:v07AAp7613* + ID_PRODUCT_FROM_DATABASE=Stick-11 V2 802.11b Adapter + +usb:v07AAp9601* + ID_PRODUCT_FROM_DATABASE=FEther USB-TXC + +usb:v07AB* + ID_VENDOR_FROM_DATABASE=Freecom Technologies + +usb:v07ABpFC01* + ID_PRODUCT_FROM_DATABASE=IDE bridge + +usb:v07ABpFC02* + ID_PRODUCT_FROM_DATABASE=Cable II USB-2 + +usb:v07ABpFC03* + ID_PRODUCT_FROM_DATABASE=USB2-IDE IDE bridge + +usb:v07ABpFCD6* + ID_PRODUCT_FROM_DATABASE=Freecom HD Classic + +usb:v07ABpFCF6* + ID_PRODUCT_FROM_DATABASE=DataBar 512 MB + +usb:v07ABpFCF8* + ID_PRODUCT_FROM_DATABASE=Freecom Classic SL Network Drive + +usb:v07ABpFCFE* + ID_PRODUCT_FROM_DATABASE=Hard Drive 80GB + +usb:v07AF* + ID_VENDOR_FROM_DATABASE=Microtech + +usb:v07AFp0004* + ID_PRODUCT_FROM_DATABASE=SCSI-DB25 SCSI Bridge [shuttle] + +usb:v07AFp0005* + ID_PRODUCT_FROM_DATABASE=SCSI-HD50 SCSI Bridge [shuttle] + +usb:v07AFp0006* + ID_PRODUCT_FROM_DATABASE=CameraMate SmartMedia and CompactFlash Card Reader [eusb/shuttle] + +usb:v07AFpFC01* + ID_PRODUCT_FROM_DATABASE=Freecom USB-IDE + +usb:v07B0* + ID_VENDOR_FROM_DATABASE=Trust Technologies + +usb:v07B0p0001* + ID_PRODUCT_FROM_DATABASE=ISDN TA + +usb:v07B0p0002* + ID_PRODUCT_FROM_DATABASE=ISDN TA128 Plus + +usb:v07B0p0003* + ID_PRODUCT_FROM_DATABASE=ISDN TA128 Deluxe + +usb:v07B0p0005* + ID_PRODUCT_FROM_DATABASE=ISDN TA128 SE + +usb:v07B0p0006* + ID_PRODUCT_FROM_DATABASE=ISDN TA128 CE + +usb:v07B0p0007* + ID_PRODUCT_FROM_DATABASE=ISDN TA + +usb:v07B0p0008* + ID_PRODUCT_FROM_DATABASE=ISDN TA + +usb:v07B1* + ID_VENDOR_FROM_DATABASE=IMP, Inc. + +usb:v07B2* + ID_VENDOR_FROM_DATABASE=Motorola BCS, Inc. + +usb:v07B2p0100* + ID_PRODUCT_FROM_DATABASE=SURFboard Voice over IP Cable Modem + +usb:v07B2p0900* + ID_PRODUCT_FROM_DATABASE=SURFboard Gateway + +usb:v07B2p0950* + ID_PRODUCT_FROM_DATABASE=SURFboard SBG950 Gateway + +usb:v07B2p1000* + ID_PRODUCT_FROM_DATABASE=SURFboard SBG1000 Gateway + +usb:v07B2p4100* + ID_PRODUCT_FROM_DATABASE=SurfBoard SB4100 Cable Modem + +usb:v07B2p4200* + ID_PRODUCT_FROM_DATABASE=SurfBoard SB4200 Cable Modem + +usb:v07B2p4210* + ID_PRODUCT_FROM_DATABASE=SurfBoard 4210 Cable Modem + +usb:v07B2p4220* + ID_PRODUCT_FROM_DATABASE=SURFboard SB4220 Cable Modem + +usb:v07B2p4500* + ID_PRODUCT_FROM_DATABASE=CG4500 Communications Gateway + +usb:v07B2p450B* + ID_PRODUCT_FROM_DATABASE=CG4501 Communications Gateway + +usb:v07B2p450E* + ID_PRODUCT_FROM_DATABASE=CG4500E Communications Gateway + +usb:v07B2p5100* + ID_PRODUCT_FROM_DATABASE=SurfBoard SB5100 Cable Modem + +usb:v07B2p5101* + ID_PRODUCT_FROM_DATABASE=SurfBoard SB5101 Cable Modem + +usb:v07B2p5120* + ID_PRODUCT_FROM_DATABASE=SurfBoard SB5120 Cable Modem (RNDIS) + +usb:v07B2p5121* + ID_PRODUCT_FROM_DATABASE=Surfboard 5121 Cable Modem + +usb:v07B2p7030* + ID_PRODUCT_FROM_DATABASE=WU830G 802.11bg Wireless Adapter [Envara WiND512] + +usb:v07B3* + ID_VENDOR_FROM_DATABASE=Plustek, Inc. + +usb:v07B3p0001* + ID_PRODUCT_FROM_DATABASE=OpticPro 1212U Scanner + +usb:v07B3p0003* + ID_PRODUCT_FROM_DATABASE=Scanner + +usb:v07B3p0010* + ID_PRODUCT_FROM_DATABASE=OpticPro U12 Scanner + +usb:v07B3p0011* + ID_PRODUCT_FROM_DATABASE=OpticPro U24 Scanner + +usb:v07B3p0013* + ID_PRODUCT_FROM_DATABASE=OpticPro UT12 Scanner + +usb:v07B3p0014* + ID_PRODUCT_FROM_DATABASE=Scanner + +usb:v07B3p0015* + ID_PRODUCT_FROM_DATABASE=OpticPro U24 Scanner + +usb:v07B3p0017* + ID_PRODUCT_FROM_DATABASE=OpticPro UT12/16/24 Scanner + +usb:v07B3p0204* + ID_PRODUCT_FROM_DATABASE=Scanner + +usb:v07B3p0400* + ID_PRODUCT_FROM_DATABASE=OpticPro 1248U Scanner + +usb:v07B3p0401* + ID_PRODUCT_FROM_DATABASE=OpticPro 1248U Scanner #2 + +usb:v07B3p0403* + ID_PRODUCT_FROM_DATABASE=OpticPro U16B Scanner + +usb:v07B3p0404* + ID_PRODUCT_FROM_DATABASE=Scanner + +usb:v07B3p0405* + ID_PRODUCT_FROM_DATABASE=A8 Namecard-s Controller + +usb:v07B3p0406* + ID_PRODUCT_FROM_DATABASE=A8 Namecard-D Controller + +usb:v07B3p0410* + ID_PRODUCT_FROM_DATABASE=Scanner + +usb:v07B3p0412* + ID_PRODUCT_FROM_DATABASE=Scanner + +usb:v07B3p0413* + ID_PRODUCT_FROM_DATABASE=OpticSlim 1200 Scanner + +usb:v07B3p0601* + ID_PRODUCT_FROM_DATABASE=OpticPro ST24 Scanner + +usb:v07B3p0800* + ID_PRODUCT_FROM_DATABASE=OpticPro ST48 Scanner + +usb:v07B3p0906* + ID_PRODUCT_FROM_DATABASE=OpticBook 3600 Scanner + +usb:v07B3p0A06* + ID_PRODUCT_FROM_DATABASE=TVcam VD100 + +usb:v07B3p0B00* + ID_PRODUCT_FROM_DATABASE=SmartPhoto F50 + +usb:v07B3p0C03* + ID_PRODUCT_FROM_DATABASE=OpticPro ST64+ Scanner + +usb:v07B3p0C04* + ID_PRODUCT_FROM_DATABASE=Optic Film 7200i scanner + +usb:v07B3p0C0C* + ID_PRODUCT_FROM_DATABASE=PL806 Scanner + +usb:v07B3p0C26* + ID_PRODUCT_FROM_DATABASE=OpticBook 4600 Scanner + +usb:v07B3p0C2B* + ID_PRODUCT_FROM_DATABASE=Mobile Office D428 Scanner + +usb:v07B4* + ID_VENDOR_FROM_DATABASE=Olympus Optical Co., Ltd + +usb:v07B4p0100* + ID_PRODUCT_FROM_DATABASE=Camedia C-2100/C-3000 Ultra Zoom Camera + +usb:v07B4p0102* + ID_PRODUCT_FROM_DATABASE=Camedia E-10/C-220/C-50 Camera + +usb:v07B4p0105* + ID_PRODUCT_FROM_DATABASE=Camedia C-310Z/C-700/C-750UZ/C-755/C-765UZ/C-3040/C-4000/C-5050Z/D-560/C-3020Z Zoom Camera + +usb:v07B4p0109* + ID_PRODUCT_FROM_DATABASE=C-370Z/C-500Z/D-535Z/X-450 + +usb:v07B4p010A* + ID_PRODUCT_FROM_DATABASE=MAUSB-10 xD and SmartMedia Card Reader + +usb:v07B4p0112* + ID_PRODUCT_FROM_DATABASE=MAUSB-100 xD Card Reader + +usb:v07B4p0113* + ID_PRODUCT_FROM_DATABASE=Mju 500 + +usb:v07B4p0114* + ID_PRODUCT_FROM_DATABASE=C-350Z Camera + +usb:v07B4p0118* + ID_PRODUCT_FROM_DATABASE=Mju Mini Digital/Mju Digital 500 Camera / Stylus 850 SW + +usb:v07B4p0184* + ID_PRODUCT_FROM_DATABASE=P-S100 port + +usb:v07B4p0203* + ID_PRODUCT_FROM_DATABASE=Digital Voice Recorder DW-90 + +usb:v07B4p0206* + ID_PRODUCT_FROM_DATABASE=Digital Voice Recorder DS-330 + +usb:v07B4p0207* + ID_PRODUCT_FROM_DATABASE=Digital Voice Recorder & Camera W-10 + +usb:v07B4p0209* + ID_PRODUCT_FROM_DATABASE=Digital Voice Recorder DM-20 + +usb:v07B4p020D* + ID_PRODUCT_FROM_DATABASE=Digital Voice Recorder VN-240PC + +usb:v07B4p0244* + ID_PRODUCT_FROM_DATABASE=Digital Voice Recorder VN-8500PC + +usb:v07B4p0280* + ID_PRODUCT_FROM_DATABASE=m:robe 100 + +usb:v07B5* + ID_VENDOR_FROM_DATABASE=Mega World International, Ltd + +usb:v07B5p0017* + ID_PRODUCT_FROM_DATABASE=Joystick + +usb:v07B5p0213* + ID_PRODUCT_FROM_DATABASE=Thrustmaster Firestorm Digital 3 Gamepad + +usb:v07B5p0312* + ID_PRODUCT_FROM_DATABASE=Gamepad + +usb:v07B5p9902* + ID_PRODUCT_FROM_DATABASE=GamePad + +usb:v07B6* + ID_VENDOR_FROM_DATABASE=Marubun Corp. + +usb:v07B7* + ID_VENDOR_FROM_DATABASE=TIME Interconnect, Ltd + +usb:v07B8* + ID_VENDOR_FROM_DATABASE=AboCom Systems Inc + +usb:v07B8p110C* + ID_PRODUCT_FROM_DATABASE=XX1 + +usb:v07B8p1201* + ID_PRODUCT_FROM_DATABASE=IEEE 802.11b Adapter + +usb:v07B8p200C* + ID_PRODUCT_FROM_DATABASE=XX2 + +usb:v07B8p2573* + ID_PRODUCT_FROM_DATABASE=Wireless LAN Card + +usb:v07B8p2770* + ID_PRODUCT_FROM_DATABASE=802.11n/b/g Mini Wireless LAN USB2.0 Adapter + +usb:v07B8p2870* + ID_PRODUCT_FROM_DATABASE=802.11n/b/g Wireless LAN USB2.0 Adapter + +usb:v07B8p3070* + ID_PRODUCT_FROM_DATABASE=802.11n/b/g Mini Wireless LAN USB2.0 Adapter + +usb:v07B8p3071* + ID_PRODUCT_FROM_DATABASE=802.11n/b/g Mini Wireless LAN USB2.0 Adapter + +usb:v07B8p3072* + ID_PRODUCT_FROM_DATABASE=802.11n/b/g Mini Wireless LAN USB2.0 Adapter + +usb:v07B8p4000* + ID_PRODUCT_FROM_DATABASE=DU-E10 Ethernet [klsi] + +usb:v07B8p4002* + ID_PRODUCT_FROM_DATABASE=DU-E100 Ethernet [pegasus] + +usb:v07B8p4003* + ID_PRODUCT_FROM_DATABASE=1/10/100 Ethernet Adapter + +usb:v07B8p4004* + ID_PRODUCT_FROM_DATABASE=XX4 + +usb:v07B8p4007* + ID_PRODUCT_FROM_DATABASE=XX5 + +usb:v07B8p400B* + ID_PRODUCT_FROM_DATABASE=XX6 + +usb:v07B8p400C* + ID_PRODUCT_FROM_DATABASE=XX7 + +usb:v07B8p401A* + ID_PRODUCT_FROM_DATABASE=RTL8151 + +usb:v07B8p4102* + ID_PRODUCT_FROM_DATABASE=USB 1.1 10/100M Fast Ethernet Adapter + +usb:v07B8p4104* + ID_PRODUCT_FROM_DATABASE=XX9 + +usb:v07B8p420A* + ID_PRODUCT_FROM_DATABASE=UF200 Ethernet + +usb:v07B8p5301* + ID_PRODUCT_FROM_DATABASE=GW-US54ZGL 802.11bg + +usb:v07B8p6001* + ID_PRODUCT_FROM_DATABASE=802.11bg + +usb:v07B8pA001* + ID_PRODUCT_FROM_DATABASE=WUG2200 802.11g Wireless Adapter [Envara WiND512] + +usb:v07B8pABC1* + ID_PRODUCT_FROM_DATABASE=DU-E10 Ethernet [pegasus] + +usb:v07B8pB000* + ID_PRODUCT_FROM_DATABASE=BWU613 + +usb:v07B8pB02A* + ID_PRODUCT_FROM_DATABASE=AboCom Bluetooth Device + +usb:v07B8pB02B* + ID_PRODUCT_FROM_DATABASE=Bluetooth dongle + +usb:v07B8pB02C* + ID_PRODUCT_FROM_DATABASE=BCM92045DG-Flash with trace filter + +usb:v07B8pB02D* + ID_PRODUCT_FROM_DATABASE=BCM92045DG-Flash with trace filter + +usb:v07B8pB02E* + ID_PRODUCT_FROM_DATABASE=BCM92045DG-Flash with trace filter + +usb:v07B8pB030* + ID_PRODUCT_FROM_DATABASE=BCM92045DG-Flash with trace filter + +usb:v07B8pB031* + ID_PRODUCT_FROM_DATABASE=BCM92045DG-Flash with trace filter + +usb:v07B8pB032* + ID_PRODUCT_FROM_DATABASE=BCM92045DG-Flash with trace filter + +usb:v07B8pB033* + ID_PRODUCT_FROM_DATABASE=BCM92045DG-Flash with trace filter + +usb:v07B8pB21A* + ID_PRODUCT_FROM_DATABASE=WUG2400 802.11g Wireless Adapter [Texas Instruments TNETW1450] + +usb:v07B8pB21B* + ID_PRODUCT_FROM_DATABASE=HWU54DM + +usb:v07B8pB21C* + ID_PRODUCT_FROM_DATABASE=RT2573 + +usb:v07B8pB21D* + ID_PRODUCT_FROM_DATABASE=RT2573 + +usb:v07B8pB21E* + ID_PRODUCT_FROM_DATABASE=RT2573 + +usb:v07B8pB21F* + ID_PRODUCT_FROM_DATABASE=WUG2700 + +usb:v07B8pD011* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v07B8pE001* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v07B8pE002* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v07B8pE003* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v07B8pE004* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v07B8pE005* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v07B8pE006* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v07B8pE007* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v07B8pE008* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v07B8pE009* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v07B8pE00A* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v07B8pE4F0* + ID_PRODUCT_FROM_DATABASE=Card Reader Driver + +usb:v07B8pF101* + ID_PRODUCT_FROM_DATABASE=DSB-560 Modem [atlas] + +usb:v07BC* + ID_VENDOR_FROM_DATABASE=Canon Computer Systems, Inc. + +usb:v07BD* + ID_VENDOR_FROM_DATABASE=Webgear, Inc. + +usb:v07BE* + ID_VENDOR_FROM_DATABASE=Veridicom + +usb:v07C0* + ID_VENDOR_FROM_DATABASE=Code Mercenaries Hard- und Software GmbH + +usb:v07C0p1113* + ID_PRODUCT_FROM_DATABASE=JoyWarrior24F8 + +usb:v07C0p1116* + ID_PRODUCT_FROM_DATABASE=JoyWarrior24F14 + +usb:v07C0p1121* + ID_PRODUCT_FROM_DATABASE=The Claw + +usb:v07C0p1500* + ID_PRODUCT_FROM_DATABASE=IO-Warrior 40 + +usb:v07C0p1501* + ID_PRODUCT_FROM_DATABASE=IO-Warrior 24 + +usb:v07C0p1502* + ID_PRODUCT_FROM_DATABASE=IO-Warrior 48 + +usb:v07C0p1503* + ID_PRODUCT_FROM_DATABASE=IO-Warrior 28 + +usb:v07C0p1511* + ID_PRODUCT_FROM_DATABASE=IO-Warrior 24 Power Vampire + +usb:v07C0p1512* + ID_PRODUCT_FROM_DATABASE=IO-Warrior 24 Power Vampire + +usb:v07C1* + ID_VENDOR_FROM_DATABASE=Keisokugiken + +usb:v07C1p0068* + ID_PRODUCT_FROM_DATABASE=HKS-0200 USBDAQ + +usb:v07C4* + ID_VENDOR_FROM_DATABASE=Datafab Systems, Inc. + +usb:v07C4p0102* + ID_PRODUCT_FROM_DATABASE=USB to LS120 + +usb:v07C4p0103* + ID_PRODUCT_FROM_DATABASE=USB to IDE + +usb:v07C4p1234* + ID_PRODUCT_FROM_DATABASE=USB to ATAPI + +usb:v07C4pA000* + ID_PRODUCT_FROM_DATABASE=CompactFlash Card Reader + +usb:v07C4pA001* + ID_PRODUCT_FROM_DATABASE=CompactFlash & SmartMedia Card Reader [eusb] + +usb:v07C4pA002* + ID_PRODUCT_FROM_DATABASE=Disk Drive + +usb:v07C4pA003* + ID_PRODUCT_FROM_DATABASE=Datafab-based Reader + +usb:v07C4pA004* + ID_PRODUCT_FROM_DATABASE=USB to MMC Class Drive + +usb:v07C4pA005* + ID_PRODUCT_FROM_DATABASE=CompactFlash & SmartMedia Card Reader + +usb:v07C4pA006* + ID_PRODUCT_FROM_DATABASE=SmartMedia Card Reader + +usb:v07C4pA007* + ID_PRODUCT_FROM_DATABASE=Memory Stick Class Drive + +usb:v07C4pA103* + ID_PRODUCT_FROM_DATABASE=MDSM-B reader + +usb:v07C4pA107* + ID_PRODUCT_FROM_DATABASE=USB to Memory Stick (LC1) Drive + +usb:v07C4pA109* + ID_PRODUCT_FROM_DATABASE=LC1 CompactFlash & SmartMedia Card Reader + +usb:v07C4pA10B* + ID_PRODUCT_FROM_DATABASE=USB to CF+MS(LC1) + +usb:v07C4pA200* + ID_PRODUCT_FROM_DATABASE=DF-UT-06 Hama MMC/SD Reader + +usb:v07C4pA400* + ID_PRODUCT_FROM_DATABASE=CompactFlash & Microdrive Reader + +usb:v07C4pA600* + ID_PRODUCT_FROM_DATABASE=Card Reader + +usb:v07C4pAD01* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v07C4pAE01* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v07C4pAF01* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v07C4pB000* + ID_PRODUCT_FROM_DATABASE=USB to CF(LC1) + +usb:v07C4pB001* + ID_PRODUCT_FROM_DATABASE=USB to CF+PCMCIA + +usb:v07C4pB004* + ID_PRODUCT_FROM_DATABASE=MMC/SD Reader + +usb:v07C4pB006* + ID_PRODUCT_FROM_DATABASE=USB to PCMCIA + +usb:v07C4pB00A* + ID_PRODUCT_FROM_DATABASE=USB to CF+SD Drive(LC1) + +usb:v07C4pB00B* + ID_PRODUCT_FROM_DATABASE=USB to Memory Stick(LC1) + +usb:v07C5* + ID_VENDOR_FROM_DATABASE=APG Cash Drawer + +usb:v07C6* + ID_VENDOR_FROM_DATABASE=ShareWave, Inc. + +usb:v07C6p0002* + ID_PRODUCT_FROM_DATABASE=Bodega Wireless Access Point + +usb:v07C6p0003* + ID_PRODUCT_FROM_DATABASE=Bodega Wireless Network Adapter + +usb:v07C7* + ID_VENDOR_FROM_DATABASE=Powertech Industrial Co., Ltd + +usb:v07C8* + ID_VENDOR_FROM_DATABASE=B.U.G., Inc. + +usb:v07C8p0202* + ID_PRODUCT_FROM_DATABASE=MN128-SOHO PAL + +usb:v07C9* + ID_VENDOR_FROM_DATABASE=Allied Telesyn International + +usb:v07C9pB100* + ID_PRODUCT_FROM_DATABASE=AT-USB100 + +usb:v07CA* + ID_VENDOR_FROM_DATABASE=AVerMedia Technologies, Inc. + +usb:v07CAp0002* + ID_PRODUCT_FROM_DATABASE=AVerTV PVR USB/EZMaker Pro Device + +usb:v07CAp0026* + ID_PRODUCT_FROM_DATABASE=AVerTV + +usb:v07CAp0337* + ID_PRODUCT_FROM_DATABASE=A867 DVB-T dongle + +usb:v07CAp0837* + ID_PRODUCT_FROM_DATABASE=H837 Hybrid ATSC/QAM + +usb:v07CAp1228* + ID_PRODUCT_FROM_DATABASE=MPEG-2 Capture Device (M038) + +usb:v07CAp1830* + ID_PRODUCT_FROM_DATABASE=AVerTV Volar Video Capture (H830) + +usb:v07CAp3835* + ID_PRODUCT_FROM_DATABASE=AVerTV Volar Green HD (A835B) + +usb:v07CAp850A* + ID_PRODUCT_FROM_DATABASE=AverTV Volar Black HD (A850) + +usb:v07CAp850B* + ID_PRODUCT_FROM_DATABASE=AverTV Red HD+ (A850T) + +usb:v07CApA309* + ID_PRODUCT_FROM_DATABASE=AVerTV DVB-T (A309) + +usb:v07CApA801* + ID_PRODUCT_FROM_DATABASE=AVerTV DVB-T (A800) + +usb:v07CApA815* + ID_PRODUCT_FROM_DATABASE=AVerTV DVB-T Volar X (A815) + +usb:v07CApA867* + ID_PRODUCT_FROM_DATABASE=AVerTV DVB-T (A867) + +usb:v07CApB800* + ID_PRODUCT_FROM_DATABASE=MR800 FM Radio + +usb:v07CApE880* + ID_PRODUCT_FROM_DATABASE=MPEG-2 Capture Device (E880) + +usb:v07CApE882* + ID_PRODUCT_FROM_DATABASE=MPEG-2 Capture Device (E882) + +usb:v07CB* + ID_VENDOR_FROM_DATABASE=Kingmax Technology, Inc. + +usb:v07CC* + ID_VENDOR_FROM_DATABASE=Carry Computer Eng., Co., Ltd + +usb:v07CCp0000* + ID_PRODUCT_FROM_DATABASE=CF Card Reader + +usb:v07CCp0001* + ID_PRODUCT_FROM_DATABASE=Reader (UICSE) + +usb:v07CCp0002* + ID_PRODUCT_FROM_DATABASE=Reader (UIS) + +usb:v07CCp0003* + ID_PRODUCT_FROM_DATABASE=SM Card Reader + +usb:v07CCp0004* + ID_PRODUCT_FROM_DATABASE=SM/CF/PCMCIA Card Reader + +usb:v07CCp0005* + ID_PRODUCT_FROM_DATABASE=Reader (UISA2SE) + +usb:v07CCp0006* + ID_PRODUCT_FROM_DATABASE=SM/CF/PCMCIA Card Reader + +usb:v07CCp0007* + ID_PRODUCT_FROM_DATABASE=Reader (UISA6SE) + +usb:v07CCp000C* + ID_PRODUCT_FROM_DATABASE=SM/CF Card Reader + +usb:v07CCp000D* + ID_PRODUCT_FROM_DATABASE=SM/CF Card Reader + +usb:v07CCp000E* + ID_PRODUCT_FROM_DATABASE=Reader (UISDA) + +usb:v07CCp000F* + ID_PRODUCT_FROM_DATABASE=Reader (UICLIK) + +usb:v07CCp0010* + ID_PRODUCT_FROM_DATABASE=Reader (UISMA) + +usb:v07CCp0012* + ID_PRODUCT_FROM_DATABASE=Reader (UISC6SE-FLASH) + +usb:v07CCp0014* + ID_PRODUCT_FROM_DATABASE=Litronic Fortezza Reader + +usb:v07CCp0030* + ID_PRODUCT_FROM_DATABASE=Mass Storage (UISDMC12S) + +usb:v07CCp0040* + ID_PRODUCT_FROM_DATABASE=Mass Storage (UISDMC13S) + +usb:v07CCp0100* + ID_PRODUCT_FROM_DATABASE=Reader (UID) + +usb:v07CCp0101* + ID_PRODUCT_FROM_DATABASE=Reader (UIM) + +usb:v07CCp0102* + ID_PRODUCT_FROM_DATABASE=Reader (UISDMA) + +usb:v07CCp0103* + ID_PRODUCT_FROM_DATABASE=Reader (UISDMC) + +usb:v07CCp0104* + ID_PRODUCT_FROM_DATABASE=Reader (UISDM) + +usb:v07CCp0200* + ID_PRODUCT_FROM_DATABASE=6-in-1 Card Reader + +usb:v07CCp0201* + ID_PRODUCT_FROM_DATABASE=Mass Storage (UISDMC1S & UISDMC3S) + +usb:v07CCp0202* + ID_PRODUCT_FROM_DATABASE=Mass Storage (UISDMC5S) + +usb:v07CCp0203* + ID_PRODUCT_FROM_DATABASE=Mass Storage (UISMC5S) + +usb:v07CCp0204* + ID_PRODUCT_FROM_DATABASE=Mass Storage (UIM4/5S & UIM7S) + +usb:v07CCp0205* + ID_PRODUCT_FROM_DATABASE=Mass Storage (UIS4/5S & UIS7S) + +usb:v07CCp0206* + ID_PRODUCT_FROM_DATABASE=Mass Storage (UISDMC10S & UISDMC11S) + +usb:v07CCp0207* + ID_PRODUCT_FROM_DATABASE=Mass Storage (UPIDMA) + +usb:v07CCp0208* + ID_PRODUCT_FROM_DATABASE=Mass Storage (UCFC II) + +usb:v07CCp0210* + ID_PRODUCT_FROM_DATABASE=Mass Storage (UPIXXA) + +usb:v07CCp0213* + ID_PRODUCT_FROM_DATABASE=Mass Storage (UPIDA) + +usb:v07CCp0214* + ID_PRODUCT_FROM_DATABASE=Mass Storage (UPIMA) + +usb:v07CCp0215* + ID_PRODUCT_FROM_DATABASE=Mass Storage (UPISA) + +usb:v07CCp0217* + ID_PRODUCT_FROM_DATABASE=Mass Storage (UPISDMA) + +usb:v07CCp0223* + ID_PRODUCT_FROM_DATABASE=Mass Storage (UCIDA) + +usb:v07CCp0224* + ID_PRODUCT_FROM_DATABASE=Mass Storage (UCIMA) + +usb:v07CCp0225* + ID_PRODUCT_FROM_DATABASE=Mass Storage (UIS7S) + +usb:v07CCp0227* + ID_PRODUCT_FROM_DATABASE=Mass Storage (UCIDMA) + +usb:v07CCp0234* + ID_PRODUCT_FROM_DATABASE=Mass Storage (UIM7S) + +usb:v07CCp0235* + ID_PRODUCT_FROM_DATABASE=Mass Storage (UIS4S-S) + +usb:v07CCp0237* + ID_PRODUCT_FROM_DATABASE=Velper (UISDMC4S) + +usb:v07CCp0300* + ID_PRODUCT_FROM_DATABASE=6-in-1 Card Reader + +usb:v07CCp0301* + ID_PRODUCT_FROM_DATABASE=6-in-1 Card Reader + +usb:v07CCp0303* + ID_PRODUCT_FROM_DATABASE=Mass Storage (UID10W) + +usb:v07CCp0304* + ID_PRODUCT_FROM_DATABASE=Mass Storage (UIM10W) + +usb:v07CCp0305* + ID_PRODUCT_FROM_DATABASE=Mass Storage (UIS10W) + +usb:v07CCp0308* + ID_PRODUCT_FROM_DATABASE=Mass Storage (UIC10W) + +usb:v07CCp0309* + ID_PRODUCT_FROM_DATABASE=Mass Storage (UISC3W) + +usb:v07CCp0310* + ID_PRODUCT_FROM_DATABASE=Mass Storage (UISDMA2W) + +usb:v07CCp0311* + ID_PRODUCT_FROM_DATABASE=Mass Storage (UISDMC14W) + +usb:v07CCp0320* + ID_PRODUCT_FROM_DATABASE=Mass Storage (UISDMC4W) + +usb:v07CCp0321* + ID_PRODUCT_FROM_DATABASE=Mass Storage (UISDMC37W) + +usb:v07CCp0330* + ID_PRODUCT_FROM_DATABASE=WINTERREADER Reader + +usb:v07CCp0350* + ID_PRODUCT_FROM_DATABASE=9-in-1 Card Reader + +usb:v07CCp0500* + ID_PRODUCT_FROM_DATABASE=Mass Storage + +usb:v07CCp0501* + ID_PRODUCT_FROM_DATABASE=Mass Storage + +usb:v07CD* + ID_VENDOR_FROM_DATABASE=Elektor + +usb:v07CDp0001* + ID_PRODUCT_FROM_DATABASE=USBuart Serial Port + +usb:v07CF* + ID_VENDOR_FROM_DATABASE=Casio Computer Co., Ltd + +usb:v07CFp1001* + ID_PRODUCT_FROM_DATABASE=QV-8000SX/5700/3000EX Digicam; Exilim EX-M20 + +usb:v07CFp1003* + ID_PRODUCT_FROM_DATABASE=Exilim EX-S500 + +usb:v07CFp1004* + ID_PRODUCT_FROM_DATABASE=Exilim EX-Z120 + +usb:v07CFp1011* + ID_PRODUCT_FROM_DATABASE=USB-CASIO PC CAMERA + +usb:v07CFp1116* + ID_PRODUCT_FROM_DATABASE=EXILIM EX-Z19 + +usb:v07CFp1125* + ID_PRODUCT_FROM_DATABASE=Exilim EX-H10 Digital Camera (mass storage mode) + +usb:v07CFp1133* + ID_PRODUCT_FROM_DATABASE=Exilim EX-Z350 Digital Camera (mass storage mode) + +usb:v07CFp1225* + ID_PRODUCT_FROM_DATABASE=Exilim EX-H10 Digital Camera (PictBridge mode) + +usb:v07CFp1233* + ID_PRODUCT_FROM_DATABASE=Exilim EX-Z350 Digital Camera (PictBridge mode) + +usb:v07CFp2002* + ID_PRODUCT_FROM_DATABASE=E-125 Cassiopeia Pocket PC + +usb:v07CFp3801* + ID_PRODUCT_FROM_DATABASE=WMP-1 MP3-Watch + +usb:v07CFp4001* + ID_PRODUCT_FROM_DATABASE=Label Printer KL-P1000 + +usb:v07CFp4007* + ID_PRODUCT_FROM_DATABASE=CW50 Device + +usb:v07CFp4104* + ID_PRODUCT_FROM_DATABASE=Cw75 Device + +usb:v07CFp4107* + ID_PRODUCT_FROM_DATABASE=CW-L300 Device + +usb:v07CFp4500* + ID_PRODUCT_FROM_DATABASE=LV-20 Digital Camera + +usb:v07CFp6801* + ID_PRODUCT_FROM_DATABASE=PL-40R + +usb:v07CFp6802* + ID_PRODUCT_FROM_DATABASE=MIDI Keyboard + +usb:v07D0* + ID_VENDOR_FROM_DATABASE=Dazzle + +usb:v07D0p0001* + ID_PRODUCT_FROM_DATABASE=Digital Video Creator I + +usb:v07D0p0002* + ID_PRODUCT_FROM_DATABASE=Global Village VideoFX Grabber + +usb:v07D0p0003* + ID_PRODUCT_FROM_DATABASE=Fusion Model DVC-50 Rev 1 (NTSC) + +usb:v07D0p0004* + ID_PRODUCT_FROM_DATABASE=DVC-800 (PAL) Grabber + +usb:v07D0p0005* + ID_PRODUCT_FROM_DATABASE=Fusion Video and Audio Ports + +usb:v07D0p0006* + ID_PRODUCT_FROM_DATABASE=DVC 150 Loader Device + +usb:v07D0p0007* + ID_PRODUCT_FROM_DATABASE=DVC 150 + +usb:v07D0p0327* + ID_PRODUCT_FROM_DATABASE=Fusion Digital Media Reader + +usb:v07D0p1001* + ID_PRODUCT_FROM_DATABASE=DM-FLEX DFU Adapter + +usb:v07D0p1002* + ID_PRODUCT_FROM_DATABASE=DMHS2 DFU Adapter + +usb:v07D0p1102* + ID_PRODUCT_FROM_DATABASE=CF Reader/Writer + +usb:v07D0p1103* + ID_PRODUCT_FROM_DATABASE=SD Reader/Writer + +usb:v07D0p1104* + ID_PRODUCT_FROM_DATABASE=SM Reader/Writer + +usb:v07D0p1105* + ID_PRODUCT_FROM_DATABASE=MS Reader/Writer + +usb:v07D0p1106* + ID_PRODUCT_FROM_DATABASE=xD/SM Reader/Writer + +usb:v07D0p1202* + ID_PRODUCT_FROM_DATABASE=MultiSlot Reader/Writer + +usb:v07D0p2000* + ID_PRODUCT_FROM_DATABASE=FX2 DFU Adapter + +usb:v07D0p2001* + ID_PRODUCT_FROM_DATABASE=eUSB CompactFlash Reader + +usb:v07D0p4100* + ID_PRODUCT_FROM_DATABASE=Kingsun SF-620 Infrared Adapter + +usb:v07D0p4101* + ID_PRODUCT_FROM_DATABASE=Connectivity Cable (CA-42 clone) + +usb:v07D0p4959* + ID_PRODUCT_FROM_DATABASE=Kingsun KS-959 Infrared Adapter + +usb:v07D1* + ID_VENDOR_FROM_DATABASE=D-Link System + +usb:v07D1p13EC* + ID_PRODUCT_FROM_DATABASE=VvBus for Helium 2xx + +usb:v07D1p13ED* + ID_PRODUCT_FROM_DATABASE=VvBus for Helium 2xx + +usb:v07D1p13F1* + ID_PRODUCT_FROM_DATABASE=DSL-302G Modem + +usb:v07D1p13F2* + ID_PRODUCT_FROM_DATABASE=DSL-502G Router + +usb:v07D1p3300* + ID_PRODUCT_FROM_DATABASE=DWA-130 802.11n Wireless N Adapter(rev.E) [Realtek RTL8191SU] + +usb:v07D1p3302* + ID_PRODUCT_FROM_DATABASE=DWA-130 802.11n Wireless N Adapter(rev.C2) [Realtek RTL8191SU] + +usb:v07D1p3303* + ID_PRODUCT_FROM_DATABASE=DWA-131 802.11n Wireless N Nano Adapter(rev.A1) [Realtek RTL8192SU] + +usb:v07D1p3304* + ID_PRODUCT_FROM_DATABASE=FR-300USB 802.11bgn Wireless Adapter + +usb:v07D1p3A07* + ID_PRODUCT_FROM_DATABASE=WUA-2340 RangeBooster G Adapter(rev.A) [Atheros AR5523] + +usb:v07D1p3A08* + ID_PRODUCT_FROM_DATABASE=WUA-2340 RangeBooster G Adapter(rev.A) (no firmware) [Atheros AR5523] + +usb:v07D1p3A09* + ID_PRODUCT_FROM_DATABASE=DWA-160 802.11abgn Xtreme N Dual Band Adapter(rev.A2) [Atheros AR9170+AR9104] + +usb:v07D1p3A0D* + ID_PRODUCT_FROM_DATABASE=DWA-120 802.11g Wireless 108G Adapter [Atheros AR5523] + +usb:v07D1p3A0F* + ID_PRODUCT_FROM_DATABASE=DWA-130 802.11n Wireless N Adapter(rev.D) [Atheros AR9170+AR9102] + +usb:v07D1p3A10* + ID_PRODUCT_FROM_DATABASE=DWA-126 802.11n Wireless Adapter [Atheros AR9271] + +usb:v07D1p3B01* + ID_PRODUCT_FROM_DATABASE=AirPlus G DWL-G122 Wireless Adapter(rev.D) [Marvell 88W8338+88W8010] + +usb:v07D1p3B10* + ID_PRODUCT_FROM_DATABASE=DWA-142 RangeBooster N Adapter [Marvell 88W8362+88W8060] + +usb:v07D1p3B11* + ID_PRODUCT_FROM_DATABASE=DWA-130 802.11n Wireless N Adapter(rev.A1) [Marvell 88W8362+88W8060] + +usb:v07D1p3C03* + ID_PRODUCT_FROM_DATABASE=AirPlus G DWL-G122 Wireless Adapter(rev.C1) [Ralink RT2571W] + +usb:v07D1p3C04* + ID_PRODUCT_FROM_DATABASE=WUA-1340 + +usb:v07D1p3C05* + ID_PRODUCT_FROM_DATABASE=EH103 Wireless G Adapter + +usb:v07D1p3C06* + ID_PRODUCT_FROM_DATABASE=DWA-111 802.11bg Wireless Adapter [Ralink RT2571W] + +usb:v07D1p3C07* + ID_PRODUCT_FROM_DATABASE=DWA-110 Wireless G Adapter(rev.A1) [Ralink RT2571W] + +usb:v07D1p3C09* + ID_PRODUCT_FROM_DATABASE=DWA-140 RangeBooster N Adapter(rev.B1) [Ralink RT2870] + +usb:v07D1p3C0A* + ID_PRODUCT_FROM_DATABASE=DWA-140 RangeBooster N Adapter(rev.B2) [Ralink RT3072] + +usb:v07D1p3C0B* + ID_PRODUCT_FROM_DATABASE=DWA-110 Wireless G Adapter(rev.B) [Ralink RT2870] + +usb:v07D1p3C0D* + ID_PRODUCT_FROM_DATABASE=DWA-125 Wireless N 150 Adapter(rev.A1) [Ralink RT3070] + +usb:v07D1p3C0E* + ID_PRODUCT_FROM_DATABASE=WUA-2340 RangeBooster G Adapter(rev.B) [Ralink RT2070] + +usb:v07D1p3C0F* + ID_PRODUCT_FROM_DATABASE=AirPlus G DWL-G122 Wireless Adapter(rev.E1) [Ralink RT2070] + +usb:v07D1p3C10* + ID_PRODUCT_FROM_DATABASE=DWA-160 802.11abgn Xtreme N Dual Band Adapter(rev.A1) [Atheros AR9170+AR9104] + +usb:v07D1p3C11* + ID_PRODUCT_FROM_DATABASE=DWA-160 Xtreme N Dual Band USB Adapter(rev.B) [Ralink RT2870] + +usb:v07D1p3C13* + ID_PRODUCT_FROM_DATABASE=DWA-130 802.11n Wireless N Adapter(rev.B) [Ralink RT2870] + +usb:v07D1p3C15* + ID_PRODUCT_FROM_DATABASE=DWA-140 RangeBooster N Adapter(rev.B3) [Ralink RT2870] + +usb:v07D1p3C16* + ID_PRODUCT_FROM_DATABASE=DWA-125 Wireless N 150 Adapter(rev.A2) [Ralink RT3070] + +usb:v07D1p3E02* + ID_PRODUCT_FROM_DATABASE=DWM-156 3.75G HSUPA Adapter + +usb:v07D1p5100* + ID_PRODUCT_FROM_DATABASE=Remote NDIS Device + +usb:v07D1pA800* + ID_PRODUCT_FROM_DATABASE=DWM-152 3.75G HSUPA Adapter + +usb:v07D1pF101* + ID_PRODUCT_FROM_DATABASE=DBT-122 Bluetooth + +usb:v07D1pFC01* + ID_PRODUCT_FROM_DATABASE=DBT-120 Bluetooth Adapter + +usb:v07D2* + ID_VENDOR_FROM_DATABASE=Aptio Products, Inc. + +usb:v07D3* + ID_VENDOR_FROM_DATABASE=Cyberdata Corp. + +usb:v07D5* + ID_VENDOR_FROM_DATABASE=Radiant Systems + +usb:v07D7* + ID_VENDOR_FROM_DATABASE=GCC Technologies, Inc. + +usb:v07DA* + ID_VENDOR_FROM_DATABASE=Arasan Chip Systems + +usb:v07DE* + ID_VENDOR_FROM_DATABASE=Diamond Multimedia + +usb:v07DEp2820* + ID_PRODUCT_FROM_DATABASE=VC500 Video Capture Dongle + +usb:v07DF* + ID_VENDOR_FROM_DATABASE=David Electronics Co., Ltd + +usb:v07E1* + ID_VENDOR_FROM_DATABASE=Ambient Technologies, Inc. + +usb:v07E1p5201* + ID_PRODUCT_FROM_DATABASE=V.90 Modem + +usb:v07E2* + ID_VENDOR_FROM_DATABASE=Elmeg GmbH & Co., Ltd + +usb:v07E3* + ID_VENDOR_FROM_DATABASE=Planex Communications, Inc. + +usb:v07E4* + ID_VENDOR_FROM_DATABASE=Movado Enterprise Co., Ltd + +usb:v07E4p0967* + ID_PRODUCT_FROM_DATABASE=SCard R/W CSR-145 + +usb:v07E4p0968* + ID_PRODUCT_FROM_DATABASE=SCard R/W CSR-145 + +usb:v07E5* + ID_VENDOR_FROM_DATABASE=QPS, Inc. + +usb:v07E5p05C2* + ID_PRODUCT_FROM_DATABASE=IDE-to-USB2.0 PCA + +usb:v07E5p5C01* + ID_PRODUCT_FROM_DATABASE=Que! CDRW + +usb:v07E6* + ID_VENDOR_FROM_DATABASE=Allied Cable Corp. + +usb:v07E7* + ID_VENDOR_FROM_DATABASE=Mirvo Toys, Inc. + +usb:v07E8* + ID_VENDOR_FROM_DATABASE=Labsystems + +usb:v07EA* + ID_VENDOR_FROM_DATABASE=Iwatsu Electric Co., Ltd + +usb:v07EB* + ID_VENDOR_FROM_DATABASE=Double-H Technology Co., Ltd + +usb:v07EC* + ID_VENDOR_FROM_DATABASE=Taiyo Electric Wire & Cable Co., Ltd + +usb:v07EE* + ID_VENDOR_FROM_DATABASE=Torex Retail (formerly Logware) + +usb:v07EEp0002* + ID_PRODUCT_FROM_DATABASE=Cash Drawer I/F + +usb:v07EF* + ID_VENDOR_FROM_DATABASE=STSN + +usb:v07EFp0001* + ID_PRODUCT_FROM_DATABASE=Internet Access Device + +usb:v07F2* + ID_VENDOR_FROM_DATABASE=Microcomputer Applications, Inc. + +usb:v07F2p0001* + ID_PRODUCT_FROM_DATABASE=KEYLOK II + +usb:v07F6* + ID_VENDOR_FROM_DATABASE=Circuit Assembly Corp. + +usb:v07F7* + ID_VENDOR_FROM_DATABASE=Century Corp. + +usb:v07F7p0005* + ID_PRODUCT_FROM_DATABASE=ScanLogic/Century Corporation uATA + +usb:v07F7p011E* + ID_PRODUCT_FROM_DATABASE=Century USB Disk Enclosure + +usb:v07F9* + ID_VENDOR_FROM_DATABASE=Dotop Technology, Inc. + +usb:v07FA* + ID_VENDOR_FROM_DATABASE=DrayTek Corp. + +usb:v07FAp0778* + ID_PRODUCT_FROM_DATABASE=miniVigor 128 ISDN TA + +usb:v07FAp1012* + ID_PRODUCT_FROM_DATABASE=BeWAN ADSL USB ST (grey) + +usb:v07FAp1196* + ID_PRODUCT_FROM_DATABASE=BWIFI-USB54AR 802.11bg + +usb:v07FApA904* + ID_PRODUCT_FROM_DATABASE=BeWAN ADSL + +usb:v07FApA905* + ID_PRODUCT_FROM_DATABASE=BeWAN ADSL ST + +usb:v07FD* + ID_VENDOR_FROM_DATABASE=Mark of the Unicorn + +usb:v07FDp0000* + ID_PRODUCT_FROM_DATABASE=FastLane MIDI Interface + +usb:v07FDp0001* + ID_PRODUCT_FROM_DATABASE=FastLane Quad MIDI Interface + +usb:v07FDp0002* + ID_PRODUCT_FROM_DATABASE=MOTU Audio for 64 bit + +usb:v07FF* + ID_VENDOR_FROM_DATABASE=Unknown + +usb:v07FFp00FF* + ID_PRODUCT_FROM_DATABASE=Portable Hard Drive + +usb:v0801* + ID_VENDOR_FROM_DATABASE=MagTek + +usb:v0801p0001* + ID_PRODUCT_FROM_DATABASE=Mini Swipe Reader (Keyboard Emulation) + +usb:v0801p0002* + ID_PRODUCT_FROM_DATABASE=Mini Swipe Reader + +usb:v0801p0003* + ID_PRODUCT_FROM_DATABASE=Magstripe Insert Reader + +usb:v0802* + ID_VENDOR_FROM_DATABASE=Mako Technologies, LLC + +usb:v0803* + ID_VENDOR_FROM_DATABASE=Zoom Telephonics, Inc. + +usb:v0803p1300* + ID_PRODUCT_FROM_DATABASE=V92 Faxmodem + +usb:v0803p4310* + ID_PRODUCT_FROM_DATABASE=4410a Wireless-G Adapter [Intersil ISL3887] + +usb:v0803p4410* + ID_PRODUCT_FROM_DATABASE=4410b Wireless-G Adapter [ZyDAS ZD1211B] + +usb:v0803p5241* + ID_PRODUCT_FROM_DATABASE=Cable Modem + +usb:v0803p5551* + ID_PRODUCT_FROM_DATABASE=DSL Modem + +usb:v0803p9700* + ID_PRODUCT_FROM_DATABASE=2986L FaxModem + +usb:v0803p9800* + ID_PRODUCT_FROM_DATABASE=Cable Modem + +usb:v0803pA312* + ID_PRODUCT_FROM_DATABASE=Wireless-G + +usb:v0809* + ID_VENDOR_FROM_DATABASE=Genicom Technology, Inc. + +usb:v080A* + ID_VENDOR_FROM_DATABASE=Evermuch Technology Co., Ltd + +usb:v080B* + ID_VENDOR_FROM_DATABASE=Cross Match Technologies + +usb:v080Bp0002* + ID_PRODUCT_FROM_DATABASE=Fingerprint Scanner (After ReNumeration) + +usb:v080Bp0010* + ID_PRODUCT_FROM_DATABASE=300LC Series Fingerprint Scanner (Before ReNumeration) + +usb:v080C* + ID_VENDOR_FROM_DATABASE=Datalogic S.p.A. + +usb:v080Cp0300* + ID_PRODUCT_FROM_DATABASE=Gryphon D120 Barcode Scanner + +usb:v080Cp0400* + ID_PRODUCT_FROM_DATABASE=Gryphon D120 Barcode Scanner + +usb:v080Cp0500* + ID_PRODUCT_FROM_DATABASE=Gryphon D120 Barcode Scanner + +usb:v080Cp0600* + ID_PRODUCT_FROM_DATABASE=Gryphon M100 Barcode Scanner + +usb:v080D* + ID_VENDOR_FROM_DATABASE=Teco Image Systems Co., Ltd + +usb:v080Dp0102* + ID_PRODUCT_FROM_DATABASE=Hercules Scan@home 48 + +usb:v080Dp0104* + ID_PRODUCT_FROM_DATABASE=3.2Slim + +usb:v080Dp0110* + ID_PRODUCT_FROM_DATABASE=UMAX AstraSlim 1200 Scanner + +usb:v0810* + ID_VENDOR_FROM_DATABASE=Personal Communication Systems, Inc. + +usb:v0810p0001* + ID_PRODUCT_FROM_DATABASE=Dual PSX Adaptor + +usb:v0810p0002* + ID_PRODUCT_FROM_DATABASE=Dual PCS Adaptor + +usb:v0810p0003* + ID_PRODUCT_FROM_DATABASE=PlayStation Gamepad + +usb:v0813* + ID_VENDOR_FROM_DATABASE=Mattel, Inc. + +usb:v0813p0001* + ID_PRODUCT_FROM_DATABASE=Intel Play QX3 Microscope + +usb:v0813p0002* + ID_PRODUCT_FROM_DATABASE=Dual Mode Camera Plus + +usb:v0819* + ID_VENDOR_FROM_DATABASE=eLicenser + +usb:v0819p0101* + ID_PRODUCT_FROM_DATABASE=License Management and Copy Protection + +usb:v081A* + ID_VENDOR_FROM_DATABASE=MG Logic + +usb:v081Ap1000* + ID_PRODUCT_FROM_DATABASE=Duo Pen Tablet + +usb:v081B* + ID_VENDOR_FROM_DATABASE=Indigita Corp. + +usb:v081Bp0600* + ID_PRODUCT_FROM_DATABASE=Storage Adapter + +usb:v081Bp0601* + ID_PRODUCT_FROM_DATABASE=Storage Adapter + +usb:v081C* + ID_VENDOR_FROM_DATABASE=Mipsys + +usb:v081E* + ID_VENDOR_FROM_DATABASE=AlphaSmart, Inc. + +usb:v081EpDF00* + ID_PRODUCT_FROM_DATABASE=Handheld + +usb:v0822* + ID_VENDOR_FROM_DATABASE=Reudo Corp. + +usb:v0822p2001* + ID_PRODUCT_FROM_DATABASE=IRXpress Infrared Device + +usb:v0825* + ID_VENDOR_FROM_DATABASE=GC Protronics + +usb:v0826* + ID_VENDOR_FROM_DATABASE=Data Transit + +usb:v0827* + ID_VENDOR_FROM_DATABASE=BroadLogic, Inc. + +usb:v0828* + ID_VENDOR_FROM_DATABASE=Sato Corp. + +usb:v0829* + ID_VENDOR_FROM_DATABASE=DirecTV Broadband, Inc. (Telocity) + +usb:v082D* + ID_VENDOR_FROM_DATABASE=Handspring + +usb:v082Dp0100* + ID_PRODUCT_FROM_DATABASE=Visor + +usb:v082Dp0200* + ID_PRODUCT_FROM_DATABASE=Treo + +usb:v082Dp0300* + ID_PRODUCT_FROM_DATABASE=Treo 600 + +usb:v082Dp0400* + ID_PRODUCT_FROM_DATABASE=Handheld + +usb:v082Dp0500* + ID_PRODUCT_FROM_DATABASE=Handheld + +usb:v082Dp0600* + ID_PRODUCT_FROM_DATABASE=Handheld + +usb:v0830* + ID_VENDOR_FROM_DATABASE=Palm, Inc. + +usb:v0830p0001* + ID_PRODUCT_FROM_DATABASE=m500 + +usb:v0830p0002* + ID_PRODUCT_FROM_DATABASE=m505 + +usb:v0830p0003* + ID_PRODUCT_FROM_DATABASE=m515 + +usb:v0830p0004* + ID_PRODUCT_FROM_DATABASE=Handheld + +usb:v0830p0005* + ID_PRODUCT_FROM_DATABASE=Handheld + +usb:v0830p0006* + ID_PRODUCT_FROM_DATABASE=Handheld + +usb:v0830p0010* + ID_PRODUCT_FROM_DATABASE=Handheld + +usb:v0830p0011* + ID_PRODUCT_FROM_DATABASE=Handheld + +usb:v0830p0012* + ID_PRODUCT_FROM_DATABASE=Handheld + +usb:v0830p0013* + ID_PRODUCT_FROM_DATABASE=Handheld + +usb:v0830p0014* + ID_PRODUCT_FROM_DATABASE=Handheld + +usb:v0830p0020* + ID_PRODUCT_FROM_DATABASE=i705 + +usb:v0830p0021* + ID_PRODUCT_FROM_DATABASE=Handheld + +usb:v0830p0022* + ID_PRODUCT_FROM_DATABASE=Handheld + +usb:v0830p0023* + ID_PRODUCT_FROM_DATABASE=Handheld + +usb:v0830p0024* + ID_PRODUCT_FROM_DATABASE=Handheld + +usb:v0830p0030* + ID_PRODUCT_FROM_DATABASE=Handheld + +usb:v0830p0031* + ID_PRODUCT_FROM_DATABASE=Tungsten W + +usb:v0830p0032* + ID_PRODUCT_FROM_DATABASE=Handheld + +usb:v0830p0033* + ID_PRODUCT_FROM_DATABASE=Handheld + +usb:v0830p0034* + ID_PRODUCT_FROM_DATABASE=Handheld + +usb:v0830p0040* + ID_PRODUCT_FROM_DATABASE=m125 + +usb:v0830p0041* + ID_PRODUCT_FROM_DATABASE=Handheld + +usb:v0830p0042* + ID_PRODUCT_FROM_DATABASE=Handheld + +usb:v0830p0043* + ID_PRODUCT_FROM_DATABASE=Handheld + +usb:v0830p0044* + ID_PRODUCT_FROM_DATABASE=Handheld + +usb:v0830p0050* + ID_PRODUCT_FROM_DATABASE=m130 + +usb:v0830p0051* + ID_PRODUCT_FROM_DATABASE=Handheld + +usb:v0830p0052* + ID_PRODUCT_FROM_DATABASE=Handheld + +usb:v0830p0053* + ID_PRODUCT_FROM_DATABASE=Handheld + +usb:v0830p0054* + ID_PRODUCT_FROM_DATABASE=Handheld + +usb:v0830p0060* + ID_PRODUCT_FROM_DATABASE=Tungsten C/E/T/T2/T3 / Zire 71 + +usb:v0830p0061* + ID_PRODUCT_FROM_DATABASE=Lifedrive / Treo 650/680 / Tunsten E2/T5/TX / Centro / Zire 21/31/72 / Z22 + +usb:v0830p0062* + ID_PRODUCT_FROM_DATABASE=Handheld + +usb:v0830p0063* + ID_PRODUCT_FROM_DATABASE=Handheld + +usb:v0830p0064* + ID_PRODUCT_FROM_DATABASE=Handheld + +usb:v0830p0070* + ID_PRODUCT_FROM_DATABASE=Zire + +usb:v0830p0071* + ID_PRODUCT_FROM_DATABASE=Handheld + +usb:v0830p0072* + ID_PRODUCT_FROM_DATABASE=Handheld + +usb:v0830p0080* + ID_PRODUCT_FROM_DATABASE=Serial Adapter [for Palm III] + +usb:v0830p0081* + ID_PRODUCT_FROM_DATABASE=Handheld + +usb:v0830p0082* + ID_PRODUCT_FROM_DATABASE=Handheld + +usb:v0830p00A0* + ID_PRODUCT_FROM_DATABASE=Treo 800w + +usb:v0830p0101* + ID_PRODUCT_FROM_DATABASE=Pre + +usb:v0832* + ID_VENDOR_FROM_DATABASE=Kouwell Electronics Corp. + +usb:v0832p5850* + ID_PRODUCT_FROM_DATABASE=Cable + +usb:v0833* + ID_VENDOR_FROM_DATABASE=Sourcenext Corp. + +usb:v0833p012E* + ID_PRODUCT_FROM_DATABASE=KeikaiDenwa 8 with charger + +usb:v0833p039F* + ID_PRODUCT_FROM_DATABASE=KeikaiDenwa 8 + +usb:v0835* + ID_VENDOR_FROM_DATABASE=Action Star Enterprise Co., Ltd + +usb:v0836* + ID_VENDOR_FROM_DATABASE=TrekStor + +usb:v0836p2836* + ID_PRODUCT_FROM_DATABASE=i.Beat mood + +usb:v0839* + ID_VENDOR_FROM_DATABASE=Samsung Techwin Co., Ltd + +usb:v0839p0005* + ID_PRODUCT_FROM_DATABASE=Digimax Camera + +usb:v0839p0008* + ID_PRODUCT_FROM_DATABASE=Digimax 230 Camera + +usb:v0839p0009* + ID_PRODUCT_FROM_DATABASE=Digimax 340 + +usb:v0839p000A* + ID_PRODUCT_FROM_DATABASE=Digimax 410 + +usb:v0839p000E* + ID_PRODUCT_FROM_DATABASE=Digimax 360 + +usb:v0839p0010* + ID_PRODUCT_FROM_DATABASE=Digimax 300 + +usb:v0839p1003* + ID_PRODUCT_FROM_DATABASE=Digimax 210SE + +usb:v0839p1005* + ID_PRODUCT_FROM_DATABASE=Digimax 220 + +usb:v0839p1009* + ID_PRODUCT_FROM_DATABASE=Digimax V4 + +usb:v0839p1012* + ID_PRODUCT_FROM_DATABASE=6500 Document Camera + +usb:v0839p1058* + ID_PRODUCT_FROM_DATABASE=S730 Camera + +usb:v0839p1064* + ID_PRODUCT_FROM_DATABASE=Digimax D830 Camera + +usb:v0839p1542* + ID_PRODUCT_FROM_DATABASE=Digimax 50 Duo + +usb:v0839p3000* + ID_PRODUCT_FROM_DATABASE=Digimax 35 MP3 + +usb:v083A* + ID_VENDOR_FROM_DATABASE=Accton Technology Corp. + +usb:v083Ap1046* + ID_PRODUCT_FROM_DATABASE=10/100 Ethernet [pegasus] + +usb:v083Ap1060* + ID_PRODUCT_FROM_DATABASE=HomeLine Adapter + +usb:v083Ap1F4D* + ID_PRODUCT_FROM_DATABASE=SMC8013WG Broadband Remote NDIS Device + +usb:v083Ap3046* + ID_PRODUCT_FROM_DATABASE=10/100 Series Adapter + +usb:v083Ap3060* + ID_PRODUCT_FROM_DATABASE=1/10/100 Adapter + +usb:v083Ap3501* + ID_PRODUCT_FROM_DATABASE=2664W + +usb:v083Ap3502* + ID_PRODUCT_FROM_DATABASE=WN3501D Wireless Adapter + +usb:v083Ap3503* + ID_PRODUCT_FROM_DATABASE=T-Sinus 111 Wireless Adapter + +usb:v083Ap4501* + ID_PRODUCT_FROM_DATABASE=T-Sinus 154data + +usb:v083Ap4502* + ID_PRODUCT_FROM_DATABASE=Siemens S30853-S1016-R107 802.11g Wireless Adapter [Intersil ISL3886] + +usb:v083Ap4505* + ID_PRODUCT_FROM_DATABASE=SMCWUSB-G 802.11bg + +usb:v083Ap4507* + ID_PRODUCT_FROM_DATABASE=SMCWUSBT-G2 802.11g Wireless Adapter [Atheros AR5523] + +usb:v083Ap4521* + ID_PRODUCT_FROM_DATABASE=Siemens S30863-S1016-R107-2 802.11g Wireless Adapter [Intersil ISL3887] + +usb:v083Ap5046* + ID_PRODUCT_FROM_DATABASE=SpeedStream 10/100 Ethernet [pegasus] + +usb:v083Ap5501* + ID_PRODUCT_FROM_DATABASE=Wireless Adapter 11g + +usb:v083Ap6500* + ID_PRODUCT_FROM_DATABASE=Cable Modem + +usb:v083Ap6618* + ID_PRODUCT_FROM_DATABASE=802.11n Wireless Adapter + +usb:v083Ap7511* + ID_PRODUCT_FROM_DATABASE=Arcadyan 802.11N Wireless Adapter + +usb:v083Ap7512* + ID_PRODUCT_FROM_DATABASE=Arcadyan 802.11N Wireless Adapter + +usb:v083Ap7522* + ID_PRODUCT_FROM_DATABASE=Arcadyan 802.11N Wireless Adapter + +usb:v083Ap8522* + ID_PRODUCT_FROM_DATABASE=Arcadyan 802.11N Wireless Adapter + +usb:v083Ap8541* + ID_PRODUCT_FROM_DATABASE=WN4501F 802.11g Wireless Adapter [Intersil ISL3887] + +usb:v083ApA512* + ID_PRODUCT_FROM_DATABASE=Arcadyan 802.11N Wireless Adapter + +usb:v083ApA618* + ID_PRODUCT_FROM_DATABASE=SMCWUSBS-N EZ Connect N Draft 11n Wireless Adapter [Ralink RT2870] + +usb:v083ApA701* + ID_PRODUCT_FROM_DATABASE=SMCWUSBS-N3 EZ Connect N Wireless Adapter [Ralink RT3070] + +usb:v083ApB004* + ID_PRODUCT_FROM_DATABASE=CPWUE001 USB/Ethernet Adapter + +usb:v083ApB522* + ID_PRODUCT_FROM_DATABASE=SMCWUSBS-N2 EZ Connect N Wireless Adapter [Ralink RT2870] + +usb:v083ApBB01* + ID_PRODUCT_FROM_DATABASE=BlueExpert Bluetooth Device + +usb:v083ApC003* + ID_PRODUCT_FROM_DATABASE=802.11b Wireless Adapter + +usb:v083ApC501* + ID_PRODUCT_FROM_DATABASE=Zoom 4410 Wireless-G [Intersil ISL3887] + +usb:v083ApC561* + ID_PRODUCT_FROM_DATABASE=802.11a/g Wireless Adapter + +usb:v083ApD522* + ID_PRODUCT_FROM_DATABASE=Speedport W 102 Stick IEEE 802.11n USB 2.0 Adapter + +usb:v083ApE501* + ID_PRODUCT_FROM_DATABASE=ZD1211B + +usb:v083ApE503* + ID_PRODUCT_FROM_DATABASE=Arcadyan WN4501 802.11b/g + +usb:v083ApE506* + ID_PRODUCT_FROM_DATABASE=WUS-201 802.11bg + +usb:v083ApF501* + ID_PRODUCT_FROM_DATABASE=802.11g Wireless Adapter + +usb:v083ApF502* + ID_PRODUCT_FROM_DATABASE=802.11g Wireless Adapter + +usb:v083ApF522* + ID_PRODUCT_FROM_DATABASE=Arcadyan WN7512 802.11n + +usb:v083F* + ID_VENDOR_FROM_DATABASE=Global Village + +usb:v083FpB100* + ID_PRODUCT_FROM_DATABASE=TelePort V.90 Fax/Modem + +usb:v0840* + ID_VENDOR_FROM_DATABASE=Argosy Research, Inc. + +usb:v0840p0060* + ID_PRODUCT_FROM_DATABASE=Storage Adapter Bridge Module + +usb:v0841* + ID_VENDOR_FROM_DATABASE=Rioport.com, Inc. + +usb:v0841p0001* + ID_PRODUCT_FROM_DATABASE=Rio 500 + +usb:v0844* + ID_VENDOR_FROM_DATABASE=Welland Industrial Co., Ltd + +usb:v0846* + ID_VENDOR_FROM_DATABASE=NetGear, Inc. + +usb:v0846p1001* + ID_PRODUCT_FROM_DATABASE=EA101 10 Mbps 10BASE-T Ethernet [Kawasaki LSI KL5KLUSB101B] + +usb:v0846p1002* + ID_PRODUCT_FROM_DATABASE=Ethernet + +usb:v0846p1020* + ID_PRODUCT_FROM_DATABASE=FA101 Fast Ethernet USB 1.1 + +usb:v0846p1040* + ID_PRODUCT_FROM_DATABASE=FA120 Fast Ethernet USB 2.0 [Asix AX88172 / AX8817x] + +usb:v0846p4110* + ID_PRODUCT_FROM_DATABASE=MA111(v1) 802.11b Wireless [Intersil Prism 3.0] + +usb:v0846p4200* + ID_PRODUCT_FROM_DATABASE=WG121(v1) 54 Mbps Wireless [Intersil ISL3886] + +usb:v0846p4210* + ID_PRODUCT_FROM_DATABASE=WG121(v2) 54 Mbps Wireless [Intersil ISL3886] + +usb:v0846p4220* + ID_PRODUCT_FROM_DATABASE=WG111(v1) 54 Mbps Wireless [Intersil ISL3886] + +usb:v0846p4230* + ID_PRODUCT_FROM_DATABASE=MA111(v2) 802.11b Wireless [SIS SIS 162] + +usb:v0846p4240* + ID_PRODUCT_FROM_DATABASE=WG111(v1) rev 2 54 Mbps Wireless [Intersil ISL3887] + +usb:v0846p4260* + ID_PRODUCT_FROM_DATABASE=WG111v3 54 Mbps Wireless [realtek RTL8187B] + +usb:v0846p4300* + ID_PRODUCT_FROM_DATABASE=WG111U Double 108 Mbps Wireless [Atheros AR5004X / AR5005UX] + +usb:v0846p4301* + ID_PRODUCT_FROM_DATABASE=WG111U (no firmware) Double 108 Mbps Wireless [Atheros AR5004X / AR5005UX] + +usb:v0846p5F00* + ID_PRODUCT_FROM_DATABASE=WPN111 802.11g Wireless Adapter [Atheros AR5523] + +usb:v0846p6A00* + ID_PRODUCT_FROM_DATABASE=WG111v2 54 Mbps Wireless [RealTek RTL8187L] + +usb:v0846p7100* + ID_PRODUCT_FROM_DATABASE=WN121T RangeMax Next Wireless-N [Marvell TopDog] + +usb:v0846p9000* + ID_PRODUCT_FROM_DATABASE=WN111(v1) RangeMax Next Wireless [Marvell 88W8362+88W8060] + +usb:v0846p9001* + ID_PRODUCT_FROM_DATABASE=WN111(v2) RangeMax Next Wireless [Atheros AR9170+AR9101] + +usb:v0846p9010* + ID_PRODUCT_FROM_DATABASE=WNDA3100v1 802.11abgn [Atheros AR9170+AR9104] + +usb:v0846p9011* + ID_PRODUCT_FROM_DATABASE=WNDA3100v2 802.11abgn [Broadcom BCM4323] + +usb:v0846p9012* + ID_PRODUCT_FROM_DATABASE=WNDA4100 802.11abgn 3x3:3 [Ralink RT3573] + +usb:v0846p9018* + ID_PRODUCT_FROM_DATABASE=WNDA3200 802.11abgn Wireless Adapter [Atheros AR7010+AR9280] + +usb:v0846p9020* + ID_PRODUCT_FROM_DATABASE=WNA3100(v1) Wireless-N 300 [Broadcom BCM43231] + +usb:v0846p9030* + ID_PRODUCT_FROM_DATABASE=WNA1100 Wireless-N 150 [Atheros AR9271] + +usb:v0846p9040* + ID_PRODUCT_FROM_DATABASE=WNA1000 Wireless-N 150 [Atheros AR9170+AR9101] + +usb:v0846p9041* + ID_PRODUCT_FROM_DATABASE=WNA1000M 802.11bgn [Realtek RTL8188CUS] + +usb:v0846pA001* + ID_PRODUCT_FROM_DATABASE=PA101 10 Mbps HPNA Home Phoneline RJ-1 + +usb:v084D* + ID_VENDOR_FROM_DATABASE=Minton Optic Industry Co., Inc. + +usb:v084Dp0001* + ID_PRODUCT_FROM_DATABASE=Jenoptik JD800i + +usb:v084Dp0003* + ID_PRODUCT_FROM_DATABASE=S-Cam F5/D-Link DSC-350 Digital Camera + +usb:v084Dp0011* + ID_PRODUCT_FROM_DATABASE=Argus DC3500 Digital Camera + +usb:v084Dp0014* + ID_PRODUCT_FROM_DATABASE=Praktica DC 32 + +usb:v084Dp0019* + ID_PRODUCT_FROM_DATABASE=Praktica DPix3000 + +usb:v084Dp0025* + ID_PRODUCT_FROM_DATABASE=Praktica DC 60 + +usb:v084Dp1001* + ID_PRODUCT_FROM_DATABASE=ScanHex SX-35d + +usb:v084E* + ID_VENDOR_FROM_DATABASE=KB Gear + +usb:v084Ep0001* + ID_PRODUCT_FROM_DATABASE=JamCam Camera + +usb:v084Ep1001* + ID_PRODUCT_FROM_DATABASE=Jam Studio Tablet + +usb:v084Ep1002* + ID_PRODUCT_FROM_DATABASE=Pablo Tablet + +usb:v084F* + ID_VENDOR_FROM_DATABASE=Empeg + +usb:v084Fp0001* + ID_PRODUCT_FROM_DATABASE=Empeg-Car Mark I/II Player + +usb:v0850* + ID_VENDOR_FROM_DATABASE=Fast Point Technologies, Inc. + +usb:v0851* + ID_VENDOR_FROM_DATABASE=Macronix International Co., Ltd + +usb:v0851p1542* + ID_PRODUCT_FROM_DATABASE=SiPix Blink + +usb:v0851p1543* + ID_PRODUCT_FROM_DATABASE=Maxell WS30 Slim Digital Camera, or Pandigital PI8004W01 digital photo frame + +usb:v0851pA168* + ID_PRODUCT_FROM_DATABASE=MXIC + +usb:v0852* + ID_VENDOR_FROM_DATABASE=CSEM + +usb:v0853* + ID_VENDOR_FROM_DATABASE=Topre Corporation + +usb:v0853p0100* + ID_PRODUCT_FROM_DATABASE=HHKB Professional + +usb:v0854* + ID_VENDOR_FROM_DATABASE=ActiveWire, Inc. + +usb:v0854p0100* + ID_PRODUCT_FROM_DATABASE=I/O Board + +usb:v0854p0101* + ID_PRODUCT_FROM_DATABASE=I/O Board, rev1 + +usb:v0856* + ID_VENDOR_FROM_DATABASE=B&B Electronics + +usb:v0856pAC01* + ID_PRODUCT_FROM_DATABASE=uLinks USOTL4 RS422/485 Adapter + +usb:v0858* + ID_VENDOR_FROM_DATABASE=Hitachi Maxell, Ltd + +usb:v0858p3102* + ID_PRODUCT_FROM_DATABASE=Bluetooth Device + +usb:v0858pFFFF* + ID_PRODUCT_FROM_DATABASE=Maxell module with BlueCore in DFU mode + +usb:v0859* + ID_VENDOR_FROM_DATABASE=Minolta Systems Laboratory, Inc. + +usb:v085A* + ID_VENDOR_FROM_DATABASE=Xircom + +usb:v085Ap0001* + ID_PRODUCT_FROM_DATABASE=Portstation Dual Serial Port + +usb:v085Ap0003* + ID_PRODUCT_FROM_DATABASE=Portstation Paraller Port + +usb:v085Ap0008* + ID_PRODUCT_FROM_DATABASE=Ethernet + +usb:v085Ap0009* + ID_PRODUCT_FROM_DATABASE=Ethernet + +usb:v085Ap000B* + ID_PRODUCT_FROM_DATABASE=Portstation Dual PS/2 Port + +usb:v085Ap0021* + ID_PRODUCT_FROM_DATABASE=1 port to Serial Converter + +usb:v085Ap0022* + ID_PRODUCT_FROM_DATABASE=Parallel Port + +usb:v085Ap0023* + ID_PRODUCT_FROM_DATABASE=2 port to Serial Converter + +usb:v085Ap0024* + ID_PRODUCT_FROM_DATABASE=Parallel Port + +usb:v085Ap0027* + ID_PRODUCT_FROM_DATABASE=1 port to Serial Converter + +usb:v085Ap0028* + ID_PRODUCT_FROM_DATABASE=PortGear to SCSI Converter + +usb:v085Ap0032* + ID_PRODUCT_FROM_DATABASE=PortStation SCSI Module + +usb:v085Ap003C* + ID_PRODUCT_FROM_DATABASE=Bluetooth Adapter + +usb:v085Ap0299* + ID_PRODUCT_FROM_DATABASE=Colorvision, Inc. Monitor Spyder + +usb:v085Ap8021* + ID_PRODUCT_FROM_DATABASE=1 port to Serial + +usb:v085Ap8023* + ID_PRODUCT_FROM_DATABASE=2 port to Serial + +usb:v085Ap8027* + ID_PRODUCT_FROM_DATABASE=PGSDB9 Serial Port + +usb:v085C* + ID_VENDOR_FROM_DATABASE=ColorVision, Inc. + +usb:v085Cp0200* + ID_PRODUCT_FROM_DATABASE=Monitor Spyder + +usb:v0862* + ID_VENDOR_FROM_DATABASE=Teletrol Systems, Inc. + +usb:v0863* + ID_VENDOR_FROM_DATABASE=Filanet Corp. + +usb:v0864* + ID_VENDOR_FROM_DATABASE=NetGear, Inc. + +usb:v0864p4100* + ID_PRODUCT_FROM_DATABASE=MA101 802.11b Adapter + +usb:v0864p4102* + ID_PRODUCT_FROM_DATABASE=MA101 802.11b Adapter + +usb:v0867* + ID_VENDOR_FROM_DATABASE=Data Translation, Inc. + +usb:v0867p9812* + ID_PRODUCT_FROM_DATABASE=ECON Data acquisition unit + +usb:v0867p9816* + ID_PRODUCT_FROM_DATABASE=DT9816 ECON data acquisition module + +usb:v0867p9836* + ID_PRODUCT_FROM_DATABASE=DT9836 data acquisition card + +usb:v086A* + ID_VENDOR_FROM_DATABASE=Emagic Soft- und Hardware GmbH + +usb:v086Ap0001* + ID_PRODUCT_FROM_DATABASE=Unitor8 + +usb:v086Ap0002* + ID_PRODUCT_FROM_DATABASE=AMT8 + +usb:v086Ap0003* + ID_PRODUCT_FROM_DATABASE=MT4 + +usb:v086C* + ID_VENDOR_FROM_DATABASE=DeTeWe - Deutsche Telephonwerke AG & Co. + +usb:v086Cp1001* + ID_PRODUCT_FROM_DATABASE=Eumex 504PC ISDN TA + +usb:v086Cp1002* + ID_PRODUCT_FROM_DATABASE=Eumex 504PC (FlashLoad) + +usb:v086Cp1003* + ID_PRODUCT_FROM_DATABASE=TA33 ISDN TA + +usb:v086Cp1004* + ID_PRODUCT_FROM_DATABASE=TA33 (FlashLoad) + +usb:v086Cp1005* + ID_PRODUCT_FROM_DATABASE=Eumex 604PC HomeNet + +usb:v086Cp1006* + ID_PRODUCT_FROM_DATABASE=Eumex 604PC HomeNet (FlashLoad) + +usb:v086Cp1007* + ID_PRODUCT_FROM_DATABASE=Eumex 704PC DSL + +usb:v086Cp1008* + ID_PRODUCT_FROM_DATABASE=Eumex 704PC DSL (FlashLoad) + +usb:v086Cp1009* + ID_PRODUCT_FROM_DATABASE=Eumex 724PC DSL + +usb:v086Cp100A* + ID_PRODUCT_FROM_DATABASE=Eumex 724PC DSL (FlashLoad) + +usb:v086Cp100B* + ID_PRODUCT_FROM_DATABASE=OpenCom 30 + +usb:v086Cp100C* + ID_PRODUCT_FROM_DATABASE=OpenCom 30 (FlashLoad) + +usb:v086Cp100D* + ID_PRODUCT_FROM_DATABASE=BeeTel Home 100 + +usb:v086Cp100E* + ID_PRODUCT_FROM_DATABASE=BeeTel Home 100 (FlashLoad) + +usb:v086Cp1011* + ID_PRODUCT_FROM_DATABASE=USB2DECT + +usb:v086Cp1012* + ID_PRODUCT_FROM_DATABASE=USB2DECT (FlashLoad) + +usb:v086Cp1013* + ID_PRODUCT_FROM_DATABASE=Eumex 704PC LAN + +usb:v086Cp1014* + ID_PRODUCT_FROM_DATABASE=Eumex 704PC LAN (FlashLoad) + +usb:v086Cp1019* + ID_PRODUCT_FROM_DATABASE=Eumex 504 SE + +usb:v086Cp101A* + ID_PRODUCT_FROM_DATABASE=Eumex 504 SE (Flash-Mode) + +usb:v086Cp1021* + ID_PRODUCT_FROM_DATABASE=OpenCom 40 + +usb:v086Cp1022* + ID_PRODUCT_FROM_DATABASE=OpenCom 40 (FlashLoad) + +usb:v086Cp1023* + ID_PRODUCT_FROM_DATABASE=OpenCom 45 + +usb:v086Cp1024* + ID_PRODUCT_FROM_DATABASE=OpenCom 45 (FlashLoad) + +usb:v086Cp1025* + ID_PRODUCT_FROM_DATABASE=Sinus 61 data + +usb:v086Cp1029* + ID_PRODUCT_FROM_DATABASE=dect BOX + +usb:v086Cp102C* + ID_PRODUCT_FROM_DATABASE=Eumex 604PC HomeNet [FlashLoad] + +usb:v086Cp1030* + ID_PRODUCT_FROM_DATABASE=Eumex 704PC DSL [FlashLoad] + +usb:v086Cp1032* + ID_PRODUCT_FROM_DATABASE=OpenCom 40 [FlashLoad] + +usb:v086Cp1033* + ID_PRODUCT_FROM_DATABASE=OpenCom 30 plus + +usb:v086Cp1034* + ID_PRODUCT_FROM_DATABASE=OpenCom 30 plus (FlashLoad) + +usb:v086Cp1041* + ID_PRODUCT_FROM_DATABASE=Eumex 220PC + +usb:v086Cp1042* + ID_PRODUCT_FROM_DATABASE=Eumex 220PC (FlashMode) + +usb:v086Cp1055* + ID_PRODUCT_FROM_DATABASE=Eumex 220 Version 2 ISDN TA + +usb:v086Cp1056* + ID_PRODUCT_FROM_DATABASE=Eumex 220 Version 2 ISDN TA (Flash-Mode) + +usb:v086Cp2000* + ID_PRODUCT_FROM_DATABASE=OpenCom 1000 + +usb:v086E* + ID_VENDOR_FROM_DATABASE=System TALKS, Inc. + +usb:v086Ep1920* + ID_PRODUCT_FROM_DATABASE=SGC-X2UL + +usb:v086F* + ID_VENDOR_FROM_DATABASE=MEC IMEX, Inc. + +usb:v0870* + ID_VENDOR_FROM_DATABASE=Metricom + +usb:v0870p0001* + ID_PRODUCT_FROM_DATABASE=Ricochet GS + +usb:v0871* + ID_VENDOR_FROM_DATABASE=SanDisk, Inc. + +usb:v0871p0001* + ID_PRODUCT_FROM_DATABASE=SDDR-01 Compact Flash Reader + +usb:v0871p0002* + ID_PRODUCT_FROM_DATABASE=SDDR-31 Compact Flash Reader + +usb:v0871p0005* + ID_PRODUCT_FROM_DATABASE=SDDR-05 Compact Flash Reader + +usb:v0873* + ID_VENDOR_FROM_DATABASE=Xpeed, Inc. + +usb:v0874* + ID_VENDOR_FROM_DATABASE=A-Tec Subsystem, Inc. + +usb:v0879* + ID_VENDOR_FROM_DATABASE=Comtrol Corp. + +usb:v087C* + ID_VENDOR_FROM_DATABASE=Adesso/Kbtek America, Inc. + +usb:v087D* + ID_VENDOR_FROM_DATABASE=Jaton Corp. + +usb:v087Dp5704* + ID_PRODUCT_FROM_DATABASE=Ethernet + +usb:v087E* + ID_VENDOR_FROM_DATABASE=Fujitsu Computer Products of America + +usb:v087F* + ID_VENDOR_FROM_DATABASE=Virtual IP Group, Inc. + +usb:v0880* + ID_VENDOR_FROM_DATABASE=APT Technologies, Inc. + +usb:v0883* + ID_VENDOR_FROM_DATABASE=Recording Industry Association of America (RIAA) + +usb:v0885* + ID_VENDOR_FROM_DATABASE=Boca Research, Inc. + +usb:v0886* + ID_VENDOR_FROM_DATABASE=XAC Automation Corp. + +usb:v0886p0630* + ID_PRODUCT_FROM_DATABASE=Intel PC Camera CS630 + +usb:v0887* + ID_VENDOR_FROM_DATABASE=Hannstar Electronics Corp. + +usb:v088B* + ID_VENDOR_FROM_DATABASE=MassWorks, Inc. + +usb:v088Bp4944* + ID_PRODUCT_FROM_DATABASE=MassWorks ID-75 TouchScreen + +usb:v088C* + ID_VENDOR_FROM_DATABASE=Swecoin AB + +usb:v088Cp2030* + ID_PRODUCT_FROM_DATABASE=Ticket Printer TTP 2030 + +usb:v088E* + ID_VENDOR_FROM_DATABASE=iLok + +usb:v088Ep5036* + ID_PRODUCT_FROM_DATABASE=Portable secure storage for software licenses + +usb:v0892* + ID_VENDOR_FROM_DATABASE=DioGraphy, Inc. + +usb:v0892p0101* + ID_PRODUCT_FROM_DATABASE=Smartdio Reader/Writer + +usb:v0897* + ID_VENDOR_FROM_DATABASE=Lauterbach + +usb:v0897p0002* + ID_PRODUCT_FROM_DATABASE=Power Debug/Power Debug II + +usb:v089C* + ID_VENDOR_FROM_DATABASE=United Technologies Research Cntr. + +usb:v089D* + ID_VENDOR_FROM_DATABASE=Icron Technologies Corp. + +usb:v089E* + ID_VENDOR_FROM_DATABASE=NST Co., Ltd + +usb:v089F* + ID_VENDOR_FROM_DATABASE=Primex Aerospace Co. + +usb:v08A5* + ID_VENDOR_FROM_DATABASE=e9, Inc. + +usb:v08A8* + ID_VENDOR_FROM_DATABASE=Andrea Electronics + +usb:v08A9* + ID_VENDOR_FROM_DATABASE=CWAV Inc. + +usb:v08A9p0005* + ID_PRODUCT_FROM_DATABASE=USBee ZX + +usb:v08A9p0009* + ID_PRODUCT_FROM_DATABASE=USBee SX + +usb:v08A9p0012* + ID_PRODUCT_FROM_DATABASE=USBee AX-Standard + +usb:v08A9p0013* + ID_PRODUCT_FROM_DATABASE=USBee AX-Plus + +usb:v08A9p0014* + ID_PRODUCT_FROM_DATABASE=USBee AX-Pro + +usb:v08A9p0015* + ID_PRODUCT_FROM_DATABASE=USBee DX + +usb:v08AE* + ID_VENDOR_FROM_DATABASE=Macally (Mace Group, Inc.) + +usb:v08B4* + ID_VENDOR_FROM_DATABASE=Sorenson Vision, Inc. + +usb:v08B7* + ID_VENDOR_FROM_DATABASE=NATSU + +usb:v08B7p0001* + ID_PRODUCT_FROM_DATABASE=Playstation adapter + +usb:v08B8* + ID_VENDOR_FROM_DATABASE=J. Gordon Electronic Design, Inc. + +usb:v08B8p01F4* + ID_PRODUCT_FROM_DATABASE=USBSIMM1 + +usb:v08B9* + ID_VENDOR_FROM_DATABASE=RadioShack Corp. (Tandy) + +usb:v08BB* + ID_VENDOR_FROM_DATABASE=Texas Instruments Japan + +usb:v08BBp2702* + ID_PRODUCT_FROM_DATABASE=Speakers + +usb:v08BBp2704* + ID_PRODUCT_FROM_DATABASE=Audio Codec + +usb:v08BBp2900* + ID_PRODUCT_FROM_DATABASE=PCM2900 Audio Codec + +usb:v08BBp2901* + ID_PRODUCT_FROM_DATABASE=PCM2901 Audio Codec + +usb:v08BBp2902* + ID_PRODUCT_FROM_DATABASE=PCM2902 Audio Codec + +usb:v08BBp2904* + ID_PRODUCT_FROM_DATABASE=PCM2904 Audio Codec + +usb:v08BBp2910* + ID_PRODUCT_FROM_DATABASE=PCM2912 Audio Codec + +usb:v08BBp29B0* + ID_PRODUCT_FROM_DATABASE=PCM2900B Audio CODEC + +usb:v08BBp29B2* + ID_PRODUCT_FROM_DATABASE=PCM2902 Audio CODEC + +usb:v08BBp29B3* + ID_PRODUCT_FROM_DATABASE=PCM2903B Audio CODEC + +usb:v08BBp29B6* + ID_PRODUCT_FROM_DATABASE=PCM2906B Audio CODEC + +usb:v08BBp29C0* + ID_PRODUCT_FROM_DATABASE=PCM2900C Audio CODEC + +usb:v08BBp29C2* + ID_PRODUCT_FROM_DATABASE=PCM2902C Audio CODEC + +usb:v08BBp29C3* + ID_PRODUCT_FROM_DATABASE=PCM2903C Audio CODEC + +usb:v08BBp29C6* + ID_PRODUCT_FROM_DATABASE=PCM2906C Audio CODEC + +usb:v08BD* + ID_VENDOR_FROM_DATABASE=Citizen Watch Co., Ltd + +usb:v08BDp0208* + ID_PRODUCT_FROM_DATABASE=CLP-521 Label Printer + +usb:v08BDp1100* + ID_PRODUCT_FROM_DATABASE=X1-USB Floppy + +usb:v08C3* + ID_VENDOR_FROM_DATABASE=Precise Biometrics + +usb:v08C3p0001* + ID_PRODUCT_FROM_DATABASE=100 SC + +usb:v08C3p0002* + ID_PRODUCT_FROM_DATABASE=100 A + +usb:v08C3p0003* + ID_PRODUCT_FROM_DATABASE=100 SC BioKeyboard + +usb:v08C3p0006* + ID_PRODUCT_FROM_DATABASE=100 A BioKeyboard + +usb:v08C3p0100* + ID_PRODUCT_FROM_DATABASE=100 MC ISP + +usb:v08C3p0101* + ID_PRODUCT_FROM_DATABASE=100 MC FingerPrint and SmartCard Reader + +usb:v08C3p0300* + ID_PRODUCT_FROM_DATABASE=100 AX + +usb:v08C3p0400* + ID_PRODUCT_FROM_DATABASE=100 SC + +usb:v08C3p0401* + ID_PRODUCT_FROM_DATABASE=150 MC + +usb:v08C3p0402* + ID_PRODUCT_FROM_DATABASE=200 MC FingerPrint and SmartCard Reader + +usb:v08C3p0404* + ID_PRODUCT_FROM_DATABASE=100 SC Upgrade + +usb:v08C3p0405* + ID_PRODUCT_FROM_DATABASE=150 MC Upgrade + +usb:v08C3p0406* + ID_PRODUCT_FROM_DATABASE=100 MC Upgrade + +usb:v08C4* + ID_VENDOR_FROM_DATABASE=Proxim, Inc. + +usb:v08C4p0100* + ID_PRODUCT_FROM_DATABASE=Skyline 802.11b Wireless Adapter + +usb:v08C4p02F2* + ID_PRODUCT_FROM_DATABASE=Farallon Home Phoneline Adapter + +usb:v08C7* + ID_VENDOR_FROM_DATABASE=Key Nice Enterprise Co., Ltd + +usb:v08C8* + ID_VENDOR_FROM_DATABASE=2Wire, Inc. + +usb:v08C9* + ID_VENDOR_FROM_DATABASE=Nippon Telegraph and Telephone Corp. + +usb:v08CA* + ID_VENDOR_FROM_DATABASE=Aiptek International, Inc. + +usb:v08CAp0001* + ID_PRODUCT_FROM_DATABASE=Tablet + +usb:v08CAp0010* + ID_PRODUCT_FROM_DATABASE=Tablet + +usb:v08CAp0020* + ID_PRODUCT_FROM_DATABASE=APT-6000U Tablet + +usb:v08CAp0021* + ID_PRODUCT_FROM_DATABASE=APT-2 Tablet + +usb:v08CAp0022* + ID_PRODUCT_FROM_DATABASE=Tablet + +usb:v08CAp0023* + ID_PRODUCT_FROM_DATABASE=Tablet + +usb:v08CAp0024* + ID_PRODUCT_FROM_DATABASE=Tablet + +usb:v08CAp0100* + ID_PRODUCT_FROM_DATABASE=Pen Drive + +usb:v08CAp0102* + ID_PRODUCT_FROM_DATABASE=DualCam + +usb:v08CAp0103* + ID_PRODUCT_FROM_DATABASE=Pocket DV Digital Camera + +usb:v08CAp0104* + ID_PRODUCT_FROM_DATABASE=Pocket DVII + +usb:v08CAp0105* + ID_PRODUCT_FROM_DATABASE=Mega DV(Disk) + +usb:v08CAp0106* + ID_PRODUCT_FROM_DATABASE=Pocket DV3100+ + +usb:v08CAp0107* + ID_PRODUCT_FROM_DATABASE=Pocket DV3100 + +usb:v08CAp0109* + ID_PRODUCT_FROM_DATABASE=Nisis DV4 Digital Camera + +usb:v08CAp010A* + ID_PRODUCT_FROM_DATABASE=Trust 738AV LCD PV Mass Storage + +usb:v08CAp0111* + ID_PRODUCT_FROM_DATABASE=PenCam VGA Plus + +usb:v08CAp2008* + ID_PRODUCT_FROM_DATABASE=Mini PenCam 2 + +usb:v08CAp2010* + ID_PRODUCT_FROM_DATABASE=Pocket CAM 3 Mega (webcam) + +usb:v08CAp2011* + ID_PRODUCT_FROM_DATABASE=Pocket CAM 3 Mega (storage) + +usb:v08CAp2016* + ID_PRODUCT_FROM_DATABASE=PocketCam 2 Mega + +usb:v08CAp2018* + ID_PRODUCT_FROM_DATABASE=Pencam SD 2M + +usb:v08CAp2020* + ID_PRODUCT_FROM_DATABASE=Slim 3000F + +usb:v08CAp2022* + ID_PRODUCT_FROM_DATABASE=Slim 3200 + +usb:v08CAp2024* + ID_PRODUCT_FROM_DATABASE=Pocket DV3500 + +usb:v08CAp2028* + ID_PRODUCT_FROM_DATABASE=Pocket Cam4M + +usb:v08CAp2040* + ID_PRODUCT_FROM_DATABASE=Pocket DV4100M + +usb:v08CAp2042* + ID_PRODUCT_FROM_DATABASE=Pocket DV5100M Composite Device + +usb:v08CAp2043* + ID_PRODUCT_FROM_DATABASE=Pocket DV5100M (Disk) + +usb:v08CAp2060* + ID_PRODUCT_FROM_DATABASE=Pocket DV5300 + +usb:v08CD* + ID_VENDOR_FROM_DATABASE=Jue Hsun Ind. Corp. + +usb:v08CE* + ID_VENDOR_FROM_DATABASE=Long Well Electronics Corp. + +usb:v08CF* + ID_VENDOR_FROM_DATABASE=Productivity Enhancement Products + +usb:v08D1* + ID_VENDOR_FROM_DATABASE=smartBridges, Inc. + +usb:v08D1p0001* + ID_PRODUCT_FROM_DATABASE=smartNIC Ethernet [catc] + +usb:v08D1p0003* + ID_PRODUCT_FROM_DATABASE=smartNIC 2 PnP Ethernet + +usb:v08D3* + ID_VENDOR_FROM_DATABASE=Virtual Ink + +usb:v08D4* + ID_VENDOR_FROM_DATABASE=Fujitsu Siemens Computers + +usb:v08D4p0009* + ID_PRODUCT_FROM_DATABASE=SCR SmartCard Reader + +usb:v08D8* + ID_VENDOR_FROM_DATABASE=IXXAT Automation GmbH + +usb:v08D8p0002* + ID_PRODUCT_FROM_DATABASE=USB-to-CAN compact + +usb:v08D8p0003* + ID_PRODUCT_FROM_DATABASE=USB-to-CAN II + +usb:v08D8p0100* + ID_PRODUCT_FROM_DATABASE=USB-to-CAN + +usb:v08D9* + ID_VENDOR_FROM_DATABASE=Increment P Corp. + +usb:v08DD* + ID_VENDOR_FROM_DATABASE=Billionton Systems, Inc. + +usb:v08DDp0112* + ID_PRODUCT_FROM_DATABASE=Wireless LAN Adapter + +usb:v08DDp0113* + ID_PRODUCT_FROM_DATABASE=Wireless LAN Adapter + +usb:v08DDp0986* + ID_PRODUCT_FROM_DATABASE=USB-100N Ethernet [pegasus] + +usb:v08DDp0987* + ID_PRODUCT_FROM_DATABASE=USBLP-100 HomePNA Ethernet [pegasus] + +usb:v08DDp0988* + ID_PRODUCT_FROM_DATABASE=USBEL-100 Ethernet [pegasus] + +usb:v08DDp1986* + ID_PRODUCT_FROM_DATABASE=10/100 LAN Adapter + +usb:v08DDp2103* + ID_PRODUCT_FROM_DATABASE=DVB-T TV-Tuner Card-R + +usb:v08DDp8511* + ID_PRODUCT_FROM_DATABASE=USBE-100 Ethernet [pegasus2] + +usb:v08DDp90FF* + ID_PRODUCT_FROM_DATABASE=USB2AR Ethernet + +usb:v08DE* + ID_VENDOR_FROM_DATABASE=??? + +usb:v08DEp7A01* + ID_PRODUCT_FROM_DATABASE=802.11b Adapter + +usb:v08DF* + ID_VENDOR_FROM_DATABASE=Spyrus, Inc. + +usb:v08DFp0001* + ID_PRODUCT_FROM_DATABASE=Rosetta Token V1 + +usb:v08DFp0002* + ID_PRODUCT_FROM_DATABASE=Rosetta Token V2 + +usb:v08DFp0003* + ID_PRODUCT_FROM_DATABASE=Rosetta Token V3 + +usb:v08DFp0A00* + ID_PRODUCT_FROM_DATABASE=Lynks Interface + +usb:v08E3* + ID_VENDOR_FROM_DATABASE=Olitec, Inc. + +usb:v08E3p0002* + ID_PRODUCT_FROM_DATABASE=USB-RS232 Bridge + +usb:v08E3p0100* + ID_PRODUCT_FROM_DATABASE=Interface ADSL + +usb:v08E3p0101* + ID_PRODUCT_FROM_DATABASE=Interface ADSL + +usb:v08E3p0102* + ID_PRODUCT_FROM_DATABASE=ADSL + +usb:v08E3p0301* + ID_PRODUCT_FROM_DATABASE=RNIS + +usb:v08E4* + ID_VENDOR_FROM_DATABASE=Pioneer Corp. + +usb:v08E5* + ID_VENDOR_FROM_DATABASE=Litronic + +usb:v08E6* + ID_VENDOR_FROM_DATABASE=Gemplus + +usb:v08E6p0001* + ID_PRODUCT_FROM_DATABASE=GemPC-Touch 430 + +usb:v08E6p0430* + ID_PRODUCT_FROM_DATABASE=GemPC430 SmartCard Reader + +usb:v08E6p0432* + ID_PRODUCT_FROM_DATABASE=GemPC432 SmartCard Reader + +usb:v08E6p0435* + ID_PRODUCT_FROM_DATABASE=GemPC435 SmartCard Reader + +usb:v08E6p0437* + ID_PRODUCT_FROM_DATABASE=GemPC433 SL SmartCard Reader + +usb:v08E6p1359* + ID_PRODUCT_FROM_DATABASE=UA SECURE STORAGE TOKEN + +usb:v08E6p2202* + ID_PRODUCT_FROM_DATABASE=Gem e-Seal Pro Token + +usb:v08E6p3437* + ID_PRODUCT_FROM_DATABASE=GemPC Twin SmartCard Reader + +usb:v08E6p3438* + ID_PRODUCT_FROM_DATABASE=GemPC Key SmartCard Reader + +usb:v08E6p3478* + ID_PRODUCT_FROM_DATABASE=PinPad Smart Card Reader + +usb:v08E6p4433* + ID_PRODUCT_FROM_DATABASE=GemPC433-Swap + +usb:v08E6p5501* + ID_PRODUCT_FROM_DATABASE=GemProx-PU Contactless Smart Card Reader + +usb:v08E6pACE0* + ID_PRODUCT_FROM_DATABASE=UA HYBRID TOKEN + +usb:v08E7* + ID_VENDOR_FROM_DATABASE=Pan-International Wire & Cable + +usb:v08E8* + ID_VENDOR_FROM_DATABASE=Integrated Memory Logic + +usb:v08E9* + ID_VENDOR_FROM_DATABASE=Extended Systems, Inc. + +usb:v08E9p0100* + ID_PRODUCT_FROM_DATABASE=XTNDAccess IrDA Dongle + +usb:v08EA* + ID_VENDOR_FROM_DATABASE=Ericsson, Inc., Blue Ridge Labs + +usb:v08EAp00C9* + ID_PRODUCT_FROM_DATABASE=ADSL Modem HM120dp Loader + +usb:v08EAp00CA* + ID_PRODUCT_FROM_DATABASE=ADSL WAN Modem HM120dp + +usb:v08EAp00CE* + ID_PRODUCT_FROM_DATABASE=HM230d Virtual Bus for Helium + +usb:v08EApABBA* + ID_PRODUCT_FROM_DATABASE=USB Driver for Bluetooth Wireless Technology + +usb:v08EApABBB* + ID_PRODUCT_FROM_DATABASE=Bluetooth Device in DFU State + +usb:v08EC* + ID_VENDOR_FROM_DATABASE=M-Systems Flash Disk Pioneers + +usb:v08ECp0001* + ID_PRODUCT_FROM_DATABASE=TravelDrive 2C + +usb:v08ECp0002* + ID_PRODUCT_FROM_DATABASE=TravelDrive 2C + +usb:v08ECp0005* + ID_PRODUCT_FROM_DATABASE=TravelDrive 2C + +usb:v08ECp0008* + ID_PRODUCT_FROM_DATABASE=TravelDrive 2C + +usb:v08ECp0010* + ID_PRODUCT_FROM_DATABASE=DiskOnKey + +usb:v08ECp0011* + ID_PRODUCT_FROM_DATABASE=DiskOnKey + +usb:v08ECp0012* + ID_PRODUCT_FROM_DATABASE=TravelDrive 2C + +usb:v08ECp0014* + ID_PRODUCT_FROM_DATABASE=TravelDrive 2C + +usb:v08ECp0015* + ID_PRODUCT_FROM_DATABASE=Kingston DataTraveler ELITE + +usb:v08ECp0016* + ID_PRODUCT_FROM_DATABASE=Kingston DataTraveler U3 + +usb:v08ECp0020* + ID_PRODUCT_FROM_DATABASE=TravelDrive + +usb:v08ECp0021* + ID_PRODUCT_FROM_DATABASE=TravelDrive + +usb:v08ECp0022* + ID_PRODUCT_FROM_DATABASE=TravelDrive + +usb:v08ECp0023* + ID_PRODUCT_FROM_DATABASE=TravelDrive + +usb:v08ECp0024* + ID_PRODUCT_FROM_DATABASE=TravelDrive + +usb:v08ECp0025* + ID_PRODUCT_FROM_DATABASE=TravelDrive + +usb:v08ECp0026* + ID_PRODUCT_FROM_DATABASE=TravelDrive + +usb:v08ECp0027* + ID_PRODUCT_FROM_DATABASE=TravelDrive + +usb:v08ECp0028* + ID_PRODUCT_FROM_DATABASE=TravelDrive + +usb:v08ECp0029* + ID_PRODUCT_FROM_DATABASE=TravelDrive + +usb:v08ECp0030* + ID_PRODUCT_FROM_DATABASE=TravelDrive + +usb:v08ECp0822* + ID_PRODUCT_FROM_DATABASE=TravelDrive 2C + +usb:v08ECp0832* + ID_PRODUCT_FROM_DATABASE=Hi-Speed Mass Storage Device + +usb:v08ECp0834* + ID_PRODUCT_FROM_DATABASE=M-Disk 220 + +usb:v08ECp0998* + ID_PRODUCT_FROM_DATABASE=Kingston Data Traveler2.0 Disk Driver + +usb:v08ECp0999* + ID_PRODUCT_FROM_DATABASE=Kingston Data Traveler2.0 Disk Driver + +usb:v08ECp1000* + ID_PRODUCT_FROM_DATABASE=TravelDrive 2C + +usb:v08ECp2000* + ID_PRODUCT_FROM_DATABASE=TravelDrive 2C + +usb:v08ECp2038* + ID_PRODUCT_FROM_DATABASE=TravelDrive + +usb:v08ECp2039* + ID_PRODUCT_FROM_DATABASE=TravelDrive + +usb:v08ECp204A* + ID_PRODUCT_FROM_DATABASE=TravelDrive + +usb:v08ECp204B* + ID_PRODUCT_FROM_DATABASE=TravelDrive + +usb:v08ED* + ID_VENDOR_FROM_DATABASE=MediaTek Inc. + +usb:v08EDp0002* + ID_PRODUCT_FROM_DATABASE=CECT M800 memory card + +usb:v08EE* + ID_VENDOR_FROM_DATABASE=CCSI/Hesso + +usb:v08F0* + ID_VENDOR_FROM_DATABASE=Corex Technologies + +usb:v08F1* + ID_VENDOR_FROM_DATABASE=CTI Electronics Corp. + +usb:v08F2* + ID_VENDOR_FROM_DATABASE=Gotop Information Inc. + +usb:v08F2p007F* + ID_PRODUCT_FROM_DATABASE=Super Q2 Tablet + +usb:v08F5* + ID_VENDOR_FROM_DATABASE=SysTec Co., Ltd + +usb:v08F6* + ID_VENDOR_FROM_DATABASE=Logic 3 International, Ltd + +usb:v08F7* + ID_VENDOR_FROM_DATABASE=Vernier + +usb:v08F7p0001* + ID_PRODUCT_FROM_DATABASE=LabPro + +usb:v08F7p0002* + ID_PRODUCT_FROM_DATABASE=EasyTemp/Go!Temp + +usb:v08F7p0003* + ID_PRODUCT_FROM_DATABASE=Go!Link + +usb:v08F7p0004* + ID_PRODUCT_FROM_DATABASE=Go!Motion + +usb:v08F8* + ID_VENDOR_FROM_DATABASE=Keen Top International Enterprise Co., Ltd + +usb:v08F9* + ID_VENDOR_FROM_DATABASE=Wipro Technologies + +usb:v08FA* + ID_VENDOR_FROM_DATABASE=Caere + +usb:v08FB* + ID_VENDOR_FROM_DATABASE=Socket Communications + +usb:v08FC* + ID_VENDOR_FROM_DATABASE=Sicon Cable Technology Co., Ltd + +usb:v08FD* + ID_VENDOR_FROM_DATABASE=Digianswer A/S + +usb:v08FDp0001* + ID_PRODUCT_FROM_DATABASE=Bluetooth Device + +usb:v08FF* + ID_VENDOR_FROM_DATABASE=AuthenTec, Inc. + +usb:v08FFp1600* + ID_PRODUCT_FROM_DATABASE=AES1600 + +usb:v08FFp1610* + ID_PRODUCT_FROM_DATABASE=AES1600 + +usb:v08FFp1660* + ID_PRODUCT_FROM_DATABASE=AES1660 Fingerprint Sensor + +usb:v08FFp1680* + ID_PRODUCT_FROM_DATABASE=AES1660 Fingerprint Sensor + +usb:v08FFp168F* + ID_PRODUCT_FROM_DATABASE=AES1660 Fingerprint Sensor + +usb:v08FFp2500* + ID_PRODUCT_FROM_DATABASE=AES2501 + +usb:v08FFp2501* + ID_PRODUCT_FROM_DATABASE=AES2501 + +usb:v08FFp2502* + ID_PRODUCT_FROM_DATABASE=AES2501 + +usb:v08FFp2503* + ID_PRODUCT_FROM_DATABASE=AES2501 + +usb:v08FFp2504* + ID_PRODUCT_FROM_DATABASE=AES2501 + +usb:v08FFp2505* + ID_PRODUCT_FROM_DATABASE=AES2501 + +usb:v08FFp2506* + ID_PRODUCT_FROM_DATABASE=AES2501 + +usb:v08FFp2507* + ID_PRODUCT_FROM_DATABASE=AES2501 + +usb:v08FFp2508* + ID_PRODUCT_FROM_DATABASE=AES2501 + +usb:v08FFp2509* + ID_PRODUCT_FROM_DATABASE=AES2501 + +usb:v08FFp250A* + ID_PRODUCT_FROM_DATABASE=AES2501 + +usb:v08FFp250B* + ID_PRODUCT_FROM_DATABASE=AES2501 + +usb:v08FFp250C* + ID_PRODUCT_FROM_DATABASE=AES2501 + +usb:v08FFp250D* + ID_PRODUCT_FROM_DATABASE=AES2501 + +usb:v08FFp250E* + ID_PRODUCT_FROM_DATABASE=AES2501 + +usb:v08FFp250F* + ID_PRODUCT_FROM_DATABASE=AES2501 + +usb:v08FFp2510* + ID_PRODUCT_FROM_DATABASE=AES2510 + +usb:v08FFp2550* + ID_PRODUCT_FROM_DATABASE=AES2550 Fingerprint Sensor + +usb:v08FFp2580* + ID_PRODUCT_FROM_DATABASE=AES2501 Fingerprint Sensor + +usb:v08FFp2588* + ID_PRODUCT_FROM_DATABASE=AES2501 + +usb:v08FFp2589* + ID_PRODUCT_FROM_DATABASE=AES2501 + +usb:v08FFp258A* + ID_PRODUCT_FROM_DATABASE=AES2501 + +usb:v08FFp258B* + ID_PRODUCT_FROM_DATABASE=AES2501 + +usb:v08FFp258C* + ID_PRODUCT_FROM_DATABASE=AES2501 + +usb:v08FFp258D* + ID_PRODUCT_FROM_DATABASE=AES2501 + +usb:v08FFp258E* + ID_PRODUCT_FROM_DATABASE=AES2501 + +usb:v08FFp258F* + ID_PRODUCT_FROM_DATABASE=AES2501 + +usb:v08FFp2660* + ID_PRODUCT_FROM_DATABASE=AES2660 Fingerprint Sensor + +usb:v08FFp2680* + ID_PRODUCT_FROM_DATABASE=AES2660 Fingerprint Sensor + +usb:v08FFp268F* + ID_PRODUCT_FROM_DATABASE=AES2660 Fingerprint Sensor + +usb:v08FFp2810* + ID_PRODUCT_FROM_DATABASE=AES2810 + +usb:v08FFp3400* + ID_PRODUCT_FROM_DATABASE=AES3400 TruePrint Sensor + +usb:v08FFp3401* + ID_PRODUCT_FROM_DATABASE=AES3400 Sensor + +usb:v08FFp3402* + ID_PRODUCT_FROM_DATABASE=AES3400 Sensor + +usb:v08FFp3403* + ID_PRODUCT_FROM_DATABASE=AES3400 Sensor + +usb:v08FFp3404* + ID_PRODUCT_FROM_DATABASE=AES3400 TruePrint Sensor + +usb:v08FFp3405* + ID_PRODUCT_FROM_DATABASE=AES3400 TruePrint Sensor + +usb:v08FFp3406* + ID_PRODUCT_FROM_DATABASE=AES3400 TruePrint Sensor + +usb:v08FFp3407* + ID_PRODUCT_FROM_DATABASE=AES3400 TruePrint Sensor + +usb:v08FFp4902* + ID_PRODUCT_FROM_DATABASE=BioMV with TruePrint AES3500 + +usb:v08FFp4903* + ID_PRODUCT_FROM_DATABASE=BioMV with TruePrint AES3400 + +usb:v08FFp5500* + ID_PRODUCT_FROM_DATABASE=AES4000 + +usb:v08FFp5501* + ID_PRODUCT_FROM_DATABASE=AES4000 TruePrint Sensor + +usb:v08FFp5503* + ID_PRODUCT_FROM_DATABASE=AES4000 TruePrint Sensor + +usb:v08FFp5505* + ID_PRODUCT_FROM_DATABASE=AES4000 TruePrint Sensor + +usb:v08FFp5507* + ID_PRODUCT_FROM_DATABASE=AES4000 TruePrint Sensor + +usb:v08FFp55FF* + ID_PRODUCT_FROM_DATABASE=AES4000 TruePrint Sensor. + +usb:v08FFp5700* + ID_PRODUCT_FROM_DATABASE=AES3500 Fingerprint Reader + +usb:v08FFp5701* + ID_PRODUCT_FROM_DATABASE=AES3500 TruePrint Sensor + +usb:v08FFp5702* + ID_PRODUCT_FROM_DATABASE=AES3500 TruePrint Sensor + +usb:v08FFp5703* + ID_PRODUCT_FROM_DATABASE=AES3500 TruePrint Sensor + +usb:v08FFp5704* + ID_PRODUCT_FROM_DATABASE=AES3500-BZ TruePrint Sensor + +usb:v08FFp5705* + ID_PRODUCT_FROM_DATABASE=AES3500-BZ TruePrint Sensor + +usb:v08FFp5706* + ID_PRODUCT_FROM_DATABASE=AES3500-BZ TruePrint Sensor + +usb:v08FFp5707* + ID_PRODUCT_FROM_DATABASE=AES3500-BZ TruePrint Sensor + +usb:v08FFp5710* + ID_PRODUCT_FROM_DATABASE=AES3500 TruePrint Sensor + +usb:v08FFp5711* + ID_PRODUCT_FROM_DATABASE=AES3500 TruePrint Sensor + +usb:v08FFp5712* + ID_PRODUCT_FROM_DATABASE=AES3500 TruePrint Sensor + +usb:v08FFp5713* + ID_PRODUCT_FROM_DATABASE=AES3500 TruePrint Sensor + +usb:v08FFp5714* + ID_PRODUCT_FROM_DATABASE=AES3500-BZ TruePrint Sensor + +usb:v08FFp5715* + ID_PRODUCT_FROM_DATABASE=AES3500-BZ TruePrint Sensor + +usb:v08FFp5716* + ID_PRODUCT_FROM_DATABASE=AES3500-BZ TruePrint Sensor + +usb:v08FFp5717* + ID_PRODUCT_FROM_DATABASE=AES3500-BZ TruePrint Sensor + +usb:v08FFp5730* + ID_PRODUCT_FROM_DATABASE=AES3500 TruePrint Sensor + +usb:v08FFp5731* + ID_PRODUCT_FROM_DATABASE=AES3500 TruePrint Sensor + +usb:v08FFp5732* + ID_PRODUCT_FROM_DATABASE=AES3500 TruePrint Sensor + +usb:v08FFp5733* + ID_PRODUCT_FROM_DATABASE=AES3500 TruePrint Sensor + +usb:v08FFp5734* + ID_PRODUCT_FROM_DATABASE=AES3500-BZ TruePrint Sensor + +usb:v08FFp5735* + ID_PRODUCT_FROM_DATABASE=AES3500-BZ TruePrint Sensor + +usb:v08FFp5736* + ID_PRODUCT_FROM_DATABASE=AES3500-BZ TruePrint Sensor + +usb:v08FFp5737* + ID_PRODUCT_FROM_DATABASE=AES3500-BZ TruePrint Sensor + +usb:v08FFpAFE3* + ID_PRODUCT_FROM_DATABASE=FingerLoc Sensor Module (Anchor) + +usb:v08FFpAFE4* + ID_PRODUCT_FROM_DATABASE=FingerLoc Sensor Module (Anchor) + +usb:v08FFpAFE5* + ID_PRODUCT_FROM_DATABASE=FingerLoc Sensor Module (Anchor) + +usb:v08FFpAFE6* + ID_PRODUCT_FROM_DATABASE=FingerLoc Sensor Module (Anchor) + +usb:v08FFpFFFD* + ID_PRODUCT_FROM_DATABASE=AES2510 Sensor (USB Emulator) + +usb:v08FFpFFFF* + ID_PRODUCT_FROM_DATABASE=Sensor (Emulator) + +usb:v0900* + ID_VENDOR_FROM_DATABASE=Pinnacle Systems, Inc. + +usb:v0901* + ID_VENDOR_FROM_DATABASE=VST Technologies + +usb:v0901p0001* + ID_PRODUCT_FROM_DATABASE=Hard Drive Adapter (TPP) + +usb:v0901p0002* + ID_PRODUCT_FROM_DATABASE=SigmaDrive Adapter (TPP) + +usb:v0906* + ID_VENDOR_FROM_DATABASE=Faraday Technology Corp. + +usb:v0908* + ID_VENDOR_FROM_DATABASE=ShenZhen SANZHAI Technology Co.,Ltd + +usb:v0908p2701* + ID_PRODUCT_FROM_DATABASE=Spy Pen VGA + +usb:v0909* + ID_VENDOR_FROM_DATABASE=Audio-Technica Corp. + +usb:v090A* + ID_VENDOR_FROM_DATABASE=Trumpion Microelectronics, Inc. + +usb:v090Ap1001* + ID_PRODUCT_FROM_DATABASE=T33520 Flash Card Controller + +usb:v090Ap1100* + ID_PRODUCT_FROM_DATABASE=Comotron C3310 MP3 player + +usb:v090Ap1200* + ID_PRODUCT_FROM_DATABASE=MP3 player + +usb:v090Ap1540* + ID_PRODUCT_FROM_DATABASE=Digitex Container Flash Disk + +usb:v090B* + ID_VENDOR_FROM_DATABASE=Neurosmith + +usb:v090C* + ID_VENDOR_FROM_DATABASE=Silicon Motion, Inc. - Taiwan (formerly Feiya Technology Corp.) + +usb:v090Cp0371* + ID_PRODUCT_FROM_DATABASE=Silicon Motion SM371 Camera + +usb:v090Cp0373* + ID_PRODUCT_FROM_DATABASE=Silicon Motion Camera + +usb:v090Cp037A* + ID_PRODUCT_FROM_DATABASE=Silicon Motion Camera + +usb:v090Cp037B* + ID_PRODUCT_FROM_DATABASE=Silicon Motion Camera + +usb:v090Cp1000* + ID_PRODUCT_FROM_DATABASE=Flash Drive + +usb:v090Cp1132* + ID_PRODUCT_FROM_DATABASE=5-in-1 Card Reader + +usb:v090Cp337B* + ID_PRODUCT_FROM_DATABASE=Silicon Motion Camera + +usb:v090Cp3710* + ID_PRODUCT_FROM_DATABASE=Silicon Motion Camera + +usb:v090Cp3720* + ID_PRODUCT_FROM_DATABASE=Silicon Motion Camera + +usb:v090Cp37BC* + ID_PRODUCT_FROM_DATABASE=HP Webcam-101 Integrated Camera + +usb:v090Cp37C0* + ID_PRODUCT_FROM_DATABASE=Silicon Motion Camera + +usb:v090Cp6000* + ID_PRODUCT_FROM_DATABASE=SD/SDHC Card Reader (SG365 / FlexiDrive XC+) + +usb:v090Cp6200* + ID_PRODUCT_FROM_DATABASE=microSD card reader + +usb:v090Cp71B3* + ID_PRODUCT_FROM_DATABASE=SM731 Camera + +usb:v090Cp837B* + ID_PRODUCT_FROM_DATABASE=Silicon Motion Camera + +usb:v090Cp937B* + ID_PRODUCT_FROM_DATABASE=Silicon Motion Camera + +usb:v090CpB370* + ID_PRODUCT_FROM_DATABASE=Silicon Motion SM370 Camera + +usb:v090CpB371* + ID_PRODUCT_FROM_DATABASE=Silicon Motion SM371 Camera + +usb:v090D* + ID_VENDOR_FROM_DATABASE=Multiport Computer Vertriebs GmbH + +usb:v090E* + ID_VENDOR_FROM_DATABASE=Shining Technology, Inc. + +usb:v090F* + ID_VENDOR_FROM_DATABASE=Fujitsu Devices, Inc. + +usb:v0910* + ID_VENDOR_FROM_DATABASE=Alation Systems, Inc. + +usb:v0911* + ID_VENDOR_FROM_DATABASE=Philips Speech Processing + +usb:v0911p149A* + ID_PRODUCT_FROM_DATABASE=SpeechMike II Pro Plus LFH5276 + +usb:v0911p2512* + ID_PRODUCT_FROM_DATABASE=SpeechMike Pro + +usb:v0912* + ID_VENDOR_FROM_DATABASE=Voquette, Inc. + +usb:v0915* + ID_VENDOR_FROM_DATABASE=GlobeSpan, Inc. + +usb:v0915p0001* + ID_PRODUCT_FROM_DATABASE=DSL Modem + +usb:v0915p0002* + ID_PRODUCT_FROM_DATABASE=ADSL ATM Modem + +usb:v0915p0005* + ID_PRODUCT_FROM_DATABASE=LAN Modem + +usb:v0915p2000* + ID_PRODUCT_FROM_DATABASE=802.11 Adapter + +usb:v0915p2002* + ID_PRODUCT_FROM_DATABASE=802.11 Adapter + +usb:v0915p8000* + ID_PRODUCT_FROM_DATABASE=ADSL LAN Modem + +usb:v0915p8005* + ID_PRODUCT_FROM_DATABASE=DSL-302G Modem + +usb:v0915p8101* + ID_PRODUCT_FROM_DATABASE=ADSL WAN Modem + +usb:v0915p8102* + ID_PRODUCT_FROM_DATABASE=DSL-200 ADSL Modem + +usb:v0915p8103* + ID_PRODUCT_FROM_DATABASE=DSL-200 ADSL Modem + +usb:v0915p8104* + ID_PRODUCT_FROM_DATABASE=DSL-200 Modem + +usb:v0915p8400* + ID_PRODUCT_FROM_DATABASE=DSL Modem + +usb:v0915p8401* + ID_PRODUCT_FROM_DATABASE=DSL Modem + +usb:v0915p8402* + ID_PRODUCT_FROM_DATABASE=DSL Modem + +usb:v0915p8500* + ID_PRODUCT_FROM_DATABASE=DSL Modem + +usb:v0915p8501* + ID_PRODUCT_FROM_DATABASE=DSL Modem + +usb:v0917* + ID_VENDOR_FROM_DATABASE=SmartDisk Corp. + +usb:v0917p0001* + ID_PRODUCT_FROM_DATABASE=eFilm Reader-11 SM/CF + +usb:v0917p0002* + ID_PRODUCT_FROM_DATABASE=eFilm Reader-11 SM + +usb:v0917p0003* + ID_PRODUCT_FROM_DATABASE=eFilm Reader-11 CF + +usb:v0917p0200* + ID_PRODUCT_FROM_DATABASE=FireFly + +usb:v0917p0201* + ID_PRODUCT_FROM_DATABASE=FireLite + +usb:v0917p0202* + ID_PRODUCT_FROM_DATABASE=STORAGE ADAPTER (FirePower) + +usb:v0917p0204* + ID_PRODUCT_FROM_DATABASE=FlashTrax Storage + +usb:v0917p0205* + ID_PRODUCT_FROM_DATABASE=STORAGE ADAPTER (CrossFire) + +usb:v0917p0206* + ID_PRODUCT_FROM_DATABASE=FireFly 20G HDD + +usb:v0917p0207* + ID_PRODUCT_FROM_DATABASE=FireLite + +usb:v0917p020F* + ID_PRODUCT_FROM_DATABASE=STORAGE ADAPTER (FireLite) + +usb:v0917pDA01* + ID_PRODUCT_FROM_DATABASE=eFilm Reader-11 Test + +usb:v0917pFFFF* + ID_PRODUCT_FROM_DATABASE=eFilm Reader-11 (Class/PDR) + +usb:v0919* + ID_VENDOR_FROM_DATABASE=Tiger Electronics + +usb:v0919p0100* + ID_PRODUCT_FROM_DATABASE=Fast Flicks Digital Camera + +usb:v091E* + ID_VENDOR_FROM_DATABASE=Garmin International + +usb:v091Ep0003* + ID_PRODUCT_FROM_DATABASE=GPS (various models) + +usb:v091Ep0004* + ID_PRODUCT_FROM_DATABASE=iQue 3600 + +usb:v091Ep0200* + ID_PRODUCT_FROM_DATABASE=Data Card Programmer (install) + +usb:v091Ep1200* + ID_PRODUCT_FROM_DATABASE=Data Card Programmer + +usb:v091Ep21A5* + ID_PRODUCT_FROM_DATABASE=etrex Cx (msc) + +usb:v091Ep2236* + ID_PRODUCT_FROM_DATABASE=nuvi 360 + +usb:v091Ep2271* + ID_PRODUCT_FROM_DATABASE=Edge 605/705 + +usb:v091Ep2295* + ID_PRODUCT_FROM_DATABASE=Colorado 300 + +usb:v091Ep22B6* + ID_PRODUCT_FROM_DATABASE=eTrex Vista HCx (Mass Storage mode) + +usb:v091Ep231B* + ID_PRODUCT_FROM_DATABASE=Oregon 400t + +usb:v091Ep2353* + ID_PRODUCT_FROM_DATABASE=Nüvi 205T + +usb:v091Ep2380* + ID_PRODUCT_FROM_DATABASE=Oregon series + +usb:v091Ep23CC* + ID_PRODUCT_FROM_DATABASE=nüvi 1350 + +usb:v091Ep2459* + ID_PRODUCT_FROM_DATABASE=GPSmap 62/78 series + +usb:v091Ep2519* + ID_PRODUCT_FROM_DATABASE=eTrex 30 + +usb:v091Ep2535* + ID_PRODUCT_FROM_DATABASE=Edge 800 + +usb:v091Ep255B* + ID_PRODUCT_FROM_DATABASE=Nuvi 2505LM + +usb:v0920* + ID_VENDOR_FROM_DATABASE=Echelon Co. + +usb:v0920p7500* + ID_PRODUCT_FROM_DATABASE=Network Interface + +usb:v0921* + ID_VENDOR_FROM_DATABASE=GoHubs, Inc. + +usb:v0921p1001* + ID_PRODUCT_FROM_DATABASE=GoCOM232 Serial + +usb:v0922* + ID_VENDOR_FROM_DATABASE=Dymo-CoStar Corp. + +usb:v0922p0007* + ID_PRODUCT_FROM_DATABASE=LabelWriter 330 + +usb:v0922p0009* + ID_PRODUCT_FROM_DATABASE=LabelWriter 310 + +usb:v0922p001A* + ID_PRODUCT_FROM_DATABASE=LabelWriter 400 Turbo + +usb:v0922p0020* + ID_PRODUCT_FROM_DATABASE=LabelWriter 450 + +usb:v0923* + ID_VENDOR_FROM_DATABASE=IC Media Corp. + +usb:v0923p010F* + ID_PRODUCT_FROM_DATABASE=SIIG MobileCam + +usb:v0924* + ID_VENDOR_FROM_DATABASE=Xerox + +usb:v0924p23DD* + ID_PRODUCT_FROM_DATABASE=DocuPrint M760 (X760_USB) + +usb:v0924p3CE8* + ID_PRODUCT_FROM_DATABASE=Phaser 3428 Printer + +usb:v0924p3D5B* + ID_PRODUCT_FROM_DATABASE=Phaser 6115MFP TWAIN Scanner + +usb:v0924p420F* + ID_PRODUCT_FROM_DATABASE=WorkCentre PE220 Series + +usb:v0924p421F* + ID_PRODUCT_FROM_DATABASE=M20 Scanner + +usb:v0924p423B* + ID_PRODUCT_FROM_DATABASE=Printing Support + +usb:v0924p4274* + ID_PRODUCT_FROM_DATABASE=Xerox Phaser 3635MFPX + +usb:v0924pFFEF* + ID_PRODUCT_FROM_DATABASE=WorkCenter M15 + +usb:v0924pFFFB* + ID_PRODUCT_FROM_DATABASE=DocuPrint M750 (X750_USB) + +usb:v0925* + ID_VENDOR_FROM_DATABASE=Lakeview Research + +usb:v0925p0005* + ID_PRODUCT_FROM_DATABASE=Gamtec.,Ltd SmartJoy PLUS Adapter + +usb:v0925p3881* + ID_PRODUCT_FROM_DATABASE=Saleae Logic + +usb:v0925p8101* + ID_PRODUCT_FROM_DATABASE=Phidgets, Inc., 1-Motor PhidgetServo v2.0 + +usb:v0925p8104* + ID_PRODUCT_FROM_DATABASE=Phidgets, Inc., 4-Motor PhidgetServo v2.0 + +usb:v0925p8800* + ID_PRODUCT_FROM_DATABASE=WiseGroup Ltd, MP-8800 Quad Joypad + +usb:v0925p8866* + ID_PRODUCT_FROM_DATABASE=WiseGroup Ltd, MP-8866 Dual Joypad + +usb:v0927* + ID_VENDOR_FROM_DATABASE=Summus, Ltd + +usb:v0928* + ID_VENDOR_FROM_DATABASE=PLX Technology, Inc. (formerly Oxford Semiconductor, Ltd) + +usb:v0928p8000* + ID_PRODUCT_FROM_DATABASE=Firmware uploader + +usb:v0929* + ID_VENDOR_FROM_DATABASE=American Biometric Co. + +usb:v092A* + ID_VENDOR_FROM_DATABASE=Toshiba Information & Industrial Sys. And Services + +usb:v092B* + ID_VENDOR_FROM_DATABASE=Sena Technologies, Inc. + +usb:v092F* + ID_VENDOR_FROM_DATABASE=Northern Embedded Science/CAVNEX + +usb:v092Fp0004* + ID_PRODUCT_FROM_DATABASE=JTAG-4 + +usb:v092Fp0005* + ID_PRODUCT_FROM_DATABASE=JTAG-5 + +usb:v0930* + ID_VENDOR_FROM_DATABASE=Toshiba Corp. + +usb:v0930p0009* + ID_PRODUCT_FROM_DATABASE=Gigabeat F/X (HDD audio player) + +usb:v0930p000C* + ID_PRODUCT_FROM_DATABASE=Gigabeat F (mtp) + +usb:v0930p0010* + ID_PRODUCT_FROM_DATABASE=Gigabeat S (mtp) + +usb:v0930p0301* + ID_PRODUCT_FROM_DATABASE=PCX1100U Cable Modem (WDM) + +usb:v0930p0302* + ID_PRODUCT_FROM_DATABASE=PCX2000 Cable Modem (WDM) + +usb:v0930p0305* + ID_PRODUCT_FROM_DATABASE=Cable Modem PCX3000 + +usb:v0930p0307* + ID_PRODUCT_FROM_DATABASE=Cable Modem PCX2500 + +usb:v0930p0308* + ID_PRODUCT_FROM_DATABASE=PCX2200 Cable Modem (WDM) + +usb:v0930p0309* + ID_PRODUCT_FROM_DATABASE=PCX5000 Cable Modem (WDM) + +usb:v0930p030B* + ID_PRODUCT_FROM_DATABASE=Cable Modem PCX2600 + +usb:v0930p0501* + ID_PRODUCT_FROM_DATABASE=Bluetooth Controller + +usb:v0930p0502* + ID_PRODUCT_FROM_DATABASE=Integrated Bluetooth + +usb:v0930p0503* + ID_PRODUCT_FROM_DATABASE=Bluetooth Controller + +usb:v0930p0505* + ID_PRODUCT_FROM_DATABASE=Integrated Bluetooth + +usb:v0930p0506* + ID_PRODUCT_FROM_DATABASE=Integrated Bluetooth + +usb:v0930p0507* + ID_PRODUCT_FROM_DATABASE=Bluetooth Adapter + +usb:v0930p0508* + ID_PRODUCT_FROM_DATABASE=Integrated Bluetooth HCI + +usb:v0930p0509* + ID_PRODUCT_FROM_DATABASE=BT EDR Dongle + +usb:v0930p0706* + ID_PRODUCT_FROM_DATABASE=PocketPC e740 + +usb:v0930p0707* + ID_PRODUCT_FROM_DATABASE=Pocket PC e330 Series + +usb:v0930p0708* + ID_PRODUCT_FROM_DATABASE=Pocket PC e350 Series + +usb:v0930p0709* + ID_PRODUCT_FROM_DATABASE=Pocket PC e750 Series + +usb:v0930p070A* + ID_PRODUCT_FROM_DATABASE=Pocket PC e400 Series + +usb:v0930p070B* + ID_PRODUCT_FROM_DATABASE=Pocket PC e800 Series + +usb:v0930p0A07* + ID_PRODUCT_FROM_DATABASE=WLM-10U1 802.11abgn Wireless Adapter [Ralink RT3572] + +usb:v0930p0B05* + ID_PRODUCT_FROM_DATABASE=PX1220E-1G25 External hard drive + +usb:v0930p0B09* + ID_PRODUCT_FROM_DATABASE=PX1396E-3T01 External hard drive + +usb:v0930p1300* + ID_PRODUCT_FROM_DATABASE=Wireless Broadband (CDMA EV-DO) SM-Bus Minicard Status Port + +usb:v0930p1301* + ID_PRODUCT_FROM_DATABASE=Wireless Broadband (CDMA EV-DO) Minicard Status Port + +usb:v0930p1302* + ID_PRODUCT_FROM_DATABASE=Wireless Broadband (3G HSDPA) SM-Bus Minicard Status Port + +usb:v0930p1303* + ID_PRODUCT_FROM_DATABASE=Wireless Broadband (3G HSDPA) Minicard Status Port + +usb:v0930p1308* + ID_PRODUCT_FROM_DATABASE=Broadband (3G HSDPA) SM-Bus Minicard Diagnostics Port + +usb:v0930p130B* + ID_PRODUCT_FROM_DATABASE=F3507g Mobile Broadband Module + +usb:v0930p130C* + ID_PRODUCT_FROM_DATABASE=F3607gw Mobile Broadband Module + +usb:v0930p1311* + ID_PRODUCT_FROM_DATABASE=F3607gw v2 Mobile Broadband Module + +usb:v0930p1400* + ID_PRODUCT_FROM_DATABASE=Memory Stick 2GB + +usb:v0930p642F* + ID_PRODUCT_FROM_DATABASE=TravelDrive + +usb:v0930p6506* + ID_PRODUCT_FROM_DATABASE=TravelDrive 2C + +usb:v0930p6507* + ID_PRODUCT_FROM_DATABASE=TravelDrive 2C + +usb:v0930p6508* + ID_PRODUCT_FROM_DATABASE=TravelDrive 2C + +usb:v0930p6509* + ID_PRODUCT_FROM_DATABASE=TravelDrive 2C + +usb:v0930p6510* + ID_PRODUCT_FROM_DATABASE=TravelDrive 2C + +usb:v0930p6517* + ID_PRODUCT_FROM_DATABASE=TravelDrive 2C + +usb:v0930p6518* + ID_PRODUCT_FROM_DATABASE=TravelDrive 2C + +usb:v0930p6519* + ID_PRODUCT_FROM_DATABASE=Kingston DataTraveler 2.0 USB Stick + +usb:v0930p651A* + ID_PRODUCT_FROM_DATABASE=TravelDrive 2C + +usb:v0930p651B* + ID_PRODUCT_FROM_DATABASE=TravelDrive 2C + +usb:v0930p651C* + ID_PRODUCT_FROM_DATABASE=TravelDrive 2C + +usb:v0930p651D* + ID_PRODUCT_FROM_DATABASE=TravelDrive 2C + +usb:v0930p651E* + ID_PRODUCT_FROM_DATABASE=TravelDrive 2C + +usb:v0930p651F* + ID_PRODUCT_FROM_DATABASE=TravelDrive 2C + +usb:v0930p6520* + ID_PRODUCT_FROM_DATABASE=TravelDrive 2C + +usb:v0930p6521* + ID_PRODUCT_FROM_DATABASE=TravelDrive 2C + +usb:v0930p6522* + ID_PRODUCT_FROM_DATABASE=TravelDrive 2C + +usb:v0930p6523* + ID_PRODUCT_FROM_DATABASE=TravelDrive + +usb:v0930p6524* + ID_PRODUCT_FROM_DATABASE=TravelDrive + +usb:v0930p6525* + ID_PRODUCT_FROM_DATABASE=TravelDrive + +usb:v0930p6526* + ID_PRODUCT_FROM_DATABASE=TravelDrive + +usb:v0930p6527* + ID_PRODUCT_FROM_DATABASE=TravelDrive + +usb:v0930p6528* + ID_PRODUCT_FROM_DATABASE=TravelDrive + +usb:v0930p6529* + ID_PRODUCT_FROM_DATABASE=TravelDrive + +usb:v0930p652A* + ID_PRODUCT_FROM_DATABASE=TravelDrive + +usb:v0930p652B* + ID_PRODUCT_FROM_DATABASE=TravelDrive + +usb:v0930p652C* + ID_PRODUCT_FROM_DATABASE=TravelDrive + +usb:v0930p652D* + ID_PRODUCT_FROM_DATABASE=TravelDrive + +usb:v0930p652F* + ID_PRODUCT_FROM_DATABASE=TravelDrive + +usb:v0930p6530* + ID_PRODUCT_FROM_DATABASE=TravelDrive + +usb:v0930p6531* + ID_PRODUCT_FROM_DATABASE=TravelDrive + +usb:v0930p6532* + ID_PRODUCT_FROM_DATABASE=256M Stick + +usb:v0930p6533* + ID_PRODUCT_FROM_DATABASE=512M Stick + +usb:v0930p6534* + ID_PRODUCT_FROM_DATABASE=TravelDrive + +usb:v0930p653C* + ID_PRODUCT_FROM_DATABASE=Kingston DataTraveler 2.0 Stick (512M) + +usb:v0930p653D* + ID_PRODUCT_FROM_DATABASE=Kingston DataTraveler 2.0 Stick (1GB) + +usb:v0930p653E* + ID_PRODUCT_FROM_DATABASE=Flash Memory + +usb:v0930p6540* + ID_PRODUCT_FROM_DATABASE=TransMemory Flash Memory + +usb:v0930p6544* + ID_PRODUCT_FROM_DATABASE=Kingston DataTraveler 2.0 Stick (2GB) + +usb:v0930p6545* + ID_PRODUCT_FROM_DATABASE=Kingston DataTraveler 102 Flash Drive / HEMA Flash Drive 2 GB / PNY Attache 4GB Stick + +usb:v0931* + ID_VENDOR_FROM_DATABASE=Harmonic Data Systems, Ltd + +usb:v0932* + ID_VENDOR_FROM_DATABASE=Crescentec Corp. + +usb:v0932p0300* + ID_PRODUCT_FROM_DATABASE=VideoAdvantage + +usb:v0932p0302* + ID_PRODUCT_FROM_DATABASE=Syntek DC-112X + +usb:v0932p0320* + ID_PRODUCT_FROM_DATABASE=VideoAdvantage + +usb:v0932p0482* + ID_PRODUCT_FROM_DATABASE=USB2.0 TVBOX + +usb:v0932p1100* + ID_PRODUCT_FROM_DATABASE=DC-1100 Video Enhamcement Device + +usb:v0932p1112* + ID_PRODUCT_FROM_DATABASE=Veo Web Camera + +usb:v0932pA311* + ID_PRODUCT_FROM_DATABASE=Video Enhancement Device + +usb:v0933* + ID_VENDOR_FROM_DATABASE=Quantum Corp. + +usb:v0934* + ID_VENDOR_FROM_DATABASE=Spirent Communications + +usb:v0936* + ID_VENDOR_FROM_DATABASE=NuTesla + +usb:v0936p0030* + ID_PRODUCT_FROM_DATABASE=Composite Device, Mass Storage Device (Flash Drive) amd HID + +usb:v0936p003C* + ID_PRODUCT_FROM_DATABASE=Rhythmedics HID Bootloader + +usb:v0939* + ID_VENDOR_FROM_DATABASE=Lumberg, Inc. + +usb:v0939p0B15* + ID_PRODUCT_FROM_DATABASE=Toshiba Stor.E Alu 2 1TB (PX1710E-1HJ0) + +usb:v093A* + ID_VENDOR_FROM_DATABASE=Pixart Imaging, Inc. + +usb:v093Ap0007* + ID_PRODUCT_FROM_DATABASE=CMOS 100K-R Rev. 1.90 + +usb:v093Ap010E* + ID_PRODUCT_FROM_DATABASE=Digital camera, CD302N/Elta Medi@ digi-cam/HE-501A + +usb:v093Ap010F* + ID_PRODUCT_FROM_DATABASE=Argus DC-1610/DC-1620/Emprex PCD3600/Philips P44417B keychain camera/Precision Mini,Model HA513A/Vivitar Vivicam 55 + +usb:v093Ap020F* + ID_PRODUCT_FROM_DATABASE=Bullet Line Photo Viewer + +usb:v093Ap050F* + ID_PRODUCT_FROM_DATABASE=Mars-Semi Pc-Camera + +usb:v093Ap2460* + ID_PRODUCT_FROM_DATABASE=Q-TEC WEBCAM 100 + +usb:v093Ap2468* + ID_PRODUCT_FROM_DATABASE=SoC PC-Camera + +usb:v093Ap2470* + ID_PRODUCT_FROM_DATABASE=SoC PC-Camera + +usb:v093Ap2471* + ID_PRODUCT_FROM_DATABASE=SoC PC-Camera + +usb:v093Ap2500* + ID_PRODUCT_FROM_DATABASE=USB Optical Mouse + +usb:v093Ap2510* + ID_PRODUCT_FROM_DATABASE=Optical Mouse + +usb:v093Ap2600* + ID_PRODUCT_FROM_DATABASE=Typhoon Easycam USB 330K (newer)/Typhoon Easycam USB 2.0 VGA 1.3M/Sansun SN-508 + +usb:v093Ap2601* + ID_PRODUCT_FROM_DATABASE=SPC 610NC Laptop Camera + +usb:v093Ap2603* + ID_PRODUCT_FROM_DATABASE=PAC7312 Camera + +usb:v093Ap2608* + ID_PRODUCT_FROM_DATABASE=PAC7311 Trust WB-3300p + +usb:v093Ap260E* + ID_PRODUCT_FROM_DATABASE=PAC7311 Gigaware VGA PC Camera:Trust WB-3350p:SIGMA cam 2350 + +usb:v093Ap260F* + ID_PRODUCT_FROM_DATABASE=PAC7311 SnakeCam + +usb:v093Ap2621* + ID_PRODUCT_FROM_DATABASE=PAC731x Trust Webcam + +usb:v093Ap2624* + ID_PRODUCT_FROM_DATABASE=Webcam + +usb:v093B* + ID_VENDOR_FROM_DATABASE=Plextor Corp. + +usb:v093Bp0010* + ID_PRODUCT_FROM_DATABASE=Storage Adapter + +usb:v093Bp0011* + ID_PRODUCT_FROM_DATABASE=PlexWriter 40/12/40U + +usb:v093Bp0041* + ID_PRODUCT_FROM_DATABASE=PX-708A DVD RW + +usb:v093Bp0042* + ID_PRODUCT_FROM_DATABASE=PX-712UF DVD RW + +usb:v093BpA002* + ID_PRODUCT_FROM_DATABASE=ConvertX M402U XLOADER + +usb:v093BpA003* + ID_PRODUCT_FROM_DATABASE=ConvertX AV100U A/V Capture Audio + +usb:v093BpA004* + ID_PRODUCT_FROM_DATABASE=ConvertX TV402U XLOADER + +usb:v093BpA005* + ID_PRODUCT_FROM_DATABASE=ConvertX TV100U A/V Capture + +usb:v093BpA102* + ID_PRODUCT_FROM_DATABASE=ConvertX M402U A/V Capture + +usb:v093BpA104* + ID_PRODUCT_FROM_DATABASE=ConvertX PX-TV402U/NA + +usb:v093C* + ID_VENDOR_FROM_DATABASE=Intrepid Control Systems, Inc. + +usb:v093Cp0601* + ID_PRODUCT_FROM_DATABASE=ValueCAN + +usb:v093Cp0701* + ID_PRODUCT_FROM_DATABASE=NeoVI Blue vehicle bus interface + +usb:v093D* + ID_VENDOR_FROM_DATABASE=InnoSync, Inc. + +usb:v093E* + ID_VENDOR_FROM_DATABASE=J.S.T. Mfg. Co., Ltd + +usb:v093F* + ID_VENDOR_FROM_DATABASE=Olympia Telecom Vertriebs GmbH + +usb:v0940* + ID_VENDOR_FROM_DATABASE=Japan Storage Battery Co., Ltd + +usb:v0941* + ID_VENDOR_FROM_DATABASE=Photobit Corp. + +usb:v0942* + ID_VENDOR_FROM_DATABASE=i2Go.com, LLC + +usb:v0943* + ID_VENDOR_FROM_DATABASE=HCL Technologies India Private, Ltd + +usb:v0944* + ID_VENDOR_FROM_DATABASE=KORG, Inc. + +usb:v0944p0001* + ID_PRODUCT_FROM_DATABASE=PXR4 4-Track Digital Recorder + +usb:v0944p0020* + ID_PRODUCT_FROM_DATABASE=KAOSS Pad KP3 Dynamic Effect/Sampler + +usb:v0944p0023* + ID_PRODUCT_FROM_DATABASE=KAOSSILATOR PRO Dynamic Phrase Synthesizer + +usb:v0944p010D* + ID_PRODUCT_FROM_DATABASE=nanoKEY MIDI keyboard + +usb:v0944p010E* + ID_PRODUCT_FROM_DATABASE=nanoPAD pad controller + +usb:v0944p010F* + ID_PRODUCT_FROM_DATABASE=nanoKONTROL studio controller + +usb:v0944p0117* + ID_PRODUCT_FROM_DATABASE=nanoKONTROL2 MIDI Controller + +usb:v0944p0F03* + ID_PRODUCT_FROM_DATABASE=K-Series K61P MIDI studio controller + +usb:v0945* + ID_VENDOR_FROM_DATABASE=Pasco Scientific + +usb:v0948* + ID_VENDOR_FROM_DATABASE=Kronauer music in digital + +usb:v0948p0301* + ID_PRODUCT_FROM_DATABASE=USB Pro (24/48) + +usb:v0948p0302* + ID_PRODUCT_FROM_DATABASE=USB Pro (24/96 playback) + +usb:v0948p0303* + ID_PRODUCT_FROM_DATABASE=USB Pro (24/96 record) + +usb:v0948p0304* + ID_PRODUCT_FROM_DATABASE=USB Pro (16/48) + +usb:v0948p1105* + ID_PRODUCT_FROM_DATABASE=USB One + +usb:v094B* + ID_VENDOR_FROM_DATABASE=Linkup Systems Corp. + +usb:v094Bp0001* + ID_PRODUCT_FROM_DATABASE=neonode N2 + +usb:v094D* + ID_VENDOR_FROM_DATABASE=Cable Television Laboratories + +usb:v094F* + ID_VENDOR_FROM_DATABASE=Yano + +usb:v094Fp0101* + ID_PRODUCT_FROM_DATABASE=U640MO-03 + +usb:v094Fp05FC* + ID_PRODUCT_FROM_DATABASE=METALWEAR-HDD + +usb:v0951* + ID_VENDOR_FROM_DATABASE=Kingston Technology + +usb:v0951p0008* + ID_PRODUCT_FROM_DATABASE=Ethernet + +usb:v0951p000A* + ID_PRODUCT_FROM_DATABASE=KNU101TX 100baseTX Ethernet + +usb:v0951p1600* + ID_PRODUCT_FROM_DATABASE=DataTraveler II Pen Drive + +usb:v0951p1601* + ID_PRODUCT_FROM_DATABASE=DataTraveler II+ Pen Drive + +usb:v0951p1602* + ID_PRODUCT_FROM_DATABASE=DataTraveler Mini + +usb:v0951p1603* + ID_PRODUCT_FROM_DATABASE=DataTraveler 1GB/2GB Pen Drive + +usb:v0951p1606* + ID_PRODUCT_FROM_DATABASE=Eee PC 701 SD Card Reader [ENE UB6225] + +usb:v0951p1607* + ID_PRODUCT_FROM_DATABASE=DataTraveler 100 + +usb:v0951p160D* + ID_PRODUCT_FROM_DATABASE=DataTraveler Vault Privacy + +usb:v0951p1613* + ID_PRODUCT_FROM_DATABASE=DataTraveler DT101C Flash Drive + +usb:v0951p1616* + ID_PRODUCT_FROM_DATABASE=DataTraveler Locker 4GB + +usb:v0951p1621* + ID_PRODUCT_FROM_DATABASE=DataTraveler 150 (32GB) + +usb:v0951p1624* + ID_PRODUCT_FROM_DATABASE=DataTraveler G2 4GB Pen Drive + +usb:v0951p1625* + ID_PRODUCT_FROM_DATABASE=DataTraveler 101 II + +usb:v0951p162A* + ID_PRODUCT_FROM_DATABASE=DataTraveler 112 4GB Pen Drive + +usb:v0951p162D* + ID_PRODUCT_FROM_DATABASE=DataTraveler 102 + +usb:v0951p1630* + ID_PRODUCT_FROM_DATABASE=DataTraveler 200 (32GB) + +usb:v0951p1642* + ID_PRODUCT_FROM_DATABASE=DT101 G2 + +usb:v0951p1643* + ID_PRODUCT_FROM_DATABASE=DataTraveler G3 4GB + +usb:v0951p1653* + ID_PRODUCT_FROM_DATABASE=Data Traveler 100 G2 8 GiB + +usb:v0951p1656* + ID_PRODUCT_FROM_DATABASE=DataTraveler Ultimate G2 + +usb:v0954* + ID_VENDOR_FROM_DATABASE=RPM Systems Corp. + +usb:v0955* + ID_VENDOR_FROM_DATABASE=NVidia Corp. + +usb:v0955p7030* + ID_PRODUCT_FROM_DATABASE=Tegra 3 (recovery mode) + +usb:v0955p7100* + ID_PRODUCT_FROM_DATABASE=Notion Ink Adam + +usb:v0956* + ID_VENDOR_FROM_DATABASE=BSquare Corp. + +usb:v0957* + ID_VENDOR_FROM_DATABASE=Agilent Technologies, Inc. + +usb:v0957p0200* + ID_PRODUCT_FROM_DATABASE=E-Video DC-350 Camera + +usb:v0957p0202* + ID_PRODUCT_FROM_DATABASE=E-Video DC-350 Camera + +usb:v0957p0518* + ID_PRODUCT_FROM_DATABASE=82357B GPIB Interface + +usb:v0957p1745* + ID_PRODUCT_FROM_DATABASE=Test and Measurement Device (IVI) + +usb:v0957p2918* + ID_PRODUCT_FROM_DATABASE=U2702A oscilloscope + +usb:v0958* + ID_VENDOR_FROM_DATABASE=CompuLink Research, Inc. + +usb:v0959* + ID_VENDOR_FROM_DATABASE=Cologne Chip AG + +usb:v0959p2BD0* + ID_PRODUCT_FROM_DATABASE=Intelligent ISDN (Ver. 3.60.04) + +usb:v095A* + ID_VENDOR_FROM_DATABASE=Portsmith + +usb:v095Ap3003* + ID_PRODUCT_FROM_DATABASE=Express Ethernet + +usb:v095B* + ID_VENDOR_FROM_DATABASE=Medialogic Corp. + +usb:v095C* + ID_VENDOR_FROM_DATABASE=K-Tec Electronics + +usb:v095D* + ID_VENDOR_FROM_DATABASE=Polycom, Inc. + +usb:v095Dp0001* + ID_PRODUCT_FROM_DATABASE=Polycom ViaVideo + +usb:v0967* + ID_VENDOR_FROM_DATABASE=Acer (??) + +usb:v0967p0204* + ID_PRODUCT_FROM_DATABASE=WarpLink 802.11b Adapter + +usb:v0968* + ID_VENDOR_FROM_DATABASE=Catalyst Enterprises, Inc. + +usb:v096E* + ID_VENDOR_FROM_DATABASE=Feitian Technologies, Inc. + +usb:v096Ep0120* + ID_PRODUCT_FROM_DATABASE=Microcosm Ltd Dinkey + +usb:v096Ep0802* + ID_PRODUCT_FROM_DATABASE=ePass2000 (G&D STARCOS SPK 2.4) + +usb:v096Ep0807* + ID_PRODUCT_FROM_DATABASE=ePass2003 + +usb:v0971* + ID_VENDOR_FROM_DATABASE=Gretag-Macbeth AG + +usb:v0971p2003* + ID_PRODUCT_FROM_DATABASE=Eye-One display + +usb:v0971p2005* + ID_PRODUCT_FROM_DATABASE=Huey + +usb:v0971p2007* + ID_PRODUCT_FROM_DATABASE=ColorMunki + +usb:v0973* + ID_VENDOR_FROM_DATABASE=Schlumberger + +usb:v0973p0001* + ID_PRODUCT_FROM_DATABASE=e-gate Smart Card + +usb:v0974* + ID_VENDOR_FROM_DATABASE=Datagraphix, a business unit of Anacomp + +usb:v0975* + ID_VENDOR_FROM_DATABASE=OL'E Communications, Inc. + +usb:v0976* + ID_VENDOR_FROM_DATABASE=Adirondack Wire & Cable + +usb:v0977* + ID_VENDOR_FROM_DATABASE=Lightsurf Technologies + +usb:v0978* + ID_VENDOR_FROM_DATABASE=Beckhoff GmbH + +usb:v0979* + ID_VENDOR_FROM_DATABASE=Jeilin Technology Corp., Ltd + +usb:v0979p0224* + ID_PRODUCT_FROM_DATABASE=JL2005A Toy Camera + +usb:v0979p0226* + ID_PRODUCT_FROM_DATABASE=JL2005A Toy Camera + +usb:v0979p0227* + ID_PRODUCT_FROM_DATABASE=JL2005B/C/D Toy Camera + +usb:v097A* + ID_VENDOR_FROM_DATABASE=Minds At Work LLC + +usb:v097Ap0001* + ID_PRODUCT_FROM_DATABASE=Digital Wallet + +usb:v097B* + ID_VENDOR_FROM_DATABASE=Knudsen Engineering, Ltd + +usb:v097C* + ID_VENDOR_FROM_DATABASE=Marunix Co., Ltd + +usb:v097D* + ID_VENDOR_FROM_DATABASE=Rosun Technologies, Inc. + +usb:v097E* + ID_VENDOR_FROM_DATABASE=Biopac Systems Inc. + +usb:v097Ep0035* + ID_PRODUCT_FROM_DATABASE=MP35 v1.0 + +usb:v097F* + ID_VENDOR_FROM_DATABASE=Barun Electronics Co., Ltd + +usb:v0981* + ID_VENDOR_FROM_DATABASE=Oak Technology, Ltd + +usb:v0984* + ID_VENDOR_FROM_DATABASE=Apricorn + +usb:v0984p0200* + ID_PRODUCT_FROM_DATABASE=Hard Drive Storage (TPP) + +usb:v0985* + ID_VENDOR_FROM_DATABASE=cab Produkttechnik GmbH & Co KG + +usb:v0985p0045* + ID_PRODUCT_FROM_DATABASE=Mach4/200 Label Printer + +usb:v0985p00A3* + ID_PRODUCT_FROM_DATABASE=A3/200 or A3/300 Label Printer + +usb:v0986* + ID_VENDOR_FROM_DATABASE=Matsushita Electric Works, Ltd. + +usb:v098C* + ID_VENDOR_FROM_DATABASE=Vitana Corp. + +usb:v098D* + ID_VENDOR_FROM_DATABASE=INDesign + +usb:v098E* + ID_VENDOR_FROM_DATABASE=Integrated Intellectual Property, Inc. + +usb:v098F* + ID_VENDOR_FROM_DATABASE=Kenwood TMI Corp. + +usb:v0993* + ID_VENDOR_FROM_DATABASE=Gemstar eBook Group, Ltd + +usb:v0993p0001* + ID_PRODUCT_FROM_DATABASE=REB1100 eBook Reader + +usb:v0993p0002* + ID_PRODUCT_FROM_DATABASE=eBook + +usb:v0996* + ID_VENDOR_FROM_DATABASE=Integrated Telecom Express, Inc. + +usb:v099A* + ID_VENDOR_FROM_DATABASE=Zippy Technology Corp. + +usb:v099Ap0638* + ID_PRODUCT_FROM_DATABASE=Sanwa Supply Inc. Small Keyboard + +usb:v099Ap610C* + ID_PRODUCT_FROM_DATABASE=EL-610 Super Mini Electron luminescent Keyboard + +usb:v099Ap7160* + ID_PRODUCT_FROM_DATABASE=Hyper Slim Keyboard + +usb:v09A3* + ID_VENDOR_FROM_DATABASE=PairGain Technologies + +usb:v09A4* + ID_VENDOR_FROM_DATABASE=Contech Research, Inc. + +usb:v09A5* + ID_VENDOR_FROM_DATABASE=VCON Telecommunications + +usb:v09A6* + ID_VENDOR_FROM_DATABASE=Poinchips + +usb:v09A6p8001* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v09A7* + ID_VENDOR_FROM_DATABASE=Data Transmission Network Corp. + +usb:v09A8* + ID_VENDOR_FROM_DATABASE=Lin Shiung Enterprise Co., Ltd + +usb:v09A9* + ID_VENDOR_FROM_DATABASE=Smart Card Technologies Co., Ltd + +usb:v09AA* + ID_VENDOR_FROM_DATABASE=Intersil Corp. + +usb:v09AAp1000* + ID_PRODUCT_FROM_DATABASE=Prism GT 802.11b/g Adapter + +usb:v09AAp3642* + ID_PRODUCT_FROM_DATABASE=Prism 2.x 802.11b Adapter + +usb:v09AB* + ID_VENDOR_FROM_DATABASE=Japan Cash Machine Co., Ltd. + +usb:v09AE* + ID_VENDOR_FROM_DATABASE=Tripp Lite + +usb:v09B2* + ID_VENDOR_FROM_DATABASE=Franklin Electronic Publishers, Inc. + +usb:v09B2p0001* + ID_PRODUCT_FROM_DATABASE=eBookman Palm Computer + +usb:v09B3* + ID_VENDOR_FROM_DATABASE=Altius Solutions, Inc. + +usb:v09B4* + ID_VENDOR_FROM_DATABASE=MDS Telephone Systems + +usb:v09B5* + ID_VENDOR_FROM_DATABASE=Celltrix Technology Co., Ltd + +usb:v09BC* + ID_VENDOR_FROM_DATABASE=Grundig + +usb:v09BCp0002* + ID_PRODUCT_FROM_DATABASE=MPaxx MP150 MP3 Player + +usb:v09BE* + ID_VENDOR_FROM_DATABASE=MySmart.Com + +usb:v09BEp0001* + ID_PRODUCT_FROM_DATABASE=MySmartPad + +usb:v09BF* + ID_VENDOR_FROM_DATABASE=Auerswald GmbH & Co. KG + +usb:v09BFp00C0* + ID_PRODUCT_FROM_DATABASE=COMpact 2104 ISDN PBX + +usb:v09BFp00DB* + ID_PRODUCT_FROM_DATABASE=COMpact 4410/2206 ISDN + +usb:v09BFp00DC* + ID_PRODUCT_FROM_DATABASE=COMpact 4406 DSL (PBX) + +usb:v09BFp00DD* + ID_PRODUCT_FROM_DATABASE=COMpact 2204 (PBX) + +usb:v09BFp00DE* + ID_PRODUCT_FROM_DATABASE=COMpact 2104 (Rev.2 PBX) + +usb:v09BFp00E0* + ID_PRODUCT_FROM_DATABASE=COMmander Business (PBX) + +usb:v09BFp00E2* + ID_PRODUCT_FROM_DATABASE=COMmander Basic.2 (PBX) + +usb:v09BFp00F1* + ID_PRODUCT_FROM_DATABASE=COMfort 2000 (System telephone) + +usb:v09BFp00F2* + ID_PRODUCT_FROM_DATABASE=COMfort 1200 (System telephone) + +usb:v09BFp00F5* + ID_PRODUCT_FROM_DATABASE=COMfortel 2500 (System telephone) + +usb:v09BFp8000* + ID_PRODUCT_FROM_DATABASE=COMpact 2104 DSL (DSL modem) + +usb:v09BFp8001* + ID_PRODUCT_FROM_DATABASE=COMpact 4406 DSL (DSL modem) + +usb:v09BFp8002* + ID_PRODUCT_FROM_DATABASE=Analog/ISDN Converter (Line converter) + +usb:v09BFp8005* + ID_PRODUCT_FROM_DATABASE=WG-640 (Automatic event dialer) + +usb:v09C0* + ID_VENDOR_FROM_DATABASE=Genpix Electronics, LLC + +usb:v09C0p0136* + ID_PRODUCT_FROM_DATABASE=Axon CNS, MultiClamp 700B + +usb:v09C0p0202* + ID_PRODUCT_FROM_DATABASE=8PSK DVB-S tuner + +usb:v09C0p0203* + ID_PRODUCT_FROM_DATABASE=Skywalker-1 DVB-S tuner + +usb:v09C0p0204* + ID_PRODUCT_FROM_DATABASE=Skywalker-CW3K DVB-S tuner + +usb:v09C0p0205* + ID_PRODUCT_FROM_DATABASE=Skywalker-CW3K DVB-S tuner + +usb:v09C0p0206* + ID_PRODUCT_FROM_DATABASE=Skywalker-2 DVB-S tuner + +usb:v09C1* + ID_VENDOR_FROM_DATABASE=Arris Interactive LLC + +usb:v09C1p1337* + ID_PRODUCT_FROM_DATABASE=TOUCHSTONE DEVICE + +usb:v09C2* + ID_VENDOR_FROM_DATABASE=Nisca Corp. + +usb:v09C3* + ID_VENDOR_FROM_DATABASE=ActivCard, Inc. + +usb:v09C3p0007* + ID_PRODUCT_FROM_DATABASE=Reader V2 + +usb:v09C3p0008* + ID_PRODUCT_FROM_DATABASE=ZFG-9800-AC SmartCard Reader + +usb:v09C3p0014* + ID_PRODUCT_FROM_DATABASE=ActivIdentity ActivKey SIM USB Token + +usb:v09C4* + ID_VENDOR_FROM_DATABASE=ACTiSYS Corp. + +usb:v09C4p0011* + ID_PRODUCT_FROM_DATABASE=ACT-IR2000U IrDA Dongle + +usb:v09C5* + ID_VENDOR_FROM_DATABASE=Memory Corp. + +usb:v09CC* + ID_VENDOR_FROM_DATABASE=Workbit Corp. + +usb:v09CCp0404* + ID_PRODUCT_FROM_DATABASE=BAFO USB-ATA/ATAPI Bridge Controller + +usb:v09CD* + ID_VENDOR_FROM_DATABASE=Psion Dacom Home Networks, Ltd + +usb:v09CDp2001* + ID_PRODUCT_FROM_DATABASE=Psion WaveFinder DAB radio receiver + +usb:v09CE* + ID_VENDOR_FROM_DATABASE=City Electronics, Ltd + +usb:v09CF* + ID_VENDOR_FROM_DATABASE=Electronics Testing Center, Taiwan + +usb:v09D1* + ID_VENDOR_FROM_DATABASE=NeoMagic, Inc. + +usb:v09D2* + ID_VENDOR_FROM_DATABASE=Vreelin Engineering, Inc. + +usb:v09D3* + ID_VENDOR_FROM_DATABASE=Com One + +usb:v09D3p0001* + ID_PRODUCT_FROM_DATABASE=ISDN TA + +usb:v09D7* + ID_VENDOR_FROM_DATABASE=Novatel Wireless + +usb:v09D7p0100* + ID_PRODUCT_FROM_DATABASE=NovAtel FlexPack GPS receiver + +usb:v09D9* + ID_VENDOR_FROM_DATABASE=KRF Tech, Ltd + +usb:v09DA* + ID_VENDOR_FROM_DATABASE=A4 Tech Co., Ltd + +usb:v09DAp0006* + ID_PRODUCT_FROM_DATABASE=Optical Mouse WOP-35 / Trust 450L Optical Mouse + +usb:v09DAp000A* + ID_PRODUCT_FROM_DATABASE=Optical Mouse Opto 510D + +usb:v09DAp000E* + ID_PRODUCT_FROM_DATABASE=X-F710F Optical Mouse 3xFire Gaming Mouse + +usb:v09DAp0018* + ID_PRODUCT_FROM_DATABASE=Trust Human Interface Device + +usb:v09DAp001A* + ID_PRODUCT_FROM_DATABASE=Wireless Mouse & RXM-15 Receiver + +usb:v09DAp002A* + ID_PRODUCT_FROM_DATABASE=Wireless Optical Mouse NB-30 + +usb:v09DAp022B* + ID_PRODUCT_FROM_DATABASE=Wireless Mouse (Battery Free) + +usb:v09DAp024F* + ID_PRODUCT_FROM_DATABASE=RF Receiver and G6-20D Wireless Optical Mouse + +usb:v09DAp0260* + ID_PRODUCT_FROM_DATABASE=KV-300H Isolation Keyboard + +usb:v09DAp032B* + ID_PRODUCT_FROM_DATABASE=Wireless Mouse (Battery Free) + +usb:v09DAp8090* + ID_PRODUCT_FROM_DATABASE=X-718BK Oscar Optical Gaming Mouse + +usb:v09DAp9090* + ID_PRODUCT_FROM_DATABASE=XL-750BK Laser Mouse + +usb:v09DB* + ID_VENDOR_FROM_DATABASE=Measurement Computing Corp. + +usb:v09DBp0075* + ID_PRODUCT_FROM_DATABASE=MiniLab 1008 + +usb:v09DBp0076* + ID_PRODUCT_FROM_DATABASE=PMD-1024 + +usb:v09DBp007A* + ID_PRODUCT_FROM_DATABASE=PMD-1208LS + +usb:v09DBp0081* + ID_PRODUCT_FROM_DATABASE=USB-1616FS + +usb:v09DBp0082* + ID_PRODUCT_FROM_DATABASE=USB-1208FS + +usb:v09DBp0088* + ID_PRODUCT_FROM_DATABASE=USB-1616FS internal hub + +usb:v09DC* + ID_VENDOR_FROM_DATABASE=Aimex Corp. + +usb:v09DD* + ID_VENDOR_FROM_DATABASE=Fellowes, Inc. + +usb:v09DF* + ID_VENDOR_FROM_DATABASE=Addonics Technologies Corp. + +usb:v09E1* + ID_VENDOR_FROM_DATABASE=Intellon Corp. + +usb:v09E1p5121* + ID_PRODUCT_FROM_DATABASE=MicroLink dLAN + +usb:v09E5* + ID_VENDOR_FROM_DATABASE=Jo-Dan International, Inc. + +usb:v09E6* + ID_VENDOR_FROM_DATABASE=Silutia, Inc. + +usb:v09E7* + ID_VENDOR_FROM_DATABASE=Real 3D, Inc. + +usb:v09E8* + ID_VENDOR_FROM_DATABASE=AKAI Professional M.I. Corp. + +usb:v09E8p0062* + ID_PRODUCT_FROM_DATABASE=MPD16 MIDI Pad Controller Unit + +usb:v09E8p006D* + ID_PRODUCT_FROM_DATABASE=EWI electronic wind instrument + +usb:v09E8p0071* + ID_PRODUCT_FROM_DATABASE=MPK25 MIDI Keyboard + +usb:v09E8p0076* + ID_PRODUCT_FROM_DATABASE=LPK25 MIDI Keyboard + +usb:v09E9* + ID_VENDOR_FROM_DATABASE=Chen-Source, Inc. + +usb:v09EB* + ID_VENDOR_FROM_DATABASE=IM Networks, Inc. + +usb:v09EBp4331* + ID_PRODUCT_FROM_DATABASE=iRhythm Tuner Remote + +usb:v09EF* + ID_VENDOR_FROM_DATABASE=Xitel + +usb:v09EFp0101* + ID_PRODUCT_FROM_DATABASE=MD-Port DG2 MiniDisc Interface + +usb:v09F3* + ID_VENDOR_FROM_DATABASE=GoFlight, Inc. + +usb:v09F3p0018* + ID_PRODUCT_FROM_DATABASE=GF-46 Multi-Mode Display Module + +usb:v09F3p0028* + ID_PRODUCT_FROM_DATABASE=RP-48 Combination Pushbutton-Rotary Module + +usb:v09F3p0048* + ID_PRODUCT_FROM_DATABASE=LGTII - Landing Gear and Trim Control Module + +usb:v09F3p0064* + ID_PRODUCT_FROM_DATABASE=MCPPro - Airliner Mode Control Panel (Autopilot) + +usb:v09F3p0300* + ID_PRODUCT_FROM_DATABASE=EFIS - Electronic Flight Information System + +usb:v09F5* + ID_VENDOR_FROM_DATABASE=AresCom + +usb:v09F5p0168* + ID_PRODUCT_FROM_DATABASE=Network Adapter + +usb:v09F5p0188* + ID_PRODUCT_FROM_DATABASE=LAN Adapter + +usb:v09F5p0850* + ID_PRODUCT_FROM_DATABASE=Adapter + +usb:v09F6* + ID_VENDOR_FROM_DATABASE=RocketChips, Inc. + +usb:v09F7* + ID_VENDOR_FROM_DATABASE=Edu-Science (H.K.), Ltd + +usb:v09F8* + ID_VENDOR_FROM_DATABASE=SoftConnex Technologies, Inc. + +usb:v09F9* + ID_VENDOR_FROM_DATABASE=Bay Associates + +usb:v09FA* + ID_VENDOR_FROM_DATABASE=Mtek Vision + +usb:v09FB* + ID_VENDOR_FROM_DATABASE=Altera + +usb:v09FBp6001* + ID_PRODUCT_FROM_DATABASE=Blaster + +usb:v09FF* + ID_VENDOR_FROM_DATABASE=Gain Technology Corp. + +usb:v0A00* + ID_VENDOR_FROM_DATABASE=Liquid Audio + +usb:v0A01* + ID_VENDOR_FROM_DATABASE=ViA, Inc. + +usb:v0A07* + ID_VENDOR_FROM_DATABASE=Ontrak Control Systems Inc. + +usb:v0A07p0064* + ID_PRODUCT_FROM_DATABASE=ADU100 Data Acquisition Interface + +usb:v0A07p0078* + ID_PRODUCT_FROM_DATABASE=ADU120 Data Acquisition Interface + +usb:v0A07p0082* + ID_PRODUCT_FROM_DATABASE=ADU130 Data Acquisition Interface + +usb:v0A07p00C8* + ID_PRODUCT_FROM_DATABASE=ADU200 Relay I/O Interface + +usb:v0A07p00D0* + ID_PRODUCT_FROM_DATABASE=ADU208 Relay I/O Interface + +usb:v0A07p00DA* + ID_PRODUCT_FROM_DATABASE=ADU218 Solid-State Relay I/O Interface + +usb:v0A0B* + ID_VENDOR_FROM_DATABASE=Cybex Computer Products Co. + +usb:v0A11* + ID_VENDOR_FROM_DATABASE=Xentec, Inc. + +usb:v0A12* + ID_VENDOR_FROM_DATABASE=Cambridge Silicon Radio, Ltd + +usb:v0A12p0001* + ID_PRODUCT_FROM_DATABASE=Bluetooth Dongle (HCI mode) + +usb:v0A12p0002* + ID_PRODUCT_FROM_DATABASE=Frontline Test Equipment Bluetooth Device + +usb:v0A12p0003* + ID_PRODUCT_FROM_DATABASE=Nanosira + +usb:v0A12p0004* + ID_PRODUCT_FROM_DATABASE=Nanosira WHQL Reference Radio + +usb:v0A12p0005* + ID_PRODUCT_FROM_DATABASE=Nanosira-Multimedia + +usb:v0A12p0006* + ID_PRODUCT_FROM_DATABASE=Nanosira-Multimedia WHQL Reference Radio + +usb:v0A12p0007* + ID_PRODUCT_FROM_DATABASE=Nanosira3-ROM + +usb:v0A12p0008* + ID_PRODUCT_FROM_DATABASE=Nanosira3-ROM + +usb:v0A12p0009* + ID_PRODUCT_FROM_DATABASE=Nanosira4-EDR WHQL Reference Radio + +usb:v0A12p000A* + ID_PRODUCT_FROM_DATABASE=Nanosira4-EDR-ROM + +usb:v0A12p000B* + ID_PRODUCT_FROM_DATABASE=Nanosira5-ROM + +usb:v0A12p0043* + ID_PRODUCT_FROM_DATABASE=Bluetooth Device + +usb:v0A12p0100* + ID_PRODUCT_FROM_DATABASE=Casira with BlueCore2-External Module + +usb:v0A12p0101* + ID_PRODUCT_FROM_DATABASE=Casira with BlueCore2-Flash Module + +usb:v0A12p0102* + ID_PRODUCT_FROM_DATABASE=Casira with BlueCore3-Multimedia Module + +usb:v0A12p0103* + ID_PRODUCT_FROM_DATABASE=Casira with BlueCore3-Flash Module + +usb:v0A12p0104* + ID_PRODUCT_FROM_DATABASE=Casira with BlueCore4-External Module + +usb:v0A12p0105* + ID_PRODUCT_FROM_DATABASE=Casira with BlueCore4-Multimedia Module + +usb:v0A12p1000* + ID_PRODUCT_FROM_DATABASE=Bluetooth Dongle (HID proxy mode) + +usb:v0A12p1010* + ID_PRODUCT_FROM_DATABASE=Bluetooth Device + +usb:v0A12p1011* + ID_PRODUCT_FROM_DATABASE=Bluetooth Device + +usb:v0A12p1012* + ID_PRODUCT_FROM_DATABASE=Bluetooth Device + +usb:v0A12pFFFF* + ID_PRODUCT_FROM_DATABASE=USB Bluetooth Device in DFU State + +usb:v0A13* + ID_VENDOR_FROM_DATABASE=Telebyte, Inc. + +usb:v0A14* + ID_VENDOR_FROM_DATABASE=Spacelabs Medical, Inc. + +usb:v0A15* + ID_VENDOR_FROM_DATABASE=Scalar Corp. + +usb:v0A16* + ID_VENDOR_FROM_DATABASE=Trek Technology (S) PTE, Ltd + +usb:v0A16p1111* + ID_PRODUCT_FROM_DATABASE=ThumbDrive + +usb:v0A16p8888* + ID_PRODUCT_FROM_DATABASE=IBM USB Memory Key + +usb:v0A16p9988* + ID_PRODUCT_FROM_DATABASE=Trek2000 TD-G2 + +usb:v0A17* + ID_VENDOR_FROM_DATABASE=Pentax Corp. + +usb:v0A17p0004* + ID_PRODUCT_FROM_DATABASE=Optio 330 + +usb:v0A17p0006* + ID_PRODUCT_FROM_DATABASE=Optio S + +usb:v0A17p0007* + ID_PRODUCT_FROM_DATABASE=Optio 550 + +usb:v0A17p0009* + ID_PRODUCT_FROM_DATABASE=Optio 33WR + +usb:v0A17p000A* + ID_PRODUCT_FROM_DATABASE=Optio 555 + +usb:v0A17p000C* + ID_PRODUCT_FROM_DATABASE=Optio 43WR (mass storage mode) + +usb:v0A17p000D* + ID_PRODUCT_FROM_DATABASE=Optio 43WR + +usb:v0A17p0015* + ID_PRODUCT_FROM_DATABASE=Optio S40/S5i + +usb:v0A17p003B* + ID_PRODUCT_FROM_DATABASE=Optio 50 (mass storage mode) + +usb:v0A17p003D* + ID_PRODUCT_FROM_DATABASE=Optio S55 + +usb:v0A17p0043* + ID_PRODUCT_FROM_DATABASE=*ist DL + +usb:v0A17p0047* + ID_PRODUCT_FROM_DATABASE=Optio S60 + +usb:v0A17p0052* + ID_PRODUCT_FROM_DATABASE=Optio 60 Digital Camera + +usb:v0A17p006E* + ID_PRODUCT_FROM_DATABASE=K10D + +usb:v0A17p0070* + ID_PRODUCT_FROM_DATABASE=K100D + +usb:v0A17p0093* + ID_PRODUCT_FROM_DATABASE=K200D + +usb:v0A17p00A7* + ID_PRODUCT_FROM_DATABASE=Optio E50 + +usb:v0A17p1001* + ID_PRODUCT_FROM_DATABASE=EI2000 Camera powered by Digita! + +usb:v0A18* + ID_VENDOR_FROM_DATABASE=Heidelberger Druckmaschinen AG + +usb:v0A19* + ID_VENDOR_FROM_DATABASE=Hua Geng Technologies, Inc. + +usb:v0A21* + ID_VENDOR_FROM_DATABASE=Medtronic Physio Control Corp. + +usb:v0A21p8001* + ID_PRODUCT_FROM_DATABASE=MMT-7305WW [Medtronic Minimed CareLink] + +usb:v0A22* + ID_VENDOR_FROM_DATABASE=Century Semiconductor USA, Inc. + +usb:v0A27* + ID_VENDOR_FROM_DATABASE=Datacard Group + +usb:v0A27p0102* + ID_PRODUCT_FROM_DATABASE=SP35 + +usb:v0A2C* + ID_VENDOR_FROM_DATABASE=AK-Modul-Bus Computer GmbH + +usb:v0A2Cp0008* + ID_PRODUCT_FROM_DATABASE=GPIO Ports + +usb:v0A34* + ID_VENDOR_FROM_DATABASE=TG3 Electronics, Inc. + +usb:v0A34p0101* + ID_PRODUCT_FROM_DATABASE=TG82tp + +usb:v0A34p0110* + ID_PRODUCT_FROM_DATABASE=Deck 82-key backlit keyboard + +usb:v0A35* + ID_VENDOR_FROM_DATABASE=Radikal Technologies + +usb:v0A35p002A* + ID_PRODUCT_FROM_DATABASE=SAC - Software Assigned Controller + +usb:v0A35p008A* + ID_PRODUCT_FROM_DATABASE=SAC Hub + +usb:v0A39* + ID_VENDOR_FROM_DATABASE=Gilat Satellite Networks, Ltd + +usb:v0A3A* + ID_VENDOR_FROM_DATABASE=PentaMedia Co., Ltd + +usb:v0A3Ap0163* + ID_PRODUCT_FROM_DATABASE=KN-W510U 1.0 Wireless LAN Adapter + +usb:v0A3C* + ID_VENDOR_FROM_DATABASE=NTT DoCoMo, Inc. + +usb:v0A3D* + ID_VENDOR_FROM_DATABASE=Varo Vision + +usb:v0A3F* + ID_VENDOR_FROM_DATABASE=Swissonic AG + +usb:v0A43* + ID_VENDOR_FROM_DATABASE=Boca Systems, Inc. + +usb:v0A46* + ID_VENDOR_FROM_DATABASE=Davicom Semiconductor, Inc. + +usb:v0A46p0268* + ID_PRODUCT_FROM_DATABASE=ST268 + +usb:v0A46p6688* + ID_PRODUCT_FROM_DATABASE=ZT6688 Fast Ethernet Adapter + +usb:v0A46p8515* + ID_PRODUCT_FROM_DATABASE=ADMtek ADM8515 NIC + +usb:v0A46p9000* + ID_PRODUCT_FROM_DATABASE=DM9000E Fast Ethernet Adapter + +usb:v0A46p9601* + ID_PRODUCT_FROM_DATABASE=DM9601 Fast Ethernet Adapter + +usb:v0A47* + ID_VENDOR_FROM_DATABASE=Hirose Electric + +usb:v0A48* + ID_VENDOR_FROM_DATABASE=I/O Interconnect + +usb:v0A48p3233* + ID_PRODUCT_FROM_DATABASE=Multimedia Card Reader + +usb:v0A48p3239* + ID_PRODUCT_FROM_DATABASE=Multimedia Card Reader + +usb:v0A48p3258* + ID_PRODUCT_FROM_DATABASE=Dane Elec zMate SD Reader + +usb:v0A48p3259* + ID_PRODUCT_FROM_DATABASE=Dane Elec zMate CF Reader + +usb:v0A48p5000* + ID_PRODUCT_FROM_DATABASE=MediaGear xD-SM + +usb:v0A48p500A* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v0A48p500F* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v0A48p5010* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v0A48p5011* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v0A48p5014* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v0A48p5020* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v0A48p5021* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v0A48p5022* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v0A48p5023* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v0A48p5024* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v0A48p5025* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v0A4B* + ID_VENDOR_FROM_DATABASE=Fujitsu Media Devices, Ltd + +usb:v0A4C* + ID_VENDOR_FROM_DATABASE=Computex Co., Ltd + +usb:v0A4Cp15D9* + ID_PRODUCT_FROM_DATABASE=OPTICAL MOUSE + +usb:v0A4D* + ID_VENDOR_FROM_DATABASE=Evolution Electronics, Ltd + +usb:v0A4Dp0064* + ID_PRODUCT_FROM_DATABASE=MK-225 Driver + +usb:v0A4Dp0065* + ID_PRODUCT_FROM_DATABASE=MK-225C Driver + +usb:v0A4Dp0066* + ID_PRODUCT_FROM_DATABASE=MK-225C Driver + +usb:v0A4Dp0067* + ID_PRODUCT_FROM_DATABASE=MK-425C Driver + +usb:v0A4Dp0078* + ID_PRODUCT_FROM_DATABASE=MK-37 Driver + +usb:v0A4Dp0079* + ID_PRODUCT_FROM_DATABASE=MK-37C Driver + +usb:v0A4Dp007A* + ID_PRODUCT_FROM_DATABASE=MK-37C Driver + +usb:v0A4Dp008C* + ID_PRODUCT_FROM_DATABASE=TerraTec MIDI MASTER + +usb:v0A4Dp008D* + ID_PRODUCT_FROM_DATABASE=MK-249C Driver + +usb:v0A4Dp008E* + ID_PRODUCT_FROM_DATABASE=MK-249C MIDI Keyboard + +usb:v0A4Dp008F* + ID_PRODUCT_FROM_DATABASE=MK-449C Driver + +usb:v0A4Dp0090* + ID_PRODUCT_FROM_DATABASE=Keystation 49e Driver + +usb:v0A4Dp0091* + ID_PRODUCT_FROM_DATABASE=Keystation 61es Driver + +usb:v0A4Dp00A0* + ID_PRODUCT_FROM_DATABASE=MK-361 Driver + +usb:v0A4Dp00A1* + ID_PRODUCT_FROM_DATABASE=MK-361C Driver + +usb:v0A4Dp00A2* + ID_PRODUCT_FROM_DATABASE=MK-361C Driver + +usb:v0A4Dp00A3* + ID_PRODUCT_FROM_DATABASE=MK-461C MIDI Keyboard + +usb:v0A4Dp00B5* + ID_PRODUCT_FROM_DATABASE=Keystation Pro 88 Driver + +usb:v0A4Dp00D2* + ID_PRODUCT_FROM_DATABASE=E-Keys Driver + +usb:v0A4Dp00F0* + ID_PRODUCT_FROM_DATABASE=UC-16 Driver + +usb:v0A4Dp00F1* + ID_PRODUCT_FROM_DATABASE=X-Session Driver + +usb:v0A4Dp00F5* + ID_PRODUCT_FROM_DATABASE=UC-33e MIDI Controller + +usb:v0A4E* + ID_VENDOR_FROM_DATABASE=Steinberg Soft-und Hardware GmbH + +usb:v0A4F* + ID_VENDOR_FROM_DATABASE=Litton Systems, Inc. + +usb:v0A50* + ID_VENDOR_FROM_DATABASE=Mimaki Engineering Co., Ltd + +usb:v0A51* + ID_VENDOR_FROM_DATABASE=Sony Electronics, Inc. + +usb:v0A52* + ID_VENDOR_FROM_DATABASE=Jebsee Electronics Co., Ltd + +usb:v0A53* + ID_VENDOR_FROM_DATABASE=Portable Peripheral Co., Ltd + +usb:v0A53p1000* + ID_PRODUCT_FROM_DATABASE=Scanner + +usb:v0A53p2000* + ID_PRODUCT_FROM_DATABASE=Q-Scan A6 Scanner + +usb:v0A53p2001* + ID_PRODUCT_FROM_DATABASE=Q-Scan A6 Scanner + +usb:v0A53p2013* + ID_PRODUCT_FROM_DATABASE=Media Drive A6 Scanner + +usb:v0A53p2014* + ID_PRODUCT_FROM_DATABASE=Media Drive A6 Scanner + +usb:v0A53p2015* + ID_PRODUCT_FROM_DATABASE=BizCardReader 600C + +usb:v0A53p2016* + ID_PRODUCT_FROM_DATABASE=BizCardReader 600C + +usb:v0A53p202A* + ID_PRODUCT_FROM_DATABASE=Scanshell-CSSN + +usb:v0A53p3000* + ID_PRODUCT_FROM_DATABASE=Q-Scan A8 Scanner + +usb:v0A53p3002* + ID_PRODUCT_FROM_DATABASE=Q-Scan A8 Reader + +usb:v0A53p3015* + ID_PRODUCT_FROM_DATABASE=BizCardReader 300G + +usb:v0A53p302A* + ID_PRODUCT_FROM_DATABASE=LM9832 - PA570 Mini Business Card Scanner [Targus] + +usb:v0A53p5001* + ID_PRODUCT_FROM_DATABASE=BizCardReader 900C + +usb:v0A5A* + ID_VENDOR_FROM_DATABASE=Electronics For Imaging, Inc. + +usb:v0A5B* + ID_VENDOR_FROM_DATABASE=EAsics NV + +usb:v0A5C* + ID_VENDOR_FROM_DATABASE=Broadcom Corp. + +usb:v0A5Cp0201* + ID_PRODUCT_FROM_DATABASE=iLine10(tm) Network Adapter + +usb:v0A5Cp2000* + ID_PRODUCT_FROM_DATABASE=Bluetooth Device + +usb:v0A5Cp2001* + ID_PRODUCT_FROM_DATABASE=Bluetooth Device + +usb:v0A5Cp2009* + ID_PRODUCT_FROM_DATABASE=BCM2035 Bluetooth + +usb:v0A5Cp200A* + ID_PRODUCT_FROM_DATABASE=BCM2035 Bluetooth dongle + +usb:v0A5Cp200F* + ID_PRODUCT_FROM_DATABASE=Bluetooth Controller + +usb:v0A5Cp201D* + ID_PRODUCT_FROM_DATABASE=Bluetooth Device + +usb:v0A5Cp201E* + ID_PRODUCT_FROM_DATABASE=IBM Integrated Bluetooth IV + +usb:v0A5Cp2020* + ID_PRODUCT_FROM_DATABASE=Bluetooth dongle + +usb:v0A5Cp2021* + ID_PRODUCT_FROM_DATABASE=BCM2035B3 Bluetooth Adapter + +usb:v0A5Cp2033* + ID_PRODUCT_FROM_DATABASE=BCM2033 Bluetooth + +usb:v0A5Cp2035* + ID_PRODUCT_FROM_DATABASE=BCM2035 Bluetooth + +usb:v0A5Cp2038* + ID_PRODUCT_FROM_DATABASE=Blutonium Device + +usb:v0A5Cp2039* + ID_PRODUCT_FROM_DATABASE=BCM2045 Bluetooth + +usb:v0A5Cp2045* + ID_PRODUCT_FROM_DATABASE=Bluetooth Controller + +usb:v0A5Cp2046* + ID_PRODUCT_FROM_DATABASE=Bluetooth Device + +usb:v0A5Cp2047* + ID_PRODUCT_FROM_DATABASE=Bluetooth Device + +usb:v0A5Cp205E* + ID_PRODUCT_FROM_DATABASE=Bluetooth Device + +usb:v0A5Cp2100* + ID_PRODUCT_FROM_DATABASE=Bluetooth 2.0+eDR dongle + +usb:v0A5Cp2101* + ID_PRODUCT_FROM_DATABASE=BCM2045 Bluetooth + +usb:v0A5Cp2102* + ID_PRODUCT_FROM_DATABASE=ANYCOM Blue USB-200/250 + +usb:v0A5Cp2110* + ID_PRODUCT_FROM_DATABASE=Bluetooth Controller + +usb:v0A5Cp2111* + ID_PRODUCT_FROM_DATABASE=ANYCOM Blue USB-UHE 200/250 + +usb:v0A5Cp2120* + ID_PRODUCT_FROM_DATABASE=2045 Bluetooth 2.0 USB-UHE Device with trace filter + +usb:v0A5Cp2121* + ID_PRODUCT_FROM_DATABASE=BCM2210 Bluetooth + +usb:v0A5Cp2122* + ID_PRODUCT_FROM_DATABASE=Bluetooth 2.0+EDR dongle + +usb:v0A5Cp2123* + ID_PRODUCT_FROM_DATABASE=Bluetooth dongle + +usb:v0A5Cp2130* + ID_PRODUCT_FROM_DATABASE=2045 Bluetooth 2.0 USB-UHE Device with trace filter + +usb:v0A5Cp2131* + ID_PRODUCT_FROM_DATABASE=2045 Bluetooth 2.0 Device with trace filter + +usb:v0A5Cp2145* + ID_PRODUCT_FROM_DATABASE=Bluetooth with Enhanced Data Rate II + +usb:v0A5Cp2148* + ID_PRODUCT_FROM_DATABASE=BCM92046DG-CL1ROM Bluetooth 2.1 Adapter + +usb:v0A5Cp2150* + ID_PRODUCT_FROM_DATABASE=BCM2046 Bluetooth Device + +usb:v0A5Cp2151* + ID_PRODUCT_FROM_DATABASE=Bluetooth + +usb:v0A5Cp217D* + ID_PRODUCT_FROM_DATABASE=HP Bluethunder + +usb:v0A5Cp217F* + ID_PRODUCT_FROM_DATABASE=Bluetooth Controller + +usb:v0A5Cp2198* + ID_PRODUCT_FROM_DATABASE=Bluetooth 3.0 Device + +usb:v0A5Cp219B* + ID_PRODUCT_FROM_DATABASE=Bluetooth 2.1 Device + +usb:v0A5Cp21B1* + ID_PRODUCT_FROM_DATABASE=HP Bluetooth Module + +usb:v0A5Cp21B4* + ID_PRODUCT_FROM_DATABASE=BCM2070 Bluetooth 2.1 + EDR + +usb:v0A5Cp21B9* + ID_PRODUCT_FROM_DATABASE=BCM2070 Bluetooth 2.1 + EDR + +usb:v0A5Cp21BA* + ID_PRODUCT_FROM_DATABASE=BCM2070 Bluetooth 2.1 + EDR + +usb:v0A5Cp21BB* + ID_PRODUCT_FROM_DATABASE=BCM2070 Bluetooth 2.1 + EDR + +usb:v0A5Cp21BC* + ID_PRODUCT_FROM_DATABASE=BCM2070 Bluetooth 2.1 + EDR + +usb:v0A5Cp21BD* + ID_PRODUCT_FROM_DATABASE=BCM2070 Bluetooth 2.1 + EDR + +usb:v0A5Cp21D7* + ID_PRODUCT_FROM_DATABASE=BCM43142 Bluetooth 4.0 + +usb:v0A5Cp21E1* + ID_PRODUCT_FROM_DATABASE=HP Portable SoftSailing + +usb:v0A5Cp21E3* + ID_PRODUCT_FROM_DATABASE=HP Portable Valentine + +usb:v0A5Cp21E6* + ID_PRODUCT_FROM_DATABASE=BCM20702 Bluetooth 4.0 [ThinkPad] + +usb:v0A5Cp21E8* + ID_PRODUCT_FROM_DATABASE=BCM20702A0 Bluetooth 4.0 + +usb:v0A5Cp21F1* + ID_PRODUCT_FROM_DATABASE=HP Portable Bumble Bee + +usb:v0A5Cp22BE* + ID_PRODUCT_FROM_DATABASE=BCM2070 Bluetooth 3.0 + HS + +usb:v0A5Cp4500* + ID_PRODUCT_FROM_DATABASE=BCM2046B1 USB 2.0 Hub (part of BCM2046 Bluetooth) + +usb:v0A5Cp4502* + ID_PRODUCT_FROM_DATABASE=Keyboard (Boot Interface Subclass) + +usb:v0A5Cp4503* + ID_PRODUCT_FROM_DATABASE=Mouse (Boot Interface Subclass) + +usb:v0A5Cp5800* + ID_PRODUCT_FROM_DATABASE=BCM5880 Secure Applications Processor + +usb:v0A5Cp5801* + ID_PRODUCT_FROM_DATABASE=BCM5880 Secure Applications Processor with fingerprint swipe sensor + +usb:v0A5Cp5802* + ID_PRODUCT_FROM_DATABASE=BCM5880 Secure Applications Processor with fingerprint touch sensor + +usb:v0A5Cp5803* + ID_PRODUCT_FROM_DATABASE=BCM5880 Secure Applications Processor with secure keyboard + +usb:v0A5Cp6300* + ID_PRODUCT_FROM_DATABASE=Pirelli Remote NDIS Device + +usb:v0A5CpBD11* + ID_PRODUCT_FROM_DATABASE=TiVo AG0100 802.11bg Wireless Adapter [Broadcom BCM4320] + +usb:v0A5CpBD13* + ID_PRODUCT_FROM_DATABASE=BCM4323 802.11abgn Wireless Adapter + +usb:v0A5CpBD17* + ID_PRODUCT_FROM_DATABASE=BCM43236 802.11abgn Wireless Adapter + +usb:v0A5CpD11B* + ID_PRODUCT_FROM_DATABASE=Eminent EM4045 [Broadcom 4320 USB] + +usb:v0A5D* + ID_VENDOR_FROM_DATABASE=Diatrend Corp. + +usb:v0A5F* + ID_VENDOR_FROM_DATABASE=Zebra + +usb:v0A5Fp0009* + ID_PRODUCT_FROM_DATABASE=LP2844 Printer + +usb:v0A5Fp0081* + ID_PRODUCT_FROM_DATABASE=GK420t Label Printer + +usb:v0A5Fp008B* + ID_PRODUCT_FROM_DATABASE=HC100 wristbands Printer + +usb:v0A5Fp930A* + ID_PRODUCT_FROM_DATABASE=Printer + +usb:v0A62* + ID_VENDOR_FROM_DATABASE=MPMan + +usb:v0A62p0010* + ID_PRODUCT_FROM_DATABASE=MPMan MP-F40 MP3 Player + +usb:v0A66* + ID_VENDOR_FROM_DATABASE=ClearCube Technology + +usb:v0A67* + ID_VENDOR_FROM_DATABASE=Medeli Electronics Co., Ltd + +usb:v0A68* + ID_VENDOR_FROM_DATABASE=Comaide Corp. + +usb:v0A69* + ID_VENDOR_FROM_DATABASE=Chroma ate, Inc. + +usb:v0A6B* + ID_VENDOR_FROM_DATABASE=Green House Co., Ltd + +usb:v0A6Bp0001* + ID_PRODUCT_FROM_DATABASE=Compact Flash R/W with MP3 player + +usb:v0A6Bp000F* + ID_PRODUCT_FROM_DATABASE=FlashDisk + +usb:v0A6C* + ID_VENDOR_FROM_DATABASE=Integrated Circuit Systems, Inc. + +usb:v0A6D* + ID_VENDOR_FROM_DATABASE=UPS Manufacturing + +usb:v0A6E* + ID_VENDOR_FROM_DATABASE=Benwin + +usb:v0A6F* + ID_VENDOR_FROM_DATABASE=Core Technology, Inc. + +usb:v0A6Fp0400* + ID_PRODUCT_FROM_DATABASE=Xanboo + +usb:v0A70* + ID_VENDOR_FROM_DATABASE=International Game Technology + +usb:v0A71* + ID_VENDOR_FROM_DATABASE=VIPColor Technologies USA, Inc. + +usb:v0A71p0001* + ID_PRODUCT_FROM_DATABASE=VP485 Printer + +usb:v0A72* + ID_VENDOR_FROM_DATABASE=Sanwa Denshi + +usb:v0A73* + ID_VENDOR_FROM_DATABASE=Mackie Designs + +usb:v0A73p0002* + ID_PRODUCT_FROM_DATABASE=XD-2 [Spike] + +usb:v0A7D* + ID_VENDOR_FROM_DATABASE=NSTL, Inc. + +usb:v0A7E* + ID_VENDOR_FROM_DATABASE=Octagon Systems Corp. + +usb:v0A80* + ID_VENDOR_FROM_DATABASE=Rexon Technology Corp., Ltd + +usb:v0A81* + ID_VENDOR_FROM_DATABASE=Chesen Electronics Corp. + +usb:v0A81p0101* + ID_PRODUCT_FROM_DATABASE=Keyboard + +usb:v0A81p0103* + ID_PRODUCT_FROM_DATABASE=Keyboard + +usb:v0A81p0203* + ID_PRODUCT_FROM_DATABASE=Mouse + +usb:v0A81p0205* + ID_PRODUCT_FROM_DATABASE=PS/2 Keyboard+Mouse Adapter + +usb:v0A81p0701* + ID_PRODUCT_FROM_DATABASE=USB Missile Launcher + +usb:v0A81pFF01* + ID_PRODUCT_FROM_DATABASE=Wireless Missile Launcher + +usb:v0A82* + ID_VENDOR_FROM_DATABASE=Syscan + +usb:v0A82p4600* + ID_PRODUCT_FROM_DATABASE=TravelScan 460/464 + +usb:v0A83* + ID_VENDOR_FROM_DATABASE=NextComm, Inc. + +usb:v0A84* + ID_VENDOR_FROM_DATABASE=Maui Innovative Peripherals + +usb:v0A85* + ID_VENDOR_FROM_DATABASE=Idexx Labs + +usb:v0A86* + ID_VENDOR_FROM_DATABASE=NITGen Co., Ltd + +usb:v0A8D* + ID_VENDOR_FROM_DATABASE=Picturetel + +usb:v0A8E* + ID_VENDOR_FROM_DATABASE=Japan Aviation Electronics Industry, Ltd + +usb:v0A8Ep2011* + ID_PRODUCT_FROM_DATABASE=Filter Driver For JAE XMC R/W + +usb:v0A90* + ID_VENDOR_FROM_DATABASE=Candy Technology Co., Ltd + +usb:v0A91* + ID_VENDOR_FROM_DATABASE=Globlink Technology, Inc. + +usb:v0A91p3801* + ID_PRODUCT_FROM_DATABASE=Targus PAKP003 Mouse + +usb:v0A92* + ID_VENDOR_FROM_DATABASE=EGO SYStems, Inc. + +usb:v0A92p0011* + ID_PRODUCT_FROM_DATABASE=SYS WaveTerminal U2A + +usb:v0A92p0021* + ID_PRODUCT_FROM_DATABASE=GIGAPort + +usb:v0A92p0031* + ID_PRODUCT_FROM_DATABASE=GIGAPortAG + +usb:v0A92p0053* + ID_PRODUCT_FROM_DATABASE=AudioTrak Optoplay + +usb:v0A92p0061* + ID_PRODUCT_FROM_DATABASE=Waveterminal U24 + +usb:v0A92p0071* + ID_PRODUCT_FROM_DATABASE=MAYA EX7 + +usb:v0A92p0091* + ID_PRODUCT_FROM_DATABASE=Maya 44 + +usb:v0A92p00B1* + ID_PRODUCT_FROM_DATABASE=MAYA EX5 + +usb:v0A92p1000* + ID_PRODUCT_FROM_DATABASE=MIDI Mate + +usb:v0A92p1010* + ID_PRODUCT_FROM_DATABASE=RoMI/O + +usb:v0A92p1020* + ID_PRODUCT_FROM_DATABASE=M4U + +usb:v0A92p1030* + ID_PRODUCT_FROM_DATABASE=M8U + +usb:v0A92p1090* + ID_PRODUCT_FROM_DATABASE=KeyControl49 + +usb:v0A92p10A0* + ID_PRODUCT_FROM_DATABASE=KeyControl25 + +usb:v0A93* + ID_VENDOR_FROM_DATABASE=C Technologies AB + +usb:v0A93p0002* + ID_PRODUCT_FROM_DATABASE=C-Pen 10 + +usb:v0A93p0005* + ID_PRODUCT_FROM_DATABASE=MyPen Light + +usb:v0A93p000D* + ID_PRODUCT_FROM_DATABASE=Input Pen + +usb:v0A93p0010* + ID_PRODUCT_FROM_DATABASE=C-Pen 20 + +usb:v0A93p0A93* + ID_PRODUCT_FROM_DATABASE=PayPen + +usb:v0A94* + ID_VENDOR_FROM_DATABASE=Intersense + +usb:v0AA3* + ID_VENDOR_FROM_DATABASE=Lava Computer Mfg., Inc. + +usb:v0AA4* + ID_VENDOR_FROM_DATABASE=Develco Elektronik + +usb:v0AA5* + ID_VENDOR_FROM_DATABASE=First International Digital + +usb:v0AA5p0002* + ID_PRODUCT_FROM_DATABASE=irock! 500 Series + +usb:v0AA5p0801* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v0AA6* + ID_VENDOR_FROM_DATABASE=Perception Digital, Ltd + +usb:v0AA6p0101* + ID_PRODUCT_FROM_DATABASE=Hercules Jukebox + +usb:v0AA6p1501* + ID_PRODUCT_FROM_DATABASE=Store 'n' Go HD Drive + +usb:v0AA7* + ID_VENDOR_FROM_DATABASE=Wincor Nixdorf International GmbH + +usb:v0AA7p0100* + ID_PRODUCT_FROM_DATABASE=POS Keyboard, TA58P-USB + +usb:v0AA7p0101* + ID_PRODUCT_FROM_DATABASE=POS Keyboard, TA85P-USB + +usb:v0AA7p0102* + ID_PRODUCT_FROM_DATABASE=POS Keyboard, TA59-USB + +usb:v0AA7p0103* + ID_PRODUCT_FROM_DATABASE=POS Keyboard, TA60-USB + +usb:v0AA7p0104* + ID_PRODUCT_FROM_DATABASE=SNIkey Keyboard, SNIKey-KB-USB + +usb:v0AA7p0200* + ID_PRODUCT_FROM_DATABASE=Operator Display, BA63-USB + +usb:v0AA7p0201* + ID_PRODUCT_FROM_DATABASE=Operator Display, BA66-USB + +usb:v0AA7p0202* + ID_PRODUCT_FROM_DATABASE=Operator Display & Scanner, XiCheck-BA63 + +usb:v0AA7p0203* + ID_PRODUCT_FROM_DATABASE=Operator Display & Scanner, XiCheck-BA66 + +usb:v0AA7p0204* + ID_PRODUCT_FROM_DATABASE=Graphics Operator Display, BA63GV + +usb:v0AA7p0300* + ID_PRODUCT_FROM_DATABASE=POS Printer (printer class mode), TH210 + +usb:v0AA7p0301* + ID_PRODUCT_FROM_DATABASE=POS Printer (native mode), TH210 + +usb:v0AA7p0302* + ID_PRODUCT_FROM_DATABASE=POS Printer (printer class mode), TH220 + +usb:v0AA7p0303* + ID_PRODUCT_FROM_DATABASE=POS Printer (native mode), TH220 + +usb:v0AA7p0304* + ID_PRODUCT_FROM_DATABASE=POS Printer, TH230 + +usb:v0AA7p0305* + ID_PRODUCT_FROM_DATABASE=Lottery Printer, XiPrintPlus + +usb:v0AA7p0306* + ID_PRODUCT_FROM_DATABASE=POS Printer (printer class mode), TH320 + +usb:v0AA7p0307* + ID_PRODUCT_FROM_DATABASE=POS Printer (native mode), TH320 + +usb:v0AA7p0308* + ID_PRODUCT_FROM_DATABASE=POS Printer (printer class mode), TH420 + +usb:v0AA7p0309* + ID_PRODUCT_FROM_DATABASE=POS Printer (native mode), TH420 + +usb:v0AA7p030A* + ID_PRODUCT_FROM_DATABASE=POS Printer, TH200B + +usb:v0AA7p0400* + ID_PRODUCT_FROM_DATABASE=Lottery Scanner, Xiscan S + +usb:v0AA7p0401* + ID_PRODUCT_FROM_DATABASE=Lottery Scanner, Xiscan 3 + +usb:v0AA7p0402* + ID_PRODUCT_FROM_DATABASE=Programmable Magnetic Swipe Card Reader, MSRP-USB + +usb:v0AA7p0500* + ID_PRODUCT_FROM_DATABASE=IDE Adapter + +usb:v0AA7p0501* + ID_PRODUCT_FROM_DATABASE=Hub Printer Interface + +usb:v0AA7p0502* + ID_PRODUCT_FROM_DATABASE=Hub SNIKey Keyboard + +usb:v0AA7p4304* + ID_PRODUCT_FROM_DATABASE=Banking Printer TP07 + +usb:v0AA7p4305* + ID_PRODUCT_FROM_DATABASE=Banking Printer TP07c + +usb:v0AA7p4500* + ID_PRODUCT_FROM_DATABASE=WN Central Special Electronics + +usb:v0AA8* + ID_VENDOR_FROM_DATABASE=TriGem Computer, Inc. + +usb:v0AA8p0060* + ID_PRODUCT_FROM_DATABASE=TG 11Mbps WLAN Mini Adapter + +usb:v0AA8p1001* + ID_PRODUCT_FROM_DATABASE=DreamComboM4100 + +usb:v0AA8p3002* + ID_PRODUCT_FROM_DATABASE=InkJet Color Printer + +usb:v0AA8p8001* + ID_PRODUCT_FROM_DATABASE=TG_iMON + +usb:v0AA8p8002* + ID_PRODUCT_FROM_DATABASE=TG_KLOSS + +usb:v0AA8pA001* + ID_PRODUCT_FROM_DATABASE=TG_X2 + +usb:v0AA8pA002* + ID_PRODUCT_FROM_DATABASE=TGVFD_KLOSS + +usb:v0AA8pFFDA* + ID_PRODUCT_FROM_DATABASE=iMON_VFD + +usb:v0AA9* + ID_VENDOR_FROM_DATABASE=Baromtec Co. + +usb:v0AA9pF01B* + ID_PRODUCT_FROM_DATABASE=Medion MD 6242 MP3 Player + +usb:v0AAA* + ID_VENDOR_FROM_DATABASE=Japan CBM Corp. + +usb:v0AAB* + ID_VENDOR_FROM_DATABASE=Vision Shape Europe SA + +usb:v0AAC* + ID_VENDOR_FROM_DATABASE=iCompression, Inc. + +usb:v0AAD* + ID_VENDOR_FROM_DATABASE=Rohde & Schwarz GmbH & Co. KG + +usb:v0AADp0003* + ID_PRODUCT_FROM_DATABASE=NRP-Z21 + +usb:v0AADp000C* + ID_PRODUCT_FROM_DATABASE=NRP-Z11 + +usb:v0AADp0013* + ID_PRODUCT_FROM_DATABASE=NRP-Z22 + +usb:v0AADp0014* + ID_PRODUCT_FROM_DATABASE=NRP-Z23 + +usb:v0AADp0015* + ID_PRODUCT_FROM_DATABASE=NRP-Z24 + +usb:v0AADp0016* + ID_PRODUCT_FROM_DATABASE=NRP-Z51 + +usb:v0AADp0017* + ID_PRODUCT_FROM_DATABASE=NRP-Z52 + +usb:v0AADp0018* + ID_PRODUCT_FROM_DATABASE=NRP-Z55 + +usb:v0AADp0019* + ID_PRODUCT_FROM_DATABASE=NRP-Z56 + +usb:v0AADp0021* + ID_PRODUCT_FROM_DATABASE=NRP-Z91 + +usb:v0AADp0023* + ID_PRODUCT_FROM_DATABASE=NRP-Z81 + +usb:v0AADp002C* + ID_PRODUCT_FROM_DATABASE=NRP-Z31 + +usb:v0AADp002D* + ID_PRODUCT_FROM_DATABASE=NRP-Z37 + +usb:v0AADp002F* + ID_PRODUCT_FROM_DATABASE=NRP-Z27 + +usb:v0AADp0051* + ID_PRODUCT_FROM_DATABASE=NRP-Z28 + +usb:v0AADp0052* + ID_PRODUCT_FROM_DATABASE=NRP-Z98 + +usb:v0AADp0062* + ID_PRODUCT_FROM_DATABASE=NRP-Z92 + +usb:v0AADp0070* + ID_PRODUCT_FROM_DATABASE=NRP-Z57 + +usb:v0AADp0083* + ID_PRODUCT_FROM_DATABASE=NRP-Z85 + +usb:v0AADp0095* + ID_PRODUCT_FROM_DATABASE=NRP-Z86 + +usb:v0AAE* + ID_VENDOR_FROM_DATABASE=NEC infrontia Corp. (Nitsuko) + +usb:v0AAF* + ID_VENDOR_FROM_DATABASE=Digitalway Co., Ltd + +usb:v0AB0* + ID_VENDOR_FROM_DATABASE=Arrow Strong Electronics Co., Ltd + +usb:v0AB1* + ID_VENDOR_FROM_DATABASE=FEIG ELECTRONIC GmbH + +usb:v0AB1p0002* + ID_PRODUCT_FROM_DATABASE=OBID RFID-Reader + +usb:v0ABA* + ID_VENDOR_FROM_DATABASE=Ellisys + +usb:v0ABAp8001* + ID_PRODUCT_FROM_DATABASE=Tracker 110 Protocol Analyzer + +usb:v0ABAp8002* + ID_PRODUCT_FROM_DATABASE=Explorer 200 Protocol Analyzer + +usb:v0ABE* + ID_VENDOR_FROM_DATABASE=Stereo-Link + +usb:v0ABEp0101* + ID_PRODUCT_FROM_DATABASE=SL1200 DAC + +usb:v0ABF* + ID_VENDOR_FROM_DATABASE=Diolan + +usb:v0ABFp3370* + ID_PRODUCT_FROM_DATABASE=I2C/SPI Adapter - U2C-12 + +usb:v0AC3* + ID_VENDOR_FROM_DATABASE=Sanyo Semiconductor Company Micro + +usb:v0AC4* + ID_VENDOR_FROM_DATABASE=Leco Corp. + +usb:v0AC5* + ID_VENDOR_FROM_DATABASE=I & C Corp. + +usb:v0AC6* + ID_VENDOR_FROM_DATABASE=Singing Electrons, Inc. + +usb:v0AC7* + ID_VENDOR_FROM_DATABASE=Panwest Corp. + +usb:v0AC8* + ID_VENDOR_FROM_DATABASE=Z-Star Microelectronics Corp. + +usb:v0AC8p0301* + ID_PRODUCT_FROM_DATABASE=Web Camera + +usb:v0AC8p0302* + ID_PRODUCT_FROM_DATABASE=ZC0302 Webcam + +usb:v0AC8p0321* + ID_PRODUCT_FROM_DATABASE=Vimicro generic vc0321 Camera + +usb:v0AC8p0323* + ID_PRODUCT_FROM_DATABASE=Luxya WC-1200 USB 2.0 Webcam + +usb:v0AC8p0328* + ID_PRODUCT_FROM_DATABASE=A4Tech PK-130MG + +usb:v0AC8p0336* + ID_PRODUCT_FROM_DATABASE=Elecom UCAM-DLQ30 + +usb:v0AC8p301B* + ID_PRODUCT_FROM_DATABASE=ZC0301 Webcam + +usb:v0AC8p303B* + ID_PRODUCT_FROM_DATABASE=ZC0303 Webcam + +usb:v0AC8p305B* + ID_PRODUCT_FROM_DATABASE=ZC0305 Webcam + +usb:v0AC8p307B* + ID_PRODUCT_FROM_DATABASE=USB 1.1 Webcam + +usb:v0AC8p332D* + ID_PRODUCT_FROM_DATABASE=Vega USB 2.0 Camera + +usb:v0AC8p3343* + ID_PRODUCT_FROM_DATABASE=Sirius USB 2.0 Camera + +usb:v0AC8p3370* + ID_PRODUCT_FROM_DATABASE=Traveler TV 6500 SF Dia-scanner + +usb:v0AC8p3420* + ID_PRODUCT_FROM_DATABASE=Venus USB2.0 Camera + +usb:v0AC8pC001* + ID_PRODUCT_FROM_DATABASE=Sony embedded vimicro Camera + +usb:v0AC8pC002* + ID_PRODUCT_FROM_DATABASE=Visual Communication Camera VGP-VCC1 + +usb:v0AC8pC302* + ID_PRODUCT_FROM_DATABASE=Vega USB 2.0 Camera + +usb:v0AC8pC303* + ID_PRODUCT_FROM_DATABASE=Saturn USB 2.0 Camera + +usb:v0AC8pC326* + ID_PRODUCT_FROM_DATABASE=Namuga 1.3M Webcam + +usb:v0AC8pC33F* + ID_PRODUCT_FROM_DATABASE=Webcam + +usb:v0AC9* + ID_VENDOR_FROM_DATABASE=Micro Solutions, Inc. + +usb:v0AC9p0000* + ID_PRODUCT_FROM_DATABASE=Backpack CD-ReWriter + +usb:v0AC9p0001* + ID_PRODUCT_FROM_DATABASE=BACKPACK 2 Cable + +usb:v0AC9p0010* + ID_PRODUCT_FROM_DATABASE=BACKPACK + +usb:v0AC9p0011* + ID_PRODUCT_FROM_DATABASE=Backpack 40GB Hard Drive + +usb:v0AC9p0110* + ID_PRODUCT_FROM_DATABASE=BACKPACK + +usb:v0AC9p0111* + ID_PRODUCT_FROM_DATABASE=BackPack + +usb:v0AC9p1234* + ID_PRODUCT_FROM_DATABASE=BACKPACK + +usb:v0ACA* + ID_VENDOR_FROM_DATABASE=OPEN Networks Ltd + +usb:v0ACAp1060* + ID_PRODUCT_FROM_DATABASE=OPEN NT1 Plus II + +usb:v0ACC* + ID_VENDOR_FROM_DATABASE=Koga Electronics Co. + +usb:v0ACD* + ID_VENDOR_FROM_DATABASE=ID Tech + +usb:v0ACDp0300* + ID_PRODUCT_FROM_DATABASE=IDT1221U RS-232 Adapter + +usb:v0ACDp0401* + ID_PRODUCT_FROM_DATABASE=Spectrum III Hybrid Smartcard Reader + +usb:v0ACDp0630* + ID_PRODUCT_FROM_DATABASE=Spectrum III Mag-Only Insert Reader (SPT3-355 Series) USB-CDC + +usb:v0ACE* + ID_VENDOR_FROM_DATABASE=ZyDAS + +usb:v0ACEp1201* + ID_PRODUCT_FROM_DATABASE=ZD1201 802.11b + +usb:v0ACEp1211* + ID_PRODUCT_FROM_DATABASE=ZD1211 802.11g + +usb:v0ACEp1215* + ID_PRODUCT_FROM_DATABASE=ZD1211B 802.11g + +usb:v0ACEp1221* + ID_PRODUCT_FROM_DATABASE=ZD1221 802.11n + +usb:v0ACEp1602* + ID_PRODUCT_FROM_DATABASE=ZyXEL Omni FaxModem 56K + +usb:v0ACEp1608* + ID_PRODUCT_FROM_DATABASE=ZyXEL Omni FaxModem 56K UNO + +usb:v0ACEp1611* + ID_PRODUCT_FROM_DATABASE=ZyXEL Omni FaxModem 56K Plus + +usb:v0ACEp2011* + ID_PRODUCT_FROM_DATABASE=Virtual media for 802.11bg + +usb:v0ACEp20FF* + ID_PRODUCT_FROM_DATABASE=Virtual media for 802.11bg + +usb:v0ACEpA211* + ID_PRODUCT_FROM_DATABASE=ZD1211 802.11b/g Wireless Adapter + +usb:v0ACEpB215* + ID_PRODUCT_FROM_DATABASE=802.11bg + +usb:v0ACF* + ID_VENDOR_FROM_DATABASE=Intoto, Inc. + +usb:v0AD0* + ID_VENDOR_FROM_DATABASE=Intellix Corp. + +usb:v0AD1* + ID_VENDOR_FROM_DATABASE=Remotec Technology, Ltd + +usb:v0AD2* + ID_VENDOR_FROM_DATABASE=Service & Quality Technology Co., Ltd + +usb:v0ADA* + ID_VENDOR_FROM_DATABASE=Data Encryption Systems Ltd. + +usb:v0ADAp0005* + ID_PRODUCT_FROM_DATABASE=DK2 + +usb:v0AE3* + ID_VENDOR_FROM_DATABASE=Allion Computer, Inc. + +usb:v0AE4* + ID_VENDOR_FROM_DATABASE=Taito Corp. + +usb:v0AE7* + ID_VENDOR_FROM_DATABASE=Neodym Systems, Inc. + +usb:v0AE8* + ID_VENDOR_FROM_DATABASE=System Support Co., Ltd + +usb:v0AE9* + ID_VENDOR_FROM_DATABASE=North Shore Circuit Design L.L.P. + +usb:v0AEA* + ID_VENDOR_FROM_DATABASE=SciEssence, LLC + +usb:v0AEB* + ID_VENDOR_FROM_DATABASE=TTP Communications, Ltd + +usb:v0AEC* + ID_VENDOR_FROM_DATABASE=Neodio Technologies Corp. + +usb:v0AECp2101* + ID_PRODUCT_FROM_DATABASE=SmartMedia Card Reader + +usb:v0AECp2102* + ID_PRODUCT_FROM_DATABASE=CompactFlash Card Reader + +usb:v0AECp2103* + ID_PRODUCT_FROM_DATABASE=MMC/SD Card Reader + +usb:v0AECp2104* + ID_PRODUCT_FROM_DATABASE=MemoryStick Card Reader + +usb:v0AECp2201* + ID_PRODUCT_FROM_DATABASE=SmartMedia+CompactFlash Card Reader + +usb:v0AECp2202* + ID_PRODUCT_FROM_DATABASE=SmartMedia+MMC/SD Card Reader + +usb:v0AECp2203* + ID_PRODUCT_FROM_DATABASE=SmartMedia+MemoryStick Card Reader + +usb:v0AECp2204* + ID_PRODUCT_FROM_DATABASE=CompactFlash+MMC/SD Card Reader + +usb:v0AECp2205* + ID_PRODUCT_FROM_DATABASE=CompactFlash+MemoryStick Card Reader + +usb:v0AECp2206* + ID_PRODUCT_FROM_DATABASE=MMC/SD+MemoryStick Card Reader + +usb:v0AECp2301* + ID_PRODUCT_FROM_DATABASE=SmartMedia+CompactFlash+MMC/SD Card Reader + +usb:v0AECp2302* + ID_PRODUCT_FROM_DATABASE=SmartMedia+CompactFlash+MemoryStick Card Reader + +usb:v0AECp2303* + ID_PRODUCT_FROM_DATABASE=SmartMedia+MMC/SD+MemoryStick Card Reader + +usb:v0AECp2304* + ID_PRODUCT_FROM_DATABASE=CompactFlash+MMC/SD+MemoryStick Card Reader + +usb:v0AECp3016* + ID_PRODUCT_FROM_DATABASE=MMC/SD+Memory Stick Card Reader + +usb:v0AECp3050* + ID_PRODUCT_FROM_DATABASE=ND3050 8-in-1 Card Reader + +usb:v0AECp3060* + ID_PRODUCT_FROM_DATABASE=1.1 FS Card Reader + +usb:v0AECp3101* + ID_PRODUCT_FROM_DATABASE=MMC/SD Card Reader + +usb:v0AECp3102* + ID_PRODUCT_FROM_DATABASE=MemoryStick Card Reader + +usb:v0AECp3201* + ID_PRODUCT_FROM_DATABASE=MMC/SD+MemoryStick Card Reader + +usb:v0AECp3216* + ID_PRODUCT_FROM_DATABASE=HS Card Reader + +usb:v0AECp3260* + ID_PRODUCT_FROM_DATABASE=7-in-1 Card Reader + +usb:v0AECp5010* + ID_PRODUCT_FROM_DATABASE=ND5010 Card Reader + +usb:v0AF0* + ID_VENDOR_FROM_DATABASE=Option + +usb:v0AF0p5000* + ID_PRODUCT_FROM_DATABASE=UMTS Card + +usb:v0AF0p6000* + ID_PRODUCT_FROM_DATABASE=GlobeTrotter 3G datacard + +usb:v0AF0p6300* + ID_PRODUCT_FROM_DATABASE=GT 3G Quad UMTS/GPRS Card + +usb:v0AF0p6600* + ID_PRODUCT_FROM_DATABASE=GlobeTrotter 3G+ datacard + +usb:v0AF0p6711* + ID_PRODUCT_FROM_DATABASE=GlobeTrotter Express 7.2 v2 + +usb:v0AF0p6971* + ID_PRODUCT_FROM_DATABASE=Globetrotter HSDPA Modem + +usb:v0AF0p7251* + ID_PRODUCT_FROM_DATABASE=Globetrotter HSUPA Modem (aka iCON HSUPA E) + +usb:v0AF0p7501* + ID_PRODUCT_FROM_DATABASE=Globetrotter HSUPA Modem (icon 411 aka "Vodafone K3760") + +usb:v0AF0p7601* + ID_PRODUCT_FROM_DATABASE=Globetrotter MO40x 3G Modem (GTM 382) + +usb:v0AF0p7701* + ID_PRODUCT_FROM_DATABASE=Globetrotter HSUPA Modem (aka icon 451) + +usb:v0AF0pD055* + ID_PRODUCT_FROM_DATABASE=Globetrotter GI0505 [iCON 505] + +usb:v0AF6* + ID_VENDOR_FROM_DATABASE=Silver I Co., Ltd + +usb:v0AF7* + ID_VENDOR_FROM_DATABASE=B2C2, Inc. + +usb:v0AF7p0101* + ID_PRODUCT_FROM_DATABASE=Digital TV USB Receiver (DVB-S/T/C / ATSC) + +usb:v0AF9* + ID_VENDOR_FROM_DATABASE=Hama, Inc. + +usb:v0AF9p0010* + ID_PRODUCT_FROM_DATABASE=USB SightCam 100 + +usb:v0AF9p0011* + ID_PRODUCT_FROM_DATABASE=Micro Innovations IC50C Webcam + +usb:v0AFC* + ID_VENDOR_FROM_DATABASE=Zaptronix Ltd + +usb:v0AFD* + ID_VENDOR_FROM_DATABASE=Tateno Dennou, Inc. + +usb:v0AFE* + ID_VENDOR_FROM_DATABASE=Cummins Engine Co. + +usb:v0AFF* + ID_VENDOR_FROM_DATABASE=Jump Zone Network Products, Inc. + +usb:v0B00* + ID_VENDOR_FROM_DATABASE=INGENICO + +usb:v0B05* + ID_VENDOR_FROM_DATABASE=ASUSTek Computer, Inc. + +usb:v0B05p1101* + ID_PRODUCT_FROM_DATABASE=Mass Storage (UISDMC4S) + +usb:v0B05p1706* + ID_PRODUCT_FROM_DATABASE=WL-167G v1 802.11g Adapter [Ralink RT2571] + +usb:v0B05p1707* + ID_PRODUCT_FROM_DATABASE=WL-167G v1 802.11g Adapter [Ralink RT2571] + +usb:v0B05p1708* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v0B05p170B* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v0B05p170C* + ID_PRODUCT_FROM_DATABASE=WL-159g 802.11bg + +usb:v0B05p170D* + ID_PRODUCT_FROM_DATABASE=802.11b/g Wireless Network Adapter + +usb:v0B05p1712* + ID_PRODUCT_FROM_DATABASE=BT-183 Bluetooth 2.0+EDR adapter + +usb:v0B05p1715* + ID_PRODUCT_FROM_DATABASE=2045 Bluetooth 2.0 Device with trace filter + +usb:v0B05p1716* + ID_PRODUCT_FROM_DATABASE=Bluetooth Device + +usb:v0B05p1717* + ID_PRODUCT_FROM_DATABASE=WL169gE 802.11g Adapter [Broadcom 4320 USB] + +usb:v0B05p171B* + ID_PRODUCT_FROM_DATABASE=A9T wireless 802.11bg + +usb:v0B05p171C* + ID_PRODUCT_FROM_DATABASE=802.11b/g Wireless Network Adapter + +usb:v0B05p171F* + ID_PRODUCT_FROM_DATABASE=My Cinema U3000 Mini [DiBcom DiB7700P] + +usb:v0B05p1723* + ID_PRODUCT_FROM_DATABASE=WL-167G v2 802.11g Adapter [Ralink RT2571W] + +usb:v0B05p1724* + ID_PRODUCT_FROM_DATABASE=RT2573 + +usb:v0B05p1726* + ID_PRODUCT_FROM_DATABASE=Laptop OLED Display + +usb:v0B05p172A* + ID_PRODUCT_FROM_DATABASE=ASUS 802.11n Network Adapter + +usb:v0B05p172B* + ID_PRODUCT_FROM_DATABASE=802.11n Network Adapter + +usb:v0B05p1731* + ID_PRODUCT_FROM_DATABASE=802.11n Network Adapter + +usb:v0B05p1732* + ID_PRODUCT_FROM_DATABASE=802.11n Network Adapter + +usb:v0B05p1734* + ID_PRODUCT_FROM_DATABASE=ASUS AF-200 + +usb:v0B05p173C* + ID_PRODUCT_FROM_DATABASE=BT-183 Bluetooth 2.0 + +usb:v0B05p173F* + ID_PRODUCT_FROM_DATABASE=My Cinema U3100 Mini + +usb:v0B05p1742* + ID_PRODUCT_FROM_DATABASE=802.11n Network Adapter + +usb:v0B05p1743* + ID_PRODUCT_FROM_DATABASE=Xonar U1 Audio Station + +usb:v0B05p1751* + ID_PRODUCT_FROM_DATABASE=BT-253 Bluetooth Adapter + +usb:v0B05p175B* + ID_PRODUCT_FROM_DATABASE=Laptop OLED Display + +usb:v0B05p1760* + ID_PRODUCT_FROM_DATABASE=802.11n Network Adapter + +usb:v0B05p1761* + ID_PRODUCT_FROM_DATABASE=USB-N11 802.11n Network Adapter [Ralink RT2870] + +usb:v0B05p1774* + ID_PRODUCT_FROM_DATABASE=Gobi Wireless Modem (QDL mode) + +usb:v0B05p1776* + ID_PRODUCT_FROM_DATABASE=Gobi Wireless Modem + +usb:v0B05p1779* + ID_PRODUCT_FROM_DATABASE=My Cinema U3100 Mini Plus [AF9035A] + +usb:v0B05p1784* + ID_PRODUCT_FROM_DATABASE=USB-N13 802.11n Network Adapter (rev. A1) [Ralink RT3072] + +usb:v0B05p1786* + ID_PRODUCT_FROM_DATABASE=USB-N10 802.11n Network Adapter [Realtek RTL8188SU] + +usb:v0B05p1791* + ID_PRODUCT_FROM_DATABASE=WL-167G v3 802.11n Adapter [Realtek RTL8188SU] + +usb:v0B05p179D* + ID_PRODUCT_FROM_DATABASE=USB-N53 802.11abgn Network Adapter [Ralink RT3572] + +usb:v0B05p179E* + ID_PRODUCT_FROM_DATABASE=Eee Note EA800 (network mode) + +usb:v0B05p179F* + ID_PRODUCT_FROM_DATABASE=Eee Note EA800 (tablet mode) + +usb:v0B05p17A1* + ID_PRODUCT_FROM_DATABASE=Eee Note EA800 (mass storage mode) + +usb:v0B05p17AB* + ID_PRODUCT_FROM_DATABASE=USB-N13 802.11n Network Adapter (rev. B1) [Realtek RTL8192CU] + +usb:v0B05p4C80* + ID_PRODUCT_FROM_DATABASE=Transformer Pad TF300TG + +usb:v0B05p4C90* + ID_PRODUCT_FROM_DATABASE=Transformer Pad Infinity TF700 + +usb:v0B05p4C91* + ID_PRODUCT_FROM_DATABASE=Transformer Pad Infinity TF700 (Debug mode) + +usb:v0B05p4D00* + ID_PRODUCT_FROM_DATABASE=Transformer Prime TF201 + +usb:v0B05p4D01* + ID_PRODUCT_FROM_DATABASE=Transformer Prime TF201 (debug mode) + +usb:v0B05p4DAF* + ID_PRODUCT_FROM_DATABASE=Transformer Pad Infinity TF700 (Fastboot) + +usb:v0B05p6101* + ID_PRODUCT_FROM_DATABASE=Cable Modem + +usb:v0B05p620A* + ID_PRODUCT_FROM_DATABASE=Remote NDIS Device + +usb:v0B05pB700* + ID_PRODUCT_FROM_DATABASE=Broadcom Bluetooth 2.1 + +usb:v0B0B* + ID_VENDOR_FROM_DATABASE=Datamax-O'Neil + +usb:v0B0Bp106E* + ID_PRODUCT_FROM_DATABASE=Datamax E-4304 + +usb:v0B0C* + ID_VENDOR_FROM_DATABASE=Todos AB + +usb:v0B0Cp0009* + ID_PRODUCT_FROM_DATABASE=Todos Argos Mini II Smart Card Reader + +usb:v0B0Cp001E* + ID_PRODUCT_FROM_DATABASE=e.dentifier2 (ABN AMRO electronic banking card reader NL) + +usb:v0B0Cp002E* + ID_PRODUCT_FROM_DATABASE=C200 smartcard controller (Nordea card reader) + +usb:v0B0Cp003F* + ID_PRODUCT_FROM_DATABASE=Todos C400 smartcard controller (Handelsbanken card reader) + +usb:v0B0Cp0050* + ID_PRODUCT_FROM_DATABASE=Argos Mini II Smart Card Reader (CCID) + +usb:v0B0D* + ID_VENDOR_FROM_DATABASE=ProjectLab + +usb:v0B0Dp0000* + ID_PRODUCT_FROM_DATABASE=CenturyCD + +usb:v0B0E* + ID_VENDOR_FROM_DATABASE=GN Netcom + +usb:v0B0Ep1022* + ID_PRODUCT_FROM_DATABASE=Jabra PRO 9450, Type 9400BS (DECT Headset) + +usb:v0B0F* + ID_VENDOR_FROM_DATABASE=AVID Technology + +usb:v0B10* + ID_VENDOR_FROM_DATABASE=Pcally + +usb:v0B11* + ID_VENDOR_FROM_DATABASE=I Tech Solutions Co., Ltd + +usb:v0B1E* + ID_VENDOR_FROM_DATABASE=Electronic Warfare Assoc., Inc. (EWA) + +usb:v0B1Ep8007* + ID_PRODUCT_FROM_DATABASE=Blackhawk USB560-BP JTAG Emulator + +usb:v0B1F* + ID_VENDOR_FROM_DATABASE=Insyde Software Corp. + +usb:v0B20* + ID_VENDOR_FROM_DATABASE=TransDimension, Inc. + +usb:v0B21* + ID_VENDOR_FROM_DATABASE=Yokogawa Electric Corp. + +usb:v0B22* + ID_VENDOR_FROM_DATABASE=Japan System Development Co., Ltd + +usb:v0B23* + ID_VENDOR_FROM_DATABASE=Pan-Asia Electronics Co., Ltd + +usb:v0B24* + ID_VENDOR_FROM_DATABASE=Link Evolution Corp. + +usb:v0B27* + ID_VENDOR_FROM_DATABASE=Ritek Corp. + +usb:v0B28* + ID_VENDOR_FROM_DATABASE=Kenwood Corp. + +usb:v0B2C* + ID_VENDOR_FROM_DATABASE=Village Center, Inc. + +usb:v0B30* + ID_VENDOR_FROM_DATABASE=PNY Technologies, Inc. + +usb:v0B30p0006* + ID_PRODUCT_FROM_DATABASE=SM Media-Shuttle Card Reader + +usb:v0B33* + ID_VENDOR_FROM_DATABASE=Contour Design, Inc. + +usb:v0B33p0020* + ID_PRODUCT_FROM_DATABASE=ShuttleXpress + +usb:v0B37* + ID_VENDOR_FROM_DATABASE=Hitachi ULSI Systems Co., Ltd + +usb:v0B38* + ID_VENDOR_FROM_DATABASE=Gear Head + +usb:v0B38p0003* + ID_PRODUCT_FROM_DATABASE=Keyboard + +usb:v0B38p0010* + ID_PRODUCT_FROM_DATABASE=107-Key Keyboard + +usb:v0B39* + ID_VENDOR_FROM_DATABASE=Omnidirectional Control Technology, Inc. + +usb:v0B39p0001* + ID_PRODUCT_FROM_DATABASE=Composite USB PS2 Converter + +usb:v0B39p0109* + ID_PRODUCT_FROM_DATABASE=USB TO Ethernet + +usb:v0B39p0421* + ID_PRODUCT_FROM_DATABASE=Serial + +usb:v0B39p0801* + ID_PRODUCT_FROM_DATABASE=USB-Parallel Bridge + +usb:v0B39p0901* + ID_PRODUCT_FROM_DATABASE=OCT To Fast Ethernet Converter + +usb:v0B39p0C03* + ID_PRODUCT_FROM_DATABASE=LAN DOCK Serial Converter + +usb:v0B3A* + ID_VENDOR_FROM_DATABASE=IPaxess + +usb:v0B3B* + ID_VENDOR_FROM_DATABASE=Tekram Technology Co., Ltd + +usb:v0B3Bp0163* + ID_PRODUCT_FROM_DATABASE=TL-WN320G 1.0 WLAN Adapter + +usb:v0B3Bp1601* + ID_PRODUCT_FROM_DATABASE=Allnet 0193 802.11b Adapter + +usb:v0B3Bp1602* + ID_PRODUCT_FROM_DATABASE=ZyXEL ZyAIR B200 802.11b Adapter + +usb:v0B3Bp1612* + ID_PRODUCT_FROM_DATABASE=AIR.Mate 2@net 802.11b Adapter + +usb:v0B3Bp1613* + ID_PRODUCT_FROM_DATABASE=802.11b Wireless LAN Adapter + +usb:v0B3Bp1620* + ID_PRODUCT_FROM_DATABASE=Allnet Wireless Network Adapter [Envara WiND512] + +usb:v0B3Bp1630* + ID_PRODUCT_FROM_DATABASE=QuickWLAN 802.11bg + +usb:v0B3Bp5630* + ID_PRODUCT_FROM_DATABASE=802.11bg + +usb:v0B3Bp6630* + ID_PRODUCT_FROM_DATABASE=ZD1211 + +usb:v0B3C* + ID_VENDOR_FROM_DATABASE=Olivetti Techcenter + +usb:v0B3CpA010* + ID_PRODUCT_FROM_DATABASE=Simple_Way Printer/Scanner/Copier + +usb:v0B3CpC000* + ID_PRODUCT_FROM_DATABASE=Olicard 100 + +usb:v0B3CpC700* + ID_PRODUCT_FROM_DATABASE=Olicard 100 (Mass Storage mode) + +usb:v0B3E* + ID_VENDOR_FROM_DATABASE=Kikusui Electronics Corp. + +usb:v0B41* + ID_VENDOR_FROM_DATABASE=Hal Corp. + +usb:v0B41p0011* + ID_PRODUCT_FROM_DATABASE=Crossam2+USB IR commander + +usb:v0B43* + ID_VENDOR_FROM_DATABASE=Play.com, Inc. + +usb:v0B43p0003* + ID_PRODUCT_FROM_DATABASE=PS2 Controller Converter + +usb:v0B43p0005* + ID_PRODUCT_FROM_DATABASE=GameCube Adaptor + +usb:v0B47* + ID_VENDOR_FROM_DATABASE=Sportbug.com, Inc. + +usb:v0B48* + ID_VENDOR_FROM_DATABASE=TechnoTrend AG + +usb:v0B48p1003* + ID_PRODUCT_FROM_DATABASE=Technotrend/Hauppauge USB-Nova + +usb:v0B48p1004* + ID_PRODUCT_FROM_DATABASE=TT-PCline + +usb:v0B48p1005* + ID_PRODUCT_FROM_DATABASE=Technotrend/Hauppauge USB-Nova + +usb:v0B48p1006* + ID_PRODUCT_FROM_DATABASE=Technotrend/Hauppauge DEC3000-s + +usb:v0B48p1007* + ID_PRODUCT_FROM_DATABASE=TT-micro plus Device + +usb:v0B48p1008* + ID_PRODUCT_FROM_DATABASE=Technotrend/Hauppauge DEC2000-t + +usb:v0B48p1009* + ID_PRODUCT_FROM_DATABASE=Technotrend/Hauppauge DEC2540-t + +usb:v0B48p3001* + ID_PRODUCT_FROM_DATABASE=DVB-S receiver + +usb:v0B48p3002* + ID_PRODUCT_FROM_DATABASE=DVB-C receiver + +usb:v0B48p3003* + ID_PRODUCT_FROM_DATABASE=DVB-T receiver + +usb:v0B48p3004* + ID_PRODUCT_FROM_DATABASE=TT TV-Stick + +usb:v0B48p3005* + ID_PRODUCT_FROM_DATABASE=TT TV-Stick (8kB EEPROM) + +usb:v0B48p3006* + ID_PRODUCT_FROM_DATABASE=TT-connect S-2400 DVB-S receiver + +usb:v0B48p3007* + ID_PRODUCT_FROM_DATABASE=TT-connect S2-3600 + +usb:v0B48p3008* + ID_PRODUCT_FROM_DATABASE=TT-connect + +usb:v0B48p3009* + ID_PRODUCT_FROM_DATABASE=TT-connect S-2400 DVB-S receiver (8kB EEPROM) + +usb:v0B48p300A* + ID_PRODUCT_FROM_DATABASE=TT-connect S2-3650 CI + +usb:v0B48p300B* + ID_PRODUCT_FROM_DATABASE=TT-connect C-3650 CI + +usb:v0B48p300C* + ID_PRODUCT_FROM_DATABASE=TT-connect T-3650 CI + +usb:v0B48p300D* + ID_PRODUCT_FROM_DATABASE=TT-connect CT-3650 CI + +usb:v0B48p300E* + ID_PRODUCT_FROM_DATABASE=TT-connect C-2400 + +usb:v0B49* + ID_VENDOR_FROM_DATABASE=ASCII Corp. + +usb:v0B49p064F* + ID_PRODUCT_FROM_DATABASE=Trance Vibrator + +usb:v0B4B* + ID_VENDOR_FROM_DATABASE=Pine Corp. Ltd. + +usb:v0B4Bp0100* + ID_PRODUCT_FROM_DATABASE=D'music MP3 Player + +usb:v0B4D* + ID_VENDOR_FROM_DATABASE=Graphtec America, Inc. + +usb:v0B4Dp110A* + ID_PRODUCT_FROM_DATABASE=Graphtec CC200-20 + +usb:v0B4E* + ID_VENDOR_FROM_DATABASE=Musical Electronics, Ltd + +usb:v0B4Ep6500* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v0B4Ep8028* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v0B4Ep8920* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v0B50* + ID_VENDOR_FROM_DATABASE=Dumpries Co., Ltd + +usb:v0B51* + ID_VENDOR_FROM_DATABASE=Comfort Keyboard Co. + +usb:v0B51p0020* + ID_PRODUCT_FROM_DATABASE=Comfort Keyboard + +usb:v0B52* + ID_VENDOR_FROM_DATABASE=Colorado MicroDisplay, Inc. + +usb:v0B54* + ID_VENDOR_FROM_DATABASE=Sinbon Electronics Co., Ltd + +usb:v0B56* + ID_VENDOR_FROM_DATABASE=TYI Systems, Ltd + +usb:v0B57* + ID_VENDOR_FROM_DATABASE=Beijing HanwangTechnology Co., Ltd + +usb:v0B59* + ID_VENDOR_FROM_DATABASE=Lake Communications, Ltd + +usb:v0B5A* + ID_VENDOR_FROM_DATABASE=Corel Corp. + +usb:v0B5F* + ID_VENDOR_FROM_DATABASE=Green Electronics Co., Ltd + +usb:v0B60* + ID_VENDOR_FROM_DATABASE=Nsine, Ltd + +usb:v0B61* + ID_VENDOR_FROM_DATABASE=NEC Viewtechnology, Ltd + +usb:v0B62* + ID_VENDOR_FROM_DATABASE=Orange Micro, Inc. + +usb:v0B62p000B* + ID_PRODUCT_FROM_DATABASE=Bluetooth Device + +usb:v0B62p0059* + ID_PRODUCT_FROM_DATABASE=iBOT2 Webcam + +usb:v0B63* + ID_VENDOR_FROM_DATABASE=ADLink Technology, Inc. + +usb:v0B64* + ID_VENDOR_FROM_DATABASE=Wonderful Wire Cable Co., Ltd + +usb:v0B65* + ID_VENDOR_FROM_DATABASE=Expert Magnetics Corp. + +usb:v0B69* + ID_VENDOR_FROM_DATABASE=CacheVision + +usb:v0B6A* + ID_VENDOR_FROM_DATABASE=Maxim Integrated Products + +usb:v0B6F* + ID_VENDOR_FROM_DATABASE=Nagano Japan Radio Co., Ltd + +usb:v0B70* + ID_VENDOR_FROM_DATABASE=PortalPlayer, Inc. + +usb:v0B70p00BA* + ID_PRODUCT_FROM_DATABASE=iRiver H10 20GB + +usb:v0B71* + ID_VENDOR_FROM_DATABASE=SHIN-EI Sangyo Co., Ltd + +usb:v0B72* + ID_VENDOR_FROM_DATABASE=Embedded Wireless Technology Co., Ltd + +usb:v0B73* + ID_VENDOR_FROM_DATABASE=Computone Corp. + +usb:v0B75* + ID_VENDOR_FROM_DATABASE=Roland DG Corp. + +usb:v0B79* + ID_VENDOR_FROM_DATABASE=Sunrise Telecom, Inc. + +usb:v0B7A* + ID_VENDOR_FROM_DATABASE=Zeevo, Inc. + +usb:v0B7Ap07D0* + ID_PRODUCT_FROM_DATABASE=Bluetooth Dongle + +usb:v0B7B* + ID_VENDOR_FROM_DATABASE=Taiko Denki Co., Ltd + +usb:v0B7C* + ID_VENDOR_FROM_DATABASE=ITRAN Communications, Ltd + +usb:v0B7D* + ID_VENDOR_FROM_DATABASE=Astrodesign, Inc. + +usb:v0B81* + ID_VENDOR_FROM_DATABASE=id3 Semiconductors + +usb:v0B81p0001* + ID_PRODUCT_FROM_DATABASE=Biothentic II smartcard reader with fingerprint sensor + +usb:v0B81p0002* + ID_PRODUCT_FROM_DATABASE=DFU-Enabled Devices (DFU) + +usb:v0B81p0012* + ID_PRODUCT_FROM_DATABASE=BioPAD biometric module (DFU + CDC) + +usb:v0B81p0102* + ID_PRODUCT_FROM_DATABASE=Certis V1 fingerprint reader + +usb:v0B81p0103* + ID_PRODUCT_FROM_DATABASE=Certis V2 fingerprint reader + +usb:v0B81p0200* + ID_PRODUCT_FROM_DATABASE=CL1356T / CL1356T5 / CL1356A smartcard readers (CCID) + +usb:v0B81p0201* + ID_PRODUCT_FROM_DATABASE=CL1356T / CL1356T5 / CL1356A smartcard readers (DFU + CCID) + +usb:v0B81p0220* + ID_PRODUCT_FROM_DATABASE=CL1356A FFPJP smartcard reader (CCID + HID) + +usb:v0B81p0221* + ID_PRODUCT_FROM_DATABASE=CL1356A smartcard reader (DFU + CCID + HID) + +usb:v0B84* + ID_VENDOR_FROM_DATABASE=Rextron Technology, Inc. + +usb:v0B85* + ID_VENDOR_FROM_DATABASE=Elkat Electronics, Sdn., Bhd. + +usb:v0B86* + ID_VENDOR_FROM_DATABASE=Exputer Systems, Inc. + +usb:v0B86p5100* + ID_PRODUCT_FROM_DATABASE=XMC5100 Zippy Drive + +usb:v0B86p5110* + ID_PRODUCT_FROM_DATABASE=XMC5110 Flash Drive + +usb:v0B86p5200* + ID_PRODUCT_FROM_DATABASE=XMC5200 Zippy Drive + +usb:v0B86p5201* + ID_PRODUCT_FROM_DATABASE=XMC5200 Zippy Drive + +usb:v0B86p5202* + ID_PRODUCT_FROM_DATABASE=XMC5200 Zippy Drive + +usb:v0B86p5280* + ID_PRODUCT_FROM_DATABASE=XMC5280 Storage Drive + +usb:v0B86pFFF0* + ID_PRODUCT_FROM_DATABASE=ISP5200 Debugger + +usb:v0B87* + ID_VENDOR_FROM_DATABASE=Plus-One I & T, Inc. + +usb:v0B88* + ID_VENDOR_FROM_DATABASE=Sigma Koki Co., Ltd, Technology Center + +usb:v0B89* + ID_VENDOR_FROM_DATABASE=Advanced Digital Broadcast, Ltd + +usb:v0B8C* + ID_VENDOR_FROM_DATABASE=SMART Technologies Inc. + +usb:v0B8Cp0001* + ID_PRODUCT_FROM_DATABASE=Interactive Whiteboard Controller (SB6) (HID) + +usb:v0B8Cp00C3* + ID_PRODUCT_FROM_DATABASE=Sympodium ID350 + +usb:v0B95* + ID_VENDOR_FROM_DATABASE=ASIX Electronics Corp. + +usb:v0B95p1720* + ID_PRODUCT_FROM_DATABASE=10/100 Ethernet + +usb:v0B95p1780* + ID_PRODUCT_FROM_DATABASE=AX88178 + +usb:v0B95p7720* + ID_PRODUCT_FROM_DATABASE=AX88772 + +usb:v0B95p772A* + ID_PRODUCT_FROM_DATABASE=AX88772A Fast Ethernet + +usb:v0B95p772B* + ID_PRODUCT_FROM_DATABASE=AX88772B + +usb:v0B95p7E2B* + ID_PRODUCT_FROM_DATABASE=AX88772B + +usb:v0B96* + ID_VENDOR_FROM_DATABASE=Sewon Telecom + +usb:v0B97* + ID_VENDOR_FROM_DATABASE=O2 Micro, Inc. + +usb:v0B97p7732* + ID_PRODUCT_FROM_DATABASE=Smart Card Reader + +usb:v0B97p7761* + ID_PRODUCT_FROM_DATABASE=Oz776 1.1 Hub + +usb:v0B97p7762* + ID_PRODUCT_FROM_DATABASE=Oz776 SmartCard Reader + +usb:v0B97p7772* + ID_PRODUCT_FROM_DATABASE=OZ776 CCID Smartcard Reader + +usb:v0B98* + ID_VENDOR_FROM_DATABASE=Playmates Toys, Inc. + +usb:v0B99* + ID_VENDOR_FROM_DATABASE=Audio International, Inc. + +usb:v0B9B* + ID_VENDOR_FROM_DATABASE=Dipl.-Ing. Stefan Kunde + +usb:v0B9Bp4012* + ID_PRODUCT_FROM_DATABASE=Reflex RC-controller Interface + +usb:v0B9D* + ID_VENDOR_FROM_DATABASE=Softprotec Co. + +usb:v0B9F* + ID_VENDOR_FROM_DATABASE=Chippo Technologies + +usb:v0BAF* + ID_VENDOR_FROM_DATABASE=U.S. Robotics + +usb:v0BAFp00E5* + ID_PRODUCT_FROM_DATABASE=USR6000 + +usb:v0BAFp00EB* + ID_PRODUCT_FROM_DATABASE=USR1120 802.11b Adapter + +usb:v0BAFp00EC* + ID_PRODUCT_FROM_DATABASE=56K Faxmodem + +usb:v0BAFp00F1* + ID_PRODUCT_FROM_DATABASE=SureConnect ADSL ATM Adapter + +usb:v0BAFp00F2* + ID_PRODUCT_FROM_DATABASE=SureConnect ADSL Loader + +usb:v0BAFp00F5* + ID_PRODUCT_FROM_DATABASE=SureConnect ADSL ATM Adapter + +usb:v0BAFp00F6* + ID_PRODUCT_FROM_DATABASE=SureConnect ADSL Loader + +usb:v0BAFp00F7* + ID_PRODUCT_FROM_DATABASE=SureConnect ADSL ATM Adapter + +usb:v0BAFp00F8* + ID_PRODUCT_FROM_DATABASE=SureConnect ADSL Loader + +usb:v0BAFp00F9* + ID_PRODUCT_FROM_DATABASE=SureConnect ADSL ATM Adapter + +usb:v0BAFp00FA* + ID_PRODUCT_FROM_DATABASE=SureConnect ADSL Loader + +usb:v0BAFp00FB* + ID_PRODUCT_FROM_DATABASE=SureConnect ADSL Ethernet/USB Router + +usb:v0BAFp0111* + ID_PRODUCT_FROM_DATABASE=USR5420 802.11g Adapter [Broadcom 4320 USB] + +usb:v0BAFp0118* + ID_PRODUCT_FROM_DATABASE=U5 802.11g Adapter + +usb:v0BAFp011B* + ID_PRODUCT_FROM_DATABASE=Wireless MAXg Adapter [Broadcom 4320] + +usb:v0BAFp0121* + ID_PRODUCT_FROM_DATABASE=USR5423 802.11bg Wireless Adapter [ZyDAS ZD1211B] + +usb:v0BAFp6112* + ID_PRODUCT_FROM_DATABASE=FaxModem Model 5633 + +usb:v0BB0* + ID_VENDOR_FROM_DATABASE=Concord Camera Corp. + +usb:v0BB0p0100* + ID_PRODUCT_FROM_DATABASE=Sound Vision Stream + +usb:v0BB0p5007* + ID_PRODUCT_FROM_DATABASE=3340z/Rollei DC3100 + +usb:v0BB1* + ID_VENDOR_FROM_DATABASE=Infinilink Corp. + +usb:v0BB2* + ID_VENDOR_FROM_DATABASE=Ambit Microsystems Corp. + +usb:v0BB2p0302* + ID_PRODUCT_FROM_DATABASE=U10H010 802.11b Wireless Adapter [Intersil PRISM 3] + +usb:v0BB2p6098* + ID_PRODUCT_FROM_DATABASE=USB Cable Modem + +usb:v0BB3* + ID_VENDOR_FROM_DATABASE=Ofuji Technology + +usb:v0BB4* + ID_VENDOR_FROM_DATABASE=HTC (High Tech Computer Corp.) + +usb:v0BB4p00CE* + ID_PRODUCT_FROM_DATABASE=mmO2 XDA GSM/GPRS Pocket PC + +usb:v0BB4p00CF* + ID_PRODUCT_FROM_DATABASE=SPV C500 Smart Phone + +usb:v0BB4p0A01* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A02* + ID_PRODUCT_FROM_DATABASE=Himalaya GSM/GPRS Pocket PC + +usb:v0BB4p0A03* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A04* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A05* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A06* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A07* + ID_PRODUCT_FROM_DATABASE=Magician PocketPC SmartPhone / O2 XDA + +usb:v0BB4p0A08* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A09* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A0A* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A0B* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A0C* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A0D* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A0E* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A0F* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A10* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A11* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A12* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A13* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A14* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A15* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A16* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A17* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A18* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A19* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A1A* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A1B* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A1C* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A1D* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A1E* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A1F* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A20* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A21* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A22* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A23* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A24* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A25* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A26* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A27* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A28* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A29* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A2A* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A2B* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A2C* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A2D* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A2E* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A2F* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A30* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A31* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A32* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A33* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A34* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A35* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A36* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A37* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A38* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A39* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A3A* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A3B* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A3C* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A3D* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A3E* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A3F* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A40* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A41* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A42* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A43* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A44* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A45* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A46* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A47* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A48* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A49* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A4A* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A4B* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A4C* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A4D* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A4E* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A4F* + ID_PRODUCT_FROM_DATABASE=PocketPC Sync + +usb:v0BB4p0A50* + ID_PRODUCT_FROM_DATABASE=HTC SmartPhone Sync + +usb:v0BB4p0A51* + ID_PRODUCT_FROM_DATABASE=SPV C400 / T-Mobile SDA GSM/GPRS Pocket PC + +usb:v0BB4p0A52* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A53* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A54* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A55* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A56* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A57* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A58* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A59* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A5A* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A5B* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A5C* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A5D* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A5E* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A5F* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A60* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A61* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A62* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A63* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A64* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A65* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A66* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A67* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A68* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A69* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A6A* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A6B* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A6C* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A6D* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A6E* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A6F* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A70* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A71* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A72* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A73* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A74* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A75* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A76* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A77* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A78* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A79* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A7A* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A7B* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A7C* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A7D* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A7E* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A7F* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A80* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A81* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A82* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A83* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A84* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A85* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A86* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A87* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A88* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A89* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A8A* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A8B* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A8C* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A8D* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A8E* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A8F* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A90* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A91* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A92* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A93* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A94* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A95* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A96* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A97* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A98* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A99* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A9A* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A9B* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A9C* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A9D* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A9E* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0A9F* + ID_PRODUCT_FROM_DATABASE=SmartPhone Sync + +usb:v0BB4p0B03* + ID_PRODUCT_FROM_DATABASE=Ozone Mobile Broadband + +usb:v0BB4p0B04* + ID_PRODUCT_FROM_DATABASE=Hermes / TyTN / T-Mobile MDA Vario II / O2 Xda Trion + +usb:v0BB4p0B05* + ID_PRODUCT_FROM_DATABASE=P3600 + +usb:v0BB4p0B06* + ID_PRODUCT_FROM_DATABASE=Athena / Advantage x7500 / Dopod U1000 / T-Mobile AMEO + +usb:v0BB4p0B0C* + ID_PRODUCT_FROM_DATABASE=Elf / Touch / P3450 / T-Mobile MDA Touch / O2 Xda Nova / Dopod S1 + +usb:v0BB4p0B1F* + ID_PRODUCT_FROM_DATABASE=Sony Ericsson XPERIA X1 + +usb:v0BB4p0B2F* + ID_PRODUCT_FROM_DATABASE=Rhodium + +usb:v0BB4p0B51* + ID_PRODUCT_FROM_DATABASE=Qtek 8310 mobile phone [Tornado Noble] + +usb:v0BB4p0BCE* + ID_PRODUCT_FROM_DATABASE=Vario MDA + +usb:v0BB4p0C01* + ID_PRODUCT_FROM_DATABASE=Dream / ADP1 / G1 / Magic / Tattoo + +usb:v0BB4p0C02* + ID_PRODUCT_FROM_DATABASE=Dream / ADP1 / G1 / Magic / Tattoo (Debug) + +usb:v0BB4p0C13* + ID_PRODUCT_FROM_DATABASE=Diamond + +usb:v0BB4p0C1F* + ID_PRODUCT_FROM_DATABASE=Sony Ericsson XPERIA X1 + +usb:v0BB4p0C5F* + ID_PRODUCT_FROM_DATABASE=Snap + +usb:v0BB4p0C86* + ID_PRODUCT_FROM_DATABASE=Sensation + +usb:v0BB4p0C87* + ID_PRODUCT_FROM_DATABASE=Desire (debug) + +usb:v0BB4p0C8D* + ID_PRODUCT_FROM_DATABASE=EVO 4G (debug) + +usb:v0BB4p0C91* + ID_PRODUCT_FROM_DATABASE=Vision + +usb:v0BB4p0C94* + ID_PRODUCT_FROM_DATABASE=Vision + +usb:v0BB4p0C97* + ID_PRODUCT_FROM_DATABASE=Legend + +usb:v0BB4p0C99* + ID_PRODUCT_FROM_DATABASE=Desire (debug) + +usb:v0BB4p0C9E* + ID_PRODUCT_FROM_DATABASE=Incredible + +usb:v0BB4p0CA2* + ID_PRODUCT_FROM_DATABASE=Desire HD (debug mode) + +usb:v0BB4p0CA5* + ID_PRODUCT_FROM_DATABASE=Android Phone [Evo Shift 4G] + +usb:v0BB4p0FF8* + ID_PRODUCT_FROM_DATABASE=Desire HD (Tethering Mode) + +usb:v0BB4p0FF9* + ID_PRODUCT_FROM_DATABASE=Desire / Desire HD / Hero (Charge Mode) + +usb:v0BB4p0FFE* + ID_PRODUCT_FROM_DATABASE=Desire HD (modem mode) + +usb:v0BB4p0FFF* + ID_PRODUCT_FROM_DATABASE=Android Fastboot Bootloader + +usb:v0BB5* + ID_VENDOR_FROM_DATABASE=Murata Manufacturing Co., Ltd + +usb:v0BB6* + ID_VENDOR_FROM_DATABASE=Network Alchemy + +usb:v0BB7* + ID_VENDOR_FROM_DATABASE=Joytech Computer Co., Ltd + +usb:v0BB8* + ID_VENDOR_FROM_DATABASE=Hitachi Semiconductor and Devices Sales Co., Ltd + +usb:v0BB9* + ID_VENDOR_FROM_DATABASE=Eiger M&C Co., Ltd + +usb:v0BBA* + ID_VENDOR_FROM_DATABASE=ZAccess Systems + +usb:v0BBB* + ID_VENDOR_FROM_DATABASE=General Meters Corp. + +usb:v0BBC* + ID_VENDOR_FROM_DATABASE=Assistive Technology, Inc. + +usb:v0BBD* + ID_VENDOR_FROM_DATABASE=System Connection, Inc. + +usb:v0BC0* + ID_VENDOR_FROM_DATABASE=Knilink Technology, Inc. + +usb:v0BC1* + ID_VENDOR_FROM_DATABASE=Fuw Yng Electronics Co., Ltd + +usb:v0BC2* + ID_VENDOR_FROM_DATABASE=Seagate RSS LLC + +usb:v0BC2p0502* + ID_PRODUCT_FROM_DATABASE=ST3300601CB-RK 300 GB External Hard Drive + +usb:v0BC2p0503* + ID_PRODUCT_FROM_DATABASE=ST3250824A [Barracuda 7200.9] + +usb:v0BC2p2000* + ID_PRODUCT_FROM_DATABASE=Storage Adapter V3 (TPP) + +usb:v0BC2p2200* + ID_PRODUCT_FROM_DATABASE=FreeAgent Go FW + +usb:v0BC2p2300* + ID_PRODUCT_FROM_DATABASE=Expansion Portable + +usb:v0BC2p2320* + ID_PRODUCT_FROM_DATABASE=USB 3.0 bridge [Portable Expansion Drive] + +usb:v0BC2p3332* + ID_PRODUCT_FROM_DATABASE=Expansion + +usb:v0BC2p5021* + ID_PRODUCT_FROM_DATABASE=FreeAgent GoFlex USB 2.0 + +usb:v0BC2p5031* + ID_PRODUCT_FROM_DATABASE=FreeAgent GoFlex USB 3.0 + +usb:v0BC2p50A5* + ID_PRODUCT_FROM_DATABASE=FreeAgent GoFlex Desk USB 3.0 + +usb:v0BC2p5121* + ID_PRODUCT_FROM_DATABASE=FreeAgent GoFlex + +usb:v0BC2p5161* + ID_PRODUCT_FROM_DATABASE=FreeAgent GoFlex dock + +usb:v0BC3* + ID_VENDOR_FROM_DATABASE=IPWireless, Inc. + +usb:v0BC3p0001* + ID_PRODUCT_FROM_DATABASE=UMTS-TDD (TD-CDMA) modem + +usb:v0BC4* + ID_VENDOR_FROM_DATABASE=Microcube Corp. + +usb:v0BC5* + ID_VENDOR_FROM_DATABASE=JCN Co., Ltd + +usb:v0BC6* + ID_VENDOR_FROM_DATABASE=ExWAY, Inc. + +usb:v0BC7* + ID_VENDOR_FROM_DATABASE=X10 Wireless Technology, Inc. + +usb:v0BC7p0001* + ID_PRODUCT_FROM_DATABASE=ActiveHome (ACPI-compliant) + +usb:v0BC7p0002* + ID_PRODUCT_FROM_DATABASE=Firecracker Interface (ACPI-compliant) + +usb:v0BC7p0003* + ID_PRODUCT_FROM_DATABASE=VGA Video Sender (ACPI-compliant) + +usb:v0BC7p0004* + ID_PRODUCT_FROM_DATABASE=X10 Receiver + +usb:v0BC7p0005* + ID_PRODUCT_FROM_DATABASE=Wireless Transceiver (ACPI-compliant) + +usb:v0BC7p0006* + ID_PRODUCT_FROM_DATABASE=Wireless Transceiver (ACPI-compliant) + +usb:v0BC7p0007* + ID_PRODUCT_FROM_DATABASE=Wireless Transceiver (ACPI-compliant) + +usb:v0BC7p0008* + ID_PRODUCT_FROM_DATABASE=Wireless Transceiver (ACPI-compliant) + +usb:v0BC7p0009* + ID_PRODUCT_FROM_DATABASE=Wireless Transceiver (ACPI-compliant) + +usb:v0BC7p000A* + ID_PRODUCT_FROM_DATABASE=Wireless Transceiver (ACPI-compliant) + +usb:v0BC7p000B* + ID_PRODUCT_FROM_DATABASE=Transceiver (ACPI-compliant) + +usb:v0BC7p000C* + ID_PRODUCT_FROM_DATABASE=Transceiver (ACPI-compliant) + +usb:v0BC7p000D* + ID_PRODUCT_FROM_DATABASE=Transceiver (ACPI-compliant) + +usb:v0BC7p000E* + ID_PRODUCT_FROM_DATABASE=Transceiver (ACPI-compliant) + +usb:v0BC7p000F* + ID_PRODUCT_FROM_DATABASE=Transceiver (ACPI-compliant) + +usb:v0BC8* + ID_VENDOR_FROM_DATABASE=Telmax Communications + +usb:v0BC9* + ID_VENDOR_FROM_DATABASE=ECI Telecom, Ltd + +usb:v0BCA* + ID_VENDOR_FROM_DATABASE=Startek Engineering, Inc. + +usb:v0BCB* + ID_VENDOR_FROM_DATABASE=Perfect Technic Enterprise Co., Ltd + +usb:v0BD7* + ID_VENDOR_FROM_DATABASE=Andrew Pargeter & Associates + +usb:v0BD7pA021* + ID_PRODUCT_FROM_DATABASE=Amptek DP4 multichannel signal analyzer + +usb:v0BDA* + ID_VENDOR_FROM_DATABASE=Realtek Semiconductor Corp. + +usb:v0BDAp0103* + ID_PRODUCT_FROM_DATABASE=USB 2.0 Card Reader + +usb:v0BDAp0104* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v0BDAp0106* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v0BDAp0107* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v0BDAp0108* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v0BDAp0111* + ID_PRODUCT_FROM_DATABASE=RTS5111 Card Reader Controller + +usb:v0BDAp0113* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v0BDAp0115* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device (Multicard Reader) + +usb:v0BDAp0116* + ID_PRODUCT_FROM_DATABASE=RTS5116 Card Reader Controller + +usb:v0BDAp0117* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v0BDAp0118* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v0BDAp0119* + ID_PRODUCT_FROM_DATABASE=Storage Device (SD card reader) + +usb:v0BDAp0129* + ID_PRODUCT_FROM_DATABASE=RTS5129 Card Reader Controller + +usb:v0BDAp0138* + ID_PRODUCT_FROM_DATABASE=RTS5138 Card Reader Controller + +usb:v0BDAp0139* + ID_PRODUCT_FROM_DATABASE=RTS5139 Card Reader Controller + +usb:v0BDAp0151* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device (Multicard Reader) + +usb:v0BDAp0152* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v0BDAp0153* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v0BDAp0156* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v0BDAp0157* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v0BDAp0158* + ID_PRODUCT_FROM_DATABASE=USB 2.0 multicard reader + +usb:v0BDAp0159* + ID_PRODUCT_FROM_DATABASE=RTS5159 Card Reader Controller + +usb:v0BDAp0161* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v0BDAp0168* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v0BDAp0169* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v0BDAp0171* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v0BDAp0176* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v0BDAp0178* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v0BDAp0186* + ID_PRODUCT_FROM_DATABASE=Card Reader + +usb:v0BDAp2831* + ID_PRODUCT_FROM_DATABASE=RTL2831U DVB-T + +usb:v0BDAp2832* + ID_PRODUCT_FROM_DATABASE=RTL2832U DVB-T + +usb:v0BDAp2838* + ID_PRODUCT_FROM_DATABASE=RTL2838 DVB-T + +usb:v0BDAp8150* + ID_PRODUCT_FROM_DATABASE=RTL8150 Fast Ethernet Adapter + +usb:v0BDAp8151* + ID_PRODUCT_FROM_DATABASE=RTL8151 Adapteon Business Mobile Networks BV + +usb:v0BDAp8171* + ID_PRODUCT_FROM_DATABASE=RTL8188SU 802.11n WLAN Adapter + +usb:v0BDAp8172* + ID_PRODUCT_FROM_DATABASE=RTL8191SU 802.11n WLAN Adapter + +usb:v0BDAp8174* + ID_PRODUCT_FROM_DATABASE=RTL8192SU 802.11n WLAN Adapter + +usb:v0BDAp8176* + ID_PRODUCT_FROM_DATABASE=RTL8188CUS 802.11n WLAN Adapter + +usb:v0BDAp8178* + ID_PRODUCT_FROM_DATABASE=RTL8192CU 802.11n WLAN Adapter + +usb:v0BDAp817F* + ID_PRODUCT_FROM_DATABASE=RTL8188RU 802.11n WLAN Adapter + +usb:v0BDAp8187* + ID_PRODUCT_FROM_DATABASE=RTL8187 Wireless Adapter + +usb:v0BDAp8189* + ID_PRODUCT_FROM_DATABASE=RTL8187B Wireless 802.11g 54Mbps Network Adapter + +usb:v0BDAp8192* + ID_PRODUCT_FROM_DATABASE=RTL8191SU 802.11n Wireless Adapter + +usb:v0BDAp8193* + ID_PRODUCT_FROM_DATABASE=RTL8192DU 802.11an WLAN Adapter + +usb:v0BDAp8197* + ID_PRODUCT_FROM_DATABASE=RTL8187B Wireless Adapter + +usb:v0BDAp8198* + ID_PRODUCT_FROM_DATABASE=RTL8187B Wireless Adapter + +usb:v0BDB* + ID_VENDOR_FROM_DATABASE=Ericsson Business Mobile Networks BV + +usb:v0BDBp1000* + ID_PRODUCT_FROM_DATABASE=BV Bluetooth Device + +usb:v0BDBp1002* + ID_PRODUCT_FROM_DATABASE=Bluetooth Device 1.2 + +usb:v0BDBp1049* + ID_PRODUCT_FROM_DATABASE=C3607w Mobile Broadband Module + +usb:v0BDBp1900* + ID_PRODUCT_FROM_DATABASE=F3507g Mobile Broadband Module + +usb:v0BDBp1902* + ID_PRODUCT_FROM_DATABASE=F3507g v2 Mobile Broadband Module + +usb:v0BDBp1904* + ID_PRODUCT_FROM_DATABASE=F3607gw Mobile Broadband Module + +usb:v0BDBp1905* + ID_PRODUCT_FROM_DATABASE=F3607gw v2 Mobile Broadband Module + +usb:v0BDBp1906* + ID_PRODUCT_FROM_DATABASE=F3607gw v3 Mobile Broadband Module + +usb:v0BDBp1909* + ID_PRODUCT_FROM_DATABASE=F3307 v2 Mobile Broadband Module + +usb:v0BDBp190A* + ID_PRODUCT_FROM_DATABASE=F3307 Mobile Broadband Module + +usb:v0BDBp190B* + ID_PRODUCT_FROM_DATABASE=C3607w v2 Mobile Broadband Module + +usb:v0BDC* + ID_VENDOR_FROM_DATABASE=Y Media Corp. + +usb:v0BDD* + ID_VENDOR_FROM_DATABASE=Orange PCS + +usb:v0BE2* + ID_VENDOR_FROM_DATABASE=Kanda Tsushin Kogyo Co., Ltd + +usb:v0BE3* + ID_VENDOR_FROM_DATABASE=TOYO Corp. + +usb:v0BE4* + ID_VENDOR_FROM_DATABASE=Elka International, Ltd + +usb:v0BE5* + ID_VENDOR_FROM_DATABASE=DOME imaging systems, Inc. + +usb:v0BE6* + ID_VENDOR_FROM_DATABASE=Dong Guan Humen Wonderful Wire Cable Factory + +usb:v0BED* + ID_VENDOR_FROM_DATABASE=Silicon Labs + +usb:v0BEDp1100* + ID_PRODUCT_FROM_DATABASE=MEI CASHFLOW SC + +usb:v0BEDp1101* + ID_PRODUCT_FROM_DATABASE=Series 2000 Combo Acceptor + +usb:v0BEE* + ID_VENDOR_FROM_DATABASE=LTK Industries, Ltd + +usb:v0BEF* + ID_VENDOR_FROM_DATABASE=Way2Call Communications + +usb:v0BF0* + ID_VENDOR_FROM_DATABASE=Pace Micro Technology PLC + +usb:v0BF1* + ID_VENDOR_FROM_DATABASE=Intracom S.A. + +usb:v0BF1p0001* + ID_PRODUCT_FROM_DATABASE=netMod Driver Ver 2.4.17 (CAPI) + +usb:v0BF1p0002* + ID_PRODUCT_FROM_DATABASE=netMod Driver Ver 2.4 (CAPI) + +usb:v0BF1p0003* + ID_PRODUCT_FROM_DATABASE=netMod Driver Ver 2.4 (CAPI) + +usb:v0BF2* + ID_VENDOR_FROM_DATABASE=Konexx + +usb:v0BF6* + ID_VENDOR_FROM_DATABASE=Addonics Technologies, Inc. + +usb:v0BF6p0103* + ID_PRODUCT_FROM_DATABASE=Storage Device + +usb:v0BF6p1234* + ID_PRODUCT_FROM_DATABASE=Storage Device + +usb:v0BF6pA000* + ID_PRODUCT_FROM_DATABASE=Cable 205 (TPP) + +usb:v0BF6pA001* + ID_PRODUCT_FROM_DATABASE=Cable 205 + +usb:v0BF6pA002* + ID_PRODUCT_FROM_DATABASE=IDE Bridge + +usb:v0BF7* + ID_VENDOR_FROM_DATABASE=Sunny Giken, Inc. + +usb:v0BF8* + ID_VENDOR_FROM_DATABASE=Fujitsu Siemens Computers + +usb:v0BF8p1001* + ID_PRODUCT_FROM_DATABASE=Fujitsu Pocket Loox 600 PDA + +usb:v0BF8p1006* + ID_PRODUCT_FROM_DATABASE=SmartCard Reader 2A + +usb:v0BF8p1007* + ID_PRODUCT_FROM_DATABASE=Connect2Air E-5400 802.11g Wireless Adapter + +usb:v0BF8p1009* + ID_PRODUCT_FROM_DATABASE=Connect2Air E-5400 D1700 802.11g Wireless Adapter [Intersil ISL3887] + +usb:v0BF8p100C* + ID_PRODUCT_FROM_DATABASE=Keyboard FSC KBPC PX + +usb:v0BF8p100F* + ID_PRODUCT_FROM_DATABASE=miniCard D2301 802.11bg Wireless Module [SiS 163U] + +usb:v0BFD* + ID_VENDOR_FROM_DATABASE=Kvaser AB + +usb:v0BFDp0004* + ID_PRODUCT_FROM_DATABASE=USBcan II + +usb:v0BFDp000B* + ID_PRODUCT_FROM_DATABASE=Leaf Light HS + +usb:v0BFDp000E* + ID_PRODUCT_FROM_DATABASE=Leaf SemiPro HS + +usb:v0C04* + ID_VENDOR_FROM_DATABASE=MOTO Development Group, Inc. + +usb:v0C05* + ID_VENDOR_FROM_DATABASE=Appian Graphics + +usb:v0C06* + ID_VENDOR_FROM_DATABASE=Hasbro Games, Inc. + +usb:v0C07* + ID_VENDOR_FROM_DATABASE=Infinite Data Storage, Ltd + +usb:v0C08* + ID_VENDOR_FROM_DATABASE=Agate + +usb:v0C08p0378* + ID_PRODUCT_FROM_DATABASE=Q 16MB Storage Device + +usb:v0C09* + ID_VENDOR_FROM_DATABASE=Comjet Information System + +usb:v0C09pA5A5* + ID_PRODUCT_FROM_DATABASE=Litto Version USB2.0 + +usb:v0C0A* + ID_VENDOR_FROM_DATABASE=Highpoint Technologies, Inc. + +usb:v0C0B* + ID_VENDOR_FROM_DATABASE=Dura Micro, Inc. (Acomdata) + +usb:v0C0Bp27CB* + ID_PRODUCT_FROM_DATABASE=6-in-1 Flash Reader and Writer + +usb:v0C0Bp27D7* + ID_PRODUCT_FROM_DATABASE=Multi Memory reader/writer MD-005 + +usb:v0C0Bp27DA* + ID_PRODUCT_FROM_DATABASE=Multi Memory reader/writer MD-005 + +usb:v0C0Bp27DC* + ID_PRODUCT_FROM_DATABASE=Multi Memory reader/writer MD-005 + +usb:v0C0Bp27E7* + ID_PRODUCT_FROM_DATABASE=3,5'' HDD case MD-231 + +usb:v0C0Bp27EE* + ID_PRODUCT_FROM_DATABASE=3,5'' HDD case MD-231 + +usb:v0C0Bp2814* + ID_PRODUCT_FROM_DATABASE=3,5'' HDD case MD-231 + +usb:v0C0Bp2815* + ID_PRODUCT_FROM_DATABASE=3,5'' HDD case MD-231 + +usb:v0C0Bp281D* + ID_PRODUCT_FROM_DATABASE=3,5'' HDD case MD-231 + +usb:v0C0Bp5FAB* + ID_PRODUCT_FROM_DATABASE=Storage Adaptor + +usb:v0C0BpA109* + ID_PRODUCT_FROM_DATABASE=CF/SM Reader and Writer + +usb:v0C0BpA10C* + ID_PRODUCT_FROM_DATABASE=SD/MS Reader and Writer + +usb:v0C0BpB001* + ID_PRODUCT_FROM_DATABASE=USB 2.0 Mass Storage IDE adapter + +usb:v0C0BpB004* + ID_PRODUCT_FROM_DATABASE=MMC/SD Reader and Writer + +usb:v0C12* + ID_VENDOR_FROM_DATABASE=Zeroplus + +usb:v0C12p0005* + ID_PRODUCT_FROM_DATABASE=PSX Vibration Feedback Converter + +usb:v0C12p0030* + ID_PRODUCT_FROM_DATABASE=PSX Vibration Feedback Converter + +usb:v0C12p700E* + ID_PRODUCT_FROM_DATABASE=Logic Analyzer (LAP-C-16032) + +usb:v0C12p8801* + ID_PRODUCT_FROM_DATABASE=Xbox Controller + +usb:v0C12p8802* + ID_PRODUCT_FROM_DATABASE=Xbox Controller + +usb:v0C12p8809* + ID_PRODUCT_FROM_DATABASE=Red Octane Ignition Xbox DDR Pad + +usb:v0C12p880A* + ID_PRODUCT_FROM_DATABASE=Pelican Eclipse PL-2023 + +usb:v0C12p8810* + ID_PRODUCT_FROM_DATABASE=Xbox Controller + +usb:v0C12p9902* + ID_PRODUCT_FROM_DATABASE=VibraX + +usb:v0C15* + ID_VENDOR_FROM_DATABASE=Iris Graphics + +usb:v0C16* + ID_VENDOR_FROM_DATABASE=Gyration, Inc. + +usb:v0C16p0002* + ID_PRODUCT_FROM_DATABASE=RF Technology Receiver + +usb:v0C16p0003* + ID_PRODUCT_FROM_DATABASE=RF Technology Receiver + +usb:v0C16p0008* + ID_PRODUCT_FROM_DATABASE=RF Technology Receiver + +usb:v0C16p0080* + ID_PRODUCT_FROM_DATABASE=eHome Infrared Receiver + +usb:v0C16p0081* + ID_PRODUCT_FROM_DATABASE=eHome Infrared Receiver + +usb:v0C17* + ID_VENDOR_FROM_DATABASE=Cyberboard A/S + +usb:v0C18* + ID_VENDOR_FROM_DATABASE=SynerTek Korea, Inc. + +usb:v0C19* + ID_VENDOR_FROM_DATABASE=cyberPIXIE, Inc. + +usb:v0C1A* + ID_VENDOR_FROM_DATABASE=Silicon Motion, Inc. + +usb:v0C1B* + ID_VENDOR_FROM_DATABASE=MIPS Technologies + +usb:v0C1C* + ID_VENDOR_FROM_DATABASE=Hang Zhou Silan Electronics Co., Ltd + +usb:v0C22* + ID_VENDOR_FROM_DATABASE=Tally Printer Corp. + +usb:v0C23* + ID_VENDOR_FROM_DATABASE=Lernout + Hauspie + +usb:v0C24* + ID_VENDOR_FROM_DATABASE=Taiyo Yuden + +usb:v0C24p0001* + ID_PRODUCT_FROM_DATABASE=Bluetooth Adaptor + +usb:v0C24p0002* + ID_PRODUCT_FROM_DATABASE=Bluetooth Device2 + +usb:v0C24p0005* + ID_PRODUCT_FROM_DATABASE=Bluetooth Device(BC04-External) + +usb:v0C24p000B* + ID_PRODUCT_FROM_DATABASE=Bluetooth Device(BC04-External) + +usb:v0C24p000C* + ID_PRODUCT_FROM_DATABASE=Bluetooth Adaptor + +usb:v0C24p000E* + ID_PRODUCT_FROM_DATABASE=Bluetooth Device(BC04-External) + +usb:v0C24p000F* + ID_PRODUCT_FROM_DATABASE=Bluetooth Device (V2.0+EDR) + +usb:v0C24p0010* + ID_PRODUCT_FROM_DATABASE=Bluetooth Device(BC04-External) + +usb:v0C24p0012* + ID_PRODUCT_FROM_DATABASE=Bluetooth Device(BC04-External) + +usb:v0C24p0018* + ID_PRODUCT_FROM_DATABASE=Bluetooth Device(BC04-External) + +usb:v0C24p0019* + ID_PRODUCT_FROM_DATABASE=Bluetooth Device + +usb:v0C24p0021* + ID_PRODUCT_FROM_DATABASE=Bluetooth Device + +usb:v0C24p0C24* + ID_PRODUCT_FROM_DATABASE=Bluetooth Device(SAMPLE) + +usb:v0C24pFFFF* + ID_PRODUCT_FROM_DATABASE=Bluetooth module with BlueCore in DFU mode + +usb:v0C25* + ID_VENDOR_FROM_DATABASE=Sampo Corp. + +usb:v0C25p0310* + ID_PRODUCT_FROM_DATABASE=Scream Cam + +usb:v0C26* + ID_VENDOR_FROM_DATABASE=Prolific Technology Inc. + +usb:v0C26p0018* + ID_PRODUCT_FROM_DATABASE=USB-Serial Controller [Icom Inc. OPC-478UC] + +usb:v0C27* + ID_VENDOR_FROM_DATABASE=RFIDeas, Inc + +usb:v0C27p3BFA* + ID_PRODUCT_FROM_DATABASE=pcProx Card Reader + +usb:v0C2E* + ID_VENDOR_FROM_DATABASE=Metrologic Instruments + +usb:v0C2Ep0007* + ID_PRODUCT_FROM_DATABASE=Metrologic MS7120 Barcode Scanner (IBM SurePOS mode) + +usb:v0C2Ep0200* + ID_PRODUCT_FROM_DATABASE=Metrologic Scanner + +usb:v0C2Ep0204* + ID_PRODUCT_FROM_DATABASE=Metrologic MS7120 Barcode Scanner (keyboard mode) + +usb:v0C2Ep0700* + ID_PRODUCT_FROM_DATABASE=Metrologic MS7120 Barcode Scanner (uni-directional serial mode) + +usb:v0C2Ep0720* + ID_PRODUCT_FROM_DATABASE=Metrologic MS7120 Barcode Scanner (bi-directional serial mode) + +usb:v0C2Ep0B61* + ID_PRODUCT_FROM_DATABASE=Vuquest 3310g + +usb:v0C2Ep0B6A* + ID_PRODUCT_FROM_DATABASE=Vuquest 3310 Area-Imaging Scanner + +usb:v0C35* + ID_VENDOR_FROM_DATABASE=Eagletron, Inc. + +usb:v0C36* + ID_VENDOR_FROM_DATABASE=E Ink Corp. + +usb:v0C37* + ID_VENDOR_FROM_DATABASE=e.Digital + +usb:v0C38* + ID_VENDOR_FROM_DATABASE=Der An Electric Wire & Cable Co., Ltd + +usb:v0C39* + ID_VENDOR_FROM_DATABASE=IFR + +usb:v0C3A* + ID_VENDOR_FROM_DATABASE=Furui Precise Component (Kunshan) Co., Ltd + +usb:v0C3B* + ID_VENDOR_FROM_DATABASE=Komatsu, Ltd + +usb:v0C3C* + ID_VENDOR_FROM_DATABASE=Radius Co., Ltd + +usb:v0C3D* + ID_VENDOR_FROM_DATABASE=Innocom, Inc. + +usb:v0C3E* + ID_VENDOR_FROM_DATABASE=Nextcell, Inc. + +usb:v0C44* + ID_VENDOR_FROM_DATABASE=Motorola iDEN + +usb:v0C44p0021* + ID_PRODUCT_FROM_DATABASE=iDEN P2k0 Device + +usb:v0C44p0022* + ID_PRODUCT_FROM_DATABASE=iDEN P2k1 Device + +usb:v0C44p03A2* + ID_PRODUCT_FROM_DATABASE=iDEN Smartphone + +usb:v0C44p41D9* + ID_PRODUCT_FROM_DATABASE=i1 phone + +usb:v0C45* + ID_VENDOR_FROM_DATABASE=Microdia + +usb:v0C45p0011* + ID_PRODUCT_FROM_DATABASE=EBUDDY + +usb:v0C45p1020* + ID_PRODUCT_FROM_DATABASE=Mass Storage Reader + +usb:v0C45p1028* + ID_PRODUCT_FROM_DATABASE=Mass Storage Reader + +usb:v0C45p1030* + ID_PRODUCT_FROM_DATABASE=Mass Storage Reader + +usb:v0C45p1031* + ID_PRODUCT_FROM_DATABASE=Sonix Mass Storage Device + +usb:v0C45p1032* + ID_PRODUCT_FROM_DATABASE=Mass Storage Reader + +usb:v0C45p1033* + ID_PRODUCT_FROM_DATABASE=Sonix Mass Storage Device + +usb:v0C45p1034* + ID_PRODUCT_FROM_DATABASE=Mass Storage Reader + +usb:v0C45p1035* + ID_PRODUCT_FROM_DATABASE=Mass Storage Reader + +usb:v0C45p1036* + ID_PRODUCT_FROM_DATABASE=Mass Storage Reader + +usb:v0C45p1037* + ID_PRODUCT_FROM_DATABASE=Sonix Mass Storage Device + +usb:v0C45p1050* + ID_PRODUCT_FROM_DATABASE=CF Card Reader + +usb:v0C45p1058* + ID_PRODUCT_FROM_DATABASE=HDD Reader + +usb:v0C45p1060* + ID_PRODUCT_FROM_DATABASE=iFlash SM-Direct Card Reader + +usb:v0C45p1061* + ID_PRODUCT_FROM_DATABASE=Mass Storage Reader + +usb:v0C45p1062* + ID_PRODUCT_FROM_DATABASE=Mass Storage Reader + +usb:v0C45p1063* + ID_PRODUCT_FROM_DATABASE=Sonix Mass Storage Device + +usb:v0C45p1064* + ID_PRODUCT_FROM_DATABASE=Mass Storage Reader + +usb:v0C45p1065* + ID_PRODUCT_FROM_DATABASE=Mass Storage Reader + +usb:v0C45p1066* + ID_PRODUCT_FROM_DATABASE=Mass Storage Reader + +usb:v0C45p1067* + ID_PRODUCT_FROM_DATABASE=Mass Storage Reader + +usb:v0C45p1158* + ID_PRODUCT_FROM_DATABASE=A56AK + +usb:v0C45p184C* + ID_PRODUCT_FROM_DATABASE=VoIP Phone + +usb:v0C45p6001* + ID_PRODUCT_FROM_DATABASE=Genius VideoCAM NB + +usb:v0C45p6005* + ID_PRODUCT_FROM_DATABASE=Sweex Mini Webcam + +usb:v0C45p6007* + ID_PRODUCT_FROM_DATABASE=VideoCAM Eye + +usb:v0C45p6009* + ID_PRODUCT_FROM_DATABASE=VideoCAM ExpressII + +usb:v0C45p600D* + ID_PRODUCT_FROM_DATABASE=TwinkleCam USB camera + +usb:v0C45p6011* + ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C102) + +usb:v0C45p6019* + ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C102) + +usb:v0C45p6024* + ID_PRODUCT_FROM_DATABASE=VideoCAM ExpressII + +usb:v0C45p6025* + ID_PRODUCT_FROM_DATABASE=VideoCAM ExpressII + +usb:v0C45p6028* + ID_PRODUCT_FROM_DATABASE=Typhoon Easycam USB 330K (older) + +usb:v0C45p6029* + ID_PRODUCT_FROM_DATABASE=Triplex i-mini PC Camera + +usb:v0C45p602A* + ID_PRODUCT_FROM_DATABASE=Meade ETX-105EC Camera + +usb:v0C45p602B* + ID_PRODUCT_FROM_DATABASE=VideoCAM NB 300 + +usb:v0C45p602C* + ID_PRODUCT_FROM_DATABASE=Clas Ohlson TWC-30XOP Webcam + +usb:v0C45p602D* + ID_PRODUCT_FROM_DATABASE=VideoCAM ExpressII + +usb:v0C45p602E* + ID_PRODUCT_FROM_DATABASE=VideoCAM Messenger + +usb:v0C45p6030* + ID_PRODUCT_FROM_DATABASE=VideoCAM ExpressII + +usb:v0C45p603F* + ID_PRODUCT_FROM_DATABASE=VideoCAM ExpressII + +usb:v0C45p6040* + ID_PRODUCT_FROM_DATABASE=CCD PC Camera (PC390A) + +usb:v0C45p606A* + ID_PRODUCT_FROM_DATABASE=CCD PC Camera (PC390A) + +usb:v0C45p607A* + ID_PRODUCT_FROM_DATABASE=CCD PC Camera (PC390A) + +usb:v0C45p607B* + ID_PRODUCT_FROM_DATABASE=Win2 PC Camera + +usb:v0C45p607C* + ID_PRODUCT_FROM_DATABASE=CCD PC Camera (PC390A) + +usb:v0C45p607E* + ID_PRODUCT_FROM_DATABASE=CCD PC Camera (PC390A) + +usb:v0C45p6080* + ID_PRODUCT_FROM_DATABASE=Audio (Microphone) + +usb:v0C45p6082* + ID_PRODUCT_FROM_DATABASE=VideoCAM Look + +usb:v0C45p6083* + ID_PRODUCT_FROM_DATABASE=VideoCAM Look + +usb:v0C45p608C* + ID_PRODUCT_FROM_DATABASE=VideoCAM Look + +usb:v0C45p608E* + ID_PRODUCT_FROM_DATABASE=VideoCAM Look + +usb:v0C45p608F* + ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C103 + OV7630) + +usb:v0C45p60A8* + ID_PRODUCT_FROM_DATABASE=VideoCAM Look + +usb:v0C45p60AA* + ID_PRODUCT_FROM_DATABASE=VideoCAM Look + +usb:v0C45p60AB* + ID_PRODUCT_FROM_DATABASE=PC Camera + +usb:v0C45p60AF* + ID_PRODUCT_FROM_DATABASE=VideoCAM Look + +usb:v0C45p60B0* + ID_PRODUCT_FROM_DATABASE=Genius VideoCam Look + +usb:v0C45p60C0* + ID_PRODUCT_FROM_DATABASE=PC Camera with Mic (SN9C105) + +usb:v0C45p60C8* + ID_PRODUCT_FROM_DATABASE=Win2 PC Camera + +usb:v0C45p60CC* + ID_PRODUCT_FROM_DATABASE=PC Camera with Mic (SN9C105) + +usb:v0C45p60EC* + ID_PRODUCT_FROM_DATABASE=PC Camera with Mic (SN9C105) + +usb:v0C45p60EF* + ID_PRODUCT_FROM_DATABASE=Win2 PC Camera + +usb:v0C45p60FA* + ID_PRODUCT_FROM_DATABASE=PC Camera with Mic (SN9C105) + +usb:v0C45p60FB* + ID_PRODUCT_FROM_DATABASE=Composite Device + +usb:v0C45p60FC* + ID_PRODUCT_FROM_DATABASE=PC Camera with Mic (SN9C105) + +usb:v0C45p60FE* + ID_PRODUCT_FROM_DATABASE=Audio (Microphone) + +usb:v0C45p6108* + ID_PRODUCT_FROM_DATABASE=Win2 PC Camera + +usb:v0C45p6122* + ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C110) + +usb:v0C45p6123* + ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C110) + +usb:v0C45p6128* + ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C325 + OM6802) + +usb:v0C45p612A* + ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C325) + +usb:v0C45p612C* + ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C110) + +usb:v0C45p612E* + ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C110) + +usb:v0C45p612F* + ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C110) + +usb:v0C45p6130* + ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C120) + +usb:v0C45p6138* + ID_PRODUCT_FROM_DATABASE=Win2 PC Camera + +usb:v0C45p613A* + ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C120) + +usb:v0C45p613B* + ID_PRODUCT_FROM_DATABASE=Win2 PC Camera + +usb:v0C45p613C* + ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C120) + +usb:v0C45p613E* + ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C120) + +usb:v0C45p6143* + ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C120 + SP80708) + +usb:v0C45p6240* + ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C201 + MI1300) + +usb:v0C45p6242* + ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C201 + MI1310) + +usb:v0C45p6243* + ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C201 + S5K4AAFX) + +usb:v0C45p6248* + ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C201 + OV9655) + +usb:v0C45p624B* + ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C201 + CX1332) + +usb:v0C45p624C* + ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C201 + MI1320) + +usb:v0C45p624E* + ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C201 + SOI968) + +usb:v0C45p624F* + ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C201 + OV9650) + +usb:v0C45p6251* + ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C201 + OV9650) + +usb:v0C45p6253* + ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C201 + OV9650) + +usb:v0C45p6260* + ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C201 + OV7670ISP) + +usb:v0C45p6262* + ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C201 + OM6802) + +usb:v0C45p6270* + ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C201 + MI0360/MT9V011 or MI0360SOC/MT9V111) U-CAM PC Camera NE878, Whitcom WHC017, ... + +usb:v0C45p627A* + ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C201 + S5K53BEB) + +usb:v0C45p627B* + ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C201 + OV7660) + +usb:v0C45p627C* + ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C201 + HV7131R) + +usb:v0C45p627F* + ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C201 + OV965x + EEPROM) + +usb:v0C45p6280* + ID_PRODUCT_FROM_DATABASE=PC Camera with Microphone (SN9C202 + MI1300) + +usb:v0C45p6282* + ID_PRODUCT_FROM_DATABASE=PC Camera with Microphone (SN9C202 + MI1310) + +usb:v0C45p6283* + ID_PRODUCT_FROM_DATABASE=PC Camera with Microphone (SN9C202 + S5K4AAFX) + +usb:v0C45p6288* + ID_PRODUCT_FROM_DATABASE=PC Camera with Microphone (SN9C202 + OV9655) + +usb:v0C45p628A* + ID_PRODUCT_FROM_DATABASE=PC Camera with Microphone (SN9C202 + ICM107) + +usb:v0C45p628B* + ID_PRODUCT_FROM_DATABASE=PC Camera with Microphone (SN9C202 + CX1332) + +usb:v0C45p628C* + ID_PRODUCT_FROM_DATABASE=PC Camera with Microphone (SN9C202 + MI1320) + +usb:v0C45p628E* + ID_PRODUCT_FROM_DATABASE=PC Camera with Microphone (SN9C202 + SOI968) + +usb:v0C45p628F* + ID_PRODUCT_FROM_DATABASE=PC Camera with Microphone (SN9C202 + OV9650) + +usb:v0C45p62A0* + ID_PRODUCT_FROM_DATABASE=PC Camera with Microphone (SN9C202 + OV7670ISP) + +usb:v0C45p62A2* + ID_PRODUCT_FROM_DATABASE=PC Camera with Microphone (SN9C202 + OM6802) + +usb:v0C45p62B0* + ID_PRODUCT_FROM_DATABASE=PC Camera with Microphone (SN9C202 + MI0360/MT9V011 or MI0360SOC/MT9V111) + +usb:v0C45p62B3* + ID_PRODUCT_FROM_DATABASE=PC Camera with Microphone (SN9C202 + OV9655) + +usb:v0C45p62BA* + ID_PRODUCT_FROM_DATABASE=PC Camera with Microphone (SN9C202 + S5K53BEB) + +usb:v0C45p62BB* + ID_PRODUCT_FROM_DATABASE=PC Camera with Microphone (SN9C202 + OV7660) + +usb:v0C45p62BC* + ID_PRODUCT_FROM_DATABASE=PC Camera with Microphone (SN9C202 + HV7131R) + +usb:v0C45p62BE* + ID_PRODUCT_FROM_DATABASE=PC Camera with Microphone (SN9C202 + OV7663) + +usb:v0C45p62C0* + ID_PRODUCT_FROM_DATABASE=Sonix USB 2.0 Camera + +usb:v0C45p62E0* + ID_PRODUCT_FROM_DATABASE=MSI Starcam Racer + +usb:v0C45p6310* + ID_PRODUCT_FROM_DATABASE=Sonix USB 2.0 Camera + +usb:v0C45p63E0* + ID_PRODUCT_FROM_DATABASE=Sonix Integrated Webcam + +usb:v0C45p63F1* + ID_PRODUCT_FROM_DATABASE=Integrated Webcam + +usb:v0C45p63F8* + ID_PRODUCT_FROM_DATABASE=Sonix Integrated Webcam + +usb:v0C45p6409* + ID_PRODUCT_FROM_DATABASE=Webcam + +usb:v0C45p6413* + ID_PRODUCT_FROM_DATABASE=Integrated Webcam + +usb:v0C45p6417* + ID_PRODUCT_FROM_DATABASE=Integrated Webcam + +usb:v0C45p641D* + ID_PRODUCT_FROM_DATABASE=1.3 MPixel Integrated Webcam + +usb:v0C45p6480* + ID_PRODUCT_FROM_DATABASE=Sonix 1.3 MP Laptop Integrated Webcam + +usb:v0C45p648B* + ID_PRODUCT_FROM_DATABASE=Integrated Webcam + +usb:v0C45p64BD* + ID_PRODUCT_FROM_DATABASE=Sony Visual Communication Camera + +usb:v0C45p7402* + ID_PRODUCT_FROM_DATABASE=TEMPerHUM Temperature & Humidity Sensor + +usb:v0C45p7403* + ID_PRODUCT_FROM_DATABASE=Foot Switch + +usb:v0C45p8000* + ID_PRODUCT_FROM_DATABASE=DC31VC + +usb:v0C45p8006* + ID_PRODUCT_FROM_DATABASE=Dual Mode Camera (8006 VGA) + +usb:v0C45p800A* + ID_PRODUCT_FROM_DATABASE=Vivitar Vivicam3350B + +usb:v0C46* + ID_VENDOR_FROM_DATABASE=WaveRider Communications, Inc. + +usb:v0C4A* + ID_VENDOR_FROM_DATABASE=ALGE-TIMING GmbH + +usb:v0C4Ap0889* + ID_PRODUCT_FROM_DATABASE=Timy + +usb:v0C4Ap088A* + ID_PRODUCT_FROM_DATABASE=Timy 2 + +usb:v0C4B* + ID_VENDOR_FROM_DATABASE=Reiner SCT Kartensysteme GmbH + +usb:v0C4Bp0100* + ID_PRODUCT_FROM_DATABASE=cyberJack e-com/pinpad + +usb:v0C4Bp0300* + ID_PRODUCT_FROM_DATABASE=cyberJack pinpad(a) + +usb:v0C4Bp9102* + ID_PRODUCT_FROM_DATABASE=cyberJack RFID basis contactless smartcard reader + +usb:v0C4C* + ID_VENDOR_FROM_DATABASE=Needham's Electronics + +usb:v0C4Cp0021* + ID_PRODUCT_FROM_DATABASE=EMP-21 Universal Programmer + +usb:v0C52* + ID_VENDOR_FROM_DATABASE=Sealevel Systems, Inc. + +usb:v0C52p2101* + ID_PRODUCT_FROM_DATABASE=SeaLINK+232 + +usb:v0C52p2102* + ID_PRODUCT_FROM_DATABASE=SeaLINK+485 + +usb:v0C52p2103* + ID_PRODUCT_FROM_DATABASE=SeaLINK+232I + +usb:v0C52p2104* + ID_PRODUCT_FROM_DATABASE=SeaLINK+485I + +usb:v0C52p2211* + ID_PRODUCT_FROM_DATABASE=SeaPORT+2/232 (Port 1) + +usb:v0C52p2212* + ID_PRODUCT_FROM_DATABASE=SeaPORT+2/485 (Port 1) + +usb:v0C52p2213* + ID_PRODUCT_FROM_DATABASE=SeaPORT+2 (Port 1) + +usb:v0C52p2221* + ID_PRODUCT_FROM_DATABASE=SeaPORT+2/232 (Port 2) + +usb:v0C52p2222* + ID_PRODUCT_FROM_DATABASE=SeaPORT+2/485 (Port 2) + +usb:v0C52p2223* + ID_PRODUCT_FROM_DATABASE=SeaPORT+2 (Port 2) + +usb:v0C52p2411* + ID_PRODUCT_FROM_DATABASE=SeaPORT+4/232 (Port 1) + +usb:v0C52p2412* + ID_PRODUCT_FROM_DATABASE=SeaPORT+4/485 (Port 1) + +usb:v0C52p2413* + ID_PRODUCT_FROM_DATABASE=SeaPORT+4 (Port 1) + +usb:v0C52p2421* + ID_PRODUCT_FROM_DATABASE=SeaPORT+4/232 (Port 2) + +usb:v0C52p2422* + ID_PRODUCT_FROM_DATABASE=SeaPORT+4/485 (Port 2) + +usb:v0C52p2423* + ID_PRODUCT_FROM_DATABASE=SeaPORT+4 (Port 2) + +usb:v0C52p2431* + ID_PRODUCT_FROM_DATABASE=SeaPORT+4/232 (Port 3) + +usb:v0C52p2432* + ID_PRODUCT_FROM_DATABASE=SeaPORT+4/485 (Port 3) + +usb:v0C52p2433* + ID_PRODUCT_FROM_DATABASE=SeaPORT+4 (Port 3) + +usb:v0C52p2441* + ID_PRODUCT_FROM_DATABASE=SeaPORT+4/232 (Port 4) + +usb:v0C52p2442* + ID_PRODUCT_FROM_DATABASE=SeaPORT+4/485 (Port 4) + +usb:v0C52p2443* + ID_PRODUCT_FROM_DATABASE=SeaPORT+4 (Port 4) + +usb:v0C52p2811* + ID_PRODUCT_FROM_DATABASE=SeaLINK+8/232 (Port 1) + +usb:v0C52p2812* + ID_PRODUCT_FROM_DATABASE=SeaLINK+8/485 (Port 1) + +usb:v0C52p2813* + ID_PRODUCT_FROM_DATABASE=SeaLINK+8 (Port 1) + +usb:v0C52p2821* + ID_PRODUCT_FROM_DATABASE=SeaLINK+8/232 (Port 2) + +usb:v0C52p2822* + ID_PRODUCT_FROM_DATABASE=SeaLINK+8/485 (Port 2) + +usb:v0C52p2823* + ID_PRODUCT_FROM_DATABASE=SeaLINK+8 (Port 2) + +usb:v0C52p2831* + ID_PRODUCT_FROM_DATABASE=SeaLINK+8/232 (Port 3) + +usb:v0C52p2832* + ID_PRODUCT_FROM_DATABASE=SeaLINK+8/485 (Port 3) + +usb:v0C52p2833* + ID_PRODUCT_FROM_DATABASE=SeaLINK+8 (Port 3) + +usb:v0C52p2841* + ID_PRODUCT_FROM_DATABASE=SeaLINK+8/232 (Port 4) + +usb:v0C52p2842* + ID_PRODUCT_FROM_DATABASE=SeaLINK+8/485 (Port 4) + +usb:v0C52p2843* + ID_PRODUCT_FROM_DATABASE=SeaLINK+8 (Port 4) + +usb:v0C52p2851* + ID_PRODUCT_FROM_DATABASE=SeaLINK+8/232 (Port 5) + +usb:v0C52p2852* + ID_PRODUCT_FROM_DATABASE=SeaLINK+8/485 (Port 5) + +usb:v0C52p2853* + ID_PRODUCT_FROM_DATABASE=SeaLINK+8 (Port 5) + +usb:v0C52p2861* + ID_PRODUCT_FROM_DATABASE=SeaLINK+8/232 (Port 6) + +usb:v0C52p2862* + ID_PRODUCT_FROM_DATABASE=SeaLINK+8/485 (Port 6) + +usb:v0C52p2863* + ID_PRODUCT_FROM_DATABASE=SeaLINK+8 (Port 6) + +usb:v0C52p2871* + ID_PRODUCT_FROM_DATABASE=SeaLINK+8/232 (Port 7) + +usb:v0C52p2872* + ID_PRODUCT_FROM_DATABASE=SeaLINK+8/485 (Port 7) + +usb:v0C52p2873* + ID_PRODUCT_FROM_DATABASE=SeaLINK+8 (Port 7) + +usb:v0C52p2881* + ID_PRODUCT_FROM_DATABASE=SeaLINK+8/232 (Port 8) + +usb:v0C52p2882* + ID_PRODUCT_FROM_DATABASE=SeaLINK+8/485 (Port 8) + +usb:v0C52p2883* + ID_PRODUCT_FROM_DATABASE=SeaLINK+8 (Port 8) + +usb:v0C52p9020* + ID_PRODUCT_FROM_DATABASE=SeaLINK+422 + +usb:v0C52pA02A* + ID_PRODUCT_FROM_DATABASE=SeaLINK+8 (Port 1+2) + +usb:v0C52pA02B* + ID_PRODUCT_FROM_DATABASE=SeaLINK+8 (Port 3+4) + +usb:v0C52pA02C* + ID_PRODUCT_FROM_DATABASE=SeaLINK+8 (Port 5+6) + +usb:v0C52pA02D* + ID_PRODUCT_FROM_DATABASE=SeaLINK+8 (Port 7+8) + +usb:v0C53* + ID_VENDOR_FROM_DATABASE=ViewPLUS, Inc. + +usb:v0C54* + ID_VENDOR_FROM_DATABASE=Glory, Ltd + +usb:v0C55* + ID_VENDOR_FROM_DATABASE=Spectrum Digital, Inc. + +usb:v0C55p0510* + ID_PRODUCT_FROM_DATABASE=Spectrum Digital XDS510 JTAG Debugger + +usb:v0C55p0540* + ID_PRODUCT_FROM_DATABASE=SPI540 + +usb:v0C55p5416* + ID_PRODUCT_FROM_DATABASE=TMS320C5416 DSK + +usb:v0C55p6416* + ID_PRODUCT_FROM_DATABASE=TMS320C6416 DDB + +usb:v0C56* + ID_VENDOR_FROM_DATABASE=Billion Bright, Ltd + +usb:v0C57* + ID_VENDOR_FROM_DATABASE=Imaginative Design Operation Co., Ltd + +usb:v0C58* + ID_VENDOR_FROM_DATABASE=Vidar Systems Corp. + +usb:v0C59* + ID_VENDOR_FROM_DATABASE=Dong Guan Shinko Wire Co., Ltd + +usb:v0C5A* + ID_VENDOR_FROM_DATABASE=TRS International Mfg., Inc. + +usb:v0C5E* + ID_VENDOR_FROM_DATABASE=Xytronix Research & Design + +usb:v0C60* + ID_VENDOR_FROM_DATABASE=Apogee Electronics Corp. + +usb:v0C62* + ID_VENDOR_FROM_DATABASE=Chant Sincere Co., Ltd + +usb:v0C63* + ID_VENDOR_FROM_DATABASE=Toko, Inc. + +usb:v0C64* + ID_VENDOR_FROM_DATABASE=Signality System Engineering Co., Ltd + +usb:v0C65* + ID_VENDOR_FROM_DATABASE=Eminence Enterprise Co., Ltd + +usb:v0C66* + ID_VENDOR_FROM_DATABASE=Rexon Electronics Corp. + +usb:v0C67* + ID_VENDOR_FROM_DATABASE=Concept Telecom, Ltd + +usb:v0C6A* + ID_VENDOR_FROM_DATABASE=ACS + +usb:v0C6Ap0005* + ID_PRODUCT_FROM_DATABASE=Color 320 x 240 LCD Display Terminal with Touchscreen + +usb:v0C6C* + ID_VENDOR_FROM_DATABASE=JETI Technische Instrumente GmbH + +usb:v0C6Cp04B2* + ID_PRODUCT_FROM_DATABASE=Specbos 1201 + +usb:v0C70* + ID_VENDOR_FROM_DATABASE=MCT Elektronikladen + +usb:v0C70p0000* + ID_PRODUCT_FROM_DATABASE=USB08 Development board + +usb:v0C70p0747* + ID_PRODUCT_FROM_DATABASE=Eye Movement Recorder [Visagraph]/[ReadAlyzer] + +usb:v0C72* + ID_VENDOR_FROM_DATABASE=PEAK System + +usb:v0C72p000C* + ID_PRODUCT_FROM_DATABASE=PCAN-USB + +usb:v0C72p000D* + ID_PRODUCT_FROM_DATABASE=PCAN Pro + +usb:v0C74* + ID_VENDOR_FROM_DATABASE=Optronic Laboratories Inc. + +usb:v0C74p0002* + ID_PRODUCT_FROM_DATABASE=OL 700-30 Goniometer + +usb:v0C76* + ID_VENDOR_FROM_DATABASE=JMTek, LLC. + +usb:v0C76p0001* + ID_PRODUCT_FROM_DATABASE=Mass Storage Controller + +usb:v0C76p0002* + ID_PRODUCT_FROM_DATABASE=Mass Storage Controller + +usb:v0C76p0003* + ID_PRODUCT_FROM_DATABASE=USBdisk + +usb:v0C76p0004* + ID_PRODUCT_FROM_DATABASE=Mass Storage Controller + +usb:v0C76p0005* + ID_PRODUCT_FROM_DATABASE=Transcend Flash disk + +usb:v0C76p0006* + ID_PRODUCT_FROM_DATABASE=Transcend JetFlash + +usb:v0C76p0007* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v0C76p1600* + ID_PRODUCT_FROM_DATABASE=Ion Quick Play LP turntable + +usb:v0C76p1605* + ID_PRODUCT_FROM_DATABASE=SSS Headphone Set + +usb:v0C76p1607* + ID_PRODUCT_FROM_DATABASE=audio controller + +usb:v0C77* + ID_VENDOR_FROM_DATABASE=Sipix Group, Ltd + +usb:v0C77p1001* + ID_PRODUCT_FROM_DATABASE=SiPix Web2 + +usb:v0C77p1002* + ID_PRODUCT_FROM_DATABASE=SiPix SC2100 + +usb:v0C77p1010* + ID_PRODUCT_FROM_DATABASE=SiPix Snap + +usb:v0C77p1011* + ID_PRODUCT_FROM_DATABASE=SiPix Blink 2 + +usb:v0C77p1015* + ID_PRODUCT_FROM_DATABASE=SiPix CAMeleon + +usb:v0C78* + ID_VENDOR_FROM_DATABASE=Detto Corp. + +usb:v0C79* + ID_VENDOR_FROM_DATABASE=NuConnex Technologies Pte., Ltd + +usb:v0C7A* + ID_VENDOR_FROM_DATABASE=Wing-Span Enterprise Co., Ltd + +usb:v0C86* + ID_VENDOR_FROM_DATABASE=NDA Technologies, Inc. + +usb:v0C88* + ID_VENDOR_FROM_DATABASE=Kyocera Wireless Corp. + +usb:v0C88p0021* + ID_PRODUCT_FROM_DATABASE=Handheld + +usb:v0C88p17DA* + ID_PRODUCT_FROM_DATABASE=Qualcomm Kyocera CDMA Technologies MSM + +usb:v0C89* + ID_VENDOR_FROM_DATABASE=Honda Tsushin Kogyo Co., Ltd + +usb:v0C8A* + ID_VENDOR_FROM_DATABASE=Pathway Connectivity, Inc. + +usb:v0C8B* + ID_VENDOR_FROM_DATABASE=Wavefly Corp. + +usb:v0C8C* + ID_VENDOR_FROM_DATABASE=Coactive Networks + +usb:v0C8D* + ID_VENDOR_FROM_DATABASE=Tempo + +usb:v0C8E* + ID_VENDOR_FROM_DATABASE=Cesscom Co., Ltd + +usb:v0C8Ep6000* + ID_PRODUCT_FROM_DATABASE=Luxian Series + +usb:v0C8F* + ID_VENDOR_FROM_DATABASE=Applied Microsystems + +usb:v0C94* + ID_VENDOR_FROM_DATABASE=Cryptera + +usb:v0C94pA000* + ID_PRODUCT_FROM_DATABASE=EPP 1217 + +usb:v0C98* + ID_VENDOR_FROM_DATABASE=Berkshire Products, Inc. + +usb:v0C98p1140* + ID_PRODUCT_FROM_DATABASE=USB PC Watchdog + +usb:v0C99* + ID_VENDOR_FROM_DATABASE=Innochips Co., Ltd + +usb:v0C9A* + ID_VENDOR_FROM_DATABASE=Hanwool Robotics Corp. + +usb:v0C9B* + ID_VENDOR_FROM_DATABASE=Jobin Yvon, Inc. + +usb:v0C9D* + ID_VENDOR_FROM_DATABASE=SemTek + +usb:v0C9Dp0170* + ID_PRODUCT_FROM_DATABASE=3873 Manual Insert card reader + +usb:v0CA2* + ID_VENDOR_FROM_DATABASE=Zyfer + +usb:v0CA3* + ID_VENDOR_FROM_DATABASE=Sega Corp. + +usb:v0CA4* + ID_VENDOR_FROM_DATABASE=ST&T Instrument Corp. + +usb:v0CA5* + ID_VENDOR_FROM_DATABASE=BAE Systems Canada, Inc. + +usb:v0CA6* + ID_VENDOR_FROM_DATABASE=Castles Technology Co., Ltd + +usb:v0CA6p0010* + ID_PRODUCT_FROM_DATABASE=EZUSB PC/SC Smart Card Reader + +usb:v0CA6p0050* + ID_PRODUCT_FROM_DATABASE=EZ220PU Reader Controller + +usb:v0CA6p1077* + ID_PRODUCT_FROM_DATABASE=Bludrive Family Smart Card Reader + +usb:v0CA6p107E* + ID_PRODUCT_FROM_DATABASE=Reader Controller + +usb:v0CA6p2010* + ID_PRODUCT_FROM_DATABASE=myPad110 PC/SC Smart Card Reader + +usb:v0CA6p3050* + ID_PRODUCT_FROM_DATABASE=EZ710 Smart Card Reader + +usb:v0CA7* + ID_VENDOR_FROM_DATABASE=Information Systems Laboratories + +usb:v0CAD* + ID_VENDOR_FROM_DATABASE=Motorola CGISS + +usb:v0CADp9001* + ID_PRODUCT_FROM_DATABASE=PowerPad Pocket PC Device + +usb:v0CAE* + ID_VENDOR_FROM_DATABASE=Ascom Business Systems, Ltd + +usb:v0CAF* + ID_VENDOR_FROM_DATABASE=Buslink + +usb:v0CAFp2507* + ID_PRODUCT_FROM_DATABASE=Hi-Speed USB-to-IDE Bridge Controller + +usb:v0CAFp2515* + ID_PRODUCT_FROM_DATABASE=Flash Disk Embedded Hub + +usb:v0CAFp2516* + ID_PRODUCT_FROM_DATABASE=Flash Disk Security Device + +usb:v0CAFp2517* + ID_PRODUCT_FROM_DATABASE=Flash Disk Mass Storage Device + +usb:v0CAFp25C7* + ID_PRODUCT_FROM_DATABASE=Hi-Speed USB-to-IDE Bridge Controller + +usb:v0CAFp3A00* + ID_PRODUCT_FROM_DATABASE=Hard Drive + +usb:v0CAFp3A20* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v0CAFp3ACD* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v0CB0* + ID_VENDOR_FROM_DATABASE=Flying Pig Systems + +usb:v0CB1* + ID_VENDOR_FROM_DATABASE=Innovonics, Inc. + +usb:v0CB6* + ID_VENDOR_FROM_DATABASE=Celestix Networks, Pte., Ltd + +usb:v0CB7* + ID_VENDOR_FROM_DATABASE=Singatron Enterprise Co., Ltd + +usb:v0CB8* + ID_VENDOR_FROM_DATABASE=Opticis Co., Ltd + +usb:v0CBA* + ID_VENDOR_FROM_DATABASE=Trust Electronic (Shanghai) Co., Ltd + +usb:v0CBB* + ID_VENDOR_FROM_DATABASE=Shanghai Darong Electronics Co., Ltd + +usb:v0CBC* + ID_VENDOR_FROM_DATABASE=Palmax Technology Co., Ltd + +usb:v0CBCp0101* + ID_PRODUCT_FROM_DATABASE=Pocket PC P6C + +usb:v0CBCp0201* + ID_PRODUCT_FROM_DATABASE=Personal Digital Assistant + +usb:v0CBCp0301* + ID_PRODUCT_FROM_DATABASE=Personal Digital Assistant P6M+ + +usb:v0CBCp0401* + ID_PRODUCT_FROM_DATABASE=Pocket PC + +usb:v0CBD* + ID_VENDOR_FROM_DATABASE=Pentel Co., Ltd (Electronics Equipment Div.) + +usb:v0CBE* + ID_VENDOR_FROM_DATABASE=Keryx Technologies, Inc. + +usb:v0CBF* + ID_VENDOR_FROM_DATABASE=Union Genius Computer Co., Ltd + +usb:v0CC0* + ID_VENDOR_FROM_DATABASE=Kuon Yi Industrial Corp. + +usb:v0CC1* + ID_VENDOR_FROM_DATABASE=Given Imaging, Ltd + +usb:v0CC2* + ID_VENDOR_FROM_DATABASE=Timex Corp. + +usb:v0CC3* + ID_VENDOR_FROM_DATABASE=Rimage Corp. + +usb:v0CC4* + ID_VENDOR_FROM_DATABASE=emsys GmbH + +usb:v0CC5* + ID_VENDOR_FROM_DATABASE=Sendo + +usb:v0CC6* + ID_VENDOR_FROM_DATABASE=Intermagic Corp. + +usb:v0CC7* + ID_VENDOR_FROM_DATABASE=Kontron Medical AG + +usb:v0CC8* + ID_VENDOR_FROM_DATABASE=Technotools Corp. + +usb:v0CC9* + ID_VENDOR_FROM_DATABASE=BroadMAX Technologies, Inc. + +usb:v0CCA* + ID_VENDOR_FROM_DATABASE=Amphenol + +usb:v0CCB* + ID_VENDOR_FROM_DATABASE=SKNet Co., Ltd + +usb:v0CCC* + ID_VENDOR_FROM_DATABASE=Domex Technology Corp. + +usb:v0CCD* + ID_VENDOR_FROM_DATABASE=TerraTec Electronic GmbH + +usb:v0CCDp0012* + ID_PRODUCT_FROM_DATABASE=PHASE 26 + +usb:v0CCDp0013* + ID_PRODUCT_FROM_DATABASE=PHASE 26 + +usb:v0CCDp0014* + ID_PRODUCT_FROM_DATABASE=PHASE 26 + +usb:v0CCDp0015* + ID_PRODUCT_FROM_DATABASE=Flash Update for TerraTec PHASE 26 + +usb:v0CCDp0021* + ID_PRODUCT_FROM_DATABASE=Cameo Grabster 200 + +usb:v0CCDp0023* + ID_PRODUCT_FROM_DATABASE=Mystify Claw + +usb:v0CCDp0028* + ID_PRODUCT_FROM_DATABASE=Aureon 5.1 MkII + +usb:v0CCDp0032* + ID_PRODUCT_FROM_DATABASE=MIDI HUBBLE + +usb:v0CCDp0035* + ID_PRODUCT_FROM_DATABASE=Miditech Play'n Roll + +usb:v0CCDp0036* + ID_PRODUCT_FROM_DATABASE=Cinergy 250 Audio + +usb:v0CCDp0037* + ID_PRODUCT_FROM_DATABASE=Cinergy 250 Audio + +usb:v0CCDp0038* + ID_PRODUCT_FROM_DATABASE=Cinergy T² DVB-T Receiver + +usb:v0CCDp0039* + ID_PRODUCT_FROM_DATABASE=Grabster AV 400 + +usb:v0CCDp003B* + ID_PRODUCT_FROM_DATABASE=Cinergy 400 + +usb:v0CCDp003C* + ID_PRODUCT_FROM_DATABASE=Grabster AV 250 + +usb:v0CCDp0042* + ID_PRODUCT_FROM_DATABASE=Cinergy Hybrid T XS + +usb:v0CCDp0043* + ID_PRODUCT_FROM_DATABASE=Cinergy T XS + +usb:v0CCDp004E* + ID_PRODUCT_FROM_DATABASE=Cinergy T XS + +usb:v0CCDp004F* + ID_PRODUCT_FROM_DATABASE=Cinergy Analog XS + +usb:v0CCDp0055* + ID_PRODUCT_FROM_DATABASE=Cinergy T XE (Version 1, AF9005) + +usb:v0CCDp005C* + ID_PRODUCT_FROM_DATABASE=Cinergy T² + +usb:v0CCDp0069* + ID_PRODUCT_FROM_DATABASE=Cinergy T XE (Version 2, AF9015) + +usb:v0CCDp006B* + ID_PRODUCT_FROM_DATABASE=Cinergy HT PVR (EU) + +usb:v0CCDp0072* + ID_PRODUCT_FROM_DATABASE=Cinergy Hybrid T + +usb:v0CCDp0077* + ID_PRODUCT_FROM_DATABASE=Aureon Dual USB + +usb:v0CCDp0078* + ID_PRODUCT_FROM_DATABASE=Cinergy T XXS + +usb:v0CCDp0086* + ID_PRODUCT_FROM_DATABASE=Cinergy Hybrid XE + +usb:v0CCDp008E* + ID_PRODUCT_FROM_DATABASE=Cinergy HTC XS + +usb:v0CCDp0097* + ID_PRODUCT_FROM_DATABASE=Cinergy T RC MKII + +usb:v0CCDp0099* + ID_PRODUCT_FROM_DATABASE=AfaTech 9015 [Cinergy T Stick Dual] + +usb:v0CCDp00A5* + ID_PRODUCT_FROM_DATABASE=Cinergy Hybrid Stick + +usb:v0CCDp00A9* + ID_PRODUCT_FROM_DATABASE=RTL2838 DVB-T COFDM Demodulator [TerraTec Cinergy T Stick Black] + +usb:v0CCDp00B3* + ID_PRODUCT_FROM_DATABASE=NOXON DAB/DAB+ Stick + +usb:v0CCDp10A7* + ID_PRODUCT_FROM_DATABASE=TerraTec G3 + +usb:v0CD4* + ID_VENDOR_FROM_DATABASE=Bang Olufsen + +usb:v0CD4p0101* + ID_PRODUCT_FROM_DATABASE=BeolinkPC2 + +usb:v0CD5* + ID_VENDOR_FROM_DATABASE=LabJack Corporation + +usb:v0CD5p0003* + ID_PRODUCT_FROM_DATABASE=U3 + +usb:v0CD5p0009* + ID_PRODUCT_FROM_DATABASE=UE9 + +usb:v0CD7* + ID_VENDOR_FROM_DATABASE=NewChip S.r.l. + +usb:v0CD8* + ID_VENDOR_FROM_DATABASE=JS Digitech, Inc. + +usb:v0CD8p2007* + ID_PRODUCT_FROM_DATABASE=Smart Card Reader/JSTU-9700 + +usb:v0CD9* + ID_VENDOR_FROM_DATABASE=Hitachi Shin Din Cable, Ltd + +usb:v0CDE* + ID_VENDOR_FROM_DATABASE=Z-Com + +usb:v0CDEp0001* + ID_PRODUCT_FROM_DATABASE=XI-750 802.11b Wireless Adapter [Atmel AT76C503A] + +usb:v0CDEp0002* + ID_PRODUCT_FROM_DATABASE=XI-725/726 Prism2.5 802.11b Adapter + +usb:v0CDEp0003* + ID_PRODUCT_FROM_DATABASE=Sagem 802.11b Dongle + +usb:v0CDEp0004* + ID_PRODUCT_FROM_DATABASE=Sagem 802.11b Dongle + +usb:v0CDEp0005* + ID_PRODUCT_FROM_DATABASE=XI-735 Prism3 802.11b Adapter + +usb:v0CDEp0006* + ID_PRODUCT_FROM_DATABASE=XG-300 802.11b Adapter + +usb:v0CDEp0008* + ID_PRODUCT_FROM_DATABASE=XG-703A 802.11g Wireless Adapter [Intersil ISL3887] + +usb:v0CDEp0009* + ID_PRODUCT_FROM_DATABASE=(ZD1211)IEEE 802.11b+g Adapter + +usb:v0CDEp0011* + ID_PRODUCT_FROM_DATABASE=ZD1211 + +usb:v0CDEp0012* + ID_PRODUCT_FROM_DATABASE=AR5523 + +usb:v0CDEp0013* + ID_PRODUCT_FROM_DATABASE=AR5523 driver (no firmware) + +usb:v0CDEp0014* + ID_PRODUCT_FROM_DATABASE=NB 802.11g Wireless LAN Adapter(3887A) + +usb:v0CDEp0015* + ID_PRODUCT_FROM_DATABASE=XG-705A 802.11g Wireless Adapter [Intersil ISL3887] + +usb:v0CDEp0016* + ID_PRODUCT_FROM_DATABASE=NB 802.11g Wireless LAN Adapter(3887A) + +usb:v0CDEp0018* + ID_PRODUCT_FROM_DATABASE=NB 802.11a/b/g Wireless LAN Adapter(3887A) + +usb:v0CDEp001A* + ID_PRODUCT_FROM_DATABASE=802.11bg + +usb:v0CDEp001C* + ID_PRODUCT_FROM_DATABASE=802.11b/g Wireless Network Adapter + +usb:v0CDEp0020* + ID_PRODUCT_FROM_DATABASE=AG-760A 802.11abg Wireless Adapter [ZyDAS ZD1211B] + +usb:v0CDEp0022* + ID_PRODUCT_FROM_DATABASE=802.11b/g/n Wireless Network Adapter + +usb:v0CDEp0023* + ID_PRODUCT_FROM_DATABASE=UB81 802.11bgn + +usb:v0CDEp0025* + ID_PRODUCT_FROM_DATABASE=802.11b/g/n USB Wireless Network Adapter + +usb:v0CDEp0026* + ID_PRODUCT_FROM_DATABASE=UB82 802.11abgn + +usb:v0CDEp0027* + ID_PRODUCT_FROM_DATABASE=Sphairon Homelink 1202 802.11n Wireless Adapter [Atheros AR9170] + +usb:v0CE5* + ID_VENDOR_FROM_DATABASE=Validation Technologies International + +usb:v0CE5p0003* + ID_PRODUCT_FROM_DATABASE=Matrix + +usb:v0CE9* + ID_VENDOR_FROM_DATABASE=pico Technology + +usb:v0CE9p1001* + ID_PRODUCT_FROM_DATABASE=PicoScope3204 + +usb:v0CF1* + ID_VENDOR_FROM_DATABASE=e-Conn Electronic Co., Ltd + +usb:v0CF2* + ID_VENDOR_FROM_DATABASE=ENE Technology, Inc. + +usb:v0CF2p6220* + ID_PRODUCT_FROM_DATABASE=SD Card Reader (SG361) + +usb:v0CF2p6225* + ID_PRODUCT_FROM_DATABASE=SD card reader (UB6225) + +usb:v0CF2p6250* + ID_PRODUCT_FROM_DATABASE=SD card reader (UB6250) + +usb:v0CF3* + ID_VENDOR_FROM_DATABASE=Atheros Communications, Inc. + +usb:v0CF3p0001* + ID_PRODUCT_FROM_DATABASE=AR5523 + +usb:v0CF3p0002* + ID_PRODUCT_FROM_DATABASE=AR5523 (no firmware) + +usb:v0CF3p0003* + ID_PRODUCT_FROM_DATABASE=AR5523 + +usb:v0CF3p0004* + ID_PRODUCT_FROM_DATABASE=AR5523 (no firmware) + +usb:v0CF3p0005* + ID_PRODUCT_FROM_DATABASE=AR5523 + +usb:v0CF3p0006* + ID_PRODUCT_FROM_DATABASE=AR5523 (no firmware) + +usb:v0CF3p1001* + ID_PRODUCT_FROM_DATABASE=Thomson TG121N [Atheros AR9001U-(2)NG] + +usb:v0CF3p1002* + ID_PRODUCT_FROM_DATABASE=TP-Link TL-WN821N v2 802.11n [Atheros AR9170] + +usb:v0CF3p1006* + ID_PRODUCT_FROM_DATABASE=TP-Link TL-WN322G v3 / TL-WN422G v2 802.11g [Atheros AR9271] + +usb:v0CF3p1010* + ID_PRODUCT_FROM_DATABASE=3Com 3CRUSBN275 802.11abgn Wireless Adapter [Atheros AR9170] + +usb:v0CF3p20FF* + ID_PRODUCT_FROM_DATABASE=AR7010 (no firmware) + +usb:v0CF3p3000* + ID_PRODUCT_FROM_DATABASE=AR3011 Bluetooth (no firmware) + +usb:v0CF3p3002* + ID_PRODUCT_FROM_DATABASE=AR3011 Bluetooth + +usb:v0CF3p3005* + ID_PRODUCT_FROM_DATABASE=AR3011 Bluetooth + +usb:v0CF3p7015* + ID_PRODUCT_FROM_DATABASE=TP-Link TL-WN821N v3 802.11n [Atheros AR7010+AR9287] + +usb:v0CF3p9170* + ID_PRODUCT_FROM_DATABASE=AR9170 802.11n + +usb:v0CF3p9271* + ID_PRODUCT_FROM_DATABASE=AR9271 802.11n + +usb:v0CF3pB002* + ID_PRODUCT_FROM_DATABASE=Ubiquiti WiFiStation 802.11n [Atheros AR9271] + +usb:v0CF3pB003* + ID_PRODUCT_FROM_DATABASE=Ubiquiti WiFiStationEXT 802.11n [Atheros AR9271] + +usb:v0CF4* + ID_VENDOR_FROM_DATABASE=Fomtex Corp. + +usb:v0CF5* + ID_VENDOR_FROM_DATABASE=Cellink Co., Ltd + +usb:v0CF6* + ID_VENDOR_FROM_DATABASE=Compucable Corp. + +usb:v0CF7* + ID_VENDOR_FROM_DATABASE=ishoni Networks + +usb:v0CF8* + ID_VENDOR_FROM_DATABASE=Clarisys, Inc. + +usb:v0CF8p0750* + ID_PRODUCT_FROM_DATABASE=Claritel-i750 - vp + +usb:v0CF9* + ID_VENDOR_FROM_DATABASE=Central System Research Co., Ltd + +usb:v0CFA* + ID_VENDOR_FROM_DATABASE=Inviso, Inc. + +usb:v0CFC* + ID_VENDOR_FROM_DATABASE=Minolta-QMS, Inc. + +usb:v0CFCp2301* + ID_PRODUCT_FROM_DATABASE=Magicolor 2300 DL + +usb:v0CFCp2350* + ID_PRODUCT_FROM_DATABASE=Magicolor 2350EN/3300 + +usb:v0CFCp3100* + ID_PRODUCT_FROM_DATABASE=Magicolor 3100 + +usb:v0CFCp7300* + ID_PRODUCT_FROM_DATABASE=Magicolor 5450/5550 + +usb:v0CFF* + ID_VENDOR_FROM_DATABASE=SAFA MEDIA Co., Ltd. + +usb:v0CFFp0320* + ID_PRODUCT_FROM_DATABASE=SR-380N + +usb:v0D06* + ID_VENDOR_FROM_DATABASE=telos EDV Systementwicklung GmbH + +usb:v0D08* + ID_VENDOR_FROM_DATABASE=UTStarcom + +usb:v0D08p0602* + ID_PRODUCT_FROM_DATABASE=DV007 [serial] + +usb:v0D08p0603* + ID_PRODUCT_FROM_DATABASE=DV007 [storage] + +usb:v0D0B* + ID_VENDOR_FROM_DATABASE=Contemporary Controls + +usb:v0D0C* + ID_VENDOR_FROM_DATABASE=Astron Electronics Co., Ltd + +usb:v0D0D* + ID_VENDOR_FROM_DATABASE=MKNet Corp. + +usb:v0D0E* + ID_VENDOR_FROM_DATABASE=Hybrid Networks, Inc. + +usb:v0D0F* + ID_VENDOR_FROM_DATABASE=Feng Shin Cable Co., Ltd + +usb:v0D10* + ID_VENDOR_FROM_DATABASE=Elastic Networks + +usb:v0D10p0001* + ID_PRODUCT_FROM_DATABASE=StormPort (WDM) + +usb:v0D11* + ID_VENDOR_FROM_DATABASE=Maspro Denkoh Corp. + +usb:v0D12* + ID_VENDOR_FROM_DATABASE=Hansol Electronics, Inc. + +usb:v0D13* + ID_VENDOR_FROM_DATABASE=BMF Corp. + +usb:v0D14* + ID_VENDOR_FROM_DATABASE=Array Comm, Inc. + +usb:v0D15* + ID_VENDOR_FROM_DATABASE=OnStream b.v. + +usb:v0D16* + ID_VENDOR_FROM_DATABASE=Hi-Touch Imaging Technologies Co., Ltd + +usb:v0D16p0001* + ID_PRODUCT_FROM_DATABASE=PhotoShuttle + +usb:v0D16p0002* + ID_PRODUCT_FROM_DATABASE=Photo Printer 730 series + +usb:v0D16p0004* + ID_PRODUCT_FROM_DATABASE=Photo Printer 63xPL/PS + +usb:v0D16p0100* + ID_PRODUCT_FROM_DATABASE=Photo Printer 63xPL/PS + +usb:v0D16p0102* + ID_PRODUCT_FROM_DATABASE=Photo Printer 64xPS + +usb:v0D16p0103* + ID_PRODUCT_FROM_DATABASE=Photo Printer 730 series + +usb:v0D16p0104* + ID_PRODUCT_FROM_DATABASE=Photo Printer 63xPL/PS + +usb:v0D16p0105* + ID_PRODUCT_FROM_DATABASE=Photo Printer 64xPS + +usb:v0D16p0200* + ID_PRODUCT_FROM_DATABASE=Photo Printer 64xDL + +usb:v0D17* + ID_VENDOR_FROM_DATABASE=NALTEC, Inc. + +usb:v0D18* + ID_VENDOR_FROM_DATABASE=coaXmedia + +usb:v0D19* + ID_VENDOR_FROM_DATABASE=Hank Connection Industrial Co., Ltd + +usb:v0D28* + ID_VENDOR_FROM_DATABASE=NXP + +usb:v0D28p0204* + ID_PRODUCT_FROM_DATABASE=LPC1768 + +usb:v0D32* + ID_VENDOR_FROM_DATABASE=Leo Hui Electric Wire & Cable Co., Ltd + +usb:v0D33* + ID_VENDOR_FROM_DATABASE=AirSpeak, Inc. + +usb:v0D34* + ID_VENDOR_FROM_DATABASE=Rearden Steel Technologies + +usb:v0D35* + ID_VENDOR_FROM_DATABASE=Dah Kun Co., Ltd + +usb:v0D3A* + ID_VENDOR_FROM_DATABASE=Posiflex Technologies, Inc. + +usb:v0D3C* + ID_VENDOR_FROM_DATABASE=Sri Cable Technology, Ltd + +usb:v0D3D* + ID_VENDOR_FROM_DATABASE=Tangtop Technology Co., Ltd + +usb:v0D3Dp0001* + ID_PRODUCT_FROM_DATABASE=HID Keyboard + +usb:v0D3E* + ID_VENDOR_FROM_DATABASE=Fitcom, inc. + +usb:v0D3F* + ID_VENDOR_FROM_DATABASE=MTS Systems Corp. + +usb:v0D40* + ID_VENDOR_FROM_DATABASE=Ascor, Inc. + +usb:v0D41* + ID_VENDOR_FROM_DATABASE=Ta Yun Terminals Industrial Co., Ltd + +usb:v0D42* + ID_VENDOR_FROM_DATABASE=Full Der Co., Ltd + +usb:v0D46* + ID_VENDOR_FROM_DATABASE=Kobil Systems GmbH + +usb:v0D46p2012* + ID_PRODUCT_FROM_DATABASE=KAAN Standard Plus (Smartcard reader) + +usb:v0D46p3003* + ID_PRODUCT_FROM_DATABASE=mIDentity Light / KAAN SIM III + +usb:v0D46p4000* + ID_PRODUCT_FROM_DATABASE=mIDentity (mass storage) + +usb:v0D46p4001* + ID_PRODUCT_FROM_DATABASE=mIDentity Basic/Classic (composite device) + +usb:v0D46p4081* + ID_PRODUCT_FROM_DATABASE=mIDentity Basic/Classic (installationless) + +usb:v0D48* + ID_VENDOR_FROM_DATABASE=Promethean Limited + +usb:v0D48p0001* + ID_PRODUCT_FROM_DATABASE=ACTIVboard + +usb:v0D48p0004* + ID_PRODUCT_FROM_DATABASE=ACTIVboard + +usb:v0D48p0100* + ID_PRODUCT_FROM_DATABASE=Audio + +usb:v0D49* + ID_VENDOR_FROM_DATABASE=Maxtor + +usb:v0D49p3000* + ID_PRODUCT_FROM_DATABASE=Drive + +usb:v0D49p3010* + ID_PRODUCT_FROM_DATABASE=3000LE Drive + +usb:v0D49p3100* + ID_PRODUCT_FROM_DATABASE=Hi-Speed USB-IDE Bridge Controller + +usb:v0D49p3200* + ID_PRODUCT_FROM_DATABASE=Personal Storage 3200 + +usb:v0D49p5000* + ID_PRODUCT_FROM_DATABASE=5000XT Drive + +usb:v0D49p5010* + ID_PRODUCT_FROM_DATABASE=5000LE Drive + +usb:v0D49p5020* + ID_PRODUCT_FROM_DATABASE=Mobile Hard Disk Drive + +usb:v0D49p7000* + ID_PRODUCT_FROM_DATABASE=OneTouch + +usb:v0D49p7010* + ID_PRODUCT_FROM_DATABASE=OneTouch + +usb:v0D49p7100* + ID_PRODUCT_FROM_DATABASE=OneTouch II 300GB External Hard Disk + +usb:v0D49p7410* + ID_PRODUCT_FROM_DATABASE=Mobile Hard Disk Drive (1TB) + +usb:v0D49p7450* + ID_PRODUCT_FROM_DATABASE=Basics Portable USB Device + +usb:v0D4A* + ID_VENDOR_FROM_DATABASE=NF Corp. + +usb:v0D4B* + ID_VENDOR_FROM_DATABASE=Grape Systems, Inc. + +usb:v0D4C* + ID_VENDOR_FROM_DATABASE=Tedas AG + +usb:v0D4D* + ID_VENDOR_FROM_DATABASE=Coherent, Inc. + +usb:v0D4E* + ID_VENDOR_FROM_DATABASE=Agere Systems Netherland BV + +usb:v0D4Ep047A* + ID_PRODUCT_FROM_DATABASE=WLAN Card + +usb:v0D4Ep1000* + ID_PRODUCT_FROM_DATABASE=Wireless Card Model 0801 + +usb:v0D4Ep1001* + ID_PRODUCT_FROM_DATABASE=Wireless Card Model 0802 + +usb:v0D4F* + ID_VENDOR_FROM_DATABASE=EADS Airbus France + +usb:v0D50* + ID_VENDOR_FROM_DATABASE=Cleware GmbH + +usb:v0D50p0011* + ID_PRODUCT_FROM_DATABASE=USB-Temp2 Thermometer + +usb:v0D51* + ID_VENDOR_FROM_DATABASE=Volex (Asia) Pte., Ltd + +usb:v0D53* + ID_VENDOR_FROM_DATABASE=HMI Co., Ltd + +usb:v0D54* + ID_VENDOR_FROM_DATABASE=Holon Corp. + +usb:v0D55* + ID_VENDOR_FROM_DATABASE=ASKA Technologies, Inc. + +usb:v0D56* + ID_VENDOR_FROM_DATABASE=AVLAB Technology, Inc. + +usb:v0D57* + ID_VENDOR_FROM_DATABASE=Solomon Microtech, Ltd + +usb:v0D5C* + ID_VENDOR_FROM_DATABASE=SMC Networks, Inc. + +usb:v0D5CpA001* + ID_PRODUCT_FROM_DATABASE=SMC2662W (v1) EZ Connect 802.11b Wireless Adapter [Atmel AT76C503A] + +usb:v0D5CpA002* + ID_PRODUCT_FROM_DATABASE=SMC2662W v2 / SMC2662W-AR / Belkin F5D6050 [Atmel at76c503a] + +usb:v0D5E* + ID_VENDOR_FROM_DATABASE=Myacom, Ltd + +usb:v0D5Ep2346* + ID_PRODUCT_FROM_DATABASE=BT Digital Access adapter + +usb:v0D5F* + ID_VENDOR_FROM_DATABASE=CSI, Inc. + +usb:v0D60* + ID_VENDOR_FROM_DATABASE=IVL Technologies, Ltd + +usb:v0D61* + ID_VENDOR_FROM_DATABASE=Meilu Electronics (Shenzhen) Co., Ltd + +usb:v0D62* + ID_VENDOR_FROM_DATABASE=Darfon Electronics Corp. + +usb:v0D62p0003* + ID_PRODUCT_FROM_DATABASE=Smartcard Reader + +usb:v0D62p0004* + ID_PRODUCT_FROM_DATABASE=Keyboard + +usb:v0D62p001C* + ID_PRODUCT_FROM_DATABASE=Benq X120 Internet Keyboard Pro + +usb:v0D62p0306* + ID_PRODUCT_FROM_DATABASE=M530 Mouse + +usb:v0D62p0800* + ID_PRODUCT_FROM_DATABASE=Magic Wheel + +usb:v0D62p2021* + ID_PRODUCT_FROM_DATABASE=AM805 Keyboard + +usb:v0D62p2026* + ID_PRODUCT_FROM_DATABASE=TECOM Bluetooth Device + +usb:v0D62p2050* + ID_PRODUCT_FROM_DATABASE=Mouse + +usb:v0D62p2106* + ID_PRODUCT_FROM_DATABASE=Dell L20U Multimedia Keyboard + +usb:v0D62pA100* + ID_PRODUCT_FROM_DATABASE=Optical Mouse + +usb:v0D63* + ID_VENDOR_FROM_DATABASE=Fritz Gegauf AG + +usb:v0D64* + ID_VENDOR_FROM_DATABASE=DXG Technology Corp. + +usb:v0D64p0105* + ID_PRODUCT_FROM_DATABASE=Dual Mode Digital Camera 1.3M + +usb:v0D64p0107* + ID_PRODUCT_FROM_DATABASE=Horus MT-409 Camera + +usb:v0D64p0108* + ID_PRODUCT_FROM_DATABASE=Dual Mode Digital Camera + +usb:v0D64p0202* + ID_PRODUCT_FROM_DATABASE=Dual Mode Video Camera Device + +usb:v0D64p0303* + ID_PRODUCT_FROM_DATABASE=DXG-305V Camera + +usb:v0D64p1001* + ID_PRODUCT_FROM_DATABASE=SiPix Stylecam/UMAX AstraPix 320s + +usb:v0D64p1002* + ID_PRODUCT_FROM_DATABASE=Fashion Cam 01 Dual-Mode DSC (Video Camera) + +usb:v0D64p1003* + ID_PRODUCT_FROM_DATABASE=Fashion Cam Dual-Mode DSC (Controller) + +usb:v0D64p1021* + ID_PRODUCT_FROM_DATABASE=D-Link DSC 350F + +usb:v0D64p1208* + ID_PRODUCT_FROM_DATABASE=Dual Mode Still Camera Device + +usb:v0D64p2208* + ID_PRODUCT_FROM_DATABASE=Mass Storage + +usb:v0D64p3105* + ID_PRODUCT_FROM_DATABASE=Dual Mode Digital Camera Disk + +usb:v0D64p3108* + ID_PRODUCT_FROM_DATABASE=Digicam Mass Storage Device + +usb:v0D65* + ID_VENDOR_FROM_DATABASE=KMJP Co., Ltd + +usb:v0D66* + ID_VENDOR_FROM_DATABASE=TMT + +usb:v0D67* + ID_VENDOR_FROM_DATABASE=Advanet, Inc. + +usb:v0D68* + ID_VENDOR_FROM_DATABASE=Super Link Electronics Co., Ltd + +usb:v0D69* + ID_VENDOR_FROM_DATABASE=NSI + +usb:v0D6A* + ID_VENDOR_FROM_DATABASE=Megapower International Corp. + +usb:v0D6B* + ID_VENDOR_FROM_DATABASE=And-Or Logic + +usb:v0D70* + ID_VENDOR_FROM_DATABASE=Try Computer Co., Ltd + +usb:v0D71* + ID_VENDOR_FROM_DATABASE=Hirakawa Hewtech Corp. + +usb:v0D72* + ID_VENDOR_FROM_DATABASE=Winmate Communication, Inc. + +usb:v0D73* + ID_VENDOR_FROM_DATABASE=Hit's Communications, Inc. + +usb:v0D76* + ID_VENDOR_FROM_DATABASE=MFP Korea, Inc. + +usb:v0D77* + ID_VENDOR_FROM_DATABASE=Power Sentry/Newpoint + +usb:v0D78* + ID_VENDOR_FROM_DATABASE=Japan Distributor Corp. + +usb:v0D7A* + ID_VENDOR_FROM_DATABASE=MARX Datentechnik GmbH + +usb:v0D7B* + ID_VENDOR_FROM_DATABASE=Wellco Technology Co., Ltd + +usb:v0D7C* + ID_VENDOR_FROM_DATABASE=Taiwan Line Tek Electronic Co., Ltd + +usb:v0D7D* + ID_VENDOR_FROM_DATABASE=Phison Electronics Corp. + +usb:v0D7Dp0100* + ID_PRODUCT_FROM_DATABASE=PS1001/1011/1006/1026 Flash Disk + +usb:v0D7Dp0110* + ID_PRODUCT_FROM_DATABASE=Gigabyte FlexDrive + +usb:v0D7Dp0120* + ID_PRODUCT_FROM_DATABASE=Disk Pro 64MB + +usb:v0D7Dp0124* + ID_PRODUCT_FROM_DATABASE=GIGABYTE Disk + +usb:v0D7Dp0240* + ID_PRODUCT_FROM_DATABASE=I/O-Magic/Transcend 6-in-1 Card Reader + +usb:v0D7Dp110E* + ID_PRODUCT_FROM_DATABASE=NEC uPD720121/130 USB-ATA/ATAPI Bridge + +usb:v0D7Dp1240* + ID_PRODUCT_FROM_DATABASE=Apacer 6-in-1 Card Reader 2.0 + +usb:v0D7Dp1270* + ID_PRODUCT_FROM_DATABASE=Wolverine SixPac 6000 + +usb:v0D7Dp1300* + ID_PRODUCT_FROM_DATABASE=Flash Disk + +usb:v0D7Dp1320* + ID_PRODUCT_FROM_DATABASE=PS2031 Flash Disk + +usb:v0D7Dp1400* + ID_PRODUCT_FROM_DATABASE=Attache 256MB USB 2.0 Flash Drive + +usb:v0D7Dp1420* + ID_PRODUCT_FROM_DATABASE=PS2044 Pen Drive + +usb:v0D7Dp1470* + ID_PRODUCT_FROM_DATABASE=Vosonic X's-Drive II+ VP2160 + +usb:v0D7Dp1620* + ID_PRODUCT_FROM_DATABASE=USB Disk Pro + +usb:v0D7Dp1900* + ID_PRODUCT_FROM_DATABASE=USB Thumb Drive + +usb:v0D7E* + ID_VENDOR_FROM_DATABASE=American Computer & Digital Components + +usb:v0D7Ep2507* + ID_PRODUCT_FROM_DATABASE=Hi-Speed USB-to-IDE Bridge Controller + +usb:v0D7Ep2517* + ID_PRODUCT_FROM_DATABASE=Hi-Speed Mass Storage Device + +usb:v0D7Ep25C7* + ID_PRODUCT_FROM_DATABASE=Hi-Speed USB-to-IDE Bridge Controller + +usb:v0D7F* + ID_VENDOR_FROM_DATABASE=Essential Reality LLC + +usb:v0D7Fp0100* + ID_PRODUCT_FROM_DATABASE=P5 Glove glove controller + +usb:v0D80* + ID_VENDOR_FROM_DATABASE=H.R. Silvine Electronics, Inc. + +usb:v0D81* + ID_VENDOR_FROM_DATABASE=TechnoVision + +usb:v0D83* + ID_VENDOR_FROM_DATABASE=Think Outside, Inc. + +usb:v0D87* + ID_VENDOR_FROM_DATABASE=Dolby Laboratories Inc. + +usb:v0D89* + ID_VENDOR_FROM_DATABASE=Oz Software + +usb:v0D8A* + ID_VENDOR_FROM_DATABASE=King Jim Co., Ltd + +usb:v0D8Ap0101* + ID_PRODUCT_FROM_DATABASE=TEPRA PRO + +usb:v0D8B* + ID_VENDOR_FROM_DATABASE=Ascom Telecommunications, Ltd + +usb:v0D8C* + ID_VENDOR_FROM_DATABASE=C-Media Electronics, Inc. + +usb:v0D8Cp0001* + ID_PRODUCT_FROM_DATABASE=Audio Device + +usb:v0D8Cp0002* + ID_PRODUCT_FROM_DATABASE=Composite Device + +usb:v0D8Cp0003* + ID_PRODUCT_FROM_DATABASE=Sound Device + +usb:v0D8Cp0006* + ID_PRODUCT_FROM_DATABASE=Storm HP-USB500 5.1 Headset + +usb:v0D8Cp000C* + ID_PRODUCT_FROM_DATABASE=Audio Adapter + +usb:v0D8Cp000D* + ID_PRODUCT_FROM_DATABASE=Composite Device + +usb:v0D8Cp000E* + ID_PRODUCT_FROM_DATABASE=Audio Adapter (Planet UP-100, Genius G-Talk) + +usb:v0D8Cp001F* + ID_PRODUCT_FROM_DATABASE=CM108 Audio Controller + +usb:v0D8Cp0102* + ID_PRODUCT_FROM_DATABASE=CM106 Like Sound Device + +usb:v0D8Cp0103* + ID_PRODUCT_FROM_DATABASE=CM102-A+/102S+ Audio Controller + +usb:v0D8Cp0104* + ID_PRODUCT_FROM_DATABASE=CM103+ Audio Controller + +usb:v0D8Cp0105* + ID_PRODUCT_FROM_DATABASE=CM108 Audio Controller + +usb:v0D8Cp0107* + ID_PRODUCT_FROM_DATABASE=CM108 Audio Controller + +usb:v0D8Cp010F* + ID_PRODUCT_FROM_DATABASE=CM108 Audio Controller + +usb:v0D8Cp0115* + ID_PRODUCT_FROM_DATABASE=CM108 Audio Controller + +usb:v0D8Cp013C* + ID_PRODUCT_FROM_DATABASE=CM108 Audio Controller + +usb:v0D8Cp0201* + ID_PRODUCT_FROM_DATABASE=CM6501 + +usb:v0D8Cp5000* + ID_PRODUCT_FROM_DATABASE=Mass Storage Controller + +usb:v0D8Cp5200* + ID_PRODUCT_FROM_DATABASE=Mass Storage Controller(0D8C,5200) + +usb:v0D8CpB213* + ID_PRODUCT_FROM_DATABASE=USB Phone CM109 (aka CT2000,VPT1000) + +usb:v0D8D* + ID_VENDOR_FROM_DATABASE=Promotion & Display Technology, Ltd + +usb:v0D8Dp0234* + ID_PRODUCT_FROM_DATABASE=V-234 Composite Device + +usb:v0D8Dp0550* + ID_PRODUCT_FROM_DATABASE=V-550 Composite Device + +usb:v0D8Dp0551* + ID_PRODUCT_FROM_DATABASE=V-551 Composite Device + +usb:v0D8Dp0552* + ID_PRODUCT_FROM_DATABASE=V-552 Composite Device + +usb:v0D8Dp0651* + ID_PRODUCT_FROM_DATABASE=V-651 Composite Device + +usb:v0D8Dp0652* + ID_PRODUCT_FROM_DATABASE=V-652 Composite Device + +usb:v0D8Dp0653* + ID_PRODUCT_FROM_DATABASE=V-653 Composite Device + +usb:v0D8Dp0654* + ID_PRODUCT_FROM_DATABASE=V-654 Composite Device + +usb:v0D8Dp0655* + ID_PRODUCT_FROM_DATABASE=V-655 Composite Device + +usb:v0D8Dp0656* + ID_PRODUCT_FROM_DATABASE=V-656 Composite Device + +usb:v0D8Dp0657* + ID_PRODUCT_FROM_DATABASE=V-657 Composite Device + +usb:v0D8Dp0658* + ID_PRODUCT_FROM_DATABASE=V-658 Composite Device + +usb:v0D8Dp0659* + ID_PRODUCT_FROM_DATABASE=V-659 Composite Device + +usb:v0D8Dp0660* + ID_PRODUCT_FROM_DATABASE=V-660 Composite Device + +usb:v0D8Dp0661* + ID_PRODUCT_FROM_DATABASE=V-661 Composite Device + +usb:v0D8Dp0662* + ID_PRODUCT_FROM_DATABASE=V-662 Composite Device + +usb:v0D8Dp0850* + ID_PRODUCT_FROM_DATABASE=V-850 Composite Device + +usb:v0D8Dp0851* + ID_PRODUCT_FROM_DATABASE=V-851 Composite Device + +usb:v0D8Dp0852* + ID_PRODUCT_FROM_DATABASE=V-852 Composite Device + +usb:v0D8Dp0901* + ID_PRODUCT_FROM_DATABASE=V-901 Composite Device + +usb:v0D8Dp0902* + ID_PRODUCT_FROM_DATABASE=V-902 Composite Device + +usb:v0D8Dp0903* + ID_PRODUCT_FROM_DATABASE=V-903 Composite Device + +usb:v0D8Dp4754* + ID_PRODUCT_FROM_DATABASE=Voyager DMP Composite Device + +usb:v0D8DpBB00* + ID_PRODUCT_FROM_DATABASE=Bloomberg Composite Device + +usb:v0D8DpBB01* + ID_PRODUCT_FROM_DATABASE=Bloomberg Composite Device + +usb:v0D8DpBB02* + ID_PRODUCT_FROM_DATABASE=Bloomberg Composite Device + +usb:v0D8DpBB03* + ID_PRODUCT_FROM_DATABASE=Bloomberg Composite Device + +usb:v0D8DpBB04* + ID_PRODUCT_FROM_DATABASE=Bloomberg Composite Device + +usb:v0D8DpBB05* + ID_PRODUCT_FROM_DATABASE=Bloomberg Composite Device + +usb:v0D8DpFFFE* + ID_PRODUCT_FROM_DATABASE=Global Tuner Composite Device + +usb:v0D8DpFFFF* + ID_PRODUCT_FROM_DATABASE=Voyager DMP Composite Device + +usb:v0D8E* + ID_VENDOR_FROM_DATABASE=Global Sun Technology, Inc. + +usb:v0D8Ep0163* + ID_PRODUCT_FROM_DATABASE=802.11g 54 Mbps Wireless Dongle + +usb:v0D8Ep1621* + ID_PRODUCT_FROM_DATABASE=802.11b Wireless Adapter + +usb:v0D8Ep3762* + ID_PRODUCT_FROM_DATABASE=Cohiba 802.11g Wireless Mini adapter [Intersil ISL3887] + +usb:v0D8Ep3763* + ID_PRODUCT_FROM_DATABASE=802.11g Wireless dongle + +usb:v0D8Ep7100* + ID_PRODUCT_FROM_DATABASE=802.11b Adapter + +usb:v0D8Ep7110* + ID_PRODUCT_FROM_DATABASE=WL-210 / WU210P 802.11b Wireless Adapter [Atmel AT76C503A] + +usb:v0D8Ep7605* + ID_PRODUCT_FROM_DATABASE=TRENDnet TEW-224UB 802.11b Wireless Adapter [Atmel AT76C503A] + +usb:v0D8Ep7801* + ID_PRODUCT_FROM_DATABASE=AR5523 + +usb:v0D8Ep7802* + ID_PRODUCT_FROM_DATABASE=AR5523 (no firmware) + +usb:v0D8Ep7811* + ID_PRODUCT_FROM_DATABASE=AR5523 + +usb:v0D8Ep7812* + ID_PRODUCT_FROM_DATABASE=AR5523 (no firmware) + +usb:v0D8Ep7A01* + ID_PRODUCT_FROM_DATABASE=PRISM25 802.11b Adapter + +usb:v0D8F* + ID_VENDOR_FROM_DATABASE=Pitney Bowes + +usb:v0D90* + ID_VENDOR_FROM_DATABASE=Sure-Fire Electrical Corp. + +usb:v0D96* + ID_VENDOR_FROM_DATABASE=Skanhex Technology, Inc. + +usb:v0D96p0000* + ID_PRODUCT_FROM_DATABASE=Jenoptik JD350 video + +usb:v0D96p3300* + ID_PRODUCT_FROM_DATABASE=SX330z Camera + +usb:v0D96p4100* + ID_PRODUCT_FROM_DATABASE=SX410z Camera + +usb:v0D96p4102* + ID_PRODUCT_FROM_DATABASE=MD 9700 Camera + +usb:v0D96p4104* + ID_PRODUCT_FROM_DATABASE=Jenoptik JD-4100z3s + +usb:v0D96p410A* + ID_PRODUCT_FROM_DATABASE=Medion 9801/Novatech SX-410z + +usb:v0D96p5200* + ID_PRODUCT_FROM_DATABASE=SX-520z Camera + +usb:v0D97* + ID_VENDOR_FROM_DATABASE=Santa Barbara Instrument Group + +usb:v0D97p0001* + ID_PRODUCT_FROM_DATABASE=SBIG Astronomy Camera (without firmware) + +usb:v0D97p0101* + ID_PRODUCT_FROM_DATABASE=SBIG Astronomy Camera (with firmware) + +usb:v0D98* + ID_VENDOR_FROM_DATABASE=Mars Semiconductor Corp. + +usb:v0D98p0300* + ID_PRODUCT_FROM_DATABASE=Avaya Wireless Card + +usb:v0D98p1007* + ID_PRODUCT_FROM_DATABASE=Discovery Kids Digital Camera + +usb:v0D99* + ID_VENDOR_FROM_DATABASE=Trazer Technologies, Inc. + +usb:v0D9A* + ID_VENDOR_FROM_DATABASE=RTX Telecom AS + +usb:v0D9Ap0001* + ID_PRODUCT_FROM_DATABASE=Bluetooth Device + +usb:v0D9B* + ID_VENDOR_FROM_DATABASE=Tat Shing Electrical Co. + +usb:v0D9C* + ID_VENDOR_FROM_DATABASE=Chee Chen Hi-Technology Co., Ltd + +usb:v0D9D* + ID_VENDOR_FROM_DATABASE=Sanwa Supply, Inc. + +usb:v0D9E* + ID_VENDOR_FROM_DATABASE=Avaya + +usb:v0D9Ep0300* + ID_PRODUCT_FROM_DATABASE=Wireless Card + +usb:v0D9F* + ID_VENDOR_FROM_DATABASE=Powercom Co., Ltd + +usb:v0D9Fp0001* + ID_PRODUCT_FROM_DATABASE=Uninterruptible Power Supply + +usb:v0D9Fp0002* + ID_PRODUCT_FROM_DATABASE=Black Knight PRO / WOW Uninterruptible Power Supply (Cypress HID->COM RS232) + +usb:v0D9Fp00A2* + ID_PRODUCT_FROM_DATABASE=Imperial Uninterruptible Power Supply (HID PDC) + +usb:v0D9Fp00A3* + ID_PRODUCT_FROM_DATABASE=Smart King PRO Uninterruptible Power Supply (HID PDC) + +usb:v0D9Fp00A4* + ID_PRODUCT_FROM_DATABASE=WOW Uninterruptible Power Supply (HID PDC) + +usb:v0D9Fp00A5* + ID_PRODUCT_FROM_DATABASE=Vanguard Uninterruptible Power Supply (HID PDC) + +usb:v0D9Fp00A6* + ID_PRODUCT_FROM_DATABASE=Black Knight PRO Uninterruptible Power Supply (HID PDC) + +usb:v0DA0* + ID_VENDOR_FROM_DATABASE=Danger Research + +usb:v0DA1* + ID_VENDOR_FROM_DATABASE=Suzhou Peter's Precise Industrial Co., Ltd + +usb:v0DA2* + ID_VENDOR_FROM_DATABASE=Land Instruments International, Ltd + +usb:v0DA3* + ID_VENDOR_FROM_DATABASE=Nippon Electro-Sensory Devices Corp. + +usb:v0DA4* + ID_VENDOR_FROM_DATABASE=Polar Electro OY + +usb:v0DA4p0001* + ID_PRODUCT_FROM_DATABASE=Interface + +usb:v0DA7* + ID_VENDOR_FROM_DATABASE=IOGear, Inc. + +usb:v0DA8* + ID_VENDOR_FROM_DATABASE=softDSP Co., Ltd + +usb:v0DA8p0001* + ID_PRODUCT_FROM_DATABASE=SDS 200A Oscilloscope + +usb:v0DAB* + ID_VENDOR_FROM_DATABASE=Cubig Group + +usb:v0DABp0100* + ID_PRODUCT_FROM_DATABASE=DVR/CVR-M140 MP3 Player + +usb:v0DAD* + ID_VENDOR_FROM_DATABASE=Westover Scientific + +usb:v0DB0* + ID_VENDOR_FROM_DATABASE=Micro Star International + +usb:v0DB0p1020* + ID_PRODUCT_FROM_DATABASE=PC2PC WLAN Card + +usb:v0DB0p1967* + ID_PRODUCT_FROM_DATABASE=Bluetooth Dongle + +usb:v0DB0p3801* + ID_PRODUCT_FROM_DATABASE=Motorola Bluetooth 2.1+EDR Device + +usb:v0DB0p4011* + ID_PRODUCT_FROM_DATABASE=Medion Flash XL V2.0 Card Reader + +usb:v0DB0p4023* + ID_PRODUCT_FROM_DATABASE=Lexar Mobile Card Reader + +usb:v0DB0p4600* + ID_PRODUCT_FROM_DATABASE=802.11b/g Turbo Wireless Adapter + +usb:v0DB0p5501* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v0DB0p5502* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v0DB0p5513* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v0DB0p5515* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v0DB0p5516* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v0DB0p5580* + ID_PRODUCT_FROM_DATABASE=Mega Sky 580 DVB-T Tuner [M902x] + +usb:v0DB0p5581* + ID_PRODUCT_FROM_DATABASE=Mega Sky 580 DVB-T Tuner [GL861] + +usb:v0DB0p6823* + ID_PRODUCT_FROM_DATABASE=UB11B/MS-6823 802.11b Wi-Fi adapter + +usb:v0DB0p6826* + ID_PRODUCT_FROM_DATABASE=IEEE 802.11g Wireless Network Adapter + +usb:v0DB0p6855* + ID_PRODUCT_FROM_DATABASE=Bluetooth Device + +usb:v0DB0p6861* + ID_PRODUCT_FROM_DATABASE=MSI-6861 802.11g WiFi adapter + +usb:v0DB0p6865* + ID_PRODUCT_FROM_DATABASE=RT2570 + +usb:v0DB0p6869* + ID_PRODUCT_FROM_DATABASE=RT2570 + +usb:v0DB0p6874* + ID_PRODUCT_FROM_DATABASE=RT2573 + +usb:v0DB0p6877* + ID_PRODUCT_FROM_DATABASE=RT2573 + +usb:v0DB0p6881* + ID_PRODUCT_FROM_DATABASE=Bluetooth Class I EDR Device + +usb:v0DB0p688A* + ID_PRODUCT_FROM_DATABASE=Bluetooth Class I EDR Device + +usb:v0DB0p6899* + ID_PRODUCT_FROM_DATABASE=802.11bgn 1T1R Mini Card Wireless Adapter + +usb:v0DB0p6970* + ID_PRODUCT_FROM_DATABASE=MS-6970 BToes Bluetooth adapter + +usb:v0DB0p697A* + ID_PRODUCT_FROM_DATABASE=Bluetooth Dongle + +usb:v0DB0p6982* + ID_PRODUCT_FROM_DATABASE=Medion Flash XL Card Reader + +usb:v0DB0pA861* + ID_PRODUCT_FROM_DATABASE=RT2573 + +usb:v0DB0pA874* + ID_PRODUCT_FROM_DATABASE=RT2573 + +usb:v0DB0pA970* + ID_PRODUCT_FROM_DATABASE=Bluetooth dongle + +usb:v0DB0pA97A* + ID_PRODUCT_FROM_DATABASE=Bluetooth EDR Device + +usb:v0DB0pB970* + ID_PRODUCT_FROM_DATABASE=Bluetooth EDR Device + +usb:v0DB0pB97A* + ID_PRODUCT_FROM_DATABASE=Bluetooth EDR Device + +usb:v0DB1* + ID_VENDOR_FROM_DATABASE=Wen Te Electronics Co., Ltd + +usb:v0DB2* + ID_VENDOR_FROM_DATABASE=Shian Hwi Plug Parts, Plastic Factory + +usb:v0DB3* + ID_VENDOR_FROM_DATABASE=Tekram Technology Co., Ltd + +usb:v0DB4* + ID_VENDOR_FROM_DATABASE=Chung Fu Chen Yeh Enterprise Corp. + +usb:v0DB7* + ID_VENDOR_FROM_DATABASE=ELCON Systemtechnik + +usb:v0DB7p0002* + ID_PRODUCT_FROM_DATABASE=Goldpfeil P-LAN + +usb:v0DBC* + ID_VENDOR_FROM_DATABASE=A&D Medical + +usb:v0DBCp0003* + ID_PRODUCT_FROM_DATABASE=AND Serial Cable [AND Smart Cable] + +usb:v0DBE* + ID_VENDOR_FROM_DATABASE=Jiuh Shiuh Precision Industry Co., Ltd + +usb:v0DBF* + ID_VENDOR_FROM_DATABASE=Jess-Link International + +usb:v0DBFp0002* + ID_PRODUCT_FROM_DATABASE=SmartDongle Security Key + +usb:v0DBFp0200* + ID_PRODUCT_FROM_DATABASE=HDD Storage Solution + +usb:v0DBFp021B* + ID_PRODUCT_FROM_DATABASE=USB-2.0 IDE Adapter + +usb:v0DBFp0300* + ID_PRODUCT_FROM_DATABASE=Storage Adapter + +usb:v0DBFp0333* + ID_PRODUCT_FROM_DATABASE=Storage Adapter + +usb:v0DBFp0707* + ID_PRODUCT_FROM_DATABASE=ZIV Drive + +usb:v0DC0* + ID_VENDOR_FROM_DATABASE=G7 Solutions (formerly Great Notions) + +usb:v0DC1* + ID_VENDOR_FROM_DATABASE=Tamagawa Seiki Co., Ltd + +usb:v0DC3* + ID_VENDOR_FROM_DATABASE=Athena Smartcard Solutions, Inc. + +usb:v0DC3p0801* + ID_PRODUCT_FROM_DATABASE=ASEDrive III + +usb:v0DC3p0802* + ID_PRODUCT_FROM_DATABASE=ASEDrive IIIe + +usb:v0DC3p1104* + ID_PRODUCT_FROM_DATABASE=ASEDrive IIIe KB + +usb:v0DC3p1701* + ID_PRODUCT_FROM_DATABASE=ASEKey + +usb:v0DC3p1702* + ID_PRODUCT_FROM_DATABASE=ASEKey + +usb:v0DC4* + ID_VENDOR_FROM_DATABASE=Macpower Peripherals, Ltd + +usb:v0DC4p0040* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v0DC4p0041* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v0DC4p0042* + ID_PRODUCT_FROM_DATABASE=Mass Storage Device + +usb:v0DC4p0101* + ID_PRODUCT_FROM_DATABASE=Hi-Speed Mass Storage Device + +usb:v0DC4p020A* + ID_PRODUCT_FROM_DATABASE=Oyen Digital MiniPro 2.5" hard drive enclosure + +usb:v0DC5* + ID_VENDOR_FROM_DATABASE=SDK Co., Ltd + +usb:v0DC6* + ID_VENDOR_FROM_DATABASE=Precision Squared Technology Corp. + +usb:v0DC6p2301* + ID_PRODUCT_FROM_DATABASE=Wireless Touchpad Keyboard + +usb:v0DC7* + ID_VENDOR_FROM_DATABASE=First Cable Line, Inc. + +usb:v0DCD* + ID_VENDOR_FROM_DATABASE=NetworkFab Corp. + +usb:v0DCDp0001* + ID_PRODUCT_FROM_DATABASE=Remote Interface Adapter + +usb:v0DCDp0002* + ID_PRODUCT_FROM_DATABASE=High Bandwidth Codec + +usb:v0DD0* + ID_VENDOR_FROM_DATABASE=Access Solutions + +usb:v0DD0p1002* + ID_PRODUCT_FROM_DATABASE=Triple Talk Speech Synthesizer + +usb:v0DD1* + ID_VENDOR_FROM_DATABASE=Contek Electronics Co., Ltd + +usb:v0DD2* + ID_VENDOR_FROM_DATABASE=Power Quotient International Co., Ltd + +usb:v0DD2p0003* + ID_PRODUCT_FROM_DATABASE=Mass Storage (P) + +usb:v0DD3* + ID_VENDOR_FROM_DATABASE=MediaQ + +usb:v0DD4* + ID_VENDOR_FROM_DATABASE=Custom Engineering SPA + +usb:v0DD5* + ID_VENDOR_FROM_DATABASE=California Micro Devices + +usb:v0DD7* + ID_VENDOR_FROM_DATABASE=Kocom Co., Ltd + +usb:v0DD8* + ID_VENDOR_FROM_DATABASE=Netac Technology Co., Ltd + +usb:v0DD8p1060* + ID_PRODUCT_FROM_DATABASE=USB-CF-Card + +usb:v0DD8pE007* + ID_PRODUCT_FROM_DATABASE=OnlyDisk U222 Pendrive + +usb:v0DD8pF607* + ID_PRODUCT_FROM_DATABASE=OnlyDisk U208 1G flash drive [U-SAFE] + +usb:v0DD9* + ID_VENDOR_FROM_DATABASE=HighSpeed Surfing + +usb:v0DDA* + ID_VENDOR_FROM_DATABASE=Integrated Circuit Solution, Inc. + +usb:v0DDAp0001* + ID_PRODUCT_FROM_DATABASE=Multi-Card Reader 6in1 + +usb:v0DDAp0002* + ID_PRODUCT_FROM_DATABASE=Multi-Card Reader 7in1 + +usb:v0DDAp0003* + ID_PRODUCT_FROM_DATABASE=Flash Disk + +usb:v0DDAp0005* + ID_PRODUCT_FROM_DATABASE=Internal Multi-Card Reader 6in1 + +usb:v0DDAp0008* + ID_PRODUCT_FROM_DATABASE=SD single card reader + +usb:v0DDAp0009* + ID_PRODUCT_FROM_DATABASE=MS single card reader + +usb:v0DDAp000A* + ID_PRODUCT_FROM_DATABASE=MS+SD Dual Card Reader + +usb:v0DDAp000B* + ID_PRODUCT_FROM_DATABASE=SM single card reader + +usb:v0DDAp0101* + ID_PRODUCT_FROM_DATABASE=All-In-One Card Reader + +usb:v0DDAp0102* + ID_PRODUCT_FROM_DATABASE=All-In-One Card Reader + +usb:v0DDAp0301* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v0DDAp0302* + ID_PRODUCT_FROM_DATABASE=Multi-Card MP3 Player + +usb:v0DDAp1001* + ID_PRODUCT_FROM_DATABASE=Multi-Flash Disk + +usb:v0DDAp2001* + ID_PRODUCT_FROM_DATABASE=Multi-Card Reader + +usb:v0DDAp2002* + ID_PRODUCT_FROM_DATABASE=Q018 default PID + +usb:v0DDAp2003* + ID_PRODUCT_FROM_DATABASE=Multi-Card Reader + +usb:v0DDAp2005* + ID_PRODUCT_FROM_DATABASE=Datalux DLX-1611 16in1 Card Reader + +usb:v0DDAp2006* + ID_PRODUCT_FROM_DATABASE=All-In-One Card Reader + +usb:v0DDAp2007* + ID_PRODUCT_FROM_DATABASE=USB to ATAPI bridge + +usb:v0DDAp2008* + ID_PRODUCT_FROM_DATABASE=All-In-One Card Reader + +usb:v0DDAp2013* + ID_PRODUCT_FROM_DATABASE=SD/MS Combo Card Reader + +usb:v0DDAp2014* + ID_PRODUCT_FROM_DATABASE=SD/MS Single Card Reader + +usb:v0DDAp2023* + ID_PRODUCT_FROM_DATABASE=card reader SD/MS DEMO board with ICSI brand name (MaskROM version) + +usb:v0DDAp2024* + ID_PRODUCT_FROM_DATABASE=card reader SD/MS DEMO board with Generic brand name (MaskROM version) + +usb:v0DDAp2026* + ID_PRODUCT_FROM_DATABASE=USB2.0 Card Reader + +usb:v0DDAp2027* + ID_PRODUCT_FROM_DATABASE=USB 2.0 Card Reader + +usb:v0DDAp2315* + ID_PRODUCT_FROM_DATABASE=UFD MP3 player (model 2) + +usb:v0DDAp2318* + ID_PRODUCT_FROM_DATABASE=UFD MP3 player (model 1) + +usb:v0DDAp2321* + ID_PRODUCT_FROM_DATABASE=UFD MP3 player + +usb:v0DDB* + ID_VENDOR_FROM_DATABASE=Tamarack, Inc. + +usb:v0DDD* + ID_VENDOR_FROM_DATABASE=Datelink Technology Co., Ltd + +usb:v0DDE* + ID_VENDOR_FROM_DATABASE=Ubicom, Inc. + +usb:v0DE0* + ID_VENDOR_FROM_DATABASE=BD Consumer Healthcare + +usb:v0DE7* + ID_VENDOR_FROM_DATABASE=USBmicro + +usb:v0DE7p0191* + ID_PRODUCT_FROM_DATABASE=U401 Interface card + +usb:v0DE7p01A5* + ID_PRODUCT_FROM_DATABASE=U421 interface card + +usb:v0DE7p01C3* + ID_PRODUCT_FROM_DATABASE=U451 relay interface card + +usb:v0DEA* + ID_VENDOR_FROM_DATABASE=UTECH Electronic (D.G.) Co., Ltd. + +usb:v0DED* + ID_VENDOR_FROM_DATABASE=Novasonics + +usb:v0DEE* + ID_VENDOR_FROM_DATABASE=Lifetime Memory Products + +usb:v0DEEp4010* + ID_PRODUCT_FROM_DATABASE=Storage Adapter + +usb:v0DEF* + ID_VENDOR_FROM_DATABASE=Full Rise Electronic Co., Ltd + +usb:v0DF4* + ID_VENDOR_FROM_DATABASE=NET&SYS + +usb:v0DF4p0201* + ID_PRODUCT_FROM_DATABASE=MNG-2005 + +usb:v0DF6* + ID_VENDOR_FROM_DATABASE=Sitecom Europe B.V. + +usb:v0DF6p0001* + ID_PRODUCT_FROM_DATABASE=C-Media VOIP Device + +usb:v0DF6p0004* + ID_PRODUCT_FROM_DATABASE=Bluetooth 2.0 Adapter 100m + +usb:v0DF6p0007* + ID_PRODUCT_FROM_DATABASE=Bluetooth 2.0 Adapter 10m + +usb:v0DF6p000B* + ID_PRODUCT_FROM_DATABASE=Bluetooth 2.0 Adapter DFU + +usb:v0DF6p000D* + ID_PRODUCT_FROM_DATABASE=WL-168 Wireless Network Adapter 54g + +usb:v0DF6p0017* + ID_PRODUCT_FROM_DATABASE=WL-182 Wireless-N Network USB Card + +usb:v0DF6p0019* + ID_PRODUCT_FROM_DATABASE=Bluetooth 2.0 adapter 10m CN-512v2 001 + +usb:v0DF6p001A* + ID_PRODUCT_FROM_DATABASE=Bluetooth 2.0 adapter 100m CN-521v2 001 + +usb:v0DF6p002B* + ID_PRODUCT_FROM_DATABASE=WL-188 Wireless Network 300N USB Adapter + +usb:v0DF6p002C* + ID_PRODUCT_FROM_DATABASE=WL-301 Wireless Network 300N USB Adapter + +usb:v0DF6p002D* + ID_PRODUCT_FROM_DATABASE=WL-302 Wireless Network 300N USB dongle + +usb:v0DF6p0036* + ID_PRODUCT_FROM_DATABASE=WL-603 Wireless Adapter + +usb:v0DF6p0039* + ID_PRODUCT_FROM_DATABASE=WL-315 Wireless-N USB Adapter + +usb:v0DF6p003B* + ID_PRODUCT_FROM_DATABASE=WL-321 Wireless USB Gaming Adapter 300N + +usb:v0DF6p003C* + ID_PRODUCT_FROM_DATABASE=WL-323 Wireless-N USB Adapter + +usb:v0DF6p003D* + ID_PRODUCT_FROM_DATABASE=WL-324 Wireless USB Adapter 300N + +usb:v0DF6p003E* + ID_PRODUCT_FROM_DATABASE=WL-343 Wireless USB Adapter 150N X1 + +usb:v0DF6p003F* + ID_PRODUCT_FROM_DATABASE=WL-608 Wireless USB Adapter 54g + +usb:v0DF6p0040* + ID_PRODUCT_FROM_DATABASE=WL-344 Wireless Adapter 300N X2 [Ralink RT3071] + +usb:v0DF6p0041* + ID_PRODUCT_FROM_DATABASE=WL-329 Wireless Dualband USB adapter 300N + +usb:v0DF6p0042* + ID_PRODUCT_FROM_DATABASE=WL-345 Wireless USB adapter 300N X3 + +usb:v0DF6p0045* + ID_PRODUCT_FROM_DATABASE=WL-353 Wireless USB Adapter 150N Nano + +usb:v0DF6p0047* + ID_PRODUCT_FROM_DATABASE=WL-352v1 Wireless USB Adapter 300N 002 + +usb:v0DF6p0048* + ID_PRODUCT_FROM_DATABASE=WL-349v1 Wireless Adapter 150N 002 [Ralink RT3070] + +usb:v0DF6p0049* + ID_PRODUCT_FROM_DATABASE=WL-356 Wireless Adapter 300N + +usb:v0DF6p004A* + ID_PRODUCT_FROM_DATABASE=WL-358v1 Wireless Micro USB Adapter 300N X3 002 + +usb:v0DF6p004B* + ID_PRODUCT_FROM_DATABASE=WL-349v3 Wireless Micro Adapter 150N X1 [Realtek RTL8192SU] + +usb:v0DF6p004C* + ID_PRODUCT_FROM_DATABASE=WL-352 802.11n Adapter [Realtek RTL8191SU] + +usb:v0DF6p0050* + ID_PRODUCT_FROM_DATABASE=WL-349v4 Wireless Micro Adapter 150N X1 [Ralink RT3370] + +usb:v0DF6p0056* + ID_PRODUCT_FROM_DATABASE=LN-031 10/100/1000 Ethernet Adapter + +usb:v0DF6p005D* + ID_PRODUCT_FROM_DATABASE=WLA-2000 v1.001 WLAN [RTL8191SU] + +usb:v0DF6p0060* + ID_PRODUCT_FROM_DATABASE=WLA-4000 802.11bgn [Ralink RT3072] + +usb:v0DF6p0062* + ID_PRODUCT_FROM_DATABASE=WLA-5000 802.11abgn [Ralink RT3572] + +usb:v0DF6p061C* + ID_PRODUCT_FROM_DATABASE=LN-028 Network USB 2.0 Adapter + +usb:v0DF6p21F4* + ID_PRODUCT_FROM_DATABASE=44 St Bluetooth Device + +usb:v0DF6p2200* + ID_PRODUCT_FROM_DATABASE=Sitecom bluetooth2.0 class 2 dongle CN-512 + +usb:v0DF6p2208* + ID_PRODUCT_FROM_DATABASE=Sitecom bluetooth2.0 class 2 dongle CN-520 + +usb:v0DF6p2209* + ID_PRODUCT_FROM_DATABASE=Sitecom bluetooth2.0 class 1 dongle CN-521 + +usb:v0DF6p9071* + ID_PRODUCT_FROM_DATABASE=WL-113 rev 1 Wireless Network USB Adapter + +usb:v0DF6p9075* + ID_PRODUCT_FROM_DATABASE=WL-117 Hi-Speed USB Adapter + +usb:v0DF6p90AC* + ID_PRODUCT_FROM_DATABASE=WL-172 Wireless Network USB Adapter 54g Turbo + +usb:v0DF6p9712* + ID_PRODUCT_FROM_DATABASE=WL-113 rev 2 Wireless Network USB Adapter + +usb:v0DF7* + ID_VENDOR_FROM_DATABASE=Mobile Action Technology, Inc. + +usb:v0DF7p0620* + ID_PRODUCT_FROM_DATABASE=MA-620 Infrared Adapter + +usb:v0DF7p0700* + ID_PRODUCT_FROM_DATABASE=MA-700 Bluetooth Adapter + +usb:v0DF7p0720* + ID_PRODUCT_FROM_DATABASE=MA-720 Bluetooth Adapter + +usb:v0DF7p0722* + ID_PRODUCT_FROM_DATABASE=Bluetooth Dongle + +usb:v0DF7p0730* + ID_PRODUCT_FROM_DATABASE=MA-730/MA-730G Bluetooth Adapter + +usb:v0DF7p0800* + ID_PRODUCT_FROM_DATABASE=Data Cable + +usb:v0DF7p0820* + ID_PRODUCT_FROM_DATABASE=Data Cable + +usb:v0DF7p0900* + ID_PRODUCT_FROM_DATABASE=MA i-gotU Travel Logger GPS + +usb:v0DF7p1800* + ID_PRODUCT_FROM_DATABASE=Generic Card Reader + +usb:v0DF7p1802* + ID_PRODUCT_FROM_DATABASE=Card Reader + +usb:v0DFA* + ID_VENDOR_FROM_DATABASE=Toyo Communication Equipment Co., Ltd + +usb:v0DFC* + ID_VENDOR_FROM_DATABASE=GeneralTouch Technology Co., Ltd + +usb:v0DFCp0001* + ID_PRODUCT_FROM_DATABASE=Touchscreen + +usb:v0E03* + ID_VENDOR_FROM_DATABASE=Nippon Systemware Co., Ltd + +usb:v0E08* + ID_VENDOR_FROM_DATABASE=Winbest Technology Co., Ltd + +usb:v0E0B* + ID_VENDOR_FROM_DATABASE=Amigo Technology Inc. + +usb:v0E0Bp9031* + ID_PRODUCT_FROM_DATABASE=802.11n Wireless USB Card + +usb:v0E0Bp9041* + ID_PRODUCT_FROM_DATABASE=802.11n Wireless USB Card + +usb:v0E0C* + ID_VENDOR_FROM_DATABASE=Gesytec + +usb:v0E0Cp0101* + ID_PRODUCT_FROM_DATABASE=LonUSB LonTalk Network Adapter + +usb:v0E0F* + ID_VENDOR_FROM_DATABASE=VMware, Inc. + +usb:v0E0Fp0001* + ID_PRODUCT_FROM_DATABASE=Device + +usb:v0E0Fp0002* + ID_PRODUCT_FROM_DATABASE=Virtual USB Hub + +usb:v0E0Fp0003* + ID_PRODUCT_FROM_DATABASE=Virtual Mouse + +usb:v0E0Fp0004* + ID_PRODUCT_FROM_DATABASE=Virtual CCID + +usb:v0E0Fp0005* + ID_PRODUCT_FROM_DATABASE=Virtual Mass Storage + +usb:v0E0Fp0006* + ID_PRODUCT_FROM_DATABASE=Virtual Keyboard + +usb:v0E0FpF80A* + ID_PRODUCT_FROM_DATABASE=Smoker FX2 + +usb:v0E16* + ID_VENDOR_FROM_DATABASE=JMTek, LLC + +usb:v0E17* + ID_VENDOR_FROM_DATABASE=Walex Electronic, Ltd + +usb:v0E1A* + ID_VENDOR_FROM_DATABASE=Unisys + +usb:v0E1B* + ID_VENDOR_FROM_DATABASE=Crewave + +usb:v0E20* + ID_VENDOR_FROM_DATABASE=Pegasus Technologies Ltd. + +usb:v0E20p0101* + ID_PRODUCT_FROM_DATABASE=NoteTaker + +usb:v0E21* + ID_VENDOR_FROM_DATABASE=Cowon Systems, Inc. + +usb:v0E21p0300* + ID_PRODUCT_FROM_DATABASE=iAudio CW200 + +usb:v0E21p0400* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v0E21p0500* + ID_PRODUCT_FROM_DATABASE=iAudio M3 + +usb:v0E21p0510* + ID_PRODUCT_FROM_DATABASE=iAudio X5, subpack USB port + +usb:v0E21p0513* + ID_PRODUCT_FROM_DATABASE=iAudio X5, side USB port + +usb:v0E21p0520* + ID_PRODUCT_FROM_DATABASE=iAudio M5, side USB port + +usb:v0E21p0601* + ID_PRODUCT_FROM_DATABASE=iAudio G3 + +usb:v0E21p0681* + ID_PRODUCT_FROM_DATABASE=iAUDIO E2 + +usb:v0E21p0700* + ID_PRODUCT_FROM_DATABASE=iAudio U3 + +usb:v0E21p0751* + ID_PRODUCT_FROM_DATABASE=iAudio 7 + +usb:v0E21p0760* + ID_PRODUCT_FROM_DATABASE=iAUDIO U5 / iAUDIO G2 + +usb:v0E21p0800* + ID_PRODUCT_FROM_DATABASE=Cowon D2 (UMS mode) + +usb:v0E21p0801* + ID_PRODUCT_FROM_DATABASE=Cowon D2 (MTP mode) + +usb:v0E21p0910* + ID_PRODUCT_FROM_DATABASE=iAUDIO 9 + +usb:v0E21p0920* + ID_PRODUCT_FROM_DATABASE=J3 + +usb:v0E22* + ID_VENDOR_FROM_DATABASE=Symbian Ltd. + +usb:v0E23* + ID_VENDOR_FROM_DATABASE=Liou Yuane Enterprise Co., Ltd + +usb:v0E25* + ID_VENDOR_FROM_DATABASE=VinChip Systems, Inc. + +usb:v0E26* + ID_VENDOR_FROM_DATABASE=J-Phone East Co., Ltd + +usb:v0E30* + ID_VENDOR_FROM_DATABASE=HeartMath LLC + +usb:v0E34* + ID_VENDOR_FROM_DATABASE=Micro Computer Control Corp. + +usb:v0E35* + ID_VENDOR_FROM_DATABASE=3Pea Technologies, Inc. + +usb:v0E36* + ID_VENDOR_FROM_DATABASE=TiePie engineering + +usb:v0E36p0008* + ID_PRODUCT_FROM_DATABASE=Handyscope HS3 + +usb:v0E36p0009* + ID_PRODUCT_FROM_DATABASE=Handyscope HS3 (br) + +usb:v0E36p000A* + ID_PRODUCT_FROM_DATABASE=Handyscope HS4 + +usb:v0E36p000B* + ID_PRODUCT_FROM_DATABASE=Handyscope HS4 (br) + +usb:v0E36p000E* + ID_PRODUCT_FROM_DATABASE=Handyscope HS4-DIFF + +usb:v0E36p000F* + ID_PRODUCT_FROM_DATABASE=Handyscope HS4-DIFF (br) + +usb:v0E36p0010* + ID_PRODUCT_FROM_DATABASE=Handyscope HS2 + +usb:v0E36p0011* + ID_PRODUCT_FROM_DATABASE=TiePieSCOPE HS805 (br) + +usb:v0E36p0012* + ID_PRODUCT_FROM_DATABASE=TiePieSCOPE HS805 + +usb:v0E36p0013* + ID_PRODUCT_FROM_DATABASE=Handyprobe HP3 + +usb:v0E36p0014* + ID_PRODUCT_FROM_DATABASE=Handyprobe HP3 + +usb:v0E36p0018* + ID_PRODUCT_FROM_DATABASE=Handyprobe HP2 + +usb:v0E36p001B* + ID_PRODUCT_FROM_DATABASE=Handyscope HS5 + +usb:v0E36p0042* + ID_PRODUCT_FROM_DATABASE=TiePieSCOPE HS801 + +usb:v0E36p00FD* + ID_PRODUCT_FROM_DATABASE=USB To Parallel adapter + +usb:v0E36p00FE* + ID_PRODUCT_FROM_DATABASE=USB To Parallel adapter + +usb:v0E38* + ID_VENDOR_FROM_DATABASE=Stratitec, Inc. + +usb:v0E39* + ID_VENDOR_FROM_DATABASE=Smart Modular Technologies, Inc. + +usb:v0E39p0137* + ID_PRODUCT_FROM_DATABASE=Bluetooth Device + +usb:v0E3A* + ID_VENDOR_FROM_DATABASE=Neostar Technology Co., Ltd + +usb:v0E3Ap1100* + ID_PRODUCT_FROM_DATABASE=CW-1100 Wireless Network Adapter + +usb:v0E3B* + ID_VENDOR_FROM_DATABASE=Mansella, Ltd + +usb:v0E41* + ID_VENDOR_FROM_DATABASE=Line6, Inc. + +usb:v0E41p4147* + ID_PRODUCT_FROM_DATABASE=TonePort GX + +usb:v0E41p4156* + ID_PRODUCT_FROM_DATABASE=POD HD Desktop + +usb:v0E41p4250* + ID_PRODUCT_FROM_DATABASE=BassPODxt + +usb:v0E41p4252* + ID_PRODUCT_FROM_DATABASE=BassPODxt Pro + +usb:v0E41p4642* + ID_PRODUCT_FROM_DATABASE=BassPODxt Live + +usb:v0E41p4650* + ID_PRODUCT_FROM_DATABASE=PODxt Live + +usb:v0E41p4750* + ID_PRODUCT_FROM_DATABASE=GuitarPort + +usb:v0E41p5044* + ID_PRODUCT_FROM_DATABASE=PODxt + +usb:v0E41p5050* + ID_PRODUCT_FROM_DATABASE=PODxt Pro + +usb:v0E41p534D* + ID_PRODUCT_FROM_DATABASE=SeaMonkey + +usb:v0E44* + ID_VENDOR_FROM_DATABASE=Sun-Riseful Technology Co., Ltd. + +usb:v0E48* + ID_VENDOR_FROM_DATABASE=Julia Corp., Ltd + +usb:v0E48p0100* + ID_PRODUCT_FROM_DATABASE=CardPro SmartCard Reader + +usb:v0E4A* + ID_VENDOR_FROM_DATABASE=Shenzhen Bao Hing Electric Wire & Cable Mfr. Co. + +usb:v0E4C* + ID_VENDOR_FROM_DATABASE=Radica Games, Ltd + +usb:v0E4Cp1097* + ID_PRODUCT_FROM_DATABASE=Gamester Controller + +usb:v0E4Cp2390* + ID_PRODUCT_FROM_DATABASE=Games Jtech Controller + +usb:v0E4Cp7288* + ID_PRODUCT_FROM_DATABASE=funkey reader + +usb:v0E50* + ID_VENDOR_FROM_DATABASE=TechnoData Interware + +usb:v0E50p0002* + ID_PRODUCT_FROM_DATABASE=Matrixlock Dongle (HID) + +usb:v0E55* + ID_VENDOR_FROM_DATABASE=Speed Dragon Multimedia, Ltd + +usb:v0E55p110A* + ID_PRODUCT_FROM_DATABASE=Tanic S110-SG1 + ISSC IS1002N [Slow Infra-Red (SIR) & Bluetooth 1.2 (Class 2) Adapter] + +usb:v0E55p110B* + ID_PRODUCT_FROM_DATABASE=MS3303H USB-to-Serial Bridge + +usb:v0E56* + ID_VENDOR_FROM_DATABASE=Kingston Technology Company, Inc. + +usb:v0E56p6021* + ID_PRODUCT_FROM_DATABASE=K-PEX 100 + +usb:v0E5A* + ID_VENDOR_FROM_DATABASE=Active Co., Ltd + +usb:v0E5B* + ID_VENDOR_FROM_DATABASE=Union Power Information Industrial Co., Ltd + +usb:v0E5C* + ID_VENDOR_FROM_DATABASE=Bitland Information Technology Co., Ltd + +usb:v0E5Cp6118* + ID_PRODUCT_FROM_DATABASE=LCD Device + +usb:v0E5Cp6119* + ID_PRODUCT_FROM_DATABASE=remote receive and control device + +usb:v0E5Cp6441* + ID_PRODUCT_FROM_DATABASE=C-Media Sound Device + +usb:v0E5D* + ID_VENDOR_FROM_DATABASE=Neltron Industrial Co., Ltd + +usb:v0E5E* + ID_VENDOR_FROM_DATABASE=Conwise Technology Co., Ltd. + +usb:v0E5Ep6622* + ID_PRODUCT_FROM_DATABASE=CW6622 + +usb:v0E66* + ID_VENDOR_FROM_DATABASE=Hawking Technologies + +usb:v0E66p0001* + ID_PRODUCT_FROM_DATABASE=HWUN1 Hi-Gain Wireless-300N Adapter w/ Upgradable Antenna [Ralink RT2870] + +usb:v0E66p0003* + ID_PRODUCT_FROM_DATABASE=HWDN1 Hi-Gain Wireless-300N Dish Adapter [Ralink RT2870] + +usb:v0E66p0009* + ID_PRODUCT_FROM_DATABASE=HWUN2 Hi-Gain Wireless-150N Adapter w/ Upgradable Antenna [Ralink RT2770] + +usb:v0E66p000B* + ID_PRODUCT_FROM_DATABASE=HWDN2 Hi-Gain Wireless-150N Dish Adapter [Ralink RT2770] + +usb:v0E66p0013* + ID_PRODUCT_FROM_DATABASE=HWUN3 Hi-Gain Wireless-N Adapter [Ralink RT3070] + +usb:v0E66p0015* + ID_PRODUCT_FROM_DATABASE=HWDN2 Rev. E Hi-Gain Wireless-150N Dish Adapter [Realtek RTL8191SU] + +usb:v0E66p0017* + ID_PRODUCT_FROM_DATABASE=HAWNU1 Hi-Gain Wireless-150N Network Adapter with Range Amplifier [Ralink RT3070] + +usb:v0E66p0018* + ID_PRODUCT_FROM_DATABASE=Wireless-N Network Adapter [Ralink RT2870] + +usb:v0E66p400B* + ID_PRODUCT_FROM_DATABASE=UF100 10/100 Network Adapter + +usb:v0E66p400C* + ID_PRODUCT_FROM_DATABASE=UF100 Ethernet [pegasus2] + +usb:v0E67* + ID_VENDOR_FROM_DATABASE=Fossil, Inc. + +usb:v0E67p0002* + ID_PRODUCT_FROM_DATABASE=Wrist PDA + +usb:v0E6A* + ID_VENDOR_FROM_DATABASE=Megawin Technology Co., Ltd + +usb:v0E6Ap0101* + ID_PRODUCT_FROM_DATABASE=MA100 [USB-UART Bridge IC] + +usb:v0E6Ap6001* + ID_PRODUCT_FROM_DATABASE=GEMBIRD Flexible keyboard KB-109F-B-DE + +usb:v0E6F* + ID_VENDOR_FROM_DATABASE=Logic3 + +usb:v0E6Fp0003* + ID_PRODUCT_FROM_DATABASE=Freebird wireless Controller + +usb:v0E6Fp0005* + ID_PRODUCT_FROM_DATABASE=Eclipse wireless Controller + +usb:v0E6Fp0006* + ID_PRODUCT_FROM_DATABASE=Edge wireless Controller + +usb:v0E70* + ID_VENDOR_FROM_DATABASE=Tokyo Electronic Industry Co., Ltd + +usb:v0E72* + ID_VENDOR_FROM_DATABASE=Hsi-Chin Electronics Co., Ltd + +usb:v0E75* + ID_VENDOR_FROM_DATABASE=TVS Electronics, Ltd + +usb:v0E79* + ID_VENDOR_FROM_DATABASE=Archos, Inc. + +usb:v0E79p1106* + ID_PRODUCT_FROM_DATABASE=Pocket Media Assistant - PMA400 + +usb:v0E79p1204* + ID_PRODUCT_FROM_DATABASE=Gmini XS 200 + +usb:v0E79p1306* + ID_PRODUCT_FROM_DATABASE=504 Portable Multimedia Player + +usb:v0E79p1330* + ID_PRODUCT_FROM_DATABASE=5 Tablet + +usb:v0E79p1332* + ID_PRODUCT_FROM_DATABASE=5 IMT + +usb:v0E79p1416* + ID_PRODUCT_FROM_DATABASE=32 IT + +usb:v0E79p1417* + ID_PRODUCT_FROM_DATABASE=A43 IT + +usb:v0E7B* + ID_VENDOR_FROM_DATABASE=On-Tech Industry Co., Ltd + +usb:v0E7E* + ID_VENDOR_FROM_DATABASE=Gmate, Inc. + +usb:v0E7Ep0001* + ID_PRODUCT_FROM_DATABASE=Yopy 3000 PDA + +usb:v0E7Ep1001* + ID_PRODUCT_FROM_DATABASE=YP3X00 PDA + +usb:v0E82* + ID_VENDOR_FROM_DATABASE=Ching Tai Electric Wire & Cable Co., Ltd + +usb:v0E83* + ID_VENDOR_FROM_DATABASE=Shin An Wire & Cable Co. + +usb:v0E8C* + ID_VENDOR_FROM_DATABASE=Well Force Electronic Co., Ltd + +usb:v0E8D* + ID_VENDOR_FROM_DATABASE=MediaTek Inc. + +usb:v0E8Dp0003* + ID_PRODUCT_FROM_DATABASE=MT6227 phone + +usb:v0E8Dp0004* + ID_PRODUCT_FROM_DATABASE=MT6227 phone + +usb:v0E8Dp1806* + ID_PRODUCT_FROM_DATABASE=Samsung SE-208AB Slim Portable DVD Writer + +usb:v0E8Dp1836* + ID_PRODUCT_FROM_DATABASE=Samsung SE-S084 Super WriteMaster Slim External DVD writer + +usb:v0E8F* + ID_VENDOR_FROM_DATABASE=GreenAsia Inc. + +usb:v0E8Fp0003* + ID_PRODUCT_FROM_DATABASE=MaxFire Blaze2 + +usb:v0E8Fp0012* + ID_PRODUCT_FROM_DATABASE=USB Wireless 2.4GHz Gamepad + +usb:v0E8Fp0016* + ID_PRODUCT_FROM_DATABASE=4 port USB 1.1 hub UH-174 + +usb:v0E8Fp0020* + ID_PRODUCT_FROM_DATABASE=USB to PS/2 Adapter + +usb:v0E8Fp0021* + ID_PRODUCT_FROM_DATABASE=Multimedia Keyboard Controller + +usb:v0E8Fp0201* + ID_PRODUCT_FROM_DATABASE=SmartJoy Frag Xpad/PS2 adaptor + +usb:v0E90* + ID_VENDOR_FROM_DATABASE=WiebeTech, LLC + +usb:v0E90p0100* + ID_PRODUCT_FROM_DATABASE=Storage Adapter V1 + +usb:v0E91* + ID_VENDOR_FROM_DATABASE=VTech Engineering Canada, Ltd + +usb:v0E92* + ID_VENDOR_FROM_DATABASE=C's Glory Enterprise Co., Ltd + +usb:v0E93* + ID_VENDOR_FROM_DATABASE=eM Technics Co., Ltd + +usb:v0E95* + ID_VENDOR_FROM_DATABASE=Future Technology Co., Ltd + +usb:v0E96* + ID_VENDOR_FROM_DATABASE=Aplux Communications, Ltd + +usb:v0E96pC001* + ID_PRODUCT_FROM_DATABASE=TRUST 380 USB2 SPACEC@M + +usb:v0E97* + ID_VENDOR_FROM_DATABASE=Fingerworks, Inc. + +usb:v0E97p0908* + ID_PRODUCT_FROM_DATABASE=Composite HID (Keyboard and Mouse) + +usb:v0E98* + ID_VENDOR_FROM_DATABASE=Advanced Analogic Technologies, Inc. + +usb:v0E99* + ID_VENDOR_FROM_DATABASE=Parallel Dice Co., Ltd + +usb:v0E9A* + ID_VENDOR_FROM_DATABASE=TA HSING Industries, Ltd + +usb:v0E9B* + ID_VENDOR_FROM_DATABASE=ADTEC Corp. + +usb:v0E9C* + ID_VENDOR_FROM_DATABASE=Streamzap, Inc. + +usb:v0E9Cp0000* + ID_PRODUCT_FROM_DATABASE=Streamzap Remote Control + +usb:v0E9F* + ID_VENDOR_FROM_DATABASE=Tamura Corp. + +usb:v0EA0* + ID_VENDOR_FROM_DATABASE=Ours Technology, Inc. + +usb:v0EA0p2126* + ID_PRODUCT_FROM_DATABASE=7-in-1 Card Reader + +usb:v0EA0p2153* + ID_PRODUCT_FROM_DATABASE=SD Card Reader Key + +usb:v0EA0p2168* + ID_PRODUCT_FROM_DATABASE=Transcend JetFlash 2.0 / Astone USB Drive + +usb:v0EA0p6803* + ID_PRODUCT_FROM_DATABASE=OTI-6803 Flash Disk + +usb:v0EA0p6808* + ID_PRODUCT_FROM_DATABASE=OTI-6808 Flash Disk + +usb:v0EA0p6828* + ID_PRODUCT_FROM_DATABASE=OTI-6828 Flash Disk + +usb:v0EA0p6858* + ID_PRODUCT_FROM_DATABASE=OTi-6858 serial adapter + +usb:v0EA6* + ID_VENDOR_FROM_DATABASE=Nihon Computer Co., Ltd + +usb:v0EA7* + ID_VENDOR_FROM_DATABASE=MSL Enterprises Corp. + +usb:v0EA8* + ID_VENDOR_FROM_DATABASE=CenDyne, Inc. + +usb:v0EAD* + ID_VENDOR_FROM_DATABASE=Humax Co., Ltd + +usb:v0EB0* + ID_VENDOR_FROM_DATABASE=NovaTech + +usb:v0EB0p9020* + ID_PRODUCT_FROM_DATABASE=NovaTech NV-902W + +usb:v0EB0p9021* + ID_PRODUCT_FROM_DATABASE=RT2573 + +usb:v0EB1* + ID_VENDOR_FROM_DATABASE=WIS Technologies, Inc. + +usb:v0EB1p6666* + ID_PRODUCT_FROM_DATABASE=WinFast WalkieTV TV Loader + +usb:v0EB1p6668* + ID_PRODUCT_FROM_DATABASE=WinFast WalkieTV TV Loader + +usb:v0EB1p7007* + ID_PRODUCT_FROM_DATABASE=WinFast WalkieTV WDM Capture + +usb:v0EB2* + ID_VENDOR_FROM_DATABASE=Y-S Electronic Co., Ltd + +usb:v0EB3* + ID_VENDOR_FROM_DATABASE=Saint Technology Corp. + +usb:v0EB7* + ID_VENDOR_FROM_DATABASE=Endor AG + +usb:v0EBE* + ID_VENDOR_FROM_DATABASE=VWeb Corp. + +usb:v0EBF* + ID_VENDOR_FROM_DATABASE=Omega Technology of Taiwan, Inc. + +usb:v0EC0* + ID_VENDOR_FROM_DATABASE=LHI Technology (China) Co., Ltd + +usb:v0EC1* + ID_VENDOR_FROM_DATABASE=Abit Computer Corp. + +usb:v0EC2* + ID_VENDOR_FROM_DATABASE=Sweetray Industrial, Ltd + +usb:v0EC3* + ID_VENDOR_FROM_DATABASE=Axell Co., Ltd + +usb:v0EC4* + ID_VENDOR_FROM_DATABASE=Ballracing Developments, Ltd + +usb:v0EC5* + ID_VENDOR_FROM_DATABASE=GT Information System Co., Ltd + +usb:v0EC6* + ID_VENDOR_FROM_DATABASE=InnoVISION Multimedia, Ltd + +usb:v0EC7* + ID_VENDOR_FROM_DATABASE=Theta Link Corp. + +usb:v0EC7p1008* + ID_PRODUCT_FROM_DATABASE=So., Show 301 Digital Camera + +usb:v0ECD* + ID_VENDOR_FROM_DATABASE=Lite-On IT Corp. + +usb:v0ECDp1400* + ID_PRODUCT_FROM_DATABASE=CD\RW 40X + +usb:v0ECDpA100* + ID_PRODUCT_FROM_DATABASE=LDW-411SX DVD/CD Rewritable Drive + +usb:v0ECE* + ID_VENDOR_FROM_DATABASE=TaiSol Electronics Co., Ltd + +usb:v0ECF* + ID_VENDOR_FROM_DATABASE=Phogenix Imaging, LLC + +usb:v0ED1* + ID_VENDOR_FROM_DATABASE=WinMaxGroup + +usb:v0ED1p6660* + ID_PRODUCT_FROM_DATABASE=Flash Disk 64M-C + +usb:v0ED1p6680* + ID_PRODUCT_FROM_DATABASE=Flash Disk 64M-B + +usb:v0ED1p7634* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v0ED2* + ID_VENDOR_FROM_DATABASE=Kyoto Micro Computer Co., Ltd + +usb:v0ED3* + ID_VENDOR_FROM_DATABASE=Wing-Tech Enterprise Co., Ltd + +usb:v0ED5* + ID_VENDOR_FROM_DATABASE=Fiberbyte + +usb:v0ED5pE000* + ID_PRODUCT_FROM_DATABASE=USB-inSync Device + +usb:v0ED5pF000* + ID_PRODUCT_FROM_DATABASE=Fiberbyte USB-inSync Device + +usb:v0ED5pF201* + ID_PRODUCT_FROM_DATABASE=Fiberbyte USB-inSync DAQ-2500X + +usb:v0EDA* + ID_VENDOR_FROM_DATABASE=Noriake Itron Corp. + +usb:v0EDF* + ID_VENDOR_FROM_DATABASE=e-MDT Co., Ltd + +usb:v0EDFp2060* + ID_PRODUCT_FROM_DATABASE=FID irock! 100 Series + +usb:v0EE0* + ID_VENDOR_FROM_DATABASE=Shima Seiki Mfg., Ltd + +usb:v0EE1* + ID_VENDOR_FROM_DATABASE=Sarotech Co., Ltd + +usb:v0EE2* + ID_VENDOR_FROM_DATABASE=AMI Semiconductor, Inc. + +usb:v0EE3* + ID_VENDOR_FROM_DATABASE=ComTrue Technology Corp. + +usb:v0EE3p1000* + ID_PRODUCT_FROM_DATABASE=Image Tank 1.5 + +usb:v0EE4* + ID_VENDOR_FROM_DATABASE=Sunrich Technology, Ltd + +usb:v0EEE* + ID_VENDOR_FROM_DATABASE=Digital Stream Technology, Inc. + +usb:v0EEEp8810* + ID_PRODUCT_FROM_DATABASE=Mass Storage Drive + +usb:v0EEF* + ID_VENDOR_FROM_DATABASE=D-WAV Scientific Co., Ltd + +usb:v0EEFp0001* + ID_PRODUCT_FROM_DATABASE=eGalax TouchScreen + +usb:v0EEFp0002* + ID_PRODUCT_FROM_DATABASE=Touchscreen Controller(Professional) + +usb:v0EF0* + ID_VENDOR_FROM_DATABASE=Hitachi Cable, Ltd + +usb:v0EF1* + ID_VENDOR_FROM_DATABASE=Aichi Micro Intelligent Corp. + +usb:v0EF2* + ID_VENDOR_FROM_DATABASE=I/O Magic Corp. + +usb:v0EF3* + ID_VENDOR_FROM_DATABASE=Lynn Products, Inc. + +usb:v0EF4* + ID_VENDOR_FROM_DATABASE=DSI Datotech + +usb:v0EF5* + ID_VENDOR_FROM_DATABASE=PointChips + +usb:v0EF5p2202* + ID_PRODUCT_FROM_DATABASE=Flash Disk + +usb:v0EF5p2366* + ID_PRODUCT_FROM_DATABASE=Flash Disk + +usb:v0EF6* + ID_VENDOR_FROM_DATABASE=Yield Microelectronics Corp. + +usb:v0EF7* + ID_VENDOR_FROM_DATABASE=SM Tech Co., Ltd (Tulip) + +usb:v0EFD* + ID_VENDOR_FROM_DATABASE=Oasis Semiconductor + +usb:v0EFE* + ID_VENDOR_FROM_DATABASE=Wem Technology, Inc. + +usb:v0F03* + ID_VENDOR_FROM_DATABASE=Unitek UPS Systems + +usb:v0F03p0001* + ID_PRODUCT_FROM_DATABASE=Alpha 1200Sx + +usb:v0F06* + ID_VENDOR_FROM_DATABASE=Visual Frontier Enterprise Co., Ltd + +usb:v0F08* + ID_VENDOR_FROM_DATABASE=CSL Wire & Plug (Shen Zhen) Co. + +usb:v0F0C* + ID_VENDOR_FROM_DATABASE=CAS Corp. + +usb:v0F0D* + ID_VENDOR_FROM_DATABASE=Hori Co., Ltd + +usb:v0F0Dp0011* + ID_PRODUCT_FROM_DATABASE=Real Arcade Pro 3 + +usb:v0F0E* + ID_VENDOR_FROM_DATABASE=Energy Full Corp. + +usb:v0F11* + ID_VENDOR_FROM_DATABASE=LD Didactic GmbH + +usb:v0F11p1000* + ID_PRODUCT_FROM_DATABASE=CASSY-S + +usb:v0F11p1010* + ID_PRODUCT_FROM_DATABASE=Pocket-CASSY + +usb:v0F11p1020* + ID_PRODUCT_FROM_DATABASE=Mobile-CASSY + +usb:v0F11p1080* + ID_PRODUCT_FROM_DATABASE=Joule and Wattmeter + +usb:v0F11p1081* + ID_PRODUCT_FROM_DATABASE=Digital Multimeter P + +usb:v0F11p1090* + ID_PRODUCT_FROM_DATABASE=UMI P + +usb:v0F11p1100* + ID_PRODUCT_FROM_DATABASE=X-Ray Apparatus + +usb:v0F11p1101* + ID_PRODUCT_FROM_DATABASE=X-Ray Apparatus + +usb:v0F11p1200* + ID_PRODUCT_FROM_DATABASE=VideoCom + +usb:v0F11p2000* + ID_PRODUCT_FROM_DATABASE=COM3LAB + +usb:v0F11p2010* + ID_PRODUCT_FROM_DATABASE=Terminal Adapter + +usb:v0F11p2020* + ID_PRODUCT_FROM_DATABASE=Network Analyser + +usb:v0F11p2030* + ID_PRODUCT_FROM_DATABASE=Converter Control Unit + +usb:v0F11p2040* + ID_PRODUCT_FROM_DATABASE=Machine Test System + +usb:v0F12* + ID_VENDOR_FROM_DATABASE=Mars Engineering Corp. + +usb:v0F13* + ID_VENDOR_FROM_DATABASE=Acetek Technology Co., Ltd + +usb:v0F18* + ID_VENDOR_FROM_DATABASE=Finger Lakes Instrumentation + +usb:v0F18p0002* + ID_PRODUCT_FROM_DATABASE=CCD + +usb:v0F18p0006* + ID_PRODUCT_FROM_DATABASE=Focuser + +usb:v0F18p0007* + ID_PRODUCT_FROM_DATABASE=Filter Wheel + +usb:v0F18p000A* + ID_PRODUCT_FROM_DATABASE=ProLine CCD + +usb:v0F18p000B* + ID_PRODUCT_FROM_DATABASE=Color Filter Wheel 4 + +usb:v0F18p000C* + ID_PRODUCT_FROM_DATABASE=PDF2 + +usb:v0F18p000D* + ID_PRODUCT_FROM_DATABASE=Guider + +usb:v0F19* + ID_VENDOR_FROM_DATABASE=Oracom Co., Ltd + +usb:v0F1B* + ID_VENDOR_FROM_DATABASE=Onset Computer Corp. + +usb:v0F1C* + ID_VENDOR_FROM_DATABASE=Funai Electric Co., Ltd + +usb:v0F1D* + ID_VENDOR_FROM_DATABASE=Iwill Corp. + +usb:v0F21* + ID_VENDOR_FROM_DATABASE=IOI Technology Corp. + +usb:v0F22* + ID_VENDOR_FROM_DATABASE=Senior Industries, Inc. + +usb:v0F23* + ID_VENDOR_FROM_DATABASE=Leader Tech Manufacturer Co., Ltd + +usb:v0F24* + ID_VENDOR_FROM_DATABASE=Flex-P Industries, Snd., Bhd. + +usb:v0F2D* + ID_VENDOR_FROM_DATABASE=ViPower, Inc. + +usb:v0F2E* + ID_VENDOR_FROM_DATABASE=Geniality Maple Technology Co., Ltd + +usb:v0F2F* + ID_VENDOR_FROM_DATABASE=Priva Design Services + +usb:v0F30* + ID_VENDOR_FROM_DATABASE=Jess Technology Co., Ltd + +usb:v0F30p001C* + ID_PRODUCT_FROM_DATABASE=PS3 Guitar Controller Dongle + +usb:v0F30p0110* + ID_PRODUCT_FROM_DATABASE=Dual Analog Rumble Pad + +usb:v0F30p0111* + ID_PRODUCT_FROM_DATABASE=Colour Rumble Pad + +usb:v0F30p0208* + ID_PRODUCT_FROM_DATABASE=Xbox & PC Gamepad + +usb:v0F31* + ID_VENDOR_FROM_DATABASE=Chrysalis Development + +usb:v0F32* + ID_VENDOR_FROM_DATABASE=YFC-BonEagle Electric Co., Ltd + +usb:v0F37* + ID_VENDOR_FROM_DATABASE=Kokuyo Co., Ltd + +usb:v0F38* + ID_VENDOR_FROM_DATABASE=Nien-Yi Industrial Corp. + +usb:v0F3D* + ID_VENDOR_FROM_DATABASE=Airprime, Incorporated + +usb:v0F3Dp0112* + ID_PRODUCT_FROM_DATABASE=CDMA 1xEVDO PC Card, PC 5220 + +usb:v0F41* + ID_VENDOR_FROM_DATABASE=RDC Semiconductor Co., Ltd + +usb:v0F42* + ID_VENDOR_FROM_DATABASE=Nital Consulting Services, Inc. + +usb:v0F44* + ID_VENDOR_FROM_DATABASE=Polhemus + +usb:v0F44pEF11* + ID_PRODUCT_FROM_DATABASE=Patriot (firmware not loaded) + +usb:v0F44pEF12* + ID_PRODUCT_FROM_DATABASE=Patriot + +usb:v0F44pFF11* + ID_PRODUCT_FROM_DATABASE=Liberty (firmware not loaded) + +usb:v0F44pFF12* + ID_PRODUCT_FROM_DATABASE=Liberty + +usb:v0F4B* + ID_VENDOR_FROM_DATABASE=St. John Technology Co., Ltd + +usb:v0F4C* + ID_VENDOR_FROM_DATABASE=WorldWide Cable Opto Corp. + +usb:v0F4D* + ID_VENDOR_FROM_DATABASE=Microtune, Inc. + +usb:v0F4Dp1000* + ID_PRODUCT_FROM_DATABASE=Bluetooth Dongle + +usb:v0F4E* + ID_VENDOR_FROM_DATABASE=Freedom Scientific + +usb:v0F52* + ID_VENDOR_FROM_DATABASE=Wing Key Electrical Co., Ltd + +usb:v0F53* + ID_VENDOR_FROM_DATABASE=Dongguan White Horse Cable Factory, Ltd + +usb:v0F54* + ID_VENDOR_FROM_DATABASE=Kawai Musical Instruments Mfg. Co., Ltd + +usb:v0F55* + ID_VENDOR_FROM_DATABASE=AmbiCom, Inc. + +usb:v0F5C* + ID_VENDOR_FROM_DATABASE=Prairiecomm, Inc. + +usb:v0F5D* + ID_VENDOR_FROM_DATABASE=NewAge International, LLC + +usb:v0F5Dp9455* + ID_PRODUCT_FROM_DATABASE=Compact Drive + +usb:v0F5F* + ID_VENDOR_FROM_DATABASE=Key Technology Corp. + +usb:v0F60* + ID_VENDOR_FROM_DATABASE=NTK, Ltd + +usb:v0F61* + ID_VENDOR_FROM_DATABASE=Varian, Inc. + +usb:v0F62* + ID_VENDOR_FROM_DATABASE=Acrox Technologies Co., Ltd + +usb:v0F62p1001* + ID_PRODUCT_FROM_DATABASE=Targus Mini Trackball Optical Mouse + +usb:v0F63* + ID_VENDOR_FROM_DATABASE=LeapFrog Enterprises + +usb:v0F63p0010* + ID_PRODUCT_FROM_DATABASE=Leapster Explorer + +usb:v0F63p0500* + ID_PRODUCT_FROM_DATABASE=Fly Fusion + +usb:v0F63p0600* + ID_PRODUCT_FROM_DATABASE=Leap Port Turbo + +usb:v0F63p0700* + ID_PRODUCT_FROM_DATABASE=POGO + +usb:v0F63p0800* + ID_PRODUCT_FROM_DATABASE=Didj + +usb:v0F63p0900* + ID_PRODUCT_FROM_DATABASE=TAGSchool + +usb:v0F63p0A00* + ID_PRODUCT_FROM_DATABASE=Leapster 2 + +usb:v0F63p0B00* + ID_PRODUCT_FROM_DATABASE=Crammer + +usb:v0F63p0C00* + ID_PRODUCT_FROM_DATABASE=Tag Jr + +usb:v0F63p0D00* + ID_PRODUCT_FROM_DATABASE=My Pal Scout + +usb:v0F63p0E00* + ID_PRODUCT_FROM_DATABASE=Tag32 + +usb:v0F63p0F00* + ID_PRODUCT_FROM_DATABASE=Tag64 + +usb:v0F63p1000* + ID_PRODUCT_FROM_DATABASE=Kiwi16 + +usb:v0F63p1100* + ID_PRODUCT_FROM_DATABASE=Leapster L2x + +usb:v0F63p1111* + ID_PRODUCT_FROM_DATABASE=Fly Fusion + +usb:v0F63p1300* + ID_PRODUCT_FROM_DATABASE=Didj UK/France (Leapster Advance) + +usb:v0F68* + ID_VENDOR_FROM_DATABASE=Kobe Steel, Ltd + +usb:v0F69* + ID_VENDOR_FROM_DATABASE=Dionex Corp. + +usb:v0F6A* + ID_VENDOR_FROM_DATABASE=Vibren Technologies, Inc. + +usb:v0F6E* + ID_VENDOR_FROM_DATABASE=INTELLIGENT SYSTEMS + +usb:v0F6Ep0100* + ID_PRODUCT_FROM_DATABASE=GameBoy Color Emulator + +usb:v0F6Ep0201* + ID_PRODUCT_FROM_DATABASE=GameBoy Advance Flash Gang Writer + +usb:v0F6Ep0202* + ID_PRODUCT_FROM_DATABASE=GameBoy Advance Capture + +usb:v0F6Ep0300* + ID_PRODUCT_FROM_DATABASE=Gamecube DOL Viewer + +usb:v0F6Ep0400* + ID_PRODUCT_FROM_DATABASE=NDS Emulator + +usb:v0F6Ep0401* + ID_PRODUCT_FROM_DATABASE=NDS UIC + +usb:v0F6Ep0402* + ID_PRODUCT_FROM_DATABASE=NDS Writer + +usb:v0F6Ep0403* + ID_PRODUCT_FROM_DATABASE=NDS Capture + +usb:v0F6Ep0404* + ID_PRODUCT_FROM_DATABASE=NDS Emulator (Lite) + +usb:v0F73* + ID_VENDOR_FROM_DATABASE=DFI + +usb:v0F7C* + ID_VENDOR_FROM_DATABASE=DQ Technology, Inc. + +usb:v0F7D* + ID_VENDOR_FROM_DATABASE=NetBotz, Inc. + +usb:v0F7E* + ID_VENDOR_FROM_DATABASE=Fluke Corp. + +usb:v0F88* + ID_VENDOR_FROM_DATABASE=VTech Holdings, Ltd + +usb:v0F88p3012* + ID_PRODUCT_FROM_DATABASE=RT2570 + +usb:v0F88p3014* + ID_PRODUCT_FROM_DATABASE=ZD1211B + +usb:v0F8B* + ID_VENDOR_FROM_DATABASE=Yazaki Corp. + +usb:v0F8C* + ID_VENDOR_FROM_DATABASE=Young Generation International Corp. + +usb:v0F8D* + ID_VENDOR_FROM_DATABASE=Uniwill Computer Corp. + +usb:v0F8E* + ID_VENDOR_FROM_DATABASE=Kingnet Technology Co., Ltd + +usb:v0F8F* + ID_VENDOR_FROM_DATABASE=Soma Networks + +usb:v0F97* + ID_VENDOR_FROM_DATABASE=CviLux Corp. + +usb:v0F98* + ID_VENDOR_FROM_DATABASE=CyberBank Corp. + +usb:v0F9C* + ID_VENDOR_FROM_DATABASE=Hyun Won, Inc. + +usb:v0F9Cp0301* + ID_PRODUCT_FROM_DATABASE=M-Any Premium DAH-610 MP3/WMA Player + +usb:v0F9Cp0332* + ID_PRODUCT_FROM_DATABASE=mobiBLU DAH-1200 MP3/Ogg Player + +usb:v0F9E* + ID_VENDOR_FROM_DATABASE=Lucent Technologies + +usb:v0FA3* + ID_VENDOR_FROM_DATABASE=Starconn Electronic Co., Ltd + +usb:v0FA4* + ID_VENDOR_FROM_DATABASE=ATL Technology + +usb:v0FA5* + ID_VENDOR_FROM_DATABASE=Sotec Co., Ltd + +usb:v0FA7* + ID_VENDOR_FROM_DATABASE=Epox Computer Co., Ltd + +usb:v0FA8* + ID_VENDOR_FROM_DATABASE=Logic Controls, Inc. + +usb:v0FAF* + ID_VENDOR_FROM_DATABASE=Winpoint Electronic Corp. + +usb:v0FB0* + ID_VENDOR_FROM_DATABASE=Haurtian Wire & Cable Co., Ltd + +usb:v0FB1* + ID_VENDOR_FROM_DATABASE=Inclose Design, Inc. + +usb:v0FB2* + ID_VENDOR_FROM_DATABASE=Juan-Chern Industrial Co., Ltd + +usb:v0FB6* + ID_VENDOR_FROM_DATABASE=Heber Ltd + +usb:v0FB6p3FC3* + ID_PRODUCT_FROM_DATABASE=Firefly X10i I/O Board (with firmware) + +usb:v0FB6p3FC4* + ID_PRODUCT_FROM_DATABASE=Firefly X10i I/O Board (without firmware) + +usb:v0FB8* + ID_VENDOR_FROM_DATABASE=Wistron Corp. + +usb:v0FB8p0002* + ID_PRODUCT_FROM_DATABASE=eHome Infrared Receiver + +usb:v0FB9* + ID_VENDOR_FROM_DATABASE=AACom Corp. + +usb:v0FBA* + ID_VENDOR_FROM_DATABASE=San Shing Electronics Co., Ltd + +usb:v0FBB* + ID_VENDOR_FROM_DATABASE=Bitwise Systems, Inc. + +usb:v0FC1* + ID_VENDOR_FROM_DATABASE=Mitac Internatinal Corp. + +usb:v0FC2* + ID_VENDOR_FROM_DATABASE=Plug and Jack Industrial, Inc. + +usb:v0FC5* + ID_VENDOR_FROM_DATABASE=Delcom Engineering + +usb:v0FC5p1222* + ID_PRODUCT_FROM_DATABASE=I/O Development Board + +usb:v0FC6* + ID_VENDOR_FROM_DATABASE=Dataplus Supplies, Inc. + +usb:v0FCA* + ID_VENDOR_FROM_DATABASE=Research In Motion, Ltd. + +usb:v0FCAp0001* + ID_PRODUCT_FROM_DATABASE=Blackberry Handheld + +usb:v0FCAp0004* + ID_PRODUCT_FROM_DATABASE=Blackberry Handheld + +usb:v0FCAp0006* + ID_PRODUCT_FROM_DATABASE=Blackberry Pearl + +usb:v0FCAp0008* + ID_PRODUCT_FROM_DATABASE=Blackberry Pearl + +usb:v0FCAp8001* + ID_PRODUCT_FROM_DATABASE=Blackberry Handheld + +usb:v0FCAp8004* + ID_PRODUCT_FROM_DATABASE=Blackberry Handheld + +usb:v0FCAp8007* + ID_PRODUCT_FROM_DATABASE=Blackberry Handheld + +usb:v0FCAp8010* + ID_PRODUCT_FROM_DATABASE=Blackberry Playbook (Connect to Windows mode) + +usb:v0FCAp8011* + ID_PRODUCT_FROM_DATABASE=Blackberry Playbook (Connect to Mac mode) + +usb:v0FCAp8020* + ID_PRODUCT_FROM_DATABASE=Blackberry Playbook (CD-Rom mode) + +usb:v0FCE* + ID_VENDOR_FROM_DATABASE=Sony Ericsson Mobile Communications AB + +usb:v0FCEp0076* + ID_PRODUCT_FROM_DATABASE=W910i (Multimedia mode) + +usb:v0FCEp00AF* + ID_PRODUCT_FROM_DATABASE=V640i Phone [PTP Camera] + +usb:v0FCEp00D4* + ID_PRODUCT_FROM_DATABASE=C902 [MTP] + +usb:v0FCEp00D9* + ID_PRODUCT_FROM_DATABASE=C702 Phone + +usb:v0FCEp0112* + ID_PRODUCT_FROM_DATABASE=W995 Walkman Phone + +usb:v0FCEp0166* + ID_PRODUCT_FROM_DATABASE=Xperia Mini Pro + +usb:v0FCEp0169* + ID_PRODUCT_FROM_DATABASE=Xperia S + +usb:v0FCEp0172* + ID_PRODUCT_FROM_DATABASE=Xperia P + +usb:v0FCEp1010* + ID_PRODUCT_FROM_DATABASE=WMC Modem + +usb:v0FCEp10AF* + ID_PRODUCT_FROM_DATABASE=V640i Phone [PictBridge] + +usb:v0FCEp10D4* + ID_PRODUCT_FROM_DATABASE=C902 Phone [PictBridge] + +usb:v0FCEp2105* + ID_PRODUCT_FROM_DATABASE=W715 Phone + +usb:v0FCEp2137* + ID_PRODUCT_FROM_DATABASE=Xperia X10 mini (USB debug) + +usb:v0FCEp2138* + ID_PRODUCT_FROM_DATABASE=Xperia X10 mini pro (Debug) + +usb:v0FCEp2149* + ID_PRODUCT_FROM_DATABASE=Xperia X8 (debug) + +usb:v0FCEp3137* + ID_PRODUCT_FROM_DATABASE=Xperia X10 mini + +usb:v0FCEp3138* + ID_PRODUCT_FROM_DATABASE=Xperia X10 mini pro + +usb:v0FCEp3149* + ID_PRODUCT_FROM_DATABASE=Xperia X8 + +usb:v0FCEp614F* + ID_PRODUCT_FROM_DATABASE=Xperia X12 (debug mode) + +usb:v0FCEp6166* + ID_PRODUCT_FROM_DATABASE=Xperia Mini Pro + +usb:v0FCEp8004* + ID_PRODUCT_FROM_DATABASE=9000 Phone [Mass Storage] + +usb:v0FCEpADDE* + ID_PRODUCT_FROM_DATABASE=Boot loader + +usb:v0FCEpD008* + ID_PRODUCT_FROM_DATABASE=V800-Vodafone 802SE Phone + +usb:v0FCEpD016* + ID_PRODUCT_FROM_DATABASE=K750i Phone + +usb:v0FCEpD017* + ID_PRODUCT_FROM_DATABASE=K608i Phone + +usb:v0FCEpD019* + ID_PRODUCT_FROM_DATABASE=VDC EGPRS Modem + +usb:v0FCEpD025* + ID_PRODUCT_FROM_DATABASE=520 WMC Data Modem + +usb:v0FCEpD028* + ID_PRODUCT_FROM_DATABASE=W800i + +usb:v0FCEpD038* + ID_PRODUCT_FROM_DATABASE=W850i Phone + +usb:v0FCEpD039* + ID_PRODUCT_FROM_DATABASE=K800i (phone mode) + +usb:v0FCEpD041* + ID_PRODUCT_FROM_DATABASE=K510i Phone + +usb:v0FCEpD042* + ID_PRODUCT_FROM_DATABASE=W810i Phone + +usb:v0FCEpD043* + ID_PRODUCT_FROM_DATABASE=V630i Phone + +usb:v0FCEpD046* + ID_PRODUCT_FROM_DATABASE=K610i Phone + +usb:v0FCEpD065* + ID_PRODUCT_FROM_DATABASE=W960i Phone (PC Suite) + +usb:v0FCEpD076* + ID_PRODUCT_FROM_DATABASE=W910i (Phone mode) + +usb:v0FCEpD089* + ID_PRODUCT_FROM_DATABASE=W580i Phone (mass storage) + +usb:v0FCEpD0A1* + ID_PRODUCT_FROM_DATABASE=K810 + +usb:v0FCEpD0AF* + ID_PRODUCT_FROM_DATABASE=V640i Phone + +usb:v0FCEpD0CF* + ID_PRODUCT_FROM_DATABASE=MD300 Mobile Broadband Modem + +usb:v0FCEpD0D4* + ID_PRODUCT_FROM_DATABASE=C902 Phone [Modem] + +usb:v0FCEpD0E1* + ID_PRODUCT_FROM_DATABASE=MD400 Mobile Broadband Modem + +usb:v0FCEpD12E* + ID_PRODUCT_FROM_DATABASE=Xperia X10 + +usb:v0FCEpE000* + ID_PRODUCT_FROM_DATABASE=K810 (PictBridge mode) + +usb:v0FCEpE039* + ID_PRODUCT_FROM_DATABASE=K800i (msc mode) + +usb:v0FCEpE042* + ID_PRODUCT_FROM_DATABASE=W810i Phone + +usb:v0FCEpE043* + ID_PRODUCT_FROM_DATABASE=V630i Phone [Mass Storage] + +usb:v0FCEpE075* + ID_PRODUCT_FROM_DATABASE=K850i + +usb:v0FCEpE076* + ID_PRODUCT_FROM_DATABASE=W910i (Mass storage) + +usb:v0FCEpE089* + ID_PRODUCT_FROM_DATABASE=W580i Phone + +usb:v0FCEpE090* + ID_PRODUCT_FROM_DATABASE=W200 Phone (Mass Storage) + +usb:v0FCEpE0A1* + ID_PRODUCT_FROM_DATABASE=K810 (Mass Storage mode) + +usb:v0FCEpE0A3* + ID_PRODUCT_FROM_DATABASE=W660i + +usb:v0FCEpE0AF* + ID_PRODUCT_FROM_DATABASE=V640i Phone [Mass Storage] + +usb:v0FCEpE0D4* + ID_PRODUCT_FROM_DATABASE=C902 Phone [Mass Storage] + +usb:v0FCEpE0EF* + ID_PRODUCT_FROM_DATABASE=C905 Phone [Mass Storage] + +usb:v0FCEpE0F3* + ID_PRODUCT_FROM_DATABASE=W595 + +usb:v0FCEpE105* + ID_PRODUCT_FROM_DATABASE=W705 + +usb:v0FCEpE112* + ID_PRODUCT_FROM_DATABASE=W995 Phone (Mass Storage) + +usb:v0FCEpE12E* + ID_PRODUCT_FROM_DATABASE=X10i Phone + +usb:v0FCEpE133* + ID_PRODUCT_FROM_DATABASE=Vivaz + +usb:v0FCEpE14F* + ID_PRODUCT_FROM_DATABASE=Xperia Arc/X12 + +usb:v0FCEpE161* + ID_PRODUCT_FROM_DATABASE=Xperia Ray + +usb:v0FCEpE166* + ID_PRODUCT_FROM_DATABASE=Xperia Mini Pro + +usb:v0FCEpE167* + ID_PRODUCT_FROM_DATABASE=XPERIA mini + +usb:v0FCF* + ID_VENDOR_FROM_DATABASE=Dynastream Innovations, Inc. + +usb:v0FCFp1003* + ID_PRODUCT_FROM_DATABASE=ANT Development Board + +usb:v0FCFp1004* + ID_PRODUCT_FROM_DATABASE=ANT2USB + +usb:v0FCFp1006* + ID_PRODUCT_FROM_DATABASE=ANT Development Board + +usb:v0FCFp1008* + ID_PRODUCT_FROM_DATABASE=Mini stick Suunto + +usb:v0FD0* + ID_VENDOR_FROM_DATABASE=Tulip Computers B.V. + +usb:v0FD1* + ID_VENDOR_FROM_DATABASE=Giant Electronics Ltd. + +usb:v0FD4* + ID_VENDOR_FROM_DATABASE=Tenovis GmbH & Co., KG + +usb:v0FD5* + ID_VENDOR_FROM_DATABASE=Direct Access Technology, Inc. + +usb:v0FD9* + ID_VENDOR_FROM_DATABASE=Elgato Systems GmbH + +usb:v0FD9p0011* + ID_PRODUCT_FROM_DATABASE=EyeTV Diversity + +usb:v0FD9p0018* + ID_PRODUCT_FROM_DATABASE=EyeTV Hybrid + +usb:v0FD9p0020* + ID_PRODUCT_FROM_DATABASE=EyeTV DTT Deluxe + +usb:v0FD9p0021* + ID_PRODUCT_FROM_DATABASE=EyeTV DTT + +usb:v0FD9p002A* + ID_PRODUCT_FROM_DATABASE=EyeTV Sat + +usb:v0FD9p002C* + ID_PRODUCT_FROM_DATABASE=EyeTV DTT Deluxe v2 + +usb:v0FD9p0033* + ID_PRODUCT_FROM_DATABASE=Video Capture + +usb:v0FD9p0037* + ID_PRODUCT_FROM_DATABASE=Video Capture v2 + +usb:v0FDC* + ID_VENDOR_FROM_DATABASE=Micro Plus + +usb:v0FE0* + ID_VENDOR_FROM_DATABASE=Osterhout Design Group + +usb:v0FE0p0100* + ID_PRODUCT_FROM_DATABASE=Bluetooth Mouse + +usb:v0FE0p0101* + ID_PRODUCT_FROM_DATABASE=Bluetooth IMU + +usb:v0FE0p0200* + ID_PRODUCT_FROM_DATABASE=Bluetooth Keypad + +usb:v0FE4* + ID_VENDOR_FROM_DATABASE=IN-Tech Electronics, Ltd + +usb:v0FE5* + ID_VENDOR_FROM_DATABASE=Greenconn (U.S.A.), Inc. + +usb:v0FE6* + ID_VENDOR_FROM_DATABASE=Kontron (Industrial Computer Source / ICS Advent) + +usb:v0FE6p8101* + ID_PRODUCT_FROM_DATABASE=DM9601 Fast Ethernet Adapter + +usb:v0FE6p811E* + ID_PRODUCT_FROM_DATABASE=Parallel Adapter + +usb:v0FE6p9700* + ID_PRODUCT_FROM_DATABASE=DM9601 Fast Ethernet Adapter + +usb:v0FE9* + ID_VENDOR_FROM_DATABASE=DVICO + +usb:v0FE9p4020* + ID_PRODUCT_FROM_DATABASE=TViX M-6500 + +usb:v0FE9pDB00* + ID_PRODUCT_FROM_DATABASE=FusionHDTV DVB-T (MT352+LgZ201) (uninitialized) + +usb:v0FE9pDB01* + ID_PRODUCT_FROM_DATABASE=FusionHDTV DVB-T (MT352+LgZ201) (initialized) + +usb:v0FE9pDB10* + ID_PRODUCT_FROM_DATABASE=FusionHDTV DVB-T (MT352+Thomson7579) (uninitialized) + +usb:v0FE9pDB11* + ID_PRODUCT_FROM_DATABASE=FusionHDTV DVB-T (MT352+Thomson7579) (initialized) + +usb:v0FE9pDB78* + ID_PRODUCT_FROM_DATABASE=FusionHDTV DVB-T Dual Digital 4 (ZL10353+xc2028/xc3028) (initialized) + +usb:v0FEA* + ID_VENDOR_FROM_DATABASE=United Computer Accessories + +usb:v0FEB* + ID_VENDOR_FROM_DATABASE=CRS Electronic Co., Ltd + +usb:v0FEC* + ID_VENDOR_FROM_DATABASE=UMC Electronics Co., Ltd + +usb:v0FED* + ID_VENDOR_FROM_DATABASE=Access Co., Ltd + +usb:v0FEE* + ID_VENDOR_FROM_DATABASE=Xsido Corp. + +usb:v0FEF* + ID_VENDOR_FROM_DATABASE=MJ Research, Inc. + +usb:v0FF6* + ID_VENDOR_FROM_DATABASE=Core Valley Co., Ltd + +usb:v0FF7* + ID_VENDOR_FROM_DATABASE=CHI SHING Computer Accessories Co., Ltd + +usb:v0FFC* + ID_VENDOR_FROM_DATABASE=Clavia DMI AB + +usb:v0FFCp0021* + ID_PRODUCT_FROM_DATABASE=Nord Stage 2 + +usb:v0FFF* + ID_VENDOR_FROM_DATABASE=Aopen, Inc. + +usb:v1000* + ID_VENDOR_FROM_DATABASE=Speed Tech Corp. + +usb:v1001* + ID_VENDOR_FROM_DATABASE=Ritronics Components (S) Pte., Ltd + +usb:v1003* + ID_VENDOR_FROM_DATABASE=Sigma Corp. + +usb:v1003p0003* + ID_PRODUCT_FROM_DATABASE=SD14 + +usb:v1003p0100* + ID_PRODUCT_FROM_DATABASE=SD9/SD10 + +usb:v1004* + ID_VENDOR_FROM_DATABASE=LG Electronics, Inc. + +usb:v1004p1FAE* + ID_PRODUCT_FROM_DATABASE=U8120 3G Cellphone + +usb:v1004p6000* + ID_PRODUCT_FROM_DATABASE=KU330/KU990/VX4400/VX6000 + +usb:v1004p6005* + ID_PRODUCT_FROM_DATABASE=T5100 + +usb:v1004p6018* + ID_PRODUCT_FROM_DATABASE=GM360/GD510/GW520/KP501 + +usb:v1004p618E* + ID_PRODUCT_FROM_DATABASE=Ally/Optimus One/Vortex (debug mode) + +usb:v1004p618F* + ID_PRODUCT_FROM_DATABASE=Ally/Optimus One + +usb:v1004p61C6* + ID_PRODUCT_FROM_DATABASE=Vortex (msc) + +usb:v1004p61CC* + ID_PRODUCT_FROM_DATABASE=Optimus S + +usb:v1004p61FC* + ID_PRODUCT_FROM_DATABASE=Optimus 3 + +usb:v1004p6800* + ID_PRODUCT_FROM_DATABASE=CDMA Modem + +usb:v1004p7000* + ID_PRODUCT_FROM_DATABASE=LG LDP-7024D(LD)USB + +usb:v1004pA400* + ID_PRODUCT_FROM_DATABASE=Renoir (KC910) + +usb:v1005* + ID_VENDOR_FROM_DATABASE=Apacer Technology, Inc. + +usb:v1005p1001* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v1005p1004* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v1005p1006* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v1005pB113* + ID_PRODUCT_FROM_DATABASE=Handy Steno 2.0/HT203 + +usb:v1005pB223* + ID_PRODUCT_FROM_DATABASE=CD-RW + 6in1 Card Reader Digital Storage / Converter + +usb:v1006* + ID_VENDOR_FROM_DATABASE=iRiver, Ltd. + +usb:v1006p3001* + ID_PRODUCT_FROM_DATABASE=iHP-100 + +usb:v1006p3002* + ID_PRODUCT_FROM_DATABASE=iHP-120/140 MP3 Player + +usb:v1006p3003* + ID_PRODUCT_FROM_DATABASE=H320/H340 + +usb:v1006p3004* + ID_PRODUCT_FROM_DATABASE=H340 (mtp) + +usb:v1009* + ID_VENDOR_FROM_DATABASE=Emuzed, Inc. + +usb:v1009p000E* + ID_PRODUCT_FROM_DATABASE=eHome Infrared Receiver + +usb:v1009p0013* + ID_PRODUCT_FROM_DATABASE=Angel MPEG Device + +usb:v1009p0015* + ID_PRODUCT_FROM_DATABASE=Lumanate Wave PAL SECAM DVBT Device + +usb:v1009p0016* + ID_PRODUCT_FROM_DATABASE=Lumanate Wave NTSC/ATSC Combo Device + +usb:v100A* + ID_VENDOR_FROM_DATABASE=AV Chaseway, Ltd + +usb:v100Ap2402* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v100Ap2404* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v100Ap2405* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v100Ap2406* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v100ApA0C0* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v100B* + ID_VENDOR_FROM_DATABASE=Chou Chin Industrial Co., Ltd + +usb:v100D* + ID_VENDOR_FROM_DATABASE=Netopia, Inc. + +usb:v100Dp3342* + ID_PRODUCT_FROM_DATABASE=Cayman 3352 DSL Modem + +usb:v100Dp3382* + ID_PRODUCT_FROM_DATABASE=3380 Series Network Interface + +usb:v100Dp6072* + ID_PRODUCT_FROM_DATABASE=DSL Modem + +usb:v100Dp9031* + ID_PRODUCT_FROM_DATABASE=Motorola 802.11n Dualband USB Wireless Adapter + +usb:v100Dp9032* + ID_PRODUCT_FROM_DATABASE=Motorola 802.11n 5G USB Wireless Adapter + +usb:v100DpCB01* + ID_PRODUCT_FROM_DATABASE=Cayman 3341 Ethernet DSL Router + +usb:v1010* + ID_VENDOR_FROM_DATABASE=Fukuda Denshi Co., Ltd + +usb:v1011* + ID_VENDOR_FROM_DATABASE=Mobile Media Tech. + +usb:v1011p0001* + ID_PRODUCT_FROM_DATABASE=AccFast Mp3 + +usb:v1012* + ID_VENDOR_FROM_DATABASE=SDKM Fibres, Wires & Cables Berhad + +usb:v1013* + ID_VENDOR_FROM_DATABASE=TST-Touchless Sensor Technology AG + +usb:v1014* + ID_VENDOR_FROM_DATABASE=Densitron Technologies PLC + +usb:v1015* + ID_VENDOR_FROM_DATABASE=Softronics Pty., Ltd + +usb:v1016* + ID_VENDOR_FROM_DATABASE=Xiamen Hung's Enterprise Co., Ltd + +usb:v1017* + ID_VENDOR_FROM_DATABASE=Speedy Industrial Supplies, Pte., Ltd + +usb:v1019* + ID_VENDOR_FROM_DATABASE=Elitegroup Computer Systems (ECS) + +usb:v1019p0C55* + ID_PRODUCT_FROM_DATABASE=Flash Reader, Desknote UCR-61S2B + +usb:v1019p0F38* + ID_PRODUCT_FROM_DATABASE=Infrared Receiver + +usb:v1020* + ID_VENDOR_FROM_DATABASE=Labtec + +usb:v1020p0006* + ID_PRODUCT_FROM_DATABASE=Wireless Keyboard + +usb:v1020p000A* + ID_PRODUCT_FROM_DATABASE=Wireless Optical Mouse + +usb:v1020p0106* + ID_PRODUCT_FROM_DATABASE=Wireless Optical Mouse + +usb:v1022* + ID_VENDOR_FROM_DATABASE=Shinko Shoji Co., Ltd + +usb:v1025* + ID_VENDOR_FROM_DATABASE=Hyper-Paltek + +usb:v1025p005E* + ID_PRODUCT_FROM_DATABASE=USB DVB-T device + +usb:v1025p005F* + ID_PRODUCT_FROM_DATABASE=USB DVB-T device + +usb:v1025p0300* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v1025p0350* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v1026* + ID_VENDOR_FROM_DATABASE=Newly Corp. + +usb:v1027* + ID_VENDOR_FROM_DATABASE=Time Domain + +usb:v1028* + ID_VENDOR_FROM_DATABASE=Inovys Corp. + +usb:v1029* + ID_VENDOR_FROM_DATABASE=Atlantic Coast Telesys + +usb:v102A* + ID_VENDOR_FROM_DATABASE=Ramos Technology Co., Ltd + +usb:v102B* + ID_VENDOR_FROM_DATABASE=Infotronic America, Inc. + +usb:v102C* + ID_VENDOR_FROM_DATABASE=Etoms Electronics Corp. + +usb:v102Cp6151* + ID_PRODUCT_FROM_DATABASE=Q-Cam Sangha CIF + +usb:v102Cp6251* + ID_PRODUCT_FROM_DATABASE=Q-Cam VGA + +usb:v102D* + ID_VENDOR_FROM_DATABASE=Winic Corp. + +usb:v1031* + ID_VENDOR_FROM_DATABASE=Comax Technology, Inc. + +usb:v1032* + ID_VENDOR_FROM_DATABASE=C-One Technology Corp. + +usb:v1033* + ID_VENDOR_FROM_DATABASE=Nucam Corp. + +usb:v1033p0068* + ID_PRODUCT_FROM_DATABASE=3,5'' HDD case MD-231 + +usb:v1038* + ID_VENDOR_FROM_DATABASE=Ideazon, Inc. + +usb:v1038p0100* + ID_PRODUCT_FROM_DATABASE=Zboard + +usb:v1039* + ID_VENDOR_FROM_DATABASE=devolo AG + +usb:v1039p0824* + ID_PRODUCT_FROM_DATABASE=1866 802.11bg [Texas Instruments TNETW1450] + +usb:v1039p2140* + ID_PRODUCT_FROM_DATABASE=dsl+ 1100 duo + +usb:v103D* + ID_VENDOR_FROM_DATABASE=Stanton + +usb:v103Dp0100* + ID_PRODUCT_FROM_DATABASE=ScratchAmp + +usb:v103Dp0101* + ID_PRODUCT_FROM_DATABASE=ScratchAmp + +usb:v1043* + ID_VENDOR_FROM_DATABASE=iCreate Technologies Corp. + +usb:v1043p160F* + ID_PRODUCT_FROM_DATABASE=Wireless Network Adapter + +usb:v1043p4901* + ID_PRODUCT_FROM_DATABASE=AV-836 Video Capture Device + +usb:v1043p8006* + ID_PRODUCT_FROM_DATABASE=Flash Disk 32-256 MB + +usb:v1043p8012* + ID_PRODUCT_FROM_DATABASE=Flash Disk 256 MB + +usb:v1044* + ID_VENDOR_FROM_DATABASE=Chu Yuen Enterprise Co., Ltd + +usb:v1044p7001* + ID_PRODUCT_FROM_DATABASE=Gigabyte U7000 DVB-T tuner + +usb:v1044p7002* + ID_PRODUCT_FROM_DATABASE=Gigabyte U8000 DVB-T tuner + +usb:v1044p7004* + ID_PRODUCT_FROM_DATABASE=Gigabyte U7100 DVB-T tuner + +usb:v1044p7005* + ID_PRODUCT_FROM_DATABASE=Gigabyte U7200 DVB-T tuner [AF9035] + +usb:v1044p7006* + ID_PRODUCT_FROM_DATABASE=Gigabyte U6000 DVB-T tuner [em2863] + +usb:v1044p8001* + ID_PRODUCT_FROM_DATABASE=GN-54G + +usb:v1044p8002* + ID_PRODUCT_FROM_DATABASE=GN-BR402W + +usb:v1044p8003* + ID_PRODUCT_FROM_DATABASE=GN-WLBM101 + +usb:v1044p8004* + ID_PRODUCT_FROM_DATABASE=GN-WLBZ101 802.11b Adapter + +usb:v1044p8005* + ID_PRODUCT_FROM_DATABASE=GN-WLBZ201 802.11b Adapter + +usb:v1044p8006* + ID_PRODUCT_FROM_DATABASE=GN-WBZB-M 802.11b Adapter + +usb:v1044p8007* + ID_PRODUCT_FROM_DATABASE=GN-WBKG + +usb:v1044p8008* + ID_PRODUCT_FROM_DATABASE=GN-WB01GS + +usb:v1044p800A* + ID_PRODUCT_FROM_DATABASE=GN-WI05GS + +usb:v1044p800B* + ID_PRODUCT_FROM_DATABASE=GN-WB30N 802.11n WLAN Card + +usb:v1044p800C* + ID_PRODUCT_FROM_DATABASE=GN-WB31N 802.11n USB WLAN Card + +usb:v1044p800D* + ID_PRODUCT_FROM_DATABASE=GN-WB32L 802.11n USB WLAN Card + +usb:v1046* + ID_VENDOR_FROM_DATABASE=Winbond Electronics Corp. [hex] + +usb:v1046p6694* + ID_PRODUCT_FROM_DATABASE=Generic W6694 USB + +usb:v1046p8901* + ID_PRODUCT_FROM_DATABASE=Bluetooth Device + +usb:v1046p9967* + ID_PRODUCT_FROM_DATABASE=W9967CF/W9968CF Webcam IC + +usb:v1048* + ID_VENDOR_FROM_DATABASE=Targus Group International + +usb:v104B* + ID_VENDOR_FROM_DATABASE=Mylex / Buslogic + +usb:v104C* + ID_VENDOR_FROM_DATABASE=AMCO TEC International, Inc. + +usb:v104D* + ID_VENDOR_FROM_DATABASE=Newport Corporation + +usb:v104Dp1003* + ID_PRODUCT_FROM_DATABASE=Model-52 LED Light Source Power Supply and Driver + +usb:v104F* + ID_VENDOR_FROM_DATABASE=WB Electronics + +usb:v104Fp0001* + ID_PRODUCT_FROM_DATABASE=Infinity Phoenix + +usb:v104Fp0002* + ID_PRODUCT_FROM_DATABASE=Smartmouse + +usb:v104Fp0003* + ID_PRODUCT_FROM_DATABASE=FunProgrammer + +usb:v104Fp0004* + ID_PRODUCT_FROM_DATABASE=Infinity Unlimited + +usb:v104Fp0006* + ID_PRODUCT_FROM_DATABASE=Infinity Smart + +usb:v104Fp0007* + ID_PRODUCT_FROM_DATABASE=Infinity Smart module + +usb:v104Fp0008* + ID_PRODUCT_FROM_DATABASE=Infinity CryptoKey + +usb:v104Fp0009* + ID_PRODUCT_FROM_DATABASE=RE-BL PlayStation 3 IR-to-Bluetooth converter + +usb:v1050* + ID_VENDOR_FROM_DATABASE=Yubico.com + +usb:v1050p0010* + ID_PRODUCT_FROM_DATABASE=Yubikey + +usb:v1053* + ID_VENDOR_FROM_DATABASE=Immanuel Electronics Co., Ltd + +usb:v1054* + ID_VENDOR_FROM_DATABASE=BMS International Beheer N.V. + +usb:v1054p5004* + ID_PRODUCT_FROM_DATABASE=DSL 7420 Loader + +usb:v1054p5005* + ID_PRODUCT_FROM_DATABASE=DSL 7420 LAN Modem + +usb:v1055* + ID_VENDOR_FROM_DATABASE=Complex Micro Interconnection Co., Ltd + +usb:v1056* + ID_VENDOR_FROM_DATABASE=Hsin Chen Ent Co., Ltd + +usb:v1057* + ID_VENDOR_FROM_DATABASE=ON Semiconductor + +usb:v1058* + ID_VENDOR_FROM_DATABASE=Western Digital Technologies, Inc. + +usb:v1058p0200* + ID_PRODUCT_FROM_DATABASE=Firewire USB Combo + +usb:v1058p0400* + ID_PRODUCT_FROM_DATABASE=External HDD + +usb:v1058p0500* + ID_PRODUCT_FROM_DATABASE=hub + +usb:v1058p0702* + ID_PRODUCT_FROM_DATABASE=Passport External HDD + +usb:v1058p0704* + ID_PRODUCT_FROM_DATABASE=Passport External HDD + +usb:v1058p070A* + ID_PRODUCT_FROM_DATABASE=My Passport Essential SE + +usb:v1058p071A* + ID_PRODUCT_FROM_DATABASE=My Passport 1TB + +usb:v1058p0740* + ID_PRODUCT_FROM_DATABASE=My Passport 1TB + +usb:v1058p0742* + ID_PRODUCT_FROM_DATABASE=My Passport Essential SE + +usb:v1058p0748* + ID_PRODUCT_FROM_DATABASE=My Passport 1TB USB 3.0 + +usb:v1058p0900* + ID_PRODUCT_FROM_DATABASE=MyBook Essential External HDD + +usb:v1058p0901* + ID_PRODUCT_FROM_DATABASE=MyBook External HDD + +usb:v1058p0903* + ID_PRODUCT_FROM_DATABASE=My Book Premium Edition + +usb:v1058p0910* + ID_PRODUCT_FROM_DATABASE=MyBook Essential External HDD + +usb:v1058p1001* + ID_PRODUCT_FROM_DATABASE=External Hard Disk [Elements] + +usb:v1058p1003* + ID_PRODUCT_FROM_DATABASE=Elements 1000 GB + +usb:v1058p1010* + ID_PRODUCT_FROM_DATABASE=Elements External HDD + +usb:v1058p1021* + ID_PRODUCT_FROM_DATABASE=Elements 2TB + +usb:v1058p1023* + ID_PRODUCT_FROM_DATABASE=Elements SE + +usb:v1058p1103* + ID_PRODUCT_FROM_DATABASE=My Book Studio + +usb:v1058p1104* + ID_PRODUCT_FROM_DATABASE=MyBook Mirror Edition External HDD + +usb:v1058p1105* + ID_PRODUCT_FROM_DATABASE=My Book Studio II + +usb:v1058p1123* + ID_PRODUCT_FROM_DATABASE=My Book 3.0 + +usb:v1058p1140* + ID_PRODUCT_FROM_DATABASE=My Book Essential USB3.0 + +usb:v1059* + ID_VENDOR_FROM_DATABASE=Giesecke & Devrient GmbH + +usb:v1059p000B* + ID_PRODUCT_FROM_DATABASE=StarSign Bio Token 3.0 + +usb:v105C* + ID_VENDOR_FROM_DATABASE=Hong Ji Electric Wire & Cable (Dongguan) Co., Ltd + +usb:v105D* + ID_VENDOR_FROM_DATABASE=Delkin Devices, Inc. + +usb:v105E* + ID_VENDOR_FROM_DATABASE=Valence Semiconductor Design, Ltd + +usb:v105F* + ID_VENDOR_FROM_DATABASE=Chin Shong Enterprise Co., Ltd + +usb:v1060* + ID_VENDOR_FROM_DATABASE=Easthome Industrial Co., Ltd + +usb:v1063* + ID_VENDOR_FROM_DATABASE=Motorola Electronics Taiwan, Ltd [hex] + +usb:v1063p1555* + ID_PRODUCT_FROM_DATABASE=MC141555 Hub + +usb:v1063p4100* + ID_PRODUCT_FROM_DATABASE=SB4100 USB Cable Modem + +usb:v1065* + ID_VENDOR_FROM_DATABASE=CCYU Technology + +usb:v1065p0020* + ID_PRODUCT_FROM_DATABASE=USB-DVR2 Dev Board + +usb:v1065p2136* + ID_PRODUCT_FROM_DATABASE=EasyDisk ED1064 + +usb:v106A* + ID_VENDOR_FROM_DATABASE=Loyal Legend, Ltd + +usb:v106C* + ID_VENDOR_FROM_DATABASE=Curitel Communications, Inc. + +usb:v106Cp1101* + ID_PRODUCT_FROM_DATABASE=CDMA 2000 1xRTT USB modem (HX-550C) + +usb:v106Cp1102* + ID_PRODUCT_FROM_DATABASE=Packet Service + +usb:v106Cp1103* + ID_PRODUCT_FROM_DATABASE=Packet Service Diagnostic Serial Port (WDM) + +usb:v106Cp1104* + ID_PRODUCT_FROM_DATABASE=Packet Service Diagnostic Serial Port (WDM) + +usb:v106Cp1105* + ID_PRODUCT_FROM_DATABASE=Composite Device + +usb:v106Cp1106* + ID_PRODUCT_FROM_DATABASE=Packet Service Diagnostic Serial Port (WDM) + +usb:v106Cp1301* + ID_PRODUCT_FROM_DATABASE=Composite Device + +usb:v106Cp1302* + ID_PRODUCT_FROM_DATABASE=Packet Service Diagnostic Serial Port (WDM) + +usb:v106Cp1303* + ID_PRODUCT_FROM_DATABASE=Packet Service + +usb:v106Cp1304* + ID_PRODUCT_FROM_DATABASE=Packet Service + +usb:v106Cp1401* + ID_PRODUCT_FROM_DATABASE=Composite Device + +usb:v106Cp1402* + ID_PRODUCT_FROM_DATABASE=Packet Service + +usb:v106Cp1403* + ID_PRODUCT_FROM_DATABASE=Packet Service Diagnostic Serial Port (WDM) + +usb:v106Cp1501* + ID_PRODUCT_FROM_DATABASE=Packet Service + +usb:v106Cp1502* + ID_PRODUCT_FROM_DATABASE=Packet Service Diagnostic Serial Port (WDM) + +usb:v106Cp1503* + ID_PRODUCT_FROM_DATABASE=Packet Service + +usb:v106Cp1601* + ID_PRODUCT_FROM_DATABASE=Packet Service + +usb:v106Cp1602* + ID_PRODUCT_FROM_DATABASE=Packet Service Diagnostic Serial Port (WDM) + +usb:v106Cp1603* + ID_PRODUCT_FROM_DATABASE=Packet Service + +usb:v106Cp2101* + ID_PRODUCT_FROM_DATABASE=AudioVox 8900 Cell Phone + +usb:v106Cp2102* + ID_PRODUCT_FROM_DATABASE=Packet Service + +usb:v106Cp2103* + ID_PRODUCT_FROM_DATABASE=Packet Service Diagnostic Serial Port (WDM) + +usb:v106Cp2301* + ID_PRODUCT_FROM_DATABASE=Packet Service + +usb:v106Cp2302* + ID_PRODUCT_FROM_DATABASE=Packet Service Diagnostic Serial Port (WDM) + +usb:v106Cp2303* + ID_PRODUCT_FROM_DATABASE=Packet Service + +usb:v106Cp2401* + ID_PRODUCT_FROM_DATABASE=Packet Service Diagnostic Serial Port (WDM) + +usb:v106Cp2402* + ID_PRODUCT_FROM_DATABASE=Packet Service + +usb:v106Cp2403* + ID_PRODUCT_FROM_DATABASE=Packet Service Diagnostic Serial Port (WDM) + +usb:v106Cp2501* + ID_PRODUCT_FROM_DATABASE=Packet Service + +usb:v106Cp2502* + ID_PRODUCT_FROM_DATABASE=Packet Service Diagnostic Serial Port (WDM) + +usb:v106Cp2503* + ID_PRODUCT_FROM_DATABASE=Packet Service + +usb:v106Cp2601* + ID_PRODUCT_FROM_DATABASE=Packet Service + +usb:v106Cp2602* + ID_PRODUCT_FROM_DATABASE=Packet Service Diagnostic Serial Port (WDM) + +usb:v106Cp2603* + ID_PRODUCT_FROM_DATABASE=Packet Service + +usb:v106Cp3701* + ID_PRODUCT_FROM_DATABASE=Broadband Wireless modem + +usb:v106Cp3702* + ID_PRODUCT_FROM_DATABASE=Pantech PX-500 + +usb:v106Cp3714* + ID_PRODUCT_FROM_DATABASE=PANTECH USB MODEM [UM175] + +usb:v106Cp3716* + ID_PRODUCT_FROM_DATABASE=UMW190 Modem + +usb:v106Cp3721* + ID_PRODUCT_FROM_DATABASE=Option Beemo (GI0801) LTE surfstick + +usb:v106Cp3B14* + ID_PRODUCT_FROM_DATABASE=Option Beemo (GI0801) LTE surfstick + +usb:v106Cp3EB4* + ID_PRODUCT_FROM_DATABASE=Packet Service Diagnostic Serial Port (WDM) + +usb:v106Cp4101* + ID_PRODUCT_FROM_DATABASE=Packet Service Diagnostic Serial Port (WDM) + +usb:v106Cp4102* + ID_PRODUCT_FROM_DATABASE=Packet Service + +usb:v106Cp4301* + ID_PRODUCT_FROM_DATABASE=Composite Device + +usb:v106Cp4302* + ID_PRODUCT_FROM_DATABASE=Packet Service Diagnostic Serial Port (WDM) + +usb:v106Cp4401* + ID_PRODUCT_FROM_DATABASE=Composite Device + +usb:v106Cp4402* + ID_PRODUCT_FROM_DATABASE=Packet Service + +usb:v106Cp4501* + ID_PRODUCT_FROM_DATABASE=Packet Service + +usb:v106Cp4502* + ID_PRODUCT_FROM_DATABASE=Packet Service Diagnostic Serial Port (WDM) + +usb:v106Cp4601* + ID_PRODUCT_FROM_DATABASE=Composite Device + +usb:v106Cp4602* + ID_PRODUCT_FROM_DATABASE=Packet Service Diagnostic Serial Port (WDM) + +usb:v106Cp5101* + ID_PRODUCT_FROM_DATABASE=Packet Service + +usb:v106Cp5102* + ID_PRODUCT_FROM_DATABASE=Packet Service Diagnostic Serial Port (WDM) + +usb:v106Cp5301* + ID_PRODUCT_FROM_DATABASE=Packet Service Diagnostic Serial Port (WDM) + +usb:v106Cp5302* + ID_PRODUCT_FROM_DATABASE=Packet Service + +usb:v106Cp5401* + ID_PRODUCT_FROM_DATABASE=Packet Service + +usb:v106Cp5402* + ID_PRODUCT_FROM_DATABASE=Packet Service Diagnostic Serial Port (WDM) + +usb:v106Cp5501* + ID_PRODUCT_FROM_DATABASE=Packet Service Diagnostic Serial Port (WDM) + +usb:v106Cp5502* + ID_PRODUCT_FROM_DATABASE=Packet Service + +usb:v106Cp5601* + ID_PRODUCT_FROM_DATABASE=Packet Service Diagnostic Serial Port (WDM) + +usb:v106Cp5602* + ID_PRODUCT_FROM_DATABASE=Packet Service + +usb:v106Cp7101* + ID_PRODUCT_FROM_DATABASE=Composite Device + +usb:v106Cp7102* + ID_PRODUCT_FROM_DATABASE=Packet Service + +usb:v106CpA000* + ID_PRODUCT_FROM_DATABASE=Packet Service + +usb:v106CpA001* + ID_PRODUCT_FROM_DATABASE=Packet Service Diagnostic Serial Port (WDM) + +usb:v106CpC100* + ID_PRODUCT_FROM_DATABASE=Packet Service + +usb:v106CpC200* + ID_PRODUCT_FROM_DATABASE=Packet Service + +usb:v106CpC500* + ID_PRODUCT_FROM_DATABASE=Packet Service Diagnostic Serial Port (WDM) + +usb:v106CpE200* + ID_PRODUCT_FROM_DATABASE=Packet Service + +usb:v106D* + ID_VENDOR_FROM_DATABASE=San Chieh Manufacturing, Ltd + +usb:v106E* + ID_VENDOR_FROM_DATABASE=ConectL + +usb:v106F* + ID_VENDOR_FROM_DATABASE=Money Controls + +usb:v106Fp0009* + ID_PRODUCT_FROM_DATABASE=CT10x Coin Transaction + +usb:v106Fp000A* + ID_PRODUCT_FROM_DATABASE=CR10x Coin Recycler + +usb:v1076* + ID_VENDOR_FROM_DATABASE=GCT Semiconductor, Inc. + +usb:v1076p0031* + ID_PRODUCT_FROM_DATABASE=Bluetooth Device + +usb:v1076p0032* + ID_PRODUCT_FROM_DATABASE=Bluetooth Device + +usb:v107B* + ID_VENDOR_FROM_DATABASE=Gateway, Inc. + +usb:v107Bp3009* + ID_PRODUCT_FROM_DATABASE=eHome Infrared Transceiver + +usb:v107Bp55B2* + ID_PRODUCT_FROM_DATABASE=WBU-110 802.11b Wireless Adapter [Intersil PRISM 3] + +usb:v107Bp55F2* + ID_PRODUCT_FROM_DATABASE=WGU-210 802.11g Adapter [Intersil ISL3886] + +usb:v107D* + ID_VENDOR_FROM_DATABASE=Arlec Australia, Ltd + +usb:v107E* + ID_VENDOR_FROM_DATABASE=Midoriya Electric Co., Ltd + +usb:v107F* + ID_VENDOR_FROM_DATABASE=KidzMouse, Inc. + +usb:v1082* + ID_VENDOR_FROM_DATABASE=Shin-Etsukaken Co., Ltd + +usb:v1083* + ID_VENDOR_FROM_DATABASE=Canon Electronics, Inc. + +usb:v1083p162C* + ID_PRODUCT_FROM_DATABASE=P-150 Scanner + +usb:v1084* + ID_VENDOR_FROM_DATABASE=Pantech Co., Ltd + +usb:v108A* + ID_VENDOR_FROM_DATABASE=Chloride Power Protection + +usb:v108B* + ID_VENDOR_FROM_DATABASE=Grand-tek Technology Co., Ltd + +usb:v108C* + ID_VENDOR_FROM_DATABASE=Robert Bosch GmbH + +usb:v108E* + ID_VENDOR_FROM_DATABASE=Lotes Co., Ltd. + +usb:v1099* + ID_VENDOR_FROM_DATABASE=Surface Optics Corp. + +usb:v109A* + ID_VENDOR_FROM_DATABASE=DATASOFT Systems GmbH + +usb:v109F* + ID_VENDOR_FROM_DATABASE=eSOL Co., Ltd + +usb:v109Fp3163* + ID_PRODUCT_FROM_DATABASE=Trigem Mobile SmartDisplay84 + +usb:v109Fp3164* + ID_PRODUCT_FROM_DATABASE=Trigem Mobile SmartDisplay121 + +usb:v10A0* + ID_VENDOR_FROM_DATABASE=Hirotech, Inc. + +usb:v10A3* + ID_VENDOR_FROM_DATABASE=Mitsubishi Materials Corp. + +usb:v10A9* + ID_VENDOR_FROM_DATABASE=SK Teletech Co., Ltd + +usb:v10A9p1102* + ID_PRODUCT_FROM_DATABASE=Sky Love Actually IM-U460K + +usb:v10A9p1104* + ID_PRODUCT_FROM_DATABASE=Sky Vega IM-A650S + +usb:v10A9p6021* + ID_PRODUCT_FROM_DATABASE=SIRIUS alpha + +usb:v10AA* + ID_VENDOR_FROM_DATABASE=Cables To Go + +usb:v10AB* + ID_VENDOR_FROM_DATABASE=USI Co., Ltd + +usb:v10ABp1002* + ID_PRODUCT_FROM_DATABASE=Bluetooth Device + +usb:v10ABp1003* + ID_PRODUCT_FROM_DATABASE=BC02-EXT in DFU + +usb:v10ABp1005* + ID_PRODUCT_FROM_DATABASE=Bluetooth Adptr + +usb:v10ABp1006* + ID_PRODUCT_FROM_DATABASE=BC04-EXT in DFU + +usb:v10ABp10C5* + ID_PRODUCT_FROM_DATABASE=Sony-Ericsson / Samsung DataCable + +usb:v10AC* + ID_VENDOR_FROM_DATABASE=Honeywell, Inc. + +usb:v10AE* + ID_VENDOR_FROM_DATABASE=Princeton Technology Corp. + +usb:v10AF* + ID_VENDOR_FROM_DATABASE=Liebert Corp. + +usb:v10AFp0000* + ID_PRODUCT_FROM_DATABASE=UPS + +usb:v10AFp0001* + ID_PRODUCT_FROM_DATABASE=PowerSure PSA UPS + +usb:v10AFp0002* + ID_PRODUCT_FROM_DATABASE=PowerSure PST UPS + +usb:v10AFp0003* + ID_PRODUCT_FROM_DATABASE=PowerSure PSP UPS + +usb:v10AFp0004* + ID_PRODUCT_FROM_DATABASE=PowerSure PSI UPS + +usb:v10AFp0005* + ID_PRODUCT_FROM_DATABASE=UPStation GXT 2U UPS + +usb:v10AFp0006* + ID_PRODUCT_FROM_DATABASE=UPStation GXT UPS + +usb:v10AFp0007* + ID_PRODUCT_FROM_DATABASE=Nfinity Power Systems UPS + +usb:v10AFp0008* + ID_PRODUCT_FROM_DATABASE=PowerSure Interactive UPS + +usb:v10B5* + ID_VENDOR_FROM_DATABASE=Comodo (PLX?) + +usb:v10B5p9060* + ID_PRODUCT_FROM_DATABASE=Test Board + +usb:v10B8* + ID_VENDOR_FROM_DATABASE=DiBcom + +usb:v10B8p0BB8* + ID_PRODUCT_FROM_DATABASE=DiBcom USB DVB-T reference design (MOD300) (cold) + +usb:v10B8p0BB9* + ID_PRODUCT_FROM_DATABASE=DiBcom USB DVB-T reference design (MOD300) (warm) + +usb:v10B8p0BC6* + ID_PRODUCT_FROM_DATABASE=DiBcom USB2.0 DVB-T reference design (MOD3000P) (cold) + +usb:v10B8p0BC7* + ID_PRODUCT_FROM_DATABASE=DiBcom USB2.0 DVB-T reference design (MOD3000P) (warm) + +usb:v10BB* + ID_VENDOR_FROM_DATABASE=TM Technology, Inc. + +usb:v10BC* + ID_VENDOR_FROM_DATABASE=Dinging Technology Co., Ltd + +usb:v10BD* + ID_VENDOR_FROM_DATABASE=TMT Technology, Inc. + +usb:v10BDp1427* + ID_PRODUCT_FROM_DATABASE=Ethernet + +usb:v10BF* + ID_VENDOR_FROM_DATABASE=SmartHome + +usb:v10BFp0001* + ID_PRODUCT_FROM_DATABASE=SmartHome PowerLinc + +usb:v10C4* + ID_VENDOR_FROM_DATABASE=Cygnal Integrated Products, Inc. + +usb:v10C4p0002* + ID_PRODUCT_FROM_DATABASE=F32x USBXpress Device + +usb:v10C4p0003* + ID_PRODUCT_FROM_DATABASE=CommandIR + +usb:v10C4p8030* + ID_PRODUCT_FROM_DATABASE=K4JRG Ham Radio devices + +usb:v10C4p8044* + ID_PRODUCT_FROM_DATABASE=USB Debug Adapter + +usb:v10C4p804E* + ID_PRODUCT_FROM_DATABASE=Software Bisque Paramount ME + +usb:v10C4p80A9* + ID_PRODUCT_FROM_DATABASE=CP210x to UART Bridge Controller + +usb:v10C4p80CA* + ID_PRODUCT_FROM_DATABASE=ATM2400 Sensor Device + +usb:v10C4p813F* + ID_PRODUCT_FROM_DATABASE=tams EasyControl + +usb:v10C4p8149* + ID_PRODUCT_FROM_DATABASE=West Mountain Radio Computerized Battery Analyzer + +usb:v10C4p814A* + ID_PRODUCT_FROM_DATABASE=West Mountain Radio RIGblaster P&P + +usb:v10C4p814B* + ID_PRODUCT_FROM_DATABASE=West Mountain Radio RIGtalk + +usb:v10C4p818A* + ID_PRODUCT_FROM_DATABASE=Silicon Labs FM Radio Reference Design + +usb:v10C4p81E8* + ID_PRODUCT_FROM_DATABASE=Zephyr BioHarness + +usb:v10C4p8460* + ID_PRODUCT_FROM_DATABASE=Sangoma Wanpipe VoiceTime + +usb:v10C4p8461* + ID_PRODUCT_FROM_DATABASE=Sangoma U100 + +usb:v10C4p8477* + ID_PRODUCT_FROM_DATABASE=Balluff RFID Reader + +usb:v10C4p8605* + ID_PRODUCT_FROM_DATABASE=dilitronics ESoLUX solar lighting controller + +usb:v10C4p86BC* + ID_PRODUCT_FROM_DATABASE=C8051F34x AudioDelay [AD-340] + +usb:v10C4p8789* + ID_PRODUCT_FROM_DATABASE=C8051F34x Extender & EDID MGR [EMX-DVI] + +usb:v10C4p87BE* + ID_PRODUCT_FROM_DATABASE=C8051F34x HDMI Audio Extractor [EMX-HD-AUD] + +usb:v10C4pEA60* + ID_PRODUCT_FROM_DATABASE=CP210x UART Bridge / myAVR mySmartUSB light + +usb:v10C4pEA61* + ID_PRODUCT_FROM_DATABASE=CP210x UART Bridge + +usb:v10C4pEA70* + ID_PRODUCT_FROM_DATABASE=CP210x UART Bridge + +usb:v10C4pEA80* + ID_PRODUCT_FROM_DATABASE=CP210x UART Bridge + +usb:v10C5* + ID_VENDOR_FROM_DATABASE=Sanei Electric, Inc. + +usb:v10C5p819A* + ID_PRODUCT_FROM_DATABASE=FM Radio + +usb:v10C6* + ID_VENDOR_FROM_DATABASE=Intec, Inc. + +usb:v10CB* + ID_VENDOR_FROM_DATABASE=Eratech + +usb:v10CC* + ID_VENDOR_FROM_DATABASE=GBM Connector Co., Ltd + +usb:v10CCp1101* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v10CD* + ID_VENDOR_FROM_DATABASE=Kycon, Inc. + +usb:v10CE* + ID_VENDOR_FROM_DATABASE=Silicon Labs + +usb:v10CEpEA6A* + ID_PRODUCT_FROM_DATABASE=MobiData EDGE USB Modem + +usb:v10CF* + ID_VENDOR_FROM_DATABASE=Velleman Components, Inc. + +usb:v10CFp2011* + ID_PRODUCT_FROM_DATABASE=R-Engine MPEG2 encoder/decoder + +usb:v10CFp5500* + ID_PRODUCT_FROM_DATABASE=8055 Experiment Interface Board (address=0) + +usb:v10CFp5501* + ID_PRODUCT_FROM_DATABASE=8055 Experiment Interface Board (address=1) + +usb:v10CFp5502* + ID_PRODUCT_FROM_DATABASE=8055 Experiment Interface Board (address=2) + +usb:v10CFp5503* + ID_PRODUCT_FROM_DATABASE=8055 Experiment Interface Board (address=3) + +usb:v10D1* + ID_VENDOR_FROM_DATABASE=Hottinger Baldwin Measurement + +usb:v10D1p0101* + ID_PRODUCT_FROM_DATABASE=USB-Module for Spider8, CP32 + +usb:v10D1p0202* + ID_PRODUCT_FROM_DATABASE=CP22 - Communication Processor + +usb:v10D1p0301* + ID_PRODUCT_FROM_DATABASE=CP42 - Communication Processor + +usb:v10D4* + ID_VENDOR_FROM_DATABASE=Man Boon Manufactory, Ltd + +usb:v10D5* + ID_VENDOR_FROM_DATABASE=Uni Class Technology Co., Ltd + +usb:v10D5p5552* + ID_PRODUCT_FROM_DATABASE=KVM Human Interface Composite Device (Keyboard/Mouse ports) + +usb:v10D5p55A2* + ID_PRODUCT_FROM_DATABASE=2Port KVMSwitcher + +usb:v10D6* + ID_VENDOR_FROM_DATABASE=Actions Semiconductor Co., Ltd + +usb:v10D6p1000* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v10D6p1100* + ID_PRODUCT_FROM_DATABASE=MPMan MP-Ki 128 MP3 Player/Recorder + +usb:v10D6p1101* + ID_PRODUCT_FROM_DATABASE=D-Wave 2GB MP4 Player / AK1025 MP3/MP4 Player + +usb:v10D6p2200* + ID_PRODUCT_FROM_DATABASE=Acer MP-120 MP3 player + +usb:v10D6p8888* + ID_PRODUCT_FROM_DATABASE=ADFU Device + +usb:v10D6pFF51* + ID_PRODUCT_FROM_DATABASE=ADFU Device + +usb:v10D6pFF61* + ID_PRODUCT_FROM_DATABASE=MP4 Player + +usb:v10D6pFF66* + ID_PRODUCT_FROM_DATABASE=Craig 2GB MP3/Video Player + +usb:v10DE* + ID_VENDOR_FROM_DATABASE=Authenex, Inc. + +usb:v10DF* + ID_VENDOR_FROM_DATABASE=In-Win Development, Inc. + +usb:v10DFp0500* + ID_PRODUCT_FROM_DATABASE=iAPP CR-e500 Card reader + +usb:v10E0* + ID_VENDOR_FROM_DATABASE=Post-Op Video, Inc. + +usb:v10E1* + ID_VENDOR_FROM_DATABASE=CablePlus, Ltd + +usb:v10E2* + ID_VENDOR_FROM_DATABASE=Nada Electronics, Ltd + +usb:v10EC* + ID_VENDOR_FROM_DATABASE=Vast Technologies, Inc. + +usb:v10F0* + ID_VENDOR_FROM_DATABASE=Nexio Co., Ltd + +usb:v10F0p2002* + ID_PRODUCT_FROM_DATABASE=iNexio Touchscreen controller + +usb:v10F1* + ID_VENDOR_FROM_DATABASE=Importek + +usb:v10F1p1A08* + ID_PRODUCT_FROM_DATABASE=Internal Webcam + +usb:v10F1p1A1E* + ID_PRODUCT_FROM_DATABASE=Laptop Integrated Webcam 1.3M + +usb:v10F1p1A2A* + ID_PRODUCT_FROM_DATABASE=Laptop Integrated Webcam + +usb:v10F5* + ID_VENDOR_FROM_DATABASE=Turtle Beach + +usb:v10F5p0200* + ID_PRODUCT_FROM_DATABASE=Audio Advantage Roadie + +usb:v10FB* + ID_VENDOR_FROM_DATABASE=Pictos Technologies, Inc. + +usb:v10FD* + ID_VENDOR_FROM_DATABASE=Anubis Electronics, Ltd + +usb:v10FDp7E50* + ID_PRODUCT_FROM_DATABASE=FlyCam Usb 100 + +usb:v10FDp804D* + ID_PRODUCT_FROM_DATABASE=Typhoon Webshot II Webcam [zc0301] + +usb:v10FDp8050* + ID_PRODUCT_FROM_DATABASE=FlyCAM-USB 300 XP2 + +usb:v10FDpDE00* + ID_PRODUCT_FROM_DATABASE=WinFast WalkieTV WDM Capture Driver. + +usb:v10FE* + ID_VENDOR_FROM_DATABASE=Thrane & Thrane + +usb:v10FEp000C* + ID_PRODUCT_FROM_DATABASE=TT-3750 BGAN-XL Radio Module + +usb:v1100* + ID_VENDOR_FROM_DATABASE=VirTouch, Ltd + +usb:v1100p0001* + ID_PRODUCT_FROM_DATABASE=VTPlayer VTP-1 Braille Mouse + +usb:v1101* + ID_VENDOR_FROM_DATABASE=EasyPass Industrial Co., Ltd + +usb:v1101p0001* + ID_PRODUCT_FROM_DATABASE=FSK Electronics Super GSM Reader + +usb:v1108* + ID_VENDOR_FROM_DATABASE=Brightcom Technologies, Ltd + +usb:v110A* + ID_VENDOR_FROM_DATABASE=Moxa Technologies Co., Ltd. + +usb:v110Ap1250* + ID_PRODUCT_FROM_DATABASE=UPort 1250 2-Port RS-232/422/485 + +usb:v110Ap1251* + ID_PRODUCT_FROM_DATABASE=UPort 1250I 2-Port RS-232/422/485 with Isolation + +usb:v110Ap1410* + ID_PRODUCT_FROM_DATABASE=UPort 1410 4-Port RS-232 + +usb:v110Ap1450* + ID_PRODUCT_FROM_DATABASE=UPort 1450 4-Port RS-232/422/485 + +usb:v110Ap1451* + ID_PRODUCT_FROM_DATABASE=UPort 1450I 4-Port RS-232/422/485 with Isolation + +usb:v110Ap1613* + ID_PRODUCT_FROM_DATABASE=UPort 1610-16 16-Port RS-232 + +usb:v110Ap1618* + ID_PRODUCT_FROM_DATABASE=UPort 1610-8 8-Port RS-232 + +usb:v110Ap1653* + ID_PRODUCT_FROM_DATABASE=UPort 1650-16 16-Port RS-232/422/485 + +usb:v110Ap1658* + ID_PRODUCT_FROM_DATABASE=UPort 1650-8 8-Port RS-232/422/485 + +usb:v1110* + ID_VENDOR_FROM_DATABASE=Analog Devices Canada, Ltd (Allied Telesyn) + +usb:v1110p5C01* + ID_PRODUCT_FROM_DATABASE=Huawei MT-882 Remote NDIS Network Device + +usb:v1110p6489* + ID_PRODUCT_FROM_DATABASE=ADSL ETH/USB RTR + +usb:v1110p9000* + ID_PRODUCT_FROM_DATABASE=ADSL LAN Adapter + +usb:v1110p9001* + ID_PRODUCT_FROM_DATABASE=ADSL Loader + +usb:v1110p900F* + ID_PRODUCT_FROM_DATABASE=AT-AR215 DSL Modem + +usb:v1110p9010* + ID_PRODUCT_FROM_DATABASE=AT-AR215 DSL Modem + +usb:v1110p9021* + ID_PRODUCT_FROM_DATABASE=ADSL WAN Adapter + +usb:v1110p9022* + ID_PRODUCT_FROM_DATABASE=ADSL Loader + +usb:v1110p9023* + ID_PRODUCT_FROM_DATABASE=ADSL WAN Adapter + +usb:v1110p9024* + ID_PRODUCT_FROM_DATABASE=ADSL Loader + +usb:v1110p9031* + ID_PRODUCT_FROM_DATABASE=ADSL LAN Adapter + +usb:v1110p9032* + ID_PRODUCT_FROM_DATABASE=ADSL Loader + +usb:v1111* + ID_VENDOR_FROM_DATABASE=Pandora International Ltd. + +usb:v1111p8888* + ID_PRODUCT_FROM_DATABASE=Evolution Device + +usb:v1112* + ID_VENDOR_FROM_DATABASE=YM ELECTRIC CO., Ltd + +usb:v1113* + ID_VENDOR_FROM_DATABASE=Medion AG + +usb:v1113pA0A2* + ID_PRODUCT_FROM_DATABASE=Active Sync device + +usb:v111E* + ID_VENDOR_FROM_DATABASE=VSO Electric Co., Ltd + +usb:v112A* + ID_VENDOR_FROM_DATABASE=RedRat + +usb:v112Ap0001* + ID_PRODUCT_FROM_DATABASE=RedRat3 IR Transceiver + +usb:v112Ap0005* + ID_PRODUCT_FROM_DATABASE=RedRat3II IR Transceiver + +usb:v112E* + ID_VENDOR_FROM_DATABASE=Master Hill Electric Wire and Cable Co., Ltd + +usb:v112F* + ID_VENDOR_FROM_DATABASE=Cellon International, Inc. + +usb:v1130* + ID_VENDOR_FROM_DATABASE=Tenx Technology, Inc. + +usb:v1130p0002* + ID_PRODUCT_FROM_DATABASE=iBuddy + +usb:v1130p0202* + ID_PRODUCT_FROM_DATABASE=Rocket Launcher + +usb:v1130p6604* + ID_PRODUCT_FROM_DATABASE=MCE IR-Receiver + +usb:v1130p660C* + ID_PRODUCT_FROM_DATABASE=Foot Pedal/Thermometer + +usb:v1130p6806* + ID_PRODUCT_FROM_DATABASE=Keychain photo frame + +usb:v1130pF211* + ID_PRODUCT_FROM_DATABASE=TP6911 Audio Headset + +usb:v1131* + ID_VENDOR_FROM_DATABASE=Integrated System Solution Corp. + +usb:v1131p1001* + ID_PRODUCT_FROM_DATABASE=KY-BT100 Bluetooth Adapter + +usb:v1131p1002* + ID_PRODUCT_FROM_DATABASE=Bluetooth Device + +usb:v1131p1003* + ID_PRODUCT_FROM_DATABASE=Bluetooth Device + +usb:v1131p1004* + ID_PRODUCT_FROM_DATABASE=Bluetooth Device + +usb:v1132* + ID_VENDOR_FROM_DATABASE=Toshiba Corp., Digital Media Equipment [hex] + +usb:v1132p4331* + ID_PRODUCT_FROM_DATABASE=PDR-M4/M5/M70 Digital Camera + +usb:v1132p4332* + ID_PRODUCT_FROM_DATABASE=PDR-M60 Digital Camera + +usb:v1132p4333* + ID_PRODUCT_FROM_DATABASE=PDR-M2300/PDR-M700 + +usb:v1132p4334* + ID_PRODUCT_FROM_DATABASE=PDR-M65 + +usb:v1132p4335* + ID_PRODUCT_FROM_DATABASE=PDR-M61 + +usb:v1132p4337* + ID_PRODUCT_FROM_DATABASE=PDR-M11 + +usb:v1132p4338* + ID_PRODUCT_FROM_DATABASE=PDR-M25 + +usb:v1136* + ID_VENDOR_FROM_DATABASE=CTS Electronincs + +usb:v1136p3131* + ID_PRODUCT_FROM_DATABASE=CTS LS515 + +usb:v113C* + ID_VENDOR_FROM_DATABASE=Arin Tech Co., Ltd + +usb:v113D* + ID_VENDOR_FROM_DATABASE=Mapower Electronics Co., Ltd + +usb:v1141* + ID_VENDOR_FROM_DATABASE=V One Multimedia, Pte., Ltd + +usb:v1142* + ID_VENDOR_FROM_DATABASE=CyberScan Technologies, Inc. + +usb:v1145* + ID_VENDOR_FROM_DATABASE=Japan Radio Company + +usb:v1145p0001* + ID_PRODUCT_FROM_DATABASE=AirH PHONE AH-J3001V/J3002V + +usb:v1146* + ID_VENDOR_FROM_DATABASE=Shimane SANYO Electric Co., Ltd. + +usb:v1147* + ID_VENDOR_FROM_DATABASE=Ever Great Electric Wire and Cable Co., Ltd + +usb:v114B* + ID_VENDOR_FROM_DATABASE=Sphairon Access Systems GmbH + +usb:v114Bp0110* + ID_PRODUCT_FROM_DATABASE=Turbolink UB801R WLAN Adapter + +usb:v114Bp0150* + ID_PRODUCT_FROM_DATABASE=Turbolink UB801RE Wireless 802.11g 54Mbps Network Adapter [RTL8187] + +usb:v114C* + ID_VENDOR_FROM_DATABASE=Tinius Olsen Testing Machine Co., Inc. + +usb:v114D* + ID_VENDOR_FROM_DATABASE=Alpha Imaging Technology Corp. + +usb:v114F* + ID_VENDOR_FROM_DATABASE=Wavecom + +usb:v115B* + ID_VENDOR_FROM_DATABASE=Salix Technology Co., Ltd. + +usb:v1162* + ID_VENDOR_FROM_DATABASE=Secugen Corp. + +usb:v1163* + ID_VENDOR_FROM_DATABASE=DeLorme Publishing, Inc. + +usb:v1163p0100* + ID_PRODUCT_FROM_DATABASE=Earthmate GPS (orig) + +usb:v1163p0200* + ID_PRODUCT_FROM_DATABASE=Earthmate GPS (LT-20, LT-40) + +usb:v1163p2020* + ID_PRODUCT_FROM_DATABASE=Earthmate GPS (PN-40) + +usb:v1164* + ID_VENDOR_FROM_DATABASE=YUAN High-Tech Development Co., Ltd + +usb:v1164p0300* + ID_PRODUCT_FROM_DATABASE=ELSAVISION 460D + +usb:v1164p0601* + ID_PRODUCT_FROM_DATABASE=Analog TV Tuner + +usb:v1164p0900* + ID_PRODUCT_FROM_DATABASE=TigerBird BMP837 USB2.0 WDM Encoder + +usb:v1164p0BC7* + ID_PRODUCT_FROM_DATABASE=Digital TV Tuner + +usb:v1164p521B* + ID_PRODUCT_FROM_DATABASE=MC521A mini Card ATSC Tuner + +usb:v1164p6601* + ID_PRODUCT_FROM_DATABASE=Digital TV Tuner Card [RTL2832U] + +usb:v1165* + ID_VENDOR_FROM_DATABASE=Telson Electronics Co., Ltd + +usb:v1166* + ID_VENDOR_FROM_DATABASE=Bantam Interactive Technologies + +usb:v1167* + ID_VENDOR_FROM_DATABASE=Salient Systems Corp. + +usb:v1168* + ID_VENDOR_FROM_DATABASE=BizConn International Corp. + +usb:v116E* + ID_VENDOR_FROM_DATABASE=Gigastorage Corp. + +usb:v116F* + ID_VENDOR_FROM_DATABASE=Silicon 10 Technology Corp. + +usb:v116Fp0005* + ID_PRODUCT_FROM_DATABASE=Flash Card Reader + +usb:v116FpC108* + ID_PRODUCT_FROM_DATABASE=Flash Card Reader + +usb:v116FpC109* + ID_PRODUCT_FROM_DATABASE=Flash Card Reader + +usb:v1175* + ID_VENDOR_FROM_DATABASE=Shengyih Steel Mold Co., Ltd + +usb:v117D* + ID_VENDOR_FROM_DATABASE=Santa Electronic, Inc. + +usb:v117E* + ID_VENDOR_FROM_DATABASE=JNC, Inc. + +usb:v1182* + ID_VENDOR_FROM_DATABASE=Venture Corp., Ltd + +usb:v1183* + ID_VENDOR_FROM_DATABASE=Compaq Computer Corp. [hex] (Digital Dream ??) + +usb:v1183p0001* + ID_PRODUCT_FROM_DATABASE=DigitalDream l'espion XS + +usb:v1183p19C7* + ID_PRODUCT_FROM_DATABASE=ISDN TA + +usb:v1183p4008* + ID_PRODUCT_FROM_DATABASE=56k FaxModem + +usb:v1183p504A* + ID_PRODUCT_FROM_DATABASE=PJB-100 Personal Jukebox + +usb:v1184* + ID_VENDOR_FROM_DATABASE=Kyocera Elco Corp. + +usb:v1188* + ID_VENDOR_FROM_DATABASE=Bloomberg L.P. + +usb:v1189* + ID_VENDOR_FROM_DATABASE=Acer Communications & Multimedia + +usb:v1189p0893* + ID_PRODUCT_FROM_DATABASE=EP-1427X-2 Ethernet Adapter [Acer] + +usb:v118F* + ID_VENDOR_FROM_DATABASE=You Yang Technology Co., Ltd + +usb:v1190* + ID_VENDOR_FROM_DATABASE=Tripace + +usb:v1191* + ID_VENDOR_FROM_DATABASE=Loyalty Founder Enterprise Co., Ltd + +usb:v1196* + ID_VENDOR_FROM_DATABASE=Yankee Robotics, LLC + +usb:v1196p0010* + ID_PRODUCT_FROM_DATABASE=Trifid Camera without code + +usb:v1196p0011* + ID_PRODUCT_FROM_DATABASE=Trifid Camera + +usb:v1197* + ID_VENDOR_FROM_DATABASE=Technoimagia Co., Ltd + +usb:v1198* + ID_VENDOR_FROM_DATABASE=StarShine Technology Corp. + +usb:v1199* + ID_VENDOR_FROM_DATABASE=Sierra Wireless, Inc. + +usb:v1199p0019* + ID_PRODUCT_FROM_DATABASE=AC595U + +usb:v1199p0021* + ID_PRODUCT_FROM_DATABASE=AC597E + +usb:v1199p0024* + ID_PRODUCT_FROM_DATABASE=MC5727 CDMA modem + +usb:v1199p0110* + ID_PRODUCT_FROM_DATABASE=Composite Device + +usb:v1199p0112* + ID_PRODUCT_FROM_DATABASE=CDMA 1xEVDO PC Card, AirCard 580 + +usb:v1199p0120* + ID_PRODUCT_FROM_DATABASE=AC595U + +usb:v1199p0218* + ID_PRODUCT_FROM_DATABASE=MC5720 Wireless Modem + +usb:v1199p6467* + ID_PRODUCT_FROM_DATABASE=MP Series Network Adapter + +usb:v1199p6468* + ID_PRODUCT_FROM_DATABASE=MP Series Network Adapter + +usb:v1199p6469* + ID_PRODUCT_FROM_DATABASE=MP Series Network Adapter + +usb:v1199p6802* + ID_PRODUCT_FROM_DATABASE=MC8755 Device + +usb:v1199p6803* + ID_PRODUCT_FROM_DATABASE=MC8765 Device + +usb:v1199p6804* + ID_PRODUCT_FROM_DATABASE=MC8755 Device + +usb:v1199p6805* + ID_PRODUCT_FROM_DATABASE=MC8765 Device + +usb:v1199p6812* + ID_PRODUCT_FROM_DATABASE=MC8775 Device + +usb:v1199p6820* + ID_PRODUCT_FROM_DATABASE=AC875 Device + +usb:v1199p6832* + ID_PRODUCT_FROM_DATABASE=MC8780 Device + +usb:v1199p6833* + ID_PRODUCT_FROM_DATABASE=MC8781 Device + +usb:v1199p683A* + ID_PRODUCT_FROM_DATABASE=MC8785 Device + +usb:v1199p683C* + ID_PRODUCT_FROM_DATABASE=MC8790 Device + +usb:v1199p6850* + ID_PRODUCT_FROM_DATABASE=AirCard 880 Device + +usb:v1199p6851* + ID_PRODUCT_FROM_DATABASE=AirCard 881 Device + +usb:v1199p6852* + ID_PRODUCT_FROM_DATABASE=AirCard 880E Device + +usb:v1199p6853* + ID_PRODUCT_FROM_DATABASE=AirCard 881E Device + +usb:v1199p6854* + ID_PRODUCT_FROM_DATABASE=AirCard 885 Device + +usb:v1199p6856* + ID_PRODUCT_FROM_DATABASE=ATT "USB Connect 881" + +usb:v1199p6870* + ID_PRODUCT_FROM_DATABASE=MC8780 Device + +usb:v1199p6871* + ID_PRODUCT_FROM_DATABASE=MC8781 Device + +usb:v1199p6893* + ID_PRODUCT_FROM_DATABASE=MC8777 Device + +usb:v1199p68A3* + ID_PRODUCT_FROM_DATABASE=MC8700 Modem + +usb:v1199p68AA* + ID_PRODUCT_FROM_DATABASE=4G LTE adapter + +usb:v1199p9000* + ID_PRODUCT_FROM_DATABASE=Gobi 2000 Wireless Modem (QDL mode) + +usb:v1199p9001* + ID_PRODUCT_FROM_DATABASE=Gobi 2000 Wireless Modem + +usb:v1199p9002* + ID_PRODUCT_FROM_DATABASE=Gobi 2000 Wireless Modem + +usb:v1199p9003* + ID_PRODUCT_FROM_DATABASE=Gobi 2000 Wireless Modem + +usb:v1199p9004* + ID_PRODUCT_FROM_DATABASE=Gobi 2000 Wireless Modem + +usb:v1199p9005* + ID_PRODUCT_FROM_DATABASE=Gobi 2000 Wireless Modem + +usb:v1199p9006* + ID_PRODUCT_FROM_DATABASE=Gobi 2000 Wireless Modem + +usb:v1199p9007* + ID_PRODUCT_FROM_DATABASE=Gobi 2000 Wireless Modem + +usb:v1199p9008* + ID_PRODUCT_FROM_DATABASE=Gobi 2000 Wireless Modem + +usb:v1199p9009* + ID_PRODUCT_FROM_DATABASE=Gobi 2000 Wireless Modem + +usb:v1199p900A* + ID_PRODUCT_FROM_DATABASE=Gobi 2000 Wireless Modem + +usb:v119A* + ID_VENDOR_FROM_DATABASE=ZHAN QI Technology Co., Ltd + +usb:v119B* + ID_VENDOR_FROM_DATABASE=ruwido austria GmbH + +usb:v119Bp0400* + ID_PRODUCT_FROM_DATABASE=Infrared Keyboard V2.01 + +usb:v11A0* + ID_VENDOR_FROM_DATABASE=Chipcon AS + +usb:v11A0pEB11* + ID_PRODUCT_FROM_DATABASE=CC2400EB 2.0 ZigBee Sniffer + +usb:v11A3* + ID_VENDOR_FROM_DATABASE=Technovas Co., Ltd + +usb:v11A3p8031* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v11A3p8032* + ID_PRODUCT_FROM_DATABASE=MP3 Player + +usb:v11AA* + ID_VENDOR_FROM_DATABASE=GlobalMedia Group, LLC + +usb:v11AAp1518* + ID_PRODUCT_FROM_DATABASE=iREZ K2 + +usb:v11AB* + ID_VENDOR_FROM_DATABASE=Exito Electronics Co., Ltd + +usb:v11B0* + ID_VENDOR_FROM_DATABASE=ATECH FLASH TECHNOLOGY + +usb:v11C5* + ID_VENDOR_FROM_DATABASE=Inmax + +usb:v11C5p0521* + ID_PRODUCT_FROM_DATABASE=IMT-0521 Smartcard Reader + +usb:v11DB* + ID_VENDOR_FROM_DATABASE=Topfield Co., Ltd. + +usb:v11DBp1000* + ID_PRODUCT_FROM_DATABASE=PVR + +usb:v11DBp1100* + ID_PRODUCT_FROM_DATABASE=PVR + +usb:v11E6* + ID_VENDOR_FROM_DATABASE=K.I. Technology Co. Ltd. + +usb:v11F5* + ID_VENDOR_FROM_DATABASE=Siemens AG + +usb:v11F5p0001* + ID_PRODUCT_FROM_DATABASE=SX1 + +usb:v11F5p0003* + ID_PRODUCT_FROM_DATABASE=Mobile phone USB cable + +usb:v11F5p0004* + ID_PRODUCT_FROM_DATABASE=X75 + +usb:v11F5p0005* + ID_PRODUCT_FROM_DATABASE=SXG75/EF81 + +usb:v11F5p0008* + ID_PRODUCT_FROM_DATABASE=UMTS/HSDPA Data Card + +usb:v11F6* + ID_VENDOR_FROM_DATABASE=Prolific + +usb:v11F6p2001* + ID_PRODUCT_FROM_DATABASE=Willcom WSIM + +usb:v11F7* + ID_VENDOR_FROM_DATABASE=Alcatel (?) + +usb:v11F7p02DF* + ID_PRODUCT_FROM_DATABASE=TD10 Mobile phone USB cable + +usb:v1203* + ID_VENDOR_FROM_DATABASE=TSC Auto ID Technology Co., Ltd + +usb:v1203p0140* + ID_PRODUCT_FROM_DATABASE=TTP-245C + +usb:v1209* + ID_VENDOR_FROM_DATABASE=InterBiometrics + +usb:v1209p1001* + ID_PRODUCT_FROM_DATABASE=USB Hub + +usb:v1209p1002* + ID_PRODUCT_FROM_DATABASE=USB Relais + +usb:v1209p1003* + ID_PRODUCT_FROM_DATABASE=IBSecureCam-P + +usb:v1209p1004* + ID_PRODUCT_FROM_DATABASE=IBSecureCam-O + +usb:v1209p1005* + ID_PRODUCT_FROM_DATABASE=IBSecureCam-N + +usb:v120E* + ID_VENDOR_FROM_DATABASE=Hudson Soft Co., Ltd + +usb:v120F* + ID_VENDOR_FROM_DATABASE=Magellan + +usb:v120Fp524E* + ID_PRODUCT_FROM_DATABASE=RoadMate 1475T + +usb:v120Fp5260* + ID_PRODUCT_FROM_DATABASE=Triton Handheld GPS Receiver (300/400/500/1500/2000) + +usb:v1210* + ID_VENDOR_FROM_DATABASE=DigiTech + +usb:v1210p001B* + ID_PRODUCT_FROM_DATABASE=RP155 Guitar Multi-Effects Processor + +usb:v1210p001C* + ID_PRODUCT_FROM_DATABASE=RP255 Guitar Multi-Effects Processor + +usb:v121E* + ID_VENDOR_FROM_DATABASE=Jungsoft Co., Ltd + +usb:v121Ep3403* + ID_PRODUCT_FROM_DATABASE=Muzio JM250 Audio Player + +usb:v1223* + ID_VENDOR_FROM_DATABASE=SKYCABLE ENTERPRISE. CO., LTD. + +usb:v1230* + ID_VENDOR_FROM_DATABASE=Chipidea-Microelectronica, S.A. + +usb:v1233* + ID_VENDOR_FROM_DATABASE=Denver Electronics + +usb:v1233p5677* + ID_PRODUCT_FROM_DATABASE=FUSB200 mp3 player + +usb:v1234* + ID_VENDOR_FROM_DATABASE=Brain Actuated Technologies + +usb:v1234p0000* + ID_PRODUCT_FROM_DATABASE=Neural Impulse Actuator Prototype 1.0 [NIA] + +usb:v1234p4321* + ID_PRODUCT_FROM_DATABASE=Human Interface Device + +usb:v1234pED02* + ID_PRODUCT_FROM_DATABASE=Emotiv EPOC Developer Headset Wireless Dongle + +usb:v1235* + ID_VENDOR_FROM_DATABASE=Novation EMS + +usb:v1235p0001* + ID_PRODUCT_FROM_DATABASE=ReMOTE Audio/XStation + +usb:v1235p0002* + ID_PRODUCT_FROM_DATABASE=Speedio + +usb:v1235p0003* + ID_PRODUCT_FROM_DATABASE=ReMOTE ZeRO SL + +usb:v1235p4661* + ID_PRODUCT_FROM_DATABASE=ReMOTE25 + +usb:v1235p8006* + ID_PRODUCT_FROM_DATABASE=Focusrite Scarlett 2i2 + +usb:v1241* + ID_VENDOR_FROM_DATABASE=Belkin + +usb:v1241p1111* + ID_PRODUCT_FROM_DATABASE=Mouse + +usb:v1241p1122* + ID_PRODUCT_FROM_DATABASE=Typhoon Stream Optical Mouse USB+PS/2 + +usb:v1241p1155* + ID_PRODUCT_FROM_DATABASE=PS2/USB Browser Combo Mouse + +usb:v1241p1166* + ID_PRODUCT_FROM_DATABASE=MI-2150 Trust Mouse + +usb:v1241p1177* + ID_PRODUCT_FROM_DATABASE=F8E842-DL Mouse + +usb:v1241p1503* + ID_PRODUCT_FROM_DATABASE=Keyboard + +usb:v1241p1603* + ID_PRODUCT_FROM_DATABASE=Keyboard + +usb:v124A* + ID_VENDOR_FROM_DATABASE=AirVast + +usb:v124Ap168B* + ID_PRODUCT_FROM_DATABASE=PRISM3 WLAN Adapter + +usb:v124Ap4017* + ID_PRODUCT_FROM_DATABASE=PC-Chips 802.11b Adapter + +usb:v124Ap4023* + ID_PRODUCT_FROM_DATABASE=WM168g 802.11bg Wireless Adapter [Intersil ISL3886] + +usb:v124Ap4025* + ID_PRODUCT_FROM_DATABASE=IOGear GWU513 v2 802.11bg Wireless Adapter [Intersil ISL3887] + +usb:v124B* + ID_VENDOR_FROM_DATABASE=Nyko (Honey Bee) + +usb:v124Bp4D01* + ID_PRODUCT_FROM_DATABASE=Airflo EX Joystick + +usb:v124C* + ID_VENDOR_FROM_DATABASE=MXI - Memory Experts International, Inc. + +usb:v124Cp3200* + ID_PRODUCT_FROM_DATABASE=Stealth MXP 1GB + +usb:v125C* + ID_VENDOR_FROM_DATABASE=Apogee Inc. + +usb:v125Cp0010* + ID_PRODUCT_FROM_DATABASE=Alta series CCD + +usb:v125F* + ID_VENDOR_FROM_DATABASE=A-DATA Technology Co., Ltd. + +usb:v125Fp312A* + ID_PRODUCT_FROM_DATABASE=Superior S102 + +usb:v125Fp312B* + ID_PRODUCT_FROM_DATABASE=Superior S102 Pro + +usb:v125FpA91A* + ID_PRODUCT_FROM_DATABASE=Portable HDD CH91 + +usb:v125FpC08A* + ID_PRODUCT_FROM_DATABASE=C008 Flash Drive + +usb:v125FpC81A* + ID_PRODUCT_FROM_DATABASE=Flash drive + +usb:v125FpC93A* + ID_PRODUCT_FROM_DATABASE=4GB Pen Drive + +usb:v125FpC96A* + ID_PRODUCT_FROM_DATABASE=C906 Flash Drive + +usb:v1260* + ID_VENDOR_FROM_DATABASE=Standard Microsystems Corp. + +usb:v1260pEE22* + ID_PRODUCT_FROM_DATABASE=SMC2862W-G v3 EZ Connect 802.11g Adapter [Intersil ISL3887] + +usb:v1264* + ID_VENDOR_FROM_DATABASE=Covidien Energy-based Devices + +usb:v1266* + ID_VENDOR_FROM_DATABASE=Pirelli Broadband Solutions + +usb:v1266p6302* + ID_PRODUCT_FROM_DATABASE=Fastweb DRG A226M ADSL Router + +usb:v1267* + ID_VENDOR_FROM_DATABASE=Logic3 / SpectraVideo plc + +usb:v1267p0103* + ID_PRODUCT_FROM_DATABASE=G-720 Keyboard + +usb:v1267p0201* + ID_PRODUCT_FROM_DATABASE=A4Tech SWOP-3 Mouse + +usb:v1267p0210* + ID_PRODUCT_FROM_DATABASE=LG Optical Mouse 3D-310 + +usb:v1267pA001* + ID_PRODUCT_FROM_DATABASE=JP260 PC Game Pad + +usb:v1267pC002* + ID_PRODUCT_FROM_DATABASE=Wireless Optical Mouse + +usb:v126C* + ID_VENDOR_FROM_DATABASE=Aristocrat Technologies + +usb:v126D* + ID_VENDOR_FROM_DATABASE=Bel Stewart + +usb:v126E* + ID_VENDOR_FROM_DATABASE=Strobe Data, Inc. + +usb:v126F* + ID_VENDOR_FROM_DATABASE=TwinMOS + +usb:v126Fp0163* + ID_PRODUCT_FROM_DATABASE=Storage device (2gB thumb drive) + +usb:v126Fp1325* + ID_PRODUCT_FROM_DATABASE=Mobile Disk + +usb:v126Fp2168* + ID_PRODUCT_FROM_DATABASE=Mobile Disk III + +usb:v126FpA006* + ID_PRODUCT_FROM_DATABASE=G240 802.11bg + +usb:v1274* + ID_VENDOR_FROM_DATABASE=Ensoniq + +usb:v1275* + ID_VENDOR_FROM_DATABASE=Xaxero Marine Software Engineering, Ltd. + +usb:v1275p0002* + ID_PRODUCT_FROM_DATABASE=WeatherFax 2000 Demodulator + +usb:v1275p0080* + ID_PRODUCT_FROM_DATABASE=SkyEye Weather Satellite Receiver + +usb:v1278* + ID_VENDOR_FROM_DATABASE=Starlight Xpress + +usb:v1278p0105* + ID_PRODUCT_FROM_DATABASE=SXV-M5 + +usb:v1278p0107* + ID_PRODUCT_FROM_DATABASE=SXV-M7 + +usb:v1278p0109* + ID_PRODUCT_FROM_DATABASE=SXV-M9 + +usb:v1278p0110* + ID_PRODUCT_FROM_DATABASE=SXVF-H16 + +usb:v1278p0115* + ID_PRODUCT_FROM_DATABASE=SXVF-H5 + +usb:v1278p0119* + ID_PRODUCT_FROM_DATABASE=SXV-H9 + +usb:v1278p0135* + ID_PRODUCT_FROM_DATABASE=SXVF-H35 + +usb:v1278p0136* + ID_PRODUCT_FROM_DATABASE=SXVF-H36 + +usb:v1278p0200* + ID_PRODUCT_FROM_DATABASE=SXV interface for paraller MX cameras + +usb:v1278p0305* + ID_PRODUCT_FROM_DATABASE=SXV-M5C + +usb:v1278p0307* + ID_PRODUCT_FROM_DATABASE=SXV-M7C + +usb:v1278p0319* + ID_PRODUCT_FROM_DATABASE=SXV-H9C + +usb:v1278p0325* + ID_PRODUCT_FROM_DATABASE=SXV-M25C + +usb:v1278p0326* + ID_PRODUCT_FROM_DATABASE=SXVR-M26C + +usb:v1278p0507* + ID_PRODUCT_FROM_DATABASE=Lodestar autoguider + +usb:v1278p0517* + ID_PRODUCT_FROM_DATABASE=CoStar + +usb:v1283* + ID_VENDOR_FROM_DATABASE=zebris Medical GmbH + +usb:v1283p0100* + ID_PRODUCT_FROM_DATABASE=USB-RS232 Adaptor + +usb:v1283p0110* + ID_PRODUCT_FROM_DATABASE=CMS20 + +usb:v1283p0111* + ID_PRODUCT_FROM_DATABASE=CMS 10 + +usb:v1283p0112* + ID_PRODUCT_FROM_DATABASE=CMS 05 + +usb:v1283p0114* + ID_PRODUCT_FROM_DATABASE=ARCUS digma PC-Interface + +usb:v1283p0115* + ID_PRODUCT_FROM_DATABASE=SAM Axioquick recorder + +usb:v1283p0116* + ID_PRODUCT_FROM_DATABASE=SAM Axioquick recorder + +usb:v1283p0120* + ID_PRODUCT_FROM_DATABASE=emed-X + +usb:v1283p0121* + ID_PRODUCT_FROM_DATABASE=emed-AT + +usb:v1283p0130* + ID_PRODUCT_FROM_DATABASE=PDM + +usb:v1283p0150* + ID_PRODUCT_FROM_DATABASE=CMS10GI (Golf) + +usb:v1286* + ID_VENDOR_FROM_DATABASE=Marvell Semiconductor, Inc. + +usb:v1286p1FAB* + ID_PRODUCT_FROM_DATABASE=88W8338 [Libertas] 802.11g + +usb:v1286p2001* + ID_PRODUCT_FROM_DATABASE=88W8388 802.11a/b/g WLAN + +usb:v1286p2006* + ID_PRODUCT_FROM_DATABASE=88W8362 802.11n WLAN + +usb:v1286p8001* + ID_PRODUCT_FROM_DATABASE=BLOB boot loader firmware + +usb:v1291* + ID_VENDOR_FROM_DATABASE=Qualcomm Flarion Technologies, Inc. / Leadtek Research, Inc. + +usb:v1291p0010* + ID_PRODUCT_FROM_DATABASE=FDM 2xxx Flash-OFDM modem + +usb:v1291p0011* + ID_PRODUCT_FROM_DATABASE=LR7F06/LR7F14 Flash-OFDM modem + +usb:v1292* + ID_VENDOR_FROM_DATABASE=Innomedia + +usb:v1292p0258* + ID_PRODUCT_FROM_DATABASE=Creative Labs VoIP Blaster + +usb:v1293* + ID_VENDOR_FROM_DATABASE=Belkin Components [hex] + +usb:v1293p0002* + ID_PRODUCT_FROM_DATABASE=F5U002 Parallel Port [uss720] + +usb:v1293p2101* + ID_PRODUCT_FROM_DATABASE=104-key keyboard + +usb:v1294* + ID_VENDOR_FROM_DATABASE=RISO KAGAKU CORP. + +usb:v129B* + ID_VENDOR_FROM_DATABASE=CyberTAN Technology + +usb:v129Bp160B* + ID_PRODUCT_FROM_DATABASE=Siemens S30853-S1031-R351 802.11g Wireless Adapter [Atheros AR5523] + +usb:v129Bp160C* + ID_PRODUCT_FROM_DATABASE=Siemens S30853-S1038-R351 802.11g Wireless Adapter [Atheros AR5523] + +usb:v129Bp1666* + ID_PRODUCT_FROM_DATABASE=TG54USB 802.11bg + +usb:v129Bp1667* + ID_PRODUCT_FROM_DATABASE=802.11bg + +usb:v129Bp1828* + ID_PRODUCT_FROM_DATABASE=Gigaset USB Adapter 300 + +usb:v12A7* + ID_VENDOR_FROM_DATABASE=Trendchip Technologies Corp. + +usb:v12AB* + ID_VENDOR_FROM_DATABASE=Honey Bee Electronic International Ltd. + +usb:v12B8* + ID_VENDOR_FROM_DATABASE=Zhejiang Xinya Electronic Technology Co., Ltd. + +usb:v12BA* + ID_VENDOR_FROM_DATABASE=Licensed by Sony Computer Entertainment America + +usb:v12BAp0100* + ID_PRODUCT_FROM_DATABASE=RedOctane Guitar for PlayStation(R)3 + +usb:v12BAp0120* + ID_PRODUCT_FROM_DATABASE=RedOctane Drum Kit for PlayStation(R)3 + +usb:v12BAp0200* + ID_PRODUCT_FROM_DATABASE=Harmonix Guitar for PlayStation(R)3 + +usb:v12BAp0210* + ID_PRODUCT_FROM_DATABASE=Harmonix Drum Kit for PlayStation(R)3 + +usb:v12C4* + ID_VENDOR_FROM_DATABASE=Autocue Group Ltd + +usb:v12C4p0006* + ID_PRODUCT_FROM_DATABASE=Teleprompter Two-button Hand Control (v1) + +usb:v12C4p0008* + ID_PRODUCT_FROM_DATABASE=Teleprompter Foot Control (v1) + +usb:v12D1* + ID_VENDOR_FROM_DATABASE=Huawei Technologies Co., Ltd. + +usb:v12D1p1001* + ID_PRODUCT_FROM_DATABASE=E169/E620/E800 HSDPA Modem + +usb:v12D1p1003* + ID_PRODUCT_FROM_DATABASE=E220 HSDPA Modem / E230/E270/E870 HSDPA/HSUPA Modem + +usb:v12D1p1004* + ID_PRODUCT_FROM_DATABASE=E220 (bis) + +usb:v12D1p1009* + ID_PRODUCT_FROM_DATABASE=U120 + +usb:v12D1p1010* + ID_PRODUCT_FROM_DATABASE=ETS2252+ CDMA Fixed Wireless Terminal + +usb:v12D1p1021* + ID_PRODUCT_FROM_DATABASE=U8520 + +usb:v12D1p1035* + ID_PRODUCT_FROM_DATABASE=U8120 + +usb:v12D1p1037* + ID_PRODUCT_FROM_DATABASE=Ideos + +usb:v12D1p1038* + ID_PRODUCT_FROM_DATABASE=Ideos (debug mode) + +usb:v12D1p1039* + ID_PRODUCT_FROM_DATABASE=Ideos (tethering mode) + +usb:v12D1p1406* + ID_PRODUCT_FROM_DATABASE=E1750 + +usb:v12D1p140B* + ID_PRODUCT_FROM_DATABASE=EC1260 Wireless Data Modem HSD USB Card + +usb:v12D1p1436* + ID_PRODUCT_FROM_DATABASE=E173 3G Modem (modem-mode) + +usb:v12D1p1446* + ID_PRODUCT_FROM_DATABASE=E1552/E1800/E173 (HSPA modem) + +usb:v12D1p1465* + ID_PRODUCT_FROM_DATABASE=K3765 HSPA + +usb:v12D1p14C3* + ID_PRODUCT_FROM_DATABASE=K5005 Vodafone LTE/UMTS/GSM Modem/Networkcard + +usb:v12D1p14C8* + ID_PRODUCT_FROM_DATABASE=K5005 Vodafone LTE/UMTS/GSM MOdem/Networkcard + +usb:v12D1p14C9* + ID_PRODUCT_FROM_DATABASE=K3770 3G Modem + +usb:v12D1p14D1* + ID_PRODUCT_FROM_DATABASE=K3770 3G Modem (Mass Storage Mode) + +usb:v12D1p14F1* + ID_PRODUCT_FROM_DATABASE=Gobi 3000 HSPA+ Modem + +usb:v12D1p1501* + ID_PRODUCT_FROM_DATABASE=Pulse + +usb:v12D1p1505* + ID_PRODUCT_FROM_DATABASE=E398 LTE/UMTS/GSM Modem/Networkcard + +usb:v12D1p1506* + ID_PRODUCT_FROM_DATABASE=E398 LTE/UMTS/GSM Modem/Networkcard + +usb:v12D1p150A* + ID_PRODUCT_FROM_DATABASE=E398 LTE/UMTS/GSM Modem/Networkcard + +usb:v12D1p1520* + ID_PRODUCT_FROM_DATABASE=K3765 HSPA + +usb:v12D1p1521* + ID_PRODUCT_FROM_DATABASE=K4505 HSPA+ + +usb:v12D1p1805* + ID_PRODUCT_FROM_DATABASE=AT&T Go Phone U2800A phone + +usb:v12D1p1C05* + ID_PRODUCT_FROM_DATABASE=E173s 3G broadband stick (modem on) + +usb:v12D1p1C0B* + ID_PRODUCT_FROM_DATABASE=E173s 3G broadband stick (modem off) + +usb:v12D1p1D50* + ID_PRODUCT_FROM_DATABASE=ET302s TD-SCDMA/TD-HSDPA Mobile Broadband + +usb:v12D1p380B* + ID_PRODUCT_FROM_DATABASE=WiMAX USB modem(s) + +usb:v12D2* + ID_VENDOR_FROM_DATABASE=LINE TECH INDUSTRIAL CO., LTD. + +usb:v12D6* + ID_VENDOR_FROM_DATABASE=EMS Dr. Thomas Wuensche + +usb:v12D6p0444* + ID_PRODUCT_FROM_DATABASE=CPC-USB/ARM7 + +usb:v12D6p0888* + ID_PRODUCT_FROM_DATABASE=CPC-USB/M16C + +usb:v12D7* + ID_VENDOR_FROM_DATABASE=BETTER WIRE FACTORY CO., LTD. + +usb:v12E6* + ID_VENDOR_FROM_DATABASE=Waldorf Music GmbH + +usb:v12E6p0013* + ID_PRODUCT_FROM_DATABASE=Blofeld + +usb:v12EF* + ID_VENDOR_FROM_DATABASE=Tapwave, Inc. + +usb:v12EFp0100* + ID_PRODUCT_FROM_DATABASE=Tapwave Handheld [Tapwave Zodiac] + +usb:v12F5* + ID_VENDOR_FROM_DATABASE=Dynamic System Electronics Corp. + +usb:v12F7* + ID_VENDOR_FROM_DATABASE=Memorex Products, Inc. + +usb:v12F7p1A00* + ID_PRODUCT_FROM_DATABASE=TD Classic 003B + +usb:v12F7p1E23* + ID_PRODUCT_FROM_DATABASE=TravelDrive 2007 Flash Drive + +usb:v12FD* + ID_VENDOR_FROM_DATABASE=AIN Comm. Technology Co., Ltd + +usb:v12FDp1001* + ID_PRODUCT_FROM_DATABASE=AWU2000b 802.11b Stick + +usb:v12FF* + ID_VENDOR_FROM_DATABASE=Fascinating Electronics, Inc. + +usb:v12FFp0101* + ID_PRODUCT_FROM_DATABASE=Advanced RC Servo Controller + +usb:v1307* + ID_VENDOR_FROM_DATABASE=Transcend Information, Inc. + +usb:v1307p0163* + ID_PRODUCT_FROM_DATABASE=256MB/512MB/1GB Flash Drive + +usb:v1307p0165* + ID_PRODUCT_FROM_DATABASE=2GB/4GB Flash Drive + +usb:v1307p0190* + ID_PRODUCT_FROM_DATABASE=Ut190 8 GB Flash Drive with MicroSD reader + +usb:v1307p0310* + ID_PRODUCT_FROM_DATABASE=SD/MicroSD CardReader [hama] + +usb:v1307p0330* + ID_PRODUCT_FROM_DATABASE=63-in-1 Multi-Card Reader/Writer + +usb:v1307p0361* + ID_PRODUCT_FROM_DATABASE=CR-75: 51-in-1 Card Reader/Writer [Sakar] + +usb:v1307p1169* + ID_PRODUCT_FROM_DATABASE=TS2GJF210 JetFlash 210 2GB + +usb:v1307p1171* + ID_PRODUCT_FROM_DATABASE=Fingerprint Reader + +usb:v1308* + ID_VENDOR_FROM_DATABASE=Shuttle, Inc. + +usb:v1308p0003* + ID_PRODUCT_FROM_DATABASE=VFD Module + +usb:v1308pC001* + ID_PRODUCT_FROM_DATABASE=eHome Infrared Transceiver + +usb:v1310* + ID_VENDOR_FROM_DATABASE=Roper + +usb:v1310p0001* + ID_PRODUCT_FROM_DATABASE=Class 1 Bluetooth Dongle + +usb:v1312* + ID_VENDOR_FROM_DATABASE=ICS Electronics + +usb:v131D* + ID_VENDOR_FROM_DATABASE=Natural Point + +usb:v131Dp0155* + ID_PRODUCT_FROM_DATABASE=TrackIR 3 Pro Head Tracker + +usb:v131Dp0156* + ID_PRODUCT_FROM_DATABASE=TrackIR 4 Pro Head Tracker + +usb:v132A* + ID_VENDOR_FROM_DATABASE=Envara Inc. + +usb:v132Ap1502* + ID_PRODUCT_FROM_DATABASE=WiND 802.11abg / 802.11bg WLAN + +usb:v132B* + ID_VENDOR_FROM_DATABASE=Konica Minolta + +usb:v132Bp0000* + ID_PRODUCT_FROM_DATABASE=Dimage A2 Camera + +usb:v132Bp0001* + ID_PRODUCT_FROM_DATABASE=Minolta DiMAGE A2 (ptp) + +usb:v132Bp0003* + ID_PRODUCT_FROM_DATABASE=Dimage Xg Camera + +usb:v132Bp0006* + ID_PRODUCT_FROM_DATABASE=Dimage Z2 Camera + +usb:v132Bp0007* + ID_PRODUCT_FROM_DATABASE=Minolta DiMAGE Z2 (PictBridge mode) + +usb:v132Bp0008* + ID_PRODUCT_FROM_DATABASE=Dimage X21 Camera + +usb:v132Bp000A* + ID_PRODUCT_FROM_DATABASE=Dimage Scan Dual IV AF-3200 (2891) + +usb:v132Bp000B* + ID_PRODUCT_FROM_DATABASE=Dimage Z10 Camera + +usb:v132Bp000D* + ID_PRODUCT_FROM_DATABASE=Dimage X50 Camera [storage?] + +usb:v132Bp000F* + ID_PRODUCT_FROM_DATABASE=Dimage X50 Camera [p2p?] + +usb:v132Bp0010* + ID_PRODUCT_FROM_DATABASE=Dimage G600 Camera + +usb:v132Bp0012* + ID_PRODUCT_FROM_DATABASE=Dimage Scan Elite 5400 II (2892) + +usb:v132Bp0013* + ID_PRODUCT_FROM_DATABASE=Dimage X31 Camera + +usb:v132Bp0015* + ID_PRODUCT_FROM_DATABASE=Dimage G530 Camera + +usb:v132Bp0017* + ID_PRODUCT_FROM_DATABASE=Dimage Z3 Camera + +usb:v132Bp0018* + ID_PRODUCT_FROM_DATABASE=Minolta DiMAGE Z3 (PictBridge mode) + +usb:v132Bp0019* + ID_PRODUCT_FROM_DATABASE=Dimage A200 Camera + +usb:v132Bp0021* + ID_PRODUCT_FROM_DATABASE=Dimage Z5 Camera + +usb:v132Bp0022* + ID_PRODUCT_FROM_DATABASE=Minolta DiMAGE Z5 (PictBridge mode) + +usb:v132Bp002C* + ID_PRODUCT_FROM_DATABASE=Dynax 5D camera + +usb:v132Bp2001* + ID_PRODUCT_FROM_DATABASE=Magicolor 2400w + +usb:v132Bp2004* + ID_PRODUCT_FROM_DATABASE=Magicolor 5430DL + +usb:v132Bp2005* + ID_PRODUCT_FROM_DATABASE=Magicolor 2430 DL + +usb:v132Bp2029* + ID_PRODUCT_FROM_DATABASE=Magicolor 5440DL + +usb:v132Bp2030* + ID_PRODUCT_FROM_DATABASE=PagePro 1350E(N) + +usb:v132Bp2033* + ID_PRODUCT_FROM_DATABASE=PagePro 1400W + +usb:v132Bp2043* + ID_PRODUCT_FROM_DATABASE=Magicolor 2530DL + +usb:v132Bp2045* + ID_PRODUCT_FROM_DATABASE=Magicolor 2500W + +usb:v132Bp2049* + ID_PRODUCT_FROM_DATABASE=Magicolor 2490MF + +usb:v1342* + ID_VENDOR_FROM_DATABASE=Mobility + +usb:v1342p0200* + ID_PRODUCT_FROM_DATABASE=EasiDock 200 Hub + +usb:v1342p0201* + ID_PRODUCT_FROM_DATABASE=EasiDock 200 Keyboard and Mouse Port + +usb:v1342p0202* + ID_PRODUCT_FROM_DATABASE=EasiDock 200 Serial Port + +usb:v1342p0203* + ID_PRODUCT_FROM_DATABASE=EasiDock 200 Printer Port + +usb:v1342p0204* + ID_PRODUCT_FROM_DATABASE=Ethernet + +usb:v1342p0304* + ID_PRODUCT_FROM_DATABASE=EasiDock Ethernet + +usb:v1345* + ID_VENDOR_FROM_DATABASE=Sino Lite Technology Corp. + +usb:v1345p001C* + ID_PRODUCT_FROM_DATABASE=Xbox Controller Hub + +usb:v1347* + ID_VENDOR_FROM_DATABASE=Moravian Instruments + +usb:v1347p0400* + ID_PRODUCT_FROM_DATABASE=G2CCD USB 1.1 obsolete + +usb:v1347p0401* + ID_PRODUCT_FROM_DATABASE=G2CCD-S with Sony ICX285 CCD + +usb:v1347p0402* + ID_PRODUCT_FROM_DATABASE=G2CCD2 + +usb:v1347p0403* + ID_PRODUCT_FROM_DATABASE=G2/G3CCD-I KAI CCD + +usb:v1347p0404* + ID_PRODUCT_FROM_DATABASE=G2/G3/G4 CCD-F KAF CCD + +usb:v1347p0410* + ID_PRODUCT_FROM_DATABASE=G1-0400 CCD + +usb:v1347p0411* + ID_PRODUCT_FROM_DATABASE=G1-0800 CCD + +usb:v1347p0412* + ID_PRODUCT_FROM_DATABASE=G1-0300 CCD + +usb:v1347p0413* + ID_PRODUCT_FROM_DATABASE=G1-2000 CCD + +usb:v1347p0414* + ID_PRODUCT_FROM_DATABASE=G1-1400 CCD + +usb:v1348* + ID_VENDOR_FROM_DATABASE=Katsuragawa Electric Co., Ltd. + +usb:v134C* + ID_VENDOR_FROM_DATABASE=PanJit International Inc. + +usb:v134Cp0001* + ID_PRODUCT_FROM_DATABASE=Touch Panel Controller + +usb:v134Cp0002* + ID_PRODUCT_FROM_DATABASE=Touch Panel Controller + +usb:v134Cp0003* + ID_PRODUCT_FROM_DATABASE=Touch Panel Controller + +usb:v134Cp0004* + ID_PRODUCT_FROM_DATABASE=Touch Panel Controller + +usb:v134E* + ID_VENDOR_FROM_DATABASE=Digby's Bitpile, Inc. DBA D Bit + +usb:v1357* + ID_VENDOR_FROM_DATABASE=P&E Microcomputer Systems + +usb:v1357p0503* + ID_PRODUCT_FROM_DATABASE=USB-ML-12 HCS08/HCS12 Multilink + +usb:v1357p0504* + ID_PRODUCT_FROM_DATABASE=DEMOJM + +usb:v1366* + ID_VENDOR_FROM_DATABASE=SEGGER + +usb:v1366p0101* + ID_PRODUCT_FROM_DATABASE=J-Link ARM + +usb:v136B* + ID_VENDOR_FROM_DATABASE=STEC + +usb:v1370* + ID_VENDOR_FROM_DATABASE=Swissbit + +usb:v1370p0323* + ID_PRODUCT_FROM_DATABASE=Swissmemory cirrusWHITE + +usb:v1370p6828* + ID_PRODUCT_FROM_DATABASE=Victorinox Flash Drive + +usb:v1371* + ID_VENDOR_FROM_DATABASE=CNet Technology Inc. + +usb:v1371p0001* + ID_PRODUCT_FROM_DATABASE=CNUSB-611AR Wireless Adapter-G [AT76C503] + +usb:v1371p0002* + ID_PRODUCT_FROM_DATABASE=CNUSB-611AR Wireless Adapter-G [AT76C503] (FiberLine WL-240U) + +usb:v1371p0013* + ID_PRODUCT_FROM_DATABASE=CNUSB-611 Wireless Adapter [AT76C505] + +usb:v1371p0014* + ID_PRODUCT_FROM_DATABASE=CNUSB-611 Wireless Adapter [AT76C505] (FiberLine WL-240U) + +usb:v1371p5743* + ID_PRODUCT_FROM_DATABASE=CNUSB-611 (D) Wireless Adapter [AT76C503] + +usb:v1371p9022* + ID_PRODUCT_FROM_DATABASE=CWD-854 [RT2573] + +usb:v1371p9032* + ID_PRODUCT_FROM_DATABASE=CWD-854 rev F + +usb:v1371p9401* + ID_PRODUCT_FROM_DATABASE=CWD-854 Wireless 802.11g 54Mbps Network Adapter [RTL8187] + +usb:v1376* + ID_VENDOR_FROM_DATABASE=Vimtron Electronics Co., Ltd. + +usb:v137B* + ID_VENDOR_FROM_DATABASE=SCAPS GmbH + +usb:v137Bp0002* + ID_PRODUCT_FROM_DATABASE=SCAPS USC-2 Scanner Controller + +usb:v1385* + ID_VENDOR_FROM_DATABASE=Netgear, Inc + +usb:v1385p4250* + ID_PRODUCT_FROM_DATABASE=WG111T + +usb:v1385p4251* + ID_PRODUCT_FROM_DATABASE=WG111T (no firmware) + +usb:v1385p5F00* + ID_PRODUCT_FROM_DATABASE=WPN111 RangeMax(TM) Wireless USB 2.0 Adapter + +usb:v1385p5F01* + ID_PRODUCT_FROM_DATABASE=WPN111 (no firmware) + +usb:v1385p5F02* + ID_PRODUCT_FROM_DATABASE=WPN111 (no firmware) + +usb:v1385p6E00* + ID_PRODUCT_FROM_DATABASE=WPNT121 802.11g 240Mbps Wireless Adapter [Airgo AGN300] + +usb:v138A* + ID_VENDOR_FROM_DATABASE=Validity Sensors, Inc. + +usb:v138Ap0001* + ID_PRODUCT_FROM_DATABASE=VFS101 Fingerprint Reader + +usb:v138Ap0005* + ID_PRODUCT_FROM_DATABASE=VFS301 Fingerprint Reader + +usb:v138Ap0007* + ID_PRODUCT_FROM_DATABASE=VFS451 Fingerprint Reader + +usb:v138Ap0008* + ID_PRODUCT_FROM_DATABASE=VFS300 Fingerprint Reader + +usb:v138Ap0011* + ID_PRODUCT_FROM_DATABASE=VFS5011 Fingerprint Reader + +usb:v138Ap003C* + ID_PRODUCT_FROM_DATABASE=VFS471 Fingerprint Reader + +usb:v138E* + ID_VENDOR_FROM_DATABASE=Jungo LTD + +usb:v138Ep9000* + ID_PRODUCT_FROM_DATABASE=Raisonance S.A. STM32 ARM evaluation board + +usb:v1390* + ID_VENDOR_FROM_DATABASE=TOMTOM B.V. + +usb:v1390p0001* + ID_PRODUCT_FROM_DATABASE=GO 520 T/GO 630/ONE XL (v9) + +usb:v1391* + ID_VENDOR_FROM_DATABASE=IdealTEK, Inc. + +usb:v1391p1000* + ID_PRODUCT_FROM_DATABASE=URTC-1000 + +usb:v1395* + ID_VENDOR_FROM_DATABASE=Sennheiser Communications + +usb:v1395p3556* + ID_PRODUCT_FROM_DATABASE=USB Headset + +usb:v1397* + ID_VENDOR_FROM_DATABASE=BEHRINGER International GmbH + +usb:v1397p00BC* + ID_PRODUCT_FROM_DATABASE=BCF2000 + +usb:v1398* + ID_VENDOR_FROM_DATABASE=Q-tec + +usb:v1398p2103* + ID_PRODUCT_FROM_DATABASE=USB 2.0 Storage Device + +usb:v13AD* + ID_VENDOR_FROM_DATABASE=Baltech + +usb:v13ADp9999* + ID_PRODUCT_FROM_DATABASE=Card reader + +usb:v13B0* + ID_VENDOR_FROM_DATABASE=PerkinElmer Optoelectronics + +usb:v13B0p000A* + ID_PRODUCT_FROM_DATABASE=Alesis Photon X25 MIDI Controller + +usb:v13B1* + ID_VENDOR_FROM_DATABASE=Linksys + +usb:v13B1p000A* + ID_PRODUCT_FROM_DATABASE=WUSB54G v2 802.11g Adapter [Intersil ISL3887] + +usb:v13B1p000B* + ID_PRODUCT_FROM_DATABASE=WUSB11 v4.0 802.11b Adapter [ALi M4301] + +usb:v13B1p000C* + ID_PRODUCT_FROM_DATABASE=WUSB54AG 802.11a/g Adapter [Intersil ISL3887] + +usb:v13B1p000D* + ID_PRODUCT_FROM_DATABASE=WUSB54G v4 802.11g Adapter [Ralink RT2500USB] + +usb:v13B1p000E* + ID_PRODUCT_FROM_DATABASE=WUSB54GS v1 802.11g Adapter [Broadcom 4320 USB] + +usb:v13B1p0011* + ID_PRODUCT_FROM_DATABASE=WUSB54GP v4.0 802.11g Adapter [Ralink RT2500USB] + +usb:v13B1p0014* + ID_PRODUCT_FROM_DATABASE=WUSB54GS v2 802.11g Adapter [Broadcom 4320 USB] + +usb:v13B1p0018* + ID_PRODUCT_FROM_DATABASE=USB200M 10/100 Ethernet Adapter + +usb:v13B1p001A* + ID_PRODUCT_FROM_DATABASE=HU200TS Wireless Adapter + +usb:v13B1p001E* + ID_PRODUCT_FROM_DATABASE=WUSBF54G 802.11bg + +usb:v13B1p0020* + ID_PRODUCT_FROM_DATABASE=WUSB54GC v1 802.11g Adapter [Ralink RT73] + +usb:v13B1p0022* + ID_PRODUCT_FROM_DATABASE=WUSB54GX4 802.11g 240Mbps Wireless Adapter [Airgo AGN300] + +usb:v13B1p0023* + ID_PRODUCT_FROM_DATABASE=WUSB54GR + +usb:v13B1p0024* + ID_PRODUCT_FROM_DATABASE=WUSBF54G v1.1 802.11bg + +usb:v13B1p0026* + ID_PRODUCT_FROM_DATABASE=WUSB54GSC v1 802.11g Adapter [Broadcom 4320 USB] + +usb:v13B1p0028* + ID_PRODUCT_FROM_DATABASE=WUSB200 802.11g Adapter [Ralink RT2671] + +usb:v13B1p0029* + ID_PRODUCT_FROM_DATABASE=WUSB300N 802.11bgn Wireless Adapter [Marvell 88W8362+88W8060] + +usb:v13B1p002F* + ID_PRODUCT_FROM_DATABASE=AE1000 v1 802.11n [Ralink RT3572] + +usb:v13B1p0031* + ID_PRODUCT_FROM_DATABASE=AM10 v1 802.11n [Ralink RT3072] + +usb:v13B1p0039* + ID_PRODUCT_FROM_DATABASE=AE1200 802.11bgn Wireless Adapter [Broadcom BCM43235] + +usb:v13B1p003A* + ID_PRODUCT_FROM_DATABASE=AE2500 802.11abgn Wireless Adapter [Broadcom BCM43236] + +usb:v13B1p13B1* + ID_PRODUCT_FROM_DATABASE=WUSB200: Wireless-G Business Network Adapter with Rangebooster + +usb:v13B2* + ID_VENDOR_FROM_DATABASE=Alesis + +usb:v13B2p0030* + ID_PRODUCT_FROM_DATABASE=Multimix 8 + +usb:v13B3* + ID_VENDOR_FROM_DATABASE=Nippon Dics Co., Ltd. + +usb:v13BA* + ID_VENDOR_FROM_DATABASE=PCPlay + +usb:v13BAp0017* + ID_PRODUCT_FROM_DATABASE=PS/2 Keyboard+Mouse Adapter + +usb:v13BAp0018* + ID_PRODUCT_FROM_DATABASE=Barcode PCP-BCG4209 + +usb:v13BE* + ID_VENDOR_FROM_DATABASE=Ricoh Printing Systems, Ltd. + +usb:v13CA* + ID_VENDOR_FROM_DATABASE=JyeTai Precision Industrial Co., Ltd. + +usb:v13CF* + ID_VENDOR_FROM_DATABASE=Wisair Ltd. + +usb:v13CFp1200* + ID_PRODUCT_FROM_DATABASE=Olidata Wireless Multimedia Adapter + +usb:v13D0* + ID_VENDOR_FROM_DATABASE=Techsan Electronics Co., Ltd. + +usb:v13D0p2282* + ID_PRODUCT_FROM_DATABASE=TechniSat DVB-PC TV Star 2 + +usb:v13D1* + ID_VENDOR_FROM_DATABASE=A-Max Technology Macao Commercial Offshore Co. Ltd. + +usb:v13D1p7019* + ID_PRODUCT_FROM_DATABASE=MD 82288 + +usb:v13D1pABE6* + ID_PRODUCT_FROM_DATABASE=Wireless 802.11g 54Mbps Network Adapter [RTL8187] + +usb:v13D2* + ID_VENDOR_FROM_DATABASE=Shark Multimedia + +usb:v13D2p0400* + ID_PRODUCT_FROM_DATABASE=Pocket Ethernet [klsi] + +usb:v13D3* + ID_VENDOR_FROM_DATABASE=IMC Networks + +usb:v13D3p3201* + ID_PRODUCT_FROM_DATABASE=VisionDTV USB-Ter/HAMA USB DVB-T device cold + +usb:v13D3p3202* + ID_PRODUCT_FROM_DATABASE=VisionDTV USB-Ter/HAMA USB DVB-T device warm + +usb:v13D3p3203* + ID_PRODUCT_FROM_DATABASE=DTV-DVB UDST7020BDA DVB-S Box(DVBS for MCE2005) + +usb:v13D3p3204* + ID_PRODUCT_FROM_DATABASE=DTV-DVB UDST7020BDA DVB-S Box(DVBS for MCE2005) + +usb:v13D3p3205* + ID_PRODUCT_FROM_DATABASE=DNTV Live! Tiny USB2 BDA (No Remote) + +usb:v13D3p3206* + ID_PRODUCT_FROM_DATABASE=DNTV Live! Tiny USB2 BDA (No Remote) + +usb:v13D3p3207* + ID_PRODUCT_FROM_DATABASE=DTV-DVB UDST7020BDA DVB-S Box(DVBS for MCE2005) + +usb:v13D3p3208* + ID_PRODUCT_FROM_DATABASE=DTV-DVB UDST7020BDA DVB-S Box(DVBS for MCE2005) + +usb:v13D3p3209* + ID_PRODUCT_FROM_DATABASE=DTV-DVB UDST7022BDA DVB-S Box(Without HID) + +usb:v13D3p3211* + ID_PRODUCT_FROM_DATABASE=DTV-DVB Hybrid Analog/Capture / Pinnacle PCTV 310e + +usb:v13D3p3212* + ID_PRODUCT_FROM_DATABASE=DTV-DVB UDTT704C - DVBT/NTSC/PAL Driver(PCM4) + +usb:v13D3p3213* + ID_PRODUCT_FROM_DATABASE=DTV-DVB UDTT704D - DVBT/NTSC/PAL Driver (PCM4) + +usb:v13D3p3214* + ID_PRODUCT_FROM_DATABASE=DTV-DVB UDTT704F -(MiniCard) DVBT/NTSC/PAL Driver(Without HID) + +usb:v13D3p3215* + ID_PRODUCT_FROM_DATABASE=DTV-DVB UDAT7240 - ATSC/NTSC/PAL Driver(PCM4) + +usb:v13D3p3216* + ID_PRODUCT_FROM_DATABASE=DTV-DVB UDTT 7047-USB 2.0 DVB-T Driver + +usb:v13D3p3217* + ID_PRODUCT_FROM_DATABASE=Digital-TV Receiver. + +usb:v13D3p3219* + ID_PRODUCT_FROM_DATABASE=DTV-DVB UDTT7049 - DVB-T Driver(Without HID) + +usb:v13D3p3220* + ID_PRODUCT_FROM_DATABASE=DTV-DVB UDTT 7047M-USB 2.0 DVB-T Driver + +usb:v13D3p3223* + ID_PRODUCT_FROM_DATABASE=DNTV Live! Tiny USB2 BDA (No Remote) + +usb:v13D3p3224* + ID_PRODUCT_FROM_DATABASE=DNTV Live! Tiny USB2 BDA (No Remote) + +usb:v13D3p3226* + ID_PRODUCT_FROM_DATABASE=DigitalNow TinyTwin DVB-T Receiver + +usb:v13D3p3234* + ID_PRODUCT_FROM_DATABASE=DVB-T FTA Half Minicard [RTL2832U] + +usb:v13D3p3236* + ID_PRODUCT_FROM_DATABASE=DTV-DVB UDTT 7047A-USB 2.0 DVB-T Driver + +usb:v13D3p3237* + ID_PRODUCT_FROM_DATABASE=DTV-DVB UDTT 704J - dual DVB-T Driver + +usb:v13D3p3239* + ID_PRODUCT_FROM_DATABASE=DTV-DVB UDTT704D - DVBT/NTSC/PAL Driver(Without HID) + +usb:v13D3p3240* + ID_PRODUCT_FROM_DATABASE=DTV-DVB UDXTTM6010 - A/D Driver(Without HID) + +usb:v13D3p3241* + ID_PRODUCT_FROM_DATABASE=DTV-DVB UDXTTM6010 - A/D Driver(Without HID) + +usb:v13D3p3242* + ID_PRODUCT_FROM_DATABASE=DTV-DVB UDAT7240LP - ATSC/NTSC/PAL Driver(Without HID) + +usb:v13D3p3243* + ID_PRODUCT_FROM_DATABASE=DTV-DVB UDXTTM6010 - A/D Driver(Without HID) + +usb:v13D3p3244* + ID_PRODUCT_FROM_DATABASE=DTV-DVB UDTT 7047Z-USB 2.0 DVB-T Driver + +usb:v13D3p3247* + ID_PRODUCT_FROM_DATABASE=802.11 n/g/b Wireless LAN Adapter + +usb:v13D3p3249* + ID_PRODUCT_FROM_DATABASE=Internal Bluetooth + +usb:v13D3p3262* + ID_PRODUCT_FROM_DATABASE=802.11 n/g/b Wireless LAN USB Adapter + +usb:v13D3p3273* + ID_PRODUCT_FROM_DATABASE=802.11 n/g/b Wireless LAN USB Mini-Card + +usb:v13D3p3274* + ID_PRODUCT_FROM_DATABASE=DVB-T Dongle [RTL2832U] + +usb:v13D3p3282* + ID_PRODUCT_FROM_DATABASE=DVB-T + GPS Minicard [RTL2832U] + +usb:v13D3p3284* + ID_PRODUCT_FROM_DATABASE=Wireless LAN USB Mini-Card + +usb:v13D3p3304* + ID_PRODUCT_FROM_DATABASE=Asus Integrated Bluetooth module [AR3011] + +usb:v13D3p3306* + ID_PRODUCT_FROM_DATABASE=Mediao 802.11n WLAN [Realtek RTL8191SU] + +usb:v13D3p3315* + ID_PRODUCT_FROM_DATABASE=Bluetooth module + +usb:v13D3p5070* + ID_PRODUCT_FROM_DATABASE=Webcam + +usb:v13D3p5111* + ID_PRODUCT_FROM_DATABASE=Integrated Webcam + +usb:v13D3p5115* + ID_PRODUCT_FROM_DATABASE=Integrated Webcam + +usb:v13D3p5116* + ID_PRODUCT_FROM_DATABASE=Integrated Webcam + +usb:v13D3p5126* + ID_PRODUCT_FROM_DATABASE=PC Cam + +usb:v13D3p5702* + ID_PRODUCT_FROM_DATABASE=UVC VGA Webcam + +usb:v13D3p5716* + ID_PRODUCT_FROM_DATABASE=UVC VGA Webcam + +usb:v13D3p7020* + ID_PRODUCT_FROM_DATABASE=DTV-DVB UDST7020BDA DVB-S Box(DVBS for MCE2005) + +usb:v13D3p7022* + ID_PRODUCT_FROM_DATABASE=DTV-DVB UDST7022BDA DVB-S Box(Without HID) + +usb:v13DC* + ID_VENDOR_FROM_DATABASE=ALEREON, INC. + +usb:v13DD* + ID_VENDOR_FROM_DATABASE=i.Tech Dynamic Limited + +usb:v13E1* + ID_VENDOR_FROM_DATABASE=Kaibo Wire & Cable (Shenzhen) Co., Ltd. + +usb:v13E5* + ID_VENDOR_FROM_DATABASE=Rane + +usb:v13E5p0001* + ID_PRODUCT_FROM_DATABASE=SL-1 + +usb:v13E5p0003* + ID_PRODUCT_FROM_DATABASE=TTM 57SL + +usb:v13E6* + ID_VENDOR_FROM_DATABASE=TechnoScope Co., Ltd. + +usb:v13EA* + ID_VENDOR_FROM_DATABASE=Hengstler + +usb:v13EAp0001* + ID_PRODUCT_FROM_DATABASE=C-56 Thermal Printer + +usb:v13EC* + ID_VENDOR_FROM_DATABASE=Zydacron + +usb:v13ECp0006* + ID_PRODUCT_FROM_DATABASE=HID Remote Control + +usb:v13EE* + ID_VENDOR_FROM_DATABASE=MosArt + +usb:v13EEp0003* + ID_PRODUCT_FROM_DATABASE=Optical Mouse + +usb:v13FD* + ID_VENDOR_FROM_DATABASE=Initio Corporation + +usb:v13FDp0840* + ID_PRODUCT_FROM_DATABASE=INIC-1618L SATA + +usb:v13FDp0841* + ID_PRODUCT_FROM_DATABASE=Samsung SE-T084M DVD-RW + +usb:v13FDp1340* + ID_PRODUCT_FROM_DATABASE=Hi-Speed USB to SATA Bridge + +usb:v13FDp160F* + ID_PRODUCT_FROM_DATABASE=RocketFish SATA Bridge [INIC-1611] + +usb:v13FDp1640* + ID_PRODUCT_FROM_DATABASE=ASUS SDRW-08D1S-U DVD-RW + +usb:v13FDp1840* + ID_PRODUCT_FROM_DATABASE=INIC-1608 SATA bridge + +usb:v13FE* + ID_VENDOR_FROM_DATABASE=Kingston Technology Company Inc. + +usb:v13FEp1A00* + ID_PRODUCT_FROM_DATABASE=512MB/1GB Flash Drive + +usb:v13FEp1A23* + ID_PRODUCT_FROM_DATABASE=512MB Flash Drive + +usb:v13FEp1D00* + ID_PRODUCT_FROM_DATABASE=DataTraveler 2.0 1GB/4GB Flash Drive / Patriot Xporter 4GB Flash Drive + +usb:v13FEp1E00* + ID_PRODUCT_FROM_DATABASE=Flash Drive 2 GB [ICIDU 2 GB] + +usb:v13FEp1E50* + ID_PRODUCT_FROM_DATABASE=U3 Smart Drive + +usb:v13FEp1F00* + ID_PRODUCT_FROM_DATABASE=DataTraveler 2.0 4GB Flash Drive / Patriot Xporter 32GB (PEF32GUSB) Flash Drive + +usb:v13FEp2240* + ID_PRODUCT_FROM_DATABASE=microSD card reader + +usb:v13FEp3100* + ID_PRODUCT_FROM_DATABASE=2/4 GB stick + +usb:v13FEp3800* + ID_PRODUCT_FROM_DATABASE=Rage XT Flash Drive + +usb:v13FEp3E00* + ID_PRODUCT_FROM_DATABASE=Flash Drive + +usb:v13FEp5100* + ID_PRODUCT_FROM_DATABASE=Flash Drive + +usb:v1400* + ID_VENDOR_FROM_DATABASE=Axxion Group Corp. + +usb:v1402* + ID_VENDOR_FROM_DATABASE=Bowe Bell & Howell + +usb:v1403* + ID_VENDOR_FROM_DATABASE=Sitronix + +usb:v1403p0001* + ID_PRODUCT_FROM_DATABASE=Digital Photo Frame + +usb:v140E* + ID_VENDOR_FROM_DATABASE=Telechips, Inc. + +usb:v140EpB011* + ID_PRODUCT_FROM_DATABASE=TCC780X-based player (USB Boot mode) + +usb:v140EpB021* + ID_PRODUCT_FROM_DATABASE=TCC77X-based players (USB Boot mode) + +usb:v1410* + ID_VENDOR_FROM_DATABASE=Novatel Wireless + +usb:v1410p1110* + ID_PRODUCT_FROM_DATABASE=Merlin S620 + +usb:v1410p1120* + ID_PRODUCT_FROM_DATABASE=Merlin EX720 + +usb:v1410p1130* + ID_PRODUCT_FROM_DATABASE=Merlin S720 + +usb:v1410p1400* + ID_PRODUCT_FROM_DATABASE=Merlin U730/U740 (Vodafone) + +usb:v1410p1410* + ID_PRODUCT_FROM_DATABASE=Merlin U740 (non-Vodafone) + +usb:v1410p1430* + ID_PRODUCT_FROM_DATABASE=Merlin XU870 + +usb:v1410p1450* + ID_PRODUCT_FROM_DATABASE=Merlin X950D + +usb:v1410p2110* + ID_PRODUCT_FROM_DATABASE=Ovation U720/MCD3000 + +usb:v1410p2410* + ID_PRODUCT_FROM_DATABASE=Expedite EU740 + +usb:v1410p2420* + ID_PRODUCT_FROM_DATABASE=Expedite EU850D/EU860D/EU870D + +usb:v1410p4100* + ID_PRODUCT_FROM_DATABASE=U727 + +usb:v1410p4400* + ID_PRODUCT_FROM_DATABASE=Ovation MC930D/MC950D + +usb:v1410pA001* + ID_PRODUCT_FROM_DATABASE=Gobi Wireless Modem + +usb:v1410pA008* + ID_PRODUCT_FROM_DATABASE=Gobi Wireless Modem (QDL mode) + +usb:v1415* + ID_VENDOR_FROM_DATABASE=Nam Tai E&E Products Ltd. or OmniVision Technologies, Inc. + +usb:v1415p0000* + ID_PRODUCT_FROM_DATABASE=Sony SingStar USBMIC + +usb:v1415p0020* + ID_PRODUCT_FROM_DATABASE=Sony Wireless SingStar + +usb:v1415p2000* + ID_PRODUCT_FROM_DATABASE=Sony Playstation Eye + +usb:v1419* + ID_VENDOR_FROM_DATABASE=ABILITY ENTERPRISE CO., LTD. + +usb:v1429* + ID_VENDOR_FROM_DATABASE=Vega Technologies Industrial (Austria) Co. + +usb:v142A* + ID_VENDOR_FROM_DATABASE=Thales E-Transactions + +usb:v142Ap0003* + ID_PRODUCT_FROM_DATABASE=Artema Hybrid + +usb:v142Ap0005* + ID_PRODUCT_FROM_DATABASE=Artema Modular + +usb:v142Ap0043* + ID_PRODUCT_FROM_DATABASE=medCompact + +usb:v142B* + ID_VENDOR_FROM_DATABASE=Arbiter Systems, Inc. + +usb:v142Bp03A5* + ID_PRODUCT_FROM_DATABASE=933A Portable Power Sentinel + +usb:v1430* + ID_VENDOR_FROM_DATABASE=RedOctane + +usb:v1430p0150* + ID_PRODUCT_FROM_DATABASE=wireless receiver for skylanders wii + +usb:v1430p4734* + ID_PRODUCT_FROM_DATABASE=Guitar Hero4 hub + +usb:v1430p474B* + ID_PRODUCT_FROM_DATABASE=Guitar Hero MIDI interface + +usb:v1431* + ID_VENDOR_FROM_DATABASE=Pertech Resources, Inc. + +usb:v1435* + ID_VENDOR_FROM_DATABASE=Wistron NeWeb + +usb:v1435p0427* + ID_PRODUCT_FROM_DATABASE=UR054g 802.11g Wireless Adapter [Intersil ISL3887] + +usb:v1435p0711* + ID_PRODUCT_FROM_DATABASE=UR055G 802.11bg + +usb:v1435p0804* + ID_PRODUCT_FROM_DATABASE=AR9170+AR9104 802.11abgn Wireless Adapter + +usb:v1435p0826* + ID_PRODUCT_FROM_DATABASE=AR5523 + +usb:v1435p0827* + ID_PRODUCT_FROM_DATABASE=AR5523 (no firmware) + +usb:v1435p0828* + ID_PRODUCT_FROM_DATABASE=AR5523 + +usb:v1435p0829* + ID_PRODUCT_FROM_DATABASE=AR5523 (no firmware) + +usb:v1436* + ID_VENDOR_FROM_DATABASE=Denali Software, Inc. + +usb:v143C* + ID_VENDOR_FROM_DATABASE=Altek Corporation + +usb:v1443* + ID_VENDOR_FROM_DATABASE=Digilent + +usb:v1443p0007* + ID_PRODUCT_FROM_DATABASE=CoolRunner-II CPLD Starter Kit + +usb:v1446* + ID_VENDOR_FROM_DATABASE=X.J.GROUP + +usb:v1446p6A73* + ID_PRODUCT_FROM_DATABASE=Stamps.com Model 510 5LB Scale + +usb:v1453* + ID_VENDOR_FROM_DATABASE=Radio Shack + +usb:v1453p4026* + ID_PRODUCT_FROM_DATABASE=26-183 Serial Cable + +usb:v1456* + ID_VENDOR_FROM_DATABASE=Extending Wire & Cable Co., Ltd. + +usb:v1457* + ID_VENDOR_FROM_DATABASE=First International Computer, Inc. + +usb:v1457p5117* + ID_PRODUCT_FROM_DATABASE=OpenMoko Neo1973 kernel usbnet (g_ether, CDC Ethernet) mode + +usb:v1457p5118* + ID_PRODUCT_FROM_DATABASE=OpenMoko Neo1973 Debug board (V2+) + +usb:v1457p5119* + ID_PRODUCT_FROM_DATABASE=OpenMoko Neo1973 u-boot cdc_acm serial port + +usb:v1457p5120* + ID_PRODUCT_FROM_DATABASE=OpenMoko Neo1973 u-boot usbtty generic serial + +usb:v1457p5121* + ID_PRODUCT_FROM_DATABASE=OpenMoko Neo1973 kernel mass storage (g_storage) mode + +usb:v1457p5122* + ID_PRODUCT_FROM_DATABASE=OpenMoko Neo1973 / Neo Freerunner kernel cdc_ether USB network + +usb:v1457p5123* + ID_PRODUCT_FROM_DATABASE=OpenMoko Neo1973 internal USB CSR4 module + +usb:v1457p5124* + ID_PRODUCT_FROM_DATABASE=OpenMoko Neo1973 Bluetooth Device ID service + +usb:v145F* + ID_VENDOR_FROM_DATABASE=Trust + +usb:v145Fp0106* + ID_PRODUCT_FROM_DATABASE=Trust K56 V92 USB Modem + +usb:v145Fp013D* + ID_PRODUCT_FROM_DATABASE=PC Camera (SN9C201 + OV7660) + +usb:v145Fp013F* + ID_PRODUCT_FROM_DATABASE=Megapixel Auto Focus Webcam + +usb:v145Fp0142* + ID_PRODUCT_FROM_DATABASE=WB-6250X Webcam + +usb:v145Fp015A* + ID_PRODUCT_FROM_DATABASE=WB-8300X 2MP Webcam + +usb:v145Fp0161* + ID_PRODUCT_FROM_DATABASE=15901 802.11bg Wireless Adapter [Realtek RTL8187L] + +usb:v145Fp0167* + ID_PRODUCT_FROM_DATABASE=Widescreen 3MP Webcam + +usb:v145Fp0176* + ID_PRODUCT_FROM_DATABASE=Isla Keyboard + +usb:v1460* + ID_VENDOR_FROM_DATABASE=Tatung Co. + +usb:v1460p9150* + ID_PRODUCT_FROM_DATABASE=eHome Infrared Transceiver + +usb:v1461* + ID_VENDOR_FROM_DATABASE=Staccato Communications + +usb:v1462* + ID_VENDOR_FROM_DATABASE=Micro Star International + +usb:v1462p5512* + ID_PRODUCT_FROM_DATABASE=MegaStick-1 Flash Stick + +usb:v1462p8807* + ID_PRODUCT_FROM_DATABASE=DIGIVOX mini III [af9015] + +usb:v1472* + ID_VENDOR_FROM_DATABASE=Huawei-3Com + +usb:v1472p0007* + ID_PRODUCT_FROM_DATABASE=Aolynk WUB300g [ZyDAS ZD1211] + +usb:v1472p0009* + ID_PRODUCT_FROM_DATABASE=Aolynk WUB320g + +usb:v147A* + ID_VENDOR_FROM_DATABASE=Formosa Industrial Computing, Inc. + +usb:v147ApE015* + ID_PRODUCT_FROM_DATABASE=eHome Infrared Receiver + +usb:v147ApE016* + ID_PRODUCT_FROM_DATABASE=eHome Infrared Receiver + +usb:v147ApE017* + ID_PRODUCT_FROM_DATABASE=eHome Infrared Receiver + +usb:v147ApE018* + ID_PRODUCT_FROM_DATABASE=eHome Infrared Receiver + +usb:v147ApE02C* + ID_PRODUCT_FROM_DATABASE=Infrared Receiver + +usb:v147ApE03A* + ID_PRODUCT_FROM_DATABASE=eHome Infrared Receiver + +usb:v147ApE03C* + ID_PRODUCT_FROM_DATABASE=eHome Infrared Receiver + +usb:v147ApE03E* + ID_PRODUCT_FROM_DATABASE=Infrared Receiver [IR605A/Q] + +usb:v147E* + ID_VENDOR_FROM_DATABASE=Upek + +usb:v147Ep1000* + ID_PRODUCT_FROM_DATABASE=Biometric Touchchip/Touchstrip Fingerprint Sensor + +usb:v147Ep1001* + ID_PRODUCT_FROM_DATABASE=TCS5B Fingerprint sensor + +usb:v147Ep2016* + ID_PRODUCT_FROM_DATABASE=Biometric Touchchip/Touchstrip Fingerprint Sensor + +usb:v147Ep2020* + ID_PRODUCT_FROM_DATABASE=TouchChip Fingerprint Coprocessor (WBF advanced mode) + +usb:v147Ep3000* + ID_PRODUCT_FROM_DATABASE=TCS1C EIM/Cypress Fingerprint sensor + +usb:v147Ep3001* + ID_PRODUCT_FROM_DATABASE=TCS1C EIM/STM32 Fingerprint sensor + +usb:v147F* + ID_VENDOR_FROM_DATABASE=Hama GmbH & Co., KG + +usb:v1482* + ID_VENDOR_FROM_DATABASE=Vaillant + +usb:v1482p1005* + ID_PRODUCT_FROM_DATABASE=VRD PC-Interface + +usb:v1484* + ID_VENDOR_FROM_DATABASE=Elsa AG [hex] + +usb:v1484p1746* + ID_PRODUCT_FROM_DATABASE=Ecomo 19H99 Monitor + +usb:v1484p7616* + ID_PRODUCT_FROM_DATABASE=Elsa Hub + +usb:v1485* + ID_VENDOR_FROM_DATABASE=Silicom + +usb:v1485p0001* + ID_PRODUCT_FROM_DATABASE=U2E + +usb:v1485p0002* + ID_PRODUCT_FROM_DATABASE=Psion Gold Port Ethernet + +usb:v1487* + ID_VENDOR_FROM_DATABASE=DSP Group, Ltd. + +usb:v148E* + ID_VENDOR_FROM_DATABASE=EVATRONIX SA + +usb:v148F* + ID_VENDOR_FROM_DATABASE=Ralink Technology, Corp. + +usb:v148Fp1706* + ID_PRODUCT_FROM_DATABASE=RT2500USB Wireless Adapter + +usb:v148Fp2070* + ID_PRODUCT_FROM_DATABASE=RT2070 Wireless Adapter + +usb:v148Fp2570* + ID_PRODUCT_FROM_DATABASE=RT2570 Wireless Adapter + +usb:v148Fp2573* + ID_PRODUCT_FROM_DATABASE=RT2501/RT2573 Wireless Adapter + +usb:v148Fp2671* + ID_PRODUCT_FROM_DATABASE=RT2601/RT2671 Wireless Adapter + +usb:v148Fp2770* + ID_PRODUCT_FROM_DATABASE=RT2770 Wireless Adapter + +usb:v148Fp2870* + ID_PRODUCT_FROM_DATABASE=RT2870 Wireless Adapter + +usb:v148Fp3070* + ID_PRODUCT_FROM_DATABASE=RT2870/RT3070 Wireless Adapter + +usb:v148Fp3071* + ID_PRODUCT_FROM_DATABASE=RT3071 Wireless Adapter + +usb:v148Fp3072* + ID_PRODUCT_FROM_DATABASE=RT3072 Wireless Adapter + +usb:v148Fp3370* + ID_PRODUCT_FROM_DATABASE=RT3370 Wireless Adapter + +usb:v148Fp3572* + ID_PRODUCT_FROM_DATABASE=RT3572 Wireless Adapter + +usb:v148Fp3573* + ID_PRODUCT_FROM_DATABASE=TEW-684UB / RT3573 Wireless Adapter + +usb:v148Fp5370* + ID_PRODUCT_FROM_DATABASE=RT5370 Wireless Adapter + +usb:v148Fp5372* + ID_PRODUCT_FROM_DATABASE=RT5372 Wireless Adapter + +usb:v148Fp5572* + ID_PRODUCT_FROM_DATABASE=RT5572 Wireless Adapter + +usb:v148Fp9020* + ID_PRODUCT_FROM_DATABASE=RT2500USB Wireless Adapter + +usb:v148Fp9021* + ID_PRODUCT_FROM_DATABASE=RT2501USB Wireless Adapter + +usb:v1491* + ID_VENDOR_FROM_DATABASE=Futronic Technology Co. Ltd. + +usb:v1491p0020* + ID_PRODUCT_FROM_DATABASE=FS81 Fingerprint Scanner Module + +usb:v1493* + ID_VENDOR_FROM_DATABASE=Suunto + +usb:v1497* + ID_VENDOR_FROM_DATABASE=Panstrong Company Ltd. + +usb:v1498* + ID_VENDOR_FROM_DATABASE=Microtek International Inc. + +usb:v1498pA090* + ID_PRODUCT_FROM_DATABASE=DVB-T Tuner + +usb:v149A* + ID_VENDOR_FROM_DATABASE=Imagination Technologies + +usb:v149Ap2107* + ID_PRODUCT_FROM_DATABASE=DBX1 DSP core + +usb:v14AA* + ID_VENDOR_FROM_DATABASE=WideView Technology Inc. + +usb:v14AAp0001* + ID_PRODUCT_FROM_DATABASE=Avermedia AverTV DVBT USB1.1 (cold) + +usb:v14AAp0002* + ID_PRODUCT_FROM_DATABASE=Avermedia AverTV DVBT USB1.1 (warm) + +usb:v14AAp0201* + ID_PRODUCT_FROM_DATABASE=AVermedia/Yakumo/Hama/Typhoon DVB-T USB2.0 (cold) + +usb:v14AAp0221* + ID_PRODUCT_FROM_DATABASE=WT-220U DVB-T dongle + +usb:v14AAp022B* + ID_PRODUCT_FROM_DATABASE=WT-220U DVB-T dongle + +usb:v14AAp0301* + ID_PRODUCT_FROM_DATABASE=AVermedia/Yakumo/Hama/Typhoon DVB-T USB2.0 (warm) + +usb:v14AD* + ID_VENDOR_FROM_DATABASE=CTK Corporation + +usb:v14AE* + ID_VENDOR_FROM_DATABASE=Printronix Inc. + +usb:v14AF* + ID_VENDOR_FROM_DATABASE=ATP Electronics Inc. + +usb:v14B0* + ID_VENDOR_FROM_DATABASE=StarTech.com Ltd. + +usb:v14B2* + ID_VENDOR_FROM_DATABASE=Ralink Technology, Corp. + +usb:v14B2p3A93* + ID_PRODUCT_FROM_DATABASE=Topcom 802.11bg Wireless Adapter [Atheros AR5523] + +usb:v14B2p3A95* + ID_PRODUCT_FROM_DATABASE=Toshiba WUS-G06G-JT 802.11bg Wireless Adapter [Atheros AR5523] + +usb:v14B2p3A98* + ID_PRODUCT_FROM_DATABASE=Airlink101 AWLL4130 802.11bg Wireless Adapter [Atheros AR5523] + +usb:v14B2p3C02* + ID_PRODUCT_FROM_DATABASE=Conceptronic C54RU v2 802.11bg Wireless Adapter [Ralink RT2571] + +usb:v14B2p3C05* + ID_PRODUCT_FROM_DATABASE=rt2570 802.11g WLAN + +usb:v14B2p3C06* + ID_PRODUCT_FROM_DATABASE=Conceptronic C300RU v1 802.11bgn Wireless Adapter [Ralink RT2870] + +usb:v14B2p3C07* + ID_PRODUCT_FROM_DATABASE=802.11n adapter + +usb:v14B2p3C09* + ID_PRODUCT_FROM_DATABASE=802.11n adapter + +usb:v14B2p3C22* + ID_PRODUCT_FROM_DATABASE=Conceptronic C54RU v3 802.11bg Wireless Adapter [Ralink RT2571W] + +usb:v14B2p3C23* + ID_PRODUCT_FROM_DATABASE=Airlink101 AWLL6080 802.11bgn Wireless Adapter [Ralink RT2870] + +usb:v14B2p3C24* + ID_PRODUCT_FROM_DATABASE=NEC NP01LM 802.11abg Wireless Adapter [Ralink RT2571W] + +usb:v14B2p3C25* + ID_PRODUCT_FROM_DATABASE=DrayTek Vigor N61 802.11bgn Wireless Adapter [Ralink RT2870] + +usb:v14B2p3C27* + ID_PRODUCT_FROM_DATABASE=Airlink101 AWLL6070 802.11bgn Wireless Adapter [Ralink RT2770] + +usb:v14B2p3C28* + ID_PRODUCT_FROM_DATABASE=Conceptronic C300RU v2 802.11bgn Wireless Adapter [Ralink RT2770] + +usb:v14B2p3C2B* + ID_PRODUCT_FROM_DATABASE=NEC NP02LM 802.11bgn Wireless Adapter [Ralink RT3070] + +usb:v14B2p3C2C* + ID_PRODUCT_FROM_DATABASE=Keebox W150NU 802.11bgn Wireless Adapter [Ralink RT3070] + +usb:v14C0* + ID_VENDOR_FROM_DATABASE=Rockwell Automation, Inc. + +usb:v14C2* + ID_VENDOR_FROM_DATABASE=Gemlight Computer, Ltd + +usb:v14C2p0250* + ID_PRODUCT_FROM_DATABASE=Storage Adapter V2 + +usb:v14C2p0350* + ID_PRODUCT_FROM_DATABASE=Storage Adapter V2 + +usb:v14C8* + ID_VENDOR_FROM_DATABASE=Zytronic + +usb:v14CD* + ID_VENDOR_FROM_DATABASE=Super Top + +usb:v14CDp121C* + ID_PRODUCT_FROM_DATABASE=microSD card reader + +usb:v14CDp123A* + ID_PRODUCT_FROM_DATABASE=SD/MMC/RS-MMC Card Reader + +usb:v14CDp125C* + ID_PRODUCT_FROM_DATABASE=SD card reader + +usb:v14CDp127B* + ID_PRODUCT_FROM_DATABASE=SDXC Reader + +usb:v14CDp6116* + ID_PRODUCT_FROM_DATABASE=M6116 SATA Bridge + +usb:v14CDp6600* + ID_PRODUCT_FROM_DATABASE=USB 2.0 IDE DEVICE + +usb:v14CDp6700* + ID_PRODUCT_FROM_DATABASE=Card Reader + +usb:v14CDp6900* + ID_PRODUCT_FROM_DATABASE=Card Reader + +usb:v14CDp8123* + ID_PRODUCT_FROM_DATABASE=SD MMC Reader + +usb:v14CDp8125* + ID_PRODUCT_FROM_DATABASE=SD MMC Reader + +usb:v14D8* + ID_VENDOR_FROM_DATABASE=JAMER INDUSTRIES CO., LTD. + +usb:v14DD* + ID_VENDOR_FROM_DATABASE=Raritan Computer, Inc. + +usb:v14DDp1007* + ID_PRODUCT_FROM_DATABASE=D2CIM-VUSB KVM connector + +usb:v14E1* + ID_VENDOR_FROM_DATABASE=Dialogue Technology Corp. + +usb:v14E1p5000* + ID_PRODUCT_FROM_DATABASE=PenMount 5000 Touch Controller + +usb:v14E5* + ID_VENDOR_FROM_DATABASE=SAIN Information & Communications Co., Ltd. + +usb:v14EA* + ID_VENDOR_FROM_DATABASE=Planex Communications + +usb:v14EApAB10* + ID_PRODUCT_FROM_DATABASE=GW-US54GZ + +usb:v14EApAB11* + ID_PRODUCT_FROM_DATABASE=GU-1000T + +usb:v14EApAB13* + ID_PRODUCT_FROM_DATABASE=GW-US54Mini 802.11bg + +usb:v14ED* + ID_VENDOR_FROM_DATABASE=Shure Inc. + +usb:v14EDp29B6* + ID_PRODUCT_FROM_DATABASE=X2u Adapter + +usb:v14F7* + ID_VENDOR_FROM_DATABASE=TechniSat Digital GmbH + +usb:v14F7p0001* + ID_PRODUCT_FROM_DATABASE=SkyStar 2 HD CI + +usb:v14F7p0002* + ID_PRODUCT_FROM_DATABASE=SkyStar 2 HD CI + +usb:v14F7p0003* + ID_PRODUCT_FROM_DATABASE=CableStar Combo HD CI + +usb:v14F7p0004* + ID_PRODUCT_FROM_DATABASE=AirStar TeleStick 2 + +usb:v14F7p0500* + ID_PRODUCT_FROM_DATABASE=DVB-PC TV Star HD + +usb:v1500* + ID_VENDOR_FROM_DATABASE=Ellisys + +usb:v1501* + ID_VENDOR_FROM_DATABASE=Pine-Tum Enterprise Co., Ltd. + +usb:v1509* + ID_VENDOR_FROM_DATABASE=First International Computer, Inc. + +usb:v1509p9242* + ID_PRODUCT_FROM_DATABASE=eHome Infrared Transceiver + +usb:v1513* + ID_VENDOR_FROM_DATABASE=medMobile + +usb:v1513p0444* + ID_PRODUCT_FROM_DATABASE=medMobile + +usb:v1514* + ID_VENDOR_FROM_DATABASE=Actel + +usb:v1514p2003* + ID_PRODUCT_FROM_DATABASE=FlashPro3 Programmer + +usb:v1514p2004* + ID_PRODUCT_FROM_DATABASE=FlashPro3 Programmer + +usb:v1514p2005* + ID_PRODUCT_FROM_DATABASE=FlashPro3 Programmer + +usb:v1516* + ID_VENDOR_FROM_DATABASE=CompUSA + +usb:v1516p1603* + ID_PRODUCT_FROM_DATABASE=Flash Drive + +usb:v1516p8628* + ID_PRODUCT_FROM_DATABASE=Pen Drive + +usb:v1518* + ID_VENDOR_FROM_DATABASE=Cheshire Engineering Corp. + +usb:v1518p0001* + ID_PRODUCT_FROM_DATABASE=HDReye High Dynamic Range Camera + +usb:v1518p0002* + ID_PRODUCT_FROM_DATABASE=HDReye (before firmware loads) + +usb:v1520* + ID_VENDOR_FROM_DATABASE=Bitwire Corp. + +usb:v1524* + ID_VENDOR_FROM_DATABASE=ENE Technology Inc + +usb:v1524p6680* + ID_PRODUCT_FROM_DATABASE=UTS 6680 + +usb:v1527* + ID_VENDOR_FROM_DATABASE=Silicon Portals + +usb:v1527p0200* + ID_PRODUCT_FROM_DATABASE=YAP Phone (no firmware) + +usb:v1527p0201* + ID_PRODUCT_FROM_DATABASE=YAP Phone + +usb:v1529* + ID_VENDOR_FROM_DATABASE=UBIQUAM Co., Ltd. + +usb:v1529p3100* + ID_PRODUCT_FROM_DATABASE=CDMA 1xRTT USB Modem (U-100/105/200/300/520) + +usb:v152A* + ID_VENDOR_FROM_DATABASE=Thesycon Systemsoftware & Consulting GmbH + +usb:v152D* + ID_VENDOR_FROM_DATABASE=JMicron Technology Corp. / JMicron USA Technology Corp. + +usb:v152Dp2329* + ID_PRODUCT_FROM_DATABASE=JM20329 SATA Bridge + +usb:v152Dp2335* + ID_PRODUCT_FROM_DATABASE=ATA/ATAPI Bridge + +usb:v152Dp2336* + ID_PRODUCT_FROM_DATABASE=Hard Disk Drive + +usb:v152Dp2337* + ID_PRODUCT_FROM_DATABASE=ATA/ATAPI Bridge + +usb:v152Dp2338* + ID_PRODUCT_FROM_DATABASE=JM20337 Hi-Speed USB to SATA & PATA Combo Bridge + +usb:v152Dp2339* + ID_PRODUCT_FROM_DATABASE=JM20339 SATA Bridge + +usb:v152Dp2352* + ID_PRODUCT_FROM_DATABASE=ATA/ATAPI Bridge + +usb:v152Dp2509* + ID_PRODUCT_FROM_DATABASE=JMS539 SuperSpeed SATA II 3.0G Bridge + +usb:v152E* + ID_VENDOR_FROM_DATABASE=LG (HLDS) + +usb:v152Ep2507* + ID_PRODUCT_FROM_DATABASE=PL-2507 IDE Controller + +usb:v152EpE001* + ID_PRODUCT_FROM_DATABASE=GSA-5120D DVD-RW + +usb:v1532* + ID_VENDOR_FROM_DATABASE=Razer USA, Ltd + +usb:v1532p0001* + ID_PRODUCT_FROM_DATABASE=RZ01-020300 Optical Mouse [Diamondback] + +usb:v1532p0003* + ID_PRODUCT_FROM_DATABASE=Krait Mouse + +usb:v1532p0007* + ID_PRODUCT_FROM_DATABASE=DeathAdder Mouse + +usb:v1532p0013* + ID_PRODUCT_FROM_DATABASE=Orochi mouse + +usb:v1532p0016* + ID_PRODUCT_FROM_DATABASE=DeathAdder Mouse + +usb:v1532p0017* + ID_PRODUCT_FROM_DATABASE=Imperator Mouse + +usb:v1532p001C* + ID_PRODUCT_FROM_DATABASE=RZ01-0036 Optical Gaming Mouse [Abyssus] + +usb:v1532p0024* + ID_PRODUCT_FROM_DATABASE=Razer Mamba + +usb:v1532p0101* + ID_PRODUCT_FROM_DATABASE=Copperhead Mouse + +usb:v1532p0102* + ID_PRODUCT_FROM_DATABASE=Tarantula Keyboard + +usb:v1532p0109* + ID_PRODUCT_FROM_DATABASE=Lycosa Keyboard + +usb:v1546* + ID_VENDOR_FROM_DATABASE=U-Blox AG + +usb:v1547* + ID_VENDOR_FROM_DATABASE=SG Intec Ltd & Co KG + +usb:v1547p1000* + ID_PRODUCT_FROM_DATABASE=SG-Lock[U2] + +usb:v154A* + ID_VENDOR_FROM_DATABASE=Celectronic GmbH + +usb:v154Ap8180* + ID_PRODUCT_FROM_DATABASE=CARD STAR/medic2 + +usb:v154B* + ID_VENDOR_FROM_DATABASE=PNY + +usb:v154Bp0010* + ID_PRODUCT_FROM_DATABASE=USB 2.0 Flash Drive + +usb:v154Bp004D* + ID_PRODUCT_FROM_DATABASE=8 GB Flash Drive + +usb:v154Bp6545* + ID_PRODUCT_FROM_DATABASE=FD Device + +usb:v154D* + ID_VENDOR_FROM_DATABASE=ConnectCounty Holdings Berhad + +usb:v154E* + ID_VENDOR_FROM_DATABASE=D&M Holdings, Inc. (Denon/Marantz) + +usb:v154Ep3000* + ID_PRODUCT_FROM_DATABASE=Marantz RC9001 Remote Control + +usb:v154F* + ID_VENDOR_FROM_DATABASE=SNBC CO., Ltd + +usb:v1554* + ID_VENDOR_FROM_DATABASE=Prolink Microsystems Corp. + +usb:v1554p5010* + ID_PRODUCT_FROM_DATABASE=PV-D231U(RN)-F [PixelView PlayTV SBTVD Full-Seg] + +usb:v1557* + ID_VENDOR_FROM_DATABASE=OQO + +usb:v1557p0002* + ID_PRODUCT_FROM_DATABASE=model 01 WiFi interface + +usb:v1557p0003* + ID_PRODUCT_FROM_DATABASE=model 01 Bluetooth interface + +usb:v1557p0A80* + ID_PRODUCT_FROM_DATABASE=Gobi Wireless Modem (QDL mode) + +usb:v1557p7720* + ID_PRODUCT_FROM_DATABASE=model 01+ Ethernet + +usb:v1557p8150* + ID_PRODUCT_FROM_DATABASE=model 01 Ethernet interface + +usb:v1568* + ID_VENDOR_FROM_DATABASE=Sunf Pu Technology Co., Ltd + +usb:v156F* + ID_VENDOR_FROM_DATABASE=Quantum Corporation + +usb:v1570* + ID_VENDOR_FROM_DATABASE=ALLTOP TECHNOLOGY CO., LTD. + +usb:v157B* + ID_VENDOR_FROM_DATABASE=Ketron SRL + +usb:v157E* + ID_VENDOR_FROM_DATABASE=TRENDnet + +usb:v157Ep3006* + ID_PRODUCT_FROM_DATABASE=TEW-444UB EU [TRENDnet] + +usb:v157Ep3007* + ID_PRODUCT_FROM_DATABASE=TEW-444UB EU (no firmware) + +usb:v157Ep300A* + ID_PRODUCT_FROM_DATABASE=TEW-429UB 802.11bg + +usb:v157Ep300B* + ID_PRODUCT_FROM_DATABASE=TEW-429UB 802.11bg + +usb:v157Ep300C* + ID_PRODUCT_FROM_DATABASE=TEW-429UF A1 802.11bg Wireless Adapter [ZyDAS ZD1211B] + +usb:v157Ep300D* + ID_PRODUCT_FROM_DATABASE=TEW-429UB C1 802.11bg + +usb:v157Ep300E* + ID_PRODUCT_FROM_DATABASE=SMC SMCWUSB-N 802.11bgn 2x2:2 Wireless Adapter [Ralink RT2870] + +usb:v157Ep3012* + ID_PRODUCT_FROM_DATABASE=TEW-604UB 802.11bg Wireless Adapter [Atheros AR5523] + +usb:v157Ep3013* + ID_PRODUCT_FROM_DATABASE=TEW-645UB 802.11bgn 1x2:2 Wireless Adapter [Ralink RT2770] + +usb:v157Ep3204* + ID_PRODUCT_FROM_DATABASE=Allnet ALL0298 v2 802.11bg + +usb:v157Ep3205* + ID_PRODUCT_FROM_DATABASE=Allnet ALL0283 [AR5523] + +usb:v157Ep3206* + ID_PRODUCT_FROM_DATABASE=Allnet ALL0283 [AR5523](no firmware) + +usb:v157Ep3207* + ID_PRODUCT_FROM_DATABASE=TEW-509UB A1 802.11abg Wireless Adapter [ZyDAS ZD1211] + +usb:v157Ep3208* + ID_PRODUCT_FROM_DATABASE=TEW-509UB 1.1R 802.11abg Wireless Adapter + +usb:v1582* + ID_VENDOR_FROM_DATABASE=Fiberline + +usb:v1582p6003* + ID_PRODUCT_FROM_DATABASE=WL-430U 802.11bg + +usb:v1587* + ID_VENDOR_FROM_DATABASE=SMA Technologie AG + +usb:v158D* + ID_VENDOR_FROM_DATABASE=Oakley Inc. + +usb:v158E* + ID_VENDOR_FROM_DATABASE=JDS Uniphase Corporation (JDSU) + +usb:v158Ep0820* + ID_PRODUCT_FROM_DATABASE=SmartPocket Class Device + +usb:v1598* + ID_VENDOR_FROM_DATABASE=Kunshan Guoji Electronics Co., Ltd. + +usb:v15A2* + ID_VENDOR_FROM_DATABASE=Freescale Semiconductor, Inc. + +usb:v15A2p003B* + ID_PRODUCT_FROM_DATABASE=USB2CAN Application for ColdFire DEMOJM board + +usb:v15A2p0042* + ID_PRODUCT_FROM_DATABASE=OSBDM - Debug Port + +usb:v15A2p004F* + ID_PRODUCT_FROM_DATABASE=i.MX28 SystemOnChip in RecoveryMode + +usb:v15A2p0052* + ID_PRODUCT_FROM_DATABASE=i.MX50 SystemOnChip in RecoveryMode + +usb:v15A2p0054* + ID_PRODUCT_FROM_DATABASE=i.MX6Q SystemOnChip in RecoveryMode + +usb:v15A4* + ID_VENDOR_FROM_DATABASE=Afatech Technologies, Inc. + +usb:v15A4p1000* + ID_PRODUCT_FROM_DATABASE=AF9015/AF9035 DVB-T stick + +usb:v15A4p1001* + ID_PRODUCT_FROM_DATABASE=AF9015/AF9035 DVB-T stick + +usb:v15A4p1336* + ID_PRODUCT_FROM_DATABASE=SDHC/MicroSD/MMC/MS/M2/CF/XD Flash Card Reader + +usb:v15A4p9015* + ID_PRODUCT_FROM_DATABASE=AF9015 DVB-T USB2.0 stick + +usb:v15A4p9016* + ID_PRODUCT_FROM_DATABASE=AF9015 DVB-T USB2.0 stick + +usb:v15A8* + ID_VENDOR_FROM_DATABASE=Teams Power Limited + +usb:v15A9* + ID_VENDOR_FROM_DATABASE=Gemtek + +usb:v15A9p0002* + ID_PRODUCT_FROM_DATABASE=SparkLAN WL-682 802.11bg Wireless Adapter [Intersil ISL3887] + +usb:v15A9p0004* + ID_PRODUCT_FROM_DATABASE=WUBR-177G [Ralink RT2571W] + +usb:v15A9p0006* + ID_PRODUCT_FROM_DATABASE=Wireless 11n USB Adapter + +usb:v15A9p0010* + ID_PRODUCT_FROM_DATABASE=802.11n USB Wireless Card + +usb:v15A9p0012* + ID_PRODUCT_FROM_DATABASE=WUBR-208N 802.11abgn Wireless Adapter [Ralink RT2870] + +usb:v15AA* + ID_VENDOR_FROM_DATABASE=Gearway Electronics (Dong Guan) Co., Ltd. + +usb:v15AD* + ID_VENDOR_FROM_DATABASE=VMware Inc. + +usb:v15BA* + ID_VENDOR_FROM_DATABASE=Olimex Ltd. + +usb:v15BAp0003* + ID_PRODUCT_FROM_DATABASE=OpenOCD JTAG + +usb:v15BAp0004* + ID_PRODUCT_FROM_DATABASE=OpenOCD JTAG TINY + +usb:v15BAp002A* + ID_PRODUCT_FROM_DATABASE=ARM-USB-TINY-H JTAG interface + +usb:v15C0* + ID_VENDOR_FROM_DATABASE=XL Imaging + +usb:v15C0p0001* + ID_PRODUCT_FROM_DATABASE=2M pixel Microscope Camera + +usb:v15C0p0002* + ID_PRODUCT_FROM_DATABASE=3M pixel Microscope Camera + +usb:v15C0p0003* + ID_PRODUCT_FROM_DATABASE=1.3M pixel Microscope Camera (mono) + +usb:v15C0p0004* + ID_PRODUCT_FROM_DATABASE=1.3M pixel Microscope Camera (colour) + +usb:v15C0p0005* + ID_PRODUCT_FROM_DATABASE=3M pixel Microscope Camera (Mk 2) + +usb:v15C0p0006* + ID_PRODUCT_FROM_DATABASE=2M pixel Microscope Camera (with capture button) + +usb:v15C0p0007* + ID_PRODUCT_FROM_DATABASE=3M pixel Microscope Camera (with capture button) + +usb:v15C0p0008* + ID_PRODUCT_FROM_DATABASE=1.3M pixel Microscope Camera (colour, with capture button) + +usb:v15C0p0009* + ID_PRODUCT_FROM_DATABASE=1.3M pixel Microscope Camera (colour, with capture button) + +usb:v15C0p000A* + ID_PRODUCT_FROM_DATABASE=2M pixel Microscope Camera (Mk 2) + +usb:v15C0p0010* + ID_PRODUCT_FROM_DATABASE=1.3M pixel "Tinycam" + +usb:v15C0p0101* + ID_PRODUCT_FROM_DATABASE=3M pixel Microscope Camera + +usb:v15C2* + ID_VENDOR_FROM_DATABASE=SoundGraph Inc. + +usb:v15C2p0036* + ID_PRODUCT_FROM_DATABASE=LC16M VFD Display/IR Receiver + +usb:v15C2p0038* + ID_PRODUCT_FROM_DATABASE=GD01 MX LCD Display/IR Receiver + +usb:v15C2pFFDA* + ID_PRODUCT_FROM_DATABASE=iMON PAD Remote Controller + +usb:v15C2pFFDC* + ID_PRODUCT_FROM_DATABASE=iMON PAD Remote Controller + +usb:v15C5* + ID_VENDOR_FROM_DATABASE=Advance Multimedia Internet Technology Inc. (AMIT) + +usb:v15C5p0008* + ID_PRODUCT_FROM_DATABASE=WL532U 802.11g Adapter + +usb:v15C6* + ID_VENDOR_FROM_DATABASE=Laboratoires MXM + +usb:v15C6p1000* + ID_PRODUCT_FROM_DATABASE=DigistimSP (cold) + +usb:v15C6p1001* + ID_PRODUCT_FROM_DATABASE=DigistimSP (warm) + +usb:v15C6p1002* + ID_PRODUCT_FROM_DATABASE=DigimapSP USB (cold) + +usb:v15C6p1003* + ID_PRODUCT_FROM_DATABASE=DigimapSP USB (warm) + +usb:v15C6p1004* + ID_PRODUCT_FROM_DATABASE=DigistimSP (cold) + +usb:v15C6p1005* + ID_PRODUCT_FROM_DATABASE=DigistimSP (warm) + +usb:v15C6p1100* + ID_PRODUCT_FROM_DATABASE=Odyssee (cold) + +usb:v15C6p1101* + ID_PRODUCT_FROM_DATABASE=Odyssee (warm) + +usb:v15C6p1200* + ID_PRODUCT_FROM_DATABASE=Digispy + +usb:v15C8* + ID_VENDOR_FROM_DATABASE=KTF Technologies + +usb:v15C8p3201* + ID_PRODUCT_FROM_DATABASE=EVER EV-W100/EV-W250 + +usb:v15C9* + ID_VENDOR_FROM_DATABASE=D-Box Technologies + +usb:v15CA* + ID_VENDOR_FROM_DATABASE=Textech International Ltd. + +usb:v15CAp00C3* + ID_PRODUCT_FROM_DATABASE=Mini Optical Mouse + +usb:v15CAp0101* + ID_PRODUCT_FROM_DATABASE=MIDI Interface cable + +usb:v15CAp1806* + ID_PRODUCT_FROM_DATABASE=MIDI Interface cable + +usb:v15D5* + ID_VENDOR_FROM_DATABASE=Coulomb Electronics Ltd. + +usb:v15D9* + ID_VENDOR_FROM_DATABASE=Trust International B.V. + +usb:v15D9p0A33* + ID_PRODUCT_FROM_DATABASE=Optical Mouse + +usb:v15D9p0A37* + ID_PRODUCT_FROM_DATABASE=Mouse + +usb:v15D9p0A41* + ID_PRODUCT_FROM_DATABASE=MI-2540D [Optical mouse] + +usb:v15D9p0A4C* + ID_PRODUCT_FROM_DATABASE=USB+PS/2 Optical Mouse + +usb:v15D9p0A4D* + ID_PRODUCT_FROM_DATABASE=Optical Mouse + +usb:v15DC* + ID_VENDOR_FROM_DATABASE=Hynix Semiconductor Inc. + +usb:v15E0* + ID_VENDOR_FROM_DATABASE=Seong Ji Industrial Co., Ltd. + +usb:v15E1* + ID_VENDOR_FROM_DATABASE=RSA + +usb:v15E1p2007* + ID_PRODUCT_FROM_DATABASE=RSA SecurID (R) Authenticator + +usb:v15E4* + ID_VENDOR_FROM_DATABASE=Numark + +usb:v15E4p0024* + ID_PRODUCT_FROM_DATABASE=Mixtrack + +usb:v15E8* + ID_VENDOR_FROM_DATABASE=SohoWare + +usb:v15E8p9100* + ID_PRODUCT_FROM_DATABASE=NUB100 Ethernet [pegasus] + +usb:v15E8p9110* + ID_PRODUCT_FROM_DATABASE=10/100 USB Ethernet + +usb:v15E9* + ID_VENDOR_FROM_DATABASE=Pacific Digital Corp. + +usb:v15E9p04CE* + ID_PRODUCT_FROM_DATABASE=MemoryFrame MF-570 + +usb:v15E9p1968* + ID_PRODUCT_FROM_DATABASE=MemoryFrame MF-570 + +usb:v15E9p1969* + ID_PRODUCT_FROM_DATABASE=Digital Frame + +usb:v15EC* + ID_VENDOR_FROM_DATABASE=Belcarra Technologies Corp. + +usb:v15F4* + ID_VENDOR_FROM_DATABASE=HanfTek + +usb:v15F4p0001* + ID_PRODUCT_FROM_DATABASE=HanfTek UMT-010 USB2.0 DVB-T (cold) + +usb:v15F4p0025* + ID_PRODUCT_FROM_DATABASE=HanfTek UMT-010 USB2.0 DVB-T (warm) + +usb:v1604* + ID_VENDOR_FROM_DATABASE=Tascam + +usb:v1604p8000* + ID_PRODUCT_FROM_DATABASE=US-428 Audio/Midi Controller (without fw) + +usb:v1604p8001* + ID_PRODUCT_FROM_DATABASE=US-428 Audio/Midi Controller + +usb:v1604p8004* + ID_PRODUCT_FROM_DATABASE=US-224 Audio/Midi Controller (without fw) + +usb:v1604p8005* + ID_PRODUCT_FROM_DATABASE=US-224 Audio/Midi Controller + +usb:v1604p8006* + ID_PRODUCT_FROM_DATABASE=US-122 Audio/Midi Interface (without fw) + +usb:v1604p8007* + ID_PRODUCT_FROM_DATABASE=US-122 Audio/Midi Interface + +usb:v1606* + ID_VENDOR_FROM_DATABASE=Umax + +usb:v1606p0002* + ID_PRODUCT_FROM_DATABASE=Astra 1236U Scanner + +usb:v1606p0010* + ID_PRODUCT_FROM_DATABASE=Astra 1220U + +usb:v1606p0030* + ID_PRODUCT_FROM_DATABASE=Astra 1600U/2000U + +usb:v1606p0050* + ID_PRODUCT_FROM_DATABASE=Scanner + +usb:v1606p0060* + ID_PRODUCT_FROM_DATABASE=Astra 3400/3450 + +usb:v1606p0070* + ID_PRODUCT_FROM_DATABASE=Astra 4400/4450 + +usb:v1606p0130* + ID_PRODUCT_FROM_DATABASE=Astra 2100U + +usb:v1606p0160* + ID_PRODUCT_FROM_DATABASE=Astra 5400U + +usb:v1606p0170* + ID_PRODUCT_FROM_DATABASE=Uniscan D50 + +usb:v1606p0230* + ID_PRODUCT_FROM_DATABASE=Astra 2200/2200SU + +usb:v1606p0350* + ID_PRODUCT_FROM_DATABASE=Astra 4800/4850 Scanner + +usb:v1606p1030* + ID_PRODUCT_FROM_DATABASE=Astra 4000U + +usb:v1606p1220* + ID_PRODUCT_FROM_DATABASE=Genesys Logic Scanner Controller NT5.0 + +usb:v1606p2010* + ID_PRODUCT_FROM_DATABASE=AstraCam Digital Camera + +usb:v1606p2020* + ID_PRODUCT_FROM_DATABASE=AstraCam 1000 + +usb:v1606p2030* + ID_PRODUCT_FROM_DATABASE=AstraCam 1800 Digital Camera + +usb:v1608* + ID_VENDOR_FROM_DATABASE=Inside Out Networks [hex] + +usb:v1608p0001* + ID_PRODUCT_FROM_DATABASE=EdgePort/4 Serial Port + +usb:v1608p0002* + ID_PRODUCT_FROM_DATABASE=Edgeport/8 + +usb:v1608p0003* + ID_PRODUCT_FROM_DATABASE=Rapidport/4 + +usb:v1608p0004* + ID_PRODUCT_FROM_DATABASE=Edgeport/4 + +usb:v1608p0005* + ID_PRODUCT_FROM_DATABASE=Edgeport/2 + +usb:v1608p0006* + ID_PRODUCT_FROM_DATABASE=Edgeport/4i + +usb:v1608p0007* + ID_PRODUCT_FROM_DATABASE=Edgeport/2i + +usb:v1608p0008* + ID_PRODUCT_FROM_DATABASE=Edgeport/8 + +usb:v1608p000C* + ID_PRODUCT_FROM_DATABASE=Edgeport/421 + +usb:v1608p000D* + ID_PRODUCT_FROM_DATABASE=Edgeport/21 + +usb:v1608p000E* + ID_PRODUCT_FROM_DATABASE=Edgeport/4 + +usb:v1608p000F* + ID_PRODUCT_FROM_DATABASE=Edgeport/8 + +usb:v1608p0010* + ID_PRODUCT_FROM_DATABASE=Edgeport/2 + +usb:v1608p0011* + ID_PRODUCT_FROM_DATABASE=Edgeport/4 + +usb:v1608p0012* + ID_PRODUCT_FROM_DATABASE=Edgeport/416 + +usb:v1608p0014* + ID_PRODUCT_FROM_DATABASE=Edgeport/8i + +usb:v1608p0018* + ID_PRODUCT_FROM_DATABASE=Edgeport/412 + +usb:v1608p0019* + ID_PRODUCT_FROM_DATABASE=Edgeport/412 + +usb:v1608p001A* + ID_PRODUCT_FROM_DATABASE=Edgeport/2+2i + +usb:v1608p0101* + ID_PRODUCT_FROM_DATABASE=Edgeport/4 + +usb:v1608p0105* + ID_PRODUCT_FROM_DATABASE=Edgeport/2 + +usb:v1608p0106* + ID_PRODUCT_FROM_DATABASE=Edgeport/4i + +usb:v1608p0107* + ID_PRODUCT_FROM_DATABASE=Edgeport/2i + +usb:v1608p010C* + ID_PRODUCT_FROM_DATABASE=Edgeport/421 + +usb:v1608p010D* + ID_PRODUCT_FROM_DATABASE=Edgeport/21 + +usb:v1608p0110* + ID_PRODUCT_FROM_DATABASE=Edgeport/2 + +usb:v1608p0111* + ID_PRODUCT_FROM_DATABASE=Edgeport/4 + +usb:v1608p0112* + ID_PRODUCT_FROM_DATABASE=Edgeport/416 + +usb:v1608p0114* + ID_PRODUCT_FROM_DATABASE=Edgeport/8i + +usb:v1608p0201* + ID_PRODUCT_FROM_DATABASE=Edgeport/4 + +usb:v1608p0203* + ID_PRODUCT_FROM_DATABASE=Rapidport/4 + +usb:v1608p0204* + ID_PRODUCT_FROM_DATABASE=Edgeport/4 + +usb:v1608p0205* + ID_PRODUCT_FROM_DATABASE=Edgeport/2 + +usb:v1608p0206* + ID_PRODUCT_FROM_DATABASE=Edgeport/4i + +usb:v1608p0207* + ID_PRODUCT_FROM_DATABASE=Edgeport/2i + +usb:v1608p020C* + ID_PRODUCT_FROM_DATABASE=Edgeport/421 + +usb:v1608p020D* + ID_PRODUCT_FROM_DATABASE=Edgeport/21 + +usb:v1608p020E* + ID_PRODUCT_FROM_DATABASE=Edgeport/4 + +usb:v1608p020F* + ID_PRODUCT_FROM_DATABASE=Edgeport/8 + +usb:v1608p0210* + ID_PRODUCT_FROM_DATABASE=Edgeport/2 + +usb:v1608p0211* + ID_PRODUCT_FROM_DATABASE=Edgeport/4 + +usb:v1608p0212* + ID_PRODUCT_FROM_DATABASE=Edgeport/416 + +usb:v1608p0214* + ID_PRODUCT_FROM_DATABASE=Edgeport/8i + +usb:v1608p0215* + ID_PRODUCT_FROM_DATABASE=Edgeport/1 + +usb:v1608p0216* + ID_PRODUCT_FROM_DATABASE=EPOS/44 + +usb:v1608p0217* + ID_PRODUCT_FROM_DATABASE=Edgeport/42 + +usb:v1608p021A* + ID_PRODUCT_FROM_DATABASE=Edgeport/2+2i + +usb:v1608p021B* + ID_PRODUCT_FROM_DATABASE=Edgeport/2c + +usb:v1608p021C* + ID_PRODUCT_FROM_DATABASE=Edgeport/221c + +usb:v1608p021D* + ID_PRODUCT_FROM_DATABASE=Edgeport/22c + +usb:v1608p021E* + ID_PRODUCT_FROM_DATABASE=Edgeport/21c + +usb:v1608p021F* + ID_PRODUCT_FROM_DATABASE=Edgeport/62 + +usb:v1608p0240* + ID_PRODUCT_FROM_DATABASE=Edgeport/1 + +usb:v1608p0241* + ID_PRODUCT_FROM_DATABASE=Edgeport/1i + +usb:v1608p0242* + ID_PRODUCT_FROM_DATABASE=Edgeport/4s + +usb:v1608p0243* + ID_PRODUCT_FROM_DATABASE=Edgeport/8s + +usb:v1608p0244* + ID_PRODUCT_FROM_DATABASE=Edgeport/8 + +usb:v1608p0245* + ID_PRODUCT_FROM_DATABASE=Edgeport/22c + +usb:v1608p0301* + ID_PRODUCT_FROM_DATABASE=Watchport/P + +usb:v1608p0302* + ID_PRODUCT_FROM_DATABASE=Watchport/M + +usb:v1608p0303* + ID_PRODUCT_FROM_DATABASE=Watchport/W + +usb:v1608p0304* + ID_PRODUCT_FROM_DATABASE=Watchport/T + +usb:v1608p0305* + ID_PRODUCT_FROM_DATABASE=Watchport/H + +usb:v1608p0306* + ID_PRODUCT_FROM_DATABASE=Watchport/E + +usb:v1608p0307* + ID_PRODUCT_FROM_DATABASE=Watchport/L + +usb:v1608p0308* + ID_PRODUCT_FROM_DATABASE=Watchport/R + +usb:v1608p0309* + ID_PRODUCT_FROM_DATABASE=Watchport/A + +usb:v1608p030A* + ID_PRODUCT_FROM_DATABASE=Watchport/D + +usb:v1608p030B* + ID_PRODUCT_FROM_DATABASE=Watchport/D + +usb:v1608p030C* + ID_PRODUCT_FROM_DATABASE=Power Management Port + +usb:v1608p030E* + ID_PRODUCT_FROM_DATABASE=Power Management Port + +usb:v1608p030F* + ID_PRODUCT_FROM_DATABASE=Watchport/G + +usb:v1608p0310* + ID_PRODUCT_FROM_DATABASE=Watchport/Tc + +usb:v1608p0311* + ID_PRODUCT_FROM_DATABASE=Watchport/Hc + +usb:v1608p1403* + ID_PRODUCT_FROM_DATABASE=MultiTech Systems MT4X56 Modem + +usb:v1608p1A17* + ID_PRODUCT_FROM_DATABASE=Agilent Technologies (E6473) + +usb:v160A* + ID_VENDOR_FROM_DATABASE=VIA Technologies, Inc. + +usb:v160Ap3184* + ID_PRODUCT_FROM_DATABASE=VIA VNT-6656 [WiFi 802.11b/g USB Dongle] + +usb:v160E* + ID_VENDOR_FROM_DATABASE=INRO + +usb:v160Ep0001* + ID_PRODUCT_FROM_DATABASE=E2USBKey + +usb:v1614* + ID_VENDOR_FROM_DATABASE=Amoi Electronics + +usb:v1614p0404* + ID_PRODUCT_FROM_DATABASE=WMA9109 UMTS Phone + +usb:v1614p0600* + ID_PRODUCT_FROM_DATABASE=Vodafone VDA GPS / Toschiba Protege G710 + +usb:v1614p0804* + ID_PRODUCT_FROM_DATABASE=WP-S1 Phone + +usb:v1619* + ID_VENDOR_FROM_DATABASE=L & K Precision Technology Co., Ltd. + +usb:v1621* + ID_VENDOR_FROM_DATABASE=Wionics Research + +usb:v1628* + ID_VENDOR_FROM_DATABASE=Stonestreet One, Inc. + +usb:v162A* + ID_VENDOR_FROM_DATABASE=Airgo Networks Inc. + +usb:v162F* + ID_VENDOR_FROM_DATABASE=WiQuest Communications, Inc. + +usb:v1630* + ID_VENDOR_FROM_DATABASE=2Wire, Inc. + +usb:v1630p0005* + ID_PRODUCT_FROM_DATABASE=802.11g Wireless Adapter [Intersil ISL3886] + +usb:v1630p0011* + ID_PRODUCT_FROM_DATABASE=PC Port 10 Mps Adapter + +usb:v1630pFF81* + ID_PRODUCT_FROM_DATABASE=802.11b Wireless Adapter [Lucent/Agere Hermes I] + +usb:v1631* + ID_VENDOR_FROM_DATABASE=Good Way Technology + +usb:v1631p6200* + ID_PRODUCT_FROM_DATABASE=GWUSB2E + +usb:v1631pC019* + ID_PRODUCT_FROM_DATABASE=RT2573 + +usb:v1645* + ID_VENDOR_FROM_DATABASE=Cross Match Technologies GmbH + +usb:v1645p0001* + ID_PRODUCT_FROM_DATABASE=1S Serial Port + +usb:v1645p0002* + ID_PRODUCT_FROM_DATABASE=2S Serial Port + +usb:v1645p0003* + ID_PRODUCT_FROM_DATABASE=1S25 Serial Port + +usb:v1645p0004* + ID_PRODUCT_FROM_DATABASE=4S Serial Port + +usb:v1645p0005* + ID_PRODUCT_FROM_DATABASE=E45 Ethernet [klsi] + +usb:v1645p0006* + ID_PRODUCT_FROM_DATABASE=Parallel Port + +usb:v1645p0007* + ID_PRODUCT_FROM_DATABASE=U1-SC25 SCSI + +usb:v1645p0008* + ID_PRODUCT_FROM_DATABASE=Ethernet + +usb:v1645p0016* + ID_PRODUCT_FROM_DATABASE=Bi-directional to Parallel Printer Converter + +usb:v1645p0080* + ID_PRODUCT_FROM_DATABASE=1 port to Serial Converter + +usb:v1645p0081* + ID_PRODUCT_FROM_DATABASE=1 port to Serial Converter + +usb:v1645p0093* + ID_PRODUCT_FROM_DATABASE=1S9 Serial Port + +usb:v1645p8000* + ID_PRODUCT_FROM_DATABASE=EZ-USB + +usb:v1645p8001* + ID_PRODUCT_FROM_DATABASE=1 port to Serial + +usb:v1645p8002* + ID_PRODUCT_FROM_DATABASE=2x Serial Port + +usb:v1645p8003* + ID_PRODUCT_FROM_DATABASE=1 port to Serial + +usb:v1645p8004* + ID_PRODUCT_FROM_DATABASE=2U4S serial/usb hub + +usb:v1645p8005* + ID_PRODUCT_FROM_DATABASE=Ethernet + +usb:v1645p8080* + ID_PRODUCT_FROM_DATABASE=1 port to Serial + +usb:v1645p8081* + ID_PRODUCT_FROM_DATABASE=1 port to Serial + +usb:v1645p8093* + ID_PRODUCT_FROM_DATABASE=PortGear Serial Port + +usb:v1649* + ID_VENDOR_FROM_DATABASE=SofTec Microsystems + +usb:v1649p0102* + ID_PRODUCT_FROM_DATABASE=uDART In-Circuit Debugger + +usb:v1649p0200* + ID_PRODUCT_FROM_DATABASE=SpYder USBSPYDER08 + +usb:v164A* + ID_VENDOR_FROM_DATABASE=ChipX + +usb:v164C* + ID_VENDOR_FROM_DATABASE=Matrix Vision GmbH + +usb:v164Cp0101* + ID_PRODUCT_FROM_DATABASE=mvBlueFOX camera (no firmware) + +usb:v164Cp0103* + ID_PRODUCT_FROM_DATABASE=mvBlueFOX camera + +usb:v164Cp0201* + ID_PRODUCT_FROM_DATABASE=mvBlueLYNX-X intelligent camera (bootloader) + +usb:v164Cp0203* + ID_PRODUCT_FROM_DATABASE=mvBlueLYNX-X intelligent camera + +usb:v1657* + ID_VENDOR_FROM_DATABASE=Struck Innovative Systeme GmbH + +usb:v1657p3150* + ID_PRODUCT_FROM_DATABASE=SIS3150 USB2.0 to VME interface + +usb:v165B* + ID_VENDOR_FROM_DATABASE=Frontier Design Group + +usb:v165Bp8101* + ID_PRODUCT_FROM_DATABASE=Tranzport Control Surface + +usb:v165BpFAD1* + ID_PRODUCT_FROM_DATABASE=Alphatrack Control Surface + +usb:v165C* + ID_VENDOR_FROM_DATABASE=Kondo Kagaku + +usb:v165Cp0002* + ID_PRODUCT_FROM_DATABASE=Serial Adapter + +usb:v1660* + ID_VENDOR_FROM_DATABASE=Creatix Polymedia GmbH + +usb:v1668* + ID_VENDOR_FROM_DATABASE=Actiontec Electronics, Inc. [hex] + +usb:v1668p0009* + ID_PRODUCT_FROM_DATABASE=Gateway + +usb:v1668p0333* + ID_PRODUCT_FROM_DATABASE=Modem + +usb:v1668p0358* + ID_PRODUCT_FROM_DATABASE=InternetPhoneWizard + +usb:v1668p0405* + ID_PRODUCT_FROM_DATABASE=Gateway + +usb:v1668p0408* + ID_PRODUCT_FROM_DATABASE=Prism2.5 802.11b Adapter + +usb:v1668p0413* + ID_PRODUCT_FROM_DATABASE=Gateway + +usb:v1668p0421* + ID_PRODUCT_FROM_DATABASE=Prism2.5 802.11b Adapter + +usb:v1668p0441* + ID_PRODUCT_FROM_DATABASE=IBM Integrated Bluetooth II + +usb:v1668p0500* + ID_PRODUCT_FROM_DATABASE=BTM200B BlueTooth Adapter + +usb:v1668p1050* + ID_PRODUCT_FROM_DATABASE=802UIG-1 802.11g Wireless Mini Adapter [Intersil ISL3887] + +usb:v1668p1200* + ID_PRODUCT_FROM_DATABASE=802AIN Wireless N Network Adapter [Atheros AR9170+AR9101] + +usb:v1668p1441* + ID_PRODUCT_FROM_DATABASE=IBM Integrated Bluetooth II + +usb:v1668p2441* + ID_PRODUCT_FROM_DATABASE=BMDC-2 IBM Bluetooth III w.56k + +usb:v1668p3441* + ID_PRODUCT_FROM_DATABASE=IBM Integrated Bluetooth III + +usb:v1668p6010* + ID_PRODUCT_FROM_DATABASE=Gateway + +usb:v1668p6097* + ID_PRODUCT_FROM_DATABASE=802.11b Wireless Adapter + +usb:v1668p6106* + ID_PRODUCT_FROM_DATABASE=802UI3(B) 802.11b Wireless Adapter [Intersil PRISM 3] + +usb:v1668p7605* + ID_PRODUCT_FROM_DATABASE=UAT1 Wireless Ethernet Adapter + +usb:v1669* + ID_VENDOR_FROM_DATABASE=PiKRON Ltd. [hex] + +usb:v1669p1001* + ID_PRODUCT_FROM_DATABASE=uLan2USB Converter - PS1 protocol + +usb:v1677* + ID_VENDOR_FROM_DATABASE=China Huada Integrated Circuit Design (Group) Co., Ltd. (CIDC Group) + +usb:v1677p0103* + ID_PRODUCT_FROM_DATABASE=Token + +usb:v1679* + ID_VENDOR_FROM_DATABASE=Total Phase + +usb:v1679p2001* + ID_PRODUCT_FROM_DATABASE=Beagle Protocol Analyzer + +usb:v1679p2002* + ID_PRODUCT_FROM_DATABASE=Cheetah SPI Host Adapter + +usb:v1680* + ID_VENDOR_FROM_DATABASE=Golden Bridge Electech Inc. + +usb:v1680pA332* + ID_PRODUCT_FROM_DATABASE=DVB-T Dongle [RTL2832U] + +usb:v1681* + ID_VENDOR_FROM_DATABASE=Prevo Technologies, Inc. + +usb:v1681p0001* + ID_PRODUCT_FROM_DATABASE=Tuner's Dashboard + +usb:v1681p0002* + ID_PRODUCT_FROM_DATABASE=Tubachron + +usb:v1682* + ID_VENDOR_FROM_DATABASE=Maxwise Production Enterprise Ltd. + +usb:v1684* + ID_VENDOR_FROM_DATABASE=Godspeed Computer Corp. + +usb:v1685* + ID_VENDOR_FROM_DATABASE=Delock + +usb:v1685p0200* + ID_PRODUCT_FROM_DATABASE=Infrared adapter + +usb:v1686* + ID_VENDOR_FROM_DATABASE=ZOOM Corporation + +usb:v1686p0045* + ID_PRODUCT_FROM_DATABASE=H4 Digital Recorder + +usb:v1687* + ID_VENDOR_FROM_DATABASE=Kingmax Digital Inc. + +usb:v1687p5289* + ID_PRODUCT_FROM_DATABASE=FlashDisk + +usb:v1687p6211* + ID_PRODUCT_FROM_DATABASE=FlashDisk + +usb:v1688* + ID_VENDOR_FROM_DATABASE=Saab AB + +usb:v1689* + ID_VENDOR_FROM_DATABASE=Razer USA, Ltd + +usb:v1689pFD00* + ID_PRODUCT_FROM_DATABASE=Onza Tournament Edition controller + +usb:v168C* + ID_VENDOR_FROM_DATABASE=Atheros Communications + +usb:v168Cp0001* + ID_PRODUCT_FROM_DATABASE=AR5523 + +usb:v168Cp0002* + ID_PRODUCT_FROM_DATABASE=AR5523 (no firmware) + +usb:v1690* + ID_VENDOR_FROM_DATABASE=Askey Computer Corp. [hex] + +usb:v1690p0101* + ID_PRODUCT_FROM_DATABASE=Creative Modem Blaster DE5670 + +usb:v1690p0102* + ID_PRODUCT_FROM_DATABASE=V1456 VQE-R2 Modem [conexant] + +usb:v1690p0103* + ID_PRODUCT_FROM_DATABASE=1456 VQE-R3 Modem [conexant] + +usb:v1690p0104* + ID_PRODUCT_FROM_DATABASE=HCF V90 Data Fax RTAD Modem + +usb:v1690p0107* + ID_PRODUCT_FROM_DATABASE=HCF V.90 Data,Fax,RTAD Modem + +usb:v1690p0109* + ID_PRODUCT_FROM_DATABASE=MagicXpress V.90 Pocket Modem [conexant] + +usb:v1690p0203* + ID_PRODUCT_FROM_DATABASE=Voyager ADSL Modem Loader + +usb:v1690p0204* + ID_PRODUCT_FROM_DATABASE=Voyager ADSL Modem + +usb:v1690p0205* + ID_PRODUCT_FROM_DATABASE=DSL Modem + +usb:v1690p0206* + ID_PRODUCT_FROM_DATABASE=GlobeSpan ADSL WAN Modem + +usb:v1690p0208* + ID_PRODUCT_FROM_DATABASE=DSL Modem + +usb:v1690p0209* + ID_PRODUCT_FROM_DATABASE=Voyager 100 ADSL Modem + +usb:v1690p0211* + ID_PRODUCT_FROM_DATABASE=Globespan Virata ADSL LAN Modem + +usb:v1690p0212* + ID_PRODUCT_FROM_DATABASE=DSL Modem + +usb:v1690p0213* + ID_PRODUCT_FROM_DATABASE=HM121d DSL Modem + +usb:v1690p0214* + ID_PRODUCT_FROM_DATABASE=HM121d DSL Modem + +usb:v1690p0215* + ID_PRODUCT_FROM_DATABASE=Voyager 105 ADSL Modem + +usb:v1690p0701* + ID_PRODUCT_FROM_DATABASE=WLAN + +usb:v1690p0710* + ID_PRODUCT_FROM_DATABASE=SMCWUSBT-G + +usb:v1690p0711* + ID_PRODUCT_FROM_DATABASE=SMCWUSBT-G (no firmware) + +usb:v1690p0712* + ID_PRODUCT_FROM_DATABASE=AR5523 + +usb:v1690p0713* + ID_PRODUCT_FROM_DATABASE=AR5523 (no firmware) + +usb:v1690p0715* + ID_PRODUCT_FROM_DATABASE=Name: Voyager 1055 Laptop 802.11g Adapter [Broadcom 4320] + +usb:v1690p0722* + ID_PRODUCT_FROM_DATABASE=RT2573 + +usb:v1690p0726* + ID_PRODUCT_FROM_DATABASE=Wi-Fi Wireless LAN Adapter + +usb:v1690p0740* + ID_PRODUCT_FROM_DATABASE=802.11n Wireless LAN Card + +usb:v1690p0901* + ID_PRODUCT_FROM_DATABASE=Voyager 205 ADSL Router + +usb:v1696* + ID_VENDOR_FROM_DATABASE=Hitachi Video and Information System, Inc. + +usb:v1697* + ID_VENDOR_FROM_DATABASE=VTec Test, Inc. + +usb:v16A5* + ID_VENDOR_FROM_DATABASE=Shenzhen Zhengerya Cable Co., Ltd. + +usb:v16A6* + ID_VENDOR_FROM_DATABASE=Unigraf + +usb:v16A6p3000* + ID_PRODUCT_FROM_DATABASE=VTG-3xxx Video Test Generator family + +usb:v16A6p4000* + ID_PRODUCT_FROM_DATABASE=VTG-4xxx Video Test Generator family + +usb:v16A6p5000* + ID_PRODUCT_FROM_DATABASE=VTG-5xxx Video Test Generator family + +usb:v16A6p5001* + ID_PRODUCT_FROM_DATABASE=VTG-5xxx Special (update) mode of VTG-5xxx family + +usb:v16AB* + ID_VENDOR_FROM_DATABASE=Global Sun Technology + +usb:v16ABp7801* + ID_PRODUCT_FROM_DATABASE=AR5523 + +usb:v16ABp7802* + ID_PRODUCT_FROM_DATABASE=AR5523 (no firmware) + +usb:v16ABp7811* + ID_PRODUCT_FROM_DATABASE=AR5523 + +usb:v16ABp7812* + ID_PRODUCT_FROM_DATABASE=AR5523 (no firmware) + +usb:v16AC* + ID_VENDOR_FROM_DATABASE=Dongguan ChingLung Wire & Cable Co., Ltd. + +usb:v16B4* + ID_VENDOR_FROM_DATABASE=iStation + +usb:v16B4p0801* + ID_PRODUCT_FROM_DATABASE=U43 + +usb:v16B5* + ID_VENDOR_FROM_DATABASE=Persentec, Inc. + +usb:v16B5p0002* + ID_PRODUCT_FROM_DATABASE=Otto driving companion + +usb:v16C0* + ID_VENDOR_FROM_DATABASE=Van Ooijen Technische Informatica + +usb:v16C0p03E8* + ID_PRODUCT_FROM_DATABASE=free for internal lab use 1000 + +usb:v16C0p03E9* + ID_PRODUCT_FROM_DATABASE=free for internal lab use 1001 + +usb:v16C0p03EA* + ID_PRODUCT_FROM_DATABASE=free for internal lab use 1002 + +usb:v16C0p03EB* + ID_PRODUCT_FROM_DATABASE=free for internal lab use 1003 + +usb:v16C0p03EC* + ID_PRODUCT_FROM_DATABASE=free for internal lab use 1004 + +usb:v16C0p03ED* + ID_PRODUCT_FROM_DATABASE=free for internal lab use 1005 + +usb:v16C0p03EE* + ID_PRODUCT_FROM_DATABASE=free for internal lab use 1006 + +usb:v16C0p03EF* + ID_PRODUCT_FROM_DATABASE=free for internal lab use 1007 + +usb:v16C0p03F0* + ID_PRODUCT_FROM_DATABASE=free for internal lab use 1008 + +usb:v16C0p03F1* + ID_PRODUCT_FROM_DATABASE=free for internal lab use 1009 + +usb:v16C0p0477* + ID_PRODUCT_FROM_DATABASE=Teensy Rebootor + +usb:v16C0p0478* + ID_PRODUCT_FROM_DATABASE=Teensy Halfkay Bootloader + +usb:v16C0p0479* + ID_PRODUCT_FROM_DATABASE=Teensy Debug + +usb:v16C0p047A* + ID_PRODUCT_FROM_DATABASE=Teensy Serial + +usb:v16C0p047B* + ID_PRODUCT_FROM_DATABASE=Teensy Serial+Debug + +usb:v16C0p047C* + ID_PRODUCT_FROM_DATABASE=Teensy Keyboard + +usb:v16C0p047D* + ID_PRODUCT_FROM_DATABASE=Teensy Keyboard+Debug + +usb:v16C0p047E* + ID_PRODUCT_FROM_DATABASE=Teensy Mouse + +usb:v16C0p047F* + ID_PRODUCT_FROM_DATABASE=Teensy Mouse+Debug + +usb:v16C0p0480* + ID_PRODUCT_FROM_DATABASE=Teensy RawHID + +usb:v16C0p0481* + ID_PRODUCT_FROM_DATABASE=Teensy RawHID+Debug + +usb:v16C0p0482* + ID_PRODUCT_FROM_DATABASE=Teensyduino Keyboard+Mouse+Joystick + +usb:v16C0p0483* + ID_PRODUCT_FROM_DATABASE=Teensyduino Serial + +usb:v16C0p0484* + ID_PRODUCT_FROM_DATABASE=Teensyduino Disk + +usb:v16C0p0485* + ID_PRODUCT_FROM_DATABASE=Teensyduino MIDI + +usb:v16C0p0486* + ID_PRODUCT_FROM_DATABASE=Teensyduino RawHID + +usb:v16C0p0487* + ID_PRODUCT_FROM_DATABASE=Teensyduino Serial+Keyboard+Mouse+Joystick + +usb:v16C0p0488* + ID_PRODUCT_FROM_DATABASE=Teensyduino Flight Sim Controls + +usb:v16C0p05DC* + ID_PRODUCT_FROM_DATABASE=shared ID for use with libusb + +usb:v16C0p05DD* + ID_PRODUCT_FROM_DATABASE=BlackcatUSB2 + +usb:v16C0p05DF* + ID_PRODUCT_FROM_DATABASE=Masterkit MA901 radio + +usb:v16C0p05E1* + ID_PRODUCT_FROM_DATABASE=CDC-ACM class devices (modems) + +usb:v16C0p05E4* + ID_PRODUCT_FROM_DATABASE=MIDI class devices + +usb:v16C0p076B* + ID_PRODUCT_FROM_DATABASE=OpenPCD 13.56MHz RFID Reader + +usb:v16C0p076C* + ID_PRODUCT_FROM_DATABASE=OpenPICC 13.56MHz RFID Simulator (native) + +usb:v16C0p08AC* + ID_PRODUCT_FROM_DATABASE=OpenBeacon USB stick + +usb:v16C0p08CA* + ID_PRODUCT_FROM_DATABASE=Alpermann+Velte Universal Display + +usb:v16C0p08CB* + ID_PRODUCT_FROM_DATABASE=Alpermann+Velte Studio Clock + +usb:v16C0p08CC* + ID_PRODUCT_FROM_DATABASE=Alpermann+Velte SAM7S MT Boot Loader + +usb:v16C0p08CD* + ID_PRODUCT_FROM_DATABASE=Alpermann+Velte SAM7X MT Boot Loader + +usb:v16C0p0A32* + ID_PRODUCT_FROM_DATABASE=jbmedia Light-Manager Pro + +usb:v16C0p27DA* + ID_PRODUCT_FROM_DATABASE=Mouse + +usb:v16C0p27DB* + ID_PRODUCT_FROM_DATABASE=Keyboard + +usb:v16C0p27DC* + ID_PRODUCT_FROM_DATABASE=Joystick + +usb:v16C0p27DD* + ID_PRODUCT_FROM_DATABASE=CDC-ACM class devices (modems) + +usb:v16C0p27DE* + ID_PRODUCT_FROM_DATABASE=MIDI class devices + +usb:v16C0p294A* + ID_PRODUCT_FROM_DATABASE=Eye Movement Recorder [Visagraph] + +usb:v16C0p294B* + ID_PRODUCT_FROM_DATABASE=Eye Movement Recorder [ReadAlyzer] + +usb:v16CA* + ID_VENDOR_FROM_DATABASE=Wireless Cables, Inc. + +usb:v16CAp1502* + ID_PRODUCT_FROM_DATABASE=Bluetooth Dongle + +usb:v16CC* + ID_VENDOR_FROM_DATABASE=silex technology, Inc. + +usb:v16D0* + ID_VENDOR_FROM_DATABASE=MCS + +usb:v16D0p0498* + ID_PRODUCT_FROM_DATABASE=Braintechnology USB-LPS + +usb:v16D0p0504* + ID_PRODUCT_FROM_DATABASE=RETRO Innovations ZoomFloppy + +usb:v16D0p054B* + ID_PRODUCT_FROM_DATABASE=GrauTec ReelBox OLED Display (external) + +usb:v16D0p05BE* + ID_PRODUCT_FROM_DATABASE=EasyLogic Board + +usb:v16D3* + ID_VENDOR_FROM_DATABASE=Frontline Test Equipment, Inc. + +usb:v16D5* + ID_VENDOR_FROM_DATABASE=AnyDATA Corporation + +usb:v16D5p6202* + ID_PRODUCT_FROM_DATABASE=CDMA/UMTS/GPRS modem + +usb:v16D5p6501* + ID_PRODUCT_FROM_DATABASE=CDMA 2000 1xRTT/EV-DO Modem + +usb:v16D5p6502* + ID_PRODUCT_FROM_DATABASE=CDMA/UMTS/GPRS modem + +usb:v16D6* + ID_VENDOR_FROM_DATABASE=JABLOCOM s.r.o. + +usb:v16D6p8000* + ID_PRODUCT_FROM_DATABASE=GDP-04 desktop phone + +usb:v16D6p8001* + ID_PRODUCT_FROM_DATABASE=EYE-02 + +usb:v16D6p8003* + ID_PRODUCT_FROM_DATABASE=GDP-04 modem + +usb:v16D6p8004* + ID_PRODUCT_FROM_DATABASE=Bootloader + +usb:v16D6p8005* + ID_PRODUCT_FROM_DATABASE=GDP-04i + +usb:v16D6p8007* + ID_PRODUCT_FROM_DATABASE=BTP-06 modem + +usb:v16D8* + ID_VENDOR_FROM_DATABASE=CMOTECH Co., Ltd. + +usb:v16D8p5141* + ID_PRODUCT_FROM_DATABASE=CMOTECH CDMA Technologies modem + +usb:v16D8p5533* + ID_PRODUCT_FROM_DATABASE=CCU-550 CDMA EV-DO modem + +usb:v16D8p5543* + ID_PRODUCT_FROM_DATABASE=CDMA 2000 1xRTT/1xEVDO modem + +usb:v16D8p6280* + ID_PRODUCT_FROM_DATABASE=CMOTECH CDMA Technologies modem + +usb:v16D8p6803* + ID_PRODUCT_FROM_DATABASE=CNU-680 CDMA EV-DO modem + +usb:v16D8p8001* + ID_PRODUCT_FROM_DATABASE=Gobi 2000 Wireless Modem (QDL mode) + +usb:v16D8p8002* + ID_PRODUCT_FROM_DATABASE=Gobi 2000 Wireless Modem + +usb:v16DC* + ID_VENDOR_FROM_DATABASE=Wiener, Plein & Baus + +usb:v16DCp0001* + ID_PRODUCT_FROM_DATABASE=CC + +usb:v16DCp000B* + ID_PRODUCT_FROM_DATABASE=VM + +usb:v16DCp0010* + ID_PRODUCT_FROM_DATABASE=PL512 Power Supply System + +usb:v16DCp0011* + ID_PRODUCT_FROM_DATABASE=MARATON Power Supply System + +usb:v16DCp0012* + ID_PRODUCT_FROM_DATABASE=MPOD Multi Channel Power Supply System + +usb:v16DCp0015* + ID_PRODUCT_FROM_DATABASE=CML Control, Measurement and Data Logging System + +usb:v16DF* + ID_VENDOR_FROM_DATABASE=King Billion Electronics Co., Ltd. + +usb:v16F0* + ID_VENDOR_FROM_DATABASE=GN ReSound A/S + +usb:v16F0p0001* + ID_PRODUCT_FROM_DATABASE=Speedlink Programming Interface + +usb:v16F0p0003* + ID_PRODUCT_FROM_DATABASE=Airlink Wireless Programming Interface + +usb:v16F5* + ID_VENDOR_FROM_DATABASE=Futurelogic Inc. + +usb:v1706* + ID_VENDOR_FROM_DATABASE=BlueView Technologies, Inc. + +usb:v1707* + ID_VENDOR_FROM_DATABASE=ARTIMI + +usb:v170B* + ID_VENDOR_FROM_DATABASE=Swissonic + +usb:v170Bp0011* + ID_PRODUCT_FROM_DATABASE=MIDI-USB 1x1 + +usb:v170D* + ID_VENDOR_FROM_DATABASE=Avnera + +usb:v1725* + ID_VENDOR_FROM_DATABASE=Vitesse Semiconductor + +usb:v1726* + ID_VENDOR_FROM_DATABASE=Axesstel, Inc. + +usb:v1726p1000* + ID_PRODUCT_FROM_DATABASE=wireless modem + +usb:v1726p2000* + ID_PRODUCT_FROM_DATABASE=wireless modem + +usb:v1726p3000* + ID_PRODUCT_FROM_DATABASE=wireless modem + +usb:v172F* + ID_VENDOR_FROM_DATABASE=Waltop International Corp. + +usb:v172Fp0022* + ID_PRODUCT_FROM_DATABASE=Tablet + +usb:v172Fp0024* + ID_PRODUCT_FROM_DATABASE=Tablet + +usb:v172Fp0025* + ID_PRODUCT_FROM_DATABASE=Tablet + +usb:v172Fp0026* + ID_PRODUCT_FROM_DATABASE=Tablet + +usb:v172Fp0031* + ID_PRODUCT_FROM_DATABASE=Slim Tablet 12.1" + +usb:v172Fp0032* + ID_PRODUCT_FROM_DATABASE=Slim Tablet 5.8" + +usb:v172Fp0034* + ID_PRODUCT_FROM_DATABASE=Slim Tablet 12.1" + +usb:v172Fp0038* + ID_PRODUCT_FROM_DATABASE=Genius G-Pen F509 + +usb:v172Fp0500* + ID_PRODUCT_FROM_DATABASE=Media Tablet 14.1" + +usb:v172Fp0501* + ID_PRODUCT_FROM_DATABASE=Media Tablet 10.6" + +usb:v172Fp0502* + ID_PRODUCT_FROM_DATABASE=Sirius Battery Free Tablet + +usb:v1733* + ID_VENDOR_FROM_DATABASE=Cellink Technology Co., Ltd + +usb:v1733p0101* + ID_PRODUCT_FROM_DATABASE=RF Wireless Optical Mouse OP-701 + +usb:v1736* + ID_VENDOR_FROM_DATABASE=CANON IMAGING SYSTEM TECHNOLOGIES INC. + +usb:v1737* + ID_VENDOR_FROM_DATABASE=Linksys + +usb:v1737p0039* + ID_PRODUCT_FROM_DATABASE=USB1000 Gigabit Notebook Adapter + +usb:v1737p0070* + ID_PRODUCT_FROM_DATABASE=WUSB100 v1 RangePlus Wireless Network Adapter [Ralink RT2870] + +usb:v1737p0071* + ID_PRODUCT_FROM_DATABASE=WUSB600N v1 Dual-Band Wireless-N Network Adapter [Ralink RT2870] + +usb:v1737p0073* + ID_PRODUCT_FROM_DATABASE=WUSB54GC v2 802.11g Adapter [Realtek RTL8187B] + +usb:v1737p0075* + ID_PRODUCT_FROM_DATABASE=WUSB54GSC v2 802.11g Adapter [Broadcom 4326U] + +usb:v1737p0077* + ID_PRODUCT_FROM_DATABASE=WUSB54GC v3 802.11g Adapter [Ralink RT2070L] + +usb:v1737p0078* + ID_PRODUCT_FROM_DATABASE=WUSB100 v2 RangePlus Wireless Network Adapter [Ralink RT3070] + +usb:v1737p0079* + ID_PRODUCT_FROM_DATABASE=WUSB600N v2 Dual-Band Wireless-N Network Adapter [Ralink RT3572] + +usb:v1740* + ID_VENDOR_FROM_DATABASE=Senao + +usb:v1740p0605* + ID_PRODUCT_FROM_DATABASE=LevelOne WUA-0605 N_Max Wireless USB Adapter + +usb:v1740p0615* + ID_PRODUCT_FROM_DATABASE=LevelOne WUA-0615 N_Max Wireless USB Adapter + +usb:v1740p1000* + ID_PRODUCT_FROM_DATABASE=NUB-350 802.11g Wireless Adapter [Intersil ISL3887] + +usb:v1740p2000* + ID_PRODUCT_FROM_DATABASE=NUB-8301 802.11bg + +usb:v1740p3701* + ID_PRODUCT_FROM_DATABASE=EUB-3701 EXT 802.11g Wireless Adapter [Ralink RT2571W] + +usb:v1740p9603* + ID_PRODUCT_FROM_DATABASE=RTL8188S WLAN Adapter + +usb:v1740p9701* + ID_PRODUCT_FROM_DATABASE=EnGenius 802.11n Wireless USB Adapter + +usb:v1740p9702* + ID_PRODUCT_FROM_DATABASE=EnGenius 802.11n Wireless USB Adapter + +usb:v1740p9703* + ID_PRODUCT_FROM_DATABASE=EnGenius 802.11n Wireless USB Adapter + +usb:v1740p9705* + ID_PRODUCT_FROM_DATABASE=EnGenius 802.11n Wireless USB Adapter + +usb:v1740p9706* + ID_PRODUCT_FROM_DATABASE=EUB9706 802.11n Wireless Adapter [Ralink RT3072] + +usb:v1740p9801* + ID_PRODUCT_FROM_DATABASE=EUB9801 802.11abgn Wireless Adapter [Ralink RT3572] + +usb:v1743* + ID_VENDOR_FROM_DATABASE=General Atomics + +usb:v174C* + ID_VENDOR_FROM_DATABASE=ASMedia Technology Inc. + +usb:v174Cp5106* + ID_PRODUCT_FROM_DATABASE=Transcend StoreJet 25M3 + +usb:v174Cp55AA* + ID_PRODUCT_FROM_DATABASE=ASMedia 2105 SATA bridge + +usb:v174F* + ID_VENDOR_FROM_DATABASE=Syntek + +usb:v174Fp1105* + ID_PRODUCT_FROM_DATABASE=SM-MS/Pro-MMC-XD Card Reader + +usb:v174Fp110B* + ID_PRODUCT_FROM_DATABASE=HP Webcam + +usb:v174Fp1403* + ID_PRODUCT_FROM_DATABASE=Integrated Webcam + +usb:v174Fp1404* + ID_PRODUCT_FROM_DATABASE=USB Camera device, 1.3 MPixel Web Cam + +usb:v174Fp5212* + ID_PRODUCT_FROM_DATABASE=USB 2.0 UVC PC Camera + +usb:v174Fp5A11* + ID_PRODUCT_FROM_DATABASE=PC Camera + +usb:v174Fp5A31* + ID_PRODUCT_FROM_DATABASE=Sonix USB 2.0 Camera + +usb:v174Fp5A35* + ID_PRODUCT_FROM_DATABASE=Sonix 1.3MPixel USB 2.0 Camera + +usb:v174Fp6A31* + ID_PRODUCT_FROM_DATABASE=Web Cam - Asus A8J, F3S, F5R, VX2S, V1S + +usb:v174Fp6A33* + ID_PRODUCT_FROM_DATABASE=Web Cam - Asus F3SA, F9J, F9S + +usb:v174Fp6A51* + ID_PRODUCT_FROM_DATABASE=2.0MPixel Web Cam - Asus Z96J, Z96S, S96S + +usb:v174Fp6A54* + ID_PRODUCT_FROM_DATABASE=Web Cam + +usb:v174Fp6D51* + ID_PRODUCT_FROM_DATABASE=2.0Mpixel Web Cam - Eurocom D900C + +usb:v174Fp8A12* + ID_PRODUCT_FROM_DATABASE=Syntek 0.3MPixel USB 2.0 UVC PC Camera + +usb:v174Fp8A33* + ID_PRODUCT_FROM_DATABASE=Syntek USB 2.0 UVC PC Camera + +usb:v174FpA311* + ID_PRODUCT_FROM_DATABASE=1.3MPixel Web Cam - Asus A3A, A6J, A6K, A6M, A6R, A6T, A6V, A7T, A7sv, A7U + +usb:v174FpA312* + ID_PRODUCT_FROM_DATABASE=1.3MPixel Web Cam + +usb:v174FpA821* + ID_PRODUCT_FROM_DATABASE=Web Cam - Packard Bell BU45, PB Easynote MX66-208W + +usb:v174FpAA11* + ID_PRODUCT_FROM_DATABASE=Web Cam + +usb:v1753* + ID_VENDOR_FROM_DATABASE=GERTEC Telecomunicacoes Ltda. + +usb:v1753pC901* + ID_PRODUCT_FROM_DATABASE=PPC900 Pinpad Terminal + +usb:v1759* + ID_VENDOR_FROM_DATABASE=LucidPort Technology, Inc. + +usb:v1761* + ID_VENDOR_FROM_DATABASE=ASUSTek Computer, Inc. (wrong ID) + +usb:v1761p0B05* + ID_PRODUCT_FROM_DATABASE=802.11n Network Adapter (wrong ID - swapped vendor and device) + +usb:v1772* + ID_VENDOR_FROM_DATABASE=System Level Solutions, Inc. + +usb:v1776* + ID_VENDOR_FROM_DATABASE=Arowana + +usb:v1776p501C* + ID_PRODUCT_FROM_DATABASE=300K CMOS Camera + +usb:v177F* + ID_VENDOR_FROM_DATABASE=Sweex + +usb:v177Fp0004* + ID_PRODUCT_FROM_DATABASE=MM004V5 Photo Key Chain (Digital Photo Frame) 1.5" + +usb:v177Fp0153* + ID_PRODUCT_FROM_DATABASE=LW153 802.11n Adapter [ralink rt3070] + +usb:v177Fp0154* + ID_PRODUCT_FROM_DATABASE=LW154 802.11bgn (1x1:1) Wireless Adapter [Realtek RTL8188SU] + +usb:v177Fp0313* + ID_PRODUCT_FROM_DATABASE=LW313 802.11n Adapter [ralink rt2770 + rt2720] + +usb:v1781* + ID_VENDOR_FROM_DATABASE=Multiple Vendors + +usb:v1781p083E* + ID_PRODUCT_FROM_DATABASE=MetaGeek Wi-Spy + +usb:v1781p083F* + ID_PRODUCT_FROM_DATABASE=MetaGeek Wi-Spy 2.4x + +usb:v1781p0938* + ID_PRODUCT_FROM_DATABASE=Iguanaworks USB IR Transceiver + +usb:v1781p0C30* + ID_PRODUCT_FROM_DATABASE=Telldus TellStick + +usb:v1781p0C31* + ID_PRODUCT_FROM_DATABASE=Telldus TellStick Duo + +usb:v1781p0C9F* + ID_PRODUCT_FROM_DATABASE=USBtiny + +usb:v1782* + ID_VENDOR_FROM_DATABASE=Spreadtrum Communications Inc. + +usb:v1784* + ID_VENDOR_FROM_DATABASE=TopSeed Technology Corp. + +usb:v1784p0001* + ID_PRODUCT_FROM_DATABASE=eHome Infrared Transceiver + +usb:v1784p0004* + ID_PRODUCT_FROM_DATABASE=RF Combo Device + +usb:v1784p0006* + ID_PRODUCT_FROM_DATABASE=eHome Infrared Transceiver + +usb:v1784p0007* + ID_PRODUCT_FROM_DATABASE=eHome Infrared Transceiver + +usb:v1784p0008* + ID_PRODUCT_FROM_DATABASE=eHome Infrared Transceiver + +usb:v1784p000A* + ID_PRODUCT_FROM_DATABASE=eHome Infrared Transceiver + +usb:v1787* + ID_VENDOR_FROM_DATABASE=ATI AIB + +usb:v1788* + ID_VENDOR_FROM_DATABASE=ShenZhen Litkconn Technology Co., Ltd. + +usb:v1796* + ID_VENDOR_FROM_DATABASE=Printrex, Inc. + +usb:v1797* + ID_VENDOR_FROM_DATABASE=JALCO CO., LTD. + +usb:v1799* + ID_VENDOR_FROM_DATABASE=Belkin Components + +usb:v1799p7051* + ID_PRODUCT_FROM_DATABASE=F5D7051 802.11g Adapter v1000 [Broadcom 4320] + +usb:v1799p8051* + ID_PRODUCT_FROM_DATABASE=F5D8051 v2 802.11bgn Wireless Adapter [Marvell 88W8362] + +usb:v179D* + ID_VENDOR_FROM_DATABASE=Ricavision International, Inc. + +usb:v179Dp0010* + ID_PRODUCT_FROM_DATABASE=Internal Infrared Transceiver + +usb:v17A0* + ID_VENDOR_FROM_DATABASE=Samson Technologies Corp. + +usb:v17A0p0001* + ID_PRODUCT_FROM_DATABASE=C01U condenser microphone + +usb:v17A0p0002* + ID_PRODUCT_FROM_DATABASE=Q1U dynamic microphone + +usb:v17A0p0100* + ID_PRODUCT_FROM_DATABASE=C03U multi-pattern microphone + +usb:v17A0p0101* + ID_PRODUCT_FROM_DATABASE=UB1 boundary microphone + +usb:v17A0p0200* + ID_PRODUCT_FROM_DATABASE=StudioDock monitors (internal hub) + +usb:v17A0p0201* + ID_PRODUCT_FROM_DATABASE=StudioDock monitors (audio) + +usb:v17A0p0301* + ID_PRODUCT_FROM_DATABASE=Q2U handheld microphone with XLR + +usb:v17A0p0302* + ID_PRODUCT_FROM_DATABASE=GoMic compact condenser microphone + +usb:v17A0p0310* + ID_PRODUCT_FROM_DATABASE=Meteor condenser microphone + +usb:v17A4* + ID_VENDOR_FROM_DATABASE=Concept2 + +usb:v17A4p0001* + ID_PRODUCT_FROM_DATABASE=Performance Monitor 3 + +usb:v17A4p0002* + ID_PRODUCT_FROM_DATABASE=Performance Monitor 4 + +usb:v17A5* + ID_VENDOR_FROM_DATABASE=Advanced Connection Technology Inc. + +usb:v17A7* + ID_VENDOR_FROM_DATABASE=MICOMSOFT CO., LTD. + +usb:v17A8* + ID_VENDOR_FROM_DATABASE=Kamstrup A/S + +usb:v17A8p0001* + ID_PRODUCT_FROM_DATABASE=Optical Eye/3-wire + +usb:v17A8p0005* + ID_PRODUCT_FROM_DATABASE=M-Bus Master MultiPort 250D + +usb:v17B3* + ID_VENDOR_FROM_DATABASE=Grey Innovation + +usb:v17B3p0004* + ID_PRODUCT_FROM_DATABASE=Linux-USB Midi Gadget + +usb:v17BA* + ID_VENDOR_FROM_DATABASE=SAURIS GmbH + +usb:v17BAp0001* + ID_PRODUCT_FROM_DATABASE=SAU510-USB [no firmware] + +usb:v17BAp0510* + ID_PRODUCT_FROM_DATABASE=SAU510-USB and SAU510-USB plus JTAG Emulators + +usb:v17BAp0511* + ID_PRODUCT_FROM_DATABASE=SAU510-USB Iso Plus JTAG Emulator + +usb:v17BAp0520* + ID_PRODUCT_FROM_DATABASE=SAU510-USB Nano JTAG Emulator + +usb:v17BAp1511* + ID_PRODUCT_FROM_DATABASE=Onboard Emulator on SAUModule development kit + +usb:v17C3* + ID_VENDOR_FROM_DATABASE=Singim International Corp. + +usb:v17CC* + ID_VENDOR_FROM_DATABASE=Native Instruments + +usb:v17CCp041C* + ID_PRODUCT_FROM_DATABASE=Audio 2 DJ + +usb:v17CCp0808* + ID_PRODUCT_FROM_DATABASE=Maschine Controller + +usb:v17CCp0815* + ID_PRODUCT_FROM_DATABASE=Audio Kontrol 1 + +usb:v17CCp0839* + ID_PRODUCT_FROM_DATABASE=Audio 4 DJ + +usb:v17CCp0D8D* + ID_PRODUCT_FROM_DATABASE=Guitarrig Mobile + +usb:v17CCp1915* + ID_PRODUCT_FROM_DATABASE=Session I/O + +usb:v17CCp1940* + ID_PRODUCT_FROM_DATABASE=RigKontrol3 + +usb:v17CCp1969* + ID_PRODUCT_FROM_DATABASE=RigKontrol2 + +usb:v17CCp1978* + ID_PRODUCT_FROM_DATABASE=Audio 8 DJ + +usb:v17CCp2280* + ID_PRODUCT_FROM_DATABASE=Medion MDPNA1500 in card reader mode + +usb:v17CCp2305* + ID_PRODUCT_FROM_DATABASE=Traktor Kontrol X1 + +usb:v17CCp4711* + ID_PRODUCT_FROM_DATABASE=Kore Controller + +usb:v17CCp4712* + ID_PRODUCT_FROM_DATABASE=Kore Controller 2 + +usb:v17CCpBAFF* + ID_PRODUCT_FROM_DATABASE=Traktor Kontrol S4 + +usb:v17CF* + ID_VENDOR_FROM_DATABASE=Hip Hing Cable & Plug Mfy. Ltd. + +usb:v17D0* + ID_VENDOR_FROM_DATABASE=Sanford L.P. + +usb:v17D3* + ID_VENDOR_FROM_DATABASE=Korea Techtron Co., Ltd. + +usb:v17E9* + ID_VENDOR_FROM_DATABASE=DisplayLink + +usb:v17E9p0051* + ID_PRODUCT_FROM_DATABASE=USB VGA Adaptor + +usb:v17E9p0377* + ID_PRODUCT_FROM_DATABASE=Plugable UD-160-A (M) + +usb:v17E9p0378* + ID_PRODUCT_FROM_DATABASE=Plugable UGA-2K-A + +usb:v17E9p0379* + ID_PRODUCT_FROM_DATABASE=Plugable UGA-125 + +usb:v17E9p037A* + ID_PRODUCT_FROM_DATABASE=Plugable UGA-165 + +usb:v17E9p037B* + ID_PRODUCT_FROM_DATABASE=Plugable USB-VGA-165 + +usb:v17E9p037C* + ID_PRODUCT_FROM_DATABASE=Plugable DC-125 + +usb:v17E9p037D* + ID_PRODUCT_FROM_DATABASE=Plugable USB2-HDMI-165 + +usb:v17E9p430A* + ID_PRODUCT_FROM_DATABASE=HP Port Replicator (Composite Device) + +usb:v17EB* + ID_VENDOR_FROM_DATABASE=Cornice, Inc. + +usb:v17EF* + ID_VENDOR_FROM_DATABASE=Lenovo + +usb:v17EFp1003* + ID_PRODUCT_FROM_DATABASE=Integrated Smart Card Reader + +usb:v17EFp1004* + ID_PRODUCT_FROM_DATABASE=Integrated Webcam + +usb:v17EFp100A* + ID_PRODUCT_FROM_DATABASE=ThinkPad Mini Dock Plus Series 3 + +usb:v17EFp3815* + ID_PRODUCT_FROM_DATABASE=ChipsBnk 2GB USB Stick + +usb:v17EFp4802* + ID_PRODUCT_FROM_DATABASE=Lenovo Vc0323+MI1310_SOC Camera + +usb:v17EFp4807* + ID_PRODUCT_FROM_DATABASE=UVC Camera + +usb:v17EFp480C* + ID_PRODUCT_FROM_DATABASE=Integrated Webcam + +usb:v17EFp480D* + ID_PRODUCT_FROM_DATABASE=Integrated Webcam [R5U877] + +usb:v17EFp480E* + ID_PRODUCT_FROM_DATABASE=Integrated Webcam [R5U877] + +usb:v17EFp480F* + ID_PRODUCT_FROM_DATABASE=Integrated Webcam [R5U877] + +usb:v17EFp4810* + ID_PRODUCT_FROM_DATABASE=Integrated Webcam [R5U877] + +usb:v17EFp4811* + ID_PRODUCT_FROM_DATABASE=Integrated Webcam [R5U877] + +usb:v17EFp4812* + ID_PRODUCT_FROM_DATABASE=Integrated Webcam [R5U877] + +usb:v17EFp4813* + ID_PRODUCT_FROM_DATABASE=Integrated Webcam [R5U877] + +usb:v17EFp4814* + ID_PRODUCT_FROM_DATABASE=Integrated Webcam [R5U877] + +usb:v17EFp4815* + ID_PRODUCT_FROM_DATABASE=Integrated Webcam [R5U877] + +usb:v17EFp481C* + ID_PRODUCT_FROM_DATABASE=Integrated Webcam + +usb:v17EFp481D* + ID_PRODUCT_FROM_DATABASE=Integrated Webcam + +usb:v17EFp6007* + ID_PRODUCT_FROM_DATABASE=Smartcard Keyboard + +usb:v17EFp6009* + ID_PRODUCT_FROM_DATABASE=ThinkPad Keyboard with TrackPoint + +usb:v17EFp6014* + ID_PRODUCT_FROM_DATABASE=Mini Wireless Keyboard N5901 + +usb:v17EFp7423* + ID_PRODUCT_FROM_DATABASE=IdeaPad A1 Tablet + +usb:v17F4* + ID_VENDOR_FROM_DATABASE=WaveSense + +usb:v17F4pAAAA* + ID_PRODUCT_FROM_DATABASE=Jazz Blood Glucose Meter + +usb:v17F5* + ID_VENDOR_FROM_DATABASE=K.K. Rocky + +usb:v17F6* + ID_VENDOR_FROM_DATABASE=Unicomp, Inc + +usb:v17F6p0709* + ID_PRODUCT_FROM_DATABASE=Model M Keyboard + +usb:v1809* + ID_VENDOR_FROM_DATABASE=Advantech + +usb:v1809p4604* + ID_PRODUCT_FROM_DATABASE=USB-4604 + +usb:v1809p4761* + ID_PRODUCT_FROM_DATABASE=USB-4761 Portable Data Acquisition Module + +usb:v1822* + ID_VENDOR_FROM_DATABASE=Twinhan + +usb:v1822p3201* + ID_PRODUCT_FROM_DATABASE=VisionDTV USB-Ter/HAMA USB DVB-T device cold + +usb:v1822p3202* + ID_PRODUCT_FROM_DATABASE=VisionDTV USB-Ter/HAMA USB DVB-T device warm + +usb:v1831* + ID_VENDOR_FROM_DATABASE=Gwo Jinn Industries Co., Ltd. + +usb:v1832* + ID_VENDOR_FROM_DATABASE=Huizhou Shenghua Industrial Co., Ltd. + +usb:v183D* + ID_VENDOR_FROM_DATABASE=VIVOphone + +usb:v183Dp0010* + ID_PRODUCT_FROM_DATABASE=VoiceKey + +usb:v1843* + ID_VENDOR_FROM_DATABASE=Vaisala + +usb:v1849* + ID_VENDOR_FROM_DATABASE=ASRock Incorporation + +usb:v1852* + ID_VENDOR_FROM_DATABASE=GYROCOM C&C Co., LTD + +usb:v1852p7922* + ID_PRODUCT_FROM_DATABASE=Audiotrak DR.DAC2 DX [GYROCOM C&C] + +usb:v1854* + ID_VENDOR_FROM_DATABASE=Memory Devices Ltd. + +usb:v185B* + ID_VENDOR_FROM_DATABASE=Compro + +usb:v185Bp3020* + ID_PRODUCT_FROM_DATABASE=K100 Infrared Receiver + +usb:v185Bp3082* + ID_PRODUCT_FROM_DATABASE=K100 Infrared Receiver v2 + +usb:v185BpD000* + ID_PRODUCT_FROM_DATABASE=Compro Videomate DVB-U2000 - DVB-T USB cold + +usb:v185BpD001* + ID_PRODUCT_FROM_DATABASE=Compro Videomate DVB-U2000 - DVB-T USB warm + +usb:v1861* + ID_VENDOR_FROM_DATABASE=Tech Technology Industrial Company + +usb:v1862* + ID_VENDOR_FROM_DATABASE=Teridian Semiconductor Corp. + +usb:v1870* + ID_VENDOR_FROM_DATABASE=Nexio Co., Ltd + +usb:v1870p0001* + ID_PRODUCT_FROM_DATABASE=iNexio Touchscreen controller + +usb:v1871* + ID_VENDOR_FROM_DATABASE=Aveo Technology Corp. + +usb:v1871p0101* + ID_PRODUCT_FROM_DATABASE=UVC camera (Bresser microscope) + +usb:v1871p0D01* + ID_PRODUCT_FROM_DATABASE=USB2.0 Camera + +usb:v1873* + ID_VENDOR_FROM_DATABASE=Navilock + +usb:v1873pEE93* + ID_PRODUCT_FROM_DATABASE=EasyLogger + +usb:v187C* + ID_VENDOR_FROM_DATABASE=Alienware Corporation + +usb:v187Cp0600* + ID_PRODUCT_FROM_DATABASE=Dual Compatible Game Pad + +usb:v187F* + ID_VENDOR_FROM_DATABASE=Siano Mobile Silicon + +usb:v187Fp0010* + ID_PRODUCT_FROM_DATABASE=Stallar Board + +usb:v187Fp0100* + ID_PRODUCT_FROM_DATABASE=Stallar Board + +usb:v187Fp0200* + ID_PRODUCT_FROM_DATABASE=Nova A + +usb:v187Fp0201* + ID_PRODUCT_FROM_DATABASE=Nova B + +usb:v187Fp0202* + ID_PRODUCT_FROM_DATABASE=Nice + +usb:v187Fp0300* + ID_PRODUCT_FROM_DATABASE=Vega + +usb:v187Fp0301* + ID_PRODUCT_FROM_DATABASE=VeNice + +usb:v1892* + ID_VENDOR_FROM_DATABASE=Vast Technologies, Inc. + +usb:v1894* + ID_VENDOR_FROM_DATABASE=Topseed + +usb:v1894p5632* + ID_PRODUCT_FROM_DATABASE=Atek Tote Remote + +usb:v1894p5641* + ID_PRODUCT_FROM_DATABASE=TSAM-004 Presentation Remote + +usb:v1897* + ID_VENDOR_FROM_DATABASE=Evertop Wire Cable Co. + +usb:v189F* + ID_VENDOR_FROM_DATABASE=3Shape A/S + +usb:v189Fp0002* + ID_PRODUCT_FROM_DATABASE=Legato2 3D Scanner + +usb:v18A4* + ID_VENDOR_FROM_DATABASE=CSSN + +usb:v18A4p0001* + ID_PRODUCT_FROM_DATABASE=Snapshell IDR + +usb:v18A5* + ID_VENDOR_FROM_DATABASE=Verbatim, Ltd + +usb:v18A5p0214* + ID_PRODUCT_FROM_DATABASE=Portable Hard Drive + +usb:v18A5p0216* + ID_PRODUCT_FROM_DATABASE=External Hard Drive + +usb:v18A5p0218* + ID_PRODUCT_FROM_DATABASE=External Hard Drive + +usb:v18A5p0227* + ID_PRODUCT_FROM_DATABASE=Pocket Hard Drive + +usb:v18A5p022B* + ID_PRODUCT_FROM_DATABASE=Portable Hard Drive (Store'n'Go) + +usb:v18A5p0237* + ID_PRODUCT_FROM_DATABASE=Portable Harddrive (500 GB) + +usb:v18B1* + ID_VENDOR_FROM_DATABASE=Petalynx + +usb:v18B1p0037* + ID_PRODUCT_FROM_DATABASE=Maxter Remote Control + +usb:v18B4* + ID_VENDOR_FROM_DATABASE=e3C Technologies + +usb:v18B4p1001* + ID_PRODUCT_FROM_DATABASE=DUTV007 + +usb:v18B4p1002* + ID_PRODUCT_FROM_DATABASE=EC168 (v5) based USB DVB-T receiver + +usb:v18B4p1689* + ID_PRODUCT_FROM_DATABASE=DUTV009 + +usb:v18B4pFFFA* + ID_PRODUCT_FROM_DATABASE=EC168 (v2) based USB DVB-T receiver + +usb:v18B4pFFFB* + ID_PRODUCT_FROM_DATABASE=EC168 (v3) based USB DVB-T receiver + +usb:v18B6* + ID_VENDOR_FROM_DATABASE=Mikkon Technology Limited + +usb:v18B7* + ID_VENDOR_FROM_DATABASE=Zotek Electronic Co., Ltd. + +usb:v18C5* + ID_VENDOR_FROM_DATABASE=AMIT Technology, Inc. + +usb:v18C5p0002* + ID_PRODUCT_FROM_DATABASE=CG-WLUSB2GO + +usb:v18C5p0008* + ID_PRODUCT_FROM_DATABASE=CG-WLUSB2GNR Corega Wireless USB Adapter + +usb:v18C5p0012* + ID_PRODUCT_FROM_DATABASE=CG-WLUSB10 Corega Wireless USB Adapter + +usb:v18CD* + ID_VENDOR_FROM_DATABASE=Ecamm + +usb:v18CDpCAFE* + ID_PRODUCT_FROM_DATABASE=Pico iMage + +usb:v18D1* + ID_VENDOR_FROM_DATABASE=Google Inc. + +usb:v18D1p0D02* + ID_PRODUCT_FROM_DATABASE=Celkon A88 + +usb:v18D1p4E11* + ID_PRODUCT_FROM_DATABASE=Nexus One + +usb:v18D1p4E12* + ID_PRODUCT_FROM_DATABASE=Nexus One (debug) + +usb:v18D1p4E13* + ID_PRODUCT_FROM_DATABASE=Nexus One (tether) + +usb:v18D1p4E20* + ID_PRODUCT_FROM_DATABASE=Nexus S (fastboot) + +usb:v18D1p4E21* + ID_PRODUCT_FROM_DATABASE=Nexus S + +usb:v18D1p4E22* + ID_PRODUCT_FROM_DATABASE=Nexus S (debug) + +usb:v18D1p4E24* + ID_PRODUCT_FROM_DATABASE=Nexus S (tether) + +usb:v18D1p7102* + ID_PRODUCT_FROM_DATABASE=Toshiba Thrive tablet + +usb:v18D1pB004* + ID_PRODUCT_FROM_DATABASE=Pandigital / B&N Novel 9" tablet + +usb:v18D5* + ID_VENDOR_FROM_DATABASE=Starline International Group Limited + +usb:v18D9* + ID_VENDOR_FROM_DATABASE=Kaba + +usb:v18D9p01A0* + ID_PRODUCT_FROM_DATABASE=B-Net 91 07 + +usb:v18DC* + ID_VENDOR_FROM_DATABASE=LKC Technologies, Inc. + +usb:v18DD* + ID_VENDOR_FROM_DATABASE=Planon System Solutions Inc. + +usb:v18DDp1000* + ID_PRODUCT_FROM_DATABASE=DocuPen RC800 + +usb:v18E3* + ID_VENDOR_FROM_DATABASE=Fitipower Integrated Technology Inc + +usb:v18E3p7102* + ID_PRODUCT_FROM_DATABASE=Multi Card Reader (Internal) + +usb:v18E3p9101* + ID_PRODUCT_FROM_DATABASE=All-in-1 Card Reader + +usb:v18E3p9102* + ID_PRODUCT_FROM_DATABASE=Multi Card Reader + +usb:v18E3p9512* + ID_PRODUCT_FROM_DATABASE=Webcam + +usb:v18E8* + ID_VENDOR_FROM_DATABASE=Qcom + +usb:v18E8p6144* + ID_PRODUCT_FROM_DATABASE=LR802UA 802.11b Wireless Adapter [ALi M4301AU] + +usb:v18E8p6196* + ID_PRODUCT_FROM_DATABASE=RT2573 + +usb:v18E8p6229* + ID_PRODUCT_FROM_DATABASE=RT2573 + +usb:v18E8p6232* + ID_PRODUCT_FROM_DATABASE=Wireless 802.11g 54Mbps Network Adapter [RTL8187] + +usb:v18EA* + ID_VENDOR_FROM_DATABASE=Matrox Graphics, Inc. + +usb:v18EAp0002* + ID_PRODUCT_FROM_DATABASE=DualHead2Go [Analog Edition] + +usb:v18EAp0004* + ID_PRODUCT_FROM_DATABASE=TripleHead2Go [Digital Edition] + +usb:v18EC* + ID_VENDOR_FROM_DATABASE=Arkmicro Technologies Inc. + +usb:v18ECp3118* + ID_PRODUCT_FROM_DATABASE=USB to IrDA adapter [ARK3116T] + +usb:v18ECp3188* + ID_PRODUCT_FROM_DATABASE=ARK3188 UVC Webcam + +usb:v18FD* + ID_VENDOR_FROM_DATABASE=FineArch Inc. + +usb:v1908* + ID_VENDOR_FROM_DATABASE=GEMBIRD + +usb:v1908p1320* + ID_PRODUCT_FROM_DATABASE=PhotoFrame PF-15-1 + +usb:v190D* + ID_VENDOR_FROM_DATABASE=Motorola GSG + +usb:v1914* + ID_VENDOR_FROM_DATABASE=Alco Digital Devices Limited + +usb:v1915* + ID_VENDOR_FROM_DATABASE=Nordic Semiconductor ASA + +usb:v1915p2233* + ID_PRODUCT_FROM_DATABASE=Linksys WUSB11 v2.8 802.11b Adapter [Atmel AT76C505] + +usb:v1915p2234* + ID_PRODUCT_FROM_DATABASE=Linksys WUSB54G v1 OEM 802.11g Adapter [Intersil ISL3886] + +usb:v1915p2235* + ID_PRODUCT_FROM_DATABASE=Linksys WUSB54GP v1 OEM 802.11g Adapter [Intersil ISL3886] + +usb:v1915p2236* + ID_PRODUCT_FROM_DATABASE=Linksys WUSB11 v3.0 802.11b Adapter [Intersil PRISM 3] + +usb:v1926* + ID_VENDOR_FROM_DATABASE=NextWindow + +usb:v1926p0003* + ID_PRODUCT_FROM_DATABASE=1900 HID Touchscreen + +usb:v1926p0006* + ID_PRODUCT_FROM_DATABASE=1950 HID Touchscreen + +usb:v1926p0064* + ID_PRODUCT_FROM_DATABASE=1950 HID Touchscreen + +usb:v1926p0065* + ID_PRODUCT_FROM_DATABASE=1950 HID Touchscreen + +usb:v1926p0066* + ID_PRODUCT_FROM_DATABASE=1950 HID Touchscreen + +usb:v1926p0067* + ID_PRODUCT_FROM_DATABASE=1950 HID Touchscreen + +usb:v1926p0068* + ID_PRODUCT_FROM_DATABASE=1950 HID Touchscreen + +usb:v1926p0069* + ID_PRODUCT_FROM_DATABASE=1950 HID Touchscreen + +usb:v1926p0071* + ID_PRODUCT_FROM_DATABASE=1950 HID Touchscreen + +usb:v1926p0072* + ID_PRODUCT_FROM_DATABASE=1950 HID Touchscreen + +usb:v1926p0073* + ID_PRODUCT_FROM_DATABASE=1950 HID Touchscreen + +usb:v1926p0074* + ID_PRODUCT_FROM_DATABASE=1950 HID Touchscreen + +usb:v1926p0075* + ID_PRODUCT_FROM_DATABASE=1950 HID Touchscreen + +usb:v1926p0076* + ID_PRODUCT_FROM_DATABASE=1950 HID Touchscreen + +usb:v1926p0077* + ID_PRODUCT_FROM_DATABASE=1950 HID Touchscreen + +usb:v1926p0078* + ID_PRODUCT_FROM_DATABASE=1950 HID Touchscreen + +usb:v1926p0079* + ID_PRODUCT_FROM_DATABASE=1950 HID Touchscreen + +usb:v1926p007A* + ID_PRODUCT_FROM_DATABASE=1950 HID Touchscreen + +usb:v1926p007E* + ID_PRODUCT_FROM_DATABASE=1950 HID Touchscreen + +usb:v1926p007F* + ID_PRODUCT_FROM_DATABASE=1950 HID Touchscreen + +usb:v1926p0080* + ID_PRODUCT_FROM_DATABASE=1950 HID Touchscreen + +usb:v1926p0081* + ID_PRODUCT_FROM_DATABASE=1950 HID Touchscreen + +usb:v1926p0082* + ID_PRODUCT_FROM_DATABASE=1950 HID Touchscreen + +usb:v1926p0083* + ID_PRODUCT_FROM_DATABASE=1950 HID Touchscreen + +usb:v1926p0084* + ID_PRODUCT_FROM_DATABASE=1950 HID Touchscreen + +usb:v1926p0085* + ID_PRODUCT_FROM_DATABASE=1950 HID Touchscreen + +usb:v1926p0086* + ID_PRODUCT_FROM_DATABASE=1950 HID Touchscreen + +usb:v1926p0087* + ID_PRODUCT_FROM_DATABASE=1950 HID Touchscreen + +usb:v192F* + ID_VENDOR_FROM_DATABASE=Avago Technologies, Pte. + +usb:v192Fp0000* + ID_PRODUCT_FROM_DATABASE=Mouse + +usb:v192Fp0416* + ID_PRODUCT_FROM_DATABASE=ADNS-5700 Optical Mouse Controller (3-button) + +usb:v192Fp0616* + ID_PRODUCT_FROM_DATABASE=ADNS-5700 Optical Mouse Controller (5-button) + +usb:v1930* + ID_VENDOR_FROM_DATABASE=Shenzhen Xianhe Technology Co., Ltd. + +usb:v1931* + ID_VENDOR_FROM_DATABASE=Ningbo Broad Telecommunication Co., Ltd. + +usb:v1934* + ID_VENDOR_FROM_DATABASE=Feature Integration Technology Inc. (Fintek) + +usb:v1934p0602* + ID_PRODUCT_FROM_DATABASE=F71610 or F71612 Consumer Infrared Receiver/Transceiver + +usb:v1934p0702* + ID_PRODUCT_FROM_DATABASE=Integrated Consumer Infrared Receiver/Transceiver + +usb:v1934p5168* + ID_PRODUCT_FROM_DATABASE=F71610A or F71612A Consumer Infrared Receiver/Transceiver + +usb:v1941* + ID_VENDOR_FROM_DATABASE=Dream Link + +usb:v1941p8021* + ID_PRODUCT_FROM_DATABASE=WH1080 Weather Station / USB Missile Launcher + +usb:v1943* + ID_VENDOR_FROM_DATABASE=Sensoray Co., Inc. + +usb:v1943p2250* + ID_PRODUCT_FROM_DATABASE=Model 2250 MPEG and JPEG Capture Card + +usb:v1943p2253* + ID_PRODUCT_FROM_DATABASE=Model 2253 Audio/Video Codec Card + +usb:v1943p2255* + ID_PRODUCT_FROM_DATABASE=Model 2255 4 Channel Capture Card + +usb:v1943p2257* + ID_PRODUCT_FROM_DATABASE=Model 2257 4 Channel Capture Card + +usb:v1943pA250* + ID_PRODUCT_FROM_DATABASE=Model 2250 MPEG and JPEG Capture Card (cold) + +usb:v1943pA253* + ID_PRODUCT_FROM_DATABASE=Model 2253 Audio/Video Codec Card (cold) + +usb:v1949* + ID_VENDOR_FROM_DATABASE=Lab126, Inc. + +usb:v1949p0002* + ID_PRODUCT_FROM_DATABASE=Amazon Kindle + +usb:v1949p0004* + ID_PRODUCT_FROM_DATABASE=Amazon Kindle 3/4 + +usb:v1949p0006* + ID_PRODUCT_FROM_DATABASE=Kindle Fire + +usb:v194F* + ID_VENDOR_FROM_DATABASE=PreSonus Audio Electronics, Inc. + +usb:v194Fp0101* + ID_PRODUCT_FROM_DATABASE=AudioBox 22 VSL + +usb:v194Fp0102* + ID_PRODUCT_FROM_DATABASE=AudioBox 44 VSL + +usb:v194Fp0103* + ID_PRODUCT_FROM_DATABASE=AudioBox 1818 VSL + +usb:v194Fp0301* + ID_PRODUCT_FROM_DATABASE=AudioBox + +usb:v1951* + ID_VENDOR_FROM_DATABASE=Hyperstone AG + +usb:v1953* + ID_VENDOR_FROM_DATABASE=Ironkey Inc. + +usb:v1954* + ID_VENDOR_FROM_DATABASE=Radiient Technologies + +usb:v195D* + ID_VENDOR_FROM_DATABASE=Itron Technology iONE + +usb:v195Dp7002* + ID_PRODUCT_FROM_DATABASE=Libra-Q11 IR remote + +usb:v195Dp7006* + ID_PRODUCT_FROM_DATABASE=Libra-Q26 / 1.0 Remote + +usb:v195Dp7777* + ID_PRODUCT_FROM_DATABASE=Scorpius wireless keyboard + +usb:v195Dp7779* + ID_PRODUCT_FROM_DATABASE=Scorpius-P20MT + +usb:v1967* + ID_VENDOR_FROM_DATABASE=CASIO HITACHI Mobile Communications Co., Ltd. + +usb:v196B* + ID_VENDOR_FROM_DATABASE=Wispro Technology Inc. + +usb:v1970* + ID_VENDOR_FROM_DATABASE=Dane-Elec Corp. USA + +usb:v1975* + ID_VENDOR_FROM_DATABASE=Dongguan Guneetal Wire & Cable Co., Ltd. + +usb:v1976* + ID_VENDOR_FROM_DATABASE=Chipsbrand Microelectronics (HK) Co., Ltd. + +usb:v1976p6025* + ID_PRODUCT_FROM_DATABASE=Flash Drive 512 MB + +usb:v1977* + ID_VENDOR_FROM_DATABASE=T-Logic + +usb:v1977p0111* + ID_PRODUCT_FROM_DATABASE=TL203 MP3 Player and Voice Recorder + +usb:v197D* + ID_VENDOR_FROM_DATABASE=Leuze electronic + +usb:v197Dp0222* + ID_PRODUCT_FROM_DATABASE=BCL 508i + +usb:v1989* + ID_VENDOR_FROM_DATABASE=Nuconn Technology Corp. + +usb:v198F* + ID_VENDOR_FROM_DATABASE=Beceem Communications Inc. + +usb:v198Fp0210* + ID_PRODUCT_FROM_DATABASE=BCS200 WiMAX Adapter + +usb:v198Fp0220* + ID_PRODUCT_FROM_DATABASE=BCSM250 WiMAX Adapter + +usb:v1990* + ID_VENDOR_FROM_DATABASE=Acron Precision Industrial Co., Ltd. + +usb:v1995* + ID_VENDOR_FROM_DATABASE=Trillium Technology Pty. Ltd. + +usb:v1995p3202* + ID_PRODUCT_FROM_DATABASE=REC-ADPT-USB (recorder) + +usb:v1995p3203* + ID_PRODUCT_FROM_DATABASE=REC-A-ADPT-USB (recorder) + +usb:v199B* + ID_VENDOR_FROM_DATABASE=MicroStrain, Inc. + +usb:v199Bp3065* + ID_PRODUCT_FROM_DATABASE=3DM-GX3-25 Orientation Sensor + +usb:v199E* + ID_VENDOR_FROM_DATABASE=The Imaging Source Europe GmbH + +usb:v199Ep8101* + ID_PRODUCT_FROM_DATABASE=DFx 21BU04 Camera + +usb:v199F* + ID_VENDOR_FROM_DATABASE=Benica Corporation + +usb:v19A8* + ID_VENDOR_FROM_DATABASE=Biforst Technology Inc. + +usb:v19AB* + ID_VENDOR_FROM_DATABASE=Bodelin + +usb:v19ABp1000* + ID_PRODUCT_FROM_DATABASE=ProScope HR + +usb:v19AF* + ID_VENDOR_FROM_DATABASE=S Life + +usb:v19AFp6611* + ID_PRODUCT_FROM_DATABASE=Celestia VoIP Phone + +usb:v19B2* + ID_VENDOR_FROM_DATABASE=Batronix + +usb:v19B2p0010* + ID_PRODUCT_FROM_DATABASE=BX32 Batupo + +usb:v19B2p0011* + ID_PRODUCT_FROM_DATABASE=BX32P Barlino + +usb:v19B2p0012* + ID_PRODUCT_FROM_DATABASE=BX40 Bagero + +usb:v19B2p0013* + ID_PRODUCT_FROM_DATABASE=BX48 Batego + +usb:v19B4* + ID_VENDOR_FROM_DATABASE=Celestron + +usb:v19B4p0002* + ID_PRODUCT_FROM_DATABASE=SkyScout Personal Planetarium + +usb:v19B4p0101* + ID_PRODUCT_FROM_DATABASE=Handheld Digital Microscope 44302 + +usb:v19B5* + ID_VENDOR_FROM_DATABASE=B & W Group + +usb:v19B6* + ID_VENDOR_FROM_DATABASE=Infotech Logistic, LLC + +usb:v19B9* + ID_VENDOR_FROM_DATABASE=Data Robotics + +usb:v19B9p8D20* + ID_PRODUCT_FROM_DATABASE=Drobo Elite + +usb:v19C2* + ID_VENDOR_FROM_DATABASE=Futuba + +usb:v19C2p6A11* + ID_PRODUCT_FROM_DATABASE=MDM166A Fluorescent Display + +usb:v19CA* + ID_VENDOR_FROM_DATABASE=Mindtribe + +usb:v19CAp0001* + ID_PRODUCT_FROM_DATABASE=Sandio 3D HID Mouse + +usb:v19CF* + ID_VENDOR_FROM_DATABASE=Parrot SA + +usb:v19D2* + ID_VENDOR_FROM_DATABASE=ZTE WCDMA Technologies MSM + +usb:v19D2p0001* + ID_PRODUCT_FROM_DATABASE=CDMA Wireless Modem + +usb:v19D2p0002* + ID_PRODUCT_FROM_DATABASE=MF632/ONDA ET502HS/MT505UP + +usb:v19D2p0007* + ID_PRODUCT_FROM_DATABASE=TU25 WiMAX Adapter [Beceem BCS200] + +usb:v19D2p0031* + ID_PRODUCT_FROM_DATABASE=MF110/MF627/MF636 + +usb:v19D2p0063* + ID_PRODUCT_FROM_DATABASE=K3565-Z HSDPA + +usb:v19D2p0064* + ID_PRODUCT_FROM_DATABASE=MF627 AU + +usb:v19D2p0083* + ID_PRODUCT_FROM_DATABASE=MF190 + +usb:v19D2p0103* + ID_PRODUCT_FROM_DATABASE=MF112 + +usb:v19D2p0104* + ID_PRODUCT_FROM_DATABASE=K4505-Z + +usb:v19D2p0167* + ID_PRODUCT_FROM_DATABASE=MF820 4G LTE + +usb:v19D2p0172* + ID_PRODUCT_FROM_DATABASE=AX226 WIMAX MODEM (After Modeswitch) + +usb:v19D2p0325* + ID_PRODUCT_FROM_DATABASE=LTE4G O2 ZTE MF821D LTE/UMTS/GSM Modem/Networkcard + +usb:v19D2p0326* + ID_PRODUCT_FROM_DATABASE=LTE4G O2 ZTE MF821D LTE/UMTS/GSM Modem/Networkcard + +usb:v19D2p1008* + ID_PRODUCT_FROM_DATABASE=K3570-Z + +usb:v19D2p1010* + ID_PRODUCT_FROM_DATABASE=K3571-Z + +usb:v19D2p1017* + ID_PRODUCT_FROM_DATABASE=K5006-Z vodafone LTE/UMTS/GSM Modem/Networkcard + +usb:v19D2p1018* + ID_PRODUCT_FROM_DATABASE=K5006-Z vodafone LTE/UMTS/GSM Modem/Networkcard + +usb:v19D2p1203* + ID_PRODUCT_FROM_DATABASE=MF691 [ T-Mobile webConnect Rocket 2.0] + +usb:v19D2p1217* + ID_PRODUCT_FROM_DATABASE=MF652 + +usb:v19D2p1218* + ID_PRODUCT_FROM_DATABASE=MF652 + +usb:v19D2p2000* + ID_PRODUCT_FROM_DATABASE=MF627/MF628/MF628+/MF636+ HSDPA/HSUPA + +usb:v19D2pFFF2* + ID_PRODUCT_FROM_DATABASE=Gobi Wireless Modem (QDL mode) + +usb:v19D2pFFF3* + ID_PRODUCT_FROM_DATABASE=Gobi Wireless Modem + +usb:v19E1* + ID_VENDOR_FROM_DATABASE=WeiDuan Electronic Accessory (S.Z.) Co., Ltd. + +usb:v19E8* + ID_VENDOR_FROM_DATABASE=Industrial Technology Research Institute + +usb:v19EF* + ID_VENDOR_FROM_DATABASE=Pak Heng Technology (Shenzhen) Co., Ltd. + +usb:v19F7* + ID_VENDOR_FROM_DATABASE=RODE Microphones + +usb:v19F7p0001* + ID_PRODUCT_FROM_DATABASE=Podcaster + +usb:v19FA* + ID_VENDOR_FROM_DATABASE=Gampaq Co.Ltd + +usb:v19FAp0703* + ID_PRODUCT_FROM_DATABASE=Steering Wheel + +usb:v19FF* + ID_VENDOR_FROM_DATABASE=Dynex + +usb:v19FFp0102* + ID_PRODUCT_FROM_DATABASE=1.3MP Webcam + +usb:v19FFp0201* + ID_PRODUCT_FROM_DATABASE=Rocketfish Wireless 2.4G Laser Mouse + +usb:v1A08* + ID_VENDOR_FROM_DATABASE=Bellwood International, Inc. + +usb:v1A0A* + ID_VENDOR_FROM_DATABASE=USB-IF non-workshop + +usb:v1A0ApBADD* + ID_PRODUCT_FROM_DATABASE=USB OTG Compliance test device + +usb:v1A12* + ID_VENDOR_FROM_DATABASE=KES Co., Ltd. + +usb:v1A1D* + ID_VENDOR_FROM_DATABASE=Veho + +usb:v1A1Dp0407* + ID_PRODUCT_FROM_DATABASE=Mimi WiFi speakers + +usb:v1A25* + ID_VENDOR_FROM_DATABASE=Amphenol East Asia Ltd. + +usb:v1A2A* + ID_VENDOR_FROM_DATABASE=Seagate Branded Solutions + +usb:v1A2C* + ID_VENDOR_FROM_DATABASE=China Resource Semico Co., Ltd + +usb:v1A2Cp0021* + ID_PRODUCT_FROM_DATABASE=Keyboard + +usb:v1A2Cp0024* + ID_PRODUCT_FROM_DATABASE=Multimedia Keyboard + +usb:v1A32* + ID_VENDOR_FROM_DATABASE=Quanta Microsystems, Inc. + +usb:v1A32p0304* + ID_PRODUCT_FROM_DATABASE=802.11n Wireless LAN Card + +usb:v1A34* + ID_VENDOR_FROM_DATABASE=ACRUX + +usb:v1A34p0802* + ID_PRODUCT_FROM_DATABASE=Gamepad + +usb:v1A36* + ID_VENDOR_FROM_DATABASE=Biwin Technology Ltd. + +usb:v1A40* + ID_VENDOR_FROM_DATABASE=Terminus Technology Inc. + +usb:v1A40p0101* + ID_PRODUCT_FROM_DATABASE=4-Port HUB + +usb:v1A40p0201* + ID_PRODUCT_FROM_DATABASE=FE 2.1 7-port Hub + +usb:v1A41* + ID_VENDOR_FROM_DATABASE=Action Electronics Co., Ltd. + +usb:v1A44* + ID_VENDOR_FROM_DATABASE=VASCO Data Security International + +usb:v1A44p0001* + ID_PRODUCT_FROM_DATABASE=Digipass 905 SmartCard Reader + +usb:v1A4A* + ID_VENDOR_FROM_DATABASE=Silicon Image + +usb:v1A4B* + ID_VENDOR_FROM_DATABASE=SafeBoot International B.V. + +usb:v1A5A* + ID_VENDOR_FROM_DATABASE=Tandberg Data + +usb:v1A61* + ID_VENDOR_FROM_DATABASE=Abbott Diabetes Care + +usb:v1A61p3410* + ID_PRODUCT_FROM_DATABASE=CoPilot System Cable + +usb:v1A6A* + ID_VENDOR_FROM_DATABASE=Spansion Inc. + +usb:v1A6D* + ID_VENDOR_FROM_DATABASE=SamYoung Electronics Co., Ltd + +usb:v1A6E* + ID_VENDOR_FROM_DATABASE=Global Unichip Corp. + +usb:v1A6F* + ID_VENDOR_FROM_DATABASE=Sagem Orga GmbH + +usb:v1A72* + ID_VENDOR_FROM_DATABASE=Physik Instrumente + +usb:v1A72p1008* + ID_PRODUCT_FROM_DATABASE=E-861 PiezoWalk NEXACT Controller + +usb:v1A79* + ID_VENDOR_FROM_DATABASE=Bayer Health Care LLC + +usb:v1A7B* + ID_VENDOR_FROM_DATABASE=Lumberg Connect GmbH & Co. KG + +usb:v1A7C* + ID_VENDOR_FROM_DATABASE=Evoluent + +usb:v1A7Cp0068* + ID_PRODUCT_FROM_DATABASE=VerticalMouse 3 + +usb:v1A7Cp0168* + ID_PRODUCT_FROM_DATABASE=VerticalMouse 3 Wireless + +usb:v1A7Cp0191* + ID_PRODUCT_FROM_DATABASE=VerticalMouse 4 + +usb:v1A81* + ID_VENDOR_FROM_DATABASE=Holtek Semiconductor, Inc. + +usb:v1A81p2203* + ID_PRODUCT_FROM_DATABASE=Laser Gaming mouse + +usb:v1A81p2204* + ID_PRODUCT_FROM_DATABASE=Optical Mouse + +usb:v1A81p2205* + ID_PRODUCT_FROM_DATABASE=Laser Mouse + +usb:v1A86* + ID_VENDOR_FROM_DATABASE=QinHeng Electronics + +usb:v1A86p5523* + ID_PRODUCT_FROM_DATABASE=CH341 in serial mode, usb to serial port converter + +usb:v1A86p5584* + ID_PRODUCT_FROM_DATABASE=CH341 in parallel mode, usb to printer port converter + +usb:v1A86p7523* + ID_PRODUCT_FROM_DATABASE=HL-340 USB-Serial adapter + +usb:v1A86p752D* + ID_PRODUCT_FROM_DATABASE=CH345 MIDI adapter + +usb:v1A86p7584* + ID_PRODUCT_FROM_DATABASE=CH340S + +usb:v1A86pE008* + ID_PRODUCT_FROM_DATABASE=HID-based serial adapater + +usb:v1A89* + ID_VENDOR_FROM_DATABASE=Dynalith Systems Co., Ltd. + +usb:v1A8B* + ID_VENDOR_FROM_DATABASE=SGS Taiwan Ltd. + +usb:v1A8D* + ID_VENDOR_FROM_DATABASE=BandRich, Inc. + +usb:v1A8Dp1002* + ID_PRODUCT_FROM_DATABASE=BandLuxe 3.5G HSDPA Adapter + +usb:v1A8Dp1009* + ID_PRODUCT_FROM_DATABASE=BandLuxe 3.5G HSPA Adapter + +usb:v1A8Dp100D* + ID_PRODUCT_FROM_DATABASE=4G LTE adapter + +usb:v1A98* + ID_VENDOR_FROM_DATABASE=Leica Camera AG + +usb:v1AA4* + ID_VENDOR_FROM_DATABASE=Data Drive Thru, Inc. + +usb:v1AA5* + ID_VENDOR_FROM_DATABASE=UBeacon Technologies, Inc. + +usb:v1AA6* + ID_VENDOR_FROM_DATABASE=eFortune Technology Corp. + +usb:v1AAD* + ID_VENDOR_FROM_DATABASE=KeeTouch + +usb:v1AADp0001* + ID_PRODUCT_FROM_DATABASE=Touchscreen + +usb:v1AB1* + ID_VENDOR_FROM_DATABASE=Rigol Technologies + +usb:v1AB1p0588* + ID_PRODUCT_FROM_DATABASE=DS1000 SERIES + +usb:v1ACB* + ID_VENDOR_FROM_DATABASE=Salcomp Plc + +usb:v1AD1* + ID_VENDOR_FROM_DATABASE=Desay Wire Co., Ltd. + +usb:v1AD4* + ID_VENDOR_FROM_DATABASE=APS + +usb:v1AD4p0002* + ID_PRODUCT_FROM_DATABASE=KM290-HRS + +usb:v1ADB* + ID_VENDOR_FROM_DATABASE=SEL C662 Serial Cable + +usb:v1AE4* + ID_VENDOR_FROM_DATABASE=ic-design Reinhard Gottinger GmbH + +usb:v1AE7* + ID_VENDOR_FROM_DATABASE=X-TENSIONS + +usb:v1AE7p0381* + ID_PRODUCT_FROM_DATABASE=VS-DVB-T 380U (af9015 based) + +usb:v1AE7p2001* + ID_PRODUCT_FROM_DATABASE=SpeedLink SL-6825 + +usb:v1AED* + ID_VENDOR_FROM_DATABASE=High Top Precision Electronic Co., Ltd. + +usb:v1AEF* + ID_VENDOR_FROM_DATABASE=Conntech Electronic (Suzhou) Corporation + +usb:v1AF1* + ID_VENDOR_FROM_DATABASE=Connect One Ltd. + +usb:v1AFE* + ID_VENDOR_FROM_DATABASE=A. Eberle GmbH & Co. KG + +usb:v1AFEp0001* + ID_PRODUCT_FROM_DATABASE=PQ Box 100 + +usb:v1B04* + ID_VENDOR_FROM_DATABASE=Meilhaus Electronic GmbH + +usb:v1B04p0630* + ID_PRODUCT_FROM_DATABASE=ME-630 + +usb:v1B04p0940* + ID_PRODUCT_FROM_DATABASE=ME-94 + +usb:v1B04p0950* + ID_PRODUCT_FROM_DATABASE=ME-95 + +usb:v1B04p0960* + ID_PRODUCT_FROM_DATABASE=ME-96 + +usb:v1B04p1000* + ID_PRODUCT_FROM_DATABASE=ME-1000 + +usb:v1B04p100A* + ID_PRODUCT_FROM_DATABASE=ME-1000 + +usb:v1B04p100B* + ID_PRODUCT_FROM_DATABASE=ME-1000 + +usb:v1B04p1400* + ID_PRODUCT_FROM_DATABASE=ME-1400 + +usb:v1B04p140A* + ID_PRODUCT_FROM_DATABASE=ME-1400A + +usb:v1B04p140B* + ID_PRODUCT_FROM_DATABASE=ME-1400B + +usb:v1B04p140C* + ID_PRODUCT_FROM_DATABASE=ME-1400C + +usb:v1B04p140D* + ID_PRODUCT_FROM_DATABASE=ME-1400D + +usb:v1B04p140E* + ID_PRODUCT_FROM_DATABASE=ME-1400E + +usb:v1B04p14EA* + ID_PRODUCT_FROM_DATABASE=ME-1400EA + +usb:v1B04p14EB* + ID_PRODUCT_FROM_DATABASE=ME-1400EB + +usb:v1B04p1604* + ID_PRODUCT_FROM_DATABASE=ME-1600/4U + +usb:v1B04p1608* + ID_PRODUCT_FROM_DATABASE=ME-1600/8U + +usb:v1B04p160C* + ID_PRODUCT_FROM_DATABASE=ME-1600/12U + +usb:v1B04p160F* + ID_PRODUCT_FROM_DATABASE=ME-1600/16U + +usb:v1B04p168F* + ID_PRODUCT_FROM_DATABASE=ME-1600/16U8I + +usb:v1B04p4610* + ID_PRODUCT_FROM_DATABASE=ME-4610 + +usb:v1B04p4650* + ID_PRODUCT_FROM_DATABASE=ME-4650 + +usb:v1B04p4660* + ID_PRODUCT_FROM_DATABASE=ME-4660 + +usb:v1B04p4661* + ID_PRODUCT_FROM_DATABASE=ME-4660I + +usb:v1B04p4662* + ID_PRODUCT_FROM_DATABASE=ME-4660 + +usb:v1B04p4663* + ID_PRODUCT_FROM_DATABASE=ME-4660I + +usb:v1B04p4670* + ID_PRODUCT_FROM_DATABASE=ME-4670 + +usb:v1B04p4671* + ID_PRODUCT_FROM_DATABASE=ME-4670I + +usb:v1B04p4672* + ID_PRODUCT_FROM_DATABASE=ME-4670S + +usb:v1B04p4673* + ID_PRODUCT_FROM_DATABASE=ME-4670IS + +usb:v1B04p4680* + ID_PRODUCT_FROM_DATABASE=ME-4680 + +usb:v1B04p4681* + ID_PRODUCT_FROM_DATABASE=ME-4680I + +usb:v1B04p4682* + ID_PRODUCT_FROM_DATABASE=ME-4680S + +usb:v1B04p4683* + ID_PRODUCT_FROM_DATABASE=ME-4680IS + +usb:v1B04p6004* + ID_PRODUCT_FROM_DATABASE=ME-6000/4 + +usb:v1B04p6008* + ID_PRODUCT_FROM_DATABASE=ME-6000/8 + +usb:v1B04p600F* + ID_PRODUCT_FROM_DATABASE=ME-6000/16 + +usb:v1B04p6014* + ID_PRODUCT_FROM_DATABASE=ME-6000I/4 + +usb:v1B04p6018* + ID_PRODUCT_FROM_DATABASE=ME-6000I/8 + +usb:v1B04p601F* + ID_PRODUCT_FROM_DATABASE=ME-6000I/16 + +usb:v1B04p6034* + ID_PRODUCT_FROM_DATABASE=ME-6000ISLE/4 + +usb:v1B04p6038* + ID_PRODUCT_FROM_DATABASE=ME-6000ISLE/8 + +usb:v1B04p603F* + ID_PRODUCT_FROM_DATABASE=ME-6000ISLE/16 + +usb:v1B04p6044* + ID_PRODUCT_FROM_DATABASE=ME-6000/4/DIO + +usb:v1B04p6048* + ID_PRODUCT_FROM_DATABASE=ME-6000/8/DIO + +usb:v1B04p604F* + ID_PRODUCT_FROM_DATABASE=ME-6000/16/DIO + +usb:v1B04p6054* + ID_PRODUCT_FROM_DATABASE=ME-6000I/4/DIO + +usb:v1B04p6058* + ID_PRODUCT_FROM_DATABASE=ME-6000I/8/DIO + +usb:v1B04p605F* + ID_PRODUCT_FROM_DATABASE=ME-6000I/16/DIO + +usb:v1B04p6074* + ID_PRODUCT_FROM_DATABASE=ME-6000ISLE/4/DIO + +usb:v1B04p6078* + ID_PRODUCT_FROM_DATABASE=ME-6000ISLE/8/DIO + +usb:v1B04p607F* + ID_PRODUCT_FROM_DATABASE=ME-6000ISLE/16/DIO + +usb:v1B04p6104* + ID_PRODUCT_FROM_DATABASE=ME-6100/4 + +usb:v1B04p6108* + ID_PRODUCT_FROM_DATABASE=ME-6100/8 + +usb:v1B04p610F* + ID_PRODUCT_FROM_DATABASE=ME-6100/16 + +usb:v1B04p6114* + ID_PRODUCT_FROM_DATABASE=ME-6100I/4 + +usb:v1B04p6118* + ID_PRODUCT_FROM_DATABASE=ME-6100I/8 + +usb:v1B04p611F* + ID_PRODUCT_FROM_DATABASE=ME-6100I/16 + +usb:v1B04p6134* + ID_PRODUCT_FROM_DATABASE=ME-6100ISLE/4 + +usb:v1B04p6138* + ID_PRODUCT_FROM_DATABASE=ME-6100ISLE/8 + +usb:v1B04p613F* + ID_PRODUCT_FROM_DATABASE=ME-6100ISLE/16 + +usb:v1B04p6144* + ID_PRODUCT_FROM_DATABASE=ME-6100/4/DIO + +usb:v1B04p6148* + ID_PRODUCT_FROM_DATABASE=ME-6100/8/DIO + +usb:v1B04p614F* + ID_PRODUCT_FROM_DATABASE=ME-6100/16/DIO + +usb:v1B04p6154* + ID_PRODUCT_FROM_DATABASE=ME-6100I/4/DIO + +usb:v1B04p6158* + ID_PRODUCT_FROM_DATABASE=ME-6100I/8/DIO + +usb:v1B04p615F* + ID_PRODUCT_FROM_DATABASE=ME-6100I/16/DIO + +usb:v1B04p6174* + ID_PRODUCT_FROM_DATABASE=ME-6100ISLE/4/DIO + +usb:v1B04p6178* + ID_PRODUCT_FROM_DATABASE=ME-6100ISLE/8/DIO + +usb:v1B04p617F* + ID_PRODUCT_FROM_DATABASE=ME-6100ISLE/16/DIO + +usb:v1B04p6259* + ID_PRODUCT_FROM_DATABASE=ME-6200I/9/DIO + +usb:v1B04p6359* + ID_PRODUCT_FROM_DATABASE=ME-6300I/9/DIO + +usb:v1B04p810A* + ID_PRODUCT_FROM_DATABASE=ME-8100A + +usb:v1B04p810B* + ID_PRODUCT_FROM_DATABASE=ME-8100B + +usb:v1B04p820A* + ID_PRODUCT_FROM_DATABASE=ME-8200A + +usb:v1B04p820B* + ID_PRODUCT_FROM_DATABASE=ME-8200B + +usb:v1B0E* + ID_VENDOR_FROM_DATABASE=BLUTRONICS S.r.l. + +usb:v1B0Ep1078* + ID_PRODUCT_FROM_DATABASE=BLUDRIVE II CCID + +usb:v1B0Ep1079* + ID_PRODUCT_FROM_DATABASE=BLUDRIVE II CCID + +usb:v1B0Ep1080* + ID_PRODUCT_FROM_DATABASE=WRITECHIP II CCID + +usb:v1B1C* + ID_VENDOR_FROM_DATABASE=Corsair + +usb:v1B1Cp0890* + ID_PRODUCT_FROM_DATABASE=Flash Padlock + +usb:v1B1Cp0A00* + ID_PRODUCT_FROM_DATABASE=SP2500 Speakers + +usb:v1B1Cp0A60* + ID_PRODUCT_FROM_DATABASE=Vengeance K60 Keyboard + +usb:v1B1Cp1A01* + ID_PRODUCT_FROM_DATABASE=Flash Voyager GT + +usb:v1B1Cp1A0A* + ID_PRODUCT_FROM_DATABASE=Survivor Stealth Flash Drive + +usb:v1B1Cp1A90* + ID_PRODUCT_FROM_DATABASE=Flash Voyager GT + +usb:v1B20* + ID_VENDOR_FROM_DATABASE=MStar Semiconductor, Inc. + +usb:v1B22* + ID_VENDOR_FROM_DATABASE=WiLinx Corp. + +usb:v1B26* + ID_VENDOR_FROM_DATABASE=Cellex Power Products, Inc. + +usb:v1B27* + ID_VENDOR_FROM_DATABASE=Current Electronics Inc. + +usb:v1B28* + ID_VENDOR_FROM_DATABASE=NAVIsis Inc. + +usb:v1B32* + ID_VENDOR_FROM_DATABASE=Ugobe Life Forms, Inc. + +usb:v1B32p0064* + ID_PRODUCT_FROM_DATABASE=Pleo robotic dinosaur + +usb:v1B36* + ID_VENDOR_FROM_DATABASE=ViXS Systems, Inc. + +usb:v1B3B* + ID_VENDOR_FROM_DATABASE=iPassion Technology Inc. + +usb:v1B3Bp2933* + ID_PRODUCT_FROM_DATABASE=PC Camera/Webcam controller + +usb:v1B3Bp2935* + ID_PRODUCT_FROM_DATABASE=PC Camera/Webcam controller + +usb:v1B3Bp2936* + ID_PRODUCT_FROM_DATABASE=PC Camera/Webcam controller + +usb:v1B3Bp2937* + ID_PRODUCT_FROM_DATABASE=PC Camera/Webcam controller + +usb:v1B3Bp2938* + ID_PRODUCT_FROM_DATABASE=PC Camera/Webcam controller + +usb:v1B3Bp2939* + ID_PRODUCT_FROM_DATABASE=PC Camera/Webcam controller + +usb:v1B3Bp2950* + ID_PRODUCT_FROM_DATABASE=PC Camera/Webcam controller + +usb:v1B3Bp2951* + ID_PRODUCT_FROM_DATABASE=PC Camera/Webcam controller + +usb:v1B3Bp2952* + ID_PRODUCT_FROM_DATABASE=PC Camera/Webcam controller + +usb:v1B3Bp2953* + ID_PRODUCT_FROM_DATABASE=PC Camera/Webcam controller + +usb:v1B3Bp2955* + ID_PRODUCT_FROM_DATABASE=PC Camera/Webcam controller + +usb:v1B3Bp2956* + ID_PRODUCT_FROM_DATABASE=PC Camera/Webcam controller + +usb:v1B3Bp2957* + ID_PRODUCT_FROM_DATABASE=PC Camera/Webcam controller + +usb:v1B3Bp2958* + ID_PRODUCT_FROM_DATABASE=PC Camera/Webcam controller + +usb:v1B3Bp2959* + ID_PRODUCT_FROM_DATABASE=PC Camera/Webcam controller + +usb:v1B3Bp2960* + ID_PRODUCT_FROM_DATABASE=PC Camera/Webcam controller + +usb:v1B3Bp2961* + ID_PRODUCT_FROM_DATABASE=PC Camera/Webcam controller + +usb:v1B3Bp2962* + ID_PRODUCT_FROM_DATABASE=PC Camera/Webcam controller + +usb:v1B3Bp2963* + ID_PRODUCT_FROM_DATABASE=PC Camera/Webcam controller + +usb:v1B3Bp2965* + ID_PRODUCT_FROM_DATABASE=PC Camera/Webcam controller + +usb:v1B3Bp2966* + ID_PRODUCT_FROM_DATABASE=PC Camera/Webcam controller + +usb:v1B3Bp2967* + ID_PRODUCT_FROM_DATABASE=PC Camera/Webcam controller + +usb:v1B3Bp2968* + ID_PRODUCT_FROM_DATABASE=PC Camera/Webcam controller + +usb:v1B3Bp2969* + ID_PRODUCT_FROM_DATABASE=PC Camera/Webcam controller + +usb:v1B3F* + ID_VENDOR_FROM_DATABASE=Generalplus Technology Inc. + +usb:v1B3Fp0C52* + ID_PRODUCT_FROM_DATABASE=808 Camera #9 (mass storage mode) + +usb:v1B3Fp2002* + ID_PRODUCT_FROM_DATABASE=808 Camera #9 (web-cam mode) + +usb:v1B47* + ID_VENDOR_FROM_DATABASE=Energizer Holdings, Inc. + +usb:v1B47p0001* + ID_PRODUCT_FROM_DATABASE=CHUSB Duo Charger (NiMH AA/AAA USB smart charger) + +usb:v1B48* + ID_VENDOR_FROM_DATABASE=Plastron Precision Co., Ltd. + +usb:v1B59* + ID_VENDOR_FROM_DATABASE=K.S. Terminals Inc. + +usb:v1B5A* + ID_VENDOR_FROM_DATABASE=Chao Zhou Kai Yuan Electric Co., Ltd. + +usb:v1B65* + ID_VENDOR_FROM_DATABASE=The Hong Kong Standards and Testing Centre Ltd. + +usb:v1B72* + ID_VENDOR_FROM_DATABASE=ATERGI TECHNOLOGY CO., LTD. + +usb:v1B73* + ID_VENDOR_FROM_DATABASE=Fresco Logic + +usb:v1B73p1000* + ID_PRODUCT_FROM_DATABASE=xHC1 Controller + +usb:v1B75* + ID_VENDOR_FROM_DATABASE=Ovislink Corp. + +usb:v1B75p3072* + ID_PRODUCT_FROM_DATABASE=AirLive WN-360USB adapter + +usb:v1B75p8171* + ID_PRODUCT_FROM_DATABASE=WN-370USB 802.11bgn Wireless Adapter [Realtek RTL8188SU] + +usb:v1B75p8187* + ID_PRODUCT_FROM_DATABASE=AirLive WL-1600USB 802.11g Adapter [Realtek RTL8187L] + +usb:v1B75p9170* + ID_PRODUCT_FROM_DATABASE=AirLive X.USB 802.11abgn [Atheros AR9170+AR9104] + +usb:v1B75pA200* + ID_PRODUCT_FROM_DATABASE=AirLive WN-200USB wireless 11b/g/n dongle + +usb:v1B76* + ID_VENDOR_FROM_DATABASE=Legend Silicon Corp. + +usb:v1B80* + ID_VENDOR_FROM_DATABASE=Afatech + +usb:v1B80pC810* + ID_PRODUCT_FROM_DATABASE=MC810 [af9015] + +usb:v1B80pD393* + ID_PRODUCT_FROM_DATABASE=DVB-T receiver [RTL2832U] + +usb:v1B80pD396* + ID_PRODUCT_FROM_DATABASE=UB396-T [RTL2832U] + +usb:v1B80pD397* + ID_PRODUCT_FROM_DATABASE=DVB-T receiver [RTL2832U] + +usb:v1B80pD398* + ID_PRODUCT_FROM_DATABASE=DVB-T receiver [RTL2832U] + +usb:v1B80pD700* + ID_PRODUCT_FROM_DATABASE=FM Radio SnapMusic Mobile 700 (FM700) + +usb:v1B80pE297* + ID_PRODUCT_FROM_DATABASE=Conceptronic DVB-T CTVDIGRCU V3.0 + +usb:v1B80pE383* + ID_PRODUCT_FROM_DATABASE=DVB-T UB383-T [af9015] + +usb:v1B80pE385* + ID_PRODUCT_FROM_DATABASE=DVB-T UB385-T [af9015] + +usb:v1B80pE386* + ID_PRODUCT_FROM_DATABASE=DVB-T UB385-T [af9015] + +usb:v1B80pE399* + ID_PRODUCT_FROM_DATABASE=DVB-T KWorld PlusTV 399U [af9015] + +usb:v1B80pE39A* + ID_PRODUCT_FROM_DATABASE=DVB-T395U [af9015] + +usb:v1B80pE39B* + ID_PRODUCT_FROM_DATABASE=DVB-T395U [af9015] + +usb:v1B80pE401* + ID_PRODUCT_FROM_DATABASE=Sveon STV22 DVB-T [af9015] + +usb:v1B80pE409* + ID_PRODUCT_FROM_DATABASE=IT9137FN Dual DVB-T [KWorld UB499-2T] + +usb:v1B86* + ID_VENDOR_FROM_DATABASE=Dongguan Guanshang Electronics Co., Ltd. + +usb:v1B88* + ID_VENDOR_FROM_DATABASE=ShenMing Electron (Dong Guan) Co., Ltd. + +usb:v1B8C* + ID_VENDOR_FROM_DATABASE=Altium Limited + +usb:v1B8D* + ID_VENDOR_FROM_DATABASE=e-MOVE Technology Co., Ltd. + +usb:v1B8E* + ID_VENDOR_FROM_DATABASE=Amlogic, Inc. + +usb:v1B8F* + ID_VENDOR_FROM_DATABASE=MA LABS, Inc. + +usb:v1B96* + ID_VENDOR_FROM_DATABASE=N-Trig + +usb:v1B96p0001* + ID_PRODUCT_FROM_DATABASE=Duosense Transparent Electromagnetic Digitizer + +usb:v1B98* + ID_VENDOR_FROM_DATABASE=YMax Communications Corp. + +usb:v1B99* + ID_VENDOR_FROM_DATABASE=Shenzhen Yuanchuan Electronic + +usb:v1BA1* + ID_VENDOR_FROM_DATABASE=JINQ CHERN ENTERPRISE CO., LTD. + +usb:v1BA2* + ID_VENDOR_FROM_DATABASE=Lite Metals & Plastic (Shenzhen) Co., Ltd. + +usb:v1BA4* + ID_VENDOR_FROM_DATABASE=Ember Corporation + +usb:v1BA4p0001* + ID_PRODUCT_FROM_DATABASE=InSight USB Link + +usb:v1BA6* + ID_VENDOR_FROM_DATABASE=Abilis Systems + +usb:v1BA8* + ID_VENDOR_FROM_DATABASE=China Telecommunication Technology Labs + +usb:v1BAD* + ID_VENDOR_FROM_DATABASE=Harmonix Music + +usb:v1BADp0002* + ID_PRODUCT_FROM_DATABASE=Guitar for Xbox 360 + +usb:v1BADp0003* + ID_PRODUCT_FROM_DATABASE=Drum Kit for Xbox 360 + +usb:v1BAE* + ID_VENDOR_FROM_DATABASE=Vuzix Corporation + +usb:v1BAEp0002* + ID_PRODUCT_FROM_DATABASE=VR920 Immersive Eyewear + +usb:v1BBB* + ID_VENDOR_FROM_DATABASE=T & A Mobile Phones + +usb:v1BC4* + ID_VENDOR_FROM_DATABASE=Ford Motor Co. + +usb:v1BC5* + ID_VENDOR_FROM_DATABASE=AVIXE Technology (China) Ltd. + +usb:v1BC7* + ID_VENDOR_FROM_DATABASE=Telit + +usb:v1BC7p0020* + ID_PRODUCT_FROM_DATABASE=HE863 + +usb:v1BC7p1003* + ID_PRODUCT_FROM_DATABASE=UC864-E + +usb:v1BC7p1004* + ID_PRODUCT_FROM_DATABASE=UC864-G + +usb:v1BC7p1005* + ID_PRODUCT_FROM_DATABASE=CC864-DUAL + +usb:v1BC7p1006* + ID_PRODUCT_FROM_DATABASE=CC864-SINGLE + +usb:v1BC7p1010* + ID_PRODUCT_FROM_DATABASE=DE910-DUAL + +usb:v1BCE* + ID_VENDOR_FROM_DATABASE=Contac Cable Industrial Limited + +usb:v1BCF* + ID_VENDOR_FROM_DATABASE=Sunplus Innovation Technology Inc. + +usb:v1BCFp0007* + ID_PRODUCT_FROM_DATABASE=Optical Mouse + +usb:v1BCFp053A* + ID_PRODUCT_FROM_DATABASE=Targa Silvercrest OMC807-C optische Funkmaus + +usb:v1BCFp05C5* + ID_PRODUCT_FROM_DATABASE=SPRF2413A [2.4GHz Wireless Keyboard/Mouse Receiver] + +usb:v1BCFp05CF* + ID_PRODUCT_FROM_DATABASE=Micro keyboard & mouse receiver + +usb:v1BCFp0C31* + ID_PRODUCT_FROM_DATABASE=SPIF30x Serial-ATA bridge + +usb:v1BCFp2888* + ID_PRODUCT_FROM_DATABASE=HP Universal Camera + +usb:v1BD0* + ID_VENDOR_FROM_DATABASE=Hangzhou Riyue Electronic Co., Ltd. + +usb:v1BD5* + ID_VENDOR_FROM_DATABASE=BG Systems, Inc. + +usb:v1BDE* + ID_VENDOR_FROM_DATABASE=P-TWO INDUSTRIES, INC. + +usb:v1BEF* + ID_VENDOR_FROM_DATABASE=Shenzhen Tongyuan Network-Communication Cables Co., Ltd + +usb:v1BF0* + ID_VENDOR_FROM_DATABASE=RealVision Inc. + +usb:v1BF5* + ID_VENDOR_FROM_DATABASE=Extranet Systems Inc. + +usb:v1BF6* + ID_VENDOR_FROM_DATABASE=Orient Semiconductor Electronics, Ltd. + +usb:v1BFD* + ID_VENDOR_FROM_DATABASE=TouchPack + +usb:v1BFDp1268* + ID_PRODUCT_FROM_DATABASE=Touch Screen + +usb:v1BFDp1368* + ID_PRODUCT_FROM_DATABASE=Touch Screen + +usb:v1BFDp1568* + ID_PRODUCT_FROM_DATABASE=Capacitive Touch Screen + +usb:v1BFDp1668* + ID_PRODUCT_FROM_DATABASE=IR Touch Screen + +usb:v1BFDp1688* + ID_PRODUCT_FROM_DATABASE=Resistive Touch Screen + +usb:v1BFDp2968* + ID_PRODUCT_FROM_DATABASE=Touch Screen + +usb:v1BFDp5968* + ID_PRODUCT_FROM_DATABASE=Touch Screen + +usb:v1BFDp6968* + ID_PRODUCT_FROM_DATABASE=Touch Screen + +usb:v1C02* + ID_VENDOR_FROM_DATABASE=Kreton Corporation + +usb:v1C04* + ID_VENDOR_FROM_DATABASE=QNAP System Inc. + +usb:v1C0C* + ID_VENDOR_FROM_DATABASE=Ionics EMS, Inc. + +usb:v1C0Cp0102* + ID_PRODUCT_FROM_DATABASE=Plug Computer + +usb:v1C0D* + ID_VENDOR_FROM_DATABASE=Relm Wireless + +usb:v1C10* + ID_VENDOR_FROM_DATABASE=Lanterra Industrial Co., Ltd. + +usb:v1C13* + ID_VENDOR_FROM_DATABASE=ALECTRONIC LIMITED + +usb:v1C1A* + ID_VENDOR_FROM_DATABASE=Datel Electronics Ltd. + +usb:v1C1B* + ID_VENDOR_FROM_DATABASE=Volkswagen of America, Inc. + +usb:v1C1F* + ID_VENDOR_FROM_DATABASE=Goldvish S.A. + +usb:v1C20* + ID_VENDOR_FROM_DATABASE=Fuji Electric Device Technology Co., Ltd. + +usb:v1C21* + ID_VENDOR_FROM_DATABASE=ADDMM LLC + +usb:v1C22* + ID_VENDOR_FROM_DATABASE=ZHONGSHAN CHIANG YU ELECTRIC CO., LTD. + +usb:v1C26* + ID_VENDOR_FROM_DATABASE=Shanghai Haiying Electronics Co., Ltd. + +usb:v1C27* + ID_VENDOR_FROM_DATABASE=HuiYang D & S Cable Co., Ltd. + +usb:v1C31* + ID_VENDOR_FROM_DATABASE=LS Cable Ltd. + +usb:v1C34* + ID_VENDOR_FROM_DATABASE=SpringCard + +usb:v1C34p7241* + ID_PRODUCT_FROM_DATABASE=Prox'N'Roll RFID Scanner + +usb:v1C37* + ID_VENDOR_FROM_DATABASE=Authorizer Technologies, Inc. + +usb:v1C3D* + ID_VENDOR_FROM_DATABASE=NONIN MEDICAL INC. + +usb:v1C3E* + ID_VENDOR_FROM_DATABASE=Wep Peripherals + +usb:v1C40* + ID_VENDOR_FROM_DATABASE=EZPrototypes + +usb:v1C40p0533* + ID_PRODUCT_FROM_DATABASE=TiltStick + +usb:v1C40p0534* + ID_PRODUCT_FROM_DATABASE=i2c-tiny-usb interface + +usb:v1C40p0535* + ID_PRODUCT_FROM_DATABASE=glcd2usb interface + +usb:v1C40p0536* + ID_PRODUCT_FROM_DATABASE=Swiss ColorPAL + +usb:v1C49* + ID_VENDOR_FROM_DATABASE=Cherng Weei Technology Corp. + +usb:v1C4F* + ID_VENDOR_FROM_DATABASE=SiGma Micro + +usb:v1C4Fp0002* + ID_PRODUCT_FROM_DATABASE=Keyboard TRACER Gamma Ivory + +usb:v1C4Fp0003* + ID_PRODUCT_FROM_DATABASE=HID controller + +usb:v1C4Fp000E* + ID_PRODUCT_FROM_DATABASE=Genius KB-120 Keyboard + +usb:v1C4Fp3000* + ID_PRODUCT_FROM_DATABASE=Micro USB Web Camera + +usb:v1C6B* + ID_VENDOR_FROM_DATABASE=Philips & Lite-ON Digital Solutions Corporation + +usb:v1C6BpA222* + ID_PRODUCT_FROM_DATABASE=DVD Writer Slimtype eTAU108 + +usb:v1C6C* + ID_VENDOR_FROM_DATABASE=Skydigital Inc. + +usb:v1C73* + ID_VENDOR_FROM_DATABASE=AMT + +usb:v1C73p861F* + ID_PRODUCT_FROM_DATABASE=Anysee E30 USB 2.0 DVB-T Receiver + +usb:v1C77* + ID_VENDOR_FROM_DATABASE=Kaetat Industrial Co., Ltd. + +usb:v1C78* + ID_VENDOR_FROM_DATABASE=Datascope Corp. + +usb:v1C79* + ID_VENDOR_FROM_DATABASE=Unigen Corporation + +usb:v1C7A* + ID_VENDOR_FROM_DATABASE=LighTuning Technology Inc. + +usb:v1C7Ap0801* + ID_PRODUCT_FROM_DATABASE=Fingerprint Reader + +usb:v1C7B* + ID_VENDOR_FROM_DATABASE=LUXSHARE PRECISION INDUSTRY (SHENZHEN) CO., LTD. + +usb:v1C87* + ID_VENDOR_FROM_DATABASE=2N TELEKOMUNIKACE a.s. + +usb:v1C88* + ID_VENDOR_FROM_DATABASE=Somagic, Inc. + +usb:v1C88p0007* + ID_PRODUCT_FROM_DATABASE=SMI Grabber (EasyCAP DC60+ clone) (no firmware) [SMI-2021CBE] + +usb:v1C88p003C* + ID_PRODUCT_FROM_DATABASE=SMI Grabber (EasyCAP DC60+ clone) [SMI-2021CBE] + +usb:v1C89* + ID_VENDOR_FROM_DATABASE=HONGKONG WEIDIDA ELECTRON LIMITED + +usb:v1C8E* + ID_VENDOR_FROM_DATABASE=ASTRON INTERNATIONAL CORP. + +usb:v1C98* + ID_VENDOR_FROM_DATABASE=ALPINE ELECTRONICS, INC. + +usb:v1C9E* + ID_VENDOR_FROM_DATABASE=OMEGA TECHNOLOGY + +usb:v1C9Ep6061* + ID_PRODUCT_FROM_DATABASE=WL-72B 3.5G MODEM + +usb:v1CA0* + ID_VENDOR_FROM_DATABASE=ACCARIO Inc. + +usb:v1CA1* + ID_VENDOR_FROM_DATABASE=Symwave + +usb:v1CA1p18AB* + ID_PRODUCT_FROM_DATABASE=SATA bridge + +usb:v1CAC* + ID_VENDOR_FROM_DATABASE=Kinstone + +usb:v1CACpA332* + ID_PRODUCT_FROM_DATABASE=C8 Webcam + +usb:v1CACpB288* + ID_PRODUCT_FROM_DATABASE=C18 Webcam + +usb:v1CB3* + ID_VENDOR_FROM_DATABASE=Aces Electronic Co., Ltd. + +usb:v1CB4* + ID_VENDOR_FROM_DATABASE=OPEX CORPORATION + +usb:v1CBE* + ID_VENDOR_FROM_DATABASE=Luminary Micro Inc. + +usb:v1CBEp00FD* + ID_PRODUCT_FROM_DATABASE=In-Circuit Debug Interface + +usb:v1CBEp00FF* + ID_PRODUCT_FROM_DATABASE=Stellaris ROM DFU Bootloader + +usb:v1CBF* + ID_VENDOR_FROM_DATABASE=FORTAT SKYMARK INDUSTRIAL COMPANY + +usb:v1CC0* + ID_VENDOR_FROM_DATABASE=PlantSense + +usb:v1CCA* + ID_VENDOR_FROM_DATABASE=NextWave Broadband Inc. + +usb:v1CCD* + ID_VENDOR_FROM_DATABASE=Bodatong Technology (Shenzhen) Co., Ltd. + +usb:v1CD4* + ID_VENDOR_FROM_DATABASE=adp corporation + +usb:v1CD5* + ID_VENDOR_FROM_DATABASE=Firecomms Ltd. + +usb:v1CD6* + ID_VENDOR_FROM_DATABASE=Antonio Precise Products Manufactory Ltd. + +usb:v1CDE* + ID_VENDOR_FROM_DATABASE=Telecommunications Technology Association (TTA) + +usb:v1CDF* + ID_VENDOR_FROM_DATABASE=WonTen Technology Co., Ltd. + +usb:v1CE0* + ID_VENDOR_FROM_DATABASE=EDIMAX TECHNOLOGY CO., LTD. + +usb:v1CE1* + ID_VENDOR_FROM_DATABASE=Amphenol KAE + +usb:v1CF1* + ID_VENDOR_FROM_DATABASE=Dresden Elektronik + +usb:v1CF1p0001* + ID_PRODUCT_FROM_DATABASE=Sensor Terminal Board + +usb:v1CF1p0004* + ID_PRODUCT_FROM_DATABASE=Wireless Handheld Terminal + +usb:v1CF1p0017* + ID_PRODUCT_FROM_DATABASE=deRFusbSniffer 2.4 GHz + +usb:v1CF1p0018* + ID_PRODUCT_FROM_DATABASE=deRFusb24E001 + +usb:v1CF1p0019* + ID_PRODUCT_FROM_DATABASE=deRFusb14E001 + +usb:v1CF1p001A* + ID_PRODUCT_FROM_DATABASE=deRFusb23E00 + +usb:v1CF1p001B* + ID_PRODUCT_FROM_DATABASE=deRFusb13E00 + +usb:v1CF1p001C* + ID_PRODUCT_FROM_DATABASE=deRFnode + +usb:v1CF1p001D* + ID_PRODUCT_FROM_DATABASE=deRFnode / gateway + +usb:v1CF1p0022* + ID_PRODUCT_FROM_DATABASE=deUSB level shifter + +usb:v1CF1p0023* + ID_PRODUCT_FROM_DATABASE=deRFusbSniffer Sub-GHz + +usb:v1CF1p0025* + ID_PRODUCT_FROM_DATABASE=deRFusb23E06 + +usb:v1CF1p0027* + ID_PRODUCT_FROM_DATABASE=deRFusb13E06 + +usb:v1CFC* + ID_VENDOR_FROM_DATABASE=ANDES TECHNOLOGY CORPORATION + +usb:v1CFD* + ID_VENDOR_FROM_DATABASE=Flextronics Digital Design Japan, LTD. + +usb:v1D03* + ID_VENDOR_FROM_DATABASE=iCON + +usb:v1D03p0028* + ID_PRODUCT_FROM_DATABASE=iCreativ MIDI Controller + +usb:v1D07* + ID_VENDOR_FROM_DATABASE=Solid-Motion + +usb:v1D08* + ID_VENDOR_FROM_DATABASE=NINGBO HENTEK DRAGON ELECTRONICS CO., LTD. + +usb:v1D09* + ID_VENDOR_FROM_DATABASE=TechFaith Wireless Technology Limited + +usb:v1D09p1026* + ID_PRODUCT_FROM_DATABASE=HSUPA Modem FLYING-LARK46-VER0.07 [Flying Angel] + +usb:v1D0A* + ID_VENDOR_FROM_DATABASE=Johnson Controls, Inc. The Automotive Business Unit + +usb:v1D0B* + ID_VENDOR_FROM_DATABASE=HAN HUA CABLE & WIRE TECHNOLOGY (J.X.) CO., LTD. + +usb:v1D0F* + ID_VENDOR_FROM_DATABASE=Sonix Technology Co., Ltd. + +usb:v1D14* + ID_VENDOR_FROM_DATABASE=ALPHA-SAT TECHNOLOGY LIMITED + +usb:v1D17* + ID_VENDOR_FROM_DATABASE=C-Thru Music Ltd. + +usb:v1D17p0001* + ID_PRODUCT_FROM_DATABASE=AXiS-49 Harmonic Table MIDI Keyboard + +usb:v1D19* + ID_VENDOR_FROM_DATABASE=Dexatek Technology Ltd. + +usb:v1D19p1101* + ID_PRODUCT_FROM_DATABASE=DK DVB-T Dongle + +usb:v1D19p1102* + ID_PRODUCT_FROM_DATABASE=DK mini DVB-T Dongle + +usb:v1D19p1103* + ID_PRODUCT_FROM_DATABASE=DK 5217 DVB-T Dongle + +usb:v1D19p6105* + ID_PRODUCT_FROM_DATABASE=Video grabber + +usb:v1D19p8202* + ID_PRODUCT_FROM_DATABASE=DK DVBC/T DONGLE + +usb:v1D1F* + ID_VENDOR_FROM_DATABASE=Diostech Co., Ltd. + +usb:v1D20* + ID_VENDOR_FROM_DATABASE=SAMTACK INC. + +usb:v1D34* + ID_VENDOR_FROM_DATABASE=Dream Cheeky + +usb:v1D34p0001* + ID_PRODUCT_FROM_DATABASE=Dream Cheeky Fidget + +usb:v1D34p0004* + ID_PRODUCT_FROM_DATABASE=Dream Cheeky Webmail Notifier + +usb:v1D34p0008* + ID_PRODUCT_FROM_DATABASE=Dream Cheeky button + +usb:v1D34p000A* + ID_PRODUCT_FROM_DATABASE=Dream Cheeky Mailbox Friends Alert + +usb:v1D34p000D* + ID_PRODUCT_FROM_DATABASE=Dream Cheeky Big Red Button + +usb:v1D34p0013* + ID_PRODUCT_FROM_DATABASE=Dream Cheeky LED Message Board + +usb:v1D4D* + ID_VENDOR_FROM_DATABASE=PEGATRON CORPORATION + +usb:v1D4Dp0002* + ID_PRODUCT_FROM_DATABASE=Ralink RT2770/2720 802.11b/g/n Wireless LAN Mini-USB Device + +usb:v1D4Dp000C* + ID_PRODUCT_FROM_DATABASE=Ralink RT3070 802.11b/g/n Wireless Lan USB Device + +usb:v1D4Dp000E* + ID_PRODUCT_FROM_DATABASE=Ralink RT3070 802.11b/g/n Wireless Lan USB Device + +usb:v1D50* + ID_VENDOR_FROM_DATABASE=OpenMoko, Inc. + +usb:v1D50p5119* + ID_PRODUCT_FROM_DATABASE=GTA01/GTA02 U-Boot Bootloader + +usb:v1D57* + ID_VENDOR_FROM_DATABASE=Xenta + +usb:v1D57p0005* + ID_PRODUCT_FROM_DATABASE=Wireless Receiver (Keyboard and Mouse) + +usb:v1D57p0006* + ID_PRODUCT_FROM_DATABASE=Wireless Receiver (RC Laser Pointer) + +usb:v1D57p000C* + ID_PRODUCT_FROM_DATABASE=Optical Mouse + +usb:v1D57p2400* + ID_PRODUCT_FROM_DATABASE=Wireless Mouse Receiver + +usb:v1D57p32DA* + ID_PRODUCT_FROM_DATABASE=2.4GHz Receiver (Keyboard and Mouse) + +usb:v1D57p83D0* + ID_PRODUCT_FROM_DATABASE=Click-mouse! + +usb:v1D57pAC01* + ID_PRODUCT_FROM_DATABASE=Wireless Receiver (Keyboard and Mouse) + +usb:v1D57pAF01* + ID_PRODUCT_FROM_DATABASE=AUVIO Universal Remote Receiver for PlayStation 3 + +usb:v1D5B* + ID_VENDOR_FROM_DATABASE=Smartronix, Inc. + +usb:v1D6B* + ID_VENDOR_FROM_DATABASE=Linux Foundation + +usb:v1D6Bp0001* + ID_PRODUCT_FROM_DATABASE=1.1 root hub + +usb:v1D6Bp0002* + ID_PRODUCT_FROM_DATABASE=2.0 root hub + +usb:v1D6Bp0003* + ID_PRODUCT_FROM_DATABASE=3.0 root hub + +usb:v1D6Bp0100* + ID_PRODUCT_FROM_DATABASE=PTP Gadget + +usb:v1D6Bp0101* + ID_PRODUCT_FROM_DATABASE=Audio Gadget + +usb:v1D6Bp0102* + ID_PRODUCT_FROM_DATABASE=EEM Gadget + +usb:v1D6Bp0103* + ID_PRODUCT_FROM_DATABASE=NCM (Ethernet) Gadget + +usb:v1D6Bp0104* + ID_PRODUCT_FROM_DATABASE=Multifunction Composite Gadget + +usb:v1D6Bp0105* + ID_PRODUCT_FROM_DATABASE=FunctionFS Gadget + +usb:v1D6Bp0200* + ID_PRODUCT_FROM_DATABASE=Qemu Audio Device + +usb:v1DE1* + ID_VENDOR_FROM_DATABASE=Actions Microelectronics Co. + +usb:v1DE1p1101* + ID_PRODUCT_FROM_DATABASE=Generic Display Device (Mass storage mode) + +usb:v1DE1pC101* + ID_PRODUCT_FROM_DATABASE=Generic Display Device + +usb:v1E0E* + ID_VENDOR_FROM_DATABASE=Qualcomm / Option + +usb:v1E0EpF000* + ID_PRODUCT_FROM_DATABASE=iCON 210 UMTS Surfstick + +usb:v1E10* + ID_VENDOR_FROM_DATABASE=Point Grey Research, Inc. + +usb:v1E10p2004* + ID_PRODUCT_FROM_DATABASE=Sony 1.3MP 1/3" ICX445 IIDC video camera [Chameleon] + +usb:v1E17* + ID_VENDOR_FROM_DATABASE=Mirion Technologies Dosimetry Services Division + +usb:v1E17p0001* + ID_PRODUCT_FROM_DATABASE=instadose dosimeter + +usb:v1E1D* + ID_VENDOR_FROM_DATABASE=Lumension Security + +usb:v1E1Dp0165* + ID_PRODUCT_FROM_DATABASE=Secure Pen drive + +usb:v1E1F* + ID_VENDOR_FROM_DATABASE=INVIA + +usb:v1E29* + ID_VENDOR_FROM_DATABASE=Festo AG & Co. KG + +usb:v1E29p0101* + ID_PRODUCT_FROM_DATABASE=CPX Adapter + +usb:v1E29p0102* + ID_PRODUCT_FROM_DATABASE=CPX Adapter >=HW10.09 [CP2102] + +usb:v1E29p0401* + ID_PRODUCT_FROM_DATABASE=iL3-TP [AT90USB646] + +usb:v1E29p0402* + ID_PRODUCT_FROM_DATABASE=FTDI232 [EasyPort] + +usb:v1E29p0403* + ID_PRODUCT_FROM_DATABASE=FTDI232 [EasyPort Mini] + +usb:v1E29p0404* + ID_PRODUCT_FROM_DATABASE=FTDI232 [Netzteil-GL] + +usb:v1E29p0405* + ID_PRODUCT_FROM_DATABASE=FTDI232 [MotorPrüfstand] + +usb:v1E29p0406* + ID_PRODUCT_FROM_DATABASE=STM32F103 [EasyKit] + +usb:v1E29p0407* + ID_PRODUCT_FROM_DATABASE=LPC2378 [Robotino] + +usb:v1E29p0408* + ID_PRODUCT_FROM_DATABASE=LPC2378 [Robotino-Arm] + +usb:v1E29p0409* + ID_PRODUCT_FROM_DATABASE=LPC2378 [Robotino-Arm Bootloader] + +usb:v1E29p040A* + ID_PRODUCT_FROM_DATABASE=LPC2378 [Robotino Bootloader] + +usb:v1E29p040B* + ID_PRODUCT_FROM_DATABASE=LPC2378 [Robotino XT] + +usb:v1E29p040C* + ID_PRODUCT_FROM_DATABASE=LPC2378 [Robotino XT Bootloader] + +usb:v1E29p040D* + ID_PRODUCT_FROM_DATABASE=LPC2378 [Robotino 3] + +usb:v1E29p040E* + ID_PRODUCT_FROM_DATABASE=LPC2378 [Robotino 3 Bootloader] + +usb:v1E29p0501* + ID_PRODUCT_FROM_DATABASE=CP2102 [CMSP] + +usb:v1E29p0601* + ID_PRODUCT_FROM_DATABASE=CMMP-AS + +usb:v1E3D* + ID_VENDOR_FROM_DATABASE=Chipsbank Microelectronics Co., Ltd + +usb:v1E3Dp2093* + ID_PRODUCT_FROM_DATABASE=CBM209x Flash Drive (OEM) + +usb:v1E3Dp4082* + ID_PRODUCT_FROM_DATABASE=CBM4082 SD Card Reader + +usb:v1E41* + ID_VENDOR_FROM_DATABASE=Cleverscope + +usb:v1E41p0001* + ID_PRODUCT_FROM_DATABASE=CS328A PC Oscilloscope + +usb:v1E4E* + ID_VENDOR_FROM_DATABASE=Cubeternet + +usb:v1E4Ep0100* + ID_PRODUCT_FROM_DATABASE=WebCam + +usb:v1E4Ep0102* + ID_PRODUCT_FROM_DATABASE=GL-UPC822 UVC WebCam + +usb:v1E54* + ID_VENDOR_FROM_DATABASE=TypeMatrix + +usb:v1E54p2030* + ID_PRODUCT_FROM_DATABASE=2030 USB Keyboard + +usb:v1E68* + ID_VENDOR_FROM_DATABASE=TrekStor GmbH & Co. KG + +usb:v1E68p001B* + ID_PRODUCT_FROM_DATABASE=DataStation maxi g.u + +usb:v1E71* + ID_VENDOR_FROM_DATABASE=NZXT + +usb:v1E71p0001* + ID_PRODUCT_FROM_DATABASE=Avatar Optical Mouse + +usb:v1E74* + ID_VENDOR_FROM_DATABASE=Coby Electronics Corporation + +usb:v1E74p2211* + ID_PRODUCT_FROM_DATABASE=MP300 + +usb:v1E74p2647* + ID_PRODUCT_FROM_DATABASE=2 GB 2 Go Video MP3 Player [MP601-2G] + +usb:v1E74p2659* + ID_PRODUCT_FROM_DATABASE=Coby 4GB Go Video MP3 Player [MP620-4G] + +usb:v1E74p4641* + ID_PRODUCT_FROM_DATABASE=A8705 MP3/Video Player + +usb:v1E74p6511* + ID_PRODUCT_FROM_DATABASE=MP705-8G MP3 player + +usb:v1E74p6512* + ID_PRODUCT_FROM_DATABASE=MP705-4G + +usb:v1E74p7111* + ID_PRODUCT_FROM_DATABASE=MP957 Music and Video Player + +usb:v1E7D* + ID_VENDOR_FROM_DATABASE=ROCCAT + +usb:v1E7Dp2C24* + ID_PRODUCT_FROM_DATABASE=Pyra Mouse (wired) + +usb:v1E7Dp2CED* + ID_PRODUCT_FROM_DATABASE=Kone Mouse + +usb:v1E7Dp2CF6* + ID_PRODUCT_FROM_DATABASE=Pyra Mouse (wireless) + +usb:v1E7Dp2D50* + ID_PRODUCT_FROM_DATABASE=Kova+ Mouse + +usb:v1E7Dp2D51* + ID_PRODUCT_FROM_DATABASE=Kone+ Mouse + +usb:v1E7Dp30D4* + ID_PRODUCT_FROM_DATABASE=Arvo Keyboard + +usb:v1EBB* + ID_VENDOR_FROM_DATABASE=NuCORE Technology, Inc. + +usb:v1EDA* + ID_VENDOR_FROM_DATABASE=AirTies Wireless Networks + +usb:v1EDAp2012* + ID_PRODUCT_FROM_DATABASE=Air2210 54 Mbps Wireless Adapter + +usb:v1EDAp2210* + ID_PRODUCT_FROM_DATABASE=Air2210 54 Mbps Wireless Adapter + +usb:v1EDAp2310* + ID_PRODUCT_FROM_DATABASE=Air2310 150 Mbps Wireless Adapter + +usb:v1EDAp2410* + ID_PRODUCT_FROM_DATABASE=Air2410 300 Mbps Wireless Adapter + +usb:v1EDB* + ID_VENDOR_FROM_DATABASE=Blackmagic design + +usb:v1EDBpBD3B* + ID_PRODUCT_FROM_DATABASE=Intensity Shuttle + +usb:v1EE8* + ID_VENDOR_FROM_DATABASE=ONDA COMMUNICATION S.p.a. + +usb:v1EE8p0014* + ID_PRODUCT_FROM_DATABASE=MT833UP + +usb:v1EF6* + ID_VENDOR_FROM_DATABASE=EADS Deutschland GmbH + +usb:v1EF6p5064* + ID_PRODUCT_FROM_DATABASE=FDR Interface + +usb:v1EF6p5648* + ID_PRODUCT_FROM_DATABASE=RIU CSMU/BSD + +usb:v1EF6p564A* + ID_PRODUCT_FROM_DATABASE=Cassidian RIU CSMU/BSD Simulator + +usb:v1F28* + ID_VENDOR_FROM_DATABASE=Cal-Comp + +usb:v1F28p0020* + ID_PRODUCT_FROM_DATABASE=CDMA USB Modem A600 + +usb:v1F28p0021* + ID_PRODUCT_FROM_DATABASE=CD INSTALLER USB Device + +usb:v1F44* + ID_VENDOR_FROM_DATABASE=The Neat Company + +usb:v1F44p0001* + ID_PRODUCT_FROM_DATABASE=NM-1000 scanner + +usb:v1F48* + ID_VENDOR_FROM_DATABASE=H-TRONIC GmbH + +usb:v1F48p0627* + ID_PRODUCT_FROM_DATABASE=Data capturing system + +usb:v1F48p0628* + ID_PRODUCT_FROM_DATABASE=Data capturing and control module + +usb:v1F4D* + ID_VENDOR_FROM_DATABASE=G-Tek Electronics Group + +usb:v1F4DpB803* + ID_PRODUCT_FROM_DATABASE=Lifeview LV5TDLX DVB-T [RTL2832U] + +usb:v1F6F* + ID_VENDOR_FROM_DATABASE=Aliph + +usb:v1F6Fp0023* + ID_PRODUCT_FROM_DATABASE=Jawbone Jambox + +usb:v1F6Fp8000* + ID_PRODUCT_FROM_DATABASE=Jawbone Jambox - Updating + +usb:v1F75* + ID_VENDOR_FROM_DATABASE=Innostor Technology Corporation + +usb:v1F75p0888* + ID_PRODUCT_FROM_DATABASE=IS888 SATA Storage Controller + +usb:v1F75p0902* + ID_PRODUCT_FROM_DATABASE=IS902 UFD controller + +usb:v1F82* + ID_VENDOR_FROM_DATABASE=TANDBERG + +usb:v1F82p0001* + ID_PRODUCT_FROM_DATABASE=PrecisionHD Camera + +usb:v1F84* + ID_VENDOR_FROM_DATABASE=Alere, Inc. + +usb:v1F87* + ID_VENDOR_FROM_DATABASE=Stantum + +usb:v1F87p0002* + ID_PRODUCT_FROM_DATABASE=Multi-touch HID Controller + +usb:v1F9B* + ID_VENDOR_FROM_DATABASE=Ubiquiti Networks, Inc. + +usb:v1F9Bp0241* + ID_PRODUCT_FROM_DATABASE=AirView2-EXT + +usb:v1FAB* + ID_VENDOR_FROM_DATABASE=Samsung Opto-Electroncs Co., Ltd. + +usb:v1FABp104D* + ID_PRODUCT_FROM_DATABASE=ES65 + +usb:v1FBD* + ID_VENDOR_FROM_DATABASE=Delphin Technology AG + +usb:v1FBDp0001* + ID_PRODUCT_FROM_DATABASE=Expert Key - Data aquisition system + +usb:v1FC9* + ID_VENDOR_FROM_DATABASE=NXP Semiconductors + +usb:v1FC9p010B* + ID_PRODUCT_FROM_DATABASE=PR533 + +usb:v1FDE* + ID_VENDOR_FROM_DATABASE=ILX Lightwave Corporation + +usb:v1FDEp0001* + ID_PRODUCT_FROM_DATABASE=UART Bridge + +usb:v1FE7* + ID_VENDOR_FROM_DATABASE=Vertex Wireless Co., Ltd. + +usb:v1FE7p1000* + ID_PRODUCT_FROM_DATABASE=VW100 series CDMA EV-DO Rev.A modem + +usb:v1FF7* + ID_VENDOR_FROM_DATABASE=CVT Electronics.Co.,Ltd + +usb:v1FF7p0013* + ID_PRODUCT_FROM_DATABASE=CVTouch Screen (HID) + +usb:v1FF7p001A* + ID_PRODUCT_FROM_DATABASE=Human Interface Device + +usb:v1FFF* + ID_VENDOR_FROM_DATABASE=Ideofy Inc. + +usb:v2001* + ID_VENDOR_FROM_DATABASE=D-Link Corp. + +usb:v2001p0001* + ID_PRODUCT_FROM_DATABASE=DWL-120 WIRELESS ADAPTER + +usb:v2001p0201* + ID_PRODUCT_FROM_DATABASE=DHN-120 10Mb Home Phoneline Adapter + +usb:v2001p1A00* + ID_PRODUCT_FROM_DATABASE=DUB-E100 10/100 Ethernet + +usb:v2001p1A02* + ID_PRODUCT_FROM_DATABASE=DUB-E100 Ethernet Adapter + +usb:v2001p200C* + ID_PRODUCT_FROM_DATABASE=10/100 Ethernet + +usb:v2001p3200* + ID_PRODUCT_FROM_DATABASE=DWL-120 802.11b Wireless Adapter(rev.E1) [Atmel at76c503a] + +usb:v2001p3301* + ID_PRODUCT_FROM_DATABASE=DWA-130 802.11n Wireless N Adapter(rev.C1) [Realtek RTL8192U] + +usb:v2001p3306* + ID_PRODUCT_FROM_DATABASE=DWL-G122 Wireless Adapter(rev.F1) [Realtek RTL8188SU] + +usb:v2001p3308* + ID_PRODUCT_FROM_DATABASE=DWA-121 802.11n Wireless N 150 Pico Adapter [Realtek RTL8188CUS] + +usb:v2001p3309* + ID_PRODUCT_FROM_DATABASE=DWA-135 802.11n Wireless N Adapter(rev.A1) [Realtek RTL8192CU] + +usb:v2001p330A* + ID_PRODUCT_FROM_DATABASE=DWA-133 802.11n Wireless N Adapter [Realtek RTL8192CU] + +usb:v2001p3500* + ID_PRODUCT_FROM_DATABASE=Elitegroup Computer Systems WLAN card WL-162 + +usb:v2001p3700* + ID_PRODUCT_FROM_DATABASE=DWL-122 802.11b [Intersil Prism 3] + +usb:v2001p3701* + ID_PRODUCT_FROM_DATABASE=DWL-G120 Spinnaker 802.11g [Intersil ISL3886] + +usb:v2001p3702* + ID_PRODUCT_FROM_DATABASE=DWL-120 802.11b Wireless Adapter(rev.F) [Intersil ISL3871] + +usb:v2001p3703* + ID_PRODUCT_FROM_DATABASE=AirPlus G DWL-G122 Wireless Adapter(rev.A1) [Intersil ISL3880] + +usb:v2001p3704* + ID_PRODUCT_FROM_DATABASE=AirPlus G DWL-G122 Wireless Adapter(rev.A2) [Intersil ISL3887] + +usb:v2001p3705* + ID_PRODUCT_FROM_DATABASE=AirPlus G DWL-G120 Wireless Adapter(rev.C) [Intersil ISL3887] + +usb:v2001p3761* + ID_PRODUCT_FROM_DATABASE=IEEE 802.11g USB2.0 Wireless Network Adapter-PN + +usb:v2001p3A00* + ID_PRODUCT_FROM_DATABASE=DWL-AG132 [Atheros AR5523] + +usb:v2001p3A01* + ID_PRODUCT_FROM_DATABASE=DWL-AG132 (no firmware) [Atheros AR5523] + +usb:v2001p3A02* + ID_PRODUCT_FROM_DATABASE=DWL-G132 [Atheros AR5523] + +usb:v2001p3A03* + ID_PRODUCT_FROM_DATABASE=DWL-G132 (no firmware) [Atheros AR5523] + +usb:v2001p3A04* + ID_PRODUCT_FROM_DATABASE=DWL-AG122 [Atheros AR5523] + +usb:v2001p3A05* + ID_PRODUCT_FROM_DATABASE=DWL-AG122 (no firmware) [Atheros AR5523] + +usb:v2001p3A80* + ID_PRODUCT_FROM_DATABASE=AirPlus Xtreme G DWL-G132 Wireless Adapter + +usb:v2001p3A81* + ID_PRODUCT_FROM_DATABASE=predator Bootloader Download + +usb:v2001p3A82* + ID_PRODUCT_FROM_DATABASE=AirPremier AG DWL-AG132 Wireless Adapter + +usb:v2001p3A83* + ID_PRODUCT_FROM_DATABASE=predator Bootloader Download + +usb:v2001p3B00* + ID_PRODUCT_FROM_DATABASE=AirPlus DWL-120+ Wireless Adapter [Texas Instruments ACX100USB] + +usb:v2001p3B01* + ID_PRODUCT_FROM_DATABASE=WLAN Boot Device + +usb:v2001p3C00* + ID_PRODUCT_FROM_DATABASE=AirPlus G DWL-G122 Wireless Adapter(rev.B1) [Ralink RT2571] + +usb:v2001p3C01* + ID_PRODUCT_FROM_DATABASE=AirPlus AG DWL-AG122 Wireless Adapter + +usb:v2001p3C02* + ID_PRODUCT_FROM_DATABASE=AirPlus G DWL-G122 Wireless Adapter + +usb:v2001p3C05* + ID_PRODUCT_FROM_DATABASE=DUB-E100 Fast Ethernet [asix] + +usb:v2001p3C15* + ID_PRODUCT_FROM_DATABASE=DWA-140 RangeBooster N Adapter(rev.B3) [Ralink RT5372] + +usb:v2001p3C17* + ID_PRODUCT_FROM_DATABASE=DWA-123 Wireless N 150 Adapter(rev.A1) [Ralink RT3370] + +usb:v2001p3C19* + ID_PRODUCT_FROM_DATABASE=DWA-125 Wireless N 150 Adapter(rev.A3) [Ralink RT5370] + +usb:v2001p3C1A* + ID_PRODUCT_FROM_DATABASE=DWA-160 802.11abgn Xtreme N Dual Band Adapter(rev.B2) [Ralink RT5572] + +usb:v2001p3C1B* + ID_PRODUCT_FROM_DATABASE=DWA-127 Wireless N 150 High-Gain Adapter(rev.A1) [Ralink RT3070] + +usb:v2001p4000* + ID_PRODUCT_FROM_DATABASE=DSB-650C Ethernet [klsi] + +usb:v2001p4001* + ID_PRODUCT_FROM_DATABASE=DSB-650TX Ethernet [pegasus] + +usb:v2001p4002* + ID_PRODUCT_FROM_DATABASE=DSB-650TX Ethernet [pegasus] + +usb:v2001p4003* + ID_PRODUCT_FROM_DATABASE=DSB-650TX-PNA Ethernet [pegasus] + +usb:v2001p400B* + ID_PRODUCT_FROM_DATABASE=10/100 Ethernet + +usb:v2001p4102* + ID_PRODUCT_FROM_DATABASE=10/100 Ethernet + +usb:v2001p5100* + ID_PRODUCT_FROM_DATABASE=DSL-200 ADSL ATM Modem + +usb:v2001p5102* + ID_PRODUCT_FROM_DATABASE=DSL-200 ADSL Loader + +usb:v2001p5B00* + ID_PRODUCT_FROM_DATABASE=Remote NDIS Network Device + +usb:v2001p9414* + ID_PRODUCT_FROM_DATABASE=Cable Modem + +usb:v2001p9B00* + ID_PRODUCT_FROM_DATABASE=Broadband Cable Modem Remote NDIS Device + +usb:v2001pABC1* + ID_PRODUCT_FROM_DATABASE=DSB-650 Ethernet [pegasus] + +usb:v2001pF013* + ID_PRODUCT_FROM_DATABASE=DLink 7 port USB2.0 Hub + +usb:v2001pF103* + ID_PRODUCT_FROM_DATABASE=DUB-H7 7-port USB 2.0 hub + +usb:v2001pF10D* + ID_PRODUCT_FROM_DATABASE=Accent Communications Modem + +usb:v2001pF110* + ID_PRODUCT_FROM_DATABASE=DUB-AV300 A/V Capture + +usb:v2001pF111* + ID_PRODUCT_FROM_DATABASE=DBT-122 Bluetooth adapter + +usb:v2001pF112* + ID_PRODUCT_FROM_DATABASE=DUB-T210 Audio Device + +usb:v2001pF116* + ID_PRODUCT_FROM_DATABASE=Formosa 2 + +usb:v2001pF117* + ID_PRODUCT_FROM_DATABASE=Formosa 3 + +usb:v2001pF118* + ID_PRODUCT_FROM_DATABASE=Formosa 4 + +usb:v2002* + ID_VENDOR_FROM_DATABASE=DAP Technologies + +usb:v200C* + ID_VENDOR_FROM_DATABASE=Reloop + +usb:v200Cp100B* + ID_PRODUCT_FROM_DATABASE=Play audio soundcard + +usb:v2013* + ID_VENDOR_FROM_DATABASE=PCTV Systems + +usb:v2013p0245* + ID_PRODUCT_FROM_DATABASE=PCTV 73ESE + +usb:v2013p0246* + ID_PRODUCT_FROM_DATABASE=PCTV 74E + +usb:v2013p0248* + ID_PRODUCT_FROM_DATABASE=PCTV 282E + +usb:v2013p024F* + ID_PRODUCT_FROM_DATABASE=nanoStick T2 290e + +usb:v2019* + ID_VENDOR_FROM_DATABASE=PLANEX + +usb:v2019p3220* + ID_PRODUCT_FROM_DATABASE=GW-US11S WLAN [Atmel AT76C503A] + +usb:v2019p4901* + ID_PRODUCT_FROM_DATABASE=GW-USSuper300 802.11bgn Wireless Adapter [Realtek RTL8191SU] + +usb:v2019p4903* + ID_PRODUCT_FROM_DATABASE=GW-USFang300 802.11abgn Wireless Adapter [Realtek RTL8192DU] + +usb:v2019p4904* + ID_PRODUCT_FROM_DATABASE=GW-USUltra300 802.11abgn Wireless Adapter [Realtek RTL8192DU] + +usb:v2019p5303* + ID_PRODUCT_FROM_DATABASE=GW-US54GXS 802.11bg + +usb:v2019p5304* + ID_PRODUCT_FROM_DATABASE=GWUS300 802.11n + +usb:v2019pAB01* + ID_PRODUCT_FROM_DATABASE=GW-US54HP + +usb:v2019pAB24* + ID_PRODUCT_FROM_DATABASE=GW-US300MiniS + +usb:v2019pAB25* + ID_PRODUCT_FROM_DATABASE=GW-USMini2N 802.11n Wireless Adapter [Ralink RT2870] + +usb:v2019pAB28* + ID_PRODUCT_FROM_DATABASE=GW-USNano + +usb:v2019pAB29* + ID_PRODUCT_FROM_DATABASE=GW-USMicro300 + +usb:v2019pAB2A* + ID_PRODUCT_FROM_DATABASE=GW-USNano2 802.11n Wireless Adapter [Realtek RTL8188CUS] + +usb:v2019pAB2B* + ID_PRODUCT_FROM_DATABASE=GW-USEco300 802.11bgn Wireless Adapter [Realtek RTL8192CU] + +usb:v2019pAB2C* + ID_PRODUCT_FROM_DATABASE=GW-USDual300 802.11abgn Wireless Adapter [Realtek RTL8192DU] + +usb:v2019pAB50* + ID_PRODUCT_FROM_DATABASE=GW-US54Mini2 + +usb:v2019pC002* + ID_PRODUCT_FROM_DATABASE=GW-US54SG + +usb:v2019pC007* + ID_PRODUCT_FROM_DATABASE=GW-US54GZL + +usb:v2019pED02* + ID_PRODUCT_FROM_DATABASE=GW-USMM + +usb:v2019pED06* + ID_PRODUCT_FROM_DATABASE=GW-US300MiniW 802.11bgn Wireless Adapter + +usb:v2019pED10* + ID_PRODUCT_FROM_DATABASE=GW-US300Mini2 + +usb:v2019pED14* + ID_PRODUCT_FROM_DATABASE=GW-USMicroN + +usb:v2019pED16* + ID_PRODUCT_FROM_DATABASE=GW-USMicroN2W 802.11bgn Wireless Adapter [Realtek RTL8188SU] + +usb:v2019pED17* + ID_PRODUCT_FROM_DATABASE=GW-USValue-EZ 802.11n Wireless Adapter [Realtek RTL8188CUS] + +usb:v2019pED18* + ID_PRODUCT_FROM_DATABASE=GW-USHyper300 / GW-USH300N 802.11bgn Wireless Adapter [Realtek RTL8191SU] + +usb:v2040* + ID_VENDOR_FROM_DATABASE=Hauppauge + +usb:v2040p0C80* + ID_PRODUCT_FROM_DATABASE=Windham + +usb:v2040p0C90* + ID_PRODUCT_FROM_DATABASE=Windham + +usb:v2040p1700* + ID_PRODUCT_FROM_DATABASE=CataMount + +usb:v2040p1800* + ID_PRODUCT_FROM_DATABASE=Okemo A + +usb:v2040p1801* + ID_PRODUCT_FROM_DATABASE=Okemo B + +usb:v2040p2000* + ID_PRODUCT_FROM_DATABASE=Tiger Minicard + +usb:v2040p2009* + ID_PRODUCT_FROM_DATABASE=Tiger Minicard R2 + +usb:v2040p200A* + ID_PRODUCT_FROM_DATABASE=Tiger Minicard + +usb:v2040p2010* + ID_PRODUCT_FROM_DATABASE=Tiger Minicard + +usb:v2040p2011* + ID_PRODUCT_FROM_DATABASE=WinTV MiniCard [Dell Digital TV Receiver] + +usb:v2040p2019* + ID_PRODUCT_FROM_DATABASE=Tiger Minicard + +usb:v2040p2400* + ID_PRODUCT_FROM_DATABASE=WinTV PVR USB2 (Model 24019) + +usb:v2040p4700* + ID_PRODUCT_FROM_DATABASE=WinTV Nova-S-USB2 + +usb:v2040p4902* + ID_PRODUCT_FROM_DATABASE=HD PVR + +usb:v2040p4903* + ID_PRODUCT_FROM_DATABASE=HS PVR + +usb:v2040p4982* + ID_PRODUCT_FROM_DATABASE=HD PVR + +usb:v2040p5500* + ID_PRODUCT_FROM_DATABASE=Windham + +usb:v2040p5510* + ID_PRODUCT_FROM_DATABASE=Windham + +usb:v2040p5520* + ID_PRODUCT_FROM_DATABASE=Windham + +usb:v2040p5530* + ID_PRODUCT_FROM_DATABASE=Windham + +usb:v2040p5580* + ID_PRODUCT_FROM_DATABASE=Windham + +usb:v2040p5590* + ID_PRODUCT_FROM_DATABASE=Windham + +usb:v2040p6500* + ID_PRODUCT_FROM_DATABASE=WinTV HVR-900 + +usb:v2040p6502* + ID_PRODUCT_FROM_DATABASE=WinTV HVR-900 + +usb:v2040p6503* + ID_PRODUCT_FROM_DATABASE=WinTV HVR-930 + +usb:v2040p6513* + ID_PRODUCT_FROM_DATABASE=WinTV HVR-980 + +usb:v2040p7050* + ID_PRODUCT_FROM_DATABASE=Nova-T Stick + +usb:v2040p7060* + ID_PRODUCT_FROM_DATABASE=Nova-T Stick 2 + +usb:v2040p7070* + ID_PRODUCT_FROM_DATABASE=Nova-T Stick 3 + +usb:v2040p7240* + ID_PRODUCT_FROM_DATABASE=WinTV HVR-850 + +usb:v2040p8400* + ID_PRODUCT_FROM_DATABASE=WinTV Nova-T-500 + +usb:v2040p9300* + ID_PRODUCT_FROM_DATABASE=WinTV NOVA-T USB2 (cold) + +usb:v2040p9301* + ID_PRODUCT_FROM_DATABASE=WinTV NOVA-T USB2 (warm) + +usb:v2040p9941* + ID_PRODUCT_FROM_DATABASE=WinTV Nova-T-500 + +usb:v2040p9950* + ID_PRODUCT_FROM_DATABASE=WinTV Nova-T-500 + +usb:v2040pB910* + ID_PRODUCT_FROM_DATABASE=Windham + +usb:v2040pB980* + ID_PRODUCT_FROM_DATABASE=Windham + +usb:v2040pB990* + ID_PRODUCT_FROM_DATABASE=Windham + +usb:v2040pC000* + ID_PRODUCT_FROM_DATABASE=Windham + +usb:v2040pC010* + ID_PRODUCT_FROM_DATABASE=Windham + +usb:v2047* + ID_VENDOR_FROM_DATABASE=Texas Instruments + +usb:v2047p0200* + ID_PRODUCT_FROM_DATABASE=MSP430 USB HID Bootstrap Loader + +usb:v2080* + ID_VENDOR_FROM_DATABASE=Barnes & Noble + +usb:v2080p0001* + ID_PRODUCT_FROM_DATABASE=nook + +usb:v2080p0002* + ID_PRODUCT_FROM_DATABASE=NOOKcolor + +usb:v2080p0003* + ID_PRODUCT_FROM_DATABASE=NOOK Simple Touch + +usb:v2080p0004* + ID_PRODUCT_FROM_DATABASE=NOOK Tablet + +usb:v2087* + ID_VENDOR_FROM_DATABASE=Cando + +usb:v2087p0A01* + ID_PRODUCT_FROM_DATABASE=Multi Touch Panel + +usb:v2087p0A02* + ID_PRODUCT_FROM_DATABASE=Multi Touch Panel + +usb:v2087p0B03* + ID_PRODUCT_FROM_DATABASE=Multi Touch Panel + +usb:v20A0* + ID_VENDOR_FROM_DATABASE=Clay Logic + +usb:v20A0p4123* + ID_PRODUCT_FROM_DATABASE=IKALOGIC SCANALOGIC 2 + +usb:v20A0p414A* + ID_PRODUCT_FROM_DATABASE=MDE SPI Interface + +usb:v20A0p415A* + ID_PRODUCT_FROM_DATABASE=OpenPilot + +usb:v20A0p415B* + ID_PRODUCT_FROM_DATABASE=CopterControl + +usb:v20A0p415C* + ID_PRODUCT_FROM_DATABASE=PipXtreme + +usb:v20B1* + ID_VENDOR_FROM_DATABASE=XMOS Ltd + +usb:v20B1p10AD* + ID_PRODUCT_FROM_DATABASE=XUSB Loader + +usb:v20B1pF7D1* + ID_PRODUCT_FROM_DATABASE=XTAG2 - JTAG Adapter + +usb:v20B3* + ID_VENDOR_FROM_DATABASE=Hanvon + +usb:v20B3p0A18* + ID_PRODUCT_FROM_DATABASE=10.1 Touch screen overlay + +usb:v20B7* + ID_VENDOR_FROM_DATABASE=Qi Hardware + +usb:v20B7p0713* + ID_PRODUCT_FROM_DATABASE=Milkymist JTAG/serial + +usb:v20B7p1540* + ID_PRODUCT_FROM_DATABASE=ben-wpan, AT86RF230-based + +usb:v20B7p1DB5* + ID_PRODUCT_FROM_DATABASE=IDBG in DFU mode + +usb:v20B7p1DB6* + ID_PRODUCT_FROM_DATABASE=IDBG in normal mode + +usb:v20B7pC25B* + ID_PRODUCT_FROM_DATABASE=C2 Dongle + +usb:v20B7pCB72* + ID_PRODUCT_FROM_DATABASE=ben-wpan, cntr + +usb:v20DF* + ID_VENDOR_FROM_DATABASE=Simtec Electronics + +usb:v20DFp0001* + ID_PRODUCT_FROM_DATABASE=Entropy Key [UDEKEY01] + +usb:v20F4* + ID_VENDOR_FROM_DATABASE=TRENDnet + +usb:v20F4p648B* + ID_PRODUCT_FROM_DATABASE=TEW-648UBM 802.11n 150Mbps Micro Wireless N Adapter [Realtek RTL8188CUS] + +usb:v2101* + ID_VENDOR_FROM_DATABASE=ActionStar + +usb:v2101p0201* + ID_PRODUCT_FROM_DATABASE=SIIG 4-to-2 Printer Switch + +usb:v2162* + ID_VENDOR_FROM_DATABASE=Creative (?) + +usb:v2162p2031* + ID_PRODUCT_FROM_DATABASE=Network Blaster Wireless Adapter + +usb:v2162p500C* + ID_PRODUCT_FROM_DATABASE=DE5771 Modem Blaster + +usb:v2162p8001* + ID_PRODUCT_FROM_DATABASE=Broadxent BritePort DSL Bridge 8010U + +usb:v2184* + ID_VENDOR_FROM_DATABASE=GW Instek + +usb:v2184p0005* + ID_PRODUCT_FROM_DATABASE=GDS-3000 Oscilloscope + +usb:v2184p0006* + ID_PRODUCT_FROM_DATABASE=GDS-3000 Oscilloscope + +usb:v2184p0011* + ID_PRODUCT_FROM_DATABASE=AFG Function Generator (CDC) + +usb:v21A1* + ID_VENDOR_FROM_DATABASE=Emotiv Systems Pty. Ltd. + +usb:v21A1p0001* + ID_PRODUCT_FROM_DATABASE=EPOC Consumer Headset Wireless Dongle + +usb:v21D6* + ID_VENDOR_FROM_DATABASE=Agecodagis SARL + +usb:v21D6p0002* + ID_PRODUCT_FROM_DATABASE=Seismic recorder [Tellus] + +usb:v2222* + ID_VENDOR_FROM_DATABASE=MacAlly + +usb:v2222p0004* + ID_PRODUCT_FROM_DATABASE=iWebKey Keyboard + +usb:v2222p2520* + ID_PRODUCT_FROM_DATABASE=Mini Tablet + +usb:v2222p4050* + ID_PRODUCT_FROM_DATABASE=AirStick joystick + +usb:v2227* + ID_VENDOR_FROM_DATABASE=SAMWOO Enterprise + +usb:v2227p3105* + ID_PRODUCT_FROM_DATABASE=SKYDATA SKD-U100 + +usb:v2233* + ID_VENDOR_FROM_DATABASE=RadioShack Corporation + +usb:v2233p6323* + ID_PRODUCT_FROM_DATABASE=USB Electronic Scale + +usb:v2237* + ID_VENDOR_FROM_DATABASE=Kobo Inc. + +usb:v2237p4161* + ID_PRODUCT_FROM_DATABASE=eReader White + +usb:v22A6* + ID_VENDOR_FROM_DATABASE=Pie Digital, Inc. + +usb:v22A6pFFFF* + ID_PRODUCT_FROM_DATABASE=PieKey "beta" 4GB model 4E4F41482E4F5247 (SM3251Q BB) + +usb:v22B8* + ID_VENDOR_FROM_DATABASE=Motorola PCS + +usb:v22B8p0001* + ID_PRODUCT_FROM_DATABASE=Wally 2.2 chipset + +usb:v22B8p0002* + ID_PRODUCT_FROM_DATABASE=Wally 2.4 chipset + +usb:v22B8p0005* + ID_PRODUCT_FROM_DATABASE=V.60c/V.60i GSM Phone + +usb:v22B8p0830* + ID_PRODUCT_FROM_DATABASE=2386C-HT820 + +usb:v22B8p0833* + ID_PRODUCT_FROM_DATABASE=2386C-HT820 [Flash Mode] + +usb:v22B8p0850* + ID_PRODUCT_FROM_DATABASE=Bluetooth Device + +usb:v22B8p1001* + ID_PRODUCT_FROM_DATABASE=Patriot 1.0 (GSM) chipset + +usb:v22B8p1002* + ID_PRODUCT_FROM_DATABASE=Patriot 2.0 chipset + +usb:v22B8p1005* + ID_PRODUCT_FROM_DATABASE=T280e GSM/GPRS Phone + +usb:v22B8p1101* + ID_PRODUCT_FROM_DATABASE=Patriot 1.0 (TDMA) chipset + +usb:v22B8p1801* + ID_PRODUCT_FROM_DATABASE=Rainbow chipset flash + +usb:v22B8p2035* + ID_PRODUCT_FROM_DATABASE=Bluetooth Device + +usb:v22B8p2805* + ID_PRODUCT_FROM_DATABASE=GSM Modem + +usb:v22B8p2821* + ID_PRODUCT_FROM_DATABASE=T720 GSM Phone + +usb:v22B8p2822* + ID_PRODUCT_FROM_DATABASE=V.120e GSM Phone + +usb:v22B8p2823* + ID_PRODUCT_FROM_DATABASE=Flash Interface + +usb:v22B8p2A01* + ID_PRODUCT_FROM_DATABASE=MSM6050 chipset + +usb:v22B8p2A02* + ID_PRODUCT_FROM_DATABASE=CDMA modem + +usb:v22B8p2A03* + ID_PRODUCT_FROM_DATABASE=MSM6050 chipset flash + +usb:v22B8p2A21* + ID_PRODUCT_FROM_DATABASE=V710 GSM Phone (P2K) + +usb:v22B8p2A22* + ID_PRODUCT_FROM_DATABASE=V710 GSM Phone (AT) + +usb:v22B8p2A23* + ID_PRODUCT_FROM_DATABASE=MSM6100 chipset flash + +usb:v22B8p2A41* + ID_PRODUCT_FROM_DATABASE=MSM6300 chipset + +usb:v22B8p2A42* + ID_PRODUCT_FROM_DATABASE=Usb Modem + +usb:v22B8p2A43* + ID_PRODUCT_FROM_DATABASE=MSM6300 chipset flash + +usb:v22B8p2A61* + ID_PRODUCT_FROM_DATABASE=E815 GSM Phone (P2K) + +usb:v22B8p2A62* + ID_PRODUCT_FROM_DATABASE=E815 GSM Phone (AT) + +usb:v22B8p2A63* + ID_PRODUCT_FROM_DATABASE=MSM6500 chipset flash + +usb:v22B8p2A81* + ID_PRODUCT_FROM_DATABASE=MSM6025 chipset + +usb:v22B8p2A83* + ID_PRODUCT_FROM_DATABASE=MSM6025 chipset flash + +usb:v22B8p2AC1* + ID_PRODUCT_FROM_DATABASE=MSM6100 chipset + +usb:v22B8p2AC3* + ID_PRODUCT_FROM_DATABASE=MSM6100 chipset flash + +usb:v22B8p2D78* + ID_PRODUCT_FROM_DATABASE=XT300[SPICE] + +usb:v22B8p3001* + ID_PRODUCT_FROM_DATABASE=A835/E1000 GSM Phone (P2K) + +usb:v22B8p3002* + ID_PRODUCT_FROM_DATABASE=A835/E1000 GSM Phone (AT) + +usb:v22B8p3801* + ID_PRODUCT_FROM_DATABASE=C350L/C450 (P2K) + +usb:v22B8p3802* + ID_PRODUCT_FROM_DATABASE=C330/C350L/C450/EZX GSM Phone (AT) + +usb:v22B8p3803* + ID_PRODUCT_FROM_DATABASE=Neptune LT chipset flash + +usb:v22B8p4001* + ID_PRODUCT_FROM_DATABASE=OMAP 1.0 chipset + +usb:v22B8p4002* + ID_PRODUCT_FROM_DATABASE=A920/A925 UMTS Phone + +usb:v22B8p4003* + ID_PRODUCT_FROM_DATABASE=OMAP 1.0 chipset flash + +usb:v22B8p4008* + ID_PRODUCT_FROM_DATABASE=OMAP 1.0 chipset RDL + +usb:v22B8p41D6* + ID_PRODUCT_FROM_DATABASE=Droid X (Windows media mode) + +usb:v22B8p41D9* + ID_PRODUCT_FROM_DATABASE=Droid/Milestone + +usb:v22B8p41DB* + ID_PRODUCT_FROM_DATABASE=Droid/Milestone (Debug mode) + +usb:v22B8p41DE* + ID_PRODUCT_FROM_DATABASE=Droid X (PC mode) + +usb:v22B8p4204* + ID_PRODUCT_FROM_DATABASE=MPx200 Smartphone + +usb:v22B8p4214* + ID_PRODUCT_FROM_DATABASE=MPc GSM + +usb:v22B8p4224* + ID_PRODUCT_FROM_DATABASE=MPx220 Smartphone + +usb:v22B8p4234* + ID_PRODUCT_FROM_DATABASE=MPc CDMA + +usb:v22B8p4244* + ID_PRODUCT_FROM_DATABASE=MPx100 Smartphone + +usb:v22B8p4285* + ID_PRODUCT_FROM_DATABASE=Droid X (Mass storage) + +usb:v22B8p4801* + ID_PRODUCT_FROM_DATABASE=Neptune LTS chipset + +usb:v22B8p4803* + ID_PRODUCT_FROM_DATABASE=Neptune LTS chipset flash + +usb:v22B8p4810* + ID_PRODUCT_FROM_DATABASE=Triplet GSM Phone (storage) + +usb:v22B8p4901* + ID_PRODUCT_FROM_DATABASE=Triplet GSM Phone (P2K) + +usb:v22B8p4902* + ID_PRODUCT_FROM_DATABASE=Triplet GSM Phone (AT) + +usb:v22B8p4903* + ID_PRODUCT_FROM_DATABASE=Neptune LTE chipset flash + +usb:v22B8p4A01* + ID_PRODUCT_FROM_DATABASE=Neptune LTX chipset + +usb:v22B8p4A03* + ID_PRODUCT_FROM_DATABASE=Neptune LTX chipset flash + +usb:v22B8p4A32* + ID_PRODUCT_FROM_DATABASE=L6-imode Phone + +usb:v22B8p5801* + ID_PRODUCT_FROM_DATABASE=Neptune ULS chipset + +usb:v22B8p5803* + ID_PRODUCT_FROM_DATABASE=Neptune ULS chipset flash + +usb:v22B8p5901* + ID_PRODUCT_FROM_DATABASE=Neptune VLT chipset + +usb:v22B8p5903* + ID_PRODUCT_FROM_DATABASE=Neptune VLT chipset flash + +usb:v22B8p6001* + ID_PRODUCT_FROM_DATABASE=Dalhart EZX + +usb:v22B8p6003* + ID_PRODUCT_FROM_DATABASE=Dalhart flash + +usb:v22B8p6004* + ID_PRODUCT_FROM_DATABASE=EZX GSM Phone (CDC Net) + +usb:v22B8p6006* + ID_PRODUCT_FROM_DATABASE=MOTOROKR E6 + +usb:v22B8p6008* + ID_PRODUCT_FROM_DATABASE=Dalhart RDL + +usb:v22B8p6009* + ID_PRODUCT_FROM_DATABASE=EZX GSM Phone (P2K) + +usb:v22B8p600A* + ID_PRODUCT_FROM_DATABASE=Dalhart EZX config 17 + +usb:v22B8p600B* + ID_PRODUCT_FROM_DATABASE=Dalhart EZX config 18 + +usb:v22B8p600C* + ID_PRODUCT_FROM_DATABASE=EZX GSM Phone (USBLAN) + +usb:v22B8p6021* + ID_PRODUCT_FROM_DATABASE=JUIX chipset + +usb:v22B8p6023* + ID_PRODUCT_FROM_DATABASE=JUIX chipset flash + +usb:v22B8p6026* + ID_PRODUCT_FROM_DATABASE=Flash RAM Downloader/miniOS + +usb:v22B8p6027* + ID_PRODUCT_FROM_DATABASE=USBLAN + +usb:v22B8p604C* + ID_PRODUCT_FROM_DATABASE=EZX GSM Phone (Storage) + +usb:v22B8p6101* + ID_PRODUCT_FROM_DATABASE=Talon integrated chipset + +usb:v22B8p6401* + ID_PRODUCT_FROM_DATABASE=Argon chipset + +usb:v22B8p6403* + ID_PRODUCT_FROM_DATABASE=Argon chipset flash + +usb:v22B8p6415* + ID_PRODUCT_FROM_DATABASE=ROKR Z6 (MTP mode) + +usb:v22B8p6604* + ID_PRODUCT_FROM_DATABASE=Washington CDMA Phone + +usb:v22B8p6631* + ID_PRODUCT_FROM_DATABASE=CDC Modem + +usb:v22B8p7001* + ID_PRODUCT_FROM_DATABASE=Q Smartphone + +usb:v22B8pFE01* + ID_PRODUCT_FROM_DATABASE=StarTAC III MS900 + +usb:v22B9* + ID_VENDOR_FROM_DATABASE=eTurboTouch Technology, Inc. + +usb:v22B9p0006* + ID_PRODUCT_FROM_DATABASE=Touch Screen + +usb:v22BA* + ID_VENDOR_FROM_DATABASE=Technology Innovation Holdings, Ltd + +usb:v2304* + ID_VENDOR_FROM_DATABASE=Pinnacle Systems, Inc. + +usb:v2304p0109* + ID_PRODUCT_FROM_DATABASE=Studio PCTV USB (SECAM) + +usb:v2304p0110* + ID_PRODUCT_FROM_DATABASE=Studio PCTV USB (PAL) + +usb:v2304p0111* + ID_PRODUCT_FROM_DATABASE=Miro PCTV USB + +usb:v2304p0112* + ID_PRODUCT_FROM_DATABASE=Studio PCTV USB (NTSC) with FM radio + +usb:v2304p0201* + ID_PRODUCT_FROM_DATABASE=Systems MovieBox Device + +usb:v2304p0204* + ID_PRODUCT_FROM_DATABASE=MovieBox USB_B + +usb:v2304p0205* + ID_PRODUCT_FROM_DATABASE=DVC 150B + +usb:v2304p0206* + ID_PRODUCT_FROM_DATABASE=Systems MovieBox Deluxe Device + +usb:v2304p0207* + ID_PRODUCT_FROM_DATABASE=Dazzle DVC90 Video Device + +usb:v2304p0208* + ID_PRODUCT_FROM_DATABASE=Studio PCTV USB2 + +usb:v2304p020E* + ID_PRODUCT_FROM_DATABASE=PCTV 200e + +usb:v2304p020F* + ID_PRODUCT_FROM_DATABASE=PCTV 400e BDA Device + +usb:v2304p0210* + ID_PRODUCT_FROM_DATABASE=Studio PCTV USB (PAL) with FM radio + +usb:v2304p0212* + ID_PRODUCT_FROM_DATABASE=Studio PCTV USB (NTSC) + +usb:v2304p0213* + ID_PRODUCT_FROM_DATABASE=500-USB Device + +usb:v2304p0214* + ID_PRODUCT_FROM_DATABASE=Studio PCTV USB (PAL) with FM radio + +usb:v2304p0216* + ID_PRODUCT_FROM_DATABASE=PCTV 60e + +usb:v2304p0219* + ID_PRODUCT_FROM_DATABASE=PCTV 260e + +usb:v2304p021A* + ID_PRODUCT_FROM_DATABASE=Dazzle DVC100 Audio Device + +usb:v2304p021B* + ID_PRODUCT_FROM_DATABASE=Dazzle DVC130/DVC170 + +usb:v2304p021D* + ID_PRODUCT_FROM_DATABASE=Dazzle DVC130 + +usb:v2304p021E* + ID_PRODUCT_FROM_DATABASE=Dazzle DVC170 + +usb:v2304p021F* + ID_PRODUCT_FROM_DATABASE=PCTV Sat HDTV Pro BDA Device + +usb:v2304p0222* + ID_PRODUCT_FROM_DATABASE=PCTV Sat Pro BDA Device + +usb:v2304p0223* + ID_PRODUCT_FROM_DATABASE=DazzleTV Sat BDA Device + +usb:v2304p0225* + ID_PRODUCT_FROM_DATABASE=Remote Kit Infrared Transceiver + +usb:v2304p0226* + ID_PRODUCT_FROM_DATABASE=PCTV 330e + +usb:v2304p0227* + ID_PRODUCT_FROM_DATABASE=PCTV for Mac, HD Stick + +usb:v2304p0228* + ID_PRODUCT_FROM_DATABASE=PCTV DVB-T Flash Stick + +usb:v2304p0229* + ID_PRODUCT_FROM_DATABASE=PCTV Dual DVB-T 2001e + +usb:v2304p022A* + ID_PRODUCT_FROM_DATABASE=PCTV 160e + +usb:v2304p022B* + ID_PRODUCT_FROM_DATABASE=PCTV 71e [Afatech AF9015] + +usb:v2304p0232* + ID_PRODUCT_FROM_DATABASE=PCTV 170e + +usb:v2304p0236* + ID_PRODUCT_FROM_DATABASE=PCTV 72e [DiBcom DiB7000PC] + +usb:v2304p0237* + ID_PRODUCT_FROM_DATABASE=PCTV 73e [DiBcom DiB7000PC] + +usb:v2304p023A* + ID_PRODUCT_FROM_DATABASE=PCTV 801e + +usb:v2304p023B* + ID_PRODUCT_FROM_DATABASE=PCTV 801e SE + +usb:v2304p023D* + ID_PRODUCT_FROM_DATABASE=PCTV 340e + +usb:v2304p023E* + ID_PRODUCT_FROM_DATABASE=PCTV 340e SE + +usb:v2304p0300* + ID_PRODUCT_FROM_DATABASE=Studio Linx Video input cable (NTSC) + +usb:v2304p0301* + ID_PRODUCT_FROM_DATABASE=Studio Linx Video input cable (PAL) + +usb:v2304p0302* + ID_PRODUCT_FROM_DATABASE=Dazzle DVC120 + +usb:v2304p0419* + ID_PRODUCT_FROM_DATABASE=PCTV Bungee USB (PAL) with FM radio + +usb:v2304p061D* + ID_PRODUCT_FROM_DATABASE=PCTV Deluxe (NTSC) Device + +usb:v2304p061E* + ID_PRODUCT_FROM_DATABASE=PCTV Deluxe (PAL) Device + +usb:v2318* + ID_VENDOR_FROM_DATABASE=Shining Technologies, Inc. [hex] + +usb:v2318p0011* + ID_PRODUCT_FROM_DATABASE=CitiDISK Jr. IDE Enclosure + +usb:v2341* + ID_VENDOR_FROM_DATABASE=Arduino SA + +usb:v2341p0001* + ID_PRODUCT_FROM_DATABASE=Uno (CDC ACM) + +usb:v2341p0010* + ID_PRODUCT_FROM_DATABASE=Mega 2560 (CDC ACM) + +usb:v2341p003B* + ID_PRODUCT_FROM_DATABASE=Serial Adapter (CDC ACM) + +usb:v2341p003F* + ID_PRODUCT_FROM_DATABASE=Mega ADK (CDC ACM) + +usb:v2341p0042* + ID_PRODUCT_FROM_DATABASE=Mega 2560 R3 (CDC ACM) + +usb:v2341p0043* + ID_PRODUCT_FROM_DATABASE=Uno R3 (CDC ACM) + +usb:v2341p0044* + ID_PRODUCT_FROM_DATABASE=Mega ADK R3 (CDC ACM) + +usb:v2341p0045* + ID_PRODUCT_FROM_DATABASE=Serial R3 (CDC ACM) + +usb:v2341p8036* + ID_PRODUCT_FROM_DATABASE=Leonardo (CDC ACM, HID) + +usb:v2373* + ID_VENDOR_FROM_DATABASE=Pumatronix Ltda + +usb:v2373p0001* + ID_PRODUCT_FROM_DATABASE=5 MegaPixel Digital Still Camera [DSC5M] + +usb:v2375* + ID_VENDOR_FROM_DATABASE=Digit@lway, Inc. + +usb:v2375p0001* + ID_PRODUCT_FROM_DATABASE=Digital Audio Player + +usb:v2406* + ID_VENDOR_FROM_DATABASE=SANHO Digital Electronics Co., Ltd. + +usb:v2406p6688* + ID_PRODUCT_FROM_DATABASE=PD7X Portable Storage + +usb:v2478* + ID_VENDOR_FROM_DATABASE=Tripp-Lite + +usb:v2478p2008* + ID_PRODUCT_FROM_DATABASE=U209-000-R Serial Port + +usb:v2632* + ID_VENDOR_FROM_DATABASE=TwinMOS + +usb:v2632p3209* + ID_PRODUCT_FROM_DATABASE=7-in-1 Card Reader + +usb:v2650* + ID_VENDOR_FROM_DATABASE=Electronics For Imaging, Inc. [hex] + +usb:v2659* + ID_VENDOR_FROM_DATABASE=Sundtek + +usb:v2659p1101* + ID_PRODUCT_FROM_DATABASE=TNT DVB-T/DAB/DAB+/FM + +usb:v2659p1201* + ID_PRODUCT_FROM_DATABASE=FM Transmitter/Receiver + +usb:v2659p1202* + ID_PRODUCT_FROM_DATABASE=MediaTV Analog/FM/DVB-T + +usb:v2659p1203* + ID_PRODUCT_FROM_DATABASE=MediaTV Analog/FM/DVB-T MiniPCIe + +usb:v2659p1204* + ID_PRODUCT_FROM_DATABASE=MediaTV Analog/FM/ATSC + +usb:v2659p1205* + ID_PRODUCT_FROM_DATABASE=SkyTV Ultimate V + +usb:v2659p1206* + ID_PRODUCT_FROM_DATABASE=MediaTV DVB-T MiniPCIe + +usb:v2659p1207* + ID_PRODUCT_FROM_DATABASE=Sundtek HD Capture + +usb:v2659p1208* + ID_PRODUCT_FROM_DATABASE=Sundtek SkyTV Ultimate III + +usb:v2730* + ID_VENDOR_FROM_DATABASE=Citizen + +usb:v2730p200F* + ID_PRODUCT_FROM_DATABASE=CT-S310 Label printer + +usb:v2735* + ID_VENDOR_FROM_DATABASE=DigitalWay + +usb:v2735p0003* + ID_PRODUCT_FROM_DATABASE=MPIO HS100 + +usb:v2735p1001* + ID_PRODUCT_FROM_DATABASE=MPIO FY200 + +usb:v2735p1002* + ID_PRODUCT_FROM_DATABASE=MPIO FL100 + +usb:v2735p1003* + ID_PRODUCT_FROM_DATABASE=MPIO FD100 + +usb:v2735p1004* + ID_PRODUCT_FROM_DATABASE=MPIO HD200 + +usb:v2735p1005* + ID_PRODUCT_FROM_DATABASE=MPIO HD300 + +usb:v2735p1006* + ID_PRODUCT_FROM_DATABASE=MPIO FG100 + +usb:v2735p1007* + ID_PRODUCT_FROM_DATABASE=MPIO FG130 + +usb:v2735p1008* + ID_PRODUCT_FROM_DATABASE=MPIO FY300 + +usb:v2735p1009* + ID_PRODUCT_FROM_DATABASE=MPIO FY400 + +usb:v2735p100A* + ID_PRODUCT_FROM_DATABASE=MPIO FL300 + +usb:v2735p100B* + ID_PRODUCT_FROM_DATABASE=MPIO HS200 + +usb:v2735p100C* + ID_PRODUCT_FROM_DATABASE=MPIO FL350 + +usb:v2735p100D* + ID_PRODUCT_FROM_DATABASE=MPIO FY500 + +usb:v2735p100E* + ID_PRODUCT_FROM_DATABASE=MPIO FY500 + +usb:v2735p100F* + ID_PRODUCT_FROM_DATABASE=MPIO FY600 + +usb:v2735p1012* + ID_PRODUCT_FROM_DATABASE=MPIO FL400 + +usb:v2735p1013* + ID_PRODUCT_FROM_DATABASE=MPIO HD400 + +usb:v2735p1014* + ID_PRODUCT_FROM_DATABASE=MPIO HD400 + +usb:v2735p1016* + ID_PRODUCT_FROM_DATABASE=MPIO FY700 + +usb:v2735p1017* + ID_PRODUCT_FROM_DATABASE=MPIO FY700 + +usb:v2735p1018* + ID_PRODUCT_FROM_DATABASE=MPIO FY800 + +usb:v2735p1019* + ID_PRODUCT_FROM_DATABASE=MPIO FY800 + +usb:v2735p101A* + ID_PRODUCT_FROM_DATABASE=MPIO FY900 + +usb:v2735p101B* + ID_PRODUCT_FROM_DATABASE=MPIO FY900 + +usb:v2735p102B* + ID_PRODUCT_FROM_DATABASE=MPIO FL500 + +usb:v2735p102C* + ID_PRODUCT_FROM_DATABASE=MPIO FL500 + +usb:v2735p103F* + ID_PRODUCT_FROM_DATABASE=MPIO FY570 + +usb:v2735p1040* + ID_PRODUCT_FROM_DATABASE=MPIO FY570 + +usb:v2735p1041* + ID_PRODUCT_FROM_DATABASE=MPIO FY670 + +usb:v2735p1042* + ID_PRODUCT_FROM_DATABASE=MPIO FY670 + +usb:v2735p1043* + ID_PRODUCT_FROM_DATABASE=HCT HMD-180A + +usb:v2735p1044* + ID_PRODUCT_FROM_DATABASE=HCT HMD-180A + +usb:v2770* + ID_VENDOR_FROM_DATABASE=NHJ, Ltd + +usb:v2770p0A01* + ID_PRODUCT_FROM_DATABASE=ScanJet 4600 series + +usb:v2770p905C* + ID_PRODUCT_FROM_DATABASE=Che-Ez Snap SNAP-U/Digigr8/Soundstar TDC-35 + +usb:v2770p9060* + ID_PRODUCT_FROM_DATABASE=A130 + +usb:v2770p9120* + ID_PRODUCT_FROM_DATABASE=Che-ez! Snap / iClick Tiny VGA Digital Camera + +usb:v2770p9130* + ID_PRODUCT_FROM_DATABASE=TCG 501 + +usb:v2770p913C* + ID_PRODUCT_FROM_DATABASE=Argus DC-1730 + +usb:v2770p9150* + ID_PRODUCT_FROM_DATABASE=Mini Cam + +usb:v2770p9153* + ID_PRODUCT_FROM_DATABASE=iClick 5X + +usb:v2770p915D* + ID_PRODUCT_FROM_DATABASE=Cyberpix S-210S / Little Tikes My Real Digital Camera + +usb:v2770p930B* + ID_PRODUCT_FROM_DATABASE=CCD Webcam(PC370R) + +usb:v2770p930C* + ID_PRODUCT_FROM_DATABASE=CCD Webcam(PC370R) + +usb:v2821* + ID_VENDOR_FROM_DATABASE=ASUSTek Computer Inc. + +usb:v2821p0161* + ID_PRODUCT_FROM_DATABASE=WL-161 802.11b Wireless Adapter [SiS 162U] + +usb:v2821p160F* + ID_PRODUCT_FROM_DATABASE=WL-160g 802.11g Wireless Adapter [Envara WiND512] + +usb:v2821p3300* + ID_PRODUCT_FROM_DATABASE=WL-140 / Hawking HWU36D 802.11b Wireless Adapter [Intersil PRISM 3] + +usb:v2899* + ID_VENDOR_FROM_DATABASE=Toptronic Industrial Co., Ltd + +usb:v2899p012C* + ID_PRODUCT_FROM_DATABASE=Camera Device + +usb:v2C02* + ID_VENDOR_FROM_DATABASE=Planex Communications + +usb:v2C02p14EA* + ID_PRODUCT_FROM_DATABASE=GW-US11H WLAN + +usb:v2C1A* + ID_VENDOR_FROM_DATABASE=Dolphin Peripherals + +usb:v2C1Ap0000* + ID_PRODUCT_FROM_DATABASE=Wireless Optical Mouse + +usb:v2FB2* + ID_VENDOR_FROM_DATABASE=Fujitsu, Ltd + +usb:v3125* + ID_VENDOR_FROM_DATABASE=Eagletron + +usb:v3125p0001* + ID_PRODUCT_FROM_DATABASE=TrackerPod Camera Stand + +usb:v3176* + ID_VENDOR_FROM_DATABASE=Whanam Electronics Co., Ltd + +usb:v3275* + ID_VENDOR_FROM_DATABASE=VidzMedia Pte Ltd + +usb:v3275p4FB1* + ID_PRODUCT_FROM_DATABASE=MonsterTV P2H + +usb:v3334* + ID_VENDOR_FROM_DATABASE=AEI + +usb:v3334p1701* + ID_PRODUCT_FROM_DATABASE=Fast Ethernet + +usb:v3340* + ID_VENDOR_FROM_DATABASE=Yakumo + +usb:v3340p043A* + ID_PRODUCT_FROM_DATABASE=Mio A701 DigiWalker PPCPhone + +usb:v3340p0E3A* + ID_PRODUCT_FROM_DATABASE=Pocket PC 300 GPS SL / Typhoon MyGuide 3500 + +usb:v3340pA0A3* + ID_PRODUCT_FROM_DATABASE=deltaX 5 BT (D) PDA + +usb:v3504* + ID_VENDOR_FROM_DATABASE=Micro Star + +usb:v3504pF110* + ID_PRODUCT_FROM_DATABASE=Security Key + +usb:v3538* + ID_VENDOR_FROM_DATABASE=Power Quotient International Co., Ltd + +usb:v3538p0001* + ID_PRODUCT_FROM_DATABASE=Travel Flash + +usb:v3538p0015* + ID_PRODUCT_FROM_DATABASE=Mass Storge Device + +usb:v3538p0022* + ID_PRODUCT_FROM_DATABASE=Hi-Speed Mass Storage Device + +usb:v3538p0042* + ID_PRODUCT_FROM_DATABASE=Cool Drive U339 Flash Disk + +usb:v3538p0054* + ID_PRODUCT_FROM_DATABASE=Flash Drive (2GB) + +usb:v3579* + ID_VENDOR_FROM_DATABASE=DIVA + +usb:v3579p6901* + ID_PRODUCT_FROM_DATABASE=Media Reader + +usb:v3636* + ID_VENDOR_FROM_DATABASE=InVibro + +usb:v3838* + ID_VENDOR_FROM_DATABASE=WEM + +usb:v3838p0001* + ID_PRODUCT_FROM_DATABASE=5-in-1 Card Reader + +usb:v3923* + ID_VENDOR_FROM_DATABASE=National Instruments Corp. + +usb:v3923p12C0* + ID_PRODUCT_FROM_DATABASE=DAQPad-6020E + +usb:v3923p12D0* + ID_PRODUCT_FROM_DATABASE=DAQPad-6507 + +usb:v3923p12E0* + ID_PRODUCT_FROM_DATABASE=NI 4350 + +usb:v3923p12F0* + ID_PRODUCT_FROM_DATABASE=NI 5102 + +usb:v3923p1750* + ID_PRODUCT_FROM_DATABASE=DAQPad-6508 + +usb:v3923p17B0* + ID_PRODUCT_FROM_DATABASE=USB-ISA-Bridge + +usb:v3923p1820* + ID_PRODUCT_FROM_DATABASE=DAQPad-6020E (68 pin I/O) + +usb:v3923p1830* + ID_PRODUCT_FROM_DATABASE=DAQPad-6020E (BNC) + +usb:v3923p1F00* + ID_PRODUCT_FROM_DATABASE=DAQPad-6024E + +usb:v3923p1F10* + ID_PRODUCT_FROM_DATABASE=DAQPad-6024E + +usb:v3923p1F20* + ID_PRODUCT_FROM_DATABASE=DAQPad-6025E + +usb:v3923p1F30* + ID_PRODUCT_FROM_DATABASE=DAQPad-6025E + +usb:v3923p1F40* + ID_PRODUCT_FROM_DATABASE=DAQPad-6036E + +usb:v3923p1F50* + ID_PRODUCT_FROM_DATABASE=DAQPad-6036E + +usb:v3923p2F80* + ID_PRODUCT_FROM_DATABASE=DAQPad-6052E + +usb:v3923p2F90* + ID_PRODUCT_FROM_DATABASE=DAQPad-6052E + +usb:v3923p702B* + ID_PRODUCT_FROM_DATABASE=GPIB-USB-B + +usb:v3923p703C* + ID_PRODUCT_FROM_DATABASE=USB-485 RS485 Cable + +usb:v3923p709B* + ID_PRODUCT_FROM_DATABASE=GPIB-USB-HS + +usb:v3923p7254* + ID_PRODUCT_FROM_DATABASE=NI MIO (data acquisition card) firmware updater + +usb:v3923p729E* + ID_PRODUCT_FROM_DATABASE=USB-6251 (OEM) data acquisition card + +usb:v40BB* + ID_VENDOR_FROM_DATABASE=I-O Data + +usb:v40BBp0A09* + ID_PRODUCT_FROM_DATABASE=USB2.0-SCSI Bridge USB2-SC + +usb:v4101* + ID_VENDOR_FROM_DATABASE=i-rocks + +usb:v4101p1301* + ID_PRODUCT_FROM_DATABASE=IR-2510 usb phone + +usb:v4102* + ID_VENDOR_FROM_DATABASE=iRiver, Ltd. + +usb:v4102p1001* + ID_PRODUCT_FROM_DATABASE=iFP-100 series mp3 player + +usb:v4102p1003* + ID_PRODUCT_FROM_DATABASE=iFP-300 series mp3 player + +usb:v4102p1005* + ID_PRODUCT_FROM_DATABASE=iFP-500 series mp3 player + +usb:v4102p1007* + ID_PRODUCT_FROM_DATABASE=iFP-700 series mp3/ogg vorbis player + +usb:v4102p1008* + ID_PRODUCT_FROM_DATABASE=iFP-800 series mp3/ogg vorbis player + +usb:v4102p100A* + ID_PRODUCT_FROM_DATABASE=iFP-1000 series mp3/ogg vorbis player + +usb:v4102p1014* + ID_PRODUCT_FROM_DATABASE=T20 series mp3/ogg vorbis player (ums firmware) + +usb:v4102p1019* + ID_PRODUCT_FROM_DATABASE=T30 + +usb:v4102p1034* + ID_PRODUCT_FROM_DATABASE=T60 + +usb:v4102p1040* + ID_PRODUCT_FROM_DATABASE=M1Player + +usb:v4102p1041* + ID_PRODUCT_FROM_DATABASE=E100 (ums) + +usb:v4102p1101* + ID_PRODUCT_FROM_DATABASE=iFP-100 series mp3 player (ums firmware) + +usb:v4102p1103* + ID_PRODUCT_FROM_DATABASE=iFP-300 series mp3 player (ums firmware) + +usb:v4102p1105* + ID_PRODUCT_FROM_DATABASE=iFP-500 series mp3 player (ums firmware) + +usb:v4102p1113* + ID_PRODUCT_FROM_DATABASE=T10 (alternate) + +usb:v4102p1117* + ID_PRODUCT_FROM_DATABASE=T10 + +usb:v4102p1119* + ID_PRODUCT_FROM_DATABASE=T30 series mp3/ogg/wma player + +usb:v4102p1141* + ID_PRODUCT_FROM_DATABASE=E100 (mtp) + +usb:v4102p2002* + ID_PRODUCT_FROM_DATABASE=H10 6GB + +usb:v4102p2101* + ID_PRODUCT_FROM_DATABASE=H10 20GB (mtp) + +usb:v4102p2102* + ID_PRODUCT_FROM_DATABASE=H10 5GB (mtp) + +usb:v4102p2105* + ID_PRODUCT_FROM_DATABASE=H10 5/6GB (mtp) + +usb:v413C* + ID_VENDOR_FROM_DATABASE=Dell Computer Corp. + +usb:v413Cp0000* + ID_PRODUCT_FROM_DATABASE=DRAC 5 Virtual Keyboard and Mouse + +usb:v413Cp0001* + ID_PRODUCT_FROM_DATABASE=DRAC 5 Virtual Media + +usb:v413Cp0058* + ID_PRODUCT_FROM_DATABASE=Port Replicator + +usb:v413Cp1001* + ID_PRODUCT_FROM_DATABASE=Keyboard Hub + +usb:v413Cp1002* + ID_PRODUCT_FROM_DATABASE=Keyboard Hub + +usb:v413Cp1003* + ID_PRODUCT_FROM_DATABASE=Keyboard Hub + +usb:v413Cp1005* + ID_PRODUCT_FROM_DATABASE=Multimedia Pro Keyboard Hub + +usb:v413Cp2001* + ID_PRODUCT_FROM_DATABASE=Keyboard HID Support + +usb:v413Cp2002* + ID_PRODUCT_FROM_DATABASE=SK-8125 Keyboard + +usb:v413Cp2003* + ID_PRODUCT_FROM_DATABASE=Keyboard + +usb:v413Cp2005* + ID_PRODUCT_FROM_DATABASE=RT7D50 Keyboard + +usb:v413Cp2010* + ID_PRODUCT_FROM_DATABASE=Keyboard + +usb:v413Cp2011* + ID_PRODUCT_FROM_DATABASE=Multimedia Pro Keyboard + +usb:v413Cp2100* + ID_PRODUCT_FROM_DATABASE=SK-3106 Keyboard + +usb:v413Cp2101* + ID_PRODUCT_FROM_DATABASE=SmartCard Reader Keyboard + +usb:v413Cp2105* + ID_PRODUCT_FROM_DATABASE=Model L100 Keyboard + +usb:v413Cp2106* + ID_PRODUCT_FROM_DATABASE=Dell QuietKey Keyboard + +usb:v413Cp2500* + ID_PRODUCT_FROM_DATABASE=DRAC4 Remote Access Card + +usb:v413Cp2513* + ID_PRODUCT_FROM_DATABASE=internal USB Hub of E-Port Replicator + +usb:v413Cp3010* + ID_PRODUCT_FROM_DATABASE=Optical Wheel Mouse + +usb:v413Cp3012* + ID_PRODUCT_FROM_DATABASE=Optical Wheel Mouse + +usb:v413Cp3016* + ID_PRODUCT_FROM_DATABASE=Optical 5-Button Wheel Mouse + +usb:v413Cp3200* + ID_PRODUCT_FROM_DATABASE=Mouse + +usb:v413Cp4001* + ID_PRODUCT_FROM_DATABASE=Axim X5 + +usb:v413Cp4002* + ID_PRODUCT_FROM_DATABASE=Axim X3 + +usb:v413Cp4003* + ID_PRODUCT_FROM_DATABASE=Axim X30 + +usb:v413Cp4004* + ID_PRODUCT_FROM_DATABASE=Axim Sync + +usb:v413Cp4005* + ID_PRODUCT_FROM_DATABASE=Axim Sync + +usb:v413Cp4006* + ID_PRODUCT_FROM_DATABASE=Axim Sync + +usb:v413Cp4007* + ID_PRODUCT_FROM_DATABASE=Axim Sync + +usb:v413Cp4008* + ID_PRODUCT_FROM_DATABASE=Axim Sync + +usb:v413Cp4009* + ID_PRODUCT_FROM_DATABASE=Axim Sync + +usb:v413Cp4011* + ID_PRODUCT_FROM_DATABASE=Axim X51v + +usb:v413Cp5103* + ID_PRODUCT_FROM_DATABASE=AIO Printer A940 + +usb:v413Cp5105* + ID_PRODUCT_FROM_DATABASE=AIO Printer A920 + +usb:v413Cp5107* + ID_PRODUCT_FROM_DATABASE=AIO Printer A960 + +usb:v413Cp5109* + ID_PRODUCT_FROM_DATABASE=Photo AIO Printer 922 + +usb:v413Cp5110* + ID_PRODUCT_FROM_DATABASE=Photo AIO Printer 962 + +usb:v413Cp5111* + ID_PRODUCT_FROM_DATABASE=Photo AIO Printer 942 + +usb:v413Cp5112* + ID_PRODUCT_FROM_DATABASE=Photo AIO Printer 924 + +usb:v413Cp5113* + ID_PRODUCT_FROM_DATABASE=Photo AIO Printer 944 + +usb:v413Cp5114* + ID_PRODUCT_FROM_DATABASE=Photo AIO Printer 964 + +usb:v413Cp5115* + ID_PRODUCT_FROM_DATABASE=Photo AIO Printer 926 + +usb:v413Cp5116* + ID_PRODUCT_FROM_DATABASE=AIO Printer 946 + +usb:v413Cp5117* + ID_PRODUCT_FROM_DATABASE=Photo AIO Printer 966 + +usb:v413Cp5118* + ID_PRODUCT_FROM_DATABASE=AIO 810 + +usb:v413Cp5124* + ID_PRODUCT_FROM_DATABASE=Laser MFP 1815 + +usb:v413Cp5128* + ID_PRODUCT_FROM_DATABASE=Photo AIO 928 + +usb:v413Cp5200* + ID_PRODUCT_FROM_DATABASE=Laser Printer + +usb:v413Cp5202* + ID_PRODUCT_FROM_DATABASE=Printing Support + +usb:v413Cp5203* + ID_PRODUCT_FROM_DATABASE=Printing Support + +usb:v413Cp5210* + ID_PRODUCT_FROM_DATABASE=Printing Support + +usb:v413Cp5211* + ID_PRODUCT_FROM_DATABASE=1110 Laser Printer + +usb:v413Cp5220* + ID_PRODUCT_FROM_DATABASE=Laser MFP 1600n + +usb:v413Cp5225* + ID_PRODUCT_FROM_DATABASE=Printing Support + +usb:v413Cp5226* + ID_PRODUCT_FROM_DATABASE=Printing Support + +usb:v413Cp5300* + ID_PRODUCT_FROM_DATABASE=Laser Printer + +usb:v413Cp5400* + ID_PRODUCT_FROM_DATABASE=Laser Printer + +usb:v413Cp5401* + ID_PRODUCT_FROM_DATABASE=Laser Printer + +usb:v413Cp5513* + ID_PRODUCT_FROM_DATABASE=WLA3310 Wireless Adapter [Intersil ISL3887] + +usb:v413Cp5601* + ID_PRODUCT_FROM_DATABASE=Laser Printer 3100cn + +usb:v413Cp5602* + ID_PRODUCT_FROM_DATABASE=Laser Printer 3000cn + +usb:v413Cp5631* + ID_PRODUCT_FROM_DATABASE=Laser Printer 5100cn + +usb:v413Cp5905* + ID_PRODUCT_FROM_DATABASE=Printing Support + +usb:v413Cp8000* + ID_PRODUCT_FROM_DATABASE=BC02 Bluetooth Adapter + +usb:v413Cp8010* + ID_PRODUCT_FROM_DATABASE=TrueMobile Bluetooth Module in + +usb:v413Cp8100* + ID_PRODUCT_FROM_DATABASE=TrueMobile 1180 802.11b Adapter [Intersil PRISM 3] + +usb:v413Cp8102* + ID_PRODUCT_FROM_DATABASE=TrueMobile 1300 802.11g Wireless Adapter [Intersil ISL3880] + +usb:v413Cp8103* + ID_PRODUCT_FROM_DATABASE=Wireless 350 Bluetooth + +usb:v413Cp8104* + ID_PRODUCT_FROM_DATABASE=Wireless 1450 Dual-band (802.11a/b/g) Adapter [Intersil ISL3887] + +usb:v413Cp8105* + ID_PRODUCT_FROM_DATABASE=U2 in HID - Driver + +usb:v413Cp8106* + ID_PRODUCT_FROM_DATABASE=Wireless 350 Bluetooth Internal Card in + +usb:v413Cp8110* + ID_PRODUCT_FROM_DATABASE=Wireless 3xx Bluetooth Internal Card + +usb:v413Cp8111* + ID_PRODUCT_FROM_DATABASE=Wireless 3xx Bluetooth Internal Card in + +usb:v413Cp8114* + ID_PRODUCT_FROM_DATABASE=Wireless 5700 Mobile Broadband (CDMA EV-DO) Minicard Modem + +usb:v413Cp8115* + ID_PRODUCT_FROM_DATABASE=Wireless 5500 Mobile Broadband (3G HSDPA) Minicard Modem + +usb:v413Cp8116* + ID_PRODUCT_FROM_DATABASE=Wireless 5505 Mobile Broadband (3G HSDPA) Minicard Modem + +usb:v413Cp8117* + ID_PRODUCT_FROM_DATABASE=Wireless 5700 Mobile Broadband (CDMA EV-DO) Expresscard Modem + +usb:v413Cp8118* + ID_PRODUCT_FROM_DATABASE=Wireless 5510 Mobile Broadband (3G HSDPA) Expresscard Status Port + +usb:v413Cp8120* + ID_PRODUCT_FROM_DATABASE=Bluetooth adapter + +usb:v413Cp8121* + ID_PRODUCT_FROM_DATABASE=Eastfold in HID + +usb:v413Cp8122* + ID_PRODUCT_FROM_DATABASE=Eastfold in DFU + +usb:v413Cp8123* + ID_PRODUCT_FROM_DATABASE=eHome Infrared Receiver + +usb:v413Cp8124* + ID_PRODUCT_FROM_DATABASE=eHome Infrared Receiver + +usb:v413Cp8126* + ID_PRODUCT_FROM_DATABASE=Wireless 355 Bluetooth + +usb:v413Cp8127* + ID_PRODUCT_FROM_DATABASE=Wireless 355 Module with Bluetooth 2.0 + EDR Technology. + +usb:v413Cp8128* + ID_PRODUCT_FROM_DATABASE=Wireless 5700-Sprint Mobile Broadband (CDMA EV-DO) Mini-Card Status Port + +usb:v413Cp8129* + ID_PRODUCT_FROM_DATABASE=Wireless 5700-Telus Mobile Broadband (CDMA EV-DO) Mini-Card Status Port + +usb:v413Cp8131* + ID_PRODUCT_FROM_DATABASE=Wireless 360 Bluetooth 2.0 + EDR module. + +usb:v413Cp8133* + ID_PRODUCT_FROM_DATABASE=Wireless 5720 VZW Mobile Broadband (EVDO Rev-A) Minicard GPS Port + +usb:v413Cp8134* + ID_PRODUCT_FROM_DATABASE=Wireless 5720 Sprint Mobile Broadband (EVDO Rev-A) Minicard Status Port + +usb:v413Cp8135* + ID_PRODUCT_FROM_DATABASE=Wireless 5720 TELUS Mobile Broadband (EVDO Rev-A) Minicard Diagnostics Port + +usb:v413Cp8136* + ID_PRODUCT_FROM_DATABASE=Wireless 5520 Cingular Mobile Broadband (3G HSDPA) Minicard Diagnostics Port + +usb:v413Cp8137* + ID_PRODUCT_FROM_DATABASE=Wireless 5520 Voda L Mobile Broadband (3G HSDPA) Minicard Status Port + +usb:v413Cp8138* + ID_PRODUCT_FROM_DATABASE=Wireless 5520 Voda I Mobile Broadband (3G HSDPA) Minicard EAP-SIM Port + +usb:v413Cp8140* + ID_PRODUCT_FROM_DATABASE=Wireless 360 Bluetooth + +usb:v413Cp8142* + ID_PRODUCT_FROM_DATABASE=Mobile 360 in DFU + +usb:v413Cp8147* + ID_PRODUCT_FROM_DATABASE=F3507g Mobile Broadband Module + +usb:v413Cp8156* + ID_PRODUCT_FROM_DATABASE=Wireless 370 Bluetooth Mini-card + +usb:v413Cp8157* + ID_PRODUCT_FROM_DATABASE=Integrated Keyboard + +usb:v413Cp8158* + ID_PRODUCT_FROM_DATABASE=Integrated Touchpad / Trackstick + +usb:v413Cp8160* + ID_PRODUCT_FROM_DATABASE=Wireless 365 Bluetooth + +usb:v413Cp8161* + ID_PRODUCT_FROM_DATABASE=Integrated Keyboard + +usb:v413Cp8162* + ID_PRODUCT_FROM_DATABASE=Integrated Touchpad [Synaptics] + +usb:v413Cp8171* + ID_PRODUCT_FROM_DATABASE=Gobi Wireless Modem (QDL mode) + +usb:v413Cp8172* + ID_PRODUCT_FROM_DATABASE=Gobi Wireless Modem + +usb:v413Cp8183* + ID_PRODUCT_FROM_DATABASE=F3607gw Mobile Broadband Module + +usb:v413Cp8184* + ID_PRODUCT_FROM_DATABASE=F3607gw v2 Mobile Broadband Module + +usb:v413Cp8185* + ID_PRODUCT_FROM_DATABASE=Gobi 2000 Wireless Modem (QDL mode) + +usb:v413Cp8186* + ID_PRODUCT_FROM_DATABASE=Gobi 2000 Wireless Modem + +usb:v413Cp8187* + ID_PRODUCT_FROM_DATABASE=DW375 Bluetooth Module + +usb:v413Cp8501* + ID_PRODUCT_FROM_DATABASE=Bluetooth Adapter + +usb:v413Cp9500* + ID_PRODUCT_FROM_DATABASE=USB CP210x UART Bridge Controller [DW700] + +usb:v413CpA001* + ID_PRODUCT_FROM_DATABASE=Hub + +usb:v413CpA005* + ID_PRODUCT_FROM_DATABASE=Internal 2.0 Hub + +usb:v413CpA700* + ID_PRODUCT_FROM_DATABASE=Hub (in 1905FP LCD Monitor) + +usb:v4146* + ID_VENDOR_FROM_DATABASE=USBest Technology + +usb:v4146p9281* + ID_PRODUCT_FROM_DATABASE=Iomega Micro Mini 128MB Flash Drive + +usb:v4146pBA01* + ID_PRODUCT_FROM_DATABASE=Intuix Flash Drive + +usb:v4242* + ID_VENDOR_FROM_DATABASE=USB Design by Example + +usb:v4242p4201* + ID_PRODUCT_FROM_DATABASE=Buttons and Lights HID device + +usb:v4242p4220* + ID_PRODUCT_FROM_DATABASE=Echo 1 Camera + +usb:v4317* + ID_VENDOR_FROM_DATABASE=Broadcom Corp. + +usb:v4317p0700* + ID_PRODUCT_FROM_DATABASE=U.S. Robotics USR5426 802.11g Adapter + +usb:v4317p0701* + ID_PRODUCT_FROM_DATABASE=U.S. Robotics USR5425 Wireless MAXg Adapter + +usb:v4317p0711* + ID_PRODUCT_FROM_DATABASE=Belkin F5D7051 v3000 802.11g + +usb:v4317p0720* + ID_PRODUCT_FROM_DATABASE=Dynex DX-BUSB + +usb:v4348* + ID_VENDOR_FROM_DATABASE=WinChipHead + +usb:v4348p5523* + ID_PRODUCT_FROM_DATABASE=USB->RS 232 adapter with Prolifec PL 2303 chipset + +usb:v4348p5537* + ID_PRODUCT_FROM_DATABASE=13.56Mhz RFID Card Reader and Writer + +usb:v4348p5584* + ID_PRODUCT_FROM_DATABASE=CH34x printer adapter cable + +usb:v4572* + ID_VENDOR_FROM_DATABASE=Shuttle, Inc. + +usb:v4572p4572* + ID_PRODUCT_FROM_DATABASE=Shuttle PN31 Remote + +usb:v4586* + ID_VENDOR_FROM_DATABASE=Panram + +usb:v4586p1026* + ID_PRODUCT_FROM_DATABASE=Crystal Bar Flash Drive + +usb:v4670* + ID_VENDOR_FROM_DATABASE=EMS Production + +usb:v4670p9394* + ID_PRODUCT_FROM_DATABASE=Game Cube USB Memory Adaptor 64M + +usb:v4752* + ID_VENDOR_FROM_DATABASE=Miditech + +usb:v4752p0011* + ID_PRODUCT_FROM_DATABASE=Midistart-2 + +usb:v4757* + ID_VENDOR_FROM_DATABASE=GW Instek + +usb:v4757p2009* + ID_PRODUCT_FROM_DATABASE=PEL-2000 Series Electronic Load (CDC) + +usb:v4757p2010* + ID_PRODUCT_FROM_DATABASE=PEL-2000 Series Electronic Load (CDC) + +usb:v4766* + ID_VENDOR_FROM_DATABASE=Aceeca + +usb:v4766p0001* + ID_PRODUCT_FROM_DATABASE=MEZ1000 RDA + +usb:v4855* + ID_VENDOR_FROM_DATABASE=Memorex + +usb:v4855p7288* + ID_PRODUCT_FROM_DATABASE=Ultra Traveldrive 160G 2.5" HDD + +usb:v4971* + ID_VENDOR_FROM_DATABASE=SimpleTech + +usb:v4971pCB01* + ID_PRODUCT_FROM_DATABASE=SP-U25/120G + +usb:v4971pCE17* + ID_PRODUCT_FROM_DATABASE=1TB SimpleDrive II USB External Hard Drive + +usb:v4D46* + ID_VENDOR_FROM_DATABASE=Musical Fidelity + +usb:v4D46p0001* + ID_PRODUCT_FROM_DATABASE=V-Link + +usb:v4D46p0002* + ID_PRODUCT_FROM_DATABASE=V-DAC II + +usb:v5032* + ID_VENDOR_FROM_DATABASE=Grandtec + +usb:v5032p0BB8* + ID_PRODUCT_FROM_DATABASE=Grandtec USB1.1 DVB-T (cold) + +usb:v5032p0BB9* + ID_PRODUCT_FROM_DATABASE=Grandtec USB1.1 DVB-T (warm) + +usb:v5032p0FA0* + ID_PRODUCT_FROM_DATABASE=Grandtec USB1.1 DVB-T (cold) + +usb:v5032p0FA1* + ID_PRODUCT_FROM_DATABASE=Grandtec USB1.1 DVB-T (warm) + +usb:v5041* + ID_VENDOR_FROM_DATABASE=Linksys (?) + +usb:v5041p2234* + ID_PRODUCT_FROM_DATABASE=WUSB54G v1 802.11g Adapter [Intersil ISL3886] + +usb:v5041p2235* + ID_PRODUCT_FROM_DATABASE=WUSB54GP v1 802.11g Adapter [Intersil ISL3886] + +usb:v50C2* + ID_VENDOR_FROM_DATABASE=Averatec (?) + +usb:v50C2p4013* + ID_PRODUCT_FROM_DATABASE=WLAN Adapter + +usb:v5173* + ID_VENDOR_FROM_DATABASE=Sweex + +usb:v5173p1809* + ID_PRODUCT_FROM_DATABASE=ZD1211 + +usb:v5219* + ID_VENDOR_FROM_DATABASE=I-Tetra + +usb:v5219p1001* + ID_PRODUCT_FROM_DATABASE=Cetus CDC Device + +usb:v5345* + ID_VENDOR_FROM_DATABASE=Owon + +usb:v5345p1234* + ID_PRODUCT_FROM_DATABASE=PDS6062T Oscilloscope + +usb:v544D* + ID_VENDOR_FROM_DATABASE=Transmeta Corp. + +usb:v5543* + ID_VENDOR_FROM_DATABASE=UC-Logic Technology Corp. + +usb:v5543p0002* + ID_PRODUCT_FROM_DATABASE=SuperPen WP3325U Tablet + +usb:v5543p0003* + ID_PRODUCT_FROM_DATABASE=Tablet WP4030U + +usb:v5543p0004* + ID_PRODUCT_FROM_DATABASE=Tablet WP5540U + +usb:v5543p0005* + ID_PRODUCT_FROM_DATABASE=Tablet WP8060U + +usb:v5543p0041* + ID_PRODUCT_FROM_DATABASE=Genius PenSketch 6x8 Tablet + +usb:v5543p0042* + ID_PRODUCT_FROM_DATABASE=Tablet PF1209 + +usb:v5543p0064* + ID_PRODUCT_FROM_DATABASE=Aiptek HyperPen 10000U + +usb:v5555* + ID_VENDOR_FROM_DATABASE=Epiphan Systems Inc. + +usb:v5555p1110* + ID_PRODUCT_FROM_DATABASE=VGA2USB + +usb:v5555p1120* + ID_PRODUCT_FROM_DATABASE=KVM2USB + +usb:v5555p2222* + ID_PRODUCT_FROM_DATABASE=DVI2USB + +usb:v5555p3333* + ID_PRODUCT_FROM_DATABASE=VGA2USB Pro + +usb:v5555p3337* + ID_PRODUCT_FROM_DATABASE=KVM2USB Pro + +usb:v5555p3340* + ID_PRODUCT_FROM_DATABASE=VGA2USB LR + +usb:v5555p3344* + ID_PRODUCT_FROM_DATABASE=KVM2USB LR + +usb:v5555p3411* + ID_PRODUCT_FROM_DATABASE=DVI2USB Solo + +usb:v5555p3422* + ID_PRODUCT_FROM_DATABASE=DVI2USB Duo + +usb:v55AA* + ID_VENDOR_FROM_DATABASE=OnSpec Electronic, Inc. + +usb:v55AAp0015* + ID_PRODUCT_FROM_DATABASE=Hard Drive + +usb:v55AAp0102* + ID_PRODUCT_FROM_DATABASE=SuperDisk + +usb:v55AAp0103* + ID_PRODUCT_FROM_DATABASE=IDE Hard Drive + +usb:v55AAp0201* + ID_PRODUCT_FROM_DATABASE=DDI to Reader-19 + +usb:v55AAp1234* + ID_PRODUCT_FROM_DATABASE=ATAPI Bridge + +usb:v55AApA103* + ID_PRODUCT_FROM_DATABASE=Sandisk SDDR-55 SmartMedia Card Reader + +usb:v55AApB000* + ID_PRODUCT_FROM_DATABASE=USB to CompactFlash Card Reader + +usb:v55AApB004* + ID_PRODUCT_FROM_DATABASE=OnSpec MMC/SD Reader/Writer + +usb:v55AApB00B* + ID_PRODUCT_FROM_DATABASE=USB to Memory Stick Card Reader + +usb:v55AApB00C* + ID_PRODUCT_FROM_DATABASE=USB to SmartMedia Card Reader + +usb:v55AApB012* + ID_PRODUCT_FROM_DATABASE=Mitsumi FA402M 8-in-2 Card Reader + +usb:v55AApB200* + ID_PRODUCT_FROM_DATABASE=Compact Flash Reader + +usb:v55AApB204* + ID_PRODUCT_FROM_DATABASE=MMC/ SD Reader + +usb:v55AApB207* + ID_PRODUCT_FROM_DATABASE=Memory Stick Reader + +usb:v5656* + ID_VENDOR_FROM_DATABASE=Uni-Trend Group Limited + +usb:v5656p0832* + ID_PRODUCT_FROM_DATABASE=UT2000/UT3000 Digital Storage Oscilloscope + +usb:v595A* + ID_VENDOR_FROM_DATABASE=IRTOUCHSYSTEMS Co. Ltd. + +usb:v595Ap0001* + ID_PRODUCT_FROM_DATABASE=Touchscreen + +usb:v5986* + ID_VENDOR_FROM_DATABASE=Acer, Inc + +usb:v5986p0100* + ID_PRODUCT_FROM_DATABASE=Orbicam + +usb:v5986p0101* + ID_PRODUCT_FROM_DATABASE=USB2.0 Camera + +usb:v5986p0102* + ID_PRODUCT_FROM_DATABASE=Crystal Eye Webcam + +usb:v5986p01A6* + ID_PRODUCT_FROM_DATABASE=Lenovo Integrated Webcam + +usb:v5986p01A7* + ID_PRODUCT_FROM_DATABASE=Lenovo Integrated Webcam + +usb:v5986p01A9* + ID_PRODUCT_FROM_DATABASE=Lenovo Integrated Webcam + +usb:v5986p0200* + ID_PRODUCT_FROM_DATABASE=OrbiCam + +usb:v5986p0203* + ID_PRODUCT_FROM_DATABASE=BisonCam NB Pro 1300 + +usb:v5986p0241* + ID_PRODUCT_FROM_DATABASE=BisonCam, NB Pro + +usb:v5986p02D0* + ID_PRODUCT_FROM_DATABASE=Lenovo Integrated Webcam [R5U877] + +usb:v5986p03D0* + ID_PRODUCT_FROM_DATABASE=Lenovo Integrated Webcam [R5U877] + +usb:v5A57* + ID_VENDOR_FROM_DATABASE=Zinwell + +usb:v5A57p0260* + ID_PRODUCT_FROM_DATABASE=RT2570 + +usb:v5A57p0280* + ID_PRODUCT_FROM_DATABASE=802.11a/b/g/n USB Wireless LAN Card + +usb:v5A57p0282* + ID_PRODUCT_FROM_DATABASE=802.11b/g/n USB Wireless LAN Card + +usb:v5A57p0283* + ID_PRODUCT_FROM_DATABASE=802.11b/g/n USB Wireless LAN Card + +usb:v5A57p0284* + ID_PRODUCT_FROM_DATABASE=802.11a/b/g/n USB Wireless LAN Card + +usb:v5A57p0290* + ID_PRODUCT_FROM_DATABASE=ZW-N290 802.11n [Realtek RTL8192SU] + +usb:v5A57p5257* + ID_PRODUCT_FROM_DATABASE=Metronic 495257 wifi 802.11ng + +usb:v6000* + ID_VENDOR_FROM_DATABASE=Beholder International Ltd. + +usb:v6000pDEC0* + ID_PRODUCT_FROM_DATABASE=TV Wander + +usb:v6000pDEC1* + ID_PRODUCT_FROM_DATABASE=TV Voyage + +usb:v601A* + ID_VENDOR_FROM_DATABASE=Ingenic Semiconductor Ltd. + +usb:v601Ap4740* + ID_PRODUCT_FROM_DATABASE=XBurst Jz4740 boot mode + +usb:v6189* + ID_VENDOR_FROM_DATABASE=Sitecom + +usb:v6189p182D* + ID_PRODUCT_FROM_DATABASE=USB 2.0 Ethernet + +usb:v6189p2068* + ID_PRODUCT_FROM_DATABASE=USB to serial cable (v2) + +usb:v6253* + ID_VENDOR_FROM_DATABASE=TwinHan Technology Co., Ltd + +usb:v6253p0100* + ID_PRODUCT_FROM_DATABASE=Ir reciver f. remote control + +usb:v636C* + ID_VENDOR_FROM_DATABASE=CoreLogic, Inc. + +usb:v6472* + ID_VENDOR_FROM_DATABASE=Unknown (Sony?) + +usb:v6472p01C8* + ID_PRODUCT_FROM_DATABASE=PlayStation Portable [Mass Storage] + +usb:v6547* + ID_VENDOR_FROM_DATABASE=Arkmicro Technologies Inc. + +usb:v6547p0232* + ID_PRODUCT_FROM_DATABASE=ARK3116 Serial + +usb:v6615* + ID_VENDOR_FROM_DATABASE=IRTOUCHSYSTEMS Co. Ltd. + +usb:v6615p0001* + ID_PRODUCT_FROM_DATABASE=Touchscreen + +usb:v6666* + ID_VENDOR_FROM_DATABASE=Prototype product Vendor ID + +usb:v6666p0667* + ID_PRODUCT_FROM_DATABASE=WiseGroup Smart Joy PSX, PS-PC Smart JoyPad + +usb:v6666p2667* + ID_PRODUCT_FROM_DATABASE=JCOP BlueZ Smartcard reader + +usb:v6666p8802* + ID_PRODUCT_FROM_DATABASE=SmartJoy Dual Plus PS2 converter + +usb:v6666p8804* + ID_PRODUCT_FROM_DATABASE=WiseGroup SuperJoy Box 5 + +usb:v6677* + ID_VENDOR_FROM_DATABASE=WiseGroup, Ltd. + +usb:v6677p8802* + ID_PRODUCT_FROM_DATABASE=SmartJoy Dual Plus PS2 converter + +usb:v6677p8811* + ID_PRODUCT_FROM_DATABASE=Deluxe Dance Mat + +usb:v6891* + ID_VENDOR_FROM_DATABASE=3Com + +usb:v6891pA727* + ID_PRODUCT_FROM_DATABASE=3CRUSB10075 802.11bg [ZyDAS ZD1211] + +usb:v695C* + ID_VENDOR_FROM_DATABASE=Opera1 + +usb:v695Cp3829* + ID_PRODUCT_FROM_DATABASE=Opera1 DVB-S (warm state) + +usb:v6993* + ID_VENDOR_FROM_DATABASE=Yealink Network Technology Co., Ltd. + +usb:v6993pB001* + ID_PRODUCT_FROM_DATABASE=VoIP Phone + +usb:v6A75* + ID_VENDOR_FROM_DATABASE=Shanghai Jujo Electronics Co., Ltd + +usb:v7104* + ID_VENDOR_FROM_DATABASE=CME (Central Music Co.) + +usb:v7104p2202* + ID_PRODUCT_FROM_DATABASE=UF5/UF6/UF7/UF8 MIDI Master Keyboard + +usb:v726C* + ID_VENDOR_FROM_DATABASE=StackFoundry LLC + +usb:v726Cp2149* + ID_PRODUCT_FROM_DATABASE=EntropyKing Random Number Generator + +usb:v734C* + ID_VENDOR_FROM_DATABASE=TBS Technologies China + +usb:v734Cp5920* + ID_PRODUCT_FROM_DATABASE=Q-Box II DVB-S2 HD + +usb:v734Cp5928* + ID_PRODUCT_FROM_DATABASE=Q-Box II DVB-S2 HD + +usb:v7392* + ID_VENDOR_FROM_DATABASE=Edimax Technology Co., Ltd + +usb:v7392p7711* + ID_PRODUCT_FROM_DATABASE=EW-7711UTn nLite Wireless Adapter [Ralink RT2870] + +usb:v7392p7717* + ID_PRODUCT_FROM_DATABASE=EW-7717UN 802.11n Wireless Adapter [Ralink RT2870] + +usb:v7392p7718* + ID_PRODUCT_FROM_DATABASE=EW-7718UN 802.11n Wireless Adapter [Ralink RT2870] + +usb:v7392p7722* + ID_PRODUCT_FROM_DATABASE=EW-7722UTn 802.11n Wireless Adapter [Ralink RT307x] + +usb:v7392p7811* + ID_PRODUCT_FROM_DATABASE=EW-7811Un 802.11n Wireless Adapter [Realtek RTL8188CUS] + +usb:v8086* + ID_VENDOR_FROM_DATABASE=Intel Corp. + +usb:v8086p0001* + ID_PRODUCT_FROM_DATABASE=AnyPoint (TM) Home Network 1.6 Mbps Wireless Adapter + +usb:v8086p0044* + ID_PRODUCT_FROM_DATABASE=CPU DRAM Controller + +usb:v8086p0046* + ID_PRODUCT_FROM_DATABASE=HD Graphics + +usb:v8086p0100* + ID_PRODUCT_FROM_DATABASE=Personal Audio Player 3000 + +usb:v8086p0101* + ID_PRODUCT_FROM_DATABASE=Personal Audio Player 3000 + +usb:v8086p0110* + ID_PRODUCT_FROM_DATABASE=Easy PC Camera + +usb:v8086p0120* + ID_PRODUCT_FROM_DATABASE=PC Camera CS120 + +usb:v8086p0180* + ID_PRODUCT_FROM_DATABASE=WiMAX Connection 2400m + +usb:v8086p0181* + ID_PRODUCT_FROM_DATABASE=WiMAX Connection 2400m + +usb:v8086p0182* + ID_PRODUCT_FROM_DATABASE=WiMAX Connection 2400m + +usb:v8086p0186* + ID_PRODUCT_FROM_DATABASE=WiMAX Connection 2400m + +usb:v8086p0188* + ID_PRODUCT_FROM_DATABASE=WiMAX Connection 2400m + +usb:v8086p0200* + ID_PRODUCT_FROM_DATABASE=AnyPoint(TM) Wireless II Network 11Mbps Adapter [Atmel AT76C503A] + +usb:v8086p0431* + ID_PRODUCT_FROM_DATABASE=Intel Pro Video PC Camera + +usb:v8086p0510* + ID_PRODUCT_FROM_DATABASE=Digital Movie Creator + +usb:v8086p0630* + ID_PRODUCT_FROM_DATABASE=Pocket PC Camera + +usb:v8086p0780* + ID_PRODUCT_FROM_DATABASE=CS780 Microphone Input + +usb:v8086p07D3* + ID_PRODUCT_FROM_DATABASE=BLOB boot loader firmware + +usb:v8086p0DAD* + ID_PRODUCT_FROM_DATABASE=Cherry MiniatureCard Keyboard + +usb:v8086p1010* + ID_PRODUCT_FROM_DATABASE=AnyPoint(TM) Home Network 10 Mbps Phoneline Adapter + +usb:v8086p110A* + ID_PRODUCT_FROM_DATABASE=Bluetooth Controller from (Ericsson P4A) + +usb:v8086p110B* + ID_PRODUCT_FROM_DATABASE=Bluetooth Controller from (Intel/CSR) + +usb:v8086p1110* + ID_PRODUCT_FROM_DATABASE=PRO/Wireless LAN Module + +usb:v8086p1111* + ID_PRODUCT_FROM_DATABASE=PRO/Wireless 2011B 802.11b Adapter [Intersil PRISM 2.5] + +usb:v8086p1134* + ID_PRODUCT_FROM_DATABASE=Hollister Mobile Monitor + +usb:v8086p1139* + ID_PRODUCT_FROM_DATABASE=In-Target Probe (ITP) + +usb:v8086p1234* + ID_PRODUCT_FROM_DATABASE=Prototype Reader/Writer + +usb:v8086p1403* + ID_PRODUCT_FROM_DATABASE=WiMAX Connection 2400m + +usb:v8086p1405* + ID_PRODUCT_FROM_DATABASE=WiMAX Connection 2400m + +usb:v8086p1406* + ID_PRODUCT_FROM_DATABASE=WiMAX Connection 2400m + +usb:v8086p2448* + ID_PRODUCT_FROM_DATABASE=82801 PCI Bridge + +usb:v8086p3100* + ID_PRODUCT_FROM_DATABASE=PRO/DSL 3220 Modem - WAN + +usb:v8086p3101* + ID_PRODUCT_FROM_DATABASE=PRO/DSL 3220 Modem + +usb:v8086p3240* + ID_PRODUCT_FROM_DATABASE=AnyPoint® 3240 Modem - WAN + +usb:v8086p3241* + ID_PRODUCT_FROM_DATABASE=AnyPoint® 3240 Modem + +usb:v8086p8602* + ID_PRODUCT_FROM_DATABASE=Miniature Card Slot + +usb:v8086p9303* + ID_PRODUCT_FROM_DATABASE=Intel 8x930Hx Hub + +usb:v8086p9500* + ID_PRODUCT_FROM_DATABASE=CE 9500 DVB-T + +usb:v8086p9890* + ID_PRODUCT_FROM_DATABASE=82930 Test Board + +usb:v8086pBEEF* + ID_PRODUCT_FROM_DATABASE=SCM Miniature Card Reader/Writer + +usb:v8086pC013* + ID_PRODUCT_FROM_DATABASE=Wireless HID Station + +usb:v8086pF001* + ID_PRODUCT_FROM_DATABASE=XScale PXA27x Bulverde flash + +usb:v8086pF1A5* + ID_PRODUCT_FROM_DATABASE=Z-U130 [Value Solid State Drive] + +usb:v8087* + ID_VENDOR_FROM_DATABASE=Intel Corp. + +usb:v8087p0020* + ID_PRODUCT_FROM_DATABASE=Integrated Rate Matching Hub + +usb:v8087p0024* + ID_PRODUCT_FROM_DATABASE=Integrated Rate Matching Hub + +usb:v80EE* + ID_VENDOR_FROM_DATABASE=VirtualBox + +usb:v80EEp0021* + ID_PRODUCT_FROM_DATABASE=USB Tablet + +usb:v8282* + ID_VENDOR_FROM_DATABASE=Keio + +usb:v8282p3201* + ID_PRODUCT_FROM_DATABASE=Retro Adapter + +usb:v8282p3301* + ID_PRODUCT_FROM_DATABASE=Retro Adapter Mouse + +usb:v8341* + ID_VENDOR_FROM_DATABASE=EGO Systems, Inc. + +usb:v8341p2000* + ID_PRODUCT_FROM_DATABASE=Flashdisk + +usb:v9016* + ID_VENDOR_FROM_DATABASE=Sitecom + +usb:v9016p182D* + ID_PRODUCT_FROM_DATABASE=WL-022 802.11b Adapter + +usb:v9022* + ID_VENDOR_FROM_DATABASE=TeVii Technology Ltd. + +usb:v9022pD630* + ID_PRODUCT_FROM_DATABASE=DVB-S S630 + +usb:v9022pD650* + ID_PRODUCT_FROM_DATABASE=DVB-S2 S650 + +usb:v9022pD660* + ID_PRODUCT_FROM_DATABASE=DVB-S2 S660 + +usb:v9148* + ID_VENDOR_FROM_DATABASE=GeoLab, Ltd + +usb:v9148p0004* + ID_PRODUCT_FROM_DATABASE=R3 Compatible Device + +usb:v9710* + ID_VENDOR_FROM_DATABASE=MosChip Semiconductor + +usb:v9710p7703* + ID_PRODUCT_FROM_DATABASE=MCS7703 Serial Port Adapter + +usb:v9710p7705* + ID_PRODUCT_FROM_DATABASE=MCS7705 Parallel port adapter + +usb:v9710p7715* + ID_PRODUCT_FROM_DATABASE=MCS7715 Parallel and serial port adapter + +usb:v9710p7717* + ID_PRODUCT_FROM_DATABASE=MCS7717 3-port hub with serial and parallel adapter + +usb:v9710p7720* + ID_PRODUCT_FROM_DATABASE=MCS7720 Dual serial port adapter + +usb:v9710p7730* + ID_PRODUCT_FROM_DATABASE=MCS7730 10/100 Mbps Ethernet adapter + +usb:v9710p7780* + ID_PRODUCT_FROM_DATABASE=MCS7780 4Mbps Fast IrDA Adapter + +usb:v9710p7830* + ID_PRODUCT_FROM_DATABASE=MCS7830 10/100 Mbps Ethernet adapter + +usb:v9710p7832* + ID_PRODUCT_FROM_DATABASE=MCS7832 10/100 Mbps Ethernet adapter + +usb:v9710p7840* + ID_PRODUCT_FROM_DATABASE=MCS7820/MCS7840 2/4 port serial adapter + +usb:v99FA* + ID_VENDOR_FROM_DATABASE=Grandtec + +usb:v99FAp8988* + ID_PRODUCT_FROM_DATABASE=V.cap Camera Device + +usb:v9AC4* + ID_VENDOR_FROM_DATABASE=J. Westhues + +usb:v9AC4p4B8F* + ID_PRODUCT_FROM_DATABASE=ProxMark-3 RFID Instrument + +usb:vA128* + ID_VENDOR_FROM_DATABASE=AnMo Electronics Corp. / Dino-Lite (?) + +usb:vA128p0610* + ID_PRODUCT_FROM_DATABASE=Dino-Lite Digital Microscope (SN9C201 + HV7131R) + +usb:vA128p0611* + ID_PRODUCT_FROM_DATABASE=Dino-Lite Digital Microscope (SN9C201 + HV7131R) + +usb:vA128p0612* + ID_PRODUCT_FROM_DATABASE=Dino-Lite Digital Microscope (SN9C120 + HV7131R) + +usb:vA128p0613* + ID_PRODUCT_FROM_DATABASE=Dino-Lite Digital Microscope (SN9C201 + HV7131R) + +usb:vA128p0614* + ID_PRODUCT_FROM_DATABASE=Dino-Lite Digital Microscope (SN9C201 + MI1310/MT9M111) + +usb:vA128p0615* + ID_PRODUCT_FROM_DATABASE=Dino-Lite Digital Microscope (SN9C201 + MI1310/MT9M111) + +usb:vA128p0616* + ID_PRODUCT_FROM_DATABASE=Dino-Lite Digital Microscope (SN9C120 + HV7131R) + +usb:vA128p0617* + ID_PRODUCT_FROM_DATABASE=Dino-Lite Digital Microscope (SN9C201 + MI1310/MT9M111) + +usb:vA128p0618* + ID_PRODUCT_FROM_DATABASE=Dino-Lite Digital Microscope (SN9C201 + HV7131R) + +usb:vA168* + ID_VENDOR_FROM_DATABASE=AnMo Electronics Corporation + +usb:vA168p0610* + ID_PRODUCT_FROM_DATABASE=Dino-Lite Digital Microscope + +usb:vA168p0611* + ID_PRODUCT_FROM_DATABASE=Dino-Lite Digital Microscope + +usb:vA168p0613* + ID_PRODUCT_FROM_DATABASE=Dino-Lite Digital Microscope + +usb:vA168p0614* + ID_PRODUCT_FROM_DATABASE=Dino-Lite Pro Digital Microscope + +usb:vA168p0615* + ID_PRODUCT_FROM_DATABASE=Dino-Lite Pro Digital Microscope + +usb:vA168p0617* + ID_PRODUCT_FROM_DATABASE=Dino-Lite Pro Digital Microscope + +usb:vA168p0618* + ID_PRODUCT_FROM_DATABASE=Dino-Lite Digital Microscope + +usb:vA600* + ID_VENDOR_FROM_DATABASE=Asix + +usb:vA600pE110* + ID_PRODUCT_FROM_DATABASE=OK1ZIA Davac 4.x + +usb:vA727* + ID_VENDOR_FROM_DATABASE=3Com + +usb:vA727p6893* + ID_PRODUCT_FROM_DATABASE=3CRUSB20075 OfficeConnect Wireless 108Mbps 11g Adapter [Atheros AR5523] + +usb:vA727p6895* + ID_PRODUCT_FROM_DATABASE=AR5523 + +usb:vA727p6897* + ID_PRODUCT_FROM_DATABASE=AR5523 + +usb:vABCD* + ID_VENDOR_FROM_DATABASE=Unknown + +usb:vABCDpCDEE* + ID_PRODUCT_FROM_DATABASE=Petcam + +usb:vC251* + ID_VENDOR_FROM_DATABASE=Keil Software, Inc. + +usb:vC251p2710* + ID_PRODUCT_FROM_DATABASE=ULink + +usb:vCACE* + ID_VENDOR_FROM_DATABASE=CACE Technologies Inc. + +usb:vCACEp0002* + ID_PRODUCT_FROM_DATABASE=AirPCAP Classic 802.11 packet capture adapter + +usb:vCACEp0300* + ID_PRODUCT_FROM_DATABASE=AirPcap NX [Atheros AR9001U-(2)NG] + +usb:vD209* + ID_VENDOR_FROM_DATABASE=Ultimarc + +usb:vD209p0301* + ID_PRODUCT_FROM_DATABASE=I-PAC Arcade Control Interface + +usb:vD209p0501* + ID_PRODUCT_FROM_DATABASE=Ultra-Stik Ultimarc Ultra-Stik Player 1 + +usb:vE4E4* + ID_VENDOR_FROM_DATABASE=Xorcom Ltd. + +usb:vE4E4p1130* + ID_PRODUCT_FROM_DATABASE=Astribank series + +usb:vE4E4p1131* + ID_PRODUCT_FROM_DATABASE=Astribank series + +usb:vE4E4p1132* + ID_PRODUCT_FROM_DATABASE=Astribank series + +usb:vE4E4p1140* + ID_PRODUCT_FROM_DATABASE=Astribank series + +usb:vE4E4p1141* + ID_PRODUCT_FROM_DATABASE=Astribank series + +usb:vE4E4p1142* + ID_PRODUCT_FROM_DATABASE=Astribank series + +usb:vE4E4p1150* + ID_PRODUCT_FROM_DATABASE=Astribank series + +usb:vE4E4p1151* + ID_PRODUCT_FROM_DATABASE=Astribank series + +usb:vE4E4p1152* + ID_PRODUCT_FROM_DATABASE=Astribank series + +usb:vE4E4p1160* + ID_PRODUCT_FROM_DATABASE=Astribank 2 series + +usb:vE4E4p1161* + ID_PRODUCT_FROM_DATABASE=Astribank 2 series + +usb:vE4E4p1162* + ID_PRODUCT_FROM_DATABASE=Astribank 2 series + +usb:vEB03* + ID_VENDOR_FROM_DATABASE=MakingThings + +usb:vEB03p0920* + ID_PRODUCT_FROM_DATABASE=Make Controller Kit + +usb:vEB1A* + ID_VENDOR_FROM_DATABASE=eMPIA Technology, Inc. + +usb:vEB1Ap17DE* + ID_PRODUCT_FROM_DATABASE=KWorld V-Stream XPERT DTV - DVB-T USB cold + +usb:vEB1Ap17DF* + ID_PRODUCT_FROM_DATABASE=KWorld V-Stream XPERT DTV - DVB-T USB warm + +usb:vEB1Ap2571* + ID_PRODUCT_FROM_DATABASE=M035 Compact Web Cam + +usb:vEB1Ap2710* + ID_PRODUCT_FROM_DATABASE=SilverCrest Webcam + +usb:vEB1Ap2750* + ID_PRODUCT_FROM_DATABASE=ECS Elitegroup G220 integrated Webcam + +usb:vEB1Ap2761* + ID_PRODUCT_FROM_DATABASE=EeePC 701 integrated Webcam + +usb:vEB1Ap2776* + ID_PRODUCT_FROM_DATABASE=Combined audio and video input device + +usb:vEB1Ap2800* + ID_PRODUCT_FROM_DATABASE=Terratec Cinergy 200 + +usb:vEB1Ap2801* + ID_PRODUCT_FROM_DATABASE=GrabBeeX+ Video Encoder + +usb:vEB1Ap2863* + ID_PRODUCT_FROM_DATABASE=Video Grabber + +usb:vEB1Ap2870* + ID_PRODUCT_FROM_DATABASE=Pinnacle PCTV Stick + +usb:vEB1Ap2881* + ID_PRODUCT_FROM_DATABASE=EM2881 Video Controller + +usb:vEB1Ap50A3* + ID_PRODUCT_FROM_DATABASE=Gadmei UTV380 TV Box + +usb:vEB1Ap50A6* + ID_PRODUCT_FROM_DATABASE=Gadmei UTV330 TV Box + +usb:vEB1ApE355* + ID_PRODUCT_FROM_DATABASE=KWorld DVB-T 355U Digital TV Dongle + +usb:vEB2A* + ID_VENDOR_FROM_DATABASE=KWorld + +usb:vF003* + ID_VENDOR_FROM_DATABASE=Hewlett Packard + +usb:vF003p6002* + ID_PRODUCT_FROM_DATABASE=PhotoSmart C500 + +usb:vF4EC* + ID_VENDOR_FROM_DATABASE=Atten Electronics / Siglent Technologies + +usb:vF4ECpEE38* + ID_PRODUCT_FROM_DATABASE=Digital Storage Oscilloscope diff --git a/hwdb/ids-update.pl b/hwdb/ids-update.pl new file mode 100755 index 000000000..13596b85c --- /dev/null +++ b/hwdb/ids-update.pl @@ -0,0 +1,268 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +sub usb_vendor { + my $vendor; + + open(IN, "<", "usb.ids"); + open(OUT, ">", "20-usb-vendor-product.hwdb"); + print(OUT "# This file is part of systemd.\n" . + "#\n" . + "# Data imported from: http://www.linux-usb.org/usb.ids\n"); + + while (my $line = ) { + $line =~ s/\s+$//; + $line =~ m/^([0-9a-f]{4})\s*(.+)$/; + if (defined $1) { + $vendor = uc $1; + my $text = $2; + print(OUT "\n"); + print(OUT "usb:v" . $vendor . "*\n"); + print(OUT " ID_VENDOR_FROM_DATABASE=" . $text . "\n"); + next; + } + + $line =~ m/^\t([0-9a-f]{4})\s*(.+)$/; + if (defined $1) { + my $product = uc $1; + my $text = $2; + print(OUT "\n"); + print(OUT "usb:v" . $vendor . "p" . $product . "*\n"); + print(OUT " ID_PRODUCT_FROM_DATABASE=" . $text . "\n"); + } + } + + close(IN); + close(OUT); +} + +sub usb_classes { + my $class; + my $subclass; + my $protocol; + + open(IN, "<", "usb.ids"); + open(OUT, ">", "20-usb-classes.hwdb"); + print(OUT "# This file is part of systemd.\n" . + "#\n" . + "# Data imported from: http://www.linux-usb.org/usb.ids\n"); + + while (my $line = ) { + $line =~ s/\s+$//; + + $line =~ m/^C\ ([0-9a-f]{2})\s*(.+)$/; + if (defined $1) { + $class = uc $1; + if ($class =~ m/^00$/) { + next; + } + my $text = $2; + print(OUT "\n"); + print(OUT "usb:v*p*d*dc" . $class . "*\n"); + print(OUT " ID_USB_CLASS_FROM_DATABASE=" . $text . "\n"); + next; + } + + if (not defined $class) { + next; + } elsif ($line =~ m/^$/) { + last; + } + + $line =~ m/^\t([0-9a-f]{2})\s*(.+)$/; + if (defined $1) { + $subclass = uc $1; + if ($subclass =~ m/^00$/) { + next; + } + my $text = $2; + if ($text =~ m/^(\?|None|Unused)$/) { + next; + } + print(OUT "\n"); + print(OUT "usb:v*p*d*dc" . $class . "dsc" . $subclass . "*\n"); + print(OUT " ID_USB_SUBCLASS_FROM_DATABASE=" . $text . "\n"); + next; + } + + $line =~ m/^\t\t([0-9a-f]{2})\s*(.+)$/; + if (defined $1) { + $protocol = uc $1; + my $text = $2; + if ($text =~ m/^(\?|None|Unused)$/) { + next; + } + print(OUT "\n"); + print(OUT "usb:v*p*d*dc" . $class . "dsc" . $subclass . "dp" . $protocol . "*\n"); + print(OUT " ID_USB_PROTOCOL_FROM_DATABASE=" . $text . "\n"); + } + } + + close(IN); + close(OUT); +} + +sub pci_vendor { + my $vendor; + my $device; + + open(IN, "<", "pci.ids"); + open(OUT, ">", "20-pci-vendor-product.hwdb"); + print(OUT "# This file is part of systemd.\n" . + "#\n" . + "# Data imported from: http://pci-ids.ucw.cz/v2.2/pci.ids\n"); + + while (my $line = ) { + $line =~ s/\s+$//; + $line =~ m/^([0-9a-f]{4})\s*(.+)$/; + + if (defined $1) { + $vendor = uc $1; + my $text = $2; + print(OUT "\n"); + print(OUT "pci:v0000" . $vendor . "*\n"); + print(OUT " ID_VENDOR_FROM_DATABASE=" . $text . "\n"); + next; + } + + $line =~ m/^\t([0-9a-f]{4})\s*(.+)$/; + if (defined $1) { + $device = uc $1; + my $text = $2; + print(OUT "\n"); + print(OUT "pci:v0000" . $vendor . "d0000" . $device . "*\n"); + print(OUT " ID_PRODUCT_FROM_DATABASE=" . $text . "\n"); + next; + } + + $line =~ m/^\t\t([0-9a-f]{4})\s*([0-9a-f]{4})\s*(.*)$/; + if (defined $1) { + my $sub_vendor = uc $1; + my $sub_device = uc $2; + my $text = $3; + print(OUT "\n"); + print(OUT "pci:v0000" . $vendor . "d0000" . $device . "sv0000" . $sub_vendor . "sd0000" . $sub_device . "*\n"); + print(OUT " ID_PRODUCT_FROM_DATABASE=" . $text . "\n"); + } + } + + close(IN); + close(OUT); +} + +sub pci_classes { + my $class; + my $subclass; + my $interface; + + open(IN, "<", "pci.ids"); + open(OUT, ">", "20-pci-classes.hwdb"); + print(OUT "# This file is part of systemd.\n" . + "#\n" . + "# Data imported from: http://pci-ids.ucw.cz/v2.2/pci.ids\n"); + + while (my $line = ) { + $line =~ s/\s+$//; + + $line =~ m/^C\ ([0-9a-f]{2})\s*(.+)$/; + if (defined $1) { + $class = uc $1; + my $text = $2; + print(OUT "\n"); + print(OUT "pci:v*d*sv*sd*bc" . $class . "*\n"); + print(OUT " ID_PCI_CLASS_FROM_DATABASE=" . $text . "\n"); + next; + } + + if (not defined $class) { + next; + } elsif ($line =~ m/^$/) { + last; + } + + $line =~ m/^\t([0-9a-f]{2})\s*(.+)$/; + if (defined $1) { + $subclass = uc $1; + my $text = $2; + print(OUT "\n"); + print(OUT "pci:v*d*sv*sd*bc" . $class . "sc" . $subclass . "*\n"); + print(OUT " ID_PCI_SUBCLASS_FROM_DATABASE=" . $text . "\n"); + next; + } + + $line =~ m/^\t\t([0-9a-f]{2})\s*(.+)$/; + if (defined $1) { + $interface = uc $1; + my $text = $2; + print(OUT "\n"); + print(OUT "pci:v*d*sv*sd*bc" . $class . "sc" . $subclass . "i" . $interface . "*\n"); + print(OUT " ID_PCI_INTERFACE_FROM_DATABASE=" . $text . "\n"); + } + } + + close(IN); + close(OUT); +} + +sub oui { + my $iab_prefix; + my %iab_prefixes = (); + + open(OUT, ">", "20-OUI.hwdb"); + print(OUT "# This file is part of systemd.\n" . + "#\n" . + "# Data imported from:\n" . + "# http://standards.ieee.org/develop/regauth/oui/oui.txt\n" . + "# http://standards.ieee.org/develop/regauth/iab/iab.txt\n"); + + open(IN, "<", "iab.txt"); + while (my $line = ) { + $line =~ s/\s+$//; + $line =~ m/^([0-9A-F]{2})-([0-9A-F]{2})-([0-9A-F]{2})\s*\(hex\)\s*.+$/; + if (defined $1) { + $iab_prefix = $1 . $2 . $3; + $iab_prefixes{ $iab_prefix } = 1; + next; + } + + $line =~ m/^([0-9A-F]{3})000-\g1FFF\s*\(base 16\)\s*(.+)$/; + if (defined $1) { + my $vendor = uc $1; + my $text = $2; + + print(OUT "\n"); + print(OUT "OUI:" . $iab_prefix . $vendor . "*\n"); + print(OUT " ID_OUI_FROM_DATABASE=" . $text . "\n"); + } + } + close(IN); + + open(IN, "<", "oui.txt"); + while (my $line = ) { + $line =~ s/\s+$//; + $line =~ m/^([0-9A-F]{6})\s*\(base 16\)\s*(.+)$/; + if (defined $1) { + my $vendor = uc $1; + my $text = $2; + + # skip the IAB prefixes + if (! exists $iab_prefixes{ $vendor }) { + print(OUT "\n"); + print(OUT "OUI:" . $vendor . "*\n"); + print(OUT " ID_OUI_FROM_DATABASE=" . $text . "\n"); + } + } + } + close(IN); + close(OUT); +} + +usb_vendor(); +usb_classes(); + +pci_vendor(); +pci_classes(); + +oui(); diff --git a/introspect.awk b/introspect.awk new file mode 100644 index 000000000..593191384 --- /dev/null +++ b/introspect.awk @@ -0,0 +1,13 @@ +BEGIN { + print "" + print "" +} + +// { + print +} + +END { + print "" +} diff --git a/keymaps-force-release/common-volume-keys b/keymaps-force-release/common-volume-keys new file mode 100644 index 000000000..3a7654d73 --- /dev/null +++ b/keymaps-force-release/common-volume-keys @@ -0,0 +1,3 @@ +0xa0 #mute +0xae #volume down +0xb0 #volume up diff --git a/keymaps-force-release/dell-touchpad b/keymaps-force-release/dell-touchpad new file mode 100644 index 000000000..18e9bdee6 --- /dev/null +++ b/keymaps-force-release/dell-touchpad @@ -0,0 +1 @@ +0x9E diff --git a/keymaps-force-release/dell-xps b/keymaps-force-release/dell-xps new file mode 100644 index 000000000..69f7899ad --- /dev/null +++ b/keymaps-force-release/dell-xps @@ -0,0 +1 @@ +0x8C diff --git a/keymaps-force-release/hp-other b/keymaps-force-release/hp-other new file mode 100644 index 000000000..662137009 --- /dev/null +++ b/keymaps-force-release/hp-other @@ -0,0 +1,3 @@ +# list of scancodes (hex or decimal), optional comment +0xd8 # Touchpad off +0xd9 # Touchpad on diff --git a/keymaps-force-release/samsung-other b/keymaps-force-release/samsung-other new file mode 100644 index 000000000..c51123a0b --- /dev/null +++ b/keymaps-force-release/samsung-other @@ -0,0 +1,10 @@ +# list of scancodes (hex or decimal), optional comment +0x82 # Fn+F4 CRT/LCD +0x83 # Fn+F2 battery +0x84 # Fn+F5 backlight on/off +0x86 # Fn+F9 WLAN +0x88 # Fn-Up brightness up +0x89 # Fn-Down brightness down +0xB3 # Fn+F8 switch power mode (battery/dynamic/performance) +0xF7 # Fn+F10 Touchpad on +0xF9 # Fn+F10 Touchpad off diff --git a/keymaps-force-release/samsung-series-9 b/keymaps-force-release/samsung-series-9 new file mode 100644 index 000000000..65707effb --- /dev/null +++ b/keymaps-force-release/samsung-series-9 @@ -0,0 +1,6 @@ +# list of scancodes (hex or decimal), optional comment +0xCE # Fn+F8 keyboard backlit up +0x8D # Fn+F7 keyboard backlit down +0x97 # Fn+F12 wifi on/off +0x96 # Fn+F1 performance mode (?) +0xD5 # Fn+F6 battery life extender diff --git a/keymaps/acer b/keymaps/acer new file mode 100644 index 000000000..4e7c297de --- /dev/null +++ b/keymaps/acer @@ -0,0 +1,22 @@ +0xA5 help # Fn+F1 +0xA6 setup # Fn+F2 Acer eSettings +0xA7 battery # Fn+F3 Power Management +0xA9 switchvideomode # Fn+F5 +0xB3 euro +0xB4 dollar +0xCE brightnessup # Fn+Right +0xD4 bluetooth # (toggle) off-to-on +0xD5 wlan # (toggle) on-to-off +0xD6 wlan # (toggle) off-to-on +0xD7 bluetooth # (toggle) on-to-off +0xD8 bluetooth # (toggle) off-to-on +0xD9 brightnessup # Fn+Right +0xEE brightnessup # Fn+Right +0xEF brightnessdown # Fn+Left +0xF1 f22 # Fn+F7 Touchpad toggle (off-to-on) +0xF2 f23 # Fn+F7 Touchpad toggle (on-to-off) +0xF3 prog2 # "P2" programmable button +0xF4 prog1 # "P1" programmable button +0xF5 presentation +0xF8 fn +0xF9 f23 # Launch NTI shadow diff --git a/keymaps/acer-aspire_5720 b/keymaps/acer-aspire_5720 new file mode 100644 index 000000000..3ff9de3f3 --- /dev/null +++ b/keymaps/acer-aspire_5720 @@ -0,0 +1,5 @@ +0x84 bluetooth # sent when bluetooth module missing, and key pressed +0x92 media # acer arcade +0xD4 bluetooth # bluetooth on +0xD9 bluetooth # bluetooth off +0xF4 prog3 # e-key diff --git a/keymaps/acer-aspire_5920g b/keymaps/acer-aspire_5920g new file mode 100644 index 000000000..633c4e854 --- /dev/null +++ b/keymaps/acer-aspire_5920g @@ -0,0 +1,5 @@ +0x8A media +0x92 media +0xA6 setup +0xB2 www +0xD9 bluetooth # (toggle) on-to-off diff --git a/keymaps/acer-aspire_6920 b/keymaps/acer-aspire_6920 new file mode 100644 index 000000000..699c954b4 --- /dev/null +++ b/keymaps/acer-aspire_6920 @@ -0,0 +1,5 @@ +0xD9 bluetooth # (toggle) on-to-off +0x92 media +0x9E back +0x83 rewind +0x89 fastforward diff --git a/keymaps/acer-aspire_8930 b/keymaps/acer-aspire_8930 new file mode 100644 index 000000000..fb27bfb4f --- /dev/null +++ b/keymaps/acer-aspire_8930 @@ -0,0 +1,5 @@ +0xCA prog3 # key 'HOLD' on cine dash media console +0x83 rewind +0x89 fastforward +0x92 media # key 'ARCADE' on cine dash media console +0x9E back diff --git a/keymaps/acer-travelmate_c300 b/keymaps/acer-travelmate_c300 new file mode 100644 index 000000000..bfef4cf86 --- /dev/null +++ b/keymaps/acer-travelmate_c300 @@ -0,0 +1,5 @@ +0x67 f24 # FIXME: rotate screen +0x68 up +0x69 down +0x6B fn +0x6C screenlock # FIXME: lock tablet device/buttons diff --git a/keymaps/asus b/keymaps/asus new file mode 100644 index 000000000..2a5995f98 --- /dev/null +++ b/keymaps/asus @@ -0,0 +1,3 @@ +0xED volumeup +0xEE volumedown +0xEF mute diff --git a/keymaps/compaq-e_evo b/keymaps/compaq-e_evo new file mode 100644 index 000000000..5fbc573aa --- /dev/null +++ b/keymaps/compaq-e_evo @@ -0,0 +1,4 @@ +0xA3 www # I key +0x9A search +0x9E email +0x9F homepage diff --git a/keymaps/dell b/keymaps/dell new file mode 100644 index 000000000..4f907b3ee --- /dev/null +++ b/keymaps/dell @@ -0,0 +1,29 @@ +0x81 playpause # Play/Pause +0x82 stopcd # Stop +0x83 previoussong # Previous song +0x84 nextsong # Next song +0x85 brightnessdown # Fn+Down arrow Brightness Down +0x86 brightnessup # Fn+Up arrow Brightness Up +0x87 battery # Fn+F3 battery icon +0x88 unknown # Fn+F2 Turn On/Off Wireless - handled in hardware +0x89 ejectclosecd # Fn+F10 Eject CD +0x8A suspend # Fn+F1 hibernate +0x8B switchvideomode # Fn+F8 CRT/LCD (high keycode: "displaytoggle") +0x8C f23 # Fn+Right arrow Auto Brightness +0x8F switchvideomode # Fn+F7 aspect ratio +0x90 previoussong # Front panel previous song +0x91 prog1 # Wifi Catcher (DELL Specific) +0x92 media # MediaDirect button (house icon) +0x93 f23 # FIXME Fn+Left arrow Auto Brightness +0x95 camera # Shutter button Takes a picture if optional camera available +0x97 email # Tablet email button +0x98 f21 # FIXME: Tablet screen rotatation +0x99 nextsong # Front panel next song +0x9A setup # Tablet tools button +0x9B switchvideomode # Display Toggle button +0x9E f21 #touchpad toggle +0xA2 playpause # Front panel play/pause +0xA4 stopcd # Front panel stop +0xED media # MediaDirect button +0xD8 screenlock # FIXME: Tablet lock button +0xD9 f21 # touchpad toggle diff --git a/keymaps/dell-latitude-xt2 b/keymaps/dell-latitude-xt2 new file mode 100644 index 000000000..39872f559 --- /dev/null +++ b/keymaps/dell-latitude-xt2 @@ -0,0 +1,4 @@ +0x9B up # tablet rocker up +0x9E enter # tablet rocker press +0x9F back # tablet back +0xA3 down # tablet rocker down diff --git a/keymaps/everex-xt5000 b/keymaps/everex-xt5000 new file mode 100644 index 000000000..4823a832f --- /dev/null +++ b/keymaps/everex-xt5000 @@ -0,0 +1,7 @@ +0x5C media +0x65 f21 # Fn+F5 Touchpad toggle +0x67 prog3 # Fan Speed Control button +0x6F brightnessup +0x7F brightnessdown +0xB2 www +0xEC mail diff --git a/keymaps/fujitsu-amilo_li_2732 b/keymaps/fujitsu-amilo_li_2732 new file mode 100644 index 000000000..9b8b36a17 --- /dev/null +++ b/keymaps/fujitsu-amilo_li_2732 @@ -0,0 +1,3 @@ +0xD9 brightnessdown # Fn+F8 brightness down +0xEF brightnessup # Fn+F9 brightness up +0xA9 switchvideomode # Fn+F10 Cycle between available video outputs diff --git a/keymaps/fujitsu-amilo_pa_2548 b/keymaps/fujitsu-amilo_pa_2548 new file mode 100644 index 000000000..f7b0c5244 --- /dev/null +++ b/keymaps/fujitsu-amilo_pa_2548 @@ -0,0 +1,3 @@ +0xE0 volumedown +0xE1 volumeup +0xE5 prog1 diff --git a/keymaps/fujitsu-amilo_pro_edition_v3505 b/keymaps/fujitsu-amilo_pro_edition_v3505 new file mode 100644 index 000000000..d2e38cbb2 --- /dev/null +++ b/keymaps/fujitsu-amilo_pro_edition_v3505 @@ -0,0 +1,4 @@ +0xA5 help # Fn-F1 +0xA9 switchvideomode # Fn-F3 +0xD9 brightnessdown # Fn-F8 +0xE0 brightnessup # Fn-F9 diff --git a/keymaps/fujitsu-amilo_pro_v3205 b/keymaps/fujitsu-amilo_pro_v3205 new file mode 100644 index 000000000..43e3199d5 --- /dev/null +++ b/keymaps/fujitsu-amilo_pro_v3205 @@ -0,0 +1,2 @@ +0xF4 f21 # FIXME: silent-mode decrease CPU/GPU clock +0xF7 switchvideomode # Fn+F3 diff --git a/keymaps/fujitsu-amilo_si_1520 b/keymaps/fujitsu-amilo_si_1520 new file mode 100644 index 000000000..1419bd9b5 --- /dev/null +++ b/keymaps/fujitsu-amilo_si_1520 @@ -0,0 +1,6 @@ +0xE1 wlan +0xF3 wlan +0xEE brightnessdown +0xE0 brightnessup +0xE2 bluetooth +0xF7 video diff --git a/keymaps/fujitsu-esprimo_mobile_v5 b/keymaps/fujitsu-esprimo_mobile_v5 new file mode 100644 index 000000000..d3d056b36 --- /dev/null +++ b/keymaps/fujitsu-esprimo_mobile_v5 @@ -0,0 +1,4 @@ +0xA9 switchvideomode +0xD9 brightnessdown +0xDF sleep +0xEF brightnessup diff --git a/keymaps/fujitsu-esprimo_mobile_v6 b/keymaps/fujitsu-esprimo_mobile_v6 new file mode 100644 index 000000000..52c70c50c --- /dev/null +++ b/keymaps/fujitsu-esprimo_mobile_v6 @@ -0,0 +1,2 @@ +0xCE brightnessup +0xEF brightnessdown diff --git a/keymaps/genius-slimstar-320 b/keymaps/genius-slimstar-320 new file mode 100644 index 000000000..d0a3656dd --- /dev/null +++ b/keymaps/genius-slimstar-320 @@ -0,0 +1,35 @@ +# Genius SlimStar 320 +# +# Only buttons which are not properly mapped yet are configured below + +# "Scroll wheel", a circular up/down/left/right button. Aimed for scolling, +# but since there are no scrollleft/scrollright, let's map to back/forward. +0x900f0 scrollup +0x900f1 scrolldown +0x900f3 back +0x900f2 forward + +# Multimedia buttons, left side (from left to right) +# [W] +0x900f5 wordprocessor +# [Ex] +0x900f6 spreadsheet +# [P] +0x900f4 presentation +# Other five (calculator, playpause, stop, mute and eject) are OK + +# Right side, from left to right +# [e] +0xc0223 www +# "man" +0x900f7 chat +# "Y" +0x900fb prog1 +# [X] +0x900f8 close +# "picture" +0x900f9 graphicseditor +# "two windows" +0x900fd scale +# "lock" +0x900fc screenlock diff --git a/keymaps/hewlett-packard b/keymaps/hewlett-packard new file mode 100644 index 000000000..4461fa2ce --- /dev/null +++ b/keymaps/hewlett-packard @@ -0,0 +1,12 @@ +0x81 fn_esc +0x89 battery # FnF8 +0x8A screenlock # FnF6 +0x8B camera +0x8C media # music +0x8E dvd +0xB1 help +0xB3 f23 # FIXME: Auto brightness +0xD7 wlan +0x92 brightnessdown # FnF7 (FnF9 on 6730b) +0x97 brightnessup # FnF8 (FnF10 on 6730b) +0xEE switchvideomode # FnF4 diff --git a/keymaps/hewlett-packard-2510p_2530p b/keymaps/hewlett-packard-2510p_2530p new file mode 100644 index 000000000..41ad2e9b5 --- /dev/null +++ b/keymaps/hewlett-packard-2510p_2530p @@ -0,0 +1,2 @@ +0xD8 f23 # touchpad off +0xD9 f22 # touchpad on diff --git a/keymaps/hewlett-packard-compaq_elitebook b/keymaps/hewlett-packard-compaq_elitebook new file mode 100644 index 000000000..42007c548 --- /dev/null +++ b/keymaps/hewlett-packard-compaq_elitebook @@ -0,0 +1,2 @@ +0x88 presentation +0xD9 help # I key (high keycode: "info") diff --git a/keymaps/hewlett-packard-pavilion b/keymaps/hewlett-packard-pavilion new file mode 100644 index 000000000..3d3cefc8e --- /dev/null +++ b/keymaps/hewlett-packard-pavilion @@ -0,0 +1,3 @@ +0x88 media # FIXME: quick play +0xD8 f23 # touchpad off +0xD9 f22 # touchpad on diff --git a/keymaps/hewlett-packard-presario-2100 b/keymaps/hewlett-packard-presario-2100 new file mode 100644 index 000000000..1df39dcbd --- /dev/null +++ b/keymaps/hewlett-packard-presario-2100 @@ -0,0 +1,3 @@ +0xF0 help +0xF1 screenlock +0xF3 search diff --git a/keymaps/hewlett-packard-tablet b/keymaps/hewlett-packard-tablet new file mode 100644 index 000000000..d19005ab9 --- /dev/null +++ b/keymaps/hewlett-packard-tablet @@ -0,0 +1,6 @@ +0x82 prog2 # Funny Key +0x83 prog1 # Q +0x84 tab +0x85 esc +0x86 pageup +0x87 pagedown diff --git a/keymaps/hewlett-packard-tx2 b/keymaps/hewlett-packard-tx2 new file mode 100644 index 000000000..36a690fcf --- /dev/null +++ b/keymaps/hewlett-packard-tx2 @@ -0,0 +1,3 @@ +0xC2 media +0xD8 f23 # Toggle touchpad button on tx2 (OFF) +0xD9 f22 # Toggle touchpad button on tx2 (ON) diff --git a/keymaps/hewlett-packard_elitebook-8440p b/keymaps/hewlett-packard_elitebook-8440p new file mode 100644 index 000000000..e0c2a1a85 --- /dev/null +++ b/keymaps/hewlett-packard_elitebook-8440p @@ -0,0 +1,5 @@ +0x88 www +0xA0 mute +0xAE volumedown +0xB0 volumeup +0xEC mail diff --git a/keymaps/ibm-thinkpad-usb-keyboard-trackpoint b/keymaps/ibm-thinkpad-usb-keyboard-trackpoint new file mode 100644 index 000000000..027e50bf8 --- /dev/null +++ b/keymaps/ibm-thinkpad-usb-keyboard-trackpoint @@ -0,0 +1,7 @@ +0x900f0 screenlock +0x900f1 wlan +0x900f2 switchvideomode +0x900f3 suspend +0x900f4 brightnessup +0x900f5 brightnessdown +0x900f8 zoom diff --git a/keymaps/inventec-symphony_6.0_7.0 b/keymaps/inventec-symphony_6.0_7.0 new file mode 100644 index 000000000..4a8b4ba5a --- /dev/null +++ b/keymaps/inventec-symphony_6.0_7.0 @@ -0,0 +1,2 @@ +0xF3 prog2 +0xF4 prog1 diff --git a/keymaps/lenovo-3000 b/keymaps/lenovo-3000 new file mode 100644 index 000000000..5bd165654 --- /dev/null +++ b/keymaps/lenovo-3000 @@ -0,0 +1,5 @@ +0x8B switchvideomode # Fn+F7 video +0x96 wlan # Fn+F5 wireless +0x97 sleep # Fn+F4 suspend +0x98 suspend # Fn+F12 hibernate +0xB4 prog1 # Lenovo Care diff --git a/keymaps/lenovo-ideapad b/keymaps/lenovo-ideapad new file mode 100644 index 000000000..fc339839f --- /dev/null +++ b/keymaps/lenovo-ideapad @@ -0,0 +1,8 @@ +# Key codes observed on S10-3, assumed valid on other IdeaPad models +0x81 rfkill # does nothing in BIOS +0x83 display_off # BIOS toggles screen state +0xB9 brightnessup # does nothing in BIOS +0xBA brightnessdown # does nothing in BIOS +0xF1 camera # BIOS toggles camera power +0xf2 f21 # touchpad toggle (key alternately emits f2 and f3) +0xf3 f21 diff --git a/keymaps/lenovo-thinkpad-usb-keyboard-trackpoint b/keymaps/lenovo-thinkpad-usb-keyboard-trackpoint new file mode 100644 index 000000000..47e8846a6 --- /dev/null +++ b/keymaps/lenovo-thinkpad-usb-keyboard-trackpoint @@ -0,0 +1,13 @@ +0x90012 screenlock # Fn+F2 +0x90013 battery # Fn+F3 +0x90014 wlan # Fn+F5 +0x90016 switchvideomode # Fn+F7 +0x90017 f21 # Fn+F8 touchpadtoggle +0x90019 suspend # Fn+F12 +0x9001A brightnessup # Fn+Home +0x9001B brightnessdown # Fn+End +0x9001D zoom # Fn+Space +0x90011 prog1 # Thinkvantage button + +0x90015 camera # Fn+F6 headset/camera VoIP key ?? +0x90010 micmute # Microphone mute button diff --git a/keymaps/lenovo-thinkpad_x200_tablet b/keymaps/lenovo-thinkpad_x200_tablet new file mode 100644 index 000000000..31ea3b2c7 --- /dev/null +++ b/keymaps/lenovo-thinkpad_x200_tablet @@ -0,0 +1,6 @@ +0x5D menu +0x63 fn +0x66 screenlock +0x67 cyclewindows # bezel circular arrow +0x68 setup # bezel setup / menu +0x6c direction # rotate screen diff --git a/keymaps/lenovo-thinkpad_x6_tablet b/keymaps/lenovo-thinkpad_x6_tablet new file mode 100644 index 000000000..6fd16b566 --- /dev/null +++ b/keymaps/lenovo-thinkpad_x6_tablet @@ -0,0 +1,8 @@ +0x6C f21 # rotate +0x68 screenlock # screenlock +0x6B esc # escape +0x6D right # right on d-pad +0x6E left # left on d-pad +0x71 up # up on d-pad +0x6F down # down on d-pad +0x69 enter # enter on d-pad diff --git a/keymaps/lg-x110 b/keymaps/lg-x110 new file mode 100644 index 000000000..ba08cba3f --- /dev/null +++ b/keymaps/lg-x110 @@ -0,0 +1,12 @@ +0xA0 mute # Fn-F9 +0xAE volumedown # Fn-Left +0xAF search # Fn-F3 +0xB0 volumeup # Fn-Right +0xB1 battery # Fn-F10 Info +0xB3 suspend # Fn-F12 +0xDF sleep # Fn-F4 +# 0xE2 bluetooth # satellite dish2 +0xE4 f21 # Fn-F5 Touchpad disable +0xF6 wlan # Fn-F6 +0xF7 reserved # brightnessdown # Fn-Down +0xF8 reserved # brightnessup # Fn-Up diff --git a/keymaps/logitech-wave b/keymaps/logitech-wave new file mode 100644 index 000000000..caa5d5d31 --- /dev/null +++ b/keymaps/logitech-wave @@ -0,0 +1,16 @@ +0x9001C scale #expo +0x9001F zoomout #zoom out +0x90020 zoomin #zoom in +0x9003D prog1 #gadget +0x90005 camera #camera +0x90018 media #media center +0x90041 wordprocessor #fn+f1 (word) +0x90042 spreadsheet #fn+f2 (excel) +0x90043 calendar #fn+f3 (calendar) +0x90044 prog2 #fn+f4 (program a) +0x90045 prog3 #fn+f5 (program b) +0x90046 prog4 #fn+f6 (program c) +0x90048 messenger #fn+f8 (msn messenger) +0x9002D find #fn+f10 (search www) +0x9004B search #fn+f11 (search pc) +0x9004C ejectclosecd #fn+f12 (eject) diff --git a/keymaps/logitech-wave-cordless b/keymaps/logitech-wave-cordless new file mode 100644 index 000000000..a10dad5e4 --- /dev/null +++ b/keymaps/logitech-wave-cordless @@ -0,0 +1,15 @@ +0xD4 zoomin +0xCC zoomout +0xC0183 media +0xC1005 camera +0xC101F zoomout +0xC1020 zoomin +0xC1041 wordprocessor +0xC1042 spreadsheet +0xC1043 calendar +0xC1044 prog2 #fn+f4 (program a) +0xC1045 prog3 #fn+f5 (program b) +0xC1046 prog4 #fn+f6 (program c) +0xC1048 messenger +0xC104A find #fn+f10 (search www) +0xC104C ejectclosecd diff --git a/keymaps/logitech-wave-pro-cordless b/keymaps/logitech-wave-pro-cordless new file mode 100644 index 000000000..e7aa02206 --- /dev/null +++ b/keymaps/logitech-wave-pro-cordless @@ -0,0 +1,12 @@ +0xC01B6 camera +0xC0183 media +0xC0184 wordprocessor +0xC0186 spreadsheet +0xC018E calendar +0xC0223 homepage +0xC01BC messenger +0xC018A mail +0xC0221 search +0xC00B8 ejectcd +0xC022D zoomin +0xC022E zoomout diff --git a/keymaps/maxdata-pro_7000 b/keymaps/maxdata-pro_7000 new file mode 100644 index 000000000..c0e4f77af --- /dev/null +++ b/keymaps/maxdata-pro_7000 @@ -0,0 +1,9 @@ +0x97 prog2 +0x9F prog1 +0xA0 mute # Fn-F5 +0x82 www +0xEC email +0xAE volumedown # Fn-Down +0xB0 volumeup # Fn-Up +0xDF suspend # Fn+F2 +0xF5 help diff --git a/keymaps/medion-fid2060 b/keymaps/medion-fid2060 new file mode 100644 index 000000000..5a76c7679 --- /dev/null +++ b/keymaps/medion-fid2060 @@ -0,0 +1,2 @@ +0x6B channeldown # Thottle Down +0x6D channelup # Thottle Up diff --git a/keymaps/medionnb-a555 b/keymaps/medionnb-a555 new file mode 100644 index 000000000..c3b5dfa60 --- /dev/null +++ b/keymaps/medionnb-a555 @@ -0,0 +1,4 @@ +0x63 www # N button +0x66 prog1 # link 1 button +0x67 email # envelope button +0x69 prog2 # link 2 button diff --git a/keymaps/micro-star b/keymaps/micro-star new file mode 100644 index 000000000..4a438698e --- /dev/null +++ b/keymaps/micro-star @@ -0,0 +1,13 @@ +0xA0 mute # Fn-F9 +0xAE volumedown # Fn-F7 +0xB0 volumeup # Fn-F8 +0xB2 www # e button +0xDF sleep # Fn-F12 +0xE2 bluetooth # satellite dish2 +0xE4 f21 # Fn-F3 Touchpad disable +0xEC email # envelope button +0xEE camera # Fn-F6 camera disable +0xF6 wlan # satellite dish1 +0xF7 brightnessdown # Fn-F4 +0xF8 brightnessup # Fn-F5 +0xF9 search diff --git a/keymaps/module-asus-w3j b/keymaps/module-asus-w3j new file mode 100644 index 000000000..773e0b3e8 --- /dev/null +++ b/keymaps/module-asus-w3j @@ -0,0 +1,11 @@ +0x41 nextsong +0x45 playpause +0x43 stopcd +0x40 previoussong +0x4C ejectclosecd +0x32 mute +0x31 volumedown +0x30 volumeup +0x5D wlan +0x7E bluetooth +0x8A media # high keycode: "tv" diff --git a/keymaps/module-ibm b/keymaps/module-ibm new file mode 100644 index 000000000..a92dfa250 --- /dev/null +++ b/keymaps/module-ibm @@ -0,0 +1,16 @@ +0x01 battery # Fn+F2 +0x02 screenlock # Fn+F3 +0x03 sleep # Fn+F4 +0x04 wlan # Fn+F5 +0x06 switchvideomode # Fn+F7 +0x07 zoom # Fn+F8 screen expand +0x08 f24 # Fn+F9 undock +0x0B suspend # Fn+F12 +0x0F brightnessup # Fn+Home +0x10 brightnessdown # Fn+End +0x11 kbdillumtoggle # Fn+PgUp - ThinkLight +0x13 zoom # Fn+Space +0x14 volumeup +0x15 volumedown +0x16 mute +0x17 prog1 # ThinkPad/ThinkVantage button (high keycode: "vendor") diff --git a/keymaps/module-lenovo b/keymaps/module-lenovo new file mode 100644 index 000000000..8e3888309 --- /dev/null +++ b/keymaps/module-lenovo @@ -0,0 +1,17 @@ +0x1 screenlock # Fn+F2 +0x2 battery # Fn+F3 +0x3 sleep # Fn+F4 +0x4 wlan # Fn+F5 +0x6 switchvideomode # Fn+F7 +0x7 f21 # Fn+F8 touchpadtoggle +0x8 f24 # Fn+F9 undock +0xB suspend # Fn+F12 +0xF brightnessup # Fn+Home +0x10 brightnessdown # Fn+End +0x11 kbdillumtoggle # Fn+PgUp - ThinkLight +0x13 zoom # Fn+Space +0x14 volumeup +0x15 volumedown +0x16 mute +0x17 prog1 # ThinkPad/ThinkVantage button (high keycode: "vendor") +0x1A micmute # Microphone mute diff --git a/keymaps/module-sony b/keymaps/module-sony new file mode 100644 index 000000000..7c000131d --- /dev/null +++ b/keymaps/module-sony @@ -0,0 +1,8 @@ +0x06 mute # Fn+F2 +0x07 volumedown # Fn+F3 +0x08 volumeup # Fn+F4 +0x09 brightnessdown # Fn+F5 +0x0A brightnessup # Fn+F6 +0x0B switchvideomode # Fn+F7 +0x0E zoom # Fn+F10 +0x10 suspend # Fn+F12 diff --git a/keymaps/module-sony-old b/keymaps/module-sony-old new file mode 100644 index 000000000..596a34258 --- /dev/null +++ b/keymaps/module-sony-old @@ -0,0 +1,2 @@ +0x06 battery +0x07 mute diff --git a/keymaps/module-sony-vgn b/keymaps/module-sony-vgn new file mode 100644 index 000000000..c8ba00151 --- /dev/null +++ b/keymaps/module-sony-vgn @@ -0,0 +1,8 @@ +0x00 brightnessdown # Fn+F5 +0x10 brightnessup # Fn+F6 +0x11 switchvideomode # Fn+F7 +0x12 zoomout +0x14 zoomin +0x15 suspend # Fn+F12 +0x17 prog1 +0x20 media diff --git a/keymaps/module-sony-vpc b/keymaps/module-sony-vpc new file mode 100644 index 000000000..681082c59 --- /dev/null +++ b/keymaps/module-sony-vpc @@ -0,0 +1,4 @@ +# 0x05 touchpad_toggle # fn_f1 -> KEY_TOUCHPAD_TOGGLE +0x05 f21 # fn_f1 -> KEY_F21 (The actual touchpad toggle) +0x0d zoomout # fn_f9 +0x0e zoomin # fn_f10 diff --git a/keymaps/olpc-xo b/keymaps/olpc-xo new file mode 100644 index 000000000..34434a121 --- /dev/null +++ b/keymaps/olpc-xo @@ -0,0 +1,74 @@ +0x59 fn +0x81 fn_esc +0xF9 camera +0xF8 sound # Fn-CAMERA = Mic + + +# Function key mappings, as per +# http://dev.laptop.org/ticket/10213#comment:20 +# +# Unmodified F1-F8 produce F1-F8, so no remap necessary. +# Unmodified F9-F12 control brightness and volume. +0x43 brightnessdown +0x44 brightnessup +0x57 volumedown +0x58 volumeup + +# fn-modified fkeys all produce the unmodified version of the key. +0xBB f1 +0xBC f2 +0xBD f3 +0xBE f4 +0xBF f5 +0xC0 f6 +0xC1 f7 +0xC2 f8 +0xC3 f9 +0xC4 f10 +0xD7 f11 +0xD8 f12 + + +# Using F13-F21 for the .5 F keys right now. +0xF7 f13 +0xF6 f14 +0xF5 f15 +0xF4 f16 +0xF3 f17 +0xF2 f18 +0xF1 f19 +0xF0 f20 +0xEF f21 + +0xEE chat +0xE4 chat # Just mapping Fn-Chat to Chat for now +0xDD menu # Frame +0xDA prog1 # Fn-Frame + +# The FN of some keys is other keys +0xD3 delete +0xD2 insert +0xC9 pageup +0xD1 pagedown +0xC7 home +0xCF end + +# Language key - don't ask what they are doing as KEY_HP +0x73 hp +0x7E hp + +0xDB leftmeta # left grab +0xDC rightmeta # right grab +0x85 rightmeta # Right grab releases on a different scancode +0xD6 kbdillumtoggle # Fn-space +0x69 switchvideomode # Brightness key + +# Game keys +0x65 kp8 # up +0x66 kp2 # down +0x67 kp4 # left +0x68 kp6 # right +0xE5 kp9 # pgup +0xE6 kp3 # pgdn +0xE7 kp7 # home +0xE8 kp1 # end diff --git a/keymaps/onkyo b/keymaps/onkyo new file mode 100644 index 000000000..ee864ade4 --- /dev/null +++ b/keymaps/onkyo @@ -0,0 +1,14 @@ +0xA0 mute # Fn+D +0xAE volumedown # Fn+F +0xB0 volumeup # Fn+G +0xDF sleep # Fn+W +0xE0 bluetooth # Fn+H +0xE2 cyclewindows # Fn+Esc +0xEE battery # Fn+Q +0xF0 media # Fn+R +0xF5 switchvideomode # Fn+E +0xF6 camera # Fn+T +0xF7 f21 # Fn+Y (touchpad toggle) +0xF8 brightnessup # Fn+S +0xF9 brightnessdown # Fn+A +0xFB wlan # Fn+J diff --git a/keymaps/oqo-model2 b/keymaps/oqo-model2 new file mode 100644 index 000000000..b7f4851ab --- /dev/null +++ b/keymaps/oqo-model2 @@ -0,0 +1,5 @@ +0x8E wlan +0xF0 switchvideomode +0xF1 mute +0xF2 volumedown +0xF3 volumeup diff --git a/keymaps/samsung-other b/keymaps/samsung-other new file mode 100644 index 000000000..3ac0c2f10 --- /dev/null +++ b/keymaps/samsung-other @@ -0,0 +1,14 @@ +0x74 prog1 # User key +0x75 www +0x78 mail +0x82 switchvideomode # Fn+F4 CRT/LCD (high keycode: "displaytoggle") +0x83 battery # Fn+F2 +0x84 prog1 # Fn+F5 backlight on/off +0x86 wlan # Fn+F9 +0x88 brightnessup # Fn-Up +0x89 brightnessdown # Fn-Down +0xB1 prog2 # Fn+F7 run Samsung Magic Doctor (keypressed event is generated twice) +0xB3 prog3 # Fn+F8 switch power mode (battery/dynamic/performance) +0xB4 wlan # Fn+F9 (X60P) +0xF7 f22 # Fn+F10 Touchpad on +0xF9 f23 # Fn+F10 Touchpad off diff --git a/keymaps/samsung-series-9 b/keymaps/samsung-series-9 new file mode 100644 index 000000000..3b65735fa --- /dev/null +++ b/keymaps/samsung-series-9 @@ -0,0 +1,5 @@ +0x96 kbdillumup # Fn+F8 keyboard backlit up +0x97 kbdillumdown # Fn+F7 keyboard backlit down +0xD5 wlan # Fn+F12 wifi on/off +0xCE prog1 # Fn+F1 performance mode +0x8D prog2 # Fn+F6 battery life extender diff --git a/keymaps/samsung-sq1us b/keymaps/samsung-sq1us new file mode 100644 index 000000000..ea2141ef8 --- /dev/null +++ b/keymaps/samsung-sq1us @@ -0,0 +1,7 @@ +0xD4 menu +0xD8 f1 +0xD9 f10 +0xD6 f3 +0xD7 f9 +0xE4 f5 +0xEE f11 diff --git a/keymaps/samsung-sx20s b/keymaps/samsung-sx20s new file mode 100644 index 000000000..9d954ee41 --- /dev/null +++ b/keymaps/samsung-sx20s @@ -0,0 +1,4 @@ +0x74 mute +0x75 mute +0x77 f22 # Touchpad on +0x79 f23 # Touchpad off diff --git a/keymaps/toshiba-satellite_a100 b/keymaps/toshiba-satellite_a100 new file mode 100644 index 000000000..22007be71 --- /dev/null +++ b/keymaps/toshiba-satellite_a100 @@ -0,0 +1,2 @@ +0xA4 stopcd +0xB2 www diff --git a/keymaps/toshiba-satellite_a110 b/keymaps/toshiba-satellite_a110 new file mode 100644 index 000000000..142940935 --- /dev/null +++ b/keymaps/toshiba-satellite_a110 @@ -0,0 +1,10 @@ +0x92 stop +0x93 www +0x94 media +0x9E f22 # Touchpad on +0x9F f23 # Touchpad off +0xB9 nextsong +0xD9 brightnessup +0xEE screenlock +0xF4 previoussong +0xF7 playpause diff --git a/keymaps/toshiba-satellite_m30x b/keymaps/toshiba-satellite_m30x new file mode 100644 index 000000000..ae8e34941 --- /dev/null +++ b/keymaps/toshiba-satellite_m30x @@ -0,0 +1,6 @@ +0xef brightnessdown +0xd9 brightnessup +0xee screenlock +0x93 media +0x9e f22 #touchpad_enable +0x9f f23 #touchpad_disable diff --git a/keymaps/zepto-znote b/keymaps/zepto-znote new file mode 100644 index 000000000..cf72fda47 --- /dev/null +++ b/keymaps/zepto-znote @@ -0,0 +1,11 @@ +0x93 switchvideomode # Fn+F3 Toggle Video Output +0x95 brightnessdown # Fn+F4 Brightness Down +0x91 brightnessup # Fn+F5 Brightness Up +0xA5 f23 # Fn+F6 Disable Touchpad +0xA6 f22 # Fn+F6 Enable Touchpad +0xA7 bluetooth # Fn+F10 Enable Bluetooth +0XA9 bluetooth # Fn+F10 Disable Bluetooth +0xF1 wlan # RF Switch Off +0xF2 wlan # RF Switch On +0xF4 prog1 # P1 Button +0xF3 prog2 # P2 Button diff --git a/m4/.gitignore b/m4/.gitignore new file mode 100644 index 000000000..cf35a86e8 --- /dev/null +++ b/m4/.gitignore @@ -0,0 +1,7 @@ +intltool.m4 +libtool.m4 +ltoptions.m4 +ltsugar.m4 +ltversion.m4 +lt~obsolete.m4 +gtk-doc.m4 diff --git a/m4/acx_libwrap.m4 b/m4/acx_libwrap.m4 new file mode 100644 index 000000000..ccf8afc0a --- /dev/null +++ b/m4/acx_libwrap.m4 @@ -0,0 +1,19 @@ +AC_DEFUN([ACX_LIBWRAP], [ +LIBWRAP_LIBS= +saved_LIBS="$LIBS" +LIBS="$LIBS -lwrap" +AC_MSG_CHECKING([for tcpwrap library and headers]) +AC_LINK_IFELSE( +[AC_LANG_PROGRAM( +[#include +#include +int allow_severity = LOG_INFO; +int deny_severity = LOG_WARNING;], +[struct request_info *req; +return hosts_access (req);])], +[AC_DEFINE(HAVE_LIBWRAP, [], [Have tcpwrap?]) +LIBWRAP_LIBS="-lwrap" +AC_MSG_RESULT(yes)], +[AC_MSG_RESULT(no)]) +LIBS="$saved_LIBS" +]) diff --git a/m4/attributes.m4 b/m4/attributes.m4 new file mode 100644 index 000000000..f0bcf2421 --- /dev/null +++ b/m4/attributes.m4 @@ -0,0 +1,288 @@ +dnl Macros to check the presence of generic (non-typed) symbols. +dnl Copyright (c) 2006-2008 Diego Pettenò +dnl Copyright (c) 2006-2008 xine project +dnl Copyright (c) 2012 Lucas De Marchi +dnl +dnl This program is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 2, or (at your option) +dnl any later version. +dnl +dnl This program is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with this program; if not, write to the Free Software +dnl Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +dnl 02110-1301, USA. +dnl +dnl As a special exception, the copyright owners of the +dnl macro gives unlimited permission to copy, distribute and modify the +dnl configure scripts that are the output of Autoconf when processing the +dnl Macro. You need not follow the terms of the GNU General Public +dnl License when using or distributing such scripts, even though portions +dnl of the text of the Macro appear in them. The GNU General Public +dnl License (GPL) does govern all other use of the material that +dnl constitutes the Autoconf Macro. +dnl +dnl This special exception to the GPL applies to versions of the +dnl Autoconf Macro released by this project. When you make and +dnl distribute a modified version of the Autoconf Macro, you may extend +dnl this special exception to the GPL to apply to your modified version as +dnl well. + +dnl Check if FLAG in ENV-VAR is supported by compiler and append it +dnl to WHERE-TO-APPEND variable +dnl CC_CHECK_FLAG_APPEND([WHERE-TO-APPEND], [ENV-VAR], [FLAG]) + +AC_DEFUN([CC_CHECK_FLAG_APPEND], [ + AC_CACHE_CHECK([if $CC supports flag $3 in envvar $2], + AS_TR_SH([cc_cv_$2_$3]), + [eval "AS_TR_SH([cc_save_$2])='${$2}'" + eval "AS_TR_SH([$2])='-Werror $3'" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([int a = 0; int main(void) { return a; } ])], + [eval "AS_TR_SH([cc_cv_$2_$3])='yes'"], + [eval "AS_TR_SH([cc_cv_$2_$3])='no'"]) + eval "AS_TR_SH([$2])='$cc_save_$2'"]) + + AS_IF([eval test x$]AS_TR_SH([cc_cv_$2_$3])[ = xyes], + [eval "$1='${$1} $3'"]) +]) + +dnl CC_CHECK_FLAGS_APPEND([WHERE-TO-APPEND], [ENV-VAR], [FLAG1 FLAG2]) +AC_DEFUN([CC_CHECK_FLAGS_APPEND], [ + for flag in $3; do + CC_CHECK_FLAG_APPEND($1, $2, $flag) + done +]) + +dnl Check if the flag is supported by linker (cacheable) +dnl CC_CHECK_LDFLAGS([FLAG], [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND]) + +AC_DEFUN([CC_CHECK_LDFLAGS], [ + AC_CACHE_CHECK([if $CC supports $1 flag], + AS_TR_SH([cc_cv_ldflags_$1]), + [ac_save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $1" + AC_LINK_IFELSE([int main() { return 1; }], + [eval "AS_TR_SH([cc_cv_ldflags_$1])='yes'"], + [eval "AS_TR_SH([cc_cv_ldflags_$1])="]) + LDFLAGS="$ac_save_LDFLAGS" + ]) + + AS_IF([eval test x$]AS_TR_SH([cc_cv_ldflags_$1])[ = xyes], + [$2], [$3]) +]) + +dnl define the LDFLAGS_NOUNDEFINED variable with the correct value for +dnl the current linker to avoid undefined references in a shared object. +AC_DEFUN([CC_NOUNDEFINED], [ + dnl We check $host for which systems to enable this for. + AC_REQUIRE([AC_CANONICAL_HOST]) + + case $host in + dnl FreeBSD (et al.) does not complete linking for shared objects when pthreads + dnl are requested, as different implementations are present; to avoid problems + dnl use -Wl,-z,defs only for those platform not behaving this way. + *-freebsd* | *-openbsd*) ;; + *) + dnl First of all check for the --no-undefined variant of GNU ld. This allows + dnl for a much more readable commandline, so that people can understand what + dnl it does without going to look for what the heck -z defs does. + for possible_flags in "-Wl,--no-undefined" "-Wl,-z,defs"; do + CC_CHECK_LDFLAGS([$possible_flags], [LDFLAGS_NOUNDEFINED="$possible_flags"]) + break + done + ;; + esac + + AC_SUBST([LDFLAGS_NOUNDEFINED]) +]) + +dnl Check for a -Werror flag or equivalent. -Werror is the GCC +dnl and ICC flag that tells the compiler to treat all the warnings +dnl as fatal. We usually need this option to make sure that some +dnl constructs (like attributes) are not simply ignored. +dnl +dnl Other compilers don't support -Werror per se, but they support +dnl an equivalent flag: +dnl - Sun Studio compiler supports -errwarn=%all +AC_DEFUN([CC_CHECK_WERROR], [ + AC_CACHE_CHECK( + [for $CC way to treat warnings as errors], + [cc_cv_werror], + [CC_CHECK_CFLAGS_SILENT([-Werror], [cc_cv_werror=-Werror], + [CC_CHECK_CFLAGS_SILENT([-errwarn=%all], [cc_cv_werror=-errwarn=%all])]) + ]) +]) + +AC_DEFUN([CC_CHECK_ATTRIBUTE], [ + AC_REQUIRE([CC_CHECK_WERROR]) + AC_CACHE_CHECK([if $CC supports __attribute__(( ifelse([$2], , [$1], [$2]) ))], + AS_TR_SH([cc_cv_attribute_$1]), + [ac_save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $cc_cv_werror" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([$3])], + [eval "AS_TR_SH([cc_cv_attribute_$1])='yes'"], + [eval "AS_TR_SH([cc_cv_attribute_$1])='no'"]) + CFLAGS="$ac_save_CFLAGS" + ]) + + AS_IF([eval test x$]AS_TR_SH([cc_cv_attribute_$1])[ = xyes], + [AC_DEFINE( + AS_TR_CPP([SUPPORT_ATTRIBUTE_$1]), 1, + [Define this if the compiler supports __attribute__(( ifelse([$2], , [$1], [$2]) ))] + ) + $4], + [$5]) +]) + +AC_DEFUN([CC_ATTRIBUTE_CONSTRUCTOR], [ + CC_CHECK_ATTRIBUTE( + [constructor],, + [void __attribute__((constructor)) ctor() { int a; }], + [$1], [$2]) +]) + +AC_DEFUN([CC_ATTRIBUTE_FORMAT], [ + CC_CHECK_ATTRIBUTE( + [format], [format(printf, n, n)], + [void __attribute__((format(printf, 1, 2))) printflike(const char *fmt, ...) { fmt = (void *)0; }], + [$1], [$2]) +]) + +AC_DEFUN([CC_ATTRIBUTE_FORMAT_ARG], [ + CC_CHECK_ATTRIBUTE( + [format_arg], [format_arg(printf)], + [char *__attribute__((format_arg(1))) gettextlike(const char *fmt) { fmt = (void *)0; }], + [$1], [$2]) +]) + +AC_DEFUN([CC_ATTRIBUTE_VISIBILITY], [ + CC_CHECK_ATTRIBUTE( + [visibility_$1], [visibility("$1")], + [void __attribute__((visibility("$1"))) $1_function() { }], + [$2], [$3]) +]) + +AC_DEFUN([CC_ATTRIBUTE_NONNULL], [ + CC_CHECK_ATTRIBUTE( + [nonnull], [nonnull()], + [void __attribute__((nonnull())) some_function(void *foo, void *bar) { foo = (void*)0; bar = (void*)0; }], + [$1], [$2]) +]) + +AC_DEFUN([CC_ATTRIBUTE_UNUSED], [ + CC_CHECK_ATTRIBUTE( + [unused], , + [void some_function(void *foo, __attribute__((unused)) void *bar);], + [$1], [$2]) +]) + +AC_DEFUN([CC_ATTRIBUTE_SENTINEL], [ + CC_CHECK_ATTRIBUTE( + [sentinel], , + [void some_function(void *foo, ...) __attribute__((sentinel));], + [$1], [$2]) +]) + +AC_DEFUN([CC_ATTRIBUTE_DEPRECATED], [ + CC_CHECK_ATTRIBUTE( + [deprecated], , + [void some_function(void *foo, ...) __attribute__((deprecated));], + [$1], [$2]) +]) + +AC_DEFUN([CC_ATTRIBUTE_ALIAS], [ + CC_CHECK_ATTRIBUTE( + [alias], [weak, alias], + [void other_function(void *foo) { } + void some_function(void *foo) __attribute__((weak, alias("other_function")));], + [$1], [$2]) +]) + +AC_DEFUN([CC_ATTRIBUTE_MALLOC], [ + CC_CHECK_ATTRIBUTE( + [malloc], , + [void * __attribute__((malloc)) my_alloc(int n);], + [$1], [$2]) +]) + +AC_DEFUN([CC_ATTRIBUTE_PACKED], [ + CC_CHECK_ATTRIBUTE( + [packed], , + [struct astructure { char a; int b; long c; void *d; } __attribute__((packed));], + [$1], [$2]) +]) + +AC_DEFUN([CC_ATTRIBUTE_CONST], [ + CC_CHECK_ATTRIBUTE( + [const], , + [int __attribute__((const)) twopow(int n) { return 1 << n; } ], + [$1], [$2]) +]) + +AC_DEFUN([CC_FLAG_VISIBILITY], [ + AC_REQUIRE([CC_CHECK_WERROR]) + AC_CACHE_CHECK([if $CC supports -fvisibility=hidden], + [cc_cv_flag_visibility], + [cc_flag_visibility_save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $cc_cv_werror" + CC_CHECK_CFLAGS_SILENT([-fvisibility=hidden], + cc_cv_flag_visibility='yes', + cc_cv_flag_visibility='no') + CFLAGS="$cc_flag_visibility_save_CFLAGS"]) + + AS_IF([test "x$cc_cv_flag_visibility" = "xyes"], + [AC_DEFINE([SUPPORT_FLAG_VISIBILITY], 1, + [Define this if the compiler supports the -fvisibility flag]) + $1], + [$2]) +]) + +AC_DEFUN([CC_FUNC_EXPECT], [ + AC_REQUIRE([CC_CHECK_WERROR]) + AC_CACHE_CHECK([if compiler has __builtin_expect function], + [cc_cv_func_expect], + [ac_save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $cc_cv_werror" + AC_COMPILE_IFELSE([AC_LANG_SOURCE( + [int some_function() { + int a = 3; + return (int)__builtin_expect(a, 3); + }])], + [cc_cv_func_expect=yes], + [cc_cv_func_expect=no]) + CFLAGS="$ac_save_CFLAGS" + ]) + + AS_IF([test "x$cc_cv_func_expect" = "xyes"], + [AC_DEFINE([SUPPORT__BUILTIN_EXPECT], 1, + [Define this if the compiler supports __builtin_expect() function]) + $1], + [$2]) +]) + +AC_DEFUN([CC_ATTRIBUTE_ALIGNED], [ + AC_REQUIRE([CC_CHECK_WERROR]) + AC_CACHE_CHECK([highest __attribute__ ((aligned ())) supported], + [cc_cv_attribute_aligned], + [ac_save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $cc_cv_werror" + for cc_attribute_align_try in 64 32 16 8 4 2; do + AC_COMPILE_IFELSE([AC_LANG_SOURCE([ + int main() { + static char c __attribute__ ((aligned($cc_attribute_align_try))) = 0; + return c; + }])], [cc_cv_attribute_aligned=$cc_attribute_align_try; break]) + done + CFLAGS="$ac_save_CFLAGS" + ]) + + if test "x$cc_cv_attribute_aligned" != "x"; then + AC_DEFINE_UNQUOTED([ATTRIBUTE_ALIGNED_MAX], [$cc_cv_attribute_aligned], + [Define the highest alignment supported]) + fi +]) diff --git a/make-directive-index.py b/make-directive-index.py new file mode 100755 index 000000000..eaf7019a2 --- /dev/null +++ b/make-directive-index.py @@ -0,0 +1,149 @@ +# -*- Mode: python; coding: utf-8; indent-tabs-mode: nil -*- */ +# +# This file is part of systemd. +# +# Copyright 2012 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 . + +import sys +import collections +import xml.etree.ElementTree as tree + +TEMPLATE = '''\ + + + + systemd.directives + systemd + + + + Developer + Zbigniew + Jędrzejewski-Szmek + zbyszek@in.waw.pl + + + + + + systemd.directives + 5 + + + + systemd.directives + Index of configuration directives + + + + Unit directives + + Directives for configuring units, used in unit + files. + + + + + + System manager directives + + Directives for configuring the behaviour of the + systemd process. + + + + + + UDEV directives + + Directives for configuring systemd units through the + udev database. + + + + + + Journal directives + + Directives for configuring the behaviour of the + journald process. + + + + +''' + +def _extract_directives(directive_groups, page): + t = tree.parse(page) + section = t.find('./refmeta/manvolnum').text + pagename = t.find('./refmeta/refentrytitle').text + for variablelist in t.iterfind('.//variablelist'): + klass = variablelist.attrib.get('class') or 'unit-directives' + stor = directive_groups[klass] + for varname in variablelist.iterfind('./varlistentry/term/varname'): + text = ''.join(varname.text.partition('=')[:2]) + stor[text].append((pagename, section)) + +def _make_section(refentry, name, directives): + varlist = refentry.find(".//*[@id='{}']".format(name)) + for varname, manpages in sorted(directives.items()): + entry = tree.SubElement(varlist, 'varlistentry') + a = tree.SubElement(tree.SubElement(entry, 'term'), 'varname') + a.text = varname + para = tree.SubElement(tree.SubElement(entry, 'listitem'), 'para') + + b = None + for manpage, manvolume in sorted(manpages): + if b is not None: + b.tail = ', ' + b = tree.SubElement(para, 'citerefentry') + c = tree.SubElement(b, 'refentrytitle') + c.text = manpage + d = tree.SubElement(b, 'manvolnum') + d.text = manvolume + entry.tail = '\n\n' + +def _make_page(directive_groups): + """Create an XML tree from directive_groups. + + directive_groups = { + 'class': {'variable': [('manpage', 'manvolume'), ...], + 'variable2': ...}, + ... + } + """ + refentry = tree.fromstring(TEMPLATE) + + for name, directives in directive_groups.items(): + _make_section(refentry, name, directives) + + return refentry + +def make_page(xml_files): + "Extract directives from xml_files and return XML index tree." + directive_groups = {name:collections.defaultdict(list) + for name in ['unit-directives', + 'udev-directives', + 'systemd-directives', + 'journal-directives', + ]} + for page in xml_files: + _extract_directives(directive_groups, page) + + return _make_page(directive_groups) + +if __name__ == '__main__': + tree.dump(make_page(sys.argv[1:])) diff --git a/make-man-index.py b/make-man-index.py new file mode 100755 index 000000000..b40c963f9 --- /dev/null +++ b/make-man-index.py @@ -0,0 +1,95 @@ +# -*- Mode: python; indent-tabs-mode: nil -*- */ +# +# This file is part of systemd. +# +# Copyright 2012 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 . + +from xml.etree.ElementTree import parse, Element, SubElement, tostring +from sys import argv, stdout + +index = {} + +def prettify(elem, indent = 0): + s = "\n" + indent * " " + if len(elem): + if not elem.text or not elem.text.strip(): + elem.text = s + " " + for e in elem: + prettify(e, indent + 1) + if not e.tail or not e.tail.strip(): + e.tail = s + " " + if not e.tail or not e.tail.strip(): + e.tail = s + else: + if indent and (not elem.tail or not elem.tail.strip()): + elem.tail = s + +for p in argv[1:]: + t = parse(p) + section = t.find('./refmeta/manvolnum').text + purpose = ' '.join(t.find('./refnamediv/refpurpose').text.split()) + for f in t.findall('./refnamediv/refname'): + index[f.text] = (p, section, purpose) + +html = Element('html') + +head = SubElement(html, 'head') +title = SubElement(head, 'title') +title.text = 'Manual Page Index' + +body = SubElement(html, 'body') +h1 = SubElement(body, 'h1') +h1.text = 'Manual Page Index' + +letter = None +for n in sorted(index.keys(), key = str.lower): + path, section, purpose = index[n] + + if path.endswith('.xml'): + path = path[:-4] + ".html" + + c = path.rfind('/') + if c >= 0: + path = path[c+1:] + + if letter is None or n[0].upper() != letter: + letter = n[0].upper() + + h2 = SubElement(body, 'h2') + h2.text = letter + + ul = SubElement(body, 'ul') + ul.set('style', 'list-style-type:none') + + li = SubElement(ul, 'li') + + a = SubElement(li, 'a') + a.set('href', path) + a.text = n + '(' + section + ')' + a.tail = ' -- ' + + i = SubElement(li, 'i') + i.text = purpose + +hr = SubElement(body, 'hr') + +p = SubElement(body, 'p') +p.text = "This index contains %s entries, referring to %i individual manual pages." % (len(index), len(argv)-1) + +if hasattr(stdout, "buffer"): + stdout = stdout.buffer +prettify(html) +stdout.write(tostring(html)) diff --git a/man/.gitignore b/man/.gitignore new file mode 100644 index 000000000..e97cda79b --- /dev/null +++ b/man/.gitignore @@ -0,0 +1,2 @@ +/systemd.directives.xml +/*.[13578] diff --git a/man/Makefile b/man/Makefile new file mode 120000 index 000000000..bd1047548 --- /dev/null +++ b/man/Makefile @@ -0,0 +1 @@ +../src/Makefile \ No newline at end of file diff --git a/man/binfmt.d.xml b/man/binfmt.d.xml new file mode 100644 index 000000000..07ae0ac23 --- /dev/null +++ b/man/binfmt.d.xml @@ -0,0 +1,124 @@ + + + + + + + + binfmt.d + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + binfmt.d + 5 + + + + binfmt.d + Configure additional binary formats for + executables at boot + + + + /etc/binfmt.d/*.conf + /run/binfmt.d/*.conf + /usr/lib/binfmt.d/*.conf + + + + Description + + At boot, + systemd-binfmt.service8 + reads configuration files from the above directories + to register in the kernel additional binary + formats for executables. + + + + Configuration Format + + Each file contains a list of binfmt_misc kernel + binary format rules. Consult binfmt_misc.txt + for more information on registration of additional + binary formats and how to write rules. + + Empty lines and lines beginning with ; and # are + ignored. Note that this means you may not use ; and # + as delimiter in binary format rules. + + Each configuration file shall be named in the + style of <program>.conf. + Files in /etc/ override files + with the same name in /usr/lib/ + and /run/. Files in + /run/ override files with the + same name in /usr/lib/. Packages + should install their configuration files in + /usr/lib/, files in + /etc/ are reserved for the local + administrator, who may use this logic to override the + configuration files installed from vendor + packages. All files are sorted by their filename in + alphabetical order, regardless in which of the + directories they reside, to guarantee that a specific + configuration file takes precedence over another file + with an alphabetically later name. + + If the administrator wants to disable a + configuration file supplied by the vendor the + recommended way is to place a symlink to + /dev/null in + /etc/binfmt.d/ bearing the + same file name. + + + + Example + + /etc/binfmt.d/wine.conf example: + + # Start WINE on Windows executables +:DOSWin:M::MZ::/usr/bin/wine: + + + + + See Also + + systemd1, + systemd-binfmt.service8, + systemd-delta1, + wine8 + + + + diff --git a/man/bootup.xml b/man/bootup.xml new file mode 100644 index 000000000..4cc4bafab --- /dev/null +++ b/man/bootup.xml @@ -0,0 +1,226 @@ + + + + + + + + + bootup + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + bootup + 7 + + + + bootup + System bootup process + + + + Description + + A number of different components are involved in the + system boot. Immediately after power-up, the system + BIOS will do minimal hardware initialization, and hand + control over to a boot loader stored on a persistent + storage device. This boot loader will then invoke an + OS kernel from disk (or the network). In the Linux + case this kernel now (optionally) extracts and + executes an initial RAM disk image (initrd) such as + dracut8 + which looks for the root file system. After the root + file system is found and mounted the initrd hands over + control to the system manager (such as + systemd1) + stored on the OS image which is then responsible for + probing all remaining hardware, mounting all necessary + file systems and spawning all configured + services. + + On shutdown the system manager stops all + services, unmounts all file systems (detaching the + storage technologies backing them), and then + (optionally) jumps back into the initrd code which + unmounts/detaches the root file system and the storage + it resides on. As last step the system is powered down. + + Additional information about the system boot + process may be found in + boot7. + + + + System Manager Bootup + + At boot, the system manager on the OS image is + responsible for initializing the required file + systems, services and drivers that are necessary for + operation of the system. On + systemd1 + systems this process is split up in various discrete + steps which are exposed as target units. (See + systemd.target5 + for detailed information about target units.) The + boot-up process is highly parallelized so that the + order in which specific target units are reached is not + deterministic, but still adheres to a limited amount + of ordering structure. + + When systemd starts up the system it will + activate all units that are dependencies of + default.target (as well as + recursively all dependencies of these + dependencies). Usually + default.target is simply an alias + of graphical.target or + multi-user.target depending on + whether the system is configured for a graphical UI or + only for a text console. To enforce minimal ordering + between the units pulled in a number of well-known + target units are available, as listed on + systemd.special7. + + The following chart is a structural overview of + these well-known units and their position in the + boot-up logic. The arrows describe which units are + pulled in and ordered before which other units. Units + near the top are started before units nearer to the + bottom of the chart. + +local-fs-pre.target + | + v +(various mounts and (various swap (various cryptsetup + fsck services...) devices...) devices...) (various low-level (various low-level + | | | services: udevd, API VFS mounts: + v v v tmpfiles, random mqueue, configfs, + local-fs.target swap.target cryptsetup.target seed, sysctl, ...) debugfs, ...) + | | | | | + \__________________|_________________ | ___________________|____________________/ + \|/ + v + sysinit.target + | + _________________/|\___________________ + / | \ + | | | + v | v + (various | rescue.service + sockets...) | | + | | v + v | rescue.target + sockets.target | + | | + \_________________ | + \| + v + basic.target + | + __________________________________/| emergency.service + / | | | + | | | v + v v v emergency.target + display- (various system (various system + manager.service services services) + | required for | + | graphical UIs) v + | | multi-user.target + | | | + \_______________ | _________________/ + \|/ + v + graphical.target + + Target units that are commonly used as boot + targets are emphasized. These + units are good choices as goal targets, for + example by passing them to the + systemd.unit= kernel command line + option (see + systemd1) + or by symlinking default.target + to them. + + + + System Manager Shutdown + + System shutdown also consists of various target + units with some minimal ordering structure + applied: + + + + + (conflicts with (conflicts with + all system all file system + services) mounts, swaps, + | cryptsetup + | devices, ...) + | | + v v + shutdown.target umount.target + | | + \_______ ______/ + \ / + v + (various low-level + services) + | + v + final.target + | + _____________________________________/ \_________________________________ + / | | \ + | | | | + v v v v +systemd-reboot.service systemd-poweroff.service systemd-halt.service systemd-kexec.service + | | | | + v v v v + reboot.target poweroff.target halt.target kexec.target + + Commonly used system shutdown targets are emphasized. + + + + See Also + + systemd1, + boot7, + systemd.special7, + systemd.target5 + + + + diff --git a/man/crypttab.xml b/man/crypttab.xml new file mode 100644 index 000000000..2a839944d --- /dev/null +++ b/man/crypttab.xml @@ -0,0 +1,313 @@ + + + + + + + + crypttab + systemd + + + + Documentation + Miloslav + Trmac + mitr@redhat.com + + + Documentation + Lennart + Poettering + lennart@poettering.net + + + + + + crypttab + 5 + + + + crypttab + Configuration for encrypted block devices + + + + /etc/crypttab + + + + Description + + The /etc/crypttab file + describes encrypted block devices that are set up + during system boot. + + Empty lines and lines starting with the # + character are ignored. Each of the remaining lines + describes one encrypted block device, fields on the + line are delimited by white space. The first two + fields are mandatory, the remaining two are + optional. + + The first field contains the name of the + resulting encrypted block device; the device is set up + within /dev/mapper/. + + The second field contains a path to the + underlying block device, or a specification of a block + device via UUID= followed by the + UUID. If the block device contains a LUKS signature, + it is opened as a LUKS encrypted partition; otherwise + it is assumed to be a raw dm-crypt partition. + + The third field specifies the encryption + password. If the field is not present or the password + is set to none, the password has to be manually + entered during system boot. Otherwise the field is + interpreted as a path to a file containing the + encryption password. For swap encryption + /dev/urandom or the hardware + device /dev/hw_random can be used + as the password file; using + /dev/random may prevent boot + completion if the system does not have enough entropy + to generate a truly random encryption key. + + The fourth field, if present, is a + comma-delimited list of options. The following + options are recognized: + + + + cipher= + + Specifies the cipher + to use; see + cryptsetup8 + for possible values and the default + value of this option. A cipher with + unpredictable IV values, such as + aes-cbc-essiv:sha256, + is recommended. + + + + + size= + + Specifies the key size + in bits; see + cryptsetup8 + for possible values and the default + value of this + option. + + + + + keyfile-size= + + Specifies the maximum number + of bytes to read from the keyfile; see + cryptsetup8 + for possible values and the default + value of this option. This option is ignored + in plain encryption mode, as the keyfile-size is then given by the key size. + + + + + keyfile-offset= + + Specifies the number + of bytes to skip at the start of + the keyfile; see + cryptsetup8 + for possible values and the default + value of this option. + + + + + hash= + + Specifies the hash to + use for password hashing; see + cryptsetup8 for possible values and + the default value of this + option. + + + + tries= + + Specifies the maximum + number of times the user is queried + for a password. + + + + verify + + If the encryption + password is read from console, it has + to be entered twice (to prevent + typos). + + + + read-only + + Set up the encrypted + block device in read-only + mode. + + + + allow-discards + + Allow discard requests + to be passed through the encrypted + block device. This improves + performance on SSD storage but has + security + implications. + + + + luks + + Force LUKS mode. + + + + plain + + Force plain encryption + mode. + + + + timeout= + + Specify the timeout + for querying for a password. If no + unit is specified seconds is used. + Supported units are s, ms, + us, min, h, d. + + + + noauto + + This device will not + be automatically unlocked on + boot. + + + + nofail + + The system will not + wait for the device to show up and be + unlocked at boot, and not fail the + boot if it doesn't show + up. + + + + swap + + The encrypted block + device will be used as a swap + partition, and will be formatted as a + swap partition after setting up the + encrypted block device, with + mkswap8. + + WARNING: Using the + swap option will + destroy the contents of the named + partition during every boot, so make + sure the underlying block device is + specified + correctly. + + + + tmp + + The encrypted block + device will be prepared for using it + as /tmp + partition: it will be formatted using + mke2fs8. + + WARNING: Using the + tmp option will + destroy the contents of the named + partition during every boot, so make + sure the underlying block device is + specified + correctly. + + + + At early boot and when the system manager + configuration is reloaded this file is translated into + native systemd units + by systemd-cryptsetup-generator8. + + + + Example + + /etc/crypttab example + Set up two encrypted block devices with + LUKS: one normal one for storage, and another + one for usage as swap device. + + luks-2505567a-9e27-4efe-a4d5-15ad146c258b UUID=2505567a-9e27-4efe-a4d5-15ad146c258b - timeout=0 +swap /dev/sda7 /dev/urandom swap + + + + + See Also + + systemd1, + systemd-cryptsetup@.service8, + systemd-cryptsetup-generator8, + cryptsetup8, + mkswap8, + mke2fs8 + + + + diff --git a/man/custom-html.xsl b/man/custom-html.xsl new file mode 100644 index 000000000..906ddc557 --- /dev/null +++ b/man/custom-html.xsl @@ -0,0 +1,50 @@ + + + + + + + + + + + + + .html + + + + + + + + + + index.html + + Index + +
+
+ + + + +
diff --git a/man/daemon.xml b/man/daemon.xml new file mode 100644 index 000000000..0d29e7aa1 --- /dev/null +++ b/man/daemon.xml @@ -0,0 +1,949 @@ + + + + + + + + + daemon + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + daemon + 7 + + + + daemon + Writing and packaging system daemons + + + + Description + + A daemon is a service process that runs in the + background and supervises the system or provides + functionality to other processes. Traditionally, + daemons are implemented following a scheme originating + in SysV Unix. Modern daemons should follow a simpler + yet more powerful scheme (here called "new-style" + daemons), as implemented by + systemd1. This + manual page covers both schemes, and in + particular includes recommendations for daemons that + shall be included in the systemd init system. + + + SysV Daemons + + When a traditional SysV daemon + starts, it should execute the following steps + as part of the initialization. Note that these + steps are unnecessary for new-style daemons (see below), + and should only be implemented if compatibility + with SysV is essential. + + + Close all open file + descriptors except STDIN, STDOUT, + STDERR (i.e. the first three file + descriptors 0, 1, 2). This ensures + that no accidentally passed file + descriptor stays around in the daemon + process. On Linux this is best + implemented by iterating through + /proc/self/fd, + with a fallback of iterating from file + descriptor 3 to the value returned by + getrlimit() for + RLIMIT_NOFILE. + + Reset all signal + handlers to their default. This is + best done by iterating through the + available signals up to the limit of + _NSIG and resetting them to + SIG_DFL. + + Reset the signal mask + using + sigprocmask(). + + Sanitize the + environment block, removing or + resetting environment variables that + might negatively impact daemon + runtime. + + Call fork(), + to create a background + process. + + In the child, call + setsid() to + detach from any terminal and create an + independent session. + + In the child, call + fork() again, to + ensure the daemon can never re-acquire + a terminal again. + + Call exit() in the + first child, so that only the second + child (the actual daemon process) + stays around. This ensures that the + daemon process is re-parented to + init/PID 1, as all daemons should + be. + + In the daemon process, + connect /dev/null + to STDIN, STDOUT, + STDERR. + + In the daemon process, + reset the umask to 0, so that the file + modes passed to open(), mkdir() and + suchlike directly control the access + mode of the created files and + directories. + + In the daemon process, + change the current directory to the + root directory (/), in order to avoid + that the daemon involuntarily + blocks mount points from being + unmounted. + + In the daemon process, + write the daemon PID (as returned by + getpid()) to a + PID file, for example + /var/run/foobar.pid + (for a hypothetical daemon "foobar"), + to ensure that the daemon cannot be + started more than once. This must be + implemented in race-free fashion so + that the PID file is only updated when + at the same time it is verified that + the PID previously stored in the PID + file no longer exists or belongs to a + foreign process. Commonly some kind of + file locking is employed to implement + this logic. + + In the daemon process, + drop privileges, if possible and + applicable. + + From the daemon + process notify the original process + started that initialization is + complete. This can be implemented via + an unnamed pipe or similar + communication channel that is created + before the first + fork() and hence + available in both the original and the + daemon process. + + Call + exit() in the + original process. The process that + invoked the daemon must be able to + rely on that this + exit() happens + after initialization is complete and + all external communication channels + are established and + accessible. + + + The BSD daemon() function should not be + used, as it implements only a subset of these steps. + + A daemon that needs to provide + compatibility with SysV systems should + implement the scheme pointed out + above. However, it is recommended to make this + behavior optional and configurable via a + command line argument, to ease debugging as + well as to simplify integration into systems + using systemd. + + + + New-Style Daemons + + Modern services for Linux should be + implemented as new-style daemons. This makes it + easier to supervise and control them at + runtime and simplifies their + implementation. + + For developing a new-style daemon none + of the initialization steps recommended for + SysV daemons need to be implemented. New-style + init systems such as systemd make all of them + redundant. Moreover, since some of these steps + interfere with process monitoring, file + descriptor passing and other functionality of + the init system it is recommended not to + execute them when run as new-style + service. + + Note that new-style init systems + guarantee execution of daemon processes in + clean process contexts: it is guaranteed that + the environment block is sanitized, that the + signal handlers and mask is reset and that no + left-over file descriptors are passed. Daemons + will be executed in their own session, and + STDIN/STDOUT/STDERR connected to + /dev/null unless + otherwise configured. The umask is reset. + + It is recommended for new-style daemons + to implement the following: + + + If SIGTERM is + received, shut down the daemon and + exit cleanly. + + If SIGHUP is received, + reload the configuration files, if + this applies. + + Provide a correct exit + code from the main daemon process, as + this is used by the init system to + detect service errors and problems. It + is recommended to follow the exit code + scheme as defined in the LSB + recommendations for SysV init + scripts. + + If possible and + applicable expose the daemon's control + interface via the D-Bus IPC system and + grab a bus name as last step of + initialization. + + For integration in + systemd, provide a + .service unit + file that carries information about + starting, stopping and otherwise + maintaining the daemon. See + systemd.service5 + for details. + + As much as possible, + rely on the init system's + functionality to limit the access of + the daemon to files, services and + other resources. i.e. in the case of + systemd, rely on systemd's resource + limit control instead of implementing + your own, rely on systemd's privilege + dropping code instead of implementing + it in the daemon, and similar. See + systemd.exec5 + for the available + controls. + + If D-Bus is used, make + your daemon bus-activatable, via + supplying a D-Bus service activation + configuration file. This has multiple + advantages: your daemon may be started + lazily on-demand; it may be started in + parallel to other daemons requiring it + -- which maximizes parallelization and + boot-up speed; your daemon can be + restarted on failure, without losing + any bus requests, as the bus queues + requests for activatable services. See + below for details. + + If your daemon + provides services to other local + processes or remote clients via a + socket, it should be made + socket-activatable following the + scheme pointed out below. Like D-Bus + activation this enables on-demand + starting of services as well as it + allows improved parallelization of + service start-up. Also, for state-less + protocols (such as syslog, DNS) a + daemon implementing socket-based + activation can be restarted without + losing a single request. See below for + details. + + If applicable a daemon + should notify the init system about + startup completion or status updates + via the + sd_notify3 + interface. + + Instead of using the + syslog() call to log directly to the + system syslog service, a new-style daemon may + choose to simply log to STDERR via + fprintf(), which is then forwarded to + syslog by the init system. If log + priorities are necessary these can be + encoded by prefixing individual log + lines with strings like "<4>" + (for log priority 4 "WARNING" in the + syslog priority scheme), following a + similar style as the Linux kernel's + printk() priority system. In fact, + using this style of logging also + enables the init system to optionally + direct all application logging to the + kernel log buffer (kmsg), as + accessible via + dmesg1. This + kind of logging may be enabled by + setting + StandardError=syslog + in the service unit file. For details + see + sd-daemon3 + and + systemd.exec5. + + + + These recommendations are similar but + not identical to the Apple + MacOS X Daemon Requirements. + + + + + Activation + + New-style init systems provide multiple + additional mechanisms to activate services, as + detailed below. It is common that services are + configured to be activated via more than one mechanism + at the same time. An example for systemd: + bluetoothd.service might get + activated either when Bluetooth hardware is plugged + in, or when an application accesses its programming + interfaces via D-Bus. Or, a print server daemon might + get activated when traffic arrives at an IPP port, or + when a printer is plugged in, or when a file is queued + in the printer spool directory. Even for services that + are intended to be started on system bootup + unconditionally it is a good idea to implement some of + the various activation schemes outlined below, in + order to maximize parallelization: if a daemon + implements a D-Bus service or listening socket, + implementing the full bus and socket activation scheme + allows starting of the daemon with its clients in + parallel (which speeds up boot-up), since all its + communication channels are established already, and no + request is lost because client requests will be queued + by the bus system (in case of D-Bus) or the kernel (in + case of sockets), until the activation is + completed. + + + Activation on Boot + + Old-style daemons are usually activated + exclusively on boot (and manually by the + administrator) via SysV init scripts, as + detailed in the LSB + Linux Standard Base Core + Specification. This method of + activation is supported ubiquitously on Linux + init systems, both old-style and new-style + systems. Among other issues SysV init scripts + have the disadvantage of involving shell + scripts in the boot process. New-style init + systems generally employ updated versions of + activation, both during boot-up and during + runtime and using more minimal service + description files. + + In systemd, if the developer or + administrator wants to make sure a service or + other unit is activated automatically on boot + it is recommended to place a symlink to the + unit file in the .wants/ + directory of either + multi-user.target or + graphical.target, which + are normally used as boot targets at system + startup. See + systemd.unit5 + for details about the + .wants/ directories, and + systemd.special7 + for details about the two boot targets. + + + + + Socket-Based Activation + + In order to maximize the possible + parallelization and robustness and simplify + configuration and development, it is + recommended for all new-style daemons that + communicate via listening sockets to employ + socket-based activation. In a socket-based + activation scheme the creation and binding of + the listening socket as primary communication + channel of daemons to local (and sometimes + remote) clients is moved out of the daemon + code and into the init system. Based on + per-daemon configuration the init system + installs the sockets and then hands them off + to the spawned process as soon as the + respective daemon is to be started. + Optionally activation of the service can be + delayed until the first inbound traffic + arrives at the socket, to implement on-demand + activation of daemons. However, the primary + advantage of this scheme is that all providers + and all consumers of the sockets can be + started in parallel as soon as all sockets + are established. In addition to that daemons + can be restarted with losing only a minimal + number of client transactions or even any + client request at all (the latter is + particularly true for state-less protocols, + such as DNS or syslog), because the socket + stays bound and accessible during the restart, + and all requests are queued while the daemon + cannot process them. + + New-style daemons which support socket + activation must be able to receive their + sockets from the init system, instead of + creating and binding them themselves. For + details about the programming interfaces for + this scheme provided by systemd see + sd_listen_fds3 + and + sd-daemon3. For + details about porting existing daemons to + socket-based activation see below. With + minimal effort it is possible to implement + socket-based activation in addition to + traditional internal socket creation in the + same codebase in order to support both + new-style and old-style init systems from the + same daemon binary. + + systemd implements socket-based + activation via .socket + units, which are described in + systemd.socket5. When + configuring socket units for socket-based + activation it is essential that all listening + sockets are pulled in by the special target + unit sockets.target. It + is recommended to place a + WantedBy=sockets.target + directive in the [Install] + section, to automatically add such a + dependency on installation of a socket + unit. Unless + DefaultDependencies=no is + set the necessary ordering dependencies are + implicitly created for all socket units. For + more information about + sockets.target see + systemd.special7. It + is not necessary or recommended to place any + additional dependencies on socket units (for + example from + multi-user.target or + suchlike) when one is installed in + sockets.target. + + + + Bus-Based Activation + + When the D-Bus IPC system is used for + communication with clients, new-style daemons + should employ bus activation so that they are + automatically activated when a client + application accesses their IPC + interfaces. This is configured in D-Bus + service files (not to be confused with systemd + service unit files!). To ensure that D-Bus + uses systemd to start-up and maintain the + daemon use the + SystemdService= directive + in these service files, to configure the + matching systemd service for a D-Bus + service. e.g.: for a D-Bus service whose D-Bus + activation file is named + org.freedesktop.RealtimeKit.service, + make sure to set + SystemdService=rtkit-daemon.service + in that file, to bind it to the systemd + service + rtkit-daemon.service. This + is needed to make sure that the daemon is + started in a race-free fashion when activated + via multiple mechanisms simultaneously. + + + + Device-Based Activation + + Often, daemons that manage a particular + type of hardware should be activated only when + the hardware of the respective kind is plugged + in or otherwise becomes available. In a + new-style init system it is possible to bind + activation to hardware plug/unplug events. In + systemd, kernel devices appearing in the + sysfs/udev device tree can be exposed as units + if they are tagged with the string + "systemd". Like any other + kind of unit they may then pull in other units + when activated (i.e. Plugged in) and thus + implement device-based activation. Systemd + dependencies may be encoded in the udev + database via the + SYSTEMD_WANTS= + property. See + systemd.device5 + for details. Often it is nicer to pull in + services from devices only indirectly via + dedicated targets. Example: instead of pulling + in bluetoothd.service + from all the various bluetooth dongles and + other hardware available, pull in + bluetooth.target from them and + bluetoothd.service from + that target. This provides for nicer + abstraction and gives administrators the + option to enable + bluetoothd.service via + controlling a + bluetooth.target.wants/ + symlink uniformly with a command like + enable of + systemctl1 + instead of manipulating the udev + ruleset. + + + + Path-Based Activation + + Often, runtime of daemons processing + spool files or directories (such as a printing + system) can be delayed until these file system + objects change state, or become + non-empty. New-style init systems provide a + way to bind service activation to file system + changes. systemd implements this scheme via + path-based activation configured in + .path units, as outlined + in + systemd.path5. + + + + Timer-Based Activation + + Some daemons that implement clean-up + jobs that are intended to be executed in + regular intervals benefit from timer-based + activation. In systemd, this is implemented + via .timer units, as + described in + systemd.timer5. + + + + Other Forms of Activation + + Other forms of activation have been + suggested and implemented in some + systems. However, often there are simpler or + better alternatives, or they can be put + together of combinations of the schemes + above. Example: sometimes it appears useful to + start daemons or .socket + units when a specific IP address is configured + on a network interface, because network + sockets shall be bound to the + address. However, an alternative to implement + this is by utilizing the Linux IP_FREEBIND + socket option, as accessible via + FreeBind=yes in systemd + socket files (see + systemd.socket5 + for details). This option, when enabled, + allows sockets to be bound to a non-local, not + configured IP address, and hence allows + bindings to a particular IP address before it + actually becomes available, making such an + explicit dependency to the configured address + redundant. Another often suggested trigger for + service activation is low system + load. However, here too, a more convincing + approach might be to make proper use of + features of the operating system: in + particular, the CPU or IO scheduler of + Linux. Instead of scheduling jobs from + userspace based on monitoring the OS + scheduler, it is advisable to leave the + scheduling of processes to the OS scheduler + itself. systemd provides fine-grained access + to the CPU and IO schedulers. If a process + executed by the init system shall not + negatively impact the amount of CPU or IO + bandwidth available to other processes, it + should be configured with + CPUSchedulingPolicy=idle + and/or + IOSchedulingClass=idle. Optionally, + this may be combined with timer-based + activation to schedule background jobs during + runtime and with minimal impact on the system, + and remove it from the boot phase + itself. + + + + + Integration with Systemd + + + Writing Systemd Unit Files + + When writing systemd unit files, it is + recommended to consider the following + suggestions: + + + If possible do not use + the Type=forking + setting in service files. But if you + do, make sure to set the PID file path + using PIDFile=. See + systemd.service5 + for details. + + If your daemon + registers a D-Bus name on the bus, + make sure to use + Type=dbus in the + service file if + possible. + + Make sure to set a + good human-readable description string + with + Description=. + + Do not disable + DefaultDependencies=, + unless you really know what you do and + your unit is involved in early boot or + late system shutdown. + + Normally, little if + any dependencies should need to + be defined explicitly. However, if you + do configure explicit dependencies, only refer to + unit names listed on + systemd.special7 + or names introduced by your own + package to keep the unit file + operating + system-independent. + + Make sure to include + an [Install] + section including installation + information for the unit file. See + systemd.unit5 + for details. To activate your service + on boot make sure to add a + WantedBy=multi-user.target + or + WantedBy=graphical.target + directive. To activate your socket on + boot, make sure to add + WantedBy=sockets.target. Usually + you also want to make sure that when + your service is installed your socket + is installed too, hence add + Also=foo.socket in + your service file + foo.service, for + a hypothetical program + foo. + + + + + + Installing Systemd Service Files + + At the build installation time + (e.g. make install during + package build) packages are recommended to + install their systemd unit files in the + directory returned by pkg-config + systemd + --variable=systemdsystemunitdir (for + system services) or pkg-config + systemd + --variable=systemduserunitdir + (for user services). This will make the + services available in the system on explicit + request but not activate them automatically + during boot. Optionally, during package + installation (e.g. rpm -i + by the administrator) symlinks should be + created in the systemd configuration + directories via the enable + command of the + systemctl1 + tool, to activate them automatically on + boot. + + Packages using + autoconf1 + are recommended to use a configure script + excerpt like the following to determine the + unit installation path during source + configuration: + + PKG_PROG_PKG_CONFIG +AC_ARG_WITH([systemdsystemunitdir], + AS_HELP_STRING([--with-systemdsystemunitdir=DIR], [Directory for systemd service files]), + [], [with_systemdsystemunitdir=$($PKG_CONFIG --variable=systemdsystemunitdir systemd)]) +if test "x$with_systemdsystemunitdir" != xno; then + AC_SUBST([systemdsystemunitdir], [$with_systemdsystemunitdir]) +fi +AM_CONDITIONAL(HAVE_SYSTEMD, [test -n "$with_systemdsystemunitdir" -a "x$with_systemdsystemunitdir" != xno ]) + + This snippet allows automatic + installation of the unit files on systemd + machines, and optionally allows their + installation even on machines lacking + systemd. (Modification of this snippet for the + user unit directory is left as an exercise for the + reader.) + + Additionally, to ensure that + make distcheck continues to + work, it is recommended to add the following + to the top-level Makefile.am + file in + automake1-based + projects: + + DISTCHECK_CONFIGURE_FLAGS = \ + --with-systemdsystemunitdir=$$dc_install_base/$(systemdsystemunitdir) + + Finally, unit files should be installed in the system with an automake excerpt like the following: + + if HAVE_SYSTEMD +systemdsystemunit_DATA = \ + foobar.socket \ + foobar.service +endif + + In the + rpm8 + .spec file use snippets + like the following to enable/disable the + service during + installation/deinstallation. This makes use of + the RPM macros shipped along systemd. Consult + the packaging guidelines of your distribution + for details and the equivalent for other + package managers. + + At the top of the file: + + BuildRequires: systemd +%{?systemd_requires} + + And as scriptlets, further down: + + %post +%systemd_post foobar.service foobar.socket + +%preun +%systemd_preun foobar.service foobar.socket + +%postun +%systemd_postun + + If the service shall be restarted during + upgrades replace the + %postun scriptlet above + with the following: + + %postun +%systemd_postun_with_restart foobar.service + + Note that + %systemd_post and + %systemd_preun expect the + names of all units that are installed/removed + as arguments, separated by + spaces. %systemd_postun + expects no + arguments. %systemd_postun_with_restart + expects the units to restart as + arguments. + + To facilitate upgrades from a package + version that shipped only SysV init scripts to + a package version that ships both a SysV init + script and a native systemd service file, use + a fragment like the following: + + %triggerun -- foobar < 0.47.11-1 +if /sbin/chkconfig --level 5 foobar ; then + /bin/systemctl --no-reload enable foobar.service foobar.socket >/dev/null 2>&1 || : +fi + + Where 0.47.11-1 is the first package + version that includes the native unit + file. This fragment will ensure that the first + time the unit file is installed it will be + enabled if and only if the SysV init script is + enabled, thus making sure that the enable + status is not changed. Note that + chkconfig is a command + specific to Fedora which can be used to check + whether a SysV init script is enabled. Other + operating systems will have to use different + commands here. + + + + + Porting Existing Daemons + + Since new-style init systems such as systemd are + compatible with traditional SysV init systems it is + not strictly necessary to port existing daemons to the + new style. However doing so offers additional + functionality to the daemons as well as simplifying + integration into new-style init systems. + + To port an existing SysV compatible daemon the + following steps are recommended: + + + If not already implemented, + add an optional command line switch to the + daemon to disable daemonization. This is + useful not only for using the daemon in + new-style init systems, but also to ease + debugging. + + If the daemon offers + interfaces to other software running on the + local system via local AF_UNIX sockets, + consider implementing socket-based activation + (see above). Usually a minimal patch is + sufficient to implement this: Extend the + socket creation in the daemon code so that + sd_listen_fds3 + is checked for already passed sockets + first. If sockets are passed (i.e. when + sd_listen_fds() returns a + positive value), skip the socket creation step + and use the passed sockets. Secondly, ensure + that the file-system socket nodes for local + AF_UNIX sockets used in the socket-based + activation are not removed when the daemon + shuts down, if sockets have been + passed. Third, if the daemon normally closes + all remaining open file descriptors as part of + its initialization, the sockets passed from + the init system must be spared. Since + new-style init systems guarantee that no + left-over file descriptors are passed to + executed processes, it might be a good choice + to simply skip the closing of all remaining + open file descriptors if sockets are + passed. + + Write and install a systemd + unit file for the service (and the sockets if + socket-based activation is used, as well as a + path unit file, if the daemon processes a + spool directory), see above for + details. + + If the daemon exposes + interfaces via D-Bus, write and install a + D-Bus activation file for the service, see + above for details. + + + + + See Also + + systemd1, + sd-daemon3, + sd_listen_fds3, + sd_notify3, + daemon3, + systemd.service5 + + + + diff --git a/man/halt.xml b/man/halt.xml new file mode 100644 index 000000000..847396519 --- /dev/null +++ b/man/halt.xml @@ -0,0 +1,172 @@ + + + + + + + + + halt + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + halt + 8 + + + + halt + poweroff + reboot + Halt, power-off or reboot the machine + + + + + halt OPTIONS + + + poweroff OPTIONS + + + reboot OPTIONS + + + + + Description + + halt, + poweroff, reboot + may be used to halt, power-off or reboot the + machine. + + + + + Options + + The following options are understood: + + + + + + Prints a short help + text and exits. + + + + + + Halt the machine, + regardless of which one of the three + commands is invoked. + + + + + + + Power-off the machine, + regardless of which one of the three + commands is invoked. + + + + + + Reboot the machine, + regardless of which one of the three + commands is invoked. + + + + + + + Force immediate halt, + power-off, reboot. Don't contact the + init system. + + + + + + + Only write wtmp + shutdown entry, don't actually halt, + power-off, reboot. + + + + + + + Don't write wtmp + shutdown entry. + + + + + + Don't send wall + message before + halt, power-off, reboot. + + + + + + Exit status + + On success 0 is returned, a non-zero failure + code otherwise. + + + + Notes + + These are legacy commands available for + compatibility only. + + + + See Also + + systemd1, + systemctl1, + shutdown8, + wall1 + + + + diff --git a/man/hostname.xml b/man/hostname.xml new file mode 100644 index 000000000..84a296166 --- /dev/null +++ b/man/hostname.xml @@ -0,0 +1,102 @@ + + + + + + + + + /etc/hostname + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + hostname + 5 + + + + hostname + Local host name configuration file + + + + /etc/hostname + + + + Description + + The /etc/hostname file + configures the name of the local system that is set + during boot, with the + sethostname2 + system call. It should contain a single + newline-terminated host name string. The + host name may be a free-form string up to 64 characters + in length, however it is recommended that it consists + only of 7bit ASCII lower-case characters and no spaces or dots, + and limits itself to the format allowed for DNS domain + name labels, even though this is not a + strict requirement. + + Depending on the operating system other + configuration files might be checked for configuration + of the host name as well, however only as fallback. + + You may use + hostnamectl1 + to change the value of this file from the command + line. + + + + History + + The simple configuration file format of + /etc/hostname originates from + Debian GNU/Linux. + + + + See Also + + systemd1, + sethostname2, + hostname1, + hostname7, + machine-id5, + machine-info5, + hostnamectl1, + systemd-hostnamed.service8 + + + + diff --git a/man/hostnamectl.xml b/man/hostnamectl.xml new file mode 100644 index 000000000..a29d2f5b7 --- /dev/null +++ b/man/hostnamectl.xml @@ -0,0 +1,254 @@ + + + + + + + + + hostnamectl + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + hostnamectl + 1 + + + + hostnamectl + Control the system hostname + + + + + hostnamectl OPTIONS COMMAND + + + + + Description + + hostnamectl may be used to + query and change the system hostname and related + settings. + + This tool distinguishes three different host + names: the high-level "pretty" hostname which might + include all kinds of special characters + (e.g. "Lennart's Laptop"), the static hostname which + is used to initialize the kernel hostname at boot + (e.g. "lennarts-laptop"), and the transient hostname + which might be assigned temporarily due to network + configuration and might revert back to the static + hostname if network connectivity is lost and is only + temporarily written to the kernel hostname + (e.g. "dhcp-47-11"). + + Note that the pretty hostname has little + restrictions on the characters used, while the static + and transient hostnames are limited to the usually + accepted characters of internet domain names. + + The static host name is stored in + /etc/hostname, see + hostname5 + for more information. The pretty host name, chassis + type and icon name are stored in + /etc/machine-info, see + machine-id5. + + + + Options + + The following options are understood: + + + + + + + Prints a short help + text and exits. + + + + + + Prints a short version + string and exits. + + + + + + Don't query the user + for authentication for privileged + operations. + + + + + + + Execute the operation + remotely. Specify a hostname, or + username and hostname separated by @, + to connect to. This will use SSH to + talk to a remote + system. + + + + + + + + If + set-hostname is + invoked and one or more of these + options are passed only the selected + hostnames is + updated. + + + + The following commands are understood: + + + + status + + Show current system + hostname and related + information. + + + + set-hostname [NAME] + + Set the system + hostname. By default this will alter + the pretty, the static, and the + transient hostname alike, however if + one or more of + , + , + are used + only the selected hostnames are + changed. If the pretty hostname is + being set, and static or transient are + being set as well the specified host + name will be simplified in regards to + the character set used before the + latter are updated. This is done by + replacing spaces by "-" and removing + special characters. This ensures that + the pretty and the static hostname + are always closely related while still + following the validity rules of the + specific name. This simplification of + the hostname string is not done if + only the transient and/or static host + names are set, and the pretty host + name is left untouched. Pass the empty + string "" as hostname to reset the + selected hostnames to their default + (usually + "localhost"). + + + + set-icon-name [NAME] + + Set the system icon + name. The icon name is used by some + graphical applications to visualize + this host. The icon name should follow + the Icon + Naming Specification. Pass an + empty string to this operation to + reset the icon name to the default + value which is determined from chassis + type (see below) and possibly other + parameters. + + + + set-chassis [TYPE] + + Set the chassis + type. The chassis type is used by some + graphical applications to visualize + the host or alter user + interaction. Currently, the following + chassis types are defined: + desktop, + laptop, + server, + tablet, + handset, as well as + the special chassis types + vm and + container for + virtualized systems that lack an + immediate physical chassis. Pass an + empty string to this operation to + reset the chassis type to the default + value which is determined from the + firmware and possibly other + parameters. + + + + + + + Exit status + + On success 0 is returned, a non-zero failure + code otherwise. + + + + See Also + + systemd1, + hostname1, + hostname5, + machine-info5, + systemctl1, + systemd-hostnamed.service8 + + + + diff --git a/man/journalctl.xml b/man/journalctl.xml new file mode 100644 index 000000000..959ae1efa --- /dev/null +++ b/man/journalctl.xml @@ -0,0 +1,584 @@ + + + + + + + + + journalctl + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + journalctl + 1 + + + + journalctl + Query the systemd journal + + + + + journalctl OPTIONS MATCHES + + + + + Description + + journalctl may be used to + query the contents of the + systemd1 + journal as written by + systemd-journald.service8. + + If called without parameter it will show the full + contents of the journal, starting with the oldest + entry collected. + + If one or more match arguments are passed the + output is filtered accordingly. A match is in the + format FIELD=VALUE, + e.g. _SYSTEMD_UNIT=httpd.service, + referring to the components of a structured journal + entry. See + systemd.journal-fields7 + for a list of well-known fields. If multiple matches + are specified matching different fields the log + entries are filtered by both, i.e. the resulting output + will show only entries matching all the specified + matches of this kind. If two matches apply to the same + field, then they are automatically matched as + alternatives, i.e. the resulting output will show + entries matching any of the specified matches for the + same field. Finally, if the character + "+" appears as separate word on the + command line all matches before and after are combined + in a disjunction (i.e. logical OR). + + As shortcuts for a few types of field/value + matches file paths may be specified. If a file path + refers to an executable file, this is equivalent to an + _EXE= match for the canonicalized + binary path. Similar, if a path refers to a device + node, this is equivalent to a + _KERNEL_DEVICE= match for the + device. + + Output is interleaved from all accessible + journal files, whether they are rotated or currently + being written, and regardless whether they belong to the + system itself or are accessible user journals. + + All users are granted access to their private + per-user journals. However, by default only root and + users who are members of the adm + group get access to the system journal and the + journals of other users. + + + + Options + + The following options are understood: + + + + + + + Prints a short help + text and exits. + + + + + + Prints a short version + string and exits. + + + + + + Do not pipe output into a + pager. + + + + + + Show all (printable) fields in + full. + + + + + + + Show all fields in + full, even if they include unprintable + characters or are very + long. + + + + + + + Show only the most recent + journal entries, and continuously print + new entries as they are appended to + the journal. + + + + + + + Show the most recent + journal events and limit the number of + events shown. If + is used, + this option is implied. The argument, + a positive integer, is optional, and + defaults to 10. + + + + + + Show all stored output + lines, even in follow mode. Undoes the + effect of + . + + + + + + + Controls the + formatting of the journal entries that + are shown. Takes one of + short, + short-monotonic, + verbose, + export, + json, + json-pretty, + json-sse, + cat. short + is the default and generates an output + that is mostly identical to the + formatting of classic syslog log + files, showing one line per journal + entry. short-monotonic + is very similar but shows monotonic + timestamps instead of wallclock + timestamps. verbose + shows the full structured entry items + with all + fields. export + serializes the journal into a binary + (but mostly text-based) stream + suitable for backups and network + transfer (see Journal + Export Format for more + information). json + formats entries as JSON data + structures, one per + line (see Journal + JSON Format for more + information). json-pretty + also formats entries as JSON data + structures, but formats them in + multiple lines in order to make them + more readable for + humans. json-sse + also formats entries as JSON data + structures, but wraps them in a format + suitable for Server-Sent + Events. cat + generates a very terse output only + showing the actual message of each + journal entry with no meta data, not + even a timestamp. + + + + + + + Augment log lines with + explanation texts from the message + catalog. This will add explanatory + help texts to log messages in the + output where this is available. These + short help texts will explain the + context of an error or log event, + possible solutions, as well as + pointers to support forums, developer + documentation and any other relevant + manuals. Note that help texts are not + available for all messages, but only + for selected ones. For more + information on the message catalog + please refer to the Message + Catalog Developer + Documentation. + + + + + + + Suppresses any warning + message regarding inaccessible system + journals when run as normal + user. + + + + + + + Show entries + interleaved from all available + journals, including remote + ones. + + + + + + + Show data only from + current boot. This will add a match + for _BOOT_ID= for + the current boot ID of the + kernel. + + + + + + + Show data only of the + specified unit. This will add a match + for _SYSTEMD_UNIT= + for the specified + unit. + + + + + + + Filter output by + message priorities or priority + ranges. Takes either a single numeric + or textual log level (i.e. between + 0/emerg and + 7/debug), or a + range of numeric/text log levels in + the form FROM..TO. The log levels are + the usual syslog log levels as + documented in + syslog3, + i.e. emerg (0), + alert (1), + crit (2), + err (3), + warning (4), + notice (5), + info (6), + debug (7). If a + single log level is specified all + messages with this log level or a + lower (hence more important) log level + are shown. If a range is specified all + messages within the range are shown, + including both the start and the end + value of the range. This will add + PRIORITY= matches + for the specified + priorities. + + + + + + + Start showing entries + from the location in the journal + specified by the passed + cursor. + + + + + + + Start showing entries + on or newer than the specified date, + or on or older than the specified + date, respectively. Date specifications should be of + the format "2012-10-30 18:17:16". If + the time part is omitted, 00:00:00 is + assumed. If only the seconds component + is omitted, :00 is assumed. If the + date component is omitted, the + current day is assumed. Alternatively + the strings + yesterday, + today, + tomorrow are + understood, which refer to 00:00:00 of + the day before the current day, the + current day, or the day after the + current day, respectively. now + refers to the current time. Finally, + relative times may be specified, + prefixed with - or + +, referring to + times before or after the current + time, respectively. + + + + + + + Print all possible + data values the specified field can + take in all entries of the + journal. + + + + + + + Takes an absolute + directory path as argument. If + specified journalctl will operate on the + specified journal directory instead of + the default runtime and system journal + paths. + + + + + + Instead of showing + journal contents generate a new 128 + bit ID suitable for identifying + messages. This is intended for usage + by developers who need a new + identifier for a new message they + introduce and want to make + recognizable. Will print the new ID in + three different formats which can be + copied into source code or + similar. + + + + + + Instead of showing + journal contents show internal header + information of the journal fields + accessed. + + + + + + Shows the current disk + usage of all + journal files. + + + + + + List the contents of + the message catalog, as table of + message IDs plus their short + description strings. + + + + + + Update the message + catalog index. This command needs to + be executed each time new catalog + files are installed, removed or + updated to rebuild the binary catalog + index. + + + + + + Instead of showing + journal contents generate a new key + pair for Forward Secure Sealing + (FSS). This will generate a sealing + key and a verification key. The + sealing key is stored in the journal + data directory and shall remain on the + host. The verification key should be + stored externally. + + + + + + Specifies the change + interval for the sealing key, when + generating an FSS key pair with + . Shorter + intervals increase CPU consumption but + shorten the time range of + undetectable journal + alterations. Defaults to + 15min. + + + + + + Check the journal file + for internal consistency. If the + file has been generated with FSS + enabled, and the FSS verification key + has been specified with + + authenticity of the journal file is + verified. + + + + + + Specifies the FSS + verification key to use for the + + operation. + + + + + + + Exit status + + On success 0 is returned, a non-zero failure + code otherwise. + + + + Environment + + + + $SYSTEMD_PAGER + Pager to use when + is not given; + overrides $PAGER. Setting + this to an empty string or the value + cat is equivalent to passing + . + + + + + + Examples + + Without arguments all collected logs are shown + unfiltered: + + journalctl + + With one match specified all entries with a field matching the expression are shown: + + journalctl _SYSTEMD_UNIT=avahi-daemon.service + + If two different fields are matched only entries matching both expressions at the same time are shown: + + journalctl _SYSTEMD_UNIT=avahi-daemon.service _PID=28097 + + If two matches refer to the same field all entries matching either expression are shown: + + journalctl _SYSTEMD_UNIT=avahi-daemon.service _SYSTEMD_UNIT=dbus.service + + If the separator "+" is used + two expressions may be combined in a logical OR. The + following will show all messages from the Avahi + service process with the PID 28097 plus all messages + from the D-Bus service (from any of its + processes): + + journalctl _SYSTEMD_UNIT=avahi-daemon.service _PID=28097 + _SYSTEMD_UNIT=dbus.service + + Show all logs generated by the D-Bus executable: + + journalctl /usr/bin/dbus-daemon + + Show all logs of the kernel device node /dev/sda: + + journalctl /dev/sda + + + + + See Also + + systemd1, + systemd-journald.service8, + systemctl1, + systemd.journal-fields7, + journald.conf5 + + + + diff --git a/man/journald.conf.xml b/man/journald.conf.xml new file mode 100644 index 000000000..30523c537 --- /dev/null +++ b/man/journald.conf.xml @@ -0,0 +1,411 @@ + + + + + + + + + journald.conf + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + journald.conf + 5 + + + + journald.conf + Journal service configuration file + + + + /etc/systemd/journald.conf + + + + Description + + This files configures various parameters of the + systemd journal service + systemd-journald.service8. + + + + + Options + + All options are configured in the + [Journal] section: + + + + + Storage= + + Controls where to + store journal data. One of + volatile, + persistent, + auto and + none. If + volatile journal + log data will be stored only in + memory, i.e. below the + /run/log/journal + hierarchy (which is created if + needed). If + persistent data will + be stored preferably on disk, + i.e. below the + /var/log/journal + hierarchy (which is created if + needed), with a fallback to + /run/log/journal + (which is created if needed), during + early boot and if the disk is not + writable. auto is + similar to + persistent but the + directory + /var/log/journal + is not created if needed, so that its + existence controls where log data + goes. none turns + off all storage, all log data received + will be dropped. Forwarding to other + targets, such as the console, the + kernel log buffer or a syslog daemon + will still work however. Defaults to + auto. + + + + Compress= + + Takes a boolean + value. If enabled (the default) data + objects that shall be stored in the + journal and are larger than a certain + threshold are compressed with the XZ + compression algorithm before they are + written to the file + system. + + + + Seal= + + Takes a boolean + value. If enabled (the default) and a + sealing key is available (as created + by + journalctl1's + + command), forward secure sealing (FSS) for + all persistent journal files is + enabled. + + + + SplitMode= + + Controls whether to + split up journal files per user. One + of login, + uid and + none. If + login each logged + in user will get his own journal + files, but systemd user IDs will log + into the system journal. If + uid any user ID + will get his own journal files + regardless whether it belongs to a + system service or refers to a real + logged in user. If + none journal files + are not split up per-user and all + messages are stored in the single + system journal. Note that splitting + up journal files per-user is only + available of journals are stored + persistently. If journals are stored + on volatile storage (see above) only a + single journal file for all user IDs + is kept. Defaults to + login. + + + + RateLimitInterval= + RateLimitBurst= + + Configures the rate + limiting that is applied to all + messages generated on the system. If + in the time interval defined by + RateLimitInterval= + more messages than specified in + RateLimitBurst= are + logged by a service all further + messages within the interval are + dropped, until the interval is over. A + message about the number of dropped + messages is generated. This rate + limiting is applied per-service, so + that two services which log do not + interfere with each others' + limits. Defaults to 200 messages in + 10s. The time specification for + RateLimitInterval= + may be specified in the following + units: s, + min, + h, + ms, + us. To turn off any + kind of rate limiting, set either + value to 0. + + + + SystemMaxUse= + SystemKeepFree= + SystemMaxFileSize= + RuntimeMaxUse= + RuntimeKeepFree= + RuntimeMaxFileSize= + + Enforce size limits on + the journal files stored. The options + prefixed with + System apply to the + journal files when stored on a + persistent file system, more + specifically + /var/log/journal. The + options prefixed with + Runtime apply to + the journal files when stored on a + volatile in-memory file system, more + specifically + /run/log/journal. The + former is used only when + /var is mounted, + writable and the directory + /var/log/journal + exists. Otherwise only the latter + applies. Note that this means that + during early boot and if the + administrator disabled persistent + logging only the latter options apply, + while the former apply if persistent + logging is enabled and the system is + fully booted + up. SystemMaxUse= + and RuntimeMaxUse= + control how much disk space the + journal may use up at + maximum. Defaults to 10% of the size + of the respective file + system. SystemKeepFree= + and + RuntimeKeepFree= + control how much disk space the + journal shall always leave free for + other uses if less than the disk space + configured in + SystemMaxUse= and + RuntimeMaxUse= is + available. Defaults to 5% of the size + of the respective file + system. SystemMaxFileSize= + and + RuntimeMaxFileSize= + control how large individual journal + files may grow at maximum. This + influences the granularity in which + disk space is made available through + rotation, i.e. deletion of historic + data. Defaults to one eighth of the + values configured with + SystemMaxUse= and + RuntimeMaxUse=, so + that usually seven rotated journal + files are kept as history. Specify + values in bytes or use K, M, G, T, P, + E as units for the specified + sizes. Note that size limits are + enforced synchronously to journal + files as they are extended, and need + no explicit rotation step triggered by + time. + + + + MaxFileSec= + + The maximum time to + store entries in a single journal + file, before rotating to the next + one. Normally time-based rotation + should not be required as size-based + rotation with options such as + SystemMaxFileSize= + should be sufficient to ensure that + journal files don't grow without + bounds. However, to ensure that not + too much data is lost at once when old + journal files are deleted it might + make sense to change this value from + the default of one month. Set to 0 to + turn off this feature. This setting + takes time values which may be + suffixed with the units year, month, + week, day, h, m to override the + default time unit of + seconds. + + + + MaxRetentionSec= + + The maximum time to + store journal entries. This + controls whether journal files + containing entries older then the + specified time span are + deleted. Normally time-based deletion + of old journal files should not be + required as size-based deletion with + options such as + SystemMaxUse= + should be sufficient to ensure that + journal files don't grow without + bounds. However, to enforce data + retention policies it might make sense + to change this value from the + default of 0 (which turns off this + feature). This setting also takes + time values which may be suffixed with + the units year, month, week, day, h, m + to override the default time unit of + seconds. + + + + ForwardToSyslog= + ForwardToKMsg= + ForwardToConsole= + + Control whether log + messages received by the journal + daemon shall be forwarded to a + traditional syslog daemon, to the + kernel log buffer (kmsg), or to the + system console. These options take + boolean arguments. If forwarding to + syslog is enabled but no syslog daemon + is running the respective option has + no effect. By default only forwarding + to syslog is enabled. These settings + may be overridden at boot time with + the kernel command line options + systemd.journald.forward_to_syslog=, + systemd.journald.forward_to_kmsg= + and + systemd.journald.forward_to_console=. + + + + + MaxLevelStore= + MaxLevelSyslog= + MaxLevelKMsg= + MaxLevelConsole= + + Controls the maximum + log level of messages that are stored + on disk, forwarded to syslog, kmsg or + the console (if that is enabled, see + above). As argument, takes one of + emerg, + alert, + crit, + err, + warning, + notice, + info, + debug or integer + values in the range of 0..7 (corresponding + to the same levels). Messages equal or below + the log level specified are + stored/forwarded, messages above are + dropped. Defaults to + debug for + MaxLevelStore= and + MaxLevelSyslog=, to + ensure that the all messages are + written to disk and forwarded to + syslog. Defaults to + notice for + MaxLevelKMsg= and + info for + MaxLevelConsole=. + + + + TTYPath= + + Change the console TTY + to use if + ForwardToConsole=yes + is used. Defaults to + /dev/console. + + + + + + + + See Also + + systemd1, + systemd-journald.service8, + journalctl1, + systemd.journal-fields7, + systemd.conf5 + + + + diff --git a/man/kernel-command-line.xml b/man/kernel-command-line.xml new file mode 100644 index 000000000..154d399d5 --- /dev/null +++ b/man/kernel-command-line.xml @@ -0,0 +1,295 @@ + + + + + + + + + kernel-command-line + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + kernel-command-line + 7 + + + + kernel-command-line + Kernel command line parameters + + + + /proc/cmdline + + + + Description + + The kernel, the initial RAM disk (initrd) and + basic userspace functionality may be configured at boot via + kernel command line arguments. + + For command line parameters understood by the + kernel please see kernel-parameters.txt + and + bootparam7. + + For command line parameters understood by the + initial RAM disk, please see + dracut.cmdline7, + or the documentation of the specific initrd + implementation of your installation. + + + + Core OS Command Line Arguments + + + + systemd.unit= + rd.systemd.unit= + systemd.dump_core= + systemd.crash_shell= + systemd.crash_chvt= + systemd.confirm_spawn= + systemd.show_status= + systemd.log_target= + systemd.log_level= + systemd.log_color= + systemd.log_location= + systemd.default_standard_output= + systemd.default_standard_error= + systemd.setenv= + + Parameters understood by + the system and service manager + to control system behavior. For details see + systemd1. + + + + + quiet + + Parameter understood by + both the kernel and the system + and service manager to control + console log verbosity. For + details see + systemd1. + + + + + emergency + single + s + S + 1 + 2 + 3 + 4 + 5 + + Parameters understood by + the system and service + manager, as compatibility + options. For details see + systemd1. + + + + + locale.LANG= + locale.LANGUAGE= + locale.LC_CTYPE= + locale.LC_NUMERIC= + locale.LC_TIME= + locale.LC_COLLATE= + locale.LC_MONETARY= + locale.LC_MESSAGES= + locale.LC_PAPER= + locale.LC_NAME= + locale.LC_ADDRESS= + locale.LC_TELEPHONE= + locale.LC_MEASUREMENT= + locale.LC_IDENTIFICATION= + + Parameters understood by + the system and service manager + to control locale and language + settings. For details see + systemd1. + + + + + fsck.mode= + + + Parameter understood by + the file system checker + services. For details see + systemd-fsck@.service8. + + + + + quotacheck.mode= + + + Parameter understood by + the file quota checker + service. For details see + systemd-quotacheck.service8. + + + + + systemd.journald.forward_to_syslog= + systemd.journald.forward_to_kmsg= + systemd.journald.forward_to_console= + + + Parameters understood by + the journal service. For + details see + systemd-journald.service8. + + + + + vconsole.keymap= + vconsole.keymap.toggle= + vconsole.font= + vconsole.font.map= + vconsole.font.unimap= + + + Parameters understood by + the virtual console setup logic. For + details see + systemd-vconsole-setup.service8. + + + + + udev.log-priority= + rd.udev.log-priority= + udev.children-max= + rd.udev.children-max= + udev.exec-delay= + rd.udev.exec-delay= + + + Parameters understood by + the device event managing daemon. For + details see + systemd-udevd.service8. + + + + + plymouth.enable= + + + May be used to disable + the Plymouth boot splash. For + details see + plymouth8. + + + + + luks= + rd.luks= + luks.crypttab= + rd.luks.crypttab= + luks.uuid= + rd.luks.uuid= + + + Configures the LUKS + full-disk encryption logic at + boot. For details see + systemd-cryptsetup-generator8. + + + + + fstab= + rd.fstab= + + + Configures the + /etc/fstab + logic at boot. For details see + systemd-fstab-generator8. + + + + + modules-load= + rd.modules-load= + + + Load a specific kernel + module early at boot. For + details see + systemd-modules-load.service8. + + + + + + + + + See Also + + systemd1, + bootparam7, + dracut.cmdline7, + systemd-fsck@.service8, + systemd-quotacheck.service8, + systemd-journald.service8, + systemd-vconsole-setup.service8, + systemd-udevd.service8, + plymouth8, + systemd-cryptsetup-generator8, + systemd-fstab-generator8, + systemd-modules-load.service8 + + + + diff --git a/man/locale.conf.xml b/man/locale.conf.xml new file mode 100644 index 000000000..06c0af0bf --- /dev/null +++ b/man/locale.conf.xml @@ -0,0 +1,149 @@ + + + + + + + + + locale.conf + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + locale.conf + 5 + + + + locale.conf + Configuration file for locale settings + + + + /etc/locale.conf + + + + Description + + The /etc/locale.conf file + configures system-wide locale settings. It is read at + early-boot by + systemd1. + + The basic file format of + locale.conf is a + newline-separated list of environment-like + shell-compatible variable assignments. It is possible + to source the configuration from shell scripts, + however, beyond mere variable assignments no shell + features are supported, allowing applications to read + the file without implementing a shell compatible + execution engine. + + Note that the kernel command line options + locale.LANG=, + locale.LANGUAGE=, + locale.LC_CTYPE=, + locale.LC_NUMERIC=, + locale.LC_TIME=, + locale.LC_COLLATE=, + locale.LC_MONETARY=, + locale.LC_MESSAGES=, + locale.LC_PAPER=, + locale.LC_NAME=, + locale.LC_ADDRESS=, + locale.LC_TELEPHONE=, + locale.LC_MEASUREMENT=, + locale.LC_IDENTIFICATION= may be + used to override the locale settings at boot. + + The locale settings configured in + /etc/locale.conf are system-wide + and are inherited by every service or user, unless + overridden or unset by individual programs or + individual users. + + Depending on the operating system other + configuration files might be checked for locale + configuration as well, however only as + fallback. + + + + Options + + The following locale settings may be set using + /etc/locale.conf: + LANG=, + LANGUAGE=, + LC_CTYPE=, + LC_NUMERIC=, + LC_TIME=, + LC_COLLATE=, + LC_MONETARY=, + LC_MESSAGES=, + LC_PAPER=, + LC_NAME=, + LC_ADDRESS=, + LC_TELEPHONE=, + LC_MEASUREMENT=, + LC_IDENTIFICATION=. Note that + LC_ALL may not be configured in + this file. For details about the meaning and semantics + of these settings, refer to + locale7. + + + + Example + + + German locale with English messages + + /etc/locale.conf: + + LANG=de_DE.UTF-8 +LC_MESSAGES=C + + + + + + See Also + + systemd1, + locale7, + systemd-localed.service8 + + + + diff --git a/man/localectl.xml b/man/localectl.xml new file mode 100644 index 000000000..33508cffe --- /dev/null +++ b/man/localectl.xml @@ -0,0 +1,259 @@ + + + + + + + + + localectl + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + localectl + 1 + + + + localectl + Control the system locale and keyboard layout settings + + + + + localectl OPTIONS COMMAND + + + + + Description + + localectl may be used to + query and change the system locale and keyboard layout + settings. + + The system locale controls the language settings + of system services and of the UI before the user logs + in, such as the display manager, as well as the + default for users after login. + + The keyboard settings control the keyboard + layout used on the text console and of the graphical + UI before the user logs in, such as the display + manager, as well as the default for users after + login. + + + + Options + + The following options are understood: + + + + + + + Prints a short help + text and exits. + + + + + + Prints a short version + string and exits. + + + + + + Do not pipe output into a + pager. + + + + + + Don't query the user + for authentication for privileged + operations. + + + + + + + Execute the operation + remotely. Specify a hostname, or + username and hostname separated by @, + to connect to. This will use SSH to + talk to a remote + system. + + + + + + If + set-keymap or + set-x11-keymap is + invoked and this option is passed then + the keymap will not be converted from + the console to X11, or X11 to console, + respectively. + + + + The following commands are understood: + + + + status + + Show current settings + of the system locale and keyboard + mapping. + + + + set-locale LOCALE... + + Set the system + locale. This takes one or more + assignments such as "LANG=de_DE.utf8", + "LC_MESSAGES=en_GB.utf8", and so + on. See + locale7 + for details on the available settings + and their meanings. Use + list-locales for a + list of available locales (see below). + + + + + list-locales + + List available locales + useful for configuration with + set-locale. + + + + set-keymap MAP [TOGGLEMAP] + + Set the system + keyboard mapping for the console. This + takes a keyboard mapping name (such as + "de" or "us"), and possibly a second + one to define a toggle keyboard + mapping. Unless + is + passed the selected setting is also + applied to the default keyboard + mapping of X11, after converting it to + the closest matching X11 keyboard + mapping. Use + list-locales for a + list of available keyboard mappings + (see below). + + + + list-keymaps + + List available + keyboard mappings for the console, + useful for configuration with + set-keyboard. + + + + set-x11-keymap LAYOUT [MODEL] [VARIANT] [OPTIONS] + + Set the system default + keyboard mapping for X11. This takes a + keyboard mapping name (such as "de" or + "us"), and possibly a model, variant + and options, see + kbd4 + for details. Unless + is + passed the selected setting is also + applied to the system console keyboard + mapping, after converting it to the + closest matching console keyboard + mapping. + + + + + + + + Exit status + + On success 0 is returned, a non-zero failure + code otherwise. + + + + Environment + + + + $SYSTEMD_PAGER + Pager to use when + is not given; + overrides $PAGER. Setting + this to an empty string or the value + cat is equivalent to passing + . + + + + + + See Also + + systemd1, + locale7, + locale.conf5, + vconsole.conf5, + loadkeys1, + kbd4, + systemctl1, + systemd-localed.service8 + + + + diff --git a/man/localtime.xml b/man/localtime.xml new file mode 100644 index 000000000..88c84a368 --- /dev/null +++ b/man/localtime.xml @@ -0,0 +1,103 @@ + + + + + + + + + /etc/localtime + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + Developer + Shawn + Landden + shawnlandden@gmail.com + + + + + + localtime + 5 + + + + localtime + Local time zone configuration file + + + + /etc/localtime -> ../usr/share/zoneinfo/… + + + + Description + + The /etc/localtime file + configures the system-wide time zone of the local + system that is used by applications for presentation + to the user. It should be an absolute or relative + symbolic link pointing to + /usr/share/zoneinfo/, followed by + a time zone identifier such as + Europe/Berlin or + Etc/UTC. The resulting link should + lead to the corresponding binary + tzfile5 + time zone data for the configured time zone. + + As the time zone identifier is extracted from + the symlink target name of + /etc/localtime this file may not + be a normal file or hardlink. + + The time zone may be overridden for individual + programs by using the TZ environment variable. See + environ7. + + You may use + timedatectl1 + to change the settings of this file from the command + line. + + + + See Also + + systemd1, + tzset3, + localtime3, + timedatectl1, + systemd-timedated.service8 + + + + diff --git a/man/loginctl.xml b/man/loginctl.xml new file mode 100644 index 000000000..5dbc1f696 --- /dev/null +++ b/man/loginctl.xml @@ -0,0 +1,474 @@ + + + + + + + + + loginctl + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + loginctl + 1 + + + + loginctl + Control the systemd login manager + + + + + loginctl OPTIONS COMMAND NAME + + + + + Description + + loginctl may be used to + introspect and control the state of the + systemd1 + login manager systemd-logind.service8. + + + + Options + + The following options are understood: + + + + + + + Prints a short help + text and exits. + + + + + + Prints a short version + string and exits. + + + + + + + When showing + session/user properties, limit + display to certain properties as + specified as argument. If not + specified all set properties are + shown. The argument should be a + property name, such as + Sessions. If + specified more than once all + properties with the specified names + are shown. + + + + + + + When showing + unit/job/manager properties, show all + properties regardless whether they are + set or not. + + + + + + + Do not pipe output into a + pager. + + + + + + Don't query the user + for authentication for privileged + operations. + + + + + + When used with + kill-session, + choose which processes to kill. Must + be one of , or + to select whether + to kill only the leader process of the + session or all processes of the + session. If omitted defaults to + . + + + + + + + When used with + kill-session or + kill-user, choose + which signal to send to selected + processes. Must be one of the well + known signal specifiers such as + SIGTERM, SIGINT or SIGSTOP. If omitted + defaults to + . + + + + + + + Execute operation + remotely. Specify a hostname, or + username and hostname separated by @, + to connect to. This will use SSH to + talk to the remote login manager + instance. + + + + + + + Acquire privileges via + PolicyKit before executing the + operation. + + + + The following commands are understood: + + + + list-sessions + + List current sessions. + + + + session-status [ID...] + + Show terse runtime + status information about one or more + sessions. This function is intended to + generate human-readable output. If you + are looking for computer-parsable + output, use + show-session + instead. + + + + show-session [ID...] + + Show properties of one + or more sessions or the manager + itself. If no argument is specified + properties of the manager will be + shown. If a session ID is specified + properties of the session is shown. By + default, empty properties are + suppressed. Use + to show those too. To select specific + properties to show use + . This + command is intended to be used + whenever computer-parsable output is + required. Use + session-status if + you are looking for formatted + human-readable + output. + + + + activate [ID...] + + Activate one or more + sessions. This brings one or more + sessions into the foreground, if + another session is currently in the + foreground on the respective + seat. + + + + lock-session [ID...] + unlock-session [ID...] + + Activates/deactivates + the screen lock on one or more + sessions, if the session supports it. + + + + lock-sessions + + Activate the screen + lock on all current sessions + supporting it. + + + + terminate-session [ID...] + + Terminates a + session. This kills all processes of + the session and deallocates all + resources attached to the + session. + + + + kill-session [ID...] + + Send a signal to one + or more processes of the session. Use + to select + which process to kill. Use + to select + the signal to send. + + + + list-users + + List currently logged + in users. + + + + user-status [USER...] + + Show terse runtime + status information about one or more + logged in users. This function is + intended to generate human-readable + output. If you are looking for + computer-parsable output, use + show-user + instead. Users may be specified by + their usernames or numeric user + IDs. + + + + show-user [USER...] + + Show properties of one + or more users or the manager + itself. If no argument is specified + properties of the manager will be + shown. If a user is specified + properties of the user is shown. By + default, empty properties are + suppressed. Use + to show those too. To select specific + properties to show use + . This + command is intended to be used + whenever computer-parsable output is + required. Use + user-status if + you are looking for formatted + human-readable + output. + + + + enable-linger [USER...] + disable-linger [USER...] + + Enable/disable user + lingering for one or more users. If + enabled for a specific user a user + manager is spawned for him/her at + boot, and kept around after + logouts. This allows users who aren't + logged in to run long-running + services. + + + + terminate-user [USER...] + + Terminates all + sessions of a user. This kills all + processes of all sessions of the user + and deallocates all runtime resources + attached to the + user. + + + + kill-user [USER...] + + Send a signal to all + processes of a user. Use + to select + the signal to send. + + + + list-seats + + List currently + available seats on the local + system. + + + + seat-status [NAME...] + + Show terse runtime + status information about one or more + seats. This function is + intended to generate human-readable + output. If you are looking for + computer-parsable output, use + show-seat + instead. + + + + show-seat [NAME...] + + Show properties of one + or more seats or the manager + itself. If no argument is specified + properties of the manager will be + shown. If a seat is specified + properties of the seat are shown. By + default, empty properties are + suppressed. Use + to show those too. To select specific + properties to show use + . This + command is intended to be used + whenever computer-parsable output is + required. Use + seat-status if you + are looking for formatted + human-readable + output. + + + + attach [NAME] [DEVICE...] + + Persistently attach + one or more devices to a seat. The + devices should be specified via device + paths in the /sys + file system. To create a new seat + attach at least one graphics card to a + previously unused seat name. Seat + names may consist only of a-z, A-Z, + 0-9, "-" and "_" and must be prefixed + with "seat". To drop assignment of a + device to a specific seat just + reassign it to a different seat, or + use + flush-devices. + + + + flush-devices + + Removes all device + assignments previously created with + attach. After this + call only automatically generated + seats will remain and all seat + hardware is assigned to + them. + + + + terminate-seat [NAME...] + + Terminates all + sessions on a seat. This kills all + processes of all sessions on a seat and + deallocates all runtime resources + attached to them. + + + + + + + Exit status + + On success 0 is returned, a non-zero failure + code otherwise. + + + + Environment + + + + $SYSTEMD_PAGER + Pager to use when + is not given; + overrides $PAGER. Setting + this to an empty string or the value + cat is equivalent to passing + . + + + + + + See Also + + systemd1, + systemctl1, + systemd-logind.service8, + logind.conf5 + + + + diff --git a/man/logind.conf.xml b/man/logind.conf.xml new file mode 100644 index 000000000..df15d51b5 --- /dev/null +++ b/man/logind.conf.xml @@ -0,0 +1,298 @@ + + + + + + + + + logind.conf + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + logind.conf + 5 + + + + logind.conf + Login manager configuration file + + + + /etc/systemd/logind.conf + + + + Description + + This file configures various parameters of the systemd login manager systemd-logind.service8. + + + + + Options + + All options are configured in the + [Login] section: + + + + + NAutoVTs= + + Takes a positive + integer. Configures how many virtual + terminals (VTs) to allocate by default + that -- when switched to and + previously unused -- + autovt services are + automatically spawned on. These + services are instantiated from the + template unit + autovt@.service + for the respective VT TTY name, + e.g. autovt@tty4.service. By + default + autovt@.service + is linked to + getty@.service, + i.e. login prompts are started + dynamically as the user switches to + unused virtual terminals. Hence, this + parameter controls how many login + gettys are + available on the VTs. If a VT is + already used by some other subsystem + (for example a graphical login) this + kind of activation will not be + attempted. Note that the VT configured + in ReserveVT= is + always subject to this kind of + activation, even if it is not one of + VTs configured with the + NAutoVTs= + directive. Defaults to 6. When set to + 0, automatic spawning of + autovt services is + disabled. + + + + ReserveVT= + + Takes a positive + integer. Configures the number of one + virtual terminal that shall + unconditionally be reserved for + autovt@.service + activation (see above). The VT + selected with this option will be + marked busy unconditionally so that no + other subsystem will allocate it. This + functionality is useful to ensure that + regardless how many VTs are allocated + by other subsystems one login + getty is always + available. Defaults to 6 (with other + words: there'll always be a + getty available on + Alt-F6.). When set to 0, VT + reservation is + disabled. + + + + KillUserProcesses= + + Takes a boolean + argument. Configures whether the + processes of a user should be killed + when she or he completely logs out (i.e. after + her/his last session ended). Defaults to + no. + + + + KillOnlyUsers= + KillExcludeUsers= + + These settings take + space separated lists of user names + that influence the effect of + KillUserProcesses=. If + not empty only processes of users + listed in + KillOnlyUsers will + be killed when they log out + entirely. Processes of users listed in + KillExcludeUsers= + are excluded from being + killed. KillExcludeUsers= + defaults to root + and takes precedence over + KillOnlyUsers= + which defaults to the empty list. + + + + Controllers= + ResetControllers= + + These settings control + the default control group hierarchies + users logging in are added to. When + logging in users will get private + control groups in all hierarchies + listed in + Controllers= and be + reset to the root control group in all + hierarchies listed in + ResetControllers=. Controllers= + defaults to the empty list, + ResetControllers= + defaults to + cpu. + + + + InhibitDelayMaxSec= + + Specifies the maximum + time a system shutdown or sleep + request is delayed due to an inhibitor + lock of type delay + being active -- before it is ignored + and the operation executed + anyway. Defaults to + 5s. + + + + HandlePowerKey= + HandleSuspendKey= + HandleHibernateKey= + HandleLidSwitch= + + Controls whether + logind shall handle the system power + and sleep keys and the lid switch to + trigger actions such as system + power-off or suspend. Can be one of + ignore, + poweroff, + reboot, + halt, + kexec, + suspend, + hibernate, + hybrid-sleep and + lock. If + ignore logind will + never handle these keys. If + lock all running + sessions will be screen + locked. Otherwise the specified action + will be taken in the respective + event. Only input devices with the + power-switch udev + tag will be watched for key/lid switch + events. HandlePowerKey= + defaults to + poweroff. + HandleSuspendKey= + and + HandleLidSwitch= + default to suspend. + HandleHibernateKey= + defaults to + hibernate. + + + + PowerKeyIgnoreInhibited= + SuspendKeyIgnoreInhibited= + HibernateKeyIgnoreInhibited= + LidSwitchIgnoreInhibited= + + Controls whether + actions triggered by the power and + sleep keys and the lid switch are + subject to inhibitor locks. These + settings take boolean arguments. If + off the inhibitor + locks taken by applications in order + to block the requested operation are + respected, if on + the requested operation is executed in + any + case. PowerKeyIgnoreInhibited=, + SuspendKeyIgnoreInhibited= + and + HibernateKeyIgnoreInhibited= + defaults to off, + LidSwitchIgnoreInhibited= + defaults to + yes. This means + that the lid switch does not respect + suspend blockers by default, but the + power and sleep keys do. + + + + + + Note that setting + KillUserProcesses=1 will break tools + like + screen1. + + Note that KillUserProcesses=1 + is a weaker version of + kill-session-processes=1 which may + be configured per-service for + pam_systemd8. The + latter kills processes of a session as soon as it + ends, the former kills processes as soon as the last + session of the user ends. + + + + See Also + + systemd1, + systemd-logind.service8, + loginctl1, + systemd.conf5 + + + + diff --git a/man/machine-id.xml b/man/machine-id.xml new file mode 100644 index 000000000..7d424b705 --- /dev/null +++ b/man/machine-id.xml @@ -0,0 +1,145 @@ + + + + + + + + + /etc/machine-id + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + machine-id + 5 + + + + machine-id + Local machine ID configuration file + + + + /etc/machine-id + + + + Description + + The /etc/machine-id file + contains the unique machine id of the local system + that is set during installation. The machine ID is a + single newline-terminated, hexadecimal, lowercase 32 + character machine ID string. (When decoded from + hexadecimal this corresponds with a 16 byte/128 bit + string.) + + The machine ID is usually generated from a + random source during system installation and stays + constant for all subsequent boots. Optionally, for + stateless systems it is generated during runtime at + boot if it is found to be empty. + + The machine ID does not change based on user + configuration, or when hardware is replaced. + + This machine ID adheres to the same format and + logic as the D-Bus machine ID. + + Programs may use this ID to identify the host + with a globally unique ID in the network, that does + not change even if the local network configuration + changes. Due to this and its greater length it is + a more useful replacement for the + gethostid3 + call POSIX specifies. + + The + systemd-machine-id-setup1 + tool may be used by installer tools to initialize the + machine ID at install time. + + + + Relation to OSF UUIDs + + Note that the machine ID historically is not an + OSF UUID as defined by RFC + 4122, nor a Microsoft GUID. Starting with + systemd v30 newly generated machine IDs however do + qualify as v4 UUIDs. + + In order to maintain compatibility with existing + installations, an application requiring a UUID should + decode the machine ID, and then apply the following + operations to turn it into a valid OSF v4 UUID. With + id being an unsigned character + array: + + /* Set UUID version to 4 --- truly random generation */ +id[6] = (id[6] & 0x0F) | 0x40; +/* Set the UUID variant to DCE */ +id[8] = (id[8] & 0x3F) | 0x80; + + (This code is inspired by + generate_random_uuid() of + drivers/char/random.c from the + kernel sources.) + + + + + History + + The simple configuration file format of + /etc/machine-id originates in the + /var/lib/dbus/machine-id file + introduced by D-Bus. In fact this latter file might be a + symlink to + /etc/machine-id. + + + + See Also + + systemd1, + systemd-machine-id-setup1, + gethostid3, + hostname5, + machine-info5, + os-release5, + sd-id1283, + sd_id128_get_machine3 + + + + diff --git a/man/machine-info.xml b/man/machine-info.xml new file mode 100644 index 000000000..1c3a21c64 --- /dev/null +++ b/man/machine-info.xml @@ -0,0 +1,183 @@ + + + + + + + + + machine-info + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + machine-info + 5 + + + + machine-info + Local machine information file + + + + /etc/machine-info + + + + Description + + The /etc/machine-info file + contains machine meta data. + + The basic file format of + machine-info is a + newline-separated list of environment-like + shell-compatible variable assignments. It is possible + to source the configuration from shell scripts, + however, beyond mere variable assignments no shell + features are supported, allowing applications to read + the file without implementing a shell compatible + execution engine. + + /etc/machine-info contains + meta data about the machine that is set by the user or + administrator. + + Depending on the operating system other + configuration files might be checked for machine + information as well, however only as fallback. + + You may use + hostnamectl1 + to change the settings of this file from the command + line. + + + + Options + + The following machine meta data parameters may + be set using + /etc/machine-info: + + + + + PRETTY_HOSTNAME= + + A pretty + human-readable UTF8 machine identifier + string. This should contain a name + like Lennart's + Laptop which is useful to + present to the user and does not + suffer by the syntax limitations of + internet domain names. If possible the + internet host name as configured in + /etc/hostname + should be kept similar to this + one. Example: if this value is + Lennart's Computer + an Internet host name of + lennarts-computer + might be a good choice. If this + parameter is not set an application + should fall back to the Internet host + name for presentation + purposes. + + + + ICON_NAME= + + An icon identifying + this machine according to the XDG + Icon Naming Specification. If + this parameter is not set an + application should fall back to + computer or a + similar icon name. + + + + CHASSIS= + + The chassis + type. Currently, the following chassis + types are defined: + desktop, + laptop, + server, + tablet, + handset, as well as + the special chassis types + vm and + container for + virtualized systems that lack an + immediate physical chassis. Note that + many systems allow detection of the + chassis type automatically (based on + firmware information or + suchlike). This setting (if set) shall + take precedence over automatically + detected information and is useful to + override misdetected configuration or + to manually configure the chassis type + where automatic detection is not + available. + + + + + + + + Example + + PRETTY_HOSTNAME="Lennart's Tablet" +ICON_NAME=computer-tablet +CHASSIS=tablet + + + + See Also + + systemd1, + os-release5, + hostname5, + machine-id5, + hostnamectl1, + systemd-hostnamed.service8 + + + + diff --git a/man/modules-load.d.xml b/man/modules-load.d.xml new file mode 100644 index 000000000..bcc4d1256 --- /dev/null +++ b/man/modules-load.d.xml @@ -0,0 +1,120 @@ + + + + + + + + modules-load.d + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + modules-load.d + 5 + + + + modules-load.d + Configure kernel modules to load at boot + + + + /etc/modules-load.d/*.conf + /run/modules-load.d/*.conf + /usr/lib/modules-load.d/*.conf + + + + Description + + systemd-modules-load.service8 + reads files from the above directories which contain + kernel modules to load during boot in a static list. + Each configuration file is named in the style of + /etc/modules-load.d/<program>.conf. Note + that it is usually a better idea to rely on the + automatic module loading by PCI IDs, USB IDs, DMI IDs + or similar triggers encoded in the kernel modules + themselves instead of static configuration like + this. In fact, most modern kernel modules are prepared + for automatic loading already. + + + + Configuration Format + + The configuration files should simply contain a + list of kernel module names to load, separated by + newlines. Empty lines and lines whose first + non-whitespace character is # or ; are ignored. + + Each configuration file shall be named in the + style of <program>.conf. + Files in /etc/ override files + with the same name in /usr/lib/ + and /run/. Files in + /run/ override files with the + same name in /usr/lib/. Packages + should install their configuration files in + /usr/lib/, files in + /etc/ are reserved for the local + administrator, who may use this logic to override the + configuration files installed from vendor + packages. + + If the administrator wants to disable a + configuration file supplied by the vendor the + recommended way is to place a symlink to + /dev/null in + /etc/modules-load.d/ bearing the + same file name. + + + + Example + + /etc/modules-load.d/virtio-net.conf example: + + # Load virtio-net.ko at boot +virtio-net + + + + + See Also + + systemd1, + systemd-modules-load.service8, + systemd-delta1, + modprobe8 + + + + diff --git a/man/os-release.xml b/man/os-release.xml new file mode 100644 index 000000000..98320efe3 --- /dev/null +++ b/man/os-release.xml @@ -0,0 +1,350 @@ + + + + + + + + + os-release + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + os-release + 5 + + + + os-release + Operating system identification + + + + /etc/os-release + + + + Description + + The /etc/os-release file + contains operating system identification data. + + The basic file format of + os-release is a newline-separated + list of environment-like shell-compatible variable + assignments. It is possible to source the + configuration from shell scripts, however, beyond mere + variable assignments no shell features are supported + (this means variable expansion is explicitly not + supported), allowing applications to read the file + without implementing a shell compatible execution + engine. Variable assignment values should be enclosed + in double or single quotes if they include spaces, + semicolons or other special characters outside of A-Z, + a-z, 0-9. All strings should be in UTF-8 format, and + non-printable characters should not be used. If double + or single quotes or backslashes are to be used within + variable assignments they should be escaped with + backslashes, following shell style. It is not + supported to concatenate multiple individually quoted + strings. Lines beginning with "#" shall be ignored as + comments. + + /etc/os-release contains + data that is defined by the operating system vendor + and should not be changed by the administrator. + + As this file only encodes names and identifiers + it should not be localized. + + The file /etc/os-release might + be a symlink to another file, but it is important that + the file is available from earliest boot on, and hence + must be located on the root file system. + + For a longer rationale for + /etc/os-release please refer to + the Announcement of /etc/os-release. + + + + Options + + The following OS identifications parameters may be set using + /etc/os-release: + + + + + NAME= + + A string identifying + the operating system, without a + version component, and suitable for + presentation to the user. If not set + defaults to + NAME=Linux. Example: + NAME=Fedora or + NAME="Debian + GNU/Linux". + + + + VERSION= + + A string identifying + the operating system version, + excluding any OS name information, + possibly including a release code + name, and suitable for presentation to + the user. This field is + optional. Example: + VERSION=17 or + VERSION="17 (Beefy + Miracle)". + + + + ID= + + A lower-case string + (no spaces or other characters outside + of 0-9, a-z, ".", "_" and "-") + identifying the operating system, + excluding any version information and + suitable for processing by scripts or + usage in generated file names. If not + set defaults to + ID=linux. Example: + ID=fedora or + ID=debian. + + + + ID_LIKE= + + A space-separated list + of operating system identifiers in the + same syntax as the + ID= setting. Should + list identifiers of operating systems + that are closely related to the local + operating system in regards to + packaging and programming interfaces, + for example listing one or more + OS identifiers the local + OS is a derivative from. An + OS should generally only list other OS + identifiers it itself is a derivative + from, and not any OSes that + are derived from it, but symmetric + relationships are possible. Build + scripts and similar should check this + variable if they need to identify the + local operating system and the value + of ID= is not + recognized. Operating systems should + be listed in order of how closely the + local operating system relates to the + listed ones, starting with the + closest. This field is + optional. Example: for an operating + system with + ID=centos an + assignment of ID_LIKE="rhel + fedora" would be + appropriate. For an operating system + with ID=ubuntu an + assignment of + ID_LIKE=debian is + appropriate. + + + + VERSION_ID= + + A lower-case string + (mostly numeric, no spaces or other + characters outside of 0-9, a-z, ".", + "_" and "-") identifying the operating + system version, excluding any OS name + information or release code name, and + suitable for processing by scripts or + usage in generated file names. This + field is optional. Example: + VERSION_ID=17 or + VERSION_ID=11.04. + + + + PRETTY_NAME= + + A pretty operating + system name in a format suitable for + presentation to the user. May or may + not contain a release code name or OS + version of some kind, as suitable. If + not set defaults to + PRETTY_NAME="Linux". Example: + PRETTY_NAME="Fedora 17 (Beefy + Miracle)". + + + + ANSI_COLOR= + + A suggested + presentation color when showing the + OS name on the console. This + should be specified as string suitable + for inclusion in the ESC [ m + ANSI/ECMA-48 escape code for setting + graphical rendition. This field is + optional. Example: + ANSI_COLOR="0;31" + for red, or + ANSI_COLOR="1;34" + for light blue. + + + + CPE_NAME= + + A CPE name for the + operating system, following the Common + Platform Enumeration + Specification as proposed by + the MITRE Corporation. This field + is optional. Example: + CPE_NAME="cpe:/o:fedoraproject:fedora:17" + + + + + HOME_URL= + SUPPORT_URL= + BUG_REPORT_URL= + + Links to resources on + the Internet related the operating + system. HOME_URL= + should refer to the homepage of the + operating system, or alternatively + some homepage of the specific version + of the operating + system. SUPPORT_URL= + should refer to the main support page + for the operating system, if there is + any. This is primarily intended for + operating systems which vendors + provide support + for. BUG_REPORT_URL= + should refer to the main bug reporting + page for the operating system, if + there is any. This is primarily + intended for operating systems that + rely on community QA. These settings + are optional, and providing only some + of these settings is common. These + URLs are intended to be exposed in + "About this system" UIs behind links + with captions such as "About this + Operating System", "Obtain Support", + and "Report a Bug". The values should + be in RFC3986 + format, and should be + http: or + https: URLs, and + possibly mailto: or + tel:. Only one URL + shall be listed in each setting. If + multiple resources need to be + referenced it is recommended to + provide an online landing page linking + all available resources. Examples: + HOME_URL="https://fedoraproject.org/" + and + BUG_REPORT_URL="https://bugzilla.redhat.com/" + + + + + + If you are reading this file from C code or a + shell script to determine the OS or a specific version + of it, use the ID and VERSION_ID fields, possibly with + ID_LIKE as fallback for ID. When looking for an OS + identification string for presentation to the user use + the PRETTY_NAME field. + + Note that operating system vendors may choose + not to provide version information, for example to + accommodate for rolling releases. In this case VERSION + and VERSION_ID may be unset. Applications should not + rely on these fields to be set. + + Operating system vendors may extend the file + format and introduce new fields. It is highly + recommended to prefix new fields with an OS specific + name in order to avoid name clashes. Applications + reading this file must ignore unknown fields. Example: + DEBIAN_BTS="debbugs://bugs.debian.org/" + + + + Example + + NAME=Fedora +VERSION="17 (Beefy Miracle)" +ID=fedora +VERSION_ID=17 +PRETTY_NAME="Fedora 17 (Beefy Miracle)" +ANSI_COLOR="0;34" +CPE_NAME="cpe:/o:fedoraproject:fedora:17" +HOME_URL="https://fedoraproject.org/" +BUG_REPORT_URL="https://bugzilla.redhat.com/" + + + + See Also + + systemd1, + lsb_release1, + hostname5, + machine-id5, + machine-info5 + + + + diff --git a/man/pam_systemd.xml b/man/pam_systemd.xml new file mode 100644 index 000000000..600bfd71b --- /dev/null +++ b/man/pam_systemd.xml @@ -0,0 +1,328 @@ + + + + + + + + + pam_systemd + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + pam_systemd + 8 + + + + pam_systemd + Register user sessions in the systemd login manager + + + + + pam_systemd.so + + + + + Description + + pam_systemd registers user + sessions in the systemd login manager + systemd-logind.service8, + and hence the systemd control group hierarchy. + + On login, this module ensures the following: + + + If it does not exist yet, the + user runtime directory + /run/user/$USER is + created and its ownership changed to the user + that is logging in. + + The + $XDG_SESSION_ID environment + variable is initialized. If auditing is + available and + pam_loginuid.so run before + this module (which is highly recommended), the + variable is initialized from the auditing + session id + (/proc/self/sessionid). Otherwise + an independent session counter is + used. + + A new control group + /user/$USER/$XDG_SESSION_ID + is created and the login process moved into + it. + + + On logout, this module ensures the following: + + + If + $XDG_SESSION_ID is set and + specified, all + remaining processes in the + /user/$USER/$XDG_SESSION_ID + control group are killed and the control group + is removed. + + If the last subgroup of the + /user/$USER control group + was removed the + $XDG_RUNTIME_DIR directory + and all its contents are + removed, too. + + + If the system was not booted up with systemd as + init system, this module does nothing and immediately + returns PAM_SUCCESS. + + + + + Options + + The following options are understood: + + + + + + Takes a boolean + argument. If true, all processes + created by the user during his session + and from his session will be + terminated when he logs out from his + session. + + + + + + Takes a comma + separated list of user names or + numeric user ids as argument. If this + option is used the effect of the + options + will apply only to the listed + users. If this option is not used the + option applies to all local + users. Note that + + takes precedence over this list and is + hence subtracted from the list + specified here. + + + + + + Takes a comma + separated list of user names or + numeric user ids as argument. Users + listed in this argument will not be + subject to the effect of + . Note + that this option takes precedence + over + , and + hence whatever is listed for + + is guaranteed to never be killed by + this PAM module, independent of any + other configuration + setting. + + + + + + Takes a comma + separated list of control group + controllers in which hierarchies a + user/session control group will be + created by default for each user + logging in, in addition to the control + group in the named 'name=systemd' + hierarchy. If omitted, defaults to an + empty list. + + + + + + Takes a comma + separated list of control group + controllers in which hierarchies the + logged in processes will be reset to + the root control + group. + + + + + + Takes a string + argument which sets the session class. + The XDG_SESSION_CLASS environmental variable + takes precedence. + + + + + + Takes a boolean + argument. If yes, the module will log + debugging information as it + operates. + + + + Note that setting + kill-session-processes=1 will break tools + like + screen1. + + Note that + kill-session-processes=1 is a + stricter version of + KillUserProcesses=1 which may be + configured system-wide in + logind.conf5. The + former kills processes of a session as soon as it + ends, the latter kills processes as soon as the last + session of the user ends. + + If the options are omitted they default to + , + , + , + , + , + . + + + + Module Types Provided + + Only is provided. + + + + Environment + + The following environment variables are set for the processes of the user's session: + + + + $XDG_SESSION_ID + + A session identifier, + suitable to be used in file names. The + string itself should be considered + opaque, although often it is just the + audit session ID as reported by + /proc/self/sessionid. Each + ID will be assigned only once during + machine uptime. It may hence be used + to uniquely label files or other + resources of this + session. + + + + $XDG_RUNTIME_DIR + + Path to a user-private + user-writable directory that is bound + to the user login time on the + machine. It is automatically created + the first time a user logs in and + removed on his final logout. If a user + logs in twice at the same time, both + sessions will see the same + $XDG_RUNTIME_DIR + and the same contents. If a user logs + in once, then logs out again, and logs + in again, the directory contents will + have been lost in between, but + applications should not rely on this + behavior and must be able to deal with + stale files. To store session-private + data in this directory the user should + include the value of $XDG_SESSION_ID + in the filename. This directory shall + be used for runtime file system + objects such as AF_UNIX sockets, + FIFOs, PID files and similar. It is + guaranteed that this directory is + local and offers the greatest possible + file system feature set the + operating system + provides. + + + + + + Example + + #%PAM-1.0 +auth required pam_unix.so +auth required pam_nologin.so +account required pam_unix.so +password required pam_unix.so +session required pam_unix.so +session required pam_loginuid.so +session required pam_systemd.so kill-session-processes=1 + + + + See Also + + systemd1, + systemd-logind.service8, + logind.conf5, + loginctl1, + pam.conf5, + pam.d5, + pam8, + pam_loginuid8 + + + + diff --git a/man/runlevel.xml b/man/runlevel.xml new file mode 100644 index 000000000..02d5371c5 --- /dev/null +++ b/man/runlevel.xml @@ -0,0 +1,154 @@ + + + + + + + + + runlevel + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + runlevel + 8 + + + + runlevel + Print previous and current SysV runlevel + + + + + runlevel options + + + + + Description + + runlevel prints the previous + and current SysV runlevel if they are known. + + The two runlevel characters are separated by a + single space character. If a runlevel cannot be + determined, N is printed instead. If neither can be + determined, the word "unknown" is printed. + + Unless overridden in the environment, this will + check the utmp database for recent runlevel + changes. + + + + Options + + The following option is understood: + + + + + + Prints a short help + text and exits. + + + + + + + Exit status + + If one or both runlevels could be determined, 0 + is returned, a non-zero failure code otherwise. + + + + + Environment + + + + $RUNLEVEL + + If + $RUNLEVEL is set, + runlevel will print + this value as current runlevel and + ignore utmp. + + + + $PREVLEVEL + + If + $PREVLEVEL is set + runlevel will print + this value as previous runlevel and + ignore utmp. + + + + + + Files + + + + /var/run/utmp + + The utmp database + runlevel reads the + previous and current runlevel + from. + + + + + + + Notes + + This is a legacy command available for compatibility + only. It should not be used anymore, as the concept of + runlevels is obsolete. + + + + See Also + + systemd1, + systemctl1 + + + + diff --git a/man/sd-daemon.xml b/man/sd-daemon.xml new file mode 100644 index 000000000..a3bf662fe --- /dev/null +++ b/man/sd-daemon.xml @@ -0,0 +1,180 @@ + + + + + + + + + sd-daemon + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + sd-daemon + 3 + + + + sd-daemon + SD_EMERG + SD_ALERT + SD_CRIT + SD_ERR + SD_WARNING + SD_NOTICE + SD_INFO + SD_DEBUG + Reference implementation of APIs for + new-style daemons + + + + + #include <systemd/sd-daemon.h> + + + + pkg-config --cflags --libs libsystemd-daemon + + + + + + Description + + sd-daemon.c and + sd-daemon.h provide a reference + implementation of various APIs for new-style daemons, + as implemented by the + systemd1 + init system. + + See + sd_listen_fds3, + sd_notify3, + sd_booted3, + sd_is_fifo3 + for more information about the functions + implemented. In addition to these functions a couple + of logging prefixes are defined as macros: + + #define SD_EMERG "<0>" /* system is unusable */ +#define SD_ALERT "<1>" /* action must be taken immediately */ +#define SD_CRIT "<2>" /* critical conditions */ +#define SD_ERR "<3>" /* error conditions */ +#define SD_WARNING "<4>" /* warning conditions */ +#define SD_NOTICE "<5>" /* normal but significant condition */ +#define SD_INFO "<6>" /* informational */ +#define SD_DEBUG "<7>" /* debug-level messages */ + + These prefixes are intended to be used in + conjunction with STDERR-based logging as implemented + by systemd. If a systemd service definition file is + configured with StandardError=syslog + or StandardError=kmsg these + prefixes can be used to encode a log level in lines + printed. This is similar to the kernel + printk()-style logging. See + klogctl2 + for more information. + + The log levels are identical to + syslog3's + log level system. To use these prefixes simply prefix + every line with one of these strings. A line that is + not prefixed will be logged at the default log level + SD_INFO. + + + Hello World + + A daemon may log with the log level + NOTICE by issuing this call: + + fprintf(stderr, SD_NOTICE "Hello World!\n"); + + + + + Notes + + These interfaces are provided by the reference + implementation of APIs for new-style daemons and + distributed with the systemd package. The algorithms + they implement are simple, and can easily be + reimplemented in daemons if it is important to support + this interface without using the reference + implementation. See the respective function man pages + for details. + + In addition, for details about the algorithms + check the liberally licensed reference implementation + sources: + + and + + These APIs are implemented in the reference + implementation's sd-daemon.c and + sd-daemon.h files. These + interfaces are available as shared library, which can + be compiled and linked to with the + libsystemd-daemon + pkg-config1 + file. Alternatively, applications consuming these APIs + may copy the implementation into their source tree, + either verbatim or in excerpts. + + The functions directly related to new-style + daemons become NOPs when -DDISABLE_SYSTEMD is set + during compilation and the reference implementation is + used as drop-in files. In addition, if + sd-daemon.c is compiled on + non-Linux systems they become NOPs. + + + + See Also + + systemd1, + sd_listen_fds3, + sd_notify3, + sd_booted3, + sd_is_fifo3, + daemon7, + systemd.service5, + systemd.socket5, + fprintf3, + sd-readahead3, + pkg-config1 + + + + diff --git a/man/sd-id128.xml b/man/sd-id128.xml new file mode 100644 index 000000000..ac2000e27 --- /dev/null +++ b/man/sd-id128.xml @@ -0,0 +1,181 @@ + + + + + + + + + sd-id128 + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + sd-id128 + 3 + + + + sd-id128 + sd_id128_t + SD_ID128_MAKE + SD_ID128_CONST_STR + SD_ID128_FORMAT_STR + SD_ID128_FORMAT_VAL + sd_id128_equal + APIs for processing 128 bit IDs + + + + + #include <systemd/sd-id128.h> + + + + pkg-config --cflags --libs libsystemd-id128 + + + + + + Description + + sd-id128.h provides APIs to + process and generate 128 bit ID values. The 128 bit ID + values processed and generated by these APIs are a + generalization of OSF UUIDs as defined by RFC + 4122, though use a simpler string + formatting. These functions impose no structure on the + used IDs, much unlike OSF UUIDs or Microsoft GUIDs, + but are fully compatible with those types of IDs. + + + See + sd_id128_to_string3, + sd_id128_randomize3 and + sd_id128_get_machine3 + for more information about the implemented + functions. + + A 128 bit ID is implemented as the following + union type: + + typedef union sd_id128 { + uint8_t bytes[16]; + uint64_t qwords[2]; +} sd_id128_t; + + This union type allows accessing the 128 bit ID + as 16 separate bytes or two 64 bit words. It is generally + safer to access the ID components by their 8 bit array + to avoid endianness issues. This union is intended to + be passed call-by-value (as opposed to + call-by-reference) and may be directly manipulated by + clients. + + A couple of macros are defined to denote and + decode 128 bit IDs: + + SD_ID128_MAKE() may be used + to denote a constant 128 bit ID in source code. A + commonly used idiom is to assign a name to a 128 bit + ID using this macro: + + #define SD_MESSAGE_COREDUMP SD_ID128_MAKE(fc,2e,22,bc,6e,e6,47,b6,b9,07,29,ab,34,a2,50,b1) + + SD_ID128_CONST_STR() may be + used to convert constant 128bit IDs into constant + strings for output. The following example code will + output the string + "fc2e22bc6ee647b6b90729ab34a250b1": + int main(int argc, char *argv[]) { + puts(SD_ID128_CONST_STR(SD_MESSAGE_COREDUMP)); +} + + SD_ID128_FORMAT_STR and + SD_ID128_FORMAT_VAL() may be used + to format a 128 bit ID in a + printf3 + format string, as shown in the following + example: + + int main(int argc, char *argv[]) { + sd_id128_t id; + id = SD_ID128_MAKE(ee,89,be,71,bd,6e,43,d6,91,e6,c5,5d,eb,03,02,07); + printf("The ID encoded in this C file is " SD_ID128_FORMAT_STR ".\n", SD_ID128_FORMAT_VAL(id)); + return 0; +} + + Use sd_id128_equal() to compare two 128 bit IDs: + + int main(int argc, char *argv[]) { + sd_id128_t a, b, c; + a = SD_ID128_MAKE(ee,89,be,71,bd,6e,43,d6,91,e6,c5,5d,eb,03,02,07); + b = SD_ID128_MAKE(f2,28,88,9c,5f,09,44,15,9d,d7,04,77,58,cb,e7,3e); + c = a; + assert(sd_id128_equal(a, c)); + assert(!sd_id128_equal(a, b)); + return 0; +} + + Note that new, randomized IDs may be generated + with + journalctl1's + --new-id option. + + + + Notes + + These APIs are implemented as a shared library, + which can be compiled and linked to with the + libsystemd-id128 + pkg-config1 + file. + + + + + See Also + + systemd1, + sd_id128_to_string3, + sd_id128_randomize3, + sd_id128_get_machine3, + printf3, + journalctl1, + sd-journal7, + pkg-config1, + machine-id5 + + + + diff --git a/man/sd-journal.xml b/man/sd-journal.xml new file mode 100644 index 000000000..a7220ec6b --- /dev/null +++ b/man/sd-journal.xml @@ -0,0 +1,132 @@ + + + + + + + + + sd-journal + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + sd-journal + 3 + + + + sd-journal + APIs for submitting and querying log entries to and from the journal + + + + + #include <systemd/sd-journal.h> + + + + pkg-config --cflags --libs libsystemd-journal + + + + + + Description + + sd-journal.h provides APIs + to submit and query log entries. The APIs exposed act + both as client for the + systemd-journald.service8 + journal service and as parser for the journal files + on disk. + + + See + sd_journal_print3, + sd_journal_stream_fd3, + sd_journal_open3, + sd_journal_next3, + sd_journal_get_realtime_usec3, + sd_journal_add_match3, + sd_journal_seek_head3, + sd_journal_get_cursor3, + sd_journal_cutoff_realtime_usec3, + sd_journal_get_usage3, + sd_journal_get_catalog3 + and + sd_journal_get_fd3 + for more information about the functions + implemented. + + Command line access for submitting entries to + the journal is available with the + systemd-cat1 + tool. Command line access for querying entries from + the journal is available with the + journalctl1 + tool. + + + + Notes + + These APIs are implemented as shared library, + which can be compiled and linked to with the + libsystemd-journal + pkg-config1 + file. + + + + See Also + + systemd1, + sd_journal_print3, + sd_journal_stream_fd3, + sd_journal_open3, + sd_journal_next3, + sd_journal_get_data3, + sd_journal_get_realtime_usec3, + sd_journal_add_match3, + sd_journal_seek_head3, + sd_journal_get_cursor3, + sd_journal_cutoff_realtime_usec3, + sd_journal_get_usage3, + sd_journal_get_fd3, + sd_journal_query_unique3, + sd_journal_get_catalog3, + journalctl1, + sd-id1283, + pkg-config1 + + + + diff --git a/man/sd-login.xml b/man/sd-login.xml new file mode 100644 index 000000000..c02ad0c14 --- /dev/null +++ b/man/sd-login.xml @@ -0,0 +1,146 @@ + + + + + + + + + sd-login + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + sd-login + 3 + + + + sd-login + APIs for + tracking logins + + + + + #include <systemd/sd-login.h> + + + + pkg-config --cflags --libs libsystemd-login + + + + + Description + + sd-login.h provides APIs to + introspect and monitor seat, login session and user + status information on the local system. + + See Multi-Seat + on Linux for an introduction into multi-seat + support on Linux, the background for this set of APIs. + + Note that these APIs only allow purely passive access + and monitoring of seats, sessions and users. To + actively make changes to the seat configuration, + terminate login sessions, or switch session on a seat + you need to utilize the D-Bus API of + systemd-logind, instead. + + These functions synchronously access data in + /proc, + /sys/fs/cgroup and + /run. All of these are virtual + file systems, hence the runtime cost of the accesses + is relatively cheap. + + It is possible (and often a very good choice) to + mix calls to the synchronous interface of + sd-login.h with the asynchronous + D-Bus interface of systemd-logind. However, if this is + done you need to think a bit about possible races + since the stream of events from D-Bus and from + sd-login.h interfaces such as the + login monitor are asynchronous and not ordered against + each other. + + If the functions return string arrays, these are + generally NULL terminated and need to be freed by the + caller with the libc + free3 + call after use, including the strings referenced + therein. Similar, individual strings returned need to + be freed, as well. + + As a special exception, instead of an empty + string array NULL may be returned, which should be + treated equivalent to an empty string array. + + See + sd_pid_get_session3, + sd_uid_get_state3, + sd_session_is_active3, + sd_seat_get_active3, + sd_get_seats3, + sd_login_monitor_new3 + for more information about the functions + implemented. + + + + Notes + + These APIs are implemented as shared library, + which can be compiled and linked to with the + libsystemd-login + pkg-config1 + file. + + + + See Also + + systemd1, + sd_pid_get_session3, + sd_uid_get_state3, + sd_session_is_active3, + sd_seat_get_active3, + sd_get_seats3, + sd_login_monitor_new3, + sd-daemon3, + sd-readahead3, + pkg-config1 + + + + diff --git a/man/sd-readahead.xml b/man/sd-readahead.xml new file mode 100644 index 000000000..cebaa5da2 --- /dev/null +++ b/man/sd-readahead.xml @@ -0,0 +1,117 @@ + + + + + + + + + sd-readahead + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + sd-readahead + 3 + + + + sd-readahead + Reference implementation of APIs for + controlling boot-time read-ahead + + + + + #include "sd-readahead.h" + + + + + Description + + sd-readahead.c and + sd-readahead.h provide a + reference implementation for APIs for controlling boot-time + read-ahead, as implemented by the read-ahead subsystem + of the + systemd1 + init system. + + See + sd_readahead3 + for more information about the function + implemented. + + + + Notes + + This interface is provided by the reference + implementation of APIs for controlling boot-time + read-ahead and distributed with the systemd + package. The algorithms it implements are simple, and + can easily be reimplemented in daemons if it is + important to support this interface without using the + reference implementation. See the respective function + man pages for details. + + In addition, for details about the algorithms + check the liberally licensed reference implementation + sources: + + and + + These APIs are implemented in the reference + implementation's drop-in + sd-readahead.c and + sd-readahead.h files. It is + recommended that applications consuming these APIs copy + the implementation into their source tree, either + verbatim or in excerpts. These interfaces are + currently not available in a dynamic library. + + The functions provided by this interface become + NOPs when -DDISABLE_SYSTEMD is set during + compilation. In addition, if + sd-readhead.c is compiled on + non-Linux systems it becomes NOPs. + + + + See Also + + systemd1, + sd_readahead3, + sd-daemon3 + + + + diff --git a/man/sd_booted.xml b/man/sd_booted.xml new file mode 100644 index 000000000..34f2cbfbc --- /dev/null +++ b/man/sd_booted.xml @@ -0,0 +1,128 @@ + + + + + + + + + sd_booted + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + sd_booted + 3 + + + + sd_booted + Test whether the system is running the systemd init system + + + + + #include <systemd/sd-daemon.h> + + + int sd_booted + void + + + + + + Description + sd_booted() checks whether + the system was booted up using the systemd init system. + + + + Return Value + + On failure, this call returns a negative + errno-style error code. If the system was booted up + with systemd as init system, this call returns a + positive return value, zero otherwise. + + + + Notes + + This function is provided by the reference + implementation of APIs for new-style daemons and + distributed with the systemd package. The algorithm it + implements is simple, and can easily be reimplemented + in daemons if it is important to support this + interface without using the reference + implementation. + + Internally, this function checks whether the + /sys/fs/cgroup/systemd virtual file + system is mounted, by comparing the st_dev value of + the stat() data of + /sys/fs/cgroup and + /sys/fs/cgroup/systemd. + + For details about the algorithm check the + liberally licensed reference implementation sources: + + and + + sd_booted() is implemented + in the reference implementation's + sd-daemon.c and + sd-daemon.h files. These + interfaces are available as shared library, which can + be compiled and linked to with the + libsystemd-daemon + pkg-config1 + file. Alternatively, applications consuming these APIs + may copy the implementation into their source + tree. For more details about the reference + implementation see + sd-daemon3. + + If the reference implementation is used as + drop-in files and -DDISABLE_SYSTEMD is set during + compilation this function will always return 0 and + otherwise become a NOP. + + + + See Also + + systemd1, + sd-daemon3 + + + + diff --git a/man/sd_get_seats.xml b/man/sd_get_seats.xml new file mode 100644 index 000000000..17adcef74 --- /dev/null +++ b/man/sd_get_seats.xml @@ -0,0 +1,129 @@ + + + + + + + + + sd_get_seats + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + sd_get_seats + 3 + + + + sd_get_seats + sd_get_sessions + sd_get_uids + Determine available seats, sessions and logged in users + + + + + #include <systemd/sd-login.h> + + + int sd_get_seats + char*** seats + + + + int sd_get_sessions + char*** sessions + + + + int sd_get_uids + char*** sessions + + + + + + + Description + + sd_get_seats() may be used + to determine all currently available local + seats. Returns a NULL terminated array of seat + identifiers. The returned array and all strings it + references need to be freed with the libc + free3 + call after use. Note that instead of an empty array + NULL may be returned and should be considered + equivalent to an empty array. + + Similar, sd_get_sessions() may + be used to determine all current login sessions. + + Similar, sd_get_uids() may + be used to determine all Unix users who currently have login sessions. + + Note that the returned lists are not sorted and in an undefined order. + + + + Return Value + + On success sd_get_seats(), + sd_get_sessions() and + sd_get_uids() return the number + of entries in the arrays. On failure, these calls + return a negative errno-style error code. + + + + Notes + + The sd_get_seats(), + sd_get_sessions() and + sd_get_uids() interfaces + are available as shared library, which can be compiled + and linked to with the + libsystemd-login + pkg-config1 + file. + + + + See Also + + + systemd1, + sd-login3, + sd_session_get_seat3 + + + + diff --git a/man/sd_id128_get_machine.xml b/man/sd_id128_get_machine.xml new file mode 100644 index 000000000..039c1dd64 --- /dev/null +++ b/man/sd_id128_get_machine.xml @@ -0,0 +1,138 @@ + + + + + + + + + sd_id128_get_machine + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + sd_id128_get_machine + 3 + + + + sd_id128_get_machine + sd_id128_get_boot + Retrieve 128 bit IDs + + + + + #include <systemd/sd-id128.h> + + + int sd_id128_get_machine + sd_id128_t* ret + + + + int sd_id128_get_boot + sd_id128_t* ret + + + + + + + Description + + sd_id128_get_machine() + returns the machine ID of the executing host. This + reads and parses the + machine-id5 + file. This function caches the machine ID internally + to make retrieving the machine ID a cheap + operation. + + sd_id128_get_boot() returns + the boot ID of the executing kernel. This reads and + parses the + /proc/sys/kernel/random/boot_id + file exposed by the kernel. It is randomly generated + early at boot and is unique for every running kernel + instance. See + random4 + for more information. This function also internally + caches the returned ID to make this call a cheap + operation. + + Note that + sd_id128_get_boot() always returns + a UUID v4 compatible + ID. sd_id128_get_machine() will + also return a UUID v4 compatible ID on new + installations, but might not on older. It is possible + to convert the machine ID into an UUID v4 compatible + one. For more information see + machine-id5. + + For more information about the + sd_id128_t type see + sd-id1283. + + + + Return Value + + The two calls return 0 on success (in which + case ret is filled in), or a + negative errno-style error code. + + + + Notes + + The sd_id128_get_machine() + and sd_id128_get_boot() + interfaces are available as shared library, which can + be compiled and linked to with the + libsystemd-id128 + pkg-config1 + file. + + + + See Also + + + systemd1, + sd-id1283, + machine-id5, + random4, + sd_id128_randomize3 + + + + diff --git a/man/sd_id128_randomize.xml b/man/sd_id128_randomize.xml new file mode 100644 index 000000000..be74937dd --- /dev/null +++ b/man/sd_id128_randomize.xml @@ -0,0 +1,118 @@ + + + + + + + + + sd_id128_randomize + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + sd_id128_randomize + 3 + + + + sd_id128_randomize + Generate 128 bit IDs + + + + + #include <systemd/sd-id128.h> + + + int sd_id128_randomize + sd_id128_t* ret + + + + + + + Description + + sd_id128_randomize() + generates a new randomized 128 bit ID and returns it + in ret. Every invocation + returns a new randomly generated ID. This uses the + /dev/urandom kernel random number + generator. + + Note that + sd_id128_randomize() always returns + a UUID v4 compatible + ID. + + For more information about the + sd_id128_t type see + sd-id1283. + + journalctl1's + --new-id command may be used as + command line front-end for + sd_id128_randomize(). + + + + Return Value + + The call returns 0 on success (in which + case ret is filled in), or a + negative errno-style error code. + + + + Notes + + The sd_id128_randomize() interface + is available as shared library, which can be compiled + and linked to with the + libsystemd-id128 + pkg-config1 + file. + + + + See Also + + + systemd1, + sd-id1283, + machine-id5, + random4, + sd_id128_get_machine3 + + + + diff --git a/man/sd_id128_to_string.xml b/man/sd_id128_to_string.xml new file mode 100644 index 000000000..ec8b263e0 --- /dev/null +++ b/man/sd_id128_to_string.xml @@ -0,0 +1,131 @@ + + + + + + + + + sd_id128_to_string + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + sd_id128_to_string + 3 + + + + sd_id128_to_string + sd_id128_from_string + Format or parse 128 bit IDs as strings + + + + + #include <systemd/sd-id128.h> + + + char* sd_id128_to_string + sd_id128_t id, char s[33] + + + + int sd_id128_from_string + const char s[33], sd_id128_t* ret + + + + + + + Description + + sd_id128_to_string() + formats a 128 bit ID as character string. It expects + the ID and a string array capable of storing 33 + characters. The ID will be formatted as 32 lowercase + hexadecimal digits and be terminated by a NUL + byte. + + sd_id128_from_string() + implements the reverse operation: it takes a 33 + character array with 32 hexadecimal digits + (terminated by NUL) and parses them back into an + 128 bit ID returned in + ret. + + For more information about the + sd_id128_t type see + sd-id1283. + + When formatting a 128 bit ID into a string it is + often easier to use a format string for + printf3. This + is easily done using the + SD_ID128_FORMAT_STR and + SD_ID128_FORMAT_VAL() macros. For + more information see + sd-id1283. + + + + Return Value + + sd_id128_to_string() always + succeeds and returns a pointer to the string array + passed in. sd_id128_from_string + returns 0 on success (in which case + ret is filled in), or a negative + errno-style error code. + + + + Notes + + The sd_id128_to_string() + and sd_id128_from_string() interfaces are + available as shared library, which can be compiled and + linked to with the libsystemd-id128 + pkg-config1 + file. + + + + See Also + + + systemd1, + sd-id1283, + printf3 + + + + diff --git a/man/sd_is_fifo.xml b/man/sd_is_fifo.xml new file mode 100644 index 000000000..595c8f112 --- /dev/null +++ b/man/sd_is_fifo.xml @@ -0,0 +1,217 @@ + + + + + + + + + sd_is_fifo + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + sd_is_fifo + 3 + + + + sd_is_fifo + sd_is_socket + sd_is_socket_inet + sd_is_socket_unix + sd_is_mq + Check the type of a file descriptor + + + + + #include <systemd/sd-daemon.h> + + + int sd_is_fifo + int fd + const char *path + + + + int sd_is_socket + int fd + int family + int type + int listening + + + + int sd_is_socket_inet + int fd + int family + int type + int listening + uint16_t port + + + + int sd_is_socket_unix + int fd + int type + int listening + const char* path + size_t length + + + + int sd_is_mq + int fd + const char *path + + + + + + + Description + + sd_is_fifo() may be called + to check whether the specified file descriptor refers + to a FIFO or pipe. If the path + parameter is not NULL, it is checked whether the FIFO + is bound to the specified file system path. + + sd_is_socket() may be + called to check whether the specified file descriptor + refers to a socket. If the + family parameter is not + AF_UNSPEC it is checked whether the socket is of the + specified family (AF_UNIX, AF_INET, ...). If the + type parameter is not 0 it is + checked whether the socket is of the specified type + (SOCK_STREAM, SOCK_DGRAM, ...). If the + listening parameter is positive + it is checked whether the socket is in accepting mode, + i.e. listen() has been called for + it. If listening is 0, it is + checked whether the socket is not in this mode. If the + parameter is negative, no such check is made. The + listening parameter should only + be used for stream sockets and should be set to a + negative value otherwise. + + sd_is_socket_inet() is + similar to sd_is_socket(), but + optionally checks the IPv4 or IPv6 port number the + socket is bound to, unless port + is zero. For this call family + must be passed as either AF_UNSPEC, AF_INET, or + AF_INET6. + + sd_is_socket_unix() is + similar to sd_is_socket(), but + optionally checks the AF_UNIX path the socket is bound + to, unless the path parameter + is NULL. For normal file system AF_UNIX sockets set + the length parameter to 0. For + Linux abstract namespace sockets set the + length to the size of the + address, including the initial 0 byte and set + path to the initial 0 byte of + the socket address. + + sd_is_mq() may be called to + check whether the specified file descriptor refers to + a POSIX message queue. If the + path parameter is not NULL, it + is checked whether the message queue is bound to the + specified name. + + + + Return Value + + On failure, these calls return a negative + errno-style error code. If the file descriptor is of + the specified type and bound to the specified address + a positive return value is returned, otherwise + zero. + + + + Notes + + These functions are provided by the reference + implementation of APIs for new-style daemons and + distributed with the systemd package. The algorithms + they implement are simple, and can easily be + reimplemented in daemons if it is important to support + this interface without using the reference + implementation. + + Internally, these function use a combination of + fstat() and + getsockname() to check the file + descriptor type and where it is bound to. + + For details about the algorithms check the + liberally licensed reference implementation sources: + + and + + sd_is_fifo() and the + related functions are implemented in the reference + implementation's sd-daemon.c and + sd-daemon.h files. These + interfaces are available as shared library, which can + be compiled and linked to with the + libsystemd-daemon + pkg-config1 + file. Alternatively, applications consuming these APIs + may copy the implementation into their source + tree. For more details about the reference + implementation see + sd-daemon3. + + These functions continue to work as described, + even if -DDISABLE_SYSTEMD is set during + compilation. + + + + See Also + + systemd1, + sd-daemon3, + sd_listen_fds3, + systemd.service5, + systemd.socket5 + + + + diff --git a/man/sd_journal_add_match.xml b/man/sd_journal_add_match.xml new file mode 100644 index 000000000..ad2486d74 --- /dev/null +++ b/man/sd_journal_add_match.xml @@ -0,0 +1,189 @@ + + + + + + + + + sd_journal_add_match + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + sd_journal_add_match + 3 + + + + sd_journal_add_match + sd_journal_add_disjunction + sd_journal_flush_matches + Add or remove entry matches + + + + + #include <systemd/sd-journal.h> + + + int sd_journal_add_match + sd_journal* j + const void* data + size_t size + + + + int sd_journal_add_disjunction + sd_journal* j + + + + int sd_journal_flush_matches + sd_journal* j + + + + + + Description + + sd_journal_add_match() adds + a match by which to filter the entries of the journal + file. Matches applied with this call will filter what + can be iterated through and read from the journal file + via calls like + sd_journal_next3 + and + sd_journal_get_data3. Matches + are of the form FIELD=value, where + the field part is a short uppercase string consisting + only of 0-9, A-Z and the underscore. It may not begin + with two underscores or be the empty string. The value + part may be any value, including binary. If a match is + applied only entries with this field set will be + iterated. Multiple matches may be active at the same + time: if they apply to different fields only entries + with both fields set like this will be iterated, if + they apply to the same fields only entries where the + field takes one of the specified values will be + iterated. Well known fields are documented in + systemd.journal-fields7. Whenever + a new match is added the current entry position is + reset, and + sd_journal_next3 (or a similar call) + needs to be called before entries can be read + again. + + sd_journal_add_disjunction() + may be used to insert a disjunction (i.e. logical OR) + in the match list. If this call is invoked all + previously added matches are combined in an OR with + all matches added afterwards, until + sd_journal_add_disjunction() is + invoked again to begin the next OR term. The + combination of + sd_journal_add_match() and + sd_journal_add_disjunction() may + be used to build complex search terms, even though + full logical expressions are not available. + + sd_journal_flush_matches() + may be used to flush all matches and disjunction terms + again. After this call all filtering is removed and + all entries in the journal will be iterated + again. + + Note that filtering via matches only applies to + the way the journal is read, it has no effect on storage + on disk. + + + + Return Value + + sd_journal_add_match() and + sd_journal_add_disjunction() + return 0 on success or a negative errno-style error + code. sd_journal_flush_matches() + returns nothing. + + + + Notes + + The sd_journal_add_match(), + sd_journal_add_disjunction() and + sd_journal_flush_matches() interfaces are + available as shared library, which can be compiled and + linked to with the + libsystemd-journal + pkg-config1 + file. + + + + Examples + + The following example adds matches to a journal + context object to iterate only through messages + generated by the Avahi service at the four error log + levels, plus all messages of the message ID + 03bb1dab98ab4ecfbf6fff2738bdd964 coming from any + service (this example lacks the necessary error + checking): + + ... +int add_matches(sd_journal *j) { + sd_journal_add_match(j, "_SYSTEMD_UNIT=avahi-daemon.service", 0); + sd_journal_add_match(j, "PRIORITY=0", 0); + sd_journal_add_match(j, "PRIORITY=1", 0); + sd_journal_add_match(j, "PRIORITY=2", 0); + sd_journal_add_match(j, "PRIORITY=3", 0); + sd_journal_add_disjunction(j); + sd_journal_add_match(j, "MESSAGE_ID=03bb1dab98ab4ecfbf6fff2738bdd964", 0); +} + + + + + See Also + + + systemd1, + sd-journal3, + sd_journal_open3, + sd_journal_next3, + sd_journal_get_data3, + systemd.journal-fields7 + + + + diff --git a/man/sd_journal_get_catalog.xml b/man/sd_journal_get_catalog.xml new file mode 100644 index 000000000..fa9bbc9b2 --- /dev/null +++ b/man/sd_journal_get_catalog.xml @@ -0,0 +1,136 @@ + + + + + + + + + sd_journal_get_catalog + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + sd_journal_get_catalog + 3 + + + + sd_journal_get_catalog + sd_journal_get_catalog_for_message_id + Retrieve message catalog entry + + + + + #include <systemd/sd-journal.h> + + + int sd_journal_get_catalog + sd_journal* j + const char** ret + + + + int sd_journal_get_catalog_for_message_id + sd_id128_t id + const char** ret + + + + + + + + Description + + sd_journal_get_catalog() + retrieves a message catalog entry for the current + journal entry. This will look up an entry in the + message catalog by using the + MESSAGE_ID= field of the current + journal entry. Before returning the entry all journal + field names in the catalog entry text enclosed in "@" + will be replaced by the respective field values of the + current entry. If a field name referenced in the + message catalog entry does not exist it the current + journal entry the "@" will be removed but the field + name otherwise left untouched. + + sd_journal_get_catalog_for_message_id() + works similar to + sd_journal_get_catalog() but the + entry is looked up by the specified message ID (no + open journal context is necessary for this), and no + field substitution is done. + + For more information about the journal message + catalog please refer to the Journal + Message Catalogs documentation page. + + + + Return Value + + sd_journal_get_catalog() + and + sd_journal_get_catalog_for_message_id() + returns 0 on success or a negative errno-style error + code. If no matching message catalog entry is found + -ENOENT is returned. + + + + Notes + + The sd_journal_get_catalog() and + sd_journal_get_catalog_for_message_id() + interfaces are available as shared library, which can + be compiled and linked to with the + libsystemd-journal + pkg-config1 + file. + + + + See Also + + + systemd1, + systemd.journal-fields7, + sd-journal3, + sd_journal_open3, + sd_journal_next3, + sd_journal_get_data3 + + + + diff --git a/man/sd_journal_get_cursor.xml b/man/sd_journal_get_cursor.xml new file mode 100644 index 000000000..354168bee --- /dev/null +++ b/man/sd_journal_get_cursor.xml @@ -0,0 +1,151 @@ + + + + + + + + + sd_journal_get_cursor + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + sd_journal_get_cursor + 3 + + + + sd_journal_get_cursor + sd_journal_test_cursor + Get cursor string for or test cursor string against the current journal entry + + + + + #include <systemd/sd-journal.h> + + + int sd_journal_get_cursor + sd_journal* j + char ** cursor + + + + int sd_journal_test_cursor + sd_journal* j + const char * cursor + + + + + + + Description + + sd_journal_get_cursor() + returns a cursor string for the current journal + entry. A cursor is a serialization of the current + journal position formatted as text. The string only + contains printable characters and can be passed around + in text form. The cursor identifies a journal entry + globally and in a stable way and may be used to later + seek to it via + sd_journal_seek_cursor3. The + cursor string should be considered opaque and not be + parsed by clients. Seeking to a cursor position + without the specific entry being available locally + will seek to the next closest (in terms of time) + available entry. The call takes two arguments: a + journal context object and a pointer to a string + pointer where the cursor string will be placed. The + string is allocated via libc + malloc3 + and should be freed after use with + free3. + + Note that + sd_journal_get_cursor() will not + work before + sd_journal_next3 + (or related call) has been called at least once, in + order to position the read pointer at a valid + entry. + + sd_journal_test_cursor() + may be used to check whether the current position in + the journal matches the specified cursor. This is + useful since cursor strings do not uniquely identify + an entry: the same entry might be referred to by + multiple different cursor strings, and hence string + comparing cursors is not possible. Use this call to + verify after an invocation of + sd_journal_seek_cursor3 + whether the entry being seeked to was actually found + in the journal or the next closest entry was used + instead. + + + + Return Value + + sd_journal_get_cursor() + returns 0 on success or a negative errno-style error + code. sd_journal_test_cursor() + returns positive if the current entry matches the + specified cursor, 0 if it doesn't match the specified + cursor or a negative errno-style error code on + failure. + + + + Notes + + The sd_journal_get_cursor() + and sd_journal_test_cursor() + interfaces are available as shared library, which can + be compiled and linked to with the + libsystemd-journal + pkg-config1 + file. + + + + See Also + + + systemd1, + sd-journal3, + sd_journal_open3, + sd_journal_seek_cursor3 + + + + diff --git a/man/sd_journal_get_cutoff_realtime_usec.xml b/man/sd_journal_get_cutoff_realtime_usec.xml new file mode 100644 index 000000000..ed014cb50 --- /dev/null +++ b/man/sd_journal_get_cutoff_realtime_usec.xml @@ -0,0 +1,142 @@ + + + + + + + + + sd_journal_get_cutoff_realtime_usec + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + sd_journal_get_cutoff_realtime_usec + 3 + + + + sd_journal_get_cutoff_realtime_usec + sd_journal_get_cutoff_monotonic_usec + Read cut-off timestamps from the current journal entry + + + + + #include <systemd/sd-journal.h> + + + int sd_journal_get_cutoff_realtime_usec + sd_journal* j + uint64_t* from + uint64_t* to + + + + int sd_journal_get_cutoff_monotonic_usec + sd_journal* j + sd_id128_t boot_id + uint64_t* from + uint64_t* to + + + + + + + Description + + sd_journal_get_cutoff_realtime_usec() + gets the realtime (wallclock) timestamps of the first + and last entries accessible in the journal. It takes + three arguments: the journal context object and two + pointers to 64 Bit unsigned integers to store the + timestamps in. The timestamps are in microseconds + since the epoch, i.e. CLOCK_REALTIME. Either one of + the two timestamp arguments may be passed as NULL in + case the timestamp is not needed, but not both. + + sd_journal_get_cutoff_monotonic_usec() + gets the monotonic timestamps of the first and last + entries accessible in the journal. It takes three + arguments: the journal context object, a 128 Bit + identifier for the boot, and two pointers to 64 Bit + unsigned integers to store the timestamps. The + timestamps are in microseconds since boot-up of the + specific boot, i.e. CLOCK_MONOTONIC. Since the + monotonic clock begins new with every reboot it only + defines a well-defined point in time when used + together with an identifier identifying the boot, see + sd_id128_get_boot3 + for more information. The function will return the + timestamps for the boot identified by the passed boot + ID. Either one of the two timestamp arguments may be + passed as NULL in case the timestamp is not needed, + but not both. + + + + Return Value + + sd_journal_get_cutoff_realtime_usec() + and + sd_journal_get_cutoff_monotonic_usec() + return 1 on success, 0 if not suitable entries are in + the journal or a negative errno-style error code. + + + + Notes + + The + sd_journal_get_cutoff_realtime_usec() + and + sd_journal_get_cutoff_monotonic_usec() + interfaces are available as shared library, which can + be compiled and linked to with the + libsystemd-journal + pkg-config1 + file. + + + + See Also + + + systemd1, + sd-journal3, + sd_journal_open3, + sd_journal_get_realtime_usec3, + sd_id128_get_boot3, + clock_gettime2 + + + + diff --git a/man/sd_journal_get_data.xml b/man/sd_journal_get_data.xml new file mode 100644 index 000000000..1259b0cdb --- /dev/null +++ b/man/sd_journal_get_data.xml @@ -0,0 +1,251 @@ + + + + + + + + + sd_journal_get_data + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + sd_journal_get_data + 3 + + + + sd_journal_get_data + sd_journal_enumerate_data + sd_journal_restart_data + SD_JOURNAL_FOREACH_DATA + sd_journal_set_data_threshold + sd_journal_get_data_threshold + Read data fields from the current journal entry + + + + + #include <systemd/sd-journal.h> + + + int sd_journal_get_data + sd_journal* j + const char* field + const void** data + size_t* length + + + + int sd_journal_enumerate_data + sd_journal* j + const void** data + size_t* length + + + + void sd_journal_restart_data + sd_journal* j + + + + SD_JOURNAL_FOREACH_DATA + sd_journal* j + const void* data + size_t length + + + + int sd_journal_set_data_threshold + sd_journal* j + size_t sz + + + + int sd_journal_get_data_threshold + sd_journal* j + size_t* sz + + + + + + Description + + sd_journal_get_data() gets + the data object associated with a specific field from + the current journal entry. It takes four arguments: + the journal context object, a string with the field + name to request, plus a pair of pointers to + pointer/size variables where the data object and its + size shall be stored in. The field name should be an + entry field name. Well-known field names are listed in + systemd.journal-fields7. The + returned data is in a read-only memory map and is only + valid until the next invocation of + sd_journal_get_data() or + sd_journal_enumerate_data(), or + the read pointer is altered. Note that the data + returned will be prefixed with the field name and + '='. Also note that by default data fields larger than + 64K might get truncated to 64K. This threshold may be + changed and turned off with + sd_journal_set_data_threshold() (see + below). + + sd_journal_enumerate_data() + may be used to iterate through all fields of the + current entry. On each invocation the data for the + next field is returned. The order of these fields is + not defined. The data returned is in the same format + as with sd_journal_get_data() and + also follows the same life-time semantics. + + sd_journal_restart_data() + resets the data enumeration index to the beginning of + the entry. The next invocation of + sd_journal_enumerate_data() will return the first + field of the entry again. + + Note that the + SD_JOURNAL_FOREACH_DATA() macro + may be used as a handy wrapper around + sd_journal_restart_data() and + sd_journal_enumerate_data(). + + Note that these functions will not work before + sd_journal_next3 + (or related call) has been called at least + once, in order to position the read pointer at a valid entry. + + sd_journal_set_data_threshold() + may be used to change the data field size threshold + for data returned by + sd_journal_get_data(), + sd_journal_enumerate_data() and + sd_journal_enumerate_unique(). This + threshold is a hint only: it indicates that the client + program is interested only in the initial parts of the + data fields, up to the threshold in size -- but the + library might still return larger data objects. That + means applications should not rely exclusively on this + setting to limit the size of the data fields returned, + but need to apply a explicit size limit on the + returned data as well. This threshold defaults to 64K + by default. To retrieve the complete data fields this + threshold should be turned off by setting it to 0, so + that the library always returns the complete data + objects. It is recommended to set this threshold as + low as possible since this relieves the library from + having to decompress large compressed data objects in + full. + + sd_journal_get_data_threshold() + returns the currently configured data field size + threshold. + + + + Return Value + + sd_journal_get_data() + returns 0 on success or a negative errno-style error + code. If the current entry does not include the + specified field -ENOENT is returned. If + sd_journal_next3 + has not been called at least once -EADDRNOTAVAIL is + returned. sd_journal_enumerate_data() + returns a positive integer if the next field has been + read, 0 when no more fields are known, or a negative + errno-style error + code. sd_journal_restart_data() + returns + nothing. sd_journal_set_data_threshold() + and sd_journal_get_threshold() + return 0 on success or a negative errno-style error + code. + + + + Notes + + The sd_journal_get_data(), + sd_journal_enumerate_data(), + sd_journal_restart_data(), + sd_journal_set_data_threshold() + and + sd_journal_get_data_threshold() + interfaces are available as shared library, which can + be compiled and linked to with the + libsystemd-journal + pkg-config1 + file. + + + + Examples + + See + sd_journal_next3 + for a complete example how to use + sd_journal_get_data(). + + Use the + SD_JOURNAL_FOREACH_DATA macro to + iterate through all fields of the current journal + entry: + + ... +int print_fields(sd_journal *j) { + const void *data; + size_t l; + SD_JOURNAL_FOREACH_DATA(j, data, length) + printf("%.*s\n", (int) length, data); +} +... + + + + + See Also + + + systemd1, + systemd.journal-fields7, + sd-journal3, + sd_journal_open3, + sd_journal_next3, + sd_journal_get_realtime_usec3, + sd_journal_query_unique3 + + + + diff --git a/man/sd_journal_get_fd.xml b/man/sd_journal_get_fd.xml new file mode 100644 index 000000000..189d21352 --- /dev/null +++ b/man/sd_journal_get_fd.xml @@ -0,0 +1,272 @@ + + + + + + + + + sd_journal_get_fd + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + sd_journal_get_fd + 3 + + + + sd_journal_get_fd + sd_journal_reliable_fd + sd_journal_process + sd_journal_wait + SD_JOURNAL_NOP + SD_JOURNAL_APPEND + SD_JOURNAL_INVALIDATE + Journal change notification + interface + + + + + #include <systemd/sd-journal.h> + + + int sd_journal_get_fd + sd_journal* j + + + + int sd_journal_reliable_fd + sd_journal* j + + + + int sd_journal_process + sd_journal* j + + + + int sd_journal_wait + sd_journal* j + uint64_t timeout_usec + + + + + + + Description + + sd_journal_get_fd() returns + a file descriptor that may be asynchronously polled in + an external event loop and is signaled readable as + soon as the journal changes, because new entries or + files were added, rotation took place, or files have + been deleted, and similar. The file descriptor is + suitable for usage in + poll2 + where it will yield POLLIN on changes. The call takes + one argument: the journal context object. Note that + not all file systems are capable of generating the + necessary events for wakeups from this file descriptor + to be enirely reliable. In particular network files + systems do not generate suitable file change events in + all cases. In such a case an application should not + rely alone on wake-ups from this file descriptor but + wake up and recheck the journal in regular time + intervals, for example every 2s. To detect + cases where this is necessary, use + sd_journal_reliable_fd(), + below. + + sd_journal_reliable_fd() + may be used to check whether the wakeup events from + the file descriptor returned by + sd_journal_get_fd are sufficient + to track changes to the journal. If this call returns + 0, it is necessary to regularly recheck for journal + changes (suggestion: every 2s). If this call returns a + positive integer this is not necessary, and wakeups + from the file descriptor returned by + sd_journal_get_fd() are + sufficient as only source for wake-ups. + + After each POLLIN wake-up + sd_journal_process() needs to be + called to process events and reset the readable state + of the file descriptor. This call will also indicate + what kind of change has been detected (see below; note + that spurious wake-ups are possible). + + A synchronous alternative for using + sd_journal_get_fd(), + sd_journal_reliable_fd() and + sd_journal_process() is + sd_journal_wait(). It will + synchronously wait until the journal gets changed, + possibly using a 2s time-out if this is necessary (see + above). In either way the maximum time this call + sleeps may be controlled with the + timeout_usec parameter. Pass + (uint64_t) -1 to wait + indefinitely. Internally this call simply combines + sd_journal_get_fd(), + sd_journal_reliable_fd(), + poll() and + sd_journal_process() into + one. + + + + + Return Value + + sd_journal_get_fd() returns a valid file descriptor on success or a negative errno-style error + code. + + sd_journal_reliable_fd() + returns a positive integer if the file descriptor + returned by sd_journal_get_fd() + is sufficient as sole wake-up source for journal + change events. Returns 0 if it is not sufficient and + the journal needs to be checked manually in regular + time intervals for changes. Returns a negative + errno-style error code on failure. + + sd_journal_process() and + sd_journal_wait() return one of + SD_JOURNAL_NOP, + SD_JOURNAL_APPEND or + SD_JOURNAL_INVALIDATE on success or + a negative errno-style error code. If + SD_JOURNAL_NOP is returned the + journal didn't change since the last invocation. If + SD_JOURNAL_APPEND is returned new + entries have been appended to the end of the + journal. If SD_JOURNAL_INVALIDATE + journal files were added or removed (possibly due to + rotation). In the latter event live-view UIs should + probably refresh their entire display while in the + case of SD_JOURNAL_APPEND it is + sufficient to simply continue reading at the previous + end of the journal. + + + + Notes + + The sd_journal_get_fd(), + sd_journal_reliable_fd(), + sd_journal_process() and + sd_journal_wait() interfaces are + available as shared library, which can be compiled and + linked to with the + libsystemd-journal + pkg-config1 + file. + + + + Examples + + Iterating through the journal, in a live view tracking all changes: + + #include <stdio.h> +#include <string.h> +#include <systemd/sd-journal.h> + +int main(int argc, char *argv[]) { + int r; + sd_journal *j; + r = sd_journal_open(&j, SD_JOURNAL_LOCAL_ONLY); + if (r < 0) { + fprintf(stderr, "Failed to open journal: %s\n", strerror(-r)); + return 1; + } + for (;;) { + const char *d; + size_t l; + r = sd_journal_next(j); + if (r < 0) { + fprintf(stderr, "Failed to iterate to next entry: %s\n", strerror(-r)); + break; + } + if (r == 0) { + /* Reached the end, let's wait for changes, and try again */ + r = sd_journal_wait(j, (uint64_t) -1); + if (r < 0) { + fprintf(stderr, "Failed to wait for changes: %s\n", strerror(-r)); + break; + } + continue; + } + r = sd_journal_get_data(j, "MESSAGE", &d, &l); + if (r < 0) { + fprintf(stderr, "Failed to read message field: %s\n", strerror(-r)); + continue; + } + printf("%.*s\n", (int) l, d); + } + sd_journal_close(j); + return 0; +} + + Waiting with poll() (this + example lacks all error checking for the sake of + simplicity): + + #include <sys/poll.h> +#include <systemd/sd-journal.h> + +int wait_for_changes(sd_journal *j) { + struct pollfd pollfd; + pollfd.fd = sd_journal_get_fd(); + pollfd.events = POLLIN; + poll(&pollfd, 1, sd_journal_reliable_fd() > 0 ? -1 : 2000); + return sd_journal_process(j); +} + + + + + + See Also + + + systemd1, + sd-journal3, + sd_journal_open3, + sd_journal_next3, + poll2 + + + + diff --git a/man/sd_journal_get_realtime_usec.xml b/man/sd_journal_get_realtime_usec.xml new file mode 100644 index 000000000..515932c6d --- /dev/null +++ b/man/sd_journal_get_realtime_usec.xml @@ -0,0 +1,146 @@ + + + + + + + + + sd_journal_get_realtime_usec + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + sd_journal_get_realtime_usec + 3 + + + + sd_journal_get_realtime_usec + sd_journal_get_monotonic_usec + Read timestamps from the current journal entry + + + + + #include <systemd/sd-journal.h> + + + int sd_journal_get_realtime_usec + sd_journal* j + uint64_t* usec + + + + int sd_journal_get_monotonic_usec + sd_journal* j + uint64_t* usec + sd_id128_t* boot_id + + + + + + + Description + + sd_journal_get_realtime_usec() + gets the realtime (wallclock) timestamp of the + current journal entry. It takes two arguments: the + journal context object and a pointer to a 64 Bit + unsigned integer to store the timestamp in. The + timestamp is in microseconds since the epoch, + i.e. CLOCK_REALTIME. + + sd_journal_get_monotonic_usec() + gets the monotonic timestamp of the current + journal entry. It takes three arguments: the journal + context object, a pointer to a 64 Bit unsigned integer + to store the timestamp in as well as a 128 Bit ID + buffer to store the boot ID of the monotonic timestamp + in. The timestamp is in microseconds since boot-up of + the specific boot, i.e. CLOCK_MONOTONIC. Since the + monotonic clock begins new with every reboot it only + defines a well-defined point in time when used + together with an identifier identifying the boot, see + sd_id128_get_boot3 + for more information. If the boot ID parameter is + passed NULL the function will fail if the monotonic + timestamp of the current entry is not of the current + system boot. + + Note that these functions will not work before + sd_journal_next3 + (or related call) has been called at least + once, in order to position the read pointer at a valid entry. + + + + Return Value + + sd_journal_get_realtime_usec() + and + sd_journal_get_monotonic_usec() + returns 0 on success or a negative errno-style error + code. If the boot ID parameter was passed NULL and the + monotonic timestamp of the current journal entry is + not of the current system boot, -ESTALE is returned by sd_journal_get_monotonic_usec(). + + + + Notes + + The + sd_journal_get_realtime_usec() + and + sd_journal_get_monotonic_usec() + interfaces are available as shared library, which can + be compiled and linked to with the + libsystemd-journal + pkg-config1 + file. + + + + See Also + + + systemd1, + sd-journal3, + sd_journal_open3, + sd_journal_next3, + sd_journal_get_data3, + sd_id128_get_boot3, + clock_gettime2, + sd_journal_get_cutoff_realtime_usec3 + + + + diff --git a/man/sd_journal_get_usage.xml b/man/sd_journal_get_usage.xml new file mode 100644 index 000000000..14eb1e2b7 --- /dev/null +++ b/man/sd_journal_get_usage.xml @@ -0,0 +1,104 @@ + + + + + + + + + sd_journal_get_usage + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + sd_journal_get_usage + 3 + + + + sd_journal_get_usage + Journal disk usage + + + + + #include <systemd/sd-journal.h> + + + int sd_journal_get_usage + sd_journal* j + uint64_t* bytes + + + + + + + Description + + sd_journal_get_usage() + determines the total disk space currently used up by + journal files. If + SD_JOURNAL_LOCAL_ONLY has been + passed when opening the journal files this value will + only reflect the size of journal files of the local + host, otherwise of all hosts. + + + + Return Value + + sd_journal_get_usage() + returns 0 on success or a negative errno-style error + code. + + + + Notes + + The sd_journal_get_usage() + interface is available as shared library, which can be + compiled and linked to with the + libsystemd-journal + pkg-config1 + file. + + + + See Also + + + systemd1, + sd-journal3, + sd_journal_open3, + + + + diff --git a/man/sd_journal_next.xml b/man/sd_journal_next.xml new file mode 100644 index 000000000..9b1cb1fc4 --- /dev/null +++ b/man/sd_journal_next.xml @@ -0,0 +1,214 @@ + + + + + + + + + sd_journal_next + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + sd_journal_next + 3 + + + + sd_journal_next + sd_journal_previous + sd_journal_next_skip + sd_journal_previous_skip + SD_JOURNAL_FOREACH + SD_JOURNAL_FOREACH_BACKWARDS + Advance or set back the read pointer in the journal + + + + + #include <systemd/sd-journal.h> + + + int sd_journal_next + sd_journal* j + + + + int sd_journal_previous + sd_journal* j + + + + int sd_journal_next_skip + sd_journal* j + uint64_t skip + + + + int sd_journal_previous_skip + sd_journal* j + uint64_t skip + + + + SD_JOURNAL_FOREACH + sd_journal* j + + + + SD_JOURNAL_FOREACH_BACKWARDS + sd_journal* j + + + + + + Description + + sd_journal_next() advances + the read pointer into the journal by one entry. The + only argument taken is a journal context object as + allocated via + sd_journal_open3. After + successful invocation the entry may be read with + functions such as + sd_journal_get_data3. + + Similar, sd_journal_previous() sets + the read pointer back one entry. + + sd_journal_next_skip() and + sd_journal_previous_skip() + advance/set back the read pointer by multiple entries + at once, as specified in the skip + parameter. + + The journal is strictly ordered by reception + time, and hence advancing to the next entry guarantees + that the entry then pointing to is later in time than + then previous one, or has the same timestamp. + + Note that + sd_journal_get_data3 + and related calls will fail unless + sd_journal_next() has been + invoked at least once in order to position the read + pointer on a journal entry. + + Note that the + SD_JOURNAL_FOREACH() macro may be used + as a wrapper around + sd_journal_seek_head3 + and sd_journal_next() in order to + make iterating through the journal easier. See below + for an example. Similar, + SD_JOURNAL_FOREACH_BACKWARDS() + may be used for iterating the journal in reverse + order. + + + + Return Value + + The four calls return the number of entries + advanced/set back on success or a negative errno-style + error code. When the end or beginning of the journal + is reached, a number smaller than requested is + returned. More specifically, if + sd_journal_next() or + sd_journal_previous() reach the + end/beginning of the journal they will return 0, + instead of 1 when they are successful. This should be + considered an EOF marker. + + + + Notes + + The sd_journal_next(), sd_journal_previous(), + sd_journal_next_skip() and + sd_journal_previous_skip() interfaces are + available as shared library, which can be compiled and + linked to with the + libsystemd-journal + pkg-config1 + file. + + + + Examples + + Iterating through the journal: + + #include <stdio.h> +#include <string.h> +#include <systemd/sd-journal.h> + +int main(int argc, char *argv[]) { + int r; + sd_journal *j; + r = sd_journal_open(&j, SD_JOURNAL_LOCAL_ONLY); + if (r < 0) { + fprintf(stderr, "Failed to open journal: %s\n", strerror(-r)); + return 1; + } + SD_JOURNAL_FOREACH(j) { + const char *d; + size_t l; + + r = sd_journal_get_data(j, "MESSAGE", &d, &l); + if (r < 0) { + fprintf(stderr, "Failed to read message field: %s\n", strerror(-r)); + continue; + } + + printf("%.*s\n", (int) l, d); + } + sd_journal_close(j); + return 0; +} + + + + + See Also + + + systemd1, + sd-journal3, + sd_journal_open3, + sd_journal_get_data3, + sd_journal_get_realtime_usec3, + sd_journal_get_cursor3 + + + + diff --git a/man/sd_journal_open.xml b/man/sd_journal_open.xml new file mode 100644 index 000000000..76b857b99 --- /dev/null +++ b/man/sd_journal_open.xml @@ -0,0 +1,184 @@ + + + + + + + + + sd_journal_open + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + sd_journal_open + 3 + + + + sd_journal_open + sd_journal_open_directory + sd_journal_close + sd_journal + SD_JOURNAL_LOCAL_ONLY + SD_JOURNAL_RUNTIME_ONLY + SD_JOURNAL_SYSTEM_ONLY + Open the system journal for reading + + + + + #include <systemd/sd-journal.h> + + + int sd_journal_open + sd_journal** ret + int flags + + + + int sd_journal_open_directory + sd_journal** ret + const char* path + int flags + + + + void sd_journal_close + sd_journal* j + + + + + + Description + + sd_journal_open() opens + the log journal for reading. It will find all journal + files automatically and interleave them automatically + when reading. As first argument it takes a pointer to + a sd_journal pointer, which on + success will contain journal context object afterwards. The + second argument is a flags field, which may consist of + the following flags ORed together: + SD_JOURNAL_LOCAL_ONLY makes sure + only journal files generated on the local machine will + be opened. SD_JOURNAL_RUNTIME_ONLY + makes sure only volatile journal files will be opened, + excluding those which are stored on persistent + storage. SD_JOURNAL_SYSTEM_ONLY + will ensure that only journal files of system services + and the kernel (in opposition to user session processes) will + be opened. + + sd_journal_open_directory() + is similar to sd_journal_open() + but takes an absolute directory path as argument. All + journal files in this directory will be opened and + interleaved automatically. This call also takes a + flags argument, but it must be passed as 0 as no flags + are currently understood for this call. + + sd_journal_close() will + close the journal context allocated with + sd_journal_open() or + sd_journal_open_directory() and + free its resources. + + When opening the journal only journal files + accessible to the calling user will be opened. If + journal files are not accessible to the caller this + will be silently ignored. + + See + sd_journal_next3 + for an example how to iterate through the journal + after opening it with + sd_journal_open(). + + A journal context object returned by + sd_journal_open() references a + specific journal entry as current entry, + similar to a file seek index in a classic file system + file, but without absolute positions. It may be + altered with + sd_journal_next3 + and + sd_journal_seek_head3 + and related calls. The current entry position may be + exported in cursor strings, as accessible + via + sd_journal_get_cursor3. Cursor + strings may be used to globally identify a specific + journal entry in a stable way and then later to seek + to it (or if the specific entry is not available + locally, to its closest entry in time) + sd_journal_seek_cursor3. + + Notification of journal changes is available via + sd_journal_get_fd() and related + calls. + + + + Return Value + + The sd_journal_open() and + sd_journal_open_directory() calls + return 0 on success or a negative errno-style error + code. sd_journal_close() returns + nothing. + + + + Notes + + The sd_journal_open(), + sd_journal_open_directory() and + sd_journal_close() interfaces are + available as shared library, which can be compiled and + linked to with the + libsystemd-journal + pkg-config1 + file. + + + + See Also + + + systemd1, + sd-journal3, + sd_journal_next3, + sd_journal_get_data3 + + + + diff --git a/man/sd_journal_print.xml b/man/sd_journal_print.xml new file mode 100644 index 000000000..7742268f5 --- /dev/null +++ b/man/sd_journal_print.xml @@ -0,0 +1,251 @@ + + + + + + + + + sd_journal_print + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + sd_journal_print + 3 + + + + sd_journal_print + sd_journal_printv + sd_journal_send + sd_journal_sendv + sd_journal_perror + SD_JOURNAL_SUPPRESS_LOCATION + Submit log entries to the journal + + + + + #include <systemd/sd-journal.h> + + + int sd_journal_print + int priority + const char* format + ... + + + + int sd_journal_printv + int priority + const char* format + va_list ap + + + + int sd_journal_send + const char* format + ... + + + + int sd_journal_sendv + const struct iovec *iov + int n + + + + int sd_journal_perror + const char* message + + + + + + + Description + + sd_journal_print() may be + used to submit simple, plain text log entries to the + system journal. The first argument is a priority + value. This is followed by a format string and its + parameters, similar to + printf3 + or + syslog3. The + priority value is one of + LOG_EMERG, + LOG_ALERT, + LOG_CRIT, + LOG_ERR, + LOG_WARNING, + LOG_NOTICE, + LOG_INFO, + LOG_DEBUG, as defined in + syslog.h, see + syslog3 + for details. It is recommended to use this call to + submit log messages in the application locale or system + locale and in UTF-8 format, but no such restrictions + are enforced. + + sd_journal_printv() is + similar to sd_journal_print() but + takes a variable argument list encapsulated in an + object of type va_list (see + stdarg3 + for more information) instead of the format string. It + is otherwise equivalent in behavior. + + sd_journal_send() may be + used to submit structured log entries to the system + journal. It takes a series of format strings, each + immediately followed by their associated parameters, + terminated by NULL. The strings passed should be of + the format VARIABLE=value. The + variable name must be in uppercase and consist only of + characters, numbers and underscores, and may not begin + with an underscore. (All assignments that do not + follow this syntax will be ignored.) The value can be + of any size and format. It is highly recommended to + submit text strings formatted in the UTF-8 character + encoding only, and submit binary fields only when + formatting in UTf-8 strings is not sensible. A number + of well known fields are defined, see + systemd.journal-fields7 + for details, but additional application defined fields + may be used. A variable may be assigned more than one + value per entry. + + sd_journal_sendv() is + similar to sd_journal_send() but + takes an array of struct iovec (as + defined in uio.h, see + readv3 + for details) instead of the format string. Each + structure should reference one field of the entry to + submit. The second argument specifies the number of + structures in the + array. sd_journal_sendv() is + particularly useful to submit binary objects to the + journal where that is necessary. + + sd_journal_perror() is a + similar to + perror3 + and writes a message to the journal that consists of + the passed string, suffixed with ": " and a human + readable representation of the current error code + stored in + errno3. If + the message string is passed as NULL or empty string + only the error string representation will be written, + prefixed with nothing. An additional journal field + ERRNO= is included in the entry containing the numeric + error code formatted as decimal string. The log + priority used is LOG_ERR (3). + + Note that sd_journal_send() + is a wrapper around + sd_journal_sendv() to make it + easier to use when only text strings shall be + submitted. Also, the following two calls are + mostly equivalent: + + sd_journal_print(LOG_INFO, "Hello World, this is PID %lu!", (unsigned long) getpid()); + +sd_journal_send("MESSAGE=Hello World, this is PID %lu!", (unsigned long) getpid(), + "PRIORITY=%i", LOG_INFO, + NULL); + + Note that these calls implicitly add fields for + the source file, function name and code line where + invoked. This is implemented with macros. If this is + not desired it can be turned off by defining + SD_JOURNAL_SUPPRESS_LOCATION before including + sd-journal.h. + + syslog3 + and sd_journal_print() may + largely be used interchangeably + functionality-wise. However, note that log messages + logged via the former take a different path to the + journal server than the later, and hence global + chronological ordering between the two streams cannot + be guaranteed. Using + sd_journal_print() has the + benefit of logging source code line, file names, and + functions as meta data along all entries, and + guaranteeing chronological ordering with structured + log entries that are generated via + sd_journal_send(). Using + syslog() has the benefit of being + more portable. + + + + Return Value + + The four calls return 0 on success or a negative + errno-style error code. The + errno3 + variable itself is not altered. + + + + Notes + + The sd_journal_print(), + sd_journal_printv(), + sd_journal_send() and + sd_journal_sendv() interfaces + are available as shared library, which can be compiled + and linked to with the + libsystemd-journal + pkg-config1 + file. + + + + See Also + + + systemd1, + sd-journal3, + sd_journal_stream_fd3, + syslog3, + perror3, + errno3, + systemd.journal-fields7 + + + + diff --git a/man/sd_journal_query_unique.xml b/man/sd_journal_query_unique.xml new file mode 100644 index 000000000..502a7e08c --- /dev/null +++ b/man/sd_journal_query_unique.xml @@ -0,0 +1,216 @@ + + + + + + + + + sd_journal_query_unique + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + sd_journal_query_unique + 3 + + + + sd_journal_query_unique + sd_journal_enumerate_unique + sd_journal_restart_unique + SD_JOURNAL_FOREACH_UNIQUE + Read unique data fields from the journal + + + + + #include <systemd/sd-journal.h> + + + int sd_journal_query_unique + sd_journal* j + const char* field + + + + int sd_journal_enumerate_unique + sd_journal* j + const void** data + size_t* length + + + + void sd_journal_restart_unique + sd_journal* j + + + + SD_JOURNAL_FOREACH_UNIQUE + sd_journal* j + const void* data + size_t length + + + + + + + Description + + sd_journal_query_unique() + queries the journal for all unique values the + specified field can take. It takes two arguments: the + journal to query and the field name to look + for. Well-known field names are listed on + systemd.journal-fields7. Field + names must be specified without a trailing '='. After + this function has been executed successfully the field + values may be queried using + sd_journal_enumerate_unique(). Invoking + this call a second time will change the field name + being queried and reset the enumeration index to the + first field value that matches. + + sd_journal_enumerate_unique() + may be used to iterate through all data fields which + match the previously selected field name as set with + sd_journal_query_unique(). On + each invocation the next field data matching the field + name is returned. The order of the returned data + fields is not defined. It takes three arguments: the + journal context object, plus a pair of pointers to + pointer/size variables where the data object and its + size shall be stored in. The returned data is in a + read-only memory map and is only valid until the next + invocation of + sd_journal_enumerate_unique(). Note + that the data returned will be prefixed with the field + name and '='. Note that this call is subject to the + data field size threshold as controlled by + sd_journal_set_data_threshold(). + + sd_journal_restart_unique() + resets the data enumeration index to the beginning of + the list. The next invocation of + sd_journal_enumerate_unique() + will return the first field data matching the field + name again. + + Note that the + SD_JOURNAL_FOREACH_UNIQUE() macro + may be used as a handy wrapper around + sd_journal_restart_unique() and + sd_journal_enumerate_unique(). + + Note that these functions currently are not + influenced by matches set with + sd_journal_add_match() but this + might change in a later version of this + software. + + + + Return Value + + sd_journal_query_unique() + returns 0 on success or a negative errno-style error + code. sd_journal_enumerate_unique() + returns a positive integer if the next field data has + been read, 0 when no more fields are known, or a + negative errno-style error + code. sd_journal_restart_unique() + returns nothing. + + + + Notes + + The sd_journal_query_unique(), + sd_journal_enumerate_unique() and + sd_journal_restart_unique() + interfaces are available as shared library, which can + be compiled and linked to with the + libsystemd-journal + pkg-config1 + file. + + + + Examples + + Use the + SD_JOURNAL_FOREACH_UNIQUE macro + to iterate through all values a field of the journal + can take. The following example lists all unit names + referenced in the journal: + + #include <stdio.h> +#include <string.h> +#include <systemd/sd-journal.h> + +int main(int argc, char *argv[]) { + sd_journal *j; + const void *d; + size_t l; + int r; + + r = sd_journal_open(&j, SD_JOURNAL_LOCAL_ONLY); + if (r < 0) { + fprintf(stderr, "Failed to open journal: %s\n", strerror(-r)); + return 1; + } + r = sd_journal_query_unique(j, "_SYSTEMD_UNIT"); + if (r < 0) { + fprintf(stderr, "Failed to query journal: %s\n", strerror(-r)); + return 1; + } + SD_JOURNAL_FOREACH_UNIQUE(j, d, l) + printf("%.*s\n", (int) l, (const char*) d); + sd_journal_close(j); + return 0; +} + + + + + See Also + + + systemd1, + systemd.journal-fields7, + sd-journal3, + sd_journal_open3, + sd_journal_get_data3, + sd_journal_add_match3 + + + + diff --git a/man/sd_journal_seek_head.xml b/man/sd_journal_seek_head.xml new file mode 100644 index 000000000..3716c5d36 --- /dev/null +++ b/man/sd_journal_seek_head.xml @@ -0,0 +1,178 @@ + + + + + + + + + sd_journal_seek_head + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + sd_journal_seek_head + 3 + + + + sd_journal_seek_head + sd_journal_seek_tail + sd_journal_seek_monotonic_usec + sd_journal_seek_realtime_usec + sd_journal_seek_cursor + Seek to a position in the + journal + + + + + #include <systemd/sd-journal.h> + + + int sd_journal_seek_head + sd_journal* j + + + + int sd_journal_seek_tail + sd_journal* j + + + + int sd_journal_seek_monotonic_usec + sd_journal* j + sd_id128_t boot_id + uint64_t usec + + + + int sd_journal_seek_realtime_usec + sd_journal* j + uint64_t usec + + + + int sd_journal_seek_cursor + sd_journal* j + const char * cursor + + + + + + Description + + sd_journal_seek_head() + seeks to the beginning of the journal, i.e. the oldest + available entry. + + Similar, + sd_journal_seek_tail() may be + used to seek to the end of the journal, i.e. the most + recent available entry. + + sd_journal_seek_monotonic_usec() + seeks to the entry with the specified monotonic + timestamp, i.e. CLOCK_MONOOTONIC. Since monotonic time + restarts on every reboot a boot ID needs to be + specified as well. + + sd_journal_seek_realtime_usec() + seeks to the entry with the specified realtime + (wallclock) timestamp, i.e. CLOCK_REALTIME. Note that + the realtime clock is not necessarily monotonic. If a + realtime timestamp is ambiguous it is not defined + which position is sought to. + + sd_journal_seek_cursor() + seeks to the entry located at the specified cursor + string. For details on cursors see + sd_journal_get_cursor3. If + no entry matching the specified cursor is found the + call will seek to the next closest entry (in terms of + time) instead. To verify whether the newly selected + entry actually matches the cursor use + sd_journal_test_cursor3. + + Note that these calls do not actually make any + entry the new current entry, this needs to be done in + a separate step with a subsequent + sd_journal_next3 + invocation (or a similar call). Only then entry data + may be retrieved via + sd_journal_get_data3. If + no entry exists that matches exactly the specified + seek address the next closest is sought to. If + sd_journal_next3 + is used the closest following entry will be sought to, + if + sd_journal_previous3 + is used the closest preceding entry is sought + to. + + + + Return Value + + The functions return 0 on success or a negative + errno-style error code. + + + + Notes + + The sd_journal_seek_head(), + sd_journal_seek_tail(), + sd_journal_seek_monotonic_usec(), + sd_journal_seek_realtime_usec(), + and sd_journal_seek_cursor() + interfaces are available as shared library, which can + be compiled and linked to with the + libsystemd-journal + pkg-config1 + file. + + + + See Also + + + systemd1, + sd-journal3, + sd_journal_open3, + sd_journal_next3, + sd_journal_get_data3, + sd_journal_get_cursor3, + sd_journal_get_realtime_usec3 + + + + diff --git a/man/sd_journal_stream_fd.xml b/man/sd_journal_stream_fd.xml new file mode 100644 index 000000000..4407296b4 --- /dev/null +++ b/man/sd_journal_stream_fd.xml @@ -0,0 +1,171 @@ + + + + + + + + + sd_journal_stream_fd + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + sd_journal_stream_fd + 3 + + + + sd_journal_stream_fd + Create log stream file descriptor to the journal + + + + + #include <systemd/sd-journal.h> + + + int sd_journal_stream_fd + const char* identifier + int priority + int level_prefix + + + + + + + Description + + sd_journal_stream_fd() may + be used to create a log stream file descriptor. Log + messages written to this file descriptor as simple + newline separated text strings are written to the + journal. This file descriptor can be used internally + by applications or be made STDOUT/STDERR of other + processes executed. + + sd_journal_stream_fd() + takes a short program identifier string as first + argument, which will be written to the journal as + _SYSLOG_IDENTIFIER= field for each log entry (see + systemd.journal-fields7 + for more information). The second argument shall be + the default priority level for all messages. The + priority level is one of LOG_EMERG, + LOG_ALERT, + LOG_CRIT, + LOG_ERR, + LOG_WARNING, + LOG_NOTICE, + LOG_INFO, + LOG_DEBUG, as defined in + syslog.h, see + syslog3 + for details. The third argument is a boolean: if true + kernel-style log priority level prefixes (such as + SD_WARNING) are interpreted, see + sd-daemon3 + for more information. + + It is recommended that applications log UTF-8 + messages only with this API, but this is not + enforced. + + + + + Return Value + + The call returns a valid write-only file descriptor on success or a + negative errno-style error code. + + + + Notes + + The sd_journal_stream_fd() + interface is available as shared library, which can + be compiled and linked to with the + libsystemd-journal + pkg-config1 + file. + + + + Examples + + Creating a log stream suitable for + fprintf3: + + #include <syslog.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <systemd/sd-journal.h> +#include <systemd/sd-daemon.h> + +int main(int argc, char *argv[]) { + int fd; + FILE *log; + fd = sd_journal_stream_fd("test", LOG_INFO, 1); + if (fd < 0) { + fprintf(stderr, "Failed to create stream fd: %s\n", strerror(-fd)); + return 1; + } + log = fdopen(fd, "w"); + if (!log) { + fprintf(stderr, "Failed to create file object: %m\n"); + close(fd); + return 1; + } + fprintf(log, "Hello World!\n"); + fprintf(log, SD_WARNING "This is a warning!\n"); + fclose(log); + return 0; +} + + + + + See Also + + + systemd1, + sd-journal3, + sd-daemon3, + sd_journal_print3, + syslog3, + fprintf3, + systemd.journal-fields7 + + + + diff --git a/man/sd_listen_fds.xml b/man/sd_listen_fds.xml new file mode 100644 index 000000000..b891b6b03 --- /dev/null +++ b/man/sd_listen_fds.xml @@ -0,0 +1,204 @@ + + + + + + + + + sd_listen_fds + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + sd_listen_fds + 3 + + + + sd_listen_fds + SD_LISTEN_FDS_START + Check for file descriptors passed by the system manager + + + + + #include <systemd/sd-daemon.h> + + #define SD_LISTEN_FDS_START 3 + + + int sd_listen_fds + int unset_environment + + + + + + Description + + sd_listen_fds() shall be + called by a daemon to check for file descriptors + passed by the init system as part of the socket-based + activation logic. + + If the unset_environment + parameter is non-zero + sd_listen_fds() will unset the + $LISTEN_FDS/$LISTEN_PID + environment variables before returning (regardless + whether the function call itself succeeded or + not). Further calls to + sd_listen_fds() will then fail, + but the variables are no longer inherited by child + processes. + + If a daemon receives more than one file + descriptor, they will be passed in the same order as + configured in the systemd socket definition + file. Nonetheless it is recommended to verify the + correct socket types before using them. To simplify + this checking the functions + sd_is_fifo3, + sd_is_socket3, + sd_is_socket_inet3, + sd_is_socket_unix3 + are provided. In order to maximize flexibility it is + recommended to make these checks as loose as possible + without allowing incorrect setups. i.e. often the + actual port number a socket is bound to matters little + for the service to work, hence it should not be + verified. On the other hand, whether a socket is a + datagram or stream socket matters a lot for the most + common program logics and should be checked. + + This function call will set the FD_CLOEXEC flag + for all passed file descriptors to avoid further + inheritance to children of the calling process. + + + + Return Value + + On failure, this call returns a negative + errno-style error code. If + $LISTEN_FDS/$LISTEN_PID + was not set or was not correctly set for this daemon and + hence no file descriptors were received, 0 is + returned. Otherwise the number of file descriptors + passed is returned. The application may find them + starting with file descriptor SD_LISTEN_FDS_START, + i.e. file descriptor 3. + + + + Notes + + This function is provided by the reference + implementation of APIs for new-style daemons and + distributed with the systemd package. The algorithm it + implements is simple, and can easily be reimplemented + in daemons if it is important to support this + interface without using the reference + implementation. + + Internally, this function checks whether the + $LISTEN_PID environment variable + equals the daemon PID. If not, it returns + immediately. Otherwise it parses the number passed in + the $LISTEN_FDS environment + variable, then sets the FD_CLOEXEC flag for the parsed + number of file descriptors starting from + SD_LISTEN_FDS_START. Finally it returns the parsed + number. + + For details about the algorithm check the + liberally licensed reference implementation sources: + + and + + sd_listen_fds() is + implemented in the reference implementation's + sd-daemon.c and + sd-daemon.h files. These + interfaces are available as shared library, which can + be compiled and linked to with the + libsystemd-daemon + pkg-config1 + file. Alternatively, applications consuming these APIs + may copy the implementation into their source + tree. For more details about the reference + implementation see + sd-daemon3. + + If the reference implementation is used as + drop-in files and -DDISABLE_SYSTEMD is set during + compilation this function will always return 0 and + otherwise become a NOP. + + + + Environment + + + + $LISTEN_PID + $LISTEN_FDS + + Set by the init system + for supervised processes that use + socket-based activation. This + environment variable specifies the + data + sd_listen_fds() + parses. See above for + details. + + + + + + See Also + + + systemd1, + sd-daemon3, + sd_is_fifo3, + sd_is_socket3, + sd_is_socket_inet3, + sd_is_socket_unix3, + daemon7, + systemd.service5, + systemd.socket5 + + + + diff --git a/man/sd_login_monitor_new.xml b/man/sd_login_monitor_new.xml new file mode 100644 index 000000000..35cb6b368 --- /dev/null +++ b/man/sd_login_monitor_new.xml @@ -0,0 +1,173 @@ + + + + + + + + + sd_login_monitor_new + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + sd_login_monitor_new + 3 + + + + sd_login_monitor_new + sd_login_monitor_unref + sd_login_monitor_flush + sd_login_monitor_get_fd + sd_login_monitor + Monitor login sessions, seats and users + + + + + #include <systemd/sd-login.h> + + + int sd_login_monitor_new + const char* category + sd_login_monitor** ret + + + + sd_login_monitor* sd_login_monitor_unref + sd_login_monitor* m + + + + int sd_login_monitor_flush + sd_login_monitor* m + + + + int sd_login_monitor_get_fd + sd_login_monitor* m + + + + + + + Description + + sd_login_monitor_new() may + be used to monitor login sessions, users and seats. Via + a monitor object a file descriptor can be integrated + into an application defined event loop which is woken + up each time a user logs in, logs out or a seat is + added or removed, or a session, user, or seat changes + state otherwise. The first parameter takes a string + which can be seat (to get + only notifications about seats being added, removed or + changed), session (to get only + notifications about sessions being created or removed + or changed) or uid (to get only + notifications when a user changes state in respect to + logins). If notifications shall be generated in all + these conditions, NULL may be passed. Note that in the + future additional categories may be defined. The + second parameter returns a monitor object and needs to + be freed with the + sd_login_monitor_unref() call + after use. + + sd_login_monitor_unref() + may be used to destroy a monitor object. Note that + this will invalidate any file descriptor returned by + sd_login_monitor_get_fd(). + + sd_login_monitor_flush() + may be used to reset the wakeup state of the monitor + object. Whenever an event causes the monitor to wake + up the event loop via the file descriptor this + function needs to be called to reset the wake-up + state. If this call is not invoked the file descriptor + will immediately wake up the event loop again. + + sd_login_monitor_get_fd() + may be used to retrieve the file descriptor of the + monitor object that may be integrated in an + application defined event loop, based around + poll2 + or a similar interface. The application should include + the returned file descriptor as wake up source for + POLLIN events. Whenever a wake-up is triggered the + file descriptor needs to be reset via + sd_login_monitor_flush(). An + application needs to reread the login state with a + function like + sd_get_seats3 + or similar to determine what changed. + + + + Return Value + + On success + sd_login_monitor_new() and + sd_login_monitor_flush() return 0 + or a positive integer. On success + sd_login_monitor_get_fd() returns + a Unix file descriptor. On failure, these calls return + a negative errno-style error code. + + sd_login_monitor_unref() + always returns NULL. + + + + Notes + + The sd_login_monitor_new(), + sd_login_monitor_unref(), sd_login_monitor_flush() and + sd_login_monitor_get_fd() interfaces + are available as shared library, which can be compiled + and linked to with the + libsystemd-login + pkg-config1 + file. + + + + See Also + + + systemd1, + sd-login3, + sd_get_seats3 + + + + diff --git a/man/sd_notify.xml b/man/sd_notify.xml new file mode 100644 index 000000000..75edeeadf --- /dev/null +++ b/man/sd_notify.xml @@ -0,0 +1,319 @@ + + + + + + + + + sd_notify + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + sd_notify + 3 + + + + sd_notify + sd_notifyf + Notify service manager about start-up completion and other daemon status changes + + + + + #include <systemd/sd-daemon.h> + + + int sd_notify + int unset_environment + const char *state + + + + int sd_notifyf + int unset_environment + const char *format + ... + + + + + + Description + sd_notify() shall be called + by a daemon to notify the init system about status + changes. It can be used to send arbitrary information, + encoded in an environment-block-like string. Most + importantly it can be used for start-up completion + notification. + + If the unset_environment + parameter is non-zero sd_notify() + will unset the $NOTIFY_SOCKET + environment variable before returning (regardless + whether the function call itself succeeded or + not). Further calls to + sd_notify() will then fail, but + the variable is no longer inherited by child + processes. + + The state parameter + should contain a newline-separated list of variable + assignments, similar in style to an environment + block. A trailing newline is implied if none is + specified. The string may contain any kind of variable + assignments, but the following shall be considered + well-known: + + + + READY=1 + + Tells the init system + that daemon startup is finished. This + is only used by systemd if the service + definition file has Type=notify + set. The passed argument is a boolean + "1" or "0". Since there is little + value in signaling non-readiness, the + only value daemons should send is + "READY=1". + + + + STATUS=... + + Passes a single-line + status string back to the init system + that describes the daemon state. This + is free-form and can be used for + various purposes: general state + feedback, fsck-like programs could + pass completion percentages and + failing programs could pass a human + readable error message. Example: + "STATUS=Completed 66% of file system + check..." + + + + ERRNO=... + + If a daemon fails, the + errno-style error code, formatted as + string. Example: "ERRNO=2" for + ENOENT. + + + + BUSERROR=... + + If a daemon fails, the + D-Bus error-style error code. Example: + "BUSERROR=org.freedesktop.DBus.Error.TimedOut" + + + + MAINPID=... + + The main pid of the + daemon, in case the init system did + not fork off the process + itself. Example: + "MAINPID=4711" + + + + WATCHDOG=1 + + Tells systemd to + update the watchdog timestamp. This is + the keep-alive ping that services need + to issue in regular intervals if + WatchdogSec= is + enabled for it. See + systemd.service5 + for details. It is recommended to send + this message if the + WATCHDOG_USEC= + environment variable has been set for + the service process, in every half the + time interval that is specified in the + variable. + + + + It is recommended to prefix variable names that + are not shown in the list above with + X_ to avoid namespace + clashes. + + Note that systemd will accept status data sent + from a daemon only if the + NotifyAccess= option is correctly + set in the service definition file. See + systemd.service5 + for details. + + sd_notifyf() is similar to + sd_notify() but takes a + printf()-like format string plus + arguments. + + + + Return Value + + On failure, these calls return a negative + errno-style error code. If + $NOTIFY_SOCKET was not set and + hence no status data could be sent, 0 is returned. If + the status was sent these functions return with a + positive return value. In order to support both, init + systems that implement this scheme and those which + don't, it is generally recommended to ignore the return + value of this call. + + + + Notes + + These functions are provided by the reference + implementation of APIs for new-style daemons and + distributed with the systemd package. The algorithms + they implement are simple, and can easily be + reimplemented in daemons if it is important to support + this interface without using the reference + implementation. + + Internally, these functions send a single + datagram with the state string as payload to the + AF_UNIX socket referenced in the + $NOTIFY_SOCKET environment + variable. If the first character of + $NOTIFY_SOCKET is @ the string is + understood as Linux abstract namespace socket. The + datagram is accompanied by the process credentials of + the sending daemon, using SCM_CREDENTIALS. + + For details about the algorithms check the + liberally licensed reference implementation sources: + + and + + sd_notify() and + sd_notifyf() are implemented in + the reference implementation's + sd-daemon.c and + sd-daemon.h files. These + interfaces are available as shared library, which can + be compiled and linked to with the + libsystemd-daemon + pkg-config1 + file. Alternatively, applications consuming these APIs + may copy the implementation into their source tree. For + more details about the reference implementation see + sd-daemon3. + + If the reference implementation is used as + drop-in files and -DDISABLE_SYSTEMD is set during + compilation these functions will always return 0 and + otherwise become a NOP. + + + + Environment + + + + $NOTIFY_SOCKET + + Set by the init system + for supervised processes for status + and start-up completion + notification. This environment variable + specifies the socket + sd_notify() talks + to. See above for details. + + + + + + Examples + + + Start-up Notification + + When a daemon finished starting up, it + might issue the following call to notify + the init system: + + sd_notify(0, "READY=1"); + + + + Extended Start-up Notification + + A daemon could send the following after + completing initialization: + + sd_notifyf(0, "READY=1\n" + "STATUS=Processing requests...\n" + "MAINPID=%lu", + (unsigned long) getpid()); + + + + Error Cause Notification + + A daemon could send the following shortly before exiting, on failure + + sd_notifyf(0, "STATUS=Failed to start up: %s\n" + "ERRNO=%i", + strerror(errno), + errno); + + + + + See Also + + systemd1, + sd-daemon3, + daemon7, + systemd.service5 + + + + diff --git a/man/sd_pid_get_session.xml b/man/sd_pid_get_session.xml new file mode 100644 index 000000000..9517795f7 --- /dev/null +++ b/man/sd_pid_get_session.xml @@ -0,0 +1,160 @@ + + + + + + + + + sd_pid_get_session + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + sd_pid_get_session + 3 + + + + sd_pid_get_session + sd_pid_get_unit + sd_pid_get_owner_uid + Determine session, service or owner of a session of a specific PID + + + + + #include <systemd/sd-login.h> + + + int sd_pid_get_session + pid_t pid + char** session + + + + int sd_pid_get_unit + pid_t pid + char** unit + + + + int sd_pid_get_owner_uid + pid_t pid + uid_t* uid + + + + + + Description + + sd_pid_get_session() may be + used to determine the login session identifier of a + process identified by the specified process + identifier. The session identifier is a short string, + suitable for usage in file system paths. Note that not + all processes are part of a login session (e.g. system + service processes, user processes that are shared + between multiple sessions of the same user, or kernel + threads). For processes not being part of a login + session this function will fail. The returned string + needs to be freed with the libc + free3 + call after use. + + sd_pid_get_unit() may be + used to determine the systemd unit (i.e. system + service) identifier of a process identified by the + specified process identifier. The unit name is a short + string, suitable for usage in file system paths. Note + that not all processes are part of a unit/service + (e.g. user processes, or kernel threads). For + processes not being part of a systemd unit/system + service this function will fail. The returned string + needs to be freed with the libc + free3 + call after use. + + sd_pid_get_owner_uid() may + be used to determine the Unix user identifier of the + owner of the session of a process identified the + specified PID. Note that this function will succeed + for user processes which are shared between multiple + login sessions of the same user, where + sd_pid_get_session() will + fail. For processes not being part of a login session + and not being a shared process of a user this function + will fail. + + If the pid parameter of any + of these functions is passed as 0 the operation is + executed for the calling process. + + + + Return Value + + On success these calls return 0 or a positive + integer. On failure, these calls return a negative + errno-style error code. + + + + Notes + + The sd_pid_get_session(), + sd_pid_get_pid(), and + sd_pid_get_owner_uid() interfaces + are available as shared library, which can be compiled + and linked to with the + libsystemd-login + pkg-config1 + file. + + Note that the login session identifier as + returned by sd_pid_get_session() + is completely unrelated to the process session + identifier as returned by + getsid2. + + + + See Also + + + systemd1, + sd-login3, + sd_session_is_active3, + getsid2 + + + + diff --git a/man/sd_readahead.xml b/man/sd_readahead.xml new file mode 100644 index 000000000..a1fc6f178 --- /dev/null +++ b/man/sd_readahead.xml @@ -0,0 +1,178 @@ + + + + + + + + + sd_readahead + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + sd_readahead + 3 + + + + sd_readahead + Control ongoing disk boot-time read-ahead operations + + + + + #include "sd-readahead.h" + + + int sd_readahead + const char *action + + + + + + Description + sd_readahead() may be + called by programs involved with early boot-up to + control ongoing boot-time disk read-ahead operations. It may be + used to terminate read-ahead operations in case an + uncommon disk access pattern is to be expected and + hence read-ahead replay or collection is unlikely to + have the desired speed-up effect on the current or + future boot-ups. + + The action should be one + of the following strings: + + + + cancel + + Terminates read-ahead + data collection, and drops all + read-ahead data collected during this + boot-up. + + + + done + + Terminates read-ahead + data collection, but keeps all + read-ahead data collected during this + boot-up around for use during + subsequent boot-ups. + + + + noreplay + + Terminates read-ahead + replay. + + + + + + + + Return Value + + On failure, these calls return a negative + errno-style error code. It is generally recommended to + ignore the return value of this call. + + + + Notes + + This function is provided by the reference + implementation of APIs for controlling boot-time + read-ahead and distributed with the systemd + package. The algorithm it implements is simple, and + can easily be reimplemented in daemons if it is + important to support this interface without using the + reference implementation. + + Internally, this function creates a file in + /run/systemd/readahead/ which is + then used as flag file to notify the read-ahead + subsystem. + + For details about the algorithm check the + liberally licensed reference implementation sources: + + and + + sd_readahead() is + implemented in the reference implementation's drop-in + sd-readahead.c and + sd-readahead.h files. It is + recommended that applications consuming this API copy + the implementation into their source tree. For more + details about the reference implementation see + sd-readahead3 + + If -DDISABLE_SYSTEMD is set during compilation + this function will always return 0 and otherwise + become a NOP. + + + + Examples + + + Cancelling all read-ahead operations + + During boots where SELinux has to + relabel the file system hierarchy, it will + create a large amount of disk accesses that + are not necessary during normal boots. Hence + it is a good idea to disable both read-ahead replay and read-ahead collection. + + + sd_readahead("cancel"); +sd_readahead("noreplay"); + + + + + + See Also + + systemd1, + sd-readahead3, + daemon7 + + + + diff --git a/man/sd_seat_get_active.xml b/man/sd_seat_get_active.xml new file mode 100644 index 000000000..b1d6d20ed --- /dev/null +++ b/man/sd_seat_get_active.xml @@ -0,0 +1,180 @@ + + + + + + + + + sd_seat_get_active + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + sd_seat_get_active + 3 + + + + sd_seat_get_active + sd_seat_get_sessions + sd_seat_can_multi_session + Determine state of a specific seat + + + + + #include <systemd/sd-login.h> + + + int sd_seat_get_active + const char* seat + char** session + uid_t* uid + + + + int sd_seat_get_sessions + const char* seat + char*** sessions + uid_t** uid + unsigned* n_uids + + + + int sd_seat_can_multi_session + const char* seat + + + + int sd_seat_can_tty + const char* seat + + + + int sd_seat_can_graphical + const char* seat + + + + + + Description + + sd_seat_get_active() may be + used to determine which session is currently active on + a seat, if there is any. Returns the session + identifier and the user identifier of the Unix user + the session is belonging to. Either the session or the + user identifier parameter can be passed NULL, in + case only one of the parameters shall be queried. The + returned string needs to be freed with the libc + free3 + call after use. + + sd_seat_get_sessions() may + be used to determine all sessions on the specified + seat. Returns two arrays, one (NULL terminated) with + the session identifiers of the sessions and one with + the user identifiers of the Unix users the sessions + belong to. An additional parameter may be used to + return the number of entries in the latter array. The + two arrays and the latter parameter may be passed as + NULL in case these values need not to be + determined. The arrays and the strings referenced by + them need to be freed with the libc + free3 + call after use. Note that instead of an empty array + NULL may be returned and should be considered + equivalent to an empty array. + + sd_seat_can_multi_session() + may be used to determine whether a specific seat is + capable of multi-session, i.e. allows multiple login + sessions in parallel (with only one being active at a + time). + + sd_seat_can_tty() may be + used to determine whether a specific seat provides TTY + functionality, i.e. is useful as a text console. + + sd_seat_can_graphical() may + be used to determine whether a specific seat provides + graphics functionality, i.e. is useful as a graphics + display. + + If the seat parameter of any + of these functions is passed as NULL the operation is + executed for the seat of the session of the calling + process, if there is any. + + + + Return Value + + On success + sd_seat_get_active() + returns 0 or a positive integer. On success + sd_seat_get_sessions() returns + the number of entries in the session identifier + array. If the test succeeds + sd_seat_can_multi_session, + sd_seat_can_tty and + sd_seat_can_graphical return a + positive integer, if it fails 0. On failure, these + calls return a negative errno-style error code. + + + + Notes + + The sd_seat_get_active(), + sd_seat_get_sessions(), + sd_seat_can_multi_session(), + sd_seat_can_tty() and + sd_seat_can_grapical() interfaces + are available as shared library, which can be compiled + and linked to with the + libsystemd-login + pkg-config1 + file. + + + + See Also + + + systemd1, + sd-login3, + sd_session_get_seat3 + + + + diff --git a/man/sd_session_is_active.xml b/man/sd_session_is_active.xml new file mode 100644 index 000000000..a9107cb95 --- /dev/null +++ b/man/sd_session_is_active.xml @@ -0,0 +1,240 @@ + + + + + + + + + sd_session_is_active + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + sd_session_is_active + 3 + + + + sd_session_is_active + sd_session_get_state + sd_session_get_uid + sd_session_get_seat + sd_session_get_service + sd_session_get_type + sd_session_get_class + sd_session_get_display + Determine state of a specific session + + + + + #include <systemd/sd-login.h> + + + int sd_session_is_active + const char* session + + + + int sd_session_get_state + const char* session + char** state + + + + int sd_session_get_uid + const char* session + uid_t* uid + + + + int sd_session_get_seat + const char* session + char** seat + + + + int sd_session_get_service + const char* session + char** service + + + + int sd_session_get_type + const char* session + char** type + + + + int sd_session_get_class + const char* session + char** class + + + + int sd_session_get_display + const char* session + char** display + + + + + + Description + + sd_session_is_active() may + be used to determine whether the session identified by + the specified session identifier is currently active + (i.e. currently in the foreground and available for + user input) or not. + + sd_session_get_state() may + be used to determine the state of the session + identified by the specified session identifier. The + following states are currently known: + online (session logged in, but + session not active, i.e. not in the foreground), + active (session logged in and + active, i.e. in the foreground), + closing (session nominally logged + out, but some processes belonging to it are still + around). In the future additional states might be + defined, client code should be written to be robust in + regards to additional state strings being + returned. This function is a more generic version of + sd_session_is_active(). The returned + string needs to be freed with the libc + free3 + call after use. + + sd_session_get_uid() may be + used to determine the user identifier of the Unix user the session + identified by the specified session identifier belongs + to. + + sd_session_get_seat() may + be used to determine the seat identifier of the seat + the session identified by the specified session + identifier belongs to. Note that not all sessions are + attached to a seat, this call will fail for them. The + returned string needs to be freed with the libc + free3 + call after use. + + sd_session_get_service() + may be used to determine the name of the service (as + passed during PAM session setup) that registered the + session identified by the specified session + identifier. The returned string needs to be freed with + the libc + free3 + call after use. + + sd_session_get_type() may + be used to determine the type of the session + identified by the specified session identifier. The + returned string is one of x11, + tty or + unspecified and needs to be freed + with the libc + free3 + call after use. + + sd_session_get_class() may + be used to determine the class of the session + identified by the specified session identifier. The + returned string is one of user, + greeter or + lock-screen and needs to be freed + with the libc + free3 + call after use. + + sd_session_get_display() + may be used to determine the X11 display of the + session identified by the specified session + identifier. The returned string is one of needs to be + freed with the libc + free3 + call after use. + + If the session parameter of + any of these functions is passed as NULL the operation + is executed for the session the calling process is a + member of, if there is any. + + + + Return Value + + If the test succeeds + sd_session_is_active() returns a + positive integer, if it fails 0. On success + sd_session_get_state(), + sd_session_get_uid(), + sd_session_get_seat(), + sd_session_get_service(), + sd_session_get_type(), + sd_session_get_class() and + sd_session_get_display() return 0 or + a positive integer. On failure, these calls return a + negative errno-style error code. + + + + Notes + + The sd_session_is_active(), + sd_session_get_state(), + sd_session_get_uid(), + sd_session_get_seat(), + sd_session_get_service(), + sd_session_get_type(), + sd_session_get_class() and + sd_session_get_display() interfaces + are available as shared library, which can be compiled + and linked to with the + libsystemd-login + pkg-config1 + file. + + + + See Also + + + systemd1, + sd-login3, + sd_pid_get_session3 + + + + diff --git a/man/sd_uid_get_state.xml b/man/sd_uid_get_state.xml new file mode 100644 index 000000000..b7bc944b1 --- /dev/null +++ b/man/sd_uid_get_state.xml @@ -0,0 +1,190 @@ + + + + + + + + + sd_uid_get_state + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + sd_uid_get_state + 3 + + + + sd_uid_get_state + sd_uid_is_on_seat + sd_uid_get_sessions + sd_uid_get_seats + Determine login state of a specific Unix user ID + + + + + #include <systemd/sd-login.h> + + + int sd_uid_get_state + uid_t uid + char** state + + + + int sd_uid_is_on_seat + uid_t uid + int require_active + const char* seat + + + + int sd_uid_get_sessions + uid_t uid + int require_active + char*** sessions + + + + int sd_uid_get_seats + uid_t uid + int require_active + char*** seats + + + + + + Description + + sd_uid_get_state() may be + used to determine the login state of a specific Unix + user identifier. The following states are currently + known: offline (user not logged in + at all), lingering (user not logged + in, but some user services running), + online (user logged in, but not + active, i.e. has no session in the foreground), + active (user logged in, and has at + least one active session, i.e. one session in the + foreground), closing (user not + logged in, and not lingering, but some processes are + still around). In the future additional states might + be defined, client code should be written to be robust + in regards to additional state strings being + returned. The returned string needs to be freed with + the libc + free3 + call after use. + + sd_uid_is_on_seat() may be + used to determine whether a specific user is logged in + or active on a specific seat. Accepts a Unix user + identifier and a seat identifier string as + parameters. The require_active + parameter is a boolean value. If non-zero (true) this + function will test if the user is active (i.e. has a + session that is in the foreground and accepting user + input) on the specified seat, otherwise (false) only + if the user is logged in (and possibly inactive) on + the specified seat. + + sd_uid_get_sessions() may + be used to determine the current sessions of the + specified user. Accepts a Unix user identifier as + parameter. The require_active + parameter controls whether the returned list shall + consist of only those sessions where the user is + currently active (> 0), where the user is currently + online but possibly inactive (= 0), or + logged in at all but possibly closing the session (< 0). The call returns a + NULL terminated string array of session identifiers in + sessions which needs to be + freed by the caller with the libc + free3 + call after use, including all the strings + referenced. If the string array parameter is passed as + NULL the array will not be filled in, but the return + code still indicates the number of current + sessions. Note that instead of an empty array NULL may + be returned and should be considered equivalent to an + empty array. + + Similar, sd_uid_get_seats() + may be used to determine the list of seats on which + the user currently has sessions. Similar semantics + apply, however note that the user may have + multiple sessions on the same seat as well as sessions + with no attached seat and hence the number of entries + in the returned array may differ from the one returned + by sd_uid_get_sessions(). + + + + Return Value + + On success + sd_uid_get_state() returns 0 or a + positive integer. If the test succeeds + sd_uid_is_on_seat() returns a + positive integer, if it fails + 0. sd_uid_get_sessions() and + sd_uid_get_seats() return the + number of entries in the returned arrays. On failure, + these calls return a negative errno-style error + code. + + + + Notes + + The sd_uid_get_state(), + sd_uid_is_on_seat(), + sd_uid_get_sessions(), and + sd_uid_get_seats() interfaces are + available as shared library, which can be compiled and + linked to with the libsystemd-login + pkg-config1 + file. + + + + See Also + + + systemd1, + sd-login3, + sd_pid_get_owner_uid3 + + + + diff --git a/man/shutdown.xml b/man/shutdown.xml new file mode 100644 index 000000000..d54fcb25a --- /dev/null +++ b/man/shutdown.xml @@ -0,0 +1,188 @@ + + + + + + + + + shutdown + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + shutdown + 8 + + + + shutdown + Halt, power-off or reboot the machine + + + + + shutdown OPTIONS TIME WALL + + + + + Description + + shutdown may be used to halt, + power-off or reboot the machine. + + The first argument may be a time string (which + is usually now). Optionally, this + may be followed by a wall message to be sent to all + logged-in users before going down. + + The time string may either be in the format + hh:mm for hour/minutes specifying + the time to execute the shutdown at, specified in 24h + clock format. Alternatively it may be in the syntax + +m referring to the specified + number of minutes m from now. now + is an alias for +0, i.e. for + triggering an immediate shutdown. If no time argument + is specified, +1 is + implied. + + Note that to specify a wall message you must + specify a time argument, too. + + If the time argument is used, 5 minutes + before the system goes down the + /etc/nologin file is created to + ensure that further logins shall not be + allowed. + + + + Options + + The following options are understood: + + + + + + Prints a short help + text and exits. + + + + + + + Halt the machine. + + + + + + + Power-off the + machine (the default). + + + + + + + Reboot the + machine. + + + + + + Equivalent to + , unless + is + specified. + + + + + + Don't halt, power-off, + reboot, just write wall + message. + + + + + + Don't send wall + message before + halt, power-off, reboot. + + + + + + Cancel a pending + shutdown. This may be used cancel the + effect of an invocation of + shutdown with a + time argument that is not + +0 or + now. + + + + + + + Exit status + + On success 0 is returned, a non-zero failure + code otherwise. + + + + Notes + + This is a legacy command available for + compatibility only. + + + + See Also + + systemd1, + systemctl1, + halt8, + wall1 + + + + diff --git a/man/sysctl.d.xml b/man/sysctl.d.xml new file mode 100644 index 000000000..69aac8cab --- /dev/null +++ b/man/sysctl.d.xml @@ -0,0 +1,127 @@ + + + + + + + + sysctl.d + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + sysctl.d + 5 + + + + sysctl.d + Configure kernel parameters at boot + + + + /etc/sysctl.d/*.conf + /run/sysctl.d/*.conf + /usr/lib/sysctl.d/*.conf + + + + Description + + At boot, + systemd-sysctl.service8 + reads configuration files from the above directories + to configure + sysctl8 + kernel parameters. + + + + Configuration Format + + The configuration files contain a list of + variable assignments, separated by newlines. Empty + lines and lines whose first non-whitespace character + is # or ; are ignored. + + Note that both / and . are accepted as label + separators within sysctl variable + names. kernel.domainname=foo and + kernel/domainname=foo hence are + entirely equivalent. + + Each configuration file shall be named in the + style of <program>.conf. + Files in /etc/ override files + with the same name in /usr/lib/ + and /run/. Files in + /run/ override files with the same + name in /usr/lib/. Packages + should install their configuration files in + /usr/lib/. Files in + /etc/ are reserved for the local + administrator, who may use this logic to override the + configuration files installed by vendor packages. All + configuration files are sorted by their filename in + alphabetical order, regardless in which of the + directories they reside, to guarantee that a specific + configuration file takes precedence over another file + with an alphabetically earlier name, if both files + contain the same variable setting. + + If the administrator wants to disable a + configuration file supplied by the vendor the + recommended way is to place a symlink to + /dev/null in + /etc/sysctl.d/ bearing the + same file name. + + + + Example + + /etc/sysctl.d/domain-name.conf example: + + # Set kernel YP domain name +kernel.domainname=example.com + + + + + See Also + + systemd1, + systemd-sysctl.service8, + systemd-delta1, + sysctl8, + sysctl.conf5 + + + + diff --git a/man/systemctl.xml b/man/systemctl.xml new file mode 100644 index 000000000..f86952c68 --- /dev/null +++ b/man/systemctl.xml @@ -0,0 +1,1286 @@ + + + + + + + + + systemctl + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemctl + 1 + + + + systemctl + Control the systemd system and service manager + + + + + systemctl OPTIONS COMMAND NAME + + + + + Description + + systemctl may be used to + introspect and control the state of the + systemd1 + system and service manager. + + + + Options + + The following options are understood: + + + + + + + Prints a short help + text and exits. + + + + + + Prints a short version + string and exits. + + + + + + + The argument should + be a unit type name such as + and + , + or a unit load state such as + and + . + + + If the argument is a unit type, + when listing units, limit display to + certain unit types. If not specified + units of all types will be shown. + + If the argument is a unit load state, + when listing units, limit display to + certain unit types. If not specified + units of in all load states will be + shown. + + As a special case, if the argument + is , a list of + allowed values will be printed and the + program will exit. + + + + + + + + When showing + unit/job/manager properties, limit + display to certain properties as + specified as argument. If not + specified all set properties are + shown. The argument should be a + property name, such as + MainPID. If + specified more than once all + properties with the specified names + are shown. + + + + + + + When listing units, + show all units, regardless of their + state, including inactive units. When + showing unit/job/manager properties, + show all properties regardless whether + they are set or not. + + + + + + When listing units, + show only failed units. Do not confuse + with + . + + + + + + Do not ellipsize unit + names and truncate unit descriptions + in the output of + list-units and + list-jobs. + + + + + + If the requested + operation conflicts with a pending + unfinished job, fail the command. If + this is not specified the requested + operation will replace the pending job, + if necessary. Do not confuse + with + . + + + + + + When enqueuing a new + job ignore all its dependencies and + execute it immediately. If passed no + required units of the unit passed will + be pulled in, and no ordering + dependencies will be honored. This is + mostly a debugging and rescue tool for + the administrator and should not be + used by + applications. + + + + + + + Suppress output to + STDOUT in + snapshot, + is-active, + is-failed, + enable and + disable. + + + + + + Do not synchronously wait for + the requested operation to finish. If this is + not specified the job will be verified, + enqueued and systemctl will + wait until it is completed. By passing this + argument it is only verified and + enqueued. + + + + + + Do not print a legend, i.e. + the column headers and the footer with hints. + + + + + + + Do not pipe output into a + pager. + + + + + + Talk to the systemd + system manager. (Default) + + + + + + Talk to the systemd + manager of the calling user. + + + + + + + When used in + conjunction with the + dot command (see + below), selects which dependencies are + shown in the dependency graph. If + is passed + only dependencies of type + After= or + Before= are + shown. If + is passed only dependencies of type + Requires=, + RequiresOverridable=, + Requisite=, + RequisiteOverridable=, + Wants= and + Conflicts= are + shown. If neither is passed, shows + dependencies of all these + types. + + + + + + Don't send wall + message before + halt, power-off, reboot. + + + + + + When used with + enable and + disable, operate on the + global user configuration + directory, thus enabling or disabling + a unit file globally for all future + logins of all users. + + + + + + When used with + enable and + disable, do not + implicitly reload daemon configuration + after executing the + changes. + + + + + + When used with + start and related + commands, disables asking for + passwords. Background services may + require input of a password or + passphrase string, for example to + unlock system hard disks or + cryptographic certificates. Unless + this option is specified and the + command is invoked from a terminal + systemctl will + query the user on the terminal for the + necessary secrets. Use this option to + switch this behavior off. In this case + the password must be supplied by some + other means (for example graphical + password agents) or the service might + fail. This also disables querying the + user for authentication for privileged + operations. + + + + + + When used with + kill, choose which + processes to kill. Must be one of + , + or + to select whether + to kill only the main process of the + unit, the control process or all + processes of the unit. If omitted + defaults to + . + + + + + + + When used with + kill, choose which + signal to send to selected + processes. Must be one of the well + known signal specifiers such as + SIGTERM, SIGINT or SIGSTOP. If + omitted defaults to + . + + + + + + + When used with + enable, overwrite any + existing conflicting + symlinks. + + When used with + halt, + poweroff, + reboot or + kexec execute the + selected operation without shutting + down all units. However, all processes + will be killed forcibly and all file + systems are unmounted or remounted + read-only. This is hence a drastic but + relatively safe option to request an + immediate reboot. If + is specified + twice for these operations, they will + be executed immediately without + terminating any processes or umounting + any file systems. Warning: specifying + twice with + any of these operations might result + in data loss. + + + + + + When used with + enable/disable/is-enabled (and + related commands), use alternative + root path when looking for unit + files. + + + + + + When used with + enable/disable/is-enabled (and related commands), make + changes only temporarily, so that they + are dropped on the next reboot. This + will have the effect that changes are + not made in subdirectories of + /etc but in + /run, with + identical immediate effects, however, + since the latter is lost on reboot, + the changes are lost + too. + + + + + + + Execute operation + remotely. Specify a hostname, or + username and hostname separated by @, + to connect to. This will use SSH to + talk to the remote systemd + instance. + + + + + + + Acquire privileges via + PolicyKit before executing the + operation. + + + + + + + When used with + status controls the + number of journal lines to show, + counting from the most recent + ones. Takes a positive integer + argument. Defaults to + 10. + + + + + + + When used with + status controls the + formatting of the journal entries that + are shown. For the available choices + see + journalctl1. Defaults + to + short. + + + + + The following commands are understood: + + + + list-units + + List known units. + + + start [NAME...] + + Start (activate) one + or more units specified on the command + line. + + + stop [NAME...] + + Stop (deactivate) one + or more units specified on the command + line. + + + reload [NAME...] + + Asks all units listed + on the command line to reload their + configuration. Note that this will + reload the service-specific + configuration, not the unit + configuration file of systemd. If you + want systemd to reload the + configuration file of a unit use the + daemon-reload + command. In other words: for the + example case of Apache, this will + reload Apache's + httpd.conf in the + web server, not the + apache.service + systemd unit file. + + This command should not be + confused with the + daemon-reload or + load + commands. + + + + restart [NAME...] + + Restart one or more + units specified on the command + line. If the units are not running yet + they will be + started. + + + try-restart [NAME...] + + Restart one or more + units specified on the command + line if the units are running. Do + nothing if units are not running. + Note that for compatibility + with Red Hat init scripts + condrestart is + equivalent to this command. + + + reload-or-restart [NAME...] + + Reload one or more + units if they support it. If not, + restart them instead. If the units + are not running yet they will be + started. + + + reload-or-try-restart [NAME...] + + Reload one or more + units if they support it. If not, + restart them instead. Do nothing if + the units are not running. Note that + for compatibility with SysV init + scripts + force-reload is + equivalent to this + command. + + + isolate [NAME] + + Start the unit + specified on the command line and its + dependencies and stop all others. + + This is similar to changing the + runlevel in a traditional init system. The + isolate command will + immediately stop processes that are not + enabled in the new unit, possibly including + the graphical environment or terminal you + are currently using. + + Note that this works only on units + where is + enabled. See + systemd.unit5 + for details. + + + kill [NAME...] + + Send a signal to one + or more processes of the unit. Use + to select + which process to kill. Use + to + select the kill mode and + to select + the signal to send. + + + is-active [NAME...] + + Check whether any of + the specified units are active + (i.e. running). Returns an exit code + 0 if at least one is active, non-zero + otherwise. Unless + is specified + this will also print the current unit + state to STDOUT. + + + is-failed [NAME...] + + Check whether any of + the specified units are failed. + Returns an exit code + 0 if at least one is failed, non-zero + otherwise. Unless + is specified + this will also print the current unit + state to STDOUT. + + + status [NAME...|PID...] + + Show terse runtime + status information about one or more + units, followed by its most recent log + data from the journal. This function + is intended to generate human-readable + output. If you are looking for + computer-parsable output, use + show instead. If a + PID is passed information about the + unit the process of the PID belongs to + is shown. + + + show [NAME...|JOB...] + + Show properties of one + or more units, jobs or the manager + itself. If no argument is specified + properties of the manager will be + shown. If a unit name is specified + properties of the unit is shown, and + if a job id is specified properties of + the job is shown. By default, empty + properties are suppressed. Use + to show those + too. To select specific properties to + show use + . This + command is intended to be used + whenever computer-parsable output is + required. Use + status if you are + looking for formatted human-readable + output. + + + help [NAME...|PID...] + + Show manual pages for + one or more units, if available. If a + PID is passed the manual pages for the + unit the process of the PID belongs to + is shown. + + + reset-failed [NAME...] + + Reset the + 'failed' state of the + specified units, or if no unit name is + passed of all units. When a unit fails + in some way (i.e. process exiting with + non-zero error code, terminating + abnormally or timing out) it will + automatically enter the + 'failed' state and + its exit code and status is recorded + for introspection by the administrator + until the service is restarted or + reset with this + command. + + + + list-unit-files + + List installed unit files. + + + + + enable [NAME...] + + Enable one or + more unit files or unit file + instances, as specified on the + command line. This will create a + number of symlinks as encoded in + the [Install] + sections of the unit files. After + the symlinks have been created the + systemd configuration is reloaded + (in a way that is equivalent to + daemon-reload) + to ensure the changes are taken into + account immediately. Note that this + does not have the effect that any of + the units enabled are also started at + the same time. If this is desired + a separate start + command must be invoked for the unit. + Also note that in case of instance + enablement, symlinks named same as + instances are created in install + location, however they all point to + the same template unit file. + + This command will + print the actions executed. This + output may be suppressed by passing + . + + Note that this operation creates + only the suggested symlinks for the + units. While this command is the + recommended way to manipulate the unit + configuration directory, the + administrator is free to make + additional changes manually, by + placing or removing symlinks in the + directory. This is particularly useful + to create configurations that deviate + from the suggested default + installation. In this case the + administrator must make sure to invoke + daemon-reload + manually as necessary, to ensure his + changes are taken into account. + + Enabling units should not be + confused with starting (activating) + units, as done by the + start + command. Enabling and starting units + is orthogonal: units may be enabled + without being started and started + without being enabled. Enabling simply + hooks the unit into various suggested + places (for example, so that the unit + is automatically started on boot or + when a particular kind of hardware is + plugged in). Starting actually spawns + the daemon process (in case of service + units), or binds the socket (in case + of socket units), and so + on. + + Depending on whether + , + or + is specified + this enables the unit for the system, + for the calling user only + or for all future logins of all + users. Note that in the latter case no + systemd daemon configuration is + reloaded. + + + + + disable [NAME...] + + Disables one or more + units. This removes all symlinks to + the specified unit files from the unit + configuration directory, and hence + undoes the changes made by + enable. Note + however that this removes + all symlinks to the unit files + (i.e. including manual additions), not + just those actually created by + enable. This call + implicitly reloads the systemd daemon + configuration after completing the + disabling of the units. Note that this + command does not implicitly stop the + units that are being disabled. If this + is desired an additional + stop command should + be executed afterwards. + + This command will print the + actions executed. This output may be + suppressed by passing + . + + + This command honors + , + , + in a similar + way as + enable. + + + + is-enabled [NAME...] + + Checks whether any of + the specified unit files are enabled + (as with + enable). Returns an + exit code of 0 if at least one is + enabled, non-zero otherwise. Prints + the current enable status. To suppress + this output use + . + + + + reenable [NAME...] + + Reenable one or more + unit files, as specified on the + command line. This is a combination of + disable and + enable and is + useful to reset the symlinks a unit is + enabled with to the defaults + configured in the + [Install] section + of the unit file. + + + + + preset [NAME...] + + Reset one or more unit + files, as specified on the command + line, to the defaults configured in + the preset policy files. This has the + same effect as + disable or + enable, depending + how the unit is listed in the preset + files. For more information on preset + policy format see + systemd.preset5. For + more information on the concept of + presets please consult the Preset + document. + + + + + mask [NAME...] + + Mask one or more unit + files, as specified on the command + line. This will link these units to + /dev/null, making + it impossible to start them. This is a stronger version + of disable, since + it prohibits all kinds of activation + of the unit, including manual + activation. Use this option with + care. + + + + + unmask [NAME...] + + Unmask one or more + unit files, as specified on the + command line. This will undo the + effect of + mask. + + + + + link [NAME...] + + Link a unit file that + is not in the unit file search paths + into the unit file search path. This + requires an absolute path to a unit + file. The effect of this can be undone + with disable. The + effect of this command is that a unit + file is available for + start and other + commands although it isn't installed + directly in the unit search + path. + + + + + load [NAME...] + + Load one or more units + specified on the command line. This + will simply load their configuration + from disk, but not start them. To + start them you need to use the + start command which + will implicitly load a unit that has + not been loaded yet. Note that systemd + garbage collects loaded units that are + not active or referenced by an active + unit. This means that units loaded + this way will usually not stay loaded + for long. Also note that this command + cannot be used to reload unit + configuration. Use the + daemon-reload + command for that. All in all, this + command is of little use except for + debugging. + This command should not be + confused with the + daemon-reload or + reload + commands. + + + list-jobs + + List jobs that are in progress. + + + cancel [JOB...] + + Cancel one or more + jobs specified on the command line by + their numeric job + IDs. If no job id is specified, cancel all pending jobs. + + + dump + + Dump server + status. This will output a (usually + very long) human readable manager + status dump. Its format is subject to + change without notice and should not + be parsed by + applications. + + + dot + + Generate textual + dependency graph description in dot + format for further processing with the + GraphViz + dot1 + tool. Use a command line like + systemctl dot | dot -Tsvg > + systemd.svg to generate a + graphical dependency tree. Unless + or + is passed + the generated graph will show both + ordering and requirement + dependencies. + + + snapshot [NAME] + + Create a snapshot. If + a snapshot name is specified, the new + snapshot will be named after it. If + none is specified an automatic + snapshot name is generated. In either + case, the snapshot name used is + printed to STDOUT, unless + is + specified. + + A snapshot refers to a saved + state of the systemd manager. It is + implemented itself as a unit that is + generated dynamically with this + command and has dependencies on all + units active at the time. At a later + time the user may return to this state + by using the + isolate command on + the snapshot unit. + + Snapshots are only useful for + saving and restoring which units are + running or are stopped, they do not + save/restore any other + state. Snapshots are dynamic and lost + on reboot. + + + delete [NAME...] + + Remove a snapshot + previously created with + snapshot. + + + daemon-reload + + Reload systemd manager + configuration. This will reload all + unit files and recreate the entire + dependency tree. While the daemon is + reloaded, all sockets systemd listens + on on behalf of user configuration will + stay accessible. This + command should not be confused with + the load or + reload + commands. + + + daemon-reexec + + Reexecute the systemd + manager. This will serialize the + manager state, reexecute the process + and deserialize the state again. This + command is of little use except for + debugging and package + upgrades. Sometimes it might be + helpful as a heavy-weight + daemon-reload. While + the daemon is reexecuted all sockets + systemd listens on on behalf of user + configuration will stay + accessible. + + + show-environment + + Dump the systemd + manager environment block. The + environment block will be dumped in + straight-forward form suitable for + sourcing into a shell script. This + environment block will be passed to + all processes the manager + spawns. + + + set-environment [NAME=VALUE...] + + Set one or more + systemd manager environment variables, + as specified on the command + line. + + + unset-environment [NAME...] + + Unset one or more + systemd manager environment + variables. If only a variable name is + specified it will be removed + regardless of its value. If a variable + and a value are specified the variable + is only removed if it has the + specified value. + + + default + + Enter default + mode. This is mostly equivalent to + start + default.target. + + + rescue + + Enter rescue + mode. This is mostly equivalent to + isolate + rescue.target but also + prints a wall message to all + users. + + + emergency + + Enter emergency + mode. This is mostly equivalent to + isolate + emergency.target but also + prints a wall message to all + users. + + + halt + + Shut down and halt the + system. This is mostly equivalent to + start halt.target + but also prints a wall message to all + users. If combined with + shutdown of + all running services is skipped, + however all processes are killed and + all file systems are unmounted or + mounted read-only, immediately + followed by the system halt. If + is specified + twice the operation is immediately + executed without terminating any + processes or unmounting any file + systems. This may result in data + loss. + + + poweroff + + Shut down and + power-off the system. This is mostly + equivalent to start + poweroff.target but also + prints a wall message to all users. If + combined with + shutdown of all running services is + skipped, however all processes are + killed and all file systems are + unmounted or mounted read-only, + immediately followed by the powering + off. If is + specified twice the operation is + immediately executed without + terminating any processes or + unmounting any file systems. This may + result in data loss. + + + reboot + + Shut down and reboot + the system. This is mostly equivalent + to start + reboot.target but also + prints a wall message to all users. If + combined with + shutdown of all running services is + skipped, however all processes are + killed and all file systems are + unmounted or mounted read-only, + immediately followed by the reboot. If + is specified + twice the operation is immediately + executed without terminating any + processes or unmounting any file + systems. This may result in data + loss. + + + kexec + + Shut down and reboot + the system via kexec. This is mostly + equivalent to start + kexec.target but also prints + a wall message to all users. If + combined with + shutdown of all running services is + skipped, however all processes are killed + and all file systems are unmounted or + mounted read-only, immediately + followed by the + reboot. + + + exit + + Ask the systemd + manager to quit. This is only + supported for user service managers + (i.e. in conjunction with the + option) and + will fail otherwise. + + + suspend + + Suspend the + system. This will trigger activation + of the special + suspend.target + target. + + + hibernate + + Hibernate the + system. This will trigger activation + of the special + hibernate.target + target. + + + hybrid-sleep + + Hibernate and suspend + the system. This will trigger + activation of the special + hybrid-sleep.target + target. + + + switch-root [ROOT] [INIT] + + Switches to a + different root directory and executes + a new system manager process below + it. This is intended for usage in + initial RAM disks ("initrd"), and will + transition from the initrd's system + manager process (a.k.a "init" process) + to the main system manager + process. Takes two arguments: the + directory to make the new root + directory, and the path to the new + system manager binary below it to + execute as PID 1. If the latter is + omitted or the empty string, a + systemd binary will automatically be + searched for and used as init. If the + system manager path is omitted or + equal the empty string the state of + the initrd's system manager process is + passed to the main system manager, + which allows later introspection of the + state of the services involved in the + initrd boot. + + + + + + + Exit status + + On success 0 is returned, a non-zero failure + code otherwise. + + + + Environment + + + + $SYSTEMD_PAGER + Pager to use when + is not given; + overrides $PAGER. Setting + this to an empty string or the value + cat is equivalent to passing + . + + + + + + See Also + + systemd1, + systemadm1, + journalctl1, + loginctl1, + systemd.unit5, + systemd.special7, + wall1, + systemd.preset5 + + + + diff --git a/man/systemd-analyze.xml b/man/systemd-analyze.xml new file mode 100644 index 000000000..c2ff9cc5b --- /dev/null +++ b/man/systemd-analyze.xml @@ -0,0 +1,138 @@ + + + + + + + + + systemd-analyze + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd-analyze + 1 + + + + systemd-analyze + Analyze system boot-up performance + + + + + systemd-analyze OPTIONS time + + + systemd-analyze OPTIONS blame + + + systemd-analyze OPTIONS plot > file.svg + + + + + Description + + systemd-analyze may be used + to determine system boot-up performance of the current + boot. + + systemd-analyze time + prints the time spent in the kernel before + userspace has been reached, the time spent in the + initial RAM disk (initrd) before normal system + userspace has been reached and the time normal system + userspace took to initialize. Note that these + measurements simply measure the time passed up to the + point where all system services have been spawned, but + not necessarily until they fully finished + initialization or the disk is idle. + + systemd-analyze blame prints + a list of all running units, ordered by the time they + took to initialize. This information may be used to + optimize boot-up times. Note that the output might be + misleading as the initialization of one service might + be slow simply because it waits for the initialization + of another service to complete. + + systemd-analyze plot prints + an SVG graphic detailing which system services have + been started at what time, highlighting the time they + spent on initialization. + + If no command is passed systemd-analyze + time is implied. + + + + + Options + + The following options are understood: + + + + + + + Prints a short help + text and exits. + + + + + + Shows performance data + of user sessions instead of the system + manager. + + + + + + + Exit status + + On success 0 is returned, a non-zero failure + code otherwise. + + + + See Also + + systemd1, + systemctl1 + + + + diff --git a/man/systemd-ask-password-console.service.xml b/man/systemd-ask-password-console.service.xml new file mode 100644 index 000000000..6c87feb17 --- /dev/null +++ b/man/systemd-ask-password-console.service.xml @@ -0,0 +1,96 @@ + + + + + + + + systemd-ask-password-console.service + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd-ask-password-console.service + 8 + + + + systemd-ask-password-console.service + systemd-ask-password-console.path + systemd-ask-password-wall.service + systemd-ask-password-wall.path + Query the user for system passwords on the + console and via wall + + + + systemd-ask-password-console.service + systemd-ask-password-console.path + systemd-ask-password-wall.service + systemd-ask-password-wall.path + + + + Description + + systemd-ask-password-console.service + is a system service that queries the user for system + passwords (such as hard disk encryption keys and SSL + certificate passphrases) on the console. It is + intended to be used during boot to ensure proper + handling of passwords necessary for + boot. systemd-ask-password-wall.service + is a system service that informs all logged in users + for system passwords via + wall1. It + is intended to be used after boot to ensure that users + are properly notified. + + See the + developer documentation for more information + about the system password logic. + + Note that these services invoke + systemd-tty-ask-password-agent1 + with either the --watch --console + or --watch --wall command line + parameters. + + + + See Also + + systemd1, + systemd-tty-ask-password-agent1, + wall1 + + + + diff --git a/man/systemd-ask-password.xml b/man/systemd-ask-password.xml new file mode 100644 index 000000000..7b0b9ab80 --- /dev/null +++ b/man/systemd-ask-password.xml @@ -0,0 +1,183 @@ + + + + + + + + + systemd-ask-password + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd-ask-password + 1 + + + + systemd-ask-password + Query the user for a system password + + + + + systemd-ask-password OPTIONS MESSAGE + + + + + Description + + systemd-ask-password may be + used to query a system password or passphrase from the + user, using a question message specified on the + command line. When run from a TTY it will query a + password on the TTY and print it to STDOUT. When run + with no TTY or with it will + query the password system-wide and allow active users + to respond via several agents. The latter is + only available to privileged processes. + + The purpose of this tool is to query system-wide + passwords -- that is passwords not attached to a + specific user account. Examples include: unlocking + encrypted hard disks when they are plugged in or at + boot, entering an SSL certificate passphrase for web + and VPN servers. + + Existing agents are: a boot-time password agent + asking the user for passwords using Plymouth; a + boot-time password agent querying the user directly on + the console; an agent requesting password input via a + wall1 + message; an agent suitable for running in a GNOME + session; a command line agent which can be started + temporarily to process queued password requests; a TTY + agent that is temporarily spawned during + systemctl1 + invocations. + + Additional password agents may be implemented + according to the systemd + Password Agent Specification. + + If a password is queried on a TTY the user may + press TAB to hide the asterisks normally shown for + each character typed. Pressing Backspace as first key + achieves the same effect. + + + + + Options + + The following options are understood: + + + + + + + Prints a short help + text and exits. + + + + + + Specify an icon name + alongside the password query, which may + be used in all agents supporting + graphical display. The icon name + should follow the XDG + Icon Naming + Specification. + + + + + + Specify the query + timeout in seconds. Defaults to + 90s. + + + + + + Never ask for password + on current TTY even if one is + available. Always use agent + system. + + + + + + If passed accept + cached passwords, i.e. passwords + previously typed in. + + + + + + When used in + conjunction with + + accept multiple passwords. This will + output one password per + line. + + + + + + + Exit status + + On success 0 is returned, a non-zero failure + code otherwise. + + + + See Also + + systemd1, + systemctl1, + plymouth8, + wall1 + + + + diff --git a/man/systemd-binfmt.service.xml b/man/systemd-binfmt.service.xml new file mode 100644 index 000000000..1db735a82 --- /dev/null +++ b/man/systemd-binfmt.service.xml @@ -0,0 +1,76 @@ + + + + + + + + systemd-binfmt.service + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd-binfmt.service + 8 + + + + systemd-binfmt.service + systemd-binfmt + Configure additional binary formats for executables at boot + + + + systemd-binfmt.service + /usr/lib/systemd/systemd-binfmt + + + + Description + + systemd-binfmt.service is + an early-boot service that registers additional binary + formats for executables in the kernel. + + See + binfmt.d5 + for information about the configuration of this + service. + + + + See Also + + systemd1, + binfmt.d5, + wine8 + + + + diff --git a/man/systemd-cat.xml b/man/systemd-cat.xml new file mode 100644 index 000000000..cac275b45 --- /dev/null +++ b/man/systemd-cat.xml @@ -0,0 +1,205 @@ + + + + + + + + + systemd-cat + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd-cat + 1 + + + + systemd-cat + Connect a pipeline or program's output with the journal + + + + + systemd-cat OPTIONS COMMAND ARGUMENTS + + + systemd-cat OPTIONS + + + + + Description + + systemd-cat may be used to + connect STDOUT and STDERR of a process with the + journal, or as a filter tool in a shell pipeline to + pass the output the previous pipeline element + generates to the journal. + + If no parameter is passed + systemd-cat will write + everything it reads from standard input (STDIN) to the journal. + + If parameters are passed they are executed as + command line with standard output (STDOUT) and standard + error output (STDERR) connected to the journal, so + that all it writes is stored in the journal. + + + + Options + + The following options are understood: + + + + + + + Prints a short help + text and exits. + + + + + + Prints a short version + string and exits. + + + + + + + Specify a short string + that is used to identify the logging + tool. If not specified no identifying + string is written to the journal. + + + + + + + Specify the default + priority level for the logged + messages. Pass one of + emerg, + alert, + crit, + err, + warning, + notice, + info, + debug, or a + value between 0 and 7 (corresponding + to the same named levels). These + priority values are the same as + defined by + syslog3. Defaults + to info. Note that + this simply controls the default, + individual lines may be logged with + different levels if they are prefixed + accordingly. For details see + + below. + + + + + + Controls whether lines + read are parsed for syslog priority + level prefixes. If enabled (the + default) a line prefixed with a + priority prefix such as + <5> is logged + at priority 5 + (notice), and + similar for the other priority + levels. Takes a boolean + argument. + + + + + + + + Exit status + + On success 0 is returned, a non-zero failure + code otherwise. + + + + Examples + + + Invoke a program + + This calls /bin/ls + with STDOUT/STDERR connected to the + journal: + + # systemd-cat ls + + + + Usage in a shell pipeline + + This builds a shell pipeline also + invoking /bin/ls and + writes the output it generates to the + journal: + + # ls | systemd-cat + + + Even though the two examples have very similar + effects the first is preferable since only one process + is running at a time, and both STDOUT and STDERR are + captured while in the second example only STDOUT is + captured. + + + + See Also + + systemd1, + systemctl1, + logger1 + + + + diff --git a/man/systemd-cgls.xml b/man/systemd-cgls.xml new file mode 100644 index 000000000..4b6ee93b4 --- /dev/null +++ b/man/systemd-cgls.xml @@ -0,0 +1,141 @@ + + + + + + + + + systemd-cgls + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd-cgls + 1 + + + + systemd-cgls + Recursively show control group contents + + + + + systemd-cgls OPTIONS CGROUP + + + + + Description + + systemd-cgls recursively + shows the contents of the selected Linux control group + hierarchy in a tree. If arguments are specified shows + all member processes of the specified control groups + plus all their subgroups and their members. The + control groups may either be specified by their full + file paths or are assumed in the systemd control group + hierarchy. If no argument is specified and the current + working directory is beneath the control group mount + point /sys/fs/cgroup shows the contents + of the control group the working directory refers + to. Otherwise the full systemd control group hierarchy + is shown. + + By default empty control groups are not + shown. + + + + Options + + The following options are understood: + + + + + + + Prints a short help + text and exits. + + + + + + Prints a short version + string and exits. + + + + + + Do not pipe output into a + pager. + + + + + + Don't hide empty + control groups in the + output. + + + + + + Include kernel + threads in output. + + + + + + + + Exit status + + On success 0 is returned, a non-zero failure + code otherwise. + + + + See Also + + systemd1, + systemctl1, + systemd-cgtop1, + ps1 + + + + diff --git a/man/systemd-cgtop.xml b/man/systemd-cgtop.xml new file mode 100644 index 000000000..7a34512b2 --- /dev/null +++ b/man/systemd-cgtop.xml @@ -0,0 +1,276 @@ + + + + + + + + + systemd-cgtop + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd-cgtop + 1 + + + + systemd-cgtop + Show top control groups by their resource usage + + + + + systemd-cgtop OPTIONS + + + + + Description + + systemd-cgtop shows the top + control groups of the local Linux control group + hierarchy, ordered by their CPU, memory and disk I/O load. The + display is refreshed in regular intervals (by default + every 1s), similar in style to + top1. + + Resource usage is only accounted for control + groups in the relevant hierarchy, i.e. CPU usage is + only accounted for control groups in the + cpuacct hierarchy, memory usage + only for those in memory and disk + I/O usage for those in + blkio. systemd1 + by default places all services in their own control + group in the cpuacct hierarchy, but + not in memory nor + blkio. If resource monitoring for + these resources is required it is recommended to add + blkio and memory + to the DefaultControllers= setting + in /etc/systemd/system.conf (see + systemd.conf5 + for details). Alternatively, it is possible to enable + resource accounting individually for services, by + making use of the ControlGroup= + option in the unit files (See + systemd.exec5 + for details). + + To emphasize this: unless + blkio and memory + are enabled for the services in question with either + of the options suggested above no resource accounting + will be available for system services and the data shown + by systemd-cgtop will be + incomplete. + + + + Options + + The following options are understood: + + + + + + + Prints a short help + text and exits. + + + + + + Prints a version string and + exits. + + + + + + Order by control group + path name. + + + + + + Order by number of + tasks in control + group (i.e. threads and processes). + + + + + + Order by CPU load. + + + + + + Order by memory usage. + + + + + + Order by disk I/O load. + + + + + + + Run in "batch" mode: + do not accept input and run until the + iteration limit set with + is + exhausted or until killed. This mode + could be useful for sending output + from systemd-cgtop + to other programs or to a + file. + + + + + + + Perform only this many + iterations. + + + + + + + Specify refresh delay + in seconds (or if one of + ms, + us, + min is specified as + unit in this time + unit). + + + + + + Maximum control group + tree traversal depth. Specifies how + deep systemd-cgtop + shall traverse the control group + hierarchies. If 0 is specified only + the root group is monitored, for 1 + only the first level of control groups + is monitored, and so on. Defaults to + 3. + + + + + + + + + Keys + + systemd-cgtop is an + interactive tool and may be controlled via user input + using the following keys: + + + + h + + Shows a short help text. + + + + SPACE + + Immediately refresh output. + + + + q + + Terminate the program. + + + + + p + t + c + m + i + + Sort the control groups + by path, number of tasks, CPU load, + memory usage, or IO + load, respectively. + + + + + + - + + Increase + or decrease refresh + delay, respectively. + + + + + + + Exit status + + On success 0 is returned, a non-zero failure + code otherwise. + + + + See Also + + systemd1, + systemctl1, + systemd-cgls1, + top1 + + + + diff --git a/man/systemd-coredumpctl.xml b/man/systemd-coredumpctl.xml new file mode 100644 index 000000000..53b82ed27 --- /dev/null +++ b/man/systemd-coredumpctl.xml @@ -0,0 +1,217 @@ + + + + + + + + + systemd-coredumpctl + systemd + + + + Developer + Zbigniew + Jędrzejewski-Szmek + zbyszek@in.waw.pl + + + + + + systemd-coredumpctl + 1 + + + + systemd-coredumpctl + Retrieve coredumps from the journal + + + + + systemd-coredumpctl + OPTIONS + COMMAND + PID|COMM|EXE|MATCH + + + + + Description + + systemd-coredumpctl may be used to + retrieve coredumps from + systemd-journald8. + + + + Options + + The following options are understood: + + + + + + + Print a short help + text and exit. + + + + + + Print a short version + string and exit. + + + + + + + Print all possible + data values the specified field + takes in matching coredump entries of the + journal. + + + + + + + Write the core to + . + + + + + + Do not pipe output of + list into a + pager. + + + + + + Do not print the column headers. + + + + + + The following commands are understood: + + + + list + + List coredumps captured in the journal + matching specified characteristics. + + + + dump + + Extract the last coredump + matching specified characteristics. + Coredump will be written on stdout, unless + an output file is specified with + . + + + + + + gdb + + Invoke the GNU + debugger on the last coredump matching + specified characteristics. + + + + + + + + + Matching + + Match can be: + + + + + + Process ID of the + process that dumped + core. An integer. + + + + + + Name of the executable + (matches ). + Must not contain slashes. + + + + + + + Path to the executable + (matches ). + Must contain at least one slash. + + + + + + + General journalctl predicates + (see journalctl1). + Must contain an equals sign. + + + + + + + Exit status + On success 0 is returned, a non-zero failure + code otherwise. Not finding any matching coredumps is treated + as failure. + + + + + See Also + + systemd-journald.service8, + gdb1 + + + + diff --git a/man/systemd-cryptsetup-generator.xml b/man/systemd-cryptsetup-generator.xml new file mode 100644 index 000000000..49d4d5545 --- /dev/null +++ b/man/systemd-cryptsetup-generator.xml @@ -0,0 +1,147 @@ + + + + + + + + systemd-cryptsetup-generator + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd-cryptsetup-generator + 8 + + + + systemd-cryptsetup-generator + Unit generator for /etc/crypttab + + + + /usr/lib/systemd/system-generators/systemd-cryptsetup-generator + + + + Description + + systemd-cryptsetup-generator + is a generator that translates + /etc/crypttab into native systemd + units early at boot and when configuration of the + system manager is reloaded. This will create + systemd-cryptsetup@.service8 + units as necessary. + + systemd-cryptsetup-generator + implements the generator + specification. + + + + Kernel Command Line + + systemd-cryptsetup-generator understands + the following kernel command line parameters: + + + + luks= + rd.luks= + + Takes a boolean + argument. Defaults to + yes. If + no disables the + generator + entirely. rd.luks= + is honored only by initial RAM disk + (initrd) while + luks= is honored + by both the main system and the + initrd. + + + + luks.crypttab= + rd.luks.crypttab= + + Takes a boolean + argument. Defaults to + yes. If + no causes the + generator to ignore any devices + configured in + /etc/crypttab + (luks.uuid= will + still work + however). rd.luks.crypttab= + is honored only by initial RAM disk + (initrd) while + luks.crypttab= is + honored by both the main system and + the initrd. + + + + luks.uuid= + rd.luks.uuid= + + Takes a LUKS super + block UUID as argument. This will + activate the specified device as part + of the boot process as if it was + listed in + /etc/fstab. This + option may be specified more than once + in order to set up multiple + devices. rd.luks.uuid= + is honored only by initial RAM disk + (initrd) while + luks.uuid= is + honored by both the main system and + the initrd. + + + + + + See Also + + systemd1, + crypttab5, + systemd-cryptsetup@.service8, + cryptsetup8, + systemd-fstab-generator8 + + + + diff --git a/man/systemd-cryptsetup@.service.xml b/man/systemd-cryptsetup@.service.xml new file mode 100644 index 000000000..abbb9d78f --- /dev/null +++ b/man/systemd-cryptsetup@.service.xml @@ -0,0 +1,87 @@ + + + + + + + + systemd-cryptsetup@.service + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd-cryptsetup@.service + 8 + + + + systemd-cryptsetup@.service + systemd-cryptsetup + Full disk decryption logic + + + + systemd-cryptsetup@.service + /usr/lib/systemd/systemd-cryptsetup + + + + Description + + systemd-cryptsetup@.service + is a service responsible for setting up encrypted + block devices. It is instantiated for each device that + requires decryption for access. + + systemd-cryptsetup@.service + will ask for hard disk passwords via the + password agent logic, in order to query the + user for the password using the right mechanism at + boot and during runtime. + + At early boot and when the system manager + configuration is reloaded this + /etc/crypttab is translated into + systemd-cryptsetup@.service units + by + systemd-cryptsetup-generator8. + + + + See Also + + systemd1, + systemd-cryptsetup-generator8, + crypttab5, + cryptsetup8 + + + + diff --git a/man/systemd-delta.xml b/man/systemd-delta.xml new file mode 100644 index 000000000..072f55f1a --- /dev/null +++ b/man/systemd-delta.xml @@ -0,0 +1,181 @@ + + + + + + + + + systemd-delta + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd-delta + 1 + + + + systemd-delta + Find overridden configuration files + + + + + systemd-delta OPTIONS SUFFIX + + + + + Description + + systemd-delta may be used to + identify and compare configuration files in + /etc that override default + counterparts in /usr. The command + line argument can be one or more name of a subdirectories of + /etc or + /usr/lib to compare, such as + tmpfiles.d, sysctl.d or + systemd/system. + + When no argument is specified a number of + well-known subdirectories are searched for overridden + files. + + + + Options + + The following options are understood: + + + + + + + Prints a short help + text and exits. + + + + + + Prints a short version + string and exits. + + + + + + Do not pipe output into a + pager. + + + + + + + When listing the + differences, only list those that are + asked for. The list itself is a + comma-separated list of desired + difference types. + + Recognized types are: + + + + masked + + Show masked files + + + + equivalent + + Show overridden + files that while overridden, do + not differ in content. + + + + redirected + + Show files that + are redirected to another. + + + + overridden + + Show overridden, + and changed files. + + + + unchanged + + Show unmodified + files too. + + + + + + + + + When showing modified + files, when a file is overridden show a + diff as well. This option takes a + boolean argument. If omitted it defaults + to . + + + + + + + + Exit status + + On success 0 is returned, a non-zero failure + code otherwise. + + + + See Also + + systemd1 + + + + diff --git a/man/systemd-detect-virt.xml b/man/systemd-detect-virt.xml new file mode 100644 index 000000000..762b6ab99 --- /dev/null +++ b/man/systemd-detect-virt.xml @@ -0,0 +1,151 @@ + + + + + + + + + systemd-detect-virt + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd-detect-virt + 1 + + + + systemd-detect-virt + Detect execution in a virtualized environment + + + + + systemd-detect-virt OPTIONS + + + + + Description + + systemd-detect-virt detects + execution in a virtualized environment. It identifies + the virtualization technology and can distinguish full + VM virtualization from container + virtualization. + + When executed without + will print a short identifier for the detected + virtualization technology. The following technologies + are currently identified: qemu, + kvm, vmware, + microsoft, + oracle, xen, + bochs, chroot, + openvz, lxc, + lxc-libvirt, + systemd-nspawn. + + If multiple virtualization solutions are used + only the "innermost" is detected and identified. That + means if both VM virtualization and container + virtualization are used in conjunction only the latter + will be identified (unless is + passed). + + + + Options + + The following options are understood: + + + + + + + Prints a short help + text and exits. + + + + + + Prints a short version + string and exits. + + + + + + + Only detects container + virtualization (i.e. shared kernel + virtualization). + + + + + + + Only detects VM + virtualization (i.e. full hardware + virtualization). + + + + + + + Suppress output of the + virtualization technology + identifier. + + + + + + + + Exit status + + If a virtualization technology is detected 0 is + returned, a non-zero code otherwise. + + + + See Also + + systemd1 + + + + diff --git a/man/systemd-fsck@.service.xml b/man/systemd-fsck@.service.xml new file mode 100644 index 000000000..62f63110e --- /dev/null +++ b/man/systemd-fsck@.service.xml @@ -0,0 +1,110 @@ + + + + + + + + systemd-fsck@.service + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd-fsck@.service + 8 + + + + systemd-fsck@.service + systemd-fsck-root.service + systemd-fsck + File system checker logic + + + + systemd-fsck@.service + systemd-fsck-root.service + /usr/lib/systemd/systemd-fsck + + + + Description + + systemd-fsck@.service is a + service responsible for file system checks. It is + instantiated for each device that requires a file + system + check. systemd-fsck-root.service is + responsible for file system checks on the root + file system. + + systemd-fsck will + forward file system checking progress to the + console. If a file system check fails emergency mode + is activated, by isolating to + emergency.target. + + + + Kernel Command Line + + systemd-fsck understands + one kernel command line parameter: + + + + fsck.mode= + + One of + auto, + force, + skip. Controls the + mode of operation. The default is + auto, and ensures + that file system checks are done when + the file system checker deems them + necessary. force + unconditionally results in full file + system checks. skip + skips any file system + checks. + + + + + + See Also + + systemd1, + fsck8, + systemd-quotacheck.service8 + + + + diff --git a/man/systemd-fstab-generator.xml b/man/systemd-fstab-generator.xml new file mode 100644 index 000000000..b265b6c08 --- /dev/null +++ b/man/systemd-fstab-generator.xml @@ -0,0 +1,118 @@ + + + + + + + + systemd-fstab-generator + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd-fstab-generator + 8 + + + + systemd-fstab-generator + Unit generator for /etc/fstab + + + + /usr/lib/systemd/system-generators/systemd-fstab-generator + + + + Description + + systemd-fstab-generator is + a generator that translates + /etc/fstab (see + fstab5 + for details) into native systemd units early at boot + and when configuration of the system manager is + reloaded. This will instantiate mount and swap units + as necessary. + + See + systemd.mount5 + and + systemd.swap5 + for more information about special + /etc/fstab mount options this + generator understands. + + systemd-fstab-generator + implements the generator + specification. + + + + Kernel Command Line + + systemd-fstab-generator understands + the following kernel command line parameters: + + + + + fstab= + rd.fstab= + + Takes a boolean + argument. Defaults to + yes. If + no causes the + generator to ignore any mounts or swaps + configured in + /etc/fstab. rd.fstab= + is honored only by initial RAM disk + (initrd) while + fstab= is + honored by both the main system and + the initrd. + + + + + + + See Also + + systemd1, + fstab5, + systemd.mount5, + systemd.swap5, + systemd-cryptsetup-generator8 + + + + diff --git a/man/systemd-getty-generator.xml b/man/systemd-getty-generator.xml new file mode 100644 index 000000000..da88e727c --- /dev/null +++ b/man/systemd-getty-generator.xml @@ -0,0 +1,96 @@ + + + + + + + + systemd-getty-generator + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd-getty-generator + 8 + + + + systemd-getty-generator + Generator for enabling getty instances on + the console + + + + /usr/lib/systemd/system-generators/systemd-getty-generator + + + + Description + + systemd-getty-generator is + a generator that automatically instantiates + serial-getty@.service on the + kernel console /dev/console if + that is not directed to the virtual console + subsystem. It will also instantiate + serial-getty@.service instances + for virtualizer consoles, if execution in a + virtualized environment is detected. This should + ensure that the user is shown a login prompt at the + right place, regardless in which environment the + system is started. For example, it is sufficient to + redirect the kernel console with a kernel command line + argument such as console= to get + both kernel messages and a getty prompt on a serial + TTY. See kernel-parameters.txt + for more information on the + console= kernel parameter. + + systemd-getty-generator + implements the generator + specification. + + Further information about configuration of + gettys you may find in systemd + for Administrators, Part XVI: Gettys on Serial + Consoles (and Elsewhere). + + + + See Also + + systemd1, + agetty8 + + + + diff --git a/man/systemd-halt.service.xml b/man/systemd-halt.service.xml new file mode 100644 index 000000000..6a6bfdc7d --- /dev/null +++ b/man/systemd-halt.service.xml @@ -0,0 +1,119 @@ + + + + + + + + + systemd-halt.service + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd-halt.service + 8 + + + + systemd-halt.service + systemd-poweroff.service + systemd-reboot.service + systemd-kexec.service + systemd-shutdown + System shutdown logic + + + + systemd-halt.service + systemd-poweroff.service + systemd-reboot.service + systemd-kexec.service + /usr/lib/systemd/systemd-shutdown + + + + Description + + systemd-halt.service is a + system service that is pulled in by + halt.target and is responsible + for the actual system halt. Similar, + systemd-poweroff.service is + pulled in by poweroff.target, + systemd-reboot.service by + reboot.target and + systemd-kexec.service by + kexec.target to execute the + respective actions. + + When these services are run they ensure that PID + 1 is replaced by the + /usr/lib/systemd/systemd-shutdown + tool which is then responsible for the actual + shutdown. Before shutting down this binary will try to + unmount all remaining file systems, disable all + remaining swap devices, detach all remaining storage + devices and kill all remaining processes. + + Immediately before executing the actual system + halt/poweroff/reboot/kexec + systemd-shutdown will run all + executables in + /usr/lib/systemd/system-shutdown/ + and pass one arguments to them: either + "halt", + "poweroff", + "reboot" or + "kexec", depending on the chosen + action. All executables in this directory are executed + in parallel, and execution of the action is not + continued before all executables finished. + + Note that + systemd-halt.service (and the + related units) should never be executed + directly. Instead, trigger system shutdown with a + command such as "systemctl halt" or + suchlike. + + + + See Also + + systemd1, + systemctl1, + systemd.special7, + reboot2, + systemd-suspend.service8 + + + + diff --git a/man/systemd-hostnamed.service.xml b/man/systemd-hostnamed.service.xml new file mode 100644 index 000000000..d9c191101 --- /dev/null +++ b/man/systemd-hostnamed.service.xml @@ -0,0 +1,87 @@ + + + + + + + + + systemd-hostnamed.service + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd-hostnamed.service + 8 + + + + systemd-hostnamed.service + systemd-hostnamed + Hostname bus mechanism + + + + systemd-hostnamed.service + /usr/lib/systemd/systemd-hostnamed + + + + Description + + systemd-hostnamed is a system + service that may be used as mechanism to change the + system hostname. systemd-hostnamed is + automatically activated on request and terminates + itself when it is unused. + + The tool + hostnamectl1 + is a command line client to this service. + + See the + developer documentation for information about + the APIs systemd-hostnamed + provides. + + + + See Also + + systemd1, + hostname5, + machine-info5, + hostnamectl1, + sethostname2 + + + + diff --git a/man/systemd-inhibit.xml b/man/systemd-inhibit.xml new file mode 100644 index 000000000..6f63c8c73 --- /dev/null +++ b/man/systemd-inhibit.xml @@ -0,0 +1,205 @@ + + + + + + + + + systemd-inhibit + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd-inhibit + 1 + + + + systemd-inhibit + Execute a program with an inhibition lock taken + + + + + systemd-inhibit OPTIONS COMMAND ARGUMENTS + + + systemd-inhibit OPTIONS --list + + + + + Description + + systemd-inhibit may be used + to execute a program with a shutdown, sleep or idle + inhibitor lock taken. The lock will be acquired before + the specified command line is executed and released + afterwards. + + Inhibitor locks may be used to block or delay + system sleep and shutdown requests from the user, as well + as automatic idle handling of the OS. This is useful + to avoid system suspends while an optical disc is + being recorded, or similar operations that should not + be interrupted. + + For more information see the Inhibitor + Lock Developer Documentation. + + + + Options + + The following options are understood: + + + + + + + Prints a short help + text and exits. + + + + + + Prints a short version + string and exits. + + + + + + Takes a colon + separated list of one or more + operations to inhibit: + shutdown, + sleep, + idle, + handle-power-key, + handle-suspend-key, + handle-hibernate-key, + handle-lid-switch, + for inhibiting + reboot/power-off/halt/kexec, + suspending/hibernating, the automatic + idle detection, or the low-level + handling of the power/sleep key and + the lid switch, respectively. If omitted, + defaults to + idle:sleep:shutdown. + + + + + + Takes a short human + readable descriptive string for the + program taking the lock. If not passed + defaults to the command line + string. + + + + + + Takes a short human + readable descriptive string for the + reason for taking the lock. Defaults + to "Unknown reason". + + + + + + Takes either + block or + delay and describes + how the lock is applied. If + block is used (the + default), the lock prohibits any of + the requested operations without time + limit, and only privileged users may + override it. If + delay is used, the + lock can only delay the requested + operations for a limited time. If the + time elapses the lock is ignored and + the operation executed. The time limit + may be specified in + systemd-logind.conf5. Note + that delay is only + available for sleep + and + shutdown. + + + + + + Lists all active + inhibition locks instead of acquiring + one. + + + + + + + Exit status + + Returns the exit status of the executed program. + + + + Example + + # systemd-inhibit wodim foobar.iso + + This burns the ISO image + foobar.iso on a CD using + wodim1, + and inhibits system sleeping, shutdown and idle while + doing so. + + + + See Also + + systemd1, + systemd-logind.conf5 + + + + diff --git a/man/systemd-initctl.service.xml b/man/systemd-initctl.service.xml new file mode 100644 index 000000000..eda6459b5 --- /dev/null +++ b/man/systemd-initctl.service.xml @@ -0,0 +1,76 @@ + + + + + + + + + systemd-initctl.service + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd-initctl.service + 8 + + + + systemd-initctl.service + systemd-initctl.socket + systemd-initctl + /dev/initctl compatibility + + + + systemd-initctl.service + systemd-initctl.socket + /usr/lib/systemd/systemd-initctl + + + + Description + + systemd-initctl is a system + service that implements compatibility with the + /dev/initctl FIFO file system + object, as implemented by the SysV init system. systemd-initctl is + automatically activated on request and terminates + itself when it is unused. + + + + See Also + + systemd1 + + + + diff --git a/man/systemd-journal-gatewayd.service.xml b/man/systemd-journal-gatewayd.service.xml new file mode 100644 index 000000000..562d22186 --- /dev/null +++ b/man/systemd-journal-gatewayd.service.xml @@ -0,0 +1,274 @@ + + + + + + + + + systemd-journal-gatewayd.service + systemd + + + + Developer + Zbigniew + Jędrzejewski-Szmek + zbyszek@in.waw.pl + + + + + + systemd-journal-gatewayd.service + 8 + + + + systemd-journal-gatewayd.service + systemd-journal-gatewayd.socket + systemd-journal-gatewayd + HTTP server for journal events + + + + systemd-journal-gatewayd.service + systemd-journal-gatewayd.socket + /usr/lib/systemd/systemd-journal-gatewayd + + + + + Description + + systemd-journal-gatewayd serves journal + events over the network. Clients must connect using + HTTP. The server listens on port 19531 by default. + + The program is started by + systemd1 + and expects to receive a single socket. Use + systemctl start systemd-journal-gatewayd.socket to start + the service, and systemctl enable systemd-journal-gatewayd.socket + to have it started on boot. + + + + Supported URLs + + The following URLs are recognized: + + + + + + Interactive browsing. + + + + + + Retrieval of events in various formats. + + The part of the HTTP header + determines the format. Supported values are described below. + + + The part of the HTTP header + determines the range of events returned. Supported values are + described below. + + + GET parameters can be used to modify what events are + returned. Supported parameters are described below. + + + + + + + Return a JSON structure describing the machine. + + Example: + +{ "machine_id" : "8cf7ed9d451ea194b77a9f118f3dc446", + "boot_id" : "3d3c9efaf556496a9b04259ee35df7f7", + "hostname" : "fedora", + "os_pretty_name" : "Fedora 19 (Rawhide)", + "virtualization" : "kvm", + ...} + + + + + + + FIELD_NAME + + Return a list of values of this field present in the logs. + + + + + + + Accept header + + + format + + + Recognized formats: + + + + + + The default. Plaintext syslog-like output, + one line per journal entry + (like journalctl --output short). + + + + + + + Entries are formatted as JSON data structures, + one per line + (like journalctl --output json). + See Journal + JSON Format for more information. + + + + + + + Entries are formatted as JSON data structures, + wrapped in a format suitable for + Server-Sent Events + (like journalctl --output json-sse). + + + + + + + + Entries are serialized into a binary (but + mostly text-based) stream suitable for backups and network + transfer + (like journalctl --output export). + See Journal + Export Format for more information. + + + + + + + Range header + + + + + + where + is a cursor string, + is an integer, + is an unsigned integer. + + + Range defaults to all available events. + + + + URL GET parameters + + Following parameters can be used as part of the URL: + + + + + + wait for new events + (like journalctl --follow, except that + the number of events returned is not limited). + + + + + + + Test that the specified cursor refers to an + entry in the journal. Returns just this entry. + + + + + + + Limit events to the current boot of the system + (like journalctl --this--boot). + + + + + + Match journal fields. See + systemd.journal-fields7. + + + + + + + Examples + Retrieve events from this boot from local journal + in Journal + Export Format: + +curl --silent -H'Accept: application/vnd.fdo.journal' \ + 'http://localhost:19531/entries?boot' + + + + Listen for core dumps: + +curl 'http://localhost:19531/entries?follow&MESSAGE_ID=fc2e22bc6ee647b6b90729ab34a250b1' + + + + + See Also + + systemd1, + journalctl1, + systemd-journald.service8, + systemd.journal-fields7, + + + + diff --git a/man/systemd-journald.service.xml b/man/systemd-journald.service.xml new file mode 100644 index 000000000..abc03df5d --- /dev/null +++ b/man/systemd-journald.service.xml @@ -0,0 +1,173 @@ + + + + + + + + + systemd-journald.service + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd-journald.service + 8 + + + + systemd-journald.service + systemd-journald.socket + systemd-journald + Journal service + + + + systemd-journald.service + systemd-journald.socket + /usr/lib/systemd/systemd-journald + + + + Description + + systemd-journald is a + system service that collects and stores logging + data. It creates and maintains structured, indexed + journals based on logging information that is received + from the kernel, from user processes via the libc + syslog3 + call, from STDOUT/STDERR of system services or via its + native API. It will implicitly collect numerous meta + data fields for each log messages in a secure and + unfakeable way. See + systemd.journal-fields7 + for more information about the collected meta data. + + + Log data collected by the journal is primarily + text based but can also include binary data where + necessary. All objects stored in the journal can be up + to 2^64-1 bytes in size. + + By default the journal stores log data in + /run/log/journal/. Since + /run/ is volatile log data is + lost at reboot. To make the data persistent it + is sufficient to create + /var/log/journal/ where + systemd-journald will then store + the data. + + systemd-journald will + forward all received log messages to the AF_UNIX + SOCK_DGRAM socket + /run/systemd/journal/syslog (if it exists) which + may be used by UNIX syslog daemons to process the data + further. + + See + journald.conf5 + for information about the configuration of this + service. + + + + Signals + + + + SIGUSR1 + + Request that journal + data from /run/ + is flushed to + /var/ in order to + make it persistent (if this is + enabled). This may be used after + /var/ is mounted, + but is generally not required since + the first journal write when + /var/ becomes + writable triggers the flushing + anyway. + + + + SIGUSR2 + + Request immediate + rotation of the journal + files. + + + + + + Kernel Command Line + + A few configuration parameters from + journald.conf may be overridden on + the kernel command line: + + + + systemd.journald.forward_to_syslog= + systemd.journald.forward_to_kmsg= + systemd.journald.forward_to_console= + + Enables/disables + forwarding of collected log messages + to syslog, the kernel log buffer or + the system console. + + + See + journald.conf5 + for information about these settings. + + + + + + + + + See Also + + systemd1, + journalctl1, + journald.conf5, + systemd.journal-fields7, + sd-journal3 + + + + diff --git a/man/systemd-localed.service.xml b/man/systemd-localed.service.xml new file mode 100644 index 000000000..6cefc4265 --- /dev/null +++ b/man/systemd-localed.service.xml @@ -0,0 +1,89 @@ + + + + + + + + + systemd-localed.service + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd-localed.service + 8 + + + + systemd-localed.service + systemd-localed + Locale bus mechanism + + + + systemd-localed.service + /usr/lib/systemd/systemd-localed + + + + Description + + systemd-localed is a system + service that may be used as mechanism to change the + system locale settings, as well as the console key + mapping and default X11 key + mapping. systemd-localed is + automatically activated on request and terminates + itself when it is unused. + + The tool + localectl1 + is a command line client to this service. + + See the + developer documentation for information about + the APIs systemd-localed + provides. + + + + See Also + + systemd1, + locale.conf5, + vconsole.conf5, + localectl1, + loadkeys1 + + + + diff --git a/man/systemd-logind.service.xml b/man/systemd-logind.service.xml new file mode 100644 index 000000000..00f34051a --- /dev/null +++ b/man/systemd-logind.service.xml @@ -0,0 +1,133 @@ + + + + + + + + + systemd-logind.service + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd-logind.service + 8 + + + + systemd-logind.service + systemd-logind + Login manager + + + + systemd-logind.service + /usr/lib/systemd/systemd-logind + + + + Description + + systemd-logind is a system + service that manages user logins. It is responsible + for: + + + Keeping track of users and sessions, their + processes and their idle state + + Creating control groups for + user processes + + Providing PolicyKit-based access + for users to operations such as system + shutdown or sleep + + Implementing a shutdown/sleep + inhibition logic for + applications + + Handling of power/sleep + hardware keys + + Multi-seat + management + + Session + switch management + + Device access management for + users + + Automatic spawning of text + logins (gettys) on virtual console activation + and user runtime directory + management + + + User sessions are registered in logind via the + pam_systemd8 + PAM module. + + See + logind.conf5 + for information about the configuration of this + service. + + See Multi-Seat + on Linux for an introduction into basic + concepts of logind such as users, sessions and seats. + + See the + logind D-Bus API Documentation for information about + the APIs systemd-logind + provides. + + For more information on the inhibition logic see + the Inhibitor + Lock Developer Documentation. + + + + See Also + + systemd1, + systemd-user-sessions.service8, + loginctl1, + logind.conf5, + pam_systemd8 + + + + diff --git a/man/systemd-machine-id-setup.xml b/man/systemd-machine-id-setup.xml new file mode 100644 index 000000000..25fb63af2 --- /dev/null +++ b/man/systemd-machine-id-setup.xml @@ -0,0 +1,132 @@ + + + + + + + + + systemd-machine-id-setup + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd-machine-id-setup + 1 + + + + systemd-machine-id-setup + Initialize the machine ID in /etc/machine-id + + + + + systemd-machine-id-setup + + + + + Description + + systemd-machine-id-setup may + be used by system installer tools to initialize the + machine ID stored in + /etc/machine-id at install time + with a randomly generated ID. See + machine-id5 + for more information about this file. + + This tool will execute no operation if + /etc/machine-id is already + initialized. + + If a valid D-Bus machine ID is already + configured for the system the D-Bus machine ID is + copied and used to initialize the machine ID in + /etc/machine-id. + + If run inside a KVM virtual machine and a UUID + is passed via the option this + UUID is used to initialize the machine ID instead of a + randomly generated one. The caller must ensure that the + UUID passed is sufficiently unique and is different + for every booted instanced of the VM. + + Similar, if run inside a Linux container + environment and a UUID is set for the container this + is used to initialize the machine ID. For details see + the documentation of the Container + Interface. + + + + + Options + + The following options are understood: + + + + + + + Prints a short help + text and exits. + + + + + + Prints a short version + string and exits. + + + + + + + Exit status + + On success 0 is returned, a non-zero failure + code otherwise. + + + + See Also + + systemd1, + machine-id5, + dbus-uuidgen1 + + + + diff --git a/man/systemd-modules-load.service.xml b/man/systemd-modules-load.service.xml new file mode 100644 index 000000000..e5f10a7be --- /dev/null +++ b/man/systemd-modules-load.service.xml @@ -0,0 +1,101 @@ + + + + + + + + systemd-modules-load.service + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd-modules-load.service + 8 + + + + systemd-modules-load.service + systemd-modules-load + Configure kernel modules to load at boot + + + + systemd-modules-load.service + /usr/lib/systemd/systemd-modules-load + + + + Description + + systemd-modules-load.service + is an early-boot service that loads kernel modules + from static configuration. + + See + modules-load.d5 + for information about the configuration of this + service. + + + + + Kernel Command Line + + systemd-modules-load.service understands + the following kernel command line parameters: + + + + + modules-load= + rd.modules-load= + + Takes a comma + separated list of kernel modules to + statically load during early boot. The + option prefixed with + rd. is read by the + initial RAM disk + only. + + + + + + + See Also + + systemd1, + modules-load.d5, + wine8 + + + + diff --git a/man/systemd-notify.xml b/man/systemd-notify.xml new file mode 100644 index 000000000..b03492c5c --- /dev/null +++ b/man/systemd-notify.xml @@ -0,0 +1,218 @@ + + + + + + + + + systemd-notify + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd-notify + 1 + + + + systemd-notify + Notify service manager about start-up completion and other daemon status changes + + + + + systemd-notify OPTIONS VARIABLE=VALUE + + + + + Description + + systemd-notify may be + called by daemon scripts to notify the init system + about status changes. It can be used to send arbitrary + information, encoded in an environment-block-like list + of strings. Most importantly it can be used for + start-up completion notification. + + This is mostly just a wrapper around + sd_notify() and makes this + functionality available to shell scripts. For details + see + sd_notify3. + + The command line may carry a list of + environment variables to send as part of the status + update. + + Note that systemd will refuse reception of + status updates from this command unless + NotifyAccess=all is set for the + service unit this command is called from. + + + + + Options + + The following options are understood: + + + + + + + Prints a short help + text and exits. + + + + + + Prints a short version + string and exits. + + + + + + Inform the init system + about service start-up + completion. This is equivalent to + systemd-notify + READY=1. For details about + the semantics of this option see + sd_notify3. + + + + + + Inform the init system + about the main PID of the + daemon. Takes a PID as argument. If + the argument is omitted the PID of the + process that invoked + systemd-notify is + used. This is equivalent to + systemd-notify + MAINPID=$PID. For details + about the semantics of this option see + sd_notify3. + + + + + + Send a free-form + status string for the daemon to the + init systemd. This option takes the + status string as argument. This is + equivalent to systemd-notify + STATUS=.... For details + about the semantics of this option see + sd_notify3. + + + + + + Returns 0 if the + system was booted up with systemd, + non-zero otherwise. If this option is + passed no message is sent. This option + is hence unrelated to the other + options. For details about the + semantics of this option see + sd_booted3. + + + + + + Controls disk + read-ahead operations. The argument + must be a string, and either "cancel", + "done" or "noreplay". For details + about the semantics of this option see + sd_readahead3. + + + + + + + Exit status + + On success 0 is returned, a non-zero failure + code otherwise. + + + + Example + + + Start-up Notification and Status Updates + + A simple shell daemon that sends + start-up notifications after having set up its + communication channel. During runtime it sends + further status updates to the init + system: + + #!/bin/bash + +mkfifo /tmp/waldo +systemd-notify --ready --status="Waiting for data..." + +while : ; do + read a < /tmp/waldo + systemd-notify --status="Processing $a" + + # Do something with $a ... + + systemd-notify --status="Waiting for data..." +done + + + + + See Also + + systemd1, + systemctl1, + systemd.unit5, + sd_notify3, + sd_booted3 + + + + diff --git a/man/systemd-nspawn.xml b/man/systemd-nspawn.xml new file mode 100644 index 000000000..fef5c2c83 --- /dev/null +++ b/man/systemd-nspawn.xml @@ -0,0 +1,331 @@ + + + + + + + + + systemd-nspawn + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd-nspawn + 1 + + + + systemd-nspawn + Spawn a namespace container for debugging, testing and building + + + + + systemd-nspawn OPTIONS COMMAND ARGS + + + + + Description + + systemd-nspawn may be used to + run a command or OS in a light-weight namespace + container. In many ways it is similar to + chroot1, + but more powerful since it fully virtualizes the file + system hierarchy, as well as the process tree, the + various IPC subsystems and the host and domain + name. + + systemd-nspawn limits access + to various kernel interfaces in the container to + read-only, such as /sys, + /proc/sys or + /sys/fs/selinux. Network + interfaces and the system clock may not be changed + from within the container. Device nodes may not be + created. The host system cannot be rebooted and kernel + modules may not be loaded from within the + container. + + Note that even though these security precautions + are taken systemd-nspawn is not + suitable for secure container setups. Many of the + security features may be circumvented and are hence + primarily useful to avoid accidental changes to the + host system from the container. The intended use of + this program is debugging and testing as well as + building of packages, distributions and software + involved with boot and systems management. + + In contrast to + chroot1 + systemd-nspawn may be used to boot + full Linux-based operating systems in a + container. + + Use a tool like + yum8 + or + debootstrap8 + to set up an OS directory tree suitable as file system + hierarchy for systemd-nspawn + containers. + + Note that systemd-nspawn will + mount file systems private to the container to + /dev, + /run and similar. These will + not be visible outside of the container, and their + contents will be lost when the container exits. + + Note that running two + systemd-nspawn containers from the + same directory tree will not make processes in them + see each other. The PID namespace separation of the + two containers is complete and the containers will + share very few runtime objects except for the + underlying file system. + + systemd-nspawn implements the + Container + Interface specification. + + + + Options + + If no arguments are passed the container is set + up and a shell started in it, otherwise the passed + command and arguments are executed in it. The + following options are understood: + + + + + + + Prints a short help + text and exits. + + + + + + + Directory to use as + file system root for the namespace + container. If omitted the current + directory will be + used. + + + + + + + Automatically search + for an init binary and invoke it + instead of a shell or a user supplied + program. + + + + + + + Run the command + under specified user, create home + directory and cd into it. As rest + of systemd-nspawn, this is not + the security feature and limits + against accidental changes only. + + + + + + + Set the specified uuid + for the container. The init system + will initialize + /etc/machine-id + from this if this file is not set yet. + + + + + + + + Makes the container appear in + other hierarchies than the name=systemd:/ one. + Takes a comma-separated list of controllers. + + + + + + + Turn off networking in + the container. This makes all network + interfaces unavailable in the + container, with the exception of the + loopback device. + + + + + + Mount the root file + system read only for the + container. + + + + + + List one or more + additional capabilities to grant the + container. Takes a comma separated + list of capability names, see + capabilities7 + 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. + + + + + + Control whether the + container's journal shall be made + visible to the host system. If enabled + allows viewing the container's journal + files from the host (but not vice + versa). Takes one of + no, + host, + guest, + auto. If + no, the journal is + not linked. If host, + the journal files are stored on the + host file system (beneath + /var/log/journal/<machine-id>) + and the subdirectory is bind-mounted + into the container at the same + location. If guest, + the journal files are stored on the + guest file system (beneath + /var/log/journal/<machine-id>) + and the subdirectory is symlinked into the host + at the same location. If + auto (the default), + and the right subdirectory of + /var/log/journal + exists, it will be bind mounted + into the container. If the + subdirectory doesn't exist, no + linking is performed. Effectively, + booting a container once with + guest or + host will link the + journal persistently if further on + the default of auto + is used. + + + + + + Equivalent to + . + + + + + + + Example 1 + + # yum --releasever=17 --nogpgcheck --installroot ~/fedora-tree/ install yum passwd vim-minimal rootfiles systemd +# systemd-nspawn -D ~/fedora-tree /usr/lib/systemd/systemd + + This installs a minimal Fedora distribution into + the directory ~/fedora-tree/ + and then boots an OS in a namespace container in it, + with systemd as init system. + + + + Example 2 + + # debootstrap --arch=amd64 unstable ~/debian-tree/ +# systemd-nspawn -D ~/debian-tree/ + + This installs a minimal Debian unstable + distribution into the directory + ~/debian-tree/ and then spawns a + shell in a namespace container in it. + + + + + Exit status + + The exit code of the program executed in the + container is returned. + + + + See Also + + systemd1, + chroot1, + yum8, + debootstrap8 + + + + diff --git a/man/systemd-quotacheck.service.xml b/man/systemd-quotacheck.service.xml new file mode 100644 index 000000000..4d0218b65 --- /dev/null +++ b/man/systemd-quotacheck.service.xml @@ -0,0 +1,102 @@ + + + + + + + + systemd-quotacheck.service + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd-quotacheck.service + 8 + + + + systemd-quotacheck.service + systemd-quotacheck + File system quota checker logic + + + + systemd-quotacheck.service + /usr/lib/systemd/systemd-quotacheck + + + + Description + + systemd-quotacheck.service + is a service responsible for file system quota + checks. It is run once at boot after all necessary + file systems are mounted. It is pulled in only if at + least one file system has quotas enabled. + + + + Kernel Command Line + + systemd-quotacheck understands + one kernel command line parameter: + + + + quotacheck.mode= + + One of + auto, + force, + skip. Controls the + mode of operation. The default is + auto, and ensures + that file system quota checks are done + when the file system quota checker + deems them + necessary. force + unconditionally results in full file + system quota + checks. skip skips + any file system quota + checks. + + + + + + See Also + + systemd1, + quotacheck8, + systemd-fsck@.service8 + + + + diff --git a/man/systemd-random-seed-load.service.xml b/man/systemd-random-seed-load.service.xml new file mode 100644 index 000000000..87f563e29 --- /dev/null +++ b/man/systemd-random-seed-load.service.xml @@ -0,0 +1,80 @@ + + + + + + + + systemd-random-seed-load.service + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd-random-seed-load.service + 8 + + + + systemd-random-seed-load.service + systemd-random-seed-save.service + systemd-random-seed + Load and save the system random seed at boot and shutdown + + + + systemd-random-seed-load.service + systemd-random-seed-save.service + /usr/lib/systemd/systemd-random-seed + + + + Description + + systemd-random-seed-load.service + is an early-boot service that restores the random seed + of the + system. systemd-random-seed-save.service + is a late-shutdown service that saves the random seed + of the system. See + random4 + for details. Saving/restoring the random seed across + boots increases the amount of available entropy early + at boot. On disk the random seed is stored in + /var/lib/random-seed. + + + + See Also + + systemd1, + random4 + + + + diff --git a/man/systemd-readahead-replay.service.xml b/man/systemd-readahead-replay.service.xml new file mode 100644 index 000000000..66d253454 --- /dev/null +++ b/man/systemd-readahead-replay.service.xml @@ -0,0 +1,113 @@ + + + + + + + + + systemd-readahead-replay.service + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd-readahead-replay.service + 8 + + + + systemd-readahead-replay.service + systemd-readahead-collect.service + systemd-readahead-done.service + systemd-readahead-done.timer + systemd-readahead + Disk read ahead logic + + + + systemd-readahead-replay.service + systemd-readahead-collect.service + systemd-readahead-done.service + systemd-readahead-done.timer + /usr/lib/systemd/systemd-readahead + + + + Description + + systemd-readahead-collect.service + is a service that collects disk usage patterns at boot + time. systemd-readahead-replay.service + is a service that replays this access data collected + at the subsequent boot. Since disks tend to be + magnitudes slower than RAM this is intended to improve + boot speeds by pre-loading early at boot all data on + disk that is known to be read for the complete boot + process. + + systemd-readahead-done.service + is executed a short while after boot completed and signals + systemd-readahead-collect.service + to end data collection. On this signal this service + will then sort the collected disk accesses and store + information about them disk in + /.readahead. + + Normally, both + systemd-readahead-collect.service + and + systemd-readahead-replay.service + are activated at boot so that access patterns from the + preceding boot are replayed and new data collected + for the subsequent boot. However, on read-only media + where the collected data cannot be stored it might + be a good idea to disable + systemd-readahead-collect.service. + + On rotating media, when replaying disk accesses + at early boot + systemd-readahead-replay.service + will order read requests by their location on disk. On + non-rotating media, they will be ordered by their + original access timestamp. If the file system supports + it + systemd-readahead-collect.service + will also defragment and rearrange files on disk to + optimize subsequent boot times. + + + + See Also + + systemd1 + + + + diff --git a/man/systemd-remount-fs.service.xml b/man/systemd-remount-fs.service.xml new file mode 100644 index 000000000..d920c0c40 --- /dev/null +++ b/man/systemd-remount-fs.service.xml @@ -0,0 +1,87 @@ + + + + + + + + systemd-remount-fs.service + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd-remount-fs.service + 8 + + + + systemd-remount-fs.service + systemd-remount-fs + Remount root and kernel file systems + + + + systemd-remount-fs.service + /usr/lib/systemd/systemd-remount-fs + + + + Description + + systemd-remount-fs.service + is an early-boot service that applies mount options + listed in + fstab5 + to the root file system, the /usr + file system and the kernel API virtual file + systems. This is required so that the mount options of + these file systems -- which are pre-mounted by the + kernel, the initial RAM disk, container environments + or system manager code -- are updated to those listed + in /etc/fstab. This service + ignores normal file systems and only changes the root + file system (i.e. /), + /usr and the virtual kernel API + file systems such as /proc, + /sys or + /dev/. This service executes no + operation if /etc/fstab does not + exist or lists no entries for the mentioned file systems. + + + + See Also + + systemd1, + fstab5, + mount8 + + + + diff --git a/man/systemd-shutdownd.service.xml b/man/systemd-shutdownd.service.xml new file mode 100644 index 000000000..c1b8ef7a4 --- /dev/null +++ b/man/systemd-shutdownd.service.xml @@ -0,0 +1,77 @@ + + + + + + + + + systemd-shutdownd.service + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd-shutdownd.service + 8 + + + + systemd-shutdownd.service + systemd-shutdownd.socket + systemd-shutdownd + Scheduled shutdown service + + + + systemd-shutdownd.service + systemd-shutdownd.socket + /usr/lib/systemd/systemd-shutdownd + + + + Description + + systemd-shutdownd.service is a + system service that implements scheduled shutdowns, as + exposed by + shutdown8. + systemd-shutdownd.service is automatically activated on request and terminates + itself when it is unused. + + + + See Also + + systemd1, + shutdown8 + + + + diff --git a/man/systemd-suspend.service.xml b/man/systemd-suspend.service.xml new file mode 100644 index 000000000..9b8bad479 --- /dev/null +++ b/man/systemd-suspend.service.xml @@ -0,0 +1,126 @@ + + + + + + + + + systemd-suspend.service + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd-suspend.service + 8 + + + + systemd-suspend.service + systemd-hibernate.service + systemd-hybrid-sleep.service + systemd-sleep + System sleep state logic + + + + systemd-suspend.service + systemd-hibernate.service + systemd-hybrid-sleep.service + /usr/lib/systemd/systemd-sleep + + + + Description + + systemd-suspend.service is + a system service that is pulled in by + suspend.target and is responsible + for the actual system suspend. Similar, + systemd-hibernate.service is + pulled in by hibernate.target to + execute the actual hibernation. Finally, + systemd-hybrid-sleep.service is + pulled in by hybrid-sleep.target + to execute hybrid hibernation with system + suspend. + + Immediately before entering system suspend + and/or hibernation + systemd-suspend.service (and the + other mentioned units, respectively) will run all + executables in + /usr/lib/systemd/system-sleep/ + and pass two arguments to them. The first argument + will be "pre", the second either + "suspend", + "hibernate", or + "hybrid-sleep" depending on the + chosen action. Immediately after leaving system + suspend and/or hibernation the same executables are run, + but the first argument is now + "post". All executables in this + directory are executed in parallel, and execution of + the action is not continued before all executables + finished. + + Note that scripts or binaries dropped in + /usr/lib/systemd/system-sleep/ + are intended for local use only and should be + considered hacks. If applications want to be notified + of system suspend/hibernation and resume there are + much nicer interfaces available. + + Note that + systemd-suspend.service, + systemd-hibernate.service and + systemd-hybrid-sleep.service + should never be executed directly. Instead, trigger + system sleep states with a command such as + "systemctl suspend" or + similar. + + Internally, this service will echo a string like + mem into + /sys/power/state, to trigger the + actual system suspend. + + + + See Also + + systemd1, + systemctl1, + systemd.special7, + systemd-halt.service8 + + + + diff --git a/man/systemd-sysctl.service.xml b/man/systemd-sysctl.service.xml new file mode 100644 index 000000000..72a102c12 --- /dev/null +++ b/man/systemd-sysctl.service.xml @@ -0,0 +1,78 @@ + + + + + + + + systemd-sysctl.service + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd-sysctl.service + 8 + + + + systemd-sysctl.service + systemd-sysctl + Configure kernel parameters at boot + + + + systemd-sysctl.service + /usr/lib/systemd/systemd-sysctl + + + + Description + + systemd-sysctl.service is + an early-boot service that configures + sysctl8 + kernel parameters. + + See + sysctl.d5 + for information about the configuration of this + service. + + + + See Also + + systemd1, + sysctl.d5, + sysctl8, + wine8 + + + + diff --git a/man/systemd-system-update-generator.xml b/man/systemd-system-update-generator.xml new file mode 100644 index 000000000..18a23ed7f --- /dev/null +++ b/man/systemd-system-update-generator.xml @@ -0,0 +1,79 @@ + + + + + + + + systemd-system-update-generator + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd-system-update-generator + 8 + + + + systemd-system-update-generator + Generator for redirecting boot to offline update mode + + + + /usr/lib/systemd/system-generators/systemd-system-update-generator + + + + Description + + systemd-system-update-generator + is a generator that automatically redirects the boot + process to system-update.target + if /system-update exists. This is + required to implement the logic explained in the + System + Updates Specification. + + + systemd-system-update-generator + implements the generator + specification. + + + + See Also + + systemd1, + systemd.special7 + + + + diff --git a/man/systemd-timedated.service.xml b/man/systemd-timedated.service.xml new file mode 100644 index 000000000..ea2abc576 --- /dev/null +++ b/man/systemd-timedated.service.xml @@ -0,0 +1,88 @@ + + + + + + + + + systemd-timedated.service + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd-timedated.service + 8 + + + + systemd-timedated.service + systemd-timedated + Time and date bus mechanism + + + + systemd-timedated.service + /usr/lib/systemd/systemd-timedated + + + + Description + + systemd-timedated is a + system service that may be used as mechanism to change + the system clock and timezone, as well as to + enable/disable NTP time + synchronization. systemd-timedated + is automatically activated on request and terminates + itself when it is unused. + + The tool + timedatectl1 + is a command line client to this service. + + See the + developer documentation for information about + the APIs systemd-timedated + provides. + + + + See Also + + systemd1, + timedatectl1, + localtime5, + hwclock8 + + + + diff --git a/man/systemd-tmpfiles.xml b/man/systemd-tmpfiles.xml new file mode 100644 index 000000000..22744c7c4 --- /dev/null +++ b/man/systemd-tmpfiles.xml @@ -0,0 +1,162 @@ + + + + + + + + + systemd-tmpfiles + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd-tmpfiles + 8 + + + + systemd-tmpfiles + systemd-tmpfiles-setup.service + systemd-tmpfiles-clean.service + systemd-tmpfiles-clean.timer + Creates, deletes and cleans up volatile + and temporary files and directories + + + + + systemd-tmpfiles OPTIONS CONFIGURATION FILE + + + systemd-tmpfiles-setup.service + systemd-tmpfiles-clean.service + systemd-tmpfiles-clean.timer + + + + Description + + systemd-tmpfiles creates, + deletes and cleans up volatile and temporary files and + directories, based on the configuration file format and + location specified in + tmpfiles.d + 5 + . + + If invoked with no arguments, it applies all + directives from all configuration files. If one or + more file names are passed on the command line, only + the directives in these files are applied. If only + the basename of a configuration file is specified, + all configuration directories as specified in + tmpfiles.d + 5 + are searched for a matching file. + + + + Options + + The following options are understood: + + + + + + If this option is passed all + files and directories marked with f, + F, d, D in the configuration files are + created. Files and directories marked with z, + Z have their ownership, access mode and security + labels set. + + + + + If this option is + passed all files and directories with + an age parameter configured will be + cleaned up. + + + + + If this option is + passed all files and directories marked + with r, R in the configuration files + are removed. + + + + Only apply rules that + apply to paths with the specified + prefix. + + + + + + + Prints a short help + text and exits. + + + + + It is possible to combine + , , + and in one invocation. For + example, during boot the following command line is + executed to ensure that all temporary and volatile + directories are removed and created according to the + configuration file: + + systemd-tmpfiles --remove --create + + + + + Exit status + + On success 0 is returned, a non-zero failure + code otherwise. + + + + See Also + + systemd1, + tmpfiles.d5, + + + + diff --git a/man/systemd-tty-ask-password-agent.xml b/man/systemd-tty-ask-password-agent.xml new file mode 100644 index 000000000..31a18ba4b --- /dev/null +++ b/man/systemd-tty-ask-password-agent.xml @@ -0,0 +1,166 @@ + + + + + + + + + systemd-tty-ask-password-agent + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd-tty-ask-password-agent + 1 + + + + systemd-tty-ask-password-agent + List or process pending systemd password requests + + + + + systemd-tty-ask-password-agent OPTIONS VARIABLE=VALUE + + + + + Description + + systemd-tty-ask-password-agent + is a password agent that handles password + requests of the system, for example for hard disk + encryption passwords or SSL certificate passwords that + need to be queried at boot-time or during + runtime. + + systemd-tty-ask-password-agent + implements the Password + Agents Specification. + + + + + Options + + The following options are understood: + + + + + + + Prints a short help + text and exits. + + + + + + Prints a short version + string and exits. + + + + + + Lists all currently pending system password requests. + + + + + + Process all currently + pending system password requests by + querying the user on the calling + TTY. + + + + + + Continuously process + password requests. + + + + + + Forward password + requests to + wall1 + instead of querying the user on the + calling TTY. + + + + + + Ask question with + plymouth8 + instead of querying the user on the + calling TTY. + + + + + + Ask question on + /dev/console + instead of querying the user on the + calling TTY. + + + + + + + + Exit status + + On success 0 is returned, a non-zero failure + code otherwise. + + + + See Also + + systemd1, + systemctl1, + systemd-ask-password-console.service8, + wall1, + plymouth8 + + + + diff --git a/man/systemd-udevd.service.xml b/man/systemd-udevd.service.xml new file mode 100644 index 000000000..92fb38f06 --- /dev/null +++ b/man/systemd-udevd.service.xml @@ -0,0 +1,168 @@ + + + + + + + systemd-udevd.service + systemd + + + Developer + Kay + Sievers + kay@vrfy.org + + + + + + systemd-udevd.service + 8 + + + + + systemd-udevd.service + systemd-udevd-control.socket + systemd-udevd-kernel.socket + systemd-udevd + Device event managing daemon + + + + systemd-udevd.service + systemd-udevd-control.socket + systemd-udevd-kernel.socket + + + /usr/lib/systemd/systemd-udevd + + + + + + + + + + + + Description + systemd-udevd listens to kernel uevents. + For every event, systemd-udevd executes matching instructions + specified in udev rules. See + udev7 + . + The behavior of the running daemon can be changed with + udevadm control. + + + Options + + + + + Detach and run in the background. + + + + + + Print debug messages to stderr. + + + + + + Limit the number of events executed in parallel. + + + + + + + Delay the execution of RUN instruction by the given + number of seconds. This option might be useful when + debugging system crashes during coldplug caused by loading + non-working kernel modules. + + + + + + Specify when systemd-udevd should resolve names of users and groups. + When set to (the default) names will be + resolved when the rules are parsed. When set to + names will be resolved for every event. + When set to names will never be resolved + and all devices will be owned by root. + + + + + + Print version number. + + + + + + Print help text. + + + + + + Environment + + + UDEV_LOG= + + Set the logging priority. + + + + + + Kernel command line + + Parameters starting with "rd." will be read when + systemd-udevd is used in an initrd. + + udev.log-priority= + rd.udev.log-priority= + + Set the logging priority. + + + + udev.children-max= + rd.udev.children-max= + + Limit the number of events executed in parallel. + + + + udev.exec-delay= + rd.udev.exec-delay= + + Delay the execution of RUN instruction by the given + number of seconds. This option might be useful when + debugging system crashes during coldplug caused by loading + non-working kernel modules. + + + + + + + See Also + + udev7 + , + udevadm8 + + + diff --git a/man/systemd-update-utmp-runlevel.service.xml b/man/systemd-update-utmp-runlevel.service.xml new file mode 100644 index 000000000..0e19581f9 --- /dev/null +++ b/man/systemd-update-utmp-runlevel.service.xml @@ -0,0 +1,76 @@ + + + + + + + + systemd-update-utmp-runlevel.service + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd-update-utmp-runlevel.service + 8 + + + + systemd-update-utmp-runlevel.service + systemd-update-utmp-shutdown.service + systemd-update-utmp + Write audit and utmp updates at runlevel + changes and shutdown + + + + systemd-update-utmp-runlevel.service + systemd-update-utmp-shutdown.service + /usr/lib/systemd/systemd-update-utmp + + + + Description + + systemd-update-utmp-runlevel.service + is a service that writes SysV runlevel changes to utmp + and wtmp, as well as the audit logs, as they + occur. systemd-update-utmp-shutdown.service + does the same for shut-down requests. + + + + See Also + + systemd1, + utmp5, + auditd8 + + + + diff --git a/man/systemd-user-sessions.service.xml b/man/systemd-user-sessions.service.xml new file mode 100644 index 000000000..9214ec9c3 --- /dev/null +++ b/man/systemd-user-sessions.service.xml @@ -0,0 +1,77 @@ + + + + + + + + systemd-user-sessions.service + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd-user-sessions.service + 8 + + + + systemd-user-sessions.service + systemd-user-sessions + Permit user logins after boot, prohibit user logins at shutdown + + + + systemd-user-sessions.service + /usr/lib/systemd/systemd-user-sessions + + + + Description + + systemd-user-sessions.service + is a service that controls user logins. After basic + system initialization is complete it removes + /run/nologin, thus permitting + logins. Before system shutdown it creates + /run/nologin, thus prohibiting + further logins. At the same time it also kills all + user processes, so that system shutdown may proceed + without any remaining user processes around. + + + + See Also + + systemd1, + systemd-logind.service8, + pam_nologin8 + + + + diff --git a/man/systemd-vconsole-setup.service.xml b/man/systemd-vconsole-setup.service.xml new file mode 100644 index 000000000..c1ef80dae --- /dev/null +++ b/man/systemd-vconsole-setup.service.xml @@ -0,0 +1,118 @@ + + + + + + + + systemd-vconsole-setup.service + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd-vconsole-setup.service + 8 + + + + systemd-vconsole-setup.service + systemd-vconsole-setup + Configure the virtual console at boot + + + + systemd-vconsole-setup.service + /usr/lib/systemd/systemd-vconsole-setup + + + + Description + + systemd-vconsole-setup.service + is an early-boot service that configures the virtual + console font and console keymap. Internally it calls + loadkeys1 + and + setfont8. + + See + vconsole.conf5 + for information about the configuration files understood by this + service. + + + + + + Kernel Command Line + + A few configuration parameters from + vconsole.conf may be overridden on + the kernel command line: + + + + vconsole.keymap= + vconsole.keymap.toggle= + + Overrides the key + mapping table for the keyboard and the + second toggle keymap. + + + + vconsole.font= + vconsole.font.map= + vconsole.font.unimap= + + Configures the console + font, the console map, and the unicode + font map. + + + + + + See + vconsole.conf5 + for information about these settings. + + + + See Also + + systemd1, + vconsole.conf5, + loadkeys1, + setfont8, + systemd-localed.service8 + + + + diff --git a/man/systemd.automount.xml b/man/systemd.automount.xml new file mode 100644 index 000000000..fe559e1dc --- /dev/null +++ b/man/systemd.automount.xml @@ -0,0 +1,167 @@ + + + + + + + + + systemd.automount + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd.automount + 5 + + + + systemd.automount + Automount unit configuration + + + + systemd.automount + + + + Description + + A unit configuration file whose name ends in + .automount encodes information + about a file system automount point controlled and + supervised by systemd. + + This man page lists the configuration options + specific to this unit type. See + systemd.unit5 + for the common options of all unit configuration + files. The common configuration items are configured + in the generic [Unit] and [Install] sections. The + automount specific configuration options are configured + in the [Automount] section. + + Automount units must be named after the + automount directories they control. Example: the + automount point /home/lennart + must be configured in a unit file + home-lennart.automount. For + details about the escaping logic used to convert a + file system path to a unit name see + systemd.unit5. + + For each automount unit file a matching mount + unit file (see + systemd.mount5 + for details) must exist which is activated when the + automount path is accessed. Example: if an automount + unit home-lennart.automount is + active and the user accesses + /home/lennart the mount unit + home-lennart.mount will be + activated. + + Automount units may be used to implement + on-demand mounting as well as parallelized mounting of + file systems. + + If an automount point is beneath another mount + point in the file system hierarchy a dependency + between both units is created automatically. + + + + <filename>fstab</filename> + + Automount units may either be configured via unit + files, or via /etc/fstab (see + fstab5 + for details). + + For details how systemd parses + /etc/fstab see + systemd.mount5. + + If an automount point is configured in both + /etc/fstab and a unit file the + configuration in the latter takes precedence. + + + + Options + + Automount files must include an [Automount] + section, which carries information about the file + system automount points it supervises. The options + specific to the [Automount] section of automount units + are the following: + + + + + Where= + Takes an absolute path + of a directory of the automount + point. If the automount point is not + existing at time that the automount + point is installed it is created. This + string must be reflected in the unit + file name. (See above.) This option is + mandatory. + + + + DirectoryMode= + Directories of + automount points (and any parent + directories) are automatically created + if needed. This option specifies the + file system access mode used when + creating these directories. Takes an + access mode in octal + notation. Defaults to + 0755. + + + + + + See Also + + systemd1, + systemctl8, + systemd.unit5, + systemd.mount5, + mount8, + automount8 + + + + diff --git a/man/systemd.conf.xml b/man/systemd.conf.xml new file mode 100644 index 000000000..a6be932c7 --- /dev/null +++ b/man/systemd.conf.xml @@ -0,0 +1,284 @@ + + + + + + + + + systemd.conf + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd.conf + 5 + + + + systemd.conf + System and service manager configuration file + + + + /etc/systemd/system.conf + /etc/systemd/user.conf + + + + Description + + When run as system instance systemd reads the + configuration file system.conf, + otherwise user.conf. These + configuration files contain a few settings controlling + basic manager operations. + + + + + Options + + All options are configured in the + [Manager] section: + + + + + LogLevel= + LogTarget= + LogColor= + LogLocation= + DumpCore=yes + CrashShell=no + ShowStatus=yes + CrashChVT=1 + DefaultStandardOutput=journal + DefaultStandardError=inherit + + Configures various + parameters of basic manager + operation. These options may be + overridden by the respective command + line arguments. See + systemd1 + for details about these command line + arguments. + + + + CPUAffinity= + + Configures the initial + CPU affinity for the init + process. Takes a space-separated list + of CPU indexes. + + + + DefaultControllers=cpu + + Configures in which + cgroup controller hierarchies to + create per-service cgroups + automatically, in addition to the + name=systemd named hierarchy. Defaults + to 'cpu'. Takes a space separated list + of controller names. Pass an empty + string to ensure that systemd does not + touch any hierarchies but its + own. + + + + JoinControllers=cpu,cpuacct,cpuset net_cls,netprio + + Configures controllers + that shall be mounted in a single + hierarchy. By default systemd will + mount all controllers which are + enabled in the kernel in individual + hierarchies, with the exception of + those listed in this setting. Takes a + space separated list of comma + separated controller names, in order + to allow multiple joined + hierarchies. Defaults to + 'cpu,cpuacct'. Pass an empty string to + ensure that systemd mounts all + controllers in separate + hierarchies. + + + + RuntimeWatchdogSec= + ShutdownWatchdogSec= + + Configure the hardware + watchdog at runtime and at + reboot. Takes a timeout value in + seconds (or in other time units if + suffixed with ms, + min, + h, + d, + w). If + RuntimeWatchdogSec= + is set to a non-zero value the + watchdog hardware + (/dev/watchdog) + will be programmed to automatically + reboot the system if it is not + contacted within the specified timeout + interval. The system manager will + ensure to contact it at least once in + half the specified timeout + interval. This feature requires a + hardware watchdog device to be + present, as it is commonly the case in + embedded and server systems. Not all + hardware watchdogs allow configuration + of the reboot timeout, in which case + the closest available timeout is + picked. ShutdownWatchdogSec= + may be used to configure the hardware + watchdog when the system is asked to + reboot. It works as a safety net to + ensure that the reboot takes place + even if a clean reboot attempt times + out. By default + RuntimeWatchdogSec= + defaults to 0 (off), and + ShutdownWatchdogSec= + to 10min. These settings have no + effect if a hardware watchdog is not + available. + + + + CapabilityBoundingSet= + + Controls which + capabilities to include in the + capability bounding set for PID 1 and + its children. See + capabilities7 + for details. Takes a whitespace + separated list of capability names as + read by + cap_from_name3. + Capabilities listed will be included + in the bounding set, all others are + removed. If the list of capabilities + is prefixed with ~ all but the listed + capabilities will be included, the + effect of the assignment + inverted. Note that this option also + affects the respective capabilities in + the effective, permitted and + inheritable capability sets. The + capability bounding set may also be + individually configured for units + using the + CapabilityBoundingSet= + directive for units, but note that + capabilities dropped for PID 1 cannot + be regained in individual units, they + are lost for good. + + + + TimerSlackNSec= + + Sets the timer slack + in nanoseconds for PID 1 which is then + inherited to all executed processes, + unless overridden individually, for + example with the + TimerSlackNSec= + setting in service units (for details + see + systemd.exec5). The + timer slack controls the accuracy of + wake-ups triggered by timers. See + prctl2 + for more information. Note that in + contrast to most other time span + definitions this parameter takes an + integer value in nano-seconds if no + unit is specified. The usual time + units are understood + too. + + + + DefaultLimitCPU= + DefaultLimitFSIZE= + DefaultLimitDATA= + DefaultLimitSTACK= + DefaultLimitCORE= + DefaultLimitRSS= + DefaultLimitNOFILE= + DefaultLimitAS= + DefaultLimitNPROC= + DefaultLimitMEMLOCK= + DefaultLimitLOCKS= + DefaultLimitSIGPENDING= + DefaultLimitMSGQUEUE= + DefaultLimitNICE= + DefaultLimitRTPRIO= + DefaultLimitRTTIME= + + These settings control + various default resource limits for + units. See + setrlimit2 + for details. Use the string + infinity to + configure no limit on a specific + resource. These settings may be + overridden in individual units + using the corresponding LimitXXX= + directives. Note that these resource + limits are only defaults for units, + they are not applied to PID 1 + itself. + + + + + + See Also + + systemd1 + + + + diff --git a/man/systemd.device.xml b/man/systemd.device.xml new file mode 100644 index 000000000..141d72e3d --- /dev/null +++ b/man/systemd.device.xml @@ -0,0 +1,168 @@ + + + + + + + + + systemd.device + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd.device + 5 + + + + systemd.device + Device unit configuration + + + + systemd.device + + + + Description + + A unit configuration file whose name ends in + .device encodes information about + a device unit as exposed in the + sysfs/udev7 + device tree. + + This unit type has no specific options. See + systemd.unit5 + for the common options of all unit configuration + files. The common configuration items are configured + in the generic [Unit] and + [Install] sections. A separate + [Device] section does not exist, + since no device-specific options may be + configured. + + systemd will automatically create dynamic device + units for all kernel devices that are marked with the + "systemd" udev tag (by default all block and network + devices, and a few others). This may be used to define + dependencies between devices and other + units. + + Device units are named after the + /sys and + /dev paths they control. Example: + the device /dev/sda5 is exposed + in systemd as dev-sda5.device. For + details about the escaping logic used to convert a + file system path to a unit name see + systemd.unit5. + + + + + The udev Database + + The settings of device units may either be + configured via unit files, or directly from the udev + database (which is recommended). The following udev + properties are understood by systemd: + + + + SYSTEMD_WANTS= + Adds dependencies of + type Wants from + this unit to all listed units. This + may be used to activate arbitrary + units, when a specific device becomes + available. Note that this and the + other tags are not taken into account + unless the device is tagged with the + "systemd" string in + the udev database, because otherwise + the device is not exposed as systemd + unit. + + + + SYSTEMD_ALIAS= + Adds an additional + alias name to the device unit. This + must be an absolute path that is + automatically transformed into a unit + name. (See above.) + + + + SYSTEMD_READY= + If set to 0 systemd + will consider this device unplugged + even if it shows up in the udev + tree. If this property is unset or set + to 1 the device will be considered + plugged the moment it shows up in the + udev tree. This property has no + influence on the behavior when a + device disappears from the udev + tree. This option is useful to support + devices that initially show up in an + uninitialized state in the tree, and for + which a changed event is generated the + moment they are fully set + up. + + + + ID_MODEL_FROM_DATABASE= + ID_MODEL= + + If set, this property is + used as description string for the + device unit. + + + + + + + + + See Also + + systemd1, + systemctl8, + systemd.unit5, + udev7 + + + + diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml new file mode 100644 index 000000000..302ac4340 --- /dev/null +++ b/man/systemd.exec.xml @@ -0,0 +1,1156 @@ + + + + + + + + + systemd.exec + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd.exec + 5 + + + + systemd.exec + Execution environment configuration + + + + systemd.service, + systemd.socket, + systemd.mount, + systemd.swap + + + + Description + + Unit configuration files for services, sockets, + mount points and swap devices share a subset of + configuration options which define the execution + environment of spawned processes. + + This man page lists the configuration options + shared by these four unit types. See + systemd.unit5 + for the common options of all unit configuration + files, and + systemd.service5, + systemd.socket5, + systemd.swap5 + and + systemd.mount5 + for more information on the specific unit + configuration files. The execution specific + configuration options are configured in the [Service], + [Socket], [Mount], or [Swap] sections, depending on the unit + type. + + + + Options + + + + + WorkingDirectory= + + Takes an absolute + directory path. Sets the working + directory for executed processes. If + not set defaults to the root directory + when systemd is running as a system + instance and the respective user's + home directory if run as + user. + + + + RootDirectory= + + Takes an absolute + directory path. Sets the root + directory for executed processes, with + the + chroot2 + system call. If this is used it must + be ensured that the process and all + its auxiliary files are available in + the chroot() + jail. + + + + User= + Group= + + Sets the Unix user + or group that the processes are executed + as, respectively. Takes a single user or group + name or ID as argument. If no group is + set, the default group of the user is + chosen. + + + + SupplementaryGroups= + + Sets the supplementary + Unix groups the processes are executed + as. This takes a space separated list + of group names or IDs. This option may + be specified more than once in which + case all listed groups are set as + supplementary groups. This option does + not override but extends the list of + supplementary groups configured in the + system group database for the + user. + + + + Nice= + + Sets the default nice + level (scheduling priority) for + executed processes. Takes an integer + between -20 (highest priority) and 19 + (lowest priority). See + setpriority2 + for details. + + + + OOMScoreAdjust= + + Sets the adjustment + level for the Out-Of-Memory killer for + executed processes. Takes an integer + between -1000 (to disable OOM killing + for this process) and 1000 (to make + killing of this process under memory + pressure very likely). See proc.txt + for details. + + + + IOSchedulingClass= + + Sets the IO scheduling + class for executed processes. Takes an + integer between 0 and 3 or one of the + strings , + , + or + . See + ioprio_set2 + for details. + + + + IOSchedulingPriority= + + Sets the IO scheduling + priority for executed processes. Takes + an integer between 0 (highest + priority) and 7 (lowest priority). The + available priorities depend on the + selected IO scheduling class (see + above). See + ioprio_set2 + for details. + + + + CPUSchedulingPolicy= + + Sets the CPU + scheduling policy for executed + processes. Takes one of + , + , + , + or + . See + sched_setscheduler2 + for details. + + + + CPUSchedulingPriority= + + Sets the CPU + scheduling priority for executed + processes. The available priority + range depends on the selected CPU + scheduling policy (see above). For + real-time scheduling policies an + integer between 1 (lowest priority) + and 99 (highest priority) can be used. + See sched_setscheduler2 + for details. + + + + + CPUSchedulingResetOnFork= + + Takes a boolean + argument. If true elevated CPU + scheduling priorities and policies + will be reset when the executed + processes fork, and can hence not leak + into child processes. See + sched_setscheduler2 + for details. Defaults to false. + + + + CPUAffinity= + + Controls the CPU + affinity of the executed + processes. Takes a space-separated + list of CPU indexes. See + sched_setaffinity2 + for details. + + + + UMask= + + Controls the file mode + creation mask. Takes an access mode in + octal notation. See + umask2 + for details. Defaults to + 0022. + + + + Environment= + + Sets environment + variables for executed + processes. Takes a space-separated + list of variable assignments. This + option may be specified more than once + in which case all listed variables + will be set. If the same variable is + set twice the later setting will + override the earlier setting. See + environ7 + for details. + + + EnvironmentFile= + Similar to + Environment= but + reads the environment variables from a + text file. The text file should + contain new-line separated variable + assignments. Empty lines and lines + starting with ; or # will be ignored, + which may be used for commenting. The + parser strips leading and + trailing whitespace from the values + of assignments, unless you use + double quotes ("). + The + argument passed should be an absolute + file name or wildcard expression, optionally prefixed with + "-", which indicates that if the file + does not exist it won't be read and no + error or warning message is + logged. The files listed with this + directive will be read shortly before + the process is executed. Settings from + these files override settings made + with + Environment=. If + the same variable is set twice from + these files the files will be read in + the order they are specified and the + later setting will override the + earlier setting. + + + + StandardInput= + Controls where file + descriptor 0 (STDIN) of the executed + processes is connected to. Takes one + of , + , + , + or + . If + is selected + standard input will be connected to + /dev/null, + i.e. all read attempts by the process + will result in immediate EOF. If + is selected + standard input is connected to a TTY + (as configured by + TTYPath=, see + below) and the executed process + becomes the controlling process of the + terminal. If the terminal is already + being controlled by another process the + executed process waits until the current + controlling process releases the + terminal. + + is similar to , + but the executed process is forcefully + and immediately made the controlling + process of the terminal, potentially + removing previous controlling + processes from the + terminal. is + similar to but if + the terminal already has a controlling + process start-up of the executed + process fails. The + option is only + valid in socket-activated services, + and only when the socket configuration + file (see + systemd.socket5 + for details) specifies a single socket + only. If this option is set standard + input will be connected to the socket + the service was activated from, which + is primarily useful for compatibility + with daemons designed for use with the + traditional + inetd8 + daemon. This setting defaults to + . + + + StandardOutput= + Controls where file + descriptor 1 (STDOUT) of the executed + processes is connected to. Takes one + of , + , + , + , + , + , + , + , + or + . If set to + the file + descriptor of standard input is + duplicated for standard output. If set + to standard + output will be connected to + /dev/null, + i.e. everything written to it will be + lost. If set to + standard output will be connected to a + tty (as configured via + TTYPath=, see + below). If the TTY is used for output + only the executed process will not + become the controlling process of the + terminal, and will not fail or wait + for other processes to release the + terminal. + connects standard output to the + syslog3 + system syslog + service. + connects it with the kernel log buffer + which is accessible via + dmesg1. + connects it with the journal which is + accessible via + journalctl1 + (Note that everything that is written + to syslog or kmsg is implicitly stored + in the journal as well, those options + are hence supersets of this + one). , + and + work + similarly but copy the output to the + system console as + well. connects + standard output to a socket from + socket activation, semantics are + similar to the respective option of + StandardInput=. + This setting defaults to the value set + with + + in + systemd.conf5, + which defaults to + . + + + StandardError= + Controls where file + descriptor 2 (STDERR) of the executed + processes is connected to. The + available options are identical to + those of + StandardOutput=, + with one exception: if set to + the file + descriptor used for standard output is + duplicated for standard error. This + setting defaults to the value set with + + in + systemd.conf5, + which defaults to + . + + + TTYPath= + Sets the terminal + device node to use if standard input, + output or stderr are connected to a + TTY (see above). Defaults to + /dev/console. + + + TTYReset= + Reset the terminal + device specified with + TTYPath= before and + after execution. Defaults to + no. + + + TTYVHangup= + Disconnect all clients + which have opened the terminal device + specified with + TTYPath= + before and after execution. Defaults + to + no. + + + TTYVTDisallocate= + If the terminal + device specified with + TTYPath= is a + virtual console terminal try to + deallocate the TTY before and after + execution. This ensures that the + screen and scrollback buffer is + cleared. Defaults to + no. + + + SyslogIdentifier= + Sets the process name + to prefix log lines sent to syslog or + the kernel log buffer with. If not set + defaults to the process name of the + executed process. This option is only + useful when + StandardOutput= or + StandardError= are + set to or + . + + + SyslogFacility= + Sets the syslog + facility to use when logging to + syslog. One of , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + or + . See + syslog3 + for details. This option is only + useful when + StandardOutput= or + StandardError= are + set to . + Defaults to + . + + + SyslogLevel= + Default syslog level + to use when logging to syslog or the + kernel log buffer. One of + , + , + , + , + , + , + , + . See + syslog3 + for details. This option is only + useful when + StandardOutput= or + StandardError= are + set to or + . Note that + individual lines output by the daemon + might be prefixed with a different log + level which can be used to override + the default log level specified + here. The interpretation of these + prefixes may be disabled with + SyslogLevelPrefix=, + see below. For details see + sd-daemon3. + + Defaults to + . + + + + SyslogLevelPrefix= + Takes a boolean + argument. If true and + StandardOutput= or + StandardError= are + set to , + or + , log lines + written by the executed process that + are prefixed with a log level will be + passed on to syslog with this log + level set but the prefix removed. If + set to false, the interpretation of + these prefixes is disabled and the + logged lines are passed on as-is. For + details about this prefixing see + sd-daemon3. + Defaults to true. + + + + TimerSlackNSec= + Sets the timer slack + in nanoseconds for the executed + processes. The timer slack controls + the accuracy of wake-ups triggered by + timers. See + prctl2 + for more information. Note that in + contrast to most other time span + definitions this parameter takes an + integer value in nano-seconds if no + unit is specified. The usual time + units are understood + too. + + + + LimitCPU= + LimitFSIZE= + LimitDATA= + LimitSTACK= + LimitCORE= + LimitRSS= + LimitNOFILE= + LimitAS= + LimitNPROC= + LimitMEMLOCK= + LimitLOCKS= + LimitSIGPENDING= + LimitMSGQUEUE= + LimitNICE= + LimitRTPRIO= + LimitRTTIME= + These settings control + various resource limits for executed + processes. See + setrlimit2 + for details. Use the string + infinity to + configure no limit on a specific + resource. + + + + PAMName= + Sets the PAM service + name to set up a session as. If set + the executed process will be + registered as a PAM session under the + specified service name. This is only + useful in conjunction with the + User= setting. If + not set no PAM session will be opened + for the executed processes. See + pam8 + for details. + + + + TCPWrapName= + If this is a + socket-activated service this sets the + tcpwrap service name to check the + permission for the current connection + with. This is only useful in + conjunction with socket-activated + services, and stream sockets (TCP) in + particular. It has no effect on other + socket types (e.g. datagram/UDP) and + on processes unrelated to socket-based + activation. If the tcpwrap + verification fails daemon start-up + will fail and the connection is + terminated. See + tcpd8 + for details. Note that this option may + be used to do access control checks + only. Shell commands and commands + described in + hosts_options5 + are not supported. + + + + CapabilityBoundingSet= + + Controls which + capabilities to include in the + capability bounding set for the + executed process. See + capabilities7 + for details. Takes a whitespace + separated list of capability names as + read by + cap_from_name3. + Capabilities listed will be included + in the bounding set, all others are + removed. If the list of capabilities + is prefixed with ~ all but the listed + capabilities will be included, the + effect of the assignment + inverted. Note that this option also + effects the respective capabilities in + the effective, permitted and + inheritable capability sets, on top of + what Capabilities= + does. If this option is not used the + capability bounding set is not + modified on process execution, hence + no limits on the capabilities of the + process are + enforced. + + + + SecureBits= + Controls the secure + bits set for the executed process. See + capabilities7 + for details. Takes a list of strings: + , + , + , + , + and/or + . + + + + + Capabilities= + Controls the + capabilities7 + set for the executed process. Take a + capability string describing the + effective, permitted and inherited + capability sets as documented in + cap_from_text3. + Note that these capability sets are + usually influenced by the capabilities + attached to the executed file. Due to + that + CapabilityBoundingSet= + is probably the much more useful + setting. + + + + ControlGroup= + + Controls the control + groups the executed processes shall be + made members of. Takes a + space-separated list of cgroup + identifiers. A cgroup identifier has a + format like + cpu:/foo/bar, + where "cpu" identifies the kernel + control group controller used, and + /foo/bar is the + control group path. The controller + name and ":" may be omitted in which + case the named systemd control group + hierarchy is implied. Alternatively, + the path and ":" may be omitted, in + which case the default control group + path for this unit is implied. This + option may be used to place executed + processes in arbitrary groups in + arbitrary hierarchies -- which can be + configured externally with additional + execution limits. By default systemd + will place all executed processes in + separate per-unit control groups + (named after the unit) in the systemd + named hierarchy. Since every process + can be in one group per hierarchy only + overriding the control group path in + the named systemd hierarchy will + disable automatic placement in the + default group. This option is + primarily intended to place executed + processes in specific paths in + specific kernel controller + hierarchies. It is however not + recommended to manipulate the service + control group path in the systemd + named hierarchy. For details about + control groups see cgroups.txt. + + + + ControlGroupModify= + Takes a boolean + argument. If true, the control groups + created for this unit will be owned by + the user specified with + User= (and the + appropriate group), and he/she can create + subgroups as well as add processes to + the group. + + + + ControlGroupPersistent= + Takes a boolean + argument. If true, the control groups + created for this unit will be marked + to be persistent, i.e. systemd will + not remove them when stopping the + unit. The default is false, meaning + that the control groups will be + removed when the unit is stopped. For + details about the semantics of this + logic see PaxControlGroups. + + + + ControlGroupAttribute= + + Set a specific control + group attribute for executed + processes, and (if needed) add the + executed processes to a cgroup in the + hierarchy of the controller the + attribute belongs to. Takes two + space-separated arguments: the + attribute name (syntax is + cpu.shares where + cpu refers to a + specific controller and + shares to the + attribute name), and the attribute + value. Example: + ControlGroupAttribute=cpu.shares + 512. If this option is used + for an attribute that belongs to a + kernel controller hierarchy the unit + is not already configured to be added + to (for example via the + ControlGroup= + option) then the unit will be added to + the controller and the default unit + cgroup path is implied. Thus, using + ControlGroupAttribute= + is in most case sufficient to make use + of control group enforcements, + explicit + ControlGroup= are + only necessary in case the implied + default control group path for a + service is not desirable. For details + about control group attributes see + cgroups.txt. This + option may appear more than once, in + order to set multiple control group + attributes. + + + + CPUShares= + + Assign the specified + overall CPU time shares to the + processes executed. Takes an integer + value. This controls the + cpu.shares control + group attribute, which defaults to + 1024. For details about this control + group attribute see sched-design-CFS.txt. + + + + MemoryLimit= + MemorySoftLimit= + + Limit the overall memory usage + of the executed processes to a certain + size. Takes a memory size in bytes. If + the value is suffixed with K, M, G or + T the specified memory size is parsed + as Kilobytes, Megabytes, Gigabytes, + or Terabytes (to the base + 1024), respectively. This controls the + memory.limit_in_bytes + and + memory.soft_limit_in_bytes + control group attributes. For details + about these control group attributes + see memory.txt. + + + + DeviceAllow= + DeviceDeny= + + Control access to + specific device nodes by the executed processes. Takes two + space separated strings: a device node + path (such as + /dev/null) + followed by a combination of r, w, m + to control reading, writing, or + creating of the specific device node + by the unit, respectively. This controls the + devices.allow + and + devices.deny + control group attributes. For details + about these control group attributes + see devices.txt. + + + + BlockIOWeight= + + Set the default or + per-device overall block IO weight + value for the executed + processes. Takes either a single + weight value (between 10 and 1000) to + set the default block IO weight, or a + space separated pair of a file path + and a weight value to specify the + device specific weight value (Example: + "/dev/sda 500"). The file path may be + specified as path to a block device + node or as any other file in which + case the backing block device of the + file system of the file is + determined. This controls the + blkio.weight and + blkio.weight_device + control group attributes, which + default to 1000. Use this option + multiple times to set weights for + multiple devices. For details about + these control group attributes see + blkio-controller.txt. + + + + BlockIOReadBandwidth= + BlockIOWriteBandwidth= + + Set the per-device + overall block IO bandwidth limit for + the executed processes. Takes a space + separated pair of a file path and a + bandwidth value (in bytes per second) + to specify the device specific + bandwidth. The file path may be + specified as path to a block device + node or as any other file in which + case the backing block device of the + file system of the file is determined. + If the bandwidth is suffixed with K, M, + G, or T the specified bandwidth is + parsed as Kilobytes, Megabytes, + Gigabytes, or Terabytes, respectively (Example: + "/dev/disk/by-path/pci-0000:00:1f.2-scsi-0:0:0:0 + 5M"). This controls the + blkio.read_bps_device + and + blkio.write_bps_device + control group attributes. Use this + option multiple times to set bandwidth + limits for multiple devices. For + details about these control group + attributes see blkio-controller.txt. + + + + ReadWriteDirectories= + ReadOnlyDirectories= + InaccessibleDirectories= + + Sets up a new + file-system name space for executed + processes. These options may be used + to limit access a process might have + to the main file-system + hierarchy. Each setting takes a + space-separated list of absolute + directory paths. Directories listed in + ReadWriteDirectories= + are accessible from within the + namespace with the same access rights + as from outside. Directories listed in + ReadOnlyDirectories= + are accessible for reading only, + writing will be refused even if the + usual file access controls would + permit this. Directories listed in + InaccessibleDirectories= + will be made inaccessible for processes + inside the namespace. Note that + restricting access with these options + does not extend to submounts of a + directory. You must list submounts + separately in these settings to + ensure the same limited access. These + options may be specified more than + once in which case all directories + listed will have limited access from + within the + namespace. + + + + PrivateTmp= + + Takes a boolean + argument. If true sets up a new file + system namespace for the executed + processes and mounts a private + /tmp directory + inside it, that is not shared by + processes outside of the + namespace. This is useful to secure + access to temporary files of the + process, but makes sharing between + processes via + /tmp + impossible. Defaults to + false. + + + + PrivateNetwork= + + Takes a boolean + argument. If true sets up a new + network namespace for the executed + processes and configures only the + loopback network device + lo inside it. No + other network devices will be + available to the executed process. + This is useful to securely turn off + network access by the executed + process. Defaults to + false. + + + + MountFlags= + + Takes a mount + propagation flag: + , + or + , which + control whether the file system + namespace set up for this unit's + processes will receive or propagate + new mounts. See + mount2 + for details. Default to + . + + + + UtmpIdentifier= + + Takes a four + character identifier string for an + utmp/wtmp entry for this service. This + should only be set for services such + as getty + implementations where utmp/wtmp + entries must be created and cleared + before and after execution. If the + configured string is longer than four + characters it is truncated and the + terminal four characters are + used. This setting interprets %I style + string replacements. This setting is + unset by default, i.e. no utmp/wtmp + entries are created or cleaned up for + this service. + + + + IgnoreSIGPIPE= + + Takes a boolean + argument. If true causes SIGPIPE to be + ignored in the executed + process. Defaults to true, since + SIGPIPE generally is useful only in + shell pipelines. + + + + NoNewPrivileges= + + Takes a boolean + argument. If true ensures that the + service process and all its children + can never gain new privileges. This + option is more powerful than the respective + secure bits flags (see above), as it + also prohibits UID changes of any + kind. This is the simplest, most + effective way to ensure that a process + and its children can never elevate + privileges again. + + + + SystemCallFilter= + + Takes a space + separated list of system call + names. If this setting is used all + system calls executed by the unit + process except for the listed ones + will result in immediate process + termination with the SIGSYS signal + (whitelisting). If the first character + of the list is ~ + the effect is inverted: only the + listed system calls will result in + immediate process termination + (blacklisting). If this option is used + NoNewPrivileges=yes + is implied. This feature makes use of + the Secure Computing Mode 2 interfaces + of the kernel ('seccomp filtering') + and is useful for enforcing a minimal + sandboxing environment. Note that the + execve, + rt_sigreturn, + sigreturn, + exit_group, + exit system calls + are implicitly whitelisted and don't + need to be listed + explicitly. + + + + + + + See Also + + systemd1, + systemctl8, + journalctl8, + systemd.unit5, + systemd.service5, + systemd.socket5, + systemd.swap5, + systemd.mount5, + systemd.kill5 + + + + diff --git a/man/systemd.journal-fields.xml b/man/systemd.journal-fields.xml new file mode 100644 index 000000000..76a436d65 --- /dev/null +++ b/man/systemd.journal-fields.xml @@ -0,0 +1,450 @@ + + + + + + + + + systemd.journal-fields + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd.journal-fields + 7 + + + + systemd.journal-fields + Special journal fields + + + + Description + + Entries in the journal resemble an environment + block in their syntax, however with fields that can + include binary data. Primarily, fields are formatted + UTF-8 text strings, and binary formatting is used only + where formatting as UTF-8 text strings makes little + sense. New fields may freely be defined by + applications, but a few fields have special + meaning. All fields with special meanings are + optional. In some cases fields may appear more than + once per entry. + + + + User Journal Fields + + User fields are fields that are directly passed + from clients and stored in the journal. + + + + MESSAGE= + + The human readable + message string for this + entry. This is supposed to be + the primary text shown to the + user. It is usually not + translated (but might be in + some cases), and is not + supposed to be parsed for meta + data. + + + + + MESSAGE_ID= + + A 128bit message + identifier ID for recognizing + certain message types, if this + is desirable. This should + contain a 128bit id formatted + as lower-case hexadecimal + string, without any separating + dashes or suchlike. This is + recommended to be a UUID + compatible ID, but this is not + enforced, and formatted + differently. Developers can + generate a new ID for this + purpose with + journalctl + --new-id. + + + + + PRIORITY= + + A priority value between + 0 (emerg) + and 7 + (debug) + formatted as decimal + string. This field is + compatible with syslog's + priority concept. + + + + + CODE_FILE= + CODE_LINE= + CODE_FUNC= + + The code location + generating this message, if + known. Contains the source + file name, the line number and + the function name. + + + + + ERRNO= + + The low-level Unix error + number causing this entry, if + any. Contains the numeric + value of + errno3 + formatted as decimal + string. + + + + + SYSLOG_FACILITY= + SYSLOG_IDENTIFIER= + SYSLOG_PID= + + Syslog compatibility + fields containing the facility + (formatted as decimal string), + the identifier string + (i.e. "tag"), and the client + PID. + + + + + + + + Trusted Journal Fields + + Fields prefixed with an underscore are trusted + fields, i.e. fields that are implicitly added by the + journal and cannot be altered by client code. + + + + _PID= + _UID= + _GID= + + The process, user and + group ID of the process the + journal entry originates from + formatted as decimal + string. + + + + + _COMM= + _EXE= + _CMDLINE= + + The name, the executable + path and the command line of + the process the journal entry + originates from. + + + + + _AUDIT_SESSION= + _AUDIT_LOGINUID= + + The session and login + UID of the process the journal + entry originates from, as + maintained by the kernel audit + subsystem. + + + + + _SYSTEMD_CGROUP= + _SYSTEMD_SESSION= + _SYSTEMD_UNIT= + _SYSTEMD_OWNER_UID= + + + The control group path in + the systemd hierarchy, the + systemd session ID (if any), + the systemd unit name (if any) + and the owner UID of the + systemd session (if any) of + the process the journal entry + originates from. + + + + + _SELINUX_CONTEXT= + + The SELinux security + context of the process the + journal entry originates + from. + + + + + _SOURCE_REALTIME_TIMESTAMP= + + The earliest trusted + timestamp of the message, if + any is known that is different + from the reception time of the + journal. This is the time in + usec since the epoch UTC + formatted as decimal + string. + + + + + _BOOT_ID= + + The kernel boot ID for + the boot the message was + generated in, formatted as + 128bit hexadecimal + string. + + + + + _MACHINE_ID= + + The machine ID of the + originating host, as available + in + machine-id5. + + + + + _HOSTNAME= + + The name of the + originating host. + + + + + _TRANSPORT= + + How the entry was + received by the journal + service. One of + driver, + syslog, + journal, + stdout, + kernel for + internally generated messages, + for those received via the + local syslog socket with the + syslog protocol, for those + received via the native + journal protocol, for the + those read from a services' + standard output or error + output, or for those read + from the kernel, respectively. + + + + + + + + Kernel Journal Fields + + Kernel fields are fields that are used by + messages originating in the kernel and stored in the + journal. + + + + _KERNEL_DEVICE= + + The kernel device + name. If the entry is + associated to a block device, + the major and minor of the + device node, separated by ':' + and prefixed by 'b'. Similar + for character devices, but + prefixed by 'c'. For network + devices the interface index, + prefixed by 'n'. For all other + devices '+' followed by the + subsystem name, followed by + ':', followed by the kernel + device name. + + + + _KERNEL_SUBSYSTEM= + + The kernel subsystem name. + + + + _UDEV_SYSNAME= + + The kernel device name + as it shows up in the device + tree below + /sys. + + + + _UDEV_DEVNODE= + + The device node path of + this device in + /dev. + + + + _UDEV_DEVLINK= + + Additional symlink names + pointing to the device node in + /dev. This + field is frequently set more + than once per entry. + + + + + + + Address Fields + + During serialization into external formats, such + as the Journal + Export Format or the Journal + JSON Format, the addresses of journal entries + are serialized into fields prefixed with double + underscores. Note that these aren't proper fields when + stored in the journal, but addressing meta data of + entries. They cannot be written as part of structured + log entries via calls such as + sd_journal_send3. They + may also not be used as matches for + sd_journal_add_match3 + + + + __CURSOR= + + The cursor for the + entry. A cursor is an opaque + text string that uniquely + describes the position of an + entry in the journal and is + portable across machines, + platforms and journal + files. + + + + + __REALTIME_TIMESTAMP= + + The wallclock time + (CLOCK_REALTIME) at the point + in time the entry was received + by the journal, in usec since + the epoch UTC formatted as + decimal string. This has + different properties from + _SOURCE_REALTIME_TIMESTAMP= + as it is usually a bit later + but more likely to be + monotonic. + + + + + __MONOTONIC_TIMESTAMP= + + The monotonic time + (CLOCK_MONOTONIC) at the point + in time the entry was received + by the journal in usec + formatted as decimal + string. To be useful as an + address for the entry this + should be combined with with + boot ID in + _BOOT_ID=. + + + + + + + See Also + + systemd1, + journalctl1, + journald.conf5, + sd-journal3 + + + + diff --git a/man/systemd.kill.xml b/man/systemd.kill.xml new file mode 100644 index 000000000..3fff2f57e --- /dev/null +++ b/man/systemd.kill.xml @@ -0,0 +1,170 @@ + + + + + + + + + systemd.kill + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd.kill + 5 + + + + systemd.kill + Kill environment configuration + + + + systemd.service, + systemd.socket, + systemd.mount, + systemd.swap + + + + Description + + Unit configuration files for services, sockets, + mount points and swap devices share a subset of + configuration options which define the process killing + parameters of spawned processes. + + This man page lists the configuration options + shared by these four unit types. See + systemd.unit5 + for the common options of all unit configuration + files, and + systemd.service5, + systemd.socket5, + systemd.swap5 + and + systemd.mount5 + for more information on the specific unit + configuration files. The execution specific + configuration options are configured in the [Service], + [Socket], [Mount], or [Swap] section, depending on the unit + type. + + + + Options + + + + + KillMode= + Specifies how + processes of this service shall be + killed. One of + , + , + . + + If set to + all + remaining processes in the control + group of this unit will be terminated + on unit stop (for services: after the + stop command is executed, as + configured with + ExecStop=). If set + to only the + main process itself is killed. If set + to no process is + killed. In this case only the stop + command will be executed on unit + stop, but no process be killed + otherwise. Processes remaining alive + after stop are left in their control + group and the control group continues + to exist after stop unless it is + empty. Defaults to + . + + Processes will first be + terminated via SIGTERM (unless the + signal to send is changed via + KillSignal=). If + then after a delay (configured via the + TimeoutSec= option) + processes still remain, the + termination request is repeated with + the SIGKILL signal (unless this is + disabled via the + SendSIGKILL= + option). See + kill2 + for more + information. + + + + KillSignal= + Specifies which signal + to use when killing a + service. Defaults to SIGTERM. + + + + + SendSIGKILL= + Specifies whether to + send SIGKILL to remaining processes + after a timeout, if the normal + shutdown procedure left processes of + the service around. Takes a boolean + value. Defaults to "yes". + + + + + + + See Also + + systemd1, + systemctl8, + journalctl8, + systemd.unit5, + systemd.service5, + systemd.socket5, + systemd.swap5, + systemd.mount5, + systemd.exec5 + + + + diff --git a/man/systemd.mount.xml b/man/systemd.mount.xml new file mode 100644 index 000000000..78b5f5257 --- /dev/null +++ b/man/systemd.mount.xml @@ -0,0 +1,289 @@ + + + + + + + + + systemd.mount + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd.mount + 5 + + + + systemd.mount + Mount unit configuration + + + + systemd.mount + + + + Description + + A unit configuration file whose name ends in + .mount encodes information about + a file system mount point controlled and supervised by + systemd. + + This man page lists the configuration options + specific to this unit type. See + systemd.unit5 + for the common options of all unit configuration + files. The common configuration items are configured + in the generic [Unit] and [Install] sections. The + mount specific configuration options are configured + in the [Mount] section. + + Additional options are listed in + systemd.exec5, + which define the execution environment the + mount8 + binary is executed in, and in + systemd.kill5 + which define the way the processes are + terminated. Note that the User= and Group= options are + not particularly useful for mount units specifying a + Type= option or using configuration + not specified in /etc/fstab; + mount8 + will refuse options that aren't listed in + /etc/fstab if it is not run as + UID 0. + + Mount units must be named after the mount point + directories they control. Example: the mount point + /home/lennart must be configured + in a unit file + home-lennart.mount. For details + about the escaping logic used to convert a file system + path to a unit name see + systemd.unit5. + + Optionally, a mount unit may be accompanied by + an automount unit, to allow on-demand or parallelized + mounting. See + systemd.automount5. + + If a mount point is beneath another mount point + in the file system hierarchy, a dependency between both + units is created automatically. + + Mount points created at runtime independent on + unit files or /etc/fstab will be + monitored by systemd and appear like any other mount + unit in systemd. + + + + <filename>/etc/fstab</filename> + + Mount units may either be configured via unit + files, or via /etc/fstab (see + fstab5 + for details). Mounts listed in + /etc/fstab will be converted into + native units dynamically at boot and when the + configuration of the system manager is reloaded. See + systemd-fstab-generator8 + for details about the conversion. + + When reading /etc/fstab a + few special mount options are understood by systemd + which influence how dependencies are created for mount + points from /etc/fstab. systemd + will create a dependency of type + from either + local-fs.target or + remote-fs.target, depending + whether the file system is local or remote. If + is set, an + automount unit will be created for the file + system. See + systemd.automount5 + for details. If + is + specified it may be used to configure how long systemd + should wait for a device to show up before giving up + on an entry from + /etc/fstab. Specify a time in + seconds or explicitly specify a unit as + s, min, + h, ms. + + If a mount point is configured in both + /etc/fstab and a unit file, the + configuration in the latter takes precedence. + + + + Options + + Mount files must include a [Mount] section, + which carries information about the file system mount points it + supervises. A number of options that may be used in + this section are shared with other unit types. These + options are documented in + systemd.exec5 + and + systemd.kill5. The + options specific to the [Mount] section of mount + units are the following: + + + + + What= + Takes an absolute path + of a device node, file or other + resource to mount. See + mount8 + for details. If this refers to a + device node, a dependency on the + respective device unit is + automatically created. (See + systemd.device5 for more information.) + This option is + mandatory. + + + + Where= + Takes an absolute path + of a directory of the mount point. If + the mount point does not exist at the + time of mounting, it is created. This + string must be reflected in the unit + file name. (See above.) This option is + mandatory. + + + + Type= + Takes a string for the + filesystem type. See + mount8 + for details. This setting is + optional. + + + + Options= + + Mount options to use + when mounting. This takes a comma + separated list of options. This + setting is optional. + + + + DirectoryMode= + Directories of mount + points (and any parent directories) + are automatically created if + needed. This option specifies the file + system access mode used when creating + these directories. Takes an access + mode in octal notation. Defaults to + 0755. + + + + TimeoutSec= + Configures the time to + wait for the mount command to + finish. If a command does not exit + within the configured time the mount + will be considered failed and be shut + down again. All commands still running + will be terminated forcibly via + SIGTERM, and after another delay of + this time with SIGKILL. (See + in + systemd.kill5.) + Takes a unit-less value in seconds, or + a time span value such as "5min + 20s". Pass 0 to disable the timeout + logic. Defaults to + 90s. + + + + Check + systemd.exec5 + and + systemd.kill5 + for more settings. + + + + Compatibility Options + + The following option is also available in the + [Mount] section, but exists purely + for compatibility reasons and should not be used in + newly written mount files. + + + + FsckPassNo= + + The pass number for + the file system checking service for + this mount. See + systemd.service5 + for more information on this setting. + + + + + + + See Also + + systemd1, + systemctl8, + systemd.unit5, + systemd.exec5, + systemd.kill5, + systemd.service5, + systemd.device5, + mount8, + systemd-fstab-generator8 + + + + diff --git a/man/systemd.path.xml b/man/systemd.path.xml new file mode 100644 index 000000000..a27a97be7 --- /dev/null +++ b/man/systemd.path.xml @@ -0,0 +1,220 @@ + + + + + + + + + systemd.path + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd.path + 5 + + + + systemd.path + Path unit configuration + + + + systemd.path + + + + Description + + A unit configuration file whose name ends in + .path encodes information about + a path monitored by systemd, for + path-based activation. + + This man page lists the configuration options + specific to this unit type. See + systemd.unit5 + for the common options of all unit configuration + files. The common configuration items are configured + in the generic [Unit] and [Install] sections. The + path specific configuration options are configured in + the [Path] section. + + For each path file, a matching unit file must + exist, describing the unit to activate when the path + changes. By default, a service by the same name as the + path (except for the suffix) is activated. Example: a + path file foo.path activates a + matching service foo.service. The + unit to activate may be controlled by + Unit= (see below). + + Internally, path units use the + inotify7 + API to monitor file systems. Due to that, it suffers by the + same limitations as inotify, and for example cannot be + used to monitor files or directories changed by other + machines on remote NFS file systems. + + If a path unit is beneath another mount + point in the file system hierarchy, a dependency + between both units is created automatically. + + Unless DefaultDependencies= + is set to , path units will + implicitly have dependencies of type + Conflicts= and + Before= on + shutdown.target. These ensure + that path units are terminated cleanly prior to system + shutdown. Only path units involved with early boot or + late system shutdown should disable this + option. + + + + Options + + Path files must include a [Path] section, + which carries information about the path(s) it + monitors. The options specific to the [Path] section + of path units are the following: + + + + PathExists= + PathExistsGlob= + PathChanged= + PathModified= + DirectoryNotEmpty= + + Defines paths to + monitor for certain changes: + PathExists= may be + used to watch the mere existence of a + file or directory. If the file + specified exists the configured unit + is + activated. PathExistsGlob= + works similar, but checks for the + existence of at least one file + matching the globbing pattern + specified. PathChanged= + may be used to watch a file or + directory and activate the configured + unit whenever it changes. It is not activated + on every write to the watched file but it is + activated if the file which was open for writing + gets closed. PathModified= + is similar, but additionally it is activated + also on simple writes to the watched file. + + DirectoryNotEmpty= + may be used to watch a directory and + activate the configured unit whenever + it contains at least one file. + + The arguments of these + directives must be absolute file + system paths. + + Multiple directives may be + combined, of the same and of different + types, to watch multiple paths. + + If a path is already existing + (in case of + PathExists= and + PathExistsGlob=) or + a directory already is not empty (in + case of + DirectoryNotEmpty=) + at the time the path unit is + activated, then the configured unit is + immediately activated as + well. Something similar does not apply + to PathChanged=. + + + + Unit= + + The unit to activate + when any of the configured paths + changes. The argument is a unit name, + whose suffix is not + .path. If not + specified, this value defaults to a + service that has the same name as the + path unit, except for the suffix. (See + above.) It is recommended that the + unit name that is activated and the + unit name of the path unit are named + identical, except for the + suffix. + + + MakeDirectory= + + Takes a boolean + argument. If true the directories to + watch are created before + watching. This option is ignored for + PathExists= + settings. Defaults to + . + + + DirectoryMode= + + If + MakeDirectory= is + enabled use the mode specified here to + create the directories in + question. Takes an access mode in + octal notation. Defaults to + . + + + + + + See Also + + systemd1, + systemctl8, + systemd.unit5, + systemd.service5, + inotify7 + + + + diff --git a/man/systemd.preset.xml b/man/systemd.preset.xml new file mode 100644 index 000000000..a69205387 --- /dev/null +++ b/man/systemd.preset.xml @@ -0,0 +1,204 @@ + + + + + + + + systemd.preset + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd.preset + 5 + + + + systemd.preset + Service enablement presets + + + + /etc/systemd/system-preset/*.preset + /run/systemd/system-preset/*.preset + /usr/lib/systemd/system-preset/*.preset + /etc/systemd/user-preset/*.preset + /run/systemd/user-preset/*.preset + /usr/lib/systemd/user-preset/*.preset + + + + Description + + Preset files may be used to encode policy which + units shall be enabled by default and which ones + shall be disabled. They are read by systemctl + preset (for more information see + systemctl1) + which uses this information to enable or disable a + unit according to preset policy. systemctl + preset is used by the post install + scriptlets of RPM packages (or other OS package formats), + to enable/disable specific units by default on package + installation, enforcing distribution, spin or + administrator preset policy. This allows choosing a certain + set of units to be enabled/disabled even before + installing the actual package. + + For more information on the preset logic please + have a look at the Presets + document. + + It is not recommended to ship preset files + within the respective software packages implementing + the units, but rather centralize them in a + distribution or spin default policy, which can be + amended by administrator policy. + + If no preset files exist, systemctl + preset will enable all units that are + installed by default. If this is not desired and all + units shall rather be disabled it is necessary to ship + a preset file with a single, catchall + "disable *" line. (See example 1, + below.) + + + + Preset File Format + + The preset files contain a list of + directives consisting of either the word + enable or + disable followed by a space and a + unit name (possibly with shell style wildcards), + separated by newlines. Empty lines and lines whose + first non-whitespace character is # or ; are + ignored. + + Two different directives are understood: + enable may be used to enable units + by default, disable to disable + units by default. + + If multiple lines apply to a unit name the + first matching one takes precedence over all + others. + + Each preset file shall be named in the style of + <priority>-<program>.conf. + Files in /etc/ override files + with the same name in /usr/lib/ + and /run/. Files in + /run/ override files with the + same name in /usr/lib/. Packages + should install their preset files in + /usr/lib/. Files in + /etc/ are reserved for the local + administrator, who may use this logic to override the + preset files installed by vendor packages. All preset + files are sorted by their filename in alphabetical + order, regardless in which of the directories they + reside, to guarantee that a specific preset file takes + precedence over another file with an alphabetically + earlier name, if both files contain lines that apply + to the same unit names. It is recommended to prefix + all file names with two-digit number, to simplify + ordering. + + If the administrator wants to disable a preset + file supplied by the vendor the recommended way is to + place a symlink to /dev/null in + /etc/systemd/system-preset/ + bearing the same file name. + + + + Example + + + Default off example <filename>/usr/lib/systemd/system-preset/99-default.preset</filename>: + + disable * + + + This disables all units. Due to the file name + prefix 99- it will be read last and + hence can easily be overridden by spin or + administrator preset policy or suchlike. + + + A GNOME spin example <filename>/usr/lib/systemd/system-preset/50-gnome.preset</filename>: + + enable gdm.service +enable colord.service +enable accounts-daemon.service +enable avahi-daemon.* + + + + This enables the three mentioned units, plus all + avahi-daemon regardless of which + unit type. A file like this could be useful for + inclusion in a GNOME spin of a distribution. It will + ensure that the units necessary for GNOME are properly + enabled as they are installed. It leaves all other + units untouched, and subject to other (later) preset + files, for example like the one from the first example + above. + + + Administrator policy <filename>/etc/systemd/system-preset/00-lennart.preset</filename>: + + enable httpd.service +enable sshd.service +enable postfix.service +disable * + + + 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 file name prefix + 00- it will be read early and hence + overrides all other preset policy files. + + + + See Also + + systemd1, + systemctl1, + systemd-delta1 + + + + diff --git a/man/systemd.service.xml b/man/systemd.service.xml new file mode 100644 index 000000000..598e86365 --- /dev/null +++ b/man/systemd.service.xml @@ -0,0 +1,929 @@ + + + + + + + + + systemd.service + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd.service + 5 + + + + systemd.service + Service unit configuration + + + + systemd.service + + + + Description + + A unit configuration file whose name ends in + .service encodes information + about a process controlled and supervised by + systemd. + + This man page lists the configuration options + specific to this unit type. See + systemd.unit5 + for the common options of all unit configuration + files. The common configuration items are configured + in the generic [Unit] and + [Install] sections. The service + specific configuration options are configured in the + [Service] section. + + Additional options are listed in + systemd.exec5, + which define the execution environment the commands + are executed in, and in + systemd.kill5 + which define the way the processes of the service are + terminated. + + Unless DefaultDependencies= + is set to , service units will + implicitly have dependencies of type + Requires= and + After= on + basic.target as well as + dependencies of type Conflicts= and + Before= on + shutdown.target. These ensure + that normal service units pull in basic system + initialization, and are terminated cleanly prior to + system shutdown. Only services involved with early + boot or late system shutdown should disable this + option. + + If a service is requested under a certain name + but no unit configuration file is found, systemd looks + for a SysV init script by the same name (with the + .service suffix removed) and + dynamically creates a service unit from that + script. This is useful for compatibility with + SysV. Note that this compatibility is quite + comprehensive but not 100%. For details about the + incompatibilities see the Incompatibilities + with SysV document. + + + + + Options + + Service files must include a + [Service] section, which carries + information about the service and the process it + supervises. A number of options that may be used in + this section are shared with other unit types. These + options are documented in + systemd.exec5 + and + systemd.kill5. The + options specific to the [Service] + section of service units are the following: + + + + Type= + + Configures the process + start-up type for this service + unit. One of , + , + , + , + or + . + + If set to + (the default + value if BusName= + is not specified) it is expected that + the process configured with + ExecStart= is the + main process of the service. In this + mode, if the process offers + functionality to other processes on + the system its communication channels + should be installed before the daemon + is started up (e.g. sockets set up by + systemd, via socket activation), as + systemd will immediately proceed + starting follow-up units. + + If set to + it is + expected that the process configured + with ExecStart= + will call fork() + as part of its start-up. The parent process is + expected to exit when start-up is + complete and all communication + channels set up. The child continues + to run as the main daemon + process. This is the behavior of + traditional UNIX daemons. If this + setting is used, it is recommended to + also use the + PIDFile= option, so + that systemd can identify the main + process of the daemon. systemd will + proceed starting follow-up units as + soon as the parent process + exits. + + Behavior of + is similar + to , however + it is expected that the process has to + exit before systemd starts follow-up + units. RemainAfterExit= + is particularly useful for this type + of service. + + Behavior of + is similar to + , however it is + expected that the daemon acquires a + name on the D-Bus bus, as configured + by + BusName=. systemd + will proceed starting follow-up units + after the D-Bus bus name has been + acquired. Service units with this + option configured implicitly gain + dependencies on the + dbus.socket + unit. This type is the default if + BusName= is + specified. + + Behavior of + is similar to + , however it is + expected that the daemon sends a + notification message via + sd_notify3 + or an equivalent call when it finished + starting up. systemd will proceed + starting follow-up units after this + notification message has been sent. If + this option is used + NotifyAccess= (see + below) should be set to open access to + the notification socket provided by + systemd. If + NotifyAccess= is + not set, it will be implicitly set to + . + + Behavior of + is very similar + to , however + actual execution of the service + binary is delayed until all jobs are + dispatched. This may be used to avoid + interleaving of output of shell + services with the status output on the + console. + + + + + RemainAfterExit= + + Takes a boolean value + that specifies whether the service + shall be considered active even when + all its processes exited. Defaults to + . + + + + + GuessMainPID= + + Takes a boolean value + that specifies whether systemd should + try to guess the main PID of a service + if it cannot be determined + reliably. This option is ignored + unless + is set and + is unset because for the other types + or with an explicitly configured PID + file the main PID is always known. The + guessing algorithm might come to + incorrect conclusions if a daemon + consists of more than one process. If + the main PID cannot be determined + failure detection and automatic + restarting of a service will not work + reliably. Defaults to + . + + + + + PIDFile= + + Takes an absolute file + name pointing to the PID file of this + daemon. Use of this option is + recommended for services where + Type= is set to + . 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. + + + + + BusName= + + Takes a D-Bus bus + name, that this service is reachable + as. This option is mandatory for + services where + Type= is set to + , but its use + is otherwise recommended as well if + the process takes a name on the D-Bus + bus. + + + + + ExecStart= + Commands with their + arguments that are executed when this + service is started. + + + When + Type=oneshot is + used, more than one command may be + specified. Multiple command lines may + be concatenated in a single directive, + by separating them with semicolons + (these semicolons must be passed as + separate words). Alternatively, this + directive may be specified more than + once with the same effect. However, + the latter syntax is not recommended + for compatibility with parsers + suitable for XDG + .desktop files. + The commands are invoked one by + one sequentially in the order they + appear in the unit file. + When Type is + not , only one + command may be given. Lone semicolons + may be escaped as + '\;'. + + Unless + Type=forking is + set, the process started via this + command line will be considered the + main process of the daemon. + + The command line accepts + '%' specifiers as + described in + systemd.unit5. Note + that the first argument of the command + line (i.e. the program to execute) may + not include specifiers. + + Optionally, if the absolute file + name is prefixed with + '@', the second token + will be passed as + argv[0] to the + executed process, followed by the + further arguments specified. If the + absolute file name is prefixed with + '-' an exit code of + the command normally considered a + failure (i.e. non-zero exit status or + abnormal exit due to signal) is ignored + and considered success. If both + '-' and + '@' are used they + can appear in either order. + + On top of that basic environment + variable substitution is + supported. Use + ${FOO} as part of a + word, or as a word of its own on the + command line, in which case it will be + replaced by the value of the + environment variable including all + whitespace it contains, resulting in a + single argument. Use + $FOO as a separate + word on the command line, in which + case it will be replaced by the value + of the environment variable split up + at whitespace, resulting in no or more + arguments. Note that the first + argument (i.e. the program to execute) + may not be a variable, and must be a + literal and absolute path + name. + + Note that this setting does not + directly support shell command + lines. If shell command lines are to + be used they need to be passed + explicitly to a shell implementation + of some kind. Example: + ExecStart=/bin/sh -c 'dmesg | tac' + + For services run by a user + instance of systemd the special + environment variable + MANAGERPID is set + to the PID of the systemd + instance. + + + + + ExecStartPre= + ExecStartPost= + Additional commands + that are executed before or after + the command in + ExecStart=, respectively. + Syntax is the same as for + ExecStart=, except + that multiple command lines are allowed + and the commands are executed one + after the other, serially. + + + + + ExecReload= + Commands to execute to + trigger a configuration reload in the + service. This argument takes multiple + command lines, following the same + scheme as described for + ExecStart= + above. Use of this setting is + optional. Specifier and environment + variable substitution is supported + here following the same scheme as for + ExecStart=. One + additional special environment + variables is set: if known + $MAINPID is set to + the main process of the daemon, and + may be used for command lines like the + following: /bin/kill -HUP + $MAINPID. + + + + ExecStop= + Commands to execute to + stop the service started via + ExecStart=. This + argument takes multiple command lines, + following the same scheme as described + for ExecStart= + above. Use of this setting is + optional. All processes remaining for + a service after the commands + configured in this option are run are + terminated according to the + KillMode= setting + (see + systemd.kill5). If + this option is not specified the + process is terminated right-away when + service stop is requested. Specifier + and environment variable substitution + is supported (including + $MAINPID, see + above). + + + + ExecStopPost= + Additional commands + that are executed after the service + was stopped using the commands + configured in + ExecStop=. This + argument takes multiple command lines, + following the same scheme as described + for ExecStart. Use + of these settings is + optional. Specifier and environment + variable substitution is + supported. + + + + RestartSec= + Configures the time to + sleep before restarting a service (as + configured with + Restart=). Takes a + unit-less value in seconds, or a time + span value such as "5min + 20s". Defaults to + 100ms. + + + + TimeoutStartSec= + Configures the time to + wait for start-up. If a + daemon service does not signal + start-up completion within the + configured time, the service will be + considered failed and be shut down + again. + Takes a unit-less value in seconds, or a + time span value such as "5min + 20s". Pass 0 to disable the timeout + logic. Defaults to 90s, except when + Type=oneshot is + used in which case the timeout + is disabled by default. + + + + + TimeoutStopSec= + Configures the time to + wait for stop. If a service is asked + to stop but does not terminate in the + specified time, it will be terminated + forcibly via SIGTERM, and after + another delay of this time with + SIGKILL (See + KillMode= + in systemd.kill5). + Takes a unit-less value in seconds, or a + time span value such as "5min + 20s". Pass 0 to disable the timeout + logic. Defaults to 90s. + + + + + TimeoutSec= + A shorthand for configuring + both TimeoutStartSec= + and TimeoutStopSec= + to the specified value. + + + + + WatchdogSec= + Configures the + watchdog timeout for a service. This + is activated when the start-up is + completed. The service must call + sd_notify3 + regularly with "WATCHDOG=1" (i.e. the + "keep-alive ping"). If the time + between two such calls is larger than + the configured time then the service + is placed in a failure state. By + setting Restart= to + or + the service + will be automatically restarted. The + time configured here will be passed to + the executed service process in the + WATCHDOG_USEC= + environment variable. This allows + daemons to automatically enable the + keep-alive pinging logic if watchdog + support is enabled for the service. If + this option is used + NotifyAccess= (see + below) should be set to open access to + the notification socket provided by + systemd. If + NotifyAccess= is + not set, it will be implicitly set to + . Defaults to 0, + which disables this + feature. + + + + Restart= + Configures whether the + main service process shall be + restarted when it exits. Takes one of + , + , + , + or + . If set to + (the default) the + service will not be restarted when it + exits. If set to + it will be + restarted only when it exited cleanly, + i.e. terminated with an exit code of + 0. If set to + it will be + restarted only when it exited with an + exit code not equaling 0, when + terminated by a signal (including on + core dump), when an operation (such as + service reload) times out or when the + configured watchdog timeout is + triggered. If set to + it will be + restarted only if it exits due to + reception of an uncaught signal + (including on core dump). If set to + the service + will be restarted regardless whether + it exited cleanly or not, got + terminated abnormally by a signal or + hit a timeout. + + + + SuccessExitStatus= + Takes a list of exit + status definitions that when returned + by the main service process will be + considered successful termination, in + addition to the normal successful exit + code 0 and the signals SIGHUP, SIGINT, + SIGTERM and SIGPIPE. Exit status + definitions can either be numeric exit + codes or termination signal names, and + are separated by spaces. Example: + "SuccessExitStatus=1 2 8 + SIGKILL", ensures that exit + codes 1, 2, 8 and the termination + signal SIGKILL are considered clean + service + terminations. + + + + RestartPreventExitStatus= + Takes a list of exit + status definitions that when returned + by the main service process will + prevent automatic service restarts + regardless of the restart setting + configured with + Restart=. Exit + status definitions can either be + numeric exit codes or termination + signal names, and are separated by + spaces. Defaults to the empty list, so + that by default no exit status is + excluded from the configured restart + logic. Example: + "RestartPreventExitStatus=1 6 + SIGABRT", ensures that exit + codes 1 and 6 and the termination signal + SIGABRT will not result in automatic + service restarting. + + + + PermissionsStartOnly= + Takes a boolean + argument. If true, the permission + related execution options as + configured with + User= and similar + options (see + systemd.exec5 + for more information) are only applied + to the process started with + ExecStart=, and not + to the various other + ExecStartPre=, + ExecStartPost=, + ExecReload=, + ExecStop=, + ExecStopPost= + commands. If false, the setting is + applied to all configured commands the + same way. Defaults to + false. + + + + RootDirectoryStartOnly= + Takes a boolean + argument. If true, the root directory + as configured with the + RootDirectory= + option (see + systemd.exec5 + for more information) is only applied + to the process started with + ExecStart=, and not + to the various other + ExecStartPre=, + ExecStartPost=, + ExecReload=, + ExecStop=, + ExecStopPost= + commands. If false, the setting is + applied to all configured commands the + same way. Defaults to + false. + + + + NonBlocking= + Set O_NONBLOCK flag + for all file descriptors passed via + socket-based activation. If true, all + file descriptors >= 3 (i.e. all except + STDIN/STDOUT/STDERR) will have + the O_NONBLOCK flag set and hence are in + non-blocking mode. This option is only + useful in conjunction with a socket + unit, as described in + systemd.socket5. Defaults + to false. + + + + NotifyAccess= + Controls access to the + service status notification socket, as + accessible via the + sd_notify3 + call. Takes one of + (the default), + or + . If + no daemon status + updates are accepted from the service + processes, all status update messages + are ignored. If + only service updates sent from the + main process of the service are + accepted. If all + services updates from all members of + the service's control group are + accepted. This option should be set to + open access to the notification socket + when using + Type=notify or + WatchdogUsec= (see + above). If those options are used but + NotifyAccess= not + configured it will be implicitly set + to + . + + + + Sockets= + Specifies the name of + the socket units this service shall + inherit the sockets from when the + service is started. Normally it + should not be necessary to use this + setting as all sockets whose unit + shares the same name as the service + (ignoring the different suffix of course) + are passed to the spawned + process. + + Note that the same socket may be + passed to multiple processes at the + same time. Also note that a different + service may be activated on incoming + traffic than inherits the sockets. Or + in other words: The + Service= setting of + .socket units + doesn't have to match the inverse of the + Sockets= setting of + the .service it + refers to. + + + + StartLimitInterval= + StartLimitBurst= + + Configure service + start rate limiting. By default + services which are started more often + than 5 times within 10s are not + permitted to start any more times + until the 10s interval ends. With + these two options this rate limiting + may be modified. Use + StartLimitInterval= + to configure the checking interval + (defaults to 10s, set to 0 to disable + any kind of rate limiting). Use + StartLimitBurst= to + configure how many starts per interval + are allowed (defaults to 5). These + configuration options are particularly + useful in conjunction with + Restart=, however + apply to all kinds of starts + (including manual), not just those + triggered by the + Restart= logic. + Note that units which are configured + for Restart= and + which reach the start limit are not + attempted to be restarted anymore, + however they may still be restarted + manually at a later point from which + point on the restart logic is again + activated. Note that + systemctl + reset-failed will cause the + restart rate counter for a service to + be flushed, which is useful if the + administrator wants to manually start + a service and the start limit + interferes with + that. + + + + StartLimitAction= + + Configure the action + to take if the rate limit configured + with + StartLimitInterval= + and + StartLimitBurst= is + hit. Takes one of + , + , + or + . If + is set, + hitting the rate limit will trigger no + action besides that the start will not + be + permitted. + causes a reboot following the normal + shutdown procedure (i.e. equivalent to + systemctl reboot), + causes + an forced reboot which will terminate + all processes forcibly but should + cause no dirty file systems on reboot + (i.e. equivalent to systemctl + reboot -f) and + + causes immediate execution of the + reboot2 + system call, which might result in + data loss. Defaults to + . + + + + + Check + systemd.exec5 + and + systemd.kill5 + for more settings. + + + + + Compatibility Options + + The following options are also available in the + [Service] section, but exist purely + for compatibility reasons and should not be used in + newly written service files. + + + + SysVStartPriority= + Set the SysV start + priority to use to order this service + in relation to SysV services lacking + LSB headers. This option is only + necessary to fix ordering in relation + to legacy SysV services, that have no + ordering information encoded in the + script headers. As such it should only + be used as temporary compatibility + option, and not be used in new unit + files. Almost always it is a better + choice to add explicit ordering + directives via + After= or + Before=, + instead. For more details see + systemd.unit5. If + used, pass an integer value in the + range 0-99. + + + + FsckPassNo= + Set the fsck passno + priority to use to order this service + in relation to other file system + checking services. This option is only + necessary to fix ordering in relation + to fsck jobs automatically created for + all /etc/fstab + entries with a value in the fs_passno + column > 0. As such it should only be + used as option for fsck + services. Almost always it is a better + choice to add explicit ordering + directives via + After= or + Before=, + instead. For more details see + systemd.unit5. If + used, pass an integer value in the + same range as + /etc/fstab's + fs_passno column. See + fstab5 + for details. + + + + + + + See Also + + systemd1, + systemctl8, + systemd.unit5, + systemd.exec5, + systemd.kill5 + + + + diff --git a/man/systemd.snapshot.xml b/man/systemd.snapshot.xml new file mode 100644 index 000000000..b432682a4 --- /dev/null +++ b/man/systemd.snapshot.xml @@ -0,0 +1,87 @@ + + + + + + + + + systemd.snapshot + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd.snapshot + 5 + + + + systemd.snapshot + Snapshot unit configuration + + + + systemd.snapshot + + + + Description + + Snapshot units are not configured via unit + configuration files. Nonetheless they are named + similar to filenames. A unit name whose name ends in + .snapshot refers to a dynamic + snapshot of the systemd runtime state. + + Snapshots are not configured on disk but created + dynamically via systemctl snapshot + (see + systemctl8 + for details) or an equivalent command. When created, + they will automatically get dependencies on the + currently activated units. They act as saved + runtime state of the systemd manager. Later on, the + user may choose to return to the saved state via + systemctl isolate. They are + useful to roll back to a defined state after + temporarily starting/stopping services or + similar. + + + + See Also + + systemd1, + systemctl8, + systemd.unit5 + + + + diff --git a/man/systemd.socket.xml b/man/systemd.socket.xml new file mode 100644 index 000000000..4b1fcc8b0 --- /dev/null +++ b/man/systemd.socket.xml @@ -0,0 +1,685 @@ + + + + + + + + + systemd.socket + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd.socket + 5 + + + + systemd.socket + Socket unit configuration + + + + systemd.socket + + + + Description + + A unit configuration file whose name ends in + .socket encodes information about + an IPC or network socket or a file system FIFO + controlled and supervised by systemd, for socket-based + activation. + + This man page lists the configuration options + specific to this unit type. See + systemd.unit5 + for the common options of all unit configuration + files. The common configuration items are configured + in the generic [Unit] and [Install] sections. The + socket specific configuration options are configured + in the [Socket] section. + + Additional options are listed in + systemd.exec5, + which define the execution environment the + , + , + and + commands are executed + in, and in + systemd.kill5 + which define the way the processes are + terminated. + + For each socket file a matching service file + (see + systemd.service5 + for details) must exist, describing the service to + start on incoming traffic on the socket. Depending on + the setting of (see below), + this must either be named like the socket unit, but + with the suffix replaced; or it must be a template + file named the same way. Example: a socket file + foo.socket needs a matching + service foo.service if + is set. If + is set a service template + file foo@.service must exist from + which services are instantiated for each incoming + connection. + + Unless DefaultDependencies= + is set to , socket units will + implicitly have dependencies of type + Requires= and + After= on + sysinit.target as well as + dependencies of type Conflicts= and + Before= on + shutdown.target. These ensure + that socket units pull in basic system + initialization, and are terminated cleanly prior to + system shutdown. Only sockets involved with early + boot or late system shutdown should disable this + option. + + Socket units may be used to implement on-demand + starting of services, as well as parallelized starting + of services. + + Note that the daemon software configured for + socket activation with socket units needs to be able + to accept sockets from systemd, either via systemd's + native socket passing interface (see + sd_listen_fds3 + for details) or via the traditional + inetd8-style + socket passing (i.e. sockets passed in via STDIN and + STDOUT, using StandardInput=socket + in the service file). + + + + Options + + Socket files must include a [Socket] section, + which carries information about the socket or FIFO it + supervises. A number of options that may be used in + this section are shared with other unit types. These + options are documented in + systemd.exec5 + and + systemd.kill5. The + options specific to the [Socket] section of socket + units are the following: + + + + ListenStream= + ListenDatagram= + ListenSequentialPacket= + Specifies an address + to listen on for a stream + (SOCK_STREAM), datagram (SOCK_DGRAM), + or sequential packet + (SOCK_SEQPACKET) socket, respectively. The address + can be written in various formats: + + If the address starts with a + slash (/), it is read as file system + socket in the AF_UNIX socket + family. + + If the address starts with an + at symbol (@) it is read as abstract + namespace socket in the AF_UNIX + family. The @ is replaced with a NUL + character before binding. For details + see + unix7. + + If the address string is a + single number it is read as port + number to listen on via + IPv6. Depending on the value of + BindIPv6Only= (see below) this + might result in the service being + available via both IPv6 and IPv4 (default) or + just via IPv6. + + + If the address string is a + string in the format v.w.x.y:z it is + read as IPv4 specifier for listening + on an address v.w.x.y on a port + z. + + If the address string is a + string in the format [x]:y it is read + as IPv6 address x on a port y. Note + that this might make the service + available via IPv4, too, depending on + the BindIPv6Only= + setting (see below). + + + Note that SOCK_SEQPACKET + (i.e. ListenSequentialPacket=) + is only available for AF_UNIX + sockets. SOCK_STREAM + (i.e. ListenStream=) + when used for IP sockets refers to TCP + sockets, SOCK_DGRAM + (i.e. ListenDatagram=) + to UDP. + + These options may be specified + more than once in which case incoming + traffic on any of the sockets will trigger + service activation, and all listed + sockets will be passed to the service, + regardless whether there is incoming + traffic on them or not. + + If an IP address is used here, it + is often desirable to listen on it + before the interface it is configured + on is up and running, and even + regardless whether it will be up and + running ever at all. To deal with this it is + recommended to set the + FreeBind= option + described below. + + + + ListenFIFO= + Specifies a file + system FIFO to listen on. This expects + an absolute file system path as + argument. Behavior otherwise is very + similar to the + ListenDatagram= + directive above. + + + + ListenSpecial= + Specifies a special + file in the file system to listen + on. This expects an absolute file + system path as argument. Behavior + otherwise is very similar to the + ListenFIFO= + directive above. Use this to open + character device nodes as well as + special files in + /proc and + /sys. + + + + ListenNetlink= + Specifies a Netlink + family to create a socket for to + listen on. This expects a short string + referring to the AF_NETLINK family + name (such as audit + or kobject-uevent) + as argument, optionally suffixed by a + whitespace followed by a multicast + group integer. Behavior otherwise is + very similar to the + ListenDatagram= + directive above. + + + + ListenMessageQueue= + Specifies a POSIX + message queue name to listen on. This + expects a valid message queue name + (i.e. beginning with /). Behavior + otherwise is very similar to the + ListenFIFO= + directive above. On Linux message + queue descriptors are actually file + descriptors and can be inherited + between processes. + + + + BindIPv6Only= + Takes a one of + , + or + . Controls + the IPV6_V6ONLY socket option (see + ipv67 + for details). If + , IPv6 sockets + bound will be accessible via both IPv4 + and IPv6. If + , they will + be accessible via IPv6 only. If + (which is the + default, surprise!) the system wide + default setting is used, as controlled + by + /proc/sys/net/ipv6/bindv6only, + which in turn defaults to the + equivalent of + . + + + + + Backlog= + Takes an unsigned + integer argument. Specifies the number + of connections to queue that have not + been accepted yet. This setting + matters only for stream and sequential + packet sockets. See + listen2 + for details. Defaults to SOMAXCONN + (128). + + + + BindToDevice= + Specifies a network + interface name to bind this socket + to. If set traffic will only be + accepted from the specified network + interfaces. This controls the + SO_BINDTODEVICE socket option (see + socket7 + for details). If this option is used, + an automatic dependency from this + socket unit on the network interface + device unit + (systemd.device5 + is created. + + + + DirectoryMode= + If listening on a file + system socket or FIFO, the parent + directories are automatically created + if needed. This option specifies the + file system access mode used when + creating these directories. Takes an + access mode in octal + notation. Defaults to + 0755. + + + + SocketMode= + If listening on a file + system socket or FIFO, this option + specifies the file system access mode + used when creating the file + node. Takes an access mode in octal + notation. Defaults to + 0666. + + + + Accept= + Takes a boolean + argument. If true, a service instance + is spawned for each incoming + connection and only the connection + socket is passed to it. If false, all + listening sockets themselves are + passed to the started service unit, + and only one service unit is spawned + for all connections (also see + above). This value is ignored for + datagram sockets and FIFOs where + a single service unit unconditionally + handles all incoming traffic. Defaults + to . For + performance reasons, it is recommended + to write new daemons only in a way + that is suitable for + . This + option is mostly useful to allow + daemons designed for usage with + inetd8, + to work unmodified with systemd socket + activation. + + + + MaxConnections= + The maximum number of + connections to simultaneously run + services instances for, when + is + set. If more concurrent connections + are coming in, they will be refused + until at least one existing connection + is terminated. This setting has no + effect for sockets configured with + or datagram + sockets. Defaults to + 64. + + + + KeepAlive= + Takes a boolean + argument. If true, the TCP/IP stack + will send a keep alive message after + 2h (depending on the configuration of + /proc/sys/net/ipv4/tcp_keepalive_time) + for all TCP streams accepted on this + socket. This controls the SO_KEEPALIVE + socket option (see + socket7 + and the TCP + Keepalive HOWTO for details.) + Defaults to + . + + + + Priority= + Takes an integer + argument controlling the priority for + all traffic sent from this + socket. This controls the SO_PRIORITY + socket option (see + socket7 + for details.). + + + + ReceiveBuffer= + SendBuffer= + Takes an integer + argument controlling the receive + or send buffer sizes of this + socket, respectively. This controls the SO_RCVBUF + and SO_SNDBUF socket options (see + socket7 + for details.). + + + + IPTOS= + Takes an integer + argument controlling the IP + Type-Of-Service field for packets + generated from this socket. This + controls the IP_TOS socket option (see + ip7 + for details.). Either a numeric string + or one of , + , + or + may be + specified. + + + + IPTTL= + Takes an integer + argument controlling the IPv4 + Time-To-Live/IPv6 Hop-Count field for + packets generated from this + socket. This sets the + IP_TTL/IPV6_UNICAST_HOPS socket + options (see + ip7 + and + ipv67 + for details.) + + + + Mark= + Takes an integer + value. Controls the firewall mark of + packets generated by this socket. This + can be used in the firewall logic to + filter packets from this socket. This + sets the SO_MARK socket option. See + iptables8 + for details. + + + + SmackLabel= + SmackLabelIPIn= + SmackLabelIPOut= + Takes a string + value. Controls the extended + attributes + security.SMACK64, + security.SMACK64IPIN + and + security.SMACK64IPOUT, + respectively, i.e. the security label + of the FIFO, or the security label for + the incoming or outgoing connections + of the socket, respectively. See + Smack.txt + for details. + + + + PipeSize= + Takes an integer + value. Controls the pipe buffer size + of FIFOs configured in this socket + unit. See + fcntl2 + for details. + + + + MessageQueueMaxMessages=, + MessageQueueMessageSize= + These two settings + take integer values and control the + mq_maxmsg field or the mq_msgsize field, respectively, when + creating the message queue. Note that + either none or both of these variables + need to be set. See + mq_setattr3 + for details. + + + + FreeBind= + Takes a boolean + value. Controls whether the socket can + be bound to non-local IP + addresses. This is useful to configure + sockets listening on specific IP + addresses before those IP addresses + are successfully configured on a + network interface. This sets the + IP_FREEBIND socket option. For + robustness reasons it is recommended + to use this option whenever you bind a + socket to a specific IP + address. Defaults to . + + + + Transparent= + Takes a boolean + value. Controls the IP_TRANSPARENT + socket option. Defaults to + . + + + + Broadcast= + Takes a boolean + value. This controls the SO_BROADCAST + socket option, which allows broadcast + datagrams to be sent from this + socket. Defaults to + . + + + + PassCredentials= + Takes a boolean + value. This controls the SO_PASSCRED + socket option, which allows AF_UNIX sockets to + receive the credentials of the sending + process in an ancillary message. + Defaults to + . + + + + PassSecurity= + Takes a boolean + value. This controls the SO_PASSSEC + socket option, which allows AF_UNIX + sockets to receive the security + context of the sending process in an + ancillary message. Defaults to + . + + + + TCPCongestion= + Takes a string + value. Controls the TCP congestion + algorithm used by this socket. Should + be one of "westwood", "veno", "cubic", + "lp" or any other available algorithm + supported by the IP stack. This + setting applies only to stream + sockets. + + + + ExecStartPre= + ExecStartPost= + Takes one or more + command lines, which are executed + before or after the listening + sockets/FIFOs are created and + bound, respectively. The first token of the command + line must be an absolute file name, + then followed by arguments for the + process. Multiple command lines may be + specified following the same scheme as + used for + ExecStartPre= of + service unit files. + + + + ExecStopPre= + ExecStopPost= + Additional commands + that are executed before or after + the listening sockets/FIFOs are closed + and removed, respectively. Multiple command lines + may be specified following the same + scheme as used for + ExecStartPre= of + service unit files. + + + + TimeoutSec= + Configures the time to + wait for the commands specified in + ExecStartPre=, + ExecStartPost=, + ExecStopPre= and + ExecStopPost= to + finish. If a command does not exit + within the configured time, the socket + will be considered failed and be shut + down again. All commands still running, + will be terminated forcibly via + SIGTERM, and after another delay of + this time with SIGKILL. (See + in systemd.kill5.) + Takes a unit-less value in seconds, or + a time span value such as "5min + 20s". Pass 0 to disable the timeout + logic. Defaults to + 90s. + + + + Service= + Specifies the service + unit name to activate on incoming + traffic. This defaults to the service + that bears the same name as the socket + (ignoring the different suffixes). In + most cases it should not be necessary + to use this option. + + + + + Check + systemd.exec5 + and + systemd.kill5 + for more settings. + + + + + See Also + + systemd1, + systemctl8, + systemd.unit5, + systemd.exec5, + systemd.kill5, + systemd.service5 + + + + diff --git a/man/systemd.special.xml b/man/systemd.special.xml new file mode 100644 index 000000000..9ea288e33 --- /dev/null +++ b/man/systemd.special.xml @@ -0,0 +1,817 @@ + + + + + + + + + systemd.special + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd.special + 7 + + + + systemd.special + Special systemd units + + + + basic.target, + bluetooth.target, + ctrl-alt-del.target, + cryptsetup.target, + dbus.service, + dbus.socket, + default.target, + display-manager.service, + emergency.target, + exit.target, + final.target, + getty.target, + graphical.target, + halt.target, + hibernate.target, + hybrid-sleep.target, + kbrequest.target, + kexec.target, + local-fs.target, + local-fs-pre.target, + mail-transfer-agent.target, + multi-user.target, + network.target, + nss-lookup.target, + nss-user-lookup.target, + poweroff.target, + printer.target, + reboot.target, + remote-fs.target, + remote-fs-pre.target, + rescue.target, + rpcbind.target, + runlevel2.target, + runlevel3.target, + runlevel4.target, + runlevel5.target, + shutdown.target, + sigpwr.target, + sleep.target, + smartcard.target, + sockets.target, + sound.target, + suspend.target, + swap.target, + sysinit.target, + syslog.socket, + syslog.target, + system-update.target, + time-sync.target, + umount.target + + + + Description + + A few units are treated specially by + systemd. They have special internal semantics and + cannot be renamed. + + + + Special System Units + + + + basic.target + + A special target unit + covering early boot-up. + systemd automatically + adds dependencies of the types + Requires and After for this + target unit to all SysV + service units configured for + runlevel 1 to 5. + Usually this should pull-in + all sockets, mount points, + swap devices and other basic + initialization necessary for + the general purpose + daemons. Most normal daemons + should have dependencies of + type After and Requires on + this unit. + + + + bluetooth.target + + This target is started + automatically as soon as a + bluetooth controller is + plugged in or becomes + available at boot. + + + + ctrl-alt-del.target + + systemd starts this + target whenever + Control+Alt+Del is pressed on + the console. Usually this + should be aliased (symlinked) + to + reboot.target. + + + + cryptsetup.target + + A target that pulls in + setup services for all + encrypted block + devices. + + + + dbus.service + + A special unit for the + D-Bus system bus. As soon as + this service is fully started + up systemd will connect to it + and register its + service. + + + + dbus.socket + + A special unit for the + D-Bus system bus socket. All + units with + Type=dbus + automatically gain a + dependency on this + unit. + + + + default.target + + The default unit systemd + starts at bootup. Usually this + should be aliased (symlinked) + to + multi-user.target + or + graphical.target. + The default unit systemd + starts at bootup can be + overridden with the + systemd.unit= + kernel command line option. + + + + display-manager.service + + The display manager + service. Usually this should + be aliased (symlinked) to + gdm.service + or a similar display manager + service. + systemd automatically + adds dependencies of type + After for this target unit to + all SysV init script service + units with a LSB header + referring to the + $x-display-manager + facility. + + + + emergency.target + + A special target unit + that starts an emergency + shell on the main + console. This unit is supposed + to be used with the kernel + command line option + systemd.unit= + and has otherwise little use. + + + + + final.target + + A special target unit + that is used during the + shutdown logic and may be used + to pull in late services after + all normal services are + already terminated and all + mounts unmounted. + + + + + getty.target + + A special target unit + that pulls in all local TTY + getty instances. + + + + + graphical.target + + A special target unit + for setting up a graphical + login screen. This pulls in + multi-user.target. + + Units that are needed + for graphical login shall add + Wants dependencies for their + unit to this unit (or + multi-user.target) + during installation. + + + + hibernate.target + + A special target unit + for hibernating the + system. This pulls in + sleep.target. + + + + hybrid-sleep.target + + A special target unit + for hibernating and suspending the + system at the same time. This pulls in + sleep.target. + + + + halt.target + + A special target unit + for shutting down and halting the system. + + Applications wanting to + halt the system should start + this unit. + + + + kbrequest.target + + systemd starts this + target whenever Alt+ArrowUp is + pressed on the console. This + is a good candidate to be + aliased (symlinked) to + rescue.target. + + + + kexec.target + + A special target unit + for shutting down and rebooting the system via kexec. + + Applications wanting to + reboot the system with kexec should start + this unit. + + + + local-fs.target + + systemd automatically + adds dependencies of type + After to all mount units that + refer to local mount points + for this target unit. In + addition, systemd adds + dependencies of type Wants to + this target unit for those + mounts listed in + /etc/fstab + that have the + and + + mount options set. + + systemd automatically + adds dependencies of type + After for this target unit to + all SysV init script service + units with an LSB header + referring to the + $local_fs + facility. + + + + local-fs-pre.target + + This target unit is + automatically ordered before + all local mount points marked + with + (see above). It can be used to + execute certain units before + all local mounts. + + + + mail-transfer-agent.target + + The mail transfer agent + (MTA) service. Usually this + should pull-in all units + necessary for + sending/receiving mails on the + local host. + + systemd automatically + adds dependencies of type + After for this target unit to + all SysV init script service + units with an LSB header + referring to the + $mail-transfer-agent. + + + + multi-user.target + + A special target unit + for setting up a multi-user + system (non-graphical). This + is pulled in by + graphical.target. + + Units that are needed + for a multi-user system shall + add Wants dependencies to + this unit for their unit during + installation. + + + + network.target + + systemd automatically + adds dependencies of type + After for this target unit to + all SysV init script service + units with an LSB header + referring to the + $network + facility. + + + + nss-lookup.target + + A target that should be + used as synchronization point + for all host/network name + service lookups. Note that + this is independent of + user/group name lookups for + which + nss-user-lookup.target + should be used. systemd + automatically adds + dependencies of type After for + this target unit to all SysV + init script service units with + an LSB header referring to the + $named + facility. + + + + nss-user-lookup.target + + A target that should be + used as synchronization point + for all user/group name + service lookups. Note that + this is independent of + host/network name lookups for + which + nss-lookup.target + should be used. + + + + poweroff.target + + A special target unit + for shutting down and powering off the system. + + Applications wanting to + power off the system should start + this unit. + + runlevel0.target + is an alias for this target + unit, for compatibility with SysV. + + + + printer.target + + This target is started + automatically as soon as a + printer is plugged in or + becomes available at + boot. + + + + reboot.target + + A special target unit + for shutting down and rebooting the system. + + Applications wanting to + reboot the system should start + this unit. + + runlevel6.target + is an alias for this target + unit, for compatibility with SysV. + + + + remote-fs.target + + Similar to + local-fs.target, + but for remote mount + points. + + systemd automatically + adds dependencies of type + After for this target unit to + all SysV init script service + units with an LSB header + referring to the + $remote_fs + facility. + + + + remote-fs-pre.target + + This target unit is + automatically ordered before + all remote mount points marked + with + (see above). It can be used to + execute certain units before + all remote mounts. + + + + rescue.target + + A special target unit + for setting up the base system + and a rescue shell. + + runlevel1.target + is an alias for this target + unit, for compatibility with SysV. + + + + rpcbind.target + + systemd automatically + adds dependencies of type + After for this target unit to + all SysV init script service + units with an LSB header + referring to the + $portmap + facility. + + + + runlevel2.target + runlevel3.target + runlevel4.target + runlevel5.target + + These are targets that + are called whenever the SysV + compatibility code asks for + runlevel 2, 3, 4, 5, + respectively. It is a good + idea to make this an alias for + (i.e. symlink to) + multi-user.target + (for runlevel 2) or + graphical.target + (the others). + + + + shutdown.target + + A special target unit + that terminates the services + on system shutdown. + + Services that shall be + terminated on system shutdown + shall add Conflicts + dependencies to this unit for + their service unit, which is + implicitly done when + DefaultDependencies=yes + is set (the default). + + systemd automatically + adds dependencies of type + Conflicts to this target unit + for all SysV init script + service units that shall be + terminated in SysV runlevels 0 + or 6. + + + + sigpwr.target + + A special target that is + started when systemd receives + the SIGPWR process signal, + which is normally sent by the + kernel or UPS daemons when + power fails. + + + + sleep.target + + A special target unit + that is pulled in by + suspend.target, + hibernate.target and hybrid-sleep.target + and may be used to hook units + into the sleep state + logic. + + + + smartcard.target + + This target is started + automatically as soon as a + smartcard controller is + plugged in or becomes + available at boot. + + + + sockets.target + + A special target unit + that sets up all service + sockets. + + Services that can be + socket-activated shall add + Wants dependencies to this + unit for their socket unit + during installation. + + + + sound.target + + This target is started + automatically as soon as a + sound card is plugged in or + becomes available at + boot. + + + + suspend.target + + A special target unit + for suspending the + system. This pulls in + sleep.target. + + + + swap.target + + Similar to + local-fs.target, but for swap + partitions and swap + files. + + + + sysinit.target + + A special target unit + covering early boot-up scripts. + systemd automatically + adds dependencies of the types + Wants and After for all + SysV service units configured + for runlevels that are not 0 + to 6 to this target unit. + This covers the special + boot-up runlevels some + distributions have, such as S + or b. + + + + syslog.socket + + The socket unit + syslog implementations should + listen on. All userspace log + messages will be made + available on this socket. For + more information about syslog + integration, please consult + the Syslog + Interface + document. + + + + syslog.target + + systemd automatically + adds dependencies of type + After for this target unit to + all SysV init script service + units with an LSB header + referring to the + $syslog + facility. + + + + system-update.target + + A special target unit + that is used for off-line + system updates. + systemd-system-update-generator8 + will redirect the boot process + to this target if + /system-update + exists. For more information + see the System + Updates + Specification. + + + + time-sync.target + + systemd automatically + adds dependencies of type + After for this target unit to + all SysV init script service + units with an LSB header + referring to the + $time + facility. + + + + umount.target + + A special target unit + that umounts all mount and + automount points on system + shutdown. + + Mounts that shall be + unmounted on system shutdown + shall add Conflicts + dependencies to this unit for + their mount unit, which is + implicitly done when + DefaultDependencies=yes + is set (the default). + + + + + + + + Special User Units + + When systemd runs as a user instance, the + following special units are available, which have + similar definitions as their system counterparts: + default.target, + shutdown.target, + sockets.target + + In addition the following special unit is + understood only when systemd runs as service instance: + + + + exit.target + + A special service unit + for shutting down the + user service manager. + + Applications wanting to + terminate the user service + manager should start this + unit. If systemd receives + SIGTERM or SIGINT when running + as user service daemon it will + start this unit. + + Normally, this pulls in + shutdown.target + which in turn should be + conflicted by all units that + want to be shut down on + user service manager exit. + + + + + + + See Also + + systemd1, + systemd.unit5, + systemd.service5, + systemd.socket5, + systemd.target5, + bootup7 + + + + diff --git a/man/systemd.swap.xml b/man/systemd.swap.xml new file mode 100644 index 000000000..a932143d4 --- /dev/null +++ b/man/systemd.swap.xml @@ -0,0 +1,213 @@ + + + + + + + + + systemd.swap + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd.swap + 5 + + + + systemd.swap + Swap unit configuration + + + + systemd.swap + + + + Description + + A unit configuration file whose name ends in + .swap encodes information about a + swap device or file for memory paging controlled and + supervised by systemd. + + This man page lists the configuration options + specific to this unit type. See + systemd.unit5 + for the common options of all unit configuration + files. The common configuration items are configured + in the generic [Unit] and [Install] sections. The swap + specific configuration options are configured in the + [Swap] section. + + Additional options are listed in + systemd.exec5, + which define the execution environment the + swapon8 + binary is executed in, and in + systemd.kill5 + which define the way the processes are + terminated. + + Swap units must be named after the devices + or files they control. Example: the swap device + /dev/sda5 must be configured in a + unit file dev-sda5.swap. For + details about the escaping logic used to convert a + file system path to a unit name see + systemd.unit5. + + All swap units automatically get the appropriate + dependencies on the devices or on the mount points + of the files they are activated from. + + Swap units with + DefaultDependencies= enabled + implicitly acquire a conflicting dependency to + umount.target so that they are + deactivated at shutdown. + + + + <filename>fstab</filename> + + Swap units may either be configured via unit + files, or via /etc/fstab (see + fstab5 + for details). Swaps listed in + /etc/fstab will be converted into + native units dynamically at boot and when the + configuration of the system manager is + reloaded. See + systemd-fstab-generator8 + for details about the conversion. + + If a swap device or file is configured in both + /etc/fstab and a unit file the + configuration in the latter takes precedence. + + Unless the option is set + for them all swap units configured in + /etc/fstab are also added as + requirements to swap.target, so + that they are waited for and activated during + boot. + + + + Options + + Swap files must include a [Swap] section, which + carries information about the swap device it + supervises. A number of options that may be used in + this section are shared with other unit types. These + options are documented in + systemd.exec5 + and + systemd.kill5. The + options specific to the [Swap] section of swap units + are the following: + + + + + What= + Takes an absolute path + of a device node or file to use for + paging. See + swapon8 + for details. If this refers to a + device node, a dependency on the + respective device unit is + automatically created. (See + systemd.device5 + for more information.) If this refers + to a file, a dependency on the + respective mount unit is automatically + created. (See + systemd.mount5 + for more information.) This option is + mandatory. + + + + Priority= + + Swap priority to use + when activating the swap device or + file. This takes an integer. This + setting is optional. + + + + TimeoutSec= + Configures the time to + wait for the swapon command to + finish. If a command does not exit + within the configured time the swap + will be considered failed and be shut + down again. All commands still running + will be terminated forcibly via + SIGTERM, and after another delay of + this time with SIGKILL. (See + in + systemd.kill5.) + Takes a unit-less value in seconds, or + a time span value such as "5min + 20s". Pass 0 to disable the timeout + logic. Defaults to + 90s. + + + + Check + systemd.exec5 + and + systemd.kill5 + for more settings. + + + + See Also + + systemd1, + systemctl8, + systemd.unit5, + systemd.exec5, + systemd.kill5, + systemd.device5, + systemd.mount5, + swapon8, + systemd-fstab-generator8 + + + + diff --git a/man/systemd.target.xml b/man/systemd.target.xml new file mode 100644 index 000000000..d1f4d2267 --- /dev/null +++ b/man/systemd.target.xml @@ -0,0 +1,108 @@ + + + + + + + + + systemd.target + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd.target + 5 + + + + systemd.target + Target unit configuration + + + + systemd.target + + + + Description + + A unit configuration file whose name ends in + .target encodes information about + a target unit of systemd, which is used for grouping + units and as well-known synchronization points during + start-up. + + This unit type has no specific options. See + systemd.unit5 + for the common options of all unit configuration + files. The common configuration items are configured + in the generic [Unit] and [Install] sections. A + separate [Target] section does not exist, since no + target-specific options may be configured. + + Target units do not offer any additional + functionality on top of the generic functionality + provided by units. They exist merely to group units via dependencies + (useful as boot targets), and to establish + standardized names for synchronization points used in + dependencies between units. Among other things, target + units are a more flexible replacement for SysV + runlevels in the classic SysV init system. (And for + compatibility reasons special + target units such as + runlevel3.target exist which are used by + the SysV runlevel compatibility code in systemd. See + systemd.special7 + for details). + + Unless DefaultDependencies= + is set to , target units will + implicitly complement all configured dependencies of + type Wants=, + Requires=, + RequiresOverridable= with + dependencies of type After= if the + units in question also have + DefaultDependencies=true. + + + + + See Also + + systemd1, + systemctl8, + systemd.unit5, + systemd.special7 + + + + diff --git a/man/systemd.time.xml b/man/systemd.time.xml new file mode 100644 index 000000000..4f80a306b --- /dev/null +++ b/man/systemd.time.xml @@ -0,0 +1,291 @@ + + + + + + + + + systemd.time + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd.time + 7 + + + + systemd.time + Time and date specifications + + + + Description + + In systemd timestamps, timespans, and calendar + events are displayed and may be specified in closely + related syntaxes. + + + + Displaying Timespans + + Timespans refer to time durations. On display + systemd will present timespans as a space separated + series of time values each suffixed by a time + unit. + + 2h 30min + + All specified time values are meant to be added + up. The above hence refers to 150 minutes. + + + + Parsing Timespans + + When parsing systemd will accept the same + timespan syntax. Separating spaces may be omitted. The + following time units are understood: + + + usec, us + msec, ms + seconds, second, sec, s + minutes, minute, min, m + hours, hour, hr, h + days, day, d + weeks, week, w + months, month + years, year, y + + + If no time unit is specified, generally seconds + are assumed, but some exceptions exist and are marked + as such. In a few cases ns, + nsec is accepted too, where the + granularity of the timespan allows for this. + + Examples for valid timespan specifications: + + 2 h +2hours +48hr +1y 12month +55s500ms +300ms20s 5day + + + + Displaying Timestamps + + Timestamps refer to specific, unique points in + time. On display systemd will format these in the + local timezone as follows: + + Fri 2012-11-23 23:02:15 CET + + The week day is printed according to the locale + choice of the user. + + + + Parsing Timestamps + + When parsing systemd will accept a similar + timestamp syntax, but excluding any timezone + specification (this limitation might be removed + eventually). The week day specification is optional, + but when the week day is specified it must either be + in the abbreviated (Wed) or + non-abbreviated (Wednesday) english + language form (case doesn't matter), and is not + subject to the locale choice of the user. Either the + date, or the time part may be omitted, in which case + the current date or 00:00:00, resp., is assumed. The + seconds component of the time may also be omitted, in + which case ":00" is assumed. Year numbers may be + specified in full or may be abbreviated (omitting the + century). + + A timestamp is considered invalid if a week day + is specified and the date does not actually match the + specified day of the week. + + When parsing systemd will also accept a few + special placeholders instead of timestamps: + now may be used to refer to the + current time (or of the invocation of the command + that is currently executed). today, + yesterday, + tomorrow refer to 00:00:00 of the + current day, the day before or the next day, + respectively. + + When parsing systemd will also accept relative + time specifications. A timespan (see above) that is + prefixed with + is evaluated to the + current time plus the specified + timespan. Correspondingly a timespan that is prefix + with - is evaluated to the current + time minus the specified timespan. Instead of + prefixing the timespan with - it + may also be suffixed with a space and the word + ago. + + Examples for valid timestamps and their + normalized form (assuming the current time was + 2012-11-23 18:15:22): + + Fri 2012-11-23 11:12:13 → Fri 2012-11-23 11:12:13 + 2012-11-23 11:12:13 → Fri 2012-11-23 11:12:13 + 2012-11-23 → Fri 2012-11-23 00:00:00 + 12-11-23 → Fri 2012-11-23 00:00:00 + 11:12:13 → Fri 2012-11-23 11:12:13 + 11:12 → Fri 2012-11-23 11:12:00 + now → Fri 2012-11-23 18:15:22 + today → Fri 2012-11-23 00:00:00 + yesterday → Fri 2012-11-22 00:00:00 + tomorrow → Fri 2012-11-24 00:00:00 + +3h30min → Fri 2012-11-23 21:45:22 + -5s → Fri 2012-11-23 18:15:17 + 11min ago → Fri 2012-11-23 18:04:22 + + Note that timestamps printed by systemd will not + be parsed correctly by systemd, as the timezone + specification is not accepted, and printing timestamps + is subject to locale settings for the week day while + parsing only accepts english week day names. + + In some cases systemd will display a relative + timestamp (relative to the current time, or the time + of invocation of the command) instead or in addition + to an absolute timestamp as described above. A + relative timestamp is formatted as follows: + + 2 months 5 days ago + + Note that any relative timestamp will also parse + correctly where a timestamp is expected. (see above) + + + + Calendar Events + + Calendar events may be used to refer to one or + more points in time in a single expression. They form + a superset of the absolute timestamps explained above: + + Thu,Fri 2012-*-1,5 11:12:13 + + The above refers to 11:12:13 of the first or + fifth day of any month of the year 2012, given that it + is a thursday or friday. + + The weekday specification is optional. If + specified it should consist of one or more english + language week day names, either in the abbreviated + (Wed) or non-abbreviated (Wednesday) form (case does + not matter), separated by colons. Specifying two week + days separated by "-" refers to a range of continuous + week days. "," and "-" may be combined freely. + + In the date and time specifications any + component may be specified as "*" in which case any + value will match. Alternatively, each component can be + specified as list of values separated by + colons. Values may also be suffixed with "/" and a + repetition value, which indicates that the value and + all values plus multiples of the repetition value are + matched. + + Either time or date specification may be + omitted, in which case the current day and 00:00:00 is + implied, respectively. If the second component is not + specified ":00" is assumed. + + Timezone names may not be specified. + + The special expressions + hourly, daily, + monthly and weekly + may be used as calendar events which refer to + *-*-* *:00:00, *-*-* + 00:00:00, *-*-01 00:00:00 and + Mon *-*-* 00:00:00, + respectively. + + Examples for valid timestamps and their + normalized form: + + Sat,Thu,Mon-Wed,Sat-Sun → Mon-Thu,Sat,Sun *-*-* 00:00:00 + Mon,Sun 12-*-* 2,1:23 → Mon,Sun 2012-*-* 01,02:23:00 + Wed *-1 → Wed *-*-01 00:00:00 + Wed-Wed,Wed *-1 → Wed *-*-01 00:00:00 + Wed, 17:48 → Wed *-*-* 17:48:00 +Wed-Sat,Tue 12-10-15 1:2:3 → Tue-Sat 2012-10-15 01:02:03 + *-*-7 0:0:0 → *-*-07 00:00:00 + 10-15 → *-10-15 00:00:00 + monday *-12-* 17:00 → Mon *-12-* 17:00:00 + Mon,Fri *-*-3,1,2 *:30:45 → Mon,Fri *-*-01,02,03 *:30:45 + 12,14,13,12:20,10,30 → *-*-* 12,13,14:10,20,30:00 + mon,fri *-1/2-1,3 *:30:45 → Mon,Fri *-01/2-01,03 *:30:45 + 03-05 08:05:40 → *-03-05 08:05:40 + 08:05:40 → *-*-* 08:05:40 + 05:40 → *-*-* 05:40:00 + Sat,Sun 12-05 08:05:40 → Sat,Sun *-12-05 08:05:40 + Sat,Sun 08:05:40 → Sat,Sun *-*-* 08:05:40 + 2003-03-05 05:40 → 2003-03-05 05:40:00 + 2003-03-05 → 2003-03-05 00:00:00 + 03-05 → *-03-05 00:00:00 + hourly → *-*-* *:00:00 + daily → *-*-* 00:00:00 + monthly → *-*-01 00:00:00 + weekly → Mon *-*-* 00:00:00 + *:2/3 → *-*-* *:02/3:00 + + Calendar events are used by timer units, see + systemd.timer5 + for details. + + + + + See Also + + systemd1, + journalctl1, + systemd.timer5, + systemd.unit5 + + + + diff --git a/man/systemd.timer.xml b/man/systemd.timer.xml new file mode 100644 index 000000000..5cc543e45 --- /dev/null +++ b/man/systemd.timer.xml @@ -0,0 +1,206 @@ + + + + + + + + + systemd.timer + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd.timer + 5 + + + + systemd.timer + Timer unit configuration + + + + systemd.timer + + + + Description + + A unit configuration file whose name ends in + .timer encodes information about + a timer controlled and supervised by systemd, for + timer-based activation. + + This man page lists the configuration options + specific to this unit type. See + systemd.unit5 + for the common options of all unit configuration + files. The common configuration items are configured + in the generic [Unit] and [Install] sections. The + timer specific configuration options are configured in + the [Timer] section. + + For each timer file, a matching unit file must + exist, describing the unit to activate when the timer + elapses. By default, a service by the same name as the + timer (except for the suffix) is activated. Example: a + timer file foo.timer activates a + matching service foo.service. The + unit to activate may be controlled by + Unit= (see below). + + Unless DefaultDependencies= + is set to , timer units will + implicitly have dependencies of type + Conflicts= and + Before= on + shutdown.target. These ensure + that timer units are stopped cleanly prior to system + shutdown. Only timer units involved with early boot or + late system shutdown should disable this + option. + + + + Options + + Timer files must include a [Timer] section, + which carries information about the timer it + defines. The options specific to the [Timer] section + of timer units are the following: + + + + OnActiveSec= + OnBootSec= + OnStartupSec= + OnUnitActiveSec= + OnUnitInactiveSec= + + Defines monotonic timers + relative to different starting points: + OnActiveSec= defines a + timer relative to the moment the timer + itself is + activated. OnBootSec= + defines a timer relative to when the + machine was booted + up. OnStartupSec= + defines a timer relative to when + systemd was + started. OnUnitActiveSec= + defines a timer relative to when the + unit the timer is activating was last + activated. OnUnitInactiveSec= + defines a timer relative to when the + unit the timer is activating was last + deactivated. + + Multiple directives may be + combined of the same and of different + types. For example, by combining + OnBootSec= and + OnUnitActiveSec= it is + possible to define a timer that + elapses in regular intervals and + activates a specific service each + time. + + The arguments to the directives + are time spans configured in + seconds. Example: "OnBootSec=50" means + 50s after boot-up. The argument may + also include time units. Example: + "OnBootSec=5h 30min" means 5 hours and + 30 minutes after boot-up. For details + about the syntax of time spans see + systemd.unit5. + + If a timer configured with + OnBootSec= or + OnStartupSec= is + already in the past when the timer + unit is activated, it will immediately + elapse and the configured unit is + started. This is not the case for + timers defined in the other + directives. + + These are monotonic timers, + independent of wall-clock time and timezones. If the + computer is temporarily suspended, the + monotonic clock stops too. + + + + + OnCalendar= + + Defines realtime + (i.e. wallclock) timers via calendar + event expressions. See + systemd.time7 + for more information on the syntax of + calendar event + expressions. + + + + Unit= + + The unit to activate + when this timer elapses. The argument is a + unit name, whose suffix is not + .timer. If not + specified, this value defaults to a + service that has the same name as the + timer unit, except for the + suffix. (See above.) It is recommended + that the unit name that is activated + and the unit name of the timer unit + are named identically, except for the + suffix. + + + + + + See Also + + systemd1, + systemctl8, + systemd.unit5, + systemd.service5, + systemd.time7 + + + + diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml new file mode 100644 index 000000000..8570815ad --- /dev/null +++ b/man/systemd.unit.xml @@ -0,0 +1,1108 @@ + + + + + + + + + systemd.unit + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd.unit + 5 + + + + systemd.unit + Unit configuration + + + + systemd.service, + systemd.socket, + systemd.device, + systemd.mount, + systemd.automount, + systemd.swap, + systemd.target, + systemd.path, + systemd.timer, + systemd.snapshot + + + + Description + + A unit configuration file encodes information + about a service, a socket, a device, a mount point, an + automount point, a swap file or partition, a start-up + target, a file system path or a timer controlled and + supervised by + systemd1. The + syntax is inspired by XDG + Desktop Entry Specification .desktop files, which are in turn + inspired by Microsoft Windows + .ini files. + + This man page lists the common configuration + options of all the unit types. These options need to + be configured in the [Unit] or [Install] + sections of the unit files. + + In addition to the generic [Unit] and [Install] + sections described here, each unit should have a + type-specific section, e.g. [Service] for a service + unit. See the respective man pages for more + information. + + Unit files may contain additional options on top + of those listed here. If systemd encounters an unknown + option it will write a warning log message but + continue loading the unit. If an option is prefixed + with it is ignored completely by + systemd. Applications may use this to include + additional information in the unit files. + + Boolean arguments used in unit files can be + written in various formats. For positive settings the + strings , , + and are + equivalent. For negative settings the strings + , , + and are + equivalent. + + Time span values encoded in unit files can be + written in various formats. A stand-alone number + specifies a time in seconds. If suffixed with a time + unit, the unit is honored. A concatenation of + multiple values with units is supported, in which case + the values are added up. Example: "50" refers to 50 + seconds; "2min 200ms" refers to 2 minutes plus 200 + milliseconds, i.e. 120200ms. The following time units + are understood: s, min, h, d, w, ms, us. For details see systemd.time7. + + Empty lines and lines starting with # or ; are + ignored. This may be used for commenting. Lines ending + in a backslash are concatenated with the following + line while reading and the backslash is replaced by a + space character. This may be used to wrap long lines. + + If a line starts with + followed by a file name, the specified file will be + parsed at this point. Make sure that the file that is + included has the appropriate section headers before + any directives. + + Along with a unit file + foo.service a directory + foo.service.wants/ may exist. All + units symlinked from such a directory are implicitly + added as dependencies of type + Wanted= to the unit. This is useful + to hook units into the start-up of other units, + without having to modify their unit configuration + files. For details about the semantics of + Wanted= see below. The preferred + way to create symlinks in the + .wants/ directory of a service is + with the enable command of the + systemctl1 + tool which reads information from the [Install] + section of unit files. (See below.) A similar + functionality exists for Requires= + type dependencies as well, the directory suffix is + .requires/ in this case. + + Note that while systemd offers a flexible + dependency system between units it is recommended to + use this functionality only sparsely and instead rely + on techniques such as bus-based or socket-based + activation which makes dependencies implicit, which + both results in a simpler and more flexible + system. + + Some unit names reflect paths existing in the + file system name space. Example: a device unit + dev-sda.device refers to a device + with the device node /dev/sda in + the file system namespace. If this applies a special + way to escape the path name is used, so that the + result is usable as part of a file name. Basically, + given a path, "/" is replaced by "-", and all + unprintable characters and the "-" are replaced by + C-style "\x20" escapes. The root directory "/" is + encoded as single dash, while otherwise the initial + and ending "/" is removed from all paths during + transformation. This escaping is reversible. + + Optionally, units may be instantiated from a + template file at runtime. This allows creation of + multiple units from a single configuration file. If + systemd looks for a unit configuration file it will + first search for the literal unit name in the + filesystem. If that yields no success and the unit + name contains an @ character, systemd will look for a + unit template that shares the same name but with the + instance string (i.e. the part between the @ character + and the suffix) removed. Example: if a service + getty@tty3.service is requested + and no file by that name is found, systemd will look + for getty@.service and + instantiate a service from that configuration file if + it is found. + + To refer to the instance string from + within the configuration file you may use the special + %i specifier in many of the + configuration options. Other specifiers exist, the + full list is: + + + Specifiers available in unit files + + + + + + + Specifier + Meaning + Details + + + + + %n + Full unit name + + + + %N + Unescaped full unit name + + + + %p + Prefix name + This refers to the string before the @, i.e. "getty" in the example above, where "tty3" is the instance name. + + + %P + Unescaped prefix name + + + + %i + Instance name + This is the string between the @ character and the suffix. + + + %I + Unescaped instance name + + + + %f + Unescaped file name + This is either the unescaped instance name (if set) with / prepended (if necessary), or the prefix name similarly prepended with /. + + + %c + Control group path of the unit + + + + %r + Root control group path of systemd + + + + %R + Parent directory of the root control group path of systemd + + + + %t + Runtime socket dir + This is either /run (for the system manager) or $XDG_RUNTIME_DIR (for user managers). + + + %u + User name + This is the name of the configured user of the unit, or (if none is set) the user running the systemd instance. + + + %U + User uid + This is the uid of the configured user of the unit, or (if none is set) the user running the systemd instance. + + + %h + User home directory + This is the home directory of the configured user of the unit, or (if none is set) the user running the systemd instance. + + + %s + User shell + This is the shell of the configured user of the unit, or (if none is set) the user running the systemd instance. + + + %m + Machine ID + The machine ID of the running system, formatted as string. See machine-id5 for more information. + + + %b + Boot ID + The boot ID of the running system, formatted as string. See random4 for more information. + + + %H + Host name + The host name of the running system. + + + +
+ + If a unit file is empty (i.e. has the file size + 0) or is symlinked to /dev/null + its configuration will not be loaded and it appears + with a load state of masked, and + cannot be activated. Use this as an effective way to + fully disable a unit, making it impossible to start it + even manually. + + The unit file format is covered by the + Interface + Stability Promise. +
+ + + Options + + Unit file may include a [Unit] section, which + carries generic information about the unit that is not + dependent on the type of unit: + + + + + Description= + A free-form string + describing the unit. This is intended + for use in UIs to show descriptive + information along with the unit + name. + + + + Documentation= + A space separated list + of URIs referencing documentation for + this unit or its + configuration. Accepted are only URIs + of the types + http://, + https://, + file:, + info:, + man:. For more + information about the syntax of these + URIs see + uri7. The + URIs should be listed in order of + relevance, starting with the most + relevant. It is a good idea to first + reference documentation that explains + what the unit's purpose is, followed + by how it is configured, followed by + any other related + documentation. + + + + Requires= + + 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 gets deactivated or + its activation fails, this unit will + be deactivated. This option may be + specified more than once, in which + case requirement dependencies for all + listed names are 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 + After= or + Before= options. If + a unit + foo.service + requires a unit + bar.service as + configured with + Requires= and no + ordering is configured with + After= or + Before=, then both + units will be started simultaneously + and without any delay between them if + foo.service is + activated. Often it is a better choice + to use Wants= + instead of + Requires= in order + to achieve a system that is more + robust when dealing with failing + services. + + Note that dependencies of this + type may also be configured outside of + the unit configuration file by + adding a symlink to a + .requires/ directory + accompanying the unit file. For + details see above. + + + + RequiresOverridable= + + Similar to + Requires=. + Dependencies listed in + RequiresOverridable= + which cannot be fulfilled or fail to + start are ignored if the startup was + explicitly requested by the user. If + the start-up was pulled in indirectly + by some dependency or automatic + start-up of units that is not + requested by the user this dependency + must be fulfilled and otherwise the + transaction fails. Hence, this option + may be used to configure dependencies + that are normally honored unless the + user explicitly starts up the unit, in + which case whether they failed or not + is irrelevant. + + + + Requisite= + RequisiteOverridable= + + Similar to + Requires= + and RequiresOverridable=, respectively. However, + if a unit listed here is not started + already it will not be started and the + transaction fails + immediately. + + + + Wants= + + A weaker version of + Requires=. A unit + listed in this option will be started + if the configuring unit is. However, + if the listed unit fails to start up + or cannot be added to the transaction + this has no impact on the validity of + the transaction as a whole. This is + the recommended way to hook start-up + of one unit to the start-up of another + unit. + + Note that dependencies of this + type may also be configured outside of + the unit configuration file by + adding a symlink to a + .wants/ directory + accompanying the unit file. For + details see above. + + + + BindsTo= + + Configures requirement + dependencies, very similar in style to + Requires=, however + in addition to this behavior it also + declares that this unit is stopped + when any of the units listed suddenly + disappears. Units can suddenly, + unexpectedly disappear if a service + terminates on its own choice, a device + is unplugged or a mount point + unmounted without involvement of + systemd. + + + + PartOf= + + Configures dependencies + similar to Requires=, + but limited to stopping and restarting + of units. When systemd stops or restarts + the units listed here, the action is + propagated to this unit. + Note that this is a one way dependency - + changes to this unit do not affect the + listed units. + + + + + Conflicts= + + Configures negative + requirement dependencies. If a unit + has a + Conflicts= setting + on another unit, starting the former + will stop the latter and vice + versa. Note that this setting is + independent of and orthogonal to the + After= and + Before= ordering + dependencies. + + If a unit A that conflicts with + a unit B is scheduled to be started at + the same time as B, the transaction + will either fail (in case both are + required part of the transaction) or + be modified to be fixed (in case one + or both jobs are not a required part + of the transaction). In the latter + case the job that is not the required + will be removed, or in case both are + not required the unit that conflicts + will be started and the unit that is + conflicted is + stopped. + + + + Before= + After= + + Configures ordering + dependencies between units. If a unit + foo.service + contains a setting + + and both units are being started, + bar.service's + start-up is delayed until + foo.service is + started up. Note that this setting is + independent of and orthogonal to the + requirement dependencies as configured + by Requires=. It is + a common pattern to include a unit + name in both the + After= and + Requires= option in + which case the unit listed will be + started before the unit that is + configured with these options. This + option may be specified more than + once, in which case ordering + dependencies for all listed names are + created. After= is + the inverse of + Before=, i.e. while + After= ensures that + the configured unit is started after + the listed unit finished starting up, + Before= ensures the + opposite, i.e. that the configured + unit is fully started up before the + listed unit is started. Note that when + two units with an ordering dependency + between them are shut down, the + inverse of the start-up order is + applied. i.e. if a unit is configured + with After= on + another unit, the former is stopped + before the latter if both are shut + down. If one unit with an ordering + dependency on another unit is shut + down while the latter is started up, + the shut down is ordered before the + start-up regardless whether the + ordering dependency is actually of + type After= or + Before=. If two + units have no ordering dependencies + between them they are shut down + or started up simultaneously, and + no ordering takes + place. + + + + OnFailure= + + Lists one or more + units that are activated when this + unit enters the + 'failed' + state. + + + + PropagatesReloadTo= + ReloadPropagatedFrom= + + Lists one or more + units where reload requests on the + unit will be propagated to/on the + other unit will be propagated + from. Issuing a reload request on a + unit will automatically also enqueue a + reload request on all units that the + reload request shall be propagated to + via these two + settings. + + + + RequiresMountsFor= + + Takes a space + separated list of absolute paths. Automatically + adds dependencies of type + Requires= and + After= for all + mount units required to access the + specified path. + + + + OnFailureIsolate= + + Takes a boolean + argument. If the + unit listed in + OnFailure= will be + enqueued in isolation mode, i.e. all + units that are not its dependency will + be stopped. If this is set only a + single unit may be listed in + OnFailure=. Defaults + to + . + + + + IgnoreOnIsolate= + + Takes a boolean + argument. If + this unit will not be stopped when + isolating another unit. Defaults to + . + + + + IgnoreOnSnapshot= + + Takes a boolean + argument. If + this unit will not be included in + snapshots. Defaults to + for device and + snapshot units, + for the others. + + + + StopWhenUnneeded= + + Takes a boolean + argument. If + this unit will be stopped when it is + no longer used. Note that in order to + minimize the work to be executed, + systemd will not stop units by default + unless they are conflicting with other + units, or the user explicitly + requested their shut down. If this + option is set, a unit will be + automatically cleaned up if no other + active unit requires it. Defaults to + . + + + + RefuseManualStart= + RefuseManualStop= + + Takes a boolean + argument. If + this unit can only be activated + or deactivated indirectly. In + this case explicit start-up + or termination requested by the + user is denied, however if it is + started or stopped as a + dependency of another unit, start-up + or termination will succeed. This + is mostly a safety feature to ensure + that the user does not accidentally + activate units that are not intended + to be activated explicitly, and not + accidentally deactivate units that are + not intended to be deactivated. + These options default to + . + + + + AllowIsolate= + + Takes a boolean + argument. If + this unit may be used with the + systemctl isolate + command. Otherwise this will be + refused. It probably is a good idea to + leave this disabled except for target + units that shall be used similar to + runlevels in SysV init systems, just + as a precaution to avoid unusable + system states. This option defaults to + . + + + + DefaultDependencies= + + Takes a boolean + argument. If + (the default), a few default + dependencies will implicitly be + created for the unit. The actual + dependencies created depend on the + unit type. For example, for service + units, these dependencies ensure that + the service is started only after + basic system initialization is + completed and is properly terminated on + system shutdown. See the respective + man pages for details. Generally, only + services involved with early boot or + late shutdown should set this option + to . It is + highly recommended to leave this + option enabled for the majority of + common units. If set to + this option + does not disable all implicit + dependencies, just non-essential + ones. + + + + JobTimeoutSec= + + When clients are + waiting for a job of this unit to + complete, time out after the specified + time. If this time limit is reached + the job will be cancelled, the unit + however will not change state or even + enter the 'failed' + mode. This value defaults to 0 (job + timeouts disabled), except for device + units. NB: this timeout is independent + from any unit-specific timeout (for + example, the timeout set with + Timeout= in service + units) as the job timeout has no + effect on the unit itself, only on the + job that might be pending for it. Or + in other words: unit-specific timeouts + are useful to abort unit state + changes, and revert them. The job + timeout set with this option however + is useful to abort only the job + waiting for the unit state to + change. + + + + ConditionPathExists= + ConditionPathExistsGlob= + ConditionPathIsDirectory= + ConditionPathIsSymbolicLink= + ConditionPathIsMountPoint= + ConditionPathIsReadWrite= + ConditionDirectoryNotEmpty= + ConditionFileNotEmpty= + ConditionFileIsExecutable= + ConditionKernelCommandLine= + ConditionVirtualization= + ConditionSecurity= + ConditionCapability= + ConditionHost= + ConditionACPower= + ConditionNull= + + Before starting a unit + verify that the specified condition is + true. If it is not true the starting + of the unit will be skipped, however + all ordering dependencies of it are + still respected. A failing condition + will not result in the unit being + moved into a failure state. The + condition is checked at the time the + queued start job is to be + executed. + + With + ConditionPathExists= + a file existence condition is + checked before a unit is started. If + the specified absolute path name does + not exist the condition will + fail. If the absolute path name passed + to + ConditionPathExists= + is prefixed with an exclamation mark + ('!'), the test is negated, and the unit + is only started if the path does not + exist. + + ConditionPathExistsGlob= + is similar to + ConditionPathExists=, + but checks for the existence of at + least one file or directory matching + the specified globbing pattern. + + ConditionPathIsDirectory= + is similar to + ConditionPathExists= + but verifies whether a certain path + exists and is a + directory. + + ConditionPathIsSymbolicLink= + is similar to + ConditionPathExists= + but verifies whether a certain path + exists and is a symbolic + link. + + ConditionPathIsMountPoint= + is similar to + ConditionPathExists= + but verifies whether a certain path + exists and is a mount + point. + + ConditionPathIsReadWrite= + is similar to + ConditionPathExists= + but verifies whether the underlying + file system is readable and writable + (i.e. not mounted + read-only). + + ConditionDirectoryNotEmpty= + is similar to + ConditionPathExists= + but verifies whether a certain path + exists and is a non-empty + directory. + + ConditionFileNotEmpty= + is similar to + ConditionPathExists= + but verifies whether a certain path + exists and refers to a regular file + with a non-zero size. + + ConditionFileIsExecutable= + is similar to + ConditionPathExists= + but verifies whether a certain path + exists, is a regular file and marked + executable. + + Similar, + ConditionKernelCommandLine= + may be used to check whether a + specific kernel command line option is + set (or if prefixed with the + exclamation mark unset). The argument + must either be a single word, or an + assignment (i.e. two words, separated + '='). In the former + case the kernel command line is + searched for the word appearing as is, + or as left hand side of an + assignment. In the latter case the + exact assignment is looked for with + right and left hand side + matching. + + ConditionVirtualization= + may be used to check whether the + system is executed in a virtualized + environment and optionally test + whether it is a specific + implementation. Takes either boolean + value to check if being executed in + any virtualized environment, or one of + vm and + container to test + against a generic type of + virtualization solution, or one of + qemu, + kvm, + vmware, + microsoft, + oracle, + xen, + bochs, + chroot, + openvz, + lxc, + lxc-libvirt, + systemd-nspawn to + test against a specific + implementation. If multiple + virtualization technologies are nested + only the innermost is considered. The + test may be negated by prepending an + exclamation mark. + + ConditionSecurity= + may be used to check whether the given + security module is enabled on the + system. Currently the only recognized + value is selinux. + The test may be negated by prepending + an exclamation + mark. + + ConditionCapability= + may be used to check whether the given + capability exists in the capability + bounding set of the service manager + (i.e. this does not check whether + capability is actually available in + the permitted or effective sets, see + capabilities7 + for details). Pass a capability name + such as CAP_MKNOD, + possibly prefixed with an exclamation + mark to negate the check. + + ConditionHost= + may be used to match against the + host name or machine ID of the + host. This either takes a host name + string (optionally with shell style + globs) which is tested against the + locally set host name as returned by + gethostname2, + or a machine ID formatted as string + (see + machine-id5). + The test may be negated by prepending + an exclamation mark. + + ConditionACPower= + may may be used to check whether the + system has AC power, or is exlcusively + battery powered at the time of + activation of the unit. This takes a + boolean argument. If set to + true the condition + will hold only if at least one AC + connector of the system is connected + to a power source, or if no AC + connectors are known. Conversely, if + set to false the + condition will hold only if there is + at least one AC connector known and + all AC connectors are disconnected + from a power source. + + Finally, + ConditionNull= may + be used to add a constant condition + check value to the unit. It takes a + boolean argument. If set to + false the condition + will always fail, otherwise + succeed. + + 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 + which case a condition becomes a + triggering condition. If at least one + triggering condition is defined for a + unit then the unit will be executed if + at least one of the triggering + conditions apply and all of the + non-triggering conditions. If you + prefix an argument with the pipe + symbol and an exclamation mark the + pipe symbol must be passed first, the + exclamation second. Except for + ConditionPathIsSymbolicLink=, + all path checks follow + symlinks. + + + + SourcePath= + A path to a + configuration file this unit has been + generated from. This is primarily + useful for implementation of generator + tools that convert configuration from + an external configuration file format + into native unit files. Thus + functionality should not be used in + normal units. + + + + Unit file may include a [Install] section, which + carries installation information for the unit. This + section is not interpreted by + systemd1 + during runtime. It is used exclusively by the + enable and + disable commands of the + systemctl1 + tool during installation of a unit: + + + + Alias= + + Additional names this + unit shall be installed under. The + names listed here must have the same + suffix (i.e. type) as the unit file + name. This option may be specified + more than once, in which case all + listed names are used. At installation + time, + systemctl enable + will create symlinks from these names + to the unit file name. + + + + WantedBy= + RequiredBy= + + Installs a symlink in + the .wants/ + or .requires/ + subdirectory for a unit, respectively. This has the + effect that when the listed unit name + is activated the unit listing it is + activated + too. WantedBy=foo.service + in a service + bar.service is + mostly equivalent to + Alias=foo.service.wants/bar.service + in the same file. + + + + Also= + + Additional units to + install when this unit is + installed. If the user requests + installation of a unit with this + option configured, + systemctl enable + will automatically install units + listed in this option as + well. + + + + + + + See Also + + systemd1, + systemctl8, + systemd.special7, + systemd.service5, + systemd.socket5, + systemd.device5, + systemd.mount5, + systemd.automount5, + systemd.swap5, + systemd.target5, + systemd.path5, + systemd.timer5, + systemd.snapshot5, + systemd.time7, + capabilities7 + + + +
diff --git a/man/systemd.xml b/man/systemd.xml new file mode 100644 index 000000000..7b3d265b8 --- /dev/null +++ b/man/systemd.xml @@ -0,0 +1,1272 @@ + + + + + + + + + systemd + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd + 1 + + + + systemd + init + systemd system and service manager + + + + + systemd OPTIONS + + + init OPTIONS COMMAND + + + + + Description + + systemd is a system and service manager for + Linux operating systems. When run as first process on + boot (as PID 1), it acts as init system that brings + up and maintains userspace services. + + For compatibility with SysV, if systemd is called + as init and a PID that is not + 1, it will execute telinit and pass + all command line arguments unmodified. That means + init and telinit + are mostly equivalent when invoked from normal login sessions. See + telinit8 + for more information. + + When run as system instance, systemd interprets + the configuration file + system.conf, otherwise + user.conf. See + systemd.conf5 + for more information. + + + + Options + + The following options are understood: + + + + + + + Prints a short help + text and exits. + + + + + Prints a systemd version + identifier and exits. + + + + + Determine startup + sequence, dump it and exit. This is an + option useful for debugging + only. + + + + + Dump understood unit + configuration items. This outputs a + terse but complete list of + configuration items understood in unit + definition files. + + + + + Extract D-Bus + interface introspection data. This is + mostly useful at install time + to generate data suitable for the + D-Bus interfaces + repository. Optionally the interface + name for the introspection data may be + specified. If omitted, the + introspection data for all interfaces + is dumped. + + + + + Set default unit to + activate on startup. If not specified + defaults to + default.target. + + + + + + For , + tell systemd to run a + system instance, even if the process ID is + not 1, i.e. systemd is not run as init process. + does the opposite, + running a user instance even if the process + ID is 1. + Normally it should not be necessary to + pass these options, as systemd + automatically detects the mode it is + started in. These options are hence of + little use except for debugging. Note + that it is not supported booting and + maintaining a full system with systemd + running in + mode, but PID not 1. In practice, + passing explicitly is + only useful in conjunction with + . + + + + + Dump core on + crash. This switch has no effect when + run as user + instance. + + + + + Run shell on + crash. This switch has no effect when + run as user + instance. + + + + + Ask for confirmation + when spawning processes. This switch + has no effect when run as user + instance. + + + + + Show terse service + status information while booting. This + switch has no effect when run as user + instance. Takes a boolean argument + which may be omitted which is + interpreted as + . + + + + + Set log + target. Argument must be one of + , + , + , + , + , + , + . + + + + + Set log level. As + argument this accepts a numerical log + level or the well-known syslog3 + symbolic names (lowercase): + , + , + , + , + , + , + , + . + + + + + Highlight important + log messages. Argument is a boolean + value. If the argument is omitted it + defaults to + . + + + + + Include code location + in log messages. This is mostly + relevant for debugging + purposes. Argument is a boolean + value. If the argument is omitted + it defaults to + . + + + + + + Sets the default + output or error output for all + services and sockets, respectively. That is, controls + the default for + + and + (see + systemd.exec5 + for details). Takes one of + , + , + , + , + , + , + , + , + . If the + argument is omitted + + defaults to + and + + to + . + + + + + + Concepts + + systemd provides a dependency system between + various entities called "units". Units encapsulate + various objects that are relevant for system boot-up + and maintenance. The majority of units are configured + in unit configuration files, whose syntax and basic + set of options is described in + systemd.unit5, + however some are created automatically from other + configuration or dynamically from system state. Units + may be 'active' (meaning started, bound, plugged in, + ... depending on the unit type, see below), or + 'inactive' (meaning stopped, unbound, unplugged, ...), + as well as in the process of being activated or + deactivated, i.e. between the two states (these 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. + + The following unit types are available: + + + Service units, which control + daemons and the processes they consist of. For + details see + systemd.service5. + + Socket units, which + encapsulate local IPC or network sockets in + the system, useful for socket-based + activation. For details about socket units see + systemd.socket5, + for details on socket-based activation and + other forms of activation, see + daemon7. + + Target units are useful to + group units, or provide well-known + synchronization points during boot-up, see + systemd.target5. + + Device units expose kernel + devices in systemd and may be used to + implement device-based activation. For details + see + systemd.device5. + + Mount units control mount + points in the file system, for details see + systemd.mount5. + + Automount units provide + automount capabilities, for on-demand mounting + of file systems as well as parallelized + boot-up. See + systemd.automount5. + + Snapshot units can be used to + temporarily save the state of the set of + systemd units, which later may be restored by + activating the saved snapshot unit. For more + information see + systemd.snapshot5. + + Timer units are useful for + triggering activation of other units based on + timers. You may find details in + systemd.timer5. + + Swap units are very similar to + mount units and encapsulate memory swap + partitions or files of the operating + system. They are described in systemd.swap5. + + Path units may be used + to activate other services when file system + objects change or are modified. See + systemd.path5. + + + + Units are named as their configuration + files. Some units have special semantics. A detailed + list is available in + systemd.special7. + + systemd knows various kinds of dependencies, + including positive and negative requirement + dependencies (i.e. Requires= and + Conflicts=) as well as ordering + dependencies (After= and + Before=). NB: ordering and + requirement dependencies are orthogonal. If only a + requirement dependency exists between two units + (e.g. foo.service requires + bar.service), but no ordering + dependency (e.g. foo.service + after bar.service) and both are + requested to start, they will be started in + parallel. It is a common pattern that both requirement + and ordering dependencies are placed between two + units. Also note that the majority of dependencies are + implicitly created and maintained by systemd. In most + cases it should be unnecessary to declare additional + dependencies manually, however it is possible to do + this. + + Application programs and units (via + dependencies) may request state changes of units. In + systemd, these requests are encapsulated as 'jobs' and + maintained in a job queue. Jobs may succeed or can + fail, their execution is ordered based on the ordering + dependencies of the units they have been scheduled + for. + + On boot systemd activates the target unit + default.target whose job is to + activate on-boot services and other on-boot units by + pulling them in via dependencies. Usually the unit + name is just an alias (symlink) for either + graphical.target (for + fully-featured boots into the UI) or + multi-user.target (for limited + console-only boots for use in embedded or server + environments, or similar; a subset of + graphical.target). However it is at the discretion of + the administrator to configure it as an alias to any + other target unit. See + systemd.special7 + for details about these target units. + + Processes systemd spawns are placed in + individual Linux control groups named after the unit + which they belong to in the private systemd + hierarchy. (see cgroups.txt + 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 via the + file system hierarchy (beneath + /sys/fs/cgroup/systemd/), or in tools + such as + ps1 + (ps xawf -eo pid,user,cgroup,args + is particularly useful to list all processes and the + systemd units they belong to.). + + systemd is compatible with the SysV init system + to a large degree: SysV init scripts are supported and + simply read as an alternative (though limited) + configuration file format. The SysV + /dev/initctl interface is + provided, and compatibility implementations of the + various SysV client tools are available. In addition to + that, various established Unix functionality such as + /etc/fstab or the + utmp database are + supported. + + systemd has a minimal transaction system: if a + unit is requested to start up or shut down it will add + it and all its dependencies to a temporary + transaction. Then, it will verify if the transaction + is consistent (i.e. whether the ordering of all units + is cycle-free). If it is not, systemd will try to fix + it up, and removes non-essential jobs from the + transaction that might remove the loop. Also, systemd + tries to suppress non-essential jobs in the + transaction that would stop a running service. Finally + it is checked whether the jobs of the transaction + contradict jobs that have already been queued, and + optionally the transaction is aborted then. If all + worked out and the transaction is consistent and + minimized in its impact it is merged with all already + outstanding jobs and added to the run + queue. Effectively this means that before executing a + requested operation, systemd will verify that it makes + sense, fixing it if possible, and only failing if it + really cannot work. + + Systemd contains native implementations of + various tasks that need to be executed as part of the + boot process. For example, it sets the host name or + configures the loopback network device. It also sets + up and mounts various API file systems, such as + /sys or + /proc. + + For more information about the concepts and + ideas behind systemd please refer to the Original + Design Document. + + Note that some but not all interfaces provided + by systemd are covered by the Interface + Stability Promise. + + Units may be generated dynamically at boot and + system manager reload time, for example based on other + configuration files or parameters passed on the kernel + command line. For details see the Generators + Specification. + + Systems which invoke systemd in a container + or initrd environment should implement the + Container + Interface or initrd + Interface specifications, respectively. + + + + Directories + + + + System unit directories + + The systemd system + manager reads unit configuration from + various directories. Packages that + want to install unit files shall place + them in the directory returned by + pkg-config systemd + --variable=systemdsystemunitdir. Other + directories checked are + /usr/local/lib/systemd/system + and + /usr/lib/systemd/system. User + configuration always takes + precedence. pkg-config + systemd + --variable=systemdsystemconfdir + returns the path of the system + configuration directory. Packages + should alter the content of these + directories only with the + enable and + disable commands of + the + systemctl1 + tool. + + + + + + User unit directories + + Similar rules apply + for the user unit + directories. However, here the XDG + Base Directory specification + is followed to find + units. Applications should place their + unit files in the directory returned + by pkg-config systemd + --variable=systemduserunitdir. Global + configuration is done in the directory + reported by pkg-config + systemd + --variable=systemduserconfdir. The + enable and + disable commands of + the + systemctl1 + tool can handle both global (i.e. for + all users) and private (for one user) + enabling/disabling of + units. + + + + + + SysV init scripts directory + + The location of the + SysV init script directory varies + between distributions. If systemd + cannot find a native unit file for a + requested service, it will look for a + SysV init script of the same name + (with the + .service suffix + removed). + + + + + + SysV runlevel link farm directory + + The location of the + SysV runlevel link farm directory + varies between distributions. systemd + will take the link farm into account + when figuring out whether a service + shall be enabled. Note that a service + unit with a native unit configuration + file cannot be started by activating it + in the SysV runlevel link + farm. + + + + + + Signals + + + + SIGTERM + + Upon receiving this + signal the systemd system manager + serializes its state, reexecutes + itself and deserializes the saved + state again. This is mostly equivalent + to systemctl + daemon-reexec. + + systemd user managers will + start the + exit.target unit + when this signal is received. This is + mostly equivalent to + systemctl --user start + exit.target. + + + + SIGINT + + Upon receiving this + signal the systemd system manager will + start the + ctrl-alt-del.target unit. This + is mostly equivalent to + systemctl start + ctl-alt-del.target. + + systemd user managers + treat this signal the same way as + SIGTERM. + + + + SIGWINCH + + When this signal is + received the systemd system manager + will start the + kbrequest.target + unit. This is mostly equivalent to + systemctl start + kbrequest.target. + + This signal is ignored by + systemd user + managers. + + + + SIGPWR + + When this signal is + received the systemd manager + will start the + sigpwr.target + unit. This is mostly equivalent to + systemctl start + sigpwr.target. + + + + SIGUSR1 + + When this signal is + received the systemd manager will try + to reconnect to the D-Bus + bus. + + + + SIGUSR2 + + When this signal is + received the systemd manager will log + its complete state in human readable + form. The data logged is the same as + printed by systemctl + dump. + + + + SIGHUP + + Reloads the complete + daemon configuration. This is mostly + equivalent to systemctl + daemon-reload. + + + + SIGRTMIN+0 + + Enters default mode, starts the + default.target + unit. This is mostly equivalent to + systemctl start + default.target. + + + + SIGRTMIN+1 + + Enters rescue mode, + starts the + rescue.target + unit. This is mostly equivalent to + systemctl isolate + rescue.target. + + + + SIGRTMIN+2 + + Enters emergency mode, + starts the + emergency.service + unit. This is mostly equivalent to + systemctl isolate + emergency.service. + + + + SIGRTMIN+3 + + Halts the machine, + starts the + halt.target + unit. This is mostly equivalent to + systemctl start + halt.target. + + + + SIGRTMIN+4 + + Powers off the machine, + starts the + poweroff.target + unit. This is mostly equivalent to + systemctl start + poweroff.target. + + + + SIGRTMIN+5 + + Reboots the machine, + starts the + reboot.target + unit. This is mostly equivalent to + systemctl start + reboot.target. + + + + SIGRTMIN+6 + + Reboots the machine via kexec, + starts the + kexec.target + unit. This is mostly equivalent to + systemctl start + kexec.target. + + + + SIGRTMIN+13 + + Immediately halts the machine. + + + + SIGRTMIN+14 + + Immediately powers off the machine. + + + + SIGRTMIN+15 + + Immediately reboots the machine. + + + + SIGRTMIN+16 + + Immediately reboots the machine with kexec. + + + + SIGRTMIN+20 + + Enables display of + status messages on the console, as + controlled via + systemd.show_status=1 + on the kernel command + line. + + + + SIGRTMIN+21 + + Disables display of + status messages on the console, as + controlled via + systemd.show_status=0 + on the kernel command + line. + + + + SIGRTMIN+22 + SIGRTMIN+23 + + Sets the log level to + debug + (or info on + SIGRTMIN+23), as + controlled via + systemd.log_level=debug + (or systemd.log_level=info + on SIGRTMIN+23) on + the kernel command + line. + + + + SIGRTMIN+24 + + Immediately exits the + manager (only available for --user + instances). + + + + SIGRTMIN+26 + SIGRTMIN+27 + SIGRTMIN+28 + SIGRTMIN+29 + + Sets the log level to + journal-or-kmsg + (or console on + SIGRTMIN+27, + kmsg on + SIGRTMIN+28, + or syslog-or-kmsg + on SIGRTMIN+29), as + controlled via + systemd.log_target=journal-or-kmsg + (or systemd.log_target=console + on SIGRTMIN+27, + systemd.log_target=kmsg + on SIGRTMIN+28, + or + systemd.log_target=syslog-or-kmsg + on SIGRTMIN+29) on + the kernel command + line. + + + + + + Environment + + + + $SYSTEMD_LOG_LEVEL + systemd reads the + log level from this environment + variable. This can be overridden with + . + + + + $SYSTEMD_LOG_TARGET + systemd reads the + log target from this environment + variable. This can be overridden with + . + + + + $SYSTEMD_LOG_COLOR + Controls whether + systemd highlights important log + messages. This can be overridden with + . + + + + $SYSTEMD_LOG_LOCATION + Controls whether + systemd prints the code location along + with log messages. This can be + overridden with + . + + + + $XDG_CONFIG_HOME + $XDG_CONFIG_DIRS + $XDG_DATA_HOME + $XDG_DATA_DIRS + + The systemd user + manager uses these variables in + accordance to the XDG + Base Directory specification + to find its configuration. + + + + $SYSTEMD_UNIT_PATH + + Controls where systemd + looks for unit + files. + + + + $SYSTEMD_SYSVINIT_PATH + + Controls where systemd + looks for SysV init scripts. + + + + $SYSTEMD_SYSVRCND_PATH + + Controls where systemd + looks for SysV init script runlevel link + farms. + + + + $LISTEN_PID + $LISTEN_FDS + + Set by systemd for + supervised processes during + socket-based activation. See + sd_listen_fds3 + for more information. + + + + + $NOTIFY_SOCKET + + Set by systemd for + supervised processes for status and + start-up completion notification. See + sd_notify3 + for more information. + + + + + + + Kernel Command Line + + When run as system instance systemd parses a + number of kernel command line + argumentsIf run inside a Linux + container these arguments may be passed as command + line arguments to systemd itself, next to any of the + command line options listed in the Options section + above. If run outside of Linux containers, these + arguments are parsed from + /proc/cmdline + instead.: + + + + systemd.unit= + rd.systemd.unit= + + Overrides the unit to + activate on boot. Defaults to + default.target. This + may be used to temporarily boot into a + different boot unit, for example + rescue.target or + emergency.service. See + systemd.special7 + for details about these units. The + option prefixed with + rd. is honored + only in the initial RAM disk (initrd), + while the one that isn't prefixed only + in the main system. + + + + systemd.dump_core= + + Takes a boolean + argument. If + systemd dumps core when it + crashes. Otherwise no core dump is + created. Defaults to + . + + + + systemd.crash_shell= + + Takes a boolean + argument. If + systemd spawns a shell when it + crashes. Otherwise no shell is + spawned. Defaults to + , for security + reasons, as the shell is not protected + by any password + authentication. + + + + systemd.crash_chvt= + + Takes an integer + argument. If positive systemd + activates the specified virtual + terminal when it crashes. Defaults to + -1. + + + + systemd.confirm_spawn= + + Takes a boolean + argument. If + asks for confirmation when spawning + processes. Defaults to + . + + + + systemd.show_status= + + Takes a boolean + argument. If + shows terse service status updates on + the console during bootup. Defaults to + , unless + is passed as + kernel command line option in which + case it defaults to + . + + + + systemd.log_target= + systemd.log_level= + systemd.log_color= + systemd.log_location= + + Controls log output, + with the same effect as the + $SYSTEMD_LOG_TARGET, $SYSTEMD_LOG_LEVEL, $SYSTEMD_LOG_COLOR, $SYSTEMD_LOG_LOCATION + environment variables described above. + + + + systemd.default_standard_output= + systemd.default_standard_error= + Controls default + standard output and error output for + services, with the same effect as the + + and + command line arguments described + above, respectively. + + + + systemd.setenv= + + Takes a string + argument in the form + VARIABLE=VALUE. May be used to set + environment variables for the init + process and all its children at boot + time. May be used more than once to + set multiple variables. If the equal + sign and variable are missing it unsets + an environment variable which might be + passed in from the initial ram + disk. + + + + quiet + + If passed turns off + status output at boot, much like + systemd.show_status=false + would. Note that this option is also + read by the kernel itself and disables + kernel log output to the + kernel. Passing this option hence + turns off the usual output from both + the system manager and the + kernel. + + + + emergency + + Boot into emergency + mode. This is equivalent to + systemd.unit=emergency.target + and provided for compatibility + reasons and to be easier to type. + + + + single + s + S + 1 + + Boot into rescue + mode. This is equivalent to + systemd.unit=rescue.target + and provided for compatibility reasons + and to be easier to + type. + + + + 2 + 3 + 4 + 5 + + Boot into the + specified legacy SysV runlevel. These + are equivalent to + systemd.unit=runlevel2.target, + systemd.unit=runlevel3.target, + systemd.unit=runlevel4.target, + and systemd.unit=runlevel5.target, respectively, + and provided for compatibility reasons + and to be easier to + type. + + + + locale.LANG= + locale.LANGUAGE= + locale.LC_CTYPE= + locale.LC_NUMERIC= + locale.LC_TIME= + locale.LC_COLLATE= + locale.LC_MONETARY= + locale.LC_MESSAGES= + locale.LC_PAPER= + locale.LC_NAME= + locale.LC_ADDRESS= + locale.LC_TELEPHONE= + locale.LC_MEASUREMENT= + locale.LC_IDENTIFICATION= + + Set the system locale + to use. This overrides the settings in + /etc/locale.conf. For + more information see + locale.conf5 + and + locale7. + + + + + For other kernel command line parameters + understood by components of the core OS, please refer + to + kernel-command-line7. + + + + Sockets and FIFOs + + + + /run/systemd/notify + + Daemon status + notification socket. This is an + AF_UNIX datagram socket and is used to + implement the daemon notification + logic as implemented by + sd_notify3. + + + + + /run/systemd/shutdownd + + Used internally by the + shutdown8 + tool to implement delayed + shutdowns. This is an AF_UNIX datagram + socket. + + + + /run/systemd/private + + Used internally as + communication channel between + systemctl1 + and the systemd process. This is an + AF_UNIX stream socket. This interface + is private to systemd and should not + be used in external + projects. + + + + /dev/initctl + + Limited compatibility + support for the SysV client interface, + as implemented by the + systemd-initctl.service + unit. This is a named pipe in the file + system. This interface is obsolete and + should not be used in new + applications. + + + + + + See Also + + systemd.conf5, + locale.conf5, + systemctl1, + journalctl1, + systemd-notify1, + daemon7, + sd-daemon3, + systemd.unit5, + systemd.special5, + pkg-config1, + kernel-command-line7, + bootup7 + + + + diff --git a/man/telinit.xml b/man/telinit.xml new file mode 100644 index 000000000..4c6064f54 --- /dev/null +++ b/man/telinit.xml @@ -0,0 +1,195 @@ + + + + + + + + + telinit + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + telinit + 8 + + + + telinit + Change SysV runlevel + + + + + telinit OPTIONS COMMAND + + + + + Description + + telinit may be used to change + the SysV system runlevel. Since the concept of SysV + runlevels is obsolete the runlevel requests + will be transparently translated into systemd unit + activation requests. + + + + + Options + + The following options are understood: + + + + + + Prints a short help + text and exits. + + + + + + Don't send wall + message before + reboot/halt/power-off. + + + + The following commands are understood: + + + + 0 + + Power-off the + machine. This is translated into an + activation request for + poweroff.target + and is equivalent to + systemctl + poweroff. + + + + 6 + + Reboot the + machine. This is translated into an + activation request for + reboot.target and + is equivalent to systemctl + reboot. + + + + 2 + 3 + 4 + 5 + + Change the SysV + runlevel. This is translated into an + activation request for + runlevel2.target, + runlevel3.target, + ... and is equivalent to + systemctl isolate + runlevel2.target, + systemctl isolate + runlevel3.target, + ... + + + + 1 + s + S + + Change into system + rescue mode. This is translated into + an activation request for + rescue.target and + is equivalent to systemctl + rescue. + + + + q + Q + + Reload daemon + configuration. This is equivalent to + systemctl + daemon-reload. + + + + u + U + + Serialize state, + reexecute daemon and deserialize state + again. This is equivalent to + systemctl + daemon-reexec. + + + + + + + Exit status + + On success 0 is returned, a non-zero failure + code otherwise. + + + + Notes + + This is a legacy command available for compatibility + only. It should not be used anymore, as the concept of + runlevels is obsolete. + + + + See Also + + systemd1, + systemctl1, + wall1 + + + + diff --git a/man/timedatectl.xml b/man/timedatectl.xml new file mode 100644 index 000000000..01ca0a73d --- /dev/null +++ b/man/timedatectl.xml @@ -0,0 +1,293 @@ + + + + + + + + + timedatectl + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + timedatectl + 1 + + + + timedatectl + Control the system time and date + + + + + timedatectl OPTIONS COMMAND + + + + + Description + + timedatectl may be used to + query and change the system clock and its + settings. + + + + Options + + The following options are understood: + + + + + + + Prints a short help + text and exits. + + + + + + Prints a short version + string and exits. + + + + + + Do not pipe output into a + pager. + + + + + + Don't query the user + for authentication for privileged + operations. + + + + + + + Execute the operation + remotely. Specify a hostname, or + username and hostname separated by @, + to connect to. This will use SSH to + talk to a remote + system. + + + + + + If + set-local-rtc is + invoked and this option is passed the + system clock is synchronized from the + RTC again, taking the new setting into + account. Otherwise the RTC is + synchronized from the system + clock. + + + + The following commands are understood: + + + + status + + Show current settings + of the system clock and + RTC. + + + + set-time [TIME] + + Set the system clock + to the specified time. This will also + update the RTC time accordingly. The time + may be specified in the format + "2012-10-30 + 18:17:16". + + + + set-timezone [TIMEZONE] + + Set the system time + zone to the specified value. Available + time zones can be listed with + list-timezones. If + the RTC is configured to be in the + local time this will also update the + RTC time. This call will alter the + /etc/localtime + symlink. See + localtime5 + for more + information. + + + + list-timezones + + List available time + zones, one per line. Entries from the + list can be set as the system + time zone with + set-timezone. + + + + set-local-rtc [BOOL] + + Takes a boolean + argument. If 0 the + system is configured to maintain the + RTC in universal time, if + 1 it will maintain + the RTC in local time instead. Note + that maintaining the RTC in the local + time zone is not fully supported and + will create various problems with time + zone changes and daylight saving + adjustments. If at all possible use + RTC in UTC. Note that invoking this + will also synchronize the RTC from the + system clock, unless + is + passed (see above). This command will + change the 3rd line of + /etc/adjtime, as + documented in + hwclock8. + + + + set-ntp [BOOL] + + Takes a boolean + argument. Controls whether NTP based + network time synchronization is + enabled (if + available). + + + + + + + + Exit status + + On success 0 is returned, a non-zero failure + code otherwise. + + + + Environment + + + + $SYSTEMD_PAGER + Pager to use when + is not given; + overrides $PAGER. Setting + this to an empty string or the value + cat is equivalent to passing + . + + + + + + Examples + Show current settings: + +$ timedatectl + Local time: Fri, 2012-11-02 09:26:46 CET + Universal time: Fri, 2012-11-02 08:26:46 UTC + RTC time: Fri, 2012-11-02 08:26:45 + Timezone: Europe/Warsaw + UTC offset: +0100 + NTP enabled: no +NTP synchronized: no + RTC in local TZ: no + DST active: no + Last DST change: CEST → CET, DST became inactive + Sun, 2012-10-28 02:59:59 CEST + Sun, 2012-10-28 02:00:00 CET + Next DST change: CET → CEST, DST will become active + the clock will jump one hour forward + Sun, 2013-03-31 01:59:59 CET + Sun, 2013-03-31 03:00:00 CEST + + + + Enable an NTP daemon (chronyd): + +$ timedatectl set-ntp true +==== AUTHENTICATING FOR org.freedesktop.timedate1.set-ntp === +Authentication is required to control whether network time synchronization shall be enabled. +Authenticating as: user +Password: ******** +==== AUTHENTICATION COMPLETE === + + + +$ systemctl status chronyd.service +chronyd.service - NTP client/server + Loaded: loaded (/usr/lib/systemd/system/chronyd.service; enabled) + Active: active (running) since Fri, 2012-11-02 09:36:25 CET; 5s ago +... + + + + + + See Also + + systemd1, + hwclock8, + date1, + localtime5, + systemctl1, + systemd-timedated.service8 + + + + diff --git a/man/tmpfiles.d.xml b/man/tmpfiles.d.xml new file mode 100644 index 000000000..785264e3c --- /dev/null +++ b/man/tmpfiles.d.xml @@ -0,0 +1,321 @@ + + + + + + + + tmpfiles.d + systemd + + + + Documentation + Brandon + Philips + brandon@ifup.org + + + + + + tmpfiles.d + 5 + + + + tmpfiles.d + Configuration for creation, deletion and + cleaning of volatile and temporary files + + + + /etc/tmpfiles.d/*.conf + /run/tmpfiles.d/*.conf + /usr/lib/tmpfiles.d/*.conf + + + + Description + + systemd-tmpfiles uses the + configuration files from the above directories to describe the + creation, cleaning and removal of volatile and + temporary files and directories which usually reside + in directories such as /run + or /tmp. + + + + Configuration Format + + Each configuration file shall be named in the + style of <program>.conf. + Files in /etc/ override files + with the same name in /usr/lib/ + and /run/. Files in + /run/ override files with the same + name in /usr/lib/. Packages + should install their configuration files in + /usr/lib/. Files in + /etc/ are reserved for the local + administrator, who may use this logic to override the + configuration files installed by vendor packages. All + configuration files are sorted by their filename in + alphabetical order, regardless in which of the + directories they reside, to guarantee that a specific + configuration file takes precedence over another file + with an alphabetically later name. + + If the administrator wants to disable a + configuration file supplied by the vendor the + recommended way is to place a symlink to + /dev/null in + /etc/tmpfiles.d/ bearing the + same file name. + + The configuration format is one line per path + containing action, path, mode, ownership, age and argument + fields: + + Type Path Mode UID GID Age Argument +d /run/user 0755 root root 10d - +L /tmp/foobar - - - - /dev/null + + + Type + + + f + Create a file if it doesn't exist yet (optionally writing a short string into it, if the argument parameter is passed) + + + + F + Create or truncate a file (optionally writing a short string into it, if the argument parameter is passed) + + + + w + Write the argument parameter to a file, if the file exists. + Lines of this type accept shell-style globs in place of normal path + names. The argument parameter will be written without a trailing + newline. C-style backslash escapes are interpreted. + + + + d + Create a directory if it doesn't exist yet + + + + D + Create or empty a directory + + + + p + Create a named pipe (FIFO) if it doesn't exist yet + + + + L + Create a symlink if it doesn't exist yet + + + + c + Create a character device node if it doesn't exist yet + + + + b + Create a block device node if it doesn't exist yet + + + + x + Ignore a path + during cleaning. Use this type + to exclude paths from clean-up + as controlled with the Age + parameter. Note that lines of + this type do not influence the + effect of r or R lines. Lines + of this type accept + shell-style globs in place of + normal path + names. + + + + r + Remove a file + or directory if it + exists. This may not be used + to remove non-empty + directories, use R for + that. Lines of this type + accept shell-style globs in + place of normal path + names. + + + + R + Recursively + remove a path and all its + subdirectories (if it is a + directory). Lines of this type + accept shell-style globs in + place of normal path + names. + + + + z + Restore + SELinux security context label + and set ownership and access + mode of a file or directory if + it exists. Lines of this type + accept shell-style globs in + place of normal path names. + + + + + Z + Recursively + restore SELinux security + context label and set + ownership and access mode of a + path and all its + subdirectories (if it is a + directory). Lines of this type + accept shell-style globs in + place of normal path + names. + + + + + + Mode + + The file access mode to use when + creating this file or directory. If omitted or + when set to - the default is used: 0755 for + directories, 0644 for all other file + objects. For z, Z lines if omitted or when set + to - the file access mode will not be + modified. This parameter is ignored for x, r, + R, L lines. + + + + UID, GID + + The user and group to use for this file + or directory. This may either be a numeric + user/group ID or a user or group name. If + omitted or when set to - the default 0 (root) + is used. For z, Z lines when omitted or when set to - + the file ownership will not be modified. + These parameters are ignored for x, r, R, L lines. + + + + Age + The date field, when set, is used to + decide what files to delete when cleaning. If + a file or directory is older than the current + time minus the age field it is deleted. The + field format is a series of integers each + followed by one of the following + postfixes for the respective time units: + + + + s + min + h + d + w + ms + m + us + + + If multiple integers and units are specified the time + values are summed up. If an integer is given without a unit, + s is assumed. + + + When the age is set to zero, the files are cleaned + unconditionally. + + The age field only applies to lines starting with + d, D and x. If omitted or set to - no automatic clean-up + is done. + + If the age field starts with a tilde + character (~) the clean-up is only applied to + files and directories one level inside the + directory specified, but not the files and + directories immediately inside it. + + + + Argument + + For L lines determines the destination + path of the symlink. For c, b determines the + major/minor of the device node, with major and + minor formatted as integers, separated by :, + e.g. "1:3". For f, F, w may be used to specify + a short string that is written to the file, + suffixed by a newline. Ignored for all other + lines. + + + + + + Example + + /etc/tmpfiles.d/screen.conf example + screen needs two directories created at boot with specific modes and ownership. + + d /var/run/screens 1777 root root 10d +d /var/run/uscreens 0755 root root 10d12h + + + + + See Also + + systemd1, + systemd-tmpfiles8, + systemd-delta1 + + + + diff --git a/man/udev.xml b/man/udev.xml new file mode 100644 index 000000000..7ec7a3fed --- /dev/null +++ b/man/udev.xml @@ -0,0 +1,705 @@ + + + + + + + udev + systemd + + + Developer + Greg + Kroah-Hartmann + greg@kroah.com + + + Developer + Kay + Sievers + kay@vrfy.org + + + + + + udev + 7 + + + + udev + Linux dynamic device management + + + Description + udev supplies the system software with device events, manages permissions + of device nodes and may create additional symlinks in the /dev + directory, or renames network interfaces. The kernel usually just assigns unpredictable + device names based on the order of discovery. Meaningful symlinks or network device + names provide a way to reliably identify devices based on their properties or + current configuration. + + The udev daemon, systemd-udevd.service + 8, receives device uevents directly from + the kernel whenever a device is added or removed from the system, or it changes its + state. When udev receives a device event, it matches its configured set of rules + against various device attributes to identify the device. Rules that match may + provide additional device information to be stored in the udev database or + to be used to create meaningful symlink names. + + All device information udev processes is stored in the udev database and + sent out to possible event subscribers. Access to all stored data and the event + sources is provided by the library libudev. + + + Configuration + udev configuration files are placed in /etc/udev + and /usr/lib/udev. All empty lines or lines beginning with + '#' are ignored. + + Configuration file + udev expects its main configuration file at /etc/udev/udev.conf. + It consists of a set of variables allowing the user to override default udev values. + The following variables can be set: + + + + + The logging priority. Valid values are the numerical syslog priorities + or their textual representations: , + and . + + + + + + Rules files + The udev rules are read from the files located in the + system rules directory /usr/lib/udev/rules.d, + the volatile runtime directory /run/udev/rules.d + and the local administration directory /etc/udev/rules.d. + All rules files are collectively sorted and processed in lexical order, + regardless of the directories in which they live. However, files with + identical file names replace each other. Files in /etc + have the highest priority, files in /run take precedence + over files with the same name in /lib. This can be + used to override a system-supplied rules file with a local file if needed; + a symlink in /etc with the same name as a rules file in + /lib, pointing to /dev/null, + disables the rules file entirely. + + Rule files must have the extension .rules; other + extensions are ignored. + + Every line in the rules file contains at least one key-value pair. + There are two kinds of keys: match and assignment. + If all match keys are matching against its value, the rule gets applied and the + assignment keys get the specified value assigned. + + A matching rule may rename a network interface, add symlinks + pointing to the device node, or run a specified program as part of + the event handling. + + A rule consists of a comma-separated list of one or more key-value pairs. + Each key has a distinct operation, depending on the used operator. Valid + operators are: + + + + + Compare for equality. + + + + + + + Compare for inequality. + + + + + + + Assign a value to a key. Keys that represent a list are reset + and only this single value is assigned. + + + + + + + Add the value to a key that holds a list of entries. + + + + + + + Assign a value to a key finally; disallow any later changes. + + + + + The following key names can be used to match against device properties. + Some of the keys also match against properties of the parent devices in sysfs, + not only the device that has generated the event. If multiple keys that match + a parent device are specified in a single rule, all these keys must match at + one and the same parent device. + + + + + Match the name of the event action. + + + + + + + Match the devpath of the event device. + + + + + + + Match the name of the event device. + + + + + + + Match the name of a network interface. It can be used once the + NAME key has been set in one of the preceding rules. + + + + + + + Match the name of a symlink targeting the node. It can + be used once a SYMLINK key has been set in one of the preceding + rules. There may be multiple symlinks; only one needs to match. + + + + + + + + Match the subsystem of the event device. + + + + + + Match the driver name of the event device. Only set this key for devices + which are bound to a driver at the time the event is generated. + + + + + + Match sysfs attribute values of the event device. Trailing + whitespace in the attribute values is ignored unless the specified match + value itself contains trailing whitespace. + + + + + + + + Search the devpath upwards for a matching device name. + + + + + + + Search the devpath upwards for a matching device subsystem name. + + + + + + + Search the devpath upwards for a matching device driver name. + + + + + + + Search the devpath upwards for a device with matching sysfs attribute values. + If multiple matches are specified, all of them + must match on the same device. Trailing whitespace in the attribute values is ignored + unless the specified match value itself contains trailing whitespace. + + + + + + + Search the devpath upwards for a device with matching tag. + + + + + + + Match against a device property value. + + + + + + + Match against a device tag. + + + + + + + Test the existence of a file. An octal mode mask can be specified + if needed. + + + + + + + Execute a program to determine whether there + is a match; the key is true if the program returns + successfully. The device properties are made available to the + executed program in the environment. The program's stdout + is available in the RESULT key. + This can only be used for very short-running foreground tasks. For details + see . + + + + + + + Match the returned string of the last PROGRAM call. This key can + be used in the same or in any later rule after a PROGRAM call. + + + + + Most of the fields support shell-style pattern matching. The following + pattern characters are supported: + + + + + Matches zero or more characters. + + + + + + Matches any single character. + + + + + + Matches any single character specified within the brackets. For + example, the pattern string 'tty[SR]' would match either 'ttyS' or 'ttyR'. + Ranges are also supported via the '-' character. + For example, to match on the range of all digits, the pattern [0-9] could + be used. If the first character following the '[' is a '!', any characters + not enclosed are matched. + + + + + The following keys can get values assigned: + + + + + The name to use for a network interface. The name of a device node + cannot be changed by udev, only additional symlinks can be created. + + + + + + + The name of a symlink targeting the node. Every matching rule adds + this value to the list of symlinks to be created. + The set of characters to name a symlink is limited. Allowed + characters are [0-9A-Za-z#+-.:=@_/], valid utf8 character sequences, + and "\x00" hex encoding. All other characters are replaced by + a '_' character. + Multiple symlinks may be specified by separating the names by the + space character. In case multiple devices claim the same name, the link + always points to the device with the highest link_priority. If the current + device goes away, the links are re-evaluated and the device with the + next highest link_priority becomes the owner of the link. If no + link_priority is specified, the order of the devices (and which one of + them owns the link) is undefined. + Symlink names must never conflict with the kernel's default device + node names, as that would result in unpredictable behavior. + + + + + + + + The permissions for the device node. Every specified value overrides + the compiled-in default value. + + + + + + + The value that should be written to a sysfs attribute of the + event device. + + + + + + + Set a device property value. Property names with a leading '.' + are neither stored in the database nor exported to events or + external tools (run by, say, the PROGRAM match key). + + + + + + + Attach a tag to a device. This is used to filter events for users + of libudev's monitor functionality, or to enumerate a group of tagged + devices. The implementation can only work efficiently if only a few + tags are attached to a device. It is only meant to be used in + contexts with specific device filter requirements, and not as a + general-purpose flag. Excessive use might result in inefficient event + handling. + + + + + + + Add a program to the list of programs to be executed for a specific + device. + If no absolute path is given, the program is expected to live in + /usr/lib/udev, otherwise the absolute path must be specified. The program + name and following arguments are separated by spaces. Single quotes can + be used to specify arguments with spaces. + This can only be used for very short-running foreground tasks. Running an + event process for a long period of time may block all further events for + this or a dependent device. + 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. + + + + + + + A named label to which a GOTO may jump. + + + + + + + Jumps to the next LABEL with a matching name. + + + + + + + Import a set of variables as device properties, + depending on type: + + + + + Execute an external program specified as the assigned value and + import its output, which must be in environment key + format. Path specification, command/argument separation, + and quoting work like in . + + + + + + Import a text file specified as the assigned value, the content + of which must be in environment key format. + + + + + + Import a single property specified as the assigned value from the + current device database. This works only if the database is already populated + by an earlier event. + + + + + + Import a single property from the kernel command line. For simple flags + the value of the property is set to '1'. + + + + + + Import the stored keys from the parent device by reading + the database entry of the parent device. The value assigned to + is used as a filter of key names + to import (with the same shell-style pattern matching used for + comparisons). + + + + This can only be used for very short-running foreground tasks. For details + see . + + + + + + + Wait for a file to become available or until a timeout of + 10 seconds expires. The path is relative to the sysfs device; + if no path is specified, this waits for an attribute to appear. + + + + + + + Rule and device options: + + + + + Specify the priority of the created symlinks. Devices with higher + priorities overwrite existing symlinks of other devices. The default is 0. + + + + + + Number of seconds an event waits for operations to finish before + giving up and terminating itself. + + + + + + Usually control and other possibly unsafe characters are replaced + in strings used for device naming. The mode of replacement can be specified + with this option. + + + + + + Apply the permissions specified in this rule to the static device node with + the specified name. Static device node creation can be requested by kernel modules. + These nodes might not have a corresponding kernel device at the time systemd-udevd is + started; they can trigger automatic kernel module loading. + + + + + + Watch the device node with inotify; when the node is closed after being opened for + writing, a change uevent is synthesized. + + + + + + Disable the watching of a device node with inotify. + + + + + + + + The , , , + , , and + fields support simple string substitutions. The + substitutions are performed after all rules have been processed, right before the program + is executed, allowing for the use of device properties set by earlier matching + rules. For all other fields, substitutions are performed while the individual rule is + being processed. The available substitutions are: + + + , + + The kernel name for this device. + + + + + , + + The kernel number for this device. For example, 'sda3' has + kernel number of '3' + + + + + , + + The devpath of the device. + + + + + , + + The name of the device matched while searching the devpath upwards for + , , and . + + + + + + + + The driver name of the device matched while searching the devpath upwards for + , , and . + + + + + + , + + The value of a sysfs attribute found at the device where + all keys of the rule have matched. If the matching device does not have + such an attribute, and a previous KERNELS, SUBSYSTEMS, DRIVERS, or + ATTRS test selected a parent device, then the attribute from that + parent device is used. + If the attribute is a symlink, the last element of the symlink target is + returned as the value. + + + + + , + + A device property value. + + + + + , + + The kernel major number for the device. + + + + + , + + The kernel minor number for the device. + + + + + , + + The string returned by the external program requested with PROGRAM. + A single part of the string, separated by a space character, may be selected + by specifying the part number as an attribute: . + If the number is followed by the '+' character, this part plus all remaining parts + of the result string are substituted: + + + + + , + + The node name of the parent device. + + + + + + + The current name of the device. If not changed by a rule, it is the + name of the kernel device. + + + + + + + A space-separated list of the current symlinks. The value is + only set during a remove event or if an earlier rule assigned a value. + + + + + , + + The udev_root value. + + + + + , + + The sysfs mount point. + + + + + , + + The name of the device node. + + + + + + + The '%' character itself. + + + + + + + The '$' character itself. + + + + + + + + See Also + + systemd-udevd.service8 + , + + udevadm8 + + + diff --git a/man/udevadm.xml b/man/udevadm.xml new file mode 100644 index 000000000..779102822 --- /dev/null +++ b/man/udevadm.xml @@ -0,0 +1,495 @@ + + + + + + + udevadm + systemd + + + Developer + Kay + Sievers + kay@vrfy.org + + + + + + udevadm + 8 + + + + + udevadmudev management tool + + + + + udevadm + + + + + + udevadm info options + + + udevadm trigger options + + + udevadm settle options + + + udevadm control command + + + udevadm monitor options + + + udevadm hwdb options + + + udevadm test options devpath + + + udevadm test-builtin options command devpath + + + + Description + udevadm expects a command and command specific options. It + controls the runtime behavior of udev, requests kernel events, + manages the event queue, and provides simple debugging mechanisms. + + + OPTIONS + + + + + Print debug messages to stderr. + + + + + + Print version number. + + + + + + Print help text. + + + + + udevadm info <replaceable>options</replaceable> + Queries the udev database for device information + stored in the udev database. It can also query the properties + of a device from its sysfs representation to help creating udev + rules that match this device. + + + + + Query the database for specified type of device data. It needs the + or to identify the specified + device. Valid queries are: + name, symlink, path, + property, all. + + + + + + The devpath of the device to query. + + + + + + The name of the device node or a symlink to query + + + + + + Print absolute paths in name or symlink + query. + + + + + + Print all sysfs properties of the specified device that can be used + in udev rules to match the specified device. It prints all devices + along the chain, up to the root of sysfs that can be used in udev rules. + + + + + + Print output as key/value pairs. Values are enclosed in single quotes. + + + + + + Add a prefix to the key name of exported values. + + + + + + Print major/minor numbers of the underlying device, where the file + lives on. + + + + + + Export the content of the udev database. + + + + + + Cleanup the udev database. + + + + + + Print version. + + + + + + Print help text. + + + + + + udevadm trigger <optional>options</optional> + Request device events from the kernel. Primarily used to replay events at system coldplug time. + + + + + Print the list of devices which will be triggered. + + + + + + Do not actually trigger the event. + + + + + + Trigger a specific type of devices. Valid types are: + devices, subsystems. + The default value is devices. + + + + + + Type of event to be triggered. The default value is change. + + + + + + Trigger events for devices which belong to a matching subsystem. This option + can be specified multiple times and supports shell style pattern matching. + + + + + + Do not trigger events for devices which belong to a matching subsystem. This option + can be specified multiple times and supports shell style pattern matching. + + + + + + Trigger events for devices with a matching sysfs attribute. If a value is specified + along with the attribute name, the content of the attribute is matched against the given + value using shell style pattern matching. If no value is specified, the existence of the + sysfs attribute is checked. This option can be specified multiple times. + + + + + + Do not trigger events for devices with a matching sysfs attribute. If a value is + specified along with the attribute name, the content of the attribute is matched against + the given value using shell style pattern matching. If no value is specified, the existence + of the sysfs attribute is checked. This option can be specified multiple times. + + + + + + Trigger events for devices with a matching property value. This option can be + specified multiple times and supports shell style pattern matching. + + + + + + Trigger events for devices with a matching tag. This option can be + specified multiple times. + + + + + + Trigger events for devices with a matching sys device name. This option can be + specified multiple times and supports shell style pattern matching. + + + + + + Trigger events for all children of a given device. + + + + + + udevadm settle <optional>options</optional> + Watches the udev event queue, and exits if all current events are handled. + + + + + Maximum number of seconds to wait for the event queue to become empty. + The default value is 120 seconds. A value of 0 will check if the queue is empty + and always return immediately. + + + + + + Wait only for events after the given sequence number. + + + + + + Wait only for events before the given sequence number. + + + + + + Stop waiting if file exists. + + + + + + Do not print any output, like the remaining queue entries when reaching the timeout. + + + + + + Print help text. + + + + + + udevadm control <replaceable>command</replaceable> + Modify the internal state of the running udev daemon. + + + + + Signal and wait for systemd-udevd to exit. + + + + + + Set the internal log level of systemd-udevd. Valid values are the numerical + syslog priorities or their textual representations: , + and . + + + + + + Signal systemd-udevd to stop executing new events. Incoming events + will be queued. + + + + + + Signal systemd-udevd to enable the execution of events. + + + + + + Signal systemd-udevd to reload the rules files and other databases like the kernel + module index. Reloading rules and databases does not apply any changes to already + existing devices; the new configuration will only be applied to new events. + + + + + + Set a global property for all events. + + + + value + + Set the maximum number of events, systemd-udevd will handle at the + same time. + + + + seconds + + The maximum number of seconds to wait for a reply from systemd-udevd. + + + + + + Print help text. + + + + + + udevadm monitor <optional>options</optional> + Listens to the kernel uevents and events sent out by a udev rule + and prints the devpath of the event to the console. It can be used to analyze the + event timing, by comparing the timestamps of the kernel uevent and the udev event. + + + + + + Print the kernel uevents. + + + + + + Print the udev event after the rule processing. + + + + + + Also print the properties of the event. + + + + + + Filter events by subsystem[/devtype]. Only udev events with a matching subsystem value will pass. + + + + + + Filter events by property. Only udev events with a given tag attached will pass. + + + + + + Print help text. + + + + + + udevadm hwdb <optional>options</optional> + Maintain the hardware database index in /etc/udev/hwdb.bin. + + + + + Compile the hardware database information located in /usr/lib/udev/hwdb.d/, + /etc/udev/hwdb.d/ and store it in /etc/udev/hwdb.bin. This should be done after + any update to the source files; it will not be called automatically. The running + udev daemon will detect a new database on its own and does not need to be + notified about it. + + + + + + Query the database with a modalias string, and print the + retrieved properties. + + + + + + udevadm test <optional>options</optional> <replaceable>devpath</replaceable> + Simulate a udev event run for the given device, and print debug output. + + + + + The action string. + + + + + + The subsystem string. + + + + + + Print help text. + + + + + + udevadm test-builtin <optional>options</optional> <replaceable>command</replaceable> <replaceable>devpath</replaceable> + Run a built-in command for the given device, and print debug output. + + + + + Print help text. + + + + + + + + See Also + + udev7 + + + systemd-udevd.service8 + + + diff --git a/man/vconsole.conf.xml b/man/vconsole.conf.xml new file mode 100644 index 000000000..45156b744 --- /dev/null +++ b/man/vconsole.conf.xml @@ -0,0 +1,147 @@ + + + + + + + + + vconsole.conf + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + vconsole.conf + 5 + + + + vconsole.conf + Configuration file for the virtual console + + + + /etc/vconsole.conf + + + + Description + + The /etc/vconsole.conf file + configures the virtual console, i.e. keyboard mapping + and console font. It is applied at boot by + systemd-vconsole-setup.service8. + + The basic file format of the + vconsole.conf is a + newline-separated list of environment-like + shell-compatible variable assignments. It is possible + to source the configuration from shell scripts, + however, beyond mere variable assignments no shell + features are supported, allowing applications to read + the file without implementing a shell compatible + execution engine. + + Note that the kernel command line options + vconsole.keymap=, + vconsole.keymap.toggle=, + vconsole.font=, + vconsole.font.map=, + vconsole.font.unimap= may be used + to override the console settings at boot. + + Depending on the operating system other + configuration files might be checked for configuration + of the virtual console as well, however only as + fallback. + + + + Options + + The following options are understood: + + + + + KEYMAP= + KEYMAP_TOGGLE= + + Configures the key + mapping table for the + keyboard. KEYMAP= + defaults to us if + not set. The + KEYMAP_TOGGLE= can + be used to configure a second toggle + keymap and is by default + unset. + + + + FONT= + FONT_MAP= + FONT_UNIMAP= + + Configures the console + font, the console map and the unicode + font map. + + + + + + + Example + + + German keyboard and console + + /etc/vconsole.conf: + + KEYMAP=de-latin1 +FONT=latarcyrheb-sun16 + + + + + + See Also + + systemd1, + systemd-vconsole-setup.service8, + loadkeys1, + setfont8, + locale.conf5, + systemd-localed.service8 + + + + diff --git a/po/.gitignore b/po/.gitignore new file mode 100644 index 000000000..1fa8d3fd5 --- /dev/null +++ b/po/.gitignore @@ -0,0 +1,5 @@ +POTFILES +Makefile.in.in +.intltool-merge-cache +Makefile +systemd.pot diff --git a/po/POTFILES.in b/po/POTFILES.in new file mode 100644 index 000000000..2829c87f1 --- /dev/null +++ b/po/POTFILES.in @@ -0,0 +1,5 @@ +src/hostname/org.freedesktop.hostname1.policy.in +src/locale/org.freedesktop.locale1.policy.in +src/login/org.freedesktop.login1.policy.in +src/timedate/org.freedesktop.timedate1.policy.in +src/core/org.freedesktop.systemd1.policy.in.in diff --git a/po/POTFILES.skip b/po/POTFILES.skip new file mode 100644 index 000000000..0502c1302 --- /dev/null +++ b/po/POTFILES.skip @@ -0,0 +1,20 @@ +src/core/dbus-automount.c +src/core/dbus-device.c +src/core/dbus-job.c +src/core/dbus-manager.c +src/core/dbus-mount.c +src/core/dbus-path.c +src/core/dbus-service.c +src/core/dbus-snapshot.c +src/core/dbus-socket.c +src/core/dbus-swap.c +src/core/dbus-target.c +src/core/dbus-timer.c +src/core/dbus-unit.c +src/hostname/hostnamed.c +src/locale/localed.c +src/core/org.freedesktop.systemd1.policy.in +src/timedate/timedated.c +units/systemd-readahead-done.service.in +units/user@.service.in +units/debug-shell.service.in diff --git a/po/pl.po b/po/pl.po new file mode 100644 index 000000000..2581d01fc --- /dev/null +++ b/po/pl.po @@ -0,0 +1,175 @@ +# translation of pl.po to Polish +# Piotr Drąg , 2011. +# Zbigniew Jędrzejewski-Szmek , 2011. +# +msgid "" +msgstr "" +"Project-Id-Version: systemd\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2011-10-14 16:18+0200\n" +"PO-Revision-Date: 2011-10-14 16:20+0200\n" +"Last-Translator: Piotr Drąg \n" +"Language-Team: Polish \n" +"Language: pl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../src/org.freedesktop.hostname1.policy.in.h:1 +msgid "Authentication is required to set local machine information." +msgstr "" +"Wymagane jest uwierzytelnienie, aby ustawić informacje o lokalnym komputerze." + +#: ../src/org.freedesktop.hostname1.policy.in.h:2 +msgid "Authentication is required to set the local host name." +msgstr "Wymagane jest uwierzytelnienie, aby ustawić nazwę lokalnego komputera." + +#: ../src/org.freedesktop.hostname1.policy.in.h:3 +msgid "" +"Authentication is required to set the statically configured local host name, " +"as well as the pretty host name." +msgstr "" +"Wymagane jest uwierzytelnienie, aby ustawić statycznie skonfigurowaną nazwę " +"lokalnego komputera, a także jego ładną nazwę." + +#: ../src/org.freedesktop.hostname1.policy.in.h:4 +msgid "Set host name" +msgstr "Ustawienie nazwy komputera" + +#: ../src/org.freedesktop.hostname1.policy.in.h:5 +msgid "Set machine information" +msgstr "Ustawienie informacji o komputerze" + +#: ../src/org.freedesktop.hostname1.policy.in.h:6 +msgid "Set static host name" +msgstr "Ustawienie statycznej nazwy komputera" + +#: ../src/org.freedesktop.locale1.policy.in.h:1 +msgid "Authentication is required to set the system keyboard settings." +msgstr "Wymagane jest uwierzytelnienie, aby ustawić klawiaturę systemu." + +#: ../src/org.freedesktop.locale1.policy.in.h:2 +msgid "Authentication is required to set the system locale." +msgstr "Wymagane jest uwierzytelnienie, aby ustawić lokalizację systemu." + +#: ../src/org.freedesktop.locale1.policy.in.h:3 +msgid "Set system keyboard settings" +msgstr "Ustawienie klawiatury systemu" + +#: ../src/org.freedesktop.locale1.policy.in.h:4 +msgid "Set system locale" +msgstr "Ustawienie lokalizacji systemu" + +#: ../src/org.freedesktop.login1.policy.in.h:1 +msgid "Allow attaching devices to seats" +msgstr "Zezwolenie na podłączanie urządzeń do stanowisk" + +#: ../src/org.freedesktop.login1.policy.in.h:2 +msgid "Allow non-logged-in users to run programs" +msgstr "Zezwolenie niezalogowanym użytkownikom na uruchamianie programów" + +#: ../src/org.freedesktop.login1.policy.in.h:3 +msgid "" +"Authentication is required to allow a non-logged-in user to run programs" +msgstr "" +"Wymagane jest uwierzytelnienie, aby ustawić zezwolić niezalogowanym " +"użytkownikom na uruchamianie programów" + +#: ../src/org.freedesktop.login1.policy.in.h:4 +msgid "Authentication is required to allow attaching a device to a seat" +msgstr "" +"Wymagane jest uwierzytelnienie, aby zezwolić na podłączenie urządzenia do " +"stanowiska" + +#: ../src/org.freedesktop.login1.policy.in.h:5 +msgid "Authentication is required to allow powering off the system" +msgstr "Wymagane jest uwierzytelnienie, aby zezwolić na wyłączanie systemu" + +#: ../src/org.freedesktop.login1.policy.in.h:6 +msgid "" +"Authentication is required to allow powering off the system while other " +"users are logged in" +msgstr "" +"Wymagane jest uwierzytelnienie, aby zezwolić na wyłączanie systemu, kiedy są " +"zalogowani inni użytkownicy" + +#: ../src/org.freedesktop.login1.policy.in.h:7 +msgid "Authentication is required to allow rebooting the system" +msgstr "" +"Wymagane jest uwierzytelnienie, aby zezwolić na ponowne uruchamianie systemu" + +#: ../src/org.freedesktop.login1.policy.in.h:8 +msgid "" +"Authentication is required to allow rebooting the system while other users " +"are logged in" +msgstr "" +"Wymagane jest uwierzytelnienie, aby zezwolić na ponowne uruchamianie " +"systemu, kiedy są zalogowani inni użytkownicy" + +#: ../src/org.freedesktop.login1.policy.in.h:9 +msgid "" +"Authentication is required to allow resetting how devices are attached to " +"seats" +msgstr "" +"Wymagane jest uwierzytelnienie, aby zezwolić na ponowne ustawianie sposobu " +"podłączenia urządzeń do stanowisk" + +#: ../src/org.freedesktop.login1.policy.in.h:10 +msgid "Flush device to seat attachments" +msgstr "Usunięcie podłączenia urządzeń do stanowisk" + +#: ../src/org.freedesktop.login1.policy.in.h:11 +msgid "Power off the system" +msgstr "Wyłączenie systemu" + +#: ../src/org.freedesktop.login1.policy.in.h:12 +msgid "Power off the system when other users are logged in" +msgstr "Wyłączenie systemu, kiedy są zalogowani inni użytkownicy" + +#: ../src/org.freedesktop.login1.policy.in.h:13 +msgid "Reboot the system" +msgstr "Ponowne uruchomienie systemu" + +#: ../src/org.freedesktop.login1.policy.in.h:14 +msgid "Reboot the system when other users are logged in" +msgstr "Ponowne uruchomienie systemu, kiedy są zalogowani inni użytkownicy" + +#: ../src/org.freedesktop.timedate1.policy.in.h:1 +msgid "" +"Authentication is required to control whether network time synchronization " +"shall be enabled." +msgstr "" +"Wymagane jest uwierzytelnienie, aby kontrolować, czy włączyć synchronizację " +"czasu przez sieć." + +#: ../src/org.freedesktop.timedate1.policy.in.h:2 +msgid "" +"Authentication is required to control whether the RTC stores the local or " +"UTC time." +msgstr "" +"Wymagane jest uwierzytelnienie, aby kontrolować, czy RTC przechowuje czas " +"lokalny lub czas UTC." + +#: ../src/org.freedesktop.timedate1.policy.in.h:3 +msgid "Authentication is required to set the system time." +msgstr "Wymagane jest uwierzytelnienie, aby ustawić czas systemu." + +#: ../src/org.freedesktop.timedate1.policy.in.h:4 +msgid "Authentication is required to set the system timezone." +msgstr "Wymagane jest uwierzytelnienie, aby ustawić strefę czasową systemu." + +#: ../src/org.freedesktop.timedate1.policy.in.h:5 +msgid "Set RTC to local timezone or UTC" +msgstr "Ustawienie RTC na lokalną strefę czasową lub strefę UTC" + +#: ../src/org.freedesktop.timedate1.policy.in.h:6 +msgid "Set system time" +msgstr "Ustawienie czasu systemu" + +#: ../src/org.freedesktop.timedate1.policy.in.h:7 +msgid "Set system timezone" +msgstr "Ustawienie strefy czasowej systemu" + +#: ../src/org.freedesktop.timedate1.policy.in.h:8 +msgid "Turn network time synchronization on or off" +msgstr "Włączenie lub wyłączenie synchronizacji czasu przez sieć" diff --git a/rules/.gitignore b/rules/.gitignore new file mode 100644 index 000000000..93a50ddd8 --- /dev/null +++ b/rules/.gitignore @@ -0,0 +1 @@ +/99-systemd.rules diff --git a/rules/42-usb-hid-pm.rules b/rules/42-usb-hid-pm.rules new file mode 100644 index 000000000..2b56b1134 --- /dev/null +++ b/rules/42-usb-hid-pm.rules @@ -0,0 +1,39 @@ +# do not edit this file, it will be overwritten on update +# +# Enable autosuspend for qemu emulated usb hid devices + +# Note that there are buggy qemu versions which advertise remote +# wakeup support but don't actually implement it correctly. This +# is the reason why we need a match for the serial number here. +# The serial number "42" is used to tag the implementations where +# remote wakeup is working. +ACTION=="add", SUBSYSTEM=="usb", ATTR{product}=="QEMU USB Mouse", ATTR{serial}=="42", TEST=="power/control", ATTR{power/control}="auto" +ACTION=="add", SUBSYSTEM=="usb", ATTR{product}=="QEMU USB Tablet", ATTR{serial}=="42", TEST=="power/control", ATTR{power/control}="auto" +ACTION=="add", SUBSYSTEM=="usb", ATTR{product}=="QEMU USB Keyboard", ATTR{serial}=="42", TEST=="power/control", ATTR{power/control}="auto" + +# Catch-all for Avocent HID devices. Keyed off interface in order to only +# trigger on HID class devices. +ACTION=="add", SUBSYSTEM=="usb", ATTRS{idVendor}=="0624", ATTR{bInterfaceClass}=="03", TEST=="../power/control", ATTR{../power/control}="auto" + +# Dell DRAC 4 +ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="413c", ATTR{idProduct}=="2500", TEST=="power/control", ATTR{power/control}="auto" + +# Dell DRAC 5 +ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="413c", ATTR{idProduct}=="0000", TEST=="power/control", ATTR{power/control}="auto" + +# IBM remote access +ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="04b3", ATTR{idProduct}=="4001", TEST=="power/control", ATTR{power/control}="auto" +ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="04b3", ATTR{idProduct}=="4002", TEST=="power/control", ATTR{power/control}="auto" +ACTION=="add", SUBSYSTEM=="usb", ATTRS{idVendor}=="04b3", ATTR{idProduct}=="4012", TEST=="power/control", ATTR{power/control}="auto" + +# Raritan Computer, Inc KVM. +ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="14dd", ATTR{idProduct}=="0002", TEST=="power/control", ATTR{power/control}="auto" + +# USB HID devices that are internal to the machine should also be safe to autosuspend + +ACTION=="add", SUBSYSTEM=="usb", SUBSYSTEMS=="usb", ATTRS{removable}=="removable", GOTO="usb_hid_pm_end" +ACTION=="add", SUBSYSTEM=="usb", SUBSYSTEMS=="usb", ATTRS{removable}=="unknown", GOTO="usb_hid_pm_end" + +ACTION=="add", SUBSYSTEM=="usb", ATTR{bInterfaceClass}=="03", ATTRS{removable}=="fixed", TEST=="../power/control", ATTR{../power/control}="auto" + +LABEL="usb_hid_pm_end" diff --git a/rules/50-udev-default.rules b/rules/50-udev-default.rules new file mode 100644 index 000000000..fc52fd17f --- /dev/null +++ b/rules/50-udev-default.rules @@ -0,0 +1,90 @@ +# do not edit this file, it will be overwritten on update + +SUBSYSTEM=="tty", KERNEL=="ptmx", GROUP="tty", MODE="0666" +SUBSYSTEM=="tty", KERNEL=="tty", GROUP="tty", MODE="0666" +SUBSYSTEM=="tty", KERNEL=="tty[0-9]*", GROUP="tty", MODE="0620" +SUBSYSTEM=="vc", KERNEL=="vcs*|vcsa*", GROUP="tty" + +# serial +KERNEL=="tty[A-Z]*[0-9]|pppox[0-9]*|ircomm[0-9]*|noz[0-9]*|rfcomm[0-9]*", GROUP="dialout" + +# virtio serial / console ports +SUBSYSTEM=="virtio-ports", KERNEL=="vport*", ATTR{name}=="?*", SYMLINK+="virtio-ports/$attr{name}" + +# mem +SUBSYSTEM=="mem", KERNEL=="mem|kmem|port", GROUP="kmem", MODE="0640" + +# input +SUBSYSTEM=="input", ENV{ID_INPUT}=="", IMPORT{builtin}="input_id" +SUBSYSTEM=="input", KERNEL=="mouse*|mice|event*", MODE="0640" +SUBSYSTEM=="input", KERNEL=="ts[0-9]*|uinput", MODE="0640" +SUBSYSTEM=="input", KERNEL=="js[0-9]*", MODE="0644" + +# video4linux +SUBSYSTEM=="video4linux", GROUP="video" + +# graphics +SUBSYSTEM=="misc", KERNEL=="agpgart", GROUP="video" +SUBSYSTEM=="graphics", GROUP="video" +SUBSYSTEM=="drm", GROUP="video" + +# sound +SUBSYSTEM=="sound", GROUP="audio", \ + OPTIONS+="static_node=snd/seq", OPTIONS+="static_node=snd/timer" + +# DVB (video) +SUBSYSTEM=="dvb", GROUP="video" + +# FireWire (firewire-core driver: IIDC devices, AV/C devices) +SUBSYSTEM=="firewire", ATTR{units}=="*0x00a02d:0x00010*", GROUP="video" +SUBSYSTEM=="firewire", ATTR{units}=="*0x00b09d:0x00010*", GROUP="video" +SUBSYSTEM=="firewire", ATTR{units}=="*0x00a02d:0x010001*", GROUP="video" +SUBSYSTEM=="firewire", ATTR{units}=="*0x00a02d:0x014001*", GROUP="video" + +# 'libusb' device nodes +SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", MODE="0664" +SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", IMPORT{builtin}="usb_id", IMPORT{builtin}="hwdb --subsystem=usb" + +# printer +KERNEL=="parport[0-9]*", GROUP="lp" +SUBSYSTEM=="printer", KERNEL=="lp*", GROUP="lp" +SUBSYSTEM=="ppdev", GROUP="lp" +KERNEL=="lp[0-9]*", GROUP="lp" +KERNEL=="irlpt[0-9]*", GROUP="lp" +SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ENV{ID_USB_INTERFACES}=="*:0701??:*", GROUP="lp" + +# block +SUBSYSTEM=="block", GROUP="disk" + +# floppy +SUBSYSTEM=="block", KERNEL=="fd[0-9]", GROUP="floppy" + +# cdrom +SUBSYSTEM=="block", KERNEL=="sr[0-9]*", GROUP="cdrom" +SUBSYSTEM=="scsi_generic", SUBSYSTEMS=="scsi", ATTRS{type}=="4|5", GROUP="cdrom" +KERNEL=="sch[0-9]*", GROUP="cdrom" +KERNEL=="pktcdvd[0-9]*", GROUP="cdrom" +KERNEL=="pktcdvd", GROUP="cdrom" + +# tape +SUBSYSTEM=="scsi_generic|scsi_tape", SUBSYSTEMS=="scsi", ATTRS{type}=="1|8", GROUP="tape" + +# block-related +SUBSYSTEM=="scsi_generic", SUBSYSTEMS=="scsi", ATTRS{type}=="0", GROUP="disk" +KERNEL=="qft[0-9]*|nqft[0-9]*|zqft[0-9]*|nzqft[0-9]*|rawqft[0-9]*|nrawqft[0-9]*", GROUP="disk" +KERNEL=="rawctl", GROUP="disk" +SUBSYSTEM=="raw", KERNEL=="raw[0-9]*", GROUP="disk" +SUBSYSTEM=="aoe", GROUP="disk", MODE="0220" +SUBSYSTEM=="aoe", KERNEL=="err", MODE="0440" + +# network +KERNEL=="tun", MODE="0666", OPTIONS+="static_node=net/tun" +KERNEL=="rfkill", MODE="0644" + +KERNEL=="fuse", ACTION=="add", MODE="0666", OPTIONS+="static_node=fuse" + +SUBSYSTEM=="rtc", ATTR{hctosys}=="1", MODE="0644", SYMLINK+="rtc" + +SUBSYSTEM=="firmware", ACTION=="add", IMPORT{builtin}="firmware" + +ENV{MODALIAS}!="", IMPORT{builtin}="hwdb --subsystem=$env{SUBSYSTEM}" diff --git a/rules/60-cdrom_id.rules b/rules/60-cdrom_id.rules new file mode 100644 index 000000000..6eaf76a72 --- /dev/null +++ b/rules/60-cdrom_id.rules @@ -0,0 +1,20 @@ +# do not edit this file, it will be overwritten on update + +ACTION=="remove", GOTO="cdrom_end" +SUBSYSTEM!="block", GOTO="cdrom_end" +KERNEL!="sr[0-9]*|xvd*", GOTO="cdrom_end" +ENV{DEVTYPE}!="disk", GOTO="cdrom_end" + +# unconditionally tag device as CDROM +KERNEL=="sr[0-9]*", ENV{ID_CDROM}="1" + +# media eject button pressed +ENV{DISK_EJECT_REQUEST}=="?*", RUN+="cdrom_id --eject-media $devnode", GOTO="cdrom_end" + +# import device and media properties and lock tray to +# enable the receiving of media eject button events +IMPORT{program}="cdrom_id --lock-media $devnode" + +KERNEL=="sr0", SYMLINK+="cdrom", OPTIONS+="link_priority=-100" + +LABEL="cdrom_end" diff --git a/rules/60-persistent-alsa.rules b/rules/60-persistent-alsa.rules new file mode 100644 index 000000000..8154e2dbb --- /dev/null +++ b/rules/60-persistent-alsa.rules @@ -0,0 +1,14 @@ +# do not edit this file, it will be overwritten on update + +ACTION=="remove", GOTO="persistent_alsa_end" +SUBSYSTEM!="sound", GOTO="persistent_alsa_end" +KERNEL!="controlC[0-9]*", GOTO="persistent_alsa_end" + +SUBSYSTEMS=="usb", ENV{ID_MODEL}=="", IMPORT{builtin}="usb_id" +ENV{ID_SERIAL}=="?*", ENV{ID_USB_INTERFACE_NUM}=="?*", SYMLINK+="snd/by-id/$env{ID_BUS}-$env{ID_SERIAL}-$env{ID_USB_INTERFACE_NUM}" +ENV{ID_SERIAL}=="?*", ENV{ID_USB_INTERFACE_NUM}=="", SYMLINK+="snd/by-id/$env{ID_BUS}-$env{ID_SERIAL}" + +IMPORT{builtin}="path_id" +ENV{ID_PATH}=="?*", SYMLINK+="snd/by-path/$env{ID_PATH}" + +LABEL="persistent_alsa_end" diff --git a/rules/60-persistent-input.rules b/rules/60-persistent-input.rules new file mode 100644 index 000000000..0e33e6838 --- /dev/null +++ b/rules/60-persistent-input.rules @@ -0,0 +1,38 @@ +# do not edit this file, it will be overwritten on update + +ACTION=="remove", GOTO="persistent_input_end" +SUBSYSTEM!="input", GOTO="persistent_input_end" +SUBSYSTEMS=="bluetooth", GOTO="persistent_input_end" + +SUBSYSTEMS=="usb", ENV{ID_BUS}=="", IMPORT{builtin}="usb_id" + +# determine class name for persistent symlinks +ENV{ID_INPUT_KEYBOARD}=="?*", ENV{.INPUT_CLASS}="kbd" +ENV{ID_INPUT_MOUSE}=="?*", ENV{.INPUT_CLASS}="mouse" +ENV{ID_INPUT_TOUCHPAD}=="?*", ENV{.INPUT_CLASS}="mouse" +ENV{ID_INPUT_TABLET}=="?*", ENV{.INPUT_CLASS}="mouse" +ENV{ID_INPUT_JOYSTICK}=="?*", ENV{.INPUT_CLASS}="joystick" +DRIVERS=="pcspkr", ENV{.INPUT_CLASS}="spkr" +ATTRS{name}=="*dvb*|*DVB*|* IR *", ENV{.INPUT_CLASS}="ir" + +# fill empty serial number +ENV{.INPUT_CLASS}=="?*", ENV{ID_SERIAL}=="", ENV{ID_SERIAL}="noserial" + +# by-id links +KERNEL=="mouse*|js*", ENV{ID_BUS}=="?*", ENV{.INPUT_CLASS}=="?*", ATTRS{bInterfaceNumber}=="|00", SYMLINK+="input/by-id/$env{ID_BUS}-$env{ID_SERIAL}-$env{.INPUT_CLASS}" +KERNEL=="mouse*|js*", ENV{ID_BUS}=="?*", ENV{.INPUT_CLASS}=="?*", ATTRS{bInterfaceNumber}=="?*", ATTRS{bInterfaceNumber}!="00", SYMLINK+="input/by-id/$env{ID_BUS}-$env{ID_SERIAL}-if$attr{bInterfaceNumber}-$env{.INPUT_CLASS}" +KERNEL=="event*", ENV{ID_BUS}=="?*", ENV{.INPUT_CLASS}=="?*", ATTRS{bInterfaceNumber}=="|00", SYMLINK+="input/by-id/$env{ID_BUS}-$env{ID_SERIAL}-event-$env{.INPUT_CLASS}" +KERNEL=="event*", ENV{ID_BUS}=="?*", ENV{.INPUT_CLASS}=="?*", ATTRS{bInterfaceNumber}=="?*", ATTRS{bInterfaceNumber}!="00", SYMLINK+="input/by-id/$env{ID_BUS}-$env{ID_SERIAL}-if$attr{bInterfaceNumber}-event-$env{.INPUT_CLASS}" +# allow empty class for USB devices, by appending the interface number +SUBSYSTEMS=="usb", ENV{ID_BUS}=="?*", KERNEL=="event*", ENV{.INPUT_CLASS}=="", ATTRS{bInterfaceNumber}=="?*", \ + SYMLINK+="input/by-id/$env{ID_BUS}-$env{ID_SERIAL}-event-if$attr{bInterfaceNumber}" + +# by-path +SUBSYSTEMS=="pci|usb|platform|acpi", IMPORT{builtin}="path_id" +ENV{ID_PATH}=="?*", KERNEL=="mouse*|js*", ENV{.INPUT_CLASS}=="?*", SYMLINK+="input/by-path/$env{ID_PATH}-$env{.INPUT_CLASS}" +ENV{ID_PATH}=="?*", KERNEL=="event*", ENV{.INPUT_CLASS}=="?*", SYMLINK+="input/by-path/$env{ID_PATH}-event-$env{.INPUT_CLASS}" +# allow empty class for platform and usb devices; platform supports only a single interface that way +SUBSYSTEMS=="usb|platform", ENV{ID_PATH}=="?*", KERNEL=="event*", ENV{.INPUT_CLASS}=="", \ + SYMLINK+="input/by-path/$env{ID_PATH}-event" + +LABEL="persistent_input_end" diff --git a/rules/60-persistent-serial.rules b/rules/60-persistent-serial.rules new file mode 100644 index 000000000..2948200c5 --- /dev/null +++ b/rules/60-persistent-serial.rules @@ -0,0 +1,20 @@ +# do not edit this file, it will be overwritten on update + +ACTION=="remove", GOTO="persistent_serial_end" +SUBSYSTEM!="tty", GOTO="persistent_serial_end" +KERNEL!="ttyUSB[0-9]*|ttyACM[0-9]*", GOTO="persistent_serial_end" + +SUBSYSTEMS=="usb-serial", ENV{.ID_PORT}="$attr{port_number}" + +IMPORT{builtin}="path_id" +ENV{ID_PATH}=="?*", ENV{.ID_PORT}=="", SYMLINK+="serial/by-path/$env{ID_PATH}" +ENV{ID_PATH}=="?*", ENV{.ID_PORT}=="?*", SYMLINK+="serial/by-path/$env{ID_PATH}-port$env{.ID_PORT}" + +IMPORT{builtin}="usb_id" +ENV{ID_SERIAL}=="", GOTO="persistent_serial_end" +SUBSYSTEMS=="usb", ENV{ID_USB_INTERFACE_NUM}="$attr{bInterfaceNumber}" +ENV{ID_USB_INTERFACE_NUM}=="", GOTO="persistent_serial_end" +ENV{.ID_PORT}=="", SYMLINK+="serial/by-id/$env{ID_BUS}-$env{ID_SERIAL}-if$env{ID_USB_INTERFACE_NUM}" +ENV{.ID_PORT}=="?*", SYMLINK+="serial/by-id/$env{ID_BUS}-$env{ID_SERIAL}-if$env{ID_USB_INTERFACE_NUM}-port$env{.ID_PORT}" + +LABEL="persistent_serial_end" diff --git a/rules/60-persistent-storage-tape.rules b/rules/60-persistent-storage-tape.rules new file mode 100644 index 000000000..f2eabd92a --- /dev/null +++ b/rules/60-persistent-storage-tape.rules @@ -0,0 +1,25 @@ +# do not edit this file, it will be overwritten on update + +# persistent storage links: /dev/tape/{by-id,by-path} + +ACTION=="remove", GOTO="persistent_storage_tape_end" + +# type 8 devices are "Medium Changers" +SUBSYSTEM=="scsi_generic", SUBSYSTEMS=="scsi", ATTRS{type}=="8", IMPORT{program}="scsi_id --sg-version=3 --export --whitelisted -d $devnode", \ + SYMLINK+="tape/by-id/scsi-$env{ID_SERIAL}" + +SUBSYSTEM!="scsi_tape", GOTO="persistent_storage_tape_end" + +KERNEL=="st*[0-9]|nst*[0-9]", ATTRS{ieee1394_id}=="?*", ENV{ID_SERIAL}="$attr{ieee1394_id}", ENV{ID_BUS}="ieee1394" +KERNEL=="st*[0-9]|nst*[0-9]", ENV{ID_SERIAL}!="?*", SUBSYSTEMS=="usb", IMPORT{builtin}="usb_id" +KERNEL=="st*[0-9]|nst*[0-9]", ENV{ID_SERIAL}!="?*", SUBSYSTEMS=="scsi", KERNELS=="[0-9]*:*[0-9]", ENV{.BSG_DEV}="$root/bsg/$id" +KERNEL=="st*[0-9]|nst*[0-9]", ENV{ID_SERIAL}!="?*", IMPORT{program}="scsi_id --whitelisted --export --device=$env{.BSG_DEV}", ENV{ID_BUS}="scsi" +KERNEL=="st*[0-9]", ENV{ID_SERIAL}=="?*", SYMLINK+="tape/by-id/$env{ID_BUS}-$env{ID_SERIAL}" +KERNEL=="nst*[0-9]", ENV{ID_SERIAL}=="?*", SYMLINK+="tape/by-id/$env{ID_BUS}-$env{ID_SERIAL}-nst" + +# by-path (parent device path) +KERNEL=="st*[0-9]|nst*[0-9]", IMPORT{builtin}="path_id" +KERNEL=="st*[0-9]", ENV{ID_PATH}=="?*", SYMLINK+="tape/by-path/$env{ID_PATH}" +KERNEL=="nst*[0-9]", ENV{ID_PATH}=="?*", SYMLINK+="tape/by-path/$env{ID_PATH}-nst" + +LABEL="persistent_storage_tape_end" diff --git a/rules/60-persistent-storage.rules b/rules/60-persistent-storage.rules new file mode 100644 index 000000000..b74821edd --- /dev/null +++ b/rules/60-persistent-storage.rules @@ -0,0 +1,89 @@ +# do not edit this file, it will be overwritten on update + +# persistent storage links: /dev/disk/{by-id,by-uuid,by-label,by-path} +# scheme based on "Linux persistent device names", 2004, Hannes Reinecke + +# forward scsi device event to corresponding block device +ACTION=="change", SUBSYSTEM=="scsi", ENV{DEVTYPE}=="scsi_device", TEST=="block", ATTR{block/*/uevent}="change" + +ACTION=="remove", GOTO="persistent_storage_end" + +# enable in-kernel media-presence polling +ACTION=="add", SUBSYSTEM=="module", KERNEL=="block", ATTR{parameters/events_dfl_poll_msecs}=="0", ATTR{parameters/events_dfl_poll_msecs}="2000" + +SUBSYSTEM!="block", GOTO="persistent_storage_end" + +# skip rules for inappropriate block devices +KERNEL=="fd*|mtd*|nbd*|gnbd*|btibm*|dm-*|md*", GOTO="persistent_storage_end" + +# ignore partitions that span the entire disk +TEST=="whole_disk", GOTO="persistent_storage_end" + +# for partitions import parent information +ENV{DEVTYPE}=="partition", IMPORT{parent}="ID_*" + +# virtio-blk +KERNEL=="vd*[!0-9]", ATTRS{serial}=="?*", ENV{ID_SERIAL}="$attr{serial}", SYMLINK+="disk/by-id/virtio-$env{ID_SERIAL}" +KERNEL=="vd*[0-9]", ATTRS{serial}=="?*", ENV{ID_SERIAL}="$attr{serial}", SYMLINK+="disk/by-id/virtio-$env{ID_SERIAL}-part%n" + +# ATA devices with their own "ata" kernel subsystem +KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}!="?*", SUBSYSTEMS=="ata", IMPORT{program}="ata_id --export $devnode" +# ATA devices using the "scsi" subsystem +KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}!="?*", SUBSYSTEMS=="scsi", ATTRS{vendor}=="ATA", IMPORT{program}="ata_id --export $devnode" +# ATA/ATAPI devices (SPC-3 or later) using the "scsi" subsystem +KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}!="?*", SUBSYSTEMS=="scsi", ATTRS{type}=="5", ATTRS{scsi_level}=="[6-9]*", IMPORT{program}="ata_id --export $devnode" + +# Run ata_id on non-removable USB Mass Storage (SATA/PATA disks in enclosures) +KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}!="?*", ATTR{removable}=="0", SUBSYSTEMS=="usb", IMPORT{program}="ata_id --export $devnode" +# Otherwise fall back to using usb_id for USB devices +KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}!="?*", SUBSYSTEMS=="usb", IMPORT{builtin}="usb_id" + +# scsi devices +KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}!="?*", IMPORT{program}="scsi_id --export --whitelisted -d $devnode", ENV{ID_BUS}="scsi" +KERNEL=="cciss*", ENV{DEVTYPE}=="disk", ENV{ID_SERIAL}!="?*", IMPORT{program}="scsi_id --export --whitelisted -d $devnode", ENV{ID_BUS}="cciss" +KERNEL=="sd*|sr*|cciss*", ENV{DEVTYPE}=="disk", ENV{ID_SERIAL}=="?*", SYMLINK+="disk/by-id/$env{ID_BUS}-$env{ID_SERIAL}" +KERNEL=="sd*|cciss*", ENV{DEVTYPE}=="partition", ENV{ID_SERIAL}=="?*", SYMLINK+="disk/by-id/$env{ID_BUS}-$env{ID_SERIAL}-part%n" + +# firewire +KERNEL=="sd*[!0-9]|sr*", ATTRS{ieee1394_id}=="?*", SYMLINK+="disk/by-id/ieee1394-$attr{ieee1394_id}" +KERNEL=="sd*[0-9]", ATTRS{ieee1394_id}=="?*", SYMLINK+="disk/by-id/ieee1394-$attr{ieee1394_id}-part%n" + +KERNEL=="mmcblk[0-9]", SUBSYSTEMS=="mmc", ATTRS{name}=="?*", ATTRS{serial}=="?*", ENV{ID_NAME}="$attr{name}", ENV{ID_SERIAL}="$attr{serial}", SYMLINK+="disk/by-id/mmc-$env{ID_NAME}_$env{ID_SERIAL}" +KERNEL=="mmcblk[0-9]p[0-9]", ENV{ID_NAME}=="?*", ENV{ID_SERIAL}=="?*", SYMLINK+="disk/by-id/mmc-$env{ID_NAME}_$env{ID_SERIAL}-part%n" +KERNEL=="mspblk[0-9]", SUBSYSTEMS=="memstick", ATTRS{name}=="?*", ATTRS{serial}=="?*", ENV{ID_NAME}="$attr{name}", ENV{ID_SERIAL}="$attr{serial}", SYMLINK+="disk/by-id/memstick-$env{ID_NAME}_$env{ID_SERIAL}" +KERNEL=="mspblk[0-9]p[0-9]", ENV{ID_NAME}=="?*", ENV{ID_SERIAL}=="?*", SYMLINK+="disk/by-id/memstick-$env{ID_NAME}_$env{ID_SERIAL}-part%n" + +# by-path (parent device path) +ENV{DEVTYPE}=="disk", DEVPATH!="*/virtual/*", IMPORT{builtin}="path_id" +ENV{DEVTYPE}=="disk", ENV{ID_PATH}=="?*", SYMLINK+="disk/by-path/$env{ID_PATH}" +ENV{DEVTYPE}=="partition", ENV{ID_PATH}=="?*", SYMLINK+="disk/by-path/$env{ID_PATH}-part%n" + +# skip unpartitioned removable media devices from drivers which do not send "change" events +ENV{DEVTYPE}=="disk", KERNEL!="sd*|sr*", ATTR{removable}=="1", GOTO="persistent_storage_end" + +# probe filesystem metadata of optical drives which have a media inserted +KERNEL=="sr*", ENV{DISK_EJECT_REQUEST}!="?*", ENV{ID_CDROM_MEDIA_TRACK_COUNT_DATA}=="?*", ENV{ID_CDROM_MEDIA_SESSION_LAST_OFFSET}=="?*", \ + IMPORT{builtin}="blkid --offset=$env{ID_CDROM_MEDIA_SESSION_LAST_OFFSET}" +# single-session CDs do not have ID_CDROM_MEDIA_SESSION_LAST_OFFSET +KERNEL=="sr*", ENV{DISK_EJECT_REQUEST}!="?*", ENV{ID_CDROM_MEDIA_TRACK_COUNT_DATA}=="?*", ENV{ID_CDROM_MEDIA_SESSION_LAST_OFFSET}=="", \ + IMPORT{builtin}="blkid --noraid" + +# probe filesystem metadata of disks +KERNEL!="sr*", IMPORT{builtin}="blkid" + +# watch metadata changes by tools closing the device after writing +KERNEL!="sr*", OPTIONS+="watch" + +# by-label/by-uuid links (filesystem metadata) +ENV{ID_FS_USAGE}=="filesystem|other|crypto", ENV{ID_FS_UUID_ENC}=="?*", SYMLINK+="disk/by-uuid/$env{ID_FS_UUID_ENC}" +ENV{ID_FS_USAGE}=="filesystem|other", ENV{ID_FS_LABEL_ENC}=="?*", SYMLINK+="disk/by-label/$env{ID_FS_LABEL_ENC}" + +# by-id (World Wide Name) +ENV{DEVTYPE}=="disk", ENV{ID_WWN_WITH_EXTENSION}=="?*", SYMLINK+="disk/by-id/wwn-$env{ID_WWN_WITH_EXTENSION}" +ENV{DEVTYPE}=="partition", ENV{ID_WWN_WITH_EXTENSION}=="?*", SYMLINK+="disk/by-id/wwn-$env{ID_WWN_WITH_EXTENSION}-part%n" + +# by-partlabel/by-partuuid links (partition metadata) +ENV{ID_PART_ENTRY_SCHEME}=="gpt", ENV{ID_PART_ENTRY_UUID}=="?*", SYMLINK+="disk/by-partuuid/$env{ID_PART_ENTRY_UUID}" +ENV{ID_PART_ENTRY_SCHEME}=="gpt", ENV{ID_PART_ENTRY_NAME}=="?*", SYMLINK+="disk/by-partlabel/$env{ID_PART_ENTRY_NAME}" + +LABEL="persistent_storage_end" diff --git a/rules/60-persistent-v4l.rules b/rules/60-persistent-v4l.rules new file mode 100644 index 000000000..93c5ee8c2 --- /dev/null +++ b/rules/60-persistent-v4l.rules @@ -0,0 +1,20 @@ +# do not edit this file, it will be overwritten on update + +ACTION=="remove", GOTO="persistent_v4l_end" +SUBSYSTEM!="video4linux", GOTO="persistent_v4l_end" +ENV{MAJOR}=="", GOTO="persistent_v4l_end" + +IMPORT{program}="v4l_id $devnode" + +SUBSYSTEMS=="usb", IMPORT{builtin}="usb_id" +KERNEL=="video*", ENV{ID_SERIAL}=="?*", SYMLINK+="v4l/by-id/$env{ID_BUS}-$env{ID_SERIAL}-video-index$attr{index}" + +# check for valid "index" number +TEST!="index", GOTO="persistent_v4l_end" +ATTR{index}!="?*", GOTO="persistent_v4l_end" + +IMPORT{builtin}="path_id" +ENV{ID_PATH}=="?*", KERNEL=="video*|vbi*", SYMLINK+="v4l/by-path/$env{ID_PATH}-video-index$attr{index}" +ENV{ID_PATH}=="?*", KERNEL=="audio*", SYMLINK+="v4l/by-path/$env{ID_PATH}-audio-index$attr{index}" + +LABEL="persistent_v4l_end" diff --git a/rules/61-accelerometer.rules b/rules/61-accelerometer.rules new file mode 100644 index 000000000..a6a2bfd08 --- /dev/null +++ b/rules/61-accelerometer.rules @@ -0,0 +1,3 @@ +# do not edit this file, it will be overwritten on update + +SUBSYSTEM=="input", ACTION!="remove", ENV{ID_INPUT_ACCELEROMETER}=="1", IMPORT{program}="accelerometer %p" diff --git a/rules/64-btrfs.rules b/rules/64-btrfs.rules new file mode 100644 index 000000000..fe0100131 --- /dev/null +++ b/rules/64-btrfs.rules @@ -0,0 +1,13 @@ +# do not edit this file, it will be overwritten on update + +SUBSYSTEM!="block", GOTO="btrfs_end" +ACTION=="remove", GOTO="btrfs_end" +ENV{ID_FS_TYPE}!="btrfs", GOTO="btrfs_end" + +# let the kernel know about this btrfs filesystem, and check if it is complete +IMPORT{builtin}="btrfs ready $devnode" + +# mark the device as not ready to be used by the system +ENV{ID_BTRFS_READY}=="0", ENV{SYSTEMD_READY}="0" + +LABEL="btrfs_end" diff --git a/rules/75-net-description.rules b/rules/75-net-description.rules new file mode 100644 index 000000000..fe9fca14d --- /dev/null +++ b/rules/75-net-description.rules @@ -0,0 +1,14 @@ +# do not edit this file, it will be overwritten on update + +ACTION=="remove", GOTO="net_end" +SUBSYSTEM!="net", GOTO="net_end" + +IMPORT{builtin}="net_id" +SUBSYSTEMS=="usb", IMPORT{builtin}="usb_id", IMPORT{builtin}="hwdb --subsystem=usb" +SUBSYSTEMS=="usb", GOTO="net_end" + +SUBSYSTEMS=="pci", ENV{ID_BUS}="pci", ENV{ID_VENDOR_ID}="$attr{vendor}", ENV{ID_MODEL_ID}="$attr{device}" + +IMPORT{builtin}="hwdb" + +LABEL="net_end" diff --git a/rules/75-probe_mtd.rules b/rules/75-probe_mtd.rules new file mode 100644 index 000000000..8848aeeae --- /dev/null +++ b/rules/75-probe_mtd.rules @@ -0,0 +1,7 @@ +# do not edit this file, it will be overwritten on update + +ACTION!="add", GOTO="mtd_probe_end" + +KERNEL=="mtd*ro", IMPORT{program}="mtd_probe $devnode" + +LABEL="mtd_probe_end" diff --git a/rules/75-tty-description.rules b/rules/75-tty-description.rules new file mode 100644 index 000000000..83083d93e --- /dev/null +++ b/rules/75-tty-description.rules @@ -0,0 +1,13 @@ +# do not edit this file, it will be overwritten on update + +ACTION=="remove", GOTO="tty_end" +SUBSYSTEM!="tty", GOTO="tty_end" + +SUBSYSTEMS=="usb", IMPORT{builtin}="usb_id", IMPORT{builtin}="hwdb --subsystem=usb" +SUBSYSTEMS=="usb", GOTO="tty_end" + +SUBSYSTEMS=="pci", ENV{ID_BUS}="pci", ENV{ID_VENDOR_ID}="$attr{vendor}", ENV{ID_MODEL_ID}="$attr{device}" + +IMPORT{builtin}="hwdb" + +LABEL="tty_end" diff --git a/rules/78-sound-card.rules b/rules/78-sound-card.rules new file mode 100644 index 000000000..295f49015 --- /dev/null +++ b/rules/78-sound-card.rules @@ -0,0 +1,86 @@ +# do not edit this file, it will be overwritten on update + +SUBSYSTEM!="sound", GOTO="sound_end" + +ACTION=="add|change", KERNEL=="controlC*", ATTR{../uevent}="change" +ACTION!="change", GOTO="sound_end" + +# Ok, we probably need a little explanation here for what the two lines above +# are good for. +# +# The story goes like this: when ALSA registers a new sound card it emits a +# series of 'add' events to userspace, for the main card device and for all the +# child device nodes that belong to it. udev relays those to applications, +# however only maintains the order between father and child, but not between +# the siblings. The control device node creation can be used as synchronization +# point. All other devices that belong to a card are created in the kernel +# before it. However unfortunately due to the fact that siblings are forwarded +# out of order by udev this fact is lost to applications. +# +# OTOH before an application can open a device it needs to make sure that all +# its device nodes are completely created and set up. +# +# As a workaround for this issue we have added the udev rule above which will +# generate a 'change' event on the main card device from the 'add' event of the +# card's control device. Due to the ordering semantics of udev this event will +# only be relayed after all child devices have finished processing properly. +# When an application needs to listen for appearing devices it can hence look +# for 'change' events only, and ignore the actual 'add' events. +# +# When the application is initialized at the same time as a device is plugged +# in it may need to figure out if the 'change' event has already been triggered +# or not for a card. To find that out we store the flag environment variable +# SOUND_INITIALIZED on the device which simply tells us if the card 'change' +# event has already been processed. + +KERNEL!="card*", GOTO="sound_end" + +ENV{SOUND_INITIALIZED}="1" + +IMPORT{builtin}="hwdb" +SUBSYSTEMS=="usb", IMPORT{builtin}="usb_id" +SUBSYSTEMS=="usb", GOTO="skip_pci" + +SUBSYSTEMS=="firewire", ATTRS{vendor_name}=="?*", ATTRS{model_name}=="?*", \ + ENV{ID_BUS}="firewire", ENV{ID_VENDOR}="$attr{vendor_name}", ENV{ID_MODEL}="$attr{model_name}" +SUBSYSTEMS=="firewire", ATTRS{guid}=="?*", ENV{ID_ID}="firewire-$attr{guid}" +SUBSYSTEMS=="firewire", GOTO="skip_pci" + +SUBSYSTEMS=="pci", ENV{ID_BUS}="pci", ENV{ID_VENDOR_ID}="$attr{vendor}", ENV{ID_MODEL_ID}="$attr{device}" +LABEL="skip_pci" + +ENV{ID_SERIAL}=="?*", ENV{ID_USB_INTERFACE_NUM}=="?*", ENV{ID_ID}="$env{ID_BUS}-$env{ID_SERIAL}-$env{ID_USB_INTERFACE_NUM}-$attr{id}" +ENV{ID_SERIAL}=="?*", ENV{ID_USB_INTERFACE_NUM}=="", ENV{ID_ID}="$env{ID_BUS}-$env{ID_SERIAL}-$attr{id}" + +IMPORT{builtin}="path_id" + +# The values used here for $SOUND_FORM_FACTOR and $SOUND_CLASS should be kept +# in sync with those defined for PulseAudio's src/pulse/proplist.h +# PA_PROP_DEVICE_FORM_FACTOR, PA_PROP_DEVICE_CLASS properties. + +# If the first PCM device of this card has the pcm class 'modem', then the card is a modem +ATTR{pcmC%nD0p/pcm_class}=="modem", ENV{SOUND_CLASS}="modem", GOTO="sound_end" + +# Identify cards on the internal PCI bus as internal +SUBSYSTEMS=="pci", DEVPATH=="*/0000:00:??.?/sound/*", ENV{SOUND_FORM_FACTOR}="internal", GOTO="sound_end" + +# Devices that also support Image/Video interfaces are most likely webcams +SUBSYSTEMS=="usb", ENV{ID_USB_INTERFACES}=="*:0e????:*", ENV{SOUND_FORM_FACTOR}="webcam", GOTO="sound_end" + +# Matching on the model strings is a bit ugly, I admit +ENV{ID_MODEL}=="*[Ss]peaker*", ENV{SOUND_FORM_FACTOR}="speaker", GOTO="sound_end" +ENV{ID_MODEL_FROM_DATABASE}=="*[Ss]peaker*", ENV{SOUND_FORM_FACTOR}="speaker", GOTO="sound_end" + +ENV{ID_MODEL}=="*[Hh]eadphone*", ENV{SOUND_FORM_FACTOR}="headphone", GOTO="sound_end" +ENV{ID_MODEL_FROM_DATABASE}=="*[Hh]eadphone*", ENV{SOUND_FORM_FACTOR}="headphone", GOTO="sound_end" + +ENV{ID_MODEL}=="*[Hh]eadset*", ENV{SOUND_FORM_FACTOR}="headset", GOTO="sound_end" +ENV{ID_MODEL_FROM_DATABASE}=="*[Hh]eadset*", ENV{SOUND_FORM_FACTOR}="headset", GOTO="sound_end" + +ENV{ID_MODEL}=="*[Hh]andset*", ENV{SOUND_FORM_FACTOR}="handset", GOTO="sound_end" +ENV{ID_MODEL_FROM_DATABASE}=="*[Hh]andset*", ENV{SOUND_FORM_FACTOR}="handset", GOTO="sound_end" + +ENV{ID_MODEL}=="*[Mm]icrophone*", ENV{SOUND_FORM_FACTOR}="microphone", GOTO="sound_end" +ENV{ID_MODEL_FROM_DATABASE}=="*[Mm]icrophone*", ENV{SOUND_FORM_FACTOR}="microphone", GOTO="sound_end" + +LABEL="sound_end" diff --git a/rules/80-drivers.rules b/rules/80-drivers.rules new file mode 100644 index 000000000..a0615cc3b --- /dev/null +++ b/rules/80-drivers.rules @@ -0,0 +1,13 @@ +# do not edit this file, it will be overwritten on update + +ACTION=="remove", GOTO="drivers_end" + +DRIVER!="?*", ENV{MODALIAS}=="?*", IMPORT{builtin}="kmod load $env{MODALIAS}" +SUBSYSTEM=="tifm", ENV{TIFM_CARD_TYPE}=="SD", IMPORT{builtin}="kmod load tifm_sd" +SUBSYSTEM=="tifm", ENV{TIFM_CARD_TYPE}=="MS", IMPORT{builtin}="kmod load tifm_ms" +SUBSYSTEM=="memstick", IMPORT{builtin}="kmod load ms_block mspro_block" +SUBSYSTEM=="i2o", IMPORT{builtin}="kmod load i2o_block" +SUBSYSTEM=="module", KERNEL=="parport_pc", RUN{builtin}="kmod load ppdev" +KERNEL=="mtd*ro", ENV{MTD_FTL}=="smartmedia", IMPORT{builtin}="kmod load sm_ftl" + +LABEL="drivers_end" diff --git a/rules/80-net-name-slot.rules b/rules/80-net-name-slot.rules new file mode 100644 index 000000000..2834e82db --- /dev/null +++ b/rules/80-net-name-slot.rules @@ -0,0 +1,11 @@ +# do not edit this file, it will be overwritten on update + +ACTION=="remove", GOTO="net_name_slot_end" +SUBSYSTEM!="net", GOTO="net_name_slot_end" +NAME!="", GOTO="net_name_slot_end" + +NAME=="", ENV{ID_NET_NAME_ONBOARD}!="", NAME="$env{ID_NET_NAME_ONBOARD}" +NAME=="", ENV{ID_NET_NAME_SLOT}!="", NAME="$env{ID_NET_NAME_SLOT}" +NAME=="", ENV{ID_NET_NAME_PATH}!="", NAME="$env{ID_NET_NAME_PATH}" + +LABEL="net_name_slot_end" diff --git a/rules/95-udev-late.rules b/rules/95-udev-late.rules new file mode 100644 index 000000000..eca0faa5c --- /dev/null +++ b/rules/95-udev-late.rules @@ -0,0 +1,4 @@ +# do not edit this file, it will be overwritten on update + +# run a command on remove events +ACTION=="remove", ENV{REMOVE_CMD}!="", RUN+="$env{REMOVE_CMD}" diff --git a/rules/99-systemd.rules.in b/rules/99-systemd.rules.in new file mode 100644 index 000000000..d17bdd9a0 --- /dev/null +++ b/rules/99-systemd.rules.in @@ -0,0 +1,60 @@ +# This file is part of systemd. +# +# 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. + +ACTION=="remove", GOTO="systemd_end" + +SUBSYSTEM=="tty", KERNEL=="tty[a-zA-Z]*|hvc*|xvc*|hvsi*", TAG+="systemd" + +KERNEL=="vport*", TAG+="systemd" + +SUBSYSTEM=="block", KERNEL!="ram*|loop*", TAG+="systemd" +SUBSYSTEM=="block", KERNEL!="ram*|loop*", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}=="1", ENV{SYSTEMD_READY}="0" + +# Ignore encrypted devices with no identified superblock on it, since +# we are probably still calling mke2fs or mkswap on it. +SUBSYSTEM=="block", KERNEL!="ram*|loop*", ENV{DM_UUID}=="CRYPT-*", ENV{ID_PART_TABLE_TYPE}=="", ENV{ID_FS_USAGE}=="", ENV{SYSTEMD_READY}="0" + +# Ignore raid devices that are not yet assembled and started +SUBSYSTEM=="block", ENV{DEVTYPE}=="disk", KERNEL=="md*", TEST!="md/array_state", ENV{SYSTEMD_READY}="0" +SUBSYSTEM=="block", ENV{DEVTYPE}=="disk", KERNEL=="md*", ATTR{md/array_state}=="|clear|inactive", ENV{SYSTEMD_READY}="0" + +# Ignore nbd devices in the "add" event, with "change" the nbd is ready +ACTION=="add", SUBSYSTEM=="block", KERNEL=="nbd*", ENV{SYSTEMD_READY}="0" + +# We need a hardware independent way to identify network devices. We +# use the /sys/subsystem path for this. Current vanilla kernels don't +# actually support that hierarchy right now, however upcoming kernels +# will. HAL and udev internally support /sys/subsystem already, hence +# it should be safe to use this here, too. This is mostly just an +# identification string for systemd, so whether the path actually is +# accessible or not does not matter as long as it is unique and in the +# filesystem namespace. +# +# http://cgit.freedesktop.org/systemd/systemd/tree/src/libudev/libudev-enumerate.c#n922 + +SUBSYSTEM=="net", KERNEL!="lo", TAG+="systemd", ENV{SYSTEMD_ALIAS}+="/sys/subsystem/net/devices/$name" +SUBSYSTEM=="bluetooth", TAG+="systemd", ENV{SYSTEMD_ALIAS}+="/sys/subsystem/bluetooth/devices/%k" + +SUBSYSTEM=="bluetooth", TAG+="systemd", ENV{SYSTEMD_WANTS}+="bluetooth.target" +ENV{ID_SMARTCARD_READER}=="*?", TAG+="systemd", ENV{SYSTEMD_WANTS}+="smartcard.target" +SUBSYSTEM=="sound", KERNEL=="card*", TAG+="systemd", ENV{SYSTEMD_WANTS}+="sound.target" + +SUBSYSTEM=="printer", TAG+="systemd", ENV{SYSTEMD_WANTS}+="printer.target" +SUBSYSTEM=="usb", KERNEL=="lp*", TAG+="systemd", ENV{SYSTEMD_WANTS}+="printer.target" +SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ENV{ID_USB_INTERFACES}=="*:0701??:*", TAG+="systemd", ENV{SYSTEMD_WANTS}+="printer.target" + +# Apply sysctl variables to network devices (and only to those) as they appear. + +SUBSYSTEM=="net", KERNEL!="lo", RUN+="@rootlibexecdir@/systemd-sysctl --prefix=/proc/sys/net/ipv4/conf/$name --prefix=/proc/sys/net/ipv4/neigh/$name --prefix=/proc/sys/net/ipv6/conf/$name --prefix=/proc/sys/net/ipv6/neigh/$name" + +# Asynchronously mount file systems implemented by these modules as +# soon as they are loaded. + +SUBSYSTEM=="module", KERNEL=="fuse", ACTION=="add", TAG+="systemd", ENV{SYSTEMD_WANTS}+="sys-fs-fuse-connections.mount" +SUBSYSTEM=="module", KERNEL=="configfs", ACTION=="add", TAG+="systemd", ENV{SYSTEMD_WANTS}+="sys-kernel-config.mount" + +LABEL="systemd_end" diff --git a/shell-completion/systemd-bash-completion.sh b/shell-completion/systemd-bash-completion.sh new file mode 100644 index 000000000..52dc72b04 --- /dev/null +++ b/shell-completion/systemd-bash-completion.sh @@ -0,0 +1,607 @@ +# This file is part of systemd. +# +# Copyright 2010 Ran Benita +# +# 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 +# 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 . + +__systemctl() { + systemctl --full --no-legend "$@" +} + +__contains_word () { + local word=$1; shift + for w in $*; do [[ $w = $word ]] && return 0; done + return 1 +} + +__filter_units_by_property () { + local property=$1 value=$2 ; shift 2 + local units=("$@") + local props + IFS=$'\n' read -rd '' -a props < \ + <(__systemctl show --property "$property" -- "${units[@]}") + for ((i=0; $i < ${#units[*]}; i++)); do + if [[ "${props[i]}" = "$property=$value" ]]; then + printf "%s\n" "${units[i]}" + fi + done +} + +__get_all_units () { __systemctl list-units --all \ + | { while read -r a b; do printf "%s\n" "$a"; done; }; } +__get_active_units () { __systemctl list-units \ + | { while read -r a b; do printf "%s\n" "$a"; done; }; } +__get_inactive_units () { __systemctl list-units --all \ + | { while read -r a b c d; do [[ $c == "inactive" ]] && printf "%s\n" "$a"; done; }; } +__get_failed_units () { __systemctl list-units \ + | { while read -r a b c d; do [[ $c == "failed" ]] && printf "%s\n" "$a"; done; }; } +__get_enabled_units () { __systemctl list-unit-files \ + | { while read -r a b c ; do [[ $b == "enabled" ]] && printf "%s\n" "$a"; done; }; } +__get_disabled_units () { __systemctl list-unit-files \ + | { while read -r a b c ; do [[ $b == "disabled" ]] && printf "%s\n" "$a"; done; }; } +__get_masked_units () { __systemctl list-unit-files \ + | { while read -r a b c ; do [[ $b == "masked" ]] && printf "%s\n" "$a"; done; }; } + +_systemctl () { + local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} + local i verb comps + + local -A OPTS=( + [STANDALONE]='--all -a --defaults --fail --ignore-dependencies --failed --force -f --full --global + --help -h --no-ask-password --no-block --no-legend --no-pager --no-reload --no-wall + --order --require --quiet -q --privileged -P --system --user --version --runtime' + [ARG]='--host -H --kill-mode --kill-who --property -p --signal -s --type -t --root' + ) + + if __contains_word "$prev" ${OPTS[ARG]}; then + case $prev in + --signal|-s) + comps=$(compgen -A signal) + ;; + --type|-t) + comps='automount device mount path service snapshot socket swap target timer' + ;; + --kill-who) + comps='all control main' + ;; + --kill-mode) + comps='control-group process' + ;; + --root) + comps=$(compgen -A directory -- "$cur" ) + compopt -o filenames + ;; + --host|-H) + comps=$(compgen -A hostname) + ;; + --property|-p) + comps='' + ;; + esac + COMPREPLY=( $(compgen -W '$comps' -- "$cur") ) + return 0 + fi + + + if [[ "$cur" = -* ]]; then + COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") ) + return 0 + fi + + local -A VERBS=( + [ALL_UNITS]='is-active is-failed is-enabled status show mask preset' + [ENABLED_UNITS]='disable reenable' + [DISABLED_UNITS]='enable' + [FAILED_UNITS]='reset-failed' + [STARTABLE_UNITS]='start' + [STOPPABLE_UNITS]='stop condstop kill try-restart condrestart' + [ISOLATABLE_UNITS]='isolate' + [RELOADABLE_UNITS]='reload condreload reload-or-try-restart force-reload' + [RESTARTABLE_UNITS]='restart reload-or-restart' + [MASKED_UNITS]='unmask' + [JOBS]='cancel' + [SNAPSHOTS]='delete' + [ENVS]='set-environment unset-environment' + [STANDALONE]='daemon-reexec daemon-reload default dot dump + emergency exit halt hibernate hybrid-sleep kexec list-jobs + list-units list-unit-files poweroff reboot rescue + show-environment suspend' + [NAME]='snapshot load' + [FILE]='link' + ) + + for ((i=0; $i <= $COMP_CWORD; i++)); do + if __contains_word "${COMP_WORDS[i]}" ${VERBS[*]} && + ! __contains_word "${COMP_WORDS[i-1]}" ${OPTS[ARG]}; then + verb=${COMP_WORDS[i]} + break + fi + done + + if [[ -z $verb ]]; then + comps="${VERBS[*]}" + + elif __contains_word "$verb" ${VERBS[ALL_UNITS]}; then + comps=$( __get_all_units ) + + elif __contains_word "$verb" ${VERBS[ENABLED_UNITS]}; then + comps=$( __get_enabled_units ) + + elif __contains_word "$verb" ${VERBS[DISABLED_UNITS]}; then + comps=$( __get_disabled_units ) + + elif __contains_word "$verb" ${VERBS[STARTABLE_UNITS]}; then + comps=$( __filter_units_by_property CanStart yes \ + $( __get_inactive_units \ + | while read -r line; do \ + [[ "$line" =~ \.(device|snapshot)$ ]] || printf "%s\n" "$line"; \ + done )) + + elif __contains_word "$verb" ${VERBS[RESTARTABLE_UNITS]}; then + comps=$( __filter_units_by_property CanStart yes \ + $( __get_all_units \ + | while read -r line; do \ + [[ "$line" =~ \.(device|snapshot|socket|timer)$ ]] || printf "%s\n" "$line"; \ + done )) + + elif __contains_word "$verb" ${VERBS[STOPPABLE_UNITS]}; then + comps=$( __filter_units_by_property CanStop yes \ + $( __get_active_units ) ) + + elif __contains_word "$verb" ${VERBS[RELOADABLE_UNITS]}; then + comps=$( __filter_units_by_property CanReload yes \ + $( __get_active_units ) ) + + elif __contains_word "$verb" ${VERBS[ISOLATABLE_UNITS]}; then + comps=$( __filter_units_by_property AllowIsolate yes \ + $( __get_all_units ) ) + + elif __contains_word "$verb" ${VERBS[FAILED_UNITS]}; then + comps=$( __get_failed_units ) + + elif __contains_word "$verb" ${VERBS[MASKED_UNITS]}; then + comps=$( __get_masked_units ) + + elif __contains_word "$verb" ${VERBS[STANDALONE]} ${VERBS[NAME]}; then + comps='' + + elif __contains_word "$verb" ${VERBS[JOBS]}; then + comps=$( __systemctl list-jobs | { while read -r a b; do printf "%s\n" "$a"; done; } ) + + elif __contains_word "$verb" ${VERBS[SNAPSHOTS]}; then + comps=$( __systemctl list-units --type snapshot --full --all \ + | { while read -r a b; do printf "%s\n" "$a"; done; } ) + + elif __contains_word "$verb" ${VERBS[ENVS]}; then + comps=$( __systemctl show-environment \ + | while read -r line; do printf "%s\n" "${line%%=*}=";done ) + compopt -o nospace + + elif __contains_word "$verb" ${VERBS[FILE]}; then + comps=$( compgen -A file -- "$cur" ) + compopt -o filenames + fi + + COMPREPLY=( $(compgen -W '$comps' -- "$cur") ) + return 0 +} +complete -F _systemctl systemctl + +__get_all_sessions () { loginctl list-sessions | { while read -r a b; do printf "%s\n" "$a"; done; } ; } +__get_all_users () { loginctl list-users | { while read -r a b; do printf "%s\n" "$b"; done; } ; } +__get_all_seats () { loginctl list-seats | { while read -r a b; do printf "%s\n" "$a"; done; } ; } + +_loginctl () { + local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} + local i verb comps + + local -A OPTS=( + [STANDALONE]='--all -a --help -h --no-pager --privileged -P --version' + [ARG]='--host -H --kill-who --property -p --signal -s' + ) + + if __contains_word "$prev" ${OPTS[ARG]}; then + case $prev in + --signal|-s) + comps=$(compgen -A signal) + ;; + --kill-who) + comps='all leader' + ;; + --host|-H) + comps=$(compgen -A hostname) + ;; + --property|-p) + comps='' + ;; + esac + COMPREPLY=( $(compgen -W '$comps' -- "$cur") ) + return 0 + fi + + + if [[ "$cur" = -* ]]; then + COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") ) + return 0 + fi + + local -A VERBS=( + [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' + [ATTACH]='attach' + ) + + for ((i=0; $i <= $COMP_CWORD; i++)); do + if __contains_word "${COMP_WORDS[i]}" ${VERBS[*]} && + ! __contains_word "${COMP_WORDS[i-1]}" ${OPTS[ARG]}; then + verb=${COMP_WORDS[i]} + break + fi + done + + if [[ -z $verb ]]; then + comps="${VERBS[*]}" + + elif __contains_word "$verb" ${VERBS[SESSIONS]}; then + comps=$( __get_all_sessions ) + + elif __contains_word "$verb" ${VERBS[USERS]}; then + comps=$( __get_all_users ) + + elif __contains_word "$verb" ${VERBS[SEATS]}; then + comps=$( __get_all_seats ) + + elif __contains_word "$verb" ${VERBS[STANDALONE]}; then + comps='' + + elif __contains_word "$verb" ${VERBS[ATTACH]}; then + if [[ $prev = $verb ]]; then + comps=$( __get_all_seats ) + else + comps=$(compgen -A file -- "$cur" ) + compopt -o filenames + fi + fi + + COMPREPLY=( $(compgen -W '$comps' -- "$cur") ) + return 0 +} +complete -F _loginctl loginctl + +__journal_fields=(MESSAGE{,_ID} PRIORITY CODE_{FILE,LINE,FUNC} + ERRNO SYSLOG_{FACILITY,IDENTIFIER,PID} COREDUMP_EXE + _{P,U,G}ID _COMM _EXE _CMDLINE + _AUDIT_{SESSION,LOGINUID} + _SYSTEMD_{CGROUP,SESSION,UNIT,OWNER_UID} + _SELINUX_CONTEXT _SOURCE_REALTIME_TIMESTAMP + _{BOOT,MACHINE}_ID _HOSTNAME _TRANSPORT + _KERNEL_{DEVICE,SUBSYSTEM} + _UDEV_{SYSNAME,DEVNODE,DEVLINK} + __CURSOR __{REALTIME,MONOTONIC}_TIMESTAMP) + +_journalctl() { + local field_vals= cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} + local -A OPTS=( + [STANDALONE]='-a --all --full + -b --this-boot --disk-usage -f --follow --header + -h --help -l --local --new-id128 -m --merge --no-pager + --no-tail -q --quiet --setup-keys --this-boot --verify + --version --list-catalog --update-catalog' + [ARG]='-D --directory -F --field -o --output -u --unit' + [ARGUNKNOWN]='-c --cursor --interval -n --lines -p --priority --since --until + --verify-key' + ) + + if __contains_word "$prev" ${OPTS[ARG]} ${OPTS[ARGUNKNOWN]}; then + case $prev in + --directory|-D) + comps=$(compgen -d -- "$cur") + compopt -o filenames + ;; + --output|-o) + comps='short short-monotonic verbose export json cat' + ;; + --field|-F) + comps=${__journal_fields[*]} + ;; + --unit|-u) + comps=$(journalctl -F '_SYSTEMD_UNIT') + ;; + *) + return 0 + ;; + esac + COMPREPLY=( $(compgen -W '$comps' -- "$cur") ) + return 0 + fi + + if [[ $cur = -* ]]; then + COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") ) + return 0 + elif [[ $cur = *=* ]]; then + mapfile -t field_vals < <(journalctl -F "${prev%=}" 2>/dev/null) + COMPREPLY=( $(compgen -W '${field_vals[*]}' -- "${cur#=}") ) + elif [[ $prev = '=' ]]; then + mapfile -t field_vals < <(journalctl -F "${COMP_WORDS[COMP_CWORD-2]}" 2>/dev/null) + COMPREPLY=( $(compgen -W '${field_vals[*]}' -- "$cur") ) + else + compopt -o nospace + COMPREPLY=( $(compgen -W '${__journal_fields[*]}' -S= -- "$cur") ) + fi +} +complete -F _journalctl journalctl + +_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' + + local -A VERBS=( + [LIST]='list' + [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 + 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 + compopt -o nospace + COMPREPLY=( $(compgen -W '${__journal_fields[*]}' -S= -- "$cur") ) + return 0 + elif [[ $cur = *=* ]]; then + mapfile -t field_vals < <(systemd-coredumpctl -F "${prev%=}" 2>/dev/null) + COMPREPLY=( $(compgen -W '${field_vals[*]}' -- "${cur#=}") ) + return 0 + elif [[ $prev = '=' ]]; then + mapfile -t field_vals < <(systemd-coredumpctl -F "${COMP_WORDS[COMP_CWORD-2]}" 2>/dev/null) + comps=${field_vals[*]} + else + for ((i=0; i <= COMP_CWORD; i++)); do + if __contains_word "${COMP_WORDS[i]}" ${VERBS[*]}; then + verb=${COMP_WORDS[i]} + break + fi + done + + if [[ -z $verb ]]; then + comps=${VERBS[*]} + elif __contains_word "$verb" ${VERBS[LIST]} ${VERBS[DUMP]}; then + comps='' + fi + fi + + COMPREPLY=( $(compgen -W '$comps' -- "$cur") ) + return 0 +} +complete -F _coredumpctl systemd-coredumpctl + +_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' + + if __contains_word "$prev" $OPTS; then + case $prev in + --host|-H) + comps='' + ;; + esac + COMPREPLY=( $(compgen -W '$comps' -- "$cur") ) + return 0 + fi + + if [[ $cur = -* ]]; then + COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") ) + return 0 + fi + + local -A VERBS=( + [BOOLEAN]='set-local-rtc set-ntp' + [STANDALONE]='status set-time list-timezones' + [TIMEZONES]='set-timezone' + [TIME]='set-time' + ) + + for ((i=0; i <= COMP_CWORD; i++)); do + if __contains_word "${COMP_WORDS[i]}" ${VERBS[*]}; then + verb=${COMP_WORDS[i]} + break + fi + done + + if [[ -z $verb ]]; then + comps=${VERBS[*]} + elif __contains_word "$verb" ${VERBS[BOOLEAN]}; then + comps='true false' + elif __contains_word "$verb" ${VERBS[TIMEZONES]}; then + comps=$(command timedatectl list-timezones) + elif __contains_word "$verb" ${VERBS[STANDALONE]} ${VERBS[TIME]}; then + comps='' + fi + + COMPREPLY=( $(compgen -W '$comps' -- "$cur") ) + return 0 +} +complete -F _timedatectl timedatectl + +_localectl() { + local i verb comps + 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' + + if __contains_word "$prev" $OPTS; then + case $prev in + --host|-H) + comps='' + ;; + esac + COMPREPLY=( $(compgen -W '$comps' -- "$cur") ) + return 0 + fi + + if [[ $cur = -* ]]; then + COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") ) + return 0 + fi + + local -A VERBS=( + [STANDALONE]='status list-locales list-keymaps' + [LOCALES]='set-locale' + [KEYMAPS]='set-keymap' + [X11]='set-x11-keymap' + ) + + for ((i=0; i <= COMP_CWORD; i++)); do + if __contains_word "${COMP_WORDS[i]}" ${VERBS[*]}; then + verb=${COMP_WORDS[i]} + break + fi + done + + if [[ -z $verb ]]; then + comps=${VERBS[*]} + elif __contains_word "$verb" ${VERBS[LOCALES]}; then + comps=$(command localectl list-locales) + elif __contains_word "$verb" ${VERBS[KEYMAPS]}; then + comps=$(command localectl list-keymaps) + elif __contains_word "$verb" ${VERBS[STANDALONE]} ${VERBS[X11]}; then + comps='' + fi + + COMPREPLY=( $(compgen -W '$comps' -- "$cur") ) + return 0 +} +complete -F _localectl localectl + +_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' + + if [[ $cur = -* ]]; then + COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") ) + return 0 + fi + + local -A VERBS=( + [STANDALONE]='status' + [ICONS]='set-icon-name' + [NAME]='set-hostname' + ) + + for ((i=0; i <= COMP_CWORD; i++)); do + if __contains_word "${COMP_WORDS[i]}" ${VERBS[*]}; then + verb=${COMP_WORDS[i]} + break + fi + done + + if [[ -z $verb ]]; then + comps=${VERBS[*]} + elif __contains_word "$verb" ${VERBS[STANDALONE]} ${VERBS[ICONS]} ${VERBS[NAME]}; then + comps='' + fi + + COMPREPLY=( $(compgen -W '$comps' -- "$cur") ) + return 0 +} +complete -F _hostnamectl hostnamectl + +__get_all_sysdevs() { + local -a devs=(/sys/bus/*/devices/*/ /sys/class/*/*/) + printf '%s\n' "${devs[@]%/}" +} + +_udevadm() { + local i verb comps + local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} + local OPTS='-h --help --version --debug' + + local -A VERBS=( + [INFO]='info' + [TRIGGER]='trigger' + [SETTLE]='settle' + [CONTROL]='control' + [MONITOR]='monitor' + [HWDB]='hwdb' + [TESTBUILTIN]='test-builtin' + [TEST]='test' + ) + + for ((i=0; $i <= $COMP_CWORD; i++)); do + if __contains_word "${COMP_WORDS[i]}" ${VERBS[*]} && + ! __contains_word "${COMP_WORDS[i-1]}" ${OPTS[ARG]}; then + verb=${COMP_WORDS[i]} + break + fi + done + + if [[ -z $verb && $cur = -* ]]; then + COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") ) + return 0 + fi + + if [[ -z $verb ]]; then + comps=${VERBS[*]} + + elif __contains_word "$verb" ${VERBS[INFO]}; then + if [[ $cur = -* ]]; then + comps='--help --query= --path= --name= --root --attribute-walk --export-db --cleanup-db' + else + comps=$( __get_all_sysdevs ) + fi + + elif __contains_word "$verb" ${VERBS[TRIGGER]}; then + comps='--help --verbose --dry-run --type= --action= --subsystem-match= + --subsystem-nomatch= --attr-match= --attr-nomatch= --property-match= + --tag-match= --sysname-match= --parent-match=' + + elif __contains_word "$verb" ${VERBS[SETTLE]}; then + comps='--help --timeout= --seq-start= --seq-end= --exit-if-exists= --quiet' + + elif __contains_word "$verb" ${VERBS[CONTROL]}; then + comps='--help --exit --log-priority= --stop-exec-queue --start-exec-queue + --reload --property= --children-max= --timeout=' + + elif __contains_word "$verb" ${VERBS[MONITOR]}; then + comps='--help --kernel --udev --property --subsystem-match= --tag-match=' + + elif __contains_word "$verb" ${VERBS[HWDB]}; then + comps='--help --update --test=' + + elif __contains_word "$verb" ${VERBS[TEST]}; then + if [[ $cur = -* ]]; then + comps='--help --action=' + else + comps=$( __get_all_sysdevs ) + fi + + elif __contains_word "$verb" ${VERBS[TESTBUILTIN]}; then + comps='blkid btrfs firmware hwdb input_id kmod net_id path_id usb_id uaccess' + fi + + COMPREPLY=( $(compgen -W '$comps' -- "$cur") ) + return 0 +} +complete -F _udevadm udevadm diff --git a/shell-completion/systemd-zsh-completion.zsh b/shell-completion/systemd-zsh-completion.zsh new file mode 100644 index 000000000..d5fb850cd --- /dev/null +++ b/shell-completion/systemd-zsh-completion.zsh @@ -0,0 +1,1029 @@ +#compdef systemctl loginctl journalctl hostnamectl localectl timedatectl systemd-coredumpctl udevadm systemd-analyze systemd-cat systemd-ask-password systemd-cgls systemd-cgtop systemd-delta systemd-detect-virt systemd-inhibit systemd-machine-id-setup systemd-notify systemd-nspawn systemd-tmpfiles systemd-tty-ask-password-agent + +_ctls() +{ + local curcontext="$curcontext" state lstate line + case "$service" in + systemctl) + # -s for aggregated options like -aP + _arguments -s \ + {-h,--help}'[Show help]' \ + '--version[Show package version]' \ + {-t,--type=}'[List only units of a particular type]:unit type:(automount device mount path service snapshot socket swap target timer)' \ + \*{-p,--property=}'[Show only properties by specific name]:unit property' \ + {-a,--all}'[Show all units/properties, including dead/empty ones]' \ + '--failed[Show only failed units]' \ + "--full[Don't ellipsize unit names on output]" \ + '--fail[When queueing a new job, fail if conflicting jobs are pending]' \ + '--ignore-dependencies[When queueing a new job, ignore all its dependencies]' \ + '--kill-who=[Who to send signal to]:killwho:(main control all)' \ + {-s,--signal=}'[Which signal to send]:signal:_signals' \ + {-H,--host=}'[Show information for remote host]:userathost:_hosts_or_user_at_host' \ + {-P,--privileged}'[Acquire privileges before execution]' \ + {-q,--quiet}'[Suppress output]' \ + '--no-block[Do not wait until operation finished]' \ + "--no-wall[Don't send wall message before halt/power-off/reboot]" \ + "--no-reload[When enabling/disabling unit files, don't reload daemon configuration]" \ + '--no-legend[Do not print a legend, i.e. the column headers and the footer with hints]' \ + '--no-pager[Do not pipe output into a pager]' \ + '--no-ask-password[Do not ask for system passwords]' \ + '--order[When generating graph for dot, show only order]' \ + '--require[When generating graph for dot, show only requirement]' \ + '--system[Connect to system manager]' \ + '--user[Connect to user service manager]' \ + '--global[Enable/disable unit files globally]' \ + {-f,--force}'[When enabling unit files, override existing symlinks. When shutting down, execute action immediately]' \ + '--root=[Enable unit files in the specified root directory]:directory:_directories' \ + '--runtime[Enable unit files only temporarily until next reboot]' \ + {-n,--lines=}'[Journal entries to show]:number of entries' \ + {-o,--output=}'[Change journal output mode]:modes:_outputmodes' \ + '*::systemctl command:_systemctl_command' + ;; + loginctl) + _arguments -s \ + {-h,--help}'[Show help]' \ + '--version[Show package version]' \ + \*{-p,--property=}'[Show only properties by this name]:unit property' \ + {-a,--all}'[Show all properties, including empty ones]' \ + '--kill-who=[Who to send signal to]:killwho:(main control all)' \ + {-s,--signal=}'[Which signal to send]:signal:_signals' \ + '--no-ask-password[Do not ask for system passwords]' \ + {-H,--host=}'[Show information for remote host]:userathost:_hosts_or_user_at_host' \ + {-P,--privileged}'[Acquire privileges before execution]' \ + '--no-pager[Do not pipe output into a pager]' \ + '*::loginctl command:_loginctl_command' + ;; + + hostnamectl) + _arguments -s \ + {-h,--help}'[Show this help]' \ + '--version[Show package version]' \ + '--transient[Only set transient hostname]' \ + '--static[Only set static hostname]' \ + '--pretty[Only set pretty hostname]' \ + '--no-ask-password[Do not prompt for password]' \ + {-H,--host=}'[Operate on remote host]:userathost:_hosts_or_user_at_host' \ + '*::hostnamectl commands:_hostnamectl_command' + ;; + journalctl) + _arguments -s \ + '--since=[Start showing entries newer or of the specified date]:YYYY-MM-DD HH\:MM\:SS' \ + '--until=[Stop showing entries older or of the specified date]:YYYY-MM-DD HH\:MM\:SS' \ + {-c,--cursor=}'[Start showing entries from specified cursor]:cursors:_journal_fields __CURSORS' \ + {-b,--this-boot}'[Show data only from current boot]' \ + {-u,--unit=}'[Show data only from the specified unit]:units:_journal_fields _SYSTEMD_UNIT' \ + {-p,--priority=}'[Show only messages within the specified priority range]:priority:_journal_fields PRIORITY' \ + {-f,--follow}'[Follow journal]' \ + {-n,--lines=}'[Number of journal entries to show]:integer' \ + '--no-tail[Show all lines, even in follow mode]' \ + {-o,--output=}'[Change journal output mode]:output modes:_outputmodes' \ + '--full[Show long fields in full]' \ + {-a,--all}'[Show all fields, including long and unprintable]' \ + {-q,--quiet}"[Don't show privilege warning]" \ + '--no-pager[Do not pipe output into a pager]' \ + {-m,--merge}'[Show entries from all available journals]' \ + {-D,--directory=}'[Show journal files from directory]:directories:_directories' \ + '--interval=[Time interval for changing the FSS sealing key]:time interval' \ + '--verify-key=[Specify FSS verification key]:FSS key' \ + {-h,--help}'[Show this help]' \ + '--version[Show package version]' \ + '--new-id128[Generate a new 128 Bit ID]' \ + '--header[Show journal header information]' \ + '--disk-usage[Show total disk usage]' \ + {-F,--field=}'[List all values a certain field takes]:Fields:_list_fields' \ + '--setup-keys[Generate new FSS key pair]' \ + '--verify[Verify journal file consistency]' \ + '--list-catalog[List messages in catalog]' \ + '--update-catalog[Update binary catalog database]' \ + ;; + localectl) + _arguments \ + {-h,--help}'[Show this help]' \ + '--version[Show package version]' \ + "--no-convert[Don't convert keyboard mappings]" \ + '--no-pager[Do not pipe output into a pager]' \ + '--no-ask-password[Do not prompt for password]' \ + {-H,--host=}'[Operate on remote host]:userathost:_hosts_or_user_at_host' \ + '*::localectl commands:_localectl_command' + ;; + systemd-coredumpctl) + _arguments \ + {-o,--output=}'[Write output to FILE]:output file:_files' \ + '--no-pager[Do not pipe output into a pager]' \ + {-h,--help}'[Show this help]' \ + '--version[Show package version]' \ + '*::systemd-coredumpctl commands:_systemd-coredumpctl_command' + + ;; + timedatectl) + _arguments -s \ + {-h,--help}'[Show this help]' \ + '--version[Show package version]' \ + '--adjust-system-clock[Adjust system clock when changing local RTC mode]' \ + '--no-pager[Do not pipe output into a pager]' \ + '--no-ask-password[Do not prompt for password]' \ + {-H,--host=}'[Operate on remote host]:userathost:_hosts_or_user_at_host' \ + '*::timedatectl commands:_timedatectl_command' + ;; + udevadm) + _arguments \ + '--debug[Print debug messages to stderr]' \ + '--version[Print version number]' \ + '--help[Print help text]' \ + '*::udevadm commands:_udevadm_command' + ;; + systemd-analyze) + _arguments \ + {-h,--help}'[Show help text.]' \ + '--user[Shows performance data of user sessions instead of the system manager.]' \ + '*::systemd-analyze commands:_systemd_analyze_command' + ;; + systemd-ask-password) + _arguments \ + {-h,--help}'[Show this help]' \ + '--icon=[Icon name]' \ + '--timeout=[Timeout in sec]' \ + '--no-tty[Ask question via agent even on TTY]' \ + '--accept-cached[Accept cached passwords]' \ + '--multiple[List multiple passwords if available]' + ;; + systemd-cat) + _arguments \ + {-h,--help}'[Show this help]' \ + '--version[Show package version.]' \ + {-t,--identifier=}'[Set syslog identifier.]' \ + {-p,--priority=}'[Set priority value.]:value:({0..7})' \ + '--level-prefix=[Control whether level prefix shall be parsed.]:boolean:(1 0)' \ + ':Message' + ;; + systemd-cgls) + _arguments \ + {-h,--help}'[Show this help]' \ + '--version[Show package version]' \ + '--no-pager[Do not pipe output into a pager]' \ + {-a,--all}'[Show all groups, including empty]' \ + '-k[Include kernel threads in output]' \ + ':cgroups:(cpuset cpu cpuacct memory devices freezer net_cls blkio)' + ;; + systemd-cgtop) + _arguments \ + {-h,--help}'[Show this help]' \ + '--version[Print version and exit]' \ + '(-c -m -i -t)-p[Order by path]' \ + '(-c -p -m -i)-t[Order by number of tasks]' \ + '(-m -p -i -t)-c[Order by CPU load]' \ + '(-c -p -i -t)-m[Order by memory load]' \ + '(-c -m -p -t)-i[Order by IO load]' \ + {-d,--delay=}'[Specify delay]' \ + {-n,--iterations=}'[Run for N iterations before exiting]' \ + {-b,--batch}'[Run in batch mode, accepting no input]' \ + '--depth=[Maximum traversal depth]' + ;; + systemd-delta) + _arguments \ + {-h,--help}'[Show this help]' \ + '--version[Show package version]' \ + '--no-pager[Do not pipe output into a pager]' \ + '--diff=[Show a diff when overridden files differ]:boolean:(1 0)' \ + {-t,--type=}'[Only display a selected set of override types]:types:(masked equivalent redirected overridden unchanged)' \ + ':SUFFIX:(tmpfiles.d sysctl.d systemd/system)' + ;; + systemd-detect-virt) + _arguments \ + {-h,--help}'[Show this help]' \ + '--version[Show package version]' \ + {-c,--container}'[Only detect whether we are run in a container]' \ + {-v,--vm}'[Only detect whether we are run in a VM]' \ + {-q,--quiet}"[Don't output anything, just set return value]" + ;; + systemd-inhibit) + _arguments \ + {-h,--help}'[Show this help]' \ + '--version[Show package version]' \ + '--what=[Operations to inhibit]:options:(shutdown sleep idle handle-power-key handle-suspend-key handle-hibernate-key handle-lid-switch)' \ + '--who=[A descriptive string who is inhibiting]' \ + '--why=[A descriptive string why is being inhibited]' \ + '--mode=[One of block or delay]' \ + '--list[List active inhibitors]' \ + '*:commands:_systemd_inhibit_command' + ;; + systemd-machine-id-setup) + _arguments \ + {-h,--help}'[Show this help]' \ + '--version[Show package version]' + ;; + systemd-notify) + _arguments \ + {-h,--help}'[Show this help]' \ + '--version[Show package version]' \ + '--ready[Inform the init system about service start-up completion.]' \ + '--pid=[Inform the init system about the main PID of the daemon]' \ + '--status=[Send a free-form status string for the daemon to the init systemd]' \ + '--booted[Returns 0 if the system was booted up with systemd]' \ + '--readahead=[Controls disk read-ahead operations]:arguments:(cancel done noreply)' + ;; + systemd-nspawn) + _arguments \ + {-h,--help}'[Show this help]' \ + {--directory=,-D}'[Directory to use as file system root for the namespace container. If omitted the current directory will be used.]:directories:_directories' \ + {--boot,-b}'[Automatically search for an init binary and invoke it instead of a shell or a user supplied program.]' \ + {--user=,-u}'[Run the command under specified user, create home directory and cd into it.]' \ + '--uuid=[Set the specified uuid for the container.]' \ + {--controllers=,-C}'[Makes the container appear in other hierarchies than the name=systemd:/ one. Takes a comma-separated list of controllers.]' \ + '--private-network[Turn off networking in the container. This makes all network interfaces unavailable in the container, with the exception of the loopback device.]' \ + '--read-only[Mount the root file system read only for the container.]' \ + '--capability=[List one or more additional capabilities to grant the container.]:capabilities:_systemd-nspawn' \ + "--link-journal=[Control whether the container's journal shall be made visible to the host system.]:options:(no, host, guest, auto)" \ + '-j[Equivalent to --link-journal=guest.]' + ;; + systemd-tmpfiles) + _arguments \ + '--create[Create, set ownership/permissions based on the config files.]' \ + '--clean[Clean up all files and directories with an age parameter configured.]' \ + '--remove[All files and directories marked with r, R in the configuration files are removed.]' \ + '--prefix=[Only apply rules that apply to paths with the specified prefix.]' \ + '--help[Prints a short help text and exits.]' \ + '*::files:_files' + ;; + systemd-tty-ask-password-agent) + _arguments \ + {-h,--help}'[Prints a short help text and exits.]' \ + '--version[Prints a short version string and exits.]' \ + '--list[Lists all currently pending system password requests.]' \ + '--query[Process all currently pending system password requests by querying the user on the calling TTY.]' \ + '--watch[Continuously process password requests.]' \ + '--wall[Forward password requests to wall(1).]' \ + '--plymouth[Ask question with plymouth(8).]' \ + '--console[Ask question on /dev/console.]' + ;; + *) _message 'eh?' ;; + esac +} + +_systemd-nspawn(){ + local -a _caps + _caps=( 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 ) + _values -s , 'capabilities' "$_caps[@]" +} + +_systemd_inhibit_command(){ + if (( CURRENT == 1 )); then + compset -q + _normal + else + local n=${words[(b:2:i)[^-]*]} + if (( n <= CURRENT )); then + compset -n $n + _alternative \ + 'files:file:_files' \ + 'commands:command:_normal' && return 0 + fi + _default + fi + +} + +_systemd_analyze_command(){ + local -a _systemd_analyze_cmds + _systemd_analyze_cmds=( + 'time:Print the time taken to start' + 'blame:prints a list of all running units, ordered by the time they took to initialize' + 'plot:prints an SVG graphic detailing which system services have been started at what time' + ) + + if (( CURRENT == 1 )); then + _describe "options" _systemd_analyze_cmds + else + _message "no more options" + fi +} + +_hosts_or_user_at_host() +{ + _alternative \ + 'users-hosts:: _user_at_host' \ + 'hosts:: _hosts' +} + +_outputmodes() { + local -a _output_opts + _output_opts=(short short-monotonic verbose export json json-pretty json-see cat) + _describe -t output 'output mode' _output_opts || compadd "$@" +} + + +(( $+functions[_systemctl_command] )) || _systemctl_command() +{ + local -a _systemctl_cmds + _systemctl_cmds=( + "list-units:List units" + "start:Start (activate) one or more units" + "stop:Stop (deactivate) one or more units" + "reload:Reload one or more units" + "restart:Start or restart one or more units" + "condrestart:Restart one or more units if active" + "try-restart:Restart one or more units if active" + "reload-or-restart:Reload one or more units if possible, otherwise start or restart" + "force-reload:Reload one or more units if possible, otherwise restart if active" + "hibernate:Hibernate the system" + "hybrid-sleep:Hibernate and suspend the system" + "reload-or-try-restart:Reload one or more units if possible, otherwise restart if active" + "isolate:Start one unit and stop all others" + "kill:Send signal to processes of a unit" + "is-active:Check whether units are active" + "is-failed:Check whether units are failed" + "status:Show runtime status of one or more units" + "show:Show properties of one or more units/jobs or the manager" + "reset-failed:Reset failed state for all, one, or more units" + "load:Load one or more units" + "list-unit-files:List installed unit files" + "enable:Enable one or more unit files" + "disable:Disable one or more unit files" + "reenable:Reenable one or more unit files" + "preset:Enable/disable one or more unit files based on preset configuration" + "mask:Mask one or more units" + "unmask:Unmask one or more units" + "link:Link one or more units files into the search path" + "is-enabled:Check whether unit files are enabled" + "list-jobs:List jobs" + "cancel:Cancel all, one, or more jobs" + "dump:Dump server status" + "dot:Dump dependency graph for dot(1)" + "snapshot:Create a snapshot" + "delete:Remove one or more snapshots" + "show-environment:Dump environment" + "set-environment:Set one or more environment variables" + "unset-environment:Unset one or more environment variables" + "daemon-reload:Reload systemd manager configuration" + "daemon-reexec:Reexecute systemd manager" + "default:Enter system default mode" + "rescue:Enter system rescue mode" + "emergency:Enter system emergency mode" + "halt:Shut down and halt the system" + "suspend:Suspend the system" + "poweroff:Shut down and power-off the system" + "reboot:Shut down and reboot the system" + "kexec:Shut down and reboot the system with kexec" + "exit:Ask for user instance termination" + ) + + if (( CURRENT == 1 )); then + _describe -t commands 'systemctl command' _systemctl_cmds || compadd "$@" + else + local curcontext="$curcontext" + + cmd="${${_systemctl_cmds[(r)$words[1]:*]%%:*}}" + # Deal with any aliases + case $cmd in + condrestart) cmd="try-restart";; + force-reload) cmd="reload-or-try-restart";; + esac + + if (( $#cmd )); then + curcontext="${curcontext%:*:*}:systemctl-${cmd}:" + + local update_policy + zstyle -s ":completion:${curcontext}:" cache-policy update_policy + if [[ -z "$update_policy" ]]; then + zstyle ":completion:${curcontext}:" cache-policy _systemctl_caching_policy + fi + + _call_function ret _systemctl_$cmd || _message 'no more arguments' + else + _message "unknown systemctl command: $words[1]" + fi + return ret + fi +} + +__systemctl() +{ + systemctl --full --no-legend --no-pager "$@" +} + + +# Fills the unit list +_systemctl_all_units() +{ + if ( [[ ${+_sys_all_units} -eq 0 ]] || _cache_invalid SYS_ALL_UNITS ) && + ! _retrieve_cache SYS_ALL_UNITS; + then + _sys_all_units=( $(__systemctl list-units --all | { while read a b; do echo "$a"; done; }) ) + _store_cache SYS_ALL_UNITS _sys_all_units + fi +} + +# Fills the unit list including all file units +_systemctl_really_all_units() +{ + local -a all_unit_files; + local -a really_all_units; + if ( [[ ${+_sys_really_all_units} -eq 0 ]] || _cache_invalid SYS_REALLY_ALL_UNITS ) && + ! _retrieve_cache SYS_REALLY_ALL_UNITS; + then + all_unit_files=( $(__systemctl list-unit-files | { while read a b; do echo "$a"; done; }) ) + _systemctl_all_units + really_all_units=($_sys_all_units $all_unit_files) + _sys_really_all_units=(${(u)really_all_units}) + _store_cache SYS_REALLY_ALL_UNITS _sys_really_all_units + fi +} + +_filter_units_by_property() { + local property=$1 value=$2 ; shift ; shift + local -a units ; units=($*) + local prop unit + for ((i=1; $i <= ${#units[*]}; i++)); do + # FIXME: "Failed to issue method call: Unknown unit" errors are ignored for + # now (related to DBUS_ERROR_UNKNOWN_OBJECT). in the future, we need to + # revert to calling 'systemctl show' once for all units, which is way + # faster + unit=${units[i]} + prop=${(f)"$(_call_program units "$service show --no-pager --property="$property" ${unit} 2>/dev/null")"} + if [[ "${prop}" = "$property=$value" ]]; then + echo "${unit}" + fi + done +} + +_systemctl_active_units() {_sys_active_units=( $(__systemctl list-units | { while read a b; do echo "$a"; done; }) )} +_systemctl_inactive_units(){_sys_inactive_units=($(__systemctl list-units --all | { while read a b c d; do [[ $c == "inactive" ]] && echo "$a"; done; }) )} +_systemctl_failed_units() {_sys_failed_units=( $(__systemctl list-units --failed | { while read a b; do echo "$a"; done; }) )} +_systemctl_enabled_units() {_sys_enabled_units=( $(__systemctl list-unit-files | { while read a b; do [[ $b == "enabled" ]] && echo "$a"; done; }) )} +_systemctl_disabled_units(){_sys_disabled_units=($(__systemctl list-unit-files | { while read a b; do [[ $b == "disabled" ]] && echo "$a"; done; }) )} +_systemctl_masked_units() {_sys_masked_units=( $(__systemctl list-unit-files | { while read a b; do [[ $b == "masked" ]] && echo "$a"; done; }) )} + +# Completion functions for ALL_UNITS +for fun in is-active is-failed is-enabled status show mask preset ; do + (( $+functions[_systemctl_$fun] )) || _systemctl_$fun() + { + _systemctl_really_all_units + compadd "$@" -a - _sys_really_all_units + } +done + +# Completion functions for ENABLED_UNITS +for fun in disable reenable ; do + (( $+functions[_systemctl_$fun] )) || _systemctl_$fun() + { + _systemctl_enabled_units + compadd "$@" -a - _sys_enabled_units + } +done + +# Completion functions for DISABLED_UNITS +(( $+functions[_systemctl_enable] )) || _systemctl_enable() +{ + _systemctl_disabled_units + compadd "$@" -a - _sys_disabled_units +} + +# Completion functions for FAILED_UNITS +(( $+functions[_systemctl_reset-failed] )) || _systemctl_reset-failed() +{ + _systemctl_failed_units + compadd "$@" -a - _sys_failed_units || _message "no failed unit found" +} + +# Completion functions for STARTABLE_UNITS +(( $+functions[_systemctl_start] )) || _systemctl_start() +{ + _systemctl_inactive_units + compadd "$@" -a - _sys_inactive_units +} + +# Completion functions for STOPPABLE_UNITS +for fun in stop kill try-restart condrestart ; do + (( $+functions[_systemctl_$fun] )) || _systemctl_$fun() + { + _systemctl_active_units + compadd "$@" - $( _filter_units_by_property CanStop yes \ + ${_sys_active_units[*]} ) + } +done + +# Completion functions for ISOLATABLE_UNITS +(( $+functions[_systemctl_isolate] )) || _systemctl_isolate() +{ + _systemctl_all_units + compadd "$@" - $( _filter_units_by_property AllowIsolate yes \ + ${_sys_all_units[*]} ) +} + +# Completion functions for RELOADABLE_UNITS +for fun in reload reload-or-try-restart force-reload ; do + (( $+functions[_systemctl_$fun] )) || _systemctl_$fun() + { + _systemctl_active_units + compadd "$@" - $( _filter_units_by_property CanReload yes \ + ${_sys_active_units[*]} ) + } +done + +# Completion functions for RESTARTABLE_UNITS +for fun in restart reload-or-restart ; do + (( $+functions[_systemctl_$fun] )) || _systemctl_$fun() + { + _systemctl_all_units + compadd "$@" - $( _filter_units_by_property CanStart yes \ + ${_sys_all_units[*]} | while read line; do \ + [[ "$line" =~ \.(device|snapshot|socket|timer)$ ]] || echo "$line"; \ + done ) + } +done + +# Completion functions for MASKED_UNITS +(( $+functions[_systemctl_unmask] )) || _systemctl_unmask() +{ + _systemctl_masked_units + compadd "$@" -a - _sys_masked_units || _message "no masked unit found" +} + +# Completion functions for JOBS +(( $+functions[_systemctl_cancel] )) || _systemctl_cancel() +{ + compadd "$@" - $(__systemctl list-jobs \ + | cut -d' ' -f1 2>/dev/null ) || _message "no job found" +} + +# Completion functions for SNAPSHOTS +(( $+functions[_systemctl_delete] )) || _systemctl_delete() +{ + compadd "$@" - $(__systemctl list-units --type snapshot --all \ + | cut -d' ' -f1 2>/dev/null ) || _message "no snampshot found" +} + +# Completion functions for ENVS +for fun in set-environment unset-environment ; do + (( $+functions[_systemctl_$fun] )) || _systemctl_$fun() + { + local fun=$0 ; fun=${fun##_systemctl_} + local suf + if [[ "${fun}" = "set-environment" ]]; then + suf='-S=' + fi + + compadd "$@" ${suf} - $(systemctl show-environment \ + | while read line; do echo "${line%%\=}";done ) + } +done + +(( $+functions[_systemctl_link] )) || _systemctl_link() { _files } + +# no systemctl completion for: +# [STANDALONE]='daemon-reexec daemon-reload default dot dump +# emergency exit halt kexec list-jobs list-units +# list-unit-files poweroff reboot rescue show-environment' +# [NAME]='snapshot load' + +_systemctl_caching_policy() +{ + local _sysunits + local -a oldcache + + # rebuild if cache is more than a day old + oldcache=( "$1"(mh+1) ) + (( $#oldcache )) && return 0 + + _sysunits=($(__systemctl --all | cut -d' ' -f1)) + + if (( $#_sysunits )); then + for unit in $_sysunits; do + [[ "$unit" -nt "$1" ]] && return 0 + done + fi + + return 1 +} + +_list_fields() { + local -a journal_fields + journal_fields=(MESSAGE{,_ID} PRIORITY CODE_{FILE,LINE,FUNC} + ERRNO SYSLOG_{FACILITY,IDENTIFIER,PID} + _{P,U,G}ID _COMM _EXE _CMDLINE + _AUDIT_{SESSION,LOGINUID} + _SYSTEMD_{CGROUP,SESSION,UNIT,OWNER_UID} + _SELINUX_CONTEXT _SOURCE_REALTIME_TIMESTAMP + _{BOOT,MACHINE}_ID _HOSTNAME _TRANSPORT + _KERNEL_{DEVICE,SUBSYSTEM} + _UDEV_{SYSNAME,DEVNODE,DEVLINK} + __CURSOR __{REALTIME,MONOTONIC}_TIMESTAMP) + _describe 'possible fields' journal_fields +} + +_journal_fields() { + local -a _fields cmd + cmd=("journalctl" "-F ${@[-1]}" "2>/dev/null" ) + _fields=( ${(f)"$(_call_program fields $cmd[@])"} ) + typeset -U _fields + _describe 'possible values' _fields +} + + +_loginctl_all_sessions(){_sys_all_sessions=($(loginctl list-sessions | { while read a b; do echo "$a"; done; }) )} +_loginctl_all_users() {_sys_all_users=( $(loginctl list-users | { while read a b; do echo "$a"; done; }) )} +_loginctl_all_seats() {_sys_all_seats=( $(loginctl list-seats | { while read a b; do echo "$a"; done; }) )} + +# Completion functions for SESSIONS +for fun in session-status show-session activate lock-session unlock-session terminate-session kill-session ; do + (( $+functions[_loginctl_$fun] )) || _loginctl_$fun() + { + _loginctl_all_sessions + compadd "$@" -a - _sys_all_sessions + } +done + +# Completion functions for USERS +for fun in user-status show-user enable-linger disable-linger terminate-user kill-user ; do + (( $+functions[_loginctl_$fun] )) || _loginctl_$fun() + { + _loginctl_all_users + compadd "$@" -a - _sys_all_users + } +done + +# Completion functions for SEATS +(( $+functions[_loginctl_seats] )) || _loginctl_seats() +{ + _loginctl_all_seats + compadd "$@" -a - _sys_all_seats +} +for fun in seat-status show-seat terminate-seat ; do + (( $+functions[_loginctl_$fun] )) || _loginctl_$fun() + { _loginctl_seats } +done + +# Completion functions for ATTACH +(( $+functions[_loginctl_attach] )) || _loginctl_attach() +{ + _loginctl_all_seats + + _arguments -w -C -S -s \ + ':seat:_loginctl_seats' \ + '*:device:_files' +} + +# no loginctl completion for: +# [STANDALONE]='list-sessions list-users list-seats flush-devices' + +(( $+functions[_loginctl_command] )) || _loginctl_command() +{ + local -a _loginctl_cmds + _loginctl_cmds=( + "list-sessions:List sessions" + "session-status:Show session status" + "show-session:Show properties of one or more sessions" + "activate:Activate a session" + "lock-session:Screen lock one or more sessions" + "unlock-session:Screen unlock one or more sessions" + "terminate-session:Terminate one or more sessions" + "kill-session:Send signal to processes of a session" + "list-users:List users" + "user-status:Show user status" + "show-user:Show properties of one or more users" + "enable-linger:Enable linger state of one or more users" + "disable-linger:Disable linger state of one or more users" + "terminate-user:Terminate all sessions of one or more users" + "kill-user:Send signal to processes of a user" + "list-seats:List seats" + "seat-status:Show seat status" + "show-seat:Show properties of one or more seats" + "attach:Attach one or more devices to a seat" + "flush-devices:Flush all device associations" + "terminate-seat:Terminate all sessions on one or more seats" + ) + + if (( CURRENT == 1 )); then + _describe -t commands 'loginctl command' _loginctl_cmds || compadd "$@" + else + local curcontext="$curcontext" + + cmd="${${_loginctl_cmds[(r)$words[1]:*]%%:*}}" + + if (( $#cmd )); then + curcontext="${curcontext%:*:*}:loginctl-${cmd}:" + + _call_function ret _loginctl_$cmd || _message 'no more arguments' + else + _message "unknown loginctl command: $words[1]" + fi + return ret + fi +} + +_hostnamectl_command() { + local -a _hostnamectl_cmds + _hostnamectl_cmds=( + "status:Show current hostname settings" + "set-hostname:Set system hostname" + "set-icon-name:Set icon name for host" + ) + if (( CURRENT == 1 )); then + _describe -t commands 'hostnamectl commands' _hostnamectl_cmds || compadd "$@" + else + local curcontext="$curcontext" + cmd="${${_hostnamectl_cmds[(r)$words[1]:*]%%:*}}" + if (( $#cmd )); then + [[ $cmd == status ]] && msg="no options" || msg="options for $cmd" + _message "$msg" + else + _message "unknown hostnamectl command: $words[1]" + fi + fi +} + +_localectl_set-locale() { + local -a _confs _locales + local expl suf + _locales=( ${(f)"$(_call_program locales "$service" list-locales)"} ) + _confs=( ${${(f)"$(_call_program confs "locale 2>/dev/null")"}%\=*} ) + if [[ -prefix 1 *\= ]]; then + local conf=${PREFIX%%\=*} + compset -P1 '*=' + _wanted locales expl "locales configs" \ + _combination localeconfs confs=$conf locales "$@" - + else + compadd -S '=' $_confs + fi +} + +_localectl_set-keymap() { + local -a _keymaps + _keymaps=( ${(f)"$(_call_program locales "$service" list-keymaps)"} ) + if (( CURRENT <= 3 )); then + _describe keymaps _keymaps + else + _message "no more options" + fi +} + +_localectl_set-x11-keymap() { + if (( $+commands[pkg-config] )); then + local -a _file _layout _model _variant _options + local _xorg_lst + _xorg_lst=${"$($commands[pkg-config] xkeyboard-config --variable=xkb_base)"} + _file=( ${(ps:\n\!:)"$(<$_xorg_lst/rules/xorg.lst)"} ) + _layout=( ${${${(M)${(f)_file[1]}:# *}# }%% *} ) + _model=( ${${${(M)${(f)_file[2]}:# *}# }%% *} ) + _variant=( ${${${(M)${(f)_file[3]}:# *}# }%% *} ) + _options=( ${${${(M)${(f)_file[4]}:# *}# }%% *} ) + #_layout=( ${(f)"$( echo $_file[1] | awk '/^ / {print $1}' )"} ) + #_model=( ${(f)"$(echo $_file[2] | awk '/^ / {print $1}')"} ) + #_variant=( ${(f)"$(echo $_file[3] | awk '/^ / {print $1}')"} ) + #_options=( ${(f)"$(echo ${_file[4]//:/\\:} | awk '/^ / {print $1}')"} ) + + case $CURRENT in + 2) _describe layouts _layout ;; + 3) _describe models _model;; + 4) _describe variants _variant;; + 5) _describe options _options;; + *) _message "no more options" + esac + fi +} + + +_localectl_command() { + local -a _localectl_cmds + _localectl_cmds=( + 'status:Show current locale settings' + 'set-locale:Set system locale' + 'list-locales:Show known locales' + 'set-keymap:Set virtual console keyboard mapping' + 'list-keymaps:Show known virtual console keyboard mappings' + 'set-x11-keymap:Set X11 keyboard mapping' + ) + if (( CURRENT == 1 )); then + _describe -t commands 'localectl command' _localectl_cmds + else + local curcontext="$curcontext" + cmd="${${_localectl_cmds[(r)$words[1]:*]%%:*}}" + if (( $+functions[_localectl_$cmd] )); then + _localectl_$cmd + else + _message "no more options" + fi + fi +} + +_timedatectl_set-timezone(){ + local -a _timezones + _timezones=( ${(f)"$(_call_program timezones "${service}" list-timezones)"} ) + compadd "$_timezones[@]" +} + +_timedatectl_set-time(){ + _message "YYYY-MM-DD HH:MM:SS" +} + +_timedatectl_set-local-rtc(){ + local -a _options + _options=( + '0:Maintain RTC in universal time' + '1:Maintain RTC in local time' + ) + _describe options _options +} + +_timedatectl_set-ntp(){ + local -a _options + _options=( + '0:Disable NTP based network time configuration' + '1:Enable NTP based network time configuration' + ) + _describe options _options +} + +_timedatectl_command(){ + local -a _timedatectl_cmds + _timedatectl_cmds=( + 'status:Show current time settings' + 'set-time:Set system time' + 'set-timezone:Set system timezone' + 'list-timezones:Show known timezones' + 'set-local-rtc:Control whether RTC is in local time' + 'set-ntp:Control whether NTP is enabled' + ) + if (( CURRENT == 1 )); then + _describe -t commands 'timedatectl command' _timedatectl_cmds + else + local curcontext="$curcontext" + cmd="${${_timedatectl_cmds[(r)$words[1]:*]%%:*}}" + if (( $#cmd )); then + if (( $+functions[_timedatectl_$cmd] )); then + _timedatectl_$cmd + else + _message "no more options" + fi + else + _message "unknown timedatectl command: $words[1]" + fi + fi +} +_systemd-coredumpctl_command(){ + local -a _systemd_coredumpctl_cmds + _systemd_coredumpctl_cmds=( + 'list:List available coredumps' + 'dump:Print coredump to std' + ) + if (( CURRENT == 1 )); then + _describe -t commands 'systemd-coredumpctl command' _systemd_coredumpctl_cmds + else + local curcontext="$curcontext" + local -a dumps + cmd="${${_systemd_coredumpctl_cmds[(r)$words[1]:*]%%:*}}" + if (( $#cmd )); then + dumps=( "${(f)$(_call_program dumps "systemd-coredumpctl list 2>/dev/null")}" ) + if [[ -n "$dumps" ]]; then + compadd "${dumps[@]}" + else + _message "no coredumps" + fi + else + _message "no more options" + fi + + fi + +} + +_udevadm_info(){ + _arguments \ + '--query=[Query the database for specified type of device data. It needs the --path or --name to identify the specified device.]:type:(name symlink path property all)' \ + '--path=[The devpath of the device to query.]:sys files:_files -P /sys/ -W /sys' \ + '--name=[The name of the device node or a symlink to query]:device files:_files -P /dev/ -W /dev' \ + '--root[Print absolute paths in name or symlink query.]' \ + '--attribute-walk[Print all sysfs properties of the specified device that can be used in udev rules to match the specified device]' \ + '--export[Print output as key/value pairs.]' \ + '--export-prefix=[Add a prefix to the key name of exported values.]:prefix' \ + '--device-id-of-file=[Print major/minor numbers of the underlying device, where the file lives on.]:files:_udevadm_mounts' \ + '--export-db[Export the content of the udev database.]' \ + '--cleanup-db[Cleanup the udev database.]' +} + +_udevadm_trigger(){ + _arguments \ + '--verbose[Print the list of devices which will be triggered.]' \ + '--dry-run[Do not actually trigger the event.]' \ + '--type=[Trigger a specific type of devices.]:types:(devices subsystems failed)' \ + '--action=[Type of event to be triggered.]:actions:(add change remove)' \ + '--subsystem-match=[Trigger events for devices which belong to a matching subsystem.]' \ + '--subsystem-nomatch=[Do not trigger events for devices which belong to a matching subsystem.]' \ + '--attr-match=attribute=[Trigger events for devices with a matching sysfs attribute.]' \ + '--attr-nomatch=attribute=[Do not trigger events for devices with a matching sysfs attribute.]' \ + '--property-match=[Trigger events for devices with a matching property value.]' \ + '--tag-match=property[Trigger events for devices with a matching tag.]' \ + '--sysname-match=[Trigger events for devices with a matching sys device name.]' \ + '--parent-match=[Trigger events for all children of a given device.]' +} + +_udevadm_settle(){ + _arguments \ + '--timeout=[Maximum number of seconds to wait for the event queue to become empty.]' \ + '--seq-start=[Wait only for events after the given sequence number.]' \ + '--seq-end=[Wait only for events before the given sequence number.]' \ + '--exit-if-exists=[Stop waiting if file exists.]:files:_files' \ + '--quiet[Do not print any output, like the remaining queue entries when reaching the timeout.]' \ + '--help[Print help text.]' +} + +_udevadm_control(){ + _arguments \ + '--exit[Signal and wait for systemd-udevd to exit.]' \ + '--log-priority=[Set the internal log level of systemd-udevd.]:priorities:(err info debug)' \ + '--stop-exec-queue[Signal systemd-udevd to stop executing new events. Incoming events will be queued.]' \ + '--start-exec-queue[Signal systemd-udevd to enable the execution of events.]' \ + '--reload[Signal systemd-udevd to reload the rules files and other databases like the kernel module index.]' \ + '--property=[Set a global property for all events.]' \ + '--children-max=[Set the maximum number of events.]' \ + '--timeout=[The maximum number of seconds to wait for a reply from systemd-udevd.]' \ + '--help[Print help text.]' +} + +_udevadm_monitor(){ + _arguments \ + '--kernel[Print the kernel uevents.]' \ + '--udev[Print the udev event after the rule processing.]' \ + '--property[Also print the properties of the event.]' \ + '--subsystem-match=[Filter events by subsystem[/devtype].]' \ + '--tag-match=[Filter events by property.]' \ + '--help[Print help text.]' +} + +_udevadm_test(){ + _arguments \ + '--action=[The action string.]:actions:(add change remove)' \ + '--subsystem=[The subsystem string.]' \ + '--help[Print help text.]' \ + '*::devpath:_files -P /sys/ -W /sys' +} + +_udevadm_test-builtin(){ + if (( CURRENT == 2 )); then + _arguments \ + '--help[Print help text]' \ + '*::builtins:(blkid btrfs firmware hwdb input_id kmod path_id usb_id uaccess)' + elif (( CURRENT == 3 )); then + _arguments \ + '--help[Print help text]' \ + '*::syspath:_files -P /sys -W /sys' + else + _arguments \ + '--help[Print help text]' + fi +} + +_udevadm_mounts(){ + local dev_tmp dpath_tmp mp_tmp mline + + tmp=( "${(@f)$(< /etc/mtab)}" ) + dev_tmp=( "${(@)${(@)tmp%% *}:#none}" ) + mp_tmp=( "${(@)${(@)tmp#* }%% *}" ) + + local MATCH + mp_tmp=("${(@q)mp_tmp//(#m)\\[0-7](#c3)/${(#)$(( 8#${MATCH[2,-1]} ))}}") + dpath_tmp=( "${(@Mq)dev_tmp:#/*}" ) + dev_tmp=( "${(@q)dev_tmp:#/*}" ) + + _alternative \ + 'device-paths: device path:compadd -a dpath_tmp' \ + 'directories:mount point:compadd -a mp_tmp' +} + + +_udevadm_command(){ + local -a _udevadm_cmds + _udevadm_cmds=( + 'info:query sysfs or the udev database' + 'trigger:request events from the kernel' + 'settle:wait for the event queue to finish' + 'control:control the udev daemon' + 'monitor:listen to kernel and udev events' + 'test:test an event run' + 'test-builtin:test a built-in command' + ) + + if ((CURRENT == 1)); then + _describe -t commands 'udevadm commands' _udevadm_cmds + else + local curcontext="$curcontext" + cmd="${${_udevadm_cmds[(r)$words[1]:*]%%:*}}" + if (($#cmd)); then + if (( $+functions[_udevadm_$cmd] )); then + _udevadm_$cmd + else + _message "no options for $cmd" + fi + else + _message "no more options" + fi + fi +} + +_ctls "$@" + +#vim: set ft=zsh sw=4 ts=4 et diff --git a/src/.gitignore b/src/.gitignore new file mode 100644 index 000000000..afabb6a5d --- /dev/null +++ b/src/.gitignore @@ -0,0 +1,6 @@ +load-fragment-gperf-nulstr.c +load-fragment-gperf.c +load-fragment-gperf.gperf +org.freedesktop.systemd1.policy.in +org.freedesktop.systemd1.policy +99-systemd.rules diff --git a/src/Makefile b/src/Makefile new file mode 100644 index 000000000..9d0750519 --- /dev/null +++ b/src/Makefile @@ -0,0 +1,28 @@ +# 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 . + +# This file is a dirty trick to simplify compilation from within +# emacs. This file is not intended to be distributed. So, don't touch +# it, even better ignore it! + +all: + $(MAKE) -C .. + +clean: + $(MAKE) -C .. clean + +.PHONY: all clean diff --git a/src/ac-power/Makefile b/src/ac-power/Makefile new file mode 120000 index 000000000..d0b0e8e00 --- /dev/null +++ b/src/ac-power/Makefile @@ -0,0 +1 @@ +../Makefile \ No newline at end of file diff --git a/src/ac-power/ac-power.c b/src/ac-power/ac-power.c new file mode 100644 index 000000000..bd1b6ecc7 --- /dev/null +++ b/src/ac-power/ac-power.c @@ -0,0 +1,37 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include "util.h" + +int main(int argc, char *argv[]) { + int r; + + /* This is mostly intended to be used for scripts which want + * to detect whether AC power is plugged in or not. */ + + r = on_ac_power(); + if (r < 0) { + log_error("Failed to read AC status: %s", strerror(-r)); + return EXIT_FAILURE; + } + + return r != 0 ? EXIT_SUCCESS : EXIT_FAILURE; +} diff --git a/src/analyze/.gitignore b/src/analyze/.gitignore new file mode 100644 index 000000000..752ea236c --- /dev/null +++ b/src/analyze/.gitignore @@ -0,0 +1 @@ +/systemd-analyze diff --git a/src/analyze/Makefile b/src/analyze/Makefile new file mode 120000 index 000000000..d0b0e8e00 --- /dev/null +++ b/src/analyze/Makefile @@ -0,0 +1 @@ +../Makefile \ No newline at end of file diff --git a/src/analyze/systemd-analyze.in b/src/analyze/systemd-analyze.in new file mode 100755 index 000000000..26a9f7b57 --- /dev/null +++ b/src/analyze/systemd-analyze.in @@ -0,0 +1,310 @@ +#!@PYTHON_BINARY@ + +import sys, os +import argparse +from gi.repository import Gio +try: + import cairo +except ImportError: + cairo = None + +def acquire_time_data(): + manager = Gio.DBusProxy.new_for_bus_sync(bus, Gio.DBusProxyFlags.NONE, + None, 'org.freedesktop.systemd1', '/org/freedesktop/systemd1', 'org.freedesktop.systemd1.Manager', None) + units = manager.ListUnits() + + l = [] + + for i in units: + if i[5] != "": + continue + + properties = Gio.DBusProxy.new_for_bus_sync(bus, Gio.DBusProxyFlags.NONE, + None, 'org.freedesktop.systemd1', i[6], 'org.freedesktop.DBus.Properties', None) + + ixt = properties.Get('(ss)', 'org.freedesktop.systemd1.Unit', 'InactiveExitTimestampMonotonic') + aet = properties.Get('(ss)', 'org.freedesktop.systemd1.Unit', 'ActiveEnterTimestampMonotonic') + axt = properties.Get('(ss)', 'org.freedesktop.systemd1.Unit', 'ActiveExitTimestampMonotonic') + iet = properties.Get('(ss)', 'org.freedesktop.systemd1.Unit', 'InactiveEnterTimestampMonotonic') + + l.append((str(i[0]), ixt, aet, axt, iet)) + + return l + +def acquire_start_time(): + properties = Gio.DBusProxy.new_for_bus_sync(bus, Gio.DBusProxyFlags.NONE, + None, 'org.freedesktop.systemd1', '/org/freedesktop/systemd1', 'org.freedesktop.DBus.Properties', None) + + # Note that the firmware/loader times are returned as positive + # values but are actually considered negative from the point + # in time of kernel initialization. Also, the monotonic kernel + # time will always be 0 since that's the epoch of the + # monotonic clock. Since we want to know whether the kernel + # timestamp is set at all we will instead ask for the realtime + # clock for this timestamp. + + firmware_time = properties.Get('(ss)', 'org.freedesktop.systemd1.Manager', 'FirmwareTimestampMonotonic') + loader_time = properties.Get('(ss)', 'org.freedesktop.systemd1.Manager', 'LoaderTimestampMonotonic') + kernel_time = properties.Get('(ss)', 'org.freedesktop.systemd1.Manager', 'KernelTimestamp') + initrd_time = properties.Get('(ss)', 'org.freedesktop.systemd1.Manager', 'InitRDTimestampMonotonic') + userspace_time = properties.Get('(ss)', 'org.freedesktop.systemd1.Manager', 'UserspaceTimestampMonotonic') + finish_time = properties.Get('(ss)', 'org.freedesktop.systemd1.Manager', 'FinishTimestampMonotonic') + + if finish_time == 0: + sys.exit("Bootup is not yet finished. Please try again later.") + + assert firmware_time >= loader_time + assert initrd_time <= userspace_time + assert userspace_time <= finish_time + + return firmware_time, loader_time, kernel_time, initrd_time, userspace_time, finish_time + +def draw_box(context, j, k, l, m, r = 0, g = 0, b = 0): + context.save() + context.set_source_rgb(r, g, b) + context.rectangle(j, k, l, m) + context.fill() + context.restore() + +def draw_text(context, x, y, text, size = 12, r = 0, g = 0, b = 0, vcenter = 0.5, hcenter = 0.5): + context.save() + + context.set_source_rgb(r, g, b) + context.select_font_face("Sans", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL) + context.set_font_size(size) + + if vcenter or hcenter: + x_bearing, y_bearing, width, height = context.text_extents(text)[:4] + + if hcenter: + x = x - width*hcenter - x_bearing + + if vcenter: + y = y - height*vcenter - y_bearing + + context.move_to(x, y) + context.show_text(text) + + context.restore() + +def time(): + + firmware_time, loader_time, kernel_time, initrd_time, userspace_time, finish_time = acquire_start_time() + + sys.stdout.write("Startup finished in ") + + if firmware_time > 0: + sys.stdout.write("%lums (firmware) + " % ((firmware_time - loader_time) / 1000)) + if loader_time > 0: + sys.stdout.write("%lums (loader) + " % (loader_time / 1000)) + if initrd_time > 0: + sys.stdout.write("%lums (kernel) + %lums (initrd) + " % (initrd_time / 1000, (userspace_time - initrd_time) / 1000)) + elif kernel_time > 0: + sys.stdout.write("%lums (kernel) + " % (userspace_time / 1000)) + + sys.stdout.write("%lums (userspace) " % ((finish_time - userspace_time) / 1000)) + + if kernel_time > 0: + sys.stdout.write("= %lums\n" % ((firmware_time + finish_time) / 1000)) + else: + sys.stdout.write("= %lums\n" % ((finish_time - userspace_time) / 1000)) + +def blame(): + + data = acquire_time_data() + s = sorted(data, key = lambda i: i[2] - i[1], reverse = True) + + for name, ixt, aet, axt, iet in s: + + if ixt <= 0 or aet <= 0: + continue + + if aet <= ixt: + continue + + sys.stdout.write("%6lums %s\n" % ((aet - ixt) / 1000, name)) + +def plot(): + if cairo is None: + sys.exit("Failed to initilize python-cairo required for 'plot' verb.") + firmware_time, loader_time, kernel_time, initrd_time, userspace_time, finish_time = acquire_start_time() + data = acquire_time_data() + s = sorted(data, key = lambda i: i[1]) + + # Account for kernel and initramfs bars if they exist + if initrd_time > 0: + count = 3 + else: + count = 2 + + for name, ixt, aet, axt, iet in s: + + if (ixt >= userspace_time and ixt <= finish_time) or \ + (aet >= userspace_time and aet <= finish_time) or \ + (axt >= userspace_time and axt <= finish_time): + count += 1 + + border = 100 + bar_height = 20 + bar_space = bar_height * 0.1 + + # 1000px = 10s, 1px = 10ms + width = finish_time/10000 + border*2 + height = count * (bar_height + bar_space) + border * 2 + + if width < 1000: + width = 1000 + + surface = cairo.SVGSurface(sys.stdout, width, height) + context = cairo.Context(surface) + + draw_box(context, 0, 0, width, height, 1, 1, 1) + + context.translate(border + 0.5, border + 0.5) + + context.save() + context.set_line_width(1) + context.set_source_rgb(0.7, 0.7, 0.7) + + for x in range(0, int(finish_time/10000) + 100, 100): + context.move_to(x, 0) + context.line_to(x, height-border*2) + + context.move_to(0, 0) + context.line_to(width-border*2, 0) + + context.move_to(0, height-border*2) + context.line_to(width-border*2, height-border*2) + + context.stroke() + context.restore() + + osrel = "Linux" + if os.path.exists("/etc/os-release"): + for line in open("/etc/os-release"): + if line.startswith('PRETTY_NAME='): + osrel = line[12:] + osrel = osrel.strip('\"\n') + break + + banner = "{} {} ({} {}) {}".format(osrel, *(os.uname()[1:5])) + draw_text(context, 0, -15, banner, hcenter = 0, vcenter = 1) + + for x in range(0, int(finish_time/10000) + 100, 100): + draw_text(context, x, -5, "%lus" % (x/100), vcenter = 0, hcenter = 0) + + y = 0 + + # draw boxes for kernel and initramfs boot time + if initrd_time > 0: + draw_box(context, 0, y, initrd_time/10000, bar_height, 0.7, 0.7, 0.7) + draw_text(context, 10, y + bar_height/2, "kernel", hcenter = 0) + y += bar_height + bar_space + + draw_box(context, initrd_time/10000, y, userspace_time/10000-initrd_time/10000, bar_height, 0.7, 0.7, 0.7) + draw_text(context, initrd_time/10000 + 10, y + bar_height/2, "initramfs", hcenter = 0) + y += bar_height + bar_space + + else: + draw_box(context, 0, y, userspace_time/10000, bar_height, 0.6, 0.6, 0.6) + draw_text(context, 10, y + bar_height/2, "kernel", hcenter = 0) + y += bar_height + bar_space + + draw_box(context, userspace_time/10000, y, finish_time/10000-userspace_time/10000, bar_height, 0.7, 0.7, 0.7) + draw_text(context, userspace_time/10000 + 10, y + bar_height/2, "userspace", hcenter = 0) + y += bar_height + bar_space + + for name, ixt, aet, axt, iet in s: + + drawn = False + left = -1 + + if ixt >= userspace_time and ixt <= finish_time: + + # Activating + a = ixt + b = min(filter(lambda x: x >= ixt, (aet, axt, iet, finish_time))) - ixt + + draw_box(context, a/10000, y, b/10000, bar_height, 1, 0, 0) + drawn = True + + if left < 0: + left = a + + if aet >= userspace_time and aet <= finish_time: + + # Active + a = aet + b = min(filter(lambda x: x >= aet, (axt, iet, finish_time))) - aet + + draw_box(context, a/10000, y, b/10000, bar_height, .8, .6, .6) + drawn = True + + if left < 0: + left = a + + if axt >= userspace_time and axt <= finish_time: + + # Deactivating + a = axt + b = min(filter(lambda x: x >= axt, (iet, finish_time))) - axt + + draw_box(context, a/10000, y, b/10000, bar_height, .6, .4, .4) + drawn = True + + if left < 0: + left = a + + if drawn: + x = left/10000 + + if x < width/2-border: + draw_text(context, x + 10, y + bar_height/2, name, hcenter = 0) + else: + draw_text(context, x - 10, y + bar_height/2, name, hcenter = 1) + + y += bar_height + bar_space + + draw_text(context, 0, height-border*2, "Legend: Red = Activating; Pink = Active; Dark Pink = Deactivating", hcenter = 0, vcenter = -1) + + if initrd_time > 0: + draw_text(context, 0, height-border*2 + bar_height, "Startup finished in %lums (kernel) + %lums (initramfs) + %lums (userspace) = %lums" % ( \ + initrd_time/1000, \ + (userspace_time - initrd_time)/1000, \ + (finish_time - userspace_time)/1000, \ + finish_time/1000), hcenter = 0, vcenter = -1) + else: + draw_text(context, 0, height-border*2 + bar_height, "Startup finished in %lums (kernel) + %lums (userspace) = %lums" % ( \ + userspace_time/1000, \ + (finish_time - userspace_time)/1000, \ + finish_time/1000), hcenter = 0, vcenter = -1) + + surface.finish() + +parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter, + version='systemd-analyze @PACKAGE_VERSION@', + description='Process systemd profiling information', + epilog='''\ +time - print time spent in the kernel before reaching userspace +blame - print list of running units ordered by time to init +plot - output SVG graphic showing service initialization +''') + +parser.add_argument('action', choices=('time', 'blame', 'plot'), + default='time', nargs='?', + help='action to perform (default: time)') +parser.add_argument('--user', action='store_true', + help='use the session bus') + +args = parser.parse_args() + +if args.user: + bus = Gio.BusType.SESSION +else: + bus = Gio.BusType.SYSTEM + +verb = {'time' : time, + 'blame': blame, + 'plot' : plot, + } +verb.get(args.action)() diff --git a/src/ask-password/Makefile b/src/ask-password/Makefile new file mode 120000 index 000000000..d0b0e8e00 --- /dev/null +++ b/src/ask-password/Makefile @@ -0,0 +1 @@ +../Makefile \ No newline at end of file diff --git a/src/ask-password/ask-password.c b/src/ask-password/ask-password.c new file mode 100644 index 000000000..5f675700f --- /dev/null +++ b/src/ask-password/ask-password.c @@ -0,0 +1,184 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "log.h" +#include "macro.h" +#include "util.h" +#include "strv.h" +#include "ask-password-api.h" +#include "def.h" + +static const char *arg_icon = NULL; +static const char *arg_message = NULL; +static bool arg_use_tty = true; +static usec_t arg_timeout = DEFAULT_TIMEOUT_USEC; +static bool arg_accept_cached = false; +static bool arg_multiple = false; + +static int help(void) { + + printf("%s [OPTIONS...] MESSAGE\n\n" + "Query the user for a system passphrase, via the TTY or an UI agent.\n\n" + " -h --help Show this help\n" + " --icon=NAME Icon name\n" + " --timeout=SEC Timeout in sec\n" + " --no-tty Ask question via agent even on TTY\n" + " --accept-cached Accept cached passwords\n" + " --multiple List multiple passwords if available\n", + program_invocation_short_name); + + return 0; +} + +static int parse_argv(int argc, char *argv[]) { + + enum { + ARG_ICON = 0x100, + ARG_TIMEOUT, + ARG_NO_TTY, + ARG_ACCEPT_CACHED, + ARG_MULTIPLE + }; + + static const struct option options[] = { + { "help", no_argument, NULL, 'h' }, + { "icon", required_argument, NULL, ARG_ICON }, + { "timeout", required_argument, NULL, ARG_TIMEOUT }, + { "no-tty", no_argument, NULL, ARG_NO_TTY }, + { "accept-cached", no_argument, NULL, ARG_ACCEPT_CACHED }, + { "multiple", no_argument, NULL, ARG_MULTIPLE }, + { NULL, 0, NULL, 0 } + }; + + int c; + + assert(argc >= 0); + assert(argv); + + while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) { + + switch (c) { + + case 'h': + help(); + return 0; + + case ARG_ICON: + arg_icon = optarg; + break; + + case ARG_TIMEOUT: + if (parse_usec(optarg, &arg_timeout) < 0) { + log_error("Failed to parse --timeout parameter %s", optarg); + return -EINVAL; + } + break; + + case ARG_NO_TTY: + arg_use_tty = false; + break; + + case ARG_ACCEPT_CACHED: + arg_accept_cached = true; + break; + + case ARG_MULTIPLE: + arg_multiple = true; + break; + + case '?': + return -EINVAL; + + default: + log_error("Unknown option code %c", c); + return -EINVAL; + } + } + + if (optind != argc-1) { + help(); + return -EINVAL; + } + + arg_message = argv[optind]; + return 1; +} + +int main(int argc, char *argv[]) { + int r; + usec_t timeout; + + log_parse_environment(); + log_open(); + + if ((r = parse_argv(argc, argv)) <= 0) + goto finish; + + if (arg_timeout > 0) + timeout = now(CLOCK_MONOTONIC) + arg_timeout; + else + timeout = 0; + + if (arg_use_tty && isatty(STDIN_FILENO)) { + char *password = NULL; + + if ((r = ask_password_tty(arg_message, timeout, NULL, &password)) >= 0) { + puts(password); + free(password); + } + + } else { + char **l; + + if ((r = ask_password_agent(arg_message, arg_icon, timeout, arg_accept_cached, &l)) >= 0) { + char **p; + + STRV_FOREACH(p, l) { + puts(*p); + + if (!arg_multiple) + break; + } + + strv_free(l); + } + } + +finish: + + return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/src/binfmt/Makefile b/src/binfmt/Makefile new file mode 120000 index 000000000..d0b0e8e00 --- /dev/null +++ b/src/binfmt/Makefile @@ -0,0 +1 @@ +../Makefile \ No newline at end of file diff --git a/src/binfmt/binfmt.c b/src/binfmt/binfmt.c new file mode 100644 index 000000000..788fd4b1a --- /dev/null +++ b/src/binfmt/binfmt.c @@ -0,0 +1,170 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include + +#include "log.h" +#include "hashmap.h" +#include "strv.h" +#include "util.h" +#include "conf-files.h" + +static int delete_rule(const char *rule) { + char *x, *fn = NULL, *e; + int r; + + assert(rule[0]); + + if (!(x = strdup(rule))) + return log_oom(); + + e = strchrnul(x+1, x[0]); + *e = 0; + + asprintf(&fn, "/proc/sys/fs/binfmt_misc/%s", x+1); + free(x); + + if (!fn) + return log_oom(); + + r = write_one_line_file(fn, "-1"); + free(fn); + + return r; +} + +static int apply_rule(const char *rule) { + int r; + + delete_rule(rule); + + if ((r = write_one_line_file("/proc/sys/fs/binfmt_misc/register", rule)) < 0) { + log_error("Failed to add binary format: %s", strerror(-r)); + return r; + } + + return 0; +} + +static int apply_file(const char *path, bool ignore_enoent) { + FILE *f; + int r = 0; + + assert(path); + + if (!(f = fopen(path, "re"))) { + if (ignore_enoent && errno == ENOENT) + return 0; + + log_error("Failed to open file '%s', ignoring: %m", path); + return -errno; + } + + log_debug("apply: %s\n", path); + while (!feof(f)) { + char l[LINE_MAX], *p; + int k; + + if (!fgets(l, sizeof(l), f)) { + if (feof(f)) + break; + + log_error("Failed to read file '%s', ignoring: %m", path); + r = -errno; + goto finish; + } + + p = strstrip(l); + + if (!*p) + continue; + + if (strchr(COMMENTS, *p)) + continue; + + if ((k = apply_rule(p)) < 0 && r == 0) + r = k; + } + +finish: + fclose(f); + + return r; +} + +int main(int argc, char *argv[]) { + int r = 0; + + log_set_target(LOG_TARGET_AUTO); + log_parse_environment(); + log_open(); + + umask(0022); + + if (argc > 1) { + int i; + + for (i = 1; i < argc; i++) { + int k; + + k = apply_file(argv[i], false); + if (k < 0 && r == 0) + r = k; + } + } else { + char **files, **f; + + r = conf_files_list(&files, ".conf", + "/etc/binfmt.d", + "/run/binfmt.d", + "/usr/local/lib/binfmt.d", + "/usr/lib/binfmt.d", +#ifdef HAVE_SPLIT_USR + "/lib/binfmt.d", +#endif + NULL); + if (r < 0) { + log_error("Failed to enumerate binfmt.d files: %s", strerror(-r)); + goto finish; + } + + /* Flush out all rules */ + write_one_line_file("/proc/sys/fs/binfmt_misc/status", "-1"); + + STRV_FOREACH(f, files) { + int k; + + k = apply_file(*f, true); + if (k < 0 && r == 0) + r = k; + } + + strv_free(files); + } +finish: + return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/src/cgls/Makefile b/src/cgls/Makefile new file mode 120000 index 000000000..d0b0e8e00 --- /dev/null +++ b/src/cgls/Makefile @@ -0,0 +1 @@ +../Makefile \ No newline at end of file diff --git a/src/cgls/cgls.c b/src/cgls/cgls.c new file mode 100644 index 000000000..cfb728bb8 --- /dev/null +++ b/src/cgls/cgls.c @@ -0,0 +1,178 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include +#include +#include + +#include "cgroup-show.h" +#include "cgroup-util.h" +#include "log.h" +#include "path-util.h" +#include "util.h" +#include "pager.h" +#include "build.h" + +static bool arg_no_pager = false; +static bool arg_kernel_threads = false; +static bool arg_all = false; + +static void help(void) { + + printf("%s [OPTIONS...] [CGROUP...]\n\n" + "Recursively show control group contents.\n\n" + " -h --help Show this help\n" + " --version Show package version\n" + " --no-pager Do not pipe output into a pager\n" + " -a --all Show all groups, including empty\n" + " -k Include kernel threads in output\n", + program_invocation_short_name); +} + +static int parse_argv(int argc, char *argv[]) { + + enum { + ARG_NO_PAGER = 0x100, + ARG_VERSION + }; + + static const struct option options[] = { + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, ARG_VERSION }, + { "no-pager", no_argument, NULL, ARG_NO_PAGER }, + { "all", no_argument, NULL, 'a' }, + { NULL, 0, NULL, 0 } + }; + + int c; + + assert(argc >= 1); + assert(argv); + + while ((c = getopt_long(argc, argv, "hka", options, NULL)) >= 0) { + + switch (c) { + + case 'h': + help(); + return 0; + + case ARG_VERSION: + puts(PACKAGE_STRING); + puts(SYSTEMD_FEATURES); + return 0; + + case ARG_NO_PAGER: + arg_no_pager = true; + break; + + case 'a': + arg_all = true; + break; + + case 'k': + arg_kernel_threads = true; + break; + + case '?': + return -EINVAL; + + default: + log_error("Unknown option code %c", c); + return -EINVAL; + } + } + + return 1; +} + +int main(int argc, char *argv[]) { + int r = 0, retval = EXIT_FAILURE; + + log_parse_environment(); + log_open(); + + r = parse_argv(argc, argv); + if (r < 0) + goto finish; + else if (r == 0) { + retval = EXIT_SUCCESS; + goto finish; + } + + if (!arg_no_pager) + pager_open(); + + if (optind < argc) { + unsigned i; + + for (i = (unsigned) optind; i < (unsigned) argc; i++) { + int q; + printf("%s:\n", argv[i]); + + q = show_cgroup_by_path(argv[i], NULL, 0, arg_kernel_threads, arg_all); + if (q < 0) + r = q; + } + + } else { + char _cleanup_free_ *p; + + p = get_current_dir_name(); + if (!p) { + log_error("Cannot determine current working directory: %m"); + goto finish; + } + + if (path_startswith(p, "/sys/fs/cgroup")) { + printf("Working Directory %s:\n", p); + r = show_cgroup_by_path(p, NULL, 0, arg_kernel_threads, arg_all); + } else { + char _cleanup_free_ *root = NULL; + const char *t = NULL; + + r = cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, 1, &root); + if (r < 0) + t = "/"; + else { + if (endswith(root, "/system")) + root[strlen(root)-7] = 0; + + t = root[0] ? root : "/"; + } + + r = show_cgroup(SYSTEMD_CGROUP_CONTROLLER, t, NULL, 0, arg_kernel_threads, arg_all); + } + } + + if (r < 0) + log_error("Failed to list cgroup tree: %s", strerror(-r)); + + retval = EXIT_SUCCESS; + +finish: + pager_close(); + + return retval; +} diff --git a/src/cgroups-agent/Makefile b/src/cgroups-agent/Makefile new file mode 120000 index 000000000..d0b0e8e00 --- /dev/null +++ b/src/cgroups-agent/Makefile @@ -0,0 +1 @@ +../Makefile \ No newline at end of file diff --git a/src/cgroups-agent/cgroups-agent.c b/src/cgroups-agent/cgroups-agent.c new file mode 100644 index 000000000..7a6173e2a --- /dev/null +++ b/src/cgroups-agent/cgroups-agent.c @@ -0,0 +1,101 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include + +#include + +#include "log.h" +#include "dbus-common.h" + +int main(int argc, char *argv[]) { + DBusError error; + DBusConnection *bus = NULL; + DBusMessage *m = NULL; + int r = EXIT_FAILURE; + + dbus_error_init(&error); + + if (argc != 2) { + log_error("Incorrect number of arguments."); + goto finish; + } + + log_set_target(LOG_TARGET_AUTO); + log_parse_environment(); + log_open(); + + /* We send this event to the private D-Bus socket and then the + * system instance will forward this to the system bus. We do + * this to avoid an activation loop when we start dbus when we + * are called when the dbus service is shut down. */ + + if (!(bus = dbus_connection_open_private("unix:path=/run/systemd/private", &error))) { +#ifndef LEGACY + dbus_error_free(&error); + + /* Retry with the pre v21 socket name, to ease upgrades */ + if (!(bus = dbus_connection_open_private("unix:abstract=/org/freedesktop/systemd1/private", &error))) { +#endif + log_error("Failed to get D-Bus connection: %s", bus_error_message(&error)); + goto finish; + } +#ifndef LEGACY + } +#endif + + if (bus_check_peercred(bus) < 0) { + log_error("Bus owner not root."); + goto finish; + } + + if (!(m = dbus_message_new_signal("/org/freedesktop/systemd1/agent", "org.freedesktop.systemd1.Agent", "Released"))) { + log_error("Could not allocate signal message."); + goto finish; + } + + if (!dbus_message_append_args(m, + DBUS_TYPE_STRING, &argv[1], + DBUS_TYPE_INVALID)) { + log_error("Could not attach group information to signal message."); + goto finish; + } + + if (!dbus_connection_send(bus, m, NULL)) { + log_error("Failed to send signal message on private connection."); + goto finish; + } + + r = EXIT_SUCCESS; + +finish: + if (bus) { + dbus_connection_flush(bus); + dbus_connection_close(bus); + dbus_connection_unref(bus); + } + + if (m) + dbus_message_unref(m); + + dbus_error_free(&error); + return r; +} diff --git a/src/cgtop/Makefile b/src/cgtop/Makefile new file mode 120000 index 000000000..d0b0e8e00 --- /dev/null +++ b/src/cgtop/Makefile @@ -0,0 +1 @@ +../Makefile \ No newline at end of file diff --git a/src/cgtop/cgtop.c b/src/cgtop/cgtop.c new file mode 100644 index 000000000..f2e62761f --- /dev/null +++ b/src/cgtop/cgtop.c @@ -0,0 +1,793 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + +#include +#include +#include +#include +#include +#include + +#include "path-util.h" +#include "util.h" +#include "hashmap.h" +#include "cgroup-util.h" +#include "build.h" + +typedef struct Group { + char *path; + + bool n_tasks_valid:1; + bool cpu_valid:1; + bool memory_valid:1; + bool io_valid:1; + + unsigned n_tasks; + + unsigned cpu_iteration; + uint64_t cpu_usage; + struct timespec cpu_timestamp; + double cpu_fraction; + + uint64_t memory; + + unsigned io_iteration; + uint64_t io_input, io_output; + struct timespec io_timestamp; + uint64_t io_input_bps, io_output_bps; +} Group; + +static unsigned arg_depth = 3; +static unsigned arg_iterations = 0; +static bool arg_batch = false; +static usec_t arg_delay = 1*USEC_PER_SEC; + +static enum { + ORDER_PATH, + ORDER_TASKS, + ORDER_CPU, + ORDER_MEMORY, + ORDER_IO +} arg_order = ORDER_CPU; + +static void group_free(Group *g) { + assert(g); + + free(g->path); + free(g); +} + +static void group_hashmap_clear(Hashmap *h) { + Group *g; + + while ((g = hashmap_steal_first(h))) + group_free(g); +} + +static void group_hashmap_free(Hashmap *h) { + group_hashmap_clear(h); + hashmap_free(h); +} + +static int process(const char *controller, const char *path, Hashmap *a, Hashmap *b, unsigned iteration) { + Group *g; + int r; + FILE *f; + pid_t pid; + unsigned n; + + assert(controller); + assert(path); + assert(a); + + g = hashmap_get(a, path); + if (!g) { + g = hashmap_get(b, path); + if (!g) { + g = new0(Group, 1); + if (!g) + return -ENOMEM; + + g->path = strdup(path); + if (!g->path) { + group_free(g); + return -ENOMEM; + } + + r = hashmap_put(a, g->path, g); + if (r < 0) { + group_free(g); + return r; + } + } else { + assert_se(hashmap_move_one(a, b, path) == 0); + g->cpu_valid = g->memory_valid = g->io_valid = g->n_tasks_valid = false; + } + } + + /* Regardless which controller, let's find the maximum number + * of processes in any of it */ + + r = cg_enumerate_tasks(controller, path, &f); + if (r < 0) + return r; + + n = 0; + while (cg_read_pid(f, &pid) > 0) + n++; + fclose(f); + + if (n > 0) { + if (g->n_tasks_valid) + g->n_tasks = MAX(g->n_tasks, n); + else + g->n_tasks = n; + + g->n_tasks_valid = true; + } + + if (streq(controller, "cpuacct")) { + uint64_t new_usage; + char *p, *v; + struct timespec ts; + + r = cg_get_path(controller, path, "cpuacct.usage", &p); + if (r < 0) + return r; + + r = read_one_line_file(p, &v); + free(p); + if (r < 0) + return r; + + r = safe_atou64(v, &new_usage); + free(v); + if (r < 0) + return r; + + assert_se(clock_gettime(CLOCK_MONOTONIC, &ts) == 0); + + if (g->cpu_iteration == iteration - 1) { + uint64_t x, y; + + x = ((uint64_t) ts.tv_sec * 1000000000ULL + (uint64_t) ts.tv_nsec) - + ((uint64_t) g->cpu_timestamp.tv_sec * 1000000000ULL + (uint64_t) g->cpu_timestamp.tv_nsec); + + y = new_usage - g->cpu_usage; + + if (y > 0) { + g->cpu_fraction = (double) y / (double) x; + g->cpu_valid = true; + } + } + + g->cpu_usage = new_usage; + g->cpu_timestamp = ts; + g->cpu_iteration = iteration; + + } else if (streq(controller, "memory")) { + char *p, *v; + + r = cg_get_path(controller, path, "memory.usage_in_bytes", &p); + if (r < 0) + return r; + + r = read_one_line_file(p, &v); + free(p); + if (r < 0) + return r; + + r = safe_atou64(v, &g->memory); + free(v); + if (r < 0) + return r; + + if (g->memory > 0) + g->memory_valid = true; + + } else if (streq(controller, "blkio")) { + char *p; + uint64_t wr = 0, rd = 0; + struct timespec ts; + + r = cg_get_path(controller, path, "blkio.io_service_bytes", &p); + if (r < 0) + return r; + + f = fopen(p, "re"); + free(p); + + if (!f) + return -errno; + + for (;;) { + char line[LINE_MAX], *l; + uint64_t k, *q; + + if (!fgets(line, sizeof(line), f)) + break; + + l = strstrip(line); + l += strcspn(l, WHITESPACE); + l += strspn(l, WHITESPACE); + + if (first_word(l, "Read")) { + l += 4; + q = &rd; + } else if (first_word(l, "Write")) { + l += 5; + q = ≀ + } else + continue; + + l += strspn(l, WHITESPACE); + r = safe_atou64(l, &k); + if (r < 0) + continue; + + *q += k; + } + + fclose(f); + + assert_se(clock_gettime(CLOCK_MONOTONIC, &ts) == 0); + + if (g->io_iteration == iteration - 1) { + uint64_t x, yr, yw; + + x = ((uint64_t) ts.tv_sec * 1000000000ULL + (uint64_t) ts.tv_nsec) - + ((uint64_t) g->io_timestamp.tv_sec * 1000000000ULL + (uint64_t) g->io_timestamp.tv_nsec); + + yr = rd - g->io_input; + yw = wr - g->io_output; + + if (yr > 0 || yw > 0) { + g->io_input_bps = (yr * 1000000000ULL) / x; + g->io_output_bps = (yw * 1000000000ULL) / x; + g->io_valid = true; + + } + } + + g->io_input = rd; + g->io_output = wr; + g->io_timestamp = ts; + g->io_iteration = iteration; + } + + return 0; +} + +static int refresh_one( + const char *controller, + const char *path, + Hashmap *a, + Hashmap *b, + unsigned iteration, + unsigned depth) { + + DIR *d = NULL; + int r; + + assert(controller); + assert(path); + assert(a); + + if (depth > arg_depth) + return 0; + + r = process(controller, path, a, b, iteration); + if (r < 0) + return r; + + r = cg_enumerate_subgroups(controller, path, &d); + if (r < 0) { + if (r == -ENOENT) + return 0; + + return r; + } + + for (;;) { + char *fn, *p; + + r = cg_read_subgroup(d, &fn); + if (r <= 0) + goto finish; + + p = strjoin(path, "/", fn, NULL); + free(fn); + + if (!p) { + r = -ENOMEM; + goto finish; + } + + path_kill_slashes(p); + + r = refresh_one(controller, p, a, b, iteration, depth + 1); + free(p); + + if (r < 0) + goto finish; + } + +finish: + if (d) + closedir(d); + + return r; +} + +static int refresh(Hashmap *a, Hashmap *b, unsigned iteration) { + int r; + + assert(a); + + r = refresh_one("name=systemd", "/", a, b, iteration, 0); + if (r < 0) + if (r != -ENOENT) + return r; + r = refresh_one("cpuacct", "/", a, b, iteration, 0); + if (r < 0) + if (r != -ENOENT) + return r; + r = refresh_one("memory", "/", a, b, iteration, 0); + if (r < 0) + if (r != -ENOENT) + return r; + + r = refresh_one("blkio", "/", a, b, iteration, 0); + if (r < 0) + if (r != -ENOENT) + return r; + return 0; +} + +static int group_compare(const void*a, const void *b) { + const Group *x = *(Group**)a, *y = *(Group**)b; + + if (path_startswith(y->path, x->path)) + return -1; + if (path_startswith(x->path, y->path)) + return 1; + + if (arg_order == ORDER_CPU) { + if (x->cpu_valid && y->cpu_valid) { + + if (x->cpu_fraction > y->cpu_fraction) + return -1; + else if (x->cpu_fraction < y->cpu_fraction) + return 1; + } else if (x->cpu_valid) + return -1; + else if (y->cpu_valid) + return 1; + } + + if (arg_order == ORDER_TASKS) { + + if (x->n_tasks_valid && y->n_tasks_valid) { + if (x->n_tasks > y->n_tasks) + return -1; + else if (x->n_tasks < y->n_tasks) + return 1; + } else if (x->n_tasks_valid) + return -1; + else if (y->n_tasks_valid) + return 1; + } + + if (arg_order == ORDER_MEMORY) { + if (x->memory_valid && y->memory_valid) { + if (x->memory > y->memory) + return -1; + else if (x->memory < y->memory) + return 1; + } else if (x->memory_valid) + return -1; + else if (y->memory_valid) + return 1; + } + + if (arg_order == ORDER_IO) { + if (x->io_valid && y->io_valid) { + if (x->io_input_bps + x->io_output_bps > y->io_input_bps + y->io_output_bps) + return -1; + else if (x->io_input_bps + x->io_output_bps < y->io_input_bps + y->io_output_bps) + return 1; + } else if (x->io_valid) + return -1; + else if (y->io_valid) + return 1; + } + + return strcmp(x->path, y->path); +} + +static int display(Hashmap *a) { + Iterator i; + Group *g; + Group **array; + unsigned rows, path_columns, n = 0, j; + + assert(a); + + /* Set cursor to top left corner and clear screen */ + fputs("\033[H" + "\033[2J", stdout); + + array = alloca(sizeof(Group*) * hashmap_size(a)); + + HASHMAP_FOREACH(g, a, i) + if (g->n_tasks_valid || g->cpu_valid || g->memory_valid || g->io_valid) + array[n++] = g; + + qsort(array, n, sizeof(Group*), group_compare); + + rows = lines(); + if (rows <= 10) + rows = 10; + + path_columns = columns() - 42; + if (path_columns < 10) + path_columns = 10; + + printf("%s%-*s%s %s%7s%s %s%6s%s %s%8s%s %s%8s%s %s%8s%s\n\n", + arg_order == ORDER_PATH ? ANSI_HIGHLIGHT_ON : "", path_columns, "Path", + arg_order == ORDER_PATH ? ANSI_HIGHLIGHT_OFF : "", + arg_order == ORDER_TASKS ? ANSI_HIGHLIGHT_ON : "", "Tasks", + arg_order == ORDER_TASKS ? ANSI_HIGHLIGHT_OFF : "", + arg_order == ORDER_CPU ? ANSI_HIGHLIGHT_ON : "", "%CPU", + arg_order == ORDER_CPU ? ANSI_HIGHLIGHT_OFF : "", + arg_order == ORDER_MEMORY ? ANSI_HIGHLIGHT_ON : "", "Memory", + arg_order == ORDER_MEMORY ? ANSI_HIGHLIGHT_OFF : "", + arg_order == ORDER_IO ? ANSI_HIGHLIGHT_ON : "", "Input/s", + arg_order == ORDER_IO ? ANSI_HIGHLIGHT_OFF : "", + arg_order == ORDER_IO ? ANSI_HIGHLIGHT_ON : "", "Output/s", + arg_order == ORDER_IO ? ANSI_HIGHLIGHT_OFF : ""); + + for (j = 0; j < n; j++) { + char *p; + char m[FORMAT_BYTES_MAX]; + + if (j + 5 > rows) + break; + + g = array[j]; + + p = ellipsize(g->path, path_columns, 33); + printf("%-*s", path_columns, p ? p : g->path); + free(p); + + if (g->n_tasks_valid) + printf(" %7u", g->n_tasks); + else + fputs(" -", stdout); + + if (g->cpu_valid) + printf(" %6.1f", g->cpu_fraction*100); + else + fputs(" -", stdout); + + if (g->memory_valid) + printf(" %8s", format_bytes(m, sizeof(m), g->memory)); + else + fputs(" -", stdout); + + if (g->io_valid) { + printf(" %8s", + format_bytes(m, sizeof(m), g->io_input_bps)); + printf(" %8s", + format_bytes(m, sizeof(m), g->io_output_bps)); + } else + fputs(" - -", stdout); + + putchar('\n'); + } + + return 0; +} + +static void help(void) { + + printf("%s [OPTIONS...]\n\n" + "Show top control groups by their resource usage.\n\n" + " -h --help Show this help\n" + " --version Print version and exit\n" + " -p Order by path\n" + " -t Order by number of tasks\n" + " -c Order by CPU load\n" + " -m Order by memory load\n" + " -i Order by IO load\n" + " -d --delay=DELAY Specify delay\n" + " -n --iterations=N Run for N iterations before exiting\n" + " -b --batch Run in batch mode, accepting no input\n" + " --depth=DEPTH Maximum traversal depth (default: 2)\n", + program_invocation_short_name); +} + +static void version(void) { + puts(PACKAGE_STRING " cgtop"); +} + +static int parse_argv(int argc, char *argv[]) { + + enum { + ARG_VERSION = 0x100, + ARG_DEPTH, + }; + + static const struct option options[] = { + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, ARG_VERSION }, + { "delay", required_argument, NULL, 'd' }, + { "iterations", required_argument, NULL, 'n' }, + { "batch", no_argument, NULL, 'b' }, + { "depth", required_argument, NULL, ARG_DEPTH }, + { NULL, 0, NULL, 0 } + }; + + int c; + int r; + + assert(argc >= 1); + assert(argv); + + while ((c = getopt_long(argc, argv, "hptcmin:bd:", options, NULL)) >= 0) { + + switch (c) { + + case 'h': + help(); + return 0; + + case ARG_VERSION: + version(); + return 0; + + case ARG_DEPTH: + r = safe_atou(optarg, &arg_depth); + if (r < 0) { + log_error("Failed to parse depth parameter."); + return -EINVAL; + } + + break; + + case 'd': + r = parse_usec(optarg, &arg_delay); + if (r < 0 || arg_delay <= 0) { + log_error("Failed to parse delay parameter."); + return -EINVAL; + } + + break; + + case 'n': + r = safe_atou(optarg, &arg_iterations); + if (r < 0) { + log_error("Failed to parse iterations parameter."); + return -EINVAL; + } + + break; + + case 'b': + arg_batch = true; + break; + + case 'p': + arg_order = ORDER_PATH; + break; + + case 't': + arg_order = ORDER_TASKS; + break; + + case 'c': + arg_order = ORDER_CPU; + break; + + case 'm': + arg_order = ORDER_MEMORY; + break; + + case 'i': + arg_order = ORDER_IO; + break; + + case '?': + return -EINVAL; + + default: + log_error("Unknown option code %c", c); + return -EINVAL; + } + } + + if (optind < argc) { + log_error("Too many arguments."); + return -EINVAL; + } + + return 1; +} + +int main(int argc, char *argv[]) { + int r; + Hashmap *a = NULL, *b = NULL; + unsigned iteration = 0; + usec_t last_refresh = 0; + bool quit = false, immediate_refresh = false; + + log_parse_environment(); + log_open(); + + r = parse_argv(argc, argv); + if (r <= 0) + goto finish; + + a = hashmap_new(string_hash_func, string_compare_func); + b = hashmap_new(string_hash_func, string_compare_func); + if (!a || !b) { + r = log_oom(); + goto finish; + } + + signal(SIGWINCH, columns_lines_cache_reset); + + while (!quit) { + Hashmap *c; + usec_t t; + char key; + char h[FORMAT_TIMESPAN_MAX]; + + t = now(CLOCK_MONOTONIC); + + if (t >= last_refresh + arg_delay || immediate_refresh) { + + r = refresh(a, b, iteration++); + if (r < 0) + goto finish; + + group_hashmap_clear(b); + + c = a; + a = b; + b = c; + + last_refresh = t; + immediate_refresh = false; + } + + r = display(b); + if (r < 0) + goto finish; + + if (arg_iterations && iteration >= arg_iterations) + break; + + if (arg_batch) { + usleep(last_refresh + arg_delay - t); + } else { + r = read_one_char(stdin, &key, + last_refresh + arg_delay - t, NULL); + if (r == -ETIMEDOUT) + continue; + if (r < 0) { + log_error("Couldn't read key: %s", strerror(-r)); + goto finish; + } + } + + fputs("\r \r", stdout); + fflush(stdout); + + if (arg_batch) + continue; + + switch (key) { + + case ' ': + immediate_refresh = true; + break; + + case 'q': + quit = true; + break; + + case 'p': + arg_order = ORDER_PATH; + break; + + case 't': + arg_order = ORDER_TASKS; + break; + + case 'c': + arg_order = ORDER_CPU; + break; + + case 'm': + arg_order = ORDER_MEMORY; + break; + + case 'i': + arg_order = ORDER_IO; + break; + + case '+': + if (arg_delay < USEC_PER_SEC) + arg_delay += USEC_PER_MSEC*250; + else + arg_delay += USEC_PER_SEC; + + fprintf(stdout, "\nIncreased delay to %s.", format_timespan(h, sizeof(h), arg_delay)); + fflush(stdout); + sleep(1); + break; + + case '-': + if (arg_delay <= USEC_PER_MSEC*500) + arg_delay = USEC_PER_MSEC*250; + else if (arg_delay < USEC_PER_MSEC*1250) + arg_delay -= USEC_PER_MSEC*250; + else + arg_delay -= USEC_PER_SEC; + + fprintf(stdout, "\nDecreased delay to %s.", format_timespan(h, sizeof(h), arg_delay)); + fflush(stdout); + sleep(1); + break; + + case '?': + case 'h': + fprintf(stdout, + "\t<" ANSI_HIGHLIGHT_ON "P" ANSI_HIGHLIGHT_OFF "> By path; <" ANSI_HIGHLIGHT_ON "T" ANSI_HIGHLIGHT_OFF "> By tasks; <" ANSI_HIGHLIGHT_ON "C" ANSI_HIGHLIGHT_OFF "> By CPU; <" ANSI_HIGHLIGHT_ON "M" ANSI_HIGHLIGHT_OFF "> By memory; <" ANSI_HIGHLIGHT_ON "I" ANSI_HIGHLIGHT_OFF "> By I/O\n" + "\t<" ANSI_HIGHLIGHT_ON "Q" ANSI_HIGHLIGHT_OFF "> Quit; <" ANSI_HIGHLIGHT_ON "+" ANSI_HIGHLIGHT_OFF "> Increase delay; <" ANSI_HIGHLIGHT_ON "-" ANSI_HIGHLIGHT_OFF "> Decrease delay; <" ANSI_HIGHLIGHT_ON "SPACE" ANSI_HIGHLIGHT_OFF "> Refresh"); + fflush(stdout); + sleep(3); + break; + + default: + fprintf(stdout, "\nUnknown key '%c'. Ignoring.", key); + fflush(stdout); + sleep(1); + break; + } + } + + log_info("Exiting."); + + r = 0; + +finish: + group_hashmap_free(a); + group_hashmap_free(b); + + if (r < 0) { + log_error("Exiting with failure: %s", strerror(-r)); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} diff --git a/src/core/.gitignore b/src/core/.gitignore new file mode 100644 index 000000000..a763f7250 --- /dev/null +++ b/src/core/.gitignore @@ -0,0 +1,6 @@ +/syscall-from-name.gperf +/syscall-from-name.h +/syscall-list.txt +/syscall-to-name.h +/macros.systemd +/systemd.pc diff --git a/src/core/Makefile b/src/core/Makefile new file mode 120000 index 000000000..d0b0e8e00 --- /dev/null +++ b/src/core/Makefile @@ -0,0 +1 @@ +../Makefile \ No newline at end of file diff --git a/src/core/audit-fd.c b/src/core/audit-fd.c new file mode 100644 index 000000000..5955bd846 --- /dev/null +++ b/src/core/audit-fd.c @@ -0,0 +1,73 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + + +#include +#include "audit-fd.h" + +#ifdef HAVE_AUDIT + +#include +#include + +#include "log.h" +#include "util.h" + +static bool initialized = false; +static int audit_fd; + +int get_audit_fd(void) { + + if (!initialized) { + audit_fd = audit_open(); + + if (audit_fd < 0) { + if (errno != EAFNOSUPPORT && errno != EPROTONOSUPPORT) + log_error("Failed to connect to audit log: %m"); + + audit_fd = errno ? -errno : -EINVAL; + } + + initialized = true; + } + + return audit_fd; +} + +void close_audit_fd(void) { + + if (initialized && audit_fd >= 0) + close_nointr_nofail(audit_fd); + + initialized = true; + audit_fd = -ECONNRESET; +} + +#else + +int get_audit_fd(void) { + return -EAFNOSUPPORT; +} + +void close_audit_fd(void) { +} + +#endif diff --git a/src/core/audit-fd.h b/src/core/audit-fd.h new file mode 100644 index 000000000..8b58289dc --- /dev/null +++ b/src/core/audit-fd.h @@ -0,0 +1,25 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + +int get_audit_fd(void); +void close_audit_fd(void); diff --git a/src/core/automount.c b/src/core/automount.c new file mode 100644 index 000000000..4a98540d8 --- /dev/null +++ b/src/core/automount.c @@ -0,0 +1,922 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "unit.h" +#include "automount.h" +#include "mount.h" +#include "load-fragment.h" +#include "load-dropin.h" +#include "unit-name.h" +#include "dbus-automount.h" +#include "bus-errors.h" +#include "special.h" +#include "label.h" +#include "mkdir.h" +#include "path-util.h" +#include "dbus-common.h" + +static const UnitActiveState state_translation_table[_AUTOMOUNT_STATE_MAX] = { + [AUTOMOUNT_DEAD] = UNIT_INACTIVE, + [AUTOMOUNT_WAITING] = UNIT_ACTIVE, + [AUTOMOUNT_RUNNING] = UNIT_ACTIVE, + [AUTOMOUNT_FAILED] = UNIT_FAILED +}; + +static int open_dev_autofs(Manager *m); + +static void automount_init(Unit *u) { + Automount *a = AUTOMOUNT(u); + + assert(u); + assert(u->load_state == UNIT_STUB); + + a->pipe_watch.fd = a->pipe_fd = -1; + a->pipe_watch.type = WATCH_INVALID; + + a->directory_mode = 0755; + + UNIT(a)->ignore_on_isolate = true; +} + +static void repeat_unmout(const char *path) { + assert(path); + + for (;;) { + /* If there are multiple mounts on a mount point, this + * removes them all */ + + if (umount2(path, MNT_DETACH) >= 0) + continue; + + if (errno != EINVAL) + log_error("Failed to unmount: %m"); + + break; + } +} + +static void unmount_autofs(Automount *a) { + assert(a); + + if (a->pipe_fd < 0) + return; + + automount_send_ready(a, -EHOSTDOWN); + + unit_unwatch_fd(UNIT(a), &a->pipe_watch); + close_nointr_nofail(a->pipe_fd); + a->pipe_fd = -1; + + /* If we reload/reexecute things we keep the mount point + * around */ + if (a->where && + (UNIT(a)->manager->exit_code != MANAGER_RELOAD && + UNIT(a)->manager->exit_code != MANAGER_REEXECUTE)) + repeat_unmout(a->where); +} + +static void automount_done(Unit *u) { + Automount *a = AUTOMOUNT(u); + + assert(a); + + unmount_autofs(a); + unit_ref_unset(&a->mount); + + free(a->where); + a->where = NULL; + + set_free(a->tokens); + a->tokens = NULL; +} + +int automount_add_one_mount_link(Automount *a, Mount *m) { + int r; + + assert(a); + assert(m); + + if (UNIT(a)->load_state != UNIT_LOADED || + UNIT(m)->load_state != UNIT_LOADED) + return 0; + + if (!path_startswith(a->where, m->where)) + return 0; + + if (path_equal(a->where, m->where)) + return 0; + + r = unit_add_two_dependencies(UNIT(a), UNIT_AFTER, UNIT_REQUIRES, UNIT(m), true); + if (r < 0) + return r; + + return 0; +} + +static int automount_add_mount_links(Automount *a) { + Unit *other; + int r; + + assert(a); + + LIST_FOREACH(units_by_type, other, UNIT(a)->manager->units_by_type[UNIT_MOUNT]) { + r = automount_add_one_mount_link(a, MOUNT(other)); + if (r < 0) + return r; + } + + return 0; +} + +static int automount_add_default_dependencies(Automount *a) { + int r; + + assert(a); + + if (UNIT(a)->manager->running_as != SYSTEMD_SYSTEM) + return 0; + + r = unit_add_two_dependencies_by_name(UNIT(a), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true); + if (r < 0) + return r; + + return 0; +} + +static int automount_verify(Automount *a) { + bool b; + char *e; + assert(a); + + if (UNIT(a)->load_state != UNIT_LOADED) + return 0; + + if (path_equal(a->where, "/")) { + log_error_unit(UNIT(a)->id, "Cannot have an automount unit for the root directory. Refusing."); + return -EINVAL; + } + + e = unit_name_from_path(a->where, ".automount"); + if (!e) + return -ENOMEM; + + b = unit_has_name(UNIT(a), e); + free(e); + + if (!b) { + log_error_unit(UNIT(a)->id, "%s's Where setting doesn't match unit name. Refusing.", UNIT(a)->id); + return -EINVAL; + } + + return 0; +} + +static int automount_load(Unit *u) { + int r; + Automount *a = AUTOMOUNT(u); + + assert(u); + assert(u->load_state == UNIT_STUB); + + /* Load a .automount file */ + r = unit_load_fragment_and_dropin_optional(u); + if (r < 0) + return r; + + if (u->load_state == UNIT_LOADED) { + Unit *x; + + if (!a->where) { + a->where = unit_name_to_path(u->id); + if (!a->where) + return -ENOMEM; + } + + path_kill_slashes(a->where); + + r = automount_add_mount_links(a); + if (r < 0) + return r; + + r = unit_load_related_unit(u, ".mount", &x); + if (r < 0) + return r; + + unit_ref_set(&a->mount, x); + + r = unit_add_two_dependencies(u, UNIT_BEFORE, UNIT_TRIGGERS, UNIT_DEREF(a->mount), true); + if (r < 0) + return r; + + if (UNIT(a)->default_dependencies) { + r = automount_add_default_dependencies(a); + if (r < 0) + return r; + } + } + + return automount_verify(a); +} + +static void automount_set_state(Automount *a, AutomountState state) { + AutomountState old_state; + assert(a); + + old_state = a->state; + a->state = state; + + if (state != AUTOMOUNT_WAITING && + state != AUTOMOUNT_RUNNING) + unmount_autofs(a); + + if (state != old_state) + log_debug_unit(UNIT(a)->id, + "%s changed %s -> %s", + UNIT(a)->id, + automount_state_to_string(old_state), + automount_state_to_string(state)); + + unit_notify(UNIT(a), state_translation_table[old_state], state_translation_table[state], true); +} + +static int automount_coldplug(Unit *u) { + Automount *a = AUTOMOUNT(u); + int r; + + assert(a); + assert(a->state == AUTOMOUNT_DEAD); + + if (a->deserialized_state != a->state) { + + r = open_dev_autofs(u->manager); + if (r < 0) + return r; + + if (a->deserialized_state == AUTOMOUNT_WAITING || + a->deserialized_state == AUTOMOUNT_RUNNING) { + + assert(a->pipe_fd >= 0); + + r = unit_watch_fd(UNIT(a), a->pipe_fd, EPOLLIN, &a->pipe_watch); + if (r < 0) + return r; + } + + automount_set_state(a, a->deserialized_state); + } + + return 0; +} + +static void automount_dump(Unit *u, FILE *f, const char *prefix) { + Automount *a = AUTOMOUNT(u); + + assert(a); + + fprintf(f, + "%sAutomount State: %s\n" + "%sResult: %s\n" + "%sWhere: %s\n" + "%sDirectoryMode: %04o\n", + prefix, automount_state_to_string(a->state), + prefix, automount_result_to_string(a->result), + prefix, a->where, + prefix, a->directory_mode); +} + +static void automount_enter_dead(Automount *a, AutomountResult f) { + assert(a); + + if (f != AUTOMOUNT_SUCCESS) + a->result = f; + + automount_set_state(a, a->result != AUTOMOUNT_SUCCESS ? AUTOMOUNT_FAILED : AUTOMOUNT_DEAD); +} + +static int open_dev_autofs(Manager *m) { + struct autofs_dev_ioctl param; + + assert(m); + + if (m->dev_autofs_fd >= 0) + return m->dev_autofs_fd; + + label_fix("/dev/autofs", false, false); + + m->dev_autofs_fd = open("/dev/autofs", O_CLOEXEC|O_RDONLY); + if (m->dev_autofs_fd < 0) { + log_error("Failed to open /dev/autofs: %s", strerror(errno)); + return -errno; + } + + init_autofs_dev_ioctl(¶m); + if (ioctl(m->dev_autofs_fd, AUTOFS_DEV_IOCTL_VERSION, ¶m) < 0) { + close_nointr_nofail(m->dev_autofs_fd); + m->dev_autofs_fd = -1; + return -errno; + } + + log_debug("Autofs kernel version %i.%i", param.ver_major, param.ver_minor); + + return m->dev_autofs_fd; +} + +static int open_ioctl_fd(int dev_autofs_fd, const char *where, dev_t devid) { + struct autofs_dev_ioctl *param; + size_t l; + + assert(dev_autofs_fd >= 0); + assert(where); + + l = sizeof(struct autofs_dev_ioctl) + strlen(where) + 1; + param = alloca(l); + + init_autofs_dev_ioctl(param); + param->size = l; + param->ioctlfd = -1; + param->openmount.devid = devid; + strcpy(param->path, where); + + if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_OPENMOUNT, param) < 0) + return -errno; + + if (param->ioctlfd < 0) + return -EIO; + + fd_cloexec(param->ioctlfd, true); + return param->ioctlfd; +} + +static int autofs_protocol(int dev_autofs_fd, int ioctl_fd) { + uint32_t major, minor; + struct autofs_dev_ioctl param; + + assert(dev_autofs_fd >= 0); + assert(ioctl_fd >= 0); + + init_autofs_dev_ioctl(¶m); + param.ioctlfd = ioctl_fd; + + if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_PROTOVER, ¶m) < 0) + return -errno; + + major = param.protover.version; + + init_autofs_dev_ioctl(¶m); + param.ioctlfd = ioctl_fd; + + if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_PROTOSUBVER, ¶m) < 0) + return -errno; + + minor = param.protosubver.sub_version; + + log_debug("Autofs protocol version %i.%i", major, minor); + return 0; +} + +static int autofs_set_timeout(int dev_autofs_fd, int ioctl_fd, time_t sec) { + struct autofs_dev_ioctl param; + + assert(dev_autofs_fd >= 0); + assert(ioctl_fd >= 0); + + init_autofs_dev_ioctl(¶m); + param.ioctlfd = ioctl_fd; + param.timeout.timeout = sec; + + if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_TIMEOUT, ¶m) < 0) + return -errno; + + return 0; +} + +static int autofs_send_ready(int dev_autofs_fd, int ioctl_fd, uint32_t token, int status) { + struct autofs_dev_ioctl param; + + assert(dev_autofs_fd >= 0); + assert(ioctl_fd >= 0); + + init_autofs_dev_ioctl(¶m); + param.ioctlfd = ioctl_fd; + + if (status) { + param.fail.token = token; + param.fail.status = status; + } else + param.ready.token = token; + + if (ioctl(dev_autofs_fd, status ? AUTOFS_DEV_IOCTL_FAIL : AUTOFS_DEV_IOCTL_READY, ¶m) < 0) + return -errno; + + return 0; +} + +int automount_send_ready(Automount *a, int status) { + int ioctl_fd, r; + unsigned token; + + assert(a); + assert(status <= 0); + + if (set_isempty(a->tokens)) + return 0; + + ioctl_fd = open_ioctl_fd(UNIT(a)->manager->dev_autofs_fd, a->where, a->dev_id); + if (ioctl_fd < 0) { + r = ioctl_fd; + goto fail; + } + + if (status) + log_debug_unit(UNIT(a)->id, "Sending failure: %s", strerror(-status)); + else + log_debug_unit(UNIT(a)->id, "Sending success."); + + r = 0; + + /* Autofs thankfully does not hand out 0 as a token */ + while ((token = PTR_TO_UINT(set_steal_first(a->tokens)))) { + int k; + + /* Autofs fun fact II: + * + * if you pass a positive status code here, the kernel will + * freeze! Yay! */ + + k = autofs_send_ready(UNIT(a)->manager->dev_autofs_fd, + ioctl_fd, + token, + status); + if (k < 0) + r = k; + } + +fail: + if (ioctl_fd >= 0) + close_nointr_nofail(ioctl_fd); + + return r; +} + +static void automount_enter_waiting(Automount *a) { + int p[2] = { -1, -1 }; + char name[32], options[128]; + bool mounted = false; + int r, ioctl_fd = -1, dev_autofs_fd; + struct stat st; + + assert(a); + assert(a->pipe_fd < 0); + assert(a->where); + + if (a->tokens) + set_clear(a->tokens); + + dev_autofs_fd = open_dev_autofs(UNIT(a)->manager); + if (dev_autofs_fd < 0) { + r = dev_autofs_fd; + goto fail; + } + + /* We knowingly ignore the results of this call */ + mkdir_p_label(a->where, 0555); + + warn_if_dir_nonempty(a->meta.id, a->where); + + if (pipe2(p, O_NONBLOCK|O_CLOEXEC) < 0) { + r = -errno; + goto fail; + } + + snprintf(options, sizeof(options), "fd=%i,pgrp=%u,minproto=5,maxproto=5,direct", p[1], (unsigned) getpgrp()); + char_array_0(options); + + snprintf(name, sizeof(name), "systemd-%u", (unsigned) getpid()); + char_array_0(name); + + if (mount(name, a->where, "autofs", 0, options) < 0) { + r = -errno; + goto fail; + } + + mounted = true; + + close_nointr_nofail(p[1]); + p[1] = -1; + + if (stat(a->where, &st) < 0) { + r = -errno; + goto fail; + } + + ioctl_fd = open_ioctl_fd(dev_autofs_fd, a->where, st.st_dev); + if (ioctl_fd < 0) { + r = ioctl_fd; + goto fail; + } + + r = autofs_protocol(dev_autofs_fd, ioctl_fd); + if (r < 0) + goto fail; + + r = autofs_set_timeout(dev_autofs_fd, ioctl_fd, 300); + if (r < 0) + goto fail; + + /* Autofs fun fact: + * + * Unless we close the ioctl fd here, for some weird reason + * the direct mount will not receive events from the + * kernel. */ + + close_nointr_nofail(ioctl_fd); + ioctl_fd = -1; + + r = unit_watch_fd(UNIT(a), p[0], EPOLLIN, &a->pipe_watch); + if (r < 0) + goto fail; + + a->pipe_fd = p[0]; + a->dev_id = st.st_dev; + + automount_set_state(a, AUTOMOUNT_WAITING); + + return; + +fail: + assert_se(close_pipe(p) == 0); + + if (ioctl_fd >= 0) + close_nointr_nofail(ioctl_fd); + + if (mounted) + repeat_unmout(a->where); + + log_error_unit(UNIT(a)->id, + "Failed to initialize automounter: %s", strerror(-r)); + automount_enter_dead(a, AUTOMOUNT_FAILURE_RESOURCES); +} + +static void automount_enter_runnning(Automount *a) { + int r; + struct stat st; + _cleanup_dbus_error_free_ DBusError error; + + assert(a); + assert(UNIT_DEREF(a->mount)); + + dbus_error_init(&error); + + /* We don't take mount requests anymore if we are supposed to + * shut down anyway */ + if (unit_pending_inactive(UNIT(a))) { + log_debug_unit(UNIT(a)->id, + "Suppressing automount request on %s since unit stop is scheduled.", UNIT(a)->id); + automount_send_ready(a, -EHOSTDOWN); + return; + } + + mkdir_p_label(a->where, a->directory_mode); + + /* Before we do anything, let's see if somebody is playing games with us? */ + if (lstat(a->where, &st) < 0) { + log_warning_unit(UNIT(a)->id, + "%s failed to stat automount point: %m", UNIT(a)->id); + goto fail; + } + + if (!S_ISDIR(st.st_mode) || st.st_dev != a->dev_id) + log_info_unit(UNIT(a)->id, + "%s's automount point already active?", UNIT(a)->id); + else if ((r = manager_add_job(UNIT(a)->manager, JOB_START, UNIT_DEREF(a->mount), JOB_REPLACE, true, &error, NULL)) < 0) { + log_warning_unit(UNIT(a)->id, + "%s failed to queue mount startup job: %s", + UNIT(a)->id, bus_error(&error, r)); + goto fail; + } + + automount_set_state(a, AUTOMOUNT_RUNNING); + return; + +fail: + automount_enter_dead(a, AUTOMOUNT_FAILURE_RESOURCES); +} + +static int automount_start(Unit *u) { + Automount *a = AUTOMOUNT(u); + + assert(a); + assert(a->state == AUTOMOUNT_DEAD || a->state == AUTOMOUNT_FAILED); + + if (path_is_mount_point(a->where, false)) { + log_error_unit(u->id, + "Path %s is already a mount point, refusing start for %s", + a->where, u->id); + return -EEXIST; + } + + if (UNIT_DEREF(a->mount)->load_state != UNIT_LOADED) + return -ENOENT; + + a->result = AUTOMOUNT_SUCCESS; + automount_enter_waiting(a); + return 0; +} + +static int automount_stop(Unit *u) { + Automount *a = AUTOMOUNT(u); + + assert(a); + assert(a->state == AUTOMOUNT_WAITING || a->state == AUTOMOUNT_RUNNING); + + automount_enter_dead(a, AUTOMOUNT_SUCCESS); + return 0; +} + +static int automount_serialize(Unit *u, FILE *f, FDSet *fds) { + Automount *a = AUTOMOUNT(u); + void *p; + Iterator i; + + assert(a); + assert(f); + assert(fds); + + unit_serialize_item(u, f, "state", automount_state_to_string(a->state)); + unit_serialize_item(u, f, "result", automount_result_to_string(a->result)); + unit_serialize_item_format(u, f, "dev-id", "%u", (unsigned) a->dev_id); + + SET_FOREACH(p, a->tokens, i) + unit_serialize_item_format(u, f, "token", "%u", PTR_TO_UINT(p)); + + if (a->pipe_fd >= 0) { + int copy; + + copy = fdset_put_dup(fds, a->pipe_fd); + if (copy < 0) + return copy; + + unit_serialize_item_format(u, f, "pipe-fd", "%i", copy); + } + + return 0; +} + +static int automount_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) { + Automount *a = AUTOMOUNT(u); + int r; + + assert(a); + assert(fds); + + if (streq(key, "state")) { + AutomountState state; + + state = automount_state_from_string(value); + if (state < 0) + log_debug_unit(u->id, "Failed to parse state value %s", value); + else + a->deserialized_state = state; + } else if (streq(key, "result")) { + AutomountResult f; + + f = automount_result_from_string(value); + if (f < 0) + log_debug_unit(u->id, "Failed to parse result value %s", value); + else if (f != AUTOMOUNT_SUCCESS) + a->result = f; + + } else if (streq(key, "dev-id")) { + unsigned d; + + if (safe_atou(value, &d) < 0) + log_debug_unit(u->id, "Failed to parse dev-id value %s", value); + else + a->dev_id = (unsigned) d; + } else if (streq(key, "token")) { + unsigned token; + + if (safe_atou(value, &token) < 0) + log_debug_unit(u->id, "Failed to parse token value %s", value); + else { + if (!a->tokens) + if (!(a->tokens = set_new(trivial_hash_func, trivial_compare_func))) + return -ENOMEM; + + r = set_put(a->tokens, UINT_TO_PTR(token)); + if (r < 0) + return r; + } + } else if (streq(key, "pipe-fd")) { + int fd; + + if (safe_atoi(value, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd)) + log_debug_unit(u->id, "Failed to parse pipe-fd value %s", value); + else { + if (a->pipe_fd >= 0) + close_nointr_nofail(a->pipe_fd); + + a->pipe_fd = fdset_remove(fds, fd); + } + } else + log_debug_unit(u->id, "Unknown serialization key '%s'", key); + + return 0; +} + +static UnitActiveState automount_active_state(Unit *u) { + assert(u); + + return state_translation_table[AUTOMOUNT(u)->state]; +} + +static const char *automount_sub_state_to_string(Unit *u) { + assert(u); + + return automount_state_to_string(AUTOMOUNT(u)->state); +} + +static bool automount_check_gc(Unit *u) { + Automount *a = AUTOMOUNT(u); + + assert(a); + + if (!UNIT_DEREF(a->mount)) + return false; + + return UNIT_VTABLE(UNIT_DEREF(a->mount))->check_gc(UNIT_DEREF(a->mount)); +} + +static void automount_fd_event(Unit *u, int fd, uint32_t events, Watch *w) { + Automount *a = AUTOMOUNT(u); + union autofs_v5_packet_union packet; + ssize_t l; + int r; + + assert(a); + assert(fd == a->pipe_fd); + + if (events != EPOLLIN) { + log_error_unit(u->id, "Got invalid poll event on pipe."); + goto fail; + } + + l = loop_read(a->pipe_fd, &packet, sizeof(packet), true); + if (l != sizeof(packet)) { + log_error_unit(u->id, "Invalid read from pipe: %s", l < 0 ? strerror(-l) : "short read"); + goto fail; + } + + switch (packet.hdr.type) { + + case autofs_ptype_missing_direct: + + if (packet.v5_packet.pid > 0) { + _cleanup_free_ char *p = NULL; + + get_process_comm(packet.v5_packet.pid, &p); + log_debug_unit(u->id, + "Got direct mount request on %s, triggered by %lu (%s)", + a->where, (unsigned long) packet.v5_packet.pid, strna(p)); + } else + log_debug_unit(u->id, "Got direct mount request on %s", a->where); + + r = set_ensure_allocated(&a->tokens, trivial_hash_func, trivial_compare_func); + if (r < 0) { + log_error_unit(u->id, "Failed to allocate token set."); + goto fail; + } + + r = set_put(a->tokens, UINT_TO_PTR(packet.v5_packet.wait_queue_token)); + if (r < 0) { + log_error_unit(u->id, "Failed to remember token: %s", strerror(-r)); + goto fail; + } + + automount_enter_runnning(a); + break; + + default: + log_error_unit(u->id, "Received unknown automount request %i", packet.hdr.type); + break; + } + + return; + +fail: + automount_enter_dead(a, AUTOMOUNT_FAILURE_RESOURCES); +} + +static void automount_shutdown(Manager *m) { + assert(m); + + if (m->dev_autofs_fd >= 0) + close_nointr_nofail(m->dev_autofs_fd); +} + +static void automount_reset_failed(Unit *u) { + Automount *a = AUTOMOUNT(u); + + assert(a); + + if (a->state == AUTOMOUNT_FAILED) + automount_set_state(a, AUTOMOUNT_DEAD); + + a->result = AUTOMOUNT_SUCCESS; +} + +static const char* const automount_state_table[_AUTOMOUNT_STATE_MAX] = { + [AUTOMOUNT_DEAD] = "dead", + [AUTOMOUNT_WAITING] = "waiting", + [AUTOMOUNT_RUNNING] = "running", + [AUTOMOUNT_FAILED] = "failed" +}; + +DEFINE_STRING_TABLE_LOOKUP(automount_state, AutomountState); + +static const char* const automount_result_table[_AUTOMOUNT_RESULT_MAX] = { + [AUTOMOUNT_SUCCESS] = "success", + [AUTOMOUNT_FAILURE_RESOURCES] = "resources" +}; + +DEFINE_STRING_TABLE_LOOKUP(automount_result, AutomountResult); + +const UnitVTable automount_vtable = { + .object_size = sizeof(Automount), + .sections = + "Unit\0" + "Automount\0" + "Install\0", + + .no_alias = true, + .no_instances = true, + + .init = automount_init, + .load = automount_load, + .done = automount_done, + + .coldplug = automount_coldplug, + + .dump = automount_dump, + + .start = automount_start, + .stop = automount_stop, + + .serialize = automount_serialize, + .deserialize_item = automount_deserialize_item, + + .active_state = automount_active_state, + .sub_state_to_string = automount_sub_state_to_string, + + .check_gc = automount_check_gc, + + .fd_event = automount_fd_event, + + .reset_failed = automount_reset_failed, + + .bus_interface = "org.freedesktop.systemd1.Automount", + .bus_message_handler = bus_automount_message_handler, + .bus_invalidating_properties = bus_automount_invalidating_properties, + + .shutdown = automount_shutdown, + + .status_message_formats = { + .finished_start_job = { + [JOB_DONE] = "Set up automount %s.", + [JOB_FAILED] = "Failed to set up automount %s.", + [JOB_DEPENDENCY] = "Dependency failed for %s.", + }, + .finished_stop_job = { + [JOB_DONE] = "Unset automount %s.", + [JOB_FAILED] = "Failed to unset automount %s.", + }, + }, +}; diff --git a/src/core/automount.h b/src/core/automount.h new file mode 100644 index 000000000..3d5736d1c --- /dev/null +++ b/src/core/automount.h @@ -0,0 +1,73 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +typedef struct Automount Automount; + +#include "unit.h" + +typedef enum AutomountState { + AUTOMOUNT_DEAD, + AUTOMOUNT_WAITING, + AUTOMOUNT_RUNNING, + AUTOMOUNT_FAILED, + _AUTOMOUNT_STATE_MAX, + _AUTOMOUNT_STATE_INVALID = -1 +} AutomountState; + +typedef enum AutomountResult { + AUTOMOUNT_SUCCESS, + AUTOMOUNT_FAILURE_RESOURCES, + _AUTOMOUNT_RESULT_MAX, + _AUTOMOUNT_RESULT_INVALID = -1 +} AutomountResult; + +struct Automount { + Unit meta; + + AutomountState state, deserialized_state; + + char *where; + + UnitRef mount; + + int pipe_fd; + mode_t directory_mode; + Watch pipe_watch; + dev_t dev_id; + + Set *tokens; + + AutomountResult result; +}; + +extern const UnitVTable automount_vtable; + +int automount_send_ready(Automount *a, int status); + +int automount_add_one_mount_link(Automount *a, Mount *m); + +const char* automount_state_to_string(AutomountState i); +AutomountState automount_state_from_string(const char *s); + +const char* automount_result_to_string(AutomountResult i); +AutomountResult automount_result_from_string(const char *s); diff --git a/src/core/build.h b/src/core/build.h new file mode 100644 index 000000000..4513a0bad --- /dev/null +++ b/src/core/build.h @@ -0,0 +1,84 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +#ifdef HAVE_PAM +#define _PAM_FEATURE_ "+PAM" +#else +#define _PAM_FEATURE_ "-PAM" +#endif + +#ifdef HAVE_LIBWRAP +#define _LIBWRAP_FEATURE_ "+LIBWRAP" +#else +#define _LIBWRAP_FEATURE_ "-LIBWRAP" +#endif + +#ifdef HAVE_AUDIT +#define _AUDIT_FEATURE_ "+AUDIT" +#else +#define _AUDIT_FEATURE_ "-AUDIT" +#endif + +#ifdef HAVE_SELINUX +#define _SELINUX_FEATURE_ "+SELINUX" +#else +#define _SELINUX_FEATURE_ "-SELINUX" +#endif + +#ifdef HAVE_IMA +#define _IMA_FEATURE_ "+IMA" +#else +#define _IMA_FEATURE_ "-IMA" +#endif + +#ifdef HAVE_SYSV_COMPAT +#define _SYSVINIT_FEATURE_ "+SYSVINIT" +#else +#define _SYSVINIT_FEATURE_ "-SYSVINIT" +#endif + +#ifdef HAVE_LIBCRYPTSETUP +#define _LIBCRYPTSETUP_FEATURE_ "+LIBCRYPTSETUP" +#else +#define _LIBCRYPTSETUP_FEATURE_ "-LIBCRYPTSETUP" +#endif + +#ifdef HAVE_GCRYPT +#define _GCRYPT_FEATURE_ "+GCRYPT" +#else +#define _GCRYPT_FEATURE_ "-GCRYPT" +#endif + +#ifdef HAVE_ACL +#define _ACL_FEATURE_ "+ACL" +#else +#define _ACL_FEATURE_ "-ACL" +#endif + +#ifdef HAVE_XZ +#define _XZ_FEATURE_ "+XZ" +#else +#define _XZ_FEATURE_ "-XZ" +#endif + +#define SYSTEMD_FEATURES _PAM_FEATURE_ " " _LIBWRAP_FEATURE_ " " _AUDIT_FEATURE_ " " _SELINUX_FEATURE_ " " _IMA_FEATURE_ " " _SYSVINIT_FEATURE_ " " _LIBCRYPTSETUP_FEATURE_ " " _GCRYPT_FEATURE_ " " _ACL_FEATURE_ " " _XZ_FEATURE_ diff --git a/src/core/bus-errors.h b/src/core/bus-errors.h new file mode 100644 index 000000000..04c1b2849 --- /dev/null +++ b/src/core/bus-errors.h @@ -0,0 +1,55 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +#include +#include + +#define BUS_ERROR_NO_SUCH_UNIT "org.freedesktop.systemd1.NoSuchUnit" +#define BUS_ERROR_NO_SUCH_JOB "org.freedesktop.systemd1.NoSuchJob" +#define BUS_ERROR_NOT_SUBSCRIBED "org.freedesktop.systemd1.NotSubscribed" +#define BUS_ERROR_INVALID_PATH "org.freedesktop.systemd1.InvalidPath" +#define BUS_ERROR_INVALID_NAME "org.freedesktop.systemd1.InvalidName" +#define BUS_ERROR_UNIT_TYPE_MISMATCH "org.freedesktop.systemd1.UnitTypeMismatch" +#define BUS_ERROR_UNIT_EXISTS "org.freedesktop.systemd1.UnitExists" +#define BUS_ERROR_NOT_SUPPORTED "org.freedesktop.systemd1.NotSupported" +#define BUS_ERROR_INVALID_JOB_MODE "org.freedesktop.systemd1.InvalidJobMode" +#define BUS_ERROR_ONLY_BY_DEPENDENCY "org.freedesktop.systemd1.OnlyByDependency" +#define BUS_ERROR_NO_ISOLATION "org.freedesktop.systemd1.NoIsolation" +#define BUS_ERROR_LOAD_FAILED "org.freedesktop.systemd1.LoadFailed" +#define BUS_ERROR_MASKED "org.freedesktop.systemd1.Masked" +#define BUS_ERROR_JOB_TYPE_NOT_APPLICABLE "org.freedesktop.systemd1.JobTypeNotApplicable" +#define BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE "org.freedesktop.systemd1.TransactionIsDestructive" +#define BUS_ERROR_TRANSACTION_JOBS_CONFLICTING "org.freedesktop.systemd1.TransactionJobsConflicting" +#define BUS_ERROR_TRANSACTION_ORDER_IS_CYCLIC "org.freedesktop.systemd1.TransactionOrderIsCyclic" +#define BUS_ERROR_SHUTTING_DOWN "org.freedesktop.systemd1.ShuttingDown" +#define BUS_ERROR_NO_SUCH_PROCESS "org.freedesktop.systemd1.NoSuchProcess" + +static inline const char *bus_error(const DBusError *e, int r) { + if (e && e->message) + return e->message; + + if (r >= 0) + return strerror(r); + + return strerror(-r); +} diff --git a/src/core/cgroup-attr.c b/src/core/cgroup-attr.c new file mode 100644 index 000000000..71af09cf8 --- /dev/null +++ b/src/core/cgroup-attr.c @@ -0,0 +1,102 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +#include "cgroup-attr.h" +#include "cgroup-util.h" +#include "list.h" + +int cgroup_attribute_apply(CGroupAttribute *a, CGroupBonding *b) { + int r; + char *path = NULL; + char *v = NULL; + + assert(a); + + b = cgroup_bonding_find_list(b, a->controller); + if (!b) + return 0; + + if (a->map_callback) { + r = a->map_callback(a->controller, a->name, a->value, &v); + if (r < 0) + return r; + } + + r = cg_get_path(a->controller, b->path, a->name, &path); + if (r < 0) { + free(v); + return r; + } + + r = write_one_line_file(path, v ? v : a->value); + if (r < 0) + log_warning("Failed to write '%s' to %s: %s", v ? v : a->value, path, strerror(-r)); + + free(path); + free(v); + + return r; +} + +int cgroup_attribute_apply_list(CGroupAttribute *first, CGroupBonding *b) { + CGroupAttribute *a; + int r = 0; + + LIST_FOREACH(by_unit, a, first) { + int k; + + k = cgroup_attribute_apply(a, b); + if (r == 0) + r = k; + } + + return r; +} + +CGroupAttribute *cgroup_attribute_find_list(CGroupAttribute *first, const char *controller, const char *name) { + CGroupAttribute *a; + + assert(controller); + assert(name); + + LIST_FOREACH(by_unit, a, first) + if (streq(a->controller, controller) && + streq(a->name, name)) + return a; + + return NULL; +} + +static void cgroup_attribute_free(CGroupAttribute *a) { + assert(a); + + free(a->controller); + free(a->name); + free(a->value); + free(a); +} + +void cgroup_attribute_free_list(CGroupAttribute *first) { + CGroupAttribute *a, *n; + + LIST_FOREACH_SAFE(by_unit, a, n, first) + cgroup_attribute_free(a); +} diff --git a/src/core/cgroup-attr.h b/src/core/cgroup-attr.h new file mode 100644 index 000000000..2b754eac4 --- /dev/null +++ b/src/core/cgroup-attr.h @@ -0,0 +1,46 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +typedef struct CGroupAttribute CGroupAttribute; + +typedef int (*CGroupAttributeMapCallback)(const char *controller, const char*name, const char *value, char **ret); + +#include "unit.h" +#include "cgroup.h" + +struct CGroupAttribute { + char *controller; + char *name; + char *value; + + CGroupAttributeMapCallback map_callback; + + LIST_FIELDS(CGroupAttribute, by_unit); +}; + +int cgroup_attribute_apply(CGroupAttribute *a, CGroupBonding *b); +int cgroup_attribute_apply_list(CGroupAttribute *first, CGroupBonding *b); + +CGroupAttribute *cgroup_attribute_find_list(CGroupAttribute *first, const char *controller, const char *name); + +void cgroup_attribute_free_list(CGroupAttribute *first); diff --git a/src/core/cgroup.c b/src/core/cgroup.c new file mode 100644 index 000000000..8fc173148 --- /dev/null +++ b/src/core/cgroup.c @@ -0,0 +1,598 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include + +#include "cgroup.h" +#include "cgroup-util.h" +#include "log.h" +#include "strv.h" +#include "path-util.h" + +int cgroup_bonding_realize(CGroupBonding *b) { + int r; + + assert(b); + assert(b->path); + assert(b->controller); + + r = cg_create(b->controller, b->path); + if (r < 0) { + log_warning("Failed to create cgroup %s:%s: %s", b->controller, b->path, strerror(-r)); + return r; + } + + b->realized = true; + + return 0; +} + +int cgroup_bonding_realize_list(CGroupBonding *first) { + CGroupBonding *b; + int r; + + LIST_FOREACH(by_unit, b, first) + if ((r = cgroup_bonding_realize(b)) < 0 && b->essential) + return r; + + return 0; +} + +void cgroup_bonding_free(CGroupBonding *b, bool trim) { + assert(b); + + if (b->unit) { + CGroupBonding *f; + + LIST_REMOVE(CGroupBonding, by_unit, b->unit->cgroup_bondings, b); + + if (streq(b->controller, SYSTEMD_CGROUP_CONTROLLER)) { + assert_se(f = hashmap_get(b->unit->manager->cgroup_bondings, b->path)); + LIST_REMOVE(CGroupBonding, by_path, f, b); + + if (f) + hashmap_replace(b->unit->manager->cgroup_bondings, b->path, f); + else + hashmap_remove(b->unit->manager->cgroup_bondings, b->path); + } + } + + if (b->realized && b->ours && trim) + cg_trim(b->controller, b->path, false); + + free(b->controller); + free(b->path); + free(b); +} + +void cgroup_bonding_free_list(CGroupBonding *first, bool remove_or_trim) { + CGroupBonding *b, *n; + + LIST_FOREACH_SAFE(by_unit, b, n, first) + cgroup_bonding_free(b, remove_or_trim); +} + +void cgroup_bonding_trim(CGroupBonding *b, bool delete_root) { + assert(b); + + if (b->realized && b->ours) + cg_trim(b->controller, b->path, delete_root); +} + +void cgroup_bonding_trim_list(CGroupBonding *first, bool delete_root) { + CGroupBonding *b; + + LIST_FOREACH(by_unit, b, first) + cgroup_bonding_trim(b, delete_root); +} + + +int cgroup_bonding_install(CGroupBonding *b, pid_t pid, const char *cgroup_suffix) { + char *p = NULL; + const char *path; + int r; + + assert(b); + assert(pid >= 0); + + if (cgroup_suffix) { + p = strjoin(b->path, "/", cgroup_suffix, NULL); + if (!p) + return -ENOMEM; + + path = p; + } else + path = b->path; + + r = cg_create_and_attach(b->controller, path, pid); + free(p); + + if (r < 0) + return r; + + b->realized = true; + return 0; +} + +int cgroup_bonding_install_list(CGroupBonding *first, pid_t pid, const char *cgroup_suffix) { + CGroupBonding *b; + int r; + + LIST_FOREACH(by_unit, b, first) { + r = cgroup_bonding_install(b, pid, cgroup_suffix); + if (r < 0 && b->essential) + return r; + } + + return 0; +} + +int cgroup_bonding_set_group_access(CGroupBonding *b, mode_t mode, uid_t uid, gid_t gid) { + assert(b); + + if (!b->realized) + return -EINVAL; + + return cg_set_group_access(b->controller, b->path, mode, uid, gid); +} + +int cgroup_bonding_set_group_access_list(CGroupBonding *first, mode_t mode, uid_t uid, gid_t gid) { + CGroupBonding *b; + int r; + + LIST_FOREACH(by_unit, b, first) { + r = cgroup_bonding_set_group_access(b, mode, uid, gid); + if (r < 0) + return r; + } + + return 0; +} + +int cgroup_bonding_set_task_access(CGroupBonding *b, mode_t mode, uid_t uid, gid_t gid, int sticky) { + assert(b); + + if (!b->realized) + return -EINVAL; + + return cg_set_task_access(b->controller, b->path, mode, uid, gid, sticky); +} + +int cgroup_bonding_set_task_access_list(CGroupBonding *first, mode_t mode, uid_t uid, gid_t gid, int sticky) { + CGroupBonding *b; + int r; + + LIST_FOREACH(by_unit, b, first) { + r = cgroup_bonding_set_task_access(b, mode, uid, gid, sticky); + if (r < 0) + return r; + } + + return 0; +} + +int cgroup_bonding_kill(CGroupBonding *b, int sig, bool sigcont, bool rem, Set *s, const char *cgroup_suffix) { + char *p = NULL; + const char *path; + int r; + + assert(b); + assert(sig >= 0); + + /* Don't kill cgroups that aren't ours */ + if (!b->ours) + return 0; + + if (cgroup_suffix) { + p = strjoin(b->path, "/", cgroup_suffix, NULL); + if (!p) + return -ENOMEM; + + path = p; + } else + path = b->path; + + r = cg_kill_recursive(b->controller, path, sig, sigcont, true, rem, s); + free(p); + + return r; +} + +int cgroup_bonding_kill_list(CGroupBonding *first, int sig, bool sigcont, bool rem, Set *s, const char *cgroup_suffix) { + CGroupBonding *b; + Set *allocated_set = NULL; + int ret = -EAGAIN, r; + + if (!first) + return 0; + + if (!s) + if (!(s = allocated_set = set_new(trivial_hash_func, trivial_compare_func))) + return -ENOMEM; + + LIST_FOREACH(by_unit, b, first) { + r = cgroup_bonding_kill(b, sig, sigcont, rem, s, cgroup_suffix); + if (r < 0) { + if (r == -EAGAIN || r == -ESRCH) + continue; + + ret = r; + goto finish; + } + + if (ret < 0 || r > 0) + ret = r; + } + +finish: + if (allocated_set) + set_free(allocated_set); + + return ret; +} + +/* Returns 1 if the group is empty, 0 if it is not, -EAGAIN if we + * cannot know */ +int cgroup_bonding_is_empty(CGroupBonding *b) { + int r; + + assert(b); + + if ((r = cg_is_empty_recursive(b->controller, b->path, true)) < 0) + return r; + + /* If it is empty it is empty */ + if (r > 0) + return 1; + + /* It's not only us using this cgroup, so we just don't know */ + return b->ours ? 0 : -EAGAIN; +} + +int cgroup_bonding_is_empty_list(CGroupBonding *first) { + CGroupBonding *b; + + LIST_FOREACH(by_unit, b, first) { + int r; + + if ((r = cgroup_bonding_is_empty(b)) < 0) { + /* If this returned -EAGAIN, then we don't know if the + * group is empty, so let's see if another group can + * tell us */ + + if (r != -EAGAIN) + return r; + } else + return r; + } + + return -EAGAIN; +} + +int manager_setup_cgroup(Manager *m) { + char *current = NULL, *path = NULL; + int r; + char suffix[32]; + + assert(m); + + /* 0. Be nice to Ingo Molnar #628004 */ + if (path_is_mount_point("/sys/fs/cgroup/systemd", false) <= 0) { + log_warning("No control group support available, not creating root group."); + return 0; + } + + /* 1. Determine hierarchy */ + r = cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, 0, ¤t); + if (r < 0) { + log_error("Cannot determine cgroup we are running in: %s", strerror(-r)); + goto finish; + } + + if (m->running_as == SYSTEMD_SYSTEM) + strcpy(suffix, "/system"); + else { + snprintf(suffix, sizeof(suffix), "/systemd-%lu", (unsigned long) getpid()); + char_array_0(suffix); + } + + free(m->cgroup_hierarchy); + if (endswith(current, suffix)) { + /* We probably got reexecuted and can continue to use our root cgroup */ + m->cgroup_hierarchy = current; + current = NULL; + + } else { + /* We need a new root cgroup */ + m->cgroup_hierarchy = NULL; + if (asprintf(&m->cgroup_hierarchy, "%s%s", streq(current, "/") ? "" : current, suffix) < 0) { + r = log_oom(); + goto finish; + } + } + + /* 2. Show data */ + r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, m->cgroup_hierarchy, NULL, &path); + if (r < 0) { + log_error("Cannot find cgroup mount point: %s", strerror(-r)); + goto finish; + } + + log_debug("Using cgroup controller " SYSTEMD_CGROUP_CONTROLLER ". File system hierarchy is at %s.", path); + + /* 3. Install agent */ + r = cg_install_release_agent(SYSTEMD_CGROUP_CONTROLLER, SYSTEMD_CGROUP_AGENT_PATH); + if (r < 0) + log_warning("Failed to install release agent, ignoring: %s", strerror(-r)); + else if (r > 0) + log_debug("Installed release agent."); + else + log_debug("Release agent already installed."); + + /* 4. Realize the group */ + r = cg_create_and_attach(SYSTEMD_CGROUP_CONTROLLER, m->cgroup_hierarchy, 0); + if (r < 0) { + log_error("Failed to create root cgroup hierarchy: %s", strerror(-r)); + goto finish; + } + + /* 5. And pin it, so that it cannot be unmounted */ + if (m->pin_cgroupfs_fd >= 0) + close_nointr_nofail(m->pin_cgroupfs_fd); + + m->pin_cgroupfs_fd = open(path, O_RDONLY|O_CLOEXEC|O_DIRECTORY|O_NOCTTY|O_NONBLOCK); + if (r < 0) { + log_error("Failed to open pin file: %m"); + r = -errno; + goto finish; + } + + log_debug("Created root group."); + + cg_shorten_controllers(m->default_controllers); + +finish: + free(current); + free(path); + + return r; +} + +void manager_shutdown_cgroup(Manager *m, bool delete) { + assert(m); + + if (delete && m->cgroup_hierarchy) + cg_delete(SYSTEMD_CGROUP_CONTROLLER, m->cgroup_hierarchy); + + if (m->pin_cgroupfs_fd >= 0) { + close_nointr_nofail(m->pin_cgroupfs_fd); + m->pin_cgroupfs_fd = -1; + } + + free(m->cgroup_hierarchy); + m->cgroup_hierarchy = NULL; +} + +int cgroup_bonding_get(Manager *m, const char *cgroup, CGroupBonding **bonding) { + CGroupBonding *b; + char *p; + + assert(m); + assert(cgroup); + assert(bonding); + + b = hashmap_get(m->cgroup_bondings, cgroup); + if (b) { + *bonding = b; + return 1; + } + + p = strdup(cgroup); + if (!p) + return -ENOMEM; + + for (;;) { + char *e; + + e = strrchr(p, '/'); + if (!e || e == p) { + free(p); + *bonding = NULL; + return 0; + } + + *e = 0; + + b = hashmap_get(m->cgroup_bondings, p); + if (b) { + free(p); + *bonding = b; + return 1; + } + } +} + +int cgroup_notify_empty(Manager *m, const char *group) { + CGroupBonding *l, *b; + int r; + + assert(m); + assert(group); + + r = cgroup_bonding_get(m, group, &l); + if (r <= 0) + return r; + + LIST_FOREACH(by_path, b, l) { + int t; + + if (!b->unit) + continue; + + t = cgroup_bonding_is_empty_list(b); + if (t < 0) { + + /* If we don't know, we don't know */ + if (t != -EAGAIN) + log_warning("Failed to check whether cgroup is empty: %s", strerror(errno)); + + continue; + } + + if (t > 0) { + /* If it is empty, let's delete it */ + cgroup_bonding_trim_list(b->unit->cgroup_bondings, true); + + if (UNIT_VTABLE(b->unit)->cgroup_notify_empty) + UNIT_VTABLE(b->unit)->cgroup_notify_empty(b->unit); + } + } + + return 0; +} + +Unit* cgroup_unit_by_pid(Manager *m, pid_t pid) { + CGroupBonding *l, *b; + char *group = NULL; + + assert(m); + + if (pid <= 1) + return NULL; + + if (cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, pid, &group) < 0) + return NULL; + + l = hashmap_get(m->cgroup_bondings, group); + + if (!l) { + char *slash; + + while ((slash = strrchr(group, '/'))) { + if (slash == group) + break; + + *slash = 0; + + if ((l = hashmap_get(m->cgroup_bondings, group))) + break; + } + } + + free(group); + + LIST_FOREACH(by_path, b, l) { + + if (!b->unit) + continue; + + if (b->ours) + return b->unit; + } + + return NULL; +} + +CGroupBonding *cgroup_bonding_find_list(CGroupBonding *first, const char *controller) { + CGroupBonding *b; + + assert(controller); + + LIST_FOREACH(by_unit, b, first) + if (streq(b->controller, controller)) + return b; + + return NULL; +} + +char *cgroup_bonding_to_string(CGroupBonding *b) { + char *r; + + assert(b); + + if (asprintf(&r, "%s:%s", b->controller, b->path) < 0) + return NULL; + + return r; +} + +pid_t cgroup_bonding_search_main_pid(CGroupBonding *b) { + FILE *f; + pid_t pid = 0, npid, mypid; + + assert(b); + + if (!b->ours) + return 0; + + if (cg_enumerate_processes(b->controller, b->path, &f) < 0) + return 0; + + mypid = getpid(); + + while (cg_read_pid(f, &npid) > 0) { + pid_t ppid; + + if (npid == pid) + continue; + + /* Ignore processes that aren't our kids */ + if (get_parent_of_pid(npid, &ppid) >= 0 && ppid != mypid) + continue; + + if (pid != 0) { + /* Dang, there's more than one daemonized PID + in this group, so we don't know what process + is the main process. */ + pid = 0; + break; + } + + pid = npid; + } + + fclose(f); + + return pid; +} + +pid_t cgroup_bonding_search_main_pid_list(CGroupBonding *first) { + CGroupBonding *b; + pid_t pid; + + /* Try to find a main pid from this cgroup, but checking if + * there's only one PID in the cgroup and returning it. Later + * on we might want to add additional, smarter heuristics + * here. */ + + LIST_FOREACH(by_unit, b, first) + if ((pid = cgroup_bonding_search_main_pid(b)) != 0) + return pid; + + return 0; + +} diff --git a/src/core/cgroup.h b/src/core/cgroup.h new file mode 100644 index 000000000..229da52ba --- /dev/null +++ b/src/core/cgroup.h @@ -0,0 +1,91 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +typedef struct CGroupBonding CGroupBonding; + +#include "unit.h" + +/* Binds a cgroup to a name */ +struct CGroupBonding { + char *controller; + char *path; + + Unit *unit; + + /* For the Unit::cgroup_bondings list */ + LIST_FIELDS(CGroupBonding, by_unit); + + /* For the Manager::cgroup_bondings hashmap */ + LIST_FIELDS(CGroupBonding, by_path); + + /* When shutting down, remove cgroup? Are our own tasks the + * only ones in this group?*/ + bool ours:1; + + /* If we cannot create this group, or add a process to it, is this fatal? */ + bool essential:1; + + /* This cgroup is realized */ + bool realized:1; +}; + +int cgroup_bonding_realize(CGroupBonding *b); +int cgroup_bonding_realize_list(CGroupBonding *first); + +void cgroup_bonding_free(CGroupBonding *b, bool trim); +void cgroup_bonding_free_list(CGroupBonding *first, bool trim); + +int cgroup_bonding_install(CGroupBonding *b, pid_t pid, const char *suffix); +int cgroup_bonding_install_list(CGroupBonding *first, pid_t pid, const char *suffix); + +int cgroup_bonding_set_group_access(CGroupBonding *b, mode_t mode, uid_t uid, gid_t gid); +int cgroup_bonding_set_group_access_list(CGroupBonding *b, mode_t mode, uid_t uid, gid_t gid); + +int cgroup_bonding_set_task_access(CGroupBonding *b, mode_t mode, uid_t uid, gid_t gid, int sticky); +int cgroup_bonding_set_task_access_list(CGroupBonding *b, mode_t mode, uid_t uid, gid_t gid, int sticky); + +int cgroup_bonding_kill(CGroupBonding *b, int sig, bool sigcont, bool rem, Set *s, const char *suffix); +int cgroup_bonding_kill_list(CGroupBonding *first, int sig, bool sigcont, bool rem, Set *s, const char *suffix); + +void cgroup_bonding_trim(CGroupBonding *first, bool delete_root); +void cgroup_bonding_trim_list(CGroupBonding *first, bool delete_root); + +int cgroup_bonding_is_empty(CGroupBonding *b); +int cgroup_bonding_is_empty_list(CGroupBonding *first); + +CGroupBonding *cgroup_bonding_find_list(CGroupBonding *first, const char *controller); + +char *cgroup_bonding_to_string(CGroupBonding *b); + +pid_t cgroup_bonding_search_main_pid(CGroupBonding *b); +pid_t cgroup_bonding_search_main_pid_list(CGroupBonding *b); + +#include "manager.h" + +int manager_setup_cgroup(Manager *m); +void manager_shutdown_cgroup(Manager *m, bool delete); + +int cgroup_bonding_get(Manager *m, const char *cgroup, CGroupBonding **bonding); +int cgroup_notify_empty(Manager *m, const char *group); + +Unit* cgroup_unit_by_pid(Manager *m, pid_t pid); diff --git a/src/core/condition.c b/src/core/condition.c new file mode 100644 index 000000000..b3184922b --- /dev/null +++ b/src/core/condition.c @@ -0,0 +1,384 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_SELINUX +#include +#endif + +#include +#include "util.h" +#include "condition.h" +#include "virt.h" +#include "path-util.h" + +Condition* condition_new(ConditionType type, const char *parameter, bool trigger, bool negate) { + Condition *c; + + assert(type < _CONDITION_TYPE_MAX); + + c = new0(Condition, 1); + if (!c) + return NULL; + + c->type = type; + c->trigger = trigger; + c->negate = negate; + + if (parameter) { + c->parameter = strdup(parameter); + if (!c->parameter) { + free(c); + return NULL; + } + } + + return c; +} + +void condition_free(Condition *c) { + assert(c); + + free(c->parameter); + free(c); +} + +void condition_free_list(Condition *first) { + Condition *c, *n; + + LIST_FOREACH_SAFE(conditions, c, n, first) + condition_free(c); +} + +static bool test_kernel_command_line(const char *parameter) { + char *line, *w, *state, *word = NULL; + bool equal; + int r; + size_t l, pl; + bool found = false; + + assert(parameter); + + if (detect_container(NULL) > 0) + return false; + + r = read_one_line_file("/proc/cmdline", &line); + if (r < 0) { + log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r)); + return false; + } + + equal = !!strchr(parameter, '='); + pl = strlen(parameter); + + FOREACH_WORD_QUOTED(w, l, line, state) { + + free(word); + word = strndup(w, l); + if (!word) + break; + + if (equal) { + if (streq(word, parameter)) { + found = true; + break; + } + } else { + if (startswith(word, parameter) && (word[pl] == '=' || word[pl] == 0)) { + found = true; + break; + } + } + + } + + free(word); + free(line); + + return found; +} + +static bool test_virtualization(const char *parameter) { + int b; + Virtualization v; + const char *id; + + assert(parameter); + + v = detect_virtualization(&id); + if (v < 0) { + log_warning("Failed to detect virtualization, ignoring: %s", strerror(-v)); + return false; + } + + /* First, compare with yes/no */ + b = parse_boolean(parameter); + + if (v > 0 && b > 0) + return true; + + if (v == 0 && b == 0) + return true; + + /* Then, compare categorization */ + if (v == VIRTUALIZATION_VM && streq(parameter, "vm")) + return true; + + if (v == VIRTUALIZATION_CONTAINER && streq(parameter, "container")) + return true; + + /* Finally compare id */ + return v > 0 && streq(parameter, id); +} + +static bool test_security(const char *parameter) { +#ifdef HAVE_SELINUX + if (streq(parameter, "selinux")) + return is_selinux_enabled() > 0; +#endif + return false; +} + +static bool test_capability(const char *parameter) { + cap_value_t value; + FILE *f; + char line[LINE_MAX]; + unsigned long long capabilities = (unsigned long long) -1; + + /* If it's an invalid capability, we don't have it */ + + if (cap_from_name(parameter, &value) < 0) + return false; + + /* If it's a valid capability we default to assume + * that we have it */ + + f = fopen("/proc/self/status", "re"); + if (!f) + return true; + + while (fgets(line, sizeof(line), f)) { + truncate_nl(line); + + if (startswith(line, "CapBnd:")) { + (void) sscanf(line+7, "%llx", &capabilities); + break; + } + } + + fclose(f); + + return !!(capabilities & (1ULL << value)); +} + +static bool test_host(const char *parameter) { + sd_id128_t x, y; + char *h; + int r; + bool b; + + if (sd_id128_from_string(parameter, &x) >= 0) { + + r = sd_id128_get_machine(&y); + if (r < 0) + return false; + + return sd_id128_equal(x, y); + } + + h = gethostname_malloc(); + if (!h) + return false; + + b = fnmatch(parameter, h, FNM_CASEFOLD) == 0; + free(h); + + return b; +} + +static bool test_ac_power(const char *parameter) { + int r; + + r = parse_boolean(parameter); + if (r < 0) + return true; + + return (on_ac_power() != 0) == !!r; +} + +bool condition_test(Condition *c) { + assert(c); + + switch(c->type) { + + case CONDITION_PATH_EXISTS: + return (access(c->parameter, F_OK) >= 0) == !c->negate; + + case CONDITION_PATH_EXISTS_GLOB: + return (glob_exists(c->parameter) > 0) == !c->negate; + + case CONDITION_PATH_IS_DIRECTORY: { + struct stat st; + + if (stat(c->parameter, &st) < 0) + return c->negate; + return S_ISDIR(st.st_mode) == !c->negate; + } + + case CONDITION_PATH_IS_SYMBOLIC_LINK: { + struct stat st; + + if (lstat(c->parameter, &st) < 0) + return c->negate; + return S_ISLNK(st.st_mode) == !c->negate; + } + + case CONDITION_PATH_IS_MOUNT_POINT: + return (path_is_mount_point(c->parameter, true) > 0) == !c->negate; + + case CONDITION_PATH_IS_READ_WRITE: + return (path_is_read_only_fs(c->parameter) > 0) == c->negate; + + case CONDITION_DIRECTORY_NOT_EMPTY: { + int k; + + k = dir_is_empty(c->parameter); + return !(k == -ENOENT || k > 0) == !c->negate; + } + + case CONDITION_FILE_NOT_EMPTY: { + struct stat st; + + if (stat(c->parameter, &st) < 0) + return c->negate; + + return (S_ISREG(st.st_mode) && st.st_size > 0) == !c->negate; + } + + case CONDITION_FILE_IS_EXECUTABLE: { + struct stat st; + + if (stat(c->parameter, &st) < 0) + return c->negate; + + return (S_ISREG(st.st_mode) && (st.st_mode & 0111)) == !c->negate; + } + + case CONDITION_KERNEL_COMMAND_LINE: + return test_kernel_command_line(c->parameter) == !c->negate; + + case CONDITION_VIRTUALIZATION: + return test_virtualization(c->parameter) == !c->negate; + + case CONDITION_SECURITY: + return test_security(c->parameter) == !c->negate; + + case CONDITION_CAPABILITY: + return test_capability(c->parameter) == !c->negate; + + case CONDITION_HOST: + return test_host(c->parameter) == !c->negate; + + case CONDITION_AC_POWER: + return test_ac_power(c->parameter) == !c->negate; + + case CONDITION_NULL: + return !c->negate; + + default: + assert_not_reached("Invalid condition type."); + } +} + +bool condition_test_list(Condition *first) { + Condition *c; + int triggered = -1; + + /* If the condition list is empty, then it is true */ + if (!first) + return true; + + /* Otherwise, if all of the non-trigger conditions apply and + * if any of the trigger conditions apply (unless there are + * none) we return true */ + LIST_FOREACH(conditions, c, first) { + bool b; + + b = condition_test(c); + + if (!c->trigger && !b) + return false; + + if (c->trigger && triggered <= 0) + triggered = b; + } + + return triggered != 0; +} + +void condition_dump(Condition *c, FILE *f, const char *prefix) { + assert(c); + assert(f); + + if (!prefix) + prefix = ""; + + fprintf(f, + "%s\t%s: %s%s%s\n", + prefix, + condition_type_to_string(c->type), + c->trigger ? "|" : "", + c->negate ? "!" : "", + c->parameter); +} + +void condition_dump_list(Condition *first, FILE *f, const char *prefix) { + Condition *c; + + LIST_FOREACH(conditions, c, first) + condition_dump(c, f, prefix); +} + +static const char* const condition_type_table[_CONDITION_TYPE_MAX] = { + [CONDITION_PATH_EXISTS] = "ConditionPathExists", + [CONDITION_PATH_EXISTS_GLOB] = "ConditionPathExistsGlob", + [CONDITION_PATH_IS_DIRECTORY] = "ConditionPathIsDirectory", + [CONDITION_PATH_IS_SYMBOLIC_LINK] = "ConditionPathIsSymbolicLink", + [CONDITION_PATH_IS_MOUNT_POINT] = "ConditionPathIsMountPoint", + [CONDITION_PATH_IS_READ_WRITE] = "ConditionPathIsReadWrite", + [CONDITION_DIRECTORY_NOT_EMPTY] = "ConditionDirectoryNotEmpty", + [CONDITION_FILE_NOT_EMPTY] = "ConditionFileNotEmpty", + [CONDITION_KERNEL_COMMAND_LINE] = "ConditionKernelCommandLine", + [CONDITION_VIRTUALIZATION] = "ConditionVirtualization", + [CONDITION_SECURITY] = "ConditionSecurity", + [CONDITION_HOST] = "ConditionHost", + [CONDITION_AC_POWER] = "ConditionACPower", + [CONDITION_NULL] = "ConditionNull" +}; + +DEFINE_STRING_TABLE_LOOKUP(condition_type, ConditionType); diff --git a/src/core/condition.h b/src/core/condition.h new file mode 100644 index 000000000..1797385d2 --- /dev/null +++ b/src/core/condition.h @@ -0,0 +1,70 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +#include + +#include "list.h" + +typedef enum ConditionType { + 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_KERNEL_COMMAND_LINE, + CONDITION_VIRTUALIZATION, + CONDITION_SECURITY, + CONDITION_CAPABILITY, + CONDITION_HOST, + CONDITION_AC_POWER, + CONDITION_NULL, + _CONDITION_TYPE_MAX, + _CONDITION_TYPE_INVALID = -1 +} ConditionType; + +typedef struct Condition { + ConditionType type; + char *parameter; + + bool trigger:1; + bool negate:1; + + LIST_FIELDS(struct Condition, conditions); +} Condition; + +Condition* condition_new(ConditionType type, const char *parameter, bool trigger, bool negate); +void condition_free(Condition *c); +void condition_free_list(Condition *c); + +bool condition_test(Condition *c); +bool condition_test_list(Condition *c); + +void condition_dump(Condition *c, FILE *f, const char *prefix); +void condition_dump_list(Condition *c, FILE *f, const char *prefix); + +const char* condition_type_to_string(ConditionType t); +int condition_type_from_string(const char *s); diff --git a/src/core/dbus-automount.c b/src/core/dbus-automount.c new file mode 100644 index 000000000..060cbf770 --- /dev/null +++ b/src/core/dbus-automount.c @@ -0,0 +1,75 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include + +#include "dbus-unit.h" +#include "dbus-automount.h" +#include "dbus-common.h" +#include "selinux-access.h" + +#define BUS_AUTOMOUNT_INTERFACE \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" + +#define INTROSPECTION \ + DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \ + "\n" \ + BUS_UNIT_INTERFACE \ + BUS_AUTOMOUNT_INTERFACE \ + BUS_PROPERTIES_INTERFACE \ + BUS_PEER_INTERFACE \ + BUS_INTROSPECTABLE_INTERFACE \ + "\n" + +#define INTERFACES_LIST \ + BUS_UNIT_INTERFACES_LIST \ + "org.freedesktop.systemd1.Automount\0" + +const char bus_automount_interface[] _introspect_("Automount") = BUS_AUTOMOUNT_INTERFACE; + +const char bus_automount_invalidating_properties[] = + "Result\0"; + +static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_automount_append_automount_result, automount_result, AutomountResult); + +static const BusProperty bus_automount_properties[] = { + { "Where", bus_property_append_string, "s", offsetof(Automount, where), true }, + { "DirectoryMode", bus_property_append_mode, "u", offsetof(Automount, directory_mode) }, + { "Result", bus_automount_append_automount_result, "s", offsetof(Automount, result) }, + { NULL, } +}; + +DBusHandlerResult bus_automount_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) { + Automount *am = AUTOMOUNT(u); + const BusBoundProperties bps[] = { + { "org.freedesktop.systemd1.Unit", bus_unit_properties, u }, + { "org.freedesktop.systemd1.Automount", bus_automount_properties, am }, + { NULL, } + }; + + SELINUX_UNIT_ACCESS_CHECK(u, c, message, "status"); + + return bus_default_message_handler(c, message, INTROSPECTION, INTERFACES_LIST, bps); +} diff --git a/src/core/dbus-automount.h b/src/core/dbus-automount.h new file mode 100644 index 000000000..b338e25fc --- /dev/null +++ b/src/core/dbus-automount.h @@ -0,0 +1,31 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +#include + +#include "unit.h" + +DBusHandlerResult bus_automount_message_handler(Unit *u, DBusConnection *c, DBusMessage *message); + +extern const char bus_automount_interface[]; +extern const char bus_automount_invalidating_properties[]; diff --git a/src/core/dbus-device.c b/src/core/dbus-device.c new file mode 100644 index 000000000..dbd91fe3d --- /dev/null +++ b/src/core/dbus-device.c @@ -0,0 +1,68 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include "dbus-unit.h" +#include "dbus-device.h" +#include "dbus-common.h" +#include "selinux-access.h" + +#define BUS_DEVICE_INTERFACE \ + " \n" \ + " \n" \ + " \n" + +#define INTROSPECTION \ + DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \ + "\n" \ + BUS_UNIT_INTERFACE \ + BUS_DEVICE_INTERFACE \ + BUS_PROPERTIES_INTERFACE \ + BUS_PEER_INTERFACE \ + BUS_INTROSPECTABLE_INTERFACE \ + "\n" + +#define INTERFACES_LIST \ + BUS_UNIT_INTERFACES_LIST \ + "org.freedesktop.systemd1.Device\0" + +const char bus_device_interface[] _introspect_("Device") = BUS_DEVICE_INTERFACE; + +const char bus_device_invalidating_properties[] = + "SysFSPath\0"; + +static const BusProperty bus_device_properties[] = { + { "SysFSPath", bus_property_append_string, "s", offsetof(Device, sysfs), true }, + { NULL, } +}; + + +DBusHandlerResult bus_device_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) { + Device *d = DEVICE(u); + const BusBoundProperties bps[] = { + { "org.freedesktop.systemd1.Unit", bus_unit_properties, u }, + { "org.freedesktop.systemd1.Device", bus_device_properties, d }, + { NULL, } + }; + + SELINUX_UNIT_ACCESS_CHECK(u, c, message, "status"); + + return bus_default_message_handler(c, message, INTROSPECTION, INTERFACES_LIST, bps); +} diff --git a/src/core/dbus-device.h b/src/core/dbus-device.h new file mode 100644 index 000000000..311e0685d --- /dev/null +++ b/src/core/dbus-device.h @@ -0,0 +1,31 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +#include + +#include "unit.h" + +DBusHandlerResult bus_device_message_handler(Unit *u, DBusConnection *c, DBusMessage *message); + +extern const char bus_device_interface[]; +extern const char bus_device_invalidating_properties[]; diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c new file mode 100644 index 000000000..e815cb58e --- /dev/null +++ b/src/core/dbus-execute.c @@ -0,0 +1,439 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include + +#include "dbus-execute.h" +#include "missing.h" +#include "ioprio.h" +#include "strv.h" +#include "dbus-common.h" +#include "syscall-list.h" + +DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_execute_append_input, exec_input, ExecInput); +DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_execute_append_output, exec_output, ExecOutput); + +int bus_execute_append_env_files(DBusMessageIter *i, const char *property, void *data) { + char **env_files = data, **j; + DBusMessageIter sub, sub2; + + assert(i); + assert(property); + + if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "(sb)", &sub)) + return -ENOMEM; + + STRV_FOREACH(j, env_files) { + dbus_bool_t b = false; + char *fn = *j; + + if (fn[0] == '-') { + b = true; + fn++; + } + + if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &fn) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_BOOLEAN, &b) || + !dbus_message_iter_close_container(&sub, &sub2)) + return -ENOMEM; + } + + if (!dbus_message_iter_close_container(i, &sub)) + return -ENOMEM; + + return 0; +} + +int bus_execute_append_oom_score_adjust(DBusMessageIter *i, const char *property, void *data) { + ExecContext *c = data; + int32_t n; + + assert(i); + assert(property); + assert(c); + + if (c->oom_score_adjust_set) + n = c->oom_score_adjust; + else { + char *t; + + n = 0; + if (read_one_line_file("/proc/self/oom_score_adj", &t) >= 0) { + safe_atoi(t, &n); + free(t); + } + } + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_INT32, &n)) + return -ENOMEM; + + return 0; +} + +int bus_execute_append_nice(DBusMessageIter *i, const char *property, void *data) { + ExecContext *c = data; + int32_t n; + + assert(i); + assert(property); + assert(c); + + if (c->nice_set) + n = c->nice; + else + n = getpriority(PRIO_PROCESS, 0); + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_INT32, &n)) + return -ENOMEM; + + return 0; +} + +int bus_execute_append_ioprio(DBusMessageIter *i, const char *property, void *data) { + ExecContext *c = data; + int32_t n; + + assert(i); + assert(property); + assert(c); + + if (c->ioprio_set) + n = c->ioprio; + else + n = ioprio_get(IOPRIO_WHO_PROCESS, 0); + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_INT32, &n)) + return -ENOMEM; + + return 0; +} + +int bus_execute_append_cpu_sched_policy(DBusMessageIter *i, const char *property, void *data) { + ExecContext *c = data; + int32_t n; + + assert(i); + assert(property); + assert(c); + + if (c->cpu_sched_set) + n = c->cpu_sched_policy; + else + n = sched_getscheduler(0); + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_INT32, &n)) + return -ENOMEM; + + return 0; +} + +int bus_execute_append_cpu_sched_priority(DBusMessageIter *i, const char *property, void *data) { + ExecContext *c = data; + int32_t n; + + assert(i); + assert(property); + assert(c); + + if (c->cpu_sched_set) + n = c->cpu_sched_priority; + else { + struct sched_param p; + n = 0; + + zero(p); + if (sched_getparam(0, &p) >= 0) + n = p.sched_priority; + } + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_INT32, &n)) + return -ENOMEM; + + return 0; +} + +int bus_execute_append_affinity(DBusMessageIter *i, const char *property, void *data) { + ExecContext *c = data; + dbus_bool_t b; + DBusMessageIter sub; + + assert(i); + assert(property); + assert(c); + + if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "y", &sub)) + return -ENOMEM; + + if (c->cpuset) + b = dbus_message_iter_append_fixed_array(&sub, DBUS_TYPE_BYTE, &c->cpuset, CPU_ALLOC_SIZE(c->cpuset_ncpus)); + else + b = dbus_message_iter_append_fixed_array(&sub, DBUS_TYPE_BYTE, &c->cpuset, 0); + + if (!b) + return -ENOMEM; + + if (!dbus_message_iter_close_container(i, &sub)) + return -ENOMEM; + + return 0; +} + +int bus_execute_append_timer_slack_nsec(DBusMessageIter *i, const char *property, void *data) { + ExecContext *c = data; + uint64_t u; + + assert(i); + assert(property); + assert(c); + + if (c->timer_slack_nsec != (nsec_t) -1) + u = (uint64_t) c->timer_slack_nsec; + else + u = (uint64_t) prctl(PR_GET_TIMERSLACK); + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_UINT64, &u)) + return -ENOMEM; + + return 0; +} + +int bus_execute_append_capability_bs(DBusMessageIter *i, const char *property, void *data) { + ExecContext *c = data; + uint64_t normal, inverted; + + assert(i); + assert(property); + assert(c); + + /* We store this negated internally, to match the kernel, but + * we expose it normalized. */ + + normal = *(uint64_t*) data; + inverted = ~normal; + + return bus_property_append_uint64(i, property, &inverted); +} + +int bus_execute_append_capabilities(DBusMessageIter *i, const char *property, void *data) { + ExecContext *c = data; + char *t = NULL; + const char *s; + dbus_bool_t b; + + assert(i); + assert(property); + assert(c); + + if (c->capabilities) + s = t = cap_to_text(c->capabilities, NULL); + else + s = ""; + + if (!s) + return -ENOMEM; + + b = dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &s); + + if (t) + cap_free(t); + + if (!b) + return -ENOMEM; + + return 0; +} + +int bus_execute_append_rlimits(DBusMessageIter *i, const char *property, void *data) { + ExecContext *c = data; + int r; + uint64_t u; + + assert(i); + assert(property); + assert(c); + + assert_se((r = rlimit_from_string(property)) >= 0); + + if (c->rlimit[r]) + u = (uint64_t) c->rlimit[r]->rlim_max; + else { + struct rlimit rl; + + zero(rl); + getrlimit(r, &rl); + + u = (uint64_t) rl.rlim_max; + } + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_UINT64, &u)) + return -ENOMEM; + + return 0; +} + +int bus_execute_append_command(DBusMessageIter *i, const char *property, void *data) { + ExecCommand *c = data; + DBusMessageIter sub, sub2, sub3; + + assert(i); + assert(property); + + if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "(sasbttttuii)", &sub)) + return -ENOMEM; + + LIST_FOREACH(command, c, c) { + char **l; + uint32_t pid; + int32_t code, status; + dbus_bool_t b; + + if (!c->path) + continue; + + if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &c->path) || + !dbus_message_iter_open_container(&sub2, DBUS_TYPE_ARRAY, "s", &sub3)) + return -ENOMEM; + + STRV_FOREACH(l, c->argv) + if (!dbus_message_iter_append_basic(&sub3, DBUS_TYPE_STRING, l)) + return -ENOMEM; + + pid = (uint32_t) c->exec_status.pid; + code = (int32_t) c->exec_status.code; + status = (int32_t) c->exec_status.status; + + b = !!c->ignore; + + if (!dbus_message_iter_close_container(&sub2, &sub3) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_BOOLEAN, &b) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT64, &c->exec_status.start_timestamp.realtime) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT64, &c->exec_status.start_timestamp.monotonic) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT64, &c->exec_status.exit_timestamp.realtime) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT64, &c->exec_status.exit_timestamp.monotonic) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT32, &pid) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_INT32, &code) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_INT32, &status)) + return -ENOMEM; + + if (!dbus_message_iter_close_container(&sub, &sub2)) + return -ENOMEM; + } + + if (!dbus_message_iter_close_container(i, &sub)) + return -ENOMEM; + + return 0; +} + +int bus_execute_append_syscall_filter(DBusMessageIter *i, const char *property, void *data) { + ExecContext *c = data; + dbus_bool_t b; + DBusMessageIter sub; + + assert(i); + assert(property); + assert(c); + + if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "u", &sub)) + return -ENOMEM; + + if (c->syscall_filter) + b = dbus_message_iter_append_fixed_array(&sub, DBUS_TYPE_UINT32, &c->syscall_filter, (syscall_max() + 31) >> 4); + else + b = dbus_message_iter_append_fixed_array(&sub, DBUS_TYPE_UINT32, &c->syscall_filter, 0); + + if (!b) + return -ENOMEM; + + if (!dbus_message_iter_close_container(i, &sub)) + return -ENOMEM; + + return 0; +} + +const BusProperty bus_exec_context_properties[] = { + { "Environment", bus_property_append_strv, "as", offsetof(ExecContext, environment), true }, + { "EnvironmentFiles", bus_execute_append_env_files, "a(sb)", offsetof(ExecContext, environment_files), true }, + { "UMask", bus_property_append_mode, "u", offsetof(ExecContext, umask) }, + { "LimitCPU", bus_execute_append_rlimits, "t", 0 }, + { "LimitFSIZE", bus_execute_append_rlimits, "t", 0 }, + { "LimitDATA", bus_execute_append_rlimits, "t", 0 }, + { "LimitSTACK", bus_execute_append_rlimits, "t", 0 }, + { "LimitCORE", bus_execute_append_rlimits, "t", 0 }, + { "LimitRSS", bus_execute_append_rlimits, "t", 0 }, + { "LimitNOFILE", bus_execute_append_rlimits, "t", 0 }, + { "LimitAS", bus_execute_append_rlimits, "t", 0 }, + { "LimitNPROC", bus_execute_append_rlimits, "t", 0 }, + { "LimitMEMLOCK", bus_execute_append_rlimits, "t", 0 }, + { "LimitLOCKS", bus_execute_append_rlimits, "t", 0 }, + { "LimitSIGPENDING", bus_execute_append_rlimits, "t", 0 }, + { "LimitMSGQUEUE", bus_execute_append_rlimits, "t", 0 }, + { "LimitNICE", bus_execute_append_rlimits, "t", 0 }, + { "LimitRTPRIO", bus_execute_append_rlimits, "t", 0 }, + { "LimitRTTIME", bus_execute_append_rlimits, "t", 0 }, + { "WorkingDirectory", bus_property_append_string, "s", offsetof(ExecContext, working_directory), true }, + { "RootDirectory", bus_property_append_string, "s", offsetof(ExecContext, root_directory), true }, + { "OOMScoreAdjust", bus_execute_append_oom_score_adjust, "i", 0 }, + { "Nice", bus_execute_append_nice, "i", 0 }, + { "IOScheduling", bus_execute_append_ioprio, "i", 0 }, + { "CPUSchedulingPolicy", bus_execute_append_cpu_sched_policy, "i", 0 }, + { "CPUSchedulingPriority", bus_execute_append_cpu_sched_priority, "i", 0 }, + { "CPUAffinity", bus_execute_append_affinity, "ay", 0 }, + { "TimerSlackNSec", bus_execute_append_timer_slack_nsec, "t", 0 }, + { "CPUSchedulingResetOnFork", bus_property_append_bool, "b", offsetof(ExecContext, cpu_sched_reset_on_fork) }, + { "NonBlocking", bus_property_append_bool, "b", offsetof(ExecContext, non_blocking) }, + { "StandardInput", bus_execute_append_input, "s", offsetof(ExecContext, std_input) }, + { "StandardOutput", bus_execute_append_output, "s", offsetof(ExecContext, std_output) }, + { "StandardError", bus_execute_append_output, "s", offsetof(ExecContext, std_error) }, + { "TTYPath", bus_property_append_string, "s", offsetof(ExecContext, tty_path), true }, + { "TTYReset", bus_property_append_bool, "b", offsetof(ExecContext, tty_reset) }, + { "TTYVHangup", bus_property_append_bool, "b", offsetof(ExecContext, tty_vhangup) }, + { "TTYVTDisallocate", bus_property_append_bool, "b", offsetof(ExecContext, tty_vt_disallocate) }, + { "SyslogPriority", bus_property_append_int, "i", offsetof(ExecContext, syslog_priority) }, + { "SyslogIdentifier", bus_property_append_string, "s", offsetof(ExecContext, syslog_identifier), true }, + { "SyslogLevelPrefix", bus_property_append_bool, "b", offsetof(ExecContext, syslog_level_prefix) }, + { "Capabilities", bus_execute_append_capabilities, "s", 0 }, + { "SecureBits", bus_property_append_int, "i", offsetof(ExecContext, secure_bits) }, + { "CapabilityBoundingSet", bus_execute_append_capability_bs, "t", offsetof(ExecContext, capability_bounding_set_drop) }, + { "User", bus_property_append_string, "s", offsetof(ExecContext, user), true }, + { "Group", bus_property_append_string, "s", offsetof(ExecContext, group), true }, + { "SupplementaryGroups", bus_property_append_strv, "as", offsetof(ExecContext, supplementary_groups), true }, + { "TCPWrapName", bus_property_append_string, "s", offsetof(ExecContext, tcpwrap_name), true }, + { "PAMName", bus_property_append_string, "s", offsetof(ExecContext, pam_name), true }, + { "ReadWriteDirectories", bus_property_append_strv, "as", offsetof(ExecContext, read_write_dirs), true }, + { "ReadOnlyDirectories", bus_property_append_strv, "as", offsetof(ExecContext, read_only_dirs), true }, + { "InaccessibleDirectories", bus_property_append_strv, "as", offsetof(ExecContext, inaccessible_dirs), true }, + { "MountFlags", bus_property_append_ul, "t", offsetof(ExecContext, mount_flags) }, + { "PrivateTmp", bus_property_append_bool, "b", offsetof(ExecContext, private_tmp) }, + { "PrivateNetwork", bus_property_append_bool, "b", offsetof(ExecContext, private_network) }, + { "SameProcessGroup", bus_property_append_bool, "b", offsetof(ExecContext, same_pgrp) }, + { "UtmpIdentifier", bus_property_append_string, "s", offsetof(ExecContext, utmp_id), true }, + { "ControlGroupModify", bus_property_append_bool, "b", offsetof(ExecContext, control_group_modify) }, + { "ControlGroupPersistent", bus_property_append_tristate_false, "b", offsetof(ExecContext, control_group_persistent) }, + { "IgnoreSIGPIPE", bus_property_append_bool, "b", offsetof(ExecContext, ignore_sigpipe) }, + { "NoNewPrivileges", bus_property_append_bool, "b", offsetof(ExecContext, no_new_privileges) }, + { "SystemCallFilter", bus_execute_append_syscall_filter, "au", 0 }, + { NULL, } +}; diff --git a/src/core/dbus-execute.h b/src/core/dbus-execute.h new file mode 100644 index 000000000..eaa1b73e6 --- /dev/null +++ b/src/core/dbus-execute.h @@ -0,0 +1,124 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +#include + +#include "manager.h" +#include "dbus-common.h" + +#define BUS_EXEC_STATUS_INTERFACE(prefix) \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" + +#define BUS_EXEC_CONTEXT_INTERFACE \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" + +#define BUS_EXEC_COMMAND_INTERFACE(name) \ + " \n" + +extern const BusProperty bus_exec_context_properties[]; + +#define BUS_EXEC_COMMAND_PROPERTY(name, command, indirect) \ + { name, bus_execute_append_command, "a(sasbttttuii)", (command), (indirect), NULL } + +int bus_execute_append_output(DBusMessageIter *i, const char *property, void *data); +int bus_execute_append_input(DBusMessageIter *i, const char *property, void *data); +int bus_execute_append_oom_score_adjust(DBusMessageIter *i, const char *property, void *data); +int bus_execute_append_nice(DBusMessageIter *i, const char *property, void *data); +int bus_execute_append_ioprio(DBusMessageIter *i, const char *property, void *data); +int bus_execute_append_cpu_sched_policy(DBusMessageIter *i, const char *property, void *data); +int bus_execute_append_cpu_sched_priority(DBusMessageIter *i, const char *property, void *data); +int bus_execute_append_affinity(DBusMessageIter *i, const char *property, void *data); +int bus_execute_append_timer_slack_nsec(DBusMessageIter *i, const char *property, void *data); +int bus_execute_append_capabilities(DBusMessageIter *i, const char *property, void *data); +int bus_execute_append_capability_bs(DBusMessageIter *i, const char *property, void *data); +int bus_execute_append_rlimits(DBusMessageIter *i, const char *property, void *data); +int bus_execute_append_command(DBusMessageIter *u, const char *property, void *data); +int bus_execute_append_env_files(DBusMessageIter *i, const char *property, void *data); +int bus_execute_append_syscall_filter(DBusMessageIter *i, const char *property, void *data); diff --git a/src/core/dbus-job.c b/src/core/dbus-job.c new file mode 100644 index 000000000..fdc1dce17 --- /dev/null +++ b/src/core/dbus-job.c @@ -0,0 +1,378 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include + +#include "dbus.h" +#include "log.h" +#include "dbus-job.h" +#include "dbus-common.h" +#include "selinux-access.h" + +#define BUS_JOB_INTERFACE \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" + +#define INTROSPECTION \ + DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \ + "\n" \ + BUS_JOB_INTERFACE \ + BUS_PROPERTIES_INTERFACE \ + BUS_PEER_INTERFACE \ + BUS_INTROSPECTABLE_INTERFACE \ + "\n" + +const char bus_job_interface[] _introspect_("Job") = BUS_JOB_INTERFACE; + +#define INTERFACES_LIST \ + BUS_GENERIC_INTERFACES_LIST \ + "org.freedesktop.systemd1.Job\0" + +#define INVALIDATING_PROPERTIES \ + "State\0" + +static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_job_append_state, job_state, JobState); +static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_job_append_type, job_type, JobType); + +static int bus_job_append_unit(DBusMessageIter *i, const char *property, void *data) { + Job *j = data; + DBusMessageIter sub; + char *p; + + assert(i); + assert(property); + assert(j); + + if (!dbus_message_iter_open_container(i, DBUS_TYPE_STRUCT, NULL, &sub)) + return -ENOMEM; + + p = unit_dbus_path(j->unit); + if (!p) + return -ENOMEM; + + if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &j->unit->id) || + !dbus_message_iter_append_basic(&sub, DBUS_TYPE_OBJECT_PATH, &p)) { + free(p); + return -ENOMEM; + } + + free(p); + + if (!dbus_message_iter_close_container(i, &sub)) + return -ENOMEM; + + return 0; +} + +static const BusProperty bus_job_properties[] = { + { "Id", bus_property_append_uint32, "u", offsetof(Job, id) }, + { "State", bus_job_append_state, "s", offsetof(Job, state) }, + { "JobType", bus_job_append_type, "s", offsetof(Job, type) }, + { "Unit", bus_job_append_unit, "(so)", 0 }, + { NULL, } +}; + +static DBusHandlerResult bus_job_message_dispatch(Job *j, DBusConnection *connection, DBusMessage *message) { + _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; + + if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Job", "Cancel")) { + + SELINUX_UNIT_ACCESS_CHECK(j->unit, connection, message, "stop"); + + reply = dbus_message_new_method_return(message); + if (!reply) + return DBUS_HANDLER_RESULT_NEED_MEMORY; + + job_finish_and_invalidate(j, JOB_CANCELED, true); + } else { + const BusBoundProperties bps[] = { + { "org.freedesktop.systemd1.Job", bus_job_properties, j }, + { NULL, } + }; + + SELINUX_UNIT_ACCESS_CHECK(j->unit, connection, message, "status"); + + return bus_default_message_handler(connection, message, INTROSPECTION, INTERFACES_LIST, bps); + } + + if (!dbus_connection_send(connection, reply, NULL)) + return DBUS_HANDLER_RESULT_NEED_MEMORY; + + return DBUS_HANDLER_RESULT_HANDLED; +} + +static DBusHandlerResult bus_job_message_handler(DBusConnection *connection, DBusMessage *message, void *data) { + Manager *m = data; + Job *j; + int r; + _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; + + assert(connection); + assert(message); + assert(m); + + if (streq(dbus_message_get_path(message), "/org/freedesktop/systemd1/job")) { + /* Be nice to gdbus and return introspection data for our mid-level paths */ + + if (dbus_message_is_method_call(message, "org.freedesktop.DBus.Introspectable", "Introspect")) { + char *introspection = NULL; + FILE *f; + Iterator i; + size_t size; + + SELINUX_ACCESS_CHECK(connection, message, "status"); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + /* We roll our own introspection code here, instead of + * relying on bus_default_message_handler() because we + * need to generate our introspection string + * dynamically. */ + + f = open_memstream(&introspection, &size); + if (!f) + goto oom; + + fputs(DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE + "\n", f); + + fputs(BUS_INTROSPECTABLE_INTERFACE, f); + fputs(BUS_PEER_INTERFACE, f); + + HASHMAP_FOREACH(j, m->jobs, i) + fprintf(f, "", (unsigned long) j->id); + + fputs("\n", f); + + if (ferror(f)) { + fclose(f); + free(introspection); + goto oom; + } + + fclose(f); + + if (!introspection) + goto oom; + + if (!dbus_message_append_args(reply, DBUS_TYPE_STRING, &introspection, DBUS_TYPE_INVALID)) { + free(introspection); + goto oom; + } + + free(introspection); + + if (!dbus_connection_send(connection, reply, NULL)) + goto oom; + + return DBUS_HANDLER_RESULT_HANDLED; + } + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + + r = manager_get_job_from_dbus_path(m, dbus_message_get_path(message), &j); + if (r == -ENOMEM) + goto oom; + if (r == -ENOENT) { + DBusError e; + + dbus_error_init(&e); + dbus_set_error_const(&e, DBUS_ERROR_UNKNOWN_OBJECT, "Unknown job"); + return bus_send_error_reply(connection, message, &e, r); + } + if (r < 0) + return bus_send_error_reply(connection, message, NULL, r); + + return bus_job_message_dispatch(j, connection, message); + +oom: + return DBUS_HANDLER_RESULT_NEED_MEMORY; +} + +const DBusObjectPathVTable bus_job_vtable = { + .message_function = bus_job_message_handler +}; + +static int job_send_message(Job *j, DBusMessage* (*new_message)(Job *j)) { + DBusMessage *m = NULL; + int r; + + assert(j); + assert(new_message); + + if (bus_has_subscriber(j->manager) || j->forgot_bus_clients) { + m = new_message(j); + if (!m) + goto oom; + r = bus_broadcast(j->manager, m); + dbus_message_unref(m); + if (r < 0) + return r; + + } else { + /* If nobody is subscribed, we just send the message + * to the client(s) which created the job */ + JobBusClient *cl; + assert(j->bus_client_list); + LIST_FOREACH(client, cl, j->bus_client_list) { + assert(cl->bus); + + m = new_message(j); + if (!m) + goto oom; + + if (!dbus_message_set_destination(m, cl->name)) + goto oom; + + if (!dbus_connection_send(cl->bus, m, NULL)) + goto oom; + + dbus_message_unref(m); + m = NULL; + } + } + + return 0; +oom: + if (m) + dbus_message_unref(m); + return -ENOMEM; +} + +static DBusMessage* new_change_signal_message(Job *j) { + DBusMessage *m = NULL; + char *p = NULL; + + p = job_dbus_path(j); + if (!p) + goto oom; + + if (j->sent_dbus_new_signal) { + /* Send a properties changed signal */ + m = bus_properties_changed_new(p, "org.freedesktop.systemd1.Job", INVALIDATING_PROPERTIES); + if (!m) + goto oom; + + } else { + /* Send a new signal */ + + m = dbus_message_new_signal("/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "JobNew"); + if (!m) + goto oom; + + if (!dbus_message_append_args(m, + DBUS_TYPE_UINT32, &j->id, + DBUS_TYPE_OBJECT_PATH, &p, + DBUS_TYPE_STRING, &j->unit->id, + DBUS_TYPE_INVALID)) + goto oom; + } + + return m; + +oom: + if (m) + dbus_message_unref(m); + free(p); + return NULL; +} + +static DBusMessage* new_removed_signal_message(Job *j) { + DBusMessage *m = NULL; + char *p = NULL; + const char *r; + + p = job_dbus_path(j); + if (!p) + goto oom; + + m = dbus_message_new_signal("/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "JobRemoved"); + if (!m) + goto oom; + + r = job_result_to_string(j->result); + + if (!dbus_message_append_args(m, + DBUS_TYPE_UINT32, &j->id, + DBUS_TYPE_OBJECT_PATH, &p, + DBUS_TYPE_STRING, &j->unit->id, + DBUS_TYPE_STRING, &r, + DBUS_TYPE_INVALID)) + goto oom; + + return m; + +oom: + if (m) + dbus_message_unref(m); + free(p); + return NULL; +} + +void bus_job_send_change_signal(Job *j) { + assert(j); + + if (j->in_dbus_queue) { + LIST_REMOVE(Job, dbus_queue, j->manager->dbus_job_queue, j); + j->in_dbus_queue = false; + } + + if (!bus_has_subscriber(j->manager) && !j->bus_client_list && !j->forgot_bus_clients) { + j->sent_dbus_new_signal = true; + return; + } + + if (job_send_message(j, new_change_signal_message) < 0) + goto oom; + + j->sent_dbus_new_signal = true; + + return; + +oom: + log_error("Failed to allocate job change signal."); +} + +void bus_job_send_removed_signal(Job *j) { + assert(j); + + if (!bus_has_subscriber(j->manager) && !j->bus_client_list && !j->forgot_bus_clients) + return; + + if (!j->sent_dbus_new_signal) + bus_job_send_change_signal(j); + + if (job_send_message(j, new_removed_signal_message) < 0) + goto oom; + + return; + +oom: + log_error("Failed to allocate job remove signal."); +} diff --git a/src/core/dbus-job.h b/src/core/dbus-job.h new file mode 100644 index 000000000..a1b928fb1 --- /dev/null +++ b/src/core/dbus-job.h @@ -0,0 +1,33 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +#include + +#include "job.h" + +void bus_job_send_change_signal(Job *j); +void bus_job_send_removed_signal(Job *j); + +extern const DBusObjectPathVTable bus_job_vtable; + +extern const char bus_job_interface[]; diff --git a/src/core/dbus-kill.c b/src/core/dbus-kill.c new file mode 100644 index 000000000..165f63074 --- /dev/null +++ b/src/core/dbus-kill.c @@ -0,0 +1,35 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + +#include +#include + +#include "dbus-kill.h" +#include "dbus-common.h" + +DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_kill_append_mode, kill_mode, KillMode); + +const BusProperty bus_kill_context_properties[] = { + { "KillMode", bus_kill_append_mode, "s", offsetof(KillContext, kill_mode) }, + { "KillSignal", bus_property_append_int, "i", offsetof(KillContext, kill_signal) }, + { "SendSIGKILL", bus_property_append_bool, "b", offsetof(KillContext, send_sigkill) }, + { NULL, } +}; diff --git a/src/core/dbus-kill.h b/src/core/dbus-kill.h new file mode 100644 index 000000000..238fbd36d --- /dev/null +++ b/src/core/dbus-kill.h @@ -0,0 +1,39 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + +#include + +#include "manager.h" +#include "dbus-common.h" + +#define BUS_KILL_CONTEXT_INTERFACE \ + " \n" \ + " \n" \ + " \n" + +#define BUS_KILL_COMMAND_INTERFACE(name) \ + " \n" + +extern const BusProperty bus_kill_context_properties[]; + +int bus_kill_append_mode(DBusMessageIter *i, const char *property, void *data); diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c new file mode 100644 index 000000000..859fa1a90 --- /dev/null +++ b/src/core/dbus-manager.c @@ -0,0 +1,1684 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include + +#include "dbus.h" +#include "log.h" +#include "dbus-manager.h" +#include "strv.h" +#include "bus-errors.h" +#include "build.h" +#include "dbus-common.h" +#include "install.h" +#include "selinux-access.h" +#include "watchdog.h" +#include "hwclock.h" +#include "path-util.h" +#include "dbus-unit.h" +#include "virt.h" + +#define BUS_MANAGER_INTERFACE_BEGIN \ + " \n" + +#define BUS_MANAGER_INTERFACE_METHODS \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" + +#define BUS_MANAGER_INTERFACE_SIGNALS \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " " \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " " \ + " \n" + +#define BUS_MANAGER_INTERFACE_PROPERTIES_GENERAL \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" + +#define BUS_MANAGER_INTERFACE_END \ + " \n" + +#define BUS_MANAGER_INTERFACE \ + BUS_MANAGER_INTERFACE_BEGIN \ + BUS_MANAGER_INTERFACE_METHODS \ + BUS_MANAGER_INTERFACE_SIGNALS \ + BUS_MANAGER_INTERFACE_PROPERTIES_GENERAL \ + BUS_MANAGER_INTERFACE_END + +#define INTROSPECTION_BEGIN \ + DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \ + "\n" \ + BUS_MANAGER_INTERFACE \ + BUS_PROPERTIES_INTERFACE \ + BUS_PEER_INTERFACE \ + BUS_INTROSPECTABLE_INTERFACE + +#define INTROSPECTION_END \ + "\n" + +#define INTERFACES_LIST \ + BUS_GENERIC_INTERFACES_LIST \ + "org.freedesktop.systemd1.Manager\0" + +const char bus_manager_interface[] _introspect_("Manager") = BUS_MANAGER_INTERFACE; + +static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_manager_append_exec_output, exec_output, ExecOutput); + +static int bus_manager_append_tainted(DBusMessageIter *i, const char *property, void *data) { + const char *t; + Manager *m = data; + char buf[LINE_MAX] = "", *e = buf, *p = NULL; + + assert(i); + assert(property); + assert(m); + + if (m->taint_usr) + e = stpcpy(e, "split-usr:"); + + if (readlink_malloc("/etc/mtab", &p) < 0) + e = stpcpy(e, "mtab-not-symlink:"); + else + free(p); + + if (access("/proc/cgroups", F_OK) < 0) + e = stpcpy(e, "cgroups-missing:"); + + if (hwclock_is_localtime() > 0) + e = stpcpy(e, "local-hwclock:"); + + /* remove the last ':' */ + if (e != buf) + e[-1] = 0; + + t = buf; + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &t)) + return -ENOMEM; + + return 0; +} + +static int bus_manager_append_log_target(DBusMessageIter *i, const char *property, void *data) { + const char *t; + + assert(i); + assert(property); + + t = log_target_to_string(log_get_target()); + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &t)) + return -ENOMEM; + + return 0; +} + +static int bus_manager_set_log_target(DBusMessageIter *i, const char *property, void *data) { + const char *t; + + assert(i); + assert(property); + + dbus_message_iter_get_basic(i, &t); + + return log_set_target_from_string(t); +} + +static int bus_manager_append_log_level(DBusMessageIter *i, const char *property, void *data) { + char *t; + int r; + + assert(i); + assert(property); + + r = log_level_to_string_alloc(log_get_max_level(), &t); + if (r < 0) + return r; + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &t)) + r = -ENOMEM; + + free(t); + return r; +} + +static int bus_manager_set_log_level(DBusMessageIter *i, const char *property, void *data) { + const char *t; + + assert(i); + assert(property); + + dbus_message_iter_get_basic(i, &t); + + return log_set_max_level_from_string(t); +} + +static int bus_manager_append_n_names(DBusMessageIter *i, const char *property, void *data) { + Manager *m = data; + uint32_t u; + + assert(i); + assert(property); + assert(m); + + u = hashmap_size(m->units); + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_UINT32, &u)) + return -ENOMEM; + + return 0; +} + +static int bus_manager_append_n_jobs(DBusMessageIter *i, const char *property, void *data) { + Manager *m = data; + uint32_t u; + + assert(i); + assert(property); + assert(m); + + u = hashmap_size(m->jobs); + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_UINT32, &u)) + return -ENOMEM; + + return 0; +} + +static int bus_manager_append_progress(DBusMessageIter *i, const char *property, void *data) { + double d; + Manager *m = data; + + assert(i); + assert(property); + assert(m); + + if (dual_timestamp_is_set(&m->finish_timestamp)) + d = 1.0; + else + d = 1.0 - ((double) hashmap_size(m->jobs) / (double) m->n_installed_jobs); + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_DOUBLE, &d)) + return -ENOMEM; + + return 0; +} + +static int bus_manager_append_virt(DBusMessageIter *i, const char *property, void *data) { + Manager *m = data; + const char *id = ""; + + assert(i); + assert(property); + assert(m); + + detect_virtualization(&id); + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &id)) + return -ENOMEM; + + return 0; +} + +static DBusMessage *message_from_file_changes( + DBusMessage *m, + UnitFileChange *changes, + unsigned n_changes, + int carries_install_info) { + + DBusMessageIter iter, sub, sub2; + DBusMessage *reply; + unsigned i; + + reply = dbus_message_new_method_return(m); + if (!reply) + return NULL; + + dbus_message_iter_init_append(reply, &iter); + + if (carries_install_info >= 0) { + dbus_bool_t b; + + b = !!carries_install_info; + if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &b)) + goto oom; + } + + if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(sss)", &sub)) + goto oom; + + for (i = 0; i < n_changes; i++) { + const char *type, *path, *source; + + type = unit_file_change_type_to_string(changes[i].type); + path = strempty(changes[i].path); + source = strempty(changes[i].source); + + if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &type) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &path) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &source) || + !dbus_message_iter_close_container(&sub, &sub2)) + goto oom; + } + + if (!dbus_message_iter_close_container(&iter, &sub)) + goto oom; + + return reply; + +oom: + dbus_message_unref(reply); + return NULL; +} + +static int bus_manager_send_unit_files_changed(Manager *m) { + DBusMessage *s; + int r; + + s = dbus_message_new_signal("/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "UnitFilesChanged"); + if (!s) + return -ENOMEM; + + r = bus_broadcast(m, s); + dbus_message_unref(s); + + return r; +} + +static int bus_manager_set_runtime_watchdog_usec(DBusMessageIter *i, const char *property, void *data) { + uint64_t *t = data; + + assert(i); + assert(property); + + dbus_message_iter_get_basic(i, t); + + return watchdog_set_timeout(t); +} + +static const char systemd_property_string[] = + PACKAGE_STRING "\0" + SYSTEMD_FEATURES; + +static const BusProperty bus_systemd_properties[] = { + { "Version", bus_property_append_string, "s", 0 }, + { "Features", bus_property_append_string, "s", sizeof(PACKAGE_STRING) }, + { NULL, } +}; + +static const BusProperty bus_manager_properties[] = { + { "Tainted", bus_manager_append_tainted, "s", 0 }, + { "FirmwareTimestamp", bus_property_append_uint64, "t", offsetof(Manager, firmware_timestamp.realtime) }, + { "FirmwareTimestampMonotonic", bus_property_append_uint64, "t", offsetof(Manager, firmware_timestamp.monotonic) }, + { "LoaderTimestamp", bus_property_append_uint64, "t", offsetof(Manager, loader_timestamp.realtime) }, + { "LoaderTimestampMonotonic", bus_property_append_uint64, "t", offsetof(Manager, loader_timestamp.monotonic) }, + { "KernelTimestamp", bus_property_append_uint64, "t", offsetof(Manager, kernel_timestamp.realtime) }, + { "KernelTimestampMonotonic", bus_property_append_uint64, "t", offsetof(Manager, kernel_timestamp.monotonic) }, + { "InitRDTimestamp", bus_property_append_uint64, "t", offsetof(Manager, initrd_timestamp.realtime) }, + { "InitRDTimestampMonotonic", bus_property_append_uint64, "t", offsetof(Manager, initrd_timestamp.monotonic) }, + { "UserspaceTimestamp", bus_property_append_uint64, "t", offsetof(Manager, userspace_timestamp.realtime) }, + { "UserspaceTimestampMonotonic", bus_property_append_uint64, "t", offsetof(Manager, userspace_timestamp.monotonic) }, + { "FinishTimestamp", bus_property_append_uint64, "t", offsetof(Manager, finish_timestamp.realtime) }, + { "FinishTimestampMonotonic", bus_property_append_uint64, "t", offsetof(Manager, finish_timestamp.monotonic) }, + { "LogLevel", bus_manager_append_log_level, "s", 0, false, bus_manager_set_log_level }, + { "LogTarget", bus_manager_append_log_target, "s", 0, false, bus_manager_set_log_target }, + { "NNames", bus_manager_append_n_names, "u", 0 }, + { "NJobs", bus_manager_append_n_jobs, "u", 0 }, + { "NInstalledJobs", bus_property_append_uint32, "u", offsetof(Manager, n_installed_jobs) }, + { "NFailedJobs", bus_property_append_uint32, "u", offsetof(Manager, n_failed_jobs) }, + { "Progress", bus_manager_append_progress, "d", 0 }, + { "Environment", bus_property_append_strv, "as", offsetof(Manager, environment), true }, + { "ConfirmSpawn", bus_property_append_bool, "b", offsetof(Manager, confirm_spawn) }, + { "ShowStatus", bus_property_append_bool, "b", offsetof(Manager, show_status) }, + { "UnitPath", bus_property_append_strv, "as", offsetof(Manager, lookup_paths.unit_path), true }, + { "ControlGroupHierarchy", bus_property_append_string, "s", offsetof(Manager, cgroup_hierarchy), true }, + { "DefaultControllers", bus_property_append_strv, "as", offsetof(Manager, default_controllers), true }, + { "DefaultStandardOutput", bus_manager_append_exec_output, "s", offsetof(Manager, default_std_output) }, + { "DefaultStandardError", bus_manager_append_exec_output, "s", offsetof(Manager, default_std_error) }, + { "RuntimeWatchdogUSec", bus_property_append_usec, "t", offsetof(Manager, runtime_watchdog), false, bus_manager_set_runtime_watchdog_usec }, + { "ShutdownWatchdogUSec", bus_property_append_usec, "t", offsetof(Manager, shutdown_watchdog), false, bus_property_set_usec }, + { "Virtualization", bus_manager_append_virt, "s", 0, }, + { NULL, } +}; + +static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, DBusMessage *message, void *data) { + _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; + _cleanup_free_ char * path = NULL; + Manager *m = data; + int r; + DBusError error; + JobType job_type = _JOB_TYPE_INVALID; + bool reload_if_possible = false; + const char *member; + + assert(connection); + assert(message); + assert(m); + + dbus_error_init(&error); + + member = dbus_message_get_member(message); + + if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "GetUnit")) { + const char *name; + Unit *u; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + u = manager_get_unit(m, name); + if (!u) { + dbus_set_error(&error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not loaded.", name); + return bus_send_error_reply(connection, message, &error, -ENOENT); + } + + SELINUX_UNIT_ACCESS_CHECK(u, connection, message, "status"); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + path = unit_dbus_path(u); + if (!path) + goto oom; + + if (!dbus_message_append_args( + reply, + DBUS_TYPE_OBJECT_PATH, &path, + DBUS_TYPE_INVALID)) + goto oom; + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "GetUnitByPID")) { + Unit *u; + uint32_t pid; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_UINT32, &pid, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + u = cgroup_unit_by_pid(m, (pid_t) pid); + if (!u) { + dbus_set_error(&error, BUS_ERROR_NO_SUCH_UNIT, "No unit for PID %lu is loaded.", (unsigned long) pid); + return bus_send_error_reply(connection, message, &error, -ENOENT); + } + + SELINUX_UNIT_ACCESS_CHECK(u, connection, message, "status"); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + path = unit_dbus_path(u); + if (!path) + goto oom; + + if (!dbus_message_append_args( + reply, + DBUS_TYPE_OBJECT_PATH, &path, + DBUS_TYPE_INVALID)) + goto oom; + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "LoadUnit")) { + const char *name; + Unit *u; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + r = manager_load_unit(m, name, NULL, &error, &u); + if (r < 0) + return bus_send_error_reply(connection, message, &error, r); + + SELINUX_UNIT_ACCESS_CHECK(u, connection, message, "status"); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + path = unit_dbus_path(u); + if (!path) + goto oom; + + if (!dbus_message_append_args( + reply, + DBUS_TYPE_OBJECT_PATH, &path, + DBUS_TYPE_INVALID)) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "StartUnit")) + job_type = JOB_START; + else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "StartUnitReplace")) + job_type = JOB_START; + else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "StopUnit")) + job_type = JOB_STOP; + else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "ReloadUnit")) + job_type = JOB_RELOAD; + else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "RestartUnit")) + job_type = JOB_RESTART; + else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "TryRestartUnit")) + job_type = JOB_TRY_RESTART; + else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "ReloadOrRestartUnit")) { + reload_if_possible = true; + job_type = JOB_RESTART; + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "ReloadOrTryRestartUnit")) { + reload_if_possible = true; + job_type = JOB_TRY_RESTART; + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "KillUnit")) { + const char *name, *swho; + int32_t signo; + Unit *u; + KillWho who; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_STRING, &swho, + DBUS_TYPE_INT32, &signo, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + if (isempty(swho)) + who = KILL_ALL; + else { + who = kill_who_from_string(swho); + if (who < 0) + return bus_send_error_reply(connection, message, &error, -EINVAL); + } + + if (signo <= 0 || signo >= _NSIG) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + u = manager_get_unit(m, name); + if (!u) { + dbus_set_error(&error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not loaded.", name); + return bus_send_error_reply(connection, message, &error, -ENOENT); + } + + SELINUX_UNIT_ACCESS_CHECK(u, connection, message, "stop"); + + r = unit_kill(u, who, signo, &error); + if (r < 0) + return bus_send_error_reply(connection, message, &error, r); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "GetJob")) { + uint32_t id; + Job *j; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_UINT32, &id, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + j = manager_get_job(m, id); + if (!j) { + dbus_set_error(&error, BUS_ERROR_NO_SUCH_JOB, "Job %u does not exist.", (unsigned) id); + return bus_send_error_reply(connection, message, &error, -ENOENT); + } + + SELINUX_UNIT_ACCESS_CHECK(j->unit, connection, message, "status"); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + path = job_dbus_path(j); + if (!path) + goto oom; + + if (!dbus_message_append_args( + reply, + DBUS_TYPE_OBJECT_PATH, &path, + DBUS_TYPE_INVALID)) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "ClearJobs")) { + + SELINUX_ACCESS_CHECK(connection, message, "reboot"); + + manager_clear_jobs(m); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "ResetFailed")) { + + SELINUX_ACCESS_CHECK(connection, message, "reload"); + + manager_reset_failed(m); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "ResetFailedUnit")) { + const char *name; + Unit *u; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + u = manager_get_unit(m, name); + if (!u) { + dbus_set_error(&error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not loaded.", name); + return bus_send_error_reply(connection, message, &error, -ENOENT); + } + + SELINUX_UNIT_ACCESS_CHECK(u, connection, message, "reload"); + + unit_reset_failed(u); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "ListUnits")) { + DBusMessageIter iter, sub; + Iterator i; + Unit *u; + const char *k; + + SELINUX_ACCESS_CHECK(connection, message, "status"); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + dbus_message_iter_init_append(reply, &iter); + + if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(ssssssouso)", &sub)) + goto oom; + + HASHMAP_FOREACH_KEY(u, k, m->units, i) { + char *u_path, *j_path; + const char *description, *load_state, *active_state, *sub_state, *sjob_type, *following; + DBusMessageIter sub2; + uint32_t job_id; + Unit *f; + + if (k != u->id) + continue; + + if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2)) + goto oom; + + description = unit_description(u); + load_state = unit_load_state_to_string(u->load_state); + active_state = unit_active_state_to_string(unit_active_state(u)); + sub_state = unit_sub_state_to_string(u); + + f = unit_following(u); + following = f ? f->id : ""; + + u_path = unit_dbus_path(u); + if (!u_path) + goto oom; + + if (u->job) { + job_id = (uint32_t) u->job->id; + + if (!(j_path = job_dbus_path(u->job))) { + free(u_path); + goto oom; + } + + sjob_type = job_type_to_string(u->job->type); + } else { + job_id = 0; + j_path = u_path; + sjob_type = ""; + } + + if (!dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &u->id) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &description) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &load_state) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &active_state) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &sub_state) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &following) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_OBJECT_PATH, &u_path) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT32, &job_id) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &sjob_type) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_OBJECT_PATH, &j_path)) { + free(u_path); + if (u->job) + free(j_path); + goto oom; + } + + free(u_path); + if (u->job) + free(j_path); + + if (!dbus_message_iter_close_container(&sub, &sub2)) + goto oom; + } + + if (!dbus_message_iter_close_container(&iter, &sub)) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "ListJobs")) { + DBusMessageIter iter, sub; + Iterator i; + Job *j; + + SELINUX_ACCESS_CHECK(connection, message, "status"); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + dbus_message_iter_init_append(reply, &iter); + + if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(usssoo)", &sub)) + goto oom; + + HASHMAP_FOREACH(j, m->jobs, i) { + char *u_path, *j_path; + const char *state, *type; + uint32_t id; + DBusMessageIter sub2; + + if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2)) + goto oom; + + id = (uint32_t) j->id; + state = job_state_to_string(j->state); + type = job_type_to_string(j->type); + + j_path = job_dbus_path(j); + if (!j_path) + goto oom; + + u_path = unit_dbus_path(j->unit); + if (!u_path) { + free(j_path); + goto oom; + } + + if (!dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT32, &id) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &j->unit->id) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &type) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &state) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_OBJECT_PATH, &j_path) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_OBJECT_PATH, &u_path)) { + free(j_path); + free(u_path); + goto oom; + } + + free(j_path); + free(u_path); + + if (!dbus_message_iter_close_container(&sub, &sub2)) + goto oom; + } + + if (!dbus_message_iter_close_container(&iter, &sub)) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "Subscribe")) { + char *client; + Set *s; + + SELINUX_ACCESS_CHECK(connection, message, "status"); + + s = BUS_CONNECTION_SUBSCRIBED(m, connection); + if (!s) { + s = set_new(string_hash_func, string_compare_func); + if (!s) + goto oom; + + if (!dbus_connection_set_data(connection, m->subscribed_data_slot, s, NULL)) { + set_free(s); + goto oom; + } + } + + client = strdup(bus_message_get_sender_with_fallback(message)); + if (!client) + goto oom; + + r = set_put(s, client); + if (r < 0) { + free(client); + return bus_send_error_reply(connection, message, NULL, r); + } + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "Unsubscribe")) { + char *client; + + SELINUX_ACCESS_CHECK(connection, message, "status"); + + client = set_remove(BUS_CONNECTION_SUBSCRIBED(m, connection), (char*) bus_message_get_sender_with_fallback(message)); + if (!client) { + dbus_set_error(&error, BUS_ERROR_NOT_SUBSCRIBED, "Client is not subscribed."); + return bus_send_error_reply(connection, message, &error, -ENOENT); + } + + free(client); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "Dump")) { + FILE *f; + char *dump = NULL; + size_t size; + + SELINUX_ACCESS_CHECK(connection, message, "status"); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + f = open_memstream(&dump, &size); + if (!f) + goto oom; + + manager_dump_units(m, f, NULL); + manager_dump_jobs(m, f, NULL); + + if (ferror(f)) { + fclose(f); + free(dump); + goto oom; + } + + fclose(f); + + if (!dbus_message_append_args(reply, DBUS_TYPE_STRING, &dump, DBUS_TYPE_INVALID)) { + free(dump); + goto oom; + } + + free(dump); + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "CreateSnapshot")) { + const char *name; + dbus_bool_t cleanup; + Snapshot *s; + + SELINUX_ACCESS_CHECK(connection, message, "start"); + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_BOOLEAN, &cleanup, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + if (isempty(name)) + name = NULL; + + r = snapshot_create(m, name, cleanup, &error, &s); + if (r < 0) + return bus_send_error_reply(connection, message, &error, r); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + path = unit_dbus_path(UNIT(s)); + if (!path) + goto oom; + + if (!dbus_message_append_args( + reply, + DBUS_TYPE_OBJECT_PATH, &path, + DBUS_TYPE_INVALID)) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.DBus.Introspectable", "Introspect")) { + char *introspection = NULL; + FILE *f; + Iterator i; + Unit *u; + Job *j; + const char *k; + size_t size; + + SELINUX_ACCESS_CHECK(connection, message, "status"); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + /* We roll our own introspection code here, instead of + * relying on bus_default_message_handler() because we + * need to generate our introspection string + * dynamically. */ + + f = open_memstream(&introspection, &size); + if (!f) + goto oom; + + fputs(INTROSPECTION_BEGIN, f); + + HASHMAP_FOREACH_KEY(u, k, m->units, i) { + char *p; + + if (k != u->id) + continue; + + p = bus_path_escape(k); + if (!p) { + fclose(f); + free(introspection); + goto oom; + } + + fprintf(f, "", p); + free(p); + } + + HASHMAP_FOREACH(j, m->jobs, i) + fprintf(f, "", (unsigned long) j->id); + + fputs(INTROSPECTION_END, f); + + if (ferror(f)) { + fclose(f); + free(introspection); + goto oom; + } + + fclose(f); + + if (!introspection) + goto oom; + + if (!dbus_message_append_args(reply, DBUS_TYPE_STRING, &introspection, DBUS_TYPE_INVALID)) { + free(introspection); + goto oom; + } + + free(introspection); + + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "Reload")) { + + SELINUX_ACCESS_CHECK(connection, message, "reload"); + + assert(!m->queued_message); + + /* Instead of sending the reply back right away, we + * just remember that we need to and then send it + * after the reload is finished. That way the caller + * knows when the reload finished. */ + + m->queued_message = dbus_message_new_method_return(message); + if (!m->queued_message) + goto oom; + + m->queued_message_connection = connection; + m->exit_code = MANAGER_RELOAD; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "Reexecute")) { + + SELINUX_ACCESS_CHECK(connection, message, "reload"); + + /* We don't send a reply back here, the client should + * just wait for us disconnecting. */ + + m->exit_code = MANAGER_REEXECUTE; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "Exit")) { + + SELINUX_ACCESS_CHECK(connection, message, "halt"); + + if (m->running_as == SYSTEMD_SYSTEM) { + dbus_set_error(&error, BUS_ERROR_NOT_SUPPORTED, "Exit is only supported for user service managers."); + return bus_send_error_reply(connection, message, &error, -ENOTSUP); + } + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + m->exit_code = MANAGER_EXIT; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "Reboot")) { + + SELINUX_ACCESS_CHECK(connection, message, "reboot"); + + if (m->running_as != SYSTEMD_SYSTEM) { + dbus_set_error(&error, BUS_ERROR_NOT_SUPPORTED, "Reboot is only supported for system managers."); + return bus_send_error_reply(connection, message, &error, -ENOTSUP); + } + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + m->exit_code = MANAGER_REBOOT; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "PowerOff")) { + + SELINUX_ACCESS_CHECK(connection, message, "halt"); + + if (m->running_as != SYSTEMD_SYSTEM) { + dbus_set_error(&error, BUS_ERROR_NOT_SUPPORTED, "Powering off is only supported for system managers."); + return bus_send_error_reply(connection, message, &error, -ENOTSUP); + } + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + m->exit_code = MANAGER_POWEROFF; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "Halt")) { + + SELINUX_ACCESS_CHECK(connection, message, "halt"); + + if (m->running_as != SYSTEMD_SYSTEM) { + dbus_set_error(&error, BUS_ERROR_NOT_SUPPORTED, "Halting is only supported for system managers."); + return bus_send_error_reply(connection, message, &error, -ENOTSUP); + } + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + m->exit_code = MANAGER_HALT; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "KExec")) { + + SELINUX_ACCESS_CHECK(connection, message, "reboot"); + + if (m->running_as != SYSTEMD_SYSTEM) { + dbus_set_error(&error, BUS_ERROR_NOT_SUPPORTED, "kexec is only supported for system managers."); + return bus_send_error_reply(connection, message, &error, -ENOTSUP); + } + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + m->exit_code = MANAGER_KEXEC; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "SwitchRoot")) { + const char *switch_root, *switch_root_init; + char *u, *v; + int k; + + SELINUX_ACCESS_CHECK(connection, message, "reboot"); + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &switch_root, + DBUS_TYPE_STRING, &switch_root_init, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + if (path_equal(switch_root, "/") || !path_is_absolute(switch_root)) + return bus_send_error_reply(connection, message, NULL, -EINVAL); + + if (!isempty(switch_root_init) && !path_is_absolute(switch_root_init)) + return bus_send_error_reply(connection, message, NULL, -EINVAL); + + if (m->running_as != SYSTEMD_SYSTEM) { + dbus_set_error(&error, BUS_ERROR_NOT_SUPPORTED, "Switching root is only supported for system managers."); + return bus_send_error_reply(connection, message, &error, -ENOTSUP); + } + + /* Safety check */ + if (isempty(switch_root_init)) + k = access(switch_root, F_OK); + else { + char *p; + + p = strjoin(switch_root, "/", switch_root_init, NULL); + if (!p) + goto oom; + + k = access(p, X_OK); + free(p); + } + if (k < 0) + return bus_send_error_reply(connection, message, NULL, -errno); + + u = strdup(switch_root); + if (!u) + goto oom; + + if (!isempty(switch_root_init)) { + v = strdup(switch_root_init); + if (!v) { + free(u); + goto oom; + } + } else + v = NULL; + + free(m->switch_root); + free(m->switch_root_init); + m->switch_root = u; + m->switch_root_init = v; + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + m->exit_code = MANAGER_SWITCH_ROOT; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "SetEnvironment")) { + char **l = NULL, **e = NULL; + + SELINUX_ACCESS_CHECK(connection, message, "reboot"); + + r = bus_parse_strv(message, &l); + if (r == -ENOMEM) + goto oom; + if (r < 0) + return bus_send_error_reply(connection, message, NULL, r); + + e = strv_env_merge(2, m->environment, l); + strv_free(l); + if (!e) + goto oom; + + reply = dbus_message_new_method_return(message); + if (!reply) { + strv_free(e); + goto oom; + } + + strv_free(m->environment); + m->environment = e; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "UnsetEnvironment")) { + char **l = NULL, **e = NULL; + + SELINUX_ACCESS_CHECK(connection, message, "reboot"); + + r = bus_parse_strv(message, &l); + if (r == -ENOMEM) + goto oom; + if (r < 0) + return bus_send_error_reply(connection, message, NULL, r); + + e = strv_env_delete(m->environment, 1, l); + strv_free(l); + + if (!e) + goto oom; + + reply = dbus_message_new_method_return(message); + if (!reply) { + strv_free(e); + goto oom; + } + + strv_free(m->environment); + m->environment = e; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "UnsetAndSetEnvironment")) { + char **l_set = NULL, **l_unset = NULL, **e = NULL, **f = NULL; + DBusMessageIter iter; + + SELINUX_ACCESS_CHECK(connection, message, "reboot"); + + if (!dbus_message_iter_init(message, &iter)) + goto oom; + + r = bus_parse_strv_iter(&iter, &l_unset); + if (r == -ENOMEM) + goto oom; + if (r < 0) + return bus_send_error_reply(connection, message, NULL, r); + + if (!dbus_message_iter_next(&iter)) { + strv_free(l_unset); + return bus_send_error_reply(connection, message, NULL, -EINVAL); + } + + r = bus_parse_strv_iter(&iter, &l_set); + if (r < 0) { + strv_free(l_unset); + if (r == -ENOMEM) + goto oom; + + return bus_send_error_reply(connection, message, NULL, r); + } + + e = strv_env_delete(m->environment, 1, l_unset); + strv_free(l_unset); + + if (!e) { + strv_free(l_set); + goto oom; + } + + f = strv_env_merge(2, e, l_set); + strv_free(l_set); + strv_free(e); + + if (!f) + goto oom; + + reply = dbus_message_new_method_return(message); + if (!reply) { + strv_free(f); + goto oom; + } + + strv_free(m->environment); + m->environment = f; + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "ListUnitFiles")) { + DBusMessageIter iter, sub, sub2; + Hashmap *h; + Iterator i; + UnitFileList *item; + + SELINUX_ACCESS_CHECK(connection, message, "status"); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + h = hashmap_new(string_hash_func, string_compare_func); + if (!h) + goto oom; + + r = unit_file_get_list(m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER, NULL, h); + if (r < 0) { + unit_file_list_free(h); + return bus_send_error_reply(connection, message, NULL, r); + } + + dbus_message_iter_init_append(reply, &iter); + + if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(ss)", &sub)) { + unit_file_list_free(h); + goto oom; + } + + HASHMAP_FOREACH(item, h, i) { + const char *state; + + state = unit_file_state_to_string(item->state); + assert(state); + + if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &item->path) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &state) || + !dbus_message_iter_close_container(&sub, &sub2)) { + unit_file_list_free(h); + goto oom; + } + } + + unit_file_list_free(h); + + if (!dbus_message_iter_close_container(&iter, &sub)) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "GetUnitFileState")) { + const char *name; + UnitFileState state; + const char *s; + + SELINUX_ACCESS_CHECK(connection, message, "status"); + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + state = unit_file_get_state(m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER, NULL, name); + if (state < 0) + return bus_send_error_reply(connection, message, NULL, state); + + s = unit_file_state_to_string(state); + assert(s); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + if (!dbus_message_append_args( + reply, + DBUS_TYPE_STRING, &s, + DBUS_TYPE_INVALID)) + goto oom; + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "EnableUnitFiles") || + dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "ReenableUnitFiles") || + dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "LinkUnitFiles") || + dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "PresetUnitFiles") || + dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "MaskUnitFiles")) { + + char **l = NULL; + DBusMessageIter iter; + UnitFileScope scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER; + UnitFileChange *changes = NULL; + unsigned n_changes = 0; + dbus_bool_t runtime, force; + int carries_install_info = -1; + + SELINUX_ACCESS_CHECK(connection, message, streq(member, "MaskUnitFiles") ? "disable" : "enable"); + + if (!dbus_message_iter_init(message, &iter)) + goto oom; + + r = bus_parse_strv_iter(&iter, &l); + if (r < 0) { + if (r == -ENOMEM) + goto oom; + + return bus_send_error_reply(connection, message, NULL, r); + } + + if (!dbus_message_iter_next(&iter) || + bus_iter_get_basic_and_next(&iter, DBUS_TYPE_BOOLEAN, &runtime, true) < 0 || + bus_iter_get_basic_and_next(&iter, DBUS_TYPE_BOOLEAN, &force, false) < 0) { + strv_free(l); + return bus_send_error_reply(connection, message, NULL, -EIO); + } + + if (streq(member, "EnableUnitFiles")) { + r = unit_file_enable(scope, runtime, NULL, l, force, &changes, &n_changes); + carries_install_info = r; + } else if (streq(member, "ReenableUnitFiles")) { + r = unit_file_reenable(scope, runtime, NULL, l, force, &changes, &n_changes); + carries_install_info = r; + } else if (streq(member, "LinkUnitFiles")) + r = unit_file_link(scope, runtime, NULL, l, force, &changes, &n_changes); + else if (streq(member, "PresetUnitFiles")) { + r = unit_file_preset(scope, runtime, NULL, l, force, &changes, &n_changes); + carries_install_info = r; + } else if (streq(member, "MaskUnitFiles")) + r = unit_file_mask(scope, runtime, NULL, l, force, &changes, &n_changes); + else + assert_not_reached("Uh? Wrong method"); + + strv_free(l); + bus_manager_send_unit_files_changed(m); + + if (r < 0) { + unit_file_changes_free(changes, n_changes); + return bus_send_error_reply(connection, message, NULL, r); + } + + reply = message_from_file_changes(message, changes, n_changes, carries_install_info); + unit_file_changes_free(changes, n_changes); + + if (!reply) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "DisableUnitFiles") || + dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "UnmaskUnitFiles")) { + + char **l = NULL; + DBusMessageIter iter; + UnitFileScope scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER; + UnitFileChange *changes = NULL; + unsigned n_changes = 0; + dbus_bool_t runtime; + + SELINUX_ACCESS_CHECK(connection, message, streq(member, "UnmaskUnitFiles") ? "enable" : "disable"); + + if (!dbus_message_iter_init(message, &iter)) + goto oom; + + r = bus_parse_strv_iter(&iter, &l); + if (r < 0) { + if (r == -ENOMEM) + goto oom; + + return bus_send_error_reply(connection, message, NULL, r); + } + + if (!dbus_message_iter_next(&iter) || + bus_iter_get_basic_and_next(&iter, DBUS_TYPE_BOOLEAN, &runtime, false) < 0) { + strv_free(l); + return bus_send_error_reply(connection, message, NULL, -EIO); + } + + if (streq(member, "DisableUnitFiles")) + r = unit_file_disable(scope, runtime, NULL, l, &changes, &n_changes); + else if (streq(member, "UnmaskUnitFiles")) + r = unit_file_unmask(scope, runtime, NULL, l, &changes, &n_changes); + else + assert_not_reached("Uh? Wrong method"); + + strv_free(l); + bus_manager_send_unit_files_changed(m); + + if (r < 0) { + unit_file_changes_free(changes, n_changes); + return bus_send_error_reply(connection, message, NULL, r); + } + + reply = message_from_file_changes(message, changes, n_changes, -1); + unit_file_changes_free(changes, n_changes); + + if (!reply) + goto oom; + + } else { + const BusBoundProperties bps[] = { + { "org.freedesktop.systemd1.Manager", bus_systemd_properties, systemd_property_string }, + { "org.freedesktop.systemd1.Manager", bus_manager_properties, m }, + { NULL, } + }; + + SELINUX_ACCESS_CHECK(connection, message, "status"); + + return bus_default_message_handler(connection, message, NULL, INTERFACES_LIST, bps); + } + + if (job_type != _JOB_TYPE_INVALID) { + const char *name, *smode, *old_name = NULL; + JobMode mode; + Unit *u; + dbus_bool_t b; + + if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "StartUnitReplace")) + b = dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &old_name, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_STRING, &smode, + DBUS_TYPE_INVALID); + else + b = dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_STRING, &smode, + DBUS_TYPE_INVALID); + if (!b) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + if (old_name) { + u = manager_get_unit(m, old_name); + if (!u || !u->job || u->job->type != JOB_START) { + dbus_set_error(&error, BUS_ERROR_NO_SUCH_JOB, "No job queued for unit %s", old_name); + return bus_send_error_reply(connection, message, &error, -ENOENT); + } + } + + mode = job_mode_from_string(smode); + if (mode < 0) { + dbus_set_error(&error, BUS_ERROR_INVALID_JOB_MODE, "Job mode %s is invalid.", smode); + return bus_send_error_reply(connection, message, &error, -EINVAL); + } + + r = manager_load_unit(m, name, NULL, &error, &u); + if (r < 0) + return bus_send_error_reply(connection, message, &error, r); + + return bus_unit_queue_job(connection, message, u, job_type, mode, reload_if_possible); + } + + if (reply) + if (!dbus_connection_send(connection, reply, NULL)) + goto oom; + + return DBUS_HANDLER_RESULT_HANDLED; + +oom: + dbus_error_free(&error); + + return DBUS_HANDLER_RESULT_NEED_MEMORY; +} + +const DBusObjectPathVTable bus_manager_vtable = { + .message_function = bus_manager_message_handler +}; diff --git a/src/core/dbus-manager.h b/src/core/dbus-manager.h new file mode 100644 index 000000000..f0dce5a2e --- /dev/null +++ b/src/core/dbus-manager.h @@ -0,0 +1,28 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +#include + +extern const DBusObjectPathVTable bus_manager_vtable; + +extern const char bus_manager_interface[]; diff --git a/src/core/dbus-mount.c b/src/core/dbus-mount.c new file mode 100644 index 000000000..d81edeb80 --- /dev/null +++ b/src/core/dbus-mount.c @@ -0,0 +1,168 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include + +#include "dbus-unit.h" +#include "dbus-mount.h" +#include "dbus-kill.h" +#include "dbus-execute.h" +#include "dbus-common.h" +#include "selinux-access.h" + +#define BUS_MOUNT_INTERFACE \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + BUS_EXEC_COMMAND_INTERFACE("ExecMount") \ + BUS_EXEC_COMMAND_INTERFACE("ExecUnmount") \ + BUS_EXEC_COMMAND_INTERFACE("ExecRemount") \ + BUS_EXEC_CONTEXT_INTERFACE \ + BUS_KILL_CONTEXT_INTERFACE \ + " \n" \ + " \n" \ + " \n" \ + " \n" + +#define INTROSPECTION \ + DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \ + "\n" \ + BUS_UNIT_INTERFACE \ + BUS_MOUNT_INTERFACE \ + BUS_PROPERTIES_INTERFACE \ + BUS_PEER_INTERFACE \ + BUS_INTROSPECTABLE_INTERFACE \ + "\n" + +#define INTERFACES_LIST \ + BUS_UNIT_INTERFACES_LIST \ + "org.freedesktop.systemd1.Mount\0" + +const char bus_mount_interface[] _introspect_("Mount") = BUS_MOUNT_INTERFACE; + +const char bus_mount_invalidating_properties[] = + "What\0" + "Options\0" + "Type\0" + "ExecMount\0" + "ExecUnmount\0" + "ExecRemount\0" + "ControlPID\0" + "Result\0"; + +static int bus_mount_append_what(DBusMessageIter *i, const char *property, void *data) { + Mount *m = data; + const char *d; + + assert(i); + assert(property); + assert(m); + + if (m->from_proc_self_mountinfo && m->parameters_proc_self_mountinfo.what) + d = m->parameters_proc_self_mountinfo.what; + else if (m->from_fragment && m->parameters_fragment.what) + d = m->parameters_fragment.what; + else + d = ""; + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &d)) + return -ENOMEM; + + return 0; +} + +static int bus_mount_append_options(DBusMessageIter *i, const char *property, void *data) { + Mount *m = data; + const char *d; + + assert(i); + assert(property); + assert(m); + + if (m->from_proc_self_mountinfo && m->parameters_proc_self_mountinfo.options) + d = m->parameters_proc_self_mountinfo.options; + else if (m->from_fragment && m->parameters_fragment.options) + d = m->parameters_fragment.options; + else + d = ""; + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &d)) + return -ENOMEM; + + return 0; +} + +static int bus_mount_append_type(DBusMessageIter *i, const char *property, void *data) { + Mount *m = data; + const char *d; + + assert(i); + assert(property); + assert(m); + + if (m->from_proc_self_mountinfo && m->parameters_proc_self_mountinfo.fstype) + d = m->parameters_proc_self_mountinfo.fstype; + else if (m->from_fragment && m->parameters_fragment.fstype) + d = m->parameters_fragment.fstype; + else + d = ""; + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &d)) + return -ENOMEM; + + return 0; +} + +static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_mount_append_mount_result, mount_result, MountResult); + +static const BusProperty bus_mount_properties[] = { + { "Where", bus_property_append_string, "s", offsetof(Mount, where), true }, + { "What", bus_mount_append_what, "s", 0 }, + { "Options", bus_mount_append_options, "s", 0 }, + { "Type", bus_mount_append_type, "s", 0 }, + { "TimeoutUSec", bus_property_append_usec, "t", offsetof(Mount, timeout_usec) }, + BUS_EXEC_COMMAND_PROPERTY("ExecMount", offsetof(Mount, exec_command[MOUNT_EXEC_MOUNT]), false), + BUS_EXEC_COMMAND_PROPERTY("ExecUnmount", offsetof(Mount, exec_command[MOUNT_EXEC_UNMOUNT]), false), + BUS_EXEC_COMMAND_PROPERTY("ExecRemount", offsetof(Mount, exec_command[MOUNT_EXEC_REMOUNT]), false), + { "ControlPID", bus_property_append_pid, "u", offsetof(Mount, control_pid) }, + { "DirectoryMode", bus_property_append_mode, "u", offsetof(Mount, directory_mode) }, + { "Result", bus_mount_append_mount_result, "s", offsetof(Mount, result) }, + { NULL, } +}; + +DBusHandlerResult bus_mount_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) { + Mount *m = MOUNT(u); + + const BusBoundProperties bps[] = { + { "org.freedesktop.systemd1.Unit", bus_unit_properties, u }, + { "org.freedesktop.systemd1.Mount", bus_mount_properties, m }, + { "org.freedesktop.systemd1.Mount", bus_exec_context_properties, &m->exec_context }, + { "org.freedesktop.systemd1.Mount", bus_kill_context_properties, &m->kill_context }, + { NULL, } + }; + + SELINUX_UNIT_ACCESS_CHECK(u, c, message, "status"); + + return bus_default_message_handler(c, message, INTROSPECTION, INTERFACES_LIST, bps ); +} diff --git a/src/core/dbus-mount.h b/src/core/dbus-mount.h new file mode 100644 index 000000000..859739437 --- /dev/null +++ b/src/core/dbus-mount.h @@ -0,0 +1,31 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +#include + +#include "unit.h" + +DBusHandlerResult bus_mount_message_handler(Unit *u, DBusConnection *c, DBusMessage *message); + +extern const char bus_mount_interface[]; +extern const char bus_mount_invalidating_properties[]; diff --git a/src/core/dbus-path.c b/src/core/dbus-path.c new file mode 100644 index 000000000..f7fed1754 --- /dev/null +++ b/src/core/dbus-path.c @@ -0,0 +1,122 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include + +#include "dbus-unit.h" +#include "dbus-path.h" +#include "dbus-execute.h" +#include "dbus-common.h" +#include "selinux-access.h" + +#define BUS_PATH_INTERFACE \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" + +#define INTROSPECTION \ + DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \ + "\n" \ + BUS_UNIT_INTERFACE \ + BUS_PATH_INTERFACE \ + BUS_PROPERTIES_INTERFACE \ + BUS_PEER_INTERFACE \ + BUS_INTROSPECTABLE_INTERFACE \ + "\n" + +#define INTERFACES_LIST \ + BUS_UNIT_INTERFACES_LIST \ + "org.freedesktop.systemd1.Path\0" + +const char bus_path_interface[] _introspect_("Path") = BUS_PATH_INTERFACE; + +const char bus_path_invalidating_properties[] = + "Result\0"; + +static int bus_path_append_paths(DBusMessageIter *i, const char *property, void *data) { + Path *p = data; + DBusMessageIter sub, sub2; + PathSpec *k; + + assert(i); + assert(property); + assert(p); + + if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "(ss)", &sub)) + return -ENOMEM; + + LIST_FOREACH(spec, k, p->specs) { + const char *t = path_type_to_string(k->type); + + if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &t) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &k->path) || + !dbus_message_iter_close_container(&sub, &sub2)) + return -ENOMEM; + } + + if (!dbus_message_iter_close_container(i, &sub)) + return -ENOMEM; + + return 0; +} + +static int bus_path_append_unit(DBusMessageIter *i, const char *property, void *data) { + Unit *u = data; + Path *p = PATH(u); + const char *t; + + assert(i); + assert(property); + assert(u); + + t = UNIT_DEREF(p->unit) ? UNIT_DEREF(p->unit)->id : ""; + + return dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &t) ? 0 : -ENOMEM; +} + +static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_path_append_path_result, path_result, PathResult); + +static const BusProperty bus_path_properties[] = { + { "Unit", bus_path_append_unit, "s", 0 }, + { "Paths", bus_path_append_paths, "a(ss)", 0 }, + { "MakeDirectory", bus_property_append_bool, "b", offsetof(Path, make_directory) }, + { "DirectoryMode", bus_property_append_mode, "u", offsetof(Path, directory_mode) }, + { "Result", bus_path_append_path_result, "s", offsetof(Path, result) }, + { NULL, } +}; + +DBusHandlerResult bus_path_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) { + Path *p = PATH(u); + const BusBoundProperties bps[] = { + { "org.freedesktop.systemd1.Unit", bus_unit_properties, u }, + { "org.freedesktop.systemd1.Path", bus_path_properties, p }, + { NULL, } + }; + + SELINUX_UNIT_ACCESS_CHECK(u, c, message, "status"); + + return bus_default_message_handler(c, message, INTROSPECTION, INTERFACES_LIST, bps); +} diff --git a/src/core/dbus-path.h b/src/core/dbus-path.h new file mode 100644 index 000000000..c945f7d58 --- /dev/null +++ b/src/core/dbus-path.h @@ -0,0 +1,32 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +#include + +#include "unit.h" + +DBusHandlerResult bus_path_message_handler(Unit *u, DBusConnection *c, DBusMessage *message); + +extern const char bus_path_interface[]; + +extern const char bus_path_invalidating_properties[]; diff --git a/src/core/dbus-service.c b/src/core/dbus-service.c new file mode 100644 index 000000000..d99058dd4 --- /dev/null +++ b/src/core/dbus-service.c @@ -0,0 +1,161 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include + +#include "dbus-unit.h" +#include "dbus-execute.h" +#include "dbus-kill.h" +#include "dbus-service.h" +#include "dbus-common.h" +#include "selinux-access.h" + +#define BUS_SERVICE_INTERFACE \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + BUS_EXEC_COMMAND_INTERFACE("ExecStartPre") \ + BUS_EXEC_COMMAND_INTERFACE("ExecStart") \ + BUS_EXEC_COMMAND_INTERFACE("ExecStartPost") \ + BUS_EXEC_COMMAND_INTERFACE("ExecReload") \ + BUS_EXEC_COMMAND_INTERFACE("ExecStop") \ + BUS_EXEC_COMMAND_INTERFACE("ExecStopPost") \ + BUS_EXEC_CONTEXT_INTERFACE \ + BUS_KILL_CONTEXT_INTERFACE \ + " \n" \ + " \n" \ + " \n" \ + BUS_EXEC_STATUS_INTERFACE("ExecMain") \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" + +#define INTROSPECTION \ + DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \ + "\n" \ + BUS_UNIT_INTERFACE \ + BUS_SERVICE_INTERFACE \ + BUS_PROPERTIES_INTERFACE \ + BUS_PEER_INTERFACE \ + BUS_INTROSPECTABLE_INTERFACE \ + "\n" + +#define INTERFACES_LIST \ + BUS_UNIT_INTERFACES_LIST \ + "org.freedesktop.systemd1.Service\0" + +const char bus_service_interface[] _introspect_("Service") = BUS_SERVICE_INTERFACE; + +const char bus_service_invalidating_properties[] = + "ExecStartPre\0" + "ExecStart\0" + "ExecStartPost\0" + "ExecReload\0" + "ExecStop\0" + "ExecStopPost\0" + "ExecMain\0" + "WatchdogTimestamp\0" + "WatchdogTimestampMonotonic\0" + "MainPID\0" + "ControlPID\0" + "StatusText\0" + "Result\0"; + +static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_service_append_type, service_type, ServiceType); +static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_service_append_restart, service_restart, ServiceRestart); +static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_service_append_notify_access, notify_access, NotifyAccess); +static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_service_append_service_result, service_result, ServiceResult); +static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_service_append_start_limit_action, start_limit_action, StartLimitAction); +static DEFINE_BUS_PROPERTY_SET_ENUM(bus_service_set_start_limit_action, start_limit_action, StartLimitAction); + +static const BusProperty bus_exec_main_status_properties[] = { + { "ExecMainStartTimestamp", bus_property_append_usec, "t", offsetof(ExecStatus, start_timestamp.realtime) }, + { "ExecMainStartTimestampMonotonic",bus_property_append_usec, "t", offsetof(ExecStatus, start_timestamp.monotonic) }, + { "ExecMainExitTimestamp", bus_property_append_usec, "t", offsetof(ExecStatus, start_timestamp.realtime) }, + { "ExecMainExitTimestampMonotonic", bus_property_append_usec, "t", offsetof(ExecStatus, start_timestamp.monotonic) }, + { "ExecMainPID", bus_property_append_pid, "u", offsetof(ExecStatus, pid) }, + { "ExecMainCode", bus_property_append_int, "i", offsetof(ExecStatus, code) }, + { "ExecMainStatus", bus_property_append_int, "i", offsetof(ExecStatus, status) }, + { NULL, } +}; + +static const BusProperty bus_service_properties[] = { + { "Type", bus_service_append_type, "s", offsetof(Service, type) }, + { "Restart", bus_service_append_restart, "s", offsetof(Service, restart) }, + { "PIDFile", bus_property_append_string, "s", offsetof(Service, pid_file), true }, + { "NotifyAccess", bus_service_append_notify_access, "s", offsetof(Service, notify_access) }, + { "RestartUSec", bus_property_append_usec, "t", offsetof(Service, restart_usec) }, + { "TimeoutUSec", bus_property_append_usec, "t", offsetof(Service, timeout_start_usec) }, + { "TimeoutStartUSec", bus_property_append_usec, "t", offsetof(Service, timeout_start_usec) }, + { "TimeoutStopUSec", bus_property_append_usec, "t", offsetof(Service, timeout_stop_usec) }, + { "WatchdogUSec", bus_property_append_usec, "t", offsetof(Service, watchdog_usec) }, + { "WatchdogTimestamp", bus_property_append_usec, "t", offsetof(Service, watchdog_timestamp.realtime) }, + { "WatchdogTimestampMonotonic",bus_property_append_usec, "t", offsetof(Service, watchdog_timestamp.monotonic) }, + { "StartLimitInterval", bus_property_append_usec, "t", offsetof(Service, start_limit.interval) }, + { "StartLimitBurst", bus_property_append_uint32, "u", offsetof(Service, start_limit.burst) }, + { "StartLimitAction", bus_service_append_start_limit_action,"s", offsetof(Service, start_limit_action), false, bus_service_set_start_limit_action}, + BUS_EXEC_COMMAND_PROPERTY("ExecStartPre", offsetof(Service, exec_command[SERVICE_EXEC_START_PRE]), true ), + BUS_EXEC_COMMAND_PROPERTY("ExecStart", offsetof(Service, exec_command[SERVICE_EXEC_START]), true ), + BUS_EXEC_COMMAND_PROPERTY("ExecStartPost", offsetof(Service, exec_command[SERVICE_EXEC_START_POST]), true ), + BUS_EXEC_COMMAND_PROPERTY("ExecReload", offsetof(Service, exec_command[SERVICE_EXEC_RELOAD]), true ), + BUS_EXEC_COMMAND_PROPERTY("ExecStop", offsetof(Service, exec_command[SERVICE_EXEC_STOP]), true ), + BUS_EXEC_COMMAND_PROPERTY("ExecStopPost", offsetof(Service, exec_command[SERVICE_EXEC_STOP_POST]), true ), + { "PermissionsStartOnly", bus_property_append_bool, "b", offsetof(Service, permissions_start_only) }, + { "RootDirectoryStartOnly", bus_property_append_bool, "b", offsetof(Service, root_directory_start_only) }, + { "RemainAfterExit", bus_property_append_bool, "b", offsetof(Service, remain_after_exit) }, + { "GuessMainPID", bus_property_append_bool, "b", offsetof(Service, guess_main_pid) }, + { "MainPID", bus_property_append_pid, "u", offsetof(Service, main_pid) }, + { "ControlPID", bus_property_append_pid, "u", offsetof(Service, control_pid) }, + { "BusName", bus_property_append_string, "s", offsetof(Service, bus_name), true }, + { "StatusText", bus_property_append_string, "s", offsetof(Service, status_text), true }, + { "Result", bus_service_append_service_result,"s", offsetof(Service, result) }, + { NULL, } +}; + +DBusHandlerResult bus_service_message_handler(Unit *u, DBusConnection *connection, DBusMessage *message) { + Service *s = SERVICE(u); + + const BusBoundProperties bps[] = { + { "org.freedesktop.systemd1.Unit", bus_unit_properties, u }, + { "org.freedesktop.systemd1.Service", bus_service_properties, s }, + { "org.freedesktop.systemd1.Service", bus_exec_context_properties, &s->exec_context }, + { "org.freedesktop.systemd1.Service", bus_kill_context_properties, &s->kill_context }, + { "org.freedesktop.systemd1.Service", bus_exec_main_status_properties, &s->main_exec_status }, + { NULL, } + }; + + SELINUX_UNIT_ACCESS_CHECK(u, connection, message, "status"); + + return bus_default_message_handler(connection, message, INTROSPECTION, INTERFACES_LIST, bps); +} diff --git a/src/core/dbus-service.h b/src/core/dbus-service.h new file mode 100644 index 000000000..143aed7ae --- /dev/null +++ b/src/core/dbus-service.h @@ -0,0 +1,31 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +#include + +#include "unit.h" + +DBusHandlerResult bus_service_message_handler(Unit *u, DBusConnection *c, DBusMessage *message); + +extern const char bus_service_interface[]; +extern const char bus_service_invalidating_properties[]; diff --git a/src/core/dbus-snapshot.c b/src/core/dbus-snapshot.c new file mode 100644 index 000000000..435c6df39 --- /dev/null +++ b/src/core/dbus-snapshot.c @@ -0,0 +1,94 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include "dbus-unit.h" +#include "dbus-snapshot.h" +#include "dbus-common.h" +#include "selinux-access.h" + +#define BUS_SNAPSHOT_INTERFACE \ + " \n" \ + " \n" \ + " \n" \ + " \n" + +#define INTROSPECTION \ + DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \ + "\n" \ + BUS_UNIT_INTERFACE \ + BUS_SNAPSHOT_INTERFACE \ + BUS_PROPERTIES_INTERFACE \ + BUS_PEER_INTERFACE \ + BUS_INTROSPECTABLE_INTERFACE \ + "\n" + +#define INTERFACES_LIST \ + BUS_UNIT_INTERFACES_LIST \ + "org.freedesktop.systemd1.Snapshot\0" + +const char bus_snapshot_interface[] _introspect_("Snapshot") = BUS_SNAPSHOT_INTERFACE; + +static const BusProperty bus_snapshot_properties[] = { + { "Cleanup", bus_property_append_bool, "b", offsetof(Snapshot, cleanup) }, + { NULL, } +}; + +DBusHandlerResult bus_snapshot_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) { + Snapshot *s = SNAPSHOT(u); + _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; + DBusError error; + + dbus_error_init(&error); + + if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Snapshot", "Remove")) { + + SELINUX_UNIT_ACCESS_CHECK(u, c, message, "stop"); + + snapshot_remove(SNAPSHOT(u)); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + } else { + const BusBoundProperties bps[] = { + { "org.freedesktop.systemd1.Unit", bus_unit_properties, u }, + { "org.freedesktop.systemd1.Snapshot", bus_snapshot_properties, s }, + { NULL, } + }; + + SELINUX_UNIT_ACCESS_CHECK(u, c, message, "status"); + + return bus_default_message_handler(c, message, INTROSPECTION, INTERFACES_LIST, bps); + } + + if (reply) { + if (!dbus_connection_send(c, reply, NULL)) + goto oom; + } + + return DBUS_HANDLER_RESULT_HANDLED; + +oom: + dbus_error_free(&error); + + return DBUS_HANDLER_RESULT_NEED_MEMORY; +} diff --git a/src/core/dbus-snapshot.h b/src/core/dbus-snapshot.h new file mode 100644 index 000000000..1208aafff --- /dev/null +++ b/src/core/dbus-snapshot.h @@ -0,0 +1,30 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +#include + +#include "unit.h" + +DBusHandlerResult bus_snapshot_message_handler(Unit *u, DBusConnection *c, DBusMessage *message); + +extern const char bus_snapshot_interface[]; diff --git a/src/core/dbus-socket.c b/src/core/dbus-socket.c new file mode 100644 index 000000000..095a03161 --- /dev/null +++ b/src/core/dbus-socket.c @@ -0,0 +1,151 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include + +#include "dbus-unit.h" +#include "dbus-socket.h" +#include "dbus-execute.h" +#include "dbus-kill.h" +#include "dbus-common.h" +#include "selinux-access.h" + +#define BUS_SOCKET_INTERFACE \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + BUS_EXEC_COMMAND_INTERFACE("ExecStartPre") \ + BUS_EXEC_COMMAND_INTERFACE("ExecStartPost") \ + BUS_EXEC_COMMAND_INTERFACE("ExecStopPre") \ + BUS_EXEC_COMMAND_INTERFACE("ExecStopPost") \ + BUS_EXEC_CONTEXT_INTERFACE \ + BUS_KILL_CONTEXT_INTERFACE \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + +#define INTROSPECTION \ + DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \ + "\n" \ + BUS_UNIT_INTERFACE \ + BUS_SOCKET_INTERFACE \ + BUS_PROPERTIES_INTERFACE \ + BUS_PEER_INTERFACE \ + BUS_INTROSPECTABLE_INTERFACE \ + "\n" + +#define INTERFACES_LIST \ + BUS_UNIT_INTERFACES_LIST \ + "org.freedesktop.systemd1.Socket\0" + +const char bus_socket_interface[] _introspect_("Socket") = BUS_SOCKET_INTERFACE; + +const char bus_socket_invalidating_properties[] = + "ExecStartPre\0" + "ExecStartPost\0" + "ExecStopPre\0" + "ExecStopPost\0" + "ControlPID\0" + "NAccepted\0" + "NConnections\0" + "Result\0"; + +static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_socket_append_bind_ipv6_only, socket_address_bind_ipv6_only, SocketAddressBindIPv6Only); +static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_socket_append_socket_result, socket_result, SocketResult); + +static const BusProperty bus_socket_properties[] = { + { "BindIPv6Only", bus_socket_append_bind_ipv6_only, "s", offsetof(Socket, bind_ipv6_only) }, + { "Backlog", bus_property_append_unsigned, "u", offsetof(Socket, backlog) }, + { "TimeoutUSec", bus_property_append_usec, "t", offsetof(Socket, timeout_usec) }, + BUS_EXEC_COMMAND_PROPERTY("ExecStartPre", offsetof(Socket, exec_command[SOCKET_EXEC_START_PRE]), true ), + BUS_EXEC_COMMAND_PROPERTY("ExecStartPost", offsetof(Socket, exec_command[SOCKET_EXEC_START_POST]), true ), + BUS_EXEC_COMMAND_PROPERTY("ExecStopPre", offsetof(Socket, exec_command[SOCKET_EXEC_STOP_PRE]), true ), + BUS_EXEC_COMMAND_PROPERTY("ExecStopPost", offsetof(Socket, exec_command[SOCKET_EXEC_STOP_POST]), true ), + { "ControlPID", bus_property_append_pid, "u", offsetof(Socket, control_pid) }, + { "BindToDevice", bus_property_append_string, "s", offsetof(Socket, bind_to_device), true }, + { "DirectoryMode", bus_property_append_mode, "u", offsetof(Socket, directory_mode) }, + { "SocketMode", bus_property_append_mode, "u", offsetof(Socket, socket_mode) }, + { "Accept", bus_property_append_bool, "b", offsetof(Socket, accept) }, + { "KeepAlive", bus_property_append_bool, "b", offsetof(Socket, keep_alive) }, + { "Priority", bus_property_append_int, "i", offsetof(Socket, priority) }, + { "ReceiveBuffer", bus_property_append_size, "t", offsetof(Socket, receive_buffer) }, + { "SendBuffer", bus_property_append_size, "t", offsetof(Socket, send_buffer) }, + { "IPTOS", bus_property_append_int, "i", offsetof(Socket, ip_tos) }, + { "IPTTL", bus_property_append_int, "i", offsetof(Socket, ip_ttl) }, + { "PipeSize", bus_property_append_size, "t", offsetof(Socket, pipe_size) }, + { "FreeBind", bus_property_append_bool, "b", offsetof(Socket, free_bind) }, + { "Transparent", bus_property_append_bool, "b", offsetof(Socket, transparent) }, + { "Broadcast", bus_property_append_bool, "b", offsetof(Socket, broadcast) }, + { "PassCredentials",bus_property_append_bool, "b", offsetof(Socket, pass_cred) }, + { "PassSecurity", bus_property_append_bool, "b", offsetof(Socket, pass_sec) }, + { "Mark", bus_property_append_int, "i", offsetof(Socket, mark) }, + { "MaxConnections", bus_property_append_unsigned, "u", offsetof(Socket, max_connections) }, + { "NConnections", bus_property_append_unsigned, "u", offsetof(Socket, n_connections) }, + { "NAccepted", bus_property_append_unsigned, "u", offsetof(Socket, n_accepted) }, + { "MessageQueueMaxMessages", bus_property_append_long, "x", offsetof(Socket, mq_maxmsg) }, + { "MessageQueueMessageSize", bus_property_append_long, "x", offsetof(Socket, mq_msgsize) }, + { "Result", bus_socket_append_socket_result, "s", offsetof(Socket, result) }, + { "SmackLabel", bus_property_append_string, "s", offsetof(Socket, smack), true }, + { "SmackLabelIPIn", bus_property_append_string, "s", offsetof(Socket, smack_ip_in), true }, + { "SmackLabelIPOut",bus_property_append_string, "s", offsetof(Socket, smack_ip_out), true }, + { NULL, } +}; + +DBusHandlerResult bus_socket_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) { + Socket *s = SOCKET(u); + const BusBoundProperties bps[] = { + { "org.freedesktop.systemd1.Unit", bus_unit_properties, u }, + { "org.freedesktop.systemd1.Socket", bus_socket_properties, s }, + { "org.freedesktop.systemd1.Socket", bus_exec_context_properties, &s->exec_context }, + { "org.freedesktop.systemd1.Socket", bus_kill_context_properties, &s->kill_context }, + { NULL, } + }; + + SELINUX_UNIT_ACCESS_CHECK(u, c, message, "status"); + + return bus_default_message_handler(c, message, INTROSPECTION, INTERFACES_LIST, bps); +} diff --git a/src/core/dbus-socket.h b/src/core/dbus-socket.h new file mode 100644 index 000000000..5369b22e5 --- /dev/null +++ b/src/core/dbus-socket.h @@ -0,0 +1,31 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +#include + +#include "unit.h" + +DBusHandlerResult bus_socket_message_handler(Unit *u, DBusConnection *c, DBusMessage *message); + +extern const char bus_socket_interface[]; +extern const char bus_socket_invalidating_properties[]; diff --git a/src/core/dbus-swap.c b/src/core/dbus-swap.c new file mode 100644 index 000000000..67ea0f24f --- /dev/null +++ b/src/core/dbus-swap.c @@ -0,0 +1,115 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + Copyright 2010 Maarten Lankhorst + + 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 . +***/ + +#include + +#include "dbus-unit.h" +#include "dbus-swap.h" +#include "dbus-execute.h" +#include "dbus-kill.h" +#include "dbus-common.h" +#include "selinux-access.h" + +#define BUS_SWAP_INTERFACE \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + BUS_EXEC_COMMAND_INTERFACE("ExecActivate") \ + BUS_EXEC_COMMAND_INTERFACE("ExecDeactivate") \ + BUS_EXEC_CONTEXT_INTERFACE \ + BUS_KILL_CONTEXT_INTERFACE \ + " \n" \ + " \n" \ + " \n" + +#define INTROSPECTION \ + DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \ + "\n" \ + BUS_UNIT_INTERFACE \ + BUS_SWAP_INTERFACE \ + BUS_PROPERTIES_INTERFACE \ + BUS_PEER_INTERFACE \ + BUS_INTROSPECTABLE_INTERFACE \ + "\n" + +#define INTERFACES_LIST \ + BUS_UNIT_INTERFACES_LIST \ + "org.freedesktop.systemd1.Swap\0" + +const char bus_swap_interface[] _introspect_("Swap") = BUS_SWAP_INTERFACE; + +const char bus_swap_invalidating_properties[] = + "What\0" + "Priority\0" + "ExecActivate\0" + "ExecDeactivate\0" + "ControlPID\0" + "Result\0"; + +static int bus_swap_append_priority(DBusMessageIter *i, const char *property, void *data) { + Swap *s = data; + dbus_int32_t j; + + assert(i); + assert(property); + assert(s); + + if (s->from_proc_swaps) + j = s->parameters_proc_swaps.priority; + else if (s->from_fragment) + j = s->parameters_fragment.priority; + else + j = -1; + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_INT32, &j)) + return -ENOMEM; + + return 0; +} + +static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_swap_append_swap_result, swap_result, SwapResult); + +static const BusProperty bus_swap_properties[] = { + { "What", bus_property_append_string, "s", offsetof(Swap, what), true }, + { "Priority", bus_swap_append_priority, "i", 0 }, + BUS_EXEC_COMMAND_PROPERTY("ExecActivate", offsetof(Swap, exec_command[SWAP_EXEC_ACTIVATE]), false), + BUS_EXEC_COMMAND_PROPERTY("ExecDeactivate", offsetof(Swap, exec_command[SWAP_EXEC_DEACTIVATE]), false), + { "ControlPID", bus_property_append_pid, "u", offsetof(Swap, control_pid) }, + { "Result", bus_swap_append_swap_result,"s", offsetof(Swap, result) }, + { NULL, } +}; + +DBusHandlerResult bus_swap_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) { + Swap *s = SWAP(u); + const BusBoundProperties bps[] = { + { "org.freedesktop.systemd1.Unit", bus_unit_properties, u }, + { "org.freedesktop.systemd1.Swap", bus_swap_properties, s }, + { "org.freedesktop.systemd1.Swap", bus_exec_context_properties, &s->exec_context }, + { "org.freedesktop.systemd1.Swap", bus_kill_context_properties, &s->kill_context }, + { NULL, } + }; + + SELINUX_UNIT_ACCESS_CHECK(u, c, message, "status"); + + return bus_default_message_handler(c, message, INTROSPECTION, INTERFACES_LIST, bps); +} diff --git a/src/core/dbus-swap.h b/src/core/dbus-swap.h new file mode 100644 index 000000000..41fe4447f --- /dev/null +++ b/src/core/dbus-swap.h @@ -0,0 +1,32 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + Copyright 2010 Maarten Lankhorst + + 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 . +***/ + +#include + +#include "unit.h" + +DBusHandlerResult bus_swap_message_handler(Unit *u, DBusConnection *c, DBusMessage *message); + +extern const char bus_swap_interface[]; +extern const char bus_swap_invalidating_properties[]; diff --git a/src/core/dbus-target.c b/src/core/dbus-target.c new file mode 100644 index 000000000..6a775506c --- /dev/null +++ b/src/core/dbus-target.c @@ -0,0 +1,58 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include + +#include "dbus-unit.h" +#include "dbus-target.h" +#include "dbus-common.h" +#include "selinux-access.h" + +#define BUS_TARGET_INTERFACE \ + " \n" \ + " \n" + +#define INTROSPECTION \ + DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \ + "\n" \ + BUS_UNIT_INTERFACE \ + BUS_TARGET_INTERFACE \ + BUS_PROPERTIES_INTERFACE \ + BUS_PEER_INTERFACE \ + BUS_INTROSPECTABLE_INTERFACE \ + "\n" + +#define INTERFACES_LIST \ + BUS_UNIT_INTERFACES_LIST \ + "org.freedesktop.systemd1.Target\0" + +const char bus_target_interface[] _introspect_("Target") = BUS_TARGET_INTERFACE; + +DBusHandlerResult bus_target_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) { + const BusBoundProperties bps[] = { + { "org.freedesktop.systemd1.Unit", bus_unit_properties, u }, + { NULL, } + }; + + SELINUX_UNIT_ACCESS_CHECK(u, c, message, "status"); + + return bus_default_message_handler(c, message, INTROSPECTION, INTERFACES_LIST, bps); +} diff --git a/src/core/dbus-target.h b/src/core/dbus-target.h new file mode 100644 index 000000000..a8a0304c7 --- /dev/null +++ b/src/core/dbus-target.h @@ -0,0 +1,30 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +#include + +#include "unit.h" + +DBusHandlerResult bus_target_message_handler(Unit *u, DBusConnection *c, DBusMessage *message); + +extern const char bus_target_interface[]; diff --git a/src/core/dbus-timer.c b/src/core/dbus-timer.c new file mode 100644 index 000000000..11d18cbd8 --- /dev/null +++ b/src/core/dbus-timer.c @@ -0,0 +1,142 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include + +#include "dbus-unit.h" +#include "dbus-timer.h" +#include "dbus-execute.h" +#include "dbus-common.h" +#include "selinux-access.h" + +#define BUS_TIMER_INTERFACE \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" + +#define INTROSPECTION \ + DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \ + "\n" \ + BUS_UNIT_INTERFACE \ + BUS_TIMER_INTERFACE \ + BUS_PROPERTIES_INTERFACE \ + BUS_PEER_INTERFACE \ + BUS_INTROSPECTABLE_INTERFACE \ + "\n" + +#define INTERFACES_LIST \ + BUS_UNIT_INTERFACES_LIST \ + "org.freedesktop.systemd1.Timer\0" + +const char bus_timer_interface[] _introspect_("Timer") = BUS_TIMER_INTERFACE; + +const char bus_timer_invalidating_properties[] = + "Timers\0" + "NextElapseUSec\0" + "Result\0"; + +static int bus_timer_append_timers(DBusMessageIter *i, const char *property, void *data) { + Timer *p = data; + DBusMessageIter sub, sub2; + TimerValue *k; + + assert(i); + assert(property); + assert(p); + + if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "(stt)", &sub)) + return -ENOMEM; + + LIST_FOREACH(value, k, p->values) { + char *buf; + const char *t; + size_t l; + bool b; + + t = timer_base_to_string(k->base); + assert(endswith(t, "Sec")); + + /* s/Sec/USec/ */ + l = strlen(t); + buf = new(char, l+2); + if (!buf) + return -ENOMEM; + + memcpy(buf, t, l-3); + memcpy(buf+l-3, "USec", 5); + + b = dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2) && + dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &buf) && + dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT64, &k->value) && + dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT64, &k->next_elapse) && + dbus_message_iter_close_container(&sub, &sub2); + + free(buf); + if (!b) + return -ENOMEM; + } + + if (!dbus_message_iter_close_container(i, &sub)) + return -ENOMEM; + + return 0; +} + +static int bus_timer_append_unit(DBusMessageIter *i, const char *property, void *data) { + Unit *u = data; + Timer *timer = TIMER(u); + const char *t; + + assert(i); + assert(property); + assert(u); + + t = UNIT_DEREF(timer->unit) ? UNIT_DEREF(timer->unit)->id : ""; + + return dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &t) ? 0 : -ENOMEM; +} + +static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_timer_append_timer_result, timer_result, TimerResult); + +static const BusProperty bus_timer_properties[] = { + { "Unit", bus_timer_append_unit, "s", 0 }, + { "Timers", bus_timer_append_timers, "a(stt)", 0 }, + { "NextElapseUSec", bus_property_append_usec, "t", offsetof(Timer, next_elapse_monotonic) }, + { "NextElapseUSecRealtime", bus_property_append_usec, "t", offsetof(Timer, next_elapse_realtime) }, + { "Result", bus_timer_append_timer_result,"s", offsetof(Timer, result) }, + { NULL, } +}; + +DBusHandlerResult bus_timer_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) { + Timer *t = TIMER(u); + const BusBoundProperties bps[] = { + { "org.freedesktop.systemd1.Unit", bus_unit_properties, u }, + { "org.freedesktop.systemd1.Timer", bus_timer_properties, t }, + { NULL, } + }; + + SELINUX_UNIT_ACCESS_CHECK(u, c, message, "status"); + + return bus_default_message_handler(c, message, INTROSPECTION, INTERFACES_LIST, bps); +} diff --git a/src/core/dbus-timer.h b/src/core/dbus-timer.h new file mode 100644 index 000000000..9ac30501d --- /dev/null +++ b/src/core/dbus-timer.h @@ -0,0 +1,31 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +#include + +#include "unit.h" + +DBusHandlerResult bus_timer_message_handler(Unit *u, DBusConnection *c, DBusMessage *message); + +extern const char bus_timer_interface[]; +extern const char bus_timer_invalidating_properties[]; diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c new file mode 100644 index 000000000..8433a720b --- /dev/null +++ b/src/core/dbus-unit.c @@ -0,0 +1,877 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include + +#include "dbus.h" +#include "log.h" +#include "dbus-unit.h" +#include "bus-errors.h" +#include "dbus-common.h" +#include "selinux-access.h" + +const char bus_unit_interface[] _introspect_("Unit") = BUS_UNIT_INTERFACE; + +#define INVALIDATING_PROPERTIES \ + "LoadState\0" \ + "ActiveState\0" \ + "SubState\0" \ + "InactiveExitTimestamp\0" \ + "ActiveEnterTimestamp\0" \ + "ActiveExitTimestamp\0" \ + "InactiveEnterTimestamp\0" \ + "Job\0" \ + "NeedDaemonReload\0" + +static int bus_unit_append_names(DBusMessageIter *i, const char *property, void *data) { + char *t; + Iterator j; + DBusMessageIter sub; + Unit *u = data; + + if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "s", &sub)) + return -ENOMEM; + + SET_FOREACH(t, u->names, j) + if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &t)) + return -ENOMEM; + + if (!dbus_message_iter_close_container(i, &sub)) + return -ENOMEM; + + return 0; +} + +static int bus_unit_append_following(DBusMessageIter *i, const char *property, void *data) { + Unit *u = data, *f; + const char *d; + + assert(i); + assert(property); + assert(u); + + f = unit_following(u); + d = f ? f->id : ""; + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &d)) + return -ENOMEM; + + return 0; +} + +static int bus_unit_append_dependencies(DBusMessageIter *i, const char *property, void *data) { + Unit *u; + Iterator j; + DBusMessageIter sub; + Set *s = data; + + if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "s", &sub)) + return -ENOMEM; + + SET_FOREACH(u, s, j) + if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &u->id)) + return -ENOMEM; + + if (!dbus_message_iter_close_container(i, &sub)) + return -ENOMEM; + + return 0; +} + +static int bus_unit_append_description(DBusMessageIter *i, const char *property, void *data) { + Unit *u = data; + const char *d; + + assert(i); + assert(property); + assert(u); + + d = unit_description(u); + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &d)) + return -ENOMEM; + + return 0; +} + +static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_unit_append_load_state, unit_load_state, UnitLoadState); + +static int bus_unit_append_active_state(DBusMessageIter *i, const char *property, void *data) { + Unit *u = data; + const char *state; + + assert(i); + assert(property); + assert(u); + + state = unit_active_state_to_string(unit_active_state(u)); + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &state)) + return -ENOMEM; + + return 0; +} + +static int bus_unit_append_sub_state(DBusMessageIter *i, const char *property, void *data) { + Unit *u = data; + const char *state; + + assert(i); + assert(property); + assert(u); + + state = unit_sub_state_to_string(u); + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &state)) + return -ENOMEM; + + return 0; +} + +static int bus_unit_append_file_state(DBusMessageIter *i, const char *property, void *data) { + Unit *u = data; + const char *state; + + assert(i); + assert(property); + assert(u); + + state = strempty(unit_file_state_to_string(unit_get_unit_file_state(u))); + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &state)) + return -ENOMEM; + + return 0; +} + +static int bus_unit_append_can_start(DBusMessageIter *i, const char *property, void *data) { + Unit *u = data; + dbus_bool_t b; + + assert(i); + assert(property); + assert(u); + + b = unit_can_start(u) && + !u->refuse_manual_start; + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b)) + return -ENOMEM; + + return 0; +} + +static int bus_unit_append_can_stop(DBusMessageIter *i, const char *property, void *data) { + Unit *u = data; + dbus_bool_t b; + + assert(i); + assert(property); + assert(u); + + /* On the lower levels we assume that every unit we can start + * we can also stop */ + + b = unit_can_start(u) && + !u->refuse_manual_stop; + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b)) + return -ENOMEM; + + return 0; +} + +static int bus_unit_append_can_reload(DBusMessageIter *i, const char *property, void *data) { + Unit *u = data; + dbus_bool_t b; + + assert(i); + assert(property); + assert(u); + + b = unit_can_reload(u); + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b)) + return -ENOMEM; + + return 0; +} + +static int bus_unit_append_can_isolate(DBusMessageIter *i, const char *property, void *data) { + Unit *u = data; + dbus_bool_t b; + + assert(i); + assert(property); + assert(u); + + b = unit_can_isolate(u) && + !u->refuse_manual_start; + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b)) + return -ENOMEM; + + return 0; +} + +static int bus_unit_append_job(DBusMessageIter *i, const char *property, void *data) { + Unit *u = data; + DBusMessageIter sub; + _cleanup_free_ char *p = NULL; + + assert(i); + assert(property); + assert(u); + + if (!dbus_message_iter_open_container(i, DBUS_TYPE_STRUCT, NULL, &sub)) + return -ENOMEM; + + if (u->job) { + + p = job_dbus_path(u->job); + if (!p) + return -ENOMEM; + + if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_UINT32, &u->job->id) || + !dbus_message_iter_append_basic(&sub, DBUS_TYPE_OBJECT_PATH, &p)) + return -ENOMEM; + } else { + uint32_t id = 0; + + /* No job, so let's fill in some placeholder + * data. Since we need to fill in a valid path we + * simple point to ourselves. */ + + p = unit_dbus_path(u); + if (!p) + return -ENOMEM; + + if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_UINT32, &id) || + !dbus_message_iter_append_basic(&sub, DBUS_TYPE_OBJECT_PATH, &p)) + return -ENOMEM; + } + + if (!dbus_message_iter_close_container(i, &sub)) + return -ENOMEM; + + return 0; +} + +static int bus_unit_append_default_cgroup(DBusMessageIter *i, const char *property, void *data) { + Unit *u = data; + char *t; + CGroupBonding *cgb; + bool success; + + assert(i); + assert(property); + assert(u); + + cgb = unit_get_default_cgroup(u); + if (cgb) { + t = cgroup_bonding_to_string(cgb); + if (!t) + return -ENOMEM; + } else + t = (char*) ""; + + success = dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &t); + + if (cgb) + free(t); + + return success ? 0 : -ENOMEM; +} + +static int bus_unit_append_cgroups(DBusMessageIter *i, const char *property, void *data) { + Unit *u = data; + CGroupBonding *cgb; + DBusMessageIter sub; + + if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "s", &sub)) + return -ENOMEM; + + LIST_FOREACH(by_unit, cgb, u->cgroup_bondings) { + char _cleanup_free_ *t = NULL; + bool success; + + t = cgroup_bonding_to_string(cgb); + if (!t) + return -ENOMEM; + + success = dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &t); + if (!success) + return -ENOMEM; + } + + if (!dbus_message_iter_close_container(i, &sub)) + return -ENOMEM; + + return 0; +} + +static int bus_unit_append_cgroup_attrs(DBusMessageIter *i, const char *property, void *data) { + Unit *u = data; + CGroupAttribute *a; + DBusMessageIter sub, sub2; + + if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "(sss)", &sub)) + return -ENOMEM; + + LIST_FOREACH(by_unit, a, u->cgroup_attributes) { + char _cleanup_free_ *v = NULL; + bool success; + + if (a->map_callback) + a->map_callback(a->controller, a->name, a->value, &v); + + success = + dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2) && + dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &a->controller) && + dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &a->name) && + dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, v ? &v : &a->value) && + dbus_message_iter_close_container(&sub, &sub2); + if (!success) + return -ENOMEM; + } + + if (!dbus_message_iter_close_container(i, &sub)) + return -ENOMEM; + + return 0; +} + +static int bus_unit_append_need_daemon_reload(DBusMessageIter *i, const char *property, void *data) { + Unit *u = data; + dbus_bool_t b; + + assert(i); + assert(property); + assert(u); + + b = unit_need_daemon_reload(u); + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b)) + return -ENOMEM; + + return 0; +} + +static int bus_unit_append_load_error(DBusMessageIter *i, const char *property, void *data) { + Unit *u = data; + const char *name, *message; + DBusMessageIter sub; + + assert(i); + assert(property); + assert(u); + + if (u->load_error != 0) { + name = bus_errno_to_dbus(u->load_error); + message = strempty(strerror(-u->load_error)); + } else + name = message = ""; + + if (!dbus_message_iter_open_container(i, DBUS_TYPE_STRUCT, NULL, &sub) || + !dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &name) || + !dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &message) || + !dbus_message_iter_close_container(i, &sub)) + return -ENOMEM; + + return 0; +} + +static DBusHandlerResult bus_unit_message_dispatch(Unit *u, DBusConnection *connection, DBusMessage *message) { + _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; + DBusError error; + JobType job_type = _JOB_TYPE_INVALID; + bool reload_if_possible = false; + int r; + + dbus_error_init(&error); + + if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Unit", "Start")) + job_type = JOB_START; + else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Unit", "Stop")) + job_type = JOB_STOP; + else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Unit", "Reload")) + job_type = JOB_RELOAD; + else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Unit", "Restart")) + job_type = JOB_RESTART; + else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Unit", "TryRestart")) + job_type = JOB_TRY_RESTART; + else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Unit", "ReloadOrRestart")) { + reload_if_possible = true; + job_type = JOB_RESTART; + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Unit", "ReloadOrTryRestart")) { + reload_if_possible = true; + job_type = JOB_TRY_RESTART; + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Unit", "Kill")) { + const char *swho; + int32_t signo; + KillWho who; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &swho, + DBUS_TYPE_INT32, &signo, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + if (isempty(swho)) + who = KILL_ALL; + else { + who = kill_who_from_string(swho); + if (who < 0) + return bus_send_error_reply(connection, message, &error, -EINVAL); + } + + if (signo <= 0 || signo >= _NSIG) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + SELINUX_UNIT_ACCESS_CHECK(u, connection, message, "stop"); + + r = unit_kill(u, who, signo, &error); + if (r < 0) + return bus_send_error_reply(connection, message, &error, r); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Unit", "ResetFailed")) { + + SELINUX_UNIT_ACCESS_CHECK(u, connection, message, "reload"); + + unit_reset_failed(u); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + } else if (UNIT_VTABLE(u)->bus_message_handler) + return UNIT_VTABLE(u)->bus_message_handler(u, connection, message); + else + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + + if (job_type != _JOB_TYPE_INVALID) { + const char *smode; + JobMode mode; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &smode, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + mode = job_mode_from_string(smode); + if (mode < 0) { + dbus_set_error(&error, BUS_ERROR_INVALID_JOB_MODE, "Job mode %s is invalid.", smode); + return bus_send_error_reply(connection, message, &error, -EINVAL); + } + + return bus_unit_queue_job(connection, message, u, job_type, mode, reload_if_possible); + } + + if (reply) + if (!dbus_connection_send(connection, reply, NULL)) + goto oom; + + return DBUS_HANDLER_RESULT_HANDLED; + +oom: + dbus_error_free(&error); + return DBUS_HANDLER_RESULT_NEED_MEMORY; +} + +static DBusHandlerResult bus_unit_message_handler(DBusConnection *connection, DBusMessage *message, void *data) { + Manager *m = data; + Unit *u; + int r; + _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; + DBusError error; + + assert(connection); + assert(message); + assert(m); + + dbus_error_init(&error); + + if (streq(dbus_message_get_path(message), "/org/freedesktop/systemd1/unit")) { + /* Be nice to gdbus and return introspection data for our mid-level paths */ + + SELINUX_ACCESS_CHECK(connection, message, "status"); + + if (dbus_message_is_method_call(message, "org.freedesktop.DBus.Introspectable", "Introspect")) { + char *introspection = NULL; + FILE *f; + Iterator i; + const char *k; + size_t size; + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + /* We roll our own introspection code here, instead of + * relying on bus_default_message_handler() because we + * need to generate our introspection string + * dynamically. */ + + f = open_memstream(&introspection, &size); + if (!f) + goto oom; + + fputs(DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE + "\n", f); + + fputs(BUS_INTROSPECTABLE_INTERFACE, f); + fputs(BUS_PEER_INTERFACE, f); + + HASHMAP_FOREACH_KEY(u, k, m->units, i) { + char *p; + + if (k != u->id) + continue; + + p = bus_path_escape(k); + if (!p) { + fclose(f); + free(introspection); + goto oom; + } + + fprintf(f, "", p); + free(p); + } + + fputs("\n", f); + + if (ferror(f)) { + fclose(f); + free(introspection); + goto oom; + } + + fclose(f); + + if (!introspection) + goto oom; + + if (!dbus_message_append_args(reply, DBUS_TYPE_STRING, &introspection, DBUS_TYPE_INVALID)) { + free(introspection); + goto oom; + } + + free(introspection); + + if (!dbus_connection_send(connection, reply, NULL)) + goto oom; + + return DBUS_HANDLER_RESULT_HANDLED; + } + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + + r = manager_load_unit_from_dbus_path(m, dbus_message_get_path(message), &error, &u); + if (r == -ENOMEM) + goto oom; + if (r < 0) + return bus_send_error_reply(connection, message, &error, r); + + return bus_unit_message_dispatch(u, connection, message); + +oom: + dbus_error_free(&error); + + return DBUS_HANDLER_RESULT_NEED_MEMORY; +} + +const DBusObjectPathVTable bus_unit_vtable = { + .message_function = bus_unit_message_handler +}; + +void bus_unit_send_change_signal(Unit *u) { + _cleanup_free_ char *p = NULL; + _cleanup_dbus_message_unref_ DBusMessage *m = NULL; + + assert(u); + + if (u->in_dbus_queue) { + LIST_REMOVE(Unit, dbus_queue, u->manager->dbus_unit_queue, u); + u->in_dbus_queue = false; + } + + if (!u->id) + return; + + if (!bus_has_subscriber(u->manager)) { + u->sent_dbus_new_signal = true; + return; + } + + p = unit_dbus_path(u); + if (!p) + goto oom; + + if (u->sent_dbus_new_signal) { + /* Send a properties changed signal. First for the + * specific type, then for the generic unit. The + * clients may rely on this order to get atomic + * behavior if needed. */ + + if (UNIT_VTABLE(u)->bus_invalidating_properties) { + + m = bus_properties_changed_new(p, + UNIT_VTABLE(u)->bus_interface, + UNIT_VTABLE(u)->bus_invalidating_properties); + if (!m) + goto oom; + + if (bus_broadcast(u->manager, m) < 0) + goto oom; + + dbus_message_unref(m); + } + + m = bus_properties_changed_new(p, "org.freedesktop.systemd1.Unit", + INVALIDATING_PROPERTIES); + if (!m) + goto oom; + + } else { + /* Send a new signal */ + + m = dbus_message_new_signal("/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "UnitNew"); + if (!m) + goto oom; + + if (!dbus_message_append_args(m, + DBUS_TYPE_STRING, &u->id, + DBUS_TYPE_OBJECT_PATH, &p, + DBUS_TYPE_INVALID)) + goto oom; + } + + if (bus_broadcast(u->manager, m) < 0) + goto oom; + + u->sent_dbus_new_signal = true; + + return; + +oom: + log_oom(); +} + +void bus_unit_send_removed_signal(Unit *u) { + _cleanup_free_ char *p = NULL; + _cleanup_dbus_message_unref_ DBusMessage *m = NULL; + + assert(u); + + if (!bus_has_subscriber(u->manager)) + return; + + if (!u->sent_dbus_new_signal) + bus_unit_send_change_signal(u); + + if (!u->id) + return; + + p = unit_dbus_path(u); + if (!p) + goto oom; + + m = dbus_message_new_signal("/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "UnitRemoved"); + if (!m) + goto oom; + + if (!dbus_message_append_args(m, + DBUS_TYPE_STRING, &u->id, + DBUS_TYPE_OBJECT_PATH, &p, + DBUS_TYPE_INVALID)) + goto oom; + + if (bus_broadcast(u->manager, m) < 0) + goto oom; + + return; + +oom: + log_oom(); +} + +DBusHandlerResult bus_unit_queue_job( + DBusConnection *connection, + DBusMessage *message, + Unit *u, + JobType type, + JobMode mode, + bool reload_if_possible) { + + _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; + _cleanup_free_ char *path = NULL; + Job *j; + JobBusClient *cl; + DBusError error; + int r; + + assert(connection); + assert(message); + assert(u); + assert(type >= 0 && type < _JOB_TYPE_MAX); + assert(mode >= 0 && mode < _JOB_MODE_MAX); + + dbus_error_init(&error); + + if (reload_if_possible && unit_can_reload(u)) { + if (type == JOB_RESTART) + type = JOB_RELOAD_OR_START; + else if (type == JOB_TRY_RESTART) + type = JOB_RELOAD; + } + + SELINUX_UNIT_ACCESS_CHECK(u, connection, message, + (type == JOB_START || type == JOB_RESTART || type == JOB_TRY_RESTART) ? "start" : + type == JOB_STOP ? "stop" : "reload"); + + if (type == JOB_STOP && u->load_state == UNIT_ERROR && unit_active_state(u) == UNIT_INACTIVE) { + dbus_set_error(&error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s not loaded.", u->id); + return bus_send_error_reply(connection, message, &error, -EPERM); + } + + if ((type == JOB_START && u->refuse_manual_start) || + (type == JOB_STOP && u->refuse_manual_stop) || + ((type == JOB_RESTART || type == JOB_TRY_RESTART) && (u->refuse_manual_start || u->refuse_manual_stop))) { + dbus_set_error(&error, BUS_ERROR_ONLY_BY_DEPENDENCY, + "Operation refused, unit %s may be requested by dependency only.", u->id); + return bus_send_error_reply(connection, message, &error, -EPERM); + } + + r = manager_add_job(u->manager, type, u, mode, true, &error, &j); + if (r < 0) + return bus_send_error_reply(connection, message, &error, r); + + cl = job_bus_client_new(connection, bus_message_get_sender_with_fallback(message)); + if (!cl) + goto oom; + + LIST_PREPEND(JobBusClient, client, j->bus_client_list, cl); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + path = job_dbus_path(j); + if (!path) + goto oom; + + if (!dbus_message_append_args( + reply, + DBUS_TYPE_OBJECT_PATH, &path, + DBUS_TYPE_INVALID)) + goto oom; + + if (!dbus_connection_send(connection, reply, NULL)) + goto oom; + + return DBUS_HANDLER_RESULT_HANDLED; + +oom: + dbus_error_free(&error); + + return DBUS_HANDLER_RESULT_NEED_MEMORY; +} + +const BusProperty bus_unit_properties[] = { + { "Id", bus_property_append_string, "s", offsetof(Unit, id), true }, + { "Names", bus_unit_append_names, "as", 0 }, + { "Following", bus_unit_append_following, "s", 0 }, + { "Requires", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_REQUIRES]), true }, + { "RequiresOverridable", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_REQUIRES_OVERRIDABLE]), true }, + { "Requisite", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_REQUISITE]), true }, + { "RequisiteOverridable", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_REQUISITE_OVERRIDABLE]), true }, + { "Wants", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_WANTS]), true }, + { "BindsTo", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_BINDS_TO]), true }, + { "PartOf", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_PART_OF]), true }, + { "RequiredBy", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_REQUIRED_BY]), true }, + { "RequiredByOverridable",bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_REQUIRED_BY_OVERRIDABLE]), true }, + { "WantedBy", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_WANTED_BY]), true }, + { "BoundBy", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_BOUND_BY]), true }, + { "ConsistsOf", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_CONSISTS_OF]), true }, + { "Conflicts", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_CONFLICTS]), true }, + { "ConflictedBy", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_CONFLICTED_BY]), true }, + { "Before", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_BEFORE]), true }, + { "After", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_AFTER]), true }, + { "OnFailure", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_ON_FAILURE]), true }, + { "Triggers", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_TRIGGERS]), true }, + { "TriggeredBy", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_TRIGGERED_BY]), true }, + { "PropagatesReloadTo", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_PROPAGATES_RELOAD_TO]), true }, + { "ReloadPropagatedFrom", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_RELOAD_PROPAGATED_FROM]), true }, + { "RequiresMountsFor", bus_property_append_strv, "as", offsetof(Unit, requires_mounts_for), true }, + { "Documentation", bus_property_append_strv, "as", offsetof(Unit, documentation), true }, + { "Description", bus_unit_append_description, "s", 0 }, + { "LoadState", bus_unit_append_load_state, "s", offsetof(Unit, load_state) }, + { "ActiveState", bus_unit_append_active_state, "s", 0 }, + { "SubState", bus_unit_append_sub_state, "s", 0 }, + { "FragmentPath", bus_property_append_string, "s", offsetof(Unit, fragment_path), true }, + { "SourcePath", bus_property_append_string, "s", offsetof(Unit, source_path), true }, + { "UnitFileState", bus_unit_append_file_state, "s", 0 }, + { "InactiveExitTimestamp",bus_property_append_usec, "t", offsetof(Unit, inactive_exit_timestamp.realtime) }, + { "InactiveExitTimestampMonotonic", bus_property_append_usec, "t", offsetof(Unit, inactive_exit_timestamp.monotonic) }, + { "ActiveEnterTimestamp", bus_property_append_usec, "t", offsetof(Unit, active_enter_timestamp.realtime) }, + { "ActiveEnterTimestampMonotonic", bus_property_append_usec, "t", offsetof(Unit, active_enter_timestamp.monotonic) }, + { "ActiveExitTimestamp", bus_property_append_usec, "t", offsetof(Unit, active_exit_timestamp.realtime) }, + { "ActiveExitTimestampMonotonic", bus_property_append_usec, "t", offsetof(Unit, active_exit_timestamp.monotonic) }, + { "InactiveEnterTimestamp", bus_property_append_usec, "t", offsetof(Unit, inactive_enter_timestamp.realtime) }, + { "InactiveEnterTimestampMonotonic",bus_property_append_usec, "t", offsetof(Unit, inactive_enter_timestamp.monotonic) }, + { "CanStart", bus_unit_append_can_start, "b", 0 }, + { "CanStop", bus_unit_append_can_stop, "b", 0 }, + { "CanReload", bus_unit_append_can_reload, "b", 0 }, + { "CanIsolate", bus_unit_append_can_isolate, "b", 0 }, + { "Job", bus_unit_append_job, "(uo)", 0 }, + { "StopWhenUnneeded", bus_property_append_bool, "b", offsetof(Unit, stop_when_unneeded) }, + { "RefuseManualStart", bus_property_append_bool, "b", offsetof(Unit, refuse_manual_start) }, + { "RefuseManualStop", bus_property_append_bool, "b", offsetof(Unit, refuse_manual_stop) }, + { "AllowIsolate", bus_property_append_bool, "b", offsetof(Unit, allow_isolate) }, + { "DefaultDependencies", bus_property_append_bool, "b", offsetof(Unit, default_dependencies) }, + { "OnFailureIsolate", bus_property_append_bool, "b", offsetof(Unit, on_failure_isolate) }, + { "IgnoreOnIsolate", bus_property_append_bool, "b", offsetof(Unit, ignore_on_isolate) }, + { "IgnoreOnSnapshot", bus_property_append_bool, "b", offsetof(Unit, ignore_on_snapshot) }, + { "DefaultControlGroup", bus_unit_append_default_cgroup, "s", 0 }, + { "ControlGroup", bus_unit_append_cgroups, "as", 0 }, + { "ControlGroupAttributes", bus_unit_append_cgroup_attrs,"a(sss)", 0 }, + { "NeedDaemonReload", bus_unit_append_need_daemon_reload, "b", 0 }, + { "JobTimeoutUSec", bus_property_append_usec, "t", offsetof(Unit, job_timeout) }, + { "ConditionTimestamp", bus_property_append_usec, "t", offsetof(Unit, condition_timestamp.realtime) }, + { "ConditionTimestampMonotonic", bus_property_append_usec, "t", offsetof(Unit, condition_timestamp.monotonic) }, + { "ConditionResult", bus_property_append_bool, "b", offsetof(Unit, condition_result) }, + { "LoadError", bus_unit_append_load_error, "(ss)", 0 }, + { NULL, } +}; diff --git a/src/core/dbus-unit.h b/src/core/dbus-unit.h new file mode 100644 index 000000000..ac6785a94 --- /dev/null +++ b/src/core/dbus-unit.h @@ -0,0 +1,147 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +#include + +#include "manager.h" +#include "dbus-common.h" + +#define BUS_UNIT_INTERFACE \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" + +#define BUS_UNIT_INTERFACES_LIST \ + BUS_GENERIC_INTERFACES_LIST \ + "org.freedesktop.systemd1.Unit\0" + +extern const BusProperty bus_unit_properties[]; + +void bus_unit_send_change_signal(Unit *u); +void bus_unit_send_removed_signal(Unit *u); + + +DBusHandlerResult bus_unit_queue_job( + DBusConnection *connection, + DBusMessage *message, + Unit *u, + JobType type, + JobMode mode, + bool reload_if_possible); + +extern const DBusObjectPathVTable bus_unit_vtable; + +extern const char bus_unit_interface[]; diff --git a/src/core/dbus.c b/src/core/dbus.c new file mode 100644 index 000000000..2a1c66054 --- /dev/null +++ b/src/core/dbus.c @@ -0,0 +1,1479 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include +#include + +#include "dbus.h" +#include "log.h" +#include "strv.h" +#include "cgroup.h" +#include "mkdir.h" +#include "missing.h" +#include "dbus-unit.h" +#include "dbus-job.h" +#include "dbus-manager.h" +#include "dbus-service.h" +#include "dbus-socket.h" +#include "dbus-target.h" +#include "dbus-device.h" +#include "dbus-mount.h" +#include "dbus-automount.h" +#include "dbus-snapshot.h" +#include "dbus-swap.h" +#include "dbus-timer.h" +#include "dbus-path.h" +#include "bus-errors.h" +#include "special.h" +#include "dbus-common.h" + +#define CONNECTIONS_MAX 52 + +/* Well-known address (http://dbus.freedesktop.org/doc/dbus-specification.html#message-bus-types) */ +#define DBUS_SYSTEM_BUS_DEFAULT_ADDRESS "unix:path=/var/run/dbus/system_bus_socket" +/* Only used as a fallback */ +#define DBUS_SESSION_BUS_DEFAULT_ADDRESS "autolaunch:" + +static const char bus_properties_interface[] = BUS_PROPERTIES_INTERFACE; +static const char bus_introspectable_interface[] = BUS_INTROSPECTABLE_INTERFACE; + +const char *const bus_interface_table[] = { + "org.freedesktop.DBus.Properties", bus_properties_interface, + "org.freedesktop.DBus.Introspectable", bus_introspectable_interface, + "org.freedesktop.systemd1.Manager", bus_manager_interface, + "org.freedesktop.systemd1.Job", bus_job_interface, + "org.freedesktop.systemd1.Unit", bus_unit_interface, + "org.freedesktop.systemd1.Service", bus_service_interface, + "org.freedesktop.systemd1.Socket", bus_socket_interface, + "org.freedesktop.systemd1.Target", bus_target_interface, + "org.freedesktop.systemd1.Device", bus_device_interface, + "org.freedesktop.systemd1.Mount", bus_mount_interface, + "org.freedesktop.systemd1.Automount", bus_automount_interface, + "org.freedesktop.systemd1.Snapshot", bus_snapshot_interface, + "org.freedesktop.systemd1.Swap", bus_swap_interface, + "org.freedesktop.systemd1.Timer", bus_timer_interface, + "org.freedesktop.systemd1.Path", bus_path_interface, + NULL +}; + +static void bus_done_api(Manager *m); +static void bus_done_system(Manager *m); +static void bus_done_private(Manager *m); +static void shutdown_connection(Manager *m, DBusConnection *c); + +static void bus_dispatch_status(DBusConnection *bus, DBusDispatchStatus status, void *data) { + Manager *m = data; + + assert(bus); + assert(m); + + /* We maintain two sets, one for those connections where we + * requested a dispatch, and another where we didn't. And then, + * we move the connections between the two sets. */ + + if (status == DBUS_DISPATCH_COMPLETE) + set_move_one(m->bus_connections, m->bus_connections_for_dispatch, bus); + else + set_move_one(m->bus_connections_for_dispatch, m->bus_connections, bus); +} + +void bus_watch_event(Manager *m, Watch *w, int events) { + assert(m); + assert(w); + + /* This is called by the event loop whenever there is + * something happening on D-Bus' file handles. */ + + if (!dbus_watch_get_enabled(w->data.bus_watch)) + return; + + dbus_watch_handle(w->data.bus_watch, bus_events_to_flags(events)); +} + +static dbus_bool_t bus_add_watch(DBusWatch *bus_watch, void *data) { + Manager *m = data; + Watch *w; + struct epoll_event ev; + + assert(bus_watch); + assert(m); + + if (!(w = new0(Watch, 1))) + return FALSE; + + w->fd = dbus_watch_get_unix_fd(bus_watch); + w->type = WATCH_DBUS_WATCH; + w->data.bus_watch = bus_watch; + + zero(ev); + ev.events = bus_flags_to_events(bus_watch); + ev.data.ptr = w; + + if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, w->fd, &ev) < 0) { + + if (errno != EEXIST) { + free(w); + return FALSE; + } + + /* Hmm, bloody D-Bus creates multiple watches on the + * same fd. epoll() does not like that. As a dirty + * hack we simply dup() the fd and hence get a second + * one we can safely add to the epoll(). */ + + if ((w->fd = dup(w->fd)) < 0) { + free(w); + return FALSE; + } + + if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, w->fd, &ev) < 0) { + close_nointr_nofail(w->fd); + free(w); + return FALSE; + } + + w->fd_is_dupped = true; + } + + dbus_watch_set_data(bus_watch, w, NULL); + + return TRUE; +} + +static void bus_remove_watch(DBusWatch *bus_watch, void *data) { + Manager *m = data; + Watch *w; + + assert(bus_watch); + assert(m); + + w = dbus_watch_get_data(bus_watch); + if (!w) + return; + + assert(w->type == WATCH_DBUS_WATCH); + assert_se(epoll_ctl(m->epoll_fd, EPOLL_CTL_DEL, w->fd, NULL) >= 0); + + if (w->fd_is_dupped) + close_nointr_nofail(w->fd); + + free(w); +} + +static void bus_toggle_watch(DBusWatch *bus_watch, void *data) { + Manager *m = data; + Watch *w; + struct epoll_event ev; + + assert(bus_watch); + assert(m); + + w = dbus_watch_get_data(bus_watch); + if (!w) + return; + + assert(w->type == WATCH_DBUS_WATCH); + + zero(ev); + ev.events = bus_flags_to_events(bus_watch); + ev.data.ptr = w; + + assert_se(epoll_ctl(m->epoll_fd, EPOLL_CTL_MOD, w->fd, &ev) == 0); +} + +static int bus_timeout_arm(Manager *m, Watch *w) { + struct itimerspec its; + + assert(m); + assert(w); + + zero(its); + + if (dbus_timeout_get_enabled(w->data.bus_timeout)) { + timespec_store(&its.it_value, dbus_timeout_get_interval(w->data.bus_timeout) * USEC_PER_MSEC); + its.it_interval = its.it_value; + } + + if (timerfd_settime(w->fd, 0, &its, NULL) < 0) + return -errno; + + return 0; +} + +void bus_timeout_event(Manager *m, Watch *w, int events) { + assert(m); + assert(w); + + /* This is called by the event loop whenever there is + * something happening on D-Bus' file handles. */ + + if (!(dbus_timeout_get_enabled(w->data.bus_timeout))) + return; + + dbus_timeout_handle(w->data.bus_timeout); +} + +static dbus_bool_t bus_add_timeout(DBusTimeout *timeout, void *data) { + Manager *m = data; + Watch *w; + struct epoll_event ev; + + assert(timeout); + assert(m); + + if (!(w = new0(Watch, 1))) + return FALSE; + + if ((w->fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK|TFD_CLOEXEC)) < 0) + goto fail; + + w->type = WATCH_DBUS_TIMEOUT; + w->data.bus_timeout = timeout; + + if (bus_timeout_arm(m, w) < 0) + goto fail; + + zero(ev); + ev.events = EPOLLIN; + ev.data.ptr = w; + + if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, w->fd, &ev) < 0) + goto fail; + + dbus_timeout_set_data(timeout, w, NULL); + + return TRUE; + +fail: + if (w->fd >= 0) + close_nointr_nofail(w->fd); + + free(w); + return FALSE; +} + +static void bus_remove_timeout(DBusTimeout *timeout, void *data) { + Manager *m = data; + Watch *w; + + assert(timeout); + assert(m); + + w = dbus_timeout_get_data(timeout); + if (!w) + return; + + assert(w->type == WATCH_DBUS_TIMEOUT); + + assert_se(epoll_ctl(m->epoll_fd, EPOLL_CTL_DEL, w->fd, NULL) >= 0); + close_nointr_nofail(w->fd); + free(w); +} + +static void bus_toggle_timeout(DBusTimeout *timeout, void *data) { + Manager *m = data; + Watch *w; + int r; + + assert(timeout); + assert(m); + + w = dbus_timeout_get_data(timeout); + if (!w) + return; + + assert(w->type == WATCH_DBUS_TIMEOUT); + + if ((r = bus_timeout_arm(m, w)) < 0) + log_error("Failed to rearm timer: %s", strerror(-r)); +} + +static DBusHandlerResult api_bus_message_filter(DBusConnection *connection, DBusMessage *message, void *data) { + Manager *m = data; + DBusError error; + DBusMessage *reply = NULL; + + assert(connection); + assert(message); + assert(m); + + dbus_error_init(&error); + + if (dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_METHOD_CALL || + dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_SIGNAL) + log_debug("Got D-Bus request: %s.%s() on %s", + dbus_message_get_interface(message), + dbus_message_get_member(message), + dbus_message_get_path(message)); + + if (dbus_message_is_signal(message, DBUS_INTERFACE_LOCAL, "Disconnected")) { + log_debug("API D-Bus connection terminated."); + bus_done_api(m); + + } else if (dbus_message_is_signal(message, DBUS_INTERFACE_DBUS, "NameOwnerChanged")) { + const char *name, *old_owner, *new_owner; + + if (!dbus_message_get_args(message, &error, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_STRING, &old_owner, + DBUS_TYPE_STRING, &new_owner, + DBUS_TYPE_INVALID)) + log_error("Failed to parse NameOwnerChanged message: %s", bus_error_message(&error)); + else { + if (set_remove(BUS_CONNECTION_SUBSCRIBED(m, connection), (char*) name)) + log_debug("Subscription client vanished: %s (left: %u)", name, set_size(BUS_CONNECTION_SUBSCRIBED(m, connection))); + + if (old_owner[0] == 0) + old_owner = NULL; + + if (new_owner[0] == 0) + new_owner = NULL; + + manager_dispatch_bus_name_owner_changed(m, name, old_owner, new_owner); + } + } else if (dbus_message_is_signal(message, "org.freedesktop.systemd1.Activator", "ActivationRequest")) { + const char *name; + + if (!dbus_message_get_args(message, &error, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_INVALID)) + log_error("Failed to parse ActivationRequest message: %s", bus_error_message(&error)); + else { + int r; + Unit *u; + + log_debug("Got D-Bus activation request for %s", name); + + if (manager_unit_pending_inactive(m, SPECIAL_DBUS_SERVICE) || + manager_unit_pending_inactive(m, SPECIAL_DBUS_SOCKET)) { + r = -EADDRNOTAVAIL; + dbus_set_error(&error, BUS_ERROR_SHUTTING_DOWN, "Refusing activation, D-Bus is shutting down."); + } else { + r = manager_load_unit(m, name, NULL, &error, &u); + + if (r >= 0 && u->refuse_manual_start) + r = -EPERM; + + if (r >= 0) + r = manager_add_job(m, JOB_START, u, JOB_REPLACE, true, &error, NULL); + } + + if (r < 0) { + const char *id, *text; + + log_debug("D-Bus activation failed for %s: %s", name, strerror(-r)); + + if (!(reply = dbus_message_new_signal("/org/freedesktop/systemd1", "org.freedesktop.systemd1.Activator", "ActivationFailure"))) + goto oom; + + id = error.name ? error.name : bus_errno_to_dbus(r); + text = bus_error(&error, r); + + if (!dbus_message_set_destination(reply, DBUS_SERVICE_DBUS) || + !dbus_message_append_args(reply, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_STRING, &id, + DBUS_TYPE_STRING, &text, + DBUS_TYPE_INVALID)) + goto oom; + } + + /* On success we don't do anything, the service will be spawned now */ + } + } + + dbus_error_free(&error); + + if (reply) { + if (!dbus_connection_send(connection, reply, NULL)) + goto oom; + + dbus_message_unref(reply); + } + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + +oom: + if (reply) + dbus_message_unref(reply); + + dbus_error_free(&error); + + return DBUS_HANDLER_RESULT_NEED_MEMORY; +} + +static DBusHandlerResult system_bus_message_filter(DBusConnection *connection, DBusMessage *message, void *data) { + Manager *m = data; + DBusError error; + + assert(connection); + assert(message); + assert(m); + + dbus_error_init(&error); + + if (m->api_bus != m->system_bus && + (dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_METHOD_CALL || + dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_SIGNAL)) + log_debug("Got D-Bus request on system bus: %s.%s() on %s", + dbus_message_get_interface(message), + dbus_message_get_member(message), + dbus_message_get_path(message)); + + if (dbus_message_is_signal(message, DBUS_INTERFACE_LOCAL, "Disconnected")) { + log_debug("System D-Bus connection terminated."); + bus_done_system(m); + + } else if (m->running_as != SYSTEMD_SYSTEM && + dbus_message_is_signal(message, "org.freedesktop.systemd1.Agent", "Released")) { + + const char *cgroup; + + if (!dbus_message_get_args(message, &error, + DBUS_TYPE_STRING, &cgroup, + DBUS_TYPE_INVALID)) + log_error("Failed to parse Released message: %s", bus_error_message(&error)); + else + cgroup_notify_empty(m, cgroup); + } + + dbus_error_free(&error); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +static DBusHandlerResult private_bus_message_filter(DBusConnection *connection, DBusMessage *message, void *data) { + Manager *m = data; + DBusError error; + + assert(connection); + assert(message); + assert(m); + + dbus_error_init(&error); + + if (dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_METHOD_CALL || + dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_SIGNAL) + log_debug("Got D-Bus request: %s.%s() on %s", + dbus_message_get_interface(message), + dbus_message_get_member(message), + dbus_message_get_path(message)); + + if (dbus_message_is_signal(message, DBUS_INTERFACE_LOCAL, "Disconnected")) + shutdown_connection(m, connection); + else if (m->running_as == SYSTEMD_SYSTEM && + dbus_message_is_signal(message, "org.freedesktop.systemd1.Agent", "Released")) { + + const char *cgroup; + + if (!dbus_message_get_args(message, &error, + DBUS_TYPE_STRING, &cgroup, + DBUS_TYPE_INVALID)) + log_error("Failed to parse Released message: %s", bus_error_message(&error)); + else + cgroup_notify_empty(m, cgroup); + + /* Forward the message to the system bus, so that user + * instances are notified as well */ + + if (m->system_bus) + dbus_connection_send(m->system_bus, message, NULL); + } + + dbus_error_free(&error); + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +unsigned bus_dispatch(Manager *m) { + DBusConnection *c; + + assert(m); + + if (m->queued_message) { + /* If we cannot get rid of this message we won't + * dispatch any D-Bus messages, so that we won't end + * up wanting to queue another message. */ + + if (m->queued_message_connection) + if (!dbus_connection_send(m->queued_message_connection, m->queued_message, NULL)) + return 0; + + dbus_message_unref(m->queued_message); + m->queued_message = NULL; + m->queued_message_connection = NULL; + } + + if ((c = set_first(m->bus_connections_for_dispatch))) { + if (dbus_connection_dispatch(c) == DBUS_DISPATCH_COMPLETE) + set_move_one(m->bus_connections, m->bus_connections_for_dispatch, c); + + return 1; + } + + return 0; +} + +static void request_name_pending_cb(DBusPendingCall *pending, void *userdata) { + DBusMessage *reply; + DBusError error; + + dbus_error_init(&error); + + assert_se(reply = dbus_pending_call_steal_reply(pending)); + + switch (dbus_message_get_type(reply)) { + + case DBUS_MESSAGE_TYPE_ERROR: + + assert_se(dbus_set_error_from_message(&error, reply)); + log_warning("RequestName() failed: %s", bus_error_message(&error)); + break; + + case DBUS_MESSAGE_TYPE_METHOD_RETURN: { + uint32_t r; + + if (!dbus_message_get_args(reply, + &error, + DBUS_TYPE_UINT32, &r, + DBUS_TYPE_INVALID)) { + log_error("Failed to parse RequestName() reply: %s", bus_error_message(&error)); + break; + } + + if (r == 1) + log_debug("Successfully acquired name."); + else + log_error("Name already owned."); + + break; + } + + default: + assert_not_reached("Invalid reply message"); + } + + dbus_message_unref(reply); + dbus_error_free(&error); +} + +static int request_name(Manager *m) { + const char *name = "org.freedesktop.systemd1"; + /* 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 */ + uint32_t flags = DBUS_NAME_FLAG_ALLOW_REPLACEMENT|DBUS_NAME_FLAG_REPLACE_EXISTING; + DBusMessage *message = NULL; + DBusPendingCall *pending = NULL; + + if (!(message = dbus_message_new_method_call( + DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS, + "RequestName"))) + goto oom; + + if (!dbus_message_append_args( + message, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_UINT32, &flags, + DBUS_TYPE_INVALID)) + goto oom; + + if (!dbus_connection_send_with_reply(m->api_bus, message, &pending, -1)) + goto oom; + + if (!dbus_pending_call_set_notify(pending, request_name_pending_cb, m, NULL)) + goto oom; + + dbus_message_unref(message); + dbus_pending_call_unref(pending); + + /* We simple ask for the name and don't wait for it. Sooner or + * later we'll have it. */ + + return 0; + +oom: + if (pending) { + dbus_pending_call_cancel(pending); + dbus_pending_call_unref(pending); + } + + if (message) + dbus_message_unref(message); + + return -ENOMEM; +} + +static void query_name_list_pending_cb(DBusPendingCall *pending, void *userdata) { + DBusMessage *reply; + DBusError error; + Manager *m = userdata; + + assert(m); + + dbus_error_init(&error); + + assert_se(reply = dbus_pending_call_steal_reply(pending)); + + switch (dbus_message_get_type(reply)) { + + case DBUS_MESSAGE_TYPE_ERROR: + + assert_se(dbus_set_error_from_message(&error, reply)); + log_warning("ListNames() failed: %s", bus_error_message(&error)); + break; + + case DBUS_MESSAGE_TYPE_METHOD_RETURN: { + int r; + char **l; + + if ((r = bus_parse_strv(reply, &l)) < 0) + log_warning("Failed to parse ListNames() reply: %s", strerror(-r)); + else { + char **t; + + STRV_FOREACH(t, l) + /* This is a bit hacky, we say the + * owner of the name is the name + * itself, because we don't want the + * extra traffic to figure out the + * real owner. */ + manager_dispatch_bus_name_owner_changed(m, *t, NULL, *t); + + strv_free(l); + } + + break; + } + + default: + assert_not_reached("Invalid reply message"); + } + + dbus_message_unref(reply); + dbus_error_free(&error); +} + +static int query_name_list(Manager *m) { + DBusMessage *message = NULL; + DBusPendingCall *pending = NULL; + + /* Asks for the currently installed bus names */ + + if (!(message = dbus_message_new_method_call( + DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS, + "ListNames"))) + goto oom; + + if (!dbus_connection_send_with_reply(m->api_bus, message, &pending, -1)) + goto oom; + + if (!dbus_pending_call_set_notify(pending, query_name_list_pending_cb, m, NULL)) + goto oom; + + dbus_message_unref(message); + dbus_pending_call_unref(pending); + + /* We simple ask for the list and don't wait for it. Sooner or + * later we'll get it. */ + + return 0; + +oom: + if (pending) { + dbus_pending_call_cancel(pending); + dbus_pending_call_unref(pending); + } + + if (message) + dbus_message_unref(message); + + return -ENOMEM; +} + +static int bus_setup_loop(Manager *m, DBusConnection *bus) { + assert(m); + assert(bus); + + dbus_connection_set_exit_on_disconnect(bus, FALSE); + + if (!dbus_connection_set_watch_functions(bus, bus_add_watch, bus_remove_watch, bus_toggle_watch, m, NULL) || + !dbus_connection_set_timeout_functions(bus, bus_add_timeout, bus_remove_timeout, bus_toggle_timeout, m, NULL)) + return log_oom(); + + if (set_put(m->bus_connections_for_dispatch, bus) < 0) + return log_oom(); + + dbus_connection_set_dispatch_status_function(bus, bus_dispatch_status, m, NULL); + return 0; +} + +static dbus_bool_t allow_only_same_user(DBusConnection *connection, unsigned long uid, void *data) { + return uid == 0 || uid == geteuid(); +} + +static void bus_new_connection( + DBusServer *server, + DBusConnection *new_connection, + void *data) { + + Manager *m = data; + + assert(m); + + if (set_size(m->bus_connections) >= CONNECTIONS_MAX) { + log_error("Too many concurrent connections."); + return; + } + + dbus_connection_set_unix_user_function(new_connection, allow_only_same_user, NULL, NULL); + + if (bus_setup_loop(m, new_connection) < 0) + return; + + if (!dbus_connection_register_object_path(new_connection, "/org/freedesktop/systemd1", &bus_manager_vtable, m) || + !dbus_connection_register_fallback(new_connection, "/org/freedesktop/systemd1/unit", &bus_unit_vtable, m) || + !dbus_connection_register_fallback(new_connection, "/org/freedesktop/systemd1/job", &bus_job_vtable, m) || + !dbus_connection_add_filter(new_connection, private_bus_message_filter, m, NULL)) { + log_oom(); + return; + } + + log_debug("Accepted connection on private bus."); + + dbus_connection_ref(new_connection); +} + +static int init_registered_system_bus(Manager *m) { + char *id; + + if (!dbus_connection_add_filter(m->system_bus, system_bus_message_filter, m, NULL)) + return log_oom(); + + if (m->running_as != SYSTEMD_SYSTEM) { + DBusError error; + + dbus_error_init(&error); + + dbus_bus_add_match(m->system_bus, + "type='signal'," + "interface='org.freedesktop.systemd1.Agent'," + "member='Released'," + "path='/org/freedesktop/systemd1/agent'", + &error); + + if (dbus_error_is_set(&error)) { + log_error("Failed to register match: %s", bus_error_message(&error)); + dbus_error_free(&error); + return -1; + } + } + + log_debug("Successfully connected to system D-Bus bus %s as %s", + strnull((id = dbus_connection_get_server_id(m->system_bus))), + strnull(dbus_bus_get_unique_name(m->system_bus))); + dbus_free(id); + + return 0; +} + +static int init_registered_api_bus(Manager *m) { + int r; + + if (!dbus_connection_register_object_path(m->api_bus, "/org/freedesktop/systemd1", &bus_manager_vtable, m) || + !dbus_connection_register_fallback(m->api_bus, "/org/freedesktop/systemd1/unit", &bus_unit_vtable, m) || + !dbus_connection_register_fallback(m->api_bus, "/org/freedesktop/systemd1/job", &bus_job_vtable, m) || + !dbus_connection_add_filter(m->api_bus, api_bus_message_filter, m, NULL)) + return log_oom(); + + /* Get NameOwnerChange messages */ + dbus_bus_add_match(m->api_bus, + "type='signal'," + "sender='"DBUS_SERVICE_DBUS"'," + "interface='"DBUS_INTERFACE_DBUS"'," + "member='NameOwnerChanged'," + "path='"DBUS_PATH_DBUS"'", + NULL); + + /* Get activation requests */ + dbus_bus_add_match(m->api_bus, + "type='signal'," + "sender='"DBUS_SERVICE_DBUS"'," + "interface='org.freedesktop.systemd1.Activator'," + "member='ActivationRequest'," + "path='"DBUS_PATH_DBUS"'", + NULL); + + r = request_name(m); + if (r < 0) + return r; + + r = query_name_list(m); + if (r < 0) + return r; + + if (m->running_as == SYSTEMD_USER) { + char *id; + log_debug("Successfully connected to API D-Bus bus %s as %s", + strnull((id = dbus_connection_get_server_id(m->api_bus))), + strnull(dbus_bus_get_unique_name(m->api_bus))); + dbus_free(id); + } else + log_debug("Successfully initialized API on the system bus"); + + return 0; +} + +static void bus_register_cb(DBusPendingCall *pending, void *userdata) { + Manager *m = userdata; + DBusConnection **conn; + DBusMessage *reply; + DBusError error; + const char *name; + int r = 0; + + dbus_error_init(&error); + + conn = dbus_pending_call_get_data(pending, m->conn_data_slot); + assert(conn == &m->system_bus || conn == &m->api_bus); + + reply = dbus_pending_call_steal_reply(pending); + + switch (dbus_message_get_type(reply)) { + case DBUS_MESSAGE_TYPE_ERROR: + assert_se(dbus_set_error_from_message(&error, reply)); + log_warning("Failed to register to bus: %s", bus_error_message(&error)); + r = -1; + break; + case DBUS_MESSAGE_TYPE_METHOD_RETURN: + if (!dbus_message_get_args(reply, &error, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_INVALID)) { + log_error("Failed to parse Hello reply: %s", bus_error_message(&error)); + r = -1; + break; + } + + log_debug("Received name %s in reply to Hello", name); + if (!dbus_bus_set_unique_name(*conn, name)) { + log_error("Failed to set unique name"); + r = -1; + break; + } + + if (conn == &m->system_bus) { + r = init_registered_system_bus(m); + if (r == 0 && m->running_as == SYSTEMD_SYSTEM) + r = init_registered_api_bus(m); + } else + r = init_registered_api_bus(m); + + break; + default: + assert_not_reached("Invalid reply message"); + } + + dbus_message_unref(reply); + dbus_error_free(&error); + + if (r < 0) { + if (conn == &m->system_bus) { + log_debug("Failed setting up the system bus"); + bus_done_system(m); + } else { + log_debug("Failed setting up the API bus"); + bus_done_api(m); + } + } +} + +static int manager_bus_async_register(Manager *m, DBusConnection **conn) { + DBusMessage *message = NULL; + DBusPendingCall *pending = NULL; + + message = dbus_message_new_method_call(DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS, + "Hello"); + if (!message) + goto oom; + + if (!dbus_connection_send_with_reply(*conn, message, &pending, -1)) + goto oom; + + if (!dbus_pending_call_set_data(pending, m->conn_data_slot, conn, NULL)) + goto oom; + + if (!dbus_pending_call_set_notify(pending, bus_register_cb, m, NULL)) + goto oom; + + dbus_message_unref(message); + dbus_pending_call_unref(pending); + + return 0; +oom: + if (pending) { + dbus_pending_call_cancel(pending); + dbus_pending_call_unref(pending); + } + + if (message) + dbus_message_unref(message); + + return -ENOMEM; +} + +static DBusConnection* manager_bus_connect_private(Manager *m, DBusBusType type) { + const char *address; + DBusConnection *connection; + DBusError error; + + switch (type) { + case DBUS_BUS_SYSTEM: + address = secure_getenv("DBUS_SYSTEM_BUS_ADDRESS"); + if (!address || !address[0]) + address = DBUS_SYSTEM_BUS_DEFAULT_ADDRESS; + break; + case DBUS_BUS_SESSION: + address = secure_getenv("DBUS_SESSION_BUS_ADDRESS"); + if (!address || !address[0]) + address = DBUS_SESSION_BUS_DEFAULT_ADDRESS; + break; + default: + assert_not_reached("Invalid bus type"); + } + + dbus_error_init(&error); + + connection = dbus_connection_open_private(address, &error); + if (!connection) { + log_warning("Failed to open private bus connection: %s", bus_error_message(&error)); + goto fail; + } + + return connection; +fail: + if (connection) + dbus_connection_close(connection); + dbus_error_free(&error); + return NULL; +} + +static int bus_init_system(Manager *m) { + int r; + + if (m->system_bus) + return 0; + + m->system_bus = manager_bus_connect_private(m, DBUS_BUS_SYSTEM); + if (!m->system_bus) { + log_debug("Failed to connect to system D-Bus, retrying later"); + r = 0; + goto fail; + } + + r = bus_setup_loop(m, m->system_bus); + if (r < 0) + goto fail; + + r = manager_bus_async_register(m, &m->system_bus); + if (r < 0) + goto fail; + + return 0; +fail: + bus_done_system(m); + + return r; +} + +static int bus_init_api(Manager *m) { + int r; + + if (m->api_bus) + return 0; + + if (m->running_as == SYSTEMD_SYSTEM) { + m->api_bus = m->system_bus; + /* In this mode there is no distinct connection to the API bus, + * the API is published on the system bus. + * bus_register_cb() is aware of that and will init the API + * when the system bus gets registered. + * No need to setup anything here. */ + return 0; + } + + m->api_bus = manager_bus_connect_private(m, DBUS_BUS_SESSION); + if (!m->api_bus) { + log_debug("Failed to connect to API D-Bus, retrying later"); + r = 0; + goto fail; + } + + r = bus_setup_loop(m, m->api_bus); + if (r < 0) + goto fail; + + r = manager_bus_async_register(m, &m->api_bus); + if (r < 0) + goto fail; + + return 0; +fail: + bus_done_api(m); + + return r; +} + +static int bus_init_private(Manager *m) { + DBusError error; + int r; + const char *const external_only[] = { + "EXTERNAL", + NULL + }; + + assert(m); + + dbus_error_init(&error); + + if (m->private_bus) + return 0; + + if (m->running_as == SYSTEMD_SYSTEM) { + + /* We want the private bus only when running as init */ + if (getpid() != 1) + return 0; + + unlink("/run/systemd/private"); + m->private_bus = dbus_server_listen("unix:path=/run/systemd/private", &error); + } else { + const char *e; + char *p; + + e = secure_getenv("XDG_RUNTIME_DIR"); + if (!e) + return 0; + + if (asprintf(&p, "unix:path=%s/systemd/private", e) < 0) { + r = log_oom(); + goto fail; + } + + mkdir_parents_label(p+10, 0755); + unlink(p+10); + m->private_bus = dbus_server_listen(p, &error); + free(p); + } + + if (!m->private_bus) { + log_error("Failed to create private D-Bus server: %s", bus_error_message(&error)); + r = -EIO; + goto fail; + } + + if (!dbus_server_set_auth_mechanisms(m->private_bus, (const char**) external_only) || + !dbus_server_set_watch_functions(m->private_bus, bus_add_watch, bus_remove_watch, bus_toggle_watch, m, NULL) || + !dbus_server_set_timeout_functions(m->private_bus, bus_add_timeout, bus_remove_timeout, bus_toggle_timeout, m, NULL)) { + r = log_oom(); + goto fail; + } + + dbus_server_set_new_connection_function(m->private_bus, bus_new_connection, m, NULL); + + log_debug("Successfully created private D-Bus server."); + + return 0; + +fail: + bus_done_private(m); + dbus_error_free(&error); + + return r; +} + +int bus_init(Manager *m, bool try_bus_connect) { + int r; + + if (set_ensure_allocated(&m->bus_connections, trivial_hash_func, trivial_compare_func) < 0 || + set_ensure_allocated(&m->bus_connections_for_dispatch, trivial_hash_func, trivial_compare_func) < 0) + goto oom; + + if (m->name_data_slot < 0) + if (!dbus_pending_call_allocate_data_slot(&m->name_data_slot)) + goto oom; + + if (m->conn_data_slot < 0) + if (!dbus_pending_call_allocate_data_slot(&m->conn_data_slot)) + goto oom; + + if (m->subscribed_data_slot < 0) + if (!dbus_connection_allocate_data_slot(&m->subscribed_data_slot)) + goto oom; + + if (try_bus_connect) { + if ((r = bus_init_system(m)) < 0 || + (r = bus_init_api(m)) < 0) + return r; + } + + if ((r = bus_init_private(m)) < 0) + return r; + + return 0; +oom: + return log_oom(); +} + +static void shutdown_connection(Manager *m, DBusConnection *c) { + Set *s; + Job *j; + Iterator i; + + HASHMAP_FOREACH(j, m->jobs, i) { + JobBusClient *cl, *nextcl; + LIST_FOREACH_SAFE(client, cl, nextcl, j->bus_client_list) { + if (cl->bus == c) { + LIST_REMOVE(JobBusClient, client, j->bus_client_list, cl); + free(cl); + } + } + } + + set_remove(m->bus_connections, c); + set_remove(m->bus_connections_for_dispatch, c); + + if ((s = BUS_CONNECTION_SUBSCRIBED(m, c))) { + char *t; + + while ((t = set_steal_first(s))) + free(t); + + set_free(s); + } + + if (m->queued_message_connection == c) { + m->queued_message_connection = NULL; + + if (m->queued_message) { + dbus_message_unref(m->queued_message); + m->queued_message = NULL; + } + } + + dbus_connection_set_dispatch_status_function(c, NULL, NULL, NULL); + /* system manager cannot afford to block on DBus */ + if (m->running_as != SYSTEMD_SYSTEM) + dbus_connection_flush(c); + dbus_connection_close(c); + dbus_connection_unref(c); +} + +static void bus_done_api(Manager *m) { + if (!m->api_bus) + return; + + if (m->running_as == SYSTEMD_USER) + shutdown_connection(m, m->api_bus); + + m->api_bus = NULL; + + if (m->queued_message) { + dbus_message_unref(m->queued_message); + m->queued_message = NULL; + } +} + +static void bus_done_system(Manager *m) { + if (!m->system_bus) + return; + + if (m->running_as == SYSTEMD_SYSTEM) + bus_done_api(m); + + shutdown_connection(m, m->system_bus); + m->system_bus = NULL; +} + +static void bus_done_private(Manager *m) { + if (!m->private_bus) + return; + + dbus_server_disconnect(m->private_bus); + dbus_server_unref(m->private_bus); + m->private_bus = NULL; +} + +void bus_done(Manager *m) { + DBusConnection *c; + + bus_done_api(m); + bus_done_system(m); + bus_done_private(m); + + while ((c = set_steal_first(m->bus_connections))) + shutdown_connection(m, c); + + while ((c = set_steal_first(m->bus_connections_for_dispatch))) + shutdown_connection(m, c); + + set_free(m->bus_connections); + set_free(m->bus_connections_for_dispatch); + + if (m->name_data_slot >= 0) + dbus_pending_call_free_data_slot(&m->name_data_slot); + + if (m->conn_data_slot >= 0) + dbus_pending_call_free_data_slot(&m->conn_data_slot); + + if (m->subscribed_data_slot >= 0) + dbus_connection_free_data_slot(&m->subscribed_data_slot); +} + +static void query_pid_pending_cb(DBusPendingCall *pending, void *userdata) { + Manager *m = userdata; + DBusMessage *reply; + DBusError error; + const char *name; + + dbus_error_init(&error); + + assert_se(name = BUS_PENDING_CALL_NAME(m, pending)); + assert_se(reply = dbus_pending_call_steal_reply(pending)); + + switch (dbus_message_get_type(reply)) { + + case DBUS_MESSAGE_TYPE_ERROR: + + assert_se(dbus_set_error_from_message(&error, reply)); + log_warning("GetConnectionUnixProcessID() failed: %s", bus_error_message(&error)); + break; + + case DBUS_MESSAGE_TYPE_METHOD_RETURN: { + uint32_t r; + + if (!dbus_message_get_args(reply, + &error, + DBUS_TYPE_UINT32, &r, + DBUS_TYPE_INVALID)) { + log_error("Failed to parse GetConnectionUnixProcessID() reply: %s", bus_error_message(&error)); + break; + } + + manager_dispatch_bus_query_pid_done(m, name, (pid_t) r); + break; + } + + default: + assert_not_reached("Invalid reply message"); + } + + dbus_message_unref(reply); + dbus_error_free(&error); +} + +int bus_query_pid(Manager *m, const char *name) { + DBusMessage *message = NULL; + DBusPendingCall *pending = NULL; + char *n = NULL; + + assert(m); + assert(name); + + if (!(message = dbus_message_new_method_call( + DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS, + "GetConnectionUnixProcessID"))) + goto oom; + + if (!(dbus_message_append_args( + message, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_INVALID))) + goto oom; + + if (!dbus_connection_send_with_reply(m->api_bus, message, &pending, -1)) + goto oom; + + if (!(n = strdup(name))) + goto oom; + + if (!dbus_pending_call_set_data(pending, m->name_data_slot, n, free)) + goto oom; + + n = NULL; + + if (!dbus_pending_call_set_notify(pending, query_pid_pending_cb, m, NULL)) + goto oom; + + dbus_message_unref(message); + dbus_pending_call_unref(pending); + + return 0; + +oom: + free(n); + + if (pending) { + dbus_pending_call_cancel(pending); + dbus_pending_call_unref(pending); + } + + if (message) + dbus_message_unref(message); + + return -ENOMEM; +} + +int bus_broadcast(Manager *m, DBusMessage *message) { + bool oom = false; + Iterator i; + DBusConnection *c; + + assert(m); + assert(message); + + SET_FOREACH(c, m->bus_connections_for_dispatch, i) + if (c != m->system_bus || m->running_as == SYSTEMD_SYSTEM) + oom = !dbus_connection_send(c, message, NULL); + + SET_FOREACH(c, m->bus_connections, i) + if (c != m->system_bus || m->running_as == SYSTEMD_SYSTEM) + oom = !dbus_connection_send(c, message, NULL); + + return oom ? -ENOMEM : 0; +} + +bool bus_has_subscriber(Manager *m) { + Iterator i; + DBusConnection *c; + + assert(m); + + SET_FOREACH(c, m->bus_connections_for_dispatch, i) + if (bus_connection_has_subscriber(m, c)) + return true; + + SET_FOREACH(c, m->bus_connections, i) + if (bus_connection_has_subscriber(m, c)) + return true; + + return false; +} + +bool bus_connection_has_subscriber(Manager *m, DBusConnection *c) { + assert(m); + assert(c); + + return !set_isempty(BUS_CONNECTION_SUBSCRIBED(m, c)); +} + +int bus_fdset_add_all(Manager *m, FDSet *fds) { + Iterator i; + DBusConnection *c; + + assert(m); + assert(fds); + + /* When we are about to reexecute we add all D-Bus fds to the + * set to pass over to the newly executed systemd. They won't + * be used there however, except that they are closed at the + * very end of deserialization, those making it possible for + * clients to synchronously wait for systemd to reexec by + * simply waiting for disconnection */ + + SET_FOREACH(c, m->bus_connections_for_dispatch, i) { + int fd; + + if (dbus_connection_get_unix_fd(c, &fd)) { + fd = fdset_put_dup(fds, fd); + + if (fd < 0) + return fd; + } + } + + SET_FOREACH(c, m->bus_connections, i) { + int fd; + + if (dbus_connection_get_unix_fd(c, &fd)) { + fd = fdset_put_dup(fds, fd); + + if (fd < 0) + return fd; + } + } + + return 0; +} + +void bus_broadcast_finished( + Manager *m, + usec_t firmware_usec, + usec_t loader_usec, + usec_t kernel_usec, + usec_t initrd_usec, + usec_t userspace_usec, + usec_t total_usec) { + + DBusMessage *message; + + assert(m); + + message = dbus_message_new_signal("/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "StartupFinished"); + if (!message) { + log_oom(); + return; + } + + assert_cc(sizeof(usec_t) == sizeof(uint64_t)); + if (!dbus_message_append_args(message, + DBUS_TYPE_UINT64, &firmware_usec, + DBUS_TYPE_UINT64, &loader_usec, + DBUS_TYPE_UINT64, &kernel_usec, + DBUS_TYPE_UINT64, &initrd_usec, + DBUS_TYPE_UINT64, &userspace_usec, + DBUS_TYPE_UINT64, &total_usec, + DBUS_TYPE_INVALID)) { + log_oom(); + goto finish; + } + + + if (bus_broadcast(m, message) < 0) { + log_oom(); + goto finish; + } + +finish: + if (message) + dbus_message_unref(message); +} diff --git a/src/core/dbus.h b/src/core/dbus.h new file mode 100644 index 000000000..c7a058e19 --- /dev/null +++ b/src/core/dbus.h @@ -0,0 +1,50 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +#include + +#include "manager.h" + +int bus_init(Manager *m, bool try_bus_connect); +void bus_done(Manager *m); + +unsigned bus_dispatch(Manager *m); + +void bus_watch_event(Manager *m, Watch *w, int events); +void bus_timeout_event(Manager *m, Watch *w, int events); + +int bus_query_pid(Manager *m, const char *name); + +int bus_broadcast(Manager *m, DBusMessage *message); + +bool bus_has_subscriber(Manager *m); +bool bus_connection_has_subscriber(Manager *m, DBusConnection *c); + +int bus_fdset_add_all(Manager *m, FDSet *fds); + +void bus_broadcast_finished(Manager *m, usec_t firmware_usec, usec_t loader_usec, usec_t kernel_usec, usec_t initrd_usec, usec_t userspace_usec, usec_t total_usec); + +#define BUS_CONNECTION_SUBSCRIBED(m, c) dbus_connection_get_data((c), (m)->subscribed_data_slot) +#define BUS_PENDING_CALL_NAME(m, p) dbus_pending_call_get_data((p), (m)->name_data_slot) + +extern const char * const bus_interface_table[]; diff --git a/src/core/device.c b/src/core/device.c new file mode 100644 index 000000000..0b01718ad --- /dev/null +++ b/src/core/device.c @@ -0,0 +1,644 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include + +#include "unit.h" +#include "device.h" +#include "strv.h" +#include "log.h" +#include "unit-name.h" +#include "dbus-device.h" +#include "def.h" +#include "path-util.h" + +static const UnitActiveState state_translation_table[_DEVICE_STATE_MAX] = { + [DEVICE_DEAD] = UNIT_INACTIVE, + [DEVICE_PLUGGED] = UNIT_ACTIVE +}; + +static void device_unset_sysfs(Device *d) { + Device *first; + + assert(d); + + if (!d->sysfs) + return; + + /* Remove this unit from the chain of devices which share the + * same sysfs path. */ + first = hashmap_get(UNIT(d)->manager->devices_by_sysfs, d->sysfs); + LIST_REMOVE(Device, same_sysfs, first, d); + + if (first) + hashmap_remove_and_replace(UNIT(d)->manager->devices_by_sysfs, d->sysfs, first->sysfs, first); + else + hashmap_remove(UNIT(d)->manager->devices_by_sysfs, d->sysfs); + + free(d->sysfs); + d->sysfs = NULL; +} + +static void device_init(Unit *u) { + Device *d = DEVICE(u); + + assert(d); + assert(UNIT(d)->load_state == UNIT_STUB); + + /* In contrast to all other unit types we timeout jobs waiting + * for devices by default. This is because they otherwise wait + * indefinitely for plugged in devices, something which cannot + * happen for the other units since their operations time out + * anyway. */ + UNIT(d)->job_timeout = DEFAULT_TIMEOUT_USEC; + + UNIT(d)->ignore_on_isolate = true; + UNIT(d)->ignore_on_snapshot = true; +} + +static void device_done(Unit *u) { + Device *d = DEVICE(u); + + assert(d); + + device_unset_sysfs(d); +} + +static void device_set_state(Device *d, DeviceState state) { + DeviceState old_state; + assert(d); + + old_state = d->state; + d->state = state; + + if (state != old_state) + log_debug_unit(UNIT(d)->id, + "%s changed %s -> %s", UNIT(d)->id, + device_state_to_string(old_state), + device_state_to_string(state)); + + unit_notify(UNIT(d), state_translation_table[old_state], state_translation_table[state], true); +} + +static int device_coldplug(Unit *u) { + Device *d = DEVICE(u); + + assert(d); + assert(d->state == DEVICE_DEAD); + + if (d->sysfs) + device_set_state(d, DEVICE_PLUGGED); + + return 0; +} + +static void device_dump(Unit *u, FILE *f, const char *prefix) { + Device *d = DEVICE(u); + + assert(d); + + fprintf(f, + "%sDevice State: %s\n" + "%sSysfs Path: %s\n", + prefix, device_state_to_string(d->state), + prefix, strna(d->sysfs)); +} + +static UnitActiveState device_active_state(Unit *u) { + assert(u); + + return state_translation_table[DEVICE(u)->state]; +} + +static const char *device_sub_state_to_string(Unit *u) { + assert(u); + + return device_state_to_string(DEVICE(u)->state); +} + +static int device_add_escaped_name(Unit *u, const char *dn) { + char *e; + int r; + + assert(u); + assert(dn); + assert(dn[0] == '/'); + + e = unit_name_from_path(dn, ".device"); + if (!e) + return -ENOMEM; + + r = unit_add_name(u, e); + free(e); + + if (r < 0 && r != -EEXIST) + return r; + + return 0; +} + +static int device_find_escape_name(Manager *m, const char *dn, Unit **_u) { + char *e; + Unit *u; + + assert(m); + assert(dn); + assert(dn[0] == '/'); + assert(_u); + + e = unit_name_from_path(dn, ".device"); + if (!e) + return -ENOMEM; + + u = manager_get_unit(m, e); + free(e); + + if (u) { + *_u = u; + return 1; + } + + return 0; +} + +static int device_update_unit(Manager *m, struct udev_device *dev, const char *path, bool main) { + const char *sysfs, *model; + Unit *u = NULL; + int r; + bool delete; + + assert(m); + + if (!(sysfs = udev_device_get_syspath(dev))) + return -ENOMEM; + + if ((r = device_find_escape_name(m, path, &u)) < 0) + return r; + + if (u && DEVICE(u)->sysfs && !path_equal(DEVICE(u)->sysfs, sysfs)) + return -EEXIST; + + if (!u) { + delete = true; + + u = unit_new(m, sizeof(Device)); + if (!u) + return -ENOMEM; + + r = device_add_escaped_name(u, path); + if (r < 0) + goto fail; + + unit_add_to_load_queue(u); + } else + delete = false; + + /* If this was created via some dependency and has not + * actually been seen yet ->sysfs will not be + * initialized. Hence initialize it if necessary. */ + + if (!DEVICE(u)->sysfs) { + Device *first; + + if (!(DEVICE(u)->sysfs = strdup(sysfs))) { + r = -ENOMEM; + goto fail; + } + + if (!m->devices_by_sysfs) + if (!(m->devices_by_sysfs = hashmap_new(string_hash_func, string_compare_func))) { + r = -ENOMEM; + goto fail; + } + + first = hashmap_get(m->devices_by_sysfs, sysfs); + LIST_PREPEND(Device, same_sysfs, first, DEVICE(u)); + + if ((r = hashmap_replace(m->devices_by_sysfs, DEVICE(u)->sysfs, first)) < 0) + goto fail; + } + + if ((model = udev_device_get_property_value(dev, "ID_MODEL_FROM_DATABASE")) || + (model = udev_device_get_property_value(dev, "ID_MODEL"))) { + if ((r = unit_set_description(u, model)) < 0) + goto fail; + } else + if ((r = unit_set_description(u, path)) < 0) + goto fail; + + if (main) { + /* The additional systemd udev properties we only + * interpret for the main object */ + const char *wants, *alias; + + alias = udev_device_get_property_value(dev, "SYSTEMD_ALIAS"); + if (alias) { + char *state, *w; + size_t l; + + FOREACH_WORD_QUOTED(w, l, alias, state) { + char *e; + + e = strndup(w, l); + if (!e) { + r = -ENOMEM; + goto fail; + } + + if (!is_path(e)) { + log_warning("SYSTEMD_ALIAS for %s is not a path, ignoring: %s", sysfs, e); + free(e); + } else { + device_update_unit(m, dev, e, false); + free(e); + } + } + } + + wants = udev_device_get_property_value(dev, "SYSTEMD_WANTS"); + if (wants) { + char *state, *w; + size_t l; + + FOREACH_WORD_QUOTED(w, l, wants, state) { + char *e; + + e = strndup(w, l); + if (!e) { + r = -ENOMEM; + goto fail; + } + + r = unit_add_dependency_by_name(u, UNIT_WANTS, e, NULL, true); + free(e); + if (r < 0) + goto fail; + } + } + } + + unit_add_to_dbus_queue(u); + return 0; + +fail: + log_warning("Failed to load device unit: %s", strerror(-r)); + + if (delete && u) + unit_free(u); + + return r; +} + +static int device_process_new_device(Manager *m, struct udev_device *dev, bool update_state) { + const char *sysfs, *dn; + struct udev_list_entry *item = NULL, *first = NULL; + + assert(m); + + if (!(sysfs = udev_device_get_syspath(dev))) + return -ENOMEM; + + /* Add the main unit named after the sysfs path */ + device_update_unit(m, dev, sysfs, true); + + /* Add an additional unit for the device node */ + if ((dn = udev_device_get_devnode(dev))) + device_update_unit(m, dev, dn, false); + + /* Add additional units for all symlinks */ + first = udev_device_get_devlinks_list_entry(dev); + udev_list_entry_foreach(item, first) { + const char *p; + struct stat st; + + /* Don't bother with the /dev/block links */ + p = udev_list_entry_get_name(item); + + if (path_startswith(p, "/dev/block/") || + path_startswith(p, "/dev/char/")) + continue; + + /* Verify that the symlink in the FS actually belongs + * to this device. This is useful to deal with + * conflicting devices, e.g. when two disks want the + * same /dev/disk/by-label/xxx link because they have + * the same label. We want to make sure that the same + * device that won the symlink wins in systemd, so we + * check the device node major/minor*/ + if (stat(p, &st) >= 0) + if ((!S_ISBLK(st.st_mode) && !S_ISCHR(st.st_mode)) || + st.st_rdev != udev_device_get_devnum(dev)) + continue; + + device_update_unit(m, dev, p, false); + } + + if (update_state) { + Device *d, *l; + + manager_dispatch_load_queue(m); + + l = hashmap_get(m->devices_by_sysfs, sysfs); + LIST_FOREACH(same_sysfs, d, l) + device_set_state(d, DEVICE_PLUGGED); + } + + return 0; +} + +static int device_process_path(Manager *m, const char *path, bool update_state) { + int r; + struct udev_device *dev; + + assert(m); + assert(path); + + if (!(dev = udev_device_new_from_syspath(m->udev, path))) { + log_warning("Failed to get udev device object from udev for path %s.", path); + return -ENOMEM; + } + + r = device_process_new_device(m, dev, update_state); + udev_device_unref(dev); + return r; +} + +static int device_process_removed_device(Manager *m, struct udev_device *dev) { + const char *sysfs; + Device *d; + + assert(m); + assert(dev); + + if (!(sysfs = udev_device_get_syspath(dev))) + return -ENOMEM; + + /* Remove all units of this sysfs path */ + while ((d = hashmap_get(m->devices_by_sysfs, sysfs))) { + device_unset_sysfs(d); + device_set_state(d, DEVICE_DEAD); + } + + return 0; +} + +static Unit *device_following(Unit *u) { + Device *d = DEVICE(u); + Device *other, *first = NULL; + + assert(d); + + if (startswith(u->id, "sys-")) + return NULL; + + /* Make everybody follow the unit that's named after the sysfs path */ + for (other = d->same_sysfs_next; other; other = other->same_sysfs_next) + if (startswith(UNIT(other)->id, "sys-")) + return UNIT(other); + + for (other = d->same_sysfs_prev; other; other = other->same_sysfs_prev) { + if (startswith(UNIT(other)->id, "sys-")) + return UNIT(other); + + first = other; + } + + return UNIT(first); +} + +static int device_following_set(Unit *u, Set **_s) { + Device *d = DEVICE(u); + Device *other; + Set *s; + int r; + + assert(d); + assert(_s); + + if (!d->same_sysfs_prev && !d->same_sysfs_next) { + *_s = NULL; + return 0; + } + + if (!(s = set_new(NULL, NULL))) + return -ENOMEM; + + for (other = d->same_sysfs_next; other; other = other->same_sysfs_next) + if ((r = set_put(s, other)) < 0) + goto fail; + + for (other = d->same_sysfs_prev; other; other = other->same_sysfs_prev) + if ((r = set_put(s, other)) < 0) + goto fail; + + *_s = s; + return 1; + +fail: + set_free(s); + return r; +} + +static void device_shutdown(Manager *m) { + assert(m); + + if (m->udev_monitor) { + udev_monitor_unref(m->udev_monitor); + m->udev_monitor = NULL; + } + + if (m->udev) { + udev_unref(m->udev); + m->udev = NULL; + } + + hashmap_free(m->devices_by_sysfs); + m->devices_by_sysfs = NULL; +} + +static int device_enumerate(Manager *m) { + struct epoll_event ev; + int r; + struct udev_enumerate *e = NULL; + struct udev_list_entry *item = NULL, *first = NULL; + + assert(m); + + if (!m->udev) { + if (!(m->udev = udev_new())) + return -ENOMEM; + + if (!(m->udev_monitor = udev_monitor_new_from_netlink(m->udev, "udev"))) { + r = -ENOMEM; + goto fail; + } + + /* This will fail if we are unprivileged, but that + * should not matter much, as user instances won't run + * during boot. */ + udev_monitor_set_receive_buffer_size(m->udev_monitor, 128*1024*1024); + + if (udev_monitor_filter_add_match_tag(m->udev_monitor, "systemd") < 0) { + r = -ENOMEM; + goto fail; + } + + if (udev_monitor_enable_receiving(m->udev_monitor) < 0) { + r = -EIO; + goto fail; + } + + m->udev_watch.type = WATCH_UDEV; + m->udev_watch.fd = udev_monitor_get_fd(m->udev_monitor); + + zero(ev); + ev.events = EPOLLIN; + ev.data.ptr = &m->udev_watch; + + if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->udev_watch.fd, &ev) < 0) + return -errno; + } + + if (!(e = udev_enumerate_new(m->udev))) { + r = -ENOMEM; + goto fail; + } + if (udev_enumerate_add_match_tag(e, "systemd") < 0) { + r = -EIO; + goto fail; + } + + if (udev_enumerate_scan_devices(e) < 0) { + r = -EIO; + goto fail; + } + + first = udev_enumerate_get_list_entry(e); + udev_list_entry_foreach(item, first) + device_process_path(m, udev_list_entry_get_name(item), false); + + udev_enumerate_unref(e); + return 0; + +fail: + if (e) + udev_enumerate_unref(e); + + device_shutdown(m); + return r; +} + +void device_fd_event(Manager *m, int events) { + struct udev_device *dev; + int r; + const char *action, *ready; + + assert(m); + + if (events != EPOLLIN) { + static RATELIMIT_DEFINE(limit, 10*USEC_PER_SEC, 5); + + if (!ratelimit_test(&limit)) + log_error("Failed to get udev event: %m"); + if (!(events & EPOLLIN)) + return; + } + + if (!(dev = udev_monitor_receive_device(m->udev_monitor))) { + /* + * libudev might filter-out devices which pass the bloom filter, + * so getting NULL here is not necessarily an error + */ + return; + } + + if (!(action = udev_device_get_action(dev))) { + log_error("Failed to get udev action string."); + goto fail; + } + + ready = udev_device_get_property_value(dev, "SYSTEMD_READY"); + + if (streq(action, "remove") || (ready && parse_boolean(ready) == 0)) { + if ((r = device_process_removed_device(m, dev)) < 0) { + log_error("Failed to process udev device event: %s", strerror(-r)); + goto fail; + } + } else { + if ((r = device_process_new_device(m, dev, true)) < 0) { + log_error("Failed to process udev device event: %s", strerror(-r)); + goto fail; + } + } + +fail: + udev_device_unref(dev); +} + +static const char* const device_state_table[_DEVICE_STATE_MAX] = { + [DEVICE_DEAD] = "dead", + [DEVICE_PLUGGED] = "plugged" +}; + +DEFINE_STRING_TABLE_LOOKUP(device_state, DeviceState); + +const UnitVTable device_vtable = { + .object_size = sizeof(Device), + .sections = + "Unit\0" + "Device\0" + "Install\0", + + .no_instances = true, + + .init = device_init, + + .load = unit_load_fragment_and_dropin_optional, + .done = device_done, + .coldplug = device_coldplug, + + .dump = device_dump, + + .active_state = device_active_state, + .sub_state_to_string = device_sub_state_to_string, + + .bus_interface = "org.freedesktop.systemd1.Device", + .bus_message_handler = bus_device_message_handler, + .bus_invalidating_properties = bus_device_invalidating_properties, + + .following = device_following, + .following_set = device_following_set, + + .enumerate = device_enumerate, + .shutdown = device_shutdown, + + .status_message_formats = { + .starting_stopping = { + [0] = "Expecting device %s...", + }, + .finished_start_job = { + [JOB_DONE] = "Found device %s.", + [JOB_TIMEOUT] = "Timed out waiting for device %s.", + }, + }, +}; diff --git a/src/core/device.h b/src/core/device.h new file mode 100644 index 000000000..3c4604f60 --- /dev/null +++ b/src/core/device.h @@ -0,0 +1,56 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +typedef struct Device Device; + +#include "unit.h" + +/* We simply watch devices, we cannot plug/unplug them. That + * simplifies the state engine greatly */ +typedef enum DeviceState { + DEVICE_DEAD, + DEVICE_PLUGGED, + _DEVICE_STATE_MAX, + _DEVICE_STATE_INVALID = -1 +} DeviceState; + +struct Device { + Unit meta; + + char *sysfs; + + /* In order to be able to distinguish dependencies on + different device nodes we might end up creating multiple + devices for the same sysfs path. We chain them up here. */ + + LIST_FIELDS(struct Device, same_sysfs); + + DeviceState state; +}; + +extern const UnitVTable device_vtable; + +void device_fd_event(Manager *m, int events); + +const char* device_state_to_string(DeviceState i); +DeviceState device_state_from_string(const char *s); diff --git a/src/core/execute.c b/src/core/execute.c new file mode 100644 index 000000000..7dc15044b --- /dev/null +++ b/src/core/execute.c @@ -0,0 +1,2160 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_PAM +#include +#endif + +#include "execute.h" +#include "strv.h" +#include "macro.h" +#include "capability.h" +#include "util.h" +#include "log.h" +#include "sd-messages.h" +#include "ioprio.h" +#include "securebits.h" +#include "cgroup.h" +#include "namespace.h" +#include "tcpwrap.h" +#include "exit-status.h" +#include "missing.h" +#include "utmp-wtmp.h" +#include "def.h" +#include "loopback-setup.h" +#include "path-util.h" +#include "syscall-list.h" + +#define IDLE_TIMEOUT_USEC (5*USEC_PER_SEC) + +/* This assumes there is a 'tty' group */ +#define TTY_MODE 0620 + +static int shift_fds(int fds[], unsigned n_fds) { + int start, restart_from; + + if (n_fds <= 0) + return 0; + + /* Modifies the fds array! (sorts it) */ + + assert(fds); + + start = 0; + for (;;) { + int i; + + restart_from = -1; + + for (i = start; i < (int) n_fds; i++) { + int nfd; + + /* Already at right index? */ + if (fds[i] == i+3) + continue; + + if ((nfd = fcntl(fds[i], F_DUPFD, i+3)) < 0) + return -errno; + + close_nointr_nofail(fds[i]); + fds[i] = nfd; + + /* Hmm, the fd we wanted isn't free? Then + * let's remember that and try again from here*/ + if (nfd != i+3 && restart_from < 0) + restart_from = i; + } + + if (restart_from < 0) + break; + + start = restart_from; + } + + return 0; +} + +static int flags_fds(const int fds[], unsigned n_fds, bool nonblock) { + unsigned i; + int r; + + if (n_fds <= 0) + return 0; + + assert(fds); + + /* Drops/Sets O_NONBLOCK and FD_CLOEXEC from the file flags */ + + for (i = 0; i < n_fds; i++) { + + if ((r = fd_nonblock(fds[i], nonblock)) < 0) + return r; + + /* We unconditionally drop FD_CLOEXEC from the fds, + * since after all we want to pass these fds to our + * children */ + + if ((r = fd_cloexec(fds[i], false)) < 0) + return r; + } + + return 0; +} + +static const char *tty_path(const ExecContext *context) { + assert(context); + + if (context->tty_path) + return context->tty_path; + + return "/dev/console"; +} + +void exec_context_tty_reset(const ExecContext *context) { + assert(context); + + if (context->tty_vhangup) + terminal_vhangup(tty_path(context)); + + if (context->tty_reset) + reset_terminal(tty_path(context)); + + if (context->tty_vt_disallocate && context->tty_path) + vt_disallocate(context->tty_path); +} + +static int open_null_as(int flags, int nfd) { + int fd, r; + + assert(nfd >= 0); + + if ((fd = open("/dev/null", flags|O_NOCTTY)) < 0) + return -errno; + + if (fd != nfd) { + r = dup2(fd, nfd) < 0 ? -errno : nfd; + close_nointr_nofail(fd); + } else + r = nfd; + + return r; +} + +static int connect_logger_as(const ExecContext *context, ExecOutput output, const char *ident, const char *unit_id, int nfd) { + int fd, r; + union sockaddr_union sa; + + assert(context); + assert(output < _EXEC_OUTPUT_MAX); + assert(ident); + assert(nfd >= 0); + + fd = socket(AF_UNIX, SOCK_STREAM, 0); + if (fd < 0) + return -errno; + + zero(sa); + sa.un.sun_family = AF_UNIX; + strncpy(sa.un.sun_path, "/run/systemd/journal/stdout", sizeof(sa.un.sun_path)); + + r = connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)); + if (r < 0) { + close_nointr_nofail(fd); + return -errno; + } + + if (shutdown(fd, SHUT_RD) < 0) { + close_nointr_nofail(fd); + return -errno; + } + + dprintf(fd, + "%s\n" + "%s\n" + "%i\n" + "%i\n" + "%i\n" + "%i\n" + "%i\n", + context->syslog_identifier ? context->syslog_identifier : ident, + unit_id, + context->syslog_priority, + !!context->syslog_level_prefix, + output == EXEC_OUTPUT_SYSLOG || output == EXEC_OUTPUT_SYSLOG_AND_CONSOLE, + output == EXEC_OUTPUT_KMSG || output == EXEC_OUTPUT_KMSG_AND_CONSOLE, + output == EXEC_OUTPUT_SYSLOG_AND_CONSOLE || output == EXEC_OUTPUT_KMSG_AND_CONSOLE || output == EXEC_OUTPUT_JOURNAL_AND_CONSOLE); + + if (fd != nfd) { + r = dup2(fd, nfd) < 0 ? -errno : nfd; + close_nointr_nofail(fd); + } else + r = nfd; + + return r; +} +static int open_terminal_as(const char *path, mode_t mode, int nfd) { + int fd, r; + + assert(path); + assert(nfd >= 0); + + if ((fd = open_terminal(path, mode | O_NOCTTY)) < 0) + return fd; + + if (fd != nfd) { + r = dup2(fd, nfd) < 0 ? -errno : nfd; + close_nointr_nofail(fd); + } else + r = nfd; + + return r; +} + +static bool is_terminal_input(ExecInput i) { + return + i == EXEC_INPUT_TTY || + i == EXEC_INPUT_TTY_FORCE || + i == EXEC_INPUT_TTY_FAIL; +} + +static int fixup_input(ExecInput std_input, int socket_fd, bool apply_tty_stdin) { + + if (is_terminal_input(std_input) && !apply_tty_stdin) + return EXEC_INPUT_NULL; + + if (std_input == EXEC_INPUT_SOCKET && socket_fd < 0) + return EXEC_INPUT_NULL; + + return std_input; +} + +static int fixup_output(ExecOutput std_output, int socket_fd) { + + if (std_output == EXEC_OUTPUT_SOCKET && socket_fd < 0) + return EXEC_OUTPUT_INHERIT; + + return std_output; +} + +static int setup_input(const ExecContext *context, int socket_fd, bool apply_tty_stdin) { + ExecInput i; + + assert(context); + + i = fixup_input(context->std_input, socket_fd, apply_tty_stdin); + + switch (i) { + + case EXEC_INPUT_NULL: + return open_null_as(O_RDONLY, STDIN_FILENO); + + case EXEC_INPUT_TTY: + case EXEC_INPUT_TTY_FORCE: + case EXEC_INPUT_TTY_FAIL: { + int fd, r; + + if ((fd = acquire_terminal( + tty_path(context), + i == EXEC_INPUT_TTY_FAIL, + i == EXEC_INPUT_TTY_FORCE, + false, + (usec_t) -1)) < 0) + return fd; + + if (fd != STDIN_FILENO) { + r = dup2(fd, STDIN_FILENO) < 0 ? -errno : STDIN_FILENO; + close_nointr_nofail(fd); + } else + r = STDIN_FILENO; + + return r; + } + + case EXEC_INPUT_SOCKET: + return dup2(socket_fd, STDIN_FILENO) < 0 ? -errno : STDIN_FILENO; + + default: + assert_not_reached("Unknown input type"); + } +} + +static int setup_output(const ExecContext *context, int socket_fd, const char *ident, const char *unit_id, bool apply_tty_stdin) { + ExecOutput o; + ExecInput i; + + assert(context); + assert(ident); + + i = fixup_input(context->std_input, socket_fd, apply_tty_stdin); + o = fixup_output(context->std_output, socket_fd); + + /* This expects the input is already set up */ + + switch (o) { + + case EXEC_OUTPUT_INHERIT: + + /* If input got downgraded, inherit the original value */ + if (i == EXEC_INPUT_NULL && is_terminal_input(context->std_input)) + return open_terminal_as(tty_path(context), O_WRONLY, STDOUT_FILENO); + + /* If the input is connected to anything that's not a /dev/null, inherit that... */ + if (i != EXEC_INPUT_NULL) + return dup2(STDIN_FILENO, STDOUT_FILENO) < 0 ? -errno : STDOUT_FILENO; + + /* If we are not started from PID 1 we just inherit STDOUT from our parent process. */ + if (getppid() != 1) + return STDOUT_FILENO; + + /* We need to open /dev/null here anew, to get the + * right access mode. So we fall through */ + + case EXEC_OUTPUT_NULL: + return open_null_as(O_WRONLY, STDOUT_FILENO); + + case EXEC_OUTPUT_TTY: + if (is_terminal_input(i)) + return dup2(STDIN_FILENO, STDOUT_FILENO) < 0 ? -errno : STDOUT_FILENO; + + /* We don't reset the terminal if this is just about output */ + return open_terminal_as(tty_path(context), O_WRONLY, STDOUT_FILENO); + + case EXEC_OUTPUT_SYSLOG: + case EXEC_OUTPUT_SYSLOG_AND_CONSOLE: + case EXEC_OUTPUT_KMSG: + case EXEC_OUTPUT_KMSG_AND_CONSOLE: + case EXEC_OUTPUT_JOURNAL: + case EXEC_OUTPUT_JOURNAL_AND_CONSOLE: + return connect_logger_as(context, o, ident, unit_id, STDOUT_FILENO); + + case EXEC_OUTPUT_SOCKET: + assert(socket_fd >= 0); + return dup2(socket_fd, STDOUT_FILENO) < 0 ? -errno : STDOUT_FILENO; + + default: + assert_not_reached("Unknown output type"); + } +} + +static int setup_error(const ExecContext *context, int socket_fd, const char *ident, const char *unit_id, bool apply_tty_stdin) { + ExecOutput o, e; + ExecInput i; + + assert(context); + assert(ident); + + i = fixup_input(context->std_input, socket_fd, apply_tty_stdin); + o = fixup_output(context->std_output, socket_fd); + e = fixup_output(context->std_error, socket_fd); + + /* This expects the input and output are already set up */ + + /* Don't change the stderr file descriptor if we inherit all + * the way and are not on a tty */ + if (e == EXEC_OUTPUT_INHERIT && + o == EXEC_OUTPUT_INHERIT && + i == EXEC_INPUT_NULL && + !is_terminal_input(context->std_input) && + getppid () != 1) + return STDERR_FILENO; + + /* Duplicate from stdout if possible */ + if (e == o || e == EXEC_OUTPUT_INHERIT) + return dup2(STDOUT_FILENO, STDERR_FILENO) < 0 ? -errno : STDERR_FILENO; + + switch (e) { + + case EXEC_OUTPUT_NULL: + return open_null_as(O_WRONLY, STDERR_FILENO); + + case EXEC_OUTPUT_TTY: + if (is_terminal_input(i)) + return dup2(STDIN_FILENO, STDERR_FILENO) < 0 ? -errno : STDERR_FILENO; + + /* We don't reset the terminal if this is just about output */ + return open_terminal_as(tty_path(context), O_WRONLY, STDERR_FILENO); + + case EXEC_OUTPUT_SYSLOG: + case EXEC_OUTPUT_SYSLOG_AND_CONSOLE: + case EXEC_OUTPUT_KMSG: + case EXEC_OUTPUT_KMSG_AND_CONSOLE: + case EXEC_OUTPUT_JOURNAL: + case EXEC_OUTPUT_JOURNAL_AND_CONSOLE: + return connect_logger_as(context, e, ident, unit_id, STDERR_FILENO); + + case EXEC_OUTPUT_SOCKET: + assert(socket_fd >= 0); + return dup2(socket_fd, STDERR_FILENO) < 0 ? -errno : STDERR_FILENO; + + default: + assert_not_reached("Unknown error type"); + } +} + +static int chown_terminal(int fd, uid_t uid) { + struct stat st; + + assert(fd >= 0); + + /* This might fail. What matters are the results. */ + (void) fchown(fd, uid, -1); + (void) fchmod(fd, TTY_MODE); + + if (fstat(fd, &st) < 0) + return -errno; + + if (st.st_uid != uid || (st.st_mode & 0777) != TTY_MODE) + return -EPERM; + + return 0; +} + +static int setup_confirm_stdio(int *_saved_stdin, + int *_saved_stdout) { + int fd = -1, saved_stdin, saved_stdout = -1, r; + + assert(_saved_stdin); + assert(_saved_stdout); + + saved_stdin = fcntl(STDIN_FILENO, F_DUPFD, 3); + if (saved_stdin < 0) + return -errno; + + saved_stdout = fcntl(STDOUT_FILENO, F_DUPFD, 3); + if (saved_stdout < 0) { + r = errno; + goto fail; + } + + fd = acquire_terminal( + "/dev/console", + false, + false, + false, + DEFAULT_CONFIRM_USEC); + if (fd < 0) { + r = fd; + goto fail; + } + + r = chown_terminal(fd, getuid()); + if (r < 0) + goto fail; + + if (dup2(fd, STDIN_FILENO) < 0) { + r = -errno; + goto fail; + } + + if (dup2(fd, STDOUT_FILENO) < 0) { + r = -errno; + goto fail; + } + + if (fd >= 2) + close_nointr_nofail(fd); + + *_saved_stdin = saved_stdin; + *_saved_stdout = saved_stdout; + + return 0; + +fail: + if (saved_stdout >= 0) + close_nointr_nofail(saved_stdout); + + if (saved_stdin >= 0) + close_nointr_nofail(saved_stdin); + + if (fd >= 0) + close_nointr_nofail(fd); + + return r; +} + +static int write_confirm_message(const char *format, ...) { + int fd; + va_list ap; + + assert(format); + + fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC); + if (fd < 0) + return fd; + + va_start(ap, format); + vdprintf(fd, format, ap); + va_end(ap); + + close_nointr_nofail(fd); + + return 0; +} + +static int restore_confirm_stdio(int *saved_stdin, + int *saved_stdout) { + + int r = 0; + + assert(saved_stdin); + assert(saved_stdout); + + release_terminal(); + + if (*saved_stdin >= 0) + if (dup2(*saved_stdin, STDIN_FILENO) < 0) + r = -errno; + + if (*saved_stdout >= 0) + if (dup2(*saved_stdout, STDOUT_FILENO) < 0) + r = -errno; + + if (*saved_stdin >= 0) + close_nointr_nofail(*saved_stdin); + + if (*saved_stdout >= 0) + close_nointr_nofail(*saved_stdout); + + return r; +} + +static int ask_for_confirmation(char *response, char **argv) { + int saved_stdout = -1, saved_stdin = -1, r; + char *line; + + r = setup_confirm_stdio(&saved_stdin, &saved_stdout); + if (r < 0) + return r; + + line = exec_command_line(argv); + if (!line) + return -ENOMEM; + + r = ask(response, "yns", "Execute %s? [Yes, No, Skip] ", line); + free(line); + + restore_confirm_stdio(&saved_stdin, &saved_stdout); + + return r; +} + +static int enforce_groups(const ExecContext *context, const char *username, gid_t gid) { + bool keep_groups = false; + int r; + + assert(context); + + /* Lookup and set GID and supplementary group list. Here too + * we avoid NSS lookups for gid=0. */ + + if (context->group || username) { + + if (context->group) { + const char *g = context->group; + + if ((r = get_group_creds(&g, &gid)) < 0) + return r; + } + + /* First step, initialize groups from /etc/groups */ + if (username && gid != 0) { + if (initgroups(username, gid) < 0) + return -errno; + + keep_groups = true; + } + + /* Second step, set our gids */ + if (setresgid(gid, gid, gid) < 0) + return -errno; + } + + if (context->supplementary_groups) { + int ngroups_max, k; + gid_t *gids; + char **i; + + /* Final step, initialize any manually set supplementary groups */ + assert_se((ngroups_max = (int) sysconf(_SC_NGROUPS_MAX)) > 0); + + if (!(gids = new(gid_t, ngroups_max))) + return -ENOMEM; + + if (keep_groups) { + if ((k = getgroups(ngroups_max, gids)) < 0) { + free(gids); + return -errno; + } + } else + k = 0; + + STRV_FOREACH(i, context->supplementary_groups) { + const char *g; + + if (k >= ngroups_max) { + free(gids); + return -E2BIG; + } + + g = *i; + r = get_group_creds(&g, gids+k); + if (r < 0) { + free(gids); + return r; + } + + k++; + } + + if (setgroups(k, gids) < 0) { + free(gids); + return -errno; + } + + free(gids); + } + + return 0; +} + +static int enforce_user(const ExecContext *context, uid_t uid) { + int r; + assert(context); + + /* Sets (but doesn't lookup) the uid and make sure we keep the + * capabilities while doing so. */ + + if (context->capabilities) { + cap_t d; + static const cap_value_t bits[] = { + CAP_SETUID, /* Necessary so that we can run setresuid() below */ + CAP_SETPCAP /* Necessary so that we can set PR_SET_SECUREBITS later on */ + }; + + /* First step: If we need to keep capabilities but + * drop privileges we need to make sure we keep our + * caps, whiel we drop privileges. */ + if (uid != 0) { + int sb = context->secure_bits|SECURE_KEEP_CAPS; + + if (prctl(PR_GET_SECUREBITS) != sb) + if (prctl(PR_SET_SECUREBITS, sb) < 0) + return -errno; + } + + /* Second step: set the capabilities. This will reduce + * the capabilities to the minimum we need. */ + + if (!(d = cap_dup(context->capabilities))) + return -errno; + + if (cap_set_flag(d, CAP_EFFECTIVE, ELEMENTSOF(bits), bits, CAP_SET) < 0 || + cap_set_flag(d, CAP_PERMITTED, ELEMENTSOF(bits), bits, CAP_SET) < 0) { + r = -errno; + cap_free(d); + return r; + } + + if (cap_set_proc(d) < 0) { + r = -errno; + cap_free(d); + return r; + } + + cap_free(d); + } + + /* Third step: actually set the uids */ + if (setresuid(uid, uid, uid) < 0) + return -errno; + + /* At this point we should have all necessary capabilities but + are otherwise a normal user. However, the caps might got + corrupted due to the setresuid() so we need clean them up + later. This is done outside of this call. */ + + return 0; +} + +#ifdef HAVE_PAM + +static int null_conv( + int num_msg, + const struct pam_message **msg, + struct pam_response **resp, + void *appdata_ptr) { + + /* We don't support conversations */ + + return PAM_CONV_ERR; +} + +static int setup_pam( + const char *name, + const char *user, + uid_t uid, + const char *tty, + char ***pam_env, + int fds[], unsigned n_fds) { + + static const struct pam_conv conv = { + .conv = null_conv, + .appdata_ptr = NULL + }; + + pam_handle_t *handle = NULL; + sigset_t ss, old_ss; + int pam_code = PAM_SUCCESS; + int err; + char **e = NULL; + bool close_session = false; + pid_t pam_pid = 0, parent_pid; + + assert(name); + assert(user); + assert(pam_env); + + /* We set up PAM in the parent process, then fork. The child + * will then stay around until killed via PR_GET_PDEATHSIG or + * systemd via the cgroup logic. It will then remove the PAM + * session again. The parent process will exec() the actual + * daemon. We do things this way to ensure that the main PID + * of the daemon is the one we initially fork()ed. */ + + if ((pam_code = pam_start(name, user, &conv, &handle)) != PAM_SUCCESS) { + handle = NULL; + goto fail; + } + + if (tty) + if ((pam_code = pam_set_item(handle, PAM_TTY, tty)) != PAM_SUCCESS) + goto fail; + + if ((pam_code = pam_acct_mgmt(handle, PAM_SILENT)) != PAM_SUCCESS) + goto fail; + + if ((pam_code = pam_open_session(handle, PAM_SILENT)) != PAM_SUCCESS) + goto fail; + + close_session = true; + + if ((!(e = pam_getenvlist(handle)))) { + pam_code = PAM_BUF_ERR; + goto fail; + } + + /* Block SIGTERM, so that we know that it won't get lost in + * the child */ + if (sigemptyset(&ss) < 0 || + sigaddset(&ss, SIGTERM) < 0 || + sigprocmask(SIG_BLOCK, &ss, &old_ss) < 0) + goto fail; + + parent_pid = getpid(); + + if ((pam_pid = fork()) < 0) + goto fail; + + if (pam_pid == 0) { + int sig; + int r = EXIT_PAM; + + /* The child's job is to reset the PAM session on + * termination */ + + /* 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); + + /* Drop privileges - we don't need any to pam_close_session + * and this will make PR_SET_PDEATHSIG work in most cases. + * If this fails, ignore the error - but expect sd-pam threads + * to fail to exit normally */ + if (setresuid(uid, uid, uid) < 0) + log_error("Error: Failed to setresuid() in sd-pam: %s", strerror(-r)); + + /* Wait until our parent died. This will only work if + * the above setresuid() succeeds, otherwise the kernel + * will not allow unprivileged parents kill their privileged + * children this way. We rely on the control groups kill logic + * to do the rest for us. */ + if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0) + goto child_finish; + + /* Check if our parent process might already have + * died? */ + if (getppid() == parent_pid) { + for (;;) { + if (sigwait(&ss, &sig) < 0) { + if (errno == EINTR) + continue; + + goto child_finish; + } + + assert(sig == SIGTERM); + break; + } + } + + /* If our parent died we'll end the session */ + if (getppid() != parent_pid) + if ((pam_code = pam_close_session(handle, PAM_DATA_SILENT)) != PAM_SUCCESS) + goto child_finish; + + r = 0; + + child_finish: + pam_end(handle, pam_code | PAM_DATA_SILENT); + _exit(r); + } + + /* If the child was forked off successfully it will do all the + * cleanups, so forget about the handle here. */ + handle = NULL; + + /* Unblock SIGTERM again in the parent */ + if (sigprocmask(SIG_SETMASK, &old_ss, NULL) < 0) + goto fail; + + /* We close the log explicitly here, since the PAM modules + * might have opened it, but we don't want this fd around. */ + closelog(); + + *pam_env = e; + e = NULL; + + return 0; + +fail: + if (pam_code != PAM_SUCCESS) + err = -EPERM; /* PAM errors do not map to errno */ + else + err = -errno; + + if (handle) { + if (close_session) + pam_code = pam_close_session(handle, PAM_DATA_SILENT); + + pam_end(handle, pam_code | PAM_DATA_SILENT); + } + + strv_free(e); + + closelog(); + + if (pam_pid > 1) { + kill(pam_pid, SIGTERM); + kill(pam_pid, SIGCONT); + } + + return err; +} +#endif + +static void rename_process_from_path(const char *path) { + char process_name[11]; + const char *p; + size_t l; + + /* This resulting string must fit in 10 chars (i.e. the length + * of "/sbin/init") to look pretty in /bin/ps */ + + p = path_get_file_name(path); + if (isempty(p)) { + rename_process("(...)"); + return; + } + + l = strlen(p); + if (l > 8) { + /* The end of the process name is usually more + * interesting, since the first bit might just be + * "systemd-" */ + p = p + l - 8; + l = 8; + } + + process_name[0] = '('; + memcpy(process_name+1, p, l); + process_name[1+l] = ')'; + process_name[1+l+1] = 0; + + rename_process(process_name); +} + +static int apply_seccomp(uint32_t *syscall_filter) { + static const struct sock_filter header[] = { + VALIDATE_ARCHITECTURE, + EXAMINE_SYSCALL + }; + static const struct sock_filter footer[] = { + _KILL_PROCESS + }; + + int i; + unsigned n; + struct sock_filter *f; + struct sock_fprog prog; + + assert(syscall_filter); + + /* First: count the syscalls to check for */ + for (i = 0, n = 0; i < syscall_max(); i++) + if (syscall_filter[i >> 4] & (1 << (i & 31))) + n++; + + /* Second: build the filter program from a header the syscall + * matches and the footer */ + f = alloca(sizeof(struct sock_filter) * (ELEMENTSOF(header) + 2*n + ELEMENTSOF(footer))); + memcpy(f, header, sizeof(header)); + + for (i = 0, n = 0; i < syscall_max(); i++) + if (syscall_filter[i >> 4] & (1 << (i & 31))) { + struct sock_filter item[] = { + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, i, 0, 1), + BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW) + }; + + assert_cc(ELEMENTSOF(item) == 2); + + f[ELEMENTSOF(header) + 2*n] = item[0]; + f[ELEMENTSOF(header) + 2*n+1] = item[1]; + + n++; + } + + memcpy(f + (ELEMENTSOF(header) + 2*n), footer, sizeof(footer)); + + /* Third: install the filter */ + zero(prog); + prog.len = ELEMENTSOF(header) + ELEMENTSOF(footer) + 2*n; + prog.filter = f; + if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) < 0) + return -errno; + + return 0; +} + +int exec_spawn(ExecCommand *command, + char **argv, + const ExecContext *context, + int fds[], unsigned n_fds, + char **environment, + bool apply_permissions, + bool apply_chroot, + bool apply_tty_stdin, + bool confirm_spawn, + CGroupBonding *cgroup_bondings, + CGroupAttribute *cgroup_attributes, + const char *cgroup_suffix, + const char *unit_id, + int idle_pipe[2], + pid_t *ret) { + + pid_t pid; + int r; + char *line; + int socket_fd; + char _cleanup_strv_free_ **files_env = NULL; + + assert(command); + assert(context); + assert(ret); + assert(fds || n_fds <= 0); + + if (context->std_input == EXEC_INPUT_SOCKET || + context->std_output == EXEC_OUTPUT_SOCKET || + context->std_error == EXEC_OUTPUT_SOCKET) { + + if (n_fds != 1) + return -EINVAL; + + socket_fd = fds[0]; + + fds = NULL; + n_fds = 0; + } else + socket_fd = -1; + + r = exec_context_load_environment(context, &files_env); + if (r < 0) { + log_struct(LOG_ERR, + "UNIT=%s", unit_id, + "MESSAGE=Failed to load environment files: %s", strerror(-r), + "ERRNO=%d", -r, + NULL); + return r; + } + + if (!argv) + argv = command->argv; + + line = exec_command_line(argv); + if (!line) + return log_oom(); + + log_struct(LOG_DEBUG, + "UNIT=%s", unit_id, + "MESSAGE=About to execute %s", line, + NULL); + free(line); + + r = cgroup_bonding_realize_list(cgroup_bondings); + if (r < 0) + return r; + + cgroup_attribute_apply_list(cgroup_attributes, cgroup_bondings); + + pid = fork(); + if (pid < 0) + return -errno; + + if (pid == 0) { + int i, err; + sigset_t ss; + const char *username = NULL, *home = NULL; + uid_t uid = (uid_t) -1; + gid_t gid = (gid_t) -1; + char _cleanup_strv_free_ **our_env = NULL, **pam_env = NULL, + **final_env = NULL, **final_argv = NULL; + unsigned n_env = 0; + bool set_access = false; + + /* child */ + + rename_process_from_path(command->path); + + /* We reset exactly these signals, since they are the + * only ones we set to SIG_IGN in the main daemon. All + * others we leave untouched because we set them to + * SIG_DFL or a valid handler initially, both of which + * will be demoted to SIG_DFL. */ + default_signals(SIGNALS_CRASH_HANDLER, + SIGNALS_IGNORE, -1); + + if (context->ignore_sigpipe) + ignore_signals(SIGPIPE, -1); + + assert_se(sigemptyset(&ss) == 0); + if (sigprocmask(SIG_SETMASK, &ss, NULL) < 0) { + err = -errno; + r = EXIT_SIGNAL_MASK; + goto fail_child; + } + + if (idle_pipe) { + if (idle_pipe[1] >= 0) + close_nointr_nofail(idle_pipe[1]); + if (idle_pipe[0] >= 0) { + fd_wait_for_event(idle_pipe[0], POLLHUP, IDLE_TIMEOUT_USEC); + close_nointr_nofail(idle_pipe[0]); + } + } + + /* Close sockets very early to make sure we don't + * block init reexecution because it cannot bind its + * sockets */ + log_forget_fds(); + err = close_all_fds(socket_fd >= 0 ? &socket_fd : fds, + socket_fd >= 0 ? 1 : n_fds); + if (err < 0) { + r = EXIT_FDS; + goto fail_child; + } + + if (!context->same_pgrp) + if (setsid() < 0) { + err = -errno; + r = EXIT_SETSID; + goto fail_child; + } + + if (context->tcpwrap_name) { + if (socket_fd >= 0) + if (!socket_tcpwrap(socket_fd, context->tcpwrap_name)) { + err = -EACCES; + r = EXIT_TCPWRAP; + goto fail_child; + } + + for (i = 0; i < (int) n_fds; i++) { + if (!socket_tcpwrap(fds[i], context->tcpwrap_name)) { + err = -EACCES; + r = EXIT_TCPWRAP; + goto fail_child; + } + } + } + + exec_context_tty_reset(context); + + if (confirm_spawn) { + char response; + + err = ask_for_confirmation(&response, argv); + if (err == -ETIMEDOUT) + write_confirm_message("Confirmation question timed out, assuming positive response.\n"); + else if (err < 0) + write_confirm_message("Couldn't ask confirmation question, assuming positive response: %s\n", strerror(-err)); + else if (response == 's') { + write_confirm_message("Skipping execution.\n"); + err = -ECANCELED; + r = EXIT_CONFIRM; + goto fail_child; + } else if (response == 'n') { + write_confirm_message("Failing execution.\n"); + err = r = 0; + goto fail_child; + } + } + + /* If a socket is connected to STDIN/STDOUT/STDERR, we + * must sure to drop O_NONBLOCK */ + if (socket_fd >= 0) + fd_nonblock(socket_fd, false); + + err = setup_input(context, socket_fd, apply_tty_stdin); + if (err < 0) { + r = EXIT_STDIN; + goto fail_child; + } + + err = setup_output(context, socket_fd, path_get_file_name(command->path), unit_id, apply_tty_stdin); + if (err < 0) { + r = EXIT_STDOUT; + goto fail_child; + } + + err = setup_error(context, socket_fd, path_get_file_name(command->path), unit_id, apply_tty_stdin); + if (err < 0) { + r = EXIT_STDERR; + goto fail_child; + } + + if (cgroup_bondings) { + err = cgroup_bonding_install_list(cgroup_bondings, 0, cgroup_suffix); + if (err < 0) { + r = EXIT_CGROUP; + goto fail_child; + } + } + + if (context->oom_score_adjust_set) { + char t[16]; + + snprintf(t, sizeof(t), "%i", context->oom_score_adjust); + char_array_0(t); + + if (write_one_line_file("/proc/self/oom_score_adj", t) < 0) { + err = -errno; + r = EXIT_OOM_ADJUST; + goto fail_child; + } + } + + if (context->nice_set) + if (setpriority(PRIO_PROCESS, 0, context->nice) < 0) { + err = -errno; + r = EXIT_NICE; + goto fail_child; + } + + if (context->cpu_sched_set) { + struct sched_param param; + + zero(param); + param.sched_priority = context->cpu_sched_priority; + + if (sched_setscheduler(0, context->cpu_sched_policy | + (context->cpu_sched_reset_on_fork ? SCHED_RESET_ON_FORK : 0), ¶m) < 0) { + err = -errno; + r = EXIT_SETSCHEDULER; + goto fail_child; + } + } + + if (context->cpuset) + if (sched_setaffinity(0, CPU_ALLOC_SIZE(context->cpuset_ncpus), context->cpuset) < 0) { + err = -errno; + r = EXIT_CPUAFFINITY; + goto fail_child; + } + + if (context->ioprio_set) + if (ioprio_set(IOPRIO_WHO_PROCESS, 0, context->ioprio) < 0) { + err = -errno; + r = EXIT_IOPRIO; + goto fail_child; + } + + if (context->timer_slack_nsec != (nsec_t) -1) + if (prctl(PR_SET_TIMERSLACK, context->timer_slack_nsec) < 0) { + err = -errno; + r = EXIT_TIMERSLACK; + goto fail_child; + } + + if (context->utmp_id) + utmp_put_init_process(context->utmp_id, getpid(), getsid(0), context->tty_path); + + if (context->user) { + username = context->user; + err = get_user_creds(&username, &uid, &gid, &home, NULL); + if (err < 0) { + r = EXIT_USER; + goto fail_child; + } + + if (is_terminal_input(context->std_input)) { + err = chown_terminal(STDIN_FILENO, uid); + if (err < 0) { + r = EXIT_STDIN; + goto fail_child; + } + } + + if (cgroup_bondings && context->control_group_modify) { + err = cgroup_bonding_set_group_access_list(cgroup_bondings, 0755, uid, gid); + if (err >= 0) + err = cgroup_bonding_set_task_access_list(cgroup_bondings, 0644, uid, gid, context->control_group_persistent); + if (err < 0) { + r = EXIT_CGROUP; + goto fail_child; + } + + set_access = true; + } + } + + if (cgroup_bondings && !set_access && context->control_group_persistent >= 0) { + err = cgroup_bonding_set_task_access_list(cgroup_bondings, (mode_t) -1, (uid_t) -1, (uid_t) -1, context->control_group_persistent); + if (err < 0) { + r = EXIT_CGROUP; + goto fail_child; + } + } + + if (apply_permissions) { + err = enforce_groups(context, username, gid); + if (err < 0) { + r = EXIT_GROUP; + goto fail_child; + } + } + + umask(context->umask); + +#ifdef HAVE_PAM + if (apply_permissions && context->pam_name && username) { + err = setup_pam(context->pam_name, username, uid, context->tty_path, &pam_env, fds, n_fds); + if (err < 0) { + r = EXIT_PAM; + goto fail_child; + } + } +#endif + if (context->private_network) { + if (unshare(CLONE_NEWNET) < 0) { + err = -errno; + r = EXIT_NETWORK; + goto fail_child; + } + + loopback_setup(); + } + + if (strv_length(context->read_write_dirs) > 0 || + strv_length(context->read_only_dirs) > 0 || + strv_length(context->inaccessible_dirs) > 0 || + context->mount_flags != 0 || + context->private_tmp) { + err = setup_namespace(context->read_write_dirs, + context->read_only_dirs, + context->inaccessible_dirs, + context->private_tmp, + context->mount_flags); + if (err < 0) { + r = EXIT_NAMESPACE; + goto fail_child; + } + } + + if (apply_chroot) { + if (context->root_directory) + if (chroot(context->root_directory) < 0) { + err = -errno; + r = EXIT_CHROOT; + goto fail_child; + } + + if (chdir(context->working_directory ? context->working_directory : "/") < 0) { + err = -errno; + r = EXIT_CHDIR; + goto fail_child; + } + } else { + char _cleanup_free_ *d = NULL; + + if (asprintf(&d, "%s/%s", + context->root_directory ? context->root_directory : "", + context->working_directory ? context->working_directory : "") < 0) { + err = -ENOMEM; + r = EXIT_MEMORY; + goto fail_child; + } + + if (chdir(d) < 0) { + err = -errno; + r = EXIT_CHDIR; + goto fail_child; + } + } + + /* We repeat the fd closing here, to make sure that + * nothing is leaked from the PAM modules */ + err = close_all_fds(fds, n_fds); + if (err >= 0) + err = shift_fds(fds, n_fds); + if (err >= 0) + err = flags_fds(fds, n_fds, context->non_blocking); + if (err < 0) { + r = EXIT_FDS; + goto fail_child; + } + + if (apply_permissions) { + + for (i = 0; i < RLIMIT_NLIMITS; i++) { + if (!context->rlimit[i]) + continue; + + if (setrlimit_closest(i, context->rlimit[i]) < 0) { + err = -errno; + r = EXIT_LIMITS; + goto fail_child; + } + } + + if (context->capability_bounding_set_drop) { + err = capability_bounding_set_drop(context->capability_bounding_set_drop, false); + if (err < 0) { + r = EXIT_CAPABILITIES; + goto fail_child; + } + } + + if (context->user) { + err = enforce_user(context, uid); + if (err < 0) { + r = EXIT_USER; + goto fail_child; + } + } + + /* PR_GET_SECUREBITS is not privileged, while + * PR_SET_SECUREBITS is. So to suppress + * potential EPERMs we'll try not to call + * PR_SET_SECUREBITS unless necessary. */ + if (prctl(PR_GET_SECUREBITS) != context->secure_bits) + if (prctl(PR_SET_SECUREBITS, context->secure_bits) < 0) { + err = -errno; + r = EXIT_SECUREBITS; + goto fail_child; + } + + if (context->capabilities) + if (cap_set_proc(context->capabilities) < 0) { + err = -errno; + r = EXIT_CAPABILITIES; + goto fail_child; + } + + if (context->no_new_privileges) + if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0) { + err = -errno; + r = EXIT_NO_NEW_PRIVILEGES; + goto fail_child; + } + + if (context->syscall_filter) { + err = apply_seccomp(context->syscall_filter); + if (err < 0) { + r = EXIT_SECCOMP; + goto fail_child; + } + } + } + + if (!(our_env = new0(char*, 7))) { + err = -ENOMEM; + r = EXIT_MEMORY; + goto fail_child; + } + + if (n_fds > 0) + if (asprintf(our_env + n_env++, "LISTEN_PID=%lu", (unsigned long) getpid()) < 0 || + asprintf(our_env + n_env++, "LISTEN_FDS=%u", n_fds) < 0) { + err = -ENOMEM; + r = EXIT_MEMORY; + goto fail_child; + } + + if (home) + if (asprintf(our_env + n_env++, "HOME=%s", home) < 0) { + err = -ENOMEM; + r = EXIT_MEMORY; + goto fail_child; + } + + if (username) + if (asprintf(our_env + n_env++, "LOGNAME=%s", username) < 0 || + asprintf(our_env + n_env++, "USER=%s", username) < 0) { + err = -ENOMEM; + r = EXIT_MEMORY; + goto fail_child; + } + + if (is_terminal_input(context->std_input) || + context->std_output == EXEC_OUTPUT_TTY || + context->std_error == EXEC_OUTPUT_TTY) + if (!(our_env[n_env++] = strdup(default_term_for_tty(tty_path(context))))) { + err = -ENOMEM; + r = EXIT_MEMORY; + goto fail_child; + } + + assert(n_env <= 7); + + if (!(final_env = strv_env_merge( + 5, + environment, + our_env, + context->environment, + files_env, + pam_env, + NULL))) { + err = -ENOMEM; + r = EXIT_MEMORY; + goto fail_child; + } + + if (!(final_argv = replace_env_argv(argv, final_env))) { + err = -ENOMEM; + r = EXIT_MEMORY; + goto fail_child; + } + + final_env = strv_env_clean(final_env); + + execve(command->path, final_argv, final_env); + err = -errno; + r = EXIT_EXEC; + + fail_child: + if (r != 0) { + log_open(); + log_struct(LOG_ERR, MESSAGE_ID(SD_MESSAGE_SPAWN_FAILED), + "EXECUTABLE=%s", command->path, + "MESSAGE=Failed at step %s spawning %s: %s", + exit_status_to_string(r, EXIT_STATUS_SYSTEMD), + command->path, strerror(-err), + "ERRNO=%d", -err, + NULL); + log_close(); + } + + _exit(r); + } + + log_struct(LOG_DEBUG, + "UNIT=%s", unit_id, + "MESSAGE=Forked %s as %lu", + command->path, (unsigned long) pid, + NULL); + + /* We add the new process to the cgroup both in the child (so + * that we can be sure that no user code is ever executed + * outside of the cgroup) and in the parent (so that we can be + * sure that when we kill the cgroup the process will be + * killed too). */ + if (cgroup_bondings) + cgroup_bonding_install_list(cgroup_bondings, pid, cgroup_suffix); + + exec_status_start(&command->exec_status, pid); + + *ret = pid; + return 0; +} + +void exec_context_init(ExecContext *c) { + assert(c); + + c->umask = 0022; + c->ioprio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 0); + c->cpu_sched_policy = SCHED_OTHER; + c->syslog_priority = LOG_DAEMON|LOG_INFO; + c->syslog_level_prefix = true; + c->control_group_persistent = -1; + c->ignore_sigpipe = true; + c->timer_slack_nsec = (nsec_t) -1; +} + +void exec_context_done(ExecContext *c) { + unsigned l; + + assert(c); + + strv_free(c->environment); + c->environment = NULL; + + strv_free(c->environment_files); + c->environment_files = NULL; + + for (l = 0; l < ELEMENTSOF(c->rlimit); l++) { + free(c->rlimit[l]); + c->rlimit[l] = NULL; + } + + free(c->working_directory); + c->working_directory = NULL; + free(c->root_directory); + c->root_directory = NULL; + + free(c->tty_path); + c->tty_path = NULL; + + free(c->tcpwrap_name); + c->tcpwrap_name = NULL; + + free(c->syslog_identifier); + c->syslog_identifier = NULL; + + free(c->user); + c->user = NULL; + + free(c->group); + c->group = NULL; + + strv_free(c->supplementary_groups); + c->supplementary_groups = NULL; + + free(c->pam_name); + c->pam_name = NULL; + + if (c->capabilities) { + cap_free(c->capabilities); + c->capabilities = NULL; + } + + strv_free(c->read_only_dirs); + c->read_only_dirs = NULL; + + strv_free(c->read_write_dirs); + c->read_write_dirs = NULL; + + strv_free(c->inaccessible_dirs); + c->inaccessible_dirs = NULL; + + if (c->cpuset) + CPU_FREE(c->cpuset); + + free(c->utmp_id); + c->utmp_id = NULL; + + free(c->syscall_filter); + c->syscall_filter = NULL; +} + +void exec_command_done(ExecCommand *c) { + assert(c); + + free(c->path); + c->path = NULL; + + strv_free(c->argv); + c->argv = NULL; +} + +void exec_command_done_array(ExecCommand *c, unsigned n) { + unsigned i; + + for (i = 0; i < n; i++) + exec_command_done(c+i); +} + +void exec_command_free_list(ExecCommand *c) { + ExecCommand *i; + + while ((i = c)) { + LIST_REMOVE(ExecCommand, command, c, i); + exec_command_done(i); + free(i); + } +} + +void exec_command_free_array(ExecCommand **c, unsigned n) { + unsigned i; + + for (i = 0; i < n; i++) { + exec_command_free_list(c[i]); + c[i] = NULL; + } +} + +int exec_context_load_environment(const ExecContext *c, char ***l) { + char **i, **r = NULL; + + assert(c); + assert(l); + + STRV_FOREACH(i, c->environment_files) { + char *fn; + int k; + bool ignore = false; + char **p; + glob_t pglob; + int count, n; + + fn = *i; + + if (fn[0] == '-') { + ignore = true; + fn ++; + } + + if (!path_is_absolute(fn)) { + + if (ignore) + continue; + + strv_free(r); + return -EINVAL; + } + + /* Filename supports globbing, take all matching files */ + zero(pglob); + errno = 0; + if (glob(fn, 0, NULL, &pglob) != 0) { + globfree(&pglob); + if (ignore) + continue; + + strv_free(r); + return errno ? -errno : -EINVAL; + } + count = pglob.gl_pathc; + if (count == 0) { + globfree(&pglob); + if (ignore) + continue; + + strv_free(r); + return -EINVAL; + } + for (n = 0; n < count; n++) { + k = load_env_file(pglob.gl_pathv[n], &p); + if (k < 0) { + if (ignore) + continue; + + strv_free(r); + globfree(&pglob); + return k; + } + + if (r == NULL) + r = p; + else { + char **m; + + m = strv_env_merge(2, r, p); + strv_free(r); + strv_free(p); + + if (!m) { + globfree(&pglob); + return -ENOMEM; + } + + r = m; + } + } + globfree(&pglob); + } + + *l = r; + + return 0; +} + +static void strv_fprintf(FILE *f, char **l) { + char **g; + + assert(f); + + STRV_FOREACH(g, l) + fprintf(f, " %s", *g); +} + +void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) { + char ** e; + unsigned i; + + assert(c); + assert(f); + + if (!prefix) + prefix = ""; + + fprintf(f, + "%sUMask: %04o\n" + "%sWorkingDirectory: %s\n" + "%sRootDirectory: %s\n" + "%sNonBlocking: %s\n" + "%sPrivateTmp: %s\n" + "%sControlGroupModify: %s\n" + "%sControlGroupPersistent: %s\n" + "%sPrivateNetwork: %s\n" + "%sIgnoreSIGPIPE: %s\n", + prefix, c->umask, + prefix, c->working_directory ? c->working_directory : "/", + prefix, c->root_directory ? c->root_directory : "/", + prefix, yes_no(c->non_blocking), + prefix, yes_no(c->private_tmp), + prefix, yes_no(c->control_group_modify), + prefix, yes_no(c->control_group_persistent), + prefix, yes_no(c->private_network), + prefix, yes_no(c->ignore_sigpipe)); + + STRV_FOREACH(e, c->environment) + fprintf(f, "%sEnvironment: %s\n", prefix, *e); + + STRV_FOREACH(e, c->environment_files) + fprintf(f, "%sEnvironmentFile: %s\n", prefix, *e); + + if (c->tcpwrap_name) + fprintf(f, + "%sTCPWrapName: %s\n", + prefix, c->tcpwrap_name); + + if (c->nice_set) + fprintf(f, + "%sNice: %i\n", + prefix, c->nice); + + if (c->oom_score_adjust_set) + fprintf(f, + "%sOOMScoreAdjust: %i\n", + prefix, c->oom_score_adjust); + + for (i = 0; i < RLIM_NLIMITS; i++) + if (c->rlimit[i]) + fprintf(f, "%s%s: %llu\n", prefix, rlimit_to_string(i), (unsigned long long) c->rlimit[i]->rlim_max); + + if (c->ioprio_set) { + char *class_str; + int r; + + r = ioprio_class_to_string_alloc(IOPRIO_PRIO_CLASS(c->ioprio), &class_str); + if (r < 0) + class_str = NULL; + fprintf(f, + "%sIOSchedulingClass: %s\n" + "%sIOPriority: %i\n", + prefix, strna(class_str), + prefix, (int) IOPRIO_PRIO_DATA(c->ioprio)); + free(class_str); + } + + if (c->cpu_sched_set) { + char *policy_str; + int r; + + r = sched_policy_to_string_alloc(c->cpu_sched_policy, &policy_str); + if (r < 0) + policy_str = NULL; + fprintf(f, + "%sCPUSchedulingPolicy: %s\n" + "%sCPUSchedulingPriority: %i\n" + "%sCPUSchedulingResetOnFork: %s\n", + prefix, strna(policy_str), + prefix, c->cpu_sched_priority, + prefix, yes_no(c->cpu_sched_reset_on_fork)); + free(policy_str); + } + + if (c->cpuset) { + fprintf(f, "%sCPUAffinity:", prefix); + for (i = 0; i < c->cpuset_ncpus; i++) + if (CPU_ISSET_S(i, CPU_ALLOC_SIZE(c->cpuset_ncpus), c->cpuset)) + fprintf(f, " %i", i); + fputs("\n", f); + } + + if (c->timer_slack_nsec != (nsec_t) -1) + fprintf(f, "%sTimerSlackNSec: %lu\n", prefix, (unsigned long)c->timer_slack_nsec); + + fprintf(f, + "%sStandardInput: %s\n" + "%sStandardOutput: %s\n" + "%sStandardError: %s\n", + prefix, exec_input_to_string(c->std_input), + prefix, exec_output_to_string(c->std_output), + prefix, exec_output_to_string(c->std_error)); + + if (c->tty_path) + fprintf(f, + "%sTTYPath: %s\n" + "%sTTYReset: %s\n" + "%sTTYVHangup: %s\n" + "%sTTYVTDisallocate: %s\n", + prefix, c->tty_path, + prefix, yes_no(c->tty_reset), + prefix, yes_no(c->tty_vhangup), + prefix, yes_no(c->tty_vt_disallocate)); + + if (c->std_output == EXEC_OUTPUT_SYSLOG || c->std_output == EXEC_OUTPUT_KMSG || c->std_output == EXEC_OUTPUT_JOURNAL || + c->std_output == EXEC_OUTPUT_SYSLOG_AND_CONSOLE || c->std_output == EXEC_OUTPUT_KMSG_AND_CONSOLE || c->std_output == EXEC_OUTPUT_JOURNAL_AND_CONSOLE || + c->std_error == EXEC_OUTPUT_SYSLOG || c->std_error == EXEC_OUTPUT_KMSG || c->std_error == EXEC_OUTPUT_JOURNAL || + c->std_error == EXEC_OUTPUT_SYSLOG_AND_CONSOLE || c->std_error == EXEC_OUTPUT_KMSG_AND_CONSOLE || c->std_error == EXEC_OUTPUT_JOURNAL_AND_CONSOLE) { + char *fac_str, *lvl_str; + int r; + + r = log_facility_unshifted_to_string_alloc(c->syslog_priority >> 3, &fac_str); + if (r < 0) + fac_str = NULL; + + r = log_level_to_string_alloc(LOG_PRI(c->syslog_priority), &lvl_str); + if (r < 0) + lvl_str = NULL; + + fprintf(f, + "%sSyslogFacility: %s\n" + "%sSyslogLevel: %s\n", + prefix, strna(fac_str), + prefix, strna(lvl_str)); + free(lvl_str); + free(fac_str); + } + + if (c->capabilities) { + char *t; + if ((t = cap_to_text(c->capabilities, NULL))) { + fprintf(f, "%sCapabilities: %s\n", + prefix, t); + cap_free(t); + } + } + + if (c->secure_bits) + fprintf(f, "%sSecure Bits:%s%s%s%s%s%s\n", + prefix, + (c->secure_bits & SECURE_KEEP_CAPS) ? " keep-caps" : "", + (c->secure_bits & SECURE_KEEP_CAPS_LOCKED) ? " keep-caps-locked" : "", + (c->secure_bits & SECURE_NO_SETUID_FIXUP) ? " no-setuid-fixup" : "", + (c->secure_bits & SECURE_NO_SETUID_FIXUP_LOCKED) ? " no-setuid-fixup-locked" : "", + (c->secure_bits & SECURE_NOROOT) ? " noroot" : "", + (c->secure_bits & SECURE_NOROOT_LOCKED) ? "noroot-locked" : ""); + + if (c->capability_bounding_set_drop) { + unsigned long l; + fprintf(f, "%sCapabilityBoundingSet:", prefix); + + for (l = 0; l <= cap_last_cap(); l++) + if (!(c->capability_bounding_set_drop & ((uint64_t) 1ULL << (uint64_t) l))) { + char *t; + + if ((t = cap_to_name(l))) { + fprintf(f, " %s", t); + cap_free(t); + } + } + + fputs("\n", f); + } + + if (c->user) + fprintf(f, "%sUser: %s\n", prefix, c->user); + if (c->group) + fprintf(f, "%sGroup: %s\n", prefix, c->group); + + if (strv_length(c->supplementary_groups) > 0) { + fprintf(f, "%sSupplementaryGroups:", prefix); + strv_fprintf(f, c->supplementary_groups); + fputs("\n", f); + } + + if (c->pam_name) + fprintf(f, "%sPAMName: %s\n", prefix, c->pam_name); + + if (strv_length(c->read_write_dirs) > 0) { + fprintf(f, "%sReadWriteDirs:", prefix); + strv_fprintf(f, c->read_write_dirs); + fputs("\n", f); + } + + if (strv_length(c->read_only_dirs) > 0) { + fprintf(f, "%sReadOnlyDirs:", prefix); + strv_fprintf(f, c->read_only_dirs); + fputs("\n", f); + } + + if (strv_length(c->inaccessible_dirs) > 0) { + fprintf(f, "%sInaccessibleDirs:", prefix); + strv_fprintf(f, c->inaccessible_dirs); + fputs("\n", f); + } + + if (c->utmp_id) + fprintf(f, + "%sUtmpIdentifier: %s\n", + prefix, c->utmp_id); +} + +void exec_status_start(ExecStatus *s, pid_t pid) { + assert(s); + + zero(*s); + s->pid = pid; + dual_timestamp_get(&s->start_timestamp); +} + +void exec_status_exit(ExecStatus *s, ExecContext *context, pid_t pid, int code, int status) { + assert(s); + + if (s->pid && s->pid != pid) + zero(*s); + + s->pid = pid; + dual_timestamp_get(&s->exit_timestamp); + + s->code = code; + s->status = status; + + if (context) { + if (context->utmp_id) + utmp_put_dead_process(context->utmp_id, pid, code, status); + + exec_context_tty_reset(context); + } +} + +void exec_status_dump(ExecStatus *s, FILE *f, const char *prefix) { + char buf[FORMAT_TIMESTAMP_MAX]; + + assert(s); + assert(f); + + if (!prefix) + prefix = ""; + + if (s->pid <= 0) + return; + + fprintf(f, + "%sPID: %lu\n", + prefix, (unsigned long) s->pid); + + if (s->start_timestamp.realtime > 0) + fprintf(f, + "%sStart Timestamp: %s\n", + prefix, format_timestamp(buf, sizeof(buf), s->start_timestamp.realtime)); + + if (s->exit_timestamp.realtime > 0) + fprintf(f, + "%sExit Timestamp: %s\n" + "%sExit Code: %s\n" + "%sExit Status: %i\n", + prefix, format_timestamp(buf, sizeof(buf), s->exit_timestamp.realtime), + prefix, sigchld_code_to_string(s->code), + prefix, s->status); +} + +char *exec_command_line(char **argv) { + size_t k; + char *n, *p, **a; + bool first = true; + + assert(argv); + + k = 1; + STRV_FOREACH(a, argv) + k += strlen(*a)+3; + + if (!(n = new(char, k))) + return NULL; + + p = n; + STRV_FOREACH(a, argv) { + + if (!first) + *(p++) = ' '; + else + first = false; + + if (strpbrk(*a, WHITESPACE)) { + *(p++) = '\''; + p = stpcpy(p, *a); + *(p++) = '\''; + } else + p = stpcpy(p, *a); + + } + + *p = 0; + + /* FIXME: this doesn't really handle arguments that have + * spaces and ticks in them */ + + return n; +} + +void exec_command_dump(ExecCommand *c, FILE *f, const char *prefix) { + char *p2; + const char *prefix2; + + char *cmd; + + assert(c); + assert(f); + + if (!prefix) + prefix = ""; + p2 = strappend(prefix, "\t"); + prefix2 = p2 ? p2 : prefix; + + cmd = exec_command_line(c->argv); + + fprintf(f, + "%sCommand Line: %s\n", + prefix, cmd ? cmd : strerror(ENOMEM)); + + free(cmd); + + exec_status_dump(&c->exec_status, f, prefix2); + + free(p2); +} + +void exec_command_dump_list(ExecCommand *c, FILE *f, const char *prefix) { + assert(f); + + if (!prefix) + prefix = ""; + + LIST_FOREACH(command, c, c) + exec_command_dump(c, f, prefix); +} + +void exec_command_append_list(ExecCommand **l, ExecCommand *e) { + ExecCommand *end; + + assert(l); + assert(e); + + if (*l) { + /* It's kind of important, that we keep the order here */ + LIST_FIND_TAIL(ExecCommand, command, *l, end); + LIST_INSERT_AFTER(ExecCommand, command, *l, end, e); + } else + *l = e; +} + +int exec_command_set(ExecCommand *c, const char *path, ...) { + va_list ap; + char **l, *p; + + assert(c); + assert(path); + + va_start(ap, path); + l = strv_new_ap(path, ap); + va_end(ap); + + if (!l) + return -ENOMEM; + + if (!(p = strdup(path))) { + strv_free(l); + return -ENOMEM; + } + + free(c->path); + c->path = p; + + strv_free(c->argv); + c->argv = l; + + return 0; +} + +static const char* const exec_input_table[_EXEC_INPUT_MAX] = { + [EXEC_INPUT_NULL] = "null", + [EXEC_INPUT_TTY] = "tty", + [EXEC_INPUT_TTY_FORCE] = "tty-force", + [EXEC_INPUT_TTY_FAIL] = "tty-fail", + [EXEC_INPUT_SOCKET] = "socket" +}; + +DEFINE_STRING_TABLE_LOOKUP(exec_input, ExecInput); + +static const char* const exec_output_table[_EXEC_OUTPUT_MAX] = { + [EXEC_OUTPUT_INHERIT] = "inherit", + [EXEC_OUTPUT_NULL] = "null", + [EXEC_OUTPUT_TTY] = "tty", + [EXEC_OUTPUT_SYSLOG] = "syslog", + [EXEC_OUTPUT_SYSLOG_AND_CONSOLE] = "syslog+console", + [EXEC_OUTPUT_KMSG] = "kmsg", + [EXEC_OUTPUT_KMSG_AND_CONSOLE] = "kmsg+console", + [EXEC_OUTPUT_JOURNAL] = "journal", + [EXEC_OUTPUT_JOURNAL_AND_CONSOLE] = "journal+console", + [EXEC_OUTPUT_SOCKET] = "socket" +}; + +DEFINE_STRING_TABLE_LOOKUP(exec_output, ExecOutput); diff --git a/src/core/execute.h b/src/core/execute.h new file mode 100644 index 000000000..2bcd2e1e6 --- /dev/null +++ b/src/core/execute.h @@ -0,0 +1,209 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +typedef struct ExecStatus ExecStatus; +typedef struct ExecCommand ExecCommand; +typedef struct ExecContext ExecContext; + +#include +#include +#include +#include +#include +#include +#include + +struct CGroupBonding; +struct CGroupAttribute; + +#include "list.h" +#include "util.h" + +typedef enum ExecInput { + EXEC_INPUT_NULL, + EXEC_INPUT_TTY, + EXEC_INPUT_TTY_FORCE, + EXEC_INPUT_TTY_FAIL, + EXEC_INPUT_SOCKET, + _EXEC_INPUT_MAX, + _EXEC_INPUT_INVALID = -1 +} ExecInput; + +typedef enum ExecOutput { + EXEC_OUTPUT_INHERIT, + EXEC_OUTPUT_NULL, + EXEC_OUTPUT_TTY, + EXEC_OUTPUT_SYSLOG, + EXEC_OUTPUT_SYSLOG_AND_CONSOLE, + EXEC_OUTPUT_KMSG, + EXEC_OUTPUT_KMSG_AND_CONSOLE, + EXEC_OUTPUT_JOURNAL, + EXEC_OUTPUT_JOURNAL_AND_CONSOLE, + EXEC_OUTPUT_SOCKET, + _EXEC_OUTPUT_MAX, + _EXEC_OUTPUT_INVALID = -1 +} ExecOutput; + +struct ExecStatus { + dual_timestamp start_timestamp; + dual_timestamp exit_timestamp; + pid_t pid; + int code; /* as in siginfo_t::si_code */ + int status; /* as in sigingo_t::si_status */ +}; + +struct ExecCommand { + char *path; + char **argv; + ExecStatus exec_status; + LIST_FIELDS(ExecCommand, command); /* useful for chaining commands */ + bool ignore; +}; + +struct ExecContext { + char **environment; + char **environment_files; + + struct rlimit *rlimit[RLIMIT_NLIMITS]; + char *working_directory, *root_directory; + + mode_t umask; + int oom_score_adjust; + int nice; + int ioprio; + int cpu_sched_policy; + int cpu_sched_priority; + + cpu_set_t *cpuset; + unsigned cpuset_ncpus; + + ExecInput std_input; + ExecOutput std_output; + ExecOutput std_error; + + nsec_t timer_slack_nsec; + + char *tcpwrap_name; + + char *tty_path; + + bool tty_reset; + bool tty_vhangup; + bool tty_vt_disallocate; + + bool ignore_sigpipe; + + /* Since resolving these names might might involve socket + * connections and we don't want to deadlock ourselves these + * names are resolved on execution only and in the child + * process. */ + char *user; + char *group; + char **supplementary_groups; + + char *pam_name; + + char *utmp_id; + + char **read_write_dirs, **read_only_dirs, **inaccessible_dirs; + unsigned long mount_flags; + + uint64_t capability_bounding_set_drop; + + cap_t capabilities; + int secure_bits; + + int syslog_priority; + char *syslog_identifier; + bool syslog_level_prefix; + + bool cpu_sched_reset_on_fork; + bool non_blocking; + bool private_tmp; + bool private_network; + + bool no_new_privileges; + + bool control_group_modify; + int control_group_persistent; + + /* This is not exposed to the user but available + * internally. We need it to make sure that whenever we spawn + * /bin/mount it is run in the same process group as us so + * that the autofs logic detects that it belongs to us and we + * don't enter a trigger loop. */ + bool same_pgrp; + + uint32_t *syscall_filter; + + bool oom_score_adjust_set:1; + bool nice_set:1; + bool ioprio_set:1; + bool cpu_sched_set:1; +}; + +int exec_spawn(ExecCommand *command, + char **argv, + const ExecContext *context, + int fds[], unsigned n_fds, + char **environment, + bool apply_permissions, + bool apply_chroot, + bool apply_tty_stdin, + bool confirm_spawn, + struct CGroupBonding *cgroup_bondings, + struct CGroupAttribute *cgroup_attributes, + const char *cgroup_suffix, + const char *unit_id, + int pipe_fd[2], + pid_t *ret); + +void exec_command_done(ExecCommand *c); +void exec_command_done_array(ExecCommand *c, unsigned n); + +void exec_command_free_list(ExecCommand *c); +void exec_command_free_array(ExecCommand **c, unsigned n); + +char *exec_command_line(char **argv); + +void exec_command_dump(ExecCommand *c, FILE *f, const char *prefix); +void exec_command_dump_list(ExecCommand *c, FILE *f, const char *prefix); +void exec_command_append_list(ExecCommand **l, ExecCommand *e); +int exec_command_set(ExecCommand *c, const char *path, ...); + +void exec_context_init(ExecContext *c); +void exec_context_done(ExecContext *c); +void exec_context_dump(ExecContext *c, FILE* f, const char *prefix); +void exec_context_tty_reset(const ExecContext *context); + +int exec_context_load_environment(const ExecContext *c, char ***l); + +void exec_status_start(ExecStatus *s, pid_t pid); +void exec_status_exit(ExecStatus *s, ExecContext *context, pid_t pid, int code, int status); +void exec_status_dump(ExecStatus *s, FILE *f, const char *prefix); + +const char* exec_output_to_string(ExecOutput i); +ExecOutput exec_output_from_string(const char *s); + +const char* exec_input_to_string(ExecInput i); +ExecInput exec_input_from_string(const char *s); diff --git a/src/core/hostname-setup.c b/src/core/hostname-setup.c new file mode 100644 index 000000000..7894f8a5f --- /dev/null +++ b/src/core/hostname-setup.c @@ -0,0 +1,91 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include +#include + +#include "hostname-setup.h" +#include "macro.h" +#include "util.h" +#include "log.h" + +static int read_and_strip_hostname(const char *path, char **hn) { + char *s; + int r; + + assert(path); + assert(hn); + + r = read_one_line_file(path, &s); + if (r < 0) + return r; + + hostname_cleanup(s); + + if (isempty(s)) { + free(s); + return -ENOENT; + } + + *hn = s; + return 0; +} + +int hostname_setup(void) { + int r; + _cleanup_free_ char *b = NULL; + const char *hn; + bool enoent = false; + + r = read_and_strip_hostname("/etc/hostname", &b); + if (r < 0) { + if (r == -ENOENT) + enoent = true; + else + log_warning("Failed to read configured hostname: %s", strerror(-r)); + + hn = NULL; + } else + hn = b; + + if (isempty(hn)) { + /* Don't override the hostname if it is already set + * and not explicitly configured */ + if (hostname_is_set()) + return 0; + + if (enoent) + log_info("No hostname configured."); + + hn = "localhost"; + } + + if (sethostname(hn, strlen(hn)) < 0) { + log_warning("Failed to set hostname to <%s>: %m", hn); + return -errno; + } + + log_info("Set hostname to <%s>.", hn); + return 0; +} diff --git a/src/core/hostname-setup.h b/src/core/hostname-setup.h new file mode 100644 index 000000000..8dc3a9e1d --- /dev/null +++ b/src/core/hostname-setup.h @@ -0,0 +1,24 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +int hostname_setup(void); diff --git a/src/core/ima-setup.c b/src/core/ima-setup.c new file mode 100644 index 000000000..e8cc1ba8b --- /dev/null +++ b/src/core/ima-setup.c @@ -0,0 +1,115 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + Copyright (C) 2012 Roberto Sassu - Politecnico di Torino, Italy + TORSEC group -- http://security.polito.it + + 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ima-setup.h" +#include "mount-setup.h" +#include "macro.h" +#include "util.h" +#include "log.h" +#include "label.h" + +#define IMA_SECFS_DIR "/sys/kernel/security/ima" +#define IMA_SECFS_POLICY IMA_SECFS_DIR "/policy" +#define IMA_POLICY_PATH "/etc/ima/ima-policy" + +int ima_setup(void) { + +#ifdef HAVE_IMA + struct stat st; + ssize_t policy_size = 0, written = 0; + char *policy; + int policyfd = -1, imafd = -1; + int result = 0; + +#ifndef HAVE_SELINUX + /* Mount the securityfs filesystem */ + mount_setup_early(); +#endif + + if (stat(IMA_POLICY_PATH, &st) < 0) + return 0; + + policy_size = st.st_size; + if (stat(IMA_SECFS_DIR, &st) < 0) { + log_debug("IMA support is disabled in the kernel, ignoring."); + return 0; + } + + if (stat(IMA_SECFS_POLICY, &st) < 0) { + log_error("Another IMA custom policy has already been loaded, " + "ignoring."); + return 0; + } + + policyfd = open(IMA_POLICY_PATH, O_RDONLY|O_CLOEXEC); + if (policyfd < 0) { + log_error("Failed to open the IMA custom policy file %s (%m), " + "ignoring.", IMA_POLICY_PATH); + return 0; + } + + imafd = open(IMA_SECFS_POLICY, O_WRONLY|O_CLOEXEC); + if (imafd < 0) { + log_error("Failed to open the IMA kernel interface %s (%m), " + "ignoring.", IMA_SECFS_POLICY); + goto out; + } + + policy = mmap(NULL, policy_size, PROT_READ, MAP_PRIVATE, policyfd, 0); + if (policy == MAP_FAILED) { + log_error("mmap() failed (%m), freezing"); + result = -errno; + goto out; + } + + written = loop_write(imafd, policy, (size_t)policy_size, false); + if (written != policy_size) { + log_error("Failed to load the IMA custom policy file %s (%m), " + "ignoring.", IMA_POLICY_PATH); + goto out_mmap; + } + + log_info("Successfully loaded the IMA custom policy %s.", + IMA_POLICY_PATH); +out_mmap: + munmap(policy, policy_size); +out: + if (policyfd >= 0) + close_nointr_nofail(policyfd); + if (imafd >= 0) + close_nointr_nofail(imafd); + if (result) + return result; +#endif /* HAVE_IMA */ + + return 0; +} diff --git a/src/core/ima-setup.h b/src/core/ima-setup.h new file mode 100644 index 000000000..14b56d1fc --- /dev/null +++ b/src/core/ima-setup.h @@ -0,0 +1,26 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + Copyright (C) 2012 Roberto Sassu - Politecnico di Torino, Italy + TORSEC group -- http://security.polito.it + + 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 . +***/ + +int ima_setup(void); diff --git a/src/core/initreq.h b/src/core/initreq.h new file mode 100644 index 000000000..859042ce4 --- /dev/null +++ b/src/core/initreq.h @@ -0,0 +1,77 @@ +/* + * initreq.h Interface to talk to init through /dev/initctl. + * + * Copyright (C) 1995-2004 Miquel van Smoorenburg + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * Version: @(#)initreq.h 1.28 31-Mar-2004 MvS + * + */ +#ifndef _INITREQ_H +#define _INITREQ_H + +#include + +#if defined(__FreeBSD_kernel__) +# define INIT_FIFO "/etc/.initctl" +#else +# define INIT_FIFO "/dev/initctl" +#endif + +#define INIT_MAGIC 0x03091969 +#define INIT_CMD_START 0 +#define INIT_CMD_RUNLVL 1 +#define INIT_CMD_POWERFAIL 2 +#define INIT_CMD_POWERFAILNOW 3 +#define INIT_CMD_POWEROK 4 +#define INIT_CMD_BSD 5 +#define INIT_CMD_SETENV 6 +#define INIT_CMD_UNSETENV 7 + +#define INIT_CMD_CHANGECONS 12345 + +#ifdef MAXHOSTNAMELEN +# define INITRQ_HLEN MAXHOSTNAMELEN +#else +# define INITRQ_HLEN 64 +#endif + +/* + * This is what BSD 4.4 uses when talking to init. + * Linux doesn't use this right now. + */ +struct init_request_bsd { + char gen_id[8]; /* Beats me.. telnetd uses "fe" */ + char tty_id[16]; /* Tty name minus /dev/tty */ + char host[INITRQ_HLEN]; /* Hostname */ + char term_type[16]; /* Terminal type */ + int signal; /* Signal to send */ + int pid; /* Process to send to */ + char exec_name[128]; /* Program to execute */ + char reserved[128]; /* For future expansion. */ +}; + + +/* + * Because of legacy interfaces, "runlevel" and "sleeptime" + * aren't in a separate struct in the union. + * + * The weird sizes are because init expects the whole + * struct to be 384 bytes. + */ +struct init_request { + int magic; /* Magic number */ + int cmd; /* What kind of request */ + int runlevel; /* Runlevel to change to */ + int sleeptime; /* Time between TERM and KILL */ + union { + struct init_request_bsd bsd; + char data[368]; + } i; +}; + +#endif diff --git a/src/core/job.c b/src/core/job.c new file mode 100644 index 000000000..5ff95f5c9 --- /dev/null +++ b/src/core/job.c @@ -0,0 +1,1102 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include + +#include "systemd/sd-id128.h" +#include "systemd/sd-messages.h" +#include "set.h" +#include "unit.h" +#include "macro.h" +#include "strv.h" +#include "load-fragment.h" +#include "load-dropin.h" +#include "log.h" +#include "dbus-job.h" + +JobBusClient* job_bus_client_new(DBusConnection *connection, const char *name) { + JobBusClient *cl; + size_t name_len; + + name_len = strlen(name); + cl = malloc0(sizeof(JobBusClient) + name_len + 1); + if (!cl) + return NULL; + + cl->bus = connection; + memcpy(cl->name, name, name_len + 1); + return cl; +} + +Job* job_new_raw(Unit *unit) { + Job *j; + + /* used for deserialization */ + + assert(unit); + + j = new0(Job, 1); + if (!j) + return NULL; + + j->manager = unit->manager; + j->unit = unit; + j->type = _JOB_TYPE_INVALID; + j->timer_watch.type = WATCH_INVALID; + + return j; +} + +Job* job_new(Unit *unit, JobType type) { + Job *j; + + assert(type < _JOB_TYPE_MAX); + + j = job_new_raw(unit); + if (!j) + return NULL; + + j->id = j->manager->current_job_id++; + j->type = type; + + /* We don't link it here, that's what job_dependency() is for */ + + return j; +} + +void job_free(Job *j) { + JobBusClient *cl; + + assert(j); + assert(!j->installed); + assert(!j->transaction_prev); + assert(!j->transaction_next); + assert(!j->subject_list); + assert(!j->object_list); + + if (j->in_run_queue) + LIST_REMOVE(Job, run_queue, j->manager->run_queue, j); + + if (j->in_dbus_queue) + LIST_REMOVE(Job, dbus_queue, j->manager->dbus_job_queue, j); + + if (j->timer_watch.type != WATCH_INVALID) { + assert(j->timer_watch.type == WATCH_JOB_TIMER); + assert(j->timer_watch.data.job == j); + assert(j->timer_watch.fd >= 0); + + assert_se(epoll_ctl(j->manager->epoll_fd, EPOLL_CTL_DEL, j->timer_watch.fd, NULL) >= 0); + close_nointr_nofail(j->timer_watch.fd); + } + + while ((cl = j->bus_client_list)) { + LIST_REMOVE(JobBusClient, client, j->bus_client_list, cl); + free(cl); + } + free(j); +} + +void job_uninstall(Job *j) { + Job **pj; + + assert(j->installed); + + pj = (j->type == JOB_NOP) ? &j->unit->nop_job : &j->unit->job; + assert(*pj == j); + + /* Detach from next 'bigger' objects */ + + /* daemon-reload should be transparent to job observers */ + if (j->manager->n_reloading <= 0) + bus_job_send_removed_signal(j); + + *pj = NULL; + + unit_add_to_gc_queue(j->unit); + + hashmap_remove(j->manager->jobs, UINT32_TO_PTR(j->id)); + j->installed = false; +} + +static bool job_type_allows_late_merge(JobType t) { + /* Tells whether it is OK to merge a job of type 't' with an already + * running job. + * Reloads cannot be merged this way. Think of the sequence: + * 1. Reload of a daemon is in progress; the daemon has already loaded + * its config file, but hasn't completed the reload operation yet. + * 2. Edit foo's config file. + * 3. Trigger another reload to have the daemon use the new config. + * Should the second reload job be merged into the first one, the daemon + * would not know about the new config. + * JOB_RESTART jobs on the other hand can be merged, because they get + * patched into JOB_START after stopping the unit. So if we see a + * JOB_RESTART running, it means the unit hasn't stopped yet and at + * this time the merge is still allowed. */ + return t != JOB_RELOAD; +} + +static void job_merge_into_installed(Job *j, Job *other) { + assert(j->installed); + assert(j->unit == other->unit); + + if (j->type != JOB_NOP) + job_type_merge_and_collapse(&j->type, other->type, j->unit); + else + assert(other->type == JOB_NOP); + + j->override = j->override || other->override; +} + +Job* job_install(Job *j) { + Job **pj; + Job *uj; + + assert(!j->installed); + assert(j->type < _JOB_TYPE_MAX_IN_TRANSACTION); + + pj = (j->type == JOB_NOP) ? &j->unit->nop_job : &j->unit->job; + uj = *pj; + + if (uj) { + if (j->type != JOB_NOP && job_type_is_conflicting(uj->type, j->type)) + job_finish_and_invalidate(uj, JOB_CANCELED, false); + else { + /* not conflicting, i.e. mergeable */ + + if (j->type == JOB_NOP || uj->state == JOB_WAITING || + (job_type_allows_late_merge(j->type) && job_type_is_superset(uj->type, j->type))) { + job_merge_into_installed(uj, j); + log_debug_unit(uj->unit->id, + "Merged into installed job %s/%s as %u", + uj->unit->id, job_type_to_string(uj->type), (unsigned) uj->id); + return uj; + } else { + /* already running and not safe to merge into */ + /* Patch uj to become a merged job and re-run it. */ + /* XXX It should be safer to queue j to run after uj finishes, but it is + * not currently possible to have more than one installed job per unit. */ + job_merge_into_installed(uj, j); + log_debug_unit(uj->unit->id, + "Merged into running job, re-running: %s/%s as %u", + uj->unit->id, job_type_to_string(uj->type), (unsigned) uj->id); + uj->state = JOB_WAITING; + return uj; + } + } + } + + /* Install the job */ + *pj = j; + j->installed = true; + j->manager->n_installed_jobs ++; + log_debug_unit(j->unit->id, + "Installed new job %s/%s as %u", + j->unit->id, job_type_to_string(j->type), (unsigned) j->id); + return j; +} + +int job_install_deserialized(Job *j) { + Job **pj; + + assert(!j->installed); + + if (j->type < 0 || j->type >= _JOB_TYPE_MAX_IN_TRANSACTION) { + log_debug("Invalid job type %s in deserialization.", strna(job_type_to_string(j->type))); + return -EINVAL; + } + + pj = (j->type == JOB_NOP) ? &j->unit->nop_job : &j->unit->job; + + if (*pj) { + log_debug_unit(j->unit->id, + "Unit %s already has a job installed. Not installing deserialized job.", + j->unit->id); + return -EEXIST; + } + *pj = j; + j->installed = true; + log_debug_unit(j->unit->id, + "Reinstalled deserialized job %s/%s as %u", + j->unit->id, job_type_to_string(j->type), (unsigned) j->id); + return 0; +} + +JobDependency* job_dependency_new(Job *subject, Job *object, bool matters, bool conflicts) { + JobDependency *l; + + assert(object); + + /* Adds a new job link, which encodes that the 'subject' job + * needs the 'object' job in some way. If 'subject' is NULL + * this means the 'anchor' job (i.e. the one the user + * explicitly asked for) is the requester. */ + + if (!(l = new0(JobDependency, 1))) + return NULL; + + l->subject = subject; + l->object = object; + l->matters = matters; + l->conflicts = conflicts; + + if (subject) + LIST_PREPEND(JobDependency, subject, subject->subject_list, l); + + LIST_PREPEND(JobDependency, object, object->object_list, l); + + return l; +} + +void job_dependency_free(JobDependency *l) { + assert(l); + + if (l->subject) + LIST_REMOVE(JobDependency, subject, l->subject->subject_list, l); + + LIST_REMOVE(JobDependency, object, l->object->object_list, l); + + free(l); +} + +void job_dump(Job *j, FILE*f, const char *prefix) { + assert(j); + assert(f); + + if (!prefix) + prefix = ""; + + fprintf(f, + "%s-> Job %u:\n" + "%s\tAction: %s -> %s\n" + "%s\tState: %s\n" + "%s\tForced: %s\n", + prefix, j->id, + prefix, j->unit->id, job_type_to_string(j->type), + prefix, job_state_to_string(j->state), + prefix, yes_no(j->override)); +} + +/* + * Merging is commutative, so imagine the matrix as symmetric. We store only + * its lower triangle to avoid duplication. We don't store the main diagonal, + * because A merged with A is simply A. + * + * If the resulting type is collapsed immediately afterwards (to get rid of + * the JOB_RELOAD_OR_START, which lies outside the lookup function's domain), + * the following properties hold: + * + * Merging is associative! A merged with B merged with C is the same as + * A merged with C merged with B. + * + * Mergeability is transitive! If A can be merged with B and B with C then + * A also with C. + * + * Also, if A merged with B cannot be merged with C, then either A or B cannot + * be merged with C either. + */ +static const JobType job_merging_table[] = { +/* What \ With * JOB_START JOB_VERIFY_ACTIVE JOB_STOP JOB_RELOAD */ +/*********************************************************************************/ +/*JOB_START */ +/*JOB_VERIFY_ACTIVE */ JOB_START, +/*JOB_STOP */ -1, -1, +/*JOB_RELOAD */ JOB_RELOAD_OR_START, JOB_RELOAD, -1, +/*JOB_RESTART */ JOB_RESTART, JOB_RESTART, -1, JOB_RESTART, +}; + +JobType job_type_lookup_merge(JobType a, JobType b) { + assert_cc(ELEMENTSOF(job_merging_table) == _JOB_TYPE_MAX_MERGING * (_JOB_TYPE_MAX_MERGING - 1) / 2); + assert(a >= 0 && a < _JOB_TYPE_MAX_MERGING); + assert(b >= 0 && b < _JOB_TYPE_MAX_MERGING); + + if (a == b) + return a; + + if (a < b) { + JobType tmp = a; + a = b; + b = tmp; + } + + return job_merging_table[(a - 1) * a / 2 + b]; +} + +bool job_type_is_redundant(JobType a, UnitActiveState b) { + switch (a) { + + case JOB_START: + return + b == UNIT_ACTIVE || + b == UNIT_RELOADING; + + case JOB_STOP: + return + b == UNIT_INACTIVE || + b == UNIT_FAILED; + + case JOB_VERIFY_ACTIVE: + return + b == UNIT_ACTIVE || + b == UNIT_RELOADING; + + case JOB_RELOAD: + return + b == UNIT_RELOADING; + + case JOB_RESTART: + return + b == UNIT_ACTIVATING; + + default: + assert_not_reached("Invalid job type"); + } +} + +void job_type_collapse(JobType *t, Unit *u) { + UnitActiveState s; + + switch (*t) { + + case JOB_TRY_RESTART: + s = unit_active_state(u); + if (UNIT_IS_INACTIVE_OR_DEACTIVATING(s)) + *t = JOB_NOP; + else + *t = JOB_RESTART; + break; + + case JOB_RELOAD_OR_START: + s = unit_active_state(u); + if (UNIT_IS_INACTIVE_OR_DEACTIVATING(s)) + *t = JOB_START; + else + *t = JOB_RELOAD; + break; + + default: + ; + } +} + +int job_type_merge_and_collapse(JobType *a, JobType b, Unit *u) { + JobType t = job_type_lookup_merge(*a, b); + if (t < 0) + return -EEXIST; + *a = t; + job_type_collapse(a, u); + return 0; +} + +bool job_is_runnable(Job *j) { + Iterator i; + Unit *other; + + assert(j); + assert(j->installed); + + /* Checks whether there is any job running for the units this + * job needs to be running after (in the case of a 'positive' + * job type) or before (in the case of a 'negative' job + * type. */ + + /* First check if there is an override */ + if (j->ignore_order) + return true; + + if (j->type == JOB_NOP) + return true; + + if (j->type == JOB_START || + j->type == JOB_VERIFY_ACTIVE || + j->type == JOB_RELOAD) { + + /* Immediate result is that the job is or might be + * started. In this case lets wait for the + * dependencies, regardless whether they are + * starting or stopping something. */ + + SET_FOREACH(other, j->unit->dependencies[UNIT_AFTER], i) + if (other->job) + return false; + } + + /* Also, if something else is being stopped and we should + * change state after it, then lets wait. */ + + SET_FOREACH(other, j->unit->dependencies[UNIT_BEFORE], i) + if (other->job && + (other->job->type == JOB_STOP || + other->job->type == JOB_RESTART)) + return false; + + /* This means that for a service a and a service b where b + * shall be started after a: + * + * start a + start b → 1st step start a, 2nd step start b + * start a + stop b → 1st step stop b, 2nd step start a + * stop a + start b → 1st step stop a, 2nd step start b + * stop a + stop b → 1st step stop b, 2nd step stop a + * + * This has the side effect that restarts are properly + * synchronized too. */ + + return true; +} + +static void job_change_type(Job *j, JobType newtype) { + log_debug_unit(j->unit->id, + "Converting job %s/%s -> %s/%s", + j->unit->id, job_type_to_string(j->type), + j->unit->id, job_type_to_string(newtype)); + + j->type = newtype; +} + +int job_run_and_invalidate(Job *j) { + int r; + uint32_t id; + Manager *m; + + assert(j); + assert(j->installed); + assert(j->type < _JOB_TYPE_MAX_IN_TRANSACTION); + assert(j->in_run_queue); + + LIST_REMOVE(Job, run_queue, j->manager->run_queue, j); + j->in_run_queue = false; + + if (j->state != JOB_WAITING) + return 0; + + if (!job_is_runnable(j)) + return -EAGAIN; + + j->state = JOB_RUNNING; + job_add_to_dbus_queue(j); + + /* While we execute this operation the job might go away (for + * example: because it is replaced by a new, conflicting + * job.) To make sure we don't access a freed job later on we + * store the id here, so that we can verify the job is still + * valid. */ + id = j->id; + m = j->manager; + + switch (j->type) { + + case JOB_START: + r = unit_start(j->unit); + + /* If this unit cannot be started, then simply wait */ + if (r == -EBADR) + r = 0; + break; + + case JOB_VERIFY_ACTIVE: { + UnitActiveState t = unit_active_state(j->unit); + if (UNIT_IS_ACTIVE_OR_RELOADING(t)) + r = -EALREADY; + else if (t == UNIT_ACTIVATING) + r = -EAGAIN; + else + r = -ENOEXEC; + break; + } + + case JOB_STOP: + case JOB_RESTART: + r = unit_stop(j->unit); + + /* If this unit cannot stopped, then simply wait. */ + if (r == -EBADR) + r = 0; + break; + + case JOB_RELOAD: + r = unit_reload(j->unit); + break; + + case JOB_NOP: + r = -EALREADY; + break; + + default: + assert_not_reached("Unknown job type"); + } + + j = manager_get_job(m, id); + if (j) { + if (r == -EALREADY) + r = job_finish_and_invalidate(j, JOB_DONE, true); + else if (r == -ENOEXEC) + r = job_finish_and_invalidate(j, JOB_SKIPPED, true); + else if (r == -EAGAIN) + j->state = JOB_WAITING; + else if (r < 0) + r = job_finish_and_invalidate(j, JOB_FAILED, true); + } + + return r; +} + +static const char *job_get_status_message_format(Unit *u, JobType t, JobResult result) { + const UnitStatusMessageFormats *format_table; + + assert(u); + assert(t >= 0); + assert(t < _JOB_TYPE_MAX); + + format_table = &UNIT_VTABLE(u)->status_message_formats; + if (!format_table) + return NULL; + + if (t == JOB_START) + return format_table->finished_start_job[result]; + else if (t == JOB_STOP || t == JOB_RESTART) + return format_table->finished_stop_job[result]; + + return NULL; +} + +static const char *job_get_status_message_format_try_harder(Unit *u, JobType t, JobResult result) { + const char *format; + + assert(u); + assert(t >= 0); + assert(t < _JOB_TYPE_MAX); + + format = job_get_status_message_format(u, t, result); + if (format) + return format; + + /* Return generic strings */ + if (t == JOB_START) { + if (result == JOB_DONE) + return "Started %s."; + else if (result == JOB_FAILED) + return "Failed to start %s."; + else if (result == JOB_DEPENDENCY) + return "Dependency failed for %s."; + else if (result == JOB_TIMEOUT) + return "Timed out starting %s."; + } else if (t == JOB_STOP || t == JOB_RESTART) { + if (result == JOB_DONE) + return "Stopped %s."; + else if (result == JOB_FAILED) + return "Stopped (with error) %s."; + else if (result == JOB_TIMEOUT) + return "Timed out stoppping %s."; + } else if (t == JOB_RELOAD) { + if (result == JOB_DONE) + return "Reloaded %s."; + else if (result == JOB_FAILED) + return "Reload failed for %s."; + else if (result == JOB_TIMEOUT) + return "Timed out reloading %s."; + } + + return NULL; +} + +static void job_print_status_message(Unit *u, JobType t, JobResult result) { + const char *format; + + assert(u); + assert(t >= 0); + assert(t < _JOB_TYPE_MAX); + + if (t == JOB_START) { + format = job_get_status_message_format(u, t, result); + if (!format) + return; + + switch (result) { + + case JOB_DONE: + if (u->condition_result) + unit_status_printf(u, ANSI_HIGHLIGHT_GREEN_ON " OK " ANSI_HIGHLIGHT_OFF, format, unit_description(u)); + break; + + case JOB_FAILED: + unit_status_printf(u, ANSI_HIGHLIGHT_RED_ON "FAILED" ANSI_HIGHLIGHT_OFF, format, unit_description(u)); + unit_status_printf(u, NULL, "See 'systemctl status %s' for details.", u->id); + break; + + case JOB_DEPENDENCY: + unit_status_printf(u, ANSI_HIGHLIGHT_YELLOW_ON "DEPEND" ANSI_HIGHLIGHT_OFF, format, unit_description(u)); + break; + + case JOB_TIMEOUT: + unit_status_printf(u, ANSI_HIGHLIGHT_RED_ON " TIME " ANSI_HIGHLIGHT_OFF, format, unit_description(u)); + break; + + default: + ; + } + + } else if (t == JOB_STOP || t == JOB_RESTART) { + + format = job_get_status_message_format(u, t, result); + if (!format) + return; + + switch (result) { + + case JOB_TIMEOUT: + unit_status_printf(u, ANSI_HIGHLIGHT_RED_ON " TIME " ANSI_HIGHLIGHT_OFF, format, unit_description(u)); + break; + + case JOB_DONE: + case JOB_FAILED: + unit_status_printf(u, ANSI_HIGHLIGHT_GREEN_ON " OK " ANSI_HIGHLIGHT_OFF, format, unit_description(u)); + break; + + default: + ; + } + + } else if (t == JOB_VERIFY_ACTIVE) { + + /* When verify-active detects the unit is inactive, report it. + * Most likely a DEPEND warning from a requisiting unit will + * occur next and it's nice to see what was requisited. */ + if (result == JOB_SKIPPED) + unit_status_printf(u, ANSI_HIGHLIGHT_ON " INFO " ANSI_HIGHLIGHT_OFF, "%s is not active.", unit_description(u)); + } +} + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wformat-nonliteral" +static void job_log_status_message(Unit *u, JobType t, JobResult result) { + const char *format; + char buf[LINE_MAX]; + + assert(u); + assert(t >= 0); + assert(t < _JOB_TYPE_MAX); + + /* Skip this if it goes to the console. since we already print + * to the console anyway... */ + + if (log_on_console()) + return; + + format = job_get_status_message_format_try_harder(u, t, result); + if (!format) + return; + + snprintf(buf, sizeof(buf), format, unit_description(u)); + char_array_0(buf); + + if (t == JOB_START) { + sd_id128_t mid; + + mid = result == JOB_DONE ? SD_MESSAGE_UNIT_STARTED : SD_MESSAGE_UNIT_FAILED; + log_struct(result == JOB_DONE ? LOG_INFO : LOG_ERR, + MESSAGE_ID(mid), + "UNIT=%s", u->id, + "RESULT=%s", job_result_to_string(result), + "MESSAGE=%s", buf, + NULL); + + } else if (t == JOB_STOP) + log_struct(result == JOB_DONE ? LOG_INFO : LOG_ERR, + MESSAGE_ID(SD_MESSAGE_UNIT_STOPPED), + "UNIT=%s", u->id, + "RESULT=%s", job_result_to_string(result), + "MESSAGE=%s", buf, + NULL); + + else if (t == JOB_RELOAD) + log_struct(result == JOB_DONE ? LOG_INFO : LOG_ERR, + MESSAGE_ID(SD_MESSAGE_UNIT_RELOADED), + "UNIT=%s", u->id, + "RESULT=%s", job_result_to_string(result), + "MESSAGE=%s", buf, + NULL); +} +#pragma GCC diagnostic pop + +int job_finish_and_invalidate(Job *j, JobResult result, bool recursive) { + Unit *u; + Unit *other; + JobType t; + Iterator i; + + assert(j); + assert(j->installed); + assert(j->type < _JOB_TYPE_MAX_IN_TRANSACTION); + + u = j->unit; + t = j->type; + + j->result = result; + + log_debug_unit(u->id, "Job %s/%s finished, result=%s", + u->id, job_type_to_string(t), job_result_to_string(result)); + + job_print_status_message(u, t, result); + job_log_status_message(u, t, result); + + job_add_to_dbus_queue(j); + + /* Patch restart jobs so that they become normal start jobs */ + if (result == JOB_DONE && t == JOB_RESTART) { + + job_change_type(j, JOB_START); + j->state = JOB_WAITING; + + job_add_to_run_queue(j); + + goto finish; + } + + if (result == JOB_FAILED) + j->manager->n_failed_jobs ++; + + job_uninstall(j); + job_free(j); + + /* Fail depending jobs on failure */ + if (result != JOB_DONE && recursive) { + + if (t == JOB_START || + t == JOB_VERIFY_ACTIVE) { + + SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY], i) + if (other->job && + (other->job->type == JOB_START || + other->job->type == JOB_VERIFY_ACTIVE)) + job_finish_and_invalidate(other->job, JOB_DEPENDENCY, true); + + SET_FOREACH(other, u->dependencies[UNIT_BOUND_BY], i) + if (other->job && + (other->job->type == JOB_START || + other->job->type == JOB_VERIFY_ACTIVE)) + job_finish_and_invalidate(other->job, JOB_DEPENDENCY, true); + + SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY_OVERRIDABLE], i) + if (other->job && + !other->job->override && + (other->job->type == JOB_START || + other->job->type == JOB_VERIFY_ACTIVE)) + job_finish_and_invalidate(other->job, JOB_DEPENDENCY, true); + + } else if (t == JOB_STOP) { + + SET_FOREACH(other, u->dependencies[UNIT_CONFLICTED_BY], i) + if (other->job && + (other->job->type == JOB_START || + other->job->type == JOB_VERIFY_ACTIVE)) + job_finish_and_invalidate(other->job, JOB_DEPENDENCY, true); + } + } + + /* Trigger OnFailure dependencies that are not generated by + * the unit itself. We don't treat JOB_CANCELED as failure in + * this context. And JOB_FAILURE is already handled by the + * unit itself. */ + if (result == JOB_TIMEOUT || result == JOB_DEPENDENCY) { + log_struct(LOG_NOTICE, + "UNIT=%s", u->id, + "JOB_TYPE=%s", job_type_to_string(t), + "JOB_RESULT=%s", job_result_to_string(t), + "Job %s/%s failed with result '%s'.", + u->id, + job_type_to_string(t), + job_result_to_string(result), + NULL); + + unit_trigger_on_failure(u); + } + +finish: + /* Try to start the next jobs that can be started */ + SET_FOREACH(other, u->dependencies[UNIT_AFTER], i) + if (other->job) + job_add_to_run_queue(other->job); + SET_FOREACH(other, u->dependencies[UNIT_BEFORE], i) + if (other->job) + job_add_to_run_queue(other->job); + + manager_check_finished(u->manager); + + return 0; +} + +int job_start_timer(Job *j) { + struct itimerspec its; + struct epoll_event ev; + int fd, r; + assert(j); + + if (j->unit->job_timeout <= 0 || + j->timer_watch.type == WATCH_JOB_TIMER) + return 0; + + assert(j->timer_watch.type == WATCH_INVALID); + + if ((fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK|TFD_CLOEXEC)) < 0) { + r = -errno; + goto fail; + } + + zero(its); + timespec_store(&its.it_value, j->unit->job_timeout); + + if (timerfd_settime(fd, 0, &its, NULL) < 0) { + r = -errno; + goto fail; + } + + zero(ev); + ev.data.ptr = &j->timer_watch; + ev.events = EPOLLIN; + + if (epoll_ctl(j->manager->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0) { + r = -errno; + goto fail; + } + + j->timer_watch.type = WATCH_JOB_TIMER; + j->timer_watch.fd = fd; + j->timer_watch.data.job = j; + + return 0; + +fail: + if (fd >= 0) + close_nointr_nofail(fd); + + return r; +} + +void job_add_to_run_queue(Job *j) { + assert(j); + assert(j->installed); + + if (j->in_run_queue) + return; + + LIST_PREPEND(Job, run_queue, j->manager->run_queue, j); + j->in_run_queue = true; +} + +void job_add_to_dbus_queue(Job *j) { + assert(j); + assert(j->installed); + + if (j->in_dbus_queue) + return; + + /* We don't check if anybody is subscribed here, since this + * job might just have been created and not yet assigned to a + * connection/client. */ + + LIST_PREPEND(Job, dbus_queue, j->manager->dbus_job_queue, j); + j->in_dbus_queue = true; +} + +char *job_dbus_path(Job *j) { + char *p; + + assert(j); + + if (asprintf(&p, "/org/freedesktop/systemd1/job/%lu", (unsigned long) j->id) < 0) + return NULL; + + return p; +} + +void job_timer_event(Job *j, uint64_t n_elapsed, Watch *w) { + assert(j); + assert(w == &j->timer_watch); + + log_warning_unit(j->unit->id, "Job %s/%s timed out.", + j->unit->id, job_type_to_string(j->type)); + job_finish_and_invalidate(j, JOB_TIMEOUT, true); +} + +int job_serialize(Job *j, FILE *f, FDSet *fds) { + fprintf(f, "job-id=%u\n", j->id); + fprintf(f, "job-type=%s\n", job_type_to_string(j->type)); + fprintf(f, "job-state=%s\n", job_state_to_string(j->state)); + fprintf(f, "job-override=%s\n", yes_no(j->override)); + fprintf(f, "job-sent-dbus-new-signal=%s\n", yes_no(j->sent_dbus_new_signal)); + fprintf(f, "job-ignore-order=%s\n", yes_no(j->ignore_order)); + /* Cannot save bus clients. Just note the fact that we're losing + * them. job_send_message() will fallback to broadcasting. */ + fprintf(f, "job-forgot-bus-clients=%s\n", + yes_no(j->forgot_bus_clients || j->bus_client_list)); + if (j->timer_watch.type == WATCH_JOB_TIMER) { + int copy = fdset_put_dup(fds, j->timer_watch.fd); + if (copy < 0) + return copy; + fprintf(f, "job-timer-watch-fd=%d\n", copy); + } + + /* End marker */ + fputc('\n', f); + return 0; +} + +int job_deserialize(Job *j, FILE *f, FDSet *fds) { + for (;;) { + char line[LINE_MAX], *l, *v; + size_t k; + + if (!fgets(line, sizeof(line), f)) { + if (feof(f)) + return 0; + return -errno; + } + + char_array_0(line); + l = strstrip(line); + + /* End marker */ + if (l[0] == 0) + return 0; + + k = strcspn(l, "="); + + if (l[k] == '=') { + l[k] = 0; + v = l+k+1; + } else + v = l+k; + + if (streq(l, "job-id")) { + if (safe_atou32(v, &j->id) < 0) + log_debug("Failed to parse job id value %s", v); + } else if (streq(l, "job-type")) { + JobType t = job_type_from_string(v); + if (t < 0) + log_debug("Failed to parse job type %s", v); + else if (t >= _JOB_TYPE_MAX_IN_TRANSACTION) + log_debug("Cannot deserialize job of type %s", v); + else + j->type = t; + } else if (streq(l, "job-state")) { + JobState s = job_state_from_string(v); + if (s < 0) + log_debug("Failed to parse job state %s", v); + else + j->state = s; + } else if (streq(l, "job-override")) { + int b = parse_boolean(v); + if (b < 0) + log_debug("Failed to parse job override flag %s", v); + else + j->override = j->override || b; + } else if (streq(l, "job-sent-dbus-new-signal")) { + int b = parse_boolean(v); + if (b < 0) + log_debug("Failed to parse job sent_dbus_new_signal flag %s", v); + else + j->sent_dbus_new_signal = j->sent_dbus_new_signal || b; + } else if (streq(l, "job-ignore-order")) { + int b = parse_boolean(v); + if (b < 0) + log_debug("Failed to parse job ignore_order flag %s", v); + else + j->ignore_order = j->ignore_order || b; + } else if (streq(l, "job-forgot-bus-clients")) { + int b = parse_boolean(v); + if (b < 0) + log_debug("Failed to parse job forgot_bus_clients flag %s", v); + else + j->forgot_bus_clients = j->forgot_bus_clients || b; + } else if (streq(l, "job-timer-watch-fd")) { + int fd; + if (safe_atoi(v, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd)) + log_debug("Failed to parse job-timer-watch-fd value %s", v); + else { + if (j->timer_watch.type == WATCH_JOB_TIMER) + close_nointr_nofail(j->timer_watch.fd); + + j->timer_watch.type = WATCH_JOB_TIMER; + j->timer_watch.fd = fdset_remove(fds, fd); + j->timer_watch.data.job = j; + } + } + } +} + +int job_coldplug(Job *j) { + struct epoll_event ev; + + if (j->timer_watch.type != WATCH_JOB_TIMER) + return 0; + + zero(ev); + ev.data.ptr = &j->timer_watch; + ev.events = EPOLLIN; + + if (epoll_ctl(j->manager->epoll_fd, EPOLL_CTL_ADD, j->timer_watch.fd, &ev) < 0) + return -errno; + + return 0; +} + +static const char* const job_state_table[_JOB_STATE_MAX] = { + [JOB_WAITING] = "waiting", + [JOB_RUNNING] = "running" +}; + +DEFINE_STRING_TABLE_LOOKUP(job_state, JobState); + +static const char* const job_type_table[_JOB_TYPE_MAX] = { + [JOB_START] = "start", + [JOB_VERIFY_ACTIVE] = "verify-active", + [JOB_STOP] = "stop", + [JOB_RELOAD] = "reload", + [JOB_RELOAD_OR_START] = "reload-or-start", + [JOB_RESTART] = "restart", + [JOB_TRY_RESTART] = "try-restart", + [JOB_NOP] = "nop", +}; + +DEFINE_STRING_TABLE_LOOKUP(job_type, JobType); + +static const char* const job_mode_table[_JOB_MODE_MAX] = { + [JOB_FAIL] = "fail", + [JOB_REPLACE] = "replace", + [JOB_ISOLATE] = "isolate", + [JOB_IGNORE_DEPENDENCIES] = "ignore-dependencies", + [JOB_IGNORE_REQUIREMENTS] = "ignore-requirements" +}; + +DEFINE_STRING_TABLE_LOOKUP(job_mode, JobMode); + +static const char* const job_result_table[_JOB_RESULT_MAX] = { + [JOB_DONE] = "done", + [JOB_CANCELED] = "canceled", + [JOB_TIMEOUT] = "timeout", + [JOB_FAILED] = "failed", + [JOB_DEPENDENCY] = "dependency", + [JOB_SKIPPED] = "skipped" +}; + +DEFINE_STRING_TABLE_LOOKUP(job_result, JobResult); diff --git a/src/core/job.h b/src/core/job.h new file mode 100644 index 000000000..3aa49d4b4 --- /dev/null +++ b/src/core/job.h @@ -0,0 +1,230 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +#include +#include +#include + +typedef struct Job Job; +typedef struct JobDependency JobDependency; +typedef struct JobBusClient JobBusClient; +typedef enum JobType JobType; +typedef enum JobState JobState; +typedef enum JobMode JobMode; +typedef enum JobResult JobResult; + +/* Be careful when changing the job types! Adjust job_merging_table[] accordingly! */ +enum JobType { + JOB_START, /* if a unit does not support being started, we'll just wait until it becomes active */ + JOB_VERIFY_ACTIVE, + + JOB_STOP, + + JOB_RELOAD, /* if running, reload */ + + /* Note that restarts are first treated like JOB_STOP, but + * then instead of finishing are patched to become + * JOB_START. */ + JOB_RESTART, /* If running, stop. Then start unconditionally. */ + + _JOB_TYPE_MAX_MERGING, + + /* JOB_NOP can enter into a transaction, but as it won't pull in + * any dependencies, it won't have to merge with anything. + * job_install() avoids the problem of merging JOB_NOP too (it's + * special-cased, only merges with other JOB_NOPs). */ + JOB_NOP = _JOB_TYPE_MAX_MERGING, /* do nothing */ + + _JOB_TYPE_MAX_IN_TRANSACTION, + + /* JOB_TRY_RESTART can never appear in a transaction, because + * it always collapses into JOB_RESTART or JOB_NOP before entering. + * Thus we never need to merge it with anything. */ + JOB_TRY_RESTART = _JOB_TYPE_MAX_IN_TRANSACTION, /* if running, stop and then start */ + + /* JOB_RELOAD_OR_START won't enter into a transaction and cannot result + * from transaction merging (there's no way for JOB_RELOAD and + * JOB_START to meet in one transaction). It can result from a merge + * during job installation, but then it will immediately collapse into + * one of the two simpler types. */ + JOB_RELOAD_OR_START, /* if running, reload, otherwise start */ + + _JOB_TYPE_MAX, + _JOB_TYPE_INVALID = -1 +}; + +enum JobState { + JOB_WAITING, + JOB_RUNNING, + _JOB_STATE_MAX, + _JOB_STATE_INVALID = -1 +}; + +enum JobMode { + JOB_FAIL, /* Fail if a conflicting job is already queued */ + JOB_REPLACE, /* Replace an existing conflicting job */ + JOB_ISOLATE, /* Start a unit, and stop all others */ + JOB_IGNORE_DEPENDENCIES, /* Ignore both requirement and ordering dependencies */ + JOB_IGNORE_REQUIREMENTS, /* Ignore requirement dependencies */ + _JOB_MODE_MAX, + _JOB_MODE_INVALID = -1 +}; + +enum JobResult { + JOB_DONE, /* Job completed successfully */ + JOB_CANCELED, /* Job canceled by a conflicting job installation or by explicit cancel request */ + JOB_TIMEOUT, /* JobTimeout elapsed */ + JOB_FAILED, /* Job failed */ + JOB_DEPENDENCY, /* A required dependency job did not result in JOB_DONE */ + JOB_SKIPPED, /* JOB_RELOAD of inactive unit; negative result of JOB_VERIFY_ACTIVE */ + _JOB_RESULT_MAX, + _JOB_RESULT_INVALID = -1 +}; + +#include "manager.h" +#include "unit.h" +#include "hashmap.h" +#include "list.h" + +struct JobDependency { + /* Encodes that the 'subject' job needs the 'object' job in + * some way. This structure is used only while building a transaction. */ + Job *subject; + Job *object; + + LIST_FIELDS(JobDependency, subject); + LIST_FIELDS(JobDependency, object); + + bool matters; + bool conflicts; +}; + +struct JobBusClient { + LIST_FIELDS(JobBusClient, client); + /* Note that this bus object is not ref counted here. */ + DBusConnection *bus; + char name[0]; +}; + +struct Job { + Manager *manager; + Unit *unit; + + LIST_FIELDS(Job, transaction); + LIST_FIELDS(Job, run_queue); + LIST_FIELDS(Job, dbus_queue); + + LIST_HEAD(JobDependency, subject_list); + LIST_HEAD(JobDependency, object_list); + + /* Used for graph algs as a "I have been here" marker */ + Job* marker; + unsigned generation; + + uint32_t id; + + JobType type; + JobState state; + + Watch timer_watch; + + /* There can be more than one client, because of job merging. */ + LIST_HEAD(JobBusClient, bus_client_list); + + JobResult result; + + bool installed:1; + bool in_run_queue:1; + bool matters_to_anchor:1; + bool override:1; + bool in_dbus_queue:1; + bool sent_dbus_new_signal:1; + bool ignore_order:1; + bool forgot_bus_clients:1; +}; + +JobBusClient* job_bus_client_new(DBusConnection *connection, const char *name); + +Job* job_new(Unit *unit, JobType type); +Job* job_new_raw(Unit *unit); +void job_free(Job *job); +Job* job_install(Job *j); +int job_install_deserialized(Job *j); +void job_uninstall(Job *j); +void job_dump(Job *j, FILE*f, const char *prefix); +int job_serialize(Job *j, FILE *f, FDSet *fds); +int job_deserialize(Job *j, FILE *f, FDSet *fds); +int job_coldplug(Job *j); + +JobDependency* job_dependency_new(Job *subject, Job *object, bool matters, bool conflicts); +void job_dependency_free(JobDependency *l); + +int job_merge(Job *j, Job *other); + +JobType job_type_lookup_merge(JobType a, JobType b); + +static inline bool job_type_is_mergeable(JobType a, JobType b) { + return job_type_lookup_merge(a, b) >= 0; +} + +static inline bool job_type_is_conflicting(JobType a, JobType b) { + return !job_type_is_mergeable(a, b); +} + +static inline bool job_type_is_superset(JobType a, JobType b) { + /* Checks whether operation a is a "superset" of b in its actions */ + return a == job_type_lookup_merge(a, b); +} + +bool job_type_is_redundant(JobType a, UnitActiveState b); + +/* Collapses a state-dependent job type into a simpler type by observing + * the state of the unit which it is going to be applied to. */ +void job_type_collapse(JobType *t, Unit *u); + +int job_type_merge_and_collapse(JobType *a, JobType b, Unit *u); + +bool job_is_runnable(Job *j); + +void job_add_to_run_queue(Job *j); +void job_add_to_dbus_queue(Job *j); + +int job_start_timer(Job *j); +void job_timer_event(Job *j, uint64_t n_elapsed, Watch *w); + +int job_run_and_invalidate(Job *j); +int job_finish_and_invalidate(Job *j, JobResult result, bool recursive); + +char *job_dbus_path(Job *j); + +const char* job_type_to_string(JobType t); +JobType job_type_from_string(const char *s); + +const char* job_state_to_string(JobState t); +JobState job_state_from_string(const char *s); + +const char* job_mode_to_string(JobMode t); +JobMode job_mode_from_string(const char *s); + +const char* job_result_to_string(JobResult t); +JobResult job_result_from_string(const char *s); diff --git a/src/core/kill.c b/src/core/kill.c new file mode 100644 index 000000000..0775653f7 --- /dev/null +++ b/src/core/kill.c @@ -0,0 +1,63 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + +#include + +#include "kill.h" +#include "util.h" + +void kill_context_init(KillContext *c) { + assert(c); + + c->kill_signal = SIGTERM; + c->send_sigkill = true; +} + +void kill_context_dump(KillContext *c, FILE *f, const char *prefix) { + assert(c); + + if (!prefix) + prefix = ""; + + fprintf(f, + "%sKillMode: %s\n" + "%sKillSignal: SIG%s\n" + "%sSendSIGKILL: %s\n", + prefix, kill_mode_to_string(c->kill_mode), + prefix, signal_to_string(c->kill_signal), + prefix, yes_no(c->send_sigkill)); +} + +static const char* const kill_mode_table[_KILL_MODE_MAX] = { + [KILL_CONTROL_GROUP] = "control-group", + [KILL_PROCESS] = "process", + [KILL_NONE] = "none" +}; + +DEFINE_STRING_TABLE_LOOKUP(kill_mode, KillMode); + +static const char* const kill_who_table[_KILL_WHO_MAX] = { + [KILL_MAIN] = "main", + [KILL_CONTROL] = "control", + [KILL_ALL] = "all" +}; + +DEFINE_STRING_TABLE_LOOKUP(kill_who, KillWho); diff --git a/src/core/kill.h b/src/core/kill.h new file mode 100644 index 000000000..3c9b0ab8d --- /dev/null +++ b/src/core/kill.h @@ -0,0 +1,60 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + +typedef struct KillContext KillContext; + +#include +#include + +typedef enum KillMode { + /* The kill mode is a property of a unit. */ + KILL_CONTROL_GROUP = 0, + KILL_PROCESS, + KILL_NONE, + _KILL_MODE_MAX, + _KILL_MODE_INVALID = -1 +} KillMode; + +struct KillContext { + KillMode kill_mode; + int kill_signal; + bool send_sigkill; +}; + +typedef enum KillWho { + /* Kill who is a property of an operation */ + KILL_MAIN, + KILL_CONTROL, + KILL_ALL, + _KILL_WHO_MAX, + _KILL_WHO_INVALID = -1 +} KillWho; + +void kill_context_init(KillContext *c); +void kill_context_dump(KillContext *c, FILE *f, const char *prefix); + +const char *kill_mode_to_string(KillMode k); +KillMode kill_mode_from_string(const char *s); + +const char *kill_who_to_string(KillWho k); +KillWho kill_who_from_string(const char *s); diff --git a/src/core/killall.c b/src/core/killall.c new file mode 100644 index 000000000..55200ffa4 --- /dev/null +++ b/src/core/killall.c @@ -0,0 +1,177 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 ProFUSION embedded systems + + 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 . +***/ + +#include +#include +#include + +#include "util.h" +#include "def.h" +#include "killall.h" + +#define TIMEOUT_USEC (5 * USEC_PER_SEC) + +static bool ignore_proc(pid_t pid) { + char buf[PATH_MAX]; + FILE *f; + char c; + size_t count; + uid_t uid; + int r; + + /* We are PID 1, let's not commit suicide */ + if (pid == 1) + return true; + + r = get_process_uid(pid, &uid); + if (r < 0) + return true; /* not really, but better safe than sorry */ + + /* Non-root processes otherwise are always subject to be killed */ + if (uid != 0) + return false; + + snprintf(buf, sizeof(buf), "/proc/%lu/cmdline", (unsigned long) pid); + char_array_0(buf); + + f = fopen(buf, "re"); + if (!f) + return true; /* not really, but has the desired effect */ + + count = fread(&c, 1, 1, f); + fclose(f); + + /* Kernel threads have an empty cmdline */ + if (count <= 0) + return true; + + /* Processes with argv[0][0] = '@' we ignore from the killing + * spree. + * + * http://www.freedesktop.org/wiki/Software/systemd/RootStorageDaemons */ + if (count == 1 && c == '@') + return true; + + return false; +} + +static void wait_for_children(int n_processes, sigset_t *mask) { + usec_t until; + + assert(mask); + + until = now(CLOCK_MONOTONIC) + TIMEOUT_USEC; + for (;;) { + struct timespec ts; + int k; + usec_t n; + + for (;;) { + pid_t pid = waitpid(-1, NULL, WNOHANG); + + if (pid == 0) + break; + + if (pid < 0 && errno == ECHILD) + return; + + if (n_processes > 0) + if (--n_processes == 0) + return; + } + + n = now(CLOCK_MONOTONIC); + if (n >= until) + return; + + timespec_store(&ts, until - n); + + if ((k = sigtimedwait(mask, NULL, &ts)) != SIGCHLD) { + + if (k < 0 && errno != EAGAIN) { + log_error("sigtimedwait() failed: %m"); + return; + } + + if (k >= 0) + log_warning("sigtimedwait() returned unexpected signal."); + } + } +} + +static int killall(int sig) { + DIR *dir; + struct dirent *d; + unsigned int n_processes = 0; + + dir = opendir("/proc"); + if (!dir) + return -errno; + + while ((d = readdir(dir))) { + pid_t pid; + + if (d->d_type != DT_DIR && + d->d_type != DT_UNKNOWN) + continue; + + if (parse_pid(d->d_name, &pid) < 0) + continue; + + if (ignore_proc(pid)) + continue; + + if (kill(pid, sig) >= 0) + n_processes++; + else if (errno != ENOENT) + log_warning("Could not kill %d: %m", pid); + } + + closedir(dir); + + return n_processes; +} + +void broadcast_signal(int sig, bool wait_for_exit) { + sigset_t mask, oldmask; + int n_processes; + + assert_se(sigemptyset(&mask) == 0); + assert_se(sigaddset(&mask, SIGCHLD) == 0); + assert_se(sigprocmask(SIG_BLOCK, &mask, &oldmask) == 0); + + if (kill(-1, SIGSTOP) < 0 && errno != ESRCH) + log_warning("kill(-1, SIGSTOP) failed: %m"); + + n_processes = killall(sig); + + if (kill(-1, SIGCONT) < 0 && errno != ESRCH) + log_warning("kill(-1, SIGCONT) failed: %m"); + + if (n_processes <= 0) + goto finish; + + if (wait_for_exit) + wait_for_children(n_processes, &mask); + +finish: + sigprocmask(SIG_SETMASK, &oldmask, NULL); +} diff --git a/src/core/killall.h b/src/core/killall.h new file mode 100644 index 000000000..d08ac142f --- /dev/null +++ b/src/core/killall.h @@ -0,0 +1,27 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef fookillallhfoo +#define fookillallhfoo + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + +void broadcast_signal(int sig, bool wait); + +#endif diff --git a/src/core/kmod-setup.c b/src/core/kmod-setup.c new file mode 100644 index 000000000..20ab23237 --- /dev/null +++ b/src/core/kmod-setup.c @@ -0,0 +1,104 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include +#include + +#include "macro.h" +#include "execute.h" + +#include "kmod-setup.h" + +typedef struct Kmodule { + const char *name; + const char *directory; + bool (*condition_fn)(void); +} KModule; + +static const KModule kmod_table[] = { + { "autofs4", "/sys/class/misc/autofs", NULL } , + { "ipv6", "/sys/module/ipv6", NULL }, + { "unix", "/proc/net/unix", NULL } , +}; + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wformat-nonliteral" +static void systemd_kmod_log(void *data, int priority, const char *file, int line, + const char *fn, const char *format, va_list args) +{ + /* library logging is enabled at debug only */ + log_metav(LOG_DEBUG, file, line, fn, format, args); +} +#pragma GCC diagnostic pop + +int kmod_setup(void) { + unsigned i; + struct kmod_ctx *ctx = NULL; + struct kmod_module *mod; + int err; + + for (i = 0; i < ELEMENTSOF(kmod_table); i += 2) { + if (kmod_table[i].condition_fn && !kmod_table[i].condition_fn()) + continue; + + if (access(kmod_table[i].directory, F_OK) >= 0) + continue; + + log_debug("Your kernel apparently lacks built-in %s support. Might be a good idea to compile it in. " + "We'll now try to work around this by loading the module...", + kmod_table[i].name); + + if (!ctx) { + ctx = kmod_new(NULL, NULL); + if (!ctx) { + log_error("Failed to allocate memory for kmod"); + return -ENOMEM; + } + + kmod_set_log_fn(ctx, systemd_kmod_log, NULL); + kmod_load_resources(ctx); + } + + err = kmod_module_new_from_name(ctx, kmod_table[i].name, &mod); + if (err < 0) { + log_error("Failed to lookup module '%s'", kmod_table[i].name); + continue; + } + + err = kmod_module_probe_insert_module(mod, KMOD_PROBE_APPLY_BLACKLIST, NULL, NULL, NULL, NULL); + if (err == 0) + log_info("Inserted module '%s'", kmod_module_get_name(mod)); + else if (err == KMOD_PROBE_APPLY_BLACKLIST) + log_info("Module '%s' is blacklisted", kmod_module_get_name(mod)); + else + log_error("Failed to insert module '%s'", kmod_module_get_name(mod)); + + kmod_module_unref(mod); + } + + if (ctx) + kmod_unref(ctx); + + return 0; +} diff --git a/src/core/kmod-setup.h b/src/core/kmod-setup.h new file mode 100644 index 000000000..24dcdddfa --- /dev/null +++ b/src/core/kmod-setup.h @@ -0,0 +1,24 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +int kmod_setup(void); diff --git a/src/core/load-dropin.c b/src/core/load-dropin.c new file mode 100644 index 000000000..86f81c748 --- /dev/null +++ b/src/core/load-dropin.c @@ -0,0 +1,150 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include + +#include "unit.h" +#include "load-dropin.h" +#include "log.h" +#include "strv.h" +#include "unit-name.h" + +static int iterate_dir(Unit *u, const char *path, UnitDependency dependency) { + DIR *d; + struct dirent *de; + int r; + + assert(u); + assert(path); + + d = opendir(path); + if (!d) { + + if (errno == ENOENT) + return 0; + + return -errno; + } + + while ((de = readdir(d))) { + char *f; + + if (ignore_file(de->d_name)) + continue; + + f = strjoin(path, "/", de->d_name, NULL); + if (!f) { + r = -ENOMEM; + goto finish; + } + + r = unit_add_dependency_by_name(u, dependency, de->d_name, f, true); + free(f); + + if (r < 0) + log_error("Cannot add dependency %s to %s, ignoring: %s", de->d_name, u->id, strerror(-r)); + } + + r = 0; + +finish: + closedir(d); + return r; +} + +static int process_dir(Unit *u, const char *unit_path, const char *name, const char *suffix, UnitDependency dependency) { + int r; + char *path; + + assert(u); + assert(unit_path); + assert(name); + assert(suffix); + + path = strjoin(unit_path, "/", name, suffix, NULL); + if (!path) + return -ENOMEM; + + if (u->manager->unit_path_cache && + !set_get(u->manager->unit_path_cache, path)) + r = 0; + else + r = iterate_dir(u, path, dependency); + free(path); + + if (r < 0) + return r; + + if (u->instance) { + char *template; + /* Also try the template dir */ + + template = unit_name_template(name); + if (!template) + return -ENOMEM; + + path = strjoin(unit_path, "/", template, suffix, NULL); + free(template); + + if (!path) + return -ENOMEM; + + if (u->manager->unit_path_cache && + !set_get(u->manager->unit_path_cache, path)) + r = 0; + else + r = iterate_dir(u, path, dependency); + free(path); + + if (r < 0) + return r; + } + + return 0; +} + +int unit_load_dropin(Unit *u) { + Iterator i; + char *t; + + assert(u); + + /* Load dependencies from supplementary drop-in directories */ + + SET_FOREACH(t, u->names, i) { + char **p; + + STRV_FOREACH(p, u->manager->lookup_paths.unit_path) { + int r; + + r = process_dir(u, *p, t, ".wants", UNIT_WANTS); + if (r < 0) + return r; + + r = process_dir(u, *p, t, ".requires", UNIT_REQUIRES); + if (r < 0) + return r; + } + } + + return 0; +} diff --git a/src/core/load-dropin.h b/src/core/load-dropin.h new file mode 100644 index 000000000..1d2fafeee --- /dev/null +++ b/src/core/load-dropin.h @@ -0,0 +1,28 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +#include "unit.h" + +/* Read service data supplementary drop-in directories */ + +int unit_load_dropin(Unit *u); diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4 new file mode 100644 index 000000000..7fba0cfb7 --- /dev/null +++ b/src/core/load-fragment-gperf.gperf.m4 @@ -0,0 +1,258 @@ +%{ +#include +#include "conf-parser.h" +#include "load-fragment.h" +#include "missing.h" +%} +struct ConfigPerfItem; +%null_strings +%language=ANSI-C +%define slot-name section_and_lvalue +%define hash-function-name load_fragment_gperf_hash +%define lookup-function-name load_fragment_gperf_lookup +%readonly-tables +%omit-struct-type +%struct-type +%includes +%% +m4_dnl Define the context options only once +m4_define(`EXEC_CONTEXT_CONFIG_ITEMS', +`$1.WorkingDirectory, config_parse_unit_path_printf, 0, offsetof($1, exec_context.working_directory) +$1.RootDirectory, config_parse_unit_path_printf, 0, offsetof($1, exec_context.root_directory) +$1.User, config_parse_unit_string_printf, 0, offsetof($1, exec_context.user) +$1.Group, config_parse_unit_string_printf, 0, offsetof($1, exec_context.group) +$1.SupplementaryGroups, config_parse_strv, 0, offsetof($1, exec_context.supplementary_groups) +$1.Nice, config_parse_exec_nice, 0, offsetof($1, exec_context) +$1.OOMScoreAdjust, config_parse_exec_oom_score_adjust, 0, offsetof($1, exec_context) +$1.IOSchedulingClass, config_parse_exec_io_class, 0, offsetof($1, exec_context) +$1.IOSchedulingPriority, config_parse_exec_io_priority, 0, offsetof($1, exec_context) +$1.CPUSchedulingPolicy, config_parse_exec_cpu_sched_policy, 0, offsetof($1, exec_context) +$1.CPUSchedulingPriority, config_parse_exec_cpu_sched_prio, 0, offsetof($1, exec_context) +$1.CPUSchedulingResetOnFork, config_parse_bool, 0, offsetof($1, exec_context.cpu_sched_reset_on_fork) +$1.CPUAffinity, config_parse_exec_cpu_affinity, 0, offsetof($1, exec_context) +$1.UMask, config_parse_mode, 0, offsetof($1, exec_context.umask) +$1.Environment, config_parse_unit_strv_printf, 0, offsetof($1, exec_context.environment) +$1.EnvironmentFile, config_parse_unit_env_file, 0, offsetof($1, exec_context.environment_files) +$1.StandardInput, config_parse_input, 0, offsetof($1, exec_context.std_input) +$1.StandardOutput, config_parse_output, 0, offsetof($1, exec_context.std_output) +$1.StandardError, config_parse_output, 0, offsetof($1, exec_context.std_error) +$1.TTYPath, config_parse_unit_path_printf, 0, offsetof($1, exec_context.tty_path) +$1.TTYReset, config_parse_bool, 0, offsetof($1, exec_context.tty_reset) +$1.TTYVHangup, config_parse_bool, 0, offsetof($1, exec_context.tty_vhangup) +$1.TTYVTDisallocate, config_parse_bool, 0, offsetof($1, exec_context.tty_vt_disallocate) +$1.SyslogIdentifier, config_parse_unit_string_printf, 0, offsetof($1, exec_context.syslog_identifier) +$1.SyslogFacility, config_parse_facility, 0, offsetof($1, exec_context.syslog_priority) +$1.SyslogLevel, config_parse_level, 0, offsetof($1, exec_context.syslog_priority) +$1.SyslogLevelPrefix, config_parse_bool, 0, offsetof($1, exec_context.syslog_level_prefix) +$1.Capabilities, config_parse_exec_capabilities, 0, offsetof($1, exec_context) +$1.SecureBits, config_parse_exec_secure_bits, 0, offsetof($1, exec_context) +$1.CapabilityBoundingSet, config_parse_bounding_set, 0, offsetof($1, exec_context.capability_bounding_set_drop) +$1.TimerSlackNSec, config_parse_nsec, 0, offsetof($1, exec_context.timer_slack_nsec) +$1.NoNewPrivileges config_parse_bool, 0, offsetof($1, exec_context.no_new_privileges) +$1.SystemCallFilter, config_parse_syscall_filter, 0, offsetof($1, exec_context) +$1.LimitCPU, config_parse_limit, RLIMIT_CPU, offsetof($1, exec_context.rlimit) +$1.LimitFSIZE, config_parse_limit, RLIMIT_FSIZE, offsetof($1, exec_context.rlimit) +$1.LimitDATA, config_parse_limit, RLIMIT_DATA, offsetof($1, exec_context.rlimit) +$1.LimitSTACK, config_parse_limit, RLIMIT_STACK, offsetof($1, exec_context.rlimit) +$1.LimitCORE, config_parse_limit, RLIMIT_CORE, offsetof($1, exec_context.rlimit) +$1.LimitRSS, config_parse_limit, RLIMIT_RSS, offsetof($1, exec_context.rlimit) +$1.LimitNOFILE, config_parse_limit, RLIMIT_NOFILE, offsetof($1, exec_context.rlimit) +$1.LimitAS, config_parse_limit, RLIMIT_AS, offsetof($1, exec_context.rlimit) +$1.LimitNPROC, config_parse_limit, RLIMIT_NPROC, offsetof($1, exec_context.rlimit) +$1.LimitMEMLOCK, config_parse_limit, RLIMIT_MEMLOCK, offsetof($1, exec_context.rlimit) +$1.LimitLOCKS, config_parse_limit, RLIMIT_LOCKS, offsetof($1, exec_context.rlimit) +$1.LimitSIGPENDING, config_parse_limit, RLIMIT_SIGPENDING, offsetof($1, exec_context.rlimit) +$1.LimitMSGQUEUE, config_parse_limit, RLIMIT_MSGQUEUE, offsetof($1, exec_context.rlimit) +$1.LimitNICE, config_parse_limit, RLIMIT_NICE, offsetof($1, exec_context.rlimit) +$1.LimitRTPRIO, config_parse_limit, RLIMIT_RTPRIO, offsetof($1, exec_context.rlimit) +$1.LimitRTTIME, config_parse_limit, RLIMIT_RTTIME, offsetof($1, exec_context.rlimit) +$1.ControlGroup, config_parse_unit_cgroup, 0, 0 +$1.ControlGroupAttribute, config_parse_unit_cgroup_attr, 0, 0 +$1.CPUShares, config_parse_unit_cpu_shares, 0, 0 +$1.MemoryLimit, config_parse_unit_memory_limit, 0, 0 +$1.MemorySoftLimit, config_parse_unit_memory_limit, 0, 0 +$1.DeviceAllow, config_parse_unit_device_allow, 0, 0 +$1.DeviceDeny, config_parse_unit_device_allow, 0, 0 +$1.BlockIOWeight, config_parse_unit_blkio_weight, 0, 0 +$1.BlockIOReadBandwidth, config_parse_unit_blkio_bandwidth, 0, 0 +$1.BlockIOWriteBandwidth, config_parse_unit_blkio_bandwidth, 0, 0 +$1.ReadWriteDirectories, config_parse_path_strv, 0, offsetof($1, exec_context.read_write_dirs) +$1.ReadOnlyDirectories, config_parse_path_strv, 0, offsetof($1, exec_context.read_only_dirs) +$1.InaccessibleDirectories, config_parse_path_strv, 0, offsetof($1, exec_context.inaccessible_dirs) +$1.PrivateTmp, config_parse_bool, 0, offsetof($1, exec_context.private_tmp) +$1.PrivateNetwork, config_parse_bool, 0, offsetof($1, exec_context.private_network) +$1.MountFlags, config_parse_exec_mount_flags, 0, offsetof($1, exec_context) +$1.TCPWrapName, config_parse_unit_string_printf, 0, offsetof($1, exec_context.tcpwrap_name) +$1.PAMName, config_parse_unit_string_printf, 0, offsetof($1, exec_context.pam_name) +$1.IgnoreSIGPIPE, config_parse_bool, 0, offsetof($1, exec_context.ignore_sigpipe) +$1.UtmpIdentifier, config_parse_unit_string_printf, 0, offsetof($1, exec_context.utmp_id) +$1.ControlGroupModify, config_parse_bool, 0, offsetof($1, exec_context.control_group_modify) +$1.ControlGroupPersistent, config_parse_tristate, 0, offsetof($1, exec_context.control_group_persistent)' +)m4_dnl +m4_define(`KILL_CONTEXT_CONFIG_ITEMS', +`$1.SendSIGKILL, config_parse_bool, 0, offsetof($1, kill_context.send_sigkill) +$1.KillMode, config_parse_kill_mode, 0, offsetof($1, kill_context.kill_mode) +$1.KillSignal, config_parse_kill_signal, 0, offsetof($1, kill_context.kill_signal)' +)m4_dnl +Unit.Description, config_parse_unit_string_printf, 0, offsetof(Unit, description) +Unit.Documentation, config_parse_documentation, 0, offsetof(Unit, documentation) +Unit.SourcePath, config_parse_path, 0, offsetof(Unit, source_path) +Unit.Requires, config_parse_unit_deps, UNIT_REQUIRES, 0 +Unit.RequiresOverridable, config_parse_unit_deps, UNIT_REQUIRES_OVERRIDABLE, 0 +Unit.Requisite, config_parse_unit_deps, UNIT_REQUISITE, 0 +Unit.RequisiteOverridable, config_parse_unit_deps, UNIT_REQUISITE_OVERRIDABLE, 0 +Unit.Wants, config_parse_unit_deps, UNIT_WANTS, 0 +Unit.BindsTo, config_parse_unit_deps, UNIT_BINDS_TO, 0 +Unit.BindTo, config_parse_unit_deps, UNIT_BINDS_TO, 0 +Unit.Conflicts, config_parse_unit_deps, UNIT_CONFLICTS, 0 +Unit.Before, config_parse_unit_deps, UNIT_BEFORE, 0 +Unit.After, config_parse_unit_deps, UNIT_AFTER, 0 +Unit.OnFailure, config_parse_unit_deps, UNIT_ON_FAILURE, 0 +Unit.PropagatesReloadTo, config_parse_unit_deps, UNIT_PROPAGATES_RELOAD_TO, 0 +Unit.PropagateReloadTo, config_parse_unit_deps, UNIT_PROPAGATES_RELOAD_TO, 0 +Unit.ReloadPropagatedFrom, config_parse_unit_deps, UNIT_RELOAD_PROPAGATED_FROM, 0 +Unit.PropagateReloadFrom, config_parse_unit_deps, UNIT_RELOAD_PROPAGATED_FROM, 0 +Unit.PartOf, config_parse_unit_deps, UNIT_PART_OF, 0 +Unit.RequiresMountsFor, config_parse_unit_requires_mounts_for, 0, offsetof(Unit, requires_mounts_for) +Unit.StopWhenUnneeded, config_parse_bool, 0, offsetof(Unit, stop_when_unneeded) +Unit.RefuseManualStart, config_parse_bool, 0, offsetof(Unit, refuse_manual_start) +Unit.RefuseManualStop, config_parse_bool, 0, offsetof(Unit, refuse_manual_stop) +Unit.AllowIsolate, config_parse_bool, 0, offsetof(Unit, allow_isolate) +Unit.DefaultDependencies, config_parse_bool, 0, offsetof(Unit, default_dependencies) +Unit.OnFailureIsolate, config_parse_bool, 0, offsetof(Unit, on_failure_isolate) +Unit.IgnoreOnIsolate, config_parse_bool, 0, offsetof(Unit, ignore_on_isolate) +Unit.IgnoreOnSnapshot, config_parse_bool, 0, offsetof(Unit, ignore_on_snapshot) +Unit.JobTimeoutSec, config_parse_usec, 0, offsetof(Unit, job_timeout) +Unit.ConditionPathExists, config_parse_unit_condition_path, CONDITION_PATH_EXISTS, 0 +Unit.ConditionPathExistsGlob, config_parse_unit_condition_path, CONDITION_PATH_EXISTS_GLOB, 0 +Unit.ConditionPathIsDirectory, config_parse_unit_condition_path, CONDITION_PATH_IS_DIRECTORY, 0 +Unit.ConditionPathIsSymbolicLink,config_parse_unit_condition_path, CONDITION_PATH_IS_SYMBOLIC_LINK,0 +Unit.ConditionPathIsMountPoint, config_parse_unit_condition_path, CONDITION_PATH_IS_MOUNT_POINT, 0 +Unit.ConditionPathIsReadWrite, config_parse_unit_condition_path, CONDITION_PATH_IS_READ_WRITE, 0 +Unit.ConditionDirectoryNotEmpty, config_parse_unit_condition_path, CONDITION_DIRECTORY_NOT_EMPTY, 0 +Unit.ConditionFileNotEmpty, config_parse_unit_condition_path, CONDITION_FILE_NOT_EMPTY, 0 +Unit.ConditionFileIsExecutable, config_parse_unit_condition_path, CONDITION_FILE_IS_EXECUTABLE, 0 +Unit.ConditionKernelCommandLine, config_parse_unit_condition_string, CONDITION_KERNEL_COMMAND_LINE, 0 +Unit.ConditionVirtualization, config_parse_unit_condition_string, CONDITION_VIRTUALIZATION, 0 +Unit.ConditionSecurity, config_parse_unit_condition_string, CONDITION_SECURITY, 0 +Unit.ConditionCapability, config_parse_unit_condition_string, CONDITION_CAPABILITY, 0 +Unit.ConditionHost, config_parse_unit_condition_string, CONDITION_HOST, 0 +Unit.ConditionACPower, config_parse_unit_condition_string, CONDITION_AC_POWER, 0 +Unit.ConditionNull, config_parse_unit_condition_null, 0, 0 +m4_dnl +Service.PIDFile, config_parse_unit_path_printf, 0, offsetof(Service, pid_file) +Service.ExecStartPre, config_parse_exec, SERVICE_EXEC_START_PRE, offsetof(Service, exec_command) +Service.ExecStart, config_parse_exec, SERVICE_EXEC_START, offsetof(Service, exec_command) +Service.ExecStartPost, config_parse_exec, SERVICE_EXEC_START_POST, offsetof(Service, exec_command) +Service.ExecReload, config_parse_exec, SERVICE_EXEC_RELOAD, offsetof(Service, exec_command) +Service.ExecStop, config_parse_exec, SERVICE_EXEC_STOP, offsetof(Service, exec_command) +Service.ExecStopPost, config_parse_exec, SERVICE_EXEC_STOP_POST, offsetof(Service, exec_command) +Service.RestartSec, config_parse_usec, 0, offsetof(Service, restart_usec) +Service.TimeoutSec, config_parse_service_timeout, 0, offsetof(Service, timeout_start_usec) +Service.TimeoutStartSec, config_parse_service_timeout, 0, offsetof(Service, timeout_start_usec) +Service.TimeoutStopSec, config_parse_service_timeout, 0, offsetof(Service, timeout_stop_usec) +Service.WatchdogSec, config_parse_usec, 0, offsetof(Service, watchdog_usec) +Service.StartLimitInterval, config_parse_usec, 0, offsetof(Service, start_limit.interval) +Service.StartLimitBurst, config_parse_unsigned, 0, offsetof(Service, start_limit.burst) +Service.StartLimitAction, config_parse_start_limit_action, 0, offsetof(Service, start_limit_action) +Service.Type, config_parse_service_type, 0, offsetof(Service, type) +Service.Restart, config_parse_service_restart, 0, offsetof(Service, restart) +Service.PermissionsStartOnly, config_parse_bool, 0, offsetof(Service, permissions_start_only) +Service.RootDirectoryStartOnly, config_parse_bool, 0, offsetof(Service, root_directory_start_only) +Service.RemainAfterExit, config_parse_bool, 0, offsetof(Service, remain_after_exit) +Service.GuessMainPID, config_parse_bool, 0, offsetof(Service, guess_main_pid) +Service.RestartPreventExitStatus, config_parse_set_status, 0, offsetof(Service, restart_ignore_status) +Service.SuccessExitStatus, config_parse_set_status, 0, offsetof(Service, success_status) +m4_ifdef(`HAVE_SYSV_COMPAT', +`Service.SysVStartPriority, config_parse_sysv_priority, 0, offsetof(Service, sysv_start_priority)', +`Service.SysVStartPriority, config_parse_warn_compat, 0, 0') +Service.NonBlocking, config_parse_bool, 0, offsetof(Service, exec_context.non_blocking) +Service.BusName, config_parse_unit_string_printf, 0, offsetof(Service, bus_name) +Service.NotifyAccess, config_parse_notify_access, 0, offsetof(Service, notify_access) +Service.Sockets, config_parse_service_sockets, 0, 0 +Service.FsckPassNo, config_parse_fsck_passno, 0, offsetof(Service, fsck_passno) +EXEC_CONTEXT_CONFIG_ITEMS(Service)m4_dnl +KILL_CONTEXT_CONFIG_ITEMS(Service)m4_dnl +m4_dnl +Socket.ListenStream, config_parse_socket_listen, 0, 0 +Socket.ListenDatagram, config_parse_socket_listen, 0, 0 +Socket.ListenSequentialPacket, config_parse_socket_listen, 0, 0 +Socket.ListenFIFO, config_parse_socket_listen, 0, 0 +Socket.ListenNetlink, config_parse_socket_listen, 0, 0 +Socket.ListenSpecial, config_parse_socket_listen, 0, 0 +Socket.ListenMessageQueue, config_parse_socket_listen, 0, 0 +Socket.BindIPv6Only, config_parse_socket_bind, 0, 0, +Socket.Backlog, config_parse_unsigned, 0, offsetof(Socket, backlog) +Socket.BindToDevice, config_parse_socket_bindtodevice, 0, 0 +Socket.ExecStartPre, config_parse_exec, SOCKET_EXEC_START_PRE, offsetof(Socket, exec_command) +Socket.ExecStartPost, config_parse_exec, SOCKET_EXEC_START_POST, offsetof(Socket, exec_command) +Socket.ExecStopPre, config_parse_exec, SOCKET_EXEC_STOP_PRE, offsetof(Socket, exec_command) +Socket.ExecStopPost, config_parse_exec, SOCKET_EXEC_STOP_POST, offsetof(Socket, exec_command) +Socket.TimeoutSec, config_parse_usec, 0, offsetof(Socket, timeout_usec) +Socket.DirectoryMode, config_parse_mode, 0, offsetof(Socket, directory_mode) +Socket.SocketMode, config_parse_mode, 0, offsetof(Socket, socket_mode) +Socket.Accept, config_parse_bool, 0, offsetof(Socket, accept) +Socket.MaxConnections, config_parse_unsigned, 0, offsetof(Socket, max_connections) +Socket.KeepAlive, config_parse_bool, 0, offsetof(Socket, keep_alive) +Socket.Priority, config_parse_int, 0, offsetof(Socket, priority) +Socket.ReceiveBuffer, config_parse_bytes_size, 0, offsetof(Socket, receive_buffer) +Socket.SendBuffer, config_parse_bytes_size, 0, offsetof(Socket, send_buffer) +Socket.IPTOS, config_parse_ip_tos, 0, offsetof(Socket, ip_tos) +Socket.IPTTL, config_parse_int, 0, offsetof(Socket, ip_ttl) +Socket.Mark, config_parse_int, 0, offsetof(Socket, mark) +Socket.PipeSize, config_parse_bytes_size, 0, offsetof(Socket, pipe_size) +Socket.FreeBind, config_parse_bool, 0, offsetof(Socket, free_bind) +Socket.Transparent, config_parse_bool, 0, offsetof(Socket, transparent) +Socket.Broadcast, config_parse_bool, 0, offsetof(Socket, broadcast) +Socket.PassCredentials, config_parse_bool, 0, offsetof(Socket, pass_cred) +Socket.PassSecurity, config_parse_bool, 0, offsetof(Socket, pass_sec) +Socket.TCPCongestion, config_parse_string, 0, offsetof(Socket, tcp_congestion) +Socket.MessageQueueMaxMessages, config_parse_long, 0, offsetof(Socket, mq_maxmsg) +Socket.MessageQueueMessageSize, config_parse_long, 0, offsetof(Socket, mq_msgsize) +Socket.Service, config_parse_socket_service, 0, 0 +Socket.SmackLabel, config_parse_string, 0, offsetof(Socket, smack) +Socket.SmackLabelIPIn, config_parse_string, 0, offsetof(Socket, smack_ip_in) +Socket.SmackLabelIPOut, config_parse_string, 0, offsetof(Socket, smack_ip_out) +EXEC_CONTEXT_CONFIG_ITEMS(Socket)m4_dnl +KILL_CONTEXT_CONFIG_ITEMS(Socket)m4_dnl +m4_dnl +Mount.What, config_parse_string, 0, offsetof(Mount, parameters_fragment.what) +Mount.Where, config_parse_path, 0, offsetof(Mount, where) +Mount.Options, config_parse_string, 0, offsetof(Mount, parameters_fragment.options) +Mount.Type, config_parse_string, 0, offsetof(Mount, parameters_fragment.fstype) +Mount.FsckPassNo, config_parse_fsck_passno, 0, offsetof(Mount, parameters_fragment.passno) +Mount.TimeoutSec, config_parse_usec, 0, offsetof(Mount, timeout_usec) +Mount.DirectoryMode, config_parse_mode, 0, offsetof(Mount, directory_mode) +EXEC_CONTEXT_CONFIG_ITEMS(Mount)m4_dnl +KILL_CONTEXT_CONFIG_ITEMS(Mount)m4_dnl +m4_dnl +Automount.Where, config_parse_path, 0, offsetof(Automount, where) +Automount.DirectoryMode, config_parse_mode, 0, offsetof(Automount, directory_mode) +m4_dnl +Swap.What, config_parse_path, 0, offsetof(Swap, parameters_fragment.what) +Swap.Priority, config_parse_int, 0, offsetof(Swap, parameters_fragment.priority) +Swap.TimeoutSec, config_parse_usec, 0, offsetof(Swap, timeout_usec) +EXEC_CONTEXT_CONFIG_ITEMS(Swap)m4_dnl +KILL_CONTEXT_CONFIG_ITEMS(Swap)m4_dnl +m4_dnl +Timer.OnCalendar, config_parse_timer, 0, 0 +Timer.OnActiveSec, config_parse_timer, 0, 0 +Timer.OnBootSec, config_parse_timer, 0, 0 +Timer.OnStartupSec, config_parse_timer, 0, 0 +Timer.OnUnitActiveSec, config_parse_timer, 0, 0 +Timer.OnUnitInactiveSec, config_parse_timer, 0, 0 +Timer.Unit, config_parse_timer_unit, 0, 0 +m4_dnl +Path.PathExists, config_parse_path_spec, 0, 0 +Path.PathExistsGlob, config_parse_path_spec, 0, 0 +Path.PathChanged, config_parse_path_spec, 0, 0 +Path.PathModified, config_parse_path_spec, 0, 0 +Path.DirectoryNotEmpty, config_parse_path_spec, 0, 0 +Path.Unit, config_parse_path_unit, 0, 0 +Path.MakeDirectory, config_parse_bool, 0, offsetof(Path, make_directory) +Path.DirectoryMode, config_parse_mode, 0, offsetof(Path, directory_mode) +m4_dnl The [Install] section is ignored here. +Install.Alias, NULL, 0, 0 +Install.WantedBy, NULL, 0, 0 +Install.RequiredBy, NULL, 0, 0 +Install.Also, NULL, 0, 0 diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c new file mode 100644 index 000000000..e35fdbc5e --- /dev/null +++ b/src/core/load-fragment.c @@ -0,0 +1,2576 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + Copyright 2012 Holger Hans Peter Freyther + + 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "unit.h" +#include "strv.h" +#include "conf-parser.h" +#include "load-fragment.h" +#include "log.h" +#include "ioprio.h" +#include "securebits.h" +#include "missing.h" +#include "unit-name.h" +#include "unit-printf.h" +#include "bus-errors.h" +#include "utf8.h" +#include "path-util.h" +#include "syscall-list.h" + +#ifndef HAVE_SYSV_COMPAT +int config_parse_warn_compat( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + log_debug("[%s:%u] Support for option %s= has been disabled at compile time and is ignored", filename, line, lvalue); + return 0; +} +#endif + +int config_parse_unit_deps( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + UnitDependency d = ltype; + Unit *u = userdata; + char *w; + size_t l; + char *state; + + assert(filename); + assert(lvalue); + assert(rvalue); + + FOREACH_WORD_QUOTED(w, l, rvalue, state) { + char _cleanup_free_ *t = NULL, *k = NULL; + int r; + + t = strndup(w, l); + if (!t) + return -ENOMEM; + + k = unit_name_printf(u, t); + if (!k) + return -ENOMEM; + + r = unit_add_dependency_by_name(u, d, k, NULL, true); + if (r < 0) + log_error("[%s:%u] Failed to add dependency on %s, ignoring: %s", + filename, line, k, strerror(-r)); + } + + return 0; +} + +int config_parse_unit_string_printf( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + Unit *u = userdata; + char *k; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(u); + + k = unit_full_printf(u, rvalue); + if (!k) + return -ENOMEM; + + r = config_parse_string(filename, line, section, lvalue, ltype, k, data, userdata); + free (k); + + return r; +} + +int config_parse_unit_strv_printf( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + Unit *u = userdata; + char *k; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(u); + + k = unit_full_printf(u, rvalue); + if (!k) + return -ENOMEM; + + r = config_parse_strv(filename, line, section, lvalue, ltype, k, data, userdata); + free(k); + + return r; +} + +int config_parse_unit_path_printf( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + Unit *u = userdata; + char *k; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(u); + + k = unit_full_printf(u, rvalue); + if (!k) + return log_oom(); + + r = config_parse_path(filename, line, section, lvalue, ltype, k, data, userdata); + free(k); + + return r; +} + +int config_parse_socket_listen( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + SocketPort *p, *tail; + Socket *s; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + s = SOCKET(data); + + p = new0(SocketPort, 1); + if (!p) + return -ENOMEM; + + if (streq(lvalue, "ListenFIFO")) { + p->type = SOCKET_FIFO; + + if (!(p->path = unit_full_printf(UNIT(s), rvalue))) { + free(p); + return -ENOMEM; + } + + path_kill_slashes(p->path); + + } else if (streq(lvalue, "ListenSpecial")) { + p->type = SOCKET_SPECIAL; + + if (!(p->path = unit_full_printf(UNIT(s), rvalue))) { + free(p); + return -ENOMEM; + } + + path_kill_slashes(p->path); + + } else if (streq(lvalue, "ListenMessageQueue")) { + + p->type = SOCKET_MQUEUE; + + if (!(p->path = unit_full_printf(UNIT(s), rvalue))) { + free(p); + return -ENOMEM; + } + + path_kill_slashes(p->path); + + } else if (streq(lvalue, "ListenNetlink")) { + char *k; + int r; + + p->type = SOCKET_SOCKET; + k = unit_full_printf(UNIT(s), rvalue); + r = socket_address_parse_netlink(&p->address, k); + free(k); + + if (r < 0) { + log_error("[%s:%u] Failed to parse address value, ignoring: %s", filename, line, rvalue); + free(p); + return 0; + } + + } else { + char *k; + int r; + + p->type = SOCKET_SOCKET; + k = unit_full_printf(UNIT(s), rvalue); + r = socket_address_parse(&p->address, k); + free(k); + + if (r < 0) { + log_error("[%s:%u] Failed to parse address value, ignoring: %s", filename, line, rvalue); + free(p); + return 0; + } + + if (streq(lvalue, "ListenStream")) + p->address.type = SOCK_STREAM; + else if (streq(lvalue, "ListenDatagram")) + p->address.type = SOCK_DGRAM; + else { + assert(streq(lvalue, "ListenSequentialPacket")); + p->address.type = SOCK_SEQPACKET; + } + + if (socket_address_family(&p->address) != AF_LOCAL && p->address.type == SOCK_SEQPACKET) { + log_error("[%s:%u] Address family not supported, ignoring: %s", filename, line, rvalue); + free(p); + return 0; + } + } + + p->fd = -1; + + if (s->ports) { + LIST_FIND_TAIL(SocketPort, port, s->ports, tail); + LIST_INSERT_AFTER(SocketPort, port, s->ports, tail, p); + } else + LIST_PREPEND(SocketPort, port, s->ports, p); + + return 0; +} + +int config_parse_socket_bind( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + Socket *s; + SocketAddressBindIPv6Only b; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + s = SOCKET(data); + + b = socket_address_bind_ipv6_only_from_string(rvalue); + if (b < 0) { + int r; + + r = parse_boolean(rvalue); + if (r < 0) { + log_error("[%s:%u] Failed to parse bind IPv6 only value, ignoring: %s", filename, line, rvalue); + return 0; + } + + s->bind_ipv6_only = r ? SOCKET_ADDRESS_IPV6_ONLY : SOCKET_ADDRESS_BOTH; + } else + s->bind_ipv6_only = b; + + return 0; +} + +int config_parse_exec_nice( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + ExecContext *c = data; + int priority; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if (safe_atoi(rvalue, &priority) < 0) { + log_error("[%s:%u] Failed to parse nice priority, ignoring: %s. ", filename, line, rvalue); + return 0; + } + + if (priority < PRIO_MIN || priority >= PRIO_MAX) { + log_error("[%s:%u] Nice priority out of range, ignoring: %s", filename, line, rvalue); + return 0; + } + + c->nice = priority; + c->nice_set = true; + + return 0; +} + +int config_parse_exec_oom_score_adjust( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + ExecContext *c = data; + int oa; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if (safe_atoi(rvalue, &oa) < 0) { + log_error("[%s:%u] Failed to parse the OOM score adjust value, ignoring: %s", filename, line, rvalue); + return 0; + } + + if (oa < OOM_SCORE_ADJ_MIN || oa > OOM_SCORE_ADJ_MAX) { + log_error("[%s:%u] OOM score adjust value out of range, ignoring: %s", filename, line, rvalue); + return 0; + } + + c->oom_score_adjust = oa; + c->oom_score_adjust_set = true; + + return 0; +} + +int config_parse_exec( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + ExecCommand **e = data, *nce; + char *path, **n; + unsigned k; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(e); + + /* We accept an absolute path as first argument, or + * alternatively an absolute prefixed with @ to allow + * overriding of argv[0]. */ + + e += ltype; + + for (;;) { + int i; + char *w; + size_t l; + char *state; + bool honour_argv0 = false, ignore = false; + + path = NULL; + nce = NULL; + n = NULL; + + rvalue += strspn(rvalue, WHITESPACE); + + if (rvalue[0] == 0) + break; + + for (i = 0; i < 2; i++) { + if (rvalue[0] == '-' && !ignore) { + ignore = true; + rvalue ++; + } + + if (rvalue[0] == '@' && !honour_argv0) { + honour_argv0 = true; + rvalue ++; + } + } + + if (*rvalue != '/') { + log_error("[%s:%u] Executable path is not absolute, ignoring: %s", + filename, line, rvalue); + return 0; + } + + k = 0; + FOREACH_WORD_QUOTED(w, l, rvalue, state) { + if (strncmp(w, ";", MAX(l, 1U)) == 0) + break; + + k++; + } + + n = new(char*, k + !honour_argv0); + if (!n) + return -ENOMEM; + + k = 0; + FOREACH_WORD_QUOTED(w, l, rvalue, state) { + if (strncmp(w, ";", MAX(l, 1U)) == 0) + break; + else if (strncmp(w, "\\;", MAX(l, 1U)) == 0) + w ++; + + if (honour_argv0 && w == rvalue) { + assert(!path); + + path = strndup(w, l); + if (!path) { + r = -ENOMEM; + goto fail; + } + + if (!utf8_is_valid(path)) { + log_error("[%s:%u] Path is not UTF-8 clean, ignoring assignment: %s", filename, line, rvalue); + r = 0; + goto fail; + } + + } else { + char *c; + + c = n[k++] = cunescape_length(w, l); + if (!c) { + r = -ENOMEM; + goto fail; + } + + if (!utf8_is_valid(c)) { + log_error("[%s:%u] Path is not UTF-8 clean, ignoring assignment: %s", filename, line, rvalue); + r = 0; + goto fail; + } + } + } + + n[k] = NULL; + + if (!n[0]) { + log_error("[%s:%u] Invalid command line, ignoring: %s", filename, line, rvalue); + r = 0; + goto fail; + } + + if (!path) { + path = strdup(n[0]); + if (!path) { + r = -ENOMEM; + goto fail; + } + } + + assert(path_is_absolute(path)); + + nce = new0(ExecCommand, 1); + if (!nce) { + r = -ENOMEM; + goto fail; + } + + nce->argv = n; + nce->path = path; + nce->ignore = ignore; + + path_kill_slashes(nce->path); + + exec_command_append_list(e, nce); + + rvalue = state; + } + + return 0; + +fail: + n[k] = NULL; + strv_free(n); + free(path); + free(nce); + + return r; +} + +DEFINE_CONFIG_PARSE_ENUM(config_parse_service_type, service_type, ServiceType, "Failed to parse service type"); +DEFINE_CONFIG_PARSE_ENUM(config_parse_service_restart, service_restart, ServiceRestart, "Failed to parse service restart specifier"); + +int config_parse_socket_bindtodevice( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + Socket *s = data; + char *n; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if (rvalue[0] && !streq(rvalue, "*")) { + if (!(n = strdup(rvalue))) + return -ENOMEM; + } else + n = NULL; + + free(s->bind_to_device); + s->bind_to_device = n; + + return 0; +} + +DEFINE_CONFIG_PARSE_ENUM(config_parse_output, exec_output, ExecOutput, "Failed to parse output specifier"); +DEFINE_CONFIG_PARSE_ENUM(config_parse_input, exec_input, ExecInput, "Failed to parse input specifier"); + +int config_parse_exec_io_class( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + ExecContext *c = data; + int x; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + x = ioprio_class_from_string(rvalue); + if (x < 0) { + log_error("[%s:%u] Failed to parse IO scheduling class, ignoring: %s", filename, line, rvalue); + return 0; + } + + c->ioprio = IOPRIO_PRIO_VALUE(x, IOPRIO_PRIO_DATA(c->ioprio)); + c->ioprio_set = true; + + return 0; +} + +int config_parse_exec_io_priority( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + ExecContext *c = data; + int i; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if (safe_atoi(rvalue, &i) < 0 || i < 0 || i >= IOPRIO_BE_NR) { + log_error("[%s:%u] Failed to parse io priority, ignoring: %s", filename, line, rvalue); + return 0; + } + + c->ioprio = IOPRIO_PRIO_VALUE(IOPRIO_PRIO_CLASS(c->ioprio), i); + c->ioprio_set = true; + + return 0; +} + +int config_parse_exec_cpu_sched_policy( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + + ExecContext *c = data; + int x; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + x = sched_policy_from_string(rvalue); + if (x < 0) { + log_error("[%s:%u] Failed to parse CPU scheduling policy, ignoring: %s", filename, line, rvalue); + return 0; + } + + c->cpu_sched_policy = x; + /* Moving to or from real-time policy? We need to adjust the priority */ + c->cpu_sched_priority = CLAMP(c->cpu_sched_priority, sched_get_priority_min(x), sched_get_priority_max(x)); + c->cpu_sched_set = true; + + return 0; +} + +int config_parse_exec_cpu_sched_prio( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + ExecContext *c = data; + int i, min, max; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if (safe_atoi(rvalue, &i) < 0) { + log_error("[%s:%u] Failed to parse CPU scheduling priority, ignoring: %s", filename, line, rvalue); + return 0; + } + + + /* On Linux RR/FIFO range from 1 to 99 and OTHER/BATCH may only be 0 */ + min = sched_get_priority_min(c->cpu_sched_policy); + max = sched_get_priority_max(c->cpu_sched_policy); + + if (i < min || i > max) { + log_error("[%s:%u] CPU scheduling priority is out of range, ignoring: %s", filename, line, rvalue); + return 0; + } + + c->cpu_sched_priority = i; + c->cpu_sched_set = true; + + return 0; +} + +int config_parse_exec_cpu_affinity( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + ExecContext *c = data; + char *w; + size_t l; + char *state; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + FOREACH_WORD_QUOTED(w, l, rvalue, state) { + char _cleanup_free_ *t = NULL; + int r; + unsigned cpu; + + t = strndup(w, l); + if (!t) + return -ENOMEM; + + r = safe_atou(t, &cpu); + + if (!c->cpuset) { + c->cpuset = cpu_set_malloc(&c->cpuset_ncpus); + if (!c->cpuset) + return -ENOMEM; + } + + if (r < 0 || cpu >= c->cpuset_ncpus) { + log_error("[%s:%u] Failed to parse CPU affinity %s, ignoring: %s", + filename, line, t, rvalue); + return 0; + } + + CPU_SET_S(cpu, CPU_ALLOC_SIZE(c->cpuset_ncpus), c->cpuset); + } + + return 0; +} + +int config_parse_exec_capabilities( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + ExecContext *c = data; + cap_t cap; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if (!(cap = cap_from_text(rvalue))) { + if (errno == ENOMEM) + return -ENOMEM; + + log_error("[%s:%u] Failed to parse capabilities, ignoring: %s", filename, line, rvalue); + return 0; + } + + if (c->capabilities) + cap_free(c->capabilities); + c->capabilities = cap; + + return 0; +} + +int config_parse_exec_secure_bits( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + ExecContext *c = data; + char *w; + size_t l; + char *state; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + FOREACH_WORD_QUOTED(w, l, rvalue, state) { + if (first_word(w, "keep-caps")) + c->secure_bits |= SECURE_KEEP_CAPS; + else if (first_word(w, "keep-caps-locked")) + c->secure_bits |= SECURE_KEEP_CAPS_LOCKED; + else if (first_word(w, "no-setuid-fixup")) + c->secure_bits |= SECURE_NO_SETUID_FIXUP; + else if (first_word(w, "no-setuid-fixup-locked")) + c->secure_bits |= SECURE_NO_SETUID_FIXUP_LOCKED; + else if (first_word(w, "noroot")) + c->secure_bits |= SECURE_NOROOT; + else if (first_word(w, "noroot-locked")) + c->secure_bits |= SECURE_NOROOT_LOCKED; + else { + log_error("[%s:%u] Failed to parse secure bits, ignoring: %s", + filename, line, rvalue); + return 0; + } + } + + return 0; +} + +int config_parse_bounding_set( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + uint64_t *capability_bounding_set_drop = data; + char *w; + size_t l; + char *state; + bool invert = false; + uint64_t sum = 0; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if (rvalue[0] == '~') { + invert = true; + rvalue++; + } + + /* Note that we store this inverted internally, since the + * kernel wants it like this. But we actually expose it + * non-inverted everywhere to have a fully normalized + * interface. */ + + FOREACH_WORD_QUOTED(w, l, rvalue, state) { + char _cleanup_free_ *t = NULL; + int r; + cap_value_t cap; + + t = strndup(w, l); + if (!t) + return -ENOMEM; + + r = cap_from_name(t, &cap); + if (r < 0) { + log_error("[%s:%u] Failed to parse capability in bounding set, ignoring: %s", + filename, line, t); + continue; + } + + sum |= ((uint64_t) 1ULL) << (uint64_t) cap; + } + + if (invert) + *capability_bounding_set_drop |= sum; + else + *capability_bounding_set_drop |= ~sum; + + return 0; +} + +int config_parse_limit( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + struct rlimit **rl = data; + unsigned long long u; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + rl += ltype; + + if (streq(rvalue, "infinity")) + u = (unsigned long long) RLIM_INFINITY; + else if (safe_atollu(rvalue, &u) < 0) { + log_error("[%s:%u] Failed to parse resource value, ignoring: %s", filename, line, rvalue); + return 0; + } + + if (!*rl) + if (!(*rl = new(struct rlimit, 1))) + return -ENOMEM; + + (*rl)->rlim_cur = (*rl)->rlim_max = (rlim_t) u; + return 0; +} + +int config_parse_unit_cgroup( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + Unit *u = userdata; + char *w; + size_t l; + char *state; + + FOREACH_WORD_QUOTED(w, l, rvalue, state) { + char _cleanup_free_ *t = NULL, *k = NULL, *ku = NULL; + int r; + + t = strndup(w, l); + if (!t) + return -ENOMEM; + + k = unit_full_printf(u, t); + if (!k) + return -ENOMEM; + + ku = cunescape(k); + if (!ku) + return -ENOMEM; + + r = unit_add_cgroup_from_text(u, ku); + if (r < 0) { + log_error("[%s:%u] Failed to parse cgroup value %s, ignoring: %s", + filename, line, k, rvalue); + return 0; + } + } + + return 0; +} + +#ifdef HAVE_SYSV_COMPAT +int config_parse_sysv_priority( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + int *priority = data; + int i; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if (safe_atoi(rvalue, &i) < 0 || i < 0) { + log_error("[%s:%u] Failed to parse SysV start priority, ignoring: %s", filename, line, rvalue); + return 0; + } + + *priority = (int) i; + return 0; +} +#endif + +int config_parse_fsck_passno( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + int *passno = data; + int i; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if (safe_atoi(rvalue, &i) || i < 0) { + log_error("[%s:%u] Failed to parse fsck pass number, ignoring: %s", filename, line, rvalue); + return 0; + } + + *passno = (int) i; + return 0; +} + +DEFINE_CONFIG_PARSE_ENUM(config_parse_kill_mode, kill_mode, KillMode, "Failed to parse kill mode"); + +int config_parse_kill_signal( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + int *sig = data; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(sig); + + if ((r = signal_from_string_try_harder(rvalue)) <= 0) { + log_error("[%s:%u] Failed to parse kill signal, ignoring: %s", filename, line, rvalue); + return 0; + } + + *sig = r; + return 0; +} + +int config_parse_exec_mount_flags( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + ExecContext *c = data; + char *w; + size_t l; + char *state; + unsigned long flags = 0; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + FOREACH_WORD_SEPARATOR(w, l, rvalue, ", ", state) { + char _cleanup_free_ *t; + + t = strndup(w, l); + if (!t) + return -ENOMEM; + + if (streq(t, "shared")) + flags |= MS_SHARED; + else if (streq(t, "slave")) + flags |= MS_SLAVE; + else if (streq(w, "private")) + flags |= MS_PRIVATE; + else { + log_error("[%s:%u] Failed to parse mount flag %s, ignoring: %s", + filename, line, t, rvalue); + return 0; + } + } + + c->mount_flags = flags; + return 0; +} + +int config_parse_timer( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + Timer *t = data; + usec_t u = 0; + TimerValue *v; + TimerBase b; + CalendarSpec *c = NULL; + clockid_t id; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + b = timer_base_from_string(lvalue); + if (b < 0) { + log_error("[%s:%u] Failed to parse timer base, ignoring: %s", filename, line, lvalue); + return 0; + } + + if (b == TIMER_CALENDAR) { + if (calendar_spec_from_string(rvalue, &c) < 0) { + log_error("[%s:%u] Failed to parse calendar specification, ignoring: %s", filename, line, rvalue); + return 0; + } + + id = CLOCK_REALTIME; + } else { + if (parse_usec(rvalue, &u) < 0) { + log_error("[%s:%u] Failed to parse timer value, ignoring: %s", filename, line, rvalue); + return 0; + } + + id = CLOCK_MONOTONIC; + } + + v = new0(TimerValue, 1); + if (!v) + return -ENOMEM; + + v->base = b; + v->clock_id = id; + v->value = u; + v->calendar_spec = c; + + LIST_PREPEND(TimerValue, value, t->values, v); + + return 0; +} + +int config_parse_timer_unit( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + Timer *t = data; + int r; + DBusError error; + Unit *u; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + dbus_error_init(&error); + + if (endswith(rvalue, ".timer")) { + log_error("[%s:%u] Unit cannot be of type timer, ignoring: %s", filename, line, rvalue); + return 0; + } + + r = manager_load_unit(UNIT(t)->manager, rvalue, NULL, NULL, &u); + if (r < 0) { + log_error("[%s:%u] Failed to load unit %s, ignoring: %s", filename, line, rvalue, bus_error(&error, r)); + dbus_error_free(&error); + return 0; + } + + unit_ref_set(&t->unit, u); + + return 0; +} + +int config_parse_path_spec( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + Path *p = data; + PathSpec *s; + PathType b; + char *k; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + b = path_type_from_string(lvalue); + if (b < 0) { + log_error("[%s:%u] Failed to parse path type, ignoring: %s", filename, line, lvalue); + return 0; + } + + k = unit_full_printf(UNIT(p), rvalue); + if (!k) + return log_oom(); + + if (!path_is_absolute(k)) { + log_error("[%s:%u] Path is not absolute, ignoring: %s", filename, line, k); + free(k); + return 0; + } + + s = new0(PathSpec, 1); + if (!s) { + free(k); + return log_oom(); + } + + s->path = path_kill_slashes(k); + s->type = b; + s->inotify_fd = -1; + + LIST_PREPEND(PathSpec, spec, p->specs, s); + + return 0; +} + +int config_parse_path_unit( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + Path *t = data; + int r; + DBusError error; + Unit *u; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + dbus_error_init(&error); + + if (endswith(rvalue, ".path")) { + log_error("[%s:%u] Unit cannot be of type path, ignoring: %s", filename, line, rvalue); + return 0; + } + + if ((r = manager_load_unit(UNIT(t)->manager, rvalue, NULL, &error, &u)) < 0) { + log_error("[%s:%u] Failed to load unit %s, ignoring: %s", filename, line, rvalue, bus_error(&error, r)); + dbus_error_free(&error); + return 0; + } + + unit_ref_set(&t->unit, u); + + return 0; +} + +int config_parse_socket_service( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + Socket *s = data; + int r; + DBusError error; + Unit *x; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + dbus_error_init(&error); + + if (!endswith(rvalue, ".service")) { + log_error("[%s:%u] Unit must be of type service, ignoring: %s", filename, line, rvalue); + return 0; + } + + r = manager_load_unit(UNIT(s)->manager, rvalue, NULL, &error, &x); + if (r < 0) { + log_error("[%s:%u] Failed to load unit %s, ignoring: %s", filename, line, rvalue, bus_error(&error, r)); + dbus_error_free(&error); + return 0; + } + + unit_ref_set(&s->service, x); + + return 0; +} + +int config_parse_service_sockets( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + Service *s = data; + int r; + char *state, *w; + size_t l; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + FOREACH_WORD_QUOTED(w, l, rvalue, state) { + char _cleanup_free_ *t = NULL, *k = NULL; + + t = strndup(w, l); + if (!t) + return -ENOMEM; + + k = unit_name_printf(UNIT(s), t); + if (!k) + return -ENOMEM; + + if (!endswith(k, ".socket")) { + log_error("[%s:%u] Unit must be of type socket, ignoring: %s", + filename, line, k); + continue; + } + + r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_WANTS, UNIT_AFTER, k, NULL, true); + if (r < 0) + log_error("[%s:%u] Failed to add dependency on %s, ignoring: %s", + filename, line, k, strerror(-r)); + + r = unit_add_dependency_by_name(UNIT(s), UNIT_TRIGGERED_BY, k, NULL, true); + if (r < 0) + return r; + } + + return 0; +} + +int config_parse_service_timeout( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + Service *s = userdata; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(s); + + r = config_parse_usec(filename, line, section, lvalue, ltype, rvalue, data, userdata); + + if (r) + return r; + + if (streq(lvalue, "TimeoutSec")) { + s->start_timeout_defined = true; + s->timeout_stop_usec = s->timeout_start_usec; + } else if (streq(lvalue, "TimeoutStartSec")) + s->start_timeout_defined = true; + + return 0; +} + +int config_parse_unit_env_file( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + char ***env = data, **k; + Unit *u = userdata; + char *s; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + s = unit_full_printf(u, rvalue); + if (!s) + return -ENOMEM; + + if (!path_is_absolute(s[0] == '-' ? s + 1 : s)) { + log_error("[%s:%u] Path '%s' is not absolute, ignoring.", filename, line, s); + free(s); + return 0; + } + + k = strv_append(*env, s); + free(s); + if (!k) + return -ENOMEM; + + strv_free(*env); + *env = k; + + return 0; +} + +int config_parse_ip_tos( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + int *ip_tos = data, x; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + x = ip_tos_from_string(rvalue); + if (x < 0) { + log_error("[%s:%u] Failed to parse IP TOS value, ignoring: %s", filename, line, rvalue); + return 0; + } + + *ip_tos = x; + return 0; +} + +int config_parse_unit_condition_path( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + ConditionType cond = ltype; + Unit *u = data; + bool trigger, negate; + Condition *c; + _cleanup_free_ char *p = NULL; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + trigger = rvalue[0] == '|'; + if (trigger) + rvalue++; + + negate = rvalue[0] == '!'; + if (negate) + rvalue++; + + p = unit_full_printf(u, rvalue); + if (!p) + return -ENOMEM; + + if (!path_is_absolute(p)) { + log_error("[%s:%u] Path in condition not absolute, ignoring: %s", filename, line, p); + return 0; + } + + c = condition_new(cond, p, trigger, negate); + if (!c) + return -ENOMEM; + + LIST_PREPEND(Condition, conditions, u->conditions, c); + return 0; +} + +int config_parse_unit_condition_string( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + ConditionType cond = ltype; + Unit *u = data; + bool trigger, negate; + Condition *c; + _cleanup_free_ char *s = NULL; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + trigger = rvalue[0] == '|'; + if (trigger) + rvalue++; + + negate = rvalue[0] == '!'; + if (negate) + rvalue++; + + s = unit_full_printf(u, rvalue); + if (!s) + return -ENOMEM; + + c = condition_new(cond, s, trigger, negate); + if (!c) + return log_oom(); + + LIST_PREPEND(Condition, conditions, u->conditions, c); + return 0; +} + +int config_parse_unit_condition_null( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + Unit *u = data; + Condition *c; + bool trigger, negate; + int b; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if ((trigger = rvalue[0] == '|')) + rvalue++; + + if ((negate = rvalue[0] == '!')) + rvalue++; + + if ((b = parse_boolean(rvalue)) < 0) { + log_error("[%s:%u] Failed to parse boolean value in condition, ignoring: %s", filename, line, rvalue); + return 0; + } + + if (!b) + negate = !negate; + + if (!(c = condition_new(CONDITION_NULL, NULL, trigger, negate))) + return -ENOMEM; + + LIST_PREPEND(Condition, conditions, u->conditions, c); + return 0; +} + +DEFINE_CONFIG_PARSE_ENUM(config_parse_notify_access, notify_access, NotifyAccess, "Failed to parse notify access specifier"); +DEFINE_CONFIG_PARSE_ENUM(config_parse_start_limit_action, start_limit_action, StartLimitAction, "Failed to parse start limit action specifier"); + +int config_parse_unit_cgroup_attr( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + Unit *u = data; + char **l; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + l = strv_split_quoted(rvalue); + if (!l) + return -ENOMEM; + + if (strv_length(l) != 2) { + log_error("[%s:%u] Failed to parse cgroup attribute value, ignoring: %s", filename, line, rvalue); + strv_free(l); + return 0; + } + + r = unit_add_cgroup_attribute(u, NULL, l[0], l[1], NULL); + strv_free(l); + + if (r < 0) { + log_error("[%s:%u] Failed to add cgroup attribute value, ignoring: %s", filename, line, rvalue); + return 0; + } + + return 0; +} + +int config_parse_unit_cpu_shares(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata) { + Unit *u = data; + int r; + unsigned long ul; + char *t; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if (safe_atolu(rvalue, &ul) < 0 || ul < 1) { + log_error("[%s:%u] Failed to parse CPU shares value, ignoring: %s", filename, line, rvalue); + return 0; + } + + if (asprintf(&t, "%lu", ul) < 0) + return -ENOMEM; + + r = unit_add_cgroup_attribute(u, "cpu", "cpu.shares", t, NULL); + free(t); + + if (r < 0) { + log_error("[%s:%u] Failed to add cgroup attribute value, ignoring: %s", filename, line, rvalue); + return 0; + } + + return 0; +} + +int config_parse_unit_memory_limit(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata) { + Unit *u = data; + int r; + off_t sz; + char *t; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if (parse_bytes(rvalue, &sz) < 0 || sz <= 0) { + log_error("[%s:%u] Failed to parse memory limit value, ignoring: %s", filename, line, rvalue); + return 0; + } + + if (asprintf(&t, "%llu", (unsigned long long) sz) < 0) + return -ENOMEM; + + r = unit_add_cgroup_attribute(u, + "memory", + streq(lvalue, "MemorySoftLimit") ? "memory.soft_limit_in_bytes" : "memory.limit_in_bytes", + t, NULL); + free(t); + + if (r < 0) { + log_error("[%s:%u] Failed to add cgroup attribute value, ignoring: %s", filename, line, rvalue); + return 0; + } + + return 0; +} + +static int device_map(const char *controller, const char *name, const char *value, char **ret) { + char **l; + + assert(controller); + assert(name); + assert(value); + assert(ret); + + l = strv_split_quoted(value); + if (!l) + return -ENOMEM; + + assert(strv_length(l) >= 1); + + if (streq(l[0], "*")) { + + if (asprintf(ret, "a *:*%s%s", + isempty(l[1]) ? "" : " ", strempty(l[1])) < 0) { + strv_free(l); + return -ENOMEM; + } + + } else { + struct stat st; + + if (stat(l[0], &st) < 0) { + log_warning("Couldn't stat device %s", l[0]); + strv_free(l); + return -errno; + } + + if (!S_ISCHR(st.st_mode) && !S_ISBLK(st.st_mode)) { + log_warning("%s is not a device.", l[0]); + strv_free(l); + return -ENODEV; + } + + if (asprintf(ret, "%c %u:%u%s%s", + S_ISCHR(st.st_mode) ? 'c' : 'b', + major(st.st_rdev), minor(st.st_rdev), + isempty(l[1]) ? "" : " ", strempty(l[1])) < 0) { + + strv_free(l); + return -ENOMEM; + } + } + + strv_free(l); + return 0; +} + +int config_parse_unit_device_allow(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata) { + Unit *u = data; + char **l; + int r; + unsigned k; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + l = strv_split_quoted(rvalue); + if (!l) + return -ENOMEM; + + k = strv_length(l); + if (k < 1 || k > 2) { + log_error("[%s:%u] Failed to parse device value, ignoring: %s", filename, line, rvalue); + strv_free(l); + return 0; + } + + if (!streq(l[0], "*") && !path_startswith(l[0], "/dev")) { + log_error("[%s:%u] Device node path not absolute, ignoring: %s", filename, line, rvalue); + strv_free(l); + return 0; + } + + if (!isempty(l[1]) && !in_charset(l[1], "rwm")) { + log_error("[%s:%u] Device access string invalid, ignoring: %s", filename, line, rvalue); + strv_free(l); + return 0; + } + strv_free(l); + + r = unit_add_cgroup_attribute(u, "devices", + streq(lvalue, "DeviceAllow") ? "devices.allow" : "devices.deny", + rvalue, device_map); + + if (r < 0) { + log_error("[%s:%u] Failed to add cgroup attribute value, ignoring: %s", filename, line, rvalue); + return 0; + } + + return 0; +} + +static int blkio_map(const char *controller, const char *name, const char *value, char **ret) { + struct stat st; + char **l; + dev_t d; + + assert(controller); + assert(name); + assert(value); + assert(ret); + + l = strv_split_quoted(value); + if (!l) + return -ENOMEM; + + assert(strv_length(l) == 2); + + if (stat(l[0], &st) < 0) { + log_warning("Couldn't stat device %s", l[0]); + strv_free(l); + return -errno; + } + + if (S_ISBLK(st.st_mode)) + d = st.st_rdev; + else if (major(st.st_dev) != 0) { + /* If this is not a device node then find the block + * device this file is stored on */ + d = st.st_dev; + + /* If this is a partition, try to get the originating + * block device */ + block_get_whole_disk(d, &d); + } else { + log_warning("%s is not a block device and file system block device cannot be determined or is not local.", l[0]); + strv_free(l); + return -ENODEV; + } + + if (asprintf(ret, "%u:%u %s", major(d), minor(d), l[1]) < 0) { + strv_free(l); + return -ENOMEM; + } + + strv_free(l); + return 0; +} + +int config_parse_unit_blkio_weight(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata) { + Unit *u = data; + int r; + unsigned long ul; + const char *device = NULL, *weight; + unsigned k; + char *t, **l; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + l = strv_split_quoted(rvalue); + if (!l) + return -ENOMEM; + + k = strv_length(l); + if (k < 1 || k > 2) { + log_error("[%s:%u] Failed to parse weight value, ignoring: %s", filename, line, rvalue); + strv_free(l); + return 0; + } + + if (k == 1) + weight = l[0]; + else { + device = l[0]; + weight = l[1]; + } + + if (device && !path_is_absolute(device)) { + log_error("[%s:%u] Failed to parse block device node value, ignoring: %s", filename, line, rvalue); + strv_free(l); + return 0; + } + + if (safe_atolu(weight, &ul) < 0 || ul < 10 || ul > 1000) { + log_error("[%s:%u] Failed to parse block IO weight value, ignoring: %s", filename, line, rvalue); + strv_free(l); + return 0; + } + + if (device) + r = asprintf(&t, "%s %lu", device, ul); + else + r = asprintf(&t, "%lu", ul); + strv_free(l); + + if (r < 0) + return -ENOMEM; + + if (device) + r = unit_add_cgroup_attribute(u, "blkio", "blkio.weight_device", t, blkio_map); + else + r = unit_add_cgroup_attribute(u, "blkio", "blkio.weight", t, NULL); + free(t); + + if (r < 0) { + log_error("[%s:%u] Failed to add cgroup attribute value, ignoring: %s", filename, line, rvalue); + return 0; + } + + return 0; +} + +int config_parse_unit_blkio_bandwidth(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata) { + Unit *u = data; + int r; + off_t bytes; + unsigned k; + char *t, **l; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + l = strv_split_quoted(rvalue); + if (!l) + return -ENOMEM; + + k = strv_length(l); + if (k != 2) { + log_error("[%s:%u] Failed to parse bandwidth value, ignoring: %s", filename, line, rvalue); + strv_free(l); + return 0; + } + + if (!path_is_absolute(l[0])) { + log_error("[%s:%u] Failed to parse block device node value, ignoring: %s", filename, line, rvalue); + strv_free(l); + return 0; + } + + if (parse_bytes(l[1], &bytes) < 0 || bytes <= 0) { + log_error("[%s:%u] Failed to parse block IO bandwidth value, ignoring: %s", filename, line, rvalue); + strv_free(l); + return 0; + } + + r = asprintf(&t, "%s %llu", l[0], (unsigned long long) bytes); + strv_free(l); + + if (r < 0) + return -ENOMEM; + + r = unit_add_cgroup_attribute(u, "blkio", + streq(lvalue, "BlockIOReadBandwidth") ? "blkio.read_bps_device" : "blkio.write_bps_device", + t, blkio_map); + free(t); + + if (r < 0) { + log_error("[%s:%u] Failed to add cgroup attribute value, ignoring: %s", filename, line, rvalue); + return 0; + } + + return 0; +} + +int config_parse_unit_requires_mounts_for( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + Unit *u = userdata; + int r; + bool empty_before; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + empty_before = !u->requires_mounts_for; + + r = config_parse_path_strv(filename, line, section, lvalue, ltype, rvalue, data, userdata); + + /* Make it easy to find units with requires_mounts set */ + if (empty_before && u->requires_mounts_for) + LIST_PREPEND(Unit, has_requires_mounts_for, u->manager->has_requires_mounts_for, u); + + return r; +} + +int config_parse_documentation( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + Unit *u = userdata; + int r; + char **a, **b; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(u); + + r = config_parse_unit_strv_printf(filename, line, section, lvalue, ltype, rvalue, data, userdata); + if (r < 0) + return r; + + for (a = b = u->documentation; a && *a; a++) { + + if (is_valid_documentation_url(*a)) + *(b++) = *a; + else { + log_error("[%s:%u] Invalid URL, ignoring: %s", filename, line, *a); + free(*a); + } + } + *b = NULL; + + return r; +} + +static void syscall_set(uint32_t *p, int nr) { + p[nr >> 4] |= 1 << (nr & 31); +} + +static void syscall_unset(uint32_t *p, int nr) { + p[nr >> 4] &= ~(1 << (nr & 31)); +} + +int config_parse_syscall_filter( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + ExecContext *c = data; + Unit *u = userdata; + bool invert = false; + char *w; + size_t l; + char *state; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(u); + + if (rvalue[0] == '~') { + invert = true; + rvalue++; + } + + if (!c->syscall_filter) { + size_t n; + + n = (syscall_max() + 31) >> 4; + c->syscall_filter = new(uint32_t, n); + if (!c->syscall_filter) + return -ENOMEM; + + memset(c->syscall_filter, invert ? 0xFF : 0, n * sizeof(uint32_t)); + + /* Add these by default */ + syscall_set(c->syscall_filter, __NR_execve); + syscall_set(c->syscall_filter, __NR_rt_sigreturn); +#ifdef __NR_sigreturn + syscall_set(c->syscall_filter, __NR_sigreturn); +#endif + syscall_set(c->syscall_filter, __NR_exit_group); + syscall_set(c->syscall_filter, __NR_exit); + } + + FOREACH_WORD_QUOTED(w, l, rvalue, state) { + int id; + char _cleanup_free_ *t = NULL; + + t = strndup(w, l); + if (!t) + return -ENOMEM; + + id = syscall_from_name(t); + + if (id < 0) { + log_error("[%s:%u] Failed to parse syscall, ignoring: %s", + filename, line, t); + continue; + } + + if (invert) + syscall_unset(c->syscall_filter, id); + else + syscall_set(c->syscall_filter, id); + } + + c->no_new_privileges = true; + + return 0; +} + +#define FOLLOW_MAX 8 + +static int open_follow(char **filename, FILE **_f, Set *names, char **_final) { + unsigned c = 0; + int fd, r; + FILE *f; + char *id = NULL; + + assert(filename); + assert(*filename); + assert(_f); + assert(names); + + /* This will update the filename pointer if the loaded file is + * reached by a symlink. The old string will be freed. */ + + for (;;) { + char *target, *name; + + if (c++ >= FOLLOW_MAX) + return -ELOOP; + + path_kill_slashes(*filename); + + /* Add the file name we are currently looking at to + * the names of this unit, but only if it is a valid + * unit name. */ + name = path_get_file_name(*filename); + + if (unit_name_is_valid(name, true)) { + + id = set_get(names, name); + if (!id) { + id = strdup(name); + if (!id) + return -ENOMEM; + + r = set_put(names, id); + if (r < 0) { + free(id); + return r; + } + } + } + + /* Try to open the file name, but don't if its a symlink */ + fd = open(*filename, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW); + if (fd >= 0) + break; + + if (errno != ELOOP) + return -errno; + + /* Hmm, so this is a symlink. Let's read the name, and follow it manually */ + r = readlink_and_make_absolute(*filename, &target); + if (r < 0) + return r; + + free(*filename); + *filename = target; + } + + f = fdopen(fd, "re"); + if (!f) { + r = -errno; + close_nointr_nofail(fd); + return r; + } + + *_f = f; + *_final = id; + return 0; +} + +static int merge_by_names(Unit **u, Set *names, const char *id) { + char *k; + int r; + + assert(u); + assert(*u); + assert(names); + + /* Let's try to add in all symlink names we found */ + while ((k = set_steal_first(names))) { + + /* First try to merge in the other name into our + * unit */ + r = unit_merge_by_name(*u, k); + if (r < 0) { + Unit *other; + + /* Hmm, we couldn't merge the other unit into + * ours? Then let's try it the other way + * round */ + + other = manager_get_unit((*u)->manager, k); + free(k); + + if (other) { + r = unit_merge(other, *u); + if (r >= 0) { + *u = other; + return merge_by_names(u, names, NULL); + } + } + + return r; + } + + if (id == k) + unit_choose_id(*u, id); + + free(k); + } + + return 0; +} + +static int load_from_path(Unit *u, const char *path) { + int r; + Set *symlink_names; + FILE *f = NULL; + char *filename = NULL, *id = NULL; + Unit *merged; + struct stat st; + + assert(u); + assert(path); + + symlink_names = set_new(string_hash_func, string_compare_func); + if (!symlink_names) + return -ENOMEM; + + if (path_is_absolute(path)) { + + filename = strdup(path); + if (!filename) { + r = -ENOMEM; + goto finish; + } + + r = open_follow(&filename, &f, symlink_names, &id); + if (r < 0) { + free(filename); + filename = NULL; + + if (r != -ENOENT) + goto finish; + } + + } else { + char **p; + + STRV_FOREACH(p, u->manager->lookup_paths.unit_path) { + + /* Instead of opening the path right away, we manually + * follow all symlinks and add their name to our unit + * name set while doing so */ + filename = path_make_absolute(path, *p); + if (!filename) { + r = -ENOMEM; + goto finish; + } + + if (u->manager->unit_path_cache && + !set_get(u->manager->unit_path_cache, filename)) + r = -ENOENT; + else + r = open_follow(&filename, &f, symlink_names, &id); + + if (r < 0) { + free(filename); + filename = NULL; + + if (r != -ENOENT) + goto finish; + + /* Empty the symlink names for the next run */ + set_clear_free(symlink_names); + continue; + } + + break; + } + } + + if (!filename) { + /* Hmm, no suitable file found? */ + r = 0; + goto finish; + } + + merged = u; + r = merge_by_names(&merged, symlink_names, id); + if (r < 0) + goto finish; + + if (merged != u) { + u->load_state = UNIT_MERGED; + r = 0; + goto finish; + } + + if (fstat(fileno(f), &st) < 0) { + r = -errno; + goto finish; + } + + if (null_or_empty(&st)) + u->load_state = UNIT_MASKED; + else { + /* Now, parse the file contents */ + r = config_parse(filename, f, UNIT_VTABLE(u)->sections, config_item_perf_lookup, (void*) load_fragment_gperf_lookup, false, u); + if (r < 0) + goto finish; + + u->load_state = UNIT_LOADED; + } + + free(u->fragment_path); + u->fragment_path = filename; + filename = NULL; + + u->fragment_mtime = timespec_load(&st.st_mtim); + + if (u->source_path) { + if (stat(u->source_path, &st) >= 0) + u->source_mtime = timespec_load(&st.st_mtim); + else + u->source_mtime = 0; + } + + r = 0; + +finish: + set_free_free(symlink_names); + free(filename); + + if (f) + fclose(f); + + return r; +} + +int unit_load_fragment(Unit *u) { + int r; + Iterator i; + const char *t; + + assert(u); + assert(u->load_state == UNIT_STUB); + assert(u->id); + + /* First, try to find the unit under its id. We always look + * for unit files in the default directories, to make it easy + * to override things by placing things in /etc/systemd/system */ + r = load_from_path(u, u->id); + if (r < 0) + return r; + + /* Try to find an alias we can load this with */ + if (u->load_state == UNIT_STUB) + SET_FOREACH(t, u->names, i) { + + if (t == u->id) + continue; + + r = load_from_path(u, t); + if (r < 0) + return r; + + if (u->load_state != UNIT_STUB) + break; + } + + /* And now, try looking for it under the suggested (originally linked) path */ + if (u->load_state == UNIT_STUB && u->fragment_path) { + + r = load_from_path(u, u->fragment_path); + if (r < 0) + return r; + + if (u->load_state == UNIT_STUB) { + /* Hmm, this didn't work? Then let's get rid + * of the fragment path stored for us, so that + * we don't point to an invalid location. */ + free(u->fragment_path); + u->fragment_path = NULL; + } + } + + /* Look for a template */ + if (u->load_state == UNIT_STUB && u->instance) { + char *k; + + k = unit_name_template(u->id); + if (!k) + return -ENOMEM; + + r = load_from_path(u, k); + free(k); + + if (r < 0) + return r; + + if (u->load_state == UNIT_STUB) + SET_FOREACH(t, u->names, i) { + + if (t == u->id) + continue; + + k = unit_name_template(t); + if (!k) + return -ENOMEM; + + r = load_from_path(u, k); + free(k); + + if (r < 0) + return r; + + if (u->load_state != UNIT_STUB) + break; + } + } + + return 0; +} + +void unit_dump_config_items(FILE *f) { + static const struct { + const ConfigParserCallback callback; + const char *rvalue; + } table[] = { + { config_parse_int, "INTEGER" }, + { config_parse_unsigned, "UNSIGNED" }, + { config_parse_bytes_size, "SIZE" }, + { config_parse_bool, "BOOLEAN" }, + { config_parse_string, "STRING" }, + { config_parse_path, "PATH" }, + { config_parse_unit_path_printf, "PATH" }, + { config_parse_strv, "STRING [...]" }, + { config_parse_exec_nice, "NICE" }, + { config_parse_exec_oom_score_adjust, "OOMSCOREADJUST" }, + { config_parse_exec_io_class, "IOCLASS" }, + { config_parse_exec_io_priority, "IOPRIORITY" }, + { config_parse_exec_cpu_sched_policy, "CPUSCHEDPOLICY" }, + { config_parse_exec_cpu_sched_prio, "CPUSCHEDPRIO" }, + { config_parse_exec_cpu_affinity, "CPUAFFINITY" }, + { config_parse_mode, "MODE" }, + { config_parse_unit_env_file, "FILE" }, + { config_parse_output, "OUTPUT" }, + { config_parse_input, "INPUT" }, + { config_parse_facility, "FACILITY" }, + { config_parse_level, "LEVEL" }, + { config_parse_exec_capabilities, "CAPABILITIES" }, + { config_parse_exec_secure_bits, "SECUREBITS" }, + { config_parse_bounding_set, "BOUNDINGSET" }, + { config_parse_limit, "LIMIT" }, + { config_parse_unit_cgroup, "CGROUP [...]" }, + { config_parse_unit_deps, "UNIT [...]" }, + { config_parse_exec, "PATH [ARGUMENT [...]]" }, + { config_parse_service_type, "SERVICETYPE" }, + { config_parse_service_restart, "SERVICERESTART" }, +#ifdef HAVE_SYSV_COMPAT + { config_parse_sysv_priority, "SYSVPRIORITY" }, +#else + { config_parse_warn_compat, "NOTSUPPORTED" }, +#endif + { config_parse_kill_mode, "KILLMODE" }, + { config_parse_kill_signal, "SIGNAL" }, + { config_parse_socket_listen, "SOCKET [...]" }, + { config_parse_socket_bind, "SOCKETBIND" }, + { config_parse_socket_bindtodevice, "NETWORKINTERFACE" }, + { config_parse_usec, "SECONDS" }, + { config_parse_nsec, "NANOSECONDS" }, + { config_parse_path_strv, "PATH [...]" }, + { config_parse_unit_requires_mounts_for, "PATH [...]" }, + { config_parse_exec_mount_flags, "MOUNTFLAG [...]" }, + { config_parse_unit_string_printf, "STRING" }, + { config_parse_timer, "TIMER" }, + { config_parse_timer_unit, "NAME" }, + { config_parse_path_spec, "PATH" }, + { config_parse_path_unit, "UNIT" }, + { config_parse_notify_access, "ACCESS" }, + { config_parse_ip_tos, "TOS" }, + { config_parse_unit_condition_path, "CONDITION" }, + { config_parse_unit_condition_string, "CONDITION" }, + { config_parse_unit_condition_null, "CONDITION" }, + }; + + const char *prev = NULL; + const char *i; + + assert(f); + + NULSTR_FOREACH(i, load_fragment_gperf_nulstr) { + const char *rvalue = "OTHER", *lvalue; + unsigned j; + size_t prefix_len; + const char *dot; + const ConfigPerfItem *p; + + assert_se(p = load_fragment_gperf_lookup(i, strlen(i))); + + dot = strchr(i, '.'); + lvalue = dot ? dot + 1 : i; + prefix_len = dot-i; + + if (dot) + if (!prev || strncmp(prev, i, prefix_len+1) != 0) { + if (prev) + fputc('\n', f); + + fprintf(f, "[%.*s]\n", (int) prefix_len, i); + } + + for (j = 0; j < ELEMENTSOF(table); j++) + if (p->parse == table[j].callback) { + rvalue = table[j].rvalue; + break; + } + + fprintf(f, "%s=%s\n", lvalue, rvalue); + prev = i; + } +} diff --git a/src/core/load-fragment.h b/src/core/load-fragment.h new file mode 100644 index 000000000..24f738464 --- /dev/null +++ b/src/core/load-fragment.h @@ -0,0 +1,88 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +#include "unit.h" + +/* Read service data from .desktop file style configuration fragments */ + +int unit_load_fragment(Unit *u); + +void unit_dump_config_items(FILE *f); + +int config_parse_warn_compat(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_unit_deps(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_unit_string_printf(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_unit_strv_printf(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_unit_path_printf(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_documentation(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_socket_listen(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_socket_bind(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_exec_nice(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_exec_oom_score_adjust(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_exec(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_service_timeout(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_service_type(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_service_restart(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_socket_bindtodevice(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_output(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_input(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_exec_io_class(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_exec_io_priority(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_exec_cpu_sched_policy(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_exec_cpu_sched_prio(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_exec_cpu_affinity(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_exec_capabilities(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_exec_secure_bits(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_bounding_set(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_limit(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_unit_cgroup(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_sysv_priority(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_fsck_passno(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_kill_signal(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_exec_mount_flags(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_timer(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_timer_unit(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_path_spec(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_path_unit(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_socket_service(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_service_sockets(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_unit_env_file(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_ip_tos(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_unit_condition_path(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_unit_condition_string(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_unit_condition_null(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_kill_mode(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_notify_access(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_start_limit_action(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_unit_cgroup_attr(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_unit_cpu_shares(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_unit_memory_limit(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_unit_device_allow(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_unit_blkio_weight(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_unit_blkio_bandwidth(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_unit_requires_mounts_for(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_syscall_filter(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); + +/* gperf prototypes */ +const struct ConfigPerfItem* load_fragment_gperf_lookup(const char *key, unsigned length); +extern const char load_fragment_gperf_nulstr[]; diff --git a/src/core/locale-setup.c b/src/core/locale-setup.c new file mode 100644 index 000000000..48b59bf44 --- /dev/null +++ b/src/core/locale-setup.c @@ -0,0 +1,146 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include + +#include "locale-setup.h" +#include "util.h" +#include "macro.h" +#include "virt.h" + +enum { + /* We don't list LC_ALL here on purpose. People should be + * using LANG instead. */ + + VARIABLE_LANG, + VARIABLE_LANGUAGE, + VARIABLE_LC_CTYPE, + VARIABLE_LC_NUMERIC, + VARIABLE_LC_TIME, + VARIABLE_LC_COLLATE, + VARIABLE_LC_MONETARY, + VARIABLE_LC_MESSAGES, + VARIABLE_LC_PAPER, + VARIABLE_LC_NAME, + VARIABLE_LC_ADDRESS, + VARIABLE_LC_TELEPHONE, + VARIABLE_LC_MEASUREMENT, + VARIABLE_LC_IDENTIFICATION, + _VARIABLE_MAX +}; + +static const char * const variable_names[_VARIABLE_MAX] = { + [VARIABLE_LANG] = "LANG", + [VARIABLE_LANGUAGE] = "LANGUAGE", + [VARIABLE_LC_CTYPE] = "LC_CTYPE", + [VARIABLE_LC_NUMERIC] = "LC_NUMERIC", + [VARIABLE_LC_TIME] = "LC_TIME", + [VARIABLE_LC_COLLATE] = "LC_COLLATE", + [VARIABLE_LC_MONETARY] = "LC_MONETARY", + [VARIABLE_LC_MESSAGES] = "LC_MESSAGES", + [VARIABLE_LC_PAPER] = "LC_PAPER", + [VARIABLE_LC_NAME] = "LC_NAME", + [VARIABLE_LC_ADDRESS] = "LC_ADDRESS", + [VARIABLE_LC_TELEPHONE] = "LC_TELEPHONE", + [VARIABLE_LC_MEASUREMENT] = "LC_MEASUREMENT", + [VARIABLE_LC_IDENTIFICATION] = "LC_IDENTIFICATION" +}; + +int locale_setup(void) { + char *variables[_VARIABLE_MAX]; + int r = 0, i; + + zero(variables); + + if (detect_container(NULL) <= 0) { + r = parse_env_file("/proc/cmdline", WHITESPACE, + "locale.LANG", &variables[VARIABLE_LANG], + "locale.LANGUAGE", &variables[VARIABLE_LANGUAGE], + "locale.LC_CTYPE", &variables[VARIABLE_LC_CTYPE], + "locale.LC_NUMERIC", &variables[VARIABLE_LC_NUMERIC], + "locale.LC_TIME", &variables[VARIABLE_LC_TIME], + "locale.LC_COLLATE", &variables[VARIABLE_LC_COLLATE], + "locale.LC_MONETARY", &variables[VARIABLE_LC_MONETARY], + "locale.LC_MESSAGES", &variables[VARIABLE_LC_MESSAGES], + "locale.LC_PAPER", &variables[VARIABLE_LC_PAPER], + "locale.LC_NAME", &variables[VARIABLE_LC_NAME], + "locale.LC_ADDRESS", &variables[VARIABLE_LC_ADDRESS], + "locale.LC_TELEPHONE", &variables[VARIABLE_LC_TELEPHONE], + "locale.LC_MEASUREMENT", &variables[VARIABLE_LC_MEASUREMENT], + "locale.LC_IDENTIFICATION", &variables[VARIABLE_LC_IDENTIFICATION], + NULL); + + if (r < 0 && r != -ENOENT) + log_warning("Failed to read /proc/cmdline: %s", strerror(-r)); + } + + /* Hmm, nothing set on the kernel cmd line? Then let's + * try /etc/locale.conf */ + if (r <= 0) { + r = parse_env_file("/etc/locale.conf", NEWLINE, + "LANG", &variables[VARIABLE_LANG], + "LANGUAGE", &variables[VARIABLE_LANGUAGE], + "LC_CTYPE", &variables[VARIABLE_LC_CTYPE], + "LC_NUMERIC", &variables[VARIABLE_LC_NUMERIC], + "LC_TIME", &variables[VARIABLE_LC_TIME], + "LC_COLLATE", &variables[VARIABLE_LC_COLLATE], + "LC_MONETARY", &variables[VARIABLE_LC_MONETARY], + "LC_MESSAGES", &variables[VARIABLE_LC_MESSAGES], + "LC_PAPER", &variables[VARIABLE_LC_PAPER], + "LC_NAME", &variables[VARIABLE_LC_NAME], + "LC_ADDRESS", &variables[VARIABLE_LC_ADDRESS], + "LC_TELEPHONE", &variables[VARIABLE_LC_TELEPHONE], + "LC_MEASUREMENT", &variables[VARIABLE_LC_MEASUREMENT], + "LC_IDENTIFICATION", &variables[VARIABLE_LC_IDENTIFICATION], + NULL); + + if (r < 0 && r != -ENOENT) + log_warning("Failed to read /etc/locale.conf: %s", strerror(-r)); + } + + if (!variables[VARIABLE_LANG]) { + variables[VARIABLE_LANG] = strdup("C"); + if (!variables[VARIABLE_LANG]) { + r = -ENOMEM; + goto finish; + } + } + + for (i = 0; i < _VARIABLE_MAX; i++) { + if (variables[i]) { + if (setenv(variable_names[i], variables[i], 1) < 0) { + r = -errno; + goto finish; + } + } else + unsetenv(variable_names[i]); + } + + r = 0; + +finish: + for (i = 0; i < _VARIABLE_MAX; i++) + free(variables[i]); + + return r; +} diff --git a/src/core/locale-setup.h b/src/core/locale-setup.h new file mode 100644 index 000000000..5a0f2f788 --- /dev/null +++ b/src/core/locale-setup.h @@ -0,0 +1,24 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +int locale_setup(void); diff --git a/src/core/loopback-setup.c b/src/core/loopback-setup.c new file mode 100644 index 000000000..065b75a6e --- /dev/null +++ b/src/core/loopback-setup.c @@ -0,0 +1,317 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "util.h" +#include "macro.h" +#include "loopback-setup.h" +#include "socket-util.h" + +#define NLMSG_TAIL(nmsg) \ + ((struct rtattr *) (((uint8_t*) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len))) + +static int add_rtattr(struct nlmsghdr *n, size_t max_length, int type, const void *data, size_t data_length) { + size_t length; + struct rtattr *rta; + + length = RTA_LENGTH(data_length); + + if (NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(length) > max_length) + return -E2BIG; + + rta = NLMSG_TAIL(n); + rta->rta_type = type; + rta->rta_len = length; + memcpy(RTA_DATA(rta), data, data_length); + n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(length); + + return 0; +} + +static ssize_t sendto_loop(int fd, const void *buf, size_t buf_len, int flags, const struct sockaddr *sa, socklen_t sa_len) { + + for (;;) { + ssize_t l; + + l = sendto(fd, buf, buf_len, flags, sa, sa_len); + if (l >= 0) + return l; + + if (errno != EINTR) + return -errno; + } +} + +static ssize_t recvfrom_loop(int fd, void *buf, size_t buf_len, int flags, struct sockaddr *sa, socklen_t *sa_len) { + + for (;;) { + ssize_t l; + + l = recvfrom(fd, buf, buf_len, flags, sa, sa_len); + if (l >= 0) + return l; + + if (errno != EINTR) + return -errno; + } +} + +static int add_adresses(int fd, int if_loopback, unsigned *requests) { + union { + struct sockaddr sa; + struct sockaddr_nl nl; + } sa; + union { + struct nlmsghdr header; + uint8_t buf[NLMSG_ALIGN(sizeof(struct nlmsghdr)) + + NLMSG_ALIGN(sizeof(struct ifaddrmsg)) + + RTA_LENGTH(sizeof(struct in6_addr))]; + } request; + + struct ifaddrmsg *ifaddrmsg; + uint32_t ipv4_address = htonl(INADDR_LOOPBACK); + int r; + + zero(request); + + request.header.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg)); + request.header.nlmsg_type = RTM_NEWADDR; + request.header.nlmsg_flags = NLM_F_REQUEST|NLM_F_CREATE|NLM_F_ACK; + request.header.nlmsg_seq = *requests + 1; + + ifaddrmsg = NLMSG_DATA(&request.header); + ifaddrmsg->ifa_family = AF_INET; + ifaddrmsg->ifa_prefixlen = 8; + ifaddrmsg->ifa_flags = IFA_F_PERMANENT; + ifaddrmsg->ifa_scope = RT_SCOPE_HOST; + ifaddrmsg->ifa_index = if_loopback; + + r = add_rtattr(&request.header, sizeof(request), IFA_LOCAL, &ipv4_address, sizeof(ipv4_address)); + if (r < 0) + return r; + + zero(sa); + sa.nl.nl_family = AF_NETLINK; + + if (sendto_loop(fd, &request, request.header.nlmsg_len, 0, &sa.sa, sizeof(sa)) < 0) + return -errno; + (*requests)++; + + if (!socket_ipv6_is_supported()) + return 0; + + request.header.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg)); + request.header.nlmsg_seq = *requests + 1; + + ifaddrmsg->ifa_family = AF_INET6; + ifaddrmsg->ifa_prefixlen = 128; + + r = add_rtattr(&request.header, sizeof(request), IFA_LOCAL, &in6addr_loopback, sizeof(in6addr_loopback)); + if (r < 0) + return r; + + if (sendto_loop(fd, &request, request.header.nlmsg_len, 0, &sa.sa, sizeof(sa)) < 0) + return -errno; + (*requests)++; + + return 0; +} + +static int start_interface(int fd, int if_loopback, unsigned *requests) { + union { + struct sockaddr sa; + struct sockaddr_nl nl; + } sa; + union { + struct nlmsghdr header; + uint8_t buf[NLMSG_ALIGN(sizeof(struct nlmsghdr)) + + NLMSG_ALIGN(sizeof(struct ifinfomsg))]; + } request; + + struct ifinfomsg *ifinfomsg; + + zero(request); + + request.header.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)); + request.header.nlmsg_type = RTM_NEWLINK; + request.header.nlmsg_flags = NLM_F_REQUEST|NLM_F_ACK; + request.header.nlmsg_seq = *requests + 1; + + ifinfomsg = NLMSG_DATA(&request.header); + ifinfomsg->ifi_family = AF_UNSPEC; + ifinfomsg->ifi_index = if_loopback; + ifinfomsg->ifi_flags = IFF_UP; + ifinfomsg->ifi_change = IFF_UP; + + zero(sa); + sa.nl.nl_family = AF_NETLINK; + + if (sendto_loop(fd, &request, request.header.nlmsg_len, 0, &sa.sa, sizeof(sa)) < 0) + return -errno; + + (*requests)++; + + return 0; +} + +static int read_response(int fd, unsigned requests_max) { + union { + struct sockaddr sa; + struct sockaddr_nl nl; + } sa; + union { + struct nlmsghdr header; + uint8_t buf[NLMSG_ALIGN(sizeof(struct nlmsghdr)) + + NLMSG_ALIGN(sizeof(struct nlmsgerr))]; + } response; + + ssize_t l; + socklen_t sa_len = sizeof(sa); + struct nlmsgerr *nlmsgerr; + + l = recvfrom_loop(fd, &response, sizeof(response), 0, &sa.sa, &sa_len); + if (l < 0) + return -errno; + + if (sa_len != sizeof(sa.nl) || + sa.nl.nl_family != AF_NETLINK) + return -EIO; + + if (sa.nl.nl_pid != 0) + return 0; + + if ((size_t) l < sizeof(struct nlmsghdr)) + return -EIO; + + if (response.header.nlmsg_type != NLMSG_ERROR || + (pid_t) response.header.nlmsg_pid != getpid() || + response.header.nlmsg_seq >= requests_max) + return 0; + + if ((size_t) l < NLMSG_LENGTH(sizeof(struct nlmsgerr)) || + response.header.nlmsg_len < NLMSG_LENGTH(sizeof(struct nlmsgerr))) + return -EIO; + + nlmsgerr = NLMSG_DATA(&response.header); + + if (nlmsgerr->error < 0 && nlmsgerr->error != -EEXIST) + return nlmsgerr->error; + + return response.header.nlmsg_seq; +} + +static int check_loopback(void) { + int r, fd; + union { + struct sockaddr sa; + struct sockaddr_in in; + } sa; + + /* If we failed to set up the loop back device, check whether + * it might already be set up */ + + fd = socket(AF_INET, SOCK_DGRAM|SOCK_NONBLOCK|SOCK_CLOEXEC, 0); + if (fd < 0) + return -errno; + + zero(sa); + sa.in.sin_family = AF_INET; + sa.in.sin_addr.s_addr = INADDR_LOOPBACK; + + if (bind(fd, &sa.sa, sizeof(sa.in)) >= 0) + r = 1; + else + r = errno == EADDRNOTAVAIL ? 0 : -errno; + + close_nointr_nofail(fd); + + return r; +} + +int loopback_setup(void) { + int r, if_loopback; + union { + struct sockaddr sa; + struct sockaddr_nl nl; + } sa; + unsigned requests = 0, i; + int fd; + bool eperm = false; + + errno = 0; + if_loopback = (int) if_nametoindex("lo"); + if (if_loopback <= 0) + return errno ? -errno : -ENODEV; + + fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE); + if (fd < 0) + return -errno; + + zero(sa); + sa.nl.nl_family = AF_NETLINK; + if (bind(fd, &sa.sa, sizeof(sa)) < 0) { + r = -errno; + goto finish; + } + + r = add_adresses(fd, if_loopback, &requests); + if (r < 0) + goto finish; + + r = start_interface(fd, if_loopback, &requests); + if (r < 0) + goto finish; + + for (i = 0; i < requests; i++) { + r = read_response(fd, requests); + + if (r == -EPERM) + eperm = true; + else if (r < 0) + goto finish; + } + + if (eperm && check_loopback() < 0) { + r = -EPERM; + goto finish; + } + + r = 0; + +finish: + if (r < 0) + log_warning("Failed to configure loopback device: %s", strerror(-r)); + + if (fd >= 0) + close_nointr_nofail(fd); + + return r; +} diff --git a/src/core/loopback-setup.h b/src/core/loopback-setup.h new file mode 100644 index 000000000..dd83cf13a --- /dev/null +++ b/src/core/loopback-setup.h @@ -0,0 +1,24 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +int loopback_setup(void); diff --git a/src/core/machine-id-setup.c b/src/core/machine-id-setup.c new file mode 100644 index 000000000..7f4c23b13 --- /dev/null +++ b/src/core/machine-id-setup.c @@ -0,0 +1,246 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "machine-id-setup.h" +#include "macro.h" +#include "util.h" +#include "mkdir.h" +#include "log.h" +#include "virt.h" + +static int shorten_uuid(char destination[36], const char *source) { + unsigned i, j; + + for (i = 0, j = 0; i < 36 && j < 32; i++) { + int t; + + t = unhexchar(source[i]); + if (t < 0) + continue; + + destination[j++] = hexchar(t); + } + + if (i == 36 && j == 32) { + destination[32] = '\n'; + destination[33] = 0; + return 0; + } + + return -EINVAL; +} + +static int generate(char id[34]) { + int fd, r; + unsigned char *p; + sd_id128_t buf; + char *q; + ssize_t k; + const char *vm_id; + + assert(id); + + /* First, try reading the D-Bus machine id, unless it is a symlink */ + fd = open("/var/lib/dbus/machine-id", O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW); + if (fd >= 0) { + + k = loop_read(fd, id, 32, false); + close_nointr_nofail(fd); + + if (k >= 32) { + id[32] = '\n'; + id[33] = 0; + + log_info("Initializing machine ID from D-Bus machine ID."); + return 0; + } + } + + /* If that didn't work, see if we are running in qemu/kvm and a + * machine ID was passed in via -uuid on the qemu/kvm command + * line */ + + r = detect_vm(&vm_id); + if (r > 0 && streq(vm_id, "kvm")) { + char uuid[37]; + + fd = open("/sys/class/dmi/id/product_uuid", O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW); + if (fd >= 0) { + k = loop_read(fd, uuid, 36, false); + close_nointr_nofail(fd); + + if (k >= 36) { + r = shorten_uuid(id, uuid); + if (r >= 0) { + log_info("Initializing machine ID from KVM UUID."); + return 0; + } + } + } + } + + /* If that didn't work either, see if we are running in a + * container, and a machine ID was passed in via + * $container_uuid the way libvirt/LXC does it */ + r = detect_container(NULL); + if (r > 0) { + char *e; + + r = getenv_for_pid(1, "container_uuid", &e); + if (r > 0) { + if (strlen(e) >= 36) { + r = shorten_uuid(id, e); + if (r >= 0) { + log_info("Initializing machine ID from container UUID."); + free(e); + return 0; + } + } + + free(e); + } + } + + /* If that didn't work, generate a random machine id */ + r = sd_id128_randomize(&buf); + if (r < 0) { + log_error("Failed to open /dev/urandom: %s", strerror(-r)); + return r; + } + + for (p = buf.bytes, q = id; p < buf.bytes + sizeof(buf); p++, q += 2) { + q[0] = hexchar(*p >> 4); + q[1] = hexchar(*p & 15); + } + + id[32] = '\n'; + id[33] = 0; + + log_info("Initializing machine ID from random generator."); + + return 0; +} + +int machine_id_setup(void) { + int fd, r; + bool writable; + struct stat st; + char id[34]; /* 32 + \n + \0 */ + mode_t m; + + m = umask(0000); + + /* We create this 0444, to indicate that this isn't really + * something you should ever modify. Of course, since the file + * will be owned by root it doesn't matter much, but maybe + * people look. */ + + fd = open("/etc/machine-id", O_RDWR|O_CREAT|O_CLOEXEC|O_NOCTTY, 0444); + if (fd >= 0) + writable = true; + else { + fd = open("/etc/machine-id", O_RDONLY|O_CLOEXEC|O_NOCTTY); + if (fd < 0) { + umask(m); + log_error("Cannot open /etc/machine-id: %m"); + return -errno; + } + + writable = false; + } + + umask(m); + + if (fstat(fd, &st) < 0) { + log_error("fstat() failed: %m"); + r = -errno; + goto finish; + } + + if (S_ISREG(st.st_mode)) { + if (loop_read(fd, id, 32, false) >= 32) { + r = 0; + goto finish; + } + } + + /* Hmm, so, the id currently stored is not useful, then let's + * generate one */ + + r = generate(id); + if (r < 0) + goto finish; + + if (S_ISREG(st.st_mode) && writable) { + lseek(fd, 0, SEEK_SET); + + if (loop_write(fd, id, 33, false) == 33) { + r = 0; + goto finish; + } + } + + close_nointr_nofail(fd); + fd = -1; + + /* Hmm, we couldn't write it? So let's write it to + * /run/machine-id as a replacement */ + + m = umask(0022); + r = write_one_line_file("/run/machine-id", id); + umask(m); + + if (r < 0) { + log_error("Cannot write /run/machine-id: %s", strerror(-r)); + + unlink("/run/machine-id"); + goto finish; + } + + /* And now, let's mount it over */ + r = mount("/run/machine-id", "/etc/machine-id", NULL, MS_BIND, NULL) < 0 ? -errno : 0; + if (r < 0) { + unlink("/run/machine-id"); + log_error("Failed to mount /etc/machine-id: %s", strerror(-r)); + } else { + log_info("Installed transient /etc/machine-id file."); + + /* Mark the mount read-only */ + mount(NULL, "/etc/machine-id", NULL, MS_BIND|MS_RDONLY|MS_REMOUNT, NULL); + } + +finish: + + if (fd >= 0) + close_nointr_nofail(fd); + + return r; +} diff --git a/src/core/machine-id-setup.h b/src/core/machine-id-setup.h new file mode 100644 index 000000000..b9e6b4d67 --- /dev/null +++ b/src/core/machine-id-setup.h @@ -0,0 +1,24 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +int machine_id_setup(void); diff --git a/src/core/macros.systemd.in b/src/core/macros.systemd.in new file mode 100644 index 000000000..647cce691 --- /dev/null +++ b/src/core/macros.systemd.in @@ -0,0 +1,73 @@ +# -*- Mode: makefile; indent-tabs-mode: t -*- */ +# +# This file is part of systemd. +# +# Copyright 2012 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 . + +# RPM macros for packages installing systemd unit files + +%_unitdir @systemunitdir@ +%_presetdir @systempresetdir@ +%_udevhwdbdir @udevhwdbdir@ +%_udevrulesdir @udevrulesdir@ +%_journalcatalogdir @catalogdir@ +%_tmpfilesdir @tmpfilesdir@ +%_sysctldir @sysctldir@ + +%systemd_requires \ +Requires(post): systemd \ +Requires(preun): systemd \ +Requires(postun): systemd \ +%{nil} + +%systemd_post() \ +if [ $1 -eq 1 ] ; then \ + # Initial installation \ + @rootbindir@/systemctl preset %{?*} >/dev/null 2>&1 || : \ +fi \ +%{nil} + +%systemd_preun() \ +if [ $1 -eq 0 ] ; then \ + # Package removal, not upgrade \ + @rootbindir@/systemctl --no-reload disable %{?*} > /dev/null 2>&1 || : \ + @rootbindir@/systemctl stop %{?*} > /dev/null 2>&1 || : \ +fi \ +%{nil} + +%systemd_postun() \ +@rootbindir@/systemctl daemon-reload >/dev/null 2>&1 || : \ +%{nil} + +%systemd_postun_with_restart() \ +@rootbindir@/systemctl daemon-reload >/dev/null 2>&1 || : \ +if [ $1 -ge 1 ] ; then \ + # Package upgrade, not uninstall \ + @rootbindir@/systemctl try-restart %{?*} >/dev/null 2>&1 || : \ +fi \ +%{nil} + +%udev_hwdb_update() \ +@bindir@/udevadm hwdb --update >/dev/null 2>&1 || : \ +%{nil} + +%udev_rules_update() \ +@bindir@/udevadm control --reload >/dev/null 2>&1 || : \ +%{nil} + +%journal_catalog_update() \ +@rootbindir@/journalctl --update-catalog >/dev/null 2>&1 || : \ +%{nil} diff --git a/src/core/main.c b/src/core/main.c new file mode 100644 index 000000000..1ee3c9c0e --- /dev/null +++ b/src/core/main.c @@ -0,0 +1,1959 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "manager.h" +#include "log.h" +#include "load-fragment.h" +#include "fdset.h" +#include "special.h" +#include "conf-parser.h" +#include "bus-errors.h" +#include "missing.h" +#include "label.h" +#include "build.h" +#include "strv.h" +#include "def.h" +#include "virt.h" +#include "watchdog.h" +#include "path-util.h" +#include "switch-root.h" +#include "capability.h" +#include "killall.h" + +#include "mount-setup.h" +#include "loopback-setup.h" +#ifdef HAVE_KMOD +#include "kmod-setup.h" +#endif +#include "hostname-setup.h" +#include "machine-id-setup.h" +#include "locale-setup.h" +#include "hwclock.h" +#include "selinux-setup.h" +#include "ima-setup.h" +#include "sd-daemon.h" + +static enum { + ACTION_RUN, + ACTION_HELP, + ACTION_VERSION, + ACTION_TEST, + ACTION_DUMP_CONFIGURATION_ITEMS, + ACTION_DONE +} arg_action = ACTION_RUN; + +static char *arg_default_unit = NULL; +static SystemdRunningAs arg_running_as = _SYSTEMD_RUNNING_AS_INVALID; + +static bool arg_dump_core = true; +static bool arg_crash_shell = false; +static int arg_crash_chvt = -1; +static bool arg_confirm_spawn = false; +static bool arg_show_status = true; +static bool arg_switched_root = false; +static char **arg_default_controllers = NULL; +static char ***arg_join_controllers = NULL; +static ExecOutput arg_default_std_output = EXEC_OUTPUT_JOURNAL; +static ExecOutput arg_default_std_error = EXEC_OUTPUT_INHERIT; +static usec_t arg_runtime_watchdog = 0; +static usec_t arg_shutdown_watchdog = 10 * USEC_PER_MINUTE; +static struct rlimit *arg_default_rlimit[RLIMIT_NLIMITS] = {}; +static uint64_t arg_capability_bounding_set_drop = 0; +static nsec_t arg_timer_slack_nsec = (nsec_t) -1; + +static FILE* serialization = NULL; + +static void nop_handler(int sig) { +} + +_noreturn_ static void crash(int sig) { + + if (!arg_dump_core) + log_error("Caught <%s>, not dumping core.", signal_to_string(sig)); + else { + struct sigaction sa; + pid_t pid; + + /* We want to wait for the core process, hence let's enable SIGCHLD */ + zero(sa); + sa.sa_handler = nop_handler; + sa.sa_flags = SA_NOCLDSTOP|SA_RESTART; + assert_se(sigaction(SIGCHLD, &sa, NULL) == 0); + + if ((pid = fork()) < 0) + log_error("Caught <%s>, cannot fork for core dump: %s", signal_to_string(sig), strerror(errno)); + + else if (pid == 0) { + struct rlimit rl; + + /* Enable default signal handler for core dump */ + zero(sa); + sa.sa_handler = SIG_DFL; + assert_se(sigaction(sig, &sa, NULL) == 0); + + /* Don't limit the core dump size */ + zero(rl); + rl.rlim_cur = RLIM_INFINITY; + rl.rlim_max = RLIM_INFINITY; + setrlimit(RLIMIT_CORE, &rl); + + /* Just to be sure... */ + assert_se(chdir("/") == 0); + + /* Raise the signal again */ + raise(sig); + + assert_not_reached("We shouldn't be here..."); + _exit(1); + + } else { + siginfo_t status; + int r; + + /* Order things nicely. */ + if ((r = wait_for_terminate(pid, &status)) < 0) + log_error("Caught <%s>, waitpid() failed: %s", signal_to_string(sig), strerror(-r)); + else if (status.si_code != CLD_DUMPED) + log_error("Caught <%s>, core dump failed.", signal_to_string(sig)); + else + log_error("Caught <%s>, dumped core as pid %lu.", signal_to_string(sig), (unsigned long) pid); + } + } + + if (arg_crash_chvt) + chvt(arg_crash_chvt); + + if (arg_crash_shell) { + struct sigaction sa; + pid_t pid; + + log_info("Executing crash shell in 10s..."); + sleep(10); + + /* Let the kernel reap children for us */ + zero(sa); + sa.sa_handler = SIG_IGN; + sa.sa_flags = SA_NOCLDSTOP|SA_NOCLDWAIT|SA_RESTART; + assert_se(sigaction(SIGCHLD, &sa, NULL) == 0); + + pid = fork(); + if (pid < 0) + log_error("Failed to fork off crash shell: %m"); + else if (pid == 0) { + make_console_stdio(); + execl("/bin/sh", "/bin/sh", NULL); + + log_error("execl() failed: %m"); + _exit(1); + } + + log_info("Successfully spawned crash shell as pid %lu.", (unsigned long) pid); + } + + log_info("Freezing execution."); + freeze(); +} + +static void install_crash_handler(void) { + struct sigaction sa; + + zero(sa); + + sa.sa_handler = crash; + sa.sa_flags = SA_NODEFER; + + sigaction_many(&sa, SIGNALS_CRASH_HANDLER, -1); +} + +static int console_setup(bool do_reset) { + int tty_fd, r; + + /* 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 (!do_reset) + return 0; + + tty_fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC); + if (tty_fd < 0) { + log_error("Failed to open /dev/console: %s", strerror(-tty_fd)); + return -tty_fd; + } + + /* We don't want to force text mode. + * plymouth may be showing pictures already from initrd. */ + r = reset_terminal_fd(tty_fd, false); + if (r < 0) + log_error("Failed to reset /dev/console: %s", strerror(-r)); + + close_nointr_nofail(tty_fd); + return r; +} + +static int set_default_unit(const char *u) { + char *c; + + assert(u); + + c = strdup(u); + if (!c) + return -ENOMEM; + + free(arg_default_unit); + arg_default_unit = c; + + return 0; +} + +static int parse_proc_cmdline_word(const char *word) { + + static const char * const rlmap[] = { + "emergency", SPECIAL_EMERGENCY_TARGET, + "-b", SPECIAL_EMERGENCY_TARGET, + "single", SPECIAL_RESCUE_TARGET, + "-s", SPECIAL_RESCUE_TARGET, + "s", SPECIAL_RESCUE_TARGET, + "S", SPECIAL_RESCUE_TARGET, + "1", SPECIAL_RESCUE_TARGET, + "2", SPECIAL_RUNLEVEL2_TARGET, + "3", SPECIAL_RUNLEVEL3_TARGET, + "4", SPECIAL_RUNLEVEL4_TARGET, + "5", SPECIAL_RUNLEVEL5_TARGET, + }; + + assert(word); + + if (startswith(word, "systemd.unit=")) { + + if (!in_initrd()) + return set_default_unit(word + 13); + + } else if (startswith(word, "rd.systemd.unit=")) { + + if (in_initrd()) + return set_default_unit(word + 16); + + } else if (startswith(word, "systemd.log_target=")) { + + if (log_set_target_from_string(word + 19) < 0) + log_warning("Failed to parse log target %s. Ignoring.", word + 19); + + } else if (startswith(word, "systemd.log_level=")) { + + if (log_set_max_level_from_string(word + 18) < 0) + log_warning("Failed to parse log level %s. Ignoring.", word + 18); + + } else if (startswith(word, "systemd.log_color=")) { + + if (log_show_color_from_string(word + 18) < 0) + log_warning("Failed to parse log color setting %s. Ignoring.", word + 18); + + } else if (startswith(word, "systemd.log_location=")) { + + if (log_show_location_from_string(word + 21) < 0) + log_warning("Failed to parse log location setting %s. Ignoring.", word + 21); + + } else if (startswith(word, "systemd.dump_core=")) { + int r; + + if ((r = parse_boolean(word + 18)) < 0) + log_warning("Failed to parse dump core switch %s. Ignoring.", word + 18); + else + arg_dump_core = r; + + } else if (startswith(word, "systemd.crash_shell=")) { + int r; + + if ((r = parse_boolean(word + 20)) < 0) + log_warning("Failed to parse crash shell switch %s. Ignoring.", word + 20); + else + arg_crash_shell = r; + + } else if (startswith(word, "systemd.confirm_spawn=")) { + int r; + + if ((r = parse_boolean(word + 22)) < 0) + log_warning("Failed to parse confirm spawn switch %s. Ignoring.", word + 22); + else + arg_confirm_spawn = r; + + } else if (startswith(word, "systemd.crash_chvt=")) { + int k; + + if (safe_atoi(word + 19, &k) < 0) + log_warning("Failed to parse crash chvt switch %s. Ignoring.", word + 19); + else + arg_crash_chvt = k; + + } else if (startswith(word, "systemd.show_status=")) { + int r; + + if ((r = parse_boolean(word + 20)) < 0) + log_warning("Failed to parse show status switch %s. Ignoring.", word + 20); + else + arg_show_status = r; + } else if (startswith(word, "systemd.default_standard_output=")) { + int r; + + if ((r = exec_output_from_string(word + 32)) < 0) + log_warning("Failed to parse default standard output switch %s. Ignoring.", word + 32); + else + arg_default_std_output = r; + } else if (startswith(word, "systemd.default_standard_error=")) { + int r; + + if ((r = exec_output_from_string(word + 31)) < 0) + log_warning("Failed to parse default standard error switch %s. Ignoring.", word + 31); + else + arg_default_std_error = r; + } else if (startswith(word, "systemd.setenv=")) { + char *cenv, *eq; + int r; + + cenv = strdup(word + 15); + if (!cenv) + return -ENOMEM; + + eq = strchr(cenv, '='); + if (!eq) { + r = unsetenv(cenv); + if (r < 0) + log_warning("unsetenv failed %m. Ignoring."); + } else { + *eq = 0; + r = setenv(cenv, eq + 1, 1); + if (r < 0) + log_warning("setenv failed %m. Ignoring."); + } + free(cenv); + + } else if (startswith(word, "systemd.") || + (in_initrd() && startswith(word, "rd.systemd."))) { + + log_warning("Unknown kernel switch %s. Ignoring.", word); + + log_info("Supported kernel switches:\n" + "systemd.unit=UNIT Default unit to start\n" + "rd.systemd.unit=UNIT Default unit to start when run in initrd\n" + "systemd.dump_core=0|1 Dump core on crash\n" + "systemd.crash_shell=0|1 Run shell on crash\n" + "systemd.crash_chvt=N Change to VT #N on crash\n" + "systemd.confirm_spawn=0|1 Confirm every process spawn\n" + "systemd.show_status=0|1 Show status updates on the console during bootup\n" + "systemd.log_target=console|kmsg|journal|journal-or-kmsg|syslog|syslog-or-kmsg|null\n" + " Log target\n" + "systemd.log_level=LEVEL Log level\n" + "systemd.log_color=0|1 Highlight important log messages\n" + "systemd.log_location=0|1 Include code location in log messages\n" + "systemd.default_standard_output=null|tty|syslog|syslog+console|kmsg|kmsg+console|journal|journal+console\n" + " Set default log output for services\n" + "systemd.default_standard_error=null|tty|syslog|syslog+console|kmsg|kmsg+console|journal|journal+console\n" + " Set default log error output for services\n" + "systemd.setenv=ASSIGNMENT Set an environment variable for all spawned processes\n"); + + } else if (streq(word, "quiet")) + arg_show_status = false; + else if (!in_initrd()) { + unsigned i; + + /* SysV compatibility */ + for (i = 0; i < ELEMENTSOF(rlmap); i += 2) + if (streq(word, rlmap[i])) + return set_default_unit(rlmap[i+1]); + } + + return 0; +} + +static int config_parse_level2( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + assert(filename); + assert(lvalue); + assert(rvalue); + + log_set_max_level_from_string(rvalue); + return 0; +} + +static int config_parse_target( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + assert(filename); + assert(lvalue); + assert(rvalue); + + log_set_target_from_string(rvalue); + return 0; +} + +static int config_parse_color( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + assert(filename); + assert(lvalue); + assert(rvalue); + + log_show_color_from_string(rvalue); + return 0; +} + +static int config_parse_location( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + assert(filename); + assert(lvalue); + assert(rvalue); + + log_show_location_from_string(rvalue); + return 0; +} + +static int config_parse_cpu_affinity2( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + char *w; + size_t l; + char *state; + cpu_set_t *c = NULL; + unsigned ncpus = 0; + + assert(filename); + assert(lvalue); + assert(rvalue); + + FOREACH_WORD_QUOTED(w, l, rvalue, state) { + char *t; + int r; + unsigned cpu; + + if (!(t = strndup(w, l))) + return log_oom(); + + r = safe_atou(t, &cpu); + free(t); + + if (!c) + if (!(c = cpu_set_malloc(&ncpus))) + return log_oom(); + + if (r < 0 || cpu >= ncpus) { + log_error("[%s:%u] Failed to parse CPU affinity: %s", filename, line, rvalue); + CPU_FREE(c); + return -EBADMSG; + } + + CPU_SET_S(cpu, CPU_ALLOC_SIZE(ncpus), c); + } + + if (c) { + if (sched_setaffinity(0, CPU_ALLOC_SIZE(ncpus), c) < 0) + log_warning("Failed to set CPU affinity: %m"); + + CPU_FREE(c); + } + + return 0; +} + +static void strv_free_free(char ***l) { + char ***i; + + if (!l) + return; + + for (i = l; *i; i++) + strv_free(*i); + + free(l); +} + +static void free_join_controllers(void) { + if (!arg_join_controllers) + return; + + strv_free_free(arg_join_controllers); + arg_join_controllers = NULL; +} + +static int config_parse_join_controllers( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + unsigned n = 0; + char *state, *w; + size_t length; + + assert(filename); + assert(lvalue); + assert(rvalue); + + free_join_controllers(); + + FOREACH_WORD_QUOTED(w, length, rvalue, state) { + char *s, **l; + + s = strndup(w, length); + if (!s) + return log_oom(); + + l = strv_split(s, ","); + free(s); + + strv_uniq(l); + + if (strv_length(l) <= 1) { + strv_free(l); + continue; + } + + if (!arg_join_controllers) { + arg_join_controllers = new(char**, 2); + if (!arg_join_controllers) { + strv_free(l); + return log_oom(); + } + + arg_join_controllers[0] = l; + arg_join_controllers[1] = NULL; + + n = 1; + } else { + char ***a; + char ***t; + + t = new0(char**, n+2); + if (!t) { + strv_free(l); + return log_oom(); + } + + n = 0; + + for (a = arg_join_controllers; *a; a++) { + + if (strv_overlap(*a, l)) { + char **c; + + c = strv_merge(*a, l); + if (!c) { + strv_free(l); + strv_free_free(t); + return log_oom(); + } + + strv_free(l); + l = c; + } else { + char **c; + + c = strv_copy(*a); + if (!c) { + strv_free(l); + strv_free_free(t); + return log_oom(); + } + + t[n++] = c; + } + } + + t[n++] = strv_uniq(l); + + strv_free_free(arg_join_controllers); + arg_join_controllers = t; + } + } + + return 0; +} + +static int parse_config_file(void) { + + const ConfigTableItem items[] = { + { "Manager", "LogLevel", config_parse_level2, 0, NULL }, + { "Manager", "LogTarget", config_parse_target, 0, NULL }, + { "Manager", "LogColor", config_parse_color, 0, NULL }, + { "Manager", "LogLocation", config_parse_location, 0, NULL }, + { "Manager", "DumpCore", config_parse_bool, 0, &arg_dump_core }, + { "Manager", "CrashShell", config_parse_bool, 0, &arg_crash_shell }, + { "Manager", "ShowStatus", config_parse_bool, 0, &arg_show_status }, + { "Manager", "CrashChVT", config_parse_int, 0, &arg_crash_chvt }, + { "Manager", "CPUAffinity", config_parse_cpu_affinity2, 0, NULL }, + { "Manager", "DefaultControllers", config_parse_strv, 0, &arg_default_controllers }, + { "Manager", "DefaultStandardOutput", config_parse_output, 0, &arg_default_std_output }, + { "Manager", "DefaultStandardError", config_parse_output, 0, &arg_default_std_error }, + { "Manager", "JoinControllers", config_parse_join_controllers, 0, &arg_join_controllers }, + { "Manager", "RuntimeWatchdogSec", config_parse_usec, 0, &arg_runtime_watchdog }, + { "Manager", "ShutdownWatchdogSec", config_parse_usec, 0, &arg_shutdown_watchdog }, + { "Manager", "CapabilityBoundingSet", config_parse_bounding_set, 0, &arg_capability_bounding_set_drop }, + { "Manager", "TimerSlackNSec", config_parse_nsec, 0, &arg_timer_slack_nsec }, + { "Manager", "DefaultLimitCPU", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_CPU]}, + { "Manager", "DefaultLimitFSIZE", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_FSIZE]}, + { "Manager", "DefaultLimitDATA", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_DATA]}, + { "Manager", "DefaultLimitSTACK", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_STACK]}, + { "Manager", "DefaultLimitCORE", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_CORE]}, + { "Manager", "DefaultLimitRSS", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_RSS]}, + { "Manager", "DefaultLimitNOFILE", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_NOFILE]}, + { "Manager", "DefaultLimitAS", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_AS]}, + { "Manager", "DefaultLimitNPROC", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_NPROC]}, + { "Manager", "DefaultLimitMEMLOCK", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_MEMLOCK]}, + { "Manager", "DefaultLimitLOCKS", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_LOCKS]}, + { "Manager", "DefaultLimitSIGPENDING",config_parse_limit, 0, &arg_default_rlimit[RLIMIT_SIGPENDING]}, + { "Manager", "DefaultLimitMSGQUEUE", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_MSGQUEUE]}, + { "Manager", "DefaultLimitNICE", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_NICE]}, + { "Manager", "DefaultLimitRTPRIO", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_RTPRIO]}, + { "Manager", "DefaultLimitRTTIME", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_RTTIME]}, + { NULL, NULL, NULL, 0, NULL } + }; + + FILE *f; + const char *fn; + int r; + + fn = arg_running_as == SYSTEMD_SYSTEM ? SYSTEM_CONFIG_FILE : USER_CONFIG_FILE; + f = fopen(fn, "re"); + if (!f) { + if (errno == ENOENT) + return 0; + + log_warning("Failed to open configuration file '%s': %m", fn); + return 0; + } + + r = config_parse(fn, f, "Manager\0", config_item_table_lookup, (void*) items, false, NULL); + if (r < 0) + log_warning("Failed to parse configuration file: %s", strerror(-r)); + + fclose(f); + + return 0; +} + +static int parse_proc_cmdline(void) { + char *line, *w, *state; + int r; + size_t l; + + /* Don't read /proc/cmdline if we are in a container, since + * that is only relevant for the host system */ + if (detect_container(NULL) > 0) + return 0; + + if ((r = read_one_line_file("/proc/cmdline", &line)) < 0) { + log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r)); + return 0; + } + + FOREACH_WORD_QUOTED(w, l, line, state) { + char *word; + + if (!(word = strndup(w, l))) { + r = -ENOMEM; + goto finish; + } + + r = parse_proc_cmdline_word(word); + if (r < 0) { + log_error("Failed on cmdline argument %s: %s", word, strerror(-r)); + free(word); + goto finish; + } + + free(word); + } + + r = 0; + +finish: + free(line); + return r; +} + +static int parse_argv(int argc, char *argv[]) { + + enum { + ARG_LOG_LEVEL = 0x100, + ARG_LOG_TARGET, + ARG_LOG_COLOR, + ARG_LOG_LOCATION, + ARG_UNIT, + ARG_SYSTEM, + ARG_USER, + ARG_TEST, + ARG_VERSION, + ARG_DUMP_CONFIGURATION_ITEMS, + ARG_DUMP_CORE, + ARG_CRASH_SHELL, + ARG_CONFIRM_SPAWN, + ARG_SHOW_STATUS, + ARG_DESERIALIZE, + ARG_SWITCHED_ROOT, + ARG_INTROSPECT, + ARG_DEFAULT_STD_OUTPUT, + ARG_DEFAULT_STD_ERROR + }; + + static const struct option options[] = { + { "log-level", required_argument, NULL, ARG_LOG_LEVEL }, + { "log-target", required_argument, NULL, ARG_LOG_TARGET }, + { "log-color", optional_argument, NULL, ARG_LOG_COLOR }, + { "log-location", optional_argument, NULL, ARG_LOG_LOCATION }, + { "unit", required_argument, NULL, ARG_UNIT }, + { "system", no_argument, NULL, ARG_SYSTEM }, + { "user", no_argument, NULL, ARG_USER }, + { "test", no_argument, NULL, ARG_TEST }, + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, ARG_VERSION }, + { "dump-configuration-items", no_argument, NULL, ARG_DUMP_CONFIGURATION_ITEMS }, + { "dump-core", optional_argument, NULL, ARG_DUMP_CORE }, + { "crash-shell", optional_argument, NULL, ARG_CRASH_SHELL }, + { "confirm-spawn", optional_argument, NULL, ARG_CONFIRM_SPAWN }, + { "show-status", optional_argument, NULL, ARG_SHOW_STATUS }, + { "deserialize", required_argument, NULL, ARG_DESERIALIZE }, + { "switched-root", no_argument, NULL, ARG_SWITCHED_ROOT }, + { "introspect", optional_argument, NULL, ARG_INTROSPECT }, + { "default-standard-output", required_argument, NULL, ARG_DEFAULT_STD_OUTPUT, }, + { "default-standard-error", required_argument, NULL, ARG_DEFAULT_STD_ERROR, }, + { NULL, 0, NULL, 0 } + }; + + int c, r; + + assert(argc >= 1); + assert(argv); + + if (getpid() == 1) + opterr = 0; + + while ((c = getopt_long(argc, argv, "hDbsz:", options, NULL)) >= 0) + + switch (c) { + + case ARG_LOG_LEVEL: + if ((r = log_set_max_level_from_string(optarg)) < 0) { + log_error("Failed to parse log level %s.", optarg); + return r; + } + + break; + + case ARG_LOG_TARGET: + + if ((r = log_set_target_from_string(optarg)) < 0) { + log_error("Failed to parse log target %s.", optarg); + return r; + } + + break; + + case ARG_LOG_COLOR: + + if (optarg) { + if ((r = log_show_color_from_string(optarg)) < 0) { + log_error("Failed to parse log color setting %s.", optarg); + return r; + } + } else + log_show_color(true); + + break; + + case ARG_LOG_LOCATION: + + if (optarg) { + if ((r = log_show_location_from_string(optarg)) < 0) { + log_error("Failed to parse log location setting %s.", optarg); + return r; + } + } else + log_show_location(true); + + break; + + case ARG_DEFAULT_STD_OUTPUT: + + if ((r = exec_output_from_string(optarg)) < 0) { + log_error("Failed to parse default standard output setting %s.", optarg); + return r; + } else + arg_default_std_output = r; + break; + + case ARG_DEFAULT_STD_ERROR: + + if ((r = exec_output_from_string(optarg)) < 0) { + log_error("Failed to parse default standard error output setting %s.", optarg); + return r; + } else + arg_default_std_error = r; + break; + + case ARG_UNIT: + + if ((r = set_default_unit(optarg)) < 0) { + log_error("Failed to set default unit %s: %s", optarg, strerror(-r)); + return r; + } + + break; + + case ARG_SYSTEM: + arg_running_as = SYSTEMD_SYSTEM; + break; + + case ARG_USER: + arg_running_as = SYSTEMD_USER; + break; + + case ARG_TEST: + arg_action = ACTION_TEST; + break; + + case ARG_VERSION: + arg_action = ACTION_VERSION; + break; + + case ARG_DUMP_CONFIGURATION_ITEMS: + arg_action = ACTION_DUMP_CONFIGURATION_ITEMS; + break; + + case ARG_DUMP_CORE: + r = optarg ? parse_boolean(optarg) : 1; + if (r < 0) { + log_error("Failed to parse dump core boolean %s.", optarg); + return r; + } + arg_dump_core = r; + break; + + case ARG_CRASH_SHELL: + r = optarg ? parse_boolean(optarg) : 1; + if (r < 0) { + log_error("Failed to parse crash shell boolean %s.", optarg); + return r; + } + arg_crash_shell = r; + break; + + case ARG_CONFIRM_SPAWN: + r = optarg ? parse_boolean(optarg) : 1; + if (r < 0) { + log_error("Failed to parse confirm spawn boolean %s.", optarg); + return r; + } + arg_confirm_spawn = r; + break; + + case ARG_SHOW_STATUS: + r = optarg ? parse_boolean(optarg) : 1; + if (r < 0) { + log_error("Failed to parse show status boolean %s.", optarg); + return r; + } + arg_show_status = r; + break; + + case ARG_DESERIALIZE: { + int fd; + FILE *f; + + r = safe_atoi(optarg, &fd); + if (r < 0 || fd < 0) { + log_error("Failed to parse deserialize option %s.", optarg); + return r < 0 ? r : -EINVAL; + } + + fd_cloexec(fd, true); + + f = fdopen(fd, "r"); + if (!f) { + log_error("Failed to open serialization fd: %m"); + return -errno; + } + + if (serialization) + fclose(serialization); + + serialization = f; + + break; + } + + case ARG_SWITCHED_ROOT: + arg_switched_root = true; + break; + + case ARG_INTROSPECT: { + const char * const * i = NULL; + + for (i = bus_interface_table; *i; i += 2) + if (!optarg || streq(i[0], optarg)) { + fputs(DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE + "\n", stdout); + fputs(i[1], stdout); + fputs("\n", stdout); + + if (optarg) + break; + } + + if (!i[0] && optarg) + log_error("Unknown interface %s.", optarg); + + arg_action = ACTION_DONE; + break; + } + + case 'h': + arg_action = ACTION_HELP; + break; + + case 'D': + log_set_max_level(LOG_DEBUG); + break; + + case 'b': + case 's': + case 'z': + /* Just to eat away the sysvinit kernel + * cmdline args without getopt() error + * messages that we'll parse in + * parse_proc_cmdline_word() or ignore. */ + + case '?': + default: + if (getpid() != 1) { + log_error("Unknown option code %c", c); + return -EINVAL; + } + + break; + } + + if (optind < argc && getpid() != 1) { + /* Hmm, when we aren't run as init system + * let's complain about excess arguments */ + + log_error("Excess arguments."); + return -EINVAL; + } + + if (detect_container(NULL) > 0) { + char **a; + + /* All /proc/cmdline arguments the kernel didn't + * understand it passed to us. We're not really + * interested in that usually since /proc/cmdline is + * more interesting and complete. With one exception: + * if we are run in a container /proc/cmdline is not + * relevant for the container, hence we rely on argv[] + * instead. */ + + for (a = argv; a < argv + argc; a++) + if ((r = parse_proc_cmdline_word(*a)) < 0) { + log_error("Failed on cmdline argument %s: %s", *a, strerror(-r)); + return r; + } + } + + return 0; +} + +static int help(void) { + + printf("%s [OPTIONS...]\n\n" + "Starts up and maintains the system or user services.\n\n" + " -h --help Show this help\n" + " --test Determine startup sequence, dump it and exit\n" + " --dump-configuration-items Dump understood unit configuration items\n" + " --introspect[=INTERFACE] Extract D-Bus interface data\n" + " --unit=UNIT Set default unit\n" + " --system Run a system instance, even if PID != 1\n" + " --user Run a user instance\n" + " --dump-core[=0|1] Dump core on crash\n" + " --crash-shell[=0|1] Run shell on crash\n" + " --confirm-spawn[=0|1] Ask for confirmation when spawning processes\n" + " --show-status[=0|1] Show status updates on the console during bootup\n" + " --log-target=TARGET Set log target (console, journal, syslog, kmsg, journal-or-kmsg, syslog-or-kmsg, null)\n" + " --log-level=LEVEL Set log level (debug, info, notice, warning, err, crit, alert, emerg)\n" + " --log-color[=0|1] Highlight important log messages\n" + " --log-location[=0|1] Include code location in log messages\n" + " --default-standard-output= Set default standard output for services\n" + " --default-standard-error= Set default standard error output for services\n", + program_invocation_short_name); + + return 0; +} + +static int version(void) { + puts(PACKAGE_STRING); + puts(SYSTEMD_FEATURES); + + return 0; +} + +static int prepare_reexecute(Manager *m, FILE **_f, FDSet **_fds, bool serialize_jobs) { + FILE *f = NULL; + FDSet *fds = NULL; + int r; + + assert(m); + assert(_f); + assert(_fds); + + /* Make sure nothing is really destructed when we shut down */ + m->n_reloading ++; + + r = manager_open_serialization(m, &f); + if (r < 0) { + log_error("Failed to create serialization file: %s", strerror(-r)); + goto fail; + } + + fds = fdset_new(); + if (!fds) { + r = -ENOMEM; + log_error("Failed to allocate fd set: %s", strerror(-r)); + goto fail; + } + + r = manager_serialize(m, f, fds, serialize_jobs); + if (r < 0) { + log_error("Failed to serialize state: %s", strerror(-r)); + goto fail; + } + + if (fseeko(f, 0, SEEK_SET) < 0) { + log_error("Failed to rewind serialization fd: %m"); + goto fail; + } + + r = fd_cloexec(fileno(f), false); + if (r < 0) { + log_error("Failed to disable O_CLOEXEC for serialization: %s", strerror(-r)); + goto fail; + } + + r = fdset_cloexec(fds, false); + if (r < 0) { + log_error("Failed to disable O_CLOEXEC for serialization fds: %s", strerror(-r)); + goto fail; + } + + *_f = f; + *_fds = fds; + + return 0; + +fail: + fdset_free(fds); + + if (f) + fclose(f); + + return r; +} + +static int bump_rlimit_nofile(struct rlimit *saved_rlimit) { + struct rlimit nl; + int r; + + assert(saved_rlimit); + + /* Save the original RLIMIT_NOFILE so that we can reset it + * later when transitioning from the initrd to the main + * systemd or suchlike. */ + if (getrlimit(RLIMIT_NOFILE, saved_rlimit) < 0) { + log_error("Reading RLIMIT_NOFILE failed: %m"); + return -errno; + } + + /* Make sure forked processes get the default kernel setting */ + if (!arg_default_rlimit[RLIMIT_NOFILE]) { + struct rlimit *rl; + + rl = newdup(struct rlimit, saved_rlimit, 1); + if (!rl) + return log_oom(); + + arg_default_rlimit[RLIMIT_NOFILE] = rl; + } + + /* Bump up the resource limit for ourselves substantially */ + nl.rlim_cur = nl.rlim_max = 64*1024; + r = setrlimit_closest(RLIMIT_NOFILE, &nl); + if (r < 0) { + log_error("Setting RLIMIT_NOFILE failed: %s", strerror(-r)); + return r; + } + + return 0; +} + +static struct dual_timestamp* parse_initrd_timestamp(struct dual_timestamp *t) { + const char *e; + unsigned long long a, b; + + assert(t); + + e = getenv("RD_TIMESTAMP"); + if (!e) + return NULL; + + if (sscanf(e, "%llu %llu", &a, &b) != 2) + return NULL; + + t->realtime = (usec_t) a; + t->monotonic = (usec_t) b; + + return t; +} + +static void test_mtab(void) { + char *p; + + /* Check that /etc/mtab is a symlink */ + + if (readlink_malloc("/etc/mtab", &p) >= 0) { + bool b; + + b = streq(p, "/proc/self/mounts") || streq(p, "/proc/mounts"); + free(p); + + if (b) + return; + } + + log_warning("/etc/mtab is not a symlink or not pointing to /proc/self/mounts. " + "This is not supported anymore. " + "Please make sure to replace this file by a symlink to avoid incorrect or misleading mount(8) output."); +} + +static void test_usr(void) { + + /* Check that /usr is not a separate fs */ + + if (dir_is_empty("/usr") <= 0) + return; + + log_warning("/usr appears to be on its own filesytem and is not already mounted. This is not a supported setup. " + "Some things will probably break (sometimes even silently) in mysterious ways. " + "Consult http://freedesktop.org/wiki/Software/systemd/separate-usr-is-broken for more information."); +} + +static void test_cgroups(void) { + + if (access("/proc/cgroups", F_OK) >= 0) + return; + + log_warning("CONFIG_CGROUPS was not set when your kernel was compiled. " + "Systems without control groups are not supported. " + "We will now sleep for 10s, and then continue boot-up. " + "Expect breakage and please do not file bugs. " + "Instead fix your kernel and enable CONFIG_CGROUPS. " + "Consult http://0pointer.de/blog/projects/cgroups-vs-cgroups.html for more information."); + + sleep(10); +} + +static int initialize_join_controllers(void) { + /* By default, mount "cpu" + "cpuacct" together, and "net_cls" + * + "net_prio". We'd like to add "cpuset" to the mix, but + * "cpuset" does't really work for groups with no initialized + * attributes. */ + + arg_join_controllers = new(char**, 3); + if (!arg_join_controllers) + return -ENOMEM; + + arg_join_controllers[0] = strv_new("cpu", "cpuacct", NULL); + if (!arg_join_controllers[0]) + return -ENOMEM; + + arg_join_controllers[1] = strv_new("net_cls", "net_prio", NULL); + if (!arg_join_controllers[1]) + return -ENOMEM; + + arg_join_controllers[2] = NULL; + return 0; +} + +int main(int argc, char *argv[]) { + Manager *m = NULL; + int r, retval = EXIT_FAILURE; + usec_t before_startup, after_startup; + char timespan[FORMAT_TIMESPAN_MAX]; + FDSet *fds = NULL; + bool reexecute = false; + const char *shutdown_verb = NULL; + dual_timestamp initrd_timestamp = { 0ULL, 0ULL }; + static char systemd[] = "systemd"; + bool skip_setup = false; + int j; + bool loaded_policy = false; + bool arm_reboot_watchdog = false; + bool queue_default_job = false; + char *switch_root_dir = NULL, *switch_root_init = NULL; + static struct rlimit saved_rlimit_nofile = { 0, 0 }; + +#ifdef HAVE_SYSV_COMPAT + if (getpid() != 1 && strstr(program_invocation_short_name, "init")) { + /* This is compatibility support for SysV, where + * calling init as a user is identical to telinit. */ + + errno = -ENOENT; + execv(SYSTEMCTL_BINARY_PATH, argv); + log_error("Failed to exec " SYSTEMCTL_BINARY_PATH ": %m"); + return 1; + } +#endif + + /* 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. */ + for (j = 1; j < argc; j++) + if (streq(argv[j], "--deserialize")) { + skip_setup = true; + break; + } + + /* If we have switched root, do all the special setup + * things */ + for (j = 1; j < argc; j++) + if (streq(argv[j], "--switched-root")) { + skip_setup = false; + break; + } + + /* 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; + prctl(PR_SET_NAME, systemd); + + saved_argv = argv; + saved_argc = argc; + + log_show_color(isatty(STDERR_FILENO) > 0); + + if (getpid() == 1 && detect_container(NULL) <= 0) { + + /* Running outside of a container as PID 1 */ + arg_running_as = SYSTEMD_SYSTEM; + make_null_stdio(); + log_set_target(LOG_TARGET_KMSG); + log_open(); + + if (in_initrd()) { + char *rd_timestamp = NULL; + + dual_timestamp_get(&initrd_timestamp); + asprintf(&rd_timestamp, "%llu %llu", + (unsigned long long) initrd_timestamp.realtime, + (unsigned long long) initrd_timestamp.monotonic); + if (rd_timestamp) { + setenv("RD_TIMESTAMP", rd_timestamp, 1); + free(rd_timestamp); + } + } + + if (!skip_setup) { + if (selinux_setup(&loaded_policy) < 0) + goto finish; + if (ima_setup() < 0) + goto finish; + } + + if (label_init(NULL) < 0) + goto finish; + + if (!skip_setup) { + if (hwclock_is_localtime() > 0) { + int min; + + /* The first-time call to settimeofday() does a time warp in the kernel */ + r = hwclock_set_timezone(&min); + if (r < 0) + log_error("Failed to apply local time delta, ignoring: %s", strerror(-r)); + else + log_info("RTC configured in localtime, applying delta of %i minutes to system time.", min); + } else if (!in_initrd()) { + /* + * Do dummy first-time call to seal the kernel's time warp magic + * + * Do not call this this from inside the initrd. The initrd might not + * carry /etc/adjtime with LOCAL, but the real system could be set up + * that way. In such case, we need to delay the time-warp or the sealing + * until we reach the real system. + */ + hwclock_reset_timezone(); + + /* Tell the kernel our time zone */ + r = hwclock_set_timezone(NULL); + if (r < 0) + log_error("Failed to set the kernel's time zone, ignoring: %s", strerror(-r)); + } + } + + /* Set the default for later on, but don't actually + * open the logs like this for now. Note that if we + * are transitioning from the initrd there might still + * be journal fd open, and we shouldn't attempt + * opening that before we parsed /proc/cmdline which + * might redirect output elsewhere. */ + log_set_target(LOG_TARGET_JOURNAL_OR_KMSG); + + } else if (getpid() == 1) { + + /* Running inside a container, as PID 1 */ + arg_running_as = SYSTEMD_SYSTEM; + log_set_target(LOG_TARGET_CONSOLE); + log_open(); + + /* For the later on, see above... */ + log_set_target(LOG_TARGET_JOURNAL); + + } else { + + /* Running as user instance */ + arg_running_as = SYSTEMD_USER; + log_set_target(LOG_TARGET_AUTO); + log_open(); + } + + /* Initialize default unit */ + r = set_default_unit(SPECIAL_DEFAULT_TARGET); + if (r < 0) { + log_error("Failed to set default unit %s: %s", SPECIAL_DEFAULT_TARGET, strerror(-r)); + goto finish; + } + + r = initialize_join_controllers(); + if (r < 0) + goto finish; + + /* Mount /proc, /sys and friends, so that /proc/cmdline and + * /proc/$PID/fd is available. */ + if (geteuid() == 0 && !getenv("SYSTEMD_SKIP_API_MOUNTS")) { + r = mount_setup(loaded_policy); + if (r < 0) + goto finish; + } + + /* Reset all signal handlers. */ + assert_se(reset_all_signal_handlers() == 0); + + /* If we are init, we can block sigkill. Yay. */ + ignore_signals(SIGNALS_IGNORE, -1); + + if (parse_config_file() < 0) + goto finish; + + if (arg_running_as == SYSTEMD_SYSTEM) + if (parse_proc_cmdline() < 0) + goto finish; + + log_parse_environment(); + + if (parse_argv(argc, argv) < 0) + goto finish; + + if (arg_action == ACTION_TEST && + geteuid() == 0) { + log_error("Don't run test mode as root."); + goto finish; + } + + if (arg_running_as == SYSTEMD_USER && + arg_action == ACTION_RUN && + sd_booted() <= 0) { + log_error("Trying to run as user instance, but the system has not been booted with systemd."); + goto finish; + } + + if (arg_running_as == SYSTEMD_SYSTEM && + arg_action == ACTION_RUN && + running_in_chroot() > 0) { + log_error("Cannot be run in a chroot() environment."); + goto finish; + } + + if (arg_action == ACTION_HELP) { + retval = help(); + goto finish; + } else if (arg_action == ACTION_VERSION) { + retval = version(); + goto finish; + } else if (arg_action == ACTION_DUMP_CONFIGURATION_ITEMS) { + unit_dump_config_items(stdout); + retval = EXIT_SUCCESS; + goto finish; + } else if (arg_action == ACTION_DONE) { + retval = EXIT_SUCCESS; + goto finish; + } + + assert_se(arg_action == ACTION_RUN || arg_action == ACTION_TEST); + + /* Close logging fds, in order not to confuse fdset below */ + log_close(); + + /* Remember open file descriptors for later deserialization */ + r = fdset_new_fill(&fds); + if (r < 0) { + log_error("Failed to allocate fd set: %s", strerror(-r)); + goto finish; + } else + fdset_cloexec(fds, true); + + if (serialization) + assert_se(fdset_remove(fds, fileno(serialization)) >= 0); + + /* Set up PATH unless it is already set */ + setenv("PATH", +#ifdef HAVE_SPLIT_USR + "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", +#else + "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin", +#endif + arg_running_as == SYSTEMD_SYSTEM); + + if (arg_running_as == SYSTEMD_SYSTEM) { + /* Parse the data passed to us. We leave this + * variables set, but the manager later on will not + * pass them on to our children. */ + if (!in_initrd()) + parse_initrd_timestamp(&initrd_timestamp); + + /* Unset some environment variables passed in from the + * kernel that don't really make sense for us. */ + unsetenv("HOME"); + unsetenv("TERM"); + + /* When we are invoked by a shell, these might be set, + * but make little sense to pass on */ + unsetenv("PWD"); + unsetenv("SHLVL"); + unsetenv("_"); + + /* When we are invoked by a chroot-like tool such as + * nspawn, these might be set, but make little sense + * to pass on */ + unsetenv("USER"); + unsetenv("LOGNAME"); + + /* We suppress the socket activation env vars, as + * we'll try to match *any* open fd to units if + * possible. */ + unsetenv("LISTEN_FDS"); + unsetenv("LISTEN_PID"); + + /* All other variables are left as is, so that clients + * can still read them via /proc/1/environ */ + } + + /* Move out of the way, so that we won't block unmounts */ + assert_se(chdir("/") == 0); + + if (arg_running_as == SYSTEMD_SYSTEM) { + /* Become a session leader if we aren't one yet. */ + setsid(); + + /* Disable the umask logic */ + umask(0); + } + + /* Make sure D-Bus doesn't fiddle with the SIGPIPE handlers */ + dbus_connection_set_change_sigpipe(FALSE); + + /* Reset the console, but only if this is really init and we + * are freshly booted */ + if (arg_running_as == SYSTEMD_SYSTEM && arg_action == ACTION_RUN) + console_setup(getpid() == 1 && !skip_setup); + + /* Open the logging devices, if possible and necessary */ + log_open(); + + /* Make sure we leave a core dump without panicing the + * kernel. */ + if (getpid() == 1) + install_crash_handler(); + + if (geteuid() == 0 && !getenv("SYSTEMD_SKIP_API_MOUNTS")) { + r = mount_cgroup_controllers(arg_join_controllers); + if (r < 0) + goto finish; + } + + if (arg_running_as == SYSTEMD_SYSTEM) { + const char *virtualization = NULL; + + log_info(PACKAGE_STRING " running in system mode. (" SYSTEMD_FEATURES ")"); + + detect_virtualization(&virtualization); + if (virtualization) + log_info("Detected virtualization '%s'.", virtualization); + + if (in_initrd()) + log_info("Running in initial RAM disk."); + + } else + log_debug(PACKAGE_STRING " running in user mode. (" SYSTEMD_FEATURES ")"); + + if (arg_running_as == SYSTEMD_SYSTEM && !skip_setup) { + locale_setup(); + + if (arg_show_status || plymouth_running()) + status_welcome(); + +#ifdef HAVE_KMOD + kmod_setup(); +#endif + hostname_setup(); + machine_id_setup(); + loopback_setup(); + + test_mtab(); + test_usr(); + test_cgroups(); + } + + if (arg_running_as == SYSTEMD_SYSTEM && arg_runtime_watchdog > 0) + watchdog_set_timeout(&arg_runtime_watchdog); + + if (arg_timer_slack_nsec != (nsec_t) -1) + if (prctl(PR_SET_TIMERSLACK, arg_timer_slack_nsec) < 0) + log_error("Failed to adjust timer slack: %m"); + + if (arg_capability_bounding_set_drop) { + r = capability_bounding_set_drop(arg_capability_bounding_set_drop, true); + if (r < 0) { + log_error("Failed to drop capability bounding set: %s", strerror(-r)); + goto finish; + } + r = capability_bounding_set_drop_usermode(arg_capability_bounding_set_drop); + if (r < 0) { + log_error("Failed to drop capability bounding set of usermode helpers: %s", strerror(-r)); + goto finish; + } + } + + if (arg_running_as == SYSTEMD_USER) { + /* Become reaper of our children */ + if (prctl(PR_SET_CHILD_SUBREAPER, 1) < 0) { + log_warning("Failed to make us a subreaper: %m"); + if (errno == EINVAL) + log_info("Perhaps the kernel version is too old (< 3.4?)"); + } + } + + if (arg_running_as == SYSTEMD_SYSTEM) + bump_rlimit_nofile(&saved_rlimit_nofile); + + r = manager_new(arg_running_as, &m); + if (r < 0) { + log_error("Failed to allocate manager object: %s", strerror(-r)); + goto finish; + } + + m->confirm_spawn = arg_confirm_spawn; + m->default_std_output = arg_default_std_output; + m->default_std_error = arg_default_std_error; + m->runtime_watchdog = arg_runtime_watchdog; + m->shutdown_watchdog = arg_shutdown_watchdog; + + manager_set_default_rlimits(m, arg_default_rlimit); + + if (dual_timestamp_is_set(&initrd_timestamp)) + m->initrd_timestamp = initrd_timestamp; + + if (arg_default_controllers) + manager_set_default_controllers(m, arg_default_controllers); + + manager_set_show_status(m, arg_show_status); + + /* Remember whether we should queue the default job */ + queue_default_job = !serialization || arg_switched_root; + + before_startup = now(CLOCK_MONOTONIC); + + r = manager_startup(m, serialization, fds); + if (r < 0) + log_error("Failed to fully start up daemon: %s", strerror(-r)); + + /* This will close all file descriptors that were opened, but + * not claimed by any unit. */ + fdset_free(fds); + + if (serialization) { + fclose(serialization); + serialization = NULL; + } + + if (queue_default_job) { + DBusError error; + Unit *target = NULL; + Job *default_unit_job; + + dbus_error_init(&error); + + log_debug("Activating default unit: %s", arg_default_unit); + + r = manager_load_unit(m, arg_default_unit, NULL, &error, &target); + if (r < 0) { + log_error("Failed to load default target: %s", bus_error(&error, r)); + dbus_error_free(&error); + } else if (target->load_state == UNIT_ERROR) + log_error("Failed to load default target: %s", strerror(-target->load_error)); + else if (target->load_state == UNIT_MASKED) + log_error("Default target masked."); + + if (!target || target->load_state != UNIT_LOADED) { + log_info("Trying to load rescue target..."); + + r = manager_load_unit(m, SPECIAL_RESCUE_TARGET, NULL, &error, &target); + if (r < 0) { + log_error("Failed to load rescue target: %s", bus_error(&error, r)); + dbus_error_free(&error); + goto finish; + } else if (target->load_state == UNIT_ERROR) { + log_error("Failed to load rescue target: %s", strerror(-target->load_error)); + goto finish; + } else if (target->load_state == UNIT_MASKED) { + log_error("Rescue target masked."); + goto finish; + } + } + + assert(target->load_state == UNIT_LOADED); + + if (arg_action == ACTION_TEST) { + printf("-> By units:\n"); + manager_dump_units(m, stdout, "\t"); + } + + r = manager_add_job(m, JOB_START, target, JOB_REPLACE, false, &error, &default_unit_job); + if (r < 0) { + log_error("Failed to start default target: %s", bus_error(&error, r)); + dbus_error_free(&error); + goto finish; + } + m->default_unit_job_id = default_unit_job->id; + + after_startup = now(CLOCK_MONOTONIC); + log_full(arg_action == ACTION_TEST ? LOG_INFO : LOG_DEBUG, + "Loaded units and determined initial transaction in %s.", + format_timespan(timespan, sizeof(timespan), after_startup - before_startup)); + + if (arg_action == ACTION_TEST) { + printf("-> By jobs:\n"); + manager_dump_jobs(m, stdout, "\t"); + retval = EXIT_SUCCESS; + goto finish; + } + } + + for (;;) { + r = manager_loop(m); + if (r < 0) { + log_error("Failed to run mainloop: %s", strerror(-r)); + goto finish; + } + + switch (m->exit_code) { + + case MANAGER_EXIT: + retval = EXIT_SUCCESS; + log_debug("Exit."); + goto finish; + + case MANAGER_RELOAD: + log_info("Reloading."); + r = manager_reload(m); + if (r < 0) + log_error("Failed to reload: %s", strerror(-r)); + break; + + case MANAGER_REEXECUTE: + + if (prepare_reexecute(m, &serialization, &fds, true) < 0) + goto finish; + + reexecute = true; + log_notice("Reexecuting."); + goto finish; + + case MANAGER_SWITCH_ROOT: + /* Steal the switch root parameters */ + switch_root_dir = m->switch_root; + switch_root_init = m->switch_root_init; + m->switch_root = m->switch_root_init = NULL; + + if (!switch_root_init) + if (prepare_reexecute(m, &serialization, &fds, false) < 0) + goto finish; + + reexecute = true; + log_notice("Switching root."); + goto finish; + + case MANAGER_REBOOT: + case MANAGER_POWEROFF: + case MANAGER_HALT: + case MANAGER_KEXEC: { + static const char * const table[_MANAGER_EXIT_CODE_MAX] = { + [MANAGER_REBOOT] = "reboot", + [MANAGER_POWEROFF] = "poweroff", + [MANAGER_HALT] = "halt", + [MANAGER_KEXEC] = "kexec" + }; + + assert_se(shutdown_verb = table[m->exit_code]); + arm_reboot_watchdog = m->exit_code == MANAGER_REBOOT; + + log_notice("Shutting down."); + goto finish; + } + + default: + assert_not_reached("Unknown exit code."); + } + } + +finish: + if (m) + manager_free(m); + + for (j = 0; j < RLIMIT_NLIMITS; j++) + free(arg_default_rlimit[j]); + + free(arg_default_unit); + strv_free(arg_default_controllers); + free_join_controllers(); + + dbus_shutdown(); + label_finish(); + + if (reexecute) { + const char **args; + unsigned i, args_size; + + /* Close and disarm the watchdog, so that the new + * instance can reinitialize it, but doesn't get + * rebooted while we do that */ + watchdog_close(true); + + /* Reset the RLIMIT_NOFILE to the kernel default, so + * that the new systemd can pass the kernel default to + * its child processes */ + if (saved_rlimit_nofile.rlim_cur > 0) + setrlimit(RLIMIT_NOFILE, &saved_rlimit_nofile); + + 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); + + /* And switch root */ + r = switch_root(switch_root_dir); + if (r < 0) + log_error("Failed to switch root, ignoring: %s", strerror(-r)); + } + + args_size = MAX(6, argc+1); + args = newa(const char*, args_size); + + if (!switch_root_init) { + char sfd[16]; + + /* First try to spawn ourselves with the right + * path, and with full serialization. We do + * this only if the user didn't specify an + * explicit init to spawn. */ + + assert(serialization); + assert(fds); + + snprintf(sfd, sizeof(sfd), "%i", fileno(serialization)); + char_array_0(sfd); + + i = 0; + args[i++] = SYSTEMD_BINARY_PATH; + if (switch_root_dir) + args[i++] = "--switched-root"; + args[i++] = arg_running_as == SYSTEMD_SYSTEM ? "--system" : "--user"; + args[i++] = "--deserialize"; + args[i++] = sfd; + args[i++] = NULL; + + assert(i <= args_size); + execv(args[0], (char* const*) args); + } + + /* Try the fallback, if there is any, without any + * serialization. We pass the original argv[] and + * envp[]. (Well, modulo the ordering changes due to + * getopt() in argv[], and some cleanups in envp[], + * but let's hope that doesn't matter.) */ + + if (serialization) { + fclose(serialization); + serialization = NULL; + } + + if (fds) { + fdset_free(fds); + fds = NULL; + } + + /* Reopen the console */ + make_console_stdio(); + + for (j = 1, i = 1; j < argc; j++) + args[i++] = argv[j]; + args[i++] = NULL; + assert(i <= args_size); + + if (switch_root_init) { + args[0] = switch_root_init; + execv(args[0], (char* const*) args); + log_warning("Failed to execute configured init, trying fallback: %m"); + } + + args[0] = "/sbin/init"; + execv(args[0], (char* const*) args); + + if (errno == ENOENT) { + log_warning("No /sbin/init, trying fallback"); + + args[0] = "/bin/sh"; + args[1] = NULL; + execv(args[0], (char* const*) args); + log_error("Failed to execute /bin/sh, giving up: %m"); + } else + log_warning("Failed to execute /sbin/init, giving up: %m"); + } + + if (serialization) + fclose(serialization); + + if (fds) + fdset_free(fds); + + if (shutdown_verb) { + const char * command_line[] = { + SYSTEMD_SHUTDOWN_BINARY_PATH, + shutdown_verb, + NULL + }; + char **env_block; + + if (arm_reboot_watchdog && arg_shutdown_watchdog > 0) { + char e[32]; + + /* If we reboot let's set the shutdown + * watchdog and tell the shutdown binary to + * repeatedly ping it */ + watchdog_set_timeout(&arg_shutdown_watchdog); + watchdog_close(false); + + /* Tell the binary how often to ping */ + snprintf(e, sizeof(e), "WATCHDOG_USEC=%llu", (unsigned long long) arg_shutdown_watchdog); + char_array_0(e); + + env_block = strv_append(environ, e); + } else { + env_block = strv_copy(environ); + watchdog_close(true); + } + + execve(SYSTEMD_SHUTDOWN_BINARY_PATH, (char **) command_line, env_block); + free(env_block); + log_error("Failed to execute shutdown binary, freezing: %m"); + } + + if (getpid() == 1) + freeze(); + + return retval; +} diff --git a/src/core/manager.c b/src/core/manager.c new file mode 100644 index 000000000..3a4023f31 --- /dev/null +++ b/src/core/manager.c @@ -0,0 +1,2461 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_AUDIT +#include +#endif + +#include "systemd/sd-daemon.h" +#include "systemd/sd-id128.h" +#include "systemd/sd-messages.h" + +#include "manager.h" +#include "transaction.h" +#include "hashmap.h" +#include "macro.h" +#include "strv.h" +#include "log.h" +#include "util.h" +#include "mkdir.h" +#include "ratelimit.h" +#include "cgroup.h" +#include "mount-setup.h" +#include "unit-name.h" +#include "dbus-unit.h" +#include "dbus-job.h" +#include "missing.h" +#include "path-lookup.h" +#include "special.h" +#include "bus-errors.h" +#include "exit-status.h" +#include "virt.h" +#include "watchdog.h" +#include "cgroup-util.h" +#include "path-util.h" +#include "audit-fd.h" + +/* As soon as 16 units are in our GC queue, make sure to run a gc sweep */ +#define GC_QUEUE_ENTRIES_MAX 16 + +/* As soon as 5s passed since a unit was added to our GC queue, make sure to run a gc sweep */ +#define GC_QUEUE_USEC_MAX (10*USEC_PER_SEC) + +/* Where clients shall send notification messages to */ +#define NOTIFY_SOCKET "@/org/freedesktop/systemd1/notify" + +static int manager_setup_notify(Manager *m) { + union { + struct sockaddr sa; + struct sockaddr_un un; + } sa; + struct epoll_event ev; + int one = 1; + + assert(m); + + m->notify_watch.type = WATCH_NOTIFY; + m->notify_watch.fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0); + if (m->notify_watch.fd < 0) { + log_error("Failed to allocate notification socket: %m"); + return -errno; + } + + zero(sa); + sa.sa.sa_family = AF_UNIX; + + if (getpid() != 1 || detect_container(NULL) > 0) + snprintf(sa.un.sun_path, sizeof(sa.un.sun_path), NOTIFY_SOCKET "/%llu", random_ull()); + else + strncpy(sa.un.sun_path, NOTIFY_SOCKET, sizeof(sa.un.sun_path)); + + sa.un.sun_path[0] = 0; + + if (bind(m->notify_watch.fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + 1 + strlen(sa.un.sun_path+1)) < 0) { + log_error("bind() failed: %m"); + return -errno; + } + + if (setsockopt(m->notify_watch.fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one)) < 0) { + log_error("SO_PASSCRED failed: %m"); + return -errno; + } + + zero(ev); + ev.events = EPOLLIN; + ev.data.ptr = &m->notify_watch; + + if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->notify_watch.fd, &ev) < 0) { + log_error("Failed to add timer change fd to epoll: %m"); + return -errno; + } + + sa.un.sun_path[0] = '@'; + m->notify_socket = strdup(sa.un.sun_path); + if (!m->notify_socket) + return log_oom(); + + log_debug("Using notification socket %s", m->notify_socket); + + return 0; +} + +static int manager_setup_time_change(Manager *m) { + struct epoll_event ev; + struct itimerspec its; + + assert(m); + assert(m->time_change_watch.type == WATCH_INVALID); + + /* Uses TFD_TIMER_CANCEL_ON_SET to get notifications whenever + * CLOCK_REALTIME makes a jump relative to CLOCK_MONOTONIC */ + + m->time_change_watch.type = WATCH_TIME_CHANGE; + m->time_change_watch.fd = timerfd_create(CLOCK_REALTIME, TFD_NONBLOCK|TFD_CLOEXEC); + if (m->time_change_watch.fd < 0) { + log_error("Failed to create timerfd: %m"); + return -errno; + } + + zero(its); + + /* We only care for the cancellation event, hence we set the + * timeout to the latest possible value. */ + assert_cc(sizeof(time_t) == sizeof(long)); + its.it_value.tv_sec = LONG_MAX; + + if (timerfd_settime(m->time_change_watch.fd, TFD_TIMER_ABSTIME|TFD_TIMER_CANCEL_ON_SET, &its, NULL) < 0) { + log_debug("Failed to set up TFD_TIMER_CANCEL_ON_SET, ignoring: %m"); + close_nointr_nofail(m->time_change_watch.fd); + watch_init(&m->time_change_watch); + return 0; + } + + zero(ev); + ev.events = EPOLLIN; + ev.data.ptr = &m->time_change_watch; + + if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->time_change_watch.fd, &ev) < 0) { + log_error("Failed to add timer change fd to epoll: %m"); + return -errno; + } + + log_debug("Set up TFD_TIMER_CANCEL_ON_SET timerfd."); + + return 0; +} + +static int enable_special_signals(Manager *m) { + int fd; + + assert(m); + + /* Enable that we get SIGINT on control-alt-del. In containers + * this will fail with EPERM (older) or EINVAL (newer), so + * ignore that. */ + if (reboot(RB_DISABLE_CAD) < 0 && errno != EPERM && errno != EINVAL) + log_warning("Failed to enable ctrl-alt-del handling: %m"); + + fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC); + if (fd < 0) { + /* Support systems without virtual console */ + if (fd != -ENOENT) + log_warning("Failed to open /dev/tty0: %m"); + } else { + /* Enable that we get SIGWINCH on kbrequest */ + if (ioctl(fd, KDSIGACCEPT, SIGWINCH) < 0) + log_warning("Failed to enable kbrequest handling: %s", strerror(errno)); + + close_nointr_nofail(fd); + } + + return 0; +} + +static int manager_setup_signals(Manager *m) { + sigset_t mask; + struct epoll_event ev; + struct sigaction sa; + + assert(m); + + /* We are not interested in SIGSTOP and friends. */ + zero(sa); + sa.sa_handler = SIG_DFL; + sa.sa_flags = SA_NOCLDSTOP|SA_RESTART; + assert_se(sigaction(SIGCHLD, &sa, NULL) == 0); + + assert_se(sigemptyset(&mask) == 0); + + sigset_add_many(&mask, + SIGCHLD, /* Child died */ + SIGTERM, /* Reexecute daemon */ + SIGHUP, /* Reload configuration */ + SIGUSR1, /* systemd/upstart: reconnect to D-Bus */ + SIGUSR2, /* systemd: dump status */ + SIGINT, /* Kernel sends us this on control-alt-del */ + SIGWINCH, /* Kernel sends us this on kbrequest (alt-arrowup) */ + SIGPWR, /* Some kernel drivers and upsd send us this on power failure */ + SIGRTMIN+0, /* systemd: start default.target */ + SIGRTMIN+1, /* systemd: isolate rescue.target */ + SIGRTMIN+2, /* systemd: isolate emergency.target */ + SIGRTMIN+3, /* systemd: start halt.target */ + SIGRTMIN+4, /* systemd: start poweroff.target */ + SIGRTMIN+5, /* systemd: start reboot.target */ + SIGRTMIN+6, /* systemd: start kexec.target */ + SIGRTMIN+13, /* systemd: Immediate halt */ + SIGRTMIN+14, /* systemd: Immediate poweroff */ + SIGRTMIN+15, /* systemd: Immediate reboot */ + SIGRTMIN+16, /* systemd: Immediate kexec */ + SIGRTMIN+20, /* systemd: enable status messages */ + SIGRTMIN+21, /* systemd: disable status messages */ + SIGRTMIN+22, /* systemd: set log level to LOG_DEBUG */ + SIGRTMIN+23, /* systemd: set log level to LOG_INFO */ + SIGRTMIN+24, /* systemd: Immediate exit (--user only) */ + SIGRTMIN+26, /* systemd: set log target to journal-or-kmsg */ + SIGRTMIN+27, /* systemd: set log target to console */ + SIGRTMIN+28, /* systemd: set log target to kmsg */ + SIGRTMIN+29, /* systemd: set log target to syslog-or-kmsg */ + -1); + assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0); + + m->signal_watch.type = WATCH_SIGNAL; + m->signal_watch.fd = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC); + if (m->signal_watch.fd < 0) + return -errno; + + zero(ev); + ev.events = EPOLLIN; + ev.data.ptr = &m->signal_watch; + + if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->signal_watch.fd, &ev) < 0) + return -errno; + + if (m->running_as == SYSTEMD_SYSTEM) + return enable_special_signals(m); + + return 0; +} + +static void manager_strip_environment(Manager *m) { + assert(m); + + /* Remove variables from the inherited set that are part of + * the container interface: + * http://www.freedesktop.org/wiki/Software/systemd/ContainerInterface */ + strv_remove_prefix(m->environment, "container="); + strv_remove_prefix(m->environment, "container_"); + + /* Remove variables from the inherited set that are part of + * the initrd interface: + * http://www.freedesktop.org/wiki/Software/systemd/InitrdInterface */ + strv_remove_prefix(m->environment, "RD_"); +} + +int manager_new(SystemdRunningAs running_as, Manager **_m) { + Manager *m; + int r = -ENOMEM; + + assert(_m); + assert(running_as >= 0); + assert(running_as < _SYSTEMD_RUNNING_AS_MAX); + + m = new0(Manager, 1); + if (!m) + return -ENOMEM; + + dual_timestamp_get(&m->userspace_timestamp); + + m->running_as = running_as; + m->name_data_slot = m->conn_data_slot = m->subscribed_data_slot = -1; + m->exit_code = _MANAGER_EXIT_CODE_INVALID; + m->pin_cgroupfs_fd = -1; + m->idle_pipe[0] = m->idle_pipe[1] = -1; + + watch_init(&m->signal_watch); + watch_init(&m->mount_watch); + watch_init(&m->swap_watch); + watch_init(&m->udev_watch); + watch_init(&m->time_change_watch); + + m->epoll_fd = m->dev_autofs_fd = -1; + m->current_job_id = 1; /* start as id #1, so that we can leave #0 around as "null-like" value */ + + m->environment = strv_copy(environ); + if (!m->environment) + goto fail; + + manager_strip_environment(m); + + if (running_as == SYSTEMD_SYSTEM) { + m->default_controllers = strv_new("cpu", NULL); + if (!m->default_controllers) + goto fail; + } + + if (!(m->units = hashmap_new(string_hash_func, string_compare_func))) + goto fail; + + if (!(m->jobs = hashmap_new(trivial_hash_func, trivial_compare_func))) + goto fail; + + if (!(m->watch_pids = hashmap_new(trivial_hash_func, trivial_compare_func))) + goto fail; + + if (!(m->cgroup_bondings = hashmap_new(string_hash_func, string_compare_func))) + goto fail; + + if (!(m->watch_bus = hashmap_new(string_hash_func, string_compare_func))) + goto fail; + + m->epoll_fd = epoll_create1(EPOLL_CLOEXEC); + if (m->epoll_fd < 0) + goto fail; + + r = manager_setup_signals(m); + if (r < 0) + goto fail; + + r = manager_setup_cgroup(m); + if (r < 0) + goto fail; + + r = manager_setup_notify(m); + if (r < 0) + goto fail; + + r = manager_setup_time_change(m); + if (r < 0) + goto fail; + + /* Try to connect to the busses, if possible. */ + r = bus_init(m, running_as != SYSTEMD_SYSTEM); + if (r < 0) + goto fail; + + m->taint_usr = dir_is_empty("/usr") > 0; + + *_m = m; + return 0; + +fail: + manager_free(m); + return r; +} + +static unsigned manager_dispatch_cleanup_queue(Manager *m) { + Unit *u; + unsigned n = 0; + + assert(m); + + while ((u = m->cleanup_queue)) { + assert(u->in_cleanup_queue); + + unit_free(u); + n++; + } + + return n; +} + +enum { + GC_OFFSET_IN_PATH, /* This one is on the path we were traveling */ + GC_OFFSET_UNSURE, /* No clue */ + GC_OFFSET_GOOD, /* We still need this unit */ + GC_OFFSET_BAD, /* We don't need this unit anymore */ + _GC_OFFSET_MAX +}; + +static void unit_gc_sweep(Unit *u, unsigned gc_marker) { + Iterator i; + Unit *other; + bool is_bad; + + assert(u); + + if (u->gc_marker == gc_marker + GC_OFFSET_GOOD || + u->gc_marker == gc_marker + GC_OFFSET_BAD || + u->gc_marker == gc_marker + GC_OFFSET_IN_PATH) + return; + + if (u->in_cleanup_queue) + goto bad; + + if (unit_check_gc(u)) + goto good; + + u->gc_marker = gc_marker + GC_OFFSET_IN_PATH; + + is_bad = true; + + SET_FOREACH(other, u->dependencies[UNIT_REFERENCED_BY], i) { + unit_gc_sweep(other, gc_marker); + + if (other->gc_marker == gc_marker + GC_OFFSET_GOOD) + goto good; + + if (other->gc_marker != gc_marker + GC_OFFSET_BAD) + is_bad = false; + } + + if (is_bad) + goto bad; + + /* We were unable to find anything out about this entry, so + * let's investigate it later */ + u->gc_marker = gc_marker + GC_OFFSET_UNSURE; + unit_add_to_gc_queue(u); + return; + +bad: + /* We definitely know that this one is not useful anymore, so + * let's mark it for deletion */ + u->gc_marker = gc_marker + GC_OFFSET_BAD; + unit_add_to_cleanup_queue(u); + return; + +good: + u->gc_marker = gc_marker + GC_OFFSET_GOOD; +} + +static unsigned manager_dispatch_gc_queue(Manager *m) { + Unit *u; + unsigned n = 0; + unsigned gc_marker; + + assert(m); + + if ((m->n_in_gc_queue < GC_QUEUE_ENTRIES_MAX) && + (m->gc_queue_timestamp <= 0 || + (m->gc_queue_timestamp + GC_QUEUE_USEC_MAX) > now(CLOCK_MONOTONIC))) + return 0; + + log_debug("Running GC..."); + + m->gc_marker += _GC_OFFSET_MAX; + if (m->gc_marker + _GC_OFFSET_MAX <= _GC_OFFSET_MAX) + m->gc_marker = 1; + + gc_marker = m->gc_marker; + + while ((u = m->gc_queue)) { + assert(u->in_gc_queue); + + unit_gc_sweep(u, gc_marker); + + LIST_REMOVE(Unit, gc_queue, m->gc_queue, u); + u->in_gc_queue = false; + + n++; + + if (u->gc_marker == gc_marker + GC_OFFSET_BAD || + u->gc_marker == gc_marker + GC_OFFSET_UNSURE) { + log_debug_unit(u->id, "Collecting %s", u->id); + u->gc_marker = gc_marker + GC_OFFSET_BAD; + unit_add_to_cleanup_queue(u); + } + } + + m->n_in_gc_queue = 0; + m->gc_queue_timestamp = 0; + + return n; +} + +static void manager_clear_jobs_and_units(Manager *m) { + Unit *u; + + assert(m); + + while ((u = hashmap_first(m->units))) + unit_free(u); + + manager_dispatch_cleanup_queue(m); + + assert(!m->load_queue); + assert(!m->run_queue); + assert(!m->dbus_unit_queue); + assert(!m->dbus_job_queue); + assert(!m->cleanup_queue); + assert(!m->gc_queue); + + assert(hashmap_isempty(m->jobs)); + assert(hashmap_isempty(m->units)); +} + +void manager_free(Manager *m) { + UnitType c; + int i; + + assert(m); + + manager_clear_jobs_and_units(m); + + for (c = 0; c < _UNIT_TYPE_MAX; c++) + if (unit_vtable[c]->shutdown) + unit_vtable[c]->shutdown(m); + + /* If we reexecute ourselves, we keep the root cgroup + * around */ + manager_shutdown_cgroup(m, m->exit_code != MANAGER_REEXECUTE); + + manager_undo_generators(m); + + bus_done(m); + + hashmap_free(m->units); + hashmap_free(m->jobs); + hashmap_free(m->watch_pids); + hashmap_free(m->watch_bus); + + if (m->epoll_fd >= 0) + close_nointr_nofail(m->epoll_fd); + if (m->signal_watch.fd >= 0) + close_nointr_nofail(m->signal_watch.fd); + if (m->notify_watch.fd >= 0) + close_nointr_nofail(m->notify_watch.fd); + if (m->time_change_watch.fd >= 0) + close_nointr_nofail(m->time_change_watch.fd); + + free(m->notify_socket); + + lookup_paths_free(&m->lookup_paths); + strv_free(m->environment); + + strv_free(m->default_controllers); + + hashmap_free(m->cgroup_bondings); + set_free_free(m->unit_path_cache); + + close_pipe(m->idle_pipe); + + free(m->switch_root); + free(m->switch_root_init); + + for (i = 0; i < RLIMIT_NLIMITS; i++) + free(m->rlimit[i]); + + free(m); +} + +int manager_enumerate(Manager *m) { + int r = 0, q; + UnitType c; + + assert(m); + + /* Let's ask every type to load all units from disk/kernel + * that it might know */ + for (c = 0; c < _UNIT_TYPE_MAX; c++) + if (unit_vtable[c]->enumerate) + if ((q = unit_vtable[c]->enumerate(m)) < 0) + r = q; + + manager_dispatch_load_queue(m); + return r; +} + +int manager_coldplug(Manager *m) { + int r = 0, q; + Iterator i; + Unit *u; + char *k; + + assert(m); + + /* Then, let's set up their initial state. */ + HASHMAP_FOREACH_KEY(u, k, m->units, i) { + + /* ignore aliases */ + if (u->id != k) + continue; + + if ((q = unit_coldplug(u)) < 0) + r = q; + } + + return r; +} + +static void manager_build_unit_path_cache(Manager *m) { + char **i; + DIR *d = NULL; + int r; + + assert(m); + + set_free_free(m->unit_path_cache); + + if (!(m->unit_path_cache = set_new(string_hash_func, string_compare_func))) { + log_error("Failed to allocate unit path cache."); + return; + } + + /* This simply builds a list of files we know exist, so that + * we don't always have to go to disk */ + + STRV_FOREACH(i, m->lookup_paths.unit_path) { + struct dirent *de; + + d = opendir(*i); + if (!d) { + log_error("Failed to open directory: %m"); + continue; + } + + while ((de = readdir(d))) { + char *p; + + if (ignore_file(de->d_name)) + continue; + + p = strjoin(streq(*i, "/") ? "" : *i, "/", de->d_name, NULL); + if (!p) { + r = -ENOMEM; + goto fail; + } + + if ((r = set_put(m->unit_path_cache, p)) < 0) { + free(p); + goto fail; + } + } + + closedir(d); + d = NULL; + } + + return; + +fail: + log_error("Failed to build unit path cache: %s", strerror(-r)); + + set_free_free(m->unit_path_cache); + m->unit_path_cache = NULL; + + if (d) + closedir(d); +} + +int manager_startup(Manager *m, FILE *serialization, FDSet *fds) { + int r, q; + + assert(m); + + manager_run_generators(m); + + r = lookup_paths_init( + &m->lookup_paths, m->running_as, true, + m->generator_unit_path, + m->generator_unit_path_early, + m->generator_unit_path_late); + if (r < 0) + return r; + + manager_build_unit_path_cache(m); + + /* If we will deserialize make sure that during enumeration + * this is already known, so we increase the counter here + * already */ + if (serialization) + m->n_reloading ++; + + /* First, enumerate what we can from all config files */ + r = manager_enumerate(m); + + /* Second, deserialize if there is something to deserialize */ + if (serialization) { + q = manager_deserialize(m, serialization, fds); + if (q < 0) + r = q; + } + + /* Any fds left? Find some unit which wants them. This is + * useful to allow container managers to pass some file + * descriptors to us pre-initialized. This enables + * socket-based activation of entire containers. */ + if (fdset_size(fds) > 0) { + q = manager_distribute_fds(m, fds); + if (q < 0) + r = q; + } + + /* Third, fire things up! */ + q = manager_coldplug(m); + if (q < 0) + r = q; + + if (serialization) { + assert(m->n_reloading > 0); + m->n_reloading --; + } + + return r; +} + +int manager_add_job(Manager *m, JobType type, Unit *unit, JobMode mode, bool override, DBusError *e, Job **_ret) { + int r; + Transaction *tr; + + assert(m); + assert(type < _JOB_TYPE_MAX); + assert(unit); + assert(mode < _JOB_MODE_MAX); + + if (mode == JOB_ISOLATE && type != JOB_START) { + dbus_set_error(e, BUS_ERROR_INVALID_JOB_MODE, "Isolate is only valid for start."); + return -EINVAL; + } + + if (mode == JOB_ISOLATE && !unit->allow_isolate) { + dbus_set_error(e, BUS_ERROR_NO_ISOLATION, "Operation refused, unit may not be isolated."); + return -EPERM; + } + + log_debug_unit(unit->id, + "Trying to enqueue job %s/%s/%s", unit->id, + job_type_to_string(type), job_mode_to_string(mode)); + + job_type_collapse(&type, unit); + + tr = transaction_new(); + if (!tr) + return -ENOMEM; + + r = transaction_add_job_and_dependencies(tr, type, unit, NULL, true, override, false, + mode == JOB_IGNORE_DEPENDENCIES || mode == JOB_IGNORE_REQUIREMENTS, + mode == JOB_IGNORE_DEPENDENCIES, e); + if (r < 0) + goto tr_abort; + + if (mode == JOB_ISOLATE) { + r = transaction_add_isolate_jobs(tr, m); + if (r < 0) + goto tr_abort; + } + + r = transaction_activate(tr, m, mode, e); + if (r < 0) + goto tr_abort; + + log_debug_unit(unit->id, + "Enqueued job %s/%s as %u", unit->id, + job_type_to_string(type), (unsigned) tr->anchor_job->id); + + if (_ret) + *_ret = tr->anchor_job; + + transaction_free(tr); + return 0; + +tr_abort: + transaction_abort(tr); + transaction_free(tr); + return r; +} + +int manager_add_job_by_name(Manager *m, JobType type, const char *name, JobMode mode, bool override, DBusError *e, Job **_ret) { + Unit *unit; + int r; + + assert(m); + assert(type < _JOB_TYPE_MAX); + assert(name); + assert(mode < _JOB_MODE_MAX); + + r = manager_load_unit(m, name, NULL, NULL, &unit); + if (r < 0) + return r; + + return manager_add_job(m, type, unit, mode, override, e, _ret); +} + +Job *manager_get_job(Manager *m, uint32_t id) { + assert(m); + + return hashmap_get(m->jobs, UINT32_TO_PTR(id)); +} + +Unit *manager_get_unit(Manager *m, const char *name) { + assert(m); + assert(name); + + return hashmap_get(m->units, name); +} + +unsigned manager_dispatch_load_queue(Manager *m) { + Unit *u; + unsigned n = 0; + + assert(m); + + /* Make sure we are not run recursively */ + if (m->dispatching_load_queue) + return 0; + + m->dispatching_load_queue = true; + + /* Dispatches the load queue. Takes a unit from the queue and + * tries to load its data until the queue is empty */ + + while ((u = m->load_queue)) { + assert(u->in_load_queue); + + unit_load(u); + n++; + } + + m->dispatching_load_queue = false; + return n; +} + +int manager_load_unit_prepare(Manager *m, const char *name, const char *path, DBusError *e, Unit **_ret) { + Unit *ret; + UnitType t; + int r; + + assert(m); + assert(name || path); + + /* This will prepare the unit for loading, but not actually + * load anything from disk. */ + + if (path && !is_path(path)) { + dbus_set_error(e, BUS_ERROR_INVALID_PATH, "Path %s is not absolute.", path); + return -EINVAL; + } + + if (!name) + name = path_get_file_name(path); + + t = unit_name_to_type(name); + + if (t == _UNIT_TYPE_INVALID || !unit_name_is_valid(name, false)) { + dbus_set_error(e, BUS_ERROR_INVALID_NAME, "Unit name %s is not valid.", name); + return -EINVAL; + } + + ret = manager_get_unit(m, name); + if (ret) { + *_ret = ret; + return 1; + } + + ret = unit_new(m, unit_vtable[t]->object_size); + if (!ret) + return -ENOMEM; + + if (path) { + ret->fragment_path = strdup(path); + if (!ret->fragment_path) { + unit_free(ret); + return -ENOMEM; + } + } + + if ((r = unit_add_name(ret, name)) < 0) { + unit_free(ret); + return r; + } + + unit_add_to_load_queue(ret); + unit_add_to_dbus_queue(ret); + unit_add_to_gc_queue(ret); + + if (_ret) + *_ret = ret; + + return 0; +} + +int manager_load_unit(Manager *m, const char *name, const char *path, DBusError *e, Unit **_ret) { + int r; + + assert(m); + + /* This will load the service information files, but not actually + * start any services or anything. */ + + r = manager_load_unit_prepare(m, name, path, e, _ret); + if (r != 0) + return r; + + manager_dispatch_load_queue(m); + + if (_ret) + *_ret = unit_follow_merge(*_ret); + + return 0; +} + +void manager_dump_jobs(Manager *s, FILE *f, const char *prefix) { + Iterator i; + Job *j; + + assert(s); + assert(f); + + HASHMAP_FOREACH(j, s->jobs, i) + job_dump(j, f, prefix); +} + +void manager_dump_units(Manager *s, FILE *f, const char *prefix) { + Iterator i; + Unit *u; + const char *t; + + assert(s); + assert(f); + + HASHMAP_FOREACH_KEY(u, t, s->units, i) + if (u->id == t) + unit_dump(u, f, prefix); +} + +void manager_clear_jobs(Manager *m) { + Job *j; + + assert(m); + + while ((j = hashmap_first(m->jobs))) + /* No need to recurse. We're cancelling all jobs. */ + job_finish_and_invalidate(j, JOB_CANCELED, false); +} + +unsigned manager_dispatch_run_queue(Manager *m) { + Job *j; + unsigned n = 0; + + if (m->dispatching_run_queue) + return 0; + + m->dispatching_run_queue = true; + + while ((j = m->run_queue)) { + assert(j->installed); + assert(j->in_run_queue); + + job_run_and_invalidate(j); + n++; + } + + m->dispatching_run_queue = false; + return n; +} + +unsigned manager_dispatch_dbus_queue(Manager *m) { + Job *j; + Unit *u; + unsigned n = 0; + + assert(m); + + if (m->dispatching_dbus_queue) + return 0; + + m->dispatching_dbus_queue = true; + + while ((u = m->dbus_unit_queue)) { + assert(u->in_dbus_queue); + + bus_unit_send_change_signal(u); + n++; + } + + while ((j = m->dbus_job_queue)) { + assert(j->in_dbus_queue); + + bus_job_send_change_signal(j); + n++; + } + + m->dispatching_dbus_queue = false; + return n; +} + +static int manager_process_notify_fd(Manager *m) { + ssize_t n; + + assert(m); + + for (;;) { + char buf[4096]; + struct msghdr msghdr; + struct iovec iovec; + struct ucred *ucred; + union { + struct cmsghdr cmsghdr; + uint8_t buf[CMSG_SPACE(sizeof(struct ucred))]; + } control; + Unit *u; + char **tags; + + zero(iovec); + iovec.iov_base = buf; + iovec.iov_len = sizeof(buf)-1; + + zero(control); + zero(msghdr); + msghdr.msg_iov = &iovec; + msghdr.msg_iovlen = 1; + msghdr.msg_control = &control; + msghdr.msg_controllen = sizeof(control); + + n = recvmsg(m->notify_watch.fd, &msghdr, MSG_DONTWAIT); + if (n <= 0) { + if (n >= 0) + return -EIO; + + if (errno == EAGAIN || errno == EINTR) + break; + + return -errno; + } + + if (msghdr.msg_controllen < CMSG_LEN(sizeof(struct ucred)) || + control.cmsghdr.cmsg_level != SOL_SOCKET || + control.cmsghdr.cmsg_type != SCM_CREDENTIALS || + control.cmsghdr.cmsg_len != CMSG_LEN(sizeof(struct ucred))) { + log_warning("Received notify message without credentials. Ignoring."); + continue; + } + + ucred = (struct ucred*) CMSG_DATA(&control.cmsghdr); + + u = hashmap_get(m->watch_pids, LONG_TO_PTR(ucred->pid)); + if (!u) { + u = cgroup_unit_by_pid(m, ucred->pid); + if (!u) { + log_warning("Cannot find unit for notify message of PID %lu.", (unsigned long) ucred->pid); + continue; + } + } + + assert((size_t) n < sizeof(buf)); + buf[n] = 0; + tags = strv_split(buf, "\n\r"); + if (!tags) + return log_oom(); + + log_debug_unit(u->id, "Got notification message for unit %s", u->id); + + if (UNIT_VTABLE(u)->notify_message) + UNIT_VTABLE(u)->notify_message(u, ucred->pid, tags); + + strv_free(tags); + } + + return 0; +} + +static int manager_dispatch_sigchld(Manager *m) { + assert(m); + + for (;;) { + siginfo_t si; + Unit *u; + int r; + + zero(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. */ + if (waitid(P_ALL, 0, &si, WEXITED|WNOHANG|WNOWAIT) < 0) { + + if (errno == ECHILD) + break; + + if (errno == EINTR) + continue; + + return -errno; + } + + if (si.si_pid <= 0) + break; + + if (si.si_code == CLD_EXITED || si.si_code == CLD_KILLED || si.si_code == CLD_DUMPED) { + char _cleanup_free_ *name = NULL; + + get_process_comm(si.si_pid, &name); + log_debug("Got SIGCHLD for process %lu (%s)", (unsigned long) si.si_pid, strna(name)); + } + + /* Let's flush any message the dying child might still + * have queued for us. This ensures that the process + * still exists in /proc so that we can figure out + * which cgroup and hence unit it belongs to. */ + r = manager_process_notify_fd(m); + if (r < 0) + return r; + + /* And now figure out the unit this belongs to */ + u = hashmap_get(m->watch_pids, LONG_TO_PTR(si.si_pid)); + if (!u) + u = cgroup_unit_by_pid(m, si.si_pid); + + /* And now, we actually reap the zombie. */ + if (waitid(P_PID, si.si_pid, &si, WEXITED) < 0) { + if (errno == EINTR) + continue; + + return -errno; + } + + if (si.si_code != CLD_EXITED && si.si_code != CLD_KILLED && si.si_code != CLD_DUMPED) + continue; + + log_debug("Child %lu died (code=%s, status=%i/%s)", + (long unsigned) si.si_pid, + 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))); + + if (!u) + continue; + + log_debug_unit(u->id, + "Child %lu belongs to %s", (long unsigned) si.si_pid, u->id); + + hashmap_remove(m->watch_pids, LONG_TO_PTR(si.si_pid)); + UNIT_VTABLE(u)->sigchld_event(u, si.si_pid, si.si_code, si.si_status); + } + + return 0; +} + +static int manager_start_target(Manager *m, const char *name, JobMode mode) { + int r; + DBusError error; + + dbus_error_init(&error); + + log_debug_unit(name, "Activating special unit %s", name); + + r = manager_add_job_by_name(m, JOB_START, name, mode, true, &error, NULL); + if (r < 0) + log_error_unit(name, + "Failed to enqueue %s job: %s", name, bus_error(&error, r)); + + dbus_error_free(&error); + + return r; +} + +static int manager_process_signal_fd(Manager *m) { + ssize_t n; + struct signalfd_siginfo sfsi; + bool sigchld = false; + + assert(m); + + for (;;) { + n = read(m->signal_watch.fd, &sfsi, sizeof(sfsi)); + if (n != sizeof(sfsi)) { + + if (n >= 0) + return -EIO; + + if (errno == EINTR || errno == EAGAIN) + break; + + return -errno; + } + + if (sfsi.ssi_pid > 0) { + char *p = NULL; + + get_process_comm(sfsi.ssi_pid, &p); + + log_debug("Received SIG%s from PID %lu (%s).", + signal_to_string(sfsi.ssi_signo), + (unsigned long) sfsi.ssi_pid, strna(p)); + free(p); + } else + log_debug("Received SIG%s.", signal_to_string(sfsi.ssi_signo)); + + switch (sfsi.ssi_signo) { + + case SIGCHLD: + sigchld = true; + break; + + case SIGTERM: + if (m->running_as == SYSTEMD_SYSTEM) { + /* This is for compatibility with the + * original sysvinit */ + m->exit_code = MANAGER_REEXECUTE; + break; + } + + /* Fall through */ + + case SIGINT: + if (m->running_as == SYSTEMD_SYSTEM) { + manager_start_target(m, SPECIAL_CTRL_ALT_DEL_TARGET, JOB_REPLACE); + break; + } + + /* Run the exit target if there is one, if not, just exit. */ + if (manager_start_target(m, SPECIAL_EXIT_TARGET, JOB_REPLACE) < 0) { + m->exit_code = MANAGER_EXIT; + return 0; + } + + break; + + case SIGWINCH: + if (m->running_as == SYSTEMD_SYSTEM) + manager_start_target(m, SPECIAL_KBREQUEST_TARGET, JOB_REPLACE); + + /* This is a nop on non-init */ + break; + + case SIGPWR: + if (m->running_as == SYSTEMD_SYSTEM) + manager_start_target(m, SPECIAL_SIGPWR_TARGET, JOB_REPLACE); + + /* This is a nop on non-init */ + break; + + case SIGUSR1: { + Unit *u; + + u = manager_get_unit(m, SPECIAL_DBUS_SERVICE); + + 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: { + FILE *f; + char *dump = NULL; + size_t size; + + if (!(f = open_memstream(&dump, &size))) { + log_warning("Failed to allocate memory stream."); + break; + } + + manager_dump_units(m, f, "\t"); + manager_dump_jobs(m, f, "\t"); + + if (ferror(f)) { + fclose(f); + free(dump); + log_warning("Failed to write status stream"); + break; + } + + fclose(f); + log_dump(LOG_INFO, dump); + free(dump); + + break; + } + + case SIGHUP: + m->exit_code = MANAGER_RELOAD; + break; + + default: { + + /* Starting SIGRTMIN+0 */ + static const char * const target_table[] = { + [0] = SPECIAL_DEFAULT_TARGET, + [1] = SPECIAL_RESCUE_TARGET, + [2] = SPECIAL_EMERGENCY_TARGET, + [3] = SPECIAL_HALT_TARGET, + [4] = SPECIAL_POWEROFF_TARGET, + [5] = SPECIAL_REBOOT_TARGET, + [6] = SPECIAL_KEXEC_TARGET + }; + + /* 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], + (idx == 1 || idx == 2) ? JOB_ISOLATE : JOB_REPLACE); + break; + } + + 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; + } + + switch (sfsi.ssi_signo - SIGRTMIN) { + + case 20: + log_debug("Enabling showing of status."); + manager_set_show_status(m, true); + break; + + case 21: + log_debug("Disabling showing of status."); + manager_set_show_status(m, false); + break; + + case 22: + log_set_max_level(LOG_DEBUG); + log_notice("Setting log level to debug."); + break; + + case 23: + log_set_max_level(LOG_INFO); + log_notice("Setting log level to info."); + break; + + case 24: + if (m->running_as == SYSTEMD_USER) { + m->exit_code = MANAGER_EXIT; + return 0; + } + + /* This is a nop on init */ + break; + + case 26: + 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; + + case 29: + log_set_target(LOG_TARGET_SYSLOG_OR_KMSG); + log_notice("Setting log target to syslog-or-kmsg."); + break; + + default: + log_warning("Got unhandled signal <%s>.", signal_to_string(sfsi.ssi_signo)); + } + } + } + } + + if (sigchld) + return manager_dispatch_sigchld(m); + + return 0; +} + +static int process_event(Manager *m, struct epoll_event *ev) { + int r; + Watch *w; + + assert(m); + assert(ev); + + assert_se(w = ev->data.ptr); + + if (w->type == WATCH_INVALID) + return 0; + + switch (w->type) { + + case WATCH_SIGNAL: + + /* An incoming signal? */ + if (ev->events != EPOLLIN) + return -EINVAL; + + if ((r = manager_process_signal_fd(m)) < 0) + return r; + + break; + + case WATCH_NOTIFY: + + /* An incoming daemon notification event? */ + if (ev->events != EPOLLIN) + return -EINVAL; + + if ((r = manager_process_notify_fd(m)) < 0) + return r; + + break; + + case WATCH_FD: + + /* Some fd event, to be dispatched to the units */ + UNIT_VTABLE(w->data.unit)->fd_event(w->data.unit, w->fd, ev->events, w); + break; + + case WATCH_UNIT_TIMER: + case WATCH_JOB_TIMER: { + uint64_t v; + ssize_t k; + + /* Some timer event, to be dispatched to the units */ + k = read(w->fd, &v, sizeof(v)); + if (k != sizeof(v)) { + + if (k < 0 && (errno == EINTR || errno == EAGAIN)) + break; + + log_error("Failed to read timer event counter: %s", k < 0 ? strerror(-k) : "Short read"); + return k < 0 ? -errno : -EIO; + } + + if (w->type == WATCH_UNIT_TIMER) + UNIT_VTABLE(w->data.unit)->timer_event(w->data.unit, v, w); + else + job_timer_event(w->data.job, v, w); + break; + } + + case WATCH_MOUNT: + /* Some mount table change, intended for the mount subsystem */ + mount_fd_event(m, ev->events); + break; + + case WATCH_SWAP: + /* Some swap table change, intended for the swap subsystem */ + swap_fd_event(m, ev->events); + break; + + case WATCH_UDEV: + /* Some notification from udev, intended for the device subsystem */ + device_fd_event(m, ev->events); + break; + + case WATCH_DBUS_WATCH: + bus_watch_event(m, w, ev->events); + break; + + case WATCH_DBUS_TIMEOUT: + bus_timeout_event(m, w, ev->events); + break; + + case WATCH_TIME_CHANGE: { + Unit *u; + Iterator i; + + log_struct(LOG_INFO, + MESSAGE_ID(SD_MESSAGE_TIME_CHANGE), + "MESSAGE=Time has been changed", + NULL); + + /* Restart the watch */ + close_nointr_nofail(m->time_change_watch.fd); + watch_init(&m->time_change_watch); + manager_setup_time_change(m); + + HASHMAP_FOREACH(u, m->units, i) { + if (UNIT_VTABLE(u)->time_change) + UNIT_VTABLE(u)->time_change(u); + } + + break; + } + + default: + log_error("event type=%i", w->type); + assert_not_reached("Unknown epoll event type."); + } + + return 0; +} + +int manager_loop(Manager *m) { + int r; + + RATELIMIT_DEFINE(rl, 1*USEC_PER_SEC, 50000); + + assert(m); + m->exit_code = MANAGER_RUNNING; + + /* Release the path cache */ + set_free_free(m->unit_path_cache); + m->unit_path_cache = NULL; + + manager_check_finished(m); + + /* There might still be some zombies hanging around from + * before we were exec()'ed. Leat's reap them */ + r = manager_dispatch_sigchld(m); + if (r < 0) + return r; + + while (m->exit_code == MANAGER_RUNNING) { + struct epoll_event event; + int n; + int wait_msec = -1; + + if (m->runtime_watchdog > 0 && m->running_as == SYSTEMD_SYSTEM) + watchdog_ping(); + + if (!ratelimit_test(&rl)) { + /* Yay, something is going seriously wrong, pause a little */ + log_warning("Looping too fast. Throttling execution a little."); + sleep(1); + continue; + } + + if (manager_dispatch_load_queue(m) > 0) + continue; + + if (manager_dispatch_run_queue(m) > 0) + continue; + + if (bus_dispatch(m) > 0) + continue; + + if (manager_dispatch_cleanup_queue(m) > 0) + continue; + + if (manager_dispatch_gc_queue(m) > 0) + continue; + + if (manager_dispatch_dbus_queue(m) > 0) + continue; + + if (swap_dispatch_reload(m) > 0) + continue; + + /* Sleep for half the watchdog time */ + if (m->runtime_watchdog > 0 && m->running_as == SYSTEMD_SYSTEM) { + wait_msec = (int) (m->runtime_watchdog / 2 / USEC_PER_MSEC); + if (wait_msec <= 0) + wait_msec = 1; + } else + wait_msec = -1; + + n = epoll_wait(m->epoll_fd, &event, 1, wait_msec); + if (n < 0) { + + if (errno == EINTR) + continue; + + return -errno; + } else if (n == 0) + continue; + + assert(n == 1); + + r = process_event(m, &event); + if (r < 0) + return r; + } + + return m->exit_code; +} + +int manager_load_unit_from_dbus_path(Manager *m, const char *s, DBusError *e, Unit **_u) { + char *n; + Unit *u; + int r; + + assert(m); + assert(s); + assert(_u); + + if (!startswith(s, "/org/freedesktop/systemd1/unit/")) + return -EINVAL; + + n = bus_path_unescape(s+31); + if (!n) + return -ENOMEM; + + r = manager_load_unit(m, n, NULL, e, &u); + free(n); + + if (r < 0) + return r; + + *_u = u; + + return 0; +} + +int manager_get_job_from_dbus_path(Manager *m, const char *s, Job **_j) { + Job *j; + unsigned id; + int r; + + assert(m); + assert(s); + assert(_j); + + if (!startswith(s, "/org/freedesktop/systemd1/job/")) + return -EINVAL; + + r = safe_atou(s + 30, &id); + if (r < 0) + return r; + + j = manager_get_job(m, id); + if (!j) + return -ENOENT; + + *_j = j; + + return 0; +} + +void manager_send_unit_audit(Manager *m, Unit *u, int type, bool success) { + +#ifdef HAVE_AUDIT + char *p; + int audit_fd; + + audit_fd = get_audit_fd(); + if (audit_fd < 0) + return; + + /* Don't generate audit events if the service was already + * started and we're just deserializing */ + if (m->n_reloading > 0) + return; + + if (m->running_as != SYSTEMD_SYSTEM) + return; + + if (u->type != UNIT_SERVICE) + return; + + p = unit_name_to_prefix_and_instance(u->id); + if (!p) { + log_error_unit(u->id, + "Failed to allocate unit name for audit message: %s", strerror(ENOMEM)); + return; + } + + if (audit_log_user_comm_message(audit_fd, type, "", p, NULL, NULL, NULL, success) < 0) { + if (errno == EPERM) { + /* We aren't allowed to send audit messages? + * Then let's not retry again. */ + close_audit_fd(); + } else + log_warning("Failed to send audit message: %m"); + } + + free(p); +#endif + +} + +void manager_send_unit_plymouth(Manager *m, Unit *u) { + int fd = -1; + union sockaddr_union sa; + int n = 0; + char *message = NULL; + + /* Don't generate plymouth events if the service was already + * started and we're just deserializing */ + if (m->n_reloading > 0) + return; + + if (m->running_as != SYSTEMD_SYSTEM) + return; + + if (u->type != UNIT_SERVICE && + u->type != UNIT_MOUNT && + u->type != UNIT_SWAP) + return; + + /* We set SOCK_NONBLOCK here so that we rather drop the + * message then wait for plymouth */ + if ((fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0)) < 0) { + log_error("socket() failed: %m"); + return; + } + + zero(sa); + sa.sa.sa_family = AF_UNIX; + strncpy(sa.un.sun_path+1, "/org/freedesktop/plymouthd", sizeof(sa.un.sun_path)-1); + if (connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + 1 + strlen(sa.un.sun_path+1)) < 0) { + + if (errno != EPIPE && + errno != EAGAIN && + errno != ENOENT && + errno != ECONNREFUSED && + errno != ECONNRESET && + errno != ECONNABORTED) + log_error("connect() failed: %m"); + + goto finish; + } + + if (asprintf(&message, "U\002%c%s%n", (int) (strlen(u->id) + 1), u->id, &n) < 0) { + log_oom(); + goto finish; + } + + errno = 0; + if (write(fd, message, n + 1) != n + 1) { + + if (errno != EPIPE && + errno != EAGAIN && + errno != ENOENT && + errno != ECONNREFUSED && + errno != ECONNRESET && + errno != ECONNABORTED) + log_error("Failed to write Plymouth message: %m"); + + goto finish; + } + +finish: + if (fd >= 0) + close_nointr_nofail(fd); + + free(message); +} + +void manager_dispatch_bus_name_owner_changed( + Manager *m, + const char *name, + const char* old_owner, + const char *new_owner) { + + Unit *u; + + assert(m); + assert(name); + + if (!(u = hashmap_get(m->watch_bus, name))) + return; + + UNIT_VTABLE(u)->bus_name_owner_change(u, name, old_owner, new_owner); +} + +void manager_dispatch_bus_query_pid_done( + Manager *m, + const char *name, + pid_t pid) { + + Unit *u; + + assert(m); + assert(name); + assert(pid >= 1); + + if (!(u = hashmap_get(m->watch_bus, name))) + return; + + UNIT_VTABLE(u)->bus_query_pid_done(u, name, pid); +} + +int manager_open_serialization(Manager *m, FILE **_f) { + char *path = NULL; + mode_t saved_umask; + int fd; + FILE *f; + + assert(_f); + + if (m->running_as == SYSTEMD_SYSTEM) + asprintf(&path, "/run/systemd/dump-%lu-XXXXXX", (unsigned long) getpid()); + else + asprintf(&path, "/tmp/systemd-dump-%lu-XXXXXX", (unsigned long) getpid()); + + if (!path) + return -ENOMEM; + + saved_umask = umask(0077); + fd = mkostemp(path, O_RDWR|O_CLOEXEC); + umask(saved_umask); + + if (fd < 0) { + free(path); + return -errno; + } + + unlink(path); + + log_debug("Serializing state to %s", path); + free(path); + + f = fdopen(fd, "w+"); + if (!f) + return -errno; + + *_f = f; + + return 0; +} + +int manager_serialize(Manager *m, FILE *f, FDSet *fds, bool serialize_jobs) { + Iterator i; + Unit *u; + const char *t; + int r; + + assert(m); + assert(f); + assert(fds); + + m->n_reloading ++; + + fprintf(f, "current-job-id=%i\n", m->current_job_id); + fprintf(f, "taint-usr=%s\n", yes_no(m->taint_usr)); + fprintf(f, "n-installed-jobs=%u\n", m->n_installed_jobs); + fprintf(f, "n-failed-jobs=%u\n", m->n_failed_jobs); + + dual_timestamp_serialize(f, "firmware-timestamp", &m->firmware_timestamp); + dual_timestamp_serialize(f, "kernel-timestamp", &m->kernel_timestamp); + dual_timestamp_serialize(f, "loader-timestamp", &m->loader_timestamp); + dual_timestamp_serialize(f, "initrd-timestamp", &m->initrd_timestamp); + + if (!in_initrd()) { + dual_timestamp_serialize(f, "userspace-timestamp", &m->userspace_timestamp); + dual_timestamp_serialize(f, "finish-timestamp", &m->finish_timestamp); + } + + fputc('\n', f); + + HASHMAP_FOREACH_KEY(u, t, m->units, i) { + if (u->id != t) + continue; + + if (!unit_can_serialize(u)) + continue; + + /* Start marker */ + fputs(u->id, f); + fputc('\n', f); + + if ((r = unit_serialize(u, f, fds, serialize_jobs)) < 0) { + m->n_reloading --; + return r; + } + } + + assert(m->n_reloading > 0); + m->n_reloading --; + + if (ferror(f)) + return -EIO; + + r = bus_fdset_add_all(m, fds); + if (r < 0) + return r; + + return 0; +} + +int manager_deserialize(Manager *m, FILE *f, FDSet *fds) { + int r = 0; + + assert(m); + assert(f); + + log_debug("Deserializing state..."); + + m->n_reloading ++; + + for (;;) { + char line[LINE_MAX], *l; + + if (!fgets(line, sizeof(line), f)) { + if (feof(f)) + r = 0; + else + r = -errno; + + goto finish; + } + + char_array_0(line); + l = strstrip(line); + + if (l[0] == 0) + break; + + if (startswith(l, "current-job-id=")) { + uint32_t id; + + if (safe_atou32(l+15, &id) < 0) + log_debug("Failed to parse current job id value %s", l+15); + else + m->current_job_id = MAX(m->current_job_id, id); + } else if (startswith(l, "n-installed-jobs=")) { + uint32_t n; + + if (safe_atou32(l+17, &n) < 0) + log_debug("Failed to parse installed jobs counter %s", l+17); + else + m->n_installed_jobs += n; + } else if (startswith(l, "n-failed-jobs=")) { + uint32_t n; + + if (safe_atou32(l+14, &n) < 0) + log_debug("Failed to parse failed jobs counter %s", l+14); + else + m->n_failed_jobs += n; + } else if (startswith(l, "taint-usr=")) { + int b; + + if ((b = parse_boolean(l+10)) < 0) + log_debug("Failed to parse taint /usr flag %s", l+10); + else + m->taint_usr = m->taint_usr || b; + } else if (startswith(l, "firmware-timestamp=")) + dual_timestamp_deserialize(l+19, &m->firmware_timestamp); + else if (startswith(l, "loader-timestamp=")) + dual_timestamp_deserialize(l+17, &m->loader_timestamp); + else if (startswith(l, "kernel-timestamp=")) + dual_timestamp_deserialize(l+17, &m->kernel_timestamp); + else if (startswith(l, "initrd-timestamp=")) + dual_timestamp_deserialize(l+17, &m->initrd_timestamp); + else if (startswith(l, "userspace-timestamp=")) + dual_timestamp_deserialize(l+20, &m->userspace_timestamp); + else if (startswith(l, "finish-timestamp=")) + dual_timestamp_deserialize(l+17, &m->finish_timestamp); + else + log_debug("Unknown serialization item '%s'", l); + } + + for (;;) { + Unit *u; + char name[UNIT_NAME_MAX+2]; + + /* Start marker */ + if (!fgets(name, sizeof(name), f)) { + if (feof(f)) + r = 0; + else + r = -errno; + + goto finish; + } + + char_array_0(name); + + r = manager_load_unit(m, strstrip(name), NULL, NULL, &u); + if (r < 0) + goto finish; + + r = unit_deserialize(u, f, fds); + if (r < 0) + goto finish; + } + +finish: + if (ferror(f)) { + r = -EIO; + goto finish; + } + + assert(m->n_reloading > 0); + m->n_reloading --; + + return r; +} + +int manager_distribute_fds(Manager *m, FDSet *fds) { + Unit *u; + Iterator i; + int r; + + assert(m); + + HASHMAP_FOREACH(u, m->units, i) { + + if (fdset_size(fds) <= 0) + break; + + if (UNIT_VTABLE(u)->distribute_fds) { + r = UNIT_VTABLE(u)->distribute_fds(u, fds); + if (r < 0) + return r; + } + } + + return 0; +} + +int manager_reload(Manager *m) { + int r, q; + FILE *f; + FDSet *fds; + + assert(m); + + r = manager_open_serialization(m, &f); + if (r < 0) + return r; + + m->n_reloading ++; + + fds = fdset_new(); + if (!fds) { + m->n_reloading --; + r = -ENOMEM; + goto finish; + } + + r = manager_serialize(m, f, fds, true); + if (r < 0) { + m->n_reloading --; + goto finish; + } + + if (fseeko(f, 0, SEEK_SET) < 0) { + m->n_reloading --; + r = -errno; + goto finish; + } + + /* From here on there is no way back. */ + manager_clear_jobs_and_units(m); + manager_undo_generators(m); + lookup_paths_free(&m->lookup_paths); + + /* Find new unit paths */ + manager_run_generators(m); + + q = lookup_paths_init( + &m->lookup_paths, m->running_as, true, + m->generator_unit_path, + m->generator_unit_path_early, + m->generator_unit_path_late); + if (q < 0) + r = q; + + manager_build_unit_path_cache(m); + + /* First, enumerate what we can from all config files */ + q = manager_enumerate(m); + if (q < 0) + r = q; + + /* Second, deserialize our stored data */ + q = manager_deserialize(m, f, fds); + if (q < 0) + r = q; + + fclose(f); + f = NULL; + + /* Third, fire things up! */ + q = manager_coldplug(m); + if (q < 0) + r = q; + + assert(m->n_reloading > 0); + m->n_reloading--; + +finish: + if (f) + fclose(f); + + if (fds) + fdset_free(fds); + + return r; +} + +bool manager_is_booting_or_shutting_down(Manager *m) { + Unit *u; + + assert(m); + + /* Is the initial job still around? */ + if (manager_get_job(m, m->default_unit_job_id)) + return true; + + /* Is there a job for the shutdown target? */ + u = manager_get_unit(m, SPECIAL_SHUTDOWN_TARGET); + if (u) + return !!u->job; + + return false; +} + +void manager_reset_failed(Manager *m) { + Unit *u; + Iterator i; + + assert(m); + + HASHMAP_FOREACH(u, m->units, i) + unit_reset_failed(u); +} + +bool manager_unit_pending_inactive(Manager *m, const char *name) { + Unit *u; + + assert(m); + assert(name); + + /* Returns true if the unit is inactive or going down */ + u = manager_get_unit(m, name); + if (!u) + return true; + + return unit_pending_inactive(u); +} + +void manager_check_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; + + assert(m); + + if (hashmap_size(m->jobs) > 0) + return; + + /* Notify Type=idle units that we are done now */ + close_pipe(m->idle_pipe); + + /* Turn off confirm spawn now */ + m->confirm_spawn = false; + + if (dual_timestamp_is_set(&m->finish_timestamp)) + return; + + dual_timestamp_get(&m->finish_timestamp); + + if (m->running_as == SYSTEMD_SYSTEM && detect_container(NULL) <= 0) { + + /* Note that m->kernel_usec.monotonic is always at 0, + * and m->firmware_usec.monotonic and + * m->loader_usec.monotonic should be considered + * negative values. */ + + firmware_usec = m->firmware_timestamp.monotonic - m->loader_timestamp.monotonic; + loader_usec = m->loader_timestamp.monotonic - m->kernel_timestamp.monotonic; + userspace_usec = m->finish_timestamp.monotonic - m->userspace_timestamp.monotonic; + total_usec = m->firmware_timestamp.monotonic + m->finish_timestamp.monotonic; + + if (dual_timestamp_is_set(&m->initrd_timestamp)) { + + kernel_usec = m->initrd_timestamp.monotonic - m->kernel_timestamp.monotonic; + initrd_usec = m->userspace_timestamp.monotonic - m->initrd_timestamp.monotonic; + + if (!log_on_console()) + log_struct(LOG_INFO, + MESSAGE_ID(SD_MESSAGE_STARTUP_FINISHED), + "KERNEL_USEC=%llu", (unsigned long long) kernel_usec, + "INITRD_USEC=%llu", (unsigned long long) initrd_usec, + "USERSPACE_USEC=%llu", (unsigned long long) userspace_usec, + "MESSAGE=Startup finished in %s (kernel) + %s (initrd) + %s (userspace) = %s.", + format_timespan(kernel, sizeof(kernel), kernel_usec), + format_timespan(initrd, sizeof(initrd), initrd_usec), + format_timespan(userspace, sizeof(userspace), userspace_usec), + format_timespan(sum, sizeof(sum), total_usec), + NULL); + } else { + kernel_usec = m->userspace_timestamp.monotonic - m->kernel_timestamp.monotonic; + initrd_usec = 0; + + if (!log_on_console()) + log_struct(LOG_INFO, + MESSAGE_ID(SD_MESSAGE_STARTUP_FINISHED), + "KERNEL_USEC=%llu", (unsigned long long) kernel_usec, + "USERSPACE_USEC=%llu", (unsigned long long) userspace_usec, + "MESSAGE=Startup finished in %s (kernel) + %s (userspace) = %s.", + format_timespan(kernel, sizeof(kernel), kernel_usec), + format_timespan(userspace, sizeof(userspace), userspace_usec), + format_timespan(sum, sizeof(sum), total_usec), + NULL); + } + } else { + firmware_usec = loader_usec = initrd_usec = kernel_usec = 0; + total_usec = userspace_usec = m->finish_timestamp.monotonic - m->userspace_timestamp.monotonic; + + if (!log_on_console()) + log_struct(LOG_INFO, + MESSAGE_ID(SD_MESSAGE_STARTUP_FINISHED), + "USERSPACE_USEC=%llu", (unsigned long long) userspace_usec, + "MESSAGE=Startup finished in %s.", + format_timespan(sum, sizeof(sum), total_usec), + NULL); + } + + bus_broadcast_finished(m, firmware_usec, loader_usec, kernel_usec, initrd_usec, userspace_usec, total_usec); + + sd_notifyf(false, + "READY=1\nSTATUS=Startup finished in %s.", + format_timespan(sum, sizeof(sum), total_usec)); +} + +static int create_generator_dir(Manager *m, char **generator, const char *name) { + char *p; + int r; + + assert(m); + assert(generator); + assert(name); + + if (*generator) + return 0; + + if (m->running_as == SYSTEMD_SYSTEM && getpid() == 1) { + + p = strappend("/run/systemd/", name); + if (!p) + return log_oom(); + + r = mkdir_p_label(p, 0755); + if (r < 0) { + log_error("Failed to create generator directory: %s", strerror(-r)); + free(p); + return r; + } + } else { + p = strjoin("/tmp/systemd-", name, ".XXXXXX", NULL); + if (!p) + return log_oom(); + + if (!mkdtemp(p)) { + free(p); + log_error("Failed to create generator directory: %m"); + return -errno; + } + } + + *generator = p; + return 0; +} + +static void trim_generator_dir(Manager *m, char **generator) { + assert(m); + assert(generator); + + if (!*generator) + return; + + if (rmdir(*generator) >= 0) { + free(*generator); + *generator = NULL; + } + + return; +} + +void manager_run_generators(Manager *m) { + DIR *d = NULL; + const char *generator_path; + const char *argv[5]; + mode_t u; + int r; + + assert(m); + + generator_path = m->running_as == SYSTEMD_SYSTEM ? SYSTEM_GENERATOR_PATH : USER_GENERATOR_PATH; + d = opendir(generator_path); + if (!d) { + if (errno == ENOENT) + return; + + log_error("Failed to enumerate generator directory: %m"); + return; + } + + r = create_generator_dir(m, &m->generator_unit_path, "generator"); + if (r < 0) + goto finish; + + r = create_generator_dir(m, &m->generator_unit_path_early, "generator.early"); + if (r < 0) + goto finish; + + r = create_generator_dir(m, &m->generator_unit_path_late, "generator.late"); + if (r < 0) + goto finish; + + argv[0] = NULL; /* Leave this empty, execute_directory() will fill something in */ + argv[1] = m->generator_unit_path; + argv[2] = m->generator_unit_path_early; + argv[3] = m->generator_unit_path_late; + argv[4] = NULL; + + u = umask(0022); + execute_directory(generator_path, d, (char**) argv); + umask(u); + + trim_generator_dir(m, &m->generator_unit_path); + trim_generator_dir(m, &m->generator_unit_path_early); + trim_generator_dir(m, &m->generator_unit_path_late); + +finish: + if (d) + closedir(d); +} + +static void remove_generator_dir(Manager *m, char **generator) { + assert(m); + assert(generator); + + if (!*generator) + return; + + strv_remove(m->lookup_paths.unit_path, *generator); + rm_rf(*generator, false, true, false); + + free(*generator); + *generator = NULL; +} + +void manager_undo_generators(Manager *m) { + assert(m); + + remove_generator_dir(m, &m->generator_unit_path); + remove_generator_dir(m, &m->generator_unit_path_early); + remove_generator_dir(m, &m->generator_unit_path_late); +} + +int manager_set_default_controllers(Manager *m, char **controllers) { + char **l; + + assert(m); + + l = strv_copy(controllers); + if (!l) + return -ENOMEM; + + strv_free(m->default_controllers); + m->default_controllers = l; + + cg_shorten_controllers(m->default_controllers); + + return 0; +} + +int manager_set_default_rlimits(Manager *m, struct rlimit **default_rlimit) { + int i; + + assert(m); + + for (i = 0; i < RLIMIT_NLIMITS; i++) { + if (!default_rlimit[i]) + continue; + + m->rlimit[i] = newdup(struct rlimit, default_rlimit[i], 1); + if (!m->rlimit[i]) + return -ENOMEM; + } + + return 0; +} + +void manager_recheck_journal(Manager *m) { + Unit *u; + + assert(m); + + if (m->running_as != SYSTEMD_SYSTEM) + return; + + u = manager_get_unit(m, SPECIAL_JOURNALD_SOCKET); + if (u && SOCKET(u)->state != SOCKET_RUNNING) { + log_close_journal(); + return; + } + + u = manager_get_unit(m, SPECIAL_JOURNALD_SERVICE); + if (u && SERVICE(u)->state != SERVICE_RUNNING) { + log_close_journal(); + return; + } + + /* Hmm, OK, so the socket is fully up and the service is up + * too, then let's make use of the thing. */ + log_open(); +} + +void manager_set_show_status(Manager *m, bool b) { + assert(m); + + if (m->running_as != SYSTEMD_SYSTEM) + return; + + m->show_status = b; + + if (b) + touch("/run/systemd/show-status"); + else + unlink("/run/systemd/show-status"); +} + +bool manager_get_show_status(Manager *m) { + assert(m); + + if (m->running_as != SYSTEMD_SYSTEM) + return false; + + if (m->show_status) + return true; + + /* If Plymouth is running make sure we show the status, so + * that there's something nice to see when people press Esc */ + + return plymouth_running(); +} + +void watch_init(Watch *w) { + assert(w); + + w->type = WATCH_INVALID; + w->fd = -1; +} diff --git a/src/core/manager.h b/src/core/manager.h new file mode 100644 index 000000000..cc4edf8f1 --- /dev/null +++ b/src/core/manager.h @@ -0,0 +1,298 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +#include +#include +#include +#include + +#include "fdset.h" + +/* Enforce upper limit how many names we allow */ +#define MANAGER_MAX_NAMES 131072 /* 128K */ + +typedef struct Manager Manager; +typedef enum WatchType WatchType; +typedef struct Watch Watch; + +typedef enum ManagerExitCode { + MANAGER_RUNNING, + MANAGER_EXIT, + MANAGER_RELOAD, + MANAGER_REEXECUTE, + MANAGER_REBOOT, + MANAGER_POWEROFF, + MANAGER_HALT, + MANAGER_KEXEC, + MANAGER_SWITCH_ROOT, + _MANAGER_EXIT_CODE_MAX, + _MANAGER_EXIT_CODE_INVALID = -1 +} ManagerExitCode; + +enum WatchType { + WATCH_INVALID, + WATCH_SIGNAL, + WATCH_NOTIFY, + WATCH_FD, + WATCH_UNIT_TIMER, + WATCH_JOB_TIMER, + WATCH_MOUNT, + WATCH_SWAP, + WATCH_UDEV, + WATCH_DBUS_WATCH, + WATCH_DBUS_TIMEOUT, + WATCH_TIME_CHANGE +}; + +struct Watch { + int fd; + WatchType type; + union { + struct Unit *unit; + struct Job *job; + DBusWatch *bus_watch; + DBusTimeout *bus_timeout; + } data; + bool fd_is_dupped:1; + bool socket_accept:1; +}; + +#include "unit.h" +#include "job.h" +#include "hashmap.h" +#include "list.h" +#include "set.h" +#include "dbus.h" +#include "path-lookup.h" + +struct Manager { + /* Note that the set of units we know of is allowed to be + * inconsistent. However the subset of it that is loaded may + * not, and the list of jobs may neither. */ + + /* Active jobs and units */ + Hashmap *units; /* name string => Unit object n:1 */ + Hashmap *jobs; /* job id => Job object 1:1 */ + + /* To make it easy to iterate through the units of a specific + * type we maintain a per type linked list */ + LIST_HEAD(Unit, units_by_type[_UNIT_TYPE_MAX]); + + /* To optimize iteration of units that have requires_mounts_for set */ + LIST_HEAD(Unit, has_requires_mounts_for); + + /* Units that need to be loaded */ + LIST_HEAD(Unit, load_queue); /* this is actually more a stack than a queue, but uh. */ + + /* Jobs that need to be run */ + LIST_HEAD(Job, run_queue); /* more a stack than a queue, too */ + + /* Units and jobs that have not yet been announced via + * D-Bus. When something about a job changes it is added here + * if it is not in there yet. This allows easy coalescing of + * D-Bus change signals. */ + LIST_HEAD(Unit, dbus_unit_queue); + LIST_HEAD(Job, dbus_job_queue); + + /* Units to remove */ + LIST_HEAD(Unit, cleanup_queue); + + /* Units to check when doing GC */ + LIST_HEAD(Unit, gc_queue); + + Hashmap *watch_pids; /* pid => Unit object n:1 */ + + char *notify_socket; + + Watch notify_watch; + Watch signal_watch; + Watch time_change_watch; + + int epoll_fd; + + unsigned n_snapshots; + + LookupPaths lookup_paths; + Set *unit_path_cache; + + char **environment; + char **default_controllers; + + usec_t runtime_watchdog; + usec_t shutdown_watchdog; + + dual_timestamp firmware_timestamp; + dual_timestamp loader_timestamp; + dual_timestamp kernel_timestamp; + dual_timestamp initrd_timestamp; + dual_timestamp userspace_timestamp; + dual_timestamp finish_timestamp; + + char *generator_unit_path; + char *generator_unit_path_early; + char *generator_unit_path_late; + + /* Data specific to the device subsystem */ + struct udev* udev; + struct udev_monitor* udev_monitor; + Watch udev_watch; + Hashmap *devices_by_sysfs; + + /* Data specific to the mount subsystem */ + FILE *proc_self_mountinfo; + Watch mount_watch; + + /* Data specific to the swap filesystem */ + FILE *proc_swaps; + Hashmap *swaps_by_proc_swaps; + bool request_reload; + Watch swap_watch; + + /* Data specific to the D-Bus subsystem */ + DBusConnection *api_bus, *system_bus; + DBusServer *private_bus; + Set *bus_connections, *bus_connections_for_dispatch; + + DBusMessage *queued_message; /* This is used during reloading: + * before the reload we queue the + * reply message here, and + * afterwards we send it */ + DBusConnection *queued_message_connection; /* The connection to send the queued message on */ + + Hashmap *watch_bus; /* D-Bus names => Unit object n:1 */ + int32_t name_data_slot; + int32_t conn_data_slot; + int32_t subscribed_data_slot; + + uint32_t current_job_id; + uint32_t default_unit_job_id; + + /* Data specific to the Automount subsystem */ + int dev_autofs_fd; + + /* Data specific to the cgroup subsystem */ + Hashmap *cgroup_bondings; /* path string => CGroupBonding object 1:n */ + char *cgroup_hierarchy; + + usec_t gc_queue_timestamp; + int gc_marker; + unsigned n_in_gc_queue; + + /* Make sure the user cannot accidentally unmount our cgroup + * file system */ + int pin_cgroupfs_fd; + + /* Flags */ + SystemdRunningAs running_as; + ManagerExitCode exit_code:5; + + bool dispatching_load_queue:1; + bool dispatching_run_queue:1; + bool dispatching_dbus_queue:1; + + bool taint_usr:1; + + bool show_status; + bool confirm_spawn; + + ExecOutput default_std_output, default_std_error; + + struct rlimit *rlimit[RLIMIT_NLIMITS]; + + /* non-zero if we are reloading or reexecuting, */ + int n_reloading; + + unsigned n_installed_jobs; + unsigned n_failed_jobs; + + /* Type=idle pipes */ + int idle_pipe[2]; + + char *switch_root; + char *switch_root_init; +}; + +int manager_new(SystemdRunningAs running_as, Manager **m); +void manager_free(Manager *m); + +int manager_enumerate(Manager *m); +int manager_coldplug(Manager *m); +int manager_startup(Manager *m, FILE *serialization, FDSet *fds); + +Job *manager_get_job(Manager *m, uint32_t id); +Unit *manager_get_unit(Manager *m, const char *name); + +int manager_get_job_from_dbus_path(Manager *m, const char *s, Job **_j); + +int manager_load_unit_prepare(Manager *m, const char *name, const char *path, DBusError *e, Unit **_ret); +int manager_load_unit(Manager *m, const char *name, const char *path, DBusError *e, Unit **_ret); +int manager_load_unit_from_dbus_path(Manager *m, const char *s, DBusError *e, Unit **_u); + +int manager_add_job(Manager *m, JobType type, Unit *unit, JobMode mode, bool force, DBusError *e, Job **_ret); +int manager_add_job_by_name(Manager *m, JobType type, const char *name, JobMode mode, bool force, DBusError *e, Job **_ret); + +void manager_dump_units(Manager *s, FILE *f, const char *prefix); +void manager_dump_jobs(Manager *s, FILE *f, const char *prefix); + +void manager_clear_jobs(Manager *m); + +unsigned manager_dispatch_load_queue(Manager *m); +unsigned manager_dispatch_run_queue(Manager *m); +unsigned manager_dispatch_dbus_queue(Manager *m); + +int manager_set_default_controllers(Manager *m, char **controllers); +int manager_set_default_rlimits(Manager *m, struct rlimit **default_rlimit); + +int manager_loop(Manager *m); + +void manager_dispatch_bus_name_owner_changed(Manager *m, const char *name, const char* old_owner, const char *new_owner); +void manager_dispatch_bus_query_pid_done(Manager *m, const char *name, pid_t pid); + +int manager_open_serialization(Manager *m, FILE **_f); + +int manager_serialize(Manager *m, FILE *f, FDSet *fds, bool serialize_jobs); +int manager_deserialize(Manager *m, FILE *f, FDSet *fds); +int manager_distribute_fds(Manager *m, FDSet *fds); + +int manager_reload(Manager *m); + +bool manager_is_booting_or_shutting_down(Manager *m); + +void manager_reset_failed(Manager *m); + +void manager_send_unit_audit(Manager *m, Unit *u, int type, bool success); +void manager_send_unit_plymouth(Manager *m, Unit *u); + +bool manager_unit_pending_inactive(Manager *m, const char *name); + +void manager_check_finished(Manager *m); + +void manager_run_generators(Manager *m); +void manager_undo_generators(Manager *m); + +void manager_recheck_journal(Manager *m); + +void manager_set_show_status(Manager *m, bool b); +bool manager_get_show_status(Manager *m); + +void watch_init(Watch *w); diff --git a/src/core/mount-setup.c b/src/core/mount-setup.c new file mode 100644 index 000000000..98614d0c3 --- /dev/null +++ b/src/core/mount-setup.c @@ -0,0 +1,441 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mount-setup.h" +#include "dev-setup.h" +#include "log.h" +#include "macro.h" +#include "util.h" +#include "label.h" +#include "set.h" +#include "strv.h" +#include "mkdir.h" +#include "path-util.h" +#include "missing.h" +#include "virt.h" + +#ifndef TTY_GID +#define TTY_GID 5 +#endif + +typedef enum MountMode { + MNT_NONE = 0, + MNT_FATAL = 1 << 0, + MNT_IN_CONTAINER = 1 << 1, +} MountMode; + +typedef struct MountPoint { + const char *what; + const char *where; + const char *type; + const char *options; + unsigned long flags; + bool (*condition_fn)(void); + MountMode mode; +} MountPoint; + +/* The first three entries we might need before SELinux is up. The + * fourth (securityfs) is needed by IMA to load a custom policy. The + * other ones we can delay until SELinux and IMA are loaded. */ +#define N_EARLY_MOUNT 4 + +static const MountPoint mount_table[] = { + { "proc", "/proc", "proc", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV, + NULL, MNT_FATAL|MNT_IN_CONTAINER }, + { "sysfs", "/sys", "sysfs", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV, + NULL, MNT_FATAL|MNT_IN_CONTAINER }, + { "devtmpfs", "/dev", "devtmpfs", "mode=755", MS_NOSUID|MS_STRICTATIME, + NULL, MNT_FATAL|MNT_IN_CONTAINER }, + { "securityfs", "/sys/kernel/security", "securityfs", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV, + NULL, MNT_NONE }, + { "efivarfs", "/sys/firmware/efi/efivars", "efivarfs", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV, + is_efiboot, MNT_NONE }, + { "tmpfs", "/dev/shm", "tmpfs", "mode=1777", MS_NOSUID|MS_NODEV|MS_STRICTATIME, + NULL, MNT_FATAL|MNT_IN_CONTAINER }, + { "devpts", "/dev/pts", "devpts", "mode=620,gid=" STRINGIFY(TTY_GID), MS_NOSUID|MS_NOEXEC, + NULL, MNT_IN_CONTAINER }, + { "tmpfs", "/run", "tmpfs", "mode=755", MS_NOSUID|MS_NODEV|MS_STRICTATIME, + NULL, MNT_FATAL|MNT_IN_CONTAINER }, + { "tmpfs", "/sys/fs/cgroup", "tmpfs", "mode=755", MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_STRICTATIME, + NULL, MNT_IN_CONTAINER }, + { "cgroup", "/sys/fs/cgroup/systemd", "cgroup", "none,name=systemd", MS_NOSUID|MS_NOEXEC|MS_NODEV, + NULL, MNT_IN_CONTAINER }, +}; + +/* These are API file systems that might be mounted by other software, + * we just list them here so that we know that we should ignore them */ + +static const char ignore_paths[] = + /* SELinux file systems */ + "/sys/fs/selinux\0" + "/selinux\0" + /* Legacy cgroup mount points */ + "/dev/cgroup\0" + "/cgroup\0" + /* Legacy kernel file system */ + "/proc/bus/usb\0" + /* Container bind mounts */ + "/proc/sys\0" + "/dev/console\0" + "/proc/kmsg\0"; + +bool mount_point_is_api(const char *path) { + unsigned i; + + /* Checks if this mount point is considered "API", and hence + * should be ignored */ + + for (i = 0; i < ELEMENTSOF(mount_table); i ++) + if (path_equal(path, mount_table[i].where)) + return true; + + return path_startswith(path, "/sys/fs/cgroup/"); +} + +bool mount_point_ignore(const char *path) { + const char *i; + + NULSTR_FOREACH(i, ignore_paths) + if (path_equal(path, i)) + return true; + + return false; +} + +static int mount_one(const MountPoint *p, bool relabel) { + int r; + + assert(p); + + if (p->condition_fn && !p->condition_fn()) + return 0; + + /* Relabel first, just in case */ + if (relabel) + label_fix(p->where, true, true); + + r = path_is_mount_point(p->where, true); + if (r < 0) + return r; + + if (r > 0) + return 0; + + /* Skip securityfs in a container */ + if (!(p->mode & MNT_IN_CONTAINER) && detect_container(NULL) > 0) + return 0; + + /* The access mode here doesn't really matter too much, since + * the mounted file system will take precedence anyway. */ + mkdir_p_label(p->where, 0755); + + log_debug("Mounting %s to %s of type %s with options %s.", + p->what, + p->where, + p->type, + strna(p->options)); + + if (mount(p->what, + p->where, + p->type, + p->flags, + p->options) < 0) { + log_full((p->mode & MNT_FATAL) ? LOG_ERR : LOG_DEBUG, "Failed to mount %s: %s", p->where, strerror(errno)); + return (p->mode & MNT_FATAL) ? -errno : 0; + } + + /* Relabel again, since we now mounted something fresh here */ + if (relabel) + label_fix(p->where, false, false); + + return 1; +} + +int mount_setup_early(void) { + unsigned i; + int r = 0; + + assert_cc(N_EARLY_MOUNT <= ELEMENTSOF(mount_table)); + + /* Do a minimal mount of /proc and friends to enable the most + * basic stuff, such as SELinux */ + for (i = 0; i < N_EARLY_MOUNT; i ++) { + int j; + + j = mount_one(mount_table + i, false); + if (r == 0) + r = j; + } + + return r; +} + +int mount_cgroup_controllers(char ***join_controllers) { + int r; + FILE *f; + char buf[LINE_MAX]; + Set *controllers; + + /* Mount all available cgroup controllers that are built into the kernel. */ + + f = fopen("/proc/cgroups", "re"); + if (!f) { + log_error("Failed to enumerate cgroup controllers: %m"); + return 0; + } + + controllers = set_new(string_hash_func, string_compare_func); + if (!controllers) { + r = log_oom(); + goto finish; + } + + /* Ignore the header line */ + (void) fgets(buf, sizeof(buf), f); + + for (;;) { + char *controller; + int enabled = 0; + + if (fscanf(f, "%ms %*i %*i %i", &controller, &enabled) != 2) { + + if (feof(f)) + break; + + log_error("Failed to parse /proc/cgroups."); + r = -EIO; + goto finish; + } + + if (!enabled) { + free(controller); + continue; + } + + r = set_put(controllers, controller); + if (r < 0) { + log_error("Failed to add controller to set."); + free(controller); + goto finish; + } + } + + for (;;) { + MountPoint p; + char *controller, *where, *options; + char ***k = NULL; + + controller = set_steal_first(controllers); + if (!controller) + break; + + if (join_controllers) + for (k = join_controllers; *k; k++) + if (strv_find(*k, controller)) + break; + + if (k && *k) { + char **i, **j; + + for (i = *k, j = *k; *i; i++) { + + if (!streq(*i, controller)) { + char *t; + + t = set_remove(controllers, *i); + if (!t) { + free(*i); + continue; + } + free(t); + } + + *(j++) = *i; + } + + *j = NULL; + + options = strv_join(*k, ","); + if (!options) { + free(controller); + r = log_oom(); + goto finish; + } + + } else { + options = controller; + controller = NULL; + } + + where = strappend("/sys/fs/cgroup/", options); + if (!where) { + free(options); + r = log_oom(); + goto finish; + } + + zero(p); + p.what = "cgroup"; + p.where = where; + p.type = "cgroup"; + p.options = options; + p.flags = MS_NOSUID|MS_NOEXEC|MS_NODEV; + + r = mount_one(&p, true); + free(controller); + free(where); + + if (r < 0) { + free(options); + goto finish; + } + + if (r > 0 && k && *k) { + char **i; + + for (i = *k; *i; i++) { + char *t; + + t = strappend("/sys/fs/cgroup/", *i); + if (!t) { + r = log_oom(); + free(options); + goto finish; + } + + r = symlink(options, t); + free(t); + + if (r < 0 && errno != EEXIST) { + log_error("Failed to create symlink: %m"); + r = -errno; + free(options); + goto finish; + } + } + } + + free(options); + } + + r = 0; + +finish: + set_free_free(controllers); + + fclose(f); + + return r; +} + +static int nftw_cb( + const char *fpath, + const struct stat *sb, + int tflag, + struct FTW *ftwbuf) { + + /* No need to label /dev twice in a row... */ + if (_unlikely_(ftwbuf->level == 0)) + return FTW_CONTINUE; + + label_fix(fpath, false, false); + + /* /run/initramfs is static data and big, no need to + * dynamically relabel its contents at boot... */ + if (_unlikely_(ftwbuf->level == 1 && + tflag == FTW_D && + streq(fpath, "/run/initramfs"))) + return FTW_SKIP_SUBTREE; + + return FTW_CONTINUE; +}; + +int mount_setup(bool loaded_policy) { + + static const char relabel[] = + "/run/initramfs/root-fsck\0" + "/run/initramfs/shutdown\0"; + + int r; + unsigned i; + const char *j; + + for (i = 0; i < ELEMENTSOF(mount_table); i ++) { + r = mount_one(mount_table + i, true); + + if (r < 0) + return r; + } + + /* Nodes in devtmpfs and /run need to be manually updated for + * the appropriate labels, after mounting. The other virtual + * API file systems like /sys and /proc do not need that, they + * use the same label for all their files. */ + if (loaded_policy) { + usec_t before_relabel, after_relabel; + char timespan[FORMAT_TIMESPAN_MAX]; + + before_relabel = now(CLOCK_MONOTONIC); + + nftw("/dev", nftw_cb, 64, FTW_MOUNT|FTW_PHYS|FTW_ACTIONRETVAL); + nftw("/run", nftw_cb, 64, FTW_MOUNT|FTW_PHYS|FTW_ACTIONRETVAL); + + /* Explicitly relabel these */ + NULSTR_FOREACH(j, relabel) + label_fix(j, true, false); + + after_relabel = now(CLOCK_MONOTONIC); + + log_info("Relabelled /dev and /run in %s.", + format_timespan(timespan, sizeof(timespan), after_relabel - before_relabel)); + } + + /* Create a few default symlinks, which are normally created + * by udevd, but some scripts might need them before we start + * udevd. */ + dev_setup(NULL); + + /* Mark the root directory as shared in regards to mount + * propagation. The kernel defaults to "private", but we think + * it makes more sense to have a default of "shared" so that + * nspawn and the container tools work out of the box. If + * specific setups need other settings they can reset the + * propagation mode to private if needed. */ + if (detect_container(NULL) <= 0) + if (mount(NULL, "/", NULL, MS_REC|MS_SHARED, NULL) < 0) + log_warning("Failed to set up the root directory for shared mount propagation: %m"); + + /* Create a few directories we always want around */ + mkdir_label("/run/systemd", 0755); + mkdir_label("/run/systemd/system", 0755); + + return 0; +} diff --git a/src/core/mount-setup.h b/src/core/mount-setup.h new file mode 100644 index 000000000..4b521ad0e --- /dev/null +++ b/src/core/mount-setup.h @@ -0,0 +1,33 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +#include + +int mount_setup_early(void); + +int mount_setup(bool loaded_policy); + +int mount_cgroup_controllers(char ***join_controllers); + +bool mount_point_is_api(const char *path); +bool mount_point_ignore(const char *path); diff --git a/src/core/mount.c b/src/core/mount.c new file mode 100644 index 000000000..5d2b01001 --- /dev/null +++ b/src/core/mount.c @@ -0,0 +1,1952 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include +#include + +#include "unit.h" +#include "mount.h" +#include "load-fragment.h" +#include "load-dropin.h" +#include "log.h" +#include "sd-messages.h" +#include "strv.h" +#include "mkdir.h" +#include "path-util.h" +#include "mount-setup.h" +#include "unit-name.h" +#include "dbus-mount.h" +#include "special.h" +#include "bus-errors.h" +#include "exit-status.h" +#include "def.h" + +static const UnitActiveState state_translation_table[_MOUNT_STATE_MAX] = { + [MOUNT_DEAD] = UNIT_INACTIVE, + [MOUNT_MOUNTING] = UNIT_ACTIVATING, + [MOUNT_MOUNTING_DONE] = UNIT_ACTIVE, + [MOUNT_MOUNTED] = UNIT_ACTIVE, + [MOUNT_REMOUNTING] = UNIT_RELOADING, + [MOUNT_UNMOUNTING] = UNIT_DEACTIVATING, + [MOUNT_MOUNTING_SIGTERM] = UNIT_DEACTIVATING, + [MOUNT_MOUNTING_SIGKILL] = UNIT_DEACTIVATING, + [MOUNT_REMOUNTING_SIGTERM] = UNIT_RELOADING, + [MOUNT_REMOUNTING_SIGKILL] = UNIT_RELOADING, + [MOUNT_UNMOUNTING_SIGTERM] = UNIT_DEACTIVATING, + [MOUNT_UNMOUNTING_SIGKILL] = UNIT_DEACTIVATING, + [MOUNT_FAILED] = UNIT_FAILED +}; + +static void mount_init(Unit *u) { + Mount *m = MOUNT(u); + + assert(u); + assert(u->load_state == UNIT_STUB); + + m->timeout_usec = DEFAULT_TIMEOUT_USEC; + m->directory_mode = 0755; + + exec_context_init(&m->exec_context); + + if (unit_has_name(u, "-.mount")) { + /* Don't allow start/stop for root directory */ + UNIT(m)->refuse_manual_start = true; + UNIT(m)->refuse_manual_stop = true; + } else { + /* The stdio/kmsg bridge socket is on /, in order to avoid a + * dep loop, don't use kmsg logging for -.mount */ + m->exec_context.std_output = u->manager->default_std_output; + m->exec_context.std_error = u->manager->default_std_error; + } + + kill_context_init(&m->kill_context); + + /* We need to make sure that /bin/mount is always called in + * the same process group as us, so that the autofs kernel + * side doesn't send us another mount request while we are + * already trying to comply its last one. */ + m->exec_context.same_pgrp = true; + + m->timer_watch.type = WATCH_INVALID; + + m->control_command_id = _MOUNT_EXEC_COMMAND_INVALID; + + UNIT(m)->ignore_on_isolate = true; +} + +static void mount_unwatch_control_pid(Mount *m) { + assert(m); + + if (m->control_pid <= 0) + return; + + unit_unwatch_pid(UNIT(m), m->control_pid); + m->control_pid = 0; +} + +static void mount_parameters_done(MountParameters *p) { + assert(p); + + free(p->what); + free(p->options); + free(p->fstype); + + p->what = p->options = p->fstype = NULL; +} + +static void mount_done(Unit *u) { + Mount *m = MOUNT(u); + + assert(m); + + free(m->where); + m->where = NULL; + + mount_parameters_done(&m->parameters_proc_self_mountinfo); + mount_parameters_done(&m->parameters_fragment); + + exec_context_done(&m->exec_context); + exec_command_done_array(m->exec_command, _MOUNT_EXEC_COMMAND_MAX); + m->control_command = NULL; + + mount_unwatch_control_pid(m); + + unit_unwatch_timer(u, &m->timer_watch); +} + +static MountParameters* get_mount_parameters_fragment(Mount *m) { + assert(m); + + if (m->from_fragment) + return &m->parameters_fragment; + + return NULL; +} + +static MountParameters* get_mount_parameters(Mount *m) { + assert(m); + + if (m->from_proc_self_mountinfo) + return &m->parameters_proc_self_mountinfo; + + return get_mount_parameters_fragment(m); +} + +static int mount_add_mount_links(Mount *m) { + Unit *other; + int r; + MountParameters *pm; + + assert(m); + + pm = get_mount_parameters_fragment(m); + + /* Adds in links to other mount points that might lie below or + * above us in the hierarchy */ + + LIST_FOREACH(units_by_type, other, UNIT(m)->manager->units_by_type[UNIT_MOUNT]) { + Mount *n = MOUNT(other); + MountParameters *pn; + + if (n == m) + continue; + + if (UNIT(n)->load_state != UNIT_LOADED) + continue; + + pn = get_mount_parameters_fragment(n); + + if (path_startswith(m->where, n->where)) { + + if ((r = unit_add_dependency(UNIT(m), UNIT_AFTER, UNIT(n), true)) < 0) + return r; + + if (pn) + if ((r = unit_add_dependency(UNIT(m), UNIT_REQUIRES, UNIT(n), true)) < 0) + return r; + + } else if (path_startswith(n->where, m->where)) { + + if ((r = unit_add_dependency(UNIT(n), UNIT_AFTER, UNIT(m), true)) < 0) + return r; + + if (pm) + if ((r = unit_add_dependency(UNIT(n), UNIT_REQUIRES, UNIT(m), true)) < 0) + return r; + + } else if (pm && pm->what && path_startswith(pm->what, n->where)) { + + if ((r = unit_add_dependency(UNIT(m), UNIT_AFTER, UNIT(n), true)) < 0) + return r; + + if ((r = unit_add_dependency(UNIT(m), UNIT_REQUIRES, UNIT(n), true)) < 0) + return r; + + } else if (pn && pn->what && path_startswith(pn->what, m->where)) { + + if ((r = unit_add_dependency(UNIT(n), UNIT_AFTER, UNIT(m), true)) < 0) + return r; + + if ((r = unit_add_dependency(UNIT(n), UNIT_REQUIRES, UNIT(m), true)) < 0) + return r; + } + } + + return 0; +} + +static int mount_add_swap_links(Mount *m) { + Unit *other; + int r; + + assert(m); + + LIST_FOREACH(units_by_type, other, UNIT(m)->manager->units_by_type[UNIT_SWAP]) { + r = swap_add_one_mount_link(SWAP(other), m); + if (r < 0) + return r; + } + + return 0; +} + +static int mount_add_path_links(Mount *m) { + Unit *other; + int r; + + assert(m); + + LIST_FOREACH(units_by_type, other, UNIT(m)->manager->units_by_type[UNIT_PATH]) { + r = path_add_one_mount_link(PATH(other), m); + if (r < 0) + return r; + } + + return 0; +} + +static int mount_add_automount_links(Mount *m) { + Unit *other; + int r; + + assert(m); + + LIST_FOREACH(units_by_type, other, UNIT(m)->manager->units_by_type[UNIT_AUTOMOUNT]) { + r = automount_add_one_mount_link(AUTOMOUNT(other), m); + if (r < 0) + return r; + } + + return 0; +} + +static int mount_add_socket_links(Mount *m) { + Unit *other; + int r; + + assert(m); + + LIST_FOREACH(units_by_type, other, UNIT(m)->manager->units_by_type[UNIT_SOCKET]) { + r = socket_add_one_mount_link(SOCKET(other), m); + if (r < 0) + return r; + } + + return 0; +} + +static int mount_add_requires_mounts_links(Mount *m) { + Unit *other; + int r; + + assert(m); + + LIST_FOREACH(has_requires_mounts_for, other, UNIT(m)->manager->has_requires_mounts_for) { + r = unit_add_one_mount_link(other, m); + if (r < 0) + return r; + } + + return 0; +} + +static char* mount_test_option(const char *haystack, const char *needle) { + struct mntent me; + + assert(needle); + + /* Like glibc's hasmntopt(), but works on a string, not a + * struct mntent */ + + if (!haystack) + return NULL; + + zero(me); + me.mnt_opts = (char*) haystack; + + return hasmntopt(&me, needle); +} + +static bool mount_is_network(MountParameters *p) { + assert(p); + + if (mount_test_option(p->options, "_netdev")) + return true; + + if (p->fstype && fstype_is_network(p->fstype)) + return true; + + return false; +} + +static bool mount_is_bind(MountParameters *p) { + assert(p); + + if (mount_test_option(p->options, "bind")) + return true; + + if (p->fstype && streq(p->fstype, "bind")) + return true; + + return false; +} + +static bool needs_quota(MountParameters *p) { + assert(p); + + if (mount_is_network(p)) + return false; + + if (mount_is_bind(p)) + return false; + + return mount_test_option(p->options, "usrquota") || + mount_test_option(p->options, "grpquota") || + mount_test_option(p->options, "quota") || + mount_test_option(p->options, "usrjquota") || + mount_test_option(p->options, "grpjquota"); +} + +static int mount_add_device_links(Mount *m) { + MountParameters *p; + int r; + + assert(m); + + p = get_mount_parameters_fragment(m); + if (!p) + return 0; + + if (!p->what) + return 0; + + if (mount_is_bind(p)) + return 0; + + if (!is_device_path(p->what)) + return 0; + + if (path_equal(m->where, "/")) + return 0; + + r = unit_add_node_link(UNIT(m), p->what, false); + if (r < 0) + return r; + + if (p->passno > 0 && + UNIT(m)->manager->running_as == SYSTEMD_SYSTEM) { + char *name; + Unit *fsck; + /* Let's add in the fsck service */ + + /* aka SPECIAL_FSCK_SERVICE */ + name = unit_name_from_path_instance("systemd-fsck", p->what, ".service"); + if (!name) + return -ENOMEM; + + r = manager_load_unit_prepare(UNIT(m)->manager, name, NULL, NULL, &fsck); + if (r < 0) { + log_warning_unit(name, + "Failed to prepare unit %s: %s", name, strerror(-r)); + free(name); + return r; + } + free(name); + + SERVICE(fsck)->fsck_passno = p->passno; + + r = unit_add_two_dependencies(UNIT(m), UNIT_AFTER, UNIT_REQUIRES, fsck, true); + if (r < 0) + return r; + } + + return 0; +} + +static int mount_add_quota_links(Mount *m) { + int r; + MountParameters *p; + + assert(m); + + if (UNIT(m)->manager->running_as != SYSTEMD_SYSTEM) + return 0; + + p = get_mount_parameters_fragment(m); + if (!p) + return 0; + + if (!needs_quota(p)) + return 0; + + r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_WANTS, SPECIAL_QUOTACHECK_SERVICE, NULL, true); + if (r < 0) + return r; + + r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_WANTS, SPECIAL_QUOTAON_SERVICE, NULL, true); + if (r < 0) + return r; + + return 0; +} + +static int mount_add_default_dependencies(Mount *m) { + int r; + MountParameters *p; + const char *after; + + assert(m); + + if (UNIT(m)->manager->running_as != SYSTEMD_SYSTEM) + return 0; + + p = get_mount_parameters_fragment(m); + if (!p) + return 0; + + if (path_equal(m->where, "/")) + return 0; + + if (mount_is_network(p)) + after = SPECIAL_REMOTE_FS_PRE_TARGET; + else + after = SPECIAL_LOCAL_FS_PRE_TARGET; + + r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_WANTS, UNIT_AFTER, after, NULL, true); + if (r < 0) + return r; + + r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true); + if (r < 0) + return r; + + return 0; +} + +static int mount_fix_timeouts(Mount *m) { + MountParameters *p; + const char *timeout = NULL; + Unit *other; + Iterator i; + usec_t u; + char *t; + int r; + + assert(m); + + p = get_mount_parameters_fragment(m); + if (!p) + return 0; + + /* Allow configuration how long we wait for a device that + * backs a mount point to show up. This is useful to support + * endless device timeouts for devices that show up only after + * user input, like crypto devices. */ + + if ((timeout = mount_test_option(p->options, "comment=systemd.device-timeout"))) + timeout += 31; + else if ((timeout = mount_test_option(p->options, "x-systemd.device-timeout"))) + timeout += 25; + else + return 0; + + t = strndup(timeout, strcspn(timeout, ",;" WHITESPACE)); + if (!t) + return -ENOMEM; + + r = parse_usec(t, &u); + free(t); + + if (r < 0) { + log_warning_unit(UNIT(m)->id, + "Failed to parse timeout for %s, ignoring: %s", + m->where, timeout); + return r; + } + + SET_FOREACH(other, UNIT(m)->dependencies[UNIT_AFTER], i) { + if (other->type != UNIT_DEVICE) + continue; + + other->job_timeout = u; + } + + return 0; +} + +static int mount_verify(Mount *m) { + bool b; + char *e; + assert(m); + + if (UNIT(m)->load_state != UNIT_LOADED) + return 0; + + if (!m->from_fragment && !m->from_proc_self_mountinfo) + return -ENOENT; + + if (!(e = unit_name_from_path(m->where, ".mount"))) + return -ENOMEM; + + b = unit_has_name(UNIT(m), e); + free(e); + + if (!b) { + log_error_unit(UNIT(m)->id, + "%s's Where setting doesn't match unit name. Refusing.", + UNIT(m)->id); + return -EINVAL; + } + + if (mount_point_is_api(m->where) || mount_point_ignore(m->where)) { + log_error_unit(UNIT(m)->id, + "Cannot create mount unit for API file system %s. Refusing.", + m->where); + return -EINVAL; + } + + if (UNIT(m)->fragment_path && !m->parameters_fragment.what) { + log_error_unit(UNIT(m)->id, + "%s's What setting is missing. Refusing.", UNIT(m)->id); + return -EBADMSG; + } + + if (m->exec_context.pam_name && m->kill_context.kill_mode != KILL_CONTROL_GROUP) { + log_error_unit(UNIT(m)->id, + "%s has PAM enabled. Kill mode must be set to control-group'. Refusing.", + UNIT(m)->id); + return -EINVAL; + } + + return 0; +} + +static int mount_add_extras(Mount *m) { + Unit *u = UNIT(m); + int r; + + if (UNIT(m)->fragment_path) + m->from_fragment = true; + + if (!m->where) { + m->where = unit_name_to_path(u->id); + if (!m->where) + return -ENOMEM; + } + + path_kill_slashes(m->where); + + r = unit_add_exec_dependencies(u, &m->exec_context); + if (r < 0) + return r; + + if (!UNIT(m)->description) { + r = unit_set_description(u, m->where); + if (r < 0) + return r; + } + + r = mount_add_device_links(m); + if (r < 0) + return r; + + r = mount_add_mount_links(m); + if (r < 0) + return r; + + r = mount_add_socket_links(m); + if (r < 0) + return r; + + r = mount_add_swap_links(m); + if (r < 0) + return r; + + r = mount_add_path_links(m); + if (r < 0) + return r; + + r = mount_add_requires_mounts_links(m); + if (r < 0) + return r; + + r = mount_add_automount_links(m); + if (r < 0) + return r; + + r = mount_add_quota_links(m); + if (r < 0) + return r; + + if (UNIT(m)->default_dependencies) { + r = mount_add_default_dependencies(m); + if (r < 0) + return r; + } + + r = unit_add_default_cgroups(u); + if (r < 0) + return r; + + r = mount_fix_timeouts(m); + if (r < 0) + return r; + + return 0; +} + +static int mount_load(Unit *u) { + Mount *m = MOUNT(u); + int r; + + assert(u); + assert(u->load_state == UNIT_STUB); + + if (m->from_proc_self_mountinfo) + r = unit_load_fragment_and_dropin_optional(u); + else + r = unit_load_fragment_and_dropin(u); + + if (r < 0) + return r; + + /* This is a new unit? Then let's add in some extras */ + if (u->load_state == UNIT_LOADED) { + r = mount_add_extras(m); + if (r < 0) + return r; + + r = unit_exec_context_defaults(u, &m->exec_context); + if (r < 0) + return r; + } + + return mount_verify(m); +} + +static int mount_notify_automount(Mount *m, int status) { + Unit *p; + int r; + Iterator i; + + assert(m); + + SET_FOREACH(p, UNIT(m)->dependencies[UNIT_TRIGGERED_BY], i) + if (p->type == UNIT_AUTOMOUNT) { + r = automount_send_ready(AUTOMOUNT(p), status); + if (r < 0) + return r; + } + + return 0; +} + +static void mount_set_state(Mount *m, MountState state) { + MountState old_state; + assert(m); + + old_state = m->state; + m->state = state; + + if (state != MOUNT_MOUNTING && + state != MOUNT_MOUNTING_DONE && + state != MOUNT_REMOUNTING && + state != MOUNT_UNMOUNTING && + state != MOUNT_MOUNTING_SIGTERM && + state != MOUNT_MOUNTING_SIGKILL && + state != MOUNT_UNMOUNTING_SIGTERM && + state != MOUNT_UNMOUNTING_SIGKILL && + state != MOUNT_REMOUNTING_SIGTERM && + state != MOUNT_REMOUNTING_SIGKILL) { + unit_unwatch_timer(UNIT(m), &m->timer_watch); + mount_unwatch_control_pid(m); + m->control_command = NULL; + m->control_command_id = _MOUNT_EXEC_COMMAND_INVALID; + } + + if (state == MOUNT_MOUNTED || + state == MOUNT_REMOUNTING) + mount_notify_automount(m, 0); + else if (state == MOUNT_DEAD || + state == MOUNT_UNMOUNTING || + state == MOUNT_MOUNTING_SIGTERM || + state == MOUNT_MOUNTING_SIGKILL || + state == MOUNT_REMOUNTING_SIGTERM || + state == MOUNT_REMOUNTING_SIGKILL || + state == MOUNT_UNMOUNTING_SIGTERM || + state == MOUNT_UNMOUNTING_SIGKILL || + state == MOUNT_FAILED) { + if (state != old_state) + mount_notify_automount(m, -ENODEV); + } + + if (state != old_state) + log_debug_unit(UNIT(m)->id, + "%s changed %s -> %s", + UNIT(m)->id, + mount_state_to_string(old_state), + mount_state_to_string(state)); + + unit_notify(UNIT(m), state_translation_table[old_state], state_translation_table[state], m->reload_result == MOUNT_SUCCESS); + m->reload_result = MOUNT_SUCCESS; +} + +static int mount_coldplug(Unit *u) { + Mount *m = MOUNT(u); + MountState new_state = MOUNT_DEAD; + int r; + + assert(m); + assert(m->state == MOUNT_DEAD); + + if (m->deserialized_state != m->state) + new_state = m->deserialized_state; + else if (m->from_proc_self_mountinfo) + new_state = MOUNT_MOUNTED; + + if (new_state != m->state) { + + if (new_state == MOUNT_MOUNTING || + new_state == MOUNT_MOUNTING_DONE || + new_state == MOUNT_REMOUNTING || + new_state == MOUNT_UNMOUNTING || + new_state == MOUNT_MOUNTING_SIGTERM || + new_state == MOUNT_MOUNTING_SIGKILL || + new_state == MOUNT_UNMOUNTING_SIGTERM || + new_state == MOUNT_UNMOUNTING_SIGKILL || + new_state == MOUNT_REMOUNTING_SIGTERM || + new_state == MOUNT_REMOUNTING_SIGKILL) { + + if (m->control_pid <= 0) + return -EBADMSG; + + r = unit_watch_pid(UNIT(m), m->control_pid); + if (r < 0) + return r; + + r = unit_watch_timer(UNIT(m), CLOCK_MONOTONIC, true, m->timeout_usec, &m->timer_watch); + if (r < 0) + return r; + } + + mount_set_state(m, new_state); + } + + return 0; +} + +static void mount_dump(Unit *u, FILE *f, const char *prefix) { + Mount *m = MOUNT(u); + MountParameters *p; + + assert(m); + assert(f); + + p = get_mount_parameters(m); + + fprintf(f, + "%sMount State: %s\n" + "%sResult: %s\n" + "%sWhere: %s\n" + "%sWhat: %s\n" + "%sFile System Type: %s\n" + "%sOptions: %s\n" + "%sFrom /proc/self/mountinfo: %s\n" + "%sFrom fragment: %s\n" + "%sDirectoryMode: %04o\n", + prefix, mount_state_to_string(m->state), + prefix, mount_result_to_string(m->result), + prefix, m->where, + prefix, strna(p->what), + prefix, strna(p->fstype), + prefix, strna(p->options), + prefix, yes_no(m->from_proc_self_mountinfo), + prefix, yes_no(m->from_fragment), + prefix, m->directory_mode); + + if (m->control_pid > 0) + fprintf(f, + "%sControl PID: %lu\n", + prefix, (unsigned long) m->control_pid); + + exec_context_dump(&m->exec_context, f, prefix); + kill_context_dump(&m->kill_context, f, prefix); +} + +static int mount_spawn(Mount *m, ExecCommand *c, pid_t *_pid) { + pid_t pid; + int r; + + assert(m); + assert(c); + assert(_pid); + + r = unit_watch_timer(UNIT(m), CLOCK_MONOTONIC, true, m->timeout_usec, &m->timer_watch); + if (r < 0) + goto fail; + + if ((r = exec_spawn(c, + NULL, + &m->exec_context, + NULL, 0, + UNIT(m)->manager->environment, + true, + true, + true, + UNIT(m)->manager->confirm_spawn, + UNIT(m)->cgroup_bondings, + UNIT(m)->cgroup_attributes, + NULL, + UNIT(m)->id, + NULL, + &pid)) < 0) + goto fail; + + if ((r = unit_watch_pid(UNIT(m), pid)) < 0) + /* FIXME: we need to do something here */ + goto fail; + + *_pid = pid; + + return 0; + +fail: + unit_unwatch_timer(UNIT(m), &m->timer_watch); + + return r; +} + +static void mount_enter_dead(Mount *m, MountResult f) { + assert(m); + + if (f != MOUNT_SUCCESS) + m->result = f; + + mount_set_state(m, m->result != MOUNT_SUCCESS ? MOUNT_FAILED : MOUNT_DEAD); +} + +static void mount_enter_mounted(Mount *m, MountResult f) { + assert(m); + + if (f != MOUNT_SUCCESS) + m->result = f; + + mount_set_state(m, MOUNT_MOUNTED); +} + +static void mount_enter_signal(Mount *m, MountState state, MountResult f) { + int r; + Set *pid_set = NULL; + bool wait_for_exit = false; + + assert(m); + + if (f != MOUNT_SUCCESS) + m->result = f; + + if (m->kill_context.kill_mode != KILL_NONE) { + int sig = (state == MOUNT_MOUNTING_SIGTERM || + state == MOUNT_UNMOUNTING_SIGTERM || + state == MOUNT_REMOUNTING_SIGTERM) ? m->kill_context.kill_signal : SIGKILL; + + if (m->control_pid > 0) { + if (kill_and_sigcont(m->control_pid, sig) < 0 && errno != ESRCH) + + log_warning_unit(UNIT(m)->id, + "Failed to kill control process %li: %m", + (long) m->control_pid); + else + wait_for_exit = true; + } + + if (m->kill_context.kill_mode == KILL_CONTROL_GROUP) { + + if (!(pid_set = set_new(trivial_hash_func, trivial_compare_func))) { + r = -ENOMEM; + goto fail; + } + + /* Exclude the control pid from being killed via the cgroup */ + if (m->control_pid > 0) + if ((r = set_put(pid_set, LONG_TO_PTR(m->control_pid))) < 0) + goto fail; + + r = cgroup_bonding_kill_list(UNIT(m)->cgroup_bondings, sig, true, false, pid_set, NULL); + if (r < 0) { + if (r != -EAGAIN && r != -ESRCH && r != -ENOENT) + log_warning_unit(UNIT(m)->id, + "Failed to kill control group: %s", + strerror(-r)); + } else if (r > 0) + wait_for_exit = true; + + set_free(pid_set); + pid_set = NULL; + } + } + + if (wait_for_exit) { + r = unit_watch_timer(UNIT(m), CLOCK_MONOTONIC, true, m->timeout_usec, &m->timer_watch); + if (r < 0) + goto fail; + + mount_set_state(m, state); + } else if (state == MOUNT_REMOUNTING_SIGTERM || state == MOUNT_REMOUNTING_SIGKILL) + mount_enter_mounted(m, MOUNT_SUCCESS); + else + mount_enter_dead(m, MOUNT_SUCCESS); + + return; + +fail: + log_warning_unit(UNIT(m)->id, + "%s failed to kill processes: %s", UNIT(m)->id, strerror(-r)); + + if (state == MOUNT_REMOUNTING_SIGTERM || state == MOUNT_REMOUNTING_SIGKILL) + mount_enter_mounted(m, MOUNT_FAILURE_RESOURCES); + else + mount_enter_dead(m, MOUNT_FAILURE_RESOURCES); + + if (pid_set) + set_free(pid_set); +} + +void warn_if_dir_nonempty(const char *unit, const char* where) { + if (dir_is_empty(where) > 0) + return; + log_struct(LOG_NOTICE, + "MESSAGE=%s: Directory %s to mount over is not empty, mounting anyway.", + unit, where, + "WHERE=%s", where, + "_SYSTEMD_UNIT=%s", unit, + MESSAGE_ID(SD_MESSAGE_OVERMOUNTING), + NULL); +} + +static void mount_enter_unmounting(Mount *m) { + int r; + + assert(m); + + m->control_command_id = MOUNT_EXEC_UNMOUNT; + m->control_command = m->exec_command + MOUNT_EXEC_UNMOUNT; + + if ((r = exec_command_set( + m->control_command, + "/bin/umount", + m->where, + NULL)) < 0) + goto fail; + + mount_unwatch_control_pid(m); + + if ((r = mount_spawn(m, m->control_command, &m->control_pid)) < 0) + goto fail; + + mount_set_state(m, MOUNT_UNMOUNTING); + + return; + +fail: + log_warning_unit(UNIT(m)->id, + "%s failed to run 'umount' task: %s", + UNIT(m)->id, strerror(-r)); + mount_enter_mounted(m, MOUNT_FAILURE_RESOURCES); +} + +static void mount_enter_mounting(Mount *m) { + int r; + MountParameters *p; + + assert(m); + + m->control_command_id = MOUNT_EXEC_MOUNT; + m->control_command = m->exec_command + MOUNT_EXEC_MOUNT; + + mkdir_p_label(m->where, m->directory_mode); + + warn_if_dir_nonempty(m->meta.id, m->where); + + /* Create the source directory for bind-mounts if needed */ + p = get_mount_parameters_fragment(m); + if (p && mount_is_bind(p)) + mkdir_p_label(p->what, m->directory_mode); + + if (m->from_fragment) + r = exec_command_set( + m->control_command, + "/bin/mount", + m->parameters_fragment.what, + m->where, + "-t", m->parameters_fragment.fstype ? m->parameters_fragment.fstype : "auto", + m->parameters_fragment.options ? "-o" : NULL, m->parameters_fragment.options, + NULL); + else + r = -ENOENT; + + if (r < 0) + goto fail; + + mount_unwatch_control_pid(m); + + r = mount_spawn(m, m->control_command, &m->control_pid); + if (r < 0) + goto fail; + + mount_set_state(m, MOUNT_MOUNTING); + + return; + +fail: + log_warning_unit(UNIT(m)->id, + "%s failed to run 'mount' task: %s", + UNIT(m)->id, strerror(-r)); + mount_enter_dead(m, MOUNT_FAILURE_RESOURCES); +} + +static void mount_enter_mounting_done(Mount *m) { + assert(m); + + mount_set_state(m, MOUNT_MOUNTING_DONE); +} + +static void mount_enter_remounting(Mount *m) { + int r; + + assert(m); + + m->control_command_id = MOUNT_EXEC_REMOUNT; + m->control_command = m->exec_command + MOUNT_EXEC_REMOUNT; + + if (m->from_fragment) { + char *buf = NULL; + const char *o; + + if (m->parameters_fragment.options) { + if (!(buf = strappend("remount,", m->parameters_fragment.options))) { + r = -ENOMEM; + goto fail; + } + + o = buf; + } else + o = "remount"; + + r = exec_command_set( + m->control_command, + "/bin/mount", + m->parameters_fragment.what, + m->where, + "-t", m->parameters_fragment.fstype ? m->parameters_fragment.fstype : "auto", + "-o", o, + NULL); + + free(buf); + } else + r = -ENOENT; + + if (r < 0) + goto fail; + + mount_unwatch_control_pid(m); + + if ((r = mount_spawn(m, m->control_command, &m->control_pid)) < 0) + goto fail; + + mount_set_state(m, MOUNT_REMOUNTING); + + return; + +fail: + log_warning_unit(UNIT(m)->id, + "%s failed to run 'remount' task: %s", + UNIT(m)->id, strerror(-r)); + m->reload_result = MOUNT_FAILURE_RESOURCES; + mount_enter_mounted(m, MOUNT_SUCCESS); +} + +static int mount_start(Unit *u) { + Mount *m = MOUNT(u); + + assert(m); + + /* We cannot fulfill this request right now, try again later + * please! */ + if (m->state == MOUNT_UNMOUNTING || + m->state == MOUNT_UNMOUNTING_SIGTERM || + m->state == MOUNT_UNMOUNTING_SIGKILL || + m->state == MOUNT_MOUNTING_SIGTERM || + m->state == MOUNT_MOUNTING_SIGKILL) + return -EAGAIN; + + /* Already on it! */ + if (m->state == MOUNT_MOUNTING) + return 0; + + assert(m->state == MOUNT_DEAD || m->state == MOUNT_FAILED); + + m->result = MOUNT_SUCCESS; + m->reload_result = MOUNT_SUCCESS; + + mount_enter_mounting(m); + return 0; +} + +static int mount_stop(Unit *u) { + Mount *m = MOUNT(u); + + assert(m); + + /* Already on it */ + if (m->state == MOUNT_UNMOUNTING || + m->state == MOUNT_UNMOUNTING_SIGKILL || + m->state == MOUNT_UNMOUNTING_SIGTERM || + m->state == MOUNT_MOUNTING_SIGTERM || + m->state == MOUNT_MOUNTING_SIGKILL) + return 0; + + assert(m->state == MOUNT_MOUNTING || + m->state == MOUNT_MOUNTING_DONE || + m->state == MOUNT_MOUNTED || + m->state == MOUNT_REMOUNTING || + m->state == MOUNT_REMOUNTING_SIGTERM || + m->state == MOUNT_REMOUNTING_SIGKILL); + + mount_enter_unmounting(m); + return 0; +} + +static int mount_reload(Unit *u) { + Mount *m = MOUNT(u); + + assert(m); + + if (m->state == MOUNT_MOUNTING_DONE) + return -EAGAIN; + + assert(m->state == MOUNT_MOUNTED); + + mount_enter_remounting(m); + return 0; +} + +static int mount_serialize(Unit *u, FILE *f, FDSet *fds) { + Mount *m = MOUNT(u); + + assert(m); + assert(f); + assert(fds); + + unit_serialize_item(u, f, "state", mount_state_to_string(m->state)); + unit_serialize_item(u, f, "result", mount_result_to_string(m->result)); + unit_serialize_item(u, f, "reload-result", mount_result_to_string(m->reload_result)); + + if (m->control_pid > 0) + unit_serialize_item_format(u, f, "control-pid", "%lu", (unsigned long) m->control_pid); + + if (m->control_command_id >= 0) + unit_serialize_item(u, f, "control-command", mount_exec_command_to_string(m->control_command_id)); + + return 0; +} + +static int mount_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) { + Mount *m = MOUNT(u); + + assert(u); + assert(key); + assert(value); + assert(fds); + + if (streq(key, "state")) { + MountState state; + + if ((state = mount_state_from_string(value)) < 0) + log_debug_unit(u->id, "Failed to parse state value %s", value); + else + m->deserialized_state = state; + } else if (streq(key, "result")) { + MountResult f; + + f = mount_result_from_string(value); + if (f < 0) + log_debug_unit(UNIT(m)->id, + "Failed to parse result value %s", value); + else if (f != MOUNT_SUCCESS) + m->result = f; + + } else if (streq(key, "reload-result")) { + MountResult f; + + f = mount_result_from_string(value); + if (f < 0) + log_debug_unit(UNIT(m)->id, + "Failed to parse reload result value %s", value); + else if (f != MOUNT_SUCCESS) + m->reload_result = f; + + } else if (streq(key, "control-pid")) { + pid_t pid; + + if (parse_pid(value, &pid) < 0) + log_debug_unit(UNIT(m)->id, + "Failed to parse control-pid value %s", value); + else + m->control_pid = pid; + } else if (streq(key, "control-command")) { + MountExecCommand id; + + if ((id = mount_exec_command_from_string(value)) < 0) + log_debug_unit(UNIT(m)->id, + "Failed to parse exec-command value %s", value); + else { + m->control_command_id = id; + m->control_command = m->exec_command + id; + } + + } else + log_debug_unit(UNIT(m)->id, + "Unknown serialization key '%s'", key); + + return 0; +} + +static UnitActiveState mount_active_state(Unit *u) { + assert(u); + + return state_translation_table[MOUNT(u)->state]; +} + +static const char *mount_sub_state_to_string(Unit *u) { + assert(u); + + return mount_state_to_string(MOUNT(u)->state); +} + +static bool mount_check_gc(Unit *u) { + Mount *m = MOUNT(u); + + assert(m); + + return m->from_proc_self_mountinfo; +} + +static void mount_sigchld_event(Unit *u, pid_t pid, int code, int status) { + Mount *m = MOUNT(u); + MountResult f; + + assert(m); + assert(pid >= 0); + + if (pid != m->control_pid) + return; + + m->control_pid = 0; + + if (is_clean_exit(code, status, NULL)) + f = MOUNT_SUCCESS; + else if (code == CLD_EXITED) + f = MOUNT_FAILURE_EXIT_CODE; + else if (code == CLD_KILLED) + f = MOUNT_FAILURE_SIGNAL; + else if (code == CLD_DUMPED) + f = MOUNT_FAILURE_CORE_DUMP; + else + assert_not_reached("Unknown code"); + + if (f != MOUNT_SUCCESS) + m->result = f; + + if (m->control_command) { + exec_status_exit(&m->control_command->exec_status, &m->exec_context, pid, code, status); + + m->control_command = NULL; + m->control_command_id = _MOUNT_EXEC_COMMAND_INVALID; + } + + log_full_unit(f == MOUNT_SUCCESS ? LOG_DEBUG : LOG_NOTICE, u->id, + "%s mount process exited, code=%s status=%i", + u->id, 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. */ + + switch (m->state) { + + case MOUNT_MOUNTING: + case MOUNT_MOUNTING_DONE: + case MOUNT_MOUNTING_SIGKILL: + case MOUNT_MOUNTING_SIGTERM: + + if (f == MOUNT_SUCCESS) + mount_enter_mounted(m, f); + else if (m->from_proc_self_mountinfo) + mount_enter_mounted(m, f); + else + mount_enter_dead(m, f); + break; + + case MOUNT_REMOUNTING: + case MOUNT_REMOUNTING_SIGKILL: + case MOUNT_REMOUNTING_SIGTERM: + + m->reload_result = f; + if (m->from_proc_self_mountinfo) + mount_enter_mounted(m, MOUNT_SUCCESS); + else + mount_enter_dead(m, MOUNT_SUCCESS); + + break; + + case MOUNT_UNMOUNTING: + case MOUNT_UNMOUNTING_SIGKILL: + case MOUNT_UNMOUNTING_SIGTERM: + + if (f == MOUNT_SUCCESS) + mount_enter_dead(m, f); + else if (m->from_proc_self_mountinfo) + mount_enter_mounted(m, f); + else + mount_enter_dead(m, f); + break; + + default: + assert_not_reached("Uh, control process died at wrong time."); + } + + /* Notify clients about changed exit status */ + unit_add_to_dbus_queue(u); +} + +static void mount_timer_event(Unit *u, uint64_t elapsed, Watch *w) { + Mount *m = MOUNT(u); + + assert(m); + assert(elapsed == 1); + assert(w == &m->timer_watch); + + switch (m->state) { + + case MOUNT_MOUNTING: + case MOUNT_MOUNTING_DONE: + log_warning_unit(u->id, + "%s mounting timed out. Stopping.", u->id); + mount_enter_signal(m, MOUNT_MOUNTING_SIGTERM, MOUNT_FAILURE_TIMEOUT); + break; + + case MOUNT_REMOUNTING: + log_warning_unit(u->id, + "%s remounting timed out. Stopping.", u->id); + m->reload_result = MOUNT_FAILURE_TIMEOUT; + mount_enter_mounted(m, MOUNT_SUCCESS); + break; + + case MOUNT_UNMOUNTING: + log_warning_unit(u->id, + "%s unmounting timed out. Stopping.", u->id); + mount_enter_signal(m, MOUNT_UNMOUNTING_SIGTERM, MOUNT_FAILURE_TIMEOUT); + break; + + case MOUNT_MOUNTING_SIGTERM: + if (m->kill_context.send_sigkill) { + log_warning_unit(u->id, + "%s mounting timed out. Killing.", u->id); + mount_enter_signal(m, MOUNT_MOUNTING_SIGKILL, MOUNT_FAILURE_TIMEOUT); + } else { + log_warning_unit(u->id, + "%s mounting timed out. Skipping SIGKILL. Ignoring.", + u->id); + + if (m->from_proc_self_mountinfo) + mount_enter_mounted(m, MOUNT_FAILURE_TIMEOUT); + else + mount_enter_dead(m, MOUNT_FAILURE_TIMEOUT); + } + break; + + case MOUNT_REMOUNTING_SIGTERM: + if (m->kill_context.send_sigkill) { + log_warning_unit(u->id, + "%s remounting timed out. Killing.", u->id); + mount_enter_signal(m, MOUNT_REMOUNTING_SIGKILL, MOUNT_FAILURE_TIMEOUT); + } else { + log_warning_unit(u->id, + "%s remounting timed out. Skipping SIGKILL. Ignoring.", + u->id); + + if (m->from_proc_self_mountinfo) + mount_enter_mounted(m, MOUNT_FAILURE_TIMEOUT); + else + mount_enter_dead(m, MOUNT_FAILURE_TIMEOUT); + } + break; + + case MOUNT_UNMOUNTING_SIGTERM: + if (m->kill_context.send_sigkill) { + log_warning_unit(u->id, + "%s unmounting timed out. Killing.", u->id); + mount_enter_signal(m, MOUNT_UNMOUNTING_SIGKILL, MOUNT_FAILURE_TIMEOUT); + } else { + log_warning_unit(u->id, + "%s unmounting timed out. Skipping SIGKILL. Ignoring.", + u->id); + + if (m->from_proc_self_mountinfo) + mount_enter_mounted(m, MOUNT_FAILURE_TIMEOUT); + else + mount_enter_dead(m, MOUNT_FAILURE_TIMEOUT); + } + break; + + case MOUNT_MOUNTING_SIGKILL: + case MOUNT_REMOUNTING_SIGKILL: + case MOUNT_UNMOUNTING_SIGKILL: + log_warning_unit(u->id, + "%s mount process still around after SIGKILL. Ignoring.", + u->id); + + if (m->from_proc_self_mountinfo) + mount_enter_mounted(m, MOUNT_FAILURE_TIMEOUT); + else + mount_enter_dead(m, MOUNT_FAILURE_TIMEOUT); + break; + + default: + assert_not_reached("Timeout at wrong time."); + } +} + +static int mount_add_one( + Manager *m, + const char *what, + const char *where, + const char *options, + const char *fstype, + int passno, + bool set_flags) { + int r; + Unit *u; + bool delete; + char *e, *w = NULL, *o = NULL, *f = NULL; + MountParameters *p; + bool load_extras = false; + + assert(m); + assert(what); + assert(where); + assert(options); + assert(fstype); + + /* Ignore API mount points. They should never be referenced in + * dependencies ever. */ + if (mount_point_is_api(where) || mount_point_ignore(where)) + return 0; + + if (streq(fstype, "autofs")) + return 0; + + /* probably some kind of swap, ignore */ + if (!is_path(where)) + return 0; + + e = unit_name_from_path(where, ".mount"); + if (!e) + return -ENOMEM; + + u = manager_get_unit(m, e); + if (!u) { + delete = true; + + u = unit_new(m, sizeof(Mount)); + if (!u) { + free(e); + return -ENOMEM; + } + + r = unit_add_name(u, e); + free(e); + + if (r < 0) + goto fail; + + MOUNT(u)->where = strdup(where); + if (!MOUNT(u)->where) { + r = -ENOMEM; + goto fail; + } + + unit_add_to_load_queue(u); + } else { + delete = false; + free(e); + + if (!MOUNT(u)->where) { + MOUNT(u)->where = strdup(where); + if (!MOUNT(u)->where) { + r = -ENOMEM; + goto fail; + } + } + + if (u->load_state == UNIT_ERROR) { + u->load_state = UNIT_LOADED; + u->load_error = 0; + + /* Load in the extras later on, after we + * finished initialization of the unit */ + load_extras = true; + } + } + + if (!(w = strdup(what)) || + !(o = strdup(options)) || + !(f = strdup(fstype))) { + r = -ENOMEM; + goto fail; + } + + p = &MOUNT(u)->parameters_proc_self_mountinfo; + if (set_flags) { + MOUNT(u)->is_mounted = true; + MOUNT(u)->just_mounted = !MOUNT(u)->from_proc_self_mountinfo; + MOUNT(u)->just_changed = !streq_ptr(p->options, o); + } + + MOUNT(u)->from_proc_self_mountinfo = true; + + free(p->what); + p->what = w; + + free(p->options); + p->options = o; + + free(p->fstype); + p->fstype = f; + + p->passno = passno; + + if (load_extras) { + r = mount_add_extras(MOUNT(u)); + if (r < 0) + goto fail; + } + + unit_add_to_dbus_queue(u); + + return 0; + +fail: + free(w); + free(o); + free(f); + + if (delete && u) + unit_free(u); + + return r; +} + +static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) { + int r = 0; + unsigned i; + char *device, *path, *options, *options2, *fstype, *d, *p, *o; + + assert(m); + + rewind(m->proc_self_mountinfo); + + for (i = 1;; i++) { + int k; + + device = path = options = options2 = fstype = d = p = o = NULL; + + if ((k = fscanf(m->proc_self_mountinfo, + "%*s " /* (1) mount id */ + "%*s " /* (2) parent id */ + "%*s " /* (3) major:minor */ + "%*s " /* (4) root */ + "%ms " /* (5) mount point */ + "%ms" /* (6) mount options */ + "%*[^-]" /* (7) optional fields */ + "- " /* (8) separator */ + "%ms " /* (9) file system type */ + "%ms" /* (10) mount source */ + "%ms" /* (11) mount options 2 */ + "%*[^\n]", /* some rubbish at the end */ + &path, + &options, + &fstype, + &device, + &options2)) != 5) { + + if (k == EOF) + break; + + log_warning("Failed to parse /proc/self/mountinfo:%u.", i); + goto clean_up; + } + + o = strjoin(options, ",", options2, NULL); + if (!o) { + r = -ENOMEM; + goto finish; + } + + if (!(d = cunescape(device)) || + !(p = cunescape(path))) { + r = -ENOMEM; + goto finish; + } + + if ((k = mount_add_one(m, d, p, o, fstype, 0, set_flags)) < 0) + r = k; + +clean_up: + free(device); + free(path); + free(options); + free(options2); + free(fstype); + free(d); + free(p); + free(o); + } + +finish: + free(device); + free(path); + free(options); + free(options2); + free(fstype); + free(d); + free(p); + free(o); + + return r; +} + +static void mount_shutdown(Manager *m) { + assert(m); + + if (m->proc_self_mountinfo) { + fclose(m->proc_self_mountinfo); + m->proc_self_mountinfo = NULL; + } +} + +static int mount_enumerate(Manager *m) { + int r; + struct epoll_event ev; + assert(m); + + if (!m->proc_self_mountinfo) { + if (!(m->proc_self_mountinfo = fopen("/proc/self/mountinfo", "re"))) + return -errno; + + m->mount_watch.type = WATCH_MOUNT; + m->mount_watch.fd = fileno(m->proc_self_mountinfo); + + zero(ev); + ev.events = EPOLLPRI; + ev.data.ptr = &m->mount_watch; + + if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->mount_watch.fd, &ev) < 0) + return -errno; + } + + if ((r = mount_load_proc_self_mountinfo(m, false)) < 0) + goto fail; + + return 0; + +fail: + mount_shutdown(m); + return r; +} + +void mount_fd_event(Manager *m, int events) { + Unit *u; + int r; + + assert(m); + assert(events & EPOLLPRI); + + /* The manager calls this for every fd event happening on the + * /proc/self/mountinfo file, which informs us about mounting + * table changes */ + + r = mount_load_proc_self_mountinfo(m, true); + if (r < 0) { + log_error("Failed to reread /proc/self/mountinfo: %s", strerror(-r)); + + /* Reset flags, just in case, for later calls */ + LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_MOUNT]) { + Mount *mount = MOUNT(u); + + mount->is_mounted = mount->just_mounted = mount->just_changed = false; + } + + return; + } + + manager_dispatch_load_queue(m); + + LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_MOUNT]) { + Mount *mount = MOUNT(u); + + if (!mount->is_mounted) { + /* This has just been unmounted. */ + + mount->from_proc_self_mountinfo = false; + + switch (mount->state) { + + case MOUNT_MOUNTED: + mount_enter_dead(mount, MOUNT_SUCCESS); + break; + + default: + mount_set_state(mount, mount->state); + break; + + } + + } else if (mount->just_mounted || mount->just_changed) { + + /* New or changed mount entry */ + + switch (mount->state) { + + case MOUNT_DEAD: + case MOUNT_FAILED: + mount_enter_mounted(mount, MOUNT_SUCCESS); + break; + + case MOUNT_MOUNTING: + mount_enter_mounting_done(mount); + break; + + default: + /* Nothing really changed, but let's + * issue an notification call + * nonetheless, in case somebody is + * waiting for this. (e.g. file system + * ro/rw remounts.) */ + mount_set_state(mount, mount->state); + break; + } + } + + /* Reset the flags for later calls */ + mount->is_mounted = mount->just_mounted = mount->just_changed = false; + } +} + +static void mount_reset_failed(Unit *u) { + Mount *m = MOUNT(u); + + assert(m); + + if (m->state == MOUNT_FAILED) + mount_set_state(m, MOUNT_DEAD); + + m->result = MOUNT_SUCCESS; + m->reload_result = MOUNT_SUCCESS; +} + +static int mount_kill(Unit *u, KillWho who, int signo, DBusError *error) { + Mount *m = MOUNT(u); + int r = 0; + Set *pid_set = NULL; + + assert(m); + + if (who == KILL_MAIN) { + dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "Mount units have no main processes"); + return -ESRCH; + } + + if (m->control_pid <= 0 && who == KILL_CONTROL) { + dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "No control process to kill"); + return -ESRCH; + } + + if (who == KILL_CONTROL || who == KILL_ALL) + if (m->control_pid > 0) + if (kill(m->control_pid, signo) < 0) + r = -errno; + + if (who == KILL_ALL) { + int q; + + pid_set = set_new(trivial_hash_func, trivial_compare_func); + if (!pid_set) + return -ENOMEM; + + /* Exclude the control pid from being killed via the cgroup */ + if (m->control_pid > 0) { + q = set_put(pid_set, LONG_TO_PTR(m->control_pid)); + if (q < 0) { + r = q; + goto finish; + } + } + + q = cgroup_bonding_kill_list(UNIT(m)->cgroup_bondings, signo, false, false, pid_set, NULL); + if (q < 0 && q != -EAGAIN && q != -ESRCH && q != -ENOENT) + r = q; + } + +finish: + if (pid_set) + set_free(pid_set); + + return r; +} + +static const char* const mount_state_table[_MOUNT_STATE_MAX] = { + [MOUNT_DEAD] = "dead", + [MOUNT_MOUNTING] = "mounting", + [MOUNT_MOUNTING_DONE] = "mounting-done", + [MOUNT_MOUNTED] = "mounted", + [MOUNT_REMOUNTING] = "remounting", + [MOUNT_UNMOUNTING] = "unmounting", + [MOUNT_MOUNTING_SIGTERM] = "mounting-sigterm", + [MOUNT_MOUNTING_SIGKILL] = "mounting-sigkill", + [MOUNT_REMOUNTING_SIGTERM] = "remounting-sigterm", + [MOUNT_REMOUNTING_SIGKILL] = "remounting-sigkill", + [MOUNT_UNMOUNTING_SIGTERM] = "unmounting-sigterm", + [MOUNT_UNMOUNTING_SIGKILL] = "unmounting-sigkill", + [MOUNT_FAILED] = "failed" +}; + +DEFINE_STRING_TABLE_LOOKUP(mount_state, MountState); + +static const char* const mount_exec_command_table[_MOUNT_EXEC_COMMAND_MAX] = { + [MOUNT_EXEC_MOUNT] = "ExecMount", + [MOUNT_EXEC_UNMOUNT] = "ExecUnmount", + [MOUNT_EXEC_REMOUNT] = "ExecRemount", +}; + +DEFINE_STRING_TABLE_LOOKUP(mount_exec_command, MountExecCommand); + +static const char* const mount_result_table[_MOUNT_RESULT_MAX] = { + [MOUNT_SUCCESS] = "success", + [MOUNT_FAILURE_RESOURCES] = "resources", + [MOUNT_FAILURE_TIMEOUT] = "timeout", + [MOUNT_FAILURE_EXIT_CODE] = "exit-code", + [MOUNT_FAILURE_SIGNAL] = "signal", + [MOUNT_FAILURE_CORE_DUMP] = "core-dump" +}; + +DEFINE_STRING_TABLE_LOOKUP(mount_result, MountResult); + +const UnitVTable mount_vtable = { + .object_size = sizeof(Mount), + .exec_context_offset = offsetof(Mount, exec_context), + + .sections = + "Unit\0" + "Mount\0" + "Install\0", + + .no_alias = true, + .no_instances = true, + + .init = mount_init, + .load = mount_load, + .done = mount_done, + + .coldplug = mount_coldplug, + + .dump = mount_dump, + + .start = mount_start, + .stop = mount_stop, + .reload = mount_reload, + + .kill = mount_kill, + + .serialize = mount_serialize, + .deserialize_item = mount_deserialize_item, + + .active_state = mount_active_state, + .sub_state_to_string = mount_sub_state_to_string, + + .check_gc = mount_check_gc, + + .sigchld_event = mount_sigchld_event, + .timer_event = mount_timer_event, + + .reset_failed = mount_reset_failed, + + .bus_interface = "org.freedesktop.systemd1.Mount", + .bus_message_handler = bus_mount_message_handler, + .bus_invalidating_properties = bus_mount_invalidating_properties, + + .enumerate = mount_enumerate, + .shutdown = mount_shutdown, + + .status_message_formats = { + .starting_stopping = { + [0] = "Mounting %s...", + [1] = "Unmounting %s...", + }, + .finished_start_job = { + [JOB_DONE] = "Mounted %s.", + [JOB_FAILED] = "Failed to mount %s.", + [JOB_DEPENDENCY] = "Dependency failed for %s.", + [JOB_TIMEOUT] = "Timed out mounting %s.", + }, + .finished_stop_job = { + [JOB_DONE] = "Unmounted %s.", + [JOB_FAILED] = "Failed unmounting %s.", + [JOB_TIMEOUT] = "Timed out unmounting %s.", + }, + }, +}; diff --git a/src/core/mount.h b/src/core/mount.h new file mode 100644 index 000000000..30c6d9b24 --- /dev/null +++ b/src/core/mount.h @@ -0,0 +1,123 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +typedef struct Mount Mount; + +#include "unit.h" +#include "kill.h" + +typedef enum MountState { + MOUNT_DEAD, + MOUNT_MOUNTING, /* /bin/mount is running, but the mount is not done yet. */ + MOUNT_MOUNTING_DONE, /* /bin/mount is running, and the mount is done. */ + MOUNT_MOUNTED, + MOUNT_REMOUNTING, + MOUNT_UNMOUNTING, + MOUNT_MOUNTING_SIGTERM, + MOUNT_MOUNTING_SIGKILL, + MOUNT_REMOUNTING_SIGTERM, + MOUNT_REMOUNTING_SIGKILL, + MOUNT_UNMOUNTING_SIGTERM, + MOUNT_UNMOUNTING_SIGKILL, + MOUNT_FAILED, + _MOUNT_STATE_MAX, + _MOUNT_STATE_INVALID = -1 +} MountState; + +typedef enum MountExecCommand { + MOUNT_EXEC_MOUNT, + MOUNT_EXEC_UNMOUNT, + MOUNT_EXEC_REMOUNT, + _MOUNT_EXEC_COMMAND_MAX, + _MOUNT_EXEC_COMMAND_INVALID = -1 +} MountExecCommand; + +typedef struct MountParameters { + char *what; + char *options; + char *fstype; + int passno; +} MountParameters; + +typedef enum MountResult { + MOUNT_SUCCESS, + MOUNT_FAILURE_RESOURCES, + MOUNT_FAILURE_TIMEOUT, + MOUNT_FAILURE_EXIT_CODE, + MOUNT_FAILURE_SIGNAL, + MOUNT_FAILURE_CORE_DUMP, + _MOUNT_RESULT_MAX, + _MOUNT_RESULT_INVALID = -1 +} MountResult; + +struct Mount { + Unit meta; + + char *where; + + MountParameters parameters_proc_self_mountinfo; + MountParameters parameters_fragment; + + bool from_proc_self_mountinfo:1; + bool from_fragment:1; + + /* Used while looking for mount points that vanished or got + * added from/to /proc/self/mountinfo */ + bool is_mounted:1; + bool just_mounted:1; + bool just_changed:1; + + MountResult result; + MountResult reload_result; + + mode_t directory_mode; + + usec_t timeout_usec; + + ExecCommand exec_command[_MOUNT_EXEC_COMMAND_MAX]; + ExecContext exec_context; + KillContext kill_context; + + MountState state, deserialized_state; + + ExecCommand* control_command; + MountExecCommand control_command_id; + pid_t control_pid; + + Watch timer_watch; +}; + +extern const UnitVTable mount_vtable; + +void mount_fd_event(Manager *m, int events); + +const char* mount_state_to_string(MountState i); +MountState mount_state_from_string(const char *s); + +const char* mount_exec_command_to_string(MountExecCommand i); +MountExecCommand mount_exec_command_from_string(const char *s); + +const char* mount_result_to_string(MountResult i); +MountResult mount_result_from_string(const char *s); + +void warn_if_dir_nonempty(const char *unit, const char* where); diff --git a/src/core/namespace.c b/src/core/namespace.c new file mode 100644 index 000000000..ba18ddc5b --- /dev/null +++ b/src/core/namespace.c @@ -0,0 +1,330 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "strv.h" +#include "util.h" +#include "path-util.h" +#include "namespace.h" +#include "missing.h" + +typedef enum PathMode { + /* This is ordered by priority! */ + INACCESSIBLE, + READONLY, + PRIVATE_TMP, + PRIVATE_VAR_TMP, + READWRITE +} PathMode; + +typedef struct Path { + const char *path; + PathMode mode; + bool done; +} Path; + +static int append_paths(Path **p, char **strv, PathMode mode) { + char **i; + + STRV_FOREACH(i, strv) { + + if (!path_is_absolute(*i)) + return -EINVAL; + + (*p)->path = *i; + (*p)->mode = mode; + (*p)++; + } + + return 0; +} + +static int path_compare(const void *a, const void *b) { + const Path *p = a, *q = b; + + if (path_equal(p->path, q->path)) { + + /* If the paths are equal, check the mode */ + if (p->mode < q->mode) + return -1; + + if (p->mode > q->mode) + return 1; + + return 0; + } + + /* If the paths are not equal, then order prefixes first */ + if (path_startswith(p->path, q->path)) + return 1; + + if (path_startswith(q->path, p->path)) + return -1; + + return 0; +} + +static void drop_duplicates(Path *p, unsigned *n, bool *need_inaccessible) { + Path *f, *t, *previous; + + assert(p); + assert(n); + assert(need_inaccessible); + + for (f = p, t = p, previous = NULL; f < p+*n; f++) { + + /* The first one wins */ + if (previous && path_equal(f->path, previous->path)) + continue; + + t->path = f->path; + t->mode = f->mode; + + if (t->mode == INACCESSIBLE) + *need_inaccessible = true; + + previous = t; + + t++; + } + + *n = t - p; +} + +static int apply_mount( + Path *p, + const char *tmp_dir, + const char *var_tmp_dir, + const char *inaccessible_dir) { + + const char *what; + int r; + + assert(p); + + switch (p->mode) { + + case INACCESSIBLE: + what = inaccessible_dir; + break; + + case READONLY: + case READWRITE: + what = p->path; + break; + + case PRIVATE_TMP: + what = tmp_dir; + break; + + case PRIVATE_VAR_TMP: + what = var_tmp_dir; + break; + + default: + assert_not_reached("Unknown mode"); + } + + assert(what); + + r = mount(what, p->path, NULL, MS_BIND|MS_REC, NULL); + if (r >= 0) + log_debug("Successfully mounted %s to %s", what, p->path); + + return r; +} + +static int make_read_only(Path *p) { + int r; + + assert(p); + + if (p->mode != INACCESSIBLE && p->mode != READONLY) + return 0; + + r = mount(NULL, p->path, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY|MS_REC, NULL); + if (r < 0) + return -errno; + + return 0; +} + +int setup_namespace( + char **writable, + char **readable, + char **inaccessible, + bool private_tmp, + unsigned long flags) { + + char + tmp_dir[] = "/tmp/systemd-private-XXXXXX", + var_tmp_dir[] = "/var/tmp/systemd-private-XXXXXX", + inaccessible_dir[] = "/tmp/systemd-inaccessible-XXXXXX"; + + Path *paths, *p; + unsigned n; + bool need_inaccessible = false; + bool remove_tmp = false, remove_var_tmp = false, remove_inaccessible = false; + int r; + + if (!flags) + flags = MS_SHARED; + + n = + strv_length(writable) + + strv_length(readable) + + strv_length(inaccessible) + + (private_tmp ? 2 : 0); + + p = paths = alloca(sizeof(Path) * n); + if ((r = append_paths(&p, writable, READWRITE)) < 0 || + (r = append_paths(&p, readable, READONLY)) < 0 || + (r = append_paths(&p, inaccessible, INACCESSIBLE)) < 0) + goto fail; + + if (private_tmp) { + p->path = "/tmp"; + p->mode = PRIVATE_TMP; + p++; + + p->path = "/var/tmp"; + p->mode = PRIVATE_VAR_TMP; + p++; + } + + assert(paths + n == p); + + qsort(paths, n, sizeof(Path), path_compare); + drop_duplicates(paths, &n, &need_inaccessible); + + if (need_inaccessible) { + mode_t u; + char *d; + + u = umask(0777); + d = mkdtemp(inaccessible_dir); + umask(u); + + if (!d) { + r = -errno; + goto fail; + } + + remove_inaccessible = true; + } + + if (private_tmp) { + mode_t u; + char *d; + + u = umask(0000); + d = mkdtemp(tmp_dir); + umask(u); + + if (!d) { + r = -errno; + goto fail; + } + + remove_tmp = true; + + u = umask(0000); + d = mkdtemp(var_tmp_dir); + umask(u); + + if (!d) { + r = -errno; + goto fail; + } + + remove_var_tmp = true; + + if (chmod(tmp_dir, 0777 + S_ISVTX) < 0) { + r = -errno; + goto fail; + } + + if (chmod(var_tmp_dir, 0777 + S_ISVTX) < 0) { + r = -errno; + goto fail; + } + } + + if (unshare(CLONE_NEWNS) < 0) { + r = -errno; + goto fail; + } + + /* Remount / as SLAVE so that nothing now mounted in the namespace + shows up in the parent */ + if (mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL) < 0) { + r = -errno; + goto fail; + } + + for (p = paths; p < paths + n; p++) { + r = apply_mount(p, tmp_dir, var_tmp_dir, inaccessible_dir); + if (r < 0) + goto undo_mounts; + } + + for (p = paths; p < paths + n; p++) { + r = make_read_only(p); + if (r < 0) + goto undo_mounts; + } + + /* Remount / as the desired mode */ + if (mount(NULL, "/", NULL, flags|MS_REC, NULL) < 0) { + r = -errno; + goto undo_mounts; + } + + return 0; + +undo_mounts: + for (p = paths; p < paths + n; p++) + if (p->done) + umount2(p->path, MNT_DETACH); + +fail: + if (remove_inaccessible) + rmdir(inaccessible_dir); + + if (remove_tmp) + rmdir(tmp_dir); + + if (remove_var_tmp) + rmdir(var_tmp_dir); + + return r; +} diff --git a/src/core/namespace.h b/src/core/namespace.h new file mode 100644 index 000000000..5d72ed91f --- /dev/null +++ b/src/core/namespace.h @@ -0,0 +1,31 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +#include + +int setup_namespace( + char **writable, + char **readable, + char **inaccessible, + bool private_tmp, + unsigned long flags); diff --git a/src/core/org.freedesktop.systemd1.conf b/src/core/org.freedesktop.systemd1.conf new file mode 100644 index 000000000..a07a8e1ce --- /dev/null +++ b/src/core/org.freedesktop.systemd1.conf @@ -0,0 +1,92 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/core/org.freedesktop.systemd1.policy.in.in b/src/core/org.freedesktop.systemd1.policy.in.in new file mode 100644 index 000000000..51bdafac4 --- /dev/null +++ b/src/core/org.freedesktop.systemd1.policy.in.in @@ -0,0 +1,41 @@ + + + + + + + + The systemd Project + http://www.freedesktop.org/wiki/Software/systemd + + + <_description>Send passphrase back to system + <_message>Authentication is required to send the entered passphrase back to the system. + + no + no + auth_admin_keep + + @rootlibexecdir@/systemd-reply-password + + + + <_description>Privileged system and service manager access + <_message>Authentication is required to access the system and service manager. + + no + no + auth_admin_keep + + @bindir@/systemd-stdio-bridge + + + diff --git a/src/core/org.freedesktop.systemd1.service b/src/core/org.freedesktop.systemd1.service new file mode 100644 index 000000000..d4df3e93a --- /dev/null +++ b/src/core/org.freedesktop.systemd1.service @@ -0,0 +1,11 @@ +# This file is part of systemd. +# +# 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. + +[D-BUS Service] +Name=org.freedesktop.systemd1 +Exec=/bin/false +User=root diff --git a/src/core/path.c b/src/core/path.c new file mode 100644 index 000000000..767620ba7 --- /dev/null +++ b/src/core/path.c @@ -0,0 +1,777 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include +#include + +#include "unit.h" +#include "unit-name.h" +#include "path.h" +#include "mkdir.h" +#include "dbus-path.h" +#include "special.h" +#include "bus-errors.h" +#include "path-util.h" + +static const UnitActiveState state_translation_table[_PATH_STATE_MAX] = { + [PATH_DEAD] = UNIT_INACTIVE, + [PATH_WAITING] = UNIT_ACTIVE, + [PATH_RUNNING] = UNIT_ACTIVE, + [PATH_FAILED] = UNIT_FAILED +}; + +int path_spec_watch(PathSpec *s, Unit *u) { + + static const int flags_table[_PATH_TYPE_MAX] = { + [PATH_EXISTS] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB, + [PATH_EXISTS_GLOB] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB, + [PATH_CHANGED] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB|IN_CLOSE_WRITE|IN_CREATE|IN_DELETE|IN_MOVED_FROM|IN_MOVED_TO, + [PATH_MODIFIED] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB|IN_CLOSE_WRITE|IN_CREATE|IN_DELETE|IN_MOVED_FROM|IN_MOVED_TO|IN_MODIFY, + [PATH_DIRECTORY_NOT_EMPTY] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB|IN_CREATE|IN_MOVED_TO + }; + + bool exists = false; + char *k, *slash; + int r; + + assert(u); + assert(s); + + path_spec_unwatch(s, u); + + if (!(k = strdup(s->path))) + return -ENOMEM; + + if ((s->inotify_fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC)) < 0) { + r = -errno; + goto fail; + } + + if (unit_watch_fd(u, s->inotify_fd, EPOLLIN, &s->watch) < 0) { + r = -errno; + goto fail; + } + + s->primary_wd = inotify_add_watch(s->inotify_fd, k, flags_table[s->type]); + if (s->primary_wd >= 0) + exists = true; + + do { + int flags; + + /* This assumes the path was passed through path_kill_slashes()! */ + slash = strrchr(k, '/'); + if (!slash) + break; + + /* Trim the path at the last slash. Keep the slash if it's the root dir. */ + slash[slash == k] = 0; + + flags = IN_MOVE_SELF; + if (!exists) + flags |= IN_DELETE_SELF | IN_ATTRIB | IN_CREATE | IN_MOVED_TO; + + if (inotify_add_watch(s->inotify_fd, k, flags) >= 0) + exists = true; + } while (slash != k); + + return 0; + +fail: + free(k); + + path_spec_unwatch(s, u); + return r; +} + +void path_spec_unwatch(PathSpec *s, Unit *u) { + + if (s->inotify_fd < 0) + return; + + unit_unwatch_fd(u, &s->watch); + + close_nointr_nofail(s->inotify_fd); + s->inotify_fd = -1; +} + +int path_spec_fd_event(PathSpec *s, uint32_t events) { + uint8_t *buf = NULL; + struct inotify_event *e; + ssize_t k; + int l; + int r = 0; + + if (events != EPOLLIN) { + log_error("Got invalid poll event on inotify."); + r = -EINVAL; + goto out; + } + + if (ioctl(s->inotify_fd, FIONREAD, &l) < 0) { + log_error("FIONREAD failed: %m"); + r = -errno; + goto out; + } + + assert(l > 0); + + buf = malloc(l); + if (!buf) { + log_error("Failed to allocate buffer: %m"); + r = -errno; + goto out; + } + + k = read(s->inotify_fd, buf, l); + if (k < 0) { + log_error("Failed to read inotify event: %m"); + r = -errno; + goto out; + } + + e = (struct inotify_event*) buf; + + while (k > 0) { + size_t step; + + if ((s->type == PATH_CHANGED || s->type == PATH_MODIFIED) && + s->primary_wd == e->wd) + r = 1; + + step = sizeof(struct inotify_event) + e->len; + assert(step <= (size_t) k); + + e = (struct inotify_event*) ((uint8_t*) e + step); + k -= step; + } +out: + free(buf); + return r; +} + +static bool path_spec_check_good(PathSpec *s, bool initial) { + bool good = false; + + switch (s->type) { + + case PATH_EXISTS: + good = access(s->path, F_OK) >= 0; + break; + + case PATH_EXISTS_GLOB: + good = glob_exists(s->path) > 0; + break; + + case PATH_DIRECTORY_NOT_EMPTY: { + int k; + + k = dir_is_empty(s->path); + good = !(k == -ENOENT || k > 0); + break; + } + + case PATH_CHANGED: + case PATH_MODIFIED: { + bool b; + + b = access(s->path, F_OK) >= 0; + good = !initial && b != s->previous_exists; + s->previous_exists = b; + break; + } + + default: + ; + } + + return good; +} + +static bool path_spec_startswith(PathSpec *s, const char *what) { + return path_startswith(s->path, what); +} + +static void path_spec_mkdir(PathSpec *s, mode_t mode) { + int r; + + if (s->type == PATH_EXISTS || s->type == PATH_EXISTS_GLOB) + return; + + r = mkdir_p_label(s->path, mode); + if (r < 0) + log_warning("mkdir(%s) failed: %s", s->path, strerror(-r)); +} + +static void path_spec_dump(PathSpec *s, FILE *f, const char *prefix) { + fprintf(f, + "%s%s: %s\n", + prefix, + path_type_to_string(s->type), + s->path); +} + +void path_spec_done(PathSpec *s) { + assert(s); + assert(s->inotify_fd == -1); + + free(s->path); +} + +static void path_init(Unit *u) { + Path *p = PATH(u); + + assert(u); + assert(u->load_state == UNIT_STUB); + + p->directory_mode = 0755; +} + +static void path_done(Unit *u) { + Path *p = PATH(u); + PathSpec *s; + + assert(p); + + unit_ref_unset(&p->unit); + + while ((s = p->specs)) { + path_spec_unwatch(s, u); + LIST_REMOVE(PathSpec, spec, p->specs, s); + path_spec_done(s); + free(s); + } +} + +int path_add_one_mount_link(Path *p, Mount *m) { + PathSpec *s; + int r; + + assert(p); + assert(m); + + if (UNIT(p)->load_state != UNIT_LOADED || + UNIT(m)->load_state != UNIT_LOADED) + return 0; + + LIST_FOREACH(spec, s, p->specs) { + + if (!path_spec_startswith(s, m->where)) + continue; + + if ((r = unit_add_two_dependencies(UNIT(p), UNIT_AFTER, UNIT_REQUIRES, UNIT(m), true)) < 0) + return r; + } + + return 0; +} + +static int path_add_mount_links(Path *p) { + Unit *other; + int r; + + assert(p); + + LIST_FOREACH(units_by_type, other, UNIT(p)->manager->units_by_type[UNIT_MOUNT]) + if ((r = path_add_one_mount_link(p, MOUNT(other))) < 0) + return r; + + return 0; +} + +static int path_verify(Path *p) { + assert(p); + + if (UNIT(p)->load_state != UNIT_LOADED) + return 0; + + if (!p->specs) { + log_error_unit(UNIT(p)->id, + "%s lacks path setting. Refusing.", UNIT(p)->id); + return -EINVAL; + } + + return 0; +} + +static int path_add_default_dependencies(Path *p) { + int r; + + assert(p); + + if (UNIT(p)->manager->running_as == SYSTEMD_SYSTEM) { + if ((r = unit_add_dependency_by_name(UNIT(p), UNIT_BEFORE, SPECIAL_BASIC_TARGET, NULL, true)) < 0) + return r; + + if ((r = unit_add_two_dependencies_by_name(UNIT(p), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SYSINIT_TARGET, NULL, true)) < 0) + return r; + } + + return unit_add_two_dependencies_by_name(UNIT(p), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true); +} + +static int path_load(Unit *u) { + Path *p = PATH(u); + int r; + + assert(u); + assert(u->load_state == UNIT_STUB); + + if ((r = unit_load_fragment_and_dropin(u)) < 0) + return r; + + if (u->load_state == UNIT_LOADED) { + + if (!UNIT_DEREF(p->unit)) { + Unit *x; + + r = unit_load_related_unit(u, ".service", &x); + if (r < 0) + return r; + + unit_ref_set(&p->unit, x); + } + + r = unit_add_two_dependencies(u, UNIT_BEFORE, UNIT_TRIGGERS, UNIT_DEREF(p->unit), true); + if (r < 0) + return r; + + if ((r = path_add_mount_links(p)) < 0) + return r; + + if (UNIT(p)->default_dependencies) + if ((r = path_add_default_dependencies(p)) < 0) + return r; + } + + return path_verify(p); +} + +static void path_dump(Unit *u, FILE *f, const char *prefix) { + Path *p = PATH(u); + PathSpec *s; + + assert(p); + assert(f); + + fprintf(f, + "%sPath State: %s\n" + "%sResult: %s\n" + "%sUnit: %s\n" + "%sMakeDirectory: %s\n" + "%sDirectoryMode: %04o\n", + prefix, path_state_to_string(p->state), + prefix, path_result_to_string(p->result), + prefix, UNIT_DEREF(p->unit)->id, + prefix, yes_no(p->make_directory), + prefix, p->directory_mode); + + LIST_FOREACH(spec, s, p->specs) + path_spec_dump(s, f, prefix); +} + +static void path_unwatch(Path *p) { + PathSpec *s; + + assert(p); + + LIST_FOREACH(spec, s, p->specs) + path_spec_unwatch(s, UNIT(p)); +} + +static int path_watch(Path *p) { + int r; + PathSpec *s; + + assert(p); + + LIST_FOREACH(spec, s, p->specs) + if ((r = path_spec_watch(s, UNIT(p))) < 0) + return r; + + return 0; +} + +static void path_set_state(Path *p, PathState state) { + PathState old_state; + assert(p); + + old_state = p->state; + p->state = state; + + if (state != PATH_WAITING && + (state != PATH_RUNNING || p->inotify_triggered)) + path_unwatch(p); + + if (state != old_state) + log_debug("%s changed %s -> %s", + UNIT(p)->id, + path_state_to_string(old_state), + path_state_to_string(state)); + + unit_notify(UNIT(p), state_translation_table[old_state], state_translation_table[state], true); +} + +static void path_enter_waiting(Path *p, bool initial, bool recheck); + +static int path_coldplug(Unit *u) { + Path *p = PATH(u); + + assert(p); + assert(p->state == PATH_DEAD); + + if (p->deserialized_state != p->state) { + + if (p->deserialized_state == PATH_WAITING || + p->deserialized_state == PATH_RUNNING) + path_enter_waiting(p, true, true); + else + path_set_state(p, p->deserialized_state); + } + + return 0; +} + +static void path_enter_dead(Path *p, PathResult f) { + assert(p); + + if (f != PATH_SUCCESS) + p->result = f; + + path_set_state(p, p->result != PATH_SUCCESS ? PATH_FAILED : PATH_DEAD); +} + +static void path_enter_running(Path *p) { + int r; + DBusError error; + + assert(p); + dbus_error_init(&error); + + /* Don't start job if we are supposed to go down */ + if (UNIT(p)->job && UNIT(p)->job->type == JOB_STOP) + return; + + if ((r = manager_add_job(UNIT(p)->manager, JOB_START, UNIT_DEREF(p->unit), JOB_REPLACE, true, &error, NULL)) < 0) + goto fail; + + p->inotify_triggered = false; + + if ((r = path_watch(p)) < 0) + goto fail; + + path_set_state(p, PATH_RUNNING); + return; + +fail: + log_warning("%s failed to queue unit startup job: %s", UNIT(p)->id, bus_error(&error, r)); + path_enter_dead(p, PATH_FAILURE_RESOURCES); + + dbus_error_free(&error); +} + +static bool path_check_good(Path *p, bool initial) { + PathSpec *s; + bool good = false; + + assert(p); + + LIST_FOREACH(spec, s, p->specs) { + good = path_spec_check_good(s, initial); + + if (good) + break; + } + + return good; +} + +static void path_enter_waiting(Path *p, bool initial, bool recheck) { + int r; + + if (recheck) + if (path_check_good(p, initial)) { + log_debug("%s got triggered.", UNIT(p)->id); + path_enter_running(p); + return; + } + + if ((r = path_watch(p)) < 0) + goto fail; + + /* Hmm, so now we have created inotify watches, but the file + * might have appeared/been removed by now, so we must + * recheck */ + + if (recheck) + if (path_check_good(p, false)) { + log_debug("%s got triggered.", UNIT(p)->id); + path_enter_running(p); + return; + } + + path_set_state(p, PATH_WAITING); + return; + +fail: + log_warning("%s failed to enter waiting state: %s", UNIT(p)->id, strerror(-r)); + path_enter_dead(p, PATH_FAILURE_RESOURCES); +} + +static void path_mkdir(Path *p) { + PathSpec *s; + + assert(p); + + if (!p->make_directory) + return; + + LIST_FOREACH(spec, s, p->specs) + path_spec_mkdir(s, p->directory_mode); +} + +static int path_start(Unit *u) { + Path *p = PATH(u); + + assert(p); + assert(p->state == PATH_DEAD || p->state == PATH_FAILED); + + if (UNIT_DEREF(p->unit)->load_state != UNIT_LOADED) + return -ENOENT; + + path_mkdir(p); + + p->result = PATH_SUCCESS; + path_enter_waiting(p, true, true); + + return 0; +} + +static int path_stop(Unit *u) { + Path *p = PATH(u); + + assert(p); + assert(p->state == PATH_WAITING || p->state == PATH_RUNNING); + + path_enter_dead(p, PATH_SUCCESS); + return 0; +} + +static int path_serialize(Unit *u, FILE *f, FDSet *fds) { + Path *p = PATH(u); + + assert(u); + assert(f); + assert(fds); + + unit_serialize_item(u, f, "state", path_state_to_string(p->state)); + unit_serialize_item(u, f, "result", path_result_to_string(p->result)); + + return 0; +} + +static int path_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) { + Path *p = PATH(u); + + assert(u); + assert(key); + assert(value); + assert(fds); + + if (streq(key, "state")) { + PathState state; + + if ((state = path_state_from_string(value)) < 0) + log_debug("Failed to parse state value %s", value); + else + p->deserialized_state = state; + + } else if (streq(key, "result")) { + PathResult f; + + f = path_result_from_string(value); + if (f < 0) + log_debug("Failed to parse result value %s", value); + else if (f != PATH_SUCCESS) + p->result = f; + + } else + log_debug("Unknown serialization key '%s'", key); + + return 0; +} + +static UnitActiveState path_active_state(Unit *u) { + assert(u); + + return state_translation_table[PATH(u)->state]; +} + +static const char *path_sub_state_to_string(Unit *u) { + assert(u); + + return path_state_to_string(PATH(u)->state); +} + +static void path_fd_event(Unit *u, int fd, uint32_t events, Watch *w) { + Path *p = PATH(u); + PathSpec *s; + int changed; + + assert(p); + assert(fd >= 0); + + if (p->state != PATH_WAITING && + p->state != PATH_RUNNING) + return; + + /* log_debug("inotify wakeup on %s.", u->id); */ + + LIST_FOREACH(spec, s, p->specs) + if (path_spec_owns_inotify_fd(s, fd)) + break; + + if (!s) { + log_error("Got event on unknown fd."); + goto fail; + } + + changed = path_spec_fd_event(s, events); + if (changed < 0) + goto fail; + + /* If we are already running, then remember that one event was + * dispatched so that we restart the service only if something + * actually changed on disk */ + p->inotify_triggered = true; + + if (changed) + path_enter_running(p); + else + path_enter_waiting(p, false, true); + + return; + +fail: + path_enter_dead(p, PATH_FAILURE_RESOURCES); +} + +void path_unit_notify(Unit *u, UnitActiveState new_state) { + Iterator i; + Unit *k; + + if (u->type == UNIT_PATH) + return; + + SET_FOREACH(k, u->dependencies[UNIT_TRIGGERED_BY], i) { + Path *p; + + if (k->type != UNIT_PATH) + continue; + + if (k->load_state != UNIT_LOADED) + continue; + + p = PATH(k); + + if (p->state == PATH_RUNNING && new_state == UNIT_INACTIVE) { + log_debug("%s got notified about unit deactivation.", UNIT(p)->id); + + /* Hmm, so inotify was triggered since the + * last activation, so I guess we need to + * recheck what is going on. */ + path_enter_waiting(p, false, p->inotify_triggered); + } + } +} + +static void path_reset_failed(Unit *u) { + Path *p = PATH(u); + + assert(p); + + if (p->state == PATH_FAILED) + path_set_state(p, PATH_DEAD); + + p->result = PATH_SUCCESS; +} + +static const char* const path_state_table[_PATH_STATE_MAX] = { + [PATH_DEAD] = "dead", + [PATH_WAITING] = "waiting", + [PATH_RUNNING] = "running", + [PATH_FAILED] = "failed" +}; + +DEFINE_STRING_TABLE_LOOKUP(path_state, PathState); + +static const char* const path_type_table[_PATH_TYPE_MAX] = { + [PATH_EXISTS] = "PathExists", + [PATH_EXISTS_GLOB] = "PathExistsGlob", + [PATH_CHANGED] = "PathChanged", + [PATH_MODIFIED] = "PathModified", + [PATH_DIRECTORY_NOT_EMPTY] = "DirectoryNotEmpty" +}; + +DEFINE_STRING_TABLE_LOOKUP(path_type, PathType); + +static const char* const path_result_table[_PATH_RESULT_MAX] = { + [PATH_SUCCESS] = "success", + [PATH_FAILURE_RESOURCES] = "resources" +}; + +DEFINE_STRING_TABLE_LOOKUP(path_result, PathResult); + +const UnitVTable path_vtable = { + .object_size = sizeof(Path), + .sections = + "Unit\0" + "Path\0" + "Install\0", + + .init = path_init, + .done = path_done, + .load = path_load, + + .coldplug = path_coldplug, + + .dump = path_dump, + + .start = path_start, + .stop = path_stop, + + .serialize = path_serialize, + .deserialize_item = path_deserialize_item, + + .active_state = path_active_state, + .sub_state_to_string = path_sub_state_to_string, + + .fd_event = path_fd_event, + + .reset_failed = path_reset_failed, + + .bus_interface = "org.freedesktop.systemd1.Path", + .bus_message_handler = bus_path_message_handler, + .bus_invalidating_properties = bus_path_invalidating_properties +}; diff --git a/src/core/path.h b/src/core/path.h new file mode 100644 index 000000000..77926888a --- /dev/null +++ b/src/core/path.h @@ -0,0 +1,110 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +typedef struct Path Path; + +#include "unit.h" +#include "mount.h" + +typedef enum PathState { + PATH_DEAD, + PATH_WAITING, + PATH_RUNNING, + PATH_FAILED, + _PATH_STATE_MAX, + _PATH_STATE_INVALID = -1 +} PathState; + +typedef enum PathType { + PATH_EXISTS, + PATH_EXISTS_GLOB, + PATH_DIRECTORY_NOT_EMPTY, + PATH_CHANGED, + PATH_MODIFIED, + _PATH_TYPE_MAX, + _PATH_TYPE_INVALID = -1 +} PathType; + +typedef struct PathSpec { + char *path; + + Watch watch; + + LIST_FIELDS(struct PathSpec, spec); + + PathType type; + int inotify_fd; + int primary_wd; + + bool previous_exists; +} PathSpec; + +int path_spec_watch(PathSpec *s, Unit *u); +void path_spec_unwatch(PathSpec *s, Unit *u); +int path_spec_fd_event(PathSpec *s, uint32_t events); +void path_spec_done(PathSpec *s); + +static inline bool path_spec_owns_inotify_fd(PathSpec *s, int fd) { + return s->inotify_fd == fd; +} + +typedef enum PathResult { + PATH_SUCCESS, + PATH_FAILURE_RESOURCES, + _PATH_RESULT_MAX, + _PATH_RESULT_INVALID = -1 +} PathResult; + +struct Path { + Unit meta; + + LIST_HEAD(PathSpec, specs); + + UnitRef unit; + + PathState state, deserialized_state; + + bool inotify_triggered; + + bool make_directory; + mode_t directory_mode; + + PathResult result; +}; + +void path_unit_notify(Unit *u, UnitActiveState new_state); + +/* Called from the mount code figure out if a mount is a dependency of + * any of the paths of this path object */ +int path_add_one_mount_link(Path *p, Mount *m); + +extern const UnitVTable path_vtable; + +const char* path_state_to_string(PathState i); +PathState path_state_from_string(const char *s); + +const char* path_type_to_string(PathType i); +PathType path_type_from_string(const char *s); + +const char* path_result_to_string(PathResult i); +PathResult path_result_from_string(const char *s); diff --git a/src/core/securebits.h b/src/core/securebits.h new file mode 100644 index 000000000..ba0bba535 --- /dev/null +++ b/src/core/securebits.h @@ -0,0 +1,45 @@ +#ifndef _LINUX_SECUREBITS_H +#define _LINUX_SECUREBITS_H 1 + +/* This is minimal version of Linux' linux/securebits.h header file, + * which is licensed GPL2 */ + +#define SECUREBITS_DEFAULT 0x00000000 + +/* When set UID 0 has no special privileges. When unset, we support + inheritance of root-permissions and suid-root executable under + compatibility mode. We raise the effective and inheritable bitmasks + *of the executable file* if the effective uid of the new process is + 0. If the real uid is 0, we raise the effective (legacy) bit of the + executable file. */ +#define SECURE_NOROOT 0 +#define SECURE_NOROOT_LOCKED 1 /* make bit-0 immutable */ + +/* When set, setuid to/from uid 0 does not trigger capability-"fixup". + When unset, to provide compatibility with old programs relying on + set*uid to gain/lose privilege, transitions to/from uid 0 cause + capabilities to be gained/lost. */ +#define SECURE_NO_SETUID_FIXUP 2 +#define SECURE_NO_SETUID_FIXUP_LOCKED 3 /* make bit-2 immutable */ + +/* When set, a process can retain its capabilities even after + transitioning to a non-root user (the set-uid fixup suppressed by + bit 2). Bit-4 is cleared when a process calls exec(); setting both + bit 4 and 5 will create a barrier through exec that no exec()'d + child can use this feature again. */ +#define SECURE_KEEP_CAPS 4 +#define SECURE_KEEP_CAPS_LOCKED 5 /* make bit-4 immutable */ + +/* Each securesetting is implemented using two bits. One bit specifies + whether the setting is on or off. The other bit specify whether the + setting is locked or not. A setting which is locked cannot be + changed from user-level. */ +#define issecure_mask(X) (1 << (X)) +#define issecure(X) (issecure_mask(X) & current_cred_xxx(securebits)) + +#define SECURE_ALL_BITS (issecure_mask(SECURE_NOROOT) | \ + issecure_mask(SECURE_NO_SETUID_FIXUP) | \ + issecure_mask(SECURE_KEEP_CAPS)) +#define SECURE_ALL_LOCKS (SECURE_ALL_BITS << 1) + +#endif /* !_LINUX_SECUREBITS_H */ diff --git a/src/core/selinux-access.c b/src/core/selinux-access.c new file mode 100644 index 000000000..6dfe8b45f --- /dev/null +++ b/src/core/selinux-access.c @@ -0,0 +1,441 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2012 Dan Walsh + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include "selinux-access.h" + +#ifdef HAVE_SELINUX + +#include +#include +#include +#include +#include +#include +#ifdef HAVE_AUDIT +#include +#endif +#include + +#include "util.h" +#include "log.h" +#include "bus-errors.h" +#include "dbus-common.h" +#include "audit.h" +#include "selinux-util.h" +#include "audit-fd.h" + +static bool initialized = false; + +struct auditstruct { + const char *path; + char *cmdline; + uid_t loginuid; + uid_t uid; + gid_t gid; +}; + +static int bus_get_selinux_security_context( + DBusConnection *connection, + const char *name, + char **scon, + DBusError *error) { + + _cleanup_dbus_message_unref_ DBusMessage *m = NULL, *reply = NULL; + DBusMessageIter iter, sub; + const char *bytes; + char *b; + int nbytes; + + m = dbus_message_new_method_call( + DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS, + "GetConnectionSELinuxSecurityContext"); + if (!m) { + dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, NULL); + return -ENOMEM; + } + + if (!dbus_message_append_args( + m, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_INVALID)) { + dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, NULL); + return -ENOMEM; + } + + reply = dbus_connection_send_with_reply_and_block(connection, m, -1, error); + if (!reply) + return -EIO; + + if (dbus_set_error_from_message(error, reply)) + return -EIO; + + if (!dbus_message_iter_init(reply, &iter)) + return -EIO; + + if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) + return -EIO; + + dbus_message_iter_recurse(&iter, &sub); + dbus_message_iter_get_fixed_array(&sub, &bytes, &nbytes); + + b = strndup(bytes, nbytes); + if (!b) + return -ENOMEM; + + *scon = b; + + log_debug("GetConnectionSELinuxSecurityContext %s (pid %ld)", *scon, (long) bus_get_unix_process_id(connection, name, error)); + + return 0; +} + +static int bus_get_audit_data( + DBusConnection *connection, + const char *name, + struct auditstruct *audit, + DBusError *error) { + + pid_t pid; + int r; + + pid = bus_get_unix_process_id(connection, name, error); + if (pid <= 0) + return -EIO; + + r = audit_loginuid_from_pid(pid, &audit->loginuid); + if (r < 0) + return r; + + r = get_process_uid(pid, &audit->uid); + if (r < 0) + return r; + + r = get_process_gid(pid, &audit->gid); + if (r < 0) + return r; + + r = get_process_cmdline(pid, LINE_MAX, true, &audit->cmdline); + if (r < 0) + return r; + + return 0; +} + +/* + Any time an access gets denied this callback will be called + with the aduit data. We then need to just copy the audit data into the msgbuf. +*/ +static int audit_callback( + void *auditdata, + security_class_t cls, + char *msgbuf, + size_t msgbufsize) { + + struct auditstruct *audit = (struct auditstruct *) auditdata; + + snprintf(msgbuf, msgbufsize, + "auid=%d uid=%d gid=%d%s%s%s%s%s%s", + audit->loginuid, + audit->uid, + audit->gid, + (audit->path ? " path=\"" : ""), + strempty(audit->path), + (audit->path ? "\"" : ""), + (audit->cmdline ? " cmdline=\"" : ""), + strempty(audit->cmdline), + (audit->cmdline ? "\"" : "")); + + msgbuf[msgbufsize-1] = 0; + + return 0; +} + +/* + Any time an access gets denied this callback will be called + code copied from dbus. If audit is turned on the messages will go as + user_avc's into the /var/log/audit/audit.log, otherwise they will be + sent to syslog. +*/ +static int log_callback(int type, const char *fmt, ...) { + va_list ap; + + va_start(ap, fmt); + +#ifdef HAVE_AUDIT + if (get_audit_fd() >= 0) { + char buf[LINE_MAX]; + + vsnprintf(buf, sizeof(buf), fmt, ap); + audit_log_user_avc_message(get_audit_fd(), AUDIT_USER_AVC, buf, NULL, NULL, NULL, 0); + va_end(ap); + + return 0; + } +#endif + log_metav(LOG_USER | LOG_INFO, __FILE__, __LINE__, __FUNCTION__, fmt, ap); + va_end(ap); + + return 0; +} + +/* + Function must be called once to initialize the SELinux AVC environment. + Sets up callbacks. + If you want to cleanup memory you should need to call selinux_access_finish. +*/ +static int access_init(void) { + int r; + + if (avc_open(NULL, 0)) { + log_error("avc_open() failed: %m"); + return -errno; + } + + selinux_set_callback(SELINUX_CB_AUDIT, (union selinux_callback) audit_callback); + selinux_set_callback(SELINUX_CB_LOG, (union selinux_callback) log_callback); + + if (security_getenforce() >= 0) + return 0; + + r = -errno; + avc_destroy(); + + return r; +} + +static int selinux_access_init(DBusError *error) { + int r; + + if (initialized) + return 0; + + if (use_selinux()) { + r = access_init(); + if (r < 0) { + dbus_set_error(error, DBUS_ERROR_ACCESS_DENIED, "Failed to initialize SELinux."); + return r; + } + } + + initialized = true; + return 0; +} + +void selinux_access_free(void) { + if (!initialized) + return; + + avc_destroy(); + initialized = false; +} + +static int get_audit_data( + DBusConnection *connection, + DBusMessage *message, + struct auditstruct *audit, + DBusError *error) { + + const char *sender; + int r, fd; + struct ucred ucred; + socklen_t len; + + sender = dbus_message_get_sender(message); + if (sender) + return bus_get_audit_data(connection, sender, audit, error); + + if (!dbus_connection_get_unix_fd(connection, &fd)) + return -EINVAL; + + r = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &ucred, &len); + if (r < 0) { + log_error("Failed to determine peer credentials: %m"); + return -errno; + } + + audit->uid = ucred.uid; + audit->gid = ucred.gid; + + r = audit_loginuid_from_pid(ucred.pid, &audit->loginuid); + if (r < 0) + return r; + + r = get_process_cmdline(ucred.pid, LINE_MAX, true, &audit->cmdline); + if (r < 0) + return r; + + return 0; +} + +/* + This function returns the security context of the remote end of the dbus + connections. Whether it is on the bus or a local connection. +*/ +static int get_calling_context( + DBusConnection *connection, + DBusMessage *message, + security_context_t *scon, + DBusError *error) { + + const char *sender; + int r; + int fd; + + /* + If sender exists then + if sender is NULL this indicates a local connection. Grab the fd + from dbus and do an getpeercon to peers process context + */ + sender = dbus_message_get_sender(message); + if (sender) { + log_error("SELinux Got Sender %s", sender); + + r = bus_get_selinux_security_context(connection, sender, scon, error); + if (r >= 0) + return r; + + log_error("bus_get_selinux_security_context failed: %m"); + return r; + } + + log_debug("SELinux No Sender"); + if (!dbus_connection_get_unix_fd(connection, &fd)) { + log_error("bus_connection_get_unix_fd failed %m"); + return -EINVAL; + } + + r = getpeercon(fd, scon); + if (r < 0) { + log_error("getpeercon failed %m"); + return -errno; + } + + return 0; +} + +/* + This function communicates with the kernel to check whether or not it should + allow the access. + If the machine is in permissive mode it will return ok. Audit messages will + still be generated if the access would be denied in enforcing mode. +*/ +int selinux_access_check( + DBusConnection *connection, + DBusMessage *message, + const char *path, + const char *permission, + DBusError *error) { + + security_context_t scon = NULL, fcon = NULL; + int r = 0; + const char *tclass = NULL; + struct auditstruct audit; + + assert(connection); + assert(message); + assert(permission); + assert(error); + + if (!use_selinux()) + return 0; + + r = selinux_access_init(error); + if (r < 0) + return r; + + log_debug("SELinux access check for path=%s permission=%s", strna(path), permission); + + audit.uid = audit.loginuid = (uid_t) -1; + audit.gid = (gid_t) -1; + audit.cmdline = NULL; + audit.path = path; + + r = get_calling_context(connection, message, &scon, error); + if (r < 0) { + log_error("Failed to get caller's security context on: %m"); + goto finish; + } + + if (path) { + tclass = "service"; + /* get the file context of the unit file */ + r = getfilecon(path, &fcon); + if (r < 0) { + dbus_set_error(error, DBUS_ERROR_ACCESS_DENIED, "Failed to get file context on %s.", path); + r = -errno; + log_error("Failed to get security context on %s: %m",path); + goto finish; + } + + } else { + tclass = "system"; + r = getcon(&fcon); + if (r < 0) { + dbus_set_error(error, DBUS_ERROR_ACCESS_DENIED, "Failed to get current context."); + r = -errno; + log_error("Failed to get current process context on: %m"); + goto finish; + } + } + + (void) get_audit_data(connection, message, &audit, error); + + errno = 0; + r = selinux_check_access(scon, fcon, tclass, permission, &audit); + if (r < 0) { + dbus_set_error(error, DBUS_ERROR_ACCESS_DENIED, "SELinux policy denies access."); + r = -errno; + log_error("SELinux policy denies access."); + } + + log_debug("SELinux access check scon=%s tcon=%s tclass=%s perm=%s path=%s cmdline=%s: %i", scon, fcon, tclass, permission, path, audit.cmdline, r); + +finish: + free(audit.cmdline); + freecon(scon); + freecon(fcon); + + if (r && security_getenforce() != 1) { + dbus_error_init(error); + r = 0; + } + + return r; +} + +#else + +int selinux_access_check( + DBusConnection *connection, + DBusMessage *message, + const char *path, + const char *permission, + DBusError *error) { + + return 0; +} + +void selinux_access_free(void) { +} + +#endif diff --git a/src/core/selinux-access.h b/src/core/selinux-access.h new file mode 100644 index 000000000..9183cbc9a --- /dev/null +++ b/src/core/selinux-access.h @@ -0,0 +1,62 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2012 Dan Walsh + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include + +void selinux_access_free(void); + +int selinux_access_check(DBusConnection *connection, DBusMessage *message, const char *path, const char *permission, DBusError *error); + +#ifdef HAVE_SELINUX + +#define SELINUX_ACCESS_CHECK(connection, message, permission) \ + do { \ + DBusError _error; \ + int _r; \ + DBusConnection *_c = (connection); \ + DBusMessage *_m = (message); \ + dbus_error_init(&_error); \ + _r = selinux_access_check(_c, _m, NULL, (permission), &_error); \ + if (_r < 0) \ + return bus_send_error_reply(_c, _m, &_error, _r); \ + } while (false) + +#define SELINUX_UNIT_ACCESS_CHECK(unit, connection, message, permission) \ + do { \ + DBusError _error; \ + int _r; \ + DBusConnection *_c = (connection); \ + DBusMessage *_m = (message); \ + Unit *_u = (unit); \ + dbus_error_init(&_error); \ + _r = selinux_access_check(_c, _m, _u->source_path ?: _u->fragment_path, (permission), &_error); \ + if (_r < 0) \ + return bus_send_error_reply(_c, _m, &_error, _r); \ + } while (false) + +#else + +#define SELINUX_ACCESS_CHECK(connection, message, permission) do { } while (false) +#define SELINUX_UNIT_ACCESS_CHECK(unit, connection, message, permission) do { } while (false) + +#endif diff --git a/src/core/selinux-setup.c b/src/core/selinux-setup.c new file mode 100644 index 000000000..e9c0de92f --- /dev/null +++ b/src/core/selinux-setup.c @@ -0,0 +1,123 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include +#include + +#ifdef HAVE_SELINUX +#include +#endif + +#include "selinux-setup.h" +#include "selinux-util.h" +#include "label.h" +#include "mount-setup.h" +#include "macro.h" +#include "util.h" +#include "log.h" + +#ifdef HAVE_SELINUX +static int null_log(int type, const char *fmt, ...) { + return 0; +} +#endif + +int selinux_setup(bool *loaded_policy) { + +#ifdef HAVE_SELINUX + int enforce = 0; + usec_t before_load, after_load; + security_context_t con; + int r; + union selinux_callback cb; + + assert(loaded_policy); + + /* Turn off all of SELinux' own logging, we want to do that */ + cb.func_log = null_log; + selinux_set_callback(SELINUX_CB_LOG, cb); + + /* Make sure getcon() works, which needs /proc and /sys */ + mount_setup_early(); + + /* Already initialized by somebody else? */ + r = getcon_raw(&con); + if (r == 0) { + bool initialized; + + initialized = !streq(con, "kernel"); + freecon(con); + + if (initialized) + return 0; + } + + /* Make sure we have no fds open while loading the policy and + * transitioning */ + log_close(); + + /* Now load the policy */ + before_load = now(CLOCK_MONOTONIC); + r = selinux_init_load_policy(&enforce); + if (r == 0) { + char timespan[FORMAT_TIMESPAN_MAX]; + char *label; + + retest_selinux(); + + /* Transition to the new context */ + r = label_get_create_label_from_exe(SYSTEMD_BINARY_PATH, &label); + if (r < 0 || label == NULL) { + log_open(); + log_error("Failed to compute init label, ignoring."); + } else { + r = setcon(label); + + log_open(); + if (r < 0) + log_error("Failed to transition into init label '%s', ignoring.", label); + + label_free(label); + } + + after_load = now(CLOCK_MONOTONIC); + + log_info("Successfully loaded SELinux policy in %s.", + format_timespan(timespan, sizeof(timespan), after_load - before_load)); + + *loaded_policy = true; + + } else { + log_open(); + + if (enforce > 0) { + log_error("Failed to load SELinux policy. Freezing."); + return -EIO; + } else + log_debug("Unable to load SELinux policy. Ignoring."); + } +#endif + + return 0; +} diff --git a/src/core/selinux-setup.h b/src/core/selinux-setup.h new file mode 100644 index 000000000..39e2bc25b --- /dev/null +++ b/src/core/selinux-setup.h @@ -0,0 +1,26 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +#include + +int selinux_setup(bool *loaded_policy); diff --git a/src/core/service.c b/src/core/service.c new file mode 100644 index 000000000..2a4e691e7 --- /dev/null +++ b/src/core/service.c @@ -0,0 +1,3901 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include +#include + +#include "manager.h" +#include "unit.h" +#include "service.h" +#include "load-fragment.h" +#include "load-dropin.h" +#include "log.h" +#include "strv.h" +#include "unit-name.h" +#include "unit-printf.h" +#include "dbus-service.h" +#include "special.h" +#include "bus-errors.h" +#include "exit-status.h" +#include "def.h" +#include "path-util.h" +#include "util.h" +#include "utf8.h" + +#ifdef HAVE_SYSV_COMPAT + +#define DEFAULT_SYSV_TIMEOUT_USEC (5*USEC_PER_MINUTE) + +typedef enum RunlevelType { + RUNLEVEL_UP, + RUNLEVEL_DOWN +} RunlevelType; + +static const struct { + const char *path; + const char *target; + const RunlevelType type; +} rcnd_table[] = { + /* Standard SysV runlevels for start-up */ + { "rc1.d", SPECIAL_RESCUE_TARGET, RUNLEVEL_UP }, + { "rc2.d", SPECIAL_RUNLEVEL2_TARGET, RUNLEVEL_UP }, + { "rc3.d", SPECIAL_RUNLEVEL3_TARGET, RUNLEVEL_UP }, + { "rc4.d", SPECIAL_RUNLEVEL4_TARGET, RUNLEVEL_UP }, + { "rc5.d", SPECIAL_RUNLEVEL5_TARGET, RUNLEVEL_UP }, + + /* Standard SysV runlevels for shutdown */ + { "rc0.d", SPECIAL_POWEROFF_TARGET, RUNLEVEL_DOWN }, + { "rc6.d", SPECIAL_REBOOT_TARGET, RUNLEVEL_DOWN } + + /* Note that the order here matters, as we read the + directories in this order, and we want to make sure that + sysv_start_priority is known when we first load the + unit. And that value we only know from S links. Hence + UP must be read before DOWN */ +}; + +#define RUNLEVELS_UP "12345" +#endif + +static const UnitActiveState state_translation_table[_SERVICE_STATE_MAX] = { + [SERVICE_DEAD] = UNIT_INACTIVE, + [SERVICE_START_PRE] = UNIT_ACTIVATING, + [SERVICE_START] = UNIT_ACTIVATING, + [SERVICE_START_POST] = UNIT_ACTIVATING, + [SERVICE_RUNNING] = UNIT_ACTIVE, + [SERVICE_EXITED] = UNIT_ACTIVE, + [SERVICE_RELOAD] = UNIT_RELOADING, + [SERVICE_STOP] = UNIT_DEACTIVATING, + [SERVICE_STOP_SIGTERM] = UNIT_DEACTIVATING, + [SERVICE_STOP_SIGKILL] = UNIT_DEACTIVATING, + [SERVICE_STOP_POST] = UNIT_DEACTIVATING, + [SERVICE_FINAL_SIGTERM] = UNIT_DEACTIVATING, + [SERVICE_FINAL_SIGKILL] = UNIT_DEACTIVATING, + [SERVICE_FAILED] = UNIT_FAILED, + [SERVICE_AUTO_RESTART] = UNIT_ACTIVATING +}; + +/* For Type=idle we never want to delay any other jobs, hence we + * consider idle jobs active as soon as we start working on them */ +static const UnitActiveState state_translation_table_idle[_SERVICE_STATE_MAX] = { + [SERVICE_DEAD] = UNIT_INACTIVE, + [SERVICE_START_PRE] = UNIT_ACTIVE, + [SERVICE_START] = UNIT_ACTIVE, + [SERVICE_START_POST] = UNIT_ACTIVE, + [SERVICE_RUNNING] = UNIT_ACTIVE, + [SERVICE_EXITED] = UNIT_ACTIVE, + [SERVICE_RELOAD] = UNIT_RELOADING, + [SERVICE_STOP] = UNIT_DEACTIVATING, + [SERVICE_STOP_SIGTERM] = UNIT_DEACTIVATING, + [SERVICE_STOP_SIGKILL] = UNIT_DEACTIVATING, + [SERVICE_STOP_POST] = UNIT_DEACTIVATING, + [SERVICE_FINAL_SIGTERM] = UNIT_DEACTIVATING, + [SERVICE_FINAL_SIGKILL] = UNIT_DEACTIVATING, + [SERVICE_FAILED] = UNIT_FAILED, + [SERVICE_AUTO_RESTART] = UNIT_ACTIVATING +}; + +static void service_init(Unit *u) { + Service *s = SERVICE(u); + + assert(u); + assert(u->load_state == UNIT_STUB); + + s->timeout_start_usec = DEFAULT_TIMEOUT_USEC; + s->timeout_stop_usec = DEFAULT_TIMEOUT_USEC; + s->restart_usec = DEFAULT_RESTART_USEC; + s->type = _SERVICE_TYPE_INVALID; + + watch_init(&s->watchdog_watch); + watch_init(&s->timer_watch); + +#ifdef HAVE_SYSV_COMPAT + s->sysv_start_priority = -1; + s->sysv_start_priority_from_rcnd = -1; +#endif + s->socket_fd = -1; + s->guess_main_pid = true; + + exec_context_init(&s->exec_context); + kill_context_init(&s->kill_context); + + RATELIMIT_INIT(s->start_limit, 10*USEC_PER_SEC, 5); + + s->control_command_id = _SERVICE_EXEC_COMMAND_INVALID; +} + +static void service_unwatch_control_pid(Service *s) { + assert(s); + + if (s->control_pid <= 0) + return; + + unit_unwatch_pid(UNIT(s), s->control_pid); + s->control_pid = 0; +} + +static void service_unwatch_main_pid(Service *s) { + assert(s); + + if (s->main_pid <= 0) + return; + + unit_unwatch_pid(UNIT(s), s->main_pid); + s->main_pid = 0; +} + +static void service_unwatch_pid_file(Service *s) { + if (!s->pid_file_pathspec) + return; + + log_debug_unit(UNIT(s)->id, "Stopping watch for %s's PID file %s", + UNIT(s)->id, s->pid_file_pathspec->path); + path_spec_unwatch(s->pid_file_pathspec, UNIT(s)); + path_spec_done(s->pid_file_pathspec); + free(s->pid_file_pathspec); + s->pid_file_pathspec = NULL; +} + +static int service_set_main_pid(Service *s, pid_t pid) { + pid_t ppid; + + assert(s); + + if (pid <= 1) + return -EINVAL; + + if (pid == getpid()) + return -EINVAL; + + s->main_pid = pid; + s->main_pid_known = true; + + if (get_parent_of_pid(pid, &ppid) >= 0 && ppid != getpid()) { + log_warning_unit(UNIT(s)->id, + "%s: Supervising process %lu which is not our child. We'll most likely not notice when it exits.", + UNIT(s)->id, (unsigned long) pid); + + s->main_pid_alien = true; + } else + s->main_pid_alien = false; + + exec_status_start(&s->main_exec_status, pid); + + return 0; +} + +static void service_close_socket_fd(Service *s) { + assert(s); + + if (s->socket_fd < 0) + return; + + close_nointr_nofail(s->socket_fd); + s->socket_fd = -1; +} + +static void service_connection_unref(Service *s) { + assert(s); + + if (!UNIT_DEREF(s->accept_socket)) + return; + + socket_connection_unref(SOCKET(UNIT_DEREF(s->accept_socket))); + unit_ref_unset(&s->accept_socket); +} + +static void service_stop_watchdog(Service *s) { + assert(s); + + unit_unwatch_timer(UNIT(s), &s->watchdog_watch); + s->watchdog_timestamp.realtime = 0; + s->watchdog_timestamp.monotonic = 0; +} + +static void service_enter_dead(Service *s, ServiceResult f, bool allow_restart); + +static void service_handle_watchdog(Service *s) { + usec_t offset; + int r; + + assert(s); + + if (s->watchdog_usec == 0) + return; + + offset = now(CLOCK_MONOTONIC) - s->watchdog_timestamp.monotonic; + if (offset >= s->watchdog_usec) { + log_error_unit(UNIT(s)->id, "%s watchdog timeout!", UNIT(s)->id); + service_enter_dead(s, SERVICE_FAILURE_WATCHDOG, true); + return; + } + + r = unit_watch_timer(UNIT(s), CLOCK_MONOTONIC, true, s->watchdog_usec - offset, &s->watchdog_watch); + if (r < 0) + log_warning_unit(UNIT(s)->id, + "%s failed to install watchdog timer: %s", + UNIT(s)->id, strerror(-r)); +} + +static void service_reset_watchdog(Service *s) { + assert(s); + + dual_timestamp_get(&s->watchdog_timestamp); + service_handle_watchdog(s); +} + +static void service_done(Unit *u) { + Service *s = SERVICE(u); + + assert(s); + + free(s->pid_file); + s->pid_file = NULL; + +#ifdef HAVE_SYSV_COMPAT + free(s->sysv_runlevels); + s->sysv_runlevels = NULL; +#endif + + free(s->status_text); + s->status_text = NULL; + + exec_context_done(&s->exec_context); + exec_command_free_array(s->exec_command, _SERVICE_EXEC_COMMAND_MAX); + s->control_command = NULL; + s->main_command = NULL; + + set_free(s->restart_ignore_status.code); + s->restart_ignore_status.code = NULL; + set_free(s->restart_ignore_status.signal); + s->restart_ignore_status.signal = NULL; + + set_free(s->success_status.code); + s->success_status.code = NULL; + set_free(s->success_status.signal); + s->success_status.signal = NULL; + + /* This will leak a process, but at least no memory or any of + * our resources */ + service_unwatch_main_pid(s); + service_unwatch_control_pid(s); + service_unwatch_pid_file(s); + + if (s->bus_name) { + unit_unwatch_bus_name(u, s->bus_name); + free(s->bus_name); + s->bus_name = NULL; + } + + service_close_socket_fd(s); + service_connection_unref(s); + + unit_ref_unset(&s->accept_socket); + + service_stop_watchdog(s); + + unit_unwatch_timer(u, &s->timer_watch); +} + +#ifdef HAVE_SYSV_COMPAT +static char *sysv_translate_name(const char *name) { + char *r; + + if (!(r = new(char, strlen(name) + sizeof(".service")))) + return NULL; + + if (endswith(name, ".sh")) + /* Drop Debian-style .sh suffix */ + strcpy(stpcpy(r, name) - 3, ".service"); + if (startswith(name, "rc.")) + /* Drop Frugalware-style rc. prefix */ + strcpy(stpcpy(r, name + 3), ".service"); + else + /* Normal init scripts */ + strcpy(stpcpy(r, name), ".service"); + + return r; +} + +static int sysv_translate_facility(const char *name, const char *filename, char **_r) { + + /* We silently ignore the $ prefix here. According to the LSB + * spec it simply indicates whether something is a + * standardized name or a distribution-specific one. Since we + * just follow what already exists and do not introduce new + * uses or names we don't care who introduced a new name. */ + + static const char * const table[] = { + /* LSB defined facilities */ + "local_fs", SPECIAL_LOCAL_FS_TARGET, + /* Due to unfortunate name selection in Mandriva, + * $network is provided by network-up which is ordered + * after network which actually starts interfaces. + * To break the loop, just ignore it */ + "network", SPECIAL_NETWORK_TARGET, + "named", SPECIAL_NSS_LOOKUP_TARGET, + "portmap", SPECIAL_RPCBIND_TARGET, + "remote_fs", SPECIAL_REMOTE_FS_TARGET, + "syslog", SPECIAL_SYSLOG_TARGET, + "time", SPECIAL_TIME_SYNC_TARGET, + + /* common extensions */ + "mail-transfer-agent", SPECIAL_MAIL_TRANSFER_AGENT_TARGET, + "x-display-manager", SPECIAL_DISPLAY_MANAGER_SERVICE, + "null", NULL, + "mail-transport-agent", SPECIAL_MAIL_TRANSFER_AGENT_TARGET, + "smtp", SPECIAL_MAIL_TRANSFER_AGENT_TARGET, + }; + + unsigned i; + char *r; + const char *n; + + assert(name); + assert(_r); + + n = *name == '$' ? name + 1 : name; + + for (i = 0; i < ELEMENTSOF(table); i += 2) { + + if (!streq(table[i], n)) + continue; + + if (!table[i+1]) + return 0; + + if (!(r = strdup(table[i+1]))) + return -ENOMEM; + + goto finish; + } + + /* If we don't know this name, fallback heuristics to figure + * out whether something is a target or a service alias. */ + + if (*name == '$') { + if (!unit_prefix_is_valid(n)) + return -EINVAL; + + /* Facilities starting with $ are most likely targets */ + r = unit_name_build(n, NULL, ".target"); + } else if (filename && streq(name, filename)) + /* Names equaling the file name of the services are redundant */ + return 0; + else + /* Everything else we assume to be normal service names */ + r = sysv_translate_name(n); + + if (!r) + return -ENOMEM; + +finish: + *_r = r; + + return 1; +} + +static int sysv_fix_order(Service *s) { + Unit *other; + int r; + + assert(s); + + if (s->sysv_start_priority < 0) + return 0; + + /* For each pair of services where at least one lacks a LSB + * header, we use the start priority value to order things. */ + + LIST_FOREACH(units_by_type, other, UNIT(s)->manager->units_by_type[UNIT_SERVICE]) { + Service *t; + UnitDependency d; + bool special_s, special_t; + + t = SERVICE(other); + + if (s == t) + continue; + + if (UNIT(t)->load_state != UNIT_LOADED) + continue; + + if (t->sysv_start_priority < 0) + continue; + + /* If both units have modern headers we don't care + * about the priorities */ + if ((UNIT(s)->fragment_path || s->sysv_has_lsb) && + (UNIT(t)->fragment_path || t->sysv_has_lsb)) + continue; + + special_s = s->sysv_runlevels && !chars_intersect(RUNLEVELS_UP, s->sysv_runlevels); + special_t = t->sysv_runlevels && !chars_intersect(RUNLEVELS_UP, t->sysv_runlevels); + + if (special_t && !special_s) + d = UNIT_AFTER; + else if (special_s && !special_t) + d = UNIT_BEFORE; + else if (t->sysv_start_priority < s->sysv_start_priority) + d = UNIT_AFTER; + else if (t->sysv_start_priority > s->sysv_start_priority) + d = UNIT_BEFORE; + else + continue; + + /* FIXME: Maybe we should compare the name here lexicographically? */ + + if ((r = unit_add_dependency(UNIT(s), d, UNIT(t), true)) < 0) + return r; + } + + return 0; +} + +static ExecCommand *exec_command_new(const char *path, const char *arg1) { + ExecCommand *c; + + if (!(c = new0(ExecCommand, 1))) + return NULL; + + if (!(c->path = strdup(path))) { + free(c); + return NULL; + } + + if (!(c->argv = strv_new(path, arg1, NULL))) { + free(c->path); + free(c); + return NULL; + } + + return c; +} + +static int sysv_exec_commands(Service *s, const bool supports_reload) { + ExecCommand *c; + + assert(s); + assert(s->is_sysv); + assert(UNIT(s)->source_path); + + c = exec_command_new(UNIT(s)->source_path, "start"); + if (!c) + return -ENOMEM; + exec_command_append_list(s->exec_command+SERVICE_EXEC_START, c); + + c = exec_command_new(UNIT(s)->source_path, "stop"); + if (!c) + return -ENOMEM; + exec_command_append_list(s->exec_command+SERVICE_EXEC_STOP, c); + + if (supports_reload) { + c = exec_command_new(UNIT(s)->source_path, "reload"); + if (!c) + return -ENOMEM; + exec_command_append_list(s->exec_command+SERVICE_EXEC_RELOAD, c); + } + + return 0; +} + +static bool usage_contains_reload(const char *line) { + return (strcasestr(line, "{reload|") || + strcasestr(line, "{reload}") || + strcasestr(line, "{reload\"") || + strcasestr(line, "|reload|") || + strcasestr(line, "|reload}") || + strcasestr(line, "|reload\"")); +} + +static int service_load_sysv_path(Service *s, const char *path) { + FILE *f; + Unit *u; + unsigned line = 0; + int r; + enum { + NORMAL, + DESCRIPTION, + LSB, + LSB_DESCRIPTION, + USAGE_CONTINUATION + } state = NORMAL; + char *short_description = NULL, *long_description = NULL, *chkconfig_description = NULL, *description; + struct stat st; + bool supports_reload = false; + + assert(s); + assert(path); + + u = UNIT(s); + + f = fopen(path, "re"); + if (!f) { + r = errno == ENOENT ? 0 : -errno; + goto finish; + } + + if (fstat(fileno(f), &st) < 0) { + r = -errno; + goto finish; + } + + free(u->source_path); + u->source_path = strdup(path); + if (!u->source_path) { + r = -ENOMEM; + goto finish; + } + u->source_mtime = timespec_load(&st.st_mtim); + + if (null_or_empty(&st)) { + u->load_state = UNIT_MASKED; + r = 0; + goto finish; + } + + s->is_sysv = true; + + while (!feof(f)) { + char l[LINE_MAX], *t; + + if (!fgets(l, sizeof(l), f)) { + if (feof(f)) + break; + + r = -errno; + log_error_unit(u->id, + "Failed to read configuration file '%s': %s", + path, strerror(-r)); + goto finish; + } + + line++; + + t = strstrip(l); + if (*t != '#') { + /* Try to figure out whether this init script supports + * the reload operation. This heuristic looks for + * "Usage" lines which include the reload option. */ + if ( state == USAGE_CONTINUATION || + (state == NORMAL && strcasestr(t, "usage"))) { + if (usage_contains_reload(t)) { + supports_reload = true; + state = NORMAL; + } else if (t[strlen(t)-1] == '\\') + state = USAGE_CONTINUATION; + else + state = NORMAL; + } + + continue; + } + + if (state == NORMAL && streq(t, "### BEGIN INIT INFO")) { + state = LSB; + s->sysv_has_lsb = true; + continue; + } + + if ((state == LSB_DESCRIPTION || state == LSB) && streq(t, "### END INIT INFO")) { + state = NORMAL; + continue; + } + + t++; + t += strspn(t, WHITESPACE); + + if (state == NORMAL) { + + /* Try to parse Red Hat style chkconfig headers */ + + if (startswith_no_case(t, "chkconfig:")) { + int start_priority; + char runlevels[16], *k; + + state = NORMAL; + + if (sscanf(t+10, "%15s %i %*i", + runlevels, + &start_priority) != 2) { + + log_warning_unit(u->id, + "[%s:%u] Failed to parse chkconfig line. Ignoring.", + path, line); + continue; + } + + /* A start priority gathered from the + * symlink farms is preferred over the + * data from the LSB header. */ + if (start_priority < 0 || start_priority > 99) + log_warning_unit(u->id, + "[%s:%u] Start priority out of range. Ignoring.", + path, line); + else + s->sysv_start_priority = start_priority; + + char_array_0(runlevels); + k = delete_chars(runlevels, WHITESPACE "-"); + + if (k[0]) { + char *d; + + if (!(d = strdup(k))) { + r = -ENOMEM; + goto finish; + } + + free(s->sysv_runlevels); + s->sysv_runlevels = d; + } + + } else if (startswith_no_case(t, "description:")) { + + size_t k = strlen(t); + char *d; + const char *j; + + if (t[k-1] == '\\') { + state = DESCRIPTION; + t[k-1] = 0; + } + + if ((j = strstrip(t+12)) && *j) { + if (!(d = strdup(j))) { + r = -ENOMEM; + goto finish; + } + } else + d = NULL; + + free(chkconfig_description); + chkconfig_description = d; + + } else if (startswith_no_case(t, "pidfile:")) { + + char *fn; + + state = NORMAL; + + fn = strstrip(t+8); + if (!path_is_absolute(fn)) { + log_warning_unit(u->id, + "[%s:%u] PID file not absolute. Ignoring.", + path, line); + continue; + } + + if (!(fn = strdup(fn))) { + r = -ENOMEM; + goto finish; + } + + free(s->pid_file); + s->pid_file = fn; + } + + } else if (state == DESCRIPTION) { + + /* Try to parse Red Hat style description + * continuation */ + + size_t k = strlen(t); + char *j; + + if (t[k-1] == '\\') + t[k-1] = 0; + else + state = NORMAL; + + if ((j = strstrip(t)) && *j) { + char *d = NULL; + + if (chkconfig_description) + d = strjoin(chkconfig_description, " ", j, NULL); + else + d = strdup(j); + + if (!d) { + r = -ENOMEM; + goto finish; + } + + free(chkconfig_description); + chkconfig_description = d; + } + + } else if (state == LSB || state == LSB_DESCRIPTION) { + + if (startswith_no_case(t, "Provides:")) { + char *i, *w; + size_t z; + + state = LSB; + + FOREACH_WORD_QUOTED(w, z, t+9, i) { + char *n, *m; + + if (!(n = strndup(w, z))) { + r = -ENOMEM; + goto finish; + } + + r = sysv_translate_facility(n, path_get_file_name(path), &m); + free(n); + + if (r < 0) + goto finish; + + if (r == 0) + continue; + + if (unit_name_to_type(m) == UNIT_SERVICE) + r = unit_add_name(u, m); + else + /* NB: SysV targets + * which are provided + * by a service are + * pulled in by the + * services, as an + * indication that the + * generic service is + * now available. This + * is strictly + * one-way. The + * targets do NOT pull + * in the SysV + * services! */ + r = unit_add_two_dependencies_by_name(u, UNIT_BEFORE, UNIT_WANTS, m, NULL, true); + + if (r < 0) + log_error_unit(u->id, + "[%s:%u] Failed to add LSB Provides name %s, ignoring: %s", + path, line, m, strerror(-r)); + + free(m); + } + + } else if (startswith_no_case(t, "Required-Start:") || + startswith_no_case(t, "Should-Start:") || + startswith_no_case(t, "X-Start-Before:") || + startswith_no_case(t, "X-Start-After:")) { + char *i, *w; + size_t z; + + state = LSB; + + FOREACH_WORD_QUOTED(w, z, strchr(t, ':')+1, i) { + char *n, *m; + + if (!(n = strndup(w, z))) { + r = -ENOMEM; + goto finish; + } + + r = sysv_translate_facility(n, path_get_file_name(path), &m); + + if (r < 0) { + log_error_unit(u->id, + "[%s:%u] Failed to translate LSB dependency %s, ignoring: %s", + path, line, n, strerror(-r)); + free(n); + continue; + } + + free(n); + + if (r == 0) + continue; + + r = unit_add_dependency_by_name(u, startswith_no_case(t, "X-Start-Before:") ? UNIT_BEFORE : UNIT_AFTER, m, NULL, true); + + if (r < 0) + log_error_unit(u->id, "[%s:%u] Failed to add dependency on %s, ignoring: %s", + path, line, m, strerror(-r)); + + free(m); + } + } else if (startswith_no_case(t, "Default-Start:")) { + char *k, *d; + + state = LSB; + + k = delete_chars(t+14, WHITESPACE "-"); + + if (k[0] != 0) { + if (!(d = strdup(k))) { + r = -ENOMEM; + goto finish; + } + + free(s->sysv_runlevels); + s->sysv_runlevels = d; + } + + } else if (startswith_no_case(t, "Description:")) { + char *d, *j; + + state = LSB_DESCRIPTION; + + if ((j = strstrip(t+12)) && *j) { + if (!(d = strdup(j))) { + r = -ENOMEM; + goto finish; + } + } else + d = NULL; + + free(long_description); + long_description = d; + + } else if (startswith_no_case(t, "Short-Description:")) { + char *d, *j; + + state = LSB; + + if ((j = strstrip(t+18)) && *j) { + if (!(d = strdup(j))) { + r = -ENOMEM; + goto finish; + } + } else + d = NULL; + + free(short_description); + short_description = d; + + } else if (state == LSB_DESCRIPTION) { + + if (startswith(l, "#\t") || startswith(l, "# ")) { + char *j; + + if ((j = strstrip(t)) && *j) { + char *d = NULL; + + if (long_description) + d = strjoin(long_description, " ", t, NULL); + else + d = strdup(j); + + if (!d) { + r = -ENOMEM; + goto finish; + } + + free(long_description); + long_description = d; + } + + } else + state = LSB; + } + } + } + + if ((r = sysv_exec_commands(s, supports_reload)) < 0) + goto finish; + + if (s->sysv_runlevels && !chars_intersect(RUNLEVELS_UP, s->sysv_runlevels)) { + /* If there a runlevels configured for this service + * but none of the standard ones, then we assume this + * is some special kind of service (which might be + * needed for early boot) and don't create any links + * to it. */ + + UNIT(s)->default_dependencies = false; + + /* Don't timeout special services during boot (like fsck) */ + s->timeout_start_usec = 0; + s->timeout_stop_usec = 0; + } else { + s->timeout_start_usec = DEFAULT_SYSV_TIMEOUT_USEC; + s->timeout_stop_usec = DEFAULT_SYSV_TIMEOUT_USEC; + } + + /* Special setting for all SysV services */ + s->type = SERVICE_FORKING; + s->remain_after_exit = !s->pid_file; + s->guess_main_pid = false; + s->restart = SERVICE_RESTART_NO; + s->exec_context.ignore_sigpipe = false; + s->kill_context.kill_mode = KILL_PROCESS; + + /* We use the long description only if + * no short description is set. */ + + if (short_description) + description = short_description; + else if (chkconfig_description) + description = chkconfig_description; + else if (long_description) + description = long_description; + else + description = NULL; + + if (description) { + char *d; + + if (!(d = strappend(s->sysv_has_lsb ? "LSB: " : "SYSV: ", description))) { + r = -ENOMEM; + goto finish; + } + + u->description = d; + } + + /* The priority that has been set in /etc/rcN.d/ hierarchies + * takes precedence over what is stored as default in the LSB + * header */ + if (s->sysv_start_priority_from_rcnd >= 0) + s->sysv_start_priority = s->sysv_start_priority_from_rcnd; + + u->load_state = UNIT_LOADED; + r = 0; + +finish: + + if (f) + fclose(f); + + free(short_description); + free(long_description); + free(chkconfig_description); + + return r; +} + +static int service_load_sysv_name(Service *s, const char *name) { + char **p; + + assert(s); + assert(name); + + /* For SysV services we strip the rc.* and *.sh + * prefixes/suffixes. */ + if (startswith(name, "rc.") || + endswith(name, ".sh.service")) + return -ENOENT; + + STRV_FOREACH(p, UNIT(s)->manager->lookup_paths.sysvinit_path) { + char *path; + int r; + + path = strjoin(*p, "/", name, NULL); + if (!path) + return -ENOMEM; + + assert(endswith(path, ".service")); + path[strlen(path)-8] = 0; + + r = service_load_sysv_path(s, path); + + if (r >= 0 && UNIT(s)->load_state == UNIT_STUB) { + /* Try Debian style *.sh source'able init scripts */ + strcat(path, ".sh"); + r = service_load_sysv_path(s, path); + } + free(path); + + if (r >= 0 && UNIT(s)->load_state == UNIT_STUB) { + /* Try Frugalware style rc.* init scripts */ + + path = strjoin(*p, "/rc.", name, NULL); + if (!path) + return -ENOMEM; + + /* Drop .service suffix */ + path[strlen(path)-8] = 0; + r = service_load_sysv_path(s, path); + free(path); + } + + if (r < 0) + return r; + + if (UNIT(s)->load_state != UNIT_STUB) + break; + } + + return 0; +} + +static int service_load_sysv(Service *s) { + const char *t; + Iterator i; + int r; + + assert(s); + + /* Load service data from SysV init scripts, preferably with + * LSB headers ... */ + + if (strv_isempty(UNIT(s)->manager->lookup_paths.sysvinit_path)) + return 0; + + if ((t = UNIT(s)->id)) + if ((r = service_load_sysv_name(s, t)) < 0) + return r; + + if (UNIT(s)->load_state == UNIT_STUB) + SET_FOREACH(t, UNIT(s)->names, i) { + if (t == UNIT(s)->id) + continue; + + if ((r = service_load_sysv_name(s, t)) < 0) + return r; + + if (UNIT(s)->load_state != UNIT_STUB) + break; + } + + return 0; +} +#endif + +static int fsck_fix_order(Service *s) { + Unit *other; + int r; + + assert(s); + + if (s->fsck_passno <= 0) + return 0; + + /* For each pair of services where both have an fsck priority + * we order things based on it. */ + + LIST_FOREACH(units_by_type, other, UNIT(s)->manager->units_by_type[UNIT_SERVICE]) { + Service *t; + UnitDependency d; + + t = SERVICE(other); + + if (s == t) + continue; + + if (UNIT(t)->load_state != UNIT_LOADED) + continue; + + if (t->fsck_passno <= 0) + continue; + + if (t->fsck_passno < s->fsck_passno) + d = UNIT_AFTER; + else if (t->fsck_passno > s->fsck_passno) + d = UNIT_BEFORE; + else + continue; + + if ((r = unit_add_dependency(UNIT(s), d, UNIT(t), true)) < 0) + return r; + } + + return 0; +} + +static int service_verify(Service *s) { + assert(s); + + if (UNIT(s)->load_state != UNIT_LOADED) + return 0; + + if (!s->exec_command[SERVICE_EXEC_START]) { + log_error_unit(UNIT(s)->id, + "%s lacks ExecStart setting. Refusing.", UNIT(s)->id); + return -EINVAL; + } + + if (s->type != SERVICE_ONESHOT && + s->exec_command[SERVICE_EXEC_START]->command_next) { + log_error_unit(UNIT(s)->id, + "%s has more than one ExecStart setting, which is only allowed for Type=oneshot services. Refusing.", UNIT(s)->id); + return -EINVAL; + } + + if (s->type == SERVICE_DBUS && !s->bus_name) { + log_error_unit(UNIT(s)->id, + "%s is of type D-Bus but no D-Bus service name has been specified. Refusing.", UNIT(s)->id); + return -EINVAL; + } + + if (s->bus_name && s->type != SERVICE_DBUS) + log_warning_unit(UNIT(s)->id, + "%s has a D-Bus service name specified, but is not of type dbus. Ignoring.", UNIT(s)->id); + + if (s->exec_context.pam_name && s->kill_context.kill_mode != KILL_CONTROL_GROUP) { + log_error_unit(UNIT(s)->id, + "%s has PAM enabled. Kill mode must be set to 'control-group'. Refusing.", UNIT(s)->id); + return -EINVAL; + } + + return 0; +} + +static int service_add_default_dependencies(Service *s) { + int r; + + assert(s); + + /* Add a number of automatic dependencies useful for the + * majority of services. */ + + /* First, pull in base system */ + if (UNIT(s)->manager->running_as == SYSTEMD_SYSTEM) { + + if ((r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_BASIC_TARGET, NULL, true)) < 0) + return r; + + } else if (UNIT(s)->manager->running_as == SYSTEMD_USER) { + + if ((r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SOCKETS_TARGET, NULL, true)) < 0) + return r; + } + + /* Second, activate normal shutdown */ + return unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true); +} + +static void service_fix_output(Service *s) { + assert(s); + + /* If nothing has been explicitly configured, patch default + * output in. If input is socket/tty we avoid this however, + * since in that case we want output to default to the same + * place as we read input from. */ + + if (s->exec_context.std_error == EXEC_OUTPUT_INHERIT && + s->exec_context.std_output == EXEC_OUTPUT_INHERIT && + s->exec_context.std_input == EXEC_INPUT_NULL) + s->exec_context.std_error = UNIT(s)->manager->default_std_error; + + if (s->exec_context.std_output == EXEC_OUTPUT_INHERIT && + s->exec_context.std_input == EXEC_INPUT_NULL) + s->exec_context.std_output = UNIT(s)->manager->default_std_output; +} + +static int service_load(Unit *u) { + int r; + Service *s = SERVICE(u); + + assert(s); + + /* Load a .service file */ + if ((r = unit_load_fragment(u)) < 0) + return r; + +#ifdef HAVE_SYSV_COMPAT + /* Load a classic init script as a fallback, if we couldn't find anything */ + if (u->load_state == UNIT_STUB) + if ((r = service_load_sysv(s)) < 0) + return r; +#endif + + /* Still nothing found? Then let's give up */ + if (u->load_state == UNIT_STUB) + return -ENOENT; + + /* We were able to load something, then let's add in the + * dropin directories. */ + if ((r = unit_load_dropin(unit_follow_merge(u))) < 0) + return r; + + /* This is a new unit? Then let's add in some extras */ + if (u->load_state == UNIT_LOADED) { + if (s->type == _SERVICE_TYPE_INVALID) + s->type = s->bus_name ? SERVICE_DBUS : SERVICE_SIMPLE; + + /* Oneshot services have disabled start timeout by default */ + if (s->type == SERVICE_ONESHOT && !s->start_timeout_defined) + s->timeout_start_usec = 0; + + service_fix_output(s); + + if ((r = unit_add_exec_dependencies(u, &s->exec_context)) < 0) + return r; + + if ((r = unit_add_default_cgroups(u)) < 0) + return r; + +#ifdef HAVE_SYSV_COMPAT + if ((r = sysv_fix_order(s)) < 0) + return r; +#endif + + if ((r = fsck_fix_order(s)) < 0) + return r; + + if (s->bus_name) + if ((r = unit_watch_bus_name(u, s->bus_name)) < 0) + return r; + + if (s->type == SERVICE_NOTIFY && s->notify_access == NOTIFY_NONE) + s->notify_access = NOTIFY_MAIN; + + if (s->watchdog_usec > 0 && s->notify_access == NOTIFY_NONE) + s->notify_access = NOTIFY_MAIN; + + if (s->type == SERVICE_DBUS || s->bus_name) + if ((r = unit_add_two_dependencies_by_name(u, UNIT_AFTER, UNIT_REQUIRES, SPECIAL_DBUS_SOCKET, NULL, true)) < 0) + return r; + + if (UNIT(s)->default_dependencies) + if ((r = service_add_default_dependencies(s)) < 0) + return r; + + r = unit_exec_context_defaults(u, &s->exec_context); + if (r < 0) + return r; + } + + return service_verify(s); +} + +static void service_dump(Unit *u, FILE *f, const char *prefix) { + + ServiceExecCommand c; + Service *s = SERVICE(u); + const char *prefix2; + char *p2; + + assert(s); + + p2 = strappend(prefix, "\t"); + prefix2 = p2 ? p2 : prefix; + + fprintf(f, + "%sService State: %s\n" + "%sResult: %s\n" + "%sReload Result: %s\n" + "%sPermissionsStartOnly: %s\n" + "%sRootDirectoryStartOnly: %s\n" + "%sRemainAfterExit: %s\n" + "%sGuessMainPID: %s\n" + "%sType: %s\n" + "%sRestart: %s\n" + "%sNotifyAccess: %s\n", + prefix, service_state_to_string(s->state), + prefix, service_result_to_string(s->result), + prefix, service_result_to_string(s->reload_result), + prefix, yes_no(s->permissions_start_only), + prefix, yes_no(s->root_directory_start_only), + prefix, yes_no(s->remain_after_exit), + prefix, yes_no(s->guess_main_pid), + prefix, service_type_to_string(s->type), + prefix, service_restart_to_string(s->restart), + prefix, notify_access_to_string(s->notify_access)); + + if (s->control_pid > 0) + fprintf(f, + "%sControl PID: %lu\n", + prefix, (unsigned long) s->control_pid); + + if (s->main_pid > 0) + fprintf(f, + "%sMain PID: %lu\n" + "%sMain PID Known: %s\n" + "%sMain PID Alien: %s\n", + prefix, (unsigned long) s->main_pid, + prefix, yes_no(s->main_pid_known), + prefix, yes_no(s->main_pid_alien)); + + if (s->pid_file) + fprintf(f, + "%sPIDFile: %s\n", + prefix, s->pid_file); + + if (s->bus_name) + fprintf(f, + "%sBusName: %s\n" + "%sBus Name Good: %s\n", + prefix, s->bus_name, + prefix, yes_no(s->bus_name_good)); + + kill_context_dump(&s->kill_context, f, prefix); + exec_context_dump(&s->exec_context, f, prefix); + + for (c = 0; c < _SERVICE_EXEC_COMMAND_MAX; c++) { + + if (!s->exec_command[c]) + continue; + + fprintf(f, "%s-> %s:\n", + prefix, service_exec_command_to_string(c)); + + exec_command_dump_list(s->exec_command[c], f, prefix2); + } + +#ifdef HAVE_SYSV_COMPAT + if (s->is_sysv) + fprintf(f, + "%sSysV Init Script has LSB Header: %s\n" + "%sSysVEnabled: %s\n", + prefix, yes_no(s->sysv_has_lsb), + prefix, yes_no(s->sysv_enabled)); + + if (s->sysv_start_priority >= 0) + fprintf(f, + "%sSysVStartPriority: %i\n", + prefix, s->sysv_start_priority); + + if (s->sysv_runlevels) + fprintf(f, "%sSysVRunLevels: %s\n", + prefix, s->sysv_runlevels); +#endif + + if (s->fsck_passno > 0) + fprintf(f, + "%sFsckPassNo: %i\n", + prefix, s->fsck_passno); + + if (s->status_text) + fprintf(f, "%sStatus Text: %s\n", + prefix, s->status_text); + + free(p2); +} + +static int service_load_pid_file(Service *s, bool may_warn) { + char *k; + int r; + pid_t pid; + + assert(s); + + if (!s->pid_file) + return -ENOENT; + + if ((r = read_one_line_file(s->pid_file, &k)) < 0) { + if (may_warn) + log_info_unit(UNIT(s)->id, + "PID file %s not readable (yet?) after %s.", + s->pid_file, service_state_to_string(s->state)); + return r; + } + + r = parse_pid(k, &pid); + free(k); + + if (r < 0) + return r; + + if (kill(pid, 0) < 0 && errno != EPERM) { + if (may_warn) + log_info_unit(UNIT(s)->id, + "PID %lu read from file %s does not exist.", + (unsigned long) pid, s->pid_file); + return -ESRCH; + } + + if (s->main_pid_known) { + if (pid == s->main_pid) + return 0; + + log_debug_unit(UNIT(s)->id, + "Main PID changing: %lu -> %lu", + (unsigned long) s->main_pid, (unsigned long) pid); + service_unwatch_main_pid(s); + s->main_pid_known = false; + } else + log_debug_unit(UNIT(s)->id, + "Main PID loaded: %lu", (unsigned long) pid); + + if ((r = service_set_main_pid(s, pid)) < 0) + return r; + + if ((r = unit_watch_pid(UNIT(s), pid)) < 0) + /* FIXME: we need to do something here */ + return r; + + return 0; +} + +static int service_search_main_pid(Service *s) { + pid_t pid; + int r; + + assert(s); + + /* If we know it anyway, don't ever fallback to unreliable + * heuristics */ + if (s->main_pid_known) + return 0; + + if (!s->guess_main_pid) + return 0; + + assert(s->main_pid <= 0); + + if ((pid = cgroup_bonding_search_main_pid_list(UNIT(s)->cgroup_bondings)) <= 0) + return -ENOENT; + + log_debug_unit(UNIT(s)->id, + "Main PID guessed: %lu", (unsigned long) pid); + if ((r = service_set_main_pid(s, pid)) < 0) + return r; + + if ((r = unit_watch_pid(UNIT(s), pid)) < 0) + /* FIXME: we need to do something here */ + return r; + + return 0; +} + +static void service_notify_sockets_dead(Service *s, bool failed_permanent) { + Iterator i; + Unit *u; + + assert(s); + + /* Notifies all our sockets when we die */ + + if (s->socket_fd >= 0) + return; + + SET_FOREACH(u, UNIT(s)->dependencies[UNIT_TRIGGERED_BY], i) + if (u->type == UNIT_SOCKET) + socket_notify_service_dead(SOCKET(u), failed_permanent); + + return; +} + +static void service_set_state(Service *s, ServiceState state) { + ServiceState old_state; + const UnitActiveState *table; + assert(s); + + table = s->type == SERVICE_IDLE ? state_translation_table_idle : state_translation_table; + + old_state = s->state; + s->state = state; + + service_unwatch_pid_file(s); + + if (state != SERVICE_START_PRE && + state != SERVICE_START && + state != SERVICE_START_POST && + state != SERVICE_RELOAD && + state != SERVICE_STOP && + state != SERVICE_STOP_SIGTERM && + state != SERVICE_STOP_SIGKILL && + state != SERVICE_STOP_POST && + state != SERVICE_FINAL_SIGTERM && + state != SERVICE_FINAL_SIGKILL && + state != SERVICE_AUTO_RESTART) + unit_unwatch_timer(UNIT(s), &s->timer_watch); + + if (state != SERVICE_START && + state != SERVICE_START_POST && + state != SERVICE_RUNNING && + state != SERVICE_RELOAD && + state != SERVICE_STOP && + state != SERVICE_STOP_SIGTERM && + state != SERVICE_STOP_SIGKILL) { + service_unwatch_main_pid(s); + s->main_command = NULL; + } + + if (state != SERVICE_START_PRE && + state != SERVICE_START && + state != SERVICE_START_POST && + state != SERVICE_RELOAD && + state != SERVICE_STOP && + state != SERVICE_STOP_SIGTERM && + state != SERVICE_STOP_SIGKILL && + state != SERVICE_STOP_POST && + state != SERVICE_FINAL_SIGTERM && + state != SERVICE_FINAL_SIGKILL) { + service_unwatch_control_pid(s); + s->control_command = NULL; + s->control_command_id = _SERVICE_EXEC_COMMAND_INVALID; + } + + if (state == SERVICE_DEAD || + state == SERVICE_STOP || + state == SERVICE_STOP_SIGTERM || + state == SERVICE_STOP_SIGKILL || + state == SERVICE_STOP_POST || + state == SERVICE_FINAL_SIGTERM || + state == SERVICE_FINAL_SIGKILL || + state == SERVICE_FAILED || + state == SERVICE_AUTO_RESTART) + service_notify_sockets_dead(s, false); + + if (state != SERVICE_START_PRE && + state != SERVICE_START && + state != SERVICE_START_POST && + state != SERVICE_RUNNING && + state != SERVICE_RELOAD && + state != SERVICE_STOP && + state != SERVICE_STOP_SIGTERM && + state != SERVICE_STOP_SIGKILL && + state != SERVICE_STOP_POST && + state != SERVICE_FINAL_SIGTERM && + state != SERVICE_FINAL_SIGKILL && + !(state == SERVICE_DEAD && UNIT(s)->job)) { + service_close_socket_fd(s); + service_connection_unref(s); + } + + if (state == SERVICE_STOP) + service_stop_watchdog(s); + + /* For the inactive states unit_notify() will trim the cgroup, + * but for exit we have to do that ourselves... */ + if (state == SERVICE_EXITED && UNIT(s)->manager->n_reloading <= 0) + cgroup_bonding_trim_list(UNIT(s)->cgroup_bondings, true); + + if (old_state != state) + log_debug_unit(UNIT(s)->id, + "%s changed %s -> %s", UNIT(s)->id, + service_state_to_string(old_state), + service_state_to_string(state)); + + unit_notify(UNIT(s), table[old_state], table[state], s->reload_result == SERVICE_SUCCESS); + s->reload_result = SERVICE_SUCCESS; +} + +static int service_coldplug(Unit *u) { + Service *s = SERVICE(u); + int r; + + assert(s); + assert(s->state == SERVICE_DEAD); + + if (s->deserialized_state != s->state) { + + if (s->deserialized_state == SERVICE_START_PRE || + s->deserialized_state == SERVICE_START || + s->deserialized_state == SERVICE_START_POST || + s->deserialized_state == SERVICE_RELOAD || + s->deserialized_state == SERVICE_STOP || + s->deserialized_state == SERVICE_STOP_SIGTERM || + s->deserialized_state == SERVICE_STOP_SIGKILL || + s->deserialized_state == SERVICE_STOP_POST || + s->deserialized_state == SERVICE_FINAL_SIGTERM || + s->deserialized_state == SERVICE_FINAL_SIGKILL || + s->deserialized_state == SERVICE_AUTO_RESTART) { + if (s->deserialized_state == SERVICE_AUTO_RESTART || s->timeout_start_usec > 0) { + usec_t k; + + k = s->deserialized_state == SERVICE_AUTO_RESTART ? s->restart_usec : s->timeout_start_usec; + + r = unit_watch_timer(UNIT(s), CLOCK_MONOTONIC, true, k, &s->timer_watch); + if (r < 0) + return r; + } + } + + if ((s->deserialized_state == SERVICE_START && + (s->type == SERVICE_FORKING || + s->type == SERVICE_DBUS || + s->type == SERVICE_ONESHOT || + s->type == SERVICE_NOTIFY)) || + s->deserialized_state == SERVICE_START_POST || + s->deserialized_state == SERVICE_RUNNING || + s->deserialized_state == SERVICE_RELOAD || + s->deserialized_state == SERVICE_STOP || + s->deserialized_state == SERVICE_STOP_SIGTERM || + s->deserialized_state == SERVICE_STOP_SIGKILL) + if (s->main_pid > 0) + if ((r = unit_watch_pid(UNIT(s), s->main_pid)) < 0) + return r; + + if (s->deserialized_state == SERVICE_START_PRE || + s->deserialized_state == SERVICE_START || + s->deserialized_state == SERVICE_START_POST || + s->deserialized_state == SERVICE_RELOAD || + s->deserialized_state == SERVICE_STOP || + s->deserialized_state == SERVICE_STOP_SIGTERM || + s->deserialized_state == SERVICE_STOP_SIGKILL || + s->deserialized_state == SERVICE_STOP_POST || + s->deserialized_state == SERVICE_FINAL_SIGTERM || + s->deserialized_state == SERVICE_FINAL_SIGKILL) + if (s->control_pid > 0) + if ((r = unit_watch_pid(UNIT(s), s->control_pid)) < 0) + return r; + + if (s->deserialized_state == SERVICE_START_POST || + s->deserialized_state == SERVICE_RUNNING) + service_handle_watchdog(s); + + service_set_state(s, s->deserialized_state); + } + return 0; +} + +static int service_collect_fds(Service *s, int **fds, unsigned *n_fds) { + Iterator i; + int r; + int *rfds = NULL; + unsigned rn_fds = 0; + Unit *u; + + assert(s); + assert(fds); + assert(n_fds); + + if (s->socket_fd >= 0) + return 0; + + SET_FOREACH(u, UNIT(s)->dependencies[UNIT_TRIGGERED_BY], i) { + int *cfds; + unsigned cn_fds; + Socket *sock; + + if (u->type != UNIT_SOCKET) + continue; + + sock = SOCKET(u); + + if ((r = socket_collect_fds(sock, &cfds, &cn_fds)) < 0) + goto fail; + + if (!cfds) + continue; + + if (!rfds) { + rfds = cfds; + rn_fds = cn_fds; + } else { + int *t; + + if (!(t = new(int, rn_fds+cn_fds))) { + free(cfds); + r = -ENOMEM; + goto fail; + } + + memcpy(t, rfds, rn_fds * sizeof(int)); + memcpy(t+rn_fds, cfds, cn_fds * sizeof(int)); + free(rfds); + free(cfds); + + rfds = t; + rn_fds = rn_fds+cn_fds; + } + } + + *fds = rfds; + *n_fds = rn_fds; + + return 0; + +fail: + free(rfds); + + return r; +} + +static int service_spawn( + Service *s, + ExecCommand *c, + bool timeout, + bool pass_fds, + bool apply_permissions, + bool apply_chroot, + bool apply_tty_stdin, + bool set_notify_socket, + bool is_control, + pid_t *_pid) { + + pid_t pid; + int r; + int *fds = NULL, *fdsbuf = NULL; + unsigned n_fds = 0, n_env = 0; + char **argv = NULL, **final_env = NULL, **our_env = NULL; + + assert(s); + assert(c); + assert(_pid); + + if (pass_fds || + s->exec_context.std_input == EXEC_INPUT_SOCKET || + s->exec_context.std_output == EXEC_OUTPUT_SOCKET || + s->exec_context.std_error == EXEC_OUTPUT_SOCKET) { + + if (s->socket_fd >= 0) { + fds = &s->socket_fd; + n_fds = 1; + } else { + if ((r = service_collect_fds(s, &fdsbuf, &n_fds)) < 0) + goto fail; + + fds = fdsbuf; + } + } + + if (timeout && s->timeout_start_usec) { + r = unit_watch_timer(UNIT(s), CLOCK_MONOTONIC, true, s->timeout_start_usec, &s->timer_watch); + if (r < 0) + goto fail; + } else + unit_unwatch_timer(UNIT(s), &s->timer_watch); + + if (!(argv = unit_full_printf_strv(UNIT(s), c->argv))) { + r = -ENOMEM; + goto fail; + } + + our_env = new0(char*, 5); + if (!our_env) { + r = -ENOMEM; + goto fail; + } + + if (set_notify_socket) + if (asprintf(our_env + n_env++, "NOTIFY_SOCKET=%s", UNIT(s)->manager->notify_socket) < 0) { + r = -ENOMEM; + goto fail; + } + + if (s->main_pid > 0) + if (asprintf(our_env + n_env++, "MAINPID=%lu", (unsigned long) s->main_pid) < 0) { + r = -ENOMEM; + goto fail; + } + + if (s->watchdog_usec > 0) + if (asprintf(our_env + n_env++, "WATCHDOG_USEC=%llu", (unsigned long long) s->watchdog_usec) < 0) { + r = -ENOMEM; + goto fail; + } + + if (s->meta.manager->running_as != SYSTEMD_SYSTEM) + if (asprintf(our_env + n_env++, "MANAGERPID=%lu", (unsigned long) getpid()) < 0) { + r = -ENOMEM; + goto fail; + } + + final_env = strv_env_merge(2, UNIT(s)->manager->environment, our_env, NULL); + if (!final_env) { + r = -ENOMEM; + goto fail; + } + + r = exec_spawn(c, + argv, + &s->exec_context, + fds, n_fds, + final_env, + apply_permissions, + apply_chroot, + apply_tty_stdin, + UNIT(s)->manager->confirm_spawn, + UNIT(s)->cgroup_bondings, + UNIT(s)->cgroup_attributes, + is_control ? "control" : NULL, + UNIT(s)->id, + s->type == SERVICE_IDLE ? UNIT(s)->manager->idle_pipe : NULL, + &pid); + + if (r < 0) + goto fail; + + if ((r = unit_watch_pid(UNIT(s), pid)) < 0) + /* FIXME: we need to do something here */ + goto fail; + + free(fdsbuf); + strv_free(argv); + strv_free(our_env); + strv_free(final_env); + + *_pid = pid; + + return 0; + +fail: + free(fdsbuf); + strv_free(argv); + strv_free(our_env); + strv_free(final_env); + + if (timeout) + unit_unwatch_timer(UNIT(s), &s->timer_watch); + + return r; +} + +static int main_pid_good(Service *s) { + assert(s); + + /* Returns 0 if the pid is dead, 1 if it is good, -1 if we + * don't know */ + + /* If we know the pid file, then lets just check if it is + * still valid */ + if (s->main_pid_known) { + + /* If it's an alien child let's check if it is still + * alive ... */ + if (s->main_pid_alien) + return kill(s->main_pid, 0) >= 0 || errno != ESRCH; + + /* .. otherwise assume we'll get a SIGCHLD for it, + * which we really should wait for to collect exit + * status and code */ + return s->main_pid > 0; + } + + /* We don't know the pid */ + return -EAGAIN; +} + +static int control_pid_good(Service *s) { + assert(s); + + return s->control_pid > 0; +} + +static int cgroup_good(Service *s) { + int r; + + assert(s); + + if ((r = cgroup_bonding_is_empty_list(UNIT(s)->cgroup_bondings)) < 0) + return r; + + return !r; +} + +static void service_enter_dead(Service *s, ServiceResult f, bool allow_restart) { + int r; + assert(s); + + if (f != SERVICE_SUCCESS) + s->result = f; + + service_set_state(s, s->result != SERVICE_SUCCESS ? SERVICE_FAILED : SERVICE_DEAD); + + if (allow_restart && + !s->forbid_restart && + (s->restart == SERVICE_RESTART_ALWAYS || + (s->restart == SERVICE_RESTART_ON_SUCCESS && s->result == SERVICE_SUCCESS) || + (s->restart == SERVICE_RESTART_ON_FAILURE && s->result != SERVICE_SUCCESS) || + (s->restart == SERVICE_RESTART_ON_ABORT && (s->result == SERVICE_FAILURE_SIGNAL || + s->result == SERVICE_FAILURE_CORE_DUMP))) && + (s->result != SERVICE_FAILURE_EXIT_CODE || + !set_contains(s->restart_ignore_status.code, INT_TO_PTR(s->main_exec_status.status))) && + (s->result != SERVICE_FAILURE_SIGNAL || + !set_contains(s->restart_ignore_status.signal, INT_TO_PTR(s->main_exec_status.status))) + ) { + + r = unit_watch_timer(UNIT(s), CLOCK_MONOTONIC, true, s->restart_usec, &s->timer_watch); + if (r < 0) + goto fail; + + service_set_state(s, SERVICE_AUTO_RESTART); + } + + s->forbid_restart = false; + + return; + +fail: + log_warning_unit(UNIT(s)->id, + "%s failed to run install restart timer: %s", + UNIT(s)->id, strerror(-r)); + service_enter_dead(s, SERVICE_FAILURE_RESOURCES, false); +} + +static void service_enter_signal(Service *s, ServiceState state, ServiceResult f); + +static void service_enter_stop_post(Service *s, ServiceResult f) { + int r; + assert(s); + + if (f != SERVICE_SUCCESS) + s->result = f; + + service_unwatch_control_pid(s); + + if ((s->control_command = s->exec_command[SERVICE_EXEC_STOP_POST])) { + s->control_command_id = SERVICE_EXEC_STOP_POST; + + r = service_spawn(s, + s->control_command, + true, + false, + !s->permissions_start_only, + !s->root_directory_start_only, + true, + false, + true, + &s->control_pid); + if (r < 0) + goto fail; + + + service_set_state(s, SERVICE_STOP_POST); + } else + service_enter_signal(s, SERVICE_FINAL_SIGTERM, SERVICE_SUCCESS); + + return; + +fail: + log_warning_unit(UNIT(s)->id, + "%s failed to run 'stop-post' task: %s", + UNIT(s)->id, strerror(-r)); + service_enter_signal(s, SERVICE_FINAL_SIGTERM, SERVICE_FAILURE_RESOURCES); +} + +static void service_enter_signal(Service *s, ServiceState state, ServiceResult f) { + int r; + Set *pid_set = NULL; + bool wait_for_exit = false; + + assert(s); + + if (f != SERVICE_SUCCESS) + s->result = f; + + if (s->kill_context.kill_mode != KILL_NONE) { + int sig = (state == SERVICE_STOP_SIGTERM || state == SERVICE_FINAL_SIGTERM) ? s->kill_context.kill_signal : SIGKILL; + + if (s->main_pid > 0) { + if (kill_and_sigcont(s->main_pid, sig) < 0 && errno != ESRCH) + log_warning_unit(UNIT(s)->id, + "Failed to kill main process %li: %m", (long) s->main_pid); + else + wait_for_exit = !s->main_pid_alien; + } + + if (s->control_pid > 0) { + if (kill_and_sigcont(s->control_pid, sig) < 0 && errno != ESRCH) + log_warning_unit(UNIT(s)->id, + "Failed to kill control process %li: %m", (long) s->control_pid); + else + wait_for_exit = true; + } + + if (s->kill_context.kill_mode == KILL_CONTROL_GROUP) { + + pid_set = set_new(trivial_hash_func, trivial_compare_func); + if (!pid_set) { + r = -ENOMEM; + goto fail; + } + + /* Exclude the main/control pids from being killed via the cgroup */ + if (s->main_pid > 0) + if ((r = set_put(pid_set, LONG_TO_PTR(s->main_pid))) < 0) + goto fail; + + if (s->control_pid > 0) + if ((r = set_put(pid_set, LONG_TO_PTR(s->control_pid))) < 0) + goto fail; + + r = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, sig, true, false, pid_set, NULL); + if (r < 0) { + if (r != -EAGAIN && r != -ESRCH && r != -ENOENT) + log_warning_unit(UNIT(s)->id, + "Failed to kill control group: %s", strerror(-r)); + } else if (r > 0) + wait_for_exit = true; + + set_free(pid_set); + pid_set = NULL; + } + } + + if (wait_for_exit) { + if (s->timeout_stop_usec > 0) { + r = unit_watch_timer(UNIT(s), CLOCK_MONOTONIC, true, s->timeout_stop_usec, &s->timer_watch); + if (r < 0) + goto fail; + } + + service_set_state(s, state); + } else if (state == SERVICE_STOP_SIGTERM || state == SERVICE_STOP_SIGKILL) + service_enter_stop_post(s, SERVICE_SUCCESS); + else + service_enter_dead(s, SERVICE_SUCCESS, true); + + return; + +fail: + log_warning_unit(UNIT(s)->id, + "%s failed to kill processes: %s", UNIT(s)->id, strerror(-r)); + + if (state == SERVICE_STOP_SIGTERM || state == SERVICE_STOP_SIGKILL) + service_enter_stop_post(s, SERVICE_FAILURE_RESOURCES); + else + service_enter_dead(s, SERVICE_FAILURE_RESOURCES, true); + + if (pid_set) + set_free(pid_set); +} + +static void service_enter_stop(Service *s, ServiceResult f) { + int r; + + assert(s); + + if (f != SERVICE_SUCCESS) + s->result = f; + + service_unwatch_control_pid(s); + + if ((s->control_command = s->exec_command[SERVICE_EXEC_STOP])) { + s->control_command_id = SERVICE_EXEC_STOP; + + r = service_spawn(s, + s->control_command, + true, + false, + !s->permissions_start_only, + !s->root_directory_start_only, + false, + false, + true, + &s->control_pid); + if (r < 0) + goto fail; + + service_set_state(s, SERVICE_STOP); + } else + service_enter_signal(s, SERVICE_STOP_SIGTERM, SERVICE_SUCCESS); + + return; + +fail: + log_warning_unit(UNIT(s)->id, + "%s failed to run 'stop' task: %s", UNIT(s)->id, strerror(-r)); + service_enter_signal(s, SERVICE_STOP_SIGTERM, SERVICE_FAILURE_RESOURCES); +} + +static void service_enter_running(Service *s, ServiceResult f) { + int main_pid_ok, cgroup_ok; + assert(s); + + if (f != SERVICE_SUCCESS) + s->result = f; + + main_pid_ok = main_pid_good(s); + cgroup_ok = cgroup_good(s); + + if ((main_pid_ok > 0 || (main_pid_ok < 0 && cgroup_ok != 0)) && + (s->bus_name_good || s->type != SERVICE_DBUS)) + service_set_state(s, SERVICE_RUNNING); + else if (s->remain_after_exit) + service_set_state(s, SERVICE_EXITED); + else + service_enter_stop(s, SERVICE_SUCCESS); +} + +static void service_enter_start_post(Service *s) { + int r; + assert(s); + + service_unwatch_control_pid(s); + + if (s->watchdog_usec > 0) + service_reset_watchdog(s); + + if ((s->control_command = s->exec_command[SERVICE_EXEC_START_POST])) { + s->control_command_id = SERVICE_EXEC_START_POST; + + r = service_spawn(s, + s->control_command, + true, + false, + !s->permissions_start_only, + !s->root_directory_start_only, + false, + false, + true, + &s->control_pid); + if (r < 0) + goto fail; + + service_set_state(s, SERVICE_START_POST); + } else + service_enter_running(s, SERVICE_SUCCESS); + + return; + +fail: + log_warning_unit(UNIT(s)->id, + "%s failed to run 'start-post' task: %s", UNIT(s)->id, strerror(-r)); + service_enter_stop(s, SERVICE_FAILURE_RESOURCES); +} + +static void service_enter_start(Service *s) { + pid_t pid; + int r; + ExecCommand *c; + + assert(s); + + assert(s->exec_command[SERVICE_EXEC_START]); + assert(!s->exec_command[SERVICE_EXEC_START]->command_next || s->type == SERVICE_ONESHOT); + + if (s->type == SERVICE_FORKING) + service_unwatch_control_pid(s); + else + service_unwatch_main_pid(s); + + /* We want to ensure that nobody leaks processes from + * START_PRE here, so let's go on a killing spree, People + * should not spawn long running processes from START_PRE. */ + cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, SIGKILL, true, true, NULL, "control"); + + if (s->type == SERVICE_FORKING) { + s->control_command_id = SERVICE_EXEC_START; + c = s->control_command = s->exec_command[SERVICE_EXEC_START]; + + s->main_command = NULL; + } else { + s->control_command_id = _SERVICE_EXEC_COMMAND_INVALID; + s->control_command = NULL; + + c = s->main_command = s->exec_command[SERVICE_EXEC_START]; + } + + r = service_spawn(s, + c, + s->type == SERVICE_FORKING || s->type == SERVICE_DBUS || s->type == SERVICE_NOTIFY || s->type == SERVICE_ONESHOT, + true, + true, + true, + true, + s->notify_access != NOTIFY_NONE, + false, + &pid); + if (r < 0) + goto fail; + + if (s->type == SERVICE_SIMPLE || s->type == SERVICE_IDLE) { + /* For simple services we immediately start + * the START_POST binaries. */ + + service_set_main_pid(s, pid); + service_enter_start_post(s); + + } else if (s->type == SERVICE_FORKING) { + + /* For forking services we wait until the start + * process exited. */ + + s->control_pid = pid; + service_set_state(s, SERVICE_START); + + } else if (s->type == SERVICE_ONESHOT || + s->type == SERVICE_DBUS || + s->type == SERVICE_NOTIFY) { + + /* For oneshot services we wait until the start + * process exited, too, but it is our main process. */ + + /* For D-Bus services we know the main pid right away, + * but wait for the bus name to appear on the + * bus. Notify services are similar. */ + + service_set_main_pid(s, pid); + service_set_state(s, SERVICE_START); + } else + assert_not_reached("Unknown service type"); + + return; + +fail: + log_warning_unit(UNIT(s)->id, + "%s failed to run 'start' task: %s", UNIT(s)->id, strerror(-r)); + service_enter_signal(s, SERVICE_FINAL_SIGTERM, SERVICE_FAILURE_RESOURCES); +} + +static void service_enter_start_pre(Service *s) { + int r; + + assert(s); + + service_unwatch_control_pid(s); + + if ((s->control_command = s->exec_command[SERVICE_EXEC_START_PRE])) { + + /* Before we start anything, let's clear up what might + * be left from previous runs. */ + cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, SIGKILL, true, true, NULL, "control"); + + s->control_command_id = SERVICE_EXEC_START_PRE; + + r = service_spawn(s, + s->control_command, + true, + false, + !s->permissions_start_only, + !s->root_directory_start_only, + true, + false, + true, + &s->control_pid); + if (r < 0) + goto fail; + + service_set_state(s, SERVICE_START_PRE); + } else + service_enter_start(s); + + return; + +fail: + log_warning_unit(UNIT(s)->id, + "%s failed to run 'start-pre' task: %s", UNIT(s)->id, strerror(-r)); + service_enter_dead(s, SERVICE_FAILURE_RESOURCES, true); +} + +static void service_enter_restart(Service *s) { + int r; + DBusError error; + + assert(s); + dbus_error_init(&error); + + if (UNIT(s)->job && UNIT(s)->job->type == JOB_STOP) { + /* Don't restart things if we are going down anyway */ + log_info_unit(UNIT(s)->id, + "Stop job pending for unit, delaying automatic restart."); + + r = unit_watch_timer(UNIT(s), CLOCK_MONOTONIC, true, s->restart_usec, &s->timer_watch); + if (r < 0) + goto fail; + + return; + } + + /* Any units that are bound to this service must also be + * restarted. We use JOB_RESTART (instead of the more obvious + * JOB_START) here so that those dependency jobs will be added + * as well. */ + r = manager_add_job(UNIT(s)->manager, JOB_RESTART, UNIT(s), JOB_FAIL, false, &error, NULL); + if (r < 0) + goto fail; + + /* Note that we stay in the SERVICE_AUTO_RESTART state here, + * it will be canceled as part of the service_stop() call that + * is executed as part of JOB_RESTART. */ + + log_debug_unit(UNIT(s)->id, + "%s scheduled restart job.", UNIT(s)->id); + return; + +fail: + log_warning_unit(UNIT(s)->id, + "%s failed to schedule restart job: %s", + UNIT(s)->id, bus_error(&error, -r)); + service_enter_dead(s, SERVICE_FAILURE_RESOURCES, false); + + dbus_error_free(&error); +} + +static void service_enter_reload(Service *s) { + int r; + + assert(s); + + service_unwatch_control_pid(s); + + if ((s->control_command = s->exec_command[SERVICE_EXEC_RELOAD])) { + s->control_command_id = SERVICE_EXEC_RELOAD; + + r = service_spawn(s, + s->control_command, + true, + false, + !s->permissions_start_only, + !s->root_directory_start_only, + false, + false, + true, + &s->control_pid); + if (r < 0) + goto fail; + + service_set_state(s, SERVICE_RELOAD); + } else + service_enter_running(s, SERVICE_SUCCESS); + + return; + +fail: + log_warning_unit(UNIT(s)->id, + "%s failed to run 'reload' task: %s", + UNIT(s)->id, strerror(-r)); + s->reload_result = SERVICE_FAILURE_RESOURCES; + service_enter_running(s, SERVICE_SUCCESS); +} + +static void service_run_next_control(Service *s) { + int r; + + assert(s); + assert(s->control_command); + assert(s->control_command->command_next); + + assert(s->control_command_id != SERVICE_EXEC_START); + + s->control_command = s->control_command->command_next; + service_unwatch_control_pid(s); + + r = service_spawn(s, + s->control_command, + true, + false, + !s->permissions_start_only, + !s->root_directory_start_only, + s->control_command_id == SERVICE_EXEC_START_PRE || + s->control_command_id == SERVICE_EXEC_STOP_POST, + false, + true, + &s->control_pid); + if (r < 0) + goto fail; + + return; + +fail: + log_warning_unit(UNIT(s)->id, + "%s failed to run next control task: %s", + UNIT(s)->id, strerror(-r)); + + if (s->state == SERVICE_START_PRE) + service_enter_signal(s, SERVICE_FINAL_SIGTERM, SERVICE_FAILURE_RESOURCES); + else if (s->state == SERVICE_STOP) + service_enter_signal(s, SERVICE_STOP_SIGTERM, SERVICE_FAILURE_RESOURCES); + else if (s->state == SERVICE_STOP_POST) + service_enter_dead(s, SERVICE_FAILURE_RESOURCES, true); + else if (s->state == SERVICE_RELOAD) { + s->reload_result = SERVICE_FAILURE_RESOURCES; + service_enter_running(s, SERVICE_SUCCESS); + } else + service_enter_stop(s, SERVICE_FAILURE_RESOURCES); +} + +static void service_run_next_main(Service *s) { + pid_t pid; + int r; + + assert(s); + assert(s->main_command); + assert(s->main_command->command_next); + assert(s->type == SERVICE_ONESHOT); + + s->main_command = s->main_command->command_next; + service_unwatch_main_pid(s); + + r = service_spawn(s, + s->main_command, + true, + true, + true, + true, + true, + s->notify_access != NOTIFY_NONE, + false, + &pid); + if (r < 0) + goto fail; + + service_set_main_pid(s, pid); + + return; + +fail: + log_warning_unit(UNIT(s)->id, + "%s failed to run next main task: %s", UNIT(s)->id, strerror(-r)); + service_enter_stop(s, SERVICE_FAILURE_RESOURCES); +} + +static int service_start_limit_test(Service *s) { + assert(s); + + if (ratelimit_test(&s->start_limit)) + return 0; + + switch (s->start_limit_action) { + + case SERVICE_START_LIMIT_NONE: + log_warning_unit(UNIT(s)->id, + "%s start request repeated too quickly, refusing to start.", + UNIT(s)->id); + break; + + case SERVICE_START_LIMIT_REBOOT: { + DBusError error; + int r; + + dbus_error_init(&error); + + log_warning_unit(UNIT(s)->id, + "%s start request repeated too quickly, rebooting.", UNIT(s)->id); + + r = manager_add_job_by_name(UNIT(s)->manager, JOB_START, SPECIAL_REBOOT_TARGET, JOB_REPLACE, true, &error, NULL); + if (r < 0) { + log_error_unit(UNIT(s)->id, + "Failed to reboot: %s.", bus_error(&error, r)); + dbus_error_free(&error); + } + + break; + } + + case SERVICE_START_LIMIT_REBOOT_FORCE: + log_warning_unit(UNIT(s)->id, + "%s start request repeated too quickly, forcibly rebooting.", UNIT(s)->id); + UNIT(s)->manager->exit_code = MANAGER_REBOOT; + break; + + case SERVICE_START_LIMIT_REBOOT_IMMEDIATE: + log_warning_unit(UNIT(s)->id, + "%s start request repeated too quickly, rebooting immediately.", UNIT(s)->id); + sync(); + reboot(RB_AUTOBOOT); + break; + + default: + log_error_unit(UNIT(s)->id, + "start limit action=%i", s->start_limit_action); + assert_not_reached("Unknown StartLimitAction."); + } + + return -ECANCELED; +} + +static int service_start(Unit *u) { + Service *s = SERVICE(u); + int r; + + assert(s); + + /* We cannot fulfill this request right now, try again later + * please! */ + if (s->state == SERVICE_STOP || + s->state == SERVICE_STOP_SIGTERM || + s->state == SERVICE_STOP_SIGKILL || + s->state == SERVICE_STOP_POST || + s->state == SERVICE_FINAL_SIGTERM || + s->state == SERVICE_FINAL_SIGKILL) + return -EAGAIN; + + /* Already on it! */ + if (s->state == SERVICE_START_PRE || + s->state == SERVICE_START || + s->state == SERVICE_START_POST) + return 0; + + /* A service that will be restarted must be stopped first to + * trigger BindsTo and/or OnFailure dependencies. If a user + * does not want to wait for the holdoff time to elapse, the + * service should be manually restarted, not started. We + * simply return EAGAIN here, so that any start jobs stay + * queued, and assume that the auto restart timer will + * eventually trigger the restart. */ + if (s->state == SERVICE_AUTO_RESTART) + return -EAGAIN; + + assert(s->state == SERVICE_DEAD || s->state == SERVICE_FAILED); + + /* Make sure we don't enter a busy loop of some kind. */ + r = service_start_limit_test(s); + if (r < 0) { + service_enter_dead(s, SERVICE_FAILURE_START_LIMIT, false); + return r; + } + + s->result = SERVICE_SUCCESS; + s->reload_result = SERVICE_SUCCESS; + s->main_pid_known = false; + s->main_pid_alien = false; + s->forbid_restart = false; + + service_enter_start_pre(s); + return 0; +} + +static int service_stop(Unit *u) { + Service *s = SERVICE(u); + + assert(s); + + /* Don't create restart jobs from here. */ + s->forbid_restart = true; + + /* Already on it */ + if (s->state == SERVICE_STOP || + s->state == SERVICE_STOP_SIGTERM || + s->state == SERVICE_STOP_SIGKILL || + s->state == SERVICE_STOP_POST || + s->state == SERVICE_FINAL_SIGTERM || + s->state == SERVICE_FINAL_SIGKILL) + return 0; + + /* A restart will be scheduled or is in progress. */ + if (s->state == SERVICE_AUTO_RESTART) { + service_set_state(s, SERVICE_DEAD); + return 0; + } + + /* If there's already something running we go directly into + * kill mode. */ + if (s->state == SERVICE_START_PRE || + s->state == SERVICE_START || + s->state == SERVICE_START_POST || + s->state == SERVICE_RELOAD) { + service_enter_signal(s, SERVICE_STOP_SIGTERM, SERVICE_SUCCESS); + return 0; + } + + assert(s->state == SERVICE_RUNNING || + s->state == SERVICE_EXITED); + + service_enter_stop(s, SERVICE_SUCCESS); + return 0; +} + +static int service_reload(Unit *u) { + Service *s = SERVICE(u); + + assert(s); + + assert(s->state == SERVICE_RUNNING || s->state == SERVICE_EXITED); + + service_enter_reload(s); + return 0; +} + +static bool service_can_reload(Unit *u) { + Service *s = SERVICE(u); + + assert(s); + + return !!s->exec_command[SERVICE_EXEC_RELOAD]; +} + +static int service_serialize(Unit *u, FILE *f, FDSet *fds) { + Service *s = SERVICE(u); + + assert(u); + assert(f); + assert(fds); + + unit_serialize_item(u, f, "state", service_state_to_string(s->state)); + unit_serialize_item(u, f, "result", service_result_to_string(s->result)); + unit_serialize_item(u, f, "reload-result", service_result_to_string(s->reload_result)); + + if (s->control_pid > 0) + unit_serialize_item_format(u, f, "control-pid", "%lu", (unsigned long) s->control_pid); + + if (s->main_pid_known && s->main_pid > 0) + unit_serialize_item_format(u, f, "main-pid", "%lu", (unsigned long) s->main_pid); + + unit_serialize_item(u, f, "main-pid-known", yes_no(s->main_pid_known)); + + if (s->status_text) + unit_serialize_item(u, f, "status-text", s->status_text); + + /* FIXME: There's a minor uncleanliness here: if there are + * multiple commands attached here, we will start from the + * first one again */ + if (s->control_command_id >= 0) + unit_serialize_item(u, f, "control-command", service_exec_command_to_string(s->control_command_id)); + + if (s->socket_fd >= 0) { + int copy; + + if ((copy = fdset_put_dup(fds, s->socket_fd)) < 0) + return copy; + + unit_serialize_item_format(u, f, "socket-fd", "%i", copy); + } + + if (s->main_exec_status.pid > 0) { + unit_serialize_item_format(u, f, "main-exec-status-pid", "%lu", (unsigned long) s->main_exec_status.pid); + dual_timestamp_serialize(f, "main-exec-status-start", &s->main_exec_status.start_timestamp); + dual_timestamp_serialize(f, "main-exec-status-exit", &s->main_exec_status.exit_timestamp); + + if (dual_timestamp_is_set(&s->main_exec_status.exit_timestamp)) { + unit_serialize_item_format(u, f, "main-exec-status-code", "%i", s->main_exec_status.code); + unit_serialize_item_format(u, f, "main-exec-status-status", "%i", s->main_exec_status.status); + } + } + if (dual_timestamp_is_set(&s->watchdog_timestamp)) + dual_timestamp_serialize(f, "watchdog-timestamp", &s->watchdog_timestamp); + + return 0; +} + +static int service_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) { + Service *s = SERVICE(u); + + assert(u); + assert(key); + assert(value); + assert(fds); + + if (streq(key, "state")) { + ServiceState state; + + if ((state = service_state_from_string(value)) < 0) + log_debug_unit(u->id, "Failed to parse state value %s", value); + else + s->deserialized_state = state; + } else if (streq(key, "result")) { + ServiceResult f; + + f = service_result_from_string(value); + if (f < 0) + log_debug_unit(u->id, "Failed to parse result value %s", value); + else if (f != SERVICE_SUCCESS) + s->result = f; + + } else if (streq(key, "reload-result")) { + ServiceResult f; + + f = service_result_from_string(value); + if (f < 0) + log_debug_unit(u->id, "Failed to parse reload result value %s", value); + else if (f != SERVICE_SUCCESS) + s->reload_result = f; + + } else if (streq(key, "control-pid")) { + pid_t pid; + + if (parse_pid(value, &pid) < 0) + log_debug_unit(u->id, "Failed to parse control-pid value %s", value); + else + s->control_pid = pid; + } else if (streq(key, "main-pid")) { + pid_t pid; + + if (parse_pid(value, &pid) < 0) + log_debug_unit(u->id, "Failed to parse main-pid value %s", value); + else + service_set_main_pid(s, (pid_t) pid); + } else if (streq(key, "main-pid-known")) { + int b; + + if ((b = parse_boolean(value)) < 0) + log_debug_unit(u->id, "Failed to parse main-pid-known value %s", value); + else + s->main_pid_known = b; + } else if (streq(key, "status-text")) { + char *t; + + if ((t = strdup(value))) { + free(s->status_text); + s->status_text = t; + } + + } else if (streq(key, "control-command")) { + ServiceExecCommand id; + + if ((id = service_exec_command_from_string(value)) < 0) + log_debug_unit(u->id, "Failed to parse exec-command value %s", value); + else { + s->control_command_id = id; + s->control_command = s->exec_command[id]; + } + } else if (streq(key, "socket-fd")) { + int fd; + + if (safe_atoi(value, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd)) + log_debug_unit(u->id, "Failed to parse socket-fd value %s", value); + else { + + if (s->socket_fd >= 0) + close_nointr_nofail(s->socket_fd); + s->socket_fd = fdset_remove(fds, fd); + } + } else if (streq(key, "main-exec-status-pid")) { + pid_t pid; + + if (parse_pid(value, &pid) < 0) + log_debug_unit(u->id, "Failed to parse main-exec-status-pid value %s", value); + else + s->main_exec_status.pid = pid; + } else if (streq(key, "main-exec-status-code")) { + int i; + + if (safe_atoi(value, &i) < 0) + log_debug_unit(u->id, "Failed to parse main-exec-status-code value %s", value); + else + s->main_exec_status.code = i; + } else if (streq(key, "main-exec-status-status")) { + int i; + + if (safe_atoi(value, &i) < 0) + log_debug_unit(u->id, "Failed to parse main-exec-status-status value %s", value); + else + s->main_exec_status.status = i; + } else if (streq(key, "main-exec-status-start")) + dual_timestamp_deserialize(value, &s->main_exec_status.start_timestamp); + else if (streq(key, "main-exec-status-exit")) + dual_timestamp_deserialize(value, &s->main_exec_status.exit_timestamp); + else if (streq(key, "watchdog-timestamp")) + dual_timestamp_deserialize(value, &s->watchdog_timestamp); + else + log_debug_unit(u->id, "Unknown serialization key '%s'", key); + + return 0; +} + +static UnitActiveState service_active_state(Unit *u) { + const UnitActiveState *table; + + assert(u); + + table = SERVICE(u)->type == SERVICE_IDLE ? state_translation_table_idle : state_translation_table; + + return table[SERVICE(u)->state]; +} + +static const char *service_sub_state_to_string(Unit *u) { + assert(u); + + return service_state_to_string(SERVICE(u)->state); +} + +static bool service_check_gc(Unit *u) { + Service *s = SERVICE(u); + + assert(s); + + /* Never clean up services that still have a process around, + * even if the service is formally dead. */ + if (cgroup_good(s) > 0 || + main_pid_good(s) > 0 || + control_pid_good(s) > 0) + return true; + +#ifdef HAVE_SYSV_COMPAT + if (s->is_sysv) + return true; +#endif + + return false; +} + +static bool service_check_snapshot(Unit *u) { + Service *s = SERVICE(u); + + assert(s); + + return !s->got_socket_fd; +} + +static int service_retry_pid_file(Service *s) { + int r; + + assert(s->pid_file); + assert(s->state == SERVICE_START || s->state == SERVICE_START_POST); + + r = service_load_pid_file(s, false); + if (r < 0) + return r; + + service_unwatch_pid_file(s); + + service_enter_running(s, SERVICE_SUCCESS); + return 0; +} + +static int service_watch_pid_file(Service *s) { + int r; + + log_debug_unit(UNIT(s)->id, + "Setting watch for %s's PID file %s", + UNIT(s)->id, s->pid_file_pathspec->path); + r = path_spec_watch(s->pid_file_pathspec, UNIT(s)); + if (r < 0) + goto fail; + + /* the pidfile might have appeared just before we set the watch */ + service_retry_pid_file(s); + + return 0; +fail: + log_error_unit(UNIT(s)->id, + "Failed to set a watch for %s's PID file %s: %s", + UNIT(s)->id, s->pid_file_pathspec->path, strerror(-r)); + service_unwatch_pid_file(s); + return r; +} + +static int service_demand_pid_file(Service *s) { + PathSpec *ps; + + assert(s->pid_file); + assert(!s->pid_file_pathspec); + + ps = new0(PathSpec, 1); + if (!ps) + return -ENOMEM; + + ps->path = strdup(s->pid_file); + if (!ps->path) { + free(ps); + return -ENOMEM; + } + + path_kill_slashes(ps->path); + + /* PATH_CHANGED would not be enough. There are daemons (sendmail) that + * keep their PID file open all the time. */ + ps->type = PATH_MODIFIED; + ps->inotify_fd = -1; + + s->pid_file_pathspec = ps; + + return service_watch_pid_file(s); +} + +static void service_fd_event(Unit *u, int fd, uint32_t events, Watch *w) { + Service *s = SERVICE(u); + + assert(s); + assert(fd >= 0); + assert(s->state == SERVICE_START || s->state == SERVICE_START_POST); + assert(s->pid_file_pathspec); + assert(path_spec_owns_inotify_fd(s->pid_file_pathspec, fd)); + + log_debug_unit(u->id, "inotify event for %s", u->id); + + if (path_spec_fd_event(s->pid_file_pathspec, events) < 0) + goto fail; + + if (service_retry_pid_file(s) == 0) + return; + + if (service_watch_pid_file(s) < 0) + goto fail; + + return; +fail: + service_unwatch_pid_file(s); + service_enter_signal(s, SERVICE_STOP_SIGTERM, SERVICE_FAILURE_RESOURCES); +} + +static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) { + Service *s = SERVICE(u); + ServiceResult f; + + assert(s); + assert(pid >= 0); + + if (UNIT(s)->fragment_path ? is_clean_exit(code, status, &s->success_status) : + is_clean_exit_lsb(code, status, &s->success_status)) + f = SERVICE_SUCCESS; + else if (code == CLD_EXITED) + f = SERVICE_FAILURE_EXIT_CODE; + else if (code == CLD_KILLED) + f = SERVICE_FAILURE_SIGNAL; + else if (code == CLD_DUMPED) + f = SERVICE_FAILURE_CORE_DUMP; + else + assert_not_reached("Unknown code"); + + if (s->main_pid == pid) { + /* 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) + return; + + s->main_pid = 0; + exec_status_exit(&s->main_exec_status, &s->exec_context, pid, code, status); + + /* If this is not a forking service than the main + * process got started and hence we copy the exit + * status so that it is recorded both as main and as + * control process exit status */ + if (s->main_command) { + s->main_command->exec_status = s->main_exec_status; + + if (s->main_command->ignore) + f = SERVICE_SUCCESS; + } + + log_struct(f == SERVICE_SUCCESS ? LOG_DEBUG : LOG_NOTICE, + "MESSAGE=%s: main process exited, code=%s, status=%i/%s", + u->id, sigchld_code_to_string(code), status, + strna(code == CLD_EXITED + ? exit_status_to_string(status, EXIT_STATUS_FULL) + : signal_to_string(status)), + "UNIT=%s", u->id, + "EXIT_CODE=%s", sigchld_code_to_string(code), + "EXIT_STATUS=%i", status, + NULL); + + if (f != SERVICE_SUCCESS) + s->result = f; + + if (s->main_command && + s->main_command->command_next && + f == SERVICE_SUCCESS) { + + /* There is another command to * + * execute, so let's do that. */ + + log_debug_unit(u->id, + "%s running next main command for state %s", + u->id, service_state_to_string(s->state)); + service_run_next_main(s); + + } else { + + /* The service exited, so the service is officially + * gone. */ + s->main_command = NULL; + + switch (s->state) { + + case SERVICE_START_POST: + case SERVICE_RELOAD: + case SERVICE_STOP: + /* Need to wait until the operation is + * done */ + break; + + case SERVICE_START: + if (s->type == SERVICE_ONESHOT) { + /* This was our main goal, so let's go on */ + if (f == SERVICE_SUCCESS) + service_enter_start_post(s); + else + service_enter_signal(s, SERVICE_FINAL_SIGTERM, f); + break; + } + + /* Fall through */ + + case SERVICE_RUNNING: + service_enter_running(s, f); + break; + + case SERVICE_STOP_SIGTERM: + case SERVICE_STOP_SIGKILL: + + if (!control_pid_good(s)) + service_enter_stop_post(s, f); + + /* If there is still a control process, wait for that first */ + break; + + default: + assert_not_reached("Uh, main process died at wrong time."); + } + } + + } else if (s->control_pid == pid) { + + s->control_pid = 0; + + if (s->control_command) { + exec_status_exit(&s->control_command->exec_status, &s->exec_context, pid, code, status); + + if (s->control_command->ignore) + f = SERVICE_SUCCESS; + } + + log_full_unit(f == SERVICE_SUCCESS ? LOG_DEBUG : LOG_NOTICE, u->id, + "%s: control process exited, code=%s status=%i", + u->id, sigchld_code_to_string(code), status); + + if (f != SERVICE_SUCCESS) + s->result = f; + + /* Immediately get rid of the cgroup, so that the + * kernel doesn't delay the cgroup empty messages for + * the service cgroup any longer than necessary */ + cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, SIGKILL, true, true, NULL, "control"); + + if (s->control_command && + s->control_command->command_next && + f == SERVICE_SUCCESS) { + + /* There is another command to * + * execute, so let's do that. */ + + log_debug_unit(u->id, + "%s running next control command for state %s", + u->id, service_state_to_string(s->state)); + service_run_next_control(s); + + } else { + /* No further commands for this step, so let's + * figure out what to do next */ + + s->control_command = NULL; + s->control_command_id = _SERVICE_EXEC_COMMAND_INVALID; + + log_debug_unit(u->id, + "%s got final SIGCHLD for state %s", + u->id, service_state_to_string(s->state)); + + switch (s->state) { + + case SERVICE_START_PRE: + if (f == SERVICE_SUCCESS) + service_enter_start(s); + else + service_enter_signal(s, SERVICE_FINAL_SIGTERM, f); + break; + + case SERVICE_START: + if (s->type != SERVICE_FORKING) + /* Maybe spurious event due to a reload that changed the type? */ + break; + + if (f != SERVICE_SUCCESS) { + service_enter_signal(s, SERVICE_FINAL_SIGTERM, f); + break; + } + + if (s->pid_file) { + bool has_start_post; + int r; + + /* Let's try to load the pid file here if we can. + * The PID file might actually be created by a START_POST + * script. In that case don't worry if the loading fails. */ + + has_start_post = !!s->exec_command[SERVICE_EXEC_START_POST]; + r = service_load_pid_file(s, !has_start_post); + if (!has_start_post && r < 0) { + r = service_demand_pid_file(s); + if (r < 0 || !cgroup_good(s)) + service_enter_signal(s, SERVICE_FINAL_SIGTERM, SERVICE_FAILURE_RESOURCES); + break; + } + } else + service_search_main_pid(s); + + service_enter_start_post(s); + break; + + case SERVICE_START_POST: + if (f != SERVICE_SUCCESS) { + service_enter_stop(s, f); + break; + } + + if (s->pid_file) { + int r; + + r = service_load_pid_file(s, true); + if (r < 0) { + r = service_demand_pid_file(s); + if (r < 0 || !cgroup_good(s)) + service_enter_stop(s, SERVICE_FAILURE_RESOURCES); + break; + } + } else + service_search_main_pid(s); + + service_enter_running(s, SERVICE_SUCCESS); + break; + + case SERVICE_RELOAD: + if (f == SERVICE_SUCCESS) { + service_load_pid_file(s, true); + service_search_main_pid(s); + } + + s->reload_result = f; + service_enter_running(s, SERVICE_SUCCESS); + break; + + case SERVICE_STOP: + service_enter_signal(s, SERVICE_STOP_SIGTERM, f); + break; + + case SERVICE_STOP_SIGTERM: + case SERVICE_STOP_SIGKILL: + if (main_pid_good(s) <= 0) + service_enter_stop_post(s, f); + + /* If there is still a service + * process around, wait until + * that one quit, too */ + break; + + case SERVICE_STOP_POST: + case SERVICE_FINAL_SIGTERM: + case SERVICE_FINAL_SIGKILL: + service_enter_dead(s, f, true); + break; + + default: + assert_not_reached("Uh, control process died at wrong time."); + } + } + } + + /* Notify clients about changed exit status */ + unit_add_to_dbus_queue(u); +} + +static void service_timer_event(Unit *u, uint64_t elapsed, Watch* w) { + Service *s = SERVICE(u); + + assert(s); + assert(elapsed == 1); + + if (w == &s->watchdog_watch) { + service_handle_watchdog(s); + return; + } + + assert(w == &s->timer_watch); + + switch (s->state) { + + case SERVICE_START_PRE: + case SERVICE_START: + log_warning_unit(u->id, + "%s operation timed out. Terminating.", u->id); + service_enter_signal(s, SERVICE_FINAL_SIGTERM, SERVICE_FAILURE_TIMEOUT); + break; + + case SERVICE_START_POST: + log_warning_unit(u->id, + "%s operation timed out. Stopping.", u->id); + service_enter_stop(s, SERVICE_FAILURE_TIMEOUT); + break; + + case SERVICE_RELOAD: + log_warning_unit(u->id, + "%s operation timed out. Stopping.", u->id); + s->reload_result = SERVICE_FAILURE_TIMEOUT; + service_enter_running(s, SERVICE_SUCCESS); + break; + + case SERVICE_STOP: + log_warning_unit(u->id, + "%s stopping timed out. Terminating.", u->id); + service_enter_signal(s, SERVICE_STOP_SIGTERM, SERVICE_FAILURE_TIMEOUT); + break; + + case SERVICE_STOP_SIGTERM: + if (s->kill_context.send_sigkill) { + log_warning_unit(u->id, + "%s stopping timed out. Killing.", u->id); + service_enter_signal(s, SERVICE_STOP_SIGKILL, SERVICE_FAILURE_TIMEOUT); + } else { + log_warning_unit(u->id, + "%s stopping timed out. Skipping SIGKILL.", u->id); + service_enter_stop_post(s, SERVICE_FAILURE_TIMEOUT); + } + + break; + + case SERVICE_STOP_SIGKILL: + /* Uh, we sent a SIGKILL and it is still not gone? + * Must be something we cannot kill, so let's just be + * weirded out and continue */ + + log_warning_unit(u->id, + "%s still around after SIGKILL. Ignoring.", u->id); + service_enter_stop_post(s, SERVICE_FAILURE_TIMEOUT); + break; + + case SERVICE_STOP_POST: + log_warning_unit(u->id, + "%s stopping timed out (2). Terminating.", u->id); + service_enter_signal(s, SERVICE_FINAL_SIGTERM, SERVICE_FAILURE_TIMEOUT); + break; + + case SERVICE_FINAL_SIGTERM: + if (s->kill_context.send_sigkill) { + log_warning_unit(u->id, + "%s stopping timed out (2). Killing.", u->id); + service_enter_signal(s, SERVICE_FINAL_SIGKILL, SERVICE_FAILURE_TIMEOUT); + } else { + log_warning_unit(u->id, + "%s stopping timed out (2). Skipping SIGKILL. Entering failed mode.", + u->id); + service_enter_dead(s, SERVICE_FAILURE_TIMEOUT, false); + } + + break; + + case SERVICE_FINAL_SIGKILL: + log_warning_unit(u->id, + "%s still around after SIGKILL (2). Entering failed mode.", u->id); + service_enter_dead(s, SERVICE_FAILURE_TIMEOUT, true); + break; + + case SERVICE_AUTO_RESTART: + log_info_unit(u->id, + "%s holdoff time over, scheduling restart.", u->id); + service_enter_restart(s); + break; + + default: + assert_not_reached("Timeout at wrong time."); + } +} + +static void service_cgroup_notify_event(Unit *u) { + Service *s = SERVICE(u); + + assert(u); + + log_debug_unit(u->id, + "%s: cgroup is empty", u->id); + + switch (s->state) { + + /* Waiting for SIGCHLD is usually more interesting, + * because it includes return codes/signals. Which is + * why we ignore the cgroup events for most cases, + * except when we don't know pid which to expect the + * SIGCHLD for. */ + + case SERVICE_START: + case SERVICE_START_POST: + /* If we were hoping for the daemon to write its PID file, + * we can give up now. */ + if (s->pid_file_pathspec) { + log_warning_unit(u->id, + "%s never wrote its PID file. Failing.", UNIT(s)->id); + service_unwatch_pid_file(s); + if (s->state == SERVICE_START) + service_enter_signal(s, SERVICE_FINAL_SIGTERM, SERVICE_FAILURE_RESOURCES); + else + service_enter_stop(s, SERVICE_FAILURE_RESOURCES); + } + break; + + case SERVICE_RUNNING: + /* service_enter_running() will figure out what to do */ + service_enter_running(s, SERVICE_SUCCESS); + break; + + case SERVICE_STOP_SIGTERM: + case SERVICE_STOP_SIGKILL: + + if (main_pid_good(s) <= 0 && !control_pid_good(s)) + service_enter_stop_post(s, SERVICE_SUCCESS); + + break; + + case SERVICE_FINAL_SIGTERM: + case SERVICE_FINAL_SIGKILL: + if (main_pid_good(s) <= 0 && !control_pid_good(s)) + service_enter_dead(s, SERVICE_SUCCESS, true); + + break; + + default: + ; + } +} + +static void service_notify_message(Unit *u, pid_t pid, char **tags) { + Service *s = SERVICE(u); + const char *e; + + assert(u); + + if (s->notify_access == NOTIFY_NONE) { + log_warning_unit(u->id, + "%s: Got notification message from PID %lu, but reception is disabled.", + u->id, (unsigned long) pid); + return; + } + + if (s->notify_access == NOTIFY_MAIN && pid != s->main_pid) { + log_warning_unit(u->id, + "%s: Got notification message from PID %lu, but reception only permitted for PID %lu", + u->id, (unsigned long) pid, (unsigned long) s->main_pid); + return; + } + + log_debug_unit(u->id, + "%s: Got message", u->id); + + /* Interpret MAINPID= */ + if ((e = strv_find_prefix(tags, "MAINPID=")) && + (s->state == SERVICE_START || + s->state == SERVICE_START_POST || + s->state == SERVICE_RUNNING || + s->state == SERVICE_RELOAD)) { + + if (parse_pid(e + 8, &pid) < 0) + log_warning_unit(u->id, + "Failed to parse notification message %s", e); + else { + log_debug_unit(u->id, + "%s: got %s", u->id, e); + service_set_main_pid(s, pid); + } + } + + /* Interpret READY= */ + if (s->type == SERVICE_NOTIFY && + s->state == SERVICE_START && + strv_find(tags, "READY=1")) { + log_debug_unit(u->id, + "%s: got READY=1", u->id); + + service_enter_start_post(s); + } + + /* Interpret STATUS= */ + e = strv_find_prefix(tags, "STATUS="); + if (e) { + char *t; + + if (e[7]) { + + if (!utf8_is_valid(e+7)) { + log_warning_unit(u->id, + "Status message in notification is not UTF-8 clean."); + return; + } + + t = strdup(e+7); + if (!t) { + log_error_unit(u->id, + "Failed to allocate string."); + return; + } + + log_debug_unit(u->id, + "%s: got %s", u->id, e); + + free(s->status_text); + s->status_text = t; + } else { + free(s->status_text); + s->status_text = NULL; + } + + } + if (strv_find(tags, "WATCHDOG=1")) { + log_debug_unit(u->id, + "%s: got WATCHDOG=1", u->id); + service_reset_watchdog(s); + } + + /* Notify clients about changed status or main pid */ + unit_add_to_dbus_queue(u); +} + +#ifdef HAVE_SYSV_COMPAT + +static int service_enumerate(Manager *m) { + char **p; + unsigned i; + DIR *d = NULL; + char *path = NULL, *fpath = NULL, *name = NULL; + Set *runlevel_services[ELEMENTSOF(rcnd_table)], *shutdown_services = NULL; + Unit *service; + Iterator j; + int r; + + assert(m); + + if (m->running_as != SYSTEMD_SYSTEM) + return 0; + + zero(runlevel_services); + + STRV_FOREACH(p, m->lookup_paths.sysvrcnd_path) + for (i = 0; i < ELEMENTSOF(rcnd_table); i ++) { + struct dirent *de; + + free(path); + path = strjoin(*p, "/", rcnd_table[i].path, NULL); + if (!path) { + r = -ENOMEM; + goto finish; + } + + if (d) + closedir(d); + + if (!(d = opendir(path))) { + if (errno != ENOENT) + log_warning("opendir() failed on %s: %s", path, strerror(errno)); + + continue; + } + + while ((de = readdir(d))) { + int a, b; + + if (ignore_file(de->d_name)) + continue; + + if (de->d_name[0] != 'S' && de->d_name[0] != 'K') + continue; + + if (strlen(de->d_name) < 4) + continue; + + a = undecchar(de->d_name[1]); + b = undecchar(de->d_name[2]); + + if (a < 0 || b < 0) + continue; + + free(fpath); + fpath = strjoin(path, "/", de->d_name, NULL); + if (!fpath) { + r = -ENOMEM; + goto finish; + } + + if (access(fpath, X_OK) < 0) { + + if (errno != ENOENT) + log_warning("access() failed on %s: %s", fpath, strerror(errno)); + + continue; + } + + free(name); + if (!(name = sysv_translate_name(de->d_name + 3))) { + r = -ENOMEM; + goto finish; + } + + r = manager_load_unit_prepare(m, name, NULL, NULL, &service); + if (r < 0) { + log_warning("Failed to prepare unit %s: %s", name, strerror(-r)); + continue; + } + + if (de->d_name[0] == 'S') { + + if (rcnd_table[i].type == RUNLEVEL_UP) { + SERVICE(service)->sysv_start_priority_from_rcnd = + MAX(a*10 + b, SERVICE(service)->sysv_start_priority_from_rcnd); + + SERVICE(service)->sysv_enabled = true; + } + + if ((r = set_ensure_allocated(&runlevel_services[i], trivial_hash_func, trivial_compare_func)) < 0) + goto finish; + + if ((r = set_put(runlevel_services[i], service)) < 0) + goto finish; + + } else if (de->d_name[0] == 'K' && + (rcnd_table[i].type == RUNLEVEL_DOWN)) { + + if ((r = set_ensure_allocated(&shutdown_services, trivial_hash_func, trivial_compare_func)) < 0) + goto finish; + + if ((r = set_put(shutdown_services, service)) < 0) + goto finish; + } + } + } + + /* Now we loaded all stubs and are aware of the lowest + start-up priority for all services, not let's actually load + the services, this will also tell us which services are + actually native now */ + manager_dispatch_load_queue(m); + + /* If this is a native service, rely on native ways to pull in + * a service, don't pull it in via sysv rcN.d links. */ + for (i = 0; i < ELEMENTSOF(rcnd_table); i ++) + SET_FOREACH(service, runlevel_services[i], j) { + service = unit_follow_merge(service); + + if (service->fragment_path) + continue; + + if ((r = unit_add_two_dependencies_by_name_inverse(service, UNIT_AFTER, UNIT_WANTS, rcnd_table[i].target, NULL, true)) < 0) + goto finish; + } + + /* We honour K links only for halt/reboot. For the normal + * runlevels we assume the stop jobs will be implicitly added + * by the core logic. Also, we don't really distinguish here + * between the runlevels 0 and 6 and just add them to the + * special shutdown target. */ + SET_FOREACH(service, shutdown_services, j) { + service = unit_follow_merge(service); + + if (service->fragment_path) + continue; + + if ((r = unit_add_two_dependencies_by_name(service, UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true)) < 0) + goto finish; + } + + r = 0; + +finish: + free(path); + free(fpath); + free(name); + + for (i = 0; i < ELEMENTSOF(rcnd_table); i++) + set_free(runlevel_services[i]); + set_free(shutdown_services); + + if (d) + closedir(d); + + return r; +} +#endif + +static void service_bus_name_owner_change( + Unit *u, + const char *name, + const char *old_owner, + const char *new_owner) { + + Service *s = SERVICE(u); + + assert(s); + assert(name); + + assert(streq(s->bus_name, name)); + assert(old_owner || new_owner); + + if (old_owner && new_owner) + log_debug_unit(u->id, + "%s's D-Bus name %s changed owner from %s to %s", + u->id, name, old_owner, new_owner); + else if (old_owner) + log_debug_unit(u->id, + "%s's D-Bus name %s no longer registered by %s", + u->id, name, old_owner); + else + log_debug_unit(u->id, + "%s's D-Bus name %s now registered by %s", + u->id, name, new_owner); + + s->bus_name_good = !!new_owner; + + if (s->type == SERVICE_DBUS) { + + /* service_enter_running() will figure out what to + * do */ + if (s->state == SERVICE_RUNNING) + service_enter_running(s, SERVICE_SUCCESS); + else if (s->state == SERVICE_START && new_owner) + service_enter_start_post(s); + + } else if (new_owner && + s->main_pid <= 0 && + (s->state == SERVICE_START || + s->state == SERVICE_START_POST || + s->state == SERVICE_RUNNING || + s->state == SERVICE_RELOAD)) { + + /* Try to acquire PID from bus service */ + log_debug_unit(u->id, + "Trying to acquire PID from D-Bus name..."); + + bus_query_pid(u->manager, name); + } +} + +static void service_bus_query_pid_done( + Unit *u, + const char *name, + pid_t pid) { + + Service *s = SERVICE(u); + + assert(s); + assert(name); + + log_debug_unit(u->id, + "%s's D-Bus name %s is now owned by process %u", + u->id, name, (unsigned) pid); + + if (s->main_pid <= 0 && + (s->state == SERVICE_START || + s->state == SERVICE_START_POST || + s->state == SERVICE_RUNNING || + s->state == SERVICE_RELOAD)) + service_set_main_pid(s, pid); +} + +int service_set_socket_fd(Service *s, int fd, Socket *sock) { + + assert(s); + assert(fd >= 0); + + /* This is called by the socket code when instantiating a new + * service for a stream socket and the socket needs to be + * configured. */ + + if (UNIT(s)->load_state != UNIT_LOADED) + return -EINVAL; + + if (s->socket_fd >= 0) + return -EBUSY; + + if (s->state != SERVICE_DEAD) + return -EAGAIN; + + s->socket_fd = fd; + s->got_socket_fd = true; + + unit_ref_set(&s->accept_socket, UNIT(sock)); + + return unit_add_two_dependencies(UNIT(sock), UNIT_BEFORE, UNIT_TRIGGERS, UNIT(s), false); +} + +static void service_reset_failed(Unit *u) { + Service *s = SERVICE(u); + + assert(s); + + if (s->state == SERVICE_FAILED) + service_set_state(s, SERVICE_DEAD); + + s->result = SERVICE_SUCCESS; + s->reload_result = SERVICE_SUCCESS; + + RATELIMIT_RESET(s->start_limit); +} + +static int service_kill(Unit *u, KillWho who, int signo, DBusError *error) { + Service *s = SERVICE(u); + int r = 0; + Set *pid_set = NULL; + + assert(s); + + if (s->main_pid <= 0 && who == KILL_MAIN) { + dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "No main process to kill"); + return -ESRCH; + } + + if (s->control_pid <= 0 && who == KILL_CONTROL) { + dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "No control process to kill"); + return -ESRCH; + } + + if (who == KILL_CONTROL || who == KILL_ALL) + if (s->control_pid > 0) + if (kill(s->control_pid, signo) < 0) + r = -errno; + + if (who == KILL_MAIN || who == KILL_ALL) + if (s->main_pid > 0) + if (kill(s->main_pid, signo) < 0) + r = -errno; + + if (who == KILL_ALL) { + int q; + + pid_set = set_new(trivial_hash_func, trivial_compare_func); + if (!pid_set) + return -ENOMEM; + + /* Exclude the control/main pid from being killed via the cgroup */ + if (s->control_pid > 0) { + q = set_put(pid_set, LONG_TO_PTR(s->control_pid)); + if (q < 0) { + r = q; + goto finish; + } + } + + if (s->main_pid > 0) { + q = set_put(pid_set, LONG_TO_PTR(s->main_pid)); + if (q < 0) { + r = q; + goto finish; + } + } + + q = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, signo, false, false, pid_set, NULL); + if (q < 0 && q != -EAGAIN && q != -ESRCH && q != -ENOENT) + r = q; + } + +finish: + if (pid_set) + set_free(pid_set); + + return r; +} + +static const char* const service_state_table[_SERVICE_STATE_MAX] = { + [SERVICE_DEAD] = "dead", + [SERVICE_START_PRE] = "start-pre", + [SERVICE_START] = "start", + [SERVICE_START_POST] = "start-post", + [SERVICE_RUNNING] = "running", + [SERVICE_EXITED] = "exited", + [SERVICE_RELOAD] = "reload", + [SERVICE_STOP] = "stop", + [SERVICE_STOP_SIGTERM] = "stop-sigterm", + [SERVICE_STOP_SIGKILL] = "stop-sigkill", + [SERVICE_STOP_POST] = "stop-post", + [SERVICE_FINAL_SIGTERM] = "final-sigterm", + [SERVICE_FINAL_SIGKILL] = "final-sigkill", + [SERVICE_FAILED] = "failed", + [SERVICE_AUTO_RESTART] = "auto-restart", +}; + +DEFINE_STRING_TABLE_LOOKUP(service_state, ServiceState); + +static const char* const service_restart_table[_SERVICE_RESTART_MAX] = { + [SERVICE_RESTART_NO] = "no", + [SERVICE_RESTART_ON_SUCCESS] = "on-success", + [SERVICE_RESTART_ON_FAILURE] = "on-failure", + [SERVICE_RESTART_ON_ABORT] = "on-abort", + [SERVICE_RESTART_ALWAYS] = "always" +}; + +DEFINE_STRING_TABLE_LOOKUP(service_restart, ServiceRestart); + +static const char* const service_type_table[_SERVICE_TYPE_MAX] = { + [SERVICE_SIMPLE] = "simple", + [SERVICE_FORKING] = "forking", + [SERVICE_ONESHOT] = "oneshot", + [SERVICE_DBUS] = "dbus", + [SERVICE_NOTIFY] = "notify", + [SERVICE_IDLE] = "idle" +}; + +DEFINE_STRING_TABLE_LOOKUP(service_type, ServiceType); + +static const char* const service_exec_command_table[_SERVICE_EXEC_COMMAND_MAX] = { + [SERVICE_EXEC_START_PRE] = "ExecStartPre", + [SERVICE_EXEC_START] = "ExecStart", + [SERVICE_EXEC_START_POST] = "ExecStartPost", + [SERVICE_EXEC_RELOAD] = "ExecReload", + [SERVICE_EXEC_STOP] = "ExecStop", + [SERVICE_EXEC_STOP_POST] = "ExecStopPost", +}; + +DEFINE_STRING_TABLE_LOOKUP(service_exec_command, ServiceExecCommand); + +static const char* const notify_access_table[_NOTIFY_ACCESS_MAX] = { + [NOTIFY_NONE] = "none", + [NOTIFY_MAIN] = "main", + [NOTIFY_ALL] = "all" +}; + +DEFINE_STRING_TABLE_LOOKUP(notify_access, NotifyAccess); + +static const char* const service_result_table[_SERVICE_RESULT_MAX] = { + [SERVICE_SUCCESS] = "success", + [SERVICE_FAILURE_RESOURCES] = "resources", + [SERVICE_FAILURE_TIMEOUT] = "timeout", + [SERVICE_FAILURE_EXIT_CODE] = "exit-code", + [SERVICE_FAILURE_SIGNAL] = "signal", + [SERVICE_FAILURE_CORE_DUMP] = "core-dump", + [SERVICE_FAILURE_WATCHDOG] = "watchdog", + [SERVICE_FAILURE_START_LIMIT] = "start-limit" +}; + +DEFINE_STRING_TABLE_LOOKUP(service_result, ServiceResult); + +static const char* const start_limit_action_table[_SERVICE_START_LIMIT_MAX] = { + [SERVICE_START_LIMIT_NONE] = "none", + [SERVICE_START_LIMIT_REBOOT] = "reboot", + [SERVICE_START_LIMIT_REBOOT_FORCE] = "reboot-force", + [SERVICE_START_LIMIT_REBOOT_IMMEDIATE] = "reboot-immediate" +}; +DEFINE_STRING_TABLE_LOOKUP(start_limit_action, StartLimitAction); + +const UnitVTable service_vtable = { + .object_size = sizeof(Service), + .exec_context_offset = offsetof(Service, exec_context), + + .sections = + "Unit\0" + "Service\0" + "Install\0", + + .init = service_init, + .done = service_done, + .load = service_load, + + .coldplug = service_coldplug, + + .dump = service_dump, + + .start = service_start, + .stop = service_stop, + .reload = service_reload, + + .can_reload = service_can_reload, + + .kill = service_kill, + + .serialize = service_serialize, + .deserialize_item = service_deserialize_item, + + .active_state = service_active_state, + .sub_state_to_string = service_sub_state_to_string, + + .check_gc = service_check_gc, + .check_snapshot = service_check_snapshot, + + .sigchld_event = service_sigchld_event, + .timer_event = service_timer_event, + .fd_event = service_fd_event, + + .reset_failed = service_reset_failed, + + .cgroup_notify_empty = service_cgroup_notify_event, + .notify_message = service_notify_message, + + .bus_name_owner_change = service_bus_name_owner_change, + .bus_query_pid_done = service_bus_query_pid_done, + + .bus_interface = "org.freedesktop.systemd1.Service", + .bus_message_handler = bus_service_message_handler, + .bus_invalidating_properties = bus_service_invalidating_properties, + +#ifdef HAVE_SYSV_COMPAT + .enumerate = service_enumerate, +#endif + .status_message_formats = { + .starting_stopping = { + [0] = "Starting %s...", + [1] = "Stopping %s...", + }, + .finished_start_job = { + [JOB_DONE] = "Started %s.", + [JOB_FAILED] = "Failed to start %s.", + [JOB_DEPENDENCY] = "Dependency failed for %s.", + [JOB_TIMEOUT] = "Timed out starting %s.", + }, + .finished_stop_job = { + [JOB_DONE] = "Stopped %s.", + [JOB_FAILED] = "Stopped (with error) %s.", + [JOB_TIMEOUT] = "Timed out stopping %s.", + }, + }, +}; diff --git a/src/core/service.h b/src/core/service.h new file mode 100644 index 000000000..d1e53bf72 --- /dev/null +++ b/src/core/service.h @@ -0,0 +1,225 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +typedef struct Service Service; + +#include "unit.h" +#include "path.h" +#include "ratelimit.h" +#include "service.h" +#include "kill.h" +#include "exit-status.h" + +typedef enum ServiceState { + SERVICE_DEAD, + SERVICE_START_PRE, + SERVICE_START, + SERVICE_START_POST, + SERVICE_RUNNING, + SERVICE_EXITED, /* Nothing is running anymore, but RemainAfterExit is true hence this is OK */ + SERVICE_RELOAD, + SERVICE_STOP, /* No STOP_PRE state, instead just register multiple STOP executables */ + SERVICE_STOP_SIGTERM, + SERVICE_STOP_SIGKILL, + SERVICE_STOP_POST, + SERVICE_FINAL_SIGTERM, /* In case the STOP_POST executable hangs, we shoot that down, too */ + SERVICE_FINAL_SIGKILL, + SERVICE_FAILED, + SERVICE_AUTO_RESTART, + _SERVICE_STATE_MAX, + _SERVICE_STATE_INVALID = -1 +} ServiceState; + +typedef enum ServiceRestart { + SERVICE_RESTART_NO, + SERVICE_RESTART_ON_SUCCESS, + SERVICE_RESTART_ON_FAILURE, + SERVICE_RESTART_ON_ABORT, + SERVICE_RESTART_ALWAYS, + _SERVICE_RESTART_MAX, + _SERVICE_RESTART_INVALID = -1 +} ServiceRestart; + +typedef enum ServiceType { + SERVICE_SIMPLE, /* we fork and go on right-away (i.e. modern socket activated daemons) */ + SERVICE_FORKING, /* forks by itself (i.e. traditional daemons) */ + SERVICE_ONESHOT, /* we fork and wait until the program finishes (i.e. programs like fsck which run and need to finish before we continue) */ + SERVICE_DBUS, /* we fork and wait until a specific D-Bus name appears on the bus */ + SERVICE_NOTIFY, /* we fork and wait until a daemon sends us a ready message with sd_notify() */ + SERVICE_IDLE, /* much like simple, but delay exec() until all jobs are dispatched. */ + _SERVICE_TYPE_MAX, + _SERVICE_TYPE_INVALID = -1 +} ServiceType; + +typedef enum ServiceExecCommand { + SERVICE_EXEC_START_PRE, + SERVICE_EXEC_START, + SERVICE_EXEC_START_POST, + SERVICE_EXEC_RELOAD, + SERVICE_EXEC_STOP, + SERVICE_EXEC_STOP_POST, + _SERVICE_EXEC_COMMAND_MAX, + _SERVICE_EXEC_COMMAND_INVALID = -1 +} ServiceExecCommand; + +typedef enum NotifyAccess { + NOTIFY_NONE, + NOTIFY_ALL, + NOTIFY_MAIN, + _NOTIFY_ACCESS_MAX, + _NOTIFY_ACCESS_INVALID = -1 +} NotifyAccess; + +typedef enum ServiceResult { + SERVICE_SUCCESS, + SERVICE_FAILURE_RESOURCES, + SERVICE_FAILURE_TIMEOUT, + SERVICE_FAILURE_EXIT_CODE, + SERVICE_FAILURE_SIGNAL, + SERVICE_FAILURE_CORE_DUMP, + SERVICE_FAILURE_WATCHDOG, + SERVICE_FAILURE_START_LIMIT, + _SERVICE_RESULT_MAX, + _SERVICE_RESULT_INVALID = -1 +} ServiceResult; + +typedef enum StartLimitAction { + SERVICE_START_LIMIT_NONE, + SERVICE_START_LIMIT_REBOOT, + SERVICE_START_LIMIT_REBOOT_FORCE, + SERVICE_START_LIMIT_REBOOT_IMMEDIATE, + _SERVICE_START_LIMIT_MAX, + _SERVICE_START_LIMIT_INVALID = -1 +} StartLimitAction; + +struct Service { + Unit meta; + + ServiceType type; + ServiceRestart restart; + ExitStatusSet restart_ignore_status; + ExitStatusSet success_status; + + /* If set we'll read the main daemon PID from this file */ + char *pid_file; + + usec_t restart_usec; + usec_t timeout_start_usec; + usec_t timeout_stop_usec; + + dual_timestamp watchdog_timestamp; + usec_t watchdog_usec; + Watch watchdog_watch; + + ExecCommand* exec_command[_SERVICE_EXEC_COMMAND_MAX]; + + ExecContext exec_context; + KillContext kill_context; + + ServiceState state, deserialized_state; + + /* The exit status of the real main process */ + ExecStatus main_exec_status; + + /* The currently executed control process */ + ExecCommand *control_command; + + /* The currently executed main process, which may be NULL if + * the main process got started via forking mode and not by + * us */ + ExecCommand *main_command; + + /* The ID of the control command currently being executed */ + ServiceExecCommand control_command_id; + + pid_t main_pid, control_pid; + int socket_fd; + + int fsck_passno; + + bool permissions_start_only; + bool root_directory_start_only; + bool remain_after_exit; + bool guess_main_pid; + + /* If we shut down, remember why */ + ServiceResult result; + ServiceResult reload_result; + + bool main_pid_known:1; + bool main_pid_alien:1; + bool bus_name_good:1; + bool forbid_restart:1; + bool got_socket_fd:1; + bool start_timeout_defined:1; +#ifdef HAVE_SYSV_COMPAT + bool is_sysv:1; + bool sysv_has_lsb:1; + bool sysv_enabled:1; + int sysv_start_priority_from_rcnd; + int sysv_start_priority; + + char *sysv_runlevels; +#endif + + char *bus_name; + + char *status_text; + + RateLimit start_limit; + StartLimitAction start_limit_action; + + UnitRef accept_socket; + + Watch timer_watch; + PathSpec *pid_file_pathspec; + + NotifyAccess notify_access; +}; + +extern const UnitVTable service_vtable; + +struct Socket; + +int service_set_socket_fd(Service *s, int fd, struct Socket *socket); + +const char* service_state_to_string(ServiceState i); +ServiceState service_state_from_string(const char *s); + +const char* service_restart_to_string(ServiceRestart i); +ServiceRestart service_restart_from_string(const char *s); + +const char* service_type_to_string(ServiceType i); +ServiceType service_type_from_string(const char *s); + +const char* service_exec_command_to_string(ServiceExecCommand i); +ServiceExecCommand service_exec_command_from_string(const char *s); + +const char* notify_access_to_string(NotifyAccess i); +NotifyAccess notify_access_from_string(const char *s); + +const char* service_result_to_string(ServiceResult i); +ServiceResult service_result_from_string(const char *s); + +const char* start_limit_action_to_string(StartLimitAction i); +StartLimitAction start_limit_action_from_string(const char *s); diff --git a/src/core/shutdown.c b/src/core/shutdown.c new file mode 100644 index 000000000..0b0e0c3d4 --- /dev/null +++ b/src/core/shutdown.c @@ -0,0 +1,327 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 ProFUSION embedded systems + + 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "missing.h" +#include "log.h" +#include "umount.h" +#include "util.h" +#include "mkdir.h" +#include "virt.h" +#include "watchdog.h" +#include "killall.h" + +#define FINALIZE_ATTEMPTS 50 + +static int prepare_new_root(void) { + static const char dirs[] = + "/run/initramfs/oldroot\0" + "/run/initramfs/proc\0" + "/run/initramfs/sys\0" + "/run/initramfs/dev\0" + "/run/initramfs/run\0"; + + const char *dir; + + if (mount("/run/initramfs", "/run/initramfs", NULL, MS_BIND, NULL) < 0) { + log_error("Failed to mount bind /run/initramfs on /run/initramfs: %m"); + return -errno; + } + + if (mount(NULL, "/run/initramfs", NULL, MS_PRIVATE, NULL) < 0) { + log_error("Failed to make /run/initramfs private mount: %m"); + return -errno; + } + + NULSTR_FOREACH(dir, dirs) + if (mkdir_p_label(dir, 0755) < 0 && errno != EEXIST) { + log_error("Failed to mkdir %s: %m", dir); + return -errno; + } + + if (mount("/sys", "/run/initramfs/sys", NULL, MS_BIND, NULL) < 0) { + log_error("Failed to mount bind /sys on /run/initramfs/sys: %m"); + return -errno; + } + + if (mount("/proc", "/run/initramfs/proc", NULL, MS_BIND, NULL) < 0) { + log_error("Failed to mount bind /proc on /run/initramfs/proc: %m"); + return -errno; + } + + if (mount("/dev", "/run/initramfs/dev", NULL, MS_BIND, NULL) < 0) { + log_error("Failed to mount bind /dev on /run/initramfs/dev: %m"); + return -errno; + } + + if (mount("/run", "/run/initramfs/run", NULL, MS_BIND, NULL) < 0) { + log_error("Failed to mount bind /run on /run/initramfs/run: %m"); + return -errno; + } + + return 0; +} + +static int pivot_to_new_root(void) { + + if (chdir("/run/initramfs") < 0) { + log_error("Failed to change directory to /run/initramfs: %m"); + return -errno; + } + + /* Work-around for a kernel bug: for some reason the kernel + * refuses switching root if any file systems are mounted + * MS_SHARED. Hence remount them MS_PRIVATE here as a + * work-around. + * + * https://bugzilla.redhat.com/show_bug.cgi?id=847418 */ + if (mount(NULL, "/", NULL, MS_REC|MS_PRIVATE, NULL) < 0) + log_warning("Failed to make \"/\" private mount: %m"); + + if (pivot_root(".", "oldroot") < 0) { + log_error("pivot failed: %m"); + /* only chroot if pivot root succeeded */ + return -errno; + } + + chroot("."); + + setsid(); + make_console_stdio(); + + log_info("Successfully changed into root pivot."); + + return 0; +} + +int main(int argc, char *argv[]) { + int cmd, r; + unsigned retries; + bool need_umount = true, need_swapoff = true, need_loop_detach = true, need_dm_detach = true; + bool in_container, use_watchdog = false; + char *arguments[3]; + + log_parse_environment(); + log_set_target(LOG_TARGET_CONSOLE); /* syslog will die if not gone yet */ + log_open(); + + umask(0022); + + if (getpid() != 1) { + log_error("Not executed by init (pid 1)."); + r = -EPERM; + goto error; + } + + if (argc != 2) { + log_error("Invalid number of arguments."); + r = -EINVAL; + goto error; + } + + in_container = detect_container(NULL) > 0; + + if (streq(argv[1], "reboot")) + cmd = RB_AUTOBOOT; + else if (streq(argv[1], "poweroff")) + cmd = RB_POWER_OFF; + else if (streq(argv[1], "halt")) + cmd = RB_HALT_SYSTEM; + else if (streq(argv[1], "kexec")) + cmd = LINUX_REBOOT_CMD_KEXEC; + else { + log_error("Unknown action '%s'.", argv[1]); + r = -EINVAL; + goto error; + } + + use_watchdog = !!getenv("WATCHDOG_USEC"); + + /* lock us into memory */ + mlockall(MCL_CURRENT|MCL_FUTURE); + + log_info("Sending SIGTERM to remaining processes..."); + broadcast_signal(SIGTERM, true); + + log_info("Sending SIGKILL to remaining processes..."); + broadcast_signal(SIGKILL, true); + + if (in_container) { + need_swapoff = false; + need_dm_detach = false; + need_loop_detach = false; + } + + /* Unmount all mountpoints, swaps, and loopback devices */ + for (retries = 0; retries < FINALIZE_ATTEMPTS; retries++) { + bool changed = false; + + if (use_watchdog) + watchdog_ping(); + + if (need_umount) { + log_info("Unmounting file systems."); + r = umount_all(&changed); + if (r == 0) { + need_umount = false; + log_info("All filesystems unmounted."); + } else if (r > 0) + log_info("Not all file systems unmounted, %d left.", r); + else + log_error("Failed to unmount file systems: %s", strerror(-r)); + } + + if (need_swapoff) { + log_info("Deactivating swaps."); + r = swapoff_all(&changed); + if (r == 0) { + need_swapoff = false; + log_info("All swaps deactivated."); + } else if (r > 0) + log_info("Not all swaps deactivated, %d left.", r); + else + log_error("Failed to deactivate swaps: %s", strerror(-r)); + } + + if (need_loop_detach) { + log_info("Detaching loop devices."); + r = loopback_detach_all(&changed); + if (r == 0) { + need_loop_detach = false; + log_info("All loop devices detached."); + } else if (r > 0) + log_info("Not all loop devices detached, %d left.", r); + else + log_error("Failed to detach loop devices: %s", strerror(-r)); + } + + if (need_dm_detach) { + log_info("Detaching DM devices."); + r = dm_detach_all(&changed); + if (r == 0) { + need_dm_detach = false; + log_info("All DM devices detached."); + } else if (r > 0) + log_info("Not all DM devices detached, %d left.", r); + else + log_error("Failed to detach DM devices: %s", strerror(-r)); + } + + if (!need_umount && !need_swapoff && !need_loop_detach && !need_dm_detach) { + if (retries > 0) + log_info("All filesystems, swaps, loop devices, DM devices detached."); + /* Yay, done */ + break; + } + + /* If in this iteration we didn't manage to + * unmount/deactivate anything, we simply give up */ + if (!changed) { + log_error("Cannot finalize remaining file systems and devices, giving up."); + break; + } + + log_debug("Couldn't finalize remaining file systems and devices after %u retries, trying again.", retries+1); + } + + if (retries >= FINALIZE_ATTEMPTS) + log_error("Too many iterations, giving up."); + + arguments[0] = NULL; + arguments[1] = argv[1]; + arguments[2] = NULL; + execute_directory(SYSTEM_SHUTDOWN_PATH, NULL, arguments); + + if (!in_container && !in_initrd() && + access("/run/initramfs/shutdown", X_OK) == 0) { + + if (prepare_new_root() >= 0 && + pivot_to_new_root() >= 0) { + execv("/shutdown", argv); + log_error("Failed to execute shutdown binary: %m"); + } + } + + /* The kernel will automaticall flush ATA disks and suchlike + * on reboot(), but the file systems need to be synce'd + * explicitly in advance. So let's do this here, but not + * needlessly slow down containers. */ + if (!in_container) + sync(); + + if (cmd == LINUX_REBOOT_CMD_KEXEC) { + + if (!in_container) { + /* We cheat and exec kexec to avoid doing all its work */ + pid_t pid = fork(); + + if (pid < 0) + log_error("Could not fork: %m. Falling back to normal reboot."); + else if (pid > 0) { + wait_for_terminate_and_warn("kexec", pid); + log_warning("kexec failed. Falling back to normal reboot."); + } else { + /* Child */ + const char *args[3] = { "/sbin/kexec", "-e", NULL }; + execv(args[0], (char * const *) args); + return EXIT_FAILURE; + } + } + + cmd = RB_AUTOBOOT; + } + + reboot(cmd); + + if (errno == EPERM && in_container) { + /* If we are in a container, and we lacked + * CAP_SYS_BOOT just exit, this will kill our + * container for good. */ + log_error("Exiting container."); + exit(0); + } + + log_error("Failed to invoke reboot(): %m"); + r = -errno; + + error: + log_error("Critical error while doing system shutdown: %s", strerror(-r)); + + freeze(); + return EXIT_FAILURE; +} diff --git a/src/core/snapshot.c b/src/core/snapshot.c new file mode 100644 index 000000000..5c2a319cb --- /dev/null +++ b/src/core/snapshot.c @@ -0,0 +1,308 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include + +#include "unit.h" +#include "snapshot.h" +#include "unit-name.h" +#include "dbus-snapshot.h" +#include "bus-errors.h" + +static const UnitActiveState state_translation_table[_SNAPSHOT_STATE_MAX] = { + [SNAPSHOT_DEAD] = UNIT_INACTIVE, + [SNAPSHOT_ACTIVE] = UNIT_ACTIVE +}; + +static void snapshot_init(Unit *u) { + Snapshot *s = SNAPSHOT(u); + + assert(s); + assert(UNIT(s)->load_state == UNIT_STUB); + + UNIT(s)->ignore_on_isolate = true; + UNIT(s)->ignore_on_snapshot = true; +} + +static void snapshot_set_state(Snapshot *s, SnapshotState state) { + SnapshotState old_state; + assert(s); + + old_state = s->state; + s->state = state; + + if (state != old_state) + log_debug("%s changed %s -> %s", + UNIT(s)->id, + snapshot_state_to_string(old_state), + snapshot_state_to_string(state)); + + unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state], true); +} + +static int snapshot_load(Unit *u) { + Snapshot *s = SNAPSHOT(u); + + assert(u); + assert(u->load_state == UNIT_STUB); + + /* Make sure that only snapshots created via snapshot_create() + * can be loaded */ + if (!s->by_snapshot_create && UNIT(s)->manager->n_reloading <= 0) + return -ENOENT; + + u->load_state = UNIT_LOADED; + return 0; +} + +static int snapshot_coldplug(Unit *u) { + Snapshot *s = SNAPSHOT(u); + + assert(s); + assert(s->state == SNAPSHOT_DEAD); + + if (s->deserialized_state != s->state) + snapshot_set_state(s, s->deserialized_state); + + return 0; +} + +static void snapshot_dump(Unit *u, FILE *f, const char *prefix) { + Snapshot *s = SNAPSHOT(u); + + assert(s); + assert(f); + + fprintf(f, + "%sSnapshot State: %s\n" + "%sClean Up: %s\n", + prefix, snapshot_state_to_string(s->state), + prefix, yes_no(s->cleanup)); +} + +static int snapshot_start(Unit *u) { + Snapshot *s = SNAPSHOT(u); + + assert(s); + assert(s->state == SNAPSHOT_DEAD); + + snapshot_set_state(s, SNAPSHOT_ACTIVE); + + if (s->cleanup) + unit_add_to_cleanup_queue(u); + + return 0; +} + +static int snapshot_stop(Unit *u) { + Snapshot *s = SNAPSHOT(u); + + assert(s); + assert(s->state == SNAPSHOT_ACTIVE); + + snapshot_set_state(s, SNAPSHOT_DEAD); + return 0; +} + +static int snapshot_serialize(Unit *u, FILE *f, FDSet *fds) { + Snapshot *s = SNAPSHOT(u); + Unit *other; + Iterator i; + + assert(s); + assert(f); + assert(fds); + + unit_serialize_item(u, f, "state", snapshot_state_to_string(s->state)); + unit_serialize_item(u, f, "cleanup", yes_no(s->cleanup)); + SET_FOREACH(other, u->dependencies[UNIT_WANTS], i) + unit_serialize_item(u, f, "wants", other->id); + + return 0; +} + +static int snapshot_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) { + Snapshot *s = SNAPSHOT(u); + int r; + + assert(u); + assert(key); + assert(value); + assert(fds); + + if (streq(key, "state")) { + SnapshotState state; + + if ((state = snapshot_state_from_string(value)) < 0) + log_debug("Failed to parse state value %s", value); + else + s->deserialized_state = state; + + } else if (streq(key, "cleanup")) { + + if ((r = parse_boolean(value)) < 0) + log_debug("Failed to parse cleanup value %s", value); + else + s->cleanup = r; + + } else if (streq(key, "wants")) { + + if ((r = unit_add_two_dependencies_by_name(u, UNIT_AFTER, UNIT_WANTS, value, NULL, true)) < 0) + return r; + } else + log_debug("Unknown serialization key '%s'", key); + + return 0; +} + +static UnitActiveState snapshot_active_state(Unit *u) { + assert(u); + + return state_translation_table[SNAPSHOT(u)->state]; +} + +static const char *snapshot_sub_state_to_string(Unit *u) { + assert(u); + + return snapshot_state_to_string(SNAPSHOT(u)->state); +} + +int snapshot_create(Manager *m, const char *name, bool cleanup, DBusError *e, Snapshot **_s) { + Iterator i; + Unit *other, *u = NULL; + char *n = NULL; + int r; + const char *k; + + assert(m); + assert(_s); + + if (name) { + if (!unit_name_is_valid(name, false)) { + dbus_set_error(e, BUS_ERROR_INVALID_NAME, "Unit name %s is not valid.", name); + return -EINVAL; + } + + if (unit_name_to_type(name) != UNIT_SNAPSHOT) { + dbus_set_error(e, BUS_ERROR_UNIT_TYPE_MISMATCH, "Unit name %s lacks snapshot suffix.", name); + return -EINVAL; + } + + if (manager_get_unit(m, name)) { + dbus_set_error(e, BUS_ERROR_UNIT_EXISTS, "Snapshot %s exists already.", name); + return -EEXIST; + } + + } else { + + for (;;) { + if (asprintf(&n, "snapshot-%u.snapshot", ++ m->n_snapshots) < 0) + return -ENOMEM; + + if (!manager_get_unit(m, n)) + break; + + free(n); + } + + name = n; + } + + r = manager_load_unit_prepare(m, name, NULL, e, &u); + free(n); + + if (r < 0) + goto fail; + + SNAPSHOT(u)->by_snapshot_create = true; + manager_dispatch_load_queue(m); + assert(u->load_state == UNIT_LOADED); + + HASHMAP_FOREACH_KEY(other, k, m->units, i) { + + if (other->ignore_on_snapshot) + continue; + + if (k != other->id) + continue; + + if (UNIT_VTABLE(other)->check_snapshot) + if (!UNIT_VTABLE(other)->check_snapshot(other)) + continue; + + if (!UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other))) + continue; + + if ((r = unit_add_two_dependencies(u, UNIT_AFTER, UNIT_WANTS, other, true)) < 0) + goto fail; + } + + SNAPSHOT(u)->cleanup = cleanup; + *_s = SNAPSHOT(u); + + return 0; + +fail: + if (u) + unit_add_to_cleanup_queue(u); + + return r; +} + +void snapshot_remove(Snapshot *s) { + assert(s); + + unit_add_to_cleanup_queue(UNIT(s)); +} + +static const char* const snapshot_state_table[_SNAPSHOT_STATE_MAX] = { + [SNAPSHOT_DEAD] = "dead", + [SNAPSHOT_ACTIVE] = "active" +}; + +DEFINE_STRING_TABLE_LOOKUP(snapshot_state, SnapshotState); + +const UnitVTable snapshot_vtable = { + .object_size = sizeof(Snapshot), + + .no_alias = true, + .no_instances = true, + .no_gc = true, + + .init = snapshot_init, + + .load = snapshot_load, + .coldplug = snapshot_coldplug, + + .dump = snapshot_dump, + + .start = snapshot_start, + .stop = snapshot_stop, + + .serialize = snapshot_serialize, + .deserialize_item = snapshot_deserialize_item, + + .active_state = snapshot_active_state, + .sub_state_to_string = snapshot_sub_state_to_string, + + .bus_interface = "org.freedesktop.systemd1.Snapshot", + .bus_message_handler = bus_snapshot_message_handler +}; diff --git a/src/core/snapshot.h b/src/core/snapshot.h new file mode 100644 index 000000000..9662d9316 --- /dev/null +++ b/src/core/snapshot.h @@ -0,0 +1,50 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +typedef struct Snapshot Snapshot; + +#include "unit.h" + +typedef enum SnapshotState { + SNAPSHOT_DEAD, + SNAPSHOT_ACTIVE, + _SNAPSHOT_STATE_MAX, + _SNAPSHOT_STATE_INVALID = -1 +} SnapshotState; + +struct Snapshot { + Unit meta; + + SnapshotState state, deserialized_state; + + bool cleanup; + bool by_snapshot_create:1; +}; + +extern const UnitVTable snapshot_vtable; + +int snapshot_create(Manager *m, const char *name, bool cleanup, DBusError *e, Snapshot **s); +void snapshot_remove(Snapshot *s); + +const char* snapshot_state_to_string(SnapshotState i); +SnapshotState snapshot_state_from_string(const char *s); diff --git a/src/core/socket.c b/src/core/socket.c new file mode 100644 index 000000000..fcbcdbe19 --- /dev/null +++ b/src/core/socket.c @@ -0,0 +1,2440 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_ATTR_XATTR_H +#include +#endif + +#include "unit.h" +#include "socket.h" +#include "netinet/tcp.h" +#include "log.h" +#include "load-dropin.h" +#include "load-fragment.h" +#include "strv.h" +#include "mkdir.h" +#include "path-util.h" +#include "unit-name.h" +#include "unit-printf.h" +#include "dbus-socket.h" +#include "missing.h" +#include "special.h" +#include "bus-errors.h" +#include "label.h" +#include "exit-status.h" +#include "def.h" + +static const UnitActiveState state_translation_table[_SOCKET_STATE_MAX] = { + [SOCKET_DEAD] = UNIT_INACTIVE, + [SOCKET_START_PRE] = UNIT_ACTIVATING, + [SOCKET_START_POST] = UNIT_ACTIVATING, + [SOCKET_LISTENING] = UNIT_ACTIVE, + [SOCKET_RUNNING] = UNIT_ACTIVE, + [SOCKET_STOP_PRE] = UNIT_DEACTIVATING, + [SOCKET_STOP_PRE_SIGTERM] = UNIT_DEACTIVATING, + [SOCKET_STOP_PRE_SIGKILL] = UNIT_DEACTIVATING, + [SOCKET_STOP_POST] = UNIT_DEACTIVATING, + [SOCKET_FINAL_SIGTERM] = UNIT_DEACTIVATING, + [SOCKET_FINAL_SIGKILL] = UNIT_DEACTIVATING, + [SOCKET_FAILED] = UNIT_FAILED +}; + +static void socket_init(Unit *u) { + Socket *s = SOCKET(u); + + assert(u); + assert(u->load_state == UNIT_STUB); + + s->backlog = SOMAXCONN; + s->timeout_usec = DEFAULT_TIMEOUT_USEC; + s->directory_mode = 0755; + s->socket_mode = 0666; + + s->max_connections = 64; + + s->priority = -1; + s->ip_tos = -1; + s->ip_ttl = -1; + s->mark = -1; + + exec_context_init(&s->exec_context); + s->exec_context.std_output = u->manager->default_std_output; + s->exec_context.std_error = u->manager->default_std_error; + kill_context_init(&s->kill_context); + + s->control_command_id = _SOCKET_EXEC_COMMAND_INVALID; +} + +static void socket_unwatch_control_pid(Socket *s) { + assert(s); + + if (s->control_pid <= 0) + return; + + unit_unwatch_pid(UNIT(s), s->control_pid); + s->control_pid = 0; +} + +static void socket_done(Unit *u) { + Socket *s = SOCKET(u); + SocketPort *p; + + assert(s); + + while ((p = s->ports)) { + LIST_REMOVE(SocketPort, port, s->ports, p); + + if (p->fd >= 0) { + unit_unwatch_fd(UNIT(s), &p->fd_watch); + close_nointr_nofail(p->fd); + } + + free(p->path); + free(p); + } + + exec_context_done(&s->exec_context); + exec_command_free_array(s->exec_command, _SOCKET_EXEC_COMMAND_MAX); + s->control_command = NULL; + + socket_unwatch_control_pid(s); + + unit_ref_unset(&s->service); + + free(s->tcp_congestion); + s->tcp_congestion = NULL; + + free(s->bind_to_device); + s->bind_to_device = NULL; + + free(s->smack); + free(s->smack_ip_in); + free(s->smack_ip_out); + + unit_unwatch_timer(u, &s->timer_watch); +} + +static int socket_instantiate_service(Socket *s) { + char *prefix, *name; + int r; + Unit *u; + + assert(s); + + /* This fills in s->service if it isn't filled in yet. For + * Accept=yes sockets we create the next connection service + * here. For Accept=no this is mostly a NOP since the service + * is figured out at load time anyway. */ + + if (UNIT_DEREF(s->service)) + return 0; + + assert(s->accept); + + if (!(prefix = unit_name_to_prefix(UNIT(s)->id))) + return -ENOMEM; + + r = asprintf(&name, "%s@%u.service", prefix, s->n_accepted); + free(prefix); + + if (r < 0) + return -ENOMEM; + + r = manager_load_unit(UNIT(s)->manager, name, NULL, NULL, &u); + free(name); + + if (r < 0) + return r; + +#ifdef HAVE_SYSV_COMPAT + if (SERVICE(u)->is_sysv) { + log_error("Using SysV services for socket activation is not supported. Refusing."); + return -ENOENT; + } +#endif + + u->no_gc = true; + unit_ref_set(&s->service, u); + + return unit_add_two_dependencies(UNIT(s), UNIT_BEFORE, UNIT_TRIGGERS, u, false); +} + +static bool have_non_accept_socket(Socket *s) { + SocketPort *p; + + assert(s); + + if (!s->accept) + return true; + + LIST_FOREACH(port, p, s->ports) { + + if (p->type != SOCKET_SOCKET) + return true; + + if (!socket_address_can_accept(&p->address)) + return true; + } + + return false; +} + +static int socket_verify(Socket *s) { + assert(s); + + if (UNIT(s)->load_state != UNIT_LOADED) + return 0; + + if (!s->ports) { + log_error_unit(UNIT(s)->id, + "%s lacks Listen setting. Refusing.", UNIT(s)->id); + return -EINVAL; + } + + if (s->accept && have_non_accept_socket(s)) { + log_error_unit(UNIT(s)->id, + "%s configured for accepting sockets, but sockets are non-accepting. Refusing.", + UNIT(s)->id); + return -EINVAL; + } + + if (s->accept && s->max_connections <= 0) { + log_error_unit(UNIT(s)->id, + "%s's MaxConnection setting too small. Refusing.", UNIT(s)->id); + return -EINVAL; + } + + if (s->accept && UNIT_DEREF(s->service)) { + log_error_unit(UNIT(s)->id, + "Explicit service configuration for accepting sockets not supported on %s. Refusing.", + UNIT(s)->id); + return -EINVAL; + } + + if (s->exec_context.pam_name && s->kill_context.kill_mode != KILL_CONTROL_GROUP) { + log_error_unit(UNIT(s)->id, + "%s has PAM enabled. Kill mode must be set to 'control-group'. Refusing.", + UNIT(s)->id); + return -EINVAL; + } + + return 0; +} + +static bool socket_needs_mount(Socket *s, const char *prefix) { + SocketPort *p; + + assert(s); + + LIST_FOREACH(port, p, s->ports) { + + if (p->type == SOCKET_SOCKET) { + if (socket_address_needs_mount(&p->address, prefix)) + return true; + } else if (p->type == SOCKET_FIFO || p->type == SOCKET_SPECIAL) { + if (path_startswith(p->path, prefix)) + return true; + } + } + + return false; +} + +int socket_add_one_mount_link(Socket *s, Mount *m) { + int r; + + assert(s); + assert(m); + + if (UNIT(s)->load_state != UNIT_LOADED || + UNIT(m)->load_state != UNIT_LOADED) + return 0; + + if (!socket_needs_mount(s, m->where)) + return 0; + + r = unit_add_two_dependencies(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, UNIT(m), true); + if (r < 0) + return r; + + return 0; +} + +static int socket_add_mount_links(Socket *s) { + Unit *other; + int r; + + assert(s); + + LIST_FOREACH(units_by_type, other, UNIT(s)->manager->units_by_type[UNIT_MOUNT]) { + r = socket_add_one_mount_link(s, MOUNT(other)); + if (r < 0) + return r; + } + + return 0; +} + +static int socket_add_device_link(Socket *s) { + char *t; + int r; + + assert(s); + + if (!s->bind_to_device) + return 0; + + if (asprintf(&t, "/sys/subsystem/net/devices/%s", s->bind_to_device) < 0) + return -ENOMEM; + + r = unit_add_node_link(UNIT(s), t, false); + free(t); + + return r; +} + +static int socket_add_default_dependencies(Socket *s) { + int r; + assert(s); + + if (UNIT(s)->manager->running_as == SYSTEMD_SYSTEM) { + if ((r = unit_add_dependency_by_name(UNIT(s), UNIT_BEFORE, SPECIAL_SOCKETS_TARGET, NULL, true)) < 0) + return r; + + if ((r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SYSINIT_TARGET, NULL, true)) < 0) + return r; + } + + return unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true); +} + +static bool socket_has_exec(Socket *s) { + unsigned i; + assert(s); + + for (i = 0; i < _SOCKET_EXEC_COMMAND_MAX; i++) + if (s->exec_command[i]) + return true; + + return false; +} + +static int socket_load(Unit *u) { + Socket *s = SOCKET(u); + int r; + + assert(u); + assert(u->load_state == UNIT_STUB); + + if ((r = unit_load_fragment_and_dropin(u)) < 0) + return r; + + /* This is a new unit? Then let's add in some extras */ + if (u->load_state == UNIT_LOADED) { + + if (have_non_accept_socket(s)) { + + if (!UNIT_DEREF(s->service)) { + Unit *x; + + r = unit_load_related_unit(u, ".service", &x); + if (r < 0) + return r; + + unit_ref_set(&s->service, x); + } + + r = unit_add_two_dependencies(u, UNIT_BEFORE, UNIT_TRIGGERS, UNIT_DEREF(s->service), true); + if (r < 0) + return r; + } + + if ((r = socket_add_mount_links(s)) < 0) + return r; + + if ((r = socket_add_device_link(s)) < 0) + return r; + + if (socket_has_exec(s)) + if ((r = unit_add_exec_dependencies(u, &s->exec_context)) < 0) + return r; + + if ((r = unit_add_default_cgroups(u)) < 0) + return r; + + if (UNIT(s)->default_dependencies) + if ((r = socket_add_default_dependencies(s)) < 0) + return r; + + r = unit_exec_context_defaults(u, &s->exec_context); + if (r < 0) + return r; + } + + return socket_verify(s); +} + +static const char* listen_lookup(int family, int type) { + + if (family == AF_NETLINK) + return "ListenNetlink"; + + if (type == SOCK_STREAM) + return "ListenStream"; + else if (type == SOCK_DGRAM) + return "ListenDatagram"; + else if (type == SOCK_SEQPACKET) + return "ListenSequentialPacket"; + + assert_not_reached("Unknown socket type"); + return NULL; +} + +static void socket_dump(Unit *u, FILE *f, const char *prefix) { + + SocketExecCommand c; + Socket *s = SOCKET(u); + SocketPort *p; + const char *prefix2; + char *p2; + + assert(s); + assert(f); + + p2 = strappend(prefix, "\t"); + prefix2 = p2 ? p2 : prefix; + + fprintf(f, + "%sSocket State: %s\n" + "%sResult: %s\n" + "%sBindIPv6Only: %s\n" + "%sBacklog: %u\n" + "%sSocketMode: %04o\n" + "%sDirectoryMode: %04o\n" + "%sKeepAlive: %s\n" + "%sFreeBind: %s\n" + "%sTransparent: %s\n" + "%sBroadcast: %s\n" + "%sPassCredentials: %s\n" + "%sPassSecurity: %s\n" + "%sTCPCongestion: %s\n", + prefix, socket_state_to_string(s->state), + prefix, socket_result_to_string(s->result), + prefix, socket_address_bind_ipv6_only_to_string(s->bind_ipv6_only), + prefix, s->backlog, + prefix, s->socket_mode, + prefix, s->directory_mode, + prefix, yes_no(s->keep_alive), + prefix, yes_no(s->free_bind), + prefix, yes_no(s->transparent), + prefix, yes_no(s->broadcast), + prefix, yes_no(s->pass_cred), + prefix, yes_no(s->pass_sec), + prefix, strna(s->tcp_congestion)); + + if (s->control_pid > 0) + fprintf(f, + "%sControl PID: %lu\n", + prefix, (unsigned long) s->control_pid); + + if (s->bind_to_device) + fprintf(f, + "%sBindToDevice: %s\n", + prefix, s->bind_to_device); + + if (s->accept) + fprintf(f, + "%sAccepted: %u\n" + "%sNConnections: %u\n" + "%sMaxConnections: %u\n", + prefix, s->n_accepted, + prefix, s->n_connections, + prefix, s->max_connections); + + if (s->priority >= 0) + fprintf(f, + "%sPriority: %i\n", + prefix, s->priority); + + if (s->receive_buffer > 0) + fprintf(f, + "%sReceiveBuffer: %zu\n", + prefix, s->receive_buffer); + + if (s->send_buffer > 0) + fprintf(f, + "%sSendBuffer: %zu\n", + prefix, s->send_buffer); + + if (s->ip_tos >= 0) + fprintf(f, + "%sIPTOS: %i\n", + prefix, s->ip_tos); + + if (s->ip_ttl >= 0) + fprintf(f, + "%sIPTTL: %i\n", + prefix, s->ip_ttl); + + if (s->pipe_size > 0) + fprintf(f, + "%sPipeSize: %zu\n", + prefix, s->pipe_size); + + if (s->mark >= 0) + fprintf(f, + "%sMark: %i\n", + prefix, s->mark); + + if (s->mq_maxmsg > 0) + fprintf(f, + "%sMessageQueueMaxMessages: %li\n", + prefix, s->mq_maxmsg); + + if (s->mq_msgsize > 0) + fprintf(f, + "%sMessageQueueMessageSize: %li\n", + prefix, s->mq_msgsize); + + if (s->smack) + fprintf(f, + "%sSmackLabel: %s\n", + prefix, s->smack); + + if (s->smack_ip_in) + fprintf(f, + "%sSmackLabelIPIn: %s\n", + prefix, s->smack_ip_in); + + if (s->smack_ip_out) + fprintf(f, + "%sSmackLabelIPOut: %s\n", + prefix, s->smack_ip_out); + + LIST_FOREACH(port, p, s->ports) { + + if (p->type == SOCKET_SOCKET) { + const char *t; + int r; + char *k = NULL; + + if ((r = socket_address_print(&p->address, &k)) < 0) + t = strerror(-r); + else + t = k; + + fprintf(f, "%s%s: %s\n", prefix, listen_lookup(socket_address_family(&p->address), p->address.type), t); + free(k); + } else if (p->type == SOCKET_SPECIAL) + fprintf(f, "%sListenSpecial: %s\n", prefix, p->path); + else if (p->type == SOCKET_MQUEUE) + fprintf(f, "%sListenMessageQueue: %s\n", prefix, p->path); + else + fprintf(f, "%sListenFIFO: %s\n", prefix, p->path); + } + + exec_context_dump(&s->exec_context, f, prefix); + kill_context_dump(&s->kill_context, f, prefix); + + for (c = 0; c < _SOCKET_EXEC_COMMAND_MAX; c++) { + if (!s->exec_command[c]) + continue; + + fprintf(f, "%s-> %s:\n", + prefix, socket_exec_command_to_string(c)); + + exec_command_dump_list(s->exec_command[c], f, prefix2); + } + + free(p2); +} + +static int instance_from_socket(int fd, unsigned nr, char **instance) { + socklen_t l; + char *r; + union { + struct sockaddr sa; + struct sockaddr_un un; + struct sockaddr_in in; + struct sockaddr_in6 in6; + struct sockaddr_storage storage; + } local, remote; + + assert(fd >= 0); + assert(instance); + + l = sizeof(local); + if (getsockname(fd, &local.sa, &l) < 0) + return -errno; + + l = sizeof(remote); + if (getpeername(fd, &remote.sa, &l) < 0) + return -errno; + + switch (local.sa.sa_family) { + + case AF_INET: { + uint32_t + a = ntohl(local.in.sin_addr.s_addr), + b = ntohl(remote.in.sin_addr.s_addr); + + if (asprintf(&r, + "%u-%u.%u.%u.%u:%u-%u.%u.%u.%u:%u", + nr, + a >> 24, (a >> 16) & 0xFF, (a >> 8) & 0xFF, a & 0xFF, + ntohs(local.in.sin_port), + b >> 24, (b >> 16) & 0xFF, (b >> 8) & 0xFF, b & 0xFF, + ntohs(remote.in.sin_port)) < 0) + return -ENOMEM; + + break; + } + + case AF_INET6: { + static const unsigned char ipv4_prefix[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF + }; + + if (memcmp(&local.in6.sin6_addr, ipv4_prefix, sizeof(ipv4_prefix)) == 0 && + memcmp(&remote.in6.sin6_addr, ipv4_prefix, sizeof(ipv4_prefix)) == 0) { + const uint8_t + *a = local.in6.sin6_addr.s6_addr+12, + *b = remote.in6.sin6_addr.s6_addr+12; + + if (asprintf(&r, + "%u-%u.%u.%u.%u:%u-%u.%u.%u.%u:%u", + nr, + a[0], a[1], a[2], a[3], + ntohs(local.in6.sin6_port), + b[0], b[1], b[2], b[3], + ntohs(remote.in6.sin6_port)) < 0) + return -ENOMEM; + } else { + char a[INET6_ADDRSTRLEN], b[INET6_ADDRSTRLEN]; + + if (asprintf(&r, + "%u-%s:%u-%s:%u", + nr, + inet_ntop(AF_INET6, &local.in6.sin6_addr, a, sizeof(a)), + ntohs(local.in6.sin6_port), + inet_ntop(AF_INET6, &remote.in6.sin6_addr, b, sizeof(b)), + ntohs(remote.in6.sin6_port)) < 0) + return -ENOMEM; + } + + break; + } + + case AF_UNIX: { + struct ucred ucred; + + l = sizeof(ucred); + if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &ucred, &l) < 0) + return -errno; + + if (asprintf(&r, + "%u-%lu-%lu", + nr, + (unsigned long) ucred.pid, + (unsigned long) ucred.uid) < 0) + return -ENOMEM; + + break; + } + + default: + assert_not_reached("Unhandled socket type."); + } + + *instance = r; + return 0; +} + +static void socket_close_fds(Socket *s) { + SocketPort *p; + + assert(s); + + LIST_FOREACH(port, p, s->ports) { + if (p->fd < 0) + continue; + + unit_unwatch_fd(UNIT(s), &p->fd_watch); + close_nointr_nofail(p->fd); + + /* One little note: we should never delete any sockets + * in the file system here! After all some other + * process we spawned might still have a reference of + * this fd and wants to continue to use it. Therefore + * we delete sockets in the file system before we + * create a new one, not after we stopped using + * one! */ + + p->fd = -1; + } +} + +static void socket_apply_socket_options(Socket *s, int fd) { + assert(s); + assert(fd >= 0); + + if (s->keep_alive) { + int b = s->keep_alive; + if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &b, sizeof(b)) < 0) + log_warning_unit(UNIT(s)->id, "SO_KEEPALIVE failed: %m"); + } + + if (s->broadcast) { + int one = 1; + if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &one, sizeof(one)) < 0) + log_warning_unit(UNIT(s)->id, "SO_BROADCAST failed: %m"); + } + + if (s->pass_cred) { + int one = 1; + if (setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one)) < 0) + log_warning_unit(UNIT(s)->id, "SO_PASSCRED failed: %m"); + } + + if (s->pass_sec) { + int one = 1; + if (setsockopt(fd, SOL_SOCKET, SO_PASSSEC, &one, sizeof(one)) < 0) + log_warning_unit(UNIT(s)->id, "SO_PASSSEC failed: %m"); + } + + if (s->priority >= 0) + if (setsockopt(fd, SOL_SOCKET, SO_PRIORITY, &s->priority, sizeof(s->priority)) < 0) + log_warning_unit(UNIT(s)->id, "SO_PRIORITY failed: %m"); + + if (s->receive_buffer > 0) { + int value = (int) s->receive_buffer; + + /* We first try with SO_RCVBUFFORCE, in case we have the perms for that */ + + if (setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE, &value, sizeof(value)) < 0) + if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, sizeof(value)) < 0) + log_warning_unit(UNIT(s)->id, "SO_RCVBUF failed: %m"); + } + + if (s->send_buffer > 0) { + int value = (int) s->send_buffer; + if (setsockopt(fd, SOL_SOCKET, SO_SNDBUFFORCE, &value, sizeof(value)) < 0) + if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, sizeof(value)) < 0) + log_warning_unit(UNIT(s)->id, "SO_SNDBUF failed: %m"); + } + + if (s->mark >= 0) + if (setsockopt(fd, SOL_SOCKET, SO_MARK, &s->mark, sizeof(s->mark)) < 0) + log_warning_unit(UNIT(s)->id, "SO_MARK failed: %m"); + + if (s->ip_tos >= 0) + if (setsockopt(fd, IPPROTO_IP, IP_TOS, &s->ip_tos, sizeof(s->ip_tos)) < 0) + log_warning_unit(UNIT(s)->id, "IP_TOS failed: %m"); + + if (s->ip_ttl >= 0) { + int r, x; + + r = setsockopt(fd, IPPROTO_IP, IP_TTL, &s->ip_ttl, sizeof(s->ip_ttl)); + + if (socket_ipv6_is_supported()) + x = setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &s->ip_ttl, sizeof(s->ip_ttl)); + else { + x = -1; + errno = EAFNOSUPPORT; + } + + if (r < 0 && x < 0) + log_warning_unit(UNIT(s)->id, + "IP_TTL/IPV6_UNICAST_HOPS failed: %m"); + } + + if (s->tcp_congestion) + if (setsockopt(fd, SOL_TCP, TCP_CONGESTION, s->tcp_congestion, strlen(s->tcp_congestion)+1) < 0) + log_warning_unit(UNIT(s)->id, "TCP_CONGESTION failed: %m"); + +#ifdef HAVE_ATTR_XATTR_H + if (s->smack_ip_in) + if (fsetxattr(fd, "security.SMACK64IPIN", s->smack_ip_in, strlen(s->smack_ip_in), 0) < 0) + log_error_unit(UNIT(s)->id, + "fsetxattr(\"security.SMACK64IPIN\"): %m"); + + if (s->smack_ip_out) + if (fsetxattr(fd, "security.SMACK64IPOUT", s->smack_ip_out, strlen(s->smack_ip_out), 0) < 0) + log_error_unit(UNIT(s)->id, + "fsetxattr(\"security.SMACK64IPOUT\"): %m"); +#endif +} + +static void socket_apply_fifo_options(Socket *s, int fd) { + assert(s); + assert(fd >= 0); + + if (s->pipe_size > 0) + if (fcntl(fd, F_SETPIPE_SZ, s->pipe_size) < 0) + log_warning_unit(UNIT(s)->id, + "F_SETPIPE_SZ: %m"); + +#ifdef HAVE_ATTR_XATTR_H + if (s->smack) + if (fsetxattr(fd, "security.SMACK64", s->smack, strlen(s->smack), 0) < 0) + log_error_unit(UNIT(s)->id, + "fsetxattr(\"security.SMACK64\"): %m"); +#endif +} + +static int fifo_address_create( + const char *path, + mode_t directory_mode, + mode_t socket_mode, + int *_fd) { + + int fd = -1, r = 0; + struct stat st; + mode_t old_mask; + + assert(path); + assert(_fd); + + mkdir_parents_label(path, directory_mode); + + r = label_context_set(path, S_IFIFO); + if (r < 0) + goto fail; + + /* Enforce the right access mode for the fifo */ + old_mask = umask(~ socket_mode); + + /* Include the original umask in our mask */ + umask(~socket_mode | old_mask); + + r = mkfifo(path, socket_mode); + umask(old_mask); + + if (r < 0 && errno != EEXIST) { + r = -errno; + goto fail; + } + + if ((fd = open(path, O_RDWR|O_CLOEXEC|O_NOCTTY|O_NONBLOCK|O_NOFOLLOW)) < 0) { + r = -errno; + goto fail; + } + + label_context_clear(); + + if (fstat(fd, &st) < 0) { + r = -errno; + goto fail; + } + + if (!S_ISFIFO(st.st_mode) || + (st.st_mode & 0777) != (socket_mode & ~old_mask) || + st.st_uid != getuid() || + st.st_gid != getgid()) { + + r = -EEXIST; + goto fail; + } + + *_fd = fd; + return 0; + +fail: + label_context_clear(); + + if (fd >= 0) + close_nointr_nofail(fd); + + return r; +} + +static int special_address_create( + const char *path, + int *_fd) { + + int fd = -1, r = 0; + struct stat st; + + assert(path); + assert(_fd); + + if ((fd = open(path, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NONBLOCK|O_NOFOLLOW)) < 0) { + r = -errno; + goto fail; + } + + if (fstat(fd, &st) < 0) { + r = -errno; + goto fail; + } + + /* Check whether this is a /proc, /sys or /dev file or char device */ + if (!S_ISREG(st.st_mode) && !S_ISCHR(st.st_mode)) { + r = -EEXIST; + goto fail; + } + + *_fd = fd; + return 0; + +fail: + if (fd >= 0) + close_nointr_nofail(fd); + + return r; +} + +static int mq_address_create( + const char *path, + mode_t mq_mode, + long maxmsg, + long msgsize, + int *_fd) { + + int fd = -1, r = 0; + struct stat st; + mode_t old_mask; + struct mq_attr _attr, *attr = NULL; + + assert(path); + assert(_fd); + + if (maxmsg > 0 && msgsize > 0) { + zero(_attr); + _attr.mq_flags = O_NONBLOCK; + _attr.mq_maxmsg = maxmsg; + _attr.mq_msgsize = msgsize; + attr = &_attr; + } + + /* Enforce the right access mode for the mq */ + old_mask = umask(~ mq_mode); + + /* Include the original umask in our mask */ + umask(~mq_mode | old_mask); + + fd = mq_open(path, O_RDONLY|O_CLOEXEC|O_NONBLOCK|O_CREAT, mq_mode, attr); + umask(old_mask); + + if (fd < 0) { + r = -errno; + goto fail; + } + + if (fstat(fd, &st) < 0) { + r = -errno; + goto fail; + } + + if ((st.st_mode & 0777) != (mq_mode & ~old_mask) || + st.st_uid != getuid() || + st.st_gid != getgid()) { + + r = -EEXIST; + goto fail; + } + + *_fd = fd; + return 0; + +fail: + if (fd >= 0) + close_nointr_nofail(fd); + + return r; +} + +static int socket_open_fds(Socket *s) { + SocketPort *p; + int r; + char *label = NULL; + bool know_label = false; + + assert(s); + + LIST_FOREACH(port, p, s->ports) { + + if (p->fd >= 0) + continue; + + if (p->type == SOCKET_SOCKET) { + + if (!know_label) { + + if ((r = socket_instantiate_service(s)) < 0) + return r; + + if (UNIT_DEREF(s->service) && + SERVICE(UNIT_DEREF(s->service))->exec_command[SERVICE_EXEC_START]) { + r = label_get_create_label_from_exe(SERVICE(UNIT_DEREF(s->service))->exec_command[SERVICE_EXEC_START]->path, &label); + + if (r < 0) { + if (r != -EPERM) + return r; + } + } + + know_label = true; + } + + if ((r = socket_address_listen( + &p->address, + s->backlog, + s->bind_ipv6_only, + s->bind_to_device, + s->free_bind, + s->transparent, + s->directory_mode, + s->socket_mode, + label, + &p->fd)) < 0) + goto rollback; + + socket_apply_socket_options(s, p->fd); + + } else if (p->type == SOCKET_SPECIAL) { + + if ((r = special_address_create( + p->path, + &p->fd)) < 0) + goto rollback; + + } else if (p->type == SOCKET_FIFO) { + + if ((r = fifo_address_create( + p->path, + s->directory_mode, + s->socket_mode, + &p->fd)) < 0) + goto rollback; + + socket_apply_fifo_options(s, p->fd); + } else if (p->type == SOCKET_MQUEUE) { + + if ((r = mq_address_create( + p->path, + s->socket_mode, + s->mq_maxmsg, + s->mq_msgsize, + &p->fd)) < 0) + goto rollback; + } else + assert_not_reached("Unknown port type"); + } + + label_free(label); + return 0; + +rollback: + socket_close_fds(s); + label_free(label); + return r; +} + +static void socket_unwatch_fds(Socket *s) { + SocketPort *p; + + assert(s); + + LIST_FOREACH(port, p, s->ports) { + if (p->fd < 0) + continue; + + unit_unwatch_fd(UNIT(s), &p->fd_watch); + } +} + +static int socket_watch_fds(Socket *s) { + SocketPort *p; + int r; + + assert(s); + + LIST_FOREACH(port, p, s->ports) { + if (p->fd < 0) + continue; + + p->fd_watch.socket_accept = + s->accept && + p->type == SOCKET_SOCKET && + socket_address_can_accept(&p->address); + + if ((r = unit_watch_fd(UNIT(s), p->fd, EPOLLIN, &p->fd_watch)) < 0) + goto fail; + } + + return 0; + +fail: + socket_unwatch_fds(s); + return r; +} + +static void socket_set_state(Socket *s, SocketState state) { + SocketState old_state; + assert(s); + + old_state = s->state; + s->state = state; + + if (state != SOCKET_START_PRE && + state != SOCKET_START_POST && + state != SOCKET_STOP_PRE && + state != SOCKET_STOP_PRE_SIGTERM && + state != SOCKET_STOP_PRE_SIGKILL && + state != SOCKET_STOP_POST && + state != SOCKET_FINAL_SIGTERM && + state != SOCKET_FINAL_SIGKILL) { + unit_unwatch_timer(UNIT(s), &s->timer_watch); + socket_unwatch_control_pid(s); + s->control_command = NULL; + s->control_command_id = _SOCKET_EXEC_COMMAND_INVALID; + } + + if (state != SOCKET_LISTENING) + socket_unwatch_fds(s); + + if (state != SOCKET_START_POST && + state != SOCKET_LISTENING && + state != SOCKET_RUNNING && + state != SOCKET_STOP_PRE && + state != SOCKET_STOP_PRE_SIGTERM && + state != SOCKET_STOP_PRE_SIGKILL) + socket_close_fds(s); + + if (state != old_state) + log_debug_unit(UNIT(s)->id, + "%s changed %s -> %s", UNIT(s)->id, + socket_state_to_string(old_state), + socket_state_to_string(state)); + + unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state], true); +} + +static int socket_coldplug(Unit *u) { + Socket *s = SOCKET(u); + int r; + + assert(s); + assert(s->state == SOCKET_DEAD); + + if (s->deserialized_state != s->state) { + + if (s->deserialized_state == SOCKET_START_PRE || + s->deserialized_state == SOCKET_START_POST || + s->deserialized_state == SOCKET_STOP_PRE || + s->deserialized_state == SOCKET_STOP_PRE_SIGTERM || + s->deserialized_state == SOCKET_STOP_PRE_SIGKILL || + s->deserialized_state == SOCKET_STOP_POST || + s->deserialized_state == SOCKET_FINAL_SIGTERM || + s->deserialized_state == SOCKET_FINAL_SIGKILL) { + + if (s->control_pid <= 0) + return -EBADMSG; + + r = unit_watch_pid(UNIT(s), s->control_pid); + if (r < 0) + return r; + + r = unit_watch_timer(UNIT(s), CLOCK_MONOTONIC, true, s->timeout_usec, &s->timer_watch); + if (r < 0) + return r; + } + + if (s->deserialized_state == SOCKET_START_POST || + s->deserialized_state == SOCKET_LISTENING || + s->deserialized_state == SOCKET_RUNNING || + s->deserialized_state == SOCKET_STOP_PRE || + s->deserialized_state == SOCKET_STOP_PRE_SIGTERM || + s->deserialized_state == SOCKET_STOP_PRE_SIGKILL) + if ((r = socket_open_fds(s)) < 0) + return r; + + if (s->deserialized_state == SOCKET_LISTENING) + if ((r = socket_watch_fds(s)) < 0) + return r; + + socket_set_state(s, s->deserialized_state); + } + + return 0; +} + +static int socket_spawn(Socket *s, ExecCommand *c, pid_t *_pid) { + pid_t pid; + int r; + char **argv; + + assert(s); + assert(c); + assert(_pid); + + r = unit_watch_timer(UNIT(s), CLOCK_MONOTONIC, true, s->timeout_usec, &s->timer_watch); + if (r < 0) + goto fail; + + argv = unit_full_printf_strv(UNIT(s), c->argv); + if (!argv) { + r = -ENOMEM; + goto fail; + } + + r = exec_spawn(c, + argv, + &s->exec_context, + NULL, 0, + UNIT(s)->manager->environment, + true, + true, + true, + UNIT(s)->manager->confirm_spawn, + UNIT(s)->cgroup_bondings, + UNIT(s)->cgroup_attributes, + NULL, + UNIT(s)->id, + NULL, + &pid); + + strv_free(argv); + if (r < 0) + goto fail; + + if ((r = unit_watch_pid(UNIT(s), pid)) < 0) + /* FIXME: we need to do something here */ + goto fail; + + *_pid = pid; + + return 0; + +fail: + unit_unwatch_timer(UNIT(s), &s->timer_watch); + + return r; +} + +static void socket_enter_dead(Socket *s, SocketResult f) { + assert(s); + + if (f != SOCKET_SUCCESS) + s->result = f; + + socket_set_state(s, s->result != SOCKET_SUCCESS ? SOCKET_FAILED : SOCKET_DEAD); +} + +static void socket_enter_signal(Socket *s, SocketState state, SocketResult f); + +static void socket_enter_stop_post(Socket *s, SocketResult f) { + int r; + assert(s); + + if (f != SOCKET_SUCCESS) + s->result = f; + + socket_unwatch_control_pid(s); + + s->control_command_id = SOCKET_EXEC_STOP_POST; + + if ((s->control_command = s->exec_command[SOCKET_EXEC_STOP_POST])) { + if ((r = socket_spawn(s, s->control_command, &s->control_pid)) < 0) + goto fail; + + socket_set_state(s, SOCKET_STOP_POST); + } else + socket_enter_signal(s, SOCKET_FINAL_SIGTERM, SOCKET_SUCCESS); + + return; + +fail: + log_warning_unit(UNIT(s)->id, + "%s failed to run 'stop-post' task: %s", + UNIT(s)->id, strerror(-r)); + socket_enter_signal(s, SOCKET_FINAL_SIGTERM, SOCKET_FAILURE_RESOURCES); +} + +static void socket_enter_signal(Socket *s, SocketState state, SocketResult f) { + int r; + Set *pid_set = NULL; + bool wait_for_exit = false; + + assert(s); + + if (f != SOCKET_SUCCESS) + s->result = f; + + if (s->kill_context.kill_mode != KILL_NONE) { + int sig = (state == SOCKET_STOP_PRE_SIGTERM || state == SOCKET_FINAL_SIGTERM) ? s->kill_context.kill_signal : SIGKILL; + + if (s->control_pid > 0) { + if (kill_and_sigcont(s->control_pid, sig) < 0 && errno != ESRCH) + + log_warning_unit(UNIT(s)->id, + "Failed to kill control process %li: %m", + (long) s->control_pid); + else + wait_for_exit = true; + } + + if (s->kill_context.kill_mode == KILL_CONTROL_GROUP) { + + if (!(pid_set = set_new(trivial_hash_func, trivial_compare_func))) { + r = -ENOMEM; + goto fail; + } + + /* Exclude the control pid from being killed via the cgroup */ + if (s->control_pid > 0) + if ((r = set_put(pid_set, LONG_TO_PTR(s->control_pid))) < 0) + goto fail; + + r = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, sig, true, false, pid_set, NULL); + if (r < 0) { + if (r != -EAGAIN && r != -ESRCH && r != -ENOENT) + log_warning_unit(UNIT(s)->id, + "Failed to kill control group: %s", + strerror(-r)); + } else if (r > 0) + wait_for_exit = true; + + set_free(pid_set); + pid_set = NULL; + } + } + + if (wait_for_exit) { + r = unit_watch_timer(UNIT(s), CLOCK_MONOTONIC, true, s->timeout_usec, &s->timer_watch); + if (r < 0) + goto fail; + + socket_set_state(s, state); + } else if (state == SOCKET_STOP_PRE_SIGTERM || state == SOCKET_STOP_PRE_SIGKILL) + socket_enter_stop_post(s, SOCKET_SUCCESS); + else + socket_enter_dead(s, SOCKET_SUCCESS); + + return; + +fail: + log_warning_unit(UNIT(s)->id, + "%s failed to kill processes: %s", + UNIT(s)->id, strerror(-r)); + + if (state == SOCKET_STOP_PRE_SIGTERM || state == SOCKET_STOP_PRE_SIGKILL) + socket_enter_stop_post(s, SOCKET_FAILURE_RESOURCES); + else + socket_enter_dead(s, SOCKET_FAILURE_RESOURCES); + + if (pid_set) + set_free(pid_set); +} + +static void socket_enter_stop_pre(Socket *s, SocketResult f) { + int r; + assert(s); + + if (f != SOCKET_SUCCESS) + s->result = f; + + socket_unwatch_control_pid(s); + + s->control_command_id = SOCKET_EXEC_STOP_PRE; + + if ((s->control_command = s->exec_command[SOCKET_EXEC_STOP_PRE])) { + if ((r = socket_spawn(s, s->control_command, &s->control_pid)) < 0) + goto fail; + + socket_set_state(s, SOCKET_STOP_PRE); + } else + socket_enter_stop_post(s, SOCKET_SUCCESS); + + return; + +fail: + log_warning_unit(UNIT(s)->id, + "%s failed to run 'stop-pre' task: %s", + UNIT(s)->id, strerror(-r)); + socket_enter_stop_post(s, SOCKET_FAILURE_RESOURCES); +} + +static void socket_enter_listening(Socket *s) { + int r; + assert(s); + + r = socket_watch_fds(s); + if (r < 0) { + log_warning_unit(UNIT(s)->id, + "%s failed to watch sockets: %s", + UNIT(s)->id, strerror(-r)); + goto fail; + } + + socket_set_state(s, SOCKET_LISTENING); + return; + +fail: + socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES); +} + +static void socket_enter_start_post(Socket *s) { + int r; + assert(s); + + r = socket_open_fds(s); + if (r < 0) { + log_warning_unit(UNIT(s)->id, + "%s failed to listen on sockets: %s", + UNIT(s)->id, strerror(-r)); + goto fail; + } + + socket_unwatch_control_pid(s); + + s->control_command_id = SOCKET_EXEC_START_POST; + + if ((s->control_command = s->exec_command[SOCKET_EXEC_START_POST])) { + r = socket_spawn(s, s->control_command, &s->control_pid); + if (r < 0) { + log_warning_unit(UNIT(s)->id, + "%s failed to run 'start-post' task: %s", + UNIT(s)->id, strerror(-r)); + goto fail; + } + + socket_set_state(s, SOCKET_START_POST); + } else + socket_enter_listening(s); + + return; + +fail: + socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES); +} + +static void socket_enter_start_pre(Socket *s) { + int r; + assert(s); + + socket_unwatch_control_pid(s); + + s->control_command_id = SOCKET_EXEC_START_PRE; + + if ((s->control_command = s->exec_command[SOCKET_EXEC_START_PRE])) { + if ((r = socket_spawn(s, s->control_command, &s->control_pid)) < 0) + goto fail; + + socket_set_state(s, SOCKET_START_PRE); + } else + socket_enter_start_post(s); + + return; + +fail: + log_warning_unit(UNIT(s)->id, + "%s failed to run 'start-pre' task: %s", + UNIT(s)->id, strerror(-r)); + socket_enter_dead(s, SOCKET_FAILURE_RESOURCES); +} + +static void socket_enter_running(Socket *s, int cfd) { + int r; + DBusError error; + + assert(s); + dbus_error_init(&error); + + /* We don't take connections anymore if we are supposed to + * shut down anyway */ + if (unit_pending_inactive(UNIT(s))) { + log_debug_unit(UNIT(s)->id, + "Suppressing connection request on %s since unit stop is scheduled.", + UNIT(s)->id); + + if (cfd >= 0) + close_nointr_nofail(cfd); + else { + /* Flush all sockets by closing and reopening them */ + socket_close_fds(s); + + r = socket_watch_fds(s); + if (r < 0) { + log_warning_unit(UNIT(s)->id, + "%s failed to watch sockets: %s", + UNIT(s)->id, strerror(-r)); + socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES); + } + } + + return; + } + + if (cfd < 0) { + Iterator i; + Unit *u; + bool pending = false; + + /* If there's already a start pending don't bother to + * do anything */ + SET_FOREACH(u, UNIT(s)->dependencies[UNIT_TRIGGERS], i) + if (unit_pending_active(u)) { + pending = true; + break; + } + + if (!pending) { + r = manager_add_job(UNIT(s)->manager, JOB_START, UNIT_DEREF(s->service), JOB_REPLACE, true, &error, NULL); + if (r < 0) + goto fail; + } + + socket_set_state(s, SOCKET_RUNNING); + } else { + char *prefix, *instance = NULL, *name; + Service *service; + + if (s->n_connections >= s->max_connections) { + log_warning_unit(UNIT(s)->id, + "%s: Too many incoming connections (%u)", + UNIT(s)->id, s->n_connections); + close_nointr_nofail(cfd); + return; + } + + r = socket_instantiate_service(s); + if (r < 0) + goto fail; + + r = instance_from_socket(cfd, s->n_accepted, &instance); + if (r < 0) { + if (r != -ENOTCONN) + goto fail; + + /* ENOTCONN is legitimate if TCP RST was received. + * This connection is over, but the socket unit lives on. */ + close_nointr_nofail(cfd); + return; + } + + prefix = unit_name_to_prefix(UNIT(s)->id); + if (!prefix) { + free(instance); + r = -ENOMEM; + goto fail; + } + + name = unit_name_build(prefix, instance, ".service"); + free(prefix); + free(instance); + + if (!name) { + r = -ENOMEM; + goto fail; + } + + r = unit_add_name(UNIT_DEREF(s->service), name); + if (r < 0) { + free(name); + goto fail; + } + + service = SERVICE(UNIT_DEREF(s->service)); + unit_ref_unset(&s->service); + s->n_accepted ++; + + UNIT(service)->no_gc = false; + + unit_choose_id(UNIT(service), name); + free(name); + + r = service_set_socket_fd(service, cfd, s); + if (r < 0) + goto fail; + + cfd = -1; + s->n_connections ++; + + r = manager_add_job(UNIT(s)->manager, JOB_START, UNIT(service), JOB_REPLACE, true, &error, NULL); + if (r < 0) + goto fail; + + /* Notify clients about changed counters */ + unit_add_to_dbus_queue(UNIT(s)); + } + + return; + +fail: + log_warning_unit(UNIT(s)->id, + "%s failed to queue service startup job (Maybe the service file is missing or not a %s unit?): %s", + UNIT(s)->id, + cfd >= 0 ? "template" : "non-template", + bus_error(&error, r)); + socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES); + + if (cfd >= 0) + close_nointr_nofail(cfd); + + dbus_error_free(&error); +} + +static void socket_run_next(Socket *s) { + int r; + + assert(s); + assert(s->control_command); + assert(s->control_command->command_next); + + socket_unwatch_control_pid(s); + + s->control_command = s->control_command->command_next; + + if ((r = socket_spawn(s, s->control_command, &s->control_pid)) < 0) + goto fail; + + return; + +fail: + log_warning_unit(UNIT(s)->id, + "%s failed to run next task: %s", + UNIT(s)->id, strerror(-r)); + + if (s->state == SOCKET_START_POST) + socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES); + else if (s->state == SOCKET_STOP_POST) + socket_enter_dead(s, SOCKET_FAILURE_RESOURCES); + else + socket_enter_signal(s, SOCKET_FINAL_SIGTERM, SOCKET_FAILURE_RESOURCES); +} + +static int socket_start(Unit *u) { + Socket *s = SOCKET(u); + + assert(s); + + /* We cannot fulfill this request right now, try again later + * please! */ + if (s->state == SOCKET_STOP_PRE || + s->state == SOCKET_STOP_PRE_SIGKILL || + s->state == SOCKET_STOP_PRE_SIGTERM || + s->state == SOCKET_STOP_POST || + s->state == SOCKET_FINAL_SIGTERM || + s->state == SOCKET_FINAL_SIGKILL) + return -EAGAIN; + + if (s->state == SOCKET_START_PRE || + s->state == SOCKET_START_POST) + return 0; + + /* Cannot run this without the service being around */ + if (UNIT_DEREF(s->service)) { + Service *service; + + service = SERVICE(UNIT_DEREF(s->service)); + + if (UNIT(service)->load_state != UNIT_LOADED) { + log_error_unit(UNIT(service)->id, + "Socket service %s not loaded, refusing.", + UNIT(service)->id); + return -ENOENT; + } + + /* If the service is already active we cannot start the + * socket */ + if (service->state != SERVICE_DEAD && + service->state != SERVICE_FAILED && + service->state != SERVICE_AUTO_RESTART) { + log_error_unit(UNIT(service)->id, + "Socket service %s already active, refusing.", + UNIT(service)->id); + return -EBUSY; + } + +#ifdef HAVE_SYSV_COMPAT + if (service->is_sysv) { + log_error_unit(UNIT(s)->id, + "Using SysV services for socket activation is not supported. Refusing."); + return -ENOENT; + } +#endif + } + + assert(s->state == SOCKET_DEAD || s->state == SOCKET_FAILED); + + s->result = SOCKET_SUCCESS; + socket_enter_start_pre(s); + return 0; +} + +static int socket_stop(Unit *u) { + Socket *s = SOCKET(u); + + assert(s); + + /* Already on it */ + if (s->state == SOCKET_STOP_PRE || + s->state == SOCKET_STOP_PRE_SIGTERM || + s->state == SOCKET_STOP_PRE_SIGKILL || + s->state == SOCKET_STOP_POST || + s->state == SOCKET_FINAL_SIGTERM || + s->state == SOCKET_FINAL_SIGKILL) + return 0; + + /* If there's already something running we go directly into + * kill mode. */ + if (s->state == SOCKET_START_PRE || + s->state == SOCKET_START_POST) { + socket_enter_signal(s, SOCKET_STOP_PRE_SIGTERM, SOCKET_SUCCESS); + return -EAGAIN; + } + + assert(s->state == SOCKET_LISTENING || s->state == SOCKET_RUNNING); + + socket_enter_stop_pre(s, SOCKET_SUCCESS); + return 0; +} + +static int socket_serialize(Unit *u, FILE *f, FDSet *fds) { + Socket *s = SOCKET(u); + SocketPort *p; + int r; + + assert(u); + assert(f); + assert(fds); + + unit_serialize_item(u, f, "state", socket_state_to_string(s->state)); + unit_serialize_item(u, f, "result", socket_result_to_string(s->result)); + unit_serialize_item_format(u, f, "n-accepted", "%u", s->n_accepted); + + if (s->control_pid > 0) + unit_serialize_item_format(u, f, "control-pid", "%lu", (unsigned long) s->control_pid); + + if (s->control_command_id >= 0) + unit_serialize_item(u, f, "control-command", socket_exec_command_to_string(s->control_command_id)); + + LIST_FOREACH(port, p, s->ports) { + int copy; + + if (p->fd < 0) + continue; + + if ((copy = fdset_put_dup(fds, p->fd)) < 0) + return copy; + + if (p->type == SOCKET_SOCKET) { + char *t; + + r = socket_address_print(&p->address, &t); + if (r < 0) + return r; + + if (socket_address_family(&p->address) == AF_NETLINK) + unit_serialize_item_format(u, f, "netlink", "%i %s", copy, t); + else + unit_serialize_item_format(u, f, "socket", "%i %i %s", copy, p->address.type, t); + free(t); + } else if (p->type == SOCKET_SPECIAL) + unit_serialize_item_format(u, f, "special", "%i %s", copy, p->path); + else if (p->type == SOCKET_MQUEUE) + unit_serialize_item_format(u, f, "mqueue", "%i %s", copy, p->path); + else { + assert(p->type == SOCKET_FIFO); + unit_serialize_item_format(u, f, "fifo", "%i %s", copy, p->path); + } + } + + return 0; +} + +static int socket_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) { + Socket *s = SOCKET(u); + + assert(u); + assert(key); + assert(value); + assert(fds); + + if (streq(key, "state")) { + SocketState state; + + state = socket_state_from_string(value); + if (state < 0) + log_debug_unit(u->id, + "Failed to parse state value %s", value); + else + s->deserialized_state = state; + } else if (streq(key, "result")) { + SocketResult f; + + f = socket_result_from_string(value); + if (f < 0) + log_debug_unit(u->id, + "Failed to parse result value %s", value); + else if (f != SOCKET_SUCCESS) + s->result = f; + + } else if (streq(key, "n-accepted")) { + unsigned k; + + if (safe_atou(value, &k) < 0) + log_debug_unit(u->id, + "Failed to parse n-accepted value %s", value); + else + s->n_accepted += k; + } else if (streq(key, "control-pid")) { + pid_t pid; + + if (parse_pid(value, &pid) < 0) + log_debug_unit(u->id, + "Failed to parse control-pid value %s", value); + else + s->control_pid = pid; + } else if (streq(key, "control-command")) { + SocketExecCommand id; + + id = socket_exec_command_from_string(value); + if (id < 0) + log_debug_unit(u->id, + "Failed to parse exec-command value %s", value); + else { + s->control_command_id = id; + s->control_command = s->exec_command[id]; + } + } else if (streq(key, "fifo")) { + int fd, skip = 0; + SocketPort *p; + + if (sscanf(value, "%i %n", &fd, &skip) < 1 || fd < 0 || !fdset_contains(fds, fd)) + log_debug_unit(u->id, + "Failed to parse fifo value %s", value); + else { + + LIST_FOREACH(port, p, s->ports) + if (p->type == SOCKET_FIFO && + streq_ptr(p->path, value+skip)) + break; + + if (p) { + if (p->fd >= 0) + close_nointr_nofail(p->fd); + p->fd = fdset_remove(fds, fd); + } + } + + } else if (streq(key, "special")) { + int fd, skip = 0; + SocketPort *p; + + if (sscanf(value, "%i %n", &fd, &skip) < 1 || fd < 0 || !fdset_contains(fds, fd)) + log_debug_unit(u->id, + "Failed to parse special value %s", value); + else { + + LIST_FOREACH(port, p, s->ports) + if (p->type == SOCKET_SPECIAL && + streq_ptr(p->path, value+skip)) + break; + + if (p) { + if (p->fd >= 0) + close_nointr_nofail(p->fd); + p->fd = fdset_remove(fds, fd); + } + } + + } else if (streq(key, "mqueue")) { + int fd, skip = 0; + SocketPort *p; + + if (sscanf(value, "%i %n", &fd, &skip) < 1 || fd < 0 || !fdset_contains(fds, fd)) + log_debug_unit(u->id, + "Failed to parse mqueue value %s", value); + else { + + LIST_FOREACH(port, p, s->ports) + if (p->type == SOCKET_MQUEUE && + streq_ptr(p->path, value+skip)) + break; + + if (p) { + if (p->fd >= 0) + close_nointr_nofail(p->fd); + p->fd = fdset_remove(fds, fd); + } + } + + } else if (streq(key, "socket")) { + int fd, type, skip = 0; + SocketPort *p; + + if (sscanf(value, "%i %i %n", &fd, &type, &skip) < 2 || fd < 0 || type < 0 || !fdset_contains(fds, fd)) + log_debug_unit(u->id, + "Failed to parse socket value %s", value); + else { + + LIST_FOREACH(port, p, s->ports) + if (socket_address_is(&p->address, value+skip, type)) + break; + + if (p) { + if (p->fd >= 0) + close_nointr_nofail(p->fd); + p->fd = fdset_remove(fds, fd); + } + } + + } else if (streq(key, "netlink")) { + int fd, skip = 0; + SocketPort *p; + + if (sscanf(value, "%i %n", &fd, &skip) < 1 || fd < 0 || !fdset_contains(fds, fd)) + log_debug_unit(u->id, + "Failed to parse socket value %s", value); + else { + + LIST_FOREACH(port, p, s->ports) + if (socket_address_is_netlink(&p->address, value+skip)) + break; + + if (p) { + if (p->fd >= 0) + close_nointr_nofail(p->fd); + p->fd = fdset_remove(fds, fd); + } + } + + } else + log_debug_unit(UNIT(s)->id, + "Unknown serialization key '%s'", key); + + return 0; +} + +static int socket_distribute_fds(Unit *u, FDSet *fds) { + Socket *s = SOCKET(u); + SocketPort *p; + + assert(u); + + LIST_FOREACH(port, p, s->ports) { + Iterator i; + int fd; + + if (p->type != SOCKET_SOCKET) + continue; + + if (p->fd >= 0) + continue; + + FDSET_FOREACH(fd, fds, i) { + if (socket_address_matches_fd(&p->address, fd)) { + p->fd = fdset_remove(fds, fd); + s->deserialized_state = SOCKET_LISTENING; + break; + } + } + } + + return 0; +} + +static UnitActiveState socket_active_state(Unit *u) { + assert(u); + + return state_translation_table[SOCKET(u)->state]; +} + +static const char *socket_sub_state_to_string(Unit *u) { + assert(u); + + return socket_state_to_string(SOCKET(u)->state); +} + +static bool socket_check_gc(Unit *u) { + Socket *s = SOCKET(u); + + assert(u); + + return s->n_connections > 0; +} + +static void socket_fd_event(Unit *u, int fd, uint32_t events, Watch *w) { + Socket *s = SOCKET(u); + int cfd = -1; + + assert(s); + assert(fd >= 0); + + if (s->state != SOCKET_LISTENING) + return; + + log_debug_unit(u->id, "Incoming traffic on %s", u->id); + + if (events != EPOLLIN) { + + if (events & EPOLLHUP) + log_error_unit(u->id, + "%s: Got POLLHUP on a listening socket. The service probably invoked shutdown() on it, and should better not do that.", + u->id); + else + log_error_unit(u->id, + "%s: Got unexpected poll event (0x%x) on socket.", + u->id, events); + + goto fail; + } + + if (w->socket_accept) { + for (;;) { + + cfd = accept4(fd, NULL, NULL, SOCK_NONBLOCK); + if (cfd < 0) { + + if (errno == EINTR) + continue; + + log_error_unit(u->id, + "Failed to accept socket: %m"); + goto fail; + } + + break; + } + + socket_apply_socket_options(s, cfd); + } + + socket_enter_running(s, cfd); + return; + +fail: + socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES); +} + +static void socket_sigchld_event(Unit *u, pid_t pid, int code, int status) { + Socket *s = SOCKET(u); + SocketResult f; + + assert(s); + assert(pid >= 0); + + if (pid != s->control_pid) + return; + + s->control_pid = 0; + + if (is_clean_exit(code, status, NULL)) + f = SOCKET_SUCCESS; + else if (code == CLD_EXITED) + f = SOCKET_FAILURE_EXIT_CODE; + else if (code == CLD_KILLED) + f = SOCKET_FAILURE_SIGNAL; + else if (code == CLD_DUMPED) + f = SOCKET_FAILURE_CORE_DUMP; + else + assert_not_reached("Unknown code"); + + if (s->control_command) { + exec_status_exit(&s->control_command->exec_status, &s->exec_context, pid, code, status); + + if (s->control_command->ignore) + f = SOCKET_SUCCESS; + } + + log_full_unit(f == SOCKET_SUCCESS ? LOG_DEBUG : LOG_NOTICE, + u->id, + "%s control process exited, code=%s status=%i", + u->id, sigchld_code_to_string(code), status); + + if (f != SOCKET_SUCCESS) + s->result = f; + + if (s->control_command && + s->control_command->command_next && + f == SOCKET_SUCCESS) { + + log_debug_unit(u->id, + "%s running next command for state %s", + u->id, socket_state_to_string(s->state)); + socket_run_next(s); + } else { + s->control_command = NULL; + s->control_command_id = _SOCKET_EXEC_COMMAND_INVALID; + + /* No further commands for this step, so let's figure + * out what to do next */ + + log_debug_unit(u->id, + "%s got final SIGCHLD for state %s", + u->id, socket_state_to_string(s->state)); + + switch (s->state) { + + case SOCKET_START_PRE: + if (f == SOCKET_SUCCESS) + socket_enter_start_post(s); + else + socket_enter_signal(s, SOCKET_FINAL_SIGTERM, f); + break; + + case SOCKET_START_POST: + if (f == SOCKET_SUCCESS) + socket_enter_listening(s); + else + socket_enter_stop_pre(s, f); + break; + + case SOCKET_STOP_PRE: + case SOCKET_STOP_PRE_SIGTERM: + case SOCKET_STOP_PRE_SIGKILL: + socket_enter_stop_post(s, f); + break; + + case SOCKET_STOP_POST: + case SOCKET_FINAL_SIGTERM: + case SOCKET_FINAL_SIGKILL: + socket_enter_dead(s, f); + break; + + default: + assert_not_reached("Uh, control process died at wrong time."); + } + } + + /* Notify clients about changed exit status */ + unit_add_to_dbus_queue(u); +} + +static void socket_timer_event(Unit *u, uint64_t elapsed, Watch *w) { + Socket *s = SOCKET(u); + + assert(s); + assert(elapsed == 1); + assert(w == &s->timer_watch); + + switch (s->state) { + + case SOCKET_START_PRE: + log_warning_unit(u->id, + "%s starting timed out. Terminating.", u->id); + socket_enter_signal(s, SOCKET_FINAL_SIGTERM, SOCKET_FAILURE_TIMEOUT); + break; + + case SOCKET_START_POST: + log_warning_unit(u->id, + "%s starting timed out. Stopping.", u->id); + socket_enter_stop_pre(s, SOCKET_FAILURE_TIMEOUT); + break; + + case SOCKET_STOP_PRE: + log_warning_unit(u->id, + "%s stopping timed out. Terminating.", u->id); + socket_enter_signal(s, SOCKET_STOP_PRE_SIGTERM, SOCKET_FAILURE_TIMEOUT); + break; + + case SOCKET_STOP_PRE_SIGTERM: + if (s->kill_context.send_sigkill) { + log_warning_unit(u->id, + "%s stopping timed out. Killing.", u->id); + socket_enter_signal(s, SOCKET_STOP_PRE_SIGKILL, SOCKET_FAILURE_TIMEOUT); + } else { + log_warning_unit(u->id, + "%s stopping timed out. Skipping SIGKILL. Ignoring.", + u->id); + socket_enter_stop_post(s, SOCKET_FAILURE_TIMEOUT); + } + break; + + case SOCKET_STOP_PRE_SIGKILL: + log_warning_unit(u->id, + "%s still around after SIGKILL. Ignoring.", u->id); + socket_enter_stop_post(s, SOCKET_FAILURE_TIMEOUT); + break; + + case SOCKET_STOP_POST: + log_warning_unit(u->id, + "%s stopping timed out (2). Terminating.", u->id); + socket_enter_signal(s, SOCKET_FINAL_SIGTERM, SOCKET_FAILURE_TIMEOUT); + break; + + case SOCKET_FINAL_SIGTERM: + if (s->kill_context.send_sigkill) { + log_warning_unit(u->id, + "%s stopping timed out (2). Killing.", u->id); + socket_enter_signal(s, SOCKET_FINAL_SIGKILL, SOCKET_FAILURE_TIMEOUT); + } else { + log_warning_unit(u->id, + "%s stopping timed out (2). Skipping SIGKILL. Ignoring.", + u->id); + socket_enter_dead(s, SOCKET_FAILURE_TIMEOUT); + } + break; + + case SOCKET_FINAL_SIGKILL: + log_warning_unit(u->id, + "%s still around after SIGKILL (2). Entering failed mode.", + u->id); + socket_enter_dead(s, SOCKET_FAILURE_TIMEOUT); + break; + + default: + assert_not_reached("Timeout at wrong time."); + } +} + +int socket_collect_fds(Socket *s, int **fds, unsigned *n_fds) { + int *rfds; + unsigned rn_fds, k; + SocketPort *p; + + assert(s); + assert(fds); + assert(n_fds); + + /* Called from the service code for requesting our fds */ + + rn_fds = 0; + LIST_FOREACH(port, p, s->ports) + if (p->fd >= 0) + rn_fds++; + + if (rn_fds <= 0) { + *fds = NULL; + *n_fds = 0; + return 0; + } + + if (!(rfds = new(int, rn_fds))) + return -ENOMEM; + + k = 0; + LIST_FOREACH(port, p, s->ports) + if (p->fd >= 0) + rfds[k++] = p->fd; + + assert(k == rn_fds); + + *fds = rfds; + *n_fds = rn_fds; + + return 0; +} + +void socket_notify_service_dead(Socket *s, bool failed_permanent) { + assert(s); + + /* The service is dead. Dang! + * + * This is strictly for one-instance-for-all-connections + * services. */ + + if (s->state == SOCKET_RUNNING) { + log_debug_unit(UNIT(s)->id, + "%s got notified about service death (failed permanently: %s)", + UNIT(s)->id, yes_no(failed_permanent)); + if (failed_permanent) + socket_enter_stop_pre(s, SOCKET_FAILURE_SERVICE_FAILED_PERMANENT); + else + socket_enter_listening(s); + } +} + +void socket_connection_unref(Socket *s) { + assert(s); + + /* The service is dead. Yay! + * + * This is strictly for one-instance-per-connection + * services. */ + + assert(s->n_connections > 0); + s->n_connections--; + + log_debug_unit(UNIT(s)->id, + "%s: One connection closed, %u left.", UNIT(s)->id, s->n_connections); +} + +static void socket_reset_failed(Unit *u) { + Socket *s = SOCKET(u); + + assert(s); + + if (s->state == SOCKET_FAILED) + socket_set_state(s, SOCKET_DEAD); + + s->result = SOCKET_SUCCESS; +} + +static int socket_kill(Unit *u, KillWho who, int signo, DBusError *error) { + Socket *s = SOCKET(u); + int r = 0; + Set *pid_set = NULL; + + assert(s); + + if (who == KILL_MAIN) { + dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "Socket units have no main processes"); + return -ESRCH; + } + + if (s->control_pid <= 0 && who == KILL_CONTROL) { + dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "No control process to kill"); + return -ESRCH; + } + + if (who == KILL_CONTROL || who == KILL_ALL) + if (s->control_pid > 0) + if (kill(s->control_pid, signo) < 0) + r = -errno; + + if (who == KILL_ALL) { + int q; + + pid_set = set_new(trivial_hash_func, trivial_compare_func); + if (!pid_set) + return -ENOMEM; + + /* Exclude the control pid from being killed via the cgroup */ + if (s->control_pid > 0) { + q = set_put(pid_set, LONG_TO_PTR(s->control_pid)); + if (q < 0) { + r = q; + goto finish; + } + } + + q = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, signo, false, false, pid_set, NULL); + if (q < 0 && q != -EAGAIN && q != -ESRCH && q != -ENOENT) + r = q; + } + +finish: + if (pid_set) + set_free(pid_set); + + return r; +} + +static const char* const socket_state_table[_SOCKET_STATE_MAX] = { + [SOCKET_DEAD] = "dead", + [SOCKET_START_PRE] = "start-pre", + [SOCKET_START_POST] = "start-post", + [SOCKET_LISTENING] = "listening", + [SOCKET_RUNNING] = "running", + [SOCKET_STOP_PRE] = "stop-pre", + [SOCKET_STOP_PRE_SIGTERM] = "stop-pre-sigterm", + [SOCKET_STOP_PRE_SIGKILL] = "stop-pre-sigkill", + [SOCKET_STOP_POST] = "stop-post", + [SOCKET_FINAL_SIGTERM] = "final-sigterm", + [SOCKET_FINAL_SIGKILL] = "final-sigkill", + [SOCKET_FAILED] = "failed" +}; + +DEFINE_STRING_TABLE_LOOKUP(socket_state, SocketState); + +static const char* const socket_exec_command_table[_SOCKET_EXEC_COMMAND_MAX] = { + [SOCKET_EXEC_START_PRE] = "StartPre", + [SOCKET_EXEC_START_POST] = "StartPost", + [SOCKET_EXEC_STOP_PRE] = "StopPre", + [SOCKET_EXEC_STOP_POST] = "StopPost" +}; + +DEFINE_STRING_TABLE_LOOKUP(socket_exec_command, SocketExecCommand); + +static const char* const socket_result_table[_SOCKET_RESULT_MAX] = { + [SOCKET_SUCCESS] = "success", + [SOCKET_FAILURE_RESOURCES] = "resources", + [SOCKET_FAILURE_TIMEOUT] = "timeout", + [SOCKET_FAILURE_EXIT_CODE] = "exit-code", + [SOCKET_FAILURE_SIGNAL] = "signal", + [SOCKET_FAILURE_CORE_DUMP] = "core-dump", + [SOCKET_FAILURE_SERVICE_FAILED_PERMANENT] = "service-failed-permanent" +}; + +DEFINE_STRING_TABLE_LOOKUP(socket_result, SocketResult); + +const UnitVTable socket_vtable = { + .object_size = sizeof(Socket), + .exec_context_offset = offsetof(Socket, exec_context), + + .sections = + "Unit\0" + "Socket\0" + "Install\0", + + .init = socket_init, + .done = socket_done, + .load = socket_load, + + .kill = socket_kill, + + .coldplug = socket_coldplug, + + .dump = socket_dump, + + .start = socket_start, + .stop = socket_stop, + + .serialize = socket_serialize, + .deserialize_item = socket_deserialize_item, + .distribute_fds = socket_distribute_fds, + + .active_state = socket_active_state, + .sub_state_to_string = socket_sub_state_to_string, + + .check_gc = socket_check_gc, + + .fd_event = socket_fd_event, + .sigchld_event = socket_sigchld_event, + .timer_event = socket_timer_event, + + .reset_failed = socket_reset_failed, + + .bus_interface = "org.freedesktop.systemd1.Socket", + .bus_message_handler = bus_socket_message_handler, + .bus_invalidating_properties = bus_socket_invalidating_properties, + + .status_message_formats = { + /*.starting_stopping = { + [0] = "Starting socket %s...", + [1] = "Stopping socket %s...", + },*/ + .finished_start_job = { + [JOB_DONE] = "Listening on %s.", + [JOB_FAILED] = "Failed to listen on %s.", + [JOB_DEPENDENCY] = "Dependency failed for %s.", + [JOB_TIMEOUT] = "Timed out starting %s.", + }, + .finished_stop_job = { + [JOB_DONE] = "Closed %s.", + [JOB_FAILED] = "Failed stopping %s.", + [JOB_TIMEOUT] = "Timed out stopping %s.", + }, + }, +}; diff --git a/src/core/socket.h b/src/core/socket.h new file mode 100644 index 000000000..f099520dc --- /dev/null +++ b/src/core/socket.h @@ -0,0 +1,175 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +typedef struct Socket Socket; + +#include "manager.h" +#include "unit.h" +#include "socket-util.h" +#include "mount.h" +#include "service.h" + +typedef enum SocketState { + SOCKET_DEAD, + SOCKET_START_PRE, + SOCKET_START_POST, + SOCKET_LISTENING, + SOCKET_RUNNING, + SOCKET_STOP_PRE, + SOCKET_STOP_PRE_SIGTERM, + SOCKET_STOP_PRE_SIGKILL, + SOCKET_STOP_POST, + SOCKET_FINAL_SIGTERM, + SOCKET_FINAL_SIGKILL, + SOCKET_FAILED, + _SOCKET_STATE_MAX, + _SOCKET_STATE_INVALID = -1 +} SocketState; + +typedef enum SocketExecCommand { + SOCKET_EXEC_START_PRE, + SOCKET_EXEC_START_POST, + SOCKET_EXEC_STOP_PRE, + SOCKET_EXEC_STOP_POST, + _SOCKET_EXEC_COMMAND_MAX, + _SOCKET_EXEC_COMMAND_INVALID = -1 +} SocketExecCommand; + +typedef enum SocketType { + SOCKET_SOCKET, + SOCKET_FIFO, + SOCKET_SPECIAL, + SOCKET_MQUEUE, + _SOCKET_FIFO_MAX, + _SOCKET_FIFO_INVALID = -1 +} SocketType; + +typedef enum SocketResult { + SOCKET_SUCCESS, + SOCKET_FAILURE_RESOURCES, + SOCKET_FAILURE_TIMEOUT, + SOCKET_FAILURE_EXIT_CODE, + SOCKET_FAILURE_SIGNAL, + SOCKET_FAILURE_CORE_DUMP, + SOCKET_FAILURE_SERVICE_FAILED_PERMANENT, + _SOCKET_RESULT_MAX, + _SOCKET_RESULT_INVALID = -1 +} SocketResult; + +typedef struct SocketPort { + SocketType type; + int fd; + + SocketAddress address; + char *path; + Watch fd_watch; + + LIST_FIELDS(struct SocketPort, port); +} SocketPort; + +struct Socket { + Unit meta; + + LIST_HEAD(SocketPort, ports); + + unsigned n_accepted; + unsigned n_connections; + unsigned max_connections; + + unsigned backlog; + usec_t timeout_usec; + + ExecCommand* exec_command[_SOCKET_EXEC_COMMAND_MAX]; + ExecContext exec_context; + KillContext kill_context; + + /* For Accept=no sockets refers to the one service we'll + activate. For Accept=yes sockets is either NULL, or filled + when the next service we spawn. */ + UnitRef service; + + SocketState state, deserialized_state; + + Watch timer_watch; + + ExecCommand* control_command; + SocketExecCommand control_command_id; + pid_t control_pid; + + mode_t directory_mode; + mode_t socket_mode; + + SocketResult result; + + bool accept; + + /* Socket options */ + bool keep_alive; + bool free_bind; + bool transparent; + bool broadcast; + bool pass_cred; + bool pass_sec; + int priority; + int mark; + size_t receive_buffer; + size_t send_buffer; + int ip_tos; + int ip_ttl; + size_t pipe_size; + char *bind_to_device; + char *tcp_congestion; + long mq_maxmsg; + long mq_msgsize; + + /* Only for INET6 sockets: issue IPV6_V6ONLY sockopt */ + SocketAddressBindIPv6Only bind_ipv6_only; + + char *smack; + char *smack_ip_in; + char *smack_ip_out; +}; + +/* Called from the service code when collecting fds */ +int socket_collect_fds(Socket *s, int **fds, unsigned *n_fds); + +/* Called from the service when it shut down */ +void socket_notify_service_dead(Socket *s, bool failed_permanent); + +/* Called from the mount code figure out if a mount is a dependency of + * any of the sockets of this socket */ +int socket_add_one_mount_link(Socket *s, Mount *m); + +/* Called from the service code when a per-connection service ended */ +void socket_connection_unref(Socket *s); + +extern const UnitVTable socket_vtable; + +const char* socket_state_to_string(SocketState i); +SocketState socket_state_from_string(const char *s); + +const char* socket_exec_command_to_string(SocketExecCommand i); +SocketExecCommand socket_exec_command_from_string(const char *s); + +const char* socket_result_to_string(SocketResult i); +SocketResult socket_result_from_string(const char *s); diff --git a/src/core/special.h b/src/core/special.h new file mode 100644 index 000000000..ef72260ec --- /dev/null +++ b/src/core/special.h @@ -0,0 +1,113 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +#define SPECIAL_DEFAULT_TARGET "default.target" + +/* Shutdown targets */ +#define SPECIAL_UMOUNT_TARGET "umount.target" +/* This is not really intended to be started by directly. This is + * mostly so that other targets (reboot/halt/poweroff) can depend on + * it to bring all services down that want to be brought down on + * system shutdown. */ +#define SPECIAL_SHUTDOWN_TARGET "shutdown.target" +#define SPECIAL_HALT_TARGET "halt.target" +#define SPECIAL_POWEROFF_TARGET "poweroff.target" +#define SPECIAL_REBOOT_TARGET "reboot.target" +#define SPECIAL_KEXEC_TARGET "kexec.target" +#define SPECIAL_EXIT_TARGET "exit.target" +#define SPECIAL_SUSPEND_TARGET "suspend.target" +#define SPECIAL_HIBERNATE_TARGET "hibernate.target" +#define SPECIAL_HYBRID_SLEEP_TARGET "hybrid-sleep.target" + +/* Special boot targets */ +#define SPECIAL_RESCUE_TARGET "rescue.target" +#define SPECIAL_EMERGENCY_TARGET "emergency.target" + +/* Early boot targets */ +#define SPECIAL_SYSINIT_TARGET "sysinit.target" +#define SPECIAL_SOCKETS_TARGET "sockets.target" +#define SPECIAL_LOCAL_FS_TARGET "local-fs.target" /* LSB's $local_fs */ +#define SPECIAL_LOCAL_FS_PRE_TARGET "local-fs-pre.target" +#define SPECIAL_REMOTE_FS_TARGET "remote-fs.target" /* LSB's $remote_fs */ +#define SPECIAL_REMOTE_FS_PRE_TARGET "remote-fs-pre.target" +#define SPECIAL_SWAP_TARGET "swap.target" +#define SPECIAL_BASIC_TARGET "basic.target" + +/* LSB compatibility */ +#define SPECIAL_NETWORK_TARGET "network.target" /* LSB's $network */ +#define SPECIAL_NSS_LOOKUP_TARGET "nss-lookup.target" /* LSB's $named */ +#define SPECIAL_RPCBIND_TARGET "rpcbind.target" /* LSB's $portmap */ +#define SPECIAL_SYSLOG_TARGET "syslog.target" /* LSB's $syslog */ +#define SPECIAL_TIME_SYNC_TARGET "time-sync.target" /* LSB's $time */ +#define SPECIAL_DISPLAY_MANAGER_SERVICE "display-manager.service" /* Common extension of LSB */ +#define SPECIAL_MAIL_TRANSFER_AGENT_TARGET "mail-transfer-agent.target" /* Common extension of LSB */ + +/* + * Rules regarding adding further high level targets like the above: + * + * - Be conservative, only add more of these when we really need + * them. We need strong usecases for further additions. + * + * - When there can be multiple implementations running side-by-side, + * it needs to be a .target unit which can pull in all + * implementations. + * + * - If something can be implemented with socket activation, and + * without, it needs to be a .target unit, so that it can pull in + * the appropriate unit. + * + * - Otherwise, it should be a .service unit. + * + * - In some cases it is OK to have both a .service and a .target + * unit, i.e. if there can be multiple parallel implementations, but + * only one is the "system" one. Example: syslog. + * + * Or to put this in other words: .service symlinks can be used to + * arbitrate between multiple implementations if there can be only one + * of a kind. .target units can be used to support multiple + * implementations that can run side-by-side. + */ + +/* Magic early boot services */ +#define SPECIAL_FSCK_SERVICE "systemd-fsck@.service" +#define SPECIAL_QUOTACHECK_SERVICE "systemd-quotacheck.service" +#define SPECIAL_QUOTAON_SERVICE "quotaon.service" +#define SPECIAL_REMOUNT_FS_SERVICE "systemd-remount-fs.service" + +/* Services systemd relies on */ +#define SPECIAL_DBUS_SERVICE "dbus.service" +#define SPECIAL_DBUS_SOCKET "dbus.socket" +#define SPECIAL_JOURNALD_SOCKET "systemd-journald.socket" +#define SPECIAL_JOURNALD_SERVICE "systemd-journald.service" + +/* Magic init signals */ +#define SPECIAL_KBREQUEST_TARGET "kbrequest.target" +#define SPECIAL_SIGPWR_TARGET "sigpwr.target" +#define SPECIAL_CTRL_ALT_DEL_TARGET "ctrl-alt-del.target" + +/* For SysV compatibility. Usually an alias for a saner target. On + * SysV-free systems this doesn't exist. */ +#define SPECIAL_RUNLEVEL2_TARGET "runlevel2.target" +#define SPECIAL_RUNLEVEL3_TARGET "runlevel3.target" +#define SPECIAL_RUNLEVEL4_TARGET "runlevel4.target" +#define SPECIAL_RUNLEVEL5_TARGET "runlevel5.target" diff --git a/src/core/swap.c b/src/core/swap.c new file mode 100644 index 000000000..c8e25d066 --- /dev/null +++ b/src/core/swap.c @@ -0,0 +1,1448 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "unit.h" +#include "swap.h" +#include "load-fragment.h" +#include "load-dropin.h" +#include "unit-name.h" +#include "dbus-swap.h" +#include "special.h" +#include "bus-errors.h" +#include "exit-status.h" +#include "def.h" +#include "path-util.h" +#include "virt.h" + +static const UnitActiveState state_translation_table[_SWAP_STATE_MAX] = { + [SWAP_DEAD] = UNIT_INACTIVE, + [SWAP_ACTIVATING] = UNIT_ACTIVATING, + [SWAP_ACTIVE] = UNIT_ACTIVE, + [SWAP_DEACTIVATING] = UNIT_DEACTIVATING, + [SWAP_ACTIVATING_SIGTERM] = UNIT_DEACTIVATING, + [SWAP_ACTIVATING_SIGKILL] = UNIT_DEACTIVATING, + [SWAP_DEACTIVATING_SIGTERM] = UNIT_DEACTIVATING, + [SWAP_DEACTIVATING_SIGKILL] = UNIT_DEACTIVATING, + [SWAP_FAILED] = UNIT_FAILED +}; + +static void swap_unset_proc_swaps(Swap *s) { + Swap *first; + Hashmap *swaps; + + assert(s); + + if (!s->parameters_proc_swaps.what) + return; + + /* Remove this unit from the chain of swaps which share the + * same kernel swap device. */ + swaps = UNIT(s)->manager->swaps_by_proc_swaps; + first = hashmap_get(swaps, s->parameters_proc_swaps.what); + LIST_REMOVE(Swap, same_proc_swaps, first, s); + + if (first) + hashmap_remove_and_replace(swaps, + s->parameters_proc_swaps.what, + first->parameters_proc_swaps.what, + first); + else + hashmap_remove(swaps, s->parameters_proc_swaps.what); + + free(s->parameters_proc_swaps.what); + s->parameters_proc_swaps.what = NULL; +} + +static void swap_init(Unit *u) { + Swap *s = SWAP(u); + + assert(s); + assert(UNIT(s)->load_state == UNIT_STUB); + + s->timeout_usec = DEFAULT_TIMEOUT_USEC; + + exec_context_init(&s->exec_context); + s->exec_context.std_output = u->manager->default_std_output; + s->exec_context.std_error = u->manager->default_std_error; + kill_context_init(&s->kill_context); + + s->parameters_proc_swaps.priority = s->parameters_fragment.priority = -1; + + s->timer_watch.type = WATCH_INVALID; + + s->control_command_id = _SWAP_EXEC_COMMAND_INVALID; + + UNIT(s)->ignore_on_isolate = true; +} + +static void swap_unwatch_control_pid(Swap *s) { + assert(s); + + if (s->control_pid <= 0) + return; + + unit_unwatch_pid(UNIT(s), s->control_pid); + s->control_pid = 0; +} + +static void swap_done(Unit *u) { + Swap *s = SWAP(u); + + assert(s); + + swap_unset_proc_swaps(s); + + free(s->what); + s->what = NULL; + + free(s->parameters_fragment.what); + s->parameters_fragment.what = NULL; + + exec_context_done(&s->exec_context); + exec_command_done_array(s->exec_command, _SWAP_EXEC_COMMAND_MAX); + s->control_command = NULL; + + swap_unwatch_control_pid(s); + + unit_unwatch_timer(u, &s->timer_watch); +} + +int swap_add_one_mount_link(Swap *s, Mount *m) { + int r; + + assert(s); + assert(m); + + if (UNIT(s)->load_state != UNIT_LOADED || + UNIT(m)->load_state != UNIT_LOADED) + return 0; + + if (is_device_path(s->what)) + return 0; + + if (!path_startswith(s->what, m->where)) + return 0; + + r = unit_add_two_dependencies(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, UNIT(m), true); + if (r < 0) + return r; + + return 0; +} + +static int swap_add_mount_links(Swap *s) { + Unit *other; + int r; + + assert(s); + + LIST_FOREACH(units_by_type, other, UNIT(s)->manager->units_by_type[UNIT_MOUNT]) + if ((r = swap_add_one_mount_link(s, MOUNT(other))) < 0) + return r; + + return 0; +} + +static int swap_add_device_links(Swap *s) { + SwapParameters *p; + + assert(s); + + if (!s->what) + return 0; + + if (s->from_fragment) + p = &s->parameters_fragment; + else + return 0; + + if (is_device_path(s->what)) + return unit_add_node_link(UNIT(s), s->what, + !p->noauto && p->nofail && + UNIT(s)->manager->running_as == SYSTEMD_SYSTEM); + else + /* File based swap devices need to be ordered after + * systemd-remount-fs.service, since they might need a + * writable file system. */ + return unit_add_dependency_by_name(UNIT(s), UNIT_AFTER, SPECIAL_REMOUNT_FS_SERVICE, NULL, true); +} + +static int swap_add_default_dependencies(Swap *s) { + int r; + + assert(s); + + if (UNIT(s)->manager->running_as != SYSTEMD_SYSTEM) + return 0; + + if (detect_container(NULL) > 0) + return 0; + + r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true); + if (r < 0) + return r; + + return 0; +} + +static int swap_verify(Swap *s) { + bool b; + char _cleanup_free_ *e = NULL; + + if (UNIT(s)->load_state != UNIT_LOADED) + return 0; + + e = unit_name_from_path(s->what, ".swap"); + if (e == NULL) + return log_oom(); + + b = unit_has_name(UNIT(s), e); + if (!b) { + log_error_unit(UNIT(s)->id, + "%s: Value of \"What\" and unit name do not match, not loading.", + UNIT(s)->id); + return -EINVAL; + } + + if (s->exec_context.pam_name && s->kill_context.kill_mode != KILL_CONTROL_GROUP) { + log_error_unit(UNIT(s)->id, + "%s has PAM enabled. Kill mode must be set to 'control-group'. Refusing to load.", + UNIT(s)->id); + return -EINVAL; + } + + return 0; +} + +static int swap_load(Unit *u) { + int r; + Swap *s = SWAP(u); + + assert(s); + assert(u->load_state == UNIT_STUB); + + /* Load a .swap file */ + r = unit_load_fragment_and_dropin_optional(u); + if (r < 0) + return r; + + if (u->load_state == UNIT_LOADED) { + r = unit_add_exec_dependencies(u, &s->exec_context); + if (r < 0) + return r; + + if (UNIT(s)->fragment_path) + s->from_fragment = true; + + if (!s->what) { + if (s->parameters_fragment.what) + s->what = strdup(s->parameters_fragment.what); + else if (s->parameters_proc_swaps.what) + s->what = strdup(s->parameters_proc_swaps.what); + else + s->what = unit_name_to_path(u->id); + + if (!s->what) + return -ENOMEM; + } + + path_kill_slashes(s->what); + + if (!UNIT(s)->description) + if ((r = unit_set_description(u, s->what)) < 0) + return r; + + r = swap_add_device_links(s); + if (r < 0) + return r; + + r = swap_add_mount_links(s); + if (r < 0) + return r; + + r = unit_add_default_cgroups(u); + if (r < 0) + return r; + + if (UNIT(s)->default_dependencies) { + r = swap_add_default_dependencies(s); + if (r < 0) + return r; + } + + r = unit_exec_context_defaults(u, &s->exec_context); + if (r < 0) + return r; + } + + return swap_verify(s); +} + +static int swap_add_one( + Manager *m, + const char *what, + const char *what_proc_swaps, + int priority, + bool noauto, + bool nofail, + bool set_flags) { + + Unit *u = NULL; + char _cleanup_free_ *e = NULL; + char *wp = NULL; + bool delete = false; + int r; + SwapParameters *p; + Swap *first; + + assert(m); + assert(what); + assert(what_proc_swaps); + + e = unit_name_from_path(what, ".swap"); + if (!e) + return log_oom(); + + u = manager_get_unit(m, e); + + if (u && + SWAP(u)->from_proc_swaps && + !path_equal(SWAP(u)->parameters_proc_swaps.what, what_proc_swaps)) + return -EEXIST; + + if (!u) { + delete = true; + + u = unit_new(m, sizeof(Swap)); + if (!u) + return log_oom(); + + r = unit_add_name(u, e); + if (r < 0) + goto fail; + + SWAP(u)->what = strdup(what); + if (!SWAP(u)->what) { + r = log_oom(); + goto fail; + } + + unit_add_to_load_queue(u); + } else + delete = false; + + p = &SWAP(u)->parameters_proc_swaps; + + if (!p->what) { + wp = strdup(what_proc_swaps); + if (!wp) { + r = log_oom(); + goto fail; + } + + if (!m->swaps_by_proc_swaps) { + m->swaps_by_proc_swaps = hashmap_new(string_hash_func, string_compare_func); + if (!m->swaps_by_proc_swaps) { + r = log_oom(); + goto fail; + } + } + + free(p->what); + p->what = wp; + + first = hashmap_get(m->swaps_by_proc_swaps, wp); + LIST_PREPEND(Swap, same_proc_swaps, first, SWAP(u)); + + r = hashmap_replace(m->swaps_by_proc_swaps, wp, first); + if (r < 0) + goto fail; + } + + if (set_flags) { + SWAP(u)->is_active = true; + SWAP(u)->just_activated = !SWAP(u)->from_proc_swaps; + } + + SWAP(u)->from_proc_swaps = true; + + p->priority = priority; + p->noauto = noauto; + p->nofail = nofail; + + unit_add_to_dbus_queue(u); + + return 0; + +fail: + log_warning_unit(e, "Failed to load swap unit: %s", strerror(-r)); + + free(wp); + + if (delete && u) + unit_free(u); + + return r; +} + +static int swap_process_new_swap(Manager *m, const char *device, int prio, bool set_flags) { + struct stat st; + int r = 0, k; + + assert(m); + + if (stat(device, &st) >= 0 && S_ISBLK(st.st_mode)) { + struct udev_device *d; + const char *dn; + struct udev_list_entry *item = NULL, *first = NULL; + + /* So this is a proper swap device. Create swap units + * for all names this swap device is known under */ + + d = udev_device_new_from_devnum(m->udev, 'b', st.st_rdev); + if (!d) + return log_oom(); + + dn = udev_device_get_devnode(d); + /* Skip dn==device, since that case will be handled below */ + if (dn && !streq(dn, device)) + r = swap_add_one(m, dn, device, prio, false, false, set_flags); + + /* Add additional units for all symlinks */ + first = udev_device_get_devlinks_list_entry(d); + udev_list_entry_foreach(item, first) { + const char *p; + + /* Don't bother with the /dev/block links */ + p = udev_list_entry_get_name(item); + + if (path_startswith(p, "/dev/block/")) + continue; + + if (stat(p, &st) >= 0) + if ((!S_ISBLK(st.st_mode)) || + st.st_rdev != udev_device_get_devnum(d)) + continue; + + k = swap_add_one(m, p, device, prio, false, false, set_flags); + if (k < 0) + r = k; + } + + udev_device_unref(d); + } + + k = swap_add_one(m, device, device, prio, false, false, set_flags); + if (k < 0) + r = k; + + return r; +} + +static void swap_set_state(Swap *s, SwapState state) { + SwapState old_state; + + assert(s); + + old_state = s->state; + s->state = state; + + if (state != SWAP_ACTIVATING && + state != SWAP_ACTIVATING_SIGTERM && + state != SWAP_ACTIVATING_SIGKILL && + state != SWAP_DEACTIVATING && + state != SWAP_DEACTIVATING_SIGTERM && + state != SWAP_DEACTIVATING_SIGKILL) { + unit_unwatch_timer(UNIT(s), &s->timer_watch); + swap_unwatch_control_pid(s); + s->control_command = NULL; + s->control_command_id = _SWAP_EXEC_COMMAND_INVALID; + } + + if (state != old_state) + log_debug_unit(UNIT(s)->id, + "%s changed %s -> %s", + UNIT(s)->id, + swap_state_to_string(old_state), + swap_state_to_string(state)); + + unit_notify(UNIT(s), state_translation_table[old_state], + state_translation_table[state], true); +} + +static int swap_coldplug(Unit *u) { + Swap *s = SWAP(u); + SwapState new_state = SWAP_DEAD; + int r; + + assert(s); + assert(s->state == SWAP_DEAD); + + if (s->deserialized_state != s->state) + new_state = s->deserialized_state; + else if (s->from_proc_swaps) + new_state = SWAP_ACTIVE; + + if (new_state != s->state) { + + if (new_state == SWAP_ACTIVATING || + new_state == SWAP_ACTIVATING_SIGTERM || + new_state == SWAP_ACTIVATING_SIGKILL || + new_state == SWAP_DEACTIVATING || + new_state == SWAP_DEACTIVATING_SIGTERM || + new_state == SWAP_DEACTIVATING_SIGKILL) { + + if (s->control_pid <= 0) + return -EBADMSG; + + r = unit_watch_pid(UNIT(s), s->control_pid); + if (r < 0) + return r; + + r = unit_watch_timer(UNIT(s), CLOCK_MONOTONIC, true, s->timeout_usec, &s->timer_watch); + if (r < 0) + return r; + } + + swap_set_state(s, new_state); + } + + return 0; +} + +static void swap_dump(Unit *u, FILE *f, const char *prefix) { + Swap *s = SWAP(u); + SwapParameters *p; + + assert(s); + assert(f); + + if (s->from_proc_swaps) + p = &s->parameters_proc_swaps; + else if (s->from_fragment) + p = &s->parameters_fragment; + else + p = NULL; + + fprintf(f, + "%sSwap State: %s\n" + "%sResult: %s\n" + "%sWhat: %s\n" + "%sFrom /proc/swaps: %s\n" + "%sFrom fragment: %s\n", + prefix, swap_state_to_string(s->state), + prefix, swap_result_to_string(s->result), + prefix, s->what, + prefix, yes_no(s->from_proc_swaps), + prefix, yes_no(s->from_fragment)); + + if (p) + fprintf(f, + "%sPriority: %i\n" + "%sNoAuto: %s\n" + "%sNoFail: %s\n", + prefix, p->priority, + prefix, yes_no(p->noauto), + prefix, yes_no(p->nofail)); + + if (s->control_pid > 0) + fprintf(f, + "%sControl PID: %lu\n", + prefix, (unsigned long) s->control_pid); + + exec_context_dump(&s->exec_context, f, prefix); + kill_context_dump(&s->kill_context, f, prefix); +} + +static int swap_spawn(Swap *s, ExecCommand *c, pid_t *_pid) { + pid_t pid; + int r; + + assert(s); + assert(c); + assert(_pid); + + r = unit_watch_timer(UNIT(s), CLOCK_MONOTONIC, true, s->timeout_usec, &s->timer_watch); + if (r < 0) + goto fail; + + r = exec_spawn(c, + NULL, + &s->exec_context, + NULL, 0, + UNIT(s)->manager->environment, + true, + true, + true, + UNIT(s)->manager->confirm_spawn, + UNIT(s)->cgroup_bondings, + UNIT(s)->cgroup_attributes, + NULL, + UNIT(s)->id, + NULL, + &pid); + if (r < 0) + goto fail; + + r = unit_watch_pid(UNIT(s), pid); + if (r < 0) + /* FIXME: we need to do something here */ + goto fail; + + *_pid = pid; + + return 0; + +fail: + unit_unwatch_timer(UNIT(s), &s->timer_watch); + + return r; +} + +static void swap_enter_dead(Swap *s, SwapResult f) { + assert(s); + + if (f != SWAP_SUCCESS) + s->result = f; + + swap_set_state(s, s->result != SWAP_SUCCESS ? SWAP_FAILED : SWAP_DEAD); +} + +static void swap_enter_active(Swap *s, SwapResult f) { + assert(s); + + if (f != SWAP_SUCCESS) + s->result = f; + + swap_set_state(s, SWAP_ACTIVE); +} + +static void swap_enter_signal(Swap *s, SwapState state, SwapResult f) { + int r; + Set *pid_set = NULL; + bool wait_for_exit = false; + + assert(s); + + if (f != SWAP_SUCCESS) + s->result = f; + + if (s->kill_context.kill_mode != KILL_NONE) { + int sig = (state == SWAP_ACTIVATING_SIGTERM || + state == SWAP_DEACTIVATING_SIGTERM) ? s->kill_context.kill_signal : SIGKILL; + + if (s->control_pid > 0) { + if (kill_and_sigcont(s->control_pid, sig) < 0 && errno != ESRCH) + + log_warning_unit(UNIT(s)->id, + "Failed to kill control process %li: %m", + (long) s->control_pid); + else + wait_for_exit = true; + } + + if (s->kill_context.kill_mode == KILL_CONTROL_GROUP) { + + pid_set = set_new(trivial_hash_func, trivial_compare_func); + if (!pid_set) { + r = log_oom(); + goto fail; + } + + /* Exclude the control pid from being killed via the cgroup */ + if (s->control_pid > 0) { + r = set_put(pid_set, LONG_TO_PTR(s->control_pid)); + if (r < 0) + goto fail; + } + + r = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, sig, true, false, pid_set, NULL); + if (r < 0) { + if (r != -EAGAIN && r != -ESRCH && r != -ENOENT) + log_warning_unit(UNIT(s)->id, + "Failed to kill control group: %s", strerror(-r)); + } else if (r > 0) + wait_for_exit = true; + + set_free(pid_set); + pid_set = NULL; + } + } + + if (wait_for_exit) { + r = unit_watch_timer(UNIT(s), CLOCK_MONOTONIC, true, s->timeout_usec, &s->timer_watch); + if (r < 0) + goto fail; + + swap_set_state(s, state); + } else + swap_enter_dead(s, SWAP_SUCCESS); + + return; + +fail: + log_warning_unit(UNIT(s)->id, + "%s failed to kill processes: %s", UNIT(s)->id, strerror(-r)); + + swap_enter_dead(s, SWAP_FAILURE_RESOURCES); + + if (pid_set) + set_free(pid_set); +} + +static void swap_enter_activating(Swap *s) { + int r, priority; + + assert(s); + + s->control_command_id = SWAP_EXEC_ACTIVATE; + s->control_command = s->exec_command + SWAP_EXEC_ACTIVATE; + + if (s->from_fragment) + priority = s->parameters_fragment.priority; + else + priority = -1; + + if (priority >= 0) { + char p[LINE_MAX]; + + snprintf(p, sizeof(p), "%i", priority); + char_array_0(p); + + r = exec_command_set( + s->control_command, + "/sbin/swapon", + "-p", + p, + s->what, + NULL); + } else + r = exec_command_set( + s->control_command, + "/sbin/swapon", + s->what, + NULL); + + if (r < 0) + goto fail; + + swap_unwatch_control_pid(s); + + r = swap_spawn(s, s->control_command, &s->control_pid); + if (r < 0) + goto fail; + + swap_set_state(s, SWAP_ACTIVATING); + + return; + +fail: + log_warning_unit(UNIT(s)->id, + "%s failed to run 'swapon' task: %s", + UNIT(s)->id, strerror(-r)); + swap_enter_dead(s, SWAP_FAILURE_RESOURCES); +} + +static void swap_enter_deactivating(Swap *s) { + int r; + + assert(s); + + s->control_command_id = SWAP_EXEC_DEACTIVATE; + s->control_command = s->exec_command + SWAP_EXEC_DEACTIVATE; + + r = exec_command_set(s->control_command, + "/sbin/swapoff", + s->what, + NULL); + if (r < 0) + goto fail; + + swap_unwatch_control_pid(s); + + r = swap_spawn(s, s->control_command, &s->control_pid); + if (r < 0) + goto fail; + + swap_set_state(s, SWAP_DEACTIVATING); + + return; + +fail: + log_warning_unit(UNIT(s)->id, + "%s failed to run 'swapoff' task: %s", + UNIT(s)->id, strerror(-r)); + swap_enter_active(s, SWAP_FAILURE_RESOURCES); +} + +static int swap_start(Unit *u) { + Swap *s = SWAP(u); + + assert(s); + + /* We cannot fulfill this request right now, try again later + * please! */ + + if (s->state == SWAP_DEACTIVATING || + s->state == SWAP_DEACTIVATING_SIGTERM || + s->state == SWAP_DEACTIVATING_SIGKILL || + s->state == SWAP_ACTIVATING_SIGTERM || + s->state == SWAP_ACTIVATING_SIGKILL) + return -EAGAIN; + + if (s->state == SWAP_ACTIVATING) + return 0; + + assert(s->state == SWAP_DEAD || s->state == SWAP_FAILED); + + if (detect_container(NULL) > 0) + return -EPERM; + + s->result = SWAP_SUCCESS; + swap_enter_activating(s); + return 0; +} + +static int swap_stop(Unit *u) { + Swap *s = SWAP(u); + + assert(s); + + if (s->state == SWAP_DEACTIVATING || + s->state == SWAP_DEACTIVATING_SIGTERM || + s->state == SWAP_DEACTIVATING_SIGKILL || + s->state == SWAP_ACTIVATING_SIGTERM || + s->state == SWAP_ACTIVATING_SIGKILL) + return 0; + + assert(s->state == SWAP_ACTIVATING || + s->state == SWAP_ACTIVE); + + if (detect_container(NULL) > 0) + return -EPERM; + + swap_enter_deactivating(s); + return 0; +} + +static int swap_serialize(Unit *u, FILE *f, FDSet *fds) { + Swap *s = SWAP(u); + + assert(s); + assert(f); + assert(fds); + + unit_serialize_item(u, f, "state", swap_state_to_string(s->state)); + unit_serialize_item(u, f, "result", swap_result_to_string(s->result)); + + if (s->control_pid > 0) + unit_serialize_item_format(u, f, "control-pid", "%lu", (unsigned long) s->control_pid); + + if (s->control_command_id >= 0) + unit_serialize_item(u, f, "control-command", swap_exec_command_to_string(s->control_command_id)); + + return 0; +} + +static int swap_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) { + Swap *s = SWAP(u); + + assert(s); + assert(fds); + + if (streq(key, "state")) { + SwapState state; + + state = swap_state_from_string(value); + if (state < 0) + log_debug_unit(u->id, "Failed to parse state value %s", value); + else + s->deserialized_state = state; + } else if (streq(key, "result")) { + SwapResult f; + + f = swap_result_from_string(value); + if (f < 0) + log_debug_unit(u->id, "Failed to parse result value %s", value); + else if (f != SWAP_SUCCESS) + s->result = f; + } else if (streq(key, "control-pid")) { + pid_t pid; + + if (parse_pid(value, &pid) < 0) + log_debug_unit(u->id, "Failed to parse control-pid value %s", value); + else + s->control_pid = pid; + + } else if (streq(key, "control-command")) { + SwapExecCommand id; + + id = swap_exec_command_from_string(value); + if (id < 0) + log_debug_unit(u->id, "Failed to parse exec-command value %s", value); + else { + s->control_command_id = id; + s->control_command = s->exec_command + id; + } + + } else + log_debug_unit(u->id, "Unknown serialization key '%s'", key); + + return 0; +} + +static UnitActiveState swap_active_state(Unit *u) { + assert(u); + + return state_translation_table[SWAP(u)->state]; +} + +static const char *swap_sub_state_to_string(Unit *u) { + assert(u); + + return swap_state_to_string(SWAP(u)->state); +} + +static bool swap_check_gc(Unit *u) { + Swap *s = SWAP(u); + + assert(s); + + return s->from_proc_swaps; +} + +static void swap_sigchld_event(Unit *u, pid_t pid, int code, int status) { + Swap *s = SWAP(u); + SwapResult f; + + assert(s); + assert(pid >= 0); + + if (pid != s->control_pid) + return; + + s->control_pid = 0; + + if (is_clean_exit(code, status, NULL)) + f = SWAP_SUCCESS; + else if (code == CLD_EXITED) + f = SWAP_FAILURE_EXIT_CODE; + else if (code == CLD_KILLED) + f = SWAP_FAILURE_SIGNAL; + else if (code == CLD_DUMPED) + f = SWAP_FAILURE_CORE_DUMP; + else + assert_not_reached("Unknown code"); + + if (f != SWAP_SUCCESS) + s->result = f; + + if (s->control_command) { + exec_status_exit(&s->control_command->exec_status, &s->exec_context, pid, code, status); + + s->control_command = NULL; + s->control_command_id = _SWAP_EXEC_COMMAND_INVALID; + } + + log_full_unit(f == SWAP_SUCCESS ? LOG_DEBUG : LOG_NOTICE, + u->id, + "%s swap process exited, code=%s status=%i", + u->id, sigchld_code_to_string(code), status); + + switch (s->state) { + + case SWAP_ACTIVATING: + case SWAP_ACTIVATING_SIGTERM: + case SWAP_ACTIVATING_SIGKILL: + + if (f == SWAP_SUCCESS) + swap_enter_active(s, f); + else + swap_enter_dead(s, f); + break; + + case SWAP_DEACTIVATING: + case SWAP_DEACTIVATING_SIGKILL: + case SWAP_DEACTIVATING_SIGTERM: + + if (f == SWAP_SUCCESS) + swap_enter_dead(s, f); + else + swap_enter_dead(s, f); + break; + + default: + assert_not_reached("Uh, control process died at wrong time."); + } + + /* Notify clients about changed exit status */ + unit_add_to_dbus_queue(u); + + /* Request a reload of /proc/swaps, so that following units + * can follow our state change */ + u->manager->request_reload = true; +} + +static void swap_timer_event(Unit *u, uint64_t elapsed, Watch *w) { + Swap *s = SWAP(u); + + assert(s); + assert(elapsed == 1); + assert(w == &s->timer_watch); + + switch (s->state) { + + case SWAP_ACTIVATING: + log_warning_unit(u->id, "%s activation timed out. Stopping.", u->id); + swap_enter_signal(s, SWAP_ACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT); + break; + + case SWAP_DEACTIVATING: + log_warning_unit(u->id, "%s deactivation timed out. Stopping.", u->id); + swap_enter_signal(s, SWAP_DEACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT); + break; + + case SWAP_ACTIVATING_SIGTERM: + if (s->kill_context.send_sigkill) { + log_warning_unit(u->id, "%s activation timed out. Killing.", u->id); + swap_enter_signal(s, SWAP_ACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT); + } else { + log_warning_unit(u->id, "%s activation timed out. Skipping SIGKILL. Ignoring.", u->id); + swap_enter_dead(s, SWAP_FAILURE_TIMEOUT); + } + break; + + case SWAP_DEACTIVATING_SIGTERM: + if (s->kill_context.send_sigkill) { + log_warning_unit(u->id, "%s deactivation timed out. Killing.", u->id); + swap_enter_signal(s, SWAP_DEACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT); + } else { + log_warning_unit(u->id, "%s deactivation timed out. Skipping SIGKILL. Ignoring.", u->id); + swap_enter_dead(s, SWAP_FAILURE_TIMEOUT); + } + break; + + case SWAP_ACTIVATING_SIGKILL: + case SWAP_DEACTIVATING_SIGKILL: + log_warning_unit(u->id, "%s swap process still around after SIGKILL. Ignoring.", u->id); + swap_enter_dead(s, SWAP_FAILURE_TIMEOUT); + break; + + default: + assert_not_reached("Timeout at wrong time."); + } +} + +static int swap_load_proc_swaps(Manager *m, bool set_flags) { + unsigned i; + int r = 0; + + assert(m); + + rewind(m->proc_swaps); + + (void) fscanf(m->proc_swaps, "%*s %*s %*s %*s %*s\n"); + + for (i = 1;; i++) { + char *dev = NULL, *d; + int prio = 0, k; + + k = fscanf(m->proc_swaps, + "%ms " /* device/file */ + "%*s " /* type of swap */ + "%*s " /* swap size */ + "%*s " /* used */ + "%i\n", /* priority */ + &dev, &prio); + if (k != 2) { + if (k == EOF) + break; + + log_warning("Failed to parse /proc/swaps:%u", i); + free(dev); + continue; + } + + d = cunescape(dev); + free(dev); + + if (!d) + return -ENOMEM; + + k = swap_process_new_swap(m, d, prio, set_flags); + free(d); + + if (k < 0) + r = k; + } + + return r; +} + +int swap_dispatch_reload(Manager *m) { + /* This function should go as soon as the kernel properly notifies us */ + + if (_likely_(!m->request_reload)) + return 0; + + m->request_reload = false; + + return swap_fd_event(m, EPOLLPRI); +} + +int swap_fd_event(Manager *m, int events) { + Unit *u; + int r; + + assert(m); + assert(events & EPOLLPRI); + + r = swap_load_proc_swaps(m, true); + if (r < 0) { + log_error("Failed to reread /proc/swaps: %s", strerror(-r)); + + /* Reset flags, just in case, for late calls */ + LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_SWAP]) { + Swap *swap = SWAP(u); + + swap->is_active = swap->just_activated = false; + } + + return 0; + } + + manager_dispatch_load_queue(m); + + LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_SWAP]) { + Swap *swap = SWAP(u); + + if (!swap->is_active) { + /* This has just been deactivated */ + + swap->from_proc_swaps = false; + swap_unset_proc_swaps(swap); + + switch (swap->state) { + + case SWAP_ACTIVE: + swap_enter_dead(swap, SWAP_SUCCESS); + break; + + default: + swap_set_state(swap, swap->state); + break; + } + + } else if (swap->just_activated) { + + /* New swap entry */ + + switch (swap->state) { + + case SWAP_DEAD: + case SWAP_FAILED: + swap_enter_active(swap, SWAP_SUCCESS); + break; + + default: + /* Nothing really changed, but let's + * issue an notification call + * nonetheless, in case somebody is + * waiting for this. */ + swap_set_state(swap, swap->state); + break; + } + } + + /* Reset the flags for later calls */ + swap->is_active = swap->just_activated = false; + } + + return 1; +} + +static Unit *swap_following(Unit *u) { + Swap *s = SWAP(u); + Swap *other, *first = NULL; + + assert(s); + + if (streq_ptr(s->what, s->parameters_proc_swaps.what)) + return NULL; + + /* Make everybody follow the unit that's named after the swap + * device in the kernel */ + + LIST_FOREACH_AFTER(same_proc_swaps, other, s) + if (streq_ptr(other->what, other->parameters_proc_swaps.what)) + return UNIT(other); + + LIST_FOREACH_BEFORE(same_proc_swaps, other, s) { + if (streq_ptr(other->what, other->parameters_proc_swaps.what)) + return UNIT(other); + + first = other; + } + + return UNIT(first); +} + +static int swap_following_set(Unit *u, Set **_set) { + Swap *s = SWAP(u); + Swap *other; + Set *set; + int r; + + assert(s); + assert(_set); + + if (LIST_JUST_US(same_proc_swaps, s)) { + *_set = NULL; + return 0; + } + + if (!(set = set_new(NULL, NULL))) + return -ENOMEM; + + LIST_FOREACH_AFTER(same_proc_swaps, other, s) + if ((r = set_put(set, other)) < 0) + goto fail; + + LIST_FOREACH_BEFORE(same_proc_swaps, other, s) + if ((r = set_put(set, other)) < 0) + goto fail; + + *_set = set; + return 1; + +fail: + set_free(set); + return r; +} + +static void swap_shutdown(Manager *m) { + assert(m); + + if (m->proc_swaps) { + fclose(m->proc_swaps); + m->proc_swaps = NULL; + } + + hashmap_free(m->swaps_by_proc_swaps); + m->swaps_by_proc_swaps = NULL; +} + +static int swap_enumerate(Manager *m) { + int r; + struct epoll_event ev; + assert(m); + + if (!m->proc_swaps) { + m->proc_swaps = fopen("/proc/swaps", "re"); + if (!m->proc_swaps) + return (errno == ENOENT) ? 0 : -errno; + + m->swap_watch.type = WATCH_SWAP; + m->swap_watch.fd = fileno(m->proc_swaps); + + zero(ev); + ev.events = EPOLLPRI; + ev.data.ptr = &m->swap_watch; + + if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->swap_watch.fd, &ev) < 0) + return -errno; + } + + r = swap_load_proc_swaps(m, false); + if (r < 0) + swap_shutdown(m); + + return r; +} + +static void swap_reset_failed(Unit *u) { + Swap *s = SWAP(u); + + assert(s); + + if (s->state == SWAP_FAILED) + swap_set_state(s, SWAP_DEAD); + + s->result = SWAP_SUCCESS; +} + +static int swap_kill(Unit *u, KillWho who, int signo, DBusError *error) { + Swap *s = SWAP(u); + int r = 0; + Set *pid_set = NULL; + + assert(s); + + if (who == KILL_MAIN) { + dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "Swap units have no main processes"); + return -ESRCH; + } + + if (s->control_pid <= 0 && who == KILL_CONTROL) { + dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "No control process to kill"); + return -ESRCH; + } + + if (who == KILL_CONTROL || who == KILL_ALL) + if (s->control_pid > 0) + if (kill(s->control_pid, signo) < 0) + r = -errno; + + if (who == KILL_ALL) { + int q; + + pid_set = set_new(trivial_hash_func, trivial_compare_func); + if (!pid_set) + return -ENOMEM; + + /* Exclude the control pid from being killed via the cgroup */ + if (s->control_pid > 0) { + q = set_put(pid_set, LONG_TO_PTR(s->control_pid)); + if (q < 0) { + r = q; + goto finish; + } + } + + q = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, signo, false, false, pid_set, NULL); + if (q < 0 && q != -EAGAIN && q != -ESRCH && q != -ENOENT) + r = q; + } + +finish: + if (pid_set) + set_free(pid_set); + + return r; +} + +static const char* const swap_state_table[_SWAP_STATE_MAX] = { + [SWAP_DEAD] = "dead", + [SWAP_ACTIVATING] = "activating", + [SWAP_ACTIVE] = "active", + [SWAP_DEACTIVATING] = "deactivating", + [SWAP_ACTIVATING_SIGTERM] = "activating-sigterm", + [SWAP_ACTIVATING_SIGKILL] = "activating-sigkill", + [SWAP_DEACTIVATING_SIGTERM] = "deactivating-sigterm", + [SWAP_DEACTIVATING_SIGKILL] = "deactivating-sigkill", + [SWAP_FAILED] = "failed" +}; + +DEFINE_STRING_TABLE_LOOKUP(swap_state, SwapState); + +static const char* const swap_exec_command_table[_SWAP_EXEC_COMMAND_MAX] = { + [SWAP_EXEC_ACTIVATE] = "ExecActivate", + [SWAP_EXEC_DEACTIVATE] = "ExecDeactivate", +}; + +DEFINE_STRING_TABLE_LOOKUP(swap_exec_command, SwapExecCommand); + +static const char* const swap_result_table[_SWAP_RESULT_MAX] = { + [SWAP_SUCCESS] = "success", + [SWAP_FAILURE_RESOURCES] = "resources", + [SWAP_FAILURE_TIMEOUT] = "timeout", + [SWAP_FAILURE_EXIT_CODE] = "exit-code", + [SWAP_FAILURE_SIGNAL] = "signal", + [SWAP_FAILURE_CORE_DUMP] = "core-dump" +}; + +DEFINE_STRING_TABLE_LOOKUP(swap_result, SwapResult); + +const UnitVTable swap_vtable = { + .object_size = sizeof(Swap), + .exec_context_offset = offsetof(Swap, exec_context), + + .sections = + "Unit\0" + "Swap\0" + "Install\0", + + .no_alias = true, + .no_instances = true, + + .init = swap_init, + .load = swap_load, + .done = swap_done, + + .coldplug = swap_coldplug, + + .dump = swap_dump, + + .start = swap_start, + .stop = swap_stop, + + .kill = swap_kill, + + .serialize = swap_serialize, + .deserialize_item = swap_deserialize_item, + + .active_state = swap_active_state, + .sub_state_to_string = swap_sub_state_to_string, + + .check_gc = swap_check_gc, + + .sigchld_event = swap_sigchld_event, + .timer_event = swap_timer_event, + + .reset_failed = swap_reset_failed, + + .bus_interface = "org.freedesktop.systemd1.Swap", + .bus_message_handler = bus_swap_message_handler, + .bus_invalidating_properties = bus_swap_invalidating_properties, + + .following = swap_following, + .following_set = swap_following_set, + + .enumerate = swap_enumerate, + .shutdown = swap_shutdown, + + .status_message_formats = { + .starting_stopping = { + [0] = "Activating swap %s...", + [1] = "Deactivating swap %s...", + }, + .finished_start_job = { + [JOB_DONE] = "Activated swap %s.", + [JOB_FAILED] = "Failed to activate swap %s.", + [JOB_DEPENDENCY] = "Dependency failed for %s.", + [JOB_TIMEOUT] = "Timed out activating swap %s.", + }, + .finished_stop_job = { + [JOB_DONE] = "Deactivated swap %s.", + [JOB_FAILED] = "Failed deactivating swap %s.", + [JOB_TIMEOUT] = "Timed out deactivating swap %s.", + }, + }, +}; diff --git a/src/core/swap.h b/src/core/swap.h new file mode 100644 index 000000000..35d47fd46 --- /dev/null +++ b/src/core/swap.h @@ -0,0 +1,121 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + Copyright 2010 Maarten Lankhorst + + 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 . +***/ + +typedef struct Swap Swap; + +#include "unit.h" + +typedef enum SwapState { + SWAP_DEAD, + SWAP_ACTIVATING, + SWAP_ACTIVE, + SWAP_DEACTIVATING, + SWAP_ACTIVATING_SIGTERM, + SWAP_ACTIVATING_SIGKILL, + SWAP_DEACTIVATING_SIGTERM, + SWAP_DEACTIVATING_SIGKILL, + SWAP_FAILED, + _SWAP_STATE_MAX, + _SWAP_STATE_INVALID = -1 +} SwapState; + +typedef enum SwapExecCommand { + SWAP_EXEC_ACTIVATE, + SWAP_EXEC_DEACTIVATE, + _SWAP_EXEC_COMMAND_MAX, + _SWAP_EXEC_COMMAND_INVALID = -1 +} SwapExecCommand; + +typedef struct SwapParameters { + char *what; + int priority; + bool noauto:1; + bool nofail:1; +} SwapParameters; + +typedef enum SwapResult { + SWAP_SUCCESS, + SWAP_FAILURE_RESOURCES, + SWAP_FAILURE_TIMEOUT, + SWAP_FAILURE_EXIT_CODE, + SWAP_FAILURE_SIGNAL, + SWAP_FAILURE_CORE_DUMP, + _SWAP_RESULT_MAX, + _SWAP_RESULT_INVALID = -1 +} SwapResult; + +struct Swap { + Unit meta; + + char *what; + + SwapParameters parameters_proc_swaps; + SwapParameters parameters_fragment; + + bool from_proc_swaps:1; + bool from_fragment:1; + + /* Used while looking for swaps that vanished or got added + * from/to /proc/swaps */ + bool is_active:1; + bool just_activated:1; + + SwapResult result; + + usec_t timeout_usec; + + ExecCommand exec_command[_SWAP_EXEC_COMMAND_MAX]; + ExecContext exec_context; + KillContext kill_context; + + SwapState state, deserialized_state; + + ExecCommand* control_command; + SwapExecCommand control_command_id; + pid_t control_pid; + + Watch timer_watch; + + /* In order to be able to distinguish dependencies on + different device nodes we might end up creating multiple + devices for the same swap. We chain them up here. */ + + LIST_FIELDS(struct Swap, same_proc_swaps); +}; + +extern const UnitVTable swap_vtable; + +int swap_add_one_mount_link(Swap *s, Mount *m); + +int swap_dispatch_reload(Manager *m); +int swap_fd_event(Manager *m, int events); + +const char* swap_state_to_string(SwapState i); +SwapState swap_state_from_string(const char *s); + +const char* swap_exec_command_to_string(SwapExecCommand i); +SwapExecCommand swap_exec_command_from_string(const char *s); + +const char* swap_result_to_string(SwapResult i); +SwapResult swap_result_from_string(const char *s); diff --git a/src/core/switch-root.c b/src/core/switch-root.c new file mode 100644 index 000000000..ce0e41d51 --- /dev/null +++ b/src/core/switch-root.c @@ -0,0 +1,167 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2012 Harald Hoyer, 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include + +#include "util.h" +#include "path-util.h" +#include "switch-root.h" +#include "missing.h" + +int switch_root(const char *new_root) { + + /* Don't try to unmount/move the old "/", there's no way to do it. */ + static const char move_mounts[] = + "/dev\0" + "/proc\0" + "/sys\0" + "/run\0"; + + int r, old_root_fd = -1; + struct stat new_root_stat; + bool old_root_remove; + const char *i; + _cleanup_free_ char *temporary_old_root = NULL; + + if (path_equal(new_root, "/")) + return 0; + + /* When using pivot_root() we assume that /mnt exists as place + * we can temporarily move the old root to. As we immediately + * unmount it from there it doesn't matter much which + * directory we choose for this, but it should be more likely + * than not that /mnt exists and is suitable as mount point + * and is on the same fs as the old root dir */ + temporary_old_root = strappend(new_root, "/mnt"); + if (!temporary_old_root) + return -ENOMEM; + + old_root_remove = in_initrd(); + + if (stat(new_root, &new_root_stat) < 0) { + r = -errno; + log_error("Failed to stat directory %s: %m", new_root); + goto fail; + } + + /* Work-around for a kernel bug: for some reason the kernel + * refuses switching root if any file systems are mounted + * MS_SHARED. Hence remount them MS_PRIVATE here as a + * work-around. + * + * https://bugzilla.redhat.com/show_bug.cgi?id=847418 */ + if (mount(NULL, "/", NULL, MS_REC|MS_PRIVATE, NULL) < 0) + log_warning("Failed to make \"/\" private mount: %m"); + + NULSTR_FOREACH(i, move_mounts) { + char new_mount[PATH_MAX]; + struct stat sb; + + snprintf(new_mount, sizeof(new_mount), "%s%s", new_root, i); + char_array_0(new_mount); + + if ((stat(new_mount, &sb) < 0) || + sb.st_dev != new_root_stat.st_dev) { + + /* Mount point seems to be mounted already or + * stat failed. Unmount the old mount + * point. */ + if (umount2(i, MNT_DETACH) < 0) + log_warning("Failed to unmount %s: %m", i); + continue; + } + + if (mount(i, new_mount, NULL, MS_MOVE, NULL) < 0) { + log_error("Failed to move mount %s to %s, forcing unmount: %m", i, new_mount); + + if (umount2(i, MNT_FORCE) < 0) + log_warning("Failed to unmount %s: %m", i); + } + } + + if (chdir(new_root) < 0) { + r = -errno; + log_error("Failed to change directory to %s: %m", new_root); + goto fail; + } + + if (old_root_remove) { + old_root_fd = open("/", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_NOCTTY|O_DIRECTORY); + if (old_root_fd < 0) + log_warning("Failed to open root directory: %m"); + } + + /* We first try a pivot_root() so that we can umount the old + * root dir. In many cases (i.e. where rootfs is /), that's + * not possible however, and hence we simply overmount root */ + if (pivot_root(new_root, temporary_old_root) >= 0) { + + /* Immediately get rid of the old root. Since we are + * running off it we need to do this lazily. */ + if (umount2(temporary_old_root, MNT_DETACH) < 0) { + r = -errno; + log_error("Failed to umount old root dir %s: %m", temporary_old_root); + goto fail; + } + + } else if (mount(new_root, "/", NULL, MS_MOVE, NULL) < 0) { + r = -errno; + log_error("Failed to mount moving %s to /: %m", new_root); + goto fail; + } + + if (chroot(".") < 0) { + r = -errno; + log_error("Failed to change root: %m"); + goto fail; + } + + if (chdir("/") < 0) { + r = -errno; + log_error("Failed to change directory: %m"); + goto fail; + } + + if (old_root_fd >= 0) { + struct stat rb; + + if (fstat(old_root_fd, &rb) < 0) + log_warning("Failed to stat old root directory, leaving: %m"); + else { + rm_rf_children(old_root_fd, false, false, &rb); + old_root_fd = -1; + } + } + + r = 0; + +fail: + if (old_root_fd >= 0) + close_nointr_nofail(old_root_fd); + + return r; +} diff --git a/src/core/switch-root.h b/src/core/switch-root.h new file mode 100644 index 000000000..0c4cd1e40 --- /dev/null +++ b/src/core/switch-root.h @@ -0,0 +1,27 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef fooswitchroothfoo +#define fooswitchroothfoo + +/*** + This file is part of systemd. + + Copyright 2012 Harald Hoyer, 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 . +***/ + +int switch_root(const char *switch_root); + +#endif diff --git a/src/core/syscall-list.c b/src/core/syscall-list.c new file mode 100644 index 000000000..05fad3e15 --- /dev/null +++ b/src/core/syscall-list.c @@ -0,0 +1,55 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + +#include +#include + +#include "util.h" + +#include "syscall-list.h" + +const struct syscall_name *lookup_syscall(register const char *str, register unsigned int len); + +#include "syscall-to-name.h" +#include "syscall-from-name.h" + +const char *syscall_to_name(int id) { + if (id < 0 || id >= (int) ELEMENTSOF(syscall_names)) + return NULL; + + return syscall_names[id]; +} + +int syscall_from_name(const char *name) { + const struct syscall_name *sc; + + assert(name); + + sc = lookup_syscall(name, strlen(name)); + if (!sc) + return -1; + + return sc->id; +} + +int syscall_max(void) { + return ELEMENTSOF(syscall_names); +} diff --git a/src/core/syscall-list.h b/src/core/syscall-list.h new file mode 100644 index 000000000..0fc685960 --- /dev/null +++ b/src/core/syscall-list.h @@ -0,0 +1,30 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foosyscalllisthfoo +#define foosyscalllisthfoo + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + +const char *syscall_to_name(int id); +int syscall_from_name(const char *name); + +int syscall_max(void); + +#endif diff --git a/src/core/sysfs-show.h b/src/core/sysfs-show.h new file mode 100644 index 000000000..9ffd129c4 --- /dev/null +++ b/src/core/sysfs-show.h @@ -0,0 +1,24 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +int show_sysfs(const char *seat, const char *prefix, unsigned columns); diff --git a/src/core/system.conf b/src/core/system.conf new file mode 100644 index 000000000..68076d973 --- /dev/null +++ b/src/core/system.conf @@ -0,0 +1,43 @@ +# This file is part of systemd. +# +# 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. +# +# See systemd.conf(5) for details + +[Manager] +#LogLevel=info +#LogTarget=journal-or-kmsg +#LogColor=yes +#LogLocation=no +#DumpCore=yes +#CrashShell=no +#ShowStatus=yes +#CrashChVT=1 +#CPUAffinity=1 2 +#DefaultControllers=cpu +#DefaultStandardOutput=journal +#DefaultStandardError=inherit +#JoinControllers=cpu,cpuacct,cpuset net_cls,net_prio +#RuntimeWatchdogSec=0 +#ShutdownWatchdogSec=10min +#CapabilityBoundingSet= +#TimerSlackNSec= +#DefaultLimitCPU= +#DefaultLimitFSIZE= +#DefaultLimitDATA= +#DefaultLimitSTACK= +#DefaultLimitCORE= +#DefaultLimitRSS= +#DefaultLimitNOFILE= +#DefaultLimitAS= +#DefaultLimitNPROC= +#DefaultLimitMEMLOCK= +#DefaultLimitLOCKS= +#DefaultLimitSIGPENDING= +#DefaultLimitMSGQUEUE= +#DefaultLimitNICE= +#DefaultLimitRTPRIO= +#DefaultLimitRTTIME= diff --git a/src/core/systemd.pc.in b/src/core/systemd.pc.in new file mode 100644 index 000000000..2f49d5df5 --- /dev/null +++ b/src/core/systemd.pc.in @@ -0,0 +1,23 @@ +# This file is part of systemd. +# +# 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. + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +systemdutildir=@rootlibexecdir@ +systemdsystemunitdir=@systemunitdir@ +systemdsystempresetdir=@systempresetdir@ +systemduserunitdir=@userunitdir@ +systemduserpresetdir=@userpresetdir@ +systemdsystemconfdir=@pkgsysconfdir@/system +systemduserconfdir=@pkgsysconfdir@/user +systemdsystemunitpath=${systemdsystemconfdir}:/etc/systemd/system:/run/systemd/system:/usr/local/lib/systemd/system:${systemdsystemunitdir}:/usr/lib/systemd/system:/lib/systemd/system +systemduserunitpath=${systemduserconfdir}:/etc/systemd/user:/run/systemd/user:/usr/local/lib/systemd/user:/usr/local/share/systemd/user:${systemduserunitdir}:/usr/lib/systemd/user:/usr/share/systemd/user + +Name: systemd +Description: systemd System and Service Manager +URL: @PACKAGE_URL@ +Version: @PACKAGE_VERSION@ diff --git a/src/core/target.c b/src/core/target.c new file mode 100644 index 000000000..981424132 --- /dev/null +++ b/src/core/target.c @@ -0,0 +1,239 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include + +#include "unit.h" +#include "target.h" +#include "load-fragment.h" +#include "log.h" +#include "dbus-target.h" +#include "special.h" +#include "unit-name.h" + +static const UnitActiveState state_translation_table[_TARGET_STATE_MAX] = { + [TARGET_DEAD] = UNIT_INACTIVE, + [TARGET_ACTIVE] = UNIT_ACTIVE +}; + +static void target_set_state(Target *t, TargetState state) { + TargetState old_state; + assert(t); + + old_state = t->state; + t->state = state; + + if (state != old_state) + log_debug("%s changed %s -> %s", + UNIT(t)->id, + target_state_to_string(old_state), + target_state_to_string(state)); + + unit_notify(UNIT(t), state_translation_table[old_state], state_translation_table[state], true); +} + +static int target_add_default_dependencies(Target *t) { + + static const UnitDependency deps[] = { + UNIT_REQUIRES, + UNIT_REQUIRES_OVERRIDABLE, + UNIT_REQUISITE, + UNIT_REQUISITE_OVERRIDABLE, + UNIT_WANTS, + UNIT_BINDS_TO, + UNIT_PART_OF + }; + + Iterator i; + Unit *other; + int r; + unsigned k; + + assert(t); + + /* Imply ordering for requirement dependencies on target + * units. Note that when the user created a contradicting + * ordering manually we won't add anything in here to make + * sure we don't create a loop. */ + + for (k = 0; k < ELEMENTSOF(deps); k++) + SET_FOREACH(other, UNIT(t)->dependencies[deps[k]], i) { + r = unit_add_default_target_dependency(other, UNIT(t)); + if (r < 0) + return r; + } + + /* Make sure targets are unloaded on shutdown */ + return unit_add_dependency_by_name(UNIT(t), UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true); +} + +static int target_load(Unit *u) { + Target *t = TARGET(u); + int r; + + assert(t); + + r = unit_load_fragment_and_dropin(u); + if (r < 0) + return r; + + /* This is a new unit? Then let's add in some extras */ + if (u->load_state == UNIT_LOADED && u->default_dependencies) { + r = target_add_default_dependencies(t); + if (r < 0) + return r; + } + + return 0; +} + +static int target_coldplug(Unit *u) { + Target *t = TARGET(u); + + assert(t); + assert(t->state == TARGET_DEAD); + + if (t->deserialized_state != t->state) + target_set_state(t, t->deserialized_state); + + return 0; +} + +static void target_dump(Unit *u, FILE *f, const char *prefix) { + Target *t = TARGET(u); + + assert(t); + assert(f); + + fprintf(f, + "%sTarget State: %s\n", + prefix, target_state_to_string(t->state)); +} + +static int target_start(Unit *u) { + Target *t = TARGET(u); + + assert(t); + assert(t->state == TARGET_DEAD); + + target_set_state(t, TARGET_ACTIVE); + return 0; +} + +static int target_stop(Unit *u) { + Target *t = TARGET(u); + + assert(t); + assert(t->state == TARGET_ACTIVE); + + target_set_state(t, TARGET_DEAD); + return 0; +} + +static int target_serialize(Unit *u, FILE *f, FDSet *fds) { + Target *s = TARGET(u); + + assert(s); + assert(f); + assert(fds); + + unit_serialize_item(u, f, "state", target_state_to_string(s->state)); + return 0; +} + +static int target_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) { + Target *s = TARGET(u); + + assert(u); + assert(key); + assert(value); + assert(fds); + + if (streq(key, "state")) { + TargetState state; + + state = target_state_from_string(value); + if (state < 0) + log_debug("Failed to parse state value %s", value); + else + s->deserialized_state = state; + + } else + log_debug("Unknown serialization key '%s'", key); + + return 0; +} + +static UnitActiveState target_active_state(Unit *u) { + assert(u); + + return state_translation_table[TARGET(u)->state]; +} + +static const char *target_sub_state_to_string(Unit *u) { + assert(u); + + return target_state_to_string(TARGET(u)->state); +} + +static const char* const target_state_table[_TARGET_STATE_MAX] = { + [TARGET_DEAD] = "dead", + [TARGET_ACTIVE] = "active" +}; + +DEFINE_STRING_TABLE_LOOKUP(target_state, TargetState); + +const UnitVTable target_vtable = { + .object_size = sizeof(Target), + .sections = + "Unit\0" + "Target\0" + "Install\0", + + .load = target_load, + .coldplug = target_coldplug, + + .dump = target_dump, + + .start = target_start, + .stop = target_stop, + + .serialize = target_serialize, + .deserialize_item = target_deserialize_item, + + .active_state = target_active_state, + .sub_state_to_string = target_sub_state_to_string, + + .bus_interface = "org.freedesktop.systemd1.Target", + .bus_message_handler = bus_target_message_handler, + + .status_message_formats = { + .finished_start_job = { + [JOB_DONE] = "Reached target %s.", + [JOB_DEPENDENCY] = "Dependency failed for %s.", + }, + .finished_stop_job = { + [JOB_DONE] = "Stopped target %s.", + }, + }, +}; diff --git a/src/core/target.h b/src/core/target.h new file mode 100644 index 000000000..1676553ad --- /dev/null +++ b/src/core/target.h @@ -0,0 +1,44 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +typedef struct Target Target; + +#include "unit.h" + +typedef enum TargetState { + TARGET_DEAD, + TARGET_ACTIVE, + _TARGET_STATE_MAX, + _TARGET_STATE_INVALID = -1 +} TargetState; + +struct Target { + Unit meta; + + TargetState state, deserialized_state; +}; + +extern const UnitVTable target_vtable; + +const char* target_state_to_string(TargetState i); +TargetState target_state_from_string(const char *s); diff --git a/src/core/tcpwrap.c b/src/core/tcpwrap.c new file mode 100644 index 000000000..6c630fac6 --- /dev/null +++ b/src/core/tcpwrap.c @@ -0,0 +1,68 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include + +#ifdef HAVE_LIBWRAP +#include +#endif + +#include "tcpwrap.h" +#include "log.h" + +bool socket_tcpwrap(int fd, const char *name) { +#ifdef HAVE_LIBWRAP + struct request_info req; + union { + struct sockaddr sa; + struct sockaddr_in in; + struct sockaddr_in6 in6; + struct sockaddr_un un; + struct sockaddr_storage storage; + } sa_union; + socklen_t l = sizeof(sa_union); + + if (getsockname(fd, &sa_union.sa, &l) < 0) + return true; + + if (sa_union.sa.sa_family != AF_INET && + sa_union.sa.sa_family != AF_INET6) + return true; + + request_init(&req, + RQ_DAEMON, name, + RQ_FILE, fd, + NULL); + + fromhost(&req); + + if (!hosts_access(&req)) { + log_warning("Connection refused by tcpwrap."); + return false; + } + + log_debug("Connection accepted by tcpwrap."); +#endif + return true; +} diff --git a/src/core/tcpwrap.h b/src/core/tcpwrap.h new file mode 100644 index 000000000..3353b6596 --- /dev/null +++ b/src/core/tcpwrap.h @@ -0,0 +1,26 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +#include + +bool socket_tcpwrap(int fd, const char *name); diff --git a/src/core/timer.c b/src/core/timer.c new file mode 100644 index 000000000..31ef176e7 --- /dev/null +++ b/src/core/timer.c @@ -0,0 +1,616 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include + +#include "unit.h" +#include "unit-name.h" +#include "timer.h" +#include "dbus-timer.h" +#include "special.h" +#include "bus-errors.h" + +static const UnitActiveState state_translation_table[_TIMER_STATE_MAX] = { + [TIMER_DEAD] = UNIT_INACTIVE, + [TIMER_WAITING] = UNIT_ACTIVE, + [TIMER_RUNNING] = UNIT_ACTIVE, + [TIMER_ELAPSED] = UNIT_ACTIVE, + [TIMER_FAILED] = UNIT_FAILED +}; + +static void timer_init(Unit *u) { + Timer *t = TIMER(u); + + assert(u); + assert(u->load_state == UNIT_STUB); + + t->next_elapse_monotonic = (usec_t) -1; + t->next_elapse_realtime = (usec_t) -1; + watch_init(&t->monotonic_watch); + watch_init(&t->realtime_watch); +} + +static void timer_done(Unit *u) { + Timer *t = TIMER(u); + TimerValue *v; + + assert(t); + + while ((v = t->values)) { + LIST_REMOVE(TimerValue, value, t->values, v); + + if (v->calendar_spec) + calendar_spec_free(v->calendar_spec); + + free(v); + } + + unit_unwatch_timer(u, &t->monotonic_watch); + unit_unwatch_timer(u, &t->realtime_watch); + + unit_ref_unset(&t->unit); +} + +static int timer_verify(Timer *t) { + assert(t); + + if (UNIT(t)->load_state != UNIT_LOADED) + return 0; + + if (!t->values) { + log_error_unit(UNIT(t)->id, + "%s lacks value setting. Refusing.", UNIT(t)->id); + return -EINVAL; + } + + return 0; +} + +static int timer_add_default_dependencies(Timer *t) { + int r; + + assert(t); + + if (UNIT(t)->manager->running_as == SYSTEMD_SYSTEM) { + r = unit_add_dependency_by_name(UNIT(t), UNIT_BEFORE, SPECIAL_BASIC_TARGET, NULL, true); + if (r < 0) + return r; + + r = unit_add_two_dependencies_by_name(UNIT(t), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SYSINIT_TARGET, NULL, true); + if (r < 0) + return r; + } + + return unit_add_two_dependencies_by_name(UNIT(t), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true); +} + +static int timer_load(Unit *u) { + Timer *t = TIMER(u); + int r; + + assert(u); + assert(u->load_state == UNIT_STUB); + + r = unit_load_fragment_and_dropin(u); + if (r < 0) + return r; + + if (u->load_state == UNIT_LOADED) { + + if (!UNIT_DEREF(t->unit)) { + Unit *x; + + r = unit_load_related_unit(u, ".service", &x); + if (r < 0) + return r; + + unit_ref_set(&t->unit, x); + } + + r = unit_add_two_dependencies(u, UNIT_BEFORE, UNIT_TRIGGERS, UNIT_DEREF(t->unit), true); + if (r < 0) + return r; + + if (UNIT(t)->default_dependencies) { + r = timer_add_default_dependencies(t); + if (r < 0) + return r; + } + } + + return timer_verify(t); +} + +static void timer_dump(Unit *u, FILE *f, const char *prefix) { + Timer *t = TIMER(u); + TimerValue *v; + + fprintf(f, + "%sTimer State: %s\n" + "%sResult: %s\n" + "%sUnit: %s\n", + prefix, timer_state_to_string(t->state), + prefix, timer_result_to_string(t->result), + prefix, UNIT_DEREF(t->unit)->id); + + LIST_FOREACH(value, v, t->values) { + + if (v->base == TIMER_CALENDAR) { + _cleanup_free_ char *p = NULL; + + calendar_spec_to_string(v->calendar_spec, &p); + + fprintf(f, + "%s%s: %s\n", + prefix, + timer_base_to_string(v->base), + strna(p)); + } else { + char timespan1[FORMAT_TIMESPAN_MAX]; + + fprintf(f, + "%s%s: %s\n", + prefix, + timer_base_to_string(v->base), + strna(format_timespan(timespan1, sizeof(timespan1), v->value))); + } + } +} + +static void timer_set_state(Timer *t, TimerState state) { + TimerState old_state; + assert(t); + + old_state = t->state; + t->state = state; + + if (state != TIMER_WAITING) { + unit_unwatch_timer(UNIT(t), &t->monotonic_watch); + unit_unwatch_timer(UNIT(t), &t->realtime_watch); + } + + if (state != old_state) + log_debug_unit(UNIT(t)->id, + "%s changed %s -> %s", UNIT(t)->id, + timer_state_to_string(old_state), + timer_state_to_string(state)); + + unit_notify(UNIT(t), state_translation_table[old_state], state_translation_table[state], true); +} + +static void timer_enter_waiting(Timer *t, bool initial); + +static int timer_coldplug(Unit *u) { + Timer *t = TIMER(u); + + assert(t); + assert(t->state == TIMER_DEAD); + + if (t->deserialized_state != t->state) { + + if (t->deserialized_state == TIMER_WAITING) + timer_enter_waiting(t, false); + else + timer_set_state(t, t->deserialized_state); + } + + return 0; +} + +static void timer_enter_dead(Timer *t, TimerResult f) { + assert(t); + + if (f != TIMER_SUCCESS) + t->result = f; + + timer_set_state(t, t->result != TIMER_SUCCESS ? TIMER_FAILED : TIMER_DEAD); +} + +static void timer_enter_waiting(Timer *t, bool initial) { + TimerValue *v; + usec_t base = 0; + dual_timestamp ts; + bool found_monotonic = false, found_realtime = false; + int r; + + dual_timestamp_get(&ts); + t->next_elapse_monotonic = t->next_elapse_realtime = 0; + + LIST_FOREACH(value, v, t->values) { + + if (v->disabled) + continue; + + if (v->base == TIMER_CALENDAR) { + + r = calendar_spec_next_usec(v->calendar_spec, ts.realtime, &v->next_elapse); + if (r < 0) + continue; + + if (!initial && v->next_elapse < ts.realtime) { + v->disabled = true; + continue; + } + + if (!found_realtime) + t->next_elapse_realtime = v->next_elapse; + else + t->next_elapse_realtime = MIN(t->next_elapse_realtime, v->next_elapse); + + found_realtime = true; + + } else { + switch (v->base) { + + case TIMER_ACTIVE: + if (state_translation_table[t->state] == UNIT_ACTIVE) + base = UNIT(t)->inactive_exit_timestamp.monotonic; + else + base = ts.monotonic; + break; + + case TIMER_BOOT: + /* CLOCK_MONOTONIC equals the uptime on Linux */ + base = 0; + break; + + case TIMER_STARTUP: + base = UNIT(t)->manager->userspace_timestamp.monotonic; + break; + + case TIMER_UNIT_ACTIVE: + + if (UNIT_DEREF(t->unit)->inactive_exit_timestamp.monotonic <= 0) + continue; + + base = UNIT_DEREF(t->unit)->inactive_exit_timestamp.monotonic; + break; + + case TIMER_UNIT_INACTIVE: + + if (UNIT_DEREF(t->unit)->inactive_enter_timestamp.monotonic <= 0) + continue; + + base = UNIT_DEREF(t->unit)->inactive_enter_timestamp.monotonic; + break; + + default: + assert_not_reached("Unknown timer base"); + } + + v->next_elapse = base + v->value; + + if (!initial && v->next_elapse < ts.monotonic) { + v->disabled = true; + continue; + } + + if (!found_monotonic) + t->next_elapse_monotonic = v->next_elapse; + else + t->next_elapse_monotonic = MIN(t->next_elapse_monotonic, v->next_elapse); + + found_monotonic = true; + } + } + + if (!found_monotonic && !found_realtime) { + log_debug_unit(UNIT(t)->id, "%s: Timer is elapsed.", UNIT(t)->id); + timer_set_state(t, TIMER_ELAPSED); + return; + } + + if (found_monotonic) { + char buf[FORMAT_TIMESPAN_MAX]; + log_debug_unit(UNIT(t)->id, + "%s: Monotonic timer elapses in %s the next time.", + UNIT(t)->id, + format_timespan(buf, sizeof(buf), t->next_elapse_monotonic - ts.monotonic)); + + r = unit_watch_timer(UNIT(t), CLOCK_MONOTONIC, false, t->next_elapse_monotonic, &t->monotonic_watch); + if (r < 0) + goto fail; + } else + unit_unwatch_timer(UNIT(t), &t->monotonic_watch); + + if (found_realtime) { + char buf[FORMAT_TIMESTAMP_MAX]; + log_debug_unit(UNIT(t)->id, + "%s: Realtime timer elapses at %s the next time.", + UNIT(t)->id, + format_timestamp(buf, sizeof(buf), t->next_elapse_realtime)); + + r = unit_watch_timer(UNIT(t), CLOCK_REALTIME, false, t->next_elapse_realtime, &t->realtime_watch); + if (r < 0) + goto fail; + } else + unit_unwatch_timer(UNIT(t), &t->realtime_watch); + + timer_set_state(t, TIMER_WAITING); + return; + +fail: + log_warning_unit(UNIT(t)->id, + "%s failed to enter waiting state: %s", + UNIT(t)->id, strerror(-r)); + timer_enter_dead(t, TIMER_FAILURE_RESOURCES); +} + +static void timer_enter_running(Timer *t) { + DBusError error; + int r; + + assert(t); + dbus_error_init(&error); + + /* Don't start job if we are supposed to go down */ + if (UNIT(t)->job && UNIT(t)->job->type == JOB_STOP) + return; + + r = manager_add_job(UNIT(t)->manager, JOB_START, UNIT_DEREF(t->unit), JOB_REPLACE, true, &error, NULL); + if (r < 0) + goto fail; + + timer_set_state(t, TIMER_RUNNING); + return; + +fail: + log_warning_unit(UNIT(t)->id, + "%s failed to queue unit startup job: %s", + UNIT(t)->id, bus_error(&error, r)); + timer_enter_dead(t, TIMER_FAILURE_RESOURCES); + + dbus_error_free(&error); +} + +static int timer_start(Unit *u) { + Timer *t = TIMER(u); + + assert(t); + assert(t->state == TIMER_DEAD || t->state == TIMER_FAILED); + + if (UNIT_DEREF(t->unit)->load_state != UNIT_LOADED) + return -ENOENT; + + t->result = TIMER_SUCCESS; + timer_enter_waiting(t, true); + return 0; +} + +static int timer_stop(Unit *u) { + Timer *t = TIMER(u); + + assert(t); + assert(t->state == TIMER_WAITING || t->state == TIMER_RUNNING || t->state == TIMER_ELAPSED); + + timer_enter_dead(t, TIMER_SUCCESS); + return 0; +} + +static int timer_serialize(Unit *u, FILE *f, FDSet *fds) { + Timer *t = TIMER(u); + + assert(u); + assert(f); + assert(fds); + + unit_serialize_item(u, f, "state", timer_state_to_string(t->state)); + unit_serialize_item(u, f, "result", timer_result_to_string(t->result)); + + return 0; +} + +static int timer_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) { + Timer *t = TIMER(u); + + assert(u); + assert(key); + assert(value); + assert(fds); + + if (streq(key, "state")) { + TimerState state; + + state = timer_state_from_string(value); + if (state < 0) + log_debug_unit(u->id, "Failed to parse state value %s", value); + else + t->deserialized_state = state; + } else if (streq(key, "result")) { + TimerResult f; + + f = timer_result_from_string(value); + if (f < 0) + log_debug_unit(u->id, "Failed to parse result value %s", value); + else if (f != TIMER_SUCCESS) + t->result = f; + + } else + log_debug_unit(u->id, "Unknown serialization key '%s'", key); + + return 0; +} + +static UnitActiveState timer_active_state(Unit *u) { + assert(u); + + return state_translation_table[TIMER(u)->state]; +} + +static const char *timer_sub_state_to_string(Unit *u) { + assert(u); + + return timer_state_to_string(TIMER(u)->state); +} + +static void timer_timer_event(Unit *u, uint64_t elapsed, Watch *w) { + Timer *t = TIMER(u); + + assert(t); + assert(elapsed == 1); + + if (t->state != TIMER_WAITING) + return; + + log_debug_unit(u->id, "Timer elapsed on %s", u->id); + timer_enter_running(t); +} + +void timer_unit_notify(Unit *u, UnitActiveState new_state) { + Iterator i; + Unit *k; + + if (u->type == UNIT_TIMER) + return; + + SET_FOREACH(k, u->dependencies[UNIT_TRIGGERED_BY], i) { + Timer *t; + TimerValue *v; + + if (k->type != UNIT_TIMER) + continue; + + if (k->load_state != UNIT_LOADED) + continue; + + t = TIMER(k); + + /* Reenable all timers that depend on unit state */ + LIST_FOREACH(value, v, t->values) + if (v->base == TIMER_UNIT_ACTIVE || + v->base == TIMER_UNIT_INACTIVE) + v->disabled = false; + + switch (t->state) { + + case TIMER_WAITING: + case TIMER_ELAPSED: + + /* Recalculate sleep time */ + timer_enter_waiting(t, false); + break; + + case TIMER_RUNNING: + + if (UNIT_IS_INACTIVE_OR_FAILED(new_state)) { + log_debug_unit(UNIT(t)->id, + "%s got notified about unit deactivation.", + UNIT(t)->id); + timer_enter_waiting(t, false); + } + + break; + + case TIMER_DEAD: + case TIMER_FAILED: + break; + + default: + assert_not_reached("Unknown timer state"); + } + } +} + +static void timer_reset_failed(Unit *u) { + Timer *t = TIMER(u); + + assert(t); + + if (t->state == TIMER_FAILED) + timer_set_state(t, TIMER_DEAD); + + t->result = TIMER_SUCCESS; +} + +static void timer_time_change(Unit *u) { + Timer *t = TIMER(u); + + assert(u); + + if (t->state != TIMER_WAITING) + return; + + log_info_unit(u->id, + "%s: time change, recalculating next elapse.", u->id); + timer_enter_waiting(t, false); +} + +static const char* const timer_state_table[_TIMER_STATE_MAX] = { + [TIMER_DEAD] = "dead", + [TIMER_WAITING] = "waiting", + [TIMER_RUNNING] = "running", + [TIMER_ELAPSED] = "elapsed", + [TIMER_FAILED] = "failed" +}; + +DEFINE_STRING_TABLE_LOOKUP(timer_state, TimerState); + +static const char* const timer_base_table[_TIMER_BASE_MAX] = { + [TIMER_ACTIVE] = "OnActiveSec", + [TIMER_BOOT] = "OnBootSec", + [TIMER_STARTUP] = "OnStartupSec", + [TIMER_UNIT_ACTIVE] = "OnUnitActiveSec", + [TIMER_UNIT_INACTIVE] = "OnUnitInactiveSec", + [TIMER_CALENDAR] = "OnCalendar" +}; + +DEFINE_STRING_TABLE_LOOKUP(timer_base, TimerBase); + +static const char* const timer_result_table[_TIMER_RESULT_MAX] = { + [TIMER_SUCCESS] = "success", + [TIMER_FAILURE_RESOURCES] = "resources" +}; + +DEFINE_STRING_TABLE_LOOKUP(timer_result, TimerResult); + +const UnitVTable timer_vtable = { + .object_size = sizeof(Timer), + .sections = + "Unit\0" + "Timer\0" + "Install\0", + + .init = timer_init, + .done = timer_done, + .load = timer_load, + + .coldplug = timer_coldplug, + + .dump = timer_dump, + + .start = timer_start, + .stop = timer_stop, + + .serialize = timer_serialize, + .deserialize_item = timer_deserialize_item, + + .active_state = timer_active_state, + .sub_state_to_string = timer_sub_state_to_string, + + .timer_event = timer_timer_event, + + .reset_failed = timer_reset_failed, + .time_change = timer_time_change, + + .bus_interface = "org.freedesktop.systemd1.Timer", + .bus_message_handler = bus_timer_message_handler, + .bus_invalidating_properties = bus_timer_invalidating_properties +}; diff --git a/src/core/timer.h b/src/core/timer.h new file mode 100644 index 000000000..57a514a68 --- /dev/null +++ b/src/core/timer.h @@ -0,0 +1,96 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +typedef struct Timer Timer; + +#include "unit.h" +#include "calendarspec.h" + +typedef enum TimerState { + TIMER_DEAD, + TIMER_WAITING, + TIMER_RUNNING, + TIMER_ELAPSED, + TIMER_FAILED, + _TIMER_STATE_MAX, + _TIMER_STATE_INVALID = -1 +} TimerState; + +typedef enum TimerBase { + TIMER_ACTIVE, + TIMER_BOOT, + TIMER_STARTUP, + TIMER_UNIT_ACTIVE, + TIMER_UNIT_INACTIVE, + TIMER_CALENDAR, + _TIMER_BASE_MAX, + _TIMER_BASE_INVALID = -1 +} TimerBase; + +typedef struct TimerValue { + TimerBase base; + bool disabled; + clockid_t clock_id; + + usec_t value; + CalendarSpec *calendar_spec; + usec_t next_elapse; + + LIST_FIELDS(struct TimerValue, value); +} TimerValue; + +typedef enum TimerResult { + TIMER_SUCCESS, + TIMER_FAILURE_RESOURCES, + _TIMER_RESULT_MAX, + _TIMER_RESULT_INVALID = -1 +} TimerResult; + +struct Timer { + Unit meta; + + LIST_HEAD(TimerValue, values); + usec_t next_elapse_monotonic; + usec_t next_elapse_realtime; + + TimerState state, deserialized_state; + UnitRef unit; + + Watch monotonic_watch; + Watch realtime_watch; + + TimerResult result; +}; + +void timer_unit_notify(Unit *u, UnitActiveState new_state); + +extern const UnitVTable timer_vtable; + +const char *timer_state_to_string(TimerState i); +TimerState timer_state_from_string(const char *s); + +const char *timer_base_to_string(TimerBase i); +TimerBase timer_base_from_string(const char *s); + +const char* timer_result_to_string(TimerResult i); +TimerResult timer_result_from_string(const char *s); diff --git a/src/core/transaction.c b/src/core/transaction.c new file mode 100644 index 000000000..1854047af --- /dev/null +++ b/src/core/transaction.c @@ -0,0 +1,1128 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include + +#include "transaction.h" +#include "bus-errors.h" + +static void transaction_unlink_job(Transaction *tr, Job *j, bool delete_dependencies); + +static void transaction_delete_job(Transaction *tr, Job *j, bool delete_dependencies) { + assert(tr); + assert(j); + + /* Deletes one job from the transaction */ + + transaction_unlink_job(tr, j, delete_dependencies); + + job_free(j); +} + +static void transaction_delete_unit(Transaction *tr, Unit *u) { + Job *j; + + /* Deletes all jobs associated with a certain unit from the + * transaction */ + + while ((j = hashmap_get(tr->jobs, u))) + transaction_delete_job(tr, j, true); +} + +void transaction_abort(Transaction *tr) { + Job *j; + + assert(tr); + + while ((j = hashmap_first(tr->jobs))) + transaction_delete_job(tr, j, false); + + assert(hashmap_isempty(tr->jobs)); +} + +static void transaction_find_jobs_that_matter_to_anchor(Job *j, unsigned generation) { + JobDependency *l; + + /* A recursive sweep through the graph that marks all units + * that matter to the anchor job, i.e. are directly or + * indirectly a dependency of the anchor job via paths that + * are fully marked as mattering. */ + + j->matters_to_anchor = true; + j->generation = generation; + + LIST_FOREACH(subject, l, j->subject_list) { + + /* This link does not matter */ + if (!l->matters) + continue; + + /* This unit has already been marked */ + if (l->object->generation == generation) + continue; + + transaction_find_jobs_that_matter_to_anchor(l->object, generation); + } +} + +static void transaction_merge_and_delete_job(Transaction *tr, Job *j, Job *other, JobType t) { + JobDependency *l, *last; + + assert(j); + assert(other); + assert(j->unit == other->unit); + assert(!j->installed); + + /* Merges 'other' into 'j' and then deletes 'other'. */ + + j->type = t; + j->state = JOB_WAITING; + j->override = j->override || other->override; + + j->matters_to_anchor = j->matters_to_anchor || other->matters_to_anchor; + + /* Patch us in as new owner of the JobDependency objects */ + last = NULL; + LIST_FOREACH(subject, l, other->subject_list) { + assert(l->subject == other); + l->subject = j; + last = l; + } + + /* Merge both lists */ + if (last) { + last->subject_next = j->subject_list; + if (j->subject_list) + j->subject_list->subject_prev = last; + j->subject_list = other->subject_list; + } + + /* Patch us in as new owner of the JobDependency objects */ + last = NULL; + LIST_FOREACH(object, l, other->object_list) { + assert(l->object == other); + l->object = j; + last = l; + } + + /* Merge both lists */ + if (last) { + last->object_next = j->object_list; + if (j->object_list) + j->object_list->object_prev = last; + j->object_list = other->object_list; + } + + /* Kill the other job */ + other->subject_list = NULL; + other->object_list = NULL; + transaction_delete_job(tr, other, true); +} + +static bool job_is_conflicted_by(Job *j) { + JobDependency *l; + + assert(j); + + /* Returns true if this job is pulled in by a least one + * ConflictedBy dependency. */ + + LIST_FOREACH(object, l, j->object_list) + if (l->conflicts) + return true; + + return false; +} + +static int delete_one_unmergeable_job(Transaction *tr, Job *j) { + Job *k; + + assert(j); + + /* Tries to delete one item in the linked list + * j->transaction_next->transaction_next->... that conflicts + * with another one, in an attempt to make an inconsistent + * transaction work. */ + + /* We rely here on the fact that if a merged with b does not + * merge with c, either a or b merge with c neither */ + LIST_FOREACH(transaction, j, j) + LIST_FOREACH(transaction, k, j->transaction_next) { + Job *d; + + /* Is this one mergeable? Then skip it */ + if (job_type_is_mergeable(j->type, k->type)) + continue; + + /* Ok, we found two that conflict, let's see if we can + * drop one of them */ + if (!j->matters_to_anchor && !k->matters_to_anchor) { + + /* Both jobs don't matter, so let's + * find the one that is smarter to + * remove. Let's think positive and + * rather remove stops then starts -- + * except if something is being + * stopped because it is conflicted by + * another unit in which case we + * rather remove the start. */ + + log_debug_unit(j->unit->id, + "Looking at job %s/%s conflicted_by=%s", + j->unit->id, job_type_to_string(j->type), + yes_no(j->type == JOB_STOP && job_is_conflicted_by(j))); + log_debug_unit(k->unit->id, + "Looking at job %s/%s conflicted_by=%s", + k->unit->id, job_type_to_string(k->type), + yes_no(k->type == JOB_STOP && job_is_conflicted_by(k))); + + if (j->type == JOB_STOP) { + + if (job_is_conflicted_by(j)) + d = k; + else + d = j; + + } else if (k->type == JOB_STOP) { + + if (job_is_conflicted_by(k)) + d = j; + else + d = k; + } else + d = j; + + } else if (!j->matters_to_anchor) + d = j; + else if (!k->matters_to_anchor) + d = k; + else + return -ENOEXEC; + + /* Ok, we can drop one, so let's do so. */ + log_debug_unit(d->unit->id, + "Fixing conflicting jobs by deleting job %s/%s", + d->unit->id, job_type_to_string(d->type)); + transaction_delete_job(tr, d, true); + return 0; + } + + return -EINVAL; +} + +static int transaction_merge_jobs(Transaction *tr, DBusError *e) { + Job *j; + Iterator i; + int r; + + assert(tr); + + /* First step, check whether any of the jobs for one specific + * task conflict. If so, try to drop one of them. */ + HASHMAP_FOREACH(j, tr->jobs, i) { + JobType t; + Job *k; + + t = j->type; + LIST_FOREACH(transaction, k, j->transaction_next) { + if (job_type_merge_and_collapse(&t, k->type, j->unit) >= 0) + continue; + + /* OK, we could not merge all jobs for this + * action. Let's see if we can get rid of one + * of them */ + + r = delete_one_unmergeable_job(tr, j); + if (r >= 0) + /* Ok, we managed to drop one, now + * let's ask our callers to call us + * again after garbage collecting */ + return -EAGAIN; + + /* We couldn't merge anything. Failure */ + dbus_set_error(e, BUS_ERROR_TRANSACTION_JOBS_CONFLICTING, "Transaction contains conflicting jobs '%s' and '%s' for %s. Probably contradicting requirement dependencies configured.", + job_type_to_string(t), job_type_to_string(k->type), k->unit->id); + return r; + } + } + + /* Second step, merge the jobs. */ + HASHMAP_FOREACH(j, tr->jobs, i) { + JobType t = j->type; + Job *k; + + /* Merge all transaction jobs for j->unit */ + LIST_FOREACH(transaction, k, j->transaction_next) + assert_se(job_type_merge_and_collapse(&t, k->type, j->unit) == 0); + + while ((k = j->transaction_next)) { + if (tr->anchor_job == k) { + transaction_merge_and_delete_job(tr, k, j, t); + j = k; + } else + transaction_merge_and_delete_job(tr, j, k, t); + } + + assert(!j->transaction_next); + assert(!j->transaction_prev); + } + + return 0; +} + +static void transaction_drop_redundant(Transaction *tr) { + Job *j; + Iterator i; + + /* Goes through the transaction and removes all jobs of the units + * whose jobs are all noops. If not all of a unit's jobs are + * redundant, they are kept. */ + + assert(tr); + +rescan: + HASHMAP_FOREACH(j, tr->jobs, i) { + Job *k; + + LIST_FOREACH(transaction, k, j) { + + if (tr->anchor_job == k || + !job_type_is_redundant(k->type, unit_active_state(k->unit)) || + (k->unit->job && job_type_is_conflicting(k->type, k->unit->job->type))) + goto next_unit; + } + + /* log_debug("Found redundant job %s/%s, dropping.", j->unit->id, job_type_to_string(j->type)); */ + transaction_delete_job(tr, j, false); + goto rescan; + next_unit:; + } +} + +static bool unit_matters_to_anchor(Unit *u, Job *j) { + assert(u); + assert(!j->transaction_prev); + + /* Checks whether at least one of the jobs for this unit + * matters to the anchor. */ + + LIST_FOREACH(transaction, j, j) + if (j->matters_to_anchor) + return true; + + return false; +} + +static int transaction_verify_order_one(Transaction *tr, Job *j, Job *from, unsigned generation, DBusError *e) { + Iterator i; + Unit *u; + int r; + + assert(tr); + assert(j); + assert(!j->transaction_prev); + + /* Does a recursive sweep through the ordering graph, looking + * for a cycle. If we find cycle we try to break it. */ + + /* Have we seen this before? */ + if (j->generation == generation) { + Job *k, *delete; + + /* If the marker is NULL we have been here already and + * decided the job was loop-free from here. Hence + * shortcut things and return right-away. */ + if (!j->marker) + return 0; + + /* So, the marker is not NULL and we already have been + * here. We have a cycle. Let's try to break it. We go + * backwards in our path and try to find a suitable + * job to remove. We use the marker to find our way + * back, since smart how we are we stored our way back + * in there. */ + log_warning_unit(j->unit->id, + "Found ordering cycle on %s/%s", + j->unit->id, job_type_to_string(j->type)); + + delete = NULL; + for (k = from; k; k = ((k->generation == generation && k->marker != k) ? k->marker : NULL)) { + + /* logging for j not k here here to provide consistent narrative */ + log_info_unit(j->unit->id, + "Walked on cycle path to %s/%s", + k->unit->id, job_type_to_string(k->type)); + + if (!delete && + !unit_matters_to_anchor(k->unit, k)) { + /* Ok, we can drop this one, so let's + * do so. */ + delete = k; + } + + /* Check if this in fact was the beginning of + * the cycle */ + if (k == j) + break; + } + + + if (delete) { + /* logging for j not k here here to provide consistent narrative */ + log_warning_unit(j->unit->id, + "Breaking ordering cycle by deleting job %s/%s", + delete->unit->id, job_type_to_string(delete->type)); + log_error_unit(delete->unit->id, + "Job %s/%s deleted to break ordering cycle starting with %s/%s", + delete->unit->id, job_type_to_string(delete->type), + j->unit->id, job_type_to_string(j->type)); + status_printf(ANSI_HIGHLIGHT_RED_ON " SKIP " ANSI_HIGHLIGHT_OFF, true, + "Ordering cycle found, skipping %s", unit_description(delete->unit)); + transaction_delete_unit(tr, delete->unit); + return -EAGAIN; + } + + log_error("Unable to break cycle"); + + dbus_set_error(e, BUS_ERROR_TRANSACTION_ORDER_IS_CYCLIC, + "Transaction order is cyclic. See system logs for details."); + return -ENOEXEC; + } + + /* Make the marker point to where we come from, so that we can + * find our way backwards if we want to break a cycle. We use + * a special marker for the beginning: we point to + * ourselves. */ + j->marker = from ? from : j; + j->generation = generation; + + /* We assume that the dependencies are bidirectional, and + * hence can ignore UNIT_AFTER */ + SET_FOREACH(u, j->unit->dependencies[UNIT_BEFORE], i) { + Job *o; + + /* Is there a job for this unit? */ + o = hashmap_get(tr->jobs, u); + if (!o) { + /* Ok, there is no job for this in the + * transaction, but maybe there is already one + * running? */ + o = u->job; + if (!o) + continue; + } + + r = transaction_verify_order_one(tr, o, j, generation, e); + if (r < 0) + return r; + } + + /* Ok, let's backtrack, and remember that this entry is not on + * our path anymore. */ + j->marker = NULL; + + return 0; +} + +static int transaction_verify_order(Transaction *tr, unsigned *generation, DBusError *e) { + Job *j; + int r; + Iterator i; + unsigned g; + + assert(tr); + assert(generation); + + /* Check if the ordering graph is cyclic. If it is, try to fix + * that up by dropping one of the jobs. */ + + g = (*generation)++; + + HASHMAP_FOREACH(j, tr->jobs, i) + if ((r = transaction_verify_order_one(tr, j, NULL, g, e)) < 0) + return r; + + return 0; +} + +static void transaction_collect_garbage(Transaction *tr) { + Iterator i; + Job *j; + + assert(tr); + + /* Drop jobs that are not required by any other job */ + +rescan: + HASHMAP_FOREACH(j, tr->jobs, i) { + if (tr->anchor_job == j || j->object_list) { + /* log_debug("Keeping job %s/%s because of %s/%s", */ + /* j->unit->id, job_type_to_string(j->type), */ + /* j->object_list->subject ? j->object_list->subject->unit->id : "root", */ + /* j->object_list->subject ? job_type_to_string(j->object_list->subject->type) : "root"); */ + continue; + } + + /* log_debug("Garbage collecting job %s/%s", j->unit->id, job_type_to_string(j->type)); */ + transaction_delete_job(tr, j, true); + goto rescan; + } +} + +static int transaction_is_destructive(Transaction *tr, DBusError *e) { + Iterator i; + Job *j; + + assert(tr); + + /* Checks whether applying this transaction means that + * existing jobs would be replaced */ + + HASHMAP_FOREACH(j, tr->jobs, i) { + + /* Assume merged */ + assert(!j->transaction_prev); + assert(!j->transaction_next); + + if (j->unit->job && + !job_type_is_superset(j->type, j->unit->job->type)) { + + dbus_set_error(e, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE, "Transaction is destructive."); + return -EEXIST; + } + } + + return 0; +} + +static void transaction_minimize_impact(Transaction *tr) { + Job *j; + Iterator i; + + assert(tr); + + /* Drops all unnecessary jobs that reverse already active jobs + * or that stop a running service. */ + +rescan: + HASHMAP_FOREACH(j, tr->jobs, i) { + LIST_FOREACH(transaction, j, j) { + bool stops_running_service, changes_existing_job; + + /* If it matters, we shouldn't drop it */ + if (j->matters_to_anchor) + continue; + + /* Would this stop a running service? + * Would this change an existing job? + * If so, let's drop this entry */ + + stops_running_service = + j->type == JOB_STOP && UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(j->unit)); + + changes_existing_job = + j->unit->job && + job_type_is_conflicting(j->type, j->unit->job->type); + + if (!stops_running_service && !changes_existing_job) + continue; + + if (stops_running_service) + log_debug_unit(j->unit->id, + "%s/%s would stop a running service.", + j->unit->id, job_type_to_string(j->type)); + + if (changes_existing_job) + log_debug_unit(j->unit->id, + "%s/%s would change existing job.", + j->unit->id, job_type_to_string(j->type)); + + /* Ok, let's get rid of this */ + log_debug_unit(j->unit->id, + "Deleting %s/%s to minimize impact.", + j->unit->id, job_type_to_string(j->type)); + + transaction_delete_job(tr, j, true); + goto rescan; + } + } +} + +static int transaction_apply(Transaction *tr, Manager *m, JobMode mode) { + Iterator i; + Job *j; + int r; + + /* Moves the transaction jobs to the set of active jobs */ + + if (mode == JOB_ISOLATE) { + + /* When isolating first kill all installed jobs which + * aren't part of the new transaction */ + HASHMAP_FOREACH(j, m->jobs, i) { + assert(j->installed); + + if (hashmap_get(tr->jobs, j->unit)) + continue; + + /* Not invalidating recursively. Avoids triggering + * OnFailure= actions of dependent jobs. Also avoids + * invalidating our iterator. */ + job_finish_and_invalidate(j, JOB_CANCELED, false); + } + } + + HASHMAP_FOREACH(j, tr->jobs, i) { + /* Assume merged */ + assert(!j->transaction_prev); + assert(!j->transaction_next); + + r = hashmap_put(m->jobs, UINT32_TO_PTR(j->id), j); + if (r < 0) + goto rollback; + } + + while ((j = hashmap_steal_first(tr->jobs))) { + Job *installed_job; + + /* Clean the job dependencies */ + transaction_unlink_job(tr, j, false); + + installed_job = job_install(j); + if (installed_job != j) { + /* j has been merged into a previously installed job */ + if (tr->anchor_job == j) + tr->anchor_job = installed_job; + hashmap_remove(m->jobs, UINT32_TO_PTR(j->id)); + job_free(j); + j = installed_job; + } + + job_add_to_run_queue(j); + job_add_to_dbus_queue(j); + job_start_timer(j); + } + + return 0; + +rollback: + + HASHMAP_FOREACH(j, tr->jobs, i) + hashmap_remove(m->jobs, UINT32_TO_PTR(j->id)); + + return r; +} + +int transaction_activate(Transaction *tr, Manager *m, JobMode mode, DBusError *e) { + Iterator i; + Job *j; + int r; + unsigned generation = 1; + + assert(tr); + + /* This applies the changes recorded in tr->jobs to + * the actual list of jobs, if possible. */ + + /* Reset the generation counter of all installed jobs. The detection of cycles + * looks at installed jobs. If they had a non-zero generation from some previous + * walk of the graph, the algorithm would break. */ + HASHMAP_FOREACH(j, m->jobs, i) + j->generation = 0; + + /* First step: figure out which jobs matter */ + transaction_find_jobs_that_matter_to_anchor(tr->anchor_job, generation++); + + /* Second step: Try not to stop any running services if + * we don't have to. Don't try to reverse running + * jobs if we don't have to. */ + if (mode == JOB_FAIL) + transaction_minimize_impact(tr); + + /* Third step: Drop redundant jobs */ + transaction_drop_redundant(tr); + + for (;;) { + /* Fourth step: Let's remove unneeded jobs that might + * be lurking. */ + if (mode != JOB_ISOLATE) + transaction_collect_garbage(tr); + + /* Fifth step: verify order makes sense and correct + * cycles if necessary and possible */ + r = transaction_verify_order(tr, &generation, e); + if (r >= 0) + break; + + if (r != -EAGAIN) { + log_warning("Requested transaction contains an unfixable cyclic ordering dependency: %s", bus_error(e, r)); + return r; + } + + /* Let's see if the resulting transaction ordering + * graph is still cyclic... */ + } + + for (;;) { + /* Sixth step: let's drop unmergeable entries if + * necessary and possible, merge entries we can + * merge */ + r = transaction_merge_jobs(tr, e); + if (r >= 0) + break; + + if (r != -EAGAIN) { + log_warning("Requested transaction contains unmergeable jobs: %s", bus_error(e, r)); + return r; + } + + /* Seventh step: an entry got dropped, let's garbage + * collect its dependencies. */ + if (mode != JOB_ISOLATE) + transaction_collect_garbage(tr); + + /* Let's see if the resulting transaction still has + * unmergeable entries ... */ + } + + /* Eights step: Drop redundant jobs again, if the merging now allows us to drop more. */ + transaction_drop_redundant(tr); + + /* Ninth step: check whether we can actually apply this */ + if (mode == JOB_FAIL) { + r = transaction_is_destructive(tr, e); + if (r < 0) { + log_notice("Requested transaction contradicts existing jobs: %s", bus_error(e, r)); + return r; + } + } + + /* Tenth step: apply changes */ + r = transaction_apply(tr, m, mode); + if (r < 0) { + log_warning("Failed to apply transaction: %s", strerror(-r)); + return r; + } + + assert(hashmap_isempty(tr->jobs)); + + if (!hashmap_isempty(m->jobs)) { + /* Are there any jobs now? Then make sure we have the + * idle pipe around. We don't really care too much + * whether this works or not, as the idle pipe is a + * feature for cosmetics, not actually useful for + * anything beyond that. */ + + if (m->idle_pipe[0] < 0 && m->idle_pipe[1] < 0) + pipe2(m->idle_pipe, O_NONBLOCK|O_CLOEXEC); + } + + return 0; +} + +static Job* transaction_add_one_job(Transaction *tr, JobType type, Unit *unit, bool override, bool *is_new) { + Job *j, *f; + + assert(tr); + assert(unit); + + /* Looks for an existing prospective job and returns that. If + * it doesn't exist it is created and added to the prospective + * jobs list. */ + + f = hashmap_get(tr->jobs, unit); + + LIST_FOREACH(transaction, j, f) { + assert(j->unit == unit); + + if (j->type == type) { + if (is_new) + *is_new = false; + return j; + } + } + + j = job_new(unit, type); + if (!j) + return NULL; + + j->generation = 0; + j->marker = NULL; + j->matters_to_anchor = false; + j->override = override; + + LIST_PREPEND(Job, transaction, f, j); + + if (hashmap_replace(tr->jobs, unit, f) < 0) { + LIST_REMOVE(Job, transaction, f, j); + job_free(j); + return NULL; + } + + if (is_new) + *is_new = true; + + /* log_debug("Added job %s/%s to transaction.", unit->id, job_type_to_string(type)); */ + + return j; +} + +static void transaction_unlink_job(Transaction *tr, Job *j, bool delete_dependencies) { + assert(tr); + assert(j); + + if (j->transaction_prev) + j->transaction_prev->transaction_next = j->transaction_next; + else if (j->transaction_next) + hashmap_replace(tr->jobs, j->unit, j->transaction_next); + else + hashmap_remove_value(tr->jobs, j->unit, j); + + if (j->transaction_next) + j->transaction_next->transaction_prev = j->transaction_prev; + + j->transaction_prev = j->transaction_next = NULL; + + while (j->subject_list) + job_dependency_free(j->subject_list); + + while (j->object_list) { + Job *other = j->object_list->matters ? j->object_list->subject : NULL; + + job_dependency_free(j->object_list); + + if (other && delete_dependencies) { + log_debug_unit(other->unit->id, + "Deleting job %s/%s as dependency of job %s/%s", + other->unit->id, job_type_to_string(other->type), + j->unit->id, job_type_to_string(j->type)); + transaction_delete_job(tr, other, delete_dependencies); + } + } +} + +int transaction_add_job_and_dependencies( + Transaction *tr, + JobType type, + Unit *unit, + Job *by, + bool matters, + bool override, + bool conflicts, + bool ignore_requirements, + bool ignore_order, + DBusError *e) { + Job *ret; + Iterator i; + Unit *dep; + int r; + bool is_new; + + assert(tr); + assert(type < _JOB_TYPE_MAX); + assert(type < _JOB_TYPE_MAX_IN_TRANSACTION); + assert(unit); + + /* log_debug("Pulling in %s/%s from %s/%s", */ + /* unit->id, job_type_to_string(type), */ + /* by ? by->unit->id : "NA", */ + /* by ? job_type_to_string(by->type) : "NA"); */ + + if (unit->load_state != UNIT_LOADED && + unit->load_state != UNIT_ERROR && + unit->load_state != UNIT_MASKED) { + dbus_set_error(e, BUS_ERROR_LOAD_FAILED, "Unit %s is not loaded properly.", unit->id); + return -EINVAL; + } + + if (type != JOB_STOP && unit->load_state == UNIT_ERROR) { + dbus_set_error(e, BUS_ERROR_LOAD_FAILED, + "Unit %s failed to load: %s. " + "See system logs and 'systemctl status %s' for details.", + unit->id, + strerror(-unit->load_error), + unit->id); + return -EINVAL; + } + + if (type != JOB_STOP && unit->load_state == UNIT_MASKED) { + dbus_set_error(e, BUS_ERROR_MASKED, "Unit %s is masked.", unit->id); + return -EADDRNOTAVAIL; + } + + if (!unit_job_is_applicable(unit, type)) { + dbus_set_error(e, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE, "Job type %s is not applicable for unit %s.", job_type_to_string(type), unit->id); + return -EBADR; + } + + /* First add the job. */ + ret = transaction_add_one_job(tr, type, unit, override, &is_new); + if (!ret) + return -ENOMEM; + + ret->ignore_order = ret->ignore_order || ignore_order; + + /* Then, add a link to the job. */ + if (by) { + if (!job_dependency_new(by, ret, matters, conflicts)) + return -ENOMEM; + } else { + /* If the job has no parent job, it is the anchor job. */ + assert(!tr->anchor_job); + tr->anchor_job = ret; + } + + if (is_new && !ignore_requirements && type != JOB_NOP) { + Set *following; + + /* If we are following some other unit, make sure we + * add all dependencies of everybody following. */ + if (unit_following_set(ret->unit, &following) > 0) { + SET_FOREACH(dep, following, i) { + r = transaction_add_job_and_dependencies(tr, type, dep, ret, false, override, false, false, ignore_order, e); + if (r < 0) { + log_warning_unit(dep->id, + "Cannot add dependency job for unit %s, ignoring: %s", + dep->id, bus_error(e, r)); + + if (e) + dbus_error_free(e); + } + } + + set_free(following); + } + + /* Finally, recursively add in all dependencies. */ + if (type == JOB_START || type == JOB_RESTART) { + SET_FOREACH(dep, ret->unit->dependencies[UNIT_REQUIRES], i) { + r = transaction_add_job_and_dependencies(tr, JOB_START, dep, ret, true, override, false, false, ignore_order, e); + if (r < 0) { + if (r != -EBADR) + goto fail; + + if (e) + dbus_error_free(e); + } + } + + SET_FOREACH(dep, ret->unit->dependencies[UNIT_BINDS_TO], i) { + r = transaction_add_job_and_dependencies(tr, JOB_START, dep, ret, true, override, false, false, ignore_order, e); + if (r < 0) { + if (r != -EBADR) + goto fail; + + if (e) + dbus_error_free(e); + } + } + + SET_FOREACH(dep, ret->unit->dependencies[UNIT_REQUIRES_OVERRIDABLE], i) { + r = transaction_add_job_and_dependencies(tr, JOB_START, dep, ret, !override, override, false, false, ignore_order, e); + if (r < 0) { + log_full_unit(r == -EADDRNOTAVAIL ? LOG_DEBUG : LOG_WARNING, dep->id, + "Cannot add dependency job for unit %s, ignoring: %s", + dep->id, bus_error(e, r)); + + if (e) + dbus_error_free(e); + } + } + + SET_FOREACH(dep, ret->unit->dependencies[UNIT_WANTS], i) { + r = transaction_add_job_and_dependencies(tr, JOB_START, dep, ret, false, false, false, false, ignore_order, e); + if (r < 0) { + log_full_unit(r == -EADDRNOTAVAIL ? LOG_DEBUG : LOG_WARNING, dep->id, + "Cannot add dependency job for unit %s, ignoring: %s", + dep->id, bus_error(e, r)); + + if (e) + dbus_error_free(e); + } + } + + SET_FOREACH(dep, ret->unit->dependencies[UNIT_REQUISITE], i) { + r = transaction_add_job_and_dependencies(tr, JOB_VERIFY_ACTIVE, dep, ret, true, override, false, false, ignore_order, e); + if (r < 0) { + if (r != -EBADR) + goto fail; + + if (e) + dbus_error_free(e); + } + } + + SET_FOREACH(dep, ret->unit->dependencies[UNIT_REQUISITE_OVERRIDABLE], i) { + r = transaction_add_job_and_dependencies(tr, JOB_VERIFY_ACTIVE, dep, ret, !override, override, false, false, ignore_order, e); + if (r < 0) { + log_full_unit(r == -EADDRNOTAVAIL ? LOG_DEBUG : LOG_WARNING, dep->id, + "Cannot add dependency job for unit %s, ignoring: %s", + dep->id, bus_error(e, r)); + + if (e) + dbus_error_free(e); + } + } + + SET_FOREACH(dep, ret->unit->dependencies[UNIT_CONFLICTS], i) { + r = transaction_add_job_and_dependencies(tr, JOB_STOP, dep, ret, true, override, true, false, ignore_order, e); + if (r < 0) { + if (r != -EBADR) + goto fail; + + if (e) + dbus_error_free(e); + } + } + + SET_FOREACH(dep, ret->unit->dependencies[UNIT_CONFLICTED_BY], i) { + r = transaction_add_job_and_dependencies(tr, JOB_STOP, dep, ret, false, override, false, false, ignore_order, e); + if (r < 0) { + log_warning_unit(dep->id, + "Cannot add dependency job for unit %s, ignoring: %s", + dep->id, bus_error(e, r)); + + if (e) + dbus_error_free(e); + } + } + + } + + if (type == JOB_STOP || type == JOB_RESTART) { + + SET_FOREACH(dep, ret->unit->dependencies[UNIT_REQUIRED_BY], i) { + r = transaction_add_job_and_dependencies(tr, type, dep, ret, true, override, false, false, ignore_order, e); + if (r < 0) { + if (r != -EBADR) + goto fail; + + if (e) + dbus_error_free(e); + } + } + + SET_FOREACH(dep, ret->unit->dependencies[UNIT_BOUND_BY], i) { + r = transaction_add_job_and_dependencies(tr, type, dep, ret, true, override, false, false, ignore_order, e); + if (r < 0) { + if (r != -EBADR) + goto fail; + + if (e) + dbus_error_free(e); + } + } + + SET_FOREACH(dep, ret->unit->dependencies[UNIT_CONSISTS_OF], i) { + r = transaction_add_job_and_dependencies(tr, type, dep, ret, true, override, false, false, ignore_order, e); + if (r < 0) { + if (r != -EBADR) + goto fail; + + if (e) + dbus_error_free(e); + } + } + + } + + if (type == JOB_RELOAD) { + + SET_FOREACH(dep, ret->unit->dependencies[UNIT_PROPAGATES_RELOAD_TO], i) { + r = transaction_add_job_and_dependencies(tr, JOB_RELOAD, dep, ret, false, override, false, false, ignore_order, e); + if (r < 0) { + log_warning_unit(dep->id, + "Cannot add dependency reload job for unit %s, ignoring: %s", + dep->id, bus_error(e, r)); + + if (e) + dbus_error_free(e); + } + } + } + + /* JOB_VERIFY_STARTED require no dependency handling */ + } + + return 0; + +fail: + return r; +} + +int transaction_add_isolate_jobs(Transaction *tr, Manager *m) { + Iterator i; + Unit *u; + char *k; + int r; + + assert(tr); + assert(m); + + HASHMAP_FOREACH_KEY(u, k, m->units, i) { + + /* ignore aliases */ + if (u->id != k) + continue; + + if (u->ignore_on_isolate) + continue; + + /* No need to stop inactive jobs */ + if (UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(u)) && !u->job) + continue; + + /* Is there already something listed for this? */ + if (hashmap_get(tr->jobs, u)) + continue; + + r = transaction_add_job_and_dependencies(tr, JOB_STOP, u, tr->anchor_job, true, false, false, false, false, NULL); + if (r < 0) + log_warning_unit(u->id, + "Cannot add isolate job for unit %s, ignoring: %s", + u->id, strerror(-r)); + } + + return 0; +} + +Transaction *transaction_new(void) { + Transaction *tr; + + tr = new0(Transaction, 1); + if (!tr) + return NULL; + + tr->jobs = hashmap_new(trivial_hash_func, trivial_compare_func); + if (!tr->jobs) { + free(tr); + return NULL; + } + + return tr; +} + +void transaction_free(Transaction *tr) { + assert(hashmap_isempty(tr->jobs)); + hashmap_free(tr->jobs); + free(tr); +} diff --git a/src/core/transaction.h b/src/core/transaction.h new file mode 100644 index 000000000..67ace4da0 --- /dev/null +++ b/src/core/transaction.h @@ -0,0 +1,56 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef footransactionhfoo +#define footransactionhfoo + +/*** + 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 . +***/ + +typedef struct Transaction Transaction; + +#include "unit.h" +#include "manager.h" +#include "job.h" +#include "hashmap.h" + +struct Transaction { + /* Jobs to be added */ + Hashmap *jobs; /* Unit object => Job object list 1:1 */ + Job *anchor_job; /* the job the user asked for */ +}; + +Transaction *transaction_new(void); +void transaction_free(Transaction *tr); + +int transaction_add_job_and_dependencies( + Transaction *tr, + JobType type, + Unit *unit, + Job *by, + bool matters, + bool override, + bool conflicts, + bool ignore_requirements, + bool ignore_order, + DBusError *e); +int transaction_activate(Transaction *tr, Manager *m, JobMode mode, DBusError *e); +int transaction_add_isolate_jobs(Transaction *tr, Manager *m); +void transaction_abort(Transaction *tr); + +#endif diff --git a/src/core/umount.c b/src/core/umount.c new file mode 100644 index 000000000..96232d38d --- /dev/null +++ b/src/core/umount.c @@ -0,0 +1,638 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 ProFUSION embedded systems + + 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "list.h" +#include "mount-setup.h" +#include "umount.h" +#include "path-util.h" +#include "util.h" +#include "virt.h" + +typedef struct MountPoint { + char *path; + dev_t devnum; + LIST_FIELDS (struct MountPoint, mount_point); +} MountPoint; + +static void mount_point_free(MountPoint **head, MountPoint *m) { + assert(head); + assert(m); + + LIST_REMOVE(MountPoint, mount_point, *head, m); + + free(m->path); + free(m); +} + +static void mount_points_list_free(MountPoint **head) { + assert(head); + + while (*head) + mount_point_free(head, *head); +} + +static int mount_points_list_get(MountPoint **head) { + FILE *proc_self_mountinfo; + char *path, *p; + unsigned int i; + int r; + + assert(head); + + if (!(proc_self_mountinfo = fopen("/proc/self/mountinfo", "re"))) + return -errno; + + for (i = 1;; i++) { + int k; + MountPoint *m; + + path = p = NULL; + + if ((k = fscanf(proc_self_mountinfo, + "%*s " /* (1) mount id */ + "%*s " /* (2) parent id */ + "%*s " /* (3) major:minor */ + "%*s " /* (4) root */ + "%ms " /* (5) mount point */ + "%*s" /* (6) mount options */ + "%*[^-]" /* (7) optional fields */ + "- " /* (8) separator */ + "%*s " /* (9) file system type */ + "%*s" /* (10) mount source */ + "%*s" /* (11) mount options 2 */ + "%*[^\n]", /* some rubbish at the end */ + &path)) != 1) { + if (k == EOF) + break; + + log_warning("Failed to parse /proc/self/mountinfo:%u.", i); + + free(path); + continue; + } + + p = cunescape(path); + free(path); + + if (!p) { + r = -ENOMEM; + goto finish; + } + + /* Ignore mount points we can't unmount because they + * are API or because we are keeping them open (like + * /dev/console) */ + if (mount_point_is_api(p) || + mount_point_ignore(p) || + path_equal(p, "/dev/console")) { + free(p); + continue; + } + + if (!(m = new0(MountPoint, 1))) { + free(p); + r = -ENOMEM; + goto finish; + } + + m->path = p; + LIST_PREPEND(MountPoint, mount_point, *head, m); + } + + r = 0; + +finish: + fclose(proc_self_mountinfo); + + return r; +} + +static int swap_list_get(MountPoint **head) { + FILE *proc_swaps; + unsigned int i; + int r; + + assert(head); + + if (!(proc_swaps = fopen("/proc/swaps", "re"))) + return (errno == ENOENT) ? 0 : -errno; + + (void) fscanf(proc_swaps, "%*s %*s %*s %*s %*s\n"); + + for (i = 2;; i++) { + MountPoint *swap; + char *dev = NULL, *d; + int k; + + if ((k = fscanf(proc_swaps, + "%ms " /* device/file */ + "%*s " /* type of swap */ + "%*s " /* swap size */ + "%*s " /* used */ + "%*s\n", /* priority */ + &dev)) != 1) { + + if (k == EOF) + break; + + log_warning("Failed to parse /proc/swaps:%u.", i); + + free(dev); + continue; + } + + if (endswith(dev, "(deleted)")) { + free(dev); + continue; + } + + d = cunescape(dev); + free(dev); + + if (!d) { + r = -ENOMEM; + goto finish; + } + + if (!(swap = new0(MountPoint, 1))) { + free(d); + r = -ENOMEM; + goto finish; + } + + swap->path = d; + LIST_PREPEND(MountPoint, mount_point, *head, swap); + } + + r = 0; + +finish: + fclose(proc_swaps); + + return r; +} + +static int loopback_list_get(MountPoint **head) { + int r; + struct udev *udev; + struct udev_enumerate *e = NULL; + struct udev_list_entry *item = NULL, *first = NULL; + + assert(head); + + if (!(udev = udev_new())) { + r = -ENOMEM; + goto finish; + } + + if (!(e = udev_enumerate_new(udev))) { + r = -ENOMEM; + goto finish; + } + + if (udev_enumerate_add_match_subsystem(e, "block") < 0 || + udev_enumerate_add_match_sysname(e, "loop*") < 0) { + r = -EIO; + goto finish; + } + + if (udev_enumerate_scan_devices(e) < 0) { + r = -EIO; + goto finish; + } + + first = udev_enumerate_get_list_entry(e); + udev_list_entry_foreach(item, first) { + MountPoint *lb; + struct udev_device *d; + char *loop; + const char *dn; + + if (!(d = udev_device_new_from_syspath(udev, udev_list_entry_get_name(item)))) { + r = -ENOMEM; + goto finish; + } + + if (!(dn = udev_device_get_devnode(d))) { + udev_device_unref(d); + continue; + } + + loop = strdup(dn); + udev_device_unref(d); + + if (!loop) { + r = -ENOMEM; + goto finish; + } + + if (!(lb = new0(MountPoint, 1))) { + free(loop); + r = -ENOMEM; + goto finish; + } + + lb->path = loop; + LIST_PREPEND(MountPoint, mount_point, *head, lb); + } + + r = 0; + +finish: + if (e) + udev_enumerate_unref(e); + + if (udev) + udev_unref(udev); + + return r; +} + +static int dm_list_get(MountPoint **head) { + int r; + struct udev *udev; + struct udev_enumerate *e = NULL; + struct udev_list_entry *item = NULL, *first = NULL; + + assert(head); + + if (!(udev = udev_new())) { + r = -ENOMEM; + goto finish; + } + + if (!(e = udev_enumerate_new(udev))) { + r = -ENOMEM; + goto finish; + } + + if (udev_enumerate_add_match_subsystem(e, "block") < 0 || + udev_enumerate_add_match_sysname(e, "dm-*") < 0) { + r = -EIO; + goto finish; + } + + if (udev_enumerate_scan_devices(e) < 0) { + r = -EIO; + goto finish; + } + + first = udev_enumerate_get_list_entry(e); + + udev_list_entry_foreach(item, first) { + MountPoint *m; + struct udev_device *d; + dev_t devnum; + char *node; + const char *dn; + + if (!(d = udev_device_new_from_syspath(udev, udev_list_entry_get_name(item)))) { + r = -ENOMEM; + goto finish; + } + + devnum = udev_device_get_devnum(d); + dn = udev_device_get_devnode(d); + + if (major(devnum) == 0 || !dn) { + udev_device_unref(d); + continue; + } + + node = strdup(dn); + udev_device_unref(d); + + if (!node) { + r = -ENOMEM; + goto finish; + } + + if (!(m = new(MountPoint, 1))) { + free(node); + r = -ENOMEM; + goto finish; + } + + m->path = node; + m->devnum = devnum; + LIST_PREPEND(MountPoint, mount_point, *head, m); + } + + r = 0; + +finish: + if (e) + udev_enumerate_unref(e); + + if (udev) + udev_unref(udev); + + return r; +} + +static int delete_loopback(const char *device) { + int fd, r; + + if ((fd = open(device, O_RDONLY|O_CLOEXEC)) < 0) + return errno == ENOENT ? 0 : -errno; + + r = ioctl(fd, LOOP_CLR_FD, 0); + close_nointr_nofail(fd); + + if (r >= 0) + return 1; + + /* ENXIO: not bound, so no error */ + if (errno == ENXIO) + return 0; + + return -errno; +} + +static int delete_dm(dev_t devnum) { + int fd, r; + struct dm_ioctl dm; + + assert(major(devnum) != 0); + + if ((fd = open("/dev/mapper/control", O_RDWR|O_CLOEXEC)) < 0) + return -errno; + + zero(dm); + dm.version[0] = DM_VERSION_MAJOR; + dm.version[1] = DM_VERSION_MINOR; + dm.version[2] = DM_VERSION_PATCHLEVEL; + + dm.data_size = sizeof(dm); + dm.dev = devnum; + + r = ioctl(fd, DM_DEV_REMOVE, &dm); + close_nointr_nofail(fd); + + return r >= 0 ? 0 : -errno; +} + +static int mount_points_list_umount(MountPoint **head, bool *changed, bool log_error) { + MountPoint *m, *n; + int n_failed = 0; + + assert(head); + + LIST_FOREACH_SAFE(mount_point, m, n, *head) { + + /* If we are in a container, don't attempt to + read-only mount anything as that brings no real + benefits, but might confuse the host, as we remount + the superblock here, not the bind mound. */ + if (detect_container(NULL) <= 0) { + /* We always try to remount directories + * read-only first, before we go on and umount + * them. + * + * Mount points can be stacked. If a mount + * point is stacked below / or /usr, we + * cannnot umount or remount it directly, + * since there is no way to refer to the + * underlying mount. There's nothing we can do + * about it for the general case, but we can + * do something about it if it is aliased + * somehwere else via a bind mount. If we + * explicitly remount the super block of that + * alias read-only we hence should be + * relatively safe regarding keeping the fs we + * can otherwise not see dirty. */ + mount(NULL, m->path, NULL, MS_REMOUNT|MS_RDONLY, NULL); + } + + /* Skip / and /usr since we cannot unmount that + * anyway, since we are running from it. They have + * already been remounted ro. */ + if (path_equal(m->path, "/") +#ifndef HAVE_SPLIT_USR + || path_equal(m->path, "/usr") +#endif + ) + continue; + + /* Trying to umount. Forcing to umount if busy (only for NFS mounts) */ + log_info("Unmounting %s.", m->path); + if (umount2(m->path, MNT_FORCE) == 0) { + if (changed) + *changed = true; + + mount_point_free(head, m); + } else if (log_error) { + log_warning("Could not unmount %s: %m", m->path); + n_failed++; + } + } + + return n_failed; +} + +static int swap_points_list_off(MountPoint **head, bool *changed) { + MountPoint *m, *n; + int n_failed = 0; + + assert(head); + + LIST_FOREACH_SAFE(mount_point, m, n, *head) { + log_info("Deactivating swap %s.", m->path); + if (swapoff(m->path) == 0) { + if (changed) + *changed = true; + + mount_point_free(head, m); + } else { + log_warning("Could not deactivate swap %s: %m", m->path); + n_failed++; + } + } + + return n_failed; +} + +static int loopback_points_list_detach(MountPoint **head, bool *changed) { + MountPoint *m, *n; + int n_failed = 0, k; + struct stat root_st; + + assert(head); + + k = lstat("/", &root_st); + + LIST_FOREACH_SAFE(mount_point, m, n, *head) { + int r; + struct stat loopback_st; + + if (k >= 0 && + major(root_st.st_dev) != 0 && + lstat(m->path, &loopback_st) >= 0 && + root_st.st_dev == loopback_st.st_rdev) { + n_failed ++; + continue; + } + + log_info("Detaching loopback %s.", m->path); + r = delete_loopback(m->path); + if (r >= 0) { + if (r > 0 && changed) + *changed = true; + + mount_point_free(head, m); + } else { + log_warning("Could not detach loopback %s: %m", m->path); + n_failed++; + } + } + + return n_failed; +} + +static int dm_points_list_detach(MountPoint **head, bool *changed) { + MountPoint *m, *n; + int n_failed = 0, k; + struct stat root_st; + + assert(head); + + k = lstat("/", &root_st); + + LIST_FOREACH_SAFE(mount_point, m, n, *head) { + int r; + + if (k >= 0 && + major(root_st.st_dev) != 0 && + root_st.st_dev == m->devnum) { + n_failed ++; + continue; + } + + log_info("Detaching DM %u:%u.", major(m->devnum), minor(m->devnum)); + r = delete_dm(m->devnum); + if (r >= 0) { + if (changed) + *changed = true; + + mount_point_free(head, m); + } else { + log_warning("Could not detach DM %s: %m", m->path); + n_failed++; + } + } + + return n_failed; +} + +int umount_all(bool *changed) { + int r; + bool umount_changed; + LIST_HEAD(MountPoint, mp_list_head); + + LIST_HEAD_INIT(MountPoint, mp_list_head); + r = mount_points_list_get(&mp_list_head); + if (r < 0) + goto end; + + /* retry umount, until nothing can be umounted anymore */ + do { + umount_changed = false; + + mount_points_list_umount(&mp_list_head, &umount_changed, false); + if (umount_changed) + *changed = true; + + } while (umount_changed); + + /* umount one more time with logging enabled */ + r = mount_points_list_umount(&mp_list_head, &umount_changed, true); + if (r <= 0) + goto end; + + end: + mount_points_list_free(&mp_list_head); + + return r; +} + +int swapoff_all(bool *changed) { + int r; + LIST_HEAD(MountPoint, swap_list_head); + + LIST_HEAD_INIT(MountPoint, swap_list_head); + + r = swap_list_get(&swap_list_head); + if (r < 0) + goto end; + + r = swap_points_list_off(&swap_list_head, changed); + + end: + mount_points_list_free(&swap_list_head); + + return r; +} + +int loopback_detach_all(bool *changed) { + int r; + LIST_HEAD(MountPoint, loopback_list_head); + + LIST_HEAD_INIT(MountPoint, loopback_list_head); + + r = loopback_list_get(&loopback_list_head); + if (r < 0) + goto end; + + r = loopback_points_list_detach(&loopback_list_head, changed); + + end: + mount_points_list_free(&loopback_list_head); + + return r; +} + +int dm_detach_all(bool *changed) { + int r; + LIST_HEAD(MountPoint, dm_list_head); + + LIST_HEAD_INIT(MountPoint, dm_list_head); + + r = dm_list_get(&dm_list_head); + if (r < 0) + goto end; + + r = dm_points_list_detach(&dm_list_head, changed); + + end: + mount_points_list_free(&dm_list_head); + + return r; +} diff --git a/src/core/umount.h b/src/core/umount.h new file mode 100644 index 000000000..8439ffe58 --- /dev/null +++ b/src/core/umount.h @@ -0,0 +1,30 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2010 ProFUSION embedded systems + + 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 . +***/ + +int umount_all(bool *changed); + +int swapoff_all(bool *changed); + +int loopback_detach_all(bool *changed); + +int dm_detach_all(bool *changed); diff --git a/src/core/unit-printf.c b/src/core/unit-printf.c new file mode 100644 index 000000000..a58c96c23 --- /dev/null +++ b/src/core/unit-printf.c @@ -0,0 +1,353 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include "systemd/sd-id128.h" +#include "unit.h" +#include "specifier.h" +#include "path-util.h" +#include "strv.h" +#include "unit-name.h" +#include "unit-printf.h" + +static char *specifier_prefix_and_instance(char specifier, void *data, void *userdata) { + Unit *u = userdata; + assert(u); + + return unit_name_to_prefix_and_instance(u->id); +} + +static char *specifier_prefix(char specifier, void *data, void *userdata) { + Unit *u = userdata; + assert(u); + + return unit_name_to_prefix(u->id); +} + +static char *specifier_prefix_unescaped(char specifier, void *data, void *userdata) { + Unit *u = userdata; + char *p, *r; + + assert(u); + + p = unit_name_to_prefix(u->id); + if (!p) + return NULL; + + r = unit_name_unescape(p); + free(p); + + return r; +} + +static char *specifier_instance_unescaped(char specifier, void *data, void *userdata) { + Unit *u = userdata; + assert(u); + + if (u->instance) + return unit_name_unescape(u->instance); + + return strdup(""); +} + +static char *specifier_filename(char specifier, void *data, void *userdata) { + Unit *u = userdata; + assert(u); + + if (u->instance) + return unit_name_path_unescape(u->instance); + + return unit_name_to_path(u->id); +} + +static char *specifier_cgroup(char specifier, void *data, void *userdata) { + Unit *u = userdata; + assert(u); + + return unit_default_cgroup_path(u); +} + +static char *specifier_cgroup_root(char specifier, void *data, void *userdata) { + Unit *u = userdata; + char *p; + assert(u); + + if (specifier == 'r') + return strdup(u->manager->cgroup_hierarchy); + + if (path_get_parent(u->manager->cgroup_hierarchy, &p) < 0) + return strdup(""); + + if (streq(p, "/")) { + free(p); + return strdup(""); + } + + return p; +} + +static char *specifier_runtime(char specifier, void *data, void *userdata) { + Unit *u = userdata; + assert(u); + + if (u->manager->running_as == SYSTEMD_USER) { + const char *e; + + e = getenv("XDG_RUNTIME_DIR"); + if (e) + return strdup(e); + } + + return strdup("/run"); +} + +static char *specifier_user_name(char specifier, void *data, void *userdata) { + Unit *u = userdata; + ExecContext *c; + int r; + const char *username; + uid_t uid; + char *printed = NULL; + + assert(u); + + c = unit_get_exec_context(u); + + /* get USER env from our own env if set */ + if (!c || !c->user) + return getusername_malloc(); + + /* fish username from passwd */ + username = c->user; + r = get_user_creds(&username, &uid, NULL, NULL, NULL); + if (r < 0) + return NULL; + + switch (specifier) { + case 'U': + if (asprintf(&printed, "%d", uid) < 0) + return NULL; + break; + case 'u': + printed = strdup(username); + break; + } + + return printed; +} + +static char *specifier_user_home(char specifier, void *data, void *userdata) { + Unit *u = userdata; + ExecContext *c; + int r; + const char *username, *home; + + assert(u); + + c = unit_get_exec_context(u); + + /* return HOME if set, otherwise from passwd */ + if (!c || !c->user) { + char *h; + + r = get_home_dir(&h); + if (r < 0) + return NULL; + + return h; + } + + username = c->user; + r = get_user_creds(&username, NULL, NULL, &home, NULL); + if (r < 0) + return NULL; + + return strdup(home); +} + +static char *specifier_user_shell(char specifier, void *data, void *userdata) { + Unit *u = userdata; + ExecContext *c; + int r; + const char *username, *shell; + + assert(u); + + c = unit_get_exec_context(u); + + /* return HOME if set, otherwise from passwd */ + if (!c || !c->user) { + char *sh; + + r = get_shell(&sh); + if (r < 0) + return strdup("/bin/sh"); + + return sh; + } + + username = c->user; + r = get_user_creds(&username, NULL, NULL, NULL, &shell); + if (r < 0) + return strdup("/bin/sh"); + + return strdup(shell); +} + +static char *specifier_machine_id(char specifier, void *data, void *userdata) { + sd_id128_t id; + char *buf; + int r; + + r = sd_id128_get_machine(&id); + if (r < 0) + return NULL; + + buf = new(char, 33); + if (!buf) + return NULL; + + return sd_id128_to_string(id, buf); +} + +static char *specifier_boot_id(char specifier, void *data, void *userdata) { + sd_id128_t id; + char *buf; + int r; + + r = sd_id128_get_boot(&id); + if (r < 0) + return NULL; + + buf = new(char, 33); + if (!buf) + return NULL; + + return sd_id128_to_string(id, buf); +} + +static char *specifier_host_name(char specifier, void *data, void *userdata) { + return gethostname_malloc(); +} + +char *unit_name_printf(Unit *u, const char* format) { + + /* + * This will use the passed string as format string and + * replace the following specifiers: + * + * %n: the full id of the unit (foo@bar.waldo) + * %N: the id of the unit without the suffix (foo@bar) + * %p: the prefix (foo) + * %i: the instance (bar) + */ + + const Specifier table[] = { + { 'n', specifier_string, u->id }, + { 'N', specifier_prefix_and_instance, NULL }, + { 'p', specifier_prefix, NULL }, + { 'i', specifier_string, u->instance }, + { 0, NULL, NULL } + }; + + assert(u); + assert(format); + + return specifier_printf(format, table, u); +} + +char *unit_full_printf(Unit *u, const char *format) { + + /* This is similar to unit_name_printf() but also supports + * unescaping. Also, adds a couple of additional codes: + * + * %f the the instance if set, otherwise the id + * %c cgroup path of unit + * %r root cgroup path of this systemd instance (e.g. "/user/lennart/shared/systemd-4711") + * %R parent of root cgroup path (e.g. "/usr/lennart/shared") + * %t the runtime directory to place sockets in (e.g. "/run" or $XDG_RUNTIME_DIR) + * %u the username of the configured user or running user + * %h the homedir of the configured user or running user + * %s the shell of the configured user or running user + * %m the machine ID of the running system + * %b the boot ID of the running system + * %H the host name of the running system + */ + + const Specifier table[] = { + { 'n', specifier_string, u->id }, + { 'N', specifier_prefix_and_instance, NULL }, + { 'p', specifier_prefix, NULL }, + { 'P', specifier_prefix_unescaped, NULL }, + { 'i', specifier_string, u->instance }, + { 'I', specifier_instance_unescaped, NULL }, + + { 'f', specifier_filename, NULL }, + { 'c', specifier_cgroup, NULL }, + { 'r', specifier_cgroup_root, NULL }, + { 'R', specifier_cgroup_root, NULL }, + { 't', specifier_runtime, NULL }, + { 'U', specifier_user_name, NULL }, + { 'u', specifier_user_name, NULL }, + { 'h', specifier_user_home, NULL }, + { 's', specifier_user_shell, NULL }, + + { 'm', specifier_machine_id, NULL }, + { 'H', specifier_host_name, NULL }, + { 'b', specifier_boot_id, NULL }, + { 0, NULL, NULL } + }; + + assert(u); + assert(format); + + return specifier_printf(format, table, u); +} + +char **unit_full_printf_strv(Unit *u, char **l) { + size_t n; + char **r, **i, **j; + + /* Applies unit_full_printf to every entry in l */ + + assert(u); + + n = strv_length(l); + r = new(char*, n+1); + if (!r) + return NULL; + + for (i = l, j = r; *i; i++, j++) { + *j = unit_full_printf(u, *i); + if (!*j) + goto fail; + } + + *j = NULL; + return r; + +fail: + for (j--; j >= r; j--) + free(*j); + + free(r); + + return NULL; +} diff --git a/src/core/unit-printf.h b/src/core/unit-printf.h new file mode 100644 index 000000000..d2f4ccd17 --- /dev/null +++ b/src/core/unit-printf.h @@ -0,0 +1,28 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +#include "unit.h" + +char *unit_name_printf(Unit *u, const char* text); +char *unit_full_printf(Unit *u, const char *text); +char **unit_full_printf_strv(Unit *u, char **l); diff --git a/src/core/unit.c b/src/core/unit.c new file mode 100644 index 000000000..45453dce6 --- /dev/null +++ b/src/core/unit.c @@ -0,0 +1,2739 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "systemd/sd-id128.h" +#include "systemd/sd-messages.h" +#include "set.h" +#include "unit.h" +#include "macro.h" +#include "strv.h" +#include "path-util.h" +#include "load-fragment.h" +#include "load-dropin.h" +#include "log.h" +#include "unit-name.h" +#include "dbus-unit.h" +#include "special.h" +#include "cgroup-util.h" +#include "missing.h" +#include "cgroup-attr.h" + +const UnitVTable * const unit_vtable[_UNIT_TYPE_MAX] = { + [UNIT_SERVICE] = &service_vtable, + [UNIT_TIMER] = &timer_vtable, + [UNIT_SOCKET] = &socket_vtable, + [UNIT_TARGET] = &target_vtable, + [UNIT_DEVICE] = &device_vtable, + [UNIT_MOUNT] = &mount_vtable, + [UNIT_AUTOMOUNT] = &automount_vtable, + [UNIT_SNAPSHOT] = &snapshot_vtable, + [UNIT_SWAP] = &swap_vtable, + [UNIT_PATH] = &path_vtable +}; + +Unit *unit_new(Manager *m, size_t size) { + Unit *u; + + assert(m); + assert(size >= sizeof(Unit)); + + u = malloc0(size); + if (!u) + return NULL; + + u->names = set_new(string_hash_func, string_compare_func); + if (!u->names) { + free(u); + return NULL; + } + + u->manager = m; + u->type = _UNIT_TYPE_INVALID; + u->deserialized_job = _JOB_TYPE_INVALID; + u->default_dependencies = true; + u->unit_file_state = _UNIT_FILE_STATE_INVALID; + + return u; +} + +bool unit_has_name(Unit *u, const char *name) { + assert(u); + assert(name); + + return !!set_get(u->names, (char*) name); +} + +int unit_add_name(Unit *u, const char *text) { + UnitType t; + char *s, *i = NULL; + int r; + + assert(u); + assert(text); + + if (unit_name_is_template(text)) { + if (!u->instance) + return -EINVAL; + + s = unit_name_replace_instance(text, u->instance); + } else + s = strdup(text); + + if (!s) + return -ENOMEM; + + if (!unit_name_is_valid(s, false)) { + r = -EINVAL; + goto fail; + } + + assert_se((t = unit_name_to_type(s)) >= 0); + + if (u->type != _UNIT_TYPE_INVALID && t != u->type) { + r = -EINVAL; + goto fail; + } + + if ((r = unit_name_to_instance(s, &i)) < 0) + goto fail; + + if (i && unit_vtable[t]->no_instances) { + r = -EINVAL; + goto fail; + } + + /* Ensure that this unit is either instanced or not instanced, + * but not both. */ + if (u->type != _UNIT_TYPE_INVALID && !u->instance != !i) { + r = -EINVAL; + goto fail; + } + + if (unit_vtable[t]->no_alias && + !set_isempty(u->names) && + !set_get(u->names, s)) { + r = -EEXIST; + goto fail; + } + + if (hashmap_size(u->manager->units) >= MANAGER_MAX_NAMES) { + r = -E2BIG; + goto fail; + } + + if ((r = set_put(u->names, s)) < 0) { + if (r == -EEXIST) + r = 0; + goto fail; + } + + if ((r = hashmap_put(u->manager->units, s, u)) < 0) { + set_remove(u->names, s); + goto fail; + } + + if (u->type == _UNIT_TYPE_INVALID) { + + u->type = t; + u->id = s; + u->instance = i; + + LIST_PREPEND(Unit, units_by_type, u->manager->units_by_type[t], u); + + if (UNIT_VTABLE(u)->init) + UNIT_VTABLE(u)->init(u); + } else + free(i); + + unit_add_to_dbus_queue(u); + return 0; + +fail: + free(s); + free(i); + + return r; +} + +int unit_choose_id(Unit *u, const char *name) { + char *s, *t = NULL, *i; + int r; + + assert(u); + assert(name); + + if (unit_name_is_template(name)) { + + if (!u->instance) + return -EINVAL; + + if (!(t = unit_name_replace_instance(name, u->instance))) + return -ENOMEM; + + name = t; + } + + /* Selects one of the names of this unit as the id */ + s = set_get(u->names, (char*) name); + free(t); + + if (!s) + return -ENOENT; + + if ((r = unit_name_to_instance(s, &i)) < 0) + return r; + + u->id = s; + + free(u->instance); + u->instance = i; + + unit_add_to_dbus_queue(u); + + return 0; +} + +int unit_set_description(Unit *u, const char *description) { + char *s; + + assert(u); + + if (!(s = strdup(description))) + return -ENOMEM; + + free(u->description); + u->description = s; + + unit_add_to_dbus_queue(u); + return 0; +} + +bool unit_check_gc(Unit *u) { + assert(u); + + if (u->load_state == UNIT_STUB) + return true; + + if (UNIT_VTABLE(u)->no_gc) + return true; + + if (u->no_gc) + return true; + + if (u->job) + return true; + + if (u->nop_job) + return true; + + if (unit_active_state(u) != UNIT_INACTIVE) + return true; + + if (u->refs) + return true; + + if (UNIT_VTABLE(u)->check_gc) + if (UNIT_VTABLE(u)->check_gc(u)) + return true; + + return false; +} + +void unit_add_to_load_queue(Unit *u) { + assert(u); + assert(u->type != _UNIT_TYPE_INVALID); + + if (u->load_state != UNIT_STUB || u->in_load_queue) + return; + + LIST_PREPEND(Unit, load_queue, u->manager->load_queue, u); + u->in_load_queue = true; +} + +void unit_add_to_cleanup_queue(Unit *u) { + assert(u); + + if (u->in_cleanup_queue) + return; + + LIST_PREPEND(Unit, cleanup_queue, u->manager->cleanup_queue, u); + u->in_cleanup_queue = true; +} + +void unit_add_to_gc_queue(Unit *u) { + assert(u); + + if (u->in_gc_queue || u->in_cleanup_queue) + return; + + if (unit_check_gc(u)) + return; + + LIST_PREPEND(Unit, gc_queue, u->manager->gc_queue, u); + u->in_gc_queue = true; + + u->manager->n_in_gc_queue ++; + + if (u->manager->gc_queue_timestamp <= 0) + u->manager->gc_queue_timestamp = now(CLOCK_MONOTONIC); +} + +void unit_add_to_dbus_queue(Unit *u) { + assert(u); + assert(u->type != _UNIT_TYPE_INVALID); + + if (u->load_state == UNIT_STUB || u->in_dbus_queue) + return; + + /* Shortcut things if nobody cares */ + if (!bus_has_subscriber(u->manager)) { + u->sent_dbus_new_signal = true; + return; + } + + LIST_PREPEND(Unit, dbus_queue, u->manager->dbus_unit_queue, u); + u->in_dbus_queue = true; +} + +static void bidi_set_free(Unit *u, Set *s) { + Iterator i; + Unit *other; + + assert(u); + + /* Frees the set and makes sure we are dropped from the + * inverse pointers */ + + SET_FOREACH(other, s, i) { + UnitDependency d; + + for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++) + set_remove(other->dependencies[d], u); + + unit_add_to_gc_queue(other); + } + + set_free(s); +} + +void unit_free(Unit *u) { + UnitDependency d; + Iterator i; + char *t; + + assert(u); + + bus_unit_send_removed_signal(u); + + if (u->load_state != UNIT_STUB) + if (UNIT_VTABLE(u)->done) + UNIT_VTABLE(u)->done(u); + + SET_FOREACH(t, u->names, i) + hashmap_remove_value(u->manager->units, t, u); + + if (u->job) { + Job *j = u->job; + job_uninstall(j); + job_free(j); + } + + if (u->nop_job) { + Job *j = u->nop_job; + job_uninstall(j); + job_free(j); + } + + for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++) + bidi_set_free(u, u->dependencies[d]); + + if (u->requires_mounts_for) { + LIST_REMOVE(Unit, has_requires_mounts_for, u->manager->has_requires_mounts_for, u); + strv_free(u->requires_mounts_for); + } + + if (u->type != _UNIT_TYPE_INVALID) + LIST_REMOVE(Unit, units_by_type, u->manager->units_by_type[u->type], u); + + if (u->in_load_queue) + LIST_REMOVE(Unit, load_queue, u->manager->load_queue, u); + + if (u->in_dbus_queue) + LIST_REMOVE(Unit, dbus_queue, u->manager->dbus_unit_queue, u); + + if (u->in_cleanup_queue) + LIST_REMOVE(Unit, cleanup_queue, u->manager->cleanup_queue, u); + + if (u->in_gc_queue) { + LIST_REMOVE(Unit, gc_queue, u->manager->gc_queue, u); + u->manager->n_in_gc_queue--; + } + + cgroup_bonding_free_list(u->cgroup_bondings, u->manager->n_reloading <= 0); + cgroup_attribute_free_list(u->cgroup_attributes); + + free(u->description); + strv_free(u->documentation); + free(u->fragment_path); + free(u->source_path); + free(u->instance); + + set_free_free(u->names); + + condition_free_list(u->conditions); + + while (u->refs) + unit_ref_unset(u->refs); + + free(u); +} + +UnitActiveState unit_active_state(Unit *u) { + assert(u); + + if (u->load_state == UNIT_MERGED) + return unit_active_state(unit_follow_merge(u)); + + /* After a reload it might happen that a unit is not correctly + * loaded but still has a process around. That's why we won't + * shortcut failed loading to UNIT_INACTIVE_FAILED. */ + + return UNIT_VTABLE(u)->active_state(u); +} + +const char* unit_sub_state_to_string(Unit *u) { + assert(u); + + return UNIT_VTABLE(u)->sub_state_to_string(u); +} + +static void complete_move(Set **s, Set **other) { + assert(s); + assert(other); + + if (!*other) + return; + + if (*s) + set_move(*s, *other); + else { + *s = *other; + *other = NULL; + } +} + +static void merge_names(Unit *u, Unit *other) { + char *t; + Iterator i; + + assert(u); + assert(other); + + complete_move(&u->names, &other->names); + + set_free_free(other->names); + other->names = NULL; + other->id = NULL; + + SET_FOREACH(t, u->names, i) + assert_se(hashmap_replace(u->manager->units, t, u) == 0); +} + +static void merge_dependencies(Unit *u, Unit *other, UnitDependency d) { + Iterator i; + Unit *back; + int r; + + assert(u); + assert(other); + assert(d < _UNIT_DEPENDENCY_MAX); + + /* Fix backwards pointers */ + SET_FOREACH(back, other->dependencies[d], i) { + UnitDependency k; + + for (k = 0; k < _UNIT_DEPENDENCY_MAX; k++) + if ((r = set_remove_and_put(back->dependencies[k], other, u)) < 0) { + + if (r == -EEXIST) + set_remove(back->dependencies[k], other); + else + assert(r == -ENOENT); + } + } + + complete_move(&u->dependencies[d], &other->dependencies[d]); + + set_free(other->dependencies[d]); + other->dependencies[d] = NULL; +} + +int unit_merge(Unit *u, Unit *other) { + UnitDependency d; + + assert(u); + assert(other); + assert(u->manager == other->manager); + assert(u->type != _UNIT_TYPE_INVALID); + + other = unit_follow_merge(other); + + if (other == u) + return 0; + + if (u->type != other->type) + return -EINVAL; + + if (!u->instance != !other->instance) + return -EINVAL; + + if (other->load_state != UNIT_STUB && + other->load_state != UNIT_ERROR) + return -EEXIST; + + if (other->job) + return -EEXIST; + + if (other->nop_job) + return -EEXIST; + + if (!UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(other))) + return -EEXIST; + + /* Merge names */ + merge_names(u, other); + + /* Redirect all references */ + while (other->refs) + unit_ref_set(other->refs, u); + + /* Merge dependencies */ + for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++) + merge_dependencies(u, other, d); + + other->load_state = UNIT_MERGED; + other->merged_into = u; + + /* If there is still some data attached to the other node, we + * don't need it anymore, and can free it. */ + if (other->load_state != UNIT_STUB) + if (UNIT_VTABLE(other)->done) + UNIT_VTABLE(other)->done(other); + + unit_add_to_dbus_queue(u); + unit_add_to_cleanup_queue(other); + + return 0; +} + +int unit_merge_by_name(Unit *u, const char *name) { + Unit *other; + int r; + char *s = NULL; + + assert(u); + assert(name); + + if (unit_name_is_template(name)) { + if (!u->instance) + return -EINVAL; + + if (!(s = unit_name_replace_instance(name, u->instance))) + return -ENOMEM; + + name = s; + } + + if (!(other = manager_get_unit(u->manager, name))) + r = unit_add_name(u, name); + else + r = unit_merge(u, other); + + free(s); + return r; +} + +Unit* unit_follow_merge(Unit *u) { + assert(u); + + while (u->load_state == UNIT_MERGED) + assert_se(u = u->merged_into); + + return u; +} + +int unit_add_exec_dependencies(Unit *u, ExecContext *c) { + int r; + + assert(u); + assert(c); + + if (c->std_output != EXEC_OUTPUT_KMSG && + c->std_output != EXEC_OUTPUT_SYSLOG && + c->std_output != EXEC_OUTPUT_JOURNAL && + c->std_output != EXEC_OUTPUT_KMSG_AND_CONSOLE && + c->std_output != EXEC_OUTPUT_SYSLOG_AND_CONSOLE && + c->std_output != EXEC_OUTPUT_JOURNAL_AND_CONSOLE && + c->std_error != EXEC_OUTPUT_KMSG && + c->std_error != EXEC_OUTPUT_SYSLOG && + c->std_error != EXEC_OUTPUT_JOURNAL && + c->std_error != EXEC_OUTPUT_KMSG_AND_CONSOLE && + c->std_error != EXEC_OUTPUT_JOURNAL_AND_CONSOLE && + c->std_error != EXEC_OUTPUT_SYSLOG_AND_CONSOLE) + return 0; + + /* If syslog or kernel logging is requested, make sure our own + * logging daemon is run first. */ + + if (u->manager->running_as == SYSTEMD_SYSTEM) + if ((r = unit_add_two_dependencies_by_name(u, UNIT_REQUIRES, UNIT_AFTER, SPECIAL_JOURNALD_SOCKET, NULL, true)) < 0) + return r; + + return 0; +} + +const char *unit_description(Unit *u) { + assert(u); + + if (u->description) + return u->description; + + return strna(u->id); +} + +void unit_dump(Unit *u, FILE *f, const char *prefix) { + char *t, **j; + UnitDependency d; + Iterator i; + char *p2; + const char *prefix2; + char + timestamp1[FORMAT_TIMESTAMP_MAX], + timestamp2[FORMAT_TIMESTAMP_MAX], + timestamp3[FORMAT_TIMESTAMP_MAX], + timestamp4[FORMAT_TIMESTAMP_MAX], + timespan[FORMAT_TIMESPAN_MAX]; + Unit *following; + + assert(u); + assert(u->type >= 0); + + if (!prefix) + prefix = ""; + p2 = strappend(prefix, "\t"); + prefix2 = p2 ? p2 : prefix; + + fprintf(f, + "%s-> Unit %s:\n" + "%s\tDescription: %s\n" + "%s\tInstance: %s\n" + "%s\tUnit Load State: %s\n" + "%s\tUnit Active State: %s\n" + "%s\tInactive Exit Timestamp: %s\n" + "%s\tActive Enter Timestamp: %s\n" + "%s\tActive Exit Timestamp: %s\n" + "%s\tInactive Enter Timestamp: %s\n" + "%s\tGC Check Good: %s\n" + "%s\tNeed Daemon Reload: %s\n", + prefix, u->id, + prefix, unit_description(u), + prefix, strna(u->instance), + prefix, unit_load_state_to_string(u->load_state), + prefix, unit_active_state_to_string(unit_active_state(u)), + prefix, strna(format_timestamp(timestamp1, sizeof(timestamp1), u->inactive_exit_timestamp.realtime)), + prefix, strna(format_timestamp(timestamp2, sizeof(timestamp2), u->active_enter_timestamp.realtime)), + prefix, strna(format_timestamp(timestamp3, sizeof(timestamp3), u->active_exit_timestamp.realtime)), + prefix, strna(format_timestamp(timestamp4, sizeof(timestamp4), u->inactive_enter_timestamp.realtime)), + prefix, yes_no(unit_check_gc(u)), + prefix, yes_no(unit_need_daemon_reload(u))); + + SET_FOREACH(t, u->names, i) + fprintf(f, "%s\tName: %s\n", prefix, t); + + STRV_FOREACH(j, u->documentation) + fprintf(f, "%s\tDocumentation: %s\n", prefix, *j); + + if ((following = unit_following(u))) + fprintf(f, "%s\tFollowing: %s\n", prefix, following->id); + + if (u->fragment_path) + fprintf(f, "%s\tFragment Path: %s\n", prefix, u->fragment_path); + + if (u->source_path) + fprintf(f, "%s\tSource Path: %s\n", prefix, u->source_path); + + if (u->job_timeout > 0) + fprintf(f, "%s\tJob Timeout: %s\n", prefix, format_timespan(timespan, sizeof(timespan), u->job_timeout)); + + condition_dump_list(u->conditions, f, prefix); + + if (dual_timestamp_is_set(&u->condition_timestamp)) + fprintf(f, + "%s\tCondition Timestamp: %s\n" + "%s\tCondition Result: %s\n", + prefix, strna(format_timestamp(timestamp1, sizeof(timestamp1), u->condition_timestamp.realtime)), + prefix, yes_no(u->condition_result)); + + for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++) { + Unit *other; + + SET_FOREACH(other, u->dependencies[d], i) + fprintf(f, "%s\t%s: %s\n", prefix, unit_dependency_to_string(d), other->id); + } + + if (!strv_isempty(u->requires_mounts_for)) { + fprintf(f, + "%s\tRequiresMountsFor:", prefix); + + STRV_FOREACH(j, u->requires_mounts_for) + fprintf(f, " %s", *j); + + fputs("\n", f); + } + + if (u->load_state == UNIT_LOADED) { + CGroupBonding *b; + CGroupAttribute *a; + + fprintf(f, + "%s\tStopWhenUnneeded: %s\n" + "%s\tRefuseManualStart: %s\n" + "%s\tRefuseManualStop: %s\n" + "%s\tDefaultDependencies: %s\n" + "%s\tOnFailureIsolate: %s\n" + "%s\tIgnoreOnIsolate: %s\n" + "%s\tIgnoreOnSnapshot: %s\n", + prefix, yes_no(u->stop_when_unneeded), + prefix, yes_no(u->refuse_manual_start), + prefix, yes_no(u->refuse_manual_stop), + prefix, yes_no(u->default_dependencies), + prefix, yes_no(u->on_failure_isolate), + prefix, yes_no(u->ignore_on_isolate), + prefix, yes_no(u->ignore_on_snapshot)); + + LIST_FOREACH(by_unit, b, u->cgroup_bondings) + fprintf(f, "%s\tControlGroup: %s:%s\n", + prefix, b->controller, b->path); + + LIST_FOREACH(by_unit, a, u->cgroup_attributes) { + char *v = NULL; + + if (a->map_callback) + a->map_callback(a->controller, a->name, a->value, &v); + + fprintf(f, "%s\tControlGroupAttribute: %s %s \"%s\"\n", + prefix, a->controller, a->name, v ? v : a->value); + + free(v); + } + + if (UNIT_VTABLE(u)->dump) + UNIT_VTABLE(u)->dump(u, f, prefix2); + + } else if (u->load_state == UNIT_MERGED) + fprintf(f, + "%s\tMerged into: %s\n", + prefix, u->merged_into->id); + else if (u->load_state == UNIT_ERROR) + fprintf(f, "%s\tLoad Error Code: %s\n", prefix, strerror(-u->load_error)); + + + if (u->job) + job_dump(u->job, f, prefix2); + + if (u->nop_job) + job_dump(u->nop_job, f, prefix2); + + free(p2); +} + +/* Common implementation for multiple backends */ +int unit_load_fragment_and_dropin(Unit *u) { + int r; + + assert(u); + + /* Load a .service file */ + if ((r = unit_load_fragment(u)) < 0) + return r; + + if (u->load_state == UNIT_STUB) + return -ENOENT; + + /* Load drop-in directory data */ + if ((r = unit_load_dropin(unit_follow_merge(u))) < 0) + return r; + + return 0; +} + +/* Common implementation for multiple backends */ +int unit_load_fragment_and_dropin_optional(Unit *u) { + int r; + + assert(u); + + /* Same as unit_load_fragment_and_dropin(), but whether + * something can be loaded or not doesn't matter. */ + + /* Load a .service file */ + if ((r = unit_load_fragment(u)) < 0) + return r; + + if (u->load_state == UNIT_STUB) + u->load_state = UNIT_LOADED; + + /* Load drop-in directory data */ + if ((r = unit_load_dropin(unit_follow_merge(u))) < 0) + return r; + + return 0; +} + +int unit_add_default_target_dependency(Unit *u, Unit *target) { + assert(u); + assert(target); + + if (target->type != UNIT_TARGET) + return 0; + + /* Only add the dependency if both units are loaded, so that + * that loop check below is reliable */ + if (u->load_state != UNIT_LOADED || + target->load_state != UNIT_LOADED) + return 0; + + /* If either side wants no automatic dependencies, then let's + * skip this */ + if (!u->default_dependencies || + !target->default_dependencies) + return 0; + + /* Don't create loops */ + if (set_get(target->dependencies[UNIT_BEFORE], u)) + return 0; + + return unit_add_dependency(target, UNIT_AFTER, u, true); +} + +static int unit_add_default_dependencies(Unit *u) { + static const UnitDependency deps[] = { + UNIT_REQUIRED_BY, + UNIT_REQUIRED_BY_OVERRIDABLE, + UNIT_WANTED_BY, + UNIT_BOUND_BY + }; + + Unit *target; + Iterator i; + int r; + unsigned k; + + assert(u); + + for (k = 0; k < ELEMENTSOF(deps); k++) + SET_FOREACH(target, u->dependencies[deps[k]], i) + if ((r = unit_add_default_target_dependency(u, target)) < 0) + return r; + + return 0; +} + +int unit_load(Unit *u) { + int r; + + assert(u); + + if (u->in_load_queue) { + LIST_REMOVE(Unit, load_queue, u->manager->load_queue, u); + u->in_load_queue = false; + } + + if (u->type == _UNIT_TYPE_INVALID) + return -EINVAL; + + if (u->load_state != UNIT_STUB) + return 0; + + if (UNIT_VTABLE(u)->load) + if ((r = UNIT_VTABLE(u)->load(u)) < 0) + goto fail; + + if (u->load_state == UNIT_STUB) { + r = -ENOENT; + goto fail; + } + + if (u->load_state == UNIT_LOADED && + u->default_dependencies) + if ((r = unit_add_default_dependencies(u)) < 0) + goto fail; + + if (u->load_state == UNIT_LOADED) { + r = unit_add_mount_links(u); + if (r < 0) + return r; + } + + if (u->on_failure_isolate && + set_size(u->dependencies[UNIT_ON_FAILURE]) > 1) { + + log_error("More than one OnFailure= dependencies specified for %s but OnFailureIsolate= enabled. Refusing.", + u->id); + + r = -EINVAL; + goto fail; + } + + assert((u->load_state != UNIT_MERGED) == !u->merged_into); + + unit_add_to_dbus_queue(unit_follow_merge(u)); + unit_add_to_gc_queue(u); + + return 0; + +fail: + u->load_state = UNIT_ERROR; + u->load_error = r; + unit_add_to_dbus_queue(u); + unit_add_to_gc_queue(u); + + log_debug("Failed to load configuration for %s: %s", u->id, strerror(-r)); + + return r; +} + +bool unit_condition_test(Unit *u) { + assert(u); + + dual_timestamp_get(&u->condition_timestamp); + u->condition_result = condition_test_list(u->conditions); + + return u->condition_result; +} + +static const char* unit_get_status_message_format(Unit *u, JobType t) { + const UnitStatusMessageFormats *format_table; + + assert(u); + assert(t >= 0); + assert(t < _JOB_TYPE_MAX); + + if (t != JOB_START && t != JOB_STOP) + return NULL; + + format_table = &UNIT_VTABLE(u)->status_message_formats; + if (!format_table) + return NULL; + + return format_table->starting_stopping[t == JOB_STOP]; +} + +static const char *unit_get_status_message_format_try_harder(Unit *u, JobType t) { + const char *format; + + assert(u); + assert(t >= 0); + assert(t < _JOB_TYPE_MAX); + + format = unit_get_status_message_format(u, t); + if (format) + return format; + + /* Return generic strings */ + if (t == JOB_START) + return "Starting %s."; + else if (t == JOB_STOP) + return "Stopping %s."; + else if (t == JOB_RELOAD) + return "Reloading %s."; + + return NULL; +} + +static void unit_status_print_starting_stopping(Unit *u, JobType t) { + const char *format; + + assert(u); + + /* We only print status messages for selected units on + * selected operations. */ + + format = unit_get_status_message_format(u, t); + if (!format) + return; + + unit_status_printf(u, "", format, unit_description(u)); +} + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wformat-nonliteral" +static void unit_status_log_starting_stopping_reloading(Unit *u, JobType t) { + const char *format; + char buf[LINE_MAX]; + sd_id128_t mid; + + assert(u); + + if (t != JOB_START && t != JOB_STOP && t != JOB_RELOAD) + return; + + if (log_on_console()) + return; + + /* We log status messages for all units and all operations. */ + + format = unit_get_status_message_format_try_harder(u, t); + if (!format) + return; + + snprintf(buf, sizeof(buf), format, unit_description(u)); + char_array_0(buf); + + mid = t == JOB_START ? SD_MESSAGE_UNIT_STARTING : + t == JOB_STOP ? SD_MESSAGE_UNIT_STOPPING : + SD_MESSAGE_UNIT_RELOADING; + + log_struct(LOG_INFO, + MESSAGE_ID(mid), + "UNIT=%s", u->id, + "MESSAGE=%s", buf, + NULL); +} +#pragma GCC diagnostic pop + +/* Errors: + * -EBADR: This unit type does not support starting. + * -EALREADY: Unit is already started. + * -EAGAIN: An operation is already in progress. Retry later. + * -ECANCELED: Too many requests for now. + */ +int unit_start(Unit *u) { + UnitActiveState state; + Unit *following; + + assert(u); + + if (u->load_state != UNIT_LOADED) + return -EINVAL; + + /* If this is already started, then this will succeed. Note + * that this will even succeed if this unit is not startable + * by the user. This is relied on to detect when we need to + * wait for units and when waiting is finished. */ + state = unit_active_state(u); + if (UNIT_IS_ACTIVE_OR_RELOADING(state)) + return -EALREADY; + + /* If the conditions failed, don't do anything at all. If we + * already are activating this call might still be useful to + * speed up activation in case there is some hold-off time, + * but we don't want to recheck the condition in that case. */ + if (state != UNIT_ACTIVATING && + !unit_condition_test(u)) { + log_debug("Starting of %s requested but condition failed. Ignoring.", u->id); + return -EALREADY; + } + + /* Forward to the main object, if we aren't it. */ + if ((following = unit_following(u))) { + log_debug("Redirecting start request from %s to %s.", u->id, following->id); + return unit_start(following); + } + + unit_status_log_starting_stopping_reloading(u, JOB_START); + unit_status_print_starting_stopping(u, JOB_START); + + /* If it is stopped, but we cannot start it, then fail */ + if (!UNIT_VTABLE(u)->start) + return -EBADR; + + /* We don't suppress calls to ->start() here when we are + * already starting, to allow this request to be used as a + * "hurry up" call, for example when the unit is in some "auto + * restart" state where it waits for a holdoff timer to elapse + * before it will start again. */ + + unit_add_to_dbus_queue(u); + + return UNIT_VTABLE(u)->start(u); +} + +bool unit_can_start(Unit *u) { + assert(u); + + return !!UNIT_VTABLE(u)->start; +} + +bool unit_can_isolate(Unit *u) { + assert(u); + + return unit_can_start(u) && + u->allow_isolate; +} + +/* Errors: + * -EBADR: This unit type does not support stopping. + * -EALREADY: Unit is already stopped. + * -EAGAIN: An operation is already in progress. Retry later. + */ +int unit_stop(Unit *u) { + UnitActiveState state; + Unit *following; + + assert(u); + + state = unit_active_state(u); + if (UNIT_IS_INACTIVE_OR_FAILED(state)) + return -EALREADY; + + if ((following = unit_following(u))) { + log_debug("Redirecting stop request from %s to %s.", u->id, following->id); + return unit_stop(following); + } + + unit_status_log_starting_stopping_reloading(u, JOB_STOP); + unit_status_print_starting_stopping(u, JOB_STOP); + + if (!UNIT_VTABLE(u)->stop) + return -EBADR; + + unit_add_to_dbus_queue(u); + + return UNIT_VTABLE(u)->stop(u); +} + +/* Errors: + * -EBADR: This unit type does not support reloading. + * -ENOEXEC: Unit is not started. + * -EAGAIN: An operation is already in progress. Retry later. + */ +int unit_reload(Unit *u) { + UnitActiveState state; + Unit *following; + + assert(u); + + if (u->load_state != UNIT_LOADED) + return -EINVAL; + + if (!unit_can_reload(u)) + return -EBADR; + + state = unit_active_state(u); + if (state == UNIT_RELOADING) + return -EALREADY; + + if (state != UNIT_ACTIVE) + return -ENOEXEC; + + if ((following = unit_following(u))) { + log_debug("Redirecting reload request from %s to %s.", u->id, following->id); + return unit_reload(following); + } + + unit_status_log_starting_stopping_reloading(u, JOB_RELOAD); + + unit_add_to_dbus_queue(u); + return UNIT_VTABLE(u)->reload(u); +} + +bool unit_can_reload(Unit *u) { + assert(u); + + if (!UNIT_VTABLE(u)->reload) + return false; + + if (!UNIT_VTABLE(u)->can_reload) + return true; + + return UNIT_VTABLE(u)->can_reload(u); +} + +static void unit_check_unneeded(Unit *u) { + Iterator i; + Unit *other; + + assert(u); + + /* If this service shall be shut down when unneeded then do + * so. */ + + if (!u->stop_when_unneeded) + return; + + if (!UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u))) + return; + + SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY], i) + if (unit_pending_active(other)) + return; + + SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY_OVERRIDABLE], i) + if (unit_pending_active(other)) + return; + + SET_FOREACH(other, u->dependencies[UNIT_WANTED_BY], i) + if (unit_pending_active(other)) + return; + + SET_FOREACH(other, u->dependencies[UNIT_BOUND_BY], i) + if (unit_pending_active(other)) + return; + + log_info("Service %s is not needed anymore. Stopping.", u->id); + + /* Ok, nobody needs us anymore. Sniff. Then let's commit suicide */ + manager_add_job(u->manager, JOB_STOP, u, JOB_FAIL, true, NULL, NULL); +} + +static void retroactively_start_dependencies(Unit *u) { + Iterator i; + Unit *other; + + assert(u); + assert(UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u))); + + SET_FOREACH(other, u->dependencies[UNIT_REQUIRES], i) + if (!set_get(u->dependencies[UNIT_AFTER], other) && + !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other))) + manager_add_job(u->manager, JOB_START, other, JOB_REPLACE, true, NULL, NULL); + + SET_FOREACH(other, u->dependencies[UNIT_BINDS_TO], i) + if (!set_get(u->dependencies[UNIT_AFTER], other) && + !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other))) + manager_add_job(u->manager, JOB_START, other, JOB_REPLACE, true, NULL, NULL); + + SET_FOREACH(other, u->dependencies[UNIT_REQUIRES_OVERRIDABLE], i) + if (!set_get(u->dependencies[UNIT_AFTER], other) && + !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other))) + manager_add_job(u->manager, JOB_START, other, JOB_FAIL, false, NULL, NULL); + + SET_FOREACH(other, u->dependencies[UNIT_REQUISITE], i) + if (!set_get(u->dependencies[UNIT_AFTER], other) && + !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other))) + manager_add_job(u->manager, JOB_START, other, JOB_REPLACE, true, NULL, NULL); + + SET_FOREACH(other, u->dependencies[UNIT_WANTS], i) + if (!set_get(u->dependencies[UNIT_AFTER], other) && + !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other))) + manager_add_job(u->manager, JOB_START, other, JOB_FAIL, false, NULL, NULL); + + SET_FOREACH(other, u->dependencies[UNIT_CONFLICTS], i) + if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other))) + manager_add_job(u->manager, JOB_STOP, other, JOB_REPLACE, true, NULL, NULL); + + SET_FOREACH(other, u->dependencies[UNIT_CONFLICTED_BY], i) + if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other))) + manager_add_job(u->manager, JOB_STOP, other, JOB_REPLACE, true, NULL, NULL); +} + +static void retroactively_stop_dependencies(Unit *u) { + Iterator i; + Unit *other; + + assert(u); + assert(UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(u))); + + /* Pull down units which are bound to us recursively if enabled */ + SET_FOREACH(other, u->dependencies[UNIT_BOUND_BY], i) + if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other))) + manager_add_job(u->manager, JOB_STOP, other, JOB_REPLACE, true, NULL, NULL); +} + +static void check_unneeded_dependencies(Unit *u) { + Iterator i; + Unit *other; + + assert(u); + assert(UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(u))); + + /* Garbage collect services that might not be needed anymore, if enabled */ + SET_FOREACH(other, u->dependencies[UNIT_REQUIRES], i) + if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other))) + unit_check_unneeded(other); + SET_FOREACH(other, u->dependencies[UNIT_REQUIRES_OVERRIDABLE], i) + if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other))) + unit_check_unneeded(other); + SET_FOREACH(other, u->dependencies[UNIT_WANTS], i) + if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other))) + unit_check_unneeded(other); + SET_FOREACH(other, u->dependencies[UNIT_REQUISITE], i) + if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other))) + unit_check_unneeded(other); + SET_FOREACH(other, u->dependencies[UNIT_REQUISITE_OVERRIDABLE], i) + if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other))) + unit_check_unneeded(other); + SET_FOREACH(other, u->dependencies[UNIT_BINDS_TO], i) + if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other))) + unit_check_unneeded(other); +} + +void unit_trigger_on_failure(Unit *u) { + Unit *other; + Iterator i; + + assert(u); + + if (set_size(u->dependencies[UNIT_ON_FAILURE]) <= 0) + return; + + log_info("Triggering OnFailure= dependencies of %s.", u->id); + + SET_FOREACH(other, u->dependencies[UNIT_ON_FAILURE], i) { + int r; + + if ((r = manager_add_job(u->manager, JOB_START, other, u->on_failure_isolate ? JOB_ISOLATE : JOB_REPLACE, true, NULL, NULL)) < 0) + log_error("Failed to enqueue OnFailure= job: %s", strerror(-r)); + } +} + +void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_success) { + bool unexpected; + + assert(u); + assert(os < _UNIT_ACTIVE_STATE_MAX); + assert(ns < _UNIT_ACTIVE_STATE_MAX); + + /* Note that this is called for all low-level state changes, + * even if they might map to the same high-level + * UnitActiveState! That means that ns == os is OK an expected + * behavior here. For example: if a mount point is remounted + * this function will be called too! */ + + if (u->manager->n_reloading <= 0) { + dual_timestamp ts; + + dual_timestamp_get(&ts); + + if (UNIT_IS_INACTIVE_OR_FAILED(os) && !UNIT_IS_INACTIVE_OR_FAILED(ns)) + u->inactive_exit_timestamp = ts; + else if (!UNIT_IS_INACTIVE_OR_FAILED(os) && UNIT_IS_INACTIVE_OR_FAILED(ns)) + u->inactive_enter_timestamp = ts; + + if (!UNIT_IS_ACTIVE_OR_RELOADING(os) && UNIT_IS_ACTIVE_OR_RELOADING(ns)) + u->active_enter_timestamp = ts; + else if (UNIT_IS_ACTIVE_OR_RELOADING(os) && !UNIT_IS_ACTIVE_OR_RELOADING(ns)) + u->active_exit_timestamp = ts; + + timer_unit_notify(u, ns); + path_unit_notify(u, ns); + } + + if (UNIT_IS_INACTIVE_OR_FAILED(ns)) + cgroup_bonding_trim_list(u->cgroup_bondings, true); + + if (u->job) { + unexpected = false; + + if (u->job->state == JOB_WAITING) + + /* So we reached a different state for this + * job. Let's see if we can run it now if it + * failed previously due to EAGAIN. */ + job_add_to_run_queue(u->job); + + /* Let's check whether this state change constitutes a + * finished job, or maybe contradicts a running job and + * hence needs to invalidate jobs. */ + + switch (u->job->type) { + + case JOB_START: + case JOB_VERIFY_ACTIVE: + + if (UNIT_IS_ACTIVE_OR_RELOADING(ns)) + job_finish_and_invalidate(u->job, JOB_DONE, true); + else if (u->job->state == JOB_RUNNING && ns != UNIT_ACTIVATING) { + unexpected = true; + + if (UNIT_IS_INACTIVE_OR_FAILED(ns)) + job_finish_and_invalidate(u->job, ns == UNIT_FAILED ? JOB_FAILED : JOB_DONE, true); + } + + break; + + case JOB_RELOAD: + case JOB_RELOAD_OR_START: + + if (u->job->state == JOB_RUNNING) { + if (ns == UNIT_ACTIVE) + job_finish_and_invalidate(u->job, reload_success ? JOB_DONE : JOB_FAILED, true); + else if (ns != UNIT_ACTIVATING && ns != UNIT_RELOADING) { + unexpected = true; + + if (UNIT_IS_INACTIVE_OR_FAILED(ns)) + job_finish_and_invalidate(u->job, ns == UNIT_FAILED ? JOB_FAILED : JOB_DONE, true); + } + } + + break; + + case JOB_STOP: + case JOB_RESTART: + case JOB_TRY_RESTART: + + if (UNIT_IS_INACTIVE_OR_FAILED(ns)) + job_finish_and_invalidate(u->job, JOB_DONE, true); + else if (u->job->state == JOB_RUNNING && ns != UNIT_DEACTIVATING) { + unexpected = true; + job_finish_and_invalidate(u->job, JOB_FAILED, true); + } + + break; + + default: + assert_not_reached("Job type unknown"); + } + + } else + unexpected = true; + + if (u->manager->n_reloading <= 0) { + + /* If this state change happened without being + * requested by a job, then let's retroactively start + * or stop dependencies. We skip that step when + * deserializing, since we don't want to create any + * additional jobs just because something is already + * activated. */ + + if (unexpected) { + if (UNIT_IS_INACTIVE_OR_FAILED(os) && UNIT_IS_ACTIVE_OR_ACTIVATING(ns)) + retroactively_start_dependencies(u); + else if (UNIT_IS_ACTIVE_OR_ACTIVATING(os) && UNIT_IS_INACTIVE_OR_DEACTIVATING(ns)) + retroactively_stop_dependencies(u); + } + + /* stop unneeded units regardless if going down was expected or not */ + if (UNIT_IS_ACTIVE_OR_ACTIVATING(os) && UNIT_IS_INACTIVE_OR_DEACTIVATING(ns)) + check_unneeded_dependencies(u); + + if (ns != os && ns == UNIT_FAILED) { + log_struct(LOG_NOTICE, + "MESSAGE=Unit %s entered failed state", u->id, + "UNIT=%s", u->id, + NULL); + unit_trigger_on_failure(u); + } + } + + /* Some names are special */ + if (UNIT_IS_ACTIVE_OR_RELOADING(ns)) { + + if (unit_has_name(u, SPECIAL_DBUS_SERVICE)) + /* The bus just might have become available, + * hence try to connect to it, if we aren't + * yet connected. */ + bus_init(u->manager, true); + + if (u->type == UNIT_SERVICE && + !UNIT_IS_ACTIVE_OR_RELOADING(os) && + u->manager->n_reloading <= 0) { + /* Write audit record if we have just finished starting up */ + manager_send_unit_audit(u->manager, u, AUDIT_SERVICE_START, true); + u->in_audit = true; + } + + if (!UNIT_IS_ACTIVE_OR_RELOADING(os)) + manager_send_unit_plymouth(u->manager, u); + + } else { + + /* We don't care about D-Bus here, since we'll get an + * asynchronous notification for it anyway. */ + + if (u->type == UNIT_SERVICE && + UNIT_IS_INACTIVE_OR_FAILED(ns) && + !UNIT_IS_INACTIVE_OR_FAILED(os) && + u->manager->n_reloading <= 0) { + + /* Hmm, if there was no start record written + * write it now, so that we always have a nice + * pair */ + if (!u->in_audit) { + manager_send_unit_audit(u->manager, u, AUDIT_SERVICE_START, ns == UNIT_INACTIVE); + + if (ns == UNIT_INACTIVE) + manager_send_unit_audit(u->manager, u, AUDIT_SERVICE_STOP, true); + } else + /* Write audit record if we have just finished shutting down */ + manager_send_unit_audit(u->manager, u, AUDIT_SERVICE_STOP, ns == UNIT_INACTIVE); + + u->in_audit = false; + } + } + + manager_recheck_journal(u->manager); + + /* Maybe we finished startup and are now ready for being + * stopped because unneeded? */ + unit_check_unneeded(u); + + unit_add_to_dbus_queue(u); + unit_add_to_gc_queue(u); +} + +int unit_watch_fd(Unit *u, int fd, uint32_t events, Watch *w) { + struct epoll_event ev; + + assert(u); + assert(fd >= 0); + assert(w); + assert(w->type == WATCH_INVALID || (w->type == WATCH_FD && w->fd == fd && w->data.unit == u)); + + zero(ev); + ev.data.ptr = w; + ev.events = events; + + if (epoll_ctl(u->manager->epoll_fd, + w->type == WATCH_INVALID ? EPOLL_CTL_ADD : EPOLL_CTL_MOD, + fd, + &ev) < 0) + return -errno; + + w->fd = fd; + w->type = WATCH_FD; + w->data.unit = u; + + return 0; +} + +void unit_unwatch_fd(Unit *u, Watch *w) { + assert(u); + assert(w); + + if (w->type == WATCH_INVALID) + return; + + assert(w->type == WATCH_FD); + assert(w->data.unit == u); + assert_se(epoll_ctl(u->manager->epoll_fd, EPOLL_CTL_DEL, w->fd, NULL) >= 0); + + w->fd = -1; + w->type = WATCH_INVALID; + w->data.unit = NULL; +} + +int unit_watch_pid(Unit *u, pid_t pid) { + assert(u); + assert(pid >= 1); + + /* Watch a specific PID. We only support one unit watching + * each PID for now. */ + + return hashmap_put(u->manager->watch_pids, LONG_TO_PTR(pid), u); +} + +void unit_unwatch_pid(Unit *u, pid_t pid) { + assert(u); + assert(pid >= 1); + + hashmap_remove_value(u->manager->watch_pids, LONG_TO_PTR(pid), u); +} + +int unit_watch_timer(Unit *u, clockid_t clock_id, bool relative, usec_t usec, Watch *w) { + struct itimerspec its; + int flags, fd; + bool ours; + + assert(u); + assert(w); + assert(w->type == WATCH_INVALID || (w->type == WATCH_UNIT_TIMER && w->data.unit == u)); + + /* This will try to reuse the old timer if there is one */ + + if (w->type == WATCH_UNIT_TIMER) { + assert(w->data.unit == u); + assert(w->fd >= 0); + + ours = false; + fd = w->fd; + } else if (w->type == WATCH_INVALID) { + + ours = true; + fd = timerfd_create(clock_id, TFD_NONBLOCK|TFD_CLOEXEC); + if (fd < 0) + return -errno; + } else + assert_not_reached("Invalid watch type"); + + zero(its); + + if (usec <= 0) { + /* Set absolute time in the past, but not 0, since we + * don't want to disarm the timer */ + its.it_value.tv_sec = 0; + its.it_value.tv_nsec = 1; + + flags = TFD_TIMER_ABSTIME; + } else { + timespec_store(&its.it_value, usec); + flags = relative ? 0 : TFD_TIMER_ABSTIME; + } + + /* This will also flush the elapse counter */ + if (timerfd_settime(fd, flags, &its, NULL) < 0) + goto fail; + + if (w->type == WATCH_INVALID) { + struct epoll_event ev; + + zero(ev); + ev.data.ptr = w; + ev.events = EPOLLIN; + + if (epoll_ctl(u->manager->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0) + goto fail; + } + + w->type = WATCH_UNIT_TIMER; + w->fd = fd; + w->data.unit = u; + + return 0; + +fail: + if (ours) + close_nointr_nofail(fd); + + return -errno; +} + +void unit_unwatch_timer(Unit *u, Watch *w) { + assert(u); + assert(w); + + if (w->type == WATCH_INVALID) + return; + + assert(w->type == WATCH_UNIT_TIMER); + assert(w->data.unit == u); + assert(w->fd >= 0); + + assert_se(epoll_ctl(u->manager->epoll_fd, EPOLL_CTL_DEL, w->fd, NULL) >= 0); + close_nointr_nofail(w->fd); + + w->fd = -1; + w->type = WATCH_INVALID; + w->data.unit = NULL; +} + +bool unit_job_is_applicable(Unit *u, JobType j) { + assert(u); + assert(j >= 0 && j < _JOB_TYPE_MAX); + + switch (j) { + + case JOB_VERIFY_ACTIVE: + case JOB_START: + case JOB_STOP: + case JOB_NOP: + return true; + + case JOB_RESTART: + case JOB_TRY_RESTART: + return unit_can_start(u); + + case JOB_RELOAD: + return unit_can_reload(u); + + case JOB_RELOAD_OR_START: + return unit_can_reload(u) && unit_can_start(u); + + default: + assert_not_reached("Invalid job type"); + } +} + +int unit_add_dependency(Unit *u, UnitDependency d, Unit *other, bool add_reference) { + + static const UnitDependency inverse_table[_UNIT_DEPENDENCY_MAX] = { + [UNIT_REQUIRES] = UNIT_REQUIRED_BY, + [UNIT_REQUIRES_OVERRIDABLE] = UNIT_REQUIRED_BY_OVERRIDABLE, + [UNIT_WANTS] = UNIT_WANTED_BY, + [UNIT_REQUISITE] = UNIT_REQUIRED_BY, + [UNIT_REQUISITE_OVERRIDABLE] = UNIT_REQUIRED_BY_OVERRIDABLE, + [UNIT_BINDS_TO] = UNIT_BOUND_BY, + [UNIT_PART_OF] = UNIT_CONSISTS_OF, + [UNIT_REQUIRED_BY] = _UNIT_DEPENDENCY_INVALID, + [UNIT_REQUIRED_BY_OVERRIDABLE] = _UNIT_DEPENDENCY_INVALID, + [UNIT_WANTED_BY] = _UNIT_DEPENDENCY_INVALID, + [UNIT_BOUND_BY] = UNIT_BINDS_TO, + [UNIT_CONSISTS_OF] = UNIT_PART_OF, + [UNIT_CONFLICTS] = UNIT_CONFLICTED_BY, + [UNIT_CONFLICTED_BY] = UNIT_CONFLICTS, + [UNIT_BEFORE] = UNIT_AFTER, + [UNIT_AFTER] = UNIT_BEFORE, + [UNIT_ON_FAILURE] = _UNIT_DEPENDENCY_INVALID, + [UNIT_REFERENCES] = UNIT_REFERENCED_BY, + [UNIT_REFERENCED_BY] = UNIT_REFERENCES, + [UNIT_TRIGGERS] = UNIT_TRIGGERED_BY, + [UNIT_TRIGGERED_BY] = UNIT_TRIGGERS, + [UNIT_PROPAGATES_RELOAD_TO] = UNIT_RELOAD_PROPAGATED_FROM, + [UNIT_RELOAD_PROPAGATED_FROM] = UNIT_PROPAGATES_RELOAD_TO, + }; + int r, q = 0, v = 0, w = 0; + + assert(u); + assert(d >= 0 && d < _UNIT_DEPENDENCY_MAX); + assert(other); + + u = unit_follow_merge(u); + other = unit_follow_merge(other); + + /* We won't allow dependencies on ourselves. We will not + * consider them an error however. */ + if (u == other) + return 0; + + if ((r = set_ensure_allocated(&u->dependencies[d], trivial_hash_func, trivial_compare_func)) < 0) + return r; + + if (inverse_table[d] != _UNIT_DEPENDENCY_INVALID) + if ((r = set_ensure_allocated(&other->dependencies[inverse_table[d]], trivial_hash_func, trivial_compare_func)) < 0) + return r; + + if (add_reference) + if ((r = set_ensure_allocated(&u->dependencies[UNIT_REFERENCES], trivial_hash_func, trivial_compare_func)) < 0 || + (r = set_ensure_allocated(&other->dependencies[UNIT_REFERENCED_BY], trivial_hash_func, trivial_compare_func)) < 0) + return r; + + if ((q = set_put(u->dependencies[d], other)) < 0) + return q; + + if (inverse_table[d] != _UNIT_DEPENDENCY_INVALID) + if ((v = set_put(other->dependencies[inverse_table[d]], u)) < 0) { + r = v; + goto fail; + } + + if (add_reference) { + if ((w = set_put(u->dependencies[UNIT_REFERENCES], other)) < 0) { + r = w; + goto fail; + } + + if ((r = set_put(other->dependencies[UNIT_REFERENCED_BY], u)) < 0) + goto fail; + } + + unit_add_to_dbus_queue(u); + return 0; + +fail: + if (q > 0) + set_remove(u->dependencies[d], other); + + if (v > 0) + set_remove(other->dependencies[inverse_table[d]], u); + + if (w > 0) + set_remove(u->dependencies[UNIT_REFERENCES], other); + + return r; +} + +int unit_add_two_dependencies(Unit *u, UnitDependency d, UnitDependency e, Unit *other, bool add_reference) { + int r; + + assert(u); + + if ((r = unit_add_dependency(u, d, other, add_reference)) < 0) + return r; + + if ((r = unit_add_dependency(u, e, other, add_reference)) < 0) + return r; + + return 0; +} + +static const char *resolve_template(Unit *u, const char *name, const char*path, char **p) { + char *s; + + assert(u); + assert(name || path); + + if (!name) + name = path_get_file_name(path); + + if (!unit_name_is_template(name)) { + *p = NULL; + return name; + } + + if (u->instance) + s = unit_name_replace_instance(name, u->instance); + else { + char *i; + + if (!(i = unit_name_to_prefix(u->id))) + return NULL; + + s = unit_name_replace_instance(name, i); + free(i); + } + + if (!s) + return NULL; + + *p = s; + return s; +} + +int unit_add_dependency_by_name(Unit *u, UnitDependency d, const char *name, const char *path, bool add_reference) { + Unit *other; + int r; + char *s; + + assert(u); + assert(name || path); + + if (!(name = resolve_template(u, name, path, &s))) + return -ENOMEM; + + if ((r = manager_load_unit(u->manager, name, path, NULL, &other)) < 0) + goto finish; + + r = unit_add_dependency(u, d, other, add_reference); + +finish: + free(s); + return r; +} + +int unit_add_two_dependencies_by_name(Unit *u, UnitDependency d, UnitDependency e, const char *name, const char *path, bool add_reference) { + Unit *other; + int r; + char *s; + + assert(u); + assert(name || path); + + if (!(name = resolve_template(u, name, path, &s))) + return -ENOMEM; + + if ((r = manager_load_unit(u->manager, name, path, NULL, &other)) < 0) + goto finish; + + r = unit_add_two_dependencies(u, d, e, other, add_reference); + +finish: + free(s); + return r; +} + +int unit_add_dependency_by_name_inverse(Unit *u, UnitDependency d, const char *name, const char *path, bool add_reference) { + Unit *other; + int r; + char *s; + + assert(u); + assert(name || path); + + if (!(name = resolve_template(u, name, path, &s))) + return -ENOMEM; + + if ((r = manager_load_unit(u->manager, name, path, NULL, &other)) < 0) + goto finish; + + r = unit_add_dependency(other, d, u, add_reference); + +finish: + free(s); + return r; +} + +int unit_add_two_dependencies_by_name_inverse(Unit *u, UnitDependency d, UnitDependency e, const char *name, const char *path, bool add_reference) { + Unit *other; + int r; + char *s; + + assert(u); + assert(name || path); + + if (!(name = resolve_template(u, name, path, &s))) + return -ENOMEM; + + if ((r = manager_load_unit(u->manager, name, path, NULL, &other)) < 0) + goto finish; + + if ((r = unit_add_two_dependencies(other, d, e, u, add_reference)) < 0) + goto finish; + +finish: + free(s); + return r; +} + +int set_unit_path(const char *p) { + char *cwd, *c; + int r; + + /* This is mostly for debug purposes */ + + if (path_is_absolute(p)) { + if (!(c = strdup(p))) + return -ENOMEM; + } else { + if (!(cwd = get_current_dir_name())) + return -errno; + + r = asprintf(&c, "%s/%s", cwd, p); + free(cwd); + + if (r < 0) + return -ENOMEM; + } + + if (setenv("SYSTEMD_UNIT_PATH", c, 0) < 0) { + r = -errno; + free(c); + return r; + } + + return 0; +} + +char *unit_dbus_path(Unit *u) { + assert(u); + + if (!u->id) + return NULL; + + return unit_dbus_path_from_name(u->id); +} + +int unit_add_cgroup(Unit *u, CGroupBonding *b) { + int r; + + assert(u); + assert(b); + + assert(b->path); + + if (!b->controller) { + if (!(b->controller = strdup(SYSTEMD_CGROUP_CONTROLLER))) + return -ENOMEM; + + b->ours = true; + } + + /* Ensure this hasn't been added yet */ + assert(!b->unit); + + if (streq(b->controller, SYSTEMD_CGROUP_CONTROLLER)) { + CGroupBonding *l; + + l = hashmap_get(u->manager->cgroup_bondings, b->path); + LIST_PREPEND(CGroupBonding, by_path, l, b); + + if ((r = hashmap_replace(u->manager->cgroup_bondings, b->path, l)) < 0) { + LIST_REMOVE(CGroupBonding, by_path, l, b); + return r; + } + } + + LIST_PREPEND(CGroupBonding, by_unit, u->cgroup_bondings, b); + b->unit = u; + + return 0; +} + +char *unit_default_cgroup_path(Unit *u) { + char *p; + + assert(u); + + if (u->instance) { + char *t; + + t = unit_name_template(u->id); + if (!t) + return NULL; + + p = strjoin(u->manager->cgroup_hierarchy, "/", t, "/", u->instance, NULL); + free(t); + } else + p = strjoin(u->manager->cgroup_hierarchy, "/", u->id, NULL); + + return p; +} + +int unit_add_cgroup_from_text(Unit *u, const char *name) { + char *controller = NULL, *path = NULL; + CGroupBonding *b = NULL; + bool ours = false; + int r; + + assert(u); + assert(name); + + if ((r = cg_split_spec(name, &controller, &path)) < 0) + return r; + + if (!path) { + path = unit_default_cgroup_path(u); + ours = true; + } + + if (!controller) { + controller = strdup(SYSTEMD_CGROUP_CONTROLLER); + ours = true; + } + + if (!path || !controller) { + free(path); + free(controller); + + return -ENOMEM; + } + + if (cgroup_bonding_find_list(u->cgroup_bondings, controller)) { + r = -EEXIST; + goto fail; + } + + if (!(b = new0(CGroupBonding, 1))) { + r = -ENOMEM; + goto fail; + } + + b->controller = controller; + b->path = path; + b->ours = ours; + b->essential = streq(controller, SYSTEMD_CGROUP_CONTROLLER); + + if ((r = unit_add_cgroup(u, b)) < 0) + goto fail; + + return 0; + +fail: + free(path); + free(controller); + free(b); + + return r; +} + +static int unit_add_one_default_cgroup(Unit *u, const char *controller) { + CGroupBonding *b = NULL; + int r = -ENOMEM; + + assert(u); + + if (!controller) + controller = SYSTEMD_CGROUP_CONTROLLER; + + if (cgroup_bonding_find_list(u->cgroup_bondings, controller)) + return 0; + + if (!(b = new0(CGroupBonding, 1))) + return -ENOMEM; + + if (!(b->controller = strdup(controller))) + goto fail; + + b->path = unit_default_cgroup_path(u); + if (!b->path) + goto fail; + + b->ours = true; + b->essential = streq(controller, SYSTEMD_CGROUP_CONTROLLER); + + if ((r = unit_add_cgroup(u, b)) < 0) + goto fail; + + return 0; + +fail: + free(b->path); + free(b->controller); + free(b); + + return r; +} + +int unit_add_default_cgroups(Unit *u) { + CGroupAttribute *a; + char **c; + int r; + + assert(u); + + /* Adds in the default cgroups, if they weren't specified + * otherwise. */ + + if (!u->manager->cgroup_hierarchy) + return 0; + + if ((r = unit_add_one_default_cgroup(u, NULL)) < 0) + return r; + + STRV_FOREACH(c, u->manager->default_controllers) + unit_add_one_default_cgroup(u, *c); + + LIST_FOREACH(by_unit, a, u->cgroup_attributes) + unit_add_one_default_cgroup(u, a->controller); + + return 0; +} + +CGroupBonding* unit_get_default_cgroup(Unit *u) { + assert(u); + + return cgroup_bonding_find_list(u->cgroup_bondings, SYSTEMD_CGROUP_CONTROLLER); +} + +int unit_add_cgroup_attribute(Unit *u, const char *controller, const char *name, const char *value, CGroupAttributeMapCallback map_callback) { + int r; + char *c = NULL; + CGroupAttribute *a; + + assert(u); + assert(name); + assert(value); + + if (!controller) { + const char *dot; + + dot = strchr(name, '.'); + if (!dot) + return -EINVAL; + + c = strndup(name, dot - name); + if (!c) + return -ENOMEM; + + controller = c; + } + + if (streq(controller, SYSTEMD_CGROUP_CONTROLLER)) { + r = -EINVAL; + goto finish; + } + + a = new0(CGroupAttribute, 1); + if (!a) { + r = -ENOMEM; + goto finish; + } + + if (c) { + a->controller = c; + c = NULL; + } else + a->controller = strdup(controller); + + a->name = strdup(name); + a->value = strdup(value); + + if (!a->controller || !a->name || !a->value) { + free(a->controller); + free(a->name); + free(a->value); + free(a); + + return -ENOMEM; + } + + a->map_callback = map_callback; + + LIST_PREPEND(CGroupAttribute, by_unit, u->cgroup_attributes, a); + + r = 0; + +finish: + free(c); + return r; +} + +int unit_load_related_unit(Unit *u, const char *type, Unit **_found) { + char *t; + int r; + + assert(u); + assert(type); + assert(_found); + + if (!(t = unit_name_change_suffix(u->id, type))) + return -ENOMEM; + + assert(!unit_has_name(u, t)); + + r = manager_load_unit(u->manager, t, NULL, NULL, _found); + free(t); + + assert(r < 0 || *_found != u); + + return r; +} + +int unit_get_related_unit(Unit *u, const char *type, Unit **_found) { + Unit *found; + char *t; + + assert(u); + assert(type); + assert(_found); + + if (!(t = unit_name_change_suffix(u->id, type))) + return -ENOMEM; + + assert(!unit_has_name(u, t)); + + found = manager_get_unit(u->manager, t); + free(t); + + if (!found) + return -ENOENT; + + *_found = found; + return 0; +} + +int unit_watch_bus_name(Unit *u, const char *name) { + assert(u); + assert(name); + + /* Watch a specific name on the bus. We only support one unit + * watching each name for now. */ + + return hashmap_put(u->manager->watch_bus, name, u); +} + +void unit_unwatch_bus_name(Unit *u, const char *name) { + assert(u); + assert(name); + + hashmap_remove_value(u->manager->watch_bus, name, u); +} + +bool unit_can_serialize(Unit *u) { + assert(u); + + return UNIT_VTABLE(u)->serialize && UNIT_VTABLE(u)->deserialize_item; +} + +int unit_serialize(Unit *u, FILE *f, FDSet *fds, bool serialize_jobs) { + int r; + + assert(u); + assert(f); + assert(fds); + + if (!unit_can_serialize(u)) + return 0; + + if ((r = UNIT_VTABLE(u)->serialize(u, f, fds)) < 0) + return r; + + + if (serialize_jobs) { + if (u->job) { + fprintf(f, "job\n"); + job_serialize(u->job, f, fds); + } + + if (u->nop_job) { + fprintf(f, "job\n"); + job_serialize(u->nop_job, f, fds); + } + } + + dual_timestamp_serialize(f, "inactive-exit-timestamp", &u->inactive_exit_timestamp); + dual_timestamp_serialize(f, "active-enter-timestamp", &u->active_enter_timestamp); + dual_timestamp_serialize(f, "active-exit-timestamp", &u->active_exit_timestamp); + dual_timestamp_serialize(f, "inactive-enter-timestamp", &u->inactive_enter_timestamp); + dual_timestamp_serialize(f, "condition-timestamp", &u->condition_timestamp); + + if (dual_timestamp_is_set(&u->condition_timestamp)) + unit_serialize_item(u, f, "condition-result", yes_no(u->condition_result)); + + /* End marker */ + fputc('\n', f); + return 0; +} + +void unit_serialize_item_format(Unit *u, FILE *f, const char *key, const char *format, ...) { + va_list ap; + + assert(u); + assert(f); + assert(key); + assert(format); + + fputs(key, f); + fputc('=', f); + + va_start(ap, format); + vfprintf(f, format, ap); + va_end(ap); + + fputc('\n', f); +} + +void unit_serialize_item(Unit *u, FILE *f, const char *key, const char *value) { + assert(u); + assert(f); + assert(key); + assert(value); + + fprintf(f, "%s=%s\n", key, value); +} + +int unit_deserialize(Unit *u, FILE *f, FDSet *fds) { + int r; + + assert(u); + assert(f); + assert(fds); + + if (!unit_can_serialize(u)) + return 0; + + for (;;) { + char line[LINE_MAX], *l, *v; + size_t k; + + if (!fgets(line, sizeof(line), f)) { + if (feof(f)) + return 0; + return -errno; + } + + char_array_0(line); + l = strstrip(line); + + /* End marker */ + if (l[0] == 0) + return 0; + + k = strcspn(l, "="); + + if (l[k] == '=') { + l[k] = 0; + v = l+k+1; + } else + v = l+k; + + if (streq(l, "job")) { + if (v[0] == '\0') { + /* new-style serialized job */ + Job *j = job_new_raw(u); + if (!j) + return -ENOMEM; + + r = job_deserialize(j, f, fds); + if (r < 0) { + job_free(j); + return r; + } + + r = hashmap_put(u->manager->jobs, UINT32_TO_PTR(j->id), j); + if (r < 0) { + job_free(j); + return r; + } + + r = job_install_deserialized(j); + if (r < 0) { + hashmap_remove(u->manager->jobs, UINT32_TO_PTR(j->id)); + job_free(j); + return r; + } + } else { + /* legacy */ + JobType type = job_type_from_string(v); + if (type < 0) + log_debug("Failed to parse job type value %s", v); + else + u->deserialized_job = type; + } + continue; + } else if (streq(l, "inactive-exit-timestamp")) { + dual_timestamp_deserialize(v, &u->inactive_exit_timestamp); + continue; + } else if (streq(l, "active-enter-timestamp")) { + dual_timestamp_deserialize(v, &u->active_enter_timestamp); + continue; + } else if (streq(l, "active-exit-timestamp")) { + dual_timestamp_deserialize(v, &u->active_exit_timestamp); + continue; + } else if (streq(l, "inactive-enter-timestamp")) { + dual_timestamp_deserialize(v, &u->inactive_enter_timestamp); + continue; + } else if (streq(l, "condition-timestamp")) { + dual_timestamp_deserialize(v, &u->condition_timestamp); + continue; + } else if (streq(l, "condition-result")) { + int b; + + if ((b = parse_boolean(v)) < 0) + log_debug("Failed to parse condition result value %s", v); + else + u->condition_result = b; + + continue; + } + + if ((r = UNIT_VTABLE(u)->deserialize_item(u, l, v, fds)) < 0) + return r; + } +} + +int unit_add_node_link(Unit *u, const char *what, bool wants) { + Unit *device; + char *e; + int r; + + assert(u); + + if (!what) + return 0; + + /* Adds in links to the device node that this unit is based on */ + + if (!is_device_path(what)) + return 0; + + e = unit_name_from_path(what, ".device"); + if (!e) + return -ENOMEM; + + r = manager_load_unit(u->manager, e, NULL, NULL, &device); + free(e); + if (r < 0) + return r; + + r = unit_add_two_dependencies(u, UNIT_AFTER, UNIT_BINDS_TO, device, true); + if (r < 0) + return r; + + if (wants) { + r = unit_add_dependency(device, UNIT_WANTS, u, false); + if (r < 0) + return r; + } + + return 0; +} + +int unit_coldplug(Unit *u) { + int r; + + assert(u); + + if (UNIT_VTABLE(u)->coldplug) + if ((r = UNIT_VTABLE(u)->coldplug(u)) < 0) + return r; + + if (u->job) { + r = job_coldplug(u->job); + if (r < 0) + return r; + } else if (u->deserialized_job >= 0) { + /* legacy */ + r = manager_add_job(u->manager, u->deserialized_job, u, JOB_IGNORE_REQUIREMENTS, false, NULL, NULL); + if (r < 0) + return r; + + u->deserialized_job = _JOB_TYPE_INVALID; + } + + return 0; +} + +void unit_status_printf(Unit *u, const char *status, const char *format, ...) { + va_list ap; + + assert(u); + assert(format); + + if (!manager_get_show_status(u->manager)) + return; + + if (!manager_is_booting_or_shutting_down(u->manager)) + return; + + va_start(ap, format); + status_vprintf(status, true, format, ap); + va_end(ap); +} + +bool unit_need_daemon_reload(Unit *u) { + struct stat st; + + assert(u); + + if (u->fragment_path) { + zero(st); + if (stat(u->fragment_path, &st) < 0) + /* What, cannot access this anymore? */ + return true; + + if (u->fragment_mtime > 0 && + timespec_load(&st.st_mtim) != u->fragment_mtime) + return true; + } + + if (u->source_path) { + zero(st); + if (stat(u->source_path, &st) < 0) + return true; + + if (u->source_mtime > 0 && + timespec_load(&st.st_mtim) != u->source_mtime) + return true; + } + + return false; +} + +void unit_reset_failed(Unit *u) { + assert(u); + + if (UNIT_VTABLE(u)->reset_failed) + UNIT_VTABLE(u)->reset_failed(u); +} + +Unit *unit_following(Unit *u) { + assert(u); + + if (UNIT_VTABLE(u)->following) + return UNIT_VTABLE(u)->following(u); + + return NULL; +} + +bool unit_pending_inactive(Unit *u) { + assert(u); + + /* Returns true if the unit is inactive or going down */ + + if (UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(u))) + return true; + + if (u->job && u->job->type == JOB_STOP) + return true; + + return false; +} + +bool unit_pending_active(Unit *u) { + assert(u); + + /* Returns true if the unit is active or going up */ + + if (UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u))) + return true; + + if (u->job && + (u->job->type == JOB_START || + u->job->type == JOB_RELOAD_OR_START || + u->job->type == JOB_RESTART)) + return true; + + return false; +} + +int unit_kill(Unit *u, KillWho w, int signo, DBusError *error) { + assert(u); + assert(w >= 0 && w < _KILL_WHO_MAX); + assert(signo > 0); + assert(signo < _NSIG); + + if (!UNIT_VTABLE(u)->kill) + return -ENOTSUP; + + return UNIT_VTABLE(u)->kill(u, w, signo, error); +} + +int unit_following_set(Unit *u, Set **s) { + assert(u); + assert(s); + + if (UNIT_VTABLE(u)->following_set) + return UNIT_VTABLE(u)->following_set(u, s); + + *s = NULL; + return 0; +} + +UnitFileState unit_get_unit_file_state(Unit *u) { + assert(u); + + if (u->unit_file_state < 0 && u->fragment_path) + u->unit_file_state = unit_file_get_state( + u->manager->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER, + NULL, path_get_file_name(u->fragment_path)); + + return u->unit_file_state; +} + +Unit* unit_ref_set(UnitRef *ref, Unit *u) { + assert(ref); + assert(u); + + if (ref->unit) + unit_ref_unset(ref); + + ref->unit = u; + LIST_PREPEND(UnitRef, refs, u->refs, ref); + return u; +} + +void unit_ref_unset(UnitRef *ref) { + assert(ref); + + if (!ref->unit) + return; + + LIST_REMOVE(UnitRef, refs, ref->unit->refs, ref); + ref->unit = NULL; +} + +int unit_add_one_mount_link(Unit *u, Mount *m) { + char **i; + + assert(u); + assert(m); + + if (u->load_state != UNIT_LOADED || + UNIT(m)->load_state != UNIT_LOADED) + return 0; + + STRV_FOREACH(i, u->requires_mounts_for) { + + if (UNIT(m) == u) + continue; + + if (!path_startswith(*i, m->where)) + continue; + + return unit_add_two_dependencies(u, UNIT_AFTER, UNIT_REQUIRES, UNIT(m), true); + } + + return 0; +} + +int unit_add_mount_links(Unit *u) { + Unit *other; + int r; + + assert(u); + + LIST_FOREACH(units_by_type, other, u->manager->units_by_type[UNIT_MOUNT]) { + r = unit_add_one_mount_link(u, MOUNT(other)); + if (r < 0) + return r; + } + + return 0; +} + +int unit_exec_context_defaults(Unit *u, ExecContext *c) { + unsigned i; + int r; + + assert(u); + assert(c); + + /* This only copies in the ones that need memory */ + + for (i = 0; i < RLIMIT_NLIMITS; i++) + if (u->manager->rlimit[i] && !c->rlimit[i]) { + c->rlimit[i] = newdup(struct rlimit, u->manager->rlimit[i], 1); + if (!c->rlimit[i]) + return -ENOMEM; + } + + if (u->manager->running_as == SYSTEMD_USER && + !c->working_directory) { + + r = get_home_dir(&c->working_directory); + if (r < 0) + return r; + } + + return 0; +} + +ExecContext *unit_get_exec_context(Unit *u) { + size_t offset; + assert(u); + + offset = UNIT_VTABLE(u)->exec_context_offset; + if (offset <= 0) + return NULL; + + return (ExecContext*) ((uint8_t*) u + offset); +} + +static const char* const unit_active_state_table[_UNIT_ACTIVE_STATE_MAX] = { + [UNIT_ACTIVE] = "active", + [UNIT_RELOADING] = "reloading", + [UNIT_INACTIVE] = "inactive", + [UNIT_FAILED] = "failed", + [UNIT_ACTIVATING] = "activating", + [UNIT_DEACTIVATING] = "deactivating" +}; + +DEFINE_STRING_TABLE_LOOKUP(unit_active_state, UnitActiveState); + +static const char* const unit_dependency_table[_UNIT_DEPENDENCY_MAX] = { + [UNIT_REQUIRES] = "Requires", + [UNIT_REQUIRES_OVERRIDABLE] = "RequiresOverridable", + [UNIT_REQUISITE] = "Requisite", + [UNIT_REQUISITE_OVERRIDABLE] = "RequisiteOverridable", + [UNIT_WANTS] = "Wants", + [UNIT_BINDS_TO] = "BindsTo", + [UNIT_PART_OF] = "PartOf", + [UNIT_REQUIRED_BY] = "RequiredBy", + [UNIT_REQUIRED_BY_OVERRIDABLE] = "RequiredByOverridable", + [UNIT_WANTED_BY] = "WantedBy", + [UNIT_BOUND_BY] = "BoundBy", + [UNIT_CONSISTS_OF] = "ConsistsOf", + [UNIT_CONFLICTS] = "Conflicts", + [UNIT_CONFLICTED_BY] = "ConflictedBy", + [UNIT_BEFORE] = "Before", + [UNIT_AFTER] = "After", + [UNIT_ON_FAILURE] = "OnFailure", + [UNIT_TRIGGERS] = "Triggers", + [UNIT_TRIGGERED_BY] = "TriggeredBy", + [UNIT_PROPAGATES_RELOAD_TO] = "PropagatesReloadTo", + [UNIT_RELOAD_PROPAGATED_FROM] = "ReloadPropagatedFrom", + [UNIT_REFERENCES] = "References", + [UNIT_REFERENCED_BY] = "ReferencedBy", +}; + +DEFINE_STRING_TABLE_LOOKUP(unit_dependency, UnitDependency); diff --git a/src/core/unit.h b/src/core/unit.h new file mode 100644 index 000000000..702bfeece --- /dev/null +++ b/src/core/unit.h @@ -0,0 +1,564 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +#include +#include + +typedef struct Unit Unit; +typedef struct UnitVTable UnitVTable; +typedef enum UnitActiveState UnitActiveState; +typedef enum UnitDependency UnitDependency; +typedef struct UnitRef UnitRef; +typedef struct UnitStatusMessageFormats UnitStatusMessageFormats; + +#include "set.h" +#include "util.h" +#include "list.h" +#include "socket-util.h" +#include "execute.h" +#include "condition.h" +#include "install.h" +#include "unit-name.h" + +enum UnitActiveState { + UNIT_ACTIVE, + UNIT_RELOADING, + UNIT_INACTIVE, + UNIT_FAILED, + UNIT_ACTIVATING, + UNIT_DEACTIVATING, + _UNIT_ACTIVE_STATE_MAX, + _UNIT_ACTIVE_STATE_INVALID = -1 +}; + +static inline bool UNIT_IS_ACTIVE_OR_RELOADING(UnitActiveState t) { + return t == UNIT_ACTIVE || t == UNIT_RELOADING; +} + +static inline bool UNIT_IS_ACTIVE_OR_ACTIVATING(UnitActiveState t) { + return t == UNIT_ACTIVE || t == UNIT_ACTIVATING || t == UNIT_RELOADING; +} + +static inline bool UNIT_IS_INACTIVE_OR_DEACTIVATING(UnitActiveState t) { + return t == UNIT_INACTIVE || t == UNIT_FAILED || t == UNIT_DEACTIVATING; +} + +static inline bool UNIT_IS_INACTIVE_OR_FAILED(UnitActiveState t) { + return t == UNIT_INACTIVE || t == UNIT_FAILED; +} + +enum UnitDependency { + /* Positive dependencies */ + UNIT_REQUIRES, + UNIT_REQUIRES_OVERRIDABLE, + UNIT_REQUISITE, + UNIT_REQUISITE_OVERRIDABLE, + UNIT_WANTS, + UNIT_BINDS_TO, + UNIT_PART_OF, + + /* Inverse of the above */ + UNIT_REQUIRED_BY, /* inverse of 'requires' and 'requisite' is 'required_by' */ + UNIT_REQUIRED_BY_OVERRIDABLE, /* inverse of 'requires_overridable' and 'requisite_overridable' is 'soft_required_by' */ + UNIT_WANTED_BY, /* inverse of 'wants' */ + UNIT_BOUND_BY, /* inverse of 'binds_to' */ + UNIT_CONSISTS_OF, /* inverse of 'part_of' */ + + /* Negative dependencies */ + UNIT_CONFLICTS, /* inverse of 'conflicts' is 'conflicted_by' */ + UNIT_CONFLICTED_BY, + + /* Order */ + UNIT_BEFORE, /* inverse of 'before' is 'after' and vice versa */ + UNIT_AFTER, + + /* On Failure */ + UNIT_ON_FAILURE, + + /* Triggers (i.e. a socket triggers a service) */ + UNIT_TRIGGERS, + UNIT_TRIGGERED_BY, + + /* Propagate reloads */ + UNIT_PROPAGATES_RELOAD_TO, + UNIT_RELOAD_PROPAGATED_FROM, + + /* Reference information for GC logic */ + UNIT_REFERENCES, /* Inverse of 'references' is 'referenced_by' */ + UNIT_REFERENCED_BY, + + _UNIT_DEPENDENCY_MAX, + _UNIT_DEPENDENCY_INVALID = -1 +}; + +#include "manager.h" +#include "job.h" +#include "cgroup.h" +#include "cgroup-attr.h" + +struct Unit { + Manager *manager; + + UnitType type; + UnitLoadState load_state; + Unit *merged_into; + + char *id; /* One name is special because we use it for identification. Points to an entry in the names set */ + char *instance; + + Set *names; + Set *dependencies[_UNIT_DEPENDENCY_MAX]; + + char **requires_mounts_for; + + char *description; + char **documentation; + + char *fragment_path; /* if loaded from a config file this is the primary path to it */ + char *source_path; /* if converted, the source file */ + usec_t fragment_mtime; + usec_t source_mtime; + + /* If there is something to do with this unit, then this is the installed job for it */ + Job *job; + + /* JOB_NOP jobs are special and can be installed without disturbing the real job. */ + Job *nop_job; + + usec_t job_timeout; + + /* References to this */ + LIST_HEAD(UnitRef, refs); + + /* Conditions to check */ + LIST_HEAD(Condition, conditions); + + dual_timestamp condition_timestamp; + + dual_timestamp inactive_exit_timestamp; + dual_timestamp active_enter_timestamp; + dual_timestamp active_exit_timestamp; + dual_timestamp inactive_enter_timestamp; + + /* Counterparts in the cgroup filesystem */ + CGroupBonding *cgroup_bondings; + CGroupAttribute *cgroup_attributes; + + /* Per type list */ + LIST_FIELDS(Unit, units_by_type); + + /* All units which have requires_mounts_for set */ + LIST_FIELDS(Unit, has_requires_mounts_for); + + /* Load queue */ + LIST_FIELDS(Unit, load_queue); + + /* D-Bus queue */ + LIST_FIELDS(Unit, dbus_queue); + + /* Cleanup queue */ + LIST_FIELDS(Unit, cleanup_queue); + + /* GC queue */ + LIST_FIELDS(Unit, gc_queue); + + /* Used during GC sweeps */ + unsigned gc_marker; + + /* When deserializing, temporarily store the job type for this + * unit here, if there was a job scheduled. + * Only for deserializing from a legacy version. New style uses full + * serialized jobs. */ + int deserialized_job; /* This is actually of type JobType */ + + /* Error code when we didn't manage to load the unit (negative) */ + int load_error; + + /* Cached unit file state */ + UnitFileState unit_file_state; + + /* Garbage collect us we nobody wants or requires us anymore */ + bool stop_when_unneeded; + + /* Create default dependencies */ + bool default_dependencies; + + /* Refuse manual starting, allow starting only indirectly via dependency. */ + bool refuse_manual_start; + + /* Don't allow the user to stop this unit manually, allow stopping only indirectly via dependency. */ + bool refuse_manual_stop; + + /* Allow isolation requests */ + bool allow_isolate; + + /* Isolate OnFailure unit */ + bool on_failure_isolate; + + /* Ignore this unit when isolating */ + bool ignore_on_isolate; + + /* Ignore this unit when snapshotting */ + bool ignore_on_snapshot; + + /* Did the last condition check succeed? */ + bool condition_result; + + bool in_load_queue:1; + bool in_dbus_queue:1; + bool in_cleanup_queue:1; + bool in_gc_queue:1; + + bool sent_dbus_new_signal:1; + + bool no_gc:1; + + bool in_audit:1; +}; + +struct UnitRef { + /* Keeps tracks of references to a unit. This is useful so + * that we can merge two units if necessary and correct all + * references to them */ + + Unit* unit; + LIST_FIELDS(UnitRef, refs); +}; + +struct UnitStatusMessageFormats { + const char *starting_stopping[2]; + const char *finished_start_job[_JOB_RESULT_MAX]; + const char *finished_stop_job[_JOB_RESULT_MAX]; +}; + +#include "service.h" +#include "timer.h" +#include "socket.h" +#include "target.h" +#include "device.h" +#include "mount.h" +#include "automount.h" +#include "snapshot.h" +#include "swap.h" +#include "path.h" + +struct UnitVTable { + /* How much memory does an object of this unit type need */ + size_t object_size; + + /* If greater than 0, the offset into the object where + * ExecContext is found, if the unit type has that */ + size_t exec_context_offset; + + /* Config file sections this unit type understands, separated + * by NUL chars */ + const char *sections; + + /* This should reset all type-specific variables. This should + * not allocate memory, and is called with zero-initialized + * data. It should hence only initialize variables that need + * to be set != 0. */ + void (*init)(Unit *u); + + /* This should free all type-specific variables. It should be + * idempotent. */ + void (*done)(Unit *u); + + /* Actually load data from disk. This may fail, and should set + * load_state to UNIT_LOADED, UNIT_MERGED or leave it at + * UNIT_STUB if no configuration could be found. */ + int (*load)(Unit *u); + + /* If a lot of units got created via enumerate(), this is + * where to actually set the state and call unit_notify(). */ + int (*coldplug)(Unit *u); + + void (*dump)(Unit *u, FILE *f, const char *prefix); + + int (*start)(Unit *u); + int (*stop)(Unit *u); + int (*reload)(Unit *u); + + int (*kill)(Unit *u, KillWho w, int signo, DBusError *error); + + bool (*can_reload)(Unit *u); + + /* Write all data that cannot be restored from other sources + * away using unit_serialize_item() */ + int (*serialize)(Unit *u, FILE *f, FDSet *fds); + + /* Restore one item from the serialization */ + int (*deserialize_item)(Unit *u, const char *key, const char *data, FDSet *fds); + + /* Try to match up fds with what we need for this unit */ + int (*distribute_fds)(Unit *u, FDSet *fds); + + /* Boils down the more complex internal state of this unit to + * a simpler one that the engine can understand */ + UnitActiveState (*active_state)(Unit *u); + + /* Returns the substate specific to this unit type as + * string. This is purely information so that we can give the + * user a more fine grained explanation in which actual state a + * unit is in. */ + const char* (*sub_state_to_string)(Unit *u); + + /* Return true when there is reason to keep this entry around + * even nothing references it and it isn't active in any + * way */ + bool (*check_gc)(Unit *u); + + /* Return true when this unit is suitable for snapshotting */ + bool (*check_snapshot)(Unit *u); + + void (*fd_event)(Unit *u, int fd, uint32_t events, Watch *w); + void (*sigchld_event)(Unit *u, pid_t pid, int code, int status); + void (*timer_event)(Unit *u, uint64_t n_elapsed, Watch *w); + + /* Reset failed state if we are in failed state */ + void (*reset_failed)(Unit *u); + + /* Called whenever any of the cgroups this unit watches for + * ran empty */ + void (*cgroup_notify_empty)(Unit *u); + + /* Called whenever a process of this unit sends us a message */ + void (*notify_message)(Unit *u, pid_t pid, char **tags); + + /* Called whenever a name thus 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); + + /* Called whenever a bus PID lookup finishes */ + void (*bus_query_pid_done)(Unit *u, const char *name, pid_t pid); + + /* Called for each message received on the bus */ + DBusHandlerResult (*bus_message_handler)(Unit *u, DBusConnection *c, DBusMessage *message); + + /* Return the unit this unit is following */ + Unit *(*following)(Unit *u); + + /* Return the set of units that are following each other */ + int (*following_set)(Unit *u, Set **s); + + /* Called whenever CLOCK_REALTIME made a jump */ + void (*time_change)(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 + * inactive state. It is the job of the coldplug() call above + * to put the units into the initial state. */ + int (*enumerate)(Manager *m); + + /* Type specific cleanups. */ + void (*shutdown)(Manager *m); + + /* When sending out PropertiesChanged signal, which properties + * shall be invalidated? This is a NUL separated list of + * strings, to minimize relocations a little. */ + const char *bus_invalidating_properties; + + /* The interface name */ + const char *bus_interface; + + UnitStatusMessageFormats status_message_formats; + + /* Can units of this type have multiple names? */ + bool no_alias:1; + + /* Instances make no sense for this type */ + bool no_instances:1; + + /* Exclude from automatic gc */ + bool no_gc:1; +}; + +extern const UnitVTable * const unit_vtable[_UNIT_TYPE_MAX]; + +#define UNIT_VTABLE(u) unit_vtable[(u)->type] + +/* For casting a unit into the various unit types */ +#define DEFINE_CAST(UPPERCASE, MixedCase) \ + static inline MixedCase* UPPERCASE(Unit *u) { \ + if (_unlikely_(!u || u->type != UNIT_##UPPERCASE)) \ + return NULL; \ + \ + return (MixedCase*) u; \ + } + +/* For casting the various unit types into a unit */ +#define UNIT(u) (&(u)->meta) + +DEFINE_CAST(SOCKET, Socket); +DEFINE_CAST(TIMER, Timer); +DEFINE_CAST(SERVICE, Service); +DEFINE_CAST(TARGET, Target); +DEFINE_CAST(DEVICE, Device); +DEFINE_CAST(MOUNT, Mount); +DEFINE_CAST(AUTOMOUNT, Automount); +DEFINE_CAST(SNAPSHOT, Snapshot); +DEFINE_CAST(SWAP, Swap); +DEFINE_CAST(PATH, Path); + +Unit *unit_new(Manager *m, size_t size); +void unit_free(Unit *u); + +int unit_add_name(Unit *u, const char *name); + +int unit_add_dependency(Unit *u, UnitDependency d, Unit *other, bool add_reference); +int unit_add_two_dependencies(Unit *u, UnitDependency d, UnitDependency e, Unit *other, bool add_reference); + +int unit_add_dependency_by_name(Unit *u, UnitDependency d, const char *name, const char *filename, bool add_reference); +int unit_add_two_dependencies_by_name(Unit *u, UnitDependency d, UnitDependency e, const char *name, const char *path, bool add_reference); + +int unit_add_dependency_by_name_inverse(Unit *u, UnitDependency d, const char *name, const char *filename, bool add_reference); +int unit_add_two_dependencies_by_name_inverse(Unit *u, UnitDependency d, UnitDependency e, const char *name, const char *path, bool add_reference); + +int unit_add_exec_dependencies(Unit *u, ExecContext *c); + +int unit_add_cgroup(Unit *u, CGroupBonding *b); +int unit_add_cgroup_from_text(Unit *u, const char *name); +int unit_add_default_cgroups(Unit *u); +CGroupBonding* unit_get_default_cgroup(Unit *u); +int unit_add_cgroup_attribute(Unit *u, const char *controller, const char *name, const char *value, CGroupAttributeMapCallback map_callback); + +int unit_choose_id(Unit *u, const char *name); +int unit_set_description(Unit *u, const char *description); + +bool unit_check_gc(Unit *u); + +void unit_add_to_load_queue(Unit *u); +void unit_add_to_dbus_queue(Unit *u); +void unit_add_to_cleanup_queue(Unit *u); +void unit_add_to_gc_queue(Unit *u); + +int unit_merge(Unit *u, Unit *other); +int unit_merge_by_name(Unit *u, const char *other); + +Unit *unit_follow_merge(Unit *u); + +int unit_load_fragment_and_dropin(Unit *u); +int unit_load_fragment_and_dropin_optional(Unit *u); +int unit_load(Unit *unit); + +const char *unit_description(Unit *u); + +bool unit_has_name(Unit *u, const char *name); + +UnitActiveState unit_active_state(Unit *u); + +const char* unit_sub_state_to_string(Unit *u); + +void unit_dump(Unit *u, FILE *f, const char *prefix); + +bool unit_can_reload(Unit *u); +bool unit_can_start(Unit *u); +bool unit_can_isolate(Unit *u); + +int unit_start(Unit *u); +int unit_stop(Unit *u); +int unit_reload(Unit *u); + +int unit_kill(Unit *u, KillWho w, int signo, DBusError *error); + +void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_success); + +int unit_watch_fd(Unit *u, int fd, uint32_t events, Watch *w); +void unit_unwatch_fd(Unit *u, Watch *w); + +int unit_watch_pid(Unit *u, pid_t pid); +void unit_unwatch_pid(Unit *u, pid_t pid); + +int unit_watch_timer(Unit *u, clockid_t, bool relative, usec_t usec, Watch *w); +void unit_unwatch_timer(Unit *u, Watch *w); + +int unit_watch_bus_name(Unit *u, const char *name); +void unit_unwatch_bus_name(Unit *u, const char *name); + +bool unit_job_is_applicable(Unit *u, JobType j); + +int set_unit_path(const char *p); + +char *unit_dbus_path(Unit *u); + +int unit_load_related_unit(Unit *u, const char *type, Unit **_found); +int unit_get_related_unit(Unit *u, const char *type, Unit **_found); + +bool unit_can_serialize(Unit *u); +int unit_serialize(Unit *u, FILE *f, FDSet *fds, bool serialize_jobs); +void unit_serialize_item_format(Unit *u, FILE *f, const char *key, const char *value, ...) _printf_attr_(4,5); +void unit_serialize_item(Unit *u, FILE *f, const char *key, const char *value); +int unit_deserialize(Unit *u, FILE *f, FDSet *fds); + +int unit_add_node_link(Unit *u, const char *what, bool wants); + +int unit_coldplug(Unit *u); + +void unit_status_printf(Unit *u, const char *status, const char *format, ...); + +bool unit_need_daemon_reload(Unit *u); + +void unit_reset_failed(Unit *u); + +Unit *unit_following(Unit *u); + +bool unit_pending_inactive(Unit *u); +bool unit_pending_active(Unit *u); + +int unit_add_default_target_dependency(Unit *u, Unit *target); + +char *unit_default_cgroup_path(Unit *u); + +int unit_following_set(Unit *u, Set **s); + +void unit_trigger_on_failure(Unit *u); + +bool unit_condition_test(Unit *u); + +UnitFileState unit_get_unit_file_state(Unit *u); + +Unit* unit_ref_set(UnitRef *ref, Unit *u); +void unit_ref_unset(UnitRef *ref); + +#define UNIT_DEREF(ref) ((ref).unit) + +int unit_add_one_mount_link(Unit *u, Mount *m); +int unit_add_mount_links(Unit *u); + +int unit_exec_context_defaults(Unit *u, ExecContext *c); + +ExecContext *unit_get_exec_context(Unit *u); + +const char *unit_active_state_to_string(UnitActiveState i); +UnitActiveState unit_active_state_from_string(const char *s); + +const char *unit_dependency_to_string(UnitDependency i); +UnitDependency unit_dependency_from_string(const char *s); + +#define log_full_unit(level, unit, ...) log_meta_object(level, __FILE__, __LINE__, __func__, "UNIT=", unit, __VA_ARGS__) +#define log_debug_unit(unit, ...) log_full_unit(LOG_DEBUG, unit, __VA_ARGS__) +#define log_info_unit(unit, ...) log_full_unit(LOG_INFO, unit, __VA_ARGS__) +#define log_notice_unit(unit, ...) log_full_unit(LOG_NOTICE, unit, __VA_ARGS__) +#define log_warning_unit(unit, ...) log_full_unit(LOG_WARNING, unit, __VA_ARGS__) +#define log_error_unit(unit, ...) log_full_unit(LOG_ERR, unit, __VA_ARGS__) diff --git a/src/core/user.conf b/src/core/user.conf new file mode 100644 index 000000000..e02b46bc3 --- /dev/null +++ b/src/core/user.conf @@ -0,0 +1,17 @@ +# This file is part of systemd. +# +# 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. +# +# See systemd.conf(5) for details + +[Manager] +#LogLevel=info +#LogTarget=console +#LogColor=yes +#LogLocation=no +#DefaultControllers=cpu +#DefaultStandardOutput=inherit +#DefaultStandardError=inherit diff --git a/src/cryptsetup/Makefile b/src/cryptsetup/Makefile new file mode 120000 index 000000000..d0b0e8e00 --- /dev/null +++ b/src/cryptsetup/Makefile @@ -0,0 +1 @@ +../Makefile \ No newline at end of file diff --git a/src/cryptsetup/cryptsetup-generator.c b/src/cryptsetup/cryptsetup-generator.c new file mode 100644 index 000000000..6e7b7070e --- /dev/null +++ b/src/cryptsetup/cryptsetup-generator.c @@ -0,0 +1,445 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include + +#include "log.h" +#include "util.h" +#include "unit-name.h" +#include "mkdir.h" +#include "virt.h" +#include "strv.h" + +static const char *arg_dest = "/tmp"; +static bool arg_enabled = true; +static bool arg_read_crypttab = true; +static char **arg_proc_cmdline_disks = NULL; + +static bool has_option(const char *haystack, const char *needle) { + const char *f = haystack; + size_t l; + + assert(needle); + + if (!haystack) + return false; + + l = strlen(needle); + + while ((f = strstr(f, needle))) { + + if (f > haystack && f[-1] != ',') { + f++; + continue; + } + + if (f[l] != 0 && f[l] != ',') { + f++; + continue; + } + + return true; + } + + return false; +} + +static int create_disk( + const char *name, + const char *device, + const char *password, + const char *options) { + + char *p = NULL, *n = NULL, *d = NULL, *u = NULL, *from = NULL, *to = NULL, *e = NULL; + int r; + FILE *f = NULL; + bool noauto, nofail; + + assert(name); + assert(device); + + noauto = has_option(options, "noauto"); + nofail = has_option(options, "nofail"); + + n = unit_name_from_path_instance("systemd-cryptsetup", name, ".service"); + if (!n) { + r = log_oom(); + goto fail; + } + + p = strjoin(arg_dest, "/", n, NULL); + if (!p) { + r = log_oom(); + goto fail; + } + + u = fstab_node_to_udev_node(device); + if (!u) { + r = log_oom(); + goto fail; + } + + d = unit_name_from_path(u, ".device"); + if (!d) { + r = log_oom(); + goto fail; + } + + f = fopen(p, "wxe"); + if (!f) { + r = -errno; + log_error("Failed to create unit file %s: %m", p); + goto fail; + } + + fprintf(f, + "# Automatically generated by systemd-cryptsetup-generator\n\n" + "[Unit]\n" + "Description=Cryptography Setup for %%I\n" + "Documentation=man:systemd-cryptsetup@.service(8) man:crypttab(5)\n" + "SourcePath=/etc/crypttab\n" + "Conflicts=umount.target\n" + "DefaultDependencies=no\n" + "BindsTo=%s dev-mapper-%%i.device\n" + "After=systemd-readahead-collect.service systemd-readahead-replay.service %s\n" + "Before=umount.target\n", + d, d); + + if (!nofail) + fprintf(f, + "Before=cryptsetup.target\n"); + + if (password && (streq(password, "/dev/urandom") || + streq(password, "/dev/random") || + streq(password, "/dev/hw_random"))) + fputs("After=systemd-random-seed-load.service\n", f); + else + fputs("Before=local-fs.target\n", f); + + fprintf(f, + "\n[Service]\n" + "Type=oneshot\n" + "RemainAfterExit=yes\n" + "TimeoutSec=0\n" /* the binary handles timeouts anyway */ + "ExecStart=" SYSTEMD_CRYPTSETUP_PATH " attach '%s' '%s' '%s' '%s'\n" + "ExecStop=" SYSTEMD_CRYPTSETUP_PATH " detach '%s'\n", + name, u, strempty(password), strempty(options), + name); + + if (has_option(options, "tmp")) + fprintf(f, + "ExecStartPost=/sbin/mke2fs '/dev/mapper/%s'\n", + name); + + if (has_option(options, "swap")) + fprintf(f, + "ExecStartPost=/sbin/mkswap '/dev/mapper/%s'\n", + name); + + fflush(f); + + if (ferror(f)) { + r = -errno; + log_error("Failed to write file %s: %m", p); + goto fail; + } + + if (asprintf(&from, "../%s", n) < 0) { + r = log_oom(); + goto fail; + } + + if (!noauto) { + + to = strjoin(arg_dest, "/", d, ".wants/", n, NULL); + if (!to) { + r = log_oom(); + goto fail; + } + + mkdir_parents_label(to, 0755); + if (symlink(from, to) < 0) { + log_error("Failed to create symlink '%s' to '%s': %m", from, to); + r = -errno; + goto fail; + } + + free(to); + + if (!nofail) + to = strjoin(arg_dest, "/cryptsetup.target.requires/", n, NULL); + else + to = strjoin(arg_dest, "/cryptsetup.target.wants/", n, NULL); + if (!to) { + r = log_oom(); + goto fail; + } + + mkdir_parents_label(to, 0755); + if (symlink(from, to) < 0) { + log_error("Failed to create symlink '%s' to '%s': %m", from, to); + r = -errno; + goto fail; + } + + free(to); + to = NULL; + } + + e = unit_name_escape(name); + to = strjoin(arg_dest, "/dev-mapper-", e, ".device.requires/", n, NULL); + if (!to) { + r = log_oom(); + goto fail; + } + + mkdir_parents_label(to, 0755); + if (symlink(from, to) < 0) { + log_error("Failed to create symlink '%s' to '%s': %m", from, to); + r = -errno; + goto fail; + } + + r = 0; + +fail: + free(p); + free(n); + free(d); + free(e); + + free(from); + free(to); + + if (f) + fclose(f); + + return r; +} + +static int parse_proc_cmdline(void) { + char *line, *w, *state; + int r; + size_t l; + + if (detect_container(NULL) > 0) + return 0; + + r = read_one_line_file("/proc/cmdline", &line); + if (r < 0) { + log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r)); + return 0; + } + + FOREACH_WORD_QUOTED(w, l, line, state) { + char *word; + + word = strndup(w, l); + if (!word) { + r = log_oom(); + goto finish; + } + + if (startswith(word, "luks=")) { + r = parse_boolean(word + 5); + if (r < 0) + log_warning("Failed to parse luks switch %s. Ignoring.", word + 5); + else + arg_enabled = r; + + } else if (startswith(word, "rd.luks=")) { + + if (in_initrd()) { + r = parse_boolean(word + 8); + if (r < 0) + log_warning("Failed to parse luks switch %s. Ignoring.", word + 8); + else + arg_enabled = r; + } + + } else if (startswith(word, "luks.crypttab=")) { + r = parse_boolean(word + 14); + if (r < 0) + log_warning("Failed to parse luks crypttab switch %s. Ignoring.", word + 14); + else + arg_read_crypttab = r; + + } else if (startswith(word, "rd.luks.crypttab=")) { + + if (in_initrd()) { + r = parse_boolean(word + 17); + if (r < 0) + log_warning("Failed to parse luks crypttab switch %s. Ignoring.", word + 17); + else + arg_read_crypttab = r; + } + + } else if (startswith(word, "luks.uuid=")) { + char **t; + + t = strv_append(arg_proc_cmdline_disks, word + 10); + if (!t) { + r = log_oom(); + goto finish; + } + strv_free(arg_proc_cmdline_disks); + arg_proc_cmdline_disks = t; + + } else if (startswith(word, "rd.luks.uuid=")) { + + if (in_initrd()) { + char **t; + + t = strv_append(arg_proc_cmdline_disks, word + 13); + if (!t) { + r = log_oom(); + goto finish; + } + strv_free(arg_proc_cmdline_disks); + arg_proc_cmdline_disks = t; + } + + } else if (startswith(word, "luks.") || + (in_initrd() && startswith(word, "rd.luks."))) { + + log_warning("Unknown kernel switch %s. Ignoring.", word); + } + + free(word); + } + + r = 0; + +finish: + free(line); + return r; +} + +int main(int argc, char *argv[]) { + FILE *f = NULL; + int r = EXIT_SUCCESS; + unsigned n = 0; + char **i; + + if (argc > 1 && argc != 4) { + log_error("This program takes three or no arguments."); + return EXIT_FAILURE; + } + + if (argc > 1) + arg_dest = argv[1]; + + log_set_target(LOG_TARGET_SAFE); + log_parse_environment(); + log_open(); + + umask(0022); + + if (parse_proc_cmdline() < 0) + return EXIT_FAILURE; + + if (!arg_enabled) { + r = EXIT_SUCCESS; + goto finish; + } + + STRV_FOREACH(i, arg_proc_cmdline_disks) { + char *name, *device; + const char *p = *i; + + if (startswith(p, "luks-")) + p += 5; + + name = strappend("luks-", p); + device = strappend("UUID=", p); + + if (!name || !device) { + log_oom(); + r = EXIT_FAILURE; + free(name); + free(device); + goto finish; + } + + if (create_disk(name, device, NULL, NULL) < 0) + r = EXIT_FAILURE; + + free(name); + free(device); + } + + if (!arg_read_crypttab) + return r; + + f = fopen("/etc/crypttab", "re"); + if (!f) { + + if (errno == ENOENT) + r = EXIT_SUCCESS; + else { + r = EXIT_FAILURE; + log_error("Failed to open /etc/crypttab: %m"); + } + + goto finish; + } + + for (;;) { + char line[LINE_MAX], *l; + char *name = NULL, *device = NULL, *password = NULL, *options = NULL; + int k; + + if (!fgets(line, sizeof(line), f)) + break; + + n++; + + l = strstrip(line); + if (*l == '#' || *l == 0) + continue; + + k = sscanf(l, "%ms %ms %ms %ms", &name, &device, &password, &options); + if (k < 2 || k > 4) { + log_error("Failed to parse /etc/crypttab:%u, ignoring.", n); + r = EXIT_FAILURE; + goto next; + } + + if (create_disk(name, device, password, options) < 0) + r = EXIT_FAILURE; + + next: + free(name); + free(device); + free(password); + free(options); + } + +finish: + if (f) + fclose(f); + + strv_free(arg_proc_cmdline_disks); + + return r; +} diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c new file mode 100644 index 000000000..f33284370 --- /dev/null +++ b/src/cryptsetup/cryptsetup.c @@ -0,0 +1,560 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include + +#include +#include + +#include "log.h" +#include "util.h" +#include "path-util.h" +#include "strv.h" +#include "ask-password-api.h" +#include "def.h" + +static const char *opt_type = NULL; /* LUKS1 or PLAIN */ +static char *opt_cipher = NULL; +static unsigned opt_key_size = 0; +static unsigned opt_keyfile_size = 0; +static unsigned opt_keyfile_offset = 0; +static char *opt_hash = NULL; +static unsigned opt_tries = 0; +static bool opt_readonly = false; +static bool opt_verify = false; +static bool opt_discards = false; +static usec_t opt_timeout = DEFAULT_TIMEOUT_USEC; + +/* Options Debian's crypttab knows we don't: + + offset= + skip= + precheck= + check= + checkargs= + noearly= + loud= + keyscript= +*/ + +static int parse_one_option(const char *option) { + assert(option); + + /* Handled outside of this tool */ + if (streq(option, "noauto") || streq(option, "nofail")) + return 0; + + if (startswith(option, "cipher=")) { + char *t; + + if (!(t = strdup(option+7))) + return -ENOMEM; + + free(opt_cipher); + opt_cipher = t; + + } else if (startswith(option, "size=")) { + + if (safe_atou(option+5, &opt_key_size) < 0) { + log_error("size= parse failure, ignoring."); + return 0; + } + + } else if (startswith(option, "keyfile-size=")) { + + if (safe_atou(option+13, &opt_keyfile_size) < 0) { + log_error("keyfile-size= parse failure, ignoring."); + return 0; + } + + } else if (startswith(option, "keyfile-offset=")) { + + if (safe_atou(option+15, &opt_keyfile_offset) < 0) { + log_error("keyfile-offset= parse failure, ignoring."); + return 0; + } + + } else if (startswith(option, "hash=")) { + char *t; + + if (!(t = strdup(option+5))) + return -ENOMEM; + + free(opt_hash); + opt_hash = t; + + } else if (startswith(option, "tries=")) { + + if (safe_atou(option+6, &opt_tries) < 0) { + log_error("tries= parse failure, ignoring."); + return 0; + } + + } else if (streq(option, "readonly")) + opt_readonly = true; + else if (streq(option, "verify")) + opt_verify = true; + else if (streq(option, "allow-discards")) + opt_discards = true; + else if (streq(option, "luks")) + opt_type = CRYPT_LUKS1; + else if (streq(option, "plain") || + streq(option, "swap") || + streq(option, "tmp")) + opt_type = CRYPT_PLAIN; + else if (startswith(option, "timeout=")) { + + if (parse_usec(option+8, &opt_timeout) < 0) { + log_error("timeout= parse failure, ignoring."); + return 0; + } + + } else if (!streq(option, "none")) + log_error("Encountered unknown /etc/crypttab option '%s', ignoring.", option); + + return 0; +} + +static int parse_options(const char *options) { + char *state; + char *w; + size_t l; + + assert(options); + + FOREACH_WORD_SEPARATOR(w, l, options, ",", state) { + char *o; + int r; + + if (!(o = strndup(w, l))) + return -ENOMEM; + + r = parse_one_option(o); + free(o); + + if (r < 0) + return r; + } + + return 0; +} + +static void log_glue(int level, const char *msg, void *usrptr) { + log_debug("%s", msg); +} + +static char *disk_description(const char *path) { + struct udev *udev = NULL; + struct udev_device *device = NULL; + struct stat st; + char *description = NULL; + const char *model; + + assert(path); + + if (stat(path, &st) < 0) + return NULL; + + if (!S_ISBLK(st.st_mode)) + return NULL; + + if (!(udev = udev_new())) + return NULL; + + if (!(device = udev_device_new_from_devnum(udev, 'b', st.st_rdev))) + goto finish; + + if ((model = udev_device_get_property_value(device, "ID_MODEL_FROM_DATABASE")) || + (model = udev_device_get_property_value(device, "ID_MODEL")) || + (model = udev_device_get_property_value(device, "DM_NAME"))) + description = strdup(model); + +finish: + if (device) + udev_device_unref(device); + + if (udev) + udev_unref(udev); + + return description; +} + +static char *disk_mount_point(const char *label) { + char *mp = NULL, *device = NULL; + FILE *f = NULL; + struct mntent *m; + + /* Yeah, we don't support native systemd unit files here for now */ + + if (asprintf(&device, "/dev/mapper/%s", label) < 0) + goto finish; + + f = setmntent("/etc/fstab", "r"); + if (!f) + goto finish; + + while ((m = getmntent(f))) + if (path_equal(m->mnt_fsname, device)) { + mp = strdup(m->mnt_dir); + break; + } + +finish: + if (f) + endmntent(f); + + free(device); + + return mp; +} + +static int help(void) { + + printf("%s attach VOLUME SOURCEDEVICE [PASSWORD] [OPTIONS]\n" + "%s detach VOLUME\n\n" + "Attaches or detaches an encrypted block device.\n", + program_invocation_short_name, + program_invocation_short_name); + + return 0; +} + +int main(int argc, char *argv[]) { + int r = EXIT_FAILURE; + struct crypt_device *cd = NULL; + char **passwords = NULL, *truncated_cipher = NULL; + const char *cipher = NULL, *cipher_mode = NULL, *hash = NULL, *name = NULL; + char *description = NULL, *name_buffer = NULL, *mount_point = NULL; + + if (argc <= 1) { + help(); + return EXIT_SUCCESS; + } + + if (argc < 3) { + log_error("This program requires at least two arguments."); + return EXIT_FAILURE; + } + + log_set_target(LOG_TARGET_AUTO); + log_parse_environment(); + log_open(); + + umask(0022); + + if (streq(argv[1], "attach")) { + uint32_t flags = 0; + int k; + unsigned try; + const char *key_file = NULL; + usec_t until; + crypt_status_info status; + + /* Arguments: systemd-cryptsetup attach VOLUME SOURCE-DEVICE [PASSWORD] [OPTIONS] */ + + if (argc < 4) { + log_error("attach requires at least two arguments."); + goto finish; + } + + if (argc >= 5 && + argv[4][0] && + !streq(argv[4], "-") && + !streq(argv[4], "none")) { + + if (!path_is_absolute(argv[4])) + log_error("Password file path %s is not absolute. Ignoring.", argv[4]); + else + key_file = argv[4]; + } + + if (argc >= 6 && argv[5][0] && !streq(argv[5], "-")) + parse_options(argv[5]); + + /* A delicious drop of snake oil */ + mlockall(MCL_FUTURE); + + description = disk_description(argv[3]); + mount_point = disk_mount_point(argv[2]); + + if (description && streq(argv[2], description)) { + /* If the description string is simply the + * volume name, then let's not show this + * twice */ + free(description); + description = NULL; + } + + if (mount_point && description) + asprintf(&name_buffer, "%s (%s) on %s", description, argv[2], mount_point); + else if (mount_point) + asprintf(&name_buffer, "%s on %s", argv[2], mount_point); + else if (description) + asprintf(&name_buffer, "%s (%s)", description, argv[2]); + + name = name_buffer ? name_buffer : argv[2]; + + if ((k = crypt_init(&cd, argv[3]))) { + log_error("crypt_init() failed: %s", strerror(-k)); + goto finish; + } + + crypt_set_log_callback(cd, log_glue, NULL); + + status = crypt_status(cd, argv[2]); + if (status == CRYPT_ACTIVE || status == CRYPT_BUSY) { + log_info("Volume %s already active.", argv[2]); + r = EXIT_SUCCESS; + goto finish; + } + + if (opt_readonly) + flags |= CRYPT_ACTIVATE_READONLY; + + if (opt_discards) + flags |= CRYPT_ACTIVATE_ALLOW_DISCARDS; + + if (opt_timeout > 0) + until = now(CLOCK_MONOTONIC) + opt_timeout; + else + until = 0; + + opt_tries = opt_tries > 0 ? opt_tries : 3; + opt_key_size = (opt_key_size > 0 ? opt_key_size : 256); + if (opt_hash) { + /* plain isn't a real hash type. it just means "use no hash" */ + if (!streq(opt_hash, "plain")) + hash = opt_hash; + } else + hash = "ripemd160"; + + if (opt_cipher) { + size_t l; + + l = strcspn(opt_cipher, "-"); + + if (!(truncated_cipher = strndup(opt_cipher, l))) { + log_oom(); + goto finish; + } + + cipher = truncated_cipher; + cipher_mode = opt_cipher[l] ? opt_cipher+l+1 : "plain"; + } else { + cipher = "aes"; + cipher_mode = "cbc-essiv:sha256"; + } + + for (try = 0; try < opt_tries; try++) { + bool pass_volume_key = false; + + strv_free(passwords); + passwords = NULL; + + if (!key_file) { + char *text; + char **p; + + if (asprintf(&text, "Please enter passphrase for disk %s!", name) < 0) { + log_oom(); + goto finish; + } + + k = ask_password_auto(text, "drive-harddisk", until, try == 0 && !opt_verify, &passwords); + free(text); + + if (k < 0) { + log_error("Failed to query password: %s", strerror(-k)); + goto finish; + } + + if (opt_verify) { + char **passwords2 = NULL; + + assert(strv_length(passwords) == 1); + + if (asprintf(&text, "Please enter passphrase for disk %s! (verification)", name) < 0) { + log_oom(); + goto finish; + } + + k = ask_password_auto(text, "drive-harddisk", until, false, &passwords2); + free(text); + + if (k < 0) { + log_error("Failed to query verification password: %s", strerror(-k)); + goto finish; + } + + assert(strv_length(passwords2) == 1); + + if (!streq(passwords[0], passwords2[0])) { + log_warning("Passwords did not match, retrying."); + strv_free(passwords2); + continue; + } + + strv_free(passwords2); + } + + strv_uniq(passwords); + + STRV_FOREACH(p, passwords) { + char *c; + + if (strlen(*p)+1 >= opt_key_size) + continue; + + /* Pad password if necessary */ + if (!(c = new(char, opt_key_size))) { + log_oom(); + goto finish; + } + + strncpy(c, *p, opt_key_size); + free(*p); + *p = c; + } + } + + k = 0; + + if (!opt_type || streq(opt_type, CRYPT_LUKS1)) + k = crypt_load(cd, CRYPT_LUKS1, NULL); + + if ((!opt_type && k < 0) || streq_ptr(opt_type, CRYPT_PLAIN)) { + struct crypt_params_plain params; + + zero(params); + params.hash = hash; + + /* for CRYPT_PLAIN limit reads + * from keyfile to key length, and + * ignore keyfile-size */ + opt_keyfile_size = opt_key_size / 8; + + /* In contrast to what the name + * crypt_setup() might suggest this + * doesn't actually format anything, + * it just configures encryption + * parameters when used for plain + * mode. */ + k = crypt_format(cd, CRYPT_PLAIN, + cipher, + cipher_mode, + NULL, + NULL, + opt_keyfile_size, + ¶ms); + + /* hash == NULL implies the user passed "plain" */ + pass_volume_key = (hash == NULL); + } + + if (k < 0) { + log_error("Loading of cryptographic parameters failed: %s", strerror(-k)); + goto finish; + } + + log_info("Set cipher %s, mode %s, key size %i bits for device %s.", + crypt_get_cipher(cd), + crypt_get_cipher_mode(cd), + crypt_get_volume_key_size(cd)*8, + argv[3]); + + if (key_file) + k = crypt_activate_by_keyfile_offset(cd, argv[2], CRYPT_ANY_SLOT, key_file, opt_keyfile_size, + opt_keyfile_offset, flags); + else { + char **p; + + STRV_FOREACH(p, passwords) { + + if (pass_volume_key) + k = crypt_activate_by_volume_key(cd, argv[2], *p, opt_key_size, flags); + else + k = crypt_activate_by_passphrase(cd, argv[2], CRYPT_ANY_SLOT, *p, strlen(*p), flags); + + if (k >= 0) + break; + } + } + + if (k >= 0) + break; + + if (k != -EPERM) { + log_error("Failed to activate: %s", strerror(-k)); + goto finish; + } + + log_warning("Invalid passphrase."); + } + + if (try >= opt_tries) { + log_error("Too many attempts."); + r = EXIT_FAILURE; + goto finish; + } + + } else if (streq(argv[1], "detach")) { + int k; + + if ((k = crypt_init_by_name(&cd, argv[2]))) { + log_error("crypt_init() failed: %s", strerror(-k)); + goto finish; + } + + crypt_set_log_callback(cd, log_glue, NULL); + + if ((k = crypt_deactivate(cd, argv[2])) < 0) { + log_error("Failed to deactivate: %s", strerror(-k)); + goto finish; + } + + } else { + log_error("Unknown verb %s.", argv[1]); + goto finish; + } + + r = EXIT_SUCCESS; + +finish: + + if (cd) + crypt_free(cd); + + free(opt_cipher); + free(opt_hash); + + free(truncated_cipher); + + strv_free(passwords); + + free(description); + free(mount_point); + free(name_buffer); + + return r; +} diff --git a/src/delta/Makefile b/src/delta/Makefile new file mode 120000 index 000000000..d0b0e8e00 --- /dev/null +++ b/src/delta/Makefile @@ -0,0 +1 @@ +../Makefile \ No newline at end of file diff --git a/src/delta/delta.c b/src/delta/delta.c new file mode 100644 index 000000000..9f2093851 --- /dev/null +++ b/src/delta/delta.c @@ -0,0 +1,489 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + +#include +#include +#include +#include +#include + +#include "hashmap.h" +#include "util.h" +#include "path-util.h" +#include "log.h" +#include "pager.h" +#include "build.h" + +static bool arg_no_pager = false; +static int arg_diff = -1; + +static enum { + SHOW_MASKED = 1 << 0, + SHOW_EQUIVALENT = 1 << 1, + SHOW_REDIRECTED = 1 << 2, + SHOW_OVERRIDDEN = 1 << 3, + SHOW_UNCHANGED = 1 << 4, + + SHOW_DEFAULTS = + (SHOW_MASKED | SHOW_EQUIVALENT | SHOW_REDIRECTED | SHOW_OVERRIDDEN) +} arg_flags = 0; + +static int equivalent(const char *a, const char *b) { + _cleanup_free_ char *x = NULL, *y = NULL; + + x = canonicalize_file_name(a); + if (!x) + return -errno; + + y = canonicalize_file_name(b); + if (!y) + return -errno; + + return path_equal(x, y); +} + +static int notify_override_masked(const char *top, const char *bottom) { + if (!(arg_flags & SHOW_MASKED)) + return 0; + + printf(ANSI_HIGHLIGHT_RED_ON "[MASKED]" ANSI_HIGHLIGHT_OFF " %s → %s\n", top, bottom); + return 1; +} + +static int notify_override_equivalent(const char *top, const char *bottom) { + if (!(arg_flags & SHOW_EQUIVALENT)) + return 0; + + printf(ANSI_HIGHLIGHT_GREEN_ON "[EQUIVALENT]" ANSI_HIGHLIGHT_OFF " %s → %s\n", top, bottom); + return 1; +} + +static int notify_override_redirected(const char *top, const char *bottom) { + if (!(arg_flags & SHOW_REDIRECTED)) + return 0; + + printf(ANSI_HIGHLIGHT_ON "[REDIRECTED]" ANSI_HIGHLIGHT_OFF " %s → %s\n", top, bottom); + return 1; +} + +static int notify_override_overridden(const char *top, const char *bottom) { + if (!(arg_flags & SHOW_OVERRIDDEN)) + return 0; + + printf(ANSI_HIGHLIGHT_ON "[OVERRIDDEN]" ANSI_HIGHLIGHT_OFF " %s → %s\n", top, bottom); + return 1; +} + +static int notify_override_unchanged(const char *f) { + if (!(arg_flags & SHOW_UNCHANGED)) + return 0; + + printf("[UNCHANGED] %s\n", f); + return 1; +} + +static int found_override(const char *top, const char *bottom) { + _cleanup_free_ char *dest = NULL; + int k; + pid_t pid; + + assert(top); + assert(bottom); + + if (null_or_empty_path(top) > 0) { + notify_override_masked(top, bottom); + return 0; + } + + k = readlink_malloc(top, &dest); + if (k >= 0) { + if (equivalent(dest, bottom) > 0) + notify_override_equivalent(top, bottom); + else + notify_override_redirected(top, bottom); + + return 0; + } + + notify_override_overridden(top, bottom); + if (!arg_diff) + return 0; + + putchar('\n'); + + fflush(stdout); + + pid = fork(); + if (pid < 0) { + log_error("Failed to fork off diff: %m"); + return -errno; + } else if (pid == 0) { + execlp("diff", "diff", "-us", "--", bottom, top, NULL); + log_error("Failed to execute diff: %m"); + _exit(1); + } + + wait_for_terminate(pid, NULL); + + putchar('\n'); + + return 0; +} + +static int enumerate_dir(Hashmap *top, Hashmap *bottom, const char *path) { + _cleanup_closedir_ DIR *d; + + assert(top); + assert(bottom); + assert(path); + + d = opendir(path); + if (!d) { + if (errno == ENOENT) + return 0; + + log_error("Failed to enumerate %s: %m", path); + return -errno; + } + + for (;;) { + struct dirent *de; + union dirent_storage buf; + int k; + char *p; + + k = readdir_r(d, &buf.de, &de); + if (k != 0) + return -k; + + if (!de) + break; + + if (!dirent_is_file(de)) + continue; + + p = strjoin(path, "/", de->d_name, NULL); + if (!p) + return -ENOMEM; + + path_kill_slashes(p); + + k = hashmap_put(top, path_get_file_name(p), p); + if (k >= 0) { + p = strdup(p); + if (!p) + return -ENOMEM; + } else if (k != -EEXIST) { + free(p); + return k; + } + + free(hashmap_remove(bottom, path_get_file_name(p))); + k = hashmap_put(bottom, path_get_file_name(p), p); + if (k < 0) { + free(p); + return k; + } + } + + return 0; +} + +static int process_suffix(const char *prefixes, const char *suffix) { + const char *p; + char *f; + Hashmap *top, *bottom=NULL; + int r = 0, k; + Iterator i; + int n_found = 0; + + assert(prefixes); + assert(suffix); + + top = hashmap_new(string_hash_func, string_compare_func); + if (!top) { + r = -ENOMEM; + goto finish; + } + + bottom = hashmap_new(string_hash_func, string_compare_func); + if (!bottom) { + r = -ENOMEM; + goto finish; + } + + NULSTR_FOREACH(p, prefixes) { + _cleanup_free_ char *t = NULL; + + t = strjoin(p, "/", suffix, NULL); + if (!t) { + r = -ENOMEM; + goto finish; + } + + k = enumerate_dir(top, bottom, t); + if (k < 0) + r = k; + + log_debug("Looking at %s", t); + } + + HASHMAP_FOREACH(f, top, i) { + char *o; + + o = hashmap_get(bottom, path_get_file_name(f)); + assert(o); + + if (path_equal(o, f)) { + notify_override_unchanged(f); + continue; + } + + k = found_override(f, o); + if (k < 0) + r = k; + + n_found ++; + } + +finish: + if (top) + hashmap_free_free(top); + if (bottom) + hashmap_free_free(bottom); + + return r < 0 ? r : n_found; +} + +static int process_suffix_chop(const char *prefixes, const char *suffix) { + const char *p; + + assert(prefixes); + assert(suffix); + + if (!path_is_absolute(suffix)) + return process_suffix(prefixes, suffix); + + /* Strip prefix from the suffix */ + NULSTR_FOREACH(p, prefixes) { + if (startswith(suffix, p)) { + suffix += strlen(p); + suffix += strspn(suffix, "/"); + return process_suffix(prefixes, suffix); + } + } + + log_error("Invalid suffix specification %s.", suffix); + return -EINVAL; +} + +static void help(void) { + + printf("%s [OPTIONS...] [SUFFIX...]\n\n" + "Find overridden configuration files.\n\n" + " -h --help Show this help\n" + " --version Show package version\n" + " --no-pager Do not pipe output into a pager\n" + " --diff[=1|0] Show a diff when overridden files differ\n" + " -t --type=LIST... Only display a selected set of override types\n", + program_invocation_short_name); +} + +static int parse_flags(const char *flag_str, int flags) { + char *w, *state; + size_t l; + + FOREACH_WORD(w, l, flag_str, state) { + if (strncmp("masked", w, l) == 0) + flags |= SHOW_MASKED; + else if (strncmp ("equivalent", w, l) == 0) + flags |= SHOW_EQUIVALENT; + else if (strncmp("redirected", w, l) == 0) + flags |= SHOW_REDIRECTED; + else if (strncmp("overridden", w, l) == 0) + flags |= SHOW_OVERRIDDEN; + else if (strncmp("unchanged", w, l) == 0) + flags |= SHOW_UNCHANGED; + else if (strncmp("default", w, l) == 0) + flags |= SHOW_DEFAULTS; + else + return -EINVAL; + } + return flags; +} + +static int parse_argv(int argc, char *argv[]) { + + enum { + ARG_NO_PAGER = 0x100, + ARG_DIFF, + ARG_VERSION + }; + + static const struct option options[] = { + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, ARG_VERSION }, + { "no-pager", no_argument, NULL, ARG_NO_PAGER }, + { "diff", optional_argument, NULL, ARG_DIFF }, + { "type", required_argument, NULL, 't' }, + { NULL, 0, NULL, 0 } + }; + + int c; + + assert(argc >= 1); + assert(argv); + + while ((c = getopt_long(argc, argv, "ht:", options, NULL)) >= 0) { + + switch (c) { + + case 'h': + help(); + return 0; + + case ARG_VERSION: + puts(PACKAGE_STRING); + puts(SYSTEMD_FEATURES); + return 0; + + case ARG_NO_PAGER: + arg_no_pager = true; + break; + + case '?': + return -EINVAL; + + case 't': { + int f; + f = parse_flags(optarg, arg_flags); + if (f < 0) { + log_error("Failed to parse flags field."); + return -EINVAL; + } + arg_flags = f; + break; + } + + case ARG_DIFF: + if (!optarg) + arg_diff = 1; + else { + int b; + + b = parse_boolean(optarg); + if (b < 0) { + log_error("Failed to parse diff boolean."); + return -EINVAL; + } else if (b) + arg_diff = 1; + else + arg_diff = 0; + } + break; + + default: + log_error("Unknown option code %c", c); + return -EINVAL; + } + } + + return 1; +} + +int main(int argc, char *argv[]) { + + const char prefixes[] = + "/etc\0" + "/run\0" + "/usr/local/lib\0" + "/usr/local/share\0" + "/usr/lib\0" + "/usr/share\0" +#ifdef HAVE_SPLIT_USR + "/lib\0" +#endif + ; + + const char suffixes[] = + "sysctl.d\0" + "tmpfiles.d\0" + "modules-load.d\0" + "binfmt.d\0" + "systemd/system\0" + "systemd/user\0" + "systemd/system-preset\0" + "systemd/user-preset\0" + "udev/rules.d\0" + "modprobe.d\0"; + + int r = 0, k; + int n_found = 0; + + log_parse_environment(); + log_open(); + + r = parse_argv(argc, argv); + if (r <= 0) + goto finish; + + if (arg_flags == 0) + arg_flags = SHOW_DEFAULTS; + + if (arg_diff < 0) + arg_diff = !!(arg_flags & SHOW_OVERRIDDEN); + else if (arg_diff) + arg_flags |= SHOW_OVERRIDDEN; + + if (!arg_no_pager) + pager_open(); + + if (optind < argc) { + int i; + + for (i = optind; i < argc; i++) { + k = process_suffix_chop(prefixes, argv[i]); + if (k < 0) + r = k; + else + n_found += k; + } + + } else { + const char *n; + + NULSTR_FOREACH(n, suffixes) { + k = process_suffix(prefixes, n); + if (k < 0) + r = k; + else + n_found += k; + } + } + + if (r >= 0) + printf("\n%i overridden configuration files found.\n", n_found); + +finish: + pager_close(); + + return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/src/detect-virt/Makefile b/src/detect-virt/Makefile new file mode 120000 index 000000000..d0b0e8e00 --- /dev/null +++ b/src/detect-virt/Makefile @@ -0,0 +1 @@ +../Makefile \ No newline at end of file diff --git a/src/detect-virt/detect-virt.c b/src/detect-virt/detect-virt.c new file mode 100644 index 000000000..bd3ee452c --- /dev/null +++ b/src/detect-virt/detect-virt.c @@ -0,0 +1,171 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include +#include + +#include "util.h" +#include "virt.h" +#include "build.h" + +static bool arg_quiet = false; +static enum { + ANY_VIRTUALIZATION, + ONLY_VM, + ONLY_CONTAINER +} arg_mode = ANY_VIRTUALIZATION; + +static int help(void) { + + printf("%s [OPTIONS...]\n\n" + "Detect execution in a virtualized environment.\n\n" + " -h --help Show this help\n" + " --version Show package version\n" + " -c --container Only detect whether we are run in a container\n" + " -v --vm Only detect whether we are run in a VM\n" + " -q --quiet Don't output anything, just set return value\n", + program_invocation_short_name); + + return 0; +} + +static int parse_argv(int argc, char *argv[]) { + + enum { + ARG_VERSION = 0x100 + }; + + static const struct option options[] = { + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, ARG_VERSION }, + { "container", no_argument, NULL, 'c' }, + { "vm", optional_argument, NULL, 'v' }, + { "quiet", no_argument, NULL, 'q' }, + { NULL, 0, NULL, 0 } + }; + + int c; + + assert(argc >= 0); + assert(argv); + + while ((c = getopt_long(argc, argv, "hqcv", options, NULL)) >= 0) { + + switch (c) { + + case 'h': + help(); + return 0; + + case ARG_VERSION: + puts(PACKAGE_STRING); + puts(SYSTEMD_FEATURES); + return 0; + + case 'q': + arg_quiet = true; + break; + + case 'c': + arg_mode = ONLY_CONTAINER; + break; + + case 'v': + arg_mode = ONLY_VM; + break; + + case '?': + return -EINVAL; + + default: + log_error("Unknown option code %c", c); + return -EINVAL; + } + } + + if (optind < argc) { + help(); + return -EINVAL; + } + + return 1; +} + +int main(int argc, char *argv[]) { + const char *id = NULL; + int r; + int retval = EXIT_SUCCESS; + + /* This is mostly intended to be used for scripts which want + * to detect whether we are being run in a virtualized + * environment or not */ + + log_parse_environment(); + log_open(); + + r = parse_argv(argc, argv); + if (r <= 0) + return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; + + switch (arg_mode) { + + case ANY_VIRTUALIZATION: { + Virtualization v; + + v = detect_virtualization(&id); + if (v < 0) { + log_error("Failed to check for virtualization: %s", strerror(-v)); + return EXIT_FAILURE; + } + + retval = v != VIRTUALIZATION_NONE ? EXIT_SUCCESS : EXIT_FAILURE; + break; + } + + case ONLY_CONTAINER: + r = detect_container(&id); + if (r < 0) { + log_error("Failed to check for container: %s", strerror(-r)); + return EXIT_FAILURE; + } + + retval = r > 0 ? EXIT_SUCCESS : EXIT_FAILURE; + break; + + case ONLY_VM: + r = detect_vm(&id); + if (r < 0) { + log_error("Failed to check for vm: %s", strerror(-r)); + return EXIT_FAILURE; + } + + retval = r > 0 ? EXIT_SUCCESS : EXIT_FAILURE; + break; + } + + if (!arg_quiet) + puts(id ? id : "none"); + + return retval; +} diff --git a/src/fsck/Makefile b/src/fsck/Makefile new file mode 120000 index 000000000..d0b0e8e00 --- /dev/null +++ b/src/fsck/Makefile @@ -0,0 +1 @@ +../Makefile \ No newline at end of file diff --git a/src/fsck/fsck.c b/src/fsck/fsck.c new file mode 100644 index 000000000..f5d38ad26 --- /dev/null +++ b/src/fsck/fsck.c @@ -0,0 +1,416 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "util.h" +#include "dbus-common.h" +#include "special.h" +#include "bus-errors.h" +#include "virt.h" + +static bool arg_skip = false; +static bool arg_force = false; +static bool arg_show_progress = false; + +static void start_target(const char *target, bool isolate) { + DBusMessage *m = NULL, *reply = NULL; + DBusError error; + const char *mode, *basic_target = "basic.target"; + DBusConnection *bus = NULL; + + assert(target); + + dbus_error_init(&error); + + if (bus_connect(DBUS_BUS_SYSTEM, &bus, NULL, &error) < 0) { + log_error("Failed to get D-Bus connection: %s", bus_error_message(&error)); + goto finish; + } + + if (isolate) + mode = "isolate"; + else + mode = "replace"; + + log_info("Running request %s/start/%s", target, mode); + + if (!(m = dbus_message_new_method_call("org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "StartUnitReplace"))) { + log_error("Could not allocate message."); + goto finish; + } + + /* Start these units only if we can replace base.target with it */ + + if (!dbus_message_append_args(m, + DBUS_TYPE_STRING, &basic_target, + DBUS_TYPE_STRING, &target, + DBUS_TYPE_STRING, &mode, + DBUS_TYPE_INVALID)) { + log_error("Could not attach target and flag information to message."); + goto finish; + } + + if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) { + + /* Don't print a warning if we aren't called during + * startup */ + if (!dbus_error_has_name(&error, BUS_ERROR_NO_SUCH_JOB)) + log_error("Failed to start unit: %s", bus_error_message(&error)); + + goto finish; + } + +finish: + if (m) + dbus_message_unref(m); + + if (reply) + dbus_message_unref(reply); + + if (bus) { + dbus_connection_flush(bus); + dbus_connection_close(bus); + dbus_connection_unref(bus); + } + + dbus_error_free(&error); +} + +static int parse_proc_cmdline(void) { + char *line, *w, *state; + int r; + size_t l; + + if (detect_container(NULL) > 0) + return 0; + + r = read_one_line_file("/proc/cmdline", &line); + if (r < 0) { + log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r)); + return 0; + } + + FOREACH_WORD_QUOTED(w, l, line, state) { + + if (strneq(w, "fsck.mode=auto", l)) + arg_force = arg_skip = false; + else if (strneq(w, "fsck.mode=force", l)) + arg_force = true; + else if (strneq(w, "fsck.mode=skip", l)) + arg_skip = true; + else if (startswith(w, "fsck")) + log_warning("Invalid fsck parameter. Ignoring."); +#ifdef HAVE_SYSV_COMPAT + else if (strneq(w, "fastboot", l)) { + log_error("Please pass 'fsck.mode=skip' rather than 'fastboot' on the kernel command line."); + arg_skip = true; + } else if (strneq(w, "forcefsck", l)) { + log_error("Please pass 'fsck.mode=force' rather than 'forcefsck' on the kernel command line."); + arg_force = true; + } +#endif + } + + free(line); + return 0; +} + +static void test_files(void) { +#ifdef HAVE_SYSV_COMPAT + if (access("/fastboot", F_OK) >= 0) { + log_error("Please pass 'fsck.mode=skip' on the kernel command line rather than creating /fastboot on the root file system."); + arg_skip = true; + } + + if (access("/forcefsck", F_OK) >= 0) { + log_error("Please pass 'fsck.mode=force' on the kernel command line rather than creating /forcefsck on the root file system."); + arg_force = true; + } +#endif + + if (access("/run/systemd/show-status", F_OK) >= 0 || plymouth_running()) + arg_show_progress = true; +} + +static double percent(int pass, unsigned long cur, unsigned long max) { + /* Values stolen from e2fsck */ + + static const int pass_table[] = { + 0, 70, 90, 92, 95, 100 + }; + + if (pass <= 0) + return 0.0; + + if ((unsigned) pass >= ELEMENTSOF(pass_table) || max == 0) + return 100.0; + + return (double) pass_table[pass-1] + + ((double) pass_table[pass] - (double) pass_table[pass-1]) * + (double) cur / (double) max; +} + +static int process_progress(int fd) { + FILE *f, *console; + usec_t last = 0; + bool locked = false; + int clear = 0; + + f = fdopen(fd, "r"); + if (!f) { + close_nointr_nofail(fd); + return -errno; + } + + console = fopen("/dev/console", "w"); + if (!console) { + fclose(f); + return -ENOMEM; + } + + while (!feof(f)) { + int pass, m; + unsigned long cur, max; + char *device; + double p; + usec_t t; + + if (fscanf(f, "%i %lu %lu %ms", &pass, &cur, &max, &device) != 4) + break; + + /* Only show one progress counter at max */ + if (!locked) { + if (flock(fileno(console), LOCK_EX|LOCK_NB) < 0) { + free(device); + continue; + } + + locked = true; + } + + /* Only update once every 50ms */ + t = now(CLOCK_MONOTONIC); + if (last + 50 * USEC_PER_MSEC > t) { + free(device); + continue; + } + + last = t; + + p = percent(pass, cur, max); + fprintf(console, "\r%s: fsck %3.1f%% complete...\r%n", device, p, &m); + fflush(console); + + free(device); + + if (m > clear) + clear = m; + } + + if (clear > 0) { + unsigned j; + + fputc('\r', console); + for (j = 0; j < (unsigned) clear; j++) + fputc(' ', console); + fputc('\r', console); + fflush(console); + } + + fclose(f); + fclose(console); + return 0; +} + +int main(int argc, char *argv[]) { + const char *cmdline[9]; + int i = 0, r = EXIT_FAILURE, q; + pid_t pid; + siginfo_t status; + struct udev *udev = NULL; + struct udev_device *udev_device = NULL; + const char *device; + bool root_directory; + int progress_pipe[2] = { -1, -1 }; + char dash_c[2+10+1]; + + if (argc > 2) { + log_error("This program expects one or no arguments."); + return EXIT_FAILURE; + } + + log_set_target(LOG_TARGET_AUTO); + log_parse_environment(); + log_open(); + + umask(0022); + + parse_proc_cmdline(); + test_files(); + + if (!arg_force && arg_skip) + return 0; + + if (argc > 1) { + device = argv[1]; + root_directory = false; + } else { + struct stat st; + struct timespec times[2]; + + /* Find root device */ + + if (stat("/", &st) < 0) { + log_error("Failed to stat() the root directory: %m"); + goto finish; + } + + /* Virtual root devices don't need an fsck */ + if (major(st.st_dev) == 0) + return 0; + + /* check if we are already writable */ + times[0] = st.st_atim; + times[1] = st.st_mtim; + if (utimensat(AT_FDCWD, "/", times, 0) == 0) { + log_info("Root directory is writable, skipping check."); + return 0; + } + + if (!(udev = udev_new())) { + log_oom(); + goto finish; + } + + if (!(udev_device = udev_device_new_from_devnum(udev, 'b', st.st_dev))) { + log_error("Failed to detect root device."); + goto finish; + } + + if (!(device = udev_device_get_devnode(udev_device))) { + log_error("Failed to detect device node of root directory."); + goto finish; + } + + root_directory = true; + } + + if (arg_show_progress) + if (pipe(progress_pipe) < 0) { + log_error("pipe(): %m"); + goto finish; + } + + cmdline[i++] = "/sbin/fsck"; + cmdline[i++] = "-a"; + cmdline[i++] = "-T"; + cmdline[i++] = "-l"; + + if (!root_directory) + cmdline[i++] = "-M"; + + if (arg_force) + cmdline[i++] = "-f"; + + if (progress_pipe[1] >= 0) { + snprintf(dash_c, sizeof(dash_c), "-C%i", progress_pipe[1]); + char_array_0(dash_c); + cmdline[i++] = dash_c; + } + + cmdline[i++] = device; + cmdline[i++] = NULL; + + pid = fork(); + if (pid < 0) { + log_error("fork(): %m"); + goto finish; + } else if (pid == 0) { + /* Child */ + if (progress_pipe[0] >= 0) + close_nointr_nofail(progress_pipe[0]); + execv(cmdline[0], (char**) cmdline); + _exit(8); /* Operational error */ + } + + if (progress_pipe[1] >= 0) { + close_nointr_nofail(progress_pipe[1]); + progress_pipe[1] = -1; + } + + if (progress_pipe[0] >= 0) { + process_progress(progress_pipe[0]); + progress_pipe[0] = -1; + } + + q = wait_for_terminate(pid, &status); + if (q < 0) { + log_error("waitid(): %s", strerror(-q)); + goto finish; + } + + if (status.si_code != CLD_EXITED || (status.si_status & ~1)) { + + if (status.si_code == CLD_KILLED || status.si_code == 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."); + + if (status.si_code == CLD_EXITED && (status.si_status & 2) && root_directory) + /* System should be rebooted. */ + start_target(SPECIAL_REBOOT_TARGET, false); + else if (status.si_code == CLD_EXITED && (status.si_status & 6)) + /* Some other problem */ + start_target(SPECIAL_EMERGENCY_TARGET, true); + else { + r = EXIT_SUCCESS; + log_warning("Ignoring error."); + } + + } else + r = EXIT_SUCCESS; + + if (status.si_code == CLD_EXITED && (status.si_status & 1)) + touch("/run/systemd/quotacheck"); + +finish: + if (udev_device) + udev_device_unref(udev_device); + + if (udev) + udev_unref(udev); + + close_pipe(progress_pipe); + + return r; +} diff --git a/src/fstab-generator/Makefile b/src/fstab-generator/Makefile new file mode 120000 index 000000000..d0b0e8e00 --- /dev/null +++ b/src/fstab-generator/Makefile @@ -0,0 +1 @@ +../Makefile \ No newline at end of file diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c new file mode 100644 index 000000000..f3ecc24be --- /dev/null +++ b/src/fstab-generator/fstab-generator.c @@ -0,0 +1,587 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + +#include +#include +#include +#include +#include + +#include "log.h" +#include "util.h" +#include "unit-name.h" +#include "path-util.h" +#include "mount-setup.h" +#include "special.h" +#include "mkdir.h" +#include "virt.h" + +static const char *arg_dest = "/tmp"; +static bool arg_enabled = true; + +static int device_name(const char *path, char **unit) { + char *p; + + assert(path); + + if (!is_device_path(path)) + return 0; + + p = unit_name_from_path(path, ".device"); + if (!p) + return log_oom(); + + *unit = p; + return 1; +} + +static int mount_find_pri(struct mntent *me, int *ret) { + char *end, *pri; + unsigned long r; + + assert(me); + assert(ret); + + pri = hasmntopt(me, "pri"); + if (!pri) + return 0; + + pri += 4; + + errno = 0; + r = strtoul(pri, &end, 10); + if (errno != 0) + return -errno; + + if (end == pri || (*end != ',' && *end != 0)) + return -EINVAL; + + *ret = (int) r; + return 1; +} + +static int add_swap(const char *what, struct mntent *me) { + char _cleanup_free_ *name = NULL, *unit = NULL, *lnk = NULL, *device = NULL; + FILE _cleanup_fclose_ *f = NULL; + bool noauto, nofail; + int r, pri = -1; + + assert(what); + assert(me); + + r = mount_find_pri(me, &pri); + if (r < 0) { + log_error("Failed to parse priority"); + return pri; + } + + noauto = !!hasmntopt(me, "noauto"); + nofail = !!hasmntopt(me, "nofail"); + + name = unit_name_from_path(what, ".swap"); + if (!name) + return log_oom(); + + unit = strjoin(arg_dest, "/", name, NULL); + if (!unit) + return log_oom(); + + f = fopen(unit, "wxe"); + if (!f) { + if (errno == EEXIST) + log_error("Failed to create swap unit file %s, as it already exists. Duplicate entry in /etc/fstab?", unit); + else + log_error("Failed to create unit file %s: %m", unit); + return -errno; + } + + fputs("# Automatically generated by systemd-fstab-generator\n\n" + "[Unit]\n" + "SourcePath=/etc/fstab\n" + "DefaultDependencies=no\n" + "Conflicts=" SPECIAL_UMOUNT_TARGET "\n" + "Before=" SPECIAL_UMOUNT_TARGET "\n", f); + + if (!noauto && !nofail) + fputs("Before=" SPECIAL_SWAP_TARGET "\n", f); + + fprintf(f, + "\n" + "[Swap]\n" + "What=%s\n", + what); + + if (pri >= 0) + fprintf(f, + "Priority=%i\n", + pri); + + fflush(f); + if (ferror(f)) { + log_error("Failed to write unit file %s: %m", unit); + return -errno; + } + + if (!noauto) { + lnk = strjoin(arg_dest, "/" SPECIAL_SWAP_TARGET ".wants/", name, NULL); + if (!lnk) + return log_oom(); + + mkdir_parents_label(lnk, 0755); + if (symlink(unit, lnk) < 0) { + log_error("Failed to create symlink %s: %m", lnk); + return -errno; + } + + r = device_name(what, &device); + if (r < 0) + return r; + + if (r > 0) { + free(lnk); + lnk = strjoin(arg_dest, "/", device, ".wants/", name, NULL); + if (!lnk) + return log_oom(); + + mkdir_parents_label(lnk, 0755); + if (symlink(unit, lnk) < 0) { + log_error("Failed to create symlink %s: %m", lnk); + return -errno; + } + } + } + + return 0; +} + +static bool mount_is_bind(struct mntent *me) { + assert(me); + + return + hasmntopt(me, "bind") || + streq(me->mnt_type, "bind"); +} + +static bool mount_is_network(struct mntent *me) { + assert(me); + + return + hasmntopt(me, "_netdev") || + fstype_is_network(me->mnt_type); +} + +static int add_mount(const char *what, const char *where, const char *type, const char *opts, + int passno, bool wait, bool noauto, bool nofail, bool automount, bool isbind, bool isnetwork, + const char *source) { + char _cleanup_free_ + *name = NULL, *unit = NULL, *lnk = NULL, *device = NULL, + *automount_name = NULL, *automount_unit = NULL; + FILE _cleanup_fclose_ *f = NULL; + int r; + const char *post, *pre; + + assert(what); + assert(where); + assert(type); + assert(opts); + assert(source); + + if (streq(type, "autofs")) + return 0; + + if (!is_path(where)) { + log_warning("Mount point %s is not a valid path, ignoring.", where); + return 0; + } + + if (mount_point_is_api(where) || + mount_point_ignore(where)) + return 0; + + if (isnetwork) { + post = SPECIAL_REMOTE_FS_TARGET; + pre = SPECIAL_REMOTE_FS_PRE_TARGET; + } else { + post = SPECIAL_LOCAL_FS_TARGET; + pre = SPECIAL_LOCAL_FS_PRE_TARGET; + } + + name = unit_name_from_path(where, ".mount"); + if (!name) + return log_oom(); + + unit = strjoin(arg_dest, "/", name, NULL); + if (!unit) + return log_oom(); + + f = fopen(unit, "wxe"); + if (!f) { + if (errno == EEXIST) + log_error("Failed to create mount unit file %s, as it already exists. Duplicate entry in /etc/fstab?", unit); + else + log_error("Failed to create unit file %s: %m", unit); + return -errno; + } + + fprintf(f, + "# Automatically generated by systemd-fstab-generator\n\n" + "[Unit]\n" + "SourcePath=%s\n" + "DefaultDependencies=no\n", + source); + + if (!path_equal(where, "/")) + fprintf(f, + "After=%s\n" + "Wants=%s\n" + "Conflicts=" SPECIAL_UMOUNT_TARGET "\n" + "Before=" SPECIAL_UMOUNT_TARGET "\n", + pre, + pre); + + + if (!noauto && !nofail && !automount) + fprintf(f, + "Before=%s\n", + post); + + fprintf(f, + "\n" + "[Mount]\n" + "What=%s\n" + "Where=%s\n" + "Type=%s\n" + "FsckPassNo=%i\n", + what, + where, + type, + passno); + + if (!isempty(opts) && + !streq(opts, "defaults")) + fprintf(f, + "Options=%s\n", + opts); + + if (wait) + fprintf(f, + "TimeoutSec=0\n"); + + fflush(f); + if (ferror(f)) { + log_error("Failed to write unit file %s: %m", unit); + return -errno; + } + + if (!noauto) { + lnk = strjoin(arg_dest, "/", post, nofail || automount ? ".wants/" : ".requires/", name, NULL); + if (!lnk) + return log_oom(); + + mkdir_parents_label(lnk, 0755); + if (symlink(unit, lnk) < 0) { + log_error("Failed to create symlink %s: %m", lnk); + return -errno; + } + + if (!isbind && + !path_equal(where, "/")) { + + r = device_name(what, &device); + if (r < 0) + return r; + + if (r > 0) { + free(lnk); + lnk = strjoin(arg_dest, "/", device, ".wants/", name, NULL); + if (!lnk) + return log_oom(); + + mkdir_parents_label(lnk, 0755); + if (symlink(unit, lnk) < 0) { + log_error("Failed to create symlink %s: %m", lnk); + return -errno; + } + } + } + } + + if (automount && !path_equal(where, "/")) { + automount_name = unit_name_from_path(where, ".automount"); + if (!name) + return log_oom(); + + automount_unit = strjoin(arg_dest, "/", automount_name, NULL); + if (!automount_unit) + return log_oom(); + + fclose(f); + f = fopen(automount_unit, "wxe"); + if (!f) { + log_error("Failed to create unit file %s: %m", automount_unit); + return -errno; + } + + fprintf(f, + "# Automatically generated by systemd-fstab-generator\n\n" + "[Unit]\n" + "SourcePath=/etc/fstab\n" + "DefaultDependencies=no\n" + "Conflicts=" SPECIAL_UMOUNT_TARGET "\n" + "Before=" SPECIAL_UMOUNT_TARGET " %s\n" + "\n" + "[Automount]\n" + "Where=%s\n", + post, + where); + + fflush(f); + if (ferror(f)) { + log_error("Failed to write unit file %s: %m", automount_unit); + return -errno; + } + + free(lnk); + lnk = strjoin(arg_dest, "/", post, nofail ? ".wants/" : ".requires/", automount_name, NULL); + if (!lnk) + return log_oom(); + + mkdir_parents_label(lnk, 0755); + if (symlink(automount_unit, lnk) < 0) { + log_error("Failed to create symlink %s: %m", lnk); + return -errno; + } + } + + return 0; +} + +static int parse_fstab(void) { + FILE *f; + int r = 0; + struct mntent *me; + + errno = 0; + f = setmntent("/etc/fstab", "r"); + if (!f) { + if (errno == ENOENT) + return 0; + + log_error("Failed to open /etc/fstab: %m"); + return -errno; + } + + while ((me = getmntent(f))) { + char _cleanup_free_ *where = NULL, *what = NULL; + int k; + + what = fstab_node_to_udev_node(me->mnt_fsname); + where = strdup(me->mnt_dir); + if (!what || !where) { + r = log_oom(); + goto finish; + } + + if (is_path(where)) + path_kill_slashes(where); + + log_debug("Found entry what=%s where=%s type=%s", what, where, me->mnt_type); + + if (streq(me->mnt_type, "swap")) + k = add_swap(what, me); + else { + bool noauto, nofail, automount, isbind, isnetwork; + + noauto = !!hasmntopt(me, "noauto"); + nofail = !!hasmntopt(me, "nofail"); + automount = + hasmntopt(me, "comment=systemd.automount") || + hasmntopt(me, "x-systemd.automount"); + isbind = mount_is_bind(me); + isnetwork = mount_is_network(me); + + k = add_mount(what, where, me->mnt_type, me->mnt_opts, + me->mnt_passno, false, noauto, nofail, + automount, isbind, isnetwork, + "/etc/fstab"); + } + + if (k < 0) + r = k; + } + +finish: + endmntent(f); + return r; +} + +static int parse_new_root_from_proc_cmdline(void) { + char *w, *state; + _cleanup_free_ char *what = NULL, *type = NULL, *opts = NULL, *line = NULL; + int r; + size_t l; + bool wait = false; + + r = read_one_line_file("/proc/cmdline", &line); + if (r < 0) { + log_error("Failed to read /proc/cmdline, ignoring: %s", strerror(-r)); + return 0; + } + + opts = strdup("defaults"); + type = strdup("auto"); + if (!opts || !type) + return log_oom(); + + /* root= and roofstype= may occur more than once, the last instance should take precedence. + * In the case of multiple rootflags= the arguments should be concatenated */ + FOREACH_WORD_QUOTED(w, l, line, state) { + char *word, *tmp_word; + + word = strndup(w, l); + if (!word) + return log_oom(); + + else if (startswith(word, "root=")) { + free(what); + what = fstab_node_to_udev_node(word+5); + if (!what) + return log_oom(); + + } else if (startswith(word, "rootfstype=")) { + free(type); + type = strdup(word + 11); + if (!type) + return log_oom(); + + } else if (startswith(word, "rootflags=")) { + tmp_word = opts; + opts = strjoin(opts, ",", word + 10, NULL); + free(tmp_word); + if (!opts) + return log_oom(); + + } else if (streq(word, "ro") || streq(word, "rw")) { + tmp_word = opts; + opts = strjoin(opts, ",", word, NULL); + free(tmp_word); + if (!opts) + return log_oom(); + + } else if (streq(word, "rootwait")) + wait = true; + + free(word); + } + + if (what) { + + log_debug("Found entry what=%s where=/new_root type=%s", what, type); + r = add_mount(what, "/new_root", type, opts, 0, wait, false, false, + false, false, false, "/proc/cmdline"); + + if (r < 0) + return r; + } else + log_error("Could not find a root= entry on the kernel commandline."); + + return 0; +} + +static int parse_proc_cmdline(void) { + char _cleanup_free_ *line = NULL; + char *w, *state; + int r; + size_t l; + + if (detect_container(NULL) > 0) + return 0; + + r = read_one_line_file("/proc/cmdline", &line); + if (r < 0) { + log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r)); + return 0; + } + + FOREACH_WORD_QUOTED(w, l, line, state) { + char _cleanup_free_ *word = NULL; + + word = strndup(w, l); + if (!word) + return log_oom(); + + if (startswith(word, "fstab=")) { + r = parse_boolean(word + 6); + if (r < 0) + log_warning("Failed to parse fstab switch %s. Ignoring.", word + 6); + else + arg_enabled = r; + + } else if (startswith(word, "rd.fstab=")) { + + if (in_initrd()) { + r = parse_boolean(word + 6); + if (r < 0) + log_warning("Failed to parse fstab switch %s. Ignoring.", word + 6); + else + arg_enabled = r; + } + + } else if (startswith(word, "fstab.") || + (in_initrd() && startswith(word, "rd.fstab."))) { + + log_warning("Unknown kernel switch %s. Ignoring.", word); + } + } + + return 0; +} + +int main(int argc, char *argv[]) { + int r, k = 0; + + if (argc > 1 && argc != 4) { + log_error("This program takes three or no arguments."); + return EXIT_FAILURE; + } + + if (argc > 1) + arg_dest = argv[1]; + + log_set_target(LOG_TARGET_SAFE); + log_parse_environment(); + log_open(); + + umask(0022); + + if (parse_proc_cmdline() < 0) + return EXIT_FAILURE; + + if (in_initrd()) + k = parse_new_root_from_proc_cmdline(); + + if (!arg_enabled) + return EXIT_SUCCESS; + + r = parse_fstab(); + + return (r < 0) || (k < 0) ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/src/getty-generator/Makefile b/src/getty-generator/Makefile new file mode 120000 index 000000000..d0b0e8e00 --- /dev/null +++ b/src/getty-generator/Makefile @@ -0,0 +1 @@ +../Makefile \ No newline at end of file diff --git a/src/getty-generator/getty-generator.c b/src/getty-generator/getty-generator.c new file mode 100644 index 000000000..cb38f2105 --- /dev/null +++ b/src/getty-generator/getty-generator.c @@ -0,0 +1,180 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include + +#include "log.h" +#include "util.h" +#include "mkdir.h" +#include "unit-name.h" +#include "virt.h" + +static const char *arg_dest = "/tmp"; + +static int add_symlink(const char *fservice, const char *tservice) { + char *from = NULL, *to = NULL; + int r; + + assert(fservice); + assert(tservice); + + from = strappend(SYSTEM_DATA_UNIT_PATH "/", fservice); + to = strjoin(arg_dest,"/getty.target.wants/", tservice, NULL); + + if (!from || !to) { + r = log_oom(); + goto finish; + } + + mkdir_parents_label(to, 0755); + + r = symlink(from, to); + if (r < 0) { + if (errno == EEXIST) + /* In case console=hvc0 is passed this will very likely result in EEXIST */ + r = 0; + else { + log_error("Failed to create symlink from %s to %s: %m", from, to); + r = -errno; + } + } + +finish: + + free(from); + free(to); + + return r; +} + +static int add_serial_getty(const char *tty) { + char *n; + int r; + + assert(tty); + + log_debug("Automatically adding serial getty for /dev/%s.", tty); + + n = unit_name_replace_instance("serial-getty@.service", tty); + if (!n) + return log_oom(); + + r = add_symlink("serial-getty@.service", n); + free(n); + + return r; +} + +int main(int argc, char *argv[]) { + + static const char virtualization_consoles[] = + "hvc0\0" + "xvc0\0" + "hvsi0\0"; + + int r = EXIT_SUCCESS; + char *active; + const char *j; + + if (argc > 1 && argc != 4) { + log_error("This program takes three or no arguments."); + return EXIT_FAILURE; + } + + if (argc > 1) + arg_dest = argv[1]; + + log_set_target(LOG_TARGET_SAFE); + log_parse_environment(); + log_open(); + + umask(0022); + + if (detect_container(NULL) > 0) { + log_debug("Automatically adding console shell."); + + if (add_symlink("console-getty.service", "console-getty.service") < 0) + r = EXIT_FAILURE; + + /* Don't add any further magic if we are in a container */ + goto finish; + } + + if (read_one_line_file("/sys/class/tty/console/active", &active) >= 0) { + const char *tty; + + tty = strrchr(active, ' '); + if (tty) + tty ++; + else + tty = active; + + /* Automatically add in a serial getty on the kernel + * console */ + if (isempty(tty) || tty_is_vc(tty)) + free(active); + else { + int k; + + /* We assume that gettys on virtual terminals are + * started via manual configuration and do this magic + * only for non-VC terminals. */ + + k = add_serial_getty(tty); + free(active); + + if (k < 0) { + r = EXIT_FAILURE; + goto finish; + } + } + } + + /* Automatically add in a serial getty on the first + * virtualizer console */ + NULSTR_FOREACH(j, virtualization_consoles) { + char *p; + int k; + + if (asprintf(&p, "/sys/class/tty/%s", j) < 0) { + log_oom(); + r = EXIT_FAILURE; + goto finish; + } + + k = access(p, F_OK); + free(p); + + if (k < 0) + continue; + + k = add_serial_getty(j); + if (k < 0) { + r = EXIT_FAILURE; + goto finish; + } + } + +finish: + return r; +} diff --git a/src/gudev/.gitignore b/src/gudev/.gitignore new file mode 100644 index 000000000..4577903c4 --- /dev/null +++ b/src/gudev/.gitignore @@ -0,0 +1,7 @@ +gudev-1.0.pc +gudevenumtypes.c +gudevenumtypes.h +gudevmarshal.c +gudevmarshal.h +GUdev-1.0.gir +GUdev-1.0.typelib diff --git a/src/gudev/Makefile b/src/gudev/Makefile new file mode 120000 index 000000000..d0b0e8e00 --- /dev/null +++ b/src/gudev/Makefile @@ -0,0 +1 @@ +../Makefile \ No newline at end of file diff --git a/src/gudev/gjs-example.js b/src/gudev/gjs-example.js new file mode 100755 index 000000000..5586fd6a6 --- /dev/null +++ b/src/gudev/gjs-example.js @@ -0,0 +1,75 @@ +#!/usr/bin/env gjs-console + +// This currently depends on the following patches to gjs +// +// http://bugzilla.gnome.org/show_bug.cgi?id=584558 +// http://bugzilla.gnome.org/show_bug.cgi?id=584560 +// http://bugzilla.gnome.org/show_bug.cgi?id=584568 + +const GUdev = imports.gi.GUdev; +const Mainloop = imports.mainloop; + +function print_device (device) { + print (" subsystem: " + device.get_subsystem ()); + print (" devtype: " + device.get_devtype ()); + print (" name: " + device.get_name ()); + print (" number: " + device.get_number ()); + print (" sysfs_path: " + device.get_sysfs_path ()); + print (" driver: " + device.get_driver ()); + print (" action: " + device.get_action ()); + print (" seqnum: " + device.get_seqnum ()); + print (" device type: " + device.get_device_type ()); + print (" device number: " + device.get_device_number ()); + print (" device file: " + device.get_device_file ()); + print (" device file symlinks: " + device.get_device_file_symlinks ()); + print (" foo: " + device.get_sysfs_attr_as_strv ("stat")); + var keys = device.get_property_keys (); + for (var n = 0; n < keys.length; n++) { + print (" " + keys[n] + "=" + device.get_property (keys[n])); + } +} + +function on_uevent (client, action, device) { + print ("action " + action + " on device " + device.get_sysfs_path()); + print_device (device); + print (""); +} + +var client = new GUdev.Client ({subsystems: ["block", "usb/usb_interface"]}); +client.connect ("uevent", on_uevent); + +var block_devices = client.query_by_subsystem ("block"); +for (var n = 0; n < block_devices.length; n++) { + print ("block device: " + block_devices[n].get_device_file ()); +} + +var d; + +d = client.query_by_device_number (GUdev.DeviceType.BLOCK, 0x0810); +if (d == null) { + print ("query_by_device_number 0x810 -> null"); +} else { + print ("query_by_device_number 0x810 -> " + d.get_device_file ()); + var dd = d.get_parent_with_subsystem ("usb", null); + print_device (dd); + print ("--------------------------------------------------------------------------"); + while (d != null) { + print_device (d); + print (""); + d = d.get_parent (); + } +} + +d = client.query_by_sysfs_path ("/sys/block/sda/sda1"); +print ("query_by_sysfs_path (\"/sys/block/sda1\") -> " + d.get_device_file ()); + +d = client.query_by_subsystem_and_name ("block", "sda2"); +print ("query_by_subsystem_and_name (\"block\", \"sda2\") -> " + d.get_device_file ()); + +d = client.query_by_device_file ("/dev/sda"); +print ("query_by_device_file (\"/dev/sda\") -> " + d.get_device_file ()); + +d = client.query_by_device_file ("/dev/block/8:0"); +print ("query_by_device_file (\"/dev/block/8:0\") -> " + d.get_device_file ()); + +Mainloop.run('udev-example'); diff --git a/src/gudev/gudev-1.0.pc.in b/src/gudev/gudev-1.0.pc.in new file mode 100644 index 000000000..058262d76 --- /dev/null +++ b/src/gudev/gudev-1.0.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: gudev-1.0 +Description: GObject bindings for libudev +Version: @VERSION@ +Requires: glib-2.0, gobject-2.0 +Libs: -L${libdir} -lgudev-1.0 +Cflags: -I${includedir}/gudev-1.0 diff --git a/src/gudev/gudev.h b/src/gudev/gudev.h new file mode 100644 index 000000000..1dc42b11b --- /dev/null +++ b/src/gudev/gudev.h @@ -0,0 +1,32 @@ +/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * + * Copyright (C) 2008 David Zeuthen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __G_UDEV_H__ +#define __G_UDEV_H__ + +#define _GUDEV_INSIDE_GUDEV_H +#include +#include +#include +#include +#include +#include +#undef _GUDEV_INSIDE_GUDEV_H + +#endif /* __G_UDEV_H__ */ diff --git a/src/gudev/gudevclient.c b/src/gudev/gudevclient.c new file mode 100644 index 000000000..a151b50ac --- /dev/null +++ b/src/gudev/gudevclient.c @@ -0,0 +1,525 @@ +/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * + * Copyright (C) 2008-2010 David Zeuthen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include "gudevclient.h" +#include "gudevdevice.h" +#include "gudevmarshal.h" +#include "gudevprivate.h" + +/** + * SECTION:gudevclient + * @short_description: Query devices and listen to uevents + * + * #GUdevClient is used to query information about devices on a Linux + * system from the Linux kernel and the udev device + * manager. + * + * Device information is retrieved from the kernel (through the + * sysfs filesystem) and the udev daemon (through a + * tmpfs filesystem) and presented through + * #GUdevDevice objects. This means that no blocking IO ever happens + * (in both cases, we are essentially just reading data from kernel + * memory) and as such there are no asynchronous versions of the + * provided methods. + * + * To get #GUdevDevice objects, use + * g_udev_client_query_by_subsystem(), + * g_udev_client_query_by_device_number(), + * g_udev_client_query_by_device_file(), + * g_udev_client_query_by_sysfs_path(), + * g_udev_client_query_by_subsystem_and_name() + * or the #GUdevEnumerator type. + * + * To listen to uevents, connect to the #GUdevClient::uevent signal. + */ + +struct _GUdevClientPrivate +{ + GSource *watch_source; + struct udev *udev; + struct udev_monitor *monitor; + + gchar **subsystems; +}; + +enum +{ + PROP_0, + PROP_SUBSYSTEMS, +}; + +enum +{ + UEVENT_SIGNAL, + LAST_SIGNAL, +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +G_DEFINE_TYPE (GUdevClient, g_udev_client, G_TYPE_OBJECT) + +/* ---------------------------------------------------------------------------------------------------- */ + +static gboolean +monitor_event (GIOChannel *source, + GIOCondition condition, + gpointer data) +{ + GUdevClient *client = (GUdevClient *) data; + GUdevDevice *device; + struct udev_device *udevice; + + if (client->priv->monitor == NULL) + goto out; + udevice = udev_monitor_receive_device (client->priv->monitor); + if (udevice == NULL) + goto out; + + device = _g_udev_device_new (udevice); + udev_device_unref (udevice); + g_signal_emit (client, + signals[UEVENT_SIGNAL], + 0, + g_udev_device_get_action (device), + device); + g_object_unref (device); + + out: + return TRUE; +} + +static void +g_udev_client_finalize (GObject *object) +{ + GUdevClient *client = G_UDEV_CLIENT (object); + + if (client->priv->watch_source != NULL) + { + g_source_destroy (client->priv->watch_source); + client->priv->watch_source = NULL; + } + + if (client->priv->monitor != NULL) + { + udev_monitor_unref (client->priv->monitor); + client->priv->monitor = NULL; + } + + if (client->priv->udev != NULL) + { + udev_unref (client->priv->udev); + client->priv->udev = NULL; + } + + g_strfreev (client->priv->subsystems); + + if (G_OBJECT_CLASS (g_udev_client_parent_class)->finalize != NULL) + G_OBJECT_CLASS (g_udev_client_parent_class)->finalize (object); +} + +static void +g_udev_client_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GUdevClient *client = G_UDEV_CLIENT (object); + + switch (prop_id) + { + case PROP_SUBSYSTEMS: + if (client->priv->subsystems != NULL) + g_strfreev (client->priv->subsystems); + client->priv->subsystems = g_strdupv (g_value_get_boxed (value)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +g_udev_client_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GUdevClient *client = G_UDEV_CLIENT (object); + + switch (prop_id) + { + case PROP_SUBSYSTEMS: + g_value_set_boxed (value, client->priv->subsystems); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +g_udev_client_constructed (GObject *object) +{ + GUdevClient *client = G_UDEV_CLIENT (object); + GIOChannel *channel; + guint n; + + client->priv->udev = udev_new (); + + /* connect to event source */ + client->priv->monitor = udev_monitor_new_from_netlink (client->priv->udev, "udev"); + + //g_debug ("ss = %p", client->priv->subsystems); + + if (client->priv->subsystems != NULL) + { + /* install subsystem filters to only wake up for certain events */ + for (n = 0; client->priv->subsystems[n] != NULL; n++) + { + gchar *subsystem; + gchar *devtype; + gchar *s; + + subsystem = g_strdup (client->priv->subsystems[n]); + devtype = NULL; + + //g_debug ("s = '%s'", subsystem); + + s = strstr (subsystem, "/"); + if (s != NULL) + { + devtype = s + 1; + *s = '\0'; + } + + if (client->priv->monitor != NULL) + udev_monitor_filter_add_match_subsystem_devtype (client->priv->monitor, subsystem, devtype); + + g_free (subsystem); + } + + /* listen to events, and buffer them */ + if (client->priv->monitor != NULL) + { + udev_monitor_enable_receiving (client->priv->monitor); + channel = g_io_channel_unix_new (udev_monitor_get_fd (client->priv->monitor)); + client->priv->watch_source = g_io_create_watch (channel, G_IO_IN); + g_io_channel_unref (channel); + g_source_set_callback (client->priv->watch_source, (GSourceFunc) monitor_event, client, NULL); + g_source_attach (client->priv->watch_source, g_main_context_get_thread_default ()); + g_source_unref (client->priv->watch_source); + } + else + { + client->priv->watch_source = NULL; + } + } + + if (G_OBJECT_CLASS (g_udev_client_parent_class)->constructed != NULL) + G_OBJECT_CLASS (g_udev_client_parent_class)->constructed (object); +} + + +static void +g_udev_client_class_init (GUdevClientClass *klass) +{ + GObjectClass *gobject_class = (GObjectClass *) klass; + + gobject_class->constructed = g_udev_client_constructed; + gobject_class->set_property = g_udev_client_set_property; + gobject_class->get_property = g_udev_client_get_property; + gobject_class->finalize = g_udev_client_finalize; + + /** + * GUdevClient:subsystems: + * + * The subsystems to listen for uevents on. + * + * To listen for only a specific DEVTYPE for a given SUBSYSTEM, use + * "subsystem/devtype". For example, to only listen for uevents + * where SUBSYSTEM is usb and DEVTYPE is usb_interface, use + * "usb/usb_interface". + * + * If this property is %NULL, then no events will be reported. If + * it's the empty array, events from all subsystems will be + * reported. + */ + g_object_class_install_property (gobject_class, + PROP_SUBSYSTEMS, + g_param_spec_boxed ("subsystems", + "The subsystems to listen for changes on", + "The subsystems to listen for changes on", + G_TYPE_STRV, + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_READWRITE)); + + /** + * GUdevClient::uevent: + * @client: The #GUdevClient receiving the event. + * @action: The action for the uevent e.g. "add", "remove", "change", "move", etc. + * @device: Details about the #GUdevDevice the event is for. + * + * Emitted when @client receives an uevent. + * + * This signal is emitted in the + * thread-default main loop + * of the thread that @client was created in. + */ + signals[UEVENT_SIGNAL] = g_signal_new ("uevent", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GUdevClientClass, uevent), + NULL, + NULL, + g_udev_marshal_VOID__STRING_OBJECT, + G_TYPE_NONE, + 2, + G_TYPE_STRING, + G_UDEV_TYPE_DEVICE); + + g_type_class_add_private (klass, sizeof (GUdevClientPrivate)); +} + +static void +g_udev_client_init (GUdevClient *client) +{ + client->priv = G_TYPE_INSTANCE_GET_PRIVATE (client, + G_UDEV_TYPE_CLIENT, + GUdevClientPrivate); +} + +/** + * g_udev_client_new: + * @subsystems: (array zero-terminated=1) (element-type utf8) (transfer none) (allow-none): A %NULL terminated string array of subsystems to listen for uevents on, %NULL to not listen on uevents at all, or an empty array to listen to uevents on all subsystems. See the documentation for the #GUdevClient:subsystems property for details on this parameter. + * + * Constructs a #GUdevClient object that can be used to query + * information about devices. Connect to the #GUdevClient::uevent + * signal to listen for uevents. Note that signals are emitted in the + * thread-default main loop + * of the thread that you call this constructor from. + * + * Returns: A new #GUdevClient object. Free with g_object_unref(). + */ +GUdevClient * +g_udev_client_new (const gchar * const *subsystems) +{ + return G_UDEV_CLIENT (g_object_new (G_UDEV_TYPE_CLIENT, "subsystems", subsystems, NULL)); +} + +/** + * g_udev_client_query_by_subsystem: + * @client: A #GUdevClient. + * @subsystem: (allow-none): The subsystem to get devices for or %NULL to get all devices. + * + * Gets all devices belonging to @subsystem. + * + * Returns: (element-type GUdevDevice) (transfer full): A list of #GUdevDevice objects. The caller should free the result by using g_object_unref() on each element in the list and then g_list_free() on the list. + */ +GList * +g_udev_client_query_by_subsystem (GUdevClient *client, + const gchar *subsystem) +{ + struct udev_enumerate *enumerate; + struct udev_list_entry *l, *devices; + GList *ret; + + g_return_val_if_fail (G_UDEV_IS_CLIENT (client), NULL); + + ret = NULL; + + /* prepare a device scan */ + enumerate = udev_enumerate_new (client->priv->udev); + + /* filter for subsystem */ + if (subsystem != NULL) + udev_enumerate_add_match_subsystem (enumerate, subsystem); + /* retrieve the list */ + udev_enumerate_scan_devices (enumerate); + + /* add devices to the list */ + devices = udev_enumerate_get_list_entry (enumerate); + for (l = devices; l != NULL; l = udev_list_entry_get_next (l)) + { + struct udev_device *udevice; + GUdevDevice *device; + + udevice = udev_device_new_from_syspath (udev_enumerate_get_udev (enumerate), + udev_list_entry_get_name (l)); + if (udevice == NULL) + continue; + device = _g_udev_device_new (udevice); + udev_device_unref (udevice); + ret = g_list_prepend (ret, device); + } + udev_enumerate_unref (enumerate); + + ret = g_list_reverse (ret); + + return ret; +} + +/** + * g_udev_client_query_by_device_number: + * @client: A #GUdevClient. + * @type: A value from the #GUdevDeviceType enumeration. + * @number: A device number. + * + * Looks up a device for a type and device number. + * + * Returns: (transfer full): A #GUdevDevice object or %NULL if the device was not found. Free with g_object_unref(). + */ +GUdevDevice * +g_udev_client_query_by_device_number (GUdevClient *client, + GUdevDeviceType type, + GUdevDeviceNumber number) +{ + struct udev_device *udevice; + GUdevDevice *device; + + g_return_val_if_fail (G_UDEV_IS_CLIENT (client), NULL); + + device = NULL; + udevice = udev_device_new_from_devnum (client->priv->udev, type, number); + + if (udevice == NULL) + goto out; + + device = _g_udev_device_new (udevice); + udev_device_unref (udevice); + + out: + return device; +} + +/** + * g_udev_client_query_by_device_file: + * @client: A #GUdevClient. + * @device_file: A device file. + * + * Looks up a device for a device file. + * + * Returns: (transfer full): A #GUdevDevice object or %NULL if the device was not found. Free with g_object_unref(). + */ +GUdevDevice * +g_udev_client_query_by_device_file (GUdevClient *client, + const gchar *device_file) +{ + struct stat stat_buf; + GUdevDevice *device; + + g_return_val_if_fail (G_UDEV_IS_CLIENT (client), NULL); + g_return_val_if_fail (device_file != NULL, NULL); + + device = NULL; + + if (stat (device_file, &stat_buf) != 0) + goto out; + + if (stat_buf.st_rdev == 0) + goto out; + + if (S_ISBLK (stat_buf.st_mode)) + device = g_udev_client_query_by_device_number (client, G_UDEV_DEVICE_TYPE_BLOCK, stat_buf.st_rdev); + else if (S_ISCHR (stat_buf.st_mode)) + device = g_udev_client_query_by_device_number (client, G_UDEV_DEVICE_TYPE_CHAR, stat_buf.st_rdev); + + out: + return device; +} + +/** + * g_udev_client_query_by_sysfs_path: + * @client: A #GUdevClient. + * @sysfs_path: A sysfs path. + * + * Looks up a device for a sysfs path. + * + * Returns: (transfer full): A #GUdevDevice object or %NULL if the device was not found. Free with g_object_unref(). + */ +GUdevDevice * +g_udev_client_query_by_sysfs_path (GUdevClient *client, + const gchar *sysfs_path) +{ + struct udev_device *udevice; + GUdevDevice *device; + + g_return_val_if_fail (G_UDEV_IS_CLIENT (client), NULL); + g_return_val_if_fail (sysfs_path != NULL, NULL); + + device = NULL; + udevice = udev_device_new_from_syspath (client->priv->udev, sysfs_path); + if (udevice == NULL) + goto out; + + device = _g_udev_device_new (udevice); + udev_device_unref (udevice); + + out: + return device; +} + +/** + * g_udev_client_query_by_subsystem_and_name: + * @client: A #GUdevClient. + * @subsystem: A subsystem name. + * @name: The name of the device. + * + * Looks up a device for a subsystem and name. + * + * Returns: (transfer full): A #GUdevDevice object or %NULL if the device was not found. Free with g_object_unref(). + */ +GUdevDevice * +g_udev_client_query_by_subsystem_and_name (GUdevClient *client, + const gchar *subsystem, + const gchar *name) +{ + struct udev_device *udevice; + GUdevDevice *device; + + g_return_val_if_fail (G_UDEV_IS_CLIENT (client), NULL); + g_return_val_if_fail (subsystem != NULL, NULL); + g_return_val_if_fail (name != NULL, NULL); + + device = NULL; + udevice = udev_device_new_from_subsystem_sysname (client->priv->udev, subsystem, name); + if (udevice == NULL) + goto out; + + device = _g_udev_device_new (udevice); + udev_device_unref (udevice); + + out: + return device; +} + +struct udev * +_g_udev_client_get_udev (GUdevClient *client) +{ + g_return_val_if_fail (G_UDEV_IS_CLIENT (client), NULL); + return client->priv->udev; +} diff --git a/src/gudev/gudevclient.h b/src/gudev/gudevclient.h new file mode 100644 index 000000000..23bfce615 --- /dev/null +++ b/src/gudev/gudevclient.h @@ -0,0 +1,99 @@ +/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * + * Copyright (C) 2008 David Zeuthen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#if !defined (_GUDEV_COMPILATION) && !defined(_GUDEV_INSIDE_GUDEV_H) +#error "Only can be included directly, this file may disappear or change contents." +#endif + +#ifndef __G_UDEV_CLIENT_H__ +#define __G_UDEV_CLIENT_H__ + +#include + +G_BEGIN_DECLS + +#define G_UDEV_TYPE_CLIENT (g_udev_client_get_type ()) +#define G_UDEV_CLIENT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_UDEV_TYPE_CLIENT, GUdevClient)) +#define G_UDEV_CLIENT_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_UDEV_TYPE_CLIENT, GUdevClientClass)) +#define G_UDEV_IS_CLIENT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_UDEV_TYPE_CLIENT)) +#define G_UDEV_IS_CLIENT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_UDEV_TYPE_CLIENT)) +#define G_UDEV_CLIENT_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_UDEV_TYPE_CLIENT, GUdevClientClass)) + +typedef struct _GUdevClientClass GUdevClientClass; +typedef struct _GUdevClientPrivate GUdevClientPrivate; + +/** + * GUdevClient: + * + * The #GUdevClient struct is opaque and should not be accessed directly. + */ +struct _GUdevClient +{ + GObject parent; + + /*< private >*/ + GUdevClientPrivate *priv; +}; + +/** + * GUdevClientClass: + * @parent_class: Parent class. + * @uevent: Signal class handler for the #GUdevClient::uevent signal. + * + * Class structure for #GUdevClient. + */ +struct _GUdevClientClass +{ + GObjectClass parent_class; + + /* signals */ + void (*uevent) (GUdevClient *client, + const gchar *action, + GUdevDevice *device); + + /*< private >*/ + /* Padding for future expansion */ + void (*reserved1) (void); + void (*reserved2) (void); + void (*reserved3) (void); + void (*reserved4) (void); + void (*reserved5) (void); + void (*reserved6) (void); + void (*reserved7) (void); + void (*reserved8) (void); +}; + +GType g_udev_client_get_type (void) G_GNUC_CONST; +GUdevClient *g_udev_client_new (const gchar* const *subsystems); +GList *g_udev_client_query_by_subsystem (GUdevClient *client, + const gchar *subsystem); +GUdevDevice *g_udev_client_query_by_device_number (GUdevClient *client, + GUdevDeviceType type, + GUdevDeviceNumber number); +GUdevDevice *g_udev_client_query_by_device_file (GUdevClient *client, + const gchar *device_file); +GUdevDevice *g_udev_client_query_by_sysfs_path (GUdevClient *client, + const gchar *sysfs_path); +GUdevDevice *g_udev_client_query_by_subsystem_and_name (GUdevClient *client, + const gchar *subsystem, + const gchar *name); + +G_END_DECLS + +#endif /* __G_UDEV_CLIENT_H__ */ diff --git a/src/gudev/gudevdevice.c b/src/gudev/gudevdevice.c new file mode 100644 index 000000000..6c9e0f56c --- /dev/null +++ b/src/gudev/gudevdevice.c @@ -0,0 +1,961 @@ +/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * + * Copyright (C) 2008 David Zeuthen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include "gudevdevice.h" +#include "gudevprivate.h" + +/** + * SECTION:gudevdevice + * @short_description: Get information about a device + * + * The #GUdevDevice class is used to get information about a specific + * device. Note that you cannot instantiate a #GUdevDevice object + * yourself. Instead you must use #GUdevClient to obtain #GUdevDevice + * objects. + * + * To get basic information about a device, use + * g_udev_device_get_subsystem(), g_udev_device_get_devtype(), + * g_udev_device_get_name(), g_udev_device_get_number(), + * g_udev_device_get_sysfs_path(), g_udev_device_get_driver(), + * g_udev_device_get_action(), g_udev_device_get_seqnum(), + * g_udev_device_get_device_type(), g_udev_device_get_device_number(), + * g_udev_device_get_device_file(), + * g_udev_device_get_device_file_symlinks(). + * + * To navigate the device tree, use g_udev_device_get_parent() and + * g_udev_device_get_parent_with_subsystem(). + * + * To access udev properties for the device, use + * g_udev_device_get_property_keys(), + * g_udev_device_has_property(), + * g_udev_device_get_property(), + * g_udev_device_get_property_as_int(), + * g_udev_device_get_property_as_uint64(), + * g_udev_device_get_property_as_double(), + * g_udev_device_get_property_as_boolean() and + * g_udev_device_get_property_as_strv(). + * + * To access sysfs attributes for the device, use + * g_udev_device_get_sysfs_attr(), + * g_udev_device_get_sysfs_attr_as_int(), + * g_udev_device_get_sysfs_attr_as_uint64(), + * g_udev_device_get_sysfs_attr_as_double(), + * g_udev_device_get_sysfs_attr_as_boolean() and + * g_udev_device_get_sysfs_attr_as_strv(). + * + * Note that all getters on #GUdevDevice are non-reffing – returned + * values are owned by the object, should not be freed and are only + * valid as long as the object is alive. + * + * By design, #GUdevDevice will not react to changes for a device – it + * only contains a snapshot of information when the #GUdevDevice + * object was created. To work with changes, you typically connect to + * the #GUdevClient::uevent signal on a #GUdevClient and get a new + * #GUdevDevice whenever an event happens. + */ + +struct _GUdevDevicePrivate +{ + struct udev_device *udevice; + + /* computed ondemand and cached */ + gchar **device_file_symlinks; + gchar **property_keys; + gchar **tags; + GHashTable *prop_strvs; + GHashTable *sysfs_attr_strvs; +}; + +G_DEFINE_TYPE (GUdevDevice, g_udev_device, G_TYPE_OBJECT) + +static void +g_udev_device_finalize (GObject *object) +{ + GUdevDevice *device = G_UDEV_DEVICE (object); + + g_strfreev (device->priv->device_file_symlinks); + g_strfreev (device->priv->property_keys); + g_strfreev (device->priv->tags); + + if (device->priv->udevice != NULL) + udev_device_unref (device->priv->udevice); + + if (device->priv->prop_strvs != NULL) + g_hash_table_unref (device->priv->prop_strvs); + + if (device->priv->sysfs_attr_strvs != NULL) + g_hash_table_unref (device->priv->sysfs_attr_strvs); + + if (G_OBJECT_CLASS (g_udev_device_parent_class)->finalize != NULL) + (* G_OBJECT_CLASS (g_udev_device_parent_class)->finalize) (object); +} + +static void +g_udev_device_class_init (GUdevDeviceClass *klass) +{ + GObjectClass *gobject_class = (GObjectClass *) klass; + + gobject_class->finalize = g_udev_device_finalize; + + g_type_class_add_private (klass, sizeof (GUdevDevicePrivate)); +} + +static void +g_udev_device_init (GUdevDevice *device) +{ + device->priv = G_TYPE_INSTANCE_GET_PRIVATE (device, + G_UDEV_TYPE_DEVICE, + GUdevDevicePrivate); +} + + +GUdevDevice * +_g_udev_device_new (struct udev_device *udevice) +{ + GUdevDevice *device; + + device = G_UDEV_DEVICE (g_object_new (G_UDEV_TYPE_DEVICE, NULL)); + device->priv->udevice = udev_device_ref (udevice); + + return device; +} + +/** + * g_udev_device_get_subsystem: + * @device: A #GUdevDevice. + * + * Gets the subsystem for @device. + * + * Returns: The subsystem for @device. + */ +const gchar * +g_udev_device_get_subsystem (GUdevDevice *device) +{ + g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL); + return udev_device_get_subsystem (device->priv->udevice); +} + +/** + * g_udev_device_get_devtype: + * @device: A #GUdevDevice. + * + * Gets the device type for @device. + * + * Returns: The devtype for @device. + */ +const gchar * +g_udev_device_get_devtype (GUdevDevice *device) +{ + g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL); + return udev_device_get_devtype (device->priv->udevice); +} + +/** + * g_udev_device_get_name: + * @device: A #GUdevDevice. + * + * Gets the name of @device, e.g. "sda3". + * + * Returns: The name of @device. + */ +const gchar * +g_udev_device_get_name (GUdevDevice *device) +{ + g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL); + return udev_device_get_sysname (device->priv->udevice); +} + +/** + * g_udev_device_get_number: + * @device: A #GUdevDevice. + * + * Gets the number of @device, e.g. "3" if g_udev_device_get_name() returns "sda3". + * + * Returns: The number of @device. + */ +const gchar * +g_udev_device_get_number (GUdevDevice *device) +{ + g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL); + return udev_device_get_sysnum (device->priv->udevice); +} + +/** + * g_udev_device_get_sysfs_path: + * @device: A #GUdevDevice. + * + * Gets the sysfs path for @device. + * + * Returns: The sysfs path for @device. + */ +const gchar * +g_udev_device_get_sysfs_path (GUdevDevice *device) +{ + g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL); + return udev_device_get_syspath (device->priv->udevice); +} + +/** + * g_udev_device_get_driver: + * @device: A #GUdevDevice. + * + * Gets the name of the driver used for @device. + * + * Returns: The name of the driver for @device or %NULL if unknown. + */ +const gchar * +g_udev_device_get_driver (GUdevDevice *device) +{ + g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL); + return udev_device_get_driver (device->priv->udevice); +} + +/** + * g_udev_device_get_action: + * @device: A #GUdevDevice. + * + * Gets the most recent action (e.g. "add", "remove", "change", etc.) for @device. + * + * Returns: An action string. + */ +const gchar * +g_udev_device_get_action (GUdevDevice *device) +{ + g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL); + return udev_device_get_action (device->priv->udevice); +} + +/** + * g_udev_device_get_seqnum: + * @device: A #GUdevDevice. + * + * Gets the most recent sequence number for @device. + * + * Returns: A sequence number. + */ +guint64 +g_udev_device_get_seqnum (GUdevDevice *device) +{ + g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0); + return udev_device_get_seqnum (device->priv->udevice); +} + +/** + * g_udev_device_get_device_type: + * @device: A #GUdevDevice. + * + * Gets the type of the device file, if any, for @device. + * + * Returns: The device number for @device or #G_UDEV_DEVICE_TYPE_NONE if the device does not have a device file. + */ +GUdevDeviceType +g_udev_device_get_device_type (GUdevDevice *device) +{ + struct stat stat_buf; + const gchar *device_file; + GUdevDeviceType type; + + g_return_val_if_fail (G_UDEV_IS_DEVICE (device), G_UDEV_DEVICE_TYPE_NONE); + + type = G_UDEV_DEVICE_TYPE_NONE; + + /* TODO: would be better to have support for this in libudev... */ + + device_file = g_udev_device_get_device_file (device); + if (device_file == NULL) + goto out; + + if (stat (device_file, &stat_buf) != 0) + goto out; + + if (S_ISBLK (stat_buf.st_mode)) + type = G_UDEV_DEVICE_TYPE_BLOCK; + else if (S_ISCHR (stat_buf.st_mode)) + type = G_UDEV_DEVICE_TYPE_CHAR; + + out: + return type; +} + +/** + * g_udev_device_get_device_number: + * @device: A #GUdevDevice. + * + * Gets the device number, if any, for @device. + * + * Returns: The device number for @device or 0 if unknown. + */ +GUdevDeviceNumber +g_udev_device_get_device_number (GUdevDevice *device) +{ + g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0); + return udev_device_get_devnum (device->priv->udevice); +} + +/** + * g_udev_device_get_device_file: + * @device: A #GUdevDevice. + * + * Gets the device file for @device. + * + * Returns: The device file for @device or %NULL if no device file + * exists. + */ +const gchar * +g_udev_device_get_device_file (GUdevDevice *device) +{ + g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL); + return udev_device_get_devnode (device->priv->udevice); +} + +/** + * g_udev_device_get_device_file_symlinks: + * @device: A #GUdevDevice. + * + * Gets a list of symlinks (in /dev) that points to + * the device file for @device. + * + * Returns: (transfer none) (array zero-terminated=1) (element-type utf8): A %NULL terminated string array of symlinks. This array is owned by @device and should not be freed by the caller. + */ +const gchar * const * +g_udev_device_get_device_file_symlinks (GUdevDevice *device) +{ + struct udev_list_entry *l; + GPtrArray *p; + + g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL); + + if (device->priv->device_file_symlinks != NULL) + goto out; + + p = g_ptr_array_new (); + for (l = udev_device_get_devlinks_list_entry (device->priv->udevice); l != NULL; l = udev_list_entry_get_next (l)) + { + g_ptr_array_add (p, g_strdup (udev_list_entry_get_name (l))); + } + g_ptr_array_add (p, NULL); + device->priv->device_file_symlinks = (gchar **) g_ptr_array_free (p, FALSE); + + out: + return (const gchar * const *) device->priv->device_file_symlinks; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * g_udev_device_get_parent: + * @device: A #GUdevDevice. + * + * Gets the immediate parent of @device, if any. + * + * Returns: (transfer full): A #GUdevDevice or %NULL if @device has no parent. Free with g_object_unref(). + */ +GUdevDevice * +g_udev_device_get_parent (GUdevDevice *device) +{ + GUdevDevice *ret; + struct udev_device *udevice; + + g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL); + + ret = NULL; + + udevice = udev_device_get_parent (device->priv->udevice); + if (udevice == NULL) + goto out; + + ret = _g_udev_device_new (udevice); + + out: + return ret; +} + +/** + * g_udev_device_get_parent_with_subsystem: + * @device: A #GUdevDevice. + * @subsystem: The subsystem of the parent to get. + * @devtype: (allow-none): The devtype of the parent to get or %NULL. + * + * Walks up the chain of parents of @device and returns the first + * device encountered where @subsystem and @devtype matches, if any. + * + * Returns: (transfer full): A #GUdevDevice or %NULL if @device has no parent with @subsystem and @devtype. Free with g_object_unref(). + */ +GUdevDevice * +g_udev_device_get_parent_with_subsystem (GUdevDevice *device, + const gchar *subsystem, + const gchar *devtype) +{ + GUdevDevice *ret; + struct udev_device *udevice; + + g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL); + g_return_val_if_fail (subsystem != NULL, NULL); + + ret = NULL; + + udevice = udev_device_get_parent_with_subsystem_devtype (device->priv->udevice, + subsystem, + devtype); + if (udevice == NULL) + goto out; + + ret = _g_udev_device_new (udevice); + + out: + return ret; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * g_udev_device_get_property_keys: + * @device: A #GUdevDevice. + * + * Gets all keys for properties on @device. + * + * Returns: (transfer none) (array zero-terminated=1) (element-type utf8): A %NULL terminated string array of property keys. This array is owned by @device and should not be freed by the caller. + */ +const gchar* const * +g_udev_device_get_property_keys (GUdevDevice *device) +{ + struct udev_list_entry *l; + GPtrArray *p; + + g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL); + + if (device->priv->property_keys != NULL) + goto out; + + p = g_ptr_array_new (); + for (l = udev_device_get_properties_list_entry (device->priv->udevice); l != NULL; l = udev_list_entry_get_next (l)) + { + g_ptr_array_add (p, g_strdup (udev_list_entry_get_name (l))); + } + g_ptr_array_add (p, NULL); + device->priv->property_keys = (gchar **) g_ptr_array_free (p, FALSE); + + out: + return (const gchar * const *) device->priv->property_keys; +} + + +/** + * g_udev_device_has_property: + * @device: A #GUdevDevice. + * @key: Name of property. + * + * Check if a the property with the given key exists. + * + * Returns: %TRUE only if the value for @key exist. + */ +gboolean +g_udev_device_has_property (GUdevDevice *device, + const gchar *key) +{ + g_return_val_if_fail (G_UDEV_IS_DEVICE (device), FALSE); + g_return_val_if_fail (key != NULL, FALSE); + return udev_device_get_property_value (device->priv->udevice, key) != NULL; +} + +/** + * g_udev_device_get_property: + * @device: A #GUdevDevice. + * @key: Name of property. + * + * Look up the value for @key on @device. + * + * Returns: The value for @key or %NULL if @key doesn't exist on @device. Do not free this string, it is owned by @device. + */ +const gchar * +g_udev_device_get_property (GUdevDevice *device, + const gchar *key) +{ + g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL); + g_return_val_if_fail (key != NULL, NULL); + return udev_device_get_property_value (device->priv->udevice, key); +} + +/** + * g_udev_device_get_property_as_int: + * @device: A #GUdevDevice. + * @key: Name of property. + * + * Look up the value for @key on @device and convert it to an integer + * using strtol(). + * + * Returns: The value for @key or 0 if @key doesn't exist or + * isn't an integer. + */ +gint +g_udev_device_get_property_as_int (GUdevDevice *device, + const gchar *key) +{ + gint result; + const gchar *s; + + g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0); + g_return_val_if_fail (key != NULL, 0); + + result = 0; + s = g_udev_device_get_property (device, key); + if (s == NULL) + goto out; + + result = strtol (s, NULL, 0); +out: + return result; +} + +/** + * g_udev_device_get_property_as_uint64: + * @device: A #GUdevDevice. + * @key: Name of property. + * + * Look up the value for @key on @device and convert it to an unsigned + * 64-bit integer using g_ascii_strtoull(). + * + * Returns: The value for @key or 0 if @key doesn't exist or isn't a + * #guint64. + */ +guint64 +g_udev_device_get_property_as_uint64 (GUdevDevice *device, + const gchar *key) +{ + guint64 result; + const gchar *s; + + g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0); + g_return_val_if_fail (key != NULL, 0); + + result = 0; + s = g_udev_device_get_property (device, key); + if (s == NULL) + goto out; + + result = g_ascii_strtoull (s, NULL, 0); +out: + return result; +} + +/** + * g_udev_device_get_property_as_double: + * @device: A #GUdevDevice. + * @key: Name of property. + * + * Look up the value for @key on @device and convert it to a double + * precision floating point number using strtod(). + * + * Returns: The value for @key or 0.0 if @key doesn't exist or isn't a + * #gdouble. + */ +gdouble +g_udev_device_get_property_as_double (GUdevDevice *device, + const gchar *key) +{ + gdouble result; + const gchar *s; + + g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0.0); + g_return_val_if_fail (key != NULL, 0.0); + + result = 0.0; + s = g_udev_device_get_property (device, key); + if (s == NULL) + goto out; + + result = strtod (s, NULL); +out: + return result; +} + +/** + * g_udev_device_get_property_as_boolean: + * @device: A #GUdevDevice. + * @key: Name of property. + * + * Look up the value for @key on @device and convert it to an + * boolean. This is done by doing a case-insensitive string comparison + * on the string value against "1" and "true". + * + * Returns: The value for @key or %FALSE if @key doesn't exist or + * isn't a #gboolean. + */ +gboolean +g_udev_device_get_property_as_boolean (GUdevDevice *device, + const gchar *key) +{ + gboolean result; + const gchar *s; + + g_return_val_if_fail (G_UDEV_IS_DEVICE (device), FALSE); + g_return_val_if_fail (key != NULL, FALSE); + + result = FALSE; + s = g_udev_device_get_property (device, key); + if (s == NULL) + goto out; + + if (strcmp (s, "1") == 0 || g_ascii_strcasecmp (s, "true") == 0) + result = TRUE; + out: + return result; +} + +static gchar ** +split_at_whitespace (const gchar *s) +{ + gchar **result; + guint n; + guint m; + + result = g_strsplit_set (s, " \v\t\r\n", 0); + + /* remove empty strings, thanks GLib */ + for (n = 0; result[n] != NULL; n++) + { + if (strlen (result[n]) == 0) + { + g_free (result[n]); + for (m = n; result[m] != NULL; m++) + result[m] = result[m + 1]; + n--; + } + } + + return result; +} + +/** + * g_udev_device_get_property_as_strv: + * @device: A #GUdevDevice. + * @key: Name of property. + * + * Look up the value for @key on @device and return the result of + * splitting it into non-empty tokens split at white space (only space + * (' '), form-feed ('\f'), newline ('\n'), carriage return ('\r'), + * horizontal tab ('\t'), and vertical tab ('\v') are considered; the + * locale is not taken into account). + * + * Returns: (transfer none) (array zero-terminated=1) (element-type utf8): The value of @key on @device split into tokens or %NULL if @key doesn't exist. This array is owned by @device and should not be freed by the caller. + */ +const gchar* const * +g_udev_device_get_property_as_strv (GUdevDevice *device, + const gchar *key) +{ + gchar **result; + const gchar *s; + + g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL); + g_return_val_if_fail (key != NULL, NULL); + + if (device->priv->prop_strvs != NULL) + { + result = g_hash_table_lookup (device->priv->prop_strvs, key); + if (result != NULL) + goto out; + } + + result = NULL; + s = g_udev_device_get_property (device, key); + if (s == NULL) + goto out; + + result = split_at_whitespace (s); + if (result == NULL) + goto out; + + if (device->priv->prop_strvs == NULL) + device->priv->prop_strvs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_strfreev); + g_hash_table_insert (device->priv->prop_strvs, g_strdup (key), result); + +out: + return (const gchar* const *) result; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * g_udev_device_get_sysfs_attr: + * @device: A #GUdevDevice. + * @name: Name of the sysfs attribute. + * + * Look up the sysfs attribute with @name on @device. + * + * Returns: The value of the sysfs attribute or %NULL if there is no + * such attribute. Do not free this string, it is owned by @device. + */ +const gchar * +g_udev_device_get_sysfs_attr (GUdevDevice *device, + const gchar *name) +{ + g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL); + g_return_val_if_fail (name != NULL, NULL); + return udev_device_get_sysattr_value (device->priv->udevice, name); +} + +/** + * g_udev_device_get_sysfs_attr_as_int: + * @device: A #GUdevDevice. + * @name: Name of the sysfs attribute. + * + * Look up the sysfs attribute with @name on @device and convert it to an integer + * using strtol(). + * + * Returns: The value of the sysfs attribute or 0 if there is no such + * attribute. + */ +gint +g_udev_device_get_sysfs_attr_as_int (GUdevDevice *device, + const gchar *name) +{ + gint result; + const gchar *s; + + g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0); + g_return_val_if_fail (name != NULL, 0); + + result = 0; + s = g_udev_device_get_sysfs_attr (device, name); + if (s == NULL) + goto out; + + result = strtol (s, NULL, 0); +out: + return result; +} + +/** + * g_udev_device_get_sysfs_attr_as_uint64: + * @device: A #GUdevDevice. + * @name: Name of the sysfs attribute. + * + * Look up the sysfs attribute with @name on @device and convert it to an unsigned + * 64-bit integer using g_ascii_strtoull(). + * + * Returns: The value of the sysfs attribute or 0 if there is no such + * attribute. + */ +guint64 +g_udev_device_get_sysfs_attr_as_uint64 (GUdevDevice *device, + const gchar *name) +{ + guint64 result; + const gchar *s; + + g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0); + g_return_val_if_fail (name != NULL, 0); + + result = 0; + s = g_udev_device_get_sysfs_attr (device, name); + if (s == NULL) + goto out; + + result = g_ascii_strtoull (s, NULL, 0); +out: + return result; +} + +/** + * g_udev_device_get_sysfs_attr_as_double: + * @device: A #GUdevDevice. + * @name: Name of the sysfs attribute. + * + * Look up the sysfs attribute with @name on @device and convert it to a double + * precision floating point number using strtod(). + * + * Returns: The value of the sysfs attribute or 0.0 if there is no such + * attribute. + */ +gdouble +g_udev_device_get_sysfs_attr_as_double (GUdevDevice *device, + const gchar *name) +{ + gdouble result; + const gchar *s; + + g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0.0); + g_return_val_if_fail (name != NULL, 0.0); + + result = 0.0; + s = g_udev_device_get_sysfs_attr (device, name); + if (s == NULL) + goto out; + + result = strtod (s, NULL); +out: + return result; +} + +/** + * g_udev_device_get_sysfs_attr_as_boolean: + * @device: A #GUdevDevice. + * @name: Name of the sysfs attribute. + * + * Look up the sysfs attribute with @name on @device and convert it to an + * boolean. This is done by doing a case-insensitive string comparison + * on the string value against "1" and "true". + * + * Returns: The value of the sysfs attribute or %FALSE if there is no such + * attribute. + */ +gboolean +g_udev_device_get_sysfs_attr_as_boolean (GUdevDevice *device, + const gchar *name) +{ + gboolean result; + const gchar *s; + + g_return_val_if_fail (G_UDEV_IS_DEVICE (device), FALSE); + g_return_val_if_fail (name != NULL, FALSE); + + result = FALSE; + s = g_udev_device_get_sysfs_attr (device, name); + if (s == NULL) + goto out; + + if (strcmp (s, "1") == 0 || g_ascii_strcasecmp (s, "true") == 0) + result = TRUE; + out: + return result; +} + +/** + * g_udev_device_get_sysfs_attr_as_strv: + * @device: A #GUdevDevice. + * @name: Name of the sysfs attribute. + * + * Look up the sysfs attribute with @name on @device and return the result of + * splitting it into non-empty tokens split at white space (only space (' '), + * form-feed ('\f'), newline ('\n'), carriage return ('\r'), horizontal + * tab ('\t'), and vertical tab ('\v') are considered; the locale is + * not taken into account). + * + * Returns: (transfer none) (array zero-terminated=1) (element-type utf8): The value of the sysfs attribute split into tokens or %NULL if there is no such attribute. This array is owned by @device and should not be freed by the caller. + */ +const gchar * const * +g_udev_device_get_sysfs_attr_as_strv (GUdevDevice *device, + const gchar *name) +{ + gchar **result; + const gchar *s; + + g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL); + g_return_val_if_fail (name != NULL, NULL); + + if (device->priv->sysfs_attr_strvs != NULL) + { + result = g_hash_table_lookup (device->priv->sysfs_attr_strvs, name); + if (result != NULL) + goto out; + } + + result = NULL; + s = g_udev_device_get_sysfs_attr (device, name); + if (s == NULL) + goto out; + + result = split_at_whitespace (s); + if (result == NULL) + goto out; + + if (device->priv->sysfs_attr_strvs == NULL) + device->priv->sysfs_attr_strvs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_strfreev); + g_hash_table_insert (device->priv->sysfs_attr_strvs, g_strdup (name), result); + +out: + return (const gchar* const *) result; +} + +/** + * g_udev_device_get_tags: + * @device: A #GUdevDevice. + * + * Gets all tags for @device. + * + * Returns: (transfer none) (array zero-terminated=1) (element-type utf8): A %NULL terminated string array of tags. This array is owned by @device and should not be freed by the caller. + * + * Since: 165 + */ +const gchar* const * +g_udev_device_get_tags (GUdevDevice *device) +{ + struct udev_list_entry *l; + GPtrArray *p; + + g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL); + + if (device->priv->tags != NULL) + goto out; + + p = g_ptr_array_new (); + for (l = udev_device_get_tags_list_entry (device->priv->udevice); l != NULL; l = udev_list_entry_get_next (l)) + { + g_ptr_array_add (p, g_strdup (udev_list_entry_get_name (l))); + } + g_ptr_array_add (p, NULL); + device->priv->tags = (gchar **) g_ptr_array_free (p, FALSE); + + out: + return (const gchar * const *) device->priv->tags; +} + +/** + * g_udev_device_get_is_initialized: + * @device: A #GUdevDevice. + * + * Gets whether @device has been initalized. + * + * Returns: Whether @device has been initialized. + * + * Since: 165 + */ +gboolean +g_udev_device_get_is_initialized (GUdevDevice *device) +{ + g_return_val_if_fail (G_UDEV_IS_DEVICE (device), FALSE); + return udev_device_get_is_initialized (device->priv->udevice); +} + +/** + * g_udev_device_get_usec_since_initialized: + * @device: A #GUdevDevice. + * + * Gets number of micro-seconds since @device was initialized. + * + * This only works for devices with properties in the udev + * database. All other devices return 0. + * + * Returns: Number of micro-seconds since @device was initialized or 0 if unknown. + * + * Since: 165 + */ +guint64 +g_udev_device_get_usec_since_initialized (GUdevDevice *device) +{ + g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0); + return udev_device_get_usec_since_initialized (device->priv->udevice); +} diff --git a/src/gudev/gudevdevice.h b/src/gudev/gudevdevice.h new file mode 100644 index 000000000..457b961c5 --- /dev/null +++ b/src/gudev/gudevdevice.h @@ -0,0 +1,127 @@ +/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * + * Copyright (C) 2008 David Zeuthen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#if !defined (_GUDEV_COMPILATION) && !defined(_GUDEV_INSIDE_GUDEV_H) +#error "Only can be included directly, this file may disappear or change contents." +#endif + +#ifndef __G_UDEV_DEVICE_H__ +#define __G_UDEV_DEVICE_H__ + +#include + +G_BEGIN_DECLS + +#define G_UDEV_TYPE_DEVICE (g_udev_device_get_type ()) +#define G_UDEV_DEVICE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_UDEV_TYPE_DEVICE, GUdevDevice)) +#define G_UDEV_DEVICE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_UDEV_TYPE_DEVICE, GUdevDeviceClass)) +#define G_UDEV_IS_DEVICE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_UDEV_TYPE_DEVICE)) +#define G_UDEV_IS_DEVICE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_UDEV_TYPE_DEVICE)) +#define G_UDEV_DEVICE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_UDEV_TYPE_DEVICE, GUdevDeviceClass)) + +typedef struct _GUdevDeviceClass GUdevDeviceClass; +typedef struct _GUdevDevicePrivate GUdevDevicePrivate; + +/** + * GUdevDevice: + * + * The #GUdevDevice struct is opaque and should not be accessed directly. + */ +struct _GUdevDevice +{ + GObject parent; + + /*< private >*/ + GUdevDevicePrivate *priv; +}; + +/** + * GUdevDeviceClass: + * @parent_class: Parent class. + * + * Class structure for #GUdevDevice. + */ +struct _GUdevDeviceClass +{ + GObjectClass parent_class; + + /*< private >*/ + /* Padding for future expansion */ + void (*reserved1) (void); + void (*reserved2) (void); + void (*reserved3) (void); + void (*reserved4) (void); + void (*reserved5) (void); + void (*reserved6) (void); + void (*reserved7) (void); + void (*reserved8) (void); +}; + +GType g_udev_device_get_type (void) G_GNUC_CONST; +gboolean g_udev_device_get_is_initialized (GUdevDevice *device); +guint64 g_udev_device_get_usec_since_initialized (GUdevDevice *device); +const gchar *g_udev_device_get_subsystem (GUdevDevice *device); +const gchar *g_udev_device_get_devtype (GUdevDevice *device); +const gchar *g_udev_device_get_name (GUdevDevice *device); +const gchar *g_udev_device_get_number (GUdevDevice *device); +const gchar *g_udev_device_get_sysfs_path (GUdevDevice *device); +const gchar *g_udev_device_get_driver (GUdevDevice *device); +const gchar *g_udev_device_get_action (GUdevDevice *device); +guint64 g_udev_device_get_seqnum (GUdevDevice *device); +GUdevDeviceType g_udev_device_get_device_type (GUdevDevice *device); +GUdevDeviceNumber g_udev_device_get_device_number (GUdevDevice *device); +const gchar *g_udev_device_get_device_file (GUdevDevice *device); +const gchar* const *g_udev_device_get_device_file_symlinks (GUdevDevice *device); +GUdevDevice *g_udev_device_get_parent (GUdevDevice *device); +GUdevDevice *g_udev_device_get_parent_with_subsystem (GUdevDevice *device, + const gchar *subsystem, + const gchar *devtype); +const gchar* const *g_udev_device_get_property_keys (GUdevDevice *device); +gboolean g_udev_device_has_property (GUdevDevice *device, + const gchar *key); +const gchar *g_udev_device_get_property (GUdevDevice *device, + const gchar *key); +gint g_udev_device_get_property_as_int (GUdevDevice *device, + const gchar *key); +guint64 g_udev_device_get_property_as_uint64 (GUdevDevice *device, + const gchar *key); +gdouble g_udev_device_get_property_as_double (GUdevDevice *device, + const gchar *key); +gboolean g_udev_device_get_property_as_boolean (GUdevDevice *device, + const gchar *key); +const gchar* const *g_udev_device_get_property_as_strv (GUdevDevice *device, + const gchar *key); + +const gchar *g_udev_device_get_sysfs_attr (GUdevDevice *device, + const gchar *name); +gint g_udev_device_get_sysfs_attr_as_int (GUdevDevice *device, + const gchar *name); +guint64 g_udev_device_get_sysfs_attr_as_uint64 (GUdevDevice *device, + const gchar *name); +gdouble g_udev_device_get_sysfs_attr_as_double (GUdevDevice *device, + const gchar *name); +gboolean g_udev_device_get_sysfs_attr_as_boolean (GUdevDevice *device, + const gchar *name); +const gchar* const *g_udev_device_get_sysfs_attr_as_strv (GUdevDevice *device, + const gchar *name); +const gchar* const *g_udev_device_get_tags (GUdevDevice *device); + +G_END_DECLS + +#endif /* __G_UDEV_DEVICE_H__ */ diff --git a/src/gudev/gudevenumerator.c b/src/gudev/gudevenumerator.c new file mode 100644 index 000000000..1fb309870 --- /dev/null +++ b/src/gudev/gudevenumerator.c @@ -0,0 +1,429 @@ +/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * + * Copyright (C) 2008-2010 David Zeuthen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include "gudevclient.h" +#include "gudevenumerator.h" +#include "gudevdevice.h" +#include "gudevmarshal.h" +#include "gudevprivate.h" + +/** + * SECTION:gudevenumerator + * @short_description: Lookup and sort devices + * + * #GUdevEnumerator is used to lookup and sort devices. + * + * Since: 165 + */ + +struct _GUdevEnumeratorPrivate +{ + GUdevClient *client; + struct udev_enumerate *e; +}; + +enum +{ + PROP_0, + PROP_CLIENT, +}; + +G_DEFINE_TYPE (GUdevEnumerator, g_udev_enumerator, G_TYPE_OBJECT) + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +g_udev_enumerator_finalize (GObject *object) +{ + GUdevEnumerator *enumerator = G_UDEV_ENUMERATOR (object); + + if (enumerator->priv->client != NULL) + { + g_object_unref (enumerator->priv->client); + enumerator->priv->client = NULL; + } + + if (enumerator->priv->e != NULL) + { + udev_enumerate_unref (enumerator->priv->e); + enumerator->priv->e = NULL; + } + + if (G_OBJECT_CLASS (g_udev_enumerator_parent_class)->finalize != NULL) + G_OBJECT_CLASS (g_udev_enumerator_parent_class)->finalize (object); +} + +static void +g_udev_enumerator_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GUdevEnumerator *enumerator = G_UDEV_ENUMERATOR (object); + + switch (prop_id) + { + case PROP_CLIENT: + if (enumerator->priv->client != NULL) + g_object_unref (enumerator->priv->client); + enumerator->priv->client = g_value_dup_object (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +g_udev_enumerator_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GUdevEnumerator *enumerator = G_UDEV_ENUMERATOR (object); + + switch (prop_id) + { + case PROP_CLIENT: + g_value_set_object (value, enumerator->priv->client); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +g_udev_enumerator_constructed (GObject *object) +{ + GUdevEnumerator *enumerator = G_UDEV_ENUMERATOR (object); + + g_assert (G_UDEV_IS_CLIENT (enumerator->priv->client)); + + enumerator->priv->e = udev_enumerate_new (_g_udev_client_get_udev (enumerator->priv->client)); + + if (G_OBJECT_CLASS (g_udev_enumerator_parent_class)->constructed != NULL) + G_OBJECT_CLASS (g_udev_enumerator_parent_class)->constructed (object); +} + +static void +g_udev_enumerator_class_init (GUdevEnumeratorClass *klass) +{ + GObjectClass *gobject_class = (GObjectClass *) klass; + + gobject_class->finalize = g_udev_enumerator_finalize; + gobject_class->set_property = g_udev_enumerator_set_property; + gobject_class->get_property = g_udev_enumerator_get_property; + gobject_class->constructed = g_udev_enumerator_constructed; + + /** + * GUdevEnumerator:client: + * + * The #GUdevClient to enumerate devices from. + * + * Since: 165 + */ + g_object_class_install_property (gobject_class, + PROP_CLIENT, + g_param_spec_object ("client", + "The client to enumerate devices from", + "The client to enumerate devices from", + G_UDEV_TYPE_CLIENT, + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_READWRITE)); + + g_type_class_add_private (klass, sizeof (GUdevEnumeratorPrivate)); +} + +static void +g_udev_enumerator_init (GUdevEnumerator *enumerator) +{ + enumerator->priv = G_TYPE_INSTANCE_GET_PRIVATE (enumerator, + G_UDEV_TYPE_ENUMERATOR, + GUdevEnumeratorPrivate); +} + +/** + * g_udev_enumerator_new: + * @client: A #GUdevClient to enumerate devices from. + * + * Constructs a #GUdevEnumerator object that can be used to enumerate + * and sort devices. Use the add_match_*() and add_nomatch_*() methods + * and execute the query to get a list of devices with + * g_udev_enumerator_execute(). + * + * Returns: A new #GUdevEnumerator object. Free with g_object_unref(). + * + * Since: 165 + */ +GUdevEnumerator * +g_udev_enumerator_new (GUdevClient *client) +{ + g_return_val_if_fail (G_UDEV_IS_CLIENT (client), NULL); + return G_UDEV_ENUMERATOR (g_object_new (G_UDEV_TYPE_ENUMERATOR, "client", client, NULL)); +} + + +/** + * g_udev_enumerator_add_match_subsystem: + * @enumerator: A #GUdevEnumerator. + * @subsystem: Wildcard for subsystem name e.g. 'scsi' or 'a*'. + * + * All returned devices will match the given @subsystem. + * + * Returns: (transfer none): The passed in @enumerator. + * + * Since: 165 + */ +GUdevEnumerator * +g_udev_enumerator_add_match_subsystem (GUdevEnumerator *enumerator, + const gchar *subsystem) +{ + g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL); + g_return_val_if_fail (subsystem != NULL, NULL); + udev_enumerate_add_match_subsystem (enumerator->priv->e, subsystem); + return enumerator; +} + +/** + * g_udev_enumerator_add_nomatch_subsystem: + * @enumerator: A #GUdevEnumerator. + * @subsystem: Wildcard for subsystem name e.g. 'scsi' or 'a*'. + * + * All returned devices will not match the given @subsystem. + * + * Returns: (transfer none): The passed in @enumerator. + * + * Since: 165 + */ +GUdevEnumerator * +g_udev_enumerator_add_nomatch_subsystem (GUdevEnumerator *enumerator, + const gchar *subsystem) +{ + g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL); + g_return_val_if_fail (subsystem != NULL, NULL); + udev_enumerate_add_nomatch_subsystem (enumerator->priv->e, subsystem); + return enumerator; +} + +/** + * g_udev_enumerator_add_match_sysfs_attr: + * @enumerator: A #GUdevEnumerator. + * @name: Wildcard filter for sysfs attribute key. + * @value: Wildcard filter for sysfs attribute value. + * + * All returned devices will have a sysfs attribute matching the given @name and @value. + * + * Returns: (transfer none): The passed in @enumerator. + * + * Since: 165 + */ +GUdevEnumerator * +g_udev_enumerator_add_match_sysfs_attr (GUdevEnumerator *enumerator, + const gchar *name, + const gchar *value) +{ + g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL); + g_return_val_if_fail (name != NULL, NULL); + g_return_val_if_fail (value != NULL, NULL); + udev_enumerate_add_match_sysattr (enumerator->priv->e, name, value); + return enumerator; +} + +/** + * g_udev_enumerator_add_nomatch_sysfs_attr: + * @enumerator: A #GUdevEnumerator. + * @name: Wildcard filter for sysfs attribute key. + * @value: Wildcard filter for sysfs attribute value. + * + * All returned devices will not have a sysfs attribute matching the given @name and @value. + * + * Returns: (transfer none): The passed in @enumerator. + * + * Since: 165 + */ +GUdevEnumerator * +g_udev_enumerator_add_nomatch_sysfs_attr (GUdevEnumerator *enumerator, + const gchar *name, + const gchar *value) +{ + g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL); + g_return_val_if_fail (name != NULL, NULL); + g_return_val_if_fail (value != NULL, NULL); + udev_enumerate_add_nomatch_sysattr (enumerator->priv->e, name, value); + return enumerator; +} + +/** + * g_udev_enumerator_add_match_property: + * @enumerator: A #GUdevEnumerator. + * @name: Wildcard filter for property name. + * @value: Wildcard filter for property value. + * + * All returned devices will have a property matching the given @name and @value. + * + * Returns: (transfer none): The passed in @enumerator. + * + * Since: 165 + */ +GUdevEnumerator * +g_udev_enumerator_add_match_property (GUdevEnumerator *enumerator, + const gchar *name, + const gchar *value) +{ + g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL); + g_return_val_if_fail (name != NULL, NULL); + g_return_val_if_fail (value != NULL, NULL); + udev_enumerate_add_match_property (enumerator->priv->e, name, value); + return enumerator; +} + +/** + * g_udev_enumerator_add_match_name: + * @enumerator: A #GUdevEnumerator. + * @name: Wildcard filter for kernel name e.g. "sda*". + * + * All returned devices will match the given @name. + * + * Returns: (transfer none): The passed in @enumerator. + * + * Since: 165 + */ +GUdevEnumerator * +g_udev_enumerator_add_match_name (GUdevEnumerator *enumerator, + const gchar *name) +{ + g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL); + g_return_val_if_fail (name != NULL, NULL); + udev_enumerate_add_match_sysname (enumerator->priv->e, name); + return enumerator; +} + +/** + * g_udev_enumerator_add_sysfs_path: + * @enumerator: A #GUdevEnumerator. + * @sysfs_path: A sysfs path, e.g. "/sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda" + * + * Add a device to the list of devices, to retrieve it back sorted in dependency order. + * + * Returns: (transfer none): The passed in @enumerator. + * + * Since: 165 + */ +GUdevEnumerator * +g_udev_enumerator_add_sysfs_path (GUdevEnumerator *enumerator, + const gchar *sysfs_path) +{ + g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL); + g_return_val_if_fail (sysfs_path != NULL, NULL); + udev_enumerate_add_syspath (enumerator->priv->e, sysfs_path); + return enumerator; +} + +/** + * g_udev_enumerator_add_match_tag: + * @enumerator: A #GUdevEnumerator. + * @tag: A udev tag e.g. "udev-acl". + * + * All returned devices will match the given @tag. + * + * Returns: (transfer none): The passed in @enumerator. + * + * Since: 165 + */ +GUdevEnumerator * +g_udev_enumerator_add_match_tag (GUdevEnumerator *enumerator, + const gchar *tag) +{ + g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL); + g_return_val_if_fail (tag != NULL, NULL); + udev_enumerate_add_match_tag (enumerator->priv->e, tag); + return enumerator; +} + +/** + * g_udev_enumerator_add_match_is_initialized: + * @enumerator: A #GUdevEnumerator. + * + * All returned devices will be initialized. + * + * Returns: (transfer none): The passed in @enumerator. + * + * Since: 165 + */ +GUdevEnumerator * +g_udev_enumerator_add_match_is_initialized (GUdevEnumerator *enumerator) +{ + g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL); + udev_enumerate_add_match_is_initialized (enumerator->priv->e); + return enumerator; +} + +/** + * g_udev_enumerator_execute: + * @enumerator: A #GUdevEnumerator. + * + * Executes the query in @enumerator. + * + * Returns: (element-type GUdevDevice) (transfer full): A list of #GUdevDevice objects. The caller should free the result by using g_object_unref() on each element in the list and then g_list_free() on the list. + * + * Since: 165 + */ +GList * +g_udev_enumerator_execute (GUdevEnumerator *enumerator) +{ + GList *ret; + struct udev_list_entry *l, *devices; + + g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL); + + ret = NULL; + + /* retrieve the list */ + udev_enumerate_scan_devices (enumerator->priv->e); + + devices = udev_enumerate_get_list_entry (enumerator->priv->e); + for (l = devices; l != NULL; l = udev_list_entry_get_next (l)) + { + struct udev_device *udevice; + GUdevDevice *device; + + udevice = udev_device_new_from_syspath (udev_enumerate_get_udev (enumerator->priv->e), + udev_list_entry_get_name (l)); + if (udevice == NULL) + continue; + + device = _g_udev_device_new (udevice); + udev_device_unref (udevice); + ret = g_list_prepend (ret, device); + } + + ret = g_list_reverse (ret); + + return ret; +} diff --git a/src/gudev/gudevenumerator.h b/src/gudev/gudevenumerator.h new file mode 100644 index 000000000..e1dbcf144 --- /dev/null +++ b/src/gudev/gudevenumerator.h @@ -0,0 +1,106 @@ +/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * + * Copyright (C) 2008-2010 David Zeuthen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#if !defined (_GUDEV_COMPILATION) && !defined(_GUDEV_INSIDE_GUDEV_H) +#error "Only can be included directly, this file may disappear or change contents." +#endif + +#ifndef __G_UDEV_ENUMERATOR_H__ +#define __G_UDEV_ENUMERATOR_H__ + +#include + +G_BEGIN_DECLS + +#define G_UDEV_TYPE_ENUMERATOR (g_udev_enumerator_get_type ()) +#define G_UDEV_ENUMERATOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_UDEV_TYPE_ENUMERATOR, GUdevEnumerator)) +#define G_UDEV_ENUMERATOR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_UDEV_TYPE_ENUMERATOR, GUdevEnumeratorClass)) +#define G_UDEV_IS_ENUMERATOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_UDEV_TYPE_ENUMERATOR)) +#define G_UDEV_IS_ENUMERATOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_UDEV_TYPE_ENUMERATOR)) +#define G_UDEV_ENUMERATOR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_UDEV_TYPE_ENUMERATOR, GUdevEnumeratorClass)) + +typedef struct _GUdevEnumeratorClass GUdevEnumeratorClass; +typedef struct _GUdevEnumeratorPrivate GUdevEnumeratorPrivate; + +/** + * GUdevEnumerator: + * + * The #GUdevEnumerator struct is opaque and should not be accessed directly. + * + * Since: 165 + */ +struct _GUdevEnumerator +{ + GObject parent; + + /*< private >*/ + GUdevEnumeratorPrivate *priv; +}; + +/** + * GUdevEnumeratorClass: + * @parent_class: Parent class. + * + * Class structure for #GUdevEnumerator. + * + * Since: 165 + */ +struct _GUdevEnumeratorClass +{ + GObjectClass parent_class; + + /*< private >*/ + /* Padding for future expansion */ + void (*reserved1) (void); + void (*reserved2) (void); + void (*reserved3) (void); + void (*reserved4) (void); + void (*reserved5) (void); + void (*reserved6) (void); + void (*reserved7) (void); + void (*reserved8) (void); +}; + +GType g_udev_enumerator_get_type (void) G_GNUC_CONST; +GUdevEnumerator *g_udev_enumerator_new (GUdevClient *client); +GUdevEnumerator *g_udev_enumerator_add_match_subsystem (GUdevEnumerator *enumerator, + const gchar *subsystem); +GUdevEnumerator *g_udev_enumerator_add_nomatch_subsystem (GUdevEnumerator *enumerator, + const gchar *subsystem); +GUdevEnumerator *g_udev_enumerator_add_match_sysfs_attr (GUdevEnumerator *enumerator, + const gchar *name, + const gchar *value); +GUdevEnumerator *g_udev_enumerator_add_nomatch_sysfs_attr (GUdevEnumerator *enumerator, + const gchar *name, + const gchar *value); +GUdevEnumerator *g_udev_enumerator_add_match_property (GUdevEnumerator *enumerator, + const gchar *name, + const gchar *value); +GUdevEnumerator *g_udev_enumerator_add_match_name (GUdevEnumerator *enumerator, + const gchar *name); +GUdevEnumerator *g_udev_enumerator_add_match_tag (GUdevEnumerator *enumerator, + const gchar *tag); +GUdevEnumerator *g_udev_enumerator_add_match_is_initialized (GUdevEnumerator *enumerator); +GUdevEnumerator *g_udev_enumerator_add_sysfs_path (GUdevEnumerator *enumerator, + const gchar *sysfs_path); +GList *g_udev_enumerator_execute (GUdevEnumerator *enumerator); + +G_END_DECLS + +#endif /* __G_UDEV_ENUMERATOR_H__ */ diff --git a/src/gudev/gudevenums.h b/src/gudev/gudevenums.h new file mode 100644 index 000000000..467e93bd6 --- /dev/null +++ b/src/gudev/gudevenums.h @@ -0,0 +1,48 @@ +/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * + * Copyright (C) 2008 David Zeuthen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#if !defined (_GUDEV_COMPILATION) && !defined(_GUDEV_INSIDE_GUDEV_H) +#error "Only can be included directly, this file may disappear or change contents." +#endif + +#ifndef __G_UDEV_ENUMS_H__ +#define __G_UDEV_ENUMS_H__ + +#include + +G_BEGIN_DECLS + +/** + * GUdevDeviceType: + * @G_UDEV_DEVICE_TYPE_NONE: Device does not have a device file. + * @G_UDEV_DEVICE_TYPE_BLOCK: Device is a block device. + * @G_UDEV_DEVICE_TYPE_CHAR: Device is a character device. + * + * Enumeration used to specify a the type of a device. + */ +typedef enum +{ + G_UDEV_DEVICE_TYPE_NONE = 0, + G_UDEV_DEVICE_TYPE_BLOCK = 'b', + G_UDEV_DEVICE_TYPE_CHAR = 'c', +} GUdevDeviceType; + +G_END_DECLS + +#endif /* __G_UDEV_ENUMS_H__ */ diff --git a/src/gudev/gudevenumtypes.c.template b/src/gudev/gudevenumtypes.c.template new file mode 100644 index 000000000..fc30b39e2 --- /dev/null +++ b/src/gudev/gudevenumtypes.c.template @@ -0,0 +1,39 @@ +/*** BEGIN file-header ***/ +#include + +/*** END file-header ***/ + +/*** BEGIN file-production ***/ +/* enumerations from "@filename@" */ +/*** END file-production ***/ + +/*** BEGIN value-header ***/ +GType +@enum_name@_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const G@Type@Value values[] = { +/*** END value-header ***/ + +/*** BEGIN value-production ***/ + { @VALUENAME@, "@VALUENAME@", "@valuenick@" }, +/*** END value-production ***/ + +/*** BEGIN value-tail ***/ + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_@type@_register_static (g_intern_static_string ("@EnumName@"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} + +/*** END value-tail ***/ + +/*** BEGIN file-tail ***/ +/*** END file-tail ***/ diff --git a/src/gudev/gudevenumtypes.h.template b/src/gudev/gudevenumtypes.h.template new file mode 100644 index 000000000..d0ab3393e --- /dev/null +++ b/src/gudev/gudevenumtypes.h.template @@ -0,0 +1,24 @@ +/*** BEGIN file-header ***/ +#ifndef __GUDEV_ENUM_TYPES_H__ +#define __GUDEV_ENUM_TYPES_H__ + +#include + +G_BEGIN_DECLS +/*** END file-header ***/ + +/*** BEGIN file-production ***/ + +/* enumerations from "@filename@" */ +/*** END file-production ***/ + +/*** BEGIN value-header ***/ +GType @enum_name@_get_type (void) G_GNUC_CONST; +#define @ENUMPREFIX@_TYPE_@ENUMSHORT@ (@enum_name@_get_type ()) +/*** END value-header ***/ + +/*** BEGIN file-tail ***/ +G_END_DECLS + +#endif /* __GUDEV_ENUM_TYPES_H__ */ +/*** END file-tail ***/ diff --git a/src/gudev/gudevmarshal.list b/src/gudev/gudevmarshal.list new file mode 100644 index 000000000..7e665999e --- /dev/null +++ b/src/gudev/gudevmarshal.list @@ -0,0 +1 @@ +VOID:STRING,OBJECT diff --git a/src/gudev/gudevprivate.h b/src/gudev/gudevprivate.h new file mode 100644 index 000000000..52e272be3 --- /dev/null +++ b/src/gudev/gudevprivate.h @@ -0,0 +1,40 @@ +/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * + * Copyright (C) 2008 David Zeuthen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#if !defined (_GUDEV_COMPILATION) && !defined(_GUDEV_INSIDE_GUDEV_H) +#error "Only can be included directly, this file may disappear or change contents." +#endif + +#ifndef __G_UDEV_PRIVATE_H__ +#define __G_UDEV_PRIVATE_H__ + +#include + +#include + +G_BEGIN_DECLS + +GUdevDevice * +_g_udev_device_new (struct udev_device *udevice); + +struct udev *_g_udev_client_get_udev (GUdevClient *client); + +G_END_DECLS + +#endif /* __G_UDEV_PRIVATE_H__ */ diff --git a/src/gudev/gudevtypes.h b/src/gudev/gudevtypes.h new file mode 100644 index 000000000..e2f688ff2 --- /dev/null +++ b/src/gudev/gudevtypes.h @@ -0,0 +1,50 @@ +/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * + * Copyright (C) 2008 David Zeuthen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#if !defined (_GUDEV_COMPILATION) && !defined(_GUDEV_INSIDE_GUDEV_H) +#error "Only can be included directly, this file may disappear or change contents." +#endif + +#ifndef __G_UDEV_TYPES_H__ +#define __G_UDEV_TYPES_H__ + +#include +#include + +G_BEGIN_DECLS + +typedef struct _GUdevClient GUdevClient; +typedef struct _GUdevDevice GUdevDevice; +typedef struct _GUdevEnumerator GUdevEnumerator; + +/** + * GUdevDeviceNumber: + * + * Corresponds to the standard #dev_t type as defined by POSIX (Until + * bug 584517 is resolved this work-around is needed). + */ +#ifdef _GUDEV_WORK_AROUND_DEV_T_BUG +typedef guint64 GUdevDeviceNumber; /* __UQUAD_TYPE */ +#else +typedef dev_t GUdevDeviceNumber; +#endif + +G_END_DECLS + +#endif /* __G_UDEV_TYPES_H__ */ diff --git a/src/gudev/seed-example-enum.js b/src/gudev/seed-example-enum.js new file mode 100755 index 000000000..66206ad80 --- /dev/null +++ b/src/gudev/seed-example-enum.js @@ -0,0 +1,38 @@ +#!/usr/bin/env seed + +const GLib = imports.gi.GLib; +const GUdev = imports.gi.GUdev; + +function print_device(device) { + print(" initialized: " + device.get_is_initialized()); + print(" usec since initialized: " + device.get_usec_since_initialized()); + print(" subsystem: " + device.get_subsystem()); + print(" devtype: " + device.get_devtype()); + print(" name: " + device.get_name()); + print(" number: " + device.get_number()); + print(" sysfs_path: " + device.get_sysfs_path()); + print(" driver: " + device.get_driver()); + print(" action: " + device.get_action()); + print(" seqnum: " + device.get_seqnum()); + print(" device type: " + device.get_device_type()); + print(" device number: " + device.get_device_number()); + print(" device file: " + device.get_device_file()); + print(" device file symlinks: " + device.get_device_file_symlinks()); + print(" tags: " + device.get_tags()); + var keys = device.get_property_keys(); + for (var n = 0; n < keys.length; n++) { + print(" " + keys[n] + "=" + device.get_property(keys[n])); + } +} + +var client = new GUdev.Client({subsystems: []}); +var enumerator = new GUdev.Enumerator({client: client}); +enumerator.add_match_subsystem('b*') + +var devices = enumerator.execute(); + +for (var n=0; n < devices.length; n++) { + var device = devices[n]; + print_device(device); + print(""); +} diff --git a/src/gudev/seed-example.js b/src/gudev/seed-example.js new file mode 100755 index 000000000..e2ac324d2 --- /dev/null +++ b/src/gudev/seed-example.js @@ -0,0 +1,72 @@ +#!/usr/bin/env seed + +// seed example + +const GLib = imports.gi.GLib; +const GUdev = imports.gi.GUdev; + +function print_device (device) { + print (" subsystem: " + device.get_subsystem ()); + print (" devtype: " + device.get_devtype ()); + print (" name: " + device.get_name ()); + print (" number: " + device.get_number ()); + print (" sysfs_path: " + device.get_sysfs_path ()); + print (" driver: " + device.get_driver ()); + print (" action: " + device.get_action ()); + print (" seqnum: " + device.get_seqnum ()); + print (" device type: " + device.get_device_type ()); + print (" device number: " + device.get_device_number ()); + print (" device file: " + device.get_device_file ()); + print (" device file symlinks: " + device.get_device_file_symlinks ()); + print (" foo: " + device.get_sysfs_attr_as_strv ("stat")); + var keys = device.get_property_keys (); + for (var n = 0; n < keys.length; n++) { + print (" " + keys[n] + "=" + device.get_property (keys[n])); + } +} + +function on_uevent (client, action, device) { + print ("action " + action + " on device " + device.get_sysfs_path()); + print_device (device); + print (""); +} + +var client = new GUdev.Client ({subsystems: ["block", "usb/usb_interface"]}); +client.signal.connect ("uevent", on_uevent); + +var block_devices = client.query_by_subsystem ("block"); +for (var n = 0; n < block_devices.length; n++) { + print ("block device: " + block_devices[n].get_device_file ()); +} + +var d; + +d = client.query_by_device_number (GUdev.DeviceType.BLOCK, 0x0810); +if (d == null) { + print ("query_by_device_number 0x810 -> null"); +} else { + print ("query_by_device_number 0x810 -> " + d.get_device_file ()); + dd = d.get_parent_with_subsystem ("usb", null); + print_device (dd); + print ("--------------------------------------------------------------------------"); + while (d != null) { + print_device (d); + print (""); + d = d.get_parent (); + } +} + +d = client.query_by_sysfs_path ("/sys/block/sda/sda1"); +print ("query_by_sysfs_path (\"/sys/block/sda1\") -> " + d.get_device_file ()); + +d = client.query_by_subsystem_and_name ("block", "sda2"); +print ("query_by_subsystem_and_name (\"block\", \"sda2\") -> " + d.get_device_file ()); + +d = client.query_by_device_file ("/dev/sda"); +print ("query_by_device_file (\"/dev/sda\") -> " + d.get_device_file ()); + +d = client.query_by_device_file ("/dev/block/8:0"); +print ("query_by_device_file (\"/dev/block/8:0\") -> " + d.get_device_file ()); + +var mainloop = GLib.main_loop_new (); +GLib.main_loop_run (mainloop); diff --git a/src/hostname/.gitignore b/src/hostname/.gitignore new file mode 100644 index 000000000..1ff281b23 --- /dev/null +++ b/src/hostname/.gitignore @@ -0,0 +1 @@ +org.freedesktop.hostname1.policy diff --git a/src/hostname/Makefile b/src/hostname/Makefile new file mode 120000 index 000000000..d0b0e8e00 --- /dev/null +++ b/src/hostname/Makefile @@ -0,0 +1 @@ +../Makefile \ No newline at end of file diff --git a/src/hostname/hostnamectl.c b/src/hostname/hostnamectl.c new file mode 100644 index 000000000..ff1f09177 --- /dev/null +++ b/src/hostname/hostnamectl.c @@ -0,0 +1,578 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dbus-common.h" +#include "util.h" +#include "spawn-polkit-agent.h" +#include "build.h" +#include "hwclock.h" +#include "strv.h" +#include "sd-id128.h" +#include "virt.h" + +static enum transport { + TRANSPORT_NORMAL, + TRANSPORT_SSH, + TRANSPORT_POLKIT +} arg_transport = TRANSPORT_NORMAL; +static bool arg_ask_password = true; +static const char *arg_host = NULL; +static bool arg_set_transient = false; +static bool arg_set_pretty = false; +static bool arg_set_static = false; + +static void polkit_agent_open_if_enabled(void) { + + /* Open the polkit agent as a child process if necessary */ + + if (!arg_ask_password) + return; + + polkit_agent_open(); +} + +typedef struct StatusInfo { + const char *hostname; + const char *static_hostname; + const char *pretty_hostname; + const char *icon_name; + const char *chassis; +} StatusInfo; + +static void print_status_info(StatusInfo *i) { + sd_id128_t mid, bid; + int r; + const char *id = NULL; + _cleanup_free_ char *pretty_name = NULL, *cpe_name = NULL; + struct utsname u; + + assert(i); + + printf(" Static hostname: %s\n", + strna(i->static_hostname)); + + if (!streq_ptr(i->hostname, i->static_hostname)) + printf("Transient hostname: %s\n", + strna(i->hostname)); + + printf(" Pretty hostname: %s\n" + " Icon name: %s\n" + " Chassis: %s\n", + strna(i->pretty_hostname), + strna(i->icon_name), + strna(i->chassis)); + + r = sd_id128_get_machine(&mid); + if (r >= 0) + printf(" Machine ID: " SD_ID128_FORMAT_STR "\n", SD_ID128_FORMAT_VAL(mid)); + + r = sd_id128_get_boot(&bid); + if (r >= 0) + printf(" Boot ID: " SD_ID128_FORMAT_STR "\n", SD_ID128_FORMAT_VAL(bid)); + + if (detect_virtualization(&id) > 0) + printf(" Virtualization: %s\n", id); + + r = parse_env_file("/etc/os-release", NEWLINE, + "PRETTY_NAME", &pretty_name, + "CPE_NAME", &cpe_name, + NULL); + + if (!isempty(pretty_name)) + printf(" Operating System: %s\n", pretty_name); + + if (!isempty(cpe_name)) + printf(" CPE OS Name: %s\n", cpe_name); + + assert_se(uname(&u) >= 0); + printf(" Kernel: %s %s\n" + " Architecture: %s\n", u.sysname, u.release, u.machine); + +} + +static int status_property(const char *name, DBusMessageIter *iter, StatusInfo *i) { + assert(name); + assert(iter); + + switch (dbus_message_iter_get_arg_type(iter)) { + + case DBUS_TYPE_STRING: { + const char *s; + + dbus_message_iter_get_basic(iter, &s); + if (!isempty(s)) { + if (streq(name, "Hostname")) + i->hostname = s; + if (streq(name, "StaticHostname")) + i->static_hostname = s; + if (streq(name, "PrettyHostname")) + i->pretty_hostname = s; + if (streq(name, "IconName")) + i->icon_name = s; + if (streq(name, "Chassis")) + i->chassis = s; + } + break; + } + } + + return 0; +} + +static int show_status(DBusConnection *bus, char **args, unsigned n) { + _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; + const char *interface = ""; + int r; + DBusMessageIter iter, sub, sub2, sub3; + StatusInfo info; + + assert(args); + + r = bus_method_call_with_reply( + bus, + "org.freedesktop.hostname1", + "/org/freedesktop/hostname1", + "org.freedesktop.DBus.Properties", + "GetAll", + &reply, + NULL, + DBUS_TYPE_STRING, &interface, + DBUS_TYPE_INVALID); + if (r < 0) + return r; + + if (!dbus_message_iter_init(reply, &iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY || + dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_DICT_ENTRY) { + log_error("Failed to parse reply."); + return -EIO; + } + + zero(info); + dbus_message_iter_recurse(&iter, &sub); + + while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { + const char *name; + + if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_DICT_ENTRY) { + log_error("Failed to parse reply."); + return -EIO; + } + + dbus_message_iter_recurse(&sub, &sub2); + + if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &name, true) < 0) { + log_error("Failed to parse reply."); + return -EIO; + } + + if (dbus_message_iter_get_arg_type(&sub2) != DBUS_TYPE_VARIANT) { + log_error("Failed to parse reply."); + return -EIO; + } + + dbus_message_iter_recurse(&sub2, &sub3); + + r = status_property(name, &sub3, &info); + if (r < 0) { + log_error("Failed to parse reply."); + return r; + } + + dbus_message_iter_next(&sub); + } + + print_status_info(&info); + return 0; +} + +static char* hostname_simplify(char *s) { + char *p, *d; + + for (p = s, d = s; *p; p++) { + if ((*p >= 'a' && *p <= 'z') || + (*p >= '0' && *p <= '9') || + *p == '-' || *p == '_') + *(d++) = *p; + else if (*p >= 'A' && *p <= 'Z') + *(d++) = *p - 'A' + 'a'; + else if (*p == ' ') + *(d++) = '-'; + } + + *d = 0; + + strshorten(s, HOST_NAME_MAX); + return s; +} + +static int set_hostname(DBusConnection *bus, char **args, unsigned n) { + _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; + dbus_bool_t interactive = true; + _cleanup_free_ char *h = NULL; + const char *hostname = args[1]; + int r; + + assert(args); + assert(n == 2); + + polkit_agent_open_if_enabled(); + + if (arg_set_pretty) { + r = bus_method_call_with_reply( + bus, + "org.freedesktop.hostname1", + "/org/freedesktop/hostname1", + "org.freedesktop.hostname1", + "SetPrettyHostname", + &reply, + NULL, + DBUS_TYPE_STRING, &hostname, + DBUS_TYPE_BOOLEAN, &interactive, + DBUS_TYPE_INVALID); + if (r < 0) + return r; + + h = strdup(hostname); + if (!h) + return log_oom(); + + hostname = hostname_simplify(h); + } + + if (arg_set_static) { + r = bus_method_call_with_reply( + bus, + "org.freedesktop.hostname1", + "/org/freedesktop/hostname1", + "org.freedesktop.hostname1", + "SetStaticHostname", + &reply, + NULL, + DBUS_TYPE_STRING, &hostname, + DBUS_TYPE_BOOLEAN, &interactive, + DBUS_TYPE_INVALID); + + if (r < 0) + return r; + } + + if (arg_set_transient) { + r = bus_method_call_with_reply( + bus, + "org.freedesktop.hostname1", + "/org/freedesktop/hostname1", + "org.freedesktop.hostname1", + "SetHostname", + &reply, + NULL, + DBUS_TYPE_STRING, &hostname, + DBUS_TYPE_BOOLEAN, &interactive, + DBUS_TYPE_INVALID); + + if (r < 0) + return r; + } + + return 0; +} + +static int set_icon_name(DBusConnection *bus, char **args, unsigned n) { + _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; + dbus_bool_t interactive = true; + + assert(args); + assert(n == 2); + + polkit_agent_open_if_enabled(); + + return bus_method_call_with_reply( + bus, + "org.freedesktop.hostname1", + "/org/freedesktop/hostname1", + "org.freedesktop.hostname1", + "SetIconName", + &reply, + NULL, + DBUS_TYPE_STRING, &args[1], + DBUS_TYPE_BOOLEAN, &interactive, + DBUS_TYPE_INVALID); +} + +static int set_chassis(DBusConnection *bus, char **args, unsigned n) { + _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; + dbus_bool_t interactive = true; + + assert(args); + assert(n == 2); + + polkit_agent_open_if_enabled(); + + return bus_method_call_with_reply( + bus, + "org.freedesktop.hostname1", + "/org/freedesktop/hostname1", + "org.freedesktop.hostname1", + "SetChassis", + &reply, + NULL, + DBUS_TYPE_STRING, &args[1], + DBUS_TYPE_BOOLEAN, &interactive, + DBUS_TYPE_INVALID); +} + +static int help(void) { + + printf("%s [OPTIONS...] COMMAND ...\n\n" + "Query or change system hostname.\n\n" + " -h --help Show this help\n" + " --version Show package version\n" + " --transient Only set transient hostname\n" + " --static Only set static hostname\n" + " --pretty Only set pretty hostname\n" + " --no-ask-password Do not prompt for password\n" + " -H --host=[USER@]HOST Operate on remote host\n\n" + "Commands:\n" + " status Show current hostname settings\n" + " set-hostname NAME Set system hostname\n" + " set-icon-name NAME Set icon name for host\n" + " set-chassis NAME Set chassis type for host\n", + program_invocation_short_name); + + return 0; +} + +static int parse_argv(int argc, char *argv[]) { + + enum { + ARG_VERSION = 0x100, + ARG_NO_ASK_PASSWORD, + ARG_SET_TRANSIENT, + ARG_SET_STATIC, + ARG_SET_PRETTY + }; + + static const struct option options[] = { + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, ARG_VERSION }, + { "transient", no_argument, NULL, ARG_SET_TRANSIENT }, + { "static", no_argument, NULL, ARG_SET_STATIC }, + { "pretty", no_argument, NULL, ARG_SET_PRETTY }, + { "host", required_argument, NULL, 'H' }, + { "privileged", no_argument, NULL, 'P' }, + { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD }, + { NULL, 0, NULL, 0 } + }; + + int c; + + assert(argc >= 0); + assert(argv); + + while ((c = getopt_long(argc, argv, "hH:P", options, NULL)) >= 0) { + + switch (c) { + + case 'h': + help(); + return 0; + + case ARG_VERSION: + puts(PACKAGE_STRING); + puts(SYSTEMD_FEATURES); + return 0; + + case 'P': + arg_transport = TRANSPORT_POLKIT; + break; + + case 'H': + arg_transport = TRANSPORT_SSH; + arg_host = optarg; + break; + + case ARG_SET_TRANSIENT: + arg_set_transient = true; + break; + + case ARG_SET_PRETTY: + arg_set_pretty = true; + break; + + case ARG_SET_STATIC: + arg_set_static = true; + break; + + case ARG_NO_ASK_PASSWORD: + arg_ask_password = false; + break; + + case '?': + return -EINVAL; + + default: + log_error("Unknown option code %c", c); + return -EINVAL; + } + } + + if (!arg_set_transient && !arg_set_pretty && !arg_set_static) + arg_set_transient = arg_set_pretty = arg_set_static = true; + + return 1; +} + +static int hostnamectl_main(DBusConnection *bus, int argc, char *argv[], DBusError *error) { + + static const struct { + const char* verb; + const enum { + MORE, + LESS, + EQUAL + } argc_cmp; + const int argc; + int (* const dispatch)(DBusConnection *bus, char **args, unsigned n); + } verbs[] = { + { "status", LESS, 1, show_status }, + { "set-hostname", EQUAL, 2, set_hostname }, + { "set-icon-name", EQUAL, 2, set_icon_name }, + { "set-chassis", EQUAL, 2, set_chassis }, + }; + + int left; + unsigned i; + + assert(argc >= 0); + assert(argv); + assert(error); + + left = argc - optind; + + if (left <= 0) + /* Special rule: no arguments means "status" */ + i = 0; + else { + if (streq(argv[optind], "help")) { + help(); + return 0; + } + + for (i = 0; i < ELEMENTSOF(verbs); i++) + if (streq(argv[optind], verbs[i].verb)) + break; + + if (i >= ELEMENTSOF(verbs)) { + log_error("Unknown operation %s", argv[optind]); + return -EINVAL; + } + } + + switch (verbs[i].argc_cmp) { + + case EQUAL: + if (left != verbs[i].argc) { + log_error("Invalid number of arguments."); + return -EINVAL; + } + + break; + + case MORE: + if (left < verbs[i].argc) { + log_error("Too few arguments."); + return -EINVAL; + } + + break; + + case LESS: + if (left > verbs[i].argc) { + log_error("Too many arguments."); + return -EINVAL; + } + + break; + + default: + assert_not_reached("Unknown comparison operator."); + } + + if (!bus) { + log_error("Failed to get D-Bus connection: %s", error->message); + return -EIO; + } + + return verbs[i].dispatch(bus, argv + optind, left); +} + +int main(int argc, char *argv[]) { + int r, retval = EXIT_FAILURE; + DBusConnection *bus = NULL; + DBusError error; + + dbus_error_init(&error); + + setlocale(LC_ALL, ""); + log_parse_environment(); + log_open(); + + r = parse_argv(argc, argv); + if (r < 0) + goto finish; + else if (r == 0) { + retval = EXIT_SUCCESS; + goto finish; + } + + if (arg_transport == TRANSPORT_NORMAL) + bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error); + else if (arg_transport == TRANSPORT_POLKIT) + bus_connect_system_polkit(&bus, &error); + else if (arg_transport == TRANSPORT_SSH) + bus_connect_system_ssh(NULL, arg_host, &bus, &error); + else + assert_not_reached("Uh, invalid transport..."); + + r = hostnamectl_main(bus, argc, argv, &error); + retval = r < 0 ? EXIT_FAILURE : r; + +finish: + if (bus) { + dbus_connection_flush(bus); + dbus_connection_close(bus); + dbus_connection_unref(bus); + } + + dbus_error_free(&error); + dbus_shutdown(); + + return retval; +} diff --git a/src/hostname/hostnamed.c b/src/hostname/hostnamed.c new file mode 100644 index 000000000..92b150bfc --- /dev/null +++ b/src/hostname/hostnamed.c @@ -0,0 +1,737 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +#include + +#include +#include +#include +#include + +#include "util.h" +#include "strv.h" +#include "dbus-common.h" +#include "polkit.h" +#include "def.h" +#include "virt.h" + +#define INTERFACE \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" + +#define INTROSPECTION \ + DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \ + "\n" \ + INTERFACE \ + BUS_PROPERTIES_INTERFACE \ + BUS_INTROSPECTABLE_INTERFACE \ + BUS_PEER_INTERFACE \ + "\n" + +#define INTERFACES_LIST \ + BUS_GENERIC_INTERFACES_LIST \ + "org.freedesktop.hostname1\0" + +const char hostname_interface[] _introspect_("hostname1") = INTERFACE; + +enum { + PROP_HOSTNAME, + PROP_STATIC_HOSTNAME, + PROP_PRETTY_HOSTNAME, + PROP_ICON_NAME, + PROP_CHASSIS, + _PROP_MAX +}; + +static char *data[_PROP_MAX] = { + NULL, + NULL, + NULL, + NULL, + NULL +}; + +static usec_t remain_until = 0; + +static void free_data(void) { + int p; + + for (p = 0; p < _PROP_MAX; p++) { + free(data[p]); + data[p] = NULL; + } +} + +static int read_data(void) { + int r; + + free_data(); + + data[PROP_HOSTNAME] = gethostname_malloc(); + if (!data[PROP_HOSTNAME]) + return -ENOMEM; + + r = read_one_line_file("/etc/hostname", &data[PROP_STATIC_HOSTNAME]); + if (r < 0 && r != -ENOENT) + return r; + + r = parse_env_file("/etc/machine-info", NEWLINE, + "PRETTY_HOSTNAME", &data[PROP_PRETTY_HOSTNAME], + "ICON_NAME", &data[PROP_ICON_NAME], + "CHASSIS", &data[PROP_CHASSIS], + NULL); + if (r < 0 && r != -ENOENT) + return r; + + return 0; +} + +static bool check_nss(void) { + void *dl; + + dl = dlopen("libnss_myhostname.so.2", RTLD_LAZY); + if (dl) { + dlclose(dl); + return true; + } + + return false; +} + +static bool valid_chassis(const char *chassis) { + + assert(chassis); + + return nulstr_contains( + "vm\0" + "container\0" + "desktop\0" + "laptop\0" + "server\0" + "tablet\0" + "handset\0", + chassis); +} + +static const char* fallback_chassis(void) { + int r; + char *type; + unsigned t; + Virtualization v; + + v = detect_virtualization(NULL); + + if (v == VIRTUALIZATION_VM) + return "vm"; + if (v == VIRTUALIZATION_CONTAINER) + return "container"; + + r = read_one_line_file("/sys/firmware/acpi/pm_profile", &type); + if (r < 0) + goto try_dmi; + + r = safe_atou(type, &t); + free(type); + if (r < 0) + goto try_dmi; + + /* We only list the really obvious cases here as the ACPI data + * is not really super reliable. + * + * See the ACPI 5.0 Spec Section 5.2.9.1 for details: + * + * http://www.acpi.info/DOWNLOADS/ACPIspec50.pdf + */ + + switch(t) { + + case 1: + case 3: + case 6: + return "desktop"; + + case 2: + return "laptop"; + + case 4: + case 5: + case 7: + return "server"; + + case 8: + return "tablet"; + } + +try_dmi: + r = read_one_line_file("/sys/class/dmi/id/chassis_type", &type); + if (r < 0) + return NULL; + + r = safe_atou(type, &t); + free(type); + if (r < 0) + return NULL; + + /* We only list the really obvious cases here. The DMI data is + unreliable enough, so let's not do any additional guesswork + on top of that. + + See the SMBIOS Specification 2.7.1 section 7.4.1 for + details about the values listed here: + + http://www.dmtf.org/sites/default/files/standards/documents/DSP0134_2.7.1.pdf + */ + + switch (t) { + + case 0x3: + case 0x4: + case 0x6: + case 0x7: + return "desktop"; + + case 0x8: + case 0x9: + case 0xA: + case 0xE: + return "laptop"; + + case 0xB: + return "handset"; + + case 0x11: + case 0x1C: + return "server"; + } + + return NULL; +} + +static char* fallback_icon_name(void) { + const char *chassis; + + if (!isempty(data[PROP_CHASSIS])) + return strappend("computer-", data[PROP_CHASSIS]); + + chassis = fallback_chassis(); + if (chassis) + return strappend("computer-", chassis); + + return strdup("computer"); +} + +static int write_data_hostname(void) { + const char *hn; + + if (isempty(data[PROP_HOSTNAME])) + hn = "localhost"; + else + hn = data[PROP_HOSTNAME]; + + if (sethostname(hn, strlen(hn)) < 0) + return -errno; + + return 0; +} + +static int write_data_static_hostname(void) { + + if (isempty(data[PROP_STATIC_HOSTNAME])) { + + if (unlink("/etc/hostname") < 0) + return errno == ENOENT ? 0 : -errno; + + return 0; + } + + return write_one_line_file_atomic("/etc/hostname", data[PROP_STATIC_HOSTNAME]); +} + +static int write_data_other(void) { + + static const char * const name[_PROP_MAX] = { + [PROP_PRETTY_HOSTNAME] = "PRETTY_HOSTNAME", + [PROP_ICON_NAME] = "ICON_NAME", + [PROP_CHASSIS] = "CHASSIS" + }; + + char **l = NULL; + int r, p; + + r = load_env_file("/etc/machine-info", &l); + if (r < 0 && r != -ENOENT) + return r; + + for (p = 2; p < _PROP_MAX; p++) { + char *t, **u; + + assert(name[p]); + + if (isempty(data[p])) { + strv_env_unset(l, name[p]); + continue; + } + + if (asprintf(&t, "%s=%s", name[p], strempty(data[p])) < 0) { + strv_free(l); + return -ENOMEM; + } + + u = strv_env_set(l, t); + free(t); + strv_free(l); + + if (!u) + return -ENOMEM; + l = u; + } + + if (strv_isempty(l)) { + + if (unlink("/etc/machine-info") < 0) + return errno == ENOENT ? 0 : -errno; + + return 0; + } + + r = write_env_file("/etc/machine-info", l); + strv_free(l); + + return r; +} + +static int bus_hostname_append_icon_name(DBusMessageIter *i, const char *property, void *userdata) { + const char *name; + _cleanup_free_ char *n = NULL; + + assert(i); + assert(property); + + if (isempty(data[PROP_ICON_NAME])) + name = n = fallback_icon_name(); + else + name = data[PROP_ICON_NAME]; + + return bus_property_append_string(i, property, (void*) name); +} + +static int bus_hostname_append_chassis(DBusMessageIter *i, const char *property, void *userdata) { + const char *name; + + assert(i); + assert(property); + + if (isempty(data[PROP_CHASSIS])) + name = fallback_chassis(); + else + name = data[PROP_CHASSIS]; + + return bus_property_append_string(i, property, (void*) name); +} + +static const BusProperty bus_hostname_properties[] = { + { "Hostname", bus_property_append_string, "s", sizeof(data[0])*PROP_HOSTNAME, true }, + { "StaticHostname", bus_property_append_string, "s", sizeof(data[0])*PROP_STATIC_HOSTNAME, true }, + { "PrettyHostname", bus_property_append_string, "s", sizeof(data[0])*PROP_PRETTY_HOSTNAME, true }, + { "IconName", bus_hostname_append_icon_name, "s", sizeof(data[0])*PROP_ICON_NAME, true }, + { "Chassis", bus_hostname_append_chassis, "s", sizeof(data[0])*PROP_CHASSIS, true }, + { NULL, } +}; + +static const BusBoundProperties bps[] = { + { "org.freedesktop.hostname1", bus_hostname_properties, data }, + { NULL, } +}; + +static DBusHandlerResult hostname_message_handler( + DBusConnection *connection, + DBusMessage *message, + void *userdata) { + + + DBusMessage *reply = NULL, *changed = NULL; + DBusError error; + int r; + + assert(connection); + assert(message); + + dbus_error_init(&error); + + if (dbus_message_is_method_call(message, "org.freedesktop.hostname1", "SetHostname")) { + const char *name; + dbus_bool_t interactive; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_BOOLEAN, &interactive, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + if (isempty(name)) + name = data[PROP_STATIC_HOSTNAME]; + + if (isempty(name)) + name = "localhost"; + + if (!hostname_is_valid(name)) + return bus_send_error_reply(connection, message, NULL, -EINVAL); + + if (!streq_ptr(name, data[PROP_HOSTNAME])) { + char *h; + + r = verify_polkit(connection, message, "org.freedesktop.hostname1.set-hostname", interactive, NULL, &error); + if (r < 0) + return bus_send_error_reply(connection, message, &error, r); + + h = strdup(name); + if (!h) + goto oom; + + free(data[PROP_HOSTNAME]); + data[PROP_HOSTNAME] = h; + + r = write_data_hostname(); + if (r < 0) { + log_error("Failed to set host name: %s", strerror(-r)); + return bus_send_error_reply(connection, message, NULL, r); + } + + log_info("Changed host name to '%s'", strempty(data[PROP_HOSTNAME])); + + changed = bus_properties_changed_new( + "/org/freedesktop/hostname1", + "org.freedesktop.hostname1", + "Hostname\0"); + if (!changed) + goto oom; + } + + } else if (dbus_message_is_method_call(message, "org.freedesktop.hostname1", "SetStaticHostname")) { + const char *name; + dbus_bool_t interactive; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_BOOLEAN, &interactive, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + if (isempty(name)) + name = NULL; + + if (!streq_ptr(name, data[PROP_STATIC_HOSTNAME])) { + + r = verify_polkit(connection, message, "org.freedesktop.hostname1.set-static-hostname", interactive, NULL, &error); + if (r < 0) + return bus_send_error_reply(connection, message, &error, r); + + if (isempty(name)) { + free(data[PROP_STATIC_HOSTNAME]); + data[PROP_STATIC_HOSTNAME] = NULL; + } else { + char *h; + + if (!hostname_is_valid(name)) + return bus_send_error_reply(connection, message, NULL, -EINVAL); + + h = strdup(name); + if (!h) + goto oom; + + free(data[PROP_STATIC_HOSTNAME]); + data[PROP_STATIC_HOSTNAME] = h; + } + + r = write_data_static_hostname(); + if (r < 0) { + log_error("Failed to write static host name: %s", strerror(-r)); + return bus_send_error_reply(connection, message, NULL, r); + } + + log_info("Changed static host name to '%s'", strempty(data[PROP_STATIC_HOSTNAME])); + + changed = bus_properties_changed_new( + "/org/freedesktop/hostname1", + "org.freedesktop.hostname1", + "StaticHostname\0"); + if (!changed) + goto oom; + } + + } else if (dbus_message_is_method_call(message, "org.freedesktop.hostname1", "SetPrettyHostname") || + dbus_message_is_method_call(message, "org.freedesktop.hostname1", "SetIconName") || + dbus_message_is_method_call(message, "org.freedesktop.hostname1", "SetChassis")) { + + const char *name; + dbus_bool_t interactive; + int k; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_BOOLEAN, &interactive, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + if (isempty(name)) + name = NULL; + + k = streq(dbus_message_get_member(message), "SetPrettyHostname") ? PROP_PRETTY_HOSTNAME : + streq(dbus_message_get_member(message), "SetChassis") ? PROP_CHASSIS : PROP_ICON_NAME; + + if (!streq_ptr(name, data[k])) { + + /* Since the pretty hostname should always be + * changed at the same time as the static one, + * use the same policy action for both... */ + + r = verify_polkit(connection, message, k == PROP_PRETTY_HOSTNAME ? + "org.freedesktop.hostname1.set-static-hostname" : + "org.freedesktop.hostname1.set-machine-info", interactive, NULL, &error); + if (r < 0) + return bus_send_error_reply(connection, message, &error, r); + + if (isempty(name)) { + free(data[k]); + data[k] = NULL; + } else { + char *h; + + /* The icon name might ultimately be + * used as file name, so better be + * safe than sorry */ + if (k == PROP_ICON_NAME && !filename_is_safe(name)) + return bus_send_error_reply(connection, message, NULL, -EINVAL); + if (k == PROP_PRETTY_HOSTNAME && !string_is_safe(name)) + return bus_send_error_reply(connection, message, NULL, -EINVAL); + if (k == PROP_CHASSIS && !valid_chassis(name)) + return bus_send_error_reply(connection, message, NULL, -EINVAL); + + h = strdup(name); + if (!h) + goto oom; + + free(data[k]); + data[k] = h; + } + + r = write_data_other(); + if (r < 0) { + log_error("Failed to write machine info: %s", strerror(-r)); + return bus_send_error_reply(connection, message, NULL, r); + } + + log_info("Changed %s to '%s'", + k == PROP_PRETTY_HOSTNAME ? "pretty host name" : + k == PROP_CHASSIS ? "chassis" : "icon name", strempty(data[k])); + + changed = bus_properties_changed_new( + "/org/freedesktop/hostname1", + "org.freedesktop.hostname1", + k == PROP_PRETTY_HOSTNAME ? "PrettyHostname\0" : + k == PROP_CHASSIS ? "Chassis\0" : "IconName\0"); + if (!changed) + goto oom; + } + + } else + return bus_default_message_handler(connection, message, INTROSPECTION, INTERFACES_LIST, bps); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + if (!dbus_connection_send(connection, reply, NULL)) + goto oom; + + dbus_message_unref(reply); + reply = NULL; + + if (changed) { + + if (!dbus_connection_send(connection, changed, NULL)) + goto oom; + + dbus_message_unref(changed); + } + + return DBUS_HANDLER_RESULT_HANDLED; + +oom: + if (reply) + dbus_message_unref(reply); + + if (changed) + dbus_message_unref(changed); + + dbus_error_free(&error); + + return DBUS_HANDLER_RESULT_NEED_MEMORY; +} + +static int connect_bus(DBusConnection **_bus) { + static const DBusObjectPathVTable hostname_vtable = { + .message_function = hostname_message_handler + }; + DBusError error; + DBusConnection *bus = NULL; + int r; + + assert(_bus); + + dbus_error_init(&error); + + bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error); + if (!bus) { + log_error("Failed to get system D-Bus connection: %s", bus_error_message(&error)); + r = -ECONNREFUSED; + goto fail; + } + + dbus_connection_set_exit_on_disconnect(bus, FALSE); + + if (!dbus_connection_register_object_path(bus, "/org/freedesktop/hostname1", &hostname_vtable, NULL) || + !dbus_connection_add_filter(bus, bus_exit_idle_filter, &remain_until, NULL)) { + r = log_oom(); + goto fail; + } + + r = dbus_bus_request_name(bus, "org.freedesktop.hostname1", DBUS_NAME_FLAG_DO_NOT_QUEUE, &error); + if (dbus_error_is_set(&error)) { + log_error("Failed to register name on bus: %s", bus_error_message(&error)); + r = -EEXIST; + goto fail; + } + + if (r != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) { + log_error("Failed to acquire name."); + r = -EEXIST; + goto fail; + } + + if (_bus) + *_bus = bus; + + return 0; + +fail: + dbus_connection_close(bus); + dbus_connection_unref(bus); + + dbus_error_free(&error); + + return r; +} + +int main(int argc, char *argv[]) { + int r; + DBusConnection *bus = NULL; + bool exiting = false; + + log_set_target(LOG_TARGET_AUTO); + log_parse_environment(); + log_open(); + + umask(0022); + + if (argc == 2 && streq(argv[1], "--introspect")) { + fputs(DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE + "\n", stdout); + fputs(hostname_interface, stdout); + fputs("\n", stdout); + return 0; + } + + if (argc != 1) { + log_error("This program takes no arguments."); + r = -EINVAL; + goto finish; + } + + if (!check_nss()) + log_warning("Warning: nss-myhostname is not installed. Changing the local hostname might make it unresolveable. Please install nss-myhostname!"); + + r = read_data(); + if (r < 0) { + log_error("Failed to read hostname data: %s", strerror(-r)); + goto finish; + } + + r = connect_bus(&bus); + if (r < 0) + goto finish; + + remain_until = now(CLOCK_MONOTONIC) + DEFAULT_EXIT_USEC; + for (;;) { + + if (!dbus_connection_read_write_dispatch(bus, exiting ? -1 : (int) (DEFAULT_EXIT_USEC/USEC_PER_MSEC))) + break; + + if (!exiting && remain_until < now(CLOCK_MONOTONIC)) { + exiting = true; + bus_async_unregister_and_exit(bus, "org.freedesktop.hostname1"); + } + } + + r = 0; + +finish: + free_data(); + + if (bus) { + dbus_connection_flush(bus); + dbus_connection_close(bus); + dbus_connection_unref(bus); + } + + return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/src/hostname/org.freedesktop.hostname1.conf b/src/hostname/org.freedesktop.hostname1.conf new file mode 100644 index 000000000..46b4aadc8 --- /dev/null +++ b/src/hostname/org.freedesktop.hostname1.conf @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + diff --git a/src/hostname/org.freedesktop.hostname1.policy.in b/src/hostname/org.freedesktop.hostname1.policy.in new file mode 100644 index 000000000..c32c1d4fd --- /dev/null +++ b/src/hostname/org.freedesktop.hostname1.policy.in @@ -0,0 +1,50 @@ + + + + + + + + The systemd Project + http://www.freedesktop.org/wiki/Software/systemd + + + <_description>Set host name + <_message>Authentication is required to set the local host name. + + auth_admin_keep + auth_admin_keep + auth_admin_keep + + + + + <_description>Set static host name + <_message>Authentication is required to set the statically configured local host name, as well as the pretty host name. + + auth_admin_keep + auth_admin_keep + auth_admin_keep + + org.freedesktop.hostname1.set-hostname org.freedesktop.hostname1.set-machine-info + + + + <_description>Set machine information + <_message>Authentication is required to set local machine information. + + auth_admin_keep + auth_admin_keep + auth_admin_keep + + + + diff --git a/src/hostname/org.freedesktop.hostname1.service b/src/hostname/org.freedesktop.hostname1.service new file mode 100644 index 000000000..6041ed60c --- /dev/null +++ b/src/hostname/org.freedesktop.hostname1.service @@ -0,0 +1,12 @@ +# This file is part of systemd. +# +# 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. + +[D-BUS Service] +Name=org.freedesktop.hostname1 +Exec=/bin/false +User=root +SystemdService=dbus-org.freedesktop.hostname1.service diff --git a/src/initctl/Makefile b/src/initctl/Makefile new file mode 120000 index 000000000..d0b0e8e00 --- /dev/null +++ b/src/initctl/Makefile @@ -0,0 +1 @@ +../Makefile \ No newline at end of file diff --git a/src/initctl/initctl.c b/src/initctl/initctl.c new file mode 100644 index 000000000..0eb008d9e --- /dev/null +++ b/src/initctl/initctl.c @@ -0,0 +1,451 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "util.h" +#include "log.h" +#include "list.h" +#include "initreq.h" +#include "special.h" +#include "dbus-common.h" +#include "def.h" + +#define SERVER_FD_MAX 16 +#define TIMEOUT_MSEC ((int) (DEFAULT_EXIT_USEC/USEC_PER_MSEC)) + +typedef struct Fifo Fifo; + +typedef struct Server { + int epoll_fd; + + LIST_HEAD(Fifo, fifos); + unsigned n_fifos; + + DBusConnection *bus; + + bool quit; +} Server; + +struct Fifo { + Server *server; + + int fd; + + struct init_request buffer; + size_t bytes_read; + + LIST_FIELDS(Fifo, fifo); +}; + +static const char *translate_runlevel(int runlevel, bool *isolate) { + static const struct { + const int runlevel; + const char *special; + bool isolate; + } table[] = { + { '0', SPECIAL_POWEROFF_TARGET, false }, + { '1', SPECIAL_RESCUE_TARGET, true }, + { 's', SPECIAL_RESCUE_TARGET, true }, + { 'S', SPECIAL_RESCUE_TARGET, true }, + { '2', SPECIAL_RUNLEVEL2_TARGET, true }, + { '3', SPECIAL_RUNLEVEL3_TARGET, true }, + { '4', SPECIAL_RUNLEVEL4_TARGET, true }, + { '5', SPECIAL_RUNLEVEL5_TARGET, true }, + { '6', SPECIAL_REBOOT_TARGET, false }, + }; + + unsigned i; + + assert(isolate); + + for (i = 0; i < ELEMENTSOF(table); i++) + if (table[i].runlevel == runlevel) { + *isolate = table[i].isolate; + if (runlevel == '6' && kexec_loaded()) + return SPECIAL_KEXEC_TARGET; + return table[i].special; + } + + return NULL; +} + +static void change_runlevel(Server *s, int runlevel) { + const char *target; + DBusMessage *m = NULL, *reply = NULL; + DBusError error; + const char *mode; + bool isolate = false; + + assert(s); + + dbus_error_init(&error); + + if (!(target = translate_runlevel(runlevel, &isolate))) { + log_warning("Got request for unknown runlevel %c, ignoring.", runlevel); + goto finish; + } + + if (isolate) + mode = "isolate"; + else + mode = "replace"; + + log_debug("Running request %s/start/%s", target, mode); + + if (!(m = dbus_message_new_method_call("org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "StartUnit"))) { + log_error("Could not allocate message."); + goto finish; + } + + if (!dbus_message_append_args(m, + DBUS_TYPE_STRING, &target, + DBUS_TYPE_STRING, &mode, + DBUS_TYPE_INVALID)) { + log_error("Could not attach target and flag information to message."); + goto finish; + } + + if (!(reply = dbus_connection_send_with_reply_and_block(s->bus, m, -1, &error))) { + log_error("Failed to start unit: %s", bus_error_message(&error)); + goto finish; + } + +finish: + if (m) + dbus_message_unref(m); + + if (reply) + dbus_message_unref(reply); + + dbus_error_free(&error); +} + +static void request_process(Server *s, const struct init_request *req) { + assert(s); + assert(req); + + if (req->magic != INIT_MAGIC) { + log_error("Got initctl request with invalid magic. Ignoring."); + return; + } + + switch (req->cmd) { + + case INIT_CMD_RUNLVL: + if (!isprint(req->runlevel)) + log_error("Got invalid runlevel. Ignoring."); + else + switch (req->runlevel) { + + /* we are async anyway, so just use kill for reexec/reload */ + case 'u': + case 'U': + if (kill(1, SIGTERM) < 0) + log_error("kill() failed: %m"); + + /* The bus connection will be + * terminated if PID 1 is reexecuted, + * hence let's just exit here, and + * rely on that we'll be restarted on + * the next request */ + s->quit = true; + break; + + case 'q': + case 'Q': + if (kill(1, SIGHUP) < 0) + log_error("kill() failed: %m"); + break; + + default: + change_runlevel(s, req->runlevel); + } + return; + + case INIT_CMD_POWERFAIL: + case INIT_CMD_POWERFAILNOW: + case INIT_CMD_POWEROK: + log_warning("Received UPS/power initctl request. This is not implemented in systemd. Upgrade your UPS daemon!"); + return; + + case INIT_CMD_CHANGECONS: + log_warning("Received console change initctl request. This is not implemented in systemd."); + return; + + case INIT_CMD_SETENV: + case INIT_CMD_UNSETENV: + log_warning("Received environment initctl request. This is not implemented in systemd."); + return; + + default: + log_warning("Received unknown initctl request. Ignoring."); + return; + } +} + +static int fifo_process(Fifo *f) { + ssize_t l; + + assert(f); + + errno = EIO; + if ((l = read(f->fd, ((uint8_t*) &f->buffer) + f->bytes_read, sizeof(f->buffer) - f->bytes_read)) <= 0) { + + if (errno == EAGAIN) + return 0; + + log_warning("Failed to read from fifo: %s", strerror(errno)); + return -1; + } + + f->bytes_read += l; + assert(f->bytes_read <= sizeof(f->buffer)); + + if (f->bytes_read == sizeof(f->buffer)) { + request_process(f->server, &f->buffer); + f->bytes_read = 0; + } + + return 0; +} + +static void fifo_free(Fifo *f) { + assert(f); + + if (f->server) { + assert(f->server->n_fifos > 0); + f->server->n_fifos--; + LIST_REMOVE(Fifo, fifo, f->server->fifos, f); + } + + if (f->fd >= 0) { + if (f->server) + epoll_ctl(f->server->epoll_fd, EPOLL_CTL_DEL, f->fd, NULL); + + close_nointr_nofail(f->fd); + } + + free(f); +} + +static void server_done(Server *s) { + assert(s); + + while (s->fifos) + fifo_free(s->fifos); + + if (s->epoll_fd >= 0) + close_nointr_nofail(s->epoll_fd); + + if (s->bus) { + dbus_connection_flush(s->bus); + dbus_connection_close(s->bus); + dbus_connection_unref(s->bus); + } +} + +static int server_init(Server *s, unsigned n_sockets) { + int r; + unsigned i; + DBusError error; + + assert(s); + assert(n_sockets > 0); + + dbus_error_init(&error); + + zero(*s); + + if ((s->epoll_fd = epoll_create1(EPOLL_CLOEXEC)) < 0) { + r = -errno; + log_error("Failed to create epoll object: %s", strerror(errno)); + goto fail; + } + + for (i = 0; i < n_sockets; i++) { + struct epoll_event ev; + Fifo *f; + int fd; + + fd = SD_LISTEN_FDS_START+i; + + if ((r = sd_is_fifo(fd, NULL)) < 0) { + log_error("Failed to determine file descriptor type: %s", strerror(-r)); + goto fail; + } + + if (!r) { + log_error("Wrong file descriptor type."); + r = -EINVAL; + goto fail; + } + + if (!(f = new0(Fifo, 1))) { + r = -ENOMEM; + log_error("Failed to create fifo object: %s", strerror(errno)); + goto fail; + } + + f->fd = -1; + + zero(ev); + ev.events = EPOLLIN; + ev.data.ptr = f; + if (epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0) { + r = -errno; + fifo_free(f); + log_error("Failed to add fifo fd to epoll object: %s", strerror(errno)); + goto fail; + } + + f->fd = fd; + LIST_PREPEND(Fifo, fifo, s->fifos, f); + f->server = s; + s->n_fifos ++; + } + + if (bus_connect(DBUS_BUS_SYSTEM, &s->bus, NULL, &error) < 0) { + log_error("Failed to get D-Bus connection: %s", bus_error_message(&error)); + goto fail; + } + + return 0; + +fail: + server_done(s); + + dbus_error_free(&error); + return r; +} + +static int process_event(Server *s, struct epoll_event *ev) { + int r; + Fifo *f; + + assert(s); + + if (!(ev->events & EPOLLIN)) { + log_info("Got invalid event from epoll. (3)"); + return -EIO; + } + + f = (Fifo*) ev->data.ptr; + + if ((r = fifo_process(f)) < 0) { + log_info("Got error on fifo: %s", strerror(-r)); + fifo_free(f); + return r; + } + + return 0; +} + +int main(int argc, char *argv[]) { + Server server; + int r = EXIT_FAILURE, n; + + if (getppid() != 1) { + log_error("This program should be invoked by init only."); + return EXIT_FAILURE; + } + + if (argc > 1) { + log_error("This program does not take arguments."); + return EXIT_FAILURE; + } + + log_set_target(LOG_TARGET_AUTO); + log_parse_environment(); + log_open(); + + umask(0022); + + if ((n = sd_listen_fds(true)) < 0) { + log_error("Failed to read listening file descriptors from environment: %s", strerror(-r)); + return EXIT_FAILURE; + } + + if (n <= 0 || n > SERVER_FD_MAX) { + log_error("No or too many file descriptors passed."); + return EXIT_FAILURE; + } + + if (server_init(&server, (unsigned) n) < 0) + return EXIT_FAILURE; + + log_debug("systemd-initctl running as pid %lu", (unsigned long) getpid()); + + sd_notify(false, + "READY=1\n" + "STATUS=Processing requests..."); + + while (!server.quit) { + struct epoll_event event; + int k; + + if ((k = epoll_wait(server.epoll_fd, + &event, 1, + TIMEOUT_MSEC)) < 0) { + + if (errno == EINTR) + continue; + + log_error("epoll_wait() failed: %s", strerror(errno)); + goto fail; + } + + if (k <= 0) + break; + + if (process_event(&server, &event) < 0) + goto fail; + } + + r = EXIT_SUCCESS; + + log_debug("systemd-initctl stopped as pid %lu", (unsigned long) getpid()); + +fail: + sd_notify(false, + "STATUS=Shutting down..."); + + server_done(&server); + + dbus_shutdown(); + + return r; +} diff --git a/src/journal/.gitignore b/src/journal/.gitignore new file mode 100644 index 000000000..d6a79460c --- /dev/null +++ b/src/journal/.gitignore @@ -0,0 +1,2 @@ +/journald-gperf.c +/libsystemd-journal.pc diff --git a/src/journal/Makefile b/src/journal/Makefile new file mode 120000 index 000000000..d0b0e8e00 --- /dev/null +++ b/src/journal/Makefile @@ -0,0 +1 @@ +../Makefile \ No newline at end of file diff --git a/src/journal/browse.html b/src/journal/browse.html new file mode 100644 index 000000000..3594f70c8 --- /dev/null +++ b/src/journal/browse.html @@ -0,0 +1,544 @@ + + + + Journal + + + + + + + +

+ +
+
+
+
+
+
+ +
+ +      + Only current boot +
+ +
+ +
+ +
+ + + + +      + + +
+ +
+ g: First Page      + ←, k, BACKSPACE: Previous Page      + →, j, SPACE: Next Page      + G: Last Page      + +: More entries      + -: Fewer entries +
+ + + + diff --git a/src/journal/cat.c b/src/journal/cat.c new file mode 100644 index 000000000..a95392ccb --- /dev/null +++ b/src/journal/cat.c @@ -0,0 +1,179 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "util.h" +#include "build.h" + +static char *arg_identifier = NULL; +static int arg_priority = LOG_INFO; +static bool arg_level_prefix = true; + +static int help(void) { + + printf("%s [OPTIONS...] {COMMAND} ...\n\n" + "Execute process with stdout/stderr connected to the journal.\n\n" + " -h --help Show this help\n" + " --version Show package version\n" + " -t --identifier=STRING Set syslog identifier\n" + " -p --priority=PRIORITY Set priority value (0..7)\n" + " --level-prefix=BOOL Control whether level prefix shall be parsed\n", + program_invocation_short_name); + + return 0; +} + +static int parse_argv(int argc, char *argv[]) { + + enum { + ARG_VERSION = 0x100, + ARG_LEVEL_PREFIX + }; + + static const struct option options[] = { + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, ARG_VERSION }, + { "identifier", required_argument, NULL, 't' }, + { "priority", required_argument, NULL, 'p' }, + { "level-prefix", required_argument, NULL, ARG_LEVEL_PREFIX }, + { NULL, 0, NULL, 0 } + }; + + int c; + + assert(argc >= 0); + assert(argv); + + while ((c = getopt_long(argc, argv, "+ht:p:", options, NULL)) >= 0) { + + switch (c) { + + case 'h': + help(); + return 0; + + case ARG_VERSION: + puts(PACKAGE_STRING); + puts(SYSTEMD_FEATURES); + return 0; + + case 't': + free(arg_identifier); + if (isempty(optarg)) + arg_identifier = NULL; + else { + arg_identifier = strdup(optarg); + if (!arg_identifier) + return log_oom(); + } + break; + + case 'p': + arg_priority = log_level_from_string(optarg); + if (arg_priority < 0) { + log_error("Failed to parse priority value."); + return arg_priority; + } + break; + + case ARG_LEVEL_PREFIX: { + int k; + + k = parse_boolean(optarg); + if (k < 0) { + log_error("Failed to parse level prefix value."); + return k; + } + arg_level_prefix = k; + break; + } + + default: + log_error("Unknown option code %c", c); + return -EINVAL; + } + } + + return 1; +} + +int main(int argc, char *argv[]) { + int r, fd = -1, saved_stderr = -1; + + log_parse_environment(); + log_open(); + + r = parse_argv(argc, argv); + if (r <= 0) + goto finish; + + fd = sd_journal_stream_fd(arg_identifier, arg_priority, arg_level_prefix); + if (fd < 0) { + log_error("Failed to create stream fd: %s", strerror(-fd)); + r = fd; + goto finish; + } + + saved_stderr = fcntl(STDERR_FILENO, F_DUPFD_CLOEXEC, 3); + + if (dup3(fd, STDOUT_FILENO, 0) < 0 || + dup3(fd, STDERR_FILENO, 0) < 0) { + log_error("Failed to duplicate fd: %m"); + r = -errno; + goto finish; + } + + if (fd >= 3) + close_nointr_nofail(fd); + + fd = -1; + + if (argc <= optind) + execl("/bin/cat", "/bin/cat", NULL); + else + execvp(argv[optind], argv + optind); + + r = -errno; + + /* Let's try to restore a working stderr, so we can print the error message */ + if (saved_stderr >= 0) + dup3(saved_stderr, STDERR_FILENO, 0); + + log_error("Failed to execute process: %s", strerror(-r)); + +finish: + if (fd >= 0) + close_nointr_nofail(fd); + + if (saved_stderr >= 0) + close_nointr_nofail(saved_stderr); + + return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/src/journal/catalog.c b/src/journal/catalog.c new file mode 100644 index 000000000..3735ad921 --- /dev/null +++ b/src/journal/catalog.c @@ -0,0 +1,593 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include + +#include "util.h" +#include "log.h" +#include "sparse-endian.h" +#include "sd-id128.h" +#include "hashmap.h" +#include "strv.h" +#include "strbuf.h" +#include "conf-files.h" +#include "mkdir.h" +#include "catalog.h" + +static const char * const conf_file_dirs[] = { + "/usr/local/lib/systemd/catalog/", + "/usr/lib/systemd/catalog/", + NULL +}; + +#define CATALOG_SIGNATURE (uint8_t[]) { 'R', 'H', 'H', 'H', 'K', 'S', 'L', 'P' } + +typedef struct CatalogHeader { + uint8_t signature[8]; /* "RHHHKSLP" */ + le32_t compatible_flags; + le32_t incompatible_flags; + le64_t header_size; + le64_t n_items; + le64_t catalog_item_size; +} CatalogHeader; + +typedef struct CatalogItem { + sd_id128_t id; + char language[32]; + le64_t offset; +} CatalogItem; + +static unsigned catalog_hash_func(const void *p) { + const CatalogItem *i = p; + + assert_cc(sizeof(unsigned) == sizeof(uint8_t)*4); + + return (((unsigned) i->id.bytes[0] << 24) | + ((unsigned) i->id.bytes[1] << 16) | + ((unsigned) i->id.bytes[2] << 8) | + ((unsigned) i->id.bytes[3])) ^ + (((unsigned) i->id.bytes[4] << 24) | + ((unsigned) i->id.bytes[5] << 16) | + ((unsigned) i->id.bytes[6] << 8) | + ((unsigned) i->id.bytes[7])) ^ + (((unsigned) i->id.bytes[8] << 24) | + ((unsigned) i->id.bytes[9] << 16) | + ((unsigned) i->id.bytes[10] << 8) | + ((unsigned) i->id.bytes[11])) ^ + (((unsigned) i->id.bytes[12] << 24) | + ((unsigned) i->id.bytes[13] << 16) | + ((unsigned) i->id.bytes[14] << 8) | + ((unsigned) i->id.bytes[15])) ^ + string_hash_func(i->language); +} + +static int catalog_compare_func(const void *a, const void *b) { + const CatalogItem *i = a, *j = b; + unsigned k; + + for (k = 0; k < ELEMENTSOF(j->id.bytes); k++) { + if (i->id.bytes[k] < j->id.bytes[k]) + return -1; + if (i->id.bytes[k] > j->id.bytes[k]) + return 1; + } + + return strncmp(i->language, j->language, sizeof(i->language)); +} + +static int finish_item( + Hashmap *h, + struct strbuf *sb, + sd_id128_t id, + const char *language, + const char *payload) { + + ssize_t offset; + CatalogItem *i; + int r; + + assert(h); + assert(sb); + assert(payload); + + offset = strbuf_add_string(sb, payload, strlen(payload)); + if (offset < 0) + return log_oom(); + + i = new0(CatalogItem, 1); + if (!i) + return log_oom(); + + i->id = id; + strncpy(i->language, language, sizeof(i->language)); + i->offset = htole64((uint64_t) offset); + + r = hashmap_put(h, i, i); + if (r == EEXIST) { + log_warning("Duplicate entry for " SD_ID128_FORMAT_STR ".%s, ignoring.", SD_ID128_FORMAT_VAL(id), language ? language : "C"); + free(i); + return 0; + } + + return 0; +} + +static int import_file(Hashmap *h, struct strbuf *sb, const char *path) { + _cleanup_fclose_ FILE *f = NULL; + _cleanup_free_ char *payload = NULL; + unsigned n = 0; + sd_id128_t id; + char language[32]; + bool got_id = false, empty_line = true; + int r; + + assert(h); + assert(sb); + assert(path); + + f = fopen(path, "re"); + if (!f) { + log_error("Failed to open file %s: %m", path); + return -errno; + } + + for (;;) { + char line[LINE_MAX]; + size_t a, b, c; + char *t; + + if (!fgets(line, sizeof(line), f)) { + if (feof(f)) + break; + + log_error("Failed to read file %s: %m", path); + return -errno; + } + + n++; + + truncate_nl(line); + + if (line[0] == 0) { + empty_line = true; + continue; + } + + if (strchr(COMMENTS, line[0])) + continue; + + if (empty_line && + strlen(line) >= 2+1+32 && + line[0] == '-' && + line[1] == '-' && + line[2] == ' ' && + (line[2+1+32] == ' ' || line[2+1+32] == 0)) { + + bool with_language; + sd_id128_t jd; + + /* New entry */ + + with_language = line[2+1+32] != 0; + line[2+1+32] = 0; + + if (sd_id128_from_string(line + 2 + 1, &jd) >= 0) { + + if (got_id) { + r = finish_item(h, sb, id, language, payload); + if (r < 0) + return r; + } + + if (with_language) { + t = strstrip(line + 2 + 1 + 32 + 1); + + c = strlen(t); + if (c <= 0) { + log_error("[%s:%u] Language too short.", path, n); + return -EINVAL; + } + if (c > sizeof(language)) { + log_error("[%s:%u] language too long.", path, n); + return -EINVAL; + } + + strncpy(language, t, sizeof(language)); + } else + zero(language); + + got_id = true; + empty_line = false; + id = jd; + + if (payload) + payload[0] = 0; + + continue; + } + } + + /* Payload */ + if (!got_id) { + log_error("[%s:%u] Got payload before ID.", path, n); + return -EINVAL; + } + + a = payload ? strlen(payload) : 0; + b = strlen(line); + + c = a + (empty_line ? 1 : 0) + b + 1 + 1; + t = realloc(payload, c); + if (!t) + return log_oom(); + + if (empty_line) { + t[a] = '\n'; + memcpy(t + a + 1, line, b); + t[a+b+1] = '\n'; + t[a+b+2] = 0; + } else { + memcpy(t + a, line, b); + t[a+b] = '\n'; + t[a+b+1] = 0; + } + + payload = t; + empty_line = false; + } + + if (got_id) { + r = finish_item(h, sb, id, language, payload); + if (r < 0) + return r; + } + + return 0; +} + +#define CATALOG_DATABASE CATALOG_PATH "/database" + +int catalog_update(void) { + _cleanup_strv_free_ char **files = NULL; + _cleanup_fclose_ FILE *w = NULL; + _cleanup_free_ char *p = NULL; + char **f; + Hashmap *h; + struct strbuf *sb = NULL; + _cleanup_free_ CatalogItem *items = NULL; + CatalogItem *i; + CatalogHeader header; + size_t k; + Iterator j; + unsigned n; + int r; + + h = hashmap_new(catalog_hash_func, catalog_compare_func); + if (!h) + return -ENOMEM; + + sb = strbuf_new(); + if (!sb) { + r = log_oom(); + goto finish; + } + + r = conf_files_list_strv(&files, ".catalog", (const char **) conf_file_dirs); + if (r < 0) { + log_error("Failed to get catalog files: %s", strerror(-r)); + goto finish; + } + + STRV_FOREACH(f, files) { + log_debug("reading file '%s'", *f); + import_file(h, sb, *f); + } + + if (hashmap_size(h) <= 0) { + log_info("No items in catalog."); + r = 0; + goto finish; + } else + log_debug("Found %u items in catalog.", hashmap_size(h)); + + strbuf_complete(sb); + + items = new(CatalogItem, hashmap_size(h)); + if (!items) { + r = log_oom(); + goto finish; + } + + n = 0; + HASHMAP_FOREACH(i, h, j) { + log_debug("Found " SD_ID128_FORMAT_STR ", language %s", SD_ID128_FORMAT_VAL(i->id), isempty(i->language) ? "C" : i->language); + items[n++] = *i; + } + + assert(n == hashmap_size(h)); + qsort(items, n, sizeof(CatalogItem), catalog_compare_func); + + r = mkdir_p(CATALOG_PATH, 0775); + if (r < 0) { + log_error("Recursive mkdir %s: %s", CATALOG_PATH, strerror(-r)); + goto finish; + } + + r = fopen_temporary(CATALOG_DATABASE, &w, &p); + if (r < 0) { + log_error("Failed to open database for writing: %s: %s", + CATALOG_DATABASE, strerror(-r)); + goto finish; + } + + zero(header); + memcpy(header.signature, CATALOG_SIGNATURE, sizeof(header.signature)); + header.header_size = htole64(ALIGN_TO(sizeof(CatalogHeader), 8)); + header.catalog_item_size = htole64(sizeof(CatalogItem)); + header.n_items = htole64(hashmap_size(h)); + + k = fwrite(&header, 1, sizeof(header), w); + if (k != sizeof(header)) { + log_error("%s: failed to write header.", p); + goto finish; + } + + k = fwrite(items, 1, n * sizeof(CatalogItem), w); + if (k != n * sizeof(CatalogItem)) { + log_error("%s: failed to write database.", p); + goto finish; + } + + k = fwrite(sb->buf, 1, sb->len, w); + if (k != sb->len) { + log_error("%s: failed to write strings.", p); + goto finish; + } + + fflush(w); + + if (ferror(w)) { + log_error("%s: failed to write database.", p); + goto finish; + } + + fchmod(fileno(w), 0644); + + if (rename(p, CATALOG_DATABASE) < 0) { + log_error("rename (%s -> %s) failed: %m", p, CATALOG_DATABASE); + r = -errno; + goto finish; + } + + log_debug("%s: wrote %u items, with %zu bytes of strings, %ld total size.", + CATALOG_DATABASE, n, sb->len, ftell(w)); + + free(p); + p = NULL; + + r = 0; + +finish: + hashmap_free_free(h); + + if (sb) + strbuf_cleanup(sb); + + if (p) + unlink(p); + + return r; +} + +static int open_mmap(int *_fd, struct stat *_st, void **_p) { + const CatalogHeader *h; + int fd; + void *p; + struct stat st; + + assert(_fd); + assert(_st); + assert(_p); + + fd = open(CATALOG_DATABASE, O_RDONLY|O_CLOEXEC); + if (fd < 0) + return -errno; + + if (fstat(fd, &st) < 0) { + close_nointr_nofail(fd); + return -errno; + } + + if (st.st_size < (off_t) sizeof(CatalogHeader)) { + close_nointr_nofail(fd); + return -EINVAL; + } + + p = mmap(NULL, PAGE_ALIGN(st.st_size), PROT_READ, MAP_SHARED, fd, 0); + if (p == MAP_FAILED) { + close_nointr_nofail(fd); + return -errno; + } + + h = p; + if (memcmp(h->signature, CATALOG_SIGNATURE, sizeof(h->signature)) != 0 || + le64toh(h->header_size) < sizeof(CatalogHeader) || + le64toh(h->catalog_item_size) < sizeof(CatalogItem) || + h->incompatible_flags != 0 || + le64toh(h->n_items) <= 0 || + st.st_size < (off_t) (le64toh(h->header_size) + le64toh(h->catalog_item_size) * le64toh(h->n_items))) { + close_nointr_nofail(fd); + munmap(p, st.st_size); + return -EBADMSG; + } + + *_fd = fd; + *_st = st; + *_p = p; + + return 0; +} + +static const char *find_id(void *p, sd_id128_t id) { + CatalogItem key, *f = NULL; + const CatalogHeader *h = p; + const char *loc; + + zero(key); + key.id = id; + + loc = setlocale(LC_MESSAGES, NULL); + if (loc && loc[0] && !streq(loc, "C") && !streq(loc, "POSIX")) { + strncpy(key.language, loc, sizeof(key.language)); + key.language[strcspn(key.language, ".@")] = 0; + + f = bsearch(&key, (const uint8_t*) p + le64toh(h->header_size), le64toh(h->n_items), le64toh(h->catalog_item_size), catalog_compare_func); + if (!f) { + char *e; + + e = strchr(key.language, '_'); + if (e) { + *e = 0; + f = bsearch(&key, (const uint8_t*) p + le64toh(h->header_size), le64toh(h->n_items), le64toh(h->catalog_item_size), catalog_compare_func); + } + } + } + + if (!f) { + zero(key.language); + f = bsearch(&key, (const uint8_t*) p + le64toh(h->header_size), le64toh(h->n_items), le64toh(h->catalog_item_size), catalog_compare_func); + } + + if (!f) + return NULL; + + return (const char*) p + + le64toh(h->header_size) + + le64toh(h->n_items) * le64toh(h->catalog_item_size) + + le64toh(f->offset); +} + +int catalog_get(sd_id128_t id, char **_text) { + _cleanup_close_ int fd = -1; + void *p = NULL; + struct stat st; + char *text = NULL; + int r; + const char *s; + + assert(_text); + + r = open_mmap(&fd, &st, &p); + if (r < 0) + return r; + + s = find_id(p, id); + if (!s) { + r = -ENOENT; + goto finish; + } + + text = strdup(s); + if (!text) { + r = -ENOMEM; + goto finish; + } + + *_text = text; + r = 0; + +finish: + if (p) + munmap(p, st.st_size); + + return r; +} + +static char *find_header(const char *s, const char *header) { + + for (;;) { + const char *v, *e; + + v = startswith(s, header); + if (v) { + v += strspn(v, WHITESPACE); + return strndup(v, strcspn(v, NEWLINE)); + } + + /* End of text */ + e = strchr(s, '\n'); + if (!e) + return NULL; + + /* End of header */ + if (e == s) + return NULL; + + s = e + 1; + } +} + +int catalog_list(FILE *f) { + _cleanup_close_ int fd = -1; + void *p = NULL; + struct stat st; + const CatalogHeader *h; + const CatalogItem *items; + int r; + unsigned n; + sd_id128_t last_id; + bool last_id_set = false; + + r = open_mmap(&fd, &st, &p); + if (r < 0) + return r; + + h = p; + items = (const CatalogItem*) ((const uint8_t*) p + le64toh(h->header_size)); + + for (n = 0; n < le64toh(h->n_items); n++) { + const char *s; + _cleanup_free_ char *subject = NULL, *defined_by = NULL; + + if (last_id_set && sd_id128_equal(last_id, items[n].id)) + continue; + + assert_se(s = find_id(p, items[n].id)); + + subject = find_header(s, "Subject:"); + defined_by = find_header(s, "Defined-By:"); + + fprintf(f, SD_ID128_FORMAT_STR " %s: %s\n", SD_ID128_FORMAT_VAL(items[n].id), strna(defined_by), strna(subject)); + + last_id_set = true; + last_id = items[n].id; + } + + munmap(p, st.st_size); + + return 0; +} diff --git a/src/journal/catalog.h b/src/journal/catalog.h new file mode 100644 index 000000000..9add773c9 --- /dev/null +++ b/src/journal/catalog.h @@ -0,0 +1,28 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + +#include "sd-id128.h" + +int catalog_update(void); +int catalog_get(sd_id128_t id, char **data); +int catalog_list(FILE *f); diff --git a/src/journal/compress.c b/src/journal/compress.c new file mode 100644 index 000000000..a4427be75 --- /dev/null +++ b/src/journal/compress.c @@ -0,0 +1,216 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +#include +#include +#include +#include + +#include "macro.h" +#include "compress.h" + +bool compress_blob(const void *src, uint64_t src_size, void *dst, uint64_t *dst_size) { + lzma_stream s = LZMA_STREAM_INIT; + lzma_ret ret; + bool b = false; + + assert(src); + assert(src_size > 0); + assert(dst); + assert(dst_size); + + /* Returns false if we couldn't compress the data or the + * compressed result is longer than the original */ + + ret = lzma_easy_encoder(&s, LZMA_PRESET_DEFAULT, LZMA_CHECK_NONE); + if (ret != LZMA_OK) + return false; + + s.next_in = src; + s.avail_in = src_size; + s.next_out = dst; + s.avail_out = src_size; + + /* Does it fit? */ + if (lzma_code(&s, LZMA_FINISH) != LZMA_STREAM_END) + goto fail; + + /* Is it actually shorter? */ + if (s.avail_out == 0) + goto fail; + + *dst_size = src_size - s.avail_out; + b = true; + +fail: + lzma_end(&s); + + return b; +} + +bool uncompress_blob(const void *src, uint64_t src_size, + void **dst, uint64_t *dst_alloc_size, uint64_t* dst_size, uint64_t dst_max) { + + lzma_stream s = LZMA_STREAM_INIT; + lzma_ret ret; + uint64_t space; + bool b = false; + + assert(src); + assert(src_size > 0); + assert(dst); + assert(dst_alloc_size); + assert(dst_size); + assert(*dst_alloc_size == 0 || *dst); + + ret = lzma_stream_decoder(&s, UINT64_MAX, 0); + if (ret != LZMA_OK) + return false; + + if (*dst_alloc_size <= src_size) { + void *p; + + p = realloc(*dst, src_size*2); + if (!p) + return false; + + *dst = p; + *dst_alloc_size = src_size*2; + } + + s.next_in = src; + s.avail_in = src_size; + + s.next_out = *dst; + space = dst_max > 0 ? MIN(*dst_alloc_size, dst_max) : *dst_alloc_size; + s.avail_out = space; + + for (;;) { + void *p; + + ret = lzma_code(&s, LZMA_FINISH); + + if (ret == LZMA_STREAM_END) + break; + + if (ret != LZMA_OK) + goto fail; + + if (dst_max > 0 && (space - s.avail_out) >= dst_max) + break; + + p = realloc(*dst, space*2); + if (!p) + goto fail; + + s.next_out = (uint8_t*) p + ((uint8_t*) s.next_out - (uint8_t*) *dst); + s.avail_out += space; + + space *= 2; + + *dst = p; + *dst_alloc_size = space; + } + + *dst_size = space - s.avail_out; + b = true; + +fail: + lzma_end(&s); + + return b; +} + +bool uncompress_startswith(const void *src, uint64_t src_size, + void **buffer, uint64_t *buffer_size, + const void *prefix, uint64_t prefix_len, + uint8_t extra) { + + lzma_stream s = LZMA_STREAM_INIT; + lzma_ret ret; + bool b = false; + + /* Checks whether the uncompressed blob starts with the + * mentioned prefix. The byte extra needs to follow the + * prefix */ + + assert(src); + assert(src_size > 0); + assert(buffer); + assert(buffer_size); + assert(prefix); + assert(*buffer_size == 0 || *buffer); + + ret = lzma_stream_decoder(&s, UINT64_MAX, 0); + if (ret != LZMA_OK) + return false; + + if (*buffer_size <= prefix_len) { + void *p; + + p = realloc(*buffer, prefix_len*2); + if (!p) + return false; + + *buffer = p; + *buffer_size = prefix_len*2; + } + + s.next_in = src; + s.avail_in = src_size; + + s.next_out = *buffer; + s.avail_out = *buffer_size; + + for (;;) { + void *p; + + ret = lzma_code(&s, LZMA_FINISH); + + if (ret != LZMA_STREAM_END && ret != LZMA_OK) + goto fail; + + if ((*buffer_size - s.avail_out > prefix_len) && + memcmp(*buffer, prefix, prefix_len) == 0 && + ((const uint8_t*) *buffer)[prefix_len] == extra) + break; + + if (ret == LZMA_STREAM_END) + goto fail; + + p = realloc(*buffer, *buffer_size*2); + if (!p) + goto fail; + + s.next_out = (uint8_t*) p + ((uint8_t*) s.next_out - (uint8_t*) *buffer); + s.avail_out += *buffer_size; + + *buffer = p; + *buffer_size *= 2; + } + + b = true; + +fail: + lzma_end(&s); + + return b; +} diff --git a/src/journal/compress.h b/src/journal/compress.h new file mode 100644 index 000000000..2b87e73a2 --- /dev/null +++ b/src/journal/compress.h @@ -0,0 +1,35 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +#include +#include + +bool compress_blob(const void *src, uint64_t src_size, void *dst, uint64_t *dst_size); + +bool uncompress_blob(const void *src, uint64_t src_size, + void **dst, uint64_t *dst_alloc_size, uint64_t* dst_size, uint64_t dst_max); + +bool uncompress_startswith(const void *src, uint64_t src_size, + void **buffer, uint64_t *buffer_size, + const void *prefix, uint64_t prefix_len, + uint8_t extra); diff --git a/src/journal/coredump.c b/src/journal/coredump.c new file mode 100644 index 000000000..a507fc65f --- /dev/null +++ b/src/journal/coredump.c @@ -0,0 +1,278 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + +#include +#include +#include +#include + +#include + +#ifdef HAVE_LOGIND +#include +#endif + +#include "log.h" +#include "util.h" +#include "mkdir.h" +#include "special.h" +#include "cgroup-util.h" + +#define COREDUMP_MAX (24*1024*1024) + +enum { + ARG_PID = 1, + ARG_UID, + ARG_GID, + ARG_SIGNAL, + ARG_TIMESTAMP, + ARG_COMM, + _ARG_MAX +}; + +static int divert_coredump(void) { + FILE *f; + int r; + + log_info("Detected coredump of the journal daemon itself, diverting coredump to /var/lib/systemd/coredump/."); + + mkdir_p_label("/var/lib/systemd/coredump", 0755); + + f = fopen("/var/lib/systemd/coredump/core.systemd-journald", "we"); + if (!f) { + log_error("Failed to create coredump file: %m"); + return -errno; + } + + for (;;) { + uint8_t buffer[4096]; + size_t l, q; + + l = fread(buffer, 1, sizeof(buffer), stdin); + if (l <= 0) { + if (ferror(f)) { + log_error("Failed to read coredump: %m"); + r = -errno; + goto finish; + } + + r = 0; + break; + } + + q = fwrite(buffer, 1, l, f); + if (q != l) { + log_error("Failed to write coredump: %m"); + r = -errno; + goto finish; + } + } + + fflush(f); + + if (ferror(f)) { + log_error("Failed to write coredump: %m"); + r = -errno; + } + +finish: + fclose(f); + return r; +} + +int main(int argc, char* argv[]) { + int r, j = 0; + char *p = NULL; + ssize_t n; + pid_t pid; + uid_t uid; + gid_t gid; + struct iovec iovec[14]; + char *core_pid = NULL, *core_uid = NULL, *core_gid = NULL, *core_signal = NULL, + *core_timestamp = NULL, *core_comm = NULL, *core_exe = NULL, *core_unit = NULL, + *core_session = NULL, *core_message = NULL, *core_cmdline = NULL, *t; + + prctl(PR_SET_DUMPABLE, 0); + + if (argc != _ARG_MAX) { + log_set_target(LOG_TARGET_JOURNAL_OR_KMSG); + log_open(); + + log_error("Invalid number of arguments passed from kernel."); + r = -EINVAL; + goto finish; + } + + r = parse_pid(argv[ARG_PID], &pid); + if (r < 0) { + log_set_target(LOG_TARGET_JOURNAL_OR_KMSG); + log_open(); + + log_error("Failed to parse PID."); + goto finish; + } + + if (cg_pid_get_unit(pid, &t) >= 0) { + + if (streq(t, SPECIAL_JOURNALD_SERVICE)) { + /* Make sure we don't make use of the journal, + * if it's the journal which is crashing */ + log_set_target(LOG_TARGET_KMSG); + log_open(); + + r = divert_coredump(); + goto finish; + } + + core_unit = strappend("COREDUMP_UNIT=", t); + free(t); + + if (core_unit) + IOVEC_SET_STRING(iovec[j++], core_unit); + } + + /* OK, now we know it's not the journal, hence make use of + * it */ + log_set_target(LOG_TARGET_JOURNAL_OR_KMSG); + log_open(); + + r = parse_uid(argv[ARG_UID], &uid); + if (r < 0) { + log_error("Failed to parse UID."); + goto finish; + } + + r = parse_gid(argv[ARG_GID], &gid); + if (r < 0) { + log_error("Failed to parse GID."); + goto finish; + } + + core_pid = strappend("COREDUMP_PID=", argv[ARG_PID]); + if (core_pid) + IOVEC_SET_STRING(iovec[j++], core_pid); + + core_uid = strappend("COREDUMP_UID=", argv[ARG_UID]); + if (core_uid) + IOVEC_SET_STRING(iovec[j++], core_uid); + + core_gid = strappend("COREDUMP_GID=", argv[ARG_GID]); + if (core_gid) + IOVEC_SET_STRING(iovec[j++], core_gid); + + core_signal = strappend("COREDUMP_SIGNAL=", argv[ARG_SIGNAL]); + if (core_signal) + IOVEC_SET_STRING(iovec[j++], core_signal); + + core_comm = strappend("COREDUMP_COMM=", argv[ARG_COMM]); + if (core_comm) + IOVEC_SET_STRING(iovec[j++], core_comm); + +#ifdef HAVE_LOGIND + if (sd_pid_get_session(pid, &t) >= 0) { + core_session = strappend("COREDUMP_SESSION=", t); + free(t); + + if (core_session) + IOVEC_SET_STRING(iovec[j++], core_session); + } + +#endif + + if (get_process_exe(pid, &t) >= 0) { + core_exe = strappend("COREDUMP_EXE=", t); + free(t); + + if (core_exe) + IOVEC_SET_STRING(iovec[j++], core_exe); + } + + if (get_process_cmdline(pid, LINE_MAX, false, &t) >= 0) { + core_cmdline = strappend("COREDUMP_CMDLINE=", t); + free(t); + + if (core_cmdline) + IOVEC_SET_STRING(iovec[j++], core_cmdline); + } + + core_timestamp = strjoin("COREDUMP_TIMESTAMP=", argv[ARG_TIMESTAMP], "000000", NULL); + if (core_timestamp) + IOVEC_SET_STRING(iovec[j++], core_timestamp); + + IOVEC_SET_STRING(iovec[j++], "MESSAGE_ID=fc2e22bc6ee647b6b90729ab34a250b1"); + IOVEC_SET_STRING(iovec[j++], "PRIORITY=2"); + + core_message = strjoin("MESSAGE=Process ", argv[ARG_PID], " (", argv[ARG_COMM], ") dumped core.", NULL); + if (core_message) + IOVEC_SET_STRING(iovec[j++], core_message); + + /* Now, let's drop privileges to become the user who owns the + * segfaulted process and allocate the coredump memory under + * his uid. This also ensures that the credentials journald + * will see are the ones of the coredumping user, thus making + * sure the user himself gets access to the core dump. */ + + if (setresgid(gid, gid, gid) < 0 || + setresuid(uid, uid, uid) < 0) { + log_error("Failed to drop privileges: %m"); + r = -errno; + goto finish; + } + + p = malloc(9 + COREDUMP_MAX); + if (!p) { + r = log_oom(); + goto finish; + } + + memcpy(p, "COREDUMP=", 9); + + n = loop_read(STDIN_FILENO, p + 9, COREDUMP_MAX, false); + if (n < 0) { + log_error("Failed to read core dump data: %s", strerror(-n)); + r = (int) n; + goto finish; + } + + iovec[j].iov_base = p; + iovec[j].iov_len = 9 + n; + j++; + + r = sd_journal_sendv(iovec, j); + if (r < 0) + log_error("Failed to send coredump: %s", strerror(-r)); + +finish: + free(p); + free(core_pid); + free(core_uid); + free(core_gid); + free(core_signal); + free(core_timestamp); + free(core_comm); + free(core_exe); + free(core_cmdline); + free(core_unit); + free(core_session); + free(core_message); + + return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/src/journal/coredumpctl.c b/src/journal/coredumpctl.c new file mode 100644 index 000000000..b6e558186 --- /dev/null +++ b/src/journal/coredumpctl.c @@ -0,0 +1,592 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + +#include +#include +#include +#include +#include +#include + +#include + +#include "build.h" +#include "set.h" +#include "util.h" +#include "log.h" +#include "path-util.h" +#include "pager.h" + +static enum { + ACTION_NONE, + ACTION_LIST, + ACTION_DUMP, + ACTION_GDB, +} arg_action = ACTION_LIST; + +static Set *matches = NULL; +static FILE* output = NULL; +static char* field = NULL; + +static int arg_no_pager = false; +static int arg_no_legend = false; + +static Set *new_matches(void) { + Set *set; + char *tmp; + int r; + + set = set_new(trivial_hash_func, trivial_compare_func); + if (!set) { + log_oom(); + return NULL; + } + + tmp = strdup("MESSAGE_ID=fc2e22bc6ee647b6b90729ab34a250b1"); + if (!tmp) { + log_oom(); + set_free(set); + return NULL; + } + + r = set_put(set, tmp); + if (r < 0) { + log_error("failed to add to set: %s", strerror(-r)); + free(tmp); + set_free(set); + return NULL; + } + + return set; +} + +static int help(void) { + printf("%s [OPTIONS...] [MATCHES...]\n\n" + "List or retrieve coredumps from the journal.\n\n" + "Flags:\n" + " -o --output=FILE Write output to FILE\n" + " --no-pager Do not pipe output into a pager\n" + + "Commands:\n" + " -h --help Show this help\n" + " --version Print version string\n" + " -F --field=FIELD List all values a certain field takes\n" + " gdb Start gdb for the first matching coredump\n" + " list List available coredumps\n" + " dump PID Print coredump to stdout\n" + " dump PATH Print coredump to stdout\n" + , program_invocation_short_name); + + return 0; +} + +static int add_match(Set *set, const char *match) { + int r = -ENOMEM; + unsigned pid; + const char* prefix; + char *pattern = NULL; + char _cleanup_free_ *p = NULL; + + if (strchr(match, '=')) + prefix = ""; + else if (strchr(match, '/')) { + p = path_make_absolute_cwd(match); + if (!p) + goto fail; + + match = p; + prefix = "COREDUMP_EXE="; + } + else if (safe_atou(match, &pid) == 0) + prefix = "COREDUMP_PID="; + else + prefix = "COREDUMP_COMM="; + + pattern = strjoin(prefix, match, NULL); + if (!pattern) + goto fail; + + r = set_put(set, pattern); + if (r < 0) { + log_error("failed to add pattern '%s': %s", + pattern, strerror(-r)); + goto fail; + } + log_debug("Added pattern: %s", pattern); + + return 0; +fail: + free(pattern); + log_error("failed to add match: %s", strerror(-r)); + return r; +} + +static int parse_argv(int argc, char *argv[]) { + enum { + ARG_VERSION = 0x100, + ARG_NO_PAGER, + ARG_NO_LEGEND, + }; + + int r, c; + + static const struct option options[] = { + { "help", no_argument, NULL, 'h' }, + { "version" , no_argument, NULL, ARG_VERSION }, + { "no-pager", no_argument, NULL, ARG_NO_PAGER }, + { "no-legend", no_argument, NULL, ARG_NO_LEGEND }, + { "output", required_argument, NULL, 'o' }, + { "field", required_argument, NULL, 'F' }, + { NULL, 0, NULL, 0 } + }; + + assert(argc >= 0); + assert(argv); + + while ((c = getopt_long(argc, argv, "ho:F:", options, NULL)) >= 0) + switch(c) { + case 'h': + help(); + arg_action = ACTION_NONE; + return 0; + + case ARG_VERSION: + puts(PACKAGE_STRING); + puts(SYSTEMD_FEATURES); + arg_action = ACTION_NONE; + return 0; + + case ARG_NO_PAGER: + arg_no_pager = true; + break; + + case ARG_NO_LEGEND: + arg_no_legend = true; + break; + + case 'o': + if (output) { + log_error("cannot set output more than once"); + return -EINVAL; + } + + output = fopen(optarg, "we"); + if (!output) { + log_error("writing to '%s': %m", optarg); + return -errno; + } + + break; + + case 'F': + if (field) { + log_error("cannot use --field/-F more than once"); + return -EINVAL; + } + + field = optarg; + break; + + case '?': + return -EINVAL; + + default: + log_error("Unknown option code %c", c); + return -EINVAL; + } + + if (optind < argc) { + const char *cmd = argv[optind++]; + if(streq(cmd, "list")) + arg_action = ACTION_LIST; + else if (streq(cmd, "dump")) + arg_action = ACTION_DUMP; + else if (streq(cmd, "gdb")) + arg_action = ACTION_GDB; + else { + log_error("Unknown action '%s'", cmd); + return -EINVAL; + } + } + + if (field && arg_action != ACTION_LIST) { + log_error("Option --field/-F only makes sense with list"); + return -EINVAL; + } + + while (optind < argc) { + r = add_match(matches, argv[optind]); + if (r != 0) + return r; + optind++; + } + + return 0; +} + +static int retrieve(const void *data, + size_t len, + const char *name, + const char **var) { + + size_t ident; + + ident = strlen(name) + 1; /* name + "=" */ + + if (len < ident) + return 0; + + if (memcmp(data, name, ident - 1) != 0) + return 0; + + if (((const char*) data)[ident - 1] != '=') + return 0; + + *var = strndup((const char*)data + ident, len - ident); + if (!*var) + return log_oom(); + + return 0; +} + +static void print_field(FILE* file, sd_journal *j) { + const char _cleanup_free_ *value = NULL; + const void *d; + size_t l; + + assert(field); + + SD_JOURNAL_FOREACH_DATA(j, d, l) + retrieve(d, l, field, &value); + if (value) + fprintf(file, "%s\n", value); +} + +static int print_entry(FILE* file, sd_journal *j, int had_legend) { + const char _cleanup_free_ + *pid = NULL, *uid = NULL, *gid = NULL, + *sgnl = NULL, *exe = NULL; + const void *d; + size_t l; + usec_t t; + char buf[FORMAT_TIMESTAMP_MAX]; + int r; + + SD_JOURNAL_FOREACH_DATA(j, d, l) { + retrieve(d, l, "COREDUMP_PID", &pid); + retrieve(d, l, "COREDUMP_PID", &pid); + retrieve(d, l, "COREDUMP_UID", &uid); + retrieve(d, l, "COREDUMP_GID", &gid); + retrieve(d, l, "COREDUMP_SIGNAL", &sgnl); + retrieve(d, l, "COREDUMP_EXE", &exe); + if (!exe) + retrieve(d, l, "COREDUMP_COMM", &exe); + if (!exe) + retrieve(d, l, "COREDUMP_CMDLINE", &exe); + } + + if (!pid && !uid && !gid && !sgnl && !exe) { + log_warning("Empty coredump log entry"); + return -EINVAL; + } + + r = sd_journal_get_realtime_usec(j, &t); + if (r < 0) { + log_error("Failed to get realtime timestamp: %s", strerror(-r)); + return r; + } + + format_timestamp(buf, sizeof(buf), t); + + if (!had_legend && !arg_no_legend) + fprintf(file, "%-*s %*s %*s %*s %*s %s\n", + FORMAT_TIMESTAMP_MAX-1, "TIME", + 6, "PID", + 5, "UID", + 5, "GID", + 3, "SIG", + "EXE"); + + fprintf(file, "%*s %*s %*s %*s %*s %s\n", + FORMAT_TIMESTAMP_MAX-1, buf, + 6, pid, + 5, uid, + 5, gid, + 3, sgnl, + exe); + + return 0; +} + +static int dump_list(sd_journal *j) { + int found = 0; + + assert(j); + + /* The coredumps are likely to compressed, and for just + * listing them we don#t need to decompress them, so let's + * pick a fairly low data threshold here */ + sd_journal_set_data_threshold(j, 4096); + + SD_JOURNAL_FOREACH(j) { + if (field) + print_field(stdout, j); + else + print_entry(stdout, j, found++); + } + + if (!field && !found) { + log_notice("No coredumps found"); + return -ESRCH; + } + + return 0; +} + +static int focus(sd_journal *j) { + int r; + + r = sd_journal_seek_tail(j); + if (r == 0) + r = sd_journal_previous(j); + if (r < 0) { + log_error("Failed to search journal: %s", strerror(-r)); + return r; + } + if (r == 0) { + log_error("No match found"); + return -ESRCH; + } + return r; +} + +static int dump_core(sd_journal* j) { + const void *data; + size_t len, ret; + int r; + + assert(j); + + /* We want full data, nothing truncated. */ + sd_journal_set_data_threshold(j, 0); + + r = focus(j); + if (r < 0) + return r; + + print_entry(output ? stdout : stderr, j, false); + + if (on_tty() && !output) { + log_error("Refusing to dump core to tty"); + return -ENOTTY; + } + + r = sd_journal_get_data(j, "COREDUMP", (const void**) &data, &len); + if (r < 0) { + log_error("Failed to retrieve COREDUMP field: %s", strerror(-r)); + return r; + } + + assert(len >= 9); + data = (const uint8_t*) data + 9; + len -= 9; + + ret = fwrite(data, len, 1, output ? output : stdout); + if (ret != 1) { + log_error("dumping coredump: %m (%zu)", ret); + return -errno; + } + + r = sd_journal_previous(j); + if (r >= 0) + log_warning("More than one entry matches, ignoring rest.\n"); + + return 0; +} + +static int run_gdb(sd_journal *j) { + char path[] = "/var/tmp/coredump-XXXXXX"; + const void *data; + size_t len; + ssize_t sz; + pid_t pid; + _cleanup_free_ char *exe = NULL; + int r; + _cleanup_close_ int fd = -1; + siginfo_t st; + + assert(j); + + sd_journal_set_data_threshold(j, 0); + + r = focus(j); + if (r < 0) + return r; + + print_entry(stdout, j, false); + + r = sd_journal_get_data(j, "COREDUMP_EXE", (const void**) &data, &len); + if (r < 0) { + log_error("Failed to retrieve COREDUMP_EXE field: %s", strerror(-r)); + return r; + } + + assert(len >= 13); + data = (const uint8_t*) data + 13; + len -= 13; + + exe = strndup(data, len); + if (!exe) + return log_oom(); + + if (endswith(exe, " (deleted)")) { + log_error("Binary already deleted."); + return -ENOENT; + } + + r = sd_journal_get_data(j, "COREDUMP", (const void**) &data, &len); + if (r < 0) { + log_error("Failed to retrieve COREDUMP field: %s", strerror(-r)); + return r; + } + + assert(len >= 9); + data = (const uint8_t*) data + 9; + len -= 9; + + fd = mkostemp(path, O_WRONLY); + if (fd < 0) { + log_error("Failed to create temporary file: %m"); + return -errno; + } + + sz = write(fd, data, len); + if (sz < 0) { + log_error("Failed to write temporary file: %s", strerror(errno)); + r = -errno; + goto finish; + } + if (sz != (ssize_t) len) { + log_error("Short write to temporary file."); + r = -EIO; + goto finish; + } + + close_nointr_nofail(fd); + fd = -1; + + pid = fork(); + if (pid < 0) { + log_error("Failed to fork(): %m"); + r = -errno; + goto finish; + } + if (pid == 0) { + execlp("gdb", "gdb", exe, path, NULL); + log_error("Failed to invoke gdb: %m"); + _exit(1); + } + + r = wait_for_terminate(pid, &st); + if (r < 0) { + log_error("Failed to wait for gdb: %m"); + goto finish; + } + + r = st.si_code == CLD_EXITED ? st.si_status : 255; + +finish: + unlink(path); + return r; +} + +int main(int argc, char *argv[]) { + sd_journal *j = NULL; + const char* match; + Iterator it; + int r = 0; + + setlocale(LC_ALL, ""); + log_parse_environment(); + log_open(); + + matches = new_matches(); + if (!matches) { + r = -ENOMEM; + goto end; + } + + r = parse_argv(argc, argv); + if (r < 0) + goto end; + + if (arg_action == ACTION_NONE) + goto end; + + r = sd_journal_open(&j, SD_JOURNAL_LOCAL_ONLY); + if (r < 0) { + log_error("Failed to open journal: %s", strerror(-r)); + goto end; + } + + SET_FOREACH(match, matches, it) { + r = sd_journal_add_match(j, match, strlen(match)); + if (r != 0) { + log_error("Failed to add match '%s': %s", + match, strerror(-r)); + goto end; + } + } + + switch(arg_action) { + + case ACTION_LIST: + if (!arg_no_pager) + pager_open(); + + r = dump_list(j); + break; + + case ACTION_DUMP: + r = dump_core(j); + break; + + case ACTION_GDB: + r = run_gdb(j); + break; + + default: + assert_not_reached("Shouldn't be here"); + } + +end: + if (j) + sd_journal_close(j); + + set_free_free(matches); + + pager_close(); + + if (output) + fclose(output); + + return r >= 0 ? r : EXIT_FAILURE; +} diff --git a/src/journal/fsprg.c b/src/journal/fsprg.c new file mode 100644 index 000000000..2190b7c79 --- /dev/null +++ b/src/journal/fsprg.c @@ -0,0 +1,384 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/* + * fsprg v0.1 - (seekable) forward-secure pseudorandom generator + * Copyright (C) 2012 B. Poettering + * Contact: fsprg@point-at-infinity.org + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include +#include +#include + +#include "fsprg.h" + +#define ISVALID_SECPAR(secpar) (((secpar) % 16 == 0) && ((secpar) >= 16) && ((secpar) <= 16384)) +#define VALIDATE_SECPAR(secpar) assert(ISVALID_SECPAR(secpar)); + +#define RND_HASH GCRY_MD_SHA256 +#define RND_GEN_P 0x01 +#define RND_GEN_Q 0x02 +#define RND_GEN_X 0x03 + +/******************************************************************************/ + +static void mpi_export(void *buf, size_t buflen, const gcry_mpi_t x) { + unsigned len; + size_t nwritten; + + assert(gcry_mpi_cmp_ui(x, 0) >= 0); + len = (gcry_mpi_get_nbits(x) + 7) / 8; + assert(len <= buflen); + memset(buf, 0, buflen); + gcry_mpi_print(GCRYMPI_FMT_USG, buf + (buflen - len), len, &nwritten, x); + assert(nwritten == len); +} + +static gcry_mpi_t mpi_import(const void *buf, size_t buflen) { + gcry_mpi_t h; + unsigned len; + + gcry_mpi_scan(&h, GCRYMPI_FMT_USG, buf, buflen, NULL); + len = (gcry_mpi_get_nbits(h) + 7) / 8; + assert(len <= buflen); + assert(gcry_mpi_cmp_ui(h, 0) >= 0); + + return h; +} + +static void uint64_export(void *buf, size_t buflen, uint64_t x) { + assert(buflen == 8); + ((uint8_t*) buf)[0] = (x >> 56) & 0xff; + ((uint8_t*) buf)[1] = (x >> 48) & 0xff; + ((uint8_t*) buf)[2] = (x >> 40) & 0xff; + ((uint8_t*) buf)[3] = (x >> 32) & 0xff; + ((uint8_t*) buf)[4] = (x >> 24) & 0xff; + ((uint8_t*) buf)[5] = (x >> 16) & 0xff; + ((uint8_t*) buf)[6] = (x >> 8) & 0xff; + ((uint8_t*) buf)[7] = (x >> 0) & 0xff; +} + +static uint64_t uint64_import(const void *buf, size_t buflen) { + assert(buflen == 8); + return + (uint64_t)(((uint8_t*) buf)[0]) << 56 | + (uint64_t)(((uint8_t*) buf)[1]) << 48 | + (uint64_t)(((uint8_t*) buf)[2]) << 40 | + (uint64_t)(((uint8_t*) buf)[3]) << 32 | + (uint64_t)(((uint8_t*) buf)[4]) << 24 | + (uint64_t)(((uint8_t*) buf)[5]) << 16 | + (uint64_t)(((uint8_t*) buf)[6]) << 8 | + (uint64_t)(((uint8_t*) buf)[7]) << 0; +} + +/* deterministically generate from seed/idx a string of buflen pseudorandom bytes */ +static void det_randomize(void *buf, size_t buflen, const void *seed, size_t seedlen, uint32_t idx) { + gcry_md_hd_t hd, hd2; + size_t olen, cpylen; + uint32_t ctr; + + olen = gcry_md_get_algo_dlen(RND_HASH); + gcry_md_open(&hd, RND_HASH, 0); + gcry_md_write(hd, seed, seedlen); + gcry_md_putc(hd, (idx >> 24) & 0xff); + gcry_md_putc(hd, (idx >> 16) & 0xff); + gcry_md_putc(hd, (idx >> 8) & 0xff); + gcry_md_putc(hd, (idx >> 0) & 0xff); + + for (ctr = 0; buflen; ctr++) { + gcry_md_copy(&hd2, hd); + gcry_md_putc(hd2, (ctr >> 24) & 0xff); + gcry_md_putc(hd2, (ctr >> 16) & 0xff); + gcry_md_putc(hd2, (ctr >> 8) & 0xff); + gcry_md_putc(hd2, (ctr >> 0) & 0xff); + gcry_md_final(hd2); + cpylen = (buflen < olen) ? buflen : olen; + memcpy(buf, gcry_md_read(hd2, RND_HASH), cpylen); + gcry_md_close(hd2); + buf += cpylen; + buflen -= cpylen; + } + gcry_md_close(hd); +} + +/* deterministically generate from seed/idx a prime of length `bits' that is 3 (mod 4) */ +static gcry_mpi_t genprime3mod4(int bits, const void *seed, size_t seedlen, uint32_t idx) { + size_t buflen = bits / 8; + uint8_t buf[buflen]; + gcry_mpi_t p; + + assert(bits % 8 == 0); + assert(buflen > 0); + + det_randomize(buf, buflen, seed, seedlen, idx); + buf[0] |= 0xc0; /* set upper two bits, so that n=pq has maximum size */ + buf[buflen - 1] |= 0x03; /* set lower two bits, to have result 3 (mod 4) */ + + p = mpi_import(buf, buflen); + while (gcry_prime_check(p, 0)) + gcry_mpi_add_ui(p, p, 4); + + return p; +} + +/* deterministically generate from seed/idx a quadratic residue (mod n) */ +static gcry_mpi_t gensquare(const gcry_mpi_t n, const void *seed, size_t seedlen, uint32_t idx, unsigned secpar) { + size_t buflen = secpar / 8; + uint8_t buf[buflen]; + gcry_mpi_t x; + + det_randomize(buf, buflen, seed, seedlen, idx); + buf[0] &= 0x7f; /* clear upper bit, so that we have x < n */ + x = mpi_import(buf, buflen); + assert(gcry_mpi_cmp(x, n) < 0); + gcry_mpi_mulm(x, x, x, n); + return x; +} + +/* compute 2^m (mod phi(p)), for a prime p */ +static gcry_mpi_t twopowmodphi(uint64_t m, const gcry_mpi_t p) { + gcry_mpi_t phi, r; + int n; + + phi = gcry_mpi_new(0); + gcry_mpi_sub_ui(phi, p, 1); + + /* count number of used bits in m */ + for (n = 0; (1ULL << n) <= m; n++) + ; + + r = gcry_mpi_new(0); + gcry_mpi_set_ui(r, 1); + while (n) { /* square and multiply algorithm for fast exponentiation */ + n--; + gcry_mpi_mulm(r, r, r, phi); + if (m & ((uint64_t)1 << n)) { + gcry_mpi_add(r, r, r); + if (gcry_mpi_cmp(r, phi) >= 0) + gcry_mpi_sub(r, r, phi); + } + } + + gcry_mpi_release(phi); + return r; +} + +/* Decompose $x \in Z_n$ into $(xp,xq) \in Z_p \times Z_q$ using Chinese Remainder Theorem */ +static void CRT_decompose(gcry_mpi_t *xp, gcry_mpi_t *xq, const gcry_mpi_t x, const gcry_mpi_t p, const gcry_mpi_t q) { + *xp = gcry_mpi_new(0); + *xq = gcry_mpi_new(0); + gcry_mpi_mod(*xp, x, p); + gcry_mpi_mod(*xq, x, q); +} + +/* Compose $(xp,xq) \in Z_p \times Z_q$ into $x \in Z_n$ using Chinese Remainder Theorem */ +static void CRT_compose(gcry_mpi_t *x, const gcry_mpi_t xp, const gcry_mpi_t xq, const gcry_mpi_t p, const gcry_mpi_t q) { + gcry_mpi_t a, u; + + a = gcry_mpi_new(0); + u = gcry_mpi_new(0); + *x = gcry_mpi_new(0); + gcry_mpi_subm(a, xq, xp, q); + gcry_mpi_invm(u, p, q); + gcry_mpi_mulm(a, a, u, q); /* a = (xq - xp) / p (mod q) */ + gcry_mpi_mul(*x, p, a); + gcry_mpi_add(*x, *x, xp); /* x = p * ((xq - xp) / p mod q) + xp */ + gcry_mpi_release(a); + gcry_mpi_release(u); +} + +static void initialize_libgcrypt(void) { + const char *p; + if (gcry_control(GCRYCTL_INITIALIZATION_FINISHED_P)) + return; + + p = gcry_check_version("1.4.5"); + assert(p); + + /* Turn off "secmem". Clients which whish to make use of this + * feature should initialize the library manually */ + gcry_control(GCRYCTL_DISABLE_SECMEM); + gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0); +} + +/******************************************************************************/ + +size_t FSPRG_mskinbytes(unsigned _secpar) { + VALIDATE_SECPAR(_secpar); + return 2 + 2 * (_secpar / 2) / 8; /* to store header,p,q */ +} + +size_t FSPRG_mpkinbytes(unsigned _secpar) { + VALIDATE_SECPAR(_secpar); + return 2 + _secpar / 8; /* to store header,n */ +} + +size_t FSPRG_stateinbytes(unsigned _secpar) { + VALIDATE_SECPAR(_secpar); + return 2 + 2 * _secpar / 8 + 8; /* to store header,n,x,epoch */ +} + +static void store_secpar(void *buf, uint16_t secpar) { + secpar = secpar / 16 - 1; + ((uint8_t*) buf)[0] = (secpar >> 8) & 0xff; + ((uint8_t*) buf)[1] = (secpar >> 0) & 0xff; +} + +static uint16_t read_secpar(const void *buf) { + uint16_t secpar; + secpar = + (uint16_t)(((uint8_t*) buf)[0]) << 8 | + (uint16_t)(((uint8_t*) buf)[1]) << 0; + return 16 * (secpar + 1); +} + +void FSPRG_GenMK(void *msk, void *mpk, const void *seed, size_t seedlen, unsigned _secpar) { + uint8_t iseed[FSPRG_RECOMMENDED_SEEDLEN]; + gcry_mpi_t n, p, q; + uint16_t secpar; + + VALIDATE_SECPAR(_secpar); + secpar = _secpar; + + initialize_libgcrypt(); + + if (!seed) { + gcry_randomize(iseed, FSPRG_RECOMMENDED_SEEDLEN, GCRY_STRONG_RANDOM); + seed = iseed; + seedlen = FSPRG_RECOMMENDED_SEEDLEN; + } + + p = genprime3mod4(secpar / 2, seed, seedlen, RND_GEN_P); + q = genprime3mod4(secpar / 2, seed, seedlen, RND_GEN_Q); + + if (msk) { + store_secpar(msk + 0, secpar); + mpi_export(msk + 2 + 0 * (secpar / 2) / 8, (secpar / 2) / 8, p); + mpi_export(msk + 2 + 1 * (secpar / 2) / 8, (secpar / 2) / 8, q); + } + + if (mpk) { + n = gcry_mpi_new(0); + gcry_mpi_mul(n, p, q); + assert(gcry_mpi_get_nbits(n) == secpar); + + store_secpar(mpk + 0, secpar); + mpi_export(mpk + 2, secpar / 8, n); + + gcry_mpi_release(n); + } + + gcry_mpi_release(p); + gcry_mpi_release(q); +} + +void FSPRG_GenState0(void *state, const void *mpk, const void *seed, size_t seedlen) { + gcry_mpi_t n, x; + uint16_t secpar; + + initialize_libgcrypt(); + + secpar = read_secpar(mpk + 0); + n = mpi_import(mpk + 2, secpar / 8); + x = gensquare(n, seed, seedlen, RND_GEN_X, secpar); + + memcpy(state, mpk, 2 + secpar / 8); + mpi_export(state + 2 + 1 * secpar / 8, secpar / 8, x); + memset(state + 2 + 2 * secpar / 8, 0, 8); + + gcry_mpi_release(n); + gcry_mpi_release(x); +} + +void FSPRG_Evolve(void *state) { + gcry_mpi_t n, x; + uint16_t secpar; + uint64_t epoch; + + initialize_libgcrypt(); + + secpar = read_secpar(state + 0); + n = mpi_import(state + 2 + 0 * secpar / 8, secpar / 8); + x = mpi_import(state + 2 + 1 * secpar / 8, secpar / 8); + epoch = uint64_import(state + 2 + 2 * secpar / 8, 8); + + gcry_mpi_mulm(x, x, x, n); + epoch++; + + mpi_export(state + 2 + 1 * secpar / 8, secpar / 8, x); + uint64_export(state + 2 + 2 * secpar / 8, 8, epoch); + + gcry_mpi_release(n); + gcry_mpi_release(x); +} + +uint64_t FSPRG_GetEpoch(const void *state) { + uint16_t secpar; + secpar = read_secpar(state + 0); + return uint64_import(state + 2 + 2 * secpar / 8, 8); +} + +void FSPRG_Seek(void *state, uint64_t epoch, const void *msk, const void *seed, size_t seedlen) { + gcry_mpi_t p, q, n, x, xp, xq, kp, kq, xm; + uint16_t secpar; + + initialize_libgcrypt(); + + secpar = read_secpar(msk + 0); + p = mpi_import(msk + 2 + 0 * (secpar / 2) / 8, (secpar / 2) / 8); + q = mpi_import(msk + 2 + 1 * (secpar / 2) / 8, (secpar / 2) / 8); + + n = gcry_mpi_new(0); + gcry_mpi_mul(n, p, q); + + x = gensquare(n, seed, seedlen, RND_GEN_X, secpar); + CRT_decompose(&xp, &xq, x, p, q); /* split (mod n) into (mod p) and (mod q) using CRT */ + + kp = twopowmodphi(epoch, p); /* compute 2^epoch (mod phi(p)) */ + kq = twopowmodphi(epoch, q); /* compute 2^epoch (mod phi(q)) */ + + gcry_mpi_powm(xp, xp, kp, p); /* compute x^(2^epoch) (mod p) */ + gcry_mpi_powm(xq, xq, kq, q); /* compute x^(2^epoch) (mod q) */ + + CRT_compose(&xm, xp, xq, p, q); /* combine (mod p) and (mod q) to (mod n) using CRT */ + + store_secpar(state + 0, secpar); + mpi_export(state + 2 + 0 * secpar / 8, secpar / 8, n); + mpi_export(state + 2 + 1 * secpar / 8, secpar / 8, xm); + uint64_export(state + 2 + 2 * secpar / 8, 8, epoch); + + gcry_mpi_release(p); + gcry_mpi_release(q); + gcry_mpi_release(n); + gcry_mpi_release(x); + gcry_mpi_release(xp); + gcry_mpi_release(xq); + gcry_mpi_release(kp); + gcry_mpi_release(kq); + gcry_mpi_release(xm); +} + +void FSPRG_GetKey(const void *state, void *key, size_t keylen, uint32_t idx) { + uint16_t secpar; + + initialize_libgcrypt(); + + secpar = read_secpar(state + 0); + det_randomize(key, keylen, state + 2, 2 * secpar / 8 + 8, idx); +} diff --git a/src/journal/fsprg.h b/src/journal/fsprg.h new file mode 100644 index 000000000..306ef18d7 --- /dev/null +++ b/src/journal/fsprg.h @@ -0,0 +1,64 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef __fsprgh__ +#define __fsprgh__ + +/* + * fsprg v0.1 - (seekable) forward-secure pseudorandom generator + * Copyright (C) 2012 B. Poettering + * Contact: fsprg@point-at-infinity.org + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define FSPRG_RECOMMENDED_SECPAR 1536 +#define FSPRG_RECOMMENDED_SEEDLEN (96/8) + +size_t FSPRG_mskinbytes(unsigned secpar); +size_t FSPRG_mpkinbytes(unsigned secpar); +size_t FSPRG_stateinbytes(unsigned secpar); + +/* Setup msk and mpk. Providing seed != NULL makes this algorithm deterministic. */ +void FSPRG_GenMK(void *msk, void *mpk, const void *seed, size_t seedlen, unsigned secpar); + +/* Initialize state deterministically in dependence on seed. */ +/* Note: in case one wants to run only one GenState0 per GenMK it is safe to use + the same seed for both GenMK and GenState0. +*/ +void FSPRG_GenState0(void *state, const void *mpk, const void *seed, size_t seedlen); + +void FSPRG_Evolve(void *state); + +uint64_t FSPRG_GetEpoch(const void *state); + +/* Seek to any arbitrary state (by providing msk together with seed from GenState0). */ +void FSPRG_Seek(void *state, uint64_t epoch, const void *msk, const void *seed, size_t seedlen); + +void FSPRG_GetKey(const void *state, void *key, size_t keylen, uint32_t idx); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/journal/journal-authenticate.c b/src/journal/journal-authenticate.c new file mode 100644 index 000000000..64bf96874 --- /dev/null +++ b/src/journal/journal-authenticate.c @@ -0,0 +1,563 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + +#include +#include + +#include "journal-def.h" +#include "journal-file.h" +#include "journal-authenticate.h" +#include "fsprg.h" + +static uint64_t journal_file_tag_seqnum(JournalFile *f) { + uint64_t r; + + assert(f); + + r = le64toh(f->header->n_tags) + 1; + f->header->n_tags = htole64(r); + + return r; +} + +int journal_file_append_tag(JournalFile *f) { + Object *o; + uint64_t p; + int r; + + assert(f); + + if (!f->seal) + return 0; + + if (!f->hmac_running) + return 0; + + assert(f->hmac); + + r = journal_file_append_object(f, OBJECT_TAG, sizeof(struct TagObject), &o, &p); + if (r < 0) + return r; + + o->tag.seqnum = htole64(journal_file_tag_seqnum(f)); + o->tag.epoch = htole64(FSPRG_GetEpoch(f->fsprg_state)); + + log_debug("Writing tag %llu for epoch %llu\n", + (unsigned long long) le64toh(o->tag.seqnum), + (unsigned long long) FSPRG_GetEpoch(f->fsprg_state)); + + /* Add the tag object itself, so that we can protect its + * header. This will exclude the actual hash value in it */ + r = journal_file_hmac_put_object(f, OBJECT_TAG, o, p); + if (r < 0) + return r; + + /* Get the HMAC tag and store it in the object */ + memcpy(o->tag.tag, gcry_md_read(f->hmac, 0), TAG_LENGTH); + f->hmac_running = false; + + return 0; +} + +int journal_file_hmac_start(JournalFile *f) { + uint8_t key[256 / 8]; /* Let's pass 256 bit from FSPRG to HMAC */ + assert(f); + + if (!f->seal) + return 0; + + if (f->hmac_running) + return 0; + + /* Prepare HMAC for next cycle */ + gcry_md_reset(f->hmac); + FSPRG_GetKey(f->fsprg_state, key, sizeof(key), 0); + gcry_md_setkey(f->hmac, key, sizeof(key)); + + f->hmac_running = true; + + return 0; +} + +static int journal_file_get_epoch(JournalFile *f, uint64_t realtime, uint64_t *epoch) { + uint64_t t; + + assert(f); + assert(epoch); + assert(f->seal); + + if (f->fss_start_usec == 0 || + f->fss_interval_usec == 0) + return -ENOTSUP; + + if (realtime < f->fss_start_usec) + return -ESTALE; + + t = realtime - f->fss_start_usec; + t = t / f->fss_interval_usec; + + *epoch = t; + return 0; +} + +static int journal_file_fsprg_need_evolve(JournalFile *f, uint64_t realtime) { + uint64_t goal, epoch; + int r; + assert(f); + + if (!f->seal) + return 0; + + r = journal_file_get_epoch(f, realtime, &goal); + if (r < 0) + return r; + + epoch = FSPRG_GetEpoch(f->fsprg_state); + if (epoch > goal) + return -ESTALE; + + return epoch != goal; +} + +int journal_file_fsprg_evolve(JournalFile *f, uint64_t realtime) { + uint64_t goal, epoch; + int r; + + assert(f); + + if (!f->seal) + return 0; + + r = journal_file_get_epoch(f, realtime, &goal); + if (r < 0) + return r; + + epoch = FSPRG_GetEpoch(f->fsprg_state); + if (epoch < goal) + log_debug("Evolving FSPRG key from epoch %llu to %llu.", (unsigned long long) epoch, (unsigned long long) goal); + + for (;;) { + if (epoch > goal) + return -ESTALE; + if (epoch == goal) + return 0; + + FSPRG_Evolve(f->fsprg_state); + epoch = FSPRG_GetEpoch(f->fsprg_state); + } +} + +int journal_file_fsprg_seek(JournalFile *f, uint64_t goal) { + void *msk; + uint64_t epoch; + + assert(f); + + if (!f->seal) + return 0; + + assert(f->fsprg_seed); + + if (f->fsprg_state) { + /* Cheaper... */ + + epoch = FSPRG_GetEpoch(f->fsprg_state); + if (goal == epoch) + return 0; + + if (goal == epoch+1) { + FSPRG_Evolve(f->fsprg_state); + return 0; + } + } else { + f->fsprg_state_size = FSPRG_stateinbytes(FSPRG_RECOMMENDED_SECPAR); + f->fsprg_state = malloc(f->fsprg_state_size); + + if (!f->fsprg_state) + return -ENOMEM; + } + + log_debug("Seeking FSPRG key to %llu.", (unsigned long long) goal); + + msk = alloca(FSPRG_mskinbytes(FSPRG_RECOMMENDED_SECPAR)); + FSPRG_GenMK(msk, NULL, f->fsprg_seed, f->fsprg_seed_size, FSPRG_RECOMMENDED_SECPAR); + FSPRG_Seek(f->fsprg_state, goal, msk, f->fsprg_seed, f->fsprg_seed_size); + return 0; +} + +int journal_file_maybe_append_tag(JournalFile *f, uint64_t realtime) { + int r; + + assert(f); + + if (!f->seal) + return 0; + + if (realtime <= 0) + realtime = now(CLOCK_REALTIME); + + r = journal_file_fsprg_need_evolve(f, realtime); + if (r <= 0) + return 0; + + r = journal_file_append_tag(f); + if (r < 0) + return r; + + r = journal_file_fsprg_evolve(f, realtime); + if (r < 0) + return r; + + return 0; +} + +int journal_file_hmac_put_object(JournalFile *f, int type, Object *o, uint64_t p) { + int r; + + assert(f); + + if (!f->seal) + return 0; + + r = journal_file_hmac_start(f); + if (r < 0) + return r; + + if (!o) { + r = journal_file_move_to_object(f, type, p, &o); + if (r < 0) + return r; + } else { + if (type >= 0 && o->object.type != type) + return -EBADMSG; + } + + gcry_md_write(f->hmac, o, offsetof(ObjectHeader, payload)); + + switch (o->object.type) { + + case OBJECT_DATA: + /* All but hash and payload are mutable */ + gcry_md_write(f->hmac, &o->data.hash, sizeof(o->data.hash)); + gcry_md_write(f->hmac, o->data.payload, le64toh(o->object.size) - offsetof(DataObject, payload)); + break; + + case OBJECT_FIELD: + /* Same here */ + gcry_md_write(f->hmac, &o->field.hash, sizeof(o->field.hash)); + gcry_md_write(f->hmac, o->field.payload, le64toh(o->object.size) - offsetof(FieldObject, payload)); + break; + + case OBJECT_ENTRY: + /* All */ + gcry_md_write(f->hmac, &o->entry.seqnum, le64toh(o->object.size) - offsetof(EntryObject, seqnum)); + break; + + case OBJECT_FIELD_HASH_TABLE: + case OBJECT_DATA_HASH_TABLE: + case OBJECT_ENTRY_ARRAY: + /* Nothing: everything is mutable */ + break; + + case OBJECT_TAG: + /* All but the tag itself */ + gcry_md_write(f->hmac, &o->tag.seqnum, sizeof(o->tag.seqnum)); + gcry_md_write(f->hmac, &o->tag.epoch, sizeof(o->tag.epoch)); + break; + default: + return -EINVAL; + } + + return 0; +} + +int journal_file_hmac_put_header(JournalFile *f) { + int r; + + assert(f); + + if (!f->seal) + return 0; + + r = journal_file_hmac_start(f); + if (r < 0) + return r; + + /* All but state+reserved, boot_id, arena_size, + * tail_object_offset, n_objects, n_entries, + * tail_entry_seqnum, head_entry_seqnum, entry_array_offset, + * head_entry_realtime, tail_entry_realtime, + * tail_entry_monotonic, n_data, n_fields, n_tags, + * n_entry_arrays. */ + + gcry_md_write(f->hmac, f->header->signature, offsetof(Header, state) - offsetof(Header, signature)); + gcry_md_write(f->hmac, &f->header->file_id, offsetof(Header, boot_id) - offsetof(Header, file_id)); + gcry_md_write(f->hmac, &f->header->seqnum_id, offsetof(Header, arena_size) - offsetof(Header, seqnum_id)); + gcry_md_write(f->hmac, &f->header->data_hash_table_offset, offsetof(Header, tail_object_offset) - offsetof(Header, data_hash_table_offset)); + + return 0; +} + +int journal_file_fss_load(JournalFile *f) { + int r, fd = -1; + char *p = NULL; + struct stat st; + FSSHeader *m = NULL; + sd_id128_t machine; + + assert(f); + + if (!f->seal) + return 0; + + r = sd_id128_get_machine(&machine); + if (r < 0) + return r; + + if (asprintf(&p, "/var/log/journal/" SD_ID128_FORMAT_STR "/fss", + SD_ID128_FORMAT_VAL(machine)) < 0) + return -ENOMEM; + + fd = open(p, O_RDWR|O_CLOEXEC|O_NOCTTY, 0600); + if (fd < 0) { + if (errno != ENOENT) + log_error("Failed to open %s: %m", p); + + r = -errno; + goto finish; + } + + if (fstat(fd, &st) < 0) { + r = -errno; + goto finish; + } + + if (st.st_size < (off_t) sizeof(FSSHeader)) { + r = -ENODATA; + goto finish; + } + + m = mmap(NULL, PAGE_ALIGN(sizeof(FSSHeader)), PROT_READ, MAP_SHARED, fd, 0); + if (m == MAP_FAILED) { + m = NULL; + r = -errno; + goto finish; + } + + if (memcmp(m->signature, FSS_HEADER_SIGNATURE, 8) != 0) { + r = -EBADMSG; + goto finish; + } + + if (m->incompatible_flags != 0) { + r = -EPROTONOSUPPORT; + goto finish; + } + + if (le64toh(m->header_size) < sizeof(FSSHeader)) { + r = -EBADMSG; + goto finish; + } + + if (le64toh(m->fsprg_state_size) != FSPRG_stateinbytes(le16toh(m->fsprg_secpar))) { + r = -EBADMSG; + goto finish; + } + + f->fss_file_size = le64toh(m->header_size) + le64toh(m->fsprg_state_size); + if ((uint64_t) st.st_size < f->fss_file_size) { + r = -ENODATA; + goto finish; + } + + if (!sd_id128_equal(machine, m->machine_id)) { + r = -EHOSTDOWN; + goto finish; + } + + if (le64toh(m->start_usec) <= 0 || + le64toh(m->interval_usec) <= 0) { + r = -EBADMSG; + goto finish; + } + + f->fss_file = mmap(NULL, PAGE_ALIGN(f->fss_file_size), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); + if (f->fss_file == MAP_FAILED) { + f->fss_file = NULL; + r = -errno; + goto finish; + } + + f->fss_start_usec = le64toh(f->fss_file->start_usec); + f->fss_interval_usec = le64toh(f->fss_file->interval_usec); + + f->fsprg_state = (uint8_t*) f->fss_file + le64toh(f->fss_file->header_size); + f->fsprg_state_size = le64toh(f->fss_file->fsprg_state_size); + + r = 0; + +finish: + if (m) + munmap(m, PAGE_ALIGN(sizeof(FSSHeader))); + + if (fd >= 0) + close_nointr_nofail(fd); + + free(p); + return r; +} + +static void initialize_libgcrypt(void) { + const char *p; + + if (gcry_control(GCRYCTL_INITIALIZATION_FINISHED_P)) + return; + + p = gcry_check_version("1.4.5"); + assert(p); + + gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0); +} + +int journal_file_hmac_setup(JournalFile *f) { + gcry_error_t e; + + if (!f->seal) + return 0; + + initialize_libgcrypt(); + + e = gcry_md_open(&f->hmac, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC); + if (e != 0) + return -ENOTSUP; + + return 0; +} + +int journal_file_append_first_tag(JournalFile *f) { + int r; + uint64_t p; + + if (!f->seal) + return 0; + + log_debug("Calculating first tag..."); + + r = journal_file_hmac_put_header(f); + if (r < 0) + return r; + + p = le64toh(f->header->field_hash_table_offset); + if (p < offsetof(Object, hash_table.items)) + return -EINVAL; + p -= offsetof(Object, hash_table.items); + + r = journal_file_hmac_put_object(f, OBJECT_FIELD_HASH_TABLE, NULL, p); + if (r < 0) + return r; + + p = le64toh(f->header->data_hash_table_offset); + if (p < offsetof(Object, hash_table.items)) + return -EINVAL; + p -= offsetof(Object, hash_table.items); + + r = journal_file_hmac_put_object(f, OBJECT_DATA_HASH_TABLE, NULL, p); + if (r < 0) + return r; + + r = journal_file_append_tag(f); + if (r < 0) + return r; + + return 0; +} + +int journal_file_parse_verification_key(JournalFile *f, const char *key) { + uint8_t *seed; + size_t seed_size, c; + const char *k; + int r; + unsigned long long start, interval; + + seed_size = FSPRG_RECOMMENDED_SEEDLEN; + seed = malloc(seed_size); + if (!seed) + return -ENOMEM; + + k = key; + for (c = 0; c < seed_size; c++) { + int x, y; + + while (*k == '-') + k++; + + x = unhexchar(*k); + if (x < 0) { + free(seed); + return -EINVAL; + } + k++; + y = unhexchar(*k); + if (y < 0) { + free(seed); + return -EINVAL; + } + k++; + + seed[c] = (uint8_t) (x * 16 + y); + } + + if (*k != '/') { + free(seed); + return -EINVAL; + } + k++; + + r = sscanf(k, "%llx-%llx", &start, &interval); + if (r != 2) { + free(seed); + return -EINVAL; + } + + f->fsprg_seed = seed; + f->fsprg_seed_size = seed_size; + + f->fss_start_usec = start * interval; + f->fss_interval_usec = interval; + + return 0; +} + +bool journal_file_next_evolve_usec(JournalFile *f, usec_t *u) { + uint64_t epoch; + + assert(f); + assert(u); + + if (!f->seal) + return false; + + epoch = FSPRG_GetEpoch(f->fsprg_state); + + *u = (usec_t) (f->fss_start_usec + f->fss_interval_usec * epoch + f->fss_interval_usec); + + return true; +} diff --git a/src/journal/journal-authenticate.h b/src/journal/journal-authenticate.h new file mode 100644 index 000000000..0aaf83672 --- /dev/null +++ b/src/journal/journal-authenticate.h @@ -0,0 +1,44 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + +#include +#include + +#include "journal-file.h" + +int journal_file_append_tag(JournalFile *f); +int journal_file_maybe_append_tag(JournalFile *f, uint64_t realtime); +int journal_file_append_first_tag(JournalFile *f); + +int journal_file_hmac_setup(JournalFile *f); +int journal_file_hmac_start(JournalFile *f); +int journal_file_hmac_put_header(JournalFile *f); +int journal_file_hmac_put_object(JournalFile *f, int type, Object *o, uint64_t p); + +int journal_file_fss_load(JournalFile *f); +int journal_file_parse_verification_key(JournalFile *f, const char *key); + +int journal_file_fsprg_evolve(JournalFile *f, uint64_t realtime); +int journal_file_fsprg_seek(JournalFile *f, uint64_t epoch); + +bool journal_file_next_evolve_usec(JournalFile *f, usec_t *u); diff --git a/src/journal/journal-def.h b/src/journal/journal-def.h new file mode 100644 index 000000000..7e407a416 --- /dev/null +++ b/src/journal/journal-def.h @@ -0,0 +1,216 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +#include "sparse-endian.h" + +#include + +#include "macro.h" + +/* + * If you change this file you probably should also change its documentation: + * + * http://www.freedesktop.org/wiki/Software/systemd/journal-files + * + */ + +typedef struct Header Header; + +typedef struct ObjectHeader ObjectHeader; +typedef union Object Object; + +typedef struct DataObject DataObject; +typedef struct FieldObject FieldObject; +typedef struct EntryObject EntryObject; +typedef struct HashTableObject HashTableObject; +typedef struct EntryArrayObject EntryArrayObject; +typedef struct TagObject TagObject; + +typedef struct EntryItem EntryItem; +typedef struct HashItem HashItem; + +typedef struct FSSHeader FSSHeader; + +/* Object types */ +enum { + OBJECT_UNUSED, + OBJECT_DATA, + OBJECT_FIELD, + OBJECT_ENTRY, + OBJECT_DATA_HASH_TABLE, + OBJECT_FIELD_HASH_TABLE, + OBJECT_ENTRY_ARRAY, + OBJECT_TAG, + _OBJECT_TYPE_MAX +}; + +/* Object flags */ +enum { + OBJECT_COMPRESSED = 1 +}; + +struct ObjectHeader { + uint8_t type; + uint8_t flags; + uint8_t reserved[6]; + le64_t size; + uint8_t payload[]; +} _packed_; + +struct DataObject { + ObjectHeader object; + le64_t hash; + le64_t next_hash_offset; + le64_t next_field_offset; + le64_t entry_offset; /* the first array entry we store inline */ + le64_t entry_array_offset; + le64_t n_entries; + uint8_t payload[]; +} _packed_; + +struct FieldObject { + ObjectHeader object; + le64_t hash; + le64_t next_hash_offset; + le64_t head_data_offset; + uint8_t payload[]; +} _packed_; + +struct EntryItem { + le64_t object_offset; + le64_t hash; +} _packed_; + +struct EntryObject { + ObjectHeader object; + le64_t seqnum; + le64_t realtime; + le64_t monotonic; + sd_id128_t boot_id; + le64_t xor_hash; + EntryItem items[]; +} _packed_; + +struct HashItem { + le64_t head_hash_offset; + le64_t tail_hash_offset; +} _packed_; + +struct HashTableObject { + ObjectHeader object; + HashItem items[]; +} _packed_; + +struct EntryArrayObject { + ObjectHeader object; + le64_t next_entry_array_offset; + le64_t items[]; +} _packed_; + +#define TAG_LENGTH (256/8) + +struct TagObject { + ObjectHeader object; + le64_t seqnum; + le64_t epoch; + uint8_t tag[TAG_LENGTH]; /* SHA-256 HMAC */ +} _packed_; + +union Object { + ObjectHeader object; + DataObject data; + FieldObject field; + EntryObject entry; + HashTableObject hash_table; + EntryArrayObject entry_array; + TagObject tag; +}; + +enum { + STATE_OFFLINE = 0, + STATE_ONLINE = 1, + STATE_ARCHIVED = 2, + _STATE_MAX +}; + +/* Header flags */ +enum { + HEADER_INCOMPATIBLE_COMPRESSED = 1 +}; + +enum { + HEADER_COMPATIBLE_SEALED = 1 +}; + +#define HEADER_SIGNATURE ((char[]) { 'L', 'P', 'K', 'S', 'H', 'H', 'R', 'H' }) + +struct Header { + uint8_t signature[8]; /* "LPKSHHRH" */ + le32_t compatible_flags; + le32_t incompatible_flags; + uint8_t state; + uint8_t reserved[7]; + sd_id128_t file_id; + sd_id128_t machine_id; + sd_id128_t boot_id; /* last writer */ + sd_id128_t seqnum_id; + le64_t header_size; + le64_t arena_size; + le64_t data_hash_table_offset; + le64_t data_hash_table_size; + le64_t field_hash_table_offset; + le64_t field_hash_table_size; + le64_t tail_object_offset; + le64_t n_objects; + le64_t n_entries; + le64_t tail_entry_seqnum; + le64_t head_entry_seqnum; + le64_t entry_array_offset; + le64_t head_entry_realtime; + le64_t tail_entry_realtime; + le64_t tail_entry_monotonic; + /* Added in 187 */ + le64_t n_data; + le64_t n_fields; + /* Added in 189 */ + le64_t n_tags; + le64_t n_entry_arrays; + + /* Size: 224 */ +} _packed_; + +#define FSS_HEADER_SIGNATURE ((char[]) { 'K', 'S', 'H', 'H', 'R', 'H', 'L', 'P' }) + +struct FSSHeader { + uint8_t signature[8]; /* "KSHHRHLP" */ + le32_t compatible_flags; + le32_t incompatible_flags; + sd_id128_t machine_id; + sd_id128_t boot_id; /* last writer */ + le64_t header_size; + le64_t start_usec; + le64_t interval_usec; + le16_t fsprg_secpar; + le16_t reserved[3]; + le64_t fsprg_state_size; +} _packed_; diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c new file mode 100644 index 000000000..13fc8edea --- /dev/null +++ b/src/journal/journal-file.c @@ -0,0 +1,2871 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_XATTR +#include +#endif + +#include "journal-def.h" +#include "journal-file.h" +#include "journal-authenticate.h" +#include "lookup3.h" +#include "compress.h" +#include "fsprg.h" + +#define DEFAULT_DATA_HASH_TABLE_SIZE (2047ULL*sizeof(HashItem)) +#define DEFAULT_FIELD_HASH_TABLE_SIZE (333ULL*sizeof(HashItem)) + +#define COMPRESSION_SIZE_THRESHOLD (512ULL) + +/* This is the minimum journal file size */ +#define JOURNAL_FILE_SIZE_MIN (64ULL*1024ULL) /* 64 KiB */ + +/* These are the lower and upper bounds if we deduce the max_use value + * from the file system size */ +#define DEFAULT_MAX_USE_LOWER (1ULL*1024ULL*1024ULL) /* 1 MiB */ +#define DEFAULT_MAX_USE_UPPER (4ULL*1024ULL*1024ULL*1024ULL) /* 4 GiB */ + +/* This is the upper bound if we deduce max_size from max_use */ +#define DEFAULT_MAX_SIZE_UPPER (128ULL*1024ULL*1024ULL) /* 128 MiB */ + +/* This is the upper bound if we deduce the keep_free value from the + * file system size */ +#define DEFAULT_KEEP_FREE_UPPER (4ULL*1024ULL*1024ULL*1024ULL) /* 4 GiB */ + +/* This is the keep_free value when we can't determine the system + * size */ +#define DEFAULT_KEEP_FREE (1024ULL*1024ULL) /* 1 MB */ + +/* n_data was the first entry we added after the initial file format design */ +#define HEADER_SIZE_MIN ALIGN64(offsetof(Header, n_data)) + +/* How many entries to keep in the entry array chain cache at max */ +#define CHAIN_CACHE_MAX 20 + +void journal_file_close(JournalFile *f) { + assert(f); + +#ifdef HAVE_GCRYPT + /* Write the final tag */ + if (f->seal && f->writable) + journal_file_append_tag(f); +#endif + + /* Sync everything to disk, before we mark the file offline */ + if (f->mmap && f->fd >= 0) + mmap_cache_close_fd(f->mmap, f->fd); + + if (f->writable && f->fd >= 0) + fdatasync(f->fd); + + if (f->header) { + /* Mark the file offline. Don't override the archived state if it already is set */ + if (f->writable && f->header->state == STATE_ONLINE) + f->header->state = STATE_OFFLINE; + + munmap(f->header, PAGE_ALIGN(sizeof(Header))); + } + + if (f->fd >= 0) + close_nointr_nofail(f->fd); + + free(f->path); + + if (f->mmap) + mmap_cache_unref(f->mmap); + + hashmap_free_free(f->chain_cache); + +#ifdef HAVE_XZ + free(f->compress_buffer); +#endif + +#ifdef HAVE_GCRYPT + if (f->fss_file) + munmap(f->fss_file, PAGE_ALIGN(f->fss_file_size)); + else if (f->fsprg_state) + free(f->fsprg_state); + + free(f->fsprg_seed); + + if (f->hmac) + gcry_md_close(f->hmac); +#endif + + free(f); +} + +static int journal_file_init_header(JournalFile *f, JournalFile *template) { + Header h; + ssize_t k; + int r; + + assert(f); + + zero(h); + memcpy(h.signature, HEADER_SIGNATURE, 8); + h.header_size = htole64(ALIGN64(sizeof(h))); + + h.incompatible_flags = + htole32(f->compress ? HEADER_INCOMPATIBLE_COMPRESSED : 0); + + h.compatible_flags = + htole32(f->seal ? HEADER_COMPATIBLE_SEALED : 0); + + r = sd_id128_randomize(&h.file_id); + if (r < 0) + return r; + + if (template) { + h.seqnum_id = template->header->seqnum_id; + h.tail_entry_seqnum = template->header->tail_entry_seqnum; + } else + h.seqnum_id = h.file_id; + + k = pwrite(f->fd, &h, sizeof(h), 0); + if (k < 0) + return -errno; + + if (k != sizeof(h)) + return -EIO; + + return 0; +} + +static int journal_file_refresh_header(JournalFile *f) { + int r; + sd_id128_t boot_id; + + assert(f); + + r = sd_id128_get_machine(&f->header->machine_id); + if (r < 0) + return r; + + r = sd_id128_get_boot(&boot_id); + if (r < 0) + return r; + + if (sd_id128_equal(boot_id, f->header->boot_id)) + f->tail_entry_monotonic_valid = true; + + f->header->boot_id = boot_id; + + f->header->state = STATE_ONLINE; + + /* Sync the online state to disk */ + msync(f->header, PAGE_ALIGN(sizeof(Header)), MS_SYNC); + fdatasync(f->fd); + + return 0; +} + +static int journal_file_verify_header(JournalFile *f) { + assert(f); + + if (memcmp(f->header->signature, HEADER_SIGNATURE, 8)) + return -EBADMSG; + + /* In both read and write mode we refuse to open files with + * incompatible flags we don't know */ +#ifdef HAVE_XZ + if ((le32toh(f->header->incompatible_flags) & ~HEADER_INCOMPATIBLE_COMPRESSED) != 0) + return -EPROTONOSUPPORT; +#else + if (f->header->incompatible_flags != 0) + return -EPROTONOSUPPORT; +#endif + + /* When open for writing we refuse to open files with + * compatible flags, too */ + if (f->writable) { +#ifdef HAVE_GCRYPT + if ((le32toh(f->header->compatible_flags) & ~HEADER_COMPATIBLE_SEALED) != 0) + return -EPROTONOSUPPORT; +#else + if (f->header->compatible_flags != 0) + return -EPROTONOSUPPORT; +#endif + } + + if (f->header->state >= _STATE_MAX) + return -EBADMSG; + + /* The first addition was n_data, so check that we are at least this large */ + if (le64toh(f->header->header_size) < HEADER_SIZE_MIN) + return -EBADMSG; + + if (JOURNAL_HEADER_SEALED(f->header) && !JOURNAL_HEADER_CONTAINS(f->header, n_entry_arrays)) + return -EBADMSG; + + if ((le64toh(f->header->header_size) + le64toh(f->header->arena_size)) > (uint64_t) f->last_stat.st_size) + return -ENODATA; + + if (le64toh(f->header->tail_object_offset) > (le64toh(f->header->header_size) + le64toh(f->header->arena_size))) + return -ENODATA; + + if (!VALID64(le64toh(f->header->data_hash_table_offset)) || + !VALID64(le64toh(f->header->field_hash_table_offset)) || + !VALID64(le64toh(f->header->tail_object_offset)) || + !VALID64(le64toh(f->header->entry_array_offset))) + return -ENODATA; + + if (le64toh(f->header->data_hash_table_offset) < le64toh(f->header->header_size) || + le64toh(f->header->field_hash_table_offset) < le64toh(f->header->header_size) || + le64toh(f->header->tail_object_offset) < le64toh(f->header->header_size) || + le64toh(f->header->entry_array_offset) < le64toh(f->header->header_size)) + return -ENODATA; + + if (f->writable) { + uint8_t state; + sd_id128_t machine_id; + int r; + + r = sd_id128_get_machine(&machine_id); + if (r < 0) + return r; + + if (!sd_id128_equal(machine_id, f->header->machine_id)) + return -EHOSTDOWN; + + state = f->header->state; + + if (state == STATE_ONLINE) { + log_debug("Journal file %s is already online. Assuming unclean closing.", f->path); + return -EBUSY; + } else if (state == STATE_ARCHIVED) + return -ESHUTDOWN; + else if (state != STATE_OFFLINE) { + log_debug("Journal file %s has unknown state %u.", f->path, state); + return -EBUSY; + } + } + + f->compress = JOURNAL_HEADER_COMPRESSED(f->header); + + f->seal = JOURNAL_HEADER_SEALED(f->header); + + return 0; +} + +static int journal_file_allocate(JournalFile *f, uint64_t offset, uint64_t size) { + uint64_t old_size, new_size; + int r; + + assert(f); + + /* We assume that this file is not sparse, and we know that + * for sure, since we always call posix_fallocate() + * ourselves */ + + old_size = + le64toh(f->header->header_size) + + le64toh(f->header->arena_size); + + new_size = PAGE_ALIGN(offset + size); + if (new_size < le64toh(f->header->header_size)) + new_size = le64toh(f->header->header_size); + + if (new_size <= old_size) + return 0; + + if (f->metrics.max_size > 0 && + new_size > f->metrics.max_size) + return -E2BIG; + + if (new_size > f->metrics.min_size && + f->metrics.keep_free > 0) { + struct statvfs svfs; + + if (fstatvfs(f->fd, &svfs) >= 0) { + uint64_t available; + + available = svfs.f_bfree * svfs.f_bsize; + + if (available >= f->metrics.keep_free) + available -= f->metrics.keep_free; + else + available = 0; + + if (new_size - old_size > available) + return -E2BIG; + } + } + + /* Note that the glibc fallocate() fallback is very + inefficient, hence we try to minimize the allocation area + as we can. */ + r = posix_fallocate(f->fd, old_size, new_size - old_size); + if (r != 0) + return -r; + + if (fstat(f->fd, &f->last_stat) < 0) + return -errno; + + f->header->arena_size = htole64(new_size - le64toh(f->header->header_size)); + + return 0; +} + +static int journal_file_move_to(JournalFile *f, int context, bool keep_always, uint64_t offset, uint64_t size, void **ret) { + assert(f); + assert(ret); + + if (size <= 0) + return -EINVAL; + + /* Avoid SIGBUS on invalid accesses */ + if (offset + size > (uint64_t) f->last_stat.st_size) { + /* Hmm, out of range? Let's refresh the fstat() data + * first, before we trust that check. */ + + if (fstat(f->fd, &f->last_stat) < 0 || + offset + size > (uint64_t) f->last_stat.st_size) + return -EADDRNOTAVAIL; + } + + return mmap_cache_get(f->mmap, f->fd, f->prot, context, keep_always, offset, size, &f->last_stat, ret); +} + +static uint64_t minimum_header_size(Object *o) { + + static uint64_t table[] = { + [OBJECT_DATA] = sizeof(DataObject), + [OBJECT_FIELD] = sizeof(FieldObject), + [OBJECT_ENTRY] = sizeof(EntryObject), + [OBJECT_DATA_HASH_TABLE] = sizeof(HashTableObject), + [OBJECT_FIELD_HASH_TABLE] = sizeof(HashTableObject), + [OBJECT_ENTRY_ARRAY] = sizeof(EntryArrayObject), + [OBJECT_TAG] = sizeof(TagObject), + }; + + if (o->object.type >= ELEMENTSOF(table) || table[o->object.type] <= 0) + return sizeof(ObjectHeader); + + return table[o->object.type]; +} + +int journal_file_move_to_object(JournalFile *f, int type, uint64_t offset, Object **ret) { + int r; + void *t; + Object *o; + uint64_t s; + unsigned context; + + assert(f); + assert(ret); + + /* Objects may only be located at multiple of 64 bit */ + if (!VALID64(offset)) + return -EFAULT; + + /* One context for each type, plus one catch-all for the rest */ + context = type > 0 && type < _OBJECT_TYPE_MAX ? type : 0; + + r = journal_file_move_to(f, context, false, offset, sizeof(ObjectHeader), &t); + if (r < 0) + return r; + + o = (Object*) t; + s = le64toh(o->object.size); + + if (s < sizeof(ObjectHeader)) + return -EBADMSG; + + if (o->object.type <= OBJECT_UNUSED) + return -EBADMSG; + + if (s < minimum_header_size(o)) + return -EBADMSG; + + if (type > 0 && o->object.type != type) + return -EBADMSG; + + if (s > sizeof(ObjectHeader)) { + r = journal_file_move_to(f, o->object.type, false, offset, s, &t); + if (r < 0) + return r; + + o = (Object*) t; + } + + *ret = o; + return 0; +} + +static uint64_t journal_file_entry_seqnum(JournalFile *f, uint64_t *seqnum) { + uint64_t r; + + assert(f); + + r = le64toh(f->header->tail_entry_seqnum) + 1; + + if (seqnum) { + /* If an external seqnum counter was passed, we update + * both the local and the external one, and set it to + * the maximum of both */ + + if (*seqnum + 1 > r) + r = *seqnum + 1; + + *seqnum = r; + } + + f->header->tail_entry_seqnum = htole64(r); + + if (f->header->head_entry_seqnum == 0) + f->header->head_entry_seqnum = htole64(r); + + return r; +} + +int journal_file_append_object(JournalFile *f, int type, uint64_t size, Object **ret, uint64_t *offset) { + int r; + uint64_t p; + Object *tail, *o; + void *t; + + assert(f); + assert(type > 0 && type < _OBJECT_TYPE_MAX); + assert(size >= sizeof(ObjectHeader)); + assert(offset); + assert(ret); + + p = le64toh(f->header->tail_object_offset); + if (p == 0) + p = le64toh(f->header->header_size); + else { + r = journal_file_move_to_object(f, -1, p, &tail); + if (r < 0) + return r; + + p += ALIGN64(le64toh(tail->object.size)); + } + + r = journal_file_allocate(f, p, size); + if (r < 0) + return r; + + r = journal_file_move_to(f, type, false, p, size, &t); + if (r < 0) + return r; + + o = (Object*) t; + + zero(o->object); + o->object.type = type; + o->object.size = htole64(size); + + f->header->tail_object_offset = htole64(p); + f->header->n_objects = htole64(le64toh(f->header->n_objects) + 1); + + *ret = o; + *offset = p; + + return 0; +} + +static int journal_file_setup_data_hash_table(JournalFile *f) { + uint64_t s, p; + Object *o; + int r; + + assert(f); + + /* We estimate that we need 1 hash table entry per 768 of + journal file and we want to make sure we never get beyond + 75% fill level. Calculate the hash table size for the + maximum file size based on these metrics. */ + + s = (f->metrics.max_size * 4 / 768 / 3) * sizeof(HashItem); + if (s < DEFAULT_DATA_HASH_TABLE_SIZE) + s = DEFAULT_DATA_HASH_TABLE_SIZE; + + log_debug("Reserving %llu entries in hash table.", (unsigned long long) (s / sizeof(HashItem))); + + r = journal_file_append_object(f, + OBJECT_DATA_HASH_TABLE, + offsetof(Object, hash_table.items) + s, + &o, &p); + if (r < 0) + return r; + + memset(o->hash_table.items, 0, s); + + f->header->data_hash_table_offset = htole64(p + offsetof(Object, hash_table.items)); + f->header->data_hash_table_size = htole64(s); + + return 0; +} + +static int journal_file_setup_field_hash_table(JournalFile *f) { + uint64_t s, p; + Object *o; + int r; + + assert(f); + + /* We use a fixed size hash table for the fields as this + * number should grow very slowly only */ + + s = DEFAULT_FIELD_HASH_TABLE_SIZE; + r = journal_file_append_object(f, + OBJECT_FIELD_HASH_TABLE, + offsetof(Object, hash_table.items) + s, + &o, &p); + if (r < 0) + return r; + + memset(o->hash_table.items, 0, s); + + f->header->field_hash_table_offset = htole64(p + offsetof(Object, hash_table.items)); + f->header->field_hash_table_size = htole64(s); + + return 0; +} + +static int journal_file_map_data_hash_table(JournalFile *f) { + uint64_t s, p; + void *t; + int r; + + assert(f); + + p = le64toh(f->header->data_hash_table_offset); + s = le64toh(f->header->data_hash_table_size); + + r = journal_file_move_to(f, + OBJECT_DATA_HASH_TABLE, + true, + p, s, + &t); + if (r < 0) + return r; + + f->data_hash_table = t; + return 0; +} + +static int journal_file_map_field_hash_table(JournalFile *f) { + uint64_t s, p; + void *t; + int r; + + assert(f); + + p = le64toh(f->header->field_hash_table_offset); + s = le64toh(f->header->field_hash_table_size); + + r = journal_file_move_to(f, + OBJECT_FIELD_HASH_TABLE, + true, + p, s, + &t); + if (r < 0) + return r; + + f->field_hash_table = t; + return 0; +} + +static int journal_file_link_field( + JournalFile *f, + Object *o, + uint64_t offset, + uint64_t hash) { + + uint64_t p, h; + int r; + + assert(f); + assert(o); + assert(offset > 0); + + if (o->object.type != OBJECT_FIELD) + return -EINVAL; + + /* This might alter the window we are looking at */ + + o->field.next_hash_offset = o->field.head_data_offset = 0; + + h = hash % (le64toh(f->header->field_hash_table_size) / sizeof(HashItem)); + p = le64toh(f->field_hash_table[h].tail_hash_offset); + if (p == 0) + f->field_hash_table[h].head_hash_offset = htole64(offset); + else { + r = journal_file_move_to_object(f, OBJECT_FIELD, p, &o); + if (r < 0) + return r; + + o->field.next_hash_offset = htole64(offset); + } + + f->field_hash_table[h].tail_hash_offset = htole64(offset); + + if (JOURNAL_HEADER_CONTAINS(f->header, n_fields)) + f->header->n_fields = htole64(le64toh(f->header->n_fields) + 1); + + return 0; +} + +static int journal_file_link_data( + JournalFile *f, + Object *o, + uint64_t offset, + uint64_t hash) { + + uint64_t p, h; + int r; + + assert(f); + assert(o); + assert(offset > 0); + + if (o->object.type != OBJECT_DATA) + return -EINVAL; + + /* This might alter the window we are looking at */ + + o->data.next_hash_offset = o->data.next_field_offset = 0; + o->data.entry_offset = o->data.entry_array_offset = 0; + o->data.n_entries = 0; + + h = hash % (le64toh(f->header->data_hash_table_size) / sizeof(HashItem)); + p = le64toh(f->data_hash_table[h].tail_hash_offset); + if (p == 0) + /* Only entry in the hash table is easy */ + f->data_hash_table[h].head_hash_offset = htole64(offset); + else { + /* Move back to the previous data object, to patch in + * pointer */ + + r = journal_file_move_to_object(f, OBJECT_DATA, p, &o); + if (r < 0) + return r; + + o->data.next_hash_offset = htole64(offset); + } + + f->data_hash_table[h].tail_hash_offset = htole64(offset); + + if (JOURNAL_HEADER_CONTAINS(f->header, n_data)) + f->header->n_data = htole64(le64toh(f->header->n_data) + 1); + + return 0; +} + +int journal_file_find_field_object_with_hash( + JournalFile *f, + const void *field, uint64_t size, uint64_t hash, + Object **ret, uint64_t *offset) { + + uint64_t p, osize, h; + int r; + + assert(f); + assert(field && size > 0); + + osize = offsetof(Object, field.payload) + size; + + if (f->header->field_hash_table_size == 0) + return -EBADMSG; + + h = hash % (le64toh(f->header->field_hash_table_size) / sizeof(HashItem)); + p = le64toh(f->field_hash_table[h].head_hash_offset); + + while (p > 0) { + Object *o; + + r = journal_file_move_to_object(f, OBJECT_FIELD, p, &o); + if (r < 0) + return r; + + if (le64toh(o->field.hash) == hash && + le64toh(o->object.size) == osize && + memcmp(o->field.payload, field, size) == 0) { + + if (ret) + *ret = o; + if (offset) + *offset = p; + + return 1; + } + + p = le64toh(o->field.next_hash_offset); + } + + return 0; +} + +int journal_file_find_field_object( + JournalFile *f, + const void *field, uint64_t size, + Object **ret, uint64_t *offset) { + + uint64_t hash; + + assert(f); + assert(field && size > 0); + + hash = hash64(field, size); + + return journal_file_find_field_object_with_hash(f, + field, size, hash, + ret, offset); +} + +int journal_file_find_data_object_with_hash( + JournalFile *f, + const void *data, uint64_t size, uint64_t hash, + Object **ret, uint64_t *offset) { + + uint64_t p, osize, h; + int r; + + assert(f); + assert(data || size == 0); + + osize = offsetof(Object, data.payload) + size; + + if (f->header->data_hash_table_size == 0) + return -EBADMSG; + + h = hash % (le64toh(f->header->data_hash_table_size) / sizeof(HashItem)); + p = le64toh(f->data_hash_table[h].head_hash_offset); + + while (p > 0) { + Object *o; + + r = journal_file_move_to_object(f, OBJECT_DATA, p, &o); + if (r < 0) + return r; + + if (le64toh(o->data.hash) != hash) + goto next; + + if (o->object.flags & OBJECT_COMPRESSED) { +#ifdef HAVE_XZ + uint64_t l, rsize; + + l = le64toh(o->object.size); + if (l <= offsetof(Object, data.payload)) + return -EBADMSG; + + l -= offsetof(Object, data.payload); + + if (!uncompress_blob(o->data.payload, l, &f->compress_buffer, &f->compress_buffer_size, &rsize, 0)) + return -EBADMSG; + + if (rsize == size && + memcmp(f->compress_buffer, data, size) == 0) { + + if (ret) + *ret = o; + + if (offset) + *offset = p; + + return 1; + } +#else + return -EPROTONOSUPPORT; +#endif + + } else if (le64toh(o->object.size) == osize && + memcmp(o->data.payload, data, size) == 0) { + + if (ret) + *ret = o; + + if (offset) + *offset = p; + + return 1; + } + + next: + p = le64toh(o->data.next_hash_offset); + } + + return 0; +} + +int journal_file_find_data_object( + JournalFile *f, + const void *data, uint64_t size, + Object **ret, uint64_t *offset) { + + uint64_t hash; + + assert(f); + assert(data || size == 0); + + hash = hash64(data, size); + + return journal_file_find_data_object_with_hash(f, + data, size, hash, + ret, offset); +} + +static int journal_file_append_field( + JournalFile *f, + const void *field, uint64_t size, + Object **ret, uint64_t *offset) { + + uint64_t hash, p; + uint64_t osize; + Object *o; + int r; + + assert(f); + assert(field && size > 0); + + hash = hash64(field, size); + + r = journal_file_find_field_object_with_hash(f, field, size, hash, &o, &p); + if (r < 0) + return r; + else if (r > 0) { + + if (ret) + *ret = o; + + if (offset) + *offset = p; + + return 0; + } + + osize = offsetof(Object, field.payload) + size; + r = journal_file_append_object(f, OBJECT_FIELD, osize, &o, &p); + + o->field.hash = htole64(hash); + memcpy(o->field.payload, field, size); + + r = journal_file_link_field(f, o, p, hash); + if (r < 0) + return r; + + /* The linking might have altered the window, so let's + * refresh our pointer */ + r = journal_file_move_to_object(f, OBJECT_FIELD, p, &o); + if (r < 0) + return r; + +#ifdef HAVE_GCRYPT + r = journal_file_hmac_put_object(f, OBJECT_FIELD, o, p); + if (r < 0) + return r; +#endif + + if (ret) + *ret = o; + + if (offset) + *offset = p; + + return 0; +} + +static int journal_file_append_data( + JournalFile *f, + const void *data, uint64_t size, + Object **ret, uint64_t *offset) { + + uint64_t hash, p; + uint64_t osize; + Object *o; + int r; + bool compressed = false; + const void *eq; + + assert(f); + assert(data || size == 0); + + hash = hash64(data, size); + + r = journal_file_find_data_object_with_hash(f, data, size, hash, &o, &p); + if (r < 0) + return r; + else if (r > 0) { + + if (ret) + *ret = o; + + if (offset) + *offset = p; + + return 0; + } + + osize = offsetof(Object, data.payload) + size; + r = journal_file_append_object(f, OBJECT_DATA, osize, &o, &p); + if (r < 0) + return r; + + o->data.hash = htole64(hash); + +#ifdef HAVE_XZ + if (f->compress && + size >= COMPRESSION_SIZE_THRESHOLD) { + uint64_t rsize; + + compressed = compress_blob(data, size, o->data.payload, &rsize); + + if (compressed) { + o->object.size = htole64(offsetof(Object, data.payload) + rsize); + o->object.flags |= OBJECT_COMPRESSED; + + log_debug("Compressed data object %lu -> %lu", (unsigned long) size, (unsigned long) rsize); + } + } +#endif + + if (!compressed && size > 0) + memcpy(o->data.payload, data, size); + + r = journal_file_link_data(f, o, p, hash); + if (r < 0) + return r; + + /* The linking might have altered the window, so let's + * refresh our pointer */ + r = journal_file_move_to_object(f, OBJECT_DATA, p, &o); + if (r < 0) + return r; + + eq = memchr(data, '=', size); + if (eq && eq > data) { + uint64_t fp; + Object *fo; + + /* Create field object ... */ + r = journal_file_append_field(f, data, (uint8_t*) eq - (uint8_t*) data, &fo, &fp); + if (r < 0) + return r; + + /* ... and link it in. */ + o->data.next_field_offset = fo->field.head_data_offset; + fo->field.head_data_offset = le64toh(p); + } + +#ifdef HAVE_GCRYPT + r = journal_file_hmac_put_object(f, OBJECT_DATA, o, p); + if (r < 0) + return r; +#endif + + if (ret) + *ret = o; + + if (offset) + *offset = p; + + return 0; +} + +uint64_t journal_file_entry_n_items(Object *o) { + assert(o); + + if (o->object.type != OBJECT_ENTRY) + return 0; + + return (le64toh(o->object.size) - offsetof(Object, entry.items)) / sizeof(EntryItem); +} + +uint64_t journal_file_entry_array_n_items(Object *o) { + assert(o); + + if (o->object.type != OBJECT_ENTRY_ARRAY) + return 0; + + return (le64toh(o->object.size) - offsetof(Object, entry_array.items)) / sizeof(uint64_t); +} + +uint64_t journal_file_hash_table_n_items(Object *o) { + assert(o); + + if (o->object.type != OBJECT_DATA_HASH_TABLE && + o->object.type != OBJECT_FIELD_HASH_TABLE) + return 0; + + return (le64toh(o->object.size) - offsetof(Object, hash_table.items)) / sizeof(HashItem); +} + +static int link_entry_into_array(JournalFile *f, + le64_t *first, + le64_t *idx, + uint64_t p) { + int r; + uint64_t n = 0, ap = 0, q, i, a, hidx; + Object *o; + + assert(f); + assert(first); + assert(idx); + assert(p > 0); + + a = le64toh(*first); + i = hidx = le64toh(*idx); + while (a > 0) { + + r = journal_file_move_to_object(f, OBJECT_ENTRY_ARRAY, a, &o); + if (r < 0) + return r; + + n = journal_file_entry_array_n_items(o); + if (i < n) { + o->entry_array.items[i] = htole64(p); + *idx = htole64(hidx + 1); + return 0; + } + + i -= n; + ap = a; + a = le64toh(o->entry_array.next_entry_array_offset); + } + + if (hidx > n) + n = (hidx+1) * 2; + else + n = n * 2; + + if (n < 4) + n = 4; + + r = journal_file_append_object(f, OBJECT_ENTRY_ARRAY, + offsetof(Object, entry_array.items) + n * sizeof(uint64_t), + &o, &q); + if (r < 0) + return r; + +#ifdef HAVE_GCRYPT + r = journal_file_hmac_put_object(f, OBJECT_ENTRY_ARRAY, o, q); + if (r < 0) + return r; +#endif + + o->entry_array.items[i] = htole64(p); + + if (ap == 0) + *first = htole64(q); + else { + r = journal_file_move_to_object(f, OBJECT_ENTRY_ARRAY, ap, &o); + if (r < 0) + return r; + + o->entry_array.next_entry_array_offset = htole64(q); + } + + if (JOURNAL_HEADER_CONTAINS(f->header, n_entry_arrays)) + f->header->n_entry_arrays = htole64(le64toh(f->header->n_entry_arrays) + 1); + + *idx = htole64(hidx + 1); + + return 0; +} + +static int link_entry_into_array_plus_one(JournalFile *f, + le64_t *extra, + le64_t *first, + le64_t *idx, + uint64_t p) { + + int r; + + assert(f); + assert(extra); + assert(first); + assert(idx); + assert(p > 0); + + if (*idx == 0) + *extra = htole64(p); + else { + le64_t i; + + i = htole64(le64toh(*idx) - 1); + r = link_entry_into_array(f, first, &i, p); + if (r < 0) + return r; + } + + *idx = htole64(le64toh(*idx) + 1); + return 0; +} + +static int journal_file_link_entry_item(JournalFile *f, Object *o, uint64_t offset, uint64_t i) { + uint64_t p; + int r; + assert(f); + assert(o); + assert(offset > 0); + + p = le64toh(o->entry.items[i].object_offset); + if (p == 0) + return -EINVAL; + + r = journal_file_move_to_object(f, OBJECT_DATA, p, &o); + if (r < 0) + return r; + + return link_entry_into_array_plus_one(f, + &o->data.entry_offset, + &o->data.entry_array_offset, + &o->data.n_entries, + offset); +} + +static int journal_file_link_entry(JournalFile *f, Object *o, uint64_t offset) { + uint64_t n, i; + int r; + + assert(f); + assert(o); + assert(offset > 0); + + if (o->object.type != OBJECT_ENTRY) + return -EINVAL; + + __sync_synchronize(); + + /* Link up the entry itself */ + r = link_entry_into_array(f, + &f->header->entry_array_offset, + &f->header->n_entries, + offset); + if (r < 0) + return r; + + /* log_debug("=> %s seqnr=%lu n_entries=%lu", f->path, (unsigned long) o->entry.seqnum, (unsigned long) f->header->n_entries); */ + + if (f->header->head_entry_realtime == 0) + f->header->head_entry_realtime = o->entry.realtime; + + f->header->tail_entry_realtime = o->entry.realtime; + f->header->tail_entry_monotonic = o->entry.monotonic; + + f->tail_entry_monotonic_valid = true; + + /* Link up the items */ + n = journal_file_entry_n_items(o); + for (i = 0; i < n; i++) { + r = journal_file_link_entry_item(f, o, offset, i); + if (r < 0) + return r; + } + + return 0; +} + +static int journal_file_append_entry_internal( + JournalFile *f, + const dual_timestamp *ts, + uint64_t xor_hash, + const EntryItem items[], unsigned n_items, + uint64_t *seqnum, + Object **ret, uint64_t *offset) { + uint64_t np; + uint64_t osize; + Object *o; + int r; + + assert(f); + assert(items || n_items == 0); + assert(ts); + + osize = offsetof(Object, entry.items) + (n_items * sizeof(EntryItem)); + + r = journal_file_append_object(f, OBJECT_ENTRY, osize, &o, &np); + if (r < 0) + return r; + + o->entry.seqnum = htole64(journal_file_entry_seqnum(f, seqnum)); + memcpy(o->entry.items, items, n_items * sizeof(EntryItem)); + o->entry.realtime = htole64(ts->realtime); + o->entry.monotonic = htole64(ts->monotonic); + o->entry.xor_hash = htole64(xor_hash); + o->entry.boot_id = f->header->boot_id; + +#ifdef HAVE_GCRYPT + r = journal_file_hmac_put_object(f, OBJECT_ENTRY, o, np); + if (r < 0) + return r; +#endif + + r = journal_file_link_entry(f, o, np); + if (r < 0) + return r; + + if (ret) + *ret = o; + + if (offset) + *offset = np; + + return 0; +} + +void journal_file_post_change(JournalFile *f) { + assert(f); + + /* inotify() does not receive IN_MODIFY events from file + * accesses done via mmap(). After each access we hence + * trigger IN_MODIFY by truncating the journal file to its + * current size which triggers IN_MODIFY. */ + + __sync_synchronize(); + + if (ftruncate(f->fd, f->last_stat.st_size) < 0) + log_error("Failed to truncate file to its own size: %m"); +} + +static int entry_item_cmp(const void *_a, const void *_b) { + const EntryItem *a = _a, *b = _b; + + if (le64toh(a->object_offset) < le64toh(b->object_offset)) + return -1; + if (le64toh(a->object_offset) > le64toh(b->object_offset)) + return 1; + return 0; +} + +int journal_file_append_entry(JournalFile *f, const dual_timestamp *ts, const struct iovec iovec[], unsigned n_iovec, uint64_t *seqnum, Object **ret, uint64_t *offset) { + unsigned i; + EntryItem *items; + int r; + uint64_t xor_hash = 0; + struct dual_timestamp _ts; + + assert(f); + assert(iovec || n_iovec == 0); + + if (!f->writable) + return -EPERM; + + if (!ts) { + dual_timestamp_get(&_ts); + ts = &_ts; + } + + if (f->tail_entry_monotonic_valid && + ts->monotonic < le64toh(f->header->tail_entry_monotonic)) + return -EINVAL; + +#ifdef HAVE_GCRYPT + r = journal_file_maybe_append_tag(f, ts->realtime); + if (r < 0) + return r; +#endif + + /* alloca() can't take 0, hence let's allocate at least one */ + items = alloca(sizeof(EntryItem) * MAX(1, n_iovec)); + + for (i = 0; i < n_iovec; i++) { + uint64_t p; + Object *o; + + r = journal_file_append_data(f, iovec[i].iov_base, iovec[i].iov_len, &o, &p); + if (r < 0) + return r; + + xor_hash ^= le64toh(o->data.hash); + items[i].object_offset = htole64(p); + items[i].hash = o->data.hash; + } + + /* Order by the position on disk, in order to improve seek + * times for rotating media. */ + qsort(items, n_iovec, sizeof(EntryItem), entry_item_cmp); + + r = journal_file_append_entry_internal(f, ts, xor_hash, items, n_iovec, seqnum, ret, offset); + + journal_file_post_change(f); + + return r; +} + +typedef struct ChainCacheItem { + uint64_t first; /* the array at the begin of the chain */ + uint64_t array; /* the cached array */ + uint64_t begin; /* the first item in the cached array */ + uint64_t total; /* the total number of items in all arrays before this one in the chain */ +} ChainCacheItem; + +static void chain_cache_put( + Hashmap *h, + ChainCacheItem *ci, + uint64_t first, + uint64_t array, + uint64_t begin, + uint64_t total) { + + if (!ci) { + /* If the chain item to cache for this chain is the + * first one it's not worth caching anything */ + if (array == first) + return; + + if (hashmap_size(h) >= CHAIN_CACHE_MAX) + ci = hashmap_steal_first(h); + else { + ci = new(ChainCacheItem, 1); + if (!ci) + return; + } + + ci->first = first; + + if (hashmap_put(h, &ci->first, ci) < 0) { + free(ci); + return; + } + } else + assert(ci->first == first); + + ci->array = array; + ci->begin = begin; + ci->total = total; +} + +static int generic_array_get(JournalFile *f, + uint64_t first, + uint64_t i, + Object **ret, uint64_t *offset) { + + Object *o; + uint64_t p = 0, a, t = 0; + int r; + ChainCacheItem *ci; + + assert(f); + + a = first; + + /* Try the chain cache first */ + ci = hashmap_get(f->chain_cache, &first); + if (ci && i > ci->total) { + a = ci->array; + i -= ci->total; + t = ci->total; + } + + while (a > 0) { + uint64_t k; + + r = journal_file_move_to_object(f, OBJECT_ENTRY_ARRAY, a, &o); + if (r < 0) + return r; + + k = journal_file_entry_array_n_items(o); + if (i < k) { + p = le64toh(o->entry_array.items[i]); + goto found; + } + + i -= k; + t += k; + a = le64toh(o->entry_array.next_entry_array_offset); + } + + return 0; + +found: + /* Let's cache this item for the next invocation */ + chain_cache_put(f->chain_cache, ci, first, a, o->entry_array.items[0], t); + + r = journal_file_move_to_object(f, OBJECT_ENTRY, p, &o); + if (r < 0) + return r; + + if (ret) + *ret = o; + + if (offset) + *offset = p; + + return 1; +} + +static int generic_array_get_plus_one(JournalFile *f, + uint64_t extra, + uint64_t first, + uint64_t i, + Object **ret, uint64_t *offset) { + + Object *o; + + assert(f); + + if (i == 0) { + int r; + + r = journal_file_move_to_object(f, OBJECT_ENTRY, extra, &o); + if (r < 0) + return r; + + if (ret) + *ret = o; + + if (offset) + *offset = extra; + + return 1; + } + + return generic_array_get(f, first, i-1, ret, offset); +} + +enum { + TEST_FOUND, + TEST_LEFT, + TEST_RIGHT +}; + +static int generic_array_bisect(JournalFile *f, + uint64_t first, + uint64_t n, + uint64_t needle, + int (*test_object)(JournalFile *f, uint64_t p, uint64_t needle), + direction_t direction, + Object **ret, + uint64_t *offset, + uint64_t *idx) { + + uint64_t a, p, t = 0, i = 0, last_p = 0; + bool subtract_one = false; + Object *o, *array = NULL; + int r; + ChainCacheItem *ci; + + assert(f); + assert(test_object); + + /* Start with the first array in the chain */ + a = first; + + ci = hashmap_get(f->chain_cache, &first); + if (ci && n > ci->total) { + /* Ah, we have iterated this bisection array chain + * previously! Let's see if we can skip ahead in the + * chain, as far as the last time. But we can't jump + * backwards in the chain, so let's check that + * first. */ + + r = test_object(f, ci->begin, needle); + if (r < 0) + return r; + + if (r == TEST_LEFT) { + /* OK, what we are looking for is right of th + * begin of this EntryArray, so let's jump + * straight to previously cached array in the + * chain */ + + a = ci->array; + n -= ci->total; + t = ci->total; + } + } + + while (a > 0) { + uint64_t left, right, k, lp; + + r = journal_file_move_to_object(f, OBJECT_ENTRY_ARRAY, a, &array); + if (r < 0) + return r; + + k = journal_file_entry_array_n_items(array); + right = MIN(k, n); + if (right <= 0) + return 0; + + i = right - 1; + lp = p = le64toh(array->entry_array.items[i]); + if (p <= 0) + return -EBADMSG; + + r = test_object(f, p, needle); + if (r < 0) + return r; + + if (r == TEST_FOUND) + r = direction == DIRECTION_DOWN ? TEST_RIGHT : TEST_LEFT; + + if (r == TEST_RIGHT) { + left = 0; + right -= 1; + for (;;) { + if (left == right) { + if (direction == DIRECTION_UP) + subtract_one = true; + + i = left; + goto found; + } + + assert(left < right); + + i = (left + right) / 2; + p = le64toh(array->entry_array.items[i]); + if (p <= 0) + return -EBADMSG; + + r = test_object(f, p, needle); + if (r < 0) + return r; + + if (r == TEST_FOUND) + r = direction == DIRECTION_DOWN ? TEST_RIGHT : TEST_LEFT; + + if (r == TEST_RIGHT) + right = i; + else + left = i + 1; + } + } + + if (k > n) { + if (direction == DIRECTION_UP) { + i = n; + subtract_one = true; + goto found; + } + + return 0; + } + + last_p = lp; + + n -= k; + t += k; + a = le64toh(array->entry_array.next_entry_array_offset); + } + + return 0; + +found: + if (subtract_one && t == 0 && i == 0) + return 0; + + /* Let's cache this item for the next invocation */ + chain_cache_put(f->chain_cache, ci, first, a, array->entry_array.items[0], t); + + if (subtract_one && i == 0) + p = last_p; + else if (subtract_one) + p = le64toh(array->entry_array.items[i-1]); + else + p = le64toh(array->entry_array.items[i]); + + r = journal_file_move_to_object(f, OBJECT_ENTRY, p, &o); + if (r < 0) + return r; + + if (ret) + *ret = o; + + if (offset) + *offset = p; + + if (idx) + *idx = t + i + (subtract_one ? -1 : 0); + + return 1; +} + +static int generic_array_bisect_plus_one(JournalFile *f, + uint64_t extra, + uint64_t first, + uint64_t n, + uint64_t needle, + int (*test_object)(JournalFile *f, uint64_t p, uint64_t needle), + direction_t direction, + Object **ret, + uint64_t *offset, + uint64_t *idx) { + + int r; + bool step_back = false; + Object *o; + + assert(f); + assert(test_object); + + if (n <= 0) + return 0; + + /* This bisects the array in object 'first', but first checks + * an extra */ + r = test_object(f, extra, needle); + if (r < 0) + return r; + + if (r == TEST_FOUND) + r = direction == DIRECTION_DOWN ? TEST_RIGHT : TEST_LEFT; + + /* if we are looking with DIRECTION_UP then we need to first + see if in the actual array there is a matching entry, and + return the last one of that. But if there isn't any we need + to return this one. Hence remember this, and return it + below. */ + if (r == TEST_LEFT) + step_back = direction == DIRECTION_UP; + + if (r == TEST_RIGHT) { + if (direction == DIRECTION_DOWN) + goto found; + else + return 0; + } + + r = generic_array_bisect(f, first, n-1, needle, test_object, direction, ret, offset, idx); + + if (r == 0 && step_back) + goto found; + + if (r > 0 && idx) + (*idx) ++; + + return r; + +found: + r = journal_file_move_to_object(f, OBJECT_ENTRY, extra, &o); + if (r < 0) + return r; + + if (ret) + *ret = o; + + if (offset) + *offset = extra; + + if (idx) + *idx = 0; + + return 1; +} + +static int test_object_offset(JournalFile *f, uint64_t p, uint64_t needle) { + assert(f); + assert(p > 0); + + if (p == needle) + return TEST_FOUND; + else if (p < needle) + return TEST_LEFT; + else + return TEST_RIGHT; +} + +int journal_file_move_to_entry_by_offset( + JournalFile *f, + uint64_t p, + direction_t direction, + Object **ret, + uint64_t *offset) { + + return generic_array_bisect(f, + le64toh(f->header->entry_array_offset), + le64toh(f->header->n_entries), + p, + test_object_offset, + direction, + ret, offset, NULL); +} + + +static int test_object_seqnum(JournalFile *f, uint64_t p, uint64_t needle) { + Object *o; + int r; + + assert(f); + assert(p > 0); + + r = journal_file_move_to_object(f, OBJECT_ENTRY, p, &o); + if (r < 0) + return r; + + if (le64toh(o->entry.seqnum) == needle) + return TEST_FOUND; + else if (le64toh(o->entry.seqnum) < needle) + return TEST_LEFT; + else + return TEST_RIGHT; +} + +int journal_file_move_to_entry_by_seqnum( + JournalFile *f, + uint64_t seqnum, + direction_t direction, + Object **ret, + uint64_t *offset) { + + return generic_array_bisect(f, + le64toh(f->header->entry_array_offset), + le64toh(f->header->n_entries), + seqnum, + test_object_seqnum, + direction, + ret, offset, NULL); +} + +static int test_object_realtime(JournalFile *f, uint64_t p, uint64_t needle) { + Object *o; + int r; + + assert(f); + assert(p > 0); + + r = journal_file_move_to_object(f, OBJECT_ENTRY, p, &o); + if (r < 0) + return r; + + if (le64toh(o->entry.realtime) == needle) + return TEST_FOUND; + else if (le64toh(o->entry.realtime) < needle) + return TEST_LEFT; + else + return TEST_RIGHT; +} + +int journal_file_move_to_entry_by_realtime( + JournalFile *f, + uint64_t realtime, + direction_t direction, + Object **ret, + uint64_t *offset) { + + return generic_array_bisect(f, + le64toh(f->header->entry_array_offset), + le64toh(f->header->n_entries), + realtime, + test_object_realtime, + direction, + ret, offset, NULL); +} + +static int test_object_monotonic(JournalFile *f, uint64_t p, uint64_t needle) { + Object *o; + int r; + + assert(f); + assert(p > 0); + + r = journal_file_move_to_object(f, OBJECT_ENTRY, p, &o); + if (r < 0) + return r; + + if (le64toh(o->entry.monotonic) == needle) + return TEST_FOUND; + else if (le64toh(o->entry.monotonic) < needle) + return TEST_LEFT; + else + return TEST_RIGHT; +} + +int journal_file_move_to_entry_by_monotonic( + JournalFile *f, + sd_id128_t boot_id, + uint64_t monotonic, + direction_t direction, + Object **ret, + uint64_t *offset) { + + char t[9+32+1] = "_BOOT_ID="; + Object *o; + int r; + + assert(f); + + sd_id128_to_string(boot_id, t + 9); + r = journal_file_find_data_object(f, t, strlen(t), &o, NULL); + if (r < 0) + return r; + if (r == 0) + return -ENOENT; + + return generic_array_bisect_plus_one(f, + le64toh(o->data.entry_offset), + le64toh(o->data.entry_array_offset), + le64toh(o->data.n_entries), + monotonic, + test_object_monotonic, + direction, + ret, offset, NULL); +} + +int journal_file_next_entry( + JournalFile *f, + Object *o, uint64_t p, + direction_t direction, + Object **ret, uint64_t *offset) { + + uint64_t i, n; + int r; + + assert(f); + assert(p > 0 || !o); + + n = le64toh(f->header->n_entries); + if (n <= 0) + return 0; + + if (!o) + i = direction == DIRECTION_DOWN ? 0 : n - 1; + else { + if (o->object.type != OBJECT_ENTRY) + return -EINVAL; + + r = generic_array_bisect(f, + le64toh(f->header->entry_array_offset), + le64toh(f->header->n_entries), + p, + test_object_offset, + DIRECTION_DOWN, + NULL, NULL, + &i); + if (r <= 0) + return r; + + if (direction == DIRECTION_DOWN) { + if (i >= n - 1) + return 0; + + i++; + } else { + if (i <= 0) + return 0; + + i--; + } + } + + /* And jump to it */ + return generic_array_get(f, + le64toh(f->header->entry_array_offset), + i, + ret, offset); +} + +int journal_file_skip_entry( + JournalFile *f, + Object *o, uint64_t p, + int64_t skip, + Object **ret, uint64_t *offset) { + + uint64_t i, n; + int r; + + assert(f); + assert(o); + assert(p > 0); + + if (o->object.type != OBJECT_ENTRY) + return -EINVAL; + + r = generic_array_bisect(f, + le64toh(f->header->entry_array_offset), + le64toh(f->header->n_entries), + p, + test_object_offset, + DIRECTION_DOWN, + NULL, NULL, + &i); + if (r <= 0) + return r; + + /* Calculate new index */ + if (skip < 0) { + if ((uint64_t) -skip >= i) + i = 0; + else + i = i - (uint64_t) -skip; + } else + i += (uint64_t) skip; + + n = le64toh(f->header->n_entries); + if (n <= 0) + return -EBADMSG; + + if (i >= n) + i = n-1; + + return generic_array_get(f, + le64toh(f->header->entry_array_offset), + i, + ret, offset); +} + +int journal_file_next_entry_for_data( + JournalFile *f, + Object *o, uint64_t p, + uint64_t data_offset, + direction_t direction, + Object **ret, uint64_t *offset) { + + uint64_t n, i; + int r; + Object *d; + + assert(f); + assert(p > 0 || !o); + + r = journal_file_move_to_object(f, OBJECT_DATA, data_offset, &d); + if (r < 0) + return r; + + n = le64toh(d->data.n_entries); + if (n <= 0) + return n; + + if (!o) + i = direction == DIRECTION_DOWN ? 0 : n - 1; + else { + if (o->object.type != OBJECT_ENTRY) + return -EINVAL; + + r = generic_array_bisect_plus_one(f, + le64toh(d->data.entry_offset), + le64toh(d->data.entry_array_offset), + le64toh(d->data.n_entries), + p, + test_object_offset, + DIRECTION_DOWN, + NULL, NULL, + &i); + + if (r <= 0) + return r; + + if (direction == DIRECTION_DOWN) { + if (i >= n - 1) + return 0; + + i++; + } else { + if (i <= 0) + return 0; + + i--; + } + + } + + return generic_array_get_plus_one(f, + le64toh(d->data.entry_offset), + le64toh(d->data.entry_array_offset), + i, + ret, offset); +} + +int journal_file_move_to_entry_by_offset_for_data( + JournalFile *f, + uint64_t data_offset, + uint64_t p, + direction_t direction, + Object **ret, uint64_t *offset) { + + int r; + Object *d; + + assert(f); + + r = journal_file_move_to_object(f, OBJECT_DATA, data_offset, &d); + if (r < 0) + return r; + + return generic_array_bisect_plus_one(f, + le64toh(d->data.entry_offset), + le64toh(d->data.entry_array_offset), + le64toh(d->data.n_entries), + p, + test_object_offset, + direction, + ret, offset, NULL); +} + +int journal_file_move_to_entry_by_monotonic_for_data( + JournalFile *f, + uint64_t data_offset, + sd_id128_t boot_id, + uint64_t monotonic, + direction_t direction, + Object **ret, uint64_t *offset) { + + char t[9+32+1] = "_BOOT_ID="; + Object *o, *d; + int r; + uint64_t b, z; + + assert(f); + + /* First, seek by time */ + sd_id128_to_string(boot_id, t + 9); + r = journal_file_find_data_object(f, t, strlen(t), &o, &b); + if (r < 0) + return r; + if (r == 0) + return -ENOENT; + + r = generic_array_bisect_plus_one(f, + le64toh(o->data.entry_offset), + le64toh(o->data.entry_array_offset), + le64toh(o->data.n_entries), + monotonic, + test_object_monotonic, + direction, + NULL, &z, NULL); + if (r <= 0) + return r; + + /* And now, continue seeking until we find an entry that + * exists in both bisection arrays */ + + for (;;) { + Object *qo; + uint64_t p, q; + + r = journal_file_move_to_object(f, OBJECT_DATA, data_offset, &d); + if (r < 0) + return r; + + r = generic_array_bisect_plus_one(f, + le64toh(d->data.entry_offset), + le64toh(d->data.entry_array_offset), + le64toh(d->data.n_entries), + z, + test_object_offset, + direction, + NULL, &p, NULL); + if (r <= 0) + return r; + + r = journal_file_move_to_object(f, OBJECT_DATA, b, &o); + if (r < 0) + return r; + + r = generic_array_bisect_plus_one(f, + le64toh(o->data.entry_offset), + le64toh(o->data.entry_array_offset), + le64toh(o->data.n_entries), + p, + test_object_offset, + direction, + &qo, &q, NULL); + + if (r <= 0) + return r; + + if (p == q) { + if (ret) + *ret = qo; + if (offset) + *offset = q; + + return 1; + } + + z = q; + } + + return 0; +} + +int journal_file_move_to_entry_by_seqnum_for_data( + JournalFile *f, + uint64_t data_offset, + uint64_t seqnum, + direction_t direction, + Object **ret, uint64_t *offset) { + + Object *d; + int r; + + assert(f); + + r = journal_file_move_to_object(f, OBJECT_DATA, data_offset, &d); + if (r < 0) + return r; + + return generic_array_bisect_plus_one(f, + le64toh(d->data.entry_offset), + le64toh(d->data.entry_array_offset), + le64toh(d->data.n_entries), + seqnum, + test_object_seqnum, + direction, + ret, offset, NULL); +} + +int journal_file_move_to_entry_by_realtime_for_data( + JournalFile *f, + uint64_t data_offset, + uint64_t realtime, + direction_t direction, + Object **ret, uint64_t *offset) { + + Object *d; + int r; + + assert(f); + + r = journal_file_move_to_object(f, OBJECT_DATA, data_offset, &d); + if (r < 0) + return r; + + return generic_array_bisect_plus_one(f, + le64toh(d->data.entry_offset), + le64toh(d->data.entry_array_offset), + le64toh(d->data.n_entries), + realtime, + test_object_realtime, + direction, + ret, offset, NULL); +} + +void journal_file_dump(JournalFile *f) { + Object *o; + int r; + uint64_t p; + + assert(f); + + journal_file_print_header(f); + + p = le64toh(f->header->header_size); + while (p != 0) { + r = journal_file_move_to_object(f, -1, p, &o); + if (r < 0) + goto fail; + + switch (o->object.type) { + + case OBJECT_UNUSED: + printf("Type: OBJECT_UNUSED\n"); + break; + + case OBJECT_DATA: + printf("Type: OBJECT_DATA\n"); + break; + + case OBJECT_FIELD: + printf("Type: OBJECT_FIELD\n"); + break; + + case OBJECT_ENTRY: + printf("Type: OBJECT_ENTRY seqnum=%llu monotonic=%llu realtime=%llu\n", + (unsigned long long) le64toh(o->entry.seqnum), + (unsigned long long) le64toh(o->entry.monotonic), + (unsigned long long) le64toh(o->entry.realtime)); + break; + + case OBJECT_FIELD_HASH_TABLE: + printf("Type: OBJECT_FIELD_HASH_TABLE\n"); + break; + + case OBJECT_DATA_HASH_TABLE: + printf("Type: OBJECT_DATA_HASH_TABLE\n"); + break; + + case OBJECT_ENTRY_ARRAY: + printf("Type: OBJECT_ENTRY_ARRAY\n"); + break; + + case OBJECT_TAG: + printf("Type: OBJECT_TAG seqnum=%llu epoch=%llu\n", + (unsigned long long) le64toh(o->tag.seqnum), + (unsigned long long) le64toh(o->tag.epoch)); + break; + + default: + printf("Type: unknown (%u)\n", o->object.type); + break; + } + + if (o->object.flags & OBJECT_COMPRESSED) + printf("Flags: COMPRESSED\n"); + + if (p == le64toh(f->header->tail_object_offset)) + p = 0; + else + p = p + ALIGN64(le64toh(o->object.size)); + } + + return; +fail: + log_error("File corrupt"); +} + +void journal_file_print_header(JournalFile *f) { + char a[33], b[33], c[33]; + char x[FORMAT_TIMESTAMP_MAX], y[FORMAT_TIMESTAMP_MAX]; + struct stat st; + char bytes[FORMAT_BYTES_MAX]; + + assert(f); + + printf("File Path: %s\n" + "File ID: %s\n" + "Machine ID: %s\n" + "Boot ID: %s\n" + "Sequential Number ID: %s\n" + "State: %s\n" + "Compatible Flags:%s%s\n" + "Incompatible Flags:%s%s\n" + "Header size: %llu\n" + "Arena size: %llu\n" + "Data Hash Table Size: %llu\n" + "Field Hash Table Size: %llu\n" + "Rotate Suggested: %s\n" + "Head Sequential Number: %llu\n" + "Tail Sequential Number: %llu\n" + "Head Realtime Timestamp: %s\n" + "Tail Realtime Timestamp: %s\n" + "Objects: %llu\n" + "Entry Objects: %llu\n", + f->path, + sd_id128_to_string(f->header->file_id, a), + sd_id128_to_string(f->header->machine_id, b), + sd_id128_to_string(f->header->boot_id, c), + sd_id128_to_string(f->header->seqnum_id, c), + f->header->state == STATE_OFFLINE ? "OFFLINE" : + f->header->state == STATE_ONLINE ? "ONLINE" : + f->header->state == STATE_ARCHIVED ? "ARCHIVED" : "UNKNOWN", + JOURNAL_HEADER_SEALED(f->header) ? " SEALED" : "", + (le32toh(f->header->compatible_flags) & ~HEADER_COMPATIBLE_SEALED) ? " ???" : "", + JOURNAL_HEADER_COMPRESSED(f->header) ? " COMPRESSED" : "", + (le32toh(f->header->incompatible_flags) & ~HEADER_INCOMPATIBLE_COMPRESSED) ? " ???" : "", + (unsigned long long) le64toh(f->header->header_size), + (unsigned long long) le64toh(f->header->arena_size), + (unsigned long long) le64toh(f->header->data_hash_table_size) / sizeof(HashItem), + (unsigned long long) le64toh(f->header->field_hash_table_size) / sizeof(HashItem), + yes_no(journal_file_rotate_suggested(f, 0)), + (unsigned long long) le64toh(f->header->head_entry_seqnum), + (unsigned long long) le64toh(f->header->tail_entry_seqnum), + format_timestamp(x, sizeof(x), le64toh(f->header->head_entry_realtime)), + format_timestamp(y, sizeof(y), le64toh(f->header->tail_entry_realtime)), + (unsigned long long) le64toh(f->header->n_objects), + (unsigned long long) le64toh(f->header->n_entries)); + + if (JOURNAL_HEADER_CONTAINS(f->header, n_data)) + printf("Data Objects: %llu\n" + "Data Hash Table Fill: %.1f%%\n", + (unsigned long long) le64toh(f->header->n_data), + 100.0 * (double) le64toh(f->header->n_data) / ((double) (le64toh(f->header->data_hash_table_size) / sizeof(HashItem)))); + + if (JOURNAL_HEADER_CONTAINS(f->header, n_fields)) + printf("Field Objects: %llu\n" + "Field Hash Table Fill: %.1f%%\n", + (unsigned long long) le64toh(f->header->n_fields), + 100.0 * (double) le64toh(f->header->n_fields) / ((double) (le64toh(f->header->field_hash_table_size) / sizeof(HashItem)))); + + if (JOURNAL_HEADER_CONTAINS(f->header, n_tags)) + printf("Tag Objects: %llu\n", + (unsigned long long) le64toh(f->header->n_tags)); + if (JOURNAL_HEADER_CONTAINS(f->header, n_entry_arrays)) + printf("Entry Array Objects: %llu\n", + (unsigned long long) le64toh(f->header->n_entry_arrays)); + + if (fstat(f->fd, &st) >= 0) + printf("Disk usage: %s\n", format_bytes(bytes, sizeof(bytes), (off_t) st.st_blocks * 512ULL)); +} + +int journal_file_open( + const char *fname, + int flags, + mode_t mode, + bool compress, + bool seal, + JournalMetrics *metrics, + MMapCache *mmap_cache, + JournalFile *template, + JournalFile **ret) { + + JournalFile *f; + int r; + bool newly_created = false; + + assert(fname); + assert(ret); + + if ((flags & O_ACCMODE) != O_RDONLY && + (flags & O_ACCMODE) != O_RDWR) + return -EINVAL; + + if (!endswith(fname, ".journal") && + !endswith(fname, ".journal~")) + return -EINVAL; + + f = new0(JournalFile, 1); + if (!f) + return -ENOMEM; + + f->fd = -1; + f->mode = mode; + + f->flags = flags; + f->prot = prot_from_flags(flags); + f->writable = (flags & O_ACCMODE) != O_RDONLY; +#ifdef HAVE_XZ + f->compress = compress; +#endif +#ifdef HAVE_GCRYPT + f->seal = seal; +#endif + + if (mmap_cache) + f->mmap = mmap_cache_ref(mmap_cache); + else { + f->mmap = mmap_cache_new(); + if (!f->mmap) { + r = -ENOMEM; + goto fail; + } + } + + f->path = strdup(fname); + if (!f->path) { + r = -ENOMEM; + goto fail; + } + + f->chain_cache = hashmap_new(uint64_hash_func, uint64_compare_func); + if (!f->chain_cache) { + r = -ENOMEM; + goto fail; + } + + f->fd = open(f->path, f->flags|O_CLOEXEC, f->mode); + if (f->fd < 0) { + r = -errno; + goto fail; + } + + if (fstat(f->fd, &f->last_stat) < 0) { + r = -errno; + goto fail; + } + + if (f->last_stat.st_size == 0 && f->writable) { +#ifdef HAVE_XATTR + uint64_t crtime; + + /* Let's attach the creation time to the journal file, + * so that the vacuuming code knows the age of this + * file even if the file might end up corrupted one + * day... Ideally we'd just use the creation time many + * file systems maintain for each file, but there is + * currently no usable API to query this, hence let's + * emulate this via extended attributes. If extended + * attributes are not supported we'll just skip this, + * and rely solely on mtime/atime/ctime of the file.*/ + + crtime = htole64((uint64_t) now(CLOCK_REALTIME)); + fsetxattr(f->fd, "user.crtime_usec", &crtime, sizeof(crtime), XATTR_CREATE); +#endif + +#ifdef HAVE_GCRYPT + /* Try to load the FSPRG state, and if we can't, then + * just don't do sealing */ + if (f->seal) { + r = journal_file_fss_load(f); + if (r < 0) + f->seal = false; + } +#endif + + r = journal_file_init_header(f, template); + if (r < 0) + goto fail; + + if (fstat(f->fd, &f->last_stat) < 0) { + r = -errno; + goto fail; + } + + newly_created = true; + } + + if (f->last_stat.st_size < (off_t) HEADER_SIZE_MIN) { + r = -EIO; + goto fail; + } + + f->header = mmap(NULL, PAGE_ALIGN(sizeof(Header)), prot_from_flags(flags), MAP_SHARED, f->fd, 0); + if (f->header == MAP_FAILED) { + f->header = NULL; + r = -errno; + goto fail; + } + + if (!newly_created) { + r = journal_file_verify_header(f); + if (r < 0) + goto fail; + } + +#ifdef HAVE_GCRYPT + if (!newly_created && f->writable) { + r = journal_file_fss_load(f); + if (r < 0) + goto fail; + } +#endif + + if (f->writable) { + if (metrics) { + journal_default_metrics(metrics, f->fd); + f->metrics = *metrics; + } else if (template) + f->metrics = template->metrics; + + r = journal_file_refresh_header(f); + if (r < 0) + goto fail; + } + +#ifdef HAVE_GCRYPT + r = journal_file_hmac_setup(f); + if (r < 0) + goto fail; +#endif + + if (newly_created) { + r = journal_file_setup_field_hash_table(f); + if (r < 0) + goto fail; + + r = journal_file_setup_data_hash_table(f); + if (r < 0) + goto fail; + +#ifdef HAVE_GCRYPT + r = journal_file_append_first_tag(f); + if (r < 0) + goto fail; +#endif + } + + r = journal_file_map_field_hash_table(f); + if (r < 0) + goto fail; + + r = journal_file_map_data_hash_table(f); + if (r < 0) + goto fail; + + *ret = f; + return 0; + +fail: + journal_file_close(f); + + return r; +} + +int journal_file_rotate(JournalFile **f, bool compress, bool seal) { + char *p; + size_t l; + JournalFile *old_file, *new_file = NULL; + int r; + + assert(f); + assert(*f); + + old_file = *f; + + if (!old_file->writable) + return -EINVAL; + + if (!endswith(old_file->path, ".journal")) + return -EINVAL; + + l = strlen(old_file->path); + + p = new(char, l + 1 + 32 + 1 + 16 + 1 + 16 + 1); + if (!p) + return -ENOMEM; + + memcpy(p, old_file->path, l - 8); + p[l-8] = '@'; + sd_id128_to_string(old_file->header->seqnum_id, p + l - 8 + 1); + snprintf(p + l - 8 + 1 + 32, 1 + 16 + 1 + 16 + 8 + 1, + "-%016llx-%016llx.journal", + (unsigned long long) le64toh((*f)->header->head_entry_seqnum), + (unsigned long long) le64toh((*f)->header->head_entry_realtime)); + + r = rename(old_file->path, p); + free(p); + + if (r < 0) + return -errno; + + old_file->header->state = STATE_ARCHIVED; + + r = journal_file_open(old_file->path, old_file->flags, old_file->mode, compress, seal, NULL, old_file->mmap, old_file, &new_file); + journal_file_close(old_file); + + *f = new_file; + return r; +} + +int journal_file_open_reliably( + const char *fname, + int flags, + mode_t mode, + bool compress, + bool seal, + JournalMetrics *metrics, + MMapCache *mmap_cache, + JournalFile *template, + JournalFile **ret) { + + int r; + size_t l; + char *p; + + r = journal_file_open(fname, flags, mode, compress, seal, + metrics, mmap_cache, template, ret); + if (r != -EBADMSG && /* corrupted */ + r != -ENODATA && /* truncated */ + r != -EHOSTDOWN && /* other machine */ + r != -EPROTONOSUPPORT && /* incompatible feature */ + r != -EBUSY && /* unclean shutdown */ + r != -ESHUTDOWN /* already archived */) + return r; + + if ((flags & O_ACCMODE) == O_RDONLY) + return r; + + if (!(flags & O_CREAT)) + return r; + + if (!endswith(fname, ".journal")) + return r; + + /* The file is corrupted. Rotate it away and try it again (but only once) */ + + l = strlen(fname); + if (asprintf(&p, "%.*s@%016llx-%016llx.journal~", + (int) (l-8), fname, + (unsigned long long) now(CLOCK_REALTIME), + random_ull()) < 0) + return -ENOMEM; + + r = rename(fname, p); + free(p); + if (r < 0) + return -errno; + + log_warning("File %s corrupted or uncleanly shut down, renaming and replacing.", fname); + + return journal_file_open(fname, flags, mode, compress, seal, + metrics, mmap_cache, template, ret); +} + +int journal_file_copy_entry(JournalFile *from, JournalFile *to, Object *o, uint64_t p, uint64_t *seqnum, Object **ret, uint64_t *offset) { + uint64_t i, n; + uint64_t q, xor_hash = 0; + int r; + EntryItem *items; + dual_timestamp ts; + + assert(from); + assert(to); + assert(o); + assert(p); + + if (!to->writable) + return -EPERM; + + ts.monotonic = le64toh(o->entry.monotonic); + ts.realtime = le64toh(o->entry.realtime); + + if (to->tail_entry_monotonic_valid && + ts.monotonic < le64toh(to->header->tail_entry_monotonic)) + return -EINVAL; + + n = journal_file_entry_n_items(o); + items = alloca(sizeof(EntryItem) * n); + + for (i = 0; i < n; i++) { + uint64_t l, h; + le64_t le_hash; + size_t t; + void *data; + Object *u; + + q = le64toh(o->entry.items[i].object_offset); + le_hash = o->entry.items[i].hash; + + r = journal_file_move_to_object(from, OBJECT_DATA, q, &o); + if (r < 0) + return r; + + if (le_hash != o->data.hash) + return -EBADMSG; + + l = le64toh(o->object.size) - offsetof(Object, data.payload); + t = (size_t) l; + + /* We hit the limit on 32bit machines */ + if ((uint64_t) t != l) + return -E2BIG; + + if (o->object.flags & OBJECT_COMPRESSED) { +#ifdef HAVE_XZ + uint64_t rsize; + + if (!uncompress_blob(o->data.payload, l, &from->compress_buffer, &from->compress_buffer_size, &rsize, 0)) + return -EBADMSG; + + data = from->compress_buffer; + l = rsize; +#else + return -EPROTONOSUPPORT; +#endif + } else + data = o->data.payload; + + r = journal_file_append_data(to, data, l, &u, &h); + if (r < 0) + return r; + + xor_hash ^= le64toh(u->data.hash); + items[i].object_offset = htole64(h); + items[i].hash = u->data.hash; + + r = journal_file_move_to_object(from, OBJECT_ENTRY, p, &o); + if (r < 0) + return r; + } + + return journal_file_append_entry_internal(to, &ts, xor_hash, items, n, seqnum, ret, offset); +} + +void journal_default_metrics(JournalMetrics *m, int fd) { + uint64_t fs_size = 0; + struct statvfs ss; + char a[FORMAT_BYTES_MAX], b[FORMAT_BYTES_MAX], c[FORMAT_BYTES_MAX], d[FORMAT_BYTES_MAX]; + + assert(m); + assert(fd >= 0); + + if (fstatvfs(fd, &ss) >= 0) + fs_size = ss.f_frsize * ss.f_blocks; + + if (m->max_use == (uint64_t) -1) { + + if (fs_size > 0) { + m->max_use = PAGE_ALIGN(fs_size / 10); /* 10% of file system size */ + + if (m->max_use > DEFAULT_MAX_USE_UPPER) + m->max_use = DEFAULT_MAX_USE_UPPER; + + if (m->max_use < DEFAULT_MAX_USE_LOWER) + m->max_use = DEFAULT_MAX_USE_LOWER; + } else + m->max_use = DEFAULT_MAX_USE_LOWER; + } else { + m->max_use = PAGE_ALIGN(m->max_use); + + if (m->max_use < JOURNAL_FILE_SIZE_MIN*2) + m->max_use = JOURNAL_FILE_SIZE_MIN*2; + } + + if (m->max_size == (uint64_t) -1) { + m->max_size = PAGE_ALIGN(m->max_use / 8); /* 8 chunks */ + + if (m->max_size > DEFAULT_MAX_SIZE_UPPER) + m->max_size = DEFAULT_MAX_SIZE_UPPER; + } else + m->max_size = PAGE_ALIGN(m->max_size); + + if (m->max_size < JOURNAL_FILE_SIZE_MIN) + m->max_size = JOURNAL_FILE_SIZE_MIN; + + if (m->max_size*2 > m->max_use) + m->max_use = m->max_size*2; + + if (m->min_size == (uint64_t) -1) + m->min_size = JOURNAL_FILE_SIZE_MIN; + else { + m->min_size = PAGE_ALIGN(m->min_size); + + if (m->min_size < JOURNAL_FILE_SIZE_MIN) + m->min_size = JOURNAL_FILE_SIZE_MIN; + + if (m->min_size > m->max_size) + m->max_size = m->min_size; + } + + if (m->keep_free == (uint64_t) -1) { + + if (fs_size > 0) { + m->keep_free = PAGE_ALIGN(fs_size / 20); /* 5% of file system size */ + + if (m->keep_free > DEFAULT_KEEP_FREE_UPPER) + m->keep_free = DEFAULT_KEEP_FREE_UPPER; + + } else + m->keep_free = DEFAULT_KEEP_FREE; + } + + log_debug("Fixed max_use=%s max_size=%s min_size=%s keep_free=%s", + format_bytes(a, sizeof(a), m->max_use), + format_bytes(b, sizeof(b), m->max_size), + format_bytes(c, sizeof(c), m->min_size), + format_bytes(d, sizeof(d), m->keep_free)); +} + +int journal_file_get_cutoff_realtime_usec(JournalFile *f, usec_t *from, usec_t *to) { + assert(f); + assert(from || to); + + if (from) { + if (f->header->head_entry_realtime == 0) + return -ENOENT; + + *from = le64toh(f->header->head_entry_realtime); + } + + if (to) { + if (f->header->tail_entry_realtime == 0) + return -ENOENT; + + *to = le64toh(f->header->tail_entry_realtime); + } + + return 1; +} + +int journal_file_get_cutoff_monotonic_usec(JournalFile *f, sd_id128_t boot_id, usec_t *from, usec_t *to) { + char t[9+32+1] = "_BOOT_ID="; + Object *o; + uint64_t p; + int r; + + assert(f); + assert(from || to); + + sd_id128_to_string(boot_id, t + 9); + + r = journal_file_find_data_object(f, t, strlen(t), &o, &p); + if (r <= 0) + return r; + + if (le64toh(o->data.n_entries) <= 0) + return 0; + + if (from) { + r = journal_file_move_to_object(f, OBJECT_ENTRY, le64toh(o->data.entry_offset), &o); + if (r < 0) + return r; + + *from = le64toh(o->entry.monotonic); + } + + if (to) { + r = journal_file_move_to_object(f, OBJECT_DATA, p, &o); + if (r < 0) + return r; + + r = generic_array_get_plus_one(f, + le64toh(o->data.entry_offset), + le64toh(o->data.entry_array_offset), + le64toh(o->data.n_entries)-1, + &o, NULL); + if (r <= 0) + return r; + + *to = le64toh(o->entry.monotonic); + } + + return 1; +} + +bool journal_file_rotate_suggested(JournalFile *f, usec_t max_file_usec) { + assert(f); + + /* If we gained new header fields we gained new features, + * hence suggest a rotation */ + if (le64toh(f->header->header_size) < sizeof(Header)) { + log_debug("%s uses an outdated header, suggesting rotation.", f->path); + return true; + } + + /* Let's check if the hash tables grew over a certain fill + * level (75%, borrowing this value from Java's hash table + * implementation), and if so suggest a rotation. To calculate + * the fill level we need the n_data field, which only exists + * in newer versions. */ + + if (JOURNAL_HEADER_CONTAINS(f->header, n_data)) + if (le64toh(f->header->n_data) * 4ULL > (le64toh(f->header->data_hash_table_size) / sizeof(HashItem)) * 3ULL) { + log_debug("Data hash table of %s has a fill level at %.1f (%llu of %llu items, %llu file size, %llu bytes per hash table item), suggesting rotation.", + f->path, + 100.0 * (double) le64toh(f->header->n_data) / ((double) (le64toh(f->header->data_hash_table_size) / sizeof(HashItem))), + (unsigned long long) le64toh(f->header->n_data), + (unsigned long long) (le64toh(f->header->data_hash_table_size) / sizeof(HashItem)), + (unsigned long long) (f->last_stat.st_size), + (unsigned long long) (f->last_stat.st_size / le64toh(f->header->n_data))); + return true; + } + + if (JOURNAL_HEADER_CONTAINS(f->header, n_fields)) + if (le64toh(f->header->n_fields) * 4ULL > (le64toh(f->header->field_hash_table_size) / sizeof(HashItem)) * 3ULL) { + log_debug("Field hash table of %s has a fill level at %.1f (%llu of %llu items), suggesting rotation.", + f->path, + 100.0 * (double) le64toh(f->header->n_fields) / ((double) (le64toh(f->header->field_hash_table_size) / sizeof(HashItem))), + (unsigned long long) le64toh(f->header->n_fields), + (unsigned long long) (le64toh(f->header->field_hash_table_size) / sizeof(HashItem))); + return true; + } + + /* Are the data objects properly indexed by field objects? */ + if (JOURNAL_HEADER_CONTAINS(f->header, n_data) && + JOURNAL_HEADER_CONTAINS(f->header, n_fields) && + le64toh(f->header->n_data) > 0 && + le64toh(f->header->n_fields) == 0) + return true; + + if (max_file_usec > 0) { + usec_t t, h; + + h = le64toh(f->header->head_entry_realtime); + t = now(CLOCK_REALTIME); + + if (h > 0 && t > h + max_file_usec) + return true; + } + + return false; +} diff --git a/src/journal/journal-file.h b/src/journal/journal-file.h new file mode 100644 index 000000000..cdbc8e41f --- /dev/null +++ b/src/journal/journal-file.h @@ -0,0 +1,193 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +#include + +#ifdef HAVE_GCRYPT +#include +#endif + +#include + +#include "sparse-endian.h" +#include "journal-def.h" +#include "util.h" +#include "mmap-cache.h" +#include "hashmap.h" + +typedef struct JournalMetrics { + uint64_t max_use; + uint64_t max_size; + uint64_t min_size; + uint64_t keep_free; +} JournalMetrics; + +typedef struct JournalFile { + int fd; + char *path; + struct stat last_stat; + mode_t mode; + + int flags; + int prot; + bool writable; + bool compress; + bool seal; + + bool tail_entry_monotonic_valid; + + Header *header; + HashItem *data_hash_table; + HashItem *field_hash_table; + + uint64_t current_offset; + + JournalMetrics metrics; + MMapCache *mmap; + + Hashmap *chain_cache; + +#ifdef HAVE_XZ + void *compress_buffer; + uint64_t compress_buffer_size; +#endif + +#ifdef HAVE_GCRYPT + gcry_md_hd_t hmac; + bool hmac_running; + + FSSHeader *fss_file; + size_t fss_file_size; + + uint64_t fss_start_usec; + uint64_t fss_interval_usec; + + void *fsprg_state; + size_t fsprg_state_size; + + void *fsprg_seed; + size_t fsprg_seed_size; +#endif +} JournalFile; + +typedef enum direction { + DIRECTION_UP, + DIRECTION_DOWN +} direction_t; + +int journal_file_open( + const char *fname, + int flags, + mode_t mode, + bool compress, + bool seal, + JournalMetrics *metrics, + MMapCache *mmap_cache, + JournalFile *template, + JournalFile **ret); + +void journal_file_close(JournalFile *j); + +int journal_file_open_reliably( + const char *fname, + int flags, + mode_t mode, + bool compress, + bool seal, + JournalMetrics *metrics, + MMapCache *mmap_cache, + JournalFile *template, + JournalFile **ret); + +#define ALIGN64(x) (((x) + 7ULL) & ~7ULL) +#define VALID64(x) (((x) & 7ULL) == 0ULL) + +static inline bool VALID_REALTIME(uint64_t u) { + /* This considers timestamps until the year 3112 valid. That should be plenty room... */ + return u > 0 && u < (1ULL << 55); +} + +static inline bool VALID_MONOTONIC(uint64_t u) { + /* This considers timestamps until 1142 years of runtime valid. */ + return u < (1ULL << 55); +} + +static inline bool VALID_EPOCH(uint64_t u) { + /* This allows changing the key for 1142 years, every usec. */ + return u < (1ULL << 55); +} + +#define JOURNAL_HEADER_CONTAINS(h, field) \ + (le64toh((h)->header_size) >= offsetof(Header, field) + sizeof((h)->field)) + +#define JOURNAL_HEADER_SEALED(h) \ + (!!(le32toh((h)->compatible_flags) & HEADER_COMPATIBLE_SEALED)) + +#define JOURNAL_HEADER_COMPRESSED(h) \ + (!!(le32toh((h)->incompatible_flags) & HEADER_INCOMPATIBLE_COMPRESSED)) + +int journal_file_move_to_object(JournalFile *f, int type, uint64_t offset, Object **ret); + +uint64_t journal_file_entry_n_items(Object *o); +uint64_t journal_file_entry_array_n_items(Object *o); +uint64_t journal_file_hash_table_n_items(Object *o); + +int journal_file_append_object(JournalFile *f, int type, uint64_t size, Object **ret, uint64_t *offset); +int journal_file_append_entry(JournalFile *f, const dual_timestamp *ts, const struct iovec iovec[], unsigned n_iovec, uint64_t *seqno, Object **ret, uint64_t *offset); + +int journal_file_find_data_object(JournalFile *f, const void *data, uint64_t size, Object **ret, uint64_t *offset); +int journal_file_find_data_object_with_hash(JournalFile *f, const void *data, uint64_t size, uint64_t hash, Object **ret, uint64_t *offset); + +int journal_file_find_field_object(JournalFile *f, const void *field, uint64_t size, Object **ret, uint64_t *offset); +int journal_file_find_field_object_with_hash(JournalFile *f, const void *field, uint64_t size, uint64_t hash, Object **ret, uint64_t *offset); + +int journal_file_next_entry(JournalFile *f, Object *o, uint64_t p, direction_t direction, Object **ret, uint64_t *offset); +int journal_file_skip_entry(JournalFile *f, Object *o, uint64_t p, int64_t skip, Object **ret, uint64_t *offset); + +int journal_file_next_entry_for_data(JournalFile *f, Object *o, uint64_t p, uint64_t data_offset, direction_t direction, Object **ret, uint64_t *offset); + +int journal_file_move_to_entry_by_offset(JournalFile *f, uint64_t seqnum, direction_t direction, Object **ret, uint64_t *offset); +int journal_file_move_to_entry_by_seqnum(JournalFile *f, uint64_t seqnum, direction_t direction, Object **ret, uint64_t *offset); +int journal_file_move_to_entry_by_realtime(JournalFile *f, uint64_t realtime, direction_t direction, Object **ret, uint64_t *offset); +int journal_file_move_to_entry_by_monotonic(JournalFile *f, sd_id128_t boot_id, uint64_t monotonic, direction_t direction, Object **ret, uint64_t *offset); + +int journal_file_move_to_entry_by_offset_for_data(JournalFile *f, uint64_t data_offset, uint64_t p, direction_t direction, Object **ret, uint64_t *offset); +int journal_file_move_to_entry_by_seqnum_for_data(JournalFile *f, uint64_t data_offset, uint64_t seqnum, direction_t direction, Object **ret, uint64_t *offset); +int journal_file_move_to_entry_by_realtime_for_data(JournalFile *f, uint64_t data_offset, uint64_t realtime, direction_t direction, Object **ret, uint64_t *offset); +int journal_file_move_to_entry_by_monotonic_for_data(JournalFile *f, uint64_t data_offset, sd_id128_t boot_id, uint64_t monotonic, direction_t direction, Object **ret, uint64_t *offset); + +int journal_file_copy_entry(JournalFile *from, JournalFile *to, Object *o, uint64_t p, uint64_t *seqnum, Object **ret, uint64_t *offset); + +void journal_file_dump(JournalFile *f); +void journal_file_print_header(JournalFile *f); + +int journal_file_rotate(JournalFile **f, bool compress, bool seal); + +void journal_file_post_change(JournalFile *f); + +void journal_default_metrics(JournalMetrics *m, int fd); + +int journal_file_get_cutoff_realtime_usec(JournalFile *f, usec_t *from, usec_t *to); +int journal_file_get_cutoff_monotonic_usec(JournalFile *f, sd_id128_t boot, usec_t *from, usec_t *to); + +bool journal_file_rotate_suggested(JournalFile *f, usec_t max_file_usec); diff --git a/src/journal/journal-gatewayd.c b/src/journal/journal-gatewayd.c new file mode 100644 index 000000000..63d974477 --- /dev/null +++ b/src/journal/journal-gatewayd.c @@ -0,0 +1,915 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + +#include +#include +#include +#include + +#include + +#include "log.h" +#include "util.h" +#include "sd-journal.h" +#include "sd-daemon.h" +#include "logs-show.h" +#include "virt.h" + +typedef struct RequestMeta { + sd_journal *journal; + + OutputMode mode; + + char *cursor; + int64_t n_skip; + uint64_t n_entries; + bool n_entries_set; + + FILE *tmp; + uint64_t delta, size; + + int argument_parse_error; + + bool follow; + bool discrete; + + uint64_t n_fields; + bool n_fields_set; +} RequestMeta; + +static const char* const mime_types[_OUTPUT_MODE_MAX] = { + [OUTPUT_SHORT] = "text/plain", + [OUTPUT_JSON] = "application/json", + [OUTPUT_JSON_SSE] = "text/event-stream", + [OUTPUT_EXPORT] = "application/vnd.fdo.journal", +}; + +static RequestMeta *request_meta(void **connection_cls) { + RequestMeta *m; + + if (*connection_cls) + return *connection_cls; + + m = new0(RequestMeta, 1); + if (!m) + return NULL; + + *connection_cls = m; + return m; +} + +static void request_meta_free( + void *cls, + struct MHD_Connection *connection, + void **connection_cls, + enum MHD_RequestTerminationCode toe) { + + RequestMeta *m = *connection_cls; + + if (!m) + return; + + if (m->journal) + sd_journal_close(m->journal); + + if (m->tmp) + fclose(m->tmp); + + free(m->cursor); + free(m); +} + +static int open_journal(RequestMeta *m) { + assert(m); + + if (m->journal) + return 0; + + return sd_journal_open(&m->journal, SD_JOURNAL_LOCAL_ONLY|SD_JOURNAL_SYSTEM_ONLY); +} + + +static int respond_oom(struct MHD_Connection *connection) { + struct MHD_Response *response; + const char m[] = "Out of memory.\n"; + int ret; + + assert(connection); + + response = MHD_create_response_from_buffer(sizeof(m)-1, (char*) m, MHD_RESPMEM_PERSISTENT); + if (!response) + return MHD_NO; + + MHD_add_response_header(response, "Content-Type", "text/plain"); + ret = MHD_queue_response(connection, MHD_HTTP_SERVICE_UNAVAILABLE, response); + MHD_destroy_response(response); + + return ret; +} + +static int respond_error( + struct MHD_Connection *connection, + unsigned code, + const char *format, ...) { + + struct MHD_Response *response; + char *m; + int r; + va_list ap; + + assert(connection); + assert(format); + + va_start(ap, format); + r = vasprintf(&m, format, ap); + va_end(ap); + + if (r < 0) + return respond_oom(connection); + + response = MHD_create_response_from_buffer(strlen(m), m, MHD_RESPMEM_MUST_FREE); + if (!response) { + free(m); + return respond_oom(connection); + } + + MHD_add_response_header(response, "Content-Type", "text/plain"); + r = MHD_queue_response(connection, code, response); + MHD_destroy_response(response); + + return r; +} + +static ssize_t request_reader_entries( + void *cls, + uint64_t pos, + char *buf, + size_t max) { + + RequestMeta *m = cls; + int r; + size_t n, k; + + assert(m); + assert(buf); + assert(max > 0); + assert(pos >= m->delta); + + pos -= m->delta; + + while (pos >= m->size) { + off_t sz; + + /* End of this entry, so let's serialize the next + * one */ + + if (m->n_entries_set && + m->n_entries <= 0) + return MHD_CONTENT_READER_END_OF_STREAM; + + if (m->n_skip < 0) + r = sd_journal_previous_skip(m->journal, (uint64_t) -m->n_skip + 1); + else if (m->n_skip > 0) + r = sd_journal_next_skip(m->journal, (uint64_t) m->n_skip + 1); + else + r = sd_journal_next(m->journal); + + if (r < 0) { + log_error("Failed to advance journal pointer: %s", strerror(-r)); + return MHD_CONTENT_READER_END_WITH_ERROR; + } else if (r == 0) { + + if (m->follow) { + r = sd_journal_wait(m->journal, (uint64_t) -1); + if (r < 0) { + log_error("Couldn't wait for journal event: %s", strerror(-r)); + return MHD_CONTENT_READER_END_WITH_ERROR; + } + + continue; + } + + return MHD_CONTENT_READER_END_OF_STREAM; + } + + if (m->discrete) { + assert(m->cursor); + + r = sd_journal_test_cursor(m->journal, m->cursor); + if (r < 0) { + log_error("Failed to test cursor: %s", strerror(-r)); + return MHD_CONTENT_READER_END_WITH_ERROR; + } + + if (r == 0) + return MHD_CONTENT_READER_END_OF_STREAM; + } + + pos -= m->size; + m->delta += m->size; + + if (m->n_entries_set) + m->n_entries -= 1; + + m->n_skip = 0; + + if (m->tmp) + rewind(m->tmp); + else { + m->tmp = tmpfile(); + if (!m->tmp) { + log_error("Failed to create temporary file: %m"); + return MHD_CONTENT_READER_END_WITH_ERROR; + } + } + + r = output_journal(m->tmp, m->journal, m->mode, 0, OUTPUT_FULL_WIDTH); + if (r < 0) { + log_error("Failed to serialize item: %s", strerror(-r)); + return MHD_CONTENT_READER_END_WITH_ERROR; + } + + sz = ftello(m->tmp); + if (sz == (off_t) -1) { + log_error("Failed to retrieve file position: %m"); + return MHD_CONTENT_READER_END_WITH_ERROR; + } + + m->size = (uint64_t) sz; + } + + if (fseeko(m->tmp, pos, SEEK_SET) < 0) { + log_error("Failed to seek to position: %m"); + return MHD_CONTENT_READER_END_WITH_ERROR; + } + + n = m->size - pos; + if (n > max) + n = max; + + errno = 0; + k = fread(buf, 1, n, m->tmp); + if (k != n) { + log_error("Failed to read from file: %s", errno ? strerror(errno) : "Premature EOF"); + return MHD_CONTENT_READER_END_WITH_ERROR; + } + + return (ssize_t) k; +} + +static int request_parse_accept( + RequestMeta *m, + struct MHD_Connection *connection) { + + const char *header; + + assert(m); + assert(connection); + + header = MHD_lookup_connection_value(connection, MHD_HEADER_KIND, "Accept"); + if (!header) + return 0; + + if (streq(header, mime_types[OUTPUT_JSON])) + m->mode = OUTPUT_JSON; + else if (streq(header, mime_types[OUTPUT_JSON_SSE])) + m->mode = OUTPUT_JSON_SSE; + else if (streq(header, mime_types[OUTPUT_EXPORT])) + m->mode = OUTPUT_EXPORT; + else + m->mode = OUTPUT_SHORT; + + return 0; +} + +static int request_parse_range( + RequestMeta *m, + struct MHD_Connection *connection) { + + const char *range, *colon, *colon2; + int r; + + assert(m); + assert(connection); + + range = MHD_lookup_connection_value(connection, MHD_HEADER_KIND, "Range"); + if (!range) + return 0; + + if (!startswith(range, "entries=")) + return 0; + + range += 8; + range += strspn(range, WHITESPACE); + + colon = strchr(range, ':'); + if (!colon) + m->cursor = strdup(range); + else { + const char *p; + + colon2 = strchr(colon + 1, ':'); + if (colon2) { + char _cleanup_free_ *t; + + t = strndup(colon + 1, colon2 - colon - 1); + if (!t) + return -ENOMEM; + + r = safe_atoi64(t, &m->n_skip); + if (r < 0) + return r; + } + + p = (colon2 ? colon2 : colon) + 1; + if (*p) { + r = safe_atou64(p, &m->n_entries); + if (r < 0) + return r; + + if (m->n_entries <= 0) + return -EINVAL; + + m->n_entries_set = true; + } + + m->cursor = strndup(range, colon - range); + } + + if (!m->cursor) + return -ENOMEM; + + m->cursor[strcspn(m->cursor, WHITESPACE)] = 0; + if (isempty(m->cursor)) { + free(m->cursor); + m->cursor = NULL; + } + + return 0; +} + +static int request_parse_arguments_iterator( + void *cls, + enum MHD_ValueKind kind, + const char *key, + const char *value) { + + RequestMeta *m = cls; + _cleanup_free_ char *p = NULL; + int r; + + assert(m); + + if (isempty(key)) { + m->argument_parse_error = -EINVAL; + return MHD_NO; + } + + if (streq(key, "follow")) { + if (isempty(value)) { + m->follow = true; + return MHD_YES; + } + + r = parse_boolean(value); + if (r < 0) { + m->argument_parse_error = r; + return MHD_NO; + } + + m->follow = r; + return MHD_YES; + } + + if (streq(key, "discrete")) { + if (isempty(value)) { + m->discrete = true; + return MHD_YES; + } + + r = parse_boolean(value); + if (r < 0) { + m->argument_parse_error = r; + return MHD_NO; + } + + m->discrete = r; + return MHD_YES; + } + + if (streq(key, "boot")) { + if (isempty(value)) + r = true; + else { + r = parse_boolean(value); + if (r < 0) { + m->argument_parse_error = r; + return MHD_NO; + } + } + + if (r) { + char match[9 + 32 + 1] = "_BOOT_ID="; + sd_id128_t bid; + + r = sd_id128_get_boot(&bid); + if (r < 0) { + log_error("Failed to get boot ID: %s", strerror(-r)); + return MHD_NO; + } + + sd_id128_to_string(bid, match + 9); + r = sd_journal_add_match(m->journal, match, sizeof(match)-1); + if (r < 0) { + m->argument_parse_error = r; + return MHD_NO; + } + } + + return MHD_YES; + } + + p = strjoin(key, "=", strempty(value), NULL); + if (!p) { + m->argument_parse_error = log_oom(); + return MHD_NO; + } + + r = sd_journal_add_match(m->journal, p, 0); + if (r < 0) { + m->argument_parse_error = r; + return MHD_NO; + } + + return MHD_YES; +} + +static int request_parse_arguments( + RequestMeta *m, + struct MHD_Connection *connection) { + + assert(m); + assert(connection); + + m->argument_parse_error = 0; + MHD_get_connection_values(connection, MHD_GET_ARGUMENT_KIND, request_parse_arguments_iterator, m); + + return m->argument_parse_error; +} + +static int request_handler_entries( + struct MHD_Connection *connection, + void **connection_cls) { + + struct MHD_Response *response; + RequestMeta *m; + int r; + + assert(connection); + assert(connection_cls); + + m = request_meta(connection_cls); + if (!m) + return respond_oom(connection); + + r = open_journal(m); + if (r < 0) + return respond_error(connection, MHD_HTTP_INTERNAL_SERVER_ERROR, "Failed to open journal: %s\n", strerror(-r)); + + if (request_parse_accept(m, connection) < 0) + return respond_error(connection, MHD_HTTP_BAD_REQUEST, "Failed to parse Accept header.\n"); + + if (request_parse_range(m, connection) < 0) + return respond_error(connection, MHD_HTTP_BAD_REQUEST, "Failed to parse Range header.\n"); + + if (request_parse_arguments(m, connection) < 0) + return respond_error(connection, MHD_HTTP_BAD_REQUEST, "Failed to parse URL arguments.\n"); + + if (m->discrete) { + if (!m->cursor) + return respond_error(connection, MHD_HTTP_BAD_REQUEST, "Discrete seeks require a cursor specification.\n"); + + m->n_entries = 1; + m->n_entries_set = true; + } + + if (m->cursor) + r = sd_journal_seek_cursor(m->journal, m->cursor); + else if (m->n_skip >= 0) + r = sd_journal_seek_head(m->journal); + else if (m->n_skip < 0) + r = sd_journal_seek_tail(m->journal); + if (r < 0) + return respond_error(connection, MHD_HTTP_BAD_REQUEST, "Failed to seek in journal.\n"); + + response = MHD_create_response_from_callback(MHD_SIZE_UNKNOWN, 4*1024, request_reader_entries, m, NULL); + if (!response) + return respond_oom(connection); + + MHD_add_response_header(response, "Content-Type", mime_types[m->mode]); + + r = MHD_queue_response(connection, MHD_HTTP_OK, response); + MHD_destroy_response(response); + + return r; +} + +static int output_field(FILE *f, OutputMode m, const char *d, size_t l) { + const char *eq; + size_t j; + + eq = memchr(d, '=', l); + if (!eq) + return -EINVAL; + + j = l - (eq - d + 1); + + if (m == OUTPUT_JSON) { + fprintf(f, "{ \"%.*s\" : ", (int) (eq - d), d); + json_escape(f, eq+1, j, OUTPUT_FULL_WIDTH); + fputs(" }\n", f); + } else { + fwrite(eq+1, 1, j, f); + fputc('\n', f); + } + + return 0; +} + +static ssize_t request_reader_fields( + void *cls, + uint64_t pos, + char *buf, + size_t max) { + + RequestMeta *m = cls; + int r; + size_t n, k; + + assert(m); + assert(buf); + assert(max > 0); + assert(pos >= m->delta); + + pos -= m->delta; + + while (pos >= m->size) { + off_t sz; + const void *d; + size_t l; + + /* End of this field, so let's serialize the next + * one */ + + if (m->n_fields_set && + m->n_fields <= 0) + return MHD_CONTENT_READER_END_OF_STREAM; + + r = sd_journal_enumerate_unique(m->journal, &d, &l); + if (r < 0) { + log_error("Failed to advance field index: %s", strerror(-r)); + return MHD_CONTENT_READER_END_WITH_ERROR; + } else if (r == 0) + return MHD_CONTENT_READER_END_OF_STREAM; + + pos -= m->size; + m->delta += m->size; + + if (m->n_fields_set) + m->n_fields -= 1; + + if (m->tmp) + rewind(m->tmp); + else { + m->tmp = tmpfile(); + if (!m->tmp) { + log_error("Failed to create temporary file: %m"); + return MHD_CONTENT_READER_END_WITH_ERROR; + } + } + + r = output_field(m->tmp, m->mode, d, l); + if (r < 0) { + log_error("Failed to serialize item: %s", strerror(-r)); + return MHD_CONTENT_READER_END_WITH_ERROR; + } + + sz = ftello(m->tmp); + if (sz == (off_t) -1) { + log_error("Failed to retrieve file position: %m"); + return MHD_CONTENT_READER_END_WITH_ERROR; + } + + m->size = (uint64_t) sz; + } + + if (fseeko(m->tmp, pos, SEEK_SET) < 0) { + log_error("Failed to seek to position: %m"); + return MHD_CONTENT_READER_END_WITH_ERROR; + } + + n = m->size - pos; + if (n > max) + n = max; + + errno = 0; + k = fread(buf, 1, n, m->tmp); + if (k != n) { + log_error("Failed to read from file: %s", errno ? strerror(errno) : "Premature EOF"); + return MHD_CONTENT_READER_END_WITH_ERROR; + } + + return (ssize_t) k; +} + +static int request_handler_fields( + struct MHD_Connection *connection, + const char *field, + void *connection_cls) { + + struct MHD_Response *response; + RequestMeta *m; + int r; + + assert(connection); + assert(connection_cls); + + m = request_meta(connection_cls); + if (!m) + return respond_oom(connection); + + r = open_journal(m); + if (r < 0) + return respond_error(connection, MHD_HTTP_INTERNAL_SERVER_ERROR, "Failed to open journal: %s\n", strerror(-r)); + + if (request_parse_accept(m, connection) < 0) + return respond_error(connection, MHD_HTTP_BAD_REQUEST, "Failed to parse Accept header.\n"); + + r = sd_journal_query_unique(m->journal, field); + if (r < 0) + return respond_error(connection, MHD_HTTP_BAD_REQUEST, "Failed to query unique fields.\n"); + + response = MHD_create_response_from_callback(MHD_SIZE_UNKNOWN, 4*1024, request_reader_fields, m, NULL); + if (!response) + return respond_oom(connection); + + MHD_add_response_header(response, "Content-Type", mime_types[m->mode == OUTPUT_JSON ? OUTPUT_JSON : OUTPUT_SHORT]); + + r = MHD_queue_response(connection, MHD_HTTP_OK, response); + MHD_destroy_response(response); + + return r; +} + +static int request_handler_redirect( + struct MHD_Connection *connection, + const char *target) { + + char *page; + struct MHD_Response *response; + int ret; + + assert(connection); + assert(target); + + if (asprintf(&page, "Please continue to the journal browser.", target) < 0) + return respond_oom(connection); + + response = MHD_create_response_from_buffer(strlen(page), page, MHD_RESPMEM_MUST_FREE); + if (!response) { + free(page); + return respond_oom(connection); + } + + MHD_add_response_header(response, "Content-Type", "text/html"); + MHD_add_response_header(response, "Location", target); + + ret = MHD_queue_response(connection, MHD_HTTP_MOVED_PERMANENTLY, response); + MHD_destroy_response(response); + + return ret; +} + +static int request_handler_file( + struct MHD_Connection *connection, + const char *path, + const char *mime_type) { + + struct MHD_Response *response; + int ret; + _cleanup_close_ int fd = -1; + struct stat st; + + assert(connection); + assert(path); + assert(mime_type); + + fd = open(path, O_RDONLY|O_CLOEXEC); + if (fd < 0) + return respond_error(connection, MHD_HTTP_NOT_FOUND, "Failed to open file %s: %m\n", path); + + if (fstat(fd, &st) < 0) + return respond_error(connection, MHD_HTTP_INTERNAL_SERVER_ERROR, "Failed to stat file: %m\n"); + + response = MHD_create_response_from_fd_at_offset(st.st_size, fd, 0); + if (!response) + return respond_oom(connection); + + fd = -1; + + MHD_add_response_header(response, "Content-Type", mime_type); + + ret = MHD_queue_response(connection, MHD_HTTP_OK, response); + MHD_destroy_response(response); + + return ret; +} + +static int request_handler_machine( + struct MHD_Connection *connection, + void **connection_cls) { + + struct MHD_Response *response; + RequestMeta *m; + int r; + _cleanup_free_ char* hostname = NULL, *os_name = NULL; + uint64_t cutoff_from, cutoff_to, usage; + char *json; + sd_id128_t mid, bid; + const char *v = "bare"; + + assert(connection); + + m = request_meta(connection_cls); + if (!m) + return respond_oom(connection); + + r = open_journal(m); + if (r < 0) + return respond_error(connection, MHD_HTTP_INTERNAL_SERVER_ERROR, "Failed to open journal: %s\n", strerror(-r)); + + r = sd_id128_get_machine(&mid); + if (r < 0) + return respond_error(connection, MHD_HTTP_INTERNAL_SERVER_ERROR, "Failed to determine machine ID: %s\n", strerror(-r)); + + r = sd_id128_get_boot(&bid); + if (r < 0) + return respond_error(connection, MHD_HTTP_INTERNAL_SERVER_ERROR, "Failed to determine boot ID: %s\n", strerror(-r)); + + hostname = gethostname_malloc(); + if (!hostname) + return respond_oom(connection); + + r = sd_journal_get_usage(m->journal, &usage); + if (r < 0) + return respond_error(connection, MHD_HTTP_INTERNAL_SERVER_ERROR, "Failed to determine disk usage: %s\n", strerror(-r)); + + r = sd_journal_get_cutoff_realtime_usec(m->journal, &cutoff_from, &cutoff_to); + if (r < 0) + return respond_error(connection, MHD_HTTP_INTERNAL_SERVER_ERROR, "Failed to determine disk usage: %s\n", strerror(-r)); + + parse_env_file("/etc/os-release", NEWLINE, "PRETTY_NAME", &os_name, NULL); + + detect_virtualization(&v); + + r = asprintf(&json, + "{ \"machine_id\" : \"" SD_ID128_FORMAT_STR "\"," + "\"boot_id\" : \"" SD_ID128_FORMAT_STR "\"," + "\"hostname\" : \"%s\"," + "\"os_pretty_name\" : \"%s\"," + "\"virtualization\" : \"%s\"," + "\"usage\" : \"%llu\"," + "\"cutoff_from_realtime\" : \"%llu\"," + "\"cutoff_to_realtime\" : \"%llu\" }\n", + SD_ID128_FORMAT_VAL(mid), + SD_ID128_FORMAT_VAL(bid), + hostname_cleanup(hostname), + os_name ? os_name : "Linux", + v, + (unsigned long long) usage, + (unsigned long long) cutoff_from, + (unsigned long long) cutoff_to); + + if (r < 0) + return respond_oom(connection); + + response = MHD_create_response_from_buffer(strlen(json), json, MHD_RESPMEM_MUST_FREE); + if (!response) { + free(json); + return respond_oom(connection); + } + + MHD_add_response_header(response, "Content-Type", "application/json"); + r = MHD_queue_response(connection, MHD_HTTP_OK, response); + MHD_destroy_response(response); + + return r; +} + +static int request_handler( + void *cls, + struct MHD_Connection *connection, + const char *url, + const char *method, + const char *version, + const char *upload_data, + size_t *upload_data_size, + void **connection_cls) { + + assert(connection); + assert(url); + assert(method); + + if (!streq(method, "GET")) + return MHD_NO; + + if (streq(url, "/")) + return request_handler_redirect(connection, "/browse"); + + if (streq(url, "/entries")) + return request_handler_entries(connection, connection_cls); + + if (startswith(url, "/fields/")) + return request_handler_fields(connection, url + 8, connection_cls); + + if (streq(url, "/browse")) + return request_handler_file(connection, DOCUMENT_ROOT "/browse.html", "text/html"); + + if (streq(url, "/machine")) + return request_handler_machine(connection, connection_cls); + + return respond_error(connection, MHD_HTTP_NOT_FOUND, "Not found.\n"); +} + +int main(int argc, char *argv[]) { + struct MHD_Daemon *d = NULL; + int r = EXIT_FAILURE, n; + + if (argc > 1) { + log_error("This program does not take arguments."); + goto finish; + } + + log_set_target(LOG_TARGET_AUTO); + log_parse_environment(); + log_open(); + + n = sd_listen_fds(1); + if (n < 0) { + log_error("Failed to determine passed sockets: %s", strerror(-n)); + goto finish; + } else if (n > 1) { + log_error("Can't listen on more than one socket."); + goto finish; + } else if (n > 0) { + d = MHD_start_daemon( + MHD_USE_THREAD_PER_CONNECTION|MHD_USE_POLL|MHD_USE_DEBUG, + 19531, + NULL, NULL, + request_handler, NULL, + MHD_OPTION_LISTEN_SOCKET, SD_LISTEN_FDS_START, + MHD_OPTION_NOTIFY_COMPLETED, request_meta_free, NULL, + MHD_OPTION_END); + } else { + d = MHD_start_daemon( + MHD_USE_DEBUG|MHD_USE_THREAD_PER_CONNECTION|MHD_USE_POLL, + 19531, + NULL, NULL, + request_handler, NULL, + MHD_OPTION_NOTIFY_COMPLETED, request_meta_free, NULL, + MHD_OPTION_END); + } + + if (!d) { + log_error("Failed to start daemon!"); + goto finish; + } + + pause(); + + r = EXIT_SUCCESS; + +finish: + if (d) + MHD_stop_daemon(d); + + return r; +} diff --git a/src/journal/journal-internal.h b/src/journal/journal-internal.h new file mode 100644 index 000000000..97de0e75f --- /dev/null +++ b/src/journal/journal-internal.h @@ -0,0 +1,129 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +#include +#include +#include + +#include + +#include "journal-def.h" +#include "list.h" +#include "hashmap.h" +#include "journal-file.h" + +typedef struct Match Match; +typedef struct Location Location; +typedef struct Directory Directory; + +typedef enum MatchType { + MATCH_DISCRETE, + MATCH_OR_TERM, + MATCH_AND_TERM +} MatchType; + +struct Match { + MatchType type; + Match *parent; + LIST_FIELDS(Match, matches); + + /* For concrete matches */ + char *data; + size_t size; + le64_t le_hash; + + /* For terms */ + LIST_HEAD(Match, matches); +}; + +typedef enum LocationType { + /* The first and last entries, resp. */ + LOCATION_HEAD, + LOCATION_TAIL, + + /* We already read the entry we currently point to, and the + * next one to read should probably not be this one again. */ + LOCATION_DISCRETE, + + /* We should seek to the precise location specified, and + * return it, as we haven't read it yet. */ + LOCATION_SEEK +} LocationType; + +struct Location { + LocationType type; + + uint64_t seqnum; + sd_id128_t seqnum_id; + bool seqnum_set; + + uint64_t realtime; + bool realtime_set; + + uint64_t monotonic; + sd_id128_t boot_id; + bool monotonic_set; + + uint64_t xor_hash; + bool xor_hash_set; +}; + +struct Directory { + char *path; + int wd; + bool is_root; +}; + +struct sd_journal { + int flags; + + char *path; + + Hashmap *files; + MMapCache *mmap; + + Location current_location; + + JournalFile *current_file; + uint64_t current_field; + + Hashmap *directories_by_path; + Hashmap *directories_by_wd; + + int inotify_fd; + + Match *level0, *level1; + + unsigned current_invalidate_counter, last_invalidate_counter; + + char *unique_field; + JournalFile *unique_file; + uint64_t unique_offset; + + bool on_network; + + size_t data_threshold; +}; + +char *journal_make_match_string(sd_journal *j); +void journal_print_header(sd_journal *j); diff --git a/src/journal/journal-qrcode.c b/src/journal/journal-qrcode.c new file mode 100644 index 000000000..10a14e4de --- /dev/null +++ b/src/journal/journal-qrcode.c @@ -0,0 +1,138 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + +#include +#include +#include +#include +#include + +#include + +#include "journal-qrcode.h" + +#define WHITE_ON_BLACK "\033[40;37;1m" +#define NORMAL "\033[0m" + +static void print_border(FILE *output, unsigned width) { + unsigned x, y; + + /* Four rows of border */ + for (y = 0; y < 4; y += 2) { + fputs(WHITE_ON_BLACK, output); + + for (x = 0; x < 4 + width + 4; x++) + fputs("\342\226\210", output); + + fputs(NORMAL "\n", output); + } +} + +int print_qr_code( + FILE *output, + const void *seed, + size_t seed_size, + uint64_t start, + uint64_t interval, + const char *hn, + sd_id128_t machine) { + + FILE *f; + char *url = NULL; + size_t url_size = 0, i; + QRcode* qr; + unsigned x, y; + + assert(seed); + assert(seed_size > 0); + + f = open_memstream(&url, &url_size); + if (!f) + return -ENOMEM; + + fputs("fss://", f); + + for (i = 0; i < seed_size; i++) { + if (i > 0 && i % 3 == 0) + fputc('-', f); + fprintf(f, "%02x", ((uint8_t*) seed)[i]); + } + + fprintf(f, "/%llx-%llx?machine=" SD_ID128_FORMAT_STR, + (unsigned long long) start, + (unsigned long long) interval, + SD_ID128_FORMAT_VAL(machine)); + + if (hn) + fprintf(f, ";hostname=%s", hn); + + if (ferror(f)) { + fclose(f); + free(url); + return -ENOMEM; + } + + fclose(f); + + qr = QRcode_encodeString(url, 0, QR_ECLEVEL_L, QR_MODE_8, 1); + free(url); + + if (!qr) + return -ENOMEM; + + print_border(output, qr->width); + + for (y = 0; y < (unsigned) qr->width; y += 2) { + const uint8_t *row1, *row2; + + row1 = qr->data + qr->width * y; + row2 = row1 + qr->width; + + fputs(WHITE_ON_BLACK, output); + for (x = 0; x < 4; x++) + fputs("\342\226\210", output); + + for (x = 0; x < (unsigned) qr->width; x ++) { + bool a, b; + + a = row1[x] & 1; + b = (y+1) < (unsigned) qr->width ? (row2[x] & 1) : false; + + if (a && b) + fputc(' ', output); + else if (a) + fputs("\342\226\204", output); + else if (b) + fputs("\342\226\200", output); + else + fputs("\342\226\210", output); + } + + for (x = 0; x < 4; x++) + fputs("\342\226\210", output); + fputs(NORMAL "\n", output); + } + + print_border(output, qr->width); + + QRcode_free(qr); + return 0; +} diff --git a/src/journal/journal-qrcode.h b/src/journal/journal-qrcode.h new file mode 100644 index 000000000..da6244c16 --- /dev/null +++ b/src/journal/journal-qrcode.h @@ -0,0 +1,30 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + +#include +#include +#include + +#include + +int print_qr_code(FILE *f, const void *seed, size_t seed_size, uint64_t start, uint64_t interval, const char *hn, sd_id128_t machine); diff --git a/src/journal/journal-send.c b/src/journal/journal-send.c new file mode 100644 index 000000000..d5ec73e37 --- /dev/null +++ b/src/journal/journal-send.c @@ -0,0 +1,622 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include + +#define SD_JOURNAL_SUPPRESS_LOCATION + +#include "sd-journal.h" +#include "util.h" +#include "socket-util.h" + +#define SNDBUF_SIZE (8*1024*1024) + +#define ALLOCA_CODE_FUNC(f, func) \ + do { \ + size_t _fl; \ + const char *_func = (func); \ + char **_f = &(f); \ + _fl = strlen(_func) + 1; \ + *_f = alloca(_fl + 10); \ + memcpy(*_f, "CODE_FUNC=", 10); \ + memcpy(*_f + 10, _func, _fl); \ + } while(false) + +/* We open a single fd, and we'll share it with the current process, + * all its threads, and all its subprocesses. This means we need to + * initialize it atomically, and need to operate on it atomically + * never assuming we are the only user */ + +static int journal_fd(void) { + int fd; + static int fd_plus_one = 0; + +retry: + if (fd_plus_one > 0) + return fd_plus_one - 1; + + fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0); + if (fd < 0) + return -errno; + + fd_inc_sndbuf(fd, SNDBUF_SIZE); + + if (!__sync_bool_compare_and_swap(&fd_plus_one, 0, fd+1)) { + close_nointr_nofail(fd); + goto retry; + } + + return fd; +} + +_public_ int sd_journal_print(int priority, const char *format, ...) { + int r; + va_list ap; + + va_start(ap, format); + r = sd_journal_printv(priority, format, ap); + va_end(ap); + + return r; +} + +_public_ int sd_journal_printv(int priority, const char *format, va_list ap) { + + /* FIXME: Instead of limiting things to LINE_MAX we could do a + C99 variable-length array on the stack here in a loop. */ + + char buffer[8 + LINE_MAX], p[11]; struct iovec iov[2]; + + if (priority < 0 || priority > 7) + return -EINVAL; + + if (!format) + return -EINVAL; + + snprintf(p, sizeof(p), "PRIORITY=%i", priority & LOG_PRIMASK); + char_array_0(p); + + memcpy(buffer, "MESSAGE=", 8); + vsnprintf(buffer+8, sizeof(buffer) - 8, format, ap); + char_array_0(buffer); + + zero(iov); + IOVEC_SET_STRING(iov[0], buffer); + IOVEC_SET_STRING(iov[1], p); + + return sd_journal_sendv(iov, 2); +} + +static int fill_iovec_sprintf(const char *format, va_list ap, int extra, struct iovec **_iov) { + int r, n = 0, i = 0, j; + struct iovec *iov = NULL; + int saved_errno; + + assert(_iov); + saved_errno = errno; + + if (extra > 0) { + n = MAX(extra * 2, extra + 4); + iov = malloc0(n * sizeof(struct iovec)); + if (!iov) { + r = -ENOMEM; + goto fail; + } + + i = extra; + } + + while (format) { + struct iovec *c; + char *buffer; + va_list aq; + + if (i >= n) { + n = MAX(i*2, 4); + c = realloc(iov, n * sizeof(struct iovec)); + if (!c) { + r = -ENOMEM; + goto fail; + } + + iov = c; + } + + va_copy(aq, ap); + if (vasprintf(&buffer, format, aq) < 0) { + va_end(aq); + r = -ENOMEM; + goto fail; + } + va_end(aq); + + VA_FORMAT_ADVANCE(format, ap); + + IOVEC_SET_STRING(iov[i++], buffer); + + format = va_arg(ap, char *); + } + + *_iov = iov; + + errno = saved_errno; + return i; + +fail: + for (j = 0; j < i; j++) + free(iov[j].iov_base); + + free(iov); + + errno = saved_errno; + return r; +} + +_public_ int sd_journal_send(const char *format, ...) { + int r, i, j; + va_list ap; + struct iovec *iov = NULL; + + va_start(ap, format); + i = fill_iovec_sprintf(format, ap, 0, &iov); + va_end(ap); + + if (_unlikely_(i < 0)) { + r = i; + goto finish; + } + + r = sd_journal_sendv(iov, i); + +finish: + for (j = 0; j < i; j++) + free(iov[j].iov_base); + + free(iov); + + return r; +} + +_public_ int sd_journal_sendv(const struct iovec *iov, int n) { + int fd, buffer_fd; + struct iovec *w; + uint64_t *l; + int r, i, j = 0; + struct msghdr mh; + struct sockaddr_un sa; + ssize_t k; + int saved_errno; + union { + struct cmsghdr cmsghdr; + uint8_t buf[CMSG_SPACE(sizeof(int))]; + } control; + struct cmsghdr *cmsg; + /* We use /dev/shm instead of /tmp here, since we want this to + * be a tmpfs, and one that is available from early boot on + * and where unprivileged users can create files. */ + char path[] = "/dev/shm/journal.XXXXXX"; + bool have_syslog_identifier = false; + + if (_unlikely_(!iov)) + return -EINVAL; + + if (_unlikely_(n <= 0)) + return -EINVAL; + + saved_errno = errno; + + w = alloca(sizeof(struct iovec) * n * 5 + 3); + l = alloca(sizeof(uint64_t) * n); + + for (i = 0; i < n; i++) { + char *c, *nl; + + if (_unlikely_(!iov[i].iov_base || iov[i].iov_len <= 1)) { + r = -EINVAL; + goto finish; + } + + c = memchr(iov[i].iov_base, '=', iov[i].iov_len); + if (_unlikely_(!c || c == iov[i].iov_base)) { + r = -EINVAL; + goto finish; + } + + have_syslog_identifier = have_syslog_identifier || + (c == (char *) iov[i].iov_base + 17 && + memcmp(iov[i].iov_base, "SYSLOG_IDENTIFIER", 17) == 0); + + nl = memchr(iov[i].iov_base, '\n', iov[i].iov_len); + if (nl) { + if (_unlikely_(nl < c)) { + r = -EINVAL; + goto finish; + } + + /* Already includes a newline? Bummer, then + * let's write the variable name, then a + * newline, then the size (64bit LE), followed + * by the data and a final newline */ + + w[j].iov_base = iov[i].iov_base; + w[j].iov_len = c - (char*) iov[i].iov_base; + j++; + + IOVEC_SET_STRING(w[j++], "\n"); + + l[i] = htole64(iov[i].iov_len - (c - (char*) iov[i].iov_base) - 1); + w[j].iov_base = &l[i]; + w[j].iov_len = sizeof(uint64_t); + j++; + + w[j].iov_base = c + 1; + w[j].iov_len = iov[i].iov_len - (c - (char*) iov[i].iov_base) - 1; + j++; + + } else + /* Nothing special? Then just add the line and + * append a newline */ + w[j++] = iov[i]; + + IOVEC_SET_STRING(w[j++], "\n"); + } + + if (!have_syslog_identifier && + string_is_safe(program_invocation_short_name)) { + + /* Implicitly add program_invocation_short_name, if it + * is not set explicitly. We only do this for + * program_invocation_short_name, and nothing else + * since everything else is much nicer to retrieve + * from the outside. */ + + IOVEC_SET_STRING(w[j++], "SYSLOG_IDENTIFIER="); + IOVEC_SET_STRING(w[j++], program_invocation_short_name); + IOVEC_SET_STRING(w[j++], "\n"); + } + + fd = journal_fd(); + if (_unlikely_(fd < 0)) { + r = fd; + goto finish; + } + + zero(sa); + sa.sun_family = AF_UNIX; + strncpy(sa.sun_path, "/run/systemd/journal/socket", sizeof(sa.sun_path)); + + zero(mh); + mh.msg_name = &sa; + mh.msg_namelen = offsetof(struct sockaddr_un, sun_path) + strlen(sa.sun_path); + mh.msg_iov = w; + mh.msg_iovlen = j; + + k = sendmsg(fd, &mh, MSG_NOSIGNAL); + if (k >= 0) { + r = 0; + goto finish; + } + + if (errno != EMSGSIZE && errno != ENOBUFS) { + r = -errno; + goto finish; + } + + /* Message doesn't fit... Let's dump the data in a temporary + * file and just pass a file descriptor of it to the other + * side */ + + buffer_fd = mkostemp(path, O_CLOEXEC|O_RDWR); + if (buffer_fd < 0) { + r = -errno; + goto finish; + } + + if (unlink(path) < 0) { + close_nointr_nofail(buffer_fd); + r = -errno; + goto finish; + } + + n = writev(buffer_fd, w, j); + if (n < 0) { + close_nointr_nofail(buffer_fd); + r = -errno; + goto finish; + } + + mh.msg_iov = NULL; + mh.msg_iovlen = 0; + + zero(control); + mh.msg_control = &control; + mh.msg_controllen = sizeof(control); + + cmsg = CMSG_FIRSTHDR(&mh); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_RIGHTS; + cmsg->cmsg_len = CMSG_LEN(sizeof(int)); + memcpy(CMSG_DATA(cmsg), &buffer_fd, sizeof(int)); + + mh.msg_controllen = cmsg->cmsg_len; + + k = sendmsg(fd, &mh, MSG_NOSIGNAL); + close_nointr_nofail(buffer_fd); + + if (k < 0) { + r = -errno; + goto finish; + } + + r = 0; + +finish: + errno = saved_errno; + + return r; +} + +static int fill_iovec_perror_and_send(const char *message, int skip, struct iovec iov[]) { + size_t n, k, r; + int saved_errno; + + saved_errno = errno; + + k = isempty(message) ? 0 : strlen(message) + 2; + n = 8 + k + 256 + 1; + + for (;;) { + char buffer[n]; + char* j; + + errno = 0; + j = strerror_r(saved_errno, buffer + 8 + k, n - 8 - k); + if (errno == 0) { + char error[6 + 10 + 1]; /* for a 32bit value */ + + if (j != buffer + 8 + k) + memmove(buffer + 8 + k, j, strlen(j)+1); + + memcpy(buffer, "MESSAGE=", 8); + + if (k > 0) { + memcpy(buffer + 8, message, k - 2); + memcpy(buffer + 8 + k - 2, ": ", 2); + } + + snprintf(error, sizeof(error), "ERRNO=%u", saved_errno); + char_array_0(error); + + IOVEC_SET_STRING(iov[skip+0], "PRIORITY=3"); + IOVEC_SET_STRING(iov[skip+1], buffer); + IOVEC_SET_STRING(iov[skip+2], error); + + r = sd_journal_sendv(iov, skip + 3); + + errno = saved_errno; + return r; + } + + if (errno != ERANGE) { + r = -errno; + errno = saved_errno; + return r; + } + + n *= 2; + } +} + +_public_ int sd_journal_perror(const char *message) { + struct iovec iovec[3]; + + return fill_iovec_perror_and_send(message, 0, iovec); +} + +_public_ int sd_journal_stream_fd(const char *identifier, int priority, int level_prefix) { + union sockaddr_union sa; + int fd; + char *header; + size_t l; + ssize_t r; + + if (priority < 0 || priority > 7) + return -EINVAL; + + fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0); + if (fd < 0) + return -errno; + + zero(sa); + sa.un.sun_family = AF_UNIX; + strncpy(sa.un.sun_path, "/run/systemd/journal/stdout", sizeof(sa.un.sun_path)); + + r = connect(fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path)); + if (r < 0) { + close_nointr_nofail(fd); + return -errno; + } + + if (shutdown(fd, SHUT_RD) < 0) { + close_nointr_nofail(fd); + return -errno; + } + + fd_inc_sndbuf(fd, SNDBUF_SIZE); + + if (!identifier) + identifier = ""; + + l = strlen(identifier); + header = alloca(l + 1 + 1 + 2 + 2 + 2 + 2 + 2); + + memcpy(header, identifier, l); + header[l++] = '\n'; + header[l++] = '\n'; /* unit id */ + header[l++] = '0' + priority; + header[l++] = '\n'; + header[l++] = '0' + !!level_prefix; + header[l++] = '\n'; + header[l++] = '0'; + header[l++] = '\n'; + header[l++] = '0'; + header[l++] = '\n'; + header[l++] = '0'; + header[l++] = '\n'; + + r = loop_write(fd, header, l, false); + if (r < 0) { + close_nointr_nofail(fd); + return (int) r; + } + + if ((size_t) r != l) { + close_nointr_nofail(fd); + return -errno; + } + + return fd; +} + +_public_ int sd_journal_print_with_location(int priority, const char *file, const char *line, const char *func, const char *format, ...) { + int r; + va_list ap; + + va_start(ap, format); + r = sd_journal_printv_with_location(priority, file, line, func, format, ap); + va_end(ap); + + return r; +} + +_public_ int sd_journal_printv_with_location(int priority, const char *file, const char *line, const char *func, const char *format, va_list ap) { + char buffer[8 + LINE_MAX], p[11]; + struct iovec iov[5]; + char *f; + + if (priority < 0 || priority > 7) + return -EINVAL; + + if (_unlikely_(!format)) + return -EINVAL; + + snprintf(p, sizeof(p), "PRIORITY=%i", priority & LOG_PRIMASK); + char_array_0(p); + + memcpy(buffer, "MESSAGE=", 8); + vsnprintf(buffer+8, sizeof(buffer) - 8, format, ap); + char_array_0(buffer); + + /* func is initialized from __func__ which is not a macro, but + * a static const char[], hence cannot easily be prefixed with + * CODE_FUNC=, hence let's do it manually here. */ + ALLOCA_CODE_FUNC(f, func); + + zero(iov); + IOVEC_SET_STRING(iov[0], buffer); + IOVEC_SET_STRING(iov[1], p); + IOVEC_SET_STRING(iov[2], file); + IOVEC_SET_STRING(iov[3], line); + IOVEC_SET_STRING(iov[4], f); + + return sd_journal_sendv(iov, ELEMENTSOF(iov)); +} + +_public_ int sd_journal_send_with_location(const char *file, const char *line, const char *func, const char *format, ...) { + int r, i, j; + va_list ap; + struct iovec *iov = NULL; + char *f; + + va_start(ap, format); + i = fill_iovec_sprintf(format, ap, 3, &iov); + va_end(ap); + + if (_unlikely_(i < 0)) { + r = i; + goto finish; + } + + ALLOCA_CODE_FUNC(f, func); + + IOVEC_SET_STRING(iov[0], file); + IOVEC_SET_STRING(iov[1], line); + IOVEC_SET_STRING(iov[2], f); + + r = sd_journal_sendv(iov, i); + +finish: + for (j = 3; j < i; j++) + free(iov[j].iov_base); + + free(iov); + + return r; +} + +_public_ int sd_journal_sendv_with_location( + const char *file, const char *line, + const char *func, + const struct iovec *iov, int n) { + + struct iovec *niov; + char *f; + + if (_unlikely_(!iov)) + return -EINVAL; + + if (_unlikely_(n <= 0)) + return -EINVAL; + + niov = alloca(sizeof(struct iovec) * (n + 3)); + memcpy(niov, iov, sizeof(struct iovec) * n); + + ALLOCA_CODE_FUNC(f, func); + + IOVEC_SET_STRING(niov[n++], file); + IOVEC_SET_STRING(niov[n++], line); + IOVEC_SET_STRING(niov[n++], f); + + return sd_journal_sendv(niov, n); +} + +_public_ int sd_journal_perror_with_location( + const char *file, const char *line, + const char *func, + const char *message) { + + struct iovec iov[6]; + char *f; + + ALLOCA_CODE_FUNC(f, func); + + IOVEC_SET_STRING(iov[0], file); + IOVEC_SET_STRING(iov[1], line); + IOVEC_SET_STRING(iov[2], f); + + return fill_iovec_perror_and_send(message, 3, iov); +} diff --git a/src/journal/journal-vacuum.c b/src/journal/journal-vacuum.c new file mode 100644 index 000000000..731f6c770 --- /dev/null +++ b/src/journal/journal-vacuum.c @@ -0,0 +1,318 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +#include +#include +#include +#include +#include + +#ifdef HAVE_XATTR +#include +#endif + +#include "journal-def.h" +#include "journal-file.h" +#include "journal-vacuum.h" +#include "sd-id128.h" +#include "util.h" + +struct vacuum_info { + off_t usage; + char *filename; + + uint64_t realtime; + sd_id128_t seqnum_id; + uint64_t seqnum; + + bool have_seqnum; +}; + +static int vacuum_compare(const void *_a, const void *_b) { + const struct vacuum_info *a, *b; + + a = _a; + b = _b; + + if (a->have_seqnum && b->have_seqnum && + sd_id128_equal(a->seqnum_id, b->seqnum_id)) { + if (a->seqnum < b->seqnum) + return -1; + else if (a->seqnum > b->seqnum) + return 1; + else + return 0; + } + + if (a->realtime < b->realtime) + return -1; + else if (a->realtime > b->realtime) + return 1; + else if (a->have_seqnum && b->have_seqnum) + return memcmp(&a->seqnum_id, &b->seqnum_id, 16); + else + return strcmp(a->filename, b->filename); +} + +static void patch_realtime( + const char *dir, + const char *fn, + const struct stat *st, + unsigned long long *realtime) { + + usec_t x; + +#ifdef HAVE_XATTR + uint64_t crtime; + _cleanup_free_ const char *path = NULL; +#endif + + /* The timestamp was determined by the file name, but let's + * see if the file might actually be older than the file name + * suggested... */ + + assert(dir); + assert(fn); + assert(st); + assert(realtime); + + x = timespec_load(&st->st_ctim); + if (x > 0 && x != (usec_t) -1 && x < *realtime) + *realtime = x; + + x = timespec_load(&st->st_atim); + if (x > 0 && x != (usec_t) -1 && x < *realtime) + *realtime = x; + + x = timespec_load(&st->st_mtim); + if (x > 0 && x != (usec_t) -1 && x < *realtime) + *realtime = x; + +#ifdef HAVE_XATTR + /* Let's read the original creation time, if possible. Ideally + * we'd just query the creation time the FS might provide, but + * unfortunately there's currently no sane API to query + * it. Hence let's implement this manually... */ + + /* Unfortunately there is is not fgetxattrat(), so we need to + * go via path here. :-( */ + + path = strjoin(dir, "/", fn, NULL); + if (!path) + return; + + if (getxattr(path, "user.crtime_usec", &crtime, sizeof(crtime)) == sizeof(crtime)) { + crtime = le64toh(crtime); + + if (crtime > 0 && crtime != (uint64_t) -1 && crtime < *realtime) + *realtime = crtime; + } +#endif +} + +int journal_directory_vacuum( + const char *directory, + uint64_t max_use, + uint64_t min_free, + usec_t max_retention_usec, + usec_t *oldest_usec) { + + DIR *d; + int r = 0; + struct vacuum_info *list = NULL; + unsigned n_list = 0, n_allocated = 0, i; + uint64_t sum = 0; + usec_t retention_limit = 0; + + assert(directory); + + if (max_use <= 0 && min_free <= 0 && max_retention_usec <= 0) + return 0; + + if (max_retention_usec > 0) { + retention_limit = now(CLOCK_REALTIME); + if (retention_limit > max_retention_usec) + retention_limit -= max_retention_usec; + else + max_retention_usec = retention_limit = 0; + } + + d = opendir(directory); + if (!d) + return -errno; + + for (;;) { + int k; + struct dirent *de; + union dirent_storage buf; + size_t q; + struct stat st; + char *p; + unsigned long long seqnum = 0, realtime; + sd_id128_t seqnum_id; + bool have_seqnum; + + k = readdir_r(d, &buf.de, &de); + if (k != 0) { + r = -k; + goto finish; + } + + if (!de) + break; + + if (fstatat(dirfd(d), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0) + continue; + + if (!S_ISREG(st.st_mode)) + continue; + + q = strlen(de->d_name); + + if (endswith(de->d_name, ".journal")) { + + /* Vacuum archived files */ + + if (q < 1 + 32 + 1 + 16 + 1 + 16 + 8) + continue; + + if (de->d_name[q-8-16-1] != '-' || + de->d_name[q-8-16-1-16-1] != '-' || + de->d_name[q-8-16-1-16-1-32-1] != '@') + continue; + + p = strdup(de->d_name); + if (!p) { + r = -ENOMEM; + goto finish; + } + + de->d_name[q-8-16-1-16-1] = 0; + if (sd_id128_from_string(de->d_name + q-8-16-1-16-1-32, &seqnum_id) < 0) { + free(p); + continue; + } + + if (sscanf(de->d_name + q-8-16-1-16, "%16llx-%16llx.journal", &seqnum, &realtime) != 2) { + free(p); + continue; + } + + have_seqnum = true; + + } else if (endswith(de->d_name, ".journal~")) { + unsigned long long tmp; + + /* Vacuum corrupted files */ + + if (q < 1 + 16 + 1 + 16 + 8 + 1) + continue; + + if (de->d_name[q-1-8-16-1] != '-' || + de->d_name[q-1-8-16-1-16-1] != '@') + continue; + + p = strdup(de->d_name); + if (!p) { + r = -ENOMEM; + goto finish; + } + + if (sscanf(de->d_name + q-1-8-16-1-16, "%16llx-%16llx.journal~", &realtime, &tmp) != 2) { + free(p); + continue; + } + + have_seqnum = false; + } else + /* We do not vacuum active files or unknown files! */ + continue; + + patch_realtime(directory, de->d_name, &st, &realtime); + + if (n_list >= n_allocated) { + struct vacuum_info *j; + + n_allocated = MAX(n_allocated * 2U, 8U); + j = realloc(list, n_allocated * sizeof(struct vacuum_info)); + if (!j) { + free(p); + r = -ENOMEM; + goto finish; + } + + list = j; + } + + list[n_list].filename = p; + list[n_list].usage = 512UL * (uint64_t) st.st_blocks; + list[n_list].seqnum = seqnum; + list[n_list].realtime = realtime; + list[n_list].seqnum_id = seqnum_id; + list[n_list].have_seqnum = have_seqnum; + + sum += list[n_list].usage; + + n_list ++; + } + + if (n_list > 0) + qsort(list, n_list, sizeof(struct vacuum_info), vacuum_compare); + + for (i = 0; i < n_list; i++) { + struct statvfs ss; + + if (fstatvfs(dirfd(d), &ss) < 0) { + r = -errno; + goto finish; + } + + if ((max_retention_usec <= 0 || list[i].realtime >= retention_limit) && + (max_use <= 0 || sum <= max_use) && + (min_free <= 0 || (uint64_t) ss.f_bavail * (uint64_t) ss.f_bsize >= min_free)) + break; + + if (unlinkat(dirfd(d), list[i].filename, 0) >= 0) { + log_debug("Deleted archived journal %s/%s.", directory, list[i].filename); + + if ((uint64_t) list[i].usage > sum) + sum -= list[i].usage; + else + sum = 0; + + } else if (errno != ENOENT) + log_warning("Failed to delete %s/%s: %m", directory, list[i].filename); + } + + if (oldest_usec && i < n_list && (*oldest_usec == 0 || list[i].realtime < *oldest_usec)) + *oldest_usec = list[i].realtime; + +finish: + for (i = 0; i < n_list; i++) + free(list[i].filename); + + free(list); + + if (d) + closedir(d); + + return r; +} diff --git a/src/journal/journal-vacuum.h b/src/journal/journal-vacuum.h new file mode 100644 index 000000000..f5e3e5291 --- /dev/null +++ b/src/journal/journal-vacuum.h @@ -0,0 +1,26 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +#include + +int journal_directory_vacuum(const char *directory, uint64_t max_use, uint64_t min_free, usec_t max_retention_usec, usec_t *oldest_usec); diff --git a/src/journal/journal-verify.c b/src/journal/journal-verify.c new file mode 100644 index 000000000..ed28b4573 --- /dev/null +++ b/src/journal/journal-verify.c @@ -0,0 +1,1163 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + +#include +#include +#include +#include + +#include "util.h" +#include "macro.h" +#include "journal-def.h" +#include "journal-file.h" +#include "journal-authenticate.h" +#include "journal-verify.h" +#include "lookup3.h" +#include "compress.h" +#include "fsprg.h" + +static int journal_file_object_verify(JournalFile *f, Object *o) { + uint64_t i; + + assert(f); + assert(o); + + /* This does various superficial tests about the length an + * possible field values. It does not follow any references to + * other objects. */ + + if ((o->object.flags & OBJECT_COMPRESSED) && + o->object.type != OBJECT_DATA) + return -EBADMSG; + + switch (o->object.type) { + + case OBJECT_DATA: { + uint64_t h1, h2; + + if (le64toh(o->data.entry_offset) <= 0 || + le64toh(o->data.n_entries) <= 0) + return -EBADMSG; + + if (le64toh(o->object.size) - offsetof(DataObject, payload) <= 0) + return -EBADMSG; + + h1 = le64toh(o->data.hash); + + if (o->object.flags & OBJECT_COMPRESSED) { +#ifdef HAVE_XZ + void *b = NULL; + uint64_t alloc = 0, b_size; + + if (!uncompress_blob(o->data.payload, + le64toh(o->object.size) - offsetof(Object, data.payload), + &b, &alloc, &b_size, 0)) + return -EBADMSG; + + h2 = hash64(b, b_size); + free(b); +#else + return -EPROTONOSUPPORT; +#endif + } else + h2 = hash64(o->data.payload, le64toh(o->object.size) - offsetof(Object, data.payload)); + + if (h1 != h2) + return -EBADMSG; + + if (!VALID64(o->data.next_hash_offset) || + !VALID64(o->data.next_field_offset) || + !VALID64(o->data.entry_offset) || + !VALID64(o->data.entry_array_offset)) + return -EBADMSG; + + break; + } + + case OBJECT_FIELD: + if (le64toh(o->object.size) - offsetof(FieldObject, payload) <= 0) + return -EBADMSG; + + if (!VALID64(o->field.next_hash_offset) || + !VALID64(o->field.head_data_offset)) + return -EBADMSG; + break; + + case OBJECT_ENTRY: + if ((le64toh(o->object.size) - offsetof(EntryObject, items)) % sizeof(EntryItem) != 0) + return -EBADMSG; + + if ((le64toh(o->object.size) - offsetof(EntryObject, items)) / sizeof(EntryItem) <= 0) + return -EBADMSG; + + if (le64toh(o->entry.seqnum) <= 0 || + !VALID_REALTIME(le64toh(o->entry.realtime)) || + !VALID_MONOTONIC(le64toh(o->entry.monotonic))) + return -EBADMSG; + + for (i = 0; i < journal_file_entry_n_items(o); i++) { + if (o->entry.items[i].object_offset == 0 || + !VALID64(o->entry.items[i].object_offset)) + return -EBADMSG; + } + + break; + + case OBJECT_DATA_HASH_TABLE: + case OBJECT_FIELD_HASH_TABLE: + if ((le64toh(o->object.size) - offsetof(HashTableObject, items)) % sizeof(HashItem) != 0) + return -EBADMSG; + + if ((le64toh(o->object.size) - offsetof(HashTableObject, items)) / sizeof(HashItem) <= 0) + return -EBADMSG; + + for (i = 0; i < journal_file_hash_table_n_items(o); i++) { + if (o->hash_table.items[i].head_hash_offset != 0 && + !VALID64(le64toh(o->hash_table.items[i].head_hash_offset))) + return -EBADMSG; + if (o->hash_table.items[i].tail_hash_offset != 0 && + !VALID64(le64toh(o->hash_table.items[i].tail_hash_offset))) + return -EBADMSG; + + if ((o->hash_table.items[i].head_hash_offset != 0) != + (o->hash_table.items[i].tail_hash_offset != 0)) + return -EBADMSG; + } + + break; + + case OBJECT_ENTRY_ARRAY: + if ((le64toh(o->object.size) - offsetof(EntryArrayObject, items)) % sizeof(le64_t) != 0) + return -EBADMSG; + + if ((le64toh(o->object.size) - offsetof(EntryArrayObject, items)) / sizeof(le64_t) <= 0) + return -EBADMSG; + + if (!VALID64(o->entry_array.next_entry_array_offset)) + return -EBADMSG; + + for (i = 0; i < journal_file_entry_array_n_items(o); i++) + if (o->entry_array.items[i] != 0 && + !VALID64(o->entry_array.items[i])) + return -EBADMSG; + + break; + + case OBJECT_TAG: + if (le64toh(o->object.size) != sizeof(TagObject)) + return -EBADMSG; + + if (!VALID_EPOCH(o->tag.epoch)) + return -EBADMSG; + + break; + } + + return 0; +} + +static void draw_progress(uint64_t p, usec_t *last_usec) { + unsigned n, i, j, k; + usec_t z, x; + + if (!on_tty()) + return; + + z = now(CLOCK_MONOTONIC); + x = *last_usec; + + if (x != 0 && x + 40 * USEC_PER_MSEC > z) + return; + + *last_usec = z; + + n = (3 * columns()) / 4; + j = (n * (unsigned) p) / 65535ULL; + k = n - j; + + fputs("\r\x1B[?25l" ANSI_HIGHLIGHT_GREEN_ON, stdout); + + for (i = 0; i < j; i++) + fputs("\xe2\x96\x88", stdout); + + fputs(ANSI_HIGHLIGHT_OFF, stdout); + + for (i = 0; i < k; i++) + fputs("\xe2\x96\x91", stdout); + + printf(" %3lu%%", 100LU * (unsigned long) p / 65535LU); + + fputs("\r\x1B[?25h", stdout); + fflush(stdout); +} + +static void flush_progress(void) { + unsigned n, i; + + if (!on_tty()) + return; + + n = (3 * columns()) / 4; + + putchar('\r'); + + for (i = 0; i < n + 5; i++) + putchar(' '); + + putchar('\r'); + fflush(stdout); +} + +static int write_uint64(int fd, uint64_t p) { + ssize_t k; + + k = write(fd, &p, sizeof(p)); + if (k < 0) + return -errno; + if (k != sizeof(p)) + return -EIO; + + return 0; +} + +static int contains_uint64(MMapCache *m, int fd, uint64_t n, uint64_t p) { + uint64_t a, b; + int r; + + assert(m); + assert(fd >= 0); + + /* Bisection ... */ + + a = 0; b = n; + while (a < b) { + uint64_t c, *z; + + c = (a + b) / 2; + + r = mmap_cache_get(m, fd, PROT_READ|PROT_WRITE, 0, false, c * sizeof(uint64_t), sizeof(uint64_t), NULL, (void **) &z); + if (r < 0) + return r; + + if (*z == p) + return 1; + + if (a + 1 >= b) + return 0; + + if (p < *z) + b = c; + else + a = c; + } + + return 0; +} + +static int entry_points_to_data( + JournalFile *f, + int entry_fd, + uint64_t n_entries, + uint64_t entry_p, + uint64_t data_p) { + + int r; + uint64_t i, n, a; + Object *o; + bool found = false; + + assert(f); + assert(entry_fd >= 0); + + if (!contains_uint64(f->mmap, entry_fd, n_entries, entry_p)) { + log_error("Data object references invalid entry at %llu", (unsigned long long) data_p); + return -EBADMSG; + } + + r = journal_file_move_to_object(f, OBJECT_ENTRY, entry_p, &o); + if (r < 0) + return r; + + n = journal_file_entry_n_items(o); + for (i = 0; i < n; i++) + if (le64toh(o->entry.items[i].object_offset) == data_p) { + found = true; + break; + } + + if (!found) { + log_error("Data object not referenced by linked entry at %llu", (unsigned long long) data_p); + return -EBADMSG; + } + + /* Check if this entry is also in main entry array. Since the + * main entry array has already been verified we can rely on + * its consistency.*/ + + i = 0; + n = le64toh(f->header->n_entries); + a = le64toh(f->header->entry_array_offset); + + while (i < n) { + uint64_t m, u; + + r = journal_file_move_to_object(f, OBJECT_ENTRY_ARRAY, a, &o); + if (r < 0) + return r; + + m = journal_file_entry_array_n_items(o); + u = MIN(n - i, m); + + if (entry_p <= le64toh(o->entry_array.items[u-1])) { + uint64_t x, y, z; + + x = 0; + y = u; + + while (x < y) { + z = (x + y) / 2; + + if (le64toh(o->entry_array.items[z]) == entry_p) + return 0; + + if (x + 1 >= y) + break; + + if (entry_p < le64toh(o->entry_array.items[z])) + y = z; + else + x = z; + } + + log_error("Entry object doesn't exist in main entry array at %llu", (unsigned long long) entry_p); + return -EBADMSG; + } + + i += u; + a = le64toh(o->entry_array.next_entry_array_offset); + } + + return 0; +} + +static int verify_data( + JournalFile *f, + Object *o, uint64_t p, + int entry_fd, uint64_t n_entries, + int entry_array_fd, uint64_t n_entry_arrays) { + + uint64_t i, n, a, last, q; + int r; + + assert(f); + assert(o); + assert(entry_fd >= 0); + assert(entry_array_fd >= 0); + + n = le64toh(o->data.n_entries); + a = le64toh(o->data.entry_array_offset); + + /* We already checked this earlier */ + assert(n > 0); + + last = q = le64toh(o->data.entry_offset); + r = entry_points_to_data(f, entry_fd, n_entries, q, p); + if (r < 0) + return r; + + i = 1; + while (i < n) { + uint64_t next, m, j; + + if (a == 0) { + log_error("Array chain too short at %llu", (unsigned long long) p); + return -EBADMSG; + } + + if (!contains_uint64(f->mmap, entry_array_fd, n_entry_arrays, a)) { + log_error("Invalid array at %llu", (unsigned long long) p); + return -EBADMSG; + } + + r = journal_file_move_to_object(f, OBJECT_ENTRY_ARRAY, a, &o); + if (r < 0) + return r; + + next = le64toh(o->entry_array.next_entry_array_offset); + if (next != 0 && next <= a) { + log_error("Array chain has cycle at %llu", (unsigned long long) p); + return -EBADMSG; + } + + m = journal_file_entry_array_n_items(o); + for (j = 0; i < n && j < m; i++, j++) { + + q = le64toh(o->entry_array.items[j]); + if (q <= last) { + log_error("Data object's entry array not sorted at %llu", (unsigned long long) p); + return -EBADMSG; + } + last = q; + + r = entry_points_to_data(f, entry_fd, n_entries, q, p); + if (r < 0) + return r; + + /* Pointer might have moved, reposition */ + r = journal_file_move_to_object(f, OBJECT_ENTRY_ARRAY, a, &o); + if (r < 0) + return r; + } + + a = next; + } + + return 0; +} + +static int verify_hash_table( + JournalFile *f, + int data_fd, uint64_t n_data, + int entry_fd, uint64_t n_entries, + int entry_array_fd, uint64_t n_entry_arrays, + usec_t *last_usec, + bool show_progress) { + + uint64_t i, n; + int r; + + assert(f); + assert(data_fd >= 0); + assert(entry_fd >= 0); + assert(entry_array_fd >= 0); + assert(last_usec); + + n = le64toh(f->header->data_hash_table_size) / sizeof(HashItem); + for (i = 0; i < n; i++) { + uint64_t last = 0, p; + + if (show_progress) + draw_progress(0xC000 + (0x3FFF * i / n), last_usec); + + p = le64toh(f->data_hash_table[i].head_hash_offset); + while (p != 0) { + Object *o; + uint64_t next; + + if (!contains_uint64(f->mmap, data_fd, n_data, p)) { + log_error("Invalid data object at hash entry %llu of %llu", + (unsigned long long) i, (unsigned long long) n); + return -EBADMSG; + } + + r = journal_file_move_to_object(f, OBJECT_DATA, p, &o); + if (r < 0) + return r; + + next = le64toh(o->data.next_hash_offset); + if (next != 0 && next <= p) { + log_error("Hash chain has a cycle in hash entry %llu of %llu", + (unsigned long long) i, (unsigned long long) n); + return -EBADMSG; + } + + if (le64toh(o->data.hash) % n != i) { + log_error("Hash value mismatch in hash entry %llu of %llu", + (unsigned long long) i, (unsigned long long) n); + return -EBADMSG; + } + + r = verify_data(f, o, p, entry_fd, n_entries, entry_array_fd, n_entry_arrays); + if (r < 0) + return r; + + last = p; + p = next; + } + + if (last != le64toh(f->data_hash_table[i].tail_hash_offset)) { + log_error("Tail hash pointer mismatch in hash table"); + return -EBADMSG; + } + } + + return 0; +} + +static int data_object_in_hash_table(JournalFile *f, uint64_t hash, uint64_t p) { + uint64_t n, h, q; + int r; + assert(f); + + n = le64toh(f->header->data_hash_table_size) / sizeof(HashItem); + h = hash % n; + + q = le64toh(f->data_hash_table[h].head_hash_offset); + while (q != 0) { + Object *o; + + if (p == q) + return 1; + + r = journal_file_move_to_object(f, OBJECT_DATA, q, &o); + if (r < 0) + return r; + + q = le64toh(o->data.next_hash_offset); + } + + return 0; +} + +static int verify_entry( + JournalFile *f, + Object *o, uint64_t p, + int data_fd, uint64_t n_data) { + + uint64_t i, n; + int r; + + assert(f); + assert(o); + assert(data_fd >= 0); + + n = journal_file_entry_n_items(o); + for (i = 0; i < n; i++) { + uint64_t q, h; + Object *u; + + q = le64toh(o->entry.items[i].object_offset); + h = le64toh(o->entry.items[i].hash); + + if (!contains_uint64(f->mmap, data_fd, n_data, q)) { + log_error("Invalid data object at entry %llu", + (unsigned long long) p); + return -EBADMSG; + } + + r = journal_file_move_to_object(f, OBJECT_DATA, q, &u); + if (r < 0) + return r; + + if (le64toh(u->data.hash) != h) { + log_error("Hash mismatch for data object at entry %llu", + (unsigned long long) p); + return -EBADMSG; + } + + r = data_object_in_hash_table(f, h, q); + if (r < 0) + return r; + if (r == 0) { + log_error("Data object missing from hash at entry %llu", + (unsigned long long) p); + return -EBADMSG; + } + } + + return 0; +} + +static int verify_entry_array( + JournalFile *f, + int data_fd, uint64_t n_data, + int entry_fd, uint64_t n_entries, + int entry_array_fd, uint64_t n_entry_arrays, + usec_t *last_usec, + bool show_progress) { + + uint64_t i = 0, a, n, last = 0; + int r; + + assert(f); + assert(data_fd >= 0); + assert(entry_fd >= 0); + assert(entry_array_fd >= 0); + assert(last_usec); + + n = le64toh(f->header->n_entries); + a = le64toh(f->header->entry_array_offset); + while (i < n) { + uint64_t next, m, j; + Object *o; + + if (show_progress) + draw_progress(0x8000 + (0x3FFF * i / n), last_usec); + + if (a == 0) { + log_error("Array chain too short at %llu of %llu", + (unsigned long long) i, (unsigned long long) n); + return -EBADMSG; + } + + if (!contains_uint64(f->mmap, entry_array_fd, n_entry_arrays, a)) { + log_error("Invalid array at %llu of %llu", + (unsigned long long) i, (unsigned long long) n); + return -EBADMSG; + } + + r = journal_file_move_to_object(f, OBJECT_ENTRY_ARRAY, a, &o); + if (r < 0) + return r; + + next = le64toh(o->entry_array.next_entry_array_offset); + if (next != 0 && next <= a) { + log_error("Array chain has cycle at %llu of %llu", + (unsigned long long) i, (unsigned long long) n); + return -EBADMSG; + } + + m = journal_file_entry_array_n_items(o); + for (j = 0; i < n && j < m; i++, j++) { + uint64_t p; + + p = le64toh(o->entry_array.items[j]); + if (p <= last) { + log_error("Entry array not sorted at %llu of %llu", + (unsigned long long) i, (unsigned long long) n); + return -EBADMSG; + } + last = p; + + if (!contains_uint64(f->mmap, entry_fd, n_entries, p)) { + log_error("Invalid array entry at %llu of %llu", + (unsigned long long) i, (unsigned long long) n); + return -EBADMSG; + } + + r = journal_file_move_to_object(f, OBJECT_ENTRY, p, &o); + if (r < 0) + return r; + + r = verify_entry(f, o, p, data_fd, n_data); + if (r < 0) + return r; + + /* Pointer might have moved, reposition */ + r = journal_file_move_to_object(f, OBJECT_ENTRY_ARRAY, a, &o); + if (r < 0) + return r; + } + + a = next; + } + + return 0; +} + +int journal_file_verify( + JournalFile *f, + const char *key, + usec_t *first_contained, usec_t *last_validated, usec_t *last_contained, + bool show_progress) { + int r; + Object *o; + uint64_t p = 0, last_epoch = 0, last_tag_realtime = 0, last_sealed_realtime = 0; + + uint64_t entry_seqnum = 0, entry_monotonic = 0, entry_realtime = 0; + sd_id128_t entry_boot_id; + bool entry_seqnum_set = false, entry_monotonic_set = false, entry_realtime_set = false, found_main_entry_array = false; + uint64_t n_weird = 0, n_objects = 0, n_entries = 0, n_data = 0, n_fields = 0, n_data_hash_tables = 0, n_field_hash_tables = 0, n_entry_arrays = 0, n_tags = 0; + usec_t last_usec = 0; + int data_fd = -1, entry_fd = -1, entry_array_fd = -1; + char data_path[] = "/var/tmp/journal-data-XXXXXX", + entry_path[] = "/var/tmp/journal-entry-XXXXXX", + entry_array_path[] = "/var/tmp/journal-entry-array-XXXXXX"; + unsigned i; + bool found_last; +#ifdef HAVE_GCRYPT + uint64_t last_tag = 0; +#endif + assert(f); + + if (key) { +#ifdef HAVE_GCRYPT + r = journal_file_parse_verification_key(f, key); + if (r < 0) { + log_error("Failed to parse seed."); + return r; + } +#else + return -ENOTSUP; +#endif + } else if (f->seal) + return -ENOKEY; + + data_fd = mkostemp(data_path, O_CLOEXEC); + if (data_fd < 0) { + log_error("Failed to create data file: %m"); + r = -errno; + goto fail; + } + unlink(data_path); + + entry_fd = mkostemp(entry_path, O_CLOEXEC); + if (entry_fd < 0) { + log_error("Failed to create entry file: %m"); + r = -errno; + goto fail; + } + unlink(entry_path); + + entry_array_fd = mkostemp(entry_array_path, O_CLOEXEC); + if (entry_array_fd < 0) { + log_error("Failed to create entry array file: %m"); + r = -errno; + goto fail; + } + unlink(entry_array_path); + +#ifdef HAVE_GCRYPT + if ((le32toh(f->header->compatible_flags) & ~HEADER_COMPATIBLE_SEALED) != 0) +#else + if (f->header->compatible_flags != 0) +#endif + { + log_error("Cannot verify file with unknown extensions."); + r = -ENOTSUP; + goto fail; + } + + for (i = 0; i < sizeof(f->header->reserved); i++) + if (f->header->reserved[i] != 0) { + log_error("Reserved field in non-zero."); + r = -EBADMSG; + goto fail; + } + + /* First iteration: we go through all objects, verify the + * superficial structure, headers, hashes. */ + + p = le64toh(f->header->header_size); + while (p != 0) { + if (show_progress) + draw_progress(0x7FFF * p / le64toh(f->header->tail_object_offset), &last_usec); + + r = journal_file_move_to_object(f, -1, p, &o); + if (r < 0) { + log_error("Invalid object at %llu", (unsigned long long) p); + goto fail; + } + + if (p > le64toh(f->header->tail_object_offset)) { + log_error("Invalid tail object pointer"); + r = -EBADMSG; + goto fail; + } + + if (p == le64toh(f->header->tail_object_offset)) + found_last = true; + + n_objects ++; + + r = journal_file_object_verify(f, o); + if (r < 0) { + log_error("Invalid object contents at %llu", (unsigned long long) p); + goto fail; + } + + if ((o->object.flags & OBJECT_COMPRESSED) && !JOURNAL_HEADER_COMPRESSED(f->header)) { + log_error("Compressed object in file without compression at %llu", (unsigned long long) p); + r = -EBADMSG; + goto fail; + } + + switch (o->object.type) { + + case OBJECT_DATA: + r = write_uint64(data_fd, p); + if (r < 0) + goto fail; + + n_data++; + break; + + case OBJECT_FIELD: + n_fields++; + break; + + case OBJECT_ENTRY: + if (JOURNAL_HEADER_SEALED(f->header) && n_tags <= 0) { + log_error("First entry before first tag at %llu", (unsigned long long) p); + r = -EBADMSG; + goto fail; + } + + r = write_uint64(entry_fd, p); + if (r < 0) + goto fail; + + if (le64toh(o->entry.realtime) < last_tag_realtime) { + log_error("Older entry after newer tag at %llu", (unsigned long long) p); + r = -EBADMSG; + goto fail; + } + + if (!entry_seqnum_set && + le64toh(o->entry.seqnum) != le64toh(f->header->head_entry_seqnum)) { + log_error("Head entry sequence number incorrect at %llu", (unsigned long long) p); + r = -EBADMSG; + goto fail; + } + + if (entry_seqnum_set && + entry_seqnum >= le64toh(o->entry.seqnum)) { + log_error("Entry sequence number out of synchronization at %llu", (unsigned long long) p); + r = -EBADMSG; + goto fail; + } + + entry_seqnum = le64toh(o->entry.seqnum); + entry_seqnum_set = true; + + if (entry_monotonic_set && + sd_id128_equal(entry_boot_id, o->entry.boot_id) && + entry_monotonic > le64toh(o->entry.monotonic)) { + log_error("Entry timestamp out of synchronization at %llu", (unsigned long long) p); + r = -EBADMSG; + goto fail; + } + + entry_monotonic = le64toh(o->entry.monotonic); + entry_boot_id = o->entry.boot_id; + entry_monotonic_set = true; + + if (!entry_realtime_set && + le64toh(o->entry.realtime) != le64toh(f->header->head_entry_realtime)) { + log_error("Head entry realtime timestamp incorrect"); + r = -EBADMSG; + goto fail; + } + + entry_realtime = le64toh(o->entry.realtime); + entry_realtime_set = true; + + n_entries ++; + break; + + case OBJECT_DATA_HASH_TABLE: + if (n_data_hash_tables > 1) { + log_error("More than one data hash table at %llu", (unsigned long long) p); + r = -EBADMSG; + goto fail; + } + + if (le64toh(f->header->data_hash_table_offset) != p + offsetof(HashTableObject, items) || + le64toh(f->header->data_hash_table_size) != le64toh(o->object.size) - offsetof(HashTableObject, items)) { + log_error("Header fields for data hash table invalid"); + r = -EBADMSG; + goto fail; + } + + n_data_hash_tables++; + break; + + case OBJECT_FIELD_HASH_TABLE: + if (n_field_hash_tables > 1) { + log_error("More than one field hash table at %llu", (unsigned long long) p); + r = -EBADMSG; + goto fail; + } + + if (le64toh(f->header->field_hash_table_offset) != p + offsetof(HashTableObject, items) || + le64toh(f->header->field_hash_table_size) != le64toh(o->object.size) - offsetof(HashTableObject, items)) { + log_error("Header fields for field hash table invalid"); + r = -EBADMSG; + goto fail; + } + + n_field_hash_tables++; + break; + + case OBJECT_ENTRY_ARRAY: + r = write_uint64(entry_array_fd, p); + if (r < 0) + goto fail; + + if (p == le64toh(f->header->entry_array_offset)) { + if (found_main_entry_array) { + log_error("More than one main entry array at %llu", (unsigned long long) p); + r = -EBADMSG; + goto fail; + } + + found_main_entry_array = true; + } + + n_entry_arrays++; + break; + + case OBJECT_TAG: + if (!JOURNAL_HEADER_SEALED(f->header)) { + log_error("Tag object in file without sealing at %llu", (unsigned long long) p); + r = -EBADMSG; + goto fail; + } + + if (le64toh(o->tag.seqnum) != n_tags + 1) { + log_error("Tag sequence number out of synchronization at %llu", (unsigned long long) p); + r = -EBADMSG; + goto fail; + } + + if (le64toh(o->tag.epoch) < last_epoch) { + log_error("Epoch sequence out of synchronization at %llu", (unsigned long long) p); + r = -EBADMSG; + goto fail; + } + +#ifdef HAVE_GCRYPT + if (f->seal) { + uint64_t q, rt; + + log_debug("Checking tag %llu..", (unsigned long long) le64toh(o->tag.seqnum)); + + rt = f->fss_start_usec + o->tag.epoch * f->fss_interval_usec; + if (entry_realtime_set && entry_realtime >= rt + f->fss_interval_usec) { + log_error("Tag/entry realtime timestamp out of synchronization at %llu", (unsigned long long) p); + r = -EBADMSG; + goto fail; + } + + /* OK, now we know the epoch. So let's now set + * it, and calculate the HMAC for everything + * since the last tag. */ + r = journal_file_fsprg_seek(f, le64toh(o->tag.epoch)); + if (r < 0) + goto fail; + + r = journal_file_hmac_start(f); + if (r < 0) + goto fail; + + if (last_tag == 0) { + r = journal_file_hmac_put_header(f); + if (r < 0) + goto fail; + + q = le64toh(f->header->header_size); + } else + q = last_tag; + + while (q <= p) { + r = journal_file_move_to_object(f, -1, q, &o); + if (r < 0) + goto fail; + + r = journal_file_hmac_put_object(f, -1, o, q); + if (r < 0) + goto fail; + + q = q + ALIGN64(le64toh(o->object.size)); + } + + /* Position might have changed, let's reposition things */ + r = journal_file_move_to_object(f, -1, p, &o); + if (r < 0) + goto fail; + + if (memcmp(o->tag.tag, gcry_md_read(f->hmac, 0), TAG_LENGTH) != 0) { + log_error("Tag failed verification at %llu", (unsigned long long) p); + r = -EBADMSG; + goto fail; + } + + f->hmac_running = false; + last_tag_realtime = rt; + last_sealed_realtime = entry_realtime; + } + + last_tag = p + ALIGN64(le64toh(o->object.size)); +#endif + + last_epoch = le64toh(o->tag.epoch); + + n_tags ++; + break; + + default: + n_weird ++; + } + + if (p == le64toh(f->header->tail_object_offset)) + p = 0; + else + p = p + ALIGN64(le64toh(o->object.size)); + } + + if (!found_last) { + log_error("Tail object pointer dead"); + r = -EBADMSG; + goto fail; + } + + if (n_objects != le64toh(f->header->n_objects)) { + log_error("Object number mismatch"); + r = -EBADMSG; + goto fail; + } + + if (n_entries != le64toh(f->header->n_entries)) { + log_error("Entry number mismatch"); + r = -EBADMSG; + goto fail; + } + + if (JOURNAL_HEADER_CONTAINS(f->header, n_data) && + n_data != le64toh(f->header->n_data)) { + log_error("Data number mismatch"); + r = -EBADMSG; + goto fail; + } + + if (JOURNAL_HEADER_CONTAINS(f->header, n_fields) && + n_fields != le64toh(f->header->n_fields)) { + log_error("Field number mismatch"); + r = -EBADMSG; + goto fail; + } + + if (JOURNAL_HEADER_CONTAINS(f->header, n_tags) && + n_tags != le64toh(f->header->n_tags)) { + log_error("Tag number mismatch"); + r = -EBADMSG; + goto fail; + } + + if (JOURNAL_HEADER_CONTAINS(f->header, n_entry_arrays) && + n_entry_arrays != le64toh(f->header->n_entry_arrays)) { + log_error("Entry array number mismatch"); + r = -EBADMSG; + goto fail; + } + + if (n_data_hash_tables != 1) { + log_error("Missing data hash table"); + r = -EBADMSG; + goto fail; + } + + if (n_field_hash_tables != 1) { + log_error("Missing field hash table"); + r = -EBADMSG; + goto fail; + } + + if (!found_main_entry_array) { + log_error("Missing entry array"); + r = -EBADMSG; + goto fail; + } + + if (entry_seqnum_set && + entry_seqnum != le64toh(f->header->tail_entry_seqnum)) { + log_error("Invalid tail seqnum"); + r = -EBADMSG; + goto fail; + } + + if (entry_monotonic_set && + (!sd_id128_equal(entry_boot_id, f->header->boot_id) || + entry_monotonic != le64toh(f->header->tail_entry_monotonic))) { + log_error("Invalid tail monotonic timestamp"); + r = -EBADMSG; + goto fail; + } + + if (entry_realtime_set && entry_realtime != le64toh(f->header->tail_entry_realtime)) { + log_error("Invalid tail realtime timestamp"); + r = -EBADMSG; + goto fail; + } + + /* Second iteration: we follow all objects referenced from the + * two entry points: the object hash table and the entry + * array. We also check that everything referenced (directly + * or indirectly) in the data hash table also exists in the + * entry array, and vice versa. Note that we do not care for + * unreferenced objects. We only care that everything that is + * referenced is consistent. */ + + r = verify_entry_array(f, + data_fd, n_data, + entry_fd, n_entries, + entry_array_fd, n_entry_arrays, + &last_usec, + show_progress); + if (r < 0) + goto fail; + + r = verify_hash_table(f, + data_fd, n_data, + entry_fd, n_entries, + entry_array_fd, n_entry_arrays, + &last_usec, + show_progress); + if (r < 0) + goto fail; + + if (show_progress) + flush_progress(); + + mmap_cache_close_fd(f->mmap, data_fd); + mmap_cache_close_fd(f->mmap, entry_fd); + mmap_cache_close_fd(f->mmap, entry_array_fd); + + close_nointr_nofail(data_fd); + close_nointr_nofail(entry_fd); + close_nointr_nofail(entry_array_fd); + + if (first_contained) + *first_contained = le64toh(f->header->head_entry_realtime); + if (last_validated) + *last_validated = last_sealed_realtime; + if (last_contained) + *last_contained = le64toh(f->header->tail_entry_realtime); + + return 0; + +fail: + if (show_progress) + flush_progress(); + + log_error("File corruption detected at %s:%llu (of %llu, %llu%%).", + f->path, + (unsigned long long) p, + (unsigned long long) f->last_stat.st_size, + (unsigned long long) (100 * p / f->last_stat.st_size)); + + if (data_fd >= 0) { + mmap_cache_close_fd(f->mmap, data_fd); + close_nointr_nofail(data_fd); + } + + if (entry_fd >= 0) { + mmap_cache_close_fd(f->mmap, entry_fd); + close_nointr_nofail(entry_fd); + } + + if (entry_array_fd >= 0) { + mmap_cache_close_fd(f->mmap, entry_array_fd); + close_nointr_nofail(entry_array_fd); + } + + return r; +} diff --git a/src/journal/journal-verify.h b/src/journal/journal-verify.h new file mode 100644 index 000000000..e392ab61d --- /dev/null +++ b/src/journal/journal-verify.h @@ -0,0 +1,26 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +#include "journal-file.h" + +int journal_file_verify(JournalFile *f, const char *key, usec_t *first_contained, usec_t *last_validated, usec_t *last_contained, bool show_progress); diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c new file mode 100644 index 000000000..a74d43be7 --- /dev/null +++ b/src/journal/journalctl.c @@ -0,0 +1,1104 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "log.h" +#include "util.h" +#include "path-util.h" +#include "build.h" +#include "pager.h" +#include "logs-show.h" +#include "strv.h" +#include "journal-internal.h" +#include "journal-def.h" +#include "journal-verify.h" +#include "journal-authenticate.h" +#include "journal-qrcode.h" +#include "fsprg.h" +#include "unit-name.h" +#include "catalog.h" + +#define DEFAULT_FSS_INTERVAL_USEC (15*USEC_PER_MINUTE) + +static OutputMode arg_output = OUTPUT_SHORT; +static bool arg_follow = false; +static bool arg_full = false; +static bool arg_all = false; +static bool arg_no_pager = false; +static unsigned arg_lines = 0; +static bool arg_no_tail = false; +static bool arg_quiet = false; +static bool arg_merge = false; +static bool arg_this_boot = false; +static const char *arg_cursor = NULL; +static const char *arg_directory = NULL; +static int arg_priorities = 0xFF; +static const char *arg_verify_key = NULL; +#ifdef HAVE_GCRYPT +static usec_t arg_interval = DEFAULT_FSS_INTERVAL_USEC; +#endif +static usec_t arg_since, arg_until; +static bool arg_since_set = false, arg_until_set = false; +static const char *arg_unit = NULL; +static const char *arg_field = NULL; +static bool arg_catalog = false; + +static enum { + ACTION_SHOW, + ACTION_NEW_ID128, + ACTION_PRINT_HEADER, + ACTION_SETUP_KEYS, + ACTION_VERIFY, + ACTION_DISK_USAGE, + ACTION_LIST_CATALOG, + ACTION_UPDATE_CATALOG +} arg_action = ACTION_SHOW; + +static int help(void) { + + printf("%s [OPTIONS...] [MATCHES...]\n\n" + "Query the journal.\n\n" + "Flags:\n" + " --since=DATE Start showing entries newer or of the specified date\n" + " --until=DATE Stop showing entries older or of the specified date\n" + " -c --cursor=CURSOR Start showing entries from specified cursor\n" + " -b --this-boot Show data only from current boot\n" + " -u --unit=UNIT Show data only from the specified unit\n" + " -p --priority=RANGE Show only messages within the specified priority range\n" + " -f --follow Follow journal\n" + " -n --lines[=INTEGER] Number of journal entries to show\n" + " --no-tail Show all lines, even in follow mode\n" + " -o --output=STRING Change journal output mode (short, short-monotonic,\n" + " verbose, export, json, json-pretty, json-sse, cat)\n" + " -x --catalog Add message explanations where available\n" + " --full Do not ellipsize fields\n" + " -a --all Show all fields, including long and unprintable\n" + " -q --quiet Don't show privilege warning\n" + " --no-pager Do not pipe output into a pager\n" + " -m --merge Show entries from all available journals\n" + " -D --directory=PATH Show journal files from directory\n" +#ifdef HAVE_GCRYPT + " --interval=TIME Time interval for changing the FSS sealing key\n" + " --verify-key=KEY Specify FSS verification key\n" +#endif + "\nCommands:\n" + " -h --help Show this help\n" + " --version Show package version\n" + " --new-id128 Generate a new 128 Bit ID\n" + " --header Show journal header information\n" + " --disk-usage Show total disk usage\n" + " -F --field=FIELD List all values a certain field takes\n" + " --list-catalog Show message IDs of all entries in the message catalog\n" + " --update-catalog Update the message catalog database\n" +#ifdef HAVE_GCRYPT + " --setup-keys Generate new FSS key pair\n" + " --verify Verify journal file consistency\n" +#endif + , program_invocation_short_name); + + return 0; +} + +static int parse_argv(int argc, char *argv[]) { + + enum { + ARG_VERSION = 0x100, + ARG_NO_PAGER, + ARG_NO_TAIL, + ARG_NEW_ID128, + ARG_HEADER, + ARG_FULL, + ARG_SETUP_KEYS, + ARG_INTERVAL, + ARG_VERIFY, + ARG_VERIFY_KEY, + ARG_DISK_USAGE, + ARG_SINCE, + ARG_UNTIL, + ARG_LIST_CATALOG, + ARG_UPDATE_CATALOG + }; + + static const struct option options[] = { + { "help", no_argument, NULL, 'h' }, + { "version" , no_argument, NULL, ARG_VERSION }, + { "no-pager", no_argument, NULL, ARG_NO_PAGER }, + { "follow", no_argument, NULL, 'f' }, + { "output", required_argument, NULL, 'o' }, + { "all", no_argument, NULL, 'a' }, + { "full", no_argument, NULL, ARG_FULL }, + { "lines", optional_argument, NULL, 'n' }, + { "no-tail", no_argument, NULL, ARG_NO_TAIL }, + { "new-id128", no_argument, NULL, ARG_NEW_ID128 }, + { "quiet", no_argument, NULL, 'q' }, + { "merge", no_argument, NULL, 'm' }, + { "this-boot", no_argument, NULL, 'b' }, + { "directory", required_argument, NULL, 'D' }, + { "header", no_argument, NULL, ARG_HEADER }, + { "priority", required_argument, NULL, 'p' }, + { "setup-keys", no_argument, NULL, ARG_SETUP_KEYS }, + { "interval", required_argument, NULL, ARG_INTERVAL }, + { "verify", no_argument, NULL, ARG_VERIFY }, + { "verify-key", required_argument, NULL, ARG_VERIFY_KEY }, + { "disk-usage", no_argument, NULL, ARG_DISK_USAGE }, + { "cursor", required_argument, NULL, 'c' }, + { "since", required_argument, NULL, ARG_SINCE }, + { "until", required_argument, NULL, ARG_UNTIL }, + { "unit", required_argument, NULL, 'u' }, + { "field", required_argument, NULL, 'F' }, + { "catalog", no_argument, NULL, 'x' }, + { "list-catalog", no_argument, NULL, ARG_LIST_CATALOG }, + { "update-catalog",no_argument, NULL, ARG_UPDATE_CATALOG }, + { NULL, 0, NULL, 0 } + }; + + int c, r; + + assert(argc >= 0); + assert(argv); + + while ((c = getopt_long(argc, argv, "hfo:an::qmbD:p:c:u:F:x", options, NULL)) >= 0) { + + switch (c) { + + case 'h': + help(); + return 0; + + case ARG_VERSION: + puts(PACKAGE_STRING); + puts(SYSTEMD_FEATURES); + return 0; + + case ARG_NO_PAGER: + arg_no_pager = true; + break; + + case 'f': + arg_follow = true; + break; + + case 'o': + arg_output = output_mode_from_string(optarg); + if (arg_output < 0) { + log_error("Unknown output format '%s'.", optarg); + return -EINVAL; + } + + if (arg_output == OUTPUT_EXPORT || + arg_output == OUTPUT_JSON || + arg_output == OUTPUT_JSON_PRETTY || + arg_output == OUTPUT_JSON_SSE || + arg_output == OUTPUT_CAT) + arg_quiet = true; + + break; + + case ARG_FULL: + arg_full = true; + break; + + case 'a': + arg_all = true; + break; + + case 'n': + if (optarg) { + r = safe_atou(optarg, &arg_lines); + if (r < 0 || arg_lines <= 0) { + log_error("Failed to parse lines '%s'", optarg); + return -EINVAL; + } + } else + arg_lines = 10; + + break; + + case ARG_NO_TAIL: + arg_no_tail = true; + break; + + case ARG_NEW_ID128: + arg_action = ACTION_NEW_ID128; + break; + + case 'q': + arg_quiet = true; + break; + + case 'm': + arg_merge = true; + break; + + case 'b': + arg_this_boot = true; + break; + + case 'D': + arg_directory = optarg; + break; + + case 'c': + arg_cursor = optarg; + break; + + case ARG_HEADER: + arg_action = ACTION_PRINT_HEADER; + break; + + case ARG_VERIFY: + arg_action = ACTION_VERIFY; + break; + + case ARG_DISK_USAGE: + arg_action = ACTION_DISK_USAGE; + break; + +#ifdef HAVE_GCRYPT + case ARG_SETUP_KEYS: + arg_action = ACTION_SETUP_KEYS; + break; + + + case ARG_VERIFY_KEY: + arg_action = ACTION_VERIFY; + arg_verify_key = optarg; + arg_merge = false; + break; + + case ARG_INTERVAL: + r = parse_usec(optarg, &arg_interval); + if (r < 0 || arg_interval <= 0) { + log_error("Failed to parse sealing key change interval: %s", optarg); + return -EINVAL; + } + break; +#else + case ARG_SETUP_KEYS: + case ARG_VERIFY_KEY: + case ARG_INTERVAL: + log_error("Forward-secure sealing not available."); + return -ENOTSUP; +#endif + + case 'p': { + const char *dots; + + dots = strstr(optarg, ".."); + if (dots) { + char *a; + int from, to, i; + + /* a range */ + a = strndup(optarg, dots - optarg); + if (!a) + return log_oom(); + + from = log_level_from_string(a); + to = log_level_from_string(dots + 2); + free(a); + + if (from < 0 || to < 0) { + log_error("Failed to parse log level range %s", optarg); + return -EINVAL; + } + + arg_priorities = 0; + + if (from < to) { + for (i = from; i <= to; i++) + arg_priorities |= 1 << i; + } else { + for (i = to; i <= from; i++) + arg_priorities |= 1 << i; + } + + } else { + int p, i; + + p = log_level_from_string(optarg); + if (p < 0) { + log_error("Unknown log level %s", optarg); + return -EINVAL; + } + + arg_priorities = 0; + + for (i = 0; i <= p; i++) + arg_priorities |= 1 << i; + } + + break; + } + + case ARG_SINCE: + r = parse_timestamp(optarg, &arg_since); + if (r < 0) { + log_error("Failed to parse timestamp: %s", optarg); + return -EINVAL; + } + arg_since_set = true; + break; + + case ARG_UNTIL: + r = parse_timestamp(optarg, &arg_until); + if (r < 0) { + log_error("Failed to parse timestamp: %s", optarg); + return -EINVAL; + } + arg_until_set = true; + break; + + case 'u': + arg_unit = optarg; + break; + + case '?': + return -EINVAL; + + case 'F': + arg_field = optarg; + break; + + case 'x': + arg_catalog = true; + break; + + case ARG_LIST_CATALOG: + arg_action = ACTION_LIST_CATALOG; + break; + + case ARG_UPDATE_CATALOG: + arg_action = ACTION_UPDATE_CATALOG; + break; + + default: + log_error("Unknown option code %c", c); + return -EINVAL; + } + } + + if (arg_follow && !arg_no_tail && arg_lines <= 0) + arg_lines = 10; + + if (arg_since_set && arg_until_set && arg_since_set > arg_until_set) { + log_error("--since= must be before --until=."); + return -EINVAL; + } + + if (arg_cursor && arg_since_set) { + log_error("Please specify either --since= or --cursor=, not both."); + return -EINVAL; + } + + return 1; +} + +static int generate_new_id128(void) { + sd_id128_t id; + int r; + unsigned i; + + r = sd_id128_randomize(&id); + if (r < 0) { + log_error("Failed to generate ID: %s", strerror(-r)); + return r; + } + + printf("As string:\n" + SD_ID128_FORMAT_STR "\n\n" + "As UUID:\n" + "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n\n" + "As macro:\n" + "#define MESSAGE_XYZ SD_ID128_MAKE(", + SD_ID128_FORMAT_VAL(id), + SD_ID128_FORMAT_VAL(id)); + + for (i = 0; i < 16; i++) + printf("%02x%s", id.bytes[i], i != 15 ? "," : ""); + + fputs(")\n", stdout); + + return 0; +} + +static int add_matches(sd_journal *j, char **args) { + char **i; + int r; + + assert(j); + + STRV_FOREACH(i, args) { + + if (streq(*i, "+")) + r = sd_journal_add_disjunction(j); + else if (path_is_absolute(*i)) { + char *p, *t = NULL; + const char *path; + struct stat st; + + p = canonicalize_file_name(*i); + path = p ? p : *i; + + if (stat(path, &st) < 0) { + free(p); + log_error("Couldn't stat file: %m"); + return -errno; + } + + if (S_ISREG(st.st_mode) && (0111 & st.st_mode)) + t = strappend("_EXE=", path); + else if (S_ISCHR(st.st_mode)) + asprintf(&t, "_KERNEL_DEVICE=c%u:%u", major(st.st_rdev), minor(st.st_rdev)); + else if (S_ISBLK(st.st_mode)) + asprintf(&t, "_KERNEL_DEVICE=b%u:%u", major(st.st_rdev), minor(st.st_rdev)); + else { + free(p); + log_error("File is not a device node, regular file or is not executable: %s", *i); + return -EINVAL; + } + + free(p); + + if (!t) + return log_oom(); + + r = sd_journal_add_match(j, t, 0); + free(t); + } else + r = sd_journal_add_match(j, *i, 0); + + if (r < 0) { + log_error("Failed to add match '%s': %s", *i, strerror(-r)); + return r; + } + } + + return 0; +} + +static int add_this_boot(sd_journal *j) { + char match[9+32+1] = "_BOOT_ID="; + sd_id128_t boot_id; + int r; + + assert(j); + + if (!arg_this_boot) + return 0; + + r = sd_id128_get_boot(&boot_id); + if (r < 0) { + log_error("Failed to get boot id: %s", strerror(-r)); + return r; + } + + sd_id128_to_string(boot_id, match + 9); + r = sd_journal_add_match(j, match, strlen(match)); + if (r < 0) { + log_error("Failed to add match: %s", strerror(-r)); + return r; + } + + return 0; +} + +static int add_unit(sd_journal *j) { + _cleanup_free_ char *m = NULL, *u = NULL; + int r; + + assert(j); + + if (isempty(arg_unit)) + return 0; + + u = unit_name_mangle(arg_unit); + if (!u) + return log_oom(); + + m = strappend("_SYSTEMD_UNIT=", u); + if (!m) + return log_oom(); + + r = sd_journal_add_match(j, m, strlen(m)); + if (r < 0) { + log_error("Failed to add match: %s", strerror(-r)); + return r; + } + + return 0; +} + +static int add_priorities(sd_journal *j) { + char match[] = "PRIORITY=0"; + int i, r; + + assert(j); + + if (arg_priorities == 0xFF) + return 0; + + for (i = LOG_EMERG; i <= LOG_DEBUG; i++) + if (arg_priorities & (1 << i)) { + match[sizeof(match)-2] = '0' + i; + + r = sd_journal_add_match(j, match, strlen(match)); + if (r < 0) { + log_error("Failed to add match: %s", strerror(-r)); + return r; + } + } + + return 0; +} + +static int setup_keys(void) { +#ifdef HAVE_GCRYPT + size_t mpk_size, seed_size, state_size, i; + uint8_t *mpk, *seed, *state; + ssize_t l; + int fd = -1, r, attr = 0; + sd_id128_t machine, boot; + char *p = NULL, *k = NULL; + struct FSSHeader h; + uint64_t n; + + r = sd_id128_get_machine(&machine); + if (r < 0) { + log_error("Failed to get machine ID: %s", strerror(-r)); + return r; + } + + r = sd_id128_get_boot(&boot); + if (r < 0) { + log_error("Failed to get boot ID: %s", strerror(-r)); + return r; + } + + if (asprintf(&p, "/var/log/journal/" SD_ID128_FORMAT_STR "/fss", + SD_ID128_FORMAT_VAL(machine)) < 0) + return log_oom(); + + if (access(p, F_OK) >= 0) { + log_error("Sealing key file %s exists already.", p); + r = -EEXIST; + goto finish; + } + + if (asprintf(&k, "/var/log/journal/" SD_ID128_FORMAT_STR "/fss.tmp.XXXXXX", + SD_ID128_FORMAT_VAL(machine)) < 0) { + r = log_oom(); + goto finish; + } + + mpk_size = FSPRG_mskinbytes(FSPRG_RECOMMENDED_SECPAR); + mpk = alloca(mpk_size); + + seed_size = FSPRG_RECOMMENDED_SEEDLEN; + seed = alloca(seed_size); + + state_size = FSPRG_stateinbytes(FSPRG_RECOMMENDED_SECPAR); + state = alloca(state_size); + + fd = open("/dev/random", O_RDONLY|O_CLOEXEC|O_NOCTTY); + if (fd < 0) { + log_error("Failed to open /dev/random: %m"); + r = -errno; + goto finish; + } + + log_info("Generating seed..."); + l = loop_read(fd, seed, seed_size, true); + if (l < 0 || (size_t) l != seed_size) { + log_error("Failed to read random seed: %s", strerror(EIO)); + r = -EIO; + goto finish; + } + + log_info("Generating key pair..."); + FSPRG_GenMK(NULL, mpk, seed, seed_size, FSPRG_RECOMMENDED_SECPAR); + + log_info("Generating sealing key..."); + FSPRG_GenState0(state, mpk, seed, seed_size); + + assert(arg_interval > 0); + + n = now(CLOCK_REALTIME); + n /= arg_interval; + + close_nointr_nofail(fd); + fd = mkostemp(k, O_WRONLY|O_CLOEXEC|O_NOCTTY); + if (fd < 0) { + log_error("Failed to open %s: %m", k); + r = -errno; + goto finish; + } + + /* Enable secure remove, exclusion from dump, synchronous + * writing and in-place updating */ + if (ioctl(fd, FS_IOC_GETFLAGS, &attr) < 0) + log_warning("FS_IOC_GETFLAGS failed: %m"); + + attr |= FS_SECRM_FL|FS_NODUMP_FL|FS_SYNC_FL|FS_NOCOW_FL; + + if (ioctl(fd, FS_IOC_SETFLAGS, &attr) < 0) + log_warning("FS_IOC_SETFLAGS failed: %m"); + + zero(h); + memcpy(h.signature, "KSHHRHLP", 8); + h.machine_id = machine; + h.boot_id = boot; + h.header_size = htole64(sizeof(h)); + h.start_usec = htole64(n * arg_interval); + h.interval_usec = htole64(arg_interval); + h.fsprg_secpar = htole16(FSPRG_RECOMMENDED_SECPAR); + h.fsprg_state_size = htole64(state_size); + + l = loop_write(fd, &h, sizeof(h), false); + if (l < 0 || (size_t) l != sizeof(h)) { + log_error("Failed to write header: %s", strerror(EIO)); + r = -EIO; + goto finish; + } + + l = loop_write(fd, state, state_size, false); + if (l < 0 || (size_t) l != state_size) { + log_error("Failed to write state: %s", strerror(EIO)); + r = -EIO; + goto finish; + } + + if (link(k, p) < 0) { + log_error("Failed to link file: %m"); + r = -errno; + goto finish; + } + + if (on_tty()) { + fprintf(stderr, + "\n" + "The new key pair has been generated. The " ANSI_HIGHLIGHT_ON "secret sealing key" ANSI_HIGHLIGHT_OFF " has been written to\n" + "the following local file. This key file is automatically updated when the\n" + "sealing key is advanced. It should not be used on multiple hosts.\n" + "\n" + "\t%s\n" + "\n" + "Please write down the following " ANSI_HIGHLIGHT_ON "secret verification key" ANSI_HIGHLIGHT_OFF ". It should be stored\n" + "at a safe location and should not be saved locally on disk.\n" + "\n\t" ANSI_HIGHLIGHT_RED_ON, p); + fflush(stderr); + } + for (i = 0; i < seed_size; i++) { + if (i > 0 && i % 3 == 0) + putchar('-'); + printf("%02x", ((uint8_t*) seed)[i]); + } + + printf("/%llx-%llx\n", (unsigned long long) n, (unsigned long long) arg_interval); + + if (on_tty()) { + char tsb[FORMAT_TIMESPAN_MAX], *hn; + + fprintf(stderr, + ANSI_HIGHLIGHT_OFF "\n" + "The sealing key is automatically changed every %s.\n", + format_timespan(tsb, sizeof(tsb), arg_interval)); + + hn = gethostname_malloc(); + + if (hn) { + hostname_cleanup(hn); + fprintf(stderr, "\nThe keys have been generated for host %s/" SD_ID128_FORMAT_STR ".\n", hn, SD_ID128_FORMAT_VAL(machine)); + } else + fprintf(stderr, "\nThe keys have been generated for host " SD_ID128_FORMAT_STR ".\n", SD_ID128_FORMAT_VAL(machine)); + +#ifdef HAVE_QRENCODE + /* If this is not an UTF-8 system don't print any QR codes */ + if (is_locale_utf8()) { + fputs("\nTo transfer the verification key to your phone please scan the QR code below:\n\n", stderr); + print_qr_code(stderr, seed, seed_size, n, arg_interval, hn, machine); + } +#endif + free(hn); + } + + r = 0; + +finish: + if (fd >= 0) + close_nointr_nofail(fd); + + if (k) { + unlink(k); + free(k); + } + + free(p); + + return r; +#else + log_error("Forward-secure sealing not available."); + return -ENOTSUP; +#endif +} + +static int verify(sd_journal *j) { + int r = 0; + Iterator i; + JournalFile *f; + + assert(j); + + log_show_color(true); + + HASHMAP_FOREACH(f, j->files, i) { + int k; + usec_t first, validated, last; + +#ifdef HAVE_GCRYPT + if (!arg_verify_key && JOURNAL_HEADER_SEALED(f->header)) + log_notice("Journal file %s has sealing enabled but verification key has not been passed using --verify-key=.", f->path); +#endif + + k = journal_file_verify(f, arg_verify_key, &first, &validated, &last, true); + if (k == -EINVAL) { + /* If the key was invalid give up right-away. */ + return k; + } else if (k < 0) { + log_warning("FAIL: %s (%s)", f->path, strerror(-k)); + r = k; + } else { + char a[FORMAT_TIMESTAMP_MAX], b[FORMAT_TIMESTAMP_MAX], c[FORMAT_TIMESPAN_MAX]; + log_info("PASS: %s", f->path); + + if (arg_verify_key && JOURNAL_HEADER_SEALED(f->header)) { + if (validated > 0) { + log_info("=> Validated from %s to %s, final %s entries not sealed.", + format_timestamp(a, sizeof(a), first), + format_timestamp(b, sizeof(b), validated), + format_timespan(c, sizeof(c), last > validated ? last - validated : 0)); + } else if (last > 0) + log_info("=> No sealing yet, %s of entries not sealed.", + format_timespan(c, sizeof(c), last - first)); + else + log_info("=> No sealing yet, no entries in file."); + } + } + } + + return r; +} + +static int access_check(void) { + +#ifdef HAVE_ACL + if (access("/var/log/journal", F_OK) < 0 && geteuid() != 0 && in_group("adm") <= 0) { + log_error("Unprivileged users can't see messages unless persistent log storage is enabled. Users in the group 'adm' can always see messages."); + return -EACCES; + } + + if (!arg_quiet && geteuid() != 0 && in_group("adm") <= 0) + log_warning("Showing user generated messages only. Users in the group 'adm' can see all messages. Pass -q to turn this notice off."); +#else + if (geteuid() != 0 && in_group("adm") <= 0) { + log_error("No access to messages. Only users in the group 'adm' can see messages."); + return -EACCES; + } +#endif + + return 0; +} + +int main(int argc, char *argv[]) { + int r; + sd_journal *j = NULL; + bool need_seek = false; + sd_id128_t previous_boot_id; + bool previous_boot_id_valid = false; + unsigned n_shown = 0; + + setlocale(LC_ALL, ""); + log_parse_environment(); + log_open(); + + r = parse_argv(argc, argv); + if (r <= 0) + goto finish; + + signal(SIGWINCH, columns_lines_cache_reset); + + if (arg_action == ACTION_NEW_ID128) { + r = generate_new_id128(); + goto finish; + } + + if (arg_action == ACTION_SETUP_KEYS) { + r = setup_keys(); + goto finish; + } + + if (arg_action == ACTION_LIST_CATALOG) { + r = catalog_list(stdout); + if (r < 0) + log_error("Failed to list catalog: %s", strerror(-r)); + goto finish; + } + + if (arg_action == ACTION_UPDATE_CATALOG) { + r = catalog_update(); + goto finish; + } + + r = access_check(); + if (r < 0) + goto finish; + + if (arg_directory) + r = sd_journal_open_directory(&j, arg_directory, 0); + else + r = sd_journal_open(&j, arg_merge ? 0 : SD_JOURNAL_LOCAL_ONLY); + if (r < 0) { + log_error("Failed to open journal: %s", strerror(-r)); + goto finish; + } + + if (arg_action == ACTION_VERIFY) { + r = verify(j); + goto finish; + } + + if (arg_action == ACTION_PRINT_HEADER) { + journal_print_header(j); + r = 0; + goto finish; + } + + if (arg_action == ACTION_DISK_USAGE) { + uint64_t bytes; + char sbytes[FORMAT_BYTES_MAX]; + + r = sd_journal_get_usage(j, &bytes); + if (r < 0) + goto finish; + + printf("Journals take up %s on disk.\n", format_bytes(sbytes, sizeof(sbytes), bytes)); + r = 0; + goto finish; + } + + r = add_this_boot(j); + if (r < 0) + goto finish; + + r = add_unit(j); + if (r < 0) + goto finish; + + r = add_matches(j, argv + optind); + if (r < 0) + goto finish; + + r = add_priorities(j); + if (r < 0) + goto finish; + + if (arg_field) { + const void *data; + size_t size; + + r = sd_journal_query_unique(j, arg_field); + if (r < 0) { + log_error("Failed to query unique data objects: %s", strerror(-r)); + goto finish; + } + + SD_JOURNAL_FOREACH_UNIQUE(j, data, size) { + const void *eq; + + if (arg_lines > 0 && n_shown >= arg_lines) + break; + + eq = memchr(data, '=', size); + if (eq) + printf("%.*s\n", (int) (size - ((const uint8_t*) eq - (const uint8_t*) data + 1)), (const char*) eq + 1); + else + printf("%.*s\n", (int) size, (const char*) data); + + n_shown ++; + } + + r = 0; + goto finish; + } + + if (arg_cursor) { + r = sd_journal_seek_cursor(j, arg_cursor); + if (r < 0) { + log_error("Failed to seek to cursor: %s", strerror(-r)); + goto finish; + } + + r = sd_journal_next(j); + + } else if (arg_since_set) { + r = sd_journal_seek_realtime_usec(j, arg_since); + if (r < 0) { + log_error("Failed to seek to date: %s", strerror(-r)); + goto finish; + } + r = sd_journal_next(j); + + } else if (arg_lines > 0) { + r = sd_journal_seek_tail(j); + if (r < 0) { + log_error("Failed to seek to tail: %s", strerror(-r)); + goto finish; + } + + r = sd_journal_previous_skip(j, arg_lines); + + } else { + r = sd_journal_seek_head(j); + if (r < 0) { + log_error("Failed to seek to head: %s", strerror(-r)); + goto finish; + } + + r = sd_journal_next(j); + } + + if (r < 0) { + log_error("Failed to iterate through journal: %s", strerror(-r)); + goto finish; + } + + if (!arg_no_pager && !arg_follow) + pager_open(); + + if (!arg_quiet) { + usec_t start, end; + char start_buf[FORMAT_TIMESTAMP_MAX], end_buf[FORMAT_TIMESTAMP_MAX]; + + r = sd_journal_get_cutoff_realtime_usec(j, &start, &end); + if (r < 0) { + log_error("Failed to get cutoff: %s", strerror(-r)); + goto finish; + } + + if (r > 0) { + if (arg_follow) + printf("-- Logs begin at %s. --\n", + format_timestamp(start_buf, sizeof(start_buf), start)); + else + printf("-- Logs begin at %s, end at %s. --\n", + format_timestamp(start_buf, sizeof(start_buf), start), + format_timestamp(end_buf, sizeof(end_buf), end)); + } + } + + for (;;) { + while (arg_lines == 0 || arg_follow || n_shown < arg_lines) { + int flags; + + if (need_seek) { + r = sd_journal_next(j); + if (r < 0) { + log_error("Failed to iterate through journal: %s", strerror(-r)); + goto finish; + } + } + + if (r == 0) + break; + + if (arg_until_set) { + usec_t usec; + + r = sd_journal_get_realtime_usec(j, &usec); + if (r < 0) { + log_error("Failed to determine timestamp: %s", strerror(-r)); + goto finish; + } + } + + if (!arg_merge) { + sd_id128_t boot_id; + + r = sd_journal_get_monotonic_usec(j, NULL, &boot_id); + if (r >= 0) { + if (previous_boot_id_valid && + !sd_id128_equal(boot_id, previous_boot_id)) + printf(ANSI_HIGHLIGHT_ON "-- Reboot --" ANSI_HIGHLIGHT_OFF "\n"); + + previous_boot_id = boot_id; + previous_boot_id_valid = true; + } + } + + flags = + arg_all * OUTPUT_SHOW_ALL | + (arg_full || !on_tty() || pager_have()) * OUTPUT_FULL_WIDTH | + on_tty() * OUTPUT_COLOR | + arg_catalog * OUTPUT_CATALOG; + + r = output_journal(stdout, j, arg_output, 0, flags); + if (r < 0) + goto finish; + + need_seek = true; + n_shown++; + } + + if (!arg_follow) + break; + + r = sd_journal_wait(j, (uint64_t) -1); + if (r < 0) { + log_error("Couldn't wait for journal event: %s", strerror(-r)); + goto finish; + } + } + +finish: + if (j) + sd_journal_close(j); + + pager_close(); + + return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/src/journal/journald-console.c b/src/journal/journald-console.c new file mode 100644 index 000000000..be55f9487 --- /dev/null +++ b/src/journal/journald-console.c @@ -0,0 +1,86 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +#include +#include +#include + +#include "journald-server.h" +#include "journald-console.h" + +void server_forward_console( + Server *s, + int priority, + const char *identifier, + const char *message, + struct ucred *ucred) { + + struct iovec iovec[4]; + char header_pid[16]; + int n = 0, fd; + char *ident_buf = NULL; + const char *tty; + + assert(s); + assert(message); + + if (LOG_PRI(priority) > s->max_level_console) + return; + + /* First: identifier and PID */ + if (ucred) { + if (!identifier) { + get_process_comm(ucred->pid, &ident_buf); + identifier = ident_buf; + } + + snprintf(header_pid, sizeof(header_pid), "[%lu]: ", (unsigned long) ucred->pid); + char_array_0(header_pid); + + if (identifier) + IOVEC_SET_STRING(iovec[n++], identifier); + + IOVEC_SET_STRING(iovec[n++], header_pid); + } else if (identifier) { + IOVEC_SET_STRING(iovec[n++], identifier); + IOVEC_SET_STRING(iovec[n++], ": "); + } + + /* Third: message */ + IOVEC_SET_STRING(iovec[n++], message); + IOVEC_SET_STRING(iovec[n++], "\n"); + + tty = s->tty_path ? s->tty_path : "/dev/console"; + + fd = open_terminal(tty, O_WRONLY|O_NOCTTY|O_CLOEXEC); + if (fd < 0) { + log_debug("Failed to open %s for logging: %s", tty, strerror(errno)); + goto finish; + } + + if (writev(fd, iovec, n) < 0) + log_debug("Failed to write to %s for logging: %s", tty, strerror(errno)); + + close_nointr_nofail(fd); + +finish: + free(ident_buf); +} diff --git a/src/journal/journald-console.h b/src/journal/journald-console.h new file mode 100644 index 000000000..aa8e6579b --- /dev/null +++ b/src/journal/journald-console.h @@ -0,0 +1,26 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +#include "journald-server.h" + +void server_forward_console(Server *s, int priority, const char *identifier, const char *message, struct ucred *ucred); diff --git a/src/journal/journald-gperf.gperf b/src/journal/journald-gperf.gperf new file mode 100644 index 000000000..1baef1411 --- /dev/null +++ b/src/journal/journald-gperf.gperf @@ -0,0 +1,39 @@ +%{ +#include +#include +#include "conf-parser.h" +#include "journald-server.h" +%} +struct ConfigPerfItem; +%null_strings +%language=ANSI-C +%define slot-name section_and_lvalue +%define hash-function-name journald_gperf_hash +%define lookup-function-name journald_gperf_lookup +%readonly-tables +%omit-struct-type +%struct-type +%includes +%% +Journal.Storage, config_parse_storage, 0, offsetof(Server, storage) +Journal.Compress, config_parse_bool, 0, offsetof(Server, compress) +Journal.Seal, config_parse_bool, 0, offsetof(Server, seal) +Journal.RateLimitInterval, config_parse_usec, 0, offsetof(Server, rate_limit_interval) +Journal.RateLimitBurst, config_parse_unsigned, 0, offsetof(Server, rate_limit_burst) +Journal.SystemMaxUse, config_parse_bytes_off, 0, offsetof(Server, system_metrics.max_use) +Journal.SystemMaxFileSize, config_parse_bytes_off, 0, offsetof(Server, system_metrics.max_size) +Journal.SystemKeepFree, config_parse_bytes_off, 0, offsetof(Server, system_metrics.keep_free) +Journal.RuntimeMaxUse, config_parse_bytes_off, 0, offsetof(Server, runtime_metrics.max_use) +Journal.RuntimeMaxFileSize, config_parse_bytes_off, 0, offsetof(Server, runtime_metrics.max_size) +Journal.RuntimeKeepFree, config_parse_bytes_off, 0, offsetof(Server, runtime_metrics.keep_free) +Journal.MaxRetentionSec, config_parse_usec, 0, offsetof(Server, max_retention_usec) +Journal.MaxFileSec, config_parse_usec, 0, offsetof(Server, max_file_usec) +Journal.ForwardToSyslog, config_parse_bool, 0, offsetof(Server, forward_to_syslog) +Journal.ForwardToKMsg, config_parse_bool, 0, offsetof(Server, forward_to_kmsg) +Journal.ForwardToConsole, config_parse_bool, 0, offsetof(Server, forward_to_console) +Journal.TTYPath, config_parse_path, 0, offsetof(Server, tty_path) +Journal.MaxLevelStore, config_parse_level, 0, offsetof(Server, max_level_store) +Journal.MaxLevelSyslog, config_parse_level, 0, offsetof(Server, max_level_syslog) +Journal.MaxLevelKMsg, config_parse_level, 0, offsetof(Server, max_level_kmsg) +Journal.MaxLevelConsole, config_parse_level, 0, offsetof(Server, max_level_console) +Journal.SplitMode, config_parse_split_mode,0, offsetof(Server, split_mode) diff --git a/src/journal/journald-kmsg.c b/src/journal/journald-kmsg.c new file mode 100644 index 000000000..b8198760d --- /dev/null +++ b/src/journal/journald-kmsg.c @@ -0,0 +1,438 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +#include +#include +#include +#include +#include + +#include +#include + +#include "journald-server.h" +#include "journald-kmsg.h" +#include "journald-syslog.h" + +void server_forward_kmsg( + Server *s, + int priority, + const char *identifier, + const char *message, + struct ucred *ucred) { + + struct iovec iovec[5]; + char header_priority[6], header_pid[16]; + int n = 0; + char *ident_buf = NULL; + + assert(s); + assert(priority >= 0); + assert(priority <= 999); + assert(message); + + if (_unlikely_(LOG_PRI(priority) > s->max_level_kmsg)) + return; + + if (_unlikely_(s->dev_kmsg_fd < 0)) + return; + + /* Never allow messages with kernel facility to be written to + * kmsg, regardless where the data comes from. */ + priority = syslog_fixup_facility(priority); + + /* First: priority field */ + snprintf(header_priority, sizeof(header_priority), "<%i>", priority); + char_array_0(header_priority); + IOVEC_SET_STRING(iovec[n++], header_priority); + + /* Second: identifier and PID */ + if (ucred) { + if (!identifier) { + get_process_comm(ucred->pid, &ident_buf); + identifier = ident_buf; + } + + snprintf(header_pid, sizeof(header_pid), "[%lu]: ", (unsigned long) ucred->pid); + char_array_0(header_pid); + + if (identifier) + IOVEC_SET_STRING(iovec[n++], identifier); + + IOVEC_SET_STRING(iovec[n++], header_pid); + } else if (identifier) { + IOVEC_SET_STRING(iovec[n++], identifier); + IOVEC_SET_STRING(iovec[n++], ": "); + } + + /* Fourth: message */ + IOVEC_SET_STRING(iovec[n++], message); + IOVEC_SET_STRING(iovec[n++], "\n"); + + if (writev(s->dev_kmsg_fd, iovec, n) < 0) + log_debug("Failed to write to /dev/kmsg for logging: %s", strerror(errno)); + + free(ident_buf); +} + +static bool is_us(const char *pid) { + pid_t t; + + assert(pid); + + if (parse_pid(pid, &t) < 0) + return false; + + return t == getpid(); +} + +static void dev_kmsg_record(Server *s, char *p, size_t l) { + struct iovec iovec[N_IOVEC_META_FIELDS + 7 + N_IOVEC_KERNEL_FIELDS + 2 + N_IOVEC_UDEV_FIELDS]; + char *message = NULL, *syslog_priority = NULL, *syslog_pid = NULL, *syslog_facility = NULL, *syslog_identifier = NULL, *source_time = NULL; + int priority, r; + unsigned n = 0, z = 0, j; + unsigned long long usec; + char *identifier = NULL, *pid = NULL, *e, *f, *k; + uint64_t serial; + size_t pl; + char *kernel_device = NULL; + + assert(s); + assert(p); + + if (l <= 0) + return; + + e = memchr(p, ',', l); + if (!e) + return; + *e = 0; + + r = safe_atoi(p, &priority); + if (r < 0 || priority < 0 || priority > 999) + return; + + if (s->forward_to_kmsg && (priority & LOG_FACMASK) != LOG_KERN) + return; + + l -= (e - p) + 1; + p = e + 1; + e = memchr(p, ',', l); + if (!e) + return; + *e = 0; + + r = safe_atou64(p, &serial); + if (r < 0) + return; + + if (s->kernel_seqnum) { + /* We already read this one? */ + if (serial < *s->kernel_seqnum) + return; + + /* Did we lose any? */ + if (serial > *s->kernel_seqnum) + server_driver_message(s, SD_MESSAGE_JOURNAL_MISSED, "Missed %llu kernel messages", (unsigned long long) serial - *s->kernel_seqnum - 1); + + /* Make sure we never read this one again. Note that + * we always store the next message serial we expect + * here, simply because this makes handling the first + * message with serial 0 easy. */ + *s->kernel_seqnum = serial + 1; + } + + l -= (e - p) + 1; + p = e + 1; + f = memchr(p, ';', l); + if (!f) + return; + /* Kernel 3.6 has the flags field, kernel 3.5 lacks that */ + e = memchr(p, ',', l); + if (!e || f < e) + e = f; + *e = 0; + + r = safe_atollu(p, &usec); + if (r < 0) + return; + + l -= (f - p) + 1; + p = f + 1; + e = memchr(p, '\n', l); + if (!e) + return; + *e = 0; + + pl = e - p; + l -= (e - p) + 1; + k = e + 1; + + for (j = 0; l > 0 && j < N_IOVEC_KERNEL_FIELDS; j++) { + char *m; + /* Meta data fields attached */ + + if (*k != ' ') + break; + + k ++, l --; + + e = memchr(k, '\n', l); + if (!e) + return; + + *e = 0; + + m = cunescape_length_with_prefix(k, e - k, "_KERNEL_"); + if (!m) + break; + + if (startswith(m, "_KERNEL_DEVICE=")) + kernel_device = m + 15; + + IOVEC_SET_STRING(iovec[n++], m); + z++; + + l -= (e - k) + 1; + k = e + 1; + } + + if (kernel_device) { + struct udev_device *ud; + + ud = udev_device_new_from_device_id(s->udev, kernel_device); + if (ud) { + const char *g; + struct udev_list_entry *ll; + char *b; + + g = udev_device_get_devnode(ud); + if (g) { + b = strappend("_UDEV_DEVNODE=", g); + if (b) { + IOVEC_SET_STRING(iovec[n++], b); + z++; + } + } + + g = udev_device_get_sysname(ud); + if (g) { + b = strappend("_UDEV_SYSNAME=", g); + if (b) { + IOVEC_SET_STRING(iovec[n++], b); + z++; + } + } + + j = 0; + ll = udev_device_get_devlinks_list_entry(ud); + udev_list_entry_foreach(ll, ll) { + + if (j > N_IOVEC_UDEV_FIELDS) + break; + + g = udev_list_entry_get_name(ll); + b = strappend("_UDEV_DEVLINK=", g); + if (g) { + IOVEC_SET_STRING(iovec[n++], b); + z++; + } + + j++; + } + + udev_device_unref(ud); + } + } + + if (asprintf(&source_time, "_SOURCE_MONOTONIC_TIMESTAMP=%llu", usec) >= 0) + IOVEC_SET_STRING(iovec[n++], source_time); + + IOVEC_SET_STRING(iovec[n++], "_TRANSPORT=kernel"); + + if (asprintf(&syslog_priority, "PRIORITY=%i", priority & LOG_PRIMASK) >= 0) + IOVEC_SET_STRING(iovec[n++], syslog_priority); + + if ((priority & LOG_FACMASK) == LOG_KERN) + IOVEC_SET_STRING(iovec[n++], "SYSLOG_IDENTIFIER=kernel"); + else { + pl -= syslog_parse_identifier((const char**) &p, &identifier, &pid); + + /* Avoid any messages we generated ourselves via + * log_info() and friends. */ + if (pid && is_us(pid)) + goto finish; + + if (identifier) { + syslog_identifier = strappend("SYSLOG_IDENTIFIER=", identifier); + if (syslog_identifier) + IOVEC_SET_STRING(iovec[n++], syslog_identifier); + } + + if (pid) { + syslog_pid = strappend("SYSLOG_PID=", pid); + if (syslog_pid) + IOVEC_SET_STRING(iovec[n++], syslog_pid); + } + + if (asprintf(&syslog_facility, "SYSLOG_FACILITY=%i", LOG_FAC(priority)) >= 0) + IOVEC_SET_STRING(iovec[n++], syslog_facility); + } + + message = cunescape_length_with_prefix(p, pl, "MESSAGE="); + if (message) + IOVEC_SET_STRING(iovec[n++], message); + + server_dispatch_message(s, iovec, n, ELEMENTSOF(iovec), NULL, NULL, NULL, 0, NULL, priority); + +finish: + for (j = 0; j < z; j++) + free(iovec[j].iov_base); + + free(message); + free(syslog_priority); + free(syslog_identifier); + free(syslog_pid); + free(syslog_facility); + free(source_time); + free(identifier); + free(pid); +} + +int server_read_dev_kmsg(Server *s) { + char buffer[8192+1]; /* the kernel-side limit per record is 8K currently */ + ssize_t l; + + assert(s); + assert(s->dev_kmsg_fd >= 0); + + l = read(s->dev_kmsg_fd, buffer, sizeof(buffer) - 1); + if (l == 0) + return 0; + if (l < 0) { + /* Old kernels who don't allow reading from /dev/kmsg + * return EINVAL when we try. So handle this cleanly, + * but don' try to ever read from it again. */ + if (errno == EINVAL) { + epoll_ctl(s->epoll_fd, EPOLL_CTL_DEL, s->dev_kmsg_fd, NULL); + return 0; + } + + if (errno == EAGAIN || errno == EINTR || errno == EPIPE) + return 0; + + log_error("Failed to read from kernel: %m"); + return -errno; + } + + dev_kmsg_record(s, buffer, l); + return 1; +} + +int server_flush_dev_kmsg(Server *s) { + int r; + + assert(s); + + if (s->dev_kmsg_fd < 0) + return 0; + + if (!s->dev_kmsg_readable) + return 0; + + log_debug("Flushing /dev/kmsg..."); + + for (;;) { + r = server_read_dev_kmsg(s); + if (r < 0) + return r; + + if (r == 0) + break; + } + + return 0; +} + +int server_open_dev_kmsg(Server *s) { + struct epoll_event ev; + + assert(s); + + s->dev_kmsg_fd = open("/dev/kmsg", O_RDWR|O_CLOEXEC|O_NONBLOCK|O_NOCTTY); + if (s->dev_kmsg_fd < 0) { + log_warning("Failed to open /dev/kmsg, ignoring: %m"); + return 0; + } + + zero(ev); + ev.events = EPOLLIN; + ev.data.fd = s->dev_kmsg_fd; + if (epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, s->dev_kmsg_fd, &ev) < 0) { + + /* This will fail with EPERM on older kernels where + * /dev/kmsg is not readable. */ + if (errno == EPERM) + return 0; + + log_error("Failed to add /dev/kmsg fd to epoll object: %m"); + return -errno; + } + + s->dev_kmsg_readable = true; + + return 0; +} + +int server_open_kernel_seqnum(Server *s) { + int fd; + uint64_t *p; + + assert(s); + + /* We store the seqnum we last read in an mmaped file. That + * way we can just use it like a variable, but it is + * persistent and automatically flushed at reboot. */ + + fd = open("/run/systemd/journal/kernel-seqnum", O_RDWR|O_CREAT|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW, 0644); + if (fd < 0) { + log_error("Failed to open /run/systemd/journal/kernel-seqnum, ignoring: %m"); + return 0; + } + + if (posix_fallocate(fd, 0, sizeof(uint64_t)) < 0) { + log_error("Failed to allocate sequential number file, ignoring: %m"); + close_nointr_nofail(fd); + return 0; + } + + p = mmap(NULL, sizeof(uint64_t), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); + if (p == MAP_FAILED) { + log_error("Failed to map sequential number file, ignoring: %m"); + close_nointr_nofail(fd); + return 0; + } + + close_nointr_nofail(fd); + s->kernel_seqnum = p; + + return 0; +} diff --git a/src/journal/journald-kmsg.h b/src/journal/journald-kmsg.h new file mode 100644 index 000000000..f28716132 --- /dev/null +++ b/src/journal/journald-kmsg.h @@ -0,0 +1,32 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +#include "journald-server.h" + +int server_open_dev_kmsg(Server *s); +int server_read_dev_kmsg(Server *s); +int server_flush_dev_kmsg(Server *s); + +void server_forward_kmsg(Server *s, int priority, const char *identifier, const char *message, struct ucred *ucred); + +int server_open_kernel_seqnum(Server *s); diff --git a/src/journal/journald-native.c b/src/journal/journald-native.c new file mode 100644 index 000000000..069114778 --- /dev/null +++ b/src/journal/journald-native.c @@ -0,0 +1,420 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +#include +#include +#include + +#include "socket-util.h" +#include "path-util.h" +#include "journald-server.h" +#include "journald-native.h" +#include "journald-kmsg.h" +#include "journald-console.h" +#include "journald-syslog.h" + +#define ENTRY_SIZE_MAX (1024*1024*64) +#define DATA_SIZE_MAX (1024*1024*64) + +static bool valid_user_field(const char *p, size_t l) { + const char *a; + + /* We kinda enforce POSIX syntax recommendations for + environment variables here, but make a couple of additional + requirements. + + http://pubs.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap08.html */ + + /* No empty field names */ + if (l <= 0) + return false; + + /* Don't allow names longer than 64 chars */ + if (l > 64) + return false; + + /* Variables starting with an underscore are protected */ + if (p[0] == '_') + return false; + + /* Don't allow digits as first character */ + if (p[0] >= '0' && p[0] <= '9') + return false; + + /* Only allow A-Z0-9 and '_' */ + for (a = p; a < p + l; a++) + if (!((*a >= 'A' && *a <= 'Z') || + (*a >= '0' && *a <= '9') || + *a == '_')) + return false; + + return true; +} + +void server_process_native_message( + Server *s, + const void *buffer, size_t buffer_size, + struct ucred *ucred, + struct timeval *tv, + const char *label, size_t label_len) { + + struct iovec *iovec = NULL; + unsigned n = 0, m = 0, j, tn = (unsigned) -1; + const char *p; + size_t remaining; + int priority = LOG_INFO; + char *identifier = NULL, *message = NULL; + + assert(s); + assert(buffer || buffer_size == 0); + + p = buffer; + remaining = buffer_size; + + while (remaining > 0) { + const char *e, *q; + + e = memchr(p, '\n', remaining); + + if (!e) { + /* Trailing noise, let's ignore it, and flush what we collected */ + log_debug("Received message with trailing noise, ignoring."); + break; + } + + if (e == p) { + /* Entry separator */ + server_dispatch_message(s, iovec, n, m, ucred, tv, label, label_len, NULL, priority); + n = 0; + priority = LOG_INFO; + + p++; + remaining--; + continue; + } + + if (*p == '.' || *p == '#') { + /* Ignore control commands for now, and + * comments too. */ + remaining -= (e - p) + 1; + p = e + 1; + continue; + } + + /* A property follows */ + + if (n+N_IOVEC_META_FIELDS >= m) { + struct iovec *c; + unsigned u; + + u = MAX((n+N_IOVEC_META_FIELDS+1) * 2U, 4U); + c = realloc(iovec, u * sizeof(struct iovec)); + if (!c) { + log_oom(); + break; + } + + iovec = c; + m = u; + } + + q = memchr(p, '=', e - p); + if (q) { + if (valid_user_field(p, q - p)) { + size_t l; + + l = e - p; + + /* If the field name starts with an + * underscore, skip the variable, + * since that indidates a trusted + * field */ + iovec[n].iov_base = (char*) p; + iovec[n].iov_len = l; + n++; + + /* We need to determine the priority + * of this entry for the rate limiting + * logic */ + if (l == 10 && + memcmp(p, "PRIORITY=", 9) == 0 && + p[9] >= '0' && p[9] <= '9') + priority = (priority & LOG_FACMASK) | (p[9] - '0'); + + else if (l == 17 && + memcmp(p, "SYSLOG_FACILITY=", 16) == 0 && + p[16] >= '0' && p[16] <= '9') + priority = (priority & LOG_PRIMASK) | ((p[16] - '0') << 3); + + else if (l == 18 && + memcmp(p, "SYSLOG_FACILITY=", 16) == 0 && + p[16] >= '0' && p[16] <= '9' && + p[17] >= '0' && p[17] <= '9') + priority = (priority & LOG_PRIMASK) | (((p[16] - '0')*10 + (p[17] - '0')) << 3); + + else if (l >= 19 && + memcmp(p, "SYSLOG_IDENTIFIER=", 18) == 0) { + char *t; + + t = strndup(p + 18, l - 18); + if (t) { + free(identifier); + identifier = t; + } + } else if (l >= 8 && + memcmp(p, "MESSAGE=", 8) == 0) { + char *t; + + t = strndup(p + 8, l - 8); + if (t) { + free(message); + message = t; + } + } + } + + remaining -= (e - p) + 1; + p = e + 1; + continue; + } else { + le64_t l_le; + uint64_t l; + char *k; + + if (remaining < e - p + 1 + sizeof(uint64_t) + 1) { + log_debug("Failed to parse message, ignoring."); + break; + } + + memcpy(&l_le, e + 1, sizeof(uint64_t)); + l = le64toh(l_le); + + if (l > DATA_SIZE_MAX) { + log_debug("Received binary data block too large, ignoring."); + break; + } + + if ((uint64_t) remaining < e - p + 1 + sizeof(uint64_t) + l + 1 || + e[1+sizeof(uint64_t)+l] != '\n') { + log_debug("Failed to parse message, ignoring."); + break; + } + + k = malloc((e - p) + 1 + l); + if (!k) { + log_oom(); + break; + } + + memcpy(k, p, e - p); + k[e - p] = '='; + memcpy(k + (e - p) + 1, e + 1 + sizeof(uint64_t), l); + + if (valid_user_field(p, e - p)) { + iovec[n].iov_base = k; + iovec[n].iov_len = (e - p) + 1 + l; + n++; + } else + free(k); + + remaining -= (e - p) + 1 + sizeof(uint64_t) + l + 1; + p = e + 1 + sizeof(uint64_t) + l + 1; + } + } + + if (n <= 0) + goto finish; + + tn = n++; + IOVEC_SET_STRING(iovec[tn], "_TRANSPORT=journal"); + + if (message) { + if (s->forward_to_syslog) + server_forward_syslog(s, priority, identifier, message, ucred, tv); + + if (s->forward_to_kmsg) + server_forward_kmsg(s, priority, identifier, message, ucred); + + if (s->forward_to_console) + server_forward_console(s, priority, identifier, message, ucred); + } + + server_dispatch_message(s, iovec, n, m, ucred, tv, label, label_len, NULL, priority); + +finish: + for (j = 0; j < n; j++) { + if (j == tn) + continue; + + if (iovec[j].iov_base < buffer || + (const uint8_t*) iovec[j].iov_base >= (const uint8_t*) buffer + buffer_size) + free(iovec[j].iov_base); + } + + free(iovec); + free(identifier); + free(message); +} + +void server_process_native_file( + Server *s, + int fd, + struct ucred *ucred, + struct timeval *tv, + const char *label, size_t label_len) { + + struct stat st; + _cleanup_free_ void *p = NULL; + ssize_t n; + int r; + + assert(s); + assert(fd >= 0); + + if (!ucred || ucred->uid != 0) { + _cleanup_free_ char *sl = NULL, *k = NULL; + const char *e; + + if (asprintf(&sl, "/proc/self/fd/%i", fd) < 0) { + log_oom(); + return; + } + + r = readlink_malloc(sl, &k); + if (r < 0) { + log_error("readlink(%s) failed: %m", sl); + return; + } + + e = path_startswith(k, "/dev/shm/"); + if (!e) + e = path_startswith(k, "/tmp/"); + if (!e) + e = path_startswith(k, "/var/tmp/"); + if (!e) { + log_error("Received file outside of allowed directories. Refusing."); + return; + } + + if (!filename_is_safe(e)) { + log_error("Received file in subdirectory of allowed directories. Refusing."); + return; + } + } + + /* Data is in the passed file, since it didn't fit in a + * datagram. We can't map the file here, since clients might + * then truncate it and trigger a SIGBUS for us. So let's + * stupidly read it */ + + if (fstat(fd, &st) < 0) { + log_error("Failed to stat passed file, ignoring: %m"); + return; + } + + if (!S_ISREG(st.st_mode)) { + log_error("File passed is not regular. Ignoring."); + return; + } + + if (st.st_size <= 0) + return; + + if (st.st_size > ENTRY_SIZE_MAX) { + log_error("File passed too large. Ignoring."); + return; + } + + p = malloc(st.st_size); + if (!p) { + log_oom(); + return; + } + + n = pread(fd, p, st.st_size, 0); + if (n < 0) + log_error("Failed to read file, ignoring: %s", strerror(-n)); + else if (n > 0) + server_process_native_message(s, p, n, ucred, tv, label, label_len); +} + +int server_open_native_socket(Server*s) { + union sockaddr_union sa; + int one, r; + struct epoll_event ev; + + assert(s); + + if (s->native_fd < 0) { + + s->native_fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0); + if (s->native_fd < 0) { + log_error("socket() failed: %m"); + return -errno; + } + + zero(sa); + sa.un.sun_family = AF_UNIX; + strncpy(sa.un.sun_path, "/run/systemd/journal/socket", sizeof(sa.un.sun_path)); + + unlink(sa.un.sun_path); + + r = bind(s->native_fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path)); + if (r < 0) { + log_error("bind() failed: %m"); + return -errno; + } + + chmod(sa.un.sun_path, 0666); + } else + fd_nonblock(s->native_fd, 1); + + one = 1; + r = setsockopt(s->native_fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one)); + if (r < 0) { + log_error("SO_PASSCRED failed: %m"); + return -errno; + } + +#ifdef HAVE_SELINUX + one = 1; + r = setsockopt(s->native_fd, SOL_SOCKET, SO_PASSSEC, &one, sizeof(one)); + if (r < 0) + log_warning("SO_PASSSEC failed: %m"); +#endif + + one = 1; + r = setsockopt(s->native_fd, SOL_SOCKET, SO_TIMESTAMP, &one, sizeof(one)); + if (r < 0) { + log_error("SO_TIMESTAMP failed: %m"); + return -errno; + } + + zero(ev); + ev.events = EPOLLIN; + ev.data.fd = s->native_fd; + if (epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, s->native_fd, &ev) < 0) { + log_error("Failed to add native server fd to epoll object: %m"); + return -errno; + } + + return 0; +} diff --git a/src/journal/journald-native.h b/src/journal/journald-native.h new file mode 100644 index 000000000..16c09f523 --- /dev/null +++ b/src/journal/journald-native.h @@ -0,0 +1,30 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +#include "journald-server.h" + +void server_process_native_message(Server *s, const void *buffer, size_t buffer_size, struct ucred *ucred, struct timeval *tv, const char *label, size_t label_len); + +void server_process_native_file(Server *s, int fd, struct ucred *ucred, struct timeval *tv, const char *label, size_t label_len); + +int server_open_native_socket(Server*s); diff --git a/src/journal/journald-rate-limit.c b/src/journal/journald-rate-limit.c new file mode 100644 index 000000000..8bd68476a --- /dev/null +++ b/src/journal/journald-rate-limit.c @@ -0,0 +1,275 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +#include +#include + +#include "journald-rate-limit.h" +#include "list.h" +#include "util.h" +#include "hashmap.h" + +#define POOLS_MAX 5 +#define BUCKETS_MAX 127 +#define GROUPS_MAX 2047 + +static const int priority_map[] = { + [LOG_EMERG] = 0, + [LOG_ALERT] = 0, + [LOG_CRIT] = 0, + [LOG_ERR] = 1, + [LOG_WARNING] = 2, + [LOG_NOTICE] = 3, + [LOG_INFO] = 3, + [LOG_DEBUG] = 4 +}; + +typedef struct JournalRateLimitPool JournalRateLimitPool; +typedef struct JournalRateLimitGroup JournalRateLimitGroup; + +struct JournalRateLimitPool { + usec_t begin; + unsigned num; + unsigned suppressed; +}; + +struct JournalRateLimitGroup { + JournalRateLimit *parent; + + char *id; + JournalRateLimitPool pools[POOLS_MAX]; + unsigned hash; + + LIST_FIELDS(JournalRateLimitGroup, bucket); + LIST_FIELDS(JournalRateLimitGroup, lru); +}; + +struct JournalRateLimit { + usec_t interval; + unsigned burst; + + JournalRateLimitGroup* buckets[BUCKETS_MAX]; + JournalRateLimitGroup *lru, *lru_tail; + + unsigned n_groups; +}; + +JournalRateLimit *journal_rate_limit_new(usec_t interval, unsigned burst) { + JournalRateLimit *r; + + assert(interval > 0 || burst == 0); + + r = new0(JournalRateLimit, 1); + if (!r) + return NULL; + + r->interval = interval; + r->burst = burst; + + return r; +} + +static void journal_rate_limit_group_free(JournalRateLimitGroup *g) { + assert(g); + + if (g->parent) { + assert(g->parent->n_groups > 0); + + if (g->parent->lru_tail == g) + g->parent->lru_tail = g->lru_prev; + + LIST_REMOVE(JournalRateLimitGroup, lru, g->parent->lru, g); + LIST_REMOVE(JournalRateLimitGroup, bucket, g->parent->buckets[g->hash % BUCKETS_MAX], g); + + g->parent->n_groups --; + } + + free(g->id); + free(g); +} + +void journal_rate_limit_free(JournalRateLimit *r) { + assert(r); + + while (r->lru) + journal_rate_limit_group_free(r->lru); + + free(r); +} + +static bool journal_rate_limit_group_expired(JournalRateLimitGroup *g, usec_t ts) { + unsigned i; + + assert(g); + + for (i = 0; i < POOLS_MAX; i++) + if (g->pools[i].begin + g->parent->interval >= ts) + return false; + + return true; +} + +static void journal_rate_limit_vacuum(JournalRateLimit *r, usec_t ts) { + assert(r); + + /* Makes room for at least one new item, but drop all + * expored items too. */ + + while (r->n_groups >= GROUPS_MAX || + (r->lru_tail && journal_rate_limit_group_expired(r->lru_tail, ts))) + journal_rate_limit_group_free(r->lru_tail); +} + +static JournalRateLimitGroup* journal_rate_limit_group_new(JournalRateLimit *r, const char *id, usec_t ts) { + JournalRateLimitGroup *g; + + assert(r); + assert(id); + + g = new0(JournalRateLimitGroup, 1); + if (!g) + return NULL; + + g->id = strdup(id); + if (!g->id) + goto fail; + + g->hash = string_hash_func(g->id); + + journal_rate_limit_vacuum(r, ts); + + LIST_PREPEND(JournalRateLimitGroup, bucket, r->buckets[g->hash % BUCKETS_MAX], g); + LIST_PREPEND(JournalRateLimitGroup, lru, r->lru, g); + if (!g->lru_next) + r->lru_tail = g; + r->n_groups ++; + + g->parent = r; + return g; + +fail: + journal_rate_limit_group_free(g); + return NULL; +} + +static uint64_t u64log2(uint64_t n) { + unsigned r; + + if (n <= 1) + return 0; + + r = 0; + for (;;) { + n = n >> 1; + if (!n) + return r; + r++; + } +} + +static unsigned burst_modulate(unsigned burst, uint64_t available) { + unsigned k; + + /* Modulates the burst rate a bit with the amount of available + * disk space */ + + k = u64log2(available); + + /* 1MB */ + if (k <= 20) + return burst; + + burst = (burst * (k-20)) / 4; + + /* + * Example: + * + * <= 1MB = rate * 1 + * 16MB = rate * 2 + * 256MB = rate * 3 + * 4GB = rate * 4 + * 64GB = rate * 5 + * 1TB = rate * 6 + */ + + return burst; +} + +int journal_rate_limit_test(JournalRateLimit *r, const char *id, int priority, uint64_t available) { + unsigned h; + JournalRateLimitGroup *g; + JournalRateLimitPool *p; + unsigned burst; + usec_t ts; + + assert(id); + + if (!r) + return 1; + + if (r->interval == 0 || r->burst == 0) + return 1; + + burst = burst_modulate(r->burst, available); + + ts = now(CLOCK_MONOTONIC); + + h = string_hash_func(id); + g = r->buckets[h % BUCKETS_MAX]; + + LIST_FOREACH(bucket, g, g) + if (streq(g->id, id)) + break; + + if (!g) { + g = journal_rate_limit_group_new(r, id, ts); + if (!g) + return -ENOMEM; + } + + p = &g->pools[priority_map[priority]]; + + if (p->begin <= 0) { + p->suppressed = 0; + p->num = 1; + p->begin = ts; + return 1; + } + + if (p->begin + r->interval < ts) { + unsigned s; + + s = p->suppressed; + p->suppressed = 0; + p->num = 1; + p->begin = ts; + + return 1 + s; + } + + if (p->num <= burst) { + p->num++; + return 1; + } + + p->suppressed++; + return 0; +} diff --git a/src/journal/journald-rate-limit.h b/src/journal/journald-rate-limit.h new file mode 100644 index 000000000..648ab2278 --- /dev/null +++ b/src/journal/journald-rate-limit.h @@ -0,0 +1,31 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +#include "macro.h" +#include "util.h" + +typedef struct JournalRateLimit JournalRateLimit; + +JournalRateLimit *journal_rate_limit_new(usec_t interval, unsigned burst); +void journal_rate_limit_free(JournalRateLimit *r); +int journal_rate_limit_test(JournalRateLimit *r, const char *id, int priority, uint64_t available); diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c new file mode 100644 index 000000000..43ffe7556 --- /dev/null +++ b/src/journal/journald-server.c @@ -0,0 +1,1504 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#ifdef HAVE_LOGIND +#include +#endif + +#include "mkdir.h" +#include "hashmap.h" +#include "journal-file.h" +#include "socket-util.h" +#include "cgroup-util.h" +#include "list.h" +#include "virt.h" +#include "missing.h" +#include "conf-parser.h" +#include "journal-internal.h" +#include "journal-vacuum.h" +#include "journal-authenticate.h" +#include "journald-server.h" +#include "journald-rate-limit.h" +#include "journald-kmsg.h" +#include "journald-syslog.h" +#include "journald-stream.h" +#include "journald-console.h" +#include "journald-native.h" + +#ifdef HAVE_ACL +#include +#include +#include "acl-util.h" +#endif + +#ifdef HAVE_SELINUX +#include +#endif + +#define USER_JOURNALS_MAX 1024 + +#define DEFAULT_RATE_LIMIT_INTERVAL (10*USEC_PER_SEC) +#define DEFAULT_RATE_LIMIT_BURST 200 + +#define RECHECK_AVAILABLE_SPACE_USEC (30*USEC_PER_SEC) + +static const char* const storage_table[] = { + [STORAGE_AUTO] = "auto", + [STORAGE_VOLATILE] = "volatile", + [STORAGE_PERSISTENT] = "persistent", + [STORAGE_NONE] = "none" +}; + +DEFINE_STRING_TABLE_LOOKUP(storage, Storage); +DEFINE_CONFIG_PARSE_ENUM(config_parse_storage, storage, Storage, "Failed to parse storage setting"); + +static const char* const split_mode_table[] = { + [SPLIT_NONE] = "none", + [SPLIT_UID] = "uid", + [SPLIT_LOGIN] = "login" +}; + +DEFINE_STRING_TABLE_LOOKUP(split_mode, SplitMode); +DEFINE_CONFIG_PARSE_ENUM(config_parse_split_mode, split_mode, SplitMode, "Failed to parse split mode setting"); + +static uint64_t available_space(Server *s) { + char ids[33], *p; + const char *f; + sd_id128_t machine; + struct statvfs ss; + uint64_t sum = 0, avail = 0, ss_avail = 0; + int r; + DIR *d; + usec_t ts; + JournalMetrics *m; + + ts = now(CLOCK_MONOTONIC); + + if (s->cached_available_space_timestamp + RECHECK_AVAILABLE_SPACE_USEC > ts) + return s->cached_available_space; + + r = sd_id128_get_machine(&machine); + if (r < 0) + return 0; + + if (s->system_journal) { + f = "/var/log/journal/"; + m = &s->system_metrics; + } else { + f = "/run/log/journal/"; + m = &s->runtime_metrics; + } + + assert(m); + + p = strappend(f, sd_id128_to_string(machine, ids)); + if (!p) + return 0; + + d = opendir(p); + free(p); + + if (!d) + return 0; + + if (fstatvfs(dirfd(d), &ss) < 0) + goto finish; + + for (;;) { + struct stat st; + struct dirent *de; + union dirent_storage buf; + + r = readdir_r(d, &buf.de, &de); + if (r != 0) + break; + + if (!de) + break; + + if (!endswith(de->d_name, ".journal") && + !endswith(de->d_name, ".journal~")) + continue; + + if (fstatat(dirfd(d), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0) + continue; + + if (!S_ISREG(st.st_mode)) + continue; + + sum += (uint64_t) st.st_blocks * 512UL; + } + + avail = sum >= m->max_use ? 0 : m->max_use - sum; + + ss_avail = ss.f_bsize * ss.f_bavail; + + ss_avail = ss_avail < m->keep_free ? 0 : ss_avail - m->keep_free; + + if (ss_avail < avail) + avail = ss_avail; + + s->cached_available_space = avail; + s->cached_available_space_timestamp = ts; + +finish: + closedir(d); + + return avail; +} + +static void server_read_file_gid(Server *s) { + const char *adm = "adm"; + int r; + + assert(s); + + if (s->file_gid_valid) + return; + + r = get_group_creds(&adm, &s->file_gid); + if (r < 0) + log_warning("Failed to resolve 'adm' group: %s", strerror(-r)); + + /* if we couldn't read the gid, then it will be 0, but that's + * fine and we shouldn't try to resolve the group again, so + * let's just pretend it worked right-away. */ + s->file_gid_valid = true; +} + +void server_fix_perms(Server *s, JournalFile *f, uid_t uid) { + int r; +#ifdef HAVE_ACL + acl_t acl; + acl_entry_t entry; + acl_permset_t permset; +#endif + + assert(f); + + server_read_file_gid(s); + + r = fchmod_and_fchown(f->fd, 0640, 0, s->file_gid); + if (r < 0) + log_warning("Failed to fix access mode/rights on %s, ignoring: %s", f->path, strerror(-r)); + +#ifdef HAVE_ACL + if (uid <= 0) + return; + + acl = acl_get_fd(f->fd); + if (!acl) { + log_warning("Failed to read ACL on %s, ignoring: %m", f->path); + return; + } + + r = acl_find_uid(acl, uid, &entry); + if (r <= 0) { + + if (acl_create_entry(&acl, &entry) < 0 || + acl_set_tag_type(entry, ACL_USER) < 0 || + acl_set_qualifier(entry, &uid) < 0) { + log_warning("Failed to patch ACL on %s, ignoring: %m", f->path); + goto finish; + } + } + + if (acl_get_permset(entry, &permset) < 0 || + acl_add_perm(permset, ACL_READ) < 0 || + acl_calc_mask(&acl) < 0) { + log_warning("Failed to patch ACL on %s, ignoring: %m", f->path); + goto finish; + } + + if (acl_set_fd(f->fd, acl) < 0) + log_warning("Failed to set ACL on %s, ignoring: %m", f->path); + +finish: + acl_free(acl); +#endif +} + +static JournalFile* find_journal(Server *s, uid_t uid) { + char *p; + int r; + JournalFile *f; + sd_id128_t machine; + + assert(s); + + /* We split up user logs only on /var, not on /run. If the + * runtime file is open, we write to it exclusively, in order + * to guarantee proper order as soon as we flush /run to + * /var and close the runtime file. */ + + if (s->runtime_journal) + return s->runtime_journal; + + if (uid <= 0) + return s->system_journal; + + r = sd_id128_get_machine(&machine); + if (r < 0) + return s->system_journal; + + f = hashmap_get(s->user_journals, UINT32_TO_PTR(uid)); + if (f) + return f; + + if (asprintf(&p, "/var/log/journal/" SD_ID128_FORMAT_STR "/user-%lu.journal", + SD_ID128_FORMAT_VAL(machine), (unsigned long) uid) < 0) + return s->system_journal; + + while (hashmap_size(s->user_journals) >= USER_JOURNALS_MAX) { + /* Too many open? Then let's close one */ + f = hashmap_steal_first(s->user_journals); + assert(f); + journal_file_close(f); + } + + r = journal_file_open_reliably(p, O_RDWR|O_CREAT, 0640, s->compress, s->seal, &s->system_metrics, s->mmap, s->system_journal, &f); + free(p); + + if (r < 0) + return s->system_journal; + + server_fix_perms(s, f, uid); + + r = hashmap_put(s->user_journals, UINT32_TO_PTR(uid), f); + if (r < 0) { + journal_file_close(f); + return s->system_journal; + } + + return f; +} + +void server_rotate(Server *s) { + JournalFile *f; + void *k; + Iterator i; + int r; + + log_debug("Rotating..."); + + if (s->runtime_journal) { + r = journal_file_rotate(&s->runtime_journal, s->compress, false); + if (r < 0) + if (s->runtime_journal) + log_error("Failed to rotate %s: %s", s->runtime_journal->path, strerror(-r)); + else + log_error("Failed to create new runtime journal: %s", strerror(-r)); + else + server_fix_perms(s, s->runtime_journal, 0); + } + + if (s->system_journal) { + r = journal_file_rotate(&s->system_journal, s->compress, s->seal); + if (r < 0) + if (s->system_journal) + log_error("Failed to rotate %s: %s", s->system_journal->path, strerror(-r)); + else + log_error("Failed to create new system journal: %s", strerror(-r)); + + else + server_fix_perms(s, s->system_journal, 0); + } + + HASHMAP_FOREACH_KEY(f, k, s->user_journals, i) { + r = journal_file_rotate(&f, s->compress, s->seal); + if (r < 0) + if (f) + log_error("Failed to rotate %s: %s", f->path, strerror(-r)); + else + log_error("Failed to create user journal: %s", strerror(-r)); + else { + hashmap_replace(s->user_journals, k, f); + server_fix_perms(s, f, PTR_TO_UINT32(k)); + } + } +} + +void server_vacuum(Server *s) { + char *p; + char ids[33]; + sd_id128_t machine; + int r; + + log_debug("Vacuuming..."); + + s->oldest_file_usec = 0; + + r = sd_id128_get_machine(&machine); + if (r < 0) { + log_error("Failed to get machine ID: %s", strerror(-r)); + return; + } + + sd_id128_to_string(machine, ids); + + if (s->system_journal) { + p = strappend("/var/log/journal/", ids); + if (!p) { + log_oom(); + return; + } + + r = journal_directory_vacuum(p, s->system_metrics.max_use, s->system_metrics.keep_free, s->max_retention_usec, &s->oldest_file_usec); + if (r < 0 && r != -ENOENT) + log_error("Failed to vacuum %s: %s", p, strerror(-r)); + free(p); + } + + if (s->runtime_journal) { + p = strappend("/run/log/journal/", ids); + if (!p) { + log_oom(); + return; + } + + r = journal_directory_vacuum(p, s->runtime_metrics.max_use, s->runtime_metrics.keep_free, s->max_retention_usec, &s->oldest_file_usec); + if (r < 0 && r != -ENOENT) + log_error("Failed to vacuum %s: %s", p, strerror(-r)); + free(p); + } + + s->cached_available_space_timestamp = 0; +} + +static char *shortened_cgroup_path(pid_t pid) { + int r; + char *process_path, *init_path, *path; + + assert(pid > 0); + + r = cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, pid, &process_path); + if (r < 0) + return NULL; + + r = cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, 1, &init_path); + if (r < 0) { + free(process_path); + return NULL; + } + + if (endswith(init_path, "/system")) + init_path[strlen(init_path) - 7] = 0; + else if (streq(init_path, "/")) + init_path[0] = 0; + + if (startswith(process_path, init_path)) { + char *p; + + p = strdup(process_path + strlen(init_path)); + if (!p) { + free(process_path); + free(init_path); + return NULL; + } + path = p; + } else { + path = process_path; + process_path = NULL; + } + + free(process_path); + free(init_path); + + return path; +} + +bool shall_try_append_again(JournalFile *f, int r) { + + /* -E2BIG Hit configured limit + -EFBIG Hit fs limit + -EDQUOT Quota limit hit + -ENOSPC Disk full + -EHOSTDOWN Other machine + -EBUSY Unclean shutdown + -EPROTONOSUPPORT Unsupported feature + -EBADMSG Corrupted + -ENODATA Truncated + -ESHUTDOWN Already archived */ + + if (r == -E2BIG || r == -EFBIG || r == -EDQUOT || r == -ENOSPC) + log_debug("%s: Allocation limit reached, rotating.", f->path); + else if (r == -EHOSTDOWN) + log_info("%s: Journal file from other machine, rotating.", f->path); + else if (r == -EBUSY) + log_info("%s: Unclean shutdown, rotating.", f->path); + else if (r == -EPROTONOSUPPORT) + log_info("%s: Unsupported feature, rotating.", f->path); + else if (r == -EBADMSG || r == -ENODATA || r == ESHUTDOWN) + log_warning("%s: Journal file corrupted, rotating.", f->path); + else + return false; + + return true; +} + +static void write_to_journal(Server *s, uid_t uid, struct iovec *iovec, unsigned n) { + JournalFile *f; + bool vacuumed = false; + int r; + + assert(s); + assert(iovec); + assert(n > 0); + + f = find_journal(s, uid); + if (!f) + return; + + if (journal_file_rotate_suggested(f, s->max_file_usec)) { + log_debug("%s: Journal header limits reached or header out-of-date, rotating.", f->path); + server_rotate(s); + server_vacuum(s); + vacuumed = true; + + f = find_journal(s, uid); + if (!f) + return; + } + + r = journal_file_append_entry(f, NULL, iovec, n, &s->seqnum, NULL, NULL); + if (r >= 0) + return; + + if (vacuumed || !shall_try_append_again(f, r)) { + log_error("Failed to write entry, ignoring: %s", strerror(-r)); + return; + } + + server_rotate(s); + server_vacuum(s); + + f = find_journal(s, uid); + if (!f) + return; + + log_debug("Retrying write."); + r = journal_file_append_entry(f, NULL, iovec, n, &s->seqnum, NULL, NULL); + if (r < 0) + log_error("Failed to write entry, ignoring: %s", strerror(-r)); +} + +static void dispatch_message_real( + Server *s, + struct iovec *iovec, unsigned n, unsigned m, + struct ucred *ucred, + struct timeval *tv, + const char *label, size_t label_len, + const char *unit_id) { + + char *pid = NULL, *uid = NULL, *gid = NULL, + *source_time = NULL, *boot_id = NULL, *machine_id = NULL, + *comm = NULL, *cmdline = NULL, *hostname = NULL, + *audit_session = NULL, *audit_loginuid = NULL, + *exe = NULL, *cgroup = NULL, *session = NULL, + *owner_uid = NULL, *unit = NULL, *selinux_context = NULL; + + char idbuf[33]; + sd_id128_t id; + int r; + char *t; + uid_t loginuid = 0, realuid = 0; + + assert(s); + assert(iovec); + assert(n > 0); + assert(n + N_IOVEC_META_FIELDS <= m); + + if (ucred) { + uint32_t audit; +#ifdef HAVE_LOGIND + uid_t owner; +#endif + + realuid = ucred->uid; + + if (asprintf(&pid, "_PID=%lu", (unsigned long) ucred->pid) >= 0) + IOVEC_SET_STRING(iovec[n++], pid); + + if (asprintf(&uid, "_UID=%lu", (unsigned long) ucred->uid) >= 0) + IOVEC_SET_STRING(iovec[n++], uid); + + if (asprintf(&gid, "_GID=%lu", (unsigned long) ucred->gid) >= 0) + IOVEC_SET_STRING(iovec[n++], gid); + + r = get_process_comm(ucred->pid, &t); + if (r >= 0) { + comm = strappend("_COMM=", t); + free(t); + + if (comm) + IOVEC_SET_STRING(iovec[n++], comm); + } + + r = get_process_exe(ucred->pid, &t); + if (r >= 0) { + exe = strappend("_EXE=", t); + free(t); + + if (exe) + IOVEC_SET_STRING(iovec[n++], exe); + } + + r = get_process_cmdline(ucred->pid, LINE_MAX, false, &t); + if (r >= 0) { + cmdline = strappend("_CMDLINE=", t); + free(t); + + if (cmdline) + IOVEC_SET_STRING(iovec[n++], cmdline); + } + + r = audit_session_from_pid(ucred->pid, &audit); + if (r >= 0) + if (asprintf(&audit_session, "_AUDIT_SESSION=%lu", (unsigned long) audit) >= 0) + IOVEC_SET_STRING(iovec[n++], audit_session); + + r = audit_loginuid_from_pid(ucred->pid, &loginuid); + if (r >= 0) + if (asprintf(&audit_loginuid, "_AUDIT_LOGINUID=%lu", (unsigned long) loginuid) >= 0) + IOVEC_SET_STRING(iovec[n++], audit_loginuid); + + t = shortened_cgroup_path(ucred->pid); + if (t) { + cgroup = strappend("_SYSTEMD_CGROUP=", t); + free(t); + + if (cgroup) + IOVEC_SET_STRING(iovec[n++], cgroup); + } + +#ifdef HAVE_LOGIND + if (sd_pid_get_session(ucred->pid, &t) >= 0) { + session = strappend("_SYSTEMD_SESSION=", t); + free(t); + + if (session) + IOVEC_SET_STRING(iovec[n++], session); + } + + if (sd_pid_get_owner_uid(ucred->uid, &owner) >= 0) + if (asprintf(&owner_uid, "_SYSTEMD_OWNER_UID=%lu", (unsigned long) owner) >= 0) + IOVEC_SET_STRING(iovec[n++], owner_uid); +#endif + + if (cg_pid_get_unit(ucred->pid, &t) >= 0) { + unit = strappend("_SYSTEMD_UNIT=", t); + free(t); + } else if (unit_id) + unit = strappend("_SYSTEMD_UNIT=", unit_id); + + if (unit) + IOVEC_SET_STRING(iovec[n++], unit); + +#ifdef HAVE_SELINUX + if (label) { + selinux_context = malloc(sizeof("_SELINUX_CONTEXT=") + label_len); + if (selinux_context) { + memcpy(selinux_context, "_SELINUX_CONTEXT=", sizeof("_SELINUX_CONTEXT=")-1); + memcpy(selinux_context+sizeof("_SELINUX_CONTEXT=")-1, label, label_len); + selinux_context[sizeof("_SELINUX_CONTEXT=")-1+label_len] = 0; + IOVEC_SET_STRING(iovec[n++], selinux_context); + } + } else { + security_context_t con; + + if (getpidcon(ucred->pid, &con) >= 0) { + selinux_context = strappend("_SELINUX_CONTEXT=", con); + if (selinux_context) + IOVEC_SET_STRING(iovec[n++], selinux_context); + + freecon(con); + } + } +#endif + } + + if (tv) { + if (asprintf(&source_time, "_SOURCE_REALTIME_TIMESTAMP=%llu", + (unsigned long long) timeval_load(tv)) >= 0) + IOVEC_SET_STRING(iovec[n++], source_time); + } + + /* Note that strictly speaking storing the boot id here is + * redundant since the entry includes this in-line + * anyway. However, we need this indexed, too. */ + r = sd_id128_get_boot(&id); + if (r >= 0) + if (asprintf(&boot_id, "_BOOT_ID=%s", sd_id128_to_string(id, idbuf)) >= 0) + IOVEC_SET_STRING(iovec[n++], boot_id); + + r = sd_id128_get_machine(&id); + if (r >= 0) + if (asprintf(&machine_id, "_MACHINE_ID=%s", sd_id128_to_string(id, idbuf)) >= 0) + IOVEC_SET_STRING(iovec[n++], machine_id); + + t = gethostname_malloc(); + if (t) { + hostname = strappend("_HOSTNAME=", t); + free(t); + if (hostname) + IOVEC_SET_STRING(iovec[n++], hostname); + } + + assert(n <= m); + + write_to_journal(s, + s->split_mode == SPLIT_NONE ? 0 : + (s->split_mode == SPLIT_UID ? realuid : + (realuid == 0 ? 0 : loginuid)), iovec, n); + + free(pid); + free(uid); + free(gid); + free(comm); + free(exe); + free(cmdline); + free(source_time); + free(boot_id); + free(machine_id); + free(hostname); + free(audit_session); + free(audit_loginuid); + free(cgroup); + free(session); + free(owner_uid); + free(unit); + free(selinux_context); +} + +void server_driver_message(Server *s, sd_id128_t message_id, const char *format, ...) { + char mid[11 + 32 + 1]; + char buffer[16 + LINE_MAX + 1]; + struct iovec iovec[N_IOVEC_META_FIELDS + 4]; + int n = 0; + va_list ap; + struct ucred ucred; + + assert(s); + assert(format); + + IOVEC_SET_STRING(iovec[n++], "PRIORITY=6"); + IOVEC_SET_STRING(iovec[n++], "_TRANSPORT=driver"); + + memcpy(buffer, "MESSAGE=", 8); + va_start(ap, format); + vsnprintf(buffer + 8, sizeof(buffer) - 8, format, ap); + va_end(ap); + char_array_0(buffer); + IOVEC_SET_STRING(iovec[n++], buffer); + + if (!sd_id128_equal(message_id, SD_ID128_NULL)) { + snprintf(mid, sizeof(mid), MESSAGE_ID(message_id)); + char_array_0(mid); + IOVEC_SET_STRING(iovec[n++], mid); + } + + zero(ucred); + ucred.pid = getpid(); + ucred.uid = getuid(); + ucred.gid = getgid(); + + dispatch_message_real(s, iovec, n, ELEMENTSOF(iovec), &ucred, NULL, NULL, 0, NULL); +} + +void server_dispatch_message( + Server *s, + struct iovec *iovec, unsigned n, unsigned m, + struct ucred *ucred, + struct timeval *tv, + const char *label, size_t label_len, + const char *unit_id, + int priority) { + + int rl; + char *path = NULL, *c; + + assert(s); + assert(iovec || n == 0); + + if (n == 0) + return; + + if (LOG_PRI(priority) > s->max_level_store) + return; + + if (!ucred) + goto finish; + + path = shortened_cgroup_path(ucred->pid); + if (!path) + goto finish; + + /* example: /user/lennart/3/foobar + * /system/dbus.service/foobar + * + * So let's cut of everything past the third /, since that is + * where user directories start */ + + c = strchr(path, '/'); + if (c) { + c = strchr(c+1, '/'); + if (c) { + c = strchr(c+1, '/'); + if (c) + *c = 0; + } + } + + rl = journal_rate_limit_test(s->rate_limit, path, priority & LOG_PRIMASK, available_space(s)); + + if (rl == 0) { + free(path); + return; + } + + /* Write a suppression message if we suppressed something */ + if (rl > 1) + server_driver_message(s, SD_MESSAGE_JOURNAL_DROPPED, "Suppressed %u messages from %s", rl - 1, path); + + free(path); + +finish: + dispatch_message_real(s, iovec, n, m, ucred, tv, label, label_len, unit_id); +} + + +static int system_journal_open(Server *s) { + int r; + char *fn; + sd_id128_t machine; + char ids[33]; + + r = sd_id128_get_machine(&machine); + if (r < 0) + return r; + + sd_id128_to_string(machine, ids); + + if (!s->system_journal && + (s->storage == STORAGE_PERSISTENT || s->storage == STORAGE_AUTO) && + access("/run/systemd/journal/flushed", F_OK) >= 0) { + + /* If in auto mode: first try to create the machine + * path, but not the prefix. + * + * If in persistent mode: create /var/log/journal and + * the machine path */ + + if (s->storage == STORAGE_PERSISTENT) + (void) mkdir("/var/log/journal/", 0755); + + fn = strappend("/var/log/journal/", ids); + if (!fn) + return -ENOMEM; + + (void) mkdir(fn, 0755); + free(fn); + + fn = strjoin("/var/log/journal/", ids, "/system.journal", NULL); + if (!fn) + return -ENOMEM; + + r = journal_file_open_reliably(fn, O_RDWR|O_CREAT, 0640, s->compress, s->seal, &s->system_metrics, s->mmap, NULL, &s->system_journal); + free(fn); + + if (r >= 0) { + char fb[FORMAT_BYTES_MAX]; + + server_fix_perms(s, s->system_journal, 0); + server_driver_message(s, SD_ID128_NULL, "Allowing system journal files to grow to %s.", + format_bytes(fb, sizeof(fb), s->system_metrics.max_use)); + + } else if (r < 0) { + + if (r != -ENOENT && r != -EROFS) + log_warning("Failed to open system journal: %s", strerror(-r)); + + r = 0; + } + } + + if (!s->runtime_journal && + (s->storage != STORAGE_NONE)) { + + fn = strjoin("/run/log/journal/", ids, "/system.journal", NULL); + if (!fn) + return -ENOMEM; + + if (s->system_journal) { + + /* Try to open the runtime journal, but only + * if it already exists, so that we can flush + * it into the system journal */ + + r = journal_file_open(fn, O_RDWR, 0640, s->compress, false, &s->runtime_metrics, s->mmap, NULL, &s->runtime_journal); + free(fn); + + if (r < 0) { + if (r != -ENOENT) + log_warning("Failed to open runtime journal: %s", strerror(-r)); + + r = 0; + } + + } else { + + /* OK, we really need the runtime journal, so create + * it if necessary. */ + + (void) mkdir_parents(fn, 0755); + r = journal_file_open_reliably(fn, O_RDWR|O_CREAT, 0640, s->compress, false, &s->runtime_metrics, s->mmap, NULL, &s->runtime_journal); + free(fn); + + if (r < 0) { + log_error("Failed to open runtime journal: %s", strerror(-r)); + return r; + } + } + + if (s->runtime_journal) { + char fb[FORMAT_BYTES_MAX]; + + server_fix_perms(s, s->runtime_journal, 0); + server_driver_message(s, SD_ID128_NULL, "Allowing runtime journal files to grow to %s.", + format_bytes(fb, sizeof(fb), s->runtime_metrics.max_use)); + } + } + + return r; +} + +int server_flush_to_var(Server *s) { + int r; + sd_id128_t machine; + sd_journal *j = NULL; + + assert(s); + + if (s->storage != STORAGE_AUTO && + s->storage != STORAGE_PERSISTENT) + return 0; + + if (!s->runtime_journal) + return 0; + + system_journal_open(s); + + if (!s->system_journal) + return 0; + + log_debug("Flushing to /var..."); + + r = sd_id128_get_machine(&machine); + if (r < 0) { + log_error("Failed to get machine id: %s", strerror(-r)); + return r; + } + + r = sd_journal_open(&j, SD_JOURNAL_RUNTIME_ONLY); + if (r < 0) { + log_error("Failed to read runtime journal: %s", strerror(-r)); + return r; + } + + sd_journal_set_data_threshold(j, 0); + + SD_JOURNAL_FOREACH(j) { + Object *o = NULL; + JournalFile *f; + + f = j->current_file; + assert(f && f->current_offset > 0); + + r = journal_file_move_to_object(f, OBJECT_ENTRY, f->current_offset, &o); + if (r < 0) { + log_error("Can't read entry: %s", strerror(-r)); + goto finish; + } + + r = journal_file_copy_entry(f, s->system_journal, o, f->current_offset, NULL, NULL, NULL); + if (r >= 0) + continue; + + if (!shall_try_append_again(s->system_journal, r)) { + log_error("Can't write entry: %s", strerror(-r)); + goto finish; + } + + server_rotate(s); + server_vacuum(s); + + log_debug("Retrying write."); + r = journal_file_copy_entry(f, s->system_journal, o, f->current_offset, NULL, NULL, NULL); + if (r < 0) { + log_error("Can't write entry: %s", strerror(-r)); + goto finish; + } + } + +finish: + journal_file_post_change(s->system_journal); + + journal_file_close(s->runtime_journal); + s->runtime_journal = NULL; + + if (r >= 0) + rm_rf("/run/log/journal", false, true, false); + + if (j) + sd_journal_close(j); + + return r; +} + +int process_event(Server *s, struct epoll_event *ev) { + assert(s); + assert(ev); + + if (ev->data.fd == s->signal_fd) { + struct signalfd_siginfo sfsi; + ssize_t n; + + if (ev->events != EPOLLIN) { + log_error("Got invalid event from epoll."); + return -EIO; + } + + n = read(s->signal_fd, &sfsi, sizeof(sfsi)); + if (n != sizeof(sfsi)) { + + if (n >= 0) + return -EIO; + + if (errno == EINTR || errno == EAGAIN) + return 1; + + return -errno; + } + + log_info("Received SIG%s", signal_to_string(sfsi.ssi_signo)); + + if (sfsi.ssi_signo == SIGUSR1) { + touch("/run/systemd/journal/flushed"); + server_flush_to_var(s); + return 1; + } + + if (sfsi.ssi_signo == SIGUSR2) { + server_rotate(s); + server_vacuum(s); + return 1; + } + + return 0; + + } else if (ev->data.fd == s->dev_kmsg_fd) { + int r; + + if (ev->events != EPOLLIN) { + log_error("Got invalid event from epoll."); + return -EIO; + } + + r = server_read_dev_kmsg(s); + if (r < 0) + return r; + + return 1; + + } else if (ev->data.fd == s->native_fd || + ev->data.fd == s->syslog_fd) { + + if (ev->events != EPOLLIN) { + log_error("Got invalid event from epoll."); + return -EIO; + } + + for (;;) { + struct msghdr msghdr; + struct iovec iovec; + struct ucred *ucred = NULL; + struct timeval *tv = NULL; + struct cmsghdr *cmsg; + char *label = NULL; + size_t label_len = 0; + union { + struct cmsghdr cmsghdr; + + /* We use NAME_MAX space for the + * SELinux label here. The kernel + * currently enforces no limit, but + * according to suggestions from the + * SELinux people this will change and + * it will probably be identical to + * NAME_MAX. For now we use that, but + * this should be updated one day when + * the final limit is known.*/ + uint8_t buf[CMSG_SPACE(sizeof(struct ucred)) + + CMSG_SPACE(sizeof(struct timeval)) + + CMSG_SPACE(sizeof(int)) + /* fd */ + CMSG_SPACE(NAME_MAX)]; /* selinux label */ + } control; + ssize_t n; + int v; + int *fds = NULL; + unsigned n_fds = 0; + + if (ioctl(ev->data.fd, SIOCINQ, &v) < 0) { + log_error("SIOCINQ failed: %m"); + return -errno; + } + + if (s->buffer_size < (size_t) v) { + void *b; + size_t l; + + l = MAX(LINE_MAX + (size_t) v, s->buffer_size * 2); + b = realloc(s->buffer, l+1); + + if (!b) { + log_error("Couldn't increase buffer."); + return -ENOMEM; + } + + s->buffer_size = l; + s->buffer = b; + } + + zero(iovec); + iovec.iov_base = s->buffer; + iovec.iov_len = s->buffer_size; + + zero(control); + zero(msghdr); + msghdr.msg_iov = &iovec; + msghdr.msg_iovlen = 1; + msghdr.msg_control = &control; + msghdr.msg_controllen = sizeof(control); + + n = recvmsg(ev->data.fd, &msghdr, MSG_DONTWAIT|MSG_CMSG_CLOEXEC); + if (n < 0) { + + if (errno == EINTR || errno == EAGAIN) + return 1; + + log_error("recvmsg() failed: %m"); + return -errno; + } + + for (cmsg = CMSG_FIRSTHDR(&msghdr); cmsg; cmsg = CMSG_NXTHDR(&msghdr, cmsg)) { + + if (cmsg->cmsg_level == SOL_SOCKET && + cmsg->cmsg_type == SCM_CREDENTIALS && + cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred))) + ucred = (struct ucred*) CMSG_DATA(cmsg); + else if (cmsg->cmsg_level == SOL_SOCKET && + cmsg->cmsg_type == SCM_SECURITY) { + label = (char*) CMSG_DATA(cmsg); + label_len = cmsg->cmsg_len - CMSG_LEN(0); + } else if (cmsg->cmsg_level == SOL_SOCKET && + cmsg->cmsg_type == SO_TIMESTAMP && + cmsg->cmsg_len == CMSG_LEN(sizeof(struct timeval))) + tv = (struct timeval*) CMSG_DATA(cmsg); + else if (cmsg->cmsg_level == SOL_SOCKET && + cmsg->cmsg_type == SCM_RIGHTS) { + fds = (int*) CMSG_DATA(cmsg); + n_fds = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int); + } + } + + if (ev->data.fd == s->syslog_fd) { + char *e; + + if (n > 0 && n_fds == 0) { + e = memchr(s->buffer, '\n', n); + if (e) + *e = 0; + else + s->buffer[n] = 0; + + server_process_syslog_message(s, strstrip(s->buffer), ucred, tv, label, label_len); + } else if (n_fds > 0) + log_warning("Got file descriptors via syslog socket. Ignoring."); + + } else { + if (n > 0 && n_fds == 0) + server_process_native_message(s, s->buffer, n, ucred, tv, label, label_len); + else if (n == 0 && n_fds == 1) + server_process_native_file(s, fds[0], ucred, tv, label, label_len); + else if (n_fds > 0) + log_warning("Got too many file descriptors via native socket. Ignoring."); + } + + close_many(fds, n_fds); + } + + return 1; + + } else if (ev->data.fd == s->stdout_fd) { + + if (ev->events != EPOLLIN) { + log_error("Got invalid event from epoll."); + return -EIO; + } + + stdout_stream_new(s); + return 1; + + } else { + StdoutStream *stream; + + if ((ev->events|EPOLLIN|EPOLLHUP) != (EPOLLIN|EPOLLHUP)) { + log_error("Got invalid event from epoll."); + return -EIO; + } + + /* If it is none of the well-known fds, it must be an + * stdout stream fd. Note that this is a bit ugly here + * (since we rely that none of the well-known fds + * could be interpreted as pointer), but nonetheless + * safe, since the well-known fds would never get an + * fd > 4096, i.e. beyond the first memory page */ + + stream = ev->data.ptr; + + if (stdout_stream_process(stream) <= 0) + stdout_stream_free(stream); + + return 1; + } + + log_error("Unknown event."); + return 0; +} + +static int open_signalfd(Server *s) { + sigset_t mask; + struct epoll_event ev; + + assert(s); + + assert_se(sigemptyset(&mask) == 0); + sigset_add_many(&mask, SIGINT, SIGTERM, SIGUSR1, SIGUSR2, -1); + assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0); + + s->signal_fd = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC); + if (s->signal_fd < 0) { + log_error("signalfd(): %m"); + return -errno; + } + + zero(ev); + ev.events = EPOLLIN; + ev.data.fd = s->signal_fd; + + if (epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, s->signal_fd, &ev) < 0) { + log_error("epoll_ctl(): %m"); + return -errno; + } + + return 0; +} + +static int server_parse_proc_cmdline(Server *s) { + char *line, *w, *state; + int r; + size_t l; + + if (detect_container(NULL) > 0) + return 0; + + r = read_one_line_file("/proc/cmdline", &line); + if (r < 0) { + log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r)); + return 0; + } + + FOREACH_WORD_QUOTED(w, l, line, state) { + char *word; + + word = strndup(w, l); + if (!word) { + r = -ENOMEM; + goto finish; + } + + if (startswith(word, "systemd.journald.forward_to_syslog=")) { + r = parse_boolean(word + 35); + if (r < 0) + log_warning("Failed to parse forward to syslog switch %s. Ignoring.", word + 35); + else + s->forward_to_syslog = r; + } else if (startswith(word, "systemd.journald.forward_to_kmsg=")) { + r = parse_boolean(word + 33); + if (r < 0) + log_warning("Failed to parse forward to kmsg switch %s. Ignoring.", word + 33); + else + s->forward_to_kmsg = r; + } else if (startswith(word, "systemd.journald.forward_to_console=")) { + r = parse_boolean(word + 36); + if (r < 0) + log_warning("Failed to parse forward to console switch %s. Ignoring.", word + 36); + else + s->forward_to_console = r; + } else if (startswith(word, "systemd.journald")) + log_warning("Invalid systemd.journald parameter. Ignoring."); + + free(word); + } + + r = 0; + +finish: + free(line); + return r; +} + +static int server_parse_config_file(Server *s) { + FILE *f; + const char *fn; + int r; + + assert(s); + + fn = "/etc/systemd/journald.conf"; + f = fopen(fn, "re"); + if (!f) { + if (errno == ENOENT) + return 0; + + log_warning("Failed to open configuration file %s: %m", fn); + return -errno; + } + + r = config_parse(fn, f, "Journal\0", config_item_perf_lookup, (void*) journald_gperf_lookup, false, s); + if (r < 0) + log_warning("Failed to parse configuration file: %s", strerror(-r)); + + fclose(f); + + return r; +} + +int server_init(Server *s) { + int n, r, fd; + + assert(s); + + zero(*s); + s->syslog_fd = s->native_fd = s->stdout_fd = s->signal_fd = s->epoll_fd = s->dev_kmsg_fd = -1; + s->compress = true; + s->seal = true; + + s->rate_limit_interval = DEFAULT_RATE_LIMIT_INTERVAL; + s->rate_limit_burst = DEFAULT_RATE_LIMIT_BURST; + + s->forward_to_syslog = true; + + s->max_level_store = LOG_DEBUG; + s->max_level_syslog = LOG_DEBUG; + s->max_level_kmsg = LOG_NOTICE; + s->max_level_console = LOG_INFO; + + memset(&s->system_metrics, 0xFF, sizeof(s->system_metrics)); + memset(&s->runtime_metrics, 0xFF, sizeof(s->runtime_metrics)); + + server_parse_config_file(s); + server_parse_proc_cmdline(s); + + mkdir_p("/run/systemd/journal", 0755); + + s->user_journals = hashmap_new(trivial_hash_func, trivial_compare_func); + if (!s->user_journals) + return log_oom(); + + s->mmap = mmap_cache_new(); + if (!s->mmap) + return log_oom(); + + s->epoll_fd = epoll_create1(EPOLL_CLOEXEC); + if (s->epoll_fd < 0) { + log_error("Failed to create epoll object: %m"); + return -errno; + } + + n = sd_listen_fds(true); + if (n < 0) { + log_error("Failed to read listening file descriptors from environment: %s", strerror(-n)); + return n; + } + + for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd++) { + + if (sd_is_socket_unix(fd, SOCK_DGRAM, -1, "/run/systemd/journal/socket", 0) > 0) { + + if (s->native_fd >= 0) { + log_error("Too many native sockets passed."); + return -EINVAL; + } + + s->native_fd = fd; + + } else if (sd_is_socket_unix(fd, SOCK_STREAM, 1, "/run/systemd/journal/stdout", 0) > 0) { + + if (s->stdout_fd >= 0) { + log_error("Too many stdout sockets passed."); + return -EINVAL; + } + + s->stdout_fd = fd; + + } else if (sd_is_socket_unix(fd, SOCK_DGRAM, -1, "/dev/log", 0) > 0) { + + if (s->syslog_fd >= 0) { + log_error("Too many /dev/log sockets passed."); + return -EINVAL; + } + + s->syslog_fd = fd; + + } else { + log_error("Unknown socket passed."); + return -EINVAL; + } + } + + r = server_open_syslog_socket(s); + if (r < 0) + return r; + + r = server_open_native_socket(s); + if (r < 0) + return r; + + r = server_open_stdout_socket(s); + if (r < 0) + return r; + + r = server_open_dev_kmsg(s); + if (r < 0) + return r; + + r = server_open_kernel_seqnum(s); + if (r < 0) + return r; + + r = open_signalfd(s); + if (r < 0) + return r; + + s->udev = udev_new(); + if (!s->udev) + return -ENOMEM; + + s->rate_limit = journal_rate_limit_new(s->rate_limit_interval, s->rate_limit_burst); + if (!s->rate_limit) + return -ENOMEM; + + r = system_journal_open(s); + if (r < 0) + return r; + + return 0; +} + +void server_maybe_append_tags(Server *s) { +#ifdef HAVE_GCRYPT + JournalFile *f; + Iterator i; + usec_t n; + + n = now(CLOCK_REALTIME); + + if (s->system_journal) + journal_file_maybe_append_tag(s->system_journal, n); + + HASHMAP_FOREACH(f, s->user_journals, i) + journal_file_maybe_append_tag(f, n); +#endif +} + +void server_done(Server *s) { + JournalFile *f; + assert(s); + + while (s->stdout_streams) + stdout_stream_free(s->stdout_streams); + + if (s->system_journal) + journal_file_close(s->system_journal); + + if (s->runtime_journal) + journal_file_close(s->runtime_journal); + + while ((f = hashmap_steal_first(s->user_journals))) + journal_file_close(f); + + hashmap_free(s->user_journals); + + if (s->epoll_fd >= 0) + close_nointr_nofail(s->epoll_fd); + + if (s->signal_fd >= 0) + close_nointr_nofail(s->signal_fd); + + if (s->syslog_fd >= 0) + close_nointr_nofail(s->syslog_fd); + + if (s->native_fd >= 0) + close_nointr_nofail(s->native_fd); + + if (s->stdout_fd >= 0) + close_nointr_nofail(s->stdout_fd); + + if (s->dev_kmsg_fd >= 0) + close_nointr_nofail(s->dev_kmsg_fd); + + if (s->rate_limit) + journal_rate_limit_free(s->rate_limit); + + if (s->kernel_seqnum) + munmap(s->kernel_seqnum, sizeof(uint64_t)); + + free(s->buffer); + free(s->tty_path); + + if (s->mmap) + mmap_cache_unref(s->mmap); + + if (s->udev) + udev_unref(s->udev); +} diff --git a/src/journal/journald-server.h b/src/journal/journald-server.h new file mode 100644 index 000000000..9f50a29e5 --- /dev/null +++ b/src/journal/journald-server.h @@ -0,0 +1,152 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +#include +#include +#include +#include +#include + +#include "journal-file.h" +#include "hashmap.h" +#include "util.h" +#include "audit.h" +#include "journald-rate-limit.h" +#include "list.h" + +typedef enum Storage { + STORAGE_AUTO, + STORAGE_VOLATILE, + STORAGE_PERSISTENT, + STORAGE_NONE, + _STORAGE_MAX, + _STORAGE_INVALID = -1 +} Storage; + +typedef enum SplitMode { + SPLIT_LOGIN, + SPLIT_UID, + SPLIT_NONE, + _SPLIT_MAX, + _SPLIT_INVALID = -1 +} SplitMode; + +typedef struct StdoutStream StdoutStream; + +typedef struct Server { + int epoll_fd; + int signal_fd; + int syslog_fd; + int native_fd; + int stdout_fd; + int dev_kmsg_fd; + + JournalFile *runtime_journal; + JournalFile *system_journal; + Hashmap *user_journals; + + uint64_t seqnum; + + char *buffer; + size_t buffer_size; + + JournalRateLimit *rate_limit; + usec_t rate_limit_interval; + unsigned rate_limit_burst; + + JournalMetrics runtime_metrics; + JournalMetrics system_metrics; + + bool compress; + bool seal; + + bool forward_to_kmsg; + bool forward_to_syslog; + bool forward_to_console; + + unsigned n_forward_syslog_missed; + usec_t last_warn_forward_syslog_missed; + + uint64_t cached_available_space; + usec_t cached_available_space_timestamp; + + uint64_t var_available_timestamp; + + usec_t max_retention_usec; + usec_t max_file_usec; + usec_t oldest_file_usec; + + gid_t file_gid; + bool file_gid_valid; + + LIST_HEAD(StdoutStream, stdout_streams); + unsigned n_stdout_streams; + + char *tty_path; + + int max_level_store; + int max_level_syslog; + int max_level_kmsg; + int max_level_console; + + Storage storage; + SplitMode split_mode; + + MMapCache *mmap; + + bool dev_kmsg_readable; + + uint64_t *kernel_seqnum; + + struct udev *udev; +} Server; + +#define N_IOVEC_META_FIELDS 17 +#define N_IOVEC_KERNEL_FIELDS 64 +#define N_IOVEC_UDEV_FIELDS 32 + +void server_dispatch_message(Server *s, struct iovec *iovec, unsigned n, unsigned m, struct ucred *ucred, struct timeval *tv, const char *label, size_t label_len, const char *unit_id, int priority); +void server_driver_message(Server *s, sd_id128_t message_id, const char *format, ...); + +/* gperf lookup function */ +const struct ConfigPerfItem* journald_gperf_lookup(const char *key, unsigned length); + +int config_parse_storage(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); + +const char *storage_to_string(Storage s); +Storage storage_from_string(const char *s); + +int config_parse_split_mode(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); + +const char *split_mode_to_string(SplitMode s); +SplitMode split_mode_from_string(const char *s); + +void server_fix_perms(Server *s, JournalFile *f, uid_t uid); +bool shall_try_append_again(JournalFile *f, int r); +int server_init(Server *s); +void server_done(Server *s); +void server_vacuum(Server *s); +void server_rotate(Server *s); +int server_flush_to_var(Server *s); +int process_event(Server *s, struct epoll_event *ev); +void server_maybe_append_tags(Server *s); diff --git a/src/journal/journald-stream.c b/src/journal/journald-stream.c new file mode 100644 index 000000000..7b88f747d --- /dev/null +++ b/src/journal/journald-stream.c @@ -0,0 +1,459 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +#include +#include +#include +#include + +#ifdef HAVE_SELINUX +#include +#endif + +#include "socket-util.h" +#include "journald-server.h" +#include "journald-stream.h" +#include "journald-syslog.h" +#include "journald-kmsg.h" +#include "journald-console.h" + +#define STDOUT_STREAMS_MAX 4096 + +typedef enum StdoutStreamState { + STDOUT_STREAM_IDENTIFIER, + STDOUT_STREAM_UNIT_ID, + STDOUT_STREAM_PRIORITY, + STDOUT_STREAM_LEVEL_PREFIX, + STDOUT_STREAM_FORWARD_TO_SYSLOG, + STDOUT_STREAM_FORWARD_TO_KMSG, + STDOUT_STREAM_FORWARD_TO_CONSOLE, + STDOUT_STREAM_RUNNING +} StdoutStreamState; + +struct StdoutStream { + Server *server; + StdoutStreamState state; + + int fd; + + struct ucred ucred; +#ifdef HAVE_SELINUX + security_context_t security_context; +#endif + + char *identifier; + char *unit_id; + int priority; + bool level_prefix:1; + bool forward_to_syslog:1; + bool forward_to_kmsg:1; + bool forward_to_console:1; + + char buffer[LINE_MAX+1]; + size_t length; + + LIST_FIELDS(StdoutStream, stdout_stream); +}; + +static int stdout_stream_log(StdoutStream *s, const char *p) { + struct iovec iovec[N_IOVEC_META_FIELDS + 5]; + char *message = NULL, *syslog_priority = NULL, *syslog_facility = NULL, *syslog_identifier = NULL; + unsigned n = 0; + int priority; + char *label = NULL; + size_t label_len = 0; + + assert(s); + assert(p); + + if (isempty(p)) + return 0; + + priority = s->priority; + + if (s->level_prefix) + syslog_parse_priority((char**) &p, &priority); + + if (s->forward_to_syslog || s->server->forward_to_syslog) + server_forward_syslog(s->server, syslog_fixup_facility(priority), s->identifier, p, &s->ucred, NULL); + + if (s->forward_to_kmsg || s->server->forward_to_kmsg) + server_forward_kmsg(s->server, priority, s->identifier, p, &s->ucred); + + if (s->forward_to_console || s->server->forward_to_console) + server_forward_console(s->server, priority, s->identifier, p, &s->ucred); + + IOVEC_SET_STRING(iovec[n++], "_TRANSPORT=stdout"); + + if (asprintf(&syslog_priority, "PRIORITY=%i", priority & LOG_PRIMASK) >= 0) + IOVEC_SET_STRING(iovec[n++], syslog_priority); + + if (priority & LOG_FACMASK) + if (asprintf(&syslog_facility, "SYSLOG_FACILITY=%i", LOG_FAC(priority)) >= 0) + IOVEC_SET_STRING(iovec[n++], syslog_facility); + + if (s->identifier) { + syslog_identifier = strappend("SYSLOG_IDENTIFIER=", s->identifier); + if (syslog_identifier) + IOVEC_SET_STRING(iovec[n++], syslog_identifier); + } + + message = strappend("MESSAGE=", p); + if (message) + IOVEC_SET_STRING(iovec[n++], message); + +#ifdef HAVE_SELINUX + if (s->security_context) { + label = (char*) s->security_context; + label_len = strlen((char*) s->security_context); + } +#endif + + server_dispatch_message(s->server, iovec, n, ELEMENTSOF(iovec), &s->ucred, NULL, label, label_len, s->unit_id, priority); + + free(message); + free(syslog_priority); + free(syslog_facility); + free(syslog_identifier); + + return 0; +} + +static int stdout_stream_line(StdoutStream *s, char *p) { + int r; + + assert(s); + assert(p); + + p = strstrip(p); + + switch (s->state) { + + case STDOUT_STREAM_IDENTIFIER: + if (isempty(p)) + s->identifier = NULL; + else { + s->identifier = strdup(p); + if (!s->identifier) + return log_oom(); + } + + s->state = STDOUT_STREAM_UNIT_ID; + return 0; + + case STDOUT_STREAM_UNIT_ID: + if (s->ucred.uid == 0) { + if (isempty(p)) + s->unit_id = NULL; + else { + s->unit_id = strdup(p); + if (!s->unit_id) + return log_oom(); + } + } + + s->state = STDOUT_STREAM_PRIORITY; + return 0; + + case STDOUT_STREAM_PRIORITY: + r = safe_atoi(p, &s->priority); + if (r < 0 || s->priority <= 0 || s->priority >= 999) { + log_warning("Failed to parse log priority line."); + return -EINVAL; + } + + s->state = STDOUT_STREAM_LEVEL_PREFIX; + return 0; + + case STDOUT_STREAM_LEVEL_PREFIX: + r = parse_boolean(p); + if (r < 0) { + log_warning("Failed to parse level prefix line."); + return -EINVAL; + } + + s->level_prefix = !!r; + s->state = STDOUT_STREAM_FORWARD_TO_SYSLOG; + return 0; + + case STDOUT_STREAM_FORWARD_TO_SYSLOG: + r = parse_boolean(p); + if (r < 0) { + log_warning("Failed to parse forward to syslog line."); + return -EINVAL; + } + + s->forward_to_syslog = !!r; + s->state = STDOUT_STREAM_FORWARD_TO_KMSG; + return 0; + + case STDOUT_STREAM_FORWARD_TO_KMSG: + r = parse_boolean(p); + if (r < 0) { + log_warning("Failed to parse copy to kmsg line."); + return -EINVAL; + } + + s->forward_to_kmsg = !!r; + s->state = STDOUT_STREAM_FORWARD_TO_CONSOLE; + return 0; + + case STDOUT_STREAM_FORWARD_TO_CONSOLE: + r = parse_boolean(p); + if (r < 0) { + log_warning("Failed to parse copy to console line."); + return -EINVAL; + } + + s->forward_to_console = !!r; + s->state = STDOUT_STREAM_RUNNING; + return 0; + + case STDOUT_STREAM_RUNNING: + return stdout_stream_log(s, p); + } + + assert_not_reached("Unknown stream state"); +} + +static int stdout_stream_scan(StdoutStream *s, bool force_flush) { + char *p; + size_t remaining; + int r; + + assert(s); + + p = s->buffer; + remaining = s->length; + for (;;) { + char *end; + size_t skip; + + end = memchr(p, '\n', remaining); + if (end) + skip = end - p + 1; + else if (remaining >= sizeof(s->buffer) - 1) { + end = p + sizeof(s->buffer) - 1; + skip = remaining; + } else + break; + + *end = 0; + + r = stdout_stream_line(s, p); + if (r < 0) + return r; + + remaining -= skip; + p += skip; + } + + if (force_flush && remaining > 0) { + p[remaining] = 0; + r = stdout_stream_line(s, p); + if (r < 0) + return r; + + p += remaining; + remaining = 0; + } + + if (p > s->buffer) { + memmove(s->buffer, p, remaining); + s->length = remaining; + } + + return 0; +} + +int stdout_stream_process(StdoutStream *s) { + ssize_t l; + int r; + + assert(s); + + l = read(s->fd, s->buffer+s->length, sizeof(s->buffer)-1-s->length); + if (l < 0) { + + if (errno == EAGAIN) + return 0; + + log_warning("Failed to read from stream: %m"); + return -errno; + } + + if (l == 0) { + r = stdout_stream_scan(s, true); + if (r < 0) + return r; + + return 0; + } + + s->length += l; + r = stdout_stream_scan(s, false); + if (r < 0) + return r; + + return 1; + +} + +void stdout_stream_free(StdoutStream *s) { + assert(s); + + if (s->server) { + assert(s->server->n_stdout_streams > 0); + s->server->n_stdout_streams --; + LIST_REMOVE(StdoutStream, stdout_stream, s->server->stdout_streams, s); + } + + if (s->fd >= 0) { + if (s->server) + epoll_ctl(s->server->epoll_fd, EPOLL_CTL_DEL, s->fd, NULL); + + close_nointr_nofail(s->fd); + } + +#ifdef HAVE_SELINUX + if (s->security_context) + freecon(s->security_context); +#endif + + free(s->identifier); + free(s); +} + +int stdout_stream_new(Server *s) { + StdoutStream *stream; + int fd, r; + socklen_t len; + struct epoll_event ev; + + assert(s); + + fd = accept4(s->stdout_fd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC); + if (fd < 0) { + if (errno == EAGAIN) + return 0; + + log_error("Failed to accept stdout connection: %m"); + return -errno; + } + + if (s->n_stdout_streams >= STDOUT_STREAMS_MAX) { + log_warning("Too many stdout streams, refusing connection."); + close_nointr_nofail(fd); + return 0; + } + + stream = new0(StdoutStream, 1); + if (!stream) { + close_nointr_nofail(fd); + return log_oom(); + } + + stream->fd = fd; + + len = sizeof(stream->ucred); + if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &stream->ucred, &len) < 0) { + log_error("Failed to determine peer credentials: %m"); + r = -errno; + goto fail; + } + +#ifdef HAVE_SELINUX + if (getpeercon(fd, &stream->security_context) < 0 && errno != ENOPROTOOPT) + log_error("Failed to determine peer security context: %m"); +#endif + + if (shutdown(fd, SHUT_WR) < 0) { + log_error("Failed to shutdown writing side of socket: %m"); + r = -errno; + goto fail; + } + + zero(ev); + ev.data.ptr = stream; + ev.events = EPOLLIN; + if (epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0) { + log_error("Failed to add stream to event loop: %m"); + r = -errno; + goto fail; + } + + stream->server = s; + LIST_PREPEND(StdoutStream, stdout_stream, s->stdout_streams, stream); + s->n_stdout_streams ++; + + return 0; + +fail: + stdout_stream_free(stream); + return r; +} + +int server_open_stdout_socket(Server *s) { + union sockaddr_union sa; + int r; + struct epoll_event ev; + + assert(s); + + if (s->stdout_fd < 0) { + + s->stdout_fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0); + if (s->stdout_fd < 0) { + log_error("socket() failed: %m"); + return -errno; + } + + zero(sa); + sa.un.sun_family = AF_UNIX; + strncpy(sa.un.sun_path, "/run/systemd/journal/stdout", sizeof(sa.un.sun_path)); + + unlink(sa.un.sun_path); + + r = bind(s->stdout_fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path)); + if (r < 0) { + log_error("bind() failed: %m"); + return -errno; + } + + chmod(sa.un.sun_path, 0666); + + if (listen(s->stdout_fd, SOMAXCONN) < 0) { + log_error("liste() failed: %m"); + return -errno; + } + } else + fd_nonblock(s->stdout_fd, 1); + + zero(ev); + ev.events = EPOLLIN; + ev.data.fd = s->stdout_fd; + if (epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, s->stdout_fd, &ev) < 0) { + log_error("Failed to add stdout server fd to epoll object: %m"); + return -errno; + } + + return 0; +} diff --git a/src/journal/journald-stream.h b/src/journal/journald-stream.h new file mode 100644 index 000000000..dfb6267bf --- /dev/null +++ b/src/journal/journald-stream.h @@ -0,0 +1,30 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +#include "journald-server.h" + +int server_open_stdout_socket(Server *s); + +int stdout_stream_new(Server *s); +void stdout_stream_free(StdoutStream *s); +int stdout_stream_process(StdoutStream *s); diff --git a/src/journal/journald-syslog.c b/src/journal/journald-syslog.c new file mode 100644 index 000000000..afddca363 --- /dev/null +++ b/src/journal/journald-syslog.c @@ -0,0 +1,492 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +#include +#include +#include + +#include "systemd/sd-messages.h" +#include "socket-util.h" +#include "journald-server.h" +#include "journald-syslog.h" +#include "journald-kmsg.h" +#include "journald-console.h" + +/* Warn once every 30s if we missed syslog message */ +#define WARN_FORWARD_SYSLOG_MISSED_USEC (30 * USEC_PER_SEC) + +static void forward_syslog_iovec(Server *s, const struct iovec *iovec, unsigned n_iovec, struct ucred *ucred, struct timeval *tv) { + struct msghdr msghdr; + struct cmsghdr *cmsg; + union { + struct cmsghdr cmsghdr; + uint8_t buf[CMSG_SPACE(sizeof(struct ucred))]; + } control; + union sockaddr_union sa; + + assert(s); + assert(iovec); + assert(n_iovec > 0); + + zero(msghdr); + msghdr.msg_iov = (struct iovec*) iovec; + msghdr.msg_iovlen = n_iovec; + + zero(sa); + sa.un.sun_family = AF_UNIX; + strncpy(sa.un.sun_path, "/run/systemd/journal/syslog", sizeof(sa.un.sun_path)); + msghdr.msg_name = &sa; + msghdr.msg_namelen = offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path); + + if (ucred) { + zero(control); + msghdr.msg_control = &control; + msghdr.msg_controllen = sizeof(control); + + cmsg = CMSG_FIRSTHDR(&msghdr); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_CREDENTIALS; + cmsg->cmsg_len = CMSG_LEN(sizeof(struct ucred)); + memcpy(CMSG_DATA(cmsg), ucred, sizeof(struct ucred)); + msghdr.msg_controllen = cmsg->cmsg_len; + } + + /* Forward the syslog message we received via /dev/log to + * /run/systemd/syslog. Unfortunately we currently can't set + * the SO_TIMESTAMP auxiliary data, and hence we don't. */ + + if (sendmsg(s->syslog_fd, &msghdr, MSG_NOSIGNAL) >= 0) + return; + + /* The socket is full? I guess the syslog implementation is + * too slow, and we shouldn't wait for that... */ + if (errno == EAGAIN) { + s->n_forward_syslog_missed++; + return; + } + + if (ucred && errno == ESRCH) { + struct ucred u; + + /* Hmm, presumably the sender process vanished + * by now, so let's fix it as good as we + * can, and retry */ + + u = *ucred; + u.pid = getpid(); + memcpy(CMSG_DATA(cmsg), &u, sizeof(struct ucred)); + + if (sendmsg(s->syslog_fd, &msghdr, MSG_NOSIGNAL) >= 0) + return; + + if (errno == EAGAIN) { + s->n_forward_syslog_missed++; + return; + } + } + + if (errno != ENOENT) + log_debug("Failed to forward syslog message: %m"); +} + +static void forward_syslog_raw(Server *s, int priority, const char *buffer, struct ucred *ucred, struct timeval *tv) { + struct iovec iovec; + + assert(s); + assert(buffer); + + if (LOG_PRI(priority) > s->max_level_syslog) + return; + + IOVEC_SET_STRING(iovec, buffer); + forward_syslog_iovec(s, &iovec, 1, ucred, tv); +} + +void server_forward_syslog(Server *s, int priority, const char *identifier, const char *message, struct ucred *ucred, struct timeval *tv) { + struct iovec iovec[5]; + char header_priority[6], header_time[64], header_pid[16]; + int n = 0; + time_t t; + struct tm *tm; + char *ident_buf = NULL; + + assert(s); + assert(priority >= 0); + assert(priority <= 999); + assert(message); + + if (LOG_PRI(priority) > s->max_level_syslog) + return; + + /* First: priority field */ + snprintf(header_priority, sizeof(header_priority), "<%i>", priority); + char_array_0(header_priority); + IOVEC_SET_STRING(iovec[n++], header_priority); + + /* Second: timestamp */ + t = tv ? tv->tv_sec : ((time_t) (now(CLOCK_REALTIME) / USEC_PER_SEC)); + tm = localtime(&t); + if (!tm) + return; + if (strftime(header_time, sizeof(header_time), "%h %e %T ", tm) <= 0) + return; + IOVEC_SET_STRING(iovec[n++], header_time); + + /* Third: identifier and PID */ + if (ucred) { + if (!identifier) { + get_process_comm(ucred->pid, &ident_buf); + identifier = ident_buf; + } + + snprintf(header_pid, sizeof(header_pid), "[%lu]: ", (unsigned long) ucred->pid); + char_array_0(header_pid); + + if (identifier) + IOVEC_SET_STRING(iovec[n++], identifier); + + IOVEC_SET_STRING(iovec[n++], header_pid); + } else if (identifier) { + IOVEC_SET_STRING(iovec[n++], identifier); + IOVEC_SET_STRING(iovec[n++], ": "); + } + + /* Fourth: message */ + IOVEC_SET_STRING(iovec[n++], message); + + forward_syslog_iovec(s, iovec, n, ucred, tv); + + free(ident_buf); +} + +int syslog_fixup_facility(int priority) { + + if ((priority & LOG_FACMASK) == 0) + return (priority & LOG_PRIMASK) | LOG_USER; + + return priority; +} + +size_t syslog_parse_identifier(const char **buf, char **identifier, char **pid) { + const char *p; + char *t; + size_t l, e; + + assert(buf); + assert(identifier); + assert(pid); + + p = *buf; + + p += strspn(p, WHITESPACE); + l = strcspn(p, WHITESPACE); + + if (l <= 0 || + p[l-1] != ':') + return 0; + + e = l; + l--; + + if (p[l-1] == ']') { + size_t k = l-1; + + for (;;) { + + if (p[k] == '[') { + t = strndup(p+k+1, l-k-2); + if (t) + *pid = t; + + l = k; + break; + } + + if (k == 0) + break; + + k--; + } + } + + t = strndup(p, l); + if (t) + *identifier = t; + + e += strspn(p + e, WHITESPACE); + *buf = p + e; + return e; +} + +void syslog_parse_priority(char **p, int *priority) { + int a = 0, b = 0, c = 0; + int k; + + assert(p); + assert(*p); + assert(priority); + + if ((*p)[0] != '<') + return; + + if (!strchr(*p, '>')) + return; + + if ((*p)[2] == '>') { + c = undecchar((*p)[1]); + k = 3; + } else if ((*p)[3] == '>') { + b = undecchar((*p)[1]); + c = undecchar((*p)[2]); + k = 4; + } else if ((*p)[4] == '>') { + a = undecchar((*p)[1]); + b = undecchar((*p)[2]); + c = undecchar((*p)[3]); + k = 5; + } else + return; + + if (a < 0 || b < 0 || c < 0) + return; + + *priority = a*100+b*10+c; + *p += k; +} + +static void syslog_skip_date(char **buf) { + enum { + LETTER, + SPACE, + NUMBER, + SPACE_OR_NUMBER, + COLON + } sequence[] = { + LETTER, LETTER, LETTER, + SPACE, + SPACE_OR_NUMBER, NUMBER, + SPACE, + SPACE_OR_NUMBER, NUMBER, + COLON, + SPACE_OR_NUMBER, NUMBER, + COLON, + SPACE_OR_NUMBER, NUMBER, + SPACE + }; + + char *p; + unsigned i; + + assert(buf); + assert(*buf); + + p = *buf; + + for (i = 0; i < ELEMENTSOF(sequence); i++, p++) { + + if (!*p) + return; + + switch (sequence[i]) { + + case SPACE: + if (*p != ' ') + return; + break; + + case SPACE_OR_NUMBER: + if (*p == ' ') + break; + + /* fall through */ + + case NUMBER: + if (*p < '0' || *p > '9') + return; + + break; + + case LETTER: + if (!(*p >= 'A' && *p <= 'Z') && + !(*p >= 'a' && *p <= 'z')) + return; + + break; + + case COLON: + if (*p != ':') + return; + break; + + } + } + + *buf = p; +} + +void server_process_syslog_message( + Server *s, + const char *buf, + struct ucred *ucred, + struct timeval *tv, + const char *label, + size_t label_len) { + + char *message = NULL, *syslog_priority = NULL, *syslog_facility = NULL, *syslog_identifier = NULL, *syslog_pid = NULL; + struct iovec iovec[N_IOVEC_META_FIELDS + 6]; + unsigned n = 0; + int priority = LOG_USER | LOG_INFO; + char *identifier = NULL, *pid = NULL; + const char *orig; + + assert(s); + assert(buf); + + orig = buf; + syslog_parse_priority((char**) &buf, &priority); + + if (s->forward_to_syslog) + forward_syslog_raw(s, priority, orig, ucred, tv); + + syslog_skip_date((char**) &buf); + syslog_parse_identifier(&buf, &identifier, &pid); + + if (s->forward_to_kmsg) + server_forward_kmsg(s, priority, identifier, buf, ucred); + + if (s->forward_to_console) + server_forward_console(s, priority, identifier, buf, ucred); + + IOVEC_SET_STRING(iovec[n++], "_TRANSPORT=syslog"); + + if (asprintf(&syslog_priority, "PRIORITY=%i", priority & LOG_PRIMASK) >= 0) + IOVEC_SET_STRING(iovec[n++], syslog_priority); + + if (priority & LOG_FACMASK) + if (asprintf(&syslog_facility, "SYSLOG_FACILITY=%i", LOG_FAC(priority)) >= 0) + IOVEC_SET_STRING(iovec[n++], syslog_facility); + + if (identifier) { + syslog_identifier = strappend("SYSLOG_IDENTIFIER=", identifier); + if (syslog_identifier) + IOVEC_SET_STRING(iovec[n++], syslog_identifier); + } + + if (pid) { + syslog_pid = strappend("SYSLOG_PID=", pid); + if (syslog_pid) + IOVEC_SET_STRING(iovec[n++], syslog_pid); + } + + message = strappend("MESSAGE=", buf); + if (message) + IOVEC_SET_STRING(iovec[n++], message); + + server_dispatch_message(s, iovec, n, ELEMENTSOF(iovec), ucred, tv, label, label_len, NULL, priority); + + free(message); + free(identifier); + free(pid); + free(syslog_priority); + free(syslog_facility); + free(syslog_identifier); + free(syslog_pid); +} + +int server_open_syslog_socket(Server *s) { + union sockaddr_union sa; + int one, r; + struct epoll_event ev; + + assert(s); + + if (s->syslog_fd < 0) { + + s->syslog_fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0); + if (s->syslog_fd < 0) { + log_error("socket() failed: %m"); + return -errno; + } + + zero(sa); + sa.un.sun_family = AF_UNIX; + strncpy(sa.un.sun_path, "/dev/log", sizeof(sa.un.sun_path)); + + unlink(sa.un.sun_path); + + r = bind(s->syslog_fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path)); + if (r < 0) { + log_error("bind() failed: %m"); + return -errno; + } + + chmod(sa.un.sun_path, 0666); + } else + fd_nonblock(s->syslog_fd, 1); + + one = 1; + r = setsockopt(s->syslog_fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one)); + if (r < 0) { + log_error("SO_PASSCRED failed: %m"); + return -errno; + } + +#ifdef HAVE_SELINUX + one = 1; + r = setsockopt(s->syslog_fd, SOL_SOCKET, SO_PASSSEC, &one, sizeof(one)); + if (r < 0) + log_warning("SO_PASSSEC failed: %m"); +#endif + + one = 1; + r = setsockopt(s->syslog_fd, SOL_SOCKET, SO_TIMESTAMP, &one, sizeof(one)); + if (r < 0) { + log_error("SO_TIMESTAMP failed: %m"); + return -errno; + } + + zero(ev); + ev.events = EPOLLIN; + ev.data.fd = s->syslog_fd; + if (epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, s->syslog_fd, &ev) < 0) { + log_error("Failed to add syslog server fd to epoll object: %m"); + return -errno; + } + + return 0; +} + +void server_maybe_warn_forward_syslog_missed(Server *s) { + usec_t n; + assert(s); + + if (s->n_forward_syslog_missed <= 0) + return; + + n = now(CLOCK_MONOTONIC); + if (s->last_warn_forward_syslog_missed + WARN_FORWARD_SYSLOG_MISSED_USEC > n) + return; + + server_driver_message(s, SD_MESSAGE_FORWARD_SYSLOG_MISSED, "Forwarding to syslog missed %u messages.", s->n_forward_syslog_missed); + + s->n_forward_syslog_missed = 0; + s->last_warn_forward_syslog_missed = n; +} diff --git a/src/journal/journald-syslog.h b/src/journal/journald-syslog.h new file mode 100644 index 000000000..7ff215b52 --- /dev/null +++ b/src/journal/journald-syslog.h @@ -0,0 +1,36 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +#include "journald-server.h" + +int syslog_fixup_facility(int priority); + +void syslog_parse_priority(char **p, int *priority); +size_t syslog_parse_identifier(const char **buf, char **identifier, char **pid); + +void server_forward_syslog(Server *s, int priority, const char *identifier, const char *message, struct ucred *ucred, struct timeval *tv); + +void server_process_syslog_message(Server *s, const char *buf, struct ucred *ucred, struct timeval *tv, const char *label, size_t label_len); +int server_open_syslog_socket(Server *s); + +void server_maybe_warn_forward_syslog_missed(Server *s); diff --git a/src/journal/journald.c b/src/journal/journald.c new file mode 100644 index 000000000..d6b9be597 --- /dev/null +++ b/src/journal/journald.c @@ -0,0 +1,140 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +#include +#include +#include +#include + +#include +#include +#include + +#include "journal-authenticate.h" +#include "journald-server.h" +#include "journald-kmsg.h" +#include "journald-syslog.h" + +int main(int argc, char *argv[]) { + Server server; + int r; + + /* if (getppid() != 1) { */ + /* log_error("This program should be invoked by init only."); */ + /* return EXIT_FAILURE; */ + /* } */ + + if (argc > 1) { + log_error("This program does not take arguments."); + return EXIT_FAILURE; + } + + log_set_target(LOG_TARGET_SAFE); + log_set_facility(LOG_SYSLOG); + log_parse_environment(); + log_open(); + + umask(0022); + + r = server_init(&server); + if (r < 0) + goto finish; + + server_vacuum(&server); + server_flush_to_var(&server); + server_flush_dev_kmsg(&server); + + log_debug("systemd-journald running as pid %lu", (unsigned long) getpid()); + server_driver_message(&server, SD_MESSAGE_JOURNAL_START, "Journal started"); + + sd_notify(false, + "READY=1\n" + "STATUS=Processing requests..."); + + for (;;) { + struct epoll_event event; + int t = -1; + usec_t n; + + n = now(CLOCK_REALTIME); + + if (server.max_retention_usec > 0 && server.oldest_file_usec > 0) { + + /* The retention time is reached, so let's vacuum! */ + if (server.oldest_file_usec + server.max_retention_usec < n) { + log_info("Retention time reached."); + server_rotate(&server); + server_vacuum(&server); + continue; + } + + /* Calculate when to rotate the next time */ + t = (int) ((server.oldest_file_usec + server.max_retention_usec - n + USEC_PER_MSEC - 1) / USEC_PER_MSEC); + log_info("Sleeping for %i ms", t); + } + +#ifdef HAVE_GCRYPT + if (server.system_journal) { + usec_t u; + + if (journal_file_next_evolve_usec(server.system_journal, &u)) { + if (n >= u) + t = 0; + else + t = MIN(t, (int) ((u - n + USEC_PER_MSEC - 1) / USEC_PER_MSEC)); + } + } +#endif + + r = epoll_wait(server.epoll_fd, &event, 1, t); + if (r < 0) { + + if (errno == EINTR) + continue; + + log_error("epoll_wait() failed: %m"); + r = -errno; + goto finish; + } + + if (r > 0) { + r = process_event(&server, &event); + if (r < 0) + goto finish; + else if (r == 0) + break; + } + + server_maybe_append_tags(&server); + server_maybe_warn_forward_syslog_missed(&server); + } + + log_debug("systemd-journald stopped as pid %lu", (unsigned long) getpid()); + server_driver_message(&server, SD_MESSAGE_JOURNAL_STOP, "Journal stopped"); + +finish: + sd_notify(false, + "STATUS=Shutting down..."); + + server_done(&server); + + return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/src/journal/journald.conf b/src/journal/journald.conf new file mode 100644 index 000000000..948318bc6 --- /dev/null +++ b/src/journal/journald.conf @@ -0,0 +1,32 @@ +# This file is part of systemd. +# +# 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. +# +# See journald.conf(5) for details + +[Journal] +#Storage=auto +#Compress=yes +#Seal=yes +#SplitMode=login +#RateLimitInterval=10s +#RateLimitBurst=200 +#SystemMaxUse= +#SystemKeepFree= +#SystemMaxFileSize= +#RuntimeMaxUse= +#RuntimeKeepFree= +#RuntimeMaxFileSize= +#MaxRetentionSec= +#MaxFileSec=1month +#ForwardToSyslog=yes +#ForwardToKMsg=no +#ForwardToConsole=no +#TTYPath=/dev/console +#MaxLevelStore=debug +#MaxLevelSyslog=debug +#MaxLevelKMsg=notice +#MaxLevelConsole=info diff --git a/src/journal/libsystemd-journal.pc.in b/src/journal/libsystemd-journal.pc.in new file mode 100644 index 000000000..988359564 --- /dev/null +++ b/src/journal/libsystemd-journal.pc.in @@ -0,0 +1,19 @@ +# This file is part of systemd. +# +# 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. + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: systemd +Description: systemd Journal Utility Library +URL: @PACKAGE_URL@ +Version: @PACKAGE_VERSION@ +Requires: libsystemd-id128 = @PACKAGE_VERSION@ +Libs: -L${libdir} -lsystemd-journal +Cflags: -I${includedir} diff --git a/src/journal/libsystemd-journal.sym b/src/journal/libsystemd-journal.sym new file mode 100644 index 000000000..7b602f59c --- /dev/null +++ b/src/journal/libsystemd-journal.sym @@ -0,0 +1,91 @@ +/*** + This file is part of systemd. + + 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. +***/ + +/* Original symbols from systemd v38 */ + +LIBSYSTEMD_JOURNAL_38 { +global: + sd_journal_print; + sd_journal_printv; + sd_journal_send; + sd_journal_sendv; + sd_journal_stream_fd; + sd_journal_open; + sd_journal_close; + sd_journal_previous; + sd_journal_next; + sd_journal_previous_skip; + sd_journal_next_skip; + sd_journal_get_realtime_usec; + sd_journal_get_monotonic_usec; + sd_journal_get_data; + sd_journal_enumerate_data; + sd_journal_restart_data; + sd_journal_add_match; + sd_journal_flush_matches; + sd_journal_seek_head; + sd_journal_seek_tail; + sd_journal_seek_monotonic_usec; + sd_journal_seek_realtime_usec; + sd_journal_seek_cursor; + sd_journal_get_cursor; + sd_journal_get_fd; + sd_journal_process; +local: + *; +}; + +LIBSYSTEMD_JOURNAL_183 { +global: + sd_journal_print_with_location; + sd_journal_printv_with_location; + sd_journal_send_with_location; + sd_journal_sendv_with_location; +} LIBSYSTEMD_JOURNAL_38; + +LIBSYSTEMD_JOURNAL_184 { +global: + sd_journal_get_cutoff_realtime_usec; + sd_journal_get_cutoff_monotonic_usec; +} LIBSYSTEMD_JOURNAL_183; + +LIBSYSTEMD_JOURNAL_187 { +global: + sd_journal_wait; + sd_journal_open_directory; + sd_journal_add_disjunction; +} LIBSYSTEMD_JOURNAL_184; + +LIBSYSTEMD_JOURNAL_188 { +global: + sd_journal_perror; + sd_journal_perror_with_location; +} LIBSYSTEMD_JOURNAL_187; + +LIBSYSTEMD_JOURNAL_190 { +global: + sd_journal_get_usage; +} LIBSYSTEMD_JOURNAL_188; + +LIBSYSTEMD_JOURNAL_195 { +global: + sd_journal_test_cursor; + sd_journal_query_unique; + sd_journal_enumerate_unique; + sd_journal_restart_unique; +} LIBSYSTEMD_JOURNAL_190; + +LIBSYSTEMD_JOURNAL_196 { +global: + sd_journal_fd_reliable; + sd_journal_get_catalog; + sd_journal_get_catalog_for_message_id; + sd_journal_set_data_threshold; + sd_journal_get_data_threshold; +} LIBSYSTEMD_JOURNAL_195; diff --git a/src/journal/lookup3.c b/src/journal/lookup3.c new file mode 100644 index 000000000..52ffdf7b1 --- /dev/null +++ b/src/journal/lookup3.c @@ -0,0 +1,1009 @@ +/* Slightly modified by Lennart Poettering, to avoid name clashes, and + * unexport a few functions. */ + +#include "lookup3.h" + +/* +------------------------------------------------------------------------------- +lookup3.c, by Bob Jenkins, May 2006, Public Domain. + +These are functions for producing 32-bit hashes for hash table lookup. +hashword(), hashlittle(), hashlittle2(), hashbig(), mix(), and final() +are externally useful functions. Routines to test the hash are included +if SELF_TEST is defined. You can use this free for any purpose. It's in +the public domain. It has no warranty. + +You probably want to use hashlittle(). hashlittle() and hashbig() +hash byte arrays. hashlittle() is faster than hashbig() on +little-endian machines. Intel and AMD are little-endian machines. +On second thought, you probably want hashlittle2(), which is identical to +hashlittle() except it returns two 32-bit hashes for the price of one. +You could implement hashbig2() if you wanted but I haven't bothered here. + +If you want to find a hash of, say, exactly 7 integers, do + a = i1; b = i2; c = i3; + mix(a,b,c); + a += i4; b += i5; c += i6; + mix(a,b,c); + a += i7; + final(a,b,c); +then use c as the hash value. If you have a variable length array of +4-byte integers to hash, use hashword(). If you have a byte array (like +a character string), use hashlittle(). If you have several byte arrays, or +a mix of things, see the comments above hashlittle(). + +Why is this so big? I read 12 bytes at a time into 3 4-byte integers, +then mix those integers. This is fast (you can do a lot more thorough +mixing with 12*3 instructions on 3 integers than you can with 3 instructions +on 1 byte), but shoehorning those bytes into integers efficiently is messy. +------------------------------------------------------------------------------- +*/ +/* #define SELF_TEST 1 */ + +#include /* defines printf for tests */ +#include /* defines time_t for timings in the test */ +#include /* defines uint32_t etc */ +#include /* attempt to define endianness */ +#ifdef linux +# include /* attempt to define endianness */ +#endif + +/* + * My best guess at if you are big-endian or little-endian. This may + * need adjustment. + */ +#if (defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && \ + __BYTE_ORDER == __LITTLE_ENDIAN) || \ + (defined(i386) || defined(__i386__) || defined(__i486__) || \ + defined(__i586__) || defined(__i686__) || defined(vax) || defined(MIPSEL)) +# define HASH_LITTLE_ENDIAN 1 +# define HASH_BIG_ENDIAN 0 +#elif (defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && \ + __BYTE_ORDER == __BIG_ENDIAN) || \ + (defined(sparc) || defined(POWERPC) || defined(mc68000) || defined(sel)) +# define HASH_LITTLE_ENDIAN 0 +# define HASH_BIG_ENDIAN 1 +#else +# define HASH_LITTLE_ENDIAN 0 +# define HASH_BIG_ENDIAN 0 +#endif + +#define hashsize(n) ((uint32_t)1<<(n)) +#define hashmask(n) (hashsize(n)-1) +#define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k)))) + +/* +------------------------------------------------------------------------------- +mix -- mix 3 32-bit values reversibly. + +This is reversible, so any information in (a,b,c) before mix() is +still in (a,b,c) after mix(). + +If four pairs of (a,b,c) inputs are run through mix(), or through +mix() in reverse, there are at least 32 bits of the output that +are sometimes the same for one pair and different for another pair. +This was tested for: +* pairs that differed by one bit, by two bits, in any combination + of top bits of (a,b,c), or in any combination of bottom bits of + (a,b,c). +* "differ" is defined as +, -, ^, or ~^. For + and -, I transformed + the output delta to a Gray code (a^(a>>1)) so a string of 1's (as + is commonly produced by subtraction) look like a single 1-bit + difference. +* the base values were pseudorandom, all zero but one bit set, or + all zero plus a counter that starts at zero. + +Some k values for my "a-=c; a^=rot(c,k); c+=b;" arrangement that +satisfy this are + 4 6 8 16 19 4 + 9 15 3 18 27 15 + 14 9 3 7 17 3 +Well, "9 15 3 18 27 15" didn't quite get 32 bits diffing +for "differ" defined as + with a one-bit base and a two-bit delta. I +used http://burtleburtle.net/bob/hash/avalanche.html to choose +the operations, constants, and arrangements of the variables. + +This does not achieve avalanche. There are input bits of (a,b,c) +that fail to affect some output bits of (a,b,c), especially of a. The +most thoroughly mixed value is c, but it doesn't really even achieve +avalanche in c. + +This allows some parallelism. Read-after-writes are good at doubling +the number of bits affected, so the goal of mixing pulls in the opposite +direction as the goal of parallelism. I did what I could. Rotates +seem to cost as much as shifts on every machine I could lay my hands +on, and rotates are much kinder to the top and bottom bits, so I used +rotates. +------------------------------------------------------------------------------- +*/ +#define mix(a,b,c) \ +{ \ + a -= c; a ^= rot(c, 4); c += b; \ + b -= a; b ^= rot(a, 6); a += c; \ + c -= b; c ^= rot(b, 8); b += a; \ + a -= c; a ^= rot(c,16); c += b; \ + b -= a; b ^= rot(a,19); a += c; \ + c -= b; c ^= rot(b, 4); b += a; \ +} + +/* +------------------------------------------------------------------------------- +final -- final mixing of 3 32-bit values (a,b,c) into c + +Pairs of (a,b,c) values differing in only a few bits will usually +produce values of c that look totally different. This was tested for +* pairs that differed by one bit, by two bits, in any combination + of top bits of (a,b,c), or in any combination of bottom bits of + (a,b,c). +* "differ" is defined as +, -, ^, or ~^. For + and -, I transformed + the output delta to a Gray code (a^(a>>1)) so a string of 1's (as + is commonly produced by subtraction) look like a single 1-bit + difference. +* the base values were pseudorandom, all zero but one bit set, or + all zero plus a counter that starts at zero. + +These constants passed: + 14 11 25 16 4 14 24 + 12 14 25 16 4 14 24 +and these came close: + 4 8 15 26 3 22 24 + 10 8 15 26 3 22 24 + 11 8 15 26 3 22 24 +------------------------------------------------------------------------------- +*/ +#define final(a,b,c) \ +{ \ + c ^= b; c -= rot(b,14); \ + a ^= c; a -= rot(c,11); \ + b ^= a; b -= rot(a,25); \ + c ^= b; c -= rot(b,16); \ + a ^= c; a -= rot(c,4); \ + b ^= a; b -= rot(a,14); \ + c ^= b; c -= rot(b,24); \ +} + +/* +-------------------------------------------------------------------- + This works on all machines. To be useful, it requires + -- that the key be an array of uint32_t's, and + -- that the length be the number of uint32_t's in the key + + The function hashword() is identical to hashlittle() on little-endian + machines, and identical to hashbig() on big-endian machines, + except that the length has to be measured in uint32_ts rather than in + bytes. hashlittle() is more complicated than hashword() only because + hashlittle() has to dance around fitting the key bytes into registers. +-------------------------------------------------------------------- +*/ +uint32_t jenkins_hashword( +const uint32_t *k, /* the key, an array of uint32_t values */ +size_t length, /* the length of the key, in uint32_ts */ +uint32_t initval) /* the previous hash, or an arbitrary value */ +{ + uint32_t a,b,c; + + /* Set up the internal state */ + a = b = c = 0xdeadbeef + (((uint32_t)length)<<2) + initval; + + /*------------------------------------------------- handle most of the key */ + while (length > 3) + { + a += k[0]; + b += k[1]; + c += k[2]; + mix(a,b,c); + length -= 3; + k += 3; + } + + /*------------------------------------------- handle the last 3 uint32_t's */ + switch(length) /* all the case statements fall through */ + { + case 3 : c+=k[2]; + case 2 : b+=k[1]; + case 1 : a+=k[0]; + final(a,b,c); + case 0: /* case 0: nothing left to add */ + break; + } + /*------------------------------------------------------ report the result */ + return c; +} + + +/* +-------------------------------------------------------------------- +hashword2() -- same as hashword(), but take two seeds and return two +32-bit values. pc and pb must both be nonnull, and *pc and *pb must +both be initialized with seeds. If you pass in (*pb)==0, the output +(*pc) will be the same as the return value from hashword(). +-------------------------------------------------------------------- +*/ +void jenkins_hashword2 ( +const uint32_t *k, /* the key, an array of uint32_t values */ +size_t length, /* the length of the key, in uint32_ts */ +uint32_t *pc, /* IN: seed OUT: primary hash value */ +uint32_t *pb) /* IN: more seed OUT: secondary hash value */ +{ + uint32_t a,b,c; + + /* Set up the internal state */ + a = b = c = 0xdeadbeef + ((uint32_t)(length<<2)) + *pc; + c += *pb; + + /*------------------------------------------------- handle most of the key */ + while (length > 3) + { + a += k[0]; + b += k[1]; + c += k[2]; + mix(a,b,c); + length -= 3; + k += 3; + } + + /*------------------------------------------- handle the last 3 uint32_t's */ + switch(length) /* all the case statements fall through */ + { + case 3 : c+=k[2]; + case 2 : b+=k[1]; + case 1 : a+=k[0]; + final(a,b,c); + case 0: /* case 0: nothing left to add */ + break; + } + /*------------------------------------------------------ report the result */ + *pc=c; *pb=b; +} + + +/* +------------------------------------------------------------------------------- +hashlittle() -- hash a variable-length key into a 32-bit value + k : the key (the unaligned variable-length array of bytes) + length : the length of the key, counting by bytes + initval : can be any 4-byte value +Returns a 32-bit value. Every bit of the key affects every bit of +the return value. Two keys differing by one or two bits will have +totally different hash values. + +The best hash table sizes are powers of 2. There is no need to do +mod a prime (mod is sooo slow!). If you need less than 32 bits, +use a bitmask. For example, if you need only 10 bits, do + h = (h & hashmask(10)); +In which case, the hash table should have hashsize(10) elements. + +If you are hashing n strings (uint8_t **)k, do it like this: + for (i=0, h=0; i 12) + { + a += k[0]; + b += k[1]; + c += k[2]; + mix(a,b,c); + length -= 12; + k += 3; + } + + /*----------------------------- handle the last (probably partial) block */ + /* + * "k[2]&0xffffff" actually reads beyond the end of the string, but + * then masks off the part it's not allowed to read. Because the + * string is aligned, the masked-off tail is in the same word as the + * rest of the string. Every machine with memory protection I've seen + * does it on word boundaries, so is OK with this. But VALGRIND will + * still catch it and complain. The masking trick does make the hash + * noticeably faster for short strings (like English words). + */ +#ifndef VALGRIND + + switch(length) + { + case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; + case 11: c+=k[2]&0xffffff; b+=k[1]; a+=k[0]; break; + case 10: c+=k[2]&0xffff; b+=k[1]; a+=k[0]; break; + case 9 : c+=k[2]&0xff; b+=k[1]; a+=k[0]; break; + case 8 : b+=k[1]; a+=k[0]; break; + case 7 : b+=k[1]&0xffffff; a+=k[0]; break; + case 6 : b+=k[1]&0xffff; a+=k[0]; break; + case 5 : b+=k[1]&0xff; a+=k[0]; break; + case 4 : a+=k[0]; break; + case 3 : a+=k[0]&0xffffff; break; + case 2 : a+=k[0]&0xffff; break; + case 1 : a+=k[0]&0xff; break; + case 0 : return c; /* zero length strings require no mixing */ + } + +#else /* make valgrind happy */ + { + const uint8_t *k8 = (const uint8_t *) k; + + switch(length) + { + case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; + case 11: c+=((uint32_t)k8[10])<<16; /* fall through */ + case 10: c+=((uint32_t)k8[9])<<8; /* fall through */ + case 9 : c+=k8[8]; /* fall through */ + case 8 : b+=k[1]; a+=k[0]; break; + case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */ + case 6 : b+=((uint32_t)k8[5])<<8; /* fall through */ + case 5 : b+=k8[4]; /* fall through */ + case 4 : a+=k[0]; break; + case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */ + case 2 : a+=((uint32_t)k8[1])<<8; /* fall through */ + case 1 : a+=k8[0]; break; + case 0 : return c; + } + } + +#endif /* !valgrind */ + + } else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) { + const uint16_t *k = (const uint16_t *)key; /* read 16-bit chunks */ + const uint8_t *k8; + + /*--------------- all but last block: aligned reads and different mixing */ + while (length > 12) + { + a += k[0] + (((uint32_t)k[1])<<16); + b += k[2] + (((uint32_t)k[3])<<16); + c += k[4] + (((uint32_t)k[5])<<16); + mix(a,b,c); + length -= 12; + k += 6; + } + + /*----------------------------- handle the last (probably partial) block */ + k8 = (const uint8_t *)k; + switch(length) + { + case 12: c+=k[4]+(((uint32_t)k[5])<<16); + b+=k[2]+(((uint32_t)k[3])<<16); + a+=k[0]+(((uint32_t)k[1])<<16); + break; + case 11: c+=((uint32_t)k8[10])<<16; /* fall through */ + case 10: c+=k[4]; + b+=k[2]+(((uint32_t)k[3])<<16); + a+=k[0]+(((uint32_t)k[1])<<16); + break; + case 9 : c+=k8[8]; /* fall through */ + case 8 : b+=k[2]+(((uint32_t)k[3])<<16); + a+=k[0]+(((uint32_t)k[1])<<16); + break; + case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */ + case 6 : b+=k[2]; + a+=k[0]+(((uint32_t)k[1])<<16); + break; + case 5 : b+=k8[4]; /* fall through */ + case 4 : a+=k[0]+(((uint32_t)k[1])<<16); + break; + case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */ + case 2 : a+=k[0]; + break; + case 1 : a+=k8[0]; + break; + case 0 : return c; /* zero length requires no mixing */ + } + + } else { /* need to read the key one byte at a time */ + const uint8_t *k = (const uint8_t *)key; + + /*--------------- all but the last block: affect some 32 bits of (a,b,c) */ + while (length > 12) + { + a += k[0]; + a += ((uint32_t)k[1])<<8; + a += ((uint32_t)k[2])<<16; + a += ((uint32_t)k[3])<<24; + b += k[4]; + b += ((uint32_t)k[5])<<8; + b += ((uint32_t)k[6])<<16; + b += ((uint32_t)k[7])<<24; + c += k[8]; + c += ((uint32_t)k[9])<<8; + c += ((uint32_t)k[10])<<16; + c += ((uint32_t)k[11])<<24; + mix(a,b,c); + length -= 12; + k += 12; + } + + /*-------------------------------- last block: affect all 32 bits of (c) */ + switch(length) /* all the case statements fall through */ + { + case 12: c+=((uint32_t)k[11])<<24; + case 11: c+=((uint32_t)k[10])<<16; + case 10: c+=((uint32_t)k[9])<<8; + case 9 : c+=k[8]; + case 8 : b+=((uint32_t)k[7])<<24; + case 7 : b+=((uint32_t)k[6])<<16; + case 6 : b+=((uint32_t)k[5])<<8; + case 5 : b+=k[4]; + case 4 : a+=((uint32_t)k[3])<<24; + case 3 : a+=((uint32_t)k[2])<<16; + case 2 : a+=((uint32_t)k[1])<<8; + case 1 : a+=k[0]; + break; + case 0 : return c; + } + } + + final(a,b,c); + return c; +} + + +/* + * hashlittle2: return 2 32-bit hash values + * + * This is identical to hashlittle(), except it returns two 32-bit hash + * values instead of just one. This is good enough for hash table + * lookup with 2^^64 buckets, or if you want a second hash if you're not + * happy with the first, or if you want a probably-unique 64-bit ID for + * the key. *pc is better mixed than *pb, so use *pc first. If you want + * a 64-bit value do something like "*pc + (((uint64_t)*pb)<<32)". + */ +void jenkins_hashlittle2( + const void *key, /* the key to hash */ + size_t length, /* length of the key */ + uint32_t *pc, /* IN: primary initval, OUT: primary hash */ + uint32_t *pb) /* IN: secondary initval, OUT: secondary hash */ +{ + uint32_t a,b,c; /* internal state */ + union { const void *ptr; size_t i; } u; /* needed for Mac Powerbook G4 */ + + /* Set up the internal state */ + a = b = c = 0xdeadbeef + ((uint32_t)length) + *pc; + c += *pb; + + u.ptr = key; + if (HASH_LITTLE_ENDIAN && ((u.i & 0x3) == 0)) { + const uint32_t *k = (const uint32_t *)key; /* read 32-bit chunks */ + + /*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */ + while (length > 12) + { + a += k[0]; + b += k[1]; + c += k[2]; + mix(a,b,c); + length -= 12; + k += 3; + } + + /*----------------------------- handle the last (probably partial) block */ + /* + * "k[2]&0xffffff" actually reads beyond the end of the string, but + * then masks off the part it's not allowed to read. Because the + * string is aligned, the masked-off tail is in the same word as the + * rest of the string. Every machine with memory protection I've seen + * does it on word boundaries, so is OK with this. But VALGRIND will + * still catch it and complain. The masking trick does make the hash + * noticeably faster for short strings (like English words). + */ +#ifndef VALGRIND + + switch(length) + { + case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; + case 11: c+=k[2]&0xffffff; b+=k[1]; a+=k[0]; break; + case 10: c+=k[2]&0xffff; b+=k[1]; a+=k[0]; break; + case 9 : c+=k[2]&0xff; b+=k[1]; a+=k[0]; break; + case 8 : b+=k[1]; a+=k[0]; break; + case 7 : b+=k[1]&0xffffff; a+=k[0]; break; + case 6 : b+=k[1]&0xffff; a+=k[0]; break; + case 5 : b+=k[1]&0xff; a+=k[0]; break; + case 4 : a+=k[0]; break; + case 3 : a+=k[0]&0xffffff; break; + case 2 : a+=k[0]&0xffff; break; + case 1 : a+=k[0]&0xff; break; + case 0 : *pc=c; *pb=b; return; /* zero length strings require no mixing */ + } + +#else /* make valgrind happy */ + + { + const uint8_t *k8 = (const uint8_t *)k; + switch(length) + { + case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; + case 11: c+=((uint32_t)k8[10])<<16; /* fall through */ + case 10: c+=((uint32_t)k8[9])<<8; /* fall through */ + case 9 : c+=k8[8]; /* fall through */ + case 8 : b+=k[1]; a+=k[0]; break; + case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */ + case 6 : b+=((uint32_t)k8[5])<<8; /* fall through */ + case 5 : b+=k8[4]; /* fall through */ + case 4 : a+=k[0]; break; + case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */ + case 2 : a+=((uint32_t)k8[1])<<8; /* fall through */ + case 1 : a+=k8[0]; break; + case 0 : *pc=c; *pb=b; return; /* zero length strings require no mixing */ + } + } + +#endif /* !valgrind */ + + } else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) { + const uint16_t *k = (const uint16_t *)key; /* read 16-bit chunks */ + const uint8_t *k8; + + /*--------------- all but last block: aligned reads and different mixing */ + while (length > 12) + { + a += k[0] + (((uint32_t)k[1])<<16); + b += k[2] + (((uint32_t)k[3])<<16); + c += k[4] + (((uint32_t)k[5])<<16); + mix(a,b,c); + length -= 12; + k += 6; + } + + /*----------------------------- handle the last (probably partial) block */ + k8 = (const uint8_t *)k; + switch(length) + { + case 12: c+=k[4]+(((uint32_t)k[5])<<16); + b+=k[2]+(((uint32_t)k[3])<<16); + a+=k[0]+(((uint32_t)k[1])<<16); + break; + case 11: c+=((uint32_t)k8[10])<<16; /* fall through */ + case 10: c+=k[4]; + b+=k[2]+(((uint32_t)k[3])<<16); + a+=k[0]+(((uint32_t)k[1])<<16); + break; + case 9 : c+=k8[8]; /* fall through */ + case 8 : b+=k[2]+(((uint32_t)k[3])<<16); + a+=k[0]+(((uint32_t)k[1])<<16); + break; + case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */ + case 6 : b+=k[2]; + a+=k[0]+(((uint32_t)k[1])<<16); + break; + case 5 : b+=k8[4]; /* fall through */ + case 4 : a+=k[0]+(((uint32_t)k[1])<<16); + break; + case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */ + case 2 : a+=k[0]; + break; + case 1 : a+=k8[0]; + break; + case 0 : *pc=c; *pb=b; return; /* zero length strings require no mixing */ + } + + } else { /* need to read the key one byte at a time */ + const uint8_t *k = (const uint8_t *)key; + + /*--------------- all but the last block: affect some 32 bits of (a,b,c) */ + while (length > 12) + { + a += k[0]; + a += ((uint32_t)k[1])<<8; + a += ((uint32_t)k[2])<<16; + a += ((uint32_t)k[3])<<24; + b += k[4]; + b += ((uint32_t)k[5])<<8; + b += ((uint32_t)k[6])<<16; + b += ((uint32_t)k[7])<<24; + c += k[8]; + c += ((uint32_t)k[9])<<8; + c += ((uint32_t)k[10])<<16; + c += ((uint32_t)k[11])<<24; + mix(a,b,c); + length -= 12; + k += 12; + } + + /*-------------------------------- last block: affect all 32 bits of (c) */ + switch(length) /* all the case statements fall through */ + { + case 12: c+=((uint32_t)k[11])<<24; + case 11: c+=((uint32_t)k[10])<<16; + case 10: c+=((uint32_t)k[9])<<8; + case 9 : c+=k[8]; + case 8 : b+=((uint32_t)k[7])<<24; + case 7 : b+=((uint32_t)k[6])<<16; + case 6 : b+=((uint32_t)k[5])<<8; + case 5 : b+=k[4]; + case 4 : a+=((uint32_t)k[3])<<24; + case 3 : a+=((uint32_t)k[2])<<16; + case 2 : a+=((uint32_t)k[1])<<8; + case 1 : a+=k[0]; + break; + case 0 : *pc=c; *pb=b; return; /* zero length strings require no mixing */ + } + } + + final(a,b,c); + *pc=c; *pb=b; +} + + + +/* + * hashbig(): + * This is the same as hashword() on big-endian machines. It is different + * from hashlittle() on all machines. hashbig() takes advantage of + * big-endian byte ordering. + */ +uint32_t jenkins_hashbig( const void *key, size_t length, uint32_t initval) +{ + uint32_t a,b,c; + union { const void *ptr; size_t i; } u; /* to cast key to (size_t) happily */ + + /* Set up the internal state */ + a = b = c = 0xdeadbeef + ((uint32_t)length) + initval; + + u.ptr = key; + if (HASH_BIG_ENDIAN && ((u.i & 0x3) == 0)) { + const uint32_t *k = (const uint32_t *)key; /* read 32-bit chunks */ + + /*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */ + while (length > 12) + { + a += k[0]; + b += k[1]; + c += k[2]; + mix(a,b,c); + length -= 12; + k += 3; + } + + /*----------------------------- handle the last (probably partial) block */ + /* + * "k[2]<<8" actually reads beyond the end of the string, but + * then shifts out the part it's not allowed to read. Because the + * string is aligned, the illegal read is in the same word as the + * rest of the string. Every machine with memory protection I've seen + * does it on word boundaries, so is OK with this. But VALGRIND will + * still catch it and complain. The masking trick does make the hash + * noticeably faster for short strings (like English words). + */ +#ifndef VALGRIND + + switch(length) + { + case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; + case 11: c+=k[2]&0xffffff00; b+=k[1]; a+=k[0]; break; + case 10: c+=k[2]&0xffff0000; b+=k[1]; a+=k[0]; break; + case 9 : c+=k[2]&0xff000000; b+=k[1]; a+=k[0]; break; + case 8 : b+=k[1]; a+=k[0]; break; + case 7 : b+=k[1]&0xffffff00; a+=k[0]; break; + case 6 : b+=k[1]&0xffff0000; a+=k[0]; break; + case 5 : b+=k[1]&0xff000000; a+=k[0]; break; + case 4 : a+=k[0]; break; + case 3 : a+=k[0]&0xffffff00; break; + case 2 : a+=k[0]&0xffff0000; break; + case 1 : a+=k[0]&0xff000000; break; + case 0 : return c; /* zero length strings require no mixing */ + } + +#else /* make valgrind happy */ + + { + const uint8_t *k8 = (const uint8_t *)k; + switch(length) /* all the case statements fall through */ + { + case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; + case 11: c+=((uint32_t)k8[10])<<8; /* fall through */ + case 10: c+=((uint32_t)k8[9])<<16; /* fall through */ + case 9 : c+=((uint32_t)k8[8])<<24; /* fall through */ + case 8 : b+=k[1]; a+=k[0]; break; + case 7 : b+=((uint32_t)k8[6])<<8; /* fall through */ + case 6 : b+=((uint32_t)k8[5])<<16; /* fall through */ + case 5 : b+=((uint32_t)k8[4])<<24; /* fall through */ + case 4 : a+=k[0]; break; + case 3 : a+=((uint32_t)k8[2])<<8; /* fall through */ + case 2 : a+=((uint32_t)k8[1])<<16; /* fall through */ + case 1 : a+=((uint32_t)k8[0])<<24; break; + case 0 : return c; + } + } + +#endif /* !VALGRIND */ + + } else { /* need to read the key one byte at a time */ + const uint8_t *k = (const uint8_t *)key; + + /*--------------- all but the last block: affect some 32 bits of (a,b,c) */ + while (length > 12) + { + a += ((uint32_t)k[0])<<24; + a += ((uint32_t)k[1])<<16; + a += ((uint32_t)k[2])<<8; + a += ((uint32_t)k[3]); + b += ((uint32_t)k[4])<<24; + b += ((uint32_t)k[5])<<16; + b += ((uint32_t)k[6])<<8; + b += ((uint32_t)k[7]); + c += ((uint32_t)k[8])<<24; + c += ((uint32_t)k[9])<<16; + c += ((uint32_t)k[10])<<8; + c += ((uint32_t)k[11]); + mix(a,b,c); + length -= 12; + k += 12; + } + + /*-------------------------------- last block: affect all 32 bits of (c) */ + switch(length) /* all the case statements fall through */ + { + case 12: c+=k[11]; + case 11: c+=((uint32_t)k[10])<<8; + case 10: c+=((uint32_t)k[9])<<16; + case 9 : c+=((uint32_t)k[8])<<24; + case 8 : b+=k[7]; + case 7 : b+=((uint32_t)k[6])<<8; + case 6 : b+=((uint32_t)k[5])<<16; + case 5 : b+=((uint32_t)k[4])<<24; + case 4 : a+=k[3]; + case 3 : a+=((uint32_t)k[2])<<8; + case 2 : a+=((uint32_t)k[1])<<16; + case 1 : a+=((uint32_t)k[0])<<24; + break; + case 0 : return c; + } + } + + final(a,b,c); + return c; +} + + +#ifdef SELF_TEST + +/* used for timings */ +void driver1() +{ + uint8_t buf[256]; + uint32_t i; + uint32_t h=0; + time_t a,z; + + time(&a); + for (i=0; i<256; ++i) buf[i] = 'x'; + for (i=0; i<1; ++i) + { + h = hashlittle(&buf[0],1,h); + } + time(&z); + if (z-a > 0) printf("time %d %.8x\n", z-a, h); +} + +/* check that every input bit changes every output bit half the time */ +#define HASHSTATE 1 +#define HASHLEN 1 +#define MAXPAIR 60 +#define MAXLEN 70 +void driver2() +{ + uint8_t qa[MAXLEN+1], qb[MAXLEN+2], *a = &qa[0], *b = &qb[1]; + uint32_t c[HASHSTATE], d[HASHSTATE], i=0, j=0, k, l, m=0, z; + uint32_t e[HASHSTATE],f[HASHSTATE],g[HASHSTATE],h[HASHSTATE]; + uint32_t x[HASHSTATE],y[HASHSTATE]; + uint32_t hlen; + + printf("No more than %d trials should ever be needed \n",MAXPAIR/2); + for (hlen=0; hlen < MAXLEN; ++hlen) + { + z=0; + for (i=0; i>(8-j)); + c[0] = hashlittle(a, hlen, m); + b[i] ^= ((k+1)<>(8-j)); + d[0] = hashlittle(b, hlen, m); + /* check every bit is 1, 0, set, and not set at least once */ + for (l=0; lz) z=k; + if (k==MAXPAIR) + { + printf("Some bit didn't change: "); + printf("%.8x %.8x %.8x %.8x %.8x %.8x ", + e[0],f[0],g[0],h[0],x[0],y[0]); + printf("i %d j %d m %d len %d\n", i, j, m, hlen); + } + if (z==MAXPAIR) goto done; + } + } + } + done: + if (z < MAXPAIR) + { + printf("Mix success %2d bytes %2d initvals ",i,m); + printf("required %d trials\n", z/2); + } + } + printf("\n"); +} + +/* Check for reading beyond the end of the buffer and alignment problems */ +void driver3() +{ + uint8_t buf[MAXLEN+20], *b; + uint32_t len; + uint8_t q[] = "This is the time for all good men to come to the aid of their country..."; + uint32_t h; + uint8_t qq[] = "xThis is the time for all good men to come to the aid of their country..."; + uint32_t i; + uint8_t qqq[] = "xxThis is the time for all good men to come to the aid of their country..."; + uint32_t j; + uint8_t qqqq[] = "xxxThis is the time for all good men to come to the aid of their country..."; + uint32_t ref,x,y; + uint8_t *p; + + printf("Endianness. These lines should all be the same (for values filled in):\n"); + printf("%.8x %.8x %.8x\n", + hashword((const uint32_t *)q, (sizeof(q)-1)/4, 13), + hashword((const uint32_t *)q, (sizeof(q)-5)/4, 13), + hashword((const uint32_t *)q, (sizeof(q)-9)/4, 13)); + p = q; + printf("%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n", + hashlittle(p, sizeof(q)-1, 13), hashlittle(p, sizeof(q)-2, 13), + hashlittle(p, sizeof(q)-3, 13), hashlittle(p, sizeof(q)-4, 13), + hashlittle(p, sizeof(q)-5, 13), hashlittle(p, sizeof(q)-6, 13), + hashlittle(p, sizeof(q)-7, 13), hashlittle(p, sizeof(q)-8, 13), + hashlittle(p, sizeof(q)-9, 13), hashlittle(p, sizeof(q)-10, 13), + hashlittle(p, sizeof(q)-11, 13), hashlittle(p, sizeof(q)-12, 13)); + p = &qq[1]; + printf("%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n", + hashlittle(p, sizeof(q)-1, 13), hashlittle(p, sizeof(q)-2, 13), + hashlittle(p, sizeof(q)-3, 13), hashlittle(p, sizeof(q)-4, 13), + hashlittle(p, sizeof(q)-5, 13), hashlittle(p, sizeof(q)-6, 13), + hashlittle(p, sizeof(q)-7, 13), hashlittle(p, sizeof(q)-8, 13), + hashlittle(p, sizeof(q)-9, 13), hashlittle(p, sizeof(q)-10, 13), + hashlittle(p, sizeof(q)-11, 13), hashlittle(p, sizeof(q)-12, 13)); + p = &qqq[2]; + printf("%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n", + hashlittle(p, sizeof(q)-1, 13), hashlittle(p, sizeof(q)-2, 13), + hashlittle(p, sizeof(q)-3, 13), hashlittle(p, sizeof(q)-4, 13), + hashlittle(p, sizeof(q)-5, 13), hashlittle(p, sizeof(q)-6, 13), + hashlittle(p, sizeof(q)-7, 13), hashlittle(p, sizeof(q)-8, 13), + hashlittle(p, sizeof(q)-9, 13), hashlittle(p, sizeof(q)-10, 13), + hashlittle(p, sizeof(q)-11, 13), hashlittle(p, sizeof(q)-12, 13)); + p = &qqqq[3]; + printf("%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n", + hashlittle(p, sizeof(q)-1, 13), hashlittle(p, sizeof(q)-2, 13), + hashlittle(p, sizeof(q)-3, 13), hashlittle(p, sizeof(q)-4, 13), + hashlittle(p, sizeof(q)-5, 13), hashlittle(p, sizeof(q)-6, 13), + hashlittle(p, sizeof(q)-7, 13), hashlittle(p, sizeof(q)-8, 13), + hashlittle(p, sizeof(q)-9, 13), hashlittle(p, sizeof(q)-10, 13), + hashlittle(p, sizeof(q)-11, 13), hashlittle(p, sizeof(q)-12, 13)); + printf("\n"); + + /* check that hashlittle2 and hashlittle produce the same results */ + i=47; j=0; + hashlittle2(q, sizeof(q), &i, &j); + if (hashlittle(q, sizeof(q), 47) != i) + printf("hashlittle2 and hashlittle mismatch\n"); + + /* check that hashword2 and hashword produce the same results */ + len = 0xdeadbeef; + i=47, j=0; + hashword2(&len, 1, &i, &j); + if (hashword(&len, 1, 47) != i) + printf("hashword2 and hashword mismatch %x %x\n", + i, hashword(&len, 1, 47)); + + /* check hashlittle doesn't read before or after the ends of the string */ + for (h=0, b=buf+1; h<8; ++h, ++b) + { + for (i=0; i +#include + +uint32_t jenkins_hashword(const uint32_t *k, size_t length, uint32_t initval); +void jenkins_hashword2(const uint32_t *k, size_t length, uint32_t *pc, uint32_t *pb); + +uint32_t jenkins_hashlittle(const void *key, size_t length, uint32_t initval); +void jenkins_hashlittle2(const void *key, size_t length, uint32_t *pc, uint32_t *pb); + +uint32_t jenkins_hashbig(const void *key, size_t length, uint32_t initval); + +static inline uint64_t hash64(const void *data, size_t length) { + uint32_t a = 0, b = 0; + + jenkins_hashlittle2(data, length, &a, &b); + + return ((uint64_t) a << 32ULL) | (uint64_t) b; +} diff --git a/src/journal/mmap-cache.c b/src/journal/mmap-cache.c new file mode 100644 index 000000000..251aefe12 --- /dev/null +++ b/src/journal/mmap-cache.c @@ -0,0 +1,577 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + +#include +#include +#include +#include + +#include "hashmap.h" +#include "list.h" +#include "log.h" +#include "util.h" +#include "macro.h" +#include "mmap-cache.h" + +typedef struct Window Window; +typedef struct Context Context; +typedef struct FileDescriptor FileDescriptor; + +struct Window { + MMapCache *cache; + + bool keep_always; + bool in_unused; + + void *ptr; + uint64_t offset; + int prot; + size_t size; + + FileDescriptor *fd; + + LIST_FIELDS(Window, by_fd); + LIST_FIELDS(Window, unused); + + LIST_HEAD(Context, contexts); +}; + +struct Context { + MMapCache *cache; + unsigned id; + Window *window; + + LIST_FIELDS(Context, by_window); +}; + +struct FileDescriptor { + MMapCache *cache; + int fd; + LIST_HEAD(Window, windows); +}; + +struct MMapCache { + int n_ref; + + Hashmap *fds; + Hashmap *contexts; + + unsigned n_windows; + + LIST_HEAD(Window, unused); + Window *last_unused; +}; + +#define WINDOWS_MIN 64 +#define WINDOW_SIZE (8ULL*1024ULL*1024ULL) + +MMapCache* mmap_cache_new(void) { + MMapCache *m; + + m = new0(MMapCache, 1); + if (!m) + return NULL; + + m->n_ref = 1; + return m; +} + +MMapCache* mmap_cache_ref(MMapCache *m) { + assert(m); + assert(m->n_ref > 0); + + m->n_ref ++; + return m; +} + +static void window_unlink(Window *w) { + Context *c; + + assert(w); + + if (w->ptr) + munmap(w->ptr, w->size); + + if (w->fd) + LIST_REMOVE(Window, by_fd, w->fd->windows, w); + + if (w->in_unused) { + if (w->cache->last_unused == w) + w->cache->last_unused = w->unused_prev; + + LIST_REMOVE(Window, unused, w->cache->unused, w); + } + + LIST_FOREACH(by_window, c, w->contexts) { + assert(c->window == w); + c->window = NULL; + } +} + +static void window_free(Window *w) { + assert(w); + + window_unlink(w); + w->cache->n_windows--; + free(w); +} + +static bool window_matches(Window *w, int fd, int prot, uint64_t offset, size_t size) { + assert(w); + assert(fd >= 0); + assert(size > 0); + + return + w->fd && + fd == w->fd->fd && + prot == w->prot && + offset >= w->offset && + offset + size <= w->offset + w->size; +} + +static Window *window_add(MMapCache *m) { + Window *w; + + assert(m); + + if (!m->last_unused || m->n_windows <= WINDOWS_MIN) { + + /* Allocate a new window */ + w = new0(Window, 1); + if (!w) + return NULL; + m->n_windows++; + } else { + + /* Reuse an existing one */ + w = m->last_unused; + window_unlink(w); + zero(*w); + } + + w->cache = m; + return w; +} + +static void context_detach_window(Context *c) { + Window *w; + + assert(c); + + if (!c->window) + return; + + w = c->window; + c->window = NULL; + LIST_REMOVE(Context, by_window, w->contexts, c); + + if (!w->contexts && !w->keep_always) { + /* Not used anymore? */ + LIST_PREPEND(Window, unused, c->cache->unused, w); + if (!c->cache->last_unused) + c->cache->last_unused = w; + + w->in_unused = true; + } +} + +static void context_attach_window(Context *c, Window *w) { + assert(c); + assert(w); + + if (c->window == w) + return; + + context_detach_window(c); + + if (w->in_unused) { + /* Used again? */ + LIST_REMOVE(Window, unused, c->cache->unused, w); + if (c->cache->last_unused == w) + c->cache->last_unused = w->unused_prev; + + w->in_unused = false; + } + + c->window = w; + LIST_PREPEND(Context, by_window, w->contexts, c); +} + +static Context *context_add(MMapCache *m, unsigned id) { + Context *c; + int r; + + assert(m); + + c = hashmap_get(m->contexts, UINT_TO_PTR(id + 1)); + if (c) + return c; + + r = hashmap_ensure_allocated(&m->contexts, trivial_hash_func, trivial_compare_func); + if (r < 0) + return NULL; + + c = new0(Context, 1); + if (!c) + return NULL; + + c->cache = m; + c->id = id; + + r = hashmap_put(m->contexts, UINT_TO_PTR(id + 1), c); + if (r < 0) { + free(c); + return NULL; + } + + return c; +} + +static void context_free(Context *c) { + assert(c); + + context_detach_window(c); + + if (c->cache) + assert_se(hashmap_remove(c->cache->contexts, UINT_TO_PTR(c->id + 1))); + + free(c); +} + +static void fd_free(FileDescriptor *f) { + assert(f); + + while (f->windows) + window_free(f->windows); + + if (f->cache) + assert_se(hashmap_remove(f->cache->fds, INT_TO_PTR(f->fd + 1))); + + free(f); +} + +static FileDescriptor* fd_add(MMapCache *m, int fd) { + FileDescriptor *f; + int r; + + assert(m); + assert(fd >= 0); + + f = hashmap_get(m->fds, INT_TO_PTR(fd + 1)); + if (f) + return f; + + r = hashmap_ensure_allocated(&m->fds, trivial_hash_func, trivial_compare_func); + if (r < 0) + return NULL; + + f = new0(FileDescriptor, 1); + if (!f) + return NULL; + + f->cache = m; + f->fd = fd; + + r = hashmap_put(m->fds, UINT_TO_PTR(fd + 1), f); + if (r < 0) { + free(f); + return NULL; + } + + return f; +} + +static void mmap_cache_free(MMapCache *m) { + Context *c; + FileDescriptor *f; + + assert(m); + + while ((c = hashmap_first(m->contexts))) + context_free(c); + + while ((f = hashmap_first(m->fds))) + fd_free(f); + + while (m->unused) + window_free(m->unused); + + free(m); +} + +MMapCache* mmap_cache_unref(MMapCache *m) { + assert(m); + assert(m->n_ref > 0); + + m->n_ref --; + if (m->n_ref == 0) + mmap_cache_free(m); + + return NULL; +} + +static int make_room(MMapCache *m) { + assert(m); + + if (!m->last_unused) + return 0; + + window_free(m->last_unused); + return 1; +} + +static int try_context( + MMapCache *m, + int fd, + int prot, + unsigned context, + bool keep_always, + uint64_t offset, + size_t size, + void **ret) { + + Context *c; + + assert(m); + assert(m->n_ref > 0); + assert(fd >= 0); + assert(size > 0); + assert(ret); + + c = hashmap_get(m->contexts, UINT_TO_PTR(context+1)); + if (!c) + return 0; + + assert(c->id == context); + + if (!c->window) + return 0; + + if (!window_matches(c->window, fd, prot, offset, size)) { + + /* Drop the reference to the window, since it's unnecessary now */ + context_detach_window(c); + return 0; + } + + c->window->keep_always = c->window->keep_always || keep_always; + + *ret = (uint8_t*) c->window->ptr + (offset - c->window->offset); + return 1; +} + +static int find_mmap( + MMapCache *m, + int fd, + int prot, + unsigned context, + bool keep_always, + uint64_t offset, + size_t size, + void **ret) { + + FileDescriptor *f; + Window *w; + Context *c; + + assert(m); + assert(m->n_ref > 0); + assert(fd >= 0); + assert(size > 0); + assert(ret); + + f = hashmap_get(m->fds, INT_TO_PTR(fd + 1)); + if (!f) + return 0; + + assert(f->fd == fd); + + LIST_FOREACH(by_fd, w, f->windows) + if (window_matches(w, fd, prot, offset, size)) + break; + + if (!w) + return 0; + + c = context_add(m, context); + if (!c) + return -ENOMEM; + + context_attach_window(c, w); + w->keep_always = w->keep_always || keep_always; + + *ret = (uint8_t*) w->ptr + (offset - w->offset); + return 1; +} + +static int add_mmap( + MMapCache *m, + int fd, + int prot, + unsigned context, + bool keep_always, + uint64_t offset, + size_t size, + struct stat *st, + void **ret) { + + uint64_t woffset, wsize; + Context *c; + FileDescriptor *f; + Window *w; + void *d; + int r; + + assert(m); + assert(m->n_ref > 0); + assert(fd >= 0); + assert(size > 0); + assert(ret); + + woffset = offset & ~((uint64_t) page_size() - 1ULL); + wsize = size + (offset - woffset); + wsize = PAGE_ALIGN(wsize); + + if (wsize < WINDOW_SIZE) { + uint64_t delta; + + delta = PAGE_ALIGN((WINDOW_SIZE - wsize) / 2); + + if (delta > offset) + woffset = 0; + else + woffset -= delta; + + wsize = WINDOW_SIZE; + } + + if (st) { + /* Memory maps that are larger then the files + underneath have undefined behavior. Hence, clamp + things to the file size if we know it */ + + if (woffset >= (uint64_t) st->st_size) + return -EADDRNOTAVAIL; + + if (woffset + wsize > (uint64_t) st->st_size) + wsize = PAGE_ALIGN(st->st_size - woffset); + } + + for (;;) { + d = mmap(NULL, wsize, prot, MAP_SHARED, fd, woffset); + if (d != MAP_FAILED) + break; + if (errno != ENOMEM) + return -errno; + + r = make_room(m); + if (r < 0) + return r; + if (r == 0) + return -ENOMEM; + } + + c = context_add(m, context); + if (!c) + return -ENOMEM; + + f = fd_add(m, fd); + if (!f) + return -ENOMEM; + + w = window_add(m); + if (!w) + return -ENOMEM; + + w->keep_always = keep_always; + w->ptr = d; + w->offset = woffset; + w->prot = prot; + w->size = wsize; + w->fd = f; + + LIST_PREPEND(Window, by_fd, f->windows, w); + + context_detach_window(c); + c->window = w; + LIST_PREPEND(Context, by_window, w->contexts, c); + + *ret = (uint8_t*) w->ptr + (offset - w->offset); + return 1; +} + +int mmap_cache_get( + MMapCache *m, + int fd, + int prot, + unsigned context, + bool keep_always, + uint64_t offset, + size_t size, + struct stat *st, + void **ret) { + + int r; + + assert(m); + assert(m->n_ref > 0); + assert(fd >= 0); + assert(size > 0); + assert(ret); + + /* Check whether the current context is the right one already */ + r = try_context(m, fd, prot, context, keep_always, offset, size, ret); + if (r != 0) + return r; + + /* Search for a matching mmap */ + r = find_mmap(m, fd, prot, context, keep_always, offset, size, ret); + if (r != 0) + return r; + + /* Create a new mmap */ + return add_mmap(m, fd, prot, context, keep_always, offset, size, st, ret); +} + +void mmap_cache_close_fd(MMapCache *m, int fd) { + FileDescriptor *f; + + assert(m); + assert(fd >= 0); + + f = hashmap_get(m->fds, INT_TO_PTR(fd + 1)); + if (!f) + return; + + fd_free(f); +} + +void mmap_cache_close_context(MMapCache *m, unsigned context) { + Context *c; + + assert(m); + + c = hashmap_get(m->contexts, UINT_TO_PTR(context + 1)); + if (!c) + return; + + context_free(c); +} diff --git a/src/journal/mmap-cache.h b/src/journal/mmap-cache.h new file mode 100644 index 000000000..0c42fb88e --- /dev/null +++ b/src/journal/mmap-cache.h @@ -0,0 +1,36 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + +#include +#include +#include + +typedef struct MMapCache MMapCache; + +MMapCache* mmap_cache_new(void); +MMapCache* mmap_cache_ref(MMapCache *m); +MMapCache* mmap_cache_unref(MMapCache *m); + +int mmap_cache_get(MMapCache *m, int fd, int prot, unsigned context, bool keep_always, uint64_t offset, size_t size, struct stat *st, void **ret); +void mmap_cache_close_fd(MMapCache *m, int fd); +void mmap_cache_close_context(MMapCache *m, unsigned context); diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c new file mode 100644 index 000000000..095fbb249 --- /dev/null +++ b/src/journal/sd-journal.c @@ -0,0 +1,2480 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "sd-journal.h" +#include "journal-def.h" +#include "journal-file.h" +#include "hashmap.h" +#include "list.h" +#include "path-util.h" +#include "lookup3.h" +#include "compress.h" +#include "journal-internal.h" +#include "missing.h" +#include "catalog.h" +#include "replace-var.h" + +#define JOURNAL_FILES_MAX 1024 + +#define JOURNAL_FILES_RECHECK_USEC (2 * USEC_PER_SEC) + +#define REPLACE_VAR_MAX 256 + +#define DEFAULT_DATA_THRESHOLD (64*1024) + +static void detach_location(sd_journal *j) { + Iterator i; + JournalFile *f; + + assert(j); + + j->current_file = NULL; + j->current_field = 0; + + HASHMAP_FOREACH(f, j->files, i) + f->current_offset = 0; +} + +static void reset_location(sd_journal *j) { + assert(j); + + detach_location(j); + zero(j->current_location); +} + +static void init_location(Location *l, LocationType type, JournalFile *f, Object *o) { + assert(l); + assert(type == LOCATION_DISCRETE || type == LOCATION_SEEK); + assert(f); + assert(o->object.type == OBJECT_ENTRY); + + l->type = type; + l->seqnum = le64toh(o->entry.seqnum); + l->seqnum_id = f->header->seqnum_id; + l->realtime = le64toh(o->entry.realtime); + l->monotonic = le64toh(o->entry.monotonic); + l->boot_id = o->entry.boot_id; + l->xor_hash = le64toh(o->entry.xor_hash); + + l->seqnum_set = l->realtime_set = l->monotonic_set = l->xor_hash_set = true; +} + +static void set_location(sd_journal *j, LocationType type, JournalFile *f, Object *o, uint64_t offset) { + assert(j); + assert(type == LOCATION_DISCRETE || type == LOCATION_SEEK); + assert(f); + assert(o); + + init_location(&j->current_location, type, f, o); + + j->current_file = f; + j->current_field = 0; + + f->current_offset = offset; +} + +static int match_is_valid(const void *data, size_t size) { + const char *b, *p; + + assert(data); + + if (size < 2) + return false; + + if (startswith(data, "__")) + return false; + + b = data; + for (p = b; p < b + size; p++) { + + if (*p == '=') + return p > b; + + if (*p == '_') + continue; + + if (*p >= 'A' && *p <= 'Z') + continue; + + if (*p >= '0' && *p <= '9') + continue; + + return false; + } + + return false; +} + +static bool same_field(const void *_a, size_t s, const void *_b, size_t t) { + const uint8_t *a = _a, *b = _b; + size_t j; + + for (j = 0; j < s && j < t; j++) { + + if (a[j] != b[j]) + return false; + + if (a[j] == '=') + return true; + } + + return true; +} + +static Match *match_new(Match *p, MatchType t) { + Match *m; + + m = new0(Match, 1); + if (!m) + return NULL; + + m->type = t; + + if (p) { + m->parent = p; + LIST_PREPEND(Match, matches, p->matches, m); + } + + return m; +} + +static void match_free(Match *m) { + assert(m); + + while (m->matches) + match_free(m->matches); + + if (m->parent) + LIST_REMOVE(Match, matches, m->parent->matches, m); + + free(m->data); + free(m); +} + +static void match_free_if_empty(Match *m) { + assert(m); + + if (m->matches) + return; + + match_free(m); +} + +_public_ int sd_journal_add_match(sd_journal *j, const void *data, size_t size) { + Match *l2, *l3, *add_here = NULL, *m; + le64_t le_hash; + + if (!j) + return -EINVAL; + + if (!data) + return -EINVAL; + + if (size == 0) + size = strlen(data); + + if (!match_is_valid(data, size)) + return -EINVAL; + + /* level 0: OR term + * level 1: AND terms + * level 2: OR terms + * level 3: concrete matches */ + + if (!j->level0) { + j->level0 = match_new(NULL, MATCH_OR_TERM); + if (!j->level0) + return -ENOMEM; + } + + if (!j->level1) { + j->level1 = match_new(j->level0, MATCH_AND_TERM); + if (!j->level1) + return -ENOMEM; + } + + assert(j->level0->type == MATCH_OR_TERM); + assert(j->level1->type == MATCH_AND_TERM); + + le_hash = htole64(hash64(data, size)); + + LIST_FOREACH(matches, l2, j->level1->matches) { + assert(l2->type == MATCH_OR_TERM); + + LIST_FOREACH(matches, l3, l2->matches) { + assert(l3->type == MATCH_DISCRETE); + + /* Exactly the same match already? Then ignore + * this addition */ + if (l3->le_hash == le_hash && + l3->size == size && + memcmp(l3->data, data, size) == 0) + return 0; + + /* Same field? Then let's add this to this OR term */ + if (same_field(data, size, l3->data, l3->size)) { + add_here = l2; + break; + } + } + + if (add_here) + break; + } + + if (!add_here) { + add_here = match_new(j->level1, MATCH_OR_TERM); + if (!add_here) + goto fail; + } + + m = match_new(add_here, MATCH_DISCRETE); + if (!m) + goto fail; + + m->le_hash = le_hash; + m->size = size; + m->data = memdup(data, size); + if (!m->data) + goto fail; + + detach_location(j); + + return 0; + +fail: + if (add_here) + match_free_if_empty(add_here); + + if (j->level1) + match_free_if_empty(j->level1); + + if (j->level0) + match_free_if_empty(j->level0); + + return -ENOMEM; +} + +_public_ int sd_journal_add_disjunction(sd_journal *j) { + Match *m; + + assert(j); + + if (!j->level0) + return 0; + + if (!j->level1) + return 0; + + if (!j->level1->matches) + return 0; + + m = match_new(j->level0, MATCH_AND_TERM); + if (!m) + return -ENOMEM; + + j->level1 = m; + return 0; +} + +static char *match_make_string(Match *m) { + char *p, *r; + Match *i; + bool enclose = false; + + if (!m) + return strdup(""); + + if (m->type == MATCH_DISCRETE) + return strndup(m->data, m->size); + + p = NULL; + LIST_FOREACH(matches, i, m->matches) { + char *t, *k; + + t = match_make_string(i); + if (!t) { + free(p); + return NULL; + } + + if (p) { + k = strjoin(p, m->type == MATCH_OR_TERM ? " OR " : " AND ", t, NULL); + free(p); + free(t); + + if (!k) + return NULL; + + p = k; + + enclose = true; + } else { + free(p); + p = t; + } + } + + if (enclose) { + r = strjoin("(", p, ")", NULL); + free(p); + return r; + } + + return p; +} + +char *journal_make_match_string(sd_journal *j) { + assert(j); + + return match_make_string(j->level0); +} + +_public_ void sd_journal_flush_matches(sd_journal *j) { + + if (!j) + return; + + if (j->level0) + match_free(j->level0); + + j->level0 = j->level1 = NULL; + + detach_location(j); +} + +static int compare_entry_order(JournalFile *af, Object *_ao, + JournalFile *bf, uint64_t bp) { + + uint64_t a, b; + Object *ao, *bo; + int r; + + assert(af); + assert(bf); + assert(_ao); + + /* The mmap cache might invalidate the object from the first + * file if we look at the one from the second file. Hence + * temporarily copy the header of the first one, and look at + * that only. */ + ao = alloca(offsetof(EntryObject, items)); + memcpy(ao, _ao, offsetof(EntryObject, items)); + + r = journal_file_move_to_object(bf, OBJECT_ENTRY, bp, &bo); + if (r < 0) + return strcmp(af->path, bf->path); + + /* We operate on two different files here, hence we can access + * two objects at the same time, which we normally can't. + * + * If contents and timestamps match, these entries are + * identical, even if the seqnum does not match */ + + if (sd_id128_equal(ao->entry.boot_id, bo->entry.boot_id) && + ao->entry.monotonic == bo->entry.monotonic && + ao->entry.realtime == bo->entry.realtime && + ao->entry.xor_hash == bo->entry.xor_hash) + return 0; + + if (sd_id128_equal(af->header->seqnum_id, bf->header->seqnum_id)) { + + /* If this is from the same seqnum source, compare + * seqnums */ + a = le64toh(ao->entry.seqnum); + b = le64toh(bo->entry.seqnum); + + if (a < b) + return -1; + if (a > b) + return 1; + + /* Wow! This is weird, different data but the same + * seqnums? Something is borked, but let's make the + * best of it and compare by time. */ + } + + if (sd_id128_equal(ao->entry.boot_id, bo->entry.boot_id)) { + + /* If the boot id matches compare monotonic time */ + a = le64toh(ao->entry.monotonic); + b = le64toh(bo->entry.monotonic); + + if (a < b) + return -1; + if (a > b) + return 1; + } + + /* Otherwise compare UTC time */ + a = le64toh(ao->entry.realtime); + b = le64toh(bo->entry.realtime); + + if (a < b) + return -1; + if (a > b) + return 1; + + /* Finally, compare by contents */ + a = le64toh(ao->entry.xor_hash); + b = le64toh(bo->entry.xor_hash); + + if (a < b) + return -1; + if (a > b) + return 1; + + return 0; +} + +static int compare_with_location(JournalFile *af, Object *ao, Location *l) { + uint64_t a; + + assert(af); + assert(ao); + assert(l); + assert(l->type == LOCATION_DISCRETE || l->type == LOCATION_SEEK); + + if (l->monotonic_set && + sd_id128_equal(ao->entry.boot_id, l->boot_id) && + l->realtime_set && + le64toh(ao->entry.realtime) == l->realtime && + l->xor_hash_set && + le64toh(ao->entry.xor_hash) == l->xor_hash) + return 0; + + if (l->seqnum_set && + sd_id128_equal(af->header->seqnum_id, l->seqnum_id)) { + + a = le64toh(ao->entry.seqnum); + + if (a < l->seqnum) + return -1; + if (a > l->seqnum) + return 1; + } + + if (l->monotonic_set && + sd_id128_equal(ao->entry.boot_id, l->boot_id)) { + + a = le64toh(ao->entry.monotonic); + + if (a < l->monotonic) + return -1; + if (a > l->monotonic) + return 1; + } + + if (l->realtime_set) { + + a = le64toh(ao->entry.realtime); + + if (a < l->realtime) + return -1; + if (a > l->realtime) + return 1; + } + + if (l->xor_hash_set) { + a = le64toh(ao->entry.xor_hash); + + if (a < l->xor_hash) + return -1; + if (a > l->xor_hash) + return 1; + } + + return 0; +} + +static int next_for_match( + sd_journal *j, + Match *m, + JournalFile *f, + uint64_t after_offset, + direction_t direction, + Object **ret, + uint64_t *offset) { + + int r; + uint64_t np = 0; + Object *n; + + assert(j); + assert(m); + assert(f); + + if (m->type == MATCH_DISCRETE) { + uint64_t dp; + + r = journal_file_find_data_object_with_hash(f, m->data, m->size, le64toh(m->le_hash), NULL, &dp); + if (r <= 0) + return r; + + return journal_file_move_to_entry_by_offset_for_data(f, dp, after_offset, direction, ret, offset); + + } else if (m->type == MATCH_OR_TERM) { + Match *i; + + /* Find the earliest match beyond after_offset */ + + LIST_FOREACH(matches, i, m->matches) { + uint64_t cp; + + r = next_for_match(j, i, f, after_offset, direction, NULL, &cp); + if (r < 0) + return r; + else if (r > 0) { + if (np == 0 || (direction == DIRECTION_DOWN ? np > cp : np < cp)) + np = cp; + } + } + + } else if (m->type == MATCH_AND_TERM) { + Match *i; + bool continue_looking; + + /* Always jump to the next matching entry and repeat + * this until we fine and offset that matches for all + * matches. */ + + if (!m->matches) + return 0; + + np = 0; + do { + continue_looking = false; + + LIST_FOREACH(matches, i, m->matches) { + uint64_t cp, limit; + + if (np == 0) + limit = after_offset; + else if (direction == DIRECTION_DOWN) + limit = MAX(np, after_offset); + else + limit = MIN(np, after_offset); + + r = next_for_match(j, i, f, limit, direction, NULL, &cp); + if (r <= 0) + return r; + + if ((direction == DIRECTION_DOWN ? cp >= after_offset : cp <= after_offset) && + (np == 0 || (direction == DIRECTION_DOWN ? cp > np : np < cp))) { + np = cp; + continue_looking = true; + } + } + + } while (continue_looking); + } + + if (np == 0) + return 0; + + r = journal_file_move_to_object(f, OBJECT_ENTRY, np, &n); + if (r < 0) + return r; + + if (ret) + *ret = n; + if (offset) + *offset = np; + + return 1; +} + +static int find_location_for_match( + sd_journal *j, + Match *m, + JournalFile *f, + direction_t direction, + Object **ret, + uint64_t *offset) { + + int r; + + assert(j); + assert(m); + assert(f); + + if (m->type == MATCH_DISCRETE) { + uint64_t dp; + + r = journal_file_find_data_object_with_hash(f, m->data, m->size, le64toh(m->le_hash), NULL, &dp); + if (r <= 0) + return r; + + /* FIXME: missing: find by monotonic */ + + if (j->current_location.type == LOCATION_HEAD) + return journal_file_next_entry_for_data(f, NULL, 0, dp, DIRECTION_DOWN, ret, offset); + if (j->current_location.type == LOCATION_TAIL) + return journal_file_next_entry_for_data(f, NULL, 0, dp, DIRECTION_UP, ret, offset); + if (j->current_location.seqnum_set && sd_id128_equal(j->current_location.seqnum_id, f->header->seqnum_id)) + return journal_file_move_to_entry_by_seqnum_for_data(f, dp, j->current_location.seqnum, direction, ret, offset); + if (j->current_location.monotonic_set) { + r = journal_file_move_to_entry_by_monotonic_for_data(f, dp, j->current_location.boot_id, j->current_location.monotonic, direction, ret, offset); + if (r != -ENOENT) + return r; + } + if (j->current_location.realtime_set) + return journal_file_move_to_entry_by_realtime_for_data(f, dp, j->current_location.realtime, direction, ret, offset); + + return journal_file_next_entry_for_data(f, NULL, 0, dp, direction, ret, offset); + + } else if (m->type == MATCH_OR_TERM) { + uint64_t np = 0; + Object *n; + Match *i; + + /* Find the earliest match */ + + LIST_FOREACH(matches, i, m->matches) { + uint64_t cp; + + r = find_location_for_match(j, i, f, direction, NULL, &cp); + if (r < 0) + return r; + else if (r > 0) { + if (np == 0 || (direction == DIRECTION_DOWN ? np > cp : np < cp)) + np = cp; + } + } + + if (np == 0) + return 0; + + r = journal_file_move_to_object(f, OBJECT_ENTRY, np, &n); + if (r < 0) + return r; + + if (ret) + *ret = n; + if (offset) + *offset = np; + + return 1; + + } else { + Match *i; + uint64_t np = 0; + + assert(m->type == MATCH_AND_TERM); + + /* First jump to the last match, and then find the + * next one where all matches match */ + + if (!m->matches) + return 0; + + LIST_FOREACH(matches, i, m->matches) { + uint64_t cp; + + r = find_location_for_match(j, i, f, direction, NULL, &cp); + if (r <= 0) + return r; + + if (np == 0 || (direction == DIRECTION_DOWN ? np < cp : np > cp)) + np = cp; + } + + return next_for_match(j, m, f, np, direction, ret, offset); + } +} + +static int find_location_with_matches( + sd_journal *j, + JournalFile *f, + direction_t direction, + Object **ret, + uint64_t *offset) { + + int r; + + assert(j); + assert(f); + assert(ret); + assert(offset); + + if (!j->level0) { + /* No matches is simple */ + + if (j->current_location.type == LOCATION_HEAD) + return journal_file_next_entry(f, NULL, 0, DIRECTION_DOWN, ret, offset); + if (j->current_location.type == LOCATION_TAIL) + return journal_file_next_entry(f, NULL, 0, DIRECTION_UP, ret, offset); + if (j->current_location.seqnum_set && sd_id128_equal(j->current_location.seqnum_id, f->header->seqnum_id)) + return journal_file_move_to_entry_by_seqnum(f, j->current_location.seqnum, direction, ret, offset); + if (j->current_location.monotonic_set) { + r = journal_file_move_to_entry_by_monotonic(f, j->current_location.boot_id, j->current_location.monotonic, direction, ret, offset); + if (r != -ENOENT) + return r; + } + if (j->current_location.realtime_set) + return journal_file_move_to_entry_by_realtime(f, j->current_location.realtime, direction, ret, offset); + + return journal_file_next_entry(f, NULL, 0, direction, ret, offset); + } else + return find_location_for_match(j, j->level0, f, direction, ret, offset); +} + +static int next_with_matches( + sd_journal *j, + JournalFile *f, + direction_t direction, + Object **ret, + uint64_t *offset) { + + Object *c; + uint64_t cp; + + assert(j); + assert(f); + assert(ret); + assert(offset); + + c = *ret; + cp = *offset; + + /* No matches is easy. We simple advance the file + * pointer by one. */ + if (!j->level0) + return journal_file_next_entry(f, c, cp, direction, ret, offset); + + /* If we have a match then we look for the next matching entry + * with an offset at least one step larger */ + return next_for_match(j, j->level0, f, direction == DIRECTION_DOWN ? cp+1 : cp-1, direction, ret, offset); +} + +static int next_beyond_location(sd_journal *j, JournalFile *f, direction_t direction, Object **ret, uint64_t *offset) { + Object *c; + uint64_t cp; + int r; + + assert(j); + assert(f); + + if (f->current_offset > 0) { + cp = f->current_offset; + + r = journal_file_move_to_object(f, OBJECT_ENTRY, cp, &c); + if (r < 0) + return r; + + r = next_with_matches(j, f, direction, &c, &cp); + if (r <= 0) + return r; + } else { + r = find_location_with_matches(j, f, direction, &c, &cp); + if (r <= 0) + return r; + } + + /* OK, we found the spot, now let's advance until to an entry + * that is actually different from what we were previously + * looking at. This is necessary to handle entries which exist + * in two (or more) journal files, and which shall all be + * suppressed but one. */ + + for (;;) { + bool found; + + if (j->current_location.type == LOCATION_DISCRETE) { + int k; + + k = compare_with_location(f, c, &j->current_location); + if (direction == DIRECTION_DOWN) + found = k > 0; + else + found = k < 0; + } else + found = true; + + if (found) { + if (ret) + *ret = c; + if (offset) + *offset = cp; + return 1; + } + + r = next_with_matches(j, f, direction, &c, &cp); + if (r <= 0) + return r; + } +} + +static int real_journal_next(sd_journal *j, direction_t direction) { + JournalFile *f, *new_file = NULL; + uint64_t new_offset = 0; + Object *o; + uint64_t p; + Iterator i; + int r; + + if (!j) + return -EINVAL; + + HASHMAP_FOREACH(f, j->files, i) { + bool found; + + r = next_beyond_location(j, f, direction, &o, &p); + if (r < 0) { + log_debug("Can't iterate through %s, ignoring: %s", f->path, strerror(-r)); + continue; + } else if (r == 0) + continue; + + if (!new_file) + found = true; + else { + int k; + + k = compare_entry_order(f, o, new_file, new_offset); + + if (direction == DIRECTION_DOWN) + found = k < 0; + else + found = k > 0; + } + + if (found) { + new_file = f; + new_offset = p; + } + } + + if (!new_file) + return 0; + + r = journal_file_move_to_object(new_file, OBJECT_ENTRY, new_offset, &o); + if (r < 0) + return r; + + set_location(j, LOCATION_DISCRETE, new_file, o, new_offset); + + return 1; +} + +_public_ int sd_journal_next(sd_journal *j) { + return real_journal_next(j, DIRECTION_DOWN); +} + +_public_ int sd_journal_previous(sd_journal *j) { + return real_journal_next(j, DIRECTION_UP); +} + +static int real_journal_next_skip(sd_journal *j, direction_t direction, uint64_t skip) { + int c = 0, r; + + if (!j) + return -EINVAL; + + if (skip == 0) { + /* If this is not a discrete skip, then at least + * resolve the current location */ + if (j->current_location.type != LOCATION_DISCRETE) + return real_journal_next(j, direction); + + return 0; + } + + do { + r = real_journal_next(j, direction); + if (r < 0) + return r; + + if (r == 0) + return c; + + skip--; + c++; + } while (skip > 0); + + return c; +} + +_public_ int sd_journal_next_skip(sd_journal *j, uint64_t skip) { + return real_journal_next_skip(j, DIRECTION_DOWN, skip); +} + +_public_ int sd_journal_previous_skip(sd_journal *j, uint64_t skip) { + return real_journal_next_skip(j, DIRECTION_UP, skip); +} + +_public_ int sd_journal_get_cursor(sd_journal *j, char **cursor) { + Object *o; + int r; + char bid[33], sid[33]; + + if (!j) + return -EINVAL; + if (!cursor) + return -EINVAL; + + if (!j->current_file || j->current_file->current_offset <= 0) + return -EADDRNOTAVAIL; + + r = journal_file_move_to_object(j->current_file, OBJECT_ENTRY, j->current_file->current_offset, &o); + if (r < 0) + return r; + + sd_id128_to_string(j->current_file->header->seqnum_id, sid); + sd_id128_to_string(o->entry.boot_id, bid); + + if (asprintf(cursor, + "s=%s;i=%llx;b=%s;m=%llx;t=%llx;x=%llx", + sid, (unsigned long long) le64toh(o->entry.seqnum), + bid, (unsigned long long) le64toh(o->entry.monotonic), + (unsigned long long) le64toh(o->entry.realtime), + (unsigned long long) le64toh(o->entry.xor_hash)) < 0) + return -ENOMEM; + + return 1; +} + +_public_ int sd_journal_seek_cursor(sd_journal *j, const char *cursor) { + char *w, *state; + size_t l; + unsigned long long seqnum, monotonic, realtime, xor_hash; + bool + seqnum_id_set = false, + seqnum_set = false, + boot_id_set = false, + monotonic_set = false, + realtime_set = false, + xor_hash_set = false; + sd_id128_t seqnum_id, boot_id; + + if (!j) + return -EINVAL; + if (isempty(cursor)) + return -EINVAL; + + FOREACH_WORD_SEPARATOR(w, l, cursor, ";", state) { + char *item; + int k = 0; + + if (l < 2 || w[1] != '=') + return -EINVAL; + + item = strndup(w, l); + if (!item) + return -ENOMEM; + + switch (w[0]) { + + case 's': + seqnum_id_set = true; + k = sd_id128_from_string(item+2, &seqnum_id); + break; + + case 'i': + seqnum_set = true; + if (sscanf(item+2, "%llx", &seqnum) != 1) + k = -EINVAL; + break; + + case 'b': + boot_id_set = true; + k = sd_id128_from_string(item+2, &boot_id); + break; + + case 'm': + monotonic_set = true; + if (sscanf(item+2, "%llx", &monotonic) != 1) + k = -EINVAL; + break; + + case 't': + realtime_set = true; + if (sscanf(item+2, "%llx", &realtime) != 1) + k = -EINVAL; + break; + + case 'x': + xor_hash_set = true; + if (sscanf(item+2, "%llx", &xor_hash) != 1) + k = -EINVAL; + break; + } + + free(item); + + if (k < 0) + return k; + } + + if ((!seqnum_set || !seqnum_id_set) && + (!monotonic_set || !boot_id_set) && + !realtime_set) + return -EINVAL; + + reset_location(j); + + j->current_location.type = LOCATION_SEEK; + + if (realtime_set) { + j->current_location.realtime = (uint64_t) realtime; + j->current_location.realtime_set = true; + } + + if (seqnum_set && seqnum_id_set) { + j->current_location.seqnum = (uint64_t) seqnum; + j->current_location.seqnum_id = seqnum_id; + j->current_location.seqnum_set = true; + } + + if (monotonic_set && boot_id_set) { + j->current_location.monotonic = (uint64_t) monotonic; + j->current_location.boot_id = boot_id; + j->current_location.monotonic_set = true; + } + + if (xor_hash_set) { + j->current_location.xor_hash = (uint64_t) xor_hash; + j->current_location.xor_hash_set = true; + } + + return 0; +} + +_public_ int sd_journal_test_cursor(sd_journal *j, const char *cursor) { + int r; + char *w, *state; + size_t l; + Object *o; + + if (!j) + return -EINVAL; + if (isempty(cursor)) + return -EINVAL; + + if (!j->current_file || j->current_file->current_offset <= 0) + return -EADDRNOTAVAIL; + + r = journal_file_move_to_object(j->current_file, OBJECT_ENTRY, j->current_file->current_offset, &o); + if (r < 0) + return r; + + FOREACH_WORD_SEPARATOR(w, l, cursor, ";", state) { + _cleanup_free_ char *item = NULL; + sd_id128_t id; + unsigned long long ll; + int k = 0; + + if (l < 2 || w[1] != '=') + return -EINVAL; + + item = strndup(w, l); + if (!item) + return -ENOMEM; + + switch (w[0]) { + + case 's': + k = sd_id128_from_string(item+2, &id); + if (k < 0) + return k; + if (!sd_id128_equal(id, j->current_file->header->seqnum_id)) + return 0; + break; + + case 'i': + if (sscanf(item+2, "%llx", &ll) != 1) + return -EINVAL; + if (ll != le64toh(o->entry.seqnum)) + return 0; + break; + + case 'b': + k = sd_id128_from_string(item+2, &id); + if (k < 0) + return k; + if (!sd_id128_equal(id, o->entry.boot_id)) + return 0; + break; + + case 'm': + if (sscanf(item+2, "%llx", &ll) != 1) + return -EINVAL; + if (ll != le64toh(o->entry.monotonic)) + return 0; + break; + + case 't': + if (sscanf(item+2, "%llx", &ll) != 1) + return -EINVAL; + if (ll != le64toh(o->entry.realtime)) + return 0; + break; + + case 'x': + if (sscanf(item+2, "%llx", &ll) != 1) + return -EINVAL; + if (ll != le64toh(o->entry.xor_hash)) + return 0; + break; + } + } + + return 1; +} + + +_public_ int sd_journal_seek_monotonic_usec(sd_journal *j, sd_id128_t boot_id, uint64_t usec) { + if (!j) + return -EINVAL; + + reset_location(j); + j->current_location.type = LOCATION_SEEK; + j->current_location.boot_id = boot_id; + j->current_location.monotonic = usec; + j->current_location.monotonic_set = true; + + return 0; +} + +_public_ int sd_journal_seek_realtime_usec(sd_journal *j, uint64_t usec) { + if (!j) + return -EINVAL; + + reset_location(j); + j->current_location.type = LOCATION_SEEK; + j->current_location.realtime = usec; + j->current_location.realtime_set = true; + + return 0; +} + +_public_ int sd_journal_seek_head(sd_journal *j) { + if (!j) + return -EINVAL; + + reset_location(j); + j->current_location.type = LOCATION_HEAD; + + return 0; +} + +_public_ int sd_journal_seek_tail(sd_journal *j) { + if (!j) + return -EINVAL; + + reset_location(j); + j->current_location.type = LOCATION_TAIL; + + return 0; +} + +static void check_network(sd_journal *j, int fd) { + struct statfs sfs; + + assert(j); + + if (j->on_network) + return; + + if (fstatfs(fd, &sfs) < 0) + return; + + j->on_network = + (long)sfs.f_type == (long)CIFS_MAGIC_NUMBER || + sfs.f_type == CODA_SUPER_MAGIC || + sfs.f_type == NCP_SUPER_MAGIC || + sfs.f_type == NFS_SUPER_MAGIC || + sfs.f_type == SMB_SUPER_MAGIC; +} + +static int add_file(sd_journal *j, const char *prefix, const char *filename) { + char *path; + int r; + JournalFile *f; + + assert(j); + assert(prefix); + assert(filename); + + if ((j->flags & SD_JOURNAL_SYSTEM_ONLY) && + !(streq(filename, "system.journal") || + streq(filename, "system.journal~") || + (startswith(filename, "system@") && + (endswith(filename, ".journal") || endswith(filename, ".journal~"))))) + return 0; + + path = strjoin(prefix, "/", filename, NULL); + if (!path) + return -ENOMEM; + + if (hashmap_get(j->files, path)) { + free(path); + return 0; + } + + if (hashmap_size(j->files) >= JOURNAL_FILES_MAX) { + log_debug("Too many open journal files, not adding %s, ignoring.", path); + free(path); + return 0; + } + + r = journal_file_open(path, O_RDONLY, 0, false, false, NULL, j->mmap, NULL, &f); + free(path); + + if (r < 0) { + if (errno == ENOENT) + return 0; + + return r; + } + + /* journal_file_dump(f); */ + + r = hashmap_put(j->files, f->path, f); + if (r < 0) { + journal_file_close(f); + return r; + } + + check_network(j, f->fd); + + j->current_invalidate_counter ++; + + log_debug("File %s got added.", f->path); + + return 0; +} + +static int remove_file(sd_journal *j, const char *prefix, const char *filename) { + char *path; + JournalFile *f; + + assert(j); + assert(prefix); + assert(filename); + + path = strjoin(prefix, "/", filename, NULL); + if (!path) + return -ENOMEM; + + f = hashmap_get(j->files, path); + free(path); + if (!f) + return 0; + + hashmap_remove(j->files, f->path); + + log_debug("File %s got removed.", f->path); + + if (j->current_file == f) { + j->current_file = NULL; + j->current_field = 0; + } + + if (j->unique_file == f) { + j->unique_file = NULL; + j->unique_offset = 0; + } + + journal_file_close(f); + + j->current_invalidate_counter ++; + + return 0; +} + +static int add_directory(sd_journal *j, const char *prefix, const char *dirname) { + char *path; + int r; + DIR *d; + sd_id128_t id, mid; + Directory *m; + + assert(j); + assert(prefix); + assert(dirname); + + if ((j->flags & SD_JOURNAL_LOCAL_ONLY) && + (sd_id128_from_string(dirname, &id) < 0 || + sd_id128_get_machine(&mid) < 0 || + !sd_id128_equal(id, mid))) + return 0; + + path = strjoin(prefix, "/", dirname, NULL); + if (!path) + return -ENOMEM; + + d = opendir(path); + if (!d) { + log_debug("Failed to open %s: %m", path); + free(path); + + if (errno == ENOENT) + return 0; + return -errno; + } + + m = hashmap_get(j->directories_by_path, path); + if (!m) { + m = new0(Directory, 1); + if (!m) { + closedir(d); + free(path); + return -ENOMEM; + } + + m->is_root = false; + m->path = path; + + if (hashmap_put(j->directories_by_path, m->path, m) < 0) { + closedir(d); + free(m->path); + free(m); + return -ENOMEM; + } + + j->current_invalidate_counter ++; + + log_debug("Directory %s got added.", m->path); + + } else if (m->is_root) { + free (path); + closedir(d); + return 0; + } else + free(path); + + if (m->wd <= 0 && j->inotify_fd >= 0) { + + m->wd = inotify_add_watch(j->inotify_fd, m->path, + IN_CREATE|IN_MOVED_TO|IN_MODIFY|IN_ATTRIB|IN_DELETE| + IN_DELETE_SELF|IN_MOVE_SELF|IN_UNMOUNT|IN_MOVED_FROM| + IN_ONLYDIR); + + if (m->wd > 0 && hashmap_put(j->directories_by_wd, INT_TO_PTR(m->wd), m) < 0) + inotify_rm_watch(j->inotify_fd, m->wd); + } + + for (;;) { + struct dirent *de; + union dirent_storage buf; + + r = readdir_r(d, &buf.de, &de); + if (r != 0 || !de) + break; + + if (dirent_is_file_with_suffix(de, ".journal") || + dirent_is_file_with_suffix(de, ".journal~")) { + r = add_file(j, m->path, de->d_name); + if (r < 0) + log_debug("Failed to add file %s/%s: %s", m->path, de->d_name, strerror(-r)); + } + } + + check_network(j, dirfd(d)); + + closedir(d); + + return 0; +} + +static int add_root_directory(sd_journal *j, const char *p) { + DIR *d; + Directory *m; + int r; + + assert(j); + assert(p); + + if ((j->flags & SD_JOURNAL_RUNTIME_ONLY) && + !path_startswith(p, "/run")) + return -EINVAL; + + d = opendir(p); + if (!d) + return -errno; + + m = hashmap_get(j->directories_by_path, p); + if (!m) { + m = new0(Directory, 1); + if (!m) { + closedir(d); + return -ENOMEM; + } + + m->is_root = true; + m->path = strdup(p); + if (!m->path) { + closedir(d); + free(m); + return -ENOMEM; + } + + if (hashmap_put(j->directories_by_path, m->path, m) < 0) { + closedir(d); + free(m->path); + free(m); + return -ENOMEM; + } + + j->current_invalidate_counter ++; + + log_debug("Root directory %s got added.", m->path); + + } else if (!m->is_root) { + closedir(d); + return 0; + } + + if (m->wd <= 0 && j->inotify_fd >= 0) { + + m->wd = inotify_add_watch(j->inotify_fd, m->path, + IN_CREATE|IN_MOVED_TO|IN_MODIFY|IN_ATTRIB|IN_DELETE| + IN_ONLYDIR); + + if (m->wd > 0 && hashmap_put(j->directories_by_wd, INT_TO_PTR(m->wd), m) < 0) + inotify_rm_watch(j->inotify_fd, m->wd); + } + + for (;;) { + struct dirent *de; + union dirent_storage buf; + sd_id128_t id; + + r = readdir_r(d, &buf.de, &de); + if (r != 0 || !de) + break; + + if (dirent_is_file_with_suffix(de, ".journal") || + dirent_is_file_with_suffix(de, ".journal~")) { + r = add_file(j, m->path, de->d_name); + if (r < 0) + log_debug("Failed to add file %s/%s: %s", m->path, de->d_name, strerror(-r)); + + } else if ((de->d_type == DT_DIR || de->d_type == DT_LNK || de->d_type == DT_UNKNOWN) && + sd_id128_from_string(de->d_name, &id) >= 0) { + + r = add_directory(j, m->path, de->d_name); + if (r < 0) + log_debug("Failed to add directory %s/%s: %s", m->path, de->d_name, strerror(-r)); + } + } + + check_network(j, dirfd(d)); + + closedir(d); + + return 0; +} + +static int remove_directory(sd_journal *j, Directory *d) { + assert(j); + + if (d->wd > 0) { + hashmap_remove(j->directories_by_wd, INT_TO_PTR(d->wd)); + + if (j->inotify_fd >= 0) + inotify_rm_watch(j->inotify_fd, d->wd); + } + + hashmap_remove(j->directories_by_path, d->path); + + if (d->is_root) + log_debug("Root directory %s got removed.", d->path); + else + log_debug("Directory %s got removed.", d->path); + + free(d->path); + free(d); + + return 0; +} + +static int add_search_paths(sd_journal *j) { + + const char search_paths[] = + "/run/log/journal\0" + "/var/log/journal\0"; + const char *p; + + assert(j); + + /* We ignore most errors here, since the idea is to only open + * what's actually accessible, and ignore the rest. */ + + NULSTR_FOREACH(p, search_paths) + add_root_directory(j, p); + + return 0; +} + +static int allocate_inotify(sd_journal *j) { + assert(j); + + if (j->inotify_fd < 0) { + j->inotify_fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC); + if (j->inotify_fd < 0) + return -errno; + } + + if (!j->directories_by_wd) { + j->directories_by_wd = hashmap_new(trivial_hash_func, trivial_compare_func); + if (!j->directories_by_wd) + return -ENOMEM; + } + + return 0; +} + +static sd_journal *journal_new(int flags, const char *path) { + sd_journal *j; + + j = new0(sd_journal, 1); + if (!j) + return NULL; + + j->inotify_fd = -1; + j->flags = flags; + j->data_threshold = DEFAULT_DATA_THRESHOLD; + + if (path) { + j->path = strdup(path); + if (!j->path) { + free(j); + return NULL; + } + } + + j->files = hashmap_new(string_hash_func, string_compare_func); + if (!j->files) { + free(j->path); + free(j); + return NULL; + } + + j->directories_by_path = hashmap_new(string_hash_func, string_compare_func); + if (!j->directories_by_path) { + hashmap_free(j->files); + free(j->path); + free(j); + return NULL; + } + + j->mmap = mmap_cache_new(); + if (!j->mmap) { + hashmap_free(j->files); + hashmap_free(j->directories_by_path); + free(j->path); + free(j); + return NULL; + } + + return j; +} + +_public_ int sd_journal_open(sd_journal **ret, int flags) { + sd_journal *j; + int r; + + if (!ret) + return -EINVAL; + + if (flags & ~(SD_JOURNAL_LOCAL_ONLY| + SD_JOURNAL_RUNTIME_ONLY| + SD_JOURNAL_SYSTEM_ONLY)) + return -EINVAL; + + j = journal_new(flags, NULL); + if (!j) + return -ENOMEM; + + r = add_search_paths(j); + if (r < 0) + goto fail; + + *ret = j; + return 0; + +fail: + sd_journal_close(j); + + return r; +} + +_public_ int sd_journal_open_directory(sd_journal **ret, const char *path, int flags) { + sd_journal *j; + int r; + + if (!ret) + return -EINVAL; + + if (!path || !path_is_absolute(path)) + return -EINVAL; + + if (flags != 0) + return -EINVAL; + + j = journal_new(flags, path); + if (!j) + return -ENOMEM; + + r = add_root_directory(j, path); + if (r < 0) + goto fail; + + *ret = j; + return 0; + +fail: + sd_journal_close(j); + + return r; +} + +_public_ void sd_journal_close(sd_journal *j) { + Directory *d; + JournalFile *f; + + if (!j) + return; + + while ((f = hashmap_steal_first(j->files))) + journal_file_close(f); + + hashmap_free(j->files); + + while ((d = hashmap_first(j->directories_by_path))) + remove_directory(j, d); + + while ((d = hashmap_first(j->directories_by_wd))) + remove_directory(j, d); + + hashmap_free(j->directories_by_path); + hashmap_free(j->directories_by_wd); + + if (j->inotify_fd >= 0) + close_nointr_nofail(j->inotify_fd); + + sd_journal_flush_matches(j); + + if (j->mmap) + mmap_cache_unref(j->mmap); + + free(j->path); + free(j->unique_field); + free(j); +} + +_public_ int sd_journal_get_realtime_usec(sd_journal *j, uint64_t *ret) { + Object *o; + JournalFile *f; + int r; + + if (!j) + return -EINVAL; + if (!ret) + return -EINVAL; + + f = j->current_file; + if (!f) + return -EADDRNOTAVAIL; + + if (f->current_offset <= 0) + return -EADDRNOTAVAIL; + + r = journal_file_move_to_object(f, OBJECT_ENTRY, f->current_offset, &o); + if (r < 0) + return r; + + *ret = le64toh(o->entry.realtime); + return 0; +} + +_public_ int sd_journal_get_monotonic_usec(sd_journal *j, uint64_t *ret, sd_id128_t *ret_boot_id) { + Object *o; + JournalFile *f; + int r; + sd_id128_t id; + + if (!j) + return -EINVAL; + + f = j->current_file; + if (!f) + return -EADDRNOTAVAIL; + + if (f->current_offset <= 0) + return -EADDRNOTAVAIL; + + r = journal_file_move_to_object(f, OBJECT_ENTRY, f->current_offset, &o); + if (r < 0) + return r; + + if (ret_boot_id) + *ret_boot_id = o->entry.boot_id; + else { + r = sd_id128_get_boot(&id); + if (r < 0) + return r; + + if (!sd_id128_equal(id, o->entry.boot_id)) + return -ESTALE; + } + + if (ret) + *ret = le64toh(o->entry.monotonic); + + return 0; +} + +static bool field_is_valid(const char *field) { + const char *p; + + assert(field); + + if (isempty(field)) + return false; + + if (startswith(field, "__")) + return false; + + for (p = field; *p; p++) { + + if (*p == '_') + continue; + + if (*p >= 'A' && *p <= 'Z') + continue; + + if (*p >= '0' && *p <= '9') + continue; + + return false; + } + + return true; +} + +_public_ int sd_journal_get_data(sd_journal *j, const char *field, const void **data, size_t *size) { + JournalFile *f; + uint64_t i, n; + size_t field_length; + int r; + Object *o; + + if (!j) + return -EINVAL; + if (!field) + return -EINVAL; + if (!data) + return -EINVAL; + if (!size) + return -EINVAL; + + if (!field_is_valid(field)) + return -EINVAL; + + f = j->current_file; + if (!f) + return -EADDRNOTAVAIL; + + if (f->current_offset <= 0) + return -EADDRNOTAVAIL; + + r = journal_file_move_to_object(f, OBJECT_ENTRY, f->current_offset, &o); + if (r < 0) + return r; + + field_length = strlen(field); + + n = journal_file_entry_n_items(o); + for (i = 0; i < n; i++) { + uint64_t p, l; + le64_t le_hash; + size_t t; + + p = le64toh(o->entry.items[i].object_offset); + le_hash = o->entry.items[i].hash; + r = journal_file_move_to_object(f, OBJECT_DATA, p, &o); + if (r < 0) + return r; + + if (le_hash != o->data.hash) + return -EBADMSG; + + l = le64toh(o->object.size) - offsetof(Object, data.payload); + + if (o->object.flags & OBJECT_COMPRESSED) { + +#ifdef HAVE_XZ + if (uncompress_startswith(o->data.payload, l, + &f->compress_buffer, &f->compress_buffer_size, + field, field_length, '=')) { + + uint64_t rsize; + + if (!uncompress_blob(o->data.payload, l, + &f->compress_buffer, &f->compress_buffer_size, &rsize, + j->data_threshold)) + return -EBADMSG; + + *data = f->compress_buffer; + *size = (size_t) rsize; + + return 0; + } +#else + return -EPROTONOSUPPORT; +#endif + + } else if (l >= field_length+1 && + memcmp(o->data.payload, field, field_length) == 0 && + o->data.payload[field_length] == '=') { + + t = (size_t) l; + + if ((uint64_t) t != l) + return -E2BIG; + + *data = o->data.payload; + *size = t; + + return 1; + } + + r = journal_file_move_to_object(f, OBJECT_ENTRY, f->current_offset, &o); + if (r < 0) + return r; + } + + return -ENOENT; +} + +static int return_data(sd_journal *j, JournalFile *f, Object *o, const void **data, size_t *size) { + size_t t; + uint64_t l; + + l = le64toh(o->object.size) - offsetof(Object, data.payload); + t = (size_t) l; + + /* We can't read objects larger than 4G on a 32bit machine */ + if ((uint64_t) t != l) + return -E2BIG; + + if (o->object.flags & OBJECT_COMPRESSED) { +#ifdef HAVE_XZ + uint64_t rsize; + + if (!uncompress_blob(o->data.payload, l, &f->compress_buffer, &f->compress_buffer_size, &rsize, j->data_threshold)) + return -EBADMSG; + + *data = f->compress_buffer; + *size = (size_t) rsize; +#else + return -EPROTONOSUPPORT; +#endif + } else { + *data = o->data.payload; + *size = t; + } + + return 0; +} + +_public_ int sd_journal_enumerate_data(sd_journal *j, const void **data, size_t *size) { + JournalFile *f; + uint64_t p, n; + le64_t le_hash; + int r; + Object *o; + + if (!j) + return -EINVAL; + if (!data) + return -EINVAL; + if (!size) + return -EINVAL; + + f = j->current_file; + if (!f) + return -EADDRNOTAVAIL; + + if (f->current_offset <= 0) + return -EADDRNOTAVAIL; + + r = journal_file_move_to_object(f, OBJECT_ENTRY, f->current_offset, &o); + if (r < 0) + return r; + + n = journal_file_entry_n_items(o); + if (j->current_field >= n) + return 0; + + p = le64toh(o->entry.items[j->current_field].object_offset); + le_hash = o->entry.items[j->current_field].hash; + r = journal_file_move_to_object(f, OBJECT_DATA, p, &o); + if (r < 0) + return r; + + if (le_hash != o->data.hash) + return -EBADMSG; + + r = return_data(j, f, o, data, size); + if (r < 0) + return r; + + j->current_field ++; + + return 1; +} + +_public_ void sd_journal_restart_data(sd_journal *j) { + if (!j) + return; + + j->current_field = 0; +} + +_public_ int sd_journal_get_fd(sd_journal *j) { + int r; + + if (!j) + return -EINVAL; + + if (j->inotify_fd >= 0) + return j->inotify_fd; + + r = allocate_inotify(j); + if (r < 0) + return r; + + /* Iterate through all dirs again, to add them to the + * inotify */ + if (j->path) + r = add_root_directory(j, j->path); + else + r = add_search_paths(j); + if (r < 0) + return r; + + return j->inotify_fd; +} + +static void process_inotify_event(sd_journal *j, struct inotify_event *e) { + Directory *d; + int r; + + assert(j); + assert(e); + + /* Is this a subdirectory we watch? */ + d = hashmap_get(j->directories_by_wd, INT_TO_PTR(e->wd)); + if (d) { + sd_id128_t id; + + if (!(e->mask & IN_ISDIR) && e->len > 0 && + (endswith(e->name, ".journal") || + endswith(e->name, ".journal~"))) { + + /* Event for a journal file */ + + if (e->mask & (IN_CREATE|IN_MOVED_TO|IN_MODIFY|IN_ATTRIB)) { + r = add_file(j, d->path, e->name); + if (r < 0) + log_debug("Failed to add file %s/%s: %s", d->path, e->name, strerror(-r)); + + } else if (e->mask & (IN_DELETE|IN_MOVED_FROM|IN_UNMOUNT)) { + + r = remove_file(j, d->path, e->name); + if (r < 0) + log_debug("Failed to remove file %s/%s: %s", d->path, e->name, strerror(-r)); + } + + } else if (!d->is_root && e->len == 0) { + + /* Event for a subdirectory */ + + if (e->mask & (IN_DELETE_SELF|IN_MOVE_SELF|IN_UNMOUNT)) { + r = remove_directory(j, d); + if (r < 0) + log_debug("Failed to remove directory %s: %s", d->path, strerror(-r)); + } + + + } else if (d->is_root && (e->mask & IN_ISDIR) && e->len > 0 && sd_id128_from_string(e->name, &id) >= 0) { + + /* Event for root directory */ + + if (e->mask & (IN_CREATE|IN_MOVED_TO|IN_MODIFY|IN_ATTRIB)) { + r = add_directory(j, d->path, e->name); + if (r < 0) + log_debug("Failed to add directory %s/%s: %s", d->path, e->name, strerror(-r)); + } + } + + return; + } + + if (e->mask & IN_IGNORED) + return; + + log_warning("Unknown inotify event."); +} + +static int determine_change(sd_journal *j) { + bool b; + + assert(j); + + b = j->current_invalidate_counter != j->last_invalidate_counter; + j->last_invalidate_counter = j->current_invalidate_counter; + + return b ? SD_JOURNAL_INVALIDATE : SD_JOURNAL_APPEND; +} + +_public_ int sd_journal_process(sd_journal *j) { + uint8_t buffer[sizeof(struct inotify_event) + FILENAME_MAX] _alignas_(struct inotify_event); + bool got_something = false; + + if (!j) + return -EINVAL; + + for (;;) { + struct inotify_event *e; + ssize_t l; + + l = read(j->inotify_fd, buffer, sizeof(buffer)); + if (l < 0) { + if (errno == EAGAIN || errno == EINTR) + return got_something ? determine_change(j) : SD_JOURNAL_NOP; + + return -errno; + } + + got_something = true; + + e = (struct inotify_event*) buffer; + while (l > 0) { + size_t step; + + process_inotify_event(j, e); + + step = sizeof(struct inotify_event) + e->len; + assert(step <= (size_t) l); + + e = (struct inotify_event*) ((uint8_t*) e + step); + l -= step; + } + } + + return determine_change(j); +} + +_public_ int sd_journal_wait(sd_journal *j, uint64_t timeout_usec) { + int r; + + assert(j); + + if (j->inotify_fd < 0) { + + /* This is the first invocation, hence create the + * inotify watch */ + r = sd_journal_get_fd(j); + if (r < 0) + return r; + + /* The journal might have changed since the context + * object was created and we weren't watching before, + * hence don't wait for anything, and return + * immediately. */ + return determine_change(j); + } + + if (j->on_network) { + /* If we are on the network we need to regularly check + * for changes manually */ + + if (timeout_usec == (uint64_t) -1 || timeout_usec > JOURNAL_FILES_RECHECK_USEC) + timeout_usec = JOURNAL_FILES_RECHECK_USEC; + } + + do { + r = fd_wait_for_event(j->inotify_fd, POLLIN, timeout_usec); + } while (r == -EINTR); + + if (r < 0) + return r; + + return sd_journal_process(j); +} + +_public_ int sd_journal_get_cutoff_realtime_usec(sd_journal *j, uint64_t *from, uint64_t *to) { + Iterator i; + JournalFile *f; + bool first = true; + int r; + + if (!j) + return -EINVAL; + if (!from && !to) + return -EINVAL; + + HASHMAP_FOREACH(f, j->files, i) { + usec_t fr, t; + + r = journal_file_get_cutoff_realtime_usec(f, &fr, &t); + if (r == -ENOENT) + continue; + if (r < 0) + return r; + if (r == 0) + continue; + + if (first) { + if (from) + *from = fr; + if (to) + *to = t; + first = false; + } else { + if (from) + *from = MIN(fr, *from); + if (to) + *to = MAX(t, *to); + } + } + + return first ? 0 : 1; +} + +_public_ int sd_journal_get_cutoff_monotonic_usec(sd_journal *j, sd_id128_t boot_id, uint64_t *from, uint64_t *to) { + Iterator i; + JournalFile *f; + bool first = true; + int r; + + if (!j) + return -EINVAL; + if (!from && !to) + return -EINVAL; + + HASHMAP_FOREACH(f, j->files, i) { + usec_t fr, t; + + r = journal_file_get_cutoff_monotonic_usec(f, boot_id, &fr, &t); + if (r == -ENOENT) + continue; + if (r < 0) + return r; + if (r == 0) + continue; + + if (first) { + if (from) + *from = fr; + if (to) + *to = t; + first = false; + } else { + if (from) + *from = MIN(fr, *from); + if (to) + *to = MAX(t, *to); + } + } + + return first ? 0 : 1; +} + +void journal_print_header(sd_journal *j) { + Iterator i; + JournalFile *f; + bool newline = false; + + assert(j); + + HASHMAP_FOREACH(f, j->files, i) { + if (newline) + putchar('\n'); + else + newline = true; + + journal_file_print_header(f); + } +} + +_public_ int sd_journal_get_usage(sd_journal *j, uint64_t *bytes) { + Iterator i; + JournalFile *f; + uint64_t sum = 0; + + if (!j) + return -EINVAL; + if (!bytes) + return -EINVAL; + + HASHMAP_FOREACH(f, j->files, i) { + struct stat st; + + if (fstat(f->fd, &st) < 0) + return -errno; + + sum += (uint64_t) st.st_blocks * 512ULL; + } + + *bytes = sum; + return 0; +} + +_public_ int sd_journal_query_unique(sd_journal *j, const char *field) { + char *f; + + if (!j) + return -EINVAL; + if (isempty(field)) + return -EINVAL; + if (!field_is_valid(field)) + return -EINVAL; + + f = strdup(field); + if (!f) + return -ENOMEM; + + free(j->unique_field); + j->unique_field = f; + j->unique_file = NULL; + j->unique_offset = 0; + + return 0; +} + +_public_ int sd_journal_enumerate_unique(sd_journal *j, const void **data, size_t *l) { + Object *o; + size_t k; + int r; + + if (!j) + return -EINVAL; + if (!data) + return -EINVAL; + if (!l) + return -EINVAL; + if (!j->unique_field) + return -EINVAL; + + k = strlen(j->unique_field); + + if (!j->unique_file) { + j->unique_file = hashmap_first(j->files); + if (!j->unique_file) + return 0; + j->unique_offset = 0; + } + + for (;;) { + JournalFile *of; + Iterator i; + const void *odata; + size_t ol; + bool found; + + /* Proceed to next data object in the field's linked list */ + if (j->unique_offset == 0) { + r = journal_file_find_field_object(j->unique_file, j->unique_field, k, &o, NULL); + if (r < 0) + return r; + + j->unique_offset = r > 0 ? le64toh(o->field.head_data_offset) : 0; + } else { + r = journal_file_move_to_object(j->unique_file, OBJECT_DATA, j->unique_offset, &o); + if (r < 0) + return r; + + j->unique_offset = le64toh(o->data.next_field_offset); + } + + /* We reached the end of the list? Then start again, with the next file */ + if (j->unique_offset == 0) { + JournalFile *n; + + n = hashmap_next(j->files, j->unique_file->path); + if (!n) + return 0; + + j->unique_file = n; + continue; + } + + /* We do not use the type context here, but 0 instead, + * so that we can look at this data object at the same + * time as one on another file */ + r = journal_file_move_to_object(j->unique_file, 0, j->unique_offset, &o); + if (r < 0) + return r; + + /* Let's do the type check by hand, since we used 0 context above. */ + if (o->object.type != OBJECT_DATA) + return -EBADMSG; + + r = return_data(j, j->unique_file, o, &odata, &ol); + if (r < 0) + return r; + + /* OK, now let's see if we already returned this data + * object by checking if it exists in the earlier + * traversed files. */ + found = false; + HASHMAP_FOREACH(of, j->files, i) { + Object *oo; + uint64_t op; + + if (of == j->unique_file) + break; + + /* Skip this file it didn't have any fields + * indexed */ + if (JOURNAL_HEADER_CONTAINS(of->header, n_fields) && + le64toh(of->header->n_fields) <= 0) + continue; + + r = journal_file_find_data_object_with_hash(of, odata, ol, le64toh(o->data.hash), &oo, &op); + if (r < 0) + return r; + + if (r > 0) + found = true; + } + + if (found) + continue; + + r = return_data(j, j->unique_file, o, data, l); + if (r < 0) + return r; + + return 1; + } +} + +_public_ void sd_journal_restart_unique(sd_journal *j) { + if (!j) + return; + + j->unique_file = NULL; + j->unique_offset = 0; +} + +_public_ int sd_journal_reliable_fd(sd_journal *j) { + if (!j) + return -EINVAL; + + return !j->on_network; +} + +static char *lookup_field(const char *field, void *userdata) { + sd_journal *j = userdata; + const void *data; + size_t size, d; + int r; + + assert(field); + assert(j); + + r = sd_journal_get_data(j, field, &data, &size); + if (r < 0 || + size > REPLACE_VAR_MAX) + return strdup(field); + + d = strlen(field) + 1; + + return strndup((const char*) data + d, size - d); +} + +_public_ int sd_journal_get_catalog(sd_journal *j, char **ret) { + const void *data; + size_t size; + sd_id128_t id; + _cleanup_free_ char *text = NULL, *cid = NULL; + char *t; + int r; + + if (!j) + return -EINVAL; + if (!ret) + return -EINVAL; + + r = sd_journal_get_data(j, "MESSAGE_ID", &data, &size); + if (r < 0) + return r; + + cid = strndup((const char*) data + 11, size - 11); + if (!cid) + return -ENOMEM; + + r = sd_id128_from_string(cid, &id); + if (r < 0) + return r; + + r = catalog_get(id, &text); + if (r < 0) + return r; + + t = replace_var(text, lookup_field, j); + if (!t) + return -ENOMEM; + + *ret = t; + return 0; +} + +_public_ int sd_journal_get_catalog_for_message_id(sd_id128_t id, char **ret) { + if (!ret) + return -EINVAL; + + return catalog_get(id, ret); +} + +_public_ int sd_journal_set_data_threshold(sd_journal *j, size_t sz) { + if (!j) + return -EINVAL; + + j->data_threshold = sz; + return 0; +} + +_public_ int sd_journal_get_data_threshold(sd_journal *j, size_t *sz) { + if (!j) + return -EINVAL; + if (!sz) + return -EINVAL; + + *sz = j->data_threshold; + return 0; +} diff --git a/src/journal/test-catalog.c b/src/journal/test-catalog.c new file mode 100644 index 000000000..cec8a11c4 --- /dev/null +++ b/src/journal/test-catalog.c @@ -0,0 +1,48 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + +#include + +#include "util.h" +#include "log.h" +#include "catalog.h" +#include "sd-messages.h" + +int main(int argc, char *argv[]) { + + _cleanup_free_ char *text = NULL; + + setlocale(LC_ALL, "de_DE.UTF-8"); + + log_set_max_level(LOG_DEBUG); + + assert_se(catalog_update() >= 0); + + assert_se(catalog_list(stdout) >= 0); + + assert_se(catalog_get(SD_MESSAGE_COREDUMP, &text) >= 0); + + printf(">>>%s<<<\n", text); + + fflush(stdout); + + return 0; +} diff --git a/src/journal/test-journal-enum.c b/src/journal/test-journal-enum.c new file mode 100644 index 000000000..8a843ecdd --- /dev/null +++ b/src/journal/test-journal-enum.c @@ -0,0 +1,53 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + +#include + +#include "log.h" +#include "sd-journal.h" + +int main(int argc, char *argv[]) { + unsigned n = 0; + sd_journal *j; + + log_set_max_level(LOG_DEBUG); + + assert_se(sd_journal_open(&j, SD_JOURNAL_LOCAL_ONLY) >= 0); + + assert_se(sd_journal_add_match(j, "_TRANSPORT=syslog", 0) >= 0); + assert_se(sd_journal_add_match(j, "_UID=0", 0) >= 0); + + SD_JOURNAL_FOREACH_BACKWARDS(j) { + const void *d; + size_t l; + + assert_se(sd_journal_get_data(j, "MESSAGE", &d, &l) >= 0); + + printf("%.*s\n", (int) l, (char*) d); + + n ++; + if (n >= 10) + break; + } + + sd_journal_close(j); + return 0; +} diff --git a/src/journal/test-journal-match.c b/src/journal/test-journal-match.c new file mode 100644 index 000000000..fa228144f --- /dev/null +++ b/src/journal/test-journal-match.c @@ -0,0 +1,67 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + +#include + +#include + +#include "journal-internal.h" +#include "util.h" +#include "log.h" + +int main(int argc, char *argv[]) { + sd_journal *j; + char *t; + + log_set_max_level(LOG_DEBUG); + + assert_se(sd_journal_open(&j, 0) >= 0); + + assert_se(sd_journal_add_match(j, "foobar", 0) < 0); + assert_se(sd_journal_add_match(j, "foobar=waldo", 0) < 0); + assert_se(sd_journal_add_match(j, "", 0) < 0); + assert_se(sd_journal_add_match(j, "=", 0) < 0); + assert_se(sd_journal_add_match(j, "=xxxxx", 0) < 0); + assert_se(sd_journal_add_match(j, "HALLO=WALDO", 0) >= 0); + assert_se(sd_journal_add_match(j, "QUUX=mmmm", 0) >= 0); + assert_se(sd_journal_add_match(j, "QUUX=xxxxx", 0) >= 0); + assert_se(sd_journal_add_match(j, "HALLO=", 0) >= 0); + assert_se(sd_journal_add_match(j, "QUUX=xxxxx", 0) >= 0); + assert_se(sd_journal_add_match(j, "QUUX=yyyyy", 0) >= 0); + assert_se(sd_journal_add_match(j, "PIFF=paff", 0) >= 0); + + assert_se(sd_journal_add_disjunction(j) >= 0); + + assert_se(sd_journal_add_match(j, "ONE=one", 0) >= 0); + assert_se(sd_journal_add_match(j, "ONE=two", 0) >= 0); + assert_se(sd_journal_add_match(j, "TWO=two", 0) >= 0); + + assert_se(t = journal_make_match_string(j)); + + assert_se(streq(t, "((TWO=two AND (ONE=two OR ONE=one)) OR (PIFF=paff AND (QUUX=yyyyy OR QUUX=xxxxx OR QUUX=mmmm) AND (HALLO= OR HALLO=WALDO)))")); + + printf("resulting match expression is: %s\n", t); + free(t); + + sd_journal_close(j); + + return 0; +} diff --git a/src/journal/test-journal-send.c b/src/journal/test-journal-send.c new file mode 100644 index 000000000..3e986ed99 --- /dev/null +++ b/src/journal/test-journal-send.c @@ -0,0 +1,78 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +#include +#include +#include + +#include "log.h" + +int main(int argc, char *argv[]) { + char huge[4096*1024]; + + log_set_max_level(LOG_DEBUG); + + sd_journal_print(LOG_INFO, "piepapo"); + + sd_journal_send("MESSAGE=foobar", + "VALUE=%i", 7, + NULL); + + errno = ENOENT; + sd_journal_perror("Foobar"); + + sd_journal_perror(""); + + memset(huge, 'x', sizeof(huge)); + memcpy(huge, "HUGE=", 5); + char_array_0(huge); + + sd_journal_send("MESSAGE=Huge field attached", + huge, + NULL); + + sd_journal_send("MESSAGE=uiui", + "VALUE=A", + "VALUE=B", + "VALUE=C", + "SINGLETON=1", + "OTHERVALUE=X", + "OTHERVALUE=Y", + "WITH_BINARY=this is a binary value \a", + NULL); + + syslog(LOG_NOTICE, "Hello World!"); + + sd_journal_print(LOG_NOTICE, "Hello World"); + + sd_journal_send("MESSAGE=Hello World!", + "MESSAGE_ID=52fb62f99e2c49d89cfbf9d6de5e3555", + "PRIORITY=5", + "HOME=%s", getenv("HOME"), + "TERM=%s", getenv("TERM"), + "PAGE_SIZE=%li", sysconf(_SC_PAGESIZE), + "N_CPUS=%li", sysconf(_SC_NPROCESSORS_ONLN), + NULL); + + sleep(10); + + return 0; +} diff --git a/src/journal/test-journal-stream.c b/src/journal/test-journal-stream.c new file mode 100644 index 000000000..b3e816db7 --- /dev/null +++ b/src/journal/test-journal-stream.c @@ -0,0 +1,185 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + +#include +#include + +#include + +#include "journal-file.h" +#include "journal-internal.h" +#include "util.h" +#include "log.h" + +#define N_ENTRIES 200 + +static void verify_contents(sd_journal *j, unsigned skip) { + unsigned i; + + assert(j); + + i = 0; + SD_JOURNAL_FOREACH(j) { + const void *d; + char *k, *c; + size_t l; + unsigned u; + + assert_se(sd_journal_get_cursor(j, &k) >= 0); + printf("cursor: %s\n", k); + free(k); + + assert_se(sd_journal_get_data(j, "MAGIC", &d, &l) >= 0); + printf("\t%.*s\n", (int) l, (const char*) d); + + assert_se(sd_journal_get_data(j, "NUMBER", &d, &l) >= 0); + assert_se(k = strndup(d, l)); + printf("\t%s\n", k); + + if (skip > 0) { + assert_se(safe_atou(k + 7, &u) >= 0); + assert_se(i == u); + i += skip; + } + + free(k); + + assert_se(sd_journal_get_cursor(j, &c) >= 0); + assert_se(sd_journal_test_cursor(j, c) > 0); + free(c); + } + + if (skip > 0) + assert_se(i == N_ENTRIES); +} + +int main(int argc, char *argv[]) { + JournalFile *one, *two, *three; + char t[] = "/tmp/journal-stream-XXXXXX"; + unsigned i; + sd_journal *j; + char *z; + const void *data; + size_t l; + + log_set_max_level(LOG_DEBUG); + + assert_se(mkdtemp(t)); + assert_se(chdir(t) >= 0); + + assert_se(journal_file_open("one.journal", O_RDWR|O_CREAT, 0666, true, false, NULL, NULL, NULL, &one) == 0); + assert_se(journal_file_open("two.journal", O_RDWR|O_CREAT, 0666, true, false, NULL, NULL, NULL, &two) == 0); + assert_se(journal_file_open("three.journal", O_RDWR|O_CREAT, 0666, true, false, NULL, NULL, NULL, &three) == 0); + + for (i = 0; i < N_ENTRIES; i++) { + char *p, *q; + dual_timestamp ts; + struct iovec iovec[2]; + + dual_timestamp_get(&ts); + + assert_se(asprintf(&p, "NUMBER=%u", i) >= 0); + iovec[0].iov_base = p; + iovec[0].iov_len = strlen(p); + + assert_se(asprintf(&q, "MAGIC=%s", i % 5 == 0 ? "quux" : "waldo") >= 0); + + iovec[1].iov_base = q; + iovec[1].iov_len = strlen(q); + + if (i % 10 == 0) + assert_se(journal_file_append_entry(three, &ts, iovec, 2, NULL, NULL, NULL) == 0); + else { + if (i % 3 == 0) + assert_se(journal_file_append_entry(two, &ts, iovec, 2, NULL, NULL, NULL) == 0); + + assert_se(journal_file_append_entry(one, &ts, iovec, 2, NULL, NULL, NULL) == 0); + } + + free(p); + free(q); + } + + journal_file_close(one); + journal_file_close(two); + journal_file_close(three); + + assert_se(sd_journal_open_directory(&j, t, 0) >= 0); + + assert_se(sd_journal_add_match(j, "MAGIC=quux", 0) >= 0); + SD_JOURNAL_FOREACH_BACKWARDS(j) { + char *c; + + assert_se(sd_journal_get_data(j, "NUMBER", &data, &l) >= 0); + printf("\t%.*s\n", (int) l, (const char*) data); + + assert_se(sd_journal_get_cursor(j, &c) >= 0); + assert_se(sd_journal_test_cursor(j, c) > 0); + free(c); + } + + SD_JOURNAL_FOREACH(j) { + char *c; + + assert_se(sd_journal_get_data(j, "NUMBER", &data, &l) >= 0); + printf("\t%.*s\n", (int) l, (const char*) data); + + assert_se(sd_journal_get_cursor(j, &c) >= 0); + assert_se(sd_journal_test_cursor(j, c) > 0); + free(c); + } + + sd_journal_flush_matches(j); + + verify_contents(j, 1); + + printf("NEXT TEST\n"); + assert_se(sd_journal_add_match(j, "MAGIC=quux", 0) >= 0); + + assert_se(z = journal_make_match_string(j)); + printf("resulting match expression is: %s\n", z); + free(z); + + verify_contents(j, 5); + + printf("NEXT TEST\n"); + sd_journal_flush_matches(j); + assert_se(sd_journal_add_match(j, "MAGIC=waldo", 0) >= 0); + assert_se(sd_journal_add_match(j, "NUMBER=10", 0) >= 0); + assert_se(sd_journal_add_match(j, "NUMBER=11", 0) >= 0); + assert_se(sd_journal_add_match(j, "NUMBER=12", 0) >= 0); + + assert_se(z = journal_make_match_string(j)); + printf("resulting match expression is: %s\n", z); + free(z); + + verify_contents(j, 0); + + assert_se(sd_journal_query_unique(j, "NUMBER") >= 0); + SD_JOURNAL_FOREACH_UNIQUE(j, data, l) + printf("%.*s\n", (int) l, (const char*) data); + + sd_journal_close(j); + + assert_se(rm_rf_dangerous(t, false, true, false) >= 0); + + return 0; +} diff --git a/src/journal/test-journal-syslog.c b/src/journal/test-journal-syslog.c new file mode 100644 index 000000000..3ae8633f2 --- /dev/null +++ b/src/journal/test-journal-syslog.c @@ -0,0 +1,44 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +#include "journald-syslog.h" +#include "macro.h" + +static void test_syslog_parse_identifier(const char* str, + const char *ident, const char*pid, int ret) { + const char *buf = str; + char *ident2 = NULL, *pid2 = NULL; + int ret2; + + ret2 = syslog_parse_identifier(&buf, &ident2, &pid2); + + assert(ret == ret2); + assert(ident==ident2 || !strcmp(ident, ident2)); + assert(pid==pid2 || !strcmp(pid, pid2)); +} + +int main(void) { + test_syslog_parse_identifier("pidu[111]: xxx", "pidu", "111", 11); + test_syslog_parse_identifier("pidu: xxx", "pidu", NULL, 6); + test_syslog_parse_identifier("pidu xxx", NULL, NULL, 0); + + return 0; +} diff --git a/src/journal/test-journal-verify.c b/src/journal/test-journal-verify.c new file mode 100644 index 000000000..b6677215c --- /dev/null +++ b/src/journal/test-journal-verify.c @@ -0,0 +1,147 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + +#include +#include +#include + +#include "util.h" +#include "log.h" +#include "journal-file.h" +#include "journal-verify.h" +#include "journal-authenticate.h" + +#define N_ENTRIES 6000 +#define RANDOM_RANGE 77 + +static void bit_toggle(const char *fn, uint64_t p) { + uint8_t b; + ssize_t r; + int fd; + + fd = open(fn, O_RDWR|O_CLOEXEC); + assert(fd >= 0); + + r = pread(fd, &b, 1, p/8); + assert(r == 1); + + b ^= 1 << (p % 8); + + r = pwrite(fd, &b, 1, p/8); + assert(r == 1); + + close_nointr_nofail(fd); +} + +static int raw_verify(const char *fn, const char *verification_key) { + JournalFile *f; + int r; + + r = journal_file_open(fn, O_RDONLY, 0666, true, !!verification_key, NULL, NULL, NULL, &f); + if (r < 0) + return r; + + r = journal_file_verify(f, verification_key, NULL, NULL, NULL, false); + journal_file_close(f); + + return r; +} + +int main(int argc, char *argv[]) { + char t[] = "/tmp/journal-XXXXXX"; + unsigned n; + JournalFile *f; + const char *verification_key = argv[1]; + usec_t from = 0, to = 0, total = 0; + char a[FORMAT_TIMESTAMP_MAX]; + char b[FORMAT_TIMESTAMP_MAX]; + char c[FORMAT_TIMESPAN_MAX]; + struct stat st; + uint64_t p; + + log_set_max_level(LOG_DEBUG); + + assert_se(mkdtemp(t)); + assert_se(chdir(t) >= 0); + + log_info("Generating..."); + + assert_se(journal_file_open("test.journal", O_RDWR|O_CREAT, 0666, true, !!verification_key, NULL, NULL, NULL, &f) == 0); + + for (n = 0; n < N_ENTRIES; n++) { + struct iovec iovec; + struct dual_timestamp ts; + char *test; + + dual_timestamp_get(&ts); + + assert_se(asprintf(&test, "RANDOM=%lu", random() % RANDOM_RANGE)); + + iovec.iov_base = (void*) test; + iovec.iov_len = strlen(test); + + assert_se(journal_file_append_entry(f, &ts, &iovec, 1, NULL, NULL, NULL) == 0); + + free(test); + } + + journal_file_close(f); + + log_info("Verifying..."); + + assert_se(journal_file_open("test.journal", O_RDONLY, 0666, true, !!verification_key, NULL, NULL, NULL, &f) == 0); + /* journal_file_print_header(f); */ + journal_file_dump(f); + + assert_se(journal_file_verify(f, verification_key, &from, &to, &total, true) >= 0); + + if (verification_key && JOURNAL_HEADER_SEALED(f->header)) { + log_info("=> Validated from %s to %s, %s missing", + format_timestamp(a, sizeof(a), from), + format_timestamp(b, sizeof(b), to), + format_timespan(c, sizeof(c), total > to ? total - to : 0)); + } + + journal_file_close(f); + + if (verification_key) { + log_info("Toggling bits..."); + + assert_se(stat("test.journal", &st) >= 0); + + for (p = 38448*8+0; p < ((uint64_t) st.st_size * 8); p ++) { + bit_toggle("test.journal", p); + + log_info("[ %llu+%llu]", (unsigned long long) p / 8, (unsigned long long) p % 8); + + if (raw_verify("test.journal", verification_key) >= 0) + log_notice(ANSI_HIGHLIGHT_RED_ON ">>>> %llu (bit %llu) can be toggled without detection." ANSI_HIGHLIGHT_OFF, (unsigned long long) p / 8, (unsigned long long) p % 8); + + bit_toggle("test.journal", p); + } + } + + log_info("Exiting..."); + + assert_se(rm_rf_dangerous(t, false, true, false) >= 0); + + return 0; +} diff --git a/src/journal/test-journal.c b/src/journal/test-journal.c new file mode 100644 index 000000000..f4dc52cd8 --- /dev/null +++ b/src/journal/test-journal.c @@ -0,0 +1,129 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +#include +#include + +#include + +#include "log.h" +#include "journal-file.h" +#include "journal-authenticate.h" +#include "journal-vacuum.h" + +int main(int argc, char *argv[]) { + dual_timestamp ts; + JournalFile *f; + struct iovec iovec; + static const char test[] = "TEST1=1", test2[] = "TEST2=2"; + Object *o; + uint64_t p; + char t[] = "/tmp/journal-XXXXXX"; + + log_set_max_level(LOG_DEBUG); + + assert_se(mkdtemp(t)); + assert_se(chdir(t) >= 0); + + assert_se(journal_file_open("test.journal", O_RDWR|O_CREAT, 0666, true, true, NULL, NULL, NULL, &f) == 0); + + dual_timestamp_get(&ts); + + iovec.iov_base = (void*) test; + iovec.iov_len = strlen(test); + assert_se(journal_file_append_entry(f, &ts, &iovec, 1, NULL, NULL, NULL) == 0); + + iovec.iov_base = (void*) test2; + iovec.iov_len = strlen(test2); + assert_se(journal_file_append_entry(f, &ts, &iovec, 1, NULL, NULL, NULL) == 0); + + iovec.iov_base = (void*) test; + iovec.iov_len = strlen(test); + assert_se(journal_file_append_entry(f, &ts, &iovec, 1, NULL, NULL, NULL) == 0); + +#ifdef HAVE_GCRYPT + journal_file_append_tag(f); +#endif + journal_file_dump(f); + + assert(journal_file_next_entry(f, NULL, 0, DIRECTION_DOWN, &o, &p) == 1); + assert(le64toh(o->entry.seqnum) == 1); + + assert(journal_file_next_entry(f, o, p, DIRECTION_DOWN, &o, &p) == 1); + assert(le64toh(o->entry.seqnum) == 2); + + assert(journal_file_next_entry(f, o, p, DIRECTION_DOWN, &o, &p) == 1); + assert(le64toh(o->entry.seqnum) == 3); + + assert(journal_file_next_entry(f, o, p, DIRECTION_DOWN, &o, &p) == 0); + + assert(journal_file_next_entry(f, NULL, 0, DIRECTION_DOWN, &o, &p) == 1); + assert(le64toh(o->entry.seqnum) == 1); + + assert(journal_file_skip_entry(f, o, p, 2, &o, &p) == 1); + assert(le64toh(o->entry.seqnum) == 3); + + assert(journal_file_skip_entry(f, o, p, -2, &o, &p) == 1); + assert(le64toh(o->entry.seqnum) == 1); + + assert(journal_file_skip_entry(f, o, p, -2, &o, &p) == 1); + assert(le64toh(o->entry.seqnum) == 1); + + assert(journal_file_find_data_object(f, test, strlen(test), NULL, &p) == 1); + assert(journal_file_next_entry_for_data(f, NULL, 0, p, DIRECTION_DOWN, &o, NULL) == 1); + assert(le64toh(o->entry.seqnum) == 1); + + assert(journal_file_next_entry_for_data(f, NULL, 0, p, DIRECTION_UP, &o, NULL) == 1); + assert(le64toh(o->entry.seqnum) == 3); + + assert(journal_file_find_data_object(f, test2, strlen(test2), NULL, &p) == 1); + assert(journal_file_next_entry_for_data(f, NULL, 0, p, DIRECTION_UP, &o, NULL) == 1); + assert(le64toh(o->entry.seqnum) == 2); + + assert(journal_file_next_entry_for_data(f, NULL, 0, p, DIRECTION_DOWN, &o, NULL) == 1); + assert(le64toh(o->entry.seqnum) == 2); + + assert(journal_file_find_data_object(f, "quux", 4, NULL, &p) == 0); + + assert(journal_file_move_to_entry_by_seqnum(f, 1, DIRECTION_DOWN, &o, NULL) == 1); + assert(le64toh(o->entry.seqnum) == 1); + + assert(journal_file_move_to_entry_by_seqnum(f, 3, DIRECTION_DOWN, &o, NULL) == 1); + assert(le64toh(o->entry.seqnum) == 3); + + assert(journal_file_move_to_entry_by_seqnum(f, 2, DIRECTION_DOWN, &o, NULL) == 1); + assert(le64toh(o->entry.seqnum) == 2); + + assert(journal_file_move_to_entry_by_seqnum(f, 10, DIRECTION_DOWN, &o, NULL) == 0); + + journal_file_rotate(&f, true, true); + journal_file_rotate(&f, true, true); + + journal_file_close(f); + + journal_directory_vacuum(".", 3000000, 0, 0, NULL); + + log_error("Exiting..."); + + assert_se(rm_rf_dangerous(t, false, true, false) >= 0); + + return 0; +} diff --git a/src/journal/test-mmap-cache.c b/src/journal/test-mmap-cache.c new file mode 100644 index 000000000..e2ffaf472 --- /dev/null +++ b/src/journal/test-mmap-cache.c @@ -0,0 +1,79 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + +#include +#include +#include + +#include "log.h" +#include "macro.h" +#include "util.h" +#include "mmap-cache.h" + +int main(int argc, char *argv[]) { + int x, y, z, r; + char px[] = "/tmp/testmmapXXXXXXX", py[] = "/tmp/testmmapYXXXXXX", pz[] = "/tmp/testmmapZXXXXXX"; + MMapCache *m; + void *p, *q; + + assert_se(m = mmap_cache_new()); + + x = mkstemp(px); + assert(x >= 0); + unlink(px); + + y = mkstemp(py); + assert(y >= 0); + unlink(py); + + z = mkstemp(pz); + assert(z >= 0); + unlink(pz); + + r = mmap_cache_get(m, x, PROT_READ, 0, false, 1, 2, NULL, &p); + assert(r >= 0); + + r = mmap_cache_get(m, x, PROT_READ, 0, false, 2, 2, NULL, &q); + assert(r >= 0); + + assert((uint8_t*) p + 1 == (uint8_t*) q); + + r = mmap_cache_get(m, x, PROT_READ, 1, false, 3, 2, NULL, &q); + assert(r >= 0); + + assert((uint8_t*) p + 2 == (uint8_t*) q); + + r = mmap_cache_get(m, x, PROT_READ, 0, false, 16ULL*1024ULL*1024ULL, 2, NULL, &p); + assert(r >= 0); + + r = mmap_cache_get(m, x, PROT_READ, 1, false, 16ULL*1024ULL*1024ULL+1, 2, NULL, &q); + assert(r >= 0); + + assert((uint8_t*) p + 1 == (uint8_t*) q); + + mmap_cache_unref(m); + + close_nointr_nofail(x); + close_nointr_nofail(y); + close_nointr_nofail(z); + + return 0; +} diff --git a/src/libsystemd-daemon/.gitignore b/src/libsystemd-daemon/.gitignore new file mode 100644 index 000000000..5184131b2 --- /dev/null +++ b/src/libsystemd-daemon/.gitignore @@ -0,0 +1 @@ +/libsystemd-daemon.pc diff --git a/src/libsystemd-daemon/Makefile b/src/libsystemd-daemon/Makefile new file mode 120000 index 000000000..d0b0e8e00 --- /dev/null +++ b/src/libsystemd-daemon/Makefile @@ -0,0 +1 @@ +../Makefile \ No newline at end of file diff --git a/src/libsystemd-daemon/libsystemd-daemon.pc.in b/src/libsystemd-daemon/libsystemd-daemon.pc.in new file mode 100644 index 000000000..8bb3a74c8 --- /dev/null +++ b/src/libsystemd-daemon/libsystemd-daemon.pc.in @@ -0,0 +1,19 @@ +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation files +# (the "Software"), to deal in the Software without restriction, +# including without limitation the rights to use, copy, modify, merge, +# publish, distribute, sublicense, and/or sell copies of the Software, +# and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: systemd +Description: systemd Daemon Utility Library +URL: @PACKAGE_URL@ +Version: @PACKAGE_VERSION@ +Libs: -L${libdir} -lsystemd-daemon +Cflags: -I${includedir} diff --git a/src/libsystemd-daemon/libsystemd-daemon.sym b/src/libsystemd-daemon/libsystemd-daemon.sym new file mode 100644 index 000000000..f44023893 --- /dev/null +++ b/src/libsystemd-daemon/libsystemd-daemon.sym @@ -0,0 +1,27 @@ +/*** + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation files + (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: +***/ + +/* Original symbols from systemd v31 */ + +LIBSYSTEMD_DAEMON_31 { +global: + sd_booted; + sd_is_fifo; + sd_is_mq; + sd_is_socket; + sd_is_socket_inet; + sd_is_socket_unix; + sd_is_special; + sd_listen_fds; + sd_notify; + sd_notifyf; +local: + *; +}; diff --git a/src/libsystemd-daemon/sd-daemon.c b/src/libsystemd-daemon/sd-daemon.c new file mode 100644 index 000000000..80aadf7ad --- /dev/null +++ b/src/libsystemd-daemon/sd-daemon.c @@ -0,0 +1,536 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + Copyright 2010 Lennart Poettering + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation files + (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +***/ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +#include +#include +#include +#include +#ifdef __BIONIC__ +#include +#else +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(__linux__) +#include +#endif + +#include "sd-daemon.h" + +#if (__GNUC__ >= 4) +#ifdef SD_EXPORT_SYMBOLS +/* Export symbols */ +#define _sd_export_ __attribute__ ((visibility("default"))) +#else +/* Don't export the symbols */ +#define _sd_export_ __attribute__ ((visibility("hidden"))) +#endif +#else +#define _sd_export_ +#endif + +_sd_export_ int sd_listen_fds(int unset_environment) { + +#if defined(DISABLE_SYSTEMD) || !defined(__linux__) + return 0; +#else + int r, fd; + const char *e; + char *p = NULL; + unsigned long l; + + e = getenv("LISTEN_PID"); + if (!e) { + r = 0; + goto finish; + } + + errno = 0; + l = strtoul(e, &p, 10); + + if (errno != 0) { + r = -errno; + goto finish; + } + + if (!p || p == e || *p || l <= 0) { + r = -EINVAL; + goto finish; + } + + /* Is this for us? */ + if (getpid() != (pid_t) l) { + r = 0; + goto finish; + } + + e = getenv("LISTEN_FDS"); + if (!e) { + r = 0; + goto finish; + } + + errno = 0; + l = strtoul(e, &p, 10); + + if (errno != 0) { + r = -errno; + goto finish; + } + + if (!p || p == e || *p) { + r = -EINVAL; + goto finish; + } + + for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + (int) l; fd ++) { + int flags; + + flags = fcntl(fd, F_GETFD); + if (flags < 0) { + r = -errno; + goto finish; + } + + if (flags & FD_CLOEXEC) + continue; + + if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) < 0) { + r = -errno; + goto finish; + } + } + + r = (int) l; + +finish: + if (unset_environment) { + unsetenv("LISTEN_PID"); + unsetenv("LISTEN_FDS"); + } + + return r; +#endif +} + +_sd_export_ int sd_is_fifo(int fd, const char *path) { + struct stat st_fd; + + if (fd < 0) + return -EINVAL; + + if (fstat(fd, &st_fd) < 0) + return -errno; + + if (!S_ISFIFO(st_fd.st_mode)) + return 0; + + if (path) { + struct stat st_path; + + if (stat(path, &st_path) < 0) { + + if (errno == ENOENT || errno == ENOTDIR) + return 0; + + return -errno; + } + + return + st_path.st_dev == st_fd.st_dev && + st_path.st_ino == st_fd.st_ino; + } + + return 1; +} + +_sd_export_ int sd_is_special(int fd, const char *path) { + struct stat st_fd; + + if (fd < 0) + return -EINVAL; + + if (fstat(fd, &st_fd) < 0) + return -errno; + + if (!S_ISREG(st_fd.st_mode) && !S_ISCHR(st_fd.st_mode)) + return 0; + + if (path) { + struct stat st_path; + + if (stat(path, &st_path) < 0) { + + if (errno == ENOENT || errno == ENOTDIR) + return 0; + + return -errno; + } + + if (S_ISREG(st_fd.st_mode) && S_ISREG(st_path.st_mode)) + return + st_path.st_dev == st_fd.st_dev && + st_path.st_ino == st_fd.st_ino; + else if (S_ISCHR(st_fd.st_mode) && S_ISCHR(st_path.st_mode)) + return st_path.st_rdev == st_fd.st_rdev; + else + return 0; + } + + return 1; +} + +static int sd_is_socket_internal(int fd, int type, int listening) { + struct stat st_fd; + + if (fd < 0 || type < 0) + return -EINVAL; + + if (fstat(fd, &st_fd) < 0) + return -errno; + + if (!S_ISSOCK(st_fd.st_mode)) + return 0; + + if (type != 0) { + int other_type = 0; + socklen_t l = sizeof(other_type); + + if (getsockopt(fd, SOL_SOCKET, SO_TYPE, &other_type, &l) < 0) + return -errno; + + if (l != sizeof(other_type)) + return -EINVAL; + + if (other_type != type) + return 0; + } + + if (listening >= 0) { + int accepting = 0; + socklen_t l = sizeof(accepting); + + if (getsockopt(fd, SOL_SOCKET, SO_ACCEPTCONN, &accepting, &l) < 0) + return -errno; + + if (l != sizeof(accepting)) + return -EINVAL; + + if (!accepting != !listening) + return 0; + } + + return 1; +} + +union sockaddr_union { + struct sockaddr sa; + struct sockaddr_in in4; + struct sockaddr_in6 in6; + struct sockaddr_un un; + struct sockaddr_storage storage; +}; + +_sd_export_ int sd_is_socket(int fd, int family, int type, int listening) { + int r; + + if (family < 0) + return -EINVAL; + + r = sd_is_socket_internal(fd, type, listening); + if (r <= 0) + return r; + + if (family > 0) { + union sockaddr_union sockaddr; + socklen_t l; + + memset(&sockaddr, 0, sizeof(sockaddr)); + l = sizeof(sockaddr); + + if (getsockname(fd, &sockaddr.sa, &l) < 0) + return -errno; + + if (l < sizeof(sa_family_t)) + return -EINVAL; + + return sockaddr.sa.sa_family == family; + } + + return 1; +} + +_sd_export_ int sd_is_socket_inet(int fd, int family, int type, int listening, uint16_t port) { + union sockaddr_union sockaddr; + socklen_t l; + int r; + + if (family != 0 && family != AF_INET && family != AF_INET6) + return -EINVAL; + + r = sd_is_socket_internal(fd, type, listening); + if (r <= 0) + return r; + + memset(&sockaddr, 0, sizeof(sockaddr)); + l = sizeof(sockaddr); + + if (getsockname(fd, &sockaddr.sa, &l) < 0) + return -errno; + + if (l < sizeof(sa_family_t)) + return -EINVAL; + + if (sockaddr.sa.sa_family != AF_INET && + sockaddr.sa.sa_family != AF_INET6) + return 0; + + if (family > 0) + if (sockaddr.sa.sa_family != family) + return 0; + + if (port > 0) { + if (sockaddr.sa.sa_family == AF_INET) { + if (l < sizeof(struct sockaddr_in)) + return -EINVAL; + + return htons(port) == sockaddr.in4.sin_port; + } else { + if (l < sizeof(struct sockaddr_in6)) + return -EINVAL; + + return htons(port) == sockaddr.in6.sin6_port; + } + } + + return 1; +} + +_sd_export_ int sd_is_socket_unix(int fd, int type, int listening, const char *path, size_t length) { + union sockaddr_union sockaddr; + socklen_t l; + int r; + + r = sd_is_socket_internal(fd, type, listening); + if (r <= 0) + return r; + + memset(&sockaddr, 0, sizeof(sockaddr)); + l = sizeof(sockaddr); + + if (getsockname(fd, &sockaddr.sa, &l) < 0) + return -errno; + + if (l < sizeof(sa_family_t)) + return -EINVAL; + + if (sockaddr.sa.sa_family != AF_UNIX) + return 0; + + if (path) { + if (length == 0) + length = strlen(path); + + if (length == 0) + /* Unnamed socket */ + return l == offsetof(struct sockaddr_un, sun_path); + + if (path[0]) + /* Normal path socket */ + return + (l >= offsetof(struct sockaddr_un, sun_path) + length + 1) && + memcmp(path, sockaddr.un.sun_path, length+1) == 0; + else + /* Abstract namespace socket */ + return + (l == offsetof(struct sockaddr_un, sun_path) + length) && + memcmp(path, sockaddr.un.sun_path, length) == 0; + } + + return 1; +} + +_sd_export_ int sd_is_mq(int fd, const char *path) { +#if !defined(__linux__) + return 0; +#else + struct mq_attr attr; + + if (fd < 0) + return -EINVAL; + + if (mq_getattr(fd, &attr) < 0) + return -errno; + + if (path) { + char fpath[PATH_MAX]; + struct stat a, b; + + if (path[0] != '/') + return -EINVAL; + + if (fstat(fd, &a) < 0) + return -errno; + + strncpy(stpcpy(fpath, "/dev/mqueue"), path, sizeof(fpath) - 12); + fpath[sizeof(fpath)-1] = 0; + + if (stat(fpath, &b) < 0) + return -errno; + + if (a.st_dev != b.st_dev || + a.st_ino != b.st_ino) + return 0; + } + + return 1; +#endif +} + +_sd_export_ int sd_notify(int unset_environment, const char *state) { +#if defined(DISABLE_SYSTEMD) || !defined(__linux__) || !defined(SOCK_CLOEXEC) + return 0; +#else + int fd = -1, r; + struct msghdr msghdr; + struct iovec iovec; + union sockaddr_union sockaddr; + const char *e; + + if (!state) { + r = -EINVAL; + goto finish; + } + + e = getenv("NOTIFY_SOCKET"); + if (!e) + return 0; + + /* Must be an abstract socket, or an absolute path */ + if ((e[0] != '@' && e[0] != '/') || e[1] == 0) { + r = -EINVAL; + goto finish; + } + + fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0); + if (fd < 0) { + r = -errno; + goto finish; + } + + memset(&sockaddr, 0, sizeof(sockaddr)); + sockaddr.sa.sa_family = AF_UNIX; + strncpy(sockaddr.un.sun_path, e, sizeof(sockaddr.un.sun_path)); + + if (sockaddr.un.sun_path[0] == '@') + sockaddr.un.sun_path[0] = 0; + + memset(&iovec, 0, sizeof(iovec)); + iovec.iov_base = (char*) state; + iovec.iov_len = strlen(state); + + memset(&msghdr, 0, sizeof(msghdr)); + msghdr.msg_name = &sockaddr; + msghdr.msg_namelen = offsetof(struct sockaddr_un, sun_path) + strlen(e); + + if (msghdr.msg_namelen > sizeof(struct sockaddr_un)) + msghdr.msg_namelen = sizeof(struct sockaddr_un); + + msghdr.msg_iov = &iovec; + msghdr.msg_iovlen = 1; + + if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0) { + r = -errno; + goto finish; + } + + r = 1; + +finish: + if (unset_environment) + unsetenv("NOTIFY_SOCKET"); + + if (fd >= 0) + close(fd); + + return r; +#endif +} + +_sd_export_ int sd_notifyf(int unset_environment, const char *format, ...) { +#if defined(DISABLE_SYSTEMD) || !defined(__linux__) + return 0; +#else + va_list ap; + char *p = NULL; + int r; + + va_start(ap, format); + r = vasprintf(&p, format, ap); + va_end(ap); + + if (r < 0 || !p) + return -ENOMEM; + + r = sd_notify(unset_environment, p); + free(p); + + return r; +#endif +} + +_sd_export_ int sd_booted(void) { +#if defined(DISABLE_SYSTEMD) || !defined(__linux__) + return 0; +#else + + struct stat a, b; + + /* We simply test whether the systemd cgroup hierarchy is + * mounted */ + + if (lstat("/sys/fs/cgroup", &a) < 0) + return 0; + + if (lstat("/sys/fs/cgroup/systemd", &b) < 0) + return 0; + + return a.st_dev != b.st_dev; +#endif +} diff --git a/src/libsystemd-id128/.gitignore b/src/libsystemd-id128/.gitignore new file mode 100644 index 000000000..144adf9be --- /dev/null +++ b/src/libsystemd-id128/.gitignore @@ -0,0 +1 @@ +/libsystemd-id128.pc diff --git a/src/libsystemd-id128/Makefile b/src/libsystemd-id128/Makefile new file mode 120000 index 000000000..d0b0e8e00 --- /dev/null +++ b/src/libsystemd-id128/Makefile @@ -0,0 +1 @@ +../Makefile \ No newline at end of file diff --git a/src/libsystemd-id128/libsystemd-id128.pc.in b/src/libsystemd-id128/libsystemd-id128.pc.in new file mode 100644 index 000000000..bb65ffde3 --- /dev/null +++ b/src/libsystemd-id128/libsystemd-id128.pc.in @@ -0,0 +1,18 @@ +# This file is part of systemd. +# +# 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. + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: systemd +Description: systemd 128 Bit ID Utility Library +URL: @PACKAGE_URL@ +Version: @PACKAGE_VERSION@ +Libs: -L${libdir} -lsystemd-id128 +Cflags: -I${includedir} diff --git a/src/libsystemd-id128/libsystemd-id128.sym b/src/libsystemd-id128/libsystemd-id128.sym new file mode 100644 index 000000000..604c0026c --- /dev/null +++ b/src/libsystemd-id128/libsystemd-id128.sym @@ -0,0 +1,21 @@ +/*** + This file is part of systemd. + + 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. +***/ + +/* Original symbols from systemd v38 */ + +LIBSYSTEMD_ID128_38 { +global: + sd_id128_to_string; + sd_id128_from_string; + sd_id128_randomize; + sd_id128_get_machine; + sd_id128_get_boot; +local: + *; +}; diff --git a/src/libsystemd-id128/sd-id128.c b/src/libsystemd-id128/sd-id128.c new file mode 100644 index 000000000..4286ae7d1 --- /dev/null +++ b/src/libsystemd-id128/sd-id128.c @@ -0,0 +1,221 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +#include +#include +#include + +#include "sd-id128.h" + +#include "util.h" +#include "macro.h" + +_public_ char *sd_id128_to_string(sd_id128_t id, char s[33]) { + unsigned n; + + if (!s) + return NULL; + + for (n = 0; n < 16; n++) { + s[n*2] = hexchar(id.bytes[n] >> 4); + s[n*2+1] = hexchar(id.bytes[n] & 0xF); + } + + s[32] = 0; + + return s; +} + +_public_ int sd_id128_from_string(const char s[33], sd_id128_t *ret) { + unsigned n; + sd_id128_t t; + + if (!s) + return -EINVAL; + if (!ret) + return -EINVAL; + + for (n = 0; n < 16; n++) { + int a, b; + + a = unhexchar(s[n*2]); + if (a < 0) + return -EINVAL; + + b = unhexchar(s[n*2+1]); + if (b < 0) + return -EINVAL; + + t.bytes[n] = (a << 4) | b; + } + + if (s[32] != 0) + return -EINVAL; + + *ret = t; + return 0; +} + +static sd_id128_t make_v4_uuid(sd_id128_t id) { + /* Stolen from generate_random_uuid() of drivers/char/random.c + * in the kernel sources */ + + /* Set UUID version to 4 --- truly random generation */ + id.bytes[6] = (id.bytes[6] & 0x0F) | 0x40; + + /* Set the UUID variant to DCE */ + id.bytes[8] = (id.bytes[8] & 0x3F) | 0x80; + + return id; +} + +_public_ int sd_id128_get_machine(sd_id128_t *ret) { + static __thread sd_id128_t saved_machine_id; + static __thread bool saved_machine_id_valid = false; + int fd; + char buf[32]; + ssize_t k; + unsigned j; + sd_id128_t t; + + if (!ret) + return -EINVAL; + + if (saved_machine_id_valid) { + *ret = saved_machine_id; + return 0; + } + + fd = open("/etc/machine-id", O_RDONLY|O_CLOEXEC|O_NOCTTY); + if (fd < 0) + return -errno; + + k = loop_read(fd, buf, 32, false); + close_nointr_nofail(fd); + + if (k < 0) + return (int) k; + + if (k < 32) + return -EIO; + + for (j = 0; j < 16; j++) { + int a, b; + + a = unhexchar(buf[j*2]); + b = unhexchar(buf[j*2+1]); + + if (a < 0 || b < 0) + return -EIO; + + t.bytes[j] = a << 4 | b; + } + + saved_machine_id = t; + saved_machine_id_valid = true; + + *ret = t; + return 0; +} + +_public_ int sd_id128_get_boot(sd_id128_t *ret) { + static __thread sd_id128_t saved_boot_id; + static __thread bool saved_boot_id_valid = false; + int fd; + char buf[36]; + ssize_t k; + unsigned j; + sd_id128_t t; + char *p; + + if (!ret) + return -EINVAL; + + if (saved_boot_id_valid) { + *ret = saved_boot_id; + return 0; + } + + fd = open("/proc/sys/kernel/random/boot_id", O_RDONLY|O_CLOEXEC|O_NOCTTY); + if (fd < 0) + return -errno; + + k = loop_read(fd, buf, 36, false); + close_nointr_nofail(fd); + + if (k < 0) + return (int) k; + + if (k < 36) + return -EIO; + + for (j = 0, p = buf; j < 16; j++) { + int a, b; + + if (*p == '-') + p++; + + a = unhexchar(p[0]); + b = unhexchar(p[1]); + + if (a < 0 || b < 0) + return -EIO; + + t.bytes[j] = a << 4 | b; + + p += 2; + } + + saved_boot_id = t; + saved_boot_id_valid = true; + + *ret = t; + return 0; +} + +_public_ int sd_id128_randomize(sd_id128_t *ret) { + int fd; + ssize_t k; + sd_id128_t t; + + if (!ret) + return -EINVAL; + + fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY); + if (fd < 0) + return -errno; + + k = loop_read(fd, &t, 16, false); + close_nointr_nofail(fd); + + if (k < 0) + return (int) k; + + if (k < 16) + return -EIO; + + /* Turn this into a valid v4 UUID, to be nice. Note that we + * only guarantee this for newly generated UUIDs, not for + * pre-existing ones.*/ + + *ret = make_v4_uuid(t); + return 0; +} diff --git a/src/libudev/.gitignore b/src/libudev/.gitignore new file mode 100644 index 000000000..0c8a5d523 --- /dev/null +++ b/src/libudev/.gitignore @@ -0,0 +1 @@ +/libudev.pc diff --git a/src/libudev/Makefile b/src/libudev/Makefile new file mode 120000 index 000000000..d0b0e8e00 --- /dev/null +++ b/src/libudev/Makefile @@ -0,0 +1 @@ +../Makefile \ No newline at end of file diff --git a/src/libudev/libudev-device-private.c b/src/libudev/libudev-device-private.c new file mode 100644 index 000000000..c12305790 --- /dev/null +++ b/src/libudev/libudev-device-private.c @@ -0,0 +1,192 @@ +/*** + This file is part of systemd. + + Copyright 2008-2012 Kay Sievers + + 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "libudev.h" +#include "libudev-private.h" + +static void udev_device_tag(struct udev_device *dev, const char *tag, bool add) +{ + const char *id; + char filename[UTIL_PATH_SIZE]; + + id = udev_device_get_id_filename(dev); + if (id == NULL) + return; + util_strscpyl(filename, sizeof(filename), "/run/udev/tags/", tag, "/", id, NULL); + + if (add) { + int fd; + + mkdir_parents(filename, 0755); + fd = open(filename, O_WRONLY|O_CREAT|O_CLOEXEC|O_TRUNC|O_NOFOLLOW, 0444); + if (fd >= 0) + close(fd); + } else { + unlink(filename); + } +} + +int udev_device_tag_index(struct udev_device *dev, struct udev_device *dev_old, bool add) +{ + struct udev_list_entry *list_entry; + bool found; + + if (add && dev_old != NULL) { + /* delete possible left-over tags */ + udev_list_entry_foreach(list_entry, udev_device_get_tags_list_entry(dev_old)) { + const char *tag_old = udev_list_entry_get_name(list_entry); + struct udev_list_entry *list_entry_current; + + found = false; + udev_list_entry_foreach(list_entry_current, udev_device_get_tags_list_entry(dev)) { + const char *tag = udev_list_entry_get_name(list_entry_current); + + if (streq(tag, tag_old)) { + found = true; + break; + } + } + if (!found) + udev_device_tag(dev_old, tag_old, false); + } + } + + udev_list_entry_foreach(list_entry, udev_device_get_tags_list_entry(dev)) + udev_device_tag(dev, udev_list_entry_get_name(list_entry), add); + + return 0; +} + +static bool device_has_info(struct udev_device *udev_device) +{ + struct udev_list_entry *list_entry; + + if (udev_device_get_devlinks_list_entry(udev_device) != NULL) + return true; + if (udev_device_get_devlink_priority(udev_device) != 0) + return true; + udev_list_entry_foreach(list_entry, udev_device_get_properties_list_entry(udev_device)) + if (udev_list_entry_get_num(list_entry)) + return true; + if (udev_device_get_tags_list_entry(udev_device) != NULL) + return true; + if (udev_device_get_watch_handle(udev_device) >= 0) + return true; + return false; +} + +int udev_device_update_db(struct udev_device *udev_device) +{ + struct udev *udev = udev_device_get_udev(udev_device); + bool has_info; + const char *id; + char filename[UTIL_PATH_SIZE]; + char filename_tmp[UTIL_PATH_SIZE]; + FILE *f; + int r; + + id = udev_device_get_id_filename(udev_device); + if (id == NULL) + return -1; + + has_info = device_has_info(udev_device); + util_strscpyl(filename, sizeof(filename), "/run/udev/data/", id, NULL); + + /* do not store anything for otherwise empty devices */ + if (!has_info && + major(udev_device_get_devnum(udev_device)) == 0 && + udev_device_get_ifindex(udev_device) == 0) { + unlink(filename); + return 0; + } + + /* write a database file */ + util_strscpyl(filename_tmp, sizeof(filename_tmp), filename, ".tmp", NULL); + mkdir_parents(filename_tmp, 0755); + f = fopen(filename_tmp, "we"); + if (f == NULL) { + udev_err(udev, "unable to create temporary db file '%s': %m\n", filename_tmp); + return -1; + } + + /* + * set 'sticky' bit to indicate that we should not clean the + * database when we transition from initramfs to the real root + */ + if (udev_device_get_db_persist(udev_device)) + fchmod(fileno(f), 01644); + + if (has_info) { + struct udev_list_entry *list_entry; + + if (major(udev_device_get_devnum(udev_device)) > 0) { + udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(udev_device)) + fprintf(f, "S:%s\n", udev_list_entry_get_name(list_entry) + strlen("/dev/")); + if (udev_device_get_devlink_priority(udev_device) != 0) + fprintf(f, "L:%i\n", udev_device_get_devlink_priority(udev_device)); + if (udev_device_get_watch_handle(udev_device) >= 0) + fprintf(f, "W:%i\n", udev_device_get_watch_handle(udev_device)); + } + + if (udev_device_get_usec_initialized(udev_device) > 0) + fprintf(f, "I:%llu\n", (unsigned long long)udev_device_get_usec_initialized(udev_device)); + + udev_list_entry_foreach(list_entry, udev_device_get_properties_list_entry(udev_device)) { + if (!udev_list_entry_get_num(list_entry)) + continue; + fprintf(f, "E:%s=%s\n", + udev_list_entry_get_name(list_entry), + udev_list_entry_get_value(list_entry)); + } + + udev_list_entry_foreach(list_entry, udev_device_get_tags_list_entry(udev_device)) + fprintf(f, "G:%s\n", udev_list_entry_get_name(list_entry)); + } + + fclose(f); + r = rename(filename_tmp, filename); + if (r < 0) + return -1; + udev_dbg(udev, "created %s file '%s' for '%s'\n", has_info ? "db" : "empty", + filename, udev_device_get_devpath(udev_device)); + return 0; +} + +int udev_device_delete_db(struct udev_device *udev_device) +{ + const char *id; + char filename[UTIL_PATH_SIZE]; + + id = udev_device_get_id_filename(udev_device); + if (id == NULL) + return -1; + util_strscpyl(filename, sizeof(filename), "/run/udev/data/", id, NULL); + unlink(filename); + return 0; +} diff --git a/src/libudev/libudev-device.c b/src/libudev/libudev-device.c new file mode 100644 index 000000000..f218b0278 --- /dev/null +++ b/src/libudev/libudev-device.c @@ -0,0 +1,1799 @@ +/*** + This file is part of systemd. + + Copyright 2008-2012 Kay Sievers + + 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "libudev.h" +#include "libudev-private.h" + +/** + * SECTION:libudev-device + * @short_description: kernel sys devices + * + * Representation of kernel sys devices. Devices are uniquely identified + * by their syspath, every device has exactly one path in the kernel sys + * filesystem. Devices usually belong to a kernel subsystem, and and have + * a unique name inside that subsystem. + */ + +/** + * udev_device: + * + * Opaque object representing one kernel sys device. + */ +struct udev_device { + struct udev *udev; + struct udev_device *parent_device; + char *syspath; + const char *devpath; + char *sysname; + const char *sysnum; + char *devnode; + mode_t devnode_mode; + uid_t devnode_uid; + gid_t devnode_gid; + char *subsystem; + char *devtype; + char *driver; + char *action; + char *devpath_old; + char *id_filename; + char **envp; + char *monitor_buf; + size_t monitor_buf_len; + struct udev_list devlinks_list; + struct udev_list properties_list; + struct udev_list sysattr_value_list; + struct udev_list sysattr_list; + struct udev_list tags_list; + unsigned long long int seqnum; + usec_t usec_initialized; + int devlink_priority; + int refcount; + dev_t devnum; + int ifindex; + int watch_handle; + int maj, min; + bool parent_set; + bool subsystem_set; + bool devtype_set; + bool devlinks_uptodate; + bool envp_uptodate; + bool tags_uptodate; + bool driver_set; + bool info_loaded; + bool db_loaded; + bool uevent_loaded; + bool is_initialized; + bool sysattr_list_read; + bool db_persist; +}; + +/** + * udev_device_get_seqnum: + * @udev_device: udev device + * + * This is only valid if the device was received through a monitor. Devices read from + * sys do not have a sequence number. + * + * Returns: the kernel event sequence number, or 0 if there is no sequence number available. + **/ +_public_ unsigned long long int udev_device_get_seqnum(struct udev_device *udev_device) +{ + if (udev_device == NULL) + return 0; + return udev_device->seqnum; +} + +static int udev_device_set_seqnum(struct udev_device *udev_device, unsigned long long int seqnum) +{ + char num[32]; + + udev_device->seqnum = seqnum; + snprintf(num, sizeof(num), "%llu", seqnum); + udev_device_add_property(udev_device, "SEQNUM", num); + return 0; +} + +int udev_device_get_ifindex(struct udev_device *udev_device) +{ + if (!udev_device->info_loaded) + udev_device_read_uevent_file(udev_device); + return udev_device->ifindex; +} + +static int udev_device_set_ifindex(struct udev_device *udev_device, int ifindex) +{ + char num[32]; + + udev_device->ifindex = ifindex; + snprintf(num, sizeof(num), "%u", ifindex); + udev_device_add_property(udev_device, "IFINDEX", num); + return 0; +} + +/** + * udev_device_get_devnum: + * @udev_device: udev device + * + * Get the device major/minor number. + * + * Returns: the dev_t number. + **/ +_public_ dev_t udev_device_get_devnum(struct udev_device *udev_device) +{ + if (udev_device == NULL) + return makedev(0, 0); + if (!udev_device->info_loaded) + udev_device_read_uevent_file(udev_device); + return udev_device->devnum; +} + +static int udev_device_set_devnum(struct udev_device *udev_device, dev_t devnum) +{ + char num[32]; + + udev_device->devnum = devnum; + + snprintf(num, sizeof(num), "%u", major(devnum)); + udev_device_add_property(udev_device, "MAJOR", num); + snprintf(num, sizeof(num), "%u", minor(devnum)); + udev_device_add_property(udev_device, "MINOR", num); + return 0; +} + +const char *udev_device_get_devpath_old(struct udev_device *udev_device) +{ + return udev_device->devpath_old; +} + +static int udev_device_set_devpath_old(struct udev_device *udev_device, const char *devpath_old) +{ + const char *pos; + + free(udev_device->devpath_old); + udev_device->devpath_old = strdup(devpath_old); + if (udev_device->devpath_old == NULL) + return -ENOMEM; + udev_device_add_property(udev_device, "DEVPATH_OLD", udev_device->devpath_old); + + pos = strrchr(udev_device->devpath_old, '/'); + if (pos == NULL) + return -EINVAL; + return 0; +} + +/** + * udev_device_get_driver: + * @udev_device: udev device + * + * Get the kernel driver name. + * + * Returns: the driver name string, or #NULL if there is no driver attached. + **/ +_public_ const char *udev_device_get_driver(struct udev_device *udev_device) +{ + char driver[UTIL_NAME_SIZE]; + + if (udev_device == NULL) + return NULL; + if (!udev_device->driver_set) { + udev_device->driver_set = true; + if (util_get_sys_core_link_value(udev_device->udev, "driver", udev_device->syspath, driver, sizeof(driver)) > 0) + udev_device->driver = strdup(driver); + } + return udev_device->driver; +} + +static int udev_device_set_driver(struct udev_device *udev_device, const char *driver) +{ + free(udev_device->driver); + udev_device->driver = strdup(driver); + if (udev_device->driver == NULL) + return -ENOMEM; + udev_device->driver_set = true; + udev_device_add_property(udev_device, "DRIVER", udev_device->driver); + return 0; +} + +/** + * udev_device_get_devtype: + * @udev_device: udev device + * + * Retrieve the devtype string of the udev device. + * + * Returns: the devtype name of the udev device, or #NULL if it can not be determined + **/ +_public_ const char *udev_device_get_devtype(struct udev_device *udev_device) +{ + if (udev_device == NULL) + return NULL; + if (!udev_device->devtype_set) { + udev_device->devtype_set = true; + udev_device_read_uevent_file(udev_device); + } + return udev_device->devtype; +} + +static int udev_device_set_devtype(struct udev_device *udev_device, const char *devtype) +{ + free(udev_device->devtype); + udev_device->devtype = strdup(devtype); + if (udev_device->devtype == NULL) + return -ENOMEM; + udev_device->devtype_set = true; + udev_device_add_property(udev_device, "DEVTYPE", udev_device->devtype); + return 0; +} + +int udev_device_set_subsystem(struct udev_device *udev_device, const char *subsystem) +{ + free(udev_device->subsystem); + udev_device->subsystem = strdup(subsystem); + if (udev_device->subsystem == NULL) + return -ENOMEM; + udev_device->subsystem_set = true; + udev_device_add_property(udev_device, "SUBSYSTEM", udev_device->subsystem); + return 0; +} + +/** + * udev_device_get_subsystem: + * @udev_device: udev device + * + * Retrieve the subsystem string of the udev device. The string does not + * contain any "/". + * + * Returns: the subsystem name of the udev device, or #NULL if it can not be determined + **/ +_public_ const char *udev_device_get_subsystem(struct udev_device *udev_device) +{ + char subsystem[UTIL_NAME_SIZE]; + + if (udev_device == NULL) + return NULL; + if (!udev_device->subsystem_set) { + udev_device->subsystem_set = true; + /* read "subsystem" link */ + if (util_get_sys_core_link_value(udev_device->udev, "subsystem", udev_device->syspath, subsystem, sizeof(subsystem)) > 0) { + udev_device_set_subsystem(udev_device, subsystem); + return udev_device->subsystem; + } + /* implicit names */ + if (startswith(udev_device->devpath, "/module/")) { + udev_device_set_subsystem(udev_device, "module"); + return udev_device->subsystem; + } + if (strstr(udev_device->devpath, "/drivers/") != NULL) { + udev_device_set_subsystem(udev_device, "drivers"); + return udev_device->subsystem; + } + if (startswith(udev_device->devpath, "/subsystem/") || + startswith(udev_device->devpath, "/class/") || + startswith(udev_device->devpath, "/bus/")) { + udev_device_set_subsystem(udev_device, "subsystem"); + return udev_device->subsystem; + } + } + return udev_device->subsystem; +} + +mode_t udev_device_get_devnode_mode(struct udev_device *udev_device) +{ + if (!udev_device->info_loaded) + udev_device_read_uevent_file(udev_device); + return udev_device->devnode_mode; +} + +static int udev_device_set_devnode_mode(struct udev_device *udev_device, mode_t mode) +{ + char num[32]; + + udev_device->devnode_mode = mode; + snprintf(num, sizeof(num), "%#o", mode); + udev_device_add_property(udev_device, "DEVMODE", num); + return 0; +} + +uid_t udev_device_get_devnode_uid(struct udev_device *udev_device) +{ + if (!udev_device->info_loaded) + udev_device_read_uevent_file(udev_device); + return udev_device->devnode_uid; +} + +static int udev_device_set_devnode_uid(struct udev_device *udev_device, uid_t uid) +{ + char num[32]; + + udev_device->devnode_uid = uid; + snprintf(num, sizeof(num), "%u", uid); + udev_device_add_property(udev_device, "DEVUID", num); + return 0; +} + +gid_t udev_device_get_devnode_gid(struct udev_device *udev_device) +{ + if (!udev_device->info_loaded) + udev_device_read_uevent_file(udev_device); + return udev_device->devnode_gid; +} + +static int udev_device_set_devnode_gid(struct udev_device *udev_device, gid_t gid) +{ + char num[32]; + + udev_device->devnode_gid = gid; + snprintf(num, sizeof(num), "%u", gid); + udev_device_add_property(udev_device, "DEVGID", num); + return 0; +} + +struct udev_list_entry *udev_device_add_property(struct udev_device *udev_device, const char *key, const char *value) +{ + udev_device->envp_uptodate = false; + if (value == NULL) { + struct udev_list_entry *list_entry; + + list_entry = udev_device_get_properties_list_entry(udev_device); + list_entry = udev_list_entry_get_by_name(list_entry, key); + if (list_entry != NULL) + udev_list_entry_delete(list_entry); + return NULL; + } + return udev_list_entry_add(&udev_device->properties_list, key, value); +} + +static struct udev_list_entry *udev_device_add_property_from_string(struct udev_device *udev_device, const char *property) +{ + char name[UTIL_LINE_SIZE]; + char *val; + + util_strscpy(name, sizeof(name), property); + val = strchr(name, '='); + if (val == NULL) + return NULL; + val[0] = '\0'; + val = &val[1]; + if (val[0] == '\0') + val = NULL; + return udev_device_add_property(udev_device, name, val); +} + +/* + * parse property string, and if needed, update internal values accordingly + * + * udev_device_add_property_from_string_parse_finish() needs to be + * called after adding properties, and its return value checked + * + * udev_device_set_info_loaded() needs to be set, to avoid trying + * to use a device without a DEVPATH set + */ +void udev_device_add_property_from_string_parse(struct udev_device *udev_device, const char *property) +{ + if (startswith(property, "DEVPATH=")) { + char path[UTIL_PATH_SIZE]; + + util_strscpyl(path, sizeof(path), "/sys", &property[8], NULL); + udev_device_set_syspath(udev_device, path); + } else if (startswith(property, "SUBSYSTEM=")) { + udev_device_set_subsystem(udev_device, &property[10]); + } else if (startswith(property, "DEVTYPE=")) { + udev_device_set_devtype(udev_device, &property[8]); + } else if (startswith(property, "DEVNAME=")) { + udev_device_set_devnode(udev_device, &property[8]); + } else if (startswith(property, "DEVLINKS=")) { + char devlinks[UTIL_PATH_SIZE]; + char *slink; + char *next; + + util_strscpy(devlinks, sizeof(devlinks), &property[9]); + slink = devlinks; + next = strchr(slink, ' '); + while (next != NULL) { + next[0] = '\0'; + udev_device_add_devlink(udev_device, slink); + slink = &next[1]; + next = strchr(slink, ' '); + } + if (slink[0] != '\0') + udev_device_add_devlink(udev_device, slink); + } else if (startswith(property, "TAGS=")) { + char tags[UTIL_PATH_SIZE]; + char *next; + + util_strscpy(tags, sizeof(tags), &property[5]); + next = strchr(tags, ':'); + if (next != NULL) { + next++; + while (next[0] != '\0') { + char *tag; + + tag = next; + next = strchr(tag, ':'); + if (next == NULL) + break; + next[0] = '\0'; + next++; + udev_device_add_tag(udev_device, tag); + } + } + } else if (startswith(property, "USEC_INITIALIZED=")) { + udev_device_set_usec_initialized(udev_device, strtoull(&property[19], NULL, 10)); + } else if (startswith(property, "DRIVER=")) { + udev_device_set_driver(udev_device, &property[7]); + } else if (startswith(property, "ACTION=")) { + udev_device_set_action(udev_device, &property[7]); + } else if (startswith(property, "MAJOR=")) { + udev_device->maj = strtoull(&property[6], NULL, 10); + } else if (startswith(property, "MINOR=")) { + udev_device->min = strtoull(&property[6], NULL, 10); + } else if (startswith(property, "DEVPATH_OLD=")) { + udev_device_set_devpath_old(udev_device, &property[12]); + } else if (startswith(property, "SEQNUM=")) { + udev_device_set_seqnum(udev_device, strtoull(&property[7], NULL, 10)); + } else if (startswith(property, "IFINDEX=")) { + udev_device_set_ifindex(udev_device, strtoull(&property[8], NULL, 10)); + } else if (startswith(property, "DEVMODE=")) { + udev_device_set_devnode_mode(udev_device, strtoul(&property[8], NULL, 8)); + } else if (startswith(property, "DEVUID=")) { + udev_device_set_devnode_uid(udev_device, strtoul(&property[7], NULL, 10)); + } else if (startswith(property, "DEVGID=")) { + udev_device_set_devnode_gid(udev_device, strtoul(&property[7], NULL, 10)); + } else { + udev_device_add_property_from_string(udev_device, property); + } +} + +int udev_device_add_property_from_string_parse_finish(struct udev_device *udev_device) +{ + if (udev_device->maj > 0) + udev_device_set_devnum(udev_device, makedev(udev_device->maj, udev_device->min)); + udev_device->maj = 0; + udev_device->min = 0; + + if (udev_device->devpath == NULL || udev_device->subsystem == NULL) + return -EINVAL; + return 0; +} + +/** + * udev_device_get_property_value: + * @udev_device: udev device + * @key: property name + * + * Get the value of a given property. + * + * Returns: the property string, or #NULL if there is no such property. + **/ +_public_ const char *udev_device_get_property_value(struct udev_device *udev_device, const char *key) +{ + struct udev_list_entry *list_entry; + + if (udev_device == NULL) + return NULL; + if (key == NULL) + return NULL; + + list_entry = udev_device_get_properties_list_entry(udev_device); + list_entry = udev_list_entry_get_by_name(list_entry, key); + return udev_list_entry_get_value(list_entry); +} + +int udev_device_read_db(struct udev_device *udev_device, const char *dbfile) +{ + char filename[UTIL_PATH_SIZE]; + char line[UTIL_LINE_SIZE]; + FILE *f; + + /* providing a database file will always force-load it */ + if (dbfile == NULL) { + const char *id; + + if (udev_device->db_loaded) + return 0; + udev_device->db_loaded = true; + + id = udev_device_get_id_filename(udev_device); + if (id == NULL) + return -1; + util_strscpyl(filename, sizeof(filename), "/run/udev/data/", id, NULL); + dbfile = filename; + } + + f = fopen(dbfile, "re"); + if (f == NULL) { + udev_dbg(udev_device->udev, "no db file to read %s: %m\n", dbfile); + return -1; + } + udev_device->is_initialized = true; + + while (fgets(line, sizeof(line), f)) { + ssize_t len; + const char *val; + struct udev_list_entry *entry; + + len = strlen(line); + if (len < 4) + break; + line[len-1] = '\0'; + val = &line[2]; + switch(line[0]) { + case 'S': + util_strscpyl(filename, sizeof(filename), "/dev/", val, NULL); + udev_device_add_devlink(udev_device, filename); + break; + case 'L': + udev_device_set_devlink_priority(udev_device, atoi(val)); + break; + case 'E': + entry = udev_device_add_property_from_string(udev_device, val); + udev_list_entry_set_num(entry, true); + break; + case 'G': + udev_device_add_tag(udev_device, val); + break; + case 'W': + udev_device_set_watch_handle(udev_device, atoi(val)); + break; + case 'I': + udev_device_set_usec_initialized(udev_device, strtoull(val, NULL, 10)); + break; + } + } + fclose(f); + + udev_dbg(udev_device->udev, "device %p filled with db file data\n", udev_device); + return 0; +} + +int udev_device_read_uevent_file(struct udev_device *udev_device) +{ + char filename[UTIL_PATH_SIZE]; + FILE *f; + char line[UTIL_LINE_SIZE]; + int maj = 0; + int min = 0; + + if (udev_device->uevent_loaded) + return 0; + + util_strscpyl(filename, sizeof(filename), udev_device->syspath, "/uevent", NULL); + f = fopen(filename, "re"); + if (f == NULL) + return -1; + udev_device->uevent_loaded = true; + + while (fgets(line, sizeof(line), f)) { + char *pos; + + pos = strchr(line, '\n'); + if (pos == NULL) + continue; + pos[0] = '\0'; + + if (startswith(line, "DEVTYPE=")) { + udev_device_set_devtype(udev_device, &line[8]); + continue; + } + if (startswith(line, "IFINDEX=")) { + udev_device_set_ifindex(udev_device, strtoull(&line[8], NULL, 10)); + continue; + } + if (startswith(line, "DEVNAME=")) { + udev_device_set_devnode(udev_device, &line[8]); + continue; + } + + if (startswith(line, "MAJOR=")) + maj = strtoull(&line[6], NULL, 10); + else if (startswith(line, "MINOR=")) + min = strtoull(&line[6], NULL, 10); + else if (startswith(line, "DEVMODE=")) + udev_device->devnode_mode = strtoul(&line[8], NULL, 8); + + udev_device_add_property_from_string(udev_device, line); + } + + udev_device->devnum = makedev(maj, min); + fclose(f); + return 0; +} + +void udev_device_set_info_loaded(struct udev_device *device) +{ + device->info_loaded = true; +} + +struct udev_device *udev_device_new(struct udev *udev) +{ + struct udev_device *udev_device; + struct udev_list_entry *list_entry; + + if (udev == NULL) + return NULL; + + udev_device = calloc(1, sizeof(struct udev_device)); + if (udev_device == NULL) + return NULL; + udev_device->refcount = 1; + udev_device->udev = udev; + udev_list_init(udev, &udev_device->devlinks_list, true); + udev_list_init(udev, &udev_device->properties_list, true); + udev_list_init(udev, &udev_device->sysattr_value_list, true); + udev_list_init(udev, &udev_device->sysattr_list, false); + udev_list_init(udev, &udev_device->tags_list, true); + udev_device->watch_handle = -1; + /* copy global properties */ + udev_list_entry_foreach(list_entry, udev_get_properties_list_entry(udev)) + udev_device_add_property(udev_device, + udev_list_entry_get_name(list_entry), + udev_list_entry_get_value(list_entry)); + return udev_device; +} + +/** + * udev_device_new_from_syspath: + * @udev: udev library context + * @syspath: sys device path including sys directory + * + * Create new udev device, and fill in information from the sys + * device and the udev database entry. The syspath is the absolute + * path to the device, including the sys mount point. + * + * The initial refcount is 1, and needs to be decremented to + * release the resources of the udev device. + * + * Returns: a new udev device, or #NULL, if it does not exist + **/ +_public_ struct udev_device *udev_device_new_from_syspath(struct udev *udev, const char *syspath) +{ + const char *subdir; + char path[UTIL_PATH_SIZE]; + char *pos; + struct stat statbuf; + struct udev_device *udev_device; + + if (udev == NULL) + return NULL; + if (syspath == NULL) + return NULL; + + /* path starts in sys */ + if (!startswith(syspath, "/sys")) { + udev_dbg(udev, "not in sys :%s\n", syspath); + return NULL; + } + + /* path is not a root directory */ + subdir = syspath + strlen("/sys"); + pos = strrchr(subdir, '/'); + if (pos == NULL || pos[1] == '\0' || pos < &subdir[2]) + return NULL; + + /* resolve possible symlink to real path */ + util_strscpy(path, sizeof(path), syspath); + util_resolve_sys_link(udev, path, sizeof(path)); + + if (startswith(path + strlen("/sys"), "/devices/")) { + char file[UTIL_PATH_SIZE]; + + /* all "devices" require a "uevent" file */ + util_strscpyl(file, sizeof(file), path, "/uevent", NULL); + if (stat(file, &statbuf) != 0) + return NULL; + } else { + /* everything else just needs to be a directory */ + if (stat(path, &statbuf) != 0 || !S_ISDIR(statbuf.st_mode)) + return NULL; + } + + udev_device = udev_device_new(udev); + if (udev_device == NULL) + return NULL; + + udev_device_set_syspath(udev_device, path); + udev_dbg(udev, "device %p has devpath '%s'\n", udev_device, udev_device_get_devpath(udev_device)); + + return udev_device; +} + +/** + * udev_device_new_from_devnum: + * @udev: udev library context + * @type: char or block device + * @devnum: device major/minor number + * + * Create new udev device, and fill in information from the sys + * device and the udev database entry. The device is looked-up + * by its major/minor number and type. Character and block device + * numbers are not unique across the two types. + * + * The initial refcount is 1, and needs to be decremented to + * release the resources of the udev device. + * + * Returns: a new udev device, or #NULL, if it does not exist + **/ +_public_ struct udev_device *udev_device_new_from_devnum(struct udev *udev, char type, dev_t devnum) +{ + char path[UTIL_PATH_SIZE]; + const char *type_str; + + if (type == 'b') + type_str = "block"; + else if (type == 'c') + type_str = "char"; + else + return NULL; + + /* use /sys/dev/{block,char}/: link */ + snprintf(path, sizeof(path), "/sys/dev/%s/%u:%u", + type_str, major(devnum), minor(devnum)); + return udev_device_new_from_syspath(udev, path); +} + +/** + * udev_device_new_from_device_id: + * @udev: udev library context + * @id: text string identifying a kernel device + * + * Create new udev device, and fill in information from the sys + * device and the udev database entry. The device is looked-up + * by a special string: + * b8:2 - block device major:minor + * c128:1 - char device major:minor + * n3 - network device ifindex + * +sound:card29 - kernel driver core subsystem:device name + * + * The initial refcount is 1, and needs to be decremented to + * release the resources of the udev device. + * + * Returns: a new udev device, or #NULL, if it does not exist + **/ +_public_ struct udev_device *udev_device_new_from_device_id(struct udev *udev, char *id) +{ + char type; + int maj, min; + char subsys[UTIL_PATH_SIZE]; + char *sysname; + + switch(id[0]) { + case 'b': + case 'c': + if (sscanf(id, "%c%i:%i", &type, &maj, &min) != 3) + return NULL; + return udev_device_new_from_devnum(udev, type, makedev(maj, min)); + case 'n': { + int sk; + struct ifreq ifr; + struct udev_device *dev; + int ifindex; + + ifindex = strtoul(&id[1], NULL, 10); + if (ifindex <= 0) + return NULL; + + sk = socket(PF_INET, SOCK_DGRAM, 0); + if (sk < 0) + return NULL; + memset(&ifr, 0x00, sizeof(struct ifreq)); + ifr.ifr_ifindex = ifindex; + if (ioctl(sk, SIOCGIFNAME, &ifr) != 0) { + close(sk); + return NULL; + } + close(sk); + + dev = udev_device_new_from_subsystem_sysname(udev, "net", ifr.ifr_name); + if (dev == NULL) + return NULL; + if (udev_device_get_ifindex(dev) == ifindex) + return dev; + udev_device_unref(dev); + return NULL; + } + case '+': + util_strscpy(subsys, sizeof(subsys), &id[1]); + sysname = strchr(subsys, ':'); + if (sysname == NULL) + return NULL; + sysname[0] = '\0'; + sysname = &sysname[1]; + return udev_device_new_from_subsystem_sysname(udev, subsys, sysname); + default: + return NULL; + } +} + +/** + * udev_device_new_from_subsystem_sysname: + * @udev: udev library context + * @subsystem: the subsystem of the device + * @sysname: the name of the device + * + * Create new udev device, and fill in information from the sys device + * and the udev database entry. The device is looked up by the subsystem + * and name string of the device, like "mem" / "zero", or "block" / "sda". + * + * The initial refcount is 1, and needs to be decremented to + * release the resources of the udev device. + * + * Returns: a new udev device, or #NULL, if it does not exist + **/ +_public_ struct udev_device *udev_device_new_from_subsystem_sysname(struct udev *udev, const char *subsystem, const char *sysname) +{ + char path[UTIL_PATH_SIZE]; + struct stat statbuf; + + if (streq(subsystem, "subsystem")) { + util_strscpyl(path, sizeof(path), "/sys/subsystem/", sysname, NULL); + if (stat(path, &statbuf) == 0) + goto found; + + util_strscpyl(path, sizeof(path), "/sys/bus/", sysname, NULL); + if (stat(path, &statbuf) == 0) + goto found; + + util_strscpyl(path, sizeof(path), "/sys/class/", sysname, NULL); + if (stat(path, &statbuf) == 0) + goto found; + goto out; + } + + if (streq(subsystem, "module")) { + util_strscpyl(path, sizeof(path), "/sys/module/", sysname, NULL); + if (stat(path, &statbuf) == 0) + goto found; + goto out; + } + + if (streq(subsystem, "drivers")) { + char subsys[UTIL_NAME_SIZE]; + char *driver; + + util_strscpy(subsys, sizeof(subsys), sysname); + driver = strchr(subsys, ':'); + if (driver != NULL) { + driver[0] = '\0'; + driver = &driver[1]; + + util_strscpyl(path, sizeof(path), "/sys/subsystem/", subsys, "/drivers/", driver, NULL); + if (stat(path, &statbuf) == 0) + goto found; + + util_strscpyl(path, sizeof(path), "/sys/bus/", subsys, "/drivers/", driver, NULL); + if (stat(path, &statbuf) == 0) + goto found; + } + goto out; + } + + util_strscpyl(path, sizeof(path), "/sys/subsystem/", subsystem, "/devices/", sysname, NULL); + if (stat(path, &statbuf) == 0) + goto found; + + util_strscpyl(path, sizeof(path), "/sys/bus/", subsystem, "/devices/", sysname, NULL); + if (stat(path, &statbuf) == 0) + goto found; + + util_strscpyl(path, sizeof(path), "/sys/class/", subsystem, "/", sysname, NULL); + if (stat(path, &statbuf) == 0) + goto found; +out: + return NULL; +found: + return udev_device_new_from_syspath(udev, path); +} + +/** + * udev_device_new_from_environment + * @udev: udev library context + * + * Create new udev device, and fill in information from the + * current process environment. This only works reliable if + * the process is called from a udev rule. It is usually used + * for tools executed from IMPORT= rules. + * + * The initial refcount is 1, and needs to be decremented to + * release the resources of the udev device. + * + * Returns: a new udev device, or #NULL, if it does not exist + **/ +_public_ struct udev_device *udev_device_new_from_environment(struct udev *udev) +{ + int i; + struct udev_device *udev_device; + + udev_device = udev_device_new(udev); + if (udev_device == NULL) + return NULL; + udev_device_set_info_loaded(udev_device); + + for (i = 0; environ[i] != NULL; i++) + udev_device_add_property_from_string_parse(udev_device, environ[i]); + + if (udev_device_add_property_from_string_parse_finish(udev_device) < 0) { + udev_dbg(udev, "missing values, invalid device\n"); + udev_device_unref(udev_device); + udev_device = NULL; + } + + return udev_device; +} + +static struct udev_device *device_new_from_parent(struct udev_device *udev_device) +{ + struct udev_device *udev_device_parent = NULL; + char path[UTIL_PATH_SIZE]; + const char *subdir; + + util_strscpy(path, sizeof(path), udev_device->syspath); + subdir = path + strlen("/sys/"); + for (;;) { + char *pos; + + pos = strrchr(subdir, '/'); + if (pos == NULL || pos < &subdir[2]) + break; + pos[0] = '\0'; + udev_device_parent = udev_device_new_from_syspath(udev_device->udev, path); + if (udev_device_parent != NULL) + return udev_device_parent; + } + return NULL; +} + +/** + * udev_device_get_parent: + * @udev_device: the device to start searching from + * + * Find the next parent device, and fill in information from the sys + * device and the udev database entry. + * + * The returned the device is not referenced. It is attached to the + * child device, and will be cleaned up when the child device + * is cleaned up. + * + * It is not necessarily just the upper level directory, empty or not + * recognized sys directories are ignored. + * + * It can be called as many times as needed, without caring about + * references. + * + * Returns: a new udev device, or #NULL, if it no parent exist. + **/ +_public_ struct udev_device *udev_device_get_parent(struct udev_device *udev_device) +{ + if (udev_device == NULL) + return NULL; + if (!udev_device->parent_set) { + udev_device->parent_set = true; + udev_device->parent_device = device_new_from_parent(udev_device); + } + return udev_device->parent_device; +} + +/** + * udev_device_get_parent_with_subsystem_devtype: + * @udev_device: udev device to start searching from + * @subsystem: the subsystem of the device + * @devtype: the type (DEVTYPE) of the device + * + * Find the next parent device, with a matching subsystem and devtype + * value, and fill in information from the sys device and the udev + * database entry. + * + * If devtype is #NULL, only subsystem is checked, and any devtype will + * match. + * + * The returned the device is not referenced. It is attached to the + * child device, and will be cleaned up when the child device + * is cleaned up. + * + * It can be called as many times as needed, without caring about + * references. + * + * Returns: a new udev device, or #NULL if no matching parent exists. + **/ +_public_ struct udev_device *udev_device_get_parent_with_subsystem_devtype(struct udev_device *udev_device, const char *subsystem, const char *devtype) +{ + struct udev_device *parent; + + if (subsystem == NULL) + return NULL; + + parent = udev_device_get_parent(udev_device); + while (parent != NULL) { + const char *parent_subsystem; + const char *parent_devtype; + + parent_subsystem = udev_device_get_subsystem(parent); + if (parent_subsystem != NULL && streq(parent_subsystem, subsystem)) { + if (devtype == NULL) + break; + parent_devtype = udev_device_get_devtype(parent); + if (parent_devtype != NULL && streq(parent_devtype, devtype)) + break; + } + parent = udev_device_get_parent(parent); + } + return parent; +} + +/** + * udev_device_get_udev: + * @udev_device: udev device + * + * Retrieve the udev library context the device was created with. + * + * Returns: the udev library context + **/ +_public_ struct udev *udev_device_get_udev(struct udev_device *udev_device) +{ + if (udev_device == NULL) + return NULL; + return udev_device->udev; +} + +/** + * udev_device_ref: + * @udev_device: udev device + * + * Take a reference of a udev device. + * + * Returns: the passed udev device + **/ +_public_ struct udev_device *udev_device_ref(struct udev_device *udev_device) +{ + if (udev_device == NULL) + return NULL; + udev_device->refcount++; + return udev_device; +} + +/** + * udev_device_unref: + * @udev_device: udev device + * + * Drop a reference of a udev device. If the refcount reaches zero, + * the resources of the device will be released. + * + * Returns: the passed udev device if it has still an active reference, or #NULL otherwise. + **/ +_public_ struct udev_device *udev_device_unref(struct udev_device *udev_device) +{ + if (udev_device == NULL) + return NULL; + udev_device->refcount--; + if (udev_device->refcount > 0) + return udev_device; + if (udev_device->parent_device != NULL) + udev_device_unref(udev_device->parent_device); + free(udev_device->syspath); + free(udev_device->sysname); + free(udev_device->devnode); + free(udev_device->subsystem); + free(udev_device->devtype); + udev_list_cleanup(&udev_device->devlinks_list); + udev_list_cleanup(&udev_device->properties_list); + udev_list_cleanup(&udev_device->sysattr_value_list); + udev_list_cleanup(&udev_device->sysattr_list); + udev_list_cleanup(&udev_device->tags_list); + free(udev_device->action); + free(udev_device->driver); + free(udev_device->devpath_old); + free(udev_device->id_filename); + free(udev_device->envp); + free(udev_device->monitor_buf); + free(udev_device); + return NULL; +} + +/** + * udev_device_get_devpath: + * @udev_device: udev device + * + * Retrieve the kernel devpath value of the udev device. The path + * does not contain the sys mount point, and starts with a '/'. + * + * Returns: the devpath of the udev device + **/ +_public_ const char *udev_device_get_devpath(struct udev_device *udev_device) +{ + if (udev_device == NULL) + return NULL; + return udev_device->devpath; +} + +/** + * udev_device_get_syspath: + * @udev_device: udev device + * + * Retrieve the sys path of the udev device. The path is an + * absolute path and starts with the sys mount point. + * + * Returns: the sys path of the udev device + **/ +_public_ const char *udev_device_get_syspath(struct udev_device *udev_device) +{ + if (udev_device == NULL) + return NULL; + return udev_device->syspath; +} + +/** + * udev_device_get_sysname: + * @udev_device: udev device + * + * Get the kernel device name in /sys. + * + * Returns: the name string of the device device + **/ +_public_ const char *udev_device_get_sysname(struct udev_device *udev_device) +{ + if (udev_device == NULL) + return NULL; + return udev_device->sysname; +} + +/** + * udev_device_get_sysnum: + * @udev_device: udev device + * + * Get the instance number of the device. + * + * Returns: the trailing number string of the device name + **/ +_public_ const char *udev_device_get_sysnum(struct udev_device *udev_device) +{ + if (udev_device == NULL) + return NULL; + return udev_device->sysnum; +} + +/** + * udev_device_get_devnode: + * @udev_device: udev device + * + * Retrieve the device node file name belonging to the udev device. + * The path is an absolute path, and starts with the device directory. + * + * Returns: the device node file name of the udev device, or #NULL if no device node exists + **/ +_public_ const char *udev_device_get_devnode(struct udev_device *udev_device) +{ + if (udev_device == NULL) + return NULL; + if (udev_device->devnode != NULL) + return udev_device->devnode; + if (!udev_device->info_loaded) + udev_device_read_uevent_file(udev_device); + return udev_device->devnode; +} + +/** + * udev_device_get_devlinks_list_entry: + * @udev_device: udev device + * + * Retrieve the list of device links pointing to the device file of + * the udev device. The next list entry can be retrieved with + * udev_list_entry_get_next(), which returns #NULL if no more entries exist. + * The devlink path can be retrieved from the list entry by + * udev_list_entry_get_name(). The path is an absolute path, and starts with + * the device directory. + * + * Returns: the first entry of the device node link list + **/ +_public_ struct udev_list_entry *udev_device_get_devlinks_list_entry(struct udev_device *udev_device) +{ + if (udev_device == NULL) + return NULL; + if (!udev_device->info_loaded) + udev_device_read_db(udev_device, NULL); + return udev_list_get_entry(&udev_device->devlinks_list); +} + +void udev_device_cleanup_devlinks_list(struct udev_device *udev_device) +{ + udev_device->devlinks_uptodate = false; + udev_list_cleanup(&udev_device->devlinks_list); +} + +/** + * udev_device_get_properties_list_entry: + * @udev_device: udev device + * + * Retrieve the list of key/value device properties of the udev + * device. The next list entry can be retrieved with udev_list_entry_get_next(), + * which returns #NULL if no more entries exist. The property name + * can be retrieved from the list entry by udev_list_entry_get_name(), + * the property value by udev_list_entry_get_value(). + * + * Returns: the first entry of the property list + **/ +_public_ struct udev_list_entry *udev_device_get_properties_list_entry(struct udev_device *udev_device) +{ + if (udev_device == NULL) + return NULL; + if (!udev_device->info_loaded) { + udev_device_read_uevent_file(udev_device); + udev_device_read_db(udev_device, NULL); + } + if (!udev_device->devlinks_uptodate) { + char symlinks[UTIL_PATH_SIZE]; + struct udev_list_entry *list_entry; + + udev_device->devlinks_uptodate = true; + list_entry = udev_device_get_devlinks_list_entry(udev_device); + if (list_entry != NULL) { + char *s; + size_t l; + + s = symlinks; + l = util_strpcpyl(&s, sizeof(symlinks), udev_list_entry_get_name(list_entry), NULL); + udev_list_entry_foreach(list_entry, udev_list_entry_get_next(list_entry)) + l = util_strpcpyl(&s, l, " ", udev_list_entry_get_name(list_entry), NULL); + udev_device_add_property(udev_device, "DEVLINKS", symlinks); + } + } + if (!udev_device->tags_uptodate) { + udev_device->tags_uptodate = true; + if (udev_device_get_tags_list_entry(udev_device) != NULL) { + char tags[UTIL_PATH_SIZE]; + struct udev_list_entry *list_entry; + char *s; + size_t l; + + s = tags; + l = util_strpcpyl(&s, sizeof(tags), ":", NULL); + udev_list_entry_foreach(list_entry, udev_device_get_tags_list_entry(udev_device)) + l = util_strpcpyl(&s, l, udev_list_entry_get_name(list_entry), ":", NULL); + udev_device_add_property(udev_device, "TAGS", tags); + } + } + return udev_list_get_entry(&udev_device->properties_list); +} + +/** + * udev_device_get_action: + * @udev_device: udev device + * + * This is only valid if the device was received through a monitor. Devices read from + * sys do not have an action string. Usual actions are: add, remove, change, online, + * offline. + * + * Returns: the kernel action value, or #NULL if there is no action value available. + **/ +_public_ const char *udev_device_get_action(struct udev_device *udev_device) +{ + if (udev_device == NULL) + return NULL; + return udev_device->action; +} + +/** + * udev_device_get_usec_since_initialized: + * @udev_device: udev device + * + * Return the number of microseconds passed since udev set up the + * device for the first time. + * + * This is only implemented for devices with need to store properties + * in the udev database. All other devices return 0 here. + * + * Returns: the number of microseconds since the device was first seen. + **/ +_public_ unsigned long long int udev_device_get_usec_since_initialized(struct udev_device *udev_device) +{ + usec_t now_ts; + + if (udev_device == NULL) + return 0; + if (!udev_device->info_loaded) + udev_device_read_db(udev_device, NULL); + if (udev_device->usec_initialized == 0) + return 0; + now_ts = now(CLOCK_MONOTONIC); + if (now_ts == 0) + return 0; + return now_ts - udev_device->usec_initialized; +} + +usec_t udev_device_get_usec_initialized(struct udev_device *udev_device) +{ + return udev_device->usec_initialized; +} + +void udev_device_set_usec_initialized(struct udev_device *udev_device, usec_t usec_initialized) +{ + char num[32]; + + udev_device->usec_initialized = usec_initialized; + snprintf(num, sizeof(num), "%llu", (unsigned long long)usec_initialized); + udev_device_add_property(udev_device, "USEC_INITIALIZED", num); +} + +/** + * udev_device_get_sysattr_value: + * @udev_device: udev device + * @sysattr: attribute name + * + * The retrieved value is cached in the device. Repeated calls will return the same + * value and not open the attribute again. + * + * Returns: the content of a sys attribute file, or #NULL if there is no sys attribute value. + **/ +_public_ const char *udev_device_get_sysattr_value(struct udev_device *udev_device, const char *sysattr) +{ + struct udev_list_entry *list_entry; + char path[UTIL_PATH_SIZE]; + char value[4096]; + struct stat statbuf; + int fd; + ssize_t size; + const char *val = NULL; + + if (udev_device == NULL) + return NULL; + if (sysattr == NULL) + return NULL; + + /* look for possibly already cached result */ + list_entry = udev_list_get_entry(&udev_device->sysattr_value_list); + list_entry = udev_list_entry_get_by_name(list_entry, sysattr); + if (list_entry != NULL) + return udev_list_entry_get_value(list_entry); + + util_strscpyl(path, sizeof(path), udev_device_get_syspath(udev_device), "/", sysattr, NULL); + if (lstat(path, &statbuf) != 0) { + udev_list_entry_add(&udev_device->sysattr_value_list, sysattr, NULL); + goto out; + } + + if (S_ISLNK(statbuf.st_mode)) { + struct udev_device *dev; + + /* + * Some core links return only the last element of the target path, + * these are just values, the paths should not be exposed. + */ + if (streq(sysattr, "driver") || + streq(sysattr, "subsystem") || + streq(sysattr, "module")) { + if (util_get_sys_core_link_value(udev_device->udev, sysattr, + udev_device->syspath, value, sizeof(value)) < 0) + return NULL; + list_entry = udev_list_entry_add(&udev_device->sysattr_value_list, sysattr, value); + val = udev_list_entry_get_value(list_entry); + goto out; + } + + /* resolve custom link to a device and return its syspath */ + if (!streq(sysattr, "device")) { + util_strscpyl(path, sizeof(path), udev_device->syspath, "/", sysattr, NULL); + dev = udev_device_new_from_syspath(udev_device->udev, path); + if (dev != NULL) { + list_entry = udev_list_entry_add(&udev_device->sysattr_value_list, sysattr, + udev_device_get_syspath(dev)); + val = udev_list_entry_get_value(list_entry); + udev_device_unref(dev); + } + } + goto out; + } + + /* skip directories */ + if (S_ISDIR(statbuf.st_mode)) + goto out; + + /* skip non-readable files */ + if ((statbuf.st_mode & S_IRUSR) == 0) + goto out; + + /* read attribute value */ + fd = open(path, O_RDONLY|O_CLOEXEC); + if (fd < 0) + goto out; + size = read(fd, value, sizeof(value)); + close(fd); + if (size < 0) + goto out; + if (size == sizeof(value)) + goto out; + + /* got a valid value, store it in cache and return it */ + value[size] = '\0'; + util_remove_trailing_chars(value, '\n'); + list_entry = udev_list_entry_add(&udev_device->sysattr_value_list, sysattr, value); + val = udev_list_entry_get_value(list_entry); +out: + return val; +} + +static int udev_device_sysattr_list_read(struct udev_device *udev_device) +{ + struct dirent *dent; + DIR *dir; + int num = 0; + + if (udev_device == NULL) + return -1; + if (udev_device->sysattr_list_read) + return 0; + + dir = opendir(udev_device_get_syspath(udev_device)); + if (!dir) + return -1; + + for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) { + char path[UTIL_PATH_SIZE]; + struct stat statbuf; + + /* only handle symlinks and regular files */ + if (dent->d_type != DT_LNK && dent->d_type != DT_REG) + continue; + + util_strscpyl(path, sizeof(path), udev_device_get_syspath(udev_device), "/", dent->d_name, NULL); + if (lstat(path, &statbuf) != 0) + continue; + if ((statbuf.st_mode & S_IRUSR) == 0) + continue; + + udev_list_entry_add(&udev_device->sysattr_list, dent->d_name, NULL); + num++; + } + + closedir(dir); + udev_device->sysattr_list_read = true; + + return num; +} + +/** + * udev_device_get_sysattr_list_entry: + * @udev_device: udev device + * + * Retrieve the list of available sysattrs, with value being empty; + * This just return all available sysfs attributes for a particular + * device without reading their values. + * + * Returns: the first entry of the property list + **/ +_public_ struct udev_list_entry *udev_device_get_sysattr_list_entry(struct udev_device *udev_device) +{ + if (!udev_device->sysattr_list_read) { + int ret; + ret = udev_device_sysattr_list_read(udev_device); + if (0 > ret) + return NULL; + } + + return udev_list_get_entry(&udev_device->sysattr_list); +} + +int udev_device_set_syspath(struct udev_device *udev_device, const char *syspath) +{ + const char *pos; + size_t len; + + free(udev_device->syspath); + udev_device->syspath = strdup(syspath); + if (udev_device->syspath == NULL) + return -ENOMEM; + udev_device->devpath = udev_device->syspath + strlen("/sys"); + udev_device_add_property(udev_device, "DEVPATH", udev_device->devpath); + + pos = strrchr(udev_device->syspath, '/'); + if (pos == NULL) + return -EINVAL; + udev_device->sysname = strdup(&pos[1]); + if (udev_device->sysname == NULL) + return -ENOMEM; + + /* some devices have '!' in their name, change that to '/' */ + len = 0; + while (udev_device->sysname[len] != '\0') { + if (udev_device->sysname[len] == '!') + udev_device->sysname[len] = '/'; + len++; + } + + /* trailing number */ + while (len > 0 && isdigit(udev_device->sysname[--len])) + udev_device->sysnum = &udev_device->sysname[len]; + + /* sysname is completely numeric */ + if (len == 0) + udev_device->sysnum = NULL; + + return 0; +} + +int udev_device_set_devnode(struct udev_device *udev_device, const char *devnode) +{ + free(udev_device->devnode); + if (devnode[0] != '/') { + if (asprintf(&udev_device->devnode, "/dev/%s", devnode) < 0) + udev_device->devnode = NULL; + } else { + udev_device->devnode = strdup(devnode); + } + if (udev_device->devnode == NULL) + return -ENOMEM; + udev_device_add_property(udev_device, "DEVNAME", udev_device->devnode); + return 0; +} + +int udev_device_add_devlink(struct udev_device *udev_device, const char *devlink) +{ + struct udev_list_entry *list_entry; + + udev_device->devlinks_uptodate = false; + list_entry = udev_list_entry_add(&udev_device->devlinks_list, devlink, NULL); + if (list_entry == NULL) + return -ENOMEM; + return 0; +} + +const char *udev_device_get_id_filename(struct udev_device *udev_device) +{ + if (udev_device->id_filename == NULL) { + if (udev_device_get_subsystem(udev_device) == NULL) + return NULL; + + if (major(udev_device_get_devnum(udev_device)) > 0) { + /* use dev_t -- b259:131072, c254:0 */ + if (asprintf(&udev_device->id_filename, "%c%u:%u", + streq(udev_device_get_subsystem(udev_device), "block") ? 'b' : 'c', + major(udev_device_get_devnum(udev_device)), + minor(udev_device_get_devnum(udev_device))) < 0) + udev_device->id_filename = NULL; + } else if (udev_device_get_ifindex(udev_device) > 0) { + /* use netdev ifindex -- n3 */ + if (asprintf(&udev_device->id_filename, "n%u", udev_device_get_ifindex(udev_device)) < 0) + udev_device->id_filename = NULL; + } else { + /* + * use $subsys:$syname -- pci:0000:00:1f.2 + * sysname() has '!' translated, get it from devpath + */ + const char *sysname; + sysname = strrchr(udev_device->devpath, '/'); + if (sysname == NULL) + return NULL; + sysname = &sysname[1]; + if (asprintf(&udev_device->id_filename, "+%s:%s", udev_device_get_subsystem(udev_device), sysname) < 0) + udev_device->id_filename = NULL; + } + } + return udev_device->id_filename; +} + +/** + * udev_device_get_is_initialized: + * @udev_device: udev device + * + * Check if udev has already handled the device and has set up + * device node permissions and context, or has renamed a network + * device. + * + * This is only implemented for devices with a device node + * or network interfaces. All other devices return 1 here. + * + * Returns: 1 if the device is set up. 0 otherwise. + **/ +_public_ int udev_device_get_is_initialized(struct udev_device *udev_device) +{ + if (!udev_device->info_loaded) + udev_device_read_db(udev_device, NULL); + return udev_device->is_initialized; +} + +void udev_device_set_is_initialized(struct udev_device *udev_device) +{ + udev_device->is_initialized = true; +} + +int udev_device_add_tag(struct udev_device *udev_device, const char *tag) +{ + if (strchr(tag, ':') != NULL || strchr(tag, ' ') != NULL) + return -EINVAL; + udev_device->tags_uptodate = false; + if (udev_list_entry_add(&udev_device->tags_list, tag, NULL) != NULL) + return 0; + return -ENOMEM; +} + +void udev_device_cleanup_tags_list(struct udev_device *udev_device) +{ + udev_device->tags_uptodate = false; + udev_list_cleanup(&udev_device->tags_list); +} + +/** + * udev_device_get_tags_list_entry: + * @udev_device: udev device + * + * Retrieve the list of tags attached to the udev device. The next + * list entry can be retrieved with udev_list_entry_get_next(), + * which returns #NULL if no more entries exist. The tag string + * can be retrieved from the list entry by udev_list_entry_get_name(). + * + * Returns: the first entry of the tag list + **/ +_public_ struct udev_list_entry *udev_device_get_tags_list_entry(struct udev_device *udev_device) +{ + if (udev_device == NULL) + return NULL; + if (!udev_device->info_loaded) + udev_device_read_db(udev_device, NULL); + return udev_list_get_entry(&udev_device->tags_list); +} + +/** + * udev_device_has_tag: + * @udev_device: udev device + * @tag: tag name + * + * Check if a given device has a certain tag associated. + * + * Returns: 1 if the tag is found. 0 otherwise. + **/ +_public_ int udev_device_has_tag(struct udev_device *udev_device, const char *tag) +{ + struct udev_list_entry *list_entry; + + if (udev_device == NULL) + return false; + if (!udev_device->info_loaded) + udev_device_read_db(udev_device, NULL); + list_entry = udev_device_get_tags_list_entry(udev_device); + if (udev_list_entry_get_by_name(list_entry, tag) != NULL) + return true; + return false; +} + +#define ENVP_SIZE 128 +#define MONITOR_BUF_SIZE 4096 +static int update_envp_monitor_buf(struct udev_device *udev_device) +{ + struct udev_list_entry *list_entry; + char *s; + size_t l; + unsigned int i; + + /* monitor buffer of property strings */ + free(udev_device->monitor_buf); + udev_device->monitor_buf_len = 0; + udev_device->monitor_buf = malloc(MONITOR_BUF_SIZE); + if (udev_device->monitor_buf == NULL) + return -ENOMEM; + + /* envp array, strings will point into monitor buffer */ + if (udev_device->envp == NULL) + udev_device->envp = malloc(sizeof(char *) * ENVP_SIZE); + if (udev_device->envp == NULL) + return -ENOMEM; + + i = 0; + s = udev_device->monitor_buf; + l = MONITOR_BUF_SIZE; + udev_list_entry_foreach(list_entry, udev_device_get_properties_list_entry(udev_device)) { + const char *key; + + key = udev_list_entry_get_name(list_entry); + /* skip private variables */ + if (key[0] == '.') + continue; + + /* add string to envp array */ + udev_device->envp[i++] = s; + if (i+1 >= ENVP_SIZE) + return -EINVAL; + + /* add property string to monitor buffer */ + l = util_strpcpyl(&s, l, key, "=", udev_list_entry_get_value(list_entry), NULL); + if (l == 0) + return -EINVAL; + /* advance past the trailing '\0' that util_strpcpyl() guarantees */ + s++; + l--; + } + udev_device->envp[i] = NULL; + udev_device->monitor_buf_len = s - udev_device->monitor_buf; + udev_device->envp_uptodate = true; + return 0; +} + +char **udev_device_get_properties_envp(struct udev_device *udev_device) +{ + if (!udev_device->envp_uptodate) + if (update_envp_monitor_buf(udev_device) != 0) + return NULL; + return udev_device->envp; +} + +ssize_t udev_device_get_properties_monitor_buf(struct udev_device *udev_device, const char **buf) +{ + if (!udev_device->envp_uptodate) + if (update_envp_monitor_buf(udev_device) != 0) + return -EINVAL; + *buf = udev_device->monitor_buf; + return udev_device->monitor_buf_len; +} + +int udev_device_set_action(struct udev_device *udev_device, const char *action) +{ + free(udev_device->action); + udev_device->action = strdup(action); + if (udev_device->action == NULL) + return -ENOMEM; + udev_device_add_property(udev_device, "ACTION", udev_device->action); + return 0; +} + +int udev_device_get_devlink_priority(struct udev_device *udev_device) +{ + if (!udev_device->info_loaded) + udev_device_read_db(udev_device, NULL); + return udev_device->devlink_priority; +} + +int udev_device_set_devlink_priority(struct udev_device *udev_device, int prio) +{ + udev_device->devlink_priority = prio; + return 0; +} + +int udev_device_get_watch_handle(struct udev_device *udev_device) +{ + if (!udev_device->info_loaded) + udev_device_read_db(udev_device, NULL); + return udev_device->watch_handle; +} + +int udev_device_set_watch_handle(struct udev_device *udev_device, int handle) +{ + udev_device->watch_handle = handle; + return 0; +} + +bool udev_device_get_db_persist(struct udev_device *udev_device) +{ + return udev_device->db_persist; +} + +void udev_device_set_db_persist(struct udev_device *udev_device) +{ + udev_device->db_persist = true; +} diff --git a/src/libudev/libudev-enumerate.c b/src/libudev/libudev-enumerate.c new file mode 100644 index 000000000..6a5f4e025 --- /dev/null +++ b/src/libudev/libudev-enumerate.c @@ -0,0 +1,958 @@ +/*** + This file is part of systemd. + + Copyright 2008-2012 Kay Sievers + + 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "libudev.h" +#include "libudev-private.h" + +/** + * SECTION:libudev-enumerate + * @short_description: lookup and sort sys devices + * + * Lookup devices in the sys filesystem, filter devices by properties, + * and return a sorted list of devices. + */ + +struct syspath { + char *syspath; + size_t len; +}; + +/** + * udev_enumerate: + * + * Opaque object representing one device lookup/sort context. + */ +struct udev_enumerate { + struct udev *udev; + int refcount; + struct udev_list sysattr_match_list; + struct udev_list sysattr_nomatch_list; + struct udev_list subsystem_match_list; + struct udev_list subsystem_nomatch_list; + struct udev_list sysname_match_list; + struct udev_list properties_match_list; + struct udev_list tags_match_list; + struct udev_device *parent_match; + struct udev_list devices_list; + struct syspath *devices; + unsigned int devices_cur; + unsigned int devices_max; + bool devices_uptodate:1; + bool match_is_initialized; +}; + +/** + * udev_enumerate_new: + * @udev: udev library context + * + * Create an enumeration context to scan /sys. + * + * Returns: an enumeration context. + **/ +_public_ struct udev_enumerate *udev_enumerate_new(struct udev *udev) +{ + struct udev_enumerate *udev_enumerate; + + if (udev == NULL) + return NULL; + udev_enumerate = calloc(1, sizeof(struct udev_enumerate)); + if (udev_enumerate == NULL) + return NULL; + udev_enumerate->refcount = 1; + udev_enumerate->udev = udev; + udev_list_init(udev, &udev_enumerate->sysattr_match_list, false); + udev_list_init(udev, &udev_enumerate->sysattr_nomatch_list, false); + udev_list_init(udev, &udev_enumerate->subsystem_match_list, true); + udev_list_init(udev, &udev_enumerate->subsystem_nomatch_list, true); + udev_list_init(udev, &udev_enumerate->sysname_match_list, true); + udev_list_init(udev, &udev_enumerate->properties_match_list, false); + udev_list_init(udev, &udev_enumerate->tags_match_list, true); + udev_list_init(udev, &udev_enumerate->devices_list, false); + return udev_enumerate; +} + +/** + * udev_enumerate_ref: + * @udev_enumerate: context + * + * Take a reference of a enumeration context. + * + * Returns: the passed enumeration context + **/ +_public_ struct udev_enumerate *udev_enumerate_ref(struct udev_enumerate *udev_enumerate) +{ + if (udev_enumerate == NULL) + return NULL; + udev_enumerate->refcount++; + return udev_enumerate; +} + +/** + * udev_enumerate_unref: + * @udev_enumerate: context + * + * Drop a reference of an enumeration context. If the refcount reaches zero, + * all resources of the enumeration context will be released. + * + * Returns: the passed enumeration context if it has still an active reference, or #NULL otherwise. + **/ +_public_ struct udev_enumerate *udev_enumerate_unref(struct udev_enumerate *udev_enumerate) +{ + unsigned int i; + + if (udev_enumerate == NULL) + return NULL; + udev_enumerate->refcount--; + if (udev_enumerate->refcount > 0) + return udev_enumerate; + udev_list_cleanup(&udev_enumerate->sysattr_match_list); + udev_list_cleanup(&udev_enumerate->sysattr_nomatch_list); + udev_list_cleanup(&udev_enumerate->subsystem_match_list); + udev_list_cleanup(&udev_enumerate->subsystem_nomatch_list); + udev_list_cleanup(&udev_enumerate->sysname_match_list); + udev_list_cleanup(&udev_enumerate->properties_match_list); + udev_list_cleanup(&udev_enumerate->tags_match_list); + udev_device_unref(udev_enumerate->parent_match); + udev_list_cleanup(&udev_enumerate->devices_list); + for (i = 0; i < udev_enumerate->devices_cur; i++) + free(udev_enumerate->devices[i].syspath); + free(udev_enumerate->devices); + free(udev_enumerate); + return NULL; +} + +/** + * udev_enumerate_get_udev: + * @udev_enumerate: context + * + * Get the udev library context. + * + * Returns: a pointer to the context. + */ +_public_ struct udev *udev_enumerate_get_udev(struct udev_enumerate *udev_enumerate) +{ + if (udev_enumerate == NULL) + return NULL; + return udev_enumerate->udev; +} + +static int syspath_add(struct udev_enumerate *udev_enumerate, const char *syspath) +{ + char *path; + struct syspath *entry; + + /* double array size if needed */ + if (udev_enumerate->devices_cur >= udev_enumerate->devices_max) { + struct syspath *buf; + unsigned int add; + + add = udev_enumerate->devices_max; + if (add < 1024) + add = 1024; + buf = realloc(udev_enumerate->devices, (udev_enumerate->devices_max + add) * sizeof(struct syspath)); + if (buf == NULL) + return -ENOMEM; + udev_enumerate->devices = buf; + udev_enumerate->devices_max += add; + } + + path = strdup(syspath); + if (path == NULL) + return -ENOMEM; + entry = &udev_enumerate->devices[udev_enumerate->devices_cur]; + entry->syspath = path; + entry->len = strlen(path); + udev_enumerate->devices_cur++; + udev_enumerate->devices_uptodate = false; + return 0; +} + +static int syspath_cmp(const void *p1, const void *p2) +{ + const struct syspath *path1 = p1; + const struct syspath *path2 = p2; + size_t len; + int ret; + + len = MIN(path1->len, path2->len); + ret = memcmp(path1->syspath, path2->syspath, len); + if (ret == 0) { + if (path1->len < path2->len) + ret = -1; + else if (path1->len > path2->len) + ret = 1; + } + return ret; +} + +/* For devices that should be moved to the absolute end of the list */ +static bool devices_delay_end(struct udev *udev, const char *syspath) +{ + static const char *delay_device_list[] = { + "/block/md", + "/block/dm-", + NULL + }; + int i; + + for (i = 0; delay_device_list[i] != NULL; i++) { + if (strstr(syspath + strlen("/sys"), delay_device_list[i]) != NULL) + return true; + } + return false; +} + +/* For devices that should just be moved a little bit later, just + * before the point where some common path prefix changes. Returns the + * number of characters that make up that common prefix */ +static size_t devices_delay_later(struct udev *udev, const char *syspath) +{ + const char *c; + + /* For sound cards the control device must be enumerated last + * to make sure it's the final device node that gets ACLs + * applied. Applications rely on this fact and use ACL changes + * on the control node as an indicator that the ACL change of + * the entire sound card completed. The kernel makes this + * guarantee when creating those devices, and hence we should + * too when enumerating them. */ + + if ((c = strstr(syspath, "/sound/card"))) { + c += 11; + c += strcspn(c, "/"); + + if (startswith(c, "/controlC")) + return c - syspath + 1; + } + + return 0; +} + +/** + * udev_enumerate_get_list_entry: + * @udev_enumerate: context + * + * Get the first entry of the sorted list of device paths. + * + * Returns: a udev_list_entry. + */ +_public_ struct udev_list_entry *udev_enumerate_get_list_entry(struct udev_enumerate *udev_enumerate) +{ + if (udev_enumerate == NULL) + return NULL; + if (!udev_enumerate->devices_uptodate) { + unsigned int i; + unsigned int max; + struct syspath *prev = NULL, *move_later = NULL; + size_t move_later_prefix = 0; + + udev_list_cleanup(&udev_enumerate->devices_list); + qsort(udev_enumerate->devices, udev_enumerate->devices_cur, sizeof(struct syspath), syspath_cmp); + + max = udev_enumerate->devices_cur; + for (i = 0; i < max; i++) { + struct syspath *entry = &udev_enumerate->devices[i]; + + /* skip duplicated entries */ + if (prev != NULL && + entry->len == prev->len && + memcmp(entry->syspath, prev->syspath, entry->len) == 0) + continue; + prev = entry; + + /* skip to be delayed devices, and add them to the end of the list */ + if (devices_delay_end(udev_enumerate->udev, entry->syspath)) { + syspath_add(udev_enumerate, entry->syspath); + /* need to update prev here for the case realloc() gives a different address */ + prev = &udev_enumerate->devices[i]; + continue; + } + + /* skip to be delayed devices, and move the to + * the point where the prefix changes. We can + * only move one item at a time. */ + if (!move_later) { + move_later_prefix = devices_delay_later(udev_enumerate->udev, entry->syspath); + + if (move_later_prefix > 0) { + move_later = entry; + continue; + } + } + + if (move_later && + strncmp(entry->syspath, move_later->syspath, move_later_prefix) != 0) { + + udev_list_entry_add(&udev_enumerate->devices_list, move_later->syspath, NULL); + move_later = NULL; + } + + udev_list_entry_add(&udev_enumerate->devices_list, entry->syspath, NULL); + } + + if (move_later) + udev_list_entry_add(&udev_enumerate->devices_list, move_later->syspath, NULL); + + /* add and cleanup delayed devices from end of list */ + for (i = max; i < udev_enumerate->devices_cur; i++) { + struct syspath *entry = &udev_enumerate->devices[i]; + + udev_list_entry_add(&udev_enumerate->devices_list, entry->syspath, NULL); + free(entry->syspath); + } + udev_enumerate->devices_cur = max; + + udev_enumerate->devices_uptodate = true; + } + return udev_list_get_entry(&udev_enumerate->devices_list); +} + +/** + * udev_enumerate_add_match_subsystem: + * @udev_enumerate: context + * @subsystem: filter for a subsystem of the device to include in the list + * + * Match only devices belonging to a certain kernel subsystem. + * + * Returns: 0 on success, otherwise a negative error value. + */ +_public_ int udev_enumerate_add_match_subsystem(struct udev_enumerate *udev_enumerate, const char *subsystem) +{ + if (udev_enumerate == NULL) + return -EINVAL; + if (subsystem == NULL) + return 0; + if (udev_list_entry_add(&udev_enumerate->subsystem_match_list, subsystem, NULL) == NULL) + return -ENOMEM; + return 0; +} + +/** + * udev_enumerate_add_nomatch_subsystem: + * @udev_enumerate: context + * @subsystem: filter for a subsystem of the device to exclude from the list + * + * Match only devices not belonging to a certain kernel subsystem. + * + * Returns: 0 on success, otherwise a negative error value. + */ +_public_ int udev_enumerate_add_nomatch_subsystem(struct udev_enumerate *udev_enumerate, const char *subsystem) +{ + if (udev_enumerate == NULL) + return -EINVAL; + if (subsystem == NULL) + return 0; + if (udev_list_entry_add(&udev_enumerate->subsystem_nomatch_list, subsystem, NULL) == NULL) + return -ENOMEM; + return 0; +} + +/** + * udev_enumerate_add_match_sysattr: + * @udev_enumerate: context + * @sysattr: filter for a sys attribute at the device to include in the list + * @value: optional value of the sys attribute + * + * Match only devices with a certain /sys device attribute. + * + * Returns: 0 on success, otherwise a negative error value. + */ +_public_ int udev_enumerate_add_match_sysattr(struct udev_enumerate *udev_enumerate, const char *sysattr, const char *value) +{ + if (udev_enumerate == NULL) + return -EINVAL; + if (sysattr == NULL) + return 0; + if (udev_list_entry_add(&udev_enumerate->sysattr_match_list, sysattr, value) == NULL) + return -ENOMEM; + return 0; +} + +/** + * udev_enumerate_add_nomatch_sysattr: + * @udev_enumerate: context + * @sysattr: filter for a sys attribute at the device to exclude from the list + * @value: optional value of the sys attribute + * + * Match only devices not having a certain /sys device attribute. + * + * Returns: 0 on success, otherwise a negative error value. + */ +_public_ int udev_enumerate_add_nomatch_sysattr(struct udev_enumerate *udev_enumerate, const char *sysattr, const char *value) +{ + if (udev_enumerate == NULL) + return -EINVAL; + if (sysattr == NULL) + return 0; + if (udev_list_entry_add(&udev_enumerate->sysattr_nomatch_list, sysattr, value) == NULL) + return -ENOMEM; + return 0; +} + +static int match_sysattr_value(struct udev_device *dev, const char *sysattr, const char *match_val) +{ + const char *val = NULL; + bool match = false; + + val = udev_device_get_sysattr_value(dev, sysattr); + if (val == NULL) + goto exit; + if (match_val == NULL) { + match = true; + goto exit; + } + if (fnmatch(match_val, val, 0) == 0) { + match = true; + goto exit; + } +exit: + return match; +} + +/** + * udev_enumerate_add_match_property: + * @udev_enumerate: context + * @property: filter for a property of the device to include in the list + * @value: value of the property + * + * Match only devices with a certain property. + * + * Returns: 0 on success, otherwise a negative error value. + */ +_public_ int udev_enumerate_add_match_property(struct udev_enumerate *udev_enumerate, const char *property, const char *value) +{ + if (udev_enumerate == NULL) + return -EINVAL; + if (property == NULL) + return 0; + if (udev_list_entry_add(&udev_enumerate->properties_match_list, property, value) == NULL) + return -ENOMEM; + return 0; +} + +/** + * udev_enumerate_add_match_tag: + * @udev_enumerate: context + * @tag: filter for a tag of the device to include in the list + * + * Match only devices with a certain tag. + * + * Returns: 0 on success, otherwise a negative error value. + */ +_public_ int udev_enumerate_add_match_tag(struct udev_enumerate *udev_enumerate, const char *tag) +{ + if (udev_enumerate == NULL) + return -EINVAL; + if (tag == NULL) + return 0; + if (udev_list_entry_add(&udev_enumerate->tags_match_list, tag, NULL) == NULL) + return -ENOMEM; + return 0; +} + +/** + * udev_enumerate_add_match_parent: + * @udev_enumerate: context + * @parent: parent device where to start searching + * + * Return the devices on the subtree of one given device. The parent + * itself is included in the list. + * + * A reference for the device is held until the udev_enumerate context + * is cleaned up. + * + * Returns: 0 on success, otherwise a negative error value. + */ +_public_ int udev_enumerate_add_match_parent(struct udev_enumerate *udev_enumerate, struct udev_device *parent) +{ + if (udev_enumerate == NULL) + return -EINVAL; + if (parent == NULL) + return 0; + if (udev_enumerate->parent_match != NULL) + udev_device_unref(udev_enumerate->parent_match); + udev_enumerate->parent_match = udev_device_ref(parent); + return 0; +} + +/** + * udev_enumerate_add_match_is_initialized: + * @udev_enumerate: context + * + * Match only devices which udev has set up already. This makes + * sure, that the device node permissions and context are properly set + * and that network devices are fully renamed. + * + * Usually, devices which are found in the kernel but not already + * handled by udev, have still pending events. Services should subscribe + * to monitor events and wait for these devices to become ready, instead + * of using uninitialized devices. + * + * For now, this will not affect devices which do not have a device node + * and are not network interfaces. + * + * Returns: 0 on success, otherwise a negative error value. + */ +_public_ int udev_enumerate_add_match_is_initialized(struct udev_enumerate *udev_enumerate) +{ + if (udev_enumerate == NULL) + return -EINVAL; + udev_enumerate->match_is_initialized = true; + return 0; +} + +/** + * udev_enumerate_add_match_sysname: + * @udev_enumerate: context + * @sysname: filter for the name of the device to include in the list + * + * Match only devices with a given /sys device name. + * + * Returns: 0 on success, otherwise a negative error value. + */ +_public_ int udev_enumerate_add_match_sysname(struct udev_enumerate *udev_enumerate, const char *sysname) +{ + if (udev_enumerate == NULL) + return -EINVAL; + if (sysname == NULL) + return 0; + if (udev_list_entry_add(&udev_enumerate->sysname_match_list, sysname, NULL) == NULL) + return -ENOMEM; + return 0; +} + +static bool match_sysattr(struct udev_enumerate *udev_enumerate, struct udev_device *dev) +{ + struct udev_list_entry *list_entry; + + /* skip list */ + udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_enumerate->sysattr_nomatch_list)) { + if (match_sysattr_value(dev, udev_list_entry_get_name(list_entry), + udev_list_entry_get_value(list_entry))) + return false; + } + /* include list */ + if (udev_list_get_entry(&udev_enumerate->sysattr_match_list) != NULL) { + udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_enumerate->sysattr_match_list)) { + /* anything that does not match, will make it FALSE */ + if (!match_sysattr_value(dev, udev_list_entry_get_name(list_entry), + udev_list_entry_get_value(list_entry))) + return false; + } + return true; + } + return true; +} + +static bool match_property(struct udev_enumerate *udev_enumerate, struct udev_device *dev) +{ + struct udev_list_entry *list_entry; + bool match = false; + + /* no match always matches */ + if (udev_list_get_entry(&udev_enumerate->properties_match_list) == NULL) + return true; + + /* loop over matches */ + udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_enumerate->properties_match_list)) { + const char *match_key = udev_list_entry_get_name(list_entry); + const char *match_value = udev_list_entry_get_value(list_entry); + struct udev_list_entry *property_entry; + + /* loop over device properties */ + udev_list_entry_foreach(property_entry, udev_device_get_properties_list_entry(dev)) { + const char *dev_key = udev_list_entry_get_name(property_entry); + const char *dev_value = udev_list_entry_get_value(property_entry); + + if (fnmatch(match_key, dev_key, 0) != 0) + continue; + if (match_value == NULL && dev_value == NULL) { + match = true; + goto out; + } + if (match_value == NULL || dev_value == NULL) + continue; + if (fnmatch(match_value, dev_value, 0) == 0) { + match = true; + goto out; + } + } + } +out: + return match; +} + +static bool match_tag(struct udev_enumerate *udev_enumerate, struct udev_device *dev) +{ + struct udev_list_entry *list_entry; + + /* no match always matches */ + if (udev_list_get_entry(&udev_enumerate->tags_match_list) == NULL) + return true; + + /* loop over matches */ + udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_enumerate->tags_match_list)) + if (!udev_device_has_tag(dev, udev_list_entry_get_name(list_entry))) + return false; + + return true; +} + +static bool match_parent(struct udev_enumerate *udev_enumerate, struct udev_device *dev) +{ + if (udev_enumerate->parent_match == NULL) + return true; + + return startswith(udev_device_get_devpath(dev), udev_device_get_devpath(udev_enumerate->parent_match)); +} + +static bool match_sysname(struct udev_enumerate *udev_enumerate, const char *sysname) +{ + struct udev_list_entry *list_entry; + + if (udev_list_get_entry(&udev_enumerate->sysname_match_list) == NULL) + return true; + + udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_enumerate->sysname_match_list)) { + if (fnmatch(udev_list_entry_get_name(list_entry), sysname, 0) != 0) + continue; + return true; + } + return false; +} + +static int scan_dir_and_add_devices(struct udev_enumerate *udev_enumerate, + const char *basedir, const char *subdir1, const char *subdir2) +{ + char path[UTIL_PATH_SIZE]; + size_t l; + char *s; + DIR *dir; + struct dirent *dent; + + s = path; + l = util_strpcpyl(&s, sizeof(path), "/sys/", basedir, NULL); + if (subdir1 != NULL) + l = util_strpcpyl(&s, l, "/", subdir1, NULL); + if (subdir2 != NULL) + util_strpcpyl(&s, l, "/", subdir2, NULL); + dir = opendir(path); + if (dir == NULL) + return -ENOENT; + for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) { + char syspath[UTIL_PATH_SIZE]; + struct udev_device *dev; + + if (dent->d_name[0] == '.') + continue; + + if (!match_sysname(udev_enumerate, dent->d_name)) + continue; + + util_strscpyl(syspath, sizeof(syspath), path, "/", dent->d_name, NULL); + dev = udev_device_new_from_syspath(udev_enumerate->udev, syspath); + if (dev == NULL) + continue; + + if (udev_enumerate->match_is_initialized) { + /* + * All devices with a device node or network interfaces + * possibly need udev to adjust the device node permission + * or context, or rename the interface before it can be + * reliably used from other processes. + * + * For now, we can only check these types of devices, we + * might not store a database, and have no way to find out + * for all other types of devices. + */ + if (!udev_device_get_is_initialized(dev) && + (major(udev_device_get_devnum(dev)) > 0 || udev_device_get_ifindex(dev) > 0)) + goto nomatch; + } + if (!match_parent(udev_enumerate, dev)) + goto nomatch; + if (!match_tag(udev_enumerate, dev)) + goto nomatch; + if (!match_property(udev_enumerate, dev)) + goto nomatch; + if (!match_sysattr(udev_enumerate, dev)) + goto nomatch; + + syspath_add(udev_enumerate, udev_device_get_syspath(dev)); +nomatch: + udev_device_unref(dev); + } + closedir(dir); + return 0; +} + +static bool match_subsystem(struct udev_enumerate *udev_enumerate, const char *subsystem) +{ + struct udev_list_entry *list_entry; + + udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_enumerate->subsystem_nomatch_list)) { + if (fnmatch(udev_list_entry_get_name(list_entry), subsystem, 0) == 0) + return false; + } + if (udev_list_get_entry(&udev_enumerate->subsystem_match_list) != NULL) { + udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_enumerate->subsystem_match_list)) { + if (fnmatch(udev_list_entry_get_name(list_entry), subsystem, 0) == 0) + return true; + } + return false; + } + return true; +} + +static int scan_dir(struct udev_enumerate *udev_enumerate, const char *basedir, const char *subdir, const char *subsystem) +{ + char path[UTIL_PATH_SIZE]; + DIR *dir; + struct dirent *dent; + + util_strscpyl(path, sizeof(path), "/sys/", basedir, NULL); + dir = opendir(path); + if (dir == NULL) + return -1; + for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) { + if (dent->d_name[0] == '.') + continue; + if (!match_subsystem(udev_enumerate, subsystem != NULL ? subsystem : dent->d_name)) + continue; + scan_dir_and_add_devices(udev_enumerate, basedir, dent->d_name, subdir); + } + closedir(dir); + return 0; +} + +/** + * udev_enumerate_add_syspath: + * @udev_enumerate: context + * @syspath: path of a device + * + * Add a device to the list of devices, to retrieve it back sorted in dependency order. + * + * Returns: 0 on success, otherwise a negative error value. + */ +_public_ int udev_enumerate_add_syspath(struct udev_enumerate *udev_enumerate, const char *syspath) +{ + struct udev_device *udev_device; + + if (udev_enumerate == NULL) + return -EINVAL; + if (syspath == NULL) + return 0; + /* resolve to real syspath */ + udev_device = udev_device_new_from_syspath(udev_enumerate->udev, syspath); + if (udev_device == NULL) + return -EINVAL; + syspath_add(udev_enumerate, udev_device_get_syspath(udev_device)); + udev_device_unref(udev_device); + return 0; +} + +static int scan_devices_tags(struct udev_enumerate *udev_enumerate) +{ + struct udev_list_entry *list_entry; + + /* scan only tagged devices, use tags reverse-index, instead of searching all devices in /sys */ + udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_enumerate->tags_match_list)) { + DIR *dir; + struct dirent *dent; + char path[UTIL_PATH_SIZE]; + + util_strscpyl(path, sizeof(path), "/run/udev/tags/", udev_list_entry_get_name(list_entry), NULL); + dir = opendir(path); + if (dir == NULL) + continue; + for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) { + struct udev_device *dev; + + if (dent->d_name[0] == '.') + continue; + + dev = udev_device_new_from_device_id(udev_enumerate->udev, dent->d_name); + if (dev == NULL) + continue; + + if (!match_subsystem(udev_enumerate, udev_device_get_subsystem(dev))) + goto nomatch; + if (!match_sysname(udev_enumerate, udev_device_get_sysname(dev))) + goto nomatch; + if (!match_parent(udev_enumerate, dev)) + goto nomatch; + if (!match_property(udev_enumerate, dev)) + goto nomatch; + if (!match_sysattr(udev_enumerate, dev)) + goto nomatch; + + syspath_add(udev_enumerate, udev_device_get_syspath(dev)); +nomatch: + udev_device_unref(dev); + } + closedir(dir); + } + return 0; +} + +static int parent_add_child(struct udev_enumerate *enumerate, const char *path) +{ + struct udev_device *dev; + + dev = udev_device_new_from_syspath(enumerate->udev, path); + if (dev == NULL) + return -ENODEV; + + if (!match_subsystem(enumerate, udev_device_get_subsystem(dev))) + return 0; + if (!match_sysname(enumerate, udev_device_get_sysname(dev))) + return 0; + if (!match_property(enumerate, dev)) + return 0; + if (!match_sysattr(enumerate, dev)) + return 0; + + syspath_add(enumerate, udev_device_get_syspath(dev)); + udev_device_unref(dev); + return 1; +} + +static int parent_crawl_children(struct udev_enumerate *enumerate, const char *path, int maxdepth) +{ + DIR *d; + struct dirent *dent; + + d = opendir(path); + if (d == NULL) + return -errno; + + for (dent = readdir(d); dent != NULL; dent = readdir(d)) { + char *child; + + if (dent->d_name[0] == '.') + continue; + if (dent->d_type != DT_DIR) + continue; + if (asprintf(&child, "%s/%s", path, dent->d_name) < 0) + continue; + parent_add_child(enumerate, child); + if (maxdepth > 0) + parent_crawl_children(enumerate, child, maxdepth-1); + free(child); + } + + closedir(d); + return 0; +} + +static int scan_devices_children(struct udev_enumerate *enumerate) +{ + const char *path; + + path = udev_device_get_syspath(enumerate->parent_match); + parent_add_child(enumerate, path); + return parent_crawl_children(enumerate, path, 256); +} + +static int scan_devices_all(struct udev_enumerate *udev_enumerate) +{ + struct stat statbuf; + + if (stat("/sys/subsystem", &statbuf) == 0) { + /* we have /subsystem/, forget all the old stuff */ + scan_dir(udev_enumerate, "subsystem", "devices", NULL); + } else { + scan_dir(udev_enumerate, "bus", "devices", NULL); + scan_dir(udev_enumerate, "class", NULL, NULL); + } + return 0; +} + +/** + * udev_enumerate_scan_devices: + * @udev_enumerate: udev enumeration context + * + * Scan /sys for all devices which match the given filters. No matches + * will return all currently available devices. + * + * Returns: 0 on success, otherwise a negative error value. + **/ +_public_ int udev_enumerate_scan_devices(struct udev_enumerate *udev_enumerate) +{ + if (udev_enumerate == NULL) + return -EINVAL; + + /* efficiently lookup tags only, we maintain a reverse-index */ + if (udev_list_get_entry(&udev_enumerate->tags_match_list) != NULL) + return scan_devices_tags(udev_enumerate); + + /* walk the subtree of one parent device only */ + if (udev_enumerate->parent_match != NULL) + return scan_devices_children(udev_enumerate); + + /* scan devices of all subsystems */ + return scan_devices_all(udev_enumerate); +} + +/** + * udev_enumerate_scan_subsystems: + * @udev_enumerate: udev enumeration context + * + * Scan /sys for all kernel subsystems, including buses, classes, drivers. + * + * Returns: 0 on success, otherwise a negative error value. + **/ +_public_ int udev_enumerate_scan_subsystems(struct udev_enumerate *udev_enumerate) +{ + struct stat statbuf; + const char *subsysdir; + + if (udev_enumerate == NULL) + return -EINVAL; + + /* all kernel modules */ + if (match_subsystem(udev_enumerate, "module")) + scan_dir_and_add_devices(udev_enumerate, "module", NULL, NULL); + + if (stat("/sys/subsystem", &statbuf) == 0) + subsysdir = "subsystem"; + else + subsysdir = "bus"; + + /* all subsystems (only buses support coldplug) */ + if (match_subsystem(udev_enumerate, "subsystem")) + scan_dir_and_add_devices(udev_enumerate, subsysdir, NULL, NULL); + + /* all subsystem drivers */ + if (match_subsystem(udev_enumerate, "drivers")) + scan_dir(udev_enumerate, subsysdir, "drivers", "drivers"); + return 0; +} diff --git a/src/libudev/libudev-hwdb-def.h b/src/libudev/libudev-hwdb-def.h new file mode 100644 index 000000000..b76a13f3e --- /dev/null +++ b/src/libudev/libudev-hwdb-def.h @@ -0,0 +1,74 @@ +/*** + This file is part of systemd. + + Copyright 2012 Kay Sievers + + 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 . +***/ + +#ifndef _LIBUDEV_HWDB_DEF_H_ +#define _LIBUDEV_HWDB_DEF_H_ + +#include "sparse-endian.h" + +#define HWDB_SIG { 'K', 'S', 'L', 'P', 'H', 'H', 'R', 'H' } + +/* on-disk trie objects */ +struct trie_header_f { + uint8_t signature[8]; + + /* version of tool which created the file */ + le64_t tool_version; + le64_t file_size; + + /* size of structures to allow them to grow */ + le64_t header_size; + le64_t node_size; + le64_t child_entry_size; + le64_t value_entry_size; + + /* offset of the root trie node */ + le64_t nodes_root_off; + + /* size of the nodes and string section */ + le64_t nodes_len; + le64_t strings_len; +} _packed_; + +struct trie_node_f { + /* prefix of lookup string, shared by all children */ + le64_t prefix_off; + /* size of children entry array appended to the node */ + uint8_t children_count; + uint8_t padding[7]; + /* size of value entry array appended to the node */ + le64_t values_count; +} _packed_; + +/* array of child entries, follows directly the node record */ +struct trie_child_entry_f { + /* index of the child node */ + uint8_t c; + uint8_t padding[7]; + /* offset of the child node */ + le64_t child_off; +} _packed_; + +/* array of value entries, follows directly the node record/child array */ +struct trie_value_entry_f { + le64_t key_off; + le64_t value_off; +} _packed_; + +#endif diff --git a/src/libudev/libudev-hwdb.c b/src/libudev/libudev-hwdb.c new file mode 100644 index 000000000..09096c4d7 --- /dev/null +++ b/src/libudev/libudev-hwdb.c @@ -0,0 +1,392 @@ +/*** + This file is part of systemd. + + Copyright 2012 Kay Sievers + Copyright 2008 Alan Jenkins + + 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "libudev-private.h" +#include "libudev-hwdb-def.h" + +/** + * SECTION:libudev-hwdb + * @short_description: retrieve properties from the hardware database + * + * Libudev hardware database interface. + */ + +/** + * udev_hwdb: + * + * Opaque object representing the hardware database. + */ +struct udev_hwdb { + struct udev *udev; + int refcount; + + FILE *f; + struct stat st; + union { + struct trie_header_f *head; + const char *map; + }; + + struct udev_list properties_list; +}; + +struct linebuf { + char bytes[LINE_MAX]; + size_t size; + size_t len; +}; + +static void linebuf_init(struct linebuf *buf) { + buf->size = 0; + buf->len = 0; +} + +static const char *linebuf_get(struct linebuf *buf) { + if (buf->len + 1 >= sizeof(buf->bytes)) + return NULL; + buf->bytes[buf->len] = '\0'; + return buf->bytes; +} + +static bool linebuf_add(struct linebuf *buf, const char *s, size_t len) { + if (buf->len + len >= sizeof(buf->bytes)) + return false; + memcpy(buf->bytes + buf->len, s, len); + buf->len += len; + return true; +} + +static bool linebuf_add_char(struct linebuf *buf, char c) +{ + if (buf->len + 1 >= sizeof(buf->bytes)) + return false; + buf->bytes[buf->len++] = c; + return true; +} + +static void linebuf_rem(struct linebuf *buf, size_t count) { + assert(buf->len >= count); + buf->len -= count; +} + +static void linebuf_rem_char(struct linebuf *buf) { + linebuf_rem(buf, 1); +} + +static const struct trie_child_entry_f *trie_node_children(struct udev_hwdb *hwdb, const struct trie_node_f *node) { + return (const struct trie_child_entry_f *)((const char *)node + le64toh(hwdb->head->node_size)); +} + +static const struct trie_value_entry_f *trie_node_values(struct udev_hwdb *hwdb, const struct trie_node_f *node) { + const char *base = (const char *)node; + + base += le64toh(hwdb->head->node_size); + base += node->children_count * le64toh(hwdb->head->child_entry_size); + return (const struct trie_value_entry_f *)base; +} + +static const struct trie_node_f *trie_node_from_off(struct udev_hwdb *hwdb, le64_t off) { + return (const struct trie_node_f *)(hwdb->map + le64toh(off)); +} + +static const char *trie_string(struct udev_hwdb *hwdb, le64_t off) { + return hwdb->map + le64toh(off); +} + +static int trie_children_cmp_f(const void *v1, const void *v2) { + const struct trie_child_entry_f *n1 = v1; + const struct trie_child_entry_f *n2 = v2; + + return n1->c - n2->c; +} + +static const struct trie_node_f *node_lookup_f(struct udev_hwdb *hwdb, const struct trie_node_f *node, uint8_t c) { + struct trie_child_entry_f *child; + struct trie_child_entry_f search; + + search.c = c; + child = bsearch(&search, trie_node_children(hwdb, node), node->children_count, + le64toh(hwdb->head->child_entry_size), trie_children_cmp_f); + if (child) + return trie_node_from_off(hwdb, child->child_off); + return NULL; +} + +static int hwdb_add_property(struct udev_hwdb *hwdb, const char *key, const char *value) { + /* TODO: add sub-matches (+) against DMI data */ + if (key[0] != ' ') + return 0; + if (udev_list_entry_add(&hwdb->properties_list, key+1, value) == NULL) + return -ENOMEM; + return 0; +} + +static int trie_fnmatch_f(struct udev_hwdb *hwdb, const struct trie_node_f *node, size_t p, + struct linebuf *buf, const char *search) { + size_t len; + size_t i; + const char *prefix; + int err; + + prefix = trie_string(hwdb, node->prefix_off); + len = strlen(prefix + p); + linebuf_add(buf, prefix + p, len); + + for (i = 0; i < node->children_count; i++) { + const struct trie_child_entry_f *child = &trie_node_children(hwdb, node)[i]; + + linebuf_add_char(buf, child->c); + err = trie_fnmatch_f(hwdb, trie_node_from_off(hwdb, child->child_off), 0, buf, search); + if (err < 0) + return err; + linebuf_rem_char(buf); + } + + if (le64toh(node->values_count) && fnmatch(linebuf_get(buf), search, 0) == 0) + for (i = 0; i < le64toh(node->values_count); i++) { + err = hwdb_add_property(hwdb, trie_string(hwdb, trie_node_values(hwdb, node)[i].key_off), + trie_string(hwdb, trie_node_values(hwdb, node)[i].value_off)); + if (err < 0) + return err; + } + + linebuf_rem(buf, len); + return 0; +} + +static int trie_search_f(struct udev_hwdb *hwdb, const char *search) { + struct linebuf buf; + const struct trie_node_f *node; + size_t i = 0; + int err; + + linebuf_init(&buf); + + node = trie_node_from_off(hwdb, hwdb->head->nodes_root_off); + while (node) { + const struct trie_node_f *child; + size_t p = 0; + + if (node->prefix_off) { + uint8_t c; + + for (; (c = trie_string(hwdb, node->prefix_off)[p]); p++) { + if (c == '*' || c == '?' || c == '[') + return trie_fnmatch_f(hwdb, node, p, &buf, search + i + p); + if (c != search[i + p]) + return 0; + } + i += p; + } + + child = node_lookup_f(hwdb, node, '*'); + if (child) { + linebuf_add_char(&buf, '*'); + err = trie_fnmatch_f(hwdb, child, 0, &buf, search + i); + if (err < 0) + return err; + linebuf_rem_char(&buf); + } + + child = node_lookup_f(hwdb, node, '?'); + if (child) { + linebuf_add_char(&buf, '?'); + err = trie_fnmatch_f(hwdb, child, 0, &buf, search + i); + if (err < 0) + return err; + linebuf_rem_char(&buf); + } + + child = node_lookup_f(hwdb, node, '['); + if (child) { + linebuf_add_char(&buf, '['); + err = trie_fnmatch_f(hwdb, child, 0, &buf, search + i); + if (err < 0) + return err; + linebuf_rem_char(&buf); + } + + if (search[i] == '\0') { + size_t n; + + for (n = 0; n < le64toh(node->values_count); n++) { + err = hwdb_add_property(hwdb, trie_string(hwdb, trie_node_values(hwdb, node)[n].key_off), + trie_string(hwdb, trie_node_values(hwdb, node)[n].value_off)); + if (err < 0) + return err; + } + return 0; + } + + child = node_lookup_f(hwdb, node, search[i]); + node = child; + i++; + } + return 0; +} + +/** + * udev_hwdb_new: + * @udev: udev library context + * + * Create a hardware database context to query properties for devices. + * + * Returns: a hwdb context. + **/ +_public_ struct udev_hwdb *udev_hwdb_new(struct udev *udev) { + struct udev_hwdb *hwdb; + const char sig[] = HWDB_SIG; + + hwdb = new0(struct udev_hwdb, 1); + if (!hwdb) + return NULL; + + hwdb->refcount = 1; + udev_list_init(udev, &hwdb->properties_list, true); + + hwdb->f = fopen(HWDB_BIN, "re"); + if (!hwdb->f) { + log_debug("error reading %s: %m", HWDB_BIN); + udev_hwdb_unref(hwdb); + return NULL; + } + + if (fstat(fileno(hwdb->f), &hwdb->st) < 0 || + (size_t)hwdb->st.st_size < offsetof(struct trie_header_f, strings_len) + 8) { + log_debug("error reading %s: %m", HWDB_BIN); + udev_hwdb_unref(hwdb); + return NULL; + } + + hwdb->map = mmap(0, hwdb->st.st_size, PROT_READ, MAP_SHARED, fileno(hwdb->f), 0); + if (hwdb->map == MAP_FAILED) { + log_debug("error mapping %s: %m", HWDB_BIN); + udev_hwdb_unref(hwdb); + return NULL; + } + + if (memcmp(hwdb->map, sig, sizeof(hwdb->head->signature)) != 0 || + (size_t)hwdb->st.st_size != le64toh(hwdb->head->file_size)) { + log_debug("error recognizing the format of %s", HWDB_BIN); + udev_hwdb_unref(hwdb); + return NULL; + } + + log_debug("=== trie on-disk ===\n"); + log_debug("tool version: %llu", (unsigned long long)le64toh(hwdb->head->tool_version)); + log_debug("file size: %8llu bytes\n", (unsigned long long)hwdb->st.st_size); + log_debug("header size %8llu bytes\n", (unsigned long long)le64toh(hwdb->head->header_size)); + log_debug("strings %8llu bytes\n", (unsigned long long)le64toh(hwdb->head->strings_len)); + log_debug("nodes %8llu bytes\n", (unsigned long long)le64toh(hwdb->head->nodes_len)); + return hwdb; +} + +/** + * udev_hwdb_ref: + * @hwdb: context + * + * Take a reference of a hwdb context. + * + * Returns: the passed enumeration context + **/ +_public_ struct udev_hwdb *udev_hwdb_ref(struct udev_hwdb *hwdb) { + if (!hwdb) + return NULL; + hwdb->refcount++; + return hwdb; +} + +/** + * udev_hwdb_unref: + * @hwdb: context + * + * Drop a reference of a hwdb context. If the refcount reaches zero, + * all resources of the hwdb context will be released. + * + * Returns: the passed hwdb context if it has still an active reference, or #NULL otherwise. + **/ +_public_ struct udev_hwdb *udev_hwdb_unref(struct udev_hwdb *hwdb) { + if (!hwdb) + return NULL; + hwdb->refcount--; + if (hwdb->refcount > 0) + return hwdb; + if (hwdb->map) + munmap((void *)hwdb->map, hwdb->st.st_size); + if (hwdb->f) + fclose(hwdb->f); + udev_list_cleanup(&hwdb->properties_list); + free(hwdb); + return NULL; +} + +bool udev_hwdb_validate(struct udev_hwdb *hwdb) { + struct stat st; + + if (!hwdb) + return false; + if (!hwdb->f) + return false; + if (fstat(fileno(hwdb->f), &st) < 0) + return true; + if (timespec_load(&hwdb->st.st_mtim) != timespec_load(&st.st_mtim)) + return true; + return false; +} + +/** + * udev_hwdb_get_properties_list_entry: + * @hwdb: context + * @modalias: modalias string + * @flags: (unused) + * + * Lookup a matching device in the hardware database. The lookup key is a + * modalias string, whose formats are defined for the Linux kernel modules. + * Examples are: pci:v00008086d00001C2D*, usb:v04F2pB221*. The first entry + * of a list of retrieved properties is returned. + * + * Returns: a udev_list_entry. + */ +_public_ struct udev_list_entry *udev_hwdb_get_properties_list_entry(struct udev_hwdb *hwdb, const char *modalias, unsigned int flags) { + int err; + + if (!hwdb || !hwdb->f) { + errno = EINVAL; + return NULL; + } + + udev_list_cleanup(&hwdb->properties_list); + err = trie_search_f(hwdb, modalias); + if (err < 0) { + errno = -err; + return NULL; + } + return udev_list_get_entry(&hwdb->properties_list); +} diff --git a/src/libudev/libudev-list.c b/src/libudev/libudev-list.c new file mode 100644 index 000000000..59ba69e27 --- /dev/null +++ b/src/libudev/libudev-list.c @@ -0,0 +1,355 @@ +/*** + This file is part of systemd. + + Copyright 2008-2012 Kay Sievers + + 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 . +***/ + +#include +#include +#include +#include +#include +#include + +#include "libudev.h" +#include "libudev-private.h" + +/** + * SECTION:libudev-list + * @short_description: list operation + * + * Libudev list operations. + */ + +/** + * udev_list_entry: + * + * Opaque object representing one entry in a list. An entry contains + * contains a name, and optionally a value. + */ +struct udev_list_entry { + struct udev_list_node node; + struct udev_list *list; + char *name; + char *value; + int num; +}; + +/* the list's head points to itself if empty */ +void udev_list_node_init(struct udev_list_node *list) +{ + list->next = list; + list->prev = list; +} + +int udev_list_node_is_empty(struct udev_list_node *list) +{ + return list->next == list; +} + +static void udev_list_node_insert_between(struct udev_list_node *new, + struct udev_list_node *prev, + struct udev_list_node *next) +{ + next->prev = new; + new->next = next; + new->prev = prev; + prev->next = new; +} + +void udev_list_node_append(struct udev_list_node *new, struct udev_list_node *list) +{ + udev_list_node_insert_between(new, list->prev, list); +} + +void udev_list_node_remove(struct udev_list_node *entry) +{ + struct udev_list_node *prev = entry->prev; + struct udev_list_node *next = entry->next; + + next->prev = prev; + prev->next = next; + + entry->prev = NULL; + entry->next = NULL; +} + +/* return list entry which embeds this node */ +static inline struct udev_list_entry *list_node_to_entry(struct udev_list_node *node) +{ + return container_of(node, struct udev_list_entry, node); +} + +void udev_list_init(struct udev *udev, struct udev_list *list, bool unique) +{ + memset(list, 0x00, sizeof(struct udev_list)); + list->udev = udev; + list->unique = unique; + udev_list_node_init(&list->node); +} + +/* insert entry into a list as the last element */ +void udev_list_entry_append(struct udev_list_entry *new, struct udev_list *list) +{ + /* inserting before the list head make the node the last node in the list */ + udev_list_node_insert_between(&new->node, list->node.prev, &list->node); + new->list = list; +} + +/* insert entry into a list, before a given existing entry */ +void udev_list_entry_insert_before(struct udev_list_entry *new, struct udev_list_entry *entry) +{ + udev_list_node_insert_between(&new->node, entry->node.prev, &entry->node); + new->list = entry->list; +} + +/* binary search in sorted array */ +static int list_search(struct udev_list *list, const char *name) +{ + unsigned int first, last; + + first = 0; + last = list->entries_cur; + while (first < last) { + unsigned int i; + int cmp; + + i = (first + last)/2; + cmp = strcmp(name, list->entries[i]->name); + if (cmp < 0) + last = i; + else if (cmp > 0) + first = i+1; + else + return i; + } + + /* not found, return negative insertion-index+1 */ + return -(first+1); +} + +struct udev_list_entry *udev_list_entry_add(struct udev_list *list, const char *name, const char *value) +{ + struct udev_list_entry *entry; + int i = 0; + + if (list->unique) { + /* lookup existing name or insertion-index */ + i = list_search(list, name); + if (i >= 0) { + entry = list->entries[i]; + + free(entry->value); + if (value == NULL) { + entry->value = NULL; + return entry; + } + entry->value = strdup(value); + if (entry->value == NULL) + return NULL; + return entry; + } + } + + /* add new name */ + entry = calloc(1, sizeof(struct udev_list_entry)); + if (entry == NULL) + return NULL; + entry->name = strdup(name); + if (entry->name == NULL) { + free(entry); + return NULL; + } + if (value != NULL) { + entry->value = strdup(value); + if (entry->value == NULL) { + free(entry->name); + free(entry); + return NULL; + } + } + + if (list->unique) { + /* allocate or enlarge sorted array if needed */ + if (list->entries_cur >= list->entries_max) { + struct udev_list_entry **entries; + unsigned int add; + + add = list->entries_max; + if (add < 1) + add = 64; + entries = realloc(list->entries, (list->entries_max + add) * sizeof(struct udev_list_entry *)); + if (entries == NULL) { + free(entry->name); + free(entry->value); + free(entry); + return NULL; + } + list->entries = entries; + list->entries_max += add; + } + + /* the negative i returned the insertion index */ + i = (-i)-1; + + /* insert into sorted list */ + if ((unsigned int)i < list->entries_cur) + udev_list_entry_insert_before(entry, list->entries[i]); + else + udev_list_entry_append(entry, list); + + /* insert into sorted array */ + memmove(&list->entries[i+1], &list->entries[i], + (list->entries_cur - i) * sizeof(struct udev_list_entry *)); + list->entries[i] = entry; + list->entries_cur++; + } else { + udev_list_entry_append(entry, list); + } + + return entry; +} + +void udev_list_entry_delete(struct udev_list_entry *entry) +{ + if (entry->list->entries != NULL) { + int i; + struct udev_list *list = entry->list; + + /* remove entry from sorted array */ + i = list_search(list, entry->name); + if (i >= 0) { + memmove(&list->entries[i], &list->entries[i+1], + ((list->entries_cur-1) - i) * sizeof(struct udev_list_entry *)); + list->entries_cur--; + } + } + + udev_list_node_remove(&entry->node); + free(entry->name); + free(entry->value); + free(entry); +} + +void udev_list_cleanup(struct udev_list *list) +{ + struct udev_list_entry *entry_loop; + struct udev_list_entry *entry_tmp; + + free(list->entries); + list->entries = NULL; + list->entries_cur = 0; + list->entries_max = 0; + udev_list_entry_foreach_safe(entry_loop, entry_tmp, udev_list_get_entry(list)) + udev_list_entry_delete(entry_loop); +} + +struct udev_list_entry *udev_list_get_entry(struct udev_list *list) +{ + if (udev_list_node_is_empty(&list->node)) + return NULL; + return list_node_to_entry(list->node.next); +} + +/** + * udev_list_entry_get_next: + * @list_entry: current entry + * + * Get the next entry from the list. + * + * Returns: udev_list_entry, #NULL if no more entries are available. + */ +_public_ struct udev_list_entry *udev_list_entry_get_next(struct udev_list_entry *list_entry) +{ + struct udev_list_node *next; + + if (list_entry == NULL) + return NULL; + next = list_entry->node.next; + /* empty list or no more entries */ + if (next == &list_entry->list->node) + return NULL; + return list_node_to_entry(next); +} + +/** + * udev_list_entry_get_by_name: + * @list_entry: current entry + * @name: name string to match + * + * Lookup an entry in the list with a certain name. + * + * Returns: udev_list_entry, #NULL if no matching entry is found. + */ +_public_ struct udev_list_entry *udev_list_entry_get_by_name(struct udev_list_entry *list_entry, const char *name) +{ + int i; + + if (list_entry == NULL) + return NULL; + + if (!list_entry->list->unique) + return NULL; + + i = list_search(list_entry->list, name); + if (i < 0) + return NULL; + return list_entry->list->entries[i]; +} + +/** + * udev_list_entry_get_name: + * @list_entry: current entry + * + * Get the name of a list entry. + * + * Returns: the name string of this entry. + */ +_public_ const char *udev_list_entry_get_name(struct udev_list_entry *list_entry) +{ + if (list_entry == NULL) + return NULL; + return list_entry->name; +} + +/** + * udev_list_entry_get_value: + * @list_entry: current entry + * + * Get the value of list entry. + * + * Returns: the value string of this entry. + */ +_public_ const char *udev_list_entry_get_value(struct udev_list_entry *list_entry) +{ + if (list_entry == NULL) + return NULL; + return list_entry->value; +} + +int udev_list_entry_get_num(struct udev_list_entry *list_entry) +{ + if (list_entry == NULL) + return -EINVAL; + return list_entry->num; +} + +void udev_list_entry_set_num(struct udev_list_entry *list_entry, int num) +{ + if (list_entry == NULL) + return; + list_entry->num = num; +} diff --git a/src/libudev/libudev-monitor.c b/src/libudev/libudev-monitor.c new file mode 100644 index 000000000..b02ea8808 --- /dev/null +++ b/src/libudev/libudev-monitor.c @@ -0,0 +1,782 @@ +/*** + This file is part of systemd. + + Copyright 2008-2012 Kay Sievers + + 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "libudev.h" +#include "libudev-private.h" +#include "socket-util.h" + +/** + * SECTION:libudev-monitor + * @short_description: device event source + * + * Connects to a device event source. + */ + +/** + * udev_monitor: + * + * Opaque object handling an event source. + */ +struct udev_monitor { + struct udev *udev; + int refcount; + int sock; + union sockaddr_union snl; + union sockaddr_union snl_trusted_sender; + union sockaddr_union snl_destination; + socklen_t addrlen; + struct udev_list filter_subsystem_list; + struct udev_list filter_tag_list; + bool bound; +}; + +enum udev_monitor_netlink_group { + UDEV_MONITOR_NONE, + UDEV_MONITOR_KERNEL, + UDEV_MONITOR_UDEV, +}; + +#define UDEV_MONITOR_MAGIC 0xfeedcafe +struct udev_monitor_netlink_header { + /* "libudev" prefix to distinguish libudev and kernel messages */ + char prefix[8]; + /* + * magic to protect against daemon <-> library message format mismatch + * used in the kernel from socket filter rules; needs to be stored in network order + */ + unsigned int magic; + /* total length of header structure known to the sender */ + unsigned int header_size; + /* properties string buffer */ + unsigned int properties_off; + unsigned int properties_len; + /* + * hashes of primary device properties strings, to let libudev subscribers + * use in-kernel socket filters; values need to be stored in network order + */ + unsigned int filter_subsystem_hash; + unsigned int filter_devtype_hash; + unsigned int filter_tag_bloom_hi; + unsigned int filter_tag_bloom_lo; +}; + +static struct udev_monitor *udev_monitor_new(struct udev *udev) +{ + struct udev_monitor *udev_monitor; + + udev_monitor = calloc(1, sizeof(struct udev_monitor)); + if (udev_monitor == NULL) + return NULL; + udev_monitor->refcount = 1; + udev_monitor->udev = udev; + udev_list_init(udev, &udev_monitor->filter_subsystem_list, false); + udev_list_init(udev, &udev_monitor->filter_tag_list, true); + return udev_monitor; +} + +struct udev_monitor *udev_monitor_new_from_netlink_fd(struct udev *udev, const char *name, int fd) +{ + struct udev_monitor *udev_monitor; + unsigned int group; + + if (udev == NULL) + return NULL; + + if (name == NULL) + group = UDEV_MONITOR_NONE; + else if (strcmp(name, "udev") == 0) + group = UDEV_MONITOR_UDEV; + else if (strcmp(name, "kernel") == 0) + group = UDEV_MONITOR_KERNEL; + else + return NULL; + + udev_monitor = udev_monitor_new(udev); + if (udev_monitor == NULL) + return NULL; + + if (fd < 0) { + udev_monitor->sock = socket(PF_NETLINK, SOCK_RAW|SOCK_CLOEXEC|SOCK_NONBLOCK, NETLINK_KOBJECT_UEVENT); + if (udev_monitor->sock == -1) { + udev_err(udev, "error getting socket: %m\n"); + free(udev_monitor); + return NULL; + } + } else { + udev_monitor->bound = true; + udev_monitor->sock = fd; + } + + udev_monitor->snl.nl.nl_family = AF_NETLINK; + udev_monitor->snl.nl.nl_groups = group; + + /* default destination for sending */ + udev_monitor->snl_destination.nl.nl_family = AF_NETLINK; + udev_monitor->snl_destination.nl.nl_groups = UDEV_MONITOR_UDEV; + + return udev_monitor; +} + +/** + * udev_monitor_new_from_netlink: + * @udev: udev library context + * @name: name of event source + * + * Create new udev monitor and connect to a specified event + * source. Valid sources identifiers are "udev" and "kernel". + * + * Applications should usually not connect directly to the + * "kernel" events, because the devices might not be useable + * at that time, before udev has configured them, and created + * device nodes. Accessing devices at the same time as udev, + * might result in unpredictable behavior. The "udev" events + * are sent out after udev has finished its event processing, + * all rules have been processed, and needed device nodes are + * created. + * + * The initial refcount is 1, and needs to be decremented to + * release the resources of the udev monitor. + * + * Returns: a new udev monitor, or #NULL, in case of an error + **/ +_public_ struct udev_monitor *udev_monitor_new_from_netlink(struct udev *udev, const char *name) +{ + return udev_monitor_new_from_netlink_fd(udev, name, -1); +} + +static inline void bpf_stmt(struct sock_filter *inss, unsigned int *i, + unsigned short code, unsigned int data) +{ + struct sock_filter *ins = &inss[*i]; + + ins->code = code; + ins->k = data; + (*i)++; +} + +static inline void bpf_jmp(struct sock_filter *inss, unsigned int *i, + unsigned short code, unsigned int data, + unsigned short jt, unsigned short jf) +{ + struct sock_filter *ins = &inss[*i]; + + ins->code = code; + ins->jt = jt; + ins->jf = jf; + ins->k = data; + (*i)++; +} + +/** + * udev_monitor_filter_update: + * @udev_monitor: monitor + * + * Update the installed socket filter. This is only needed, + * if the filter was removed or changed. + * + * Returns: 0 on success, otherwise a negative error value. + */ +_public_ int udev_monitor_filter_update(struct udev_monitor *udev_monitor) +{ + struct sock_filter ins[512]; + struct sock_fprog filter; + unsigned int i; + struct udev_list_entry *list_entry; + int err; + + if (udev_list_get_entry(&udev_monitor->filter_subsystem_list) == NULL && + udev_list_get_entry(&udev_monitor->filter_tag_list) == NULL) + return 0; + + memset(ins, 0x00, sizeof(ins)); + i = 0; + + /* load magic in A */ + bpf_stmt(ins, &i, BPF_LD|BPF_W|BPF_ABS, offsetof(struct udev_monitor_netlink_header, magic)); + /* jump if magic matches */ + bpf_jmp(ins, &i, BPF_JMP|BPF_JEQ|BPF_K, UDEV_MONITOR_MAGIC, 1, 0); + /* wrong magic, pass packet */ + bpf_stmt(ins, &i, BPF_RET|BPF_K, 0xffffffff); + + if (udev_list_get_entry(&udev_monitor->filter_tag_list) != NULL) { + int tag_matches; + + /* count tag matches, to calculate end of tag match block */ + tag_matches = 0; + udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_monitor->filter_tag_list)) + tag_matches++; + + /* add all tags matches */ + udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_monitor->filter_tag_list)) { + uint64_t tag_bloom_bits = util_string_bloom64(udev_list_entry_get_name(list_entry)); + uint32_t tag_bloom_hi = tag_bloom_bits >> 32; + uint32_t tag_bloom_lo = tag_bloom_bits & 0xffffffff; + + /* load device bloom bits in A */ + bpf_stmt(ins, &i, BPF_LD|BPF_W|BPF_ABS, offsetof(struct udev_monitor_netlink_header, filter_tag_bloom_hi)); + /* clear bits (tag bits & bloom bits) */ + bpf_stmt(ins, &i, BPF_ALU|BPF_AND|BPF_K, tag_bloom_hi); + /* jump to next tag if it does not match */ + bpf_jmp(ins, &i, BPF_JMP|BPF_JEQ|BPF_K, tag_bloom_hi, 0, 3); + + /* load device bloom bits in A */ + bpf_stmt(ins, &i, BPF_LD|BPF_W|BPF_ABS, offsetof(struct udev_monitor_netlink_header, filter_tag_bloom_lo)); + /* clear bits (tag bits & bloom bits) */ + bpf_stmt(ins, &i, BPF_ALU|BPF_AND|BPF_K, tag_bloom_lo); + /* jump behind end of tag match block if tag matches */ + tag_matches--; + bpf_jmp(ins, &i, BPF_JMP|BPF_JEQ|BPF_K, tag_bloom_lo, 1 + (tag_matches * 6), 0); + } + + /* nothing matched, drop packet */ + bpf_stmt(ins, &i, BPF_RET|BPF_K, 0); + } + + /* add all subsystem matches */ + if (udev_list_get_entry(&udev_monitor->filter_subsystem_list) != NULL) { + udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_monitor->filter_subsystem_list)) { + unsigned int hash = util_string_hash32(udev_list_entry_get_name(list_entry)); + + /* load device subsystem value in A */ + bpf_stmt(ins, &i, BPF_LD|BPF_W|BPF_ABS, offsetof(struct udev_monitor_netlink_header, filter_subsystem_hash)); + if (udev_list_entry_get_value(list_entry) == NULL) { + /* jump if subsystem does not match */ + bpf_jmp(ins, &i, BPF_JMP|BPF_JEQ|BPF_K, hash, 0, 1); + } else { + /* jump if subsystem does not match */ + bpf_jmp(ins, &i, BPF_JMP|BPF_JEQ|BPF_K, hash, 0, 3); + + /* load device devtype value in A */ + bpf_stmt(ins, &i, BPF_LD|BPF_W|BPF_ABS, offsetof(struct udev_monitor_netlink_header, filter_devtype_hash)); + /* jump if value does not match */ + hash = util_string_hash32(udev_list_entry_get_value(list_entry)); + bpf_jmp(ins, &i, BPF_JMP|BPF_JEQ|BPF_K, hash, 0, 1); + } + + /* matched, pass packet */ + bpf_stmt(ins, &i, BPF_RET|BPF_K, 0xffffffff); + + if (i+1 >= ELEMENTSOF(ins)) + return -1; + } + + /* nothing matched, drop packet */ + bpf_stmt(ins, &i, BPF_RET|BPF_K, 0); + } + + /* matched, pass packet */ + bpf_stmt(ins, &i, BPF_RET|BPF_K, 0xffffffff); + + /* install filter */ + memset(&filter, 0x00, sizeof(filter)); + filter.len = i; + filter.filter = ins; + err = setsockopt(udev_monitor->sock, SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof(filter)); + return err; +} + +int udev_monitor_allow_unicast_sender(struct udev_monitor *udev_monitor, struct udev_monitor *sender) +{ + udev_monitor->snl_trusted_sender.nl.nl_pid = sender->snl.nl.nl_pid; + return 0; +} +/** + * udev_monitor_enable_receiving: + * @udev_monitor: the monitor which should receive events + * + * Binds the @udev_monitor socket to the event source. + * + * Returns: 0 on success, otherwise a negative error value. + */ +_public_ int udev_monitor_enable_receiving(struct udev_monitor *udev_monitor) +{ + int err = 0; + const int on = 1; + + if (udev_monitor->snl.nl.nl_family == 0) + return -EINVAL; + + udev_monitor_filter_update(udev_monitor); + + if (!udev_monitor->bound) { + err = bind(udev_monitor->sock, + &udev_monitor->snl.sa, sizeof(struct sockaddr_nl)); + if (err == 0) + udev_monitor->bound = true; + } + + if (err >= 0) { + union sockaddr_union snl; + socklen_t addrlen; + + /* + * get the address the kernel has assigned us + * it is usually, but not necessarily the pid + */ + addrlen = sizeof(struct sockaddr_nl); + err = getsockname(udev_monitor->sock, &snl.sa, &addrlen); + if (err == 0) + udev_monitor->snl.nl.nl_pid = snl.nl.nl_pid; + } else { + udev_err(udev_monitor->udev, "bind failed: %m\n"); + return err; + } + + /* enable receiving of sender credentials */ + setsockopt(udev_monitor->sock, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on)); + return 0; +} + +/** + * udev_monitor_set_receive_buffer_size: + * @udev_monitor: the monitor which should receive events + * @size: the size in bytes + * + * Set the size of the kernel socket buffer. This call needs the + * appropriate privileges to succeed. + * + * Returns: 0 on success, otherwise -1 on error. + */ +_public_ int udev_monitor_set_receive_buffer_size(struct udev_monitor *udev_monitor, int size) +{ + if (udev_monitor == NULL) + return -1; + return setsockopt(udev_monitor->sock, SOL_SOCKET, SO_RCVBUFFORCE, &size, sizeof(size)); +} + +int udev_monitor_disconnect(struct udev_monitor *udev_monitor) +{ + int err; + + err = close(udev_monitor->sock); + udev_monitor->sock = -1; + return err; +} + +/** + * udev_monitor_ref: + * @udev_monitor: udev monitor + * + * Take a reference of a udev monitor. + * + * Returns: the passed udev monitor + **/ +_public_ struct udev_monitor *udev_monitor_ref(struct udev_monitor *udev_monitor) +{ + if (udev_monitor == NULL) + return NULL; + udev_monitor->refcount++; + return udev_monitor; +} + +/** + * udev_monitor_unref: + * @udev_monitor: udev monitor + * + * Drop a reference of a udev monitor. If the refcount reaches zero, + * the bound socket will be closed, and the resources of the monitor + * will be released. + * + * Returns: the passed udev monitor if it has still an active reference, or #NULL otherwise. + **/ +_public_ struct udev_monitor *udev_monitor_unref(struct udev_monitor *udev_monitor) +{ + if (udev_monitor == NULL) + return NULL; + udev_monitor->refcount--; + if (udev_monitor->refcount > 0) + return udev_monitor; + if (udev_monitor->sock >= 0) + close(udev_monitor->sock); + udev_list_cleanup(&udev_monitor->filter_subsystem_list); + udev_list_cleanup(&udev_monitor->filter_tag_list); + free(udev_monitor); + return NULL; +} + +/** + * udev_monitor_get_udev: + * @udev_monitor: udev monitor + * + * Retrieve the udev library context the monitor was created with. + * + * Returns: the udev library context + **/ +_public_ struct udev *udev_monitor_get_udev(struct udev_monitor *udev_monitor) +{ + if (udev_monitor == NULL) + return NULL; + return udev_monitor->udev; +} + +/** + * udev_monitor_get_fd: + * @udev_monitor: udev monitor + * + * Retrieve the socket file descriptor associated with the monitor. + * + * Returns: the socket file descriptor + **/ +_public_ int udev_monitor_get_fd(struct udev_monitor *udev_monitor) +{ + if (udev_monitor == NULL) + return -1; + return udev_monitor->sock; +} + +static int passes_filter(struct udev_monitor *udev_monitor, struct udev_device *udev_device) +{ + struct udev_list_entry *list_entry; + + if (udev_list_get_entry(&udev_monitor->filter_subsystem_list) == NULL) + goto tag; + udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_monitor->filter_subsystem_list)) { + const char *subsys = udev_list_entry_get_name(list_entry); + const char *dsubsys = udev_device_get_subsystem(udev_device); + const char *devtype; + const char *ddevtype; + + if (strcmp(dsubsys, subsys) != 0) + continue; + + devtype = udev_list_entry_get_value(list_entry); + if (devtype == NULL) + goto tag; + ddevtype = udev_device_get_devtype(udev_device); + if (ddevtype == NULL) + continue; + if (strcmp(ddevtype, devtype) == 0) + goto tag; + } + return 0; + +tag: + if (udev_list_get_entry(&udev_monitor->filter_tag_list) == NULL) + return 1; + udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_monitor->filter_tag_list)) { + const char *tag = udev_list_entry_get_name(list_entry); + + if (udev_device_has_tag(udev_device, tag)) + return 1; + } + return 0; +} + +/** + * udev_monitor_receive_device: + * @udev_monitor: udev monitor + * + * Receive data from the udev monitor socket, allocate a new udev + * device, fill in the received data, and return the device. + * + * Only socket connections with uid=0 are accepted. + * + * The monitor socket is by default set to NONBLOCK. A variant of poll() on + * the file descriptor returned by udev_monitor_get_fd() should to be used to + * wake up when new devices arrive, or alternatively the file descriptor + * switched into blocking mode. + * + * The initial refcount is 1, and needs to be decremented to + * release the resources of the udev device. + * + * Returns: a new udev device, or #NULL, in case of an error + **/ +_public_ struct udev_device *udev_monitor_receive_device(struct udev_monitor *udev_monitor) +{ + struct udev_device *udev_device; + struct msghdr smsg; + struct iovec iov; + char cred_msg[CMSG_SPACE(sizeof(struct ucred))]; + struct cmsghdr *cmsg; + union sockaddr_union snl; + struct ucred *cred; + char buf[8192]; + ssize_t buflen; + ssize_t bufpos; + struct udev_monitor_netlink_header *nlh; + +retry: + if (udev_monitor == NULL) + return NULL; + iov.iov_base = &buf; + iov.iov_len = sizeof(buf); + memset (&smsg, 0x00, sizeof(struct msghdr)); + smsg.msg_iov = &iov; + smsg.msg_iovlen = 1; + smsg.msg_control = cred_msg; + smsg.msg_controllen = sizeof(cred_msg); + + if (udev_monitor->snl.nl.nl_family != 0) { + smsg.msg_name = &snl; + smsg.msg_namelen = sizeof(snl); + } + + buflen = recvmsg(udev_monitor->sock, &smsg, 0); + if (buflen < 0) { + if (errno != EINTR) + udev_dbg(udev_monitor->udev, "unable to receive message\n"); + return NULL; + } + + if (buflen < 32 || (size_t)buflen >= sizeof(buf)) { + udev_dbg(udev_monitor->udev, "invalid message length\n"); + return NULL; + } + + if (udev_monitor->snl.nl.nl_family != 0) { + if (snl.nl.nl_groups == 0) { + /* unicast message, check if we trust the sender */ + if (udev_monitor->snl_trusted_sender.nl.nl_pid == 0 || + snl.nl.nl_pid != udev_monitor->snl_trusted_sender.nl.nl_pid) { + udev_dbg(udev_monitor->udev, "unicast netlink message ignored\n"); + return NULL; + } + } else if (snl.nl.nl_groups == UDEV_MONITOR_KERNEL) { + if (snl.nl.nl_pid > 0) { + udev_dbg(udev_monitor->udev, "multicast kernel netlink message from pid %d ignored\n", + snl.nl.nl_pid); + return NULL; + } + } + } + + cmsg = CMSG_FIRSTHDR(&smsg); + if (cmsg == NULL || cmsg->cmsg_type != SCM_CREDENTIALS) { + udev_dbg(udev_monitor->udev, "no sender credentials received, message ignored\n"); + return NULL; + } + + cred = (struct ucred *)CMSG_DATA(cmsg); + if (cred->uid != 0) { + udev_dbg(udev_monitor->udev, "sender uid=%d, message ignored\n", cred->uid); + return NULL; + } + + if (memcmp(buf, "libudev", 8) == 0) { + /* udev message needs proper version magic */ + nlh = (struct udev_monitor_netlink_header *) buf; + if (nlh->magic != htonl(UDEV_MONITOR_MAGIC)) { + udev_err(udev_monitor->udev, "unrecognized message signature (%x != %x)\n", + nlh->magic, htonl(UDEV_MONITOR_MAGIC)); + return NULL; + } + if (nlh->properties_off+32 > (size_t)buflen) + return NULL; + bufpos = nlh->properties_off; + } else { + /* kernel message with header */ + bufpos = strlen(buf) + 1; + if ((size_t)bufpos < sizeof("a@/d") || bufpos >= buflen) { + udev_dbg(udev_monitor->udev, "invalid message length\n"); + return NULL; + } + + /* check message header */ + if (strstr(buf, "@/") == NULL) { + udev_dbg(udev_monitor->udev, "unrecognized message header\n"); + return NULL; + } + } + + udev_device = udev_device_new(udev_monitor->udev); + if (udev_device == NULL) + return NULL; + udev_device_set_info_loaded(udev_device); + + while (bufpos < buflen) { + char *key; + size_t keylen; + + key = &buf[bufpos]; + keylen = strlen(key); + if (keylen == 0) + break; + bufpos += keylen + 1; + udev_device_add_property_from_string_parse(udev_device, key); + } + + if (udev_device_add_property_from_string_parse_finish(udev_device) < 0) { + udev_dbg(udev_monitor->udev, "missing values, invalid device\n"); + udev_device_unref(udev_device); + return NULL; + } + + /* skip device, if it does not pass the current filter */ + if (!passes_filter(udev_monitor, udev_device)) { + struct pollfd pfd[1]; + int rc; + + udev_device_unref(udev_device); + + /* if something is queued, get next device */ + pfd[0].fd = udev_monitor->sock; + pfd[0].events = POLLIN; + rc = poll(pfd, 1, 0); + if (rc > 0) + goto retry; + return NULL; + } + + return udev_device; +} + +int udev_monitor_send_device(struct udev_monitor *udev_monitor, + struct udev_monitor *destination, struct udev_device *udev_device) +{ + const char *buf; + ssize_t blen; + ssize_t count; + struct msghdr smsg; + struct iovec iov[2]; + const char *val; + struct udev_monitor_netlink_header nlh; + struct udev_list_entry *list_entry; + uint64_t tag_bloom_bits; + + if (udev_monitor->snl.nl.nl_family == 0) + return -EINVAL; + + blen = udev_device_get_properties_monitor_buf(udev_device, &buf); + if (blen < 32) + return -EINVAL; + + /* add versioned header */ + memset(&nlh, 0x00, sizeof(struct udev_monitor_netlink_header)); + memcpy(nlh.prefix, "libudev", 8); + nlh.magic = htonl(UDEV_MONITOR_MAGIC); + nlh.header_size = sizeof(struct udev_monitor_netlink_header); + val = udev_device_get_subsystem(udev_device); + nlh.filter_subsystem_hash = htonl(util_string_hash32(val)); + val = udev_device_get_devtype(udev_device); + if (val != NULL) + nlh.filter_devtype_hash = htonl(util_string_hash32(val)); + iov[0].iov_base = &nlh; + iov[0].iov_len = sizeof(struct udev_monitor_netlink_header); + + /* add tag bloom filter */ + tag_bloom_bits = 0; + udev_list_entry_foreach(list_entry, udev_device_get_tags_list_entry(udev_device)) + tag_bloom_bits |= util_string_bloom64(udev_list_entry_get_name(list_entry)); + if (tag_bloom_bits > 0) { + nlh.filter_tag_bloom_hi = htonl(tag_bloom_bits >> 32); + nlh.filter_tag_bloom_lo = htonl(tag_bloom_bits & 0xffffffff); + } + + /* add properties list */ + nlh.properties_off = iov[0].iov_len; + nlh.properties_len = blen; + iov[1].iov_base = (char *)buf; + iov[1].iov_len = blen; + + memset(&smsg, 0x00, sizeof(struct msghdr)); + smsg.msg_iov = iov; + smsg.msg_iovlen = 2; + /* + * Use custom address for target, or the default one. + * + * If we send to a multicast group, we will get + * ECONNREFUSED, which is expected. + */ + if (destination != NULL) + smsg.msg_name = &destination->snl; + else + smsg.msg_name = &udev_monitor->snl_destination; + smsg.msg_namelen = sizeof(struct sockaddr_nl); + count = sendmsg(udev_monitor->sock, &smsg, 0); + udev_dbg(udev_monitor->udev, "passed %zi bytes to netlink monitor %p\n", count, udev_monitor); + return count; +} + +/** + * udev_monitor_filter_add_match_subsystem_devtype: + * @udev_monitor: the monitor + * @subsystem: the subsystem value to match the incoming devices against + * @devtype: the devtype value to match the incoming devices against + * + * This filter is efficiently executed inside the kernel, and libudev subscribers + * will usually not be woken up for devices which do not match. + * + * The filter must be installed before the monitor is switched to listening mode. + * + * Returns: 0 on success, otherwise a negative error value. + */ +_public_ int udev_monitor_filter_add_match_subsystem_devtype(struct udev_monitor *udev_monitor, const char *subsystem, const char *devtype) +{ + if (udev_monitor == NULL) + return -EINVAL; + if (subsystem == NULL) + return -EINVAL; + if (udev_list_entry_add(&udev_monitor->filter_subsystem_list, subsystem, devtype) == NULL) + return -ENOMEM; + return 0; +} + +/** + * udev_monitor_filter_add_match_tag: + * @udev_monitor: the monitor + * @tag: the name of a tag + * + * This filter is efficiently executed inside the kernel, and libudev subscribers + * will usually not be woken up for devices which do not match. + * + * The filter must be installed before the monitor is switched to listening mode. + * + * Returns: 0 on success, otherwise a negative error value. + */ +_public_ int udev_monitor_filter_add_match_tag(struct udev_monitor *udev_monitor, const char *tag) +{ + if (udev_monitor == NULL) + return -EINVAL; + if (tag == NULL) + return -EINVAL; + if (udev_list_entry_add(&udev_monitor->filter_tag_list, tag, NULL) == NULL) + return -ENOMEM; + return 0; +} + +/** + * udev_monitor_filter_remove: + * @udev_monitor: monitor + * + * Remove all filters from monitor. + * + * Returns: 0 on success, otherwise a negative error value. + */ +_public_ int udev_monitor_filter_remove(struct udev_monitor *udev_monitor) +{ + static struct sock_fprog filter = { 0, NULL }; + + udev_list_cleanup(&udev_monitor->filter_subsystem_list); + return setsockopt(udev_monitor->sock, SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof(filter)); +} diff --git a/src/libudev/libudev-private.h b/src/libudev/libudev-private.h new file mode 100644 index 000000000..1b8638470 --- /dev/null +++ b/src/libudev/libudev-private.h @@ -0,0 +1,183 @@ +/*** + This file is part of systemd. + + Copyright 2008-2012 Kay Sievers + + 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 . +***/ + +#ifndef _LIBUDEV_PRIVATE_H_ +#define _LIBUDEV_PRIVATE_H_ + +#include +#include +#include +#include + +#include "libudev.h" +#include "macro.h" +#include "util.h" +#include "mkdir.h" + +#define READ_END 0 +#define WRITE_END 1 + +/* avoid (sometimes expensive) calculations of parameters for debug output */ +#define udev_log_cond(udev, prio, arg...) \ + do { \ + if (udev_get_log_priority(udev) >= prio) \ + udev_log(udev, prio, __FILE__, __LINE__, __FUNCTION__, ## arg); \ + } while (0) + +#define udev_dbg(udev, arg...) udev_log_cond(udev, LOG_DEBUG, ## arg) +#define udev_info(udev, arg...) udev_log_cond(udev, LOG_INFO, ## arg) +#define udev_err(udev, arg...) udev_log_cond(udev, LOG_ERR, ## arg) + +/* libudev.c */ +void udev_log(struct udev *udev, + int priority, const char *file, int line, const char *fn, + const char *format, ...) + __attribute__((format(printf, 6, 7))); +int udev_get_rules_path(struct udev *udev, char **path[], usec_t *ts_usec[]); +struct udev_list_entry *udev_add_property(struct udev *udev, const char *key, const char *value); +struct udev_list_entry *udev_get_properties_list_entry(struct udev *udev); + +/* libudev-device.c */ +struct udev_device *udev_device_new(struct udev *udev); +mode_t udev_device_get_devnode_mode(struct udev_device *udev_device); +uid_t udev_device_get_devnode_uid(struct udev_device *udev_device); +gid_t udev_device_get_devnode_gid(struct udev_device *udev_device); +int udev_device_set_subsystem(struct udev_device *udev_device, const char *subsystem); +int udev_device_set_syspath(struct udev_device *udev_device, const char *syspath); +int udev_device_set_devnode(struct udev_device *udev_device, const char *devnode); +int udev_device_add_devlink(struct udev_device *udev_device, const char *devlink); +void udev_device_cleanup_devlinks_list(struct udev_device *udev_device); +struct udev_list_entry *udev_device_add_property(struct udev_device *udev_device, const char *key, const char *value); +void udev_device_add_property_from_string_parse(struct udev_device *udev_device, const char *property); +int udev_device_add_property_from_string_parse_finish(struct udev_device *udev_device); +char **udev_device_get_properties_envp(struct udev_device *udev_device); +ssize_t udev_device_get_properties_monitor_buf(struct udev_device *udev_device, const char **buf); +int udev_device_read_db(struct udev_device *udev_device, const char *dbfile); +int udev_device_read_uevent_file(struct udev_device *udev_device); +int udev_device_set_action(struct udev_device *udev_device, const char *action); +const char *udev_device_get_devpath_old(struct udev_device *udev_device); +const char *udev_device_get_id_filename(struct udev_device *udev_device); +void udev_device_set_is_initialized(struct udev_device *udev_device); +int udev_device_add_tag(struct udev_device *udev_device, const char *tag); +void udev_device_cleanup_tags_list(struct udev_device *udev_device); +usec_t udev_device_get_usec_initialized(struct udev_device *udev_device); +void udev_device_set_usec_initialized(struct udev_device *udev_device, usec_t usec_initialized); +int udev_device_get_devlink_priority(struct udev_device *udev_device); +int udev_device_set_devlink_priority(struct udev_device *udev_device, int prio); +int udev_device_get_watch_handle(struct udev_device *udev_device); +int udev_device_set_watch_handle(struct udev_device *udev_device, int handle); +int udev_device_get_ifindex(struct udev_device *udev_device); +void udev_device_set_info_loaded(struct udev_device *device); +bool udev_device_get_db_persist(struct udev_device *udev_device); +void udev_device_set_db_persist(struct udev_device *udev_device); + +/* libudev-device-private.c */ +int udev_device_update_db(struct udev_device *udev_device); +int udev_device_delete_db(struct udev_device *udev_device); +int udev_device_tag_index(struct udev_device *dev, struct udev_device *dev_old, bool add); + +/* libudev-monitor.c - netlink/unix socket communication */ +int udev_monitor_disconnect(struct udev_monitor *udev_monitor); +int udev_monitor_allow_unicast_sender(struct udev_monitor *udev_monitor, struct udev_monitor *sender); +int udev_monitor_send_device(struct udev_monitor *udev_monitor, + struct udev_monitor *destination, struct udev_device *udev_device); +struct udev_monitor *udev_monitor_new_from_netlink_fd(struct udev *udev, const char *name, int fd); + +/* libudev-list.c */ +struct udev_list_node { + struct udev_list_node *next, *prev; +}; +struct udev_list { + struct udev *udev; + struct udev_list_node node; + struct udev_list_entry **entries; + unsigned int entries_cur; + unsigned int entries_max; + bool unique; +}; +#define UDEV_LIST(list) struct udev_list_node list = { &(list), &(list) } +void udev_list_node_init(struct udev_list_node *list); +int udev_list_node_is_empty(struct udev_list_node *list); +void udev_list_node_append(struct udev_list_node *new, struct udev_list_node *list); +void udev_list_node_remove(struct udev_list_node *entry); +#define udev_list_node_foreach(node, list) \ + for (node = (list)->next; \ + node != list; \ + node = (node)->next) +#define udev_list_node_foreach_safe(node, tmp, list) \ + for (node = (list)->next, tmp = (node)->next; \ + node != list; \ + node = tmp, tmp = (tmp)->next) +void udev_list_init(struct udev *udev, struct udev_list *list, bool unique); +void udev_list_cleanup(struct udev_list *list); +struct udev_list_entry *udev_list_get_entry(struct udev_list *list); +struct udev_list_entry *udev_list_entry_add(struct udev_list *list, const char *name, const char *value); +void udev_list_entry_delete(struct udev_list_entry *entry); +void udev_list_entry_insert_before(struct udev_list_entry *new, struct udev_list_entry *entry); +void udev_list_entry_append(struct udev_list_entry *new, struct udev_list *list); +int udev_list_entry_get_num(struct udev_list_entry *list_entry); +void udev_list_entry_set_num(struct udev_list_entry *list_entry, int num); +#define udev_list_entry_foreach_safe(entry, tmp, first) \ + for (entry = first, tmp = udev_list_entry_get_next(entry); \ + entry != NULL; \ + entry = tmp, tmp = udev_list_entry_get_next(tmp)) + +/* libudev-queue.c */ +unsigned long long int udev_get_kernel_seqnum(struct udev *udev); +int udev_queue_read_seqnum(FILE *queue_file, unsigned long long int *seqnum); +ssize_t udev_queue_read_devpath(FILE *queue_file, char *devpath, size_t size); +ssize_t udev_queue_skip_devpath(FILE *queue_file); + +/* libudev-queue-private.c */ +struct udev_queue_export *udev_queue_export_new(struct udev *udev); +struct udev_queue_export *udev_queue_export_unref(struct udev_queue_export *udev_queue_export); +void udev_queue_export_cleanup(struct udev_queue_export *udev_queue_export); +int udev_queue_export_device_queued(struct udev_queue_export *udev_queue_export, struct udev_device *udev_device); +int udev_queue_export_device_finished(struct udev_queue_export *udev_queue_export, struct udev_device *udev_device); + +/* libudev-hwdb.c */ +bool udev_hwdb_validate(struct udev_hwdb *hwdb); + +/* libudev-util.c */ +#define UTIL_PATH_SIZE 1024 +#define UTIL_NAME_SIZE 512 +#define UTIL_LINE_SIZE 16384 +#define UDEV_ALLOWED_CHARS_INPUT "/ $%?," +ssize_t util_get_sys_core_link_value(struct udev *udev, const char *slink, const char *syspath, char *value, size_t size); +int util_resolve_sys_link(struct udev *udev, char *syspath, size_t size); +int util_log_priority(const char *priority); +size_t util_path_encode(const char *src, char *dest, size_t size); +void util_remove_trailing_chars(char *path, char c); +size_t util_strpcpy(char **dest, size_t size, const char *src); +size_t util_strpcpyf(char **dest, size_t size, const char *src, ...) __attribute__((format(printf, 3, 4))); +size_t util_strpcpyl(char **dest, size_t size, const char *src, ...) __attribute__((sentinel)); +size_t util_strscpy(char *dest, size_t size, const char *src); +size_t util_strscpyl(char *dest, size_t size, const char *src, ...) __attribute__((sentinel)); +int util_replace_whitespace(const char *str, char *to, size_t len); +int util_replace_chars(char *str, const char *white); +unsigned int util_string_hash32(const char *key); +uint64_t util_string_bloom64(const char *str); + +/* libudev-util-private.c */ +int util_delete_path(struct udev *udev, const char *path); +uid_t util_lookup_user(struct udev *udev, const char *user); +gid_t util_lookup_group(struct udev *udev, const char *group); +int util_resolve_subsys_kernel(struct udev *udev, const char *string, char *result, size_t maxsize, int read_value); +ssize_t print_kmsg(const char *fmt, ...) __attribute__((format(printf, 1, 2))); +#endif diff --git a/src/libudev/libudev-queue-private.c b/src/libudev/libudev-queue-private.c new file mode 100644 index 000000000..80d7ceef2 --- /dev/null +++ b/src/libudev/libudev-queue-private.c @@ -0,0 +1,406 @@ +/*** + This file is part of systemd. + + Copyright 2008-2012 Kay Sievers + Copyright 2009 Alan Jenkins + + 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 . +***/ + +/* + * DISCLAIMER - The file format mentioned here is private to udev/libudev, + * and may be changed without notice. + * + * The udev event queue is exported as a binary log file. + * Each log record consists of a sequence number followed by the device path. + * + * When a new event is queued, its details are appended to the log. + * When the event finishes, a second record is appended to the log + * with the same sequence number but a devpath len of 0. + * + * Example: + * { 0x0000000000000001 } + * { 0x0000000000000001, 0x0019, "/devices/virtual/mem/null" }, + * { 0x0000000000000002, 0x001b, "/devices/virtual/mem/random" }, + * { 0x0000000000000001, 0x0000 }, + * { 0x0000000000000003, 0x0019, "/devices/virtual/mem/zero" }, + * + * Events 2 and 3 are still queued, but event 1 has finished. + * + * The queue does not grow indefinitely. It is periodically re-created + * to remove finished events. Atomic rename() makes this transparent to readers. + * + * The queue file starts with a single sequence number which specifies the + * minimum sequence number in the log that follows. Any events prior to this + * sequence number have already finished. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "libudev.h" +#include "libudev-private.h" + +static int rebuild_queue_file(struct udev_queue_export *udev_queue_export); + +struct udev_queue_export { + struct udev *udev; + int queued_count; /* number of unfinished events exported in queue file */ + FILE *queue_file; + unsigned long long int seqnum_max; /* earliest sequence number in queue file */ + unsigned long long int seqnum_min; /* latest sequence number in queue file */ + int waste_bytes; /* queue file bytes wasted on finished events */ +}; + +struct udev_queue_export *udev_queue_export_new(struct udev *udev) +{ + struct udev_queue_export *udev_queue_export; + unsigned long long int initial_seqnum; + + if (udev == NULL) + return NULL; + + udev_queue_export = calloc(1, sizeof(struct udev_queue_export)); + if (udev_queue_export == NULL) + return NULL; + udev_queue_export->udev = udev; + + initial_seqnum = udev_get_kernel_seqnum(udev); + udev_queue_export->seqnum_min = initial_seqnum; + udev_queue_export->seqnum_max = initial_seqnum; + + udev_queue_export_cleanup(udev_queue_export); + if (rebuild_queue_file(udev_queue_export) != 0) { + free(udev_queue_export); + return NULL; + } + + return udev_queue_export; +} + +struct udev_queue_export *udev_queue_export_unref(struct udev_queue_export *udev_queue_export) +{ + if (udev_queue_export == NULL) + return NULL; + if (udev_queue_export->queue_file != NULL) + fclose(udev_queue_export->queue_file); + free(udev_queue_export); + return NULL; +} + +void udev_queue_export_cleanup(struct udev_queue_export *udev_queue_export) +{ + if (udev_queue_export == NULL) + return; + unlink("/run/udev/queue.tmp"); + unlink("/run/udev/queue.bin"); +} + +static int skip_to(FILE *file, long offset) +{ + long old_offset; + + /* fseek may drop buffered data, avoid it for small seeks */ + old_offset = ftell(file); + if (offset > old_offset && offset - old_offset <= BUFSIZ) { + size_t skip_bytes = offset - old_offset; + char *buf = alloca(skip_bytes); + + if (fread(buf, skip_bytes, 1, file) != skip_bytes) + return -1; + } + + return fseek(file, offset, SEEK_SET); +} + +struct queue_devpaths { + unsigned int devpaths_first; /* index of first queued event */ + unsigned int devpaths_size; + long devpaths[]; /* seqnum -> offset of devpath in queue file (or 0) */ +}; + +/* + * Returns a table mapping seqnum to devpath file offset for currently queued events. + * devpaths[i] represents the event with seqnum = i + udev_queue_export->seqnum_min. + */ +static struct queue_devpaths *build_index(struct udev_queue_export *udev_queue_export) +{ + struct queue_devpaths *devpaths; + unsigned long long int range; + long devpath_offset; + ssize_t devpath_len; + unsigned long long int seqnum; + unsigned long long int n; + unsigned int i; + + /* seek to the first event in the file */ + rewind(udev_queue_export->queue_file); + udev_queue_read_seqnum(udev_queue_export->queue_file, &seqnum); + + /* allocate the table */ + range = udev_queue_export->seqnum_min - udev_queue_export->seqnum_max; + if (range - 1 > INT_MAX) { + udev_err(udev_queue_export->udev, "queue file overflow\n"); + return NULL; + } + devpaths = calloc(1, sizeof(struct queue_devpaths) + (range + 1) * sizeof(long)); + if (devpaths == NULL) + return NULL; + devpaths->devpaths_size = range + 1; + + /* read all records and populate the table */ + for (;;) { + if (udev_queue_read_seqnum(udev_queue_export->queue_file, &seqnum) < 0) + break; + n = seqnum - udev_queue_export->seqnum_max; + if (n >= devpaths->devpaths_size) + goto read_error; + + devpath_offset = ftell(udev_queue_export->queue_file); + devpath_len = udev_queue_skip_devpath(udev_queue_export->queue_file); + if (devpath_len < 0) + goto read_error; + + if (devpath_len > 0) + devpaths->devpaths[n] = devpath_offset; + else + devpaths->devpaths[n] = 0; + } + + /* find first queued event */ + for (i = 0; i < devpaths->devpaths_size; i++) { + if (devpaths->devpaths[i] != 0) + break; + } + devpaths->devpaths_first = i; + + return devpaths; + +read_error: + udev_err(udev_queue_export->udev, "queue file corrupted\n"); + free(devpaths); + return NULL; +} + +static int rebuild_queue_file(struct udev_queue_export *udev_queue_export) +{ + unsigned long long int seqnum; + struct queue_devpaths *devpaths = NULL; + FILE *new_queue_file = NULL; + unsigned int i; + + /* read old queue file */ + if (udev_queue_export->queue_file != NULL) { + devpaths = build_index(udev_queue_export); + if (devpaths != NULL) + udev_queue_export->seqnum_max += devpaths->devpaths_first; + } + if (devpaths == NULL) { + udev_queue_export->queued_count = 0; + udev_queue_export->seqnum_max = udev_queue_export->seqnum_min; + } + + /* create new queue file */ + new_queue_file = fopen("/run/udev/queue.tmp", "w+e"); + if (new_queue_file == NULL) + goto error; + seqnum = udev_queue_export->seqnum_max; + fwrite(&seqnum, 1, sizeof(unsigned long long int), new_queue_file); + + /* copy unfinished events only to the new file */ + if (devpaths != NULL) { + for (i = devpaths->devpaths_first; i < devpaths->devpaths_size; i++) { + char devpath[UTIL_PATH_SIZE]; + int err; + unsigned short devpath_len; + + if (devpaths->devpaths[i] != 0) + { + skip_to(udev_queue_export->queue_file, devpaths->devpaths[i]); + err = udev_queue_read_devpath(udev_queue_export->queue_file, devpath, sizeof(devpath)); + devpath_len = err; + + fwrite(&seqnum, sizeof(unsigned long long int), 1, new_queue_file); + fwrite(&devpath_len, sizeof(unsigned short), 1, new_queue_file); + fwrite(devpath, 1, devpath_len, new_queue_file); + } + seqnum++; + } + free(devpaths); + devpaths = NULL; + } + fflush(new_queue_file); + if (ferror(new_queue_file)) + goto error; + + /* rename the new file on top of the old one */ + if (rename("/run/udev/queue.tmp", "/run/udev/queue.bin") != 0) + goto error; + + if (udev_queue_export->queue_file != NULL) + fclose(udev_queue_export->queue_file); + udev_queue_export->queue_file = new_queue_file; + udev_queue_export->waste_bytes = 0; + + return 0; + +error: + udev_err(udev_queue_export->udev, "failed to create queue file: %m\n"); + udev_queue_export_cleanup(udev_queue_export); + + if (udev_queue_export->queue_file != NULL) { + fclose(udev_queue_export->queue_file); + udev_queue_export->queue_file = NULL; + } + if (new_queue_file != NULL) + fclose(new_queue_file); + + if (devpaths != NULL) + free(devpaths); + udev_queue_export->queued_count = 0; + udev_queue_export->waste_bytes = 0; + udev_queue_export->seqnum_max = udev_queue_export->seqnum_min; + + return -1; +} + +static int write_queue_record(struct udev_queue_export *udev_queue_export, + unsigned long long int seqnum, const char *devpath, size_t devpath_len) +{ + unsigned short len; + + if (udev_queue_export->queue_file == NULL) + return -1; + + if (fwrite(&seqnum, sizeof(unsigned long long int), 1, udev_queue_export->queue_file) != 1) + goto write_error; + + len = (devpath_len < USHRT_MAX) ? devpath_len : USHRT_MAX; + if (fwrite(&len, sizeof(unsigned short), 1, udev_queue_export->queue_file) != 1) + goto write_error; + if (len > 0) { + if (fwrite(devpath, 1, len, udev_queue_export->queue_file) != len) + goto write_error; + } + + /* *must* flush output; caller may fork */ + if (fflush(udev_queue_export->queue_file) != 0) + goto write_error; + + return 0; + +write_error: + /* if we failed half way through writing a record to a file, + we should not try to write any further records to it. */ + udev_err(udev_queue_export->udev, "error writing to queue file: %m\n"); + fclose(udev_queue_export->queue_file); + udev_queue_export->queue_file = NULL; + + return -1; +} + +enum device_state { + DEVICE_QUEUED, + DEVICE_FINISHED, +}; + +static inline size_t queue_record_size(size_t devpath_len) +{ + return sizeof(unsigned long long int) + sizeof(unsigned short int) + devpath_len; +} + +static int update_queue(struct udev_queue_export *udev_queue_export, + struct udev_device *udev_device, enum device_state state) +{ + unsigned long long int seqnum = udev_device_get_seqnum(udev_device); + const char *devpath = NULL; + size_t devpath_len = 0; + int bytes; + int err; + + /* FINISHED records have a zero length devpath */ + if (state == DEVICE_QUEUED) { + devpath = udev_device_get_devpath(udev_device); + devpath_len = strlen(devpath); + } + + /* recover from an earlier failed rebuild */ + if (udev_queue_export->queue_file == NULL) { + if (rebuild_queue_file(udev_queue_export) != 0) + return -1; + } + + /* if we're removing the last event from the queue, that's the best time to rebuild it */ + if (state != DEVICE_QUEUED && udev_queue_export->queued_count == 1) { + /* we don't need to read the old queue file */ + fclose(udev_queue_export->queue_file); + udev_queue_export->queue_file = NULL; + rebuild_queue_file(udev_queue_export); + return 0; + } + + /* try to rebuild the queue files before they grow larger than one page. */ + bytes = ftell(udev_queue_export->queue_file) + queue_record_size(devpath_len); + if ((udev_queue_export->waste_bytes > bytes / 2) && bytes > 4096) + rebuild_queue_file(udev_queue_export); + + /* don't record a finished event, if we already dropped the event in a failed rebuild */ + if (seqnum < udev_queue_export->seqnum_max) + return 0; + + /* now write to the queue */ + if (state == DEVICE_QUEUED) { + udev_queue_export->queued_count++; + udev_queue_export->seqnum_min = seqnum; + } else { + udev_queue_export->waste_bytes += queue_record_size(devpath_len) + queue_record_size(0); + udev_queue_export->queued_count--; + } + err = write_queue_record(udev_queue_export, seqnum, devpath, devpath_len); + + /* try to handle ENOSPC */ + if (err != 0 && udev_queue_export->queued_count == 0) { + udev_queue_export_cleanup(udev_queue_export); + err = rebuild_queue_file(udev_queue_export); + } + + return err; +} + +static int update(struct udev_queue_export *udev_queue_export, + struct udev_device *udev_device, enum device_state state) +{ + if (update_queue(udev_queue_export, udev_device, state) != 0) + return -1; + + return 0; +} + +int udev_queue_export_device_queued(struct udev_queue_export *udev_queue_export, struct udev_device *udev_device) +{ + return update(udev_queue_export, udev_device, DEVICE_QUEUED); +} + +int udev_queue_export_device_finished(struct udev_queue_export *udev_queue_export, struct udev_device *udev_device) +{ + return update(udev_queue_export, udev_device, DEVICE_FINISHED); +} diff --git a/src/libudev/libudev-queue.c b/src/libudev/libudev-queue.c new file mode 100644 index 000000000..08d52ab1f --- /dev/null +++ b/src/libudev/libudev-queue.c @@ -0,0 +1,480 @@ +/*** + This file is part of systemd. + + Copyright 2008-2012 Kay Sievers + Copyright 2009 Alan Jenkins + + 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "libudev.h" +#include "libudev-private.h" + +/** + * SECTION:libudev-queue + * @short_description: access to currently active events + * + * The udev daemon processes events asynchronously. All events which do not have + * interdependencies run in parallel. This exports the current state of the + * event processing queue, and the current event sequence numbers from the kernel + * and the udev daemon. + */ + +/** + * udev_queue: + * + * Opaque object representing the current event queue in the udev daemon. + */ +struct udev_queue { + struct udev *udev; + int refcount; + struct udev_list queue_list; +}; + +/** + * udev_queue_new: + * @udev: udev library context + * + * The initial refcount is 1, and needs to be decremented to + * release the resources of the udev queue context. + * + * Returns: the udev queue context, or #NULL on error. + **/ +_public_ struct udev_queue *udev_queue_new(struct udev *udev) +{ + struct udev_queue *udev_queue; + + if (udev == NULL) + return NULL; + + udev_queue = calloc(1, sizeof(struct udev_queue)); + if (udev_queue == NULL) + return NULL; + udev_queue->refcount = 1; + udev_queue->udev = udev; + udev_list_init(udev, &udev_queue->queue_list, false); + return udev_queue; +} + +/** + * udev_queue_ref: + * @udev_queue: udev queue context + * + * Take a reference of a udev queue context. + * + * Returns: the same udev queue context. + **/ +_public_ struct udev_queue *udev_queue_ref(struct udev_queue *udev_queue) +{ + if (udev_queue == NULL) + return NULL; + udev_queue->refcount++; + return udev_queue; +} + +/** + * udev_queue_unref: + * @udev_queue: udev queue context + * + * Drop a reference of a udev queue context. If the refcount reaches zero, + * the resources of the queue context will be released. + * + * Returns: the passed queue context if it has still an active reference, or #NULL otherwise. + **/ +_public_ struct udev_queue *udev_queue_unref(struct udev_queue *udev_queue) +{ + if (udev_queue == NULL) + return NULL; + udev_queue->refcount--; + if (udev_queue->refcount > 0) + return udev_queue; + udev_list_cleanup(&udev_queue->queue_list); + free(udev_queue); + return NULL; +} + +/** + * udev_queue_get_udev: + * @udev_queue: udev queue context + * + * Retrieve the udev library context the queue context was created with. + * + * Returns: the udev library context. + **/ +_public_ struct udev *udev_queue_get_udev(struct udev_queue *udev_queue) +{ + if (udev_queue == NULL) + return NULL; + return udev_queue->udev; +} + +unsigned long long int udev_get_kernel_seqnum(struct udev *udev) +{ + unsigned long long int seqnum; + int fd; + char buf[32]; + ssize_t len; + + fd = open("/sys/kernel/uevent_seqnum", O_RDONLY|O_CLOEXEC); + if (fd < 0) + return 0; + len = read(fd, buf, sizeof(buf)); + close(fd); + if (len <= 2) + return 0; + buf[len-1] = '\0'; + seqnum = strtoull(buf, NULL, 10); + return seqnum; +} + +/** + * udev_queue_get_kernel_seqnum: + * @udev_queue: udev queue context + * + * Get the current kernel event sequence number. + * + * Returns: the sequence number. + **/ +_public_ unsigned long long int udev_queue_get_kernel_seqnum(struct udev_queue *udev_queue) +{ + unsigned long long int seqnum; + + if (udev_queue == NULL) + return -EINVAL; + + seqnum = udev_get_kernel_seqnum(udev_queue->udev); + return seqnum; +} + +int udev_queue_read_seqnum(FILE *queue_file, unsigned long long int *seqnum) +{ + if (fread(seqnum, sizeof(unsigned long long int), 1, queue_file) != 1) + return -1; + + return 0; +} + +ssize_t udev_queue_skip_devpath(FILE *queue_file) +{ + unsigned short int len; + + if (fread(&len, sizeof(unsigned short int), 1, queue_file) == 1) { + char *devpath = alloca(len); + + /* use fread to skip, fseek might drop buffered data */ + if (fread(devpath, 1, len, queue_file) == len) + return len; + } + + return -1; +} + +ssize_t udev_queue_read_devpath(FILE *queue_file, char *devpath, size_t size) +{ + unsigned short int read_bytes = 0; + unsigned short int len; + + if (fread(&len, sizeof(unsigned short int), 1, queue_file) != 1) + return -1; + + read_bytes = (len < size - 1) ? len : size - 1; + if (fread(devpath, 1, read_bytes, queue_file) != read_bytes) + return -1; + devpath[read_bytes] = '\0'; + + /* if devpath was too long, skip unread characters */ + if (read_bytes != len) { + unsigned short int skip_bytes = len - read_bytes; + char *buf = alloca(skip_bytes); + + if (fread(buf, 1, skip_bytes, queue_file) != skip_bytes) + return -1; + } + + return read_bytes; +} + +static FILE *open_queue_file(struct udev_queue *udev_queue, unsigned long long int *seqnum_start) +{ + FILE *queue_file; + + queue_file = fopen("/run/udev/queue.bin", "re"); + if (queue_file == NULL) + return NULL; + + if (udev_queue_read_seqnum(queue_file, seqnum_start) < 0) { + udev_err(udev_queue->udev, "corrupt queue file\n"); + fclose(queue_file); + return NULL; + } + + return queue_file; +} + +/** + * udev_queue_get_udev_seqnum: + * @udev_queue: udev queue context + * + * Get the last known udev event sequence number. + * + * Returns: the sequence number. + **/ +_public_ unsigned long long int udev_queue_get_udev_seqnum(struct udev_queue *udev_queue) +{ + unsigned long long int seqnum_udev; + FILE *queue_file; + + queue_file = open_queue_file(udev_queue, &seqnum_udev); + if (queue_file == NULL) + return 0; + + for (;;) { + unsigned long long int seqnum; + ssize_t devpath_len; + + if (udev_queue_read_seqnum(queue_file, &seqnum) < 0) + break; + devpath_len = udev_queue_skip_devpath(queue_file); + if (devpath_len < 0) + break; + if (devpath_len > 0) + seqnum_udev = seqnum; + } + + fclose(queue_file); + return seqnum_udev; +} + +/** + * udev_queue_get_udev_is_active: + * @udev_queue: udev queue context + * + * Check if udev is active on the system. + * + * Returns: a flag indicating if udev is active. + **/ +_public_ int udev_queue_get_udev_is_active(struct udev_queue *udev_queue) +{ + unsigned long long int seqnum_start; + FILE *queue_file; + + queue_file = open_queue_file(udev_queue, &seqnum_start); + if (queue_file == NULL) + return 0; + + fclose(queue_file); + return 1; +} + +/** + * udev_queue_get_queue_is_empty: + * @udev_queue: udev queue context + * + * Check if udev is currently processing any events. + * + * Returns: a flag indicating if udev is currently handling events. + **/ +_public_ int udev_queue_get_queue_is_empty(struct udev_queue *udev_queue) +{ + unsigned long long int seqnum_kernel; + unsigned long long int seqnum_udev = 0; + int queued = 0; + int is_empty = 0; + FILE *queue_file; + + if (udev_queue == NULL) + return -EINVAL; + queue_file = open_queue_file(udev_queue, &seqnum_udev); + if (queue_file == NULL) + return 1; + + for (;;) { + unsigned long long int seqnum; + ssize_t devpath_len; + + if (udev_queue_read_seqnum(queue_file, &seqnum) < 0) + break; + devpath_len = udev_queue_skip_devpath(queue_file); + if (devpath_len < 0) + break; + + if (devpath_len > 0) { + queued++; + seqnum_udev = seqnum; + } else { + queued--; + } + } + + if (queued > 0) + goto out; + + seqnum_kernel = udev_queue_get_kernel_seqnum(udev_queue); + if (seqnum_udev < seqnum_kernel) + goto out; + + is_empty = 1; + +out: + fclose(queue_file); + return is_empty; +} + +/** + * udev_queue_get_seqnum_sequence_is_finished: + * @udev_queue: udev queue context + * @start: first event sequence number + * @end: last event sequence number + * + * Check if udev is currently processing any events in a given sequence number range. + * + * Returns: a flag indicating if any of the sequence numbers in the given range is currently active. + **/ +_public_ int udev_queue_get_seqnum_sequence_is_finished(struct udev_queue *udev_queue, + unsigned long long int start, unsigned long long int end) +{ + unsigned long long int seqnum; + ssize_t devpath_len; + int unfinished; + FILE *queue_file; + + if (udev_queue == NULL) + return -EINVAL; + queue_file = open_queue_file(udev_queue, &seqnum); + if (queue_file == NULL) + return 1; + if (start < seqnum) + start = seqnum; + if (start > end) { + fclose(queue_file); + return 1; + } + if (end - start > INT_MAX - 1) { + fclose(queue_file); + return -EOVERFLOW; + } + + /* + * we might start with 0, and handle the initial seqnum + * only when we find an entry in the queue file + **/ + unfinished = end - start; + + do { + if (udev_queue_read_seqnum(queue_file, &seqnum) < 0) + break; + devpath_len = udev_queue_skip_devpath(queue_file); + if (devpath_len < 0) + break; + + /* + * we might start with an empty or re-build queue file, where + * the initial seqnum is not recorded as finished + */ + if (start == seqnum && devpath_len > 0) + unfinished++; + + if (devpath_len == 0) { + if (seqnum >= start && seqnum <= end) + unfinished--; + } + } while (unfinished > 0); + + fclose(queue_file); + + return (unfinished == 0); +} + +/** + * udev_queue_get_seqnum_is_finished: + * @udev_queue: udev queue context + * @seqnum: sequence number + * + * Check if udev is currently processing a given sequence number. + * + * Returns: a flag indicating if the given sequence number is currently active. + **/ +_public_ int udev_queue_get_seqnum_is_finished(struct udev_queue *udev_queue, unsigned long long int seqnum) +{ + if (!udev_queue_get_seqnum_sequence_is_finished(udev_queue, seqnum, seqnum)) + return 0; + + return 1; +} + +/** + * udev_queue_get_queued_list_entry: + * @udev_queue: udev queue context + * + * Get the first entry of the list of queued events. + * + * Returns: a udev_list_entry. + **/ +_public_ struct udev_list_entry *udev_queue_get_queued_list_entry(struct udev_queue *udev_queue) +{ + unsigned long long int seqnum; + FILE *queue_file; + + if (udev_queue == NULL) + return NULL; + udev_list_cleanup(&udev_queue->queue_list); + + queue_file = open_queue_file(udev_queue, &seqnum); + if (queue_file == NULL) + return NULL; + + for (;;) { + char syspath[UTIL_PATH_SIZE]; + char *s; + size_t l; + ssize_t len; + char seqnum_str[32]; + struct udev_list_entry *list_entry; + + if (udev_queue_read_seqnum(queue_file, &seqnum) < 0) + break; + snprintf(seqnum_str, sizeof(seqnum_str), "%llu", seqnum); + + s = syspath; + l = util_strpcpy(&s, sizeof(syspath), "/sys"); + len = udev_queue_read_devpath(queue_file, s, l); + if (len < 0) + break; + + if (len > 0) { + udev_list_entry_add(&udev_queue->queue_list, syspath, seqnum_str); + } else { + udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_queue->queue_list)) { + if (strcmp(seqnum_str, udev_list_entry_get_value(list_entry)) == 0) { + udev_list_entry_delete(list_entry); + break; + } + } + } + } + fclose(queue_file); + + return udev_list_get_entry(&udev_queue->queue_list); +} diff --git a/src/libudev/libudev-util.c b/src/libudev/libudev-util.c new file mode 100644 index 000000000..b55bf75bf --- /dev/null +++ b/src/libudev/libudev-util.c @@ -0,0 +1,742 @@ +/*** + This file is part of systemd. + + Copyright 2008-2012 Kay Sievers + + 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "libudev.h" +#include "libudev-private.h" + +/** + * SECTION:libudev-util + * @short_description: utils + * + * Utilities useful when dealing with devices and device node names. + */ + +int util_delete_path(struct udev *udev, const char *path) +{ + char p[UTIL_PATH_SIZE]; + char *pos; + int err = 0; + + if (path[0] == '/') + while(path[1] == '/') + path++; + util_strscpy(p, sizeof(p), path); + pos = strrchr(p, '/'); + if (pos == p || pos == NULL) + return 0; + + for (;;) { + *pos = '\0'; + pos = strrchr(p, '/'); + + /* don't remove the last one */ + if ((pos == p) || (pos == NULL)) + break; + + err = rmdir(p); + if (err < 0) { + if (errno == ENOENT) + err = 0; + break; + } + } + return err; +} + +uid_t util_lookup_user(struct udev *udev, const char *user) +{ + char *endptr; + struct passwd pwbuf; + struct passwd *pw; + uid_t uid; + size_t buflen = sysconf(_SC_GETPW_R_SIZE_MAX); + char *buf = alloca(buflen); + + if (strcmp(user, "root") == 0) + return 0; + uid = strtoul(user, &endptr, 10); + if (endptr[0] == '\0') + return uid; + + errno = getpwnam_r(user, &pwbuf, buf, buflen, &pw); + if (pw != NULL) + return pw->pw_uid; + if (errno == 0 || errno == ENOENT || errno == ESRCH) + udev_err(udev, "specified user '%s' unknown\n", user); + else + udev_err(udev, "error resolving user '%s': %m\n", user); + return 0; +} + +gid_t util_lookup_group(struct udev *udev, const char *group) +{ + char *endptr; + struct group grbuf; + struct group *gr; + gid_t gid = 0; + size_t buflen = sysconf(_SC_GETPW_R_SIZE_MAX); + char *buf = NULL; + + if (strcmp(group, "root") == 0) + return 0; + gid = strtoul(group, &endptr, 10); + if (endptr[0] == '\0') + return gid; + gid = 0; + for (;;) { + char *newbuf; + + newbuf = realloc(buf, buflen); + if (!newbuf) + break; + buf = newbuf; + errno = getgrnam_r(group, &grbuf, buf, buflen, &gr); + if (gr != NULL) { + gid = gr->gr_gid; + } else if (errno == ERANGE) { + buflen *= 2; + continue; + } else if (errno == 0 || errno == ENOENT || errno == ESRCH) { + udev_err(udev, "specified group '%s' unknown\n", group); + } else { + udev_err(udev, "error resolving group '%s': %m\n", group); + } + break; + } + free(buf); + return gid; +} + +/* handle "[/]" format */ +int util_resolve_subsys_kernel(struct udev *udev, const char *string, + char *result, size_t maxsize, int read_value) +{ + char temp[UTIL_PATH_SIZE]; + char *subsys; + char *sysname; + struct udev_device *dev; + char *attr; + + if (string[0] != '[') + return -1; + + util_strscpy(temp, sizeof(temp), string); + + subsys = &temp[1]; + + sysname = strchr(subsys, '/'); + if (sysname == NULL) + return -1; + sysname[0] = '\0'; + sysname = &sysname[1]; + + attr = strchr(sysname, ']'); + if (attr == NULL) + return -1; + attr[0] = '\0'; + attr = &attr[1]; + if (attr[0] == '/') + attr = &attr[1]; + if (attr[0] == '\0') + attr = NULL; + + if (read_value && attr == NULL) + return -1; + + dev = udev_device_new_from_subsystem_sysname(udev, subsys, sysname); + if (dev == NULL) + return -1; + + if (read_value) { + const char *val; + + val = udev_device_get_sysattr_value(dev, attr); + if (val != NULL) + util_strscpy(result, maxsize, val); + else + result[0] = '\0'; + udev_dbg(udev, "value '[%s/%s]%s' is '%s'\n", subsys, sysname, attr, result); + } else { + size_t l; + char *s; + + s = result; + l = util_strpcpyl(&s, maxsize, udev_device_get_syspath(dev), NULL); + if (attr != NULL) + util_strpcpyl(&s, l, "/", attr, NULL); + udev_dbg(udev, "path '[%s/%s]%s' is '%s'\n", subsys, sysname, attr, result); + } + udev_device_unref(dev); + return 0; +} +ssize_t util_get_sys_core_link_value(struct udev *udev, const char *slink, const char *syspath, char *value, size_t size) +{ + char path[UTIL_PATH_SIZE]; + char target[UTIL_PATH_SIZE]; + ssize_t len; + const char *pos; + + util_strscpyl(path, sizeof(path), syspath, "/", slink, NULL); + len = readlink(path, target, sizeof(target)); + if (len <= 0 || len == (ssize_t)sizeof(target)) + return -1; + target[len] = '\0'; + pos = strrchr(target, '/'); + if (pos == NULL) + return -1; + pos = &pos[1]; + return util_strscpy(value, size, pos); +} + +int util_resolve_sys_link(struct udev *udev, char *syspath, size_t size) +{ + char link_target[UTIL_PATH_SIZE]; + + ssize_t len; + int i; + int back; + char *base = NULL; + + len = readlink(syspath, link_target, sizeof(link_target)); + if (len <= 0 || len == (ssize_t)sizeof(link_target)) + return -1; + link_target[len] = '\0'; + + for (back = 0; startswith(&link_target[back * 3], "../"); back++) + ; + for (i = 0; i <= back; i++) { + base = strrchr(syspath, '/'); + if (base == NULL) + return -EINVAL; + base[0] = '\0'; + } + if (base == NULL) + return -EINVAL; + util_strscpyl(base, size - (base - syspath), "/", &link_target[back * 3], NULL); + return 0; +} + +int util_log_priority(const char *priority) +{ + char *endptr; + int prio; + + prio = strtol(priority, &endptr, 10); + if (endptr[0] == '\0' || isspace(endptr[0])) + return prio; + if (startswith(priority, "err")) + return LOG_ERR; + if (startswith(priority, "info")) + return LOG_INFO; + if (startswith(priority, "debug")) + return LOG_DEBUG; + return 0; +} + +size_t util_path_encode(const char *src, char *dest, size_t size) +{ + size_t i, j; + + for (i = 0, j = 0; src[i] != '\0'; i++) { + if (src[i] == '/') { + if (j+4 >= size) { + j = 0; + break; + } + memcpy(&dest[j], "\\x2f", 4); + j += 4; + } else if (src[i] == '\\') { + if (j+4 >= size) { + j = 0; + break; + } + memcpy(&dest[j], "\\x5c", 4); + j += 4; + } else { + if (j+1 >= size) { + j = 0; + break; + } + dest[j] = src[i]; + j++; + } + } + dest[j] = '\0'; + return j; +} + +void util_remove_trailing_chars(char *path, char c) +{ + size_t len; + + if (path == NULL) + return; + len = strlen(path); + while (len > 0 && path[len-1] == c) + path[--len] = '\0'; +} + +/* + * Concatenates strings. In any case, terminates in _all_ cases with '\0' + * and moves the @dest pointer forward to the added '\0'. Returns the + * remaining size, and 0 if the string was truncated. + */ +size_t util_strpcpy(char **dest, size_t size, const char *src) +{ + size_t len; + + len = strlen(src); + if (len >= size) { + if (size > 1) + *dest = mempcpy(*dest, src, size-1); + size = 0; + } else { + if (len > 0) { + *dest = mempcpy(*dest, src, len); + size -= len; + } + } + *dest[0] = '\0'; + return size; +} + +size_t util_strpcpyf(char **dest, size_t size, const char *src, ...) +{ + va_list va; + int i; + + va_start(va, src); + i = vsnprintf(*dest, size, src, va); + if (i < (int)size) { + *dest += i; + size -= i; + } else { + *dest += size; + size = 0; + } + va_end(va); + *dest[0] = '\0'; + return size; +} + +/* concatenates list of strings, moves dest forward */ +size_t util_strpcpyl(char **dest, size_t size, const char *src, ...) +{ + va_list va; + + va_start(va, src); + do { + size = util_strpcpy(dest, size, src); + src = va_arg(va, char *); + } while (src != NULL); + va_end(va); + return size; +} + +/* copies string */ +size_t util_strscpy(char *dest, size_t size, const char *src) +{ + char *s; + + s = dest; + return util_strpcpy(&s, size, src); +} + +/* concatenates list of strings */ +size_t util_strscpyl(char *dest, size_t size, const char *src, ...) +{ + va_list va; + char *s; + + va_start(va, src); + s = dest; + do { + size = util_strpcpy(&s, size, src); + src = va_arg(va, char *); + } while (src != NULL); + va_end(va); + + return size; +} + +/* count of characters used to encode one unicode char */ +static int utf8_encoded_expected_len(const char *str) +{ + unsigned char c = (unsigned char)str[0]; + + if (c < 0x80) + return 1; + if ((c & 0xe0) == 0xc0) + return 2; + if ((c & 0xf0) == 0xe0) + return 3; + if ((c & 0xf8) == 0xf0) + return 4; + if ((c & 0xfc) == 0xf8) + return 5; + if ((c & 0xfe) == 0xfc) + return 6; + return 0; +} + +/* decode one unicode char */ +static int utf8_encoded_to_unichar(const char *str) +{ + int unichar; + int len; + int i; + + len = utf8_encoded_expected_len(str); + switch (len) { + case 1: + return (int)str[0]; + case 2: + unichar = str[0] & 0x1f; + break; + case 3: + unichar = (int)str[0] & 0x0f; + break; + case 4: + unichar = (int)str[0] & 0x07; + break; + case 5: + unichar = (int)str[0] & 0x03; + break; + case 6: + unichar = (int)str[0] & 0x01; + break; + default: + return -1; + } + + for (i = 1; i < len; i++) { + if (((int)str[i] & 0xc0) != 0x80) + return -1; + unichar <<= 6; + unichar |= (int)str[i] & 0x3f; + } + + return unichar; +} + +/* expected size used to encode one unicode char */ +static int utf8_unichar_to_encoded_len(int unichar) +{ + if (unichar < 0x80) + return 1; + if (unichar < 0x800) + return 2; + if (unichar < 0x10000) + return 3; + if (unichar < 0x200000) + return 4; + if (unichar < 0x4000000) + return 5; + return 6; +} + +/* check if unicode char has a valid numeric range */ +static int utf8_unichar_valid_range(int unichar) +{ + if (unichar > 0x10ffff) + return 0; + if ((unichar & 0xfffff800) == 0xd800) + return 0; + if ((unichar > 0xfdcf) && (unichar < 0xfdf0)) + return 0; + if ((unichar & 0xffff) == 0xffff) + return 0; + return 1; +} + +/* validate one encoded unicode char and return its length */ +static int utf8_encoded_valid_unichar(const char *str) +{ + int len; + int unichar; + int i; + + len = utf8_encoded_expected_len(str); + if (len == 0) + return -1; + + /* ascii is valid */ + if (len == 1) + return 1; + + /* check if expected encoded chars are available */ + for (i = 0; i < len; i++) + if ((str[i] & 0x80) != 0x80) + return -1; + + unichar = utf8_encoded_to_unichar(str); + + /* check if encoded length matches encoded value */ + if (utf8_unichar_to_encoded_len(unichar) != len) + return -1; + + /* check if value has valid range */ + if (!utf8_unichar_valid_range(unichar)) + return -1; + + return len; +} + +int util_replace_whitespace(const char *str, char *to, size_t len) +{ + size_t i, j; + + /* strip trailing whitespace */ + len = strnlen(str, len); + while (len && isspace(str[len-1])) + len--; + + /* strip leading whitespace */ + i = 0; + while (isspace(str[i]) && (i < len)) + i++; + + j = 0; + while (i < len) { + /* substitute multiple whitespace with a single '_' */ + if (isspace(str[i])) { + while (isspace(str[i])) + i++; + to[j++] = '_'; + } + to[j++] = str[i++]; + } + to[j] = '\0'; + return 0; +} + +static int is_whitelisted(char c, const char *white) +{ + if ((c >= '0' && c <= '9') || + (c >= 'A' && c <= 'Z') || + (c >= 'a' && c <= 'z') || + strchr("#+-.:=@_", c) != NULL || + (white != NULL && strchr(white, c) != NULL)) + return 1; + return 0; +} + +/* allow chars in whitelist, plain ascii, hex-escaping and valid utf8 */ +int util_replace_chars(char *str, const char *white) +{ + size_t i = 0; + int replaced = 0; + + while (str[i] != '\0') { + int len; + + if (is_whitelisted(str[i], white)) { + i++; + continue; + } + + /* accept hex encoding */ + if (str[i] == '\\' && str[i+1] == 'x') { + i += 2; + continue; + } + + /* accept valid utf8 */ + len = utf8_encoded_valid_unichar(&str[i]); + if (len > 1) { + i += len; + continue; + } + + /* if space is allowed, replace whitespace with ordinary space */ + if (isspace(str[i]) && white != NULL && strchr(white, ' ') != NULL) { + str[i] = ' '; + i++; + replaced++; + continue; + } + + /* everything else is replaced with '_' */ + str[i] = '_'; + i++; + replaced++; + } + return replaced; +} + +/** + * udev_util_encode_string: + * @str: input string to be encoded + * @str_enc: output string to store the encoded input string + * @len: maximum size of the output string, which may be + * four times as long as the input string + * + * Encode all potentially unsafe characters of a string to the + * corresponding 2 char hex value prefixed by '\x'. + * + * Returns: 0 if the entire string was copied, non-zero otherwise. + **/ +_public_ int udev_util_encode_string(const char *str, char *str_enc, size_t len) +{ + size_t i, j; + + if (str == NULL || str_enc == NULL) + return -1; + + for (i = 0, j = 0; str[i] != '\0'; i++) { + int seqlen; + + seqlen = utf8_encoded_valid_unichar(&str[i]); + if (seqlen > 1) { + if (len-j < (size_t)seqlen) + goto err; + memcpy(&str_enc[j], &str[i], seqlen); + j += seqlen; + i += (seqlen-1); + } else if (str[i] == '\\' || !is_whitelisted(str[i], NULL)) { + if (len-j < 4) + goto err; + sprintf(&str_enc[j], "\\x%02x", (unsigned char) str[i]); + j += 4; + } else { + if (len-j < 1) + goto err; + str_enc[j] = str[i]; + j++; + } + } + if (len-j < 1) + goto err; + str_enc[j] = '\0'; + return 0; +err: + return -1; +} + +/* + * http://sites.google.com/site/murmurhash/ + * + * All code is released to the public domain. For business purposes, + * Murmurhash is under the MIT license. + * + */ +static unsigned int murmur_hash2(const char *key, int len, unsigned int seed) +{ + /* + * 'm' and 'r' are mixing constants generated offline. + * They're not really 'magic', they just happen to work well. + */ + const unsigned int m = 0x5bd1e995; + const int r = 24; + + /* initialize the hash to a 'random' value */ + unsigned int h = seed ^ len; + + /* mix 4 bytes at a time into the hash */ + const unsigned char * data = (const unsigned char *)key; + + while(len >= 4) { + unsigned int k = *(unsigned int *)data; + + k *= m; + k ^= k >> r; + k *= m; + h *= m; + h ^= k; + + data += 4; + len -= 4; + } + + /* handle the last few bytes of the input array */ + switch(len) { + case 3: + h ^= data[2] << 16; + case 2: + h ^= data[1] << 8; + case 1: + h ^= data[0]; + h *= m; + }; + + /* do a few final mixes of the hash to ensure the last few bytes are well-incorporated */ + h ^= h >> 13; + h *= m; + h ^= h >> 15; + + return h; +} + +unsigned int util_string_hash32(const char *str) +{ + return murmur_hash2(str, strlen(str), 0); +} + +/* get a bunch of bit numbers out of the hash, and set the bits in our bit field */ +uint64_t util_string_bloom64(const char *str) +{ + uint64_t bits = 0; + unsigned int hash = util_string_hash32(str); + + bits |= 1LLU << (hash & 63); + bits |= 1LLU << ((hash >> 6) & 63); + bits |= 1LLU << ((hash >> 12) & 63); + bits |= 1LLU << ((hash >> 18) & 63); + return bits; +} + +ssize_t print_kmsg(const char *fmt, ...) +{ + int fd; + va_list ap; + char text[1024]; + ssize_t len; + ssize_t ret; + + fd = open("/dev/kmsg", O_WRONLY|O_NOCTTY|O_CLOEXEC); + if (fd < 0) + return -errno; + + len = snprintf(text, sizeof(text), "<30>systemd-udevd[%u]: ", getpid()); + + va_start(ap, fmt); + len += vsnprintf(text + len, sizeof(text) - len, fmt, ap); + va_end(ap); + + ret = write(fd, text, len); + if (ret < 0) + ret = -errno; + close(fd); + return ret; +} diff --git a/src/libudev/libudev.c b/src/libudev/libudev.c new file mode 100644 index 000000000..d860ebc08 --- /dev/null +++ b/src/libudev/libudev.c @@ -0,0 +1,314 @@ +/*** + This file is part of systemd. + + Copyright 2008-2012 Kay Sievers + + 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "libudev.h" +#include "libudev-private.h" +#include "missing.h" + +/** + * SECTION:libudev + * @short_description: libudev context + * + * The context contains the default values read from the udev config file, + * and is passed to all library operations. + */ + +/** + * udev: + * + * Opaque object representing the library context. + */ +struct udev { + int refcount; + void (*log_fn)(struct udev *udev, + int priority, const char *file, int line, const char *fn, + const char *format, va_list args); + void *userdata; + struct udev_list properties_list; + int log_priority; +}; + +void udev_log(struct udev *udev, + int priority, const char *file, int line, const char *fn, + const char *format, ...) +{ + va_list args; + + va_start(args, format); + udev->log_fn(udev, priority, file, line, fn, format, args); + va_end(args); +} + +static void log_stderr(struct udev *udev, + int priority, const char *file, int line, const char *fn, + const char *format, va_list args) +{ + fprintf(stderr, "libudev: %s: ", fn); + vfprintf(stderr, format, args); +} + +/** + * udev_get_userdata: + * @udev: udev library context + * + * Retrieve stored data pointer from library context. This might be useful + * to access from callbacks like a custom logging function. + * + * Returns: stored userdata + **/ +_public_ void *udev_get_userdata(struct udev *udev) +{ + if (udev == NULL) + return NULL; + return udev->userdata; +} + +/** + * udev_set_userdata: + * @udev: udev library context + * @userdata: data pointer + * + * Store custom @userdata in the library context. + **/ +_public_ void udev_set_userdata(struct udev *udev, void *userdata) +{ + if (udev == NULL) + return; + udev->userdata = userdata; +} + +/** + * udev_new: + * + * Create udev library context. This reads the udev configuration + * file, and fills in the default values. + * + * The initial refcount is 1, and needs to be decremented to + * release the resources of the udev library context. + * + * Returns: a new udev library context + **/ +_public_ struct udev *udev_new(void) +{ + struct udev *udev; + const char *env; + FILE *f; + + udev = calloc(1, sizeof(struct udev)); + if (udev == NULL) + return NULL; + udev->refcount = 1; + udev->log_fn = log_stderr; + udev->log_priority = LOG_ERR; + udev_list_init(udev, &udev->properties_list, true); + + f = fopen("/etc/udev/udev.conf", "re"); + if (f != NULL) { + char line[UTIL_LINE_SIZE]; + int line_nr = 0; + + while (fgets(line, sizeof(line), f)) { + size_t len; + char *key; + char *val; + + line_nr++; + + /* find key */ + key = line; + while (isspace(key[0])) + key++; + + /* comment or empty line */ + if (key[0] == '#' || key[0] == '\0') + continue; + + /* split key/value */ + val = strchr(key, '='); + if (val == NULL) { + udev_err(udev, "missing = in /etc/udev/udev.conf[%i]; skip line\n", line_nr); + continue; + } + val[0] = '\0'; + val++; + + /* find value */ + while (isspace(val[0])) + val++; + + /* terminate key */ + len = strlen(key); + if (len == 0) + continue; + while (isspace(key[len-1])) + len--; + key[len] = '\0'; + + /* terminate value */ + len = strlen(val); + if (len == 0) + continue; + while (isspace(val[len-1])) + len--; + val[len] = '\0'; + + if (len == 0) + continue; + + /* unquote */ + if (val[0] == '"' || val[0] == '\'') { + if (val[len-1] != val[0]) { + udev_err(udev, "inconsistent quoting in /etc/udev/udev.conf[%i]; skip line\n", line_nr); + continue; + } + val[len-1] = '\0'; + val++; + } + + if (strcmp(key, "udev_log") == 0) { + udev_set_log_priority(udev, util_log_priority(val)); + continue; + } + } + fclose(f); + } + + /* environment overrides config */ + env = secure_getenv("UDEV_LOG"); + if (env != NULL) + udev_set_log_priority(udev, util_log_priority(env)); + + return udev; +} + +/** + * udev_ref: + * @udev: udev library context + * + * Take a reference of the udev library context. + * + * Returns: the passed udev library context + **/ +_public_ struct udev *udev_ref(struct udev *udev) +{ + if (udev == NULL) + return NULL; + udev->refcount++; + return udev; +} + +/** + * udev_unref: + * @udev: udev library context + * + * Drop a reference of the udev library context. If the refcount + * reaches zero, the resources of the context will be released. + * + * Returns: the passed udev library context if it has still an active reference, or #NULL otherwise. + **/ +_public_ struct udev *udev_unref(struct udev *udev) +{ + if (udev == NULL) + return NULL; + udev->refcount--; + if (udev->refcount > 0) + return udev; + udev_list_cleanup(&udev->properties_list); + free(udev); + return NULL; +} + +/** + * udev_set_log_fn: + * @udev: udev library context + * @log_fn: function to be called for logging messages + * + * The built-in logging writes to stderr. It can be + * overridden by a custom function, to plug log messages + * into the users' logging functionality. + * + **/ +_public_ void udev_set_log_fn(struct udev *udev, + void (*log_fn)(struct udev *udev, + int priority, const char *file, int line, const char *fn, + const char *format, va_list args)) +{ + udev->log_fn = log_fn; + udev_dbg(udev, "custom logging function %p registered\n", log_fn); +} + +/** + * udev_get_log_priority: + * @udev: udev library context + * + * The initial logging priority is read from the udev config file + * at startup. + * + * Returns: the current logging priority + **/ +_public_ int udev_get_log_priority(struct udev *udev) +{ + return udev->log_priority; +} + +/** + * udev_set_log_priority: + * @udev: udev library context + * @priority: the new logging priority + * + * Set the current logging priority. The value controls which messages + * are logged. + **/ +_public_ void udev_set_log_priority(struct udev *udev, int priority) +{ + char num[32]; + + udev->log_priority = priority; + snprintf(num, sizeof(num), "%u", udev->log_priority); + udev_add_property(udev, "UDEV_LOG", num); +} + +struct udev_list_entry *udev_add_property(struct udev *udev, const char *key, const char *value) +{ + if (value == NULL) { + struct udev_list_entry *list_entry; + + list_entry = udev_get_properties_list_entry(udev); + list_entry = udev_list_entry_get_by_name(list_entry, key); + if (list_entry != NULL) + udev_list_entry_delete(list_entry); + return NULL; + } + return udev_list_entry_add(&udev->properties_list, key, value); +} + +struct udev_list_entry *udev_get_properties_list_entry(struct udev *udev) +{ + return udev_list_get_entry(&udev->properties_list); +} diff --git a/src/libudev/libudev.h b/src/libudev/libudev.h new file mode 100644 index 000000000..bb41532a2 --- /dev/null +++ b/src/libudev/libudev.h @@ -0,0 +1,204 @@ +/*** + This file is part of systemd. + + Copyright 2008-2012 Kay Sievers + + 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 . +***/ + +#ifndef _LIBUDEV_H_ +#define _LIBUDEV_H_ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * udev - library context + * + * reads the udev config and system environment + * allows custom logging + */ +struct udev; +struct udev *udev_ref(struct udev *udev); +struct udev *udev_unref(struct udev *udev); +struct udev *udev_new(void); +void udev_set_log_fn(struct udev *udev, + void (*log_fn)(struct udev *udev, + int priority, const char *file, int line, const char *fn, + const char *format, va_list args)); +int udev_get_log_priority(struct udev *udev); +void udev_set_log_priority(struct udev *udev, int priority); +void *udev_get_userdata(struct udev *udev); +void udev_set_userdata(struct udev *udev, void *userdata); + +/* + * udev_list + * + * access to libudev generated lists + */ +struct udev_list_entry; +struct udev_list_entry *udev_list_entry_get_next(struct udev_list_entry *list_entry); +struct udev_list_entry *udev_list_entry_get_by_name(struct udev_list_entry *list_entry, const char *name); +const char *udev_list_entry_get_name(struct udev_list_entry *list_entry); +const char *udev_list_entry_get_value(struct udev_list_entry *list_entry); +/** + * udev_list_entry_foreach: + * @list_entry: entry to store the current position + * @first_entry: first entry to start with + * + * Helper to iterate over all entries of a list. + */ +#define udev_list_entry_foreach(list_entry, first_entry) \ + for (list_entry = first_entry; \ + list_entry != NULL; \ + list_entry = udev_list_entry_get_next(list_entry)) + +/* + * udev_device + * + * access to sysfs/kernel devices + */ +struct udev_device; +struct udev_device *udev_device_ref(struct udev_device *udev_device); +struct udev_device *udev_device_unref(struct udev_device *udev_device); +struct udev *udev_device_get_udev(struct udev_device *udev_device); +struct udev_device *udev_device_new_from_syspath(struct udev *udev, const char *syspath); +struct udev_device *udev_device_new_from_devnum(struct udev *udev, char type, dev_t devnum); +struct udev_device *udev_device_new_from_subsystem_sysname(struct udev *udev, const char *subsystem, const char *sysname); +struct udev_device *udev_device_new_from_device_id(struct udev *udev, char *id); +struct udev_device *udev_device_new_from_environment(struct udev *udev); +/* udev_device_get_parent_*() does not take a reference on the returned device, it is automatically unref'd with the parent */ +struct udev_device *udev_device_get_parent(struct udev_device *udev_device); +struct udev_device *udev_device_get_parent_with_subsystem_devtype(struct udev_device *udev_device, + const char *subsystem, const char *devtype); +/* retrieve device properties */ +const char *udev_device_get_devpath(struct udev_device *udev_device); +const char *udev_device_get_subsystem(struct udev_device *udev_device); +const char *udev_device_get_devtype(struct udev_device *udev_device); +const char *udev_device_get_syspath(struct udev_device *udev_device); +const char *udev_device_get_sysname(struct udev_device *udev_device); +const char *udev_device_get_sysnum(struct udev_device *udev_device); +const char *udev_device_get_devnode(struct udev_device *udev_device); +int udev_device_get_is_initialized(struct udev_device *udev_device); +struct udev_list_entry *udev_device_get_devlinks_list_entry(struct udev_device *udev_device); +struct udev_list_entry *udev_device_get_properties_list_entry(struct udev_device *udev_device); +struct udev_list_entry *udev_device_get_tags_list_entry(struct udev_device *udev_device); +struct udev_list_entry *udev_device_get_sysattr_list_entry(struct udev_device *udev_device); +const char *udev_device_get_property_value(struct udev_device *udev_device, const char *key); +const char *udev_device_get_driver(struct udev_device *udev_device); +dev_t udev_device_get_devnum(struct udev_device *udev_device); +const char *udev_device_get_action(struct udev_device *udev_device); +unsigned long long int udev_device_get_seqnum(struct udev_device *udev_device); +unsigned long long int udev_device_get_usec_since_initialized(struct udev_device *udev_device); +const char *udev_device_get_sysattr_value(struct udev_device *udev_device, const char *sysattr); +int udev_device_has_tag(struct udev_device *udev_device, const char *tag); + +/* + * udev_monitor + * + * access to kernel uevents and udev events + */ +struct udev_monitor; +struct udev_monitor *udev_monitor_ref(struct udev_monitor *udev_monitor); +struct udev_monitor *udev_monitor_unref(struct udev_monitor *udev_monitor); +struct udev *udev_monitor_get_udev(struct udev_monitor *udev_monitor); +/* kernel and udev generated events over netlink */ +struct udev_monitor *udev_monitor_new_from_netlink(struct udev *udev, const char *name); +/* bind socket */ +int udev_monitor_enable_receiving(struct udev_monitor *udev_monitor); +int udev_monitor_set_receive_buffer_size(struct udev_monitor *udev_monitor, int size); +int udev_monitor_get_fd(struct udev_monitor *udev_monitor); +struct udev_device *udev_monitor_receive_device(struct udev_monitor *udev_monitor); +/* in-kernel socket filters to select messages that get delivered to a listener */ +int udev_monitor_filter_add_match_subsystem_devtype(struct udev_monitor *udev_monitor, + const char *subsystem, const char *devtype); +int udev_monitor_filter_add_match_tag(struct udev_monitor *udev_monitor, const char *tag); +int udev_monitor_filter_update(struct udev_monitor *udev_monitor); +int udev_monitor_filter_remove(struct udev_monitor *udev_monitor); + +/* + * udev_enumerate + * + * search sysfs for specific devices and provide a sorted list + */ +struct udev_enumerate; +struct udev_enumerate *udev_enumerate_ref(struct udev_enumerate *udev_enumerate); +struct udev_enumerate *udev_enumerate_unref(struct udev_enumerate *udev_enumerate); +struct udev *udev_enumerate_get_udev(struct udev_enumerate *udev_enumerate); +struct udev_enumerate *udev_enumerate_new(struct udev *udev); +/* device properties filter */ +int udev_enumerate_add_match_subsystem(struct udev_enumerate *udev_enumerate, const char *subsystem); +int udev_enumerate_add_nomatch_subsystem(struct udev_enumerate *udev_enumerate, const char *subsystem); +int udev_enumerate_add_match_sysattr(struct udev_enumerate *udev_enumerate, const char *sysattr, const char *value); +int udev_enumerate_add_nomatch_sysattr(struct udev_enumerate *udev_enumerate, const char *sysattr, const char *value); +int udev_enumerate_add_match_property(struct udev_enumerate *udev_enumerate, const char *property, const char *value); +int udev_enumerate_add_match_sysname(struct udev_enumerate *udev_enumerate, const char *sysname); +int udev_enumerate_add_match_tag(struct udev_enumerate *udev_enumerate, const char *tag); +int udev_enumerate_add_match_parent(struct udev_enumerate *udev_enumerate, struct udev_device *parent); +int udev_enumerate_add_match_is_initialized(struct udev_enumerate *udev_enumerate); +int udev_enumerate_add_syspath(struct udev_enumerate *udev_enumerate, const char *syspath); +/* run enumeration with active filters */ +int udev_enumerate_scan_devices(struct udev_enumerate *udev_enumerate); +int udev_enumerate_scan_subsystems(struct udev_enumerate *udev_enumerate); +/* return device list */ +struct udev_list_entry *udev_enumerate_get_list_entry(struct udev_enumerate *udev_enumerate); + +/* + * udev_queue + * + * access to the currently running udev events + */ +struct udev_queue; +struct udev_queue *udev_queue_ref(struct udev_queue *udev_queue); +struct udev_queue *udev_queue_unref(struct udev_queue *udev_queue); +struct udev *udev_queue_get_udev(struct udev_queue *udev_queue); +struct udev_queue *udev_queue_new(struct udev *udev); +unsigned long long int udev_queue_get_kernel_seqnum(struct udev_queue *udev_queue); +unsigned long long int udev_queue_get_udev_seqnum(struct udev_queue *udev_queue); +int udev_queue_get_udev_is_active(struct udev_queue *udev_queue); +int udev_queue_get_queue_is_empty(struct udev_queue *udev_queue); +int udev_queue_get_seqnum_is_finished(struct udev_queue *udev_queue, unsigned long long int seqnum); +int udev_queue_get_seqnum_sequence_is_finished(struct udev_queue *udev_queue, + unsigned long long int start, unsigned long long int end); +struct udev_list_entry *udev_queue_get_queued_list_entry(struct udev_queue *udev_queue); + +/* + * udev_hwdb + * + * access to the static hardware properties database + */ +struct udev_hwdb; +struct udev_hwdb *udev_hwdb_new(struct udev *udev); +struct udev_hwdb *udev_hwdb_ref(struct udev_hwdb *hwdb); +struct udev_hwdb *udev_hwdb_unref(struct udev_hwdb *hwdb); +struct udev_list_entry *udev_hwdb_get_properties_list_entry(struct udev_hwdb *hwdb, const char *modalias, unsigned int flags); + +/* + * udev_util + * + * udev specific utilities + */ +int udev_util_encode_string(const char *str, char *str_enc, size_t len); + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/src/libudev/libudev.pc.in b/src/libudev/libudev.pc.in new file mode 100644 index 000000000..dad7139c8 --- /dev/null +++ b/src/libudev/libudev.pc.in @@ -0,0 +1,18 @@ +# This file is part of systemd. +# +# 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. + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: libudev +Description: Library to access udev device information +Version: @VERSION@ +Libs: -L${libdir} -ludev -lrt +Libs.private: +Cflags: -I${includedir} diff --git a/src/libudev/libudev.sym b/src/libudev/libudev.sym new file mode 100644 index 000000000..df6a1aedd --- /dev/null +++ b/src/libudev/libudev.sym @@ -0,0 +1,110 @@ +/*** + This file is part of systemd. + + 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. +***/ + +LIBUDEV_183 { +global: + udev_device_get_action; + udev_device_get_devlinks_list_entry; + udev_device_get_devnode; + udev_device_get_devnum; + udev_device_get_devpath; + udev_device_get_devtype; + udev_device_get_driver; + udev_device_get_is_initialized; + udev_device_get_parent; + udev_device_get_parent_with_subsystem_devtype; + udev_device_get_properties_list_entry; + udev_device_get_property_value; + udev_device_get_seqnum; + udev_device_get_subsystem; + udev_device_get_sysattr_list_entry; + udev_device_get_sysattr_value; + udev_device_get_sysname; + udev_device_get_sysnum; + udev_device_get_syspath; + udev_device_get_tags_list_entry; + udev_device_get_udev; + udev_device_get_usec_since_initialized; + udev_device_has_tag; + udev_device_new_from_devnum; + udev_device_new_from_environment; + udev_device_new_from_subsystem_sysname; + udev_device_new_from_syspath; + udev_device_ref; + udev_device_unref; + udev_enumerate_add_match_is_initialized; + udev_enumerate_add_match_parent; + udev_enumerate_add_match_property; + udev_enumerate_add_match_subsystem; + udev_enumerate_add_match_sysattr; + udev_enumerate_add_match_sysname; + udev_enumerate_add_match_tag; + udev_enumerate_add_nomatch_subsystem; + udev_enumerate_add_nomatch_sysattr; + udev_enumerate_add_syspath; + udev_enumerate_get_list_entry; + udev_enumerate_get_udev; + udev_enumerate_new; + udev_enumerate_ref; + udev_enumerate_scan_devices; + udev_enumerate_scan_subsystems; + udev_enumerate_unref; + udev_get_log_priority; + udev_get_userdata; + udev_list_entry_get_by_name; + udev_list_entry_get_name; + udev_list_entry_get_next; + udev_list_entry_get_value; + udev_monitor_enable_receiving; + udev_monitor_filter_add_match_subsystem_devtype; + udev_monitor_filter_add_match_tag; + udev_monitor_filter_remove; + udev_monitor_filter_update; + udev_monitor_get_fd; + udev_monitor_get_udev; + udev_monitor_new_from_netlink; + udev_monitor_new_from_socket; + udev_monitor_receive_device; + udev_monitor_ref; + udev_monitor_set_receive_buffer_size; + udev_monitor_unref; + udev_new; + udev_queue_get_kernel_seqnum; + udev_queue_get_queue_is_empty; + udev_queue_get_queued_list_entry; + udev_queue_get_seqnum_is_finished; + udev_queue_get_seqnum_sequence_is_finished; + udev_queue_get_udev; + udev_queue_get_udev_is_active; + udev_queue_get_udev_seqnum; + udev_queue_new; + udev_queue_ref; + udev_queue_unref; + udev_ref; + udev_set_log_fn; + udev_set_log_priority; + udev_set_userdata; + udev_unref; + udev_util_encode_string; +local: + *; +}; + +LIBUDEV_189 { +global: + udev_device_new_from_device_id; +} LIBUDEV_183; + +LIBUDEV_196 { +global: + udev_hwdb_new; + udev_hwdb_ref; + udev_hwdb_unref; + udev_hwdb_get_properties_list_entry; +} LIBUDEV_189; diff --git a/src/locale/.gitignore b/src/locale/.gitignore new file mode 100644 index 000000000..b1e0ba755 --- /dev/null +++ b/src/locale/.gitignore @@ -0,0 +1 @@ +org.freedesktop.locale1.policy diff --git a/src/locale/Makefile b/src/locale/Makefile new file mode 120000 index 000000000..d0b0e8e00 --- /dev/null +++ b/src/locale/Makefile @@ -0,0 +1 @@ +../Makefile \ No newline at end of file diff --git a/src/locale/generate-kbd-model-map b/src/locale/generate-kbd-model-map new file mode 100755 index 000000000..b8ffa0f22 --- /dev/null +++ b/src/locale/generate-kbd-model-map @@ -0,0 +1,31 @@ +import sys +import system_config_keyboard.keyboard_models + +def strdash(s): + return s.strip() or '-' + +def tab_extend(s, n=1): + s = strdash(s) + k = len(s) // 8 + + if k >= n: + f = 1 + else: + f = n - k + + return s + '\t'*f + + +models = system_config_keyboard.keyboard_models.KeyboardModels().get_models() + +print "# Generated from system-config-keyboard's model list" +print "# consolelayout\t\txlayout\txmodel\t\txvariant\txoptions" + +for key, value in reversed(models.items()): + options = "terminate:ctrl_alt_bksp" + if value[4]: + options += ',' + value[4] + + print ''.join((tab_extend(key, 3), tab_extend(value[1]), + tab_extend(value[2], 2), tab_extend(value[3], 2), + options)) diff --git a/src/locale/kbd-model-map b/src/locale/kbd-model-map new file mode 100644 index 000000000..b0860abe8 --- /dev/null +++ b/src/locale/kbd-model-map @@ -0,0 +1,76 @@ +# Generated from system-config-keyboard's model list +# consolelayout xlayout xmodel xvariant xoptions +sg ch pc105 de_nodeadkeys terminate:ctrl_alt_bksp +nl nl pc105 - terminate:ctrl_alt_bksp +mk-utf mk,us pc105 - terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll +trq tr pc105 - terminate:ctrl_alt_bksp +guj in,us pc105 guj terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll +uk gb pc105 - terminate:ctrl_alt_bksp +is-latin1 is pc105 - terminate:ctrl_alt_bksp +de de pc105 - terminate:ctrl_alt_bksp +gur gur,us pc105 - terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll +la-latin1 latam pc105 - terminate:ctrl_alt_bksp +us us pc105+inet - terminate:ctrl_alt_bksp +ko kr pc105 - terminate:ctrl_alt_bksp +ro-std ro pc105 std terminate:ctrl_alt_bksp +de-latin1 de pc105 - terminate:ctrl_alt_bksp +tml-inscript in,us pc105 tam terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll +slovene si pc105 - terminate:ctrl_alt_bksp +hu101 hu pc105 qwerty terminate:ctrl_alt_bksp +jp106 jp jp106 - terminate:ctrl_alt_bksp +croat hr pc105 - terminate:ctrl_alt_bksp +ben-probhat in,us pc105 ben_probhat terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll +fi-latin1 fi pc105 - terminate:ctrl_alt_bksp +it2 it pc105 - terminate:ctrl_alt_bksp +hu hu pc105 - terminate:ctrl_alt_bksp +sr-latin rs pc105 latin terminate:ctrl_alt_bksp +fi fi pc105 - terminate:ctrl_alt_bksp +fr_CH ch pc105 fr terminate:ctrl_alt_bksp +dk-latin1 dk pc105 - terminate:ctrl_alt_bksp +fr fr pc105 - terminate:ctrl_alt_bksp +it it pc105 - terminate:ctrl_alt_bksp +tml-uni in,us pc105 tam_TAB terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll +ua-utf ua,us pc105 - terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll +fr-latin1 fr pc105 - terminate:ctrl_alt_bksp +sg-latin1 ch pc105 de_nodeadkeys terminate:ctrl_alt_bksp +be-latin1 be pc105 - terminate:ctrl_alt_bksp +dk dk pc105 - terminate:ctrl_alt_bksp +fr-pc fr pc105 - terminate:ctrl_alt_bksp +bg_pho-utf8 bg,us pc105 ,phonetic terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll +it-ibm it pc105 - terminate:ctrl_alt_bksp +cz-us-qwertz cz,us pc105 - terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll +ar-digits ara,us pc105 digits terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll +br-abnt2 br abnt2 - terminate:ctrl_alt_bksp +ro ro pc105 - terminate:ctrl_alt_bksp +us-acentos us pc105 intl terminate:ctrl_alt_bksp +pt-latin1 pt pc105 - terminate:ctrl_alt_bksp +ro-std-cedilla ro pc105 std_cedilla terminate:ctrl_alt_bksp +tj tj pc105 - terminate:ctrl_alt_bksp +ar-qwerty ara,us pc105 qwerty terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll +ar-azerty-digits ara,us pc105 azerty_digits terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll +ben in,us pc105 ben terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll +de-latin1-nodeadkeys de pc105 nodeadkeys terminate:ctrl_alt_bksp +no no pc105 - terminate:ctrl_alt_bksp +bg_bds-utf8 bg,us pc105 - terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll +dvorak us pc105 dvorak terminate:ctrl_alt_bksp +ru ru,us pc105 - terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll +cz-lat2 cz pc105 qwerty terminate:ctrl_alt_bksp +pl2 pl pc105 - terminate:ctrl_alt_bksp +es es pc105 - terminate:ctrl_alt_bksp +ro-cedilla ro pc105 cedilla terminate:ctrl_alt_bksp +ie ie pc105 - terminate:ctrl_alt_bksp +ar-azerty ara,us pc105 azerty terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll +ar-qwerty-digits ara,us pc105 qwerty_digits terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll +et ee pc105 - terminate:ctrl_alt_bksp +sk-qwerty sk pc105 - terminate:ctrl_alt_bksp,qwerty +dev dev,us pc105 - terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll +fr-latin9 fr pc105 latin9 terminate:ctrl_alt_bksp +fr_CH-latin1 ch pc105 fr terminate:ctrl_alt_bksp +cf ca pc105 - terminate:ctrl_alt_bksp +sv-latin1 se pc105 - terminate:ctrl_alt_bksp +sr-cy rs pc105 - terminate:ctrl_alt_bksp +gr gr,us pc105 - terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll +by by,us pc105 - terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll +il il pc105 - terminate:ctrl_alt_bksp +kazakh kz,us pc105 - terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll +lt lt pc105 - terminate:ctrl_alt_bksp diff --git a/src/locale/localectl.c b/src/locale/localectl.c new file mode 100644 index 000000000..5d35f9cda --- /dev/null +++ b/src/locale/localectl.c @@ -0,0 +1,780 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dbus-common.h" +#include "util.h" +#include "spawn-polkit-agent.h" +#include "build.h" +#include "strv.h" +#include "pager.h" +#include "set.h" +#include "path-util.h" + +static bool arg_no_pager = false; +static enum transport { + TRANSPORT_NORMAL, + TRANSPORT_SSH, + TRANSPORT_POLKIT +} arg_transport = TRANSPORT_NORMAL; +static bool arg_ask_password = true; +static const char *arg_host = NULL; +static bool arg_convert = true; + +static void pager_open_if_enabled(void) { + + if (arg_no_pager) + return; + + pager_open(); +} + +static void polkit_agent_open_if_enabled(void) { + + /* Open the polkit agent as a child process if necessary */ + + if (!arg_ask_password) + return; + + polkit_agent_open(); +} + +typedef struct StatusInfo { + char **locale; + const char *vconsole_keymap; + const char *vconsole_keymap_toggle; + const char *x11_layout; + const char *x11_model; + const char *x11_variant; + const char *x11_options; +} StatusInfo; + +static void print_status_info(StatusInfo *i) { + assert(i); + + if (strv_isempty(i->locale)) + puts(" System Locale: n/a\n"); + else { + char **j; + + printf(" System Locale: %s\n", i->locale[0]); + STRV_FOREACH(j, i->locale + 1) + printf(" %s\n", *j); + } + + printf(" VC Keymap: %s\n", strna(i->vconsole_keymap)); + if (!isempty(i->vconsole_keymap_toggle)) + printf("VC Toggle Keymap: %s\n", i->vconsole_keymap_toggle); + + printf(" X11 Layout: %s\n", strna(i->x11_layout)); + if (!isempty(i->x11_model)) + printf(" X11 Model: %s\n", i->x11_model); + if (!isempty(i->x11_variant)) + printf(" X11 Variant: %s\n", i->x11_variant); + if (!isempty(i->x11_options)) + printf(" X11 Options: %s\n", i->x11_options); +} + +static int status_property(const char *name, DBusMessageIter *iter, StatusInfo *i) { + int r; + + assert(name); + assert(iter); + + switch (dbus_message_iter_get_arg_type(iter)) { + + case DBUS_TYPE_STRING: { + const char *s; + + dbus_message_iter_get_basic(iter, &s); + if (!isempty(s)) { + if (streq(name, "VConsoleKeymap")) + i->vconsole_keymap = s; + else if (streq(name, "VConsoleKeymapToggle")) + i->vconsole_keymap_toggle = s; + else if (streq(name, "X11Layout")) + i->x11_layout = s; + else if (streq(name, "X11Model")) + i->x11_model = s; + else if (streq(name, "X11Variant")) + i->x11_variant = s; + else if (streq(name, "X11Options")) + i->x11_options = s; + } + break; + } + + case DBUS_TYPE_ARRAY: + + if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRING) { + char **l; + + r = bus_parse_strv_iter(iter, &l); + if (r < 0) + return r; + + if (streq(name, "Locale")) { + strv_free(i->locale); + i->locale = l; + l = NULL; + } + + strv_free(l); + } + } + + return 0; +} + +static int show_status(DBusConnection *bus, char **args, unsigned n) { + _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; + const char *interface = ""; + int r; + DBusMessageIter iter, sub, sub2, sub3; + StatusInfo info; + + assert(args); + + r = bus_method_call_with_reply( + bus, + "org.freedesktop.locale1", + "/org/freedesktop/locale1", + "org.freedesktop.DBus.Properties", + "GetAll", + &reply, + NULL, + DBUS_TYPE_STRING, &interface, + DBUS_TYPE_INVALID); + if (r < 0) + return r; + + if (!dbus_message_iter_init(reply, &iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY || + dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_DICT_ENTRY) { + log_error("Failed to parse reply."); + return -EIO; + } + + zero(info); + dbus_message_iter_recurse(&iter, &sub); + + while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { + const char *name; + + if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_DICT_ENTRY) { + log_error("Failed to parse reply."); + return -EIO; + } + + dbus_message_iter_recurse(&sub, &sub2); + + if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &name, true) < 0) { + log_error("Failed to parse reply."); + return -EIO; + } + + if (dbus_message_iter_get_arg_type(&sub2) != DBUS_TYPE_VARIANT) { + log_error("Failed to parse reply."); + return -EIO; + } + + dbus_message_iter_recurse(&sub2, &sub3); + + r = status_property(name, &sub3, &info); + if (r < 0) { + log_error("Failed to parse reply."); + return r; + } + + dbus_message_iter_next(&sub); + } + + print_status_info(&info); + strv_free(info.locale); + return 0; +} + +static int set_locale(DBusConnection *bus, char **args, unsigned n) { + _cleanup_dbus_message_unref_ DBusMessage *m = NULL, *reply = NULL; + dbus_bool_t interactive = true; + DBusError error; + DBusMessageIter iter; + int r; + + assert(bus); + assert(args); + + dbus_error_init(&error); + + polkit_agent_open_if_enabled(); + + m = dbus_message_new_method_call( + "org.freedesktop.locale1", + "/org/freedesktop/locale1", + "org.freedesktop.locale1", + "SetLocale"); + if (!m) + return log_oom(); + + dbus_message_iter_init_append(m, &iter); + + r = bus_append_strv_iter(&iter, args + 1); + if (r < 0) + return log_oom(); + + if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &interactive)) + return log_oom(); + + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error); + if (!reply) { + log_error("Failed to issue method call: %s", bus_error_message(&error)); + r = -EIO; + goto finish; + } + + r = 0; + +finish: + dbus_error_free(&error); + return r; +} + +static int list_locales(DBusConnection *bus, char **args, unsigned n) { + /* Stolen from glibc... */ + + struct locarhead { + uint32_t magic; + /* Serial number. */ + uint32_t serial; + /* Name hash table. */ + uint32_t namehash_offset; + uint32_t namehash_used; + uint32_t namehash_size; + /* String table. */ + uint32_t string_offset; + uint32_t string_used; + uint32_t string_size; + /* Table with locale records. */ + uint32_t locrectab_offset; + uint32_t locrectab_used; + uint32_t locrectab_size; + /* MD5 sum hash table. */ + uint32_t sumhash_offset; + uint32_t sumhash_used; + uint32_t sumhash_size; + }; + + struct namehashent { + /* Hash value of the name. */ + uint32_t hashval; + /* Offset of the name in the string table. */ + uint32_t name_offset; + /* Offset of the locale record. */ + uint32_t locrec_offset; + }; + + const struct locarhead *h; + const struct namehashent *e; + const void *p = MAP_FAILED; + _cleanup_close_ int fd = -1; + _cleanup_strv_free_ char **l = NULL; + char **j; + Set *locales; + size_t sz = 0; + struct stat st; + unsigned i; + int r; + + locales = set_new(string_hash_func, string_compare_func); + if (!locales) + return log_oom(); + + fd = open("/usr/lib/locale/locale-archive", O_RDONLY|O_NOCTTY|O_CLOEXEC); + if (fd < 0) { + log_error("Failed to open locale archive: %m"); + r = -errno; + goto finish; + } + + if (fstat(fd, &st) < 0) { + log_error("fstat() failed: %m"); + r = -errno; + goto finish; + } + + if (!S_ISREG(st.st_mode)) { + log_error("Archive file is not regular"); + r = -EBADMSG; + goto finish; + } + + if (st.st_size < (off_t) sizeof(struct locarhead)) { + log_error("Archive has invalid size"); + r = -EBADMSG; + goto finish; + } + + p = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0); + if (p == MAP_FAILED) { + log_error("Failed to map archive: %m"); + r = -errno; + goto finish; + } + + h = (const struct locarhead *) p; + if (h->magic != 0xde020109 || + h->namehash_offset + h->namehash_size > st.st_size || + h->string_offset + h->string_size > st.st_size || + h->locrectab_offset + h->locrectab_size > st.st_size || + h->sumhash_offset + h->sumhash_size > st.st_size) { + log_error("Invalid archive file."); + r = -EBADMSG; + goto finish; + } + + e = (const struct namehashent*) ((const uint8_t*) p + h->namehash_offset); + for (i = 0; i < h->namehash_size; i++) { + char *z; + + if (e[i].locrec_offset == 0) + continue; + + z = strdup((char*) p + e[i].name_offset); + if (!z) { + r = log_oom(); + goto finish; + } + + r = set_put(locales, z); + if (r < 0) { + free(z); + log_error("Failed to add locale: %s", strerror(-r)); + goto finish; + } + } + + l = set_get_strv(locales); + if (!l) { + r = log_oom(); + goto finish; + } + + set_free(locales); + locales = NULL; + + strv_sort(l); + + pager_open_if_enabled(); + + STRV_FOREACH(j, l) + puts(*j); + + r = 0; + +finish: + if (p != MAP_FAILED) + munmap((void*) p, sz); + + set_free_free(locales); + + return r; +} + +static int set_vconsole_keymap(DBusConnection *bus, char **args, unsigned n) { + _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; + dbus_bool_t interactive = true, b; + const char *map, *toggle_map; + + assert(bus); + assert(args); + + if (n > 3) { + log_error("Too many arguments."); + return -EINVAL; + } + + polkit_agent_open_if_enabled(); + + map = args[1]; + toggle_map = n > 2 ? args[2] : ""; + b = arg_convert; + + return bus_method_call_with_reply( + bus, + "org.freedesktop.locale1", + "/org/freedesktop/locale1", + "org.freedesktop.locale1", + "SetVConsoleKeyboard", + &reply, + NULL, + DBUS_TYPE_STRING, &map, + DBUS_TYPE_STRING, &toggle_map, + DBUS_TYPE_BOOLEAN, &b, + DBUS_TYPE_BOOLEAN, &interactive, + DBUS_TYPE_INVALID); +} + +static Set *keymaps = NULL; + +static int nftw_cb( + const char *fpath, + const struct stat *sb, + int tflag, + struct FTW *ftwbuf) { + + char *p, *e; + int r; + + if (tflag != FTW_F) + return 0; + + if (!endswith(fpath, ".map") && + !endswith(fpath, ".map.gz")) + return 0; + + p = strdup(path_get_file_name(fpath)); + if (!p) + return log_oom(); + + e = endswith(p, ".map"); + if (e) + *e = 0; + + e = endswith(p, ".map.gz"); + if (e) + *e = 0; + + r = set_put(keymaps, p); + if (r == -EEXIST) + free(p); + else if (r < 0) { + log_error("Can't add keymap: %s", strerror(-r)); + free(p); + return r; + } + + return 0; +} + +static int list_vconsole_keymaps(DBusConnection *bus, char **args, unsigned n) { + char _cleanup_strv_free_ **l = NULL; + char **i; + + keymaps = set_new(string_hash_func, string_compare_func); + if (!keymaps) + return log_oom(); + + nftw("/usr/share/kbd/keymaps/", nftw_cb, 20, FTW_MOUNT|FTW_PHYS); + nftw("/usr/lib/kbd/keymaps/", nftw_cb, 20, FTW_MOUNT|FTW_PHYS); + nftw("/lib/kbd/keymaps/", nftw_cb, 20, FTW_MOUNT|FTW_PHYS); + + l = set_get_strv(keymaps); + if (!l) { + set_free_free(keymaps); + return log_oom(); + } + + set_free(keymaps); + + if (strv_isempty(l)) { + log_error("Couldn't find any console keymaps."); + return -ENOENT; + } + + strv_sort(l); + + pager_open_if_enabled(); + + STRV_FOREACH(i, l) + puts(*i); + + + return 0; +} + +static int set_x11_keymap(DBusConnection *bus, char **args, unsigned n) { + _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; + dbus_bool_t interactive = true, b; + const char *layout, *model, *variant, *options; + + assert(bus); + assert(args); + + if (n > 5) { + log_error("Too many arguments."); + return -EINVAL; + } + + polkit_agent_open_if_enabled(); + + layout = args[1]; + model = n > 2 ? args[2] : ""; + variant = n > 3 ? args[3] : ""; + options = n > 4 ? args[4] : ""; + b = arg_convert; + + return bus_method_call_with_reply( + bus, + "org.freedesktop.locale1", + "/org/freedesktop/locale1", + "org.freedesktop.locale1", + "SetX11Keyboard", + &reply, + NULL, + DBUS_TYPE_STRING, &layout, + DBUS_TYPE_STRING, &model, + DBUS_TYPE_STRING, &variant, + DBUS_TYPE_STRING, &options, + DBUS_TYPE_BOOLEAN, &b, + DBUS_TYPE_BOOLEAN, &interactive, + DBUS_TYPE_INVALID); +} + +static int help(void) { + + printf("%s [OPTIONS...] COMMAND ...\n\n" + "Query or change system time and date settings.\n\n" + " -h --help Show this help\n" + " --version Show package version\n" + " --no-convert Don't convert keyboard mappings\n" + " --no-pager Do not pipe output into a pager\n" + " --no-ask-password Do not prompt for password\n" + " -H --host=[USER@]HOST Operate on remote host\n\n" + "Commands:\n" + " status Show current locale settings\n" + " set-locale LOCALE... Set system locale\n" + " list-locales Show known locales\n" + " set-keymap MAP [MAP] Set virtual console keyboard mapping\n" + " list-keymaps Show known virtual console keyboard mappings\n" + " set-x11-keymap LAYOUT [MODEL] [VARIANT] [OPTIONS]\n" + " Set X11 keyboard mapping\n", + program_invocation_short_name); + + return 0; +} + +static int parse_argv(int argc, char *argv[]) { + + enum { + ARG_VERSION = 0x100, + ARG_NO_PAGER, + ARG_NO_CONVERT, + ARG_NO_ASK_PASSWORD + }; + + static const struct option options[] = { + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, ARG_VERSION }, + { "no-pager", no_argument, NULL, ARG_NO_PAGER }, + { "host", required_argument, NULL, 'H' }, + { "privileged", no_argument, NULL, 'P' }, + { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD }, + { "no-convert", no_argument, NULL, ARG_NO_CONVERT }, + { NULL, 0, NULL, 0 } + }; + + int c; + + assert(argc >= 0); + assert(argv); + + while ((c = getopt_long(argc, argv, "has:H:P", options, NULL)) >= 0) { + + switch (c) { + + case 'h': + help(); + return 0; + + case ARG_VERSION: + puts(PACKAGE_STRING); + puts(SYSTEMD_FEATURES); + return 0; + + case 'P': + arg_transport = TRANSPORT_POLKIT; + break; + + case 'H': + arg_transport = TRANSPORT_SSH; + arg_host = optarg; + break; + + case ARG_NO_CONVERT: + arg_convert = false; + break; + + case ARG_NO_PAGER: + arg_no_pager = true; + break; + + case '?': + return -EINVAL; + + default: + log_error("Unknown option code %c", c); + return -EINVAL; + } + } + + return 1; +} + +static int localectl_main(DBusConnection *bus, int argc, char *argv[], DBusError *error) { + + static const struct { + const char* verb; + const enum { + MORE, + LESS, + EQUAL + } argc_cmp; + const int argc; + int (* const dispatch)(DBusConnection *bus, char **args, unsigned n); + } verbs[] = { + { "status", LESS, 1, show_status }, + { "set-locale", MORE, 2, set_locale }, + { "list-locales", EQUAL, 1, list_locales }, + { "set-keymap", MORE, 2, set_vconsole_keymap }, + { "list-keymaps", EQUAL, 1, list_vconsole_keymaps }, + { "set-x11-keymap", MORE, 2, set_x11_keymap }, + }; + + int left; + unsigned i; + + assert(argc >= 0); + assert(argv); + assert(error); + + left = argc - optind; + + if (left <= 0) + /* Special rule: no arguments means "status" */ + i = 0; + else { + if (streq(argv[optind], "help")) { + help(); + return 0; + } + + for (i = 0; i < ELEMENTSOF(verbs); i++) + if (streq(argv[optind], verbs[i].verb)) + break; + + if (i >= ELEMENTSOF(verbs)) { + log_error("Unknown operation %s", argv[optind]); + return -EINVAL; + } + } + + switch (verbs[i].argc_cmp) { + + case EQUAL: + if (left != verbs[i].argc) { + log_error("Invalid number of arguments."); + return -EINVAL; + } + + break; + + case MORE: + if (left < verbs[i].argc) { + log_error("Too few arguments."); + return -EINVAL; + } + + break; + + case LESS: + if (left > verbs[i].argc) { + log_error("Too many arguments."); + return -EINVAL; + } + + break; + + default: + assert_not_reached("Unknown comparison operator."); + } + + if (!bus) { + log_error("Failed to get D-Bus connection: %s", error->message); + return -EIO; + } + + return verbs[i].dispatch(bus, argv + optind, left); +} + +int main(int argc, char *argv[]) { + int r, retval = EXIT_FAILURE; + DBusConnection *bus = NULL; + DBusError error; + + dbus_error_init(&error); + + setlocale(LC_ALL, ""); + log_parse_environment(); + log_open(); + + r = parse_argv(argc, argv); + if (r < 0) + goto finish; + else if (r == 0) { + retval = EXIT_SUCCESS; + goto finish; + } + + if (arg_transport == TRANSPORT_NORMAL) + bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error); + else if (arg_transport == TRANSPORT_POLKIT) + bus_connect_system_polkit(&bus, &error); + else if (arg_transport == TRANSPORT_SSH) + bus_connect_system_ssh(NULL, arg_host, &bus, &error); + else + assert_not_reached("Uh, invalid transport..."); + + r = localectl_main(bus, argc, argv, &error); + retval = r < 0 ? EXIT_FAILURE : r; + +finish: + if (bus) { + dbus_connection_flush(bus); + dbus_connection_close(bus); + dbus_connection_unref(bus); + } + + dbus_error_free(&error); + dbus_shutdown(); + + pager_close(); + + return retval; +} diff --git a/src/locale/localed.c b/src/locale/localed.c new file mode 100644 index 000000000..bb2a3a2e5 --- /dev/null +++ b/src/locale/localed.c @@ -0,0 +1,1417 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +#include + +#include +#include +#include + +#include "util.h" +#include "mkdir.h" +#include "strv.h" +#include "dbus-common.h" +#include "polkit.h" +#include "def.h" + +#define INTERFACE \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" + +#define INTROSPECTION \ + DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \ + "\n" \ + INTERFACE \ + BUS_PROPERTIES_INTERFACE \ + BUS_INTROSPECTABLE_INTERFACE \ + BUS_PEER_INTERFACE \ + "\n" + +#define INTERFACES_LIST \ + BUS_GENERIC_INTERFACES_LIST \ + "org.freedesktop.locale1\0" + +const char locale_interface[] _introspect_("locale1") = INTERFACE; + +enum { + /* We don't list LC_ALL here on purpose. People should be + * using LANG instead. */ + + PROP_LANG, + PROP_LANGUAGE, + PROP_LC_CTYPE, + PROP_LC_NUMERIC, + PROP_LC_TIME, + PROP_LC_COLLATE, + PROP_LC_MONETARY, + PROP_LC_MESSAGES, + PROP_LC_PAPER, + PROP_LC_NAME, + PROP_LC_ADDRESS, + PROP_LC_TELEPHONE, + PROP_LC_MEASUREMENT, + PROP_LC_IDENTIFICATION, + _PROP_MAX +}; + +static const char * const names[_PROP_MAX] = { + [PROP_LANG] = "LANG", + [PROP_LANGUAGE] = "LANGUAGE", + [PROP_LC_CTYPE] = "LC_CTYPE", + [PROP_LC_NUMERIC] = "LC_NUMERIC", + [PROP_LC_TIME] = "LC_TIME", + [PROP_LC_COLLATE] = "LC_COLLATE", + [PROP_LC_MONETARY] = "LC_MONETARY", + [PROP_LC_MESSAGES] = "LC_MESSAGES", + [PROP_LC_PAPER] = "LC_PAPER", + [PROP_LC_NAME] = "LC_NAME", + [PROP_LC_ADDRESS] = "LC_ADDRESS", + [PROP_LC_TELEPHONE] = "LC_TELEPHONE", + [PROP_LC_MEASUREMENT] = "LC_MEASUREMENT", + [PROP_LC_IDENTIFICATION] = "LC_IDENTIFICATION" +}; + +static char *data[_PROP_MAX] = { + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL +}; + +typedef struct State { + char *x11_layout, *x11_model, *x11_variant, *x11_options; + char *vc_keymap, *vc_keymap_toggle; +} State; + +static State state; + +static usec_t remain_until = 0; + +static int free_and_set(char **s, const char *v) { + int r; + char *t; + + assert(s); + + r = strdup_or_null(isempty(v) ? NULL : v, &t); + if (r < 0) + return r; + + free(*s); + *s = t; + + return 0; +} + +static void free_data_locale(void) { + int p; + + for (p = 0; p < _PROP_MAX; p++) { + free(data[p]); + data[p] = NULL; + } +} + +static void free_data_x11(void) { + free(state.x11_layout); + free(state.x11_model); + free(state.x11_variant); + free(state.x11_options); + + state.x11_layout = state.x11_model = state.x11_variant = state.x11_options = NULL; +} + +static void free_data_vconsole(void) { + free(state.vc_keymap); + free(state.vc_keymap_toggle); + + state.vc_keymap = state.vc_keymap_toggle = NULL; +} + +static void simplify(void) { + int p; + + for (p = 1; p < _PROP_MAX; p++) + if (isempty(data[p]) || streq_ptr(data[PROP_LANG], data[p])) { + free(data[p]); + data[p] = NULL; + } +} + +static int read_data_locale(void) { + int r; + + free_data_locale(); + + r = parse_env_file("/etc/locale.conf", NEWLINE, + "LANG", &data[PROP_LANG], + "LANGUAGE", &data[PROP_LANGUAGE], + "LC_CTYPE", &data[PROP_LC_CTYPE], + "LC_NUMERIC", &data[PROP_LC_NUMERIC], + "LC_TIME", &data[PROP_LC_TIME], + "LC_COLLATE", &data[PROP_LC_COLLATE], + "LC_MONETARY", &data[PROP_LC_MONETARY], + "LC_MESSAGES", &data[PROP_LC_MESSAGES], + "LC_PAPER", &data[PROP_LC_PAPER], + "LC_NAME", &data[PROP_LC_NAME], + "LC_ADDRESS", &data[PROP_LC_ADDRESS], + "LC_TELEPHONE", &data[PROP_LC_TELEPHONE], + "LC_MEASUREMENT", &data[PROP_LC_MEASUREMENT], + "LC_IDENTIFICATION", &data[PROP_LC_IDENTIFICATION], + NULL); + + if (r == -ENOENT) { + int p; + + /* Fill in what we got passed from systemd. */ + + for (p = 0; p < _PROP_MAX; p++) { + char *e, *d; + + assert(names[p]); + + e = getenv(names[p]); + if (e) { + d = strdup(e); + if (!d) + return -ENOMEM; + } else + d = NULL; + + free(data[p]); + data[p] = d; + } + + r = 0; + } + + simplify(); + return r; +} + +static void free_data(void) { + free_data_locale(); + free_data_vconsole(); + free_data_x11(); +} + +static int read_data_vconsole(void) { + int r; + + free_data_vconsole(); + + r = parse_env_file("/etc/vconsole.conf", NEWLINE, + "KEYMAP", &state.vc_keymap, + "KEYMAP_TOGGLE", &state.vc_keymap_toggle, + NULL); + + if (r < 0 && r != -ENOENT) + return r; + + return 0; +} + +static int read_data_x11(void) { + FILE *f; + char line[LINE_MAX]; + bool in_section = false; + + free_data_x11(); + + f = fopen("/etc/X11/xorg.conf.d/00-keyboard.conf", "re"); + if (!f) + return errno == ENOENT ? 0 : -errno; + + while (fgets(line, sizeof(line), f)) { + char *l; + + char_array_0(line); + l = strstrip(line); + + if (l[0] == 0 || l[0] == '#') + continue; + + if (in_section && first_word(l, "Option")) { + char **a; + + a = strv_split_quoted(l); + if (!a) { + fclose(f); + return -ENOMEM; + } + + if (strv_length(a) == 3) { + + if (streq(a[1], "XkbLayout")) { + free(state.x11_layout); + state.x11_layout = a[2]; + a[2] = NULL; + } else if (streq(a[1], "XkbModel")) { + free(state.x11_model); + state.x11_model = a[2]; + a[2] = NULL; + } else if (streq(a[1], "XkbVariant")) { + free(state.x11_variant); + state.x11_variant = a[2]; + a[2] = NULL; + } else if (streq(a[1], "XkbOptions")) { + free(state.x11_options); + state.x11_options = a[2]; + a[2] = NULL; + } + } + + strv_free(a); + + } else if (!in_section && first_word(l, "Section")) { + char **a; + + a = strv_split_quoted(l); + if (!a) { + fclose(f); + return -ENOMEM; + } + + if (strv_length(a) == 2 && streq(a[1], "InputClass")) + in_section = true; + + strv_free(a); + } else if (in_section && first_word(l, "EndSection")) + in_section = false; + } + + fclose(f); + + return 0; +} + +static int read_data(void) { + int r, q, p; + + r = read_data_locale(); + q = read_data_vconsole(); + p = read_data_x11(); + + return r < 0 ? r : q < 0 ? q : p; +} + +static int write_data_locale(void) { + int r, p; + char **l = NULL; + + r = load_env_file("/etc/locale.conf", &l); + if (r < 0 && r != -ENOENT) + return r; + + for (p = 0; p < _PROP_MAX; p++) { + char *t, **u; + + assert(names[p]); + + if (isempty(data[p])) { + l = strv_env_unset(l, names[p]); + continue; + } + + if (asprintf(&t, "%s=%s", names[p], data[p]) < 0) { + strv_free(l); + return -ENOMEM; + } + + u = strv_env_set(l, t); + free(t); + strv_free(l); + + if (!u) + return -ENOMEM; + + l = u; + } + + if (strv_isempty(l)) { + strv_free(l); + + if (unlink("/etc/locale.conf") < 0) + return errno == ENOENT ? 0 : -errno; + + return 0; + } + + r = write_env_file("/etc/locale.conf", l); + strv_free(l); + + return r; +} + +static void push_data(DBusConnection *bus) { + char **l_set = NULL, **l_unset = NULL, **t; + int c_set = 0, c_unset = 0, p; + DBusError error; + DBusMessage *m = NULL, *reply = NULL; + DBusMessageIter iter, sub; + + dbus_error_init(&error); + + assert(bus); + + l_set = new0(char*, _PROP_MAX); + l_unset = new0(char*, _PROP_MAX); + if (!l_set || !l_unset) { + log_oom(); + goto finish; + } + + for (p = 0; p < _PROP_MAX; p++) { + assert(names[p]); + + if (isempty(data[p])) + l_unset[c_set++] = (char*) names[p]; + else { + char *s; + + if (asprintf(&s, "%s=%s", names[p], data[p]) < 0) { + log_oom(); + goto finish; + } + + l_set[c_unset++] = s; + } + } + + assert(c_set + c_unset == _PROP_MAX); + m = dbus_message_new_method_call("org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "UnsetAndSetEnvironment"); + if (!m) { + log_error("Could not allocate message."); + goto finish; + } + + dbus_message_iter_init_append(m, &iter); + + if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "s", &sub)) { + log_oom(); + goto finish; + } + + STRV_FOREACH(t, l_unset) + if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, t)) { + log_oom(); + goto finish; + } + + if (!dbus_message_iter_close_container(&iter, &sub) || + !dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "s", &sub)) { + log_oom(); + goto finish; + } + + STRV_FOREACH(t, l_set) + if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, t)) { + log_oom(); + goto finish; + } + + if (!dbus_message_iter_close_container(&iter, &sub)) { + log_oom(); + goto finish; + } + + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error); + if (!reply) { + log_error("Failed to set locale information: %s", bus_error_message(&error)); + goto finish; + } + +finish: + if (m) + dbus_message_unref(m); + + if (reply) + dbus_message_unref(reply); + + dbus_error_free(&error); + + strv_free(l_set); + free(l_unset); +} + +static int write_data_vconsole(void) { + int r; + char **l = NULL; + + r = load_env_file("/etc/vconsole.conf", &l); + if (r < 0 && r != -ENOENT) + return r; + + if (isempty(state.vc_keymap)) + l = strv_env_unset(l, "KEYMAP"); + else { + char *s, **u; + + s = strappend("KEYMAP=", state.vc_keymap); + if (!s) { + strv_free(l); + return -ENOMEM; + } + + u = strv_env_set(l, s); + free(s); + strv_free(l); + + if (!u) + return -ENOMEM; + + l = u; + } + + if (isempty(state.vc_keymap_toggle)) + l = strv_env_unset(l, "KEYMAP_TOGGLE"); + else { + char *s, **u; + + s = strappend("KEYMAP_TOGGLE=", state.vc_keymap_toggle); + if (!s) { + strv_free(l); + return -ENOMEM; + } + + u = strv_env_set(l, s); + free(s); + strv_free(l); + + if (!u) + return -ENOMEM; + + l = u; + } + + if (strv_isempty(l)) { + strv_free(l); + + if (unlink("/etc/vconsole.conf") < 0) + return errno == ENOENT ? 0 : -errno; + + return 0; + } + + r = write_env_file("/etc/vconsole.conf", l); + strv_free(l); + + return r; +} + +static int write_data_x11(void) { + FILE *f; + char *temp_path; + int r; + + if (isempty(state.x11_layout) && + isempty(state.x11_model) && + isempty(state.x11_variant) && + isempty(state.x11_options)) { + + if (unlink("/etc/X11/xorg.conf.d/00-keyboard.conf") < 0) + return errno == ENOENT ? 0 : -errno; + + return 0; + } + + mkdir_p_label("/etc/X11/xorg.conf.d", 0755); + + r = fopen_temporary("/etc/X11/xorg.conf.d/00-keyboard.conf", &f, &temp_path); + if (r < 0) + return r; + + fchmod(fileno(f), 0644); + + fputs("# Read and parsed by systemd-localed. It's probably wise not to edit this file\n" + "# manually too freely.\n" + "Section \"InputClass\"\n" + " Identifier \"system-keyboard\"\n" + " MatchIsKeyboard \"on\"\n", f); + + if (!isempty(state.x11_layout)) + fprintf(f, " Option \"XkbLayout\" \"%s\"\n", state.x11_layout); + + if (!isempty(state.x11_model)) + fprintf(f, " Option \"XkbModel\" \"%s\"\n", state.x11_model); + + if (!isempty(state.x11_variant)) + fprintf(f, " Option \"XkbVariant\" \"%s\"\n", state.x11_variant); + + if (!isempty(state.x11_options)) + fprintf(f, " Option \"XkbOptions\" \"%s\"\n", state.x11_options); + + fputs("EndSection\n", f); + fflush(f); + + if (ferror(f) || rename(temp_path, "/etc/X11/xorg.conf.d/00-keyboard.conf") < 0) { + r = -errno; + unlink("/etc/X11/xorg.conf.d/00-keyboard.conf"); + unlink(temp_path); + } else + r = 0; + + fclose(f); + free(temp_path); + + return r; +} + +static int load_vconsole_keymap(DBusConnection *bus, DBusError *error) { + DBusMessage *m = NULL, *reply = NULL; + const char *name = "systemd-vconsole-setup.service", *mode = "replace"; + int r; + DBusError _error; + + assert(bus); + + if (!error) { + dbus_error_init(&_error); + error = &_error; + } + + m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "RestartUnit"); + if (!m) { + log_error("Could not allocate message."); + r = -ENOMEM; + goto finish; + } + + if (!dbus_message_append_args(m, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_STRING, &mode, + DBUS_TYPE_INVALID)) { + log_error("Could not append arguments to message."); + r = -ENOMEM; + goto finish; + } + + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, error); + if (!reply) { + log_error("Failed to issue method call: %s", bus_error_message(error)); + r = -EIO; + goto finish; + } + + r = 0; + +finish: + if (m) + dbus_message_unref(m); + + if (reply) + dbus_message_unref(reply); + + if (error == &_error) + dbus_error_free(error); + + return r; +} + +static char *strnulldash(const char *s) { + return s == NULL || *s == 0 || (s[0] == '-' && s[1] == 0) ? NULL : (char*) s; +} + +static int read_next_mapping(FILE *f, unsigned *n, char ***a) { + assert(f); + assert(n); + assert(a); + + for (;;) { + char line[LINE_MAX]; + char *l, **b; + + errno = 0; + if (!fgets(line, sizeof(line), f)) { + + if (ferror(f)) + return errno ? -errno : -EIO; + + return 0; + } + + (*n) ++; + + l = strstrip(line); + if (l[0] == 0 || l[0] == '#') + continue; + + b = strv_split_quoted(l); + if (!b) + return -ENOMEM; + + if (strv_length(b) < 5) { + log_error("Invalid line "SYSTEMD_KBD_MODEL_MAP":%u, ignoring.", *n); + strv_free(b); + continue; + + } + + *a = b; + return 1; + } +} + +static int convert_vconsole_to_x11(DBusConnection *connection) { + bool modified = false; + + assert(connection); + + if (isempty(state.vc_keymap)) { + + modified = + !isempty(state.x11_layout) || + !isempty(state.x11_model) || + !isempty(state.x11_variant) || + !isempty(state.x11_options); + + free_data_x11(); + } else { + FILE *f; + unsigned n = 0; + + f = fopen(SYSTEMD_KBD_MODEL_MAP, "re"); + if (!f) + return -errno; + + for (;;) { + char **a; + int r; + + r = read_next_mapping(f, &n, &a); + if (r < 0) { + fclose(f); + return r; + } + + if (r == 0) + break; + + if (!streq(state.vc_keymap, a[0])) { + strv_free(a); + continue; + } + + if (!streq_ptr(state.x11_layout, strnulldash(a[1])) || + !streq_ptr(state.x11_model, strnulldash(a[2])) || + !streq_ptr(state.x11_variant, strnulldash(a[3])) || + !streq_ptr(state.x11_options, strnulldash(a[4]))) { + + if (free_and_set(&state.x11_layout, strnulldash(a[1])) < 0 || + free_and_set(&state.x11_model, strnulldash(a[2])) < 0 || + free_and_set(&state.x11_variant, strnulldash(a[3])) < 0 || + free_and_set(&state.x11_options, strnulldash(a[4])) < 0) { + strv_free(a); + fclose(f); + return -ENOMEM; + } + + modified = true; + } + + strv_free(a); + break; + } + + fclose(f); + } + + if (modified) { + dbus_bool_t b; + DBusMessage *changed; + int r; + + r = write_data_x11(); + if (r < 0) + log_error("Failed to set X11 keyboard layout: %s", strerror(-r)); + + changed = bus_properties_changed_new( + "/org/freedesktop/locale1", + "org.freedesktop.locale1", + "X11Layout\0" + "X11Model\0" + "X11Variant\0" + "X11Options\0"); + + if (!changed) + return -ENOMEM; + + b = dbus_connection_send(connection, changed, NULL); + dbus_message_unref(changed); + + if (!b) + return -ENOMEM; + } + + return 0; +} + +static int convert_x11_to_vconsole(DBusConnection *connection) { + bool modified = false; + + assert(connection); + + if (isempty(state.x11_layout)) { + + modified = + !isempty(state.vc_keymap) || + !isempty(state.vc_keymap_toggle); + + free_data_x11(); + } else { + FILE *f; + unsigned n = 0; + unsigned best_matching = 0; + char *new_keymap = NULL; + + f = fopen(SYSTEMD_KBD_MODEL_MAP, "re"); + if (!f) + return -errno; + + for (;;) { + char **a; + unsigned matching = 0; + int r; + + r = read_next_mapping(f, &n, &a); + if (r < 0) { + fclose(f); + return r; + } + + if (r == 0) + break; + + /* Determine how well matching this entry is */ + if (streq_ptr(state.x11_layout, a[1])) + /* If we got an exact match, this is best */ + matching = 10; + else { + size_t x; + + x = strcspn(state.x11_layout, ","); + + /* We have multiple X layouts, look + * for an entry that matches our key + * with the everything but the first + * layout stripped off. */ + if (x > 0 && + strlen(a[1]) == x && + strncmp(state.x11_layout, a[1], x) == 0) + matching = 5; + else { + size_t w; + + /* If that didn't work, strip + * off the other layouts from + * the entry, too */ + + w = strcspn(a[1], ","); + + if (x > 0 && x == w && + memcmp(state.x11_layout, a[1], x) == 0) + matching = 1; + } + } + + if (matching > 0 && + streq_ptr(state.x11_model, a[2])) { + matching++; + + if (streq_ptr(state.x11_variant, a[3])) { + matching++; + + if (streq_ptr(state.x11_options, a[4])) + matching++; + } + } + + /* The best matching entry so far, then let's + * save that */ + if (matching > best_matching) { + best_matching = matching; + + free(new_keymap); + new_keymap = strdup(a[0]); + + if (!new_keymap) { + strv_free(a); + fclose(f); + return -ENOMEM; + } + } + + strv_free(a); + } + + fclose(f); + + if (!streq_ptr(state.vc_keymap, new_keymap)) { + free(state.vc_keymap); + state.vc_keymap = new_keymap; + + free(state.vc_keymap_toggle); + state.vc_keymap_toggle = NULL; + + modified = true; + } else + free(new_keymap); + } + + if (modified) { + dbus_bool_t b; + DBusMessage *changed; + int r; + + r = write_data_vconsole(); + if (r < 0) + log_error("Failed to set virtual console keymap: %s", strerror(-r)); + + changed = bus_properties_changed_new( + "/org/freedesktop/locale1", + "org.freedesktop.locale1", + "VConsoleKeymap\0" + "VConsoleKeymapToggle\0"); + + if (!changed) + return -ENOMEM; + + b = dbus_connection_send(connection, changed, NULL); + dbus_message_unref(changed); + + if (!b) + return -ENOMEM; + + return load_vconsole_keymap(connection, NULL); + } + + return 0; +} + +static int append_locale(DBusMessageIter *i, const char *property, void *userdata) { + int r, c = 0, p; + char **l; + + l = new0(char*, _PROP_MAX+1); + if (!l) + return -ENOMEM; + + for (p = 0; p < _PROP_MAX; p++) { + char *t; + + if (isempty(data[p])) + continue; + + if (asprintf(&t, "%s=%s", names[p], data[p]) < 0) { + strv_free(l); + return -ENOMEM; + } + + l[c++] = t; + } + + r = bus_property_append_strv(i, property, (void*) l); + strv_free(l); + + return r; +} + +static const BusProperty bus_locale_properties[] = { + { "Locale", append_locale, "as", 0 }, + { "X11Layout", bus_property_append_string, "s", offsetof(State, x11_layout), true }, + { "X11Model", bus_property_append_string, "s", offsetof(State, x11_model), true }, + { "X11Variant", bus_property_append_string, "s", offsetof(State, x11_variant), true }, + { "X11Options", bus_property_append_string, "s", offsetof(State, x11_options), true }, + { "VConsoleKeymap", bus_property_append_string, "s", offsetof(State, vc_keymap), true }, + { "VConsoleKeymapToggle", bus_property_append_string, "s", offsetof(State, vc_keymap_toggle), true }, + { NULL, } +}; + +static const BusBoundProperties bps[] = { + { "org.freedesktop.locale1", bus_locale_properties, &state }, + { NULL, } +}; + +static DBusHandlerResult locale_message_handler( + DBusConnection *connection, + DBusMessage *message, + void *userdata) { + + DBusMessage *reply = NULL, *changed = NULL; + DBusError error; + int r; + + assert(connection); + assert(message); + + dbus_error_init(&error); + + if (dbus_message_is_method_call(message, "org.freedesktop.locale1", "SetLocale")) { + char **l = NULL, **i; + dbus_bool_t interactive; + DBusMessageIter iter; + bool modified = false; + bool passed[_PROP_MAX]; + int p; + + if (!dbus_message_iter_init(message, &iter)) + return bus_send_error_reply(connection, message, NULL, -EINVAL); + + r = bus_parse_strv_iter(&iter, &l); + if (r < 0) { + if (r == -ENOMEM) + goto oom; + + return bus_send_error_reply(connection, message, NULL, r); + } + + if (!dbus_message_iter_next(&iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_BOOLEAN) { + strv_free(l); + return bus_send_error_reply(connection, message, NULL, -EINVAL); + } + + dbus_message_iter_get_basic(&iter, &interactive); + + zero(passed); + + /* Check whether a variable changed and if so valid */ + STRV_FOREACH(i, l) { + bool valid = false; + + for (p = 0; p < _PROP_MAX; p++) { + size_t k; + + k = strlen(names[p]); + if (startswith(*i, names[p]) && + (*i)[k] == '=' && + string_is_safe((*i) + k + 1)) { + valid = true; + passed[p] = true; + + if (!streq_ptr(*i + k + 1, data[p])) + modified = true; + + break; + } + } + + if (!valid) { + strv_free(l); + return bus_send_error_reply(connection, message, NULL, -EINVAL); + } + } + + /* Check whether a variable is unset */ + if (!modified) { + for (p = 0; p < _PROP_MAX; p++) + if (!isempty(data[p]) && !passed[p]) { + modified = true; + break; + } + } + + if (modified) { + + r = verify_polkit(connection, message, "org.freedesktop.locale1.set-locale", interactive, NULL, &error); + if (r < 0) { + strv_free(l); + return bus_send_error_reply(connection, message, &error, r); + } + + STRV_FOREACH(i, l) { + for (p = 0; p < _PROP_MAX; p++) { + size_t k; + + k = strlen(names[p]); + if (startswith(*i, names[p]) && (*i)[k] == '=') { + char *t; + + t = strdup(*i + k + 1); + if (!t) { + strv_free(l); + goto oom; + } + + free(data[p]); + data[p] = t; + + break; + } + } + } + + strv_free(l); + + for (p = 0; p < _PROP_MAX; p++) { + if (passed[p]) + continue; + + free(data[p]); + data[p] = NULL; + } + + simplify(); + + r = write_data_locale(); + if (r < 0) { + log_error("Failed to set locale: %s", strerror(-r)); + return bus_send_error_reply(connection, message, NULL, r); + } + + push_data(connection); + + log_info("Changed locale information."); + + changed = bus_properties_changed_new( + "/org/freedesktop/locale1", + "org.freedesktop.locale1", + "Locale\0"); + if (!changed) + goto oom; + } else + strv_free(l); + + } else if (dbus_message_is_method_call(message, "org.freedesktop.locale1", "SetVConsoleKeyboard")) { + + const char *keymap, *keymap_toggle; + dbus_bool_t convert, interactive; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &keymap, + DBUS_TYPE_STRING, &keymap_toggle, + DBUS_TYPE_BOOLEAN, &convert, + DBUS_TYPE_BOOLEAN, &interactive, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + if (isempty(keymap)) + keymap = NULL; + + if (isempty(keymap_toggle)) + keymap_toggle = NULL; + + if (!streq_ptr(keymap, state.vc_keymap) || + !streq_ptr(keymap_toggle, state.vc_keymap_toggle)) { + + if ((keymap && (!filename_is_safe(keymap) || !string_is_safe(keymap))) || + (keymap_toggle && (!filename_is_safe(keymap_toggle) || !string_is_safe(keymap_toggle)))) + return bus_send_error_reply(connection, message, NULL, -EINVAL); + + r = verify_polkit(connection, message, "org.freedesktop.locale1.set-keyboard", interactive, NULL, &error); + if (r < 0) + return bus_send_error_reply(connection, message, &error, r); + + if (free_and_set(&state.vc_keymap, keymap) < 0 || + free_and_set(&state.vc_keymap_toggle, keymap_toggle) < 0) + goto oom; + + r = write_data_vconsole(); + if (r < 0) { + log_error("Failed to set virtual console keymap: %s", strerror(-r)); + return bus_send_error_reply(connection, message, NULL, r); + } + + log_info("Changed virtual console keymap to '%s'", strempty(state.vc_keymap)); + + r = load_vconsole_keymap(connection, NULL); + if (r < 0) + log_error("Failed to request keymap reload: %s", strerror(-r)); + + changed = bus_properties_changed_new( + "/org/freedesktop/locale1", + "org.freedesktop.locale1", + "VConsoleKeymap\0" + "VConsoleKeymapToggle\0"); + if (!changed) + goto oom; + + if (convert) { + r = convert_vconsole_to_x11(connection); + + if (r < 0) + log_error("Failed to convert keymap data: %s", strerror(-r)); + } + } + + } else if (dbus_message_is_method_call(message, "org.freedesktop.locale1", "SetX11Keyboard")) { + + const char *layout, *model, *variant, *options; + dbus_bool_t convert, interactive; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &layout, + DBUS_TYPE_STRING, &model, + DBUS_TYPE_STRING, &variant, + DBUS_TYPE_STRING, &options, + DBUS_TYPE_BOOLEAN, &convert, + DBUS_TYPE_BOOLEAN, &interactive, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + if (isempty(layout)) + layout = NULL; + + if (isempty(model)) + model = NULL; + + if (isempty(variant)) + variant = NULL; + + if (isempty(options)) + options = NULL; + + if (!streq_ptr(layout, state.x11_layout) || + !streq_ptr(model, state.x11_model) || + !streq_ptr(variant, state.x11_variant) || + !streq_ptr(options, state.x11_options)) { + + if ((layout && !string_is_safe(layout)) || + (model && !string_is_safe(model)) || + (variant && !string_is_safe(variant)) || + (options && !string_is_safe(options))) + return bus_send_error_reply(connection, message, NULL, -EINVAL); + + r = verify_polkit(connection, message, "org.freedesktop.locale1.set-keyboard", interactive, NULL, &error); + if (r < 0) + return bus_send_error_reply(connection, message, &error, r); + + if (free_and_set(&state.x11_layout, layout) < 0 || + free_and_set(&state.x11_model, model) < 0 || + free_and_set(&state.x11_variant, variant) < 0 || + free_and_set(&state.x11_options, options) < 0) + goto oom; + + r = write_data_x11(); + if (r < 0) { + log_error("Failed to set X11 keyboard layout: %s", strerror(-r)); + return bus_send_error_reply(connection, message, NULL, r); + } + + log_info("Changed X11 keyboard layout to '%s'", strempty(state.x11_layout)); + + changed = bus_properties_changed_new( + "/org/freedesktop/locale1", + "org.freedesktop.locale1", + "X11Layout\0" + "X11Model\0" + "X11Variant\0" + "X11Options\0"); + if (!changed) + goto oom; + + if (convert) { + r = convert_x11_to_vconsole(connection); + + if (r < 0) + log_error("Failed to convert keymap data: %s", strerror(-r)); + } + } + } else + return bus_default_message_handler(connection, message, INTROSPECTION, INTERFACES_LIST, bps); + + if (!(reply = dbus_message_new_method_return(message))) + goto oom; + + if (!dbus_connection_send(connection, reply, NULL)) + goto oom; + + dbus_message_unref(reply); + reply = NULL; + + if (changed) { + + if (!dbus_connection_send(connection, changed, NULL)) + goto oom; + + dbus_message_unref(changed); + } + + return DBUS_HANDLER_RESULT_HANDLED; + +oom: + if (reply) + dbus_message_unref(reply); + + if (changed) + dbus_message_unref(changed); + + dbus_error_free(&error); + + return DBUS_HANDLER_RESULT_NEED_MEMORY; +} + +static int connect_bus(DBusConnection **_bus) { + static const DBusObjectPathVTable locale_vtable = { + .message_function = locale_message_handler + }; + DBusError error; + DBusConnection *bus = NULL; + int r; + + assert(_bus); + + dbus_error_init(&error); + + bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error); + if (!bus) { + log_error("Failed to get system D-Bus connection: %s", bus_error_message(&error)); + r = -ECONNREFUSED; + goto fail; + } + + dbus_connection_set_exit_on_disconnect(bus, FALSE); + + if (!dbus_connection_register_object_path(bus, "/org/freedesktop/locale1", &locale_vtable, NULL) || + !dbus_connection_add_filter(bus, bus_exit_idle_filter, &remain_until, NULL)) { + r = log_oom(); + goto fail; + } + + r = dbus_bus_request_name(bus, "org.freedesktop.locale1", DBUS_NAME_FLAG_DO_NOT_QUEUE, &error); + if (dbus_error_is_set(&error)) { + log_error("Failed to register name on bus: %s", bus_error_message(&error)); + r = -EEXIST; + goto fail; + } + + if (r != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) { + log_error("Failed to acquire name."); + r = -EEXIST; + goto fail; + } + + if (_bus) + *_bus = bus; + + return 0; + +fail: + dbus_connection_close(bus); + dbus_connection_unref(bus); + + dbus_error_free(&error); + + return r; +} + +int main(int argc, char *argv[]) { + int r; + DBusConnection *bus = NULL; + bool exiting = false; + + log_set_target(LOG_TARGET_AUTO); + log_parse_environment(); + log_open(); + + umask(0022); + + if (argc == 2 && streq(argv[1], "--introspect")) { + fputs(DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE + "\n", stdout); + fputs(locale_interface, stdout); + fputs("\n", stdout); + return 0; + } + + if (argc != 1) { + log_error("This program takes no arguments."); + r = -EINVAL; + goto finish; + } + + r = read_data(); + if (r < 0) { + log_error("Failed to read locale data: %s", strerror(-r)); + goto finish; + } + + r = connect_bus(&bus); + if (r < 0) + goto finish; + + remain_until = now(CLOCK_MONOTONIC) + DEFAULT_EXIT_USEC; + for (;;) { + + if (!dbus_connection_read_write_dispatch(bus, exiting ? -1 : (int) (DEFAULT_EXIT_USEC/USEC_PER_MSEC))) + break; + + if (!exiting && remain_until < now(CLOCK_MONOTONIC)) { + exiting = true; + bus_async_unregister_and_exit(bus, "org.freedesktop.locale1"); + } + } + + r = 0; + +finish: + free_data(); + + if (bus) { + dbus_connection_flush(bus); + dbus_connection_close(bus); + dbus_connection_unref(bus); + } + + return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/src/locale/org.freedesktop.locale1.conf b/src/locale/org.freedesktop.locale1.conf new file mode 100644 index 000000000..79d0ecd2b --- /dev/null +++ b/src/locale/org.freedesktop.locale1.conf @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + diff --git a/src/locale/org.freedesktop.locale1.policy.in b/src/locale/org.freedesktop.locale1.policy.in new file mode 100644 index 000000000..df63845e9 --- /dev/null +++ b/src/locale/org.freedesktop.locale1.policy.in @@ -0,0 +1,40 @@ + + + + + + + + The systemd Project + http://www.freedesktop.org/wiki/Software/systemd + + + <_description>Set system locale + <_message>Authentication is required to set the system locale. + + auth_admin_keep + auth_admin_keep + auth_admin_keep + + org.freedesktop.locale1.set-keyboard + + + + <_description>Set system keyboard settings + <_message>Authentication is required to set the system keyboard settings. + + auth_admin_keep + auth_admin_keep + auth_admin_keep + + + + diff --git a/src/locale/org.freedesktop.locale1.service b/src/locale/org.freedesktop.locale1.service new file mode 100644 index 000000000..025f9a0fc --- /dev/null +++ b/src/locale/org.freedesktop.locale1.service @@ -0,0 +1,12 @@ +# This file is part of systemd. +# +# 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. + +[D-BUS Service] +Name=org.freedesktop.locale1 +Exec=/bin/false +User=root +SystemdService=dbus-org.freedesktop.locale1.service diff --git a/src/login/.gitignore b/src/login/.gitignore new file mode 100644 index 000000000..d3840c7af --- /dev/null +++ b/src/login/.gitignore @@ -0,0 +1,5 @@ +/libsystemd-login.pc +/logind-gperf.c +/org.freedesktop.login1.policy +/71-seat.rules +/73-seat-late.rules diff --git a/src/login/70-power-switch.rules b/src/login/70-power-switch.rules new file mode 100644 index 000000000..36fb82731 --- /dev/null +++ b/src/login/70-power-switch.rules @@ -0,0 +1,13 @@ +# This file is part of systemd. +# +# 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. + +ACTION=="remove", GOTO="power_switch_end" + +SUBSYSTEM=="input", KERNEL=="event*", SUBSYSTEMS=="acpi", TAG+="power-switch" +SUBSYSTEM=="input", KERNEL=="event*", KERNELS=="thinkpad_acpi", TAG+="power-switch" + +LABEL="power_switch_end" diff --git a/src/login/70-uaccess.rules b/src/login/70-uaccess.rules new file mode 100644 index 000000000..d1275f2ca --- /dev/null +++ b/src/login/70-uaccess.rules @@ -0,0 +1,75 @@ +# This file is part of systemd. +# +# 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. + +ACTION=="remove", GOTO="uaccess_end" +ENV{MAJOR}=="", GOTO="uaccess_end" + +# PTP/MTP protocol devices, cameras, portable media players +SUBSYSTEM=="usb", ENV{ID_USB_INTERFACES}=="", ENV{DEVTYPE}=="usb_device", IMPORT{builtin}="usb_id" +SUBSYSTEM=="usb", ENV{ID_USB_INTERFACES}=="*:060101:*", TAG+="uaccess" + +# Digicams with proprietary protocol +ENV{ID_GPHOTO2}=="*?", TAG+="uaccess" + +# SCSI and USB scanners +ENV{libsane_matched}=="yes", TAG+="uaccess" + +# HPLIP devices (necessary for ink level check and HP tool maintenance) +ENV{ID_HPLIP}=="1", TAG+="uaccess" + +# optical drives +SUBSYSTEM=="block", ENV{ID_CDROM}=="1", TAG+="uaccess" +SUBSYSTEM=="scsi_generic", SUBSYSTEMS=="scsi", ATTRS{type}=="4|5", TAG+="uaccess" + +# Sound devices +SUBSYSTEM=="sound", TAG+="uaccess" + +# ffado is an userspace driver for firewire sound cards +SUBSYSTEM=="firewire", ENV{ID_FFADO}=="1", TAG+="uaccess" + +# Webcams, frame grabber, TV cards +SUBSYSTEM=="video4linux", TAG+="uaccess" +SUBSYSTEM=="dvb", TAG+="uaccess" + +# IIDC devices: industrial cameras and some webcams +SUBSYSTEM=="firewire", ATTR{units}=="*0x00a02d:0x00010*", TAG+="uaccess" +SUBSYSTEM=="firewire", ATTR{units}=="*0x00b09d:0x00010*", TAG+="uaccess" +# AV/C devices: camcorders, set-top boxes, TV sets, audio devices, and more +SUBSYSTEM=="firewire", ATTR{units}=="*0x00a02d:0x010001*", TAG+="uaccess" +SUBSYSTEM=="firewire", ATTR{units}=="*0x00a02d:0x014001*", TAG+="uaccess" + +# DRI video devices +SUBSYSTEM=="drm", KERNEL=="card*", TAG+="uaccess" + +# KVM +SUBSYSTEM=="misc", KERNEL=="kvm", TAG+="uaccess" + +# smart-card readers +ENV{ID_SMARTCARD_READER}=="*?", TAG+="uaccess" + +# (USB) authentication devices +ENV{ID_SECURITY_TOKEN}=="*?", TAG+="uaccess" + +# PDA devices +ENV{ID_PDA}=="*?", TAG+="uaccess" + +# Programmable remote control +ENV{ID_REMOTE_CONTROL}=="1", TAG+="uaccess" + +# joysticks +SUBSYSTEM=="input", ENV{ID_INPUT_JOYSTICK}=="?*", TAG+="uaccess" + +# color measurement devices +ENV{COLOR_MEASUREMENT_DEVICE}=="*?", TAG+="uaccess" + +# DDC/CI device, usually high-end monitors such as the DreamColor +ENV{DDC_DEVICE}=="*?", TAG+="uaccess" + +# media player raw devices (for user-mode drivers, Android SDK, etc.) +SUBSYSTEM=="usb", ENV{ID_MEDIA_PLAYER}=="?*", TAG+="uaccess" + +LABEL="uaccess_end" diff --git a/src/login/71-seat.rules.in b/src/login/71-seat.rules.in new file mode 100644 index 000000000..f554d7f61 --- /dev/null +++ b/src/login/71-seat.rules.in @@ -0,0 +1,48 @@ +# This file is part of systemd. +# +# 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. + +ACTION=="remove", GOTO="seat_end" + +TAG=="uaccess", SUBSYSTEM!="sound", TAG+="seat" +SUBSYSTEM=="sound", KERNEL=="card*", TAG+="seat" +SUBSYSTEM=="input", KERNEL=="input*", TAG+="seat" +SUBSYSTEM=="graphics", KERNEL=="fb[0-9]*", TAG+="seat" +SUBSYSTEM=="usb", ATTR{bDeviceClass}=="09", TAG+="seat" + +# 'Plugable' USB hub, sound, network, graphics adapter +SUBSYSTEM=="usb", ATTR{idVendor}=="2230", ATTR{idProduct}=="000[13]", ENV{ID_AUTOSEAT}="1" + +# Mimo 720, with integrated USB hub, displaylink graphics, and e2i +# touchscreen. This device carries no proper VID/PID in the USB hub, +# but it does carry good ID data in the graphics component, hence we +# check it from the parent. There's a bit of a race here however, +# given that the child devices might not exist yet at the time this +# rule is executed. To work around this we'll trigger the parent from +# the child if we notice that the parent wasn't recognized yet. + +# Match parent +SUBSYSTEM=="usb", ATTR{idVendor}=="058f", ATTR{idProduct}=="6254", \ + ATTR{%k.2/idVendor}=="17e9", ATTR{%k.2/idProduct}=="401a", ATTR{%k.2/product}=="mimo inc", \ + ENV{ID_AUTOSEAT}="1", ENV{ID_AVOID_LOOP}="1" + +# Match child, look for parent's ID_AVOID_LOOP +SUBSYSTEM=="usb", ATTR{idVendor}=="17e9", ATTR{idProduct}=="401a", ATTR{product}=="mimo inc", \ + ATTR{../idVendor}=="058f", ATTR{../idProduct}=="6254", \ + IMPORT{parent}="ID_AVOID_LOOP" + +# Match child, retrigger parent +SUBSYSTEM=="usb", ATTR{idVendor}=="17e9", ATTR{idProduct}=="401a", ATTR{product}=="mimo inc", \ + ATTR{../idVendor}=="058f", ATTR{../idProduct}=="6254", \ + ENV{ID_AVOID_LOOP}=="", \ + RUN+="@bindir@/udevadm trigger --parent-match=%p/.." + +TAG=="seat", ENV{ID_PATH}=="", IMPORT{builtin}="path_id" +TAG=="seat", ENV{ID_FOR_SEAT}=="", ENV{ID_PATH_TAG}!="", ENV{ID_FOR_SEAT}="$env{SUBSYSTEM}-$env{ID_PATH_TAG}" + +SUBSYSTEM=="input", ATTR{name}=="Wiebetech LLC Wiebetech", RUN+="@rootbindir@/loginctl lock-sessions" + +LABEL="seat_end" diff --git a/src/login/73-seat-late.rules.in b/src/login/73-seat-late.rules.in new file mode 100644 index 000000000..901df750f --- /dev/null +++ b/src/login/73-seat-late.rules.in @@ -0,0 +1,17 @@ +# This file is part of systemd. +# +# 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. + +ACTION=="remove", GOTO="seat_late_end" + +ENV{ID_SEAT}=="", ENV{ID_AUTOSEAT}=="1", ENV{ID_FOR_SEAT}!="", ENV{ID_SEAT}="seat-$env{ID_FOR_SEAT}" +ENV{ID_SEAT}=="", IMPORT{parent}="ID_SEAT" + +ENV{ID_SEAT}!="", TAG+="$env{ID_SEAT}" + +TAG=="uaccess", ENV{MAJOR}!="", RUN{builtin}+="uaccess" + +LABEL="seat_late_end" diff --git a/src/login/Makefile b/src/login/Makefile new file mode 120000 index 000000000..d0b0e8e00 --- /dev/null +++ b/src/login/Makefile @@ -0,0 +1 @@ +../Makefile \ No newline at end of file diff --git a/src/login/inhibit.c b/src/login/inhibit.c new file mode 100644 index 000000000..9b6613340 --- /dev/null +++ b/src/login/inhibit.c @@ -0,0 +1,331 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + +#include +#include +#include +#include +#include +#include + +#include "dbus-common.h" +#include "util.h" +#include "build.h" +#include "strv.h" + +static const char* arg_what = "idle:sleep:shutdown"; +static const char* arg_who = NULL; +static const char* arg_why = "Unknown reason"; +static const char* arg_mode = "block"; + +static enum { + ACTION_INHIBIT, + ACTION_LIST +} arg_action = ACTION_INHIBIT; + +static int inhibit(DBusConnection *bus, DBusError *error) { + DBusMessage *reply = NULL; + int r; + + r = bus_method_call_with_reply( + bus, + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + "Inhibit", + &reply, + NULL, + DBUS_TYPE_STRING, &arg_what, + DBUS_TYPE_STRING, &arg_who, + DBUS_TYPE_STRING, &arg_why, + DBUS_TYPE_STRING, &arg_mode, + DBUS_TYPE_INVALID); + if (r < 0) + return r; + + if (!dbus_message_get_args(reply, error, + DBUS_TYPE_UNIX_FD, &r, + DBUS_TYPE_INVALID)) + r = -EIO; + + dbus_message_unref(reply); + + return r; +} + +static int print_inhibitors(DBusConnection *bus, DBusError *error) { + DBusMessage *reply = NULL; + unsigned n = 0; + DBusMessageIter iter, sub, sub2; + int r; + + r = bus_method_call_with_reply( + bus, + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + "ListInhibitors", + &reply, + NULL, + DBUS_TYPE_INVALID); + if (r < 0) + goto finish; + + if (!dbus_message_iter_init(reply, &iter)) { + r = -ENOMEM; + goto finish; + } + + if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) { + r = -EIO; + goto finish; + } + + printf("%-21s %-20s %-20s %-5s %6s %6s\n", + "WHAT", + "WHO", + "WHY", + "MODE", + "UID", + "PID"); + + dbus_message_iter_recurse(&iter, &sub); + while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { + const char *what, *who, *why, *mode; + char *ewho, *ewhy; + dbus_uint32_t uid, pid; + + if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRUCT) { + r = -EIO; + goto finish; + } + + dbus_message_iter_recurse(&sub, &sub2); + + if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &what, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &who, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &why, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &mode, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT32, &uid, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT32, &pid, false) < 0) { + r = -EIO; + goto finish; + } + + ewho = ellipsize(who, 20, 66); + ewhy = ellipsize(why, 20, 66); + + printf("%-21s %-20s %-20s %-5s %6lu %6lu\n", + what, ewho ? ewho : who, ewhy ? ewhy : why, mode, (unsigned long) uid, (unsigned long) pid); + + free(ewho); + free(ewhy); + + dbus_message_iter_next(&sub); + + n++; + } + + printf("\n%u inhibitors listed.\n", n); + r = 0; + +finish: + if (reply) + dbus_message_unref(reply); + + return r; +} + +static int help(void) { + + printf("%s [OPTIONS...] {COMMAND} ...\n\n" + "Execute a process while inhibiting shutdown/sleep/idle.\n\n" + " -h --help Show this help\n" + " --version Show package version\n" + " --what=WHAT Operations to inhibit, colon separated list of:\n" + " shutdown, sleep, idle, handle-power-key,\n" + " handle-suspend-key, handle-hibernate-key,\n" + " handle-lid-switch\n" + " --who=STRING A descriptive string who is inhibiting\n" + " --why=STRING A descriptive string why is being inhibited\n" + " --mode=MODE One of block or delay\n" + " --list List active inhibitors\n", + program_invocation_short_name); + + return 0; +} + +static int parse_argv(int argc, char *argv[]) { + + enum { + ARG_VERSION = 0x100, + ARG_WHAT, + ARG_WHO, + ARG_WHY, + ARG_MODE, + ARG_LIST, + }; + + static const struct option options[] = { + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, ARG_VERSION }, + { "what", required_argument, NULL, ARG_WHAT }, + { "who", required_argument, NULL, ARG_WHO }, + { "why", required_argument, NULL, ARG_WHY }, + { "mode", required_argument, NULL, ARG_MODE }, + { "list", no_argument, NULL, ARG_LIST }, + { NULL, 0, NULL, 0 } + }; + + int c; + + assert(argc >= 0); + assert(argv); + + while ((c = getopt_long(argc, argv, "+h", options, NULL)) >= 0) { + + switch (c) { + + case 'h': + help(); + return 0; + + case ARG_VERSION: + puts(PACKAGE_STRING); + puts(SYSTEMD_FEATURES); + return 0; + + case ARG_WHAT: + arg_what = optarg; + break; + + case ARG_WHO: + arg_who = optarg; + break; + + case ARG_WHY: + arg_why = optarg; + break; + + case ARG_MODE: + arg_mode = optarg; + break; + + case ARG_LIST: + arg_action = ACTION_LIST; + break; + + default: + log_error("Unknown option code %c", c); + return -EINVAL; + } + } + + if (arg_action == ACTION_INHIBIT && optind >= argc) { + log_error("Missing command line to execute."); + return -EINVAL; + } + + return 1; +} + +int main(int argc, char *argv[]) { + int r, exit_code = 0; + DBusConnection *bus = NULL; + DBusError error; + int fd = -1; + + dbus_error_init(&error); + + log_parse_environment(); + log_open(); + + r = parse_argv(argc, argv); + if (r <= 0) + goto finish; + + bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error); + if (!bus) { + log_error("Failed to connect to bus: %s", bus_error_message(&error)); + r = -EIO; + goto finish; + } + + if (arg_action == ACTION_LIST) { + + r = print_inhibitors(bus, &error); + if (r < 0) { + log_error("Failed to list inhibitors: %s", bus_error_message_or_strerror(&error, -r)); + goto finish; + } + + } else { + char *w = NULL; + pid_t pid; + + if (!arg_who) + arg_who = w = strv_join(argv + optind, " "); + + fd = inhibit(bus, &error); + free(w); + + if (fd < 0) { + log_error("Failed to inhibit: %s", bus_error_message_or_strerror(&error, -r)); + r = fd; + goto finish; + } + + pid = fork(); + if (pid < 0) { + log_error("Failed to fork: %m"); + r = -errno; + goto finish; + } + + if (pid == 0) { + /* Child */ + + close_nointr_nofail(fd); + close_all_fds(NULL, 0); + + execvp(argv[optind], argv + optind); + log_error("Failed to execute %s: %m", argv[optind]); + _exit(EXIT_FAILURE); + } + + r = wait_for_terminate_and_warn(argv[optind], pid); + if (r >= 0) + exit_code = r; + } + +finish: + if (bus) { + dbus_connection_close(bus); + dbus_connection_unref(bus); + } + + dbus_error_free(&error); + + if (fd >= 0) + close_nointr_nofail(fd); + + return r < 0 ? EXIT_FAILURE : exit_code; +} diff --git a/src/login/libsystemd-login.pc.in b/src/login/libsystemd-login.pc.in new file mode 100644 index 000000000..7b2a7245f --- /dev/null +++ b/src/login/libsystemd-login.pc.in @@ -0,0 +1,18 @@ +# This file is part of systemd. +# +# 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. + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: systemd +Description: systemd Login Utility Library +URL: @PACKAGE_URL@ +Version: @PACKAGE_VERSION@ +Libs: -L${libdir} -lsystemd-login +Cflags: -I${includedir} diff --git a/src/login/libsystemd-login.sym b/src/login/libsystemd-login.sym new file mode 100644 index 000000000..ff51be729 --- /dev/null +++ b/src/login/libsystemd-login.sym @@ -0,0 +1,55 @@ +/*** + This file is part of systemd. + + 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. +***/ + +/* Original symbols from systemd v31 */ + +LIBSYSTEMD_LOGIN_31 { +global: + sd_get_seats; + sd_get_sessions; + sd_get_uids; + sd_login_monitor_flush; + sd_login_monitor_get_fd; + sd_login_monitor_new; + sd_login_monitor_unref; + sd_pid_get_owner_uid; + sd_pid_get_session; + sd_seat_can_multi_session; + sd_seat_get_active; + sd_seat_get_sessions; + sd_session_get_seat; + sd_session_get_uid; + sd_session_is_active; + sd_uid_get_seats; + sd_uid_get_sessions; + sd_uid_get_state; + sd_uid_is_on_seat; +local: + *; +}; + +LIBSYSTEMD_LOGIN_38 { +global: + sd_pid_get_unit; + sd_session_get_service; +} LIBSYSTEMD_LOGIN_31; + +LIBSYSTEMD_LOGIN_43 { +global: + sd_session_get_type; + sd_session_get_class; + sd_session_get_display; +} LIBSYSTEMD_LOGIN_38; + +LIBSYSTEMD_LOGIN_186 { +global: + sd_session_get_state; + sd_seat_can_tty; + sd_seat_can_graphical; +} LIBSYSTEMD_LOGIN_43; diff --git a/src/login/loginctl.c b/src/login/loginctl.c new file mode 100644 index 000000000..e2b33a626 --- /dev/null +++ b/src/login/loginctl.c @@ -0,0 +1,1610 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include + +#include "log.h" +#include "util.h" +#include "macro.h" +#include "pager.h" +#include "dbus-common.h" +#include "build.h" +#include "strv.h" +#include "cgroup-show.h" +#include "sysfs-show.h" +#include "spawn-polkit-agent.h" + +static char **arg_property = NULL; +static bool arg_all = false; +static bool arg_no_pager = false; +static const char *arg_kill_who = NULL; +static int arg_signal = SIGTERM; +static enum transport { + TRANSPORT_NORMAL, + TRANSPORT_SSH, + TRANSPORT_POLKIT +} arg_transport = TRANSPORT_NORMAL; +static bool arg_ask_password = true; +static const char *arg_host = NULL; + +static void pager_open_if_enabled(void) { + + /* Cache result before we open the pager */ + if (arg_no_pager) + return; + + pager_open(); +} + +static void polkit_agent_open_if_enabled(void) { + + /* Open the polkit agent as a child process if necessary */ + + if (!arg_ask_password) + return; + + polkit_agent_open(); +} + +static int list_sessions(DBusConnection *bus, char **args, unsigned n) { + DBusMessage *reply = NULL; + int r; + DBusMessageIter iter, sub, sub2; + unsigned k = 0; + + pager_open_if_enabled(); + + r = bus_method_call_with_reply ( + bus, + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + "ListSessions", + &reply, + NULL, + DBUS_TYPE_INVALID); + if (r) + goto finish; + + if (!dbus_message_iter_init(reply, &iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY || + dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_STRUCT) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_recurse(&iter, &sub); + + if (on_tty()) + printf("%10s %10s %-16s %-16s\n", "SESSION", "UID", "USER", "SEAT"); + + while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { + const char *id, *user, *seat, *object; + uint32_t uid; + + if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRUCT) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_recurse(&sub, &sub2); + + if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &id, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT32, &uid, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &user, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &seat, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_OBJECT_PATH, &object, false) < 0) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + printf("%10s %10u %-16s %-16s\n", id, (unsigned) uid, user, seat); + + k++; + + dbus_message_iter_next(&sub); + } + + if (on_tty()) + printf("\n%u sessions listed.\n", k); + + r = 0; + +finish: + if (reply) + dbus_message_unref(reply); + + return r; +} + +static int list_users(DBusConnection *bus, char **args, unsigned n) { + DBusMessage *reply = NULL; + int r; + DBusMessageIter iter, sub, sub2; + unsigned k = 0; + + pager_open_if_enabled(); + + r = bus_method_call_with_reply ( + bus, + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + "ListUsers", + &reply, + NULL, + DBUS_TYPE_INVALID); + if (r) + goto finish; + + if (!dbus_message_iter_init(reply, &iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY || + dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_STRUCT) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_recurse(&iter, &sub); + + if (on_tty()) + printf("%10s %-16s\n", "UID", "USER"); + + while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { + const char *user, *object; + uint32_t uid; + + if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRUCT) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_recurse(&sub, &sub2); + + if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT32, &uid, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &user, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_OBJECT_PATH, &object, false) < 0) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + printf("%10u %-16s\n", (unsigned) uid, user); + + k++; + + dbus_message_iter_next(&sub); + } + + if (on_tty()) + printf("\n%u users listed.\n", k); + + r = 0; + +finish: + if (reply) + dbus_message_unref(reply); + + return r; +} + +static int list_seats(DBusConnection *bus, char **args, unsigned n) { + DBusMessage *reply = NULL; + int r; + DBusMessageIter iter, sub, sub2; + unsigned k = 0; + + pager_open_if_enabled(); + + r = bus_method_call_with_reply ( + bus, + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + "ListSeats", + &reply, + NULL, + DBUS_TYPE_INVALID); + if (r) + goto finish; + + if (!dbus_message_iter_init(reply, &iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY || + dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_STRUCT) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_recurse(&iter, &sub); + + if (on_tty()) + printf("%-16s\n", "SEAT"); + + while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { + const char *seat, *object; + + if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRUCT) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_recurse(&sub, &sub2); + + if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &seat, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_OBJECT_PATH, &object, false) < 0) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + printf("%-16s\n", seat); + + k++; + + dbus_message_iter_next(&sub); + } + + if (on_tty()) + printf("\n%u seats listed.\n", k); + + r = 0; + +finish: + if (reply) + dbus_message_unref(reply); + + return r; +} + +typedef struct SessionStatusInfo { + const char *id; + uid_t uid; + const char *name; + usec_t timestamp; + const char *default_control_group; + int vtnr; + const char *seat; + const char *tty; + const char *display; + bool remote; + const char *remote_host; + const char *remote_user; + const char *service; + pid_t leader; + const char *type; + const char *class; + const char *state; +} SessionStatusInfo; + +typedef struct UserStatusInfo { + uid_t uid; + const char *name; + usec_t timestamp; + const char *default_control_group; + const char *state; + char **sessions; + const char *display; +} UserStatusInfo; + +typedef struct SeatStatusInfo { + const char *id; + const char *active_session; + char **sessions; +} SeatStatusInfo; + +static void print_session_status_info(SessionStatusInfo *i) { + char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1; + char since2[FORMAT_TIMESTAMP_MAX], *s2; + assert(i); + + printf("%s - ", strna(i->id)); + + if (i->name) + printf("%s (%u)\n", i->name, (unsigned) i->uid); + else + printf("%u\n", (unsigned) i->uid); + + s1 = format_timestamp_relative(since1, sizeof(since1), i->timestamp); + s2 = format_timestamp(since2, sizeof(since2), i->timestamp); + + if (s1) + printf("\t Since: %s; %s\n", s2, s1); + else if (s2) + printf("\t Since: %s\n", s2); + + if (i->leader > 0) { + char *t = NULL; + + printf("\t Leader: %u", (unsigned) i->leader); + + get_process_comm(i->leader, &t); + if (t) { + printf(" (%s)", t); + free(t); + } + + printf("\n"); + } + + if (i->seat) { + printf("\t Seat: %s", i->seat); + + if (i->vtnr > 0) + printf("; vc%i", i->vtnr); + + printf("\n"); + } + + if (i->tty) + printf("\t TTY: %s\n", i->tty); + else if (i->display) + printf("\t Display: %s\n", i->display); + + if (i->remote_host && i->remote_user) + printf("\t Remote: %s@%s\n", i->remote_user, i->remote_host); + else if (i->remote_host) + printf("\t Remote: %s\n", i->remote_host); + else if (i->remote_user) + printf("\t Remote: user %s\n", i->remote_user); + else if (i->remote) + printf("\t Remote: Yes\n"); + + if (i->service) { + printf("\t Service: %s", i->service); + + if (i->type) + printf("; type %s", i->type); + + if (i->class) + printf("; class %s", i->class); + + printf("\n"); + } else if (i->type) { + printf("\t Type: %s\n", i->type); + + if (i->class) + printf("; class %s", i->class); + } else if (i->class) + printf("\t Class: %s\n", i->class); + + if (i->state) + printf("\t State: %s\n", i->state); + + if (i->default_control_group) { + unsigned c; + + printf("\t CGroup: %s\n", i->default_control_group); + + if (arg_transport != TRANSPORT_SSH) { + c = columns(); + if (c > 18) + c -= 18; + else + c = 0; + + show_cgroup_and_extra_by_spec(i->default_control_group, "\t\t ", c, false, arg_all, &i->leader, i->leader > 0 ? 1 : 0); + } + } +} + +static void print_user_status_info(UserStatusInfo *i) { + char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1; + char since2[FORMAT_TIMESTAMP_MAX], *s2; + assert(i); + + if (i->name) + printf("%s (%u)\n", i->name, (unsigned) i->uid); + else + printf("%u\n", (unsigned) i->uid); + + s1 = format_timestamp_relative(since1, sizeof(since1), i->timestamp); + s2 = format_timestamp(since2, sizeof(since2), i->timestamp); + + if (s1) + printf("\t Since: %s; %s\n", s2, s1); + else if (s2) + printf("\t Since: %s\n", s2); + + if (!isempty(i->state)) + printf("\t State: %s\n", i->state); + + if (!strv_isempty(i->sessions)) { + char **l; + printf("\tSessions:"); + + STRV_FOREACH(l, i->sessions) { + if (streq_ptr(*l, i->display)) + printf(" *%s", *l); + else + printf(" %s", *l); + } + + printf("\n"); + } + + if (i->default_control_group) { + unsigned c; + + printf("\t CGroup: %s\n", i->default_control_group); + + if (arg_transport != TRANSPORT_SSH) { + c = columns(); + if (c > 18) + c -= 18; + else + c = 0; + + show_cgroup_by_path(i->default_control_group, "\t\t ", c, false, arg_all); + } + } +} + +static void print_seat_status_info(SeatStatusInfo *i) { + assert(i); + + printf("%s\n", strna(i->id)); + + if (!strv_isempty(i->sessions)) { + char **l; + printf("\tSessions:"); + + STRV_FOREACH(l, i->sessions) { + if (streq_ptr(*l, i->active_session)) + printf(" *%s", *l); + else + printf(" %s", *l); + } + + printf("\n"); + } + + if (arg_transport != TRANSPORT_SSH) { + unsigned c; + + c = columns(); + if (c > 21) + c -= 21; + else + c = 0; + + printf("\t Devices:\n"); + + show_sysfs(i->id, "\t\t ", c); + } +} + +static int status_property_session(const char *name, DBusMessageIter *iter, SessionStatusInfo *i) { + assert(name); + assert(iter); + assert(i); + + switch (dbus_message_iter_get_arg_type(iter)) { + + case DBUS_TYPE_STRING: { + const char *s; + + dbus_message_iter_get_basic(iter, &s); + + if (!isempty(s)) { + if (streq(name, "Id")) + i->id = s; + else if (streq(name, "Name")) + i->name = s; + else if (streq(name, "DefaultControlGroup")) + i->default_control_group = s; + else if (streq(name, "TTY")) + i->tty = s; + else if (streq(name, "Display")) + i->display = s; + else if (streq(name, "RemoteHost")) + i->remote_host = s; + else if (streq(name, "RemoteUser")) + i->remote_user = s; + else if (streq(name, "Service")) + i->service = s; + else if (streq(name, "Type")) + i->type = s; + else if (streq(name, "Class")) + i->class = s; + else if (streq(name, "State")) + i->state = s; + } + break; + } + + case DBUS_TYPE_UINT32: { + uint32_t u; + + dbus_message_iter_get_basic(iter, &u); + + if (streq(name, "VTNr")) + i->vtnr = (int) u; + else if (streq(name, "Leader")) + i->leader = (pid_t) u; + + break; + } + + case DBUS_TYPE_BOOLEAN: { + dbus_bool_t b; + + dbus_message_iter_get_basic(iter, &b); + + if (streq(name, "Remote")) + i->remote = b; + + break; + } + + case DBUS_TYPE_UINT64: { + uint64_t u; + + dbus_message_iter_get_basic(iter, &u); + + if (streq(name, "Timestamp")) + i->timestamp = (usec_t) u; + + break; + } + + case DBUS_TYPE_STRUCT: { + DBusMessageIter sub; + + dbus_message_iter_recurse(iter, &sub); + + if (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_UINT32 && streq(name, "User")) { + uint32_t u; + + dbus_message_iter_get_basic(&sub, &u); + i->uid = (uid_t) u; + + } else if (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRING && streq(name, "Seat")) { + const char *s; + + dbus_message_iter_get_basic(&sub, &s); + + if (!isempty(s)) + i->seat = s; + } + + break; + } + } + + return 0; +} + +static int status_property_user(const char *name, DBusMessageIter *iter, UserStatusInfo *i) { + assert(name); + assert(iter); + assert(i); + + switch (dbus_message_iter_get_arg_type(iter)) { + + case DBUS_TYPE_STRING: { + const char *s; + + dbus_message_iter_get_basic(iter, &s); + + if (!isempty(s)) { + if (streq(name, "Name")) + i->name = s; + else if (streq(name, "DefaultControlGroup")) + i->default_control_group = s; + else if (streq(name, "State")) + i->state = s; + } + break; + } + + case DBUS_TYPE_UINT32: { + uint32_t u; + + dbus_message_iter_get_basic(iter, &u); + + if (streq(name, "UID")) + i->uid = (uid_t) u; + + break; + } + + case DBUS_TYPE_UINT64: { + uint64_t u; + + dbus_message_iter_get_basic(iter, &u); + + if (streq(name, "Timestamp")) + i->timestamp = (usec_t) u; + + break; + } + + case DBUS_TYPE_STRUCT: { + DBusMessageIter sub; + + dbus_message_iter_recurse(iter, &sub); + + if (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRING && streq(name, "Display")) { + const char *s; + + dbus_message_iter_get_basic(&sub, &s); + + if (!isempty(s)) + i->display = s; + } + + break; + } + + case DBUS_TYPE_ARRAY: { + + if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT && streq(name, "Sessions")) { + DBusMessageIter sub, sub2; + + dbus_message_iter_recurse(iter, &sub); + while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRUCT) { + const char *id; + const char *path; + + dbus_message_iter_recurse(&sub, &sub2); + + if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &id, true) >= 0 && + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_OBJECT_PATH, &path, false) >= 0) { + char **l; + + l = strv_append(i->sessions, id); + if (!l) + return -ENOMEM; + + strv_free(i->sessions); + i->sessions = l; + } + + dbus_message_iter_next(&sub); + } + + return 0; + } + } + } + + return 0; +} + +static int status_property_seat(const char *name, DBusMessageIter *iter, SeatStatusInfo *i) { + assert(name); + assert(iter); + assert(i); + + switch (dbus_message_iter_get_arg_type(iter)) { + + case DBUS_TYPE_STRING: { + const char *s; + + dbus_message_iter_get_basic(iter, &s); + + if (!isempty(s)) { + if (streq(name, "Id")) + i->id = s; + } + break; + } + + case DBUS_TYPE_STRUCT: { + DBusMessageIter sub; + + dbus_message_iter_recurse(iter, &sub); + + if (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRING && streq(name, "ActiveSession")) { + const char *s; + + dbus_message_iter_get_basic(&sub, &s); + + if (!isempty(s)) + i->active_session = s; + } + + break; + } + + case DBUS_TYPE_ARRAY: { + + if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT && streq(name, "Sessions")) { + DBusMessageIter sub, sub2; + + dbus_message_iter_recurse(iter, &sub); + while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRUCT) { + const char *id; + const char *path; + + dbus_message_iter_recurse(&sub, &sub2); + + if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &id, true) >= 0 && + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_OBJECT_PATH, &path, false) >= 0) { + char **l; + + l = strv_append(i->sessions, id); + if (!l) + return -ENOMEM; + + strv_free(i->sessions); + i->sessions = l; + } + + dbus_message_iter_next(&sub); + } + + return 0; + } + } + } + + return 0; +} + +static int print_property(const char *name, DBusMessageIter *iter) { + assert(name); + assert(iter); + + if (arg_property && !strv_find(arg_property, name)) + return 0; + + switch (dbus_message_iter_get_arg_type(iter)) { + + case DBUS_TYPE_STRUCT: { + DBusMessageIter sub; + + dbus_message_iter_recurse(iter, &sub); + + if (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRING && + (streq(name, "Display") || streq(name, "ActiveSession"))) { + const char *s; + + dbus_message_iter_get_basic(&sub, &s); + + if (arg_all || !isempty(s)) + printf("%s=%s\n", name, s); + return 0; + } + break; + } + + case DBUS_TYPE_ARRAY: + + if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT && streq(name, "Sessions")) { + DBusMessageIter sub, sub2; + bool found = false; + + dbus_message_iter_recurse(iter, &sub); + while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRUCT) { + const char *id; + const char *path; + + dbus_message_iter_recurse(&sub, &sub2); + + if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &id, true) >= 0 && + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_OBJECT_PATH, &path, false) >= 0) { + if (found) + printf(" %s", id); + else { + printf("%s=%s", name, id); + found = true; + } + } + + dbus_message_iter_next(&sub); + } + + if (!found && arg_all) + printf("%s=\n", name); + else if (found) + printf("\n"); + + return 0; + } + + break; + } + + if (generic_print_property(name, iter, arg_all) > 0) + return 0; + + if (arg_all) + printf("%s=[unprintable]\n", name); + + return 0; +} + +static int show_one(const char *verb, DBusConnection *bus, const char *path, bool show_properties, bool *new_line) { + _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; + const char *interface = ""; + int r; + DBusMessageIter iter, sub, sub2, sub3; + SessionStatusInfo session_info; + UserStatusInfo user_info; + SeatStatusInfo seat_info; + + assert(path); + assert(new_line); + + zero(session_info); + zero(user_info); + zero(seat_info); + + r = bus_method_call_with_reply( + bus, + "org.freedesktop.login1", + path, + "org.freedesktop.DBus.Properties", + "GetAll", + &reply, + NULL, + DBUS_TYPE_STRING, &interface, + DBUS_TYPE_INVALID); + if (r < 0) + goto finish; + + if (!dbus_message_iter_init(reply, &iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY || + dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_DICT_ENTRY) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_recurse(&iter, &sub); + + if (*new_line) + printf("\n"); + + *new_line = true; + + while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { + const char *name; + + if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_DICT_ENTRY) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_recurse(&sub, &sub2); + + if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &name, true) < 0) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + if (dbus_message_iter_get_arg_type(&sub2) != DBUS_TYPE_VARIANT) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_recurse(&sub2, &sub3); + + if (show_properties) + r = print_property(name, &sub3); + else if (strstr(verb, "session")) + r = status_property_session(name, &sub3, &session_info); + else if (strstr(verb, "user")) + r = status_property_user(name, &sub3, &user_info); + else + r = status_property_seat(name, &sub3, &seat_info); + + if (r < 0) { + log_error("Failed to parse reply."); + goto finish; + } + + dbus_message_iter_next(&sub); + } + + if (!show_properties) { + if (strstr(verb, "session")) + print_session_status_info(&session_info); + else if (strstr(verb, "user")) + print_user_status_info(&user_info); + else + print_seat_status_info(&seat_info); + } + + r = 0; + +finish: + strv_free(seat_info.sessions); + strv_free(user_info.sessions); + + return r; +} + +static int show(DBusConnection *bus, char **args, unsigned n) { + DBusMessage *reply = NULL; + int r, ret = 0; + DBusError error; + unsigned i; + bool show_properties, new_line = false; + + assert(bus); + assert(args); + + dbus_error_init(&error); + + show_properties = !strstr(args[0], "status"); + + pager_open_if_enabled(); + + if (show_properties && n <= 1) { + /* If not argument is specified inspect the manager + * itself */ + + ret = show_one(args[0], bus, "/org/freedesktop/login1", show_properties, &new_line); + goto finish; + } + + for (i = 1; i < n; i++) { + const char *path = NULL; + + if (strstr(args[0], "session")) { + + ret = bus_method_call_with_reply ( + bus, + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + "GetSession", + &reply, + NULL, + DBUS_TYPE_STRING, &args[i], + DBUS_TYPE_INVALID); + + } else if (strstr(args[0], "user")) { + uid_t uid; + uint32_t u; + + ret = get_user_creds((const char**) (args+i), &uid, NULL, NULL, NULL); + if (ret < 0) { + log_error("User %s unknown.", args[i]); + goto finish; + } + + u = (uint32_t) uid; + ret = bus_method_call_with_reply ( + bus, + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + "GetUser", + &reply, + NULL, + DBUS_TYPE_UINT32, &u, + DBUS_TYPE_INVALID); + } else { + + ret = bus_method_call_with_reply ( + bus, + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + "GetSeat", + &reply, + NULL, + DBUS_TYPE_STRING, &args[i], + DBUS_TYPE_INVALID); + } + if (ret) + goto finish; + + if (!dbus_message_get_args(reply, &error, + DBUS_TYPE_OBJECT_PATH, &path, + DBUS_TYPE_INVALID)) { + log_error("Failed to parse reply: %s", bus_error_message(&error)); + ret = -EIO; + goto finish; + } + + r = show_one(args[0], bus, path, show_properties, &new_line); + if (r != 0) + ret = r; + + dbus_message_unref(reply); + reply = NULL; + } + +finish: + if (reply) + dbus_message_unref(reply); + + dbus_error_free(&error); + + return ret; +} + +static int activate(DBusConnection *bus, char **args, unsigned n) { + int ret = 0; + unsigned i; + + assert(args); + + for (i = 1; i < n; i++) { + + ret = bus_method_call_with_reply ( + bus, + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + streq(args[0], "lock-session") ? "LockSession" : + streq(args[0], "unlock-session") ? "UnlockSession" : + streq(args[0], "terminate-session") ? "TerminateSession" : + "ActivateSession", + NULL, + NULL, + DBUS_TYPE_STRING, &args[i], + DBUS_TYPE_INVALID); + if (ret) + goto finish; + } + +finish: + return ret; +} + +static int kill_session(DBusConnection *bus, char **args, unsigned n) { + int ret = 0; + unsigned i; + + assert(args); + + if (!arg_kill_who) + arg_kill_who = "all"; + + for (i = 1; i < n; i++) { + ret = bus_method_call_with_reply ( + bus, + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + "KillSession", + NULL, + NULL, + DBUS_TYPE_STRING, &args[i], + DBUS_TYPE_STRING, &arg_kill_who, + DBUS_TYPE_INT32, &arg_signal, + DBUS_TYPE_INVALID); + if (ret) + goto finish; + } + +finish: + return ret; +} + +static int enable_linger(DBusConnection *bus, char **args, unsigned n) { + int ret = 0; + unsigned i; + dbus_bool_t b, interactive = true; + + assert(args); + + polkit_agent_open_if_enabled(); + + b = streq(args[0], "enable-linger"); + + for (i = 1; i < n; i++) { + uint32_t u; + uid_t uid; + + ret = get_user_creds((const char**) (args+i), &uid, NULL, NULL, NULL); + if (ret < 0) { + log_error("Failed to resolve user %s: %s", args[i], strerror(-ret)); + goto finish; + } + + u = (uint32_t) uid; + ret = bus_method_call_with_reply ( + bus, + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + "SetUserLinger", + NULL, + NULL, + DBUS_TYPE_UINT32, &u, + DBUS_TYPE_BOOLEAN, &b, + DBUS_TYPE_BOOLEAN, &interactive, + DBUS_TYPE_INVALID); + if (ret) + goto finish; + } + +finish: + return ret; +} + +static int terminate_user(DBusConnection *bus, char **args, unsigned n) { + int ret = 0; + unsigned i; + + assert(args); + + for (i = 1; i < n; i++) { + uint32_t u; + uid_t uid; + + ret = get_user_creds((const char**) (args+i), &uid, NULL, NULL, NULL); + if (ret < 0) { + log_error("Failed to look up user %s: %s", args[i], strerror(-ret)); + goto finish; + } + + u = (uint32_t) uid; + ret = bus_method_call_with_reply ( + bus, + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + "TerminateUser", + NULL, + NULL, + DBUS_TYPE_UINT32, &u, + DBUS_TYPE_INVALID); + if (ret) + goto finish; + } + +finish: + return ret; +} + +static int kill_user(DBusConnection *bus, char **args, unsigned n) { + int ret = 0; + unsigned i; + + assert(args); + + if (!arg_kill_who) + arg_kill_who = "all"; + + for (i = 1; i < n; i++) { + uid_t uid; + uint32_t u; + + ret = get_user_creds((const char**) (args+i), &uid, NULL, NULL, NULL); + if (ret < 0) { + log_error("Failed to look up user %s: %s", args[i], strerror(-ret)); + goto finish; + } + + u = (uint32_t) uid; + ret = bus_method_call_with_reply ( + bus, + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + "KillUser", + NULL, + NULL, + DBUS_TYPE_UINT32, &u, + DBUS_TYPE_INT32, &arg_signal, + DBUS_TYPE_INVALID); + if (ret) + goto finish; + } + +finish: + return ret; +} + +static int attach(DBusConnection *bus, char **args, unsigned n) { + int ret = 0; + unsigned i; + dbus_bool_t interactive = true; + + assert(args); + + polkit_agent_open_if_enabled(); + + for (i = 2; i < n; i++) { + ret = bus_method_call_with_reply ( + bus, + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + "AttachDevice", + NULL, + NULL, + DBUS_TYPE_STRING, &args[1], + DBUS_TYPE_STRING, &args[i], + DBUS_TYPE_BOOLEAN, &interactive, + DBUS_TYPE_INVALID); + if (ret) + goto finish; + } + +finish: + return ret; +} + +static int flush_devices(DBusConnection *bus, char **args, unsigned n) { + dbus_bool_t interactive = true; + + assert(args); + + polkit_agent_open_if_enabled(); + + return bus_method_call_with_reply ( + bus, + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + "FlushDevices", + NULL, + NULL, + DBUS_TYPE_BOOLEAN, &interactive, + DBUS_TYPE_INVALID); +} + +static int lock_sessions(DBusConnection *bus, char **args, unsigned n) { + polkit_agent_open_if_enabled(); + + return bus_method_call_with_reply ( + bus, + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + "LockSessions", + NULL, + NULL, + DBUS_TYPE_INVALID); +} + +static int terminate_seat(DBusConnection *bus, char **args, unsigned n) { + int ret = 0; + unsigned i; + + assert(args); + + for (i = 1; i < n; i++) { + ret = bus_method_call_with_reply ( + bus, + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + "TerminateSeat", + NULL, + NULL, + DBUS_TYPE_STRING, &args[i], + DBUS_TYPE_INVALID); + if (ret) + goto finish; + } + +finish: + return ret; +} + +static int help(void) { + + printf("%s [OPTIONS...] {COMMAND} ...\n\n" + "Send control commands to or query the login manager.\n\n" + " -h --help Show this help\n" + " --version Show package version\n" + " -p --property=NAME Show only properties by this name\n" + " -a --all Show all properties, including empty ones\n" + " --kill-who=WHO Who to send signal to\n" + " -s --signal=SIGNAL Which signal to send\n" + " --no-ask-password Don't prompt for password\n" + " -H --host=[USER@]HOST Show information for remote host\n" + " -P --privileged Acquire privileges before execution\n" + " --no-pager Do not pipe output into a pager\n\n" + "Commands:\n" + " list-sessions List sessions\n" + " session-status [ID...] Show session status\n" + " show-session [ID...] Show properties of one or more sessions\n" + " activate [ID] Activate a session\n" + " lock-session [ID...] Screen lock one or more sessions\n" + " unlock-session [ID...] Screen unlock one or more sessions\n" + " lock-sessions Screen lock all current sessions\n" + " terminate-session [ID...] Terminate one or more sessions\n" + " kill-session [ID...] Send signal to processes of a session\n" + " list-users List users\n" + " user-status [USER...] Show user status\n" + " show-user [USER...] Show properties of one or more users\n" + " enable-linger [USER...] Enable linger state of one or more users\n" + " disable-linger [USER...] Disable linger state of one or more users\n" + " terminate-user [USER...] Terminate all sessions of one or more users\n" + " kill-user [USER...] Send signal to processes of a user\n" + " list-seats List seats\n" + " seat-status [NAME...] Show seat status\n" + " show-seat [NAME...] Show properties of one or more seats\n" + " attach [NAME] [DEVICE...] Attach one or more devices to a seat\n" + " flush-devices Flush all device associations\n" + " terminate-seat [NAME...] Terminate all sessions on one or more seats\n", + program_invocation_short_name); + + return 0; +} + +static int parse_argv(int argc, char *argv[]) { + + enum { + ARG_VERSION = 0x100, + ARG_NO_PAGER, + ARG_KILL_WHO, + ARG_NO_ASK_PASSWORD + }; + + static const struct option options[] = { + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, ARG_VERSION }, + { "property", required_argument, NULL, 'p' }, + { "all", no_argument, NULL, 'a' }, + { "no-pager", no_argument, NULL, ARG_NO_PAGER }, + { "kill-who", required_argument, NULL, ARG_KILL_WHO }, + { "signal", required_argument, NULL, 's' }, + { "host", required_argument, NULL, 'H' }, + { "privileged", no_argument, NULL, 'P' }, + { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD }, + { NULL, 0, NULL, 0 } + }; + + int c; + + assert(argc >= 0); + assert(argv); + + while ((c = getopt_long(argc, argv, "hp:as:H:P", options, NULL)) >= 0) { + + switch (c) { + + case 'h': + help(); + return 0; + + case ARG_VERSION: + puts(PACKAGE_STRING); + puts(SYSTEMD_FEATURES); + return 0; + + case 'p': { + char **l; + + l = strv_append(arg_property, optarg); + if (!l) + return -ENOMEM; + + strv_free(arg_property); + arg_property = l; + + /* If the user asked for a particular + * property, show it to him, even if it is + * empty. */ + arg_all = true; + break; + } + + case 'a': + arg_all = true; + break; + + case ARG_NO_PAGER: + arg_no_pager = true; + break; + + case ARG_NO_ASK_PASSWORD: + arg_ask_password = false; + break; + + case ARG_KILL_WHO: + arg_kill_who = optarg; + break; + + case 's': + arg_signal = signal_from_string_try_harder(optarg); + if (arg_signal < 0) { + log_error("Failed to parse signal string %s.", optarg); + return -EINVAL; + } + break; + + case 'P': + arg_transport = TRANSPORT_POLKIT; + break; + + case 'H': + arg_transport = TRANSPORT_SSH; + arg_host = optarg; + break; + + case '?': + return -EINVAL; + + default: + log_error("Unknown option code %c", c); + return -EINVAL; + } + } + + return 1; +} + +static int loginctl_main(DBusConnection *bus, int argc, char *argv[], DBusError *error) { + + static const struct { + const char* verb; + const enum { + MORE, + LESS, + EQUAL + } argc_cmp; + const int argc; + int (* const dispatch)(DBusConnection *bus, char **args, unsigned n); + } verbs[] = { + { "list-sessions", LESS, 1, list_sessions }, + { "session-status", MORE, 2, show }, + { "show-session", MORE, 1, show }, + { "activate", EQUAL, 2, activate }, + { "lock-session", MORE, 2, activate }, + { "unlock-session", MORE, 2, activate }, + { "lock-sessions", EQUAL, 1, lock_sessions }, + { "terminate-session", MORE, 2, activate }, + { "kill-session", MORE, 2, kill_session }, + { "list-users", EQUAL, 1, list_users }, + { "user-status", MORE, 2, show }, + { "show-user", MORE, 1, show }, + { "enable-linger", MORE, 2, enable_linger }, + { "disable-linger", MORE, 2, enable_linger }, + { "terminate-user", MORE, 2, terminate_user }, + { "kill-user", MORE, 2, kill_user }, + { "list-seats", EQUAL, 1, list_seats }, + { "seat-status", MORE, 2, show }, + { "show-seat", MORE, 1, show }, + { "attach", MORE, 3, attach }, + { "flush-devices", EQUAL, 1, flush_devices }, + { "terminate-seat", MORE, 2, terminate_seat }, + }; + + int left; + unsigned i; + + assert(argc >= 0); + assert(argv); + assert(error); + + left = argc - optind; + + if (left <= 0) + /* Special rule: no arguments means "list-sessions" */ + i = 0; + else { + if (streq(argv[optind], "help")) { + help(); + return 0; + } + + for (i = 0; i < ELEMENTSOF(verbs); i++) + if (streq(argv[optind], verbs[i].verb)) + break; + + if (i >= ELEMENTSOF(verbs)) { + log_error("Unknown operation %s", argv[optind]); + return -EINVAL; + } + } + + switch (verbs[i].argc_cmp) { + + case EQUAL: + if (left != verbs[i].argc) { + log_error("Invalid number of arguments."); + return -EINVAL; + } + + break; + + case MORE: + if (left < verbs[i].argc) { + log_error("Too few arguments."); + return -EINVAL; + } + + break; + + case LESS: + if (left > verbs[i].argc) { + log_error("Too many arguments."); + return -EINVAL; + } + + break; + + default: + assert_not_reached("Unknown comparison operator."); + } + + if (!bus) { + log_error("Failed to get D-Bus connection: %s", error->message); + return -EIO; + } + + return verbs[i].dispatch(bus, argv + optind, left); +} + +int main(int argc, char*argv[]) { + int r, retval = EXIT_FAILURE; + DBusConnection *bus = NULL; + DBusError error; + + dbus_error_init(&error); + + setlocale(LC_ALL, ""); + log_parse_environment(); + log_open(); + + r = parse_argv(argc, argv); + if (r < 0) + goto finish; + else if (r == 0) { + retval = EXIT_SUCCESS; + goto finish; + } + + if (arg_transport == TRANSPORT_NORMAL) + bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error); + else if (arg_transport == TRANSPORT_POLKIT) + bus_connect_system_polkit(&bus, &error); + else if (arg_transport == TRANSPORT_SSH) + bus_connect_system_ssh(NULL, arg_host, &bus, &error); + else + assert_not_reached("Uh, invalid transport..."); + + r = loginctl_main(bus, argc, argv, &error); + retval = r < 0 ? EXIT_FAILURE : r; + +finish: + if (bus) { + dbus_connection_flush(bus); + dbus_connection_close(bus); + dbus_connection_unref(bus); + } + + dbus_error_free(&error); + dbus_shutdown(); + + strv_free(arg_property); + + pager_close(); + + return retval; +} diff --git a/src/login/logind-acl.c b/src/login/logind-acl.c new file mode 100644 index 000000000..cb045a992 --- /dev/null +++ b/src/login/logind-acl.c @@ -0,0 +1,248 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +#include +#include +#include +#include +#include + +#include "logind-acl.h" +#include "util.h" +#include "acl-util.h" + +static int flush_acl(acl_t acl) { + acl_entry_t i; + int found; + bool changed = false; + + assert(acl); + + for (found = acl_get_entry(acl, ACL_FIRST_ENTRY, &i); + found > 0; + found = acl_get_entry(acl, ACL_NEXT_ENTRY, &i)) { + + acl_tag_t tag; + + if (acl_get_tag_type(i, &tag) < 0) + return -errno; + + if (tag != ACL_USER) + continue; + + if (acl_delete_entry(acl, i) < 0) + return -errno; + + changed = true; + } + + if (found < 0) + return -errno; + + return changed; +} + +int devnode_acl(const char *path, + bool flush, + bool del, uid_t old_uid, + bool add, uid_t new_uid) { + + acl_t acl; + int r = 0; + bool changed = false; + + assert(path); + + acl = acl_get_file(path, ACL_TYPE_ACCESS); + if (!acl) + return -errno; + + if (flush) { + + r = flush_acl(acl); + if (r < 0) + goto finish; + if (r > 0) + changed = true; + + } else if (del && old_uid > 0) { + acl_entry_t entry; + + r = acl_find_uid(acl, old_uid, &entry); + if (r < 0) + goto finish; + + if (r > 0) { + if (acl_delete_entry(acl, entry) < 0) { + r = -errno; + goto finish; + } + + changed = true; + } + } + + if (add && new_uid > 0) { + acl_entry_t entry; + acl_permset_t permset; + int rd, wt; + + r = acl_find_uid(acl, new_uid, &entry); + if (r < 0) + goto finish; + + if (r == 0) { + if (acl_create_entry(&acl, &entry) < 0) { + r = -errno; + goto finish; + } + + if (acl_set_tag_type(entry, ACL_USER) < 0 || + acl_set_qualifier(entry, &new_uid) < 0) { + r = -errno; + goto finish; + } + } + + if (acl_get_permset(entry, &permset) < 0) { + r = -errno; + goto finish; + } + + rd = acl_get_perm(permset, ACL_READ); + if (rd < 0) { + r = -errno; + goto finish; + } + + wt = acl_get_perm(permset, ACL_WRITE); + if (wt < 0) { + r = -errno; + goto finish; + } + + if (!rd || !wt) { + + if (acl_add_perm(permset, ACL_READ|ACL_WRITE) < 0) { + r = -errno; + goto finish; + } + + changed = true; + } + } + + if (!changed) + goto finish; + + if (acl_calc_mask(&acl) < 0) { + r = -errno; + goto finish; + } + + if (acl_set_file(path, ACL_TYPE_ACCESS, acl) < 0) { + r = -errno; + goto finish; + } + + r = 0; + +finish: + acl_free(acl); + + return r; +} + +int devnode_acl_all(struct udev *udev, + const char *seat, + bool flush, + bool del, uid_t old_uid, + bool add, uid_t new_uid) { + + struct udev_list_entry *item = NULL, *first = NULL; + struct udev_enumerate *e; + int r; + + assert(udev); + + if (isempty(seat)) + seat = "seat0"; + + e = udev_enumerate_new(udev); + if (!e) + return -ENOMEM; + + /* We can only match by one tag in libudev. We choose + * "uaccess" for that. If we could match for two tags here we + * could add the seat name as second match tag, but this would + * be hardly optimizable in libudev, and hence checking the + * second tag manually in our loop is a good solution. */ + + r = udev_enumerate_add_match_tag(e, "uaccess"); + if (r < 0) + goto finish; + + r = udev_enumerate_scan_devices(e); + if (r < 0) + goto finish; + + first = udev_enumerate_get_list_entry(e); + udev_list_entry_foreach(item, first) { + struct udev_device *d; + const char *node, *sn; + + d = udev_device_new_from_syspath(udev, udev_list_entry_get_name(item)); + if (!d) { + r = -ENOMEM; + goto finish; + } + + sn = udev_device_get_property_value(d, "ID_SEAT"); + if (isempty(sn)) + sn = "seat0"; + + if (!streq(seat, sn)) { + udev_device_unref(d); + continue; + } + + node = udev_device_get_devnode(d); + if (!node) { + /* In case people mistag devices with nodes, we need to ignore this */ + udev_device_unref(d); + continue; + } + + log_debug("Fixing up %s for seat %s...", node, sn); + + r = devnode_acl(node, flush, del, old_uid, add, new_uid); + udev_device_unref(d); + + if (r < 0) + goto finish; + } + +finish: + if (e) + udev_enumerate_unref(e); + + return r; +} diff --git a/src/login/logind-acl.h b/src/login/logind-acl.h new file mode 100644 index 000000000..ec09843a7 --- /dev/null +++ b/src/login/logind-acl.h @@ -0,0 +1,57 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +#include +#include +#include + +#ifdef HAVE_ACL + +int devnode_acl(const char *path, + bool flush, + bool del, uid_t old_uid, + bool add, uid_t new_uid); + +int devnode_acl_all(struct udev *udev, + const char *seat, + bool flush, + bool del, uid_t old_uid, + bool add, uid_t new_uid); +#else + +static inline int devnode_acl(const char *path, + bool flush, + bool del, uid_t old_uid, + bool add, uid_t new_uid) { + return 0; +} + +static inline int devnode_acl_all(struct udev *udev, + const char *seat, + bool flush, + bool del, uid_t old_uid, + bool add, uid_t new_uid) { + return 0; +} + +#endif diff --git a/src/login/logind-action.c b/src/login/logind-action.c new file mode 100644 index 000000000..e1517d6ac --- /dev/null +++ b/src/login/logind-action.c @@ -0,0 +1,141 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + +#include + +#include "conf-parser.h" +#include "special.h" +#include "dbus-common.h" +#include "logind-action.h" + +int manager_handle_action( + Manager *m, + InhibitWhat inhibit_key, + HandleAction handle, + bool ignore_inhibited, + bool is_edge) { + + static const char * const message_table[_HANDLE_ACTION_MAX] = { + [HANDLE_POWEROFF] = "Powering Off...", + [HANDLE_REBOOT] = "Rebooting...", + [HANDLE_HALT] = "Halting...", + [HANDLE_KEXEC] = "Rebooting via kexec...", + [HANDLE_SUSPEND] = "Suspending...", + [HANDLE_HIBERNATE] = "Hibernating...", + [HANDLE_HYBRID_SLEEP] = "Hibernating and suspending..." + }; + + static const char * const target_table[_HANDLE_ACTION_MAX] = { + [HANDLE_POWEROFF] = SPECIAL_POWEROFF_TARGET, + [HANDLE_REBOOT] = SPECIAL_REBOOT_TARGET, + [HANDLE_HALT] = SPECIAL_HALT_TARGET, + [HANDLE_KEXEC] = SPECIAL_KEXEC_TARGET, + [HANDLE_SUSPEND] = SPECIAL_SUSPEND_TARGET, + [HANDLE_HIBERNATE] = SPECIAL_HIBERNATE_TARGET, + [HANDLE_HYBRID_SLEEP] = SPECIAL_HYBRID_SLEEP_TARGET + }; + + DBusError error; + int r; + InhibitWhat inhibit_operation; + bool supported = true; + + assert(m); + + /* If the key handling is turned off, don't do anything */ + if (handle == HANDLE_IGNORE) { + log_debug("Refusing operation, as it is turned off."); + return 0; + } + + if (handle == HANDLE_SUSPEND) + supported = can_sleep("mem") > 0; + else if (handle == HANDLE_HIBERNATE) + supported = can_sleep("disk") > 0; + else if (handle == HANDLE_HYBRID_SLEEP) + supported = can_sleep("disk") > 0 && can_sleep_disk("suspend") > 0; + else if (handle == HANDLE_KEXEC) + supported = access("/sbin/kexec", X_OK) >= 0; + + if (!supported) { + log_warning("Requested operation not supported, ignoring."); + return -ENOTSUP; + } + + /* If the key handling is inhibited, don't do anything */ + if (inhibit_key > 0) { + if (manager_is_inhibited(m, inhibit_key, INHIBIT_BLOCK, NULL, true, false, 0)) { + log_debug("Refusing operation, %s is inhibited.", inhibit_what_to_string(inhibit_key)); + return 0; + } + } + + /* Locking is handled differently from the rest. */ + if (handle == HANDLE_LOCK) { + log_info("Locking sessions..."); + session_send_lock_all(m, true); + return 1; + } + + inhibit_operation = handle == HANDLE_SUSPEND || handle == HANDLE_HIBERNATE || handle == HANDLE_HYBRID_SLEEP ? INHIBIT_SLEEP : INHIBIT_SHUTDOWN; + + /* If the actual operation is inhibited, warn and fail */ + if (!ignore_inhibited && + manager_is_inhibited(m, inhibit_operation, INHIBIT_BLOCK, NULL, false, false, 0)) { + + /* If this is just a recheck of the lid switch then don't warn about anything */ + if (!is_edge) { + log_debug("Refusing operation, %s is inhibited.", inhibit_what_to_string(inhibit_operation)); + return 0; + } + + log_error("Refusing operation, %s is inhibited.", inhibit_what_to_string(inhibit_operation)); + warn_melody(); + return -EPERM; + } + + log_info("%s", message_table[handle]); + + dbus_error_init(&error); + r = bus_manager_shutdown_or_sleep_now_or_later(m, target_table[handle], inhibit_operation, &error); + if (r < 0) { + log_error("Failed to execute operation: %s", bus_error_message(&error)); + dbus_error_free(&error); + return r; + } + + return 1; +} + +static const char* const handle_action_table[_HANDLE_ACTION_MAX] = { + [HANDLE_IGNORE] = "ignore", + [HANDLE_POWEROFF] = "poweroff", + [HANDLE_REBOOT] = "reboot", + [HANDLE_HALT] = "halt", + [HANDLE_KEXEC] = "kexec", + [HANDLE_SUSPEND] = "suspend", + [HANDLE_HIBERNATE] = "hibernate", + [HANDLE_HYBRID_SLEEP] = "hybrid-sleep", + [HANDLE_LOCK] = "lock" +}; + +DEFINE_STRING_TABLE_LOOKUP(handle_action, HandleAction); +DEFINE_CONFIG_PARSE_ENUM(config_parse_handle_action, handle_action, HandleAction, "Failed to parse handle action setting"); diff --git a/src/login/logind-action.h b/src/login/logind-action.h new file mode 100644 index 000000000..7ab44644f --- /dev/null +++ b/src/login/logind-action.h @@ -0,0 +1,54 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foologindactionhfoo +#define foologindactionhfoo + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + +typedef enum HandleAction { + HANDLE_IGNORE, + HANDLE_POWEROFF, + HANDLE_REBOOT, + HANDLE_HALT, + HANDLE_KEXEC, + HANDLE_SUSPEND, + HANDLE_HIBERNATE, + HANDLE_HYBRID_SLEEP, + HANDLE_LOCK, + _HANDLE_ACTION_MAX, + _HANDLE_ACTION_INVALID = -1 +} HandleAction; + +#include "logind.h" +#include "logind-inhibit.h" + +int manager_handle_action( + Manager *m, + InhibitWhat inhibit_key, + HandleAction handle, + bool ignore_inhibited, + bool is_edge); + +const char* handle_action_to_string(HandleAction h); +HandleAction handle_action_from_string(const char *s); + +int config_parse_handle_action(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); + +#endif diff --git a/src/login/logind-button.c b/src/login/logind-button.c new file mode 100644 index 000000000..dbf3d3c44 --- /dev/null +++ b/src/login/logind-button.c @@ -0,0 +1,241 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "conf-parser.h" +#include "util.h" +#include "logind-button.h" +#include "special.h" +#include "dbus-common.h" + +Button* button_new(Manager *m, const char *name) { + Button *b; + + assert(m); + assert(name); + + b = new0(Button, 1); + if (!b) + return NULL; + + b->name = strdup(name); + if (!b->name) { + free(b); + return NULL; + } + + if (hashmap_put(m->buttons, b->name, b) < 0) { + free(b->name); + free(b); + return NULL; + } + + b->manager = m; + b->fd = -1; + + return b; +} + +void button_free(Button *b) { + assert(b); + + hashmap_remove(b->manager->buttons, b->name); + + if (b->fd >= 0) { + hashmap_remove(b->manager->button_fds, INT_TO_PTR(b->fd + 1)); + assert_se(epoll_ctl(b->manager->epoll_fd, EPOLL_CTL_DEL, b->fd, NULL) == 0); + close_nointr_nofail(b->fd); + } + + free(b->name); + free(b->seat); + free(b); +} + +int button_set_seat(Button *b, const char *sn) { + char *s; + + assert(b); + assert(sn); + + s = strdup(sn); + if (!s) + return -ENOMEM; + + free(b->seat); + b->seat = s; + + return 0; +} + +int button_open(Button *b) { + char name[256], *p; + struct epoll_event ev; + int r; + + assert(b); + + if (b->fd >= 0) { + close_nointr_nofail(b->fd); + b->fd = -1; + } + + p = strappend("/dev/input/", b->name); + if (!p) + return log_oom(); + + b->fd = open(p, O_RDWR|O_CLOEXEC|O_NOCTTY|O_NONBLOCK); + free(p); + if (b->fd < 0) { + log_warning("Failed to open %s: %m", b->name); + return -errno; + } + + if (ioctl(b->fd, EVIOCGNAME(sizeof(name)), name) < 0) { + log_error("Failed to get input name: %m"); + r = -errno; + goto fail; + } + + zero(ev); + ev.events = EPOLLIN; + ev.data.u32 = FD_OTHER_BASE + b->fd; + + if (epoll_ctl(b->manager->epoll_fd, EPOLL_CTL_ADD, b->fd, &ev) < 0) { + log_error("Failed to add to epoll: %m"); + r = -errno; + goto fail; + } + + r = hashmap_put(b->manager->button_fds, INT_TO_PTR(b->fd + 1), b); + if (r < 0) { + log_error("Failed to add to hash map: %s", strerror(-r)); + assert_se(epoll_ctl(b->manager->epoll_fd, EPOLL_CTL_DEL, b->fd, NULL) == 0); + goto fail; + } + + log_info("Watching system buttons on /dev/input/%s (%s)", b->name, name); + + return 0; + +fail: + close_nointr_nofail(b->fd); + b->fd = -1; + return r; +} + +static int button_handle( + Button *b, + InhibitWhat inhibit_key, + HandleAction handle, + bool ignore_inhibited, + bool is_edge) { + + int r; + + assert(b); + + r = manager_handle_action(b->manager, inhibit_key, handle, ignore_inhibited, is_edge); + if (r > 0) + /* We are executing the operation, so make sure we don't + * execute another one until the lid is opened/closed again */ + b->lid_close_queued = false; + + return r; +} + +int button_process(Button *b) { + struct input_event ev; + ssize_t l; + + assert(b); + + l = read(b->fd, &ev, sizeof(ev)); + if (l < 0) + return errno != EAGAIN ? -errno : 0; + if ((size_t) l < sizeof(ev)) + return -EIO; + + if (ev.type == EV_KEY && ev.value > 0) { + + switch (ev.code) { + + case KEY_POWER: + case KEY_POWER2: + log_info("Power key pressed."); + return button_handle(b, INHIBIT_HANDLE_POWER_KEY, b->manager->handle_power_key, b->manager->power_key_ignore_inhibited, true); + + /* The kernel is a bit confused here: + + KEY_SLEEP = suspend-to-ram, which everybody else calls "suspend" + KEY_SUSPEND = suspend-to-disk, which everybody else calls "hibernate" + */ + + case KEY_SLEEP: + log_info("Suspend key pressed."); + return button_handle(b, INHIBIT_HANDLE_SUSPEND_KEY, b->manager->handle_suspend_key, b->manager->suspend_key_ignore_inhibited, true); + + case KEY_SUSPEND: + log_info("Hibernate key pressed."); + return button_handle(b, INHIBIT_HANDLE_HIBERNATE_KEY, b->manager->handle_hibernate_key, b->manager->hibernate_key_ignore_inhibited, true); + } + + } else if (ev.type == EV_SW && ev.value > 0) { + + switch (ev.code) { + + case SW_LID: + log_info("Lid closed."); + b->lid_close_queued = true; + + return button_handle(b, INHIBIT_HANDLE_LID_SWITCH, b->manager->handle_lid_switch, b->manager->lid_switch_ignore_inhibited, true); + } + + } else if (ev.type == EV_SW && ev.value == 0) { + + switch (ev.code) { + + case SW_LID: + log_info("Lid opened."); + b->lid_close_queued = false; + break; + } + } + + return 0; +} + +int button_recheck(Button *b) { + assert(b); + + if (!b->lid_close_queued) + return 0; + + return button_handle(b, INHIBIT_HANDLE_LID_SWITCH, b->manager->handle_lid_switch, b->manager->lid_switch_ignore_inhibited, false); +} diff --git a/src/login/logind-button.h b/src/login/logind-button.h new file mode 100644 index 000000000..1c5a84553 --- /dev/null +++ b/src/login/logind-button.h @@ -0,0 +1,48 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foologindbuttonhfoo +#define foologindbuttonhfoo + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + +typedef struct Button Button; + +#include "list.h" +#include "util.h" +#include "logind.h" + +struct Button { + Manager *manager; + + char *name; + char *seat; + int fd; + + bool lid_close_queued; +}; + +Button* button_new(Manager *m, const char *name); +void button_free(Button*b); +int button_open(Button *b); +int button_process(Button *b); +int button_recheck(Button *b); +int button_set_seat(Button *b, const char *sn); + +#endif diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c new file mode 100644 index 000000000..77a06f2ce --- /dev/null +++ b/src/login/logind-dbus.c @@ -0,0 +1,2393 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +#include +#include +#include +#include + +#include "logind.h" +#include "dbus-common.h" +#include "strv.h" +#include "mkdir.h" +#include "path-util.h" +#include "polkit.h" +#include "special.h" +#include "systemd/sd-id128.h" +#include "systemd/sd-messages.h" + +#define BUS_MANAGER_INTERFACE \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" + +#define INTROSPECTION_BEGIN \ + DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \ + "\n" \ + BUS_MANAGER_INTERFACE \ + BUS_PROPERTIES_INTERFACE \ + BUS_PEER_INTERFACE \ + BUS_INTROSPECTABLE_INTERFACE + +#define INTROSPECTION_END \ + "\n" + +#define INTERFACES_LIST \ + BUS_GENERIC_INTERFACES_LIST \ + "org.freedesktop.login1.Manager\0" + +static int bus_manager_append_idle_hint(DBusMessageIter *i, const char *property, void *data) { + Manager *m = data; + dbus_bool_t b; + + assert(i); + assert(property); + assert(m); + + b = manager_get_idle_hint(m, NULL) > 0; + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b)) + return -ENOMEM; + + return 0; +} + +static int bus_manager_append_idle_hint_since(DBusMessageIter *i, const char *property, void *data) { + Manager *m = data; + dual_timestamp t; + uint64_t u; + + assert(i); + assert(property); + assert(m); + + manager_get_idle_hint(m, &t); + u = streq(property, "IdleSinceHint") ? t.realtime : t.monotonic; + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_UINT64, &u)) + return -ENOMEM; + + return 0; +} + +static int bus_manager_append_inhibited(DBusMessageIter *i, const char *property, void *data) { + Manager *m = data; + InhibitWhat w; + const char *p; + + w = manager_inhibit_what(m, streq(property, "BlockInhibited") ? INHIBIT_BLOCK : INHIBIT_DELAY); + p = inhibit_what_to_string(w); + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &p)) + return -ENOMEM; + + return 0; +} + +static int bus_manager_append_preparing(DBusMessageIter *i, const char *property, void *data) { + Manager *m = data; + dbus_bool_t b; + + assert(i); + assert(property); + + if (streq(property, "PreparingForShutdown")) + b = !!(m->delayed_what & INHIBIT_SHUTDOWN); + else + b = !!(m->delayed_what & INHIBIT_SLEEP); + + dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b); + return 0; +} + +static int bus_manager_create_session(Manager *m, DBusMessage *message, DBusMessage **_reply) { + Session *session = NULL; + User *user = NULL; + const char *type, *class, *seat, *tty, *display, *remote_user, *remote_host, *service; + uint32_t uid, leader, audit_id = 0; + dbus_bool_t remote, kill_processes, exists; + char **controllers = NULL, **reset_controllers = NULL; + SessionType t; + SessionClass c; + Seat *s; + DBusMessageIter iter; + int r; + char *id = NULL, *p; + uint32_t vtnr = 0; + int fifo_fd = -1; + DBusMessage *reply = NULL; + bool b; + + assert(m); + assert(message); + assert(_reply); + + if (!dbus_message_iter_init(message, &iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_UINT32) + return -EINVAL; + + dbus_message_iter_get_basic(&iter, &uid); + + if (!dbus_message_iter_next(&iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_UINT32) + return -EINVAL; + + dbus_message_iter_get_basic(&iter, &leader); + + if (leader <= 0 || + !dbus_message_iter_next(&iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) + return -EINVAL; + + dbus_message_iter_get_basic(&iter, &service); + + if (!dbus_message_iter_next(&iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) + return -EINVAL; + + dbus_message_iter_get_basic(&iter, &type); + t = session_type_from_string(type); + + if (t < 0 || + !dbus_message_iter_next(&iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) + return -EINVAL; + + dbus_message_iter_get_basic(&iter, &class); + if (isempty(class)) + c = SESSION_USER; + else + c = session_class_from_string(class); + + if (c < 0 || + !dbus_message_iter_next(&iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) + return -EINVAL; + + dbus_message_iter_get_basic(&iter, &seat); + + if (isempty(seat)) + s = NULL; + else { + s = hashmap_get(m->seats, seat); + if (!s) + return -ENOENT; + } + + if (!dbus_message_iter_next(&iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_UINT32) + return -EINVAL; + + dbus_message_iter_get_basic(&iter, &vtnr); + + if (!dbus_message_iter_next(&iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) + return -EINVAL; + + dbus_message_iter_get_basic(&iter, &tty); + + if (tty_is_vc(tty)) { + int v; + + if (!s) + s = m->vtconsole; + else if (s != m->vtconsole) + return -EINVAL; + + v = vtnr_from_tty(tty); + + if (v <= 0) + return v < 0 ? v : -EINVAL; + + if (vtnr <= 0) + vtnr = (uint32_t) v; + else if (vtnr != (uint32_t) v) + return -EINVAL; + } else if (tty_is_console(tty)) { + + if (!s) + s = m->vtconsole; + else if (s != m->vtconsole) + return -EINVAL; + + if (vtnr != 0) + return -EINVAL; + + } + + if (s) { + if (seat_can_multi_session(s)) { + if (vtnr > 63) + return -EINVAL; + } else { + if (vtnr != 0) + return -EINVAL; + } + } + + if (!dbus_message_iter_next(&iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) + return -EINVAL; + + dbus_message_iter_get_basic(&iter, &display); + + if (!dbus_message_iter_next(&iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_BOOLEAN) + return -EINVAL; + + dbus_message_iter_get_basic(&iter, &remote); + + if (!dbus_message_iter_next(&iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) + return -EINVAL; + + dbus_message_iter_get_basic(&iter, &remote_user); + + if (!dbus_message_iter_next(&iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) + return -EINVAL; + + dbus_message_iter_get_basic(&iter, &remote_host); + + if (!dbus_message_iter_next(&iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY || + dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_STRING) + return -EINVAL; + + r = bus_parse_strv_iter(&iter, &controllers); + if (r < 0) + return -EINVAL; + + if (strv_contains(controllers, "systemd") || + !dbus_message_iter_next(&iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY || + dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_STRING) { + r = -EINVAL; + goto fail; + } + + r = bus_parse_strv_iter(&iter, &reset_controllers); + if (r < 0) + goto fail; + + if (strv_contains(reset_controllers, "systemd") || + !dbus_message_iter_next(&iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_BOOLEAN) { + r = -EINVAL; + goto fail; + } + + dbus_message_iter_get_basic(&iter, &kill_processes); + + r = manager_add_user_by_uid(m, uid, &user); + if (r < 0) + goto fail; + + audit_session_from_pid(leader, &audit_id); + + if (audit_id > 0) { + asprintf(&id, "%lu", (unsigned long) audit_id); + + if (!id) { + r = -ENOMEM; + goto fail; + } + + session = hashmap_get(m->sessions, id); + + if (session) { + free(id); + + fifo_fd = session_create_fifo(session); + if (fifo_fd < 0) { + r = fifo_fd; + goto fail; + } + + /* Session already exists, client is probably + * something like "su" which changes uid but + * is still the same audit session */ + + reply = dbus_message_new_method_return(message); + if (!reply) { + r = -ENOMEM; + goto fail; + } + + p = session_bus_path(session); + if (!p) { + r = -ENOMEM; + goto fail; + } + + seat = session->seat ? session->seat->id : ""; + vtnr = session->vtnr; + exists = true; + + b = dbus_message_append_args( + reply, + DBUS_TYPE_STRING, &session->id, + DBUS_TYPE_OBJECT_PATH, &p, + DBUS_TYPE_STRING, &session->user->runtime_path, + DBUS_TYPE_UNIX_FD, &fifo_fd, + DBUS_TYPE_STRING, &seat, + DBUS_TYPE_UINT32, &vtnr, + DBUS_TYPE_BOOLEAN, &exists, + DBUS_TYPE_INVALID); + free(p); + + if (!b) { + r = -ENOMEM; + goto fail; + } + + close_nointr_nofail(fifo_fd); + *_reply = reply; + + strv_free(controllers); + strv_free(reset_controllers); + + return 0; + } + + } else { + do { + free(id); + id = NULL; + + if (asprintf(&id, "c%lu", ++m->session_counter) < 0) { + r = -ENOMEM; + goto fail; + } + + } while (hashmap_get(m->sessions, id)); + } + + r = manager_add_session(m, user, id, &session); + free(id); + if (r < 0) + goto fail; + + session->leader = leader; + session->audit_id = audit_id; + session->type = t; + session->class = c; + session->remote = remote; + session->controllers = controllers; + session->reset_controllers = reset_controllers; + session->kill_processes = kill_processes; + session->vtnr = vtnr; + + controllers = reset_controllers = NULL; + + if (!isempty(tty)) { + session->tty = strdup(tty); + if (!session->tty) { + r = -ENOMEM; + goto fail; + } + } + + if (!isempty(display)) { + session->display = strdup(display); + if (!session->display) { + r = -ENOMEM; + goto fail; + } + } + + if (!isempty(remote_user)) { + session->remote_user = strdup(remote_user); + if (!session->remote_user) { + r = -ENOMEM; + goto fail; + } + } + + if (!isempty(remote_host)) { + session->remote_host = strdup(remote_host); + if (!session->remote_host) { + r = -ENOMEM; + goto fail; + } + } + + if (!isempty(service)) { + session->service = strdup(service); + if (!session->service) { + r = -ENOMEM; + goto fail; + } + } + + fifo_fd = session_create_fifo(session); + if (fifo_fd < 0) { + r = fifo_fd; + goto fail; + } + + if (s) { + r = seat_attach_session(s, session); + if (r < 0) + goto fail; + } + + r = session_start(session); + if (r < 0) + goto fail; + + reply = dbus_message_new_method_return(message); + if (!reply) { + r = -ENOMEM; + goto fail; + } + + p = session_bus_path(session); + if (!p) { + r = -ENOMEM; + goto fail; + } + + seat = s ? s->id : ""; + exists = false; + b = dbus_message_append_args( + reply, + DBUS_TYPE_STRING, &session->id, + DBUS_TYPE_OBJECT_PATH, &p, + DBUS_TYPE_STRING, &session->user->runtime_path, + DBUS_TYPE_UNIX_FD, &fifo_fd, + DBUS_TYPE_STRING, &seat, + DBUS_TYPE_UINT32, &vtnr, + DBUS_TYPE_BOOLEAN, &exists, + DBUS_TYPE_INVALID); + free(p); + + if (!b) { + r = -ENOMEM; + goto fail; + } + + close_nointr_nofail(fifo_fd); + *_reply = reply; + + return 0; + +fail: + strv_free(controllers); + strv_free(reset_controllers); + + if (session) + session_add_to_gc_queue(session); + + if (user) + user_add_to_gc_queue(user); + + if (fifo_fd >= 0) + close_nointr_nofail(fifo_fd); + + if (reply) + dbus_message_unref(reply); + + return r; +} + +static int bus_manager_inhibit(Manager *m, DBusConnection *connection, DBusMessage *message, DBusError *error, DBusMessage **_reply) { + Inhibitor *i = NULL; + char *id = NULL; + const char *who, *why, *what, *mode; + pid_t pid; + InhibitWhat w; + InhibitMode mm; + unsigned long ul; + int r, fifo_fd = -1; + DBusMessage *reply = NULL; + + assert(m); + assert(connection); + assert(message); + assert(error); + assert(_reply); + + if (!dbus_message_get_args( + message, + error, + DBUS_TYPE_STRING, &what, + DBUS_TYPE_STRING, &who, + DBUS_TYPE_STRING, &why, + DBUS_TYPE_STRING, &mode, + DBUS_TYPE_INVALID)) { + r = -EIO; + goto fail; + } + + w = inhibit_what_from_string(what); + if (w <= 0) { + r = -EINVAL; + goto fail; + } + + mm = inhibit_mode_from_string(mode); + if (mm < 0) { + r = -EINVAL; + goto fail; + } + + /* Delay is only supported for shutdown/sleep */ + if (mm == INHIBIT_DELAY && (w & ~(INHIBIT_SHUTDOWN|INHIBIT_SLEEP))) { + r = -EINVAL; + goto fail; + } + + r = verify_polkit(connection, message, + w == INHIBIT_SHUTDOWN ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-shutdown" : "org.freedesktop.login1.inhibit-delay-shutdown") : + w == INHIBIT_SLEEP ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-sleep" : "org.freedesktop.login1.inhibit-delay-sleep") : + w == INHIBIT_IDLE ? "org.freedesktop.login1.inhibit-block-idle" : + w == INHIBIT_HANDLE_POWER_KEY ? "org.freedesktop.login1.inhibit-handle-power-key" : + w == INHIBIT_HANDLE_SUSPEND_KEY ? "org.freedesktop.login1.inhibit-handle-suspend-key" : + w == INHIBIT_HANDLE_HIBERNATE_KEY ? "org.freedesktop.login1.inhibit-handle-hibernate-key" : + "org.freedesktop.login1.inhibit-handle-lid-switch", + false, NULL, error); + if (r < 0) + goto fail; + + ul = dbus_bus_get_unix_user(connection, dbus_message_get_sender(message), error); + if (ul == (unsigned long) -1) { + r = -EIO; + goto fail; + } + + pid = bus_get_unix_process_id(connection, dbus_message_get_sender(message), error); + if (pid <= 0) { + r = -EIO; + goto fail; + } + + do { + free(id); + id = NULL; + + if (asprintf(&id, "%lu", ++m->inhibit_counter) < 0) { + r = -ENOMEM; + goto fail; + } + } while (hashmap_get(m->inhibitors, id)); + + r = manager_add_inhibitor(m, id, &i); + free(id); + + if (r < 0) + goto fail; + + i->what = w; + i->mode = mm; + i->pid = pid; + i->uid = (uid_t) ul; + i->why = strdup(why); + i->who = strdup(who); + + if (!i->why || !i->who) { + r = -ENOMEM; + goto fail; + } + + fifo_fd = inhibitor_create_fifo(i); + if (fifo_fd < 0) { + r = fifo_fd; + goto fail; + } + + reply = dbus_message_new_method_return(message); + if (!reply) { + r = -ENOMEM; + goto fail; + } + + if (!dbus_message_append_args( + reply, + DBUS_TYPE_UNIX_FD, &fifo_fd, + DBUS_TYPE_INVALID)) { + r = -ENOMEM; + goto fail; + } + + close_nointr_nofail(fifo_fd); + *_reply = reply; + + inhibitor_start(i); + + return 0; + +fail: + if (i) + inhibitor_free(i); + + if (fifo_fd >= 0) + close_nointr_nofail(fifo_fd); + + if (reply) + dbus_message_unref(reply); + + return r; +} + +static int trigger_device(Manager *m, struct udev_device *d) { + struct udev_enumerate *e; + struct udev_list_entry *first, *item; + int r; + + assert(m); + + e = udev_enumerate_new(m->udev); + if (!e) { + r = -ENOMEM; + goto finish; + } + + if (d) { + if (udev_enumerate_add_match_parent(e, d) < 0) { + r = -EIO; + goto finish; + } + } + + if (udev_enumerate_scan_devices(e) < 0) { + r = -EIO; + goto finish; + } + + first = udev_enumerate_get_list_entry(e); + udev_list_entry_foreach(item, first) { + char *t; + const char *p; + + p = udev_list_entry_get_name(item); + + t = strappend(p, "/uevent"); + if (!t) { + r = -ENOMEM; + goto finish; + } + + write_one_line_file(t, "change"); + free(t); + } + + r = 0; + +finish: + if (e) + udev_enumerate_unref(e); + + return r; +} + +static int attach_device(Manager *m, const char *seat, const char *sysfs) { + struct udev_device *d; + char *rule = NULL, *file = NULL; + const char *id_for_seat; + int r; + + assert(m); + assert(seat); + assert(sysfs); + + d = udev_device_new_from_syspath(m->udev, sysfs); + if (!d) + return -ENODEV; + + if (!udev_device_has_tag(d, "seat")) { + r = -ENODEV; + goto finish; + } + + id_for_seat = udev_device_get_property_value(d, "ID_FOR_SEAT"); + if (!id_for_seat) { + r = -ENODEV; + goto finish; + } + + if (asprintf(&file, "/etc/udev/rules.d/72-seat-%s.rules", id_for_seat) < 0) { + r = -ENOMEM; + goto finish; + } + + if (asprintf(&rule, "TAG==\"seat\", ENV{ID_FOR_SEAT}==\"%s\", ENV{ID_SEAT}=\"%s\"", id_for_seat, seat) < 0) { + r = -ENOMEM; + goto finish; + } + + mkdir_p_label("/etc/udev/rules.d", 0755); + r = write_one_line_file_atomic(file, rule); + if (r < 0) + goto finish; + + r = trigger_device(m, d); + +finish: + free(rule); + free(file); + + if (d) + udev_device_unref(d); + + return r; +} + +static int flush_devices(Manager *m) { + DIR *d; + + assert(m); + + d = opendir("/etc/udev/rules.d"); + if (!d) { + if (errno != ENOENT) + log_warning("Failed to open /etc/udev/rules.d: %m"); + } else { + struct dirent *de; + + while ((de = readdir(d))) { + + if (!dirent_is_file(de)) + continue; + + if (!startswith(de->d_name, "72-seat-")) + continue; + + if (!endswith(de->d_name, ".rules")) + continue; + + if (unlinkat(dirfd(d), de->d_name, 0) < 0) + log_warning("Failed to unlink %s: %m", de->d_name); + } + + closedir(d); + } + + return trigger_device(m, NULL); +} + +static int have_multiple_sessions( + Manager *m, + uid_t uid) { + + Session *session; + Iterator i; + + assert(m); + + /* Check for other users' sessions. Greeter sessions do not count. */ + HASHMAP_FOREACH(session, m->sessions, i) + if (session->class == SESSION_USER && session->user->uid != uid) + return true; + + return false; +} + +static int send_start_unit(DBusConnection *connection, const char *unit_name, DBusError *error) { + const char *mode = "replace"; + + assert(unit_name); + + return bus_method_call_with_reply ( + connection, + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "StartUnit", + NULL, + NULL, + DBUS_TYPE_STRING, &unit_name, + DBUS_TYPE_STRING, &mode, + DBUS_TYPE_INVALID); +} + +static int send_prepare_for(Manager *m, InhibitWhat w, bool _active) { + static const char * const signal_name[_INHIBIT_WHAT_MAX] = { + [INHIBIT_SHUTDOWN] = "PrepareForShutdown", + [INHIBIT_SLEEP] = "PrepareForSleep" + }; + + dbus_bool_t active = _active; + DBusMessage *message; + int r = 0; + + assert(m); + assert(w >= 0); + assert(w < _INHIBIT_WHAT_MAX); + assert(signal_name[w]); + + message = dbus_message_new_signal("/org/freedesktop/login1", "org.freedesktop.login1.Manager", signal_name[w]); + if (!message) + return -ENOMEM; + + if (!dbus_message_append_args(message, DBUS_TYPE_BOOLEAN, &active, DBUS_TYPE_INVALID) || + !dbus_connection_send(m->bus, message, NULL)) + r = -ENOMEM; + + dbus_message_unref(message); + return r; +} + +static int delay_shutdown_or_sleep(Manager *m, InhibitWhat w, const char *unit_name) { + assert(m); + assert(w >= 0); + assert(w < _INHIBIT_WHAT_MAX); + + /* Tell everybody to prepare for shutdown/sleep */ + send_prepare_for(m, w, true); + + /* Update timestamp for timeout */ + if (!m->delayed_unit) + m->delayed_timestamp = now(CLOCK_MONOTONIC); + + /* Remember what we want to do, possibly overriding what kind + * of unit we previously queued. */ + m->delayed_unit = unit_name; + m->delayed_what = w; + + return 0; +} + +static int bus_manager_can_shutdown_or_sleep( + Manager *m, + DBusConnection *connection, + DBusMessage *message, + InhibitWhat w, + const char *action, + const char *action_multiple_sessions, + const char *action_ignore_inhibit, + const char *sleep_type, + const char *sleep_disk_type, + DBusError *error, + DBusMessage **_reply) { + + bool multiple_sessions, challenge, blocked, b; + const char *result; + DBusMessage *reply = NULL; + int r; + unsigned long ul; + + assert(m); + assert(connection); + assert(message); + assert(w >= 0); + assert(w <= _INHIBIT_WHAT_MAX); + assert(action); + assert(action_multiple_sessions); + assert(action_ignore_inhibit); + assert(error); + assert(_reply); + + if (sleep_type) { + r = can_sleep(sleep_type); + if (r < 0) + return r; + + if (r == 0) { + result = "na"; + goto finish; + } + } + + if (sleep_disk_type) { + r = can_sleep_disk(sleep_disk_type); + if (r < 0) + return r; + + if (r == 0) { + result = "na"; + goto finish; + } + } + + ul = dbus_bus_get_unix_user(connection, dbus_message_get_sender(message), error); + if (ul == (unsigned long) -1) + return -EIO; + + r = have_multiple_sessions(m, (uid_t) ul); + if (r < 0) + return r; + + multiple_sessions = r > 0; + blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, (uid_t) ul); + + if (multiple_sessions) { + r = verify_polkit(connection, message, action_multiple_sessions, false, &challenge, error); + if (r < 0) + return r; + + if (r > 0) + result = "yes"; + else if (challenge) + result = "challenge"; + else + result = "no"; + } + + if (blocked) { + r = verify_polkit(connection, message, action_ignore_inhibit, false, &challenge, error); + if (r < 0) + return r; + + if (r > 0 && !result) + result = "yes"; + else if (challenge && (!result || streq(result, "yes"))) + result = "challenge"; + else + result = "no"; + } + + if (!multiple_sessions && !blocked) { + /* If neither inhibit nor multiple sessions + * apply then just check the normal policy */ + + r = verify_polkit(connection, message, action, false, &challenge, error); + if (r < 0) + return r; + + if (r > 0) + result = "yes"; + else if (challenge) + result = "challenge"; + else + result = "no"; + } + +finish: + reply = dbus_message_new_method_return(message); + if (!reply) + return -ENOMEM; + + b = dbus_message_append_args( + reply, + DBUS_TYPE_STRING, &result, + DBUS_TYPE_INVALID); + if (!b) { + dbus_message_unref(reply); + return -ENOMEM; + } + + *_reply = reply; + return 0; +} + +static int bus_manager_log_shutdown( + Manager *m, + InhibitWhat w, + const char *unit_name) { + + const char *p, *q; + + assert(m); + assert(unit_name); + + if (w != INHIBIT_SHUTDOWN) + return 0; + + if (streq(unit_name, SPECIAL_POWEROFF_TARGET)) { + p = "MESSAGE=System is powering down."; + q = "SHUTDOWN=power-off"; + } else if (streq(unit_name, SPECIAL_HALT_TARGET)) { + p = "MESSAGE=System is halting."; + q = "SHUTDOWN=halt"; + } else if (streq(unit_name, SPECIAL_REBOOT_TARGET)) { + p = "MESSAGE=System is rebooting."; + q = "SHUTDOWN=reboot"; + } else if (streq(unit_name, SPECIAL_KEXEC_TARGET)) { + p = "MESSAGE=System is rebooting with kexec."; + q = "SHUTDOWN=kexec"; + } else { + p = "MESSAGE=System is shutting down."; + q = NULL; + } + + return log_struct(LOG_NOTICE, MESSAGE_ID(SD_MESSAGE_SHUTDOWN), + p, + q, NULL); +} + +int bus_manager_shutdown_or_sleep_now_or_later( + Manager *m, + const char *unit_name, + InhibitWhat w, + DBusError *error) { + + bool delayed; + int r; + + assert(m); + assert(unit_name); + assert(w >= 0); + assert(w <= _INHIBIT_WHAT_MAX); + + delayed = + m->inhibit_delay_max > 0 && + manager_is_inhibited(m, w, INHIBIT_DELAY, NULL, false, false, 0); + + if (delayed) + /* Shutdown is delayed, keep in mind what we + * want to do, and start a timeout */ + r = delay_shutdown_or_sleep(m, w, unit_name); + else { + bus_manager_log_shutdown(m, w, unit_name); + + /* Shutdown is not delayed, execute it + * immediately */ + r = send_start_unit(m->bus, unit_name, error); + } + + return r; +} + +static int bus_manager_do_shutdown_or_sleep( + Manager *m, + DBusConnection *connection, + DBusMessage *message, + const char *unit_name, + InhibitWhat w, + const char *action, + const char *action_multiple_sessions, + const char *action_ignore_inhibit, + const char *sleep_type, + const char *sleep_disk_type, + DBusError *error, + DBusMessage **_reply) { + + dbus_bool_t interactive; + bool multiple_sessions, blocked; + DBusMessage *reply = NULL; + int r; + unsigned long ul; + + assert(m); + assert(connection); + assert(message); + assert(unit_name); + assert(w >= 0); + assert(w <= _INHIBIT_WHAT_MAX); + assert(action); + assert(action_multiple_sessions); + assert(action_ignore_inhibit); + assert(error); + assert(_reply); + + if (!dbus_message_get_args( + message, + error, + DBUS_TYPE_BOOLEAN, &interactive, + DBUS_TYPE_INVALID)) + return -EINVAL; + + if (sleep_type) { + r = can_sleep(sleep_type); + if (r < 0) + return r; + + if (r == 0) + return -ENOTSUP; + } + + if (sleep_disk_type) { + r = can_sleep_disk(sleep_disk_type); + if (r < 0) + return r; + + if (r == 0) + return -ENOTSUP; + } + + ul = dbus_bus_get_unix_user(connection, dbus_message_get_sender(message), error); + if (ul == (unsigned long) -1) + return -EIO; + + r = have_multiple_sessions(m, (uid_t) ul); + if (r < 0) + return r; + + multiple_sessions = r > 0; + blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, (uid_t) ul); + + if (multiple_sessions) { + r = verify_polkit(connection, message, action_multiple_sessions, interactive, NULL, error); + if (r < 0) + return r; + } + + if (blocked) { + r = verify_polkit(connection, message, action_ignore_inhibit, interactive, NULL, error); + if (r < 0) + return r; + } + + if (!multiple_sessions && !blocked) { + r = verify_polkit(connection, message, action, interactive, NULL, error); + if (r < 0) + return r; + } + + r = bus_manager_shutdown_or_sleep_now_or_later(m, unit_name, w, error); + if (r < 0) + return r; + + reply = dbus_message_new_method_return(message); + if (!reply) + return -ENOMEM; + + *_reply = reply; + return 0; +} + +static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_manager_append_handle_action, handle_action, HandleAction); + +static const BusProperty bus_login_manager_properties[] = { + { "ControlGroupHierarchy", bus_property_append_string, "s", offsetof(Manager, cgroup_path), true }, + { "Controllers", bus_property_append_strv, "as", offsetof(Manager, controllers), true }, + { "ResetControllers", bus_property_append_strv, "as", offsetof(Manager, reset_controllers), true }, + { "NAutoVTs", bus_property_append_unsigned, "u", offsetof(Manager, n_autovts) }, + { "KillOnlyUsers", bus_property_append_strv, "as", offsetof(Manager, kill_only_users), true }, + { "KillExcludeUsers", bus_property_append_strv, "as", offsetof(Manager, kill_exclude_users), true }, + { "KillUserProcesses", bus_property_append_bool, "b", offsetof(Manager, kill_user_processes) }, + { "IdleHint", bus_manager_append_idle_hint, "b", 0 }, + { "IdleSinceHint", bus_manager_append_idle_hint_since, "t", 0 }, + { "IdleSinceHintMonotonic", bus_manager_append_idle_hint_since, "t", 0 }, + { "BlockInhibited", bus_manager_append_inhibited, "s", 0 }, + { "DelayInhibited", bus_manager_append_inhibited, "s", 0 }, + { "InhibitDelayMaxUSec", bus_property_append_usec, "t", offsetof(Manager, inhibit_delay_max) }, + { "HandlePowerKey", bus_manager_append_handle_action, "s", offsetof(Manager, handle_power_key) }, + { "HandleSuspendKey", bus_manager_append_handle_action, "s", offsetof(Manager, handle_suspend_key) }, + { "HandleHibernateKey", bus_manager_append_handle_action, "s", offsetof(Manager, handle_hibernate_key)}, + { "HandleLidSwitch", bus_manager_append_handle_action, "s", offsetof(Manager, handle_lid_switch) }, + { "IdleAction", bus_manager_append_handle_action, "s", offsetof(Manager, idle_action) }, + { "IdleActionUSec", bus_property_append_usec, "t", offsetof(Manager, idle_action_usec) }, + { "PreparingForShutdown", bus_manager_append_preparing, "b", 0 }, + { "PreparingForSleep", bus_manager_append_preparing, "b", 0 }, + { NULL, } +}; + +static DBusHandlerResult manager_message_handler( + DBusConnection *connection, + DBusMessage *message, + void *userdata) { + + Manager *m = userdata; + + DBusError error; + DBusMessage *reply = NULL; + int r; + + assert(connection); + assert(message); + assert(m); + + dbus_error_init(&error); + + if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "GetSession")) { + const char *name; + char *p; + Session *session; + bool b; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + session = hashmap_get(m->sessions, name); + if (!session) + return bus_send_error_reply(connection, message, &error, -ENOENT); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + p = session_bus_path(session); + if (!p) + goto oom; + + b = dbus_message_append_args( + reply, + DBUS_TYPE_OBJECT_PATH, &p, + DBUS_TYPE_INVALID); + free(p); + + if (!b) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "GetSessionByPID")) { + uint32_t pid; + char *p; + Session *session; + bool b; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_UINT32, &pid, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + r = manager_get_session_by_pid(m, pid, &session); + if (r <= 0) + return bus_send_error_reply(connection, message, NULL, r < 0 ? r : -ENOENT); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + p = session_bus_path(session); + if (!p) + goto oom; + + b = dbus_message_append_args( + reply, + DBUS_TYPE_OBJECT_PATH, &p, + DBUS_TYPE_INVALID); + free(p); + + if (!b) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "GetUser")) { + uint32_t uid; + char *p; + User *user; + bool b; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_UINT32, &uid, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + user = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid)); + if (!user) + return bus_send_error_reply(connection, message, &error, -ENOENT); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + p = user_bus_path(user); + if (!p) + goto oom; + + b = dbus_message_append_args( + reply, + DBUS_TYPE_OBJECT_PATH, &p, + DBUS_TYPE_INVALID); + free(p); + + if (!b) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "GetSeat")) { + const char *name; + char *p; + Seat *seat; + bool b; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + seat = hashmap_get(m->seats, name); + if (!seat) + return bus_send_error_reply(connection, message, &error, -ENOENT); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + p = seat_bus_path(seat); + if (!p) + goto oom; + + b = dbus_message_append_args( + reply, + DBUS_TYPE_OBJECT_PATH, &p, + DBUS_TYPE_INVALID); + free(p); + + if (!b) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "ListSessions")) { + char *p; + Session *session; + Iterator i; + DBusMessageIter iter, sub; + const char *empty = ""; + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + dbus_message_iter_init_append(reply, &iter); + + if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(susso)", &sub)) + goto oom; + + HASHMAP_FOREACH(session, m->sessions, i) { + DBusMessageIter sub2; + uint32_t uid; + + if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2)) + goto oom; + + uid = session->user->uid; + + p = session_bus_path(session); + if (!p) + goto oom; + + if (!dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &session->id) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT32, &uid) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &session->user->name) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, session->seat ? (const char**) &session->seat->id : &empty) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_OBJECT_PATH, &p)) { + free(p); + goto oom; + } + + free(p); + + if (!dbus_message_iter_close_container(&sub, &sub2)) + goto oom; + } + + if (!dbus_message_iter_close_container(&iter, &sub)) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "ListUsers")) { + char *p; + User *user; + Iterator i; + DBusMessageIter iter, sub; + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + dbus_message_iter_init_append(reply, &iter); + + if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(uso)", &sub)) + goto oom; + + HASHMAP_FOREACH(user, m->users, i) { + DBusMessageIter sub2; + uint32_t uid; + + if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2)) + goto oom; + + uid = user->uid; + + p = user_bus_path(user); + if (!p) + goto oom; + + if (!dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT32, &uid) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &user->name) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_OBJECT_PATH, &p)) { + free(p); + goto oom; + } + + free(p); + + if (!dbus_message_iter_close_container(&sub, &sub2)) + goto oom; + } + + if (!dbus_message_iter_close_container(&iter, &sub)) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "ListSeats")) { + char *p; + Seat *seat; + Iterator i; + DBusMessageIter iter, sub; + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + dbus_message_iter_init_append(reply, &iter); + + if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(so)", &sub)) + goto oom; + + HASHMAP_FOREACH(seat, m->seats, i) { + DBusMessageIter sub2; + + if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2)) + goto oom; + + p = seat_bus_path(seat); + if (!p) + goto oom; + + if (!dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &seat->id) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_OBJECT_PATH, &p)) { + free(p); + goto oom; + } + + free(p); + + if (!dbus_message_iter_close_container(&sub, &sub2)) + goto oom; + } + + if (!dbus_message_iter_close_container(&iter, &sub)) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "ListInhibitors")) { + Inhibitor *inhibitor; + Iterator i; + DBusMessageIter iter, sub; + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + dbus_message_iter_init_append(reply, &iter); + + if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(ssssuu)", &sub)) + goto oom; + + HASHMAP_FOREACH(inhibitor, m->inhibitors, i) { + DBusMessageIter sub2; + dbus_uint32_t uid, pid; + const char *what, *who, *why, *mode; + + if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2)) + goto oom; + + what = strempty(inhibit_what_to_string(inhibitor->what)); + who = strempty(inhibitor->who); + why = strempty(inhibitor->why); + mode = strempty(inhibit_mode_to_string(inhibitor->mode)); + uid = (dbus_uint32_t) inhibitor->uid; + pid = (dbus_uint32_t) inhibitor->pid; + + if (!dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &what) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &who) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &why) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &mode) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT32, &uid) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT32, &pid)) + goto oom; + + if (!dbus_message_iter_close_container(&sub, &sub2)) + goto oom; + } + + if (!dbus_message_iter_close_container(&iter, &sub)) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "Inhibit")) { + + r = bus_manager_inhibit(m, connection, message, &error, &reply); + + if (r < 0) + return bus_send_error_reply(connection, message, &error, r); + + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "CreateSession")) { + + r = bus_manager_create_session(m, message, &reply); + + /* Don't delay the work on OOM here, since it might be + * triggered by a low RLIMIT_NOFILE here (since we + * send a dupped fd to the client), and we'd rather + * see this fail quickly then be retried later */ + + if (r < 0) + return bus_send_error_reply(connection, message, NULL, r); + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "ReleaseSession")) { + const char *name; + Session *session; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + session = hashmap_get(m->sessions, name); + if (!session) + return bus_send_error_reply(connection, message, &error, -ENOENT); + + /* We use the FIFO to detect stray sessions where the + process invoking PAM dies abnormally. We need to make + sure that that process is not killed if at the clean + end of the session it closes the FIFO. Hence, with + this call explicitly turn off the FIFO logic, so that + the PAM code can finish clean up on its own */ + session_remove_fifo(session); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "ActivateSession")) { + const char *name; + Session *session; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + session = hashmap_get(m->sessions, name); + if (!session) + return bus_send_error_reply(connection, message, &error, -ENOENT); + + r = session_activate(session); + if (r < 0) + return bus_send_error_reply(connection, message, NULL, r); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "ActivateSessionOnSeat")) { + const char *session_name, *seat_name; + Session *session; + Seat *seat; + + /* Same as ActivateSession() but refuses to work if + * the seat doesn't match */ + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &session_name, + DBUS_TYPE_STRING, &seat_name, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + session = hashmap_get(m->sessions, session_name); + if (!session) + return bus_send_error_reply(connection, message, &error, -ENOENT); + + seat = hashmap_get(m->seats, seat_name); + if (!seat) + return bus_send_error_reply(connection, message, &error, -ENOENT); + + if (session->seat != seat) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + r = session_activate(session); + if (r < 0) + return bus_send_error_reply(connection, message, NULL, r); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "LockSession") || + dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "UnlockSession")) { + const char *name; + Session *session; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + session = hashmap_get(m->sessions, name); + if (!session) + return bus_send_error_reply(connection, message, NULL, -ENOENT); + + if (session_send_lock(session, streq(dbus_message_get_member(message), "LockSession")) < 0) + goto oom; + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "LockSessions")) { + r = session_send_lock_all(m, true); + if (r < 0) + bus_send_error_reply(connection, message, NULL, r); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "KillSession")) { + const char *swho; + int32_t signo; + KillWho who; + const char *name; + Session *session; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_STRING, &swho, + DBUS_TYPE_INT32, &signo, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + if (isempty(swho)) + who = KILL_ALL; + else { + who = kill_who_from_string(swho); + if (who < 0) + return bus_send_error_reply(connection, message, &error, -EINVAL); + } + + if (signo <= 0 || signo >= _NSIG) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + session = hashmap_get(m->sessions, name); + if (!session) + return bus_send_error_reply(connection, message, &error, -ENOENT); + + r = session_kill(session, who, signo); + if (r < 0) + return bus_send_error_reply(connection, message, NULL, r); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "KillUser")) { + uint32_t uid; + User *user; + int32_t signo; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_UINT32, &uid, + DBUS_TYPE_INT32, &signo, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + if (signo <= 0 || signo >= _NSIG) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + user = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid)); + if (!user) + return bus_send_error_reply(connection, message, &error, -ENOENT); + + r = user_kill(user, signo); + if (r < 0) + return bus_send_error_reply(connection, message, NULL, r); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "TerminateSession")) { + const char *name; + Session *session; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + session = hashmap_get(m->sessions, name); + if (!session) + return bus_send_error_reply(connection, message, &error, -ENOENT); + + r = session_stop(session); + if (r < 0) + return bus_send_error_reply(connection, message, NULL, r); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "TerminateUser")) { + uint32_t uid; + User *user; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_UINT32, &uid, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + user = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid)); + if (!user) + return bus_send_error_reply(connection, message, &error, -ENOENT); + + r = user_stop(user); + if (r < 0) + return bus_send_error_reply(connection, message, NULL, r); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "TerminateSeat")) { + const char *name; + Seat *seat; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + seat = hashmap_get(m->seats, name); + if (!seat) + return bus_send_error_reply(connection, message, &error, -ENOENT); + + r = seat_stop_sessions(seat); + if (r < 0) + return bus_send_error_reply(connection, message, NULL, r); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "SetUserLinger")) { + uint32_t uid; + struct passwd *pw; + dbus_bool_t b, interactive; + char *path; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_UINT32, &uid, + DBUS_TYPE_BOOLEAN, &b, + DBUS_TYPE_BOOLEAN, &interactive, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + errno = 0; + pw = getpwuid(uid); + if (!pw) + return bus_send_error_reply(connection, message, NULL, errno ? -errno : -EINVAL); + + r = verify_polkit(connection, message, "org.freedesktop.login1.set-user-linger", interactive, NULL, &error); + if (r < 0) + return bus_send_error_reply(connection, message, &error, r); + + mkdir_p_label("/var/lib/systemd", 0755); + + r = mkdir_safe_label("/var/lib/systemd/linger", 0755, 0, 0); + if (r < 0) + return bus_send_error_reply(connection, message, &error, r); + + path = strappend("/var/lib/systemd/linger/", pw->pw_name); + if (!path) + goto oom; + + if (b) { + User *u; + + r = touch(path); + free(path); + + if (r < 0) + return bus_send_error_reply(connection, message, &error, r); + + if (manager_add_user_by_uid(m, uid, &u) >= 0) + user_start(u); + + } else { + User *u; + + r = unlink(path); + free(path); + + if (r < 0 && errno != ENOENT) + return bus_send_error_reply(connection, message, &error, -errno); + + u = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid)); + if (u) + user_add_to_gc_queue(u); + } + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "AttachDevice")) { + const char *sysfs, *seat; + dbus_bool_t interactive; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &seat, + DBUS_TYPE_STRING, &sysfs, + DBUS_TYPE_BOOLEAN, &interactive, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + if (!path_startswith(sysfs, "/sys") || !seat_name_is_valid(seat)) + return bus_send_error_reply(connection, message, NULL, -EINVAL); + + r = verify_polkit(connection, message, "org.freedesktop.login1.attach-device", interactive, NULL, &error); + if (r < 0) + return bus_send_error_reply(connection, message, &error, r); + + r = attach_device(m, seat, sysfs); + if (r < 0) + return bus_send_error_reply(connection, message, NULL, -EINVAL); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "FlushDevices")) { + dbus_bool_t interactive; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_BOOLEAN, &interactive, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + r = verify_polkit(connection, message, "org.freedesktop.login1.flush-devices", interactive, NULL, &error); + if (r < 0) + return bus_send_error_reply(connection, message, &error, r); + + r = flush_devices(m); + if (r < 0) + return bus_send_error_reply(connection, message, NULL, -EINVAL); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "PowerOff")) { + + r = bus_manager_do_shutdown_or_sleep( + m, connection, message, + SPECIAL_POWEROFF_TARGET, + INHIBIT_SHUTDOWN, + "org.freedesktop.login1.power-off", + "org.freedesktop.login1.power-off-multiple-sessions", + "org.freedesktop.login1.power-off-ignore-inhibit", + NULL, NULL, + &error, &reply); + if (r < 0) + return bus_send_error_reply(connection, message, &error, r); + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "Reboot")) { + r = bus_manager_do_shutdown_or_sleep( + m, connection, message, + SPECIAL_REBOOT_TARGET, + INHIBIT_SHUTDOWN, + "org.freedesktop.login1.reboot", + "org.freedesktop.login1.reboot-multiple-sessions", + "org.freedesktop.login1.reboot-ignore-inhibit", + NULL, NULL, + &error, &reply); + if (r < 0) + return bus_send_error_reply(connection, message, &error, r); + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "Suspend")) { + r = bus_manager_do_shutdown_or_sleep( + m, connection, message, + SPECIAL_SUSPEND_TARGET, + INHIBIT_SLEEP, + "org.freedesktop.login1.suspend", + "org.freedesktop.login1.suspend-multiple-sessions", + "org.freedesktop.login1.suspend-ignore-inhibit", + "mem", NULL, + &error, &reply); + if (r < 0) + return bus_send_error_reply(connection, message, &error, r); + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "Hibernate")) { + r = bus_manager_do_shutdown_or_sleep( + m, connection, message, + SPECIAL_HIBERNATE_TARGET, + INHIBIT_SLEEP, + "org.freedesktop.login1.hibernate", + "org.freedesktop.login1.hibernate-multiple-sessions", + "org.freedesktop.login1.hibernate-ignore-inhibit", + "disk", NULL, + &error, &reply); + if (r < 0) + return bus_send_error_reply(connection, message, &error, r); + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "HybridSleep")) { + r = bus_manager_do_shutdown_or_sleep( + m, connection, message, + SPECIAL_HYBRID_SLEEP_TARGET, + INHIBIT_SLEEP, + "org.freedesktop.login1.hibernate", + "org.freedesktop.login1.hibernate-multiple-sessions", + "org.freedesktop.login1.hibernate-ignore-inhibit", + "disk", "suspend", + &error, &reply); + if (r < 0) + return bus_send_error_reply(connection, message, &error, r); + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "CanPowerOff")) { + + r = bus_manager_can_shutdown_or_sleep( + m, connection, message, + INHIBIT_SHUTDOWN, + "org.freedesktop.login1.power-off", + "org.freedesktop.login1.power-off-multiple-sessions", + "org.freedesktop.login1.power-off-ignore-inhibit", + NULL, NULL, + &error, &reply); + if (r < 0) + return bus_send_error_reply(connection, message, &error, r); + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "CanReboot")) { + r = bus_manager_can_shutdown_or_sleep( + m, connection, message, + INHIBIT_SHUTDOWN, + "org.freedesktop.login1.reboot", + "org.freedesktop.login1.reboot-multiple-sessions", + "org.freedesktop.login1.reboot-ignore-inhibit", + NULL, NULL, + &error, &reply); + if (r < 0) + return bus_send_error_reply(connection, message, &error, r); + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "CanSuspend")) { + r = bus_manager_can_shutdown_or_sleep( + m, connection, message, + INHIBIT_SLEEP, + "org.freedesktop.login1.suspend", + "org.freedesktop.login1.suspend-multiple-sessions", + "org.freedesktop.login1.suspend-ignore-inhibit", + "mem", NULL, + &error, &reply); + if (r < 0) + return bus_send_error_reply(connection, message, &error, r); + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "CanHibernate")) { + r = bus_manager_can_shutdown_or_sleep( + m, connection, message, + INHIBIT_SLEEP, + "org.freedesktop.login1.hibernate", + "org.freedesktop.login1.hibernate-multiple-sessions", + "org.freedesktop.login1.hibernate-ignore-inhibit", + "disk", NULL, + &error, &reply); + if (r < 0) + return bus_send_error_reply(connection, message, &error, r); + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "CanHybridSleep")) { + r = bus_manager_can_shutdown_or_sleep( + m, connection, message, + INHIBIT_SLEEP, + "org.freedesktop.login1.hibernate", + "org.freedesktop.login1.hibernate-multiple-sessions", + "org.freedesktop.login1.hibernate-ignore-inhibit", + "disk", "suspend", + &error, &reply); + if (r < 0) + return bus_send_error_reply(connection, message, &error, r); + + } else if (dbus_message_is_method_call(message, "org.freedesktop.DBus.Introspectable", "Introspect")) { + char *introspection = NULL; + FILE *f; + Iterator i; + Session *session; + Seat *seat; + User *user; + size_t size; + char *p; + + if (!(reply = dbus_message_new_method_return(message))) + goto oom; + + /* We roll our own introspection code here, instead of + * relying on bus_default_message_handler() because we + * need to generate our introspection string + * dynamically. */ + + if (!(f = open_memstream(&introspection, &size))) + goto oom; + + fputs(INTROSPECTION_BEGIN, f); + + HASHMAP_FOREACH(seat, m->seats, i) { + p = bus_path_escape(seat->id); + + if (p) { + fprintf(f, "", p); + free(p); + } + } + + HASHMAP_FOREACH(user, m->users, i) + fprintf(f, "", (unsigned long long) user->uid); + + HASHMAP_FOREACH(session, m->sessions, i) { + p = bus_path_escape(session->id); + + if (p) { + fprintf(f, "", p); + free(p); + } + } + + fputs(INTROSPECTION_END, f); + + if (ferror(f)) { + fclose(f); + free(introspection); + goto oom; + } + + fclose(f); + + if (!introspection) + goto oom; + + if (!dbus_message_append_args(reply, DBUS_TYPE_STRING, &introspection, DBUS_TYPE_INVALID)) { + free(introspection); + goto oom; + } + + free(introspection); + } else { + const BusBoundProperties bps[] = { + { "org.freedesktop.login1.Manager", bus_login_manager_properties, m }, + { NULL, } + }; + return bus_default_message_handler(connection, message, NULL, INTERFACES_LIST, bps); + } + + if (reply) { + if (!bus_maybe_send_reply(connection, message, reply)) + goto oom; + + dbus_message_unref(reply); + } + + return DBUS_HANDLER_RESULT_HANDLED; + +oom: + if (reply) + dbus_message_unref(reply); + + dbus_error_free(&error); + + return DBUS_HANDLER_RESULT_NEED_MEMORY; +} + +const DBusObjectPathVTable bus_manager_vtable = { + .message_function = manager_message_handler +}; + +DBusHandlerResult bus_message_filter( + DBusConnection *connection, + DBusMessage *message, + void *userdata) { + + Manager *m = userdata; + DBusError error; + + assert(m); + assert(connection); + assert(message); + + dbus_error_init(&error); + + if (dbus_message_is_signal(message, "org.freedesktop.systemd1.Agent", "Released")) { + const char *cgroup; + + if (!dbus_message_get_args(message, &error, + DBUS_TYPE_STRING, &cgroup, + DBUS_TYPE_INVALID)) + log_error("Failed to parse Released message: %s", bus_error_message(&error)); + else + manager_cgroup_notify_empty(m, cgroup); + } + + dbus_error_free(&error); + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +int manager_send_changed(Manager *manager, const char *properties) { + DBusMessage *m; + int r = -ENOMEM; + + assert(manager); + + m = bus_properties_changed_new("/org/freedesktop/login1", "org.freedesktop.login1.Manager", properties); + if (!m) + goto finish; + + if (!dbus_connection_send(manager->bus, m, NULL)) + goto finish; + + r = 0; + +finish: + if (m) + dbus_message_unref(m); + + return r; +} + +int manager_dispatch_delayed(Manager *manager) { + const char *unit_name; + DBusError error; + bool delayed; + int r; + + assert(manager); + + if (!manager->delayed_unit) + return 0; + + /* Continue delay? */ + delayed = + manager->delayed_timestamp + manager->inhibit_delay_max > now(CLOCK_MONOTONIC) && + manager_is_inhibited(manager, manager->delayed_what, INHIBIT_DELAY, NULL, false, false, 0); + if (delayed) + return 0; + + bus_manager_log_shutdown(manager, manager->delayed_what, manager->delayed_unit); + + /* Reset delay data */ + unit_name = manager->delayed_unit; + manager->delayed_unit = NULL; + + /* Actually do the shutdown */ + dbus_error_init(&error); + r = send_start_unit(manager->bus, unit_name, &error); + if (r < 0) { + log_warning("Failed to send delayed message: %s", bus_error_message_or_strerror(&error, -r)); + dbus_error_free(&error); + return r; + } + + /* Tell people about it */ + send_prepare_for(manager, manager->delayed_what, false); + + return 1; +} diff --git a/src/login/logind-device.c b/src/login/logind-device.c new file mode 100644 index 000000000..51b15358b --- /dev/null +++ b/src/login/logind-device.c @@ -0,0 +1,96 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +#include +#include + +#include "logind-device.h" +#include "util.h" + +Device* device_new(Manager *m, const char *sysfs) { + Device *d; + + assert(m); + assert(sysfs); + + d = new0(Device, 1); + if (!d) + return NULL; + + d->sysfs = strdup(sysfs); + if (!d->sysfs) { + free(d); + return NULL; + } + + if (hashmap_put(m->devices, d->sysfs, d) < 0) { + free(d->sysfs); + free(d); + return NULL; + } + + d->manager = m; + dual_timestamp_get(&d->timestamp); + + return d; +} + +void device_free(Device *d) { + assert(d); + + device_detach(d); + + hashmap_remove(d->manager->devices, d->sysfs); + + free(d->sysfs); + free(d); +} + +void device_detach(Device *d) { + Seat *s; + assert(d); + + if (!d->seat) + return; + + s = d->seat; + LIST_REMOVE(Device, devices, d->seat->devices, d); + d->seat = NULL; + + seat_add_to_gc_queue(s); + seat_send_changed(s, "CanGraphical\0"); +} + +void device_attach(Device *d, Seat *s) { + assert(d); + assert(s); + + if (d->seat == s) + return; + + if (d->seat) + device_detach(d); + + d->seat = s; + LIST_PREPEND(Device, devices, s->devices, d); + + seat_send_changed(s, "CanGraphical\0"); +} diff --git a/src/login/logind-device.h b/src/login/logind-device.h new file mode 100644 index 000000000..3b153568c --- /dev/null +++ b/src/login/logind-device.h @@ -0,0 +1,45 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +typedef struct Device Device; + +#include "list.h" +#include "util.h" +#include "logind.h" +#include "logind-seat.h" + +struct Device { + Manager *manager; + + char *sysfs; + Seat *seat; + + dual_timestamp timestamp; + + LIST_FIELDS(struct Device, devices); +}; + +Device* device_new(Manager *m, const char *sysfs); +void device_free(Device *d); +void device_attach(Device *d, Seat *s); +void device_detach(Device *d); diff --git a/src/login/logind-gperf.gperf b/src/login/logind-gperf.gperf new file mode 100644 index 000000000..076d11616 --- /dev/null +++ b/src/login/logind-gperf.gperf @@ -0,0 +1,34 @@ +%{ +#include +#include "conf-parser.h" +#include "logind.h" +%} +struct ConfigPerfItem; +%null_strings +%language=ANSI-C +%define slot-name section_and_lvalue +%define hash-function-name logind_gperf_hash +%define lookup-function-name logind_gperf_lookup +%readonly-tables +%omit-struct-type +%struct-type +%includes +%% +Login.NAutoVTs, config_parse_unsigned, 0, offsetof(Manager, n_autovts) +Login.ReserveVT, config_parse_unsigned, 0, offsetof(Manager, reserve_vt) +Login.KillUserProcesses, config_parse_bool, 0, offsetof(Manager, kill_user_processes) +Login.KillOnlyUsers, config_parse_strv, 0, offsetof(Manager, kill_only_users) +Login.KillExcludeUsers, config_parse_strv, 0, offsetof(Manager, kill_exclude_users) +Login.Controllers, config_parse_strv, 0, offsetof(Manager, controllers) +Login.ResetControllers, config_parse_strv, 0, offsetof(Manager, reset_controllers) +Login.InhibitDelayMaxSec, config_parse_usec, 0, offsetof(Manager, inhibit_delay_max) +Login.HandlePowerKey, config_parse_handle_action, 0, offsetof(Manager, handle_power_key) +Login.HandleSuspendKey, config_parse_handle_action, 0, offsetof(Manager, handle_suspend_key) +Login.HandleHibernateKey, config_parse_handle_action, 0, offsetof(Manager, handle_hibernate_key) +Login.HandleLidSwitch, config_parse_handle_action, 0, offsetof(Manager, handle_lid_switch) +Login.PowerKeyIgnoreInhibited, config_parse_bool, 0, offsetof(Manager, power_key_ignore_inhibited) +Login.SuspendKeyIgnoreInhibited, config_parse_bool, 0, offsetof(Manager, suspend_key_ignore_inhibited) +Login.HibernateKeyIgnoreInhibited, config_parse_bool, 0, offsetof(Manager, hibernate_key_ignore_inhibited) +Login.LidSwitchIgnoreInhibited, config_parse_bool, 0, offsetof(Manager, lid_switch_ignore_inhibited) +Login.IdleAction, config_parse_handle_action, 0, offsetof(Manager, idle_action) +Login.IdleActionSec, config_parse_usec, 0, offsetof(Manager, idle_action_usec) diff --git a/src/login/logind-inhibit.c b/src/login/logind-inhibit.c new file mode 100644 index 000000000..f1b9cca83 --- /dev/null +++ b/src/login/logind-inhibit.c @@ -0,0 +1,468 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + +#include +#include +#include +#include +#include +#include + +#include "util.h" +#include "mkdir.h" +#include "path-util.h" +#include "logind-inhibit.h" + +Inhibitor* inhibitor_new(Manager *m, const char* id) { + Inhibitor *i; + + assert(m); + + i = new0(Inhibitor, 1); + if (!i) + return NULL; + + i->state_file = strappend("/run/systemd/inhibit/", id); + if (!i->state_file) { + free(i); + return NULL; + } + + i->id = path_get_file_name(i->state_file); + + if (hashmap_put(m->inhibitors, i->id, i) < 0) { + free(i->state_file); + free(i); + return NULL; + } + + i->manager = m; + i->fifo_fd = -1; + + return i; +} + +void inhibitor_free(Inhibitor *i) { + assert(i); + + free(i->who); + free(i->why); + + hashmap_remove(i->manager->inhibitors, i->id); + inhibitor_remove_fifo(i); + + if (i->state_file) { + unlink(i->state_file); + free(i->state_file); + } + + free(i); +} + +int inhibitor_save(Inhibitor *i) { + char *temp_path, *cc; + int r; + FILE *f; + + assert(i); + + r = mkdir_safe_label("/run/systemd/inhibit", 0755, 0, 0); + if (r < 0) + goto finish; + + r = fopen_temporary(i->state_file, &f, &temp_path); + if (r < 0) + goto finish; + + fchmod(fileno(f), 0644); + + fprintf(f, + "# This is private data. Do not parse.\n" + "WHAT=%s\n" + "MODE=%s\n" + "UID=%lu\n" + "PID=%lu\n", + inhibit_what_to_string(i->what), + inhibit_mode_to_string(i->mode), + (unsigned long) i->uid, + (unsigned long) i->pid); + + if (i->who) { + cc = cescape(i->who); + if (!cc) + r = -ENOMEM; + else { + fprintf(f, "WHO=%s\n", cc); + free(cc); + } + } + + if (i->why) { + cc = cescape(i->why); + if (!cc) + r = -ENOMEM; + else { + fprintf(f, "WHY=%s\n", cc); + free(cc); + } + } + + if (i->fifo_path) + fprintf(f, "FIFO=%s\n", i->fifo_path); + + fflush(f); + + if (ferror(f) || rename(temp_path, i->state_file) < 0) { + r = -errno; + unlink(i->state_file); + unlink(temp_path); + } + + fclose(f); + free(temp_path); + +finish: + if (r < 0) + log_error("Failed to save inhibit data for %s: %s", i->id, strerror(-r)); + + return r; +} + +int inhibitor_start(Inhibitor *i) { + assert(i); + + if (i->started) + return 0; + + dual_timestamp_get(&i->since); + + log_debug("Inhibitor %s (%s) pid=%lu uid=%lu mode=%s started.", + strna(i->who), strna(i->why), + (unsigned long) i->pid, (unsigned long) i->uid, + inhibit_mode_to_string(i->mode)); + + inhibitor_save(i); + + i->started = true; + + manager_send_changed(i->manager, i->mode == INHIBIT_BLOCK ? "BlockInhibited\0" : "DelayInhibited\0"); + + return 0; +} + +int inhibitor_stop(Inhibitor *i) { + assert(i); + + if (i->started) + log_debug("Inhibitor %s (%s) pid=%lu uid=%lu mode=%s stopped.", + strna(i->who), strna(i->why), + (unsigned long) i->pid, (unsigned long) i->uid, + inhibit_mode_to_string(i->mode)); + + if (i->state_file) + unlink(i->state_file); + + i->started = false; + + manager_send_changed(i->manager, i->mode == INHIBIT_BLOCK ? "BlockInhibited\0" : "DelayInhibited\0"); + + return 0; +} + +int inhibitor_load(Inhibitor *i) { + InhibitWhat w; + InhibitMode mm; + int r; + char *cc, + *what = NULL, + *uid = NULL, + *pid = NULL, + *who = NULL, + *why = NULL, + *mode = NULL; + + r = parse_env_file(i->state_file, NEWLINE, + "WHAT", &what, + "UID", &uid, + "PID", &pid, + "WHO", &who, + "WHY", &why, + "MODE", &mode, + "FIFO", &i->fifo_path, + NULL); + if (r < 0) + goto finish; + + w = what ? inhibit_what_from_string(what) : 0; + if (w >= 0) + i->what = w; + + mm = mode ? inhibit_mode_from_string(mode) : INHIBIT_BLOCK; + if (mm >= 0) + i->mode = mm; + + if (uid) { + r = parse_uid(uid, &i->uid); + if (r < 0) + goto finish; + } + + if (pid) { + r = parse_pid(pid, &i->pid); + if (r < 0) + goto finish; + } + + if (who) { + cc = cunescape(who); + if (!cc) { + r = -ENOMEM; + goto finish; + } + + free(i->who); + i->who = cc; + } + + if (why) { + cc = cunescape(why); + if (!cc) { + r = -ENOMEM; + goto finish; + } + + free(i->why); + i->why = cc; + } + + if (i->fifo_path) { + int fd; + + fd = inhibitor_create_fifo(i); + if (fd >= 0) + close_nointr_nofail(fd); + } + +finish: + free(what); + free(uid); + free(pid); + free(who); + free(why); + + return r; +} + +int inhibitor_create_fifo(Inhibitor *i) { + int r; + + assert(i); + + /* Create FIFO */ + if (!i->fifo_path) { + r = mkdir_safe_label("/run/systemd/inhibit", 0755, 0, 0); + if (r < 0) + return r; + + if (asprintf(&i->fifo_path, "/run/systemd/inhibit/%s.ref", i->id) < 0) + return -ENOMEM; + + if (mkfifo(i->fifo_path, 0600) < 0 && errno != EEXIST) + return -errno; + } + + /* Open reading side */ + if (i->fifo_fd < 0) { + struct epoll_event ev; + + i->fifo_fd = open(i->fifo_path, O_RDONLY|O_CLOEXEC|O_NDELAY); + if (i->fifo_fd < 0) + return -errno; + + r = hashmap_put(i->manager->inhibitor_fds, INT_TO_PTR(i->fifo_fd + 1), i); + if (r < 0) + return r; + + zero(ev); + ev.events = 0; + ev.data.u32 = FD_OTHER_BASE + i->fifo_fd; + + if (epoll_ctl(i->manager->epoll_fd, EPOLL_CTL_ADD, i->fifo_fd, &ev) < 0) + return -errno; + } + + /* Open writing side */ + r = open(i->fifo_path, O_WRONLY|O_CLOEXEC|O_NDELAY); + if (r < 0) + return -errno; + + return r; +} + +void inhibitor_remove_fifo(Inhibitor *i) { + assert(i); + + if (i->fifo_fd >= 0) { + assert_se(hashmap_remove(i->manager->inhibitor_fds, INT_TO_PTR(i->fifo_fd + 1)) == i); + assert_se(epoll_ctl(i->manager->epoll_fd, EPOLL_CTL_DEL, i->fifo_fd, NULL) == 0); + close_nointr_nofail(i->fifo_fd); + i->fifo_fd = -1; + } + + if (i->fifo_path) { + unlink(i->fifo_path); + free(i->fifo_path); + i->fifo_path = NULL; + } +} + +InhibitWhat manager_inhibit_what(Manager *m, InhibitMode mm) { + Inhibitor *i; + Iterator j; + InhibitWhat what = 0; + + assert(m); + + HASHMAP_FOREACH(i, m->inhibitor_fds, j) + if (i->mode == mm) + what |= i->what; + + return what; +} + +static int pid_is_active(Manager *m, pid_t pid) { + Session *s; + int r; + + r = manager_get_session_by_pid(m, pid, &s); + if (r <= 0) + return r; + + return session_is_active(s); +} + +bool manager_is_inhibited( + Manager *m, + InhibitWhat w, + InhibitMode mm, + dual_timestamp *since, + bool ignore_inactive, + bool ignore_uid, + uid_t uid) { + + Inhibitor *i; + Iterator j; + struct dual_timestamp ts = { 0, 0 }; + bool inhibited = false; + + assert(m); + assert(w > 0 && w < _INHIBIT_WHAT_MAX); + + HASHMAP_FOREACH(i, m->inhibitor_fds, j) { + if (!(i->what & w)) + continue; + + if (i->mode != mm) + continue; + + if (ignore_inactive && pid_is_active(m, i->pid) <= 0) + continue; + + if (ignore_uid && i->uid == uid) + continue; + + if (!inhibited || + i->since.monotonic < ts.monotonic) + ts = i->since; + + inhibited = true; + } + + if (since) + *since = ts; + + return inhibited; +} + +const char *inhibit_what_to_string(InhibitWhat w) { + static __thread char buffer[97]; + char *p; + + if (w < 0 || w >= _INHIBIT_WHAT_MAX) + return NULL; + + p = buffer; + if (w & INHIBIT_SHUTDOWN) + p = stpcpy(p, "shutdown:"); + if (w & INHIBIT_SLEEP) + p = stpcpy(p, "sleep:"); + if (w & INHIBIT_IDLE) + p = stpcpy(p, "idle:"); + if (w & INHIBIT_HANDLE_POWER_KEY) + p = stpcpy(p, "handle-power-key:"); + if (w & INHIBIT_HANDLE_SUSPEND_KEY) + p = stpcpy(p, "handle-suspend-key:"); + if (w & INHIBIT_HANDLE_HIBERNATE_KEY) + p = stpcpy(p, "handle-hibernate-key:"); + if (w & INHIBIT_HANDLE_LID_SWITCH) + p = stpcpy(p, "handle-lid-switch:"); + + if (p > buffer) + *(p-1) = 0; + else + *p = 0; + + return buffer; +} + +InhibitWhat inhibit_what_from_string(const char *s) { + InhibitWhat what = 0; + char *w, *state; + size_t l; + + FOREACH_WORD_SEPARATOR(w, l, s, ":", state) { + if (l == 8 && strncmp(w, "shutdown", l) == 0) + what |= INHIBIT_SHUTDOWN; + else if (l == 5 && strncmp(w, "sleep", l) == 0) + what |= INHIBIT_SLEEP; + else if (l == 4 && strncmp(w, "idle", l) == 0) + what |= INHIBIT_IDLE; + else if (l == 16 && strncmp(w, "handle-power-key", l) == 0) + what |= INHIBIT_HANDLE_POWER_KEY; + else if (l == 18 && strncmp(w, "handle-suspend-key", l) == 0) + what |= INHIBIT_HANDLE_SUSPEND_KEY; + else if (l == 20 && strncmp(w, "handle-hibernate-key", l) == 0) + what |= INHIBIT_HANDLE_HIBERNATE_KEY; + else if (l == 17 && strncmp(w, "handle-lid-switch", l) == 0) + what |= INHIBIT_HANDLE_LID_SWITCH; + else + return _INHIBIT_WHAT_INVALID; + } + + return what; +} + +static const char* const inhibit_mode_table[_INHIBIT_MODE_MAX] = { + [INHIBIT_BLOCK] = "block", + [INHIBIT_DELAY] = "delay" +}; + +DEFINE_STRING_TABLE_LOOKUP(inhibit_mode, InhibitMode); diff --git a/src/login/logind-inhibit.h b/src/login/logind-inhibit.h new file mode 100644 index 000000000..4c158ee0f --- /dev/null +++ b/src/login/logind-inhibit.h @@ -0,0 +1,95 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foologindinhibithfoo +#define foologindinhibithfoo + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + +typedef struct Inhibitor Inhibitor; + +#include "list.h" +#include "util.h" + +typedef enum InhibitWhat { + INHIBIT_SHUTDOWN = 1, + INHIBIT_SLEEP = 2, + INHIBIT_IDLE = 4, + INHIBIT_HANDLE_POWER_KEY = 8, + INHIBIT_HANDLE_SUSPEND_KEY = 16, + INHIBIT_HANDLE_HIBERNATE_KEY = 32, + INHIBIT_HANDLE_LID_SWITCH = 64, + _INHIBIT_WHAT_MAX = 128, + _INHIBIT_WHAT_INVALID = -1 +} InhibitWhat; + +typedef enum InhibitMode { + INHIBIT_BLOCK, + INHIBIT_DELAY, + _INHIBIT_MODE_MAX, + _INHIBIT_MODE_INVALID = -1 +} InhibitMode; + +#include "logind.h" +#include "logind-seat.h" + +struct Inhibitor { + Manager *manager; + + char *id; + char *state_file; + + bool started; + + InhibitWhat what; + char *who; + char *why; + InhibitMode mode; + + pid_t pid; + uid_t uid; + + dual_timestamp since; + + char *fifo_path; + int fifo_fd; +}; + +Inhibitor* inhibitor_new(Manager *m, const char *id); +void inhibitor_free(Inhibitor *i); + +int inhibitor_save(Inhibitor *i); +int inhibitor_load(Inhibitor *i); + +int inhibitor_start(Inhibitor *i); +int inhibitor_stop(Inhibitor *i); + +int inhibitor_create_fifo(Inhibitor *i); +void inhibitor_remove_fifo(Inhibitor *i); + +InhibitWhat manager_inhibit_what(Manager *m, InhibitMode mm); +bool manager_is_inhibited(Manager *m, InhibitWhat w, InhibitMode mm, dual_timestamp *since, bool ignore_inactive, bool ignore_uid, uid_t uid); + +const char *inhibit_what_to_string(InhibitWhat k); +InhibitWhat inhibit_what_from_string(const char *s); + +const char *inhibit_mode_to_string(InhibitMode k); +InhibitMode inhibit_mode_from_string(const char *s); + +#endif diff --git a/src/login/logind-seat-dbus.c b/src/login/logind-seat-dbus.c new file mode 100644 index 000000000..7833d70a0 --- /dev/null +++ b/src/login/logind-seat-dbus.c @@ -0,0 +1,444 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +#include +#include + +#include "logind.h" +#include "logind-seat.h" +#include "dbus-common.h" +#include "util.h" + +#define BUS_SEAT_INTERFACE \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + +#define INTROSPECTION \ + DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \ + "\n" \ + BUS_SEAT_INTERFACE \ + BUS_PROPERTIES_INTERFACE \ + BUS_PEER_INTERFACE \ + BUS_INTROSPECTABLE_INTERFACE \ + "\n" + +#define INTERFACES_LIST \ + BUS_GENERIC_INTERFACES_LIST \ + "org.freedesktop.login1.Seat\0" + +static int bus_seat_append_active(DBusMessageIter *i, const char *property, void *data) { + DBusMessageIter sub; + Seat *s = data; + const char *id, *path; + char *p = NULL; + + assert(i); + assert(property); + assert(s); + + if (!dbus_message_iter_open_container(i, DBUS_TYPE_STRUCT, NULL, &sub)) + return -ENOMEM; + + if (s->active) { + id = s->active->id; + path = p = session_bus_path(s->active); + + if (!p) + return -ENOMEM; + } else { + id = ""; + path = "/"; + } + + if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &id) || + !dbus_message_iter_append_basic(&sub, DBUS_TYPE_OBJECT_PATH, &path)) { + free(p); + return -ENOMEM; + } + + free(p); + + if (!dbus_message_iter_close_container(i, &sub)) + return -ENOMEM; + + return 0; +} + +static int bus_seat_append_sessions(DBusMessageIter *i, const char *property, void *data) { + DBusMessageIter sub, sub2; + Seat *s = data; + Session *session; + + assert(i); + assert(property); + assert(s); + + if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "(so)", &sub)) + return -ENOMEM; + + LIST_FOREACH(sessions_by_seat, session, s->sessions) { + char *p; + + if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2)) + return -ENOMEM; + + p = session_bus_path(session); + if (!p) + return -ENOMEM; + + if (!dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &session->id) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_OBJECT_PATH, &p)) { + free(p); + return -ENOMEM; + } + + free(p); + + if (!dbus_message_iter_close_container(&sub, &sub2)) + return -ENOMEM; + } + + if (!dbus_message_iter_close_container(i, &sub)) + return -ENOMEM; + + return 0; +} + +static int bus_seat_append_can_multi_session(DBusMessageIter *i, const char *property, void *data) { + Seat *s = data; + dbus_bool_t b; + + assert(i); + assert(property); + assert(s); + + b = seat_can_multi_session(s); + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b)) + return -ENOMEM; + + return 0; +} + +static int bus_seat_append_can_tty(DBusMessageIter *i, const char *property, void *data) { + Seat *s = data; + dbus_bool_t b; + + assert(i); + assert(property); + assert(s); + + b = seat_can_tty(s); + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b)) + return -ENOMEM; + + return 0; +} + +static int bus_seat_append_can_graphical(DBusMessageIter *i, const char *property, void *data) { + Seat *s = data; + dbus_bool_t b; + + assert(i); + assert(property); + assert(s); + + b = seat_can_graphical(s); + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b)) + return -ENOMEM; + + return 0; +} + +static int bus_seat_append_idle_hint(DBusMessageIter *i, const char *property, void *data) { + Seat *s = data; + dbus_bool_t b; + + assert(i); + assert(property); + assert(s); + + b = seat_get_idle_hint(s, NULL) > 0; + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b)) + return -ENOMEM; + + return 0; +} + +static int bus_seat_append_idle_hint_since(DBusMessageIter *i, const char *property, void *data) { + Seat *s = data; + dual_timestamp t; + uint64_t k; + + assert(i); + assert(property); + assert(s); + + seat_get_idle_hint(s, &t); + k = streq(property, "IdleSinceHint") ? t.realtime : t.monotonic; + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_UINT64, &k)) + return -ENOMEM; + + return 0; +} + +static int get_seat_for_path(Manager *m, const char *path, Seat **_s) { + Seat *s; + char *id; + + assert(m); + assert(path); + assert(_s); + + if (!startswith(path, "/org/freedesktop/login1/seat/")) + return -EINVAL; + + id = bus_path_unescape(path + 29); + if (!id) + return -ENOMEM; + + s = hashmap_get(m->seats, id); + free(id); + + if (!s) + return -ENOENT; + + *_s = s; + return 0; +} + +static const BusProperty bus_login_seat_properties[] = { + { "Id", bus_property_append_string, "s", offsetof(Seat, id), true }, + { "ActiveSession", bus_seat_append_active, "(so)", 0 }, + { "CanMultiSession", bus_seat_append_can_multi_session, "b", 0 }, + { "CanTTY", bus_seat_append_can_tty, "b", 0 }, + { "CanGraphical", bus_seat_append_can_graphical, "b", 0 }, + { "Sessions", bus_seat_append_sessions, "a(so)", 0 }, + { "IdleHint", bus_seat_append_idle_hint, "b", 0 }, + { "IdleSinceHint", bus_seat_append_idle_hint_since, "t", 0 }, + { "IdleSinceHintMonotonic", bus_seat_append_idle_hint_since, "t", 0 }, + { NULL, } +}; + +static DBusHandlerResult seat_message_dispatch( + Seat *s, + DBusConnection *connection, + DBusMessage *message) { + + DBusError error; + DBusMessage *reply = NULL; + int r; + + assert(s); + assert(connection); + assert(message); + + dbus_error_init(&error); + + if (dbus_message_is_method_call(message, "org.freedesktop.login1.Seat", "Terminate")) { + + r = seat_stop_sessions(s); + if (r < 0) + return bus_send_error_reply(connection, message, NULL, r); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Seat", "ActivateSession")) { + const char *name; + Session *session; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + session = hashmap_get(s->manager->sessions, name); + if (!session || session->seat != s) + return bus_send_error_reply(connection, message, &error, -ENOENT); + + r = session_activate(session); + if (r < 0) + return bus_send_error_reply(connection, message, NULL, r); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + } else { + const BusBoundProperties bps[] = { + { "org.freedesktop.login1.Seat", bus_login_seat_properties, s }, + { NULL, } + }; + return bus_default_message_handler(connection, message, INTROSPECTION, INTERFACES_LIST, bps); + } + + if (reply) { + if (!dbus_connection_send(connection, reply, NULL)) + goto oom; + + dbus_message_unref(reply); + } + + return DBUS_HANDLER_RESULT_HANDLED; + +oom: + if (reply) + dbus_message_unref(reply); + + dbus_error_free(&error); + + return DBUS_HANDLER_RESULT_NEED_MEMORY; +} + +static DBusHandlerResult seat_message_handler( + DBusConnection *connection, + DBusMessage *message, + void *userdata) { + + Manager *m = userdata; + Seat *s; + int r; + + r = get_seat_for_path(m, dbus_message_get_path(message), &s); + if (r < 0) { + + if (r == -ENOMEM) + return DBUS_HANDLER_RESULT_NEED_MEMORY; + + if (r == -ENOENT) { + DBusError e; + + dbus_error_init(&e); + dbus_set_error_const(&e, DBUS_ERROR_UNKNOWN_OBJECT, "Unknown seat"); + return bus_send_error_reply(connection, message, &e, r); + } + + return bus_send_error_reply(connection, message, NULL, r); + } + + return seat_message_dispatch(s, connection, message); +} + +const DBusObjectPathVTable bus_seat_vtable = { + .message_function = seat_message_handler +}; + +char *seat_bus_path(Seat *s) { + char *t, *r; + + assert(s); + + t = bus_path_escape(s->id); + if (!t) + return NULL; + + r = strappend("/org/freedesktop/login1/seat/", t); + free(t); + + return r; +} + +int seat_send_signal(Seat *s, bool new_seat) { + DBusMessage *m; + int r = -ENOMEM; + char *p = NULL; + + assert(s); + + m = dbus_message_new_signal("/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + new_seat ? "SeatNew" : "SeatRemoved"); + + if (!m) + return -ENOMEM; + + p = seat_bus_path(s); + if (!p) + goto finish; + + if (!dbus_message_append_args( + m, + DBUS_TYPE_STRING, &s->id, + DBUS_TYPE_OBJECT_PATH, &p, + DBUS_TYPE_INVALID)) + goto finish; + + if (!dbus_connection_send(s->manager->bus, m, NULL)) + goto finish; + + r = 0; + +finish: + dbus_message_unref(m); + free(p); + + return r; +} + +int seat_send_changed(Seat *s, const char *properties) { + DBusMessage *m; + int r = -ENOMEM; + char *p = NULL; + + assert(s); + + if (!s->started) + return 0; + + p = seat_bus_path(s); + if (!p) + return -ENOMEM; + + m = bus_properties_changed_new(p, "org.freedesktop.login1.Seat", properties); + if (!m) + goto finish; + + if (!dbus_connection_send(s->manager->bus, m, NULL)) + goto finish; + + r = 0; + +finish: + if (m) + dbus_message_unref(m); + free(p); + + return r; +} diff --git a/src/login/logind-seat.c b/src/login/logind-seat.c new file mode 100644 index 000000000..470d08bc0 --- /dev/null +++ b/src/login/logind-seat.c @@ -0,0 +1,543 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include + +#include "systemd/sd-id128.h" +#include "systemd/sd-messages.h" +#include "logind-seat.h" +#include "logind-acl.h" +#include "util.h" +#include "mkdir.h" +#include "path-util.h" + +Seat *seat_new(Manager *m, const char *id) { + Seat *s; + + assert(m); + assert(id); + + s = new0(Seat, 1); + if (!s) + return NULL; + + s->state_file = strappend("/run/systemd/seats/", id); + if (!s->state_file) { + free(s); + return NULL; + } + + s->id = path_get_file_name(s->state_file); + s->manager = m; + + if (hashmap_put(m->seats, s->id, s) < 0) { + free(s->state_file); + free(s); + return NULL; + } + + return s; +} + +void seat_free(Seat *s) { + assert(s); + + if (s->in_gc_queue) + LIST_REMOVE(Seat, gc_queue, s->manager->seat_gc_queue, s); + + while (s->sessions) + session_free(s->sessions); + + assert(!s->active); + + while (s->devices) + device_free(s->devices); + + hashmap_remove(s->manager->seats, s->id); + + free(s->state_file); + free(s); +} + +int seat_save(Seat *s) { + int r; + FILE *f; + char *temp_path; + + assert(s); + + if (!s->started) + return 0; + + r = mkdir_safe_label("/run/systemd/seats", 0755, 0, 0); + if (r < 0) + goto finish; + + r = fopen_temporary(s->state_file, &f, &temp_path); + if (r < 0) + goto finish; + + fchmod(fileno(f), 0644); + + fprintf(f, + "# This is private data. Do not parse.\n" + "IS_VTCONSOLE=%i\n" + "CAN_MULTI_SESSION=%i\n" + "CAN_TTY=%i\n" + "CAN_GRAPHICAL=%i\n", + seat_is_vtconsole(s), + seat_can_multi_session(s), + seat_can_tty(s), + seat_can_graphical(s)); + + if (s->active) { + assert(s->active->user); + + fprintf(f, + "ACTIVE=%s\n" + "ACTIVE_UID=%lu\n", + s->active->id, + (unsigned long) s->active->user->uid); + } + + if (s->sessions) { + Session *i; + + fputs("SESSIONS=", f); + LIST_FOREACH(sessions_by_seat, i, s->sessions) { + fprintf(f, + "%s%c", + i->id, + i->sessions_by_seat_next ? ' ' : '\n'); + } + + fputs("UIDS=", f); + LIST_FOREACH(sessions_by_seat, i, s->sessions) + fprintf(f, + "%lu%c", + (unsigned long) i->user->uid, + i->sessions_by_seat_next ? ' ' : '\n'); + } + + fflush(f); + + if (ferror(f) || rename(temp_path, s->state_file) < 0) { + r = -errno; + unlink(s->state_file); + unlink(temp_path); + } + + fclose(f); + free(temp_path); + +finish: + if (r < 0) + log_error("Failed to save seat data for %s: %s", s->id, strerror(-r)); + + return r; +} + +int seat_load(Seat *s) { + assert(s); + + /* There isn't actually anything to read here ... */ + + return 0; +} + +static int vt_allocate(int vtnr) { + int fd, r; + char *p; + + assert(vtnr >= 1); + + if (asprintf(&p, "/dev/tty%i", vtnr) < 0) + return -ENOMEM; + + fd = open_terminal(p, O_RDWR|O_NOCTTY|O_CLOEXEC); + free(p); + + r = fd < 0 ? -errno : 0; + + if (fd >= 0) + close_nointr_nofail(fd); + + return r; +} + +int seat_preallocate_vts(Seat *s) { + int r = 0; + unsigned i; + + assert(s); + assert(s->manager); + + log_debug("Preallocating VTs..."); + + if (s->manager->n_autovts <= 0) + return 0; + + if (!seat_can_multi_session(s)) + return 0; + + for (i = 1; i <= s->manager->n_autovts; i++) { + int q; + + q = vt_allocate(i); + if (q < 0) { + log_error("Failed to preallocate VT %i: %s", i, strerror(-q)); + r = q; + } + } + + return r; +} + +int seat_apply_acls(Seat *s, Session *old_active) { + int r; + + assert(s); + + r = devnode_acl_all(s->manager->udev, + s->id, + false, + !!old_active, old_active ? old_active->user->uid : 0, + !!s->active, s->active ? s->active->user->uid : 0); + + if (r < 0) + log_error("Failed to apply ACLs: %s", strerror(-r)); + + return r; +} + +int seat_set_active(Seat *s, Session *session) { + Session *old_active; + + assert(s); + assert(!session || session->seat == s); + + if (session == s->active) + return 0; + + old_active = s->active; + s->active = session; + + seat_apply_acls(s, old_active); + + if (session && session->started) + session_send_changed(session, "Active\0"); + + if (!session || session->started) + seat_send_changed(s, "ActiveSession\0"); + + seat_save(s); + + if (session) { + session_save(session); + user_save(session->user); + } + + if (old_active) { + session_save(old_active); + if (!session || session->user != old_active->user) + user_save(old_active->user); + } + + return 0; +} + +int seat_active_vt_changed(Seat *s, int vtnr) { + Session *i, *new_active = NULL; + int r; + + assert(s); + assert(vtnr >= 1); + + if (!seat_can_multi_session(s)) + return -EINVAL; + + log_debug("VT changed to %i", vtnr); + + LIST_FOREACH(sessions_by_seat, i, s->sessions) + if (i->vtnr == vtnr) { + new_active = i; + break; + } + + r = seat_set_active(s, new_active); + manager_spawn_autovt(s->manager, vtnr); + + return r; +} + +int seat_read_active_vt(Seat *s) { + char t[64]; + ssize_t k; + int r, vtnr; + + assert(s); + + if (!seat_can_multi_session(s)) + return 0; + + lseek(s->manager->console_active_fd, SEEK_SET, 0); + + k = read(s->manager->console_active_fd, t, sizeof(t)-1); + if (k <= 0) { + log_error("Failed to read current console: %s", k < 0 ? strerror(-errno) : "EOF"); + return k < 0 ? -errno : -EIO; + } + + t[k] = 0; + truncate_nl(t); + + if (!startswith(t, "tty")) { + log_error("Hm, /sys/class/tty/tty0/active is badly formatted."); + return -EIO; + } + + r = safe_atoi(t+3, &vtnr); + if (r < 0) { + log_error("Failed to parse VT number %s", t+3); + return r; + } + + if (vtnr <= 0) { + log_error("VT number invalid: %s", t+3); + return -EIO; + } + + return seat_active_vt_changed(s, vtnr); +} + +int seat_start(Seat *s) { + assert(s); + + if (s->started) + return 0; + + log_struct(LOG_INFO, + MESSAGE_ID(SD_MESSAGE_SEAT_START), + "SEAT_ID=%s", s->id, + "MESSAGE=New seat %s.", s->id, + NULL); + + /* Initialize VT magic stuff */ + seat_preallocate_vts(s); + + /* Read current VT */ + seat_read_active_vt(s); + + s->started = true; + + /* Save seat data */ + seat_save(s); + + seat_send_signal(s, true); + + return 0; +} + +int seat_stop(Seat *s) { + int r = 0; + + assert(s); + + if (s->started) + log_struct(LOG_INFO, + MESSAGE_ID(SD_MESSAGE_SEAT_STOP), + "SEAT_ID=%s", s->id, + "MESSAGE=Removed seat %s.", s->id, + NULL); + + seat_stop_sessions(s); + + unlink(s->state_file); + seat_add_to_gc_queue(s); + + if (s->started) + seat_send_signal(s, false); + + s->started = false; + + return r; +} + +int seat_stop_sessions(Seat *s) { + Session *session; + int r = 0, k; + + assert(s); + + LIST_FOREACH(sessions_by_seat, session, s->sessions) { + k = session_stop(session); + if (k < 0) + r = k; + } + + return r; +} + +int seat_attach_session(Seat *s, Session *session) { + assert(s); + assert(session); + assert(!session->seat); + + session->seat = s; + LIST_PREPEND(Session, sessions_by_seat, s->sessions, session); + + seat_send_changed(s, "Sessions\0"); + + /* Note that even if a seat is not multi-session capable it + * still might have multiple sessions on it since old, dead + * sessions might continue to be tracked until all their + * processes are gone. The most recently added session + * (i.e. the first in s->sessions) is the one that matters. */ + + if (!seat_can_multi_session(s)) + seat_set_active(s, session); + + return 0; +} + +bool seat_is_vtconsole(Seat *s) { + assert(s); + + return s->manager->vtconsole == s; +} + +bool seat_can_multi_session(Seat *s) { + assert(s); + + if (!seat_is_vtconsole(s)) + return false; + + /* If we can't watch which VT is in the foreground, we don't + * support VT switching */ + + return s->manager->console_active_fd >= 0; +} + +bool seat_can_tty(Seat *s) { + assert(s); + + return seat_is_vtconsole(s); +} + +bool seat_can_graphical(Seat *s) { + assert(s); + + return !!s->devices; +} + +int seat_get_idle_hint(Seat *s, dual_timestamp *t) { + Session *session; + bool idle_hint = true; + dual_timestamp ts = { 0, 0 }; + + assert(s); + + LIST_FOREACH(sessions_by_seat, session, s->sessions) { + dual_timestamp k; + int ih; + + ih = session_get_idle_hint(session, &k); + if (ih < 0) + return ih; + + if (!ih) { + if (!idle_hint) { + if (k.monotonic > ts.monotonic) + ts = k; + } else { + idle_hint = false; + ts = k; + } + } else if (idle_hint) { + + if (k.monotonic > ts.monotonic) + ts = k; + } + } + + if (t) + *t = ts; + + return idle_hint; +} + +int seat_check_gc(Seat *s, bool drop_not_started) { + assert(s); + + if (drop_not_started && !s->started) + return 0; + + if (seat_is_vtconsole(s)) + return 1; + + return !!s->devices; +} + +void seat_add_to_gc_queue(Seat *s) { + assert(s); + + if (s->in_gc_queue) + return; + + LIST_PREPEND(Seat, gc_queue, s->manager->seat_gc_queue, s); + s->in_gc_queue = true; +} + +static bool seat_name_valid_char(char c) { + return + (c >= 'a' && c <= 'z') || + (c >= 'A' && c <= 'Z') || + (c >= '0' && c <= '9') || + c == '-' || + c == '_'; +} + +bool seat_name_is_valid(const char *name) { + const char *p; + + assert(name); + + if (!startswith(name, "seat")) + return false; + + if (!name[4]) + return false; + + for (p = name; *p; p++) + if (!seat_name_valid_char(*p)) + return false; + + if (strlen(name) > 255) + return false; + + return true; +} diff --git a/src/login/logind-seat.h b/src/login/logind-seat.h new file mode 100644 index 000000000..c8ab17f7c --- /dev/null +++ b/src/login/logind-seat.h @@ -0,0 +1,83 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +typedef struct Seat Seat; + +#include "list.h" +#include "util.h" +#include "logind.h" +#include "logind-device.h" +#include "logind-session.h" + +struct Seat { + Manager *manager; + char *id; + + char *state_file; + + LIST_HEAD(Device, devices); + + Session *active; + LIST_HEAD(Session, sessions); + + bool in_gc_queue:1; + bool started:1; + + LIST_FIELDS(Seat, gc_queue); +}; + +Seat *seat_new(Manager *m, const char *id); +void seat_free(Seat *s); + +int seat_save(Seat *s); +int seat_load(Seat *s); + +int seat_apply_acls(Seat *s, Session *old_active); +int seat_set_active(Seat *s, Session *session); +int seat_active_vt_changed(Seat *s, int vtnr); +int seat_read_active_vt(Seat *s); +int seat_preallocate_vts(Seat *s); + +int seat_attach_session(Seat *s, Session *session); + +bool seat_is_vtconsole(Seat *s); +bool seat_can_multi_session(Seat *s); +bool seat_can_tty(Seat *s); +bool seat_can_graphical(Seat *s); + +int seat_get_idle_hint(Seat *s, dual_timestamp *t); + +int seat_start(Seat *s); +int seat_stop(Seat *s); +int seat_stop_sessions(Seat *s); + +int seat_check_gc(Seat *s, bool drop_not_started); +void seat_add_to_gc_queue(Seat *s); + +bool seat_name_is_valid(const char *name); +char *seat_bus_path(Seat *s); + +extern const DBusObjectPathVTable bus_seat_vtable; + +int seat_send_signal(Seat *s, bool new_seat); +int seat_send_changed(Seat *s, const char *properties); diff --git a/src/login/logind-session-dbus.c b/src/login/logind-session-dbus.c new file mode 100644 index 000000000..ef73cd434 --- /dev/null +++ b/src/login/logind-session-dbus.c @@ -0,0 +1,590 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +#include +#include + +#include "logind.h" +#include "logind-session.h" +#include "dbus-common.h" +#include "util.h" + +#define BUS_SESSION_INTERFACE \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" + +#define INTROSPECTION \ + DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \ + "\n" \ + BUS_SESSION_INTERFACE \ + BUS_PROPERTIES_INTERFACE \ + BUS_PEER_INTERFACE \ + BUS_INTROSPECTABLE_INTERFACE \ + "\n" + +#define INTERFACES_LIST \ + BUS_GENERIC_INTERFACES_LIST \ + "org.freedesktop.login1.Session\0" + +static int bus_session_append_seat(DBusMessageIter *i, const char *property, void *data) { + DBusMessageIter sub; + Session *s = data; + const char *id, *path; + char *p = NULL; + + assert(i); + assert(property); + assert(s); + + if (!dbus_message_iter_open_container(i, DBUS_TYPE_STRUCT, NULL, &sub)) + return -ENOMEM; + + if (s->seat) { + id = s->seat->id; + path = p = seat_bus_path(s->seat); + + if (!p) + return -ENOMEM; + } else { + id = ""; + path = "/"; + } + + if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &id) || + !dbus_message_iter_append_basic(&sub, DBUS_TYPE_OBJECT_PATH, &path)) { + free(p); + return -ENOMEM; + } + + free(p); + + if (!dbus_message_iter_close_container(i, &sub)) + return -ENOMEM; + + return 0; +} + +static int bus_session_append_user(DBusMessageIter *i, const char *property, void *data) { + DBusMessageIter sub; + User *u = data; + char *p = NULL; + + assert(i); + assert(property); + assert(u); + + if (!dbus_message_iter_open_container(i, DBUS_TYPE_STRUCT, NULL, &sub)) + return -ENOMEM; + + p = user_bus_path(u); + if (!p) + return -ENOMEM; + + if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_UINT32, &u->uid) || + !dbus_message_iter_append_basic(&sub, DBUS_TYPE_OBJECT_PATH, &p)) { + free(p); + return -ENOMEM; + } + + free(p); + + if (!dbus_message_iter_close_container(i, &sub)) + return -ENOMEM; + + return 0; +} + +static int bus_session_append_active(DBusMessageIter *i, const char *property, void *data) { + Session *s = data; + dbus_bool_t b; + + assert(i); + assert(property); + assert(s); + + b = session_is_active(s); + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b)) + return -ENOMEM; + + return 0; +} + +static int bus_session_append_idle_hint(DBusMessageIter *i, const char *property, void *data) { + Session *s = data; + int b; + + assert(i); + assert(property); + assert(s); + + b = session_get_idle_hint(s, NULL) > 0; + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b)) + return -ENOMEM; + + return 0; +} + +static int bus_session_append_idle_hint_since(DBusMessageIter *i, const char *property, void *data) { + Session *s = data; + dual_timestamp t; + uint64_t u; + int r; + + assert(i); + assert(property); + assert(s); + + r = session_get_idle_hint(s, &t); + if (r < 0) + return r; + + u = streq(property, "IdleSinceHint") ? t.realtime : t.monotonic; + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_UINT64, &u)) + return -ENOMEM; + + return 0; +} + +static int bus_session_append_default_cgroup(DBusMessageIter *i, const char *property, void *data) { + Session *s = data; + char *t; + int r; + bool success; + + assert(i); + assert(property); + assert(s); + + r = cg_join_spec(SYSTEMD_CGROUP_CONTROLLER, s->cgroup_path, &t); + if (r < 0) + return r; + + success = dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &t); + free(t); + + return success ? 0 : -ENOMEM; +} + +static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_session_append_type, session_type, SessionType); +static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_session_append_class, session_class, SessionClass); + +static int bus_session_append_state(DBusMessageIter *i, const char *property, void *data) { + Session *s = data; + const char *state; + + assert(i); + assert(property); + assert(s); + + state = session_state_to_string(session_get_state(s)); + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &state)) + return -ENOMEM; + + return 0; +} + +static int get_session_for_path(Manager *m, const char *path, Session **_s) { + Session *s; + char *id; + + assert(m); + assert(path); + assert(_s); + + if (!startswith(path, "/org/freedesktop/login1/session/")) + return -EINVAL; + + id = bus_path_unescape(path + 32); + if (!id) + return -ENOMEM; + + s = hashmap_get(m->sessions, id); + free(id); + + if (!s) + return -ENOENT; + + *_s = s; + return 0; +} + +static const BusProperty bus_login_session_properties[] = { + { "Id", bus_property_append_string, "s", offsetof(Session, id), true }, + { "Timestamp", bus_property_append_usec, "t", offsetof(Session, timestamp.realtime) }, + { "TimestampMonotonic", bus_property_append_usec, "t", offsetof(Session, timestamp.monotonic) }, + { "DefaultControlGroup", bus_session_append_default_cgroup, "s", 0, }, + { "VTNr", bus_property_append_uint32, "u", offsetof(Session, vtnr) }, + { "Seat", bus_session_append_seat, "(so)", 0 }, + { "TTY", bus_property_append_string, "s", offsetof(Session, tty), true }, + { "Display", bus_property_append_string, "s", offsetof(Session, display), true }, + { "Remote", bus_property_append_bool, "b", offsetof(Session, remote) }, + { "RemoteUser", bus_property_append_string, "s", offsetof(Session, remote_user), true }, + { "RemoteHost", bus_property_append_string, "s", offsetof(Session, remote_host), true }, + { "Service", bus_property_append_string, "s", offsetof(Session, service), true }, + { "Leader", bus_property_append_pid, "u", offsetof(Session, leader) }, + { "Audit", bus_property_append_uint32, "u", offsetof(Session, audit_id) }, + { "Type", bus_session_append_type, "s", offsetof(Session, type) }, + { "Class", bus_session_append_class, "s", offsetof(Session, class) }, + { "Active", bus_session_append_active, "b", 0 }, + { "State", bus_session_append_state, "s", 0 }, + { "Controllers", bus_property_append_strv, "as", offsetof(Session, controllers), true }, + { "ResetControllers", bus_property_append_strv, "as", offsetof(Session, reset_controllers), true }, + { "KillProcesses", bus_property_append_bool, "b", offsetof(Session, kill_processes) }, + { "IdleHint", bus_session_append_idle_hint, "b", 0 }, + { "IdleSinceHint", bus_session_append_idle_hint_since, "t", 0 }, + { "IdleSinceHintMonotonic", bus_session_append_idle_hint_since, "t", 0 }, + { NULL, } +}; + +static const BusProperty bus_login_session_user_properties[] = { + { "User", bus_session_append_user, "(uo)", 0 }, + { "Name", bus_property_append_string, "s", offsetof(User, name), true }, + { NULL, } +}; + +static DBusHandlerResult session_message_dispatch( + Session *s, + DBusConnection *connection, + DBusMessage *message) { + + DBusError error; + DBusMessage *reply = NULL; + int r; + + assert(s); + assert(connection); + assert(message); + + dbus_error_init(&error); + + if (dbus_message_is_method_call(message, "org.freedesktop.login1.Session", "Terminate")) { + + r = session_stop(s); + if (r < 0) + return bus_send_error_reply(connection, message, NULL, r); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Session", "Activate")) { + + r = session_activate(s); + if (r < 0) + return bus_send_error_reply(connection, message, NULL, r); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Session", "Lock") || + dbus_message_is_method_call(message, "org.freedesktop.login1.Session", "Unlock")) { + + if (session_send_lock(s, streq(dbus_message_get_member(message), "Lock")) < 0) + goto oom; + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Session", "SetIdleHint")) { + dbus_bool_t b; + unsigned long ul; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_BOOLEAN, &b, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + ul = dbus_bus_get_unix_user(connection, dbus_message_get_sender(message), &error); + if (ul == (unsigned long) -1) + return bus_send_error_reply(connection, message, &error, -EIO); + + if (ul != 0 && ul != s->user->uid) + return bus_send_error_reply(connection, message, NULL, -EPERM); + + session_set_idle_hint(s, b); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Session", "Kill")) { + const char *swho; + int32_t signo; + KillWho who; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &swho, + DBUS_TYPE_INT32, &signo, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + if (isempty(swho)) + who = KILL_ALL; + else { + who = kill_who_from_string(swho); + if (who < 0) + return bus_send_error_reply(connection, message, &error, -EINVAL); + } + + if (signo <= 0 || signo >= _NSIG) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + r = session_kill(s, who, signo); + if (r < 0) + return bus_send_error_reply(connection, message, NULL, r); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + } else { + const BusBoundProperties bps[] = { + { "org.freedesktop.login1.Session", bus_login_session_properties, s }, + { "org.freedesktop.login1.Session", bus_login_session_user_properties, s->user }, + { NULL, } + }; + return bus_default_message_handler(connection, message, INTROSPECTION, INTERFACES_LIST, bps); + } + + if (reply) { + if (!dbus_connection_send(connection, reply, NULL)) + goto oom; + + dbus_message_unref(reply); + } + + return DBUS_HANDLER_RESULT_HANDLED; + +oom: + if (reply) + dbus_message_unref(reply); + + dbus_error_free(&error); + + return DBUS_HANDLER_RESULT_NEED_MEMORY; +} + +static DBusHandlerResult session_message_handler( + DBusConnection *connection, + DBusMessage *message, + void *userdata) { + + Manager *m = userdata; + Session *s; + int r; + + r = get_session_for_path(m, dbus_message_get_path(message), &s); + if (r < 0) { + + if (r == -ENOMEM) + return DBUS_HANDLER_RESULT_NEED_MEMORY; + + if (r == -ENOENT) { + DBusError e; + + dbus_error_init(&e); + dbus_set_error_const(&e, DBUS_ERROR_UNKNOWN_OBJECT, "Unknown session"); + return bus_send_error_reply(connection, message, &e, r); + } + + return bus_send_error_reply(connection, message, NULL, r); + } + + return session_message_dispatch(s, connection, message); +} + +const DBusObjectPathVTable bus_session_vtable = { + .message_function = session_message_handler +}; + +char *session_bus_path(Session *s) { + char *t, *r; + + assert(s); + + t = bus_path_escape(s->id); + if (!t) + return NULL; + + r = strappend("/org/freedesktop/login1/session/", t); + free(t); + + return r; +} + +int session_send_signal(Session *s, bool new_session) { + DBusMessage *m; + int r = -ENOMEM; + char *p = NULL; + + assert(s); + + m = dbus_message_new_signal("/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + new_session ? "SessionNew" : "SessionRemoved"); + + if (!m) + return -ENOMEM; + + p = session_bus_path(s); + if (!p) + goto finish; + + if (!dbus_message_append_args( + m, + DBUS_TYPE_STRING, &s->id, + DBUS_TYPE_OBJECT_PATH, &p, + DBUS_TYPE_INVALID)) + goto finish; + + if (!dbus_connection_send(s->manager->bus, m, NULL)) + goto finish; + + r = 0; + +finish: + dbus_message_unref(m); + free(p); + + return r; +} + +int session_send_changed(Session *s, const char *properties) { + DBusMessage *m; + int r = -ENOMEM; + char *p = NULL; + + assert(s); + + if (!s->started) + return 0; + + p = session_bus_path(s); + if (!p) + return -ENOMEM; + + m = bus_properties_changed_new(p, "org.freedesktop.login1.Session", properties); + if (!m) + goto finish; + + if (!dbus_connection_send(s->manager->bus, m, NULL)) + goto finish; + + r = 0; + +finish: + if (m) + dbus_message_unref(m); + free(p); + + return r; +} + +int session_send_lock(Session *s, bool lock) { + DBusMessage *m; + bool b; + char *p; + + assert(s); + + p = session_bus_path(s); + if (!p) + return -ENOMEM; + + m = dbus_message_new_signal(p, "org.freedesktop.login1.Session", lock ? "Lock" : "Unlock"); + free(p); + + if (!m) + return -ENOMEM; + + b = dbus_connection_send(s->manager->bus, m, NULL); + dbus_message_unref(m); + + if (!b) + return -ENOMEM; + + return 0; +} + +int session_send_lock_all(Manager *m, bool lock) { + Session *session; + Iterator i; + int r = 0; + + assert(m); + + HASHMAP_FOREACH(session, m->sessions, i) { + int k; + + k = session_send_lock(session, lock); + if (k < 0) + r = k; + } + + return r; +} diff --git a/src/login/logind-session.c b/src/login/logind-session.c new file mode 100644 index 000000000..b64a5d302 --- /dev/null +++ b/src/login/logind-session.c @@ -0,0 +1,1070 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +#include +#include +#include +#include +#include + +#include "systemd/sd-id128.h" +#include "systemd/sd-messages.h" +#include "strv.h" +#include "util.h" +#include "mkdir.h" +#include "path-util.h" +#include "cgroup-util.h" +#include "logind-session.h" + +Session* session_new(Manager *m, User *u, const char *id) { + Session *s; + + assert(m); + assert(id); + + s = new0(Session, 1); + if (!s) + return NULL; + + s->state_file = strappend("/run/systemd/sessions/", id); + if (!s->state_file) { + free(s); + return NULL; + } + + s->id = path_get_file_name(s->state_file); + + if (hashmap_put(m->sessions, s->id, s) < 0) { + free(s->state_file); + free(s); + return NULL; + } + + s->manager = m; + s->fifo_fd = -1; + s->user = u; + + LIST_PREPEND(Session, sessions_by_user, u->sessions, s); + + return s; +} + +void session_free(Session *s) { + assert(s); + + if (s->in_gc_queue) + LIST_REMOVE(Session, gc_queue, s->manager->session_gc_queue, s); + + if (s->user) { + LIST_REMOVE(Session, sessions_by_user, s->user->sessions, s); + + if (s->user->display == s) + s->user->display = NULL; + } + + if (s->seat) { + if (s->seat->active == s) + s->seat->active = NULL; + + LIST_REMOVE(Session, sessions_by_seat, s->seat->sessions, s); + } + + if (s->cgroup_path) + hashmap_remove(s->manager->session_cgroups, s->cgroup_path); + + free(s->cgroup_path); + strv_free(s->controllers); + + free(s->tty); + free(s->display); + free(s->remote_host); + free(s->remote_user); + free(s->service); + + hashmap_remove(s->manager->sessions, s->id); + session_remove_fifo(s); + + free(s->state_file); + free(s); +} + +int session_save(Session *s) { + FILE *f; + int r = 0; + char *temp_path; + + assert(s); + + if (!s->started) + return 0; + + r = mkdir_safe_label("/run/systemd/sessions", 0755, 0, 0); + if (r < 0) + goto finish; + + r = fopen_temporary(s->state_file, &f, &temp_path); + if (r < 0) + goto finish; + + assert(s->user); + + fchmod(fileno(f), 0644); + + fprintf(f, + "# This is private data. Do not parse.\n" + "UID=%lu\n" + "USER=%s\n" + "ACTIVE=%i\n" + "STATE=%s\n" + "REMOTE=%i\n" + "KILL_PROCESSES=%i\n", + (unsigned long) s->user->uid, + s->user->name, + session_is_active(s), + session_state_to_string(session_get_state(s)), + s->remote, + s->kill_processes); + + if (s->type >= 0) + fprintf(f, + "TYPE=%s\n", + session_type_to_string(s->type)); + + if (s->class >= 0) + fprintf(f, + "CLASS=%s\n", + session_class_to_string(s->class)); + + if (s->cgroup_path) + fprintf(f, + "CGROUP=%s\n", + s->cgroup_path); + + if (s->fifo_path) + fprintf(f, + "FIFO=%s\n", + s->fifo_path); + + if (s->seat) + fprintf(f, + "SEAT=%s\n", + s->seat->id); + + if (s->tty) + fprintf(f, + "TTY=%s\n", + s->tty); + + if (s->display) + fprintf(f, + "DISPLAY=%s\n", + s->display); + + if (s->remote_host) + fprintf(f, + "REMOTE_HOST=%s\n", + s->remote_host); + + if (s->remote_user) + fprintf(f, + "REMOTE_USER=%s\n", + s->remote_user); + + if (s->service) + fprintf(f, + "SERVICE=%s\n", + s->service); + + if (s->seat && seat_can_multi_session(s->seat)) + fprintf(f, + "VTNR=%i\n", + s->vtnr); + + if (s->leader > 0) + fprintf(f, + "LEADER=%lu\n", + (unsigned long) s->leader); + + if (s->audit_id > 0) + fprintf(f, + "AUDIT=%llu\n", + (unsigned long long) s->audit_id); + + fflush(f); + + if (ferror(f) || rename(temp_path, s->state_file) < 0) { + r = -errno; + unlink(s->state_file); + unlink(temp_path); + } + + fclose(f); + free(temp_path); + +finish: + if (r < 0) + log_error("Failed to save session data for %s: %s", s->id, strerror(-r)); + + return r; +} + +int session_load(Session *s) { + char *remote = NULL, + *kill_processes = NULL, + *seat = NULL, + *vtnr = NULL, + *leader = NULL, + *audit_id = NULL, + *type = NULL, + *class = NULL; + + int k, r; + + assert(s); + + r = parse_env_file(s->state_file, NEWLINE, + "REMOTE", &remote, + "KILL_PROCESSES", &kill_processes, + "CGROUP", &s->cgroup_path, + "FIFO", &s->fifo_path, + "SEAT", &seat, + "TTY", &s->tty, + "DISPLAY", &s->display, + "REMOTE_HOST", &s->remote_host, + "REMOTE_USER", &s->remote_user, + "SERVICE", &s->service, + "VTNR", &vtnr, + "LEADER", &leader, + "TYPE", &type, + "CLASS", &class, + NULL); + + if (r < 0) + goto finish; + + if (remote) { + k = parse_boolean(remote); + if (k >= 0) + s->remote = k; + } + + if (kill_processes) { + k = parse_boolean(kill_processes); + if (k >= 0) + s->kill_processes = k; + } + + if (seat && !s->seat) { + Seat *o; + + o = hashmap_get(s->manager->seats, seat); + if (o) + seat_attach_session(o, s); + } + + if (vtnr && s->seat && seat_can_multi_session(s->seat)) { + int v; + + k = safe_atoi(vtnr, &v); + if (k >= 0 && v >= 1) + s->vtnr = v; + } + + if (leader) { + k = parse_pid(leader, &s->leader); + if (k >= 0) + audit_session_from_pid(s->leader, &s->audit_id); + } + + if (type) { + SessionType t; + + t = session_type_from_string(type); + if (t >= 0) + s->type = t; + } + + if (class) { + SessionClass c; + + c = session_class_from_string(class); + if (c >= 0) + s->class = c; + } + + if (s->fifo_path) { + int fd; + + /* If we open an unopened pipe for reading we will not + get an EOF. to trigger an EOF we hence open it for + reading, but close it right-away which then will + trigger the EOF. */ + + fd = session_create_fifo(s); + if (fd >= 0) + close_nointr_nofail(fd); + } + +finish: + free(remote); + free(kill_processes); + free(seat); + free(vtnr); + free(leader); + free(audit_id); + free(class); + + return r; +} + +int session_activate(Session *s) { + int r; + + assert(s); + + if (s->vtnr < 0) + return -ENOTSUP; + + if (!s->seat) + return -ENOTSUP; + + if (s->seat->active == s) + return 0; + + assert(seat_is_vtconsole(s->seat)); + + r = chvt(s->vtnr); + if (r < 0) + return r; + + return seat_set_active(s->seat, s); +} + +static int session_link_x11_socket(Session *s) { + char *t, *f, *c; + size_t k; + + assert(s); + assert(s->user); + assert(s->user->runtime_path); + + if (s->user->display) + return 0; + + if (!s->display || !display_is_local(s->display)) + return 0; + + k = strspn(s->display+1, "0123456789"); + f = new(char, sizeof("/tmp/.X11-unix/X") + k); + if (!f) + return log_oom(); + + c = stpcpy(f, "/tmp/.X11-unix/X"); + memcpy(c, s->display+1, k); + c[k] = 0; + + if (access(f, F_OK) < 0) { + log_warning("Session %s has display %s with non-existing socket %s.", s->id, s->display, f); + free(f); + return -ENOENT; + } + + /* Note that this cannot be in a subdir to avoid + * vulnerabilities since we are privileged but the runtime + * path is owned by the user */ + + t = strappend(s->user->runtime_path, "/X11-display"); + if (!t) { + free(f); + return log_oom(); + } + + if (link(f, t) < 0) { + if (errno == EEXIST) { + unlink(t); + + if (link(f, t) >= 0) + goto done; + } + + if (symlink(f, t) < 0) { + + if (errno == EEXIST) { + unlink(t); + + if (symlink(f, t) >= 0) + goto done; + } + + log_error("Failed to link %s to %s: %m", f, t); + free(f); + free(t); + return -errno; + } + } + +done: + log_info("Linked %s to %s.", f, t); + free(f); + free(t); + + s->user->display = s; + + return 0; +} + +static int session_create_one_group(Session *s, const char *controller, const char *path) { + int r; + + assert(s); + assert(controller); + assert(path); + + if (s->leader > 0) { + r = cg_create_and_attach(controller, path, s->leader); + if (r < 0) + r = cg_create(controller, path); + } else + r = cg_create(controller, path); + + if (r < 0) + return r; + + r = cg_set_task_access(controller, path, 0644, s->user->uid, s->user->gid, -1); + if (r >= 0) + r = cg_set_group_access(controller, path, 0755, s->user->uid, s->user->gid); + + return r; +} + +static int session_create_cgroup(Session *s) { + char **k; + char *p; + int r; + + assert(s); + assert(s->user); + assert(s->user->cgroup_path); + + if (!s->cgroup_path) { + if (asprintf(&p, "%s/%s", s->user->cgroup_path, s->id) < 0) + return log_oom(); + } else + p = s->cgroup_path; + + r = session_create_one_group(s, SYSTEMD_CGROUP_CONTROLLER, p); + if (r < 0) { + log_error("Failed to create "SYSTEMD_CGROUP_CONTROLLER":%s: %s", p, strerror(-r)); + free(p); + s->cgroup_path = NULL; + return r; + } + + s->cgroup_path = p; + + STRV_FOREACH(k, s->controllers) { + + if (strv_contains(s->reset_controllers, *k)) + continue; + + r = session_create_one_group(s, *k, p); + if (r < 0) + log_warning("Failed to create %s:%s: %s", *k, p, strerror(-r)); + } + + STRV_FOREACH(k, s->manager->controllers) { + + if (strv_contains(s->reset_controllers, *k) || + strv_contains(s->manager->reset_controllers, *k) || + strv_contains(s->controllers, *k)) + continue; + + r = session_create_one_group(s, *k, p); + if (r < 0) + log_warning("Failed to create %s:%s: %s", *k, p, strerror(-r)); + } + + if (s->leader > 0) { + + STRV_FOREACH(k, s->reset_controllers) { + r = cg_attach(*k, "/", s->leader); + if (r < 0) + log_warning("Failed to reset controller %s: %s", *k, strerror(-r)); + + } + + STRV_FOREACH(k, s->manager->reset_controllers) { + + if (strv_contains(s->reset_controllers, *k) || + strv_contains(s->controllers, *k)) + continue; + + r = cg_attach(*k, "/", s->leader); + if (r < 0) + log_warning("Failed to reset controller %s: %s", *k, strerror(-r)); + + } + } + + r = hashmap_put(s->manager->session_cgroups, s->cgroup_path, s); + if (r < 0) + log_warning("Failed to create mapping between cgroup and session"); + + return 0; +} + +int session_start(Session *s) { + int r; + + assert(s); + assert(s->user); + + if (s->started) + return 0; + + r = user_start(s->user); + if (r < 0) + return r; + + log_struct(s->type == SESSION_TTY || s->type == SESSION_X11 ? LOG_INFO : LOG_DEBUG, + MESSAGE_ID(SD_MESSAGE_SESSION_START), + "SESSION_ID=%s", s->id, + "USER_ID=%s", s->user->name, + "LEADER=%lu", (unsigned long) s->leader, + "MESSAGE=New session %s of user %s.", s->id, s->user->name, + NULL); + + /* Create cgroup */ + r = session_create_cgroup(s); + if (r < 0) + return r; + + /* Create X11 symlink */ + session_link_x11_socket(s); + + dual_timestamp_get(&s->timestamp); + + if (s->seat) + seat_read_active_vt(s->seat); + + s->started = true; + + /* Save session data */ + session_save(s); + user_save(s->user); + + session_send_signal(s, true); + + if (s->seat) { + seat_save(s->seat); + + if (s->seat->active == s) + seat_send_changed(s->seat, "Sessions\0ActiveSession\0"); + else + seat_send_changed(s->seat, "Sessions\0"); + } + + user_send_changed(s->user, "Sessions\0"); + + return 0; +} + +static bool session_shall_kill(Session *s) { + assert(s); + + if (!s->kill_processes) + return false; + + if (strv_contains(s->manager->kill_exclude_users, s->user->name)) + return false; + + if (strv_isempty(s->manager->kill_only_users)) + return true; + + return strv_contains(s->manager->kill_only_users, s->user->name); +} + +static int session_terminate_cgroup(Session *s) { + int r; + char **k; + + assert(s); + + if (!s->cgroup_path) + return 0; + + cg_trim(SYSTEMD_CGROUP_CONTROLLER, s->cgroup_path, false); + + if (session_shall_kill(s)) { + + r = cg_kill_recursive_and_wait(SYSTEMD_CGROUP_CONTROLLER, s->cgroup_path, true); + if (r < 0) + log_error("Failed to kill session cgroup: %s", strerror(-r)); + + } else { + if (s->leader > 0) { + Session *t; + + /* We still send a HUP to the leader process, + * even if we are not supposed to kill the + * whole cgroup. But let's first check the + * leader still exists and belongs to our + * session... */ + + r = manager_get_session_by_pid(s->manager, s->leader, &t); + if (r > 0 && t == s) { + kill(s->leader, SIGTERM); /* for normal processes */ + kill(s->leader, SIGHUP); /* for shells */ + kill(s->leader, SIGCONT); /* in case they are stopped */ + } + } + + r = cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, s->cgroup_path, true); + if (r < 0) + log_error("Failed to check session cgroup: %s", strerror(-r)); + else if (r > 0) { + r = cg_delete(SYSTEMD_CGROUP_CONTROLLER, s->cgroup_path); + if (r < 0) + log_error("Failed to delete session cgroup: %s", strerror(-r)); + } + } + + STRV_FOREACH(k, s->user->manager->controllers) + cg_trim(*k, s->cgroup_path, true); + + hashmap_remove(s->manager->session_cgroups, s->cgroup_path); + + free(s->cgroup_path); + s->cgroup_path = NULL; + + return 0; +} + +static int session_unlink_x11_socket(Session *s) { + char *t; + int r; + + assert(s); + assert(s->user); + + if (s->user->display != s) + return 0; + + s->user->display = NULL; + + t = strappend(s->user->runtime_path, "/X11-display"); + if (!t) + return log_oom(); + + r = unlink(t); + free(t); + + return r < 0 ? -errno : 0; +} + +int session_stop(Session *s) { + int r = 0, k; + + assert(s); + + if (s->started) + log_struct(s->type == SESSION_TTY || s->type == SESSION_X11 ? LOG_INFO : LOG_DEBUG, + MESSAGE_ID(SD_MESSAGE_SESSION_STOP), + "SESSION_ID=%s", s->id, + "USER_ID=%s", s->user->name, + "LEADER=%lu", (unsigned long) s->leader, + "MESSAGE=Removed session %s.", s->id, + NULL); + + /* Kill cgroup */ + k = session_terminate_cgroup(s); + if (k < 0) + r = k; + + /* Remove X11 symlink */ + session_unlink_x11_socket(s); + + unlink(s->state_file); + session_add_to_gc_queue(s); + user_add_to_gc_queue(s->user); + + if (s->started) + session_send_signal(s, false); + + if (s->seat) { + if (s->seat->active == s) + seat_set_active(s->seat, NULL); + + seat_send_changed(s->seat, "Sessions\0"); + seat_save(s->seat); + } + + user_send_changed(s->user, "Sessions\0"); + user_save(s->user); + + s->started = false; + + return r; +} + +bool session_is_active(Session *s) { + assert(s); + + if (!s->seat) + return true; + + return s->seat->active == s; +} + +static int get_tty_atime(const char *tty, usec_t *atime) { + _cleanup_free_ char *p = NULL; + struct stat st; + + assert(tty); + assert(atime); + + if (!path_is_absolute(tty)) { + p = strappend("/dev/", tty); + if (!p) + return -ENOMEM; + + tty = p; + } else if (!path_startswith(tty, "/dev/")) + return -ENOENT; + + if (lstat(tty, &st) < 0) + return -errno; + + *atime = timespec_load(&st.st_atim); + return 0; +} + +static int get_process_ctty_atime(pid_t pid, usec_t *atime) { + _cleanup_free_ char *p = NULL; + int r; + + assert(pid > 0); + assert(atime); + + r = get_ctty(pid, NULL, &p); + if (r < 0) + return r; + + return get_tty_atime(p, atime); +} + +int session_get_idle_hint(Session *s, dual_timestamp *t) { + _cleanup_free_ char *p = NULL; + usec_t atime = 0, n; + int r; + + assert(s); + + /* Explicit idle hint is set */ + if (s->idle_hint) { + if (t) + *t = s->idle_hint_timestamp; + + return s->idle_hint; + } + + /* Graphical sessions really should really implement a real + * idle hint logic */ + if (s->display) + goto dont_know; + + /* For sessions with an explicitly configured tty, let's check + * its atime */ + if (s->tty) { + r = get_tty_atime(s->tty, &atime); + if (r >= 0) + goto found_atime; + } + + /* For sessions with a leader but no explicitly configured + * tty, let's check the controlling tty of the leader */ + if (s->leader > 0) { + r = get_process_ctty_atime(s->leader, &atime); + if (r >= 0) + goto found_atime; + } + + /* For other TTY sessions, let's find the most recent atime of + * the ttys of any of the processes of the session */ + if (s->cgroup_path) { + _cleanup_fclose_ FILE *f = NULL; + + if (cg_enumerate_processes(SYSTEMD_CGROUP_CONTROLLER, s->cgroup_path, &f) >= 0) { + pid_t pid; + + atime = 0; + while (cg_read_pid(f, &pid) > 0) { + usec_t a; + + if (get_process_ctty_atime(pid, &a) >= 0) + if (atime == 0 || atime < a) + atime = a; + } + + if (atime != 0) + goto found_atime; + } + } + +dont_know: + if (t) + *t = s->idle_hint_timestamp; + + return 0; + +found_atime: + if (t) + dual_timestamp_from_realtime(t, atime); + + n = now(CLOCK_REALTIME); + + if (s->manager->idle_action_usec <= 0) + return 0; + + return atime + s->manager->idle_action_usec <= n; +} + +void session_set_idle_hint(Session *s, bool b) { + assert(s); + + if (s->idle_hint == b) + return; + + s->idle_hint = b; + dual_timestamp_get(&s->idle_hint_timestamp); + + session_send_changed(s, + "IdleHint\0" + "IdleSinceHint\0" + "IdleSinceHintMonotonic\0"); + + if (s->seat) + seat_send_changed(s->seat, + "IdleHint\0" + "IdleSinceHint\0" + "IdleSinceHintMonotonic\0"); + + user_send_changed(s->user, + "IdleHint\0" + "IdleSinceHint\0" + "IdleSinceHintMonotonic\0"); + + manager_send_changed(s->manager, + "IdleHint\0" + "IdleSinceHint\0" + "IdleSinceHintMonotonic\0"); +} + +int session_create_fifo(Session *s) { + int r; + + assert(s); + + /* Create FIFO */ + if (!s->fifo_path) { + r = mkdir_safe_label("/run/systemd/sessions", 0755, 0, 0); + if (r < 0) + return r; + + if (asprintf(&s->fifo_path, "/run/systemd/sessions/%s.ref", s->id) < 0) + return -ENOMEM; + + if (mkfifo(s->fifo_path, 0600) < 0 && errno != EEXIST) + return -errno; + } + + /* Open reading side */ + if (s->fifo_fd < 0) { + struct epoll_event ev; + + s->fifo_fd = open(s->fifo_path, O_RDONLY|O_CLOEXEC|O_NDELAY); + if (s->fifo_fd < 0) + return -errno; + + r = hashmap_put(s->manager->session_fds, INT_TO_PTR(s->fifo_fd + 1), s); + if (r < 0) + return r; + + zero(ev); + ev.events = 0; + ev.data.u32 = FD_OTHER_BASE + s->fifo_fd; + + if (epoll_ctl(s->manager->epoll_fd, EPOLL_CTL_ADD, s->fifo_fd, &ev) < 0) + return -errno; + } + + /* Open writing side */ + r = open(s->fifo_path, O_WRONLY|O_CLOEXEC|O_NDELAY); + if (r < 0) + return -errno; + + return r; +} + +void session_remove_fifo(Session *s) { + assert(s); + + if (s->fifo_fd >= 0) { + assert_se(hashmap_remove(s->manager->session_fds, INT_TO_PTR(s->fifo_fd + 1)) == s); + assert_se(epoll_ctl(s->manager->epoll_fd, EPOLL_CTL_DEL, s->fifo_fd, NULL) == 0); + close_nointr_nofail(s->fifo_fd); + s->fifo_fd = -1; + + session_save(s); + user_save(s->user); + } + + if (s->fifo_path) { + unlink(s->fifo_path); + free(s->fifo_path); + s->fifo_path = NULL; + } +} + +int session_check_gc(Session *s, bool drop_not_started) { + int r; + + assert(s); + + if (drop_not_started && !s->started) + return 0; + + if (s->fifo_fd >= 0) { + + r = pipe_eof(s->fifo_fd); + if (r < 0) + return r; + + if (r == 0) + return 1; + } + + if (s->cgroup_path) { + + r = cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, s->cgroup_path, false); + if (r < 0) + return r; + + if (r <= 0) + return 1; + } + + return 0; +} + +void session_add_to_gc_queue(Session *s) { + assert(s); + + if (s->in_gc_queue) + return; + + LIST_PREPEND(Session, gc_queue, s->manager->session_gc_queue, s); + s->in_gc_queue = true; +} + +SessionState session_get_state(Session *s) { + assert(s); + + if (s->fifo_fd < 0) + return SESSION_CLOSING; + + if (session_is_active(s)) + return SESSION_ACTIVE; + + return SESSION_ONLINE; +} + +int session_kill(Session *s, KillWho who, int signo) { + int r = 0; + Set *pid_set = NULL; + + assert(s); + + if (!s->cgroup_path) + return -ESRCH; + + if (s->leader <= 0 && who == KILL_LEADER) + return -ESRCH; + + if (s->leader > 0) + if (kill(s->leader, signo) < 0) + r = -errno; + + if (who == KILL_ALL) { + int q; + + pid_set = set_new(trivial_hash_func, trivial_compare_func); + if (!pid_set) + return -ENOMEM; + + if (s->leader > 0) { + q = set_put(pid_set, LONG_TO_PTR(s->leader)); + if (q < 0) + r = q; + } + + q = cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, s->cgroup_path, signo, false, true, false, pid_set); + if (q < 0) + if (q != -EAGAIN && q != -ESRCH && q != -ENOENT) + r = q; + } + + if (pid_set) + set_free(pid_set); + + return r; +} + +static const char* const session_state_table[_SESSION_TYPE_MAX] = { + [SESSION_ONLINE] = "online", + [SESSION_ACTIVE] = "active", + [SESSION_CLOSING] = "closing" +}; + +DEFINE_STRING_TABLE_LOOKUP(session_state, SessionState); + +static const char* const session_type_table[_SESSION_TYPE_MAX] = { + [SESSION_TTY] = "tty", + [SESSION_X11] = "x11", + [SESSION_UNSPECIFIED] = "unspecified" +}; + +DEFINE_STRING_TABLE_LOOKUP(session_type, SessionType); + +static const char* const session_class_table[_SESSION_CLASS_MAX] = { + [SESSION_USER] = "user", + [SESSION_GREETER] = "greeter", + [SESSION_LOCK_SCREEN] = "lock-screen" +}; + +DEFINE_STRING_TABLE_LOOKUP(session_class, SessionClass); + +static const char* const kill_who_table[_KILL_WHO_MAX] = { + [KILL_LEADER] = "leader", + [KILL_ALL] = "all" +}; + +DEFINE_STRING_TABLE_LOOKUP(kill_who, KillWho); diff --git a/src/login/logind-session.h b/src/login/logind-session.h new file mode 100644 index 000000000..7598afa61 --- /dev/null +++ b/src/login/logind-session.h @@ -0,0 +1,147 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +typedef struct Session Session; + +#include "list.h" +#include "util.h" +#include "logind.h" +#include "logind-seat.h" +#include "logind-user.h" + +typedef enum SessionState { + SESSION_ONLINE, /* Logged in */ + SESSION_ACTIVE, /* Logged in and in the fg */ + SESSION_CLOSING, /* Logged out, but processes still remain */ + _SESSION_STATE_MAX, + _SESSION_STATE_INVALID = -1 +} SessionState; + +typedef enum SessionType { + SESSION_UNSPECIFIED, + SESSION_TTY, + SESSION_X11, + _SESSION_TYPE_MAX, + _SESSION_TYPE_INVALID = -1 +} SessionType; + +typedef enum SessionClass { + SESSION_USER, + SESSION_GREETER, + SESSION_LOCK_SCREEN, + _SESSION_CLASS_MAX, + _SESSION_CLASS_INVALID = -1 +} SessionClass; + +typedef enum KillWho { + KILL_LEADER, + KILL_ALL, + _KILL_WHO_MAX, + _KILL_WHO_INVALID = -1 +} KillWho; + +struct Session { + Manager *manager; + + char *id; + SessionType type; + SessionClass class; + + char *state_file; + + User *user; + + dual_timestamp timestamp; + + char *tty; + char *display; + + bool remote; + char *remote_user; + char *remote_host; + + char *service; + + int vtnr; + Seat *seat; + + pid_t leader; + uint32_t audit_id; + + int fifo_fd; + char *fifo_path; + + char *cgroup_path; + char **controllers, **reset_controllers; + + bool idle_hint; + dual_timestamp idle_hint_timestamp; + + bool kill_processes; + bool in_gc_queue:1; + bool started:1; + + LIST_FIELDS(Session, sessions_by_user); + LIST_FIELDS(Session, sessions_by_seat); + + LIST_FIELDS(Session, gc_queue); +}; + +Session *session_new(Manager *m, User *u, const char *id); +void session_free(Session *s); +int session_check_gc(Session *s, bool drop_not_started); +void session_add_to_gc_queue(Session *s); +int session_activate(Session *s); +bool session_is_active(Session *s); +int session_get_idle_hint(Session *s, dual_timestamp *t); +void session_set_idle_hint(Session *s, bool b); +int session_create_fifo(Session *s); +void session_remove_fifo(Session *s); +int session_start(Session *s); +int session_stop(Session *s); +int session_save(Session *s); +int session_load(Session *s); +int session_kill(Session *s, KillWho who, int signo); + +char *session_bus_path(Session *s); + +SessionState session_get_state(Session *u); + +extern const DBusObjectPathVTable bus_session_vtable; + +int session_send_signal(Session *s, bool new_session); +int session_send_changed(Session *s, const char *properties); +int session_send_lock(Session *s, bool lock); +int session_send_lock_all(Manager *m, bool lock); + +const char* session_state_to_string(SessionState t); +SessionState session_state_from_string(const char *s); + +const char* session_type_to_string(SessionType t); +SessionType session_type_from_string(const char *s); + +const char* session_class_to_string(SessionClass t); +SessionClass session_class_from_string(const char *s); + +const char *kill_who_to_string(KillWho k); +KillWho kill_who_from_string(const char *s); diff --git a/src/login/logind-user-dbus.c b/src/login/logind-user-dbus.c new file mode 100644 index 000000000..ddf9d9d5c --- /dev/null +++ b/src/login/logind-user-dbus.c @@ -0,0 +1,437 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +#include +#include + +#include "logind.h" +#include "logind-user.h" +#include "dbus-common.h" + +#define BUS_USER_INTERFACE \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + +#define INTROSPECTION \ + DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \ + "\n" \ + BUS_USER_INTERFACE \ + BUS_PROPERTIES_INTERFACE \ + BUS_PEER_INTERFACE \ + BUS_INTROSPECTABLE_INTERFACE \ + "\n" + +#define INTERFACES_LIST \ + BUS_GENERIC_INTERFACES_LIST \ + "org.freedesktop.login1.User\0" + +static int bus_user_append_display(DBusMessageIter *i, const char *property, void *data) { + DBusMessageIter sub; + User *u = data; + const char *id, *path; + char *p = NULL; + + assert(i); + assert(property); + assert(u); + + if (!dbus_message_iter_open_container(i, DBUS_TYPE_STRUCT, NULL, &sub)) + return -ENOMEM; + + if (u->display) { + id = u->display->id; + path = p = session_bus_path(u->display); + + if (!p) + return -ENOMEM; + } else { + id = ""; + path = "/"; + } + + if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &id) || + !dbus_message_iter_append_basic(&sub, DBUS_TYPE_OBJECT_PATH, &path)) { + free(p); + return -ENOMEM; + } + + free(p); + + if (!dbus_message_iter_close_container(i, &sub)) + return -ENOMEM; + + return 0; +} + +static int bus_user_append_state(DBusMessageIter *i, const char *property, void *data) { + User *u = data; + const char *state; + + assert(i); + assert(property); + assert(u); + + state = user_state_to_string(user_get_state(u)); + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &state)) + return -ENOMEM; + + return 0; +} + +static int bus_user_append_sessions(DBusMessageIter *i, const char *property, void *data) { + DBusMessageIter sub, sub2; + User *u = data; + Session *session; + + assert(i); + assert(property); + assert(u); + + if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "(so)", &sub)) + return -ENOMEM; + + LIST_FOREACH(sessions_by_user, session, u->sessions) { + char *p; + + if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2)) + return -ENOMEM; + + p = session_bus_path(session); + if (!p) + return -ENOMEM; + + if (!dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &session->id) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_OBJECT_PATH, &p)) { + free(p); + return -ENOMEM; + } + + free(p); + + if (!dbus_message_iter_close_container(&sub, &sub2)) + return -ENOMEM; + } + + if (!dbus_message_iter_close_container(i, &sub)) + return -ENOMEM; + + return 0; +} + +static int bus_user_append_idle_hint(DBusMessageIter *i, const char *property, void *data) { + User *u = data; + dbus_bool_t b; + + assert(i); + assert(property); + assert(u); + + b = user_get_idle_hint(u, NULL) > 0; + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b)) + return -ENOMEM; + + return 0; +} + +static int bus_user_append_idle_hint_since(DBusMessageIter *i, const char *property, void *data) { + User *u = data; + dual_timestamp t; + uint64_t k; + + assert(i); + assert(property); + assert(u); + + user_get_idle_hint(u, &t); + k = streq(property, "IdleSinceHint") ? t.realtime : t.monotonic; + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_UINT64, &k)) + return -ENOMEM; + + return 0; +} + +static int bus_user_append_default_cgroup(DBusMessageIter *i, const char *property, void *data) { + User *u = data; + char *t; + int r; + bool success; + + assert(i); + assert(property); + assert(u); + + r = cg_join_spec(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, &t); + if (r < 0) + return r; + + success = dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &t); + free(t); + + return success ? 0 : -ENOMEM; +} + +static int get_user_for_path(Manager *m, const char *path, User **_u) { + User *u; + unsigned long lu; + int r; + + assert(m); + assert(path); + assert(_u); + + if (!startswith(path, "/org/freedesktop/login1/user/")) + return -EINVAL; + + r = safe_atolu(path + 29, &lu); + if (r < 0) + return r; + + u = hashmap_get(m->users, ULONG_TO_PTR(lu)); + if (!u) + return -ENOENT; + + *_u = u; + return 0; +} + +static const BusProperty bus_login_user_properties[] = { + { "UID", bus_property_append_uid, "u", offsetof(User, uid) }, + { "GID", bus_property_append_gid, "u", offsetof(User, gid) }, + { "Name", bus_property_append_string, "s", offsetof(User, name), true }, + { "Timestamp", bus_property_append_usec, "t", offsetof(User, timestamp.realtime) }, + { "TimestampMonotonic", bus_property_append_usec, "t", offsetof(User, timestamp.monotonic) }, + { "RuntimePath", bus_property_append_string, "s", offsetof(User, runtime_path), true }, + { "DefaultControlGroup", bus_user_append_default_cgroup, "s", 0 }, + { "Service", bus_property_append_string, "s", offsetof(User, service), true }, + { "Display", bus_user_append_display, "(so)", 0 }, + { "State", bus_user_append_state, "s", 0 }, + { "Sessions", bus_user_append_sessions, "a(so)", 0 }, + { "IdleHint", bus_user_append_idle_hint, "b", 0 }, + { "IdleSinceHint", bus_user_append_idle_hint_since, "t", 0 }, + { "IdleSinceHintMonotonic", bus_user_append_idle_hint_since, "t", 0 }, + { NULL, } +}; + +static DBusHandlerResult user_message_dispatch( + User *u, + DBusConnection *connection, + DBusMessage *message) { + + DBusError error; + DBusMessage *reply = NULL; + int r; + + assert(u); + assert(connection); + assert(message); + + if (dbus_message_is_method_call(message, "org.freedesktop.login1.User", "Terminate")) { + + r = user_stop(u); + if (r < 0) + return bus_send_error_reply(connection, message, NULL, r); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.User", "Kill")) { + int32_t signo; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_INT32, &signo, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + if (signo <= 0 || signo >= _NSIG) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + r = user_kill(u, signo); + if (r < 0) + return bus_send_error_reply(connection, message, NULL, r); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + } else { + const BusBoundProperties bps[] = { + { "org.freedesktop.login1.User", bus_login_user_properties, u }, + { NULL, } + }; + + return bus_default_message_handler(connection, message, INTROSPECTION, INTERFACES_LIST, bps); + } + + if (reply) { + if (!dbus_connection_send(connection, reply, NULL)) + goto oom; + + dbus_message_unref(reply); + } + + return DBUS_HANDLER_RESULT_HANDLED; + +oom: + if (reply) + dbus_message_unref(reply); + + dbus_error_free(&error); + + return DBUS_HANDLER_RESULT_NEED_MEMORY; +} + +static DBusHandlerResult user_message_handler( + DBusConnection *connection, + DBusMessage *message, + void *userdata) { + + Manager *m = userdata; + User *u; + int r; + + r = get_user_for_path(m, dbus_message_get_path(message), &u); + if (r < 0) { + + if (r == -ENOMEM) + return DBUS_HANDLER_RESULT_NEED_MEMORY; + + if (r == -ENOENT) { + DBusError e; + + dbus_error_init(&e); + dbus_set_error_const(&e, DBUS_ERROR_UNKNOWN_OBJECT, "Unknown user"); + return bus_send_error_reply(connection, message, &e, r); + } + + return bus_send_error_reply(connection, message, NULL, r); + } + + return user_message_dispatch(u, connection, message); +} + +const DBusObjectPathVTable bus_user_vtable = { + .message_function = user_message_handler +}; + +char *user_bus_path(User *u) { + char *s; + + assert(u); + + if (asprintf(&s, "/org/freedesktop/login1/user/%llu", (unsigned long long) u->uid) < 0) + return NULL; + + return s; +} + +int user_send_signal(User *u, bool new_user) { + DBusMessage *m; + int r = -ENOMEM; + char *p = NULL; + uint32_t uid; + + assert(u); + + m = dbus_message_new_signal("/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + new_user ? "UserNew" : "UserRemoved"); + + if (!m) + return -ENOMEM; + + p = user_bus_path(u); + if (!p) + goto finish; + + uid = u->uid; + + if (!dbus_message_append_args( + m, + DBUS_TYPE_UINT32, &uid, + DBUS_TYPE_OBJECT_PATH, &p, + DBUS_TYPE_INVALID)) + goto finish; + + if (!dbus_connection_send(u->manager->bus, m, NULL)) + goto finish; + + r = 0; + +finish: + dbus_message_unref(m); + free(p); + + return r; +} + +int user_send_changed(User *u, const char *properties) { + DBusMessage *m; + int r = -ENOMEM; + char *p = NULL; + + assert(u); + + if (!u->started) + return 0; + + p = user_bus_path(u); + if (!p) + return -ENOMEM; + + m = bus_properties_changed_new(p, "org.freedesktop.login1.User", properties); + if (!m) + goto finish; + + if (!dbus_connection_send(u->manager->bus, m, NULL)) + goto finish; + + r = 0; + +finish: + if (m) + dbus_message_unref(m); + free(p); + + return r; +} diff --git a/src/login/logind-user.c b/src/login/logind-user.c new file mode 100644 index 000000000..b692b533e --- /dev/null +++ b/src/login/logind-user.c @@ -0,0 +1,656 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +#include +#include +#include + +#include "logind-user.h" +#include "util.h" +#include "mkdir.h" +#include "cgroup-util.h" +#include "hashmap.h" +#include "strv.h" + +User* user_new(Manager *m, uid_t uid, gid_t gid, const char *name) { + User *u; + + assert(m); + assert(name); + + u = new0(User, 1); + if (!u) + return NULL; + + u->name = strdup(name); + if (!u->name) { + free(u); + return NULL; + } + + if (asprintf(&u->state_file, "/run/systemd/users/%lu", (unsigned long) uid) < 0) { + free(u->name); + free(u); + return NULL; + } + + if (hashmap_put(m->users, ULONG_TO_PTR((unsigned long) uid), u) < 0) { + free(u->state_file); + free(u->name); + free(u); + return NULL; + } + + u->manager = m; + u->uid = uid; + u->gid = gid; + + return u; +} + +void user_free(User *u) { + assert(u); + + if (u->in_gc_queue) + LIST_REMOVE(User, gc_queue, u->manager->user_gc_queue, u); + + while (u->sessions) + session_free(u->sessions); + + if (u->cgroup_path) + hashmap_remove(u->manager->user_cgroups, u->cgroup_path); + free(u->cgroup_path); + + free(u->service); + free(u->runtime_path); + + hashmap_remove(u->manager->users, ULONG_TO_PTR((unsigned long) u->uid)); + + free(u->name); + free(u->state_file); + free(u); +} + +int user_save(User *u) { + FILE *f; + int r; + char *temp_path; + + assert(u); + assert(u->state_file); + + if (!u->started) + return 0; + + r = mkdir_safe_label("/run/systemd/users", 0755, 0, 0); + if (r < 0) + goto finish; + + r = fopen_temporary(u->state_file, &f, &temp_path); + if (r < 0) + goto finish; + + fchmod(fileno(f), 0644); + + fprintf(f, + "# This is private data. Do not parse.\n" + "NAME=%s\n" + "STATE=%s\n", + u->name, + user_state_to_string(user_get_state(u))); + + if (u->cgroup_path) + fprintf(f, + "CGROUP=%s\n", + u->cgroup_path); + + if (u->runtime_path) + fprintf(f, + "RUNTIME=%s\n", + u->runtime_path); + + if (u->service) + fprintf(f, + "SERVICE=%s\n", + u->service); + + if (u->display) + fprintf(f, + "DISPLAY=%s\n", + u->display->id); + + if (u->sessions) { + Session *i; + bool first; + + fputs("SESSIONS=", f); + first = true; + LIST_FOREACH(sessions_by_user, i, u->sessions) { + if (first) + first = false; + else + fputc(' ', f); + + fputs(i->id, f); + } + + fputs("\nSEATS=", f); + first = true; + LIST_FOREACH(sessions_by_user, i, u->sessions) { + if (!i->seat) + continue; + + if (first) + first = false; + else + fputc(' ', f); + + fputs(i->seat->id, f); + } + + fputs("\nACTIVE_SESSIONS=", f); + first = true; + LIST_FOREACH(sessions_by_user, i, u->sessions) { + if (!session_is_active(i)) + continue; + + if (first) + first = false; + else + fputc(' ', f); + + fputs(i->id, f); + } + + fputs("\nONLINE_SESSIONS=", f); + first = true; + LIST_FOREACH(sessions_by_user, i, u->sessions) { + if (session_get_state(i) == SESSION_CLOSING) + continue; + + if (first) + first = false; + else + fputc(' ', f); + + fputs(i->id, f); + } + + fputs("\nACTIVE_SEATS=", f); + first = true; + LIST_FOREACH(sessions_by_user, i, u->sessions) { + if (!session_is_active(i) || !i->seat) + continue; + + if (first) + first = false; + else + fputc(' ', f); + + fputs(i->seat->id, f); + } + + fputs("\nONLINE_SEATS=", f); + first = true; + LIST_FOREACH(sessions_by_user, i, u->sessions) { + if (session_get_state(i) == SESSION_CLOSING || !i->seat) + continue; + + if (first) + first = false; + else + fputc(' ', f); + + fputs(i->seat->id, f); + } + fputc('\n', f); + } + + fflush(f); + + if (ferror(f) || rename(temp_path, u->state_file) < 0) { + r = -errno; + unlink(u->state_file); + unlink(temp_path); + } + + fclose(f); + free(temp_path); + +finish: + if (r < 0) + log_error("Failed to save user data for %s: %s", u->name, strerror(-r)); + + return r; +} + +int user_load(User *u) { + int r; + char *display = NULL; + Session *s = NULL; + + assert(u); + + r = parse_env_file(u->state_file, NEWLINE, + "CGROUP", &u->cgroup_path, + "RUNTIME", &u->runtime_path, + "SERVICE", &u->service, + "DISPLAY", &display, + NULL); + if (r < 0) { + free(display); + + if (r == -ENOENT) + return 0; + + log_error("Failed to read %s: %s", u->state_file, strerror(-r)); + return r; + } + + if (display) { + s = hashmap_get(u->manager->sessions, display); + free(display); + } + + if (s && s->display && display_is_local(s->display)) + u->display = s; + + return r; +} + +static int user_mkdir_runtime_path(User *u) { + char *p; + int r; + + assert(u); + + r = mkdir_safe_label("/run/user", 0755, 0, 0); + if (r < 0) { + log_error("Failed to create /run/user: %s", strerror(-r)); + return r; + } + + if (!u->runtime_path) { + if (asprintf(&p, "/run/user/%lu", (unsigned long) u->uid) < 0) + return log_oom(); + } else + p = u->runtime_path; + + r = mkdir_safe_label(p, 0700, u->uid, u->gid); + if (r < 0) { + log_error("Failed to create runtime directory %s: %s", p, strerror(-r)); + free(p); + u->runtime_path = NULL; + return r; + } + + u->runtime_path = p; + return 0; +} + +static int user_create_cgroup(User *u) { + char **k; + char *p; + int r; + + assert(u); + + if (!u->cgroup_path) { + if (asprintf(&p, "%s/%s", u->manager->cgroup_path, u->name) < 0) + return log_oom(); + } else + p = u->cgroup_path; + + r = cg_create(SYSTEMD_CGROUP_CONTROLLER, p); + if (r < 0) { + log_error("Failed to create cgroup "SYSTEMD_CGROUP_CONTROLLER":%s: %s", p, strerror(-r)); + free(p); + u->cgroup_path = NULL; + return r; + } + + u->cgroup_path = p; + + STRV_FOREACH(k, u->manager->controllers) { + + if (strv_contains(u->manager->reset_controllers, *k)) + continue; + + r = cg_create(*k, p); + if (r < 0) + log_warning("Failed to create cgroup %s:%s: %s", *k, p, strerror(-r)); + } + + r = hashmap_put(u->manager->user_cgroups, u->cgroup_path, u); + if (r < 0) + log_warning("Failed to create mapping between cgroup and user"); + + return 0; +} + +static int user_start_service(User *u) { + assert(u); + + /* FIXME: Fill me in later ... */ + + return 0; +} + +int user_start(User *u) { + int r; + + assert(u); + + if (u->started) + return 0; + + log_debug("New user %s logged in.", u->name); + + /* Make XDG_RUNTIME_DIR */ + r = user_mkdir_runtime_path(u); + if (r < 0) + return r; + + /* Create cgroup */ + r = user_create_cgroup(u); + if (r < 0) + return r; + + /* Spawn user systemd */ + r = user_start_service(u); + if (r < 0) + return r; + + dual_timestamp_get(&u->timestamp); + + u->started = true; + + /* Save new user data */ + user_save(u); + + user_send_signal(u, true); + + return 0; +} + +static int user_stop_service(User *u) { + assert(u); + + if (!u->service) + return 0; + + return 0; +} + +static int user_shall_kill(User *u) { + assert(u); + + if (!u->manager->kill_user_processes) + return false; + + if (strv_contains(u->manager->kill_exclude_users, u->name)) + return false; + + if (strv_isempty(u->manager->kill_only_users)) + return true; + + return strv_contains(u->manager->kill_only_users, u->name); +} + +static int user_terminate_cgroup(User *u) { + int r; + char **k; + + assert(u); + + if (!u->cgroup_path) + return 0; + + cg_trim(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, false); + + if (user_shall_kill(u)) { + + r = cg_kill_recursive_and_wait(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, true); + if (r < 0) + log_error("Failed to kill user cgroup: %s", strerror(-r)); + } else { + + r = cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, true); + if (r < 0) + log_error("Failed to check user cgroup: %s", strerror(-r)); + else if (r > 0) { + r = cg_delete(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path); + if (r < 0) + log_error("Failed to delete user cgroup: %s", strerror(-r)); + } else + r = -EBUSY; + } + + STRV_FOREACH(k, u->manager->controllers) + cg_trim(*k, u->cgroup_path, true); + + hashmap_remove(u->manager->user_cgroups, u->cgroup_path); + + free(u->cgroup_path); + u->cgroup_path = NULL; + + return r; +} + +static int user_remove_runtime_path(User *u) { + int r; + + assert(u); + + if (!u->runtime_path) + return 0; + + r = rm_rf(u->runtime_path, false, true, false); + if (r < 0) + log_error("Failed to remove runtime directory %s: %s", u->runtime_path, strerror(-r)); + + free(u->runtime_path); + u->runtime_path = NULL; + + return r; +} + +int user_stop(User *u) { + Session *s; + int r = 0, k; + assert(u); + + if (u->started) + log_debug("User %s logged out.", u->name); + + LIST_FOREACH(sessions_by_user, s, u->sessions) { + k = session_stop(s); + if (k < 0) + r = k; + } + + /* Kill systemd */ + k = user_stop_service(u); + if (k < 0) + r = k; + + /* Kill cgroup */ + k = user_terminate_cgroup(u); + if (k < 0) + r = k; + + /* Kill XDG_RUNTIME_DIR */ + k = user_remove_runtime_path(u); + if (k < 0) + r = k; + + unlink(u->state_file); + user_add_to_gc_queue(u); + + if (u->started) + user_send_signal(u, false); + + u->started = false; + + return r; +} + +int user_get_idle_hint(User *u, dual_timestamp *t) { + Session *s; + bool idle_hint = true; + dual_timestamp ts = { 0, 0 }; + + assert(u); + + LIST_FOREACH(sessions_by_user, s, u->sessions) { + dual_timestamp k; + int ih; + + ih = session_get_idle_hint(s, &k); + if (ih < 0) + return ih; + + if (!ih) { + if (!idle_hint) { + if (k.monotonic < ts.monotonic) + ts = k; + } else { + idle_hint = false; + ts = k; + } + } else if (idle_hint) { + + if (k.monotonic > ts.monotonic) + ts = k; + } + } + + if (t) + *t = ts; + + return idle_hint; +} + +static int user_check_linger_file(User *u) { + char *p; + int r; + + if (asprintf(&p, "/var/lib/systemd/linger/%s", u->name) < 0) + return -ENOMEM; + + r = access(p, F_OK) >= 0; + free(p); + + return r; +} + +int user_check_gc(User *u, bool drop_not_started) { + int r; + + assert(u); + + if (drop_not_started && !u->started) + return 0; + + if (u->sessions) + return 1; + + if (user_check_linger_file(u) > 0) + return 1; + + if (u->cgroup_path) { + r = cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, false); + if (r < 0) + return r; + + if (r <= 0) + return 1; + } + + return 0; +} + +void user_add_to_gc_queue(User *u) { + assert(u); + + if (u->in_gc_queue) + return; + + LIST_PREPEND(User, gc_queue, u->manager->user_gc_queue, u); + u->in_gc_queue = true; +} + +UserState user_get_state(User *u) { + Session *i; + bool all_closing = true; + + assert(u); + + + LIST_FOREACH(sessions_by_user, i, u->sessions) { + if (session_is_active(i)) + return USER_ACTIVE; + if (session_get_state(i) != SESSION_CLOSING) + all_closing = false; + } + + if (u->sessions) + return all_closing ? USER_CLOSING : USER_ONLINE; + + if (user_check_linger_file(u) > 0) + return USER_LINGERING; + + return USER_CLOSING; +} + +int user_kill(User *u, int signo) { + int r = 0, q; + Set *pid_set = NULL; + + assert(u); + + if (!u->cgroup_path) + return -ESRCH; + + pid_set = set_new(trivial_hash_func, trivial_compare_func); + if (!pid_set) + return -ENOMEM; + + q = cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, signo, false, true, false, pid_set); + if (q < 0) + if (q != -EAGAIN && q != -ESRCH && q != -ENOENT) + r = q; + + if (pid_set) + set_free(pid_set); + + return r; +} + +static const char* const user_state_table[_USER_STATE_MAX] = { + [USER_OFFLINE] = "offline", + [USER_LINGERING] = "lingering", + [USER_ONLINE] = "online", + [USER_ACTIVE] = "active", + [USER_CLOSING] = "closing" +}; + +DEFINE_STRING_TABLE_LOOKUP(user_state, UserState); diff --git a/src/login/logind-user.h b/src/login/logind-user.h new file mode 100644 index 000000000..a679d43a3 --- /dev/null +++ b/src/login/logind-user.h @@ -0,0 +1,84 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +typedef struct User User; + +#include "list.h" +#include "util.h" +#include "logind.h" +#include "logind-session.h" + +typedef enum UserState { + USER_OFFLINE, /* Not logged in at all */ + USER_LINGERING, /* Lingering has been enabled by the admin for this user */ + USER_ONLINE, /* User logged in */ + USER_ACTIVE, /* User logged in and has a session in the fg */ + USER_CLOSING, /* User logged out, but processes still remain and lingering is not enabled */ + _USER_STATE_MAX, + _USER_STATE_INVALID = -1 +} UserState; + +struct User { + Manager *manager; + + uid_t uid; + gid_t gid; + char *name; + + char *state_file; + char *runtime_path; + char *service; + char *cgroup_path; + + Session *display; + + dual_timestamp timestamp; + + bool in_gc_queue:1; + bool started:1; + + LIST_HEAD(Session, sessions); + LIST_FIELDS(User, gc_queue); +}; + +User* user_new(Manager *m, uid_t uid, gid_t gid, const char *name); +void user_free(User *u); +int user_check_gc(User *u, bool drop_not_started); +void user_add_to_gc_queue(User *u); +int user_start(User *u); +int user_stop(User *u); +UserState user_get_state(User *u); +int user_get_idle_hint(User *u, dual_timestamp *t); +int user_save(User *u); +int user_load(User *u); +int user_kill(User *u, int signo); + +char *user_bus_path(User *s); + +extern const DBusObjectPathVTable bus_user_vtable; + +int user_send_signal(User *u, bool new_user); +int user_send_changed(User *u, const char *properties); + +const char* user_state_to_string(UserState s); +UserState user_state_from_string(const char *s); diff --git a/src/login/logind.c b/src/login/logind.c new file mode 100644 index 000000000..6438631b5 --- /dev/null +++ b/src/login/logind.c @@ -0,0 +1,1768 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "logind.h" +#include "dbus-common.h" +#include "dbus-loop.h" +#include "strv.h" +#include "conf-parser.h" + +Manager *manager_new(void) { + Manager *m; + + m = new0(Manager, 1); + if (!m) + return NULL; + + m->console_active_fd = -1; + m->bus_fd = -1; + m->udev_seat_fd = -1; + m->udev_vcsa_fd = -1; + m->udev_button_fd = -1; + m->epoll_fd = -1; + m->reserve_vt_fd = -1; + + m->n_autovts = 6; + m->reserve_vt = 6; + m->inhibit_delay_max = 5 * USEC_PER_SEC; + m->handle_power_key = HANDLE_POWEROFF; + m->handle_suspend_key = HANDLE_SUSPEND; + m->handle_hibernate_key = HANDLE_HIBERNATE; + m->handle_lid_switch = HANDLE_SUSPEND; + m->lid_switch_ignore_inhibited = true; + + m->idle_action_fd = -1; + m->idle_action_usec = 30 * USEC_PER_MINUTE; + m->idle_action = HANDLE_IGNORE; + m->idle_action_not_before_usec = now(CLOCK_MONOTONIC); + + m->devices = hashmap_new(string_hash_func, string_compare_func); + m->seats = hashmap_new(string_hash_func, string_compare_func); + m->sessions = hashmap_new(string_hash_func, string_compare_func); + m->users = hashmap_new(trivial_hash_func, trivial_compare_func); + m->inhibitors = hashmap_new(string_hash_func, string_compare_func); + m->buttons = hashmap_new(string_hash_func, string_compare_func); + + m->user_cgroups = hashmap_new(string_hash_func, string_compare_func); + m->session_cgroups = hashmap_new(string_hash_func, string_compare_func); + + m->session_fds = hashmap_new(trivial_hash_func, trivial_compare_func); + m->inhibitor_fds = hashmap_new(trivial_hash_func, trivial_compare_func); + m->button_fds = hashmap_new(trivial_hash_func, trivial_compare_func); + + if (!m->devices || !m->seats || !m->sessions || !m->users || !m->inhibitors || !m->buttons || + !m->user_cgroups || !m->session_cgroups || + !m->session_fds || !m->inhibitor_fds || !m->button_fds) { + manager_free(m); + return NULL; + } + + m->reset_controllers = strv_new("cpu", NULL); + m->kill_exclude_users = strv_new("root", NULL); + if (!m->reset_controllers || !m->kill_exclude_users) { + manager_free(m); + return NULL; + } + + m->udev = udev_new(); + if (!m->udev) { + manager_free(m); + return NULL; + } + + if (cg_get_user_path(&m->cgroup_path) < 0) { + manager_free(m); + return NULL; + } + + return m; +} + +void manager_free(Manager *m) { + Session *session; + User *u; + Device *d; + Seat *s; + Inhibitor *i; + Button *b; + + assert(m); + + while ((session = hashmap_first(m->sessions))) + session_free(session); + + while ((u = hashmap_first(m->users))) + user_free(u); + + while ((d = hashmap_first(m->devices))) + device_free(d); + + while ((s = hashmap_first(m->seats))) + seat_free(s); + + while ((i = hashmap_first(m->inhibitors))) + inhibitor_free(i); + + while ((b = hashmap_first(m->buttons))) + button_free(b); + + hashmap_free(m->devices); + hashmap_free(m->seats); + hashmap_free(m->sessions); + hashmap_free(m->users); + hashmap_free(m->inhibitors); + hashmap_free(m->buttons); + + hashmap_free(m->user_cgroups); + hashmap_free(m->session_cgroups); + + hashmap_free(m->session_fds); + hashmap_free(m->inhibitor_fds); + hashmap_free(m->button_fds); + + if (m->console_active_fd >= 0) + close_nointr_nofail(m->console_active_fd); + + if (m->udev_seat_monitor) + udev_monitor_unref(m->udev_seat_monitor); + if (m->udev_vcsa_monitor) + udev_monitor_unref(m->udev_vcsa_monitor); + if (m->udev_button_monitor) + udev_monitor_unref(m->udev_button_monitor); + + if (m->udev) + udev_unref(m->udev); + + if (m->bus) { + dbus_connection_flush(m->bus); + dbus_connection_close(m->bus); + dbus_connection_unref(m->bus); + } + + if (m->bus_fd >= 0) + close_nointr_nofail(m->bus_fd); + + if (m->epoll_fd >= 0) + close_nointr_nofail(m->epoll_fd); + + if (m->reserve_vt_fd >= 0) + close_nointr_nofail(m->reserve_vt_fd); + + if (m->idle_action_fd >= 0) + close_nointr_nofail(m->idle_action_fd); + + strv_free(m->controllers); + strv_free(m->reset_controllers); + strv_free(m->kill_only_users); + strv_free(m->kill_exclude_users); + + free(m->cgroup_path); + free(m); +} + +int manager_add_device(Manager *m, const char *sysfs, Device **_device) { + Device *d; + + assert(m); + assert(sysfs); + + d = hashmap_get(m->devices, sysfs); + if (d) { + if (_device) + *_device = d; + + return 0; + } + + d = device_new(m, sysfs); + if (!d) + return -ENOMEM; + + if (_device) + *_device = d; + + return 0; +} + +int manager_add_seat(Manager *m, const char *id, Seat **_seat) { + Seat *s; + + assert(m); + assert(id); + + s = hashmap_get(m->seats, id); + if (s) { + if (_seat) + *_seat = s; + + return 0; + } + + s = seat_new(m, id); + if (!s) + return -ENOMEM; + + if (_seat) + *_seat = s; + + return 0; +} + +int manager_add_session(Manager *m, User *u, const char *id, Session **_session) { + Session *s; + + assert(m); + assert(id); + + s = hashmap_get(m->sessions, id); + if (s) { + if (_session) + *_session = s; + + return 0; + } + + s = session_new(m, u, id); + if (!s) + return -ENOMEM; + + if (_session) + *_session = s; + + return 0; +} + +int manager_add_user(Manager *m, uid_t uid, gid_t gid, const char *name, User **_user) { + User *u; + + assert(m); + assert(name); + + u = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid)); + if (u) { + if (_user) + *_user = u; + + return 0; + } + + u = user_new(m, uid, gid, name); + if (!u) + return -ENOMEM; + + if (_user) + *_user = u; + + return 0; +} + +int manager_add_user_by_name(Manager *m, const char *name, User **_user) { + uid_t uid; + gid_t gid; + int r; + + assert(m); + assert(name); + + r = get_user_creds(&name, &uid, &gid, NULL, NULL); + if (r < 0) + return r; + + return manager_add_user(m, uid, gid, name, _user); +} + +int manager_add_user_by_uid(Manager *m, uid_t uid, User **_user) { + struct passwd *p; + + assert(m); + + errno = 0; + p = getpwuid(uid); + if (!p) + return errno ? -errno : -ENOENT; + + return manager_add_user(m, uid, p->pw_gid, p->pw_name, _user); +} + +int manager_add_inhibitor(Manager *m, const char* id, Inhibitor **_inhibitor) { + Inhibitor *i; + + assert(m); + assert(id); + + i = hashmap_get(m->inhibitors, id); + if (i) { + if (_inhibitor) + *_inhibitor = i; + + return 0; + } + + i = inhibitor_new(m, id); + if (!i) + return -ENOMEM; + + if (_inhibitor) + *_inhibitor = i; + + return 0; +} + +int manager_add_button(Manager *m, const char *name, Button **_button) { + Button *b; + + assert(m); + assert(name); + + b = hashmap_get(m->buttons, name); + if (b) { + if (_button) + *_button = b; + + return 0; + } + + b = button_new(m, name); + if (!b) + return -ENOMEM; + + if (_button) + *_button = b; + + return 0; +} + +int manager_process_seat_device(Manager *m, struct udev_device *d) { + Device *device; + int r; + + assert(m); + + if (streq_ptr(udev_device_get_action(d), "remove")) { + + device = hashmap_get(m->devices, udev_device_get_syspath(d)); + if (!device) + return 0; + + seat_add_to_gc_queue(device->seat); + device_free(device); + + } else { + const char *sn; + Seat *seat; + + sn = udev_device_get_property_value(d, "ID_SEAT"); + if (isempty(sn)) + sn = "seat0"; + + if (!seat_name_is_valid(sn)) { + log_warning("Device with invalid seat name %s found, ignoring.", sn); + return 0; + } + + r = manager_add_device(m, udev_device_get_syspath(d), &device); + if (r < 0) + return r; + + r = manager_add_seat(m, sn, &seat); + if (r < 0) { + if (!device->seat) + device_free(device); + + return r; + } + + device_attach(device, seat); + seat_start(seat); + } + + return 0; +} + +int manager_process_button_device(Manager *m, struct udev_device *d) { + Button *b; + + int r; + + assert(m); + + if (streq_ptr(udev_device_get_action(d), "remove")) { + + b = hashmap_get(m->buttons, udev_device_get_sysname(d)); + if (!b) + return 0; + + button_free(b); + + } else { + const char *sn; + + r = manager_add_button(m, udev_device_get_sysname(d), &b); + if (r < 0) + return r; + + sn = udev_device_get_property_value(d, "ID_SEAT"); + if (isempty(sn)) + sn = "seat0"; + + button_set_seat(b, sn); + button_open(b); + } + + return 0; +} + +int manager_enumerate_devices(Manager *m) { + struct udev_list_entry *item = NULL, *first = NULL; + struct udev_enumerate *e; + int r; + + assert(m); + + /* Loads devices from udev and creates seats for them as + * necessary */ + + e = udev_enumerate_new(m->udev); + if (!e) { + r = -ENOMEM; + goto finish; + } + + r = udev_enumerate_add_match_subsystem(e, "graphics"); + if (r < 0) + goto finish; + + r = udev_enumerate_add_match_tag(e, "seat"); + if (r < 0) + goto finish; + + r = udev_enumerate_scan_devices(e); + if (r < 0) + goto finish; + + first = udev_enumerate_get_list_entry(e); + udev_list_entry_foreach(item, first) { + struct udev_device *d; + int k; + + d = udev_device_new_from_syspath(m->udev, udev_list_entry_get_name(item)); + if (!d) { + r = -ENOMEM; + goto finish; + } + + k = manager_process_seat_device(m, d); + udev_device_unref(d); + + if (k < 0) + r = k; + } + +finish: + if (e) + udev_enumerate_unref(e); + + return r; +} + +int manager_enumerate_buttons(Manager *m) { + struct udev_list_entry *item = NULL, *first = NULL; + struct udev_enumerate *e; + int r; + + assert(m); + + /* Loads buttons from udev */ + + if (m->handle_power_key == HANDLE_IGNORE && + m->handle_suspend_key == HANDLE_IGNORE && + m->handle_hibernate_key == HANDLE_IGNORE && + m->handle_lid_switch == HANDLE_IGNORE) + return 0; + + e = udev_enumerate_new(m->udev); + if (!e) { + r = -ENOMEM; + goto finish; + } + + r = udev_enumerate_add_match_subsystem(e, "input"); + if (r < 0) + goto finish; + + r = udev_enumerate_add_match_tag(e, "power-switch"); + if (r < 0) + goto finish; + + r = udev_enumerate_scan_devices(e); + if (r < 0) + goto finish; + + first = udev_enumerate_get_list_entry(e); + udev_list_entry_foreach(item, first) { + struct udev_device *d; + int k; + + d = udev_device_new_from_syspath(m->udev, udev_list_entry_get_name(item)); + if (!d) { + r = -ENOMEM; + goto finish; + } + + k = manager_process_button_device(m, d); + udev_device_unref(d); + + if (k < 0) + r = k; + } + +finish: + if (e) + udev_enumerate_unref(e); + + return r; +} + +int manager_enumerate_seats(Manager *m) { + DIR *d; + struct dirent *de; + int r = 0; + + assert(m); + + /* This loads data about seats stored on disk, but does not + * actually create any seats. Removes data of seats that no + * longer exist. */ + + d = opendir("/run/systemd/seats"); + if (!d) { + if (errno == ENOENT) + return 0; + + log_error("Failed to open /run/systemd/seats: %m"); + return -errno; + } + + while ((de = readdir(d))) { + Seat *s; + int k; + + if (!dirent_is_file(de)) + continue; + + s = hashmap_get(m->seats, de->d_name); + if (!s) { + unlinkat(dirfd(d), de->d_name, 0); + continue; + } + + k = seat_load(s); + if (k < 0) + r = k; + } + + closedir(d); + + return r; +} + +static int manager_enumerate_users_from_cgroup(Manager *m) { + int r = 0, k; + char *name; + DIR *d; + + r = cg_enumerate_subgroups(SYSTEMD_CGROUP_CONTROLLER, m->cgroup_path, &d); + if (r < 0) { + if (r == -ENOENT) + return 0; + + log_error("Failed to open %s: %s", m->cgroup_path, strerror(-r)); + return r; + } + + while ((k = cg_read_subgroup(d, &name)) > 0) { + User *user; + + k = manager_add_user_by_name(m, name, &user); + if (k < 0) { + free(name); + r = k; + continue; + } + + user_add_to_gc_queue(user); + + if (!user->cgroup_path) + if (asprintf(&user->cgroup_path, "%s/%s", m->cgroup_path, name) < 0) { + r = -ENOMEM; + free(name); + break; + } + + free(name); + } + + if (r >= 0 && k < 0) + r = k; + + closedir(d); + + return r; +} + +static int manager_enumerate_linger_users(Manager *m) { + DIR *d; + struct dirent *de; + int r = 0; + + d = opendir("/var/lib/systemd/linger"); + if (!d) { + if (errno == ENOENT) + return 0; + + log_error("Failed to open /var/lib/systemd/linger/: %m"); + return -errno; + } + + while ((de = readdir(d))) { + int k; + + if (!dirent_is_file(de)) + continue; + + k = manager_add_user_by_name(m, de->d_name, NULL); + if (k < 0) { + log_notice("Couldn't add lingering user %s: %s", de->d_name, strerror(-k)); + r = k; + } + } + + closedir(d); + + return r; +} + +int manager_enumerate_users(Manager *m) { + DIR *d; + struct dirent *de; + int r, k; + + assert(m); + + /* First, enumerate user cgroups */ + r = manager_enumerate_users_from_cgroup(m); + + /* Second, add lingering users on top */ + k = manager_enumerate_linger_users(m); + if (k < 0) + r = k; + + /* Third, read in user data stored on disk */ + d = opendir("/run/systemd/users"); + if (!d) { + if (errno == ENOENT) + return 0; + + log_error("Failed to open /run/systemd/users: %m"); + return -errno; + } + + while ((de = readdir(d))) { + uid_t uid; + User *u; + + if (!dirent_is_file(de)) + continue; + + k = parse_uid(de->d_name, &uid); + if (k < 0) { + log_error("Failed to parse file name %s: %s", de->d_name, strerror(-k)); + continue; + } + + u = hashmap_get(m->users, ULONG_TO_PTR(uid)); + if (!u) { + unlinkat(dirfd(d), de->d_name, 0); + continue; + } + + k = user_load(u); + if (k < 0) + r = k; + } + + closedir(d); + + return r; +} + +static int manager_enumerate_sessions_from_cgroup(Manager *m) { + User *u; + Iterator i; + int r = 0; + + HASHMAP_FOREACH(u, m->users, i) { + DIR *d; + char *name; + int k; + + if (!u->cgroup_path) + continue; + + k = cg_enumerate_subgroups(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, &d); + if (k < 0) { + if (k == -ENOENT) + continue; + + log_error("Failed to open %s: %s", u->cgroup_path, strerror(-k)); + r = k; + continue; + } + + while ((k = cg_read_subgroup(d, &name)) > 0) { + Session *session; + + if (streq(name, "shared")) + continue; + + k = manager_add_session(m, u, name, &session); + if (k < 0) { + free(name); + break; + } + + session_add_to_gc_queue(session); + + if (!session->cgroup_path) + if (asprintf(&session->cgroup_path, "%s/%s", u->cgroup_path, name) < 0) { + k = -ENOMEM; + free(name); + break; + } + + free(name); + } + + closedir(d); + + if (k < 0) + r = k; + } + + return r; +} + +int manager_enumerate_sessions(Manager *m) { + DIR *d; + struct dirent *de; + int r = 0; + + assert(m); + + /* First enumerate session cgroups */ + r = manager_enumerate_sessions_from_cgroup(m); + + /* Second, read in session data stored on disk */ + d = opendir("/run/systemd/sessions"); + if (!d) { + if (errno == ENOENT) + return 0; + + log_error("Failed to open /run/systemd/sessions: %m"); + return -errno; + } + + while ((de = readdir(d))) { + struct Session *s; + int k; + + if (!dirent_is_file(de)) + continue; + + s = hashmap_get(m->sessions, de->d_name); + if (!s) { + unlinkat(dirfd(d), de->d_name, 0); + continue; + } + + k = session_load(s); + if (k < 0) + r = k; + } + + closedir(d); + + return r; +} + +int manager_enumerate_inhibitors(Manager *m) { + DIR *d; + struct dirent *de; + int r = 0; + + assert(m); + + d = opendir("/run/systemd/inhibit"); + if (!d) { + if (errno == ENOENT) + return 0; + + log_error("Failed to open /run/systemd/inhibit: %m"); + return -errno; + } + + while ((de = readdir(d))) { + int k; + Inhibitor *i; + + if (!dirent_is_file(de)) + continue; + + k = manager_add_inhibitor(m, de->d_name, &i); + if (k < 0) { + log_notice("Couldn't add inhibitor %s: %s", de->d_name, strerror(-k)); + r = k; + continue; + } + + k = inhibitor_load(i); + if (k < 0) + r = k; + } + + closedir(d); + + return r; +} + +int manager_dispatch_seat_udev(Manager *m) { + struct udev_device *d; + int r; + + assert(m); + + d = udev_monitor_receive_device(m->udev_seat_monitor); + if (!d) + return -ENOMEM; + + r = manager_process_seat_device(m, d); + udev_device_unref(d); + + return r; +} + +int manager_dispatch_vcsa_udev(Manager *m) { + struct udev_device *d; + int r = 0; + const char *name; + + assert(m); + + d = udev_monitor_receive_device(m->udev_vcsa_monitor); + if (!d) + return -ENOMEM; + + name = udev_device_get_sysname(d); + + /* Whenever a VCSA device is removed try to reallocate our + * VTs, to make sure our auto VTs never go away. */ + + if (name && startswith(name, "vcsa") && streq_ptr(udev_device_get_action(d), "remove")) + r = seat_preallocate_vts(m->vtconsole); + + udev_device_unref(d); + + return r; +} + +int manager_dispatch_button_udev(Manager *m) { + struct udev_device *d; + int r; + + assert(m); + + d = udev_monitor_receive_device(m->udev_button_monitor); + if (!d) + return -ENOMEM; + + r = manager_process_button_device(m, d); + udev_device_unref(d); + + return r; +} + +int manager_dispatch_console(Manager *m) { + assert(m); + + if (m->vtconsole) + seat_read_active_vt(m->vtconsole); + + return 0; +} + +static int vt_is_busy(int vtnr) { + struct vt_stat vt_stat; + int r = 0, fd; + + assert(vtnr >= 1); + + /* We explicitly open /dev/tty1 here instead of /dev/tty0. If + * we'd open the latter we'd open the foreground tty which + * hence would be unconditionally busy. By opening /dev/tty1 + * we avoid this. Since tty1 is special and needs to be an + * explicitly loaded getty or DM this is safe. */ + + fd = open_terminal("/dev/tty1", O_RDWR|O_NOCTTY|O_CLOEXEC); + if (fd < 0) + return -errno; + + if (ioctl(fd, VT_GETSTATE, &vt_stat) < 0) + r = -errno; + else + r = !!(vt_stat.v_state & (1 << vtnr)); + + close_nointr_nofail(fd); + + return r; +} + +int manager_spawn_autovt(Manager *m, int vtnr) { + int r; + char *name = NULL; + const char *mode = "fail"; + + assert(m); + assert(vtnr >= 1); + + if ((unsigned) vtnr > m->n_autovts && + (unsigned) vtnr != m->reserve_vt) + return 0; + + if ((unsigned) vtnr != m->reserve_vt) { + /* If this is the reserved TTY, we'll start the getty + * on it in any case, but otherwise only if it is not + * busy. */ + + r = vt_is_busy(vtnr); + if (r < 0) + return r; + else if (r > 0) + return -EBUSY; + } + + if (asprintf(&name, "autovt@tty%i.service", vtnr) < 0) { + log_error("Could not allocate service name."); + r = -ENOMEM; + goto finish; + } + + r = bus_method_call_with_reply ( + m->bus, + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "StartUnit", + NULL, + NULL, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_STRING, &mode, + DBUS_TYPE_INVALID); + +finish: + free(name); + + return r; +} + +static int manager_reserve_vt(Manager *m) { + _cleanup_free_ char *p = NULL; + + assert(m); + + if (m->reserve_vt <= 0) + return 0; + + if (asprintf(&p, "/dev/tty%u", m->reserve_vt) < 0) + return log_oom(); + + m->reserve_vt_fd = open(p, O_RDWR|O_NOCTTY|O_CLOEXEC|O_NONBLOCK); + if (m->reserve_vt_fd < 0) { + + /* Don't complain on VT-less systems */ + if (errno != ENOENT) + log_warning("Failed to pin reserved VT: %m"); + return -errno; + } + + return 0; +} + +int manager_get_session_by_cgroup(Manager *m, const char *cgroup, Session **session) { + Session *s; + char *p; + + assert(m); + assert(cgroup); + assert(session); + + s = hashmap_get(m->session_cgroups, cgroup); + if (s) { + *session = s; + return 1; + } + + p = strdup(cgroup); + if (!p) + return log_oom(); + + for (;;) { + char *e; + + e = strrchr(p, '/'); + if (!e || e == p) { + free(p); + *session = NULL; + return 0; + } + + *e = 0; + + s = hashmap_get(m->session_cgroups, p); + if (s) { + free(p); + *session = s; + return 1; + } + } +} + +int manager_get_user_by_cgroup(Manager *m, const char *cgroup, User **user) { + User *u; + char *p; + + assert(m); + assert(cgroup); + assert(user); + + u = hashmap_get(m->user_cgroups, cgroup); + if (u) { + *user = u; + return 1; + } + + p = strdup(cgroup); + if (!p) + return log_oom(); + + for (;;) { + char *e; + + e = strrchr(p, '/'); + if (!e || e == p) { + free(p); + *user = NULL; + return 0; + } + + *e = 0; + + u = hashmap_get(m->user_cgroups, p); + if (u) { + free(p); + *user = u; + return 1; + } + } +} + +int manager_get_session_by_pid(Manager *m, pid_t pid, Session **session) { + char *p; + int r; + + assert(m); + assert(pid >= 1); + assert(session); + + r = cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, pid, &p); + if (r < 0) + return r; + + r = manager_get_session_by_cgroup(m, p, session); + free(p); + + return r; +} + +void manager_cgroup_notify_empty(Manager *m, const char *cgroup) { + Session *s; + User *u; + int r; + + r = manager_get_session_by_cgroup(m, cgroup, &s); + if (r > 0) + session_add_to_gc_queue(s); + + r = manager_get_user_by_cgroup(m, cgroup, &u); + if (r > 0) + user_add_to_gc_queue(u); +} + +static void manager_dispatch_other(Manager *m, int fd) { + Session *s; + Inhibitor *i; + Button *b; + + assert_se(m); + assert_se(fd >= 0); + + s = hashmap_get(m->session_fds, INT_TO_PTR(fd + 1)); + if (s) { + assert(s->fifo_fd == fd); + session_remove_fifo(s); + session_stop(s); + return; + } + + i = hashmap_get(m->inhibitor_fds, INT_TO_PTR(fd + 1)); + if (i) { + assert(i->fifo_fd == fd); + inhibitor_stop(i); + inhibitor_free(i); + return; + } + + b = hashmap_get(m->button_fds, INT_TO_PTR(fd + 1)); + if (b) { + assert(b->fd == fd); + button_process(b); + return; + } + + assert_not_reached("Got event for unknown fd"); +} + +static int manager_connect_bus(Manager *m) { + DBusError error; + int r; + struct epoll_event ev; + + assert(m); + assert(!m->bus); + assert(m->bus_fd < 0); + + dbus_error_init(&error); + + m->bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error); + if (!m->bus) { + log_error("Failed to get system D-Bus connection: %s", bus_error_message(&error)); + r = -ECONNREFUSED; + goto fail; + } + + if (!dbus_connection_register_object_path(m->bus, "/org/freedesktop/login1", &bus_manager_vtable, m) || + !dbus_connection_register_fallback(m->bus, "/org/freedesktop/login1/seat", &bus_seat_vtable, m) || + !dbus_connection_register_fallback(m->bus, "/org/freedesktop/login1/session", &bus_session_vtable, m) || + !dbus_connection_register_fallback(m->bus, "/org/freedesktop/login1/user", &bus_user_vtable, m) || + !dbus_connection_add_filter(m->bus, bus_message_filter, m, NULL)) { + r = log_oom(); + goto fail; + } + + dbus_bus_add_match(m->bus, + "type='signal'," + "interface='org.freedesktop.systemd1.Agent'," + "member='Released'," + "path='/org/freedesktop/systemd1/agent'", + &error); + + if (dbus_error_is_set(&error)) { + log_error("Failed to register match: %s", bus_error_message(&error)); + r = -EIO; + goto fail; + } + + r = dbus_bus_request_name(m->bus, "org.freedesktop.login1", DBUS_NAME_FLAG_DO_NOT_QUEUE, &error); + if (dbus_error_is_set(&error)) { + log_error("Failed to register name on bus: %s", bus_error_message(&error)); + r = -EIO; + goto fail; + } + + if (r != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) { + log_error("Failed to acquire name."); + r = -EEXIST; + goto fail; + } + + m->bus_fd = bus_loop_open(m->bus); + if (m->bus_fd < 0) { + r = m->bus_fd; + goto fail; + } + + zero(ev); + ev.events = EPOLLIN; + ev.data.u32 = FD_BUS; + + if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->bus_fd, &ev) < 0) + goto fail; + + return 0; + +fail: + dbus_error_free(&error); + + return r; +} + +static int manager_connect_console(Manager *m) { + struct epoll_event ev; + + assert(m); + assert(m->console_active_fd < 0); + + /* On certain architectures (S390 and Xen, and containers), + /dev/tty0 does not exist, so don't fail if we can't open + it. */ + if (access("/dev/tty0", F_OK) < 0) { + m->console_active_fd = -1; + return 0; + } + + m->console_active_fd = open("/sys/class/tty/tty0/active", O_RDONLY|O_NOCTTY|O_CLOEXEC); + if (m->console_active_fd < 0) { + + /* On some systems the device node /dev/tty0 may exist + * even though /sys/class/tty/tty0 does not. */ + if (errno == ENOENT) + return 0; + + log_error("Failed to open /sys/class/tty/tty0/active: %m"); + return -errno; + } + + zero(ev); + ev.events = 0; + ev.data.u32 = FD_CONSOLE; + + if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->console_active_fd, &ev) < 0) + return -errno; + + return 0; +} + +static int manager_connect_udev(Manager *m) { + struct epoll_event ev; + int r; + + assert(m); + assert(!m->udev_seat_monitor); + assert(!m->udev_vcsa_monitor); + assert(!m->udev_button_monitor); + + m->udev_seat_monitor = udev_monitor_new_from_netlink(m->udev, "udev"); + if (!m->udev_seat_monitor) + return -ENOMEM; + + r = udev_monitor_filter_add_match_tag(m->udev_seat_monitor, "seat"); + if (r < 0) + return r; + + r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_seat_monitor, "graphics", NULL); + if (r < 0) + return r; + + r = udev_monitor_enable_receiving(m->udev_seat_monitor); + if (r < 0) + return r; + + m->udev_seat_fd = udev_monitor_get_fd(m->udev_seat_monitor); + + zero(ev); + ev.events = EPOLLIN; + ev.data.u32 = FD_SEAT_UDEV; + if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->udev_seat_fd, &ev) < 0) + return -errno; + + /* Don't watch keys if nobody cares */ + if (m->handle_power_key != HANDLE_IGNORE || + m->handle_suspend_key != HANDLE_IGNORE || + m->handle_hibernate_key != HANDLE_IGNORE || + m->handle_lid_switch != HANDLE_IGNORE) { + + m->udev_button_monitor = udev_monitor_new_from_netlink(m->udev, "udev"); + if (!m->udev_button_monitor) + return -ENOMEM; + + r = udev_monitor_filter_add_match_tag(m->udev_button_monitor, "power-switch"); + if (r < 0) + return r; + + r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_button_monitor, "input", NULL); + if (r < 0) + return r; + + r = udev_monitor_enable_receiving(m->udev_button_monitor); + if (r < 0) + return r; + + m->udev_button_fd = udev_monitor_get_fd(m->udev_button_monitor); + + zero(ev); + ev.events = EPOLLIN; + ev.data.u32 = FD_BUTTON_UDEV; + if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->udev_button_fd, &ev) < 0) + return -errno; + } + + /* Don't bother watching VCSA devices, if nobody cares */ + if (m->n_autovts > 0 && m->console_active_fd >= 0) { + + m->udev_vcsa_monitor = udev_monitor_new_from_netlink(m->udev, "udev"); + if (!m->udev_vcsa_monitor) + return -ENOMEM; + + r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_vcsa_monitor, "vc", NULL); + if (r < 0) + return r; + + r = udev_monitor_enable_receiving(m->udev_vcsa_monitor); + if (r < 0) + return r; + + m->udev_vcsa_fd = udev_monitor_get_fd(m->udev_vcsa_monitor); + + zero(ev); + ev.events = EPOLLIN; + ev.data.u32 = FD_VCSA_UDEV; + if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->udev_vcsa_fd, &ev) < 0) + return -errno; + } + + return 0; +} + +void manager_gc(Manager *m, bool drop_not_started) { + Seat *seat; + Session *session; + User *user; + + assert(m); + + while ((seat = m->seat_gc_queue)) { + LIST_REMOVE(Seat, gc_queue, m->seat_gc_queue, seat); + seat->in_gc_queue = false; + + if (seat_check_gc(seat, drop_not_started) == 0) { + seat_stop(seat); + seat_free(seat); + } + } + + while ((session = m->session_gc_queue)) { + LIST_REMOVE(Session, gc_queue, m->session_gc_queue, session); + session->in_gc_queue = false; + + if (session_check_gc(session, drop_not_started) == 0) { + session_stop(session); + session_free(session); + } + } + + while ((user = m->user_gc_queue)) { + LIST_REMOVE(User, gc_queue, m->user_gc_queue, user); + user->in_gc_queue = false; + + if (user_check_gc(user, drop_not_started) == 0) { + user_stop(user); + user_free(user); + } + } +} + +int manager_get_idle_hint(Manager *m, dual_timestamp *t) { + Session *s; + bool idle_hint; + dual_timestamp ts = { 0, 0 }; + Iterator i; + + assert(m); + + idle_hint = !manager_is_inhibited(m, INHIBIT_IDLE, INHIBIT_BLOCK, t, false, false, 0); + + HASHMAP_FOREACH(s, m->sessions, i) { + dual_timestamp k; + int ih; + + ih = session_get_idle_hint(s, &k); + if (ih < 0) + return ih; + + if (!ih) { + if (!idle_hint) { + if (k.monotonic < ts.monotonic) + ts = k; + } else { + idle_hint = false; + ts = k; + } + } else if (idle_hint) { + + if (k.monotonic > ts.monotonic) + ts = k; + } + } + + if (t) + *t = ts; + + return idle_hint; +} + +int manager_dispatch_idle_action(Manager *m) { + struct dual_timestamp since; + struct itimerspec its; + int r; + usec_t n; + + assert(m); + + if (m->idle_action == HANDLE_IGNORE || + m->idle_action_usec <= 0) { + r = 0; + goto finish; + } + + zero(its); + n = now(CLOCK_MONOTONIC); + + r = manager_get_idle_hint(m, &since); + if (r <= 0) + /* Not idle. Let's check if after a timeout it it might be idle then. */ + timespec_store(&its.it_value, n + m->idle_action_usec); + else { + /* Idle! Let's see if it's time to do something, or if + * we shall sleep for longer. */ + + if (n >= since.monotonic + m->idle_action_usec && + (m->idle_action_not_before_usec <= 0 || n >= m->idle_action_not_before_usec + m->idle_action_usec)) { + log_info("System idle. Taking action."); + + manager_handle_action(m, 0, m->idle_action, false, false); + m->idle_action_not_before_usec = n; + } + + timespec_store(&its.it_value, MAX(since.monotonic, m->idle_action_not_before_usec) + m->idle_action_usec); + } + + if (m->idle_action_fd < 0) { + struct epoll_event ev; + + m->idle_action_fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK|TFD_CLOEXEC); + if (m->idle_action_fd < 0) { + log_error("Failed to create idle action timer: %m"); + r = -errno; + goto finish; + } + + zero(ev); + ev.events = EPOLLIN; + ev.data.u32 = FD_IDLE_ACTION; + + if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->idle_action_fd, &ev) < 0) { + log_error("Failed to add idle action timer to epoll: %m"); + r = -errno; + goto finish; + } + } + + if (timerfd_settime(m->idle_action_fd, TFD_TIMER_ABSTIME, &its, NULL) < 0) { + log_error("Failed to reset timerfd: %m"); + r = -errno; + goto finish; + } + + return 0; + +finish: + if (m->idle_action_fd >= 0) { + close_nointr_nofail(m->idle_action_fd); + m->idle_action_fd = -1; + } + + return r; +} +int manager_startup(Manager *m) { + int r; + Seat *seat; + Session *session; + User *user; + Inhibitor *inhibitor; + Iterator i; + + assert(m); + assert(m->epoll_fd <= 0); + + cg_shorten_controllers(m->reset_controllers); + cg_shorten_controllers(m->controllers); + + m->epoll_fd = epoll_create1(EPOLL_CLOEXEC); + if (m->epoll_fd < 0) + return -errno; + + /* Connect to console */ + r = manager_connect_console(m); + if (r < 0) + return r; + + /* Connect to udev */ + r = manager_connect_udev(m); + if (r < 0) + return r; + + /* Connect to the bus */ + r = manager_connect_bus(m); + if (r < 0) + return r; + + /* Instantiate magic seat 0 */ + r = manager_add_seat(m, "seat0", &m->vtconsole); + if (r < 0) + return r; + + /* Deserialize state */ + manager_enumerate_devices(m); + manager_enumerate_seats(m); + manager_enumerate_users(m); + manager_enumerate_sessions(m); + manager_enumerate_inhibitors(m); + manager_enumerate_buttons(m); + + /* Remove stale objects before we start them */ + manager_gc(m, false); + + /* Reserve the special reserved VT */ + manager_reserve_vt(m); + + /* And start everything */ + HASHMAP_FOREACH(seat, m->seats, i) + seat_start(seat); + + HASHMAP_FOREACH(user, m->users, i) + user_start(user); + + HASHMAP_FOREACH(session, m->sessions, i) + session_start(session); + + HASHMAP_FOREACH(inhibitor, m->inhibitors, i) + inhibitor_start(inhibitor); + + manager_dispatch_idle_action(m); + + return 0; +} + +static int manager_recheck_buttons(Manager *m) { + Iterator i; + Button *b; + int r = 0; + + assert(m); + + HASHMAP_FOREACH(b, m->buttons, i) { + int q; + + q = button_recheck(b); + if (q > 0) + return 1; + if (q < 0) + r = q; + } + + return r; +} + +int manager_run(Manager *m) { + assert(m); + + for (;;) { + struct epoll_event event; + int n; + int msec = -1; + + manager_gc(m, true); + + if (manager_dispatch_delayed(m) > 0) + continue; + + if (manager_recheck_buttons(m) > 0) + continue; + + if (dbus_connection_dispatch(m->bus) != DBUS_DISPATCH_COMPLETE) + continue; + + manager_gc(m, true); + + if (m->delayed_unit) { + usec_t x, y; + + x = now(CLOCK_MONOTONIC); + y = m->delayed_timestamp + m->inhibit_delay_max; + + msec = x >= y ? 0 : (int) ((y - x) / USEC_PER_MSEC); + } + + n = epoll_wait(m->epoll_fd, &event, 1, msec); + if (n < 0) { + if (errno == EINTR || errno == EAGAIN) + continue; + + log_error("epoll() failed: %m"); + return -errno; + } + + if (n == 0) + continue; + + switch (event.data.u32) { + + case FD_SEAT_UDEV: + manager_dispatch_seat_udev(m); + break; + + case FD_VCSA_UDEV: + manager_dispatch_vcsa_udev(m); + break; + + case FD_BUTTON_UDEV: + manager_dispatch_button_udev(m); + break; + + case FD_CONSOLE: + manager_dispatch_console(m); + break; + + case FD_IDLE_ACTION: + manager_dispatch_idle_action(m); + break; + + case FD_BUS: + bus_loop_dispatch(m->bus_fd); + break; + + default: + if (event.data.u32 >= FD_OTHER_BASE) + manager_dispatch_other(m, event.data.u32 - FD_OTHER_BASE); + } + } + + return 0; +} + +static int manager_parse_config_file(Manager *m) { + FILE *f; + const char *fn; + int r; + + assert(m); + + fn = "/etc/systemd/logind.conf"; + f = fopen(fn, "re"); + if (!f) { + if (errno == ENOENT) + return 0; + + log_warning("Failed to open configuration file %s: %m", fn); + return -errno; + } + + r = config_parse(fn, f, "Login\0", config_item_perf_lookup, (void*) logind_gperf_lookup, false, m); + if (r < 0) + log_warning("Failed to parse configuration file: %s", strerror(-r)); + + fclose(f); + + return r; +} + +int main(int argc, char *argv[]) { + Manager *m = NULL; + int r; + + log_set_target(LOG_TARGET_AUTO); + log_set_facility(LOG_AUTH); + log_parse_environment(); + log_open(); + + umask(0022); + + if (argc != 1) { + log_error("This program takes no arguments."); + r = -EINVAL; + goto finish; + } + + m = manager_new(); + if (!m) { + r = log_oom(); + goto finish; + } + + manager_parse_config_file(m); + + r = manager_startup(m); + if (r < 0) { + log_error("Failed to fully start up daemon: %s", strerror(-r)); + goto finish; + } + + log_debug("systemd-logind running as pid %lu", (unsigned long) getpid()); + + sd_notify(false, + "READY=1\n" + "STATUS=Processing requests..."); + + r = manager_run(m); + + log_debug("systemd-logind stopped as pid %lu", (unsigned long) getpid()); + +finish: + sd_notify(false, + "STATUS=Shutting down..."); + + if (m) + manager_free(m); + + return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/src/login/logind.conf b/src/login/logind.conf new file mode 100644 index 000000000..0861d73e0 --- /dev/null +++ b/src/login/logind.conf @@ -0,0 +1,28 @@ +# This file is part of systemd. +# +# 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. +# +# See logind.conf(5) for details + +[Login] +#NAutoVTs=6 +#ReserveVT=6 +#KillUserProcesses=no +#KillOnlyUsers= +#KillExcludeUsers=root +#Controllers= +#ResetControllers=cpu +#InhibitDelayMaxSec=5 +#HandlePowerKey=poweroff +#HandleSuspendKey=suspend +#HandleHibernateKey=hibernate +#HandleLidSwitch=suspend +#PowerKeyIgnoreInhibited=no +#SuspendKeyIgnoreInhibited=no +#HibernateKeyIgnoreInhibited=no +#LidSwitchIgnoreInhibited=yes +#IdleAction=ignore +#IdleActionSec=30min diff --git a/src/login/logind.h b/src/login/logind.h new file mode 100644 index 000000000..816635dcf --- /dev/null +++ b/src/login/logind.h @@ -0,0 +1,182 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +#include +#include +#include +#include + +#include "util.h" +#include "audit.h" +#include "list.h" +#include "hashmap.h" +#include "cgroup-util.h" + +typedef struct Manager Manager; + +#include "logind-device.h" +#include "logind-seat.h" +#include "logind-session.h" +#include "logind-user.h" +#include "logind-inhibit.h" +#include "logind-button.h" +#include "logind-action.h" + +struct Manager { + DBusConnection *bus; + + Hashmap *devices; + Hashmap *seats; + Hashmap *sessions; + Hashmap *users; + Hashmap *inhibitors; + Hashmap *buttons; + + LIST_HEAD(Seat, seat_gc_queue); + LIST_HEAD(Session, session_gc_queue); + LIST_HEAD(User, user_gc_queue); + + struct udev *udev; + struct udev_monitor *udev_seat_monitor, *udev_vcsa_monitor, *udev_button_monitor; + + int udev_seat_fd; + int udev_vcsa_fd; + int udev_button_fd; + + int console_active_fd; + int bus_fd; + int epoll_fd; + + unsigned n_autovts; + + unsigned reserve_vt; + int reserve_vt_fd; + + Seat *vtconsole; + + char *cgroup_path; + char **controllers, **reset_controllers; + + char **kill_only_users, **kill_exclude_users; + + bool kill_user_processes; + + unsigned long session_counter; + unsigned long inhibit_counter; + + Hashmap *session_cgroups; + Hashmap *user_cgroups; + + Hashmap *session_fds; + Hashmap *inhibitor_fds; + Hashmap *button_fds; + + /* If a shutdown was delayed due to a inhibitor this contains + the unit name we are supposed to start after the delay is + over */ + const char *delayed_unit; + InhibitWhat delayed_what; + usec_t delayed_timestamp; + + usec_t inhibit_delay_max; + + int idle_action_fd; + usec_t idle_action_usec; + usec_t idle_action_not_before_usec; + HandleAction idle_action; + + HandleAction handle_power_key; + HandleAction handle_suspend_key; + HandleAction handle_hibernate_key; + HandleAction handle_lid_switch; + + bool power_key_ignore_inhibited; + bool suspend_key_ignore_inhibited; + bool hibernate_key_ignore_inhibited; + bool lid_switch_ignore_inhibited; +}; + +enum { + FD_SEAT_UDEV, + FD_VCSA_UDEV, + FD_BUTTON_UDEV, + FD_CONSOLE, + FD_BUS, + FD_IDLE_ACTION, + FD_OTHER_BASE +}; + +Manager *manager_new(void); +void manager_free(Manager *m); + +int manager_add_device(Manager *m, const char *sysfs, Device **_device); +int manager_add_button(Manager *m, const char *name, Button **_button); +int manager_add_seat(Manager *m, const char *id, Seat **_seat); +int manager_add_session(Manager *m, User *u, const char *id, Session **_session); +int manager_add_user(Manager *m, uid_t uid, gid_t gid, const char *name, User **_user); +int manager_add_user_by_name(Manager *m, const char *name, User **_user); +int manager_add_user_by_uid(Manager *m, uid_t uid, User **_user); +int manager_add_inhibitor(Manager *m, const char* id, Inhibitor **_inhibitor); + +int manager_process_seat_device(Manager *m, struct udev_device *d); +int manager_process_button_device(Manager *m, struct udev_device *d); + +int manager_dispatch_seat_udev(Manager *m); +int manager_dispatch_vcsa_udev(Manager *m); +int manager_dispatch_button_udev(Manager *m); +int manager_dispatch_console(Manager *m); +int manager_dispatch_idle_action(Manager *m); + +int manager_enumerate_devices(Manager *m); +int manager_enumerate_buttons(Manager *m); +int manager_enumerate_seats(Manager *m); +int manager_enumerate_sessions(Manager *m); +int manager_enumerate_users(Manager *m); +int manager_enumerate_inhibitors(Manager *m); + +int manager_startup(Manager *m); +int manager_run(Manager *m); +int manager_spawn_autovt(Manager *m, int vtnr); + +void manager_cgroup_notify_empty(Manager *m, const char *cgroup); + +void manager_gc(Manager *m, bool drop_not_started); + +int manager_get_idle_hint(Manager *m, dual_timestamp *t); + +int manager_get_user_by_cgroup(Manager *m, const char *cgroup, User **user); +int manager_get_session_by_cgroup(Manager *m, const char *cgroup, Session **session); +int manager_get_session_by_pid(Manager *m, pid_t pid, Session **session); + +extern const DBusObjectPathVTable bus_manager_vtable; + +DBusHandlerResult bus_message_filter(DBusConnection *c, DBusMessage *message, void *userdata); + +int bus_manager_shutdown_or_sleep_now_or_later(Manager *m, const char *unit_name, InhibitWhat w, DBusError *error); + +int manager_send_changed(Manager *manager, const char *properties); + +int manager_dispatch_delayed(Manager *manager); + +/* gperf lookup function */ +const struct ConfigPerfItem* logind_gperf_lookup(const char *key, unsigned length); diff --git a/src/login/multi-seat-x.c b/src/login/multi-seat-x.c new file mode 100644 index 000000000..83760d419 --- /dev/null +++ b/src/login/multi-seat-x.c @@ -0,0 +1,108 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +#include +#include + +#include "util.h" +#include "mkdir.h" + +int main(int argc, char *argv[]) { + + int i; + const char *seat = NULL; + char **new_argv; + _cleanup_free_ char *path = NULL; + int r; + _cleanup_fclose_ FILE *f = NULL; + + /* This binary will go away as soon as X natively takes the + * arguments in question as command line parameters, instead + * of requiring them in the configuration file. */ + + /* If this file is removed, don't forget to remove the code + * that invokes this in gdm and other display managers. */ + + for (i = 1; i < argc; i++) + if (streq(argv[i], "-seat")) + seat = argv[i+1]; + + if (isempty(seat) || streq(seat, "seat0")) { + argv[0] = (char*) X_SERVER; + execv(X_SERVER, argv); + log_error("Failed to execute real X server: %m"); + goto fail; + } + + r = mkdir_safe_label("/run/systemd/multi-session-x", 0755, 0, 0); + if (r < 0) { + log_error("Failed to create directory: %s", strerror(-r)); + goto fail; + } + + path = strappend("/run/systemd/multi-session-x/", seat); + if (!path) { + log_oom(); + goto fail; + } + + f = fopen(path, "we"); + if (!f) { + log_error("Failed to write configuration file: %m"); + goto fail; + } + + fprintf(f, + "Section \"ServerFlags\"\n" + " Option \"AutoAddDevices\" \"True\"\n" + " Option \"AllowEmptyInput\" \"True\"\n" + " Option \"DontVTSwitch\" \"True\"\n" + "EndSection\n" + "Section \"InputClass\"\n" + " Identifier \"Force Input Devices to Seat\"\n" + " Option \"GrabDevice\" \"True\"\n" + "EndSection\n"); + + fflush(f); + + if (ferror(f)) { + log_error("Failed to write configuration file: %m"); + goto fail; + } + + fclose(f); + f = NULL; + + new_argv = newa(char*, argc + 3 + 1); + memcpy(new_argv, argv, sizeof(char*) * (argc + 2 + 1)); + + new_argv[0] = (char*) X_SERVER; + new_argv[argc+0] = (char*) "-config"; + new_argv[argc+1] = path; + new_argv[argc+2] = (char*) "-sharevts"; + new_argv[argc+3] = NULL; + + execv(X_SERVER, new_argv); + log_error("Failed to execute real X server: %m"); + +fail: + return EXIT_FAILURE; +} diff --git a/src/login/org.freedesktop.login1.conf b/src/login/org.freedesktop.login1.conf new file mode 100644 index 000000000..6c1f2f57e --- /dev/null +++ b/src/login/org.freedesktop.login1.conf @@ -0,0 +1,150 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/login/org.freedesktop.login1.policy.in b/src/login/org.freedesktop.login1.policy.in new file mode 100644 index 000000000..b5f5db4f6 --- /dev/null +++ b/src/login/org.freedesktop.login1.policy.in @@ -0,0 +1,273 @@ + + + + + + + + The systemd Project + http://www.freedesktop.org/wiki/Software/systemd + + + <_description>Allow applications to inhibit system shutdown + <_message>Authentication is required to allow an application to inhibit system shutdown. + + no + yes + yes + + org.freedesktop.login1.inhibit-delay-shutdown org.freedesktop.login1.inhibit-block-sleep org.freedesktop.login1.inhibit-delay-sleep org.freedesktop.login1.inhibit-block-idle + + + + <_description>Allow applications to delay system shutdown + <_message>Authentication is required to allow an application to delay system shutdown. + + yes + yes + yes + + org.freedesktop.login1.inhibit-delay-sleep + + + + <_description>Allow applications to inhibit system sleep + <_message>Authentication is required to allow an application to inhibit system sleep. + + no + yes + yes + + org.freedesktop.login1.inhibit-delay-sleep org.freedesktop.login1.inhibit-block-idle + + + + <_description>Allow applications to delay system sleep + <_message>Authentication is required to allow an application to delay system sleep. + + yes + yes + yes + + + + + <_description>Allow applications to inhibit automatic system suspend + <_message>Authentication is required to allow an application to inhibit automatic system suspend. + + yes + yes + yes + + + + + <_description>Allow applications to inhibit system handling of the power key + <_message>Authentication is required to allow an application to inhibit system handling of the power key. + + no + yes + yes + + org.freedesktop.login1.inhibit-handle-suspend-key org.freedesktop.login1.inhibit-handle-hibernate-key org.freedesktop.login1.inhibit-handle-lid-switch + + + + <_description>Allow applications to inhibit system handling of the suspend key + <_message>Authentication is required to allow an application to inhibit system handling of the suspend key. + + no + yes + yes + + org.freedesktop.login1.inhibit-handle-hibernate-key org.freedesktop.login1.inhibit-handle-lid-switch + + + + <_description>Allow applications to inhibit system handling of the hibernate key + <_message>Authentication is required to allow an application to inhibit system handling of the hibernate key. + + no + yes + yes + + + + + <_description>Allow applications to inhibit system handling of the lid switch + <_message>Authentication is required to allow an application to inhibit system handling of the lid switch. + + no + yes + yes + + + + + <_description>Allow non-logged-in users to run programs + <_message>Authentication is required to allow a non-logged-in user to run programs. + + auth_admin_keep + auth_admin_keep + auth_admin_keep + + + + + <_description>Allow attaching devices to seats + <_message>Authentication is required for attaching a device to a seat. + + auth_admin_keep + auth_admin_keep + auth_admin_keep + + org.freedesktop.login1.flush-devices + + + + <_description>Flush device to seat attachments + <_message>Authentication is required for resetting how devices are attached to seats. + + auth_admin_keep + auth_admin_keep + auth_admin_keep + + + + + <_description>Power off the system + <_message>Authentication is required for powering off the system. + + auth_admin_keep + auth_admin_keep + yes + + + + + <_description>Power off the system while other users are logged in + <_message>Authentication is required for powering off the system while other users are logged in. + + auth_admin_keep + auth_admin_keep + auth_admin_keep + + org.freedesktop.login1.power-off + + + + <_description>Power off the system while an application asked to inhibit it + <_message>Authentication is required for powering off the system while an application asked to inhibit it. + + auth_admin_keep + auth_admin_keep + auth_admin_keep + + org.freedesktop.login1.power-off + + + + <_description>Reboot the system + <_message>Authentication is required for rebooting the system. + + auth_admin_keep + auth_admin_keep + yes + + + + + <_description>Reboot the system while other users are logged in + <_message>Authentication is required for rebooting the system while other users are logged in. + + auth_admin_keep + auth_admin_keep + auth_admin_keep + + org.freedesktop.login1.reboot + + + + <_description>Reboot the system while an application asked to inhibit it + <_message>Authentication is required for rebooting the system while an application asked to inhibit it. + + auth_admin_keep + auth_admin_keep + auth_admin_keep + + org.freedesktop.login1.reboot + + + + <_description>Suspend the system + <_message>Authentication is required for suspending the system. + + auth_admin_keep + auth_admin_keep + yes + + + + + <_description>Suspend the system while other users are logged in + <_message>Authentication is required for suspending the system while other users are logged in. + + auth_admin_keep + auth_admin_keep + yes + + org.freedesktop.login1.suspend + + + + <_description>Suspend the system while an application asked to inhibit it + <_message>Authentication is required for suspending the system while an application asked to inhibit it. + + auth_admin_keep + auth_admin_keep + auth_admin_keep + + org.freedesktop.login1.suspend + + + + <_description>Hibernate the system + <_message>Authentication is required for hibernating the system. + + auth_admin_keep + auth_admin_keep + yes + + + + + <_description>Hibernate the system while other users are logged in + <_message>Authentication is required for hibernating the system while other users are logged in. + + auth_admin_keep + auth_admin_keep + auth_admin_keep + + org.freedesktop.login1.hibernate + + + + <_description>Hibernate the system while an application asked to inhibit it + <_message>Authentication is required for hibernating the system while an application asked to inhibit it. + + auth_admin_keep + auth_admin_keep + auth_admin_keep + + org.freedesktop.login1.hibernate + + + diff --git a/src/login/org.freedesktop.login1.service b/src/login/org.freedesktop.login1.service new file mode 100644 index 000000000..762dae2bb --- /dev/null +++ b/src/login/org.freedesktop.login1.service @@ -0,0 +1,12 @@ +# This file is part of systemd. +# +# 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. + +[D-BUS Service] +Name=org.freedesktop.login1 +Exec=/bin/false +User=root +SystemdService=dbus-org.freedesktop.login1.service diff --git a/src/login/pam-module.c b/src/login/pam-module.c new file mode 100644 index 000000000..88b0ef9e4 --- /dev/null +++ b/src/login/pam-module.c @@ -0,0 +1,733 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include "util.h" +#include "audit.h" +#include "macro.h" +#include "strv.h" +#include "dbus-common.h" +#include "def.h" +#include "socket-util.h" + +static int parse_argv(pam_handle_t *handle, + int argc, const char **argv, + char ***controllers, + char ***reset_controllers, + bool *kill_processes, + char ***kill_only_users, + char ***kill_exclude_users, + const char **class, + bool *debug) { + + unsigned i; + + assert(argc >= 0); + assert(argc == 0 || argv); + + for (i = 0; i < (unsigned) argc; i++) { + int k; + + if (startswith(argv[i], "kill-session-processes=")) { + if ((k = parse_boolean(argv[i] + 23)) < 0) { + pam_syslog(handle, LOG_ERR, "Failed to parse kill-session-processes= argument."); + return k; + } + + if (kill_processes) + *kill_processes = k; + + } else if (startswith(argv[i], "kill-session=")) { + /* As compatibility for old versions */ + + if ((k = parse_boolean(argv[i] + 13)) < 0) { + pam_syslog(handle, LOG_ERR, "Failed to parse kill-session= argument."); + return k; + } + + if (kill_processes) + *kill_processes = k; + + } else if (startswith(argv[i], "controllers=")) { + + if (controllers) { + char **l; + + if (!(l = strv_split(argv[i] + 12, ","))) { + pam_syslog(handle, LOG_ERR, "Out of memory."); + return -ENOMEM; + } + + strv_free(*controllers); + *controllers = l; + } + + } else if (startswith(argv[i], "reset-controllers=")) { + + if (reset_controllers) { + char **l; + + if (!(l = strv_split(argv[i] + 18, ","))) { + pam_syslog(handle, LOG_ERR, "Out of memory."); + return -ENOMEM; + } + + strv_free(*reset_controllers); + *reset_controllers = l; + } + + } else if (startswith(argv[i], "kill-only-users=")) { + + if (kill_only_users) { + char **l; + + if (!(l = strv_split(argv[i] + 16, ","))) { + pam_syslog(handle, LOG_ERR, "Out of memory."); + return -ENOMEM; + } + + strv_free(*kill_only_users); + *kill_only_users = l; + } + + } else if (startswith(argv[i], "kill-exclude-users=")) { + + if (kill_exclude_users) { + char **l; + + if (!(l = strv_split(argv[i] + 19, ","))) { + pam_syslog(handle, LOG_ERR, "Out of memory."); + return -ENOMEM; + } + + strv_free(*kill_exclude_users); + *kill_exclude_users = l; + } + + } else if (startswith(argv[i], "class=")) { + + if (class) + *class = argv[i] + 6; + + } else if (startswith(argv[i], "debug=")) { + if ((k = parse_boolean(argv[i] + 6)) < 0) { + pam_syslog(handle, LOG_ERR, "Failed to parse debug= argument."); + return k; + } + + if (debug) + *debug = k; + + } else if (startswith(argv[i], "create-session=") || + startswith(argv[i], "kill-user=")) { + + pam_syslog(handle, LOG_WARNING, "Option %s not supported anymore, ignoring.", argv[i]); + + } else { + pam_syslog(handle, LOG_ERR, "Unknown parameter '%s'.", argv[i]); + return -EINVAL; + } + } + + return 0; +} + +static int get_user_data( + pam_handle_t *handle, + const char **ret_username, + struct passwd **ret_pw) { + + const char *username = NULL; + struct passwd *pw = NULL; + uid_t uid; + int r; + + assert(handle); + assert(ret_username); + assert(ret_pw); + + r = audit_loginuid_from_pid(0, &uid); + if (r >= 0) + pw = pam_modutil_getpwuid(handle, uid); + else { + r = pam_get_user(handle, &username, NULL); + if (r != PAM_SUCCESS) { + pam_syslog(handle, LOG_ERR, "Failed to get user name."); + return r; + } + + if (isempty(username)) { + pam_syslog(handle, LOG_ERR, "User name not valid."); + return PAM_AUTH_ERR; + } + + pw = pam_modutil_getpwnam(handle, username); + } + + if (!pw) { + pam_syslog(handle, LOG_ERR, "Failed to get user data."); + return PAM_USER_UNKNOWN; + } + + *ret_pw = pw; + *ret_username = username ? username : pw->pw_name; + + return PAM_SUCCESS; +} + +static bool check_user_lists( + pam_handle_t *handle, + uid_t uid, + char **kill_only_users, + char **kill_exclude_users) { + + const char *name = NULL; + char **l; + + assert(handle); + + if (uid == 0) + name = "root"; /* Avoid obvious NSS requests, to suppress network traffic */ + else { + struct passwd *pw; + + pw = pam_modutil_getpwuid(handle, uid); + if (pw) + name = pw->pw_name; + } + + STRV_FOREACH(l, kill_exclude_users) { + uid_t u; + + if (parse_uid(*l, &u) >= 0) + if (u == uid) + return false; + + if (name && streq(name, *l)) + return false; + } + + if (strv_isempty(kill_only_users)) + return true; + + STRV_FOREACH(l, kill_only_users) { + uid_t u; + + if (parse_uid(*l, &u) >= 0) + if (u == uid) + return true; + + if (name && streq(name, *l)) + return true; + } + + return false; +} + +static int get_seat_from_display(const char *display, const char **seat, uint32_t *vtnr) { + char *p = NULL; + int r; + int fd; + union sockaddr_union sa; + struct ucred ucred; + socklen_t l; + char *tty; + int v; + + assert(display); + assert(vtnr); + + /* We deduce the X11 socket from the display name, then use + * SO_PEERCRED to determine the X11 server process, ask for + * the controlling tty of that and if it's a VC then we know + * the seat and the virtual terminal. Sounds ugly, is only + * semi-ugly. */ + + r = socket_from_display(display, &p); + if (r < 0) + return r; + + fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0); + if (fd < 0) { + free(p); + return -errno; + } + + zero(sa); + sa.un.sun_family = AF_UNIX; + strncpy(sa.un.sun_path, p, sizeof(sa.un.sun_path)-1); + free(p); + + if (connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0) { + close_nointr_nofail(fd); + return -errno; + } + + l = sizeof(ucred); + r = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &ucred, &l); + close_nointr_nofail(fd); + + if (r < 0) + return -errno; + + r = get_ctty(ucred.pid, NULL, &tty); + if (r < 0) + return r; + + v = vtnr_from_tty(tty); + free(tty); + + if (v < 0) + return v; + else if (v == 0) + return -ENOENT; + + if (seat) + *seat = "seat0"; + *vtnr = (uint32_t) v; + + return 0; +} + +_public_ PAM_EXTERN int pam_sm_open_session( + pam_handle_t *handle, + int flags, + int argc, const char **argv) { + + struct passwd *pw; + bool kill_processes = false, debug = false; + const char *username, *id, *object_path, *runtime_path, *service = NULL, *tty = NULL, *display = NULL, *remote_user = NULL, *remote_host = NULL, *seat = NULL, *type = NULL, *class = NULL, *class_pam = NULL, *cvtnr = NULL; + char **controllers = NULL, **reset_controllers = NULL, **kill_only_users = NULL, **kill_exclude_users = NULL; + DBusError error; + uint32_t uid, pid; + DBusMessageIter iter; + dbus_bool_t kp; + int session_fd = -1; + DBusConnection *bus = NULL; + DBusMessage *m = NULL, *reply = NULL; + dbus_bool_t remote, existing; + int r; + uint32_t vtnr = 0; + + assert(handle); + + dbus_error_init(&error); + + /* pam_syslog(handle, LOG_INFO, "pam-systemd initializing"); */ + + /* Make this a NOP on non-systemd systems */ + if (sd_booted() <= 0) + return PAM_SUCCESS; + + if (parse_argv(handle, + argc, argv, + &controllers, &reset_controllers, + &kill_processes, &kill_only_users, &kill_exclude_users, + &class_pam, &debug) < 0) { + r = PAM_SESSION_ERR; + goto finish; + } + + r = get_user_data(handle, &username, &pw); + if (r != PAM_SUCCESS) + goto finish; + + /* Make sure we don't enter a loop by talking to + * systemd-logind when it is actually waiting for the + * background to finish start-up. If the service is + * "systemd-shared" we simply set XDG_RUNTIME_DIR and + * leave. */ + + pam_get_item(handle, PAM_SERVICE, (const void**) &service); + if (streq_ptr(service, "systemd-shared")) { + char *p, *rt = NULL; + + if (asprintf(&p, "/run/systemd/users/%lu", (unsigned long) pw->pw_uid) < 0) { + r = PAM_BUF_ERR; + goto finish; + } + + r = parse_env_file(p, NEWLINE, + "RUNTIME", &rt, + NULL); + free(p); + + if (r < 0 && r != -ENOENT) { + r = PAM_SESSION_ERR; + free(rt); + goto finish; + } + + if (rt) { + r = pam_misc_setenv(handle, "XDG_RUNTIME_DIR", rt, 0); + free(rt); + + if (r != PAM_SUCCESS) { + pam_syslog(handle, LOG_ERR, "Failed to set runtime dir."); + goto finish; + } + } + + r = PAM_SUCCESS; + goto finish; + } + + if (kill_processes) + kill_processes = check_user_lists(handle, pw->pw_uid, kill_only_users, kill_exclude_users); + + dbus_connection_set_change_sigpipe(FALSE); + + bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error); + if (!bus) { + pam_syslog(handle, LOG_ERR, "Failed to connect to system bus: %s", bus_error_message(&error)); + r = PAM_SESSION_ERR; + goto finish; + } + + m = dbus_message_new_method_call( + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + "CreateSession"); + if (!m) { + pam_syslog(handle, LOG_ERR, "Could not allocate create session message."); + r = PAM_BUF_ERR; + goto finish; + } + + uid = pw->pw_uid; + pid = getpid(); + + pam_get_item(handle, PAM_XDISPLAY, (const void**) &display); + pam_get_item(handle, PAM_TTY, (const void**) &tty); + pam_get_item(handle, PAM_RUSER, (const void**) &remote_user); + pam_get_item(handle, PAM_RHOST, (const void**) &remote_host); + + seat = pam_getenv(handle, "XDG_SEAT"); + if (isempty(seat)) + seat = getenv("XDG_SEAT"); + + cvtnr = pam_getenv(handle, "XDG_VTNR"); + if (isempty(cvtnr)) + cvtnr = getenv("XDG_VTNR"); + + service = strempty(service); + tty = strempty(tty); + display = strempty(display); + remote_user = strempty(remote_user); + remote_host = strempty(remote_host); + seat = strempty(seat); + + if (strchr(tty, ':')) { + /* A tty with a colon is usually an X11 display, place + * there to show up in utmp. We rearrange things and + * don't pretend that an X display was a tty */ + + if (isempty(display)) + display = tty; + tty = ""; + } else if (streq(tty, "cron")) { + /* cron has been setting PAM_TTY to "cron" for a very + * long time and it probably shouldn't stop doing that + * for compatibility reasons. */ + tty = ""; + type = "unspecified"; + } else if (streq(tty, "ssh")) { + /* ssh has been setting PAM_TTY to "ssh" for a very + * long time and probably shouldn't stop doing that + * for compatibility reasons. */ + tty = ""; + type ="tty"; + } + + /* If this fails vtnr will be 0, that's intended */ + if (!isempty(cvtnr)) + safe_atou32(cvtnr, &vtnr); + + if (!isempty(display) && vtnr <= 0) { + if (isempty(seat)) + get_seat_from_display(display, &seat, &vtnr); + else if (streq(seat, "seat0")) + get_seat_from_display(display, NULL, &vtnr); + } + + if (!type) + type = !isempty(display) ? "x11" : + !isempty(tty) ? "tty" : "unspecified"; + + class = pam_getenv(handle, "XDG_SESSION_CLASS"); + if (isempty(class)) + class = getenv("XDG_SESSION_CLASS"); + if (isempty(class)) + class = class_pam; + if (isempty(class)) + class = "user"; + + remote = !isempty(remote_host) && + !streq(remote_host, "localhost") && + !streq(remote_host, "localhost.localdomain"); + + if (!dbus_message_append_args(m, + DBUS_TYPE_UINT32, &uid, + DBUS_TYPE_UINT32, &pid, + DBUS_TYPE_STRING, &service, + DBUS_TYPE_STRING, &type, + DBUS_TYPE_STRING, &class, + DBUS_TYPE_STRING, &seat, + DBUS_TYPE_UINT32, &vtnr, + DBUS_TYPE_STRING, &tty, + DBUS_TYPE_STRING, &display, + DBUS_TYPE_BOOLEAN, &remote, + DBUS_TYPE_STRING, &remote_user, + DBUS_TYPE_STRING, &remote_host, + DBUS_TYPE_INVALID)) { + pam_syslog(handle, LOG_ERR, "Could not attach parameters to message."); + r = PAM_BUF_ERR; + goto finish; + } + + dbus_message_iter_init_append(m, &iter); + + r = bus_append_strv_iter(&iter, controllers); + if (r < 0) { + pam_syslog(handle, LOG_ERR, "Could not attach parameter to message."); + r = PAM_BUF_ERR; + goto finish; + } + + r = bus_append_strv_iter(&iter, reset_controllers); + if (r < 0) { + pam_syslog(handle, LOG_ERR, "Could not attach parameter to message."); + r = PAM_BUF_ERR; + goto finish; + } + + kp = kill_processes; + if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &kp)) { + pam_syslog(handle, LOG_ERR, "Could not attach parameter to message."); + r = PAM_BUF_ERR; + goto finish; + } + + if (debug) + pam_syslog(handle, LOG_DEBUG, "Asking logind to create session: " + "uid=%u pid=%u service=%s type=%s class=%s seat=%s vtnr=%u tty=%s display=%s remote=%s remote_user=%s remote_host=%s", + uid, pid, service, type, class, seat, vtnr, tty, display, yes_no(remote), remote_user, remote_host); + + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error); + if (!reply) { + pam_syslog(handle, LOG_ERR, "Failed to create session: %s", bus_error_message(&error)); + r = PAM_SESSION_ERR; + goto finish; + } + + if (!dbus_message_get_args(reply, &error, + DBUS_TYPE_STRING, &id, + DBUS_TYPE_OBJECT_PATH, &object_path, + DBUS_TYPE_STRING, &runtime_path, + DBUS_TYPE_UNIX_FD, &session_fd, + DBUS_TYPE_STRING, &seat, + DBUS_TYPE_UINT32, &vtnr, + DBUS_TYPE_BOOLEAN, &existing, + DBUS_TYPE_INVALID)) { + pam_syslog(handle, LOG_ERR, "Failed to parse message: %s", bus_error_message(&error)); + r = PAM_SESSION_ERR; + goto finish; + } + + if (debug) + pam_syslog(handle, LOG_DEBUG, "Reply from logind: " + "id=%s object_path=%s runtime_path=%s session_fd=%d seat=%s vtnr=%u", + id, object_path, runtime_path, session_fd, seat, vtnr); + + r = pam_misc_setenv(handle, "XDG_SESSION_ID", id, 0); + if (r != PAM_SUCCESS) { + pam_syslog(handle, LOG_ERR, "Failed to set session id."); + goto finish; + } + + r = pam_misc_setenv(handle, "XDG_RUNTIME_DIR", runtime_path, 0); + if (r != PAM_SUCCESS) { + pam_syslog(handle, LOG_ERR, "Failed to set runtime dir."); + goto finish; + } + + if (!isempty(seat)) { + r = pam_misc_setenv(handle, "XDG_SEAT", seat, 0); + if (r != PAM_SUCCESS) { + pam_syslog(handle, LOG_ERR, "Failed to set seat."); + goto finish; + } + } + + if (vtnr > 0) { + char buf[11]; + snprintf(buf, sizeof(buf), "%u", vtnr); + char_array_0(buf); + + r = pam_misc_setenv(handle, "XDG_VTNR", buf, 0); + if (r != PAM_SUCCESS) { + pam_syslog(handle, LOG_ERR, "Failed to set virtual terminal number."); + goto finish; + } + } + + r = pam_set_data(handle, "systemd.existing", INT_TO_PTR(!!existing), NULL); + if (r != PAM_SUCCESS) { + pam_syslog(handle, LOG_ERR, "Failed to install existing flag."); + return r; + } + + if (session_fd >= 0) { + r = pam_set_data(handle, "systemd.session-fd", INT_TO_PTR(session_fd+1), NULL); + if (r != PAM_SUCCESS) { + pam_syslog(handle, LOG_ERR, "Failed to install session fd."); + return r; + } + } + + session_fd = -1; + + r = PAM_SUCCESS; + +finish: + strv_free(controllers); + strv_free(reset_controllers); + strv_free(kill_only_users); + strv_free(kill_exclude_users); + + dbus_error_free(&error); + + if (bus) { + dbus_connection_close(bus); + dbus_connection_unref(bus); + } + + if (m) + dbus_message_unref(m); + + if (reply) + dbus_message_unref(reply); + + if (session_fd >= 0) + close_nointr_nofail(session_fd); + + return r; +} + +_public_ PAM_EXTERN int pam_sm_close_session( + pam_handle_t *handle, + int flags, + int argc, const char **argv) { + + const void *p = NULL, *existing = NULL; + const char *id; + DBusConnection *bus = NULL; + DBusMessage *m = NULL, *reply = NULL; + DBusError error; + int r; + + assert(handle); + + dbus_error_init(&error); + + /* Only release session if it wasn't pre-existing when we + * tried to create it */ + pam_get_data(handle, "systemd.existing", &existing); + + id = pam_getenv(handle, "XDG_SESSION_ID"); + if (id && !existing) { + + /* Before we go and close the FIFO we need to tell + * logind that this is a clean session shutdown, so + * that it doesn't just go and slaughter us + * immediately after closing the fd */ + + bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error); + if (!bus) { + pam_syslog(handle, LOG_ERR, "Failed to connect to system bus: %s", bus_error_message(&error)); + r = PAM_SESSION_ERR; + goto finish; + } + + m = dbus_message_new_method_call( + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + "ReleaseSession"); + if (!m) { + pam_syslog(handle, LOG_ERR, "Could not allocate release session message."); + r = PAM_BUF_ERR; + goto finish; + } + + if (!dbus_message_append_args(m, + DBUS_TYPE_STRING, &id, + DBUS_TYPE_INVALID)) { + pam_syslog(handle, LOG_ERR, "Could not attach parameters to message."); + r = PAM_BUF_ERR; + goto finish; + } + + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error); + if (!reply) { + pam_syslog(handle, LOG_ERR, "Failed to release session: %s", bus_error_message(&error)); + r = PAM_SESSION_ERR; + goto finish; + } + } + + r = PAM_SUCCESS; + +finish: + pam_get_data(handle, "systemd.session-fd", &p); + if (p) + close_nointr(PTR_TO_INT(p) - 1); + + dbus_error_free(&error); + + if (bus) { + dbus_connection_close(bus); + dbus_connection_unref(bus); + } + + if (m) + dbus_message_unref(m); + + if (reply) + dbus_message_unref(reply); + + return r; +} diff --git a/src/login/sd-login.c b/src/login/sd-login.c new file mode 100644 index 000000000..45e3bb8dc --- /dev/null +++ b/src/login/sd-login.c @@ -0,0 +1,794 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +#include +#include +#include +#include + +#include "util.h" +#include "cgroup-util.h" +#include "macro.h" +#include "sd-login.h" +#include "strv.h" + +_public_ int sd_pid_get_session(pid_t pid, char **session) { + int r; + char *cgroup, *p; + + if (pid < 0) + return -EINVAL; + + if (!session) + return -EINVAL; + + r = cg_pid_get_cgroup(pid, NULL, &cgroup); + if (r < 0) + return r; + + if (!startswith(cgroup, "/user/")) { + free(cgroup); + return -ENOENT; + } + + p = strchr(cgroup + 6, '/'); + if (!p) { + free(cgroup); + return -ENOENT; + } + + p++; + if (startswith(p, "shared/") || streq(p, "shared")) { + free(cgroup); + return -ENOENT; + } + + p = strndup(p, strcspn(p, "/")); + free(cgroup); + + if (!p) + return -ENOMEM; + + *session = p; + return 0; +} + +_public_ int sd_pid_get_unit(pid_t pid, char **unit) { + + if (pid < 0) + return -EINVAL; + + if (!unit) + return -EINVAL; + + return cg_pid_get_unit(pid, unit); +} + +_public_ int sd_pid_get_owner_uid(pid_t pid, uid_t *uid) { + int r; + char *root, *cgroup, *p, *cc; + struct stat st; + + if (pid < 0) + return -EINVAL; + + if (!uid) + return -EINVAL; + + r = cg_pid_get_cgroup(pid, &root, &cgroup); + if (r < 0) + return r; + + if (!startswith(cgroup, "/user/")) { + free(cgroup); + free(root); + return -ENOENT; + } + + p = strchr(cgroup + 6, '/'); + if (!p) { + free(cgroup); + return -ENOENT; + } + + p++; + p += strcspn(p, "/"); + *p = 0; + + r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, root, cgroup, &cc); + free(root); + free(cgroup); + + if (r < 0) + return -ENOMEM; + + r = lstat(cc, &st); + free(cc); + + if (r < 0) + return -errno; + + if (!S_ISDIR(st.st_mode)) + return -ENOTDIR; + + *uid = st.st_uid; + return 0; +} + +_public_ int sd_uid_get_state(uid_t uid, char**state) { + char *p, *s = NULL; + int r; + + if (!state) + return -EINVAL; + + if (asprintf(&p, "/run/systemd/users/%lu", (unsigned long) uid) < 0) + return -ENOMEM; + + r = parse_env_file(p, NEWLINE, "STATE", &s, NULL); + free(p); + + if (r == -ENOENT) { + free(s); + s = strdup("offline"); + if (!s) + return -ENOMEM; + + *state = s; + return 0; + } else if (r < 0) { + free(s); + return r; + } else if (!s) + return -EIO; + + *state = s; + return 0; +} + +_public_ int sd_uid_is_on_seat(uid_t uid, int require_active, const char *seat) { + char *p, *w, *t, *state, *s = NULL; + size_t l; + int r; + const char *variable; + + if (!seat) + return -EINVAL; + + variable = require_active ? "ACTIVE_UID" : "UIDS"; + + p = strappend("/run/systemd/seats/", seat); + if (!p) + return -ENOMEM; + + r = parse_env_file(p, NEWLINE, variable, &s, NULL); + free(p); + + if (r < 0) { + free(s); + return r; + } + + if (!s) + return -EIO; + + if (asprintf(&t, "%lu", (unsigned long) uid) < 0) { + free(s); + return -ENOMEM; + } + + FOREACH_WORD(w, l, s, state) { + if (strncmp(t, w, l) == 0) { + free(s); + free(t); + + return 1; + } + } + + free(s); + free(t); + + return 0; +} + +static int uid_get_array(uid_t uid, const char *variable, char ***array) { + char *p, *s = NULL; + char **a; + int r; + + if (asprintf(&p, "/run/systemd/users/%lu", (unsigned long) uid) < 0) + return -ENOMEM; + + r = parse_env_file(p, NEWLINE, + variable, &s, + NULL); + free(p); + + if (r < 0) { + free(s); + + if (r == -ENOENT) { + if (array) + *array = NULL; + return 0; + } + + return r; + } + + if (!s) { + if (array) + *array = NULL; + return 0; + } + + a = strv_split(s, " "); + free(s); + + if (!a) + return -ENOMEM; + + strv_uniq(a); + r = strv_length(a); + + if (array) + *array = a; + else + strv_free(a); + + return r; +} + +_public_ int sd_uid_get_sessions(uid_t uid, int require_active, char ***sessions) { + return uid_get_array( + uid, + require_active == 0 ? "ONLINE_SESSIONS" : + require_active > 0 ? "ACTIVE_SESSIONS" : + "SESSIONS", + sessions); +} + +_public_ int sd_uid_get_seats(uid_t uid, int require_active, char ***seats) { + return uid_get_array( + uid, + require_active == 0 ? "ONLINE_SEATS" : + require_active > 0 ? "ACTIVE_SEATS" : + "SEATS", + seats); +} + +static int file_of_session(const char *session, char **_p) { + char *p; + int r; + + assert(_p); + + if (session) + p = strappend("/run/systemd/sessions/", session); + else { + char *buf; + + r = sd_pid_get_session(0, &buf); + if (r < 0) + return r; + + p = strappend("/run/systemd/sessions/", buf); + free(buf); + } + + if (!p) + return -ENOMEM; + + *_p = p; + return 0; +} + +_public_ int sd_session_is_active(const char *session) { + int r; + char *p, *s = NULL; + + r = file_of_session(session, &p); + if (r < 0) + return r; + + r = parse_env_file(p, NEWLINE, "ACTIVE", &s, NULL); + free(p); + + if (r < 0) { + free(s); + return r; + } + + if (!s) + return -EIO; + + r = parse_boolean(s); + free(s); + + return r; +} + +_public_ int sd_session_get_state(const char *session, char **state) { + char *p, *s = NULL; + int r; + + if (!state) + return -EINVAL; + + r = file_of_session(session, &p); + if (r < 0) + return r; + + r = parse_env_file(p, NEWLINE, "STATE", &s, NULL); + free(p); + + if (r < 0) { + free(s); + return r; + } else if (!s) + return -EIO; + + *state = s; + return 0; +} + +_public_ int sd_session_get_uid(const char *session, uid_t *uid) { + int r; + char *p, *s = NULL; + + if (!uid) + return -EINVAL; + + r = file_of_session(session, &p); + if (r < 0) + return r; + + r = parse_env_file(p, NEWLINE, "UID", &s, NULL); + free(p); + + if (r < 0) { + free(s); + return r; + } + + if (!s) + return -EIO; + + r = parse_uid(s, uid); + free(s); + + return r; +} + +static int session_get_string(const char *session, const char *field, char **value) { + char *p, *s = NULL; + int r; + + if (!value) + return -EINVAL; + + r = file_of_session(session, &p); + if (r < 0) + return r; + + r = parse_env_file(p, NEWLINE, field, &s, NULL); + free(p); + + if (r < 0) { + free(s); + return r; + } + + if (isempty(s)) + return -ENOENT; + + *value = s; + return 0; +} + +_public_ int sd_session_get_seat(const char *session, char **seat) { + return session_get_string(session, "SEAT", seat); +} + +_public_ int sd_session_get_service(const char *session, char **service) { + return session_get_string(session, "SERVICE", service); +} + +_public_ int sd_session_get_type(const char *session, char **type) { + return session_get_string(session, "TYPE", type); +} + +_public_ int sd_session_get_class(const char *session, char **class) { + return session_get_string(session, "CLASS", class); +} + +_public_ int sd_session_get_display(const char *session, char **display) { + return session_get_string(session, "DISPLAY", display); +} + +static int file_of_seat(const char *seat, char **_p) { + char *p; + int r; + + assert(_p); + + if (seat) + p = strappend("/run/systemd/seats/", seat); + else { + char *buf; + + r = sd_session_get_seat(NULL, &buf); + if (r < 0) + return r; + + p = strappend("/run/systemd/seats/", buf); + free(buf); + } + + if (!p) + return -ENOMEM; + + *_p = p; + return 0; +} + +_public_ int sd_seat_get_active(const char *seat, char **session, uid_t *uid) { + char *p, *s = NULL, *t = NULL; + int r; + + if (!session && !uid) + return -EINVAL; + + r = file_of_seat(seat, &p); + if (r < 0) + return r; + + r = parse_env_file(p, NEWLINE, + "ACTIVE", &s, + "ACTIVE_UID", &t, + NULL); + free(p); + + if (r < 0) { + free(s); + free(t); + return r; + } + + if (session && !s) { + free(t); + return -ENOENT; + } + + if (uid && !t) { + free(s); + return -ENOENT; + } + + if (uid && t) { + r = parse_uid(t, uid); + if (r < 0) { + free(t); + free(s); + return r; + } + } + + free(t); + + if (session && s) + *session = s; + else + free(s); + + return 0; +} + +_public_ int sd_seat_get_sessions(const char *seat, char ***sessions, uid_t **uids, unsigned *n_uids) { + char *p, *s = NULL, *t = NULL, **a = NULL; + uid_t *b = NULL; + unsigned n = 0; + int r; + + r = file_of_seat(seat, &p); + if (r < 0) + return r; + + r = parse_env_file(p, NEWLINE, + "SESSIONS", &s, + "ACTIVE_SESSIONS", &t, + NULL); + free(p); + + if (r < 0) { + free(s); + free(t); + return r; + } + + if (s) { + a = strv_split(s, " "); + if (!a) { + free(s); + free(t); + return -ENOMEM; + } + } + + free(s); + + if (uids && t) { + char *w, *state; + size_t l; + + FOREACH_WORD(w, l, t, state) + n++; + + if (n == 0) + b = NULL; + else { + unsigned i = 0; + + b = new(uid_t, n); + if (!b) { + strv_free(a); + return -ENOMEM; + } + + FOREACH_WORD(w, l, t, state) { + char *k; + + k = strndup(w, l); + if (!k) { + free(t); + free(b); + strv_free(a); + return -ENOMEM; + } + + r = parse_uid(k, b + i); + free(k); + if (r < 0) + continue; + + i++; + } + } + } + + free(t); + + r = strv_length(a); + + if (sessions) + *sessions = a; + else + strv_free(a); + + if (uids) + *uids = b; + + if (n_uids) + *n_uids = n; + + return r; +} + +static int seat_get_can(const char *seat, const char *variable) { + char *p, *s = NULL; + int r; + + r = file_of_seat(seat, &p); + if (r < 0) + return r; + + r = parse_env_file(p, NEWLINE, + variable, &s, + NULL); + free(p); + + if (r < 0) { + free(s); + return r; + } + + if (s) { + r = parse_boolean(s); + free(s); + } else + r = 0; + + return r; +} + +_public_ int sd_seat_can_multi_session(const char *seat) { + return seat_get_can(seat, "CAN_MULTI_SESSION"); +} + +_public_ int sd_seat_can_tty(const char *seat) { + return seat_get_can(seat, "CAN_TTY"); +} + +_public_ int sd_seat_can_graphical(const char *seat) { + return seat_get_can(seat, "CAN_GRAPHICAL"); +} + +_public_ int sd_get_seats(char ***seats) { + return get_files_in_directory("/run/systemd/seats/", seats); +} + +_public_ int sd_get_sessions(char ***sessions) { + return get_files_in_directory("/run/systemd/sessions/", sessions); +} + +_public_ int sd_get_uids(uid_t **users) { + DIR *d; + int r = 0; + unsigned n = 0; + uid_t *l = NULL; + + d = opendir("/run/systemd/users/"); + if (!d) + return -errno; + + for (;;) { + struct dirent *de; + union dirent_storage buf; + int k; + uid_t uid; + + k = readdir_r(d, &buf.de, &de); + if (k != 0) { + r = -k; + goto finish; + } + + if (!de) + break; + + dirent_ensure_type(d, de); + + if (!dirent_is_file(de)) + continue; + + k = parse_uid(de->d_name, &uid); + if (k < 0) + continue; + + if (users) { + if ((unsigned) r >= n) { + uid_t *t; + + n = MAX(16, 2*r); + t = realloc(l, sizeof(uid_t) * n); + if (!t) { + r = -ENOMEM; + goto finish; + } + + l = t; + } + + assert((unsigned) r < n); + l[r++] = uid; + } else + r++; + } + +finish: + if (d) + closedir(d); + + if (r >= 0) { + if (users) + *users = l; + } else + free(l); + + return r; +} + +static inline int MONITOR_TO_FD(sd_login_monitor *m) { + return (int) (unsigned long) m - 1; +} + +static inline sd_login_monitor* FD_TO_MONITOR(int fd) { + return (sd_login_monitor*) (unsigned long) (fd + 1); +} + +_public_ int sd_login_monitor_new(const char *category, sd_login_monitor **m) { + int fd, k; + bool good = false; + + if (!m) + return -EINVAL; + + fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC); + if (fd < 0) + return errno; + + if (!category || streq(category, "seat")) { + k = inotify_add_watch(fd, "/run/systemd/seats/", IN_MOVED_TO|IN_DELETE); + if (k < 0) { + close_nointr_nofail(fd); + return -errno; + } + + good = true; + } + + if (!category || streq(category, "session")) { + k = inotify_add_watch(fd, "/run/systemd/sessions/", IN_MOVED_TO|IN_DELETE); + if (k < 0) { + close_nointr_nofail(fd); + return -errno; + } + + good = true; + } + + if (!category || streq(category, "uid")) { + k = inotify_add_watch(fd, "/run/systemd/users/", IN_MOVED_TO|IN_DELETE); + if (k < 0) { + close_nointr_nofail(fd); + return -errno; + } + + good = true; + } + + if (!good) { + close_nointr(fd); + return -EINVAL; + } + + *m = FD_TO_MONITOR(fd); + return 0; +} + +_public_ sd_login_monitor* sd_login_monitor_unref(sd_login_monitor *m) { + int fd; + + if (!m) + return NULL; + + fd = MONITOR_TO_FD(m); + close_nointr(fd); + + return NULL; +} + +_public_ int sd_login_monitor_flush(sd_login_monitor *m) { + + if (!m) + return -EINVAL; + + return flush_fd(MONITOR_TO_FD(m)); +} + +_public_ int sd_login_monitor_get_fd(sd_login_monitor *m) { + + if (!m) + return -EINVAL; + + return MONITOR_TO_FD(m); +} diff --git a/src/login/sysfs-show.c b/src/login/sysfs-show.c new file mode 100644 index 000000000..d113ec3e4 --- /dev/null +++ b/src/login/sysfs-show.c @@ -0,0 +1,190 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include + +#include "util.h" +#include "sysfs-show.h" +#include "path-util.h" + +static int show_sysfs_one( + struct udev *udev, + const char *seat, + struct udev_list_entry **item, + const char *sub, + const char *prefix, + unsigned n_columns) { + + assert(udev); + assert(seat); + assert(item); + assert(prefix); + + while (*item) { + struct udev_list_entry *next, *lookahead; + struct udev_device *d; + const char *sn, *name, *sysfs, *subsystem, *sysname; + char *l, *k; + + sysfs = udev_list_entry_get_name(*item); + if (!path_startswith(sysfs, sub)) + return 0; + + d = udev_device_new_from_syspath(udev, sysfs); + if (!d) { + *item = udev_list_entry_get_next(*item); + continue; + } + + sn = udev_device_get_property_value(d, "ID_SEAT"); + if (isempty(sn)) + sn = "seat0"; + + /* fixme, also check for tag 'seat' here */ + if (!streq(seat, sn) || !udev_device_has_tag(d, "seat")) { + udev_device_unref(d); + *item = udev_list_entry_get_next(*item); + continue; + } + + name = udev_device_get_sysattr_value(d, "name"); + if (!name) + name = udev_device_get_sysattr_value(d, "id"); + subsystem = udev_device_get_subsystem(d); + sysname = udev_device_get_sysname(d); + + /* Look if there's more coming after this */ + lookahead = next = udev_list_entry_get_next(*item); + while (lookahead) { + const char *lookahead_sysfs; + + lookahead_sysfs = udev_list_entry_get_name(lookahead); + + if (path_startswith(lookahead_sysfs, sub) && + !path_startswith(lookahead_sysfs, sysfs)) { + struct udev_device *lookahead_d; + + lookahead_d = udev_device_new_from_syspath(udev, lookahead_sysfs); + if (lookahead_d) { + const char *lookahead_sn; + bool found; + + lookahead_sn = udev_device_get_property_value(d, "ID_SEAT"); + if (isempty(lookahead_sn)) + lookahead_sn = "seat0"; + + found = streq(seat, lookahead_sn) && udev_device_has_tag(lookahead_d, "seat"); + udev_device_unref(lookahead_d); + + if (found) + break; + } + } + + lookahead = udev_list_entry_get_next(lookahead); + } + + k = ellipsize(sysfs, n_columns, 20); + printf("%s%s%s\n", prefix, draw_special_char(lookahead ? DRAW_TREE_BRANCH : DRAW_TREE_RIGHT), + k ? k : sysfs); + free(k); + + if (asprintf(&l, + "(%s:%s)%s%s%s", + subsystem, sysname, + name ? " \"" : "", name ? name : "", name ? "\"" : "") < 0) { + udev_device_unref(d); + return -ENOMEM; + } + + k = ellipsize(l, n_columns, 70); + printf("%s%s%s\n", prefix, lookahead ? draw_special_char(DRAW_TREE_VERT) : " ", + k ? k : l); + free(k); + free(l); + + *item = next; + if (*item) { + char *p; + + p = strappend(prefix, lookahead ? draw_special_char(DRAW_TREE_VERT) : " "); + show_sysfs_one(udev, seat, item, sysfs, p ? p : prefix, n_columns - 2); + free(p); + } + + udev_device_unref(d); + } + + return 0; +} + +int show_sysfs(const char *seat, const char *prefix, unsigned n_columns) { + struct udev *udev; + struct udev_list_entry *first = NULL; + struct udev_enumerate *e; + int r; + + if (n_columns <= 0) + n_columns = columns(); + + if (!prefix) + prefix = ""; + + if (isempty(seat)) + seat = "seat0"; + + udev = udev_new(); + if (!udev) + return -ENOMEM; + + e = udev_enumerate_new(udev); + if (!e) { + r = -ENOMEM; + goto finish; + } + + if (!streq(seat, "seat0")) + r = udev_enumerate_add_match_tag(e, seat); + else + r = udev_enumerate_add_match_tag(e, "seat"); + + if (r < 0) + goto finish; + + r = udev_enumerate_scan_devices(e); + if (r < 0) + goto finish; + + first = udev_enumerate_get_list_entry(e); + if (first) + show_sysfs_one(udev, seat, &first, "/", prefix, n_columns); + +finish: + if (e) + udev_enumerate_unref(e); + + if (udev) + udev_unref(udev); + + return r; +} diff --git a/src/login/test-inhibit.c b/src/login/test-inhibit.c new file mode 100644 index 000000000..7b6deffc3 --- /dev/null +++ b/src/login/test-inhibit.c @@ -0,0 +1,139 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + +#include + +#include + +#include "macro.h" +#include "util.h" +#include "dbus-common.h" + +static int inhibit(DBusConnection *bus, const char *what) { + DBusMessage *m, *reply; + DBusError error; + const char *who = "Test Tool", *reason = "Just because!", *mode = "block"; + int fd; + + dbus_error_init(&error); + + m = dbus_message_new_method_call( + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + "Inhibit"); + assert(m); + + assert_se(dbus_message_append_args(m, + DBUS_TYPE_STRING, &what, + DBUS_TYPE_STRING, &who, + DBUS_TYPE_STRING, &reason, + DBUS_TYPE_STRING, &mode, + DBUS_TYPE_INVALID)); + + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error); + assert(reply); + + assert(dbus_message_get_args(reply, &error, + DBUS_TYPE_UNIX_FD, &fd, + DBUS_TYPE_INVALID)); + + dbus_message_unref(m); + dbus_message_unref(reply); + + return fd; +} + +static void print_inhibitors(DBusConnection *bus) { + DBusMessage *m, *reply; + DBusError error; + unsigned n = 0; + DBusMessageIter iter, sub, sub2; + + dbus_error_init(&error); + + m = dbus_message_new_method_call( + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + "ListInhibitors"); + assert(m); + + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error); + assert(reply); + + assert(dbus_message_iter_init(reply, &iter)); + dbus_message_iter_recurse(&iter, &sub); + + while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { + const char *what, *who, *why, *mode; + dbus_uint32_t uid, pid; + + dbus_message_iter_recurse(&sub, &sub2); + + assert_se(bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &what, true) >= 0); + assert_se(bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &who, true) >= 0); + assert_se(bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &why, true) >= 0); + assert_se(bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &mode, true) >= 0); + assert_se(bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT32, &uid, true) >= 0); + assert_se(bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT32, &pid, false) >= 0); + + printf("what=<%s> who=<%s> why=<%s> mode=<%s> uid=<%lu> pid=<%lu>\n", + what, who, why, mode, (unsigned long) uid, (unsigned long) pid); + + dbus_message_iter_next(&sub); + + n++; + } + + printf("%u inhibitors\n", n); + + dbus_message_unref(m); + dbus_message_unref(reply); +} + +int main(int argc, char*argv[]) { + DBusConnection *bus; + int fd1, fd2; + + bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, NULL); + assert(bus); + + print_inhibitors(bus); + + fd1 = inhibit(bus, "sleep"); + assert(fd1 >= 0); + print_inhibitors(bus); + + fd2 = inhibit(bus, "idle:shutdown"); + assert(fd2 >= 0); + print_inhibitors(bus); + + close_nointr_nofail(fd1); + sleep(1); + print_inhibitors(bus); + + close_nointr_nofail(fd2); + sleep(1); + print_inhibitors(bus); + + return 0; +} diff --git a/src/login/test-login.c b/src/login/test-login.c new file mode 100644 index 000000000..159ff3efc --- /dev/null +++ b/src/login/test-login.c @@ -0,0 +1,201 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +#include +#include + +#include + +#include "util.h" +#include "strv.h" + +int main(int argc, char* argv[]) { + int r, k; + uid_t u, u2; + char *seat, *type, *class, *display; + char *session; + char *state; + char *session2; + char *t; + char **seats, **sessions; + uid_t *uids; + unsigned n; + struct pollfd pollfd; + sd_login_monitor *m; + + assert_se(sd_pid_get_session(0, &session) == 0); + printf("session = %s\n", session); + + assert_se(sd_pid_get_owner_uid(0, &u2) == 0); + printf("user = %lu\n", (unsigned long) u2); + + r = sd_uid_get_sessions(u2, false, &sessions); + assert_se(r >= 0); + assert_se(r == (int) strv_length(sessions)); + assert_se(t = strv_join(sessions, ", ")); + strv_free(sessions); + printf("sessions = %s\n", t); + free(t); + + assert_se(r == sd_uid_get_sessions(u2, false, NULL)); + + r = sd_uid_get_seats(u2, false, &seats); + assert_se(r >= 0); + assert_se(r == (int) strv_length(seats)); + assert_se(t = strv_join(seats, ", ")); + strv_free(seats); + printf("seats = %s\n", t); + free(t); + + assert_se(r == sd_uid_get_seats(u2, false, NULL)); + + r = sd_session_is_active(session); + assert_se(r >= 0); + printf("active = %s\n", yes_no(r)); + + r = sd_session_get_state(session, &state); + assert_se(r >= 0); + printf("state = %s\n", state); + free(state); + + assert_se(sd_session_get_uid(session, &u) >= 0); + printf("uid = %lu\n", (unsigned long) u); + assert_se(u == u2); + + assert_se(sd_session_get_type(session, &type) >= 0); + printf("type = %s\n", type); + free(type); + + assert_se(sd_session_get_class(session, &class) >= 0); + printf("class = %s\n", class); + free(class); + + assert_se(sd_session_get_display(session, &display) >= 0); + printf("display = %s\n", display); + free(display); + + assert_se(sd_session_get_seat(session, &seat) >= 0); + printf("seat = %s\n", seat); + + r = sd_seat_can_multi_session(seat); + assert_se(r >= 0); + printf("can do multi session = %s\n", yes_no(r)); + + r = sd_seat_can_tty(seat); + assert_se(r >= 0); + printf("can do tty = %s\n", yes_no(r)); + + r = sd_seat_can_graphical(seat); + assert_se(r >= 0); + printf("can do graphical = %s\n", yes_no(r)); + + assert_se(sd_uid_get_state(u, &state) >= 0); + printf("state = %s\n", state); + + assert_se(sd_uid_is_on_seat(u, 0, seat) > 0); + + k = sd_uid_is_on_seat(u, 1, seat); + assert_se(k >= 0); + assert_se(!!r == !!r); + + assert_se(sd_seat_get_active(seat, &session2, &u2) >= 0); + printf("session2 = %s\n", session2); + printf("uid2 = %lu\n", (unsigned long) u2); + + r = sd_seat_get_sessions(seat, &sessions, &uids, &n); + assert_se(r >= 0); + printf("n_sessions = %i\n", r); + assert_se(r == (int) strv_length(sessions)); + assert_se(t = strv_join(sessions, ", ")); + strv_free(sessions); + printf("sessions = %s\n", t); + free(t); + printf("uids ="); + for (k = 0; k < (int) n; k++) + printf(" %lu", (unsigned long) uids[k]); + printf("\n"); + free(uids); + + assert_se(sd_seat_get_sessions(seat, NULL, NULL, NULL) == r); + + free(session); + free(state); + free(session2); + free(seat); + + r = sd_get_seats(&seats); + assert_se(r >= 0); + assert_se(r == (int) strv_length(seats)); + assert_se(t = strv_join(seats, ", ")); + strv_free(seats); + printf("n_seats = %i\n", r); + printf("seats = %s\n", t); + free(t); + + assert_se(sd_get_seats(NULL) == r); + + r = sd_seat_get_active(NULL, &t, NULL); + assert_se(r >= 0); + printf("active session on current seat = %s\n", t); + free(t); + + r = sd_get_sessions(&sessions); + assert_se(r >= 0); + assert_se(r == (int) strv_length(sessions)); + assert_se(t = strv_join(sessions, ", ")); + strv_free(sessions); + printf("n_sessions = %i\n", r); + printf("sessions = %s\n", t); + free(t); + + assert_se(sd_get_sessions(NULL) == r); + + r = sd_get_uids(&uids); + assert_se(r >= 0); + + printf("uids ="); + for (k = 0; k < r; k++) + printf(" %lu", (unsigned long) uids[k]); + printf("\n"); + free(uids); + + printf("n_uids = %i\n", r); + assert_se(sd_get_uids(NULL) == r); + + r = sd_login_monitor_new("session", &m); + assert_se(r >= 0); + + zero(pollfd); + pollfd.fd = sd_login_monitor_get_fd(m); + pollfd.events = POLLIN; + + for (n = 0; n < 5; n++) { + r = poll(&pollfd, 1, -1); + assert_se(r >= 0); + + sd_login_monitor_flush(m); + printf("Wake!\n"); + } + + sd_login_monitor_unref(m); + + return 0; +} diff --git a/src/login/uaccess.c b/src/login/uaccess.c new file mode 100644 index 000000000..2c530c8f3 --- /dev/null +++ b/src/login/uaccess.c @@ -0,0 +1,91 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +#include +#include + +#include +#include + +#include "logind-acl.h" +#include "util.h" +#include "log.h" + +int main(int argc, char *argv[]) { + int r; + const char *path = NULL, *seat; + bool changed_acl = false; + uid_t uid; + + log_set_target(LOG_TARGET_AUTO); + log_parse_environment(); + log_open(); + + umask(0022); + + if (argc < 2 || argc > 3) { + log_error("This program expects one or two arguments."); + r = -EINVAL; + goto finish; + } + + /* Make sure we don't muck around with ACLs the system is not + * running systemd. */ + if (!sd_booted()) + return 0; + + path = argv[1]; + seat = argc < 3 || isempty(argv[2]) ? "seat0" : argv[2]; + + r = sd_seat_get_active(seat, NULL, &uid); + if (r == -ENOENT) { + /* No active session on this seat */ + r = 0; + goto finish; + } else if (r < 0) { + log_error("Failed to determine active user on seat %s.", seat); + goto finish; + } + + r = devnode_acl(path, true, false, 0, true, uid); + if (r < 0) { + log_error("Failed to apply ACL on %s: %s", path, strerror(-r)); + goto finish; + } + + changed_acl = true; + r = 0; + +finish: + if (path && !changed_acl) { + int k; + /* Better be safe that sorry and reset ACL */ + + k = devnode_acl(path, true, false, 0, false, 0); + if (k < 0) { + log_error("Failed to apply ACL on %s: %s", path, strerror(-k)); + if (r >= 0) + r = k; + } + } + + return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/src/login/user-sessions.c b/src/login/user-sessions.c new file mode 100644 index 000000000..91531e8f3 --- /dev/null +++ b/src/login/user-sessions.c @@ -0,0 +1,101 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include + +#include "log.h" +#include "util.h" +#include "cgroup-util.h" + +int main(int argc, char*argv[]) { + int ret = EXIT_FAILURE; + + if (argc != 2) { + log_error("This program requires one argument."); + return EXIT_FAILURE; + } + + log_set_target(LOG_TARGET_AUTO); + log_parse_environment(); + log_open(); + + umask(0022); + + if (streq(argv[1], "start")) { + int q = 0, r = 0; + + if (unlink("/run/nologin") < 0 && errno != ENOENT) { + log_error("Failed to remove /run/nologin file: %m"); + r = -errno; + } + + if (unlink("/etc/nologin") < 0 && errno != ENOENT) { + + /* If the file doesn't exist and /etc simply + * was read-only (in which case unlink() + * returns EROFS even if the file doesn't + * exist), don't complain */ + + if (errno != EROFS || access("/etc/nologin", F_OK) >= 0) { + log_error("Failed to remove /etc/nologin file: %m"); + q = -errno; + } + } + + if (r < 0 || q < 0) + goto finish; + + } else if (streq(argv[1], "stop")) { + int r, q; + char *cgroup_user_tree = NULL; + + r = write_one_line_file_atomic("/run/nologin", "System is going down."); + if (r < 0) + log_error("Failed to create /run/nologin: %s", strerror(-r)); + + q = cg_get_user_path(&cgroup_user_tree); + if (q < 0) { + log_error("Failed to determine use path: %s", strerror(-q)); + goto finish; + } + + q = cg_kill_recursive_and_wait(SYSTEMD_CGROUP_CONTROLLER, cgroup_user_tree, true); + free(cgroup_user_tree); + if (q < 0) { + log_error("Failed to kill sessions: %s", strerror(-q)); + goto finish; + } + + if (r < 0) + goto finish; + + } else { + log_error("Unknown verb %s.", argv[1]); + goto finish; + } + + ret = EXIT_SUCCESS; + +finish: + return ret; +} diff --git a/src/machine-id-setup/Makefile b/src/machine-id-setup/Makefile new file mode 120000 index 000000000..d0b0e8e00 --- /dev/null +++ b/src/machine-id-setup/Makefile @@ -0,0 +1 @@ +../Makefile \ No newline at end of file diff --git a/src/machine-id-setup/machine-id-setup-main.c b/src/machine-id-setup/machine-id-setup-main.c new file mode 100644 index 000000000..eb2d51485 --- /dev/null +++ b/src/machine-id-setup/machine-id-setup-main.c @@ -0,0 +1,101 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include +#include + +#include "machine-id-setup.h" +#include "log.h" +#include "build.h" + +static int help(void) { + + printf("%s [OPTIONS...]\n\n" + "Initialize /etc/machine-id from a random source.\n\n" + " -h --help Show this help\n" + " --version Show package version\n", + program_invocation_short_name); + + return 0; +} + +static int parse_argv(int argc, char *argv[]) { + + enum { + ARG_VERSION = 0x100 + }; + + static const struct option options[] = { + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, ARG_VERSION }, + { NULL, 0, NULL, 0 } + }; + + int c; + + assert(argc >= 0); + assert(argv); + + while ((c = getopt_long(argc, argv, "hqcv", options, NULL)) >= 0) { + + switch (c) { + + case 'h': + help(); + return 0; + + case ARG_VERSION: + puts(PACKAGE_STRING); + puts(SYSTEMD_FEATURES); + return 0; + + case '?': + return -EINVAL; + + default: + log_error("Unknown option code %c", c); + return -EINVAL; + } + } + + if (optind < argc) { + help(); + return -EINVAL; + } + + return 1; +} + +int main(int argc, char *argv[]) { + int r; + + log_parse_environment(); + log_open(); + + r = parse_argv(argc, argv); + if (r <= 0) + return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; + + return machine_id_setup() < 0 ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/src/modules-load/Makefile b/src/modules-load/Makefile new file mode 120000 index 000000000..d0b0e8e00 --- /dev/null +++ b/src/modules-load/Makefile @@ -0,0 +1 @@ +../Makefile \ No newline at end of file diff --git a/src/modules-load/modules-load.c b/src/modules-load/modules-load.c new file mode 100644 index 000000000..f6279e197 --- /dev/null +++ b/src/modules-load/modules-load.c @@ -0,0 +1,259 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "log.h" +#include "util.h" +#include "strv.h" +#include "conf-files.h" +#include "virt.h" + +static char **arg_proc_cmdline_modules = NULL; + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wformat-nonliteral" +static void systemd_kmod_log(void *data, int priority, const char *file, int line, + const char *fn, const char *format, va_list args) +{ + log_metav(priority, file, line, fn, format, args); +} +#pragma GCC diagnostic pop + +static int add_modules(const char *p) { + char **t, **k; + + k = strv_split(p, ","); + if (!k) + return log_oom(); + + t = strv_merge(arg_proc_cmdline_modules, k); + strv_free(k); + if (!t) + return log_oom(); + + strv_free(arg_proc_cmdline_modules); + arg_proc_cmdline_modules = t; + + return 0; +} + +static int parse_proc_cmdline(void) { + char _cleanup_free_ *line = NULL; + char *w, *state; + int r; + size_t l; + + if (detect_container(NULL) > 0) + return 0; + + r = read_one_line_file("/proc/cmdline", &line); + if (r < 0) { + log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r)); + return 0; + } + + FOREACH_WORD_QUOTED(w, l, line, state) { + char _cleanup_free_ *word; + + word = strndup(w, l); + if (!word) + return log_oom(); + + if (startswith(word, "modules-load=")) { + + r = add_modules(word + 13); + if (r < 0) + return r; + + } else if (startswith(word, "rd.modules-load=")) { + + if (in_initrd()) { + r = add_modules(word + 16); + if (r < 0) + return r; + } + + } + } + + return 0; +} + +static int load_module(struct kmod_ctx *ctx, const char *m) { + const int probe_flags = KMOD_PROBE_APPLY_BLACKLIST; + struct kmod_list *itr, *modlist = NULL; + int r = 0; + + log_debug("load: %s\n", m); + + r = kmod_module_new_from_lookup(ctx, m, &modlist); + if (r < 0) { + log_error("Failed to lookup alias '%s': %s", m, strerror(-r)); + return r; + } + + if (!modlist) { + log_error("Failed to find module '%s'", m); + return -ENOENT; + } + + kmod_list_foreach(itr, modlist) { + struct kmod_module *mod; + int state, err; + + mod = kmod_module_get_module(itr); + state = kmod_module_get_initstate(mod); + + switch (state) { + case KMOD_MODULE_BUILTIN: + log_info("Module '%s' is builtin", kmod_module_get_name(mod)); + break; + + case KMOD_MODULE_LIVE: + log_info("Module '%s' is already loaded", kmod_module_get_name(mod)); + break; + + default: + err = kmod_module_probe_insert_module(mod, probe_flags, + NULL, NULL, NULL, NULL); + + if (err == 0) + log_info("Inserted module '%s'", kmod_module_get_name(mod)); + else if (err == KMOD_PROBE_APPLY_BLACKLIST) + log_info("Module '%s' is blacklisted", kmod_module_get_name(mod)); + else { + log_error("Failed to insert '%s': %s", kmod_module_get_name(mod), + strerror(-err)); + r = err; + } + } + + kmod_module_unref(mod); + } + + kmod_module_unref_list(modlist); + + return r; +} + +int main(int argc, char *argv[]) { + int r = EXIT_FAILURE, k; + char **files = NULL, **fn, **i; + struct kmod_ctx *ctx; + + if (argc > 1) { + log_error("This program takes no argument."); + return EXIT_FAILURE; + } + + log_set_target(LOG_TARGET_AUTO); + log_parse_environment(); + log_open(); + + umask(0022); + + if (parse_proc_cmdline() < 0) + return EXIT_FAILURE; + + ctx = kmod_new(NULL, NULL); + if (!ctx) { + log_error("Failed to allocate memory for kmod."); + goto finish; + } + + kmod_load_resources(ctx); + kmod_set_log_fn(ctx, systemd_kmod_log, NULL); + + r = EXIT_SUCCESS; + + STRV_FOREACH(i, arg_proc_cmdline_modules) { + k = load_module(ctx, *i); + if (k < 0) + r = EXIT_FAILURE; + } + + k = conf_files_list(&files, ".conf", + "/etc/modules-load.d", + "/run/modules-load.d", + "/usr/local/lib/modules-load.d", + "/usr/lib/modules-load.d", +#ifdef HAVE_SPLIT_USR + "/lib/modules-load.d", +#endif + NULL); + if (k < 0) { + log_error("Failed to enumerate modules-load.d files: %s", strerror(-k)); + r = EXIT_FAILURE; + goto finish; + } + + STRV_FOREACH(fn, files) { + FILE *f; + + f = fopen(*fn, "re"); + if (!f) { + if (errno == ENOENT) + continue; + + log_error("Failed to open %s: %m", *fn); + r = EXIT_FAILURE; + continue; + } + + log_debug("apply: %s\n", *fn); + for (;;) { + char line[LINE_MAX], *l; + + if (!fgets(line, sizeof(line), f)) + break; + + l = strstrip(line); + if (*l == '#' || *l == 0) + continue; + + k = load_module(ctx, l); + if (k < 0) + r = EXIT_FAILURE; + } + + if (ferror(f)) { + log_error("Failed to read from file: %m"); + r = EXIT_FAILURE; + } + + fclose(f); + } + +finish: + strv_free(files); + kmod_unref(ctx); + strv_free(arg_proc_cmdline_modules); + + return r; +} diff --git a/src/notify/Makefile b/src/notify/Makefile new file mode 120000 index 000000000..d0b0e8e00 --- /dev/null +++ b/src/notify/Makefile @@ -0,0 +1 @@ +../Makefile \ No newline at end of file diff --git a/src/notify/notify.c b/src/notify/notify.c new file mode 100644 index 000000000..f521f5665 --- /dev/null +++ b/src/notify/notify.c @@ -0,0 +1,227 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "strv.h" +#include "util.h" +#include "log.h" +#include "sd-readahead.h" +#include "build.h" + +static bool arg_ready = false; +static pid_t arg_pid = 0; +static const char *arg_status = NULL; +static bool arg_booted = false; +static const char *arg_readahead = NULL; + +static int help(void) { + + printf("%s [OPTIONS...] [VARIABLE=VALUE...]\n\n" + "Notify the init system about service status updates.\n\n" + " -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" + " --status=TEXT Set status text\n" + " --booted Returns 0 if the system was booted up with systemd, non-zero otherwise\n" + " --readahead=ACTION Controls read-ahead operations\n", + program_invocation_short_name); + + return 0; +} + +static int parse_argv(int argc, char *argv[]) { + + enum { + ARG_READY = 0x100, + ARG_VERSION, + ARG_PID, + ARG_STATUS, + ARG_BOOTED, + ARG_READAHEAD + }; + + static const struct option options[] = { + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, ARG_VERSION }, + { "ready", no_argument, NULL, ARG_READY }, + { "pid", optional_argument, NULL, ARG_PID }, + { "status", required_argument, NULL, ARG_STATUS }, + { "booted", no_argument, NULL, ARG_BOOTED }, + { "readahead", required_argument, NULL, ARG_READAHEAD }, + { NULL, 0, NULL, 0 } + }; + + int c; + + assert(argc >= 0); + assert(argv); + + while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) { + + switch (c) { + + case 'h': + help(); + return 0; + + case ARG_VERSION: + puts(PACKAGE_STRING); + puts(SYSTEMD_FEATURES); + return 0; + + case ARG_READY: + arg_ready = true; + break; + + case ARG_PID: + + if (optarg) { + if (parse_pid(optarg, &arg_pid) < 0) { + log_error("Failed to parse PID %s.", optarg); + return -EINVAL; + } + } else + arg_pid = getppid(); + + break; + + case ARG_STATUS: + arg_status = optarg; + break; + + case ARG_BOOTED: + arg_booted = true; + break; + + case ARG_READAHEAD: + arg_readahead = optarg; + break; + + case '?': + return -EINVAL; + + default: + log_error("Unknown option code %c", c); + return -EINVAL; + } + } + + if (optind >= argc && + !arg_ready && + !arg_status && + !arg_pid && + !arg_booted && + !arg_readahead) { + help(); + return -EINVAL; + } + + return 1; +} + +int main(int argc, char* argv[]) { + char* our_env[4], **final_env = NULL; + unsigned i = 0; + char *status = NULL, *cpid = NULL, *n = NULL; + int r, retval = EXIT_FAILURE; + + log_parse_environment(); + log_open(); + + if ((r = parse_argv(argc, argv)) <= 0) { + retval = r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; + goto finish; + } + + if (arg_booted) + return sd_booted() <= 0; + + if (arg_readahead) { + if ((r = sd_readahead(arg_readahead)) < 0) { + log_error("Failed to issue read-ahead control command: %s", strerror(-r)); + goto finish; + } + } + + if (arg_ready) + our_env[i++] = (char*) "READY=1"; + + if (arg_status) { + if (!(status = strappend("STATUS=", arg_status))) { + log_error("Failed to allocate STATUS string."); + goto finish; + } + + our_env[i++] = status; + } + + if (arg_pid > 0) { + if (asprintf(&cpid, "MAINPID=%lu", (unsigned long) arg_pid) < 0) { + log_error("Failed to allocate MAINPID string."); + goto finish; + } + + our_env[i++] = cpid; + } + + our_env[i++] = NULL; + + if (!(final_env = strv_env_merge(2, our_env, argv + optind))) { + log_error("Failed to merge string sets."); + goto finish; + } + + if (strv_length(final_env) <= 0) { + retval = EXIT_SUCCESS; + goto finish; + } + + if (!(n = strv_join(final_env, "\n"))) { + log_error("Failed to concatenate strings."); + goto finish; + } + + if ((r = sd_notify(false, n)) < 0) { + log_error("Failed to notify init system: %s", strerror(-r)); + goto finish; + } + + retval = r <= 0 ? EXIT_FAILURE : EXIT_SUCCESS; + +finish: + free(status); + free(cpid); + free(n); + + strv_free(final_env); + + return retval; +} diff --git a/src/nspawn/Makefile b/src/nspawn/Makefile new file mode 120000 index 000000000..d0b0e8e00 --- /dev/null +++ b/src/nspawn/Makefile @@ -0,0 +1 @@ +../Makefile \ No newline at end of file diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c new file mode 100644 index 000000000..1f3bda5b4 --- /dev/null +++ b/src/nspawn/nspawn.c @@ -0,0 +1,1533 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "log.h" +#include "util.h" +#include "mkdir.h" +#include "macro.h" +#include "audit.h" +#include "missing.h" +#include "cgroup-util.h" +#include "strv.h" +#include "path-util.h" +#include "loopback-setup.h" +#include "sd-id128.h" +#include "dev-setup.h" +#include "fdset.h" + +typedef enum LinkJournal { + LINK_NO, + LINK_AUTO, + LINK_HOST, + LINK_GUEST +} LinkJournal; + +static char *arg_directory = NULL; +static char *arg_user = NULL; +static char **arg_controllers = NULL; +static char *arg_uuid = NULL; +static bool arg_private_network = false; +static bool arg_read_only = false; +static bool arg_boot = false; +static LinkJournal arg_link_journal = LINK_AUTO; +static uint64_t arg_retain = + (1ULL << CAP_CHOWN) | + (1ULL << CAP_DAC_OVERRIDE) | + (1ULL << CAP_DAC_READ_SEARCH) | + (1ULL << CAP_FOWNER) | + (1ULL << CAP_FSETID) | + (1ULL << CAP_IPC_OWNER) | + (1ULL << CAP_KILL) | + (1ULL << CAP_LEASE) | + (1ULL << CAP_LINUX_IMMUTABLE) | + (1ULL << CAP_NET_BIND_SERVICE) | + (1ULL << CAP_NET_BROADCAST) | + (1ULL << CAP_NET_RAW) | + (1ULL << CAP_SETGID) | + (1ULL << CAP_SETFCAP) | + (1ULL << CAP_SETPCAP) | + (1ULL << CAP_SETUID) | + (1ULL << CAP_SYS_ADMIN) | + (1ULL << CAP_SYS_CHROOT) | + (1ULL << CAP_SYS_NICE) | + (1ULL << CAP_SYS_PTRACE) | + (1ULL << CAP_SYS_TTY_CONFIG) | + (1ULL << CAP_SYS_RESOURCE) | + (1ULL << CAP_SYS_BOOT); + +static int help(void) { + + printf("%s [OPTIONS...] [PATH] [ARGUMENTS...]\n\n" + "Spawn a minimal namespace container for debugging, testing and building.\n\n" + " -h --help Show this help\n" + " -D --directory=NAME Root directory for the container\n" + " -b --boot Boot up full system (i.e. invoke init)\n" + " -u --user=USER Run the command under specified user or uid\n" + " -C --controllers=LIST Put the container in specified comma-separated cgroup hierarchies\n" + " --uuid=UUID Set a specific machine UUID for the container\n" + " --private-network Disable network in container\n" + " --read-only Mount the root directory read-only\n" + " --capability=CAP In addition to the default, retain specified capability\n" + " --link-journal=MODE Link up guest journal, one of no, auto, guest, host\n" + " -j Equivalent to --link-journal=host\n", + program_invocation_short_name); + + return 0; +} + +static int parse_argv(int argc, char *argv[]) { + + enum { + ARG_PRIVATE_NETWORK = 0x100, + ARG_UUID, + ARG_READ_ONLY, + ARG_CAPABILITY, + ARG_LINK_JOURNAL + }; + + static const struct option options[] = { + { "help", no_argument, NULL, 'h' }, + { "directory", required_argument, NULL, 'D' }, + { "user", required_argument, NULL, 'u' }, + { "controllers", required_argument, NULL, 'C' }, + { "private-network", no_argument, NULL, ARG_PRIVATE_NETWORK }, + { "boot", no_argument, NULL, 'b' }, + { "uuid", required_argument, NULL, ARG_UUID }, + { "read-only", no_argument, NULL, ARG_READ_ONLY }, + { "capability", required_argument, NULL, ARG_CAPABILITY }, + { "link-journal", required_argument, NULL, ARG_LINK_JOURNAL }, + { NULL, 0, NULL, 0 } + }; + + int c; + + assert(argc >= 0); + assert(argv); + + while ((c = getopt_long(argc, argv, "+hD:u:C:bj", options, NULL)) >= 0) { + + switch (c) { + + case 'h': + help(); + return 0; + + case 'D': + free(arg_directory); + arg_directory = canonicalize_file_name(optarg); + if (!arg_directory) { + log_error("Failed to canonicalize root directory."); + return -ENOMEM; + } + + break; + + case 'u': + free(arg_user); + if (!(arg_user = strdup(optarg))) { + log_error("Failed to duplicate user name."); + return -ENOMEM; + } + + break; + + case 'C': + strv_free(arg_controllers); + arg_controllers = strv_split(optarg, ","); + if (!arg_controllers) { + log_error("Failed to split controllers list."); + return -ENOMEM; + } + strv_uniq(arg_controllers); + + break; + + case ARG_PRIVATE_NETWORK: + arg_private_network = true; + break; + + case 'b': + arg_boot = true; + break; + + case ARG_UUID: + arg_uuid = optarg; + break; + + case ARG_READ_ONLY: + arg_read_only = true; + break; + + case ARG_CAPABILITY: { + char *state, *word; + size_t length; + + FOREACH_WORD_SEPARATOR(word, length, optarg, ",", state) { + cap_value_t cap; + char *t; + + t = strndup(word, length); + if (!t) + return log_oom(); + + if (cap_from_name(t, &cap) < 0) { + log_error("Failed to parse capability %s.", t); + free(t); + return -EINVAL; + } + + free(t); + arg_retain |= 1ULL << (uint64_t) cap; + } + + break; + } + + case 'j': + arg_link_journal = LINK_GUEST; + break; + + case ARG_LINK_JOURNAL: + if (streq(optarg, "auto")) + arg_link_journal = LINK_AUTO; + else if (streq(optarg, "no")) + arg_link_journal = LINK_NO; + else if (streq(optarg, "guest")) + arg_link_journal = LINK_GUEST; + else if (streq(optarg, "host")) + arg_link_journal = LINK_HOST; + else { + log_error("Failed to parse link journal mode %s", optarg); + return -EINVAL; + } + + break; + + case '?': + return -EINVAL; + + default: + log_error("Unknown option code %c", c); + return -EINVAL; + } + } + + return 1; +} + +static int mount_all(const char *dest) { + + typedef struct MountPoint { + const char *what; + const char *where; + const char *type; + const char *options; + unsigned long flags; + bool fatal; + } MountPoint; + + static const MountPoint mount_table[] = { + { "proc", "/proc", "proc", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV, true }, + { "/proc/sys", "/proc/sys", NULL, NULL, MS_BIND, true }, /* Bind mount first */ + { NULL, "/proc/sys", NULL, NULL, MS_BIND|MS_RDONLY|MS_REMOUNT, true }, /* Then, make it r/o */ + { "sysfs", "/sys", "sysfs", NULL, MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV, true }, + { "tmpfs", "/dev", "tmpfs", "mode=755", MS_NOSUID|MS_STRICTATIME, true }, + { "/dev/pts", "/dev/pts", NULL, NULL, MS_BIND, true }, + { "tmpfs", "/dev/shm", "tmpfs", "mode=1777", MS_NOSUID|MS_NODEV|MS_STRICTATIME, true }, + { "tmpfs", "/run", "tmpfs", "mode=755", MS_NOSUID|MS_NODEV|MS_STRICTATIME, true }, +#ifdef HAVE_SELINUX + { "/sys/fs/selinux", "/sys/fs/selinux", NULL, NULL, MS_BIND, false }, /* Bind mount first */ + { NULL, "/sys/fs/selinux", NULL, NULL, MS_BIND|MS_RDONLY|MS_REMOUNT, false }, /* Then, make it r/o */ +#endif + }; + + unsigned k; + int r = 0; + + for (k = 0; k < ELEMENTSOF(mount_table); k++) { + char _cleanup_free_ *where = NULL; + int t; + + if (asprintf(&where, "%s/%s", dest, mount_table[k].where) < 0) { + log_oom(); + + if (r == 0) + r = -ENOMEM; + + break; + } + + t = path_is_mount_point(where, true); + if (t < 0) { + log_error("Failed to detect whether %s is a mount point: %s", where, strerror(-t)); + + if (r == 0) + r = t; + + continue; + } + + /* Skip this entry if it is not a remount. */ + if (mount_table[k].what && t > 0) + continue; + + mkdir_p_label(where, 0755); + + if (mount(mount_table[k].what, + where, + mount_table[k].type, + mount_table[k].flags, + mount_table[k].options) < 0 && + mount_table[k].fatal) { + + log_error("mount(%s) failed: %m", where); + + if (r == 0) + r = -errno; + } + } + + return r; +} + +static int setup_timezone(const char *dest) { + _cleanup_free_ char *where = NULL, *p = NULL, *q = NULL, *check = NULL, *what = NULL; + char *z, *y; + int r; + + assert(dest); + + /* Fix the timezone, if possible */ + r = readlink_malloc("/etc/localtime", &p); + if (r < 0) { + log_warning("/etc/localtime is not a symlink, not updating container timezone."); + return 0; + } + + z = path_startswith(p, "../usr/share/zoneinfo/"); + if (!z) + z = path_startswith(p, "/usr/share/zoneinfo/"); + if (!z) { + log_warning("/etc/localtime does not point into /usr/share/zoneinfo/, not updating container timezone."); + return 0; + } + + where = strappend(dest, "/etc/localtime"); + if (!where) + return log_oom(); + + r = readlink_malloc(where, &q); + if (r >= 0) { + y = path_startswith(q, "../usr/share/zoneinfo/"); + if (!y) + y = path_startswith(q, "/usr/share/zoneinfo/"); + + + /* Already pointing to the right place? Then do nothing .. */ + if (y && streq(y, z)) + return 0; + } + + check = strjoin(dest, "/usr/share/zoneinfo/", z, NULL); + if (!check) + return log_oom(); + + if (access(check, F_OK) < 0) { + log_warning("Timezone %s does not exist in container, not updating container timezone.", z); + return 0; + } + + what = strappend("../usr/share/zoneinfo/", z); + if (!what) + return log_oom(); + + unlink(where); + if (symlink(what, where) < 0) { + log_error("Failed to correct timezone of container: %m"); + return 0; + } + + return 0; +} + +static int setup_resolv_conf(const char *dest) { + char *where; + + assert(dest); + + if (arg_private_network) + return 0; + + /* Fix resolv.conf, if possible */ + where = strappend(dest, "/etc/resolv.conf"); + if (!where) + return log_oom(); + + /* We don't really care for the results of this really. If it + * fails, it fails, but meh... */ + if (mount("/etc/resolv.conf", where, "bind", MS_BIND, NULL) >= 0) + mount("/etc/resolv.conf", where, "bind", MS_BIND|MS_REMOUNT|MS_RDONLY, NULL); + + free(where); + + return 0; +} + +static int setup_boot_id(const char *dest) { + char _cleanup_free_ *from = NULL, *to = NULL; + sd_id128_t rnd; + char as_uuid[37]; + int r; + + assert(dest); + + /* Generate a new randomized boot ID, so that each boot-up of + * the container gets a new one */ + + from = strappend(dest, "/dev/proc-sys-kernel-random-boot-id"); + to = strappend(dest, "/proc/sys/kernel/random/boot_id"); + if (!from || !to) + return log_oom(); + + r = sd_id128_randomize(&rnd); + if (r < 0) { + log_error("Failed to generate random boot id: %s", strerror(-r)); + return r; + } + + snprintf(as_uuid, sizeof(as_uuid), + "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", + SD_ID128_FORMAT_VAL(rnd)); + char_array_0(as_uuid); + + r = write_one_line_file(from, as_uuid); + if (r < 0) { + log_error("Failed to write boot id: %s", strerror(-r)); + return r; + } + + if (mount(from, to, "bind", MS_BIND, NULL) < 0) { + log_error("Failed to bind mount boot id: %m"); + r = -errno; + } else + mount(from, to, "bind", MS_BIND|MS_REMOUNT|MS_RDONLY, NULL); + + unlink(from); + return r; +} + +static int copy_devnodes(const char *dest) { + + static const char devnodes[] = + "null\0" + "zero\0" + "full\0" + "random\0" + "urandom\0" + "tty\0" + "ptmx\0"; + + const char *d; + int r = 0; + mode_t _cleanup_umask_ u; + + assert(dest); + + u = umask(0000); + + NULSTR_FOREACH(d, devnodes) { + struct stat st; + char _cleanup_free_ *from = NULL, *to = NULL; + + asprintf(&from, "/dev/%s", d); + asprintf(&to, "%s/dev/%s", dest, d); + + if (!from || !to) { + log_oom(); + + if (r == 0) + r = -ENOMEM; + + break; + } + + if (stat(from, &st) < 0) { + + if (errno != ENOENT) { + log_error("Failed to stat %s: %m", from); + if (r == 0) + r = -errno; + } + + } else if (!S_ISCHR(st.st_mode) && !S_ISBLK(st.st_mode)) { + + log_error("%s is not a char or block device, cannot copy", from); + if (r == 0) + r = -EIO; + + } else if (mknod(to, st.st_mode, st.st_rdev) < 0) { + + log_error("mknod(%s) failed: %m", dest); + if (r == 0) + r = -errno; + } + } + + return r; +} + +static int setup_dev_console(const char *dest, const char *console) { + struct stat st; + char _cleanup_free_ *to = NULL; + int r; + mode_t _cleanup_umask_ u; + + assert(dest); + assert(console); + + u = umask(0000); + + if (stat(console, &st) < 0) { + log_error("Failed to stat %s: %m", console); + return -errno; + + } else if (!S_ISCHR(st.st_mode)) { + log_error("/dev/console is not a char device"); + return -EIO; + } + + r = chmod_and_chown(console, 0600, 0, 0); + if (r < 0) { + log_error("Failed to correct access mode for TTY: %s", strerror(-r)); + return r; + } + + if (asprintf(&to, "%s/dev/console", dest) < 0) + return log_oom(); + + /* We need to bind mount the right tty to /dev/console since + * ptys can only exist on pts file systems. To have something + * to bind mount things on we create a device node first, that + * has the right major/minor (note that the major minor + * doesn't actually matter here, since we mount it over + * anyway). */ + + if (mknod(to, (st.st_mode & ~07777) | 0600, st.st_rdev) < 0) { + log_error("mknod() for /dev/console failed: %m"); + return -errno; + } + + if (mount(console, to, "bind", MS_BIND, NULL) < 0) { + log_error("Bind mount for /dev/console failed: %m"); + return -errno; + } + + return 0; +} + +static int setup_kmsg(const char *dest, int kmsg_socket) { + char _cleanup_free_ *from = NULL, *to = NULL; + int r, fd, k; + mode_t _cleanup_umask_ u; + union { + struct cmsghdr cmsghdr; + uint8_t buf[CMSG_SPACE(sizeof(int))]; + } control; + struct msghdr mh; + struct cmsghdr *cmsg; + + assert(dest); + assert(kmsg_socket >= 0); + + u = umask(0000); + + /* We create the kmsg FIFO as /dev/kmsg, but immediately + * delete it after bind mounting it to /proc/kmsg. While FIFOs + * on the reading side behave very similar to /proc/kmsg, + * their writing side behaves differently from /dev/kmsg in + * that writing blocks when nothing is reading. In order to + * avoid any problems with containers deadlocking due to this + * we simply make /dev/kmsg unavailable to the container. */ + if (asprintf(&from, "%s/dev/kmsg", dest) < 0 || + asprintf(&to, "%s/proc/kmsg", dest) < 0) + return log_oom(); + + if (mkfifo(from, 0600) < 0) { + log_error("mkfifo() for /dev/kmsg failed: %m"); + return -errno; + } + + r = chmod_and_chown(from, 0600, 0, 0); + if (r < 0) { + log_error("Failed to correct access mode for /dev/kmsg: %s", strerror(-r)); + return r; + } + + if (mount(from, to, "bind", MS_BIND, NULL) < 0) { + log_error("Bind mount for /proc/kmsg failed: %m"); + return -errno; + } + + fd = open(from, O_RDWR|O_NDELAY|O_CLOEXEC); + if (fd < 0) { + log_error("Failed to open fifo: %m"); + return -errno; + } + + zero(mh); + zero(control); + + mh.msg_control = &control; + mh.msg_controllen = sizeof(control); + + cmsg = CMSG_FIRSTHDR(&mh); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_RIGHTS; + cmsg->cmsg_len = CMSG_LEN(sizeof(int)); + memcpy(CMSG_DATA(cmsg), &fd, sizeof(int)); + + mh.msg_controllen = cmsg->cmsg_len; + + /* Store away the fd in the socket, so that it stays open as + * long as we run the child */ + k = sendmsg(kmsg_socket, &mh, MSG_DONTWAIT|MSG_NOSIGNAL); + close_nointr_nofail(fd); + + if (k < 0) { + log_error("Failed to send FIFO fd: %m"); + return -errno; + } + + /* And now make the FIFO unavailable as /dev/kmsg... */ + unlink(from); + return 0; +} + +static int setup_hostname(void) { + char *hn; + int r = 0; + + hn = path_get_file_name(arg_directory); + if (hn) { + hn = strdup(hn); + if (!hn) + return -ENOMEM; + + hostname_cleanup(hn); + + if (!isempty(hn)) + if (sethostname(hn, strlen(hn)) < 0) + r = -errno; + + free(hn); + } + + return r; +} + +static int setup_journal(const char *directory) { + sd_id128_t machine_id; + char _cleanup_free_ *p = NULL, *b = NULL, *q = NULL, *d = NULL; + char *id; + int r; + + if (arg_link_journal == LINK_NO) + return 0; + + p = strappend(directory, "/etc/machine-id"); + if (!p) + return log_oom(); + + r = read_one_line_file(p, &b); + if (r == -ENOENT && arg_link_journal == LINK_AUTO) + return 0; + else if (r < 0) { + log_error("Failed to read machine ID from %s: %s", p, strerror(-r)); + return r; + } + + id = strstrip(b); + if (isempty(id) && arg_link_journal == LINK_AUTO) + return 0; + + /* Verify validity */ + r = sd_id128_from_string(id, &machine_id); + if (r < 0) { + log_error("Failed to parse machine ID from %s: %s", p, strerror(-r)); + return r; + } + + free(p); + p = strappend("/var/log/journal/", id); + q = strjoin(directory, "/var/log/journal/", id, NULL); + if (!p || !q) + return log_oom(); + + if (path_is_mount_point(p, false) > 0) { + if (arg_link_journal != LINK_AUTO) { + log_error("%s: already a mount point, refusing to use for journal", p); + return -EEXIST; + } + + return 0; + } + + if (path_is_mount_point(q, false) > 0) { + if (arg_link_journal != LINK_AUTO) { + log_error("%s: already a mount point, refusing to use for journal", q); + return -EEXIST; + } + + return 0; + } + + r = readlink_and_make_absolute(p, &d); + if (r >= 0) { + if ((arg_link_journal == LINK_GUEST || + arg_link_journal == LINK_AUTO) && + path_equal(d, q)) { + + r = mkdir_p(q, 0755); + if (r < 0) + log_warning("failed to create directory %s: %m", q); + return 0; + } + + if (unlink(p) < 0) { + log_error("Failed to remove symlink %s: %m", p); + return -errno; + } + } else if (r == -EINVAL) { + + if (arg_link_journal == LINK_GUEST && + rmdir(p) < 0) { + + if (errno == ENOTDIR) { + log_error("%s already exists and is neither a symlink nor a directory", p); + return r; + } else { + log_error("Failed to remove %s: %m", p); + return -errno; + } + } + } else if (r != -ENOENT) { + log_error("readlink(%s) failed: %m", p); + return r; + } + + if (arg_link_journal == LINK_GUEST) { + + if (symlink(q, p) < 0) { + log_error("Failed to symlink %s to %s: %m", q, p); + return -errno; + } + + r = mkdir_p(q, 0755); + if (r < 0) + log_warning("failed to create directory %s: %m", q); + return 0; + } + + if (arg_link_journal == LINK_HOST) { + r = mkdir_p(p, 0755); + if (r < 0) { + log_error("Failed to create %s: %m", p); + return r; + } + + } else if (access(p, F_OK) < 0) + return 0; + + if (dir_is_empty(q) == 0) { + log_error("%s not empty.", q); + return -ENOTEMPTY; + } + + r = mkdir_p(q, 0755); + if (r < 0) { + log_error("Failed to create %s: %m", q); + return r; + } + + if (mount(p, q, "bind", MS_BIND, NULL) < 0) { + log_error("Failed to bind mount journal from host into guest: %m"); + return -errno; + } + + return 0; +} + +static int drop_capabilities(void) { + return capability_bounding_set_drop(~arg_retain, false); +} + +static int is_os_tree(const char *path) { + int r; + char *p; + /* We use /bin/sh as flag file if something is an OS */ + + if (asprintf(&p, "%s/bin/sh", path) < 0) + return -ENOMEM; + + r = access(p, F_OK); + free(p); + + return r < 0 ? 0 : 1; +} + +static int process_pty(int master, pid_t pid, sigset_t *mask) { + + char in_buffer[LINE_MAX], out_buffer[LINE_MAX]; + size_t in_buffer_full = 0, out_buffer_full = 0; + struct epoll_event stdin_ev, stdout_ev, master_ev, signal_ev; + bool stdin_readable = false, stdout_writable = false, master_readable = false, master_writable = false; + int ep = -1, signal_fd = -1, r; + bool tried_orderly_shutdown = false; + + assert(master >= 0); + assert(pid > 0); + assert(mask); + + fd_nonblock(STDIN_FILENO, 1); + fd_nonblock(STDOUT_FILENO, 1); + fd_nonblock(master, 1); + + signal_fd = signalfd(-1, mask, SFD_NONBLOCK|SFD_CLOEXEC); + if (signal_fd < 0) { + log_error("signalfd(): %m"); + r = -errno; + goto finish; + } + + ep = epoll_create1(EPOLL_CLOEXEC); + if (ep < 0) { + log_error("Failed to create epoll: %m"); + r = -errno; + goto finish; + } + + /* We read from STDIN only if this is actually a TTY, + * otherwise we assume non-interactivity. */ + if (isatty(STDIN_FILENO)) { + zero(stdin_ev); + stdin_ev.events = EPOLLIN|EPOLLET; + stdin_ev.data.fd = STDIN_FILENO; + + if (epoll_ctl(ep, EPOLL_CTL_ADD, STDIN_FILENO, &stdin_ev) < 0) { + log_error("Failed to register STDIN in epoll: %m"); + r = -errno; + goto finish; + } + } + + zero(stdout_ev); + stdout_ev.events = EPOLLOUT|EPOLLET; + stdout_ev.data.fd = STDOUT_FILENO; + + zero(master_ev); + master_ev.events = EPOLLIN|EPOLLOUT|EPOLLET; + master_ev.data.fd = master; + + zero(signal_ev); + signal_ev.events = EPOLLIN; + signal_ev.data.fd = signal_fd; + + if (epoll_ctl(ep, EPOLL_CTL_ADD, STDOUT_FILENO, &stdout_ev) < 0 || + epoll_ctl(ep, EPOLL_CTL_ADD, master, &master_ev) < 0 || + epoll_ctl(ep, EPOLL_CTL_ADD, signal_fd, &signal_ev) < 0) { + log_error("Failed to register fds in epoll: %m"); + r = -errno; + goto finish; + } + + for (;;) { + struct epoll_event ev[16]; + ssize_t k; + int i, nfds; + + nfds = epoll_wait(ep, ev, ELEMENTSOF(ev), -1); + if (nfds < 0) { + + if (errno == EINTR || errno == EAGAIN) + continue; + + log_error("epoll_wait(): %m"); + r = -errno; + goto finish; + } + + assert(nfds >= 1); + + for (i = 0; i < nfds; i++) { + if (ev[i].data.fd == STDIN_FILENO) { + + if (ev[i].events & (EPOLLIN|EPOLLHUP)) + stdin_readable = true; + + } else if (ev[i].data.fd == STDOUT_FILENO) { + + if (ev[i].events & (EPOLLOUT|EPOLLHUP)) + stdout_writable = true; + + } else if (ev[i].data.fd == master) { + + if (ev[i].events & (EPOLLIN|EPOLLHUP)) + master_readable = true; + + if (ev[i].events & (EPOLLOUT|EPOLLHUP)) + master_writable = true; + + } else if (ev[i].data.fd == signal_fd) { + struct signalfd_siginfo sfsi; + ssize_t n; + + n = read(signal_fd, &sfsi, sizeof(sfsi)); + if (n != sizeof(sfsi)) { + + if (n >= 0) { + log_error("Failed to read from signalfd: invalid block size"); + r = -EIO; + goto finish; + } + + if (errno != EINTR && errno != EAGAIN) { + log_error("Failed to read from signalfd: %m"); + r = -errno; + goto finish; + } + } else { + + if (sfsi.ssi_signo == SIGWINCH) { + struct winsize ws; + + /* The window size changed, let's forward that. */ + if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) >= 0) + ioctl(master, TIOCSWINSZ, &ws); + } else if (sfsi.ssi_signo == SIGTERM && arg_boot && !tried_orderly_shutdown) { + + log_info("Trying to halt container. Send SIGTERM again to trigger immediate termination."); + + /* This only works for systemd... */ + tried_orderly_shutdown = true; + kill(pid, SIGRTMIN+3); + + } else { + r = 0; + goto finish; + } + } + } + } + + while ((stdin_readable && in_buffer_full <= 0) || + (master_writable && in_buffer_full > 0) || + (master_readable && out_buffer_full <= 0) || + (stdout_writable && out_buffer_full > 0)) { + + if (stdin_readable && in_buffer_full < LINE_MAX) { + + k = read(STDIN_FILENO, in_buffer + in_buffer_full, LINE_MAX - in_buffer_full); + if (k < 0) { + + if (errno == EAGAIN || errno == EPIPE || errno == ECONNRESET || errno == EIO) + stdin_readable = false; + else { + log_error("read(): %m"); + r = -errno; + goto finish; + } + } else + in_buffer_full += (size_t) k; + } + + if (master_writable && in_buffer_full > 0) { + + k = write(master, in_buffer, in_buffer_full); + if (k < 0) { + + if (errno == EAGAIN || errno == EPIPE || errno == ECONNRESET || errno == EIO) + master_writable = false; + else { + log_error("write(): %m"); + r = -errno; + goto finish; + } + + } else { + assert(in_buffer_full >= (size_t) k); + memmove(in_buffer, in_buffer + k, in_buffer_full - k); + in_buffer_full -= k; + } + } + + if (master_readable && out_buffer_full < LINE_MAX) { + + k = read(master, out_buffer + out_buffer_full, LINE_MAX - out_buffer_full); + if (k < 0) { + + if (errno == EAGAIN || errno == EPIPE || errno == ECONNRESET || errno == EIO) + master_readable = false; + else { + log_error("read(): %m"); + r = -errno; + goto finish; + } + } else + out_buffer_full += (size_t) k; + } + + if (stdout_writable && out_buffer_full > 0) { + + k = write(STDOUT_FILENO, out_buffer, out_buffer_full); + if (k < 0) { + + if (errno == EAGAIN || errno == EPIPE || errno == ECONNRESET || errno == EIO) + stdout_writable = false; + else { + log_error("write(): %m"); + r = -errno; + goto finish; + } + + } else { + assert(out_buffer_full >= (size_t) k); + memmove(out_buffer, out_buffer + k, out_buffer_full - k); + out_buffer_full -= k; + } + } + } + } + +finish: + if (ep >= 0) + close_nointr_nofail(ep); + + if (signal_fd >= 0) + close_nointr_nofail(signal_fd); + + return r; +} + +int main(int argc, char *argv[]) { + pid_t pid = 0; + int r = EXIT_FAILURE, k; + char *oldcg = NULL, *newcg = NULL; + char **controller = NULL; + int master = -1, n_fd_passed; + const char *console = NULL; + struct termios saved_attr, raw_attr; + sigset_t mask; + bool saved_attr_valid = false; + struct winsize ws; + int kmsg_socket_pair[2] = { -1, -1 }; + FDSet *fds = NULL; + + log_parse_environment(); + log_open(); + + r = parse_argv(argc, argv); + if (r <= 0) + goto finish; + + if (arg_directory) { + char *p; + + p = path_make_absolute_cwd(arg_directory); + free(arg_directory); + arg_directory = p; + } else + arg_directory = get_current_dir_name(); + + if (!arg_directory) { + log_error("Failed to determine path"); + goto finish; + } + + path_kill_slashes(arg_directory); + + if (geteuid() != 0) { + log_error("Need to be root."); + goto finish; + } + + if (sd_booted() <= 0) { + log_error("Not running on a systemd system."); + goto finish; + } + + if (path_equal(arg_directory, "/")) { + log_error("Spawning container on root directory not supported."); + goto finish; + } + + if (is_os_tree(arg_directory) <= 0) { + log_error("Directory %s doesn't look like an OS root directory. Refusing.", arg_directory); + goto finish; + } + + log_close(); + n_fd_passed = sd_listen_fds(false); + if (n_fd_passed > 0) { + k = fdset_new_listen_fds(&fds, false); + if (k < 0) { + log_error("Failed to collect file descriptors: %s", strerror(-k)); + goto finish; + } + } + fdset_close_others(fds); + log_open(); + + k = cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, 0, &oldcg); + if (k < 0) { + log_error("Failed to determine current cgroup: %s", strerror(-k)); + goto finish; + } + + if (asprintf(&newcg, "%s/nspawn-%lu", oldcg, (unsigned long) getpid()) < 0) { + log_error("Failed to allocate cgroup path."); + goto finish; + } + + k = cg_create_and_attach(SYSTEMD_CGROUP_CONTROLLER, newcg, 0); + if (k < 0) { + log_error("Failed to create cgroup: %s", strerror(-k)); + goto finish; + } + + STRV_FOREACH(controller, arg_controllers) { + k = cg_create_and_attach(*controller, newcg, 0); + if (k < 0) + log_warning("Failed to create cgroup in controller %s: %s", *controller, strerror(-k)); + } + + master = posix_openpt(O_RDWR|O_NOCTTY|O_CLOEXEC|O_NDELAY); + if (master < 0) { + log_error("Failed to acquire pseudo tty: %m"); + goto finish; + } + + console = ptsname(master); + if (!console) { + log_error("Failed to determine tty name: %m"); + goto finish; + } + + log_info("Spawning namespace container on %s (console is %s).", arg_directory, console); + + if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) >= 0) + ioctl(master, TIOCSWINSZ, &ws); + + if (unlockpt(master) < 0) { + log_error("Failed to unlock tty: %m"); + goto finish; + } + + if (tcgetattr(STDIN_FILENO, &saved_attr) >= 0) { + saved_attr_valid = true; + + raw_attr = saved_attr; + cfmakeraw(&raw_attr); + raw_attr.c_lflag &= ~ECHO; + } + + if (socketpair(AF_UNIX, SOCK_DGRAM|SOCK_NONBLOCK|SOCK_CLOEXEC, 0, kmsg_socket_pair) < 0) { + log_error("Failed to create kmsg socket pair"); + goto finish; + } + + assert_se(sigemptyset(&mask) == 0); + sigset_add_many(&mask, SIGCHLD, SIGWINCH, SIGTERM, SIGINT, -1); + assert_se(sigprocmask(SIG_BLOCK, &mask, NULL) == 0); + + for (;;) { + siginfo_t status; + + if (saved_attr_valid) { + if (tcsetattr(STDIN_FILENO, TCSANOW, &raw_attr) < 0) { + log_error("Failed to set terminal attributes: %m"); + goto finish; + } + } + + pid = syscall(__NR_clone, SIGCHLD|CLONE_NEWIPC|CLONE_NEWNS|CLONE_NEWPID|CLONE_NEWUTS|(arg_private_network ? CLONE_NEWNET : 0), NULL); + if (pid < 0) { + if (errno == EINVAL) + log_error("clone() failed, do you have namespace support enabled in your kernel? (You need UTS, IPC, PID and NET namespacing built in): %m"); + else + log_error("clone() failed: %m"); + + goto finish; + } + + if (pid == 0) { + /* child */ + + const char *home = NULL; + uid_t uid = (uid_t) -1; + gid_t gid = (gid_t) -1; + unsigned n_env = 0; + const char *envp[] = { + "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", + "container=systemd-nspawn", /* LXC sets container=lxc, so follow the scheme here */ + NULL, /* TERM */ + NULL, /* HOME */ + NULL, /* USER */ + NULL, /* LOGNAME */ + NULL, /* container_uuid */ + NULL, /* LISTEN_FDS */ + NULL, /* LISTEN_PID */ + NULL + }; + + envp[2] = strv_find_prefix(environ, "TERM="); + n_env = 3; + + close_nointr_nofail(master); + master = -1; + + close_nointr(STDIN_FILENO); + close_nointr(STDOUT_FILENO); + close_nointr(STDERR_FILENO); + + close_nointr_nofail(kmsg_socket_pair[0]); + kmsg_socket_pair[0] = -1; + + reset_all_signal_handlers(); + + assert_se(sigemptyset(&mask) == 0); + assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0); + + k = open_terminal(console, O_RDWR); + if (k != STDIN_FILENO) { + if (k >= 0) { + close_nointr_nofail(k); + k = -EINVAL; + } + + log_error("Failed to open console: %s", strerror(-k)); + goto child_fail; + } + + if (dup2(STDIN_FILENO, STDOUT_FILENO) != STDOUT_FILENO || + dup2(STDIN_FILENO, STDERR_FILENO) != STDERR_FILENO) { + log_error("Failed to duplicate console: %m"); + goto child_fail; + } + + if (setsid() < 0) { + log_error("setsid() failed: %m"); + goto child_fail; + } + + if (prctl(PR_SET_PDEATHSIG, SIGKILL) < 0) { + log_error("PR_SET_PDEATHSIG failed: %m"); + goto child_fail; + } + + /* Mark everything as slave, so that we still + * receive mounts from the real root, but don't + * propagate mounts to the real root. */ + if (mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL) < 0) { + log_error("MS_SLAVE|MS_REC failed: %m"); + goto child_fail; + } + + /* Turn directory into bind mount */ + if (mount(arg_directory, arg_directory, "bind", MS_BIND|MS_REC, NULL) < 0) { + log_error("Failed to make bind mount."); + goto child_fail; + } + + if (arg_read_only) + if (mount(arg_directory, arg_directory, "bind", MS_BIND|MS_REMOUNT|MS_RDONLY|MS_REC, NULL) < 0) { + log_error("Failed to make read-only."); + goto child_fail; + } + + if (mount_all(arg_directory) < 0) + goto child_fail; + + if (copy_devnodes(arg_directory) < 0) + goto child_fail; + + dev_setup(arg_directory); + + if (setup_dev_console(arg_directory, console) < 0) + goto child_fail; + + if (setup_kmsg(arg_directory, kmsg_socket_pair[1]) < 0) + goto child_fail; + + close_nointr_nofail(kmsg_socket_pair[1]); + kmsg_socket_pair[1] = -1; + + if (setup_boot_id(arg_directory) < 0) + goto child_fail; + + if (setup_timezone(arg_directory) < 0) + goto child_fail; + + if (setup_resolv_conf(arg_directory) < 0) + goto child_fail; + + if (setup_journal(arg_directory) < 0) + goto child_fail; + + if (chdir(arg_directory) < 0) { + log_error("chdir(%s) failed: %m", arg_directory); + goto child_fail; + } + + if (mount(arg_directory, "/", NULL, MS_MOVE, NULL) < 0) { + log_error("mount(MS_MOVE) failed: %m"); + goto child_fail; + } + + if (chroot(".") < 0) { + log_error("chroot() failed: %m"); + goto child_fail; + } + + if (chdir("/") < 0) { + log_error("chdir() failed: %m"); + goto child_fail; + } + + umask(0022); + + loopback_setup(); + + if (drop_capabilities() < 0) { + log_error("drop_capabilities() failed: %m"); + goto child_fail; + } + + if (arg_user) { + + /* Note that this resolves user names + * inside the container, and hence + * accesses the NSS modules from the + * container and not the host. This is + * a bit weird... */ + + if (get_user_creds((const char**)&arg_user, &uid, &gid, &home, NULL) < 0) { + log_error("get_user_creds() failed: %m"); + goto child_fail; + } + + if (mkdir_parents_label(home, 0775) < 0) { + log_error("mkdir_parents_label() failed: %m"); + goto child_fail; + } + + if (mkdir_safe_label(home, 0775, uid, gid) < 0) { + log_error("mkdir_safe_label() failed: %m"); + goto child_fail; + } + + if (initgroups((const char*)arg_user, gid) < 0) { + log_error("initgroups() failed: %m"); + goto child_fail; + } + + if (setresgid(gid, gid, gid) < 0) { + log_error("setregid() failed: %m"); + goto child_fail; + } + + if (setresuid(uid, uid, uid) < 0) { + log_error("setreuid() failed: %m"); + goto child_fail; + } + } else { + /* Reset everything fully to 0, just in case */ + + if (setgroups(0, NULL) < 0) { + log_error("setgroups() failed: %m"); + goto child_fail; + } + + if (setresgid(0, 0, 0) < 0) { + log_error("setregid() failed: %m"); + goto child_fail; + } + + if (setresuid(0, 0, 0) < 0) { + log_error("setreuid() failed: %m"); + goto child_fail; + } + } + + if ((asprintf((char**)(envp + n_env++), "HOME=%s", home ? home: "/root") < 0) || + (asprintf((char**)(envp + n_env++), "USER=%s", arg_user ? arg_user : "root") < 0) || + (asprintf((char**)(envp + n_env++), "LOGNAME=%s", arg_user ? arg_user : "root") < 0)) { + log_oom(); + goto child_fail; + } + + if (arg_uuid) { + if (asprintf((char**)(envp + n_env++), "container_uuid=%s", arg_uuid) < 0) { + log_oom(); + goto child_fail; + } + } + + if (fdset_size(fds) > 0) { + k = fdset_cloexec(fds, false); + if (k < 0) { + log_error("Failed to unset O_CLOEXEC for file descriptors."); + goto child_fail; + } + + if ((asprintf((char **)(envp + n_env++), "LISTEN_FDS=%u", n_fd_passed) < 0) || + (asprintf((char **)(envp + n_env++), "LISTEN_PID=%lu", (unsigned long) getpid()) < 0)) { + log_oom(); + goto child_fail; + } + } + + setup_hostname(); + + if (arg_boot) { + char **a; + size_t l; + + /* Automatically search for the init system */ + + l = 1 + argc - optind; + a = newa(char*, l + 1); + memcpy(a + 1, argv + optind, l * sizeof(char*)); + + a[0] = (char*) "/usr/lib/systemd/systemd"; + execve(a[0], a, (char**) envp); + + a[0] = (char*) "/lib/systemd/systemd"; + execve(a[0], a, (char**) envp); + + a[0] = (char*) "/sbin/init"; + execve(a[0], a, (char**) envp); + } else if (argc > optind) + execvpe(argv[optind], argv + optind, (char**) envp); + else { + chdir(home ? home : "/root"); + execle("/bin/bash", "-bash", NULL, (char**) envp); + } + + log_error("execv() failed: %m"); + + child_fail: + _exit(EXIT_FAILURE); + } + + fdset_free(fds); + fds = NULL; + + if (process_pty(master, pid, &mask) < 0) + goto finish; + + if (saved_attr_valid) + tcsetattr(STDIN_FILENO, TCSANOW, &saved_attr); + + r = wait_for_terminate(pid, &status); + if (r < 0) { + r = EXIT_FAILURE; + break; + } + + if (status.si_code == CLD_EXITED) { + if (status.si_status != 0) { + log_error("Container failed with error code %i.", status.si_status); + r = status.si_status; + break; + } + + log_debug("Container exited successfully."); + break; + } else if (status.si_code == CLD_KILLED && + status.si_status == SIGINT) { + log_info("Container has been shut down."); + r = 0; + break; + } else if (status.si_code == CLD_KILLED && + status.si_status == SIGHUP) { + log_info("Container is being rebooted."); + continue; + } else if (status.si_code == CLD_KILLED || + status.si_code == CLD_DUMPED) { + + log_error("Container terminated by signal %s.", signal_to_string(status.si_status)); + r = EXIT_FAILURE; + break; + } else { + log_error("Container failed due to unknown reason."); + r = EXIT_FAILURE; + break; + } + } + +finish: + if (saved_attr_valid) + tcsetattr(STDIN_FILENO, TCSANOW, &saved_attr); + + if (master >= 0) + close_nointr_nofail(master); + + close_pipe(kmsg_socket_pair); + + if (oldcg) + cg_attach(SYSTEMD_CGROUP_CONTROLLER, oldcg, 0); + + if (newcg) + cg_kill_recursive_and_wait(SYSTEMD_CGROUP_CONTROLLER, newcg, true); + + free(arg_directory); + strv_free(arg_controllers); + free(oldcg); + free(newcg); + + fdset_free(fds); + + return r; +} diff --git a/src/python-systemd/Makefile b/src/python-systemd/Makefile new file mode 120000 index 000000000..d0b0e8e00 --- /dev/null +++ b/src/python-systemd/Makefile @@ -0,0 +1 @@ +../Makefile \ No newline at end of file diff --git a/src/python-systemd/__init__.py b/src/python-systemd/__init__.py new file mode 100644 index 000000000..0d56b992f --- /dev/null +++ b/src/python-systemd/__init__.py @@ -0,0 +1,18 @@ +# -*- Mode: python; indent-tabs-mode: nil -*- */ +# +# This file is part of systemd. +# +# Copyright 2012 David Strauss +# +# 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 . diff --git a/src/python-systemd/_journal.c b/src/python-systemd/_journal.c new file mode 100644 index 000000000..0bdf709ae --- /dev/null +++ b/src/python-systemd/_journal.c @@ -0,0 +1,141 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2012 David Strauss + + 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 . +***/ + +#include + +#include + +#define SD_JOURNAL_SUPPRESS_LOCATION +#include + +PyDoc_STRVAR(journal_sendv__doc__, + "sendv('FIELD=value', 'FIELD=value', ...) -> None\n\n" + "Send an entry to the journal." +); + +static PyObject *journal_sendv(PyObject *self, PyObject *args) { + struct iovec *iov = NULL; + int argc; + int i, r; + PyObject *ret = NULL; + PyObject **encoded; + + /* Allocate an array for the argument strings */ + argc = PyTuple_Size(args); + encoded = alloca(argc * sizeof(PyObject*)); + memset(encoded, 0, argc * sizeof(PyObject*)); + + /* Allocate sufficient iovector space for the arguments. */ + iov = alloca(argc * sizeof(struct iovec)); + + /* Iterate through the Python arguments and fill the iovector. */ + for (i = 0; i < argc; ++i) { + PyObject *item = PyTuple_GetItem(args, i); + char *stritem; + Py_ssize_t length; + + if (PyUnicode_Check(item)) { + encoded[i] = PyUnicode_AsEncodedString(item, "utf-8", "strict"); + if (encoded[i] == NULL) + goto out; + item = encoded[i]; + } + if (PyBytes_AsStringAndSize(item, &stritem, &length)) + goto out; + + iov[i].iov_base = stritem; + iov[i].iov_len = length; + } + + /* Send the iovector to the journal. */ + r = sd_journal_sendv(iov, argc); + if (r < 0) { + errno = -r; + PyErr_SetFromErrno(PyExc_IOError); + goto out; + } + + /* End with success. */ + Py_INCREF(Py_None); + ret = Py_None; + +out: + for (i = 0; i < argc; ++i) + Py_XDECREF(encoded[i]); + + return ret; +} + +PyDoc_STRVAR(journal_stream_fd__doc__, + "stream_fd(identifier, priority, level_prefix) -> fd\n\n" + "Open a stream to journal by calling sd_journal_stream_fd(3)." +); + +static PyObject* journal_stream_fd(PyObject *self, PyObject *args) { + const char* identifier; + int priority, level_prefix; + int fd; + + if (!PyArg_ParseTuple(args, "sii:stream_fd", + &identifier, &priority, &level_prefix)) + return NULL; + + fd = sd_journal_stream_fd(identifier, priority, level_prefix); + if (fd < 0) { + errno = -fd; + return PyErr_SetFromErrno(PyExc_IOError); + } + + return PyLong_FromLong(fd); +} + +static PyMethodDef methods[] = { + { "sendv", journal_sendv, METH_VARARGS, journal_sendv__doc__ }, + { "stream_fd", journal_stream_fd, METH_VARARGS, journal_stream_fd__doc__ }, + { NULL, NULL, 0, NULL } /* Sentinel */ +}; + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmissing-prototypes" + +#if PY_MAJOR_VERSION < 3 + +PyMODINIT_FUNC init_journal(void) { + (void) Py_InitModule("_journal", methods); +} + +#else + +static struct PyModuleDef module = { + PyModuleDef_HEAD_INIT, + "_journal", /* name of module */ + NULL, /* module documentation, may be NULL */ + 0, /* size of per-interpreter state of the module */ + methods +}; + +PyMODINIT_FUNC PyInit__journal(void) { + return PyModule_Create(&module); +} + +#endif + +#pragma GCC diagnostic pop diff --git a/src/python-systemd/journal.py b/src/python-systemd/journal.py new file mode 100644 index 000000000..516ca1ab5 --- /dev/null +++ b/src/python-systemd/journal.py @@ -0,0 +1,201 @@ +# -*- Mode: python; indent-tabs-mode: nil -*- */ +# +# This file is part of systemd. +# +# Copyright 2012 David Strauss +# +# 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 . + +import traceback as _traceback +import os as _os +import logging as _logging +from syslog import (LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_ERR, + LOG_WARNING, LOG_NOTICE, LOG_INFO, LOG_DEBUG) +from ._journal import sendv, stream_fd + +def _make_line(field, value): + if isinstance(value, bytes): + return field.encode('utf-8') + b'=' + value + else: + return field + '=' + value + +def send(MESSAGE, MESSAGE_ID=None, + CODE_FILE=None, CODE_LINE=None, CODE_FUNC=None, + **kwargs): + r"""Send a message to journald. + + >>> journal.send('Hello world') + >>> journal.send('Hello, again, world', FIELD2='Greetings!') + >>> journal.send('Binary message', BINARY=b'\xde\xad\xbe\xef') + + Value of the MESSAGE argument will be used for the MESSAGE= + field. + + MESSAGE_ID can be given to uniquely identify the type of + message. + + Other parts of the message can be specified as keyword + arguments. + + Both MESSAGE and MESSAGE_ID, if present, must be strings, and + will be sent as UTF-8 to journal. Other arguments can be + bytes, in which case they will be sent as-is to journal. + + CODE_LINE, CODE_FILE, and CODE_FUNC can be specified to + identify the caller. Unless at least on of the three is given, + values are extracted from the stack frame of the caller of + send(). CODE_FILE and CODE_FUNC must be strings, CODE_LINE + must be an integer. + + Other useful fields include PRIORITY, SYSLOG_FACILITY, + SYSLOG_IDENTIFIER, SYSLOG_PID. + """ + + args = ['MESSAGE=' + MESSAGE] + + if MESSAGE_ID is not None: + args.append('MESSAGE_ID=' + MESSAGE_ID) + + if CODE_LINE == CODE_FILE == CODE_FUNC == None: + CODE_FILE, CODE_LINE, CODE_FUNC = \ + _traceback.extract_stack(limit=2)[0][:3] + if CODE_FILE is not None: + args.append('CODE_FILE=' + CODE_FILE) + if CODE_LINE is not None: + args.append('CODE_LINE={:d}'.format(CODE_LINE)) + if CODE_FUNC is not None: + args.append('CODE_FUNC=' + CODE_FUNC) + + args.extend(_make_line(key, val) for key, val in kwargs.items()) + return sendv(*args) + +def stream(identifier, priority=LOG_DEBUG, level_prefix=False): + r"""Return a file object wrapping a stream to journal. + + Log messages written to this file as simple newline sepearted + text strings are written to the journal. + + The file will be line buffered, so messages are actually sent + after a newline character is written. + + >>> stream = journal.stream('myapp') + >>> stream + ', mode 'w' at 0x...> + >>> stream.write('message...\n') + + will produce the following message in the journal: + + PRIORITY=7 + SYSLOG_IDENTIFIER=myapp + MESSAGE=message... + + Using the interface with print might be more convinient: + + >>> from __future__ import print_function + >>> print('message...', file=stream) + + priority is the syslog priority, one of LOG_EMERG, LOG_ALERT, + LOG_CRIT, LOG_ERR, LOG_WARNING, LOG_NOTICE, LOG_INFO, LOG_DEBUG. + + level_prefix is a boolean. If true, kernel-style log priority + level prefixes (such as '<1>') are interpreted. See + sd-daemon(3) for more information. + """ + + fd = stream_fd(identifier, priority, level_prefix) + return _os.fdopen(fd, 'w', 1) + +class JournalHandler(_logging.Handler): + """Journal handler class for the Python logging framework. + + Please see the Python logging module documentation for an + overview: http://docs.python.org/library/logging.html + + To create a custom logger whose messages go only to journal: + + >>> log = logging.getLogger('custom_logger_name') + >>> log.propagate = False + >>> log.addHandler(journal.JournalHandler()) + >>> log.warn("Some message: %s", detail) + + Note that by default, message levels INFO and DEBUG are ignored + by the logging framework. To enable those log levels: + + >>> log.setLevel(logging.DEBUG) + + To attach journal MESSAGE_ID, an extra field is supported: + + >>> log.warn("Message with ID", + >>> extra={'MESSAGE_ID': '22bb01335f724c959ac4799627d1cb61'}) + + To redirect all logging messages to journal regardless of where + they come from, attach it to the root logger: + + >>> logging.root.addHandler(journal.JournalHandler()) + + For more complex configurations when using dictConfig or + fileConfig, specify 'systemd.journal.JournalHandler' as the + handler class. Only standard handler configuration options + are supported: level, formatter, filters. + + The following journal fields will be sent: + + MESSAGE, PRIORITY, THREAD_NAME, CODE_FILE, CODE_LINE, + CODE_FUNC, LOGGER (name as supplied to getLogger call), + MESSAGE_ID (optional, see above). + """ + + def emit(self, record): + """Write record as journal event. + + MESSAGE is taken from the message provided by the + user, and PRIORITY, LOGGER, THREAD_NAME, + CODE_{FILE,LINE,FUNC} fields are appended + automatically. In addition, record.MESSAGE_ID will be + used if present. + """ + try: + msg = self.format(record) + pri = self.mapPriority(record.levelno) + mid = getattr(record, 'MESSAGE_ID', None) + send(msg, + MESSAGE_ID=mid, + PRIORITY=format(pri), + LOGGER=record.name, + THREAD_NAME=record.threadName, + CODE_FILE=record.pathname, + CODE_LINE=record.lineno, + CODE_FUNC=record.funcName) + except Exception: + self.handleError(record) + + @staticmethod + def mapPriority(levelno): + """Map logging levels to journald priorities. + + Since Python log level numbers are "sparse", we have + to map numbers in between the standard levels too. + """ + if levelno <= _logging.DEBUG: + return LOG_DEBUG + elif levelno <= _logging.INFO: + return LOG_INFO + elif levelno <= _logging.WARNING: + return LOG_WARNING + elif levelno <= _logging.ERROR: + return LOG_ERR + elif levelno <= _logging.CRITICAL: + return LOG_CRIT + else: + return LOG_ALERT diff --git a/src/quotacheck/Makefile b/src/quotacheck/Makefile new file mode 120000 index 000000000..d0b0e8e00 --- /dev/null +++ b/src/quotacheck/Makefile @@ -0,0 +1 @@ +../Makefile \ No newline at end of file diff --git a/src/quotacheck/quotacheck.c b/src/quotacheck/quotacheck.c new file mode 100644 index 000000000..e7a440502 --- /dev/null +++ b/src/quotacheck/quotacheck.c @@ -0,0 +1,123 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include +#include + +#include "util.h" +#include "virt.h" + +static bool arg_skip = false; +static bool arg_force = false; + +static int parse_proc_cmdline(void) { + char *line, *w, *state; + int r; + size_t l; + + if (detect_container(NULL) > 0) + return 0; + + if ((r = read_one_line_file("/proc/cmdline", &line)) < 0) { + log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r)); + return 0; + } + + FOREACH_WORD_QUOTED(w, l, line, state) { + + if (strneq(w, "quotacheck.mode=auto", l)) + arg_force = arg_skip = false; + else if (strneq(w, "quotacheck.mode=force", l)) + arg_force = true; + else if (strneq(w, "quotacheck.mode=skip", l)) + arg_skip = true; + else if (startswith(w, "quotacheck")) + log_warning("Invalid quotacheck parameter. Ignoring."); +#ifdef HAVE_SYSV_COMPAT + else if (strneq(w, "forcequotacheck", l)) { + log_error("Please use 'quotacheck.mode=force' rather than 'forcequotacheck' on the kernel command line."); + arg_force = true; + } +#endif + } + + free(line); + return 0; +} + +static void test_files(void) { +#ifdef HAVE_SYSV_COMPAT + if (access("/forcequotacheck", F_OK) >= 0) { + log_error("Please pass 'quotacheck.mode=force' on the kernel command line rather than creating /forcequotacheck on the root file system."); + arg_force = true; + } +#endif +} + +int main(int argc, char *argv[]) { + static const char * const cmdline[] = { + "/sbin/quotacheck", + "-anug", + NULL + }; + + int r = EXIT_FAILURE; + pid_t pid; + + if (argc > 1) { + log_error("This program takes no arguments."); + return EXIT_FAILURE; + } + + log_set_target(LOG_TARGET_AUTO); + log_parse_environment(); + log_open(); + + umask(0022); + + parse_proc_cmdline(); + test_files(); + + if (!arg_force) { + if (arg_skip) + return 0; + + if (access("/run/systemd/quotacheck", F_OK) < 0) + return 0; + } + + if ((pid = fork()) < 0) { + log_error("fork(): %m"); + goto finish; + } else if (pid == 0) { + /* Child */ + execv(cmdline[0], (char**) cmdline); + _exit(1); /* Operational error */ + } + + r = wait_for_terminate_and_warn("quotacheck", pid) == 0 ? EXIT_SUCCESS : EXIT_FAILURE; + +finish: + return r; +} diff --git a/src/random-seed/Makefile b/src/random-seed/Makefile new file mode 120000 index 000000000..d0b0e8e00 --- /dev/null +++ b/src/random-seed/Makefile @@ -0,0 +1 @@ +../Makefile \ No newline at end of file diff --git a/src/random-seed/random-seed.c b/src/random-seed/random-seed.c new file mode 100644 index 000000000..fdcaa1e15 --- /dev/null +++ b/src/random-seed/random-seed.c @@ -0,0 +1,149 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include +#include + +#include "log.h" +#include "util.h" +#include "mkdir.h" + +#define POOL_SIZE_MIN 512 + +int main(int argc, char *argv[]) { + int seed_fd = -1, random_fd = -1; + int ret = EXIT_FAILURE; + void* buf; + size_t buf_size = 0; + ssize_t r; + FILE *f; + + if (argc != 2) { + log_error("This program requires one argument."); + return EXIT_FAILURE; + } + + log_set_target(LOG_TARGET_AUTO); + log_parse_environment(); + log_open(); + + umask(0022); + + /* Read pool size, if possible */ + if ((f = fopen("/proc/sys/kernel/random/poolsize", "re"))) { + if (fscanf(f, "%zu", &buf_size) > 0) { + /* poolsize is in bits on 2.6, but we want bytes */ + buf_size /= 8; + } + + fclose(f); + } + + if (buf_size <= POOL_SIZE_MIN) + buf_size = POOL_SIZE_MIN; + + if (!(buf = malloc(buf_size))) { + log_error("Failed to allocate buffer."); + goto finish; + } + + if (mkdir_parents_label(RANDOM_SEED, 0755) < 0) { + log_error("Failed to create directories parents of %s: %m", RANDOM_SEED); + goto finish; + } + + /* When we load the seed we read it and write it to the device + * and then immediately update the saved seed with new data, + * to make sure the next boot gets seeded differently. */ + + if (streq(argv[1], "load")) { + + if ((seed_fd = open(RANDOM_SEED, O_RDWR|O_CLOEXEC|O_NOCTTY|O_CREAT, 0600)) < 0) { + if ((seed_fd = open(RANDOM_SEED, O_RDONLY|O_CLOEXEC|O_NOCTTY)) < 0) { + log_error("Failed to open random seed: %m"); + goto finish; + } + } + + if ((random_fd = open("/dev/urandom", O_RDWR|O_CLOEXEC|O_NOCTTY, 0600)) < 0) { + if ((random_fd = open("/dev/urandom", O_WRONLY|O_CLOEXEC|O_NOCTTY, 0600)) < 0) { + log_error("Failed to open /dev/urandom: %m"); + goto finish; + } + } + + if ((r = loop_read(seed_fd, buf, buf_size, false)) <= 0) { + + if (r != 0) + log_error("Failed to read seed file: %m"); + } else { + lseek(seed_fd, 0, SEEK_SET); + + if ((r = loop_write(random_fd, buf, (size_t) r, false)) <= 0) + log_error("Failed to write seed to /dev/urandom: %s", + r < 0 ? strerror(errno) : "short write"); + } + + } else if (streq(argv[1], "save")) { + + if ((seed_fd = open(RANDOM_SEED, O_WRONLY|O_CLOEXEC|O_NOCTTY|O_CREAT, 0600)) < 0) { + log_error("Failed to open random seed: %m"); + goto finish; + } + + if ((random_fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY)) < 0) { + log_error("Failed to open /dev/urandom: %m"); + goto finish; + } + } else { + log_error("Unknown verb %s.", argv[1]); + goto finish; + } + + /* This is just a safety measure. Given that we are root and + * most likely created the file ourselves the mode and owner + * should be correct anyway. */ + fchmod(seed_fd, 0600); + fchown(seed_fd, 0, 0); + + if ((r = loop_read(random_fd, buf, buf_size, false)) <= 0) + log_error("Failed to read new seed from /dev/urandom: %s", r < 0 ? strerror(errno) : "EOF"); + else { + if ((r = loop_write(seed_fd, buf, (size_t) r, false)) <= 0) + log_error("Failed to write new random seed file: %s", r < 0 ? strerror(errno) : "short write"); + } + + ret = EXIT_SUCCESS; + +finish: + if (random_fd >= 0) + close_nointr_nofail(random_fd); + + if (seed_fd >= 0) + close_nointr_nofail(seed_fd); + + free(buf); + + return ret; +} diff --git a/src/rc-local-generator/Makefile b/src/rc-local-generator/Makefile new file mode 120000 index 000000000..d0b0e8e00 --- /dev/null +++ b/src/rc-local-generator/Makefile @@ -0,0 +1 @@ +../Makefile \ No newline at end of file diff --git a/src/rc-local-generator/rc-local-generator.c b/src/rc-local-generator/rc-local-generator.c new file mode 100644 index 000000000..448980ba2 --- /dev/null +++ b/src/rc-local-generator/rc-local-generator.c @@ -0,0 +1,115 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + Copyright 2011 Michal Schmidt + + 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 . +***/ + +#include +#include +#include + +#include "log.h" +#include "util.h" +#include "mkdir.h" + +#ifndef RC_LOCAL_SCRIPT_PATH_START +#define RC_LOCAL_SCRIPT_PATH_START "/etc/rc.d/rc.local" +#endif + +#ifndef RC_LOCAL_SCRIPT_PATH_STOP +#define RC_LOCAL_SCRIPT_PATH_STOP "/sbin/halt.local" +#endif + +const char *arg_dest = "/tmp"; + +static int add_symlink(const char *service, const char *where) { + char *from = NULL, *to = NULL; + int r; + + assert(service); + + asprintf(&from, SYSTEM_DATA_UNIT_PATH "/%s", service); + asprintf(&to, "%s/%s.wants/%s", arg_dest, where, service); + + if (!from || !to) { + r = log_oom(); + goto finish; + } + + mkdir_parents_label(to, 0755); + + r = symlink(from, to); + if (r < 0) { + if (errno == EEXIST) + r = 0; + else { + log_error("Failed to create symlink from %s to %s: %m", from, to); + r = -errno; + } + } + +finish: + free(from); + free(to); + + return r; +} + +static bool file_is_executable(const char *f) { + struct stat st; + + if (stat(f, &st) < 0) + return false; + + return S_ISREG(st.st_mode) && (st.st_mode & 0111); +} + +int main(int argc, char *argv[]) { + int r = EXIT_SUCCESS; + + if (argc > 1 && argc != 4) { + log_error("This program takes three or no arguments."); + return EXIT_FAILURE; + } + + if (argc > 1) + arg_dest = argv[1]; + + log_set_target(LOG_TARGET_SAFE); + log_parse_environment(); + log_open(); + + umask(0022); + + if (file_is_executable(RC_LOCAL_SCRIPT_PATH_START)) { + log_debug("Automatically adding rc-local.service."); + + if (add_symlink("rc-local.service", "multi-user.target") < 0) + r = EXIT_FAILURE; + } + + if (file_is_executable(RC_LOCAL_SCRIPT_PATH_STOP)) { + log_debug("Automatically adding halt-local.service."); + + if (add_symlink("halt-local.service", "final.target") < 0) + r = EXIT_FAILURE; + } + + return r; +} diff --git a/src/readahead/Makefile b/src/readahead/Makefile new file mode 120000 index 000000000..d0b0e8e00 --- /dev/null +++ b/src/readahead/Makefile @@ -0,0 +1 @@ +../Makefile \ No newline at end of file diff --git a/src/readahead/readahead-analyze.c b/src/readahead/readahead-analyze.c new file mode 100644 index 000000000..9a929c093 --- /dev/null +++ b/src/readahead/readahead-analyze.c @@ -0,0 +1,150 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2012 Auke Kok + + 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 . +***/ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "readahead-common.h" + +int main_analyze(const char *pack_path) { + char line[LINE_MAX]; + FILE *pack; + int a; + int missing = 0; + off_t tsize = 0; + + if (!pack_path) + pack_path = "/.readahead"; + + pack = fopen(pack_path, "re"); + if (!pack) { + log_error("Pack file missing."); + goto fail; + } + + if (!fgets(line, sizeof(line), pack)) { + log_error("Pack file corrupt."); + goto fail; + } + + char_array_0(line); + + if (!endswith(line, READAHEAD_PACK_FILE_VERSION)) { + log_error("Pack file version incompatible with this parser."); + goto fail; + } + + if ((a = getc(pack)) == EOF) { + log_error("Pack file corrupt."); + goto fail; + } + + fputs(" pct sections size: path\n" + " === ======== ====: ====\n", stdout); + + for (;;) { + char path[PATH_MAX]; + struct stat st; + uint64_t inode; + int pages = 0; + int sections = 0; + + if (!fgets(path, sizeof(path), pack)) + break; /* done */ + + path[strlen(path)-1] = 0; + + if (fread(&inode, sizeof(inode), 1, pack) != 1) { + log_error("Pack file corrupt."); + goto fail; + } + + for (;;) { + uint32_t b, c; + + if (fread(&b, sizeof(b), 1, pack) != 1 || + fread(&c, sizeof(c), 1, pack) != 1) { + log_error("Pack file corrupt."); + goto fail; + } + if ((b == 0) && (c == 0)) + break; + + /* Uncomment this to get all the chunks separately + printf(" %d: %d %d\n", sections, b, c); + */ + + pages += (c - b); + sections++; + } + + if (stat(path, &st) == 0) { + off_t size; + + if (sections == 0) + size = st.st_size; + else + size = pages * page_size(); + + tsize += size; + + printf(" %4d%% (%2d) %12ld: %s\n", + sections ? (int) (size * 100 / st.st_size) : 100, + sections ? sections : 1, + (unsigned long)size, + path); + } else { + printf(" %4dp (%2d) %12s: %s (MISSING)\n", + sections ? pages : -1, + sections ? sections : 1, + "???", + path); + missing++; + } + + } + + fclose(pack); + + printf("\nHOST: %s" + "TYPE: %c\n" + "MISSING: %d\n" + "TOTAL: %llu\n", + line, + a, + missing, + (unsigned long long) tsize); + + return EXIT_SUCCESS; + +fail: + if(pack) + fclose(pack); + return EXIT_FAILURE; +} diff --git a/src/readahead/readahead-collect.c b/src/readahead/readahead-collect.c new file mode 100644 index 000000000..5d07f4704 --- /dev/null +++ b/src/readahead/readahead-collect.c @@ -0,0 +1,623 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_FANOTIFY_INIT +#include +#endif + +#include + +#include "missing.h" +#include "util.h" +#include "set.h" +#include "ioprio.h" +#include "readahead-common.h" +#include "virt.h" + +/* fixme: + * + * - detect ssd on btrfs/lvm... + * - read ahead directories + * - gzip? + * - remount rw? + * - handle files where nothing is in mincore + * - does ioprio_set work with fadvise()? + */ + +static ReadaheadShared *shared = NULL; + +/* Avoid collisions with the NULL pointer */ +#define SECTOR_TO_PTR(s) ULONG_TO_PTR((s)+1) +#define PTR_TO_SECTOR(p) (PTR_TO_ULONG(p)-1) + +static int btrfs_defrag(int fd) { + struct btrfs_ioctl_vol_args data; + + zero(data); + data.fd = fd; + + return ioctl(fd, BTRFS_IOC_DEFRAG, &data); +} + +static int pack_file(FILE *pack, const char *fn, bool on_btrfs) { + struct stat st; + void *start = MAP_FAILED; + uint8_t *vec; + uint32_t b, c; + uint64_t inode; + size_t l, pages; + bool mapped; + int r = 0, fd = -1, k; + + assert(pack); + assert(fn); + + fd = open(fn, O_RDONLY|O_CLOEXEC|O_NOATIME|O_NOCTTY|O_NOFOLLOW); + if (fd < 0) { + + if (errno == ENOENT) + return 0; + + if (errno == EPERM || errno == EACCES) + return 0; + + log_warning("open(%s) failed: %m", fn); + r = -errno; + goto finish; + } + + k = file_verify(fd, fn, arg_file_size_max, &st); + if (k <= 0) { + r = k; + goto finish; + } + + if (on_btrfs) + btrfs_defrag(fd); + + l = PAGE_ALIGN(st.st_size); + start = mmap(NULL, l, PROT_READ, MAP_SHARED, fd, 0); + if (start == MAP_FAILED) { + log_warning("mmap(%s) failed: %m", fn); + r = -errno; + goto finish; + } + + pages = l / page_size(); + vec = alloca(pages); + memset(vec, 0, pages); + if (mincore(start, l, vec) < 0) { + log_warning("mincore(%s) failed: %m", fn); + r = -errno; + goto finish; + } + + fputs(fn, pack); + fputc('\n', pack); + + /* Store the inode, so that we notice when the file is deleted */ + inode = (uint64_t) st.st_ino; + fwrite(&inode, sizeof(inode), 1, pack); + + mapped = false; + for (c = 0; c < pages; c++) { + bool new_mapped = !!(vec[c] & 1); + + if (!mapped && new_mapped) + b = c; + else if (mapped && !new_mapped) { + fwrite(&b, sizeof(b), 1, pack); + fwrite(&c, sizeof(c), 1, pack); + + log_debug("%s: page %u to %u", fn, b, c); + } + + mapped = new_mapped; + } + + /* We don't write any range data if we should read the entire file */ + if (mapped && b > 0) { + fwrite(&b, sizeof(b), 1, pack); + fwrite(&c, sizeof(c), 1, pack); + + log_debug("%s: page %u to %u", fn, b, c); + } + + /* End marker */ + b = 0; + fwrite(&b, sizeof(b), 1, pack); + fwrite(&b, sizeof(b), 1, pack); + +finish: + if (start != MAP_FAILED) + munmap(start, l); + + if (fd >= 0) + close_nointr_nofail(fd); + + return r; +} + +static unsigned long fd_first_block(int fd) { + struct { + struct fiemap fiemap; + struct fiemap_extent extent; + } data; + + zero(data); + data.fiemap.fm_length = ~0ULL; + data.fiemap.fm_extent_count = 1; + + if (ioctl(fd, FS_IOC_FIEMAP, &data) < 0) + return 0; + + if (data.fiemap.fm_mapped_extents <= 0) + return 0; + + if (data.fiemap.fm_extents[0].fe_flags & FIEMAP_EXTENT_UNKNOWN) + return 0; + + return (unsigned long) data.fiemap.fm_extents[0].fe_physical; +} + +struct item { + const char *path; + unsigned long block; +}; + +static int qsort_compare(const void *a, const void *b) { + const struct item *i, *j; + + i = a; + j = b; + + if (i->block < j->block) + return -1; + if (i->block > j->block) + return 1; + + return strcmp(i->path, j->path); +} + +static int collect(const char *root) { + enum { + FD_FANOTIFY, /* Get the actual fs events */ + FD_SIGNAL, + FD_INOTIFY, /* We get notifications to quit early via this fd */ + _FD_MAX + }; + struct pollfd pollfd[_FD_MAX]; + int fanotify_fd = -1, signal_fd = -1, inotify_fd = -1, r = 0; + pid_t my_pid; + Hashmap *files = NULL; + Iterator i; + char *p, *q; + sigset_t mask; + FILE *pack = NULL; + char *pack_fn_new = NULL, *pack_fn = NULL; + bool on_ssd, on_btrfs; + struct statfs sfs; + usec_t not_after; + uint64_t previous_block_readahead; + bool previous_block_readahead_set = false; + + assert(root); + + if (asprintf(&pack_fn, "%s/.readahead", root) < 0) { + r = log_oom(); + goto finish; + } + + /* If there's no pack file yet we lower the kernel readahead + * so that mincore() is accurate. If there is a pack file + * already we assume it is accurate enough so that kernel + * readahead is never triggered. */ + previous_block_readahead_set = + access(pack_fn, F_OK) < 0 && + block_get_readahead(root, &previous_block_readahead) >= 0 && + block_set_readahead(root, 8*1024) >= 0; + + if (ioprio_set(IOPRIO_WHO_PROCESS, getpid(), IOPRIO_PRIO_VALUE(IOPRIO_CLASS_IDLE, 0)) < 0) + log_warning("Failed to set IDLE IO priority class: %m"); + + assert_se(sigemptyset(&mask) == 0); + sigset_add_many(&mask, SIGINT, SIGTERM, -1); + assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0); + + if ((signal_fd = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC)) < 0) { + log_error("signalfd(): %m"); + r = -errno; + goto finish; + } + + if (!(files = hashmap_new(string_hash_func, string_compare_func))) { + log_error("Failed to allocate set."); + r = -ENOMEM; + goto finish; + } + + if ((fanotify_fd = fanotify_init(FAN_CLOEXEC|FAN_NONBLOCK, O_RDONLY|O_LARGEFILE|O_CLOEXEC|O_NOATIME)) < 0) { + log_error("Failed to create fanotify object: %m"); + r = -errno; + goto finish; + } + + if (fanotify_mark(fanotify_fd, FAN_MARK_ADD|FAN_MARK_MOUNT, FAN_OPEN, AT_FDCWD, root) < 0) { + log_error("Failed to mark %s: %m", root); + r = -errno; + goto finish; + } + + if ((inotify_fd = open_inotify()) < 0) { + r = inotify_fd; + goto finish; + } + + not_after = now(CLOCK_MONOTONIC) + arg_timeout; + + my_pid = getpid(); + + zero(pollfd); + pollfd[FD_FANOTIFY].fd = fanotify_fd; + pollfd[FD_FANOTIFY].events = POLLIN; + pollfd[FD_SIGNAL].fd = signal_fd; + pollfd[FD_SIGNAL].events = POLLIN; + pollfd[FD_INOTIFY].fd = inotify_fd; + pollfd[FD_INOTIFY].events = POLLIN; + + sd_notify(0, + "READY=1\n" + "STATUS=Collecting readahead data"); + + log_debug("Collecting..."); + + if (access("/run/systemd/readahead/cancel", F_OK) >= 0) { + log_debug("Collection canceled"); + r = -ECANCELED; + goto finish; + } + + if (access("/run/systemd/readahead/done", F_OK) >= 0) { + log_debug("Got termination request"); + goto done; + } + + for (;;) { + union { + struct fanotify_event_metadata metadata; + char buffer[4096]; + } data; + ssize_t n; + struct fanotify_event_metadata *m; + usec_t t; + int h; + + if (hashmap_size(files) > arg_files_max) { + log_debug("Reached maximum number of read ahead files, ending collection."); + break; + } + + t = now(CLOCK_MONOTONIC); + if (t >= not_after) { + log_debug("Reached maximum collection time, ending collection."); + break; + } + + if ((h = poll(pollfd, _FD_MAX, (int) ((not_after - t) / USEC_PER_MSEC))) < 0) { + + if (errno == EINTR) + continue; + + log_error("poll(): %m"); + r = -errno; + goto finish; + } + + if (h == 0) { + log_debug("Reached maximum collection time, ending collection."); + break; + } + + if (pollfd[FD_SIGNAL].revents) { + log_debug("Got signal."); + break; + } + + if (pollfd[FD_INOTIFY].revents) { + uint8_t inotify_buffer[sizeof(struct inotify_event) + FILENAME_MAX]; + struct inotify_event *e; + + if ((n = read(inotify_fd, &inotify_buffer, sizeof(inotify_buffer))) < 0) { + if (errno == EINTR || errno == EAGAIN) + continue; + + log_error("Failed to read inotify event: %m"); + r = -errno; + goto finish; + } + + e = (struct inotify_event*) inotify_buffer; + while (n > 0) { + size_t step; + + if ((e->mask & IN_CREATE) && streq(e->name, "cancel")) { + log_debug("Collection canceled"); + r = -ECANCELED; + goto finish; + } + + if ((e->mask & IN_CREATE) && streq(e->name, "done")) { + log_debug("Got termination request"); + goto done; + } + + step = sizeof(struct inotify_event) + e->len; + assert(step <= (size_t) n); + + e = (struct inotify_event*) ((uint8_t*) e + step); + n -= step; + } + } + + if ((n = read(fanotify_fd, &data, sizeof(data))) < 0) { + + if (errno == EINTR || errno == EAGAIN) + continue; + + /* fanotify sometimes returns EACCES on read() + * where it shouldn't. For now let's just + * ignore it here (which is safe), but + * eventually this should be + * dropped when the kernel is fixed. + * + * https://bugzilla.redhat.com/show_bug.cgi?id=707577 */ + if (errno == EACCES) + continue; + + log_error("Failed to read event: %m"); + r = -errno; + goto finish; + } + + for (m = &data.metadata; FAN_EVENT_OK(m, n); m = FAN_EVENT_NEXT(m, n)) { + char fn[PATH_MAX]; + int k; + + if (m->fd < 0) + goto next_iteration; + + if (m->pid == my_pid) + goto next_iteration; + + __sync_synchronize(); + if (m->pid == shared->replay) + goto next_iteration; + + snprintf(fn, sizeof(fn), "/proc/self/fd/%i", m->fd); + char_array_0(fn); + + if ((k = readlink_malloc(fn, &p)) >= 0) { + if (startswith(p, "/tmp") || + endswith(p, " (deleted)") || + hashmap_get(files, p)) + /* Not interesting, or + * already read */ + free(p); + else { + unsigned long ul; + + ul = fd_first_block(m->fd); + + if ((k = hashmap_put(files, p, SECTOR_TO_PTR(ul))) < 0) { + log_warning("set_put() failed: %s", strerror(-k)); + free(p); + } + } + + } else + log_warning("readlink(%s) failed: %s", fn, strerror(-k)); + + next_iteration: + if (m->fd >= 0) + close_nointr_nofail(m->fd); + } + } + +done: + if (fanotify_fd >= 0) { + close_nointr_nofail(fanotify_fd); + fanotify_fd = -1; + } + + log_debug("Writing Pack File..."); + + on_ssd = fs_on_ssd(root) > 0; + log_debug("On SSD: %s", yes_no(on_ssd)); + + on_btrfs = statfs(root, &sfs) >= 0 && (long) sfs.f_type == (long) BTRFS_SUPER_MAGIC; + log_debug("On btrfs: %s", yes_no(on_btrfs)); + + if (asprintf(&pack_fn_new, "%s/.readahead.new", root) < 0) { + r = log_oom(); + goto finish; + } + + pack = fopen(pack_fn_new, "we"); + if (!pack) { + log_error("Failed to open pack file: %m"); + r = -errno; + goto finish; + } + + fputs(CANONICAL_HOST READAHEAD_PACK_FILE_VERSION, pack); + putc(on_ssd ? 'S' : 'R', pack); + + if (on_ssd || on_btrfs) { + + /* On SSD or on btrfs, just write things out in the + * order the files were accessed. */ + + HASHMAP_FOREACH_KEY(q, p, files, i) + pack_file(pack, p, on_btrfs); + } else { + struct item *ordered, *j; + unsigned k, n; + + /* On rotating media, order things by the block + * numbers */ + + log_debug("Ordering..."); + + n = hashmap_size(files); + if (!(ordered = new(struct item, n))) { + r = log_oom(); + goto finish; + } + + j = ordered; + HASHMAP_FOREACH_KEY(q, p, files, i) { + j->path = p; + j->block = PTR_TO_SECTOR(q); + j++; + } + + assert(ordered + n == j); + + qsort(ordered, n, sizeof(struct item), qsort_compare); + + for (k = 0; k < n; k++) + pack_file(pack, ordered[k].path, on_btrfs); + + free(ordered); + } + + log_debug("Finalizing..."); + + fflush(pack); + + if (ferror(pack)) { + log_error("Failed to write pack file."); + r = -EIO; + goto finish; + } + + if (rename(pack_fn_new, pack_fn) < 0) { + log_error("Failed to rename readahead file: %m"); + r = -errno; + goto finish; + } + + fclose(pack); + pack = NULL; + + log_debug("Done."); + +finish: + if (fanotify_fd >= 0) + close_nointr_nofail(fanotify_fd); + + if (signal_fd >= 0) + close_nointr_nofail(signal_fd); + + if (inotify_fd >= 0) + close_nointr_nofail(inotify_fd); + + if (pack) { + fclose(pack); + unlink(pack_fn_new); + } + free(pack_fn_new); + free(pack_fn); + + while ((p = hashmap_steal_first_key(files))) + free(p); + + hashmap_free(files); + + if (previous_block_readahead_set) { + uint64_t bytes; + + /* Restore the original kernel readahead setting if we + * changed it, and nobody has overwritten it since + * yet. */ + if (block_get_readahead(root, &bytes) >= 0 && bytes == 8*1024) + block_set_readahead(root, previous_block_readahead); + } + + return r; +} + +int main_collect(const char *root) { + + if (!root) + root = "/"; + + /* Skip this step on read-only media. Note that we check the + * underlying block device here, not he read-only flag of the + * file system on top, since that one is most likely mounted + * read-only anyway at boot, even if the underlying block + * device is theoretically writable. */ + if (fs_on_read_only(root) > 0) { + log_info("Disabling readahead collector due to read-only media."); + return EXIT_SUCCESS; + } + + if (!enough_ram()) { + log_info("Disabling readahead collector due to low memory."); + return EXIT_SUCCESS; + } + + shared = shared_get(); + if (!shared) + return EXIT_FAILURE; + + shared->collect = getpid(); + __sync_synchronize(); + + if (collect(root) < 0) + return EXIT_FAILURE; + + return EXIT_SUCCESS; +} diff --git a/src/readahead/readahead-common.c b/src/readahead/readahead-common.c new file mode 100644 index 000000000..41aaff0a3 --- /dev/null +++ b/src/readahead/readahead-common.c @@ -0,0 +1,410 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "log.h" +#include "readahead-common.h" +#include "util.h" +#include "missing.h" + +int file_verify(int fd, const char *fn, off_t file_size_max, struct stat *st) { + assert(fd >= 0); + assert(fn); + assert(st); + + if (fstat(fd, st) < 0) { + log_warning("fstat(%s) failed: %m", fn); + return -errno; + } + + if (!S_ISREG(st->st_mode)) { + log_debug("Not preloading special file %s", fn); + return 0; + } + + if (st->st_size <= 0 || st->st_size > file_size_max) { + log_debug("Not preloading file %s with size out of bounds %llu", fn, (unsigned long long) st->st_size); + return 0; + } + + return 1; +} + +int fs_on_ssd(const char *p) { + struct stat st; + struct udev *udev = NULL; + struct udev_device *udev_device = NULL, *look_at = NULL; + bool b = false; + const char *devtype, *rotational, *model, *id; + int r; + + assert(p); + + if (stat(p, &st) < 0) + return -errno; + + if (major(st.st_dev) == 0) { + _cleanup_fclose_ FILE *f = NULL; + int mount_id; + struct file_handle *h; + + /* Might be btrfs, which exposes "ssd" as mount flag if it is on ssd. + * + * We first determine the mount ID here, if we can, + * and then lookup the mount ID in mountinfo to find + * the mount options. */ + + h = alloca(MAX_HANDLE_SZ); + h->handle_bytes = MAX_HANDLE_SZ; + r = name_to_handle_at(AT_FDCWD, p, h, &mount_id, AT_SYMLINK_FOLLOW); + if (r < 0) + return false; + + f = fopen("/proc/self/mountinfo", "re"); + if (!f) + return false; + + for (;;) { + char line[LINE_MAX], *e; + _cleanup_free_ char *opts = NULL; + int mid; + + if (!fgets(line, sizeof(line), f)) + return false; + + truncate_nl(line); + + if (sscanf(line, "%i", &mid) != 1) + continue; + + if (mid != mount_id) + continue; + + e = strstr(line, " - "); + if (!e) + continue; + + if (sscanf(e+3, "%*s %*s %ms", &opts) != 1) + continue; + + if (streq(opts, "ssd") || startswith(opts, "ssd,") || endswith(opts, ",ssd") || strstr(opts, ",ssd,")) + return true; + } + + return false; + } + + udev = udev_new(); + if (!udev) + return -ENOMEM; + + udev_device = udev_device_new_from_devnum(udev, 'b', st.st_dev); + if (!udev_device) + goto finish; + + devtype = udev_device_get_property_value(udev_device, "DEVTYPE"); + if (devtype && streq(devtype, "partition")) + look_at = udev_device_get_parent(udev_device); + else + look_at = udev_device; + + if (!look_at) + goto finish; + + /* First, try high-level property */ + id = udev_device_get_property_value(look_at, "ID_SSD"); + if (id) { + b = streq(id, "1"); + goto finish; + } + + /* Second, try kernel attribute */ + rotational = udev_device_get_sysattr_value(look_at, "queue/rotational"); + if (rotational) { + b = streq(rotational, "0"); + goto finish; + } + + /* Finally, fallback to heuristics */ + look_at = udev_device_get_parent(look_at); + if (!look_at) + goto finish; + + model = udev_device_get_sysattr_value(look_at, "model"); + if (model) + b = !!strstr(model, "SSD"); + +finish: + if (udev_device) + udev_device_unref(udev_device); + + if (udev) + udev_unref(udev); + + return b; +} + +int fs_on_read_only(const char *p) { + struct stat st; + struct udev *udev = NULL; + struct udev_device *udev_device = NULL; + bool b = false; + const char *read_only; + + assert(p); + + if (stat(p, &st) < 0) + return -errno; + + if (major(st.st_dev) == 0) + return false; + + if (!(udev = udev_new())) + return -ENOMEM; + + if (!(udev_device = udev_device_new_from_devnum(udev, 'b', st.st_dev))) + goto finish; + + if ((read_only = udev_device_get_sysattr_value(udev_device, "ro"))) + if ((b = streq(read_only, "1"))) + goto finish; + +finish: + if (udev_device) + udev_device_unref(udev_device); + + if (udev) + udev_unref(udev); + + return b; +} + +bool enough_ram(void) { + struct sysinfo si; + + assert_se(sysinfo(&si) >= 0); + + /* Enable readahead only with at least 128MB memory */ + return si.totalram > 127 * 1024*1024 / si.mem_unit; +} + +int open_inotify(void) { + int fd; + + if ((fd = inotify_init1(IN_CLOEXEC|IN_NONBLOCK)) < 0) { + log_error("Failed to create inotify handle: %m"); + return -errno; + } + + mkdir("/run/systemd", 0755); + mkdir("/run/systemd/readahead", 0755); + + if (inotify_add_watch(fd, "/run/systemd/readahead", IN_CREATE) < 0) { + log_error("Failed to watch /run/systemd/readahead: %m"); + close_nointr_nofail(fd); + return -errno; + } + + return fd; +} + +ReadaheadShared *shared_get(void) { + int fd; + ReadaheadShared *m = NULL; + + mkdir("/run/systemd", 0755); + mkdir("/run/systemd/readahead", 0755); + + if ((fd = open("/run/systemd/readahead/shared", O_CREAT|O_RDWR|O_CLOEXEC, 0644)) < 0) { + log_error("Failed to create shared memory segment: %m"); + goto finish; + } + + if (ftruncate(fd, sizeof(ReadaheadShared)) < 0) { + log_error("Failed to truncate shared memory segment: %m"); + goto finish; + } + + if ((m = mmap(NULL, sizeof(ReadaheadShared), PROT_WRITE|PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED) { + log_error("Failed to mmap shared memory segment: %m"); + m = NULL; + goto finish; + } + +finish: + if (fd >= 0) + close_nointr_nofail(fd); + + return m; +} + +/* We use 20K instead of the more human digestable 16K here. Why? + Simply so that it is more unlikely that users end up picking this + value too so that we can recognize better whether the user changed + the value while we had it temporarily bumped. */ +#define BUMP_REQUEST_NR (20*1024) + +int block_bump_request_nr(const char *p) { + struct stat st; + uint64_t u; + char *ap = NULL, *line = NULL; + int r; + dev_t d; + + assert(p); + + if (stat(p, &st) < 0) + return -errno; + + if (major(st.st_dev) == 0) + return 0; + + d = st.st_dev; + block_get_whole_disk(d, &d); + + if (asprintf(&ap, "/sys/dev/block/%u:%u/queue/nr_requests", major(d), minor(d)) < 0) { + r= -ENOMEM; + goto finish; + } + + r = read_one_line_file(ap, &line); + if (r < 0) { + if (r == -ENOENT) + r = 0; + goto finish; + } + + r = safe_atou64(line, &u); + if (r >= 0 && u >= BUMP_REQUEST_NR) { + r = 0; + goto finish; + } + + free(line); + line = NULL; + + if (asprintf(&line, "%lu", (unsigned long) BUMP_REQUEST_NR) < 0) { + r = -ENOMEM; + goto finish; + } + + r = write_one_line_file(ap, line); + if (r < 0) + goto finish; + + log_info("Bumped block_nr parameter of %u:%u to %lu. This is a temporary hack and should be removed one day.", major(d), minor(d), (unsigned long) BUMP_REQUEST_NR); + r = 1; + +finish: + free(ap); + free(line); + + return r; +} + +int block_get_readahead(const char *p, uint64_t *bytes) { + struct stat st; + char *ap = NULL, *line = NULL; + int r; + dev_t d; + uint64_t u; + + assert(p); + assert(bytes); + + if (stat(p, &st) < 0) + return -errno; + + if (major(st.st_dev) == 0) + return 0; + + d = st.st_dev; + block_get_whole_disk(d, &d); + + if (asprintf(&ap, "/sys/dev/block/%u:%u/bdi/read_ahead_kb", major(d), minor(d)) < 0) { + r = -ENOMEM; + goto finish; + } + + r = read_one_line_file(ap, &line); + if (r < 0) + goto finish; + + r = safe_atou64(line, &u); + if (r < 0) + goto finish; + + *bytes = u * 1024ULL; + +finish: + free(ap); + free(line); + + return r; +} + +int block_set_readahead(const char *p, uint64_t bytes) { + struct stat st; + char *ap = NULL, *line = NULL; + int r; + dev_t d; + + assert(p); + assert(bytes); + + if (stat(p, &st) < 0) + return -errno; + + if (major(st.st_dev) == 0) + return 0; + + d = st.st_dev; + block_get_whole_disk(d, &d); + + if (asprintf(&ap, "/sys/dev/block/%u:%u/bdi/read_ahead_kb", major(d), minor(d)) < 0) { + r = -ENOMEM; + goto finish; + } + + if (asprintf(&line, "%llu", (unsigned long long) bytes / 1024ULL) < 0) { + r = -ENOMEM; + goto finish; + } + + r = write_one_line_file(ap, line); + if (r < 0) + goto finish; + +finish: + free(ap); + free(line); + + return r; +} diff --git a/src/readahead/readahead-common.h b/src/readahead/readahead-common.h new file mode 100644 index 000000000..b34f3aadd --- /dev/null +++ b/src/readahead/readahead-common.h @@ -0,0 +1,61 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +#include +#include + +#include "macro.h" +#include "util.h" + +#define READAHEAD_FILE_SIZE_MAX (10*1024*1024) + +#define READAHEAD_PACK_FILE_VERSION ";VERSION=2\n" + +extern unsigned arg_files_max; +extern off_t arg_file_size_max; +extern usec_t arg_timeout; + +int file_verify(int fd, const char *fn, off_t file_size_max, struct stat *st); + +int fs_on_ssd(const char *p); +int fs_on_read_only(const char *p); + +bool enough_ram(void); + +int open_inotify(void); + +typedef struct ReadaheadShared { + pid_t collect; + pid_t replay; +} _packed_ ReadaheadShared; + +ReadaheadShared *shared_get(void); + +int block_bump_request_nr(const char *p); + +int block_get_readahead(const char *p, uint64_t *bytes); +int block_set_readahead(const char *p, uint64_t bytes); + +int main_collect(const char *root); +int main_replay(const char *root); +int main_analyze(const char *pack_path); diff --git a/src/readahead/readahead-replay.c b/src/readahead/readahead-replay.c new file mode 100644 index 000000000..cb04e5f9c --- /dev/null +++ b/src/readahead/readahead-replay.c @@ -0,0 +1,311 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "missing.h" +#include "util.h" +#include "set.h" +#include "ioprio.h" +#include "readahead-common.h" +#include "virt.h" + +static ReadaheadShared *shared = NULL; + +static int unpack_file(FILE *pack) { + char fn[PATH_MAX]; + int r = 0, fd = -1; + bool any = false; + struct stat st; + uint64_t inode; + + assert(pack); + + if (!fgets(fn, sizeof(fn), pack)) + return 0; + + char_array_0(fn); + truncate_nl(fn); + + fd = open(fn, O_RDONLY|O_CLOEXEC|O_NOATIME|O_NOCTTY|O_NOFOLLOW); + if (fd < 0) { + + if (errno != ENOENT && errno != EPERM && errno != EACCES && errno != ELOOP) + log_warning("open(%s) failed: %m", fn); + + } else if (file_verify(fd, fn, arg_file_size_max, &st) <= 0) { + close_nointr_nofail(fd); + fd = -1; + } + + if (fread(&inode, sizeof(inode), 1, pack) != 1) { + log_error("Premature end of pack file."); + r = -EIO; + goto finish; + } + + if (fd >= 0) { + /* If the inode changed the file got deleted, so just + * ignore this entry */ + if (st.st_ino != (uint64_t) inode) { + close_nointr_nofail(fd); + fd = -1; + } + } + + for (;;) { + uint32_t b, c; + + if (fread(&b, sizeof(b), 1, pack) != 1 || + fread(&c, sizeof(c), 1, pack) != 1) { + log_error("Premature end of pack file."); + r = -EIO; + goto finish; + } + + if (b == 0 && c == 0) + break; + + if (c <= b) { + log_error("Invalid pack file."); + r = -EIO; + goto finish; + } + + log_debug("%s: page %u to %u", fn, b, c); + + any = true; + + if (fd >= 0) + if (posix_fadvise(fd, b * page_size(), (c - b) * page_size(), POSIX_FADV_WILLNEED) < 0) { + log_warning("posix_fadvise() failed: %m"); + goto finish; + } + } + + if (!any && fd >= 0) { + /* if no range is encoded in the pack file this is + * intended to mean that the whole file shall be + * read */ + + if (posix_fadvise(fd, 0, st.st_size, POSIX_FADV_WILLNEED) < 0) { + log_warning("posix_fadvise() failed: %m"); + goto finish; + } + } + +finish: + if (fd >= 0) + close_nointr_nofail(fd); + + return r; +} + +static int replay(const char *root) { + FILE *pack = NULL; + char line[LINE_MAX]; + int r = 0; + char *pack_fn = NULL; + int c; + bool on_ssd, ready = false; + int prio; + int inotify_fd = -1; + + assert(root); + + block_bump_request_nr(root); + + if (asprintf(&pack_fn, "%s/.readahead", root) < 0) { + r = log_oom(); + goto finish; + } + + pack = fopen(pack_fn, "re"); + if (!pack) { + if (errno == ENOENT) + log_debug("No pack file found."); + else { + log_error("Failed to open pack file: %m"); + r = -errno; + } + + goto finish; + } + + posix_fadvise(fileno(pack), 0, 0, POSIX_FADV_WILLNEED); + + if ((inotify_fd = open_inotify()) < 0) { + r = inotify_fd; + goto finish; + } + + if (!(fgets(line, sizeof(line), pack))) { + log_error("Premature end of pack file."); + r = -EIO; + goto finish; + } + + char_array_0(line); + + if (!streq(line, CANONICAL_HOST READAHEAD_PACK_FILE_VERSION)) { + log_debug("Pack file host or version type mismatch."); + goto finish; + } + + if ((c = getc(pack)) == EOF) { + log_debug("Premature end of pack file."); + r = -EIO; + goto finish; + } + + /* We do not retest SSD here, so that we can start replaying + * before udev is up.*/ + on_ssd = c == 'S'; + log_debug("On SSD: %s", yes_no(on_ssd)); + + if (on_ssd) + prio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_IDLE, 0); + else + /* We are not using RT here, since we'd starve IO that + we didn't record (which is for example blkid, since + its disk accesses go directly to the block device and + are thus not visible in fallocate) to death. However, + we do ask for an IO prio that is slightly higher than + the default (which is BE. 4) */ + prio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 2); + + if (ioprio_set(IOPRIO_WHO_PROCESS, getpid(), prio) < 0) + log_warning("Failed to set IDLE IO priority class: %m"); + + sd_notify(0, "STATUS=Replaying readahead data"); + + log_debug("Replaying..."); + + if (access("/run/systemd/readahead/noreplay", F_OK) >= 0) { + log_debug("Got termination request"); + goto done; + } + + while (!feof(pack) && !ferror(pack)) { + uint8_t inotify_buffer[sizeof(struct inotify_event) + FILENAME_MAX]; + int k; + ssize_t n; + + if ((n = read(inotify_fd, &inotify_buffer, sizeof(inotify_buffer))) < 0) { + if (errno != EINTR && errno != EAGAIN) { + log_error("Failed to read inotify event: %m"); + r = -errno; + goto finish; + } + } else { + struct inotify_event *e = (struct inotify_event*) inotify_buffer; + + while (n > 0) { + size_t step; + + if ((e->mask & IN_CREATE) && streq(e->name, "noreplay")) { + log_debug("Got termination request"); + goto done; + } + + step = sizeof(struct inotify_event) + e->len; + assert(step <= (size_t) n); + + e = (struct inotify_event*) ((uint8_t*) e + step); + n -= step; + } + } + + if ((k = unpack_file(pack)) < 0) { + r = k; + goto finish; + } + + if (!ready) { + /* We delay the ready notification until we + * queued at least one read */ + sd_notify(0, "READY=1"); + ready = true; + } + } + +done: + if (!ready) + sd_notify(0, "READY=1"); + + if (ferror(pack)) { + log_error("Failed to read pack file."); + r = -EIO; + goto finish; + } + + log_debug("Done."); + +finish: + if (pack) + fclose(pack); + + if (inotify_fd >= 0) + close_nointr_nofail(inotify_fd); + + free(pack_fn); + + return r; +} + +int main_replay(const char *root) { + + if (!root) + root = "/"; + + if (!enough_ram()) { + log_info("Disabling readahead replay due to low memory."); + return EXIT_SUCCESS; + } + + shared = shared_get(); + if (!shared) + return EXIT_FAILURE; + + shared->replay = getpid(); + __sync_synchronize(); + + if (replay(root) < 0) + return EXIT_FAILURE; + + return EXIT_SUCCESS; +} diff --git a/src/readahead/readahead.c b/src/readahead/readahead.c new file mode 100644 index 000000000..abeecc763 --- /dev/null +++ b/src/readahead/readahead.c @@ -0,0 +1,158 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include + +#include "util.h" +#include "def.h" +#include "readahead-common.h" + +unsigned arg_files_max = 16*1024; +off_t arg_file_size_max = READAHEAD_FILE_SIZE_MAX; +usec_t arg_timeout = 2*USEC_PER_MINUTE; + +static int help(void) { + + printf("%s [OPTIONS...] collect [DIRECTORY]\n\n" + "Collect read-ahead data on early boot.\n\n" + " -h --help Show this help\n" + " --max-files=INT Maximum number of files to read ahead\n" + " --file-size-max=BYTES Maximum size of files to read ahead\n" + " --timeout=USEC Maximum time to spend collecting data\n\n\n", + program_invocation_short_name); + + printf("%s [OPTIONS...] replay [DIRECTORY]\n\n" + "Replay collected read-ahead data on early boot.\n\n" + " -h --help Show this help\n" + " --file-size-max=BYTES Maximum size of files to read ahead\n\n\n", + program_invocation_short_name); + + printf("%s [OPTIONS...] analyze [PACK FILE]\n\n" + "Analyze collected read-ahead data.\n\n" + " -h --help Show this help\n", + program_invocation_short_name); + + return 0; +} + +static int parse_argv(int argc, char *argv[]) { + + enum { + ARG_FILES_MAX = 0x100, + ARG_FILE_SIZE_MAX, + ARG_TIMEOUT + }; + + static const struct option options[] = { + { "help", no_argument, NULL, 'h' }, + { "files-max", required_argument, NULL, ARG_FILES_MAX }, + { "file-size-max", required_argument, NULL, ARG_FILE_SIZE_MAX }, + { "timeout", required_argument, NULL, ARG_TIMEOUT }, + { NULL, 0, NULL, 0 } + }; + + int c; + + assert(argc >= 0); + assert(argv); + + while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) { + + switch (c) { + + case 'h': + help(); + return 0; + + case ARG_FILES_MAX: + if (safe_atou(optarg, &arg_files_max) < 0 || arg_files_max <= 0) { + log_error("Failed to parse maximum number of files %s.", optarg); + return -EINVAL; + } + break; + + case ARG_FILE_SIZE_MAX: { + unsigned long long ull; + + if (safe_atollu(optarg, &ull) < 0 || ull <= 0) { + log_error("Failed to parse maximum file size %s.", optarg); + return -EINVAL; + } + + arg_file_size_max = (off_t) ull; + break; + } + + case ARG_TIMEOUT: + if (parse_usec(optarg, &arg_timeout) < 0 || arg_timeout <= 0) { + log_error("Failed to parse timeout %s.", optarg); + return -EINVAL; + } + + break; + + case '?': + return -EINVAL; + + default: + log_error("Unknown option code %c", c); + return -EINVAL; + } + } + + if (optind != argc-1 && + optind != argc-2) { + help(); + return -EINVAL; + } + + return 1; +} + +int main(int argc, char *argv[]) { + int r; + + log_set_target(LOG_TARGET_SAFE); + log_parse_environment(); + log_open(); + + umask(0022); + + r = parse_argv(argc, argv); + if (r <= 0) + return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; + + if (streq(argv[optind], "collect")) + return main_collect(argv[optind+1]); + else if (streq(argv[optind], "replay")) + return main_replay(argv[optind+1]); + else if (streq(argv[optind], "analyze")) + return main_analyze(argv[optind+1]); + + log_error("Unknown verb %s.", argv[optind]); + return EXIT_FAILURE; +} diff --git a/src/readahead/sd-readahead.c b/src/readahead/sd-readahead.c new file mode 100644 index 000000000..d48cd7680 --- /dev/null +++ b/src/readahead/sd-readahead.c @@ -0,0 +1,89 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + Copyright 2010 Lennart Poettering + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation files + (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +***/ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +#include +#include +#include +#include +#include +#include + +#include "sd-readahead.h" + +#if (__GNUC__ >= 4) +#ifdef SD_EXPORT_SYMBOLS +/* Export symbols */ +#define _sd_export_ __attribute__ ((visibility("default"))) +#else +/* Don't export the symbols */ +#define _sd_export_ __attribute__ ((visibility("hidden"))) +#endif +#else +#define _sd_export_ +#endif + +static int touch(const char *path) { + +#if !defined(DISABLE_SYSTEMD) && defined(__linux__) + int fd; + + mkdir("/run/systemd", 0755); + mkdir("/run/systemd/readahead", 0755); + + fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY, 0666); + if (fd < 0) + return -errno; + + for (;;) { + if (close(fd) >= 0) + break; + + if (errno != -EINTR) + return -errno; + } + +#endif + return 0; +} + +_sd_export_ int sd_readahead(const char *action) { + + if (!action) + return -EINVAL; + + if (strcmp(action, "cancel") == 0) + return touch("/run/systemd/readahead/cancel"); + else if (strcmp(action, "done") == 0) + return touch("/run/systemd/readahead/done"); + else if (strcmp(action, "noreplay") == 0) + return touch("/run/systemd/readahead/noreplay"); + + return -EINVAL; +} diff --git a/src/remount-fs/Makefile b/src/remount-fs/Makefile new file mode 120000 index 000000000..d0b0e8e00 --- /dev/null +++ b/src/remount-fs/Makefile @@ -0,0 +1 @@ +../Makefile \ No newline at end of file diff --git a/src/remount-fs/remount-fs.c b/src/remount-fs/remount-fs.c new file mode 100644 index 000000000..b49d095cb --- /dev/null +++ b/src/remount-fs/remount-fs.c @@ -0,0 +1,170 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include + +#include "log.h" +#include "util.h" +#include "path-util.h" +#include "set.h" +#include "mount-setup.h" +#include "exit-status.h" + +/* Goes through /etc/fstab and remounts all API file systems, applying + * options that are in /etc/fstab that systemd might not have + * respected */ + +int main(int argc, char *argv[]) { + int ret = EXIT_FAILURE; + FILE *f = NULL; + struct mntent* me; + Hashmap *pids = NULL; + + if (argc > 1) { + log_error("This program takes no argument."); + return EXIT_FAILURE; + } + + log_set_target(LOG_TARGET_AUTO); + log_parse_environment(); + log_open(); + + umask(0022); + + f = setmntent("/etc/fstab", "r"); + if (!f) { + if (errno == ENOENT) { + ret = EXIT_SUCCESS; + goto finish; + } + + log_error("Failed to open /etc/fstab: %m"); + goto finish; + } + + pids = hashmap_new(trivial_hash_func, trivial_compare_func); + if (!pids) { + log_error("Failed to allocate set"); + goto finish; + } + + ret = EXIT_SUCCESS; + + while ((me = getmntent(f))) { + pid_t pid; + int k; + char *s; + + /* Remount the root fs, /usr and all API VFS */ + if (!mount_point_is_api(me->mnt_dir) && + !path_equal(me->mnt_dir, "/") && + !path_equal(me->mnt_dir, "/usr")) + continue; + + log_debug("Remounting %s", me->mnt_dir); + + pid = fork(); + if (pid < 0) { + log_error("Failed to fork: %m"); + ret = EXIT_FAILURE; + continue; + } + + if (pid == 0) { + const char *arguments[5]; + /* Child */ + + arguments[0] = "/bin/mount"; + arguments[1] = me->mnt_dir; + arguments[2] = "-o"; + arguments[3] = "remount"; + arguments[4] = NULL; + + execv("/bin/mount", (char **) arguments); + + log_error("Failed to execute /bin/mount: %m"); + _exit(EXIT_FAILURE); + } + + /* Parent */ + + s = strdup(me->mnt_dir); + if (!s) { + log_oom(); + ret = EXIT_FAILURE; + continue; + } + + + k = hashmap_put(pids, UINT_TO_PTR(pid), s); + if (k < 0) { + log_error("Failed to add PID to set: %s", strerror(-k)); + ret = EXIT_FAILURE; + continue; + } + } + + while (!hashmap_isempty(pids)) { + siginfo_t si; + char *s; + + zero(si); + if (waitid(P_ALL, 0, &si, WEXITED) < 0) { + + if (errno == EINTR) + continue; + + log_error("waitid() failed: %m"); + ret = EXIT_FAILURE; + break; + } + + s = hashmap_remove(pids, UINT_TO_PTR(si.si_pid)); + if (s) { + if (!is_clean_exit(si.si_code, si.si_status, NULL)) { + if (si.si_code == CLD_EXITED) + log_error("/bin/mount for %s exited with exit status %i.", s, si.si_status); + else + log_error("/bin/mount for %s terminated by signal %s.", s, signal_to_string(si.si_status)); + + ret = EXIT_FAILURE; + } + + free(s); + } + } + +finish: + + if (pids) + hashmap_free_free(pids); + + if (f) + endmntent(f); + + return ret; +} diff --git a/src/reply-password/Makefile b/src/reply-password/Makefile new file mode 120000 index 000000000..d0b0e8e00 --- /dev/null +++ b/src/reply-password/Makefile @@ -0,0 +1 @@ +../Makefile \ No newline at end of file diff --git a/src/reply-password/reply-password.c b/src/reply-password/reply-password.c new file mode 100644 index 000000000..a935d0f08 --- /dev/null +++ b/src/reply-password/reply-password.c @@ -0,0 +1,109 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "log.h" +#include "macro.h" +#include "util.h" + +static int send_on_socket(int fd, const char *socket_name, const void *packet, size_t size) { + union { + struct sockaddr sa; + struct sockaddr_un un; + } sa; + + assert(fd >= 0); + assert(socket_name); + assert(packet); + + zero(sa); + sa.un.sun_family = AF_UNIX; + strncpy(sa.un.sun_path, socket_name, sizeof(sa.un.sun_path)); + + if (sendto(fd, packet, size, MSG_NOSIGNAL, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(socket_name)) < 0) { + log_error("Failed to send: %m"); + return -1; + } + + return 0; +} + +int main(int argc, char *argv[]) { + int fd = -1, r = EXIT_FAILURE; + char packet[LINE_MAX]; + size_t length; + + log_set_target(LOG_TARGET_AUTO); + log_parse_environment(); + log_open(); + + if (argc != 3) { + log_error("Wrong number of arguments."); + goto finish; + } + + if (streq(argv[1], "1")) { + + packet[0] = '+'; + if (!fgets(packet+1, sizeof(packet)-1, stdin)) { + log_error("Failed to read password: %m"); + goto finish; + } + + truncate_nl(packet+1); + length = 1 + strlen(packet+1) + 1; + } else if (streq(argv[1], "0")) { + packet[0] = '-'; + length = 1; + } else { + log_error("Invalid first argument %s", argv[1]); + goto finish; + } + + if ((fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0)) < 0) { + log_error("socket() failed: %m"); + goto finish; + } + + if (send_on_socket(fd, argv[2], packet, length) < 0) + goto finish; + + r = EXIT_SUCCESS; + +finish: + if (fd >= 0) + close_nointr_nofail(fd); + + return r; +} diff --git a/src/shared/Makefile b/src/shared/Makefile new file mode 120000 index 000000000..d0b0e8e00 --- /dev/null +++ b/src/shared/Makefile @@ -0,0 +1 @@ +../Makefile \ No newline at end of file diff --git a/src/shared/acl-util.c b/src/shared/acl-util.c new file mode 100644 index 000000000..d1eb6f226 --- /dev/null +++ b/src/shared/acl-util.c @@ -0,0 +1,68 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +#include +#include +#include +#include +#include + +#include "acl-util.h" + +int acl_find_uid(acl_t acl, uid_t uid, acl_entry_t *entry) { + acl_entry_t i; + int found; + + assert(acl); + assert(entry); + + for (found = acl_get_entry(acl, ACL_FIRST_ENTRY, &i); + found > 0; + found = acl_get_entry(acl, ACL_NEXT_ENTRY, &i)) { + + acl_tag_t tag; + uid_t *u; + bool b; + + if (acl_get_tag_type(i, &tag) < 0) + return -errno; + + if (tag != ACL_USER) + continue; + + u = acl_get_qualifier(i); + if (!u) + return -errno; + + b = *u == uid; + acl_free(u); + + if (b) { + *entry = i; + return 1; + } + } + + if (found < 0) + return -errno; + + return 0; +} diff --git a/src/shared/acl-util.h b/src/shared/acl-util.h new file mode 100644 index 000000000..31fbbcd51 --- /dev/null +++ b/src/shared/acl-util.h @@ -0,0 +1,24 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +int acl_find_uid(acl_t acl, uid_t uid, acl_entry_t *entry); diff --git a/src/shared/ask-password-api.c b/src/shared/ask-password-api.c new file mode 100644 index 000000000..8a0fb89a8 --- /dev/null +++ b/src/shared/ask-password-api.c @@ -0,0 +1,576 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "util.h" +#include "mkdir.h" +#include "strv.h" + +#include "ask-password-api.h" + +static void backspace_chars(int ttyfd, size_t p) { + + if (ttyfd < 0) + return; + + while (p > 0) { + p--; + + loop_write(ttyfd, "\b \b", 3, false); + } +} + +int ask_password_tty( + const char *message, + usec_t until, + const char *flag_file, + char **_passphrase) { + + struct termios old_termios, new_termios; + char passphrase[LINE_MAX]; + size_t p = 0; + int r, ttyfd = -1, notify = -1; + struct pollfd pollfd[2]; + bool reset_tty = false; + bool silent_mode = false; + bool dirty = false; + enum { + POLL_TTY, + POLL_INOTIFY + }; + + assert(message); + assert(_passphrase); + + if (flag_file) { + if ((notify = inotify_init1(IN_CLOEXEC|IN_NONBLOCK)) < 0) { + r = -errno; + goto finish; + } + + if (inotify_add_watch(notify, flag_file, IN_ATTRIB /* for the link count */) < 0) { + r = -errno; + goto finish; + } + } + + if ((ttyfd = open("/dev/tty", O_RDWR|O_NOCTTY|O_CLOEXEC)) >= 0) { + + if (tcgetattr(ttyfd, &old_termios) < 0) { + r = -errno; + goto finish; + } + + loop_write(ttyfd, ANSI_HIGHLIGHT_ON, sizeof(ANSI_HIGHLIGHT_ON)-1, false); + loop_write(ttyfd, message, strlen(message), false); + loop_write(ttyfd, " ", 1, false); + loop_write(ttyfd, ANSI_HIGHLIGHT_OFF, sizeof(ANSI_HIGHLIGHT_OFF)-1, false); + + new_termios = old_termios; + new_termios.c_lflag &= ~(ICANON|ECHO); + new_termios.c_cc[VMIN] = 1; + new_termios.c_cc[VTIME] = 0; + + if (tcsetattr(ttyfd, TCSADRAIN, &new_termios) < 0) { + r = -errno; + goto finish; + } + + reset_tty = true; + } + + zero(pollfd); + + pollfd[POLL_TTY].fd = ttyfd >= 0 ? ttyfd : STDIN_FILENO; + pollfd[POLL_TTY].events = POLLIN; + pollfd[POLL_INOTIFY].fd = notify; + pollfd[POLL_INOTIFY].events = POLLIN; + + for (;;) { + char c; + int sleep_for = -1, k; + ssize_t n; + + if (until > 0) { + usec_t y; + + y = now(CLOCK_MONOTONIC); + + if (y > until) { + r = -ETIME; + goto finish; + } + + sleep_for = (int) ((until - y) / USEC_PER_MSEC); + } + + if (flag_file) + if (access(flag_file, F_OK) < 0) { + r = -errno; + goto finish; + } + + if ((k = poll(pollfd, notify > 0 ? 2 : 1, sleep_for)) < 0) { + + if (errno == EINTR) + continue; + + r = -errno; + goto finish; + } else if (k == 0) { + r = -ETIME; + goto finish; + } + + if (notify > 0 && pollfd[POLL_INOTIFY].revents != 0) + flush_fd(notify); + + if (pollfd[POLL_TTY].revents == 0) + continue; + + if ((n = read(ttyfd >= 0 ? ttyfd : STDIN_FILENO, &c, 1)) < 0) { + + if (errno == EINTR || errno == EAGAIN) + continue; + + r = -errno; + goto finish; + + } else if (n == 0) + break; + + if (c == '\n') + break; + else if (c == 21) { /* C-u */ + + if (!silent_mode) + backspace_chars(ttyfd, p); + p = 0; + + } else if (c == '\b' || c == 127) { + + if (p > 0) { + + if (!silent_mode) + backspace_chars(ttyfd, 1); + + p--; + } else if (!dirty && !silent_mode) { + + silent_mode = true; + + /* There are two ways to enter silent + * mode. Either by pressing backspace + * as first key (and only as first key), + * or ... */ + if (ttyfd >= 0) + loop_write(ttyfd, "(no echo) ", 10, false); + + } else if (ttyfd >= 0) + loop_write(ttyfd, "\a", 1, false); + + } else if (c == '\t' && !silent_mode) { + + backspace_chars(ttyfd, p); + silent_mode = true; + + /* ... or by pressing TAB at any time. */ + + if (ttyfd >= 0) + loop_write(ttyfd, "(no echo) ", 10, false); + } else { + passphrase[p++] = c; + + if (!silent_mode && ttyfd >= 0) + loop_write(ttyfd, "*", 1, false); + + dirty = true; + } + } + + passphrase[p] = 0; + + if (!(*_passphrase = strdup(passphrase))) { + r = -ENOMEM; + goto finish; + } + + r = 0; + +finish: + if (notify >= 0) + close_nointr_nofail(notify); + + if (ttyfd >= 0) { + + if (reset_tty) { + loop_write(ttyfd, "\n", 1, false); + tcsetattr(ttyfd, TCSADRAIN, &old_termios); + } + + close_nointr_nofail(ttyfd); + } + + return r; +} + +static int create_socket(char **name) { + int fd; + union { + struct sockaddr sa; + struct sockaddr_un un; + } sa; + int one = 1, r; + char *c; + mode_t u; + + assert(name); + + if ((fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0)) < 0) { + log_error("socket() failed: %m"); + return -errno; + } + + zero(sa); + sa.un.sun_family = AF_UNIX; + snprintf(sa.un.sun_path, sizeof(sa.un.sun_path)-1, "/run/systemd/ask-password/sck.%llu", random_ull()); + + u = umask(0177); + r = bind(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)); + umask(u); + + if (r < 0) { + r = -errno; + log_error("bind() failed: %m"); + goto fail; + } + + if (setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one)) < 0) { + r = -errno; + log_error("SO_PASSCRED failed: %m"); + goto fail; + } + + if (!(c = strdup(sa.un.sun_path))) { + r = log_oom(); + goto fail; + } + + *name = c; + return fd; + +fail: + close_nointr_nofail(fd); + + return r; +} + +int ask_password_agent( + const char *message, + const char *icon, + usec_t until, + bool accept_cached, + char ***_passphrases) { + + enum { + FD_SOCKET, + FD_SIGNAL, + _FD_MAX + }; + + char temp[] = "/run/systemd/ask-password/tmp.XXXXXX"; + char final[sizeof(temp)] = ""; + int fd = -1, r; + FILE *f = NULL; + char *socket_name = NULL; + int socket_fd = -1, signal_fd = -1; + sigset_t mask, oldmask; + struct pollfd pollfd[_FD_MAX]; + mode_t u; + + assert(_passphrases); + + assert_se(sigemptyset(&mask) == 0); + sigset_add_many(&mask, SIGINT, SIGTERM, -1); + assert_se(sigprocmask(SIG_BLOCK, &mask, &oldmask) == 0); + + mkdir_p_label("/run/systemd/ask-password", 0755); + + u = umask(0022); + fd = mkostemp(temp, O_CLOEXEC|O_CREAT|O_WRONLY); + umask(u); + + if (fd < 0) { + log_error("Failed to create password file: %m"); + r = -errno; + goto finish; + } + + fchmod(fd, 0644); + + if (!(f = fdopen(fd, "w"))) { + log_error("Failed to allocate FILE: %m"); + r = -errno; + goto finish; + } + + fd = -1; + + if ((signal_fd = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC)) < 0) { + log_error("signalfd(): %m"); + r = -errno; + goto finish; + } + + if ((socket_fd = create_socket(&socket_name)) < 0) { + r = socket_fd; + goto finish; + } + + fprintf(f, + "[Ask]\n" + "PID=%lu\n" + "Socket=%s\n" + "AcceptCached=%i\n" + "NotAfter=%llu\n", + (unsigned long) getpid(), + socket_name, + accept_cached ? 1 : 0, + (unsigned long long) until); + + if (message) + fprintf(f, "Message=%s\n", message); + + if (icon) + fprintf(f, "Icon=%s\n", icon); + + fflush(f); + + if (ferror(f)) { + log_error("Failed to write query file: %m"); + r = -errno; + goto finish; + } + + memcpy(final, temp, sizeof(temp)); + + final[sizeof(final)-11] = 'a'; + final[sizeof(final)-10] = 's'; + final[sizeof(final)-9] = 'k'; + + if (rename(temp, final) < 0) { + log_error("Failed to rename query file: %m"); + r = -errno; + goto finish; + } + + zero(pollfd); + pollfd[FD_SOCKET].fd = socket_fd; + pollfd[FD_SOCKET].events = POLLIN; + pollfd[FD_SIGNAL].fd = signal_fd; + pollfd[FD_SIGNAL].events = POLLIN; + + for (;;) { + char passphrase[LINE_MAX+1]; + struct msghdr msghdr; + struct iovec iovec; + struct ucred *ucred; + union { + struct cmsghdr cmsghdr; + uint8_t buf[CMSG_SPACE(sizeof(struct ucred))]; + } control; + ssize_t n; + int k; + usec_t t; + + t = now(CLOCK_MONOTONIC); + + if (until > 0 && until <= t) { + log_notice("Timed out"); + r = -ETIME; + goto finish; + } + + if ((k = poll(pollfd, _FD_MAX, until > 0 ? (int) ((until-t)/USEC_PER_MSEC) : -1)) < 0) { + + if (errno == EINTR) + continue; + + log_error("poll() failed: %m"); + r = -errno; + goto finish; + } + + if (k <= 0) { + log_notice("Timed out"); + r = -ETIME; + goto finish; + } + + if (pollfd[FD_SIGNAL].revents & POLLIN) { + r = -EINTR; + goto finish; + } + + if (pollfd[FD_SOCKET].revents != POLLIN) { + log_error("Unexpected poll() event."); + r = -EIO; + goto finish; + } + + zero(iovec); + iovec.iov_base = passphrase; + iovec.iov_len = sizeof(passphrase); + + zero(control); + zero(msghdr); + msghdr.msg_iov = &iovec; + msghdr.msg_iovlen = 1; + msghdr.msg_control = &control; + msghdr.msg_controllen = sizeof(control); + + if ((n = recvmsg(socket_fd, &msghdr, 0)) < 0) { + + if (errno == EAGAIN || + errno == EINTR) + continue; + + log_error("recvmsg() failed: %m"); + r = -errno; + goto finish; + } + + if (n <= 0) { + log_error("Message too short"); + continue; + } + + if (msghdr.msg_controllen < CMSG_LEN(sizeof(struct ucred)) || + control.cmsghdr.cmsg_level != SOL_SOCKET || + control.cmsghdr.cmsg_type != SCM_CREDENTIALS || + control.cmsghdr.cmsg_len != CMSG_LEN(sizeof(struct ucred))) { + log_warning("Received message without credentials. Ignoring."); + continue; + } + + ucred = (struct ucred*) CMSG_DATA(&control.cmsghdr); + if (ucred->uid != 0) { + log_warning("Got request from unprivileged user. Ignoring."); + continue; + } + + if (passphrase[0] == '+') { + char **l; + + if (n == 1) + l = strv_new("", NULL); + else + l = strv_parse_nulstr(passphrase+1, n-1); + /* An empty message refers to the empty password */ + + if (!l) { + r = -ENOMEM; + goto finish; + } + + if (strv_length(l) <= 0) { + strv_free(l); + log_error("Invalid packet"); + continue; + } + + *_passphrases = l; + + } else if (passphrase[0] == '-') { + r = -ECANCELED; + goto finish; + } else { + log_error("Invalid packet"); + continue; + } + + break; + } + + r = 0; + +finish: + if (fd >= 0) + close_nointr_nofail(fd); + + if (socket_name) { + unlink(socket_name); + free(socket_name); + } + + if (socket_fd >= 0) + close_nointr_nofail(socket_fd); + + if (signal_fd >= 0) + close_nointr_nofail(signal_fd); + + if (f) + fclose(f); + + unlink(temp); + + if (final[0]) + unlink(final); + + assert_se(sigprocmask(SIG_SETMASK, &oldmask, NULL) == 0); + + return r; +} + +int ask_password_auto(const char *message, const char *icon, usec_t until, bool accept_cached, char ***_passphrases) { + assert(message); + assert(_passphrases); + + if (isatty(STDIN_FILENO)) { + int r; + char *s = NULL, **l = NULL; + + if ((r = ask_password_tty(message, until, NULL, &s)) < 0) + return r; + + l = strv_new(s, NULL); + free(s); + + if (!l) + return -ENOMEM; + + *_passphrases = l; + return r; + + } else + return ask_password_agent(message, icon, until, accept_cached, _passphrases); +} diff --git a/src/shared/ask-password-api.h b/src/shared/ask-password-api.h new file mode 100644 index 000000000..288a0f48c --- /dev/null +++ b/src/shared/ask-password-api.h @@ -0,0 +1,30 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +#include "util.h" + +int ask_password_tty(const char *message, usec_t until, const char *flag_file, char **_passphrase); + +int ask_password_agent(const char *message, const char *icon, usec_t until, bool accept_cached, char ***_passphrases); + +int ask_password_auto(const char *message, const char *icon, usec_t until, bool accept_cached, char ***_passphrases); diff --git a/src/shared/audit.c b/src/shared/audit.c new file mode 100644 index 000000000..e5c483ab0 --- /dev/null +++ b/src/shared/audit.c @@ -0,0 +1,118 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "macro.h" +#include "audit.h" +#include "util.h" +#include "log.h" + +int audit_session_from_pid(pid_t pid, uint32_t *id) { + char *s; + uint32_t u; + int r; + + assert(id); + + if (have_effective_cap(CAP_AUDIT_CONTROL) <= 0) + return -ENOENT; + + if (pid == 0) + r = read_one_line_file("/proc/self/sessionid", &s); + else { + char *p; + + if (asprintf(&p, "/proc/%lu/sessionid", (unsigned long) pid) < 0) + return -ENOMEM; + + r = read_one_line_file(p, &s); + free(p); + } + + if (r < 0) + return r; + + r = safe_atou32(s, &u); + free(s); + + if (r < 0) + return r; + + if (u == (uint32_t) -1 || u <= 0) + return -ENOENT; + + *id = u; + return 0; +} + +int audit_loginuid_from_pid(pid_t pid, uid_t *uid) { + char *s; + uid_t u; + int r; + + assert(uid); + + /* Only use audit login uid if we are executed with sufficient + * capabilities so that pam_loginuid could do its job. If we + * are lacking the CAP_AUDIT_CONTROL capabality we most likely + * are being run in a container and /proc/self/loginuid is + * useless since it probably contains a uid of the host + * system. */ + + if (have_effective_cap(CAP_AUDIT_CONTROL) <= 0) + return -ENOENT; + + if (pid == 0) + r = read_one_line_file("/proc/self/loginuid", &s); + else { + char *p; + + if (asprintf(&p, "/proc/%lu/loginuid", (unsigned long) pid) < 0) + return -ENOMEM; + + r = read_one_line_file(p, &s); + free(p); + } + + if (r < 0) + return r; + + r = parse_uid(s, &u); + free(s); + + if (r < 0) + return r; + + if (u == (uid_t) -1) + return -ENOENT; + + *uid = (uid_t) u; + return 0; +} diff --git a/src/shared/audit.h b/src/shared/audit.h new file mode 100644 index 000000000..490a0b032 --- /dev/null +++ b/src/shared/audit.h @@ -0,0 +1,32 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef fooaudithfoo +#define fooaudithfoo + +/*** + 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 . +***/ + +#include + +#include "capability.h" + +int audit_session_from_pid(pid_t pid, uint32_t *id); +int audit_loginuid_from_pid(pid_t pid, uid_t *uid); + +#endif diff --git a/src/shared/calendarspec.c b/src/shared/calendarspec.c new file mode 100644 index 000000000..c2eae3f13 --- /dev/null +++ b/src/shared/calendarspec.c @@ -0,0 +1,927 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + +#include +#include + +#include "calendarspec.h" + +static void free_chain(CalendarComponent *c) { + CalendarComponent *n; + + while (c) { + n = c->next; + free(c); + c = n; + } +} + +void calendar_spec_free(CalendarSpec *c) { + assert(c); + + free_chain(c->year); + free_chain(c->month); + free_chain(c->day); + free_chain(c->hour); + free_chain(c->minute); + free_chain(c->second); + + free(c); +} + +static int component_compare(const void *_a, const void *_b) { + CalendarComponent * const *a = _a, * const *b = _b; + + if ((*a)->value < (*b)->value) + return -1; + if ((*a)->value > (*b)->value) + return 1; + + if ((*a)->repeat < (*b)->repeat) + return -1; + if ((*a)->repeat > (*b)->repeat) + return 1; + + return 0; +} + +static void sort_chain(CalendarComponent **c) { + unsigned n = 0, k; + CalendarComponent **b, *i, **j, *next; + + assert(c); + + for (i = *c; i; i = i->next) + n++; + + if (n <= 1) + return; + + j = b = alloca(sizeof(CalendarComponent*) * n); + for (i = *c; i; i = i->next) + *(j++) = i; + + qsort(b, n, sizeof(CalendarComponent*), component_compare); + + b[n-1]->next = NULL; + next = b[n-1]; + + /* Drop non-unique entries */ + for (k = n-1; k > 0; k--) { + if (b[k-1]->value == next->value && + b[k-1]->repeat == next->repeat) { + free(b[k-1]); + continue; + } + + b[k-1]->next = next; + next = b[k-1]; + } + + *c = next; +} + +static void fix_year(CalendarComponent *c) { + /* Turns 12 → 2012, 89 → 1989 */ + + while(c) { + CalendarComponent *n = c->next; + + if (c->value >= 0 && c->value < 70) + c->value += 2000; + + if (c->value >= 70 && c->value < 100) + c->value += 1900; + + c = n; + } +} + +int calendar_spec_normalize(CalendarSpec *c) { + assert(c); + + if (c->weekdays_bits <= 0 || c->weekdays_bits >= 127) + c->weekdays_bits = -1; + + fix_year(c->year); + + sort_chain(&c->year); + sort_chain(&c->month); + sort_chain(&c->day); + sort_chain(&c->hour); + sort_chain(&c->minute); + sort_chain(&c->second); + + return 0; +} + +static bool chain_valid(CalendarComponent *c, int from, int to) { + if (!c) + return true; + + if (c->value < from || c->value > to) + return false; + + if (c->value + c->repeat > to) + return false; + + if (c->next) + return chain_valid(c->next, from, to); + + return true; +} + +bool calendar_spec_valid(CalendarSpec *c) { + assert(c); + + if (c->weekdays_bits > 127) + return false; + + if (!chain_valid(c->year, 1970, 2199)) + return false; + + if (!chain_valid(c->month, 1, 12)) + return false; + + if (!chain_valid(c->day, 1, 31)) + return false; + + if (!chain_valid(c->hour, 0, 23)) + return false; + + if (!chain_valid(c->minute, 0, 59)) + return false; + + if (!chain_valid(c->second, 0, 59)) + return false; + + return true; +} + +static void format_weekdays(FILE *f, const CalendarSpec *c) { + static const char *const days[] = { + "Mon", + "Tue", + "Wed", + "Thu", + "Fri", + "Sat", + "Sun" + }; + + int l, x; + bool need_colon = false; + + assert(f); + assert(c); + assert(c->weekdays_bits > 0 && c->weekdays_bits <= 127); + + for (x = 0, l = -1; x < (int) ELEMENTSOF(days); x++) { + + if (c->weekdays_bits & (1 << x)) { + + if (l < 0) { + if (need_colon) + fputc(',', f); + else + need_colon = true; + + fputs(days[x], f); + l = x; + } + + } else if (l >= 0) { + + if (x > l + 1) { + fputc(x > l + 2 ? '-' : ',', f); + fputs(days[x-1], f); + } + + l = -1; + } + } + + if (l >= 0 && x > l + 1) { + fputc(x > l + 2 ? '-' : ',', f); + fputs(days[x-1], f); + } +} + +static void format_chain(FILE *f, int space, const CalendarComponent *c) { + assert(f); + + if (!c) { + fputc('*', f); + return; + } + + assert(c->value >= 0); + fprintf(f, "%0*i", space, c->value); + + if (c->repeat > 0) + fprintf(f, "/%i", c->repeat); + + if (c->next) { + fputc(',', f); + format_chain(f, space, c->next); + } +} + +int calendar_spec_to_string(const CalendarSpec *c, char **p) { + char *buf = NULL; + size_t sz = 0; + FILE *f; + + assert(c); + assert(p); + + f = open_memstream(&buf, &sz); + if (!f) + return -ENOMEM; + + if (c->weekdays_bits > 0 && c->weekdays_bits <= 127) { + format_weekdays(f, c); + fputc(' ', f); + } + + format_chain(f, 4, c->year); + fputc('-', f); + format_chain(f, 2, c->month); + fputc('-', f); + format_chain(f, 2, c->day); + fputc(' ', f); + format_chain(f, 2, c->hour); + fputc(':', f); + format_chain(f, 2, c->minute); + fputc(':', f); + format_chain(f, 2, c->second); + + fflush(f); + + if (ferror(f)) { + free(buf); + fclose(f); + return -ENOMEM; + } + + fclose(f); + + *p = buf; + return 0; +} + +static int parse_weekdays(const char **p, CalendarSpec *c) { + static const struct { + const char *name; + const int nr; + } day_nr[] = { + { "Monday", 0 }, + { "Mon", 0 }, + { "Tuesday", 1 }, + { "Tue", 1 }, + { "Wednesday", 2 }, + { "Wed", 2 }, + { "Thursday", 3 }, + { "Thu", 3 }, + { "Friday", 4 }, + { "Fri", 4 }, + { "Saturday", 5 }, + { "Sat", 5 }, + { "Sunday", 6 }, + { "Sun", 6 } + }; + + int l = -1; + bool first = true; + + assert(p); + assert(*p); + assert(c); + + for (;;) { + unsigned i; + + if (!first && **p == ' ') + return 0; + + for (i = 0; i < ELEMENTSOF(day_nr); i++) { + size_t skip; + + if (!startswith_no_case(*p, day_nr[i].name)) + continue; + + skip = strlen(day_nr[i].name); + + if ((*p)[skip] != '-' && + (*p)[skip] != ',' && + (*p)[skip] != ' ' && + (*p)[skip] != 0) + return -EINVAL; + + c->weekdays_bits |= 1 << day_nr[i].nr; + + if (l >= 0) { + int j; + + if (l > day_nr[i].nr) + return -EINVAL; + + for (j = l + 1; j < day_nr[i].nr; j++) + c->weekdays_bits |= 1 << j; + } + + *p += skip; + break; + } + + /* Couldn't find this prefix, so let's assume the + weekday was not specified and let's continue with + the date */ + if (i >= ELEMENTSOF(day_nr)) + return first ? 0 : -EINVAL; + + /* We reached the end of the string */ + if (**p == 0) + return 0; + + /* We reached the end of the weekday spec part */ + if (**p == ' ') { + *p += strspn(*p, " "); + return 0; + } + + if (**p == '-') { + if (l >= 0) + return -EINVAL; + + l = day_nr[i].nr; + } else + l = -1; + + *p += 1; + first = false; + } +} + +static int prepend_component(const char **p, CalendarComponent **c) { + unsigned long value, repeat = 0; + char *e = NULL, *ee = NULL; + CalendarComponent *cc; + + assert(p); + assert(c); + + errno = 0; + value = strtoul(*p, &e, 10); + if (errno != 0) + return -errno; + if (e == *p) + return -EINVAL; + if ((unsigned long) (int) value != value) + return -ERANGE; + + if (*e == '/') { + repeat = strtoul(e+1, &ee, 10); + if (errno != 0) + return -errno; + if (ee == e+1) + return -EINVAL; + if ((unsigned long) (int) repeat != repeat) + return -ERANGE; + if (repeat <= 0) + return -ERANGE; + + e = ee; + } + + if (*e != 0 && *e != ' ' && *e != ',' && *e != '-' && *e != ':') + return -EINVAL; + + cc = new0(CalendarComponent, 1); + if (!cc) + return -ENOMEM; + + cc->value = value; + cc->repeat = repeat; + cc->next = *c; + + *p = e; + *c = cc; + + if (*e ==',') { + *p += 1; + return prepend_component(p, c); + } + + return 0; +} + +static int parse_chain(const char **p, CalendarComponent **c) { + const char *t; + CalendarComponent *cc = NULL; + int r; + + assert(p); + assert(c); + + t = *p; + + if (t[0] == '*') { + *p = t + 1; + *c = NULL; + return 0; + } + + r = prepend_component(&t, &cc); + if (r < 0) { + free_chain(cc); + return r; + } + + *p = t; + *c = cc; + return 0; +} + +static int const_chain(int value, CalendarComponent **c) { + CalendarComponent *cc = NULL; + + assert(c); + + cc = new0(CalendarComponent, 1); + if (!cc) + return -ENOMEM; + + cc->value = value; + cc->repeat = 0; + cc->next = NULL; + + *c = cc; + + return 0; +} + +static int parse_date(const char **p, CalendarSpec *c) { + const char *t; + int r; + CalendarComponent *first, *second, *third; + + assert(p); + assert(*p); + assert(c); + + t = *p; + + if (*t == 0) + return 0; + + r = parse_chain(&t, &first); + if (r < 0) + return r; + + /* Already the end? A ':' as separator? In that case this was a time, not a date */ + if (*t == 0 || *t == ':') { + free_chain(first); + return 0; + } + + if (*t != '-') { + free_chain(first); + return -EINVAL; + } + + t++; + r = parse_chain(&t, &second); + if (r < 0) { + free_chain(first); + return r; + } + + /* Got two parts, hence it's month and day */ + if (*t == ' ' || *t == 0) { + *p = t + strspn(t, " "); + c->month = first; + c->day = second; + return 0; + } + + if (*t != '-') { + free_chain(first); + free_chain(second); + return -EINVAL; + } + + t++; + r = parse_chain(&t, &third); + if (r < 0) { + free_chain(first); + free_chain(second); + return r; + } + + /* Got tree parts, hence it is year, month and day */ + if (*t == ' ' || *t == 0) { + *p = t + strspn(t, " "); + c->year = first; + c->month = second; + c->day = third; + return 0; + } + + free_chain(first); + free_chain(second); + free_chain(third); + return -EINVAL; +} + +static int parse_time(const char **p, CalendarSpec *c) { + CalendarComponent *h = NULL, *m = NULL, *s = NULL; + const char *t; + int r; + + assert(p); + assert(*p); + assert(c); + + t = *p; + + if (*t == 0) { + /* If no time is specified at all, but a date of some + * kind, then this means 00:00:00 */ + if (c->day || c->weekdays_bits > 0) + goto null_hour; + + goto finish; + } + + r = parse_chain(&t, &h); + if (r < 0) + goto fail; + + if (*t != ':') { + r = -EINVAL; + goto fail; + } + + t++; + r = parse_chain(&t, &m); + if (r < 0) + goto fail; + + /* Already at the end? Then it's hours and minutes, and seconds are 0 */ + if (*t == 0) { + if (m != NULL) + goto null_second; + + goto finish; + } + + if (*t != ':') { + r = -EINVAL; + goto fail; + } + + t++; + r = parse_chain(&t, &s); + if (r < 0) + goto fail; + + /* At the end? Then it's hours, minutes and seconds */ + if (*t == 0) + goto finish; + + r = -EINVAL; + goto fail; + +null_hour: + r = const_chain(0, &h); + if (r < 0) + goto fail; + + r = const_chain(0, &m); + if (r < 0) + goto fail; + +null_second: + r = const_chain(0, &s); + if (r < 0) + goto fail; + +finish: + *p = t; + c->hour = h; + c->minute = m; + c->second = s; + return 0; + +fail: + free_chain(h); + free_chain(m); + free_chain(s); + return r; +} + +int calendar_spec_from_string(const char *p, CalendarSpec **spec) { + CalendarSpec *c; + int r; + + assert(p); + assert(spec); + + if (isempty(p)) + return -EINVAL; + + c = new0(CalendarSpec, 1); + if (!c) + return -ENOMEM; + + if (strcasecmp(p, "hourly") == 0) { + r = const_chain(0, &c->minute); + if (r < 0) + goto fail; + r = const_chain(0, &c->second); + if (r < 0) + goto fail; + + } else if (strcasecmp(p, "daily") == 0) { + r = const_chain(0, &c->hour); + if (r < 0) + goto fail; + r = const_chain(0, &c->minute); + if (r < 0) + goto fail; + r = const_chain(0, &c->second); + if (r < 0) + goto fail; + + } else if (strcasecmp(p, "monthly") == 0) { + r = const_chain(1, &c->day); + if (r < 0) + goto fail; + r = const_chain(0, &c->hour); + if (r < 0) + goto fail; + r = const_chain(0, &c->minute); + if (r < 0) + goto fail; + r = const_chain(0, &c->second); + if (r < 0) + goto fail; + + } else if (strcasecmp(p, "weekly") == 0) { + + c->weekdays_bits = 1; + + r = const_chain(0, &c->hour); + if (r < 0) + goto fail; + r = const_chain(0, &c->minute); + if (r < 0) + goto fail; + r = const_chain(0, &c->second); + if (r < 0) + goto fail; + + } else { + r = parse_weekdays(&p, c); + if (r < 0) + goto fail; + + r = parse_date(&p, c); + if (r < 0) + goto fail; + + r = parse_time(&p, c); + if (r < 0) + goto fail; + + if (*p != 0) { + r = -EINVAL; + goto fail; + } + } + + r = calendar_spec_normalize(c); + if (r < 0) + goto fail; + + if (!calendar_spec_valid(c)) { + r = -EINVAL; + goto fail; + } + + *spec = c; + return 0; + +fail: + calendar_spec_free(c); + return r; +} + +static int find_matching_component(const CalendarComponent *c, int *val) { + const CalendarComponent *n; + int d = -1; + bool d_set = false; + int r; + + assert(val); + + if (!c) + return 0; + + while (c) { + n = c->next; + + if (c->value >= *val) { + + if (!d_set || c->value < d) { + d = c->value; + d_set = true; + } + + } else if (c->repeat > 0) { + int k; + + k = c->value + c->repeat * ((*val - c->value + c->repeat -1) / c->repeat); + + if (!d_set || k < d) { + d = k; + d_set = true; + } + } + + c = n; + } + + if (!d_set) + return -ENOENT; + + r = *val != d; + *val = d; + return r; +} + +static bool tm_out_of_bounds(const struct tm *tm) { + struct tm t; + assert(tm); + + t = *tm; + + if (mktime(&t) == (time_t) -1) + return true; + + /* Did any normalization take place? If so, it was out of bounds before */ + return + t.tm_year != tm->tm_year || + t.tm_mon != tm->tm_mon || + t.tm_mday != tm->tm_mday || + t.tm_hour != tm->tm_hour || + t.tm_min != tm->tm_min || + t.tm_sec != tm->tm_sec; +} + +static bool matches_weekday(int weekdays_bits, const struct tm *tm) { + struct tm t; + int k; + + if (weekdays_bits < 0 || weekdays_bits >= 127) + return true; + + t = *tm; + if (mktime(&t) == (time_t) -1) + return false; + + k = t.tm_wday == 0 ? 6 : t.tm_wday - 1; + return (weekdays_bits & (1 << k)); +} + +static int find_next(const CalendarSpec *spec, struct tm *tm) { + struct tm c; + int r; + + assert(spec); + assert(tm); + + c = *tm; + + for (;;) { + /* Normalize the current date */ + mktime(&c); + c.tm_isdst = -1; + + c.tm_year += 1900; + r = find_matching_component(spec->year, &c.tm_year); + c.tm_year -= 1900; + + if (r > 0) { + c.tm_mon = 0; + c.tm_mday = 1; + c.tm_hour = c.tm_min = c.tm_sec = 0; + } + if (r < 0 || tm_out_of_bounds(&c)) + return r; + + c.tm_mon += 1; + r = find_matching_component(spec->month, &c.tm_mon); + c.tm_mon -= 1; + + if (r > 0) { + c.tm_mday = 1; + c.tm_hour = c.tm_min = c.tm_sec = 0; + } + if (r < 0 || tm_out_of_bounds(&c)) { + c.tm_year ++; + c.tm_mon = 0; + c.tm_mday = 1; + c.tm_hour = c.tm_min = c.tm_sec = 0; + continue; + } + + r = find_matching_component(spec->day, &c.tm_mday); + if (r > 0) + c.tm_hour = c.tm_min = c.tm_sec = 0; + if (r < 0 || tm_out_of_bounds(&c)) { + c.tm_mon ++; + c.tm_mday = 1; + c.tm_hour = c.tm_min = c.tm_sec = 0; + continue; + } + + if (!matches_weekday(spec->weekdays_bits, &c)) { + c.tm_mday++; + c.tm_hour = c.tm_min = c.tm_sec = 0; + continue; + } + + r = find_matching_component(spec->hour, &c.tm_hour); + if (r > 0) + c.tm_min = c.tm_sec = 0; + if (r < 0 || tm_out_of_bounds(&c)) { + c.tm_mday ++; + c.tm_hour = c.tm_min = c.tm_sec = 0; + continue; + } + + r = find_matching_component(spec->minute, &c.tm_min); + if (r > 0) + c.tm_sec = 0; + if (r < 0 || tm_out_of_bounds(&c)) { + c.tm_hour ++; + c.tm_min = c.tm_sec = 0; + continue; + } + + r = find_matching_component(spec->second, &c.tm_sec); + if (r < 0 || tm_out_of_bounds(&c)) { + c.tm_min ++; + c.tm_sec = 0; + continue; + } + + + *tm = c; + return 0; + } +} + +int calendar_spec_next_usec(const CalendarSpec *spec, usec_t usec, usec_t *next) { + struct tm tm; + time_t t; + int r; + + assert(spec); + assert(next); + + t = (time_t) (usec / USEC_PER_SEC) + 1; + assert_se(localtime_r(&t, &tm)); + + r = find_next(spec, &tm); + if (r < 0) + return r; + + t = mktime(&tm); + if (t == (time_t) -1) + return -EINVAL; + + + *next = (usec_t) t * USEC_PER_SEC; + return 0; +} diff --git a/src/shared/calendarspec.h b/src/shared/calendarspec.h new file mode 100644 index 000000000..7baf31824 --- /dev/null +++ b/src/shared/calendarspec.h @@ -0,0 +1,57 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + +/* A structure for specifying (possibly repetitive) points in calendar + * time, a la cron */ + +#include +#include "util.h" + +typedef struct CalendarComponent { + int value; + int repeat; + + struct CalendarComponent *next; +} CalendarComponent; + +typedef struct CalendarSpec { + int weekdays_bits; + + CalendarComponent *year; + CalendarComponent *month; + CalendarComponent *day; + + CalendarComponent *hour; + CalendarComponent *minute; + CalendarComponent *second; +} CalendarSpec; + +void calendar_spec_free(CalendarSpec *c); + +int calendar_spec_normalize(CalendarSpec *spec); +bool calendar_spec_valid(CalendarSpec *spec); + +int calendar_spec_to_string(const CalendarSpec *spec, char **p); +int calendar_spec_from_string(const char *p, CalendarSpec **spec); + +int calendar_spec_next_usec(const CalendarSpec *spec, usec_t usec, usec_t *next); diff --git a/src/shared/capability.c b/src/shared/capability.c new file mode 100644 index 000000000..9b743e86d --- /dev/null +++ b/src/shared/capability.c @@ -0,0 +1,224 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "macro.h" +#include "capability.h" +#include "util.h" +#include "log.h" + +int have_effective_cap(int value) { + cap_t cap; + cap_flag_value_t fv; + int r; + + cap = cap_get_proc(); + if (!cap) + return -errno; + + if (cap_get_flag(cap, value, CAP_EFFECTIVE, &fv) < 0) + r = -errno; + else + r = fv == CAP_SET; + + cap_free(cap); + return r; +} + +unsigned long cap_last_cap(void) { + static __thread unsigned long saved; + static __thread bool valid = false; + unsigned long p; + + if (valid) + return saved; + + p = (unsigned long) CAP_LAST_CAP; + + if (prctl(PR_CAPBSET_READ, p) < 0) { + + /* Hmm, look downwards, until we find one that + * works */ + for (p--; p > 0; p --) + if (prctl(PR_CAPBSET_READ, p) >= 0) + break; + + } else { + + /* Hmm, look upwards, until we find one that doesn't + * work */ + for (;; p++) + if (prctl(PR_CAPBSET_READ, p+1) < 0) + break; + } + + saved = p; + valid = true; + + return p; +} + +int capability_bounding_set_drop(uint64_t drop, bool right_now) { + unsigned long i; + cap_t after_cap = NULL, temp_cap = NULL; + cap_flag_value_t fv; + int r; + + /* If we are run as PID 1 we will lack CAP_SETPCAP by default + * in the effective set (yes, the kernel drops that when + * executing init!), so get it back temporarily so that we can + * call PR_CAPBSET_DROP. */ + + after_cap = cap_get_proc(); + if (!after_cap) + return -errno; + + if (cap_get_flag(after_cap, CAP_SETPCAP, CAP_EFFECTIVE, &fv) < 0) { + cap_free(after_cap); + return -errno; + } + + if (fv != CAP_SET) { + static const cap_value_t v = CAP_SETPCAP; + + temp_cap = cap_dup(after_cap); + if (!temp_cap) { + r = -errno; + goto finish; + } + + if (cap_set_flag(temp_cap, CAP_EFFECTIVE, 1, &v, CAP_SET) < 0) { + r = -errno; + goto finish; + } + + if (cap_set_proc(temp_cap) < 0) { + r = -errno; + goto finish; + } + } + + for (i = 0; i <= cap_last_cap(); i++) { + + if (drop & ((uint64_t) 1ULL << (uint64_t) i)) { + cap_value_t v; + + /* Drop it from the bounding set */ + if (prctl(PR_CAPBSET_DROP, i) < 0) { + r = -errno; + goto finish; + } + v = i; + + /* Also drop it from the inheritable set, so + * that anything we exec() loses the + * capability for good. */ + if (cap_set_flag(after_cap, CAP_INHERITABLE, 1, &v, CAP_CLEAR) < 0) { + r = -errno; + goto finish; + } + + /* If we shall apply this right now drop it + * also from our own capability sets. */ + if (right_now) { + if (cap_set_flag(after_cap, CAP_PERMITTED, 1, &v, CAP_CLEAR) < 0 || + cap_set_flag(after_cap, CAP_EFFECTIVE, 1, &v, CAP_CLEAR) < 0) { + r = -errno; + goto finish; + } + } + } + } + + r = 0; + +finish: + if (temp_cap) + cap_free(temp_cap); + + if (after_cap) { + cap_set_proc(after_cap); + cap_free(after_cap); + } + + return r; +} + +static int drop_from_file(const char *fn, uint64_t drop) { + int r, k; + uint32_t hi, lo; + uint64_t current, after; + char *p; + + r = read_one_line_file(fn, &p); + if (r < 0) + return r; + + assert_cc(sizeof(hi) == sizeof(unsigned)); + assert_cc(sizeof(lo) == sizeof(unsigned)); + + k = sscanf(p, "%u %u", &lo, &hi); + free(p); + + if (k != 2) + return -EIO; + + current = (uint64_t) lo | ((uint64_t) hi << 32ULL); + after = current & ~drop; + + if (current == after) + return 0; + + lo = (unsigned) (after & 0xFFFFFFFFULL); + hi = (unsigned) ((after >> 32ULL) & 0xFFFFFFFFULL); + + if (asprintf(&p, "%u %u", lo, hi) < 0) + return -ENOMEM; + + r = write_one_line_file(fn, p); + free(p); + + return r; +} + +int capability_bounding_set_drop_usermode(uint64_t drop) { + int r; + + r = drop_from_file("/proc/sys/kernel/usermodehelper/inheritable", drop); + if (r < 0) + return r; + + r = drop_from_file("/proc/sys/kernel/usermodehelper/bset", drop); + if (r < 0) + return r; + + return r; +} diff --git a/src/shared/capability.h b/src/shared/capability.h new file mode 100644 index 000000000..6cb31bb51 --- /dev/null +++ b/src/shared/capability.h @@ -0,0 +1,33 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foocapabilityhfoo +#define foocapabilityhfoo + +/*** + 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 . +***/ + +#include +#include + +unsigned long cap_last_cap(void); +int have_effective_cap(int value); +int capability_bounding_set_drop(uint64_t drop, bool right_now); +int capability_bounding_set_drop_usermode(uint64_t drop); + +#endif diff --git a/src/shared/cgroup-label.c b/src/shared/cgroup-label.c new file mode 100644 index 000000000..beeeec583 --- /dev/null +++ b/src/shared/cgroup-label.c @@ -0,0 +1,82 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "cgroup-util.h" +#include "log.h" +#include "set.h" +#include "macro.h" +#include "util.h" +#include "mkdir.h" + +int cg_create(const char *controller, const char *path) { + char *fs; + int r; + + assert(controller); + assert(path); + + r = cg_get_path_and_check(controller, path, NULL, &fs); + if (r < 0) + return r; + + r = mkdir_parents_label(fs, 0755); + + if (r >= 0) { + if (mkdir(fs, 0755) >= 0) + r = 1; + else if (errno == EEXIST) + r = 0; + else + r = -errno; + } + + free(fs); + + return r; +} + +int cg_create_and_attach(const char *controller, const char *path, pid_t pid) { + int r, q; + + assert(controller); + assert(path); + assert(pid >= 0); + + if ((r = cg_create(controller, path)) < 0) + return r; + + if ((q = cg_attach(controller, path, pid)) < 0) + return q; + + /* This does not remove the cgroup on failure */ + + return r; +} diff --git a/src/shared/cgroup-show.c b/src/shared/cgroup-show.c new file mode 100644 index 000000000..2b79f370f --- /dev/null +++ b/src/shared/cgroup-show.c @@ -0,0 +1,347 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include + +#include "util.h" +#include "macro.h" +#include "path-util.h" +#include "cgroup-util.h" +#include "cgroup-show.h" + +static int compare(const void *a, const void *b) { + const pid_t *p = a, *q = b; + + if (*p < *q) + return -1; + if (*p > *q) + return 1; + return 0; +} + +static unsigned ilog10(unsigned long ul) { + int n = 0; + + while (ul > 0) { + n++; + ul /= 10; + } + + return n; +} + +static void show_pid_array(int pids[], unsigned n_pids, const char *prefix, unsigned n_columns, bool extra, bool more, bool kernel_threads) { + unsigned i, m, pid_width; + pid_t biggest = 0; + + /* Filter duplicates */ + m = 0; + for (i = 0; i < n_pids; i++) { + unsigned j; + + if (pids[i] > biggest) + biggest = pids[i]; + + for (j = i+1; j < n_pids; j++) + if (pids[i] == pids[j]) + break; + + if (j >= n_pids) + pids[m++] = pids[i]; + } + n_pids = m; + pid_width = ilog10(biggest); + + /* And sort */ + qsort(pids, n_pids, sizeof(pid_t), compare); + + if (n_columns > pid_width+2) + n_columns -= pid_width+2; + else + n_columns = 20; + + for (i = 0; i < n_pids; i++) { + char *t = NULL; + + get_process_cmdline(pids[i], n_columns, true, &t); + + printf("%s%s%*lu %s\n", + prefix, + draw_special_char(extra ? DRAW_TRIANGULAR_BULLET : + ((more || i < n_pids-1) ? DRAW_TREE_BRANCH : DRAW_TREE_RIGHT)), + pid_width, + (unsigned long) pids[i], + strna(t)); + + free(t); + } +} + + +static int show_cgroup_one_by_path(const char *path, const char *prefix, unsigned n_columns, bool more, bool kernel_threads) { + char *fn; + FILE *f; + size_t n = 0, n_allocated = 0; + pid_t *pids = NULL; + char *p; + pid_t pid; + int r; + + r = cg_fix_path(path, &p); + if (r < 0) + return r; + + r = asprintf(&fn, "%s/cgroup.procs", p); + free(p); + if (r < 0) + return -ENOMEM; + + f = fopen(fn, "re"); + free(fn); + if (!f) + return -errno; + + while ((r = cg_read_pid(f, &pid)) > 0) { + + if (!kernel_threads && is_kernel_thread(pid) > 0) + continue; + + if (n >= n_allocated) { + pid_t *npids; + + n_allocated = MAX(16U, n*2U); + + npids = realloc(pids, sizeof(pid_t) * n_allocated); + if (!npids) { + r = -ENOMEM; + goto finish; + } + + pids = npids; + } + + assert(n < n_allocated); + pids[n++] = pid; + } + + if (r < 0) + goto finish; + + if (n > 0) + show_pid_array(pids, n, prefix, n_columns, false, more, kernel_threads); + + r = 0; + +finish: + free(pids); + + if (f) + fclose(f); + + return r; +} + +int show_cgroup_by_path(const char *path, const char *prefix, unsigned n_columns, bool kernel_threads, bool all) { + DIR *d; + char *last = NULL; + char *p1 = NULL, *p2 = NULL, *fn = NULL, *gn = NULL; + bool shown_pids = false; + int r; + + assert(path); + + if (n_columns <= 0) + n_columns = columns(); + + if (!prefix) + prefix = ""; + + r = cg_fix_path(path, &fn); + if (r < 0) + return r; + + d = opendir(fn); + if (!d) { + free(fn); + return -errno; + } + + while ((r = cg_read_subgroup(d, &gn)) > 0) { + char *k; + + r = asprintf(&k, "%s/%s", fn, gn); + free(gn); + if (r < 0) { + r = -ENOMEM; + goto finish; + } + + if (!all && cg_is_empty_recursive(NULL, k, false) > 0) { + free(k); + continue; + } + + if (!shown_pids) { + show_cgroup_one_by_path(path, prefix, n_columns, true, kernel_threads); + shown_pids = true; + } + + if (last) { + printf("%s%s%s\n", prefix, draw_special_char(DRAW_TREE_BRANCH), + path_get_file_name(last)); + + if (!p1) { + p1 = strappend(prefix, draw_special_char(DRAW_TREE_VERT)); + if (!p1) { + free(k); + r = -ENOMEM; + goto finish; + } + } + + show_cgroup_by_path(last, p1, n_columns-2, kernel_threads, all); + free(last); + } + + last = k; + } + + if (r < 0) + goto finish; + + if (!shown_pids) + show_cgroup_one_by_path(path, prefix, n_columns, !!last, kernel_threads); + + if (last) { + printf("%s%s%s\n", prefix, draw_special_char(DRAW_TREE_RIGHT), + path_get_file_name(last)); + + if (!p2) { + p2 = strappend(prefix, " "); + if (!p2) { + r = -ENOMEM; + goto finish; + } + } + + show_cgroup_by_path(last, p2, n_columns-2, kernel_threads, all); + } + + r = 0; + +finish: + free(p1); + free(p2); + free(last); + free(fn); + + closedir(d); + + return r; +} + +int show_cgroup(const char *controller, const char *path, const char *prefix, unsigned n_columns, bool kernel_threads, bool all) { + char *p; + int r; + + assert(controller); + assert(path); + + r = cg_get_path(controller, path, NULL, &p); + if (r < 0) + return r; + + r = show_cgroup_by_path(p, prefix, n_columns, kernel_threads, all); + free(p); + + return r; +} + +static int show_extra_pids(const char *controller, const char *path, const char *prefix, unsigned n_columns, const pid_t pids[], unsigned n_pids) { + pid_t *copy; + unsigned i, j; + int r; + + assert(controller); + assert(path); + + if (n_pids <= 0) + return 0; + + if (n_columns <= 0) + n_columns = columns(); + + if (!prefix) + prefix = ""; + + copy = new(pid_t, n_pids); + if (!copy) + return -ENOMEM; + + for (i = 0, j = 0; i < n_pids; i++) { + char *k; + + r = cg_get_by_pid(controller, pids[i], &k); + if (r < 0) { + free(copy); + return r; + } + + if (path_startswith(k, path)) + continue; + + copy[j++] = pids[i]; + } + + show_pid_array(copy, j, prefix, n_columns, true, false, false); + + free(copy); + return 0; +} + +int show_cgroup_and_extra(const char *controller, const char *path, const char *prefix, unsigned n_columns, bool kernel_threads, bool all, const pid_t extra_pids[], unsigned n_extra_pids) { + int r; + + assert(controller); + assert(path); + + r = show_cgroup(controller, path, prefix, n_columns, kernel_threads, all); + if (r < 0) + return r; + + return show_extra_pids(controller, path, prefix, n_columns, extra_pids, n_extra_pids); +} + +int show_cgroup_and_extra_by_spec(const char *spec, const char *prefix, unsigned n_columns, bool kernel_threads, bool all, const pid_t extra_pids[], unsigned n_extra_pids) { + int r; + _cleanup_free_ char *controller = NULL, *path = NULL; + + assert(spec); + + r = cg_split_spec(spec, &controller, &path); + if (r < 0) + return r; + + return show_cgroup_and_extra(controller, path, prefix, n_columns, kernel_threads, all, extra_pids, n_extra_pids); +} diff --git a/src/shared/cgroup-show.h b/src/shared/cgroup-show.h new file mode 100644 index 000000000..dba900a15 --- /dev/null +++ b/src/shared/cgroup-show.h @@ -0,0 +1,34 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foocgroupshowhfoo +#define foocgroupshowhfoo + +/*** + 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 . +***/ + +#include +#include + +int show_cgroup_by_path(const char *path, const char *prefix, unsigned columns, bool kernel_threads, bool all); +int show_cgroup(const char *controller, const char *path, const char *prefix, unsigned columns, bool kernel_threads, bool all); + +int show_cgroup_and_extra_by_spec(const char *spec, const char *prefix, unsigned n_columns, bool kernel_threads, bool all, const pid_t extra_pids[], unsigned n_extra_pids); +int show_cgroup_and_extra(const char *controller, const char *path, const char *prefix, unsigned n_columns, bool kernel_threads, bool all, const pid_t extra_pids[], unsigned n_extra_pids); + +#endif diff --git a/src/shared/cgroup-util.c b/src/shared/cgroup-util.c new file mode 100644 index 000000000..18cbf0412 --- /dev/null +++ b/src/shared/cgroup-util.c @@ -0,0 +1,1270 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "cgroup-util.h" +#include "log.h" +#include "set.h" +#include "macro.h" +#include "util.h" +#include "path-util.h" +#include "strv.h" + +int cg_enumerate_processes(const char *controller, const char *path, FILE **_f) { + char *fs; + int r; + FILE *f; + + assert(path); + assert(_f); + + r = cg_get_path(controller, path, "cgroup.procs", &fs); + if (r < 0) + return r; + + f = fopen(fs, "re"); + free(fs); + + if (!f) + return -errno; + + *_f = f; + return 0; +} + +int cg_enumerate_tasks(const char *controller, const char *path, FILE **_f) { + char *fs; + int r; + FILE *f; + + assert(path); + assert(_f); + + r = cg_get_path(controller, path, "tasks", &fs); + if (r < 0) + return r; + + f = fopen(fs, "re"); + free(fs); + + if (!f) + return -errno; + + *_f = f; + return 0; +} + +int cg_read_pid(FILE *f, pid_t *_pid) { + unsigned long ul; + + /* Note that the cgroup.procs might contain duplicates! See + * cgroups.txt for details. */ + + errno = 0; + if (fscanf(f, "%lu", &ul) != 1) { + + if (feof(f)) + return 0; + + return errno ? -errno : -EIO; + } + + if (ul <= 0) + return -EIO; + + *_pid = (pid_t) ul; + return 1; +} + +int cg_enumerate_subgroups(const char *controller, const char *path, DIR **_d) { + char *fs; + int r; + DIR *d; + + assert(path); + assert(_d); + + /* This is not recursive! */ + + r = cg_get_path(controller, path, NULL, &fs); + if (r < 0) + return r; + + d = opendir(fs); + free(fs); + + if (!d) + return -errno; + + *_d = d; + return 0; +} + +int cg_read_subgroup(DIR *d, char **fn) { + struct dirent *de; + + assert(d); + + errno = 0; + while ((de = readdir(d))) { + char *b; + + if (de->d_type != DT_DIR) + continue; + + if (streq(de->d_name, ".") || + streq(de->d_name, "..")) + continue; + + if (!(b = strdup(de->d_name))) + return -ENOMEM; + + *fn = b; + return 1; + } + + if (errno) + return -errno; + + return 0; +} + +int cg_rmdir(const char *controller, const char *path, bool honour_sticky) { + char *p; + int r; + + r = cg_get_path(controller, path, NULL, &p); + if (r < 0) + return r; + + if (honour_sticky) { + char *tasks; + + /* If the sticky bit is set don't remove the directory */ + + tasks = strappend(p, "/tasks"); + if (!tasks) { + free(p); + return -ENOMEM; + } + + r = file_is_priv_sticky(tasks); + free(tasks); + + if (r > 0) { + free(p); + return 0; + } + } + + r = rmdir(p); + free(p); + + return (r < 0 && errno != ENOENT) ? -errno : 0; +} + +int cg_kill(const char *controller, const char *path, int sig, bool sigcont, bool ignore_self, Set *s) { + bool done = false; + int r, ret = 0; + pid_t my_pid; + FILE *f = NULL; + Set *allocated_set = NULL; + + assert(controller); + assert(path); + assert(sig >= 0); + + /* This goes through the tasks list and kills them all. This + * is repeated until no further processes are added to the + * tasks list, to properly handle forking processes */ + + if (!s) + if (!(s = allocated_set = set_new(trivial_hash_func, trivial_compare_func))) + return -ENOMEM; + + my_pid = getpid(); + + do { + pid_t pid = 0; + done = true; + + if ((r = cg_enumerate_processes(controller, path, &f)) < 0) { + if (ret >= 0 && r != -ENOENT) + ret = r; + + goto finish; + } + + while ((r = cg_read_pid(f, &pid)) > 0) { + + if (pid == my_pid && ignore_self) + continue; + + if (set_get(s, LONG_TO_PTR(pid)) == LONG_TO_PTR(pid)) + continue; + + /* If we haven't killed this process yet, kill + * it */ + if (kill(pid, sig) < 0) { + if (ret >= 0 && errno != ESRCH) + ret = -errno; + } else if (ret == 0) { + + if (sigcont) + kill(pid, SIGCONT); + + ret = 1; + } + + done = false; + + if ((r = set_put(s, LONG_TO_PTR(pid))) < 0) { + if (ret >= 0) + ret = r; + + goto finish; + } + } + + if (r < 0) { + if (ret >= 0) + ret = r; + + goto finish; + } + + fclose(f); + f = NULL; + + /* To avoid racing against processes which fork + * quicker than we can kill them we repeat this until + * no new pids need to be killed. */ + + } while (!done); + +finish: + if (allocated_set) + set_free(allocated_set); + + if (f) + fclose(f); + + return ret; +} + +int cg_kill_recursive(const char *controller, const char *path, int sig, bool sigcont, bool ignore_self, bool rem, Set *s) { + int r, ret = 0; + DIR *d = NULL; + char *fn; + Set *allocated_set = NULL; + + assert(path); + assert(controller); + assert(sig >= 0); + + if (!s) + if (!(s = allocated_set = set_new(trivial_hash_func, trivial_compare_func))) + return -ENOMEM; + + ret = cg_kill(controller, path, sig, sigcont, ignore_self, s); + + if ((r = cg_enumerate_subgroups(controller, path, &d)) < 0) { + if (ret >= 0 && r != -ENOENT) + ret = r; + + goto finish; + } + + while ((r = cg_read_subgroup(d, &fn)) > 0) { + char *p = NULL; + + r = asprintf(&p, "%s/%s", path, fn); + free(fn); + + if (r < 0) { + if (ret >= 0) + ret = -ENOMEM; + + goto finish; + } + + r = cg_kill_recursive(controller, p, sig, sigcont, ignore_self, rem, s); + free(p); + + if (r != 0 && ret >= 0) + ret = r; + } + + if (r < 0 && ret >= 0) + ret = r; + + if (rem) + if ((r = cg_rmdir(controller, path, true)) < 0) { + if (ret >= 0 && + r != -ENOENT && + r != -EBUSY) + ret = r; + } + +finish: + if (d) + closedir(d); + + if (allocated_set) + set_free(allocated_set); + + return ret; +} + +int cg_kill_recursive_and_wait(const char *controller, const char *path, bool rem) { + unsigned i; + + assert(path); + assert(controller); + + /* This safely kills all processes; first it sends a SIGTERM, + * then checks 8 times after 200ms whether the group is now + * empty, then kills everything that is left with SIGKILL and + * finally checks 5 times after 200ms each whether the group + * is finally empty. */ + + for (i = 0; i < 15; i++) { + int sig, r; + + if (i <= 0) + sig = SIGTERM; + else if (i == 9) + sig = SIGKILL; + else + sig = 0; + + if ((r = cg_kill_recursive(controller, path, sig, true, true, rem, NULL)) <= 0) + return r; + + usleep(200 * USEC_PER_MSEC); + } + + return 0; +} + +int cg_migrate(const char *controller, const char *from, const char *to, bool ignore_self) { + bool done = false; + Set *s; + int r, ret = 0; + pid_t my_pid; + FILE *f = NULL; + + assert(controller); + assert(from); + assert(to); + + if (!(s = set_new(trivial_hash_func, trivial_compare_func))) + return -ENOMEM; + + my_pid = getpid(); + + do { + pid_t pid = 0; + done = true; + + if ((r = cg_enumerate_tasks(controller, from, &f)) < 0) { + if (ret >= 0 && r != -ENOENT) + ret = r; + + goto finish; + } + + while ((r = cg_read_pid(f, &pid)) > 0) { + + /* This might do weird stuff if we aren't a + * single-threaded program. However, we + * luckily know we are not */ + if (pid == my_pid && ignore_self) + continue; + + if (set_get(s, LONG_TO_PTR(pid)) == LONG_TO_PTR(pid)) + continue; + + if ((r = cg_attach(controller, to, pid)) < 0) { + if (ret >= 0 && r != -ESRCH) + ret = r; + } else if (ret == 0) + ret = 1; + + done = false; + + if ((r = set_put(s, LONG_TO_PTR(pid))) < 0) { + if (ret >= 0) + ret = r; + + goto finish; + } + } + + if (r < 0) { + if (ret >= 0) + ret = r; + + goto finish; + } + + fclose(f); + f = NULL; + + } while (!done); + +finish: + set_free(s); + + if (f) + fclose(f); + + return ret; +} + +int cg_migrate_recursive(const char *controller, const char *from, const char *to, bool ignore_self, bool rem) { + int r, ret = 0; + DIR *d = NULL; + char *fn; + + assert(controller); + assert(from); + assert(to); + + ret = cg_migrate(controller, from, to, ignore_self); + + if ((r = cg_enumerate_subgroups(controller, from, &d)) < 0) { + if (ret >= 0 && r != -ENOENT) + ret = r; + goto finish; + } + + while ((r = cg_read_subgroup(d, &fn)) > 0) { + char *p = NULL; + + r = asprintf(&p, "%s/%s", from, fn); + free(fn); + + if (r < 0) { + if (ret >= 0) + ret = -ENOMEM; + + goto finish; + } + + r = cg_migrate_recursive(controller, p, to, ignore_self, rem); + free(p); + + if (r != 0 && ret >= 0) + ret = r; + } + + if (r < 0 && ret >= 0) + ret = r; + + if (rem) + if ((r = cg_rmdir(controller, from, true)) < 0) { + if (ret >= 0 && + r != -ENOENT && + r != -EBUSY) + ret = r; + } + +finish: + if (d) + closedir(d); + + return ret; +} + +static const char *normalize_controller(const char *controller) { + + if (streq(controller, SYSTEMD_CGROUP_CONTROLLER)) + return "systemd"; + else if (startswith(controller, "name=")) + return controller + 5; + else + return controller; +} + +static int join_path(const char *controller, const char *path, const char *suffix, char **fs) { + char *t = NULL; + + if (!(controller || path)) + return -EINVAL; + + if (controller) { + if (path && suffix) + t = strjoin("/sys/fs/cgroup/", controller, "/", path, "/", suffix, NULL); + else if (path) + t = strjoin("/sys/fs/cgroup/", controller, "/", path, NULL); + else if (suffix) + t = strjoin("/sys/fs/cgroup/", controller, "/", suffix, NULL); + else + t = strjoin("/sys/fs/cgroup/", controller, NULL); + } else { + if (path && suffix) + t = strjoin(path, "/", suffix, NULL); + else if (path) + t = strdup(path); + } + + if (!t) + return -ENOMEM; + + path_kill_slashes(t); + + *fs = t; + return 0; +} + +int cg_get_path(const char *controller, const char *path, const char *suffix, char **fs) { + const char *p; + static __thread bool good = false; + + assert(fs); + + if (_unlikely_(!good)) { + int r; + + r = path_is_mount_point("/sys/fs/cgroup", false); + if (r <= 0) + return r < 0 ? r : -ENOENT; + + /* Cache this to save a few stat()s */ + good = true; + } + + p = controller ? normalize_controller(controller) : NULL; + return join_path(p, path, suffix, fs); +} + +static int check(const char *p) { + char *cc; + + assert(p); + + /* Check if this controller actually really exists */ + cc = alloca(sizeof("/sys/fs/cgroup/") + strlen(p)); + strcpy(stpcpy(cc, "/sys/fs/cgroup/"), p); + if (access(cc, F_OK) < 0) + return -errno; + + return 0; +} + +int cg_get_path_and_check(const char *controller, const char *path, const char *suffix, char **fs) { + const char *p; + int r; + + assert(controller); + assert(fs); + + if (isempty(controller)) + return -EINVAL; + + /* Normalize the controller syntax */ + p = normalize_controller(controller); + + /* Check if this controller actually really exists */ + r = check(p); + if (r < 0) + return r; + + return join_path(p, path, suffix, fs); +} + +static int trim_cb(const char *path, const struct stat *sb, int typeflag, struct FTW *ftwbuf) { + char *p; + bool is_sticky; + + if (typeflag != FTW_DP) + return 0; + + if (ftwbuf->level < 1) + return 0; + + p = strappend(path, "/tasks"); + if (!p) { + errno = ENOMEM; + return 1; + } + + is_sticky = file_is_priv_sticky(p) > 0; + free(p); + + if (is_sticky) + return 0; + + rmdir(path); + return 0; +} + +int cg_trim(const char *controller, const char *path, bool delete_root) { + char *fs; + int r = 0; + + assert(controller); + assert(path); + + r = cg_get_path(controller, path, NULL, &fs); + if (r < 0) + return r; + + errno = 0; + if (nftw(fs, trim_cb, 64, FTW_DEPTH|FTW_MOUNT|FTW_PHYS) < 0) + r = errno ? -errno : -EIO; + + if (delete_root) { + bool is_sticky; + char *p; + + p = strappend(fs, "/tasks"); + if (!p) { + free(fs); + return -ENOMEM; + } + + is_sticky = file_is_priv_sticky(p) > 0; + free(p); + + if (!is_sticky) + if (rmdir(fs) < 0 && errno != ENOENT) { + if (r == 0) + r = -errno; + } + } + + free(fs); + + return r; +} + +int cg_delete(const char *controller, const char *path) { + char *parent; + int r; + + assert(controller); + assert(path); + + if ((r = path_get_parent(path, &parent)) < 0) + return r; + + r = cg_migrate_recursive(controller, path, parent, false, true); + free(parent); + + return r == -ENOENT ? 0 : r; +} + +int cg_attach(const char *controller, const char *path, pid_t pid) { + char *fs; + int r; + char c[32]; + + assert(controller); + assert(path); + assert(pid >= 0); + + r = cg_get_path_and_check(controller, path, "tasks", &fs); + if (r < 0) + return r; + + if (pid == 0) + pid = getpid(); + + snprintf(c, sizeof(c), "%lu\n", (unsigned long) pid); + char_array_0(c); + + r = write_one_line_file(fs, c); + free(fs); + + return r; +} + +int cg_set_group_access(const char *controller, const char *path, mode_t mode, uid_t uid, gid_t gid) { + char *fs; + int r; + + assert(controller); + assert(path); + + if (mode != (mode_t) -1) + mode &= 0777; + + r = cg_get_path(controller, path, NULL, &fs); + if (r < 0) + return r; + + r = chmod_and_chown(fs, mode, uid, gid); + free(fs); + + return r; +} + +int cg_set_task_access(const char *controller, const char *path, mode_t mode, uid_t uid, gid_t gid, int sticky) { + char *fs; + int r; + + assert(controller); + assert(path); + + if (mode == (mode_t) -1 && uid == (uid_t) -1 && gid == (gid_t) -1 && sticky < 0) + return 0; + + if (mode != (mode_t) -1) + mode &= 0666; + + r = cg_get_path(controller, path, "tasks", &fs); + if (r < 0) + return r; + + if (sticky >= 0 && mode != (mode_t) -1) + /* Both mode and sticky param are passed */ + mode |= (sticky ? S_ISVTX : 0); + else if ((sticky >= 0 && mode == (mode_t) -1) || + (mode != (mode_t) -1 && sticky < 0)) { + struct stat st; + + /* Only one param is passed, hence read the current + * mode from the file itself */ + + r = lstat(fs, &st); + if (r < 0) { + free(fs); + return -errno; + } + + if (mode == (mode_t) -1) + /* No mode set, we just shall set the sticky bit */ + mode = (st.st_mode & ~S_ISVTX) | (sticky ? S_ISVTX : 0); + else + /* Only mode set, leave sticky bit untouched */ + mode = (st.st_mode & ~0777) | mode; + } + + r = chmod_and_chown(fs, mode, uid, gid); + free(fs); + + return r; +} + +int cg_get_by_pid(const char *controller, pid_t pid, char **path) { + int r; + char *p = NULL; + FILE *f; + char *fs; + size_t cs; + + assert(controller); + assert(path); + assert(pid >= 0); + + if (pid == 0) + pid = getpid(); + + if (asprintf(&fs, "/proc/%lu/cgroup", (unsigned long) pid) < 0) + return -ENOMEM; + + f = fopen(fs, "re"); + free(fs); + + if (!f) + return errno == ENOENT ? -ESRCH : -errno; + + cs = strlen(controller); + + while (!feof(f)) { + char line[LINE_MAX]; + char *l; + + errno = 0; + if (!(fgets(line, sizeof(line), f))) { + if (feof(f)) + break; + + r = errno ? -errno : -EIO; + goto finish; + } + + truncate_nl(line); + + if (!(l = strchr(line, ':'))) + continue; + + l++; + if (strncmp(l, controller, cs) != 0) + continue; + + if (l[cs] != ':') + continue; + + if (!(p = strdup(l + cs + 1))) { + r = -ENOMEM; + goto finish; + } + + *path = p; + r = 0; + goto finish; + } + + r = -ENOENT; + +finish: + fclose(f); + + return r; +} + +int cg_install_release_agent(const char *controller, const char *agent) { + char *fs = NULL, *contents = NULL, *line = NULL, *sc; + int r; + + assert(controller); + assert(agent); + + if ((r = cg_get_path(controller, NULL, "release_agent", &fs)) < 0) + return r; + + if ((r = read_one_line_file(fs, &contents)) < 0) + goto finish; + + sc = strstrip(contents); + if (sc[0] == 0) { + + if (asprintf(&line, "%s\n", agent) < 0) { + r = -ENOMEM; + goto finish; + } + + if ((r = write_one_line_file(fs, line)) < 0) + goto finish; + + } else if (!streq(sc, agent)) { + r = -EEXIST; + goto finish; + } + + free(fs); + fs = NULL; + if ((r = cg_get_path(controller, NULL, "notify_on_release", &fs)) < 0) + goto finish; + + free(contents); + contents = NULL; + if ((r = read_one_line_file(fs, &contents)) < 0) + goto finish; + + sc = strstrip(contents); + + if (streq(sc, "0")) { + if ((r = write_one_line_file(fs, "1\n")) < 0) + goto finish; + + r = 1; + } else if (!streq(sc, "1")) { + r = -EIO; + goto finish; + } else + r = 0; + +finish: + free(fs); + free(contents); + free(line); + + return r; +} + +int cg_is_empty(const char *controller, const char *path, bool ignore_self) { + pid_t pid = 0, self_pid; + int r; + FILE *f = NULL; + bool found = false; + + assert(path); + + r = cg_enumerate_tasks(controller, path, &f); + if (r < 0) + return r == -ENOENT ? 1 : r; + + self_pid = getpid(); + + while ((r = cg_read_pid(f, &pid)) > 0) { + + if (ignore_self && pid == self_pid) + continue; + + found = true; + break; + } + + fclose(f); + + if (r < 0) + return r; + + return !found; +} + +int cg_is_empty_by_spec(const char *spec, bool ignore_self) { + int r; + _cleanup_free_ char *controller = NULL, *path = NULL; + + assert(spec); + + r = cg_split_spec(spec, &controller, &path); + if (r < 0) + return r; + + return cg_is_empty(controller, path, ignore_self); +} + + +int cg_is_empty_recursive(const char *controller, const char *path, bool ignore_self) { + int r; + DIR *d = NULL; + char *fn; + + assert(path); + + r = cg_is_empty(controller, path, ignore_self); + if (r <= 0) + return r; + + r = cg_enumerate_subgroups(controller, path, &d); + if (r < 0) + return r == -ENOENT ? 1 : r; + + while ((r = cg_read_subgroup(d, &fn)) > 0) { + char *p = NULL; + + r = asprintf(&p, "%s/%s", path, fn); + free(fn); + + if (r < 0) { + r = -ENOMEM; + goto finish; + } + + r = cg_is_empty_recursive(controller, p, ignore_self); + free(p); + + if (r <= 0) + goto finish; + } + + if (r >= 0) + r = 1; + +finish: + + if (d) + closedir(d); + + return r; +} + +int cg_split_spec(const char *spec, char **controller, char **path) { + const char *e; + char *t = NULL, *u = NULL; + + assert(spec); + assert(controller || path); + + if (*spec == '/') { + + if (path) { + if (!(t = strdup(spec))) + return -ENOMEM; + + *path = t; + } + + if (controller) + *controller = NULL; + + return 0; + } + + if (!(e = strchr(spec, ':'))) { + + if (strchr(spec, '/') || spec[0] == 0) + return -EINVAL; + + if (controller) { + if (!(t = strdup(spec))) + return -ENOMEM; + + *controller = t; + } + + if (path) + *path = NULL; + + return 0; + } + + if (e[1] != '/' || + e == spec || + memchr(spec, '/', e-spec)) + return -EINVAL; + + if (controller) + if (!(t = strndup(spec, e-spec))) + return -ENOMEM; + + if (path) + if (!(u = strdup(e+1))) { + free(t); + return -ENOMEM; + } + + if (controller) + *controller = t; + + if (path) + *path = u; + + return 0; +} + +int cg_join_spec(const char *controller, const char *path, char **spec) { + assert(controller); + assert(path); + + if (!path_is_absolute(path) || + controller[0] == 0 || + strchr(controller, ':') || + strchr(controller, '/')) + return -EINVAL; + + if (asprintf(spec, "%s:%s", controller, path) < 0) + return -ENOMEM; + + return 0; +} + +int cg_fix_path(const char *path, char **result) { + char *t, *c, *p; + int r; + + assert(path); + assert(result); + + /* First check if it already is a filesystem path */ + if (path_startswith(path, "/sys/fs/cgroup") && + access(path, F_OK) >= 0) { + + t = strdup(path); + if (!t) + return -ENOMEM; + + *result = t; + return 0; + } + + /* Otherwise treat it as cg spec */ + r = cg_split_spec(path, &c, &p); + if (r < 0) + return r; + + r = cg_get_path(c ? c : SYSTEMD_CGROUP_CONTROLLER, p ? p : "/", NULL, result); + free(c); + free(p); + + return r; +} + +int cg_get_user_path(char **path) { + char *root, *p; + + assert(path); + + /* Figure out the place to put user cgroups below. We use the + * same as PID 1 has but with the "/system" suffix replaced by + * "/user" */ + + if (cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, 1, &root) < 0) + p = strdup("/user"); + else { + if (endswith(root, "/system")) + root[strlen(root) - 7] = 0; + else if (streq(root, "/")) + root[0] = 0; + + p = strappend(root, "/user"); + free(root); + } + + if (!p) + return -ENOMEM; + + *path = p; + return 0; +} + +char **cg_shorten_controllers(char **controllers) { + char **f, **t; + + controllers = strv_uniq(controllers); + + if (!controllers) + return controllers; + + for (f = controllers, t = controllers; *f; f++) { + int r; + const char *p; + + if (streq(*f, "systemd") || streq(*f, SYSTEMD_CGROUP_CONTROLLER)) { + free(*f); + continue; + } + + p = normalize_controller(*f); + + r = check(p); + if (r < 0) { + log_debug("Controller %s is not available, removing from controllers list.", *f); + free(*f); + continue; + } + + *(t++) = *f; + } + + *t = NULL; + return controllers; +} + +int cg_pid_get_cgroup(pid_t pid, char **root, char **cgroup) { + char *cg_process, *cg_init, *p; + int r; + + assert(pid >= 0); + + if (pid == 0) + pid = getpid(); + + r = cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, pid, &cg_process); + if (r < 0) + return r; + + r = cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, 1, &cg_init); + if (r < 0) { + free(cg_process); + return r; + } + + if (endswith(cg_init, "/system")) + cg_init[strlen(cg_init)-7] = 0; + else if (streq(cg_init, "/")) + cg_init[0] = 0; + + if (startswith(cg_process, cg_init)) + p = cg_process + strlen(cg_init); + else + p = cg_process; + + free(cg_init); + + if (cgroup) { + char* c; + + c = strdup(p); + if (!c) { + free(cg_process); + return -ENOMEM; + } + + *cgroup = c; + } + + if (root) { + cg_process[p-cg_process] = 0; + *root = cg_process; + } else + free(cg_process); + + return 0; +} + +int cg_pid_get_unit(pid_t pid, char **unit) { + int r; + char *cgroup, *p, *at, *b; + size_t k; + + assert(pid >= 0); + assert(unit); + + r = cg_pid_get_cgroup(pid, NULL, &cgroup); + if (r < 0) + return r; + + if (!startswith(cgroup, "/system/")) { + free(cgroup); + return -ENOENT; + } + + p = cgroup + 8; + k = strcspn(p, "/"); + + at = memchr(p, '@', k); + if (at && at[1] == '.') { + size_t j; + + /* This is a templated service */ + if (p[k] != '/') { + free(cgroup); + return -EIO; + } + + j = strcspn(p+k+1, "/"); + + b = malloc(k + j + 1); + + if (b) { + memcpy(b, p, at - p + 1); + memcpy(b + (at - p) + 1, p + k + 1, j); + memcpy(b + (at - p) + 1 + j, at + 1, k - (at - p) - 1); + b[k+j] = 0; + } + } else + b = strndup(p, k); + + free(cgroup); + + if (!b) + return -ENOMEM; + + *unit = b; + return 0; + +} diff --git a/src/shared/cgroup-util.h b/src/shared/cgroup-util.h new file mode 100644 index 000000000..af2efc39b --- /dev/null +++ b/src/shared/cgroup-util.h @@ -0,0 +1,75 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +#include +#include +#include + +#include "set.h" +#include "def.h" + +int cg_enumerate_processes(const char *controller, const char *path, FILE **_f); +int cg_enumerate_tasks(const char *controller, const char *path, FILE **_f); +int cg_read_pid(FILE *f, pid_t *_pid); + +int cg_enumerate_subgroups(const char *controller, const char *path, DIR **_d); +int cg_read_subgroup(DIR *d, char **fn); + +int cg_kill(const char *controller, const char *path, int sig, bool sigcont, bool ignore_self, Set *s); +int cg_kill_recursive(const char *controller, const char *path, int sig, bool sigcont, bool ignore_self, bool remove, Set *s); +int cg_kill_recursive_and_wait(const char *controller, const char *path, bool remove); + +int cg_migrate(const char *controller, const char *from, const char *to, bool ignore_self); +int cg_migrate_recursive(const char *controller, const char *from, const char *to, bool ignore_self, bool remove); + +int cg_split_spec(const char *spec, char **controller, char **path); +int cg_join_spec(const char *controller, const char *path, char **spec); +int cg_fix_path(const char *path, char **result); + +int cg_get_path(const char *controller, const char *path, const char *suffix, char **fs); +int cg_get_path_and_check(const char *controller, const char *path, const char *suffix, char **fs); +int cg_get_by_pid(const char *controller, pid_t pid, char **path); + +int cg_trim(const char *controller, const char *path, bool delete_root); + +int cg_rmdir(const char *controller, const char *path, bool honour_sticky); +int cg_delete(const char *controller, const char *path); + +int cg_create(const char *controller, const char *path); +int cg_attach(const char *controller, const char *path, pid_t pid); +int cg_create_and_attach(const char *controller, const char *path, pid_t pid); + +int cg_set_group_access(const char *controller, const char *path, mode_t mode, uid_t uid, gid_t gid); +int cg_set_task_access(const char *controller, const char *path, mode_t mode, uid_t uid, gid_t gid, int sticky); + +int cg_install_release_agent(const char *controller, const char *agent); + +int cg_is_empty(const char *controller, const char *path, bool ignore_self); +int cg_is_empty_by_spec(const char *spec, bool ignore_self); +int cg_is_empty_recursive(const char *controller, const char *path, bool ignore_self); + +int cg_get_user_path(char **path); +int cg_pid_get_cgroup(pid_t pid, char **root, char **cgroup); +int cg_pid_get_unit(pid_t pid, char **unit); + +char **cg_shorten_controllers(char **controllers); diff --git a/src/shared/conf-files.c b/src/shared/conf-files.c new file mode 100644 index 000000000..34b86293d --- /dev/null +++ b/src/shared/conf-files.c @@ -0,0 +1,153 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "macro.h" +#include "util.h" +#include "missing.h" +#include "log.h" +#include "strv.h" +#include "path-util.h" +#include "hashmap.h" +#include "conf-files.h" + +static int files_add(Hashmap *h, const char *path, const char *suffix) { + DIR *dir; + int r = 0; + + dir = opendir(path); + if (!dir) { + if (errno == ENOENT) + return 0; + return -errno; + } + + for (;;) { + struct dirent *de; + union dirent_storage buf; + int k; + char *p; + + k = readdir_r(dir, &buf.de, &de); + if (k != 0) { + r = -k; + goto finish; + } + + if (!de) + break; + + if (!dirent_is_file_with_suffix(de, suffix)) + continue; + + if (asprintf(&p, "%s/%s", path, de->d_name) < 0) { + r = -ENOMEM; + goto finish; + } + + if (hashmap_put(h, path_get_file_name(p), p) <= 0) { + log_debug("Skip overridden file: %s.", p); + free(p); + } + } + +finish: + closedir(dir); + return r; +} + +static int base_cmp(const void *a, const void *b) { + const char *s1, *s2; + + s1 = *(char * const *)a; + s2 = *(char * const *)b; + return strcmp(path_get_file_name(s1), path_get_file_name(s2)); +} + +int conf_files_list_strv(char ***strv, const char *suffix, const char **dirs) { + Hashmap *fh = NULL; + char **files = NULL; + const char **p; + int r; + + assert(dirs); + + fh = hashmap_new(string_hash_func, string_compare_func); + if (!fh) { + r = -ENOMEM; + goto finish; + } + + STRV_FOREACH(p, dirs) { + r = files_add(fh, *p, suffix); + if (r < 0) + log_warning("Failed to search for files in %s: %s", + *p, strerror(-r)); + } + + files = hashmap_get_strv(fh); + if (files == NULL) { + log_error("Failed to compose list of files."); + r = -ENOMEM; + goto finish; + } + qsort(files, hashmap_size(fh), sizeof(char *), base_cmp); + r = 0; + +finish: + hashmap_free(fh); + *strv = files; + return r; +} + +int conf_files_list(char ***strv, const char *suffix, const char *dir, ...) { + char **dirs = NULL; + va_list ap; + int r; + + va_start(ap, dir); + dirs = strv_new_ap(dir, ap); + va_end(ap); + if (!dirs) { + r = -ENOMEM; + goto finish; + } + + if (!path_strv_canonicalize(dirs)) { + r = -ENOMEM; + goto finish; + } + strv_uniq(dirs); + + r = conf_files_list_strv(strv, suffix, (const char **)dirs); + +finish: + strv_free(dirs); + return r; +} diff --git a/src/shared/conf-files.h b/src/shared/conf-files.h new file mode 100644 index 000000000..f37ee1f3d --- /dev/null +++ b/src/shared/conf-files.h @@ -0,0 +1,31 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef fooconffileshfoo +#define fooconffileshfoo + +/*** + This file is part of systemd. + + Copyright 2010-2012 Lennart Poettering + Copyright 2010-2012 Kay Sievers + + 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 . +***/ + +#include "macro.h" + +int conf_files_list(char ***strv, const char *suffix, const char *dir, ...); +int conf_files_list_strv(char ***strv, const char *suffix, const char **dirs); + +#endif diff --git a/src/shared/conf-parser.c b/src/shared/conf-parser.c new file mode 100644 index 000000000..9f5c07c76 --- /dev/null +++ b/src/shared/conf-parser.c @@ -0,0 +1,1007 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include +#include + +#include "conf-parser.h" +#include "util.h" +#include "macro.h" +#include "strv.h" +#include "log.h" +#include "utf8.h" +#include "path-util.h" +#include "set.h" +#include "exit-status.h" + +int config_item_table_lookup( + void *table, + const char *section, + const char *lvalue, + ConfigParserCallback *func, + int *ltype, + void **data, + void *userdata) { + + ConfigTableItem *t; + + assert(table); + assert(lvalue); + assert(func); + assert(ltype); + assert(data); + + for (t = table; t->lvalue; t++) { + + if (!streq(lvalue, t->lvalue)) + continue; + + if (!streq_ptr(section, t->section)) + continue; + + *func = t->parse; + *ltype = t->ltype; + *data = t->data; + return 1; + } + + return 0; +} + +int config_item_perf_lookup( + void *table, + const char *section, + const char *lvalue, + ConfigParserCallback *func, + int *ltype, + void **data, + void *userdata) { + + ConfigPerfItemLookup lookup = (ConfigPerfItemLookup) table; + const ConfigPerfItem *p; + + assert(table); + assert(lvalue); + assert(func); + assert(ltype); + assert(data); + + if (!section) + p = lookup(lvalue, strlen(lvalue)); + else { + char *key; + + key = strjoin(section, ".", lvalue, NULL); + if (!key) + return -ENOMEM; + + p = lookup(key, strlen(key)); + free(key); + } + + if (!p) + return 0; + + *func = p->parse; + *ltype = p->ltype; + *data = (uint8_t*) userdata + p->offset; + return 1; +} + +/* Run the user supplied parser for an assignment */ +static int next_assignment( + const char *filename, + unsigned line, + ConfigItemLookup lookup, + void *table, + const char *section, + const char *lvalue, + const char *rvalue, + bool relaxed, + void *userdata) { + + ConfigParserCallback func = NULL; + int ltype = 0; + void *data = NULL; + int r; + + assert(filename); + assert(line > 0); + assert(lookup); + assert(lvalue); + assert(rvalue); + + r = lookup(table, section, lvalue, &func, <ype, &data, userdata); + if (r < 0) + return r; + + if (r > 0) { + if (func) + return func(filename, line, section, lvalue, ltype, rvalue, data, userdata); + + return 0; + } + + /* Warn about unknown non-extension fields. */ + if (!relaxed && !startswith(lvalue, "X-")) + log_info("[%s:%u] Unknown lvalue '%s' in section '%s'. Ignoring.", filename, line, lvalue, section); + + return 0; +} + +/* Parse a variable assignment line */ +static int parse_line( + const char *filename, + unsigned line, + const char *sections, + ConfigItemLookup lookup, + void *table, + bool relaxed, + char **section, + char *l, + void *userdata) { + + char *e; + + assert(filename); + assert(line > 0); + assert(lookup); + assert(l); + + l = strstrip(l); + + if (!*l) + return 0; + + if (strchr(COMMENTS, *l)) + return 0; + + if (startswith(l, ".include ")) { + char *fn; + int r; + + fn = file_in_same_dir(filename, strstrip(l+9)); + if (!fn) + return -ENOMEM; + + r = config_parse(fn, NULL, sections, lookup, table, relaxed, userdata); + free(fn); + + return r; + } + + if (*l == '[') { + size_t k; + char *n; + + k = strlen(l); + assert(k > 0); + + if (l[k-1] != ']') { + log_error("[%s:%u] Invalid section header.", filename, line); + return -EBADMSG; + } + + n = strndup(l+1, k-2); + if (!n) + return -ENOMEM; + + if (sections && !nulstr_contains(sections, n)) { + + if (!relaxed) + log_info("[%s:%u] Unknown section '%s'. Ignoring.", filename, line, n); + + free(n); + *section = NULL; + } else { + free(*section); + *section = n; + } + + return 0; + } + + if (sections && !*section) { + + if (!relaxed) + log_info("[%s:%u] Assignment outside of section. Ignoring.", filename, line); + + return 0; + } + + e = strchr(l, '='); + if (!e) { + log_error("[%s:%u] Missing '='.", filename, line); + return -EBADMSG; + } + + *e = 0; + e++; + + return next_assignment( + filename, + line, + lookup, + table, + *section, + strstrip(l), + strstrip(e), + relaxed, + userdata); +} + +/* Go through the file and parse each line */ +int config_parse( + const char *filename, + FILE *f, + const char *sections, + ConfigItemLookup lookup, + void *table, + bool relaxed, + void *userdata) { + + unsigned line = 0; + char *section = NULL; + int r; + bool ours = false; + char *continuation = NULL; + + assert(filename); + assert(lookup); + + if (!f) { + f = fopen(filename, "re"); + if (!f) { + r = -errno; + log_error("Failed to open configuration file '%s': %s", filename, strerror(-r)); + goto finish; + } + + ours = true; + } + + while (!feof(f)) { + char l[LINE_MAX], *p, *c = NULL, *e; + bool escaped = false; + + if (!fgets(l, sizeof(l), f)) { + if (feof(f)) + break; + + r = -errno; + log_error("Failed to read configuration file '%s': %s", filename, strerror(-r)); + goto finish; + } + + truncate_nl(l); + + if (continuation) { + c = strappend(continuation, l); + if (!c) { + r = -ENOMEM; + goto finish; + } + + free(continuation); + continuation = NULL; + p = c; + } else + p = l; + + for (e = p; *e; e++) { + if (escaped) + escaped = false; + else if (*e == '\\') + escaped = true; + } + + if (escaped) { + *(e-1) = ' '; + + if (c) + continuation = c; + else { + continuation = strdup(l); + if (!continuation) { + r = -ENOMEM; + goto finish; + } + } + + continue; + } + + r = parse_line(filename, + ++line, + sections, + lookup, + table, + relaxed, + §ion, + p, + userdata); + free(c); + + if (r < 0) + goto finish; + } + + r = 0; + +finish: + free(section); + free(continuation); + + if (f && ours) + fclose(f); + + return r; +} + +int config_parse_int( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + int *i = data; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if ((r = safe_atoi(rvalue, i)) < 0) { + log_error("[%s:%u] Failed to parse numeric value, ingoring: %s", filename, line, rvalue); + return 0; + } + + return 0; +} + +int config_parse_long( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + long *i = data; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if ((r = safe_atoli(rvalue, i)) < 0) { + log_error("[%s:%u] Failed to parse numeric value, ignoring: %s", filename, line, rvalue); + return 0; + } + + return 0; +} + +int config_parse_uint64( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + uint64_t *u = data; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if ((r = safe_atou64(rvalue, u)) < 0) { + log_error("[%s:%u] Failed to parse numeric value, ignoring: %s", filename, line, rvalue); + return 0; + } + + return 0; +} + +int config_parse_unsigned( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + unsigned *u = data; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if ((r = safe_atou(rvalue, u)) < 0) { + log_error("[%s:%u] Failed to parse numeric value: %s", filename, line, rvalue); + return r; + } + + return 0; +} + +int config_parse_bytes_size( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + size_t *sz = data; + off_t o; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if (parse_bytes(rvalue, &o) < 0 || (off_t) (size_t) o != o) { + log_error("[%s:%u] Failed to parse byte value, ignoring: %s", filename, line, rvalue); + return 0; + } + + *sz = (size_t) o; + return 0; +} + + +int config_parse_bytes_off( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + off_t *bytes = data; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + assert_cc(sizeof(off_t) == sizeof(uint64_t)); + + if (parse_bytes(rvalue, bytes) < 0) { + log_error("[%s:%u] Failed to parse bytes value, ignoring: %s", filename, line, rvalue); + return 0; + } + + return 0; +} + +int config_parse_bool( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + int k; + bool *b = data; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if ((k = parse_boolean(rvalue)) < 0) { + log_error("[%s:%u] Failed to parse boolean value, ignoring: %s", filename, line, rvalue); + return 0; + } + + *b = !!k; + return 0; +} + +int config_parse_tristate( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + int k; + int *b = data; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + /* Tristates are like booleans, but can also take the 'default' value, i.e. "-1" */ + + k = parse_boolean(rvalue); + if (k < 0) { + log_error("[%s:%u] Failed to parse boolean value, ignoring: %s", filename, line, rvalue); + return 0; + } + + *b = !!k; + return 0; +} + +int config_parse_string( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + char **s = data; + char *n; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + n = strdup(rvalue); + if (!n) + return -ENOMEM; + + if (!utf8_is_valid(n)) { + log_error("[%s:%u] String is not UTF-8 clean, ignoring assignment: %s", filename, line, rvalue); + free(n); + return 0; + } + + free(*s); + if (*n) + *s = n; + else { + free(n); + *s = NULL; + } + + return 0; +} + +int config_parse_path( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + char **s = data; + char *n; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if (!utf8_is_valid(rvalue)) { + log_error("[%s:%u] Path is not UTF-8 clean, ignoring assignment: %s", filename, line, rvalue); + return 0; + } + + if (!path_is_absolute(rvalue)) { + log_error("[%s:%u] Not an absolute path, ignoring: %s", filename, line, rvalue); + return 0; + } + + n = strdup(rvalue); + if (!n) + return -ENOMEM; + + path_kill_slashes(n); + + free(*s); + *s = n; + + return 0; +} + +int config_parse_strv( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + char*** sv = data; + char **n; + char *w; + unsigned k; + size_t l; + char *state; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + k = strv_length(*sv); + FOREACH_WORD_QUOTED(w, l, rvalue, state) + k++; + + n = new(char*, k+1); + if (!n) + return -ENOMEM; + + if (*sv) + for (k = 0; (*sv)[k]; k++) + n[k] = (*sv)[k]; + else + k = 0; + + FOREACH_WORD_QUOTED(w, l, rvalue, state) { + n[k] = cunescape_length(w, l); + if (!n[k]) { + r = -ENOMEM; + goto fail; + } + + if (!utf8_is_valid(n[k])) { + log_error("[%s:%u] String is not UTF-8 clean, ignoring assignment: %s", filename, line, rvalue); + free(n[k]); + continue; + } + + k++; + } + + n[k] = NULL; + free(*sv); + *sv = n; + + return 0; + +fail: + for (; k > 0; k--) + free(n[k-1]); + free(n); + + return r; +} + +int config_parse_path_strv( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + char*** sv = data; + char **n; + char *w; + unsigned k; + size_t l; + char *state; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + k = strv_length(*sv); + FOREACH_WORD_QUOTED(w, l, rvalue, state) + k++; + + n = new(char*, k+1); + if (!n) + return -ENOMEM; + + k = 0; + if (*sv) + for (; (*sv)[k]; k++) + n[k] = (*sv)[k]; + + FOREACH_WORD_QUOTED(w, l, rvalue, state) { + n[k] = strndup(w, l); + if (!n[k]) { + r = -ENOMEM; + goto fail; + } + + if (!utf8_is_valid(n[k])) { + log_error("[%s:%u] Path is not UTF-8 clean, ignoring assignment: %s", filename, line, rvalue); + free(n[k]); + continue; + } + + if (!path_is_absolute(n[k])) { + log_error("[%s:%u] Not an absolute path, ignoring: %s", filename, line, rvalue); + free(n[k]); + continue; + } + + path_kill_slashes(n[k]); + k++; + } + + n[k] = NULL; + free(*sv); + *sv = n; + + return 0; + +fail: + for (; k > 0; k--) + free(n[k-1]); + free(n); + + return r; +} + +int config_parse_usec( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + usec_t *usec = data; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if (parse_usec(rvalue, usec) < 0) { + log_error("[%s:%u] Failed to parse time value, ignoring: %s", filename, line, rvalue); + return 0; + } + + return 0; +} + +int config_parse_nsec( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + nsec_t *nsec = data; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if (parse_nsec(rvalue, nsec) < 0) { + log_error("[%s:%u] Failed to parse time value, ignoring: %s", filename, line, rvalue); + return 0; + } + + return 0; +} + +int config_parse_mode( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + mode_t *m = data; + long l; + char *x = NULL; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + errno = 0; + l = strtol(rvalue, &x, 8); + if (!x || x == rvalue || *x || errno) { + log_error("[%s:%u] Failed to parse mode value, ignoring: %s", filename, line, rvalue); + return 0; + } + + if (l < 0000 || l > 07777) { + log_error("[%s:%u] mode value out of range, ignoring: %s", filename, line, rvalue); + return 0; + } + + *m = (mode_t) l; + return 0; +} + +int config_parse_facility( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + + int *o = data, x; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + x = log_facility_unshifted_from_string(rvalue); + if (x < 0) { + log_error("[%s:%u] Failed to parse log facility, ignoring: %s", filename, line, rvalue); + return 0; + } + + *o = (x << 3) | LOG_PRI(*o); + + return 0; +} + +int config_parse_level( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + + int *o = data, x; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + x = log_level_from_string(rvalue); + if (x < 0) { + log_error("[%s:%u] Failed to parse log level, ignoring: %s", filename, line, rvalue); + return 0; + } + + *o = (*o & LOG_FACMASK) | x; + return 0; +} + +int config_parse_set_status( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + char *w; + size_t l; + char *state; + int r; + ExitStatusSet *status_set = data; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + FOREACH_WORD(w, l, rvalue, state) { + int val; + char *temp; + + temp = strndup(w, l); + if (!temp) + return log_oom(); + + r = safe_atoi(temp, &val); + if (r < 0) { + val = signal_from_string_try_harder(temp); + free(temp); + + if (val > 0) { + r = set_ensure_allocated(&status_set->signal, trivial_hash_func, trivial_compare_func); + if (r < 0) + return log_oom(); + + r = set_put(status_set->signal, INT_TO_PTR(val)); + if (r < 0) { + log_error("[%s:%u] Unable to store: %s", filename, line, w); + return r; + } + } else { + log_error("[%s:%u] Failed to parse value, ignoring: %s", filename, line, w); + return 0; + } + } else { + free(temp); + + if (val < 0 || val > 255) + log_warning("[%s:%u] Value %d is outside range 0-255, ignoring", filename, line, val); + else { + r = set_ensure_allocated(&status_set->code, trivial_hash_func, trivial_compare_func); + if (r < 0) + return log_oom(); + + r = set_put(status_set->code, INT_TO_PTR(val)); + if (r < 0) { + log_error("[%s:%u] Unable to store: %s", filename, line, w); + return r; + } + } + } + } + + return 0; +} diff --git a/src/shared/conf-parser.h b/src/shared/conf-parser.h new file mode 100644 index 000000000..56ffc2f8a --- /dev/null +++ b/src/shared/conf-parser.h @@ -0,0 +1,136 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +#include +#include + +/* An abstract parser for simple, line based, shallow configuration + * files consisting of variable assignments only. */ + +/* Prototype for a parser for a specific configuration setting */ +typedef int (*ConfigParserCallback)( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata); + +/* Wraps information for parsing a specific configuration variable, to + * be stored in a simple array */ +typedef struct ConfigTableItem { + const char *section; /* Section */ + const char *lvalue; /* Name of the variable */ + ConfigParserCallback parse; /* Function that is called to parse the variable's value */ + int ltype; /* Distinguish different variables passed to the same callback */ + void *data; /* Where to store the variable's data */ +} ConfigTableItem; + +/* Wraps information for parsing a specific configuration variable, to + * ve srored in a gperf perfect hashtable */ +typedef struct ConfigPerfItem { + const char *section_and_lvalue; /* Section + "." + name of the variable */ + ConfigParserCallback parse; /* Function that is called to parse the variable's value */ + int ltype; /* Distinguish different variables passed to the same callback */ + size_t offset; /* Offset where to store data, from the beginning of userdata */ +} ConfigPerfItem; + +/* Prototype for a low-level gperf lookup function */ +typedef const ConfigPerfItem* (*ConfigPerfItemLookup)(const char *section_and_lvalue, unsigned length); + +/* Prototype for a generic high-level lookup function */ +typedef int (*ConfigItemLookup)( + void *table, + const char *section, + const char *lvalue, + ConfigParserCallback *func, + int *ltype, + void **data, + void *userdata); + +/* Linear table search implementation of ConfigItemLookup, based on + * ConfigTableItem arrays */ +int config_item_table_lookup(void *table, const char *section, const char *lvalue, ConfigParserCallback *func, int *ltype, void **data, void *userdata); + +/* gperf implementation of ConfigItemLookup, based on gperf + * ConfigPerfItem tables */ +int config_item_perf_lookup(void *table, const char *section, const char *lvalue, ConfigParserCallback *func, int *ltype, void **data, void *userdata); + +int config_parse( + const char *filename, + FILE *f, + const char *sections, /* nulstr */ + ConfigItemLookup lookup, + void *table, + bool relaxed, + void *userdata); + +/* Generic parsers */ +int config_parse_int(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_unsigned(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_long(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_uint64(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_bytes_size(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_bytes_off(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_bool(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_tristate(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_string(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_path(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_strv(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_path_strv(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_usec(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_nsec(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_mode(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_facility(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_level(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_set_status(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); + +#define DEFINE_CONFIG_PARSE_ENUM(function,name,type,msg) \ + int function( \ + const char *filename, \ + unsigned line, \ + const char *section, \ + const char *lvalue, \ + int ltype, \ + const char *rvalue, \ + void *data, \ + void *userdata) { \ + \ + type *i = data, x; \ + \ + assert(filename); \ + assert(lvalue); \ + assert(rvalue); \ + assert(data); \ + \ + if ((x = name##_from_string(rvalue)) < 0) { \ + log_error("[%s:%u] " msg ", ignoring: %s", filename, line, rvalue); \ + return 0; \ + } \ + \ + *i = x; \ + \ + return 0; \ + } diff --git a/src/shared/dbus-common.c b/src/shared/dbus-common.c new file mode 100644 index 000000000..e9a78c299 --- /dev/null +++ b/src/shared/dbus-common.c @@ -0,0 +1,1335 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "log.h" +#include "dbus-common.h" +#include "util.h" +#include "missing.h" +#include "def.h" +#include "strv.h" + +int bus_check_peercred(DBusConnection *c) { + int fd; + struct ucred ucred; + socklen_t l; + + assert(c); + + assert_se(dbus_connection_get_unix_fd(c, &fd)); + + l = sizeof(struct ucred); + if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &ucred, &l) < 0) { + log_error("SO_PEERCRED failed: %m"); + return -errno; + } + + if (l != sizeof(struct ucred)) { + log_error("SO_PEERCRED returned wrong size."); + return -E2BIG; + } + + if (ucred.uid != 0 && ucred.uid != geteuid()) + return -EPERM; + + return 1; +} + +static int sync_auth(DBusConnection *bus, DBusError *error) { + usec_t begin, tstamp; + + assert(bus); + + /* This complexity should probably move into D-Bus itself: + * + * https://bugs.freedesktop.org/show_bug.cgi?id=35189 */ + + begin = tstamp = now(CLOCK_MONOTONIC); + for (;;) { + + if (tstamp > begin + DEFAULT_TIMEOUT_USEC) + break; + + if (dbus_connection_get_is_authenticated(bus)) + break; + + if (!dbus_connection_read_write_dispatch(bus, ((begin + DEFAULT_TIMEOUT_USEC - tstamp) + USEC_PER_MSEC - 1) / USEC_PER_MSEC)) + break; + + tstamp = now(CLOCK_MONOTONIC); + } + + if (!dbus_connection_get_is_connected(bus)) { + dbus_set_error_const(error, DBUS_ERROR_NO_SERVER, "Connection terminated during authentication."); + return -ECONNREFUSED; + } + + if (!dbus_connection_get_is_authenticated(bus)) { + dbus_set_error_const(error, DBUS_ERROR_TIMEOUT, "Failed to authenticate in time."); + return -EACCES; + } + + return 0; +} + +int bus_connect(DBusBusType t, DBusConnection **_bus, bool *_private, DBusError *error) { + DBusConnection *bus = NULL; + int r; + bool private = true; + + assert(_bus); + + if (geteuid() == 0 && t == DBUS_BUS_SYSTEM) { + /* If we are root, then let's talk directly to the + * system instance, instead of going via the bus */ + + bus = dbus_connection_open_private("unix:path=/run/systemd/private", error); + if (!bus) + return -EIO; + + } else { + if (t == DBUS_BUS_SESSION) { + const char *e; + + /* If we are supposed to talk to the instance, + * try via XDG_RUNTIME_DIR first, then + * fallback to normal bus access */ + + e = secure_getenv("XDG_RUNTIME_DIR"); + if (e) { + char *p; + + if (asprintf(&p, "unix:path=%s/systemd/private", e) < 0) + return -ENOMEM; + + bus = dbus_connection_open_private(p, NULL); + free(p); + } + } + + if (!bus) { + bus = dbus_bus_get_private(t, error); + if (!bus) + return -EIO; + + private = false; + } + } + + dbus_connection_set_exit_on_disconnect(bus, FALSE); + + if (private) { + if (bus_check_peercred(bus) < 0) { + dbus_connection_close(bus); + dbus_connection_unref(bus); + + dbus_set_error_const(error, DBUS_ERROR_ACCESS_DENIED, "Failed to verify owner of bus."); + return -EACCES; + } + } + + r = sync_auth(bus, error); + if (r < 0) { + dbus_connection_close(bus); + dbus_connection_unref(bus); + return r; + } + + if (_private) + *_private = private; + + *_bus = bus; + return 0; +} + +int bus_connect_system_ssh(const char *user, const char *host, DBusConnection **_bus, DBusError *error) { + DBusConnection *bus; + char *p = NULL; + int r; + + assert(_bus); + assert(user || host); + + if (user && host) + asprintf(&p, "unixexec:path=ssh,argv1=-xT,argv2=%s@%s,argv3=systemd-stdio-bridge", user, host); + else if (user) + asprintf(&p, "unixexec:path=ssh,argv1=-xT,argv2=%s@localhost,argv3=systemd-stdio-bridge", user); + else if (host) + asprintf(&p, "unixexec:path=ssh,argv1=-xT,argv2=%s,argv3=systemd-stdio-bridge", host); + + if (!p) { + dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, NULL); + return -ENOMEM; + } + + bus = dbus_connection_open_private(p, error); + free(p); + + if (!bus) + return -EIO; + + dbus_connection_set_exit_on_disconnect(bus, FALSE); + + if ((r = sync_auth(bus, error)) < 0) { + dbus_connection_close(bus); + dbus_connection_unref(bus); + return r; + } + + if (!dbus_bus_register(bus, error)) { + dbus_connection_close(bus); + dbus_connection_unref(bus); + return r; + } + + *_bus = bus; + return 0; +} + +int bus_connect_system_polkit(DBusConnection **_bus, DBusError *error) { + DBusConnection *bus; + int r; + + assert(_bus); + + /* Don't bother with PolicyKit if we are root */ + if (geteuid() == 0) + return bus_connect(DBUS_BUS_SYSTEM, _bus, NULL, error); + + bus = dbus_connection_open_private("unixexec:path=pkexec,argv1=" SYSTEMD_STDIO_BRIDGE_BINARY_PATH, error); + if (!bus) + return -EIO; + + dbus_connection_set_exit_on_disconnect(bus, FALSE); + + r = sync_auth(bus, error); + if (r < 0) { + dbus_connection_close(bus); + dbus_connection_unref(bus); + return r; + } + + if (!dbus_bus_register(bus, error)) { + dbus_connection_close(bus); + dbus_connection_unref(bus); + return r; + } + + *_bus = bus; + return 0; +} + +const char *bus_error_message(const DBusError *error) { + if (!error) + return NULL; + + /* Sometimes the D-Bus server is a little bit too verbose with + * its error messages, so let's override them here */ + if (dbus_error_has_name(error, DBUS_ERROR_ACCESS_DENIED)) + return "Access denied"; + + return error->message; +} + +const char *bus_error_message_or_strerror(const DBusError *error, int err) { + + if (error && dbus_error_is_set(error)) + return bus_error_message(error); + + return strerror(err); +} + +DBusHandlerResult bus_default_message_handler( + DBusConnection *c, + DBusMessage *message, + const char *introspection, + const char *interfaces, + const BusBoundProperties *bound_properties) { + + DBusError error; + _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; + int r; + + assert(c); + assert(message); + + dbus_error_init(&error); + + if (dbus_message_is_method_call(message, "org.freedesktop.DBus.Introspectable", "Introspect") && introspection) { + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + if (!dbus_message_append_args(reply, DBUS_TYPE_STRING, &introspection, DBUS_TYPE_INVALID)) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.DBus.Properties", "Get") && bound_properties) { + const char *interface, *property; + const BusBoundProperties *bp; + const BusProperty *p; + void *data; + DBusMessageIter iter, sub; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &interface, + DBUS_TYPE_STRING, &property, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(c, message, &error, -EINVAL); + + for (bp = bound_properties; bp->interface; bp++) { + if (!streq(bp->interface, interface)) + continue; + + for (p = bp->properties; p->property; p++) + if (streq(p->property, property)) + goto get_prop; + } + + /* no match */ + if (!nulstr_contains(interfaces, interface)) + dbus_set_error_const(&error, DBUS_ERROR_UNKNOWN_INTERFACE, "Unknown interface"); + else + dbus_set_error_const(&error, DBUS_ERROR_UNKNOWN_PROPERTY, "Unknown property"); + + return bus_send_error_reply(c, message, &error, -EINVAL); + +get_prop: + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + dbus_message_iter_init_append(reply, &iter); + + if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT, p->signature, &sub)) + goto oom; + + data = (char*)bp->base + p->offset; + if (p->indirect) + data = *(void**)data; + + r = p->append(&sub, property, data); + if (r == -ENOMEM) + goto oom; + if (r < 0) + return bus_send_error_reply(c, message, NULL, r); + + if (!dbus_message_iter_close_container(&iter, &sub)) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.DBus.Properties", "GetAll") && bound_properties) { + const char *interface; + const BusBoundProperties *bp; + const BusProperty *p; + DBusMessageIter iter, sub, sub2, sub3; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &interface, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(c, message, &error, -EINVAL); + + if (interface[0] && !nulstr_contains(interfaces, interface)) { + dbus_set_error_const(&error, DBUS_ERROR_UNKNOWN_INTERFACE, "Unknown interface"); + return bus_send_error_reply(c, message, &error, -EINVAL); + } + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + dbus_message_iter_init_append(reply, &iter); + + if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "{sv}", &sub)) + goto oom; + + for (bp = bound_properties; bp->interface; bp++) { + if (interface[0] && !streq(bp->interface, interface)) + continue; + + for (p = bp->properties; p->property; p++) { + void *data; + + if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_DICT_ENTRY, NULL, &sub2) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &p->property) || + !dbus_message_iter_open_container(&sub2, DBUS_TYPE_VARIANT, p->signature, &sub3)) + goto oom; + + data = (char*)bp->base + p->offset; + if (p->indirect) + data = *(void**)data; + r = p->append(&sub3, p->property, data); + if (r == -ENOMEM) + goto oom; + if (r < 0) + return bus_send_error_reply(c, message, NULL, r); + + if (!dbus_message_iter_close_container(&sub2, &sub3) || + !dbus_message_iter_close_container(&sub, &sub2)) + goto oom; + } + } + + if (!dbus_message_iter_close_container(&iter, &sub)) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.DBus.Properties", "Set") && bound_properties) { + const char *interface, *property; + DBusMessageIter iter; + const BusBoundProperties *bp; + const BusProperty *p; + DBusMessageIter sub; + char *sig; + void *data; + DBusMessage *changed; + + if (!dbus_message_iter_init(message, &iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) + return bus_send_error_reply(c, message, NULL, -EINVAL); + + dbus_message_iter_get_basic(&iter, &interface); + + if (!dbus_message_iter_next(&iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) + return bus_send_error_reply(c, message, NULL, -EINVAL); + + dbus_message_iter_get_basic(&iter, &property); + + if (!dbus_message_iter_next(&iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT || + dbus_message_iter_has_next(&iter)) + return bus_send_error_reply(c, message, NULL, -EINVAL); + + for (bp = bound_properties; bp->interface; bp++) { + if (!streq(bp->interface, interface)) + continue; + + for (p = bp->properties; p->property; p++) + if (streq(p->property, property)) + goto set_prop; + } + + /* no match */ + if (!nulstr_contains(interfaces, interface)) + dbus_set_error_const(&error, DBUS_ERROR_UNKNOWN_INTERFACE, "Unknown interface"); + else + dbus_set_error_const(&error, DBUS_ERROR_UNKNOWN_PROPERTY, "Unknown property"); + + return bus_send_error_reply(c, message, &error, -EINVAL); + +set_prop: + if (!p->set) { + dbus_set_error_const(&error, DBUS_ERROR_PROPERTY_READ_ONLY, "Property read-only"); + return bus_send_error_reply(c, message, &error, -EINVAL); + } + + dbus_message_iter_recurse(&iter, &sub); + + sig = dbus_message_iter_get_signature(&sub); + if (!sig) + goto oom; + + if (!streq(sig, p->signature)) { + dbus_free(sig); + return bus_send_error_reply(c, message, NULL, -EINVAL); + } + dbus_free(sig); + + data = (uint8_t*) bp->base + p->offset; + if (p->indirect) + data = *(void**)data; + + r = p->set(&sub, property, data); + if (r == -ENOMEM) + goto oom; + else if (r < 0) + return bus_send_error_reply(c, message, NULL, r); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + /* Send out a signal about this, but it doesn't really + * matter if this fails, so eat all errors */ + changed = bus_properties_changed_one_new( + dbus_message_get_path(message), + interface, + property); + if (changed) { + dbus_connection_send(c, changed, NULL); + dbus_message_unref(changed); + } + + + } else { + const char *interface = dbus_message_get_interface(message); + + if (!interface || !nulstr_contains(interfaces, interface)) { + dbus_set_error_const(&error, DBUS_ERROR_UNKNOWN_INTERFACE, "Unknown interface"); + return bus_send_error_reply(c, message, &error, -EINVAL); + } + } + + if (reply) { + if (!bus_maybe_send_reply(c, message, reply)) + goto oom; + + return DBUS_HANDLER_RESULT_HANDLED; + } + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + +oom: + dbus_error_free(&error); + + return DBUS_HANDLER_RESULT_NEED_MEMORY; +} + +int bus_property_append_string(DBusMessageIter *i, const char *property, void *data) { + const char *t = data; + + assert(i); + assert(property); + + if (!t) + t = ""; + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &t)) + return -ENOMEM; + + return 0; +} + +int bus_property_append_strv(DBusMessageIter *i, const char *property, void *data) { + char **t = data; + + assert(i); + assert(property); + + return bus_append_strv_iter(i, t); +} + +int bus_property_append_bool(DBusMessageIter *i, const char *property, void *data) { + bool *b = data; + dbus_bool_t db; + + assert(i); + assert(property); + assert(b); + + db = *b; + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &db)) + return -ENOMEM; + + return 0; +} + +int bus_property_append_tristate_false(DBusMessageIter *i, const char *property, void *data) { + int *b = data; + dbus_bool_t db; + + assert(i); + assert(property); + assert(b); + + db = *b > 0; + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &db)) + return -ENOMEM; + + return 0; +} + +int bus_property_append_uint64(DBusMessageIter *i, const char *property, void *data) { + assert(i); + assert(property); + assert(data); + + /* Let's ensure that usec_t is actually 64bit, and hence this + * function can be used for usec_t */ + assert_cc(sizeof(uint64_t) == sizeof(usec_t)); + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_UINT64, data)) + return -ENOMEM; + + return 0; +} + +int bus_property_append_uint32(DBusMessageIter *i, const char *property, void *data) { + assert(i); + assert(property); + assert(data); + + /* Let's ensure that pid_t, mode_t, uid_t, gid_t are actually + * 32bit, and hence this function can be used for + * pid_t/mode_t/uid_t/gid_t */ + assert_cc(sizeof(uint32_t) == sizeof(pid_t)); + assert_cc(sizeof(uint32_t) == sizeof(mode_t)); + assert_cc(sizeof(uint32_t) == sizeof(unsigned)); + assert_cc(sizeof(uint32_t) == sizeof(uid_t)); + assert_cc(sizeof(uint32_t) == sizeof(gid_t)); + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_UINT32, data)) + return -ENOMEM; + + return 0; +} + +int bus_property_append_int32(DBusMessageIter *i, const char *property, void *data) { + assert(i); + assert(property); + assert(data); + + assert_cc(sizeof(int32_t) == sizeof(int)); + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_INT32, data)) + return -ENOMEM; + + return 0; +} + +int bus_property_append_size(DBusMessageIter *i, const char *property, void *data) { + uint64_t u; + + assert(i); + assert(property); + assert(data); + + u = (uint64_t) *(size_t*) data; + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_UINT64, &u)) + return -ENOMEM; + + return 0; +} + +int bus_property_append_ul(DBusMessageIter *i, const char *property, void *data) { + uint64_t u; + + assert(i); + assert(property); + assert(data); + + u = (uint64_t) *(unsigned long*) data; + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_UINT64, &u)) + return -ENOMEM; + + return 0; +} + +int bus_property_append_long(DBusMessageIter *i, const char *property, void *data) { + int64_t l; + + assert(i); + assert(property); + assert(data); + + l = (int64_t) *(long*) data; + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_INT64, &l)) + return -ENOMEM; + + return 0; +} + +int bus_property_set_uint64(DBusMessageIter *i, const char *property, void *data) { + uint64_t *t = data; + + assert(i); + assert(property); + + dbus_message_iter_get_basic(i, t); + return 0; +} + +const char *bus_errno_to_dbus(int error) { + + switch(error) { + + case -EINVAL: + return DBUS_ERROR_INVALID_ARGS; + + case -ENOMEM: + return DBUS_ERROR_NO_MEMORY; + + case -EPERM: + case -EACCES: + return DBUS_ERROR_ACCESS_DENIED; + + case -ESRCH: + return DBUS_ERROR_UNIX_PROCESS_ID_UNKNOWN; + + case -ENOENT: + return DBUS_ERROR_FILE_NOT_FOUND; + + case -EEXIST: + return DBUS_ERROR_FILE_EXISTS; + + case -ETIMEDOUT: + case -ETIME: + return DBUS_ERROR_TIMEOUT; + + case -EIO: + return DBUS_ERROR_IO_ERROR; + + case -ENETRESET: + case -ECONNABORTED: + case -ECONNRESET: + return DBUS_ERROR_DISCONNECTED; + } + + return DBUS_ERROR_FAILED; +} + +dbus_bool_t bus_maybe_send_reply (DBusConnection *c, + DBusMessage *message, + DBusMessage *reply) +{ + if (dbus_message_get_no_reply (message)) + return TRUE; + return dbus_connection_send (c, reply, NULL); +} + +DBusHandlerResult bus_send_error_reply(DBusConnection *c, DBusMessage *message, DBusError *berror, int error) { + _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; + const char *name, *text; + + if (berror && dbus_error_is_set(berror)) { + name = berror->name; + text = berror->message; + } else { + name = bus_errno_to_dbus(error); + text = strerror(-error); + } + + reply = dbus_message_new_error(message, name, text); + if (!reply) + goto oom; + + if (!bus_maybe_send_reply(c, message, reply)) + goto oom; + + if (berror) + dbus_error_free(berror); + + return DBUS_HANDLER_RESULT_HANDLED; + +oom: + if (reply) + dbus_message_unref(reply); + + if (berror) + dbus_error_free(berror); + + return DBUS_HANDLER_RESULT_NEED_MEMORY; +} + +DBusMessage* bus_properties_changed_new(const char *path, const char *interface, const char *properties) { + DBusMessage *m; + DBusMessageIter iter, sub; + const char *i; + + assert(interface); + assert(properties); + + m = dbus_message_new_signal(path, "org.freedesktop.DBus.Properties", "PropertiesChanged"); + if (!m) + goto oom; + + dbus_message_iter_init_append(m, &iter); + + /* We won't send any property values, since they might be + * large and sometimes not cheap to generated */ + + if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &interface) || + !dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "{sv}", &sub) || + !dbus_message_iter_close_container(&iter, &sub) || + !dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "s", &sub)) + goto oom; + + NULSTR_FOREACH(i, properties) + if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &i)) + goto oom; + + if (!dbus_message_iter_close_container(&iter, &sub)) + goto oom; + + return m; + +oom: + if (m) + dbus_message_unref(m); + + return NULL; +} + +DBusMessage* bus_properties_changed_one_new(const char *path, const char *interface, const char *property) { + DBusMessage *m; + DBusMessageIter iter, sub; + + assert(interface); + assert(property); + + m = dbus_message_new_signal(path, "org.freedesktop.DBus.Properties", "PropertiesChanged"); + if (!m) + goto oom; + + dbus_message_iter_init_append(m, &iter); + + /* We won't send any property values, since they might be + * large and sometimes not cheap to generated */ + + if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &interface) || + !dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "{sv}", &sub) || + !dbus_message_iter_close_container(&iter, &sub) || + !dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "s", &sub)) + goto oom; + + if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &property)) + goto oom; + + if (!dbus_message_iter_close_container(&iter, &sub)) + goto oom; + + return m; + +oom: + if (m) + dbus_message_unref(m); + + return NULL; +} + +uint32_t bus_flags_to_events(DBusWatch *bus_watch) { + unsigned flags; + uint32_t events = 0; + + assert(bus_watch); + + /* no watch flags for disabled watches */ + if (!dbus_watch_get_enabled(bus_watch)) + return 0; + + flags = dbus_watch_get_flags(bus_watch); + + if (flags & DBUS_WATCH_READABLE) + events |= EPOLLIN; + if (flags & DBUS_WATCH_WRITABLE) + events |= EPOLLOUT; + + return events | EPOLLHUP | EPOLLERR; +} + +unsigned bus_events_to_flags(uint32_t events) { + unsigned flags = 0; + + if (events & EPOLLIN) + flags |= DBUS_WATCH_READABLE; + if (events & EPOLLOUT) + flags |= DBUS_WATCH_WRITABLE; + if (events & EPOLLHUP) + flags |= DBUS_WATCH_HANGUP; + if (events & EPOLLERR) + flags |= DBUS_WATCH_ERROR; + + return flags; +} + +int bus_parse_strv(DBusMessage *m, char ***_l) { + DBusMessageIter iter; + + assert(m); + assert(_l); + + if (!dbus_message_iter_init(m, &iter)) + return -EINVAL; + + return bus_parse_strv_iter(&iter, _l); +} + +int bus_parse_strv_iter(DBusMessageIter *iter, char ***_l) { + DBusMessageIter sub; + unsigned n = 0, i = 0; + char **l; + + assert(iter); + assert(_l); + + if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY || + dbus_message_iter_get_element_type(iter) != DBUS_TYPE_STRING) + return -EINVAL; + + dbus_message_iter_recurse(iter, &sub); + + while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { + n++; + dbus_message_iter_next(&sub); + } + + l = new(char*, n+1); + if (!l) + return -ENOMEM; + + dbus_message_iter_recurse(iter, &sub); + + while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { + const char *s; + + assert_se(dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRING); + dbus_message_iter_get_basic(&sub, &s); + + if (!(l[i++] = strdup(s))) { + strv_free(l); + return -ENOMEM; + } + + dbus_message_iter_next(&sub); + } + + assert(i == n); + l[i] = NULL; + + if (_l) + *_l = l; + + return 0; +} + +int bus_append_strv_iter(DBusMessageIter *iter, char **l) { + DBusMessageIter sub; + + assert(iter); + + if (!dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, "s", &sub)) + return -ENOMEM; + + STRV_FOREACH(l, l) + if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, l)) + return -ENOMEM; + + if (!dbus_message_iter_close_container(iter, &sub)) + return -ENOMEM; + + return 0; +} + +int bus_iter_get_basic_and_next(DBusMessageIter *iter, int type, void *data, bool next) { + + assert(iter); + assert(data); + + if (dbus_message_iter_get_arg_type(iter) != type) + return -EIO; + + dbus_message_iter_get_basic(iter, data); + + if (!dbus_message_iter_next(iter) != !next) + return -EIO; + + return 0; +} + +int generic_print_property(const char *name, DBusMessageIter *iter, bool all) { + assert(name); + assert(iter); + + switch (dbus_message_iter_get_arg_type(iter)) { + + case DBUS_TYPE_STRING: { + const char *s; + dbus_message_iter_get_basic(iter, &s); + + if (all || !isempty(s)) + printf("%s=%s\n", name, s); + + return 1; + } + + case DBUS_TYPE_BOOLEAN: { + dbus_bool_t b; + + dbus_message_iter_get_basic(iter, &b); + printf("%s=%s\n", name, yes_no(b)); + + return 1; + } + + case DBUS_TYPE_UINT64: { + uint64_t u; + dbus_message_iter_get_basic(iter, &u); + + /* Yes, heuristics! But we can change this check + * should it turn out to not be sufficient */ + + if (endswith(name, "Timestamp")) { + char timestamp[FORMAT_TIMESTAMP_MAX], *t; + + t = format_timestamp(timestamp, sizeof(timestamp), u); + if (t || all) + printf("%s=%s\n", name, strempty(t)); + + } else if (strstr(name, "USec")) { + char timespan[FORMAT_TIMESPAN_MAX]; + + printf("%s=%s\n", name, format_timespan(timespan, sizeof(timespan), u)); + } else + printf("%s=%llu\n", name, (unsigned long long) u); + + return 1; + } + + case DBUS_TYPE_UINT32: { + uint32_t u; + dbus_message_iter_get_basic(iter, &u); + + if (strstr(name, "UMask") || strstr(name, "Mode")) + printf("%s=%04o\n", name, u); + else + printf("%s=%u\n", name, (unsigned) u); + + return 1; + } + + case DBUS_TYPE_INT32: { + int32_t i; + dbus_message_iter_get_basic(iter, &i); + + printf("%s=%i\n", name, (int) i); + return 1; + } + + case DBUS_TYPE_DOUBLE: { + double d; + dbus_message_iter_get_basic(iter, &d); + + printf("%s=%g\n", name, d); + return 1; + } + + case DBUS_TYPE_ARRAY: + + if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRING) { + DBusMessageIter sub; + bool space = false; + + dbus_message_iter_recurse(iter, &sub); + if (all || + dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { + printf("%s=", name); + + while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { + const char *s; + + assert(dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRING); + dbus_message_iter_get_basic(&sub, &s); + printf("%s%s", space ? " " : "", s); + + space = true; + dbus_message_iter_next(&sub); + } + + puts(""); + } + + return 1; + + } else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_BYTE) { + DBusMessageIter sub; + + dbus_message_iter_recurse(iter, &sub); + if (all || + dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { + printf("%s=", name); + + while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { + uint8_t u; + + assert(dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_BYTE); + dbus_message_iter_get_basic(&sub, &u); + printf("%02x", u); + + dbus_message_iter_next(&sub); + } + + puts(""); + } + + return 1; + + } else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_UINT32) { + DBusMessageIter sub; + + dbus_message_iter_recurse(iter, &sub); + if (all || + dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { + printf("%s=", name); + + while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { + uint32_t u; + + assert(dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_UINT32); + dbus_message_iter_get_basic(&sub, &u); + printf("%08x", u); + + dbus_message_iter_next(&sub); + } + + puts(""); + } + + return 1; + } + + break; + } + + return 0; +} + +static void release_name_pending_cb(DBusPendingCall *pending, void *userdata) { + DBusMessage *reply; + DBusConnection *bus = userdata; + + assert_se(reply = dbus_pending_call_steal_reply(pending)); + dbus_message_unref(reply); + + dbus_connection_close(bus); +} + +void bus_async_unregister_and_exit(DBusConnection *bus, const char *name) { + _cleanup_dbus_message_unref_ DBusMessage *m = NULL; + DBusPendingCall *pending = NULL; + + assert(bus); + + /* We unregister the name here, but we continue to process + * requests, until we get the response for it, so that all + * requests are guaranteed to be processed. */ + + m = dbus_message_new_method_call( + DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS, + "ReleaseName"); + if (!m) + goto oom; + + if (!dbus_message_append_args( + m, + DBUS_TYPE_STRING, + &name, + DBUS_TYPE_INVALID)) + goto oom; + + if (!dbus_connection_send_with_reply(bus, m, &pending, -1)) + goto oom; + + if (!dbus_pending_call_set_notify(pending, release_name_pending_cb, bus, NULL)) + goto oom; + + dbus_pending_call_unref(pending); + + return; + +oom: + log_oom(); + + if (pending) { + dbus_pending_call_cancel(pending); + dbus_pending_call_unref(pending); + } +} + +DBusHandlerResult bus_exit_idle_filter(DBusConnection *bus, DBusMessage *m, void *userdata) { + usec_t *remain_until = userdata; + + assert(bus); + assert(m); + assert(remain_until); + + /* Every time we get a new message we reset out timeout */ + *remain_until = now(CLOCK_MONOTONIC) + DEFAULT_EXIT_USEC; + + if (dbus_message_is_signal(m, DBUS_INTERFACE_LOCAL, "Disconnected")) + dbus_connection_close(bus); + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +/* This mimics dbus_bus_get_unix_user() */ +pid_t bus_get_unix_process_id( + DBusConnection *connection, + const char *name, + DBusError *error) { + + _cleanup_dbus_message_unref_ DBusMessage *m = NULL, *reply = NULL; + uint32_t pid = 0; + + m = dbus_message_new_method_call( + DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS, + "GetConnectionUnixProcessID"); + if (!m) { + dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, NULL); + return 0; + } + + if (!dbus_message_append_args( + m, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_INVALID)) { + dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, NULL); + return 0; + } + + reply = dbus_connection_send_with_reply_and_block(connection, m, -1, error); + if (!reply) + return 0; + + if (dbus_set_error_from_message(error, reply)) + return 0; + + if (!dbus_message_get_args( + reply, error, + DBUS_TYPE_UINT32, &pid, + DBUS_TYPE_INVALID)) + return 0; + + return (pid_t) pid; +} + +bool bus_error_is_no_service(const DBusError *error) { + assert(error); + + if (!dbus_error_is_set(error)) + return false; + + if (dbus_error_has_name(error, DBUS_ERROR_NAME_HAS_NO_OWNER)) + return true; + + if (dbus_error_has_name(error, DBUS_ERROR_SERVICE_UNKNOWN)) + return true; + + return startswith(error->name, "org.freedesktop.DBus.Error.Spawn."); +} + +int bus_method_call_with_reply( + DBusConnection *bus, + const char *destination, + const char *path, + const char *interface, + const char *method, + DBusMessage **return_reply, + DBusError *return_error, + int first_arg_type, ...) { + + DBusError error; + _cleanup_dbus_message_unref_ DBusMessage *m = NULL; + DBusMessage *reply; + va_list ap; + int r = 0; + + dbus_error_init(&error); + assert(bus); + + m = dbus_message_new_method_call(destination, path, interface, method); + if (!m) { + r = log_oom(); + goto finish; + } + + va_start(ap, first_arg_type); + if (!dbus_message_append_args_valist(m, first_arg_type, ap)) { + va_end(ap); + r = log_oom(); + goto finish; + } + va_end(ap); + + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error); + if (!reply) { + if (!return_error) + log_error("Failed to issue method call: %s", bus_error_message(&error)); + + if (bus_error_is_no_service(&error)) + r = -ENOENT; + else if (dbus_error_has_name(&error, DBUS_ERROR_ACCESS_DENIED)) + r = -EACCES; + else if (dbus_error_has_name(&error, DBUS_ERROR_NO_REPLY)) + r = -ETIMEDOUT; + else + r = -EIO; + goto finish; + } + + if (return_reply) + *return_reply = reply; + else + dbus_message_unref(reply); + +finish: + if (return_error) + *return_error = error; + else + dbus_error_free(&error); + + return r; +} + +void bus_message_unrefp(DBusMessage **reply) { + if (!reply) + return; + + if (!*reply) + return; + + dbus_message_unref(*reply); +} + +const char *bus_message_get_sender_with_fallback(DBusMessage *m) { + const char *s; + + assert(m); + + s = dbus_message_get_sender(m); + if (s) + return s; + + /* When the message came in from a direct connection the + * message will have no sender. We fix that here. */ + + return ":no-sender"; +} diff --git a/src/shared/dbus-common.h b/src/shared/dbus-common.h new file mode 100644 index 000000000..bcbf18ffa --- /dev/null +++ b/src/shared/dbus-common.h @@ -0,0 +1,228 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +#include +#include +#include + +#ifndef DBUS_ERROR_UNKNOWN_OBJECT +#define DBUS_ERROR_UNKNOWN_OBJECT "org.freedesktop.DBus.Error.UnknownObject" +#endif + +#ifndef DBUS_ERROR_UNKNOWN_INTERFACE +#define DBUS_ERROR_UNKNOWN_INTERFACE "org.freedesktop.DBus.Error.UnknownInterface" +#endif + +#ifndef DBUS_ERROR_UNKNOWN_PROPERTY +#define DBUS_ERROR_UNKNOWN_PROPERTY "org.freedesktop.DBus.Error.UnknownProperty" +#endif + +#ifndef DBUS_ERROR_PROPERTY_READ_ONLY +#define DBUS_ERROR_PROPERTY_READ_ONLY "org.freedesktop.DBus.Error.PropertyReadOnly" +#endif + +#define BUS_PROPERTIES_INTERFACE \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" + +#define BUS_INTROSPECTABLE_INTERFACE \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" + +#define BUS_PEER_INTERFACE \ + "\n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + "\n" + +#define BUS_GENERIC_INTERFACES_LIST \ + "org.freedesktop.DBus.Properties\0" \ + "org.freedesktop.DBus.Introspectable\0" \ + "org.freedesktop.DBus.Peer\0" + +int bus_check_peercred(DBusConnection *c); + +int bus_connect(DBusBusType t, DBusConnection **_bus, bool *private_bus, DBusError *error); + +int bus_connect_system_ssh(const char *user, const char *host, DBusConnection **_bus, DBusError *error); +int bus_connect_system_polkit(DBusConnection **_bus, DBusError *error); + +const char *bus_error_message(const DBusError *error); +const char *bus_error_message_or_strerror(const DBusError *error, int err); + +typedef int (*BusPropertyCallback)(DBusMessageIter *iter, const char *property, void *data); +typedef int (*BusPropertySetCallback)(DBusMessageIter *iter, const char *property, void *data); + +typedef struct BusProperty { + const char *property; /* name of the property */ + BusPropertyCallback append; /* Function that is called to serialize this property */ + const char *signature; + const uint16_t offset; /* Offset from BusBoundProperties::base address to the property data. + * uint16_t is sufficient, because we have no structs too big. + * -Werror=overflow will catch it if this does not hold. */ + bool indirect; /* data is indirect, ie. not base+offset, but *(base+offset) */ + BusPropertySetCallback set; /* Optional: Function that is called to set this property */ +} BusProperty; + +typedef struct BusBoundProperties { + const char *interface; /* interface of the properties */ + const BusProperty *properties; /* array of properties, ended by a NULL-filled element */ + const void *const base; /* base pointer to which the offset must be added to reach data */ +} BusBoundProperties; + +dbus_bool_t bus_maybe_send_reply (DBusConnection *c, + DBusMessage *message, + DBusMessage *reply); + +DBusHandlerResult bus_send_error_reply( + DBusConnection *c, + DBusMessage *message, + DBusError *bus_error, + int error); + +DBusHandlerResult bus_default_message_handler( + DBusConnection *c, + DBusMessage *message, + const char *introspection, + const char *interfaces, + const BusBoundProperties *bound_properties); + +int bus_property_append_string(DBusMessageIter *i, const char *property, void *data); +int bus_property_append_strv(DBusMessageIter *i, const char *property, void *data); +int bus_property_append_bool(DBusMessageIter *i, const char *property, void *data); +int bus_property_append_tristate_false(DBusMessageIter *i, const char *property, void *data); +int bus_property_append_int32(DBusMessageIter *i, const char *property, void *data); +int bus_property_append_uint32(DBusMessageIter *i, const char *property, void *data); +int bus_property_append_uint64(DBusMessageIter *i, const char *property, void *data); +int bus_property_append_size(DBusMessageIter *i, const char *property, void *data); +int bus_property_append_ul(DBusMessageIter *i, const char *property, void *data); +int bus_property_append_long(DBusMessageIter *i, const char *property, void *data); + +#define bus_property_append_int bus_property_append_int32 +#define bus_property_append_pid bus_property_append_uint32 +#define bus_property_append_uid bus_property_append_uint32 +#define bus_property_append_gid bus_property_append_uint32 +#define bus_property_append_mode bus_property_append_uint32 +#define bus_property_append_unsigned bus_property_append_uint32 +#define bus_property_append_usec bus_property_append_uint64 + +int bus_property_set_uint64(DBusMessageIter *i, const char *property, void *data); +#define bus_property_set_usec bus_property_set_uint64 + +#define DEFINE_BUS_PROPERTY_APPEND_ENUM(function,name,type) \ + int function(DBusMessageIter *i, const char *property, void *data) { \ + const char *value; \ + type *field = data; \ + \ + assert(i); \ + assert(property); \ + \ + value = strempty(name##_to_string(*field)); \ + \ + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &value)) \ + return -ENOMEM; \ + \ + return 0; \ + } + +#define DEFINE_BUS_PROPERTY_SET_ENUM(function,name,type) \ + int function(DBusMessageIter *i, const char *property, void *data) { \ + const char *value; \ + type f, *field = data; \ + \ + assert(i); \ + assert(property); \ + \ + dbus_message_iter_get_basic(i, &value); \ + \ + f = name##_from_string(value); \ + if (f < 0) \ + return f; \ + \ + *field = f; \ + return 0; \ + } + +const char *bus_errno_to_dbus(int error); + +DBusMessage* bus_properties_changed_new(const char *path, const char *interface, const char *properties); +DBusMessage* bus_properties_changed_one_new(const char *path, const char *interface, const char *property); + +uint32_t bus_flags_to_events(DBusWatch *bus_watch); +unsigned bus_events_to_flags(uint32_t events); + +int bus_parse_strv(DBusMessage *m, char ***_l); +int bus_parse_strv_iter(DBusMessageIter *iter, char ***_l); + +int bus_append_strv_iter(DBusMessageIter *iter, char **l); + +int bus_iter_get_basic_and_next(DBusMessageIter *iter, int type, void *data, bool next); + +int generic_print_property(const char *name, DBusMessageIter *iter, bool all); + +void bus_async_unregister_and_exit(DBusConnection *bus, const char *name); + +DBusHandlerResult bus_exit_idle_filter(DBusConnection *bus, DBusMessage *m, void *userdata); + +pid_t bus_get_unix_process_id(DBusConnection *connection, const char *name, DBusError *error); + +bool bus_error_is_no_service(const DBusError *error); +int bus_method_call_with_reply(DBusConnection *bus, + const char *destination, + const char *path, + const char *interface, + const char *method, + DBusMessage **return_reply, + DBusError *return_error, + int first_arg_type, ...); + +const char *bus_message_get_sender_with_fallback(DBusMessage *m); + +void bus_message_unrefp(DBusMessage **reply); + +#define _cleanup_dbus_message_unref_ __attribute__((cleanup(bus_message_unrefp))) +#define _cleanup_dbus_error_free_ __attribute__((cleanup(dbus_error_free))) diff --git a/src/shared/dbus-loop.c b/src/shared/dbus-loop.c new file mode 100644 index 000000000..da0a00443 --- /dev/null +++ b/src/shared/dbus-loop.c @@ -0,0 +1,263 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include + +#include "dbus-loop.h" +#include "dbus-common.h" +#include "util.h" + +/* Minimal implementation of the dbus loop which integrates all dbus + * events into a single epoll fd which we can triviall integrate with + * other loops. Note that this is not used in the main systemd daemon + * since we run a more elaborate mainloop there. */ + +typedef struct EpollData { + int fd; + void *object; + bool is_timeout:1; + bool fd_is_dupped:1; +} EpollData; + +static dbus_bool_t add_watch(DBusWatch *watch, void *data) { + EpollData *e; + struct epoll_event ev; + + assert(watch); + + e = new0(EpollData, 1); + if (!e) + return FALSE; + + e->fd = dbus_watch_get_unix_fd(watch); + e->object = watch; + e->is_timeout = false; + + zero(ev); + ev.events = bus_flags_to_events(watch); + ev.data.ptr = e; + + if (epoll_ctl(PTR_TO_INT(data), EPOLL_CTL_ADD, e->fd, &ev) < 0) { + + if (errno != EEXIST) { + free(e); + return FALSE; + } + + /* Hmm, bloody D-Bus creates multiple watches on the + * same fd. epoll() does not like that. As a dirty + * hack we simply dup() the fd and hence get a second + * one we can safely add to the epoll(). */ + + e->fd = dup(e->fd); + if (e->fd < 0) { + free(e); + return FALSE; + } + + if (epoll_ctl(PTR_TO_INT(data), EPOLL_CTL_ADD, e->fd, &ev) < 0) { + close_nointr_nofail(e->fd); + free(e); + return FALSE; + } + + e->fd_is_dupped = true; + } + + dbus_watch_set_data(watch, e, NULL); + + return TRUE; +} + +static void remove_watch(DBusWatch *watch, void *data) { + EpollData *e; + + assert(watch); + + e = dbus_watch_get_data(watch); + if (!e) + return; + + assert_se(epoll_ctl(PTR_TO_INT(data), EPOLL_CTL_DEL, e->fd, NULL) >= 0); + + if (e->fd_is_dupped) + close_nointr_nofail(e->fd); + + free(e); +} + +static void toggle_watch(DBusWatch *watch, void *data) { + EpollData *e; + struct epoll_event ev; + + assert(watch); + + e = dbus_watch_get_data(watch); + if (!e) + return; + + zero(ev); + ev.events = bus_flags_to_events(watch); + ev.data.ptr = e; + + assert_se(epoll_ctl(PTR_TO_INT(data), EPOLL_CTL_MOD, e->fd, &ev) == 0); +} + +static int timeout_arm(EpollData *e) { + struct itimerspec its; + + assert(e); + assert(e->is_timeout); + + zero(its); + + if (dbus_timeout_get_enabled(e->object)) { + timespec_store(&its.it_value, dbus_timeout_get_interval(e->object) * USEC_PER_MSEC); + its.it_interval = its.it_value; + } + + if (timerfd_settime(e->fd, 0, &its, NULL) < 0) + return -errno; + + return 0; +} + +static dbus_bool_t add_timeout(DBusTimeout *timeout, void *data) { + EpollData *e; + struct epoll_event ev; + + assert(timeout); + + e = new0(EpollData, 1); + if (!e) + return FALSE; + + e->fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK|TFD_CLOEXEC); + if (e->fd < 0) + goto fail; + + e->object = timeout; + e->is_timeout = true; + + if (timeout_arm(e) < 0) + goto fail; + + zero(ev); + ev.events = EPOLLIN; + ev.data.ptr = e; + + if (epoll_ctl(PTR_TO_INT(data), EPOLL_CTL_ADD, e->fd, &ev) < 0) + goto fail; + + dbus_timeout_set_data(timeout, e, NULL); + + return TRUE; + +fail: + if (e->fd >= 0) + close_nointr_nofail(e->fd); + + free(e); + return FALSE; +} + +static void remove_timeout(DBusTimeout *timeout, void *data) { + EpollData *e; + + assert(timeout); + + e = dbus_timeout_get_data(timeout); + if (!e) + return; + + assert_se(epoll_ctl(PTR_TO_INT(data), EPOLL_CTL_DEL, e->fd, NULL) >= 0); + close_nointr_nofail(e->fd); + free(e); +} + +static void toggle_timeout(DBusTimeout *timeout, void *data) { + EpollData *e; + int r; + + assert(timeout); + + e = dbus_timeout_get_data(timeout); + if (!e) + return; + + r = timeout_arm(e); + if (r < 0) + log_error("Failed to rearm timer: %s", strerror(-r)); +} + +int bus_loop_open(DBusConnection *c) { + int fd; + + assert(c); + + fd = epoll_create1(EPOLL_CLOEXEC); + if (fd < 0) + return -errno; + + if (!dbus_connection_set_watch_functions(c, add_watch, remove_watch, toggle_watch, INT_TO_PTR(fd), NULL) || + !dbus_connection_set_timeout_functions(c, add_timeout, remove_timeout, toggle_timeout, INT_TO_PTR(fd), NULL)) { + close_nointr_nofail(fd); + return -ENOMEM; + } + + return fd; +} + +int bus_loop_dispatch(int fd) { + int n; + struct epoll_event event; + EpollData *d; + + assert(fd >= 0); + + zero(event); + + n = epoll_wait(fd, &event, 1, 0); + if (n < 0) + return errno == EAGAIN || errno == EINTR ? 0 : -errno; + + assert_se(d = event.data.ptr); + + if (d->is_timeout) { + DBusTimeout *t = d->object; + + if (dbus_timeout_get_enabled(t)) + dbus_timeout_handle(t); + } else { + DBusWatch *w = d->object; + + if (dbus_watch_get_enabled(w)) + dbus_watch_handle(w, bus_events_to_flags(event.events)); + } + + return 0; +} diff --git a/src/shared/dbus-loop.h b/src/shared/dbus-loop.h new file mode 100644 index 000000000..a5e768d93 --- /dev/null +++ b/src/shared/dbus-loop.h @@ -0,0 +1,27 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +#include + +int bus_loop_open(DBusConnection *c); +int bus_loop_dispatch(int fd); diff --git a/src/shared/def.h b/src/shared/def.h new file mode 100644 index 000000000..5ba170f96 --- /dev/null +++ b/src/shared/def.h @@ -0,0 +1,35 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +#include "util.h" + +#define DEFAULT_TIMEOUT_USEC (90*USEC_PER_SEC) +#define DEFAULT_RESTART_USEC (100*USEC_PER_MSEC) +#define DEFAULT_CONFIRM_USEC (30*USEC_PER_SEC) + +#define DEFAULT_EXIT_USEC (5*USEC_PER_MINUTE) + +#define SYSTEMD_CGROUP_CONTROLLER "name=systemd" + +#define SIGNALS_CRASH_HANDLER SIGSEGV,SIGILL,SIGFPE,SIGBUS,SIGQUIT,SIGABRT +#define SIGNALS_IGNORE SIGKILL,SIGPIPE diff --git a/src/shared/dev-setup.c b/src/shared/dev-setup.c new file mode 100644 index 000000000..b0ac02d46 --- /dev/null +++ b/src/shared/dev-setup.c @@ -0,0 +1,78 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010-2012 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 . +***/ + +#include +#include +#include +#include +#include +#include + +#include "dev-setup.h" +#include "log.h" +#include "macro.h" +#include "util.h" +#include "label.h" + +static int symlink_and_label(const char *old_path, const char *new_path) { + int r; + + assert(old_path); + assert(new_path); + + r = label_context_set(new_path, S_IFLNK); + if (r < 0) + return r; + + if (symlink(old_path, new_path) < 0) + r = -errno; + + label_context_clear(); + + return r; +} + +void dev_setup(const char *prefix) { + const char *j, *k; + + static const char symlinks[] = + "/proc/kcore\0" "/dev/core\0" + "/proc/self/fd\0" "/dev/fd\0" + "/proc/self/fd/0\0" "/dev/stdin\0" + "/proc/self/fd/1\0" "/dev/stdout\0" + "/proc/self/fd/2\0" "/dev/stderr\0"; + + NULSTR_FOREACH_PAIR(j, k, symlinks) { + + if (prefix) { + char *linkname; + + if (asprintf(&linkname, "%s/%s", prefix, k) < 0) { + log_oom(); + break; + } + + symlink_and_label(j, linkname); + free(linkname); + } else + symlink_and_label(j, k); + } +} diff --git a/src/shared/dev-setup.h b/src/shared/dev-setup.h new file mode 100644 index 000000000..320c0b30b --- /dev/null +++ b/src/shared/dev-setup.h @@ -0,0 +1,24 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2010-2012 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 . +***/ + +void dev_setup(const char *pathprefix); diff --git a/src/shared/exit-status.c b/src/shared/exit-status.c new file mode 100644 index 000000000..45131f2b2 --- /dev/null +++ b/src/shared/exit-status.c @@ -0,0 +1,192 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include + +#include "exit-status.h" +#include "set.h" +#include "macro.h" + +const char* exit_status_to_string(ExitStatus status, ExitStatusLevel level) { + + /* We cast to int here, so that -Wenum doesn't complain that + * EXIT_SUCCESS/EXIT_FAILURE aren't in the enum */ + + switch ((int) status) { + + case EXIT_SUCCESS: + return "SUCCESS"; + + case EXIT_FAILURE: + return "FAILURE"; + } + + + if (level == EXIT_STATUS_SYSTEMD || level == EXIT_STATUS_LSB) { + switch ((int) status) { + + case EXIT_CHDIR: + return "CHDIR"; + + case EXIT_NICE: + return "NICE"; + + case EXIT_FDS: + return "FDS"; + + case EXIT_EXEC: + return "EXEC"; + + case EXIT_MEMORY: + return "MEMORY"; + + case EXIT_LIMITS: + return "LIMITS"; + + case EXIT_OOM_ADJUST: + return "OOM_ADJUST"; + + case EXIT_SIGNAL_MASK: + return "SIGNAL_MASK"; + + case EXIT_STDIN: + return "STDIN"; + + case EXIT_STDOUT: + return "STDOUT"; + + case EXIT_CHROOT: + return "CHROOT"; + + case EXIT_IOPRIO: + return "IOPRIO"; + + case EXIT_TIMERSLACK: + return "TIMERSLACK"; + + case EXIT_SECUREBITS: + return "SECUREBITS"; + + case EXIT_SETSCHEDULER: + return "SETSCHEDULER"; + + case EXIT_CPUAFFINITY: + return "CPUAFFINITY"; + + case EXIT_GROUP: + return "GROUP"; + + case EXIT_USER: + return "USER"; + + case EXIT_CAPABILITIES: + return "CAPABILITIES"; + + case EXIT_CGROUP: + return "CGROUP"; + + case EXIT_SETSID: + return "SETSID"; + + case EXIT_CONFIRM: + return "CONFIRM"; + + case EXIT_STDERR: + return "STDERR"; + + case EXIT_TCPWRAP: + return "TCPWRAP"; + + case EXIT_PAM: + return "PAM"; + + case EXIT_NETWORK: + return "NETWORK"; + + case EXIT_NAMESPACE: + return "NAMESPACE"; + + case EXIT_NO_NEW_PRIVILEGES: + return "NO_NEW_PRIVILEGES"; + + case EXIT_SECCOMP: + return "SECCOMP"; + } + } + + if (level == EXIT_STATUS_LSB) { + switch ((int) status) { + + case EXIT_INVALIDARGUMENT: + return "INVALIDARGUMENT"; + + case EXIT_NOTIMPLEMENTED: + return "NOTIMPLEMENTED"; + + case EXIT_NOPERMISSION: + return "NOPERMISSION"; + + case EXIT_NOTINSTALLED: + return "NOTINSSTALLED"; + + case EXIT_NOTCONFIGURED: + return "NOTCONFIGURED"; + + case EXIT_NOTRUNNING: + return "NOTRUNNING"; + } + } + + return NULL; +} + + +bool is_clean_exit(int code, int status, ExitStatusSet *success_status) { + + if (code == CLD_EXITED) + return status == 0 || + (success_status && + set_contains(success_status->code, INT_TO_PTR(status))); + + /* If a daemon does not implement handlers for some of the + * signals that's not considered an unclean shutdown */ + if (code == CLD_KILLED) + return + status == SIGHUP || + status == SIGINT || + status == SIGTERM || + status == SIGPIPE || + (success_status && + set_contains(success_status->signal, INT_TO_PTR(status))); + + return false; +} + +bool is_clean_exit_lsb(int code, int status, ExitStatusSet *success_status) { + + if (is_clean_exit(code, status, success_status)) + return true; + + return + code == CLD_EXITED && + (status == EXIT_NOTINSTALLED || status == EXIT_NOTCONFIGURED); +} diff --git a/src/shared/exit-status.h b/src/shared/exit-status.h new file mode 100644 index 000000000..d3b548fc9 --- /dev/null +++ b/src/shared/exit-status.h @@ -0,0 +1,88 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +#include +#include "set.h" +typedef enum ExitStatus { + /* EXIT_SUCCESS defined by libc */ + /* EXIT_FAILURE defined by libc */ + EXIT_INVALIDARGUMENT = 2, + EXIT_NOTIMPLEMENTED = 3, + EXIT_NOPERMISSION = 4, + EXIT_NOTINSTALLED = 5, + EXIT_NOTCONFIGURED = 6, + EXIT_NOTRUNNING = 7, + + /* The LSB suggests that error codes >= 200 are "reserved". We + * use them here under the assumption that they hence are + * unused by init scripts. + * + * http://refspecs.freestandards.org/LSB_3.1.0/LSB-Core-generic/LSB-Core-generic/iniscrptact.html */ + + EXIT_CHDIR = 200, + EXIT_NICE, + EXIT_FDS, + EXIT_EXEC, + EXIT_MEMORY, + EXIT_LIMITS, + EXIT_OOM_ADJUST, + EXIT_SIGNAL_MASK, + EXIT_STDIN, + EXIT_STDOUT, + EXIT_CHROOT, /* 210 */ + EXIT_IOPRIO, + EXIT_TIMERSLACK, + EXIT_SECUREBITS, + EXIT_SETSCHEDULER, + EXIT_CPUAFFINITY, + EXIT_GROUP, + EXIT_USER, + EXIT_CAPABILITIES, + EXIT_CGROUP, + EXIT_SETSID, /* 220 */ + EXIT_CONFIRM, + EXIT_STDERR, + EXIT_TCPWRAP, + EXIT_PAM, + EXIT_NETWORK, + EXIT_NAMESPACE, + EXIT_NO_NEW_PRIVILEGES, + EXIT_SECCOMP +} ExitStatus; + +typedef enum ExitStatusLevel { + EXIT_STATUS_MINIMAL, + EXIT_STATUS_SYSTEMD, + EXIT_STATUS_LSB, + EXIT_STATUS_FULL = EXIT_STATUS_LSB +} ExitStatusLevel; + +typedef struct ExitStatusSet { + Set *code; + Set *signal; +} ExitStatusSet; + +const char* exit_status_to_string(ExitStatus status, ExitStatusLevel level); + +bool is_clean_exit(int code, int status, ExitStatusSet *success_status); +bool is_clean_exit_lsb(int code, int status, ExitStatusSet *success_status); diff --git a/src/shared/fdset.c b/src/shared/fdset.c new file mode 100644 index 000000000..fd27398eb --- /dev/null +++ b/src/shared/fdset.c @@ -0,0 +1,236 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include + +#include "set.h" +#include "util.h" +#include "macro.h" +#include "fdset.h" +#include "sd-daemon.h" + +#define MAKE_SET(s) ((Set*) s) +#define MAKE_FDSET(s) ((FDSet*) s) + +/* Make sure we can distuingish fd 0 and NULL */ +#define FD_TO_PTR(fd) INT_TO_PTR((fd)+1) +#define PTR_TO_FD(p) (PTR_TO_INT(p)-1) + +FDSet *fdset_new(void) { + return MAKE_FDSET(set_new(trivial_hash_func, trivial_compare_func)); +} + +void fdset_free(FDSet *s) { + void *p; + + while ((p = set_steal_first(MAKE_SET(s)))) { + /* Valgrind's fd might have ended up in this set here, + * due to fdset_new_fill(). We'll ignore all failures + * here, so that the EBADFD that valgrind will return + * us on close() doesn't influence us */ + + /* When reloading duplicates of the private bus + * connection fds and suchlike are closed here, which + * has no effect at all, since they are only + * duplicates. So don't be surprised about these log + * messages. */ + + log_debug("Closing left-over fd %i", PTR_TO_FD(p)); + close_nointr(PTR_TO_FD(p)); + } + + set_free(MAKE_SET(s)); +} + +int fdset_put(FDSet *s, int fd) { + assert(s); + assert(fd >= 0); + + return set_put(MAKE_SET(s), FD_TO_PTR(fd)); +} + +int fdset_put_dup(FDSet *s, int fd) { + int copy, r; + + assert(s); + assert(fd >= 0); + + copy = fcntl(fd, F_DUPFD_CLOEXEC, 3); + if (copy < 0) + return -errno; + + r = fdset_put(s, copy); + if (r < 0) { + close_nointr_nofail(copy); + return r; + } + + return copy; +} + +bool fdset_contains(FDSet *s, int fd) { + assert(s); + assert(fd >= 0); + + return !!set_get(MAKE_SET(s), FD_TO_PTR(fd)); +} + +int fdset_remove(FDSet *s, int fd) { + assert(s); + assert(fd >= 0); + + return set_remove(MAKE_SET(s), FD_TO_PTR(fd)) ? fd : -ENOENT; +} + +int fdset_new_fill(FDSet **_s) { + DIR *d; + struct dirent *de; + int r = 0; + FDSet *s; + + assert(_s); + + /* Creates an fdset and fills in all currently open file + * descriptors. */ + + d = opendir("/proc/self/fd"); + if (!d) + return -errno; + + s = fdset_new(); + if (!s) { + r = -ENOMEM; + goto finish; + } + + while ((de = readdir(d))) { + int fd = -1; + + if (ignore_file(de->d_name)) + continue; + + r = safe_atoi(de->d_name, &fd); + if (r < 0) + goto finish; + + if (fd < 3) + continue; + + if (fd == dirfd(d)) + continue; + + r = fdset_put(s, fd); + if (r < 0) + goto finish; + } + + r = 0; + *_s = s; + s = NULL; + +finish: + closedir(d); + + /* We won't close the fds here! */ + if (s) + set_free(MAKE_SET(s)); + + return r; +} + +int fdset_cloexec(FDSet *fds, bool b) { + Iterator i; + void *p; + int r; + + assert(fds); + + SET_FOREACH(p, MAKE_SET(fds), i) + if ((r = fd_cloexec(PTR_TO_FD(p), b)) < 0) + return r; + + return 0; +} + +int fdset_new_listen_fds(FDSet **_s, bool unset) { + int n, fd, r; + FDSet *s; + + assert(_s); + + /* Creates an fdset and fills in all passed file descriptors */ + + s = fdset_new(); + if (!s) { + r = -ENOMEM; + goto fail; + } + + n = sd_listen_fds(unset); + for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++) { + r = fdset_put(s, fd); + if (r < 0) + goto fail; + } + + *_s = s; + return 0; + + +fail: + if (s) + set_free(MAKE_SET(s)); + + return r; +} + +int fdset_close_others(FDSet *fds) { + void *e; + Iterator i; + int *a; + unsigned j, m; + + j = 0, m = fdset_size(fds); + a = alloca(sizeof(int) * m); + SET_FOREACH(e, MAKE_SET(fds), i) + a[j++] = PTR_TO_FD(e); + + assert(j == m); + + return close_all_fds(a, j); +} + +unsigned fdset_size(FDSet *fds) { + return set_size(MAKE_SET(fds)); +} + +int fdset_iterate(FDSet *s, Iterator *i) { + void *p; + + p = set_iterate(MAKE_SET(s), i); + if (!p) + return -ENOENT; + + return PTR_TO_FD(p); +} diff --git a/src/shared/fdset.h b/src/shared/fdset.h new file mode 100644 index 000000000..a7bd5e2b4 --- /dev/null +++ b/src/shared/fdset.h @@ -0,0 +1,49 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +#include "set.h" + +typedef struct FDSet FDSet; + +FDSet* fdset_new(void); +void fdset_free(FDSet *s); + +int fdset_put(FDSet *s, int fd); +int fdset_put_dup(FDSet *s, int fd); + +bool fdset_contains(FDSet *s, int fd); +int fdset_remove(FDSet *s, int fd); + +int fdset_new_fill(FDSet **_s); +int fdset_new_listen_fds(FDSet **_s, bool unset); + +int fdset_cloexec(FDSet *fds, bool b); + +int fdset_close_others(FDSet *fds); + +unsigned fdset_size(FDSet *fds); + +int fdset_iterate(FDSet *s, Iterator *i); + +#define FDSET_FOREACH(fd, fds, i) \ + for ((i) = ITERATOR_FIRST, (fd) = fdset_iterate((fds), &(i)); (fd) >= 0; (fd) = fdset_iterate((fds), &(i))) diff --git a/src/shared/hashmap.c b/src/shared/hashmap.c new file mode 100644 index 000000000..a2c728d64 --- /dev/null +++ b/src/shared/hashmap.c @@ -0,0 +1,835 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include + +#include "util.h" +#include "hashmap.h" +#include "macro.h" + +#define NBUCKETS 127 + +struct hashmap_entry { + const void *key; + void *value; + struct hashmap_entry *bucket_next, *bucket_previous; + struct hashmap_entry *iterate_next, *iterate_previous; +}; + +struct Hashmap { + hash_func_t hash_func; + compare_func_t compare_func; + + struct hashmap_entry *iterate_list_head, *iterate_list_tail; + unsigned n_entries; + + bool from_pool; +}; + +#define BY_HASH(h) ((struct hashmap_entry**) ((uint8_t*) (h) + ALIGN(sizeof(Hashmap)))) + +struct pool { + struct pool *next; + unsigned n_tiles; + unsigned n_used; +}; + +static struct pool *first_hashmap_pool = NULL; +static void *first_hashmap_tile = NULL; + +static struct pool *first_entry_pool = NULL; +static void *first_entry_tile = NULL; + +static void* allocate_tile(struct pool **first_pool, void **first_tile, size_t tile_size) { + unsigned i; + + if (*first_tile) { + void *r; + + r = *first_tile; + *first_tile = * (void**) (*first_tile); + return r; + } + + if (_unlikely_(!*first_pool) || _unlikely_((*first_pool)->n_used >= (*first_pool)->n_tiles)) { + unsigned n; + size_t size; + struct pool *p; + + n = *first_pool ? (*first_pool)->n_tiles : 0; + n = MAX(512U, n * 2); + size = PAGE_ALIGN(ALIGN(sizeof(struct pool)) + n*tile_size); + n = (size - ALIGN(sizeof(struct pool))) / tile_size; + + p = malloc(size); + if (!p) + return NULL; + + p->next = *first_pool; + p->n_tiles = n; + p->n_used = 0; + + *first_pool = p; + } + + i = (*first_pool)->n_used++; + + return ((uint8_t*) (*first_pool)) + ALIGN(sizeof(struct pool)) + i*tile_size; +} + +static void deallocate_tile(void **first_tile, void *p) { + * (void**) p = *first_tile; + *first_tile = p; +} + +#ifdef VALGRIND + +static void drop_pool(struct pool *p) { + while (p) { + struct pool *n; + n = p->next; + free(p); + p = n; + } +} + +__attribute__((destructor)) static void cleanup_pool(void) { + /* Be nice to valgrind */ + + drop_pool(first_hashmap_pool); + drop_pool(first_entry_pool); +} + +#endif + +unsigned string_hash_func(const void *p) { + unsigned hash = 5381; + const signed char *c; + + /* DJB's hash function */ + + for (c = p; *c; c++) + hash = (hash << 5) + hash + (unsigned) *c; + + return hash; +} + +int string_compare_func(const void *a, const void *b) { + return strcmp(a, b); +} + +unsigned trivial_hash_func(const void *p) { + return PTR_TO_UINT(p); +} + +int trivial_compare_func(const void *a, const void *b) { + return a < b ? -1 : (a > b ? 1 : 0); +} + +unsigned uint64_hash_func(const void *p) { + uint64_t u; + + assert_cc(sizeof(uint64_t) == 2*sizeof(unsigned)); + + u = *(const uint64_t*) p; + + return (unsigned) ((u >> 32) ^ u); +} + +int uint64_compare_func(const void *_a, const void *_b) { + uint64_t a, b; + + a = *(const uint64_t*) _a; + b = *(const uint64_t*) _b; + + return a < b ? -1 : (a > b ? 1 : 0); +} + +Hashmap *hashmap_new(hash_func_t hash_func, compare_func_t compare_func) { + bool b; + Hashmap *h; + size_t size; + + b = is_main_thread(); + + size = ALIGN(sizeof(Hashmap)) + NBUCKETS * sizeof(struct hashmap_entry*); + + if (b) { + h = allocate_tile(&first_hashmap_pool, &first_hashmap_tile, size); + if (!h) + return NULL; + + memset(h, 0, size); + } else { + h = malloc0(size); + + if (!h) + return NULL; + } + + h->hash_func = hash_func ? hash_func : trivial_hash_func; + h->compare_func = compare_func ? compare_func : trivial_compare_func; + + h->n_entries = 0; + h->iterate_list_head = h->iterate_list_tail = NULL; + + h->from_pool = b; + + return h; +} + +int hashmap_ensure_allocated(Hashmap **h, hash_func_t hash_func, compare_func_t compare_func) { + assert(h); + + if (*h) + return 0; + + if (!(*h = hashmap_new(hash_func, compare_func))) + return -ENOMEM; + + return 0; +} + +static void link_entry(Hashmap *h, struct hashmap_entry *e, unsigned hash) { + assert(h); + assert(e); + + /* Insert into hash table */ + e->bucket_next = BY_HASH(h)[hash]; + e->bucket_previous = NULL; + if (BY_HASH(h)[hash]) + BY_HASH(h)[hash]->bucket_previous = e; + BY_HASH(h)[hash] = e; + + /* Insert into iteration list */ + e->iterate_previous = h->iterate_list_tail; + e->iterate_next = NULL; + if (h->iterate_list_tail) { + assert(h->iterate_list_head); + h->iterate_list_tail->iterate_next = e; + } else { + assert(!h->iterate_list_head); + h->iterate_list_head = e; + } + h->iterate_list_tail = e; + + h->n_entries++; + assert(h->n_entries >= 1); +} + +static void unlink_entry(Hashmap *h, struct hashmap_entry *e, unsigned hash) { + assert(h); + assert(e); + + /* Remove from iteration list */ + if (e->iterate_next) + e->iterate_next->iterate_previous = e->iterate_previous; + else + h->iterate_list_tail = e->iterate_previous; + + if (e->iterate_previous) + e->iterate_previous->iterate_next = e->iterate_next; + else + h->iterate_list_head = e->iterate_next; + + /* Remove from hash table bucket list */ + if (e->bucket_next) + e->bucket_next->bucket_previous = e->bucket_previous; + + if (e->bucket_previous) + e->bucket_previous->bucket_next = e->bucket_next; + else + BY_HASH(h)[hash] = e->bucket_next; + + assert(h->n_entries >= 1); + h->n_entries--; +} + +static void remove_entry(Hashmap *h, struct hashmap_entry *e) { + unsigned hash; + + assert(h); + assert(e); + + hash = h->hash_func(e->key) % NBUCKETS; + + unlink_entry(h, e, hash); + + if (h->from_pool) + deallocate_tile(&first_entry_tile, e); + else + free(e); +} + +void hashmap_free(Hashmap*h) { + + /* Free the hashmap, but nothing in it */ + + if (!h) + return; + + hashmap_clear(h); + + if (h->from_pool) + deallocate_tile(&first_hashmap_tile, h); + else + free(h); +} + +void hashmap_free_free(Hashmap *h) { + + /* Free the hashmap and all data objects in it, but not the + * keys */ + + if (!h) + return; + + hashmap_clear_free(h); + hashmap_free(h); +} + +void hashmap_clear(Hashmap *h) { + if (!h) + return; + + while (h->iterate_list_head) + remove_entry(h, h->iterate_list_head); +} + +void hashmap_clear_free(Hashmap *h) { + void *p; + + if (!h) + return; + + while ((p = hashmap_steal_first(h))) + free(p); +} + +static struct hashmap_entry *hash_scan(Hashmap *h, unsigned hash, const void *key) { + struct hashmap_entry *e; + assert(h); + assert(hash < NBUCKETS); + + for (e = BY_HASH(h)[hash]; e; e = e->bucket_next) + if (h->compare_func(e->key, key) == 0) + return e; + + return NULL; +} + +int hashmap_put(Hashmap *h, const void *key, void *value) { + struct hashmap_entry *e; + unsigned hash; + + assert(h); + + hash = h->hash_func(key) % NBUCKETS; + + e = hash_scan(h, hash, key); + if (e) { + + if (e->value == value) + return 0; + + return -EEXIST; + } + + if (h->from_pool) + e = allocate_tile(&first_entry_pool, &first_entry_tile, sizeof(struct hashmap_entry)); + else + e = new(struct hashmap_entry, 1); + + if (!e) + return -ENOMEM; + + e->key = key; + e->value = value; + + link_entry(h, e, hash); + + return 1; +} + +int hashmap_replace(Hashmap *h, const void *key, void *value) { + struct hashmap_entry *e; + unsigned hash; + + assert(h); + + hash = h->hash_func(key) % NBUCKETS; + e = hash_scan(h, hash, key); + if (e) { + e->key = key; + e->value = value; + return 0; + } + + return hashmap_put(h, key, value); +} + +int hashmap_update(Hashmap *h, const void *key, void *value) { + struct hashmap_entry *e; + unsigned hash; + + assert(h); + + hash = h->hash_func(key) % NBUCKETS; + e = hash_scan(h, hash, key); + if (!e) + return -ENOENT; + + e->value = value; + return 0; +} + +void* hashmap_get(Hashmap *h, const void *key) { + unsigned hash; + struct hashmap_entry *e; + + if (!h) + return NULL; + + hash = h->hash_func(key) % NBUCKETS; + e = hash_scan(h, hash, key); + if (!e) + return NULL; + + return e->value; +} + +void* hashmap_get2(Hashmap *h, const void *key, void **key2) { + unsigned hash; + struct hashmap_entry *e; + + if (!h) + return NULL; + + hash = h->hash_func(key) % NBUCKETS; + e = hash_scan(h, hash, key); + if (!e) + return NULL; + + if (key2) + *key2 = (void*) e->key; + + return e->value; +} + +bool hashmap_contains(Hashmap *h, const void *key) { + unsigned hash; + + if (!h) + return false; + + hash = h->hash_func(key) % NBUCKETS; + + if (!hash_scan(h, hash, key)) + return false; + + return true; +} + +void* hashmap_remove(Hashmap *h, const void *key) { + struct hashmap_entry *e; + unsigned hash; + void *data; + + if (!h) + return NULL; + + hash = h->hash_func(key) % NBUCKETS; + + if (!(e = hash_scan(h, hash, key))) + return NULL; + + data = e->value; + remove_entry(h, e); + + return data; +} + +int hashmap_remove_and_put(Hashmap *h, const void *old_key, const void *new_key, void *value) { + struct hashmap_entry *e; + unsigned old_hash, new_hash; + + if (!h) + return -ENOENT; + + old_hash = h->hash_func(old_key) % NBUCKETS; + if (!(e = hash_scan(h, old_hash, old_key))) + return -ENOENT; + + new_hash = h->hash_func(new_key) % NBUCKETS; + if (hash_scan(h, new_hash, new_key)) + return -EEXIST; + + unlink_entry(h, e, old_hash); + + e->key = new_key; + e->value = value; + + link_entry(h, e, new_hash); + + return 0; +} + +int hashmap_remove_and_replace(Hashmap *h, const void *old_key, const void *new_key, void *value) { + struct hashmap_entry *e, *k; + unsigned old_hash, new_hash; + + if (!h) + return -ENOENT; + + old_hash = h->hash_func(old_key) % NBUCKETS; + if (!(e = hash_scan(h, old_hash, old_key))) + return -ENOENT; + + new_hash = h->hash_func(new_key) % NBUCKETS; + + if ((k = hash_scan(h, new_hash, new_key))) + if (e != k) + remove_entry(h, k); + + unlink_entry(h, e, old_hash); + + e->key = new_key; + e->value = value; + + link_entry(h, e, new_hash); + + return 0; +} + +void* hashmap_remove_value(Hashmap *h, const void *key, void *value) { + struct hashmap_entry *e; + unsigned hash; + + if (!h) + return NULL; + + hash = h->hash_func(key) % NBUCKETS; + + if (!(e = hash_scan(h, hash, key))) + return NULL; + + if (e->value != value) + return NULL; + + remove_entry(h, e); + + return value; +} + +void *hashmap_iterate(Hashmap *h, Iterator *i, const void **key) { + struct hashmap_entry *e; + + assert(i); + + if (!h) + goto at_end; + + if (*i == ITERATOR_LAST) + goto at_end; + + if (*i == ITERATOR_FIRST && !h->iterate_list_head) + goto at_end; + + e = *i == ITERATOR_FIRST ? h->iterate_list_head : (struct hashmap_entry*) *i; + + if (e->iterate_next) + *i = (Iterator) e->iterate_next; + else + *i = ITERATOR_LAST; + + if (key) + *key = e->key; + + return e->value; + +at_end: + *i = ITERATOR_LAST; + + if (key) + *key = NULL; + + return NULL; +} + +void *hashmap_iterate_backwards(Hashmap *h, Iterator *i, const void **key) { + struct hashmap_entry *e; + + assert(i); + + if (!h) + goto at_beginning; + + if (*i == ITERATOR_FIRST) + goto at_beginning; + + if (*i == ITERATOR_LAST && !h->iterate_list_tail) + goto at_beginning; + + e = *i == ITERATOR_LAST ? h->iterate_list_tail : (struct hashmap_entry*) *i; + + if (e->iterate_previous) + *i = (Iterator) e->iterate_previous; + else + *i = ITERATOR_FIRST; + + if (key) + *key = e->key; + + return e->value; + +at_beginning: + *i = ITERATOR_FIRST; + + if (key) + *key = NULL; + + return NULL; +} + +void *hashmap_iterate_skip(Hashmap *h, const void *key, Iterator *i) { + unsigned hash; + struct hashmap_entry *e; + + if (!h) + return NULL; + + hash = h->hash_func(key) % NBUCKETS; + + if (!(e = hash_scan(h, hash, key))) + return NULL; + + *i = (Iterator) e; + + return e->value; +} + +void* hashmap_first(Hashmap *h) { + + if (!h) + return NULL; + + if (!h->iterate_list_head) + return NULL; + + return h->iterate_list_head->value; +} + +void* hashmap_first_key(Hashmap *h) { + + if (!h) + return NULL; + + if (!h->iterate_list_head) + return NULL; + + return (void*) h->iterate_list_head->key; +} + +void* hashmap_last(Hashmap *h) { + + if (!h) + return NULL; + + if (!h->iterate_list_tail) + return NULL; + + return h->iterate_list_tail->value; +} + +void* hashmap_steal_first(Hashmap *h) { + void *data; + + if (!h) + return NULL; + + if (!h->iterate_list_head) + return NULL; + + data = h->iterate_list_head->value; + remove_entry(h, h->iterate_list_head); + + return data; +} + +void* hashmap_steal_first_key(Hashmap *h) { + void *key; + + if (!h) + return NULL; + + if (!h->iterate_list_head) + return NULL; + + key = (void*) h->iterate_list_head->key; + remove_entry(h, h->iterate_list_head); + + return key; +} + +unsigned hashmap_size(Hashmap *h) { + + if (!h) + return 0; + + return h->n_entries; +} + +bool hashmap_isempty(Hashmap *h) { + + if (!h) + return true; + + return h->n_entries == 0; +} + +int hashmap_merge(Hashmap *h, Hashmap *other) { + struct hashmap_entry *e; + + assert(h); + + if (!other) + return 0; + + for (e = other->iterate_list_head; e; e = e->iterate_next) { + int r; + + if ((r = hashmap_put(h, e->key, e->value)) < 0) + if (r != -EEXIST) + return r; + } + + return 0; +} + +void hashmap_move(Hashmap *h, Hashmap *other) { + struct hashmap_entry *e, *n; + + assert(h); + + /* The same as hashmap_merge(), but every new item from other + * is moved to h. This function is guaranteed to succeed. */ + + if (!other) + return; + + for (e = other->iterate_list_head; e; e = n) { + unsigned h_hash, other_hash; + + n = e->iterate_next; + + h_hash = h->hash_func(e->key) % NBUCKETS; + + if (hash_scan(h, h_hash, e->key)) + continue; + + other_hash = other->hash_func(e->key) % NBUCKETS; + + unlink_entry(other, e, other_hash); + link_entry(h, e, h_hash); + } +} + +int hashmap_move_one(Hashmap *h, Hashmap *other, const void *key) { + unsigned h_hash, other_hash; + struct hashmap_entry *e; + + if (!other) + return 0; + + assert(h); + + h_hash = h->hash_func(key) % NBUCKETS; + if (hash_scan(h, h_hash, key)) + return -EEXIST; + + other_hash = other->hash_func(key) % NBUCKETS; + if (!(e = hash_scan(other, other_hash, key))) + return -ENOENT; + + unlink_entry(other, e, other_hash); + link_entry(h, e, h_hash); + + return 0; +} + +Hashmap *hashmap_copy(Hashmap *h) { + Hashmap *copy; + + assert(h); + + if (!(copy = hashmap_new(h->hash_func, h->compare_func))) + return NULL; + + if (hashmap_merge(copy, h) < 0) { + hashmap_free(copy); + return NULL; + } + + return copy; +} + +char **hashmap_get_strv(Hashmap *h) { + char **sv; + Iterator it; + char *item; + int n; + + sv = new(char*, h->n_entries+1); + if (!sv) + return NULL; + + n = 0; + HASHMAP_FOREACH(item, h, it) + sv[n++] = item; + sv[n] = NULL; + + return sv; +} + +void *hashmap_next(Hashmap *h, const void *key) { + unsigned hash; + struct hashmap_entry *e; + + assert(h); + assert(key); + + if (!h) + return NULL; + + hash = h->hash_func(key) % NBUCKETS; + e = hash_scan(h, hash, key); + if (!e) + return NULL; + + e = e->iterate_next; + if (!e) + return NULL; + + return e->value; +} diff --git a/src/shared/hashmap.h b/src/shared/hashmap.h new file mode 100644 index 000000000..6fd71cf51 --- /dev/null +++ b/src/shared/hashmap.h @@ -0,0 +1,98 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +#include + +/* Pretty straightforward hash table implementation. As a minor + * optimization a NULL hashmap object will be treated as empty hashmap + * for all read operations. That way it is not necessary to + * instantiate an object for each Hashmap use. */ + +typedef struct Hashmap Hashmap; +typedef struct _IteratorStruct _IteratorStruct; +typedef _IteratorStruct* Iterator; + +#define ITERATOR_FIRST ((Iterator) 0) +#define ITERATOR_LAST ((Iterator) -1) + +typedef unsigned (*hash_func_t)(const void *p); +typedef int (*compare_func_t)(const void *a, const void *b); + +unsigned string_hash_func(const void *p); +int string_compare_func(const void *a, const void *b); + +unsigned trivial_hash_func(const void *p); +int trivial_compare_func(const void *a, const void *b); + +unsigned uint64_hash_func(const void *p); +int uint64_compare_func(const void *a, const void *b); + +Hashmap *hashmap_new(hash_func_t hash_func, compare_func_t compare_func); +void hashmap_free(Hashmap *h); +void hashmap_free_free(Hashmap *h); +Hashmap *hashmap_copy(Hashmap *h); +int hashmap_ensure_allocated(Hashmap **h, hash_func_t hash_func, compare_func_t compare_func); + +int hashmap_put(Hashmap *h, const void *key, void *value); +int hashmap_update(Hashmap *h, const void *key, void *value); +int hashmap_replace(Hashmap *h, const void *key, void *value); +void* hashmap_get(Hashmap *h, const void *key); +void* hashmap_get2(Hashmap *h, const void *key, void **rkey); +bool hashmap_contains(Hashmap *h, const void *key); +void* hashmap_remove(Hashmap *h, const void *key); +void* hashmap_remove_value(Hashmap *h, const void *key, void *value); +int hashmap_remove_and_put(Hashmap *h, const void *old_key, const void *new_key, void *value); +int hashmap_remove_and_replace(Hashmap *h, const void *old_key, const void *new_key, void *value); + +int hashmap_merge(Hashmap *h, Hashmap *other); +void hashmap_move(Hashmap *h, Hashmap *other); +int hashmap_move_one(Hashmap *h, Hashmap *other, const void *key); + +unsigned hashmap_size(Hashmap *h); +bool hashmap_isempty(Hashmap *h); + +void *hashmap_iterate(Hashmap *h, Iterator *i, const void **key); +void *hashmap_iterate_backwards(Hashmap *h, Iterator *i, const void **key); +void *hashmap_iterate_skip(Hashmap *h, const void *key, Iterator *i); + +void hashmap_clear(Hashmap *h); +void hashmap_clear_free(Hashmap *h); + +void *hashmap_steal_first(Hashmap *h); +void *hashmap_steal_first_key(Hashmap *h); +void* hashmap_first(Hashmap *h); +void* hashmap_first_key(Hashmap *h); +void* hashmap_last(Hashmap *h); + +void *hashmap_next(Hashmap *h, const void *key); + +char **hashmap_get_strv(Hashmap *h); + +#define HASHMAP_FOREACH(e, h, i) \ + for ((i) = ITERATOR_FIRST, (e) = hashmap_iterate((h), &(i), NULL); (e); (e) = hashmap_iterate((h), &(i), NULL)) + +#define HASHMAP_FOREACH_KEY(e, k, h, i) \ + for ((i) = ITERATOR_FIRST, (e) = hashmap_iterate((h), &(i), (const void**) &(k)); (e); (e) = hashmap_iterate((h), &(i), (const void**) &(k))) + +#define HASHMAP_FOREACH_BACKWARDS(e, h, i) \ + for ((i) = ITERATOR_LAST, (e) = hashmap_iterate_backwards((h), &(i), NULL); (e); (e) = hashmap_iterate_backwards((h), &(i), NULL)) diff --git a/src/shared/hwclock.c b/src/shared/hwclock.c new file mode 100644 index 000000000..f9adf0369 --- /dev/null +++ b/src/shared/hwclock.c @@ -0,0 +1,240 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010-2012 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "macro.h" +#include "util.h" +#include "log.h" +#include "strv.h" +#include "hwclock.h" + +static int rtc_open(int flags) { + int fd; + DIR *d; + + /* First, we try to make use of the /dev/rtc symlink. If that + * doesn't exist, we open the first RTC which has hctosys=1 + * set. If we don't find any we just take the first RTC that + * exists at all. */ + + fd = open("/dev/rtc", flags); + if (fd >= 0) + return fd; + + d = opendir("/sys/class/rtc"); + if (!d) + goto fallback; + + for (;;) { + char *p, *v; + struct dirent *de; + union dirent_storage buf; + int r; + + r = readdir_r(d, &buf.de, &de); + if (r != 0) + goto fallback; + + if (!de) + goto fallback; + + if (ignore_file(de->d_name)) + continue; + + p = strjoin("/sys/class/rtc/", de->d_name, "/hctosys", NULL); + if (!p) { + closedir(d); + return -ENOMEM; + } + + r = read_one_line_file(p, &v); + free(p); + + if (r < 0) + continue; + + r = parse_boolean(v); + free(v); + + if (r <= 0) + continue; + + p = strappend("/dev/", de->d_name); + if (!p) { + closedir(d); + return -ENOMEM; + } + + fd = open(p, flags); + free(p); + + if (fd >= 0) { + closedir(d); + return fd; + } + } + +fallback: + if (d) + closedir(d); + + fd = open("/dev/rtc0", flags); + if (fd < 0) + return -errno; + + return fd; +} + +int hwclock_get_time(struct tm *tm) { + int fd; + int err = 0; + + assert(tm); + + fd = rtc_open(O_RDONLY|O_CLOEXEC); + if (fd < 0) + return -errno; + + /* This leaves the timezone fields of struct tm + * uninitialized! */ + if (ioctl(fd, RTC_RD_TIME, tm) < 0) + err = -errno; + + /* We don't know daylight saving, so we reset this in order not + * to confused mktime(). */ + tm->tm_isdst = -1; + + close_nointr_nofail(fd); + + return err; +} + +int hwclock_set_time(const struct tm *tm) { + int fd; + int err = 0; + + assert(tm); + + fd = rtc_open(O_RDONLY|O_CLOEXEC); + if (fd < 0) + return -errno; + + if (ioctl(fd, RTC_SET_TIME, tm) < 0) + err = -errno; + + close_nointr_nofail(fd); + + return err; +} + +int hwclock_is_localtime(void) { + FILE *f; + bool local = false; + + /* + * The third line of adjtime is "UTC" or "LOCAL" or nothing. + * # /etc/adjtime + * 0.0 0 0 + * 0 + * UTC + */ + f = fopen("/etc/adjtime", "re"); + if (f) { + char line[LINE_MAX]; + bool b; + + b = fgets(line, sizeof(line), f) && + fgets(line, sizeof(line), f) && + fgets(line, sizeof(line), f); + + fclose(f); + + if (!b) + return -EIO; + + truncate_nl(line); + local = streq(line, "LOCAL"); + + } else if (errno != -ENOENT) + return -errno; + + return local; +} + +int hwclock_set_timezone(int *min) { + const struct timeval *tv_null = NULL; + struct timespec ts; + struct tm *tm; + int minutesdelta; + struct timezone tz; + + assert_se(clock_gettime(CLOCK_REALTIME, &ts) == 0); + assert_se(tm = localtime(&ts.tv_sec)); + minutesdelta = tm->tm_gmtoff / 60; + + tz.tz_minuteswest = -minutesdelta; + tz.tz_dsttime = 0; /* DST_NONE*/ + + /* + * If the hardware clock does not run in UTC, but in local time: + * The very first time we set the kernel's timezone, it will warp + * the clock so that it runs in UTC instead of local time. + */ + if (settimeofday(tv_null, &tz) < 0) + return -errno; + if (min) + *min = minutesdelta; + return 0; +} + +int hwclock_reset_timezone(void) { + const struct timeval *tv_null = NULL; + struct timezone tz; + + tz.tz_minuteswest = 0; + tz.tz_dsttime = 0; /* DST_NONE*/ + + /* + * The very first time we set the kernel's timezone, it will warp + * the clock. Do a dummy call here, so the time warping is sealed + * and we set only the time zone with next call. + */ + if (settimeofday(tv_null, &tz) < 0) + return -errno; + + return 0; +} diff --git a/src/shared/hwclock.h b/src/shared/hwclock.h new file mode 100644 index 000000000..b2bdc78f0 --- /dev/null +++ b/src/shared/hwclock.h @@ -0,0 +1,31 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foohwclockhfoo +#define foohwclockhfoo + +/*** + This file is part of systemd. + + Copyright 2010-2012 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 . +***/ + +int hwclock_is_localtime(void); +int hwclock_set_timezone(int *min); +int hwclock_reset_timezone(void); +int hwclock_get_time(struct tm *tm); +int hwclock_set_time(const struct tm *tm); + +#endif diff --git a/src/shared/install.c b/src/shared/install.c new file mode 100644 index 000000000..a9d75f3b7 --- /dev/null +++ b/src/shared/install.c @@ -0,0 +1,2059 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +#include +#include +#include +#include +#include + +#include "util.h" +#include "mkdir.h" +#include "hashmap.h" +#include "set.h" +#include "path-util.h" +#include "path-lookup.h" +#include "strv.h" +#include "unit-name.h" +#include "install.h" +#include "conf-parser.h" +#include "conf-files.h" + +typedef struct { + char *name; + char *path; + + char **aliases; + char **wanted_by; + char **required_by; +} InstallInfo; + +typedef struct { + Hashmap *will_install; + Hashmap *have_installed; +} InstallContext; + +static int lookup_paths_init_from_scope(LookupPaths *paths, UnitFileScope scope) { + assert(paths); + assert(scope >= 0); + assert(scope < _UNIT_FILE_SCOPE_MAX); + + zero(*paths); + + return lookup_paths_init(paths, + scope == UNIT_FILE_SYSTEM ? SYSTEMD_SYSTEM : SYSTEMD_USER, + scope == UNIT_FILE_USER, + NULL, NULL, NULL); +} + +static int get_config_path(UnitFileScope scope, bool runtime, const char *root_dir, char **ret) { + char *p = NULL; + int r; + + assert(scope >= 0); + assert(scope < _UNIT_FILE_SCOPE_MAX); + assert(ret); + + switch (scope) { + + case UNIT_FILE_SYSTEM: + + if (root_dir && runtime) + asprintf(&p, "%s/run/systemd/system", root_dir); + else if (runtime) + p = strdup("/run/systemd/system"); + else if (root_dir) + asprintf(&p, "%s/%s", root_dir, SYSTEM_CONFIG_UNIT_PATH); + else + p = strdup(SYSTEM_CONFIG_UNIT_PATH); + + break; + + case UNIT_FILE_GLOBAL: + + if (root_dir) + return -EINVAL; + + if (runtime) + p = strdup("/run/systemd/user"); + else + p = strdup(USER_CONFIG_UNIT_PATH); + break; + + case UNIT_FILE_USER: + + if (root_dir || runtime) + return -EINVAL; + + r = user_config_home(&p); + if (r <= 0) + return r < 0 ? r : -ENOENT; + + break; + + default: + assert_not_reached("Bad scope"); + } + + if (!p) + return -ENOMEM; + + *ret = p; + return 0; +} + +static int add_file_change( + UnitFileChange **changes, + unsigned *n_changes, + UnitFileChangeType type, + const char *path, + const char *source) { + + UnitFileChange *c; + unsigned i; + + assert(path); + assert(!changes == !n_changes); + + if (!changes) + return 0; + + c = realloc(*changes, (*n_changes + 1) * sizeof(UnitFileChange)); + if (!c) + return -ENOMEM; + + *changes = c; + i = *n_changes; + + c[i].type = type; + c[i].path = strdup(path); + if (!c[i].path) + return -ENOMEM; + + if (source) { + c[i].source = strdup(source); + if (!c[i].source) { + free(c[i].path); + return -ENOMEM; + } + } else + c[i].source = NULL; + + *n_changes = i+1; + return 0; +} + +static int mark_symlink_for_removal( + Set **remove_symlinks_to, + const char *p) { + + char *n; + int r; + + assert(p); + + r = set_ensure_allocated(remove_symlinks_to, string_hash_func, string_compare_func); + if (r < 0) + return r; + + n = strdup(p); + if (!n) + return -ENOMEM; + + path_kill_slashes(n); + + r = set_put(*remove_symlinks_to, n); + if (r < 0) { + free(n); + return r == -EEXIST ? 0 : r; + } + + return 0; +} + +static int remove_marked_symlinks_fd( + Set *remove_symlinks_to, + int fd, + const char *path, + const char *config_path, + bool *deleted, + UnitFileChange **changes, + unsigned *n_changes, + char** files) { + + int r = 0; + DIR *d; + + assert(remove_symlinks_to); + assert(fd >= 0); + assert(path); + assert(config_path); + assert(deleted); + + d = fdopendir(fd); + if (!d) { + close_nointr_nofail(fd); + return -errno; + } + + rewinddir(d); + + for (;;) { + struct dirent *de; + union dirent_storage buf; + int k; + + k = readdir_r(d, &buf.de, &de); + if (k != 0) { + r = -errno; + break; + } + + if (!de) + break; + + if (ignore_file(de->d_name)) + continue; + + dirent_ensure_type(d, de); + + if (de->d_type == DT_DIR) { + int nfd, q; + char *p; + + nfd = openat(fd, de->d_name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW); + if (nfd < 0) { + if (errno == ENOENT) + continue; + + if (r == 0) + r = -errno; + continue; + } + + p = path_make_absolute(de->d_name, path); + if (!p) { + close_nointr_nofail(nfd); + r = -ENOMEM; + break; + } + + /* This will close nfd, regardless whether it succeeds or not */ + q = remove_marked_symlinks_fd(remove_symlinks_to, nfd, p, config_path, deleted, changes, n_changes, files); + free(p); + + if (r == 0) + r = q; + + } else if (de->d_type == DT_LNK) { + char *p, *dest; + int q; + bool found; + + p = path_make_absolute(de->d_name, path); + if (!p) { + r = -ENOMEM; + break; + } + + q = readlink_and_canonicalize(p, &dest); + if (q < 0) { + free(p); + + if (q == -ENOENT) + continue; + + if (r == 0) + r = q; + continue; + } + + found = + set_get(remove_symlinks_to, dest) || + set_get(remove_symlinks_to, path_get_file_name(dest)); + + if (unit_name_is_instance(p)) + found = found && strv_contains(files, path_get_file_name(p)); + + if (found) { + + if (unlink(p) < 0 && errno != ENOENT) { + + if (r == 0) + r = -errno; + } else { + rmdir_parents(p, config_path); + path_kill_slashes(p); + + add_file_change(changes, n_changes, UNIT_FILE_UNLINK, p, NULL); + + if (!set_get(remove_symlinks_to, p)) { + + q = mark_symlink_for_removal(&remove_symlinks_to, p); + if (q < 0) { + if (r == 0) + r = q; + } else + *deleted = true; + } + } + } + + free(p); + free(dest); + } + } + + closedir(d); + + return r; +} + +static int remove_marked_symlinks( + Set *remove_symlinks_to, + const char *config_path, + UnitFileChange **changes, + unsigned *n_changes, + char** files) { + + int fd, r = 0; + bool deleted; + + assert(config_path); + + if (set_size(remove_symlinks_to) <= 0) + return 0; + + fd = open(config_path, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW); + if (fd < 0) + return -errno; + + do { + int q, cfd; + deleted = false; + + cfd = dup(fd); + if (cfd < 0) { + r = -errno; + break; + } + + /* This takes possession of cfd and closes it */ + q = remove_marked_symlinks_fd(remove_symlinks_to, cfd, config_path, config_path, &deleted, changes, n_changes, files); + if (r == 0) + r = q; + } while (deleted); + + close_nointr_nofail(fd); + + return r; +} + +static int find_symlinks_fd( + const char *name, + int fd, + const char *path, + const char *config_path, + bool *same_name_link) { + + int r = 0; + DIR *d; + + assert(name); + assert(fd >= 0); + assert(path); + assert(config_path); + assert(same_name_link); + + d = fdopendir(fd); + if (!d) { + close_nointr_nofail(fd); + return -errno; + } + + for (;;) { + int k; + struct dirent *de; + union dirent_storage buf; + + k = readdir_r(d, &buf.de, &de); + if (k != 0) { + r = -errno; + break; + } + + if (!de) + break; + + if (ignore_file(de->d_name)) + continue; + + dirent_ensure_type(d, de); + + if (de->d_type == DT_DIR) { + int nfd, q; + char *p; + + nfd = openat(fd, de->d_name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW); + if (nfd < 0) { + if (errno == ENOENT) + continue; + + if (r == 0) + r = -errno; + continue; + } + + p = path_make_absolute(de->d_name, path); + if (!p) { + close_nointr_nofail(nfd); + r = -ENOMEM; + break; + } + + /* This will close nfd, regardless whether it succeeds or not */ + q = find_symlinks_fd(name, nfd, p, config_path, same_name_link); + free(p); + + if (q > 0) { + r = 1; + break; + } + + if (r == 0) + r = q; + + } else if (de->d_type == DT_LNK) { + char *p, *dest; + bool found_path, found_dest, b = false; + int q; + + /* Acquire symlink name */ + p = path_make_absolute(de->d_name, path); + if (!p) { + r = -ENOMEM; + break; + } + + /* Acquire symlink destination */ + q = readlink_and_canonicalize(p, &dest); + if (q < 0) { + free(p); + + if (q == -ENOENT) + continue; + + if (r == 0) + r = q; + continue; + } + + /* Check if the symlink itself matches what we + * are looking for */ + if (path_is_absolute(name)) + found_path = path_equal(p, name); + else + found_path = streq(de->d_name, name); + + /* Check if what the symlink points to + * matches what we are looking for */ + if (path_is_absolute(name)) + found_dest = path_equal(dest, name); + else + found_dest = streq(path_get_file_name(dest), name); + + free(dest); + + if (found_path && found_dest) { + char *t; + + /* Filter out same name links in the main + * config path */ + t = path_make_absolute(name, config_path); + if (!t) { + free(p); + r = -ENOMEM; + break; + } + + b = path_equal(t, p); + free(t); + } + + free(p); + + if (b) + *same_name_link = true; + else if (found_path || found_dest) { + r = 1; + break; + } + } + } + + closedir(d); + + return r; +} + +static int find_symlinks( + const char *name, + const char *config_path, + bool *same_name_link) { + + int fd; + + assert(name); + assert(config_path); + assert(same_name_link); + + fd = open(config_path, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW); + if (fd < 0) { + if (errno == ENOENT) + return 0; + return -errno; + } + + /* This takes possession of fd and closes it */ + return find_symlinks_fd(name, fd, config_path, config_path, same_name_link); +} + +static int find_symlinks_in_scope( + UnitFileScope scope, + const char *root_dir, + const char *name, + UnitFileState *state) { + + int r; + char _cleanup_free_ *path = NULL; + bool same_name_link_runtime = false, same_name_link = false; + + assert(scope >= 0); + assert(scope < _UNIT_FILE_SCOPE_MAX); + assert(name); + + if (scope == UNIT_FILE_SYSTEM || scope == UNIT_FILE_GLOBAL) { + + /* First look in runtime config path */ + r = get_config_path(scope, true, root_dir, &path); + if (r < 0) + return r; + + r = find_symlinks(name, path, &same_name_link_runtime); + if (r < 0) + return r; + else if (r > 0) { + *state = UNIT_FILE_ENABLED_RUNTIME; + return r; + } + } + + /* Then look in the normal config path */ + r = get_config_path(scope, false, root_dir, &path); + if (r < 0) + return r; + + r = find_symlinks(name, path, &same_name_link); + if (r < 0) + return r; + else if (r > 0) { + *state = UNIT_FILE_ENABLED; + return r; + } + + /* Hmm, we didn't find it, but maybe we found the same name + * link? */ + if (same_name_link_runtime) { + *state = UNIT_FILE_LINKED_RUNTIME; + return 1; + } else if (same_name_link) { + *state = UNIT_FILE_LINKED; + return 1; + } + + return 0; +} + +int unit_file_mask( + UnitFileScope scope, + bool runtime, + const char *root_dir, + char *files[], + bool force, + UnitFileChange **changes, + unsigned *n_changes) { + + char **i; + char _cleanup_free_ *prefix; + int r; + + assert(scope >= 0); + assert(scope < _UNIT_FILE_SCOPE_MAX); + + r = get_config_path(scope, runtime, root_dir, &prefix); + if (r < 0) + return r; + + STRV_FOREACH(i, files) { + char _cleanup_free_ *path = NULL; + + if (!unit_name_is_valid(*i, true)) { + if (r == 0) + r = -EINVAL; + continue; + } + + path = path_make_absolute(*i, prefix); + if (!path) { + r = -ENOMEM; + break; + } + + if (symlink("/dev/null", path) >= 0) { + add_file_change(changes, n_changes, UNIT_FILE_SYMLINK, path, "/dev/null"); + + continue; + } + + if (errno == EEXIST) { + + if (null_or_empty_path(path) > 0) + continue; + + if (force) { + unlink(path); + + if (symlink("/dev/null", path) >= 0) { + + add_file_change(changes, n_changes, UNIT_FILE_UNLINK, path, NULL); + add_file_change(changes, n_changes, UNIT_FILE_SYMLINK, path, "/dev/null"); + + continue; + } + } + + if (r == 0) + r = -EEXIST; + } else { + if (r == 0) + r = -errno; + } + } + + return r; +} + +int unit_file_unmask( + UnitFileScope scope, + bool runtime, + const char *root_dir, + char *files[], + UnitFileChange **changes, + unsigned *n_changes) { + + char **i, *config_path = NULL; + int r, q; + Set *remove_symlinks_to = NULL; + + assert(scope >= 0); + assert(scope < _UNIT_FILE_SCOPE_MAX); + + r = get_config_path(scope, runtime, root_dir, &config_path); + if (r < 0) + goto finish; + + STRV_FOREACH(i, files) { + char *path; + + if (!unit_name_is_valid(*i, true)) { + if (r == 0) + r = -EINVAL; + continue; + } + + path = path_make_absolute(*i, config_path); + if (!path) { + r = -ENOMEM; + break; + } + + q = null_or_empty_path(path); + if (q > 0) { + if (unlink(path) >= 0) { + mark_symlink_for_removal(&remove_symlinks_to, path); + add_file_change(changes, n_changes, UNIT_FILE_UNLINK, path, NULL); + + free(path); + continue; + } + + q = -errno; + } + + if (q != -ENOENT && r == 0) + r = q; + + free(path); + } + + +finish: + q = remove_marked_symlinks(remove_symlinks_to, config_path, changes, n_changes, files); + if (r == 0) + r = q; + + set_free_free(remove_symlinks_to); + free(config_path); + + return r; +} + +int unit_file_link( + UnitFileScope scope, + bool runtime, + const char *root_dir, + char *files[], + bool force, + UnitFileChange **changes, + unsigned *n_changes) { + + LookupPaths paths; + char **i, *config_path = NULL; + int r, q; + + assert(scope >= 0); + assert(scope < _UNIT_FILE_SCOPE_MAX); + + zero(paths); + + r = lookup_paths_init_from_scope(&paths, scope); + if (r < 0) + return r; + + r = get_config_path(scope, runtime, root_dir, &config_path); + if (r < 0) + goto finish; + + STRV_FOREACH(i, files) { + char *path, *fn; + struct stat st; + + fn = path_get_file_name(*i); + + if (!path_is_absolute(*i) || + !unit_name_is_valid(fn, true)) { + if (r == 0) + r = -EINVAL; + continue; + } + + if (lstat(*i, &st) < 0) { + if (r == 0) + r = -errno; + continue; + } + + if (!S_ISREG(st.st_mode)) { + r = -ENOENT; + continue; + } + + q = in_search_path(*i, paths.unit_path); + if (q < 0) { + r = q; + break; + } + + if (q > 0) + continue; + + path = path_make_absolute(fn, config_path); + if (!path) { + r = -ENOMEM; + break; + } + + if (symlink(*i, path) >= 0) { + add_file_change(changes, n_changes, UNIT_FILE_SYMLINK, path, *i); + + free(path); + continue; + } + + if (errno == EEXIST) { + char *dest = NULL; + + q = readlink_and_make_absolute(path, &dest); + + if (q < 0 && errno != ENOENT) { + free(path); + + if (r == 0) + r = q; + + continue; + } + + if (q >= 0 && path_equal(dest, *i)) { + free(dest); + free(path); + continue; + } + + free(dest); + + if (force) { + unlink(path); + + if (symlink(*i, path) >= 0) { + + add_file_change(changes, n_changes, UNIT_FILE_UNLINK, path, NULL); + add_file_change(changes, n_changes, UNIT_FILE_SYMLINK, path, *i); + + free(path); + continue; + } + } + + if (r == 0) + r = -EEXIST; + } else { + if (r == 0) + r = -errno; + } + + free(path); + } + + finish: + lookup_paths_free(&paths); + free(config_path); + + return r; +} + +void unit_file_list_free(Hashmap *h) { + UnitFileList *i; + + while ((i = hashmap_steal_first(h))) { + free(i->path); + free(i); + } + + hashmap_free(h); +} + +void unit_file_changes_free(UnitFileChange *changes, unsigned n_changes) { + unsigned i; + + assert(changes || n_changes == 0); + + if (!changes) + return; + + for (i = 0; i < n_changes; i++) { + free(changes[i].path); + free(changes[i].source); + } + + free(changes); +} + +static void install_info_free(InstallInfo *i) { + assert(i); + + free(i->name); + free(i->path); + strv_free(i->aliases); + strv_free(i->wanted_by); + strv_free(i->required_by); + free(i); +} + +static void install_info_hashmap_free(Hashmap *m) { + InstallInfo *i; + + if (!m) + return; + + while ((i = hashmap_steal_first(m))) + install_info_free(i); + + hashmap_free(m); +} + +static void install_context_done(InstallContext *c) { + assert(c); + + install_info_hashmap_free(c->will_install); + install_info_hashmap_free(c->have_installed); + + c->will_install = c->have_installed = NULL; +} + +static int install_info_add( + InstallContext *c, + const char *name, + const char *path) { + InstallInfo *i = NULL; + int r; + + assert(c); + assert(name || path); + + if (!name) + name = path_get_file_name(path); + + if (!unit_name_is_valid(name, true)) + return -EINVAL; + + if (hashmap_get(c->have_installed, name) || + hashmap_get(c->will_install, name)) + return 0; + + r = hashmap_ensure_allocated(&c->will_install, string_hash_func, string_compare_func); + if (r < 0) + return r; + + i = new0(InstallInfo, 1); + if (!i) + return -ENOMEM; + + i->name = strdup(name); + if (!i->name) { + r = -ENOMEM; + goto fail; + } + + if (path) { + i->path = strdup(path); + if (!i->path) { + r = -ENOMEM; + goto fail; + } + } + + r = hashmap_put(c->will_install, i->name, i); + if (r < 0) + goto fail; + + return 0; + +fail: + if (i) + install_info_free(i); + + return r; +} + +static int install_info_add_auto( + InstallContext *c, + const char *name_or_path) { + + assert(c); + assert(name_or_path); + + if (path_is_absolute(name_or_path)) + return install_info_add(c, NULL, name_or_path); + else + return install_info_add(c, name_or_path, NULL); +} + +static int config_parse_also( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + char *w; + size_t l; + char *state; + InstallContext *c = data; + + assert(filename); + assert(lvalue); + assert(rvalue); + + FOREACH_WORD_QUOTED(w, l, rvalue, state) { + char *n; + int r; + + n = strndup(w, l); + if (!n) + return -ENOMEM; + + r = install_info_add(c, n, NULL); + if (r < 0) { + free(n); + return r; + } + + free(n); + } + + return 0; +} + +static int unit_file_load( + InstallContext *c, + InstallInfo *info, + const char *path, + bool allow_symlink) { + + const ConfigTableItem items[] = { + { "Install", "Alias", config_parse_strv, 0, &info->aliases }, + { "Install", "WantedBy", config_parse_strv, 0, &info->wanted_by }, + { "Install", "RequiredBy", config_parse_strv, 0, &info->required_by }, + { "Install", "Also", config_parse_also, 0, c }, + { NULL, NULL, NULL, 0, NULL } + }; + + int fd; + FILE *f; + int r; + + assert(c); + assert(info); + assert(path); + + fd = open(path, O_RDONLY|O_CLOEXEC|O_NOCTTY|(allow_symlink ? 0 : O_NOFOLLOW)); + if (fd < 0) + return -errno; + + f = fdopen(fd, "re"); + if (!f) { + close_nointr_nofail(fd); + return -ENOMEM; + } + + r = config_parse(path, f, NULL, config_item_table_lookup, (void*) items, true, info); + fclose(f); + if (r < 0) + return r; + + return + strv_length(info->aliases) + + strv_length(info->wanted_by) + + strv_length(info->required_by); +} + +static int unit_file_search( + InstallContext *c, + InstallInfo *info, + LookupPaths *paths, + const char *root_dir, + bool allow_symlink) { + + char **p; + int r; + + assert(c); + assert(info); + assert(paths); + + if (info->path) + return unit_file_load(c, info, info->path, allow_symlink); + + assert(info->name); + + STRV_FOREACH(p, paths->unit_path) { + char *path = NULL; + + if (isempty(root_dir)) + asprintf(&path, "%s/%s", *p, info->name); + else + asprintf(&path, "%s/%s/%s", root_dir, *p, info->name); + + if (!path) + return -ENOMEM; + + r = unit_file_load(c, info, path, allow_symlink); + + if (r >= 0) + info->path = path; + else { + if (r == -ENOENT && unit_name_is_instance(info->name)) { + /* unit file doesn't exist, however instance enablement was request */ + /* we will check if it is possible to load template unit file */ + char *template = NULL, + *template_path = NULL, + *template_dir = NULL; + + template = unit_name_template(info->name); + if (!template) { + free(path); + return -ENOMEM; + } + + /* we will reuse path variable since we don't need it anymore */ + template_dir = path; + *(strrchr(path, '/') + 1) = '\0'; + + template_path = strjoin(template_dir, template, NULL); + if (!template_path) { + free(path); + free(template); + return -ENOMEM; + } + + /* let's try to load template unit */ + r = unit_file_load(c, info, template_path, allow_symlink); + if (r >= 0) { + info->path = strdup(template_path); + if (!info->path) { + free(path); + free(template); + free(template_path); + return -ENOMEM; + } + } + + free(template); + free(template_path); + } + free(path); + } + + if (r != -ENOENT && r != -ELOOP) + return r; + } + + return -ENOENT; +} + +static int unit_file_can_install( + LookupPaths *paths, + const char *root_dir, + const char *name, + bool allow_symlink) { + + InstallContext c; + InstallInfo *i; + int r; + + assert(paths); + assert(name); + + zero(c); + + r = install_info_add_auto(&c, name); + if (r < 0) + return r; + + assert_se(i = hashmap_first(c.will_install)); + + r = unit_file_search(&c, i, paths, root_dir, allow_symlink); + + if (r >= 0) + r = + strv_length(i->aliases) + + strv_length(i->wanted_by) + + strv_length(i->required_by); + + install_context_done(&c); + + return r; +} + +static int create_symlink( + const char *old_path, + const char *new_path, + bool force, + UnitFileChange **changes, + unsigned *n_changes) { + + char *dest; + int r; + + assert(old_path); + assert(new_path); + + mkdir_parents_label(new_path, 0755); + + if (symlink(old_path, new_path) >= 0) { + add_file_change(changes, n_changes, UNIT_FILE_SYMLINK, new_path, old_path); + return 0; + } + + if (errno != EEXIST) + return -errno; + + r = readlink_and_make_absolute(new_path, &dest); + if (r < 0) + return r; + + if (path_equal(dest, old_path)) { + free(dest); + return 0; + } + + free(dest); + + if (!force) + return -EEXIST; + + unlink(new_path); + + if (symlink(old_path, new_path) >= 0) { + add_file_change(changes, n_changes, UNIT_FILE_UNLINK, new_path, NULL); + add_file_change(changes, n_changes, UNIT_FILE_SYMLINK, new_path, old_path); + return 0; + } + + return -errno; +} + +static int install_info_symlink_alias( + InstallInfo *i, + const char *config_path, + bool force, + UnitFileChange **changes, + unsigned *n_changes) { + + char **s; + int r = 0, q; + + assert(i); + assert(config_path); + + STRV_FOREACH(s, i->aliases) { + char *alias_path; + + alias_path = path_make_absolute(*s, config_path); + + if (!alias_path) + return -ENOMEM; + + q = create_symlink(i->path, alias_path, force, changes, n_changes); + free(alias_path); + + if (r == 0) + r = q; + } + + return r; +} + +static int install_info_symlink_wants( + InstallInfo *i, + const char *config_path, + bool force, + UnitFileChange **changes, + unsigned *n_changes) { + + char **s; + int r = 0, q; + + assert(i); + assert(config_path); + + STRV_FOREACH(s, i->wanted_by) { + char *path; + + if (!unit_name_is_valid(*s, true)) { + r = -EINVAL; + continue; + } + + if (asprintf(&path, "%s/%s.wants/%s", config_path, *s, i->name) < 0) + return -ENOMEM; + + q = create_symlink(i->path, path, force, changes, n_changes); + free(path); + + if (r == 0) + r = q; + } + + return r; +} + +static int install_info_symlink_requires( + InstallInfo *i, + const char *config_path, + bool force, + UnitFileChange **changes, + unsigned *n_changes) { + + char **s; + int r = 0, q; + + assert(i); + assert(config_path); + + STRV_FOREACH(s, i->required_by) { + char *path; + + if (!unit_name_is_valid(*s, true)) { + r = -EINVAL; + continue; + } + + if (asprintf(&path, "%s/%s.requires/%s", config_path, *s, i->name) < 0) + return -ENOMEM; + + q = create_symlink(i->path, path, force, changes, n_changes); + free(path); + + if (r == 0) + r = q; + } + + return r; +} + +static int install_info_symlink_link( + InstallInfo *i, + LookupPaths *paths, + const char *config_path, + bool force, + UnitFileChange **changes, + unsigned *n_changes) { + + int r; + char *path; + + assert(i); + assert(paths); + assert(config_path); + assert(i->path); + + r = in_search_path(i->path, paths->unit_path); + if (r != 0) + return r; + + if (asprintf(&path, "%s/%s", config_path, i->name) < 0) + return -ENOMEM; + + r = create_symlink(i->path, path, force, changes, n_changes); + free(path); + + return r; +} + +static int install_info_apply( + InstallInfo *i, + LookupPaths *paths, + const char *config_path, + bool force, + UnitFileChange **changes, + unsigned *n_changes) { + + int r, q; + + assert(i); + assert(paths); + assert(config_path); + + r = install_info_symlink_alias(i, config_path, force, changes, n_changes); + + q = install_info_symlink_wants(i, config_path, force, changes, n_changes); + if (r == 0) + r = q; + + q = install_info_symlink_requires(i, config_path, force, changes, n_changes); + if (r == 0) + r = q; + + q = install_info_symlink_link(i, paths, config_path, force, changes, n_changes); + if (r == 0) + r = q; + + return r; +} + +static int install_context_apply( + InstallContext *c, + LookupPaths *paths, + const char *config_path, + const char *root_dir, + bool force, + UnitFileChange **changes, + unsigned *n_changes) { + + InstallInfo *i; + int r = 0, q; + + assert(c); + assert(paths); + assert(config_path); + + while ((i = hashmap_first(c->will_install))) { + + q = hashmap_ensure_allocated(&c->have_installed, string_hash_func, string_compare_func); + if (q < 0) + return q; + + assert_se(hashmap_move_one(c->have_installed, c->will_install, i->name) == 0); + + q = unit_file_search(c, i, paths, root_dir, false); + if (q < 0) { + if (r >= 0) + r = q; + + return r; + } else if (r >= 0) + r += q; + + q = install_info_apply(i, paths, config_path, force, changes, n_changes); + if (r >= 0 && q < 0) + r = q; + } + + return r; +} + +static int install_context_mark_for_removal( + InstallContext *c, + LookupPaths *paths, + Set **remove_symlinks_to, + const char *config_path, + const char *root_dir) { + + InstallInfo *i; + int r = 0, q; + + assert(c); + assert(paths); + assert(config_path); + + /* Marks all items for removal */ + + while ((i = hashmap_first(c->will_install))) { + + q = hashmap_ensure_allocated(&c->have_installed, string_hash_func, string_compare_func); + if (q < 0) + return q; + + assert_se(hashmap_move_one(c->have_installed, c->will_install, i->name) == 0); + + q = unit_file_search(c, i, paths, root_dir, false); + if (q < 0) { + if (r >= 0) + r = q; + + return r; + } else if (r >= 0) + r += q; + + if (unit_name_is_instance(i->name)) { + char *unit_file = NULL; + + unit_file = path_get_file_name(i->path); + + if (unit_name_is_instance(unit_file)) + /* unit file named as instance exists, thus all symlinks pointing to it, will be removed */ + q = mark_symlink_for_removal(remove_symlinks_to, i->name); + else + /* does not exist, thus we will mark for removal symlinks to template unit file */ + q = mark_symlink_for_removal(remove_symlinks_to, unit_file); + } else + q = mark_symlink_for_removal(remove_symlinks_to, i->name); + + if (r >= 0 && q < 0) + r = q; + } + + return r; +} + +int unit_file_enable( + UnitFileScope scope, + bool runtime, + const char *root_dir, + char *files[], + bool force, + UnitFileChange **changes, + unsigned *n_changes) { + + LookupPaths paths; + InstallContext c; + char **i, *config_path = NULL; + int r; + + assert(scope >= 0); + assert(scope < _UNIT_FILE_SCOPE_MAX); + + zero(paths); + zero(c); + + r = lookup_paths_init_from_scope(&paths, scope); + if (r < 0) + return r; + + r = get_config_path(scope, runtime, root_dir, &config_path); + if (r < 0) + goto finish; + + STRV_FOREACH(i, files) { + r = install_info_add_auto(&c, *i); + if (r < 0) + goto finish; + } + + /* This will return the number of symlink rules that were + supposed to be created, not the ones actually created. This is + useful to determine whether the passed files had any + installation data at all. */ + r = install_context_apply(&c, &paths, config_path, root_dir, force, changes, n_changes); + +finish: + install_context_done(&c); + lookup_paths_free(&paths); + free(config_path); + + return r; +} + +int unit_file_disable( + UnitFileScope scope, + bool runtime, + const char *root_dir, + char *files[], + UnitFileChange **changes, + unsigned *n_changes) { + + LookupPaths paths; + InstallContext c; + char **i, *config_path = NULL; + Set *remove_symlinks_to = NULL; + int r, q; + + assert(scope >= 0); + assert(scope < _UNIT_FILE_SCOPE_MAX); + + zero(paths); + zero(c); + + r = lookup_paths_init_from_scope(&paths, scope); + if (r < 0) + return r; + + r = get_config_path(scope, runtime, root_dir, &config_path); + if (r < 0) + goto finish; + + STRV_FOREACH(i, files) { + r = install_info_add_auto(&c, *i); + if (r < 0) + goto finish; + } + + r = install_context_mark_for_removal(&c, &paths, &remove_symlinks_to, config_path, root_dir); + + q = remove_marked_symlinks(remove_symlinks_to, config_path, changes, n_changes, files); + if (r == 0) + r = q; + +finish: + install_context_done(&c); + lookup_paths_free(&paths); + set_free_free(remove_symlinks_to); + free(config_path); + + return r; +} + +int unit_file_reenable( + UnitFileScope scope, + bool runtime, + const char *root_dir, + char *files[], + bool force, + UnitFileChange **changes, + unsigned *n_changes) { + + LookupPaths paths; + InstallContext c; + char **i, *config_path = NULL; + Set *remove_symlinks_to = NULL; + int r, q; + + assert(scope >= 0); + assert(scope < _UNIT_FILE_SCOPE_MAX); + + zero(paths); + zero(c); + + r = lookup_paths_init_from_scope(&paths, scope); + if (r < 0) + return r; + + r = get_config_path(scope, runtime, root_dir, &config_path); + if (r < 0) + goto finish; + + STRV_FOREACH(i, files) { + r = mark_symlink_for_removal(&remove_symlinks_to, *i); + if (r < 0) + goto finish; + + r = install_info_add_auto(&c, *i); + if (r < 0) + goto finish; + } + + r = remove_marked_symlinks(remove_symlinks_to, config_path, changes, n_changes, files); + + /* Returns number of symlinks that where supposed to be installed. */ + q = install_context_apply(&c, &paths, config_path, root_dir, force, changes, n_changes); + if (r == 0) + r = q; + +finish: + lookup_paths_free(&paths); + install_context_done(&c); + set_free_free(remove_symlinks_to); + free(config_path); + + return r; +} + +UnitFileState unit_file_get_state( + UnitFileScope scope, + const char *root_dir, + const char *name) { + + LookupPaths paths; + UnitFileState state = _UNIT_FILE_STATE_INVALID; + char **i, *path = NULL; + int r; + + assert(scope >= 0); + assert(scope < _UNIT_FILE_SCOPE_MAX); + assert(name); + + zero(paths); + + if (root_dir && scope != UNIT_FILE_SYSTEM) + return -EINVAL; + + if (!unit_name_is_valid(name, true)) + return -EINVAL; + + r = lookup_paths_init_from_scope(&paths, scope); + if (r < 0) + return r; + + STRV_FOREACH(i, paths.unit_path) { + struct stat st; + + free(path); + path = NULL; + + if (root_dir) + asprintf(&path, "%s/%s/%s", root_dir, *i, name); + else + asprintf(&path, "%s/%s", *i, name); + + if (!path) { + r = -ENOMEM; + goto finish; + } + + if (lstat(path, &st) < 0) { + r = -errno; + if (errno == ENOENT) + continue; + + goto finish; + } + + if (!S_ISREG(st.st_mode) && !S_ISLNK(st.st_mode)) { + r = -ENOENT; + goto finish; + } + + r = null_or_empty_path(path); + if (r < 0 && r != -ENOENT) + goto finish; + else if (r > 0) { + state = path_startswith(*i, "/run") ? + UNIT_FILE_MASKED_RUNTIME : UNIT_FILE_MASKED; + r = 0; + goto finish; + } + + r = find_symlinks_in_scope(scope, root_dir, name, &state); + if (r < 0) { + goto finish; + } else if (r > 0) { + r = 0; + goto finish; + } + + r = unit_file_can_install(&paths, root_dir, path, true); + if (r < 0 && errno != -ENOENT) + goto finish; + else if (r > 0) { + state = UNIT_FILE_DISABLED; + r = 0; + goto finish; + } else if (r == 0) { + state = UNIT_FILE_STATIC; + r = 0; + goto finish; + } + } + +finish: + lookup_paths_free(&paths); + free(path); + + return r < 0 ? r : state; +} + +int unit_file_query_preset(UnitFileScope scope, const char *name) { + char **files, **i; + int r; + + assert(scope >= 0); + assert(scope < _UNIT_FILE_SCOPE_MAX); + assert(name); + + if (scope == UNIT_FILE_SYSTEM) + r = conf_files_list(&files, ".preset", + "/etc/systemd/system-preset", + "/usr/local/lib/systemd/system-preset", + "/usr/lib/systemd/system-preset", +#ifdef HAVE_SPLIT_USR + "/lib/systemd/system-preset", +#endif + NULL); + else if (scope == UNIT_FILE_GLOBAL) + r = conf_files_list(&files, ".preset", + "/etc/systemd/user-preset", + "/usr/local/lib/systemd/user-preset", + "/usr/lib/systemd/user-preset", + NULL); + else + return 1; + + if (r < 0) + return r; + + STRV_FOREACH(i, files) { + FILE *f; + + f = fopen(*i, "re"); + if (!f) { + if (errno == ENOENT) + continue; + + r = -errno; + goto finish; + } + + for (;;) { + char line[LINE_MAX], *l; + + if (!fgets(line, sizeof(line), f)) + break; + + l = strstrip(line); + if (!*l) + continue; + + if (strchr(COMMENTS, *l)) + continue; + + if (first_word(l, "enable")) { + l += 6; + l += strspn(l, WHITESPACE); + + if (fnmatch(l, name, FNM_NOESCAPE) == 0) { + r = 1; + fclose(f); + goto finish; + } + } else if (first_word(l, "disable")) { + l += 7; + l += strspn(l, WHITESPACE); + + if (fnmatch(l, name, FNM_NOESCAPE) == 0) { + r = 0; + fclose(f); + goto finish; + } + } else + log_debug("Couldn't parse line '%s'", l); + } + + fclose(f); + } + + /* Default is "enable" */ + r = 1; + +finish: + strv_free(files); + + return r; +} + +int unit_file_preset( + UnitFileScope scope, + bool runtime, + const char *root_dir, + char *files[], + bool force, + UnitFileChange **changes, + unsigned *n_changes) { + + LookupPaths paths; + InstallContext plus, minus; + char **i, *config_path = NULL; + Set *remove_symlinks_to = NULL; + int r, q; + + assert(scope >= 0); + assert(scope < _UNIT_FILE_SCOPE_MAX); + + zero(paths); + zero(plus); + zero(minus); + + r = lookup_paths_init_from_scope(&paths, scope); + if (r < 0) + return r; + + r = get_config_path(scope, runtime, root_dir, &config_path); + if (r < 0) + goto finish; + + STRV_FOREACH(i, files) { + + if (!unit_name_is_valid(*i, true)) { + r = -EINVAL; + goto finish; + } + + r = unit_file_query_preset(scope, *i); + if (r < 0) + goto finish; + + if (r) + r = install_info_add_auto(&plus, *i); + else + r = install_info_add_auto(&minus, *i); + + if (r < 0) + goto finish; + } + + r = install_context_mark_for_removal(&minus, &paths, &remove_symlinks_to, config_path, root_dir); + + q = remove_marked_symlinks(remove_symlinks_to, config_path, changes, n_changes, files); + if (r == 0) + r = q; + + /* Returns number of symlinks that where supposed to be installed. */ + q = install_context_apply(&plus, &paths, config_path, root_dir, force, changes, n_changes); + if (r == 0) + r = q; + +finish: + lookup_paths_free(&paths); + install_context_done(&plus); + install_context_done(&minus); + set_free_free(remove_symlinks_to); + free(config_path); + + return r; +} + +int unit_file_get_list( + UnitFileScope scope, + const char *root_dir, + Hashmap *h) { + + LookupPaths paths; + char **i, *buf = NULL; + DIR *d = NULL; + int r; + + assert(scope >= 0); + assert(scope < _UNIT_FILE_SCOPE_MAX); + assert(h); + + zero(paths); + + if (root_dir && scope != UNIT_FILE_SYSTEM) + return -EINVAL; + + r = lookup_paths_init_from_scope(&paths, scope); + if (r < 0) + return r; + + STRV_FOREACH(i, paths.unit_path) { + const char *units_dir; + + free(buf); + buf = NULL; + + if (root_dir) { + if (asprintf(&buf, "%s/%s", root_dir, *i) < 0) { + r = -ENOMEM; + goto finish; + } + units_dir = buf; + } else + units_dir = *i; + + if (d) + closedir(d); + + d = opendir(units_dir); + if (!d) { + if (errno == ENOENT) + continue; + + r = -errno; + goto finish; + } + + for (;;) { + struct dirent *de; + union dirent_storage buffer; + UnitFileList *f; + + r = readdir_r(d, &buffer.de, &de); + if (r != 0) { + r = -r; + goto finish; + } + + if (!de) + break; + + if (ignore_file(de->d_name)) + continue; + + if (!unit_name_is_valid(de->d_name, true)) + continue; + + if (hashmap_get(h, de->d_name)) + continue; + + r = dirent_ensure_type(d, de); + if (r < 0) { + if (r == -ENOENT) + continue; + + goto finish; + } + + if (de->d_type != DT_LNK && de->d_type != DT_REG) + continue; + + f = new0(UnitFileList, 1); + if (!f) { + r = -ENOMEM; + goto finish; + } + + f->path = path_make_absolute(de->d_name, units_dir); + if (!f->path) { + free(f); + r = -ENOMEM; + goto finish; + } + + r = null_or_empty_path(f->path); + if (r < 0 && r != -ENOENT) { + free(f->path); + free(f); + goto finish; + } else if (r > 0) { + f->state = + path_startswith(*i, "/run") ? + UNIT_FILE_MASKED_RUNTIME : UNIT_FILE_MASKED; + goto found; + } + + r = find_symlinks_in_scope(scope, root_dir, de->d_name, &f->state); + if (r < 0) { + free(f->path); + free(f); + goto finish; + } else if (r > 0) { + f->state = UNIT_FILE_ENABLED; + goto found; + } + + r = unit_file_can_install(&paths, root_dir, f->path, true); + if (r == -EINVAL || /* Invalid setting? */ + r == -EBADMSG || /* Invalid format? */ + r == -ENOENT /* Included file not found? */) + f->state = UNIT_FILE_INVALID; + else if (r < 0) { + free(f->path); + free(f); + goto finish; + } else if (r > 0) + f->state = UNIT_FILE_DISABLED; + else + f->state = UNIT_FILE_STATIC; + + found: + r = hashmap_put(h, path_get_file_name(f->path), f); + if (r < 0) { + free(f->path); + free(f); + goto finish; + } + } + } + +finish: + lookup_paths_free(&paths); + free(buf); + + if (d) + closedir(d); + + return r; +} + +static const char* const unit_file_state_table[_UNIT_FILE_STATE_MAX] = { + [UNIT_FILE_ENABLED] = "enabled", + [UNIT_FILE_ENABLED_RUNTIME] = "enabled-runtime", + [UNIT_FILE_LINKED] = "linked", + [UNIT_FILE_LINKED_RUNTIME] = "linked-runtime", + [UNIT_FILE_MASKED] = "masked", + [UNIT_FILE_MASKED_RUNTIME] = "masked-runtime", + [UNIT_FILE_STATIC] = "static", + [UNIT_FILE_DISABLED] = "disabled", + [UNIT_FILE_INVALID] = "invalid", +}; + +DEFINE_STRING_TABLE_LOOKUP(unit_file_state, UnitFileState); + +static const char* const unit_file_change_type_table[_UNIT_FILE_CHANGE_TYPE_MAX] = { + [UNIT_FILE_SYMLINK] = "symlink", + [UNIT_FILE_UNLINK] = "unlink", +}; + +DEFINE_STRING_TABLE_LOOKUP(unit_file_change_type, UnitFileChangeType); diff --git a/src/shared/install.h b/src/shared/install.h new file mode 100644 index 000000000..55249914b --- /dev/null +++ b/src/shared/install.h @@ -0,0 +1,87 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +#include "hashmap.h" + +typedef enum UnitFileScope { + UNIT_FILE_SYSTEM, + UNIT_FILE_GLOBAL, + UNIT_FILE_USER, + _UNIT_FILE_SCOPE_MAX, + _UNIT_FILE_SCOPE_INVALID = -1 +} UnitFileScope; + +typedef enum UnitFileState { + UNIT_FILE_ENABLED, + UNIT_FILE_ENABLED_RUNTIME, + UNIT_FILE_LINKED, + UNIT_FILE_LINKED_RUNTIME, + UNIT_FILE_MASKED, + UNIT_FILE_MASKED_RUNTIME, + UNIT_FILE_STATIC, + UNIT_FILE_DISABLED, + UNIT_FILE_INVALID, + _UNIT_FILE_STATE_MAX, + _UNIT_FILE_STATE_INVALID = -1 +} UnitFileState; + +typedef enum UnitFileChangeType { + UNIT_FILE_SYMLINK, + UNIT_FILE_UNLINK, + _UNIT_FILE_CHANGE_TYPE_MAX, + _UNIT_FILE_CHANGE_TYPE_INVALID = -1 +} UnitFileChangeType; + +typedef struct UnitFileChange { + UnitFileChangeType type; + char *path; + char *source; +} UnitFileChange; + +typedef struct UnitFileList { + char *path; + UnitFileState state; +} UnitFileList; + +int unit_file_enable(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], bool force, UnitFileChange **changes, unsigned *n_changes); +int unit_file_disable(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], UnitFileChange **changes, unsigned *n_changes); +int unit_file_reenable(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], bool force, UnitFileChange **changes, unsigned *n_changes); +int unit_file_link(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], bool force, UnitFileChange **changes, unsigned *n_changes); +int unit_file_preset(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], bool force, UnitFileChange **changes, unsigned *n_changes); +int unit_file_mask(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], bool force, UnitFileChange **changes, unsigned *n_changes); +int unit_file_unmask(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], UnitFileChange **changes, unsigned *n_changes); + +UnitFileState unit_file_get_state(UnitFileScope scope, const char *root_dir, const char *filename); + +int unit_file_get_list(UnitFileScope scope, const char *root_dir, Hashmap *h); + +void unit_file_list_free(Hashmap *h); +void unit_file_changes_free(UnitFileChange *changes, unsigned n_changes); + +int unit_file_query_preset(UnitFileScope scope, const char *name); + +const char *unit_file_state_to_string(UnitFileState s); +UnitFileState unit_file_state_from_string(const char *s); + +const char *unit_file_change_type_to_string(UnitFileChangeType s); +UnitFileChangeType unit_file_change_type_from_string(const char *s); diff --git a/src/shared/ioprio.h b/src/shared/ioprio.h new file mode 100644 index 000000000..9800fc255 --- /dev/null +++ b/src/shared/ioprio.h @@ -0,0 +1,57 @@ +#ifndef IOPRIO_H +#define IOPRIO_H + +/* This is minimal version of Linux' linux/ioprio.h header file, which + * is licensed GPL2 */ + +#include +#include + +/* + * Gives us 8 prio classes with 13-bits of data for each class + */ +#define IOPRIO_BITS (16) +#define IOPRIO_CLASS_SHIFT (13) +#define IOPRIO_PRIO_MASK ((1UL << IOPRIO_CLASS_SHIFT) - 1) + +#define IOPRIO_PRIO_CLASS(mask) ((mask) >> IOPRIO_CLASS_SHIFT) +#define IOPRIO_PRIO_DATA(mask) ((mask) & IOPRIO_PRIO_MASK) +#define IOPRIO_PRIO_VALUE(class, data) (((class) << IOPRIO_CLASS_SHIFT) | data) + +#define ioprio_valid(mask) (IOPRIO_PRIO_CLASS((mask)) != IOPRIO_CLASS_NONE) + +/* + * These are the io priority groups as implemented by CFQ. RT is the realtime + * class, it always gets premium service. BE is the best-effort scheduling + * class, the default for any process. IDLE is the idle scheduling class, it + * is only served when no one else is using the disk. + */ +enum { + IOPRIO_CLASS_NONE, + IOPRIO_CLASS_RT, + IOPRIO_CLASS_BE, + IOPRIO_CLASS_IDLE, +}; + +/* + * 8 best effort priority levels are supported + */ +#define IOPRIO_BE_NR (8) + +enum { + IOPRIO_WHO_PROCESS = 1, + IOPRIO_WHO_PGRP, + IOPRIO_WHO_USER, +}; + +static inline int ioprio_set(int which, int who, int ioprio) +{ + return syscall(__NR_ioprio_set, which, who, ioprio); +} + +static inline int ioprio_get(int which, int who) +{ + return syscall(__NR_ioprio_get, which, who); +} + +#endif diff --git a/src/shared/label.c b/src/shared/label.c new file mode 100644 index 000000000..d353da57e --- /dev/null +++ b/src/shared/label.c @@ -0,0 +1,382 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include +#include +#include + +#include "label.h" +#include "util.h" +#include "path-util.h" + +#ifdef HAVE_SELINUX +#include "selinux-util.h" +#include +#include + +static struct selabel_handle *label_hnd = NULL; + +#endif + +int label_init(const char *prefix) { + int r = 0; + +#ifdef HAVE_SELINUX + usec_t before_timestamp, after_timestamp; + struct mallinfo before_mallinfo, after_mallinfo; + + if (!use_selinux()) + return 0; + + if (label_hnd) + return 0; + + before_mallinfo = mallinfo(); + before_timestamp = now(CLOCK_MONOTONIC); + + if (prefix) { + struct selinux_opt options[] = { + { .type = SELABEL_OPT_SUBSET, .value = prefix }, + }; + + label_hnd = selabel_open(SELABEL_CTX_FILE, options, ELEMENTSOF(options)); + } else + label_hnd = selabel_open(SELABEL_CTX_FILE, NULL, 0); + + if (!label_hnd) { + log_full(security_getenforce() == 1 ? LOG_ERR : LOG_DEBUG, + "Failed to initialize SELinux context: %m"); + r = security_getenforce() == 1 ? -errno : 0; + } else { + char timespan[FORMAT_TIMESPAN_MAX]; + int l; + + after_timestamp = now(CLOCK_MONOTONIC); + after_mallinfo = mallinfo(); + + l = after_mallinfo.uordblks > before_mallinfo.uordblks ? after_mallinfo.uordblks - before_mallinfo.uordblks : 0; + + log_debug("Successfully loaded SELinux database in %s, size on heap is %iK.", + format_timespan(timespan, sizeof(timespan), after_timestamp - before_timestamp), + (l+1023)/1024); + } +#endif + + return r; +} + +int label_fix(const char *path, bool ignore_enoent, bool ignore_erofs) { + int r = 0; + +#ifdef HAVE_SELINUX + struct stat st; + security_context_t fcon; + + if (!use_selinux() || !label_hnd) + return 0; + + r = lstat(path, &st); + if (r == 0) { + r = selabel_lookup_raw(label_hnd, &fcon, path, st.st_mode); + + /* If there's no label to set, then exit without warning */ + if (r < 0 && errno == ENOENT) + return 0; + + if (r == 0) { + r = lsetfilecon(path, fcon); + freecon(fcon); + + /* If the FS doesn't support labels, then exit without warning */ + if (r < 0 && errno == ENOTSUP) + return 0; + } + } + + if (r < 0) { + /* Ignore ENOENT in some cases */ + if (ignore_enoent && errno == ENOENT) + return 0; + + if (ignore_erofs && errno == EROFS) + return 0; + + log_full(security_getenforce() == 1 ? LOG_ERR : LOG_DEBUG, + "Unable to fix label of %s: %m", path); + r = security_getenforce() == 1 ? -errno : 0; + } +#endif + + return r; +} + +void label_finish(void) { + +#ifdef HAVE_SELINUX + if (use_selinux() && label_hnd) + selabel_close(label_hnd); +#endif +} + +int label_get_create_label_from_exe(const char *exe, char **label) { + + int r = 0; + +#ifdef HAVE_SELINUX + security_context_t mycon = NULL, fcon = NULL; + security_class_t sclass; + + if (!use_selinux()) { + *label = NULL; + return 0; + } + + r = getcon(&mycon); + if (r < 0) + goto fail; + + r = getfilecon(exe, &fcon); + if (r < 0) + goto fail; + + sclass = string_to_security_class("process"); + r = security_compute_create(mycon, fcon, sclass, (security_context_t *) label); + if (r == 0) + log_debug("SELinux Socket context for %s will be set to %s", exe, *label); + +fail: + if (r < 0 && security_getenforce() == 1) + r = -errno; + + freecon(mycon); + freecon(fcon); +#endif + + return r; +} + +int label_context_set(const char *path, mode_t mode) { + int r = 0; + +#ifdef HAVE_SELINUX + security_context_t filecon = NULL; + + if (!use_selinux() || !label_hnd) + return 0; + + r = selabel_lookup_raw(label_hnd, &filecon, path, mode); + if (r < 0 && errno != ENOENT) + r = -errno; + else if (r == 0) { + r = setfscreatecon(filecon); + if (r < 0) { + log_error("Failed to set SELinux file context on %s: %m", path); + r = -errno; + } + + freecon(filecon); + } + + if (r < 0 && security_getenforce() == 0) + r = 0; +#endif + + return r; +} + +int label_socket_set(const char *label) { + +#ifdef HAVE_SELINUX + if (!use_selinux()) + return 0; + + if (setsockcreatecon((security_context_t) label) < 0) { + log_full(security_getenforce() == 1 ? LOG_ERR : LOG_DEBUG, + "Failed to set SELinux context (%s) on socket: %m", label); + + if (security_getenforce() == 1) + return -errno; + } +#endif + + return 0; +} + +void label_context_clear(void) { + +#ifdef HAVE_SELINUX + if (!use_selinux()) + return; + + setfscreatecon(NULL); +#endif +} + +void label_socket_clear(void) { + +#ifdef HAVE_SELINUX + if (!use_selinux()) + return; + + setsockcreatecon(NULL); +#endif +} + +void label_free(const char *label) { + +#ifdef HAVE_SELINUX + if (!use_selinux()) + return; + + freecon((security_context_t) label); +#endif +} + +int label_mkdir(const char *path, mode_t mode, bool apply) { + + /* Creates a directory and labels it according to the SELinux policy */ +#ifdef HAVE_SELINUX + int r; + security_context_t fcon = NULL; + + if (!apply || !use_selinux() || !label_hnd) + goto skipped; + + if (path_is_absolute(path)) + r = selabel_lookup_raw(label_hnd, &fcon, path, S_IFDIR); + else { + char *newpath; + + newpath = path_make_absolute_cwd(path); + if (!newpath) + return -ENOMEM; + + r = selabel_lookup_raw(label_hnd, &fcon, newpath, S_IFDIR); + free(newpath); + } + + if (r == 0) + r = setfscreatecon(fcon); + + if (r < 0 && errno != ENOENT) { + log_error("Failed to set security context %s for %s: %m", fcon, path); + + if (security_getenforce() == 1) { + r = -errno; + goto finish; + } + } + + r = mkdir(path, mode); + if (r < 0) + r = -errno; + +finish: + setfscreatecon(NULL); + freecon(fcon); + + return r; + +skipped: +#endif + return mkdir(path, mode) < 0 ? -errno : 0; +} + +int label_bind(int fd, const struct sockaddr *addr, socklen_t addrlen) { + + /* Binds a socket and label its file system object according to the SELinux policy */ + +#ifdef HAVE_SELINUX + int r; + security_context_t fcon = NULL; + const struct sockaddr_un *un; + char *path = NULL; + + assert(fd >= 0); + assert(addr); + assert(addrlen >= sizeof(sa_family_t)); + + if (!use_selinux() || !label_hnd) + goto skipped; + + /* Filter out non-local sockets */ + if (addr->sa_family != AF_UNIX) + goto skipped; + + /* Filter out anonymous sockets */ + if (addrlen < sizeof(sa_family_t) + 1) + goto skipped; + + /* Filter out abstract namespace sockets */ + un = (const struct sockaddr_un*) addr; + if (un->sun_path[0] == 0) + goto skipped; + + path = strndup(un->sun_path, addrlen - offsetof(struct sockaddr_un, sun_path)); + if (!path) + return -ENOMEM; + + if (path_is_absolute(path)) + r = selabel_lookup_raw(label_hnd, &fcon, path, S_IFSOCK); + else { + char *newpath; + + newpath = path_make_absolute_cwd(path); + + if (!newpath) { + free(path); + return -ENOMEM; + } + + r = selabel_lookup_raw(label_hnd, &fcon, newpath, S_IFSOCK); + free(newpath); + } + + if (r == 0) + r = setfscreatecon(fcon); + + if (r < 0 && errno != ENOENT) { + log_error("Failed to set security context %s for %s: %m", fcon, path); + + if (security_getenforce() == 1) { + r = -errno; + goto finish; + } + } + + r = bind(fd, addr, addrlen); + if (r < 0) + r = -errno; + +finish: + setfscreatecon(NULL); + freecon(fcon); + free(path); + + return r; + +skipped: +#endif + return bind(fd, addr, addrlen) < 0 ? -errno : 0; +} diff --git a/src/shared/label.h b/src/shared/label.h new file mode 100644 index 000000000..1220b1896 --- /dev/null +++ b/src/shared/label.h @@ -0,0 +1,47 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +#include +#include +#include + +int label_init(const char *prefix); +void label_finish(void); + +int label_fix(const char *path, bool ignore_enoent, bool ignore_erofs); + +int label_socket_set(const char *label); +void label_socket_clear(void); + +int label_context_set(const char *path, mode_t mode); +void label_context_clear(void); + +void label_free(const char *label); + +int label_get_create_label_from_exe(const char *exe, char **label); + +int label_mkdir(const char *path, mode_t mode, bool apply); + +void label_retest_selinux(void); + +int label_bind(int fd, const struct sockaddr *addr, socklen_t addrlen); diff --git a/src/shared/linux/Makefile b/src/shared/linux/Makefile new file mode 120000 index 000000000..d0b0e8e00 --- /dev/null +++ b/src/shared/linux/Makefile @@ -0,0 +1 @@ +../Makefile \ No newline at end of file diff --git a/src/shared/linux/auto_dev-ioctl.h b/src/shared/linux/auto_dev-ioctl.h new file mode 100644 index 000000000..850f39b33 --- /dev/null +++ b/src/shared/linux/auto_dev-ioctl.h @@ -0,0 +1,229 @@ +/* + * Copyright 2008 Red Hat, Inc. All rights reserved. + * Copyright 2008 Ian Kent + * + * This file is part of the Linux kernel and is made available under + * the terms of the GNU General Public License, version 2, or at your + * option, any later version, incorporated herein by reference. + */ + +#ifndef _LINUX_AUTO_DEV_IOCTL_H +#define _LINUX_AUTO_DEV_IOCTL_H + +#include + +#ifdef __KERNEL__ +#include +#else +#include +#endif /* __KERNEL__ */ + +#define AUTOFS_DEVICE_NAME "autofs" + +#define AUTOFS_DEV_IOCTL_VERSION_MAJOR 1 +#define AUTOFS_DEV_IOCTL_VERSION_MINOR 0 + +#define AUTOFS_DEVID_LEN 16 + +#define AUTOFS_DEV_IOCTL_SIZE sizeof(struct autofs_dev_ioctl) + +/* + * An ioctl interface for autofs mount point control. + */ + +struct args_protover { + __u32 version; +}; + +struct args_protosubver { + __u32 sub_version; +}; + +struct args_openmount { + __u32 devid; +}; + +struct args_ready { + __u32 token; +}; + +struct args_fail { + __u32 token; + __s32 status; +}; + +struct args_setpipefd { + __s32 pipefd; +}; + +struct args_timeout { + __u64 timeout; +}; + +struct args_requester { + __u32 uid; + __u32 gid; +}; + +struct args_expire { + __u32 how; +}; + +struct args_askumount { + __u32 may_umount; +}; + +struct args_ismountpoint { + union { + struct args_in { + __u32 type; + } in; + struct args_out { + __u32 devid; + __u32 magic; + } out; + }; +}; + +/* + * All the ioctls use this structure. + * When sending a path size must account for the total length + * of the chunk of memory otherwise is is the size of the + * structure. + */ + +struct autofs_dev_ioctl { + __u32 ver_major; + __u32 ver_minor; + __u32 size; /* total size of data passed in + * including this struct */ + __s32 ioctlfd; /* automount command fd */ + + /* Command parameters */ + + union { + struct args_protover protover; + struct args_protosubver protosubver; + struct args_openmount openmount; + struct args_ready ready; + struct args_fail fail; + struct args_setpipefd setpipefd; + struct args_timeout timeout; + struct args_requester requester; + struct args_expire expire; + struct args_askumount askumount; + struct args_ismountpoint ismountpoint; + }; + + char path[0]; +}; + +static inline void init_autofs_dev_ioctl(struct autofs_dev_ioctl *in) +{ + memset(in, 0, sizeof(struct autofs_dev_ioctl)); + in->ver_major = AUTOFS_DEV_IOCTL_VERSION_MAJOR; + in->ver_minor = AUTOFS_DEV_IOCTL_VERSION_MINOR; + in->size = sizeof(struct autofs_dev_ioctl); + in->ioctlfd = -1; + return; +} + +/* + * If you change this make sure you make the corresponding change + * to autofs-dev-ioctl.c:lookup_ioctl() + */ +enum { + /* Get various version info */ + AUTOFS_DEV_IOCTL_VERSION_CMD = 0x71, + AUTOFS_DEV_IOCTL_PROTOVER_CMD, + AUTOFS_DEV_IOCTL_PROTOSUBVER_CMD, + + /* Open mount ioctl fd */ + AUTOFS_DEV_IOCTL_OPENMOUNT_CMD, + + /* Close mount ioctl fd */ + AUTOFS_DEV_IOCTL_CLOSEMOUNT_CMD, + + /* Mount/expire status returns */ + AUTOFS_DEV_IOCTL_READY_CMD, + AUTOFS_DEV_IOCTL_FAIL_CMD, + + /* Activate/deactivate autofs mount */ + AUTOFS_DEV_IOCTL_SETPIPEFD_CMD, + AUTOFS_DEV_IOCTL_CATATONIC_CMD, + + /* Expiry timeout */ + AUTOFS_DEV_IOCTL_TIMEOUT_CMD, + + /* Get mount last requesting uid and gid */ + AUTOFS_DEV_IOCTL_REQUESTER_CMD, + + /* Check for eligible expire candidates */ + AUTOFS_DEV_IOCTL_EXPIRE_CMD, + + /* Request busy status */ + AUTOFS_DEV_IOCTL_ASKUMOUNT_CMD, + + /* Check if path is a mountpoint */ + AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD, +}; + +#define AUTOFS_IOCTL 0x93 + +#define AUTOFS_DEV_IOCTL_VERSION \ + _IOWR(AUTOFS_IOCTL, \ + AUTOFS_DEV_IOCTL_VERSION_CMD, struct autofs_dev_ioctl) + +#define AUTOFS_DEV_IOCTL_PROTOVER \ + _IOWR(AUTOFS_IOCTL, \ + AUTOFS_DEV_IOCTL_PROTOVER_CMD, struct autofs_dev_ioctl) + +#define AUTOFS_DEV_IOCTL_PROTOSUBVER \ + _IOWR(AUTOFS_IOCTL, \ + AUTOFS_DEV_IOCTL_PROTOSUBVER_CMD, struct autofs_dev_ioctl) + +#define AUTOFS_DEV_IOCTL_OPENMOUNT \ + _IOWR(AUTOFS_IOCTL, \ + AUTOFS_DEV_IOCTL_OPENMOUNT_CMD, struct autofs_dev_ioctl) + +#define AUTOFS_DEV_IOCTL_CLOSEMOUNT \ + _IOWR(AUTOFS_IOCTL, \ + AUTOFS_DEV_IOCTL_CLOSEMOUNT_CMD, struct autofs_dev_ioctl) + +#define AUTOFS_DEV_IOCTL_READY \ + _IOWR(AUTOFS_IOCTL, \ + AUTOFS_DEV_IOCTL_READY_CMD, struct autofs_dev_ioctl) + +#define AUTOFS_DEV_IOCTL_FAIL \ + _IOWR(AUTOFS_IOCTL, \ + AUTOFS_DEV_IOCTL_FAIL_CMD, struct autofs_dev_ioctl) + +#define AUTOFS_DEV_IOCTL_SETPIPEFD \ + _IOWR(AUTOFS_IOCTL, \ + AUTOFS_DEV_IOCTL_SETPIPEFD_CMD, struct autofs_dev_ioctl) + +#define AUTOFS_DEV_IOCTL_CATATONIC \ + _IOWR(AUTOFS_IOCTL, \ + AUTOFS_DEV_IOCTL_CATATONIC_CMD, struct autofs_dev_ioctl) + +#define AUTOFS_DEV_IOCTL_TIMEOUT \ + _IOWR(AUTOFS_IOCTL, \ + AUTOFS_DEV_IOCTL_TIMEOUT_CMD, struct autofs_dev_ioctl) + +#define AUTOFS_DEV_IOCTL_REQUESTER \ + _IOWR(AUTOFS_IOCTL, \ + AUTOFS_DEV_IOCTL_REQUESTER_CMD, struct autofs_dev_ioctl) + +#define AUTOFS_DEV_IOCTL_EXPIRE \ + _IOWR(AUTOFS_IOCTL, \ + AUTOFS_DEV_IOCTL_EXPIRE_CMD, struct autofs_dev_ioctl) + +#define AUTOFS_DEV_IOCTL_ASKUMOUNT \ + _IOWR(AUTOFS_IOCTL, \ + AUTOFS_DEV_IOCTL_ASKUMOUNT_CMD, struct autofs_dev_ioctl) + +#define AUTOFS_DEV_IOCTL_ISMOUNTPOINT \ + _IOWR(AUTOFS_IOCTL, \ + AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD, struct autofs_dev_ioctl) + +#endif /* _LINUX_AUTO_DEV_IOCTL_H */ diff --git a/src/shared/linux/fanotify.h b/src/shared/linux/fanotify.h new file mode 100644 index 000000000..63531a6b4 --- /dev/null +++ b/src/shared/linux/fanotify.h @@ -0,0 +1,98 @@ +#ifndef _LINUX_FANOTIFY_H +#define _LINUX_FANOTIFY_H + +#include + +/* the following events that user-space can register for */ +#define FAN_ACCESS 0x00000001 /* File was accessed */ +#define FAN_MODIFY 0x00000002 /* File was modified */ +#define FAN_CLOSE_WRITE 0x00000008 /* Unwrittable file closed */ +#define FAN_CLOSE_NOWRITE 0x00000010 /* Writtable file closed */ +#define FAN_OPEN 0x00000020 /* File was opened */ + +#define FAN_EVENT_ON_CHILD 0x08000000 /* interested in child events */ + +/* FIXME currently Q's have no limit.... */ +#define FAN_Q_OVERFLOW 0x00004000 /* Event queued overflowed */ + +#define FAN_OPEN_PERM 0x00010000 /* File open in perm check */ +#define FAN_ACCESS_PERM 0x00020000 /* File accessed in perm check */ + +/* helper events */ +#define FAN_CLOSE (FAN_CLOSE_WRITE | FAN_CLOSE_NOWRITE) /* close */ + +/* flags used for fanotify_init() */ +#define FAN_CLOEXEC 0x00000001 +#define FAN_NONBLOCK 0x00000002 + +#define FAN_ALL_INIT_FLAGS (FAN_CLOEXEC | FAN_NONBLOCK) + +/* flags used for fanotify_modify_mark() */ +#define FAN_MARK_ADD 0x00000001 +#define FAN_MARK_REMOVE 0x00000002 +#define FAN_MARK_DONT_FOLLOW 0x00000004 +#define FAN_MARK_ONLYDIR 0x00000008 +#define FAN_MARK_MOUNT 0x00000010 +#define FAN_MARK_IGNORED_MASK 0x00000020 +#define FAN_MARK_IGNORED_SURV_MODIFY 0x00000040 +#define FAN_MARK_FLUSH 0x00000080 + +#define FAN_ALL_MARK_FLAGS (FAN_MARK_ADD |\ + FAN_MARK_REMOVE |\ + FAN_MARK_DONT_FOLLOW |\ + FAN_MARK_ONLYDIR |\ + FAN_MARK_MOUNT |\ + FAN_MARK_IGNORED_MASK |\ + FAN_MARK_IGNORED_SURV_MODIFY) + +/* + * All of the events - we build the list by hand so that we can add flags in + * the future and not break backward compatibility. Apps will get only the + * events that they originally wanted. Be sure to add new events here! + */ +#define FAN_ALL_EVENTS (FAN_ACCESS |\ + FAN_MODIFY |\ + FAN_CLOSE |\ + FAN_OPEN) + +/* + * All events which require a permission response from userspace + */ +#define FAN_ALL_PERM_EVENTS (FAN_OPEN_PERM |\ + FAN_ACCESS_PERM) + +#define FAN_ALL_OUTGOING_EVENTS (FAN_ALL_EVENTS |\ + FAN_ALL_PERM_EVENTS |\ + FAN_Q_OVERFLOW) + +#define FANOTIFY_METADATA_VERSION 2 + +struct fanotify_event_metadata { + __u32 event_len; + __u32 vers; + __u64 mask; + __s32 fd; + __s32 pid; +} __attribute__ ((packed)); + +struct fanotify_response { + __s32 fd; + __u32 response; +} __attribute__ ((packed)); + +/* Legit userspace responses to a _PERM event */ +#define FAN_ALLOW 0x01 +#define FAN_DENY 0x02 + +/* Helper functions to deal with fanotify_event_metadata buffers */ +#define FAN_EVENT_METADATA_LEN (sizeof(struct fanotify_event_metadata)) + +#define FAN_EVENT_NEXT(meta, len) ((len) -= (meta)->event_len, \ + (struct fanotify_event_metadata*)(((char *)(meta)) + \ + (meta)->event_len)) + +#define FAN_EVENT_OK(meta, len) ((long)(len) >= (long)FAN_EVENT_METADATA_LEN && \ + (long)(meta)->event_len >= (long)FAN_EVENT_METADATA_LEN && \ + (long)(meta)->event_len <= (long)(len)) + +#endif /* _LINUX_FANOTIFY_H */ diff --git a/src/shared/linux/seccomp-bpf.h b/src/shared/linux/seccomp-bpf.h new file mode 100644 index 000000000..1e3d13673 --- /dev/null +++ b/src/shared/linux/seccomp-bpf.h @@ -0,0 +1,76 @@ +/* + * seccomp example for x86 (32-bit and 64-bit) with BPF macros + * + * Copyright (c) 2012 The Chromium OS Authors + * Authors: + * Will Drewry + * Kees Cook + * + * The code may be used by anyone for any purpose, and can serve as a + * starting point for developing applications using mode 2 seccomp. + */ +#ifndef _SECCOMP_BPF_H_ +#define _SECCOMP_BPF_H_ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#ifndef SECCOMP_MODE_FILTER +# define SECCOMP_MODE_FILTER 2 /* uses user-supplied filter. */ +# define SECCOMP_RET_KILL 0x00000000U /* kill the task immediately */ +# define SECCOMP_RET_TRAP 0x00030000U /* disallow and force a SIGSYS */ +# define SECCOMP_RET_ALLOW 0x7fff0000U /* allow */ +struct seccomp_data { + int nr; + __u32 arch; + __u64 instruction_pointer; + __u64 args[6]; +}; +#endif +#ifndef SYS_SECCOMP +# define SYS_SECCOMP 1 +#endif + +#define syscall_nr (offsetof(struct seccomp_data, nr)) +#define arch_nr (offsetof(struct seccomp_data, arch)) + +#if defined(__i386__) +# define REG_SYSCALL REG_EAX +# define ARCH_NR AUDIT_ARCH_I386 +#elif defined(__x86_64__) +# define REG_SYSCALL REG_RAX +# define ARCH_NR AUDIT_ARCH_X86_64 +#else +# warning "Platform does not support seccomp filter yet" +# define REG_SYSCALL 0 +# define ARCH_NR 0 +#endif + +#define VALIDATE_ARCHITECTURE \ + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, arch_nr), \ + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ARCH_NR, 1, 0), \ + BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL) + +#define EXAMINE_SYSCALL \ + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, syscall_nr) + +#define ALLOW_SYSCALL(name) \ + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_##name, 0, 1), \ + BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW) + +#define _KILL_PROCESS \ + BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL) + +#endif /* _SECCOMP_BPF_H_ */ diff --git a/src/shared/linux/seccomp.h b/src/shared/linux/seccomp.h new file mode 100644 index 000000000..9c03683fa --- /dev/null +++ b/src/shared/linux/seccomp.h @@ -0,0 +1,47 @@ +#ifndef _LINUX_SECCOMP_H +#define _LINUX_SECCOMP_H + + +#include + + +/* Valid values for seccomp.mode and prctl(PR_SET_SECCOMP, ) */ +#define SECCOMP_MODE_DISABLED 0 /* seccomp is not in use. */ +#define SECCOMP_MODE_STRICT 1 /* uses hard-coded filter. */ +#define SECCOMP_MODE_FILTER 2 /* uses user-supplied filter. */ + +/* + * All BPF programs must return a 32-bit value. + * The bottom 16-bits are for optional return data. + * The upper 16-bits are ordered from least permissive values to most. + * + * The ordering ensures that a min_t() over composed return values always + * selects the least permissive choice. + */ +#define SECCOMP_RET_KILL 0x00000000U /* kill the task immediately */ +#define SECCOMP_RET_TRAP 0x00030000U /* disallow and force a SIGSYS */ +#define SECCOMP_RET_ERRNO 0x00050000U /* returns an errno */ +#define SECCOMP_RET_TRACE 0x7ff00000U /* pass to a tracer or disallow */ +#define SECCOMP_RET_ALLOW 0x7fff0000U /* allow */ + +/* Masks for the return value sections. */ +#define SECCOMP_RET_ACTION 0x7fff0000U +#define SECCOMP_RET_DATA 0x0000ffffU + +/** + * struct seccomp_data - the format the BPF program executes over. + * @nr: the system call number + * @arch: indicates system call convention as an AUDIT_ARCH_* value + * as defined in . + * @instruction_pointer: at the time of the system call. + * @args: up to 6 system call arguments always stored as 64-bit values + * regardless of the architecture. + */ +struct seccomp_data { + int nr; + __u32 arch; + __u64 instruction_pointer; + __u64 args[6]; +}; + +#endif /* _LINUX_SECCOMP_H */ diff --git a/src/shared/list.h b/src/shared/list.h new file mode 100644 index 000000000..47f275a01 --- /dev/null +++ b/src/shared/list.h @@ -0,0 +1,125 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +/* The head of the linked list. Use this in the structure that shall + * contain the head of the linked list */ +#define LIST_HEAD(t,name) \ + t *name + +/* The pointers in the linked list's items. Use this in the item structure */ +#define LIST_FIELDS(t,name) \ + t *name##_next, *name##_prev + +/* Initialize the list's head */ +#define LIST_HEAD_INIT(t,head) \ + do { \ + (head) = NULL; } \ + while(false) + +/* Initialize a list item */ +#define LIST_INIT(t,name,item) \ + do { \ + t *_item = (item); \ + assert(_item); \ + _item->name##_prev = _item->name##_next = NULL; \ + } while(false) + +/* Prepend an item to the list */ +#define LIST_PREPEND(t,name,head,item) \ + do { \ + t **_head = &(head), *_item = (item); \ + assert(_item); \ + if ((_item->name##_next = *_head)) \ + _item->name##_next->name##_prev = _item; \ + _item->name##_prev = NULL; \ + *_head = _item; \ + } while(false) + +/* Remove an item from the list */ +#define LIST_REMOVE(t,name,head,item) \ + do { \ + t **_head = &(head), *_item = (item); \ + assert(_item); \ + if (_item->name##_next) \ + _item->name##_next->name##_prev = _item->name##_prev; \ + if (_item->name##_prev) \ + _item->name##_prev->name##_next = _item->name##_next; \ + else { \ + assert(*_head == _item); \ + *_head = _item->name##_next; \ + } \ + _item->name##_next = _item->name##_prev = NULL; \ + } while(false) + +/* Find the head of the list */ +#define LIST_FIND_HEAD(t,name,item,head) \ + do { \ + t *_item = (item); \ + assert(_item); \ + while (_item->name##_prev) \ + _item = _item->name##_prev; \ + (head) = _item; \ + } while (false) + +/* Find the head of the list */ +#define LIST_FIND_TAIL(t,name,item,tail) \ + do { \ + t *_item = (item); \ + assert(_item); \ + while (_item->name##_next) \ + _item = _item->name##_next; \ + (tail) = _item; \ + } while (false) + +/* Insert an item after another one (a = where, b = what) */ +#define LIST_INSERT_AFTER(t,name,head,a,b) \ + do { \ + t **_head = &(head), *_a = (a), *_b = (b); \ + assert(_b); \ + if (!_a) { \ + if ((_b->name##_next = *_head)) \ + _b->name##_next->name##_prev = _b; \ + _b->name##_prev = NULL; \ + *_head = _b; \ + } else { \ + if ((_b->name##_next = _a->name##_next)) \ + _b->name##_next->name##_prev = _b; \ + _b->name##_prev = _a; \ + _a->name##_next = _b; \ + } \ + } while(false) + +#define LIST_JUST_US(name,item) \ + (!(item)->name##_prev && !(item)->name##_next) \ + +#define LIST_FOREACH(name,i,head) \ + for ((i) = (head); (i); (i) = (i)->name##_next) + +#define LIST_FOREACH_SAFE(name,i,n,head) \ + for ((i) = (head); (i) && (((n) = (i)->name##_next), 1); (i) = (n)) + +#define LIST_FOREACH_BEFORE(name,i,p) \ + for ((i) = (p)->name##_prev; (i); (i) = (i)->name##_prev) + +#define LIST_FOREACH_AFTER(name,i,p) \ + for ((i) = (p)->name##_next; (i); (i) = (i)->name##_next) diff --git a/src/shared/log.c b/src/shared/log.c new file mode 100644 index 000000000..8d3458e73 --- /dev/null +++ b/src/shared/log.c @@ -0,0 +1,952 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "log.h" +#include "util.h" +#include "missing.h" +#include "macro.h" +#include "socket-util.h" + +#define SNDBUF_SIZE (8*1024*1024) + +static LogTarget log_target = LOG_TARGET_CONSOLE; +static int log_max_level = LOG_INFO; +static int log_facility = LOG_DAEMON; + +static int console_fd = STDERR_FILENO; +static int syslog_fd = -1; +static int kmsg_fd = -1; +static int journal_fd = -1; + +static bool syslog_is_stream = false; + +static bool show_color = false; +static bool show_location = 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) { + + if (console_fd < 0) + return; + + if (getpid() == 1) { + if (console_fd >= 3) + close_nointr_nofail(console_fd); + + console_fd = -1; + } +} + +static int log_open_console(void) { + + if (console_fd >= 0) + return 0; + + if (getpid() == 1) { + 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) { + + if (kmsg_fd < 0) + return; + + close_nointr_nofail(kmsg_fd); + kmsg_fd = -1; +} + +static int log_open_kmsg(void) { + + if (kmsg_fd >= 0) + return 0; + + kmsg_fd = open("/dev/kmsg", O_WRONLY|O_NOCTTY|O_CLOEXEC); + if (kmsg_fd < 0) + return -errno; + + return 0; +} + +void log_close_syslog(void) { + + if (syslog_fd < 0) + return; + + close_nointr_nofail(syslog_fd); + syslog_fd = -1; +} + +static int create_log_socket(int type) { + int fd; + + /* All output to the syslog/journal fds we do asynchronously, + * and if the buffers are full we just drop the messages */ + + fd = socket(AF_UNIX, type|SOCK_CLOEXEC|SOCK_NONBLOCK, 0); + if (fd < 0) + return -errno; + + fd_inc_sndbuf(fd, SNDBUF_SIZE); + + return fd; +} + +static int log_open_syslog(void) { + union sockaddr_union sa; + int r; + + if (syslog_fd >= 0) + return 0; + + zero(sa); + sa.un.sun_family = AF_UNIX; + strncpy(sa.un.sun_path, "/dev/log", sizeof(sa.un.sun_path)); + + syslog_fd = create_log_socket(SOCK_DGRAM); + if (syslog_fd < 0) { + r = syslog_fd; + goto fail; + } + + if (connect(syslog_fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0) { + close_nointr_nofail(syslog_fd); + + /* Some legacy syslog systems still use stream + * sockets. They really shouldn't. But what can we + * do... */ + syslog_fd = create_log_socket(SOCK_STREAM); + if (syslog_fd < 0) { + r = syslog_fd; + goto fail; + } + + if (connect(syslog_fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0) { + r = -errno; + goto fail; + } + + syslog_is_stream = true; + } else + syslog_is_stream = false; + + return 0; + +fail: + log_close_syslog(); + return r; +} + +void log_close_journal(void) { + + if (journal_fd < 0) + return; + + close_nointr_nofail(journal_fd); + journal_fd = -1; +} + +static int log_open_journal(void) { + union sockaddr_union sa; + int r; + + if (journal_fd >= 0) + return 0; + + journal_fd = create_log_socket(SOCK_DGRAM); + if (journal_fd < 0) { + r = journal_fd; + goto fail; + } + + zero(sa); + sa.un.sun_family = AF_UNIX; + strncpy(sa.un.sun_path, "/run/systemd/journal/socket", sizeof(sa.un.sun_path)); + + if (connect(journal_fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0) { + r = -errno; + goto fail; + } + + return 0; + +fail: + log_close_journal(); + return r; +} + +int log_open(void) { + int r; + + /* 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, + * because there is no reason to close it. */ + + if (log_target == LOG_TARGET_NULL) { + log_close_journal(); + log_close_syslog(); + log_close_console(); + return 0; + } + + if ((log_target != LOG_TARGET_AUTO && log_target != LOG_TARGET_SAFE) || + getpid() == 1 || + isatty(STDERR_FILENO) <= 0) { + + if (log_target == LOG_TARGET_AUTO || + log_target == LOG_TARGET_JOURNAL_OR_KMSG || + log_target == LOG_TARGET_JOURNAL) { + r = log_open_journal(); + if (r >= 0) { + log_close_syslog(); + log_close_console(); + return r; + } + } + + if (log_target == LOG_TARGET_SYSLOG_OR_KMSG || + log_target == LOG_TARGET_SYSLOG) { + r = log_open_syslog(); + if (r >= 0) { + log_close_journal(); + log_close_console(); + return r; + } + } + + if (log_target == LOG_TARGET_AUTO || + log_target == LOG_TARGET_SAFE || + log_target == LOG_TARGET_JOURNAL_OR_KMSG || + log_target == LOG_TARGET_SYSLOG_OR_KMSG || + log_target == LOG_TARGET_KMSG) { + r = log_open_kmsg(); + if (r >= 0) { + log_close_journal(); + log_close_syslog(); + log_close_console(); + return r; + } + } + } + + log_close_journal(); + log_close_syslog(); + + /* Get the real /dev/console if we are PID=1, hence reopen */ + log_close_console(); + return log_open_console(); +} + +void log_set_target(LogTarget target) { + assert(target >= 0); + assert(target < _LOG_TARGET_MAX); + + log_target = target; +} + +void log_close(void) { + log_close_journal(); + log_close_syslog(); + log_close_kmsg(); + log_close_console(); +} + +void log_forget_fds(void) { + console_fd = kmsg_fd = syslog_fd = journal_fd = -1; +} + +void log_set_max_level(int level) { + assert((level & LOG_PRIMASK) == level); + + log_max_level = level; +} + +void log_set_facility(int facility) { + log_facility = facility; +} + +static int write_to_console( + int level, + const char*file, + int line, + const char *func, + const char *object_name, + const char *object, + const char *buffer) { + + char location[64]; + struct iovec iovec[5]; + unsigned n = 0; + bool highlight; + + if (console_fd < 0) + return 0; + + highlight = LOG_PRI(level) <= LOG_ERR && show_color; + + zero(iovec); + + if (show_location) { + snprintf(location, sizeof(location), "(%s:%u) ", file, line); + char_array_0(location); + IOVEC_SET_STRING(iovec[n++], location); + } + + if (highlight) + IOVEC_SET_STRING(iovec[n++], ANSI_HIGHLIGHT_RED_ON); + IOVEC_SET_STRING(iovec[n++], buffer); + if (highlight) + IOVEC_SET_STRING(iovec[n++], ANSI_HIGHLIGHT_OFF); + IOVEC_SET_STRING(iovec[n++], "\n"); + + if (writev(console_fd, iovec, n) < 0) + return -errno; + + return 1; +} + +static int write_to_syslog( + int level, + const char*file, + int line, + const char *func, + const char *object_name, + const char *object, + const char *buffer) { + + char header_priority[16], header_time[64], header_pid[16]; + struct iovec iovec[5]; + struct msghdr msghdr; + time_t t; + struct tm *tm; + + if (syslog_fd < 0) + return 0; + + snprintf(header_priority, sizeof(header_priority), "<%i>", level); + char_array_0(header_priority); + + t = (time_t) (now(CLOCK_REALTIME) / USEC_PER_SEC); + tm = localtime(&t); + if (!tm) + return -EINVAL; + + if (strftime(header_time, sizeof(header_time), "%h %e %T ", tm) <= 0) + return -EINVAL; + + snprintf(header_pid, sizeof(header_pid), "[%lu]: ", (unsigned long) getpid()); + char_array_0(header_pid); + + zero(iovec); + IOVEC_SET_STRING(iovec[0], header_priority); + IOVEC_SET_STRING(iovec[1], header_time); + IOVEC_SET_STRING(iovec[2], program_invocation_short_name); + IOVEC_SET_STRING(iovec[3], header_pid); + IOVEC_SET_STRING(iovec[4], buffer); + + /* When using syslog via SOCK_STREAM separate the messages by NUL chars */ + if (syslog_is_stream) + iovec[4].iov_len++; + + zero(msghdr); + msghdr.msg_iov = iovec; + msghdr.msg_iovlen = ELEMENTSOF(iovec); + + for (;;) { + ssize_t n; + + n = sendmsg(syslog_fd, &msghdr, MSG_NOSIGNAL); + if (n < 0) + return -errno; + + if (!syslog_is_stream || + (size_t) n >= IOVEC_TOTAL_SIZE(iovec, ELEMENTSOF(iovec))) + break; + + IOVEC_INCREMENT(iovec, ELEMENTSOF(iovec), n); + } + + return 1; +} + +static int write_to_kmsg( + int level, + const char*file, + int line, + const char *func, + const char *object_name, + const char *object, + const char *buffer) { + + char header_priority[16], header_pid[16]; + struct iovec iovec[5]; + + if (kmsg_fd < 0) + return 0; + + snprintf(header_priority, sizeof(header_priority), "<%i>", level); + char_array_0(header_priority); + + snprintf(header_pid, sizeof(header_pid), "[%lu]: ", (unsigned long) getpid()); + char_array_0(header_pid); + + zero(iovec); + IOVEC_SET_STRING(iovec[0], header_priority); + IOVEC_SET_STRING(iovec[1], program_invocation_short_name); + IOVEC_SET_STRING(iovec[2], header_pid); + IOVEC_SET_STRING(iovec[3], buffer); + IOVEC_SET_STRING(iovec[4], "\n"); + + if (writev(kmsg_fd, iovec, ELEMENTSOF(iovec)) < 0) + return -errno; + + return 1; +} + +static int write_to_journal( + int level, + const char*file, + int line, + const char *func, + const char *object_name, + const char *object, + const char *buffer) { + + char header[LINE_MAX]; + struct iovec iovec[3]; + struct msghdr mh; + + if (journal_fd < 0) + return 0; + + snprintf(header, sizeof(header), + "PRIORITY=%i\n" + "SYSLOG_FACILITY=%i\n" + "CODE_FILE=%s\n" + "CODE_LINE=%i\n" + "CODE_FUNCTION=%s\n" + "%s%.*s%s" + "SYSLOG_IDENTIFIER=%s\n" + "MESSAGE=", + LOG_PRI(level), + LOG_FAC(level), + file, + line, + func, + object ? object_name : "", + object ? LINE_MAX : 0, object, /* %.0s means no output */ + object ? "\n" : "", + program_invocation_short_name); + + char_array_0(header); + + zero(iovec); + IOVEC_SET_STRING(iovec[0], header); + IOVEC_SET_STRING(iovec[1], buffer); + IOVEC_SET_STRING(iovec[2], "\n"); + + zero(mh); + mh.msg_iov = iovec; + mh.msg_iovlen = ELEMENTSOF(iovec); + + if (sendmsg(journal_fd, &mh, MSG_NOSIGNAL) < 0) + return -errno; + + return 1; +} + +static int log_dispatch( + int level, + const char*file, + int line, + const char *func, + const char *object_name, + const char *object, + char *buffer) { + + int r = 0; + + if (log_target == LOG_TARGET_NULL) + return 0; + + /* Patch in LOG_DAEMON facility if necessary */ + if ((level & LOG_FACMASK) == 0) + level = log_facility | LOG_PRI(level); + + do { + char *e; + int k = 0; + + buffer += strspn(buffer, NEWLINE); + + if (buffer[0] == 0) + break; + + if ((e = strpbrk(buffer, NEWLINE))) + *(e++) = 0; + + if (log_target == LOG_TARGET_AUTO || + log_target == LOG_TARGET_JOURNAL_OR_KMSG || + log_target == LOG_TARGET_JOURNAL) { + + k = write_to_journal(level, file, line, func, + object_name, object, buffer); + if (k < 0) { + if (k != -EAGAIN) + log_close_journal(); + log_open_kmsg(); + } else if (k > 0) + r++; + } + + if (log_target == LOG_TARGET_SYSLOG_OR_KMSG || + log_target == LOG_TARGET_SYSLOG) { + + k = write_to_syslog(level, file, line, func, + object_name, object, buffer); + if (k < 0) { + if (k != -EAGAIN) + log_close_syslog(); + log_open_kmsg(); + } else if (k > 0) + r++; + } + + if (k <= 0 && + (log_target == LOG_TARGET_AUTO || + log_target == LOG_TARGET_SAFE || + log_target == LOG_TARGET_SYSLOG_OR_KMSG || + log_target == LOG_TARGET_JOURNAL_OR_KMSG || + log_target == LOG_TARGET_KMSG)) { + + k = write_to_kmsg(level, file, line, func, + object_name, object, buffer); + if (k < 0) { + log_close_kmsg(); + log_open_console(); + } else if (k > 0) + r++; + } + + if (k <= 0) { + k = write_to_console(level, file, line, func, + object_name, object, buffer); + if (k < 0) + return k; + } + + buffer = e; + } while (buffer); + + return r; +} + +int log_dump_internal( + int level, + const char*file, + int line, + const char *func, + char *buffer) { + + int saved_errno, r; + + /* This modifies the buffer... */ + + if (_likely_(LOG_PRI(level) > log_max_level)) + return 0; + + saved_errno = errno; + r = log_dispatch(level, file, line, func, NULL, NULL, buffer); + errno = saved_errno; + + return r; +} + +int log_metav( + int level, + const char*file, + int line, + const char *func, + const char *format, + va_list ap) { + + char buffer[LINE_MAX]; + int saved_errno, r; + + if (_likely_(LOG_PRI(level) > log_max_level)) + return 0; + + saved_errno = errno; + vsnprintf(buffer, sizeof(buffer), format, ap); + char_array_0(buffer); + + r = log_dispatch(level, file, line, func, NULL, NULL, buffer); + errno = saved_errno; + + return r; +} + +int log_meta( + int level, + const char*file, + int line, + const char *func, + const char *format, ...) { + + int r; + va_list ap; + + va_start(ap, format); + r = log_metav(level, file, line, func, format, ap); + va_end(ap); + + return r; +} + +int log_metav_object( + int level, + const char*file, + int line, + const char *func, + const char *object_name, + const char *object, + const char *format, + va_list ap) { + + char buffer[LINE_MAX]; + int saved_errno, r; + + if (_likely_(LOG_PRI(level) > log_max_level)) + return 0; + + saved_errno = errno; + vsnprintf(buffer, sizeof(buffer), format, ap); + char_array_0(buffer); + + r = log_dispatch(level, file, line, func, + object_name, object, buffer); + errno = saved_errno; + + return r; +} + +int log_meta_object( + int level, + const char*file, + int line, + const char *func, + const char *object_name, + const char *object, + const char *format, ...) { + + int r; + va_list ap; + + va_start(ap, format); + r = log_metav_object(level, file, line, func, + object_name, object, format, ap); + va_end(ap); + + return r; +} + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wformat-nonliteral" +_noreturn_ static void log_assert(const char *text, const char *file, int line, const char *func, const char *format) { + static char buffer[LINE_MAX]; + + snprintf(buffer, sizeof(buffer), format, text, file, line, func); + + char_array_0(buffer); + log_abort_msg = buffer; + + log_dispatch(LOG_CRIT, file, line, func, NULL, NULL, buffer); + abort(); +} +#pragma GCC diagnostic pop + +_noreturn_ void log_assert_failed(const char *text, const char *file, int line, const char *func) { + log_assert(text, file, line, func, "Assertion '%s' failed at %s:%u, function %s(). Aborting."); +} + +_noreturn_ void log_assert_failed_unreachable(const char *text, const char *file, int line, const char *func) { + log_assert(text, file, line, func, "Code should not be reached '%s' at %s:%u, function %s(). Aborting."); +} + +int log_oom_internal(const char *file, int line, const char *func) { + log_meta(LOG_ERR, file, line, func, "Out of memory."); + return -ENOMEM; +} + +int log_struct_internal( + int level, + const char *file, + int line, + const char *func, + const char *format, ...) { + + int saved_errno; + va_list ap; + int r; + + if (_likely_(LOG_PRI(level) > log_max_level)) + return 0; + + if (log_target == LOG_TARGET_NULL) + return 0; + + if ((level & LOG_FACMASK) == 0) + level = log_facility | LOG_PRI(level); + + saved_errno = errno; + + if ((log_target == LOG_TARGET_AUTO || + log_target == LOG_TARGET_JOURNAL_OR_KMSG || + log_target == LOG_TARGET_JOURNAL) && + journal_fd >= 0) { + + char header[LINE_MAX]; + struct iovec iovec[17]; + unsigned n = 0, i; + struct msghdr mh; + const char nl = '\n'; + + /* If the journal is available do structured logging */ + + snprintf(header, sizeof(header), + "PRIORITY=%i\n" + "SYSLOG_FACILITY=%i\n" + "CODE_FILE=%s\n" + "CODE_LINE=%i\n" + "CODE_FUNCTION=%s\n" + "SYSLOG_IDENTIFIER=%s\n", + LOG_PRI(level), + LOG_FAC(level), + file, + line, + func, + program_invocation_short_name); + char_array_0(header); + + zero(iovec); + IOVEC_SET_STRING(iovec[n++], header); + + va_start(ap, format); + while (format && n + 1 < ELEMENTSOF(iovec)) { + char *buf; + va_list aq; + + /* We need to copy the va_list structure, + * since vasprintf() leaves it afterwards at + * an undefined location */ + + va_copy(aq, ap); + if (vasprintf(&buf, format, aq) < 0) { + va_end(aq); + r = -ENOMEM; + goto finish; + } + va_end(aq); + + /* Now, jump enough ahead, so that we point to + * the next format string */ + VA_FORMAT_ADVANCE(format, ap); + + IOVEC_SET_STRING(iovec[n++], buf); + + iovec[n].iov_base = (char*) &nl; + iovec[n].iov_len = 1; + n++; + + format = va_arg(ap, char *); + } + + zero(mh); + mh.msg_iov = iovec; + mh.msg_iovlen = n; + + if (sendmsg(journal_fd, &mh, MSG_NOSIGNAL) < 0) + r = -errno; + else + r = 1; + + finish: + va_end(ap); + for (i = 1; i < n; i += 2) + free(iovec[i].iov_base); + + } else { + char buf[LINE_MAX]; + bool found = false; + + /* Fallback if journal logging is not available */ + + va_start(ap, format); + while (format) { + va_list aq; + + va_copy(aq, ap); + vsnprintf(buf, sizeof(buf), format, aq); + va_end(aq); + char_array_0(buf); + + if (startswith(buf, "MESSAGE=")) { + found = true; + break; + } + + VA_FORMAT_ADVANCE(format, ap); + + format = va_arg(ap, char *); + } + va_end(ap); + + if (found) + r = log_dispatch(level, file, line, func, + NULL, NULL, buf + 8); + else + r = -EINVAL; + } + + errno = saved_errno; + return r; +} + +int log_set_target_from_string(const char *e) { + LogTarget t; + + t = log_target_from_string(e); + if (t < 0) + return -EINVAL; + + log_set_target(t); + return 0; +} + +int log_set_max_level_from_string(const char *e) { + int t; + + t = log_level_from_string(e); + if (t < 0) + return t; + + log_set_max_level(t); + return 0; +} + +void log_parse_environment(void) { + const char *e; + + e = secure_getenv("SYSTEMD_LOG_TARGET"); + if (e && log_set_target_from_string(e) < 0) + log_warning("Failed to parse log target %s. Ignoring.", e); + + e = secure_getenv("SYSTEMD_LOG_LEVEL"); + if (e && log_set_max_level_from_string(e) < 0) + log_warning("Failed to parse log level %s. Ignoring.", e); + + e = secure_getenv("SYSTEMD_LOG_COLOR"); + if (e && log_show_color_from_string(e) < 0) + log_warning("Failed to parse bool %s. Ignoring.", e); + + e = secure_getenv("SYSTEMD_LOG_LOCATION"); + if (e && log_show_location_from_string(e) < 0) + log_warning("Failed to parse bool %s. Ignoring.", e); +} + +LogTarget log_get_target(void) { + return log_target; +} + +int log_get_max_level(void) { + return log_max_level; +} + +void log_show_color(bool b) { + show_color = b; +} + +void log_show_location(bool b) { + show_location = b; +} + +int log_show_color_from_string(const char *e) { + int t; + + t = parse_boolean(e); + if (t < 0) + return t; + + log_show_color(t); + return 0; +} + +int log_show_location_from_string(const char *e) { + int t; + + t = parse_boolean(e); + if (t < 0) + return t; + + log_show_location(t); + return 0; +} + +bool log_on_console(void) { + if (log_target == LOG_TARGET_CONSOLE) + return true; + + return syslog_fd < 0 && kmsg_fd < 0 && journal_fd < 0; +} + +static const char *const log_target_table[] = { + [LOG_TARGET_CONSOLE] = "console", + [LOG_TARGET_KMSG] = "kmsg", + [LOG_TARGET_JOURNAL] = "journal", + [LOG_TARGET_JOURNAL_OR_KMSG] = "journal-or-kmsg", + [LOG_TARGET_SYSLOG] = "syslog", + [LOG_TARGET_SYSLOG_OR_KMSG] = "syslog-or-kmsg", + [LOG_TARGET_AUTO] = "auto", + [LOG_TARGET_SAFE] = "safe", + [LOG_TARGET_NULL] = "null" +}; + +DEFINE_STRING_TABLE_LOOKUP(log_target, LogTarget); diff --git a/src/shared/log.h b/src/shared/log.h new file mode 100644 index 000000000..9aafcb410 --- /dev/null +++ b/src/shared/log.h @@ -0,0 +1,159 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +#include +#include +#include +#include + +#include "macro.h" +#include "sd-id128.h" + +typedef enum LogTarget{ + LOG_TARGET_CONSOLE, + LOG_TARGET_KMSG, + LOG_TARGET_JOURNAL, + LOG_TARGET_JOURNAL_OR_KMSG, + 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 +} LogTarget; + +void log_set_target(LogTarget target); +void log_set_max_level(int level); +void log_set_facility(int facility); + +int log_set_target_from_string(const char *e); +int log_set_max_level_from_string(const char *e); + +void log_show_color(bool b); +void log_show_location(bool b); + +int log_show_color_from_string(const char *e); +int log_show_location_from_string(const char *e); + +LogTarget log_get_target(void); +int log_get_max_level(void); + +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(void); + +int log_meta( + int level, + const char*file, + int line, + const char *func, + const char *format, ...) _printf_attr_(5,6); + +int log_metav( + int level, + const char*file, + int line, + const char *func, + const char *format, + va_list ap); + +int log_meta_object( + int level, + const char*file, + int line, + const char *func, + const char *object_name, + const char *object, + const char *format, ...) _printf_attr_(7,8); + +int log_metav_object( + int level, + const char*file, + int line, + const char *func, + const char *object_name, + const char *object, + const char *format, + va_list ap); + +int log_struct_internal( + int level, + const char *file, + int line, + const char *func, + const char *format, ...) _sentinel_; + +int log_oom_internal( + const char *file, + int line, + const char *func); + +/* This modifies the buffer passed! */ +int log_dump_internal( + int level, + const char*file, + int line, + const char *func, + char *buffer); + +_noreturn_ void log_assert_failed( + const char *text, + const char *file, + int line, + const char *func); + +_noreturn_ void log_assert_failed_unreachable( + const char *text, + const char *file, + int line, + const char *func); + +#define log_full(level, ...) log_meta(level, __FILE__, __LINE__, __func__, __VA_ARGS__) + +#define log_debug(...) log_meta(LOG_DEBUG, __FILE__, __LINE__, __func__, __VA_ARGS__) +#define log_info(...) log_meta(LOG_INFO, __FILE__, __LINE__, __func__, __VA_ARGS__) +#define log_notice(...) log_meta(LOG_NOTICE, __FILE__, __LINE__, __func__, __VA_ARGS__) +#define log_warning(...) log_meta(LOG_WARNING, __FILE__, __LINE__, __func__, __VA_ARGS__) +#define log_error(...) log_meta(LOG_ERR, __FILE__, __LINE__, __func__, __VA_ARGS__) + +#define log_struct(level, ...) log_struct_internal(level, __FILE__, __LINE__, __func__, __VA_ARGS__) + +#define log_oom() log_oom_internal(__FILE__, __LINE__, __func__) + +/* This modifies the buffer passed! */ +#define log_dump(level, buffer) log_dump_internal(level, __FILE__, __LINE__, __func__, buffer) + +bool log_on_console(void); + +const char *log_target_to_string(LogTarget target); +LogTarget log_target_from_string(const char *s); + +#define MESSAGE_ID(x) "MESSAGE_ID=" SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(x) diff --git a/src/shared/logs-show.c b/src/shared/logs-show.c new file mode 100644 index 000000000..04450a550 --- /dev/null +++ b/src/shared/logs-show.c @@ -0,0 +1,943 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + +#include +#include +#include +#include +#include + +#include "logs-show.h" +#include "log.h" +#include "util.h" +#include "utf8.h" +#include "hashmap.h" + +#define PRINT_THRESHOLD 128 +#define JSON_THRESHOLD 4096 + +static int print_catalog(FILE *f, sd_journal *j) { + int r; + _cleanup_free_ char *t = NULL, *z = NULL; + + + r = sd_journal_get_catalog(j, &t); + if (r < 0) + return r; + + z = strreplace(strstrip(t), "\n", "\n-- "); + if (!z) + return log_oom(); + + fputs("-- ", f); + fputs(z, f); + fputc('\n', f); + + return 0; +} + +static int parse_field(const void *data, size_t length, const char *field, char **target, size_t *target_size) { + size_t fl, nl; + void *buf; + + assert(data); + assert(field); + assert(target); + assert(target_size); + + fl = strlen(field); + if (length < fl) + return 0; + + if (memcmp(data, field, fl)) + return 0; + + nl = length - fl; + buf = malloc(nl+1); + if (!buf) + return log_oom(); + + memcpy(buf, (const char*) data + fl, nl); + ((char*)buf)[nl] = 0; + + free(*target); + *target = buf; + *target_size = nl; + + return 1; +} + +static bool shall_print(const char *p, size_t l, OutputFlags flags) { + assert(p); + + if (flags & OUTPUT_SHOW_ALL) + return true; + + if (l >= PRINT_THRESHOLD) + return false; + + if (!utf8_is_printable_n(p, l)) + return false; + + return true; +} + +static int output_short( + FILE *f, + sd_journal *j, + OutputMode mode, + unsigned n_columns, + OutputFlags flags) { + + int r; + const void *data; + size_t length; + size_t n = 0; + _cleanup_free_ char *hostname = NULL, *identifier = NULL, *comm = NULL, *pid = NULL, *fake_pid = NULL, *message = NULL, *realtime = NULL, *monotonic = NULL, *priority = NULL; + size_t hostname_len = 0, identifier_len = 0, comm_len = 0, pid_len = 0, fake_pid_len = 0, message_len = 0, realtime_len = 0, monotonic_len = 0, priority_len = 0; + int p = LOG_INFO; + const char *color_on = "", *color_off = ""; + + assert(f); + assert(j); + + sd_journal_set_data_threshold(j, flags & OUTPUT_SHOW_ALL ? 0 : PRINT_THRESHOLD); + + SD_JOURNAL_FOREACH_DATA(j, data, length) { + + r = parse_field(data, length, "PRIORITY=", &priority, &priority_len); + if (r < 0) + return r; + else if (r > 0) + continue; + + r = parse_field(data, length, "_HOSTNAME=", &hostname, &hostname_len); + if (r < 0) + return r; + else if (r > 0) + continue; + + r = parse_field(data, length, "SYSLOG_IDENTIFIER=", &identifier, &identifier_len); + if (r < 0) + return r; + else if (r > 0) + continue; + + r = parse_field(data, length, "_COMM=", &comm, &comm_len); + if (r < 0) + return r; + else if (r > 0) + continue; + + r = parse_field(data, length, "_PID=", &pid, &pid_len); + if (r < 0) + return r; + else if (r > 0) + continue; + + r = parse_field(data, length, "SYSLOG_PID=", &fake_pid, &fake_pid_len); + if (r < 0) + return r; + else if (r > 0) + continue; + + r = parse_field(data, length, "_SOURCE_REALTIME_TIMESTAMP=", &realtime, &realtime_len); + if (r < 0) + return r; + else if (r > 0) + continue; + + r = parse_field(data, length, "_SOURCE_MONOTONIC_TIMESTAMP=", &monotonic, &monotonic_len); + if (r < 0) + return r; + else if (r > 0) + continue; + + r = parse_field(data, length, "MESSAGE=", &message, &message_len); + if (r < 0) + return r; + } + + if (!message) + return 0; + + if (!(flags & OUTPUT_SHOW_ALL)) + strip_tab_ansi(&message, &message_len); + + if (priority_len == 1 && *priority >= '0' && *priority <= '7') + p = *priority - '0'; + + if (mode == OUTPUT_SHORT_MONOTONIC) { + uint64_t t; + sd_id128_t boot_id; + + r = -ENOENT; + + if (monotonic) + r = safe_atou64(monotonic, &t); + + if (r < 0) + r = sd_journal_get_monotonic_usec(j, &t, &boot_id); + + if (r < 0) { + log_error("Failed to get monotonic: %s", strerror(-r)); + return r; + } + + fprintf(f, "[%5llu.%06llu]", + (unsigned long long) (t / USEC_PER_SEC), + (unsigned long long) (t % USEC_PER_SEC)); + + n += 1 + 5 + 1 + 6 + 1; + + } else { + char buf[64]; + uint64_t x; + time_t t; + struct tm tm; + + r = -ENOENT; + + if (realtime) + r = safe_atou64(realtime, &x); + + if (r < 0) + r = sd_journal_get_realtime_usec(j, &x); + + if (r < 0) { + log_error("Failed to get realtime: %s", strerror(-r)); + return r; + } + + t = (time_t) (x / USEC_PER_SEC); + if (strftime(buf, sizeof(buf), "%b %d %H:%M:%S", localtime_r(&t, &tm)) <= 0) { + log_error("Failed to format time."); + return r; + } + + fputs(buf, f); + n += strlen(buf); + } + + if (hostname && shall_print(hostname, hostname_len, flags)) { + fprintf(f, " %.*s", (int) hostname_len, hostname); + n += hostname_len + 1; + } + + if (identifier && shall_print(identifier, identifier_len, flags)) { + fprintf(f, " %.*s", (int) identifier_len, identifier); + n += identifier_len + 1; + } else if (comm && shall_print(comm, comm_len, flags)) { + fprintf(f, " %.*s", (int) comm_len, comm); + n += comm_len + 1; + } else + fputc(' ', f); + + if (pid && shall_print(pid, pid_len, flags)) { + fprintf(f, "[%.*s]", (int) pid_len, pid); + n += pid_len + 2; + } else if (fake_pid && shall_print(fake_pid, fake_pid_len, flags)) { + fprintf(f, "[%.*s]", (int) fake_pid_len, fake_pid); + n += fake_pid_len + 2; + } + + if (flags & OUTPUT_COLOR) { + if (p <= LOG_ERR) { + color_on = ANSI_HIGHLIGHT_RED_ON; + color_off = ANSI_HIGHLIGHT_OFF; + } else if (p <= LOG_NOTICE) { + color_on = ANSI_HIGHLIGHT_ON; + color_off = ANSI_HIGHLIGHT_OFF; + } + } + + if (flags & OUTPUT_SHOW_ALL) + fprintf(f, ": %s%.*s%s\n", color_on, (int) message_len, message, color_off); + else if (!utf8_is_printable_n(message, message_len)) { + char bytes[FORMAT_BYTES_MAX]; + fprintf(f, ": [%s blob data]\n", format_bytes(bytes, sizeof(bytes), message_len)); + } else if ((flags & OUTPUT_FULL_WIDTH) || (message_len + n + 1 < n_columns)) + fprintf(f, ": %s%.*s%s\n", color_on, (int) message_len, message, color_off); + else if (n < n_columns && n_columns - n - 2 >= 3) { + char *e; + + e = ellipsize_mem(message, message_len, n_columns - n - 2, 90); + + if (!e) + fprintf(f, ": %s%.*s%s\n", color_on, (int) message_len, message, color_off); + else + fprintf(f, ": %s%s%s\n", color_on, e, color_off); + + free(e); + } else + fputs("\n", f); + + if (flags & OUTPUT_CATALOG) + print_catalog(f, j); + + return 0; +} + +static int output_verbose( + FILE *f, + sd_journal *j, + OutputMode mode, + unsigned n_columns, + OutputFlags flags) { + + const void *data; + size_t length; + char *cursor; + uint64_t realtime; + char ts[FORMAT_TIMESTAMP_MAX]; + int r; + + assert(f); + assert(j); + + sd_journal_set_data_threshold(j, 0); + + r = sd_journal_get_realtime_usec(j, &realtime); + if (r < 0) { + log_error("Failed to get realtime timestamp: %s", strerror(-r)); + return r; + } + + r = sd_journal_get_cursor(j, &cursor); + if (r < 0) { + log_error("Failed to get cursor: %s", strerror(-r)); + return r; + } + + fprintf(f, "%s [%s]\n", + format_timestamp(ts, sizeof(ts), realtime), + cursor); + + free(cursor); + + SD_JOURNAL_FOREACH_DATA(j, data, length) { + if (!shall_print(data, length, flags)) { + const char *c; + char bytes[FORMAT_BYTES_MAX]; + + c = memchr(data, '=', length); + if (!c) { + log_error("Invalid field."); + return -EINVAL; + } + + fprintf(f, "\t%.*s=[%s blob data]\n", + (int) (c - (const char*) data), + (const char*) data, + format_bytes(bytes, sizeof(bytes), length - (c - (const char *) data) - 1)); + } else + fprintf(f, "\t%.*s\n", (int) length, (const char*) data); + } + + if (flags & OUTPUT_CATALOG) + print_catalog(f, j); + + return 0; +} + +static int output_export( + FILE *f, + sd_journal *j, + OutputMode mode, + unsigned n_columns, + OutputFlags flags) { + + sd_id128_t boot_id; + char sid[33]; + int r; + usec_t realtime, monotonic; + char *cursor; + const void *data; + size_t length; + + assert(j); + + sd_journal_set_data_threshold(j, 0); + + r = sd_journal_get_realtime_usec(j, &realtime); + if (r < 0) { + log_error("Failed to get realtime timestamp: %s", strerror(-r)); + return r; + } + + r = sd_journal_get_monotonic_usec(j, &monotonic, &boot_id); + if (r < 0) { + log_error("Failed to get monotonic timestamp: %s", strerror(-r)); + return r; + } + + r = sd_journal_get_cursor(j, &cursor); + if (r < 0) { + log_error("Failed to get cursor: %s", strerror(-r)); + return r; + } + + fprintf(f, + "__CURSOR=%s\n" + "__REALTIME_TIMESTAMP=%llu\n" + "__MONOTONIC_TIMESTAMP=%llu\n" + "_BOOT_ID=%s\n", + cursor, + (unsigned long long) realtime, + (unsigned long long) monotonic, + sd_id128_to_string(boot_id, sid)); + + free(cursor); + + SD_JOURNAL_FOREACH_DATA(j, data, length) { + + /* We already printed the boot id, from the data in + * the header, hence let's suppress it here */ + if (length >= 9 && + memcmp(data, "_BOOT_ID=", 9) == 0) + continue; + + if (!utf8_is_printable_n(data, length)) { + const char *c; + uint64_t le64; + + c = memchr(data, '=', length); + if (!c) { + log_error("Invalid field."); + return -EINVAL; + } + + fwrite(data, c - (const char*) data, 1, f); + fputc('\n', f); + le64 = htole64(length - (c - (const char*) data) - 1); + fwrite(&le64, sizeof(le64), 1, f); + fwrite(c + 1, length - (c - (const char*) data) - 1, 1, f); + } else + fwrite(data, length, 1, f); + + fputc('\n', f); + } + + fputc('\n', f); + + return 0; +} + +void json_escape( + FILE *f, + const char* p, + size_t l, + OutputFlags flags) { + + assert(f); + assert(p); + + if (!(flags & OUTPUT_SHOW_ALL) && l >= JSON_THRESHOLD) + + fputs("null", f); + + else if (!utf8_is_printable_n(p, l)) { + bool not_first = false; + + fputs("[ ", f); + + while (l > 0) { + if (not_first) + fprintf(f, ", %u", (uint8_t) *p); + else { + not_first = true; + fprintf(f, "%u", (uint8_t) *p); + } + + p++; + l--; + } + + fputs(" ]", f); + } else { + fputc('\"', f); + + while (l > 0) { + if (*p == '"' || *p == '\\') { + fputc('\\', f); + fputc(*p, f); + } else if (*p < ' ') + fprintf(f, "\\u%04x", *p); + else + fputc(*p, f); + + p++; + l--; + } + + fputc('\"', f); + } +} + +static int output_json( + FILE *f, + sd_journal *j, + OutputMode mode, + unsigned n_columns, + OutputFlags flags) { + + uint64_t realtime, monotonic; + char *cursor, *k; + const void *data; + size_t length; + sd_id128_t boot_id; + char sid[33]; + int r; + Hashmap *h = NULL; + bool done, separator; + + assert(j); + + sd_journal_set_data_threshold(j, flags & OUTPUT_SHOW_ALL ? 0 : JSON_THRESHOLD); + + r = sd_journal_get_realtime_usec(j, &realtime); + if (r < 0) { + log_error("Failed to get realtime timestamp: %s", strerror(-r)); + return r; + } + + r = sd_journal_get_monotonic_usec(j, &monotonic, &boot_id); + if (r < 0) { + log_error("Failed to get monotonic timestamp: %s", strerror(-r)); + return r; + } + + r = sd_journal_get_cursor(j, &cursor); + if (r < 0) { + log_error("Failed to get cursor: %s", strerror(-r)); + return r; + } + + if (mode == OUTPUT_JSON_PRETTY) + fprintf(f, + "{\n" + "\t\"__CURSOR\" : \"%s\",\n" + "\t\"__REALTIME_TIMESTAMP\" : \"%llu\",\n" + "\t\"__MONOTONIC_TIMESTAMP\" : \"%llu\",\n" + "\t\"_BOOT_ID\" : \"%s\"", + cursor, + (unsigned long long) realtime, + (unsigned long long) monotonic, + sd_id128_to_string(boot_id, sid)); + else { + if (mode == OUTPUT_JSON_SSE) + fputs("data: ", f); + + fprintf(f, + "{ \"__CURSOR\" : \"%s\", " + "\"__REALTIME_TIMESTAMP\" : \"%llu\", " + "\"__MONOTONIC_TIMESTAMP\" : \"%llu\", " + "\"_BOOT_ID\" : \"%s\"", + cursor, + (unsigned long long) realtime, + (unsigned long long) monotonic, + sd_id128_to_string(boot_id, sid)); + } + free(cursor); + + h = hashmap_new(string_hash_func, string_compare_func); + if (!h) + return -ENOMEM; + + /* First round, iterate through the entry and count how often each field appears */ + SD_JOURNAL_FOREACH_DATA(j, data, length) { + const char *eq; + char *n; + unsigned u; + + if (length >= 9 && + memcmp(data, "_BOOT_ID=", 9) == 0) + continue; + + eq = memchr(data, '=', length); + if (!eq) + continue; + + n = strndup(data, eq - (const char*) data); + if (!n) { + r = -ENOMEM; + goto finish; + } + + u = PTR_TO_UINT(hashmap_get(h, n)); + if (u == 0) { + r = hashmap_put(h, n, UINT_TO_PTR(1)); + if (r < 0) { + free(n); + goto finish; + } + } else { + r = hashmap_update(h, n, UINT_TO_PTR(u + 1)); + free(n); + if (r < 0) + goto finish; + } + } + + separator = true; + do { + done = true; + + SD_JOURNAL_FOREACH_DATA(j, data, length) { + const char *eq; + char *kk, *n; + size_t m; + unsigned u; + + /* We already printed the boot id, from the data in + * the header, hence let's suppress it here */ + if (length >= 9 && + memcmp(data, "_BOOT_ID=", 9) == 0) + continue; + + eq = memchr(data, '=', length); + if (!eq) + continue; + + if (separator) { + if (mode == OUTPUT_JSON_PRETTY) + fputs(",\n\t", f); + else + fputs(", ", f); + } + + m = eq - (const char*) data; + + n = strndup(data, m); + if (!n) { + r = -ENOMEM; + goto finish; + } + + u = PTR_TO_UINT(hashmap_get2(h, n, (void**) &kk)); + if (u == 0) { + /* We already printed this, let's jump to the next */ + free(n); + separator = false; + + continue; + } else if (u == 1) { + /* Field only appears once, output it directly */ + + json_escape(f, data, m, flags); + fputs(" : ", f); + + json_escape(f, eq + 1, length - m - 1, flags); + + hashmap_remove(h, n); + free(kk); + free(n); + + separator = true; + + continue; + + } else { + /* Field appears multiple times, output it as array */ + json_escape(f, data, m, flags); + fputs(" : [ ", f); + json_escape(f, eq + 1, length - m - 1, flags); + + /* Iterate through the end of the list */ + + while (sd_journal_enumerate_data(j, &data, &length) > 0) { + if (length < m + 1) + continue; + + if (memcmp(data, n, m) != 0) + continue; + + if (((const char*) data)[m] != '=') + continue; + + fputs(", ", f); + json_escape(f, (const char*) data + m + 1, length - m - 1, flags); + } + + fputs(" ]", f); + + hashmap_remove(h, n); + free(kk); + free(n); + + /* Iterate data fields form the beginning */ + done = false; + separator = true; + + break; + } + } + + } while (!done); + + if (mode == OUTPUT_JSON_PRETTY) + fputs("\n}\n", f); + else if (mode == OUTPUT_JSON_SSE) + fputs("}\n\n", f); + else + fputs(" }\n", f); + + r = 0; + +finish: + while ((k = hashmap_steal_first_key(h))) + free(k); + + hashmap_free(h); + + return r; +} + +static int output_cat( + FILE *f, + sd_journal *j, + OutputMode mode, + unsigned n_columns, + OutputFlags flags) { + + const void *data; + size_t l; + int r; + + assert(j); + assert(f); + + sd_journal_set_data_threshold(j, 0); + + r = sd_journal_get_data(j, "MESSAGE", &data, &l); + if (r < 0) { + /* An entry without MESSAGE=? */ + if (r == -ENOENT) + return 0; + + log_error("Failed to get data: %s", strerror(-r)); + return r; + } + + assert(l >= 8); + + fwrite((const char*) data + 8, 1, l - 8, f); + fputc('\n', f); + + return 0; +} + +static int (*output_funcs[_OUTPUT_MODE_MAX])( + FILE *f, + sd_journal*j, + OutputMode mode, + unsigned n_columns, + OutputFlags flags) = { + + [OUTPUT_SHORT] = output_short, + [OUTPUT_SHORT_MONOTONIC] = output_short, + [OUTPUT_VERBOSE] = output_verbose, + [OUTPUT_EXPORT] = output_export, + [OUTPUT_JSON] = output_json, + [OUTPUT_JSON_PRETTY] = output_json, + [OUTPUT_JSON_SSE] = output_json, + [OUTPUT_CAT] = output_cat +}; + +int output_journal( + FILE *f, + sd_journal *j, + OutputMode mode, + unsigned n_columns, + OutputFlags flags) { + + int ret; + assert(mode >= 0); + assert(mode < _OUTPUT_MODE_MAX); + + if (n_columns <= 0) + n_columns = columns(); + + ret = output_funcs[mode](f, j, mode, n_columns, flags); + fflush(stdout); + return ret; +} + +int show_journal_by_unit( + FILE *f, + const char *unit, + OutputMode mode, + unsigned n_columns, + usec_t not_before, + unsigned how_many, + OutputFlags flags) { + + _cleanup_free_ char *m1 = NULL, *m2 = NULL, *m3 = NULL; + sd_journal *j = NULL; + int r; + unsigned line = 0; + bool need_seek = false; + int warn_cutoff = flags & OUTPUT_WARN_CUTOFF; + + assert(mode >= 0); + assert(mode < _OUTPUT_MODE_MAX); + assert(unit); + + if (!endswith(unit, ".service") && + !endswith(unit, ".socket") && + !endswith(unit, ".mount") && + !endswith(unit, ".swap")) + return 0; + + if (how_many <= 0) + return 0; + + if (asprintf(&m1, "_SYSTEMD_UNIT=%s", unit) < 0 || + asprintf(&m2, "COREDUMP_UNIT=%s", unit) < 0 || + asprintf(&m3, "UNIT=%s", unit) < 0) { + r = -ENOMEM; + goto finish; + } + + r = sd_journal_open(&j, SD_JOURNAL_LOCAL_ONLY|SD_JOURNAL_SYSTEM_ONLY); + if (r < 0) + goto finish; + + /* Look for messages from the service itself */ + r = sd_journal_add_match(j, m1, 0); + if (r < 0) + goto finish; + + /* Look for coredumps of the service */ + r = sd_journal_add_disjunction(j); + if (r < 0) + goto finish; + r = sd_journal_add_match(j, "MESSAGE_ID=fc2e22bc6ee647b6b90729ab34a250b1", 0); + if (r < 0) + goto finish; + r = sd_journal_add_match(j, m2, 0); + if (r < 0) + goto finish; + + /* Look for messages from PID 1 about this service */ + r = sd_journal_add_disjunction(j); + if (r < 0) + goto finish; + r = sd_journal_add_match(j, "_PID=1", 0); + if (r < 0) + goto finish; + r = sd_journal_add_match(j, m3, 0); + if (r < 0) + goto finish; + + /* Seek to end */ + r = sd_journal_seek_tail(j); + if (r < 0) + goto finish; + + r = sd_journal_previous_skip(j, how_many); + if (r < 0) + goto finish; + + for (;;) { + for (;;) { + usec_t usec; + + if (need_seek) { + r = sd_journal_next(j); + if (r < 0) + goto finish; + } + + if (r == 0) + break; + + need_seek = true; + + if (not_before > 0) { + r = sd_journal_get_monotonic_usec(j, &usec, NULL); + + /* -ESTALE is returned if the + timestamp is not from this boot */ + if (r == -ESTALE) + continue; + else if (r < 0) + goto finish; + + if (usec < not_before) + continue; + } + + line ++; + + r = output_journal(f, j, mode, n_columns, flags); + if (r < 0) + goto finish; + } + + if (warn_cutoff && line < how_many && not_before > 0) { + sd_id128_t boot_id; + usec_t cutoff; + + /* Check whether the cutoff line is too early */ + + r = sd_id128_get_boot(&boot_id); + if (r < 0) + goto finish; + + r = sd_journal_get_cutoff_monotonic_usec(j, boot_id, &cutoff, NULL); + if (r < 0) + goto finish; + + if (r > 0 && not_before < cutoff) + fprintf(f, "Warning: Journal has been rotated since unit was started. Log output is incomplete or unavailable.\n"); + + warn_cutoff = false; + } + + if (!(flags & OUTPUT_FOLLOW)) + break; + + r = sd_journal_wait(j, (usec_t) -1); + if (r < 0) + goto finish; + + } + +finish: + if (j) + sd_journal_close(j); + + return r; +} + +static const char *const output_mode_table[_OUTPUT_MODE_MAX] = { + [OUTPUT_SHORT] = "short", + [OUTPUT_SHORT_MONOTONIC] = "short-monotonic", + [OUTPUT_VERBOSE] = "verbose", + [OUTPUT_EXPORT] = "export", + [OUTPUT_JSON] = "json", + [OUTPUT_JSON_PRETTY] = "json-pretty", + [OUTPUT_JSON_SSE] = "json-sse", + [OUTPUT_CAT] = "cat" +}; + +DEFINE_STRING_TABLE_LOOKUP(output_mode, OutputMode); diff --git a/src/shared/logs-show.h b/src/shared/logs-show.h new file mode 100644 index 000000000..11cb41aab --- /dev/null +++ b/src/shared/logs-show.h @@ -0,0 +1,75 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + +#include + +#include + +#include "util.h" + +typedef enum OutputMode { + OUTPUT_SHORT, + OUTPUT_SHORT_MONOTONIC, + OUTPUT_VERBOSE, + OUTPUT_EXPORT, + OUTPUT_JSON, + OUTPUT_JSON_PRETTY, + OUTPUT_JSON_SSE, + OUTPUT_CAT, + _OUTPUT_MODE_MAX, + _OUTPUT_MODE_INVALID = -1 +} OutputMode; + +typedef enum OutputFlags { + OUTPUT_SHOW_ALL = 1 << 0, + OUTPUT_FOLLOW = 1 << 1, + OUTPUT_WARN_CUTOFF = 1 << 2, + OUTPUT_FULL_WIDTH = 1 << 3, + OUTPUT_COLOR = 1 << 4, + OUTPUT_CATALOG = 1 << 5 +} OutputFlags; + +int output_journal( + FILE *f, + sd_journal *j, + OutputMode mode, + unsigned n_columns, + OutputFlags flags); + +int show_journal_by_unit( + FILE *f, + const char *unit, + OutputMode mode, + unsigned n_columns, + usec_t not_before, + unsigned how_many, + OutputFlags flags); + +void json_escape( + FILE *f, + const char* p, + size_t l, + OutputFlags flags); + +const char* output_mode_to_string(OutputMode m); +OutputMode output_mode_from_string(const char *s); diff --git a/src/shared/macro.h b/src/shared/macro.h new file mode 100644 index 000000000..700171b83 --- /dev/null +++ b/src/shared/macro.h @@ -0,0 +1,249 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +#include +#include +#include +#include +#include + +#define _printf_attr_(a,b) __attribute__ ((format (printf, a, b))) +#define _sentinel_ __attribute__ ((sentinel)) +#define _noreturn_ __attribute__((noreturn)) +#define _unused_ __attribute__ ((unused)) +#define _destructor_ __attribute__ ((destructor)) +#define _pure_ __attribute__ ((pure)) +#define _const_ __attribute__ ((const)) +#define _deprecated_ __attribute__ ((deprecated)) +#define _packed_ __attribute__ ((packed)) +#define _malloc_ __attribute__ ((malloc)) +#define _weak_ __attribute__ ((weak)) +#define _likely_(x) (__builtin_expect(!!(x),1)) +#define _unlikely_(x) (__builtin_expect(!!(x),0)) +#define _public_ __attribute__ ((visibility("default"))) +#define _hidden_ __attribute__ ((visibility("hidden"))) +#define _weakref_(x) __attribute__((weakref(#x))) +#define _introspect_(x) __attribute__((section("introspect." x))) +#define _alignas_(x) __attribute__((aligned(__alignof(x)))) + +#define XSTRINGIFY(x) #x +#define STRINGIFY(x) XSTRINGIFY(x) + +/* Rounds up */ +#define ALIGN(l) ALIGN_TO((l), sizeof(void*)) +static inline size_t ALIGN_TO(size_t l, size_t ali) { + return ((l + ali - 1) & ~(ali - 1)); +} + +#define ELEMENTSOF(x) (sizeof(x)/sizeof((x)[0])) + +/* + * container_of - cast a member of a structure out to the containing structure + * @ptr: the pointer to the member. + * @type: the type of the container struct this is embedded in. + * @member: the name of the member within the struct. + * + */ +#define container_of(ptr, type, member) ({ \ + const typeof( ((type *)0)->member ) *__mptr = (ptr); \ + (type *)( (char *)__mptr - offsetof(type,member) );}) + +#ifndef MAX +#define MAX(a,b) \ + __extension__ ({ \ + typeof(a) _a = (a); \ + typeof(b) _b = (b); \ + _a > _b ? _a : _b; \ + }) +#endif + +#define MAX3(a,b,c) \ + MAX(MAX(a,b),c) + +#ifndef MIN +#define MIN(a,b) \ + __extension__ ({ \ + typeof(a) _a = (a); \ + typeof(b) _b = (b); \ + _a < _b ? _a : _b; \ + }) +#endif + +#define MIN3(a,b,c) \ + MIN(MIN(a,b),c) + +#define CLAMP(x, low, high) \ + __extension__ ({ \ + typeof(x) _x = (x); \ + typeof(low) _low = (low); \ + typeof(high) _high = (high); \ + ((_x > _high) ? _high : ((_x < _low) ? _low : _x)); \ + }) + +#define assert_se(expr) \ + do { \ + if (_unlikely_(!(expr))) \ + log_assert_failed(#expr, __FILE__, __LINE__, __PRETTY_FUNCTION__); \ + } while (false) \ + +/* We override the glibc assert() here. */ +#undef assert +#ifdef NDEBUG +#define assert(expr) do {} while(false) +#else +#define assert(expr) assert_se(expr) +#endif + +#define assert_not_reached(t) \ + do { \ + log_assert_failed_unreachable(t, __FILE__, __LINE__, __PRETTY_FUNCTION__); \ + } while (false) + +#if defined(static_assert) +#define assert_cc(expr) \ + do { \ + static_assert(expr, #expr); \ + } while (false) +#else +#define assert_cc(expr) \ + do { \ + switch (0) { \ + case 0: \ + case !!(expr): \ + ; \ + } \ + } while (false) +#endif + +#define PTR_TO_UINT(p) ((unsigned int) ((uintptr_t) (p))) +#define UINT_TO_PTR(u) ((void*) ((uintptr_t) (u))) + +#define PTR_TO_UINT32(p) ((uint32_t) ((uintptr_t) (p))) +#define UINT32_TO_PTR(u) ((void*) ((uintptr_t) (u))) + +#define PTR_TO_ULONG(p) ((unsigned long) ((uintptr_t) (p))) +#define ULONG_TO_PTR(u) ((void*) ((uintptr_t) (u))) + +#define PTR_TO_INT(p) ((int) ((intptr_t) (p))) +#define INT_TO_PTR(u) ((void*) ((intptr_t) (u))) + +#define TO_INT32(p) ((int32_t) ((intptr_t) (p))) +#define INT32_TO_PTR(u) ((void*) ((intptr_t) (u))) + +#define PTR_TO_LONG(p) ((long) ((intptr_t) (p))) +#define LONG_TO_PTR(u) ((void*) ((intptr_t) (u))) + +#define memzero(x,l) (memset((x), 0, (l))) +#define zero(x) (memzero(&(x), sizeof(x))) + +#define char_array_0(x) x[sizeof(x)-1] = 0; + +#define IOVEC_SET_STRING(i, s) \ + do { \ + struct iovec *_i = &(i); \ + char *_s = (char *)(s); \ + _i->iov_base = _s; \ + _i->iov_len = strlen(_s); \ + } while(false) + +static inline size_t IOVEC_TOTAL_SIZE(const struct iovec *i, unsigned n) { + unsigned j; + size_t r = 0; + + for (j = 0; j < n; j++) + r += i[j].iov_len; + + return r; +} + +static inline size_t IOVEC_INCREMENT(struct iovec *i, unsigned n, size_t k) { + unsigned j; + + for (j = 0; j < n; j++) { + size_t sub; + + if (_unlikely_(k <= 0)) + break; + + sub = MIN(i[j].iov_len, k); + i[j].iov_len -= sub; + i[j].iov_base = (uint8_t*) i[j].iov_base + sub; + k -= sub; + } + + return k; +} + +#define _cleanup_free_ __attribute__((cleanup(freep))) +#define _cleanup_fclose_ __attribute__((cleanup(fclosep))) +#define _cleanup_close_ __attribute__((cleanup(closep))) +#define _cleanup_closedir_ __attribute__((cleanup(closedirp))) +#define _cleanup_umask_ __attribute__((cleanup(umaskp))) +#define _cleanup_strv_free_ __attribute__((cleanup(strv_freep))) + +#define VA_FORMAT_ADVANCE(format, ap) \ +do { \ + int _argtypes[128]; \ + size_t _i, _k; \ + _k = parse_printf_format((format), ELEMENTSOF(_argtypes), _argtypes); \ + assert(_k < ELEMENTSOF(_argtypes)); \ + for (_i = 0; _i < _k; _i++) { \ + if (_argtypes[_i] & PA_FLAG_PTR) { \ + (void) va_arg(ap, void*); \ + continue; \ + } \ + \ + switch (_argtypes[_i]) { \ + case PA_INT: \ + case PA_INT|PA_FLAG_SHORT: \ + case PA_CHAR: \ + (void) va_arg(ap, int); \ + break; \ + case PA_INT|PA_FLAG_LONG: \ + (void) va_arg(ap, long int); \ + break; \ + case PA_INT|PA_FLAG_LONG_LONG: \ + (void) va_arg(ap, long long int); \ + break; \ + case PA_WCHAR: \ + (void) va_arg(ap, wchar_t); \ + break; \ + case PA_WSTRING: \ + case PA_STRING: \ + case PA_POINTER: \ + (void) va_arg(ap, void*); \ + break; \ + case PA_FLOAT: \ + case PA_DOUBLE: \ + (void) va_arg(ap, double); \ + break; \ + case PA_DOUBLE|PA_FLAG_LONG_DOUBLE: \ + (void) va_arg(ap, long double); \ + break; \ + default: \ + assert_not_reached("Unknown format string argument."); \ + } \ + } \ +} while(false) + +#include "log.h" diff --git a/src/shared/missing.h b/src/shared/missing.h new file mode 100644 index 000000000..c53579ff7 --- /dev/null +++ b/src/shared/missing.h @@ -0,0 +1,259 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +/* Missing glibc definitions to access certain kernel APIs */ + +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_AUDIT +#include +#endif + +#include "macro.h" + +#ifdef ARCH_MIPS +#include +#endif + +#ifndef RLIMIT_RTTIME +#define RLIMIT_RTTIME 15 +#endif + +#ifndef F_LINUX_SPECIFIC_BASE +#define F_LINUX_SPECIFIC_BASE 1024 +#endif + +#ifndef F_SETPIPE_SZ +#define F_SETPIPE_SZ (F_LINUX_SPECIFIC_BASE + 7) +#endif + +#ifndef F_GETPIPE_SZ +#define F_GETPIPE_SZ (F_LINUX_SPECIFIC_BASE + 8) +#endif + +#ifndef IP_FREEBIND +#define IP_FREEBIND 15 +#endif + +#ifndef OOM_SCORE_ADJ_MIN +#define OOM_SCORE_ADJ_MIN (-1000) +#endif + +#ifndef OOM_SCORE_ADJ_MAX +#define OOM_SCORE_ADJ_MAX 1000 +#endif + +#ifndef AUDIT_SERVICE_START +#define AUDIT_SERVICE_START 1130 /* Service (daemon) start */ +#endif + +#ifndef AUDIT_SERVICE_STOP +#define AUDIT_SERVICE_STOP 1131 /* Service (daemon) stop */ +#endif + +#ifndef TIOCVHANGUP +#define TIOCVHANGUP 0x5437 +#endif + +#ifndef IP_TRANSPARENT +#define IP_TRANSPARENT 19 +#endif + +#if !HAVE_DECL_PIVOT_ROOT +static inline int pivot_root(const char *new_root, const char *put_old) { + return syscall(SYS_pivot_root, new_root, put_old); +} +#endif + +#ifdef __x86_64__ +# ifndef __NR_fanotify_init +# define __NR_fanotify_init 300 +# endif +# ifndef __NR_fanotify_mark +# define __NR_fanotify_mark 301 +# endif +#elif defined _MIPS_SIM +# if _MIPS_SIM == _MIPS_SIM_ABI32 +# ifndef __NR_fanotify_init +# define __NR_fanotify_init 4336 +# endif +# ifndef __NR_fanotify_mark +# define __NR_fanotify_mark 4337 +# endif +# elif _MIPS_SIM == _MIPS_SIM_NABI32 +# ifndef __NR_fanotify_init +# define __NR_fanotify_init 6300 +# endif +# ifndef __NR_fanotify_mark +# define __NR_fanotify_mark 6301 +# endif +# elif _MIPS_SIM == _MIPS_SIM_ABI64 +# ifndef __NR_fanotify_init +# define __NR_fanotify_init 5295 +# endif +# ifndef __NR_fanotify_mark +# define __NR_fanotify_mark 5296 +# endif +# endif +#else +# ifndef __NR_fanotify_init +# define __NR_fanotify_init 338 +# endif +# ifndef __NR_fanotify_mark +# define __NR_fanotify_mark 339 +# endif +#endif + +#ifndef HAVE_FANOTIFY_INIT +static inline int fanotify_init(unsigned int flags, unsigned int event_f_flags) { + return syscall(__NR_fanotify_init, flags, event_f_flags); +} +#endif + +#ifndef HAVE_FANOTIFY_MARK +static inline int fanotify_mark(int fanotify_fd, unsigned int flags, uint64_t mask, + int dfd, const char *pathname) { +#if defined _MIPS_SIM && _MIPS_SIM == _MIPS_SIM_ABI32 || defined __powerpc__ && !defined __powerpc64__ + union { + uint64_t _64; + uint32_t _32[2]; + } _mask; + _mask._64 = mask; + + return syscall(__NR_fanotify_mark, fanotify_fd, flags, + _mask._32[0], _mask._32[1], dfd, pathname); +#else + return syscall(__NR_fanotify_mark, fanotify_fd, flags, mask, dfd, pathname); +#endif +} +#endif + +#ifndef BTRFS_IOCTL_MAGIC +#define BTRFS_IOCTL_MAGIC 0x94 +#endif + +#ifndef BTRFS_PATH_NAME_MAX +#define BTRFS_PATH_NAME_MAX 4087 +#endif + +struct btrfs_ioctl_vol_args { + int64_t fd; + char name[BTRFS_PATH_NAME_MAX + 1]; +}; + +#ifndef BTRFS_IOC_DEFRAG +#define BTRFS_IOC_DEFRAG _IOW(BTRFS_IOCTL_MAGIC, 2, struct btrfs_ioctl_vol_args) +#endif + +#ifndef BTRFS_SUPER_MAGIC +#define BTRFS_SUPER_MAGIC 0x9123683E +#endif + +#ifndef MS_MOVE +#define MS_MOVE 8192 +#endif + +#ifndef MS_PRIVATE +#define MS_PRIVATE (1 << 18) +#endif + +#if !HAVE_DECL_GETTID +static inline pid_t gettid(void) { + return (pid_t) syscall(SYS_gettid); +} +#endif + +#ifndef SCM_SECURITY +#define SCM_SECURITY 0x03 +#endif + +#ifndef MS_STRICTATIME +#define MS_STRICTATIME (1<<24) +#endif + +#ifndef PR_SET_NO_NEW_PRIVS +#define PR_SET_NO_NEW_PRIVS 38 +#endif + +#ifndef PR_SET_CHILD_SUBREAPER +#define PR_SET_CHILD_SUBREAPER 36 +#endif + +#ifndef MAX_HANDLE_SZ +#define MAX_HANDLE_SZ 128 +#endif + +#if defined __x86_64__ +# ifndef __NR_name_to_handle_at +# define __NR_name_to_handle_at 303 +# endif +#elif defined __i386__ +# ifndef __NR_name_to_handle_at +# define __NR_name_to_handle_at 341 +# endif +#elif defined __arm__ +# ifndef __NR_name_to_handle_at +# define __NR_name_to_handle_at 370 +# endif +#elif defined __powerpc__ +# ifndef __NR_name_to_handle_at +# define __NR_name_to_handle_at 345 +# endif +#else +# ifndef __NR_name_to_handle_at +# error __NR_name_to_handle_at is not defined +# endif +#endif + +#if !HAVE_DECL_NAME_TO_HANDLE_AT +struct file_handle { + unsigned int handle_bytes; + int handle_type; + unsigned char f_handle[0]; +}; + +static inline int name_to_handle_at(int fd, const char *name, struct file_handle *handle, int *mnt_id, int flags) { + return syscall(__NR_name_to_handle_at, fd, name, handle, mnt_id, flags); +} +#endif + +#ifndef HAVE_SECURE_GETENV +# ifdef HAVE___SECURE_GETENV +# define secure_getenv __secure_getenv +# else +# error neither secure_getenv nor __secure_getenv are available +# endif +#endif + +#ifndef CIFS_MAGIC_NUMBER +#define CIFS_MAGIC_NUMBER 0xFF534D42 +#endif + +#ifndef TFD_TIMER_CANCEL_ON_SET +#define TFD_TIMER_CANCEL_ON_SET (1 << 1) +#endif diff --git a/src/shared/mkdir.c b/src/shared/mkdir.c new file mode 100644 index 000000000..0e51b64f6 --- /dev/null +++ b/src/shared/mkdir.c @@ -0,0 +1,147 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include +#include +#include + +#include "mkdir.h" +#include "label.h" +#include "util.h" + +int mkdir_label(const char *path, mode_t mode) { + return label_mkdir(path, mode, true); +} + +static int makedir_safe(const char *path, mode_t mode, uid_t uid, gid_t gid, bool apply) { + struct stat st; + + if (label_mkdir(path, mode, apply) >= 0) + if (chmod_and_chown(path, mode, uid, gid) < 0) + return -errno; + + if (lstat(path, &st) < 0) + return -errno; + + if ((st.st_mode & 0777) != mode || + st.st_uid != uid || + st.st_gid != gid || + !S_ISDIR(st.st_mode)) { + errno = EEXIST; + return -errno; + } + + return 0; +} + +int mkdir_safe(const char *path, mode_t mode, uid_t uid, gid_t gid) { + return makedir_safe(path, mode, uid, gid, false); +} + +int mkdir_safe_label(const char *path, mode_t mode, uid_t uid, gid_t gid) { + return makedir_safe(path, mode, uid, gid, true); +} + +static int makedir_parents(const char *path, mode_t mode, bool apply) { + struct stat st; + const char *p, *e; + + assert(path); + + /* return immediately if directory exists */ + e = strrchr(path, '/'); + if (!e) + return -EINVAL; + p = strndupa(path, e - path); + if (stat(p, &st) >= 0) { + if ((st.st_mode & S_IFMT) == S_IFDIR) + return 0; + else + return -ENOTDIR; + } + + /* create every parent directory in the path, except the last component */ + p = path + strspn(path, "/"); + for (;;) { + int r; + char *t; + + e = p + strcspn(p, "/"); + p = e + strspn(e, "/"); + + /* Is this the last component? If so, then we're + * done */ + if (*p == 0) + return 0; + + t = strndup(path, e - path); + if (!t) + return -ENOMEM; + + r = label_mkdir(t, mode, apply); + free(t); + + if (r < 0 && errno != EEXIST) + return -errno; + } +} + +int mkdir_parents(const char *path, mode_t mode) { + return makedir_parents(path, mode, false); +} + +int mkdir_parents_label(const char *path, mode_t mode) { + return makedir_parents(path, mode, true); +} + +static int is_dir(const char* path) { + struct stat st; + if (stat(path, &st) < 0) + return -errno; + return S_ISDIR(st.st_mode); +} + +static int makedir_p(const char *path, mode_t mode, bool apply) { + int r; + + /* Like mkdir -p */ + + r = makedir_parents(path, mode, apply); + if (r < 0) + return r; + + r = label_mkdir(path, mode, apply); + if (r < 0 && (errno != EEXIST || is_dir(path) <= 0)) + return -errno; + + return 0; +} + +int mkdir_p(const char *path, mode_t mode) { + return makedir_p(path, mode, false); +} + +int mkdir_p_label(const char *path, mode_t mode) { + return makedir_p(path, mode, true); +} diff --git a/src/shared/mkdir.h b/src/shared/mkdir.h new file mode 100644 index 000000000..ce1c35e9b --- /dev/null +++ b/src/shared/mkdir.h @@ -0,0 +1,32 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foomkdirhfoo +#define foomkdirhfoo + +/*** + 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 . +***/ + +int mkdir_label(const char *path, mode_t mode); +int mkdir_safe(const char *path, mode_t mode, uid_t uid, gid_t gid); +int mkdir_safe_label(const char *path, mode_t mode, uid_t uid, gid_t gid); +int mkdir_parents(const char *path, mode_t mode); +int mkdir_parents_label(const char *path, mode_t mode); +int mkdir_p(const char *path, mode_t mode); +int mkdir_p_label(const char *path, mode_t mode); +#endif diff --git a/src/shared/pager.c b/src/shared/pager.c new file mode 100644 index 000000000..488a12c76 --- /dev/null +++ b/src/shared/pager.c @@ -0,0 +1,143 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include +#include +#include + +#include "pager.h" +#include "util.h" +#include "macro.h" + +static pid_t pager_pid = 0; + +_noreturn_ static void pager_fallback(void) { + ssize_t n; + do { + n = splice(STDIN_FILENO, NULL, STDOUT_FILENO, NULL, 64*1024, 0); + } while (n > 0); + if (n < 0) { + log_error("Internal pager failed: %m"); + _exit(EXIT_FAILURE); + } + _exit(EXIT_SUCCESS); +} + +int pager_open(void) { + int fd[2]; + const char *pager; + pid_t parent_pid; + int r; + + if (pager_pid > 0) + return 1; + + if ((pager = getenv("SYSTEMD_PAGER")) || (pager = getenv("PAGER"))) + if (!*pager || streq(pager, "cat")) + return 0; + + if (!on_tty()) + return 0; + + /* Determine and cache number of columns before we spawn the + * pager so that we get the value from the actual tty */ + columns(); + + if (pipe(fd) < 0) { + log_error("Failed to create pager pipe: %m"); + return -errno; + } + + parent_pid = getpid(); + + pager_pid = fork(); + if (pager_pid < 0) { + r = -errno; + log_error("Failed to fork pager: %m"); + close_pipe(fd); + return r; + } + + /* In the child start the pager */ + if (pager_pid == 0) { + + dup2(fd[0], STDIN_FILENO); + close_pipe(fd); + + setenv("LESS", "FRSX", 0); + + /* 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); + } + + /* Debian's alternatives command for pagers is + * called 'pager'. Note that we do not call + * sensible-pagers here, since that is just a + * shell script that implements a logic that + * is similar to this one anyway, but is + * Debian-specific. */ + execlp("pager", "pager", NULL); + + execlp("less", "less", NULL); + execlp("more", "more", NULL); + + pager_fallback(); + /* not reached */ + } + + /* Return in the parent */ + if (dup2(fd[1], STDOUT_FILENO) < 0) { + log_error("Failed to duplicate pager pipe: %m"); + return -errno; + } + + close_pipe(fd); + return 1; +} + +void pager_close(void) { + + if (pager_pid <= 0) + return; + + /* Inform pager that we are done */ + fclose(stdout); + kill(pager_pid, SIGCONT); + wait_for_terminate(pager_pid, NULL); + pager_pid = 0; +} + +bool pager_have(void) { + return pager_pid > 0; +} diff --git a/src/shared/pager.h b/src/shared/pager.h new file mode 100644 index 000000000..5e7b5ab91 --- /dev/null +++ b/src/shared/pager.h @@ -0,0 +1,28 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +#include + +int pager_open(void); +void pager_close(void); +bool pager_have(void); diff --git a/src/shared/path-lookup.c b/src/shared/path-lookup.c new file mode 100644 index 000000000..6e5529e0c --- /dev/null +++ b/src/shared/path-lookup.c @@ -0,0 +1,430 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include +#include +#include + +#include "util.h" +#include "mkdir.h" +#include "strv.h" +#include "path-util.h" +#include "path-lookup.h" + +static const char* const systemd_running_as_table[_SYSTEMD_RUNNING_AS_MAX] = { + [SYSTEMD_SYSTEM] = "system", + [SYSTEMD_USER] = "user" +}; + +DEFINE_STRING_TABLE_LOOKUP(systemd_running_as, SystemdRunningAs); + +int user_config_home(char **config_home) { + const char *e; + + e = getenv("XDG_CONFIG_HOME"); + if (e) { + if (asprintf(config_home, "%s/systemd/user", e) < 0) + return -ENOMEM; + + return 1; + } else { + const char *home; + + home = getenv("HOME"); + if (home) { + if (asprintf(config_home, "%s/.config/systemd/user", home) < 0) + return -ENOMEM; + + return 1; + } + } + + return 0; +} + +static char** user_dirs( + const char *generator, + const char *generator_early, + const char *generator_late) { + + const char * const config_unit_paths[] = { + USER_CONFIG_UNIT_PATH, + "/etc/systemd/user", + "/run/systemd/user", + NULL + }; + + const char * const data_unit_paths[] = { + "/usr/local/lib/systemd/user", + "/usr/local/share/systemd/user", + USER_DATA_UNIT_PATH, + "/usr/lib/systemd/user", + "/usr/share/systemd/user", + NULL + }; + + const char *home, *e; + char *config_home = NULL, *data_home = NULL; + char **config_dirs = NULL, **data_dirs = NULL; + char **r = NULL, **t; + + /* Implement the mechanisms defined in + * + * http://standards.freedesktop.org/basedir-spec/basedir-spec-0.6.html + * + * We look in both the config and the data dirs because we + * want to encourage that distributors ship their unit files + * as data, and allow overriding as configuration. + */ + + if (user_config_home(&config_home) < 0) + goto fail; + + home = getenv("HOME"); + + e = getenv("XDG_CONFIG_DIRS"); + if (e) { + config_dirs = strv_split(e, ":"); + if (!config_dirs) + goto fail; + } + + /* We don't treat /etc/xdg/systemd here as the spec + * suggests because we assume that that is a link to + * /etc/systemd/ anyway. */ + + e = getenv("XDG_DATA_HOME"); + if (e) { + if (asprintf(&data_home, "%s/systemd/user", e) < 0) + goto fail; + + } else if (home) { + if (asprintf(&data_home, "%s/.local/share/systemd/user", home) < 0) + goto fail; + + /* There is really no need for two unit dirs in $HOME, + * except to be fully compliant with the XDG spec. We + * now try to link the two dirs, so that we can + * minimize disk seeks a little. Further down we'll + * then filter out this link, if it is actually is + * one. */ + + mkdir_parents_label(data_home, 0777); + (void) symlink("../../../.config/systemd/user", data_home); + } + + e = getenv("XDG_DATA_DIRS"); + if (e) + data_dirs = strv_split(e, ":"); + else + data_dirs = strv_new("/usr/local/share", + "/usr/share", + NULL); + if (!data_dirs) + goto fail; + + /* Now merge everything we found. */ + if (generator_early) { + t = strv_append(r, generator_early); + if (!t) + goto fail; + strv_free(r); + r = t; + } + + if (config_home) { + t = strv_append(r, config_home); + if (!t) + goto fail; + strv_free(r); + r = t; + } + + if (!strv_isempty(config_dirs)) { + t = strv_merge_concat(r, config_dirs, "/systemd/user"); + if (!t) + goto finish; + strv_free(r); + r = t; + } + + t = strv_merge(r, (char**) config_unit_paths); + if (!t) + goto fail; + strv_free(r); + r = t; + + if (generator) { + t = strv_append(r, generator); + if (!t) + goto fail; + strv_free(r); + r = t; + } + + if (data_home) { + t = strv_append(r, data_home); + if (!t) + goto fail; + strv_free(r); + r = t; + } + + if (!strv_isempty(data_dirs)) { + t = strv_merge_concat(r, data_dirs, "/systemd/user"); + if (!t) + goto fail; + strv_free(r); + r = t; + } + + t = strv_merge(r, (char**) data_unit_paths); + if (!t) + goto fail; + strv_free(r); + r = t; + + if (generator_late) { + t = strv_append(r, generator_late); + if (!t) + goto fail; + strv_free(r); + r = t; + } + + if (!path_strv_make_absolute_cwd(r)) + goto fail; + +finish: + free(config_home); + strv_free(config_dirs); + free(data_home); + strv_free(data_dirs); + + return r; + +fail: + strv_free(r); + r = NULL; + goto finish; +} + +int lookup_paths_init( + LookupPaths *p, + SystemdRunningAs running_as, + bool personal, + const char *generator, + const char *generator_early, + const char *generator_late) { + + const char *e; + char *t; + + assert(p); + + /* First priority is whatever has been passed to us via env + * vars */ + e = getenv("SYSTEMD_UNIT_PATH"); + if (e) { + p->unit_path = path_split_and_make_absolute(e); + if (!p->unit_path) + return -ENOMEM; + } else + p->unit_path = NULL; + + if (strv_isempty(p->unit_path)) { + /* Nothing is set, so let's figure something out. */ + strv_free(p->unit_path); + + /* For the user units we include share/ in the search + * path in order to comply with the XDG basedir + * spec. For the system stuff we avoid such + * nonsense. OTOH we include /lib in the search path + * for the system stuff but avoid it for user + * stuff. */ + + if (running_as == SYSTEMD_USER) { + + if (personal) + p->unit_path = user_dirs(generator, generator_early, generator_late); + else + p->unit_path = strv_new( + /* If you modify this you also want to modify + * systemduserunitpath= in systemd.pc.in, and + * the arrays in user_dirs() above! */ + STRV_IFNOTNULL(generator_early), + USER_CONFIG_UNIT_PATH, + "/etc/systemd/user", + "/run/systemd/user", + STRV_IFNOTNULL(generator), + "/usr/local/lib/systemd/user", + "/usr/local/share/systemd/user", + USER_DATA_UNIT_PATH, + "/usr/lib/systemd/user", + "/usr/share/systemd/user", + STRV_IFNOTNULL(generator_late), + NULL); + + if (!p->unit_path) + return -ENOMEM; + + } else { + p->unit_path = strv_new( + /* If you modify this you also want to modify + * systemdsystemunitpath= in systemd.pc.in! */ + STRV_IFNOTNULL(generator_early), + SYSTEM_CONFIG_UNIT_PATH, + "/etc/systemd/system", + "/run/systemd/system", + STRV_IFNOTNULL(generator), + "/usr/local/lib/systemd/system", + SYSTEM_DATA_UNIT_PATH, + "/usr/lib/systemd/system", +#ifdef HAVE_SPLIT_USR + "/lib/systemd/system", +#endif + STRV_IFNOTNULL(generator_late), + NULL); + + if (!p->unit_path) + return -ENOMEM; + } + } + + if (!path_strv_canonicalize(p->unit_path)) + return -ENOMEM; + + strv_uniq(p->unit_path); + path_strv_remove_empty(p->unit_path); + + if (!strv_isempty(p->unit_path)) { + + t = strv_join(p->unit_path, "\n\t"); + if (!t) + return -ENOMEM; + log_debug("Looking for unit files in:\n\t%s", t); + free(t); + } else { + log_debug("Ignoring unit files."); + strv_free(p->unit_path); + p->unit_path = NULL; + } + + if (running_as == SYSTEMD_SYSTEM) { +#ifdef HAVE_SYSV_COMPAT + /* /etc/init.d/ compatibility does not matter to users */ + + e = getenv("SYSTEMD_SYSVINIT_PATH"); + if (e) { + p->sysvinit_path = path_split_and_make_absolute(e); + if (!p->sysvinit_path) + return -ENOMEM; + } else + p->sysvinit_path = NULL; + + if (strv_isempty(p->sysvinit_path)) { + strv_free(p->sysvinit_path); + + p->sysvinit_path = strv_new( + SYSTEM_SYSVINIT_PATH, /* /etc/init.d/ */ + NULL); + if (!p->sysvinit_path) + return -ENOMEM; + } + + e = getenv("SYSTEMD_SYSVRCND_PATH"); + if (e) { + p->sysvrcnd_path = path_split_and_make_absolute(e); + if (!p->sysvrcnd_path) + return -ENOMEM; + } else + p->sysvrcnd_path = NULL; + + if (strv_isempty(p->sysvrcnd_path)) { + strv_free(p->sysvrcnd_path); + + p->sysvrcnd_path = strv_new( + SYSTEM_SYSVRCND_PATH, /* /etc/rcN.d/ */ + NULL); + if (!p->sysvrcnd_path) + return -ENOMEM; + } + + if (!path_strv_canonicalize(p->sysvinit_path)) + return -ENOMEM; + + if (!path_strv_canonicalize(p->sysvrcnd_path)) + return -ENOMEM; + + strv_uniq(p->sysvinit_path); + strv_uniq(p->sysvrcnd_path); + path_strv_remove_empty(p->sysvinit_path); + path_strv_remove_empty(p->sysvrcnd_path); + + if (!strv_isempty(p->sysvinit_path)) { + + t = strv_join(p->sysvinit_path, "\n\t"); + if (!t) + return -ENOMEM; + log_debug("Looking for SysV init scripts in:\n\t%s", t); + free(t); + } else { + log_debug("Ignoring SysV init scripts."); + strv_free(p->sysvinit_path); + p->sysvinit_path = NULL; + } + + if (!strv_isempty(p->sysvrcnd_path)) { + + t = strv_join(p->sysvrcnd_path, "\n\t"); + if (!t) + return -ENOMEM; + + log_debug("Looking for SysV rcN.d links in:\n\t%s", t); + free(t); + } else { + log_debug("Ignoring SysV rcN.d links."); + strv_free(p->sysvrcnd_path); + p->sysvrcnd_path = NULL; + } +#else + log_debug("Disabled SysV init scripts and rcN.d links support"); +#endif + } + + return 0; +} + +void lookup_paths_free(LookupPaths *p) { + assert(p); + + strv_free(p->unit_path); + p->unit_path = NULL; + +#ifdef HAVE_SYSV_COMPAT + strv_free(p->sysvinit_path); + strv_free(p->sysvrcnd_path); + p->sysvinit_path = p->sysvrcnd_path = NULL; +#endif +} diff --git a/src/shared/path-lookup.h b/src/shared/path-lookup.h new file mode 100644 index 000000000..baef62228 --- /dev/null +++ b/src/shared/path-lookup.h @@ -0,0 +1,45 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +typedef struct LookupPaths { + char **unit_path; +#ifdef HAVE_SYSV_COMPAT + char **sysvinit_path; + char **sysvrcnd_path; +#endif +} LookupPaths; + +typedef enum SystemdRunningAs { + SYSTEMD_SYSTEM, + SYSTEMD_USER, + _SYSTEMD_RUNNING_AS_MAX, + _SYSTEMD_RUNNING_AS_INVALID = -1 +} SystemdRunningAs; + +const char* systemd_running_as_to_string(SystemdRunningAs i); +SystemdRunningAs systemd_running_as_from_string(const char *s); + +int user_config_home(char **config_home); + +int lookup_paths_init(LookupPaths *p, SystemdRunningAs running_as, bool personal, const char *generator, const char *generator_early, const char *generator_late); +void lookup_paths_free(LookupPaths *p); diff --git a/src/shared/path-util.c b/src/shared/path-util.c new file mode 100644 index 000000000..dd12d3d63 --- /dev/null +++ b/src/shared/path-util.c @@ -0,0 +1,420 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010-2012 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "macro.h" +#include "util.h" +#include "log.h" +#include "strv.h" +#include "path-util.h" +#include "missing.h" + +bool path_is_absolute(const char *p) { + return p[0] == '/'; +} + +bool is_path(const char *p) { + return !!strchr(p, '/'); +} + +char *path_get_file_name(const char *p) { + char *r; + + assert(p); + + if ((r = strrchr(p, '/'))) + return r + 1; + + return (char*) p; +} + +int path_get_parent(const char *path, char **_r) { + const char *e, *a = NULL, *b = NULL, *p; + char *r; + bool slash = false; + + assert(path); + assert(_r); + + if (!*path) + return -EINVAL; + + for (e = path; *e; e++) { + + if (!slash && *e == '/') { + a = b; + b = e; + slash = true; + } else if (slash && *e != '/') + slash = false; + } + + if (*(e-1) == '/') + p = a; + else + p = b; + + if (!p) + return -EINVAL; + + if (p == path) + r = strdup("/"); + else + r = strndup(path, p-path); + + if (!r) + return -ENOMEM; + + *_r = r; + return 0; +} + +char **path_split_and_make_absolute(const char *p) { + char **l; + assert(p); + + if (!(l = strv_split(p, ":"))) + return NULL; + + if (!path_strv_make_absolute_cwd(l)) { + strv_free(l); + return NULL; + } + + return l; +} + +char *path_make_absolute(const char *p, const char *prefix) { + assert(p); + + /* Makes every item in the list an absolute path by prepending + * the prefix, if specified and necessary */ + + if (path_is_absolute(p) || !prefix) + return strdup(p); + + return strjoin(prefix, "/", p, NULL); +} + +char *path_make_absolute_cwd(const char *p) { + char *cwd, *r; + + assert(p); + + /* Similar to path_make_absolute(), but prefixes with the + * current working directory. */ + + if (path_is_absolute(p)) + return strdup(p); + + if (!(cwd = get_current_dir_name())) + return NULL; + + r = path_make_absolute(p, cwd); + free(cwd); + + return r; +} + +char **path_strv_make_absolute_cwd(char **l) { + char **s; + + /* Goes through every item in the string list and makes it + * absolute. This works in place and won't rollback any + * changes on failure. */ + + STRV_FOREACH(s, l) { + char *t; + + if (!(t = path_make_absolute_cwd(*s))) + return NULL; + + free(*s); + *s = t; + } + + return l; +} + +char **path_strv_canonicalize(char **l) { + char **s; + unsigned k = 0; + bool enomem = false; + + if (strv_isempty(l)) + return l; + + /* Goes through every item in the string list and canonicalize + * the path. This works in place and won't rollback any + * changes on failure. */ + + STRV_FOREACH(s, l) { + char *t, *u; + + t = path_make_absolute_cwd(*s); + free(*s); + *s = NULL; + + if (!t) { + enomem = true; + continue; + } + + errno = 0; + u = canonicalize_file_name(t); + free(t); + + if (!u) { + if (errno == ENOMEM || !errno) + enomem = true; + + continue; + } + + l[k++] = u; + } + + l[k] = NULL; + + if (enomem) + return NULL; + + return l; +} + +char **path_strv_remove_empty(char **l) { + char **f, **t; + + if (!l) + return NULL; + + for (f = t = l; *f; f++) { + + if (dir_is_empty(*f) > 0) { + free(*f); + continue; + } + + *(t++) = *f; + } + + *t = NULL; + return l; +} + +char *path_kill_slashes(char *path) { + char *f, *t; + bool slash = false; + + /* Removes redundant inner and trailing slashes. Modifies the + * passed string in-place. + * + * ///foo///bar/ becomes /foo/bar + */ + + for (f = path, t = path; *f; f++) { + + if (*f == '/') { + slash = true; + continue; + } + + if (slash) { + slash = false; + *(t++) = '/'; + } + + *(t++) = *f; + } + + /* Special rule, if we are talking of the root directory, a + trailing slash is good */ + + if (t == path && slash) + *(t++) = '/'; + + *t = 0; + return path; +} + +char* path_startswith(const char *path, const char *prefix) { + assert(path); + assert(prefix); + + if ((path[0] == '/') != (prefix[0] == '/')) + return NULL; + + for (;;) { + size_t a, b; + + path += strspn(path, "/"); + prefix += strspn(prefix, "/"); + + if (*prefix == 0) + return (char*) path; + + if (*path == 0) + return NULL; + + a = strcspn(path, "/"); + b = strcspn(prefix, "/"); + + if (a != b) + return NULL; + + if (memcmp(path, prefix, a) != 0) + return NULL; + + path += a; + prefix += b; + } +} + +bool path_equal(const char *a, const char *b) { + assert(a); + assert(b); + + if ((a[0] == '/') != (b[0] == '/')) + return false; + + for (;;) { + size_t j, k; + + a += strspn(a, "/"); + b += strspn(b, "/"); + + if (*a == 0 && *b == 0) + return true; + + if (*a == 0 || *b == 0) + return false; + + j = strcspn(a, "/"); + k = strcspn(b, "/"); + + if (j != k) + return false; + + if (memcmp(a, b, j) != 0) + return false; + + a += j; + b += k; + } +} + +int path_is_mount_point(const char *t, bool allow_symlink) { + char *parent; + int r; + struct file_handle *h; + int mount_id, mount_id_parent; + struct stat a, b; + + /* We are not actually interested in the file handles, but + * name_to_handle_at() also passes us the mount ID, hence use + * it but throw the handle away */ + + if (path_equal(t, "/")) + return 1; + + h = alloca(MAX_HANDLE_SZ); + h->handle_bytes = MAX_HANDLE_SZ; + + r = name_to_handle_at(AT_FDCWD, t, h, &mount_id, allow_symlink ? AT_SYMLINK_FOLLOW : 0); + if (r < 0) { + if (errno == ENOSYS || errno == ENOTSUP) + /* This kernel or file system does not support + * name_to_handle_at(), hence fallback to the + * traditional stat() logic */ + goto fallback; + + if (errno == ENOENT) + return 0; + + return -errno; + } + + r = path_get_parent(t, &parent); + if (r < 0) + return r; + + h->handle_bytes = MAX_HANDLE_SZ; + r = name_to_handle_at(AT_FDCWD, parent, h, &mount_id_parent, 0); + free(parent); + + if (r < 0) { + /* The parent can't do name_to_handle_at() but the + * directory we are interested in can? If so, it must + * be a mount point */ + if (errno == ENOTSUP) + return 1; + + return -errno; + } + + return mount_id != mount_id_parent; + +fallback: + if (allow_symlink) + r = stat(t, &a); + else + r = lstat(t, &a); + + if (r < 0) { + if (errno == ENOENT) + return 0; + + return -errno; + } + + r = path_get_parent(t, &parent); + if (r < 0) + return r; + + r = lstat(parent, &b); + free(parent); + + if (r < 0) + return -errno; + + return a.st_dev != b.st_dev; +} + +int path_is_read_only_fs(const char *path) { + struct statvfs st; + + assert(path); + + if (statvfs(path, &st) < 0) + return -errno; + + return !!(st.f_flag & ST_RDONLY); +} diff --git a/src/shared/path-util.h b/src/shared/path-util.h new file mode 100644 index 000000000..e81821a28 --- /dev/null +++ b/src/shared/path-util.h @@ -0,0 +1,45 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foopathutilhfoo +#define foopathutilhfoo + +/*** + This file is part of systemd. + + Copyright 2010-2012 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 . +***/ + +#include "stdbool.h" + +bool is_path(const char *p); +char **path_split_and_make_absolute(const char *p); +char *path_get_file_name(const char *p); +int path_get_parent(const char *path, char **parent); +bool path_is_absolute(const char *p); +char *path_make_absolute(const char *p, const char *prefix); +char *path_make_absolute_cwd(const char *p); +char *path_kill_slashes(char *path); +char *path_startswith(const char *path, const char *prefix); +bool path_equal(const char *a, const char *b); + +char **path_strv_make_absolute_cwd(char **l); +char **path_strv_canonicalize(char **l); +char **path_strv_remove_empty(char **l); + +int path_is_mount_point(const char *path, bool allow_symlink); +int path_is_read_only_fs(const char *path); + +#endif diff --git a/src/shared/polkit.c b/src/shared/polkit.c new file mode 100644 index 000000000..826944585 --- /dev/null +++ b/src/shared/polkit.c @@ -0,0 +1,166 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +#include + +#include + +#include "util.h" +#include "dbus-common.h" +#include "polkit.h" + +int verify_polkit( + DBusConnection *c, + DBusMessage *request, + const char *action, + bool interactive, + bool *_challenge, + DBusError *error) { + + DBusMessage *m = NULL, *reply = NULL; + const char *unix_process = "unix-process", *pid = "pid", *starttime = "start-time", *cancel_id = ""; + const char *sender; + uint32_t flags = interactive ? 1 : 0; + pid_t pid_raw; + uint32_t pid_u32; + unsigned long long starttime_raw; + uint64_t starttime_u64; + DBusMessageIter iter_msg, iter_struct, iter_array, iter_dict, iter_variant; + int r; + dbus_bool_t authorized = FALSE, challenge = FALSE; + unsigned long ul; + + assert(c); + assert(request); + + sender = dbus_message_get_sender(request); + if (!sender) + return -EINVAL; + + ul = dbus_bus_get_unix_user(c, sender, error); + if (ul == (unsigned long) -1) + return -EINVAL; + + /* Shortcut things for root, to avoid the PK roundtrip and dependency */ + if (ul == 0) + return 1; + + pid_raw = bus_get_unix_process_id(c, sender, error); + if (pid_raw == 0) + return -EINVAL; + + r = get_starttime_of_pid(pid_raw, &starttime_raw); + if (r < 0) + return r; + + m = dbus_message_new_method_call( + "org.freedesktop.PolicyKit1", + "/org/freedesktop/PolicyKit1/Authority", + "org.freedesktop.PolicyKit1.Authority", + "CheckAuthorization"); + if (!m) + return -ENOMEM; + + dbus_message_iter_init_append(m, &iter_msg); + + pid_u32 = (uint32_t) pid_raw; + starttime_u64 = (uint64_t) starttime_raw; + + if (!dbus_message_iter_open_container(&iter_msg, DBUS_TYPE_STRUCT, NULL, &iter_struct) || + !dbus_message_iter_append_basic(&iter_struct, DBUS_TYPE_STRING, &unix_process) || + !dbus_message_iter_open_container(&iter_struct, DBUS_TYPE_ARRAY, "{sv}", &iter_array) || + !dbus_message_iter_open_container(&iter_array, DBUS_TYPE_DICT_ENTRY, NULL, &iter_dict) || + !dbus_message_iter_append_basic(&iter_dict, DBUS_TYPE_STRING, &pid) || + !dbus_message_iter_open_container(&iter_dict, DBUS_TYPE_VARIANT, "u", &iter_variant) || + !dbus_message_iter_append_basic(&iter_variant, DBUS_TYPE_UINT32, &pid_u32) || + !dbus_message_iter_close_container(&iter_dict, &iter_variant) || + !dbus_message_iter_close_container(&iter_array, &iter_dict) || + !dbus_message_iter_open_container(&iter_array, DBUS_TYPE_DICT_ENTRY, NULL, &iter_dict) || + !dbus_message_iter_append_basic(&iter_dict, DBUS_TYPE_STRING, &starttime) || + !dbus_message_iter_open_container(&iter_dict, DBUS_TYPE_VARIANT, "t", &iter_variant) || + !dbus_message_iter_append_basic(&iter_variant, DBUS_TYPE_UINT64, &starttime_u64) || + !dbus_message_iter_close_container(&iter_dict, &iter_variant) || + !dbus_message_iter_close_container(&iter_array, &iter_dict) || + !dbus_message_iter_close_container(&iter_struct, &iter_array) || + !dbus_message_iter_close_container(&iter_msg, &iter_struct) || + !dbus_message_iter_append_basic(&iter_msg, DBUS_TYPE_STRING, &action) || + !dbus_message_iter_open_container(&iter_msg, DBUS_TYPE_ARRAY, "{ss}", &iter_array) || + !dbus_message_iter_close_container(&iter_msg, &iter_array) || + !dbus_message_iter_append_basic(&iter_msg, DBUS_TYPE_UINT32, &flags) || + !dbus_message_iter_append_basic(&iter_msg, DBUS_TYPE_STRING, &cancel_id)) { + r = -ENOMEM; + goto finish; + } + + reply = dbus_connection_send_with_reply_and_block(c, m, -1, error); + if (!reply) { + + /* Treat no PK available as access denied */ + if (dbus_error_has_name(error, DBUS_ERROR_SERVICE_UNKNOWN)) { + r = -EACCES; + dbus_error_free(error); + goto finish; + } + + r = -EIO; + goto finish; + } + + if (!dbus_message_iter_init(reply, &iter_msg) || + dbus_message_iter_get_arg_type(&iter_msg) != DBUS_TYPE_STRUCT) { + r = -EIO; + goto finish; + } + + dbus_message_iter_recurse(&iter_msg, &iter_struct); + + if (dbus_message_iter_get_arg_type(&iter_struct) != DBUS_TYPE_BOOLEAN) { + r = -EIO; + goto finish; + } + + dbus_message_iter_get_basic(&iter_struct, &authorized); + + if (!dbus_message_iter_next(&iter_struct) || + dbus_message_iter_get_arg_type(&iter_struct) != DBUS_TYPE_BOOLEAN) { + r = -EIO; + goto finish; + } + + dbus_message_iter_get_basic(&iter_struct, &challenge); + + if (authorized) + r = 1; + else if (_challenge) { + *_challenge = !!challenge; + r = 0; + } else + r = -EPERM; + +finish: + if (m) + dbus_message_unref(m); + + if (reply) + dbus_message_unref(reply); + + return r; +} diff --git a/src/shared/polkit.h b/src/shared/polkit.h new file mode 100644 index 000000000..6255d1f61 --- /dev/null +++ b/src/shared/polkit.h @@ -0,0 +1,33 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +#include +#include + +int verify_polkit( + DBusConnection *c, + DBusMessage *request, + const char *action, + bool interactive, + bool *challenge, + DBusError *error); diff --git a/src/shared/ratelimit.c b/src/shared/ratelimit.c new file mode 100644 index 000000000..1054d52f9 --- /dev/null +++ b/src/shared/ratelimit.c @@ -0,0 +1,57 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include + +#include "ratelimit.h" +#include "log.h" + +/* Modelled after Linux' lib/ratelimit.c by Dave Young + * , which is licensed GPLv2. */ + +bool ratelimit_test(RateLimit *r) { + usec_t ts; + + assert(r); + + if (r->interval <= 0 || r->burst <= 0) + return true; + + ts = now(CLOCK_MONOTONIC); + + if (r->begin <= 0 || + r->begin + r->interval < ts) { + r->begin = ts; + + /* Reset counter */ + r->num = 0; + goto good; + } + + if (r->num <= r->burst) + goto good; + + return false; + +good: + r->num++; + return true; +} diff --git a/src/shared/ratelimit.h b/src/shared/ratelimit.h new file mode 100644 index 000000000..58efca7df --- /dev/null +++ b/src/shared/ratelimit.h @@ -0,0 +1,57 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +#include "util.h" + +typedef struct RateLimit { + usec_t interval; + usec_t begin; + unsigned burst; + unsigned num; +} RateLimit; + +#define RATELIMIT_DEFINE(_name, _interval, _burst) \ + RateLimit _name = { \ + .interval = (_interval), \ + .burst = (_burst), \ + .num = 0, \ + .begin = 0 \ + } + +#define RATELIMIT_INIT(v, _interval, _burst) \ + do { \ + RateLimit *_r = &(v); \ + _r->interval = (_interval); \ + _r->burst = (_burst); \ + _r->num = 0; \ + _r->begin = 0; \ + } while (false) + +#define RATELIMIT_RESET(v) \ + do { \ + RateLimit *_r = &(v); \ + _r->num = 0; \ + _r->begin = 0; \ + } while (false) + +bool ratelimit_test(RateLimit *r); diff --git a/src/shared/replace-var.c b/src/shared/replace-var.c new file mode 100644 index 000000000..e11c57a43 --- /dev/null +++ b/src/shared/replace-var.c @@ -0,0 +1,110 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + +#include + +#include "macro.h" +#include "util.h" +#include "replace-var.h" + +/* + * Generic infrastructure for replacing @FOO@ style variables in + * strings. Will call a callback for each replacement. + */ + +static int get_variable(const char *b, char **r) { + size_t k; + char *t; + + assert(b); + assert(r); + + if (*b != '@') + return 0; + + k = strspn(b + 1, "ABCDEFGHIJKLMNOPQRSTUVWXYZ_"); + if (k <= 0 || b[k+1] != '@') + return 0; + + t = strndup(b + 1, k); + if (!t) + return -ENOMEM; + + *r = t; + return 1; +} + +char *replace_var(const char *text, char *(*lookup)(const char *variable, void*userdata), void *userdata) { + char *r, *t; + const char *f; + size_t l; + + assert(text); + assert(lookup); + + l = strlen(text); + r = new(char, l+1); + if (!r) + return NULL; + + f = text; + t = r; + while (*f) { + _cleanup_free_ char *v = NULL, *n = NULL; + char *a; + int k; + size_t skip, d, nl; + + k = get_variable(f, &v); + if (k < 0) + goto oom; + if (k == 0) { + *(t++) = *(f++); + continue; + } + + n = lookup(v, userdata); + if (!n) + goto oom; + + skip = strlen(v) + 2; + + d = t - r; + nl = l - skip + strlen(n); + a = realloc(r, nl + 1); + if (!a) + goto oom; + + l = nl; + r = a; + t = r + d; + + t = stpcpy(t, n); + f += skip; + } + + *t = 0; + return r; + +oom: + free(r); + return NULL; +} diff --git a/src/shared/replace-var.h b/src/shared/replace-var.h new file mode 100644 index 000000000..7eaee93a3 --- /dev/null +++ b/src/shared/replace-var.h @@ -0,0 +1,24 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + +char *replace_var(const char *text, char *(*lookup)(const char *variable, void*userdata), void *userdata); diff --git a/src/shared/selinux-util.c b/src/shared/selinux-util.c new file mode 100644 index 000000000..ff3375607 --- /dev/null +++ b/src/shared/selinux-util.c @@ -0,0 +1,42 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include "selinux-util.h" + +#ifdef HAVE_SELINUX + +#include + +static int use_selinux_cached = -1; + +bool use_selinux(void) { + + if (use_selinux_cached < 0) + use_selinux_cached = is_selinux_enabled() > 0; + + return use_selinux_cached; +} + +void retest_selinux(void) { + use_selinux_cached = -1; +} + +#endif diff --git a/src/shared/selinux-util.h b/src/shared/selinux-util.h new file mode 100644 index 000000000..4b8120274 --- /dev/null +++ b/src/shared/selinux-util.h @@ -0,0 +1,27 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +#include + +bool use_selinux(void); +void retest_selinux(void); diff --git a/src/shared/set.c b/src/shared/set.c new file mode 100644 index 000000000..5f83c5083 --- /dev/null +++ b/src/shared/set.c @@ -0,0 +1,130 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include + +#include "set.h" +#include "hashmap.h" + +#define MAKE_SET(h) ((Set*) (h)) +#define MAKE_HASHMAP(s) ((Hashmap*) (s)) + +/* For now this is not much more than a wrapper around a hashmap */ + +Set *set_new(hash_func_t hash_func, compare_func_t compare_func) { + return MAKE_SET(hashmap_new(hash_func, compare_func)); +} + +void set_free(Set* s) { + hashmap_free(MAKE_HASHMAP(s)); +} + +void set_free_free(Set *s) { + hashmap_free_free(MAKE_HASHMAP(s)); +} + +int set_ensure_allocated(Set **s, hash_func_t hash_func, compare_func_t compare_func) { + return hashmap_ensure_allocated((Hashmap**) s, hash_func, compare_func); +} + +int set_put(Set *s, void *value) { + return hashmap_put(MAKE_HASHMAP(s), value, value); +} + +int set_replace(Set *s, void *value) { + return hashmap_replace(MAKE_HASHMAP(s), value, value); +} + +void *set_get(Set *s, void *value) { + return hashmap_get(MAKE_HASHMAP(s), value); +} + +bool set_contains(Set *s, void *value) { + return hashmap_contains(MAKE_HASHMAP(s), value); +} + +void *set_remove(Set *s, void *value) { + return hashmap_remove(MAKE_HASHMAP(s), value); +} + +int set_remove_and_put(Set *s, void *old_value, void *new_value) { + return hashmap_remove_and_put(MAKE_HASHMAP(s), old_value, new_value, new_value); +} + +unsigned set_size(Set *s) { + return hashmap_size(MAKE_HASHMAP(s)); +} + +bool set_isempty(Set *s) { + return hashmap_isempty(MAKE_HASHMAP(s)); +} + +void *set_iterate(Set *s, Iterator *i) { + return hashmap_iterate(MAKE_HASHMAP(s), i, NULL); +} + +void *set_iterate_backwards(Set *s, Iterator *i) { + return hashmap_iterate_backwards(MAKE_HASHMAP(s), i, NULL); +} + +void *set_iterate_skip(Set *s, void *value, Iterator *i) { + return hashmap_iterate_skip(MAKE_HASHMAP(s), value, i); +} + +void *set_steal_first(Set *s) { + return hashmap_steal_first(MAKE_HASHMAP(s)); +} + +void* set_first(Set *s) { + return hashmap_first(MAKE_HASHMAP(s)); +} + +void* set_last(Set *s) { + return hashmap_last(MAKE_HASHMAP(s)); +} + +int set_merge(Set *s, Set *other) { + return hashmap_merge(MAKE_HASHMAP(s), MAKE_HASHMAP(other)); +} + +void set_move(Set *s, Set *other) { + return hashmap_move(MAKE_HASHMAP(s), MAKE_HASHMAP(other)); +} + +int set_move_one(Set *s, Set *other, void *value) { + return hashmap_move_one(MAKE_HASHMAP(s), MAKE_HASHMAP(other), value); +} + +Set* set_copy(Set *s) { + return MAKE_SET(hashmap_copy(MAKE_HASHMAP(s))); +} + +void set_clear(Set *s) { + hashmap_clear(MAKE_HASHMAP(s)); +} + +void set_clear_free(Set *s) { + hashmap_clear_free(MAKE_HASHMAP(s)); +} + +char **set_get_strv(Set *s) { + return hashmap_get_strv(MAKE_HASHMAP(s)); +} diff --git a/src/shared/set.h b/src/shared/set.h new file mode 100644 index 000000000..9162e2ae8 --- /dev/null +++ b/src/shared/set.h @@ -0,0 +1,71 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +/* Pretty straightforward set implementation. Internally based on the + * hashmap. That means that as a minor optimization a NULL set + * object will be treated as empty set for all read + * operations. That way it is not necessary to instantiate an object + * for each set use. */ + +#include "hashmap.h" + +typedef struct Set Set; + +Set *set_new(hash_func_t hash_func, compare_func_t compare_func); +void set_free(Set* s); +void set_free_free(Set *s); +Set* set_copy(Set *s); +int set_ensure_allocated(Set **s, hash_func_t hash_func, compare_func_t compare_func); + +int set_put(Set *s, void *value); +int set_replace(Set *s, void *value); +void *set_get(Set *s, void *value); +bool set_contains(Set *s, void *value); +void *set_remove(Set *s, void *value); +int set_remove_and_put(Set *s, void *old_value, void *new_value); + +int set_merge(Set *s, Set *other); +void set_move(Set *s, Set *other); +int set_move_one(Set *s, Set *other, void *value); + +unsigned set_size(Set *s); +bool set_isempty(Set *s); + +void *set_iterate(Set *s, Iterator *i); +void *set_iterate_backwards(Set *s, Iterator *i); +void *set_iterate_skip(Set *s, void *value, Iterator *i); + +void set_clear(Set *s); +void set_clear_free(Set *s); + +void *set_steal_first(Set *s); +void* set_first(Set *s); +void* set_last(Set *s); + +char **set_get_strv(Set *s); + +#define SET_FOREACH(e, s, i) \ + for ((i) = ITERATOR_FIRST, (e) = set_iterate((s), &(i)); (e); (e) = set_iterate((s), &(i))) + +#define SET_FOREACH_BACKWARDS(e, s, i) \ + for ((i) = ITERATOR_LAST, (e) = set_iterate_backwards((s), &(i)); (e); (e) = set_iterate_backwards((s), &(i))) diff --git a/src/shared/socket-label.c b/src/shared/socket-label.c new file mode 100644 index 000000000..ff212de82 --- /dev/null +++ b/src/shared/socket-label.c @@ -0,0 +1,143 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "macro.h" +#include "util.h" +#include "mkdir.h" +#include "socket-util.h" +#include "missing.h" +#include "label.h" + +int socket_address_listen( + const SocketAddress *a, + int backlog, + SocketAddressBindIPv6Only only, + const char *bind_to_device, + bool free_bind, + bool transparent, + mode_t directory_mode, + mode_t socket_mode, + const char *label, + int *ret) { + + int r, fd, one; + assert(a); + assert(ret); + + if ((r = socket_address_verify(a)) < 0) + return r; + + if (socket_address_family(a) == AF_INET6 && !socket_ipv6_is_supported()) + return -EAFNOSUPPORT; + + r = label_socket_set(label); + if (r < 0) + return r; + + fd = socket(socket_address_family(a), a->type | SOCK_NONBLOCK | SOCK_CLOEXEC, a->protocol); + r = fd < 0 ? -errno : 0; + + label_socket_clear(); + + if (r < 0) + return r; + + if (socket_address_family(a) == AF_INET6 && only != SOCKET_ADDRESS_DEFAULT) { + int flag = only == SOCKET_ADDRESS_IPV6_ONLY; + + if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &flag, sizeof(flag)) < 0) + goto fail; + } + + if (socket_address_family(a) == AF_INET || socket_address_family(a) == AF_INET6) { + if (bind_to_device) + if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, bind_to_device, strlen(bind_to_device)+1) < 0) + goto fail; + + if (free_bind) { + one = 1; + if (setsockopt(fd, IPPROTO_IP, IP_FREEBIND, &one, sizeof(one)) < 0) + log_warning("IP_FREEBIND failed: %m"); + } + + if (transparent) { + one = 1; + if (setsockopt(fd, IPPROTO_IP, IP_TRANSPARENT, &one, sizeof(one)) < 0) + log_warning("IP_TRANSPARENT failed: %m"); + } + } + + one = 1; + if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) < 0) + goto fail; + + if (socket_address_family(a) == AF_UNIX && a->sockaddr.un.sun_path[0] != 0) { + mode_t old_mask; + + /* Create parents */ + mkdir_parents_label(a->sockaddr.un.sun_path, directory_mode); + + /* Enforce the right access mode for the socket*/ + old_mask = umask(~ socket_mode); + + /* Include the original umask in our mask */ + umask(~socket_mode | old_mask); + + r = label_bind(fd, &a->sockaddr.sa, a->size); + + if (r < 0 && errno == EADDRINUSE) { + /* Unlink and try again */ + unlink(a->sockaddr.un.sun_path); + r = bind(fd, &a->sockaddr.sa, a->size); + } + + umask(old_mask); + } else + r = bind(fd, &a->sockaddr.sa, a->size); + + if (r < 0) + goto fail; + + if (socket_address_can_accept(a)) + if (listen(fd, backlog) < 0) + goto fail; + + *ret = fd; + return 0; + +fail: + r = -errno; + close_nointr_nofail(fd); + return r; +} diff --git a/src/shared/socket-util.c b/src/shared/socket-util.c new file mode 100644 index 000000000..56ec99f44 --- /dev/null +++ b/src/shared/socket-util.c @@ -0,0 +1,595 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "macro.h" +#include "util.h" +#include "mkdir.h" +#include "path-util.h" +#include "socket-util.h" +#include "missing.h" + +int socket_address_parse(SocketAddress *a, const char *s) { + int r; + char *e, *n; + unsigned u; + + assert(a); + assert(s); + + zero(*a); + a->type = SOCK_STREAM; + + if (*s == '[') { + /* IPv6 in [x:.....:z]:p notation */ + + if (!socket_ipv6_is_supported()) { + log_warning("Binding to IPv6 address not available since kernel does not support IPv6."); + return -EAFNOSUPPORT; + } + + if (!(e = strchr(s+1, ']'))) + return -EINVAL; + + if (!(n = strndup(s+1, e-s-1))) + return -ENOMEM; + + errno = 0; + if (inet_pton(AF_INET6, n, &a->sockaddr.in6.sin6_addr) <= 0) { + free(n); + return errno != 0 ? -errno : -EINVAL; + } + + free(n); + + e++; + if (*e != ':') + return -EINVAL; + + e++; + if ((r = safe_atou(e, &u)) < 0) + return r; + + if (u <= 0 || u > 0xFFFF) + return -EINVAL; + + a->sockaddr.in6.sin6_family = AF_INET6; + a->sockaddr.in6.sin6_port = htons((uint16_t) u); + a->size = sizeof(struct sockaddr_in6); + + } else if (*s == '/') { + /* AF_UNIX socket */ + + size_t l; + + l = strlen(s); + if (l >= sizeof(a->sockaddr.un.sun_path)) + return -EINVAL; + + a->sockaddr.un.sun_family = AF_UNIX; + memcpy(a->sockaddr.un.sun_path, s, l); + a->size = offsetof(struct sockaddr_un, sun_path) + l + 1; + + } else if (*s == '@') { + /* Abstract AF_UNIX socket */ + size_t l; + + l = strlen(s+1); + if (l >= sizeof(a->sockaddr.un.sun_path) - 1) + return -EINVAL; + + a->sockaddr.un.sun_family = AF_UNIX; + memcpy(a->sockaddr.un.sun_path+1, s+1, l); + a->size = offsetof(struct sockaddr_un, sun_path) + 1 + l; + + } else { + + if ((e = strchr(s, ':'))) { + + if ((r = safe_atou(e+1, &u)) < 0) + return r; + + if (u <= 0 || u > 0xFFFF) + return -EINVAL; + + if (!(n = strndup(s, e-s))) + return -ENOMEM; + + /* IPv4 in w.x.y.z:p notation? */ + if ((r = inet_pton(AF_INET, n, &a->sockaddr.in4.sin_addr)) < 0) { + free(n); + return -errno; + } + + if (r > 0) { + /* Gotcha, it's a traditional IPv4 address */ + free(n); + + a->sockaddr.in4.sin_family = AF_INET; + a->sockaddr.in4.sin_port = htons((uint16_t) u); + a->size = sizeof(struct sockaddr_in); + } else { + unsigned idx; + + if (strlen(n) > IF_NAMESIZE-1) { + free(n); + return -EINVAL; + } + + /* Uh, our last resort, an interface name */ + idx = if_nametoindex(n); + free(n); + + if (idx == 0) + return -EINVAL; + + if (!socket_ipv6_is_supported()) { + log_warning("Binding to interface is not available since kernel does not support IPv6."); + return -EAFNOSUPPORT; + } + + a->sockaddr.in6.sin6_family = AF_INET6; + a->sockaddr.in6.sin6_port = htons((uint16_t) u); + a->sockaddr.in6.sin6_scope_id = idx; + a->sockaddr.in6.sin6_addr = in6addr_any; + a->size = sizeof(struct sockaddr_in6); + } + } else { + + /* Just a port */ + r = safe_atou(s, &u); + 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 = htons((uint16_t) u); + a->sockaddr.in6.sin6_addr = in6addr_any; + a->size = sizeof(struct sockaddr_in6); + } else { + a->sockaddr.in4.sin_family = AF_INET; + a->sockaddr.in4.sin_port = htons((uint16_t) u); + a->sockaddr.in4.sin_addr.s_addr = INADDR_ANY; + a->size = sizeof(struct sockaddr_in); + } + } + } + + return 0; +} + +int socket_address_parse_netlink(SocketAddress *a, const char *s) { + int family; + unsigned group = 0; + _cleanup_free_ char *sfamily = NULL; + assert(a); + assert(s); + + zero(*a); + a->type = SOCK_RAW; + + errno = 0; + if (sscanf(s, "%ms %u", &sfamily, &group) < 1) + return errno ? -errno : -EINVAL; + + family = netlink_family_from_string(sfamily); + if (family < 0) + return -EINVAL; + + a->sockaddr.nl.nl_family = AF_NETLINK; + a->sockaddr.nl.nl_groups = group; + + a->type = SOCK_RAW; + a->size = sizeof(struct sockaddr_nl); + a->protocol = family; + + return 0; +} + +int socket_address_verify(const SocketAddress *a) { + assert(a); + + switch (socket_address_family(a)) { + + case AF_INET: + if (a->size != sizeof(struct sockaddr_in)) + return -EINVAL; + + if (a->sockaddr.in4.sin_port == 0) + return -EINVAL; + + if (a->type != SOCK_STREAM && a->type != SOCK_DGRAM) + return -EINVAL; + + return 0; + + case AF_INET6: + if (a->size != sizeof(struct sockaddr_in6)) + return -EINVAL; + + if (a->sockaddr.in6.sin6_port == 0) + return -EINVAL; + + if (a->type != SOCK_STREAM && a->type != SOCK_DGRAM) + return -EINVAL; + + return 0; + + case AF_UNIX: + if (a->size < offsetof(struct sockaddr_un, sun_path)) + return -EINVAL; + + if (a->size > offsetof(struct sockaddr_un, sun_path)) { + + if (a->sockaddr.un.sun_path[0] != 0) { + char *e; + + /* path */ + if (!(e = memchr(a->sockaddr.un.sun_path, 0, sizeof(a->sockaddr.un.sun_path)))) + return -EINVAL; + + if (a->size != offsetof(struct sockaddr_un, sun_path) + (e - a->sockaddr.un.sun_path) + 1) + return -EINVAL; + } + } + + if (a->type != SOCK_STREAM && a->type != SOCK_DGRAM && a->type != SOCK_SEQPACKET) + return -EINVAL; + + return 0; + + case AF_NETLINK: + + if (a->size != sizeof(struct sockaddr_nl)) + return -EINVAL; + + if (a->type != SOCK_RAW && a->type != SOCK_DGRAM) + return -EINVAL; + + return 0; + + default: + return -EAFNOSUPPORT; + } +} + +int socket_address_print(const SocketAddress *a, char **p) { + int r; + assert(a); + assert(p); + + if ((r = socket_address_verify(a)) < 0) + return r; + + switch (socket_address_family(a)) { + + case AF_INET: { + char *ret; + + if (!(ret = new(char, INET_ADDRSTRLEN+1+5+1))) + return -ENOMEM; + + if (!inet_ntop(AF_INET, &a->sockaddr.in4.sin_addr, ret, INET_ADDRSTRLEN)) { + free(ret); + return -errno; + } + + sprintf(strchr(ret, 0), ":%u", ntohs(a->sockaddr.in4.sin_port)); + *p = ret; + return 0; + } + + case AF_INET6: { + char *ret; + + if (!(ret = new(char, 1+INET6_ADDRSTRLEN+2+5+1))) + return -ENOMEM; + + ret[0] = '['; + if (!inet_ntop(AF_INET6, &a->sockaddr.in6.sin6_addr, ret+1, INET6_ADDRSTRLEN)) { + free(ret); + return -errno; + } + + sprintf(strchr(ret, 0), "]:%u", ntohs(a->sockaddr.in6.sin6_port)); + *p = ret; + return 0; + } + + case AF_UNIX: { + char *ret; + + if (a->size <= offsetof(struct sockaddr_un, sun_path)) { + + if (!(ret = strdup(""))) + return -ENOMEM; + + } else if (a->sockaddr.un.sun_path[0] == 0) { + /* abstract */ + + /* FIXME: We assume we can print the + * socket path here and that it hasn't + * more than one NUL byte. That is + * actually an invalid assumption */ + + if (!(ret = new(char, sizeof(a->sockaddr.un.sun_path)+1))) + return -ENOMEM; + + ret[0] = '@'; + memcpy(ret+1, a->sockaddr.un.sun_path+1, sizeof(a->sockaddr.un.sun_path)-1); + ret[sizeof(a->sockaddr.un.sun_path)] = 0; + + } else { + + if (!(ret = strdup(a->sockaddr.un.sun_path))) + return -ENOMEM; + } + + *p = ret; + return 0; + } + + case AF_NETLINK: { + char _cleanup_free_ *sfamily = NULL; + + r = netlink_family_to_string_alloc(a->protocol, &sfamily); + if (r < 0) + return r; + r = asprintf(p, "%s %u", sfamily, a->sockaddr.nl.nl_groups); + if (r < 0) + return -ENOMEM; + + return 0; + } + + default: + return -EINVAL; + } +} + +bool socket_address_can_accept(const SocketAddress *a) { + assert(a); + + return + a->type == SOCK_STREAM || + a->type == SOCK_SEQPACKET; +} + +bool socket_address_equal(const SocketAddress *a, const SocketAddress *b) { + assert(a); + assert(b); + + /* Invalid addresses are unequal to all */ + if (socket_address_verify(a) < 0 || + socket_address_verify(b) < 0) + return false; + + if (a->type != b->type) + return false; + + if (a->size != b->size) + return false; + + if (socket_address_family(a) != socket_address_family(b)) + return false; + + switch (socket_address_family(a)) { + + case AF_INET: + if (a->sockaddr.in4.sin_addr.s_addr != b->sockaddr.in4.sin_addr.s_addr) + return false; + + if (a->sockaddr.in4.sin_port != b->sockaddr.in4.sin_port) + return false; + + break; + + case AF_INET6: + if (memcmp(&a->sockaddr.in6.sin6_addr, &b->sockaddr.in6.sin6_addr, sizeof(a->sockaddr.in6.sin6_addr)) != 0) + return false; + + if (a->sockaddr.in6.sin6_port != b->sockaddr.in6.sin6_port) + return false; + + break; + + case AF_UNIX: + + if ((a->sockaddr.un.sun_path[0] == 0) != (b->sockaddr.un.sun_path[0] == 0)) + return false; + + if (a->sockaddr.un.sun_path[0]) { + if (strncmp(a->sockaddr.un.sun_path, b->sockaddr.un.sun_path, sizeof(a->sockaddr.un.sun_path)) != 0) + return false; + } else { + if (memcmp(a->sockaddr.un.sun_path, b->sockaddr.un.sun_path, a->size) != 0) + return false; + } + + break; + + case AF_NETLINK: + + if (a->protocol != b->protocol) + return false; + + if (a->sockaddr.nl.nl_groups != b->sockaddr.nl.nl_groups) + return false; + + break; + + default: + /* Cannot compare, so we assume the addresses are different */ + return false; + } + + return true; +} + +bool socket_address_is(const SocketAddress *a, const char *s, int type) { + struct SocketAddress b; + + assert(a); + assert(s); + + if (socket_address_parse(&b, s) < 0) + return false; + + b.type = type; + + return socket_address_equal(a, &b); +} + +bool socket_address_is_netlink(const SocketAddress *a, const char *s) { + struct SocketAddress b; + + assert(a); + assert(s); + + if (socket_address_parse_netlink(&b, s) < 0) + return false; + + return socket_address_equal(a, &b); +} + +bool socket_address_needs_mount(const SocketAddress *a, const char *prefix) { + assert(a); + + if (socket_address_family(a) != AF_UNIX) + return false; + + if (a->sockaddr.un.sun_path[0] == 0) + return false; + + return path_startswith(a->sockaddr.un.sun_path, prefix); +} + +bool socket_ipv6_is_supported(void) { + char *l = 0; + bool enabled; + + if (access("/sys/module/ipv6", F_OK) != 0) + return 0; + + /* If we can't check "disable" parameter, assume enabled */ + if (read_one_line_file("/sys/module/ipv6/parameters/disable", &l) < 0) + return 1; + + /* If module was loaded with disable=1 no IPv6 available */ + enabled = l[0] == '0'; + free(l); + + return enabled; +} + +bool socket_address_matches_fd(const SocketAddress *a, int fd) { + union sockaddr_union sa; + socklen_t salen = sizeof(sa), solen; + int protocol, type; + + assert(a); + assert(fd >= 0); + + if (getsockname(fd, &sa.sa, &salen) < 0) + return false; + + if (sa.sa.sa_family != a->sockaddr.sa.sa_family) + return false; + + solen = sizeof(type); + if (getsockopt(fd, SOL_SOCKET, SO_TYPE, &type, &solen) < 0) + return false; + + if (type != a->type) + return false; + + if (a->protocol != 0) { + solen = sizeof(protocol); + if (getsockopt(fd, SOL_SOCKET, SO_PROTOCOL, &protocol, &solen) < 0) + return false; + + if (protocol != a->protocol) + return false; + } + + switch (sa.sa.sa_family) { + + case AF_INET: + return sa.in4.sin_port == a->sockaddr.in4.sin_port && + sa.in4.sin_addr.s_addr == a->sockaddr.in4.sin_addr.s_addr; + + case AF_INET6: + return sa.in6.sin6_port == a->sockaddr.in6.sin6_port && + memcmp(&sa.in6.sin6_addr, &a->sockaddr.in6.sin6_addr, sizeof(struct in6_addr)) == 0; + + case AF_UNIX: + return salen == a->size && + memcmp(sa.un.sun_path, a->sockaddr.un.sun_path, salen - offsetof(struct sockaddr_un, sun_path)) == 0; + + } + + return false; +} + +static const char* const netlink_family_table[] = { + [NETLINK_ROUTE] = "route", + [NETLINK_FIREWALL] = "firewall", + [NETLINK_INET_DIAG] = "inet-diag", + [NETLINK_NFLOG] = "nflog", + [NETLINK_XFRM] = "xfrm", + [NETLINK_SELINUX] = "selinux", + [NETLINK_ISCSI] = "iscsi", + [NETLINK_AUDIT] = "audit", + [NETLINK_FIB_LOOKUP] = "fib-lookup", + [NETLINK_CONNECTOR] = "connector", + [NETLINK_NETFILTER] = "netfilter", + [NETLINK_IP6_FW] = "ip6-fw", + [NETLINK_DNRTMSG] = "dnrtmsg", + [NETLINK_KOBJECT_UEVENT] = "kobject-uevent", + [NETLINK_GENERIC] = "generic", + [NETLINK_SCSITRANSPORT] = "scsitransport", + [NETLINK_ECRYPTFS] = "ecryptfs" +}; + +DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(netlink_family, int, INT_MAX); + +static const char* const socket_address_bind_ipv6_only_table[_SOCKET_ADDRESS_BIND_IPV6_ONLY_MAX] = { + [SOCKET_ADDRESS_DEFAULT] = "default", + [SOCKET_ADDRESS_BOTH] = "both", + [SOCKET_ADDRESS_IPV6_ONLY] = "ipv6-only" +}; + +DEFINE_STRING_TABLE_LOOKUP(socket_address_bind_ipv6_only, SocketAddressBindIPv6Only); diff --git a/src/shared/socket-util.h b/src/shared/socket-util.h new file mode 100644 index 000000000..771765d32 --- /dev/null +++ b/src/shared/socket-util.h @@ -0,0 +1,101 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +#include +#include +#include +#include +#include +#include + +#include "macro.h" +#include "util.h" + +union sockaddr_union { + struct sockaddr sa; + struct sockaddr_in in4; + struct sockaddr_in6 in6; + struct sockaddr_un un; + struct sockaddr_nl nl; + struct sockaddr_storage storage; +}; + +typedef struct SocketAddress { + union sockaddr_union sockaddr; + + /* We store the size here explicitly due to the weird + * sockaddr_un semantics for abstract sockets */ + socklen_t size; + + /* Socket type, i.e. SOCK_STREAM, SOCK_DGRAM, ... */ + int type; + + /* Socket protocol, IPPROTO_xxx, usually 0, except for netlink */ + int protocol; +} SocketAddress; + +typedef enum SocketAddressBindIPv6Only { + SOCKET_ADDRESS_DEFAULT, + SOCKET_ADDRESS_BOTH, + SOCKET_ADDRESS_IPV6_ONLY, + _SOCKET_ADDRESS_BIND_IPV6_ONLY_MAX, + _SOCKET_ADDRESS_BIND_IPV6_ONLY_INVALID = -1 +} SocketAddressBindIPv6Only; + +#define socket_address_family(a) ((a)->sockaddr.sa.sa_family) + +int socket_address_parse(SocketAddress *a, const char *s); +int socket_address_parse_netlink(SocketAddress *a, const char *s); +int socket_address_print(const SocketAddress *a, char **p); +int socket_address_verify(const SocketAddress *a); + +bool socket_address_can_accept(const SocketAddress *a); + +int socket_address_listen( + const SocketAddress *a, + int backlog, + SocketAddressBindIPv6Only only, + const char *bind_to_device, + bool free_bind, + bool transparent, + mode_t directory_mode, + mode_t socket_mode, + const char *label, + int *ret); + +bool socket_address_is(const SocketAddress *a, const char *s, int type); +bool socket_address_is_netlink(const SocketAddress *a, const char *s); + +bool socket_address_matches_fd(const SocketAddress *a, int fd); + +bool socket_address_equal(const SocketAddress *a, const SocketAddress *b); + +bool socket_address_needs_mount(const SocketAddress *a, const char *prefix); + +const char* socket_address_bind_ipv6_only_to_string(SocketAddressBindIPv6Only b); +SocketAddressBindIPv6Only socket_address_bind_ipv6_only_from_string(const char *s); + +int netlink_family_to_string_alloc(int b, char **s); +int netlink_family_from_string(const char *s); + +bool socket_ipv6_is_supported(void); diff --git a/src/shared/sparse-endian.h b/src/shared/sparse-endian.h new file mode 100644 index 000000000..eb4dbf361 --- /dev/null +++ b/src/shared/sparse-endian.h @@ -0,0 +1,87 @@ +/* Copyright (c) 2012 Josh Triplett + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ +#ifndef SPARSE_ENDIAN_H +#define SPARSE_ENDIAN_H + +#include +#include + +#ifdef __CHECKER__ +#define __bitwise __attribute__((bitwise)) +#define __force __attribute__((force)) +#else +#define __bitwise +#define __force +#endif + +typedef uint16_t __bitwise le16_t; +typedef uint16_t __bitwise be16_t; +typedef uint32_t __bitwise le32_t; +typedef uint32_t __bitwise be32_t; +typedef uint64_t __bitwise le64_t; +typedef uint64_t __bitwise be64_t; + +#undef htobe16 +#undef htole16 +#undef be16toh +#undef le16toh +#undef htobe32 +#undef htole32 +#undef be32toh +#undef le32toh +#undef htobe64 +#undef htole64 +#undef be64toh +#undef le64toh + +#if __BYTE_ORDER == __LITTLE_ENDIAN +#define bswap_16_on_le(x) __bswap_16(x) +#define bswap_32_on_le(x) __bswap_32(x) +#define bswap_64_on_le(x) __bswap_64(x) +#define bswap_16_on_be(x) (x) +#define bswap_32_on_be(x) (x) +#define bswap_64_on_be(x) (x) +#elif __BYTE_ORDER == __BIG_ENDIAN +#define bswap_16_on_le(x) (x) +#define bswap_32_on_le(x) (x) +#define bswap_64_on_le(x) (x) +#define bswap_16_on_be(x) __bswap_16(x) +#define bswap_32_on_be(x) __bswap_32(x) +#define bswap_64_on_be(x) __bswap_64(x) +#endif + +static inline le16_t htole16(uint16_t value) { return (le16_t __force) bswap_16_on_be(value); } +static inline le32_t htole32(uint32_t value) { return (le32_t __force) bswap_32_on_be(value); } +static inline le64_t htole64(uint64_t value) { return (le64_t __force) bswap_64_on_be(value); } + +static inline be16_t htobe16(uint16_t value) { return (be16_t __force) bswap_16_on_le(value); } +static inline be32_t htobe32(uint32_t value) { return (be32_t __force) bswap_32_on_le(value); } +static inline be64_t htobe64(uint64_t value) { return (be64_t __force) bswap_64_on_le(value); } + +static inline uint16_t le16toh(le16_t value) { return bswap_16_on_be((uint16_t __force)value); } +static inline uint32_t le32toh(le32_t value) { return bswap_32_on_be((uint32_t __force)value); } +static inline uint64_t le64toh(le64_t value) { return bswap_64_on_be((uint64_t __force)value); } + +static inline uint16_t be16toh(be16_t value) { return bswap_16_on_le((uint16_t __force)value); } +static inline uint32_t be32toh(be32_t value) { return bswap_32_on_le((uint32_t __force)value); } +static inline uint64_t be64toh(be64_t value) { return bswap_64_on_le((uint64_t __force)value); } + +#endif /* SPARSE_ENDIAN_H */ diff --git a/src/shared/spawn-ask-password-agent.c b/src/shared/spawn-ask-password-agent.c new file mode 100644 index 000000000..c1a9c5868 --- /dev/null +++ b/src/shared/spawn-ask-password-agent.c @@ -0,0 +1,67 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include + +#include "log.h" +#include "util.h" +#include "spawn-ask-password-agent.h" + +static pid_t agent_pid = 0; + +int ask_password_agent_open(void) { + int r; + + if (agent_pid > 0) + return 0; + + /* We check STDIN here, not STDOUT, since this is about input, + * not output */ + if (!isatty(STDIN_FILENO)) + return 0; + + r = fork_agent(&agent_pid, + NULL, 0, + SYSTEMD_TTY_ASK_PASSWORD_AGENT_BINARY_PATH, + SYSTEMD_TTY_ASK_PASSWORD_AGENT_BINARY_PATH, "--watch", NULL); + if (r < 0) + log_error("Failed to fork TTY ask password agent: %s", strerror(-r)); + + return r; +} + +void ask_password_agent_close(void) { + + if (agent_pid <= 0) + return; + + /* Inform agent that we are done */ + kill(agent_pid, SIGTERM); + kill(agent_pid, SIGCONT); + wait_for_terminate(agent_pid, NULL); + agent_pid = 0; +} diff --git a/src/shared/spawn-ask-password-agent.h b/src/shared/spawn-ask-password-agent.h new file mode 100644 index 000000000..31b4beab5 --- /dev/null +++ b/src/shared/spawn-ask-password-agent.h @@ -0,0 +1,25 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +int ask_password_agent_open(void); +void ask_password_agent_close(void); diff --git a/src/shared/spawn-polkit-agent.c b/src/shared/spawn-polkit-agent.c new file mode 100644 index 000000000..fcb3722dd --- /dev/null +++ b/src/shared/spawn-polkit-agent.c @@ -0,0 +1,86 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "log.h" +#include "util.h" +#include "spawn-polkit-agent.h" + +static pid_t agent_pid = 0; + +int polkit_agent_open(void) { + int r; + int pipe_fd[2]; + char notify_fd[10 + 1]; + + if (agent_pid > 0) + return 0; + + /* We check STDIN here, not STDOUT, since this is about input, + * not output */ + if (!isatty(STDIN_FILENO)) + return 0; + + if (pipe2(pipe_fd, 0) < 0) + return -errno; + + snprintf(notify_fd, sizeof(notify_fd), "%i", pipe_fd[1]); + char_array_0(notify_fd); + + r = fork_agent(&agent_pid, + &pipe_fd[1], 1, + POLKIT_AGENT_BINARY_PATH, + POLKIT_AGENT_BINARY_PATH, "--notify-fd", notify_fd, "--fallback", NULL); + + /* Close the writing side, because that's the one for the agent */ + close_nointr_nofail(pipe_fd[1]); + + if (r < 0) + log_error("Failed to fork TTY ask password agent: %s", strerror(-r)); + else + /* Wait until the agent closes the fd */ + fd_wait_for_event(pipe_fd[0], POLLHUP, (usec_t) -1); + + close_nointr_nofail(pipe_fd[0]); + + return r; +} + +void polkit_agent_close(void) { + + if (agent_pid <= 0) + return; + + /* Inform agent that we are done */ + kill(agent_pid, SIGTERM); + kill(agent_pid, SIGCONT); + wait_for_terminate(agent_pid, NULL); + agent_pid = 0; +} diff --git a/src/shared/spawn-polkit-agent.h b/src/shared/spawn-polkit-agent.h new file mode 100644 index 000000000..b91d20f12 --- /dev/null +++ b/src/shared/spawn-polkit-agent.h @@ -0,0 +1,28 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foospawnpolkitagenthfoo +#define foospawnpolkitagenthfoo + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + +int polkit_agent_open(void); +void polkit_agent_close(void); + +#endif diff --git a/src/shared/specifier.c b/src/shared/specifier.c new file mode 100644 index 000000000..599027cd4 --- /dev/null +++ b/src/shared/specifier.c @@ -0,0 +1,111 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include + +#include "macro.h" +#include "util.h" +#include "specifier.h" + +/* + * Generic infrastructure for replacing %x style specifiers in + * strings. Will call a callback for each replacement. + * + */ + +char *specifier_printf(const char *text, const Specifier table[], void *userdata) { + char *r, *t; + const char *f; + bool percent = false; + size_t l; + + assert(text); + assert(table); + + l = strlen(text); + r = new(char, l+1); + if (!r) + return NULL; + + t = r; + + for (f = text; *f; f++, l--) { + + if (percent) { + if (*f == '%') + *(t++) = '%'; + else { + const Specifier *i; + + for (i = table; i->specifier; i++) + if (i->specifier == *f) + break; + + if (i->lookup) { + char *n, *w; + size_t k, j; + + w = i->lookup(i->specifier, i->data, userdata); + if (!w) { + free(r); + return NULL; + } + + j = t - r; + k = strlen(w); + + n = new(char, j + k + l + 1); + if (!n) { + free(r); + free(w); + return NULL; + } + + memcpy(n, r, j); + memcpy(n + j, w, k); + + free(r); + free(w); + + r = n; + t = n + j + k; + } else { + *(t++) = '%'; + *(t++) = *f; + } + } + + percent = false; + } else if (*f == '%') + percent = true; + else + *(t++) = *f; + } + + *t = 0; + return r; +} + +/* Generic handler for simple string replacements */ + +char* specifier_string(char specifier, void *data, void *userdata) { + return strdup(strempty(data)); +} diff --git a/src/shared/specifier.h b/src/shared/specifier.h new file mode 100644 index 000000000..25a27a423 --- /dev/null +++ b/src/shared/specifier.h @@ -0,0 +1,34 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +typedef char* (*SpecifierCallback)(char specifier, void *data, void *userdata); + +typedef struct Specifier { + const char specifier; + const SpecifierCallback lookup; + void *data; +} Specifier; + +char *specifier_printf(const char *text, const Specifier table[], void *userdata); + +char* specifier_string(char specifier, void *data, void *userdata); diff --git a/src/shared/strbuf.c b/src/shared/strbuf.c new file mode 100644 index 000000000..915cd3ac9 --- /dev/null +++ b/src/shared/strbuf.c @@ -0,0 +1,176 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2012 Kay Sievers + + 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 . +***/ + +#include +#include + +#include "util.h" +#include "strbuf.h" + +/* + * Strbuf stores given strings in a single continous allocated memory + * area. Identical strings are de-duplicated and return the same offset + * as the first string stored. If the tail of a string already exists + * in the buffer, the tail is returned. + * + * A trie (http://en.wikipedia.org/wiki/Trie) is used to maintain the + * information about the stored strings. + * + * Example of udev rules: + * $ ./udevadm test . + * ... + * read rules file: /usr/lib/udev/rules.d/99-systemd.rules + * rules contain 196608 bytes tokens (16384 * 12 bytes), 39742 bytes strings + * 23939 strings (207859 bytes), 20404 de-duplicated (171653 bytes), 3536 trie nodes used + * ... + */ + +struct strbuf *strbuf_new(void) { + struct strbuf *str; + + str = new0(struct strbuf, 1); + if (!str) + return NULL; + + str->buf = new0(char, 1); + if (!str->buf) + goto err; + str->len = 1; + + str->root = new0(struct strbuf_node, 1); + if (!str->root) + goto err; + str->nodes_count = 1; + return str; +err: + free(str->buf); + free(str->root); + free(str); + return NULL; +} + +static void strbuf_node_cleanup(struct strbuf_node *node) { + size_t i; + + for (i = 0; i < node->children_count; i++) + strbuf_node_cleanup(node->children[i].child); + free(node->children); + free(node); +} + +/* clean up trie data, leave only the string buffer */ +void strbuf_complete(struct strbuf *str) { + if (!str) + return; + if (str->root) + strbuf_node_cleanup(str->root); + str->root = NULL; +} + +/* clean up everything */ +void strbuf_cleanup(struct strbuf *str) { + if (!str) + return; + if (str->root) + strbuf_node_cleanup(str->root); + free(str->buf); + free(str); +} + +static int strbuf_children_cmp(const void *v1, const void *v2) { + const struct strbuf_child_entry *n1 = v1; + const struct strbuf_child_entry *n2 = v2; + + return n1->c - n2->c; +} + +/* add string, return the index/offset into the buffer */ +ssize_t strbuf_add_string(struct strbuf *str, const char *s, size_t len) { + uint8_t c; + struct strbuf_node *node; + size_t depth; + char *buf_new; + struct strbuf_child_entry *child; + struct strbuf_node *node_child; + ssize_t off; + + if (!str->root) + return -EINVAL; + + /* search string; start from last character to find possibly matching tails */ + if (len == 0) + return 0; + str->in_count++; + str->in_len += len; + + node = str->root; + c = s[len-1]; + for (depth = 0; depth <= len; depth++) { + struct strbuf_child_entry search; + + /* match against current node */ + off = node->value_off + node->value_len - len; + if (depth == len || (node->value_len >= len && memcmp(str->buf + off, s, len) == 0)) { + str->dedup_len += len; + str->dedup_count++; + return off; + } + + /* lookup child node */ + c = s[len - 1 - depth]; + search.c = c; + child = bsearch(&search, node->children, node->children_count, sizeof(struct strbuf_child_entry), + strbuf_children_cmp); + if (!child) + break; + node = child->child; + } + + /* add new string */ + buf_new = realloc(str->buf, str->len + len+1); + if (!buf_new) + return -ENOMEM; + str->buf = buf_new; + off = str->len; + memcpy(str->buf + off, s, len); + str->len += len; + str->buf[str->len++] = '\0'; + + /* new node */ + node_child = new0(struct strbuf_node, 1); + if (!node_child) + return -ENOMEM; + str->nodes_count++; + node_child->value_off = off; + node_child->value_len = len; + + /* extend array, add new entry, sort for bisection */ + child = realloc(node->children, (node->children_count + 1) * sizeof(struct strbuf_child_entry)); + if (!child) + return -ENOMEM; + node->children = child; + node->children[node->children_count].c = c; + node->children[node->children_count].child = node_child; + node->children_count++; + qsort(node->children, node->children_count, sizeof(struct strbuf_child_entry), strbuf_children_cmp); + + return off; +} diff --git a/src/shared/strbuf.h b/src/shared/strbuf.h new file mode 100644 index 000000000..2347fd432 --- /dev/null +++ b/src/shared/strbuf.h @@ -0,0 +1,56 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2012 Kay Sievers + + 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 . +***/ + +#include +#include +#include + +struct strbuf { + char *buf; + size_t len; + struct strbuf_node *root; + + size_t nodes_count; + size_t in_count; + size_t in_len; + size_t dedup_len; + size_t dedup_count; +}; + +struct strbuf_node { + size_t value_off; + size_t value_len; + + struct strbuf_child_entry *children; + uint8_t children_count; +}; + +struct strbuf_child_entry { + uint8_t c; + struct strbuf_node *child; +}; + +struct strbuf *strbuf_new(void); +ssize_t strbuf_add_string(struct strbuf *str, const char *s, size_t len); +void strbuf_complete(struct strbuf *str); +void strbuf_cleanup(struct strbuf *str); diff --git a/src/shared/strv.c b/src/shared/strv.c new file mode 100644 index 000000000..6b76d0eae --- /dev/null +++ b/src/shared/strv.c @@ -0,0 +1,750 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include +#include + +#include "util.h" +#include "strv.h" + +char *strv_find(char **l, const char *name) { + char **i; + + assert(name); + + STRV_FOREACH(i, l) + if (streq(*i, name)) + return *i; + + return NULL; +} + +char *strv_find_prefix(char **l, const char *name) { + char **i; + + assert(name); + + STRV_FOREACH(i, l) + if (startswith(*i, name)) + return *i; + + return NULL; +} + +void strv_free(char **l) { + char **k; + + if (!l) + return; + + for (k = l; *k; k++) + free(*k); + + free(l); +} + +void strv_freep(char ***l) { + if (!l) + return; + + strv_free(*l); + *l = NULL; +} + +char **strv_copy(char **l) { + char **r, **k; + + k = r = new(char*, strv_length(l) + 1); + if (!r) + return NULL; + + if (l) + for (; *l; k++, l++) { + *k = strdup(*l); + if (!*k) { + strv_free(r); + return NULL; + } + } + + *k = NULL; + return r; +} + +unsigned strv_length(char **l) { + unsigned n = 0; + + if (!l) + return 0; + + for (; *l; l++) + n++; + + return n; +} + +char **strv_new_ap(const char *x, va_list ap) { + const char *s; + char **a; + unsigned n = 0, i = 0; + va_list aq; + + /* As a special trick we ignore all listed strings that equal + * (const char*) -1. This is supposed to be used with the + * STRV_IFNOTNULL() macro to include possibly NULL strings in + * the string list. */ + + if (x) { + n = x == (const char*) -1 ? 0 : 1; + + va_copy(aq, ap); + while ((s = va_arg(aq, const char*))) { + if (s == (const char*) -1) + continue; + + n++; + } + + va_end(aq); + } + + a = new(char*, n+1); + if (!a) + return NULL; + + if (x) { + if (x != (const char*) -1) { + a[i] = strdup(x); + if (!a[i]) + goto fail; + i++; + } + + while ((s = va_arg(ap, const char*))) { + + if (s == (const char*) -1) + continue; + + a[i] = strdup(s); + if (!a[i]) + goto fail; + + i++; + } + } + + a[i] = NULL; + + return a; + +fail: + strv_free(a); + return NULL; +} + +char **strv_new(const char *x, ...) { + char **r; + va_list ap; + + va_start(ap, x); + r = strv_new_ap(x, ap); + va_end(ap); + + return r; +} + +char **strv_merge(char **a, char **b) { + char **r, **k; + + if (!a) + return strv_copy(b); + + if (!b) + return strv_copy(a); + + r = new(char*, strv_length(a) + strv_length(b) + 1); + if (!r) + return NULL; + + for (k = r; *a; k++, a++) { + *k = strdup(*a); + if (!*k) + goto fail; + } + + for (; *b; k++, b++) { + *k = strdup(*b); + if (!*k) + goto fail; + } + + *k = NULL; + return r; + +fail: + strv_free(r); + return NULL; +} + +char **strv_merge_concat(char **a, char **b, const char *suffix) { + char **r, **k; + + /* Like strv_merge(), but appends suffix to all strings in b, before adding */ + + if (!b) + return strv_copy(a); + + r = new(char*, strv_length(a) + strv_length(b) + 1); + if (!r) + return NULL; + + k = r; + if (a) + for (; *a; k++, a++) { + *k = strdup(*a); + if (!*k) + goto fail; + } + + for (; *b; k++, b++) { + *k = strappend(*b, suffix); + if (!*k) + goto fail; + } + + *k = NULL; + return r; + +fail: + strv_free(r); + return NULL; + +} + +char **strv_split(const char *s, const char *separator) { + char *state; + char *w; + size_t l; + unsigned n, i; + char **r; + + assert(s); + + n = 0; + FOREACH_WORD_SEPARATOR(w, l, s, separator, state) + n++; + + r = new(char*, n+1); + if (!r) + return NULL; + + i = 0; + FOREACH_WORD_SEPARATOR(w, l, s, separator, state) { + r[i] = strndup(w, l); + if (!r[i]) { + strv_free(r); + return NULL; + } + + i++; + } + + r[i] = NULL; + return r; +} + +char **strv_split_quoted(const char *s) { + char *state; + char *w; + size_t l; + unsigned n, i; + char **r; + + assert(s); + + n = 0; + FOREACH_WORD_QUOTED(w, l, s, state) + n++; + + r = new(char*, n+1); + if (!r) + return NULL; + + i = 0; + FOREACH_WORD_QUOTED(w, l, s, state) { + r[i] = cunescape_length(w, l); + if (!r[i]) { + strv_free(r); + return NULL; + } + i++; + } + + r[i] = NULL; + return r; +} + +char *strv_join(char **l, const char *separator) { + char *r, *e; + char **s; + size_t n, k; + + if (!separator) + separator = " "; + + k = strlen(separator); + + n = 0; + STRV_FOREACH(s, l) { + if (n != 0) + n += k; + n += strlen(*s); + } + + r = new(char, n+1); + if (!r) + return NULL; + + e = r; + STRV_FOREACH(s, l) { + if (e != r) + e = stpcpy(e, separator); + + e = stpcpy(e, *s); + } + + *e = 0; + + return r; +} + +char **strv_append(char **l, const char *s) { + char **r, **k; + + if (!l) + return strv_new(s, NULL); + + if (!s) + return strv_copy(l); + + r = new(char*, strv_length(l)+2); + if (!r) + return NULL; + + for (k = r; *l; k++, l++) { + *k = strdup(*l); + if (!*k) + goto fail; + } + + k[0] = strdup(s); + if (!k[0]) + goto fail; + + k[1] = NULL; + return r; + +fail: + strv_free(r); + return NULL; +} + +char **strv_uniq(char **l) { + char **i; + + /* Drops duplicate entries. The first identical string will be + * kept, the others dropped */ + + STRV_FOREACH(i, l) + strv_remove(i+1, *i); + + return l; +} + +char **strv_remove(char **l, const char *s) { + char **f, **t; + + if (!l) + return NULL; + + assert(s); + + /* Drops every occurrence of s in the string list, edits + * in-place. */ + + for (f = t = l; *f; f++) { + + if (streq(*f, s)) { + free(*f); + continue; + } + + *(t++) = *f; + } + + *t = NULL; + return l; +} + +char **strv_remove_prefix(char **l, const char *s) { + char **f, **t; + + if (!l) + return NULL; + + assert(s); + + /* Drops every occurrence of a string prefixed with s in the + * string list, edits in-place. */ + + for (f = t = l; *f; f++) { + + if (startswith(*f, s)) { + free(*f); + continue; + } + + *(t++) = *f; + } + + *t = NULL; + return l; +} + +static int env_append(char **r, char ***k, char **a) { + assert(r); + assert(k); + + if (!a) + return 0; + + /* Add the entries of a to *k unless they already exist in *r + * in which case they are overridden instead. This assumes + * there is enough space in the r array. */ + + for (; *a; a++) { + char **j; + size_t n; + + n = strcspn(*a, "="); + + if ((*a)[n] == '=') + n++; + + for (j = r; j < *k; j++) + if (strncmp(*j, *a, n) == 0) + break; + + if (j >= *k) + (*k)++; + else + free(*j); + + *j = strdup(*a); + if (!*j) + return -ENOMEM; + } + + return 0; +} + +char **strv_env_merge(unsigned n_lists, ...) { + size_t n = 0; + char **l, **k, **r; + va_list ap; + unsigned i; + + /* Merges an arbitrary number of environment sets */ + + va_start(ap, n_lists); + for (i = 0; i < n_lists; i++) { + l = va_arg(ap, char**); + n += strv_length(l); + } + va_end(ap); + + r = new(char*, n+1); + if (!r) + return NULL; + + k = r; + + va_start(ap, n_lists); + for (i = 0; i < n_lists; i++) { + l = va_arg(ap, char**); + if (env_append(r, &k, l) < 0) + goto fail; + } + va_end(ap); + + *k = NULL; + + return r; + +fail: + va_end(ap); + strv_free(r); + + return NULL; +} + +static bool env_match(const char *t, const char *pattern) { + assert(t); + assert(pattern); + + /* pattern a matches string a + * a matches a= + * a matches a=b + * a= matches a= + * a=b matches a=b + * a= does not match a + * a=b does not match a= + * a=b does not match a + * a=b does not match a=c */ + + if (streq(t, pattern)) + return true; + + if (!strchr(pattern, '=')) { + size_t l = strlen(pattern); + + return strncmp(t, pattern, l) == 0 && t[l] == '='; + } + + return false; +} + +char **strv_env_delete(char **x, unsigned n_lists, ...) { + size_t n, i = 0; + char **k, **r; + va_list ap; + + /* Deletes every entry from x that is mentioned in the other + * string lists */ + + n = strv_length(x); + + r = new(char*, n+1); + if (!r) + return NULL; + + STRV_FOREACH(k, x) { + unsigned v; + + va_start(ap, n_lists); + for (v = 0; v < n_lists; v++) { + char **l, **j; + + l = va_arg(ap, char**); + STRV_FOREACH(j, l) + if (env_match(*k, *j)) + goto skip; + } + va_end(ap); + + r[i] = strdup(*k); + if (!r[i]) { + strv_free(r); + return NULL; + } + + i++; + continue; + + skip: + va_end(ap); + } + + r[i] = NULL; + + assert(i <= n); + + return r; +} + +char **strv_env_unset(char **l, const char *p) { + + char **f, **t; + + if (!l) + return NULL; + + assert(p); + + /* Drops every occurrence of the env var setting p in the + * string list. edits in-place. */ + + for (f = t = l; *f; f++) { + + if (env_match(*f, p)) { + free(*f); + continue; + } + + *(t++) = *f; + } + + *t = NULL; + return l; +} + +char **strv_env_set(char **x, const char *p) { + + char **k, **r; + char* m[2] = { (char*) p, NULL }; + + /* Overrides the env var setting of p, returns a new copy */ + + r = new(char*, strv_length(x)+2); + if (!r) + return NULL; + + k = r; + if (env_append(r, &k, x) < 0) + goto fail; + + if (env_append(r, &k, m) < 0) + goto fail; + + *k = NULL; + + return r; + +fail: + strv_free(r); + return NULL; + +} + +char *strv_env_get_with_length(char **l, const char *name, size_t k) { + char **i; + + assert(name); + + STRV_FOREACH(i, l) + if (strncmp(*i, name, k) == 0 && + (*i)[k] == '=') + return *i + k + 1; + + return NULL; +} + +char *strv_env_get(char **l, const char *name) { + return strv_env_get_with_length(l, name, strlen(name)); +} + +char **strv_env_clean(char **l) { + char **r, **ret; + + for (r = ret = l; *l; l++) { + const char *equal; + + equal = strchr(*l, '='); + + if (equal && equal[1] == 0) { + free(*l); + continue; + } + + *(r++) = *l; + } + + *r = NULL; + + return ret; +} + +char **strv_parse_nulstr(const char *s, size_t l) { + const char *p; + unsigned c = 0, i = 0; + char **v; + + assert(s || l <= 0); + + if (l <= 0) + return strv_new(NULL, NULL); + + for (p = s; p < s + l; p++) + if (*p == 0) + c++; + + if (s[l-1] != 0) + c++; + + v = new0(char*, c+1); + if (!v) + return NULL; + + p = s; + while (p < s + l) { + const char *e; + + e = memchr(p, 0, s + l - p); + + v[i] = strndup(p, e ? e - p : s + l - p); + if (!v[i]) { + strv_free(v); + return NULL; + } + + i++; + + if (!e) + break; + + p = e + 1; + } + + assert(i == c); + + return v; +} + +bool strv_overlap(char **a, char **b) { + char **i, **j; + + STRV_FOREACH(i, a) { + STRV_FOREACH(j, b) { + if (streq(*i, *j)) + return true; + } + } + + return false; +} + +static int str_compare(const void *_a, const void *_b) { + const char **a = (const char**) _a, **b = (const char**) _b; + + return strcmp(*a, *b); +} + +char **strv_sort(char **l) { + + if (strv_isempty(l)) + return l; + + qsort(l, strv_length(l), sizeof(char*), str_compare); + return l; +} diff --git a/src/shared/strv.h b/src/shared/strv.h new file mode 100644 index 000000000..45558d896 --- /dev/null +++ b/src/shared/strv.h @@ -0,0 +1,84 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +#include +#include + +#include "macro.h" + +char *strv_find(char **l, const char *name); +char *strv_find_prefix(char **l, const char *name); + +void strv_free(char **l); +void strv_freep(char ***l); +char **strv_copy(char **l) _malloc_; +unsigned strv_length(char **l); + +char **strv_merge(char **a, char **b); +char **strv_merge_concat(char **a, char **b, const char *suffix); +char **strv_append(char **l, const char *s); + +char **strv_remove(char **l, const char *s); +char **strv_remove_prefix(char **l, const char *s); +char **strv_uniq(char **l); + +#define strv_contains(l, s) (!!strv_find((l), (s))) + +char **strv_new(const char *x, ...) _sentinel_ _malloc_; +char **strv_new_ap(const char *x, va_list ap) _malloc_; + +static inline const char* STRV_IFNOTNULL(const char *x) { + return x ? x : (const char *) -1; +} + +static inline bool strv_isempty(char **l) { + return !l || !*l; +} + +char **strv_split(const char *s, const char *separator) _malloc_; +char **strv_split_quoted(const char *s) _malloc_; + +char *strv_join(char **l, const char *separator) _malloc_; + +char **strv_env_merge(unsigned n_lists, ...); +char **strv_env_delete(char **x, unsigned n_lists, ...); + +char **strv_env_set(char **x, const char *p); +char **strv_env_unset(char **l, const char *p); + +char *strv_env_get_with_length(char **l, const char *name, size_t k); +char *strv_env_get(char **x, const char *n); + +char **strv_env_clean(char **l); + +char **strv_parse_nulstr(const char *s, size_t l); + +bool strv_overlap(char **a, char **b); + +#define STRV_FOREACH(s, l) \ + for ((s) = (l); (s) && *(s); (s)++) + +#define STRV_FOREACH_BACKWARDS(s, l) \ + for (; (l) && ((s) >= (l)); (s)--) + +char **strv_sort(char **l); diff --git a/src/shared/time-dst.c b/src/shared/time-dst.c new file mode 100644 index 000000000..afc893ccc --- /dev/null +++ b/src/shared/time-dst.c @@ -0,0 +1,341 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Timezone file reading code from glibc 2.16. + + Copyright (C) 1991-2012 Free Software Foundation, Inc. + Copyright 2012 Kay Sievers + + 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 . +***/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "time-dst.h" + +/* + * If tzh_version is '2' or greater, the above is followed by a second instance + * of tzhead and a second instance of the data in which each coded transition + * time uses 8 rather than 4 chars, then a POSIX-TZ-environment-variable-style + * string for use in handling instants after the last transition time stored in + * the file * (with nothing between the newlines if there is no POSIX + * representation for such instants). + */ +#define TZ_MAGIC "TZif" +struct tzhead { + char tzh_magic[4]; /* TZ_MAGIC */ + char tzh_version[1]; /* '\0' or '2' as of 2005 */ + char tzh_reserved[15]; /* reserved--must be zero */ + char tzh_ttisgmtcnt[4]; /* coded number of trans. time flags */ + char tzh_ttisstdcnt[4]; /* coded number of trans. time flags */ + char tzh_leapcnt[4]; /* coded number of leap seconds */ + char tzh_timecnt[4]; /* coded number of transition times */ + char tzh_typecnt[4]; /* coded number of local time types */ + char tzh_charcnt[4]; /* coded number of abbr. chars */ +}; + +struct ttinfo { + long int offset; /* Seconds east of GMT. */ + unsigned char isdst; /* Used to set tm_isdst. */ + unsigned char idx; /* Index into `zone_names'. */ + unsigned char isstd; /* Transition times are in standard time. */ + unsigned char isgmt; /* Transition times are in GMT. */ +}; + +struct leap { + time_t transition; /* Time the transition takes effect. */ + long int change; /* Seconds of correction to apply. */ +}; + +static inline int decode(const void *ptr) { + return be32toh(*(int *)ptr); +} + +static inline int64_t decode64(const void *ptr) { + return be64toh(*(int64_t *)ptr); +} + +int time_get_dst(time_t date, const char *tzfile, + time_t *switch_cur, char **zone_cur, bool *dst_cur, + time_t *switch_next, int *delta_next, char **zone_next, bool *dst_next) { + time_t *transitions = NULL; + size_t num_transitions = 0; + unsigned char *type_idxs = 0; + size_t num_types = 0; + struct ttinfo *types = NULL; + char *zone_names = NULL; + struct stat st; + size_t num_isstd, num_isgmt; + FILE *f; + struct tzhead tzhead; + size_t chars; + size_t i; + size_t total_size; + size_t types_idx; + int trans_width = 4; + size_t tzspec_len; + size_t num_leaps; + size_t lo, hi; + int err = -EINVAL; + + f = fopen(tzfile, "re"); + if (f == NULL) + return -errno; + + if (fstat(fileno(f), &st) < 0) { + err = -errno; + fclose(f); + return err; + } + +read_again: + if (fread((void *)&tzhead, sizeof(tzhead), 1, f) != 1 || + memcmp(tzhead.tzh_magic, TZ_MAGIC, sizeof(tzhead.tzh_magic)) != 0) + goto lose; + + num_transitions = (size_t)decode(tzhead.tzh_timecnt); + num_types = (size_t)decode(tzhead.tzh_typecnt); + chars = (size_t)decode(tzhead.tzh_charcnt); + num_leaps = (size_t)decode(tzhead.tzh_leapcnt); + num_isstd = (size_t)decode(tzhead.tzh_ttisstdcnt); + num_isgmt = (size_t)decode(tzhead.tzh_ttisgmtcnt); + + /* For platforms with 64-bit time_t we use the new format if available. */ + if (sizeof(time_t) == 8 && trans_width == 4 && tzhead.tzh_version[0] != '\0') { + size_t to_skip; + + /* We use the 8-byte format. */ + trans_width = 8; + + /* Position the stream before the second header. */ + to_skip = (num_transitions * (4 + 1) + + num_types * 6 + + chars + + num_leaps * 8 + num_isstd + num_isgmt); + if (fseek(f, to_skip, SEEK_CUR) != 0) + goto lose; + + goto read_again; + } + + if (num_transitions > ((SIZE_MAX - (__alignof__(struct ttinfo) - 1)) / (sizeof(time_t) + 1))) + goto lose; + + total_size = num_transitions * (sizeof(time_t) + 1); + total_size = ((total_size + __alignof__(struct ttinfo) - 1) & ~(__alignof__(struct ttinfo) - 1)); + types_idx = total_size; + if (num_leaps > (SIZE_MAX - total_size) / sizeof(struct ttinfo)) + goto lose; + + total_size += num_types * sizeof(struct ttinfo); + if (chars > SIZE_MAX - total_size) + goto lose; + + total_size += chars; + if (__alignof__(struct leap) - 1 > SIZE_MAX - total_size) + goto lose; + + total_size = ((total_size + __alignof__(struct leap) - 1) & ~(__alignof__(struct leap) - 1)); + if (num_leaps > (SIZE_MAX - total_size) / sizeof(struct leap)) + goto lose; + + total_size += num_leaps * sizeof(struct leap); + tzspec_len = 0; + if (sizeof(time_t) == 8 && trans_width == 8) { + off_t rem = st.st_size - ftello(f); + + if (rem < 0 || (size_t) rem < (num_transitions * (8 + 1) + num_types * 6 + chars)) + goto lose; + tzspec_len = (size_t) rem - (num_transitions * (8 + 1) + num_types * 6 + chars); + if (num_leaps > SIZE_MAX / 12 || tzspec_len < num_leaps * 12) + goto lose; + tzspec_len -= num_leaps * 12; + if (tzspec_len < num_isstd) + goto lose; + tzspec_len -= num_isstd; + if (tzspec_len == 0 || tzspec_len - 1 < num_isgmt) + goto lose; + tzspec_len -= num_isgmt + 1; + if (SIZE_MAX - total_size < tzspec_len) + goto lose; + } + + transitions = (time_t *)calloc(total_size + tzspec_len, 1); + if (transitions == NULL) + goto lose; + + type_idxs = (unsigned char *)transitions + (num_transitions + * sizeof(time_t)); + types = (struct ttinfo *)((char *)transitions + types_idx); + zone_names = (char *)types + num_types * sizeof(struct ttinfo); + + if (sizeof(time_t) == 4 || trans_width == 8) { + if (fread(transitions, trans_width + 1, num_transitions, f) != num_transitions) + goto lose; + } else { + if (fread(transitions, 4, num_transitions, f) != num_transitions || + fread(type_idxs, 1, num_transitions, f) != num_transitions) + goto lose; + } + + /* Check for bogus indices in the data file, so we can hereafter + safely use type_idxs[T] as indices into `types' and never crash. */ + for (i = 0; i < num_transitions; ++i) + if (type_idxs[i] >= num_types) + goto lose; + + if ((BYTE_ORDER != BIG_ENDIAN && (sizeof(time_t) == 4 || trans_width == 4)) || + (BYTE_ORDER == BIG_ENDIAN && sizeof(time_t) == 8 && trans_width == 4)) { + /* Decode the transition times, stored as 4-byte integers in + network (big-endian) byte order. We work from the end of + the array so as not to clobber the next element to be + processed when sizeof (time_t) > 4. */ + i = num_transitions; + while (i-- > 0) + transitions[i] = decode((char *)transitions + i * 4); + } else if (BYTE_ORDER != BIG_ENDIAN && sizeof(time_t) == 8) { + /* Decode the transition times, stored as 8-byte integers in + network (big-endian) byte order. */ + for (i = 0; i < num_transitions; ++i) + transitions[i] = decode64((char *)transitions + i * 8); + } + + for (i = 0; i < num_types; ++i) { + unsigned char x[4]; + int c; + + if (fread(x, 1, sizeof(x), f) != sizeof(x)) + goto lose; + c = getc(f); + if ((unsigned int)c > 1u) + goto lose; + types[i].isdst = c; + c = getc(f); + if ((size_t) c > chars) + /* Bogus index in data file. */ + goto lose; + types[i].idx = c; + types[i].offset = (long int)decode(x); + } + + if (fread(zone_names, 1, chars, f) != chars) + goto lose; + + for (i = 0; i < num_isstd; ++i) { + int c = getc(f); + if (c == EOF) + goto lose; + types[i].isstd = c != 0; + } + + while (i < num_types) + types[i++].isstd = 0; + + for (i = 0; i < num_isgmt; ++i) { + int c = getc(f); + if (c == EOF) + goto lose; + types[i].isgmt = c != 0; + } + + while (i < num_types) + types[i++].isgmt = 0; + + if (num_transitions == 0) + goto lose; + + if (date < transitions[0] || date >= transitions[num_transitions - 1]) + goto lose; + + /* Find the first transition after TIMER, and + then pick the type of the transition before it. */ + lo = 0; + hi = num_transitions - 1; + + /* Assume that DST is changing twice a year and guess initial + search spot from it. + Half of a gregorian year has on average 365.2425 * 86400 / 2 + = 15778476 seconds. */ + i = (transitions[num_transitions - 1] - date) / 15778476; + if (i < num_transitions) { + i = num_transitions - 1 - i; + if (date < transitions[i]) { + if (i < 10 || date >= transitions[i - 10]) { + /* Linear search. */ + while (date < transitions[i - 1]) + i--; + goto found; + } + hi = i - 10; + } else { + if (i + 10 >= num_transitions || date < transitions[i + 10]) { + /* Linear search. */ + while (date >= transitions[i]) + i++; + goto found; + } + lo = i + 10; + } + } + + /* Binary search. */ + while (lo + 1 < hi) { + i = (lo + hi) / 2; + if (date < transitions[i]) + hi = i; + else + lo = i; + } + i = hi; + +found: + if (switch_cur) + *switch_cur = transitions[i-1]; + if (zone_cur) + *zone_cur = strdup(&zone_names[types[type_idxs[i - 1]].idx]); + if (dst_cur) + *dst_cur = types[type_idxs[i-1]].isdst; + + if (switch_next) + *switch_next = transitions[i]; + if (delta_next) + *delta_next = (types[type_idxs[i]].offset - types[type_idxs[i-1]].offset) / 60; + if (zone_next) + *zone_next = strdup(&zone_names[types[type_idxs[i]].idx]); + if (dst_next) + *dst_next = types[type_idxs[i]].isdst; + + free(transitions); + fclose(f); + return 0; +lose: + free(transitions); + fclose(f); + return err; +} diff --git a/src/shared/time-dst.h b/src/shared/time-dst.h new file mode 100644 index 000000000..536b6bbdf --- /dev/null +++ b/src/shared/time-dst.h @@ -0,0 +1,26 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2012 Kay Sievers + + 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 . +***/ + +int time_get_dst(time_t date, const char *tzfile, + time_t *switch_cur, char **zone_cur, bool *dst_cur, + time_t *switch_next, int *delta_next, char **zone_next, bool *dst_next); diff --git a/src/shared/time-util.c b/src/shared/time-util.c new file mode 100644 index 000000000..13d57ba5c --- /dev/null +++ b/src/shared/time-util.c @@ -0,0 +1,628 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include + +#include "util.h" +#include "time-util.h" + +usec_t now(clockid_t clock_id) { + struct timespec ts; + + assert_se(clock_gettime(clock_id, &ts) == 0); + + return timespec_load(&ts); +} + +dual_timestamp* dual_timestamp_get(dual_timestamp *ts) { + assert(ts); + + ts->realtime = now(CLOCK_REALTIME); + ts->monotonic = now(CLOCK_MONOTONIC); + + return ts; +} + +dual_timestamp* dual_timestamp_from_realtime(dual_timestamp *ts, usec_t u) { + int64_t delta; + assert(ts); + + ts->realtime = u; + + if (u == 0) + ts->monotonic = 0; + else { + delta = (int64_t) now(CLOCK_REALTIME) - (int64_t) u; + + ts->monotonic = now(CLOCK_MONOTONIC); + + if ((int64_t) ts->monotonic > delta) + ts->monotonic -= delta; + else + ts->monotonic = 0; + } + + return ts; +} + +usec_t timespec_load(const struct timespec *ts) { + assert(ts); + + if (ts->tv_sec == (time_t) -1 && + ts->tv_nsec == (long) -1) + return (usec_t) -1; + + if ((usec_t) ts->tv_sec > (UINT64_MAX - (ts->tv_nsec / NSEC_PER_USEC)) / USEC_PER_SEC) + return (usec_t) -1; + + return + (usec_t) ts->tv_sec * USEC_PER_SEC + + (usec_t) ts->tv_nsec / NSEC_PER_USEC; +} + +struct timespec *timespec_store(struct timespec *ts, usec_t u) { + assert(ts); + + if (u == (usec_t) -1) { + ts->tv_sec = (time_t) -1; + ts->tv_nsec = (long) -1; + return ts; + } + + ts->tv_sec = (time_t) (u / USEC_PER_SEC); + ts->tv_nsec = (long int) ((u % USEC_PER_SEC) * NSEC_PER_USEC); + + return ts; +} + +usec_t timeval_load(const struct timeval *tv) { + assert(tv); + + if (tv->tv_sec == (time_t) -1 && + tv->tv_usec == (suseconds_t) -1) + return (usec_t) -1; + + if ((usec_t) tv->tv_sec > (UINT64_MAX - tv->tv_usec) / USEC_PER_SEC) + return (usec_t) -1; + + return + (usec_t) tv->tv_sec * USEC_PER_SEC + + (usec_t) tv->tv_usec; +} + +struct timeval *timeval_store(struct timeval *tv, usec_t u) { + assert(tv); + + if (u == (usec_t) -1) { + tv->tv_sec = (time_t) -1; + tv->tv_usec = (suseconds_t) -1; + return tv; + } + + tv->tv_sec = (time_t) (u / USEC_PER_SEC); + tv->tv_usec = (suseconds_t) (u % USEC_PER_SEC); + + return tv; +} + +char *format_timestamp(char *buf, size_t l, usec_t t) { + struct tm tm; + time_t sec; + + assert(buf); + assert(l > 0); + + if (t <= 0) + return NULL; + + sec = (time_t) (t / USEC_PER_SEC); + + if (strftime(buf, l, "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&sec, &tm)) <= 0) + return NULL; + + return buf; +} + +char *format_timestamp_relative(char *buf, size_t l, usec_t t) { + usec_t n, d; + + n = now(CLOCK_REALTIME); + + if (t <= 0 || t > n || t + USEC_PER_DAY*7 <= t) + return NULL; + + d = n - t; + + if (d >= USEC_PER_YEAR) + snprintf(buf, l, "%llu years %llu months ago", + (unsigned long long) (d / USEC_PER_YEAR), + (unsigned long long) ((d % USEC_PER_YEAR) / USEC_PER_MONTH)); + else if (d >= USEC_PER_MONTH) + snprintf(buf, l, "%llu months %llu days ago", + (unsigned long long) (d / USEC_PER_MONTH), + (unsigned long long) ((d % USEC_PER_MONTH) / USEC_PER_DAY)); + else if (d >= USEC_PER_WEEK) + snprintf(buf, l, "%llu weeks %llu days ago", + (unsigned long long) (d / USEC_PER_WEEK), + (unsigned long long) ((d % USEC_PER_WEEK) / USEC_PER_DAY)); + else if (d >= 2*USEC_PER_DAY) + snprintf(buf, l, "%llu days ago", (unsigned long long) (d / USEC_PER_DAY)); + else if (d >= 25*USEC_PER_HOUR) + snprintf(buf, l, "1 day %lluh ago", + (unsigned long long) ((d - USEC_PER_DAY) / USEC_PER_HOUR)); + else if (d >= 6*USEC_PER_HOUR) + snprintf(buf, l, "%lluh ago", + (unsigned long long) (d / USEC_PER_HOUR)); + else if (d >= USEC_PER_HOUR) + snprintf(buf, l, "%lluh %llumin ago", + (unsigned long long) (d / USEC_PER_HOUR), + (unsigned long long) ((d % USEC_PER_HOUR) / USEC_PER_MINUTE)); + else if (d >= 5*USEC_PER_MINUTE) + snprintf(buf, l, "%llumin ago", + (unsigned long long) (d / USEC_PER_MINUTE)); + else if (d >= USEC_PER_MINUTE) + snprintf(buf, l, "%llumin %llus ago", + (unsigned long long) (d / USEC_PER_MINUTE), + (unsigned long long) ((d % USEC_PER_MINUTE) / USEC_PER_SEC)); + else if (d >= USEC_PER_SEC) + snprintf(buf, l, "%llus ago", + (unsigned long long) (d / USEC_PER_SEC)); + else if (d >= USEC_PER_MSEC) + snprintf(buf, l, "%llums ago", + (unsigned long long) (d / USEC_PER_MSEC)); + else if (d > 0) + snprintf(buf, l, "%lluus ago", + (unsigned long long) d); + else + snprintf(buf, l, "now"); + + buf[l-1] = 0; + return buf; +} + +char *format_timespan(char *buf, size_t l, usec_t t) { + static const struct { + const char *suffix; + usec_t usec; + } table[] = { + { "w", USEC_PER_WEEK }, + { "d", USEC_PER_DAY }, + { "h", USEC_PER_HOUR }, + { "min", USEC_PER_MINUTE }, + { "s", USEC_PER_SEC }, + { "ms", USEC_PER_MSEC }, + { "us", 1 }, + }; + + unsigned i; + char *p = buf; + + assert(buf); + assert(l > 0); + + if (t == (usec_t) -1) + return NULL; + + if (t == 0) { + snprintf(p, l, "0"); + p[l-1] = 0; + return p; + } + + /* The result of this function can be parsed with parse_usec */ + + for (i = 0; i < ELEMENTSOF(table); i++) { + int k; + size_t n; + + if (t < table[i].usec) + continue; + + if (l <= 1) + break; + + k = snprintf(p, l, "%s%llu%s", p > buf ? " " : "", (unsigned long long) (t / table[i].usec), table[i].suffix); + n = MIN((size_t) k, l); + + l -= n; + p += n; + + t %= table[i].usec; + } + + *p = 0; + + return buf; +} + +void dual_timestamp_serialize(FILE *f, const char *name, dual_timestamp *t) { + + assert(f); + assert(name); + assert(t); + + if (!dual_timestamp_is_set(t)) + return; + + fprintf(f, "%s=%llu %llu\n", + name, + (unsigned long long) t->realtime, + (unsigned long long) t->monotonic); +} + +void dual_timestamp_deserialize(const char *value, dual_timestamp *t) { + unsigned long long a, b; + + assert(value); + assert(t); + + if (sscanf(value, "%lli %llu", &a, &b) != 2) + log_debug("Failed to parse finish timestamp value %s", value); + else { + t->realtime = a; + t->monotonic = b; + } +} + +int parse_timestamp(const char *t, usec_t *usec) { + static const struct { + const char *name; + const int nr; + } day_nr[] = { + { "Sunday", 0 }, + { "Sun", 0 }, + { "Monday", 1 }, + { "Mon", 1 }, + { "Tuesday", 2 }, + { "Tue", 2 }, + { "Wednesday", 3 }, + { "Wed", 3 }, + { "Thursday", 4 }, + { "Thu", 4 }, + { "Friday", 5 }, + { "Fri", 5 }, + { "Saturday", 6 }, + { "Sat", 6 }, + }; + + const char *k; + struct tm tm, copy; + time_t x; + usec_t plus = 0, minus = 0, ret; + int r, weekday = -1; + unsigned i; + + /* + * Allowed syntaxes: + * + * 2012-09-22 16:34:22 + * 2012-09-22 16:34 (seconds will be set to 0) + * 2012-09-22 (time will be set to 00:00:00) + * 16:34:22 (date will be set to today) + * 16:34 (date will be set to today, seconds to 0) + * now + * yesterday (time is set to 00:00:00) + * today (time is set to 00:00:00) + * tomorrow (time is set to 00:00:00) + * +5min + * -5days + * + */ + + assert(t); + assert(usec); + + x = time(NULL); + assert_se(localtime_r(&x, &tm)); + tm.tm_isdst = -1; + + if (streq(t, "now")) + goto finish; + + else if (streq(t, "today")) { + tm.tm_sec = tm.tm_min = tm.tm_hour = 0; + goto finish; + + } else if (streq(t, "yesterday")) { + tm.tm_mday --; + tm.tm_sec = tm.tm_min = tm.tm_hour = 0; + goto finish; + + } else if (streq(t, "tomorrow")) { + tm.tm_mday ++; + tm.tm_sec = tm.tm_min = tm.tm_hour = 0; + goto finish; + + } else if (t[0] == '+') { + + r = parse_usec(t+1, &plus); + if (r < 0) + return r; + + goto finish; + } else if (t[0] == '-') { + + r = parse_usec(t+1, &minus); + if (r < 0) + return r; + + goto finish; + + } else if (endswith(t, " ago")) { + _cleanup_free_ char *z; + + z = strndup(t, strlen(t) - 4); + if (!z) + return -ENOMEM; + + r = parse_usec(z, &minus); + if (r < 0) + return r; + + goto finish; + } + + for (i = 0; i < ELEMENTSOF(day_nr); i++) { + size_t skip; + + if (!startswith_no_case(t, day_nr[i].name)) + continue; + + skip = strlen(day_nr[i].name); + if (t[skip] != ' ') + continue; + + weekday = day_nr[i].nr; + t += skip + 1; + break; + } + + copy = tm; + k = strptime(t, "%y-%m-%d %H:%M:%S", &tm); + if (k && *k == 0) + goto finish; + + tm = copy; + k = strptime(t, "%Y-%m-%d %H:%M:%S", &tm); + if (k && *k == 0) + goto finish; + + tm = copy; + k = strptime(t, "%y-%m-%d %H:%M", &tm); + if (k && *k == 0) { + tm.tm_sec = 0; + goto finish; + } + + tm = copy; + k = strptime(t, "%Y-%m-%d %H:%M", &tm); + if (k && *k == 0) { + tm.tm_sec = 0; + goto finish; + } + + tm = copy; + k = strptime(t, "%y-%m-%d", &tm); + if (k && *k == 0) { + tm.tm_sec = tm.tm_min = tm.tm_hour = 0; + goto finish; + } + + tm = copy; + k = strptime(t, "%Y-%m-%d", &tm); + if (k && *k == 0) { + tm.tm_sec = tm.tm_min = tm.tm_hour = 0; + goto finish; + } + + tm = copy; + k = strptime(t, "%H:%M:%S", &tm); + if (k && *k == 0) + goto finish; + + tm = copy; + k = strptime(t, "%H:%M", &tm); + if (k && *k == 0) { + tm.tm_sec = 0; + goto finish; + } + + return -EINVAL; + +finish: + x = mktime(&tm); + if (x == (time_t) -1) + return -EINVAL; + + if (weekday >= 0 && tm.tm_wday != weekday) + return -EINVAL; + + ret = (usec_t) x * USEC_PER_SEC; + + ret += plus; + if (ret > minus) + ret -= minus; + else + ret = 0; + + *usec = ret; + + return 0; +} + +int parse_usec(const char *t, usec_t *usec) { + static const struct { + const char *suffix; + usec_t usec; + } table[] = { + { "seconds", USEC_PER_SEC }, + { "second", USEC_PER_SEC }, + { "sec", USEC_PER_SEC }, + { "s", USEC_PER_SEC }, + { "minutes", USEC_PER_MINUTE }, + { "minute", USEC_PER_MINUTE }, + { "min", USEC_PER_MINUTE }, + { "months", USEC_PER_MONTH }, + { "month", USEC_PER_MONTH }, + { "msec", USEC_PER_MSEC }, + { "ms", USEC_PER_MSEC }, + { "m", USEC_PER_MINUTE }, + { "hours", USEC_PER_HOUR }, + { "hour", USEC_PER_HOUR }, + { "hr", USEC_PER_HOUR }, + { "h", USEC_PER_HOUR }, + { "days", USEC_PER_DAY }, + { "day", USEC_PER_DAY }, + { "d", USEC_PER_DAY }, + { "weeks", USEC_PER_WEEK }, + { "week", USEC_PER_WEEK }, + { "w", USEC_PER_WEEK }, + { "years", USEC_PER_YEAR }, + { "year", USEC_PER_YEAR }, + { "y", USEC_PER_YEAR }, + { "usec", 1ULL }, + { "us", 1ULL }, + { "", USEC_PER_SEC }, /* default is sec */ + }; + + const char *p; + usec_t r = 0; + + assert(t); + assert(usec); + + p = t; + do { + long long l; + char *e; + unsigned i; + + errno = 0; + l = strtoll(p, &e, 10); + + if (errno != 0) + return -errno; + + if (l < 0) + return -ERANGE; + + if (e == p) + return -EINVAL; + + e += strspn(e, WHITESPACE); + + for (i = 0; i < ELEMENTSOF(table); i++) + if (startswith(e, table[i].suffix)) { + r += (usec_t) l * table[i].usec; + p = e + strlen(table[i].suffix); + break; + } + + if (i >= ELEMENTSOF(table)) + return -EINVAL; + + } while (*p != 0); + + *usec = r; + + return 0; +} + +int parse_nsec(const char *t, nsec_t *nsec) { + static const struct { + const char *suffix; + nsec_t nsec; + } table[] = { + { "seconds", NSEC_PER_SEC }, + { "second", NSEC_PER_SEC }, + { "sec", NSEC_PER_SEC }, + { "s", NSEC_PER_SEC }, + { "minutes", NSEC_PER_MINUTE }, + { "minute", NSEC_PER_MINUTE }, + { "min", NSEC_PER_MINUTE }, + { "months", NSEC_PER_MONTH }, + { "month", NSEC_PER_MONTH }, + { "msec", NSEC_PER_MSEC }, + { "ms", NSEC_PER_MSEC }, + { "m", NSEC_PER_MINUTE }, + { "hours", NSEC_PER_HOUR }, + { "hour", NSEC_PER_HOUR }, + { "hr", NSEC_PER_HOUR }, + { "h", NSEC_PER_HOUR }, + { "days", NSEC_PER_DAY }, + { "day", NSEC_PER_DAY }, + { "d", NSEC_PER_DAY }, + { "weeks", NSEC_PER_WEEK }, + { "week", NSEC_PER_WEEK }, + { "w", NSEC_PER_WEEK }, + { "years", NSEC_PER_YEAR }, + { "year", NSEC_PER_YEAR }, + { "y", NSEC_PER_YEAR }, + { "usec", NSEC_PER_USEC }, + { "us", NSEC_PER_USEC }, + { "nsec", 1ULL }, + { "ns", 1ULL }, + { "", 1ULL }, /* default is nsec */ + }; + + const char *p; + nsec_t r = 0; + + assert(t); + assert(nsec); + + p = t; + do { + long long l; + char *e; + unsigned i; + + errno = 0; + l = strtoll(p, &e, 10); + + if (errno != 0) + return -errno; + + if (l < 0) + return -ERANGE; + + if (e == p) + return -EINVAL; + + e += strspn(e, WHITESPACE); + + for (i = 0; i < ELEMENTSOF(table); i++) + if (startswith(e, table[i].suffix)) { + r += (nsec_t) l * table[i].nsec; + p = e + strlen(table[i].suffix); + break; + } + + if (i >= ELEMENTSOF(table)) + return -EINVAL; + + } while (*p != 0); + + *nsec = r; + + return 0; +} diff --git a/src/shared/time-util.h b/src/shared/time-util.h new file mode 100644 index 000000000..7194875ec --- /dev/null +++ b/src/shared/time-util.h @@ -0,0 +1,83 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +#include + +typedef uint64_t usec_t; +typedef uint64_t nsec_t; + +#include "macro.h" + +typedef struct dual_timestamp { + usec_t realtime; + usec_t monotonic; +} dual_timestamp; + +#define MSEC_PER_SEC 1000ULL +#define USEC_PER_SEC 1000000ULL +#define USEC_PER_MSEC 1000ULL +#define NSEC_PER_SEC 1000000000ULL +#define NSEC_PER_MSEC 1000000ULL +#define NSEC_PER_USEC 1000ULL + +#define USEC_PER_MINUTE (60ULL*USEC_PER_SEC) +#define NSEC_PER_MINUTE (60ULL*NSEC_PER_SEC) +#define USEC_PER_HOUR (60ULL*USEC_PER_MINUTE) +#define NSEC_PER_HOUR (60ULL*NSEC_PER_MINUTE) +#define USEC_PER_DAY (24ULL*USEC_PER_HOUR) +#define NSEC_PER_DAY (24ULL*NSEC_PER_HOUR) +#define USEC_PER_WEEK (7ULL*USEC_PER_DAY) +#define NSEC_PER_WEEK (7ULL*NSEC_PER_DAY) +#define USEC_PER_MONTH (2629800ULL*USEC_PER_SEC) +#define NSEC_PER_MONTH (2629800ULL*NSEC_PER_SEC) +#define USEC_PER_YEAR (31557600ULL*USEC_PER_SEC) +#define NSEC_PER_YEAR (31557600ULL*NSEC_PER_SEC) + +#define FORMAT_TIMESTAMP_MAX ((4*4+1)+11+9+4+1) /* weekdays can be unicode */ +#define FORMAT_TIMESTAMP_RELATIVE_MAX 256 +#define FORMAT_TIMESPAN_MAX 64 + +usec_t now(clockid_t clock); + +dual_timestamp* dual_timestamp_get(dual_timestamp *ts); +dual_timestamp* dual_timestamp_from_realtime(dual_timestamp *ts, usec_t u); + +#define dual_timestamp_is_set(ts) ((ts)->realtime > 0) + +usec_t timespec_load(const struct timespec *ts); +struct timespec *timespec_store(struct timespec *ts, usec_t u); + +usec_t timeval_load(const struct timeval *tv); +struct timeval *timeval_store(struct timeval *tv, usec_t u); + +char *format_timestamp(char *buf, size_t l, usec_t t); +char *format_timestamp_relative(char *buf, size_t l, usec_t t); +char *format_timespan(char *buf, size_t l, usec_t t); + +void dual_timestamp_serialize(FILE *f, const char *name, dual_timestamp *t); +void dual_timestamp_deserialize(const char *value, dual_timestamp *t); + +int parse_timestamp(const char *t, usec_t *usec); + +int parse_usec(const char *t, usec_t *usec); +int parse_nsec(const char *t, nsec_t *nsec); diff --git a/src/shared/unit-name.c b/src/shared/unit-name.c new file mode 100644 index 000000000..88ca0b8f2 --- /dev/null +++ b/src/shared/unit-name.c @@ -0,0 +1,519 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include + +#include "path-util.h" +#include "util.h" +#include "unit-name.h" + +#define VALID_CHARS \ + "0123456789" \ + "abcdefghijklmnopqrstuvwxyz" \ + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \ + ":-_.\\" + +const char* const unit_type_table[_UNIT_TYPE_MAX] = { + [UNIT_SERVICE] = "service", + [UNIT_SOCKET] = "socket", + [UNIT_TARGET] = "target", + [UNIT_DEVICE] = "device", + [UNIT_MOUNT] = "mount", + [UNIT_AUTOMOUNT] = "automount", + [UNIT_SNAPSHOT] = "snapshot", + [UNIT_TIMER] = "timer", + [UNIT_SWAP] = "swap", + [UNIT_PATH] = "path", +}; + +DEFINE_STRING_TABLE_LOOKUP(unit_type, UnitType); + +const char* const unit_load_state_table[_UNIT_LOAD_STATE_MAX] = { + [UNIT_STUB] = "stub", + [UNIT_LOADED] = "loaded", + [UNIT_ERROR] = "error", + [UNIT_MERGED] = "merged", + [UNIT_MASKED] = "masked" +}; + +DEFINE_STRING_TABLE_LOOKUP(unit_load_state, UnitLoadState); + +bool unit_name_is_valid(const char *n, bool template_ok) { + const char *e, *i, *at; + + /* Valid formats: + * + * string@instance.suffix + * string.suffix + */ + + assert(n); + + if (strlen(n) >= UNIT_NAME_MAX) + return false; + + e = strrchr(n, '.'); + if (!e || e == n) + return false; + + if (unit_type_from_string(e + 1) < 0) + return false; + + for (i = n, at = NULL; i < e; i++) { + + if (*i == '@' && !at) + at = i; + + if (!strchr("@" VALID_CHARS, *i)) + return false; + } + + if (at) { + if (at == n) + return false; + + if (!template_ok && at+1 == e) + return false; + } + + return true; +} + +bool unit_instance_is_valid(const char *i) { + assert(i); + + /* The max length depends on the length of the string, so we + * don't really check this here. */ + + if (i[0] == 0) + return false; + + /* We allow additional @ in the instance string, we do not + * allow them in the prefix! */ + + for (; *i; i++) + if (!strchr("@" VALID_CHARS, *i)) + return false; + + return true; +} + +bool unit_prefix_is_valid(const char *p) { + + /* We don't allow additional @ in the instance string */ + + if (p[0] == 0) + return false; + + for (; *p; p++) + if (!strchr(VALID_CHARS, *p)) + return false; + + return true; +} + +int unit_name_to_instance(const char *n, char **instance) { + const char *p, *d; + char *i; + + assert(n); + assert(instance); + + /* Everything past the first @ and before the last . is the instance */ + p = strchr(n, '@'); + if (!p) { + *instance = NULL; + return 0; + } + + assert_se(d = strrchr(n, '.')); + assert(p < d); + + i = strndup(p+1, d-p-1); + if (!i) + return -ENOMEM; + + *instance = i; + return 0; +} + +char *unit_name_to_prefix_and_instance(const char *n) { + const char *d; + + assert(n); + + assert_se(d = strrchr(n, '.')); + + return strndup(n, d - n); +} + +char *unit_name_to_prefix(const char *n) { + const char *p; + + p = strchr(n, '@'); + if (p) + return strndup(n, p - n); + + return unit_name_to_prefix_and_instance(n); +} + +char *unit_name_change_suffix(const char *n, const char *suffix) { + char *e, *r; + size_t a, b; + + assert(n); + assert(unit_name_is_valid(n, true)); + assert(suffix); + + assert_se(e = strrchr(n, '.')); + a = e - n; + b = strlen(suffix); + + r = new(char, a + b + 1); + if (!r) + return NULL; + + memcpy(r, n, a); + memcpy(r+a, suffix, b+1); + + return r; +} + +char *unit_name_build(const char *prefix, const char *instance, const char *suffix) { + assert(prefix); + assert(unit_prefix_is_valid(prefix)); + assert(!instance || unit_instance_is_valid(instance)); + assert(suffix); + + if (!instance) + return strappend(prefix, suffix); + + return strjoin(prefix, "@", instance, suffix, NULL); +} + +static char *do_escape_char(char c, char *t) { + *(t++) = '\\'; + *(t++) = 'x'; + *(t++) = hexchar(c >> 4); + *(t++) = hexchar(c); + return t; +} + +static char *do_escape(const char *f, char *t) { + assert(f); + assert(t); + + /* do not create units with a leading '.', like for "/.dotdir" mount points */ + if (*f == '.') { + t = do_escape_char(*f, t); + f++; + } + + for (; *f; f++) { + if (*f == '/') + *(t++) = '-'; + else if (*f == '-' || *f == '\\' || !strchr(VALID_CHARS, *f)) + t = do_escape_char(*f, t); + else + *(t++) = *f; + } + + return t; +} + +char *unit_name_escape(const char *f) { + char *r, *t; + + r = new(char, strlen(f)*4+1); + if (!r) + return NULL; + + t = do_escape(f, r); + *t = 0; + + return r; +} + +char *unit_name_unescape(const char *f) { + char *r, *t; + + assert(f); + + r = strdup(f); + if (!r) + return NULL; + + for (t = r; *f; f++) { + if (*f == '-') + *(t++) = '/'; + else if (*f == '\\') { + int a, b; + + if (f[1] != 'x' || + (a = unhexchar(f[2])) < 0 || + (b = unhexchar(f[3])) < 0) { + /* Invalid escape code, let's take it literal then */ + *(t++) = '\\'; + } else { + *(t++) = (char) ((a << 4) | b); + f += 3; + } + } else + *(t++) = *f; + } + + *t = 0; + + return r; +} + +char *unit_name_path_escape(const char *f) { + char *p, *e; + + assert(f); + + p = strdup(f); + if (!p) + return NULL; + + path_kill_slashes(p); + + if (streq(p, "/")) { + free(p); + return strdup("-"); + } + + e = unit_name_escape(p[0] == '/' ? p + 1 : p); + free(p); + + return e; +} + +char *unit_name_path_unescape(const char *f) { + char *e; + + assert(f); + + e = unit_name_unescape(f); + if (!e) + return NULL; + + if (e[0] != '/') { + char *w; + + w = strappend("/", e); + free(e); + + return w; + } + + return e; +} + +bool unit_name_is_template(const char *n) { + const char *p; + + assert(n); + + p = strchr(n, '@'); + if (!p) + return false; + + return p[1] == '.'; +} + +bool unit_name_is_instance(const char *n) { + const char *p; + + assert(n); + + p = strchr(n, '@'); + if (!p) + return false; + + return p[1] != '.'; +} + +char *unit_name_replace_instance(const char *f, const char *i) { + const char *p, *e; + char *r, *k; + size_t a, b; + + assert(f); + + p = strchr(f, '@'); + if (!p) + return strdup(f); + + e = strrchr(f, '.'); + if (!e) + assert_se(e = strchr(f, 0)); + + a = p - f; + b = strlen(i); + + r = new(char, a + 1 + b + strlen(e) + 1); + if (!r) + return NULL; + + k = mempcpy(r, f, a + 1); + k = mempcpy(k, i, b); + strcpy(k, e); + + return r; +} + +char *unit_name_template(const char *f) { + const char *p, *e; + char *r; + size_t a; + + p = strchr(f, '@'); + if (!p) + return strdup(f); + + assert_se(e = strrchr(f, '.')); + a = p - f + 1; + + r = new(char, a + strlen(e) + 1); + if (!r) + return NULL; + + strcpy(mempcpy(r, f, a), e); + return r; + +} + +char *unit_name_from_path(const char *path, const char *suffix) { + char *p, *r; + + assert(path); + assert(suffix); + + p = unit_name_path_escape(path); + if (!p) + return NULL; + + r = strappend(p, suffix); + free(p); + + return r; +} + +char *unit_name_from_path_instance(const char *prefix, const char *path, const char *suffix) { + char *p, *r; + + assert(prefix); + assert(path); + assert(suffix); + + p = unit_name_path_escape(path); + if (!p) + return NULL; + + r = strjoin(prefix, "@", p, suffix, NULL); + free(p); + + return r; +} + +char *unit_name_to_path(const char *name) { + char *w, *e; + + assert(name); + + w = unit_name_to_prefix(name); + if (!w) + return NULL; + + e = unit_name_path_unescape(w); + free(w); + + return e; +} + +char *unit_dbus_path_from_name(const char *name) { + char *e, *p; + + assert(name); + + e = bus_path_escape(name); + if (!e) + return NULL; + + p = strappend("/org/freedesktop/systemd1/unit/", e); + free(e); + + return p; +} + +char *unit_name_mangle(const char *name) { + char *r, *t; + const char *f; + + assert(name); + + /* Try to turn a string that might not be a unit name into a + * sensible unit name. */ + + if (is_device_path(name)) + return unit_name_from_path(name, ".device"); + + if (path_is_absolute(name)) + return unit_name_from_path(name, ".mount"); + + /* We'll only escape the obvious characters here, to play + * safe. */ + + r = new(char, strlen(name) * 4 + 1 + sizeof(".service")-1); + if (!r) + return NULL; + + for (f = name, t = r; *f; f++) { + if (*f == '/') + *(t++) = '-'; + else if (!strchr("@" VALID_CHARS, *f)) + t = do_escape_char(*f, t); + else + *(t++) = *f; + } + + if (unit_name_to_type(name) < 0) + strcpy(t, ".service"); + else + *t = 0; + + return r; +} + +UnitType unit_name_to_type(const char *n) { + const char *e; + + assert(n); + + e = strrchr(n, '.'); + if (!e) + return _UNIT_TYPE_INVALID; + + return unit_type_from_string(e + 1); +} diff --git a/src/shared/unit-name.h b/src/shared/unit-name.h new file mode 100644 index 000000000..d7528a3ac --- /dev/null +++ b/src/shared/unit-name.h @@ -0,0 +1,96 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +#include + +#define UNIT_NAME_MAX 256 + +typedef enum UnitType UnitType; +typedef enum UnitLoadState UnitLoadState; + +enum UnitType { + UNIT_SERVICE = 0, + UNIT_SOCKET, + UNIT_TARGET, + UNIT_DEVICE, + UNIT_MOUNT, + UNIT_AUTOMOUNT, + UNIT_SNAPSHOT, + UNIT_TIMER, + UNIT_SWAP, + UNIT_PATH, + _UNIT_TYPE_MAX, + _UNIT_TYPE_INVALID = -1 +}; + +enum UnitLoadState { + UNIT_STUB = 0, + UNIT_LOADED, + UNIT_ERROR, + UNIT_MERGED, + UNIT_MASKED, + _UNIT_LOAD_STATE_MAX, + _UNIT_LOAD_STATE_INVALID = -1 +}; + +extern const char* const unit_type_table[]; +const char *unit_type_to_string(UnitType i); +UnitType unit_type_from_string(const char *s); + +extern const char* const unit_load_state_table[]; +const char *unit_load_state_to_string(UnitLoadState i); +UnitLoadState unit_load_state_from_string(const char *s); + +int unit_name_to_instance(const char *n, char **instance); +char* unit_name_to_prefix(const char *n); +char* unit_name_to_prefix_and_instance(const char *n); + +bool unit_name_is_valid(const char *n, bool template_ok); +bool unit_prefix_is_valid(const char *p); +bool unit_instance_is_valid(const char *i); + +UnitType unit_name_to_type(const char *n); + +char *unit_name_change_suffix(const char *n, const char *suffix); + +char *unit_name_build(const char *prefix, const char *instance, const char *suffix); + +char *unit_name_escape(const char *f); +char *unit_name_unescape(const char *f); +char *unit_name_path_escape(const char *f); +char *unit_name_path_unescape(const char *f); + +bool unit_name_is_template(const char *n); +bool unit_name_is_instance(const char *n); + +char *unit_name_replace_instance(const char *f, const char *i); + +char *unit_name_template(const char *f); + +char *unit_name_from_path(const char *path, const char *suffix); +char *unit_name_from_path_instance(const char *prefix, const char *path, const char *suffix); +char *unit_name_to_path(const char *name); + +char *unit_dbus_path_from_name(const char *name); + +char *unit_name_mangle(const char *name); diff --git a/src/shared/utf8.c b/src/shared/utf8.c new file mode 100644 index 000000000..62e280391 --- /dev/null +++ b/src/shared/utf8.c @@ -0,0 +1,285 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + +/* This file is based on the GLIB utf8 validation functions. The + * original license text follows. */ + +/* gutf8.c - Operations on UTF-8 strings. + * + * Copyright (C) 1999 Tom Tromey + * Copyright (C) 2000 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include + +#include "utf8.h" + +#define FILTER_CHAR '_' + +static inline bool is_unicode_valid(uint32_t ch) { + + if (ch >= 0x110000) /* End of unicode space */ + return false; + if ((ch & 0xFFFFF800) == 0xD800) /* Reserved area for UTF-16 */ + return false; + if ((ch >= 0xFDD0) && (ch <= 0xFDEF)) /* Reserved */ + return false; + if ((ch & 0xFFFE) == 0xFFFE) /* BOM (Byte Order Mark) */ + return false; + + return true; +} + +static inline bool is_continuation_char(uint8_t ch) { + if ((ch & 0xc0) != 0x80) /* 10xxxxxx */ + return false; + return true; +} + +static inline void merge_continuation_char(uint32_t *u_ch, uint8_t ch) { + *u_ch <<= 6; + *u_ch |= ch & 0x3f; +} + +static bool is_unicode_control(uint32_t ch) { + + /* + 0 to ' '-1 is the C0 range. + DEL=0x7F, and DEL+1 to 0x9F is C1 range. + '\t' is in C0 range, but more or less harmless and commonly used. + */ + + return (ch < ' ' && ch != '\t') || + (0x7F <= ch && ch <= 0x9F); +} + +char* utf8_is_printable_n(const char* str, size_t length) { + uint32_t val = 0; + uint32_t min = 0; + const uint8_t *p; + + assert(str); + + for (p = (const uint8_t*) str; length; p++, length--) { + if (*p < 128) { + val = *p; + } else { + if ((*p & 0xe0) == 0xc0) { /* 110xxxxx two-char seq. */ + min = 128; + val = (uint32_t) (*p & 0x1e); + goto ONE_REMAINING; + } else if ((*p & 0xf0) == 0xe0) { /* 1110xxxx three-char seq.*/ + min = (1 << 11); + val = (uint32_t) (*p & 0x0f); + goto TWO_REMAINING; + } else if ((*p & 0xf8) == 0xf0) { /* 11110xxx four-char seq */ + min = (1 << 16); + val = (uint32_t) (*p & 0x07); + } else + goto error; + + p++; + length--; + if (!length || !is_continuation_char(*p)) + goto error; + merge_continuation_char(&val, *p); + + TWO_REMAINING: + p++; + length--; + if (!is_continuation_char(*p)) + goto error; + merge_continuation_char(&val, *p); + + ONE_REMAINING: + p++; + length--; + if (!is_continuation_char(*p)) + goto error; + merge_continuation_char(&val, *p); + + if (val < min) + goto error; + } + + if (is_unicode_control(val)) + goto error; + } + + return (char*) str; + +error: + return NULL; +} + +static char* utf8_validate(const char *str, char *output) { + uint32_t val = 0; + uint32_t min = 0; + const uint8_t *p, *last; + int size; + uint8_t *o; + + assert(str); + + o = (uint8_t*) output; + for (p = (const uint8_t*) str; *p; p++) { + if (*p < 128) { + if (o) + *o = *p; + } else { + last = p; + + if ((*p & 0xe0) == 0xc0) { /* 110xxxxx two-char seq. */ + size = 2; + min = 128; + val = (uint32_t) (*p & 0x1e); + goto ONE_REMAINING; + } else if ((*p & 0xf0) == 0xe0) { /* 1110xxxx three-char seq.*/ + size = 3; + min = (1 << 11); + val = (uint32_t) (*p & 0x0f); + goto TWO_REMAINING; + } else if ((*p & 0xf8) == 0xf0) { /* 11110xxx four-char seq */ + size = 4; + min = (1 << 16); + val = (uint32_t) (*p & 0x07); + } else + goto error; + + p++; + if (!is_continuation_char(*p)) + goto error; + merge_continuation_char(&val, *p); + + TWO_REMAINING: + p++; + if (!is_continuation_char(*p)) + goto error; + merge_continuation_char(&val, *p); + + ONE_REMAINING: + p++; + if (!is_continuation_char(*p)) + goto error; + merge_continuation_char(&val, *p); + + if (val < min) + goto error; + + if (!is_unicode_valid(val)) + goto error; + + if (o) { + memcpy(o, last, (size_t) size); + o += size; + } + + continue; + + error: + if (o) { + *o = FILTER_CHAR; + p = last; /* We retry at the next character */ + } else + goto failure; + } + + if (o) + o++; + } + + if (o) { + *o = '\0'; + return output; + } + + return (char*) str; + +failure: + return NULL; +} + +char* utf8_is_valid (const char *str) { + return utf8_validate(str, NULL); +} + +char* utf8_filter (const char *str) { + char *new_str; + + assert(str); + + new_str = malloc(strlen(str) + 1); + if (!new_str) + return NULL; + + return utf8_validate(str, new_str); +} + +char *ascii_is_valid(const char *str) { + const char *p; + + assert(str); + + for (p = str; *p; p++) + if ((unsigned char) *p >= 128) + return NULL; + + return (char*) str; +} + +char *ascii_filter(const char *str) { + const char *s; + char *r, *d; + size_t l; + + assert(str); + + l = strlen(str); + r = malloc(l + 1); + if (!r) + return NULL; + + for (s = str, d = r; *s; s++) + if ((unsigned char) *s < 128) + *(d++) = *s; + + *d = 0; + + return r; +} diff --git a/src/shared/utf8.h b/src/shared/utf8.h new file mode 100644 index 000000000..13d2f6a98 --- /dev/null +++ b/src/shared/utf8.h @@ -0,0 +1,32 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + +#include "macro.h" + +char *utf8_is_valid(const char *s) _pure_; +char *ascii_is_valid(const char *s) _pure_; + +char *utf8_is_printable_n(const char* str, size_t length) _pure_; + +char *utf8_filter(const char *s); +char *ascii_filter(const char *s); diff --git a/src/shared/util.c b/src/shared/util.c new file mode 100644 index 000000000..49b58444c --- /dev/null +++ b/src/shared/util.c @@ -0,0 +1,5843 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "macro.h" +#include "util.h" +#include "ioprio.h" +#include "missing.h" +#include "log.h" +#include "strv.h" +#include "label.h" +#include "path-util.h" +#include "exit-status.h" +#include "hashmap.h" + +int saved_argc = 0; +char **saved_argv = NULL; + +static volatile unsigned cached_columns = 0; +static volatile unsigned cached_lines = 0; + +bool is_efiboot(void) { + return access("/sys/firmware/efi", F_OK) >= 0; +} + +size_t page_size(void) { + static __thread size_t pgsz = 0; + long r; + + if (_likely_(pgsz > 0)) + return pgsz; + + r = sysconf(_SC_PAGESIZE); + assert(r > 0); + + pgsz = (size_t) r; + return pgsz; +} + +bool streq_ptr(const char *a, const char *b) { + + /* Like streq(), but tries to make sense of NULL pointers */ + + if (a && b) + return streq(a, b); + + if (!a && !b) + return true; + + return false; +} + +char* endswith(const char *s, const char *postfix) { + size_t sl, pl; + + assert(s); + assert(postfix); + + sl = strlen(s); + pl = strlen(postfix); + + if (pl == 0) + return (char*) s + sl; + + if (sl < pl) + return NULL; + + if (memcmp(s + sl - pl, postfix, pl) != 0) + return NULL; + + return (char*) s + sl - pl; +} + +char* startswith(const char *s, const char *prefix) { + const char *a, *b; + + assert(s); + assert(prefix); + + a = s, b = prefix; + for (;;) { + if (*b == 0) + return (char*) a; + if (*a != *b) + return NULL; + + a++, b++; + } +} + +char* startswith_no_case(const char *s, const char *prefix) { + const char *a, *b; + + assert(s); + assert(prefix); + + a = s, b = prefix; + for (;;) { + if (*b == 0) + return (char*) a; + if (tolower(*a) != tolower(*b)) + return NULL; + + a++, b++; + } +} + +bool first_word(const char *s, const char *word) { + size_t sl, wl; + + assert(s); + assert(word); + + sl = strlen(s); + wl = strlen(word); + + if (sl < wl) + return false; + + if (wl == 0) + return true; + + if (memcmp(s, word, wl) != 0) + return false; + + return s[wl] == 0 || + strchr(WHITESPACE, s[wl]); +} + +int close_nointr(int fd) { + assert(fd >= 0); + + for (;;) { + int r; + + r = close(fd); + if (r >= 0) + return r; + + if (errno != EINTR) + return -errno; + } +} + +void close_nointr_nofail(int fd) { + int saved_errno = errno; + + /* like close_nointr() but cannot fail, and guarantees errno + * is unchanged */ + + assert_se(close_nointr(fd) == 0); + + errno = saved_errno; +} + +void close_many(const int fds[], unsigned n_fd) { + unsigned i; + + for (i = 0; i < n_fd; i++) + close_nointr_nofail(fds[i]); +} + +int parse_boolean(const char *v) { + assert(v); + + if (streq(v, "1") || v[0] == 'y' || v[0] == 'Y' || v[0] == 't' || v[0] == 'T' || !strcasecmp(v, "on")) + return 1; + else if (streq(v, "0") || v[0] == 'n' || v[0] == 'N' || v[0] == 'f' || v[0] == 'F' || !strcasecmp(v, "off")) + return 0; + + return -EINVAL; +} + +int parse_pid(const char *s, pid_t* ret_pid) { + unsigned long ul = 0; + pid_t pid; + int r; + + assert(s); + assert(ret_pid); + + r = safe_atolu(s, &ul); + if (r < 0) + return r; + + pid = (pid_t) ul; + + if ((unsigned long) pid != ul) + return -ERANGE; + + if (pid <= 0) + return -ERANGE; + + *ret_pid = pid; + return 0; +} + +int parse_uid(const char *s, uid_t* ret_uid) { + unsigned long ul = 0; + uid_t uid; + int r; + + assert(s); + assert(ret_uid); + + r = safe_atolu(s, &ul); + if (r < 0) + return r; + + uid = (uid_t) ul; + + if ((unsigned long) uid != ul) + return -ERANGE; + + *ret_uid = uid; + return 0; +} + +int safe_atou(const char *s, unsigned *ret_u) { + char *x = NULL; + unsigned long l; + + assert(s); + assert(ret_u); + + errno = 0; + l = strtoul(s, &x, 0); + + if (!x || x == s || *x || errno) + return errno ? -errno : -EINVAL; + + if ((unsigned long) (unsigned) l != l) + return -ERANGE; + + *ret_u = (unsigned) l; + return 0; +} + +int safe_atoi(const char *s, int *ret_i) { + char *x = NULL; + long l; + + assert(s); + assert(ret_i); + + errno = 0; + l = strtol(s, &x, 0); + + if (!x || x == s || *x || errno) + return errno ? -errno : -EINVAL; + + if ((long) (int) l != l) + return -ERANGE; + + *ret_i = (int) l; + return 0; +} + +int safe_atollu(const char *s, long long unsigned *ret_llu) { + char *x = NULL; + unsigned long long l; + + assert(s); + assert(ret_llu); + + errno = 0; + l = strtoull(s, &x, 0); + + if (!x || x == s || *x || errno) + return errno ? -errno : -EINVAL; + + *ret_llu = l; + return 0; +} + +int safe_atolli(const char *s, long long int *ret_lli) { + char *x = NULL; + long long l; + + assert(s); + assert(ret_lli); + + errno = 0; + l = strtoll(s, &x, 0); + + if (!x || x == s || *x || errno) + return errno ? -errno : -EINVAL; + + *ret_lli = l; + return 0; +} + +/* Split a string into words. */ +char *split(const char *c, size_t *l, const char *separator, char **state) { + char *current; + + current = *state ? *state : (char*) c; + + if (!*current || *c == 0) + return NULL; + + current += strspn(current, separator); + *l = strcspn(current, separator); + *state = current+*l; + + return (char*) current; +} + +/* Split a string into words, but consider strings enclosed in '' and + * "" as words even if they include spaces. */ +char *split_quoted(const char *c, size_t *l, char **state) { + char *current, *e; + bool escaped = false; + + current = *state ? *state : (char*) c; + + if (!*current || *c == 0) + return NULL; + + current += strspn(current, WHITESPACE); + + if (*current == '\'') { + current ++; + + for (e = current; *e; e++) { + if (escaped) + escaped = false; + else if (*e == '\\') + escaped = true; + else if (*e == '\'') + break; + } + + *l = e-current; + *state = *e == 0 ? e : e+1; + } else if (*current == '\"') { + current ++; + + for (e = current; *e; e++) { + if (escaped) + escaped = false; + else if (*e == '\\') + escaped = true; + else if (*e == '\"') + break; + } + + *l = e-current; + *state = *e == 0 ? e : e+1; + } else { + for (e = current; *e; e++) { + if (escaped) + escaped = false; + else if (*e == '\\') + escaped = true; + else if (strchr(WHITESPACE, *e)) + break; + } + *l = e-current; + *state = e; + } + + return (char*) current; +} + +int get_parent_of_pid(pid_t pid, pid_t *_ppid) { + int r; + _cleanup_fclose_ FILE *f = NULL; + char fn[PATH_MAX], line[LINE_MAX], *p; + long unsigned ppid; + + assert(pid > 0); + assert(_ppid); + + assert_se(snprintf(fn, sizeof(fn)-1, "/proc/%lu/stat", (unsigned long) pid) < (int) (sizeof(fn)-1)); + char_array_0(fn); + + f = fopen(fn, "re"); + if (!f) + return -errno; + + if (!fgets(line, sizeof(line), f)) { + r = feof(f) ? -EIO : -errno; + fclose(f); + return r; + } + + /* Let's skip the pid and comm fields. The latter is enclosed + * in () but does not escape any () in its value, so let's + * skip over it manually */ + + p = strrchr(line, ')'); + if (!p) + return -EIO; + + p++; + + if (sscanf(p, " " + "%*c " /* state */ + "%lu ", /* ppid */ + &ppid) != 1) + return -EIO; + + if ((long unsigned) (pid_t) ppid != ppid) + return -ERANGE; + + *_ppid = (pid_t) ppid; + + return 0; +} + +int get_starttime_of_pid(pid_t pid, unsigned long long *st) { + _cleanup_fclose_ FILE *f = NULL; + char fn[PATH_MAX], line[LINE_MAX], *p; + + assert(pid > 0); + assert(st); + + assert_se(snprintf(fn, sizeof(fn)-1, "/proc/%lu/stat", (unsigned long) pid) < (int) (sizeof(fn)-1)); + char_array_0(fn); + + f = fopen(fn, "re"); + if (!f) + return -errno; + + if (!fgets(line, sizeof(line), f)) { + if (ferror(f)) + return -errno; + + return -EIO; + } + + /* Let's skip the pid and comm fields. The latter is enclosed + * in () but does not escape any () in its value, so let's + * skip over it manually */ + + p = strrchr(line, ')'); + if (!p) + return -EIO; + + p++; + + if (sscanf(p, " " + "%*c " /* state */ + "%*d " /* ppid */ + "%*d " /* pgrp */ + "%*d " /* session */ + "%*d " /* tty_nr */ + "%*d " /* tpgid */ + "%*u " /* flags */ + "%*u " /* minflt */ + "%*u " /* cminflt */ + "%*u " /* majflt */ + "%*u " /* cmajflt */ + "%*u " /* utime */ + "%*u " /* stime */ + "%*d " /* cutime */ + "%*d " /* cstime */ + "%*d " /* priority */ + "%*d " /* nice */ + "%*d " /* num_threads */ + "%*d " /* itrealvalue */ + "%llu " /* starttime */, + st) != 1) + return -EIO; + + return 0; +} + +int write_one_line_file(const char *fn, const char *line) { + _cleanup_fclose_ FILE *f = NULL; + + assert(fn); + assert(line); + + f = fopen(fn, "we"); + if (!f) + return -errno; + + errno = 0; + if (fputs(line, f) < 0) + return errno ? -errno : -EIO; + + if (!endswith(line, "\n")) + fputc('\n', f); + + fflush(f); + + if (ferror(f)) + return errno ? -errno : -EIO; + + return 0; +} + +int fchmod_umask(int fd, mode_t m) { + mode_t u; + int r; + + u = umask(0777); + r = fchmod(fd, m & (~u)) < 0 ? -errno : 0; + umask(u); + + return r; +} + +int write_one_line_file_atomic(const char *fn, const char *line) { + FILE *f; + int r; + char *p; + + assert(fn); + assert(line); + + r = fopen_temporary(fn, &f, &p); + if (r < 0) + return r; + + fchmod_umask(fileno(f), 0644); + + errno = 0; + if (fputs(line, f) < 0) { + r = -errno; + goto finish; + } + + if (!endswith(line, "\n")) + fputc('\n', f); + + fflush(f); + + if (ferror(f)) { + if (errno != 0) + r = -errno; + else + r = -EIO; + } else { + if (rename(p, fn) < 0) + r = -errno; + else + r = 0; + } + +finish: + if (r < 0) + unlink(p); + + fclose(f); + free(p); + + return r; +} + +int read_one_line_file(const char *fn, char **line) { + _cleanup_fclose_ FILE *f = NULL; + char t[LINE_MAX], *c; + + assert(fn); + assert(line); + + f = fopen(fn, "re"); + if (!f) + return -errno; + + if (!fgets(t, sizeof(t), f)) { + + if (ferror(f)) + return errno ? -errno : -EIO; + + t[0] = 0; + } + + c = strdup(t); + if (!c) + return -ENOMEM; + truncate_nl(c); + + *line = c; + return 0; +} + +int read_full_file(const char *fn, char **contents, size_t *size) { + _cleanup_fclose_ FILE *f = NULL; + size_t n, l; + _cleanup_free_ char *buf = NULL; + struct stat st; + + f = fopen(fn, "re"); + if (!f) + return -errno; + + if (fstat(fileno(f), &st) < 0) + return -errno; + + /* Safety check */ + if (st.st_size > 4*1024*1024) + return -E2BIG; + + n = st.st_size > 0 ? st.st_size : LINE_MAX; + l = 0; + + for (;;) { + char *t; + size_t k; + + t = realloc(buf, n+1); + if (!t) + return -ENOMEM; + + buf = t; + k = fread(buf + l, 1, n - l, f); + + if (k <= 0) { + if (ferror(f)) + return -errno; + + break; + } + + l += k; + n *= 2; + + /* Safety check */ + if (n > 4*1024*1024) + return -E2BIG; + } + + buf[l] = 0; + *contents = buf; + buf = NULL; + + if (size) + *size = l; + + return 0; +} + +int parse_env_file( + const char *fname, + const char *separator, ...) { + + int r = 0; + char *contents = NULL, *p; + + assert(fname); + assert(separator); + + if ((r = read_full_file(fname, &contents, NULL)) < 0) + return r; + + p = contents; + for (;;) { + const char *key = NULL; + + p += strspn(p, separator); + p += strspn(p, WHITESPACE); + + if (!*p) + break; + + if (!strchr(COMMENTS, *p)) { + va_list ap; + char **value; + + va_start(ap, separator); + while ((key = va_arg(ap, char *))) { + size_t n; + char *v; + + value = va_arg(ap, char **); + + n = strlen(key); + if (strncmp(p, key, n) != 0 || + p[n] != '=') + continue; + + p += n + 1; + n = strcspn(p, separator); + + if (n >= 2 && + strchr(QUOTES, p[0]) && + p[n-1] == p[0]) + v = strndup(p+1, n-2); + else + v = strndup(p, n); + + if (!v) { + r = -ENOMEM; + va_end(ap); + goto fail; + } + + if (v[0] == '\0') { + /* return empty value strings as NULL */ + free(v); + v = NULL; + } + + free(*value); + *value = v; + + p += n; + + r ++; + break; + } + va_end(ap); + } + + if (!key) + p += strcspn(p, separator); + } + +fail: + free(contents); + return r; +} + +int load_env_file( + const char *fname, + char ***rl) { + + FILE *f; + char **m = NULL; + int r; + + assert(fname); + assert(rl); + + if (!(f = fopen(fname, "re"))) + return -errno; + + while (!feof(f)) { + char l[LINE_MAX], *p, *u; + char **t; + + if (!fgets(l, sizeof(l), f)) { + if (feof(f)) + break; + + r = -errno; + goto finish; + } + + p = strstrip(l); + + if (!*p) + continue; + + if (strchr(COMMENTS, *p)) + continue; + + if (!(u = normalize_env_assignment(p))) { + r = log_oom(); + goto finish; + } + + t = strv_append(m, u); + free(u); + + if (!t) { + r = log_oom(); + goto finish; + } + + strv_free(m); + m = t; + } + + r = 0; + + *rl = m; + m = NULL; + +finish: + if (f) + fclose(f); + + strv_free(m); + + return r; +} + +int write_env_file(const char *fname, char **l) { + char **i, *p; + FILE *f; + int r; + + r = fopen_temporary(fname, &f, &p); + if (r < 0) + return r; + + fchmod_umask(fileno(f), 0644); + + errno = 0; + STRV_FOREACH(i, l) { + fputs(*i, f); + fputc('\n', f); + } + + fflush(f); + + if (ferror(f)) { + if (errno != 0) + r = -errno; + else + r = -EIO; + } else { + if (rename(p, fname) < 0) + r = -errno; + else + r = 0; + } + + if (r < 0) + unlink(p); + + fclose(f); + free(p); + + return r; +} + +char *truncate_nl(char *s) { + assert(s); + + s[strcspn(s, NEWLINE)] = 0; + return s; +} + +int get_process_comm(pid_t pid, char **name) { + int r; + + assert(name); + + if (pid == 0) + r = read_one_line_file("/proc/self/comm", name); + else { + char *p; + if (asprintf(&p, "/proc/%lu/comm", (unsigned long) pid) < 0) + return -ENOMEM; + + r = read_one_line_file(p, name); + free(p); + } + + return r; +} + +int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char **line) { + char *r, *k; + int c; + bool space = false; + size_t left; + FILE *f; + + assert(max_length > 0); + assert(line); + + if (pid == 0) + f = fopen("/proc/self/cmdline", "re"); + else { + char *p; + if (asprintf(&p, "/proc/%lu/cmdline", (unsigned long) pid) < 0) + return -ENOMEM; + + f = fopen(p, "re"); + free(p); + } + + if (!f) + return -errno; + + r = new(char, max_length); + if (!r) { + fclose(f); + return -ENOMEM; + } + + k = r; + left = max_length; + while ((c = getc(f)) != EOF) { + + if (isprint(c)) { + if (space) { + if (left <= 4) + break; + + *(k++) = ' '; + left--; + space = false; + } + + if (left <= 4) + break; + + *(k++) = (char) c; + left--; + } else + space = true; + } + + if (left <= 4) { + size_t n = MIN(left-1, 3U); + memcpy(k, "...", n); + k[n] = 0; + } else + *k = 0; + + fclose(f); + + /* Kernel threads have no argv[] */ + if (r[0] == 0) { + char *t; + int h; + + free(r); + + if (!comm_fallback) + return -ENOENT; + + h = get_process_comm(pid, &t); + if (h < 0) + return h; + + r = strjoin("[", t, "]", NULL); + free(t); + + if (!r) + return -ENOMEM; + } + + *line = r; + return 0; +} + +int is_kernel_thread(pid_t pid) { + char *p; + size_t count; + char c; + bool eof; + FILE *f; + + if (pid == 0) + return 0; + + if (asprintf(&p, "/proc/%lu/cmdline", (unsigned long) pid) < 0) + return -ENOMEM; + + f = fopen(p, "re"); + free(p); + + if (!f) + return -errno; + + count = fread(&c, 1, 1, f); + eof = feof(f); + fclose(f); + + /* Kernel threads have an empty cmdline */ + + if (count <= 0) + return eof ? 1 : -errno; + + return 0; +} + +int get_process_exe(pid_t pid, char **name) { + int r; + + assert(name); + + if (pid == 0) + r = readlink_malloc("/proc/self/exe", name); + else { + char *p; + if (asprintf(&p, "/proc/%lu/exe", (unsigned long) pid) < 0) + return -ENOMEM; + + r = readlink_malloc(p, name); + free(p); + } + + return r; +} + +static int get_process_id(pid_t pid, const char *field, uid_t *uid) { + char *p; + FILE *f; + int r; + + assert(uid); + + if (pid == 0) + return getuid(); + + if (asprintf(&p, "/proc/%lu/status", (unsigned long) pid) < 0) + return -ENOMEM; + + f = fopen(p, "re"); + free(p); + + if (!f) + return -errno; + + while (!feof(f)) { + char line[LINE_MAX], *l; + + if (!fgets(line, sizeof(line), f)) { + if (feof(f)) + break; + + r = -errno; + goto finish; + } + + l = strstrip(line); + + if (startswith(l, field)) { + l += strlen(field); + l += strspn(l, WHITESPACE); + + l[strcspn(l, WHITESPACE)] = 0; + + r = parse_uid(l, uid); + goto finish; + } + } + + r = -EIO; + +finish: + fclose(f); + + return r; +} + +int get_process_uid(pid_t pid, uid_t *uid) { + return get_process_id(pid, "Uid:", uid); +} + +int get_process_gid(pid_t pid, gid_t *gid) { + return get_process_id(pid, "Gid:", gid); +} + +char *strnappend(const char *s, const char *suffix, size_t b) { + size_t a; + char *r; + + if (!s && !suffix) + return strdup(""); + + if (!s) + return strndup(suffix, b); + + if (!suffix) + return strdup(s); + + assert(s); + assert(suffix); + + a = strlen(s); + if (b > ((size_t) -1) - a) + return NULL; + + r = new(char, a+b+1); + if (!r) + return NULL; + + memcpy(r, s, a); + memcpy(r+a, suffix, b); + r[a+b] = 0; + + return r; +} + +char *strappend(const char *s, const char *suffix) { + return strnappend(s, suffix, suffix ? strlen(suffix) : 0); +} + +int readlink_malloc(const char *p, char **r) { + size_t l = 100; + + assert(p); + assert(r); + + for (;;) { + char *c; + ssize_t n; + + if (!(c = new(char, l))) + return -ENOMEM; + + if ((n = readlink(p, c, l-1)) < 0) { + int ret = -errno; + free(c); + return ret; + } + + if ((size_t) n < l-1) { + c[n] = 0; + *r = c; + return 0; + } + + free(c); + l *= 2; + } +} + +int readlink_and_make_absolute(const char *p, char **r) { + char *target, *k; + int j; + + assert(p); + assert(r); + + if ((j = readlink_malloc(p, &target)) < 0) + return j; + + k = file_in_same_dir(p, target); + free(target); + + if (!k) + return -ENOMEM; + + *r = k; + return 0; +} + +int readlink_and_canonicalize(const char *p, char **r) { + char *t, *s; + int j; + + assert(p); + assert(r); + + j = readlink_and_make_absolute(p, &t); + if (j < 0) + return j; + + s = canonicalize_file_name(t); + if (s) { + free(t); + *r = s; + } else + *r = t; + + path_kill_slashes(*r); + + return 0; +} + +int reset_all_signal_handlers(void) { + int sig; + + for (sig = 1; sig < _NSIG; sig++) { + struct sigaction sa; + + if (sig == SIGKILL || sig == SIGSTOP) + continue; + + zero(sa); + sa.sa_handler = SIG_DFL; + sa.sa_flags = SA_RESTART; + + /* On Linux the first two RT signals are reserved by + * glibc, and sigaction() will return EINVAL for them. */ + if ((sigaction(sig, &sa, NULL) < 0)) + if (errno != EINVAL) + return -errno; + } + + return 0; +} + +char *strstrip(char *s) { + char *e; + + /* Drops trailing whitespace. Modifies the string in + * place. Returns pointer to first non-space character */ + + s += strspn(s, WHITESPACE); + + for (e = strchr(s, 0); e > s; e --) + if (!strchr(WHITESPACE, e[-1])) + break; + + *e = 0; + + return s; +} + +char *delete_chars(char *s, const char *bad) { + char *f, *t; + + /* Drops all whitespace, regardless where in the string */ + + for (f = s, t = s; *f; f++) { + if (strchr(bad, *f)) + continue; + + *(t++) = *f; + } + + *t = 0; + + return s; +} + +bool in_charset(const char *s, const char* charset) { + const char *i; + + assert(s); + assert(charset); + + for (i = s; *i; i++) + if (!strchr(charset, *i)) + return false; + + return true; +} + +char *file_in_same_dir(const char *path, const char *filename) { + char *e, *r; + size_t k; + + assert(path); + assert(filename); + + /* This removes the last component of path and appends + * filename, unless the latter is absolute anyway or the + * former isn't */ + + if (path_is_absolute(filename)) + return strdup(filename); + + if (!(e = strrchr(path, '/'))) + return strdup(filename); + + k = strlen(filename); + if (!(r = new(char, e-path+1+k+1))) + return NULL; + + memcpy(r, path, e-path+1); + memcpy(r+(e-path)+1, filename, k+1); + + return r; +} + +int rmdir_parents(const char *path, const char *stop) { + size_t l; + int r = 0; + + assert(path); + assert(stop); + + l = strlen(path); + + /* Skip trailing slashes */ + while (l > 0 && path[l-1] == '/') + l--; + + while (l > 0) { + char *t; + + /* Skip last component */ + while (l > 0 && path[l-1] != '/') + l--; + + /* Skip trailing slashes */ + while (l > 0 && path[l-1] == '/') + l--; + + if (l <= 0) + break; + + if (!(t = strndup(path, l))) + return -ENOMEM; + + if (path_startswith(stop, t)) { + free(t); + return 0; + } + + r = rmdir(t); + free(t); + + if (r < 0) + if (errno != ENOENT) + return -errno; + } + + return 0; +} + + +char hexchar(int x) { + static const char table[16] = "0123456789abcdef"; + + return table[x & 15]; +} + +int unhexchar(char c) { + + if (c >= '0' && c <= '9') + return c - '0'; + + if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + + if (c >= 'A' && c <= 'F') + return c - 'A' + 10; + + return -1; +} + +char octchar(int x) { + return '0' + (x & 7); +} + +int unoctchar(char c) { + + if (c >= '0' && c <= '7') + return c - '0'; + + return -1; +} + +char decchar(int x) { + return '0' + (x % 10); +} + +int undecchar(char c) { + + if (c >= '0' && c <= '9') + return c - '0'; + + return -1; +} + +char *cescape(const char *s) { + char *r, *t; + const char *f; + + assert(s); + + /* Does C style string escaping. */ + + r = new(char, strlen(s)*4 + 1); + if (!r) + return NULL; + + for (f = s, t = r; *f; f++) + + switch (*f) { + + case '\a': + *(t++) = '\\'; + *(t++) = 'a'; + break; + case '\b': + *(t++) = '\\'; + *(t++) = 'b'; + break; + case '\f': + *(t++) = '\\'; + *(t++) = 'f'; + break; + case '\n': + *(t++) = '\\'; + *(t++) = 'n'; + break; + case '\r': + *(t++) = '\\'; + *(t++) = 'r'; + break; + case '\t': + *(t++) = '\\'; + *(t++) = 't'; + break; + case '\v': + *(t++) = '\\'; + *(t++) = 'v'; + break; + case '\\': + *(t++) = '\\'; + *(t++) = '\\'; + break; + case '"': + *(t++) = '\\'; + *(t++) = '"'; + break; + case '\'': + *(t++) = '\\'; + *(t++) = '\''; + break; + + default: + /* For special chars we prefer octal over + * hexadecimal encoding, simply because glib's + * g_strescape() does the same */ + if ((*f < ' ') || (*f >= 127)) { + *(t++) = '\\'; + *(t++) = octchar((unsigned char) *f >> 6); + *(t++) = octchar((unsigned char) *f >> 3); + *(t++) = octchar((unsigned char) *f); + } else + *(t++) = *f; + break; + } + + *t = 0; + + return r; +} + +char *cunescape_length_with_prefix(const char *s, size_t length, const char *prefix) { + char *r, *t; + const char *f; + size_t pl; + + assert(s); + + /* Undoes C style string escaping, and optionally prefixes it. */ + + pl = prefix ? strlen(prefix) : 0; + + r = new(char, pl+length+1); + if (!r) + return r; + + if (prefix) + memcpy(r, prefix, pl); + + for (f = s, t = r + pl; f < s + length; f++) { + + if (*f != '\\') { + *(t++) = *f; + continue; + } + + f++; + + switch (*f) { + + case 'a': + *(t++) = '\a'; + break; + case 'b': + *(t++) = '\b'; + break; + case 'f': + *(t++) = '\f'; + break; + case 'n': + *(t++) = '\n'; + break; + case 'r': + *(t++) = '\r'; + break; + case 't': + *(t++) = '\t'; + break; + case 'v': + *(t++) = '\v'; + break; + case '\\': + *(t++) = '\\'; + break; + case '"': + *(t++) = '"'; + break; + case '\'': + *(t++) = '\''; + break; + + case 's': + /* This is an extension of the XDG syntax files */ + *(t++) = ' '; + break; + + case 'x': { + /* hexadecimal encoding */ + int a, b; + + a = unhexchar(f[1]); + b = unhexchar(f[2]); + + if (a < 0 || b < 0) { + /* Invalid escape code, let's take it literal then */ + *(t++) = '\\'; + *(t++) = 'x'; + } else { + *(t++) = (char) ((a << 4) | b); + f += 2; + } + + break; + } + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': { + /* octal encoding */ + int a, b, c; + + a = unoctchar(f[0]); + b = unoctchar(f[1]); + c = unoctchar(f[2]); + + if (a < 0 || b < 0 || c < 0) { + /* Invalid escape code, let's take it literal then */ + *(t++) = '\\'; + *(t++) = f[0]; + } else { + *(t++) = (char) ((a << 6) | (b << 3) | c); + f += 2; + } + + break; + } + + case 0: + /* premature end of string.*/ + *(t++) = '\\'; + goto finish; + + default: + /* Invalid escape code, let's take it literal then */ + *(t++) = '\\'; + *(t++) = *f; + break; + } + } + +finish: + *t = 0; + return r; +} + +char *cunescape_length(const char *s, size_t length) { + return cunescape_length_with_prefix(s, length, NULL); +} + +char *cunescape(const char *s) { + assert(s); + + return cunescape_length(s, strlen(s)); +} + +char *xescape(const char *s, const char *bad) { + char *r, *t; + const char *f; + + /* Escapes all chars in bad, in addition to \ and all special + * chars, in \xFF style escaping. May be reversed with + * cunescape. */ + + r = new(char, strlen(s) * 4 + 1); + if (!r) + return NULL; + + for (f = s, t = r; *f; f++) { + + if ((*f < ' ') || (*f >= 127) || + (*f == '\\') || strchr(bad, *f)) { + *(t++) = '\\'; + *(t++) = 'x'; + *(t++) = hexchar(*f >> 4); + *(t++) = hexchar(*f); + } else + *(t++) = *f; + } + + *t = 0; + + return r; +} + +char *bus_path_escape(const char *s) { + char *r, *t; + const char *f; + + assert(s); + + /* Escapes all chars that D-Bus' object path cannot deal + * with. Can be reverse with bus_path_unescape() */ + + if (!(r = new(char, strlen(s)*3+1))) + return NULL; + + for (f = s, t = r; *f; f++) { + + if (!(*f >= 'A' && *f <= 'Z') && + !(*f >= 'a' && *f <= 'z') && + !(*f >= '0' && *f <= '9')) { + *(t++) = '_'; + *(t++) = hexchar(*f >> 4); + *(t++) = hexchar(*f); + } else + *(t++) = *f; + } + + *t = 0; + + return r; +} + +char *bus_path_unescape(const char *f) { + char *r, *t; + + assert(f); + + if (!(r = strdup(f))) + return NULL; + + for (t = r; *f; f++) { + + if (*f == '_') { + int a, b; + + if ((a = unhexchar(f[1])) < 0 || + (b = unhexchar(f[2])) < 0) { + /* Invalid escape code, let's take it literal then */ + *(t++) = '_'; + } else { + *(t++) = (char) ((a << 4) | b); + f += 2; + } + } else + *(t++) = *f; + } + + *t = 0; + + return r; +} + +char *ascii_strlower(char *t) { + char *p; + + assert(t); + + for (p = t; *p; p++) + if (*p >= 'A' && *p <= 'Z') + *p = *p - 'A' + 'a'; + + return t; +} + +static bool ignore_file_allow_backup(const char *filename) { + assert(filename); + + return + filename[0] == '.' || + streq(filename, "lost+found") || + streq(filename, "aquota.user") || + streq(filename, "aquota.group") || + endswith(filename, ".rpmnew") || + endswith(filename, ".rpmsave") || + endswith(filename, ".rpmorig") || + endswith(filename, ".dpkg-old") || + endswith(filename, ".dpkg-new") || + endswith(filename, ".swp"); +} + +bool ignore_file(const char *filename) { + assert(filename); + + if (endswith(filename, "~")) + return false; + + return ignore_file_allow_backup(filename); +} + +int fd_nonblock(int fd, bool nonblock) { + int flags; + + assert(fd >= 0); + + if ((flags = fcntl(fd, F_GETFL, 0)) < 0) + return -errno; + + if (nonblock) + flags |= O_NONBLOCK; + else + flags &= ~O_NONBLOCK; + + if (fcntl(fd, F_SETFL, flags) < 0) + return -errno; + + return 0; +} + +int fd_cloexec(int fd, bool cloexec) { + int flags; + + assert(fd >= 0); + + if ((flags = fcntl(fd, F_GETFD, 0)) < 0) + return -errno; + + if (cloexec) + flags |= FD_CLOEXEC; + else + flags &= ~FD_CLOEXEC; + + if (fcntl(fd, F_SETFD, flags) < 0) + return -errno; + + return 0; +} + +static bool fd_in_set(int fd, const int fdset[], unsigned n_fdset) { + unsigned i; + + assert(n_fdset == 0 || fdset); + + for (i = 0; i < n_fdset; i++) + if (fdset[i] == fd) + return true; + + return false; +} + +int close_all_fds(const int except[], unsigned n_except) { + DIR *d; + struct dirent *de; + int r = 0; + + assert(n_except == 0 || except); + + d = opendir("/proc/self/fd"); + if (!d) { + int fd; + struct rlimit rl; + + /* When /proc isn't available (for example in chroots) + * the fallback is brute forcing through the fd + * table */ + + assert_se(getrlimit(RLIMIT_NOFILE, &rl) >= 0); + for (fd = 3; fd < (int) rl.rlim_max; fd ++) { + + if (fd_in_set(fd, except, n_except)) + continue; + + if (close_nointr(fd) < 0) + if (errno != EBADF && r == 0) + r = -errno; + } + + return r; + } + + while ((de = readdir(d))) { + int fd = -1; + + if (ignore_file(de->d_name)) + continue; + + if (safe_atoi(de->d_name, &fd) < 0) + /* Let's better ignore this, just in case */ + continue; + + if (fd < 3) + continue; + + if (fd == dirfd(d)) + continue; + + 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; + } + } + + closedir(d); + return r; +} + +bool chars_intersect(const char *a, const char *b) { + const char *p; + + /* Returns true if any of the chars in a are in b. */ + for (p = a; *p; p++) + if (strchr(b, *p)) + return true; + + return false; +} + +bool fstype_is_network(const char *fstype) { + static const char table[] = + "cifs\0" + "smbfs\0" + "ncpfs\0" + "nfs\0" + "nfs4\0" + "gfs\0" + "gfs2\0"; + + return nulstr_contains(table, fstype); +} + +int chvt(int vt) { + _cleanup_close_ int fd; + + fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC); + if (fd < 0) + return -errno; + + if (vt < 0) { + int tiocl[2] = { + TIOCL_GETKMSGREDIRECT, + 0 + }; + + if (ioctl(fd, TIOCLINUX, tiocl) < 0) + return -errno; + + vt = tiocl[0] <= 0 ? 1 : tiocl[0]; + } + + if (ioctl(fd, VT_ACTIVATE, vt) < 0) + return -errno; + + return 0; +} + +int read_one_char(FILE *f, char *ret, usec_t t, bool *need_nl) { + struct termios old_termios, new_termios; + char c; + char line[LINE_MAX]; + + assert(f); + assert(ret); + + if (tcgetattr(fileno(f), &old_termios) >= 0) { + new_termios = old_termios; + + new_termios.c_lflag &= ~ICANON; + new_termios.c_cc[VMIN] = 1; + new_termios.c_cc[VTIME] = 0; + + if (tcsetattr(fileno(f), TCSADRAIN, &new_termios) >= 0) { + size_t k; + + if (t != (usec_t) -1) { + if (fd_wait_for_event(fileno(f), POLLIN, t) <= 0) { + tcsetattr(fileno(f), TCSADRAIN, &old_termios); + return -ETIMEDOUT; + } + } + + k = fread(&c, 1, 1, f); + + tcsetattr(fileno(f), TCSADRAIN, &old_termios); + + if (k <= 0) + return -EIO; + + if (need_nl) + *need_nl = c != '\n'; + + *ret = c; + return 0; + } + } + + if (t != (usec_t) -1) + if (fd_wait_for_event(fileno(f), POLLIN, t) <= 0) + return -ETIMEDOUT; + + if (!fgets(line, sizeof(line), f)) + return -EIO; + + truncate_nl(line); + + if (strlen(line) != 1) + return -EBADMSG; + + if (need_nl) + *need_nl = false; + + *ret = line[0]; + return 0; +} + +int ask(char *ret, const char *replies, const char *text, ...) { + + assert(ret); + assert(replies); + assert(text); + + for (;;) { + va_list ap; + char c; + int r; + bool need_nl = true; + + if (on_tty()) + fputs(ANSI_HIGHLIGHT_ON, stdout); + + va_start(ap, text); + vprintf(text, ap); + va_end(ap); + + if (on_tty()) + fputs(ANSI_HIGHLIGHT_OFF, stdout); + + fflush(stdout); + + r = read_one_char(stdin, &c, (usec_t) -1, &need_nl); + if (r < 0) { + + if (r == -EBADMSG) { + puts("Bad input, please try again."); + continue; + } + + putchar('\n'); + return r; + } + + if (need_nl) + putchar('\n'); + + if (strchr(replies, c)) { + *ret = c; + return 0; + } + + puts("Read unexpected character, please try again."); + } +} + +int reset_terminal_fd(int fd, bool switch_to_text) { + struct termios termios; + int r = 0; + + /* Set terminal to some sane defaults */ + + assert(fd >= 0); + + /* We leave locked terminal attributes untouched, so that + * Plymouth may set whatever it wants to set, and we don't + * interfere with that. */ + + /* Disable exclusive mode, just in case */ + ioctl(fd, TIOCNXCL); + + /* Switch to text mode */ + if (switch_to_text) + ioctl(fd, KDSETMODE, KD_TEXT); + + /* Enable console unicode mode */ + ioctl(fd, KDSKBMODE, K_UNICODE); + + if (tcgetattr(fd, &termios) < 0) { + r = -errno; + goto finish; + } + + /* We only reset the stuff that matters to the software. How + * hardware is set up we don't touch assuming that somebody + * else will do that for us */ + + termios.c_iflag &= ~(IGNBRK | BRKINT | ISTRIP | INLCR | IGNCR | IUCLC); + termios.c_iflag |= ICRNL | IMAXBEL | IUTF8; + termios.c_oflag |= ONLCR; + termios.c_cflag |= CREAD; + termios.c_lflag = ISIG | ICANON | IEXTEN | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOPRT | ECHOKE; + + termios.c_cc[VINTR] = 03; /* ^C */ + termios.c_cc[VQUIT] = 034; /* ^\ */ + termios.c_cc[VERASE] = 0177; + termios.c_cc[VKILL] = 025; /* ^X */ + termios.c_cc[VEOF] = 04; /* ^D */ + termios.c_cc[VSTART] = 021; /* ^Q */ + termios.c_cc[VSTOP] = 023; /* ^S */ + termios.c_cc[VSUSP] = 032; /* ^Z */ + termios.c_cc[VLNEXT] = 026; /* ^V */ + termios.c_cc[VWERASE] = 027; /* ^W */ + termios.c_cc[VREPRINT] = 022; /* ^R */ + termios.c_cc[VEOL] = 0; + termios.c_cc[VEOL2] = 0; + + termios.c_cc[VTIME] = 0; + termios.c_cc[VMIN] = 1; + + if (tcsetattr(fd, TCSANOW, &termios) < 0) + r = -errno; + +finish: + /* Just in case, flush all crap out */ + tcflush(fd, TCIOFLUSH); + + return r; +} + +int reset_terminal(const char *name) { + int fd, r; + + fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC); + if (fd < 0) + return fd; + + r = reset_terminal_fd(fd, true); + close_nointr_nofail(fd); + + return r; +} + +int open_terminal(const char *name, int mode) { + int fd, r; + unsigned c = 0; + + /* + * If a TTY is in the process of being closed opening it might + * cause EIO. This is horribly awful, but unlikely to be + * changed in the kernel. Hence we work around this problem by + * retrying a couple of times. + * + * https://bugs.launchpad.net/ubuntu/+source/linux/+bug/554172/comments/245 + */ + + for (;;) { + fd = open(name, mode); + if (fd >= 0) + break; + + if (errno != EIO) + return -errno; + + /* Max 1s in total */ + if (c >= 20) + return -errno; + + usleep(50 * USEC_PER_MSEC); + c++; + } + + if (fd < 0) + return -errno; + + r = isatty(fd); + if (r < 0) { + close_nointr_nofail(fd); + return -errno; + } + + if (!r) { + close_nointr_nofail(fd); + return -ENOTTY; + } + + return fd; +} + +int flush_fd(int fd) { + struct pollfd pollfd; + + zero(pollfd); + pollfd.fd = fd; + pollfd.events = POLLIN; + + for (;;) { + char buf[LINE_MAX]; + ssize_t l; + int r; + + if ((r = poll(&pollfd, 1, 0)) < 0) { + + if (errno == EINTR) + continue; + + return -errno; + } + + if (r == 0) + return 0; + + if ((l = read(fd, buf, sizeof(buf))) < 0) { + + if (errno == EINTR) + continue; + + if (errno == EAGAIN) + return 0; + + return -errno; + } + + if (l <= 0) + return 0; + } +} + +int acquire_terminal( + const char *name, + bool fail, + bool force, + bool ignore_tiocstty_eperm, + usec_t timeout) { + + int fd = -1, notify = -1, r = 0, wd = -1; + usec_t ts = 0; + struct sigaction sa_old, sa_new; + + assert(name); + + /* We use inotify to be notified when the tty is closed. We + * create the watch before checking if we can actually acquire + * it, so that we don't lose any event. + * + * Note: strictly speaking this actually watches for the + * device being closed, it does *not* really watch whether a + * tty loses its controlling process. However, unless some + * rogue process uses TIOCNOTTY on /dev/tty *after* closing + * its tty otherwise this will not become a problem. As long + * as the administrator makes sure not configure any service + * on the same tty as an untrusted user this should not be a + * problem. (Which he probably should not do anyway.) */ + + if (timeout != (usec_t) -1) + ts = now(CLOCK_MONOTONIC); + + if (!fail && !force) { + notify = inotify_init1(IN_CLOEXEC | (timeout != (usec_t) -1 ? IN_NONBLOCK : 0)); + if (notify < 0) { + r = -errno; + goto fail; + } + + wd = inotify_add_watch(notify, name, IN_CLOSE); + if (wd < 0) { + r = -errno; + goto fail; + } + } + + for (;;) { + if (notify >= 0) { + r = flush_fd(notify); + if (r < 0) + goto fail; + } + + /* We pass here O_NOCTTY only so that we can check the return + * value TIOCSCTTY and have a reliable way to figure out if we + * successfully became the controlling process of the tty */ + fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC); + if (fd < 0) + return fd; + + /* Temporarily ignore SIGHUP, so that we don't get SIGHUP'ed + * if we already own the tty. */ + zero(sa_new); + sa_new.sa_handler = SIG_IGN; + sa_new.sa_flags = SA_RESTART; + assert_se(sigaction(SIGHUP, &sa_new, &sa_old) == 0); + + /* First, try to get the tty */ + if (ioctl(fd, TIOCSCTTY, force) < 0) + r = -errno; + + assert_se(sigaction(SIGHUP, &sa_old, NULL) == 0); + + /* Sometimes it makes sense to ignore TIOCSCTTY + * returning EPERM, i.e. when very likely we already + * are have this controlling terminal. */ + if (r < 0 && r == -EPERM && ignore_tiocstty_eperm) + r = 0; + + if (r < 0 && (force || fail || r != -EPERM)) { + goto fail; + } + + if (r >= 0) + break; + + assert(!fail); + assert(!force); + assert(notify >= 0); + + for (;;) { + uint8_t inotify_buffer[sizeof(struct inotify_event) + FILENAME_MAX]; + ssize_t l; + struct inotify_event *e; + + if (timeout != (usec_t) -1) { + usec_t n; + + n = now(CLOCK_MONOTONIC); + if (ts + timeout < n) { + r = -ETIMEDOUT; + goto fail; + } + + r = fd_wait_for_event(fd, POLLIN, ts + timeout - n); + if (r < 0) + goto fail; + + if (r == 0) { + r = -ETIMEDOUT; + goto fail; + } + } + + l = read(notify, inotify_buffer, sizeof(inotify_buffer)); + if (l < 0) { + + if (errno == EINTR || errno == EAGAIN) + continue; + + r = -errno; + goto fail; + } + + e = (struct inotify_event*) inotify_buffer; + + while (l > 0) { + size_t step; + + if (e->wd != wd || !(e->mask & IN_CLOSE)) { + r = -EIO; + goto fail; + } + + step = sizeof(struct inotify_event) + e->len; + assert(step <= (size_t) l); + + e = (struct inotify_event*) ((uint8_t*) e + step); + l -= step; + } + + break; + } + + /* We close the tty fd here since if the old session + * ended our handle will be dead. It's important that + * we do this after sleeping, so that we don't enter + * an endless loop. */ + close_nointr_nofail(fd); + } + + if (notify >= 0) + close_nointr_nofail(notify); + + r = reset_terminal_fd(fd, true); + if (r < 0) + log_warning("Failed to reset terminal: %s", strerror(-r)); + + return fd; + +fail: + if (fd >= 0) + close_nointr_nofail(fd); + + if (notify >= 0) + close_nointr_nofail(notify); + + return r; +} + +int release_terminal(void) { + int r = 0, fd; + struct sigaction sa_old, sa_new; + + if ((fd = open("/dev/tty", O_RDWR|O_NOCTTY|O_NDELAY|O_CLOEXEC)) < 0) + return -errno; + + /* Temporarily ignore SIGHUP, so that we don't get SIGHUP'ed + * by our own TIOCNOTTY */ + + zero(sa_new); + sa_new.sa_handler = SIG_IGN; + sa_new.sa_flags = SA_RESTART; + assert_se(sigaction(SIGHUP, &sa_new, &sa_old) == 0); + + if (ioctl(fd, TIOCNOTTY) < 0) + r = -errno; + + assert_se(sigaction(SIGHUP, &sa_old, NULL) == 0); + + close_nointr_nofail(fd); + return r; +} + +int sigaction_many(const struct sigaction *sa, ...) { + va_list ap; + int r = 0, sig; + + va_start(ap, sa); + while ((sig = va_arg(ap, int)) > 0) + if (sigaction(sig, sa, NULL) < 0) + r = -errno; + va_end(ap); + + return r; +} + +int ignore_signals(int sig, ...) { + struct sigaction sa; + va_list ap; + int r = 0; + + zero(sa); + sa.sa_handler = SIG_IGN; + sa.sa_flags = SA_RESTART; + + if (sigaction(sig, &sa, NULL) < 0) + r = -errno; + + va_start(ap, sig); + while ((sig = va_arg(ap, int)) > 0) + if (sigaction(sig, &sa, NULL) < 0) + r = -errno; + va_end(ap); + + return r; +} + +int default_signals(int sig, ...) { + struct sigaction sa; + va_list ap; + int r = 0; + + zero(sa); + sa.sa_handler = SIG_DFL; + sa.sa_flags = SA_RESTART; + + if (sigaction(sig, &sa, NULL) < 0) + r = -errno; + + va_start(ap, sig); + while ((sig = va_arg(ap, int)) > 0) + if (sigaction(sig, &sa, NULL) < 0) + r = -errno; + va_end(ap); + + return r; +} + +int close_pipe(int p[]) { + int a = 0, b = 0; + + assert(p); + + if (p[0] >= 0) { + a = close_nointr(p[0]); + p[0] = -1; + } + + if (p[1] >= 0) { + b = close_nointr(p[1]); + p[1] = -1; + } + + return a < 0 ? a : b; +} + +ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll) { + uint8_t *p; + ssize_t n = 0; + + assert(fd >= 0); + assert(buf); + + p = buf; + + while (nbytes > 0) { + ssize_t k; + + if ((k = read(fd, p, nbytes)) <= 0) { + + if (k < 0 && errno == EINTR) + continue; + + if (k < 0 && errno == EAGAIN && do_poll) { + struct pollfd pollfd; + + zero(pollfd); + pollfd.fd = fd; + pollfd.events = POLLIN; + + if (poll(&pollfd, 1, -1) < 0) { + if (errno == EINTR) + continue; + + return n > 0 ? n : -errno; + } + + if (pollfd.revents != POLLIN) + return n > 0 ? n : -EIO; + + continue; + } + + return n > 0 ? n : (k < 0 ? -errno : 0); + } + + p += k; + nbytes -= k; + n += k; + } + + return n; +} + +ssize_t loop_write(int fd, const void *buf, size_t nbytes, bool do_poll) { + const uint8_t *p; + ssize_t n = 0; + + assert(fd >= 0); + assert(buf); + + p = buf; + + while (nbytes > 0) { + ssize_t k; + + k = write(fd, p, nbytes); + if (k <= 0) { + + if (k < 0 && errno == EINTR) + continue; + + if (k < 0 && errno == EAGAIN && do_poll) { + struct pollfd pollfd; + + zero(pollfd); + pollfd.fd = fd; + pollfd.events = POLLOUT; + + if (poll(&pollfd, 1, -1) < 0) { + if (errno == EINTR) + continue; + + return n > 0 ? n : -errno; + } + + if (pollfd.revents != POLLOUT) + return n > 0 ? n : -EIO; + + continue; + } + + return n > 0 ? n : (k < 0 ? -errno : 0); + } + + p += k; + nbytes -= k; + n += k; + } + + return n; +} + +int parse_bytes(const char *t, off_t *bytes) { + static const struct { + const char *suffix; + off_t factor; + } table[] = { + { "B", 1 }, + { "K", 1024ULL }, + { "M", 1024ULL*1024ULL }, + { "G", 1024ULL*1024ULL*1024ULL }, + { "T", 1024ULL*1024ULL*1024ULL*1024ULL }, + { "P", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL }, + { "E", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL*1024ULL }, + { "", 1 }, + }; + + const char *p; + off_t r = 0; + + assert(t); + assert(bytes); + + p = t; + do { + long long l; + char *e; + unsigned i; + + errno = 0; + l = strtoll(p, &e, 10); + + if (errno != 0) + return -errno; + + if (l < 0) + return -ERANGE; + + if (e == p) + return -EINVAL; + + e += strspn(e, WHITESPACE); + + for (i = 0; i < ELEMENTSOF(table); i++) + if (startswith(e, table[i].suffix)) { + r += (off_t) l * table[i].factor; + p = e + strlen(table[i].suffix); + break; + } + + if (i >= ELEMENTSOF(table)) + return -EINVAL; + + } while (*p != 0); + + *bytes = r; + + return 0; +} + +int make_stdio(int fd) { + int r, s, t; + + assert(fd >= 0); + + r = dup3(fd, STDIN_FILENO, 0); + s = dup3(fd, STDOUT_FILENO, 0); + t = dup3(fd, STDERR_FILENO, 0); + + if (fd >= 3) + close_nointr_nofail(fd); + + if (r < 0 || s < 0 || t < 0) + return -errno; + + /* We rely here that the new fd has O_CLOEXEC not set */ + + return 0; +} + +int make_null_stdio(void) { + int null_fd; + + null_fd = open("/dev/null", O_RDWR|O_NOCTTY); + if (null_fd < 0) + return -errno; + + return make_stdio(null_fd); +} + +bool is_device_path(const char *path) { + + /* Returns true on paths that refer to a device, either in + * sysfs or in /dev */ + + return + path_startswith(path, "/dev/") || + path_startswith(path, "/sys/"); +} + +int dir_is_empty(const char *path) { + _cleanup_closedir_ DIR *d; + int r; + + d = opendir(path); + if (!d) + return -errno; + + for (;;) { + struct dirent *de; + union dirent_storage buf; + + r = readdir_r(d, &buf.de, &de); + if (r > 0) + return -r; + + if (!de) + return 1; + + if (!ignore_file(de->d_name)) + return 0; + } +} + +unsigned long long random_ull(void) { + _cleanup_close_ int fd; + uint64_t ull; + ssize_t r; + + fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY); + if (fd < 0) + goto fallback; + + r = loop_read(fd, &ull, sizeof(ull), true); + if (r != sizeof(ull)) + goto fallback; + + return ull; + +fallback: + return random() * RAND_MAX + random(); +} + +void rename_process(const char name[8]) { + assert(name); + + /* This is a like a poor man's setproctitle(). It changes the + * comm field, argv[0], and also the glibc's internally used + * name of the process. For the first one a limit of 16 chars + * applies, to the second one usually one of 10 (i.e. length + * of "/sbin/init"), to the third one one of 7 (i.e. length of + * "systemd"). If you pass a longer string it will be + * truncated */ + + prctl(PR_SET_NAME, name); + + if (program_invocation_name) + strncpy(program_invocation_name, name, strlen(program_invocation_name)); + + if (saved_argc > 0) { + int i; + + if (saved_argv[0]) + strncpy(saved_argv[0], name, strlen(saved_argv[0])); + + for (i = 1; i < saved_argc; i++) { + if (!saved_argv[i]) + break; + + memset(saved_argv[i], 0, strlen(saved_argv[i])); + } + } +} + +void sigset_add_many(sigset_t *ss, ...) { + va_list ap; + int sig; + + assert(ss); + + va_start(ap, ss); + while ((sig = va_arg(ap, int)) > 0) + assert_se(sigaddset(ss, sig) == 0); + va_end(ap); +} + +char* gethostname_malloc(void) { + struct utsname u; + + assert_se(uname(&u) >= 0); + + if (!isempty(u.nodename) && !streq(u.nodename, "(none)")) + return strdup(u.nodename); + + return strdup(u.sysname); +} + +bool hostname_is_set(void) { + struct utsname u; + + assert_se(uname(&u) >= 0); + + return !isempty(u.nodename) && !streq(u.nodename, "(none)"); +} + +static char *lookup_uid(uid_t uid) { + long bufsize; + char *name; + _cleanup_free_ char *buf = NULL; + struct passwd pwbuf, *pw = NULL; + + /* Shortcut things to avoid NSS lookups */ + if (uid == 0) + return strdup("root"); + + bufsize = sysconf(_SC_GETPW_R_SIZE_MAX); + if (bufsize <= 0) + bufsize = 4096; + + buf = malloc(bufsize); + if (!buf) + return NULL; + + if (getpwuid_r(uid, &pwbuf, buf, bufsize, &pw) == 0 && pw) + return strdup(pw->pw_name); + + if (asprintf(&name, "%lu", (unsigned long) uid) < 0) + return NULL; + + return name; +} + +char* getlogname_malloc(void) { + uid_t uid; + struct stat st; + + if (isatty(STDIN_FILENO) && fstat(STDIN_FILENO, &st) >= 0) + uid = st.st_uid; + else + uid = getuid(); + + return lookup_uid(uid); +} + +char *getusername_malloc(void) { + const char *e; + + e = getenv("USER"); + if (e) + return strdup(e); + + return lookup_uid(getuid()); +} + +int getttyname_malloc(int fd, char **r) { + char path[PATH_MAX], *c; + int k; + + assert(r); + + k = ttyname_r(fd, path, sizeof(path)); + if (k != 0) + return -k; + + char_array_0(path); + + c = strdup(startswith(path, "/dev/") ? path + 5 : path); + if (!c) + return -ENOMEM; + + *r = c; + return 0; +} + +int getttyname_harder(int fd, char **r) { + int k; + char *s; + + k = getttyname_malloc(fd, &s); + if (k < 0) + return k; + + if (streq(s, "tty")) { + free(s); + return get_ctty(0, NULL, r); + } + + *r = s; + return 0; +} + +int get_ctty_devnr(pid_t pid, dev_t *d) { + int k; + char line[LINE_MAX], *p, *fn; + unsigned long ttynr; + FILE *f; + + if (asprintf(&fn, "/proc/%lu/stat", (unsigned long) (pid <= 0 ? getpid() : pid)) < 0) + return -ENOMEM; + + f = fopen(fn, "re"); + free(fn); + if (!f) + return -errno; + + if (!fgets(line, sizeof(line), f)) { + k = feof(f) ? -EIO : -errno; + fclose(f); + return k; + } + + fclose(f); + + p = strrchr(line, ')'); + if (!p) + return -EIO; + + p++; + + if (sscanf(p, " " + "%*c " /* state */ + "%*d " /* ppid */ + "%*d " /* pgrp */ + "%*d " /* session */ + "%lu ", /* ttynr */ + &ttynr) != 1) + return -EIO; + + if (major(ttynr) == 0 && minor(ttynr) == 0) + return -ENOENT; + + *d = (dev_t) ttynr; + return 0; +} + +int get_ctty(pid_t pid, dev_t *_devnr, char **r) { + int k; + char fn[PATH_MAX], *s, *b, *p; + dev_t devnr; + + assert(r); + + k = get_ctty_devnr(pid, &devnr); + if (k < 0) + return k; + + snprintf(fn, sizeof(fn), "/dev/char/%u:%u", major(devnr), minor(devnr)); + char_array_0(fn); + + k = readlink_malloc(fn, &s); + if (k < 0) { + + if (k != -ENOENT) + return k; + + /* This is an ugly hack */ + if (major(devnr) == 136) { + if (asprintf(&b, "pts/%lu", (unsigned long) minor(devnr)) < 0) + return -ENOMEM; + + *r = b; + if (_devnr) + *_devnr = devnr; + + return 0; + } + + /* Probably something like the ptys which have no + * symlink in /dev/char. Let's return something + * vaguely useful. */ + + b = strdup(fn + 5); + if (!b) + return -ENOMEM; + + *r = b; + if (_devnr) + *_devnr = devnr; + + return 0; + } + + if (startswith(s, "/dev/")) + p = s + 5; + else if (startswith(s, "../")) + p = s + 3; + else + p = s; + + b = strdup(p); + free(s); + + if (!b) + return -ENOMEM; + + *r = b; + if (_devnr) + *_devnr = devnr; + + return 0; +} + +int rm_rf_children_dangerous(int fd, bool only_dirs, bool honour_sticky, struct stat *root_dev) { + DIR *d; + int ret = 0; + + assert(fd >= 0); + + /* This returns the first error we run into, but nevertheless + * tries to go on. This closes the passed fd. */ + + d = fdopendir(fd); + if (!d) { + close_nointr_nofail(fd); + + return errno == ENOENT ? 0 : -errno; + } + + for (;;) { + struct dirent *de; + union dirent_storage buf; + bool is_dir, keep_around; + struct stat st; + int r; + + r = readdir_r(d, &buf.de, &de); + if (r != 0 && ret == 0) { + ret = -r; + break; + } + + if (!de) + break; + + if (streq(de->d_name, ".") || streq(de->d_name, "..")) + continue; + + if (de->d_type == DT_UNKNOWN || + honour_sticky || + (de->d_type == DT_DIR && root_dev)) { + if (fstatat(fd, de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0) { + if (ret == 0 && errno != ENOENT) + ret = -errno; + continue; + } + + is_dir = S_ISDIR(st.st_mode); + keep_around = + honour_sticky && + (st.st_uid == 0 || st.st_uid == getuid()) && + (st.st_mode & S_ISVTX); + } else { + is_dir = de->d_type == DT_DIR; + keep_around = false; + } + + if (is_dir) { + int subdir_fd; + + /* if root_dev is set, remove subdirectories only, if device is same as dir */ + if (root_dev && st.st_dev != root_dev->st_dev) + continue; + + subdir_fd = openat(fd, de->d_name, + O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME); + if (subdir_fd < 0) { + if (ret == 0 && errno != ENOENT) + ret = -errno; + continue; + } + + r = rm_rf_children_dangerous(subdir_fd, only_dirs, honour_sticky, root_dev); + if (r < 0 && ret == 0) + ret = r; + + if (!keep_around) + if (unlinkat(fd, de->d_name, AT_REMOVEDIR) < 0) { + if (ret == 0 && errno != ENOENT) + ret = -errno; + } + + } else if (!only_dirs && !keep_around) { + + if (unlinkat(fd, de->d_name, 0) < 0) { + if (ret == 0 && errno != ENOENT) + ret = -errno; + } + } + } + + closedir(d); + + return ret; +} + +static int is_temporary_fs(struct statfs *s) { + assert(s); + return s->f_type == TMPFS_MAGIC || + (long)s->f_type == (long)RAMFS_MAGIC; +} + +int rm_rf_children(int fd, bool only_dirs, bool honour_sticky, struct stat *root_dev) { + struct statfs s; + + assert(fd >= 0); + + if (fstatfs(fd, &s) < 0) { + close_nointr_nofail(fd); + return -errno; + } + + /* We refuse to clean disk file systems with this call. This + * is extra paranoia just to be sure we never ever remove + * non-state data */ + if (!is_temporary_fs(&s)) { + log_error("Attempted to remove disk file system, and we can't allow that."); + close_nointr_nofail(fd); + return -EPERM; + } + + return rm_rf_children_dangerous(fd, only_dirs, honour_sticky, root_dev); +} + +static int rm_rf_internal(const char *path, bool only_dirs, bool delete_root, bool honour_sticky, bool dangerous) { + int fd, r; + struct statfs s; + + assert(path); + + /* We refuse to clean the root file system with this + * call. This is extra paranoia to never cause a really + * seriously broken system. */ + if (path_equal(path, "/")) { + log_error("Attempted to remove entire root file system, and we can't allow that."); + return -EPERM; + } + + fd = open(path, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME); + if (fd < 0) { + + if (errno != ENOTDIR) + return -errno; + + if (!dangerous) { + if (statfs(path, &s) < 0) + return -errno; + + if (!is_temporary_fs(&s)) { + log_error("Attempted to remove disk file system, and we can't allow that."); + return -EPERM; + } + } + + if (delete_root && !only_dirs) + if (unlink(path) < 0 && errno != ENOENT) + return -errno; + + return 0; + } + + if (!dangerous) { + if (fstatfs(fd, &s) < 0) { + close_nointr_nofail(fd); + return -errno; + } + + if (!is_temporary_fs(&s)) { + log_error("Attempted to remove disk file system, and we can't allow that."); + close_nointr_nofail(fd); + return -EPERM; + } + } + + r = rm_rf_children_dangerous(fd, only_dirs, honour_sticky, NULL); + if (delete_root) { + + if (honour_sticky && file_is_priv_sticky(path) > 0) + return r; + + if (rmdir(path) < 0 && errno != ENOENT) { + if (r == 0) + r = -errno; + } + } + + return r; +} + +int rm_rf(const char *path, bool only_dirs, bool delete_root, bool honour_sticky) { + return rm_rf_internal(path, only_dirs, delete_root, honour_sticky, false); +} + +int rm_rf_dangerous(const char *path, bool only_dirs, bool delete_root, bool honour_sticky) { + return rm_rf_internal(path, only_dirs, delete_root, honour_sticky, true); +} + +int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid) { + assert(path); + + /* Under the assumption that we are running privileged we + * first change the access mode and only then hand out + * ownership to avoid a window where access is too open. */ + + if (mode != (mode_t) -1) + if (chmod(path, mode) < 0) + return -errno; + + if (uid != (uid_t) -1 || gid != (gid_t) -1) + if (chown(path, uid, gid) < 0) + return -errno; + + return 0; +} + +int fchmod_and_fchown(int fd, mode_t mode, uid_t uid, gid_t gid) { + assert(fd >= 0); + + /* Under the assumption that we are running privileged we + * first change the access mode and only then hand out + * ownership to avoid a window where access is too open. */ + + if (fchmod(fd, mode) < 0) + return -errno; + + if (fchown(fd, uid, gid) < 0) + return -errno; + + return 0; +} + +cpu_set_t* cpu_set_malloc(unsigned *ncpus) { + cpu_set_t *r; + unsigned n = 1024; + + /* Allocates the cpuset in the right size */ + + for (;;) { + if (!(r = CPU_ALLOC(n))) + return NULL; + + if (sched_getaffinity(0, CPU_ALLOC_SIZE(n), r) >= 0) { + CPU_ZERO_S(CPU_ALLOC_SIZE(n), r); + + if (ncpus) + *ncpus = n; + + return r; + } + + CPU_FREE(r); + + if (errno != EINVAL) + return NULL; + + n *= 2; + } +} + +int status_vprintf(const char *status, bool ellipse, const char *format, va_list ap) { + static const char status_indent[] = " "; /* "[" STATUS "] " */ + _cleanup_free_ char *s = NULL; + _cleanup_close_ int fd = -1; + struct iovec iovec[5]; + int n = 0; + + assert(format); + + /* This is independent of logging, as status messages are + * optional and go exclusively to the console. */ + + if (vasprintf(&s, format, ap) < 0) + return log_oom(); + + fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC); + if (fd < 0) + return fd; + + if (ellipse) { + char *e; + size_t emax, sl; + int c; + + c = fd_columns(fd); + if (c <= 0) + c = 80; + + sl = status ? sizeof(status_indent)-1 : 0; + + emax = c - sl - 1; + if (emax < 3) + emax = 3; + + e = ellipsize(s, emax, 75); + if (e) { + free(s); + s = e; + } + } + + zero(iovec); + + if (status) { + if (!isempty(status)) { + IOVEC_SET_STRING(iovec[n++], "["); + IOVEC_SET_STRING(iovec[n++], status); + IOVEC_SET_STRING(iovec[n++], "] "); + } else + IOVEC_SET_STRING(iovec[n++], status_indent); + } + + IOVEC_SET_STRING(iovec[n++], s); + IOVEC_SET_STRING(iovec[n++], "\n"); + + if (writev(fd, iovec, n) < 0) + return -errno; + + return 0; +} + +int status_printf(const char *status, bool ellipse, const char *format, ...) { + va_list ap; + int r; + + assert(format); + + va_start(ap, format); + r = status_vprintf(status, ellipse, format, ap); + va_end(ap); + + return r; +} + +int status_welcome(void) { + int r; + _cleanup_free_ char *pretty_name = NULL, *ansi_color = NULL; + + r = parse_env_file("/etc/os-release", NEWLINE, + "PRETTY_NAME", &pretty_name, + "ANSI_COLOR", &ansi_color, + NULL); + if (r < 0 && r != -ENOENT) + log_warning("Failed to read /etc/os-release: %s", strerror(-r)); + + return status_printf(NULL, false, + "\nWelcome to \x1B[%sm%s\x1B[0m!\n", + isempty(ansi_color) ? "1" : ansi_color, + isempty(pretty_name) ? "Linux" : pretty_name); +} + +char *replace_env(const char *format, char **env) { + enum { + WORD, + CURLY, + VARIABLE + } state = WORD; + + const char *e, *word = format; + char *r = NULL, *k; + + assert(format); + + for (e = format; *e; e ++) { + + switch (state) { + + case WORD: + if (*e == '$') + state = CURLY; + break; + + case CURLY: + if (*e == '{') { + if (!(k = strnappend(r, word, e-word-1))) + goto fail; + + free(r); + r = k; + + word = e-1; + state = VARIABLE; + + } else if (*e == '$') { + if (!(k = strnappend(r, word, e-word))) + goto fail; + + free(r); + r = k; + + word = e+1; + state = WORD; + } else + state = WORD; + break; + + case VARIABLE: + if (*e == '}') { + const char *t; + + if (!(t = strv_env_get_with_length(env, word+2, e-word-2))) + t = ""; + + if (!(k = strappend(r, t))) + goto fail; + + free(r); + r = k; + + word = e+1; + state = WORD; + } + break; + } + } + + if (!(k = strnappend(r, word, e-word))) + goto fail; + + free(r); + return k; + +fail: + free(r); + return NULL; +} + +char **replace_env_argv(char **argv, char **env) { + char **r, **i; + unsigned k = 0, l = 0; + + l = strv_length(argv); + + if (!(r = new(char*, l+1))) + return NULL; + + STRV_FOREACH(i, argv) { + + /* If $FOO appears as single word, replace it by the split up variable */ + if ((*i)[0] == '$' && (*i)[1] != '{') { + char *e; + char **w, **m; + unsigned q; + + if ((e = strv_env_get(env, *i+1))) { + + if (!(m = strv_split_quoted(e))) { + r[k] = NULL; + strv_free(r); + return NULL; + } + } else + m = NULL; + + q = strv_length(m); + l = l + q - 1; + + if (!(w = realloc(r, sizeof(char*) * (l+1)))) { + r[k] = NULL; + strv_free(r); + strv_free(m); + return NULL; + } + + r = w; + if (m) { + memcpy(r + k, m, q * sizeof(char*)); + free(m); + } + + k += q; + continue; + } + + /* If ${FOO} appears as part of a word, replace it by the variable as-is */ + if (!(r[k++] = replace_env(*i, env))) { + strv_free(r); + return NULL; + } + } + + r[k] = NULL; + return r; +} + +int fd_columns(int fd) { + struct winsize ws; + zero(ws); + + if (ioctl(fd, TIOCGWINSZ, &ws) < 0) + return -errno; + + if (ws.ws_col <= 0) + return -EIO; + + return ws.ws_col; +} + +unsigned columns(void) { + const char *e; + int c; + + if (_likely_(cached_columns > 0)) + return cached_columns; + + c = 0; + e = getenv("COLUMNS"); + if (e) + safe_atoi(e, &c); + + if (c <= 0) + c = fd_columns(STDOUT_FILENO); + + if (c <= 0) + c = 80; + + cached_columns = c; + return c; +} + +int fd_lines(int fd) { + struct winsize ws; + zero(ws); + + if (ioctl(fd, TIOCGWINSZ, &ws) < 0) + return -errno; + + if (ws.ws_row <= 0) + return -EIO; + + return ws.ws_row; +} + +unsigned lines(void) { + const char *e; + unsigned l; + + if (_likely_(cached_lines > 0)) + return cached_lines; + + l = 0; + e = getenv("LINES"); + if (e) + safe_atou(e, &l); + + if (l <= 0) + l = fd_lines(STDOUT_FILENO); + + if (l <= 0) + l = 24; + + cached_lines = l; + return cached_lines; +} + +/* intended to be used as a SIGWINCH sighandler */ +void columns_lines_cache_reset(int signum) { + cached_columns = 0; + cached_lines = 0; +} + +bool on_tty(void) { + static int cached_on_tty = -1; + + if (_unlikely_(cached_on_tty < 0)) + cached_on_tty = isatty(STDOUT_FILENO) > 0; + + return cached_on_tty; +} + +int running_in_chroot(void) { + struct stat a, b; + + zero(a); + zero(b); + + /* Only works as root */ + + if (stat("/proc/1/root", &a) < 0) + return -errno; + + if (stat("/", &b) < 0) + return -errno; + + return + a.st_dev != b.st_dev || + a.st_ino != b.st_ino; +} + +char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent) { + size_t x; + char *r; + + assert(s); + assert(percent <= 100); + assert(new_length >= 3); + + if (old_length <= 3 || old_length <= new_length) + return strndup(s, old_length); + + r = new0(char, new_length+1); + if (!r) + return r; + + x = (new_length * percent) / 100; + + if (x > new_length - 3) + x = new_length - 3; + + memcpy(r, s, x); + r[x] = '.'; + r[x+1] = '.'; + r[x+2] = '.'; + memcpy(r + x + 3, + s + old_length - (new_length - x - 3), + new_length - x - 3); + + return r; +} + +char *ellipsize(const char *s, size_t length, unsigned percent) { + return ellipsize_mem(s, strlen(s), length, percent); +} + +int touch(const char *path) { + int fd; + + assert(path); + + /* This just opens the file for writing, ensuring it + * exists. It doesn't call utimensat() the way /usr/bin/touch + * does it. */ + + fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY, 0644); + if (fd < 0) + return -errno; + + close_nointr_nofail(fd); + return 0; +} + +char *unquote(const char *s, const char* quotes) { + size_t l; + assert(s); + + /* This is rather stupid, simply removes the heading and + * trailing quotes if there is one. Doesn't care about + * escaping or anything. We should make this smarter one + * day...*/ + + l = strlen(s); + if (l < 2) + return strdup(s); + + if (strchr(quotes, s[0]) && s[l-1] == s[0]) + return strndup(s+1, l-2); + + return strdup(s); +} + +char *normalize_env_assignment(const char *s) { + _cleanup_free_ char *name = NULL, *value = NULL, *p = NULL; + char *eq, *r; + + eq = strchr(s, '='); + if (!eq) { + char *t; + + r = strdup(s); + if (!r) + return NULL; + + t = strstrip(r); + if (t == r) + return r; + + memmove(r, t, strlen(t) + 1); + return r; + } + + name = strndup(s, eq - s); + if (!name) + return NULL; + + p = strdup(eq + 1); + if (!p) + return NULL; + + value = unquote(strstrip(p), QUOTES); + if (!value) + return NULL; + + if (asprintf(&r, "%s=%s", strstrip(name), value) < 0) + r = NULL; + + return r; +} + +int wait_for_terminate(pid_t pid, siginfo_t *status) { + siginfo_t dummy; + + assert(pid >= 1); + + if (!status) + status = &dummy; + + for (;;) { + zero(*status); + + if (waitid(P_PID, pid, status, WEXITED) < 0) { + + if (errno == EINTR) + continue; + + return -errno; + } + + return 0; + } +} + +int wait_for_terminate_and_warn(const char *name, pid_t pid) { + int r; + siginfo_t status; + + assert(name); + assert(pid > 1); + + r = wait_for_terminate(pid, &status); + if (r < 0) { + log_warning("Failed to wait for %s: %s", name, strerror(-r)); + return r; + } + + if (status.si_code == CLD_EXITED) { + if (status.si_status != 0) { + log_warning("%s failed with error code %i.", name, status.si_status); + return status.si_status; + } + + log_debug("%s succeeded.", name); + return 0; + + } else if (status.si_code == CLD_KILLED || + status.si_code == CLD_DUMPED) { + + log_warning("%s terminated by signal %s.", name, signal_to_string(status.si_status)); + return -EPROTO; + } + + log_warning("%s failed due to unknown reason.", name); + return -EPROTO; +} + +_noreturn_ void freeze(void) { + + /* Make sure nobody waits for us on a socket anymore */ + close_all_fds(NULL, 0); + + sync(); + + for (;;) + pause(); +} + +bool null_or_empty(struct stat *st) { + assert(st); + + if (S_ISREG(st->st_mode) && st->st_size <= 0) + return true; + + if (S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode)) + return true; + + return false; +} + +int null_or_empty_path(const char *fn) { + struct stat st; + + assert(fn); + + if (stat(fn, &st) < 0) + return -errno; + + return null_or_empty(&st); +} + +DIR *xopendirat(int fd, const char *name, int flags) { + int nfd; + DIR *d; + + nfd = openat(fd, name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|flags); + if (nfd < 0) + return NULL; + + d = fdopendir(nfd); + if (!d) { + close_nointr_nofail(nfd); + return NULL; + } + + return d; +} + +int signal_from_string_try_harder(const char *s) { + int signo; + assert(s); + + signo = signal_from_string(s); + if (signo <= 0) + if (startswith(s, "SIG")) + return signal_from_string(s+3); + + return signo; +} + +static char *tag_to_udev_node(const char *tagvalue, const char *by) { + char *dn, *t, *u; + int r; + + /* FIXME: to follow udev's logic 100% we need to leave valid + * UTF8 chars unescaped */ + + u = unquote(tagvalue, "\"\'"); + if (u == NULL) + return NULL; + + t = xescape(u, "/ "); + free(u); + + if (t == NULL) + return NULL; + + r = asprintf(&dn, "/dev/disk/by-%s/%s", by, t); + free(t); + + if (r < 0) + return NULL; + + return dn; +} + +char *fstab_node_to_udev_node(const char *p) { + assert(p); + + if (startswith(p, "LABEL=")) + return tag_to_udev_node(p+6, "label"); + + if (startswith(p, "UUID=")) + return tag_to_udev_node(p+5, "uuid"); + + if (startswith(p, "PARTUUID=")) + return tag_to_udev_node(p+9, "partuuid"); + + if (startswith(p, "PARTLABEL=")) + return tag_to_udev_node(p+10, "partlabel"); + + return strdup(p); +} + +bool tty_is_vc(const char *tty) { + assert(tty); + + if (startswith(tty, "/dev/")) + tty += 5; + + return vtnr_from_tty(tty) >= 0; +} + +bool tty_is_console(const char *tty) { + assert(tty); + + if (startswith(tty, "/dev/")) + tty += 5; + + return streq(tty, "console"); +} + +int vtnr_from_tty(const char *tty) { + int i, r; + + assert(tty); + + if (startswith(tty, "/dev/")) + tty += 5; + + if (!startswith(tty, "tty") ) + return -EINVAL; + + if (tty[3] < '0' || tty[3] > '9') + return -EINVAL; + + r = safe_atoi(tty+3, &i); + if (r < 0) + return r; + + if (i < 0 || i > 63) + return -EINVAL; + + return i; +} + +bool tty_is_vc_resolve(const char *tty) { + char *active = NULL; + bool b; + + assert(tty); + + if (startswith(tty, "/dev/")) + tty += 5; + + /* Resolve where /dev/console is pointing to, if /sys is + * actually ours (i.e. not read-only-mounted which is a sign + * for container setups) */ + if (streq(tty, "console") && path_is_read_only_fs("/sys") <= 0) + if (read_one_line_file("/sys/class/tty/console/active", &active) >= 0) { + /* If multiple log outputs are configured the + * last one is what /dev/console points to */ + tty = strrchr(active, ' '); + if (tty) + tty++; + else + tty = active; + } + + b = tty_is_vc(tty); + free(active); + + return b; +} + +const char *default_term_for_tty(const char *tty) { + assert(tty); + + return tty_is_vc_resolve(tty) ? "TERM=linux" : "TERM=vt102"; +} + +bool dirent_is_file(const struct dirent *de) { + assert(de); + + if (ignore_file(de->d_name)) + return false; + + if (de->d_type != DT_REG && + de->d_type != DT_LNK && + de->d_type != DT_UNKNOWN) + return false; + + return true; +} + +bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) { + assert(de); + + if (de->d_type != DT_REG && + de->d_type != DT_LNK && + de->d_type != DT_UNKNOWN) + return false; + + if (ignore_file_allow_backup(de->d_name)) + return false; + + return endswith(de->d_name, suffix); +} + +void execute_directory(const char *directory, DIR *d, char *argv[]) { + DIR *_d = NULL; + struct dirent *de; + Hashmap *pids = NULL; + + assert(directory); + + /* Executes all binaries in a directory in parallel and waits + * until all they all finished. */ + + if (!d) { + if (!(_d = opendir(directory))) { + + if (errno == ENOENT) + return; + + log_error("Failed to enumerate directory %s: %m", directory); + return; + } + + d = _d; + } + + if (!(pids = hashmap_new(trivial_hash_func, trivial_compare_func))) { + log_error("Failed to allocate set."); + goto finish; + } + + while ((de = readdir(d))) { + char *path; + pid_t pid; + int k; + + if (!dirent_is_file(de)) + continue; + + if (asprintf(&path, "%s/%s", directory, de->d_name) < 0) { + log_oom(); + continue; + } + + if ((pid = fork()) < 0) { + log_error("Failed to fork: %m"); + free(path); + continue; + } + + if (pid == 0) { + char *_argv[2]; + /* Child */ + + if (!argv) { + _argv[0] = path; + _argv[1] = NULL; + argv = _argv; + } else + argv[0] = path; + + execv(path, argv); + + log_error("Failed to execute %s: %m", path); + _exit(EXIT_FAILURE); + } + + log_debug("Spawned %s as %lu", path, (unsigned long) pid); + + if ((k = hashmap_put(pids, UINT_TO_PTR(pid), path)) < 0) { + log_error("Failed to add PID to set: %s", strerror(-k)); + free(path); + } + } + + while (!hashmap_isempty(pids)) { + pid_t pid = PTR_TO_UINT(hashmap_first_key(pids)); + siginfo_t si; + char *path; + + zero(si); + if (waitid(P_PID, pid, &si, WEXITED) < 0) { + + if (errno == EINTR) + continue; + + log_error("waitid() failed: %m"); + goto finish; + } + + if ((path = hashmap_remove(pids, UINT_TO_PTR(si.si_pid)))) { + if (!is_clean_exit(si.si_code, si.si_status, NULL)) { + if (si.si_code == CLD_EXITED) + log_error("%s exited with exit status %i.", path, si.si_status); + else + log_error("%s terminated by signal %s.", path, signal_to_string(si.si_status)); + } else + log_debug("%s exited successfully.", path); + + free(path); + } + } + +finish: + if (_d) + closedir(_d); + + if (pids) + hashmap_free_free(pids); +} + +int kill_and_sigcont(pid_t pid, int sig) { + int r; + + r = kill(pid, sig) < 0 ? -errno : 0; + + if (r >= 0) + kill(pid, SIGCONT); + + return r; +} + +bool nulstr_contains(const char*nulstr, const char *needle) { + const char *i; + + if (!nulstr) + return false; + + NULSTR_FOREACH(i, nulstr) + if (streq(i, needle)) + return true; + + return false; +} + +bool plymouth_running(void) { + return access("/run/plymouth/pid", F_OK) >= 0; +} + +char* strshorten(char *s, size_t l) { + assert(s); + + if (l < strlen(s)) + s[l] = 0; + + return s; +} + +static bool hostname_valid_char(char c) { + return + (c >= 'a' && c <= 'z') || + (c >= 'A' && c <= 'Z') || + (c >= '0' && c <= '9') || + c == '-' || + c == '_' || + c == '.'; +} + +bool hostname_is_valid(const char *s) { + const char *p; + + if (isempty(s)) + return false; + + for (p = s; *p; p++) + if (!hostname_valid_char(*p)) + return false; + + if (p-s > HOST_NAME_MAX) + return false; + + return true; +} + +char* hostname_cleanup(char *s) { + char *p, *d; + + for (p = s, d = s; *p; p++) + if ((*p >= 'a' && *p <= 'z') || + (*p >= 'A' && *p <= 'Z') || + (*p >= '0' && *p <= '9') || + *p == '-' || + *p == '_' || + *p == '.') + *(d++) = *p; + + *d = 0; + + strshorten(s, HOST_NAME_MAX); + return s; +} + +int pipe_eof(int fd) { + struct pollfd pollfd; + int r; + + zero(pollfd); + pollfd.fd = fd; + pollfd.events = POLLIN|POLLHUP; + + r = poll(&pollfd, 1, 0); + if (r < 0) + return -errno; + + if (r == 0) + return 0; + + return pollfd.revents & POLLHUP; +} + +int fd_wait_for_event(int fd, int event, usec_t t) { + struct pollfd pollfd; + int r; + + zero(pollfd); + pollfd.fd = fd; + pollfd.events = event; + + r = poll(&pollfd, 1, t == (usec_t) -1 ? -1 : (int) (t / USEC_PER_MSEC)); + if (r < 0) + return -errno; + + if (r == 0) + return 0; + + return pollfd.revents; +} + +int fopen_temporary(const char *path, FILE **_f, char **_temp_path) { + FILE *f; + char *t; + const char *fn; + size_t k; + int fd; + + assert(path); + assert(_f); + assert(_temp_path); + + t = new(char, strlen(path) + 1 + 6 + 1); + if (!t) + return -ENOMEM; + + fn = path_get_file_name(path); + k = fn-path; + memcpy(t, path, k); + t[k] = '.'; + stpcpy(stpcpy(t+k+1, fn), "XXXXXX"); + + fd = mkostemp(t, O_WRONLY|O_CLOEXEC); + if (fd < 0) { + free(t); + return -errno; + } + + f = fdopen(fd, "we"); + if (!f) { + unlink(t); + free(t); + return -errno; + } + + *_f = f; + *_temp_path = t; + + return 0; +} + +int terminal_vhangup_fd(int fd) { + assert(fd >= 0); + + if (ioctl(fd, TIOCVHANGUP) < 0) + return -errno; + + return 0; +} + +int terminal_vhangup(const char *name) { + int fd, r; + + fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC); + if (fd < 0) + return fd; + + r = terminal_vhangup_fd(fd); + close_nointr_nofail(fd); + + return r; +} + +int vt_disallocate(const char *name) { + int fd, r; + unsigned u; + + /* Deallocate the VT if possible. If not possible + * (i.e. because it is the active one), at least clear it + * entirely (including the scrollback buffer) */ + + if (!startswith(name, "/dev/")) + return -EINVAL; + + if (!tty_is_vc(name)) { + /* So this is not a VT. I guess we cannot deallocate + * it then. But let's at least clear the screen */ + + fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC); + if (fd < 0) + return fd; + + loop_write(fd, + "\033[r" /* clear scrolling region */ + "\033[H" /* move home */ + "\033[2J", /* clear screen */ + 10, false); + close_nointr_nofail(fd); + + return 0; + } + + if (!startswith(name, "/dev/tty")) + return -EINVAL; + + r = safe_atou(name+8, &u); + if (r < 0) + return r; + + if (u <= 0) + return -EINVAL; + + /* Try to deallocate */ + fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC); + if (fd < 0) + return fd; + + r = ioctl(fd, VT_DISALLOCATE, u); + close_nointr_nofail(fd); + + if (r >= 0) + return 0; + + if (errno != EBUSY) + return -errno; + + /* Couldn't deallocate, so let's clear it fully with + * scrollback */ + fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC); + if (fd < 0) + return fd; + + loop_write(fd, + "\033[r" /* clear scrolling region */ + "\033[H" /* move home */ + "\033[3J", /* clear screen including scrollback, requires Linux 2.6.40 */ + 10, false); + close_nointr_nofail(fd); + + return 0; +} + +int copy_file(const char *from, const char *to) { + int r, fdf, fdt; + + assert(from); + assert(to); + + fdf = open(from, O_RDONLY|O_CLOEXEC|O_NOCTTY); + if (fdf < 0) + return -errno; + + fdt = open(to, O_WRONLY|O_CREAT|O_EXCL|O_CLOEXEC|O_NOCTTY, 0644); + if (fdt < 0) { + close_nointr_nofail(fdf); + return -errno; + } + + for (;;) { + char buf[PIPE_BUF]; + ssize_t n, k; + + n = read(fdf, buf, sizeof(buf)); + if (n < 0) { + r = -errno; + + close_nointr_nofail(fdf); + close_nointr(fdt); + unlink(to); + + return r; + } + + if (n == 0) + break; + + errno = 0; + k = loop_write(fdt, buf, n, false); + if (n != k) { + r = k < 0 ? k : (errno ? -errno : -EIO); + + close_nointr_nofail(fdf); + close_nointr(fdt); + + unlink(to); + return r; + } + } + + close_nointr_nofail(fdf); + r = close_nointr(fdt); + + if (r < 0) { + unlink(to); + return r; + } + + return 0; +} + +int symlink_atomic(const char *from, const char *to) { + char *x; + _cleanup_free_ char *t; + const char *fn; + size_t k; + unsigned long long ull; + unsigned i; + int r; + + assert(from); + assert(to); + + t = new(char, strlen(to) + 1 + 16 + 1); + if (!t) + return -ENOMEM; + + fn = path_get_file_name(to); + k = fn-to; + memcpy(t, to, k); + t[k] = '.'; + x = stpcpy(t+k+1, fn); + + ull = random_ull(); + for (i = 0; i < 16; i++) { + *(x++) = hexchar(ull & 0xF); + ull >>= 4; + } + + *x = 0; + + if (symlink(from, t) < 0) + return -errno; + + if (rename(t, to) < 0) { + r = -errno; + unlink(t); + return r; + } + + return 0; +} + +bool display_is_local(const char *display) { + assert(display); + + return + display[0] == ':' && + display[1] >= '0' && + display[1] <= '9'; +} + +int socket_from_display(const char *display, char **path) { + size_t k; + char *f, *c; + + assert(display); + assert(path); + + if (!display_is_local(display)) + return -EINVAL; + + k = strspn(display+1, "0123456789"); + + f = new(char, sizeof("/tmp/.X11-unix/X") + k); + if (!f) + return -ENOMEM; + + c = stpcpy(f, "/tmp/.X11-unix/X"); + memcpy(c, display+1, k); + c[k] = 0; + + *path = f; + + return 0; +} + +int get_user_creds( + const char **username, + uid_t *uid, gid_t *gid, + const char **home, + const char **shell) { + + struct passwd *p; + uid_t u; + + assert(username); + assert(*username); + + /* We enforce some special rules for uid=0: in order to avoid + * NSS lookups for root we hardcode its data. */ + + if (streq(*username, "root") || streq(*username, "0")) { + *username = "root"; + + if (uid) + *uid = 0; + + if (gid) + *gid = 0; + + if (home) + *home = "/root"; + + if (shell) + *shell = "/bin/sh"; + + return 0; + } + + if (parse_uid(*username, &u) >= 0) { + errno = 0; + p = getpwuid(u); + + /* If there are multiple users with the same id, make + * sure to leave $USER to the configured value instead + * of the first occurrence in the database. However if + * the uid was configured by a numeric uid, then let's + * pick the real username from /etc/passwd. */ + if (p) + *username = p->pw_name; + } else { + errno = 0; + p = getpwnam(*username); + } + + if (!p) + return errno != 0 ? -errno : -ESRCH; + + if (uid) + *uid = p->pw_uid; + + if (gid) + *gid = p->pw_gid; + + if (home) + *home = p->pw_dir; + + if (shell) + *shell = p->pw_shell; + + return 0; +} + +int get_group_creds(const char **groupname, gid_t *gid) { + struct group *g; + gid_t id; + + assert(groupname); + + /* We enforce some special rules for gid=0: in order to avoid + * NSS lookups for root we hardcode its data. */ + + if (streq(*groupname, "root") || streq(*groupname, "0")) { + *groupname = "root"; + + if (gid) + *gid = 0; + + return 0; + } + + if (parse_gid(*groupname, &id) >= 0) { + errno = 0; + g = getgrgid(id); + + if (g) + *groupname = g->gr_name; + } else { + errno = 0; + g = getgrnam(*groupname); + } + + if (!g) + return errno != 0 ? -errno : -ESRCH; + + if (gid) + *gid = g->gr_gid; + + return 0; +} + +int in_group(const char *name) { + gid_t gid, *gids; + int ngroups_max, r, i; + + r = get_group_creds(&name, &gid); + if (r < 0) + return r; + + if (getgid() == gid) + return 1; + + if (getegid() == gid) + return 1; + + ngroups_max = sysconf(_SC_NGROUPS_MAX); + assert(ngroups_max > 0); + + gids = alloca(sizeof(gid_t) * ngroups_max); + + r = getgroups(ngroups_max, gids); + if (r < 0) + return -errno; + + for (i = 0; i < r; i++) + if (gids[i] == gid) + return 1; + + return 0; +} + +int glob_exists(const char *path) { + glob_t g; + int r, k; + + assert(path); + + zero(g); + errno = 0; + k = glob(path, GLOB_NOSORT|GLOB_BRACE, NULL, &g); + + if (k == GLOB_NOMATCH) + r = 0; + else if (k == GLOB_NOSPACE) + r = -ENOMEM; + else if (k == 0) + r = !strv_isempty(g.gl_pathv); + else + r = errno ? -errno : -EIO; + + globfree(&g); + + return r; +} + +int dirent_ensure_type(DIR *d, struct dirent *de) { + struct stat st; + + assert(d); + assert(de); + + if (de->d_type != DT_UNKNOWN) + return 0; + + if (fstatat(dirfd(d), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0) + return -errno; + + de->d_type = + S_ISREG(st.st_mode) ? DT_REG : + S_ISDIR(st.st_mode) ? DT_DIR : + S_ISLNK(st.st_mode) ? DT_LNK : + S_ISFIFO(st.st_mode) ? DT_FIFO : + S_ISSOCK(st.st_mode) ? DT_SOCK : + S_ISCHR(st.st_mode) ? DT_CHR : + S_ISBLK(st.st_mode) ? DT_BLK : + DT_UNKNOWN; + + return 0; +} + +int in_search_path(const char *path, char **search) { + char **i, *parent; + int r; + + r = path_get_parent(path, &parent); + if (r < 0) + return r; + + r = 0; + + STRV_FOREACH(i, search) { + if (path_equal(parent, *i)) { + r = 1; + break; + } + } + + free(parent); + + return r; +} + +int get_files_in_directory(const char *path, char ***list) { + DIR *d; + int r = 0; + unsigned n = 0; + char **l = NULL; + + assert(path); + + /* Returns all files in a directory in *list, and the number + * of files as return value. If list is NULL returns only the + * number */ + + d = opendir(path); + if (!d) + return -errno; + + for (;;) { + struct dirent *de; + union dirent_storage buf; + int k; + + k = readdir_r(d, &buf.de, &de); + if (k != 0) { + r = -k; + goto finish; + } + + if (!de) + break; + + dirent_ensure_type(d, de); + + if (!dirent_is_file(de)) + continue; + + if (list) { + if ((unsigned) r >= n) { + char **t; + + n = MAX(16, 2*r); + t = realloc(l, sizeof(char*) * n); + if (!t) { + r = -ENOMEM; + goto finish; + } + + l = t; + } + + assert((unsigned) r < n); + + l[r] = strdup(de->d_name); + if (!l[r]) { + r = -ENOMEM; + goto finish; + } + + l[++r] = NULL; + } else + r++; + } + +finish: + if (d) + closedir(d); + + if (r >= 0) { + if (list) + *list = l; + } else + strv_free(l); + + return r; +} + +char *strjoin(const char *x, ...) { + va_list ap; + size_t l; + char *r, *p; + + va_start(ap, x); + + if (x) { + l = strlen(x); + + for (;;) { + const char *t; + size_t n; + + t = va_arg(ap, const char *); + if (!t) + break; + + n = strlen(t); + if (n > ((size_t) -1) - l) { + va_end(ap); + return NULL; + } + + l += n; + } + } else + l = 0; + + va_end(ap); + + r = new(char, l+1); + if (!r) + return NULL; + + if (x) { + p = stpcpy(r, x); + + va_start(ap, x); + + for (;;) { + const char *t; + + t = va_arg(ap, const char *); + if (!t) + break; + + p = stpcpy(p, t); + } + + va_end(ap); + } else + r[0] = 0; + + return r; +} + +bool is_main_thread(void) { + static __thread int cached = 0; + + if (_unlikely_(cached == 0)) + cached = getpid() == gettid() ? 1 : -1; + + return cached > 0; +} + +int block_get_whole_disk(dev_t d, dev_t *ret) { + char *p, *s; + int r; + unsigned n, m; + + assert(ret); + + /* If it has a queue this is good enough for us */ + if (asprintf(&p, "/sys/dev/block/%u:%u/queue", major(d), minor(d)) < 0) + return -ENOMEM; + + r = access(p, F_OK); + free(p); + + if (r >= 0) { + *ret = d; + return 0; + } + + /* If it is a partition find the originating device */ + if (asprintf(&p, "/sys/dev/block/%u:%u/partition", major(d), minor(d)) < 0) + return -ENOMEM; + + r = access(p, F_OK); + free(p); + + if (r < 0) + return -ENOENT; + + /* Get parent dev_t */ + if (asprintf(&p, "/sys/dev/block/%u:%u/../dev", major(d), minor(d)) < 0) + return -ENOMEM; + + r = read_one_line_file(p, &s); + free(p); + + if (r < 0) + return r; + + r = sscanf(s, "%u:%u", &m, &n); + free(s); + + if (r != 2) + return -EINVAL; + + /* Only return this if it is really good enough for us. */ + if (asprintf(&p, "/sys/dev/block/%u:%u/queue", m, n) < 0) + return -ENOMEM; + + r = access(p, F_OK); + free(p); + + if (r >= 0) { + *ret = makedev(m, n); + return 0; + } + + return -ENOENT; +} + +int file_is_priv_sticky(const char *p) { + struct stat st; + + assert(p); + + if (lstat(p, &st) < 0) + return -errno; + + return + (st.st_uid == 0 || st.st_uid == getuid()) && + (st.st_mode & S_ISVTX); +} + +static const char *const ioprio_class_table[] = { + [IOPRIO_CLASS_NONE] = "none", + [IOPRIO_CLASS_RT] = "realtime", + [IOPRIO_CLASS_BE] = "best-effort", + [IOPRIO_CLASS_IDLE] = "idle" +}; + +DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ioprio_class, int, INT_MAX); + +static const char *const sigchld_code_table[] = { + [CLD_EXITED] = "exited", + [CLD_KILLED] = "killed", + [CLD_DUMPED] = "dumped", + [CLD_TRAPPED] = "trapped", + [CLD_STOPPED] = "stopped", + [CLD_CONTINUED] = "continued", +}; + +DEFINE_STRING_TABLE_LOOKUP(sigchld_code, int); + +static const char *const log_facility_unshifted_table[LOG_NFACILITIES] = { + [LOG_FAC(LOG_KERN)] = "kern", + [LOG_FAC(LOG_USER)] = "user", + [LOG_FAC(LOG_MAIL)] = "mail", + [LOG_FAC(LOG_DAEMON)] = "daemon", + [LOG_FAC(LOG_AUTH)] = "auth", + [LOG_FAC(LOG_SYSLOG)] = "syslog", + [LOG_FAC(LOG_LPR)] = "lpr", + [LOG_FAC(LOG_NEWS)] = "news", + [LOG_FAC(LOG_UUCP)] = "uucp", + [LOG_FAC(LOG_CRON)] = "cron", + [LOG_FAC(LOG_AUTHPRIV)] = "authpriv", + [LOG_FAC(LOG_FTP)] = "ftp", + [LOG_FAC(LOG_LOCAL0)] = "local0", + [LOG_FAC(LOG_LOCAL1)] = "local1", + [LOG_FAC(LOG_LOCAL2)] = "local2", + [LOG_FAC(LOG_LOCAL3)] = "local3", + [LOG_FAC(LOG_LOCAL4)] = "local4", + [LOG_FAC(LOG_LOCAL5)] = "local5", + [LOG_FAC(LOG_LOCAL6)] = "local6", + [LOG_FAC(LOG_LOCAL7)] = "local7" +}; + +DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(log_facility_unshifted, int, LOG_FAC(~0)); + +static const char *const log_level_table[] = { + [LOG_EMERG] = "emerg", + [LOG_ALERT] = "alert", + [LOG_CRIT] = "crit", + [LOG_ERR] = "err", + [LOG_WARNING] = "warning", + [LOG_NOTICE] = "notice", + [LOG_INFO] = "info", + [LOG_DEBUG] = "debug" +}; + +DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(log_level, int, LOG_DEBUG); + +static const char* const sched_policy_table[] = { + [SCHED_OTHER] = "other", + [SCHED_BATCH] = "batch", + [SCHED_IDLE] = "idle", + [SCHED_FIFO] = "fifo", + [SCHED_RR] = "rr" +}; + +DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(sched_policy, int, INT_MAX); + +static const char* const rlimit_table[] = { + [RLIMIT_CPU] = "LimitCPU", + [RLIMIT_FSIZE] = "LimitFSIZE", + [RLIMIT_DATA] = "LimitDATA", + [RLIMIT_STACK] = "LimitSTACK", + [RLIMIT_CORE] = "LimitCORE", + [RLIMIT_RSS] = "LimitRSS", + [RLIMIT_NOFILE] = "LimitNOFILE", + [RLIMIT_AS] = "LimitAS", + [RLIMIT_NPROC] = "LimitNPROC", + [RLIMIT_MEMLOCK] = "LimitMEMLOCK", + [RLIMIT_LOCKS] = "LimitLOCKS", + [RLIMIT_SIGPENDING] = "LimitSIGPENDING", + [RLIMIT_MSGQUEUE] = "LimitMSGQUEUE", + [RLIMIT_NICE] = "LimitNICE", + [RLIMIT_RTPRIO] = "LimitRTPRIO", + [RLIMIT_RTTIME] = "LimitRTTIME" +}; + +DEFINE_STRING_TABLE_LOOKUP(rlimit, int); + +static const char* const ip_tos_table[] = { + [IPTOS_LOWDELAY] = "low-delay", + [IPTOS_THROUGHPUT] = "throughput", + [IPTOS_RELIABILITY] = "reliability", + [IPTOS_LOWCOST] = "low-cost", +}; + +DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ip_tos, int, 0xff); + +static const char *const __signal_table[] = { + [SIGHUP] = "HUP", + [SIGINT] = "INT", + [SIGQUIT] = "QUIT", + [SIGILL] = "ILL", + [SIGTRAP] = "TRAP", + [SIGABRT] = "ABRT", + [SIGBUS] = "BUS", + [SIGFPE] = "FPE", + [SIGKILL] = "KILL", + [SIGUSR1] = "USR1", + [SIGSEGV] = "SEGV", + [SIGUSR2] = "USR2", + [SIGPIPE] = "PIPE", + [SIGALRM] = "ALRM", + [SIGTERM] = "TERM", +#ifdef SIGSTKFLT + [SIGSTKFLT] = "STKFLT", /* Linux on SPARC doesn't know SIGSTKFLT */ +#endif + [SIGCHLD] = "CHLD", + [SIGCONT] = "CONT", + [SIGSTOP] = "STOP", + [SIGTSTP] = "TSTP", + [SIGTTIN] = "TTIN", + [SIGTTOU] = "TTOU", + [SIGURG] = "URG", + [SIGXCPU] = "XCPU", + [SIGXFSZ] = "XFSZ", + [SIGVTALRM] = "VTALRM", + [SIGPROF] = "PROF", + [SIGWINCH] = "WINCH", + [SIGIO] = "IO", + [SIGPWR] = "PWR", + [SIGSYS] = "SYS" +}; + +DEFINE_PRIVATE_STRING_TABLE_LOOKUP(__signal, int); + +const char *signal_to_string(int signo) { + static __thread char buf[12]; + const char *name; + + name = __signal_to_string(signo); + if (name) + return name; + + if (signo >= SIGRTMIN && signo <= SIGRTMAX) + snprintf(buf, sizeof(buf) - 1, "RTMIN+%d", signo - SIGRTMIN); + else + snprintf(buf, sizeof(buf) - 1, "%d", signo); + char_array_0(buf); + return buf; +} + +int signal_from_string(const char *s) { + int signo; + int offset = 0; + unsigned u; + + signo = __signal_from_string(s); + if (signo > 0) + return signo; + + if (startswith(s, "RTMIN+")) { + s += 6; + offset = SIGRTMIN; + } + if (safe_atou(s, &u) >= 0) { + signo = (int) u + offset; + if (signo > 0 && signo < _NSIG) + return signo; + } + return -1; +} + +bool kexec_loaded(void) { + bool loaded = false; + char *s; + + if (read_one_line_file("/sys/kernel/kexec_loaded", &s) >= 0) { + if (s[0] == '1') + loaded = true; + free(s); + } + return loaded; +} + +int strdup_or_null(const char *a, char **b) { + char *c; + + assert(b); + + if (!a) { + *b = NULL; + return 0; + } + + c = strdup(a); + if (!c) + return -ENOMEM; + + *b = c; + return 0; +} + +int prot_from_flags(int flags) { + + switch (flags & O_ACCMODE) { + + case O_RDONLY: + return PROT_READ; + + case O_WRONLY: + return PROT_WRITE; + + case O_RDWR: + return PROT_READ|PROT_WRITE; + + default: + return -EINVAL; + } +} + +char *format_bytes(char *buf, size_t l, off_t t) { + unsigned i; + + static const struct { + const char *suffix; + off_t factor; + } table[] = { + { "E", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL*1024ULL }, + { "P", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL }, + { "T", 1024ULL*1024ULL*1024ULL*1024ULL }, + { "G", 1024ULL*1024ULL*1024ULL }, + { "M", 1024ULL*1024ULL }, + { "K", 1024ULL }, + }; + + for (i = 0; i < ELEMENTSOF(table); i++) { + + if (t >= table[i].factor) { + snprintf(buf, l, + "%llu.%llu%s", + (unsigned long long) (t / table[i].factor), + (unsigned long long) (((t*10ULL) / table[i].factor) % 10ULL), + table[i].suffix); + + goto finish; + } + } + + snprintf(buf, l, "%lluB", (unsigned long long) t); + +finish: + buf[l-1] = 0; + return buf; + +} + +void* memdup(const void *p, size_t l) { + void *r; + + assert(p); + + r = malloc(l); + if (!r) + return NULL; + + memcpy(r, p, l); + return r; +} + +int fd_inc_sndbuf(int fd, size_t n) { + int r, value; + socklen_t l = sizeof(value); + + r = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, &l); + if (r >= 0 && + l == sizeof(value) && + (size_t) value >= n*2) + return 0; + + value = (int) n; + r = setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, sizeof(value)); + if (r < 0) + return -errno; + + return 1; +} + +int fd_inc_rcvbuf(int fd, size_t n) { + int r, value; + socklen_t l = sizeof(value); + + r = getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, &l); + if (r >= 0 && + l == sizeof(value) && + (size_t) value >= n*2) + return 0; + + value = (int) n; + r = setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, sizeof(value)); + if (r < 0) + return -errno; + + return 1; +} + +int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *path, ...) { + pid_t parent_pid, agent_pid; + int fd; + bool stdout_is_tty, stderr_is_tty; + unsigned n, i; + va_list ap; + char **l; + + assert(pid); + assert(path); + + parent_pid = getpid(); + + /* Spawns a temporary TTY agent, making sure it goes away when + * we go away */ + + agent_pid = fork(); + if (agent_pid < 0) + return -errno; + + if (agent_pid != 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); + + /* Check whether our parent died before we were able + * to set the death signal */ + 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) { + /* 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("Failed to open /dev/tty: %m"); + _exit(EXIT_FAILURE); + } + + if (!stdout_is_tty) + dup2(fd, STDOUT_FILENO); + + if (!stderr_is_tty) + dup2(fd, STDERR_FILENO); + + if (fd > 2) + 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); +} + +int setrlimit_closest(int resource, const struct rlimit *rlim) { + struct rlimit highest, fixed; + + assert(rlim); + + if (setrlimit(resource, rlim) >= 0) + return 0; + + if (errno != EPERM) + return -errno; + + /* So we failed to set the desired setrlimit, then let's try + * to get as close as we can */ + assert_se(getrlimit(resource, &highest) == 0); + + fixed.rlim_cur = MIN(rlim->rlim_cur, highest.rlim_max); + fixed.rlim_max = MIN(rlim->rlim_max, highest.rlim_max); + + if (setrlimit(resource, &fixed) < 0) + return -errno; + + return 0; +} + +int getenv_for_pid(pid_t pid, const char *field, char **_value) { + char path[sizeof("/proc/")-1+10+sizeof("/environ")], *value = NULL; + int r; + FILE *f; + bool done = false; + size_t l; + + assert(field); + assert(_value); + + if (pid == 0) + pid = getpid(); + + snprintf(path, sizeof(path), "/proc/%lu/environ", (unsigned long) pid); + char_array_0(path); + + f = fopen(path, "re"); + if (!f) + return -errno; + + l = strlen(field); + r = 0; + + do { + char line[LINE_MAX]; + unsigned i; + + for (i = 0; i < sizeof(line)-1; i++) { + int c; + + c = getc(f); + if (_unlikely_(c == EOF)) { + done = true; + break; + } else if (c == 0) + break; + + line[i] = c; + } + line[i] = 0; + + if (memcmp(line, field, l) == 0 && line[l] == '=') { + value = strdup(line + l + 1); + if (!value) { + r = -ENOMEM; + break; + } + + r = 1; + break; + } + + } while (!done); + + fclose(f); + + if (r >= 0) + *_value = value; + + return r; +} + +int can_sleep(const char *type) { + char *w, *state; + size_t l, k; + int r; + _cleanup_free_ char *p = NULL; + + assert(type); + + /* If /sys is read-only we cannot sleep */ + if (access("/sys/power/state", W_OK) < 0) + return false; + + r = read_one_line_file("/sys/power/state", &p); + if (r < 0) + return false; + + k = strlen(type); + FOREACH_WORD_SEPARATOR(w, l, p, WHITESPACE, state) + if (l == k && memcmp(w, type, l) == 0) + return true; + + return false; +} + +int can_sleep_disk(const char *type) { + char *w, *state; + size_t l, k; + int r; + _cleanup_free_ char *p = NULL; + + assert(type); + + /* If /sys is read-only we cannot sleep */ + if (access("/sys/power/state", W_OK) < 0 || + access("/sys/power/disk", W_OK) < 0) + return false; + + r = read_one_line_file("/sys/power/disk", &p); + if (r < 0) + return false; + + k = strlen(type); + FOREACH_WORD_SEPARATOR(w, l, p, WHITESPACE, state) { + if (l == k && memcmp(w, type, l) == 0) + return true; + + if (l == k + 2 && w[0] == '[' && memcmp(w + 1, type, l - 2) == 0 && w[l-1] == ']') + return true; + } + + return false; +} + +bool is_valid_documentation_url(const char *url) { + assert(url); + + if (startswith(url, "http://") && url[7]) + return true; + + if (startswith(url, "https://") && url[8]) + return true; + + if (startswith(url, "file:") && url[5]) + return true; + + if (startswith(url, "info:") && url[5]) + return true; + + if (startswith(url, "man:") && url[4]) + return true; + + return false; +} + +bool in_initrd(void) { + static __thread int saved = -1; + struct statfs s; + + if (saved >= 0) + return saved; + + /* We make two checks here: + * + * 1. the flag file /etc/initrd-release must exist + * 2. the root file system must be a memory file system + * + * The second check is extra paranoia, since misdetecting an + * initrd can have bad bad consequences due the initrd + * emptying when transititioning to the main systemd. + */ + + saved = access("/etc/initrd-release", F_OK) >= 0 && + statfs("/", &s) >= 0 && + is_temporary_fs(&s); + + return saved; +} + +void warn_melody(void) { + _cleanup_close_ int fd = -1; + + fd = open("/dev/console", O_WRONLY|O_CLOEXEC|O_NOCTTY); + if (fd < 0) + return; + + /* Yeah, this is synchronous. Kinda sucks. But well... */ + + ioctl(fd, KIOCSOUND, (int)(1193180/440)); + usleep(125*USEC_PER_MSEC); + + ioctl(fd, KIOCSOUND, (int)(1193180/220)); + usleep(125*USEC_PER_MSEC); + + ioctl(fd, KIOCSOUND, (int)(1193180/220)); + usleep(125*USEC_PER_MSEC); + + ioctl(fd, KIOCSOUND, 0); +} + +int make_console_stdio(void) { + int fd, r; + + /* Make /dev/console the controlling terminal and stdin/stdout/stderr */ + + fd = acquire_terminal("/dev/console", false, true, true, (usec_t) -1); + if (fd < 0) { + log_error("Failed to acquire terminal: %s", strerror(-fd)); + return fd; + } + + r = make_stdio(fd); + if (r < 0) { + log_error("Failed to duplicate terminal fd: %s", strerror(-r)); + return r; + } + + return 0; +} + +int get_home_dir(char **_h) { + char *h; + const char *e; + uid_t u; + struct passwd *p; + + assert(_h); + + /* Take the user specified one */ + e = getenv("HOME"); + if (e) { + h = strdup(e); + if (!h) + return -ENOMEM; + + *_h = h; + return 0; + } + + /* Hardcode home directory for root to avoid NSS */ + u = getuid(); + if (u == 0) { + h = strdup("/root"); + if (!h) + return -ENOMEM; + + *_h = h; + return 0; + } + + /* Check the database... */ + errno = 0; + p = getpwuid(u); + if (!p) + return errno ? -errno : -ESRCH; + + if (!path_is_absolute(p->pw_dir)) + return -EINVAL; + + h = strdup(p->pw_dir); + if (!h) + return -ENOMEM; + + *_h = h; + return 0; +} + +int get_shell(char **_sh) { + char *sh; + const char *e; + uid_t u; + struct passwd *p; + + assert(_sh); + + /* Take the user specified one */ + e = getenv("SHELL"); + if (e) { + sh = strdup(e); + if (!sh) + return -ENOMEM; + + *_sh = sh; + return 0; + } + + /* Hardcode home directory for root to avoid NSS */ + u = getuid(); + if (u == 0) { + sh = strdup("/bin/sh"); + if (!sh) + return -ENOMEM; + + *_sh = sh; + return 0; + } + + /* Check the database... */ + errno = 0; + p = getpwuid(u); + if (!p) + return errno ? -errno : -ESRCH; + + if (!path_is_absolute(p->pw_shell)) + return -EINVAL; + + sh = strdup(p->pw_shell); + if (!sh) + return -ENOMEM; + + *_sh = sh; + return 0; +} + +void freep(void *p) { + free(*(void**) p); +} + +void fclosep(FILE **f) { + if (*f) + fclose(*f); +} + +void closep(int *fd) { + if (*fd >= 0) + close_nointr_nofail(*fd); +} + +void closedirp(DIR **d) { + if (*d) + closedir(*d); +} + +void umaskp(mode_t *u) { + umask(*u); +} + +bool filename_is_safe(const char *p) { + + if (isempty(p)) + return false; + + if (strchr(p, '/')) + return false; + + if (streq(p, ".")) + return false; + + if (streq(p, "..")) + return false; + + if (strlen(p) > FILENAME_MAX) + return false; + + return true; +} + +bool string_is_safe(const char *p) { + const char *t; + + assert(p); + + for (t = p; *t; t++) { + if (*t > 0 && *t < ' ') + return false; + + if (strchr("\\\"\'", *t)) + return false; + } + + return true; +} + +/* hey glibc, APIs with callbacks without a user pointer are so useless */ +void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size, + int (*compar) (const void *, const void *, void *), void *arg) { + size_t l, u, idx; + const void *p; + int comparison; + + l = 0; + u = nmemb; + while (l < u) { + idx = (l + u) / 2; + p = (void *)(((const char *) base) + (idx * size)); + comparison = compar(key, p, arg); + if (comparison < 0) + u = idx; + else if (comparison > 0) + l = idx + 1; + else + return (void *)p; + } + return NULL; +} + +bool is_locale_utf8(void) { + const char *set; + static int cached_answer = -1; + + if (cached_answer >= 0) + goto out; + + if (!setlocale(LC_ALL, "")) { + cached_answer = true; + goto out; + } + + set = nl_langinfo(CODESET); + if (!set) { + cached_answer = true; + goto out; + } + + cached_answer = streq(set, "UTF-8"); +out: + return (bool)cached_answer; +} + +const char *draw_special_char(DrawSpecialChar ch) { + static const char *draw_table[2][_DRAW_SPECIAL_CHAR_MAX] = { + /* UTF-8 */ { + [DRAW_TREE_VERT] = "\342\224\202 ", /* │ */ + [DRAW_TREE_BRANCH] = "\342\224\234\342\224\200", /* ├─ */ + [DRAW_TREE_RIGHT] = "\342\224\224\342\224\200", /* └─ */ + [DRAW_TRIANGULAR_BULLET] = "\342\200\243 ", /* ‣ */ + }, + /* ASCII fallback */ { + [DRAW_TREE_VERT] = "| ", + [DRAW_TREE_BRANCH] = "|-", + [DRAW_TREE_RIGHT] = "`-", + [DRAW_TRIANGULAR_BULLET] = "> ", + } + }; + + return draw_table[!is_locale_utf8()][ch]; +} + +char *strreplace(const char *text, const char *old_string, const char *new_string) { + const char *f; + char *t, *r; + size_t l, old_len, new_len; + + assert(text); + assert(old_string); + assert(new_string); + + old_len = strlen(old_string); + new_len = strlen(new_string); + + l = strlen(text); + r = new(char, l+1); + if (!r) + return NULL; + + f = text; + t = r; + while (*f) { + char *a; + size_t d, nl; + + if (!startswith(f, old_string)) { + *(t++) = *(f++); + continue; + } + + d = t - r; + nl = l - old_len + new_len; + a = realloc(r, nl + 1); + if (!a) + goto oom; + + l = nl; + r = a; + t = r + d; + + t = stpcpy(t, new_string); + f += old_len; + } + + *t = 0; + return r; + +oom: + free(r); + return NULL; +} + +char *strip_tab_ansi(char **ibuf, size_t *_isz) { + const char *i, *begin = NULL; + enum { + STATE_OTHER, + STATE_ESCAPE, + STATE_BRACKET + } state = STATE_OTHER; + char *obuf = NULL; + size_t osz = 0, isz; + FILE *f; + + assert(ibuf); + assert(*ibuf); + + /* Strips ANSI color and replaces TABs by 8 spaces */ + + isz = _isz ? *_isz : strlen(*ibuf); + + f = open_memstream(&obuf, &osz); + if (!f) + return NULL; + + for (i = *ibuf; i < *ibuf + isz + 1; i++) { + + switch (state) { + + case STATE_OTHER: + if (i >= *ibuf + isz) /* EOT */ + break; + else if (*i == '\x1B') + state = STATE_ESCAPE; + else if (*i == '\t') + fputs(" ", f); + else + fputc(*i, f); + break; + + case STATE_ESCAPE: + if (i >= *ibuf + isz) { /* EOT */ + fputc('\x1B', f); + break; + } else if (*i == '[') { + state = STATE_BRACKET; + begin = i + 1; + } else { + fputc('\x1B', f); + fputc(*i, f); + state = STATE_OTHER; + } + + break; + + case STATE_BRACKET: + + if (i >= *ibuf + isz || /* EOT */ + (!(*i >= '0' && *i <= '9') && *i != ';' && *i != 'm')) { + fputc('\x1B', f); + fputc('[', f); + state = STATE_OTHER; + i = begin-1; + } else if (*i == 'm') + state = STATE_OTHER; + break; + } + } + + if (ferror(f)) { + fclose(f); + free(obuf); + return NULL; + } + + fclose(f); + + free(*ibuf); + *ibuf = obuf; + + if (_isz) + *_isz = osz; + + return obuf; +} + +int on_ac_power(void) { + bool found_offline = false, found_online = false; + _cleanup_closedir_ DIR *d = NULL; + + d = opendir("/sys/class/power_supply"); + if (!d) + return -errno; + + for (;;) { + struct dirent *de; + union dirent_storage buf; + _cleanup_free_ char *p = NULL; + _cleanup_close_ int fd = -1, device = -1; + char contents[6]; + ssize_t n; + int k; + + k = readdir_r(d, &buf.de, &de); + if (k != 0) + return -k; + + if (!de) + break; + + if (ignore_file(de->d_name)) + continue; + + device = openat(dirfd(d), de->d_name, O_DIRECTORY|O_RDONLY|O_CLOEXEC|O_NOCTTY); + if (device < 0) { + if (errno == ENOENT || errno == ENOTDIR) + continue; + + return -errno; + } + + fd = openat(device, "type", O_RDONLY|O_CLOEXEC|O_NOCTTY); + if (fd < 0) { + if (errno == ENOENT) + continue; + + return -errno; + } + + n = read(fd, contents, sizeof(contents)); + if (n < 0) + return -errno; + + if (n != 6 || memcmp(contents, "Mains\n", 6)) + continue; + + close_nointr_nofail(fd); + fd = openat(device, "online", O_RDONLY|O_CLOEXEC|O_NOCTTY); + if (fd < 0) { + if (errno == ENOENT) + continue; + + return -errno; + } + + n = read(fd, contents, sizeof(contents)); + if (n < 0) + return -errno; + + if (n != 2 || contents[1] != '\n') + return -EIO; + + if (contents[0] == '1') { + found_online = true; + break; + } else if (contents[0] == '0') + found_offline = true; + else + return -EIO; + } + + return found_online || !found_offline; +} diff --git a/src/shared/util.h b/src/shared/util.h new file mode 100644 index 000000000..bb6602fb2 --- /dev/null +++ b/src/shared/util.h @@ -0,0 +1,565 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "macro.h" +#include "time-util.h" + +union dirent_storage { + struct dirent de; + uint8_t storage[offsetof(struct dirent, d_name) + + ((NAME_MAX + 1 + sizeof(long)) & ~(sizeof(long) - 1))]; +}; + +/* What is interpreted as whitespace? */ +#define WHITESPACE " \t\n\r" +#define NEWLINE "\n\r" +#define QUOTES "\"\'" +#define COMMENTS "#;\n" + +#define FORMAT_BYTES_MAX 8 + +#define ANSI_HIGHLIGHT_ON "\x1B[1;39m" +#define ANSI_HIGHLIGHT_RED_ON "\x1B[1;31m" +#define ANSI_HIGHLIGHT_GREEN_ON "\x1B[1;32m" +#define ANSI_HIGHLIGHT_YELLOW_ON "\x1B[1;33m" +#define ANSI_HIGHLIGHT_OFF "\x1B[0m" + +bool is_efiboot(void); + +size_t page_size(void); +#define PAGE_ALIGN(l) ALIGN_TO((l), page_size()) + +#define streq(a,b) (strcmp((a),(b)) == 0) +#define strneq(a, b, n) (strncmp((a), (b), (n)) == 0) + +bool streq_ptr(const char *a, const char *b); + +#define new(t, n) ((t*) malloc_multiply(sizeof(t), (n))) + +#define new0(t, n) ((t*) calloc((n), sizeof(t))) + +#define newa(t, n) ((t*) alloca(sizeof(t)*(n))) + +#define newdup(t, p, n) ((t*) memdup_multiply(p, sizeof(t), (n))) + +#define malloc0(n) (calloc((n), 1)) + +static inline const char* yes_no(bool b) { + return b ? "yes" : "no"; +} + +static inline const char* strempty(const char *s) { + return s ? s : ""; +} + +static inline const char* strnull(const char *s) { + return s ? s : "(null)"; +} + +static inline const char *strna(const char *s) { + return s ? s : "n/a"; +} + +static inline bool isempty(const char *p) { + return !p || !p[0]; +} + +char *endswith(const char *s, const char *postfix); +char *startswith(const char *s, const char *prefix); +char *startswith_no_case(const char *s, const char *prefix); + +bool first_word(const char *s, const char *word); + +int close_nointr(int fd); +void close_nointr_nofail(int fd); +void close_many(const int fds[], unsigned n_fd); + +int parse_boolean(const char *v); +int parse_bytes(const char *t, off_t *bytes); +int parse_pid(const char *s, pid_t* ret_pid); +int parse_uid(const char *s, uid_t* ret_uid); +#define parse_gid(s, ret_uid) parse_uid(s, ret_uid) + +int safe_atou(const char *s, unsigned *ret_u); +int safe_atoi(const char *s, int *ret_i); + +int safe_atollu(const char *s, unsigned long long *ret_u); +int safe_atolli(const char *s, long long int *ret_i); + +#if __WORDSIZE == 32 +static inline int safe_atolu(const char *s, unsigned long *ret_u) { + assert_cc(sizeof(unsigned long) == sizeof(unsigned)); + return safe_atou(s, (unsigned*) ret_u); +} +static inline int safe_atoli(const char *s, long int *ret_u) { + assert_cc(sizeof(long int) == sizeof(int)); + return safe_atoi(s, (int*) ret_u); +} +#else +static inline int safe_atolu(const char *s, unsigned long *ret_u) { + assert_cc(sizeof(unsigned long) == sizeof(unsigned long long)); + return safe_atollu(s, (unsigned long long*) ret_u); +} +static inline int safe_atoli(const char *s, long int *ret_u) { + assert_cc(sizeof(long int) == sizeof(long long int)); + return safe_atolli(s, (long long int*) ret_u); +} +#endif + +static inline int safe_atou32(const char *s, uint32_t *ret_u) { + assert_cc(sizeof(uint32_t) == sizeof(unsigned)); + return safe_atou(s, (unsigned*) ret_u); +} + +static inline int safe_atoi32(const char *s, int32_t *ret_i) { + assert_cc(sizeof(int32_t) == sizeof(int)); + return safe_atoi(s, (int*) ret_i); +} + +static inline int safe_atou64(const char *s, uint64_t *ret_u) { + assert_cc(sizeof(uint64_t) == sizeof(unsigned long long)); + return safe_atollu(s, (unsigned long long*) ret_u); +} + +static inline int safe_atoi64(const char *s, int64_t *ret_i) { + assert_cc(sizeof(int64_t) == sizeof(long long int)); + return safe_atolli(s, (long long int*) ret_i); +} + +char *split(const char *c, size_t *l, const char *separator, char **state); +char *split_quoted(const char *c, size_t *l, char **state); + +#define FOREACH_WORD(word, length, s, state) \ + for ((state) = NULL, (word) = split((s), &(length), WHITESPACE, &(state)); (word); (word) = split((s), &(length), WHITESPACE, &(state))) + +#define FOREACH_WORD_SEPARATOR(word, length, s, separator, state) \ + for ((state) = NULL, (word) = split((s), &(length), (separator), &(state)); (word); (word) = split((s), &(length), (separator), &(state))) + +#define FOREACH_WORD_QUOTED(word, length, s, state) \ + for ((state) = NULL, (word) = split_quoted((s), &(length), &(state)); (word); (word) = split_quoted((s), &(length), &(state))) + +pid_t get_parent_of_pid(pid_t pid, pid_t *ppid); +int get_starttime_of_pid(pid_t pid, unsigned long long *st); + +int write_one_line_file(const char *fn, const char *line); +int write_one_line_file_atomic(const char *fn, const char *line); +int read_one_line_file(const char *fn, char **line); +int read_full_file(const char *fn, char **contents, size_t *size); + +int parse_env_file(const char *fname, const char *separator, ...) _sentinel_; +int load_env_file(const char *fname, char ***l); +int write_env_file(const char *fname, char **l); + +char *strappend(const char *s, const char *suffix); +char *strnappend(const char *s, const char *suffix, size_t length); + +char *replace_env(const char *format, char **env); +char **replace_env_argv(char **argv, char **env); + +int readlink_malloc(const char *p, char **r); +int readlink_and_make_absolute(const char *p, char **r); +int readlink_and_canonicalize(const char *p, char **r); + +int reset_all_signal_handlers(void); + +char *strstrip(char *s); +char *delete_chars(char *s, const char *bad); +char *truncate_nl(char *s); + +char *file_in_same_dir(const char *path, const char *filename); + +int rmdir_parents(const char *path, const char *stop); + +int get_process_comm(pid_t pid, char **name); +int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char **line); +int get_process_exe(pid_t pid, char **name); +int get_process_uid(pid_t pid, uid_t *uid); +int get_process_gid(pid_t pid, gid_t *gid); + +char hexchar(int x); +int unhexchar(char c); +char octchar(int x); +int unoctchar(char c); +char decchar(int x); +int undecchar(char c); + +char *cescape(const char *s); +char *cunescape(const char *s); +char *cunescape_length(const char *s, size_t length); +char *cunescape_length_with_prefix(const char *s, size_t length, const char *prefix); + +char *xescape(const char *s, const char *bad); + +char *bus_path_escape(const char *s); +char *bus_path_unescape(const char *s); + +char *ascii_strlower(char *path); + +bool dirent_is_file(const struct dirent *de); +bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix); + +bool ignore_file(const char *filename); + +bool chars_intersect(const char *a, const char *b); + +int make_stdio(int fd); +int make_null_stdio(void); +int make_console_stdio(void); + +unsigned long long random_ull(void); + +/* For basic lookup tables with strictly enumerated entries */ +#define __DEFINE_STRING_TABLE_LOOKUP(name,type,scope) \ + scope const char *name##_to_string(type i) { \ + if (i < 0 || i >= (type) ELEMENTSOF(name##_table)) \ + return NULL; \ + return name##_table[i]; \ + } \ + scope type name##_from_string(const char *s) { \ + type i; \ + assert(s); \ + for (i = 0; i < (type)ELEMENTSOF(name##_table); i++) \ + if (name##_table[i] && \ + streq(name##_table[i], s)) \ + return i; \ + return (type) -1; \ + } \ + struct __useless_struct_to_allow_trailing_semicolon__ + +#define DEFINE_STRING_TABLE_LOOKUP(name,type) __DEFINE_STRING_TABLE_LOOKUP(name,type,) +#define DEFINE_PRIVATE_STRING_TABLE_LOOKUP(name,type) __DEFINE_STRING_TABLE_LOOKUP(name,type,static) + +/* For string conversions where numbers are also acceptable */ +#define DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(name,type,max) \ + int name##_to_string_alloc(type i, char **str) { \ + char *s; \ + int r; \ + if (i < 0 || i > max) \ + return -ERANGE; \ + if (i < (type) ELEMENTSOF(name##_table)) { \ + s = strdup(name##_table[i]); \ + if (!s) \ + return log_oom(); \ + } else { \ + r = asprintf(&s, "%u", i); \ + if (r < 0) \ + return log_oom(); \ + } \ + *str = s; \ + return 0; \ + } \ + type name##_from_string(const char *s) { \ + type i; \ + unsigned u = 0; \ + assert(s); \ + for (i = 0; i < (type)ELEMENTSOF(name##_table); i++) \ + if (name##_table[i] && \ + streq(name##_table[i], s)) \ + return i; \ + if (safe_atou(s, &u) >= 0 && u <= max) \ + return (type) u; \ + return (type) -1; \ + } \ + struct __useless_struct_to_allow_trailing_semicolon__ + +int fd_nonblock(int fd, bool nonblock); +int fd_cloexec(int fd, bool cloexec); + +int close_all_fds(const int except[], unsigned n_except); + +bool fstype_is_network(const char *fstype); + +int chvt(int vt); + +int read_one_char(FILE *f, char *ret, usec_t timeout, bool *need_nl); +int ask(char *ret, const char *replies, const char *text, ...); + +int reset_terminal_fd(int fd, bool switch_to_text); +int reset_terminal(const char *name); + +int open_terminal(const char *name, int mode); +int acquire_terminal(const char *name, bool fail, bool force, bool ignore_tiocstty_eperm, usec_t timeout); +int release_terminal(void); + +int flush_fd(int fd); + +int ignore_signals(int sig, ...); +int default_signals(int sig, ...); +int sigaction_many(const struct sigaction *sa, ...); + +int close_pipe(int p[]); +int fopen_temporary(const char *path, FILE **_f, char **_temp_path); + +ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll); +ssize_t loop_write(int fd, const void *buf, size_t nbytes, bool do_poll); + +bool is_device_path(const char *path); + +int dir_is_empty(const char *path); + +void rename_process(const char name[8]); + +void sigset_add_many(sigset_t *ss, ...); + +bool hostname_is_set(void); + +char* gethostname_malloc(void); +char* getlogname_malloc(void); +char* getusername_malloc(void); + +int getttyname_malloc(int fd, char **r); +int getttyname_harder(int fd, char **r); + +int get_ctty_devnr(pid_t pid, dev_t *d); +int get_ctty(pid_t, dev_t *_devnr, char **r); + +int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid); +int fchmod_and_fchown(int fd, mode_t mode, uid_t uid, gid_t gid); + +int rm_rf_children(int fd, bool only_dirs, bool honour_sticky, struct stat *root_dev); +int rm_rf_children_dangerous(int fd, bool only_dirs, bool honour_sticky, struct stat *root_dev); +int rm_rf(const char *path, bool only_dirs, bool delete_root, bool honour_sticky); +int rm_rf_dangerous(const char *path, bool only_dirs, bool delete_root, bool honour_sticky); + +int pipe_eof(int fd); + +cpu_set_t* cpu_set_malloc(unsigned *ncpus); + +int status_vprintf(const char *status, bool ellipse, const char *format, va_list ap); +int status_printf(const char *status, bool ellipse, const char *format, ...); +int status_welcome(void); + +int fd_columns(int fd); +unsigned columns(void); +int fd_lines(int fd); +unsigned lines(void); +void columns_lines_cache_reset(int _unused_ signum); + +bool on_tty(void); + +int running_in_chroot(void); + +char *ellipsize(const char *s, size_t length, unsigned percent); +char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent); + +int touch(const char *path); + +char *unquote(const char *s, const char *quotes); +char *normalize_env_assignment(const char *s); + +int wait_for_terminate(pid_t pid, siginfo_t *status); +int wait_for_terminate_and_warn(const char *name, pid_t pid); + +_noreturn_ void freeze(void); + +bool null_or_empty(struct stat *st); +int null_or_empty_path(const char *fn); + +DIR *xopendirat(int dirfd, const char *name, int flags); + +char *fstab_node_to_udev_node(const char *p); + +bool tty_is_vc(const char *tty); +bool tty_is_vc_resolve(const char *tty); +bool tty_is_console(const char *tty); +int vtnr_from_tty(const char *tty); +const char *default_term_for_tty(const char *tty); + +void execute_directory(const char *directory, DIR *_d, char *argv[]); + +int kill_and_sigcont(pid_t pid, int sig); + +bool nulstr_contains(const char*nulstr, const char *needle); + +bool plymouth_running(void); + +bool hostname_is_valid(const char *s); +char* hostname_cleanup(char *s); + +char* strshorten(char *s, size_t l); + +int terminal_vhangup_fd(int fd); +int terminal_vhangup(const char *name); + +int vt_disallocate(const char *name); + +int copy_file(const char *from, const char *to); + +int symlink_atomic(const char *from, const char *to); + +int fchmod_umask(int fd, mode_t mode); + +bool display_is_local(const char *display); +int socket_from_display(const char *display, char **path); + +int get_user_creds(const char **username, uid_t *uid, gid_t *gid, const char **home, const char **shell); +int get_group_creds(const char **groupname, gid_t *gid); + +int in_group(const char *name); + +int glob_exists(const char *path); + +int dirent_ensure_type(DIR *d, struct dirent *de); + +int in_search_path(const char *path, char **search); +int get_files_in_directory(const char *path, char ***list); + +char *strjoin(const char *x, ...) _sentinel_; + +bool is_main_thread(void); + +bool in_charset(const char *s, const char* charset); + +int block_get_whole_disk(dev_t d, dev_t *ret); + +int file_is_priv_sticky(const char *p); + +int strdup_or_null(const char *a, char **b); + +#define NULSTR_FOREACH(i, l) \ + for ((i) = (l); (i) && *(i); (i) = strchr((i), 0)+1) + +#define NULSTR_FOREACH_PAIR(i, j, l) \ + for ((i) = (l), (j) = strchr((i), 0)+1; (i) && *(i); (i) = strchr((j), 0)+1, (j) = *(i) ? strchr((i), 0)+1 : (i)) + +int ioprio_class_to_string_alloc(int i, char **s); +int ioprio_class_from_string(const char *s); + +const char *sigchld_code_to_string(int i); +int sigchld_code_from_string(const char *s); + +int log_facility_unshifted_to_string_alloc(int i, char **s); +int log_facility_unshifted_from_string(const char *s); + +int log_level_to_string_alloc(int i, char **s); +int log_level_from_string(const char *s); + +int sched_policy_to_string_alloc(int i, char **s); +int sched_policy_from_string(const char *s); + +const char *rlimit_to_string(int i); +int rlimit_from_string(const char *s); + +int ip_tos_to_string_alloc(int i, char **s); +int ip_tos_from_string(const char *s); + +const char *signal_to_string(int i); +int signal_from_string(const char *s); + +int signal_from_string_try_harder(const char *s); + +extern int saved_argc; +extern char **saved_argv; + +bool kexec_loaded(void); + +int prot_from_flags(int flags); + +char *format_bytes(char *buf, size_t l, off_t t); + +int fd_wait_for_event(int fd, int event, usec_t timeout); + +void* memdup(const void *p, size_t l) _malloc_; + +int is_kernel_thread(pid_t pid); + +int fd_inc_sndbuf(int fd, size_t n); +int fd_inc_rcvbuf(int fd, size_t n); + +int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *path, ...); + +int setrlimit_closest(int resource, const struct rlimit *rlim); + +int getenv_for_pid(pid_t pid, const char *field, char **_value); + +int can_sleep(const char *type); +int can_sleep_disk(const char *type); + +bool is_valid_documentation_url(const char *url); + +bool in_initrd(void); + +void warn_melody(void); + +int get_shell(char **ret); +int get_home_dir(char **ret); + +void freep(void *p); +void fclosep(FILE **f); +void closep(int *fd); +void closedirp(DIR **d); +void umaskp(mode_t *u); + +_malloc_ static inline void *malloc_multiply(size_t a, size_t b) { + if (_unlikely_(b == 0 || a > ((size_t) -1) / b)) + return NULL; + + return malloc(a * b); +} + +_malloc_ static inline void *memdup_multiply(const void *p, size_t a, size_t b) { + if (_unlikely_(b == 0 || a > ((size_t) -1) / b)) + return NULL; + + return memdup(p, a * b); +} + +bool filename_is_safe(const char *p); +bool string_is_safe(const char *p); + +void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size, + int (*compar) (const void *, const void *, void *), + void *arg); + +bool is_locale_utf8(void); + +typedef enum DrawSpecialChar { + DRAW_TREE_VERT, + DRAW_TREE_BRANCH, + DRAW_TREE_RIGHT, + DRAW_TRIANGULAR_BULLET, + _DRAW_SPECIAL_CHAR_MAX +} DrawSpecialChar; +const char *draw_special_char(DrawSpecialChar ch); + +char *strreplace(const char *text, const char *old_string, const char *new_string); + +char *strip_tab_ansi(char **p, size_t *l); + +int on_ac_power(void); diff --git a/src/shared/utmp-wtmp.c b/src/shared/utmp-wtmp.c new file mode 100644 index 000000000..046fb584f --- /dev/null +++ b/src/shared/utmp-wtmp.c @@ -0,0 +1,431 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "macro.h" +#include "path-util.h" +#include "utmp-wtmp.h" + +int utmp_get_runlevel(int *runlevel, int *previous) { + struct utmpx lookup, *found; + int r; + const char *e; + + assert(runlevel); + + /* If these values are set in the environment this takes + * precedence. Presumably, sysvinit does this to work around a + * race condition that would otherwise exist where we'd always + * go to disk and hence might read runlevel data that might be + * very new and does not apply to the current script being + * executed. */ + + if ((e = getenv("RUNLEVEL")) && e[0] > 0) { + *runlevel = e[0]; + + if (previous) { + /* $PREVLEVEL seems to be an Upstart thing */ + + if ((e = getenv("PREVLEVEL")) && e[0] > 0) + *previous = e[0]; + else + *previous = 0; + } + + return 0; + } + + if (utmpxname(_PATH_UTMPX) < 0) + return -errno; + + setutxent(); + + zero(lookup); + lookup.ut_type = RUN_LVL; + + if (!(found = getutxid(&lookup))) + r = -errno; + else { + int a, b; + + a = found->ut_pid & 0xFF; + b = (found->ut_pid >> 8) & 0xFF; + + if (a < 0 || b < 0) + r = -EIO; + else { + *runlevel = a; + + if (previous) + *previous = b; + r = 0; + } + } + + endutxent(); + + return r; +} + +static void init_timestamp(struct utmpx *store, usec_t t) { + assert(store); + + zero(*store); + + if (t <= 0) + t = now(CLOCK_REALTIME); + + store->ut_tv.tv_sec = t / USEC_PER_SEC; + store->ut_tv.tv_usec = t % USEC_PER_SEC; +} + +static void init_entry(struct utmpx *store, usec_t t) { + struct utsname uts; + + assert(store); + + init_timestamp(store, t); + + zero(uts); + + if (uname(&uts) >= 0) + strncpy(store->ut_host, uts.release, sizeof(store->ut_host)); + + strncpy(store->ut_line, "~", sizeof(store->ut_line)); /* or ~~ ? */ + strncpy(store->ut_id, "~~", sizeof(store->ut_id)); +} + +static int write_entry_utmp(const struct utmpx *store) { + int r; + + assert(store); + + /* utmp is similar to wtmp, but there is only one entry for + * each entry type resp. user; i.e. basically a key/value + * table. */ + + if (utmpxname(_PATH_UTMPX) < 0) + return -errno; + + setutxent(); + + if (!pututxline(store)) + r = -errno; + else + r = 0; + + endutxent(); + + return r; +} + +static int write_entry_wtmp(const struct utmpx *store) { + assert(store); + + /* wtmp is a simple append-only file where each entry is + simply appended to * the end; i.e. basically a log. */ + + errno = 0; + updwtmpx(_PATH_WTMPX, store); + return -errno; +} + +static int write_utmp_wtmp(const struct utmpx *store_utmp, const struct utmpx *store_wtmp) { + int r, s; + + r = write_entry_utmp(store_utmp); + s = write_entry_wtmp(store_wtmp); + + if (r >= 0) + r = s; + + /* If utmp/wtmp have been disabled, that's a good thing, hence + * ignore the errors */ + if (r == -ENOENT) + r = 0; + + return r; +} + +static int write_entry_both(const struct utmpx *store) { + return write_utmp_wtmp(store, store); +} + +int utmp_put_shutdown(void) { + struct utmpx store; + + init_entry(&store, 0); + + store.ut_type = RUN_LVL; + strncpy(store.ut_user, "shutdown", sizeof(store.ut_user)); + + return write_entry_both(&store); +} + +int utmp_put_reboot(usec_t t) { + struct utmpx store; + + init_entry(&store, t); + + store.ut_type = BOOT_TIME; + strncpy(store.ut_user, "reboot", sizeof(store.ut_user)); + + return write_entry_both(&store); +} + +static const char *sanitize_id(const char *id) { + size_t l; + + assert(id); + l = strlen(id); + + if (l <= sizeof(((struct utmpx*) NULL)->ut_id)) + return id; + + return id + l - sizeof(((struct utmpx*) NULL)->ut_id); +} + +int utmp_put_init_process(const char *id, pid_t pid, pid_t sid, const char *line) { + struct utmpx store; + + assert(id); + + init_timestamp(&store, 0); + + store.ut_type = INIT_PROCESS; + store.ut_pid = pid; + store.ut_session = sid; + + strncpy(store.ut_id, sanitize_id(id), sizeof(store.ut_id)); + + if (line) + strncpy(store.ut_line, path_get_file_name(line), sizeof(store.ut_line)); + + return write_entry_both(&store); +} + +int utmp_put_dead_process(const char *id, pid_t pid, int code, int status) { + struct utmpx lookup, store, store_wtmp, *found; + + assert(id); + + setutxent(); + + zero(lookup); + lookup.ut_type = INIT_PROCESS; /* looks for DEAD_PROCESS, LOGIN_PROCESS, USER_PROCESS, too */ + strncpy(lookup.ut_id, sanitize_id(id), sizeof(lookup.ut_id)); + + if (!(found = getutxid(&lookup))) + return 0; + + if (found->ut_pid != pid) + return 0; + + memcpy(&store, found, sizeof(store)); + store.ut_type = DEAD_PROCESS; + store.ut_exit.e_termination = code; + store.ut_exit.e_exit = status; + + zero(store.ut_user); + zero(store.ut_host); + zero(store.ut_tv); + + memcpy(&store_wtmp, &store, sizeof(store_wtmp)); + /* wtmp wants the current time */ + init_timestamp(&store_wtmp, 0); + + return write_utmp_wtmp(&store, &store_wtmp); +} + + +int utmp_put_runlevel(int runlevel, int previous) { + struct utmpx store; + int r; + + assert(runlevel > 0); + + if (previous <= 0) { + /* Find the old runlevel automatically */ + + if ((r = utmp_get_runlevel(&previous, NULL)) < 0) { + if (r != -ESRCH) + return r; + + previous = 0; + } + } + + if (previous == runlevel) + return 0; + + init_entry(&store, 0); + + store.ut_type = RUN_LVL; + store.ut_pid = (runlevel & 0xFF) | ((previous & 0xFF) << 8); + strncpy(store.ut_user, "runlevel", sizeof(store.ut_user)); + + return write_entry_both(&store); +} + +#define TIMEOUT_MSEC 50 + +static int write_to_terminal(const char *tty, const char *message) { + int fd, r; + const char *p; + size_t left; + usec_t end; + + assert(tty); + assert(message); + + if ((fd = open(tty, O_WRONLY|O_NDELAY|O_NOCTTY|O_CLOEXEC)) < 0) + return -errno; + + if (!isatty(fd)) { + r = -errno; + goto finish; + } + + p = message; + left = strlen(message); + + end = now(CLOCK_MONOTONIC) + TIMEOUT_MSEC*USEC_PER_MSEC; + + while (left > 0) { + ssize_t n; + struct pollfd pollfd; + usec_t t; + int k; + + t = now(CLOCK_MONOTONIC); + + if (t >= end) { + r = -ETIME; + goto finish; + } + + zero(pollfd); + pollfd.fd = fd; + pollfd.events = POLLOUT; + + if ((k = poll(&pollfd, 1, (end - t) / USEC_PER_MSEC)) < 0) + return -errno; + + if (k <= 0) { + r = -ETIME; + goto finish; + } + + if ((n = write(fd, p, left)) < 0) { + + if (errno == EAGAIN) + continue; + + r = -errno; + goto finish; + } + + assert((size_t) n <= left); + + p += n; + left -= n; + } + + r = 0; + +finish: + close_nointr_nofail(fd); + + return r; +} + +int utmp_wall(const char *message, bool (*match_tty)(const char *tty)) { + struct utmpx *u; + char date[FORMAT_TIMESTAMP_MAX]; + char *text = NULL, *hn = NULL, *un = NULL, *tty = NULL; + int r; + + if (!(hn = gethostname_malloc()) || + !(un = getlogname_malloc())) { + r = -ENOMEM; + goto finish; + } + + getttyname_harder(STDIN_FILENO, &tty); + + if (asprintf(&text, + "\a\r\n" + "Broadcast message from %s@%s%s%s (%s):\r\n\r\n" + "%s\r\n\r\n", + un, hn, + tty ? " on " : "", strempty(tty), + format_timestamp(date, sizeof(date), now(CLOCK_REALTIME)), + message) < 0) { + r = -ENOMEM; + goto finish; + } + + setutxent(); + + r = 0; + + while ((u = getutxent())) { + int q; + const char *path; + char *buf = NULL; + + if (u->ut_type != USER_PROCESS || u->ut_user[0] == 0) + continue; + + if (path_startswith(u->ut_line, "/dev/")) + path = u->ut_line; + else { + if (asprintf(&buf, "/dev/%s", u->ut_line) < 0) { + r = -ENOMEM; + goto finish; + } + + path = buf; + } + + if (!match_tty || match_tty(path)) + if ((q = write_to_terminal(path, text)) < 0) + r = q; + + free(buf); + } + +finish: + free(hn); + free(un); + free(tty); + free(text); + + return r; +} diff --git a/src/shared/utmp-wtmp.h b/src/shared/utmp-wtmp.h new file mode 100644 index 000000000..592402320 --- /dev/null +++ b/src/shared/utmp-wtmp.h @@ -0,0 +1,35 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +#include "util.h" + +int utmp_get_runlevel(int *runlevel, int *previous); + +int utmp_put_shutdown(void); +int utmp_put_reboot(usec_t timestamp); +int utmp_put_runlevel(int runlevel, int previous); + +int utmp_put_dead_process(const char *id, pid_t pid, int code, int status); +int utmp_put_init_process(const char *id, pid_t pid, pid_t sid, const char *line); + +int utmp_wall(const char *message, bool (*match_tty)(const char *tty)); diff --git a/src/shared/virt.c b/src/shared/virt.c new file mode 100644 index 000000000..fc62c7232 --- /dev/null +++ b/src/shared/virt.c @@ -0,0 +1,259 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +#include +#include +#include + +#include "util.h" +#include "virt.h" + +/* Returns a short identifier for the various VM implementations */ +int detect_vm(const char **id) { + +#if defined(__i386__) || defined(__x86_64__) + + /* Both CPUID and DMI are x86 specific interfaces... */ + + static const char *const dmi_vendors[] = { + "/sys/class/dmi/id/sys_vendor", + "/sys/class/dmi/id/board_vendor", + "/sys/class/dmi/id/bios_vendor" + }; + + static const char dmi_vendor_table[] = + "QEMU\0" "qemu\0" + /* http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458 */ + "VMware\0" "vmware\0" + "VMW\0" "vmware\0" + "Microsoft Corporation\0" "microsoft\0" + "innotek GmbH\0" "oracle\0" + "Xen\0" "xen\0" + "Bochs\0" "bochs\0"; + + static const char cpuid_vendor_table[] = + "XenVMMXenVMM\0" "xen\0" + "KVMKVMKVM\0" "kvm\0" + /* http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458 */ + "VMwareVMware\0" "vmware\0" + /* http://msdn.microsoft.com/en-us/library/ff542428.aspx */ + "Microsoft Hv\0" "microsoft\0"; + + uint32_t eax, ecx; + union { + uint32_t sig32[3]; + char text[13]; + } sig; + unsigned i; + const char *j, *k; + bool hypervisor; + + /* http://lwn.net/Articles/301888/ */ + zero(sig); + +#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) + ); + + hypervisor = !!(ecx & 0x80000000U); + + if (hypervisor) { + + /* 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) + ); + + NULSTR_FOREACH_PAIR(j, k, cpuid_vendor_table) + if (streq(sig.text, j)) { + + if (id) + *id = k; + + return 1; + } + } + + for (i = 0; i < ELEMENTSOF(dmi_vendors); i++) { + char *s; + int r; + const char *found = NULL; + + if ((r = read_one_line_file(dmi_vendors[i], &s)) < 0) { + if (r != -ENOENT) + return r; + + continue; + } + + NULSTR_FOREACH_PAIR(j, k, dmi_vendor_table) + if (startswith(s, j)) + found = k; + free(s); + + if (found) { + if (id) + *id = found; + + return 1; + } + } + + if (hypervisor) { + if (id) + *id = "other"; + + return 1; + } + +#endif + return 0; +} + +int detect_container(const char **id) { + char *e = NULL; + int r; + + /* Unfortunately many of these operations require root access + * in one way or another */ + + r = running_in_chroot(); + if (r < 0) + return r; + if (r > 0) { + + if (id) + *id = "chroot"; + + return 1; + } + + /* /proc/vz exists in container and outside of the container, + * /proc/bc only outside of the container. */ + if (access("/proc/vz", F_OK) >= 0 && + access("/proc/bc", F_OK) < 0) { + + if (id) + *id = "openvz"; + + return 1; + } + + r = getenv_for_pid(1, "container", &e); + if (r <= 0) + return r; + + /* We only recognize a selected few here, since we want to + * enforce a redacted namespace */ + if (streq(e, "lxc")) { + if (id) + *id = "lxc"; + } else if (streq(e, "lxc-libvirt")) { + if (id) + *id = "lxc-libvirt"; + } else if (streq(e, "systemd-nspawn")) { + if (id) + *id = "systemd-nspawn"; + } else { + if (id) + *id = "other"; + } + + free(e); + + return r; +} + +/* Returns a short identifier for the various VM/container implementations */ +Virtualization detect_virtualization(const char **id) { + + static __thread Virtualization cached_virt = _VIRTUALIZATION_INVALID; + static __thread const char *cached_id = NULL; + + const char *_id; + int r; + Virtualization v; + + if (_likely_(cached_virt >= 0)) { + + if (id && cached_virt > 0) + *id = cached_id; + + return cached_virt; + } + + r = detect_container(&_id); + if (r < 0) { + v = r; + goto finish; + } else if (r > 0) { + v = VIRTUALIZATION_CONTAINER; + goto finish; + } + + r = detect_vm(&_id); + if (r < 0) { + v = r; + goto finish; + } else if (r > 0) { + v = VIRTUALIZATION_VM; + goto finish; + } + + v = VIRTUALIZATION_NONE; + +finish: + if (v > 0) { + cached_id = _id; + + if (id) + *id = _id; + } + + if (v >= 0) + cached_virt = v; + + return v; +} diff --git a/src/shared/virt.h b/src/shared/virt.h new file mode 100644 index 000000000..aa6ad35ba --- /dev/null +++ b/src/shared/virt.h @@ -0,0 +1,35 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +int detect_vm(const char **id); +int detect_container(const char **id); + +typedef enum Virtualization { + VIRTUALIZATION_NONE = 0, + VIRTUALIZATION_VM, + VIRTUALIZATION_CONTAINER, + _VIRTUALIZATION_MAX, + _VIRTUALIZATION_INVALID = -1 +} Virtualization; + +Virtualization detect_virtualization(const char **id); diff --git a/src/shared/watchdog.c b/src/shared/watchdog.c new file mode 100644 index 000000000..13265e769 --- /dev/null +++ b/src/shared/watchdog.c @@ -0,0 +1,169 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + +#include +#include +#include +#include +#include + +#include "watchdog.h" +#include "log.h" + +static int watchdog_fd = -1; +static usec_t watchdog_timeout = (usec_t) -1; + +static int update_timeout(void) { + int r; + + if (watchdog_fd < 0) + return 0; + + if (watchdog_timeout == (usec_t) -1) + return 0; + else if (watchdog_timeout == 0) { + int flags; + + flags = WDIOS_DISABLECARD; + r = ioctl(watchdog_fd, WDIOC_SETOPTIONS, &flags); + if (r < 0) { + log_warning("Failed to disable hardware watchdog: %m"); + return -errno; + } + } else { + int sec, flags; + char buf[FORMAT_TIMESPAN_MAX]; + + sec = (int) ((watchdog_timeout + USEC_PER_SEC - 1) / USEC_PER_SEC); + r = ioctl(watchdog_fd, WDIOC_SETTIMEOUT, &sec); + if (r < 0) { + log_warning("Failed to set timeout to %is: %m", sec); + return -errno; + } + + watchdog_timeout = (usec_t) sec * USEC_PER_SEC; + log_info("Set hardware watchdog to %s.", format_timespan(buf, sizeof(buf), watchdog_timeout)); + + flags = WDIOS_ENABLECARD; + r = ioctl(watchdog_fd, WDIOC_SETOPTIONS, &flags); + if (r < 0) { + log_warning("Failed to enable hardware watchdog: %m"); + return -errno; + } + + r = ioctl(watchdog_fd, WDIOC_KEEPALIVE, 0); + if (r < 0) { + log_warning("Failed to ping hardware watchdog: %m"); + return -errno; + } + } + + return 0; +} + +static int open_watchdog(void) { + struct watchdog_info ident; + + if (watchdog_fd >= 0) + return 0; + + watchdog_fd = open("/dev/watchdog", O_WRONLY|O_CLOEXEC); + if (watchdog_fd < 0) + return -errno; + + if (ioctl(watchdog_fd, WDIOC_GETSUPPORT, &ident) >= 0) + log_info("Hardware watchdog '%s', version %x", + ident.identity, + ident.firmware_version); + + return update_timeout(); +} + +int watchdog_set_timeout(usec_t *usec) { + int r; + + watchdog_timeout = *usec; + + /* If we didn't open the watchdog yet and didn't get any + * explicit timeout value set, don't do anything */ + if (watchdog_fd < 0 && watchdog_timeout == (usec_t) -1) + return 0; + + if (watchdog_fd < 0) + r = open_watchdog(); + else + r = update_timeout(); + + *usec = watchdog_timeout; + + return r; +} + +int watchdog_ping(void) { + int r; + + if (watchdog_fd < 0) { + r = open_watchdog(); + if (r < 0) + return r; + } + + r = ioctl(watchdog_fd, WDIOC_KEEPALIVE, 0); + if (r < 0) { + log_warning("Failed to ping hardware watchdog: %m"); + return -errno; + } + + return 0; +} + +void watchdog_close(bool disarm) { + int r; + + if (watchdog_fd < 0) + return; + + if (disarm) { + int flags; + + /* Explicitly disarm it */ + flags = WDIOS_DISABLECARD; + r = ioctl(watchdog_fd, WDIOC_SETOPTIONS, &flags); + if (r < 0) + log_warning("Failed to disable hardware watchdog: %m"); + + /* To be sure, use magic close logic, too */ + for (;;) { + static const char v = 'V'; + + if (write(watchdog_fd, &v, 1) > 0) + break; + + if (errno != EINTR) { + log_error("Failed to disarm watchdog timer: %m"); + break; + } + } + } + + close_nointr_nofail(watchdog_fd); + watchdog_fd = -1; +} diff --git a/src/shared/watchdog.h b/src/shared/watchdog.h new file mode 100644 index 000000000..b748b1585 --- /dev/null +++ b/src/shared/watchdog.h @@ -0,0 +1,28 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + +#include "util.h" + +int watchdog_set_timeout(usec_t *usec); +int watchdog_ping(void); +void watchdog_close(bool disarm); diff --git a/src/shutdownd/Makefile b/src/shutdownd/Makefile new file mode 120000 index 000000000..d0b0e8e00 --- /dev/null +++ b/src/shutdownd/Makefile @@ -0,0 +1 @@ +../Makefile \ No newline at end of file diff --git a/src/shutdownd/shutdownd.c b/src/shutdownd/shutdownd.c new file mode 100644 index 000000000..c0747415f --- /dev/null +++ b/src/shutdownd/shutdownd.c @@ -0,0 +1,478 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "log.h" +#include "macro.h" +#include "util.h" +#include "utmp-wtmp.h" +#include "mkdir.h" + +union shutdown_buffer { + struct sd_shutdown_command command; + char space[offsetof(struct sd_shutdown_command, wall_message) + LINE_MAX]; +}; + +static int read_packet(int fd, union shutdown_buffer *_b) { + struct msghdr msghdr; + struct iovec iovec; + struct ucred *ucred; + union { + struct cmsghdr cmsghdr; + uint8_t buf[CMSG_SPACE(sizeof(struct ucred))]; + } control; + ssize_t n; + union shutdown_buffer b; /* We maintain our own copy here, in order not to corrupt the last message */ + + assert(fd >= 0); + assert(_b); + + zero(iovec); + iovec.iov_base = &b; + iovec.iov_len = sizeof(b) - 1; + + zero(control); + zero(msghdr); + msghdr.msg_iov = &iovec; + msghdr.msg_iovlen = 1; + msghdr.msg_control = &control; + msghdr.msg_controllen = sizeof(control); + + n = recvmsg(fd, &msghdr, MSG_DONTWAIT); + if (n <= 0) { + if (n == 0) { + log_error("Short read"); + return -EIO; + } + + if (errno == EAGAIN || errno == EINTR) + return 0; + + log_error("recvmsg(): %m"); + return -errno; + } + + if (msghdr.msg_controllen < CMSG_LEN(sizeof(struct ucred)) || + control.cmsghdr.cmsg_level != SOL_SOCKET || + control.cmsghdr.cmsg_type != SCM_CREDENTIALS || + control.cmsghdr.cmsg_len != CMSG_LEN(sizeof(struct ucred))) { + log_warning("Received message without credentials. Ignoring."); + return 0; + } + + ucred = (struct ucred*) CMSG_DATA(&control.cmsghdr); + if (ucred->uid != 0) { + log_warning("Got request from unprivileged user. Ignoring."); + return 0; + } + + if ((size_t) n < offsetof(struct sd_shutdown_command, wall_message)) { + log_warning("Message has invalid size. Ignoring."); + return 0; + } + + if (b.command.mode != SD_SHUTDOWN_NONE && + b.command.mode != SD_SHUTDOWN_REBOOT && + b.command.mode != SD_SHUTDOWN_POWEROFF && + b.command.mode != SD_SHUTDOWN_HALT && + b.command.mode != SD_SHUTDOWN_KEXEC) { + log_warning("Message has invalid mode. Ignoring."); + return 0; + } + + b.space[n] = 0; + + *_b = b; + return 1; +} + +static void warn_wall(usec_t n, struct sd_shutdown_command *c) { + char date[FORMAT_TIMESTAMP_MAX]; + const char *prefix; + char *l = NULL; + + assert(c); + assert(c->warn_wall); + + if (n >= c->usec) + return; + + if (c->mode == SD_SHUTDOWN_HALT) + prefix = "The system is going down for system halt at "; + else if (c->mode == SD_SHUTDOWN_POWEROFF) + prefix = "The system is going down for power-off at "; + else if (c->mode == SD_SHUTDOWN_REBOOT) + prefix = "The system is going down for reboot at "; + else if (c->mode == SD_SHUTDOWN_KEXEC) + prefix = "The system is going down for kexec reboot at "; + else if (c->mode == SD_SHUTDOWN_NONE) + prefix = "The system shutdown has been cancelled at "; + else + assert_not_reached("Unknown mode!"); + + if (asprintf(&l, "%s%s%s%s!", c->wall_message, c->wall_message[0] ? "\n" : "", + prefix, format_timestamp(date, sizeof(date), c->usec)) < 0) + log_error("Failed to allocate wall message"); + else { + utmp_wall(l, NULL); + free(l); + } +} + +static usec_t when_wall(usec_t n, usec_t elapse) { + + static const struct { + usec_t delay; + usec_t interval; + } table[] = { + { 10 * USEC_PER_MINUTE, USEC_PER_MINUTE }, + { USEC_PER_HOUR, 15 * USEC_PER_MINUTE }, + { 3 * USEC_PER_HOUR, 30 * USEC_PER_MINUTE } + }; + + usec_t left, sub; + unsigned i; + + /* If the time is already passed, then don't announce */ + if (n >= elapse) + return 0; + + left = elapse - n; + for (i = 0; i < ELEMENTSOF(table); i++) + if (n + table[i].delay >= elapse) { + sub = ((left / table[i].interval) * table[i].interval); + break; + } + + if (i >= ELEMENTSOF(table)) + sub = ((left / USEC_PER_HOUR) * USEC_PER_HOUR); + + return elapse > sub ? elapse - sub : 1; +} + +static usec_t when_nologin(usec_t elapse) { + return elapse > 5*USEC_PER_MINUTE ? elapse - 5*USEC_PER_MINUTE : 1; +} + +static const char *mode_to_string(enum sd_shutdown_mode m) { + switch (m) { + case SD_SHUTDOWN_REBOOT: + return "reboot"; + case SD_SHUTDOWN_POWEROFF: + return "poweroff"; + case SD_SHUTDOWN_HALT: + return "halt"; + case SD_SHUTDOWN_KEXEC: + return "kexec"; + default: + return NULL; + } +} + +static int update_schedule_file(struct sd_shutdown_command *c) { + int r; + FILE *f; + char *temp_path, *t; + + assert(c); + + r = mkdir_safe_label("/run/systemd/shutdown", 0755, 0, 0); + if (r < 0) { + log_error("Failed to create shutdown subdirectory: %s", strerror(-r)); + return r; + } + + t = cescape(c->wall_message); + if (!t) + return log_oom(); + + r = fopen_temporary("/run/systemd/shutdown/scheduled", &f, &temp_path); + if (r < 0) { + log_error("Failed to save information about scheduled shutdowns: %s", strerror(-r)); + free(t); + return r; + } + + fchmod(fileno(f), 0644); + + fprintf(f, + "USEC=%llu\n" + "WARN_WALL=%i\n" + "MODE=%s\n", + (unsigned long long) c->usec, + c->warn_wall, + mode_to_string(c->mode)); + + if (c->dry_run) + fputs("DRY_RUN=1\n", f); + + if (!isempty(t)) + fprintf(f, "WALL_MESSAGE=%s\n", t); + + free(t); + + fflush(f); + + if (ferror(f) || rename(temp_path, "/run/systemd/shutdown/scheduled") < 0) { + log_error("Failed to write information about scheduled shutdowns: %m"); + r = -errno; + + unlink(temp_path); + unlink("/run/systemd/shutdown/scheduled"); + } + + fclose(f); + free(temp_path); + + return r; +} + +static bool scheduled(struct sd_shutdown_command *c) { + return c->usec > 0 && c->mode != SD_SHUTDOWN_NONE; +} + +int main(int argc, char *argv[]) { + enum { + FD_SOCKET, + FD_WALL_TIMER, + FD_NOLOGIN_TIMER, + FD_SHUTDOWN_TIMER, + _FD_MAX + }; + + int r = EXIT_FAILURE, n_fds; + union shutdown_buffer b; + struct pollfd pollfd[_FD_MAX]; + bool exec_shutdown = false, unlink_nologin = false; + unsigned i; + + if (getppid() != 1) { + log_error("This program should be invoked by init only."); + return EXIT_FAILURE; + } + + if (argc > 1) { + log_error("This program does not take arguments."); + return EXIT_FAILURE; + } + + log_set_target(LOG_TARGET_AUTO); + log_parse_environment(); + log_open(); + + umask(0022); + + n_fds = sd_listen_fds(true); + if (n_fds < 0) { + log_error("Failed to read listening file descriptors from environment: %s", strerror(-r)); + return EXIT_FAILURE; + } + + if (n_fds != 1) { + log_error("Need exactly one file descriptor."); + return EXIT_FAILURE; + } + + zero(b); + zero(pollfd); + + pollfd[FD_SOCKET].fd = SD_LISTEN_FDS_START; + pollfd[FD_SOCKET].events = POLLIN; + + for (i = FD_WALL_TIMER; i < _FD_MAX; i++) { + pollfd[i].events = POLLIN; + pollfd[i].fd = timerfd_create(CLOCK_REALTIME, TFD_NONBLOCK|TFD_CLOEXEC); + if (pollfd[i].fd < 0) { + log_error("timerfd_create(): %m"); + goto finish; + } + } + + log_debug("systemd-shutdownd running as pid %lu", (unsigned long) getpid()); + + sd_notify(false, + "READY=1\n" + "STATUS=Processing requests..."); + + for (;;) { + int k; + usec_t n; + + k = poll(pollfd, _FD_MAX, scheduled(&b.command) ? -1 : 0); + if (k < 0) { + + if (errno == EAGAIN || errno == EINTR) + continue; + + log_error("poll(): %m"); + goto finish; + } + + /* Exit on idle */ + if (k == 0) + break; + + n = now(CLOCK_REALTIME); + + if (pollfd[FD_SOCKET].revents) { + + k = read_packet(pollfd[FD_SOCKET].fd, &b); + if (k < 0) + goto finish; + else if (k > 0) { + struct itimerspec its; + char date[FORMAT_TIMESTAMP_MAX]; + + if (!scheduled(&b.command)) { + log_info("Shutdown canceled."); + if (b.command.warn_wall) + warn_wall(0, &b.command); + break; + } + + zero(its); + if (b.command.warn_wall) { + /* Send wall messages every so often */ + timespec_store(&its.it_value, when_wall(n, b.command.usec)); + + /* Warn immediately if less than 15 minutes are left */ + if (n < b.command.usec && + n + 15*USEC_PER_MINUTE >= b.command.usec) + warn_wall(n, &b.command); + } + if (timerfd_settime(pollfd[FD_WALL_TIMER].fd, TFD_TIMER_ABSTIME, &its, NULL) < 0) { + log_error("timerfd_settime(): %m"); + goto finish; + } + + /* Disallow logins 5 minutes prior to shutdown */ + zero(its); + timespec_store(&its.it_value, when_nologin(b.command.usec)); + if (timerfd_settime(pollfd[FD_NOLOGIN_TIMER].fd, TFD_TIMER_ABSTIME, &its, NULL) < 0) { + log_error("timerfd_settime(): %m"); + goto finish; + } + + /* Shutdown after the specified time is reached */ + zero(its); + timespec_store(&its.it_value, b.command.usec); + if (timerfd_settime(pollfd[FD_SHUTDOWN_TIMER].fd, TFD_TIMER_ABSTIME, &its, NULL) < 0) { + log_error("timerfd_settime(): %m"); + goto finish; + } + + update_schedule_file(&b.command); + + sd_notifyf(false, + "STATUS=Shutting down at %s (%s)...", + format_timestamp(date, sizeof(date), b.command.usec), + mode_to_string(b.command.mode)); + + log_info("Shutting down at %s (%s)...", date, mode_to_string(b.command.mode)); + } + } + + if (pollfd[FD_WALL_TIMER].revents) { + struct itimerspec its; + + warn_wall(n, &b.command); + flush_fd(pollfd[FD_WALL_TIMER].fd); + + /* Restart timer */ + zero(its); + timespec_store(&its.it_value, when_wall(n, b.command.usec)); + if (timerfd_settime(pollfd[FD_WALL_TIMER].fd, TFD_TIMER_ABSTIME, &its, NULL) < 0) { + log_error("timerfd_settime(): %m"); + goto finish; + } + } + + if (pollfd[FD_NOLOGIN_TIMER].revents) { + int e; + + log_info("Creating /run/nologin, blocking further logins..."); + + e = write_one_line_file_atomic("/run/nologin", "System is going down."); + if (e < 0) + log_error("Failed to create /run/nologin: %s", strerror(-e)); + else + unlink_nologin = true; + + flush_fd(pollfd[FD_NOLOGIN_TIMER].fd); + } + + if (pollfd[FD_SHUTDOWN_TIMER].revents) { + exec_shutdown = true; + goto finish; + } + } + + r = EXIT_SUCCESS; + + log_debug("systemd-shutdownd stopped as pid %lu", (unsigned long) getpid()); + +finish: + + for (i = 0; i < _FD_MAX; i++) + if (pollfd[i].fd >= 0) + close_nointr_nofail(pollfd[i].fd); + + if (unlink_nologin) + unlink("/run/nologin"); + + unlink("/run/systemd/shutdown/scheduled"); + + if (exec_shutdown && !b.command.dry_run) { + char sw[3]; + + sw[0] = '-'; + sw[1] = b.command.mode; + sw[2] = 0; + + execl(SYSTEMCTL_BINARY_PATH, + "shutdown", + sw, + "now", + (b.command.warn_wall && b.command.wall_message[0]) ? b.command.wall_message : + (b.command.warn_wall ? NULL : "--no-wall"), + NULL); + + log_error("Failed to execute /sbin/shutdown: %m"); + } + + sd_notify(false, + "STATUS=Exiting..."); + + return r; +} diff --git a/src/sleep/Makefile b/src/sleep/Makefile new file mode 120000 index 000000000..d0b0e8e00 --- /dev/null +++ b/src/sleep/Makefile @@ -0,0 +1 @@ +../Makefile \ No newline at end of file diff --git a/src/sleep/sleep.c b/src/sleep/sleep.c new file mode 100644 index 000000000..218de3a56 --- /dev/null +++ b/src/sleep/sleep.c @@ -0,0 +1,127 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + +#include +#include +#include + +#include "log.h" +#include "util.h" +#include "systemd/sd-id128.h" +#include "systemd/sd-messages.h" + +int main(int argc, char *argv[]) { + const char *verb; + char* arguments[4]; + int r; + FILE *f; + + log_set_target(LOG_TARGET_AUTO); + log_parse_environment(); + log_open(); + + if (argc != 2) { + log_error("Invalid number of arguments."); + r = -EINVAL; + goto finish; + } + + if (streq(argv[1], "suspend")) + verb = "mem"; + else if (streq(argv[1], "hibernate") || streq(argv[1], "hybrid-sleep")) + verb = "disk"; + else { + log_error("Unknown action '%s'.", argv[1]); + r = -EINVAL; + goto finish; + } + + /* Configure the hibernation mode */ + if (streq(argv[1], "hibernate")) { + if (write_one_line_file("/sys/power/disk", "platform") < 0) + write_one_line_file("/sys/power/disk", "shutdown"); + } else if (streq(argv[1], "hybrid-sleep")) { + if (write_one_line_file("/sys/power/disk", "suspend") < 0) + if (write_one_line_file("/sys/power/disk", "platform") < 0) + write_one_line_file("/sys/power/disk", "shutdown"); + } + + f = fopen("/sys/power/state", "we"); + if (!f) { + log_error("Failed to open /sys/power/state: %m"); + r = -errno; + goto finish; + } + + arguments[0] = NULL; + arguments[1] = (char*) "pre"; + arguments[2] = argv[1]; + arguments[3] = NULL; + execute_directory(SYSTEM_SLEEP_PATH, NULL, arguments); + + if (streq(argv[1], "suspend")) + log_struct(LOG_INFO, + MESSAGE_ID(SD_MESSAGE_SLEEP_START), + "MESSAGE=Suspending system...", + "SLEEP=suspend", + NULL); + else if (streq(argv[1], "hibernate")) + log_struct(LOG_INFO, + MESSAGE_ID(SD_MESSAGE_SLEEP_START), + "MESSAGE=Hibernating system...", + "SLEEP=hibernate", + NULL); + else + log_struct(LOG_INFO, + MESSAGE_ID(SD_MESSAGE_SLEEP_START), + "MESSAGE=Hibernating and suspending system...", + "SLEEP=hybrid-sleep", + NULL); + + fputs(verb, f); + fputc('\n', f); + fflush(f); + + r = ferror(f) ? -errno : 0; + + if (streq(argv[1], "suspend")) + log_struct(LOG_INFO, + MESSAGE_ID(SD_MESSAGE_SLEEP_STOP), + "MESSAGE=System resumed.", + "SLEEP=suspend", + NULL); + else + log_struct(LOG_INFO, + MESSAGE_ID(SD_MESSAGE_SLEEP_STOP), + "MESSAGE=System thawed.", + "SLEEP=hibernate", + NULL); + + arguments[1] = (char*) "post"; + execute_directory(SYSTEM_SLEEP_PATH, NULL, arguments); + + fclose(f); + +finish: + + return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; + +} diff --git a/src/stdio-bridge/Makefile b/src/stdio-bridge/Makefile new file mode 120000 index 000000000..d0b0e8e00 --- /dev/null +++ b/src/stdio-bridge/Makefile @@ -0,0 +1 @@ +../Makefile \ No newline at end of file diff --git a/src/stdio-bridge/stdio-bridge.c b/src/stdio-bridge/stdio-bridge.c new file mode 100644 index 000000000..f926fe553 --- /dev/null +++ b/src/stdio-bridge/stdio-bridge.c @@ -0,0 +1,367 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "log.h" +#include "util.h" +#include "socket-util.h" + +#define BUFFER_SIZE (64*1024) +#define EXTRA_SIZE 16 + +static bool initial_nul = false; +static bool auth_over = false; + +static void format_uid(char *buf, size_t l) { + char text[20 + 1]; /* enough space for a 64bit integer plus NUL */ + unsigned j; + + assert(l > 0); + + snprintf(text, sizeof(text)-1, "%llu", (unsigned long long) geteuid()); + text[sizeof(text)-1] = 0; + + memset(buf, 0, l); + + for (j = 0; text[j] && j*2+2 < l; j++) { + buf[j*2] = hexchar(text[j] >> 4); + buf[j*2+1] = hexchar(text[j] & 0xF); + } + + buf[j*2] = 0; +} + +static size_t patch_in_line(char *line, size_t l, size_t left) { + size_t r; + + if (line[0] == 0 && !initial_nul) { + initial_nul = true; + line += 1; + l -= 1; + r = 1; + } else + r = 0; + + if (l == 5 && strncmp(line, "BEGIN", 5) == 0) { + r += l; + auth_over = true; + + } else if (l == 17 && strncmp(line, "NEGOTIATE_UNIX_FD", 17) == 0) { + memmove(line + 13, line + 17, left); + memcpy(line, "NEGOTIATE_NOP", 13); + r += 13; + + } else if (l >= 14 && strncmp(line, "AUTH EXTERNAL ", 14) == 0) { + char uid[20*2 + 1]; + size_t len; + + format_uid(uid, sizeof(uid)); + len = strlen(uid); + assert(len <= EXTRA_SIZE); + + memmove(line + 14 + len, line + l, left); + memcpy(line + 14, uid, len); + + r += 14 + len; + } else + r += l; + + return r; +} + +static size_t patch_in_buffer(char* in_buffer, size_t *in_buffer_full) { + size_t i, good = 0; + + if (*in_buffer_full <= 0) + return *in_buffer_full; + + /* If authentication is done, we don't touch anything anymore */ + if (auth_over) + return *in_buffer_full; + + if (*in_buffer_full < 2) + return 0; + + for (i = 0; i <= *in_buffer_full - 2; i ++) { + + /* Fully lines can be send on */ + if (in_buffer[i] == '\r' && in_buffer[i+1] == '\n') { + if (i > good) { + size_t old_length, new_length; + + old_length = i - good; + new_length = patch_in_line(in_buffer+good, old_length, *in_buffer_full - i); + *in_buffer_full = *in_buffer_full + new_length - old_length; + + good += new_length + 2; + + } else + good = i+2; + } + + if (auth_over) + break; + } + + return good; +} + +int main(int argc, char *argv[]) { + int r = EXIT_FAILURE, fd = -1, ep = -1; + union sockaddr_union sa; + char in_buffer[BUFFER_SIZE+EXTRA_SIZE], out_buffer[BUFFER_SIZE+EXTRA_SIZE]; + size_t in_buffer_full = 0, out_buffer_full = 0; + struct epoll_event stdin_ev, stdout_ev, fd_ev; + bool stdin_readable = false, stdout_writable = false, fd_readable = false, fd_writable = false; + bool stdin_rhup = false, stdout_whup = false, fd_rhup = false, fd_whup = false; + + if (argc > 1) { + log_error("This program takes no argument."); + return EXIT_FAILURE; + } + + log_set_target(LOG_TARGET_JOURNAL_OR_KMSG); + log_parse_environment(); + log_open(); + + if ((fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0)) < 0) { + log_error("Failed to create socket: %s", strerror(errno)); + goto finish; + } + + zero(sa); + sa.un.sun_family = AF_UNIX; + strncpy(sa.un.sun_path, "/run/dbus/system_bus_socket", sizeof(sa.un.sun_path)); + + if (connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0) { + log_error("Failed to connect: %m"); + goto finish; + } + + fd_nonblock(STDIN_FILENO, 1); + fd_nonblock(STDOUT_FILENO, 1); + + if ((ep = epoll_create1(EPOLL_CLOEXEC)) < 0) { + log_error("Failed to create epoll: %m"); + goto finish; + } + + zero(stdin_ev); + stdin_ev.events = EPOLLIN|EPOLLET; + stdin_ev.data.fd = STDIN_FILENO; + + zero(stdout_ev); + stdout_ev.events = EPOLLOUT|EPOLLET; + stdout_ev.data.fd = STDOUT_FILENO; + + zero(fd_ev); + fd_ev.events = EPOLLIN|EPOLLOUT|EPOLLET; + fd_ev.data.fd = fd; + + if (epoll_ctl(ep, EPOLL_CTL_ADD, STDIN_FILENO, &stdin_ev) < 0 || + epoll_ctl(ep, EPOLL_CTL_ADD, STDOUT_FILENO, &stdout_ev) < 0 || + epoll_ctl(ep, EPOLL_CTL_ADD, fd, &fd_ev) < 0) { + log_error("Failed to regiser fds in epoll: %m"); + goto finish; + } + + do { + struct epoll_event ev[16]; + ssize_t k; + int i, nfds; + + if ((nfds = epoll_wait(ep, ev, ELEMENTSOF(ev), -1)) < 0) { + + if (errno == EINTR || errno == EAGAIN) + continue; + + log_error("epoll_wait(): %m"); + goto finish; + } + + assert(nfds >= 1); + + for (i = 0; i < nfds; i++) { + if (ev[i].data.fd == STDIN_FILENO) { + + if (!stdin_rhup && (ev[i].events & (EPOLLHUP|EPOLLIN))) + stdin_readable = true; + + } else if (ev[i].data.fd == STDOUT_FILENO) { + + if (ev[i].events & EPOLLHUP) { + stdout_writable = false; + stdout_whup = true; + } + + if (!stdout_whup && (ev[i].events & EPOLLOUT)) + stdout_writable = true; + + } else if (ev[i].data.fd == fd) { + + if (ev[i].events & EPOLLHUP) { + fd_writable = false; + fd_whup = true; + } + + if (!fd_rhup && (ev[i].events & (EPOLLHUP|EPOLLIN))) + fd_readable = true; + + if (!fd_whup && (ev[i].events & EPOLLOUT)) + fd_writable = true; + } + } + + while ((stdin_readable && in_buffer_full <= 0) || + (fd_writable && patch_in_buffer(in_buffer, &in_buffer_full) > 0) || + (fd_readable && out_buffer_full <= 0) || + (stdout_writable && out_buffer_full > 0)) { + + size_t in_buffer_good = 0; + + if (stdin_readable && in_buffer_full < BUFFER_SIZE) { + + if ((k = read(STDIN_FILENO, in_buffer + in_buffer_full, BUFFER_SIZE - in_buffer_full)) < 0) { + + if (errno == EAGAIN) + stdin_readable = false; + else if (errno == EPIPE || errno == ECONNRESET) + k = 0; + else { + log_error("read(): %m"); + goto finish; + } + } else + in_buffer_full += (size_t) k; + + if (k == 0) { + stdin_rhup = true; + stdin_readable = false; + shutdown(STDIN_FILENO, SHUT_RD); + close_nointr_nofail(STDIN_FILENO); + } + } + + in_buffer_good = patch_in_buffer(in_buffer, &in_buffer_full); + + if (fd_writable && in_buffer_good > 0) { + + if ((k = write(fd, in_buffer, in_buffer_good)) < 0) { + + if (errno == EAGAIN) + fd_writable = false; + else if (errno == EPIPE || errno == ECONNRESET) { + fd_whup = true; + fd_writable = false; + shutdown(fd, SHUT_WR); + } else { + log_error("write(): %m"); + goto finish; + } + + } else { + assert(in_buffer_full >= (size_t) k); + memmove(in_buffer, in_buffer + k, in_buffer_full - k); + in_buffer_full -= k; + } + } + + if (fd_readable && out_buffer_full < BUFFER_SIZE) { + + if ((k = read(fd, out_buffer + out_buffer_full, BUFFER_SIZE - out_buffer_full)) < 0) { + + if (errno == EAGAIN) + fd_readable = false; + else if (errno == EPIPE || errno == ECONNRESET) + k = 0; + else { + log_error("read(): %m"); + goto finish; + } + } else + out_buffer_full += (size_t) k; + + if (k == 0) { + fd_rhup = true; + fd_readable = false; + shutdown(fd, SHUT_RD); + } + } + + if (stdout_writable && out_buffer_full > 0) { + + if ((k = write(STDOUT_FILENO, out_buffer, out_buffer_full)) < 0) { + + if (errno == EAGAIN) + stdout_writable = false; + else if (errno == EPIPE || errno == ECONNRESET) { + stdout_whup = true; + stdout_writable = false; + shutdown(STDOUT_FILENO, SHUT_WR); + close_nointr(STDOUT_FILENO); + } else { + log_error("write(): %m"); + goto finish; + } + + } else { + assert(out_buffer_full >= (size_t) k); + memmove(out_buffer, out_buffer + k, out_buffer_full - k); + out_buffer_full -= k; + } + } + } + + if (stdin_rhup && in_buffer_full <= 0 && !fd_whup) { + fd_whup = true; + fd_writable = false; + shutdown(fd, SHUT_WR); + } + + if (fd_rhup && out_buffer_full <= 0 && !stdout_whup) { + stdout_whup = true; + stdout_writable = false; + shutdown(STDOUT_FILENO, SHUT_WR); + close_nointr(STDOUT_FILENO); + } + + } while (!stdout_whup || !fd_whup); + + r = EXIT_SUCCESS; + +finish: + if (fd >= 0) + close_nointr_nofail(fd); + + if (ep >= 0) + close_nointr_nofail(ep); + + return r; +} diff --git a/src/sysctl/Makefile b/src/sysctl/Makefile new file mode 120000 index 000000000..d0b0e8e00 --- /dev/null +++ b/src/sysctl/Makefile @@ -0,0 +1 @@ +../Makefile \ No newline at end of file diff --git a/src/sysctl/sysctl.c b/src/sysctl/sysctl.c new file mode 100644 index 000000000..035e0ec32 --- /dev/null +++ b/src/sysctl/sysctl.c @@ -0,0 +1,336 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include + +#include "log.h" +#include "strv.h" +#include "util.h" +#include "strv.h" +#include "hashmap.h" +#include "path-util.h" +#include "conf-files.h" + +#define PROC_SYS_PREFIX "/proc/sys/" + +static char **arg_prefixes; +static Hashmap *sysctl_options; + +static int apply_sysctl(const char *property, const char *value) { + char *p, *n; + int r = 0, k; + + log_debug("Setting '%s' to '%s'", property, value); + + p = new(char, sizeof(PROC_SYS_PREFIX) + strlen(property)); + if (!p) + return log_oom(); + + n = stpcpy(p, PROC_SYS_PREFIX); + strcpy(n, property); + + for (; *n; n++) + if (*n == '.') + *n = '/'; + + if (!strv_isempty(arg_prefixes)) { + char **i; + bool good = false; + + STRV_FOREACH(i, arg_prefixes) + if (path_startswith(p, *i)) { + good = true; + break; + } + + if (!good) { + log_debug("Skipping %s", p); + free(p); + return 0; + } + } + + k = write_one_line_file(p, value); + if (k < 0) { + + log_full(k == -ENOENT ? LOG_DEBUG : LOG_WARNING, + "Failed to write '%s' to '%s': %s", value, p, strerror(-k)); + + if (k != -ENOENT && r == 0) + r = k; + } + + free(p); + + return r; +} + +static int apply_all(void) { + int r = 0; + char *property, *value; + Iterator i; + + HASHMAP_FOREACH_KEY(value, property, sysctl_options, i) { + int k; + + k = apply_sysctl(property, value); + if (k < 0 && r == 0) + r = k; + } + return r; +} + +static int parse_file(const char *path, bool ignore_enoent) { + FILE *f; + int r = 0; + + assert(path); + + f = fopen(path, "re"); + if (!f) { + if (ignore_enoent && errno == ENOENT) + return 0; + + log_error("Failed to open file '%s', ignoring: %m", path); + return -errno; + } + + log_debug("parse: %s\n", path); + while (!feof(f)) { + char l[LINE_MAX], *p, *value, *new_value, *property; + + if (!fgets(l, sizeof(l), f)) { + if (feof(f)) + break; + + log_error("Failed to read file '%s', ignoring: %m", path); + r = -errno; + goto finish; + } + + p = strstrip(l); + + if (!*p) + continue; + + if (strchr(COMMENTS, *p)) + continue; + + value = strchr(p, '='); + if (!value) { + log_error("Line is not an assignment in file '%s': %s", path, value); + + if (r == 0) + r = -EINVAL; + continue; + } + + *value = 0; + value++; + + property = strdup(strstrip(p)); + if (!property) { + r = log_oom(); + goto finish; + } + + new_value = strdup(strstrip(value)); + if (!new_value) { + free(property); + r = log_oom(); + goto finish; + } + + r = hashmap_put(sysctl_options, property, new_value); + if (r < 0) { + if (r == -EEXIST) { + /* ignore this "error" to avoid returning it + * for the function when this is the last key + * in the file being parsed. */ + r = 0; + log_debug("Skipping previously assigned sysctl variable %s", property); + } else + log_error("Failed to add sysctl variable %s to hashmap: %s", property, strerror(-r)); + + free(property); + free(new_value); + if (r != 0) + goto finish; + } + } + +finish: + fclose(f); + + return r; +} + +static int help(void) { + + printf("%s [OPTIONS...] [CONFIGURATION FILE...]\n\n" + "Applies kernel sysctl settings.\n\n" + " -h --help Show this help\n" + " --prefix=PATH Only apply rules that apply to paths with the specified prefix\n", + program_invocation_short_name); + + return 0; +} + +static int parse_argv(int argc, char *argv[]) { + + enum { + ARG_PREFIX + }; + + static const struct option options[] = { + { "help", no_argument, NULL, 'h' }, + { "prefix", required_argument, NULL, ARG_PREFIX }, + { NULL, 0, NULL, 0 } + }; + + int c; + + assert(argc >= 0); + assert(argv); + + while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) { + + switch (c) { + + case 'h': + help(); + return 0; + + case ARG_PREFIX: { + char *p; + char **l; + + for (p = optarg; *p; p++) + if (*p == '.') + *p = '/'; + + l = strv_append(arg_prefixes, optarg); + if (!l) + return log_oom(); + + strv_free(arg_prefixes); + arg_prefixes = l; + + break; + } + + case '?': + return -EINVAL; + + default: + log_error("Unknown option code %c", c); + return -EINVAL; + } + } + + return 1; +} + +int main(int argc, char *argv[]) { + int r = 0, k; + char *property, *value; + Iterator it; + + r = parse_argv(argc, argv); + if (r <= 0) + return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; + + log_set_target(LOG_TARGET_AUTO); + log_parse_environment(); + log_open(); + + umask(0022); + + sysctl_options = hashmap_new(string_hash_func, string_compare_func); + if (!sysctl_options) { + r = log_oom(); + goto finish; + } + + r = 0; + + if (argc > optind) { + int i; + + for (i = optind; i < argc; i++) { + k = parse_file(argv[i], false); + if (k < 0) + r = k; + } + } else { + char **files, **f; + + r = conf_files_list(&files, ".conf", + "/etc/sysctl.d", + "/run/sysctl.d", + "/usr/local/lib/sysctl.d", + "/usr/lib/sysctl.d", +#ifdef HAVE_SPLIT_USR + "/lib/sysctl.d", +#endif + NULL); + if (r < 0) { + log_error("Failed to enumerate sysctl.d files: %s", strerror(-r)); + goto finish; + } + + /* We parse the files in decreasing order of precedence. + * parse_file() will skip keys that were already assigned. */ + + r = parse_file("/etc/sysctl.conf", true); + + f = files + strv_length(files) - 1; + STRV_FOREACH_BACKWARDS(f, files) { + k = parse_file(*f, true); + if (k < 0) + r = k; + } + + strv_free(files); + } + + k = apply_all(); + if (k < 0) + r = k; + +finish: + HASHMAP_FOREACH_KEY(value, property, sysctl_options, it) { + hashmap_remove(sysctl_options, property); + free(property); + free(value); + } + hashmap_free(sysctl_options); + + strv_free(arg_prefixes); + + return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/src/system-update-generator/Makefile b/src/system-update-generator/Makefile new file mode 120000 index 000000000..d0b0e8e00 --- /dev/null +++ b/src/system-update-generator/Makefile @@ -0,0 +1 @@ +../Makefile \ No newline at end of file diff --git a/src/system-update-generator/system-update-generator.c b/src/system-update-generator/system-update-generator.c new file mode 100644 index 000000000..6660192f5 --- /dev/null +++ b/src/system-update-generator/system-update-generator.c @@ -0,0 +1,84 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + +#include +#include + +#include "log.h" +#include "util.h" +#include "unit-name.h" +#include "path-util.h" + +/* + * Implements the logic described in + * http://freedesktop.org/wiki/Software/systemd/SystemUpdates + */ + +static const char *arg_dest = "/tmp"; + +static int generate_symlink(void) { + struct stat st; + char *p; + + if (lstat("/system-update", &st) < 0) { + if (errno == ENOENT) + return 0; + + log_error("Failed to check for system update: %m"); + return -EINVAL; + } + + p = strappend(arg_dest, "/default.target"); + if (!p) + return log_oom(); + + if (symlink(SYSTEM_DATA_UNIT_PATH "/system-update.target", p) < 0) { + free(p); + log_error("Failed to create symlink: %m"); + return -errno; + } + + free(p); + + return 0; +} + +int main(int argc, char *argv[]) { + int r; + + if (argc > 1 && argc != 4) { + log_error("This program takes three or no arguments."); + return EXIT_FAILURE; + } + + if (argc > 1) + arg_dest = argv[2]; + + log_set_target(LOG_TARGET_SAFE); + log_parse_environment(); + log_open(); + + umask(0022); + + r = generate_symlink(); + + return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/src/systemctl/Makefile b/src/systemctl/Makefile new file mode 120000 index 000000000..d0b0e8e00 --- /dev/null +++ b/src/systemctl/Makefile @@ -0,0 +1 @@ +../Makefile \ No newline at end of file diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c new file mode 100644 index 000000000..2ebfff8da --- /dev/null +++ b/src/systemctl/systemctl.c @@ -0,0 +1,5430 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "log.h" +#include "util.h" +#include "macro.h" +#include "set.h" +#include "utmp-wtmp.h" +#include "special.h" +#include "initreq.h" +#include "path-util.h" +#include "strv.h" +#include "dbus-common.h" +#include "cgroup-show.h" +#include "cgroup-util.h" +#include "list.h" +#include "path-lookup.h" +#include "conf-parser.h" +#include "exit-status.h" +#include "bus-errors.h" +#include "build.h" +#include "unit-name.h" +#include "pager.h" +#include "spawn-ask-password-agent.h" +#include "spawn-polkit-agent.h" +#include "install.h" +#include "logs-show.h" +#include "path-util.h" +#include "socket-util.h" + +static const char *arg_type = NULL; +static const char *arg_load_state = NULL; +static char **arg_property = NULL; +static bool arg_all = false; +static const char *arg_job_mode = "replace"; +static UnitFileScope arg_scope = UNIT_FILE_SYSTEM; +static bool arg_no_block = false; +static bool arg_no_legend = false; +static bool arg_no_pager = false; +static bool arg_no_wtmp = false; +static bool arg_no_wall = false; +static bool arg_no_reload = false; +static bool arg_dry = false; +static bool arg_quiet = false; +static bool arg_full = false; +static int arg_force = 0; +static bool arg_ask_password = true; +static bool arg_failed = false; +static bool arg_runtime = false; +static char **arg_wall = NULL; +static const char *arg_kill_who = NULL; +static int arg_signal = SIGTERM; +static const char *arg_root = NULL; +static usec_t arg_when = 0; +static enum action { + ACTION_INVALID, + ACTION_SYSTEMCTL, + ACTION_HALT, + ACTION_POWEROFF, + ACTION_REBOOT, + ACTION_KEXEC, + ACTION_EXIT, + ACTION_SUSPEND, + ACTION_HIBERNATE, + ACTION_HYBRID_SLEEP, + ACTION_RUNLEVEL2, + ACTION_RUNLEVEL3, + ACTION_RUNLEVEL4, + ACTION_RUNLEVEL5, + ACTION_RESCUE, + ACTION_EMERGENCY, + ACTION_DEFAULT, + ACTION_RELOAD, + ACTION_REEXEC, + ACTION_RUNLEVEL, + ACTION_CANCEL_SHUTDOWN, + _ACTION_MAX +} arg_action = ACTION_SYSTEMCTL; +static enum dot { + DOT_ALL, + DOT_ORDER, + DOT_REQUIRE +} arg_dot = DOT_ALL; +static enum transport { + TRANSPORT_NORMAL, + TRANSPORT_SSH, + TRANSPORT_POLKIT +} arg_transport = TRANSPORT_NORMAL; +static const char *arg_host = NULL; +static unsigned arg_lines = 10; +static OutputMode arg_output = OUTPUT_SHORT; + +static bool private_bus = false; + +static int daemon_reload(DBusConnection *bus, char **args); +static void halt_now(enum action a); + +static void pager_open_if_enabled(void) { + + if (arg_no_pager) + return; + + pager_open(); +} + +static void ask_password_agent_open_if_enabled(void) { + + /* Open the password agent as a child process if necessary */ + + if (!arg_ask_password) + return; + + if (arg_scope != UNIT_FILE_SYSTEM) + return; + + ask_password_agent_open(); +} + +#ifdef HAVE_LOGIND +static void polkit_agent_open_if_enabled(void) { + + /* Open the polkit agent as a child process if necessary */ + + if (!arg_ask_password) + return; + + if (arg_scope != UNIT_FILE_SYSTEM) + return; + + polkit_agent_open(); +} +#endif + +static const char *ansi_highlight(bool b) { + + if (!on_tty()) + return ""; + + return b ? ANSI_HIGHLIGHT_ON : ANSI_HIGHLIGHT_OFF; +} + +static const char *ansi_highlight_red(bool b) { + + if (!on_tty()) + return ""; + + return b ? ANSI_HIGHLIGHT_RED_ON : ANSI_HIGHLIGHT_OFF; +} + +static const char *ansi_highlight_green(bool b) { + + if (!on_tty()) + return ""; + + return b ? ANSI_HIGHLIGHT_GREEN_ON : ANSI_HIGHLIGHT_OFF; +} + +static int translate_bus_error_to_exit_status(int r, const DBusError *error) { + assert(error); + + if (!dbus_error_is_set(error)) + return r; + + if (dbus_error_has_name(error, DBUS_ERROR_ACCESS_DENIED) || + dbus_error_has_name(error, BUS_ERROR_ONLY_BY_DEPENDENCY) || + dbus_error_has_name(error, BUS_ERROR_NO_ISOLATION) || + dbus_error_has_name(error, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE)) + return EXIT_NOPERMISSION; + + if (dbus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT)) + return EXIT_NOTINSTALLED; + + if (dbus_error_has_name(error, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE) || + dbus_error_has_name(error, BUS_ERROR_NOT_SUPPORTED)) + return EXIT_NOTIMPLEMENTED; + + if (dbus_error_has_name(error, BUS_ERROR_LOAD_FAILED)) + return EXIT_NOTCONFIGURED; + + if (r != 0) + return r; + + return EXIT_FAILURE; +} + +static void warn_wall(enum action a) { + static const char *table[_ACTION_MAX] = { + [ACTION_HALT] = "The system is going down for system halt NOW!", + [ACTION_REBOOT] = "The system is going down for reboot NOW!", + [ACTION_POWEROFF] = "The system is going down for power-off NOW!", + [ACTION_KEXEC] = "The system is going down for kexec reboot NOW!", + [ACTION_RESCUE] = "The system is going down to rescue mode NOW!", + [ACTION_EMERGENCY] = "The system is going down to emergency mode NOW!", + [ACTION_CANCEL_SHUTDOWN] = "The system shutdown has been cancelled NOW!" + }; + + if (arg_no_wall) + return; + + if (arg_wall) { + char *p; + + p = strv_join(arg_wall, " "); + if (!p) { + log_error("Failed to join strings."); + return; + } + + if (*p) { + utmp_wall(p, NULL); + free(p); + return; + } + + free(p); + } + + if (!table[a]) + return; + + utmp_wall(table[a], NULL); +} + +static bool avoid_bus(void) { + + if (running_in_chroot() > 0) + return true; + + if (sd_booted() <= 0) + return true; + + if (!isempty(arg_root)) + return true; + + if (arg_scope == UNIT_FILE_GLOBAL) + return true; + + return false; +} + +struct unit_info { + const char *id; + const char *description; + const char *load_state; + const char *active_state; + const char *sub_state; + const char *following; + const char *unit_path; + uint32_t job_id; + const char *job_type; + const char *job_path; +}; + +static int compare_unit_info(const void *a, const void *b) { + const char *d1, *d2; + const struct unit_info *u = a, *v = b; + + d1 = strrchr(u->id, '.'); + d2 = strrchr(v->id, '.'); + + if (d1 && d2) { + int r; + + if ((r = strcasecmp(d1, d2)) != 0) + return r; + } + + return strcasecmp(u->id, v->id); +} + +static bool output_show_unit(const struct unit_info *u) { + const char *dot; + + if (arg_failed) + return streq(u->active_state, "failed"); + + return (!arg_type || ((dot = strrchr(u->id, '.')) && + streq(dot+1, arg_type))) && + (!arg_load_state || streq(u->load_state, arg_load_state)) && + (arg_all || !(streq(u->active_state, "inactive") + || u->following[0]) || u->job_id > 0); +} + +static void output_units_list(const struct unit_info *unit_infos, unsigned c) { + unsigned id_len, max_id_len, active_len, sub_len, job_len, desc_len, n_shown = 0; + const struct unit_info *u; + int job_count = 0; + + max_id_len = sizeof("UNIT")-1; + active_len = sizeof("ACTIVE")-1; + sub_len = sizeof("SUB")-1; + job_len = sizeof("JOB")-1; + desc_len = 0; + + for (u = unit_infos; u < unit_infos + c; u++) { + if (!output_show_unit(u)) + continue; + + max_id_len = MAX(max_id_len, strlen(u->id)); + active_len = MAX(active_len, strlen(u->active_state)); + sub_len = MAX(sub_len, strlen(u->sub_state)); + if (u->job_id != 0) { + job_len = MAX(job_len, strlen(u->job_type)); + job_count++; + } + } + + if (!arg_full) { + unsigned basic_len; + id_len = MIN(max_id_len, 25); + basic_len = 5 + id_len + 5 + active_len + sub_len; + if (job_count) + basic_len += job_len + 1; + if (basic_len < (unsigned) columns()) { + unsigned extra_len, incr; + extra_len = columns() - basic_len; + /* Either UNIT already got 25, or is fully satisfied. + * Grant up to 25 to DESC now. */ + incr = MIN(extra_len, 25); + desc_len += incr; + extra_len -= incr; + /* split the remaining space between UNIT and DESC, + * but do not give UNIT more than it needs. */ + if (extra_len > 0) { + incr = MIN(extra_len / 2, max_id_len - id_len); + id_len += incr; + desc_len += extra_len - incr; + } + } + } else + id_len = max_id_len; + + for (u = unit_infos; u < unit_infos + c; u++) { + char *e; + const char *on_loaded, *off_loaded; + const char *on_active, *off_active; + + if (!output_show_unit(u)) + continue; + + if (!n_shown && !arg_no_legend) { + printf("%-*s %-6s %-*s %-*s ", id_len, "UNIT", "LOAD", + active_len, "ACTIVE", sub_len, "SUB"); + if (job_count) + printf("%-*s ", job_len, "JOB"); + if (!arg_full && arg_no_pager) + printf("%.*s\n", desc_len, "DESCRIPTION"); + else + printf("%s\n", "DESCRIPTION"); + } + + n_shown++; + + if (streq(u->load_state, "error")) { + on_loaded = ansi_highlight_red(true); + off_loaded = ansi_highlight_red(false); + } else + on_loaded = off_loaded = ""; + + if (streq(u->active_state, "failed")) { + on_active = ansi_highlight_red(true); + off_active = ansi_highlight_red(false); + } else + on_active = off_active = ""; + + e = arg_full ? NULL : ellipsize(u->id, id_len, 33); + + printf("%-*s %s%-6s%s %s%-*s %-*s%s %-*s", + id_len, e ? e : u->id, + on_loaded, u->load_state, off_loaded, + on_active, active_len, u->active_state, + sub_len, u->sub_state, off_active, + job_count ? job_len + 1 : 0, u->job_id ? u->job_type : ""); + if (!arg_full && arg_no_pager) + printf("%.*s\n", desc_len, u->description); + else + printf("%s\n", u->description); + + free(e); + } + + if (!arg_no_legend) { + const char *on, *off; + + if (n_shown) { + printf("\nLOAD = Reflects whether the unit definition was properly loaded.\n" + "ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n" + "SUB = The low-level unit activation state, values depend on unit type.\n"); + if (job_count) + printf("JOB = Pending job for the unit.\n"); + puts(""); + on = ansi_highlight(true); + off = ansi_highlight(false); + } else { + on = ansi_highlight_red(true); + off = ansi_highlight_red(false); + } + + if (arg_all) + printf("%s%u loaded units listed.%s\n" + "To show all installed unit files use 'systemctl list-unit-files'.\n", + on, n_shown, off); + else + printf("%s%u loaded units listed.%s Pass --all to see loaded but inactive units, too.\n" + "To show all installed unit files use 'systemctl list-unit-files'.\n", + on, n_shown, off); + } +} + +static int list_units(DBusConnection *bus, char **args) { + DBusMessage *reply = NULL; + int r; + DBusMessageIter iter, sub, sub2; + unsigned c = 0, n_units = 0; + struct unit_info *unit_infos = NULL; + + pager_open_if_enabled(); + + r = bus_method_call_with_reply ( + bus, + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "ListUnits", + &reply, + NULL, + DBUS_TYPE_INVALID); + if (r) + goto finish; + + if (!dbus_message_iter_init(reply, &iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY || + dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_STRUCT) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_recurse(&iter, &sub); + + while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { + struct unit_info *u; + + if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRUCT) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + if (c >= n_units) { + struct unit_info *w; + + n_units = MAX(2*c, 16); + w = realloc(unit_infos, sizeof(struct unit_info) * n_units); + + if (!w) { + log_error("Failed to allocate unit array."); + r = -ENOMEM; + goto finish; + } + + unit_infos = w; + } + + u = unit_infos+c; + + dbus_message_iter_recurse(&sub, &sub2); + + if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &u->id, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &u->description, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &u->load_state, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &u->active_state, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &u->sub_state, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &u->following, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_OBJECT_PATH, &u->unit_path, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT32, &u->job_id, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &u->job_type, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_OBJECT_PATH, &u->job_path, false) < 0) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_next(&sub); + c++; + } + + if (c > 0) { + qsort(unit_infos, c, sizeof(struct unit_info), compare_unit_info); + output_units_list(unit_infos, c); + } + +finish: + if (reply) + dbus_message_unref(reply); + + free(unit_infos); + + return r; +} + +static int compare_unit_file_list(const void *a, const void *b) { + const char *d1, *d2; + const UnitFileList *u = a, *v = b; + + d1 = strrchr(u->path, '.'); + d2 = strrchr(v->path, '.'); + + if (d1 && d2) { + int r; + + r = strcasecmp(d1, d2); + if (r != 0) + return r; + } + + return strcasecmp(path_get_file_name(u->path), path_get_file_name(v->path)); +} + +static bool output_show_unit_file(const UnitFileList *u) { + const char *dot; + + return !arg_type || ((dot = strrchr(u->path, '.')) && streq(dot+1, arg_type)); +} + +static void output_unit_file_list(const UnitFileList *units, unsigned c) { + unsigned max_id_len, id_cols, state_cols, n_shown = 0; + const UnitFileList *u; + + max_id_len = sizeof("UNIT FILE")-1; + state_cols = sizeof("STATE")-1; + for (u = units; u < units + c; u++) { + if (!output_show_unit_file(u)) + continue; + + max_id_len = MAX(max_id_len, strlen(path_get_file_name(u->path))); + state_cols = MAX(state_cols, strlen(unit_file_state_to_string(u->state))); + } + + if (!arg_full) { + unsigned basic_cols; + id_cols = MIN(max_id_len, 25); + basic_cols = 1 + id_cols + state_cols; + if (basic_cols < (unsigned) columns()) + id_cols += MIN(columns() - basic_cols, max_id_len - id_cols); + } else + id_cols = max_id_len; + + if (!arg_no_legend) + printf("%-*s %-*s\n", id_cols, "UNIT FILE", state_cols, "STATE"); + + for (u = units; u < units + c; u++) { + char *e; + const char *on, *off; + const char *id; + + if (!output_show_unit_file(u)) + continue; + + n_shown++; + + if (u->state == UNIT_FILE_MASKED || + u->state == UNIT_FILE_MASKED_RUNTIME || + u->state == UNIT_FILE_DISABLED || + u->state == UNIT_FILE_INVALID) { + on = ansi_highlight_red(true); + off = ansi_highlight_red(false); + } else if (u->state == UNIT_FILE_ENABLED) { + on = ansi_highlight_green(true); + off = ansi_highlight_green(false); + } else + on = off = ""; + + id = path_get_file_name(u->path); + + e = arg_full ? NULL : ellipsize(id, id_cols, 33); + + printf("%-*s %s%-*s%s\n", + id_cols, e ? e : id, + on, state_cols, unit_file_state_to_string(u->state), off); + + free(e); + } + + if (!arg_no_legend) + printf("\n%u unit files listed.\n", n_shown); +} + +static int list_unit_files(DBusConnection *bus, char **args) { + DBusMessage *reply = NULL; + int r; + DBusMessageIter iter, sub, sub2; + unsigned c = 0, n_units = 0; + UnitFileList *units = NULL; + + pager_open_if_enabled(); + + if (avoid_bus()) { + Hashmap *h; + UnitFileList *u; + Iterator i; + + h = hashmap_new(string_hash_func, string_compare_func); + if (!h) + return log_oom(); + + r = unit_file_get_list(arg_scope, arg_root, h); + if (r < 0) { + unit_file_list_free(h); + log_error("Failed to get unit file list: %s", strerror(-r)); + return r; + } + + n_units = hashmap_size(h); + units = new(UnitFileList, n_units); + if (!units) { + unit_file_list_free(h); + return log_oom(); + } + + HASHMAP_FOREACH(u, h, i) { + memcpy(units + c++, u, sizeof(UnitFileList)); + free(u); + } + + hashmap_free(h); + } else { + r = bus_method_call_with_reply ( + bus, + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "ListUnitFiles", + &reply, + NULL, + DBUS_TYPE_INVALID); + if (r) + goto finish; + + if (!dbus_message_iter_init(reply, &iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY || + dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_STRUCT) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_recurse(&iter, &sub); + + while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { + UnitFileList *u; + const char *state; + + if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRUCT) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + if (c >= n_units) { + UnitFileList *w; + + n_units = MAX(2*c, 16); + w = realloc(units, sizeof(struct UnitFileList) * n_units); + + if (!w) { + log_error("Failed to allocate unit array."); + r = -ENOMEM; + goto finish; + } + + units = w; + } + + u = units+c; + + dbus_message_iter_recurse(&sub, &sub2); + + if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &u->path, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &state, false) < 0) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + u->state = unit_file_state_from_string(state); + + dbus_message_iter_next(&sub); + c++; + } + } + + if (c > 0) { + qsort(units, c, sizeof(UnitFileList), compare_unit_file_list); + output_unit_file_list(units, c); + } + + r = 0; + +finish: + if (reply) + dbus_message_unref(reply); + + free(units); + + return r; +} + +static int dot_one_property(const char *name, const char *prop, DBusMessageIter *iter) { + static const char * const colors[] = { + "Requires", "[color=\"black\"]", + "RequiresOverridable", "[color=\"black\"]", + "Requisite", "[color=\"darkblue\"]", + "RequisiteOverridable", "[color=\"darkblue\"]", + "Wants", "[color=\"grey66\"]", + "Conflicts", "[color=\"red\"]", + "ConflictedBy", "[color=\"red\"]", + "After", "[color=\"green\"]" + }; + + const char *c = NULL; + unsigned i; + + assert(name); + assert(prop); + assert(iter); + + for (i = 0; i < ELEMENTSOF(colors); i += 2) + if (streq(colors[i], prop)) { + c = colors[i+1]; + break; + } + + if (!c) + return 0; + + if (arg_dot != DOT_ALL) + if ((arg_dot == DOT_ORDER) != streq(prop, "After")) + return 0; + + switch (dbus_message_iter_get_arg_type(iter)) { + + case DBUS_TYPE_ARRAY: + + if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRING) { + DBusMessageIter sub; + + dbus_message_iter_recurse(iter, &sub); + + while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { + const char *s; + + assert(dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRING); + dbus_message_iter_get_basic(&sub, &s); + printf("\t\"%s\"->\"%s\" %s;\n", name, s, c); + + dbus_message_iter_next(&sub); + } + + return 0; + } + } + + return 0; +} + +static int dot_one(DBusConnection *bus, const char *name, const char *path) { + DBusMessage *reply = NULL; + const char *interface = "org.freedesktop.systemd1.Unit"; + int r; + DBusMessageIter iter, sub, sub2, sub3; + + assert(path); + + r = bus_method_call_with_reply ( + bus, + "org.freedesktop.systemd1", + path, + "org.freedesktop.DBus.Properties", + "GetAll", + &reply, + NULL, + DBUS_TYPE_STRING, &interface, + DBUS_TYPE_INVALID); + if (r) + goto finish; + + if (!dbus_message_iter_init(reply, &iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY || + dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_DICT_ENTRY) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_recurse(&iter, &sub); + + while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { + const char *prop; + + if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_DICT_ENTRY) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_recurse(&sub, &sub2); + + if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &prop, true) < 0) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + if (dbus_message_iter_get_arg_type(&sub2) != DBUS_TYPE_VARIANT) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_recurse(&sub2, &sub3); + + if (dot_one_property(name, prop, &sub3)) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_next(&sub); + } + +finish: + if (reply) + dbus_message_unref(reply); + + return r; +} + +static int dot(DBusConnection *bus, char **args) { + DBusMessage *reply = NULL; + int r; + DBusMessageIter iter, sub, sub2; + + r = bus_method_call_with_reply ( + bus, + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "ListUnits", + &reply, + NULL, + DBUS_TYPE_INVALID); + if (r) + goto finish; + + if (!dbus_message_iter_init(reply, &iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY || + dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_STRUCT) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + printf("digraph systemd {\n"); + + dbus_message_iter_recurse(&iter, &sub); + while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { + const char *id, *description, *load_state, *active_state, *sub_state, *following, *unit_path; + + if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRUCT) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_recurse(&sub, &sub2); + + if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &id, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &description, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &load_state, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &active_state, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &sub_state, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &following, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_OBJECT_PATH, &unit_path, true) < 0) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + if ((r = dot_one(bus, id, unit_path)) < 0) + goto finish; + + /* printf("\t\"%s\";\n", id); */ + dbus_message_iter_next(&sub); + } + + printf("}\n"); + + log_info(" Color legend: black = Requires\n" + " dark blue = Requisite\n" + " dark grey = Wants\n" + " red = Conflicts\n" + " green = After\n"); + + if (on_tty()) + log_notice("-- You probably want to process this output with graphviz' dot tool.\n" + "-- Try a shell pipeline like 'systemctl dot | dot -Tsvg > systemd.svg'!\n"); + + r = 0; + +finish: + if (reply) + dbus_message_unref(reply); + + return r; +} + +static int list_jobs(DBusConnection *bus, char **args) { + DBusMessage *reply = NULL; + int r; + DBusMessageIter iter, sub, sub2; + unsigned k = 0; + + pager_open_if_enabled(); + + r = bus_method_call_with_reply ( + bus, + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "ListJobs", + &reply, + NULL, + DBUS_TYPE_INVALID); + if (r) + goto finish; + + if (!dbus_message_iter_init(reply, &iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY || + dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_STRUCT) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_recurse(&iter, &sub); + + if (on_tty()) + printf("%4s %-25s %-15s %-7s\n", "JOB", "UNIT", "TYPE", "STATE"); + + while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { + const char *name, *type, *state, *job_path, *unit_path; + uint32_t id; + char *e; + + if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRUCT) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_recurse(&sub, &sub2); + + if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT32, &id, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &name, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &type, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &state, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_OBJECT_PATH, &job_path, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_OBJECT_PATH, &unit_path, false) < 0) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + e = arg_full ? NULL : ellipsize(name, 25, 33); + printf("%4u %-25s %-15s %-7s\n", id, e ? e : name, type, state); + free(e); + + k++; + + dbus_message_iter_next(&sub); + } + + if (on_tty()) + printf("\n%u jobs listed.\n", k); + + r = 0; + +finish: + if (reply) + dbus_message_unref(reply); + + return r; +} + +static int load_unit(DBusConnection *bus, char **args) { + int r = 0; + char **name, *n; + + assert(args); + + STRV_FOREACH(name, args+1) { + n = unit_name_mangle(*name); + r = bus_method_call_with_reply ( + bus, + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "LoadUnit", + NULL, + NULL, + DBUS_TYPE_STRING, n ? &n : name, + DBUS_TYPE_INVALID); + free(n); + if (r) + goto finish; + } + +finish: + return r; +} + +static int cancel_job(DBusConnection *bus, char **args) { + DBusMessage *reply = NULL; + int r = 0; + char **name; + + assert(args); + + if (strv_length(args) <= 1) + return daemon_reload(bus, args); + + STRV_FOREACH(name, args+1) { + unsigned id; + const char *path; + + r = safe_atou(*name, &id); + if (r < 0) { + log_error("Failed to parse job id: %s", strerror(-r)); + goto finish; + } + assert_cc(sizeof(uint32_t) == sizeof(id)); + + r = bus_method_call_with_reply ( + bus, + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "GetJob", + &reply, + NULL, + DBUS_TYPE_UINT32, &id, + DBUS_TYPE_INVALID); + if (r) + goto finish; + + if (!dbus_message_get_args(reply, NULL, + DBUS_TYPE_OBJECT_PATH, &path, + DBUS_TYPE_INVALID)) { + log_error("Failed to parse reply"); + dbus_message_unref(reply); + r = -EIO; + goto finish; + } + dbus_message_unref(reply); + + r = bus_method_call_with_reply ( + bus, + "org.freedesktop.systemd1", + path, + "org.freedesktop.systemd1.Job", + "Cancel", + NULL, + NULL, + DBUS_TYPE_INVALID); + if (r) + goto finish; + } + +finish: + return r; +} + +static bool need_daemon_reload(DBusConnection *bus, const char *unit) { + DBusMessage *reply = NULL; + dbus_bool_t b = FALSE; + DBusMessageIter iter, sub; + const char + *interface = "org.freedesktop.systemd1.Unit", + *property = "NeedDaemonReload", + *path; + char *n; + int r; + + /* We ignore all errors here, since this is used to show a warning only */ + + n = unit_name_mangle(unit); + r = bus_method_call_with_reply ( + bus, + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "GetUnit", + &reply, + NULL, + DBUS_TYPE_STRING, n ? (const char**) &n : &unit, + DBUS_TYPE_INVALID); + free(n); + if (r) + goto finish; + + if (!dbus_message_get_args(reply, NULL, + DBUS_TYPE_OBJECT_PATH, &path, + DBUS_TYPE_INVALID)) + goto finish; + + dbus_message_unref(reply); + r = bus_method_call_with_reply ( + bus, + "org.freedesktop.systemd1", + path, + "org.freedesktop.DBus.Properties", + "Get", + &reply, + NULL, + DBUS_TYPE_STRING, &interface, + DBUS_TYPE_STRING, &property, + DBUS_TYPE_INVALID); + if (r) + goto finish; + + if (!dbus_message_iter_init(reply, &iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT) + goto finish; + + dbus_message_iter_recurse(&iter, &sub); + + if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_BOOLEAN) + goto finish; + + dbus_message_iter_get_basic(&sub, &b); + +finish: + if (reply) + dbus_message_unref(reply); + + return b; +} + +typedef struct WaitData { + Set *set; + + char *name; + char *result; +} WaitData; + +static DBusHandlerResult wait_filter(DBusConnection *connection, DBusMessage *message, void *data) { + DBusError error; + WaitData *d = data; + + assert(connection); + assert(message); + assert(d); + + dbus_error_init(&error); + + log_debug("Got D-Bus request: %s.%s() on %s", + dbus_message_get_interface(message), + dbus_message_get_member(message), + dbus_message_get_path(message)); + + if (dbus_message_is_signal(message, DBUS_INTERFACE_LOCAL, "Disconnected")) { + log_error("Warning! D-Bus connection terminated."); + dbus_connection_close(connection); + + } else if (dbus_message_is_signal(message, "org.freedesktop.systemd1.Manager", "JobRemoved")) { + uint32_t id; + const char *path, *result, *unit; + dbus_bool_t success = true; + + if (dbus_message_get_args(message, &error, + DBUS_TYPE_UINT32, &id, + DBUS_TYPE_OBJECT_PATH, &path, + DBUS_TYPE_STRING, &unit, + DBUS_TYPE_STRING, &result, + DBUS_TYPE_INVALID)) { + char *p; + + p = set_remove(d->set, (char*) path); + free(p); + + if (!isempty(result)) + d->result = strdup(result); + + if (!isempty(unit)) + d->name = strdup(unit); + + goto finish; + } +#ifndef LEGACY + dbus_error_free(&error); + if (dbus_message_get_args(message, &error, + DBUS_TYPE_UINT32, &id, + DBUS_TYPE_OBJECT_PATH, &path, + DBUS_TYPE_STRING, &result, + DBUS_TYPE_INVALID)) { + char *p; + + /* Compatibility with older systemd versions < + * 183 during upgrades. This should be dropped + * one day. */ + p = set_remove(d->set, (char*) path); + free(p); + + if (*result) + d->result = strdup(result); + + goto finish; + } + + dbus_error_free(&error); + if (dbus_message_get_args(message, &error, + DBUS_TYPE_UINT32, &id, + DBUS_TYPE_OBJECT_PATH, &path, + DBUS_TYPE_BOOLEAN, &success, + DBUS_TYPE_INVALID)) { + char *p; + + /* Compatibility with older systemd versions < + * 19 during upgrades. This should be dropped + * one day */ + + p = set_remove(d->set, (char*) path); + free(p); + + if (!success) + d->result = strdup("failed"); + + goto finish; + } +#endif + + log_error("Failed to parse message: %s", bus_error_message(&error)); + } + +finish: + dbus_error_free(&error); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +static int enable_wait_for_jobs(DBusConnection *bus) { + DBusError error; + + assert(bus); + + if (private_bus) + return 0; + + dbus_error_init(&error); + dbus_bus_add_match(bus, + "type='signal'," + "sender='org.freedesktop.systemd1'," + "interface='org.freedesktop.systemd1.Manager'," + "member='JobRemoved'," + "path='/org/freedesktop/systemd1'", + &error); + + if (dbus_error_is_set(&error)) { + log_error("Failed to add match: %s", bus_error_message(&error)); + dbus_error_free(&error); + return -EIO; + } + + /* This is slightly dirty, since we don't undo the match registrations. */ + return 0; +} + +static int wait_for_jobs(DBusConnection *bus, Set *s) { + int r = 0; + WaitData d; + + assert(bus); + assert(s); + + zero(d); + d.set = s; + + if (!dbus_connection_add_filter(bus, wait_filter, &d, NULL)) + return log_oom(); + + while (!set_isempty(s)) { + + if (!dbus_connection_read_write_dispatch(bus, -1)) { + log_error("Disconnected from bus."); + return -ECONNREFUSED; + } + + if (!d.result) + goto free_name; + + if (!arg_quiet) { + if (streq(d.result, "timeout")) + log_error("Job for %s timed out.", strna(d.name)); + else if (streq(d.result, "canceled")) + log_error("Job for %s canceled.", strna(d.name)); + else if (streq(d.result, "dependency")) + log_error("A dependency job for %s failed. See 'journalctl -xn' for details.", strna(d.name)); + else if (!streq(d.result, "done") && !streq(d.result, "skipped")) + log_error("Job for %s failed. See 'systemctl status %s' and 'journalctl -xn' for details.", strna(d.name), strna(d.name)); + } + + if (streq_ptr(d.result, "timeout")) + r = -ETIME; + else if (streq_ptr(d.result, "canceled")) + r = -ECANCELED; + else if (!streq_ptr(d.result, "done") && !streq_ptr(d.result, "skipped")) + r = -EIO; + + free(d.result); + d.result = NULL; + + free_name: + free(d.name); + d.name = NULL; + } + + dbus_connection_remove_filter(bus, wait_filter, &d); + return r; +} + +static int check_one_unit(DBusConnection *bus, char *name, char **check_states, bool quiet) { + DBusMessage *reply = NULL; + DBusMessageIter iter, sub; + const char + *interface = "org.freedesktop.systemd1.Unit", + *property = "ActiveState"; + const char *path = NULL; + const char *state; + int r; + char *n; + + assert(name); + + n = unit_name_mangle(name); + r = bus_method_call_with_reply ( + bus, + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "GetUnit", + &reply, + NULL, + DBUS_TYPE_STRING, n ? &n : &name, + DBUS_TYPE_INVALID); + free(n); + if (r) { + if ((r != -ENOMEM) && (!quiet)) + puts("unknown"); + goto finish; + } + + if (!dbus_message_get_args(reply, NULL, + DBUS_TYPE_OBJECT_PATH, &path, + DBUS_TYPE_INVALID)) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_unref(reply); + r = bus_method_call_with_reply ( + bus, + "org.freedesktop.systemd1", + path, + "org.freedesktop.DBus.Properties", + "Get", + &reply, + NULL, + DBUS_TYPE_STRING, &interface, + DBUS_TYPE_STRING, &property, + DBUS_TYPE_INVALID); + if (r) + goto finish; + + if (!dbus_message_iter_init(reply, &iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_recurse(&iter, &sub); + + if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_get_basic(&sub, &state); + + if (!quiet) + puts(state); + + if (strv_find(check_states, state)) + r = 0; + else + r = 3; /* According to LSB: "program is not running" */ + +finish: + if (reply) + dbus_message_unref(reply); + + return r; +} + +static void check_triggering_units( + DBusConnection *bus, + const char *unit_name) { + + _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; + DBusMessageIter iter, sub; + char *service_trigger = NULL; + const char *interface = "org.freedesktop.systemd1.Unit", + *triggered_by_property = "TriggeredBy"; + + char _cleanup_free_ *unit_path = NULL, *n = NULL; + bool print_warning_label = true; + int r; + + n = unit_name_mangle(unit_name); + if (!n) { + log_oom(); + return; + } + + unit_path = unit_dbus_path_from_name(n); + if (!unit_path) { + log_oom(); + return; + } + + r = bus_method_call_with_reply ( + bus, + "org.freedesktop.systemd1", + unit_path, + "org.freedesktop.DBus.Properties", + "Get", + &reply, + NULL, + DBUS_TYPE_STRING, &interface, + DBUS_TYPE_STRING, &triggered_by_property, + DBUS_TYPE_INVALID); + if (r) + return; + + if (!dbus_message_iter_init(reply, &iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT) { + log_error("Failed to parse reply."); + return; + } + + dbus_message_iter_recurse(&iter, &sub); + dbus_message_iter_recurse(&sub, &iter); + sub = iter; + + while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { + char **check_states = NULL; + + if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING) { + log_error("Failed to parse reply."); + return; + } + + dbus_message_iter_get_basic(&sub, &service_trigger); + + check_states = strv_new("active", "reloading", NULL); + r = check_one_unit(bus, service_trigger, check_states, true); + strv_free(check_states); + if (r < 0) + return; + if (r == 0) { + if (print_warning_label) { + log_warning("Warning: Stopping %s, but it can still be activated by:", unit_name); + print_warning_label = false; + } + log_warning(" %s", service_trigger); + } + + dbus_message_iter_next(&sub); + } +} + +static int start_unit_one( + DBusConnection *bus, + const char *method, + const char *name, + const char *mode, + DBusError *error, + Set *s) { + + _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; + const char *path; + int r; + _cleanup_free_ char *n, *p = NULL; + + assert(method); + assert(name); + assert(mode); + assert(error); + + n = unit_name_mangle(name); + if (!n) + return log_oom(); + + r = bus_method_call_with_reply( + bus, + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + method, + &reply, + error, + DBUS_TYPE_STRING, &n, + DBUS_TYPE_STRING, &mode, + DBUS_TYPE_INVALID); + if (r) { + if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL) + /* There's always a fallback possible for + * legacy actions. */ + r = -EADDRNOTAVAIL; + else + log_error("Failed to issue method call: %s", bus_error_message(error)); + + return r; + } + + if (!dbus_message_get_args(reply, error, + DBUS_TYPE_OBJECT_PATH, &path, + DBUS_TYPE_INVALID)) { + log_error("Failed to parse reply: %s", bus_error_message(error)); + return -EIO; + } + + if (need_daemon_reload(bus, n)) + log_warning("Warning: Unit file of %s changed on disk, 'systemctl %s daemon-reload' recommended.", + n, arg_scope == UNIT_FILE_SYSTEM ? "--system" : "--user"); + + if (s) { + p = strdup(path); + if (!p) + return log_oom(); + + r = set_put(s, p); + if (r < 0) { + log_error("Failed to add path to set."); + return r; + } + + p = NULL; + } + + return 0; +} + +static enum action verb_to_action(const char *verb) { + if (streq(verb, "halt")) + return ACTION_HALT; + else if (streq(verb, "poweroff")) + return ACTION_POWEROFF; + else if (streq(verb, "reboot")) + return ACTION_REBOOT; + else if (streq(verb, "kexec")) + return ACTION_KEXEC; + else if (streq(verb, "rescue")) + return ACTION_RESCUE; + else if (streq(verb, "emergency")) + return ACTION_EMERGENCY; + else if (streq(verb, "default")) + return ACTION_DEFAULT; + else if (streq(verb, "exit")) + return ACTION_EXIT; + else if (streq(verb, "suspend")) + return ACTION_SUSPEND; + else if (streq(verb, "hibernate")) + return ACTION_HIBERNATE; + else if (streq(verb, "hybrid-sleep")) + return ACTION_HYBRID_SLEEP; + else + return ACTION_INVALID; +} + +static int start_unit(DBusConnection *bus, char **args) { + + static const char * const table[_ACTION_MAX] = { + [ACTION_HALT] = SPECIAL_HALT_TARGET, + [ACTION_POWEROFF] = SPECIAL_POWEROFF_TARGET, + [ACTION_REBOOT] = SPECIAL_REBOOT_TARGET, + [ACTION_KEXEC] = SPECIAL_KEXEC_TARGET, + [ACTION_RUNLEVEL2] = SPECIAL_RUNLEVEL2_TARGET, + [ACTION_RUNLEVEL3] = SPECIAL_RUNLEVEL3_TARGET, + [ACTION_RUNLEVEL4] = SPECIAL_RUNLEVEL4_TARGET, + [ACTION_RUNLEVEL5] = SPECIAL_RUNLEVEL5_TARGET, + [ACTION_RESCUE] = SPECIAL_RESCUE_TARGET, + [ACTION_EMERGENCY] = SPECIAL_EMERGENCY_TARGET, + [ACTION_DEFAULT] = SPECIAL_DEFAULT_TARGET, + [ACTION_EXIT] = SPECIAL_EXIT_TARGET, + [ACTION_SUSPEND] = SPECIAL_SUSPEND_TARGET, + [ACTION_HIBERNATE] = SPECIAL_HIBERNATE_TARGET, + [ACTION_HYBRID_SLEEP] = SPECIAL_HYBRID_SLEEP_TARGET + }; + + int r, ret = 0; + const char *method, *mode, *one_name; + Set *s = NULL; + DBusError error; + char **name; + + dbus_error_init(&error); + + assert(bus); + + ask_password_agent_open_if_enabled(); + + if (arg_action == ACTION_SYSTEMCTL) { + method = + streq(args[0], "stop") || + streq(args[0], "condstop") ? "StopUnit" : + streq(args[0], "reload") ? "ReloadUnit" : + streq(args[0], "restart") ? "RestartUnit" : + + streq(args[0], "try-restart") || + streq(args[0], "condrestart") ? "TryRestartUnit" : + + streq(args[0], "reload-or-restart") ? "ReloadOrRestartUnit" : + + streq(args[0], "reload-or-try-restart") || + streq(args[0], "condreload") || + + streq(args[0], "force-reload") ? "ReloadOrTryRestartUnit" : + "StartUnit"; + + mode = + (streq(args[0], "isolate") || + streq(args[0], "rescue") || + streq(args[0], "emergency")) ? "isolate" : arg_job_mode; + + one_name = table[verb_to_action(args[0])]; + + } else { + assert(arg_action < ELEMENTSOF(table)); + assert(table[arg_action]); + + method = "StartUnit"; + + mode = (arg_action == ACTION_EMERGENCY || + arg_action == ACTION_RESCUE || + arg_action == ACTION_RUNLEVEL2 || + arg_action == ACTION_RUNLEVEL3 || + arg_action == ACTION_RUNLEVEL4 || + arg_action == ACTION_RUNLEVEL5) ? "isolate" : "replace"; + + one_name = table[arg_action]; + } + + if (!arg_no_block) { + ret = enable_wait_for_jobs(bus); + if (ret < 0) { + log_error("Could not watch jobs: %s", strerror(-ret)); + goto finish; + } + + s = set_new(string_hash_func, string_compare_func); + if (!s) { + ret = log_oom(); + goto finish; + } + } + + if (one_name) { + ret = start_unit_one(bus, method, one_name, mode, &error, s); + if (ret < 0) + ret = translate_bus_error_to_exit_status(ret, &error); + } else { + STRV_FOREACH(name, args+1) { + r = start_unit_one(bus, method, *name, mode, &error, s); + if (r < 0) { + ret = translate_bus_error_to_exit_status(r, &error); + dbus_error_free(&error); + } + } + } + + if (!arg_no_block) { + r = wait_for_jobs(bus, s); + if (r < 0) { + ret = r; + goto finish; + } + + /* When stopping units, warn if they can still be triggered by + * another active unit (socket, path, timer) */ + if (!arg_quiet && streq(method, "StopUnit")) { + if (one_name) + check_triggering_units(bus, one_name); + else + STRV_FOREACH(name, args+1) + check_triggering_units(bus, *name); + } + } + +finish: + set_free_free(s); + dbus_error_free(&error); + + return ret; +} + +/* Ask systemd-logind, which might grant access to unprivileged users + * through PolicyKit */ +static int reboot_with_logind(DBusConnection *bus, enum action a) { +#ifdef HAVE_LOGIND + const char *method; + dbus_bool_t interactive = true; + + polkit_agent_open_if_enabled(); + + switch (a) { + + case ACTION_REBOOT: + method = "Reboot"; + break; + + case ACTION_POWEROFF: + method = "PowerOff"; + break; + + case ACTION_SUSPEND: + method = "Suspend"; + break; + + case ACTION_HIBERNATE: + method = "Hibernate"; + break; + + case ACTION_HYBRID_SLEEP: + method = "HybridSleep"; + break; + + default: + return -EINVAL; + } + + return bus_method_call_with_reply ( + bus, + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + method, + NULL, + NULL, + DBUS_TYPE_BOOLEAN, &interactive, + DBUS_TYPE_INVALID); +#else + return -ENOSYS; +#endif +} + +static int start_special(DBusConnection *bus, char **args) { + enum action a; + int r; + + assert(args); + + a = verb_to_action(args[0]); + + if (arg_force >= 2 && geteuid() != 0) { + log_error("Must be root."); + return -EPERM; + } + + if (arg_force >= 2 && + (a == ACTION_HALT || + a == ACTION_POWEROFF || + a == ACTION_REBOOT)) + halt_now(a); + + if (arg_force >= 1 && + (a == ACTION_HALT || + a == ACTION_POWEROFF || + a == ACTION_REBOOT || + a == ACTION_KEXEC || + a == ACTION_EXIT)) + return daemon_reload(bus, args); + + /* first try logind, to allow authentication with polkit */ + if (geteuid() != 0 && + (a == ACTION_POWEROFF || + a == ACTION_REBOOT || + a == ACTION_SUSPEND || + a == ACTION_HIBERNATE || + a == ACTION_HYBRID_SLEEP)) { + r = reboot_with_logind(bus, a); + if (r >= 0) + return r; + } + + r = start_unit(bus, args); + if (r >= 0) + warn_wall(a); + + return r; +} + +static int check_unit_active(DBusConnection *bus, char **args) { + char **name; + int r = 3; /* According to LSB: "program is not running" */ + + assert(bus); + assert(args); + + STRV_FOREACH(name, args+1) { + char **check_states = strv_new("active", "reloading", NULL); + int state = check_one_unit(bus, *name, check_states, arg_quiet); + strv_free(check_states); + if (state < 0) + return state; + if (state == 0) + r = 0; + } + + return r; +} + +static int check_unit_failed(DBusConnection *bus, char **args) { + char **name; + int r = 1; + + assert(bus); + assert(args); + + STRV_FOREACH(name, args+1) { + char **check_states = strv_new("failed", NULL); + int state = check_one_unit(bus, *name, check_states, arg_quiet); + strv_free(check_states); + if (state < 0) + return state; + if (state == 0) + r = 0; + } + + return r; +} + +static int kill_unit(DBusConnection *bus, char **args) { + int r = 0; + char **name, *n; + + assert(args); + + if (!arg_kill_who) + arg_kill_who = "all"; + + STRV_FOREACH(name, args+1) { + n = unit_name_mangle(*name); + r = bus_method_call_with_reply ( + bus, + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "KillUnit", + NULL, + NULL, + DBUS_TYPE_STRING, n ? &n : name, + DBUS_TYPE_STRING, &arg_kill_who, + DBUS_TYPE_INT32, &arg_signal, + DBUS_TYPE_INVALID); + free(n); + if (r) + return r; + } + return 0; +} + +typedef struct ExecStatusInfo { + char *name; + + char *path; + char **argv; + + bool ignore; + + usec_t start_timestamp; + usec_t exit_timestamp; + pid_t pid; + int code; + int status; + + LIST_FIELDS(struct ExecStatusInfo, exec); +} ExecStatusInfo; + +static void exec_status_info_free(ExecStatusInfo *i) { + assert(i); + + free(i->name); + free(i->path); + strv_free(i->argv); + free(i); +} + +static int exec_status_info_deserialize(DBusMessageIter *sub, ExecStatusInfo *i) { + uint64_t start_timestamp, exit_timestamp, start_timestamp_monotonic, exit_timestamp_monotonic; + DBusMessageIter sub2, sub3; + const char*path; + unsigned n; + uint32_t pid; + int32_t code, status; + dbus_bool_t ignore; + + assert(i); + assert(i); + + if (dbus_message_iter_get_arg_type(sub) != DBUS_TYPE_STRUCT) + return -EIO; + + dbus_message_iter_recurse(sub, &sub2); + + if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &path, true) < 0) + return -EIO; + + if (!(i->path = strdup(path))) + return -ENOMEM; + + if (dbus_message_iter_get_arg_type(&sub2) != DBUS_TYPE_ARRAY || + dbus_message_iter_get_element_type(&sub2) != DBUS_TYPE_STRING) + return -EIO; + + n = 0; + dbus_message_iter_recurse(&sub2, &sub3); + while (dbus_message_iter_get_arg_type(&sub3) != DBUS_TYPE_INVALID) { + assert(dbus_message_iter_get_arg_type(&sub3) == DBUS_TYPE_STRING); + dbus_message_iter_next(&sub3); + n++; + } + + + if (!(i->argv = new0(char*, n+1))) + return -ENOMEM; + + n = 0; + dbus_message_iter_recurse(&sub2, &sub3); + while (dbus_message_iter_get_arg_type(&sub3) != DBUS_TYPE_INVALID) { + const char *s; + + assert(dbus_message_iter_get_arg_type(&sub3) == DBUS_TYPE_STRING); + dbus_message_iter_get_basic(&sub3, &s); + dbus_message_iter_next(&sub3); + + if (!(i->argv[n++] = strdup(s))) + return -ENOMEM; + } + + if (!dbus_message_iter_next(&sub2) || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_BOOLEAN, &ignore, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT64, &start_timestamp, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT64, &start_timestamp_monotonic, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT64, &exit_timestamp, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT64, &exit_timestamp_monotonic, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT32, &pid, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_INT32, &code, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_INT32, &status, false) < 0) + return -EIO; + + i->ignore = ignore; + i->start_timestamp = (usec_t) start_timestamp; + i->exit_timestamp = (usec_t) exit_timestamp; + i->pid = (pid_t) pid; + i->code = code; + i->status = status; + + return 0; +} + +typedef struct UnitStatusInfo { + const char *id; + const char *load_state; + const char *active_state; + const char *sub_state; + const char *unit_file_state; + + const char *description; + const char *following; + + char **documentation; + + const char *fragment_path; + const char *source_path; + const char *default_control_group; + + const char *load_error; + const char *result; + + usec_t inactive_exit_timestamp; + usec_t inactive_exit_timestamp_monotonic; + usec_t active_enter_timestamp; + usec_t active_exit_timestamp; + usec_t inactive_enter_timestamp; + + bool need_daemon_reload; + + /* Service */ + pid_t main_pid; + pid_t control_pid; + const char *status_text; + bool running:1; + + usec_t start_timestamp; + usec_t exit_timestamp; + + int exit_code, exit_status; + + usec_t condition_timestamp; + bool condition_result; + + /* Socket */ + unsigned n_accepted; + unsigned n_connections; + bool accept; + + /* Device */ + const char *sysfs_path; + + /* Mount, Automount */ + const char *where; + + /* Swap */ + const char *what; + + LIST_HEAD(ExecStatusInfo, exec); +} UnitStatusInfo; + +static void print_status_info(UnitStatusInfo *i) { + ExecStatusInfo *p; + const char *on, *off, *ss; + usec_t timestamp; + char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1; + char since2[FORMAT_TIMESTAMP_MAX], *s2; + const char *path; + + assert(i); + + /* This shows pretty information about a unit. See + * print_property() for a low-level property printer */ + + printf("%s", strna(i->id)); + + if (i->description && !streq_ptr(i->id, i->description)) + printf(" - %s", i->description); + + printf("\n"); + + if (i->following) + printf("\t Follow: unit currently follows state of %s\n", i->following); + + if (streq_ptr(i->load_state, "error")) { + on = ansi_highlight_red(true); + off = ansi_highlight_red(false); + } else + on = off = ""; + + path = i->source_path ? i->source_path : i->fragment_path; + + if (i->load_error) + printf("\t Loaded: %s%s%s (Reason: %s)\n", on, strna(i->load_state), off, i->load_error); + else if (path && i->unit_file_state) + printf("\t Loaded: %s%s%s (%s; %s)\n", on, strna(i->load_state), off, path, i->unit_file_state); + else if (path) + printf("\t Loaded: %s%s%s (%s)\n", on, strna(i->load_state), off, path); + else + printf("\t Loaded: %s%s%s\n", on, strna(i->load_state), off); + + ss = streq_ptr(i->active_state, i->sub_state) ? NULL : i->sub_state; + + if (streq_ptr(i->active_state, "failed")) { + on = ansi_highlight_red(true); + off = ansi_highlight_red(false); + } else if (streq_ptr(i->active_state, "active") || streq_ptr(i->active_state, "reloading")) { + on = ansi_highlight_green(true); + off = ansi_highlight_green(false); + } else + on = off = ""; + + if (ss) + printf("\t Active: %s%s (%s)%s", + on, + strna(i->active_state), + ss, + off); + else + printf("\t Active: %s%s%s", + on, + strna(i->active_state), + off); + + if (!isempty(i->result) && !streq(i->result, "success")) + printf(" (Result: %s)", i->result); + + timestamp = (streq_ptr(i->active_state, "active") || + streq_ptr(i->active_state, "reloading")) ? i->active_enter_timestamp : + (streq_ptr(i->active_state, "inactive") || + streq_ptr(i->active_state, "failed")) ? i->inactive_enter_timestamp : + streq_ptr(i->active_state, "activating") ? i->inactive_exit_timestamp : + i->active_exit_timestamp; + + s1 = format_timestamp_relative(since1, sizeof(since1), timestamp); + s2 = format_timestamp(since2, sizeof(since2), timestamp); + + if (s1) + printf(" since %s; %s\n", s2, s1); + else if (s2) + printf(" since %s\n", s2); + else + printf("\n"); + + if (!i->condition_result && i->condition_timestamp > 0) { + s1 = format_timestamp_relative(since1, sizeof(since1), i->condition_timestamp); + s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp); + + if (s1) + printf("\t start condition failed at %s; %s\n", s2, s1); + else if (s2) + printf("\t start condition failed at %s\n", s2); + } + + if (i->sysfs_path) + printf("\t Device: %s\n", i->sysfs_path); + if (i->where) + printf("\t Where: %s\n", i->where); + if (i->what) + printf("\t What: %s\n", i->what); + + if (!strv_isempty(i->documentation)) { + char **t; + bool first = true; + + STRV_FOREACH(t, i->documentation) { + if (first) { + printf("\t Docs: %s\n", *t); + first = false; + } else + printf("\t %s\n", *t); + } + } + + if (i->accept) + printf("\tAccepted: %u; Connected: %u\n", i->n_accepted, i->n_connections); + + LIST_FOREACH(exec, p, i->exec) { + char *t; + bool good; + + /* Only show exited processes here */ + if (p->code == 0) + continue; + + t = strv_join(p->argv, " "); + printf("\t Process: %u %s=%s ", p->pid, p->name, strna(t)); + free(t); + + good = is_clean_exit_lsb(p->code, p->status, NULL); + if (!good) { + on = ansi_highlight_red(true); + off = ansi_highlight_red(false); + } else + on = off = ""; + + printf("%s(code=%s, ", on, sigchld_code_to_string(p->code)); + + if (p->code == CLD_EXITED) { + const char *c; + + printf("status=%i", p->status); + + c = exit_status_to_string(p->status, EXIT_STATUS_SYSTEMD); + if (c) + printf("/%s", c); + + } else + printf("signal=%s", signal_to_string(p->status)); + + printf(")%s\n", off); + + if (i->main_pid == p->pid && + i->start_timestamp == p->start_timestamp && + i->exit_timestamp == p->start_timestamp) + /* Let's not show this twice */ + i->main_pid = 0; + + if (p->pid == i->control_pid) + i->control_pid = 0; + } + + if (i->main_pid > 0 || i->control_pid > 0) { + printf("\t"); + + if (i->main_pid > 0) { + printf("Main PID: %u", (unsigned) i->main_pid); + + if (i->running) { + char *t = NULL; + get_process_comm(i->main_pid, &t); + if (t) { + printf(" (%s)", t); + free(t); + } + } else if (i->exit_code > 0) { + printf(" (code=%s, ", sigchld_code_to_string(i->exit_code)); + + if (i->exit_code == CLD_EXITED) { + const char *c; + + printf("status=%i", i->exit_status); + + c = exit_status_to_string(i->exit_status, EXIT_STATUS_SYSTEMD); + if (c) + printf("/%s", c); + + } else + printf("signal=%s", signal_to_string(i->exit_status)); + printf(")"); + } + } + + if (i->main_pid > 0 && i->control_pid > 0) + printf(";"); + + if (i->control_pid > 0) { + char *t = NULL; + + printf(" Control: %u", (unsigned) i->control_pid); + + get_process_comm(i->control_pid, &t); + if (t) { + printf(" (%s)", t); + free(t); + } + } + + printf("\n"); + } + + if (i->status_text) + printf("\t Status: \"%s\"\n", i->status_text); + + if (i->default_control_group && + (i->main_pid > 0 || i->control_pid > 0 || cg_is_empty_by_spec(i->default_control_group, false) == 0)) { + unsigned c; + + printf("\t CGroup: %s\n", i->default_control_group); + + if (arg_transport != TRANSPORT_SSH) { + unsigned k = 0; + pid_t extra[2]; + + c = columns(); + if (c > 18) + c -= 18; + else + c = 0; + + if (i->main_pid > 0) + extra[k++] = i->main_pid; + + if (i->control_pid > 0) + extra[k++] = i->control_pid; + + show_cgroup_and_extra_by_spec(i->default_control_group, "\t\t ", c, false, arg_all, extra, k); + } + } + + if (i->id && arg_transport != TRANSPORT_SSH) { + int flags = + arg_all * OUTPUT_SHOW_ALL | + (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH | + on_tty() * OUTPUT_COLOR | + !arg_quiet * OUTPUT_WARN_CUTOFF; + + printf("\n"); + show_journal_by_unit(stdout, + i->id, + arg_output, + 0, + i->inactive_exit_timestamp_monotonic, + arg_lines, + flags); + } + + if (i->need_daemon_reload) + printf("\n%sWarning:%s Unit file changed on disk, 'systemctl %s daemon-reload' recommended.\n", + ansi_highlight_red(true), + ansi_highlight_red(false), + arg_scope == UNIT_FILE_SYSTEM ? "--system" : "--user"); +} + +static void show_unit_help(UnitStatusInfo *i) { + char **p; + + assert(i); + + if (!i->documentation) { + log_info("Documentation for %s not known.", i->id); + return; + } + + STRV_FOREACH(p, i->documentation) { + + if (startswith(*p, "man:")) { + size_t k; + char *e = NULL; + char *page = NULL, *section = NULL; + const char *args[4] = { "man", NULL, NULL, NULL }; + pid_t pid; + + k = strlen(*p); + + if ((*p)[k-1] == ')') + e = strrchr(*p, '('); + + if (e) { + page = strndup((*p) + 4, e - *p - 4); + if (!page) { + log_oom(); + return; + } + + section = strndup(e + 1, *p + k - e - 2); + if (!section) { + free(page); + log_oom(); + return; + } + + args[1] = section; + args[2] = page; + } else + args[1] = *p + 4; + + pid = fork(); + if (pid < 0) { + log_error("Failed to fork: %m"); + free(page); + free(section); + continue; + } + + if (pid == 0) { + /* Child */ + execvp(args[0], (char**) args); + log_error("Failed to execute man: %m"); + _exit(EXIT_FAILURE); + } + + free(page); + free(section); + + wait_for_terminate(pid, NULL); + } else + log_info("Can't show: %s", *p); + } +} + +static int status_property(const char *name, DBusMessageIter *iter, UnitStatusInfo *i) { + + assert(name); + assert(iter); + assert(i); + + switch (dbus_message_iter_get_arg_type(iter)) { + + case DBUS_TYPE_STRING: { + const char *s; + + dbus_message_iter_get_basic(iter, &s); + + if (!isempty(s)) { + if (streq(name, "Id")) + i->id = s; + else if (streq(name, "LoadState")) + i->load_state = s; + else if (streq(name, "ActiveState")) + i->active_state = s; + else if (streq(name, "SubState")) + i->sub_state = s; + else if (streq(name, "Description")) + i->description = s; + else if (streq(name, "FragmentPath")) + i->fragment_path = s; + else if (streq(name, "SourcePath")) + i->source_path = s; + else if (streq(name, "DefaultControlGroup")) + i->default_control_group = s; + else if (streq(name, "StatusText")) + i->status_text = s; + else if (streq(name, "SysFSPath")) + i->sysfs_path = s; + else if (streq(name, "Where")) + i->where = s; + else if (streq(name, "What")) + i->what = s; + else if (streq(name, "Following")) + i->following = s; + else if (streq(name, "UnitFileState")) + i->unit_file_state = s; + else if (streq(name, "Result")) + i->result = s; + } + + break; + } + + case DBUS_TYPE_BOOLEAN: { + dbus_bool_t b; + + dbus_message_iter_get_basic(iter, &b); + + if (streq(name, "Accept")) + i->accept = b; + else if (streq(name, "NeedDaemonReload")) + i->need_daemon_reload = b; + else if (streq(name, "ConditionResult")) + i->condition_result = b; + + break; + } + + case DBUS_TYPE_UINT32: { + uint32_t u; + + dbus_message_iter_get_basic(iter, &u); + + if (streq(name, "MainPID")) { + if (u > 0) { + i->main_pid = (pid_t) u; + i->running = true; + } + } else if (streq(name, "ControlPID")) + i->control_pid = (pid_t) u; + else if (streq(name, "ExecMainPID")) { + if (u > 0) + i->main_pid = (pid_t) u; + } else if (streq(name, "NAccepted")) + i->n_accepted = u; + else if (streq(name, "NConnections")) + i->n_connections = u; + + break; + } + + case DBUS_TYPE_INT32: { + int32_t j; + + dbus_message_iter_get_basic(iter, &j); + + if (streq(name, "ExecMainCode")) + i->exit_code = (int) j; + else if (streq(name, "ExecMainStatus")) + i->exit_status = (int) j; + + break; + } + + case DBUS_TYPE_UINT64: { + uint64_t u; + + dbus_message_iter_get_basic(iter, &u); + + if (streq(name, "ExecMainStartTimestamp")) + i->start_timestamp = (usec_t) u; + else if (streq(name, "ExecMainExitTimestamp")) + i->exit_timestamp = (usec_t) u; + else if (streq(name, "ActiveEnterTimestamp")) + i->active_enter_timestamp = (usec_t) u; + else if (streq(name, "InactiveEnterTimestamp")) + i->inactive_enter_timestamp = (usec_t) u; + else if (streq(name, "InactiveExitTimestamp")) + i->inactive_exit_timestamp = (usec_t) u; + else if (streq(name, "InactiveExitTimestampMonotonic")) + i->inactive_exit_timestamp_monotonic = (usec_t) u; + else if (streq(name, "ActiveExitTimestamp")) + i->active_exit_timestamp = (usec_t) u; + else if (streq(name, "ConditionTimestamp")) + i->condition_timestamp = (usec_t) u; + + break; + } + + case DBUS_TYPE_ARRAY: { + + if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT && + startswith(name, "Exec")) { + DBusMessageIter sub; + + dbus_message_iter_recurse(iter, &sub); + while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRUCT) { + ExecStatusInfo *info; + int r; + + if (!(info = new0(ExecStatusInfo, 1))) + return -ENOMEM; + + if (!(info->name = strdup(name))) { + free(info); + return -ENOMEM; + } + + if ((r = exec_status_info_deserialize(&sub, info)) < 0) { + free(info); + return r; + } + + LIST_PREPEND(ExecStatusInfo, exec, i->exec, info); + + dbus_message_iter_next(&sub); + } + } else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRING && + streq(name, "Documentation")) { + + DBusMessageIter sub; + + dbus_message_iter_recurse(iter, &sub); + while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRING) { + const char *s; + char **l; + + dbus_message_iter_get_basic(&sub, &s); + + l = strv_append(i->documentation, s); + if (!l) + return -ENOMEM; + + strv_free(i->documentation); + i->documentation = l; + + dbus_message_iter_next(&sub); + } + } + + break; + } + + case DBUS_TYPE_STRUCT: { + + if (streq(name, "LoadError")) { + DBusMessageIter sub; + const char *n, *message; + int r; + + dbus_message_iter_recurse(iter, &sub); + + r = bus_iter_get_basic_and_next(&sub, DBUS_TYPE_STRING, &n, true); + if (r < 0) + return r; + + r = bus_iter_get_basic_and_next(&sub, DBUS_TYPE_STRING, &message, false); + if (r < 0) + return r; + + if (!isempty(message)) + i->load_error = message; + } + + break; + } + } + + return 0; +} + +static int print_property(const char *name, DBusMessageIter *iter) { + assert(name); + assert(iter); + + /* This is a low-level property printer, see + * print_status_info() for the nicer output */ + + if (arg_property && !strv_find(arg_property, name)) + return 0; + + switch (dbus_message_iter_get_arg_type(iter)) { + + case DBUS_TYPE_STRUCT: { + DBusMessageIter sub; + dbus_message_iter_recurse(iter, &sub); + + if (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_UINT32 && streq(name, "Job")) { + uint32_t u; + + dbus_message_iter_get_basic(&sub, &u); + + if (u) + printf("%s=%u\n", name, (unsigned) u); + else if (arg_all) + printf("%s=\n", name); + + return 0; + } else if (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRING && streq(name, "Unit")) { + const char *s; + + dbus_message_iter_get_basic(&sub, &s); + + if (arg_all || s[0]) + printf("%s=%s\n", name, s); + + return 0; + } else if (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRING && streq(name, "LoadError")) { + const char *a = NULL, *b = NULL; + + if (bus_iter_get_basic_and_next(&sub, DBUS_TYPE_STRING, &a, true) >= 0) + bus_iter_get_basic_and_next(&sub, DBUS_TYPE_STRING, &b, false); + + if (arg_all || !isempty(a) || !isempty(b)) + printf("%s=%s \"%s\"\n", name, strempty(a), strempty(b)); + + return 0; + } + + break; + } + + case DBUS_TYPE_ARRAY: + + if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT && streq(name, "EnvironmentFiles")) { + DBusMessageIter sub, sub2; + + dbus_message_iter_recurse(iter, &sub); + while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRUCT) { + const char *path; + dbus_bool_t ignore; + + dbus_message_iter_recurse(&sub, &sub2); + + if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &path, true) >= 0 && + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_BOOLEAN, &ignore, false) >= 0) + printf("EnvironmentFile=%s (ignore_errors=%s)\n", path, yes_no(ignore)); + + dbus_message_iter_next(&sub); + } + + return 0; + + } else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT && streq(name, "Paths")) { + DBusMessageIter sub, sub2; + + dbus_message_iter_recurse(iter, &sub); + while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRUCT) { + const char *type, *path; + + dbus_message_iter_recurse(&sub, &sub2); + + if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &type, true) >= 0 && + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &path, false) >= 0) + printf("%s=%s\n", type, path); + + dbus_message_iter_next(&sub); + } + + return 0; + + } else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT && streq(name, "Timers")) { + DBusMessageIter sub, sub2; + + dbus_message_iter_recurse(iter, &sub); + while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRUCT) { + const char *base; + uint64_t value, next_elapse; + + dbus_message_iter_recurse(&sub, &sub2); + + if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &base, true) >= 0 && + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT64, &value, true) >= 0 && + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT64, &next_elapse, false) >= 0) { + char timespan1[FORMAT_TIMESPAN_MAX], timespan2[FORMAT_TIMESPAN_MAX]; + + printf("%s={ value=%s ; next_elapse=%s }\n", + base, + format_timespan(timespan1, sizeof(timespan1), value), + format_timespan(timespan2, sizeof(timespan2), next_elapse)); + } + + dbus_message_iter_next(&sub); + } + + return 0; + + } else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT && streq(name, "ControlGroupAttributes")) { + DBusMessageIter sub, sub2; + + dbus_message_iter_recurse(iter, &sub); + while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRUCT) { + const char *controller, *attr, *value; + + dbus_message_iter_recurse(&sub, &sub2); + + if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &controller, true) >= 0 && + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &attr, true) >= 0 && + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &value, false) >= 0) { + + printf("ControlGroupAttribute={ controller=%s ; attribute=%s ; value=\"%s\" }\n", + controller, + attr, + value); + } + + dbus_message_iter_next(&sub); + } + + return 0; + + } else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT && startswith(name, "Exec")) { + DBusMessageIter sub; + + dbus_message_iter_recurse(iter, &sub); + while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRUCT) { + ExecStatusInfo info; + + zero(info); + if (exec_status_info_deserialize(&sub, &info) >= 0) { + char timestamp1[FORMAT_TIMESTAMP_MAX], timestamp2[FORMAT_TIMESTAMP_MAX]; + char *t; + + t = strv_join(info.argv, " "); + + printf("%s={ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid=%u ; code=%s ; status=%i%s%s }\n", + name, + strna(info.path), + strna(t), + yes_no(info.ignore), + strna(format_timestamp(timestamp1, sizeof(timestamp1), info.start_timestamp)), + strna(format_timestamp(timestamp2, sizeof(timestamp2), info.exit_timestamp)), + (unsigned) info. pid, + sigchld_code_to_string(info.code), + info.status, + info.code == CLD_EXITED ? "" : "/", + strempty(info.code == CLD_EXITED ? NULL : signal_to_string(info.status))); + + free(t); + } + + free(info.path); + strv_free(info.argv); + + dbus_message_iter_next(&sub); + } + + return 0; + } + + break; + } + + if (generic_print_property(name, iter, arg_all) > 0) + return 0; + + if (arg_all) + printf("%s=[unprintable]\n", name); + + return 0; +} + +static int show_one(const char *verb, DBusConnection *bus, const char *path, bool show_properties, bool *new_line) { + DBusMessage *reply = NULL; + const char *interface = ""; + int r; + DBusMessageIter iter, sub, sub2, sub3; + UnitStatusInfo info; + ExecStatusInfo *p; + + assert(path); + assert(new_line); + + zero(info); + + r = bus_method_call_with_reply ( + bus, + "org.freedesktop.systemd1", + path, + "org.freedesktop.DBus.Properties", + "GetAll", + &reply, + NULL, + DBUS_TYPE_STRING, &interface, + DBUS_TYPE_INVALID); + if (r) + goto finish; + + if (!dbus_message_iter_init(reply, &iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY || + dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_DICT_ENTRY) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_recurse(&iter, &sub); + + if (*new_line) + printf("\n"); + + *new_line = true; + + while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { + const char *name; + + if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_DICT_ENTRY) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_recurse(&sub, &sub2); + + if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &name, true) < 0) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + if (dbus_message_iter_get_arg_type(&sub2) != DBUS_TYPE_VARIANT) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_recurse(&sub2, &sub3); + + if (show_properties) + r = print_property(name, &sub3); + else + r = status_property(name, &sub3, &info); + + if (r < 0) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_next(&sub); + } + + r = 0; + + if (!show_properties) { + if (streq(verb, "help")) + show_unit_help(&info); + else + print_status_info(&info); + } + + strv_free(info.documentation); + + if (!streq_ptr(info.active_state, "active") && + !streq_ptr(info.active_state, "reloading") && + streq(verb, "status")) + /* According to LSB: "program not running" */ + r = 3; + + while ((p = info.exec)) { + LIST_REMOVE(ExecStatusInfo, exec, info.exec, p); + exec_status_info_free(p); + } + +finish: + if (reply) + dbus_message_unref(reply); + + return r; +} + +static int show_one_by_pid(const char *verb, DBusConnection *bus, uint32_t pid, bool *new_line) { + DBusMessage *reply = NULL; + const char *path = NULL; + DBusError error; + int r; + + dbus_error_init(&error); + + r = bus_method_call_with_reply ( + bus, + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "GetUnitByPID", + &reply, + NULL, + DBUS_TYPE_UINT32, &pid, + DBUS_TYPE_INVALID); + if (r) + goto finish; + + if (!dbus_message_get_args(reply, &error, + DBUS_TYPE_OBJECT_PATH, &path, + DBUS_TYPE_INVALID)) { + log_error("Failed to parse reply: %s", bus_error_message(&error)); + r = -EIO; + goto finish; + } + + r = show_one(verb, bus, path, false, new_line); + +finish: + if (reply) + dbus_message_unref(reply); + + dbus_error_free(&error); + + return r; +} + +static int show(DBusConnection *bus, char **args) { + int r, ret = 0; + bool show_properties, new_line = false; + char **name; + + assert(bus); + assert(args); + + show_properties = streq(args[0], "show"); + + if (show_properties) + pager_open_if_enabled(); + + if (show_properties && strv_length(args) <= 1) { + /* If not argument is specified inspect the manager + * itself */ + + return show_one(args[0], bus, "/org/freedesktop/systemd1", show_properties, &new_line); + } + + STRV_FOREACH(name, args+1) { + uint32_t id; + + if (safe_atou32(*name, &id) < 0) { + char *p, *n; + /* Interpret as unit name */ + + n = unit_name_mangle(*name); + p = unit_dbus_path_from_name(n ? n : *name); + free(n); + if (!p) + return log_oom(); + + r = show_one(args[0], bus, p, show_properties, &new_line); + free(p); + + if (r != 0) + ret = r; + + } else if (show_properties) { + + /* Interpret as job id */ + + char *p; + if (asprintf(&p, "/org/freedesktop/systemd1/job/%u", id) < 0) + return log_oom(); + + r = show_one(args[0], bus, p, show_properties, &new_line); + free(p); + + if (r != 0) + ret = r; + + } else { + + /* Interpret as PID */ + + r = show_one_by_pid(args[0], bus, id, &new_line); + if (r != 0) + ret = r; + } + } + + return ret; +} + +static int dump(DBusConnection *bus, char **args) { + DBusMessage *reply = NULL; + DBusError error; + int r; + const char *text; + + dbus_error_init(&error); + + pager_open_if_enabled(); + + r = bus_method_call_with_reply ( + bus, + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "Dump", + &reply, + NULL, + DBUS_TYPE_INVALID); + if (r) + goto finish; + + if (!dbus_message_get_args(reply, &error, + DBUS_TYPE_STRING, &text, + DBUS_TYPE_INVALID)) { + log_error("Failed to parse reply: %s", bus_error_message(&error)); + r = -EIO; + goto finish; + } + + fputs(text, stdout); + +finish: + if (reply) + dbus_message_unref(reply); + + dbus_error_free(&error); + + return r; +} + +static int snapshot(DBusConnection *bus, char **args) { + DBusMessage *reply = NULL; + DBusError error; + int r; + dbus_bool_t cleanup = FALSE; + DBusMessageIter iter, sub; + const char + *name = "", *path, *id, + *interface = "org.freedesktop.systemd1.Unit", + *property = "Id"; + char *n; + + dbus_error_init(&error); + + if (strv_length(args) > 1) + name = args[1]; + + n = unit_name_mangle(name); + r = bus_method_call_with_reply ( + bus, + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "CreateSnapshot", + &reply, + NULL, + DBUS_TYPE_STRING, n ? (const char**) &n : &name, + DBUS_TYPE_BOOLEAN, &cleanup, + DBUS_TYPE_INVALID); + free(n); + if (r) + goto finish; + + if (!dbus_message_get_args(reply, &error, + DBUS_TYPE_OBJECT_PATH, &path, + DBUS_TYPE_INVALID)) { + log_error("Failed to parse reply: %s", bus_error_message(&error)); + r = -EIO; + goto finish; + } + + dbus_message_unref(reply); + r = bus_method_call_with_reply ( + bus, + "org.freedesktop.systemd1", + path, + "org.freedesktop.DBus.Properties", + "Get", + &reply, + NULL, + DBUS_TYPE_STRING, &interface, + DBUS_TYPE_STRING, &property, + DBUS_TYPE_INVALID); + if (r) + goto finish; + + if (!dbus_message_iter_init(reply, &iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_recurse(&iter, &sub); + + if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_get_basic(&sub, &id); + + if (!arg_quiet) + puts(id); + +finish: + if (reply) + dbus_message_unref(reply); + + dbus_error_free(&error); + + return r; +} + +static int delete_snapshot(DBusConnection *bus, char **args) { + DBusMessage *reply = NULL; + int r = 0; + DBusError error; + char **name; + + assert(args); + + dbus_error_init(&error); + + STRV_FOREACH(name, args+1) { + const char *path = NULL; + char *n; + + n = unit_name_mangle(*name); + r = bus_method_call_with_reply ( + bus, + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "GetUnit", + &reply, + NULL, + DBUS_TYPE_STRING, n ? &n : name, + DBUS_TYPE_INVALID); + free(n); + if (r) + goto finish; + + if (!dbus_message_get_args(reply, &error, + DBUS_TYPE_OBJECT_PATH, &path, + DBUS_TYPE_INVALID)) { + log_error("Failed to parse reply: %s", bus_error_message(&error)); + r = -EIO; + dbus_message_unref(reply); + dbus_error_free(&error); + goto finish; + } + dbus_message_unref(reply); + + r = bus_method_call_with_reply ( + bus, + "org.freedesktop.systemd1", + path, + "org.freedesktop.systemd1.Snapshot", + "Remove", + NULL, + NULL, + DBUS_TYPE_INVALID); + if (r) + goto finish; + } + +finish: + return r; +} + +static int daemon_reload(DBusConnection *bus, char **args) { + int r; + const char *method; + DBusError error; + + if (arg_action == ACTION_RELOAD) + method = "Reload"; + else if (arg_action == ACTION_REEXEC) + method = "Reexecute"; + else { + assert(arg_action == ACTION_SYSTEMCTL); + + method = + streq(args[0], "clear-jobs") || + streq(args[0], "cancel") ? "ClearJobs" : + streq(args[0], "daemon-reexec") ? "Reexecute" : + streq(args[0], "reset-failed") ? "ResetFailed" : + streq(args[0], "halt") ? "Halt" : + streq(args[0], "poweroff") ? "PowerOff" : + streq(args[0], "reboot") ? "Reboot" : + streq(args[0], "kexec") ? "KExec" : + streq(args[0], "exit") ? "Exit" : + /* "daemon-reload" */ "Reload"; + } + + r = bus_method_call_with_reply ( + bus, + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + method, + NULL, + &error, + DBUS_TYPE_INVALID); + + if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL) + /* There's always a fallback possible for + * legacy actions. */ + r = -EADDRNOTAVAIL; + else if (r == -ETIMEDOUT && streq(method, "Reexecute")) + /* On reexecution, we expect a disconnect, not + * a reply */ + r = 0; + else if (r) + log_error("Failed to issue method call: %s", bus_error_message(&error)); + dbus_error_free(&error); + + return r; +} + +static int reset_failed(DBusConnection *bus, char **args) { + int r = 0; + char **name, *n; + + if (strv_length(args) <= 1) + return daemon_reload(bus, args); + + STRV_FOREACH(name, args+1) { + n = unit_name_mangle(*name); + r = bus_method_call_with_reply ( + bus, + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "ResetFailedUnit", + NULL, + NULL, + DBUS_TYPE_STRING, n ? &n : name, + DBUS_TYPE_INVALID); + free(n); + if (r) + goto finish; + } + +finish: + return r; +} + +static int show_enviroment(DBusConnection *bus, char **args) { + DBusMessage *reply = NULL; + DBusMessageIter iter, sub, sub2; + int r; + const char + *interface = "org.freedesktop.systemd1.Manager", + *property = "Environment"; + + pager_open_if_enabled(); + + r = bus_method_call_with_reply ( + bus, + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.DBus.Properties", + "Get", + &reply, + NULL, + DBUS_TYPE_STRING, &interface, + DBUS_TYPE_STRING, &property, + DBUS_TYPE_INVALID); + if (r) + goto finish; + + if (!dbus_message_iter_init(reply, &iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_recurse(&iter, &sub); + + if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_ARRAY || + dbus_message_iter_get_element_type(&sub) != DBUS_TYPE_STRING) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_recurse(&sub, &sub2); + + while (dbus_message_iter_get_arg_type(&sub2) != DBUS_TYPE_INVALID) { + const char *text; + + if (dbus_message_iter_get_arg_type(&sub2) != DBUS_TYPE_STRING) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_get_basic(&sub2, &text); + printf("%s\n", text); + + dbus_message_iter_next(&sub2); + } + + r = 0; + +finish: + if (reply) + dbus_message_unref(reply); + + return r; +} + +static int switch_root(DBusConnection *bus, char **args) { + unsigned l; + const char *root; + _cleanup_free_ char *init = NULL; + + l = strv_length(args); + if (l < 2 || l > 3) { + log_error("Wrong number of arguments."); + return -EINVAL; + } + + root = args[1]; + + if (l >= 3) + init = strdup(args[2]); + else { + parse_env_file("/proc/cmdline", WHITESPACE, + "init", &init, + NULL); + + if (!init) + init = strdup(""); + + if (!init) + return log_oom(); + + } + + log_debug("switching root - root: %s; init: %s", root, init); + + return bus_method_call_with_reply ( + bus, + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "SwitchRoot", + NULL, + NULL, + DBUS_TYPE_STRING, &root, + DBUS_TYPE_STRING, &init, + DBUS_TYPE_INVALID); +} + +static int set_environment(DBusConnection *bus, char **args) { + _cleanup_dbus_message_unref_ DBusMessage *m = NULL, *reply = NULL; + DBusError error; + const char *method; + DBusMessageIter iter; + int r; + + assert(bus); + + dbus_error_init(&error); + + method = streq(args[0], "set-environment") + ? "SetEnvironment" + : "UnsetEnvironment"; + + m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + method); + if (!m) + return log_oom(); + + dbus_message_iter_init_append(m, &iter); + + r = bus_append_strv_iter(&iter, args + 1); + if (r < 0) + return log_oom(); + + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error); + if (!reply) { + log_error("Failed to issue method call: %s", bus_error_message(&error)); + r = -EIO; + goto finish; + } + + r = 0; + +finish: + dbus_error_free(&error); + return r; +} + +static int enable_sysv_units(char **args) { + int r = 0; + +#if defined(HAVE_SYSV_COMPAT) && defined(HAVE_CHKCONFIG) + const char *verb = args[0]; + unsigned f = 1, t = 1; + LookupPaths paths; + + if (arg_scope != UNIT_FILE_SYSTEM) + return 0; + + if (!streq(verb, "enable") && + !streq(verb, "disable") && + !streq(verb, "is-enabled")) + return 0; + + /* Processes all SysV units, and reshuffles the array so that + * afterwards only the native units remain */ + + zero(paths); + r = lookup_paths_init(&paths, SYSTEMD_SYSTEM, false, NULL, NULL, NULL); + if (r < 0) + return r; + + r = 0; + for (f = 1; args[f]; f++) { + const char *name; + char *p; + bool found_native = false, found_sysv; + unsigned c = 1; + const char *argv[6] = { "/sbin/chkconfig", NULL, NULL, NULL, NULL }; + char **k, *l, *q = NULL; + int j; + pid_t pid; + siginfo_t status; + + name = args[f]; + + if (!endswith(name, ".service")) + continue; + + if (path_is_absolute(name)) + continue; + + STRV_FOREACH(k, paths.unit_path) { + p = NULL; + + if (!isempty(arg_root)) + asprintf(&p, "%s/%s/%s", arg_root, *k, name); + else + asprintf(&p, "%s/%s", *k, name); + + if (!p) { + r = log_oom(); + goto finish; + } + + found_native = access(p, F_OK) >= 0; + free(p); + + if (found_native) + break; + } + + if (found_native) + continue; + + p = NULL; + if (!isempty(arg_root)) + asprintf(&p, "%s/" SYSTEM_SYSVINIT_PATH "/%s", arg_root, name); + else + asprintf(&p, SYSTEM_SYSVINIT_PATH "/%s", name); + if (!p) { + r = log_oom(); + goto finish; + } + + p[strlen(p) - sizeof(".service") + 1] = 0; + found_sysv = access(p, F_OK) >= 0; + + if (!found_sysv) { + free(p); + continue; + } + + /* Mark this entry, so that we don't try enabling it as native unit */ + args[f] = (char*) ""; + + log_info("%s is not a native service, redirecting to /sbin/chkconfig.", name); + + if (!isempty(arg_root)) + argv[c++] = q = strappend("--root=", arg_root); + + argv[c++] = path_get_file_name(p); + argv[c++] = + streq(verb, "enable") ? "on" : + streq(verb, "disable") ? "off" : "--level=5"; + argv[c] = NULL; + + l = strv_join((char**)argv, " "); + if (!l) { + free(q); + free(p); + r = log_oom(); + goto finish; + } + + log_info("Executing %s", l); + free(l); + + pid = fork(); + if (pid < 0) { + log_error("Failed to fork: %m"); + free(p); + free(q); + r = -errno; + goto finish; + } else if (pid == 0) { + /* Child */ + + execv(argv[0], (char**) argv); + _exit(EXIT_FAILURE); + } + + free(p); + free(q); + + j = wait_for_terminate(pid, &status); + if (j < 0) { + log_error("Failed to wait for child: %s", strerror(-r)); + r = j; + goto finish; + } + + 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"); + } + + } else if (status.si_status != 0) { + r = -EINVAL; + goto finish; + } + } else { + r = -EPROTO; + goto finish; + } + } + +finish: + lookup_paths_free(&paths); + + /* Drop all SysV units */ + for (f = 1, t = 1; args[f]; f++) { + + if (isempty(args[f])) + continue; + + args[t++] = args[f]; + } + + args[t] = NULL; + +#endif + return r; +} + +static int mangle_names(char **original_names, char ***mangled_names) { + char **i, **l, **name; + + l = new(char*, strv_length(original_names) + 1); + if (!l) + return log_oom(); + + i = l; + STRV_FOREACH(name, original_names) { + + /* When enabling units qualified path names are OK, + * too, hence allow them explicitly. */ + + if (is_path(*name)) + *i = strdup(*name); + else + *i = unit_name_mangle(*name); + + if (!*i) { + strv_free(l); + return log_oom(); + } + + i++; + } + + *i = NULL; + *mangled_names = l; + + return 0; +} + +static int enable_unit(DBusConnection *bus, char **args) { + const char *verb = args[0]; + UnitFileChange *changes = NULL; + unsigned n_changes = 0, i; + int carries_install_info = -1; + DBusMessage *m = NULL, *reply = NULL; + int r; + DBusError error; + char **mangled_names = NULL; + + r = enable_sysv_units(args); + if (r < 0) + return r; + + if (!args[1]) + return 0; + + dbus_error_init(&error); + + if (!bus || avoid_bus()) { + if (streq(verb, "enable")) { + r = unit_file_enable(arg_scope, arg_runtime, arg_root, args+1, arg_force, &changes, &n_changes); + carries_install_info = r; + } else if (streq(verb, "disable")) + r = unit_file_disable(arg_scope, arg_runtime, arg_root, args+1, &changes, &n_changes); + else if (streq(verb, "reenable")) { + r = unit_file_reenable(arg_scope, arg_runtime, arg_root, args+1, arg_force, &changes, &n_changes); + carries_install_info = r; + } else if (streq(verb, "link")) + r = unit_file_link(arg_scope, arg_runtime, arg_root, args+1, arg_force, &changes, &n_changes); + else if (streq(verb, "preset")) { + r = unit_file_preset(arg_scope, arg_runtime, arg_root, args+1, arg_force, &changes, &n_changes); + carries_install_info = r; + } else if (streq(verb, "mask")) + r = unit_file_mask(arg_scope, arg_runtime, arg_root, args+1, arg_force, &changes, &n_changes); + else if (streq(verb, "unmask")) + r = unit_file_unmask(arg_scope, arg_runtime, arg_root, args+1, &changes, &n_changes); + else + assert_not_reached("Unknown verb"); + + if (r < 0) { + log_error("Operation failed: %s", strerror(-r)); + goto finish; + } + + if (!arg_quiet) { + for (i = 0; i < n_changes; i++) { + if (changes[i].type == UNIT_FILE_SYMLINK) + log_info("ln -s '%s' '%s'", changes[i].source, changes[i].path); + else + log_info("rm '%s'", changes[i].path); + } + } + + r = 0; + } else { + const char *method; + bool send_force = true, expect_carries_install_info = false; + dbus_bool_t a, b; + DBusMessageIter iter, sub, sub2; + + if (streq(verb, "enable")) { + method = "EnableUnitFiles"; + expect_carries_install_info = true; + } else if (streq(verb, "disable")) { + method = "DisableUnitFiles"; + send_force = false; + } else if (streq(verb, "reenable")) { + method = "ReenableUnitFiles"; + expect_carries_install_info = true; + } else if (streq(verb, "link")) + method = "LinkUnitFiles"; + else if (streq(verb, "preset")) { + method = "PresetUnitFiles"; + expect_carries_install_info = true; + } else if (streq(verb, "mask")) + method = "MaskUnitFiles"; + else if (streq(verb, "unmask")) { + method = "UnmaskUnitFiles"; + send_force = false; + } else + assert_not_reached("Unknown verb"); + + m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + method); + if (!m) { + r = log_oom(); + goto finish; + } + + dbus_message_iter_init_append(m, &iter); + + r = mangle_names(args+1, &mangled_names); + if(r < 0) + goto finish; + + r = bus_append_strv_iter(&iter, mangled_names); + if (r < 0) { + log_error("Failed to append unit files."); + goto finish; + } + + a = arg_runtime; + if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &a)) { + log_error("Failed to append runtime boolean."); + r = -ENOMEM; + goto finish; + } + + if (send_force) { + b = arg_force; + + if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &b)) { + log_error("Failed to append force boolean."); + r = -ENOMEM; + goto finish; + } + } + + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error); + if (!reply) { + log_error("Failed to issue method call: %s", bus_error_message(&error)); + r = -EIO; + goto finish; + } + + if (!dbus_message_iter_init(reply, &iter)) { + log_error("Failed to initialize iterator."); + goto finish; + } + + if (expect_carries_install_info) { + r = bus_iter_get_basic_and_next(&iter, DBUS_TYPE_BOOLEAN, &b, true); + if (r < 0) { + log_error("Failed to parse reply."); + goto finish; + } + + carries_install_info = b; + } + + if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY || + dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_STRUCT) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_recurse(&iter, &sub); + while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { + const char *type, *path, *source; + + if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRUCT) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_recurse(&sub, &sub2); + + if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &type, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &path, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &source, false) < 0) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + if (!arg_quiet) { + if (streq(type, "symlink")) + log_info("ln -s '%s' '%s'", source, path); + else + log_info("rm '%s'", path); + } + + dbus_message_iter_next(&sub); + } + + /* Try to reload if enabeld */ + if (!arg_no_reload) + r = daemon_reload(bus, args); + } + + if (carries_install_info == 0) + log_warning( +"The unit files have no [Install] section. They are not meant to be enabled\n" +"using systemctl.\n" +"Possible reasons for having this kind of units are:\n" +"1) A unit may be statically enabled by being symlinked from another unit's\n" +" .wants/ or .requires/ directory.\n" +"2) A unit's purpose may be to act as a helper for some other unit which has\n" +" a requirement dependency on it.\n" +"3) A unit may be started when needed via activation (socket, path, timer,\n" +" D-Bus, udev, scripted systemctl call, ...).\n"); + +finish: + if (m) + dbus_message_unref(m); + + if (reply) + dbus_message_unref(reply); + + unit_file_changes_free(changes, n_changes); + + dbus_error_free(&error); + + strv_free(mangled_names); + + return r; +} + +static int unit_is_enabled(DBusConnection *bus, char **args) { + DBusError error; + int r; + DBusMessage *reply = NULL; + bool enabled; + char **name; + + dbus_error_init(&error); + + r = enable_sysv_units(args); + if (r < 0) + return r; + + enabled = r > 0; + + if (!bus || avoid_bus()) { + + STRV_FOREACH(name, args+1) { + UnitFileState state; + + state = unit_file_get_state(arg_scope, arg_root, *name); + if (state < 0) { + r = state; + goto finish; + } + + if (state == UNIT_FILE_ENABLED || + state == UNIT_FILE_ENABLED_RUNTIME || + state == UNIT_FILE_STATIC) + enabled = true; + + if (!arg_quiet) + puts(unit_file_state_to_string(state)); + } + + } else { + STRV_FOREACH(name, args+1) { + const char *s; + + r = bus_method_call_with_reply ( + bus, + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "GetUnitFileState", + &reply, + NULL, + DBUS_TYPE_STRING, name, + DBUS_TYPE_INVALID); + if (r) + goto finish; + + if (!dbus_message_get_args(reply, &error, + DBUS_TYPE_STRING, &s, + DBUS_TYPE_INVALID)) { + log_error("Failed to parse reply: %s", bus_error_message(&error)); + r = -EIO; + goto finish; + } + + dbus_message_unref(reply); + reply = NULL; + + if (streq(s, "enabled") || + streq(s, "enabled-runtime") || + streq(s, "static")) + enabled = true; + + if (!arg_quiet) + puts(s); + } + } + + r = enabled ? 0 : 1; + +finish: + if (reply) + dbus_message_unref(reply); + + dbus_error_free(&error); + return r; +} + +static int systemctl_help(void) { + + pager_open_if_enabled(); + + printf("%s [OPTIONS...] {COMMAND} ...\n\n" + "Query or send control commands to the systemd manager.\n\n" + " -h --help Show this help\n" + " --version Show package version\n" + " -t --type=TYPE List only units of a particular type\n" + " -p --property=NAME Show only properties by this name\n" + " -a --all Show all units/properties, including dead/empty ones\n" + " --failed Show only failed units\n" + " --full Don't ellipsize unit names on output\n" + " --fail When queueing a new job, fail if conflicting jobs are\n" + " pending\n" + " --ignore-dependencies\n" + " When queueing a new job, ignore all its dependencies\n" + " --kill-who=WHO Who to send signal to\n" + " -s --signal=SIGNAL Which signal to send\n" + " -H --host=[USER@]HOST\n" + " Show information for remote host\n" + " -P --privileged Acquire privileges before execution\n" + " -q --quiet Suppress output\n" + " --no-block Do not wait until operation finished\n" + " --no-wall Don't send wall message before halt/power-off/reboot\n" + " --no-reload When enabling/disabling unit files, don't reload daemon\n" + " configuration\n" + " --no-legend Do not print a legend (column headers and hints)\n" + " --no-pager Do not pipe output into a pager\n" + " --no-ask-password\n" + " Do not ask for system passwords\n" + " --order When generating graph for dot, show only order\n" + " --require When generating graph for dot, show only requirement\n" + " --system Connect to system manager\n" + " --user Connect to user service manager\n" + " --global Enable/disable unit files globally\n" + " -f --force When enabling unit files, override existing symlinks\n" + " When shutting down, execute action immediately\n" + " --root=PATH Enable unit files in the specified root directory\n" + " --runtime Enable unit files only temporarily until next reboot\n" + " -n --lines=INTEGER Journal entries to show\n" + " -o --output=STRING Change journal output mode (short, short-monotonic,\n" + " verbose, export, json, json-pretty, json-sse, cat)\n\n" + "Unit Commands:\n" + " list-units List loaded units\n" + " start [NAME...] Start (activate) one or more units\n" + " stop [NAME...] Stop (deactivate) one or more units\n" + " reload [NAME...] Reload one or more units\n" + " restart [NAME...] Start or restart one or more units\n" + " try-restart [NAME...] Restart one or more units if active\n" + " reload-or-restart [NAME...] Reload one or more units if possible,\n" + " otherwise start or restart\n" + " reload-or-try-restart [NAME...] Reload one or more units if possible,\n" + " otherwise restart if active\n" + " isolate [NAME] Start one unit and stop all others\n" + " kill [NAME...] Send signal to processes of a unit\n" + " is-active [NAME...] Check whether units are active\n" + " is-failed [NAME...] Check whether units are failed\n" + " status [NAME...|PID...] Show runtime status of one or more units\n" + " show [NAME...|JOB...] Show properties of one or more\n" + " units/jobs or the manager\n" + " help [NAME...|PID...] Show manual for one or more units\n" + " reset-failed [NAME...] Reset failed state for all, one, or more\n" + " units\n" + " load [NAME...] Load one or more units\n\n" + "Unit File Commands:\n" + " list-unit-files List installed unit files\n" + " enable [NAME...] Enable one or more unit files\n" + " disable [NAME...] Disable one or more unit files\n" + " reenable [NAME...] Reenable one or more unit files\n" + " preset [NAME...] Enable/disable one or more unit files\n" + " based on preset configuration\n" + " mask [NAME...] Mask one or more units\n" + " unmask [NAME...] Unmask one or more units\n" + " link [PATH...] Link one or more units files into\n" + " the search path\n" + " is-enabled [NAME...] Check whether unit files are enabled\n\n" + "Job Commands:\n" + " list-jobs List jobs\n" + " cancel [JOB...] Cancel all, one, or more jobs\n\n" + "Status Commands:\n" + " dump Dump server status\n" + " dot Dump dependency graph for dot(1)\n\n" + "Snapshot Commands:\n" + " snapshot [NAME] Create a snapshot\n" + " delete [NAME...] Remove one or more snapshots\n\n" + "Environment Commands:\n" + " show-environment Dump environment\n" + " set-environment [NAME=VALUE...] Set one or more environment variables\n" + " unset-environment [NAME...] Unset one or more environment variables\n\n" + "Manager Lifecycle Commands:\n" + " daemon-reload Reload systemd manager configuration\n" + " daemon-reexec Reexecute systemd manager\n\n" + "System Commands:\n" + " default Enter system default mode\n" + " rescue Enter system rescue mode\n" + " emergency Enter system emergency mode\n" + " halt Shut down and halt the system\n" + " poweroff Shut down and power-off the system\n" + " reboot Shut down and reboot the system\n" + " kexec Shut down and reboot the system with kexec\n" + " exit Request user instance exit\n" + " switch-root [ROOT] [INIT] Change to a different root file system\n" + " suspend Suspend the system\n" + " hibernate Hibernate the system\n" + " hybrid-sleep Hibernate and suspend the system\n", + program_invocation_short_name); + + return 0; +} + +static int halt_help(void) { + + printf("%s [OPTIONS...]\n\n" + "%s the system.\n\n" + " --help Show this help\n" + " --halt Halt the machine\n" + " -p --poweroff Switch off the machine\n" + " --reboot Reboot the machine\n" + " -f --force Force immediate halt/power-off/reboot\n" + " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n" + " -d --no-wtmp Don't write wtmp record\n" + " --no-wall Don't send wall message before halt/power-off/reboot\n", + program_invocation_short_name, + arg_action == ACTION_REBOOT ? "Reboot" : + arg_action == ACTION_POWEROFF ? "Power off" : + "Halt"); + + return 0; +} + +static int shutdown_help(void) { + + printf("%s [OPTIONS...] [TIME] [WALL...]\n\n" + "Shut down the system.\n\n" + " --help Show this help\n" + " -H --halt Halt the machine\n" + " -P --poweroff Power-off the machine\n" + " -r --reboot Reboot the machine\n" + " -h Equivalent to --poweroff, overridden by --halt\n" + " -k Don't halt/power-off/reboot, just send warnings\n" + " --no-wall Don't send wall message before halt/power-off/reboot\n" + " -c Cancel a pending shutdown\n", + program_invocation_short_name); + + return 0; +} + +static int telinit_help(void) { + + printf("%s [OPTIONS...] {COMMAND}\n\n" + "Send control commands to the init daemon.\n\n" + " --help Show this help\n" + " --no-wall Don't send wall message before halt/power-off/reboot\n\n" + "Commands:\n" + " 0 Power-off the machine\n" + " 6 Reboot the machine\n" + " 2, 3, 4, 5 Start runlevelX.target unit\n" + " 1, s, S Enter rescue mode\n" + " q, Q Reload init daemon configuration\n" + " u, U Reexecute init daemon\n", + program_invocation_short_name); + + return 0; +} + +static int runlevel_help(void) { + + printf("%s [OPTIONS...]\n\n" + "Prints the previous and current runlevel of the init system.\n\n" + " --help Show this help\n", + program_invocation_short_name); + + return 0; +} + +static int help_types(void) { + int i; + + puts("Available unit types:"); + for(i = UNIT_SERVICE; i < _UNIT_TYPE_MAX; i++) + if (unit_type_table[i]) + puts(unit_type_table[i]); + + puts("\nAvailable unit load states: "); + for(i = UNIT_STUB; i < _UNIT_LOAD_STATE_MAX; i++) + if (unit_type_table[i]) + puts(unit_load_state_table[i]); + + return 0; +} + +static int systemctl_parse_argv(int argc, char *argv[]) { + + enum { + ARG_FAIL = 0x100, + ARG_IGNORE_DEPENDENCIES, + ARG_VERSION, + ARG_USER, + ARG_SYSTEM, + ARG_GLOBAL, + ARG_NO_BLOCK, + ARG_NO_LEGEND, + ARG_NO_PAGER, + ARG_NO_WALL, + ARG_ORDER, + ARG_REQUIRE, + ARG_ROOT, + ARG_FULL, + ARG_NO_RELOAD, + ARG_KILL_WHO, + ARG_NO_ASK_PASSWORD, + ARG_FAILED, + ARG_RUNTIME, + ARG_FORCE + }; + + static const struct option options[] = { + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, ARG_VERSION }, + { "type", required_argument, NULL, 't' }, + { "property", required_argument, NULL, 'p' }, + { "all", no_argument, NULL, 'a' }, + { "failed", no_argument, NULL, ARG_FAILED }, + { "full", no_argument, NULL, ARG_FULL }, + { "fail", no_argument, NULL, ARG_FAIL }, + { "ignore-dependencies", no_argument, NULL, ARG_IGNORE_DEPENDENCIES }, + { "user", no_argument, NULL, ARG_USER }, + { "system", no_argument, NULL, ARG_SYSTEM }, + { "global", no_argument, NULL, ARG_GLOBAL }, + { "no-block", no_argument, NULL, ARG_NO_BLOCK }, + { "no-legend", no_argument, NULL, ARG_NO_LEGEND }, + { "no-pager", no_argument, NULL, ARG_NO_PAGER }, + { "no-wall", no_argument, NULL, ARG_NO_WALL }, + { "quiet", no_argument, NULL, 'q' }, + { "order", no_argument, NULL, ARG_ORDER }, + { "require", no_argument, NULL, ARG_REQUIRE }, + { "root", required_argument, NULL, ARG_ROOT }, + { "force", no_argument, NULL, ARG_FORCE }, + { "no-reload", no_argument, NULL, ARG_NO_RELOAD }, + { "kill-who", required_argument, NULL, ARG_KILL_WHO }, + { "signal", required_argument, NULL, 's' }, + { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD }, + { "host", required_argument, NULL, 'H' }, + { "privileged",no_argument, NULL, 'P' }, + { "runtime", no_argument, NULL, ARG_RUNTIME }, + { "lines", required_argument, NULL, 'n' }, + { "output", required_argument, NULL, 'o' }, + { NULL, 0, NULL, 0 } + }; + + int c; + + assert(argc >= 0); + assert(argv); + + while ((c = getopt_long(argc, argv, "ht:p:aqfs:H:Pn:o:", options, NULL)) >= 0) { + + switch (c) { + + case 'h': + systemctl_help(); + return 0; + + case ARG_VERSION: + puts(PACKAGE_STRING); + puts(SYSTEMD_FEATURES); + return 0; + + case 't': + if (streq(optarg, "help")) { + help_types(); + return 0; + } + + if (unit_type_from_string(optarg) >= 0) { + arg_type = optarg; + break; + } + if (unit_load_state_from_string(optarg) >= 0) { + arg_load_state = optarg; + break; + } + log_error("Unkown unit type or load state '%s'.", + optarg); + log_info("Use -t help to see a list of allowed values."); + return -EINVAL; + case 'p': { + char **l; + + if (!(l = strv_append(arg_property, optarg))) + return -ENOMEM; + + strv_free(arg_property); + arg_property = l; + + /* If the user asked for a particular + * property, show it to him, even if it is + * empty. */ + arg_all = true; + break; + } + + case 'a': + arg_all = true; + break; + + case ARG_FAIL: + arg_job_mode = "fail"; + break; + + case ARG_IGNORE_DEPENDENCIES: + arg_job_mode = "ignore-dependencies"; + break; + + case ARG_USER: + arg_scope = UNIT_FILE_USER; + break; + + case ARG_SYSTEM: + arg_scope = UNIT_FILE_SYSTEM; + break; + + case ARG_GLOBAL: + arg_scope = UNIT_FILE_GLOBAL; + break; + + case ARG_NO_BLOCK: + arg_no_block = true; + break; + + case ARG_NO_LEGEND: + arg_no_legend = true; + break; + + case ARG_NO_PAGER: + arg_no_pager = true; + break; + + case ARG_NO_WALL: + arg_no_wall = true; + break; + + case ARG_ORDER: + arg_dot = DOT_ORDER; + break; + + case ARG_REQUIRE: + arg_dot = DOT_REQUIRE; + break; + + case ARG_ROOT: + arg_root = optarg; + break; + + case ARG_FULL: + arg_full = true; + break; + + case ARG_FAILED: + arg_failed = true; + break; + + case 'q': + arg_quiet = true; + break; + + case ARG_FORCE: + arg_force ++; + break; + + case 'f': + arg_force ++; + break; + + case ARG_NO_RELOAD: + arg_no_reload = true; + break; + + case ARG_KILL_WHO: + arg_kill_who = optarg; + break; + + case 's': + if ((arg_signal = signal_from_string_try_harder(optarg)) < 0) { + log_error("Failed to parse signal string %s.", optarg); + return -EINVAL; + } + break; + + case ARG_NO_ASK_PASSWORD: + arg_ask_password = false; + break; + + case 'P': + arg_transport = TRANSPORT_POLKIT; + break; + + case 'H': + arg_transport = TRANSPORT_SSH; + arg_host = optarg; + break; + + case ARG_RUNTIME: + arg_runtime = true; + break; + + case 'n': + if (safe_atou(optarg, &arg_lines) < 0) { + log_error("Failed to parse lines '%s'", optarg); + return -EINVAL; + } + break; + + case 'o': + arg_output = output_mode_from_string(optarg); + if (arg_output < 0) { + log_error("Unknown output '%s'.", optarg); + return -EINVAL; + } + break; + + case '?': + return -EINVAL; + + default: + log_error("Unknown option code '%c'.", c); + return -EINVAL; + } + } + + if (arg_transport != TRANSPORT_NORMAL && arg_scope != UNIT_FILE_SYSTEM) { + log_error("Cannot access user instance remotely."); + return -EINVAL; + } + + return 1; +} + +static int halt_parse_argv(int argc, char *argv[]) { + + enum { + ARG_HELP = 0x100, + ARG_HALT, + ARG_REBOOT, + ARG_NO_WALL + }; + + static const struct option options[] = { + { "help", no_argument, NULL, ARG_HELP }, + { "halt", no_argument, NULL, ARG_HALT }, + { "poweroff", no_argument, NULL, 'p' }, + { "reboot", no_argument, NULL, ARG_REBOOT }, + { "force", no_argument, NULL, 'f' }, + { "wtmp-only", no_argument, NULL, 'w' }, + { "no-wtmp", no_argument, NULL, 'd' }, + { "no-wall", no_argument, NULL, ARG_NO_WALL }, + { NULL, 0, NULL, 0 } + }; + + int c, runlevel; + + assert(argc >= 0); + assert(argv); + + if (utmp_get_runlevel(&runlevel, NULL) >= 0) + if (runlevel == '0' || runlevel == '6') + arg_force = 2; + + while ((c = getopt_long(argc, argv, "pfwdnih", options, NULL)) >= 0) { + switch (c) { + + case ARG_HELP: + halt_help(); + return 0; + + case ARG_HALT: + arg_action = ACTION_HALT; + break; + + case 'p': + if (arg_action != ACTION_REBOOT) + arg_action = ACTION_POWEROFF; + break; + + case ARG_REBOOT: + arg_action = ACTION_REBOOT; + break; + + case 'f': + arg_force = 2; + break; + + case 'w': + arg_dry = true; + break; + + case 'd': + arg_no_wtmp = true; + break; + + case ARG_NO_WALL: + arg_no_wall = true; + break; + + case 'i': + case 'h': + case 'n': + /* Compatibility nops */ + break; + + case '?': + return -EINVAL; + + default: + log_error("Unknown option code '%c'.", c); + return -EINVAL; + } + } + + if (optind < argc) { + log_error("Too many arguments."); + return -EINVAL; + } + + return 1; +} + +static int parse_time_spec(const char *t, usec_t *_u) { + assert(t); + assert(_u); + + if (streq(t, "now")) + *_u = 0; + else if (!strchr(t, ':')) { + uint64_t u; + + if (safe_atou64(t, &u) < 0) + return -EINVAL; + + *_u = now(CLOCK_REALTIME) + USEC_PER_MINUTE * u; + } else { + char *e = NULL; + long hour, minute; + struct tm tm; + time_t s; + usec_t n; + + errno = 0; + hour = strtol(t, &e, 10); + if (errno != 0 || *e != ':' || hour < 0 || hour > 23) + return -EINVAL; + + minute = strtol(e+1, &e, 10); + if (errno != 0 || *e != 0 || minute < 0 || minute > 59) + return -EINVAL; + + n = now(CLOCK_REALTIME); + s = (time_t) (n / USEC_PER_SEC); + + zero(tm); + assert_se(localtime_r(&s, &tm)); + + tm.tm_hour = (int) hour; + tm.tm_min = (int) minute; + tm.tm_sec = 0; + + assert_se(s = mktime(&tm)); + + *_u = (usec_t) s * USEC_PER_SEC; + + while (*_u <= n) + *_u += USEC_PER_DAY; + } + + return 0; +} + +static int shutdown_parse_argv(int argc, char *argv[]) { + + enum { + ARG_HELP = 0x100, + ARG_NO_WALL + }; + + static const struct option options[] = { + { "help", no_argument, NULL, ARG_HELP }, + { "halt", no_argument, NULL, 'H' }, + { "poweroff", no_argument, NULL, 'P' }, + { "reboot", no_argument, NULL, 'r' }, + { "kexec", no_argument, NULL, 'K' }, /* not documented extension */ + { "no-wall", no_argument, NULL, ARG_NO_WALL }, + { NULL, 0, NULL, 0 } + }; + + int c, r; + + assert(argc >= 0); + assert(argv); + + while ((c = getopt_long(argc, argv, "HPrhkt:afFc", options, NULL)) >= 0) { + switch (c) { + + case ARG_HELP: + shutdown_help(); + return 0; + + case 'H': + arg_action = ACTION_HALT; + break; + + case 'P': + arg_action = ACTION_POWEROFF; + break; + + case 'r': + if (kexec_loaded()) + arg_action = ACTION_KEXEC; + else + arg_action = ACTION_REBOOT; + break; + + case 'K': + arg_action = ACTION_KEXEC; + break; + + case 'h': + if (arg_action != ACTION_HALT) + arg_action = ACTION_POWEROFF; + break; + + case 'k': + arg_dry = true; + break; + + case ARG_NO_WALL: + arg_no_wall = true; + break; + + case 't': + case 'a': + /* Compatibility nops */ + break; + + case 'c': + arg_action = ACTION_CANCEL_SHUTDOWN; + break; + + case '?': + return -EINVAL; + + default: + log_error("Unknown option code '%c'.", c); + return -EINVAL; + } + } + + if (argc > optind && arg_action != ACTION_CANCEL_SHUTDOWN) { + r = parse_time_spec(argv[optind], &arg_when); + if (r < 0) { + log_error("Failed to parse time specification: %s", argv[optind]); + return r; + } + } else + arg_when = now(CLOCK_REALTIME) + USEC_PER_MINUTE; + + if (argc > optind && arg_action == ACTION_CANCEL_SHUTDOWN) + /* No time argument for shutdown cancel */ + arg_wall = argv + optind; + else if (argc > optind + 1) + /* We skip the time argument */ + arg_wall = argv + optind + 1; + + optind = argc; + + return 1; +} + +static int telinit_parse_argv(int argc, char *argv[]) { + + enum { + ARG_HELP = 0x100, + ARG_NO_WALL + }; + + static const struct option options[] = { + { "help", no_argument, NULL, ARG_HELP }, + { "no-wall", no_argument, NULL, ARG_NO_WALL }, + { NULL, 0, NULL, 0 } + }; + + static const struct { + char from; + enum action to; + } table[] = { + { '0', ACTION_POWEROFF }, + { '6', ACTION_REBOOT }, + { '1', ACTION_RESCUE }, + { '2', ACTION_RUNLEVEL2 }, + { '3', ACTION_RUNLEVEL3 }, + { '4', ACTION_RUNLEVEL4 }, + { '5', ACTION_RUNLEVEL5 }, + { 's', ACTION_RESCUE }, + { 'S', ACTION_RESCUE }, + { 'q', ACTION_RELOAD }, + { 'Q', ACTION_RELOAD }, + { 'u', ACTION_REEXEC }, + { 'U', ACTION_REEXEC } + }; + + unsigned i; + int c; + + assert(argc >= 0); + assert(argv); + + while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) { + switch (c) { + + case ARG_HELP: + telinit_help(); + return 0; + + case ARG_NO_WALL: + arg_no_wall = true; + break; + + case '?': + return -EINVAL; + + default: + log_error("Unknown option code '%c'.", c); + return -EINVAL; + } + } + + if (optind >= argc) { + telinit_help(); + return -EINVAL; + } + + if (optind + 1 < argc) { + log_error("Too many arguments."); + return -EINVAL; + } + + if (strlen(argv[optind]) != 1) { + log_error("Expected single character argument."); + return -EINVAL; + } + + for (i = 0; i < ELEMENTSOF(table); i++) + if (table[i].from == argv[optind][0]) + break; + + if (i >= ELEMENTSOF(table)) { + log_error("Unknown command '%s'.", argv[optind]); + return -EINVAL; + } + + arg_action = table[i].to; + + optind ++; + + return 1; +} + +static int runlevel_parse_argv(int argc, char *argv[]) { + + enum { + ARG_HELP = 0x100, + }; + + static const struct option options[] = { + { "help", no_argument, NULL, ARG_HELP }, + { NULL, 0, NULL, 0 } + }; + + int c; + + assert(argc >= 0); + assert(argv); + + while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) { + switch (c) { + + case ARG_HELP: + runlevel_help(); + return 0; + + case '?': + return -EINVAL; + + default: + log_error("Unknown option code '%c'.", c); + return -EINVAL; + } + } + + if (optind < argc) { + log_error("Too many arguments."); + return -EINVAL; + } + + return 1; +} + +static int parse_argv(int argc, char *argv[]) { + assert(argc >= 0); + assert(argv); + + if (program_invocation_short_name) { + + if (strstr(program_invocation_short_name, "halt")) { + arg_action = ACTION_HALT; + return halt_parse_argv(argc, argv); + } else if (strstr(program_invocation_short_name, "poweroff")) { + arg_action = ACTION_POWEROFF; + return halt_parse_argv(argc, argv); + } else if (strstr(program_invocation_short_name, "reboot")) { + if (kexec_loaded()) + arg_action = ACTION_KEXEC; + else + arg_action = ACTION_REBOOT; + return halt_parse_argv(argc, argv); + } else if (strstr(program_invocation_short_name, "shutdown")) { + arg_action = ACTION_POWEROFF; + return shutdown_parse_argv(argc, argv); + } else if (strstr(program_invocation_short_name, "init")) { + + if (sd_booted() > 0) { + arg_action = ACTION_INVALID; + return telinit_parse_argv(argc, argv); + } else { + /* Hmm, so some other init system is + * running, we need to forward this + * request to it. For now we simply + * guess that it is Upstart. */ + + execv("/lib/upstart/telinit", argv); + + log_error("Couldn't find an alternative telinit implementation to spawn."); + return -EIO; + } + + } else if (strstr(program_invocation_short_name, "runlevel")) { + arg_action = ACTION_RUNLEVEL; + return runlevel_parse_argv(argc, argv); + } + } + + arg_action = ACTION_SYSTEMCTL; + return systemctl_parse_argv(argc, argv); +} + +static int action_to_runlevel(void) { + + static const char table[_ACTION_MAX] = { + [ACTION_HALT] = '0', + [ACTION_POWEROFF] = '0', + [ACTION_REBOOT] = '6', + [ACTION_RUNLEVEL2] = '2', + [ACTION_RUNLEVEL3] = '3', + [ACTION_RUNLEVEL4] = '4', + [ACTION_RUNLEVEL5] = '5', + [ACTION_RESCUE] = '1' + }; + + assert(arg_action < _ACTION_MAX); + + return table[arg_action]; +} + +static int talk_upstart(void) { + DBusMessage *m = NULL, *reply = NULL; + DBusError error; + int previous, rl, r; + char + env1_buf[] = "RUNLEVEL=X", + env2_buf[] = "PREVLEVEL=X"; + char *env1 = env1_buf, *env2 = env2_buf; + const char *emit = "runlevel"; + dbus_bool_t b_false = FALSE; + DBusMessageIter iter, sub; + DBusConnection *bus; + + dbus_error_init(&error); + + if (!(rl = action_to_runlevel())) + return 0; + + if (utmp_get_runlevel(&previous, NULL) < 0) + previous = 'N'; + + if (!(bus = dbus_connection_open_private("unix:abstract=/com/ubuntu/upstart", &error))) { + if (dbus_error_has_name(&error, DBUS_ERROR_NO_SERVER)) { + r = 0; + goto finish; + } + + log_error("Failed to connect to Upstart bus: %s", bus_error_message(&error)); + r = -EIO; + goto finish; + } + + if ((r = bus_check_peercred(bus)) < 0) { + log_error("Failed to verify owner of bus."); + goto finish; + } + + if (!(m = dbus_message_new_method_call( + "com.ubuntu.Upstart", + "/com/ubuntu/Upstart", + "com.ubuntu.Upstart0_6", + "EmitEvent"))) { + + log_error("Could not allocate message."); + r = -ENOMEM; + goto finish; + } + + dbus_message_iter_init_append(m, &iter); + + env1_buf[sizeof(env1_buf)-2] = rl; + env2_buf[sizeof(env2_buf)-2] = previous; + + if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &emit) || + !dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "s", &sub) || + !dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &env1) || + !dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &env2) || + !dbus_message_iter_close_container(&iter, &sub) || + !dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &b_false)) { + log_error("Could not append arguments to message."); + r = -ENOMEM; + goto finish; + } + + if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) { + + if (bus_error_is_no_service(&error)) { + r = -EADDRNOTAVAIL; + goto finish; + } + + log_error("Failed to issue method call: %s", bus_error_message(&error)); + r = -EIO; + goto finish; + } + + r = 1; + +finish: + if (m) + dbus_message_unref(m); + + if (reply) + dbus_message_unref(reply); + + if (bus) { + dbus_connection_flush(bus); + dbus_connection_close(bus); + dbus_connection_unref(bus); + } + + dbus_error_free(&error); + + return r; +} + +static int talk_initctl(void) { + struct init_request request; + int r, fd; + char rl; + + if (!(rl = action_to_runlevel())) + return 0; + + zero(request); + request.magic = INIT_MAGIC; + request.sleeptime = 0; + request.cmd = INIT_CMD_RUNLVL; + request.runlevel = rl; + + if ((fd = open(INIT_FIFO, O_WRONLY|O_NDELAY|O_CLOEXEC|O_NOCTTY)) < 0) { + + if (errno == ENOENT) + return 0; + + log_error("Failed to open "INIT_FIFO": %m"); + return -errno; + } + + errno = 0; + r = loop_write(fd, &request, sizeof(request), false) != sizeof(request); + close_nointr_nofail(fd); + + if (r < 0) { + log_error("Failed to write to "INIT_FIFO": %m"); + return errno ? -errno : -EIO; + } + + return 1; +} + +static int systemctl_main(DBusConnection *bus, int argc, char *argv[], DBusError *error) { + + static const struct { + const char* verb; + const enum { + MORE, + LESS, + EQUAL + } argc_cmp; + const int argc; + int (* const dispatch)(DBusConnection *bus, char **args); + } verbs[] = { + { "list-units", LESS, 1, list_units }, + { "list-unit-files", EQUAL, 1, list_unit_files }, + { "list-jobs", EQUAL, 1, list_jobs }, + { "clear-jobs", EQUAL, 1, daemon_reload }, + { "load", MORE, 2, load_unit }, + { "cancel", MORE, 2, cancel_job }, + { "start", MORE, 2, start_unit }, + { "stop", MORE, 2, start_unit }, + { "condstop", MORE, 2, start_unit }, /* For compatibility with ALTLinux */ + { "reload", MORE, 2, start_unit }, + { "restart", MORE, 2, start_unit }, + { "try-restart", MORE, 2, start_unit }, + { "reload-or-restart", MORE, 2, start_unit }, + { "reload-or-try-restart", MORE, 2, start_unit }, + { "force-reload", MORE, 2, start_unit }, /* For compatibility with SysV */ + { "condreload", MORE, 2, start_unit }, /* For compatibility with ALTLinux */ + { "condrestart", MORE, 2, start_unit }, /* For compatibility with RH */ + { "isolate", EQUAL, 2, start_unit }, + { "kill", MORE, 2, kill_unit }, + { "is-active", MORE, 2, check_unit_active }, + { "check", MORE, 2, check_unit_active }, + { "is-failed", MORE, 2, check_unit_failed }, + { "show", MORE, 1, show }, + { "status", MORE, 2, show }, + { "help", MORE, 2, show }, + { "dump", EQUAL, 1, dump }, + { "dot", EQUAL, 1, dot }, + { "snapshot", LESS, 2, snapshot }, + { "delete", MORE, 2, delete_snapshot }, + { "daemon-reload", EQUAL, 1, daemon_reload }, + { "daemon-reexec", EQUAL, 1, daemon_reload }, + { "show-environment", EQUAL, 1, show_enviroment }, + { "set-environment", MORE, 2, set_environment }, + { "unset-environment", MORE, 2, set_environment }, + { "halt", EQUAL, 1, start_special }, + { "poweroff", EQUAL, 1, start_special }, + { "reboot", EQUAL, 1, start_special }, + { "kexec", EQUAL, 1, start_special }, + { "suspend", EQUAL, 1, start_special }, + { "hibernate", EQUAL, 1, start_special }, + { "hybrid-sleep", EQUAL, 1, start_special }, + { "default", EQUAL, 1, start_special }, + { "rescue", EQUAL, 1, start_special }, + { "emergency", EQUAL, 1, start_special }, + { "exit", EQUAL, 1, start_special }, + { "reset-failed", MORE, 1, reset_failed }, + { "enable", MORE, 2, enable_unit }, + { "disable", MORE, 2, enable_unit }, + { "is-enabled", MORE, 2, unit_is_enabled }, + { "reenable", MORE, 2, enable_unit }, + { "preset", MORE, 2, enable_unit }, + { "mask", MORE, 2, enable_unit }, + { "unmask", MORE, 2, enable_unit }, + { "link", MORE, 2, enable_unit }, + { "switch-root", MORE, 2, switch_root }, + }; + + int left; + unsigned i; + + assert(argc >= 0); + assert(argv); + assert(error); + + left = argc - optind; + + if (left <= 0) + /* Special rule: no arguments means "list-units" */ + i = 0; + else { + if (streq(argv[optind], "help") && !argv[optind+1]) { + log_error("This command expects one or more " + "unit names. Did you mean --help?"); + return -EINVAL; + } + + for (i = 0; i < ELEMENTSOF(verbs); i++) + if (streq(argv[optind], verbs[i].verb)) + break; + + if (i >= ELEMENTSOF(verbs)) { + log_error("Unknown operation '%s'.", argv[optind]); + return -EINVAL; + } + } + + switch (verbs[i].argc_cmp) { + + case EQUAL: + if (left != verbs[i].argc) { + log_error("Invalid number of arguments."); + return -EINVAL; + } + + break; + + case MORE: + if (left < verbs[i].argc) { + log_error("Too few arguments."); + return -EINVAL; + } + + break; + + case LESS: + if (left > verbs[i].argc) { + log_error("Too many arguments."); + return -EINVAL; + } + + break; + + default: + assert_not_reached("Unknown comparison operator."); + } + + /* Require a bus connection for all operations but + * enable/disable */ + if (!streq(verbs[i].verb, "enable") && + !streq(verbs[i].verb, "disable") && + !streq(verbs[i].verb, "is-enabled") && + !streq(verbs[i].verb, "list-unit-files") && + !streq(verbs[i].verb, "reenable") && + !streq(verbs[i].verb, "preset") && + !streq(verbs[i].verb, "mask") && + !streq(verbs[i].verb, "unmask") && + !streq(verbs[i].verb, "link")) { + + if (running_in_chroot() > 0) { + log_info("Running in chroot, ignoring request."); + return 0; + } + + if (((!streq(verbs[i].verb, "reboot") && + !streq(verbs[i].verb, "halt") && + !streq(verbs[i].verb, "poweroff")) || arg_force <= 0) && !bus) { + log_error("Failed to get D-Bus connection: %s", + dbus_error_is_set(error) ? error->message : "No connection to service manager."); + return -EIO; + } + + } else { + + if (!bus && !avoid_bus()) { + log_error("Failed to get D-Bus connection: %s", + dbus_error_is_set(error) ? error->message : "No connection to service manager."); + return -EIO; + } + } + + return verbs[i].dispatch(bus, argv + optind); +} + +static int send_shutdownd(usec_t t, char mode, bool dry_run, bool warn, const char *message) { + int fd; + struct msghdr msghdr; + struct iovec iovec[2]; + union sockaddr_union sockaddr; + struct sd_shutdown_command c; + + fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0); + if (fd < 0) + return -errno; + + zero(c); + c.usec = t; + c.mode = mode; + c.dry_run = dry_run; + c.warn_wall = warn; + + zero(sockaddr); + sockaddr.sa.sa_family = AF_UNIX; + strncpy(sockaddr.un.sun_path, "/run/systemd/shutdownd", sizeof(sockaddr.un.sun_path)); + + zero(msghdr); + msghdr.msg_name = &sockaddr; + msghdr.msg_namelen = offsetof(struct sockaddr_un, sun_path) + sizeof("/run/systemd/shutdownd") - 1; + + zero(iovec); + iovec[0].iov_base = (char*) &c; + iovec[0].iov_len = offsetof(struct sd_shutdown_command, wall_message); + + if (isempty(message)) + msghdr.msg_iovlen = 1; + else { + iovec[1].iov_base = (char*) message; + iovec[1].iov_len = strlen(message); + msghdr.msg_iovlen = 2; + } + msghdr.msg_iov = iovec; + + if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0) { + close_nointr_nofail(fd); + return -errno; + } + + close_nointr_nofail(fd); + return 0; +} + +static int reload_with_fallback(DBusConnection *bus) { + + if (bus) { + /* First, try systemd via D-Bus. */ + if (daemon_reload(bus, NULL) >= 0) + return 0; + } + + /* Nothing else worked, so let's try signals */ + assert(arg_action == ACTION_RELOAD || arg_action == ACTION_REEXEC); + + if (kill(1, arg_action == ACTION_RELOAD ? SIGHUP : SIGTERM) < 0) { + log_error("kill() failed: %m"); + return -errno; + } + + return 0; +} + +static int start_with_fallback(DBusConnection *bus) { + + if (bus) { + /* First, try systemd via D-Bus. */ + if (start_unit(bus, NULL) >= 0) + goto done; + } + + /* Hmm, talking to systemd via D-Bus didn't work. Then + * let's try to talk to Upstart via D-Bus. */ + if (talk_upstart() > 0) + goto done; + + /* Nothing else worked, so let's try + * /dev/initctl */ + if (talk_initctl() > 0) + goto done; + + log_error("Failed to talk to init daemon."); + return -EIO; + +done: + warn_wall(arg_action); + return 0; +} + +static _noreturn_ void halt_now(enum action a) { + + /* Make sure C-A-D is handled by the kernel from this + * point on... */ + reboot(RB_ENABLE_CAD); + + switch (a) { + + case ACTION_HALT: + log_info("Halting."); + reboot(RB_HALT_SYSTEM); + break; + + case ACTION_POWEROFF: + log_info("Powering off."); + reboot(RB_POWER_OFF); + break; + + case ACTION_REBOOT: + log_info("Rebooting."); + reboot(RB_AUTOBOOT); + break; + + default: + assert_not_reached("Unknown halt action."); + } + + assert_not_reached("Uh? This shouldn't happen."); +} + +static int halt_main(DBusConnection *bus) { + int r; + + if (geteuid() != 0) { + /* Try logind if we are a normal user and no special + * mode applies. Maybe PolicyKit allows us to shutdown + * the machine. */ + + if (arg_when <= 0 && + !arg_dry && + !arg_force && + (arg_action == ACTION_POWEROFF || + arg_action == ACTION_REBOOT)) { + r = reboot_with_logind(bus, arg_action); + if (r >= 0) + return r; + } + + log_error("Must be root."); + return -EPERM; + } + + if (arg_when > 0) { + char *m; + + m = strv_join(arg_wall, " "); + r = send_shutdownd(arg_when, + arg_action == ACTION_HALT ? 'H' : + arg_action == ACTION_POWEROFF ? 'P' : + arg_action == ACTION_KEXEC ? 'K' : + 'r', + arg_dry, + !arg_no_wall, + m); + free(m); + + if (r < 0) + log_warning("Failed to talk to shutdownd, proceeding with immediate shutdown: %s", strerror(-r)); + else { + char date[FORMAT_TIMESTAMP_MAX]; + + log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.", + format_timestamp(date, sizeof(date), arg_when)); + return 0; + } + } + + if (!arg_dry && !arg_force) + return start_with_fallback(bus); + + if (!arg_no_wtmp) { + if (sd_booted() > 0) + log_debug("Not writing utmp record, assuming that systemd-update-utmp is used."); + else { + r = utmp_put_shutdown(); + if (r < 0) + log_warning("Failed to write utmp record: %s", strerror(-r)); + } + } + + if (arg_dry) + return 0; + + halt_now(arg_action); + /* We should never reach this. */ + return -ENOSYS; +} + +static int runlevel_main(void) { + int r, runlevel, previous; + + r = utmp_get_runlevel(&runlevel, &previous); + if (r < 0) { + puts("unknown"); + return r; + } + + printf("%c %c\n", + previous <= 0 ? 'N' : previous, + runlevel <= 0 ? 'N' : runlevel); + + return 0; +} + +int main(int argc, char*argv[]) { + int r, retval = EXIT_FAILURE; + DBusConnection *bus = NULL; + DBusError error; + + dbus_error_init(&error); + + setlocale(LC_ALL, ""); + log_parse_environment(); + log_open(); + + r = parse_argv(argc, argv); + if (r < 0) + goto finish; + else if (r == 0) { + retval = EXIT_SUCCESS; + goto finish; + } + + /* /sbin/runlevel doesn't need to communicate via D-Bus, so + * let's shortcut this */ + if (arg_action == ACTION_RUNLEVEL) { + r = runlevel_main(); + retval = r < 0 ? EXIT_FAILURE : r; + goto finish; + } + + if (running_in_chroot() > 0 && arg_action != ACTION_SYSTEMCTL) { + log_info("Running in chroot, ignoring request."); + retval = 0; + goto finish; + } + + if (!avoid_bus()) { + if (arg_transport == TRANSPORT_NORMAL) + bus_connect(arg_scope == UNIT_FILE_SYSTEM ? DBUS_BUS_SYSTEM : DBUS_BUS_SESSION, &bus, &private_bus, &error); + else if (arg_transport == TRANSPORT_POLKIT) { + bus_connect_system_polkit(&bus, &error); + private_bus = false; + } else if (arg_transport == TRANSPORT_SSH) { + bus_connect_system_ssh(NULL, arg_host, &bus, &error); + private_bus = false; + } else + assert_not_reached("Uh, invalid transport..."); + } + + switch (arg_action) { + + case ACTION_SYSTEMCTL: + r = systemctl_main(bus, argc, argv, &error); + break; + + case ACTION_HALT: + case ACTION_POWEROFF: + case ACTION_REBOOT: + case ACTION_KEXEC: + r = halt_main(bus); + break; + + case ACTION_RUNLEVEL2: + case ACTION_RUNLEVEL3: + case ACTION_RUNLEVEL4: + case ACTION_RUNLEVEL5: + case ACTION_RESCUE: + case ACTION_EMERGENCY: + case ACTION_DEFAULT: + r = start_with_fallback(bus); + break; + + case ACTION_RELOAD: + case ACTION_REEXEC: + r = reload_with_fallback(bus); + break; + + case ACTION_CANCEL_SHUTDOWN: { + char *m = NULL; + + if (arg_wall) { + m = strv_join(arg_wall, " "); + if (!m) { + retval = EXIT_FAILURE; + goto finish; + } + } + r = send_shutdownd(arg_when, SD_SHUTDOWN_NONE, false, !arg_no_wall, m); + if (r < 0) + log_warning("Failed to talk to shutdownd, shutdown hasn't been cancelled: %s", strerror(-r)); + free(m); + break; + } + + case ACTION_INVALID: + case ACTION_RUNLEVEL: + default: + assert_not_reached("Unknown action"); + } + + retval = r < 0 ? EXIT_FAILURE : r; + +finish: + if (bus) { + dbus_connection_flush(bus); + dbus_connection_close(bus); + dbus_connection_unref(bus); + } + + dbus_error_free(&error); + + dbus_shutdown(); + + strv_free(arg_property); + + pager_close(); + ask_password_agent_close(); + polkit_agent_close(); + + return retval; +} diff --git a/src/systemd/Makefile b/src/systemd/Makefile new file mode 120000 index 000000000..d0b0e8e00 --- /dev/null +++ b/src/systemd/Makefile @@ -0,0 +1 @@ +../Makefile \ No newline at end of file diff --git a/src/systemd/sd-daemon.h b/src/systemd/sd-daemon.h new file mode 100644 index 000000000..fb7456d50 --- /dev/null +++ b/src/systemd/sd-daemon.h @@ -0,0 +1,282 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foosddaemonhfoo +#define foosddaemonhfoo + +/*** + Copyright 2010 Lennart Poettering + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation files + (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +***/ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + Reference implementation of a few systemd related interfaces for + writing daemons. These interfaces are trivial to implement. To + simplify porting we provide this reference implementation. + Applications are welcome to reimplement the algorithms described + here if they do not want to include these two source files. + + The following functionality is provided: + + - Support for logging with log levels on stderr + - File descriptor passing for socket-based activation + - Daemon startup and status notification + - Detection of systemd boots + + You may compile this with -DDISABLE_SYSTEMD to disable systemd + support. This makes all those calls NOPs that are directly related to + systemd (i.e. only sd_is_xxx() will stay useful). + + Since this is drop-in code we don't want any of our symbols to be + exported in any case. Hence we declare hidden visibility for all of + them. + + You may find an up-to-date version of these source files online: + + http://cgit.freedesktop.org/systemd/systemd/plain/src/systemd/sd-daemon.h + http://cgit.freedesktop.org/systemd/systemd/plain/src/libsystemd-daemon/sd-daemon.c + + This should compile on non-Linux systems, too, but with the + exception of the sd_is_xxx() calls all functions will become NOPs. + + See sd-daemon(3) for more information. +*/ + +#ifndef _sd_printf_attr_ +#if __GNUC__ >= 4 +#define _sd_printf_attr_(a,b) __attribute__ ((format (printf, a, b))) +#else +#define _sd_printf_attr_(a,b) +#endif +#endif + +/* + Log levels for usage on stderr: + + fprintf(stderr, SD_NOTICE "Hello World!\n"); + + This is similar to printk() usage in the kernel. +*/ +#define SD_EMERG "<0>" /* system is unusable */ +#define SD_ALERT "<1>" /* action must be taken immediately */ +#define SD_CRIT "<2>" /* critical conditions */ +#define SD_ERR "<3>" /* error conditions */ +#define SD_WARNING "<4>" /* warning conditions */ +#define SD_NOTICE "<5>" /* normal but significant condition */ +#define SD_INFO "<6>" /* informational */ +#define SD_DEBUG "<7>" /* debug-level messages */ + +/* The first passed file descriptor is fd 3 */ +#define SD_LISTEN_FDS_START 3 + +/* + Returns how many file descriptors have been passed, or a negative + errno code on failure. Optionally, removes the $LISTEN_FDS and + $LISTEN_PID file descriptors from the environment (recommended, but + problematic in threaded environments). If r is the return value of + this function you'll find the file descriptors passed as fds + SD_LISTEN_FDS_START to SD_LISTEN_FDS_START+r-1. Returns a negative + errno style error code on failure. This function call ensures that + the FD_CLOEXEC flag is set for the passed file descriptors, to make + sure they are not passed on to child processes. If FD_CLOEXEC shall + not be set, the caller needs to unset it after this call for all file + descriptors that are used. + + See sd_listen_fds(3) for more information. +*/ +int sd_listen_fds(int unset_environment); + +/* + Helper call for identifying a passed file descriptor. Returns 1 if + the file descriptor is a FIFO in the file system stored under the + specified path, 0 otherwise. If path is NULL a path name check will + not be done and the call only verifies if the file descriptor + refers to a FIFO. Returns a negative errno style error code on + failure. + + See sd_is_fifo(3) for more information. +*/ +int sd_is_fifo(int fd, const char *path); + +/* + Helper call for identifying a passed file descriptor. Returns 1 if + the file descriptor is a special character device on the file + system stored under the specified path, 0 otherwise. + If path is NULL a path name check will not be done and the call + only verifies if the file descriptor refers to a special character. + Returns a negative errno style error code on failure. + + See sd_is_special(3) for more information. +*/ +int sd_is_special(int fd, const char *path); + +/* + Helper call for identifying a passed file descriptor. Returns 1 if + the file descriptor is a socket of the specified family (AF_INET, + ...) and type (SOCK_DGRAM, SOCK_STREAM, ...), 0 otherwise. If + family is 0 a socket family check will not be done. If type is 0 a + socket type check will not be done and the call only verifies if + the file descriptor refers to a socket. If listening is > 0 it is + verified that the socket is in listening mode. (i.e. listen() has + been called) If listening is == 0 it is verified that the socket is + not in listening mode. If listening is < 0 no listening mode check + is done. Returns a negative errno style error code on failure. + + See sd_is_socket(3) for more information. +*/ +int sd_is_socket(int fd, int family, int type, int listening); + +/* + Helper call for identifying a passed file descriptor. Returns 1 if + the file descriptor is an Internet socket, of the specified family + (either AF_INET or AF_INET6) and the specified type (SOCK_DGRAM, + SOCK_STREAM, ...), 0 otherwise. If version is 0 a protocol version + check is not done. If type is 0 a socket type check will not be + done. If port is 0 a socket port check will not be done. The + listening flag is used the same way as in sd_is_socket(). Returns a + negative errno style error code on failure. + + See sd_is_socket_inet(3) for more information. +*/ +int sd_is_socket_inet(int fd, int family, int type, int listening, uint16_t port); + +/* + Helper call for identifying a passed file descriptor. Returns 1 if + the file descriptor is an AF_UNIX socket of the specified type + (SOCK_DGRAM, SOCK_STREAM, ...) and path, 0 otherwise. If type is 0 + a socket type check will not be done. If path is NULL a socket path + check will not be done. For normal AF_UNIX sockets set length to + 0. For abstract namespace sockets set length to the length of the + socket name (including the initial 0 byte), and pass the full + socket path in path (including the initial 0 byte). The listening + flag is used the same way as in sd_is_socket(). Returns a negative + errno style error code on failure. + + See sd_is_socket_unix(3) for more information. +*/ +int sd_is_socket_unix(int fd, int type, int listening, const char *path, size_t length); + +/* + Helper call for identifying a passed file descriptor. Returns 1 if + the file descriptor is a POSIX Message Queue of the specified name, + 0 otherwise. If path is NULL a message queue name check is not + done. Returns a negative errno style error code on failure. +*/ +int sd_is_mq(int fd, const char *path); + +/* + Informs systemd about changed daemon state. This takes a number of + newline separated environment-style variable assignments in a + string. The following variables are known: + + READY=1 Tells systemd that daemon startup is finished (only + relevant for services of Type=notify). The passed + argument is a boolean "1" or "0". Since there is + little value in signaling non-readiness the only + value daemons should send is "READY=1". + + STATUS=... Passes a single-line status string back to systemd + that describes the daemon state. This is free-from + and can be used for various purposes: general state + feedback, fsck-like programs could pass completion + percentages and failing programs could pass a human + readable error message. Example: "STATUS=Completed + 66% of file system check..." + + ERRNO=... If a daemon fails, the errno-style error code, + formatted as string. Example: "ERRNO=2" for ENOENT. + + BUSERROR=... If a daemon fails, the D-Bus error-style error + code. Example: "BUSERROR=org.freedesktop.DBus.Error.TimedOut" + + MAINPID=... The main pid of a daemon, in case systemd did not + fork off the process itself. Example: "MAINPID=4711" + + WATCHDOG=1 Tells systemd to update the watchdog timestamp. + Services using this feature should do this in + regular intervals. A watchdog framework can use the + timestamps to detect failed services. + + Daemons can choose to send additional variables. However, it is + recommended to prefix variable names not listed above with X_. + + Returns a negative errno-style error code on failure. Returns > 0 + if systemd could be notified, 0 if it couldn't possibly because + systemd is not running. + + Example: When a daemon finished starting up, it could issue this + call to notify systemd about it: + + sd_notify(0, "READY=1"); + + See sd_notifyf() for more complete examples. + + See sd_notify(3) for more information. +*/ +int sd_notify(int unset_environment, const char *state); + +/* + Similar to sd_notify() but takes a format string. + + Example 1: A daemon could send the following after initialization: + + sd_notifyf(0, "READY=1\n" + "STATUS=Processing requests...\n" + "MAINPID=%lu", + (unsigned long) getpid()); + + Example 2: A daemon could send the following shortly before + exiting, on failure: + + sd_notifyf(0, "STATUS=Failed to start up: %s\n" + "ERRNO=%i", + strerror(errno), + errno); + + See sd_notifyf(3) for more information. +*/ +int sd_notifyf(int unset_environment, const char *format, ...) _sd_printf_attr_(2,3); + +/* + Returns > 0 if the system was booted with systemd. Returns < 0 on + error. Returns 0 if the system was not booted with systemd. Note + that all of the functions above handle non-systemd boots just + fine. You should NOT protect them with a call to this function. Also + note that this function checks whether the system, not the user + session is controlled by systemd. However the functions above work + for both user and system services. + + See sd_booted(3) for more information. +*/ +int sd_booted(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/systemd/sd-id128.h b/src/systemd/sd-id128.h new file mode 100644 index 000000000..79bb8b3c9 --- /dev/null +++ b/src/systemd/sd-id128.h @@ -0,0 +1,109 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef fooid128hfoo +#define fooid128hfoo + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* 128 Bit ID APIs. See sd-id128(3) for more information. */ + +typedef union sd_id128 sd_id128_t; + +union sd_id128 { + uint8_t bytes[16]; + uint64_t qwords[2]; +}; + +char *sd_id128_to_string(sd_id128_t id, char s[33]); + +int sd_id128_from_string(const char s[33], sd_id128_t *ret); + +int sd_id128_randomize(sd_id128_t *ret); + +int sd_id128_get_machine(sd_id128_t *ret); + +int sd_id128_get_boot(sd_id128_t *ret); + +#define SD_ID128_MAKE(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) \ + ((sd_id128_t) { .bytes = { 0x##v0, 0x##v1, 0x##v2, 0x##v3, 0x##v4, 0x##v5, 0x##v6, 0x##v7, \ + 0x##v8, 0x##v9, 0x##v10, 0x##v11, 0x##v12, 0x##v13, 0x##v14, 0x##v15 }}) + +/* Note that SD_ID128_FORMAT_VAL will evaluate the passed argument 16 + * times. It is hence not a good idea to call this macro with an + * expensive function as paramater or an expression with side + * effects */ + +#define SD_ID128_FORMAT_STR "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x" +#define SD_ID128_FORMAT_VAL(x) (x).bytes[0], (x).bytes[1], (x).bytes[2], (x).bytes[3], (x).bytes[4], (x).bytes[5], (x).bytes[6], (x).bytes[7], (x).bytes[8], (x).bytes[9], (x).bytes[10], (x).bytes[11], (x).bytes[12], (x).bytes[13], (x).bytes[14], (x).bytes[15] + +#define SD_ID128_CONST_STR(x) \ + ((char[33]) { \ + ((x).bytes[0] >> 4) >= 10 ? 'a' + ((x).bytes[0] >> 4) - 10 : '0' + ((x).bytes[0] >> 4), \ + ((x).bytes[0] & 15) >= 10 ? 'a' + ((x).bytes[0] & 15) - 10 : '0' + ((x).bytes[0] & 15), \ + ((x).bytes[1] >> 4) >= 10 ? 'a' + ((x).bytes[1] >> 4) - 10 : '0' + ((x).bytes[1] >> 4), \ + ((x).bytes[1] & 15) >= 10 ? 'a' + ((x).bytes[1] & 15) - 10 : '0' + ((x).bytes[1] & 15), \ + ((x).bytes[2] >> 4) >= 10 ? 'a' + ((x).bytes[2] >> 4) - 10 : '0' + ((x).bytes[2] >> 4), \ + ((x).bytes[2] & 15) >= 10 ? 'a' + ((x).bytes[2] & 15) - 10 : '0' + ((x).bytes[2] & 15), \ + ((x).bytes[3] >> 4) >= 10 ? 'a' + ((x).bytes[3] >> 4) - 10 : '0' + ((x).bytes[3] >> 4), \ + ((x).bytes[3] & 15) >= 10 ? 'a' + ((x).bytes[3] & 15) - 10 : '0' + ((x).bytes[3] & 15), \ + ((x).bytes[4] >> 4) >= 10 ? 'a' + ((x).bytes[4] >> 4) - 10 : '0' + ((x).bytes[4] >> 4), \ + ((x).bytes[4] & 15) >= 10 ? 'a' + ((x).bytes[4] & 15) - 10 : '0' + ((x).bytes[4] & 15), \ + ((x).bytes[5] >> 4) >= 10 ? 'a' + ((x).bytes[5] >> 4) - 10 : '0' + ((x).bytes[5] >> 4), \ + ((x).bytes[5] & 15) >= 10 ? 'a' + ((x).bytes[5] & 15) - 10 : '0' + ((x).bytes[5] & 15), \ + ((x).bytes[6] >> 4) >= 10 ? 'a' + ((x).bytes[6] >> 4) - 10 : '0' + ((x).bytes[6] >> 4), \ + ((x).bytes[6] & 15) >= 10 ? 'a' + ((x).bytes[6] & 15) - 10 : '0' + ((x).bytes[6] & 15), \ + ((x).bytes[7] >> 4) >= 10 ? 'a' + ((x).bytes[7] >> 4) - 10 : '0' + ((x).bytes[7] >> 4), \ + ((x).bytes[7] & 15) >= 10 ? 'a' + ((x).bytes[7] & 15) - 10 : '0' + ((x).bytes[7] & 15), \ + ((x).bytes[8] >> 4) >= 10 ? 'a' + ((x).bytes[8] >> 4) - 10 : '0' + ((x).bytes[8] >> 4), \ + ((x).bytes[8] & 15) >= 10 ? 'a' + ((x).bytes[8] & 15) - 10 : '0' + ((x).bytes[8] & 15), \ + ((x).bytes[9] >> 4) >= 10 ? 'a' + ((x).bytes[9] >> 4) - 10 : '0' + ((x).bytes[9] >> 4), \ + ((x).bytes[9] & 15) >= 10 ? 'a' + ((x).bytes[9] & 15) - 10 : '0' + ((x).bytes[9] & 15), \ + ((x).bytes[10] >> 4) >= 10 ? 'a' + ((x).bytes[10] >> 4) - 10 : '0' + ((x).bytes[10] >> 4), \ + ((x).bytes[10] & 15) >= 10 ? 'a' + ((x).bytes[10] & 15) - 10 : '0' + ((x).bytes[10] & 15), \ + ((x).bytes[11] >> 4) >= 10 ? 'a' + ((x).bytes[11] >> 4) - 10 : '0' + ((x).bytes[11] >> 4), \ + ((x).bytes[11] & 15) >= 10 ? 'a' + ((x).bytes[11] & 15) - 10 : '0' + ((x).bytes[11] & 15), \ + ((x).bytes[12] >> 4) >= 10 ? 'a' + ((x).bytes[12] >> 4) - 10 : '0' + ((x).bytes[12] >> 4), \ + ((x).bytes[12] & 15) >= 10 ? 'a' + ((x).bytes[12] & 15) - 10 : '0' + ((x).bytes[12] & 15), \ + ((x).bytes[13] >> 4) >= 10 ? 'a' + ((x).bytes[13] >> 4) - 10 : '0' + ((x).bytes[13] >> 4), \ + ((x).bytes[13] & 15) >= 10 ? 'a' + ((x).bytes[13] & 15) - 10 : '0' + ((x).bytes[13] & 15), \ + ((x).bytes[14] >> 4) >= 10 ? 'a' + ((x).bytes[14] >> 4) - 10 : '0' + ((x).bytes[14] >> 4), \ + ((x).bytes[14] & 15) >= 10 ? 'a' + ((x).bytes[14] & 15) - 10 : '0' + ((x).bytes[14] & 15), \ + ((x).bytes[15] >> 4) >= 10 ? 'a' + ((x).bytes[15] >> 4) - 10 : '0' + ((x).bytes[15] >> 4), \ + ((x).bytes[15] & 15) >= 10 ? 'a' + ((x).bytes[15] & 15) - 10 : '0' + ((x).bytes[15] & 15), \ + 0 }) + +static inline int sd_id128_equal(sd_id128_t a, sd_id128_t b) { + return memcmp(&a, &b, 16) == 0; +} + +#define SD_ID128_NULL ((sd_id128_t) { .qwords = { 0, 0 }}) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/systemd/sd-journal.h b/src/systemd/sd-journal.h new file mode 100644 index 000000000..2e8d2d882 --- /dev/null +++ b/src/systemd/sd-journal.h @@ -0,0 +1,155 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foojournalhfoo +#define foojournalhfoo + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +#include +#include +#include +#include +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Journal APIs. See sd-journal(3) for more information. */ + +/* Write to daemon */ +int sd_journal_print(int priority, const char *format, ...) __attribute__ ((format (printf, 2, 3))); +int sd_journal_printv(int priority, const char *format, va_list ap); +int sd_journal_send(const char *format, ...) __attribute__((sentinel)); +int sd_journal_sendv(const struct iovec *iov, int n); +int sd_journal_perror(const char *message); + +/* Used by the macros below. Don't call this directly. */ +int sd_journal_print_with_location(int priority, const char *file, const char *line, const char *func, const char *format, ...) __attribute__ ((format (printf, 5, 6))); +int sd_journal_printv_with_location(int priority, const char *file, const char *line, const char *func, const char *format, va_list ap); +int sd_journal_send_with_location(const char *file, const char *line, const char *func, const char *format, ...) __attribute__((sentinel)); +int sd_journal_sendv_with_location(const char *file, const char *line, const char *func, const struct iovec *iov, int n); +int sd_journal_perror_with_location(const char *file, const char *line, const char *func, const char *message); + +/* implicitly add code location to messages sent, if this is enabled */ +#ifndef SD_JOURNAL_SUPPRESS_LOCATION + +#define _sd_XSTRINGIFY(x) #x +#define _sd_STRINGIFY(x) _sd_XSTRINGIFY(x) + +#define sd_journal_print(priority, ...) sd_journal_print_with_location(priority, "CODE_FILE=" __FILE__, "CODE_LINE=" _sd_STRINGIFY(__LINE__), __func__, __VA_ARGS__) +#define sd_journal_printv(priority, format, ap) sd_journal_printv_with_location(priority, "CODE_FILE=" __FILE__, "CODE_LINE=" _sd_STRINGIFY(__LINE__), __func__, format, ap) +#define sd_journal_send(...) sd_journal_send_with_location("CODE_FILE=" __FILE__, "CODE_LINE=" _sd_STRINGIFY(__LINE__), __func__, __VA_ARGS__) +#define sd_journal_sendv(iovec, n) sd_journal_sendv_with_location("CODE_FILE=" __FILE__, "CODE_LINE=" _sd_STRINGIFY(__LINE__), __func__, iovec, n) +#define sd_journal_perror(message) sd_journal_perror_with_location("CODE_FILE=" __FILE__, "CODE_LINE=" _sd_STRINGIFY(__LINE__), __func__, message) + +#endif + +int sd_journal_stream_fd(const char *identifier, int priority, int level_prefix); + +/* Browse journal stream */ + +typedef struct sd_journal sd_journal; + +/* Open flags */ +enum { + SD_JOURNAL_LOCAL_ONLY = 1, + SD_JOURNAL_RUNTIME_ONLY = 2, + SD_JOURNAL_SYSTEM_ONLY = 4 +}; + +/* Wakeup event types */ +enum { + SD_JOURNAL_NOP, + SD_JOURNAL_APPEND, + SD_JOURNAL_INVALIDATE +}; + +int sd_journal_open(sd_journal **ret, int flags); +int sd_journal_open_directory(sd_journal **ret, const char *path, int flags); +void sd_journal_close(sd_journal *j); + +int sd_journal_previous(sd_journal *j); +int sd_journal_next(sd_journal *j); + +int sd_journal_previous_skip(sd_journal *j, uint64_t skip); +int sd_journal_next_skip(sd_journal *j, uint64_t skip); + +int sd_journal_get_realtime_usec(sd_journal *j, uint64_t *ret); +int sd_journal_get_monotonic_usec(sd_journal *j, uint64_t *ret, sd_id128_t *ret_boot_id); + +int sd_journal_set_data_threshold(sd_journal *j, size_t sz); +int sd_journal_get_data_threshold(sd_journal *j, size_t *sz); + +int sd_journal_get_data(sd_journal *j, const char *field, const void **data, size_t *l); +int sd_journal_enumerate_data(sd_journal *j, const void **data, size_t *l); +void sd_journal_restart_data(sd_journal *j); + +int sd_journal_add_match(sd_journal *j, const void *data, size_t size); +int sd_journal_add_disjunction(sd_journal *j); +void sd_journal_flush_matches(sd_journal *j); + +int sd_journal_seek_head(sd_journal *j); +int sd_journal_seek_tail(sd_journal *j); +int sd_journal_seek_monotonic_usec(sd_journal *j, sd_id128_t boot_id, uint64_t usec); +int sd_journal_seek_realtime_usec(sd_journal *j, uint64_t usec); +int sd_journal_seek_cursor(sd_journal *j, const char *cursor); + +int sd_journal_get_cursor(sd_journal *j, char **cursor); +int sd_journal_test_cursor(sd_journal *j, const char *cursor); + +int sd_journal_get_cutoff_realtime_usec(sd_journal *j, uint64_t *from, uint64_t *to); +int sd_journal_get_cutoff_monotonic_usec(sd_journal *j, const sd_id128_t boot_id, uint64_t *from, uint64_t *to); + +int sd_journal_get_usage(sd_journal *j, uint64_t *bytes); + +int sd_journal_query_unique(sd_journal *j, const char *field); +int sd_journal_enumerate_unique(sd_journal *j, const void **data, size_t *l); +void sd_journal_restart_unique(sd_journal *j); + +int sd_journal_get_fd(sd_journal *j); +int sd_journal_reliable_fd(sd_journal *j); +int sd_journal_process(sd_journal *j); +int sd_journal_wait(sd_journal *j, uint64_t timeout_usec); + +int sd_journal_get_catalog(sd_journal *j, char **text); +int sd_journal_get_catalog_for_message_id(sd_id128_t id, char **ret); + +#define SD_JOURNAL_FOREACH(j) \ + if (sd_journal_seek_head(j) >= 0) \ + while (sd_journal_next(j) > 0) + +#define SD_JOURNAL_FOREACH_BACKWARDS(j) \ + if (sd_journal_seek_tail(j) >= 0) \ + while (sd_journal_previous(j) > 0) + +#define SD_JOURNAL_FOREACH_DATA(j, data, l) \ + for (sd_journal_restart_data(j); sd_journal_enumerate_data((j), &(data), &(l)) > 0; ) + +#define SD_JOURNAL_FOREACH_UNIQUE(j, data, l) \ + for (sd_journal_restart_unique(j); sd_journal_enumerate_unique((j), &(data), &(l)) > 0; ) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/systemd/sd-login.h b/src/systemd/sd-login.h new file mode 100644 index 000000000..6bd1f2da4 --- /dev/null +++ b/src/systemd/sd-login.h @@ -0,0 +1,160 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foosdloginhfoo +#define foosdloginhfoo + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * A few points: + * + * Instead of returning an empty string array or empty uid array, we + * may return NULL. + * + * Free the data the library returns with libc free(). String arrays + * are NULL terminated and you need to free the array itself in + * addition to the strings contained. + * + * We return error codes as negative errno, kernel-style. 0 or + * positive on success. + * + * These functions access data in /proc, /sys/fs/cgroup and /run. All + * of these are virtual file systems, hence the accesses are + * relatively cheap. + * + * See sd-login(3) for more information. + */ + +/* Get session from PID. Note that 'shared' processes of a user are + * not attached to a session, but only attached to a user. This will + * return an error for system processes and 'shared' processes of a + * user. */ +int sd_pid_get_session(pid_t pid, char **session); + +/* Get UID of the owner of the session of the PID (or in case the + * process is a 'shared' user process the UID of that user is + * returned). This will not return the UID of the process, but rather + * the UID of the owner of the cgroup the process is in. This will + * return an error for system processes. */ +int sd_pid_get_owner_uid(pid_t pid, uid_t *uid); + +/* Get systemd unit (i.e. service) name from PID. This will return an + * error for non-service processes. */ +int sd_pid_get_unit(pid_t, char **unit); + +/* Get state from uid. Possible states: offline, lingering, online, active, closing */ +int sd_uid_get_state(uid_t uid, char**state); + +/* Return 1 if uid has session on seat. If require_active is true will + * look for active sessions only. */ +int sd_uid_is_on_seat(uid_t uid, int require_active, const char *seat); + +/* Return sessions of user. If require_active is true will look for + * active sessions only. Returns number of sessions as return + * value. If sessions is NULL will just return number of sessions. */ +int sd_uid_get_sessions(uid_t uid, int require_active, char ***sessions); + +/* Return seats of user is on. If require_active is true will look for + * active seats only. Returns number of seats. If seats is NULL will + * just return number of seats.*/ +int sd_uid_get_seats(uid_t uid, int require_active, char ***seats); + +/* Return 1 if the session is a active. */ +int sd_session_is_active(const char *session); + +/* Get state from session. Possible states: online, active, closing + * (This function is a more generic version of + * sd_session_is_active().) */ +int sd_session_get_state(const char *sessio, char **state); + +/* Determine user id of session */ +int sd_session_get_uid(const char *session, uid_t *uid); + +/* Determine seat of session */ +int sd_session_get_seat(const char *session, char **seat); + +/* Determine the (PAM) service name this session was registered by. */ +int sd_session_get_service(const char *session, char **service); + +/* Determine the type of this session, i.e. one of "tty", "x11" or "unspecified". */ +int sd_session_get_type(const char *session, char **type); + +/* Determine the class of this session, i.e. one of "user", "greeter" or "lock-screen". */ +int sd_session_get_class(const char *session, char **clazz); + +/* Determine the X11 display of this session. */ +int sd_session_get_display(const char *session, char **display); + +/* Return active session and user of seat */ +int sd_seat_get_active(const char *seat, char **session, uid_t *uid); + +/* Return sessions and users on seat. Returns number of sessions as + * return value. If sessions is NULL returns only the number of + * sessions. */ +int sd_seat_get_sessions(const char *seat, char ***sessions, uid_t **uid, unsigned *n_uids); + +/* Return whether the seat is multi-session capable */ +int sd_seat_can_multi_session(const char *seat); + +/* Return whether the seat is TTY capable, i.e. suitable for showing console UIs */ +int sd_seat_can_tty(const char *seat); + +/* Return whether the seat is graphics capable, i.e. suitable for showing graphical UIs */ +int sd_seat_can_graphical(const char *seat); + +/* Get all seats, store in *seats. Returns the number of seats. If + * seats is NULL only returns number of seats. */ +int sd_get_seats(char ***seats); + +/* Get all sessions, store in *sessions. Returns the number of + * sessions. If sessions is NULL only returns number of sessions. */ +int sd_get_sessions(char ***sessions); + +/* Get all logged in users, store in *users. Returns the number of + * users. If users is NULL only returns the number of users. */ +int sd_get_uids(uid_t **users); + +/* Monitor object */ +typedef struct sd_login_monitor sd_login_monitor; + +/* Create a new monitor. Category must be NULL, "seat", "session", + * "uid" to get monitor events for the specific category (or all). */ +int sd_login_monitor_new(const char *category, sd_login_monitor** ret); + +/* Destroys the passed monitor. Returns NULL. */ +sd_login_monitor* sd_login_monitor_unref(sd_login_monitor *m); + +/* Flushes the monitor */ +int sd_login_monitor_flush(sd_login_monitor *m); + +/* Get FD from monitor */ +int sd_login_monitor_get_fd(sd_login_monitor *m); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/systemd/sd-messages.h b/src/systemd/sd-messages.h new file mode 100644 index 000000000..bc560947d --- /dev/null +++ b/src/systemd/sd-messages.h @@ -0,0 +1,74 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foosdmessageshfoo +#define foosdmessageshfoo + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Hey! If you add a new message here, you *must* also update the + * message catalog with an appropriate explanation */ + +#define SD_MESSAGE_JOURNAL_START SD_ID128_MAKE(f7,73,79,a8,49,0b,40,8b,be,5f,69,40,50,5a,77,7b) +#define SD_MESSAGE_JOURNAL_STOP SD_ID128_MAKE(d9,3f,b3,c9,c2,4d,45,1a,97,ce,a6,15,ce,59,c0,0b) +#define SD_MESSAGE_JOURNAL_DROPPED SD_ID128_MAKE(a5,96,d6,fe,7b,fa,49,94,82,8e,72,30,9e,95,d6,1e) +#define SD_MESSAGE_JOURNAL_MISSED SD_ID128_MAKE(e9,bf,28,e6,e8,34,48,1b,b6,f4,8f,54,8a,d1,36,06) + +#define SD_MESSAGE_COREDUMP SD_ID128_MAKE(fc,2e,22,bc,6e,e6,47,b6,b9,07,29,ab,34,a2,50,b1) + +#define SD_MESSAGE_SESSION_START SD_ID128_MAKE(8d,45,62,0c,1a,43,48,db,b1,74,10,da,57,c6,0c,66) +#define SD_MESSAGE_SESSION_STOP SD_ID128_MAKE(33,54,93,94,24,b4,45,6d,98,02,ca,83,33,ed,42,4a) +#define SD_MESSAGE_SEAT_START SD_ID128_MAKE(fc,be,fc,5d,a2,3d,42,80,93,f9,7c,82,a9,29,0f,7b) +#define SD_MESSAGE_SEAT_STOP SD_ID128_MAKE(e7,85,2b,fe,46,78,4e,d0,ac,cd,e0,4b,c8,64,c2,d5) + +#define SD_MESSAGE_TIME_CHANGE SD_ID128_MAKE(c7,a7,87,07,9b,35,4e,aa,a9,e7,7b,37,18,93,cd,27) +#define SD_MESSAGE_TIMEZONE_CHANGE SD_ID128_MAKE(45,f8,2f,4a,ef,7a,4b,bf,94,2c,e8,61,d1,f2,09,90) + +#define SD_MESSAGE_STARTUP_FINISHED SD_ID128_MAKE(b0,7a,24,9c,d0,24,41,4a,82,dd,00,cd,18,13,78,ff) + +#define SD_MESSAGE_SLEEP_START SD_ID128_MAKE(6b,bd,95,ee,97,79,41,e4,97,c4,8b,e2,7c,25,41,28) +#define SD_MESSAGE_SLEEP_STOP SD_ID128_MAKE(88,11,e6,df,2a,8e,40,f5,8a,94,ce,a2,6f,8e,bf,14) + +#define SD_MESSAGE_SHUTDOWN SD_ID128_MAKE(98,26,88,66,d1,d5,4a,49,9c,4e,98,92,1d,93,bc,40) + +#define SD_MESSAGE_UNIT_STARTING SD_ID128_MAKE(7d,49,58,e8,42,da,4a,75,8f,6c,1c,dc,7b,36,dc,c5) +#define SD_MESSAGE_UNIT_STARTED SD_ID128_MAKE(39,f5,34,79,d3,a0,45,ac,8e,11,78,62,48,23,1f,bf) +#define SD_MESSAGE_UNIT_STOPPING SD_ID128_MAKE(de,5b,42,6a,63,be,47,a7,b6,ac,3e,aa,c8,2e,2f,6f) +#define SD_MESSAGE_UNIT_STOPPED SD_ID128_MAKE(9d,1a,aa,27,d6,01,40,bd,96,36,54,38,aa,d2,02,86) +#define SD_MESSAGE_UNIT_FAILED SD_ID128_MAKE(be,02,cf,68,55,d2,42,8b,a4,0d,f7,e9,d0,22,f0,3d) +#define SD_MESSAGE_UNIT_RELOADING SD_ID128_MAKE(d3,4d,03,7f,ff,18,47,e6,ae,66,9a,37,0e,69,47,25) +#define SD_MESSAGE_UNIT_RELOADED SD_ID128_MAKE(7b,05,eb,c6,68,38,42,22,ba,a8,88,11,79,cf,da,54) + +#define SD_MESSAGE_SPAWN_FAILED SD_ID128_MAKE(64,12,57,65,1c,1b,4e,c9,a8,62,4d,7a,40,a9,e1,e7) + +#define SD_MESSAGE_FORWARD_SYSLOG_MISSED SD_ID128_MAKE(00,27,22,9c,a0,64,41,81,a7,6c,4e,92,45,8a,fa,2e) + +#define SD_MESSAGE_OVERMOUNTING SD_ID128_MAKE(1d,ee,03,69,c7,fc,47,36,b7,09,9b,38,ec,b4,6e,e7) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/systemd/sd-readahead.h b/src/systemd/sd-readahead.h new file mode 100644 index 000000000..2dac104f7 --- /dev/null +++ b/src/systemd/sd-readahead.h @@ -0,0 +1,73 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foosdreadaheadhfoo +#define foosdreadaheadhfoo + +/*** + Copyright 2010 Lennart Poettering + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation files + (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +***/ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + Reference implementation of a few boot readahead related + interfaces. These interfaces are trivial to implement. To simplify + porting we provide this reference implementation. Applications are + welcome to reimplement the algorithms described here if they do not + want to include these two source files. + + You may compile this with -DDISABLE_SYSTEMD to disable systemd + support. This makes all calls NOPs. + + Since this is drop-in code we don't want any of our symbols to be + exported in any case. Hence we declare hidden visibility for all of + them. + + You may find an up-to-date version of these source files online: + + http://cgit.freedesktop.org/systemd/systemd/plain/src/systemd/sd-readahead.h + http://cgit.freedesktop.org/systemd/systemd/plain/src/readahead/sd-readahead.c + + This should compile on non-Linux systems, too, but all functions + will become NOPs. + + See sd-readahead(3) for more information. +*/ + +/* + Controls ongoing disk read-ahead operations during boot-up. The argument + must be a string, and either "cancel", "done" or "noreplay". + + cancel = terminate read-ahead data collection, drop collected information + done = terminate read-ahead data collection, keep collected information + noreplay = terminate read-ahead replay +*/ +int sd_readahead(const char *action); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/systemd/sd-shutdown.h b/src/systemd/sd-shutdown.h new file mode 100644 index 000000000..cee435017 --- /dev/null +++ b/src/systemd/sd-shutdown.h @@ -0,0 +1,108 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foosdshutdownhfoo +#define foosdshutdownhfoo + +/*** + 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 . +***/ + +/* Interface for scheduling and cancelling timed shutdowns. */ + +#include + +typedef enum sd_shutdown_mode { + SD_SHUTDOWN_NONE = 0, + SD_SHUTDOWN_REBOOT = 'r', + SD_SHUTDOWN_POWEROFF = 'P', + SD_SHUTDOWN_HALT = 'H', + SD_SHUTDOWN_KEXEC = 'K' +} sd_shutdown_mode_t; + +/* Calculate the size of the message as "offsetof(struct + * sd_shutdown_command, wall_message) + + * strlen(command.wall_message)" */ +__attribute__((packed)) struct sd_shutdown_command { + /* Microseconds after the epoch 1970 UTC */ + uint64_t usec; + + /* H, P, r, i.e. the switches usually passed to + * /usr/bin/shutdown to select whether to halt, power-off or + * reboot the machine */ + sd_shutdown_mode_t mode:8; + + /* If non-zero, don't actually shut down, just pretend */ + unsigned dry_run:1; + + /* If non-zero, send our wall message */ + unsigned warn_wall:1; + + /* The wall message to send around. Leave empty for the + * default wall message */ + char wall_message[]; +}; + +/* The scheme is very simple: + * + * To schedule a shutdown, simply fill in and send a single + * AF_UNIX/SOCK_DGRAM datagram with the structure above suffixed with + * the wall message to the socket /run/systemd/shutdownd (leave an + * empty wall message for the default shutdown message). To calculate + * the size of the message use "offsetof(struct sd_shutdown_command, + * wall_message) + strlen(command.wall_message)". + * + * To cancel a shutdown, do the same, but send an fully zeroed out + * structure. + * + * To be notified about scheduled shutdowns, create an inotify watch + * on /run/shutdown/. Whenever a file called "scheduled" appears a + * shutdown is scheduled. If it is removed it is canceled. It is + * replaced the scheduled shutdown has been changed. The file contains + * a simple environment-like block, that contains information about + * the scheduled shutdown: + * + * USEC= + * encodes the time for the shutdown in usecs since the epoch UTC, + * formatted as numeric string. + * + * WARN_WALL= + * is 1 if a wall message shall be sent + * + * DRY_RUN= + * is 1 if a dry run shutdown is scheduled + * + * MODE= + * is the shutdown mode, one of "poweroff", "reboot", "halt", "kexec" + * + * WALL_MESSAGE= + * is the wall message to use, with all special characters escape in C style. + * + * Note that some fields might be missing if they do not apply. + * + * Note that the file is first written to a temporary file and then + * renamed, in order to provide atomic properties for readers: if the + * file exists under the name "scheduled" it is guaranteed to be fully + * written. A reader should ignore all files in that directory by any + * other name. + * + * Scheduled shutdowns are only accepted from privileged processes, + * but the directory may be watched and the file in it read by + * anybody. + */ + +#endif diff --git a/src/test/Makefile b/src/test/Makefile new file mode 120000 index 000000000..d0b0e8e00 --- /dev/null +++ b/src/test/Makefile @@ -0,0 +1 @@ +../Makefile \ No newline at end of file diff --git a/src/test/test-calendarspec.c b/src/test/test-calendarspec.c new file mode 100644 index 000000000..21b002438 --- /dev/null +++ b/src/test/test-calendarspec.c @@ -0,0 +1,88 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + +#include + +#include "calendarspec.h" +#include "util.h" + +static void test_one(const char *input, const char *output) { + CalendarSpec *c; + _cleanup_free_ char *p = NULL, *q = NULL; + usec_t u; + char buf[FORMAT_TIMESTAMP_MAX]; + int r; + + assert_se(calendar_spec_from_string(input, &c) >= 0); + + assert_se(calendar_spec_to_string(c, &p) >= 0); + printf("\"%s\" → \"%s\"\n", input, p); + + assert_se(streq(p, output)); + + u = now(CLOCK_REALTIME); + r = calendar_spec_next_usec(c, u, &u); + printf("Next: %s\n", r < 0 ? strerror(-r) : format_timestamp(buf, sizeof(buf), u)); + calendar_spec_free(c); + + assert_se(calendar_spec_from_string(p, &c) >= 0); + assert_se(calendar_spec_to_string(c, &q) >= 0); + calendar_spec_free(c); + + assert_se(streq(q, p)); +} + +int main(int argc, char* argv[]) { + CalendarSpec *c; + + test_one("Sat,Thu,Mon-Wed,Sat-Sun", "Mon-Thu,Sat,Sun *-*-* 00:00:00"); + test_one("Mon,Sun 12-*-* 2,1:23", "Mon,Sun 2012-*-* 01,02:23:00"); + test_one("Wed *-1", "Wed *-*-01 00:00:00"); + test_one("Wed-Wed,Wed *-1", "Wed *-*-01 00:00:00"); + test_one("Wed, 17:48", "Wed *-*-* 17:48:00"); + test_one("Wed-Sat,Tue 12-10-15 1:2:3", "Tue-Sat 2012-10-15 01:02:03"); + test_one("*-*-7 0:0:0", "*-*-07 00:00:00"); + test_one("10-15", "*-10-15 00:00:00"); + test_one("monday *-12-* 17:00", "Mon *-12-* 17:00:00"); + test_one("Mon,Fri *-*-3,1,2 *:30:45", "Mon,Fri *-*-01,02,03 *:30:45"); + test_one("12,14,13,12:20,10,30", "*-*-* 12,13,14:10,20,30:00"); + test_one("mon,fri *-1/2-1,3 *:30:45", "Mon,Fri *-01/2-01,03 *:30:45"); + test_one("03-05 08:05:40", "*-03-05 08:05:40"); + test_one("08:05:40", "*-*-* 08:05:40"); + test_one("05:40", "*-*-* 05:40:00"); + test_one("Sat,Sun 12-05 08:05:40", "Sat,Sun *-12-05 08:05:40"); + test_one("Sat,Sun 08:05:40", "Sat,Sun *-*-* 08:05:40"); + test_one("2003-03-05 05:40", "2003-03-05 05:40:00"); + test_one("2003-03-05", "2003-03-05 00:00:00"); + test_one("03-05", "*-03-05 00:00:00"); + test_one("hourly", "*-*-* *:00:00"); + test_one("daily", "*-*-* 00:00:00"); + test_one("monthly", "*-*-01 00:00:00"); + test_one("weekly", "Mon *-*-* 00:00:00"); + test_one("*:2/3", "*-*-* *:02/3:00"); + + assert_se(calendar_spec_from_string("test", &c) < 0); + assert_se(calendar_spec_from_string("", &c) < 0); + assert_se(calendar_spec_from_string("7", &c) < 0); + assert_se(calendar_spec_from_string("121212:1:2", &c) < 0); + + return 0; +} diff --git a/src/test/test-cgroup.c b/src/test/test-cgroup.c new file mode 100644 index 000000000..6d64a4e47 --- /dev/null +++ b/src/test/test-cgroup.c @@ -0,0 +1,105 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include + +#include "cgroup-util.h" +#include "path-util.h" +#include "util.h" +#include "log.h" + +int main(int argc, char*argv[]) { + char *path; + char *c, *p; + + assert_se(cg_create(SYSTEMD_CGROUP_CONTROLLER, "/test-a") == 0); + assert_se(cg_create(SYSTEMD_CGROUP_CONTROLLER, "/test-a") == 0); + assert_se(cg_create(SYSTEMD_CGROUP_CONTROLLER, "/test-b") == 0); + assert_se(cg_create(SYSTEMD_CGROUP_CONTROLLER, "/test-b/test-c") == 0); + assert_se(cg_create_and_attach(SYSTEMD_CGROUP_CONTROLLER, "/test-b", 0) == 0); + + assert_se(cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, getpid(), &path) == 0); + assert_se(streq(path, "/test-b")); + free(path); + + assert_se(cg_attach(SYSTEMD_CGROUP_CONTROLLER, "/test-a", 0) == 0); + + assert_se(cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, getpid(), &path) == 0); + assert_se(path_equal(path, "/test-a")); + free(path); + + assert_se(cg_create_and_attach(SYSTEMD_CGROUP_CONTROLLER, "/test-b/test-d", 0) == 0); + + assert_se(cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, getpid(), &path) == 0); + assert_se(path_equal(path, "/test-b/test-d")); + free(path); + + assert_se(cg_get_path(SYSTEMD_CGROUP_CONTROLLER, "/test-b/test-d", NULL, &path) == 0); + assert_se(path_equal(path, "/sys/fs/cgroup/systemd/test-b/test-d")); + free(path); + + assert_se(cg_is_empty(SYSTEMD_CGROUP_CONTROLLER, "/test-a", false) > 0); + assert_se(cg_is_empty(SYSTEMD_CGROUP_CONTROLLER, "/test-b", false) > 0); + assert_se(cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, "/test-a", false) > 0); + assert_se(cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, "/test-b", false) == 0); + + assert_se(cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, "/test-a", 0, false, false, false, NULL) == 0); + assert_se(cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, "/test-b", 0, false, false, false, NULL) > 0); + + assert_se(cg_migrate_recursive(SYSTEMD_CGROUP_CONTROLLER, "/test-b", "/test-a", false, false) > 0); + + assert_se(cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, "/test-a", false) == 0); + assert_se(cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, "/test-b", false) > 0); + + assert_se(cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, "/test-a", 0, false, false, false, NULL) > 0); + assert_se(cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, "/test-b", 0, false, false, false, NULL) == 0); + + cg_trim(SYSTEMD_CGROUP_CONTROLLER, "/", false); + + assert_se(cg_delete(SYSTEMD_CGROUP_CONTROLLER, "/test-b") < 0); + assert_se(cg_delete(SYSTEMD_CGROUP_CONTROLLER, "/test-a") >= 0); + + assert_se(cg_split_spec("foobar:/", &c, &p) == 0); + assert(streq(c, "foobar")); + assert(streq(p, "/")); + free(c); + free(p); + + assert_se(cg_split_spec("foobar:", &c, &p) < 0); + assert_se(cg_split_spec("foobar:asdfd", &c, &p) < 0); + assert_se(cg_split_spec(":///", &c, &p) < 0); + assert_se(cg_split_spec(":", &c, &p) < 0); + assert_se(cg_split_spec("", &c, &p) < 0); + assert_se(cg_split_spec("fo/obar:/", &c, &p) < 0); + + assert_se(cg_split_spec("/", &c, &p) >= 0); + assert(c == NULL); + assert(streq(p, "/")); + free(p); + + assert_se(cg_split_spec("foo", &c, &p) >= 0); + assert(streq(c, "foo")); + assert(p == NULL); + free(c); + + return 0; +} diff --git a/src/test/test-daemon.c b/src/test/test-daemon.c new file mode 100644 index 000000000..3215f0c56 --- /dev/null +++ b/src/test/test-daemon.c @@ -0,0 +1,37 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include + +#include + +int main(int argc, char*argv[]) { + + sd_notify(0, "STATUS=Starting up"); + sleep(5); + sd_notify(0, + "STATUS=Running\n" + "READY=1"); + sleep(10); + sd_notify(0, "STATUS=Quitting"); + + return 0; +} diff --git a/src/test/test-date.c b/src/test/test-date.c new file mode 100644 index 000000000..40ffc17b2 --- /dev/null +++ b/src/test/test-date.c @@ -0,0 +1,61 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + +#include + +#include "util.h" + +static void test_one(const char *p) { + usec_t t, q; + char buf[FORMAT_TIMESTAMP_MAX], buf_relative[FORMAT_TIMESTAMP_RELATIVE_MAX]; + + assert_se(parse_timestamp(p, &t) >= 0); + log_info("%s", format_timestamp(buf, sizeof(buf), t)); + + /* Chop off timezone */ + *strrchr(buf, ' ') = 0; + + assert_se(parse_timestamp(buf, &q) >= 0); + assert_se(q == t); + + log_info("%s", strna(format_timestamp_relative(buf_relative, sizeof(buf_relative), t))); + assert_se(parse_timestamp(buf, &q) >= 0); +} + +int main(int argc, char *argv[]) { + test_one("17:41"); + test_one("18:42:44"); + test_one("12-10-02 12:13:14"); + test_one("12-10-2 12:13:14"); + test_one("12-10-03 12:13"); + test_one("2012-12-30 18:42"); + test_one("2012-10-02"); + test_one("Tue 2012-10-02"); + test_one("now"); + test_one("yesterday"); + test_one("today"); + test_one("tomorrow"); + test_one("+2d"); + test_one("+2y 4d"); + test_one("5months ago"); + + return 0; +} diff --git a/src/test/test-engine.c b/src/test/test-engine.c new file mode 100644 index 000000000..0f3862226 --- /dev/null +++ b/src/test/test-engine.c @@ -0,0 +1,99 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include + +#include "manager.h" + +int main(int argc, char *argv[]) { + Manager *m = NULL; + Unit *a = NULL, *b = NULL, *c = NULL, *d = NULL, *e = NULL, *g = NULL, *h = NULL; + Job *j; + + assert_se(set_unit_path("test") >= 0); + + assert_se(manager_new(SYSTEMD_SYSTEM, &m) >= 0); + + printf("Load1:\n"); + assert_se(manager_load_unit(m, "a.service", NULL, NULL, &a) >= 0); + assert_se(manager_load_unit(m, "b.service", NULL, NULL, &b) >= 0); + assert_se(manager_load_unit(m, "c.service", NULL, NULL, &c) >= 0); + manager_dump_units(m, stdout, "\t"); + + printf("Test1: (Trivial)\n"); + assert_se(manager_add_job(m, JOB_START, c, JOB_REPLACE, false, NULL, &j) == 0); + manager_dump_jobs(m, stdout, "\t"); + + printf("Load2:\n"); + manager_clear_jobs(m); + assert_se(manager_load_unit(m, "d.service", NULL, NULL, &d) >= 0); + assert_se(manager_load_unit(m, "e.service", NULL, NULL, &e) >= 0); + manager_dump_units(m, stdout, "\t"); + + printf("Test2: (Cyclic Order, Unfixable)\n"); + assert_se(manager_add_job(m, JOB_START, d, JOB_REPLACE, false, NULL, &j) == -ENOEXEC); + manager_dump_jobs(m, stdout, "\t"); + + printf("Test3: (Cyclic Order, Fixable, Garbage Collector)\n"); + assert_se(manager_add_job(m, JOB_START, e, JOB_REPLACE, false, NULL, &j) == 0); + manager_dump_jobs(m, stdout, "\t"); + + printf("Test4: (Identical transaction)\n"); + assert_se(manager_add_job(m, JOB_START, e, JOB_FAIL, false, NULL, &j) == 0); + manager_dump_jobs(m, stdout, "\t"); + + printf("Load3:\n"); + assert_se(manager_load_unit(m, "g.service", NULL, NULL, &g) >= 0); + manager_dump_units(m, stdout, "\t"); + + printf("Test5: (Colliding transaction, fail)\n"); + assert_se(manager_add_job(m, JOB_START, g, JOB_FAIL, false, NULL, &j) == -EEXIST); + + printf("Test6: (Colliding transaction, replace)\n"); + assert_se(manager_add_job(m, JOB_START, g, JOB_REPLACE, false, NULL, &j) == 0); + manager_dump_jobs(m, stdout, "\t"); + + printf("Test7: (Unmergeable job type, fail)\n"); + assert_se(manager_add_job(m, JOB_STOP, g, JOB_FAIL, false, NULL, &j) == -EEXIST); + + printf("Test8: (Mergeable job type, fail)\n"); + assert_se(manager_add_job(m, JOB_RESTART, g, JOB_FAIL, false, NULL, &j) == 0); + manager_dump_jobs(m, stdout, "\t"); + + printf("Test9: (Unmergeable job type, replace)\n"); + assert_se(manager_add_job(m, JOB_STOP, g, JOB_REPLACE, false, NULL, &j) == 0); + manager_dump_jobs(m, stdout, "\t"); + + printf("Load4:\n"); + assert_se(manager_load_unit(m, "h.service", NULL, NULL, &h) >= 0); + manager_dump_units(m, stdout, "\t"); + + printf("Test10: (Unmergeable job type of auxiliary job, fail)\n"); + assert_se(manager_add_job(m, JOB_START, h, JOB_FAIL, false, NULL, &j) == 0); + manager_dump_jobs(m, stdout, "\t"); + + manager_free(m); + + return 0; +} diff --git a/src/test/test-env-replace.c b/src/test/test-env-replace.c new file mode 100644 index 000000000..cd596a6e1 --- /dev/null +++ b/src/test/test-env-replace.c @@ -0,0 +1,143 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include + +#include "util.h" +#include "log.h" +#include "strv.h" + +int main(int argc, char *argv[]) { + + const char *env[] = { + "FOO=BAR BAR", + "BAR=waldo", + NULL + }; + + const char *line[] = { + "FOO$FOO", + "FOO$FOOFOO", + "FOO${FOO}$FOO", + "FOO${FOO}", + "${FOO}", + "$FOO", + "$FOO$FOO", + "${FOO}${BAR}", + "${FOO", + NULL + }; + + char **i, **r, *t, **a, **b; + const char nulstr[] = "fuck\0fuck2\0fuck3\0\0fuck5\0\0xxx"; + + a = strv_parse_nulstr(nulstr, sizeof(nulstr)-1); + + STRV_FOREACH(i, a) + printf("nulstr--%s\n", *i); + + strv_free(a); + + r = replace_env_argv((char**) line, (char**) env); + + STRV_FOREACH(i, r) + printf("%s\n", *i); + + strv_free(r); + + t = normalize_env_assignment("foo=bar"); + printf("%s\n", t); + free(t); + + t = normalize_env_assignment("=bar"); + printf("%s\n", t); + free(t); + + t = normalize_env_assignment("foo="); + printf("%s\n", t); + free(t); + + t = normalize_env_assignment("="); + printf("%s\n", t); + free(t); + + t = normalize_env_assignment(""); + printf("%s\n", t); + free(t); + + t = normalize_env_assignment("a=\"waldo\""); + printf("%s\n", t); + free(t); + + t = normalize_env_assignment("a=\"waldo"); + printf("%s\n", t); + free(t); + + t = normalize_env_assignment("a=waldo\""); + printf("%s\n", t); + free(t); + + t = normalize_env_assignment("a=\'"); + printf("%s\n", t); + free(t); + + t = normalize_env_assignment("a=\'\'"); + printf("%s\n", t); + free(t); + + t = normalize_env_assignment(" xyz "); + printf("<%s>\n", t); + free(t); + + t = normalize_env_assignment(" xyz = bar "); + printf("<%s>\n", t); + free(t); + + t = normalize_env_assignment(" xyz = 'bar ' "); + printf("<%s>\n", t); + free(t); + + t = normalize_env_assignment(" ' xyz' = 'bar ' "); + printf("<%s>\n", t); + free(t); + + a = strv_new("FOO=BAR", "WALDO=WALDO", "WALDO=", "PIEP", "SCHLUMPF=SMURF", NULL); + b = strv_new("FOO=KKK", "FOO=", "PIEP=", "SCHLUMPF=SMURFF", "NANANANA=YES", NULL); + + r = strv_env_merge(2, a, b); + strv_free(a); + strv_free(b); + + STRV_FOREACH(i, r) + printf("%s\n", *i); + + printf("CLEANED UP:\n"); + + r = strv_env_clean(r); + + STRV_FOREACH(i, r) + printf("%s\n", *i); + + strv_free(r); + + return 0; +} diff --git a/src/test/test-hostname.c b/src/test/test-hostname.c new file mode 100644 index 000000000..ad4f28561 --- /dev/null +++ b/src/test/test-hostname.c @@ -0,0 +1,38 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include + +#include "hostname-setup.h" +#include "util.h" + +int main(int argc, char* argv[]) { + int r; + + r = hostname_setup(); + if (r < 0) + fprintf(stderr, "hostname: %s\n", strerror(-r)); + + return 0; +} diff --git a/src/test/test-id128.c b/src/test/test-id128.c new file mode 100644 index 000000000..bfd743eca --- /dev/null +++ b/src/test/test-id128.c @@ -0,0 +1,52 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +#include + +#include + +#include "util.h" +#include "macro.h" + +#define ID128_WALDI SD_ID128_MAKE(01, 02, 03, 04, 05, 06, 07, 08, 09, 0a, 0b, 0c, 0d, 0e, 0f, 10) + +int main(int argc, char *argv[]) { + sd_id128_t id, id2; + char t[33]; + + assert_se(sd_id128_randomize(&id) == 0); + printf("random: %s\n", sd_id128_to_string(id, t)); + + assert_se(sd_id128_from_string(t, &id2) == 0); + assert_se(sd_id128_equal(id, id2)); + + assert_se(sd_id128_get_machine(&id) == 0); + printf("machine: %s\n", sd_id128_to_string(id, t)); + + assert_se(sd_id128_get_boot(&id) == 0); + printf("boot: %s\n", sd_id128_to_string(id, t)); + + printf("waldi: %s\n", sd_id128_to_string(ID128_WALDI, t)); + + printf("waldi2: " SD_ID128_FORMAT_STR "\n", SD_ID128_FORMAT_VAL(ID128_WALDI)); + + return 0; +} diff --git a/src/test/test-install.c b/src/test/test-install.c new file mode 100644 index 000000000..2c1b9efcb --- /dev/null +++ b/src/test/test-install.c @@ -0,0 +1,265 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +#include +#include +#include +#include + +#include "util.h" +#include "path-util.h" +#include "install.h" + +static void dump_changes(UnitFileChange *c, unsigned n) { + unsigned i; + + assert(n == 0 || c); + + for (i = 0; i < n; i++) { + if (c[i].type == UNIT_FILE_UNLINK) + printf("rm '%s'\n", c[i].path); + else if (c[i].type == UNIT_FILE_SYMLINK) + printf("ln -s '%s' '%s'\n", c[i].source, c[i].path); + } +} + +int main(int argc, char* argv[]) { + Hashmap *h; + UnitFileList *p; + Iterator i; + int r; + const char *const files[] = { "avahi-daemon.service", NULL }; + const char *const files2[] = { "/home/lennart/test.service", NULL }; + UnitFileChange *changes = NULL; + unsigned n_changes = 0; + + h = hashmap_new(string_hash_func, string_compare_func); + r = unit_file_get_list(UNIT_FILE_SYSTEM, NULL, h); + assert_se(r == 0); + + HASHMAP_FOREACH(p, h, i) { + UnitFileState s; + + s = unit_file_get_state(UNIT_FILE_SYSTEM, NULL, path_get_file_name(p->path)); + + assert_se(p->state == s); + + fprintf(stderr, "%s (%s)\n", + p->path, + unit_file_state_to_string(p->state)); + } + + unit_file_list_free(h); + + log_error("enable"); + + r = unit_file_enable(UNIT_FILE_SYSTEM, false, NULL, (char**) files, false, &changes, &n_changes); + assert_se(r >= 0); + + log_error("enable2"); + + r = unit_file_enable(UNIT_FILE_SYSTEM, false, NULL, (char**) files, false, &changes, &n_changes); + assert_se(r >= 0); + + dump_changes(changes, n_changes); + unit_file_changes_free(changes, n_changes); + + assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, files[0]) == UNIT_FILE_ENABLED); + + log_error("disable"); + + changes = NULL; + n_changes = 0; + + r = unit_file_disable(UNIT_FILE_SYSTEM, false, NULL, (char**) files, &changes, &n_changes); + assert_se(r >= 0); + + dump_changes(changes, n_changes); + unit_file_changes_free(changes, n_changes); + + assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, files[0]) == UNIT_FILE_DISABLED); + + log_error("mask"); + changes = NULL; + n_changes = 0; + + r = unit_file_mask(UNIT_FILE_SYSTEM, false, NULL, (char**) files, false, &changes, &n_changes); + assert_se(r >= 0); + log_error("mask2"); + r = unit_file_mask(UNIT_FILE_SYSTEM, false, NULL, (char**) files, false, &changes, &n_changes); + assert_se(r >= 0); + + dump_changes(changes, n_changes); + unit_file_changes_free(changes, n_changes); + + assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, files[0]) == UNIT_FILE_MASKED); + + log_error("unmask"); + changes = NULL; + n_changes = 0; + + r = unit_file_unmask(UNIT_FILE_SYSTEM, false, NULL, (char**) files, &changes, &n_changes); + assert_se(r >= 0); + log_error("unmask2"); + r = unit_file_unmask(UNIT_FILE_SYSTEM, false, NULL, (char**) files, &changes, &n_changes); + assert_se(r >= 0); + + dump_changes(changes, n_changes); + unit_file_changes_free(changes, n_changes); + + assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, files[0]) == UNIT_FILE_DISABLED); + + log_error("mask"); + changes = NULL; + n_changes = 0; + + r = unit_file_mask(UNIT_FILE_SYSTEM, false, NULL, (char**) files, false, &changes, &n_changes); + assert_se(r >= 0); + + dump_changes(changes, n_changes); + unit_file_changes_free(changes, n_changes); + + assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, files[0]) == UNIT_FILE_MASKED); + + log_error("disable"); + changes = NULL; + n_changes = 0; + + r = unit_file_disable(UNIT_FILE_SYSTEM, false, NULL, (char**) files, &changes, &n_changes); + assert_se(r >= 0); + log_error("disable2"); + r = unit_file_disable(UNIT_FILE_SYSTEM, false, NULL, (char**) files, &changes, &n_changes); + assert_se(r >= 0); + + dump_changes(changes, n_changes); + unit_file_changes_free(changes, n_changes); + + assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, files[0]) == UNIT_FILE_MASKED); + + log_error("umask"); + changes = NULL; + n_changes = 0; + + r = unit_file_unmask(UNIT_FILE_SYSTEM, false, NULL, (char**) files, &changes, &n_changes); + assert_se(r >= 0); + + dump_changes(changes, n_changes); + unit_file_changes_free(changes, n_changes); + + assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, files[0]) == UNIT_FILE_DISABLED); + + log_error("enable files2"); + changes = NULL; + n_changes = 0; + + r = unit_file_enable(UNIT_FILE_SYSTEM, false, NULL, (char**) files2, false, &changes, &n_changes); + assert_se(r >= 0); + + dump_changes(changes, n_changes); + unit_file_changes_free(changes, n_changes); + + assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, path_get_file_name(files2[0])) == UNIT_FILE_ENABLED); + + log_error("disable files2"); + changes = NULL; + n_changes = 0; + + r = unit_file_disable(UNIT_FILE_SYSTEM, false, NULL, (char**) files2, &changes, &n_changes); + assert_se(r >= 0); + + dump_changes(changes, n_changes); + unit_file_changes_free(changes, n_changes); + + assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, path_get_file_name(files2[0])) == _UNIT_FILE_STATE_INVALID); + + log_error("link files2"); + changes = NULL; + n_changes = 0; + + r = unit_file_link(UNIT_FILE_SYSTEM, false, NULL, (char**) files2, false, &changes, &n_changes); + assert_se(r >= 0); + + dump_changes(changes, n_changes); + unit_file_changes_free(changes, n_changes); + + assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, path_get_file_name(files2[0])) == UNIT_FILE_LINKED); + + log_error("disable files2"); + changes = NULL; + n_changes = 0; + + r = unit_file_disable(UNIT_FILE_SYSTEM, false, NULL, (char**) files2, &changes, &n_changes); + assert_se(r >= 0); + + dump_changes(changes, n_changes); + unit_file_changes_free(changes, n_changes); + + assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, path_get_file_name(files2[0])) == _UNIT_FILE_STATE_INVALID); + + log_error("link files2"); + changes = NULL; + n_changes = 0; + + r = unit_file_link(UNIT_FILE_SYSTEM, false, NULL, (char**) files2, false, &changes, &n_changes); + assert_se(r >= 0); + + dump_changes(changes, n_changes); + unit_file_changes_free(changes, n_changes); + + assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, path_get_file_name(files2[0])) == UNIT_FILE_LINKED); + + log_error("reenable files2"); + changes = NULL; + n_changes = 0; + + r = unit_file_reenable(UNIT_FILE_SYSTEM, false, NULL, (char**) files2, false, &changes, &n_changes); + assert_se(r >= 0); + + dump_changes(changes, n_changes); + unit_file_changes_free(changes, n_changes); + + assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, path_get_file_name(files2[0])) == UNIT_FILE_ENABLED); + + log_error("disable files2"); + changes = NULL; + n_changes = 0; + + r = unit_file_disable(UNIT_FILE_SYSTEM, false, NULL, (char**) files2, &changes, &n_changes); + assert_se(r >= 0); + + dump_changes(changes, n_changes); + unit_file_changes_free(changes, n_changes); + + assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, path_get_file_name(files2[0])) == _UNIT_FILE_STATE_INVALID); + log_error("preset files"); + changes = NULL; + n_changes = 0; + + r = unit_file_preset(UNIT_FILE_SYSTEM, false, NULL, (char**) files, false, &changes, &n_changes); + assert_se(r >= 0); + + dump_changes(changes, n_changes); + unit_file_changes_free(changes, n_changes); + + assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, path_get_file_name(files[0])) == UNIT_FILE_ENABLED); + + return 0; +} diff --git a/src/test/test-job-type.c b/src/test/test-job-type.c new file mode 100644 index 000000000..106637443 --- /dev/null +++ b/src/test/test-job-type.c @@ -0,0 +1,105 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include + +#include "job.h" +#include "unit.h" +#include "service.h" + +int main(int argc, char*argv[]) { + JobType a, b, c, ab, bc, ab_c, bc_a, a_bc; + const ServiceState test_states[] = { SERVICE_DEAD, SERVICE_RUNNING }; + unsigned i; + bool merged_ab; + + /* fake a unit */ + static Service s = { + .meta.load_state = UNIT_LOADED, + .type = SERVICE_SIMPLE, + }; + Unit *u = UNIT(&s); + + for (i = 0; i < ELEMENTSOF(test_states); i++) { + s.state = test_states[i]; + printf("\nWith collapsing for service state %s\n" + "=========================================\n", service_state_to_string(s.state)); + for (a = 0; a < _JOB_TYPE_MAX_MERGING; a++) { + for (b = 0; b < _JOB_TYPE_MAX_MERGING; b++) { + + ab = a; + merged_ab = (job_type_merge_and_collapse(&ab, b, u) >= 0); + + if (!job_type_is_mergeable(a, b)) { + assert(!merged_ab); + printf("Not mergeable: %s + %s\n", job_type_to_string(a), job_type_to_string(b)); + continue; + } + + assert(merged_ab); + printf("%s + %s = %s\n", job_type_to_string(a), job_type_to_string(b), job_type_to_string(ab)); + + for (c = 0; c < _JOB_TYPE_MAX_MERGING; c++) { + + /* Verify transitivity of mergeability of job types */ + assert(!job_type_is_mergeable(a, b) || + !job_type_is_mergeable(b, c) || + job_type_is_mergeable(a, c)); + + /* Verify that merged entries can be merged with the same entries + * they can be merged with separately */ + assert(!job_type_is_mergeable(a, c) || job_type_is_mergeable(ab, c)); + assert(!job_type_is_mergeable(b, c) || job_type_is_mergeable(ab, c)); + + /* Verify that if a merged with b is not mergeable with c, then + * either a or b is not mergeable with c either. */ + assert(job_type_is_mergeable(ab, c) || !job_type_is_mergeable(a, c) || !job_type_is_mergeable(b, c)); + + bc = b; + if (job_type_merge_and_collapse(&bc, c, u) >= 0) { + + /* Verify associativity */ + + ab_c = ab; + assert(job_type_merge_and_collapse(&ab_c, c, u) == 0); + + bc_a = bc; + assert(job_type_merge_and_collapse(&bc_a, a, u) == 0); + + a_bc = a; + assert(job_type_merge_and_collapse(&a_bc, bc, u) == 0); + + assert(ab_c == bc_a); + assert(ab_c == a_bc); + + printf("%s + %s + %s = %s\n", job_type_to_string(a), job_type_to_string(b), job_type_to_string(c), job_type_to_string(ab_c)); + } + } + } + } + } + + + return 0; +} diff --git a/src/test/test-libudev.c b/src/test/test-libudev.c new file mode 100644 index 000000000..caa3b4d14 --- /dev/null +++ b/src/test/test-libudev.c @@ -0,0 +1,520 @@ +/*** + This file is part of systemd. + + Copyright 2008-2012 Kay Sievers + + 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "libudev.h" +#include "util.h" + +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) + +static void log_fn(struct udev *udev, + int priority, const char *file, int line, const char *fn, + const char *format, va_list args) +{ + printf("test-libudev: %s %s:%d ", fn, file, line); + vprintf(format, args); +} + +static void print_device(struct udev_device *device) +{ + const char *str; + dev_t devnum; + int count; + struct udev_list_entry *list_entry; + + printf("*** device: %p ***\n", device); + str = udev_device_get_action(device); + if (str != NULL) + printf("action: '%s'\n", str); + + str = udev_device_get_syspath(device); + printf("syspath: '%s'\n", str); + + str = udev_device_get_sysname(device); + printf("sysname: '%s'\n", str); + + str = udev_device_get_sysnum(device); + if (str != NULL) + printf("sysnum: '%s'\n", str); + + str = udev_device_get_devpath(device); + printf("devpath: '%s'\n", str); + + str = udev_device_get_subsystem(device); + if (str != NULL) + printf("subsystem: '%s'\n", str); + + str = udev_device_get_devtype(device); + if (str != NULL) + printf("devtype: '%s'\n", str); + + str = udev_device_get_driver(device); + if (str != NULL) + printf("driver: '%s'\n", str); + + str = udev_device_get_devnode(device); + if (str != NULL) + printf("devname: '%s'\n", str); + + devnum = udev_device_get_devnum(device); + if (major(devnum) > 0) + printf("devnum: %u:%u\n", major(devnum), minor(devnum)); + + count = 0; + udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(device)) { + printf("link: '%s'\n", udev_list_entry_get_name(list_entry)); + count++; + } + if (count > 0) + printf("found %i links\n", count); + + count = 0; + udev_list_entry_foreach(list_entry, udev_device_get_properties_list_entry(device)) { + printf("property: '%s=%s'\n", + udev_list_entry_get_name(list_entry), + udev_list_entry_get_value(list_entry)); + count++; + } + if (count > 0) + printf("found %i properties\n", count); + + str = udev_device_get_property_value(device, "MAJOR"); + if (str != NULL) + printf("MAJOR: '%s'\n", str); + + str = udev_device_get_sysattr_value(device, "dev"); + if (str != NULL) + printf("attr{dev}: '%s'\n", str); + + printf("\n"); +} + +static int test_device(struct udev *udev, const char *syspath) +{ + struct udev_device *device; + + printf("looking at device: %s\n", syspath); + device = udev_device_new_from_syspath(udev, syspath); + if (device == NULL) { + printf("no device found\n"); + return -1; + } + print_device(device); + udev_device_unref(device); + return 0; +} + +static int test_device_parents(struct udev *udev, const char *syspath) +{ + struct udev_device *device; + struct udev_device *device_parent; + + printf("looking at device: %s\n", syspath); + device = udev_device_new_from_syspath(udev, syspath); + if (device == NULL) + return -1; + + printf("looking at parents\n"); + device_parent = device; + do { + print_device(device_parent); + device_parent = udev_device_get_parent(device_parent); + } while (device_parent != NULL); + + printf("looking at parents again\n"); + device_parent = device; + do { + print_device(device_parent); + device_parent = udev_device_get_parent(device_parent); + } while (device_parent != NULL); + udev_device_unref(device); + + return 0; +} + +static int test_device_devnum(struct udev *udev) +{ + dev_t devnum = makedev(1, 3); + struct udev_device *device; + + printf("looking up device: %u:%u\n", major(devnum), minor(devnum)); + device = udev_device_new_from_devnum(udev, 'c', devnum); + if (device == NULL) + return -1; + print_device(device); + udev_device_unref(device); + return 0; +} + +static int test_device_subsys_name(struct udev *udev) +{ + struct udev_device *device; + + printf("looking up device: 'block':'sda'\n"); + device = udev_device_new_from_subsystem_sysname(udev, "block", "sda"); + if (device == NULL) + return -1; + print_device(device); + udev_device_unref(device); + + printf("looking up device: 'subsystem':'pci'\n"); + device = udev_device_new_from_subsystem_sysname(udev, "subsystem", "pci"); + if (device == NULL) + return -1; + print_device(device); + udev_device_unref(device); + + printf("looking up device: 'drivers':'scsi:sd'\n"); + device = udev_device_new_from_subsystem_sysname(udev, "drivers", "scsi:sd"); + if (device == NULL) + return -1; + print_device(device); + udev_device_unref(device); + + printf("looking up device: 'module':'printk'\n"); + device = udev_device_new_from_subsystem_sysname(udev, "module", "printk"); + if (device == NULL) + return -1; + print_device(device); + udev_device_unref(device); + return 0; +} + +static int test_enumerate_print_list(struct udev_enumerate *enumerate) +{ + struct udev_list_entry *list_entry; + int count = 0; + + udev_list_entry_foreach(list_entry, udev_enumerate_get_list_entry(enumerate)) { + struct udev_device *device; + + device = udev_device_new_from_syspath(udev_enumerate_get_udev(enumerate), + udev_list_entry_get_name(list_entry)); + if (device != NULL) { + printf("device: '%s' (%s)\n", + udev_device_get_syspath(device), + udev_device_get_subsystem(device)); + udev_device_unref(device); + count++; + } + } + printf("found %i devices\n\n", count); + return count; +} + +static int test_monitor(struct udev *udev) +{ + struct udev_monitor *udev_monitor = NULL; + int fd_ep; + int fd_udev = -1; + struct epoll_event ep_udev, ep_stdin; + + fd_ep = epoll_create1(EPOLL_CLOEXEC); + if (fd_ep < 0) { + printf("error creating epoll fd: %m\n"); + goto out; + } + + udev_monitor = udev_monitor_new_from_netlink(udev, "udev"); + if (udev_monitor == NULL) { + printf("no socket\n"); + goto out; + } + fd_udev = udev_monitor_get_fd(udev_monitor); + + if (udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "block", NULL) < 0 || + udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "tty", NULL) < 0 || + udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "usb", "usb_device") < 0) { + printf("filter failed\n"); + goto out; + } + + if (udev_monitor_enable_receiving(udev_monitor) < 0) { + printf("bind failed\n"); + goto out; + } + + memset(&ep_udev, 0, sizeof(struct epoll_event)); + ep_udev.events = EPOLLIN; + ep_udev.data.fd = fd_udev; + if (epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_udev, &ep_udev) < 0) { + printf("fail to add fd to epoll: %m\n"); + goto out; + } + + memset(&ep_stdin, 0, sizeof(struct epoll_event)); + ep_stdin.events = EPOLLIN; + ep_stdin.data.fd = STDIN_FILENO; + if (epoll_ctl(fd_ep, EPOLL_CTL_ADD, STDIN_FILENO, &ep_stdin) < 0) { + printf("fail to add fd to epoll: %m\n"); + goto out; + } + + for (;;) { + int fdcount; + struct epoll_event ev[4]; + struct udev_device *device; + int i; + + printf("waiting for events from udev, press ENTER to exit\n"); + fdcount = epoll_wait(fd_ep, ev, ARRAY_SIZE(ev), -1); + printf("epoll fd count: %i\n", fdcount); + + for (i = 0; i < fdcount; i++) { + if (ev[i].data.fd == fd_udev && ev[i].events & EPOLLIN) { + device = udev_monitor_receive_device(udev_monitor); + if (device == NULL) { + printf("no device from socket\n"); + continue; + } + print_device(device); + udev_device_unref(device); + } else if (ev[i].data.fd == STDIN_FILENO && ev[i].events & EPOLLIN) { + printf("exiting loop\n"); + goto out; + } + } + } +out: + if (fd_ep >= 0) + close(fd_ep); + udev_monitor_unref(udev_monitor); + return 0; +} + +static int test_queue(struct udev *udev) +{ + struct udev_queue *udev_queue; + unsigned long long int seqnum; + struct udev_list_entry *list_entry; + + udev_queue = udev_queue_new(udev); + if (udev_queue == NULL) + return -1; + seqnum = udev_queue_get_kernel_seqnum(udev_queue); + printf("seqnum kernel: %llu\n", seqnum); + seqnum = udev_queue_get_udev_seqnum(udev_queue); + printf("seqnum udev : %llu\n", seqnum); + + if (udev_queue_get_queue_is_empty(udev_queue)) + printf("queue is empty\n"); + printf("get queue list\n"); + udev_list_entry_foreach(list_entry, udev_queue_get_queued_list_entry(udev_queue)) + printf("queued: '%s' [%s]\n", udev_list_entry_get_name(list_entry), udev_list_entry_get_value(list_entry)); + printf("\n"); + printf("get queue list again\n"); + udev_list_entry_foreach(list_entry, udev_queue_get_queued_list_entry(udev_queue)) + printf("queued: '%s' [%s]\n", udev_list_entry_get_name(list_entry), udev_list_entry_get_value(list_entry)); + printf("\n"); + + list_entry = udev_queue_get_queued_list_entry(udev_queue); + if (list_entry != NULL) { + printf("event [%llu] is queued\n", seqnum); + seqnum = strtoull(udev_list_entry_get_value(list_entry), NULL, 10); + if (udev_queue_get_seqnum_is_finished(udev_queue, seqnum)) + printf("event [%llu] is not finished\n", seqnum); + else + printf("event [%llu] is finished\n", seqnum); + } + printf("\n"); + udev_queue_unref(udev_queue); + return 0; +} + +static int test_enumerate(struct udev *udev, const char *subsystem) +{ + struct udev_enumerate *udev_enumerate; + + printf("enumerate '%s'\n", subsystem == NULL ? "" : subsystem); + udev_enumerate = udev_enumerate_new(udev); + if (udev_enumerate == NULL) + return -1; + udev_enumerate_add_match_subsystem(udev_enumerate, subsystem); + udev_enumerate_scan_devices(udev_enumerate); + test_enumerate_print_list(udev_enumerate); + udev_enumerate_unref(udev_enumerate); + + printf("enumerate 'net' + duplicated scan + null + zero\n"); + udev_enumerate = udev_enumerate_new(udev); + if (udev_enumerate == NULL) + return -1; + udev_enumerate_add_match_subsystem(udev_enumerate, "net"); + udev_enumerate_scan_devices(udev_enumerate); + udev_enumerate_scan_devices(udev_enumerate); + udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/zero"); + udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/null"); + udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/zero"); + udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/null"); + udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/zero"); + udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/null"); + udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/null"); + udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/zero"); + udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/zero"); + udev_enumerate_scan_devices(udev_enumerate); + test_enumerate_print_list(udev_enumerate); + udev_enumerate_unref(udev_enumerate); + + printf("enumerate 'block'\n"); + udev_enumerate = udev_enumerate_new(udev); + if (udev_enumerate == NULL) + return -1; + udev_enumerate_add_match_subsystem(udev_enumerate,"block"); + udev_enumerate_add_match_is_initialized(udev_enumerate); + udev_enumerate_scan_devices(udev_enumerate); + test_enumerate_print_list(udev_enumerate); + udev_enumerate_unref(udev_enumerate); + + printf("enumerate 'not block'\n"); + udev_enumerate = udev_enumerate_new(udev); + if (udev_enumerate == NULL) + return -1; + udev_enumerate_add_nomatch_subsystem(udev_enumerate, "block"); + udev_enumerate_scan_devices(udev_enumerate); + test_enumerate_print_list(udev_enumerate); + udev_enumerate_unref(udev_enumerate); + + printf("enumerate 'pci, mem, vc'\n"); + udev_enumerate = udev_enumerate_new(udev); + if (udev_enumerate == NULL) + return -1; + udev_enumerate_add_match_subsystem(udev_enumerate, "pci"); + udev_enumerate_add_match_subsystem(udev_enumerate, "mem"); + udev_enumerate_add_match_subsystem(udev_enumerate, "vc"); + udev_enumerate_scan_devices(udev_enumerate); + test_enumerate_print_list(udev_enumerate); + udev_enumerate_unref(udev_enumerate); + + printf("enumerate 'subsystem'\n"); + udev_enumerate = udev_enumerate_new(udev); + if (udev_enumerate == NULL) + return -1; + udev_enumerate_scan_subsystems(udev_enumerate); + test_enumerate_print_list(udev_enumerate); + udev_enumerate_unref(udev_enumerate); + + printf("enumerate 'property IF_FS_*=filesystem'\n"); + udev_enumerate = udev_enumerate_new(udev); + if (udev_enumerate == NULL) + return -1; + udev_enumerate_add_match_property(udev_enumerate, "ID_FS*", "filesystem"); + udev_enumerate_scan_devices(udev_enumerate); + test_enumerate_print_list(udev_enumerate); + udev_enumerate_unref(udev_enumerate); + return 0; +} + +static int test_hwdb(struct udev *udev, const char *modalias) { + struct udev_hwdb * hwdb; + struct udev_list_entry *entry; + + hwdb = udev_hwdb_new(udev); + + udev_list_entry_foreach(entry, udev_hwdb_get_properties_list_entry(hwdb, modalias, 0)) + printf("'%s'='%s'\n", udev_list_entry_get_name(entry), udev_list_entry_get_value(entry)); + printf("\n"); + + hwdb = udev_hwdb_unref(hwdb); + return 0; +} + +int main(int argc, char *argv[]) +{ + struct udev *udev = NULL; + static const struct option options[] = { + { "syspath", required_argument, NULL, 'p' }, + { "subsystem", required_argument, NULL, 's' }, + { "debug", no_argument, NULL, 'd' }, + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, 'V' }, + {} + }; + const char *syspath = "/devices/virtual/mem/null"; + const char *subsystem = NULL; + char path[1024]; + + udev = udev_new(); + printf("context: %p\n", udev); + if (udev == NULL) { + printf("no context\n"); + return 1; + } + udev_set_log_fn(udev, log_fn); + printf("set log: %p\n", log_fn); + + for (;;) { + int option; + + option = getopt_long(argc, argv, "+p:s:dhV", options, NULL); + if (option == -1) + break; + + switch (option) { + case 'p': + syspath = optarg; + break; + case 's': + subsystem = optarg; + break; + case 'd': + if (udev_get_log_priority(udev) < LOG_INFO) + udev_set_log_priority(udev, LOG_INFO); + break; + case 'h': + printf("--debug --syspath= --subsystem= --help\n"); + goto out; + case 'V': + printf("%s\n", VERSION); + goto out; + default: + goto out; + } + } + + /* add sys path if needed */ + if (!startswith(syspath, "/sys")) { + snprintf(path, sizeof(path), "/sys/%s", syspath); + syspath = path; + } + + test_device(udev, syspath); + test_device_devnum(udev); + test_device_subsys_name(udev); + test_device_parents(udev, syspath); + + test_enumerate(udev, subsystem); + + test_queue(udev); + + test_hwdb(udev, "usb:v0D50p0011*"); + + test_monitor(udev); +out: + udev_unref(udev); + return 0; +} diff --git a/src/test/test-log.c b/src/test/test-log.c new file mode 100644 index 000000000..8dc3d5383 --- /dev/null +++ b/src/test/test-log.c @@ -0,0 +1,53 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + +#include +#include + +#include "log.h" + +int main(int argc, char* argv[]) { + + log_set_target(LOG_TARGET_CONSOLE); + log_open(); + + log_struct(LOG_INFO, + "MESSAGE=Waldo PID=%lu", (unsigned long) getpid(), + "SERVICE=piepapo", + NULL); + + log_set_target(LOG_TARGET_JOURNAL); + log_open(); + + log_struct(LOG_INFO, + "MESSAGE=Foobar PID=%lu", (unsigned long) getpid(), + "SERVICE=foobar", + NULL); + + log_struct(LOG_INFO, + "MESSAGE=Foobar PID=%lu", (unsigned long) getpid(), + "FORMAT_STR_TEST=1=%i A=%c 2=%hi 3=%li 4=%lli 1=%p foo=%s 2.5=%g 3.5=%g 4.5=%Lg", + (int) 1, 'A', (short) 2, (long int) 3, (long long int) 4, (void*) 1, "foo", (float) 2.5f, (double) 3.5, (long double) 4.5, + "SUFFIX=GOT IT", + NULL); + + return 0; +} diff --git a/src/test/test-loopback.c b/src/test/test-loopback.c new file mode 100644 index 000000000..ab330ac84 --- /dev/null +++ b/src/test/test-loopback.c @@ -0,0 +1,37 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include + +#include "loopback-setup.h" +#include "util.h" + +int main(int argc, char* argv[]) { + int r; + + if ((r = loopback_setup()) < 0) + fprintf(stderr, "loopback: %s\n", strerror(-r)); + + return 0; +} diff --git a/src/test/test-ns.c b/src/test/test-ns.c new file mode 100644 index 000000000..b1c759fc2 --- /dev/null +++ b/src/test/test-ns.c @@ -0,0 +1,61 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include +#include + +#include "namespace.h" +#include "log.h" + +int main(int argc, char *argv[]) { + const char * const writable[] = { + "/home", + NULL + }; + + const char * const readonly[] = { + "/", + "/usr", + "/boot", + NULL + }; + + const char * const inaccessible[] = { + "/home/lennart/projects", + NULL + }; + + int r; + + r = setup_namespace((char**) writable, (char**) readonly, (char**) inaccessible, true, 0); + if (r < 0) { + log_error("Failed to setup namespace: %s", strerror(-r)); + return 1; + } + + execl("/bin/sh", "/bin/sh", NULL); + log_error("execl(): %m"); + + return 1; +} diff --git a/src/test/test-replace-var.c b/src/test/test-replace-var.c new file mode 100644 index 000000000..b1d42d77f --- /dev/null +++ b/src/test/test-replace-var.c @@ -0,0 +1,46 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + +#include + +#include "util.h" +#include "macro.h" +#include "replace-var.h" + +static char *lookup(const char *variable, void *userdata) { + return strjoin("<<<", variable, ">>>", NULL); +} + +int main(int argc, char *argv[]) { + char *r; + + assert_se(r = replace_var("@@@foobar@xyz@HALLO@foobar@test@@testtest@TEST@...@@@", lookup, NULL)); + puts(r); + assert_se(streq(r, "@@@foobar@xyz<<>>foobar@test@@testtest<<>>...@@@")); + free(r); + + assert_se(r = strreplace("XYZFFFFXYZFFFFXYZ", "XYZ", "ABC")); + puts(r); + assert_se(streq(r, "ABCFFFFABCFFFFABC")); + free(r); + + return 0; +} diff --git a/src/test/test-sched-prio.c b/src/test/test-sched-prio.c new file mode 100644 index 000000000..29235e834 --- /dev/null +++ b/src/test/test-sched-prio.c @@ -0,0 +1,86 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2012 Holger Hans Peter Freyther + + 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 . +***/ + +#include + +#include "manager.h" + + +int main(int argc, char *argv[]) { + Manager *m; + Unit *idle_ok, *idle_bad, *rr_ok, *rr_bad, *rr_sched; + Service *ser; + FILE *serial = NULL; + FDSet *fdset = NULL; + + /* prepare the test */ + assert_se(set_unit_path(TEST_DIR) >= 0); + assert_se(manager_new(SYSTEMD_SYSTEM, &m) >= 0); + assert_se(manager_startup(m, serial, fdset) >= 0); + + /* load idle ok */ + assert_se(manager_load_unit(m, "sched_idle_ok.service", NULL, NULL, &idle_ok) >= 0); + assert_se(idle_ok->load_state == UNIT_LOADED); + ser = SERVICE(idle_ok); + assert_se(ser->exec_context.cpu_sched_policy == SCHED_OTHER); + assert_se(ser->exec_context.cpu_sched_priority == 0); + + /* + * load idle bad. This should print a warning but we have no way to look at it. + */ + assert_se(manager_load_unit(m, "sched_idle_bad.service", NULL, NULL, &idle_bad) >= 0); + assert_se(idle_bad->load_state == UNIT_LOADED); + ser = SERVICE(idle_ok); + assert_se(ser->exec_context.cpu_sched_policy == SCHED_OTHER); + assert_se(ser->exec_context.cpu_sched_priority == 0); + + /* + * load rr ok. + * Test that the default priority is moving from 0 to 1. + */ + assert_se(manager_load_unit(m, "sched_rr_ok.service", NULL, NULL, &rr_ok) >= 0); + assert_se(rr_ok->load_state == UNIT_LOADED); + ser = SERVICE(rr_ok); + assert_se(ser->exec_context.cpu_sched_policy == SCHED_RR); + assert_se(ser->exec_context.cpu_sched_priority == 1); + + /* + * load rr bad. + * Test that the value of 0 and 100 is ignored. + */ + assert_se(manager_load_unit(m, "sched_rr_bad.service", NULL, NULL, &rr_bad) >= 0); + assert_se(rr_bad->load_state == UNIT_LOADED); + ser = SERVICE(rr_bad); + assert_se(ser->exec_context.cpu_sched_policy == SCHED_RR); + assert_se(ser->exec_context.cpu_sched_priority == 1); + + /* + * load rr change. + * Test that anything between 1 and 99 can be set. + */ + assert_se(manager_load_unit(m, "sched_rr_change.service", NULL, NULL, &rr_sched) >= 0); + assert_se(rr_sched->load_state == UNIT_LOADED); + ser = SERVICE(rr_sched); + assert_se(ser->exec_context.cpu_sched_policy == SCHED_RR); + assert_se(ser->exec_context.cpu_sched_priority == 99); + + return 0; +} diff --git a/src/test/test-sleep.c b/src/test/test-sleep.c new file mode 100644 index 000000000..5a98ecda2 --- /dev/null +++ b/src/test/test-sleep.c @@ -0,0 +1,39 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + +#include +#include +#include +#include + +#include "util.h" +#include "log.h" + +int main(int argc, char* argv[]) { + log_info("Can Suspend: %s", yes_no(can_sleep("mem") > 0)); + log_info("Can Hibernate: %s", yes_no(can_sleep("disk") > 0)); + log_info("Can Hibernate+Suspend (Hybrid-Sleep): %s", yes_no(can_sleep_disk("suspend") > 0)); + log_info("Can Hibernate+Reboot: %s", yes_no(can_sleep_disk("reboot") > 0)); + log_info("Can Hibernate+Platform: %s", yes_no(can_sleep_disk("platform") > 0)); + log_info("Can Hibernate+Shutdown: %s", yes_no(can_sleep_disk("shutdown") > 0)); + + return 0; +} diff --git a/src/test/test-strip-tab-ansi.c b/src/test/test-strip-tab-ansi.c new file mode 100644 index 000000000..5016906ad --- /dev/null +++ b/src/test/test-strip-tab-ansi.c @@ -0,0 +1,52 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + +#include + +#include "util.h" + +int main(int argc, char *argv[]) { + char *p; + + assert_se(p = strdup("\tFoobar\tbar\twaldo\t")); + assert_se(strip_tab_ansi(&p, NULL)); + fprintf(stdout, "<%s>\n", p); + assert_se(streq(p, " Foobar bar waldo ")); + free(p); + + assert_se(p = strdup(ANSI_HIGHLIGHT_ON "Hello" ANSI_HIGHLIGHT_OFF ANSI_HIGHLIGHT_RED_ON " world!" ANSI_HIGHLIGHT_OFF)); + assert_se(strip_tab_ansi(&p, NULL)); + fprintf(stdout, "<%s>\n", p); + assert_se(streq(p, "Hello world!")); + free(p); + + assert_se(p = strdup("\x1B[\x1B[\t\x1B[" ANSI_HIGHLIGHT_ON "\x1B[" "Hello" ANSI_HIGHLIGHT_OFF ANSI_HIGHLIGHT_RED_ON " world!" ANSI_HIGHLIGHT_OFF)); + assert_se(strip_tab_ansi(&p, 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(streq(p, "\x1B[waldo")); + free(p); + + return 0; +} diff --git a/src/test/test-strv.c b/src/test/test-strv.c new file mode 100644 index 000000000..5ee444766 --- /dev/null +++ b/src/test/test-strv.c @@ -0,0 +1,66 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include + +#include "util.h" +#include "specifier.h" + +int main(int argc, char *argv[]) { + const Specifier table[] = { + { 'a', specifier_string, (char*) "AAAA" }, + { 'b', specifier_string, (char*) "BBBB" }, + { 0, NULL, NULL } + }; + + char *w, *state; + size_t l; + const char test[] = "test a b c 'd' e '' '' hhh '' ''"; + + printf("<%s>\n", test); + + FOREACH_WORD_QUOTED(w, l, test, state) { + char *t; + + assert_se(t = strndup(w, l)); + printf("<%s>\n", t); + free(t); + } + + printf("%s\n", default_term_for_tty("/dev/tty23")); + printf("%s\n", default_term_for_tty("/dev/ttyS23")); + printf("%s\n", default_term_for_tty("/dev/tty0")); + printf("%s\n", default_term_for_tty("/dev/pty0")); + printf("%s\n", default_term_for_tty("/dev/pts/0")); + printf("%s\n", default_term_for_tty("/dev/console")); + printf("%s\n", default_term_for_tty("tty23")); + printf("%s\n", default_term_for_tty("ttyS23")); + printf("%s\n", default_term_for_tty("tty0")); + printf("%s\n", default_term_for_tty("pty0")); + printf("%s\n", default_term_for_tty("pts/0")); + printf("%s\n", default_term_for_tty("console")); + + w = specifier_printf("xxx a=%a b=%b yyy", table, NULL); + printf("<%s>\n", w); + free(w); + + return 0; +} diff --git a/src/test/test-udev.c b/src/test/test-udev.c new file mode 100644 index 000000000..db9d36124 --- /dev/null +++ b/src/test/test-udev.c @@ -0,0 +1,170 @@ +/*** + This file is part of systemd. + + Copyright 2003-2004 Greg Kroah-Hartman + Copyright 2004-2012 Kay Sievers + + 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "udev.h" + +void udev_main_log(struct udev *udev, int priority, + const char *file, int line, const char *fn, + const char *format, va_list args) {} + +static int fake_filesystems(void) { + static const struct fakefs { + const char *src; + const char *target; + const char *error; + } fakefss[] = { + { "test/sys", "/sys", "failed to mount test /sys" }, + { "test/dev", "/dev", "failed to mount test /dev" }, + { "test/run", "/run", "failed to mount test /run" }, + { "test/run", "/etc/udev/rules.d", "failed to mount empty /etc/udev/rules.d" }, + { "test/run", "/usr/lib/udev/rules.d", "failed to mount empty /usr/lib/udev/rules.d" }, + }; + unsigned int i; + int err; + + err = unshare(CLONE_NEWNS); + if (err < 0) { + err = -errno; + fprintf(stderr, "failed to call unshare(): %m\n"); + goto out; + } + + if (mount(NULL, "/", NULL, MS_PRIVATE|MS_REC, NULL) < 0) { + err = -errno; + fprintf(stderr, "failed to mount / as private: %m\n"); + goto out; + } + + for (i = 0; i < ELEMENTSOF(fakefss); i++) { + err = mount(fakefss[i].src, fakefss[i].target, NULL, MS_BIND, NULL); + if (err < 0) { + err = -errno; + fprintf(stderr, "%s %m", fakefss[i].error); + return err; + } + } +out: + return err; +} + + +int main(int argc, char *argv[]) +{ + struct udev *udev; + struct udev_event *event = NULL; + struct udev_device *dev = NULL; + struct udev_rules *rules = NULL; + char syspath[UTIL_PATH_SIZE]; + const char *devpath; + const char *action; + sigset_t mask, sigmask_orig; + int err; + + err = fake_filesystems(); + if (err < 0) + return EXIT_FAILURE; + + udev = udev_new(); + if (udev == NULL) + exit(EXIT_FAILURE); + log_debug("version %s\n", VERSION); + label_init("/dev"); + + sigprocmask(SIG_SETMASK, NULL, &sigmask_orig); + + action = argv[1]; + if (action == NULL) { + log_error("action missing\n"); + goto out; + } + + devpath = argv[2]; + if (devpath == NULL) { + log_error("devpath missing\n"); + goto out; + } + + rules = udev_rules_new(udev, 1); + + util_strscpyl(syspath, sizeof(syspath), "/sys", devpath, NULL); + dev = udev_device_new_from_syspath(udev, syspath); + if (dev == NULL) { + log_debug("unknown device '%s'\n", devpath); + goto out; + } + + udev_device_set_action(dev, action); + event = udev_event_new(dev); + + sigfillset(&mask); + sigprocmask(SIG_SETMASK, &mask, &sigmask_orig); + event->fd_signal = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC); + if (event->fd_signal < 0) { + fprintf(stderr, "error creating signalfd\n"); + goto out; + } + + /* do what devtmpfs usually provides us */ + if (udev_device_get_devnode(dev) != NULL) { + mode_t mode = 0600; + + if (strcmp(udev_device_get_subsystem(dev), "block") == 0) + mode |= S_IFBLK; + else + mode |= S_IFCHR; + + if (strcmp(action, "remove") != 0) { + mkdir_parents_label(udev_device_get_devnode(dev), 0755); + mknod(udev_device_get_devnode(dev), mode, udev_device_get_devnum(dev)); + } else { + unlink(udev_device_get_devnode(dev)); + util_delete_path(udev, udev_device_get_devnode(dev)); + } + } + + err = udev_event_execute_rules(event, rules, &sigmask_orig); + if (err == 0) + udev_event_execute_run(event, NULL); +out: + if (event != NULL && event->fd_signal >= 0) + close(event->fd_signal); + udev_event_unref(event); + udev_device_unref(dev); + udev_rules_unref(rules); + label_finish(); + udev_unref(udev); + if (err != 0) + return EXIT_FAILURE; + return EXIT_SUCCESS; +} diff --git a/src/test/test-unit-file.c b/src/test/test-unit-file.c new file mode 100644 index 000000000..6636b949e --- /dev/null +++ b/src/test/test-unit-file.c @@ -0,0 +1,183 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + +#include +#include +#include +#include + +#include "install.h" +#include "util.h" +#include "macro.h" +#include "hashmap.h" +#include "load-fragment.h" + +static void test_unit_file_get_set(void) { + int r; + Hashmap *h; + Iterator i; + UnitFileList *p; + + h = hashmap_new(string_hash_func, string_compare_func); + assert(h); + + r = unit_file_get_list(UNIT_FILE_SYSTEM, NULL, h); + log_info("unit_file_get_list: %s", strerror(-r)); + assert(r >= 0); + + HASHMAP_FOREACH(p, h, i) + printf("%s = %s\n", p->path, unit_file_state_to_string(p->state)); + + unit_file_list_free(h); +} + +static void check_execcommand(ExecCommand *c, + const char* path, + const char* argv0, + const char* argv1, + bool ignore) { + assert_se(c); + log_info("%s %s %s %s", + c->path, c->argv[0], c->argv[1], c->argv[2]); + assert_se(streq(c->path, path)); + assert_se(streq(c->argv[0], argv0)); + assert_se(streq(c->argv[1], argv1)); + assert_se(c->argv[2] == NULL); + assert_se(c->ignore == ignore); +} + +static void test_config_parse_exec(void) { + /* int config_parse_exec( */ + /* const char *filename, */ + /* unsigned line, */ + /* const char *section, */ + /* const char *lvalue, */ + /* int ltype, */ + /* const char *rvalue, */ + /* void *data, */ + /* void *userdata) */ + int r; + + ExecCommand *c = NULL, *c1; + + /* basic test */ + r = config_parse_exec("fake", 1, "section", + "LValue", 0, "/RValue r1", + &c, NULL); + assert_se(r >= 0); + check_execcommand(c, "/RValue", "/RValue", "r1", false); + + r = config_parse_exec("fake", 2, "section", + "LValue", 0, "/RValue///slashes/// r1", + &c, NULL); + /* test slashes */ + assert_se(r >= 0); + c1 = c->command_next; + check_execcommand(c1, "/RValue/slashes", "/RValue///slashes///", + "r1", false); + + /* honour_argv0 */ + r = config_parse_exec("fake", 3, "section", + "LValue", 0, "@/RValue///slashes2/// argv0 r1", + &c, NULL); + assert_se(r >= 0); + c1 = c1->command_next; + check_execcommand(c1, "/RValue/slashes2", "argv0", "r1", false); + + /* ignore && honour_argv0 */ + r = config_parse_exec("fake", 4, "section", + "LValue", 0, "-@/RValue///slashes3/// argv0a r1", + &c, NULL); + assert_se(r >= 0); + c1 = c1->command_next; + check_execcommand(c1, + "/RValue/slashes3", "argv0a", "r1", true); + + /* ignore && honour_argv0 */ + r = config_parse_exec("fake", 4, "section", + "LValue", 0, "@-/RValue///slashes4/// argv0b r1", + &c, NULL); + assert_se(r >= 0); + c1 = c1->command_next; + check_execcommand(c1, + "/RValue/slashes4", "argv0b", "r1", true); + + /* ignore && ignore */ + r = config_parse_exec("fake", 4, "section", + "LValue", 0, "--/RValue argv0 r1", + &c, NULL); + assert_se(r == 0); + assert_se(c1->command_next == NULL); + + /* ignore && ignore */ + r = config_parse_exec("fake", 4, "section", + "LValue", 0, "-@-/RValue argv0 r1", + &c, NULL); + assert_se(r == 0); + assert_se(c1->command_next == NULL); + + /* semicolon */ + r = config_parse_exec("fake", 5, "section", + "LValue", 0, + "-@/RValue argv0 r1 ; " + "/goo/goo boo", + &c, NULL); + assert_se(r >= 0); + c1 = c1->command_next; + check_execcommand(c1, + "/RValue", "argv0", "r1", true); + + c1 = c1->command_next; + check_execcommand(c1, + "/goo/goo", "/goo/goo", "boo", false); + + /* trailing semicolon */ + r = config_parse_exec("fake", 5, "section", + "LValue", 0, + "-@/RValue argv0 r1 ; ", + &c, NULL); + assert_se(r >= 0); + c1 = c1->command_next; + check_execcommand(c1, + "/RValue", "argv0", "r1", true); + + assert_se(c1->command_next == NULL); + + /* escaped semicolon */ + r = config_parse_exec("fake", 5, "section", + "LValue", 0, + "/usr/bin/find \\;", + &c, NULL); + assert_se(r >= 0); + c1 = c1->command_next; + check_execcommand(c1, + "/usr/bin/find", "/usr/bin/find", ";", false); + + exec_command_free_list(c); +} + +int main(int argc, char *argv[]) { + + test_unit_file_get_set(); + test_config_parse_exec(); + + return 0; +} diff --git a/src/test/test-unit-name.c b/src/test/test-unit-name.c new file mode 100644 index 000000000..50187e112 --- /dev/null +++ b/src/test/test-unit-name.c @@ -0,0 +1,177 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + +#include +#include +#include + +#include "unit-name.h" +#include "util.h" + +int main(int argc, char* argv[]) { + char *t, *k; + + t = unit_name_replace_instance("foo@.service", "waldo"); + puts(t); + free(t); + + t = unit_name_replace_instance("foo@xyz.service", "waldo"); + puts(t); + free(t); + + t = unit_name_replace_instance("xyz", "waldo"); + puts(t); + free(t); + + t = unit_name_replace_instance("", "waldo"); + puts(t); + free(t); + + t = unit_name_replace_instance("", ""); + puts(t); + free(t); + + t = unit_name_replace_instance("foo.service", "waldo"); + puts(t); + free(t); + + t = unit_name_replace_instance(".service", "waldo"); + puts(t); + free(t); + + t = unit_name_replace_instance("foo@bar", "waldo"); + puts(t); + free(t); + + t = unit_name_replace_instance("foo@", "waldo"); + puts(t); + free(t); + + t = unit_name_replace_instance("@", "waldo"); + puts(t); + free(t); + + t = unit_name_replace_instance("@bar", "waldo"); + puts(t); + free(t); + + t = unit_name_from_path("/waldo", ".mount"); + puts(t); + k = unit_name_to_path(t); + puts(k); + free(k); + free(t); + + t = unit_name_from_path("/waldo/quuix", ".mount"); + puts(t); + k = unit_name_to_path(t); + puts(k); + free(k); + free(t); + + t = unit_name_from_path("/waldo/quuix/", ".mount"); + puts(t); + k = unit_name_to_path(t); + puts(k); + free(k); + free(t); + + t = unit_name_from_path("/", ".mount"); + puts(t); + k = unit_name_to_path(t); + puts(k); + free(k); + free(t); + + t = unit_name_from_path("///", ".mount"); + puts(t); + k = unit_name_to_path(t); + puts(k); + free(k); + free(t); + + t = unit_name_from_path_instance("waldo", "/waldo", ".mount"); + puts(t); + free(t); + + t = unit_name_from_path_instance("waldo", "/waldo////quuix////", ".mount"); + puts(t); + free(t); + + t = unit_name_from_path_instance("waldo", "/", ".mount"); + puts(t); + free(t); + + t = unit_name_from_path_instance("wa--ldo", "/--", ".mount"); + puts(t); + free(t); + + assert_se(t = unit_name_mangle("/home")); + assert_se(k = unit_name_mangle(t)); + puts(t); + assert_se(streq(t, k)); + free(t); + free(k); + + assert_se(t = unit_name_mangle("/dev/sda")); + assert_se(k = unit_name_mangle(t)); + puts(t); + assert_se(streq(t, k)); + free(t); + free(k); + + assert_se(t = unit_name_mangle("üxknürz.service")); + assert_se(k = unit_name_mangle(t)); + puts(t); + assert_se(streq(t, k)); + free(t); + free(k); + + assert_se(t = unit_name_mangle("foobar-meh...waldi.service")); + assert_se(k = unit_name_mangle(t)); + puts(t); + assert_se(streq(t, k)); + free(t); + free(k); + + assert_se(t = unit_name_mangle("_____####----.....service")); + assert_se(k = unit_name_mangle(t)); + puts(t); + assert_se(streq(t, k)); + free(t); + free(k); + + assert_se(t = unit_name_mangle("_____##@;;;,,,##----.....service")); + assert_se(k = unit_name_mangle(t)); + puts(t); + assert_se(streq(t, k)); + free(t); + free(k); + + assert_se(t = unit_name_mangle("xxx@@@@/////\\\\\\\\\\yyy.service")); + assert_se(k = unit_name_mangle(t)); + puts(t); + assert_se(streq(t, k)); + free(t); + free(k); + + return 0; +} diff --git a/src/test/test-watchdog.c b/src/test/test-watchdog.c new file mode 100644 index 000000000..ccb185470 --- /dev/null +++ b/src/test/test-watchdog.c @@ -0,0 +1,51 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + +#include +#include + +#include "watchdog.h" +#include "log.h" + +int main(int argc, char *argv[]) { + usec_t t = 10 * USEC_PER_SEC; + unsigned i; + int r; + + log_set_max_level(LOG_DEBUG); + log_parse_environment(); + + r = watchdog_set_timeout(&t); + if (r < 0) + log_warning("Failed to open watchdog: %s", strerror(-r)); + + for (i = 0; i < 5; i++) { + log_info("Pinging..."); + r = watchdog_ping(); + if (r < 0) + log_warning("Failed to ping watchdog: %s", strerror(-r)); + + usleep(t/2); + } + + watchdog_close(true); + return 0; +} diff --git a/src/timedate/.gitignore b/src/timedate/.gitignore new file mode 100644 index 000000000..48757f096 --- /dev/null +++ b/src/timedate/.gitignore @@ -0,0 +1 @@ +org.freedesktop.timedate1.policy diff --git a/src/timedate/Makefile b/src/timedate/Makefile new file mode 120000 index 000000000..d0b0e8e00 --- /dev/null +++ b/src/timedate/Makefile @@ -0,0 +1 @@ +../Makefile \ No newline at end of file diff --git a/src/timedate/org.freedesktop.timedate1.conf b/src/timedate/org.freedesktop.timedate1.conf new file mode 100644 index 000000000..36557d584 --- /dev/null +++ b/src/timedate/org.freedesktop.timedate1.conf @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + diff --git a/src/timedate/org.freedesktop.timedate1.policy.in b/src/timedate/org.freedesktop.timedate1.policy.in new file mode 100644 index 000000000..aa30b7083 --- /dev/null +++ b/src/timedate/org.freedesktop.timedate1.policy.in @@ -0,0 +1,62 @@ + + + + + + + + The systemd Project + http://www.freedesktop.org/wiki/Software/systemd + + + <_description>Set system time + <_message>Authentication is required to set the system time. + + auth_admin_keep + auth_admin_keep + auth_admin_keep + + org.freedesktop.timedate1.set-timezone org.freedesktop.timedate1.set-ntp + + + + <_description>Set system timezone + <_message>Authentication is required to set the system timezone. + + auth_admin_keep + auth_admin_keep + auth_admin_keep + + + + + <_description>Set RTC to local timezone or UTC + <_message>Authentication is required to control whether + the RTC stores the local or UTC time. + + auth_admin_keep + auth_admin_keep + auth_admin_keep + + + + + <_description>Turn network time synchronization on or off + <_message>Authentication is required to control whether + network time synchronization shall be enabled. + + auth_admin_keep + auth_admin_keep + auth_admin_keep + + + + diff --git a/src/timedate/org.freedesktop.timedate1.service b/src/timedate/org.freedesktop.timedate1.service new file mode 100644 index 000000000..875f4bec7 --- /dev/null +++ b/src/timedate/org.freedesktop.timedate1.service @@ -0,0 +1,12 @@ +# This file is part of systemd. +# +# 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. + +[D-BUS Service] +Name=org.freedesktop.timedate1 +Exec=/bin/false +User=root +SystemdService=dbus-org.freedesktop.timedate1.service diff --git a/src/timedate/timedatectl.c b/src/timedate/timedatectl.c new file mode 100644 index 000000000..281c0524d --- /dev/null +++ b/src/timedate/timedatectl.c @@ -0,0 +1,716 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include + +#include "dbus-common.h" +#include "util.h" +#include "spawn-polkit-agent.h" +#include "build.h" +#include "hwclock.h" +#include "strv.h" +#include "pager.h" +#include "time-dst.h" + +static bool arg_adjust_system_clock = false; +static bool arg_no_pager = false; +static enum transport { + TRANSPORT_NORMAL, + TRANSPORT_SSH, + TRANSPORT_POLKIT +} arg_transport = TRANSPORT_NORMAL; +static bool arg_ask_password = true; +static const char *arg_host = NULL; + +static void pager_open_if_enabled(void) { + + if (arg_no_pager) + return; + + pager_open(); +} + +static void polkit_agent_open_if_enabled(void) { + + /* Open the polkit agent as a child process if necessary */ + + if (!arg_ask_password) + return; + + polkit_agent_open(); +} + +typedef struct StatusInfo { + const char *timezone; + bool local_rtc; + bool ntp; +} StatusInfo; + +static bool ntp_synced(void) { + struct timex txc; + + zero(txc); + if (adjtimex(&txc) < 0) + return false; + + if (txc.status & STA_UNSYNC) + return false; + + return true; +} + +static const char *jump_str(int delta_minutes, char *s, size_t size) { + if (delta_minutes == 60) + return "one hour forward"; + if (delta_minutes == -60) + return "one hour backwards"; + if (delta_minutes < 0) { + snprintf(s, size, "%i minutes backwards", -delta_minutes); + return s; + } + if (delta_minutes > 0) { + snprintf(s, size, "%i minutes forward", delta_minutes); + return s; + } + return ""; +} + +static void print_status_info(StatusInfo *i) { + usec_t n; + char a[FORMAT_TIMESTAMP_MAX]; + char b[FORMAT_TIMESTAMP_MAX]; + char s[32]; + struct tm tm; + time_t sec; + char *zc, *zn; + time_t t, tc, tn; + int dn; + bool is_dstc, is_dstn; + int r; + + assert(i); + + /* enforce the values of /etc/localtime */ + if (getenv("TZ")) { + fprintf(stderr, "Warning: ignoring the TZ variable, reading the system's timezone setting only.\n\n"); + unsetenv("TZ"); + } + + n = now(CLOCK_REALTIME); + sec = (time_t) (n / USEC_PER_SEC); + + zero(tm); + assert_se(strftime(a, sizeof(a), "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&sec, &tm)) > 0); + char_array_0(a); + printf(" Local time: %s\n", a); + + zero(tm); + assert_se(strftime(a, sizeof(a), "%a %Y-%m-%d %H:%M:%S UTC", gmtime_r(&sec, &tm)) > 0); + char_array_0(a); + printf(" Universal time: %s\n", a); + + zero(tm); + r = hwclock_get_time(&tm); + if (r >= 0) { + /* Calculcate the week-day */ + mktime(&tm); + + assert_se(strftime(a, sizeof(a), "%a %Y-%m-%d %H:%M:%S", &tm) > 0); + char_array_0(a); + printf(" RTC time: %s\n", a); + } + + zero(tm); + assert_se(strftime(a, sizeof(a), "%Z, %z", localtime_r(&sec, &tm)) > 0); + char_array_0(a); + printf(" Timezone: %s (%s)\n" + " NTP enabled: %s\n" + "NTP synchronized: %s\n" + " RTC in local TZ: %s\n", + strna(i->timezone), + a, + yes_no(i->ntp), + yes_no(ntp_synced()), + yes_no(i->local_rtc)); + + r = time_get_dst(sec, "/etc/localtime", + &tc, &zc, &is_dstc, + &tn, &dn, &zn, &is_dstn); + if (r < 0) + printf(" DST active: n/a\n"); + else { + printf(" DST active: %s\n", yes_no(is_dstc)); + + t = tc - 1; + zero(tm); + assert_se(strftime(a, sizeof(a), "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&t, &tm)) > 0); + char_array_0(a); + + zero(tm); + assert_se(strftime(b, sizeof(b), "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&tc, &tm)) > 0); + char_array_0(b); + printf(" Last DST change: DST %s at\n" + " %s\n" + " %s\n", + is_dstc ? "began" : "ended", a, b); + + t = tn - 1; + zero(tm); + assert_se(strftime(a, sizeof(a), "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&t, &tm)) > 0); + char_array_0(a); + + zero(tm); + assert_se(strftime(b, sizeof(b), "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&tn, &tm)) > 0); + char_array_0(b); + printf(" Next DST change: DST %s (the clock jumps %s) at\n" + " %s\n" + " %s\n", + is_dstn ? "begins" : "ends", jump_str(dn, s, sizeof(s)), a, b); + + free(zc); + free(zn); + } + + if (i->local_rtc) + fputs("\n" ANSI_HIGHLIGHT_ON + "Warning: The RTC is configured to maintain time in the local time zone. This\n" + " mode is not fully supported and will create various problems with time\n" + " zone changes and daylight saving adjustments. If at all possible use\n" + " RTC in UTC, by calling 'timedatectl set-local-rtc 0'" ANSI_HIGHLIGHT_OFF ".\n", stdout); +} + +static int status_property(const char *name, DBusMessageIter *iter, StatusInfo *i) { + assert(name); + assert(iter); + + switch (dbus_message_iter_get_arg_type(iter)) { + + case DBUS_TYPE_STRING: { + const char *s; + + dbus_message_iter_get_basic(iter, &s); + if (!isempty(s)) { + if (streq(name, "Timezone")) + i->timezone = s; + } + break; + } + + case DBUS_TYPE_BOOLEAN: { + dbus_bool_t b; + + dbus_message_iter_get_basic(iter, &b); + if (streq(name, "LocalRTC")) + i->local_rtc = b; + else if (streq(name, "NTP")) + i->ntp = b; + } + } + + return 0; +} + +static int show_status(DBusConnection *bus, char **args, unsigned n) { + _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; + const char *interface = ""; + int r; + DBusMessageIter iter, sub, sub2, sub3; + StatusInfo info; + + assert(args); + + r = bus_method_call_with_reply( + bus, + "org.freedesktop.timedate1", + "/org/freedesktop/timedate1", + "org.freedesktop.DBus.Properties", + "GetAll", + &reply, + NULL, + DBUS_TYPE_STRING, &interface, + DBUS_TYPE_INVALID); + if (r < 0) + return r; + + if (!dbus_message_iter_init(reply, &iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY || + dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_DICT_ENTRY) { + log_error("Failed to parse reply."); + return -EIO; + } + + zero(info); + dbus_message_iter_recurse(&iter, &sub); + + while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { + const char *name; + + if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_DICT_ENTRY) { + log_error("Failed to parse reply."); + return -EIO; + } + + dbus_message_iter_recurse(&sub, &sub2); + + if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &name, true) < 0) { + log_error("Failed to parse reply."); + return -EIO; + } + + if (dbus_message_iter_get_arg_type(&sub2) != DBUS_TYPE_VARIANT) { + log_error("Failed to parse reply."); + return -EIO; + } + + dbus_message_iter_recurse(&sub2, &sub3); + + r = status_property(name, &sub3, &info); + if (r < 0) { + log_error("Failed to parse reply."); + return r; + } + + dbus_message_iter_next(&sub); + } + + print_status_info(&info); + return 0; +} + +static int set_time(DBusConnection *bus, char **args, unsigned n) { + _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; + dbus_bool_t relative = false, interactive = true; + usec_t t; + dbus_int64_t u; + int r; + + assert(args); + assert(n == 2); + + polkit_agent_open_if_enabled(); + + r = parse_timestamp(args[1], &t); + if (r < 0) { + log_error("Failed to parse time specification: %s", args[1]); + return r; + } + + u = (dbus_uint64_t) t; + + return bus_method_call_with_reply( + bus, + "org.freedesktop.timedate1", + "/org/freedesktop/timedate1", + "org.freedesktop.timedate1", + "SetTime", + &reply, + NULL, + DBUS_TYPE_INT64, &u, + DBUS_TYPE_BOOLEAN, &relative, + DBUS_TYPE_BOOLEAN, &interactive, + DBUS_TYPE_INVALID); +} + +static int set_timezone(DBusConnection *bus, char **args, unsigned n) { + _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; + dbus_bool_t interactive = true; + + assert(args); + assert(n == 2); + + polkit_agent_open_if_enabled(); + + return bus_method_call_with_reply( + bus, + "org.freedesktop.timedate1", + "/org/freedesktop/timedate1", + "org.freedesktop.timedate1", + "SetTimezone", + &reply, + NULL, + DBUS_TYPE_STRING, &args[1], + DBUS_TYPE_BOOLEAN, &interactive, + DBUS_TYPE_INVALID); +} + +static int set_local_rtc(DBusConnection *bus, char **args, unsigned n) { + _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; + dbus_bool_t interactive = true, b, q; + int r; + + assert(args); + assert(n == 2); + + polkit_agent_open_if_enabled(); + + r = parse_boolean(args[1]); + if (r < 0) { + log_error("Failed to parse local RTC setting: %s", args[1]); + return r; + } + + b = r; + q = arg_adjust_system_clock; + + return bus_method_call_with_reply( + bus, + "org.freedesktop.timedate1", + "/org/freedesktop/timedate1", + "org.freedesktop.timedate1", + "SetLocalRTC", + &reply, + NULL, + DBUS_TYPE_BOOLEAN, &b, + DBUS_TYPE_BOOLEAN, &q, + DBUS_TYPE_BOOLEAN, &interactive, + DBUS_TYPE_INVALID); +} + +static int set_ntp(DBusConnection *bus, char **args, unsigned n) { + _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; + dbus_bool_t interactive = true, b; + int r; + + assert(args); + assert(n == 2); + + polkit_agent_open_if_enabled(); + + r = parse_boolean(args[1]); + if (r < 0) { + log_error("Failed to parse NTP setting: %s", args[1]); + return r; + } + + b = r; + + return bus_method_call_with_reply( + bus, + "org.freedesktop.timedate1", + "/org/freedesktop/timedate1", + "org.freedesktop.timedate1", + "SetNTP", + &reply, + NULL, + DBUS_TYPE_BOOLEAN, &b, + DBUS_TYPE_BOOLEAN, &interactive, + DBUS_TYPE_INVALID); +} + +static int list_timezones(DBusConnection *bus, char **args, unsigned n) { + _cleanup_fclose_ FILE *f = NULL; + _cleanup_strv_free_ char **zones = NULL; + size_t n_zones = 0; + char **i; + + assert(args); + assert(n == 1); + + f = fopen("/usr/share/zoneinfo/zone.tab", "re"); + if (!f) { + log_error("Failed to open timezone database: %m"); + return -errno; + } + + for (;;) { + char l[LINE_MAX], *p, **z, *w; + size_t k; + + if (!fgets(l, sizeof(l), f)) { + if (feof(f)) + break; + + log_error("Failed to read timezone database: %m"); + return -errno; + } + + p = strstrip(l); + + if (isempty(p) || *p == '#') + continue; + + + /* Skip over country code */ + p += strcspn(p, WHITESPACE); + p += strspn(p, WHITESPACE); + + /* Skip over coordinates */ + p += strcspn(p, WHITESPACE); + p += strspn(p, WHITESPACE); + + /* Found timezone name */ + k = strcspn(p, WHITESPACE); + if (k <= 0) + continue; + + w = strndup(p, k); + if (!w) + return log_oom(); + + z = realloc(zones, sizeof(char*) * (n_zones + 2)); + if (!z) { + free(w); + return log_oom(); + } + + zones = z; + zones[n_zones++] = w; + } + + if (zones) + zones[n_zones] = NULL; + + pager_open_if_enabled(); + + strv_sort(zones); + STRV_FOREACH(i, zones) + puts(*i); + + return 0; +} + +static int help(void) { + + printf("%s [OPTIONS...] COMMAND ...\n\n" + "Query or change system time and date settings.\n\n" + " -h --help Show this help\n" + " --version Show package version\n" + " --adjust-system-clock\n" + " Adjust system clock when changing local RTC mode\n" + " --no-pager Do not pipe output into a pager\n" + " --no-ask-password Do not prompt for password\n" + " -H --host=[USER@]HOST Operate on remote host\n\n" + "Commands:\n" + " status Show current time settings\n" + " set-time TIME Set system time\n" + " set-timezone ZONE Set system timezone\n" + " list-timezones Show known timezones\n" + " set-local-rtc BOOL Control whether RTC is in local time\n" + " set-ntp BOOL Control whether NTP is enabled\n", + program_invocation_short_name); + + return 0; +} + +static int parse_argv(int argc, char *argv[]) { + + enum { + ARG_VERSION = 0x100, + ARG_NO_PAGER, + ARG_ADJUST_SYSTEM_CLOCK, + ARG_NO_ASK_PASSWORD + }; + + static const struct option options[] = { + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, ARG_VERSION }, + { "no-pager", no_argument, NULL, ARG_NO_PAGER }, + { "host", required_argument, NULL, 'H' }, + { "privileged", no_argument, NULL, 'P' }, + { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD }, + { "adjust-system-clock", no_argument, NULL, ARG_ADJUST_SYSTEM_CLOCK }, + { NULL, 0, NULL, 0 } + }; + + int c; + + assert(argc >= 0); + assert(argv); + + while ((c = getopt_long(argc, argv, "+hH:P", options, NULL)) >= 0) { + + switch (c) { + + case 'h': + help(); + return 0; + + case ARG_VERSION: + puts(PACKAGE_STRING); + puts(SYSTEMD_FEATURES); + return 0; + + case 'P': + arg_transport = TRANSPORT_POLKIT; + break; + + case 'H': + arg_transport = TRANSPORT_SSH; + arg_host = optarg; + break; + + case ARG_ADJUST_SYSTEM_CLOCK: + arg_adjust_system_clock = true; + break; + + case ARG_NO_PAGER: + arg_no_pager = true; + break; + + case '?': + return -EINVAL; + + default: + log_error("Unknown option code %c", c); + return -EINVAL; + } + } + + return 1; +} + +static int timedatectl_main(DBusConnection *bus, int argc, char *argv[], DBusError *error) { + + static const struct { + const char* verb; + const enum { + MORE, + LESS, + EQUAL + } argc_cmp; + const int argc; + int (* const dispatch)(DBusConnection *bus, char **args, unsigned n); + } verbs[] = { + { "status", LESS, 1, show_status }, + { "set-time", EQUAL, 2, set_time }, + { "set-timezone", EQUAL, 2, set_timezone }, + { "list-timezones", EQUAL, 1, list_timezones }, + { "set-local-rtc", EQUAL, 2, set_local_rtc }, + { "set-ntp", EQUAL, 2, set_ntp, }, + }; + + int left; + unsigned i; + + assert(argc >= 0); + assert(argv); + assert(error); + + left = argc - optind; + + if (left <= 0) + /* Special rule: no arguments means "status" */ + i = 0; + else { + if (streq(argv[optind], "help")) { + help(); + return 0; + } + + for (i = 0; i < ELEMENTSOF(verbs); i++) + if (streq(argv[optind], verbs[i].verb)) + break; + + if (i >= ELEMENTSOF(verbs)) { + log_error("Unknown operation %s", argv[optind]); + return -EINVAL; + } + } + + switch (verbs[i].argc_cmp) { + + case EQUAL: + if (left != verbs[i].argc) { + log_error("Invalid number of arguments."); + return -EINVAL; + } + + break; + + case MORE: + if (left < verbs[i].argc) { + log_error("Too few arguments."); + return -EINVAL; + } + + break; + + case LESS: + if (left > verbs[i].argc) { + log_error("Too many arguments."); + return -EINVAL; + } + + break; + + default: + assert_not_reached("Unknown comparison operator."); + } + + if (!bus) { + log_error("Failed to get D-Bus connection: %s", error->message); + return -EIO; + } + + return verbs[i].dispatch(bus, argv + optind, left); +} + +int main(int argc, char *argv[]) { + int r, retval = EXIT_FAILURE; + DBusConnection *bus = NULL; + DBusError error; + + dbus_error_init(&error); + + setlocale(LC_ALL, ""); + log_parse_environment(); + log_open(); + + r = parse_argv(argc, argv); + if (r < 0) + goto finish; + else if (r == 0) { + retval = EXIT_SUCCESS; + goto finish; + } + + if (arg_transport == TRANSPORT_NORMAL) + bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error); + else if (arg_transport == TRANSPORT_POLKIT) + bus_connect_system_polkit(&bus, &error); + else if (arg_transport == TRANSPORT_SSH) + bus_connect_system_ssh(NULL, arg_host, &bus, &error); + else + assert_not_reached("Uh, invalid transport..."); + + r = timedatectl_main(bus, argc, argv, &error); + retval = r < 0 ? EXIT_FAILURE : r; + +finish: + if (bus) { + dbus_connection_flush(bus); + dbus_connection_close(bus); + dbus_connection_unref(bus); + } + + dbus_error_free(&error); + dbus_shutdown(); + + pager_close(); + + return retval; +} diff --git a/src/timedate/timedated.c b/src/timedate/timedated.c new file mode 100644 index 000000000..fdb433546 --- /dev/null +++ b/src/timedate/timedated.c @@ -0,0 +1,1025 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +#include + +#include +#include +#include + +#include "systemd/sd-id128.h" +#include "systemd/sd-messages.h" +#include "util.h" +#include "strv.h" +#include "dbus-common.h" +#include "polkit.h" +#include "def.h" +#include "hwclock.h" +#include "conf-files.h" +#include "path-util.h" + +#define NULL_ADJTIME_UTC "0.0 0 0\n0\nUTC\n" +#define NULL_ADJTIME_LOCAL "0.0 0 0\n0\nLOCAL\n" + +#define INTERFACE \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" + +#define INTROSPECTION \ + DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \ + "\n" \ + INTERFACE \ + BUS_PROPERTIES_INTERFACE \ + BUS_INTROSPECTABLE_INTERFACE \ + BUS_PEER_INTERFACE \ + "\n" + +#define INTERFACES_LIST \ + BUS_GENERIC_INTERFACES_LIST \ + "org.freedesktop.timedate1\0" + +const char timedate_interface[] _introspect_("timedate1") = INTERFACE; + +typedef struct TZ { + char *zone; + bool local_rtc; + int use_ntp; +} TZ; + +static TZ tz = { + .use_ntp = -1, +}; + +static usec_t remain_until; + +static void free_data(void) { + free(tz.zone); + tz.zone = NULL; + + tz.local_rtc = false; +} + +static bool valid_timezone(const char *name) { + const char *p; + char *t; + bool slash = false; + int r; + struct stat st; + + assert(name); + + if (*name == '/' || *name == 0) + return false; + + for (p = name; *p; p++) { + if (!(*p >= '0' && *p <= '9') && + !(*p >= 'a' && *p <= 'z') && + !(*p >= 'A' && *p <= 'Z') && + !(*p == '-' || *p == '_' || *p == '+' || *p == '/')) + return false; + + if (*p == '/') { + + if (slash) + return false; + + slash = true; + } else + slash = false; + } + + if (slash) + return false; + + t = strappend("/usr/share/zoneinfo/", name); + if (!t) + return false; + + r = stat(t, &st); + free(t); + + if (r < 0) + return false; + + if (!S_ISREG(st.st_mode)) + return false; + + return true; +} + +static int read_data(void) { + int r; + _cleanup_free_ char *t = NULL; + + free_data(); + + r = readlink_malloc("/etc/localtime", &t); + if (r < 0) { + if (r == -EINVAL) + log_warning("/etc/localtime should be a symbolic link to a timezone data file in /usr/share/zoneinfo/."); + else + log_warning("Failed to get target of /etc/localtime: %s", strerror(-r)); + } else { + const char *e; + + e = path_startswith(t, "/usr/share/zoneinfo/"); + if (!e) + e = path_startswith(t, "../usr/share/zoneinfo/"); + + if (!e) + log_warning("/etc/localtime should be a symbolic link to a timezone data file in /usr/share/zoneinfo/."); + else { + tz.zone = strdup(e); + if (!tz.zone) + return log_oom(); + + goto have_timezone; + } + } + +#ifdef HAVE_DEBIAN + r = read_one_line_file("/etc/timezone", &tz.zone); + if (r < 0) { + if (r != -ENOENT) + log_warning("Failed to read /etc/timezone: %s", strerror(-r)); + } +#endif + +have_timezone: + if (isempty(tz.zone)) { + free(tz.zone); + tz.zone = NULL; + } + + tz.local_rtc = hwclock_is_localtime() > 0; + + return 0; +} + +static int write_data_timezone(void) { + int r = 0; + _cleanup_free_ char *p = NULL; + + if (!tz.zone) { + if (unlink("/etc/localtime") < 0 && errno != ENOENT) + r = -errno; + + return r; + } + + p = strappend("../usr/share/zoneinfo/", tz.zone); + if (!p) + return log_oom(); + + r = symlink_atomic(p, "/etc/localtime"); + if (r < 0) + return r; + + return 0; +} + +static int write_data_local_rtc(void) { + int r; + char *s, *w; + + r = read_full_file("/etc/adjtime", &s, NULL); + if (r < 0) { + if (r != -ENOENT) + return r; + + if (!tz.local_rtc) + return 0; + + w = strdup(NULL_ADJTIME_LOCAL); + if (!w) + return -ENOMEM; + } else { + char *p, *e; + size_t a, b; + + p = strchr(s, '\n'); + if (!p) { + free(s); + return -EIO; + } + + p = strchr(p+1, '\n'); + if (!p) { + free(s); + return -EIO; + } + + p++; + e = strchr(p, '\n'); + if (!e) { + free(s); + return -EIO; + } + + a = p - s; + b = strlen(e); + + w = new(char, a + (tz.local_rtc ? 5 : 3) + b + 1); + if (!w) { + free(s); + return -ENOMEM; + } + + *(char*) mempcpy(stpcpy(mempcpy(w, s, a), tz.local_rtc ? "LOCAL" : "UTC"), e, b) = 0; + + if (streq(w, NULL_ADJTIME_UTC)) { + free(w); + + if (unlink("/etc/adjtime") < 0) { + if (errno != ENOENT) + return -errno; + } + + return 0; + } + } + + r = write_one_line_file_atomic("/etc/adjtime", w); + free(w); + + return r; +} + +static char** get_ntp_services(void) { + char **r = NULL, **files, **i; + int k; + + k = conf_files_list(&files, ".list", + "/etc/systemd/ntp-units.d", + "/run/systemd/ntp-units.d", + "/usr/local/lib/systemd/ntp-units.d", + "/usr/lib/systemd/ntp-units.d", + NULL); + if (k < 0) + return NULL; + + STRV_FOREACH(i, files) { + FILE *f; + + f = fopen(*i, "re"); + if (!f) + continue; + + for (;;) { + char line[PATH_MAX], *l, **q; + + if (!fgets(line, sizeof(line), f)) { + + if (ferror(f)) + log_error("Failed to read NTP units file: %m"); + + break; + } + + l = strstrip(line); + if (l[0] == 0 || l[0] == '#') + continue; + + q = strv_append(r, l); + if (!q) { + log_oom(); + break; + } + + strv_free(r); + r = q; + } + + fclose(f); + } + + strv_free(files); + + return strv_uniq(r); +} + +static int read_ntp(DBusConnection *bus) { + DBusMessage *m = NULL, *reply = NULL; + DBusError error; + int r; + char **i, **l; + + assert(bus); + + dbus_error_init(&error); + + l = get_ntp_services(); + STRV_FOREACH(i, l) { + const char *s; + + if (m) + dbus_message_unref(m); + m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "GetUnitFileState"); + if (!m) { + r = log_oom(); + goto finish; + } + + if (!dbus_message_append_args(m, + DBUS_TYPE_STRING, i, + DBUS_TYPE_INVALID)) { + r = log_oom(); + goto finish; + } + + if (reply) + dbus_message_unref(reply); + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error); + if (!reply) { + if (streq(error.name, "org.freedesktop.DBus.Error.FileNotFound")) { + /* This implementation does not exist, try next one */ + dbus_error_free(&error); + continue; + } + + log_error("Failed to issue method call: %s", bus_error_message(&error)); + r = -EIO; + goto finish; + } + + if (!dbus_message_get_args(reply, &error, + DBUS_TYPE_STRING, &s, + DBUS_TYPE_INVALID)) { + log_error("Failed to parse reply: %s", bus_error_message(&error)); + r = -EIO; + goto finish; + } + + tz.use_ntp = + streq(s, "enabled") || + streq(s, "enabled-runtime"); + r = 0; + goto finish; + } + + /* NTP is not installed. */ + tz.use_ntp = 0; + r = 0; + +finish: + if (m) + dbus_message_unref(m); + + if (reply) + dbus_message_unref(reply); + + strv_free(l); + + dbus_error_free(&error); + + return r; +} + +static int start_ntp(DBusConnection *bus, DBusError *error) { + DBusMessage *m = NULL, *reply = NULL; + const char *mode = "replace"; + char **i, **l; + int r; + + assert(bus); + assert(error); + + l = get_ntp_services(); + STRV_FOREACH(i, l) { + if (m) + dbus_message_unref(m); + m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + tz.use_ntp ? "StartUnit" : "StopUnit"); + if (!m) { + log_error("Could not allocate message."); + r = -ENOMEM; + goto finish; + } + + if (!dbus_message_append_args(m, + DBUS_TYPE_STRING, i, + DBUS_TYPE_STRING, &mode, + DBUS_TYPE_INVALID)) { + log_error("Could not append arguments to message."); + r = -ENOMEM; + goto finish; + } + + if (reply) + dbus_message_unref(reply); + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, error); + if (!reply) { + if (streq(error->name, "org.freedesktop.DBus.Error.FileNotFound") || + streq(error->name, "org.freedesktop.systemd1.LoadFailed") || + streq(error->name, "org.freedesktop.systemd1.NoSuchUnit")) { + /* This implementation does not exist, try next one */ + dbus_error_free(error); + continue; + } + + log_error("Failed to issue method call: %s", bus_error_message(error)); + r = -EIO; + goto finish; + } + + r = 0; + goto finish; + } + + /* No implementaiton available... */ + r = -ENOENT; + +finish: + if (m) + dbus_message_unref(m); + + if (reply) + dbus_message_unref(reply); + + strv_free(l); + + return r; +} + +static int enable_ntp(DBusConnection *bus, DBusError *error) { + DBusMessage *m = NULL, *reply = NULL; + int r; + DBusMessageIter iter; + dbus_bool_t f = FALSE, t = TRUE; + char **i, **l; + + assert(bus); + assert(error); + + l = get_ntp_services(); + STRV_FOREACH(i, l) { + char* k[2]; + + if (m) + dbus_message_unref(m); + m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + tz.use_ntp ? "EnableUnitFiles" : "DisableUnitFiles"); + if (!m) { + log_error("Could not allocate message."); + r = -ENOMEM; + goto finish; + } + + dbus_message_iter_init_append(m, &iter); + + k[0] = *i; + k[1] = NULL; + + r = bus_append_strv_iter(&iter, k); + if (r < 0) { + log_error("Failed to append unit files."); + goto finish; + } + + /* send runtime bool */ + if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &f)) { + log_error("Failed to append runtime boolean."); + r = -ENOMEM; + goto finish; + } + + if (tz.use_ntp) { + /* send force bool */ + if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &t)) { + log_error("Failed to append force boolean."); + r = -ENOMEM; + goto finish; + } + } + + if (reply) + dbus_message_unref(reply); + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, error); + if (!reply) { + if (streq(error->name, "org.freedesktop.DBus.Error.FileNotFound")) { + /* This implementation does not exist, try next one */ + dbus_error_free(error); + continue; + } + + log_error("Failed to issue method call: %s", bus_error_message(error)); + r = -EIO; + goto finish; + } + + dbus_message_unref(m); + m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "Reload"); + if (!m) { + log_error("Could not allocate message."); + r = -ENOMEM; + goto finish; + } + + dbus_message_unref(reply); + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, error); + if (!reply) { + log_error("Failed to issue method call: %s", bus_error_message(error)); + r = -EIO; + goto finish; + } + + r = 0; + goto finish; + } + + r = -ENOENT; + +finish: + if (m) + dbus_message_unref(m); + + if (reply) + dbus_message_unref(reply); + + strv_free(l); + + return r; +} + +static int property_append_ntp(DBusMessageIter *i, const char *property, void *data) { + dbus_bool_t db; + + assert(i); + assert(property); + + db = tz.use_ntp > 0; + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &db)) + return -ENOMEM; + + return 0; +} + +static const BusProperty bus_timedate_properties[] = { + { "Timezone", bus_property_append_string, "s", offsetof(TZ, zone), true }, + { "LocalRTC", bus_property_append_bool, "b", offsetof(TZ, local_rtc) }, + { "NTP", property_append_ntp, "b", offsetof(TZ, use_ntp) }, + { NULL, } +}; + +static const BusBoundProperties bps[] = { + { "org.freedesktop.timedate1", bus_timedate_properties, &tz }, + { NULL, } +}; + +static DBusHandlerResult timedate_message_handler( + DBusConnection *connection, + DBusMessage *message, + void *userdata) { + + DBusMessage *reply = NULL, *changed = NULL; + DBusError error; + int r; + + assert(connection); + assert(message); + + dbus_error_init(&error); + + if (dbus_message_is_method_call(message, "org.freedesktop.timedate1", "SetTimezone")) { + const char *z; + dbus_bool_t interactive; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &z, + DBUS_TYPE_BOOLEAN, &interactive, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + if (!valid_timezone(z)) + return bus_send_error_reply(connection, message, NULL, -EINVAL); + + if (!streq_ptr(z, tz.zone)) { + char *t; + + r = verify_polkit(connection, message, "org.freedesktop.timedate1.set-timezone", interactive, NULL, &error); + if (r < 0) + return bus_send_error_reply(connection, message, &error, r); + + t = strdup(z); + if (!t) + goto oom; + + free(tz.zone); + tz.zone = t; + + /* 1. Write new configuration file */ + r = write_data_timezone(); + if (r < 0) { + log_error("Failed to set timezone: %s", strerror(-r)); + return bus_send_error_reply(connection, message, NULL, r); + } + + /* 2. Tell the kernel our time zone */ + hwclock_set_timezone(NULL); + + if (tz.local_rtc) { + struct timespec ts; + struct tm *tm; + + /* 3. Sync RTC from system clock, with the new delta */ + assert_se(clock_gettime(CLOCK_REALTIME, &ts) == 0); + assert_se(tm = localtime(&ts.tv_sec)); + hwclock_set_time(tm); + } + + log_struct(LOG_INFO, + MESSAGE_ID(SD_MESSAGE_TIMEZONE_CHANGE), + "TIMEZONE=%s", tz.zone, + "MESSAGE=Changed timezone to '%s'.", tz.zone, + NULL); + + changed = bus_properties_changed_new( + "/org/freedesktop/timedate1", + "org.freedesktop.timedate1", + "Timezone\0"); + if (!changed) + goto oom; + } + + } else if (dbus_message_is_method_call(message, "org.freedesktop.timedate1", "SetLocalRTC")) { + dbus_bool_t lrtc; + dbus_bool_t fix_system; + dbus_bool_t interactive; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_BOOLEAN, &lrtc, + DBUS_TYPE_BOOLEAN, &fix_system, + DBUS_TYPE_BOOLEAN, &interactive, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + if (lrtc != tz.local_rtc) { + struct timespec ts; + + r = verify_polkit(connection, message, "org.freedesktop.timedate1.set-local-rtc", interactive, NULL, &error); + if (r < 0) + return bus_send_error_reply(connection, message, &error, r); + + tz.local_rtc = lrtc; + + /* 1. Write new configuration file */ + r = write_data_local_rtc(); + if (r < 0) { + log_error("Failed to set RTC to local/UTC: %s", strerror(-r)); + return bus_send_error_reply(connection, message, NULL, r); + } + + /* 2. Tell the kernel our time zone */ + hwclock_set_timezone(NULL); + + /* 3. Synchronize clocks */ + assert_se(clock_gettime(CLOCK_REALTIME, &ts) == 0); + + if (fix_system) { + struct tm tm; + + /* Sync system clock from RTC; first, + * initialize the timezone fields of + * struct tm. */ + if (tz.local_rtc) + tm = *localtime(&ts.tv_sec); + else + tm = *gmtime(&ts.tv_sec); + + /* Override the main fields of + * struct tm, but not the timezone + * fields */ + if (hwclock_get_time(&tm) >= 0) { + + /* And set the system clock + * with this */ + if (tz.local_rtc) + ts.tv_sec = mktime(&tm); + else + ts.tv_sec = timegm(&tm); + + clock_settime(CLOCK_REALTIME, &ts); + } + + } else { + struct tm *tm; + + /* Sync RTC from system clock */ + if (tz.local_rtc) + tm = localtime(&ts.tv_sec); + else + tm = gmtime(&ts.tv_sec); + + hwclock_set_time(tm); + } + + log_info("RTC configured to %s time.", tz.local_rtc ? "local" : "UTC"); + + changed = bus_properties_changed_new( + "/org/freedesktop/timedate1", + "org.freedesktop.timedate1", + "LocalRTC\0"); + if (!changed) + goto oom; + } + + } else if (dbus_message_is_method_call(message, "org.freedesktop.timedate1", "SetTime")) { + int64_t utc; + dbus_bool_t relative; + dbus_bool_t interactive; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_INT64, &utc, + DBUS_TYPE_BOOLEAN, &relative, + DBUS_TYPE_BOOLEAN, &interactive, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + if (!relative && utc <= 0) + return bus_send_error_reply(connection, message, NULL, -EINVAL); + + if (!relative || utc != 0) { + struct timespec ts; + struct tm* tm; + + r = verify_polkit(connection, message, "org.freedesktop.timedate1.set-time", interactive, NULL, &error); + if (r < 0) + return bus_send_error_reply(connection, message, &error, r); + + if (relative) + timespec_store(&ts, now(CLOCK_REALTIME) + utc); + else + timespec_store(&ts, utc); + + /* Set system clock */ + if (clock_settime(CLOCK_REALTIME, &ts) < 0) { + log_error("Failed to set local time: %m"); + return bus_send_error_reply(connection, message, NULL, -errno); + } + + /* Sync down to RTC */ + if (tz.local_rtc) + tm = localtime(&ts.tv_sec); + else + tm = gmtime(&ts.tv_sec); + + hwclock_set_time(tm); + + log_struct(LOG_INFO, + MESSAGE_ID(SD_MESSAGE_TIME_CHANGE), + "REALTIME=%llu", (unsigned long long) timespec_load(&ts), + "MESSAGE=Changed local time to %s", ctime(&ts.tv_sec), + NULL); + } + } else if (dbus_message_is_method_call(message, "org.freedesktop.timedate1", "SetNTP")) { + dbus_bool_t ntp; + dbus_bool_t interactive; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_BOOLEAN, &ntp, + DBUS_TYPE_BOOLEAN, &interactive, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + if (ntp != !!tz.use_ntp) { + + r = verify_polkit(connection, message, "org.freedesktop.timedate1.set-ntp", interactive, NULL, &error); + if (r < 0) + return bus_send_error_reply(connection, message, &error, r); + + tz.use_ntp = !!ntp; + + r = enable_ntp(connection, &error); + if (r < 0) + return bus_send_error_reply(connection, message, &error, r); + + r = start_ntp(connection, &error); + if (r < 0) + return bus_send_error_reply(connection, message, &error, r); + + log_info("Set NTP to %s", tz.use_ntp ? "enabled" : "disabled"); + + changed = bus_properties_changed_new( + "/org/freedesktop/timedate1", + "org.freedesktop.timedate1", + "NTP\0"); + if (!changed) + goto oom; + } + + } else + return bus_default_message_handler(connection, message, INTROSPECTION, INTERFACES_LIST, bps); + + if (!(reply = dbus_message_new_method_return(message))) + goto oom; + + if (!dbus_connection_send(connection, reply, NULL)) + goto oom; + + dbus_message_unref(reply); + reply = NULL; + + if (changed) { + + if (!dbus_connection_send(connection, changed, NULL)) + goto oom; + + dbus_message_unref(changed); + } + + return DBUS_HANDLER_RESULT_HANDLED; + +oom: + if (reply) + dbus_message_unref(reply); + + if (changed) + dbus_message_unref(changed); + + dbus_error_free(&error); + + return DBUS_HANDLER_RESULT_NEED_MEMORY; +} + +static int connect_bus(DBusConnection **_bus) { + static const DBusObjectPathVTable timedate_vtable = { + .message_function = timedate_message_handler + }; + DBusError error; + DBusConnection *bus = NULL; + int r; + + assert(_bus); + + dbus_error_init(&error); + + bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error); + if (!bus) { + log_error("Failed to get system D-Bus connection: %s", bus_error_message(&error)); + r = -ECONNREFUSED; + goto fail2; + } + + dbus_connection_set_exit_on_disconnect(bus, FALSE); + + if (!dbus_connection_register_object_path(bus, "/org/freedesktop/timedate1", &timedate_vtable, NULL) || + !dbus_connection_add_filter(bus, bus_exit_idle_filter, &remain_until, NULL)) { + r = log_oom(); + goto fail; + } + + r = dbus_bus_request_name(bus, "org.freedesktop.timedate1", DBUS_NAME_FLAG_DO_NOT_QUEUE, &error); + if (dbus_error_is_set(&error)) { + log_error("Failed to register name on bus: %s", bus_error_message(&error)); + r = -EEXIST; + goto fail; + } + + if (r != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) { + log_error("Failed to acquire name."); + r = -EEXIST; + goto fail; + } + + if (_bus) + *_bus = bus; + + return 0; + +fail: + dbus_connection_close(bus); + dbus_connection_unref(bus); +fail2: + dbus_error_free(&error); + + return r; +} + +int main(int argc, char *argv[]) { + int r; + DBusConnection *bus = NULL; + bool exiting = false; + + log_set_target(LOG_TARGET_AUTO); + log_parse_environment(); + log_open(); + + umask(0022); + + if (argc == 2 && streq(argv[1], "--introspect")) { + fputs(DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE + "\n", stdout); + fputs(timedate_interface, stdout); + fputs("\n", stdout); + return 0; + } + + if (argc != 1) { + log_error("This program takes no arguments."); + r = -EINVAL; + goto finish; + } + + r = read_data(); + if (r < 0) { + log_error("Failed to read timezone data: %s", strerror(-r)); + goto finish; + } + + r = connect_bus(&bus); + if (r < 0) + goto finish; + + r = read_ntp(bus); + if (r < 0) { + log_error("Failed to determine whether NTP is enabled: %s", strerror(-r)); + goto finish; + } + + remain_until = now(CLOCK_MONOTONIC) + DEFAULT_EXIT_USEC; + for (;;) { + + if (!dbus_connection_read_write_dispatch(bus, exiting ? -1 : (int) (DEFAULT_EXIT_USEC/USEC_PER_MSEC))) + break; + + if (!exiting && remain_until < now(CLOCK_MONOTONIC)) { + exiting = true; + bus_async_unregister_and_exit(bus, "org.freedesktop.timedated1"); + } + } + + r = 0; + +finish: + free_data(); + + if (bus) { + dbus_connection_flush(bus); + dbus_connection_close(bus); + dbus_connection_unref(bus); + } + + return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/src/timestamp/Makefile b/src/timestamp/Makefile new file mode 120000 index 000000000..d0b0e8e00 --- /dev/null +++ b/src/timestamp/Makefile @@ -0,0 +1 @@ +../Makefile \ No newline at end of file diff --git a/src/timestamp/timestamp.c b/src/timestamp/timestamp.c new file mode 100644 index 000000000..1152f1b52 --- /dev/null +++ b/src/timestamp/timestamp.c @@ -0,0 +1,39 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include + +#include "util.h" + +int main(int argc, char *argv[]) { + struct dual_timestamp t; + + /* This is mostly useful for stuff like init ram disk scripts + * which want to take a proper timestamp to do minimal bootup + * profiling. */ + + dual_timestamp_get(&t); + printf("%llu %llu\n", + (unsigned long long) t.realtime, + (unsigned long long) t.monotonic); + + return 0; +} diff --git a/src/tmpfiles/Makefile b/src/tmpfiles/Makefile new file mode 120000 index 000000000..d0b0e8e00 --- /dev/null +++ b/src/tmpfiles/Makefile @@ -0,0 +1 @@ +../Makefile \ No newline at end of file diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c new file mode 100644 index 000000000..d8fb07e59 --- /dev/null +++ b/src/tmpfiles/tmpfiles.c @@ -0,0 +1,1420 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering, Kay Sievers + + 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "log.h" +#include "util.h" +#include "macro.h" +#include "mkdir.h" +#include "path-util.h" +#include "strv.h" +#include "label.h" +#include "set.h" +#include "conf-files.h" +#include "capability.h" + +/* This reads all files listed in /etc/tmpfiles.d/?*.conf and creates + * them in the file system. This is intended to be used to create + * properly owned directories beneath /tmp, /var/tmp, /run, which are + * volatile and hence need to be recreated on bootup. */ + +typedef enum ItemType { + /* These ones take file names */ + CREATE_FILE = 'f', + TRUNCATE_FILE = 'F', + WRITE_FILE = 'w', + CREATE_DIRECTORY = 'd', + TRUNCATE_DIRECTORY = 'D', + CREATE_FIFO = 'p', + CREATE_SYMLINK = 'L', + CREATE_CHAR_DEVICE = 'c', + CREATE_BLOCK_DEVICE = 'b', + + /* These ones take globs */ + IGNORE_PATH = 'x', + REMOVE_PATH = 'r', + RECURSIVE_REMOVE_PATH = 'R', + RELABEL_PATH = 'z', + RECURSIVE_RELABEL_PATH = 'Z' +} ItemType; + +typedef struct Item { + ItemType type; + + char *path; + char *argument; + uid_t uid; + gid_t gid; + mode_t mode; + usec_t age; + + dev_t major_minor; + + bool uid_set:1; + bool gid_set:1; + bool mode_set:1; + bool age_set:1; + + bool keep_first_level:1; +} Item; + +static Hashmap *items = NULL, *globs = NULL; +static Set *unix_sockets = NULL; + +static bool arg_create = false; +static bool arg_clean = false; +static bool arg_remove = false; + +static const char *arg_prefix = NULL; + +static const char * const conf_file_dirs[] = { + "/etc/tmpfiles.d", + "/run/tmpfiles.d", + "/usr/local/lib/tmpfiles.d", + "/usr/lib/tmpfiles.d", +#ifdef HAVE_SPLIT_USR + "/lib/tmpfiles.d", +#endif + NULL +}; + +#define MAX_DEPTH 256 + +static bool needs_glob(ItemType t) { + return t == IGNORE_PATH || t == REMOVE_PATH || t == RECURSIVE_REMOVE_PATH || t == RELABEL_PATH || t == RECURSIVE_RELABEL_PATH; +} + +static struct Item* find_glob(Hashmap *h, const char *match) { + Item *j; + Iterator i; + + HASHMAP_FOREACH(j, h, i) + if (fnmatch(j->path, match, FNM_PATHNAME|FNM_PERIOD) == 0) + return j; + + return NULL; +} + +static void load_unix_sockets(void) { + FILE *f = NULL; + char line[LINE_MAX]; + + if (unix_sockets) + return; + + /* 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_func, string_compare_func); + if (!unix_sockets) + return; + + f = fopen("/proc/net/unix", "re"); + if (!f) + return; + + /* Skip header */ + if (!fgets(line, sizeof(line), f)) + goto fail; + + for (;;) { + char *p, *s; + int k; + + if (!fgets(line, sizeof(line), f)) + break; + + truncate_nl(line); + + p = strchr(line, ':'); + if (!p) + continue; + + if (strlen(p) < 37) + continue; + + p += 37; + p += strspn(p, WHITESPACE); + p += strcspn(p, WHITESPACE); /* skip one more word */ + p += strspn(p, WHITESPACE); + + if (*p != '/') + continue; + + s = strdup(p); + if (!s) + goto fail; + + path_kill_slashes(s); + + k = set_put(unix_sockets, s); + if (k < 0) { + free(s); + + if (k != -EEXIST) + goto fail; + } + } + + fclose(f); + return; + +fail: + set_free_free(unix_sockets); + unix_sockets = NULL; + + if (f) + fclose(f); +} + +static bool unix_socket_alive(const char *fn) { + assert(fn); + + load_unix_sockets(); + + if (unix_sockets) + return !!set_get(unix_sockets, (char*) fn); + + /* We don't know, so assume yes */ + return true; +} + +static int dir_cleanup( + const char *p, + DIR *d, + const struct stat *ds, + usec_t cutoff, + dev_t rootdev, + bool mountpoint, + int maxdepth, + bool keep_this_level) +{ + struct dirent *dent; + struct timespec times[2]; + bool deleted = false; + char *sub_path = NULL; + int r = 0; + + while ((dent = readdir(d))) { + struct stat s; + usec_t age; + + if (streq(dent->d_name, ".") || + streq(dent->d_name, "..")) + continue; + + if (fstatat(dirfd(d), dent->d_name, &s, AT_SYMLINK_NOFOLLOW) < 0) { + + if (errno != ENOENT) { + log_error("stat(%s/%s) failed: %m", p, dent->d_name); + r = -errno; + } + + continue; + } + + /* Stay on the same filesystem */ + if (s.st_dev != rootdev) + continue; + + /* Do not delete read-only files owned by root */ + if (s.st_uid == 0 && !(s.st_mode & S_IWUSR)) + continue; + + free(sub_path); + sub_path = NULL; + + if (asprintf(&sub_path, "%s/%s", p, dent->d_name) < 0) { + r = log_oom(); + goto finish; + } + + /* Is there an item configured for this path? */ + if (hashmap_get(items, sub_path)) + continue; + + if (find_glob(globs, sub_path)) + continue; + + if (S_ISDIR(s.st_mode)) { + + if (mountpoint && + streq(dent->d_name, "lost+found") && + s.st_uid == 0) + continue; + + if (maxdepth <= 0) + log_warning("Reached max depth on %s.", sub_path); + else { + DIR *sub_dir; + int q; + + sub_dir = xopendirat(dirfd(d), dent->d_name, O_NOFOLLOW|O_NOATIME); + if (sub_dir == NULL) { + if (errno != ENOENT) { + log_error("opendir(%s/%s) failed: %m", p, dent->d_name); + r = -errno; + } + + continue; + } + + q = dir_cleanup(sub_path, sub_dir, &s, cutoff, rootdev, false, maxdepth-1, false); + closedir(sub_dir); + + if (q < 0) + r = q; + } + + /* Note: if you are wondering why we don't + * support the sticky bit for excluding + * directories from cleaning like we do it for + * other file system objects: well, the sticky + * bit already has a meaning for directories, + * so we don't want to overload that. */ + + if (keep_this_level) + continue; + + /* Ignore ctime, we change it when deleting */ + age = MAX(timespec_load(&s.st_mtim), + timespec_load(&s.st_atim)); + if (age >= cutoff) + continue; + + log_debug("rmdir '%s'\n", sub_path); + + if (unlinkat(dirfd(d), dent->d_name, AT_REMOVEDIR) < 0) { + if (errno != ENOENT && errno != ENOTEMPTY) { + log_error("rmdir(%s): %m", sub_path); + r = -errno; + } + } + + } else { + /* Skip files for which the sticky bit is + * set. These are semantics we define, and are + * unknown elsewhere. See XDG_RUNTIME_DIR + * specification for details. */ + if (s.st_mode & S_ISVTX) + continue; + + if (mountpoint && S_ISREG(s.st_mode)) { + if (streq(dent->d_name, ".journal") && + s.st_uid == 0) + continue; + + if (streq(dent->d_name, "aquota.user") || + streq(dent->d_name, "aquota.group")) + continue; + } + + /* Ignore sockets that are listed in /proc/net/unix */ + if (S_ISSOCK(s.st_mode) && unix_socket_alive(sub_path)) + continue; + + /* Ignore device nodes */ + if (S_ISCHR(s.st_mode) || S_ISBLK(s.st_mode)) + continue; + + /* Keep files on this level around if this is + * requested */ + if (keep_this_level) + continue; + + age = MAX3(timespec_load(&s.st_mtim), + timespec_load(&s.st_atim), + timespec_load(&s.st_ctim)); + + if (age >= cutoff) + continue; + + log_debug("unlink '%s'\n", sub_path); + + if (unlinkat(dirfd(d), dent->d_name, 0) < 0) { + if (errno != ENOENT) { + log_error("unlink(%s): %m", sub_path); + r = -errno; + } + } + + deleted = true; + } + } + +finish: + if (deleted) { + /* Restore original directory timestamps */ + times[0] = ds->st_atim; + times[1] = ds->st_mtim; + + if (futimens(dirfd(d), times) < 0) + log_error("utimensat(%s): %m", p); + } + + free(sub_path); + + return r; +} + +static int clean_item(Item *i) { + DIR *d; + struct stat s, ps; + bool mountpoint; + int r; + usec_t cutoff, n; + + assert(i); + + if (i->type != CREATE_DIRECTORY && + i->type != TRUNCATE_DIRECTORY && + i->type != IGNORE_PATH) + return 0; + + if (!i->age_set) + return 0; + + n = now(CLOCK_REALTIME); + if (n < i->age) + return 0; + + cutoff = n - i->age; + + d = opendir(i->path); + if (!d) { + if (errno == ENOENT) + return 0; + + log_error("Failed to open directory %s: %m", i->path); + return -errno; + } + + if (fstat(dirfd(d), &s) < 0) { + log_error("stat(%s) failed: %m", i->path); + r = -errno; + goto finish; + } + + if (!S_ISDIR(s.st_mode)) { + log_error("%s is not a directory.", i->path); + r = -ENOTDIR; + goto finish; + } + + if (fstatat(dirfd(d), "..", &ps, AT_SYMLINK_NOFOLLOW) != 0) { + log_error("stat(%s/..) failed: %m", i->path); + r = -errno; + goto finish; + } + + mountpoint = s.st_dev != ps.st_dev || + (s.st_dev == ps.st_dev && s.st_ino == ps.st_ino); + + r = dir_cleanup(i->path, d, &s, cutoff, s.st_dev, mountpoint, MAX_DEPTH, i->keep_first_level); + +finish: + if (d) + closedir(d); + + return r; +} + +static int item_set_perms(Item *i, const char *path) { + /* not using i->path directly because it may be a glob */ + if (i->mode_set) + if (chmod(path, i->mode) < 0) { + log_error("chmod(%s) failed: %m", path); + return -errno; + } + + if (i->uid_set || i->gid_set) + if (chown(path, + i->uid_set ? i->uid : (uid_t) -1, + i->gid_set ? i->gid : (gid_t) -1) < 0) { + + log_error("chown(%s) failed: %m", path); + return -errno; + } + + return label_fix(path, false, false); +} + +static int write_one_file(Item *i, const char *path) { + int r, e, fd, flags; + struct stat st; + mode_t u; + + flags = i->type == CREATE_FILE ? O_CREAT|O_APPEND : + i->type == TRUNCATE_FILE ? O_CREAT|O_TRUNC : 0; + + u = umask(0); + label_context_set(path, S_IFREG); + fd = open(path, flags|O_NDELAY|O_CLOEXEC|O_WRONLY|O_NOCTTY|O_NOFOLLOW, i->mode); + e = errno; + label_context_clear(); + umask(u); + errno = e; + + if (fd < 0) { + if (i->type == WRITE_FILE && errno == ENOENT) + return 0; + + log_error("Failed to create file %s: %m", path); + return -errno; + } + + if (i->argument) { + ssize_t n; + size_t l; + _cleanup_free_ char *unescaped; + + unescaped = cunescape(i->argument); + if (unescaped == NULL) { + close_nointr_nofail(fd); + return log_oom(); + } + + l = strlen(unescaped); + n = write(fd, unescaped, l); + + if (n < 0 || (size_t) n < l) { + log_error("Failed to write file %s: %s", path, n < 0 ? strerror(-n) : "Short write"); + close_nointr_nofail(fd); + return n < 0 ? n : -EIO; + } + } + + close_nointr_nofail(fd); + + if (stat(path, &st) < 0) { + log_error("stat(%s) failed: %m", path); + return -errno; + } + + if (!S_ISREG(st.st_mode)) { + log_error("%s is not a file.", path); + return -EEXIST; + } + + r = item_set_perms(i, path); + if (r < 0) + return r; + + return 0; +} + +static int recursive_relabel_children(Item *i, const char *path) { + DIR *d; + int ret = 0; + + /* This returns the first error we run into, but nevertheless + * tries to go on */ + + d = opendir(path); + if (!d) + return errno == ENOENT ? 0 : -errno; + + for (;;) { + struct dirent *de; + union dirent_storage buf; + bool is_dir; + int r; + char *entry_path; + + r = readdir_r(d, &buf.de, &de); + if (r != 0) { + if (ret == 0) + ret = -r; + break; + } + + if (!de) + break; + + if (streq(de->d_name, ".") || streq(de->d_name, "..")) + continue; + + if (asprintf(&entry_path, "%s/%s", path, de->d_name) < 0) { + if (ret == 0) + ret = -ENOMEM; + continue; + } + + if (de->d_type == DT_UNKNOWN) { + struct stat st; + + if (lstat(entry_path, &st) < 0) { + if (ret == 0 && errno != ENOENT) + ret = -errno; + free(entry_path); + continue; + } + + is_dir = S_ISDIR(st.st_mode); + + } else + is_dir = de->d_type == DT_DIR; + + r = item_set_perms(i, entry_path); + if (r < 0) { + if (ret == 0 && r != -ENOENT) + ret = r; + free(entry_path); + continue; + } + + if (is_dir) { + r = recursive_relabel_children(i, entry_path); + if (r < 0 && ret == 0) + ret = r; + } + + free(entry_path); + } + + closedir(d); + + return ret; +} + +static int recursive_relabel(Item *i, const char *path) { + int r; + struct stat st; + + r = item_set_perms(i, path); + if (r < 0) + return r; + + if (lstat(path, &st) < 0) + return -errno; + + if (S_ISDIR(st.st_mode)) + r = recursive_relabel_children(i, path); + + return r; +} + +static int glob_item(Item *i, int (*action)(Item *, const char *)) { + int r = 0, k; + glob_t g; + char **fn; + + zero(g); + + errno = 0; + if ((k = glob(i->path, GLOB_NOSORT|GLOB_BRACE, NULL, &g)) != 0) { + + if (k != GLOB_NOMATCH) { + if (errno != 0) + errno = EIO; + + log_error("glob(%s) failed: %m", i->path); + return -errno; + } + } + + STRV_FOREACH(fn, g.gl_pathv) + if ((k = action(i, *fn)) < 0) + r = k; + + globfree(&g); + return r; +} + +static int create_item(Item *i) { + int r, e; + mode_t u; + struct stat st; + + assert(i); + + switch (i->type) { + + case IGNORE_PATH: + case REMOVE_PATH: + case RECURSIVE_REMOVE_PATH: + return 0; + + case CREATE_FILE: + case TRUNCATE_FILE: + r = write_one_file(i, i->path); + if (r < 0) + return r; + break; + case WRITE_FILE: + r = glob_item(i, write_one_file); + if (r < 0) + return r; + + break; + + case TRUNCATE_DIRECTORY: + case CREATE_DIRECTORY: + + u = umask(0); + mkdir_parents_label(i->path, 0755); + r = mkdir(i->path, i->mode); + umask(u); + + if (r < 0 && errno != EEXIST) { + log_error("Failed to create directory %s: %m", i->path); + return -errno; + } + + if (stat(i->path, &st) < 0) { + log_error("stat(%s) failed: %m", i->path); + return -errno; + } + + if (!S_ISDIR(st.st_mode)) { + log_error("%s is not a directory.", i->path); + return -EEXIST; + } + + r = item_set_perms(i, i->path); + if (r < 0) + return r; + + break; + + case CREATE_FIFO: + + u = umask(0); + r = mkfifo(i->path, i->mode); + umask(u); + + if (r < 0 && errno != EEXIST) { + log_error("Failed to create fifo %s: %m", i->path); + return -errno; + } + + if (stat(i->path, &st) < 0) { + log_error("stat(%s) failed: %m", i->path); + return -errno; + } + + if (!S_ISFIFO(st.st_mode)) { + log_error("%s is not a fifo.", i->path); + return -EEXIST; + } + + r = item_set_perms(i, i->path); + if (r < 0) + return r; + + break; + + case CREATE_SYMLINK: { + char *x; + + label_context_set(i->path, S_IFLNK); + r = symlink(i->argument, i->path); + e = errno; + label_context_clear(); + errno = e; + + if (r < 0 && errno != EEXIST) { + log_error("symlink(%s, %s) failed: %m", i->argument, i->path); + return -errno; + } + + r = readlink_malloc(i->path, &x); + if (r < 0) { + log_error("readlink(%s) failed: %s", i->path, strerror(-r)); + return -errno; + } + + if (!streq(i->argument, x)) { + free(x); + log_error("%s is not the right symlinks.", i->path); + return -EEXIST; + } + + free(x); + break; + } + + case CREATE_BLOCK_DEVICE: + case CREATE_CHAR_DEVICE: { + mode_t file_type; + + if (have_effective_cap(CAP_MKNOD) == 0) { + /* In a container we lack CAP_MKNOD. We + shouldnt attempt to create the device node in + that case to avoid noise, and we don't support + virtualized devices in containers anyway. */ + + log_debug("We lack CAP_MKNOD, skipping creation of device node %s.", i->path); + return 0; + } + + file_type = (i->type == CREATE_BLOCK_DEVICE ? S_IFBLK : S_IFCHR); + + u = umask(0); + label_context_set(i->path, file_type); + r = mknod(i->path, i->mode | file_type, i->major_minor); + e = errno; + label_context_clear(); + umask(u); + errno = e; + + if (r < 0 && errno != EEXIST) { + log_error("Failed to create device node %s: %m", i->path); + return -errno; + } + + if (stat(i->path, &st) < 0) { + log_error("stat(%s) failed: %m", i->path); + return -errno; + } + + if ((st.st_mode & S_IFMT) != file_type) { + log_error("%s is not a device node.", i->path); + return -EEXIST; + } + + r = item_set_perms(i, i->path); + if (r < 0) + return r; + + break; + } + + case RELABEL_PATH: + + r = glob_item(i, item_set_perms); + if (r < 0) + return 0; + break; + + case RECURSIVE_RELABEL_PATH: + + r = glob_item(i, recursive_relabel); + if (r < 0) + return r; + } + + log_debug("%s created successfully.", i->path); + + return 0; +} + +static int remove_item_instance(Item *i, const char *instance) { + int r; + + assert(i); + + switch (i->type) { + + case CREATE_FILE: + case TRUNCATE_FILE: + case CREATE_DIRECTORY: + case CREATE_FIFO: + case CREATE_SYMLINK: + case CREATE_BLOCK_DEVICE: + case CREATE_CHAR_DEVICE: + case IGNORE_PATH: + case RELABEL_PATH: + case RECURSIVE_RELABEL_PATH: + case WRITE_FILE: + break; + + case REMOVE_PATH: + if (remove(instance) < 0 && errno != ENOENT) { + log_error("remove(%s): %m", instance); + return -errno; + } + + break; + + case TRUNCATE_DIRECTORY: + case RECURSIVE_REMOVE_PATH: + /* FIXME: we probably should use dir_cleanup() here + * instead of rm_rf() so that 'x' is honoured. */ + r = rm_rf_dangerous(instance, false, i->type == RECURSIVE_REMOVE_PATH, false); + if (r < 0 && r != -ENOENT) { + log_error("rm_rf(%s): %s", instance, strerror(-r)); + return r; + } + + break; + } + + return 0; +} + +static int remove_item(Item *i) { + int r = 0; + + assert(i); + + switch (i->type) { + + case CREATE_FILE: + case TRUNCATE_FILE: + case CREATE_DIRECTORY: + case CREATE_FIFO: + case CREATE_SYMLINK: + case CREATE_CHAR_DEVICE: + case CREATE_BLOCK_DEVICE: + case IGNORE_PATH: + case RELABEL_PATH: + case RECURSIVE_RELABEL_PATH: + case WRITE_FILE: + break; + + case REMOVE_PATH: + case TRUNCATE_DIRECTORY: + case RECURSIVE_REMOVE_PATH: + r = glob_item(i, remove_item_instance); + break; + } + + return r; +} + +static int process_item(Item *i) { + int r, q, p; + + assert(i); + + r = arg_create ? create_item(i) : 0; + q = arg_remove ? remove_item(i) : 0; + p = arg_clean ? clean_item(i) : 0; + + if (r < 0) + return r; + + if (q < 0) + return q; + + return p; +} + +static void item_free(Item *i) { + assert(i); + + free(i->path); + free(i->argument); + free(i); +} + +static bool item_equal(Item *a, Item *b) { + assert(a); + assert(b); + + if (!streq_ptr(a->path, b->path)) + return false; + + if (a->type != b->type) + return false; + + if (a->uid_set != b->uid_set || + (a->uid_set && a->uid != b->uid)) + return false; + + if (a->gid_set != b->gid_set || + (a->gid_set && a->gid != b->gid)) + return false; + + if (a->mode_set != b->mode_set || + (a->mode_set && a->mode != b->mode)) + return false; + + if (a->age_set != b->age_set || + (a->age_set && a->age != b->age)) + return false; + + if ((a->type == CREATE_FILE || + a->type == TRUNCATE_FILE || + a->type == WRITE_FILE || + a->type == CREATE_SYMLINK) && + !streq_ptr(a->argument, b->argument)) + return false; + + if ((a->type == CREATE_CHAR_DEVICE || + a->type == CREATE_BLOCK_DEVICE) && + a->major_minor != b->major_minor) + return false; + + return true; +} + +static int parse_line(const char *fname, unsigned line, const char *buffer) { + Item *i, *existing; + char *mode = NULL, *user = NULL, *group = NULL, *age = NULL; + char type; + Hashmap *h; + int r, n = -1; + + assert(fname); + assert(line >= 1); + assert(buffer); + + i = new0(Item, 1); + if (!i) + return log_oom(); + + if (sscanf(buffer, + "%c " + "%ms " + "%ms " + "%ms " + "%ms " + "%ms " + "%n", + &type, + &i->path, + &mode, + &user, + &group, + &age, + &n) < 2) { + log_error("[%s:%u] Syntax error.", fname, line); + r = -EIO; + goto finish; + } + + if (n >= 0) { + n += strspn(buffer+n, WHITESPACE); + if (buffer[n] != 0 && (buffer[n] != '-' || buffer[n+1] != 0)) { + i->argument = unquote(buffer+n, "\""); + if (!i->argument) + return log_oom(); + } + } + + switch(type) { + + case CREATE_FILE: + case TRUNCATE_FILE: + case CREATE_DIRECTORY: + case TRUNCATE_DIRECTORY: + case CREATE_FIFO: + case IGNORE_PATH: + case REMOVE_PATH: + case RECURSIVE_REMOVE_PATH: + case RELABEL_PATH: + case RECURSIVE_RELABEL_PATH: + break; + + case CREATE_SYMLINK: + if (!i->argument) { + log_error("[%s:%u] Symlink file requires argument.", fname, line); + r = -EBADMSG; + goto finish; + } + break; + + case WRITE_FILE: + if (!i->argument) { + log_error("[%s:%u] Write file requires argument.", fname, line); + r = -EBADMSG; + goto finish; + } + break; + + case CREATE_CHAR_DEVICE: + case CREATE_BLOCK_DEVICE: { + unsigned major, minor; + + if (!i->argument) { + log_error("[%s:%u] Device file requires argument.", fname, line); + r = -EBADMSG; + goto finish; + } + + if (sscanf(i->argument, "%u:%u", &major, &minor) != 2) { + log_error("[%s:%u] Can't parse device file major/minor '%s'.", fname, line, i->argument); + r = -EBADMSG; + goto finish; + } + + i->major_minor = makedev(major, minor); + break; + } + + default: + log_error("[%s:%u] Unknown file type '%c'.", fname, line, type); + r = -EBADMSG; + goto finish; + } + + i->type = type; + + if (!path_is_absolute(i->path)) { + log_error("[%s:%u] Path '%s' not absolute.", fname, line, i->path); + r = -EBADMSG; + goto finish; + } + + path_kill_slashes(i->path); + + if (arg_prefix && !path_startswith(i->path, arg_prefix)) { + r = 0; + goto finish; + } + + if (user && !streq(user, "-")) { + const char *u = user; + + r = get_user_creds(&u, &i->uid, NULL, NULL, NULL); + if (r < 0) { + log_error("[%s:%u] Unknown user '%s'.", fname, line, user); + goto finish; + } + + i->uid_set = true; + } + + if (group && !streq(group, "-")) { + const char *g = group; + + r = get_group_creds(&g, &i->gid); + if (r < 0) { + log_error("[%s:%u] Unknown group '%s'.", fname, line, group); + goto finish; + } + + i->gid_set = true; + } + + if (mode && !streq(mode, "-")) { + unsigned m; + + if (sscanf(mode, "%o", &m) != 1) { + log_error("[%s:%u] Invalid mode '%s'.", fname, line, mode); + r = -ENOENT; + goto finish; + } + + i->mode = m; + i->mode_set = true; + } else + i->mode = + i->type == CREATE_DIRECTORY || + i->type == TRUNCATE_DIRECTORY ? 0755 : 0644; + + if (age && !streq(age, "-")) { + const char *a = age; + + if (*a == '~') { + i->keep_first_level = true; + a++; + } + + if (parse_usec(a, &i->age) < 0) { + log_error("[%s:%u] Invalid age '%s'.", fname, line, age); + r = -EBADMSG; + goto finish; + } + + i->age_set = true; + } + + h = needs_glob(i->type) ? globs : items; + + existing = hashmap_get(h, i->path); + if (existing) { + + /* Two identical items are fine */ + if (!item_equal(existing, i)) + log_warning("Two or more conflicting lines for %s configured, ignoring.", i->path); + + r = 0; + goto finish; + } + + r = hashmap_put(h, i->path, i); + if (r < 0) { + log_error("Failed to insert item %s: %s", i->path, strerror(-r)); + goto finish; + } + + i = NULL; + r = 0; + +finish: + free(user); + free(group); + free(mode); + free(age); + + if (i) + item_free(i); + + return r; +} + +static int help(void) { + + printf("%s [OPTIONS...] [CONFIGURATION FILE...]\n\n" + "Creates, deletes and cleans up volatile and temporary files and directories.\n\n" + " -h --help Show this help\n" + " --create Create marked files/directories\n" + " --clean Clean up marked directories\n" + " --remove Remove marked files/directories\n" + " --prefix=PATH Only apply rules that apply to paths with the specified prefix\n", + program_invocation_short_name); + + return 0; +} + +static int parse_argv(int argc, char *argv[]) { + + enum { + ARG_CREATE, + ARG_CLEAN, + ARG_REMOVE, + ARG_PREFIX + }; + + static const struct option options[] = { + { "help", no_argument, NULL, 'h' }, + { "create", no_argument, NULL, ARG_CREATE }, + { "clean", no_argument, NULL, ARG_CLEAN }, + { "remove", no_argument, NULL, ARG_REMOVE }, + { "prefix", required_argument, NULL, ARG_PREFIX }, + { NULL, 0, NULL, 0 } + }; + + int c; + + assert(argc >= 0); + assert(argv); + + while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) { + + switch (c) { + + case 'h': + help(); + return 0; + + case ARG_CREATE: + arg_create = true; + break; + + case ARG_CLEAN: + arg_clean = true; + break; + + case ARG_REMOVE: + arg_remove = true; + break; + + case ARG_PREFIX: + arg_prefix = optarg; + break; + + case '?': + return -EINVAL; + + default: + log_error("Unknown option code %c", c); + return -EINVAL; + } + } + + if (!arg_clean && !arg_create && !arg_remove) { + log_error("You need to specify at least one of --clean, --create or --remove."); + return -EINVAL; + } + + return 1; +} + +static int read_config_file(const char *fn, bool ignore_enoent) { + FILE *f; + unsigned v = 0; + int r = 0; + + assert(fn); + + f = fopen(fn, "re"); + if (!f) { + + if (ignore_enoent && errno == ENOENT) + return 0; + + log_error("Failed to open %s: %m", fn); + return -errno; + } + + log_debug("apply: %s\n", fn); + for (;;) { + char line[LINE_MAX], *l; + int k; + + if (!(fgets(line, sizeof(line), f))) + break; + + v++; + + l = strstrip(line); + if (*l == '#' || *l == 0) + continue; + + if ((k = parse_line(fn, v, l)) < 0) + if (r == 0) + r = k; + } + + if (ferror(f)) { + log_error("Failed to read from file %s: %m", fn); + if (r == 0) + r = -EIO; + } + + fclose(f); + + return r; +} + +static char *resolve_fragment(const char *fragment, const char **search_paths) { + const char **p; + char *resolved_path; + + if (is_path(fragment)) + return strdup(fragment); + + STRV_FOREACH(p, search_paths) { + resolved_path = strjoin(*p, "/", fragment, NULL); + if (resolved_path == NULL) { + log_oom(); + return NULL; + } + + if (access(resolved_path, F_OK) == 0) + return resolved_path; + + free(resolved_path); + } + + errno = ENOENT; + return NULL; +} + +int main(int argc, char *argv[]) { + int r; + Item *i; + Iterator iterator; + + r = parse_argv(argc, argv); + if (r <= 0) + return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; + + log_set_target(LOG_TARGET_AUTO); + log_parse_environment(); + log_open(); + + umask(0022); + + label_init(NULL); + + items = hashmap_new(string_hash_func, string_compare_func); + globs = hashmap_new(string_hash_func, string_compare_func); + + if (!items || !globs) { + log_oom(); + r = EXIT_FAILURE; + goto finish; + } + + r = EXIT_SUCCESS; + + if (optind < argc) { + int j; + + for (j = optind; j < argc; j++) { + char *fragment; + + fragment = resolve_fragment(argv[j], (const char **)conf_file_dirs); + if (!fragment) { + log_error("Failed to find a %s file: %m", argv[j]); + r = EXIT_FAILURE; + goto finish; + } + if (read_config_file(fragment, false) < 0) + r = EXIT_FAILURE; + free(fragment); + } + + } else { + char **files, **f; + + r = conf_files_list_strv(&files, ".conf", (const char **)conf_file_dirs); + if (r < 0) { + log_error("Failed to enumerate tmpfiles.d files: %s", strerror(-r)); + r = EXIT_FAILURE; + goto finish; + } + + STRV_FOREACH(f, files) { + if (read_config_file(*f, true) < 0) + r = EXIT_FAILURE; + } + + strv_free(files); + } + + HASHMAP_FOREACH(i, globs, iterator) + process_item(i); + + HASHMAP_FOREACH(i, items, iterator) + process_item(i); + +finish: + while ((i = hashmap_steal_first(items))) + item_free(i); + + while ((i = hashmap_steal_first(globs))) + item_free(i); + + hashmap_free(items); + hashmap_free(globs); + + set_free_free(unix_sockets); + + label_finish(); + + return r; +} diff --git a/src/tty-ask-password-agent/Makefile b/src/tty-ask-password-agent/Makefile new file mode 120000 index 000000000..d0b0e8e00 --- /dev/null +++ b/src/tty-ask-password-agent/Makefile @@ -0,0 +1 @@ +../Makefile \ No newline at end of file diff --git a/src/tty-ask-password-agent/tty-ask-password-agent.c b/src/tty-ask-password-agent/tty-ask-password-agent.c new file mode 100644 index 000000000..99a626c6c --- /dev/null +++ b/src/tty-ask-password-agent/tty-ask-password-agent.c @@ -0,0 +1,763 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "util.h" +#include "mkdir.h" +#include "path-util.h" +#include "conf-parser.h" +#include "utmp-wtmp.h" +#include "socket-util.h" +#include "ask-password-api.h" +#include "strv.h" +#include "build.h" + +static enum { + ACTION_LIST, + ACTION_QUERY, + ACTION_WATCH, + ACTION_WALL +} arg_action = ACTION_QUERY; + +static bool arg_plymouth = false; +static bool arg_console = false; + +static int ask_password_plymouth( + const char *message, + usec_t until, + const char *flag_file, + bool accept_cached, + char ***_passphrases) { + + int fd = -1, notify = -1; + union sockaddr_union sa; + char *packet = NULL; + ssize_t k; + int r, n; + struct pollfd pollfd[2]; + char buffer[LINE_MAX]; + size_t p = 0; + enum { + POLL_SOCKET, + POLL_INOTIFY + }; + + assert(_passphrases); + + if (flag_file) { + if ((notify = inotify_init1(IN_CLOEXEC|IN_NONBLOCK)) < 0) { + r = -errno; + goto finish; + } + + if (inotify_add_watch(notify, flag_file, IN_ATTRIB /* for the link count */) < 0) { + r = -errno; + goto finish; + } + } + + if ((fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0)) < 0) { + r = -errno; + goto finish; + } + + zero(sa); + sa.sa.sa_family = AF_UNIX; + strncpy(sa.un.sun_path+1, "/org/freedesktop/plymouthd", sizeof(sa.un.sun_path)-1); + if (connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + 1 + strlen(sa.un.sun_path+1)) < 0) { + log_error("Failed to connect to Plymouth: %m"); + r = -errno; + goto finish; + } + + if (accept_cached) { + packet = strdup("c"); + n = 1; + } else + asprintf(&packet, "*\002%c%s%n", (int) (strlen(message) + 1), message, &n); + + if (!packet) { + r = -ENOMEM; + goto finish; + } + + if ((k = loop_write(fd, packet, n+1, true)) != n+1) { + r = k < 0 ? (int) k : -EIO; + goto finish; + } + + zero(pollfd); + pollfd[POLL_SOCKET].fd = fd; + pollfd[POLL_SOCKET].events = POLLIN; + pollfd[POLL_INOTIFY].fd = notify; + pollfd[POLL_INOTIFY].events = POLLIN; + + for (;;) { + int sleep_for = -1, j; + + if (until > 0) { + usec_t y; + + y = now(CLOCK_MONOTONIC); + + if (y > until) { + r = -ETIME; + goto finish; + } + + sleep_for = (int) ((until - y) / USEC_PER_MSEC); + } + + if (flag_file) + if (access(flag_file, F_OK) < 0) { + r = -errno; + goto finish; + } + + if ((j = poll(pollfd, notify > 0 ? 2 : 1, sleep_for)) < 0) { + + if (errno == EINTR) + continue; + + r = -errno; + goto finish; + } else if (j == 0) { + r = -ETIME; + goto finish; + } + + if (notify > 0 && pollfd[POLL_INOTIFY].revents != 0) + flush_fd(notify); + + if (pollfd[POLL_SOCKET].revents == 0) + continue; + + if ((k = read(fd, buffer + p, sizeof(buffer) - p)) <= 0) { + r = k < 0 ? -errno : -EIO; + goto finish; + } + + p += k; + + if (p < 1) + continue; + + if (buffer[0] == 5) { + + if (accept_cached) { + /* Hmm, first try with cached + * passwords failed, so let's retry + * with a normal password request */ + free(packet); + packet = NULL; + + if (asprintf(&packet, "*\002%c%s%n", (int) (strlen(message) + 1), message, &n) < 0) { + r = -ENOMEM; + goto finish; + } + + if ((k = loop_write(fd, packet, n+1, true)) != n+1) { + r = k < 0 ? (int) k : -EIO; + goto finish; + } + + accept_cached = false; + p = 0; + continue; + } + + /* No password, because UI not shown */ + r = -ENOENT; + goto finish; + + } else if (buffer[0] == 2 || buffer[0] == 9) { + uint32_t size; + char **l; + + /* One ore more answers */ + if (p < 5) + continue; + + memcpy(&size, buffer+1, sizeof(size)); + size = le32toh(size); + if (size+5 > sizeof(buffer)) { + r = -EIO; + goto finish; + } + + if (p-5 < size) + continue; + + if (!(l = strv_parse_nulstr(buffer + 5, size))) { + r = -ENOMEM; + goto finish; + } + + *_passphrases = l; + break; + + } else { + /* Unknown packet */ + r = -EIO; + goto finish; + } + } + + r = 0; + +finish: + if (notify >= 0) + close_nointr_nofail(notify); + + if (fd >= 0) + close_nointr_nofail(fd); + + free(packet); + + return r; +} + +static int parse_password(const char *filename, char **wall) { + char *socket_name = NULL, *message = NULL, *packet = NULL; + uint64_t not_after = 0; + unsigned pid = 0; + int socket_fd = -1; + bool accept_cached = false; + + const ConfigTableItem items[] = { + { "Ask", "Socket", config_parse_string, 0, &socket_name }, + { "Ask", "NotAfter", config_parse_uint64, 0, ¬_after }, + { "Ask", "Message", config_parse_string, 0, &message }, + { "Ask", "PID", config_parse_unsigned, 0, &pid }, + { "Ask", "AcceptCached", config_parse_bool, 0, &accept_cached }, + { NULL, NULL, NULL, 0, NULL } + }; + + FILE *f; + int r; + + assert(filename); + + f = fopen(filename, "re"); + if (!f) { + if (errno == ENOENT) + return 0; + + log_error("open(%s): %m", filename); + return -errno; + } + + r = config_parse(filename, f, NULL, config_item_table_lookup, (void*) items, true, NULL); + if (r < 0) { + log_error("Failed to parse password file %s: %s", filename, strerror(-r)); + goto finish; + } + + if (!socket_name) { + log_error("Invalid password file %s", filename); + r = -EBADMSG; + goto finish; + } + + if (not_after > 0) { + if (now(CLOCK_MONOTONIC) > not_after) { + r = 0; + goto finish; + } + } + + if (pid > 0 && + kill(pid, 0) < 0 && + errno == ESRCH) { + r = 0; + goto finish; + } + + if (arg_action == ACTION_LIST) + printf("'%s' (PID %u)\n", message, pid); + else if (arg_action == ACTION_WALL) { + char *_wall; + + if (asprintf(&_wall, + "%s%sPassword entry required for \'%s\' (PID %u).\r\n" + "Please enter password with the systemd-tty-ask-password-agent tool!", + *wall ? *wall : "", + *wall ? "\r\n\r\n" : "", + message, + pid) < 0) { + r = log_oom(); + goto finish; + } + + free(*wall); + *wall = _wall; + } else { + union { + struct sockaddr sa; + struct sockaddr_un un; + } sa; + size_t packet_length = 0; + + assert(arg_action == ACTION_QUERY || + arg_action == ACTION_WATCH); + + if (access(socket_name, W_OK) < 0) { + + if (arg_action == ACTION_QUERY) + log_info("Not querying '%s' (PID %u), lacking privileges.", message, pid); + + r = 0; + goto finish; + } + + if (arg_plymouth) { + char **passwords = NULL; + + if ((r = ask_password_plymouth(message, not_after, filename, accept_cached, &passwords)) >= 0) { + char **p; + + packet_length = 1; + STRV_FOREACH(p, passwords) + packet_length += strlen(*p) + 1; + + if (!(packet = new(char, packet_length))) + r = -ENOMEM; + else { + char *d; + + packet[0] = '+'; + d = packet+1; + + STRV_FOREACH(p, passwords) + d = stpcpy(d, *p) + 1; + } + } + + } else { + int tty_fd = -1; + char *password; + + if (arg_console) + if ((tty_fd = acquire_terminal("/dev/console", false, false, false, (usec_t) -1)) < 0) { + r = tty_fd; + goto finish; + } + + r = ask_password_tty(message, not_after, filename, &password); + + if (arg_console) { + close_nointr_nofail(tty_fd); + release_terminal(); + } + + if (r >= 0) { + packet_length = 1+strlen(password)+1; + if (!(packet = new(char, packet_length))) + r = -ENOMEM; + else { + packet[0] = '+'; + strcpy(packet+1, password); + } + + free(password); + } + } + + if (r == -ETIME || r == -ENOENT) { + /* If the query went away, that's OK */ + r = 0; + goto finish; + } + + if (r < 0) { + log_error("Failed to query password: %s", strerror(-r)); + goto finish; + } + + if ((socket_fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0)) < 0) { + log_error("socket(): %m"); + r = -errno; + goto finish; + } + + zero(sa); + sa.un.sun_family = AF_UNIX; + strncpy(sa.un.sun_path, socket_name, sizeof(sa.un.sun_path)); + + if (sendto(socket_fd, packet, packet_length, MSG_NOSIGNAL, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(socket_name)) < 0) { + log_error("Failed to send: %m"); + r = -errno; + goto finish; + } + } + +finish: + fclose(f); + + if (socket_fd >= 0) + close_nointr_nofail(socket_fd); + + free(packet); + free(socket_name); + free(message); + + return r; +} + +static int wall_tty_block(void) { + char *p; + int fd, r; + dev_t devnr; + + r = get_ctty_devnr(0, &devnr); + if (r < 0) + return -r; + + if (asprintf(&p, "/run/systemd/ask-password-block/%u:%u", major(devnr), minor(devnr)) < 0) + return -ENOMEM; + + mkdir_parents_label(p, 0700); + mkfifo(p, 0600); + + fd = open(p, O_RDONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY); + free(p); + + if (fd < 0) + return -errno; + + return fd; +} + +static bool wall_tty_match(const char *path) { + int fd, k; + char *p; + struct stat st; + + if (path_is_absolute(path)) + k = lstat(path, &st); + else { + if (asprintf(&p, "/dev/%s", path) < 0) + return true; + + k = lstat(p, &st); + free(p); + } + + if (k < 0) + return true; + + if (!S_ISCHR(st.st_mode)) + return true; + + /* We use named pipes to ensure that wall messages suggesting + * password entry are not printed over password prompts + * already shown. We use the fact here that opening a pipe in + * non-blocking mode for write-only will succeed only if + * there's some writer behind it. Using pipes has the + * advantage that the block will automatically go away if the + * process dies. */ + + if (asprintf(&p, "/run/systemd/ask-password-block/%u:%u", major(st.st_rdev), minor(st.st_rdev)) < 0) + return true; + + fd = open(p, O_WRONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY); + free(p); + + if (fd < 0) + return true; + + /* What, we managed to open the pipe? Then this tty is filtered. */ + close_nointr_nofail(fd); + return false; +} + +static int show_passwords(void) { + DIR *d; + struct dirent *de; + int r = 0; + + if (!(d = opendir("/run/systemd/ask-password"))) { + if (errno == ENOENT) + return 0; + + log_error("opendir(): %m"); + return -errno; + } + + while ((de = readdir(d))) { + char *p; + int q; + char *wall; + + /* We only support /dev on tmpfs, hence we can rely on + * d_type to be reliable */ + + if (de->d_type != DT_REG) + continue; + + if (ignore_file(de->d_name)) + continue; + + if (!startswith(de->d_name, "ask.")) + continue; + + if (!(p = strappend("/run/systemd/ask-password/", de->d_name))) { + r = log_oom(); + goto finish; + } + + wall = NULL; + if ((q = parse_password(p, &wall)) < 0) + r = q; + + free(p); + + if (wall) { + utmp_wall(wall, wall_tty_match); + free(wall); + } + } + +finish: + if (d) + closedir(d); + + return r; +} + +static int watch_passwords(void) { + enum { + FD_INOTIFY, + FD_SIGNAL, + _FD_MAX + }; + + int notify = -1, signal_fd = -1, tty_block_fd = -1; + struct pollfd pollfd[_FD_MAX]; + sigset_t mask; + int r; + + tty_block_fd = wall_tty_block(); + + mkdir_p_label("/run/systemd/ask-password", 0755); + + if ((notify = inotify_init1(IN_CLOEXEC)) < 0) { + r = -errno; + goto finish; + } + + if (inotify_add_watch(notify, "/run/systemd/ask-password", IN_CLOSE_WRITE|IN_MOVED_TO) < 0) { + r = -errno; + goto finish; + } + + assert_se(sigemptyset(&mask) == 0); + sigset_add_many(&mask, SIGINT, SIGTERM, -1); + assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0); + + if ((signal_fd = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC)) < 0) { + log_error("signalfd(): %m"); + r = -errno; + goto finish; + } + + zero(pollfd); + pollfd[FD_INOTIFY].fd = notify; + pollfd[FD_INOTIFY].events = POLLIN; + pollfd[FD_SIGNAL].fd = signal_fd; + pollfd[FD_SIGNAL].events = POLLIN; + + for (;;) { + if ((r = show_passwords()) < 0) + log_error("Failed to show password: %s", strerror(-r)); + + if (poll(pollfd, _FD_MAX, -1) < 0) { + + if (errno == EINTR) + continue; + + r = -errno; + goto finish; + } + + if (pollfd[FD_INOTIFY].revents != 0) + flush_fd(notify); + + if (pollfd[FD_SIGNAL].revents != 0) + break; + } + + r = 0; + +finish: + if (notify >= 0) + close_nointr_nofail(notify); + + if (signal_fd >= 0) + close_nointr_nofail(signal_fd); + + if (tty_block_fd >= 0) + close_nointr_nofail(tty_block_fd); + + return r; +} + +static int help(void) { + + printf("%s [OPTIONS...]\n\n" + "Process system password requests.\n\n" + " -h --help Show this help\n" + " --version Show package version\n" + " --list Show pending password requests\n" + " --query Process pending password requests\n" + " --watch Continuously process password requests\n" + " --wall Continuously forward password requests to wall\n" + " --plymouth Ask question with Plymouth instead of on TTY\n" + " --console Ask question on /dev/console instead of current TTY\n", + program_invocation_short_name); + + return 0; +} + +static int parse_argv(int argc, char *argv[]) { + + enum { + ARG_LIST = 0x100, + ARG_QUERY, + ARG_WATCH, + ARG_WALL, + ARG_PLYMOUTH, + ARG_CONSOLE, + ARG_VERSION + }; + + static const struct option options[] = { + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, ARG_VERSION }, + { "list", no_argument, NULL, ARG_LIST }, + { "query", no_argument, NULL, ARG_QUERY }, + { "watch", no_argument, NULL, ARG_WATCH }, + { "wall", no_argument, NULL, ARG_WALL }, + { "plymouth", no_argument, NULL, ARG_PLYMOUTH }, + { "console", no_argument, NULL, ARG_CONSOLE }, + { NULL, 0, NULL, 0 } + }; + + int c; + + assert(argc >= 0); + assert(argv); + + while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) { + + switch (c) { + + case 'h': + help(); + return 0; + + case ARG_VERSION: + puts(PACKAGE_STRING); + puts(SYSTEMD_FEATURES); + return 0; + + case ARG_LIST: + arg_action = ACTION_LIST; + break; + + case ARG_QUERY: + arg_action = ACTION_QUERY; + break; + + case ARG_WATCH: + arg_action = ACTION_WATCH; + break; + + case ARG_WALL: + arg_action = ACTION_WALL; + break; + + case ARG_PLYMOUTH: + arg_plymouth = true; + break; + + case ARG_CONSOLE: + arg_console = true; + break; + + case '?': + return -EINVAL; + + default: + log_error("Unknown option code %c", c); + return -EINVAL; + } + } + + if (optind != argc) { + help(); + return -EINVAL; + } + + return 1; +} + +int main(int argc, char *argv[]) { + int r; + + log_set_target(LOG_TARGET_AUTO); + log_parse_environment(); + log_open(); + + umask(0022); + + if ((r = parse_argv(argc, argv)) <= 0) + goto finish; + + if (arg_console) { + setsid(); + release_terminal(); + } + + if (arg_action == ACTION_WATCH || + arg_action == ACTION_WALL) + r = watch_passwords(); + else + r = show_passwords(); + + if (r < 0) + log_error("Error: %s", strerror(-r)); + +finish: + return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/src/udev/.gitignore b/src/udev/.gitignore new file mode 100644 index 000000000..3e375a772 --- /dev/null +++ b/src/udev/.gitignore @@ -0,0 +1 @@ +/udev.pc diff --git a/src/udev/.vimrc b/src/udev/.vimrc new file mode 100644 index 000000000..366fbdca4 --- /dev/null +++ b/src/udev/.vimrc @@ -0,0 +1,4 @@ +" 'set exrc' in ~/.vimrc will read .vimrc from the current directory +set tabstop=8 +set shiftwidth=8 +set expandtab diff --git a/src/udev/Makefile b/src/udev/Makefile new file mode 120000 index 000000000..d0b0e8e00 --- /dev/null +++ b/src/udev/Makefile @@ -0,0 +1 @@ +../Makefile \ No newline at end of file diff --git a/src/udev/accelerometer/accelerometer.c b/src/udev/accelerometer/accelerometer.c new file mode 100644 index 000000000..21f51936e --- /dev/null +++ b/src/udev/accelerometer/accelerometer.c @@ -0,0 +1,358 @@ +/* + * accelerometer - exports device orientation through property + * + * When an "change" event is received on an accelerometer, + * open its device node, and from the value, as well as the previous + * value of the property, calculate the device's new orientation, + * and export it as ID_INPUT_ACCELEROMETER_ORIENTATION. + * + * Possible values are: + * undefined + * * normal + * * bottom-up + * * left-up + * * right-up + * + * The property will be persistent across sessions, and the new + * orientations can be deducted from the previous one (it allows + * for a threshold for switching between opposite ends of the + * orientation). + * + * Copyright (C) 2011 Red Hat, Inc. + * Author: + * Bastien Nocera + * + * orientation_calc() from the sensorfw package + * Copyright (C) 2009-2010 Nokia Corporation + * Authors: + * Üstün Ergenoglu + * Timo Rongas + * Lihan Guo + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "libudev.h" +#include "libudev-private.h" + +/* we must use this kernel-compatible implementation */ +#define BITS_PER_LONG (sizeof(unsigned long) * 8) +#define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1) +#define OFF(x) ((x)%BITS_PER_LONG) +#define BIT(x) (1UL<> OFF(bit)) & 1) + +static int debug = 0; + +static void log_fn(struct udev *udev, int priority, + const char *file, int line, const char *fn, + const char *format, va_list args) +{ + if (debug) { + fprintf(stderr, "%s: ", fn); + vfprintf(stderr, format, args); + } else { + vsyslog(priority, format, args); + } +} + +typedef enum { + ORIENTATION_UNDEFINED, + ORIENTATION_NORMAL, + ORIENTATION_BOTTOM_UP, + ORIENTATION_LEFT_UP, + ORIENTATION_RIGHT_UP +} OrientationUp; + +static const char *orientations[] = { + "undefined", + "normal", + "bottom-up", + "left-up", + "right-up", + NULL +}; + +#define ORIENTATION_UP_UP ORIENTATION_NORMAL + +#define DEFAULT_THRESHOLD 250 +#define RADIANS_TO_DEGREES 180.0/M_PI +#define SAME_AXIS_LIMIT 5 + +#define THRESHOLD_LANDSCAPE 25 +#define THRESHOLD_PORTRAIT 20 + +static const char * +orientation_to_string (OrientationUp o) +{ + return orientations[o]; +} + +static OrientationUp +string_to_orientation (const char *orientation) +{ + int i; + + if (orientation == NULL) + return ORIENTATION_UNDEFINED; + for (i = 0; orientations[i] != NULL; i++) { + if (strcmp (orientation, orientations[i]) == 0) + return i; + } + return ORIENTATION_UNDEFINED; +} + +static OrientationUp +orientation_calc (OrientationUp prev, + int x, int y, int z) +{ + int rotation; + OrientationUp ret = prev; + + /* Portrait check */ + rotation = round(atan((double) x / sqrt(y * y + z * z)) * RADIANS_TO_DEGREES); + + if (abs(rotation) > THRESHOLD_PORTRAIT) { + ret = (rotation < 0) ? ORIENTATION_LEFT_UP : ORIENTATION_RIGHT_UP; + + /* Some threshold to switching between portrait modes */ + if (prev == ORIENTATION_LEFT_UP || prev == ORIENTATION_RIGHT_UP) { + if (abs(rotation) < SAME_AXIS_LIMIT) { + ret = prev; + } + } + + } else { + /* Landscape check */ + rotation = round(atan((double) y / sqrt(x * x + z * z)) * RADIANS_TO_DEGREES); + + if (abs(rotation) > THRESHOLD_LANDSCAPE) { + ret = (rotation < 0) ? ORIENTATION_BOTTOM_UP : ORIENTATION_NORMAL; + + /* Some threshold to switching between landscape modes */ + if (prev == ORIENTATION_BOTTOM_UP || prev == ORIENTATION_NORMAL) { + if (abs(rotation) < SAME_AXIS_LIMIT) { + ret = prev; + } + } + } + } + + return ret; +} + +static OrientationUp +get_prev_orientation(struct udev_device *dev) +{ + const char *value; + + value = udev_device_get_property_value(dev, "ID_INPUT_ACCELEROMETER_ORIENTATION"); + if (value == NULL) + return ORIENTATION_UNDEFINED; + return string_to_orientation(value); +} + +#define SET_AXIS(axis, code_) if (ev[i].code == code_) { if (got_##axis == 0) { axis = ev[i].value; got_##axis = 1; } } + +/* accelerometers */ +static void test_orientation(struct udev *udev, + struct udev_device *dev, + const char *devpath) +{ + OrientationUp old, new; + int fd, r; + struct input_event ev[64]; + int got_syn = 0; + int got_x, got_y, got_z; + int x = 0, y = 0, z = 0; + char text[64]; + + old = get_prev_orientation(dev); + + if ((fd = open(devpath, O_RDONLY)) < 0) + return; + + got_x = got_y = got_z = 0; + + while (1) { + int i; + + r = read(fd, ev, sizeof(struct input_event) * 64); + + if (r < (int) sizeof(struct input_event)) { + close(fd); + return; + } + + for (i = 0; i < r / (int) sizeof(struct input_event); i++) { + if (got_syn == 1) { + if (ev[i].type == EV_ABS) { + SET_AXIS(x, ABS_X); + SET_AXIS(y, ABS_Y); + SET_AXIS(z, ABS_Z); + } + } + if (ev[i].type == EV_SYN && ev[i].code == SYN_REPORT) { + got_syn = 1; + } + if (got_x && got_y && got_z) + goto read_dev; + } + } + +read_dev: + close(fd); + + if (!got_x || !got_y || !got_z) + return; + + new = orientation_calc(old, x, y, z); + snprintf(text, sizeof(text), "ID_INPUT_ACCELEROMETER_ORIENTATION=%s", orientation_to_string(new)); + puts(text); +} + +static void help(void) +{ + printf("Usage: accelerometer [options] \n" + " --debug debug to stderr\n" + " --help print this help text\n\n"); +} + +int main (int argc, char** argv) +{ + struct udev *udev; + struct udev_device *dev; + + static const struct option options[] = { + { "debug", no_argument, NULL, 'd' }, + { "help", no_argument, NULL, 'h' }, + {} + }; + + char devpath[PATH_MAX]; + char *devnode; + const char *id_path; + struct udev_enumerate *enumerate; + struct udev_list_entry *list_entry; + + udev = udev_new(); + if (udev == NULL) + return 1; + + log_open(); + udev_set_log_fn(udev, log_fn); + + /* CLI argument parsing */ + while (1) { + int option; + + option = getopt_long(argc, argv, "dxh", options, NULL); + if (option == -1) + break; + + switch (option) { + case 'd': + debug = 1; + log_set_max_level(LOG_DEBUG); + udev_set_log_priority(udev, LOG_DEBUG); + break; + case 'h': + help(); + exit(0); + default: + exit(1); + } + } + + if (argv[optind] == NULL) { + help(); + exit(1); + } + + /* get the device */ + snprintf(devpath, sizeof(devpath), "/sys/%s", argv[optind]); + dev = udev_device_new_from_syspath(udev, devpath); + if (dev == NULL) { + fprintf(stderr, "unable to access '%s'\n", devpath); + return 1; + } + + id_path = udev_device_get_property_value(dev, "ID_PATH"); + if (id_path == NULL) { + fprintf (stderr, "unable to get property ID_PATH for '%s'", devpath); + return 0; + } + + /* Get the children devices and find the devnode */ + /* FIXME: use udev_enumerate_add_match_parent() instead */ + devnode = NULL; + enumerate = udev_enumerate_new(udev); + udev_enumerate_add_match_property(enumerate, "ID_PATH", id_path); + udev_enumerate_add_match_subsystem(enumerate, "input"); + udev_enumerate_scan_devices(enumerate); + udev_list_entry_foreach(list_entry, udev_enumerate_get_list_entry(enumerate)) { + struct udev_device *device; + const char *node; + + device = udev_device_new_from_syspath(udev_enumerate_get_udev(enumerate), + udev_list_entry_get_name(list_entry)); + if (device == NULL) + continue; + /* Already found it */ + if (devnode != NULL) { + udev_device_unref(device); + continue; + } + + node = udev_device_get_devnode(device); + if (node == NULL) { + udev_device_unref(device); + continue; + } + /* Use the event sub-device */ + if (strstr(node, "/event") == NULL) { + udev_device_unref(device); + continue; + } + + devnode = strdup(node); + udev_device_unref(device); + } + + if (devnode == NULL) { + fprintf(stderr, "unable to get device node for '%s'\n", devpath); + return 0; + } + + log_debug("opening accelerometer device %s\n", devnode); + test_orientation(udev, dev, devnode); + free(devnode); + log_close(); + return 0; +} diff --git a/src/udev/ata_id/ata_id.c b/src/udev/ata_id/ata_id.c new file mode 100644 index 000000000..488fed4ac --- /dev/null +++ b/src/udev/ata_id/ata_id.c @@ -0,0 +1,714 @@ +/* + * ata_id - reads product/serial number from ATA drives + * + * Copyright (C) 2005-2008 Kay Sievers + * Copyright (C) 2009 Lennart Poettering + * Copyright (C) 2009-2010 David Zeuthen + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "libudev.h" +#include "libudev-private.h" +#include "log.h" + +#define COMMAND_TIMEOUT_MSEC (30 * 1000) + +static int disk_scsi_inquiry_command(int fd, + void *buf, + size_t buf_len) +{ + struct sg_io_v4 io_v4; + uint8_t cdb[6]; + uint8_t sense[32]; + int ret; + + /* + * INQUIRY, see SPC-4 section 6.4 + */ + memset(cdb, 0, sizeof(cdb)); + cdb[0] = 0x12; /* OPERATION CODE: INQUIRY */ + cdb[3] = (buf_len >> 8); /* ALLOCATION LENGTH */ + cdb[4] = (buf_len & 0xff); + + memset(sense, 0, sizeof(sense)); + + memset(&io_v4, 0, sizeof(struct sg_io_v4)); + io_v4.guard = 'Q'; + io_v4.protocol = BSG_PROTOCOL_SCSI; + io_v4.subprotocol = BSG_SUB_PROTOCOL_SCSI_CMD; + io_v4.request_len = sizeof (cdb); + io_v4.request = (uintptr_t) cdb; + io_v4.max_response_len = sizeof (sense); + io_v4.response = (uintptr_t) sense; + io_v4.din_xfer_len = buf_len; + io_v4.din_xferp = (uintptr_t) buf; + io_v4.timeout = COMMAND_TIMEOUT_MSEC; + + ret = ioctl(fd, SG_IO, &io_v4); + if (ret != 0) { + /* could be that the driver doesn't do version 4, try version 3 */ + if (errno == EINVAL) { + struct sg_io_hdr io_hdr; + + memset(&io_hdr, 0, sizeof(struct sg_io_hdr)); + io_hdr.interface_id = 'S'; + io_hdr.cmdp = (unsigned char*) cdb; + io_hdr.cmd_len = sizeof (cdb); + io_hdr.dxferp = buf; + io_hdr.dxfer_len = buf_len; + io_hdr.sbp = sense; + io_hdr.mx_sb_len = sizeof (sense); + io_hdr.dxfer_direction = SG_DXFER_FROM_DEV; + io_hdr.timeout = COMMAND_TIMEOUT_MSEC; + + ret = ioctl(fd, SG_IO, &io_hdr); + if (ret != 0) + goto out; + + /* even if the ioctl succeeds, we need to check the return value */ + if (!(io_hdr.status == 0 && + io_hdr.host_status == 0 && + io_hdr.driver_status == 0)) { + errno = EIO; + ret = -1; + goto out; + } + } else { + goto out; + } + } + + /* even if the ioctl succeeds, we need to check the return value */ + if (!(io_v4.device_status == 0 && + io_v4.transport_status == 0 && + io_v4.driver_status == 0)) { + errno = EIO; + ret = -1; + goto out; + } + + out: + return ret; +} + +static int disk_identify_command(int fd, + void *buf, + size_t buf_len) +{ + struct sg_io_v4 io_v4; + uint8_t cdb[12]; + uint8_t sense[32]; + uint8_t *desc = sense+8; + int ret; + + /* + * ATA Pass-Through 12 byte command, as described in + * + * T10 04-262r8 ATA Command Pass-Through + * + * from http://www.t10.org/ftp/t10/document.04/04-262r8.pdf + */ + memset(cdb, 0, sizeof(cdb)); + cdb[0] = 0xa1; /* OPERATION CODE: 12 byte pass through */ + cdb[1] = 4 << 1; /* PROTOCOL: PIO Data-in */ + cdb[2] = 0x2e; /* OFF_LINE=0, CK_COND=1, T_DIR=1, BYT_BLOK=1, T_LENGTH=2 */ + cdb[3] = 0; /* FEATURES */ + cdb[4] = 1; /* SECTORS */ + cdb[5] = 0; /* LBA LOW */ + cdb[6] = 0; /* LBA MID */ + cdb[7] = 0; /* LBA HIGH */ + cdb[8] = 0 & 0x4F; /* SELECT */ + cdb[9] = 0xEC; /* Command: ATA IDENTIFY DEVICE */; + memset(sense, 0, sizeof(sense)); + + memset(&io_v4, 0, sizeof(struct sg_io_v4)); + io_v4.guard = 'Q'; + io_v4.protocol = BSG_PROTOCOL_SCSI; + io_v4.subprotocol = BSG_SUB_PROTOCOL_SCSI_CMD; + io_v4.request_len = sizeof (cdb); + io_v4.request = (uintptr_t) cdb; + io_v4.max_response_len = sizeof (sense); + io_v4.response = (uintptr_t) sense; + io_v4.din_xfer_len = buf_len; + io_v4.din_xferp = (uintptr_t) buf; + io_v4.timeout = COMMAND_TIMEOUT_MSEC; + + ret = ioctl(fd, SG_IO, &io_v4); + if (ret != 0) { + /* could be that the driver doesn't do version 4, try version 3 */ + if (errno == EINVAL) { + struct sg_io_hdr io_hdr; + + memset(&io_hdr, 0, sizeof(struct sg_io_hdr)); + io_hdr.interface_id = 'S'; + io_hdr.cmdp = (unsigned char*) cdb; + io_hdr.cmd_len = sizeof (cdb); + io_hdr.dxferp = buf; + io_hdr.dxfer_len = buf_len; + io_hdr.sbp = sense; + io_hdr.mx_sb_len = sizeof (sense); + io_hdr.dxfer_direction = SG_DXFER_FROM_DEV; + io_hdr.timeout = COMMAND_TIMEOUT_MSEC; + + ret = ioctl(fd, SG_IO, &io_hdr); + if (ret != 0) + goto out; + } else { + goto out; + } + } + + if (!(sense[0] == 0x72 && desc[0] == 0x9 && desc[1] == 0x0c)) { + errno = EIO; + ret = -1; + goto out; + } + + out: + return ret; +} + +static int disk_identify_packet_device_command(int fd, + void *buf, + size_t buf_len) +{ + struct sg_io_v4 io_v4; + uint8_t cdb[16]; + uint8_t sense[32]; + uint8_t *desc = sense+8; + int ret; + + /* + * ATA Pass-Through 16 byte command, as described in + * + * T10 04-262r8 ATA Command Pass-Through + * + * from http://www.t10.org/ftp/t10/document.04/04-262r8.pdf + */ + memset(cdb, 0, sizeof(cdb)); + cdb[0] = 0x85; /* OPERATION CODE: 16 byte pass through */ + cdb[1] = 4 << 1; /* PROTOCOL: PIO Data-in */ + cdb[2] = 0x2e; /* OFF_LINE=0, CK_COND=1, T_DIR=1, BYT_BLOK=1, T_LENGTH=2 */ + cdb[3] = 0; /* FEATURES */ + cdb[4] = 0; /* FEATURES */ + cdb[5] = 0; /* SECTORS */ + cdb[6] = 1; /* SECTORS */ + cdb[7] = 0; /* LBA LOW */ + cdb[8] = 0; /* LBA LOW */ + cdb[9] = 0; /* LBA MID */ + cdb[10] = 0; /* LBA MID */ + cdb[11] = 0; /* LBA HIGH */ + cdb[12] = 0; /* LBA HIGH */ + cdb[13] = 0; /* DEVICE */ + cdb[14] = 0xA1; /* Command: ATA IDENTIFY PACKET DEVICE */; + cdb[15] = 0; /* CONTROL */ + memset(sense, 0, sizeof(sense)); + + memset(&io_v4, 0, sizeof(struct sg_io_v4)); + io_v4.guard = 'Q'; + io_v4.protocol = BSG_PROTOCOL_SCSI; + io_v4.subprotocol = BSG_SUB_PROTOCOL_SCSI_CMD; + io_v4.request_len = sizeof (cdb); + io_v4.request = (uintptr_t) cdb; + io_v4.max_response_len = sizeof (sense); + io_v4.response = (uintptr_t) sense; + io_v4.din_xfer_len = buf_len; + io_v4.din_xferp = (uintptr_t) buf; + io_v4.timeout = COMMAND_TIMEOUT_MSEC; + + ret = ioctl(fd, SG_IO, &io_v4); + if (ret != 0) { + /* could be that the driver doesn't do version 4, try version 3 */ + if (errno == EINVAL) { + struct sg_io_hdr io_hdr; + + memset(&io_hdr, 0, sizeof(struct sg_io_hdr)); + io_hdr.interface_id = 'S'; + io_hdr.cmdp = (unsigned char*) cdb; + io_hdr.cmd_len = sizeof (cdb); + io_hdr.dxferp = buf; + io_hdr.dxfer_len = buf_len; + io_hdr.sbp = sense; + io_hdr.mx_sb_len = sizeof (sense); + io_hdr.dxfer_direction = SG_DXFER_FROM_DEV; + io_hdr.timeout = COMMAND_TIMEOUT_MSEC; + + ret = ioctl(fd, SG_IO, &io_hdr); + if (ret != 0) + goto out; + } else { + goto out; + } + } + + if (!(sense[0] == 0x72 && desc[0] == 0x9 && desc[1] == 0x0c)) { + errno = EIO; + ret = -1; + goto out; + } + + out: + return ret; +} + +/** + * disk_identify_get_string: + * @identify: A block of IDENTIFY data + * @offset_words: Offset of the string to get, in words. + * @dest: Destination buffer for the string. + * @dest_len: Length of destination buffer, in bytes. + * + * Copies the ATA string from @identify located at @offset_words into @dest. + */ +static void disk_identify_get_string(uint8_t identify[512], + unsigned int offset_words, + char *dest, + size_t dest_len) +{ + unsigned int c1; + unsigned int c2; + + while (dest_len > 0) { + c1 = identify[offset_words * 2 + 1]; + c2 = identify[offset_words * 2]; + *dest = c1; + dest++; + *dest = c2; + dest++; + offset_words++; + dest_len -= 2; + } +} + +static void disk_identify_fixup_string(uint8_t identify[512], + unsigned int offset_words, + size_t len) +{ + disk_identify_get_string(identify, offset_words, + (char *) identify + offset_words * 2, len); +} + +static void disk_identify_fixup_uint16 (uint8_t identify[512], unsigned int offset_words) +{ + uint16_t *p; + + p = (uint16_t *) identify; + p[offset_words] = le16toh (p[offset_words]); +} + +/** + * disk_identify: + * @udev: The libudev context. + * @fd: File descriptor for the block device. + * @out_identify: Return location for IDENTIFY data. + * @out_is_packet_device: Return location for whether returned data is from a IDENTIFY PACKET DEVICE. + * + * Sends the IDENTIFY DEVICE or IDENTIFY PACKET DEVICE command to the + * device represented by @fd. If successful, then the result will be + * copied into @out_identify and @out_is_packet_device. + * + * This routine is based on code from libatasmart, Copyright 2008 + * Lennart Poettering, LGPL v2.1. + * + * Returns: 0 if the data was successfully obtained, otherwise + * non-zero with errno set. + */ +static int disk_identify(struct udev *udev, + int fd, + uint8_t out_identify[512], + int *out_is_packet_device) +{ + int ret; + uint8_t inquiry_buf[36]; + int peripheral_device_type; + int all_nul_bytes; + int n; + int is_packet_device; + + /* init results */ + memset(out_identify, '\0', 512); + is_packet_device = 0; + + /* If we were to use ATA PASS_THROUGH (12) on an ATAPI device + * we could accidentally blank media. This is because MMC's BLANK + * command has the same op-code (0x61). + * + * To prevent this from happening we bail out if the device + * isn't a Direct Access Block Device, e.g. SCSI type 0x00 + * (CD/DVD devices are type 0x05). So we send a SCSI INQUIRY + * command first... libata is handling this via its SCSI + * emulation layer. + * + * This also ensures that we're actually dealing with a device + * that understands SCSI commands. + * + * (Yes, it is a bit perverse that we're tunneling the ATA + * command through SCSI and relying on the ATA driver + * emulating SCSI well-enough...) + * + * (See commit 160b069c25690bfb0c785994c7c3710289179107 for + * the original bug-fix and see http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=556635 + * for the original bug-report.) + */ + ret = disk_scsi_inquiry_command (fd, inquiry_buf, sizeof (inquiry_buf)); + if (ret != 0) + goto out; + + /* SPC-4, section 6.4.2: Standard INQUIRY data */ + peripheral_device_type = inquiry_buf[0] & 0x1f; + if (peripheral_device_type == 0x05) + { + is_packet_device = 1; + ret = disk_identify_packet_device_command(fd, out_identify, 512); + goto check_nul_bytes; + } + if (peripheral_device_type != 0x00) { + ret = -1; + errno = EIO; + goto out; + } + + /* OK, now issue the IDENTIFY DEVICE command */ + ret = disk_identify_command(fd, out_identify, 512); + if (ret != 0) + goto out; + + check_nul_bytes: + /* Check if IDENTIFY data is all NUL bytes - if so, bail */ + all_nul_bytes = 1; + for (n = 0; n < 512; n++) { + if (out_identify[n] != '\0') { + all_nul_bytes = 0; + break; + } + } + + if (all_nul_bytes) { + ret = -1; + errno = EIO; + goto out; + } + +out: + if (out_is_packet_device != NULL) + *out_is_packet_device = is_packet_device; + return ret; +} + +static void log_fn(struct udev *udev, int priority, + const char *file, int line, const char *fn, + const char *format, va_list args) +{ + vsyslog(priority, format, args); +} + +int main(int argc, char *argv[]) +{ + struct udev *udev; + struct hd_driveid id; + uint8_t identify[512]; + uint16_t *identify_words; + char model[41]; + char model_enc[256]; + char serial[21]; + char revision[9]; + const char *node = NULL; + int export = 0; + int fd; + uint16_t word; + int rc = 0; + int is_packet_device = 0; + static const struct option options[] = { + { "export", no_argument, NULL, 'x' }, + { "help", no_argument, NULL, 'h' }, + {} + }; + + udev = udev_new(); + if (udev == NULL) + goto exit; + + log_open(); + udev_set_log_fn(udev, log_fn); + + while (1) { + int option; + + option = getopt_long(argc, argv, "xh", options, NULL); + if (option == -1) + break; + + switch (option) { + case 'x': + export = 1; + break; + case 'h': + printf("Usage: ata_id [--export] [--help] \n" + " --export print values as environment keys\n" + " --help print this help text\n\n"); + goto exit; + } + } + + node = argv[optind]; + if (node == NULL) { + log_error("no node specified\n"); + rc = 1; + goto exit; + } + + fd = open(node, O_RDONLY|O_NONBLOCK); + if (fd < 0) { + log_error("unable to open '%s'\n", node); + rc = 1; + goto exit; + } + + if (disk_identify(udev, fd, identify, &is_packet_device) == 0) { + /* + * fix up only the fields from the IDENTIFY data that we are going to + * use and copy it into the hd_driveid struct for convenience + */ + disk_identify_fixup_string(identify, 10, 20); /* serial */ + disk_identify_fixup_string(identify, 23, 8); /* fwrev */ + disk_identify_fixup_string(identify, 27, 40); /* model */ + disk_identify_fixup_uint16(identify, 0); /* configuration */ + disk_identify_fixup_uint16(identify, 75); /* queue depth */ + disk_identify_fixup_uint16(identify, 75); /* SATA capabilities */ + disk_identify_fixup_uint16(identify, 82); /* command set supported */ + disk_identify_fixup_uint16(identify, 83); /* command set supported */ + disk_identify_fixup_uint16(identify, 84); /* command set supported */ + disk_identify_fixup_uint16(identify, 85); /* command set supported */ + disk_identify_fixup_uint16(identify, 86); /* command set supported */ + disk_identify_fixup_uint16(identify, 87); /* command set supported */ + disk_identify_fixup_uint16(identify, 89); /* time required for SECURITY ERASE UNIT */ + disk_identify_fixup_uint16(identify, 90); /* time required for enhanced SECURITY ERASE UNIT */ + disk_identify_fixup_uint16(identify, 91); /* current APM values */ + disk_identify_fixup_uint16(identify, 94); /* current AAM value */ + disk_identify_fixup_uint16(identify, 128); /* device lock function */ + disk_identify_fixup_uint16(identify, 217); /* nominal media rotation rate */ + memcpy(&id, identify, sizeof id); + } else { + /* If this fails, then try HDIO_GET_IDENTITY */ + if (ioctl(fd, HDIO_GET_IDENTITY, &id) != 0) { + log_info("HDIO_GET_IDENTITY failed for '%s': %m\n", node); + rc = 2; + goto close; + } + } + identify_words = (uint16_t *) identify; + + memcpy (model, id.model, 40); + model[40] = '\0'; + udev_util_encode_string(model, model_enc, sizeof(model_enc)); + util_replace_whitespace((char *) id.model, model, 40); + util_replace_chars(model, NULL); + util_replace_whitespace((char *) id.serial_no, serial, 20); + util_replace_chars(serial, NULL); + util_replace_whitespace((char *) id.fw_rev, revision, 8); + util_replace_chars(revision, NULL); + + if (export) { + /* Set this to convey the disk speaks the ATA protocol */ + printf("ID_ATA=1\n"); + + if ((id.config >> 8) & 0x80) { + /* This is an ATAPI device */ + switch ((id.config >> 8) & 0x1f) { + case 0: + printf("ID_TYPE=cd\n"); + break; + case 1: + printf("ID_TYPE=tape\n"); + break; + case 5: + printf("ID_TYPE=cd\n"); + break; + case 7: + printf("ID_TYPE=optical\n"); + break; + default: + printf("ID_TYPE=generic\n"); + break; + } + } else { + printf("ID_TYPE=disk\n"); + } + printf("ID_BUS=ata\n"); + printf("ID_MODEL=%s\n", model); + printf("ID_MODEL_ENC=%s\n", model_enc); + printf("ID_REVISION=%s\n", revision); + if (serial[0] != '\0') { + printf("ID_SERIAL=%s_%s\n", model, serial); + printf("ID_SERIAL_SHORT=%s\n", serial); + } else { + printf("ID_SERIAL=%s\n", model); + } + + if (id.command_set_1 & (1<<5)) { + printf ("ID_ATA_WRITE_CACHE=1\n"); + printf ("ID_ATA_WRITE_CACHE_ENABLED=%d\n", (id.cfs_enable_1 & (1<<5)) ? 1 : 0); + } + if (id.command_set_1 & (1<<10)) { + printf("ID_ATA_FEATURE_SET_HPA=1\n"); + printf("ID_ATA_FEATURE_SET_HPA_ENABLED=%d\n", (id.cfs_enable_1 & (1<<10)) ? 1 : 0); + + /* + * TODO: use the READ NATIVE MAX ADDRESS command to get the native max address + * so it is easy to check whether the protected area is in use. + */ + } + if (id.command_set_1 & (1<<3)) { + printf("ID_ATA_FEATURE_SET_PM=1\n"); + printf("ID_ATA_FEATURE_SET_PM_ENABLED=%d\n", (id.cfs_enable_1 & (1<<3)) ? 1 : 0); + } + if (id.command_set_1 & (1<<1)) { + printf("ID_ATA_FEATURE_SET_SECURITY=1\n"); + printf("ID_ATA_FEATURE_SET_SECURITY_ENABLED=%d\n", (id.cfs_enable_1 & (1<<1)) ? 1 : 0); + printf("ID_ATA_FEATURE_SET_SECURITY_ERASE_UNIT_MIN=%d\n", id.trseuc * 2); + if ((id.cfs_enable_1 & (1<<1))) /* enabled */ { + if (id.dlf & (1<<8)) + printf("ID_ATA_FEATURE_SET_SECURITY_LEVEL=maximum\n"); + else + printf("ID_ATA_FEATURE_SET_SECURITY_LEVEL=high\n"); + } + if (id.dlf & (1<<5)) + printf("ID_ATA_FEATURE_SET_SECURITY_ENHANCED_ERASE_UNIT_MIN=%d\n", id.trsEuc * 2); + if (id.dlf & (1<<4)) + printf("ID_ATA_FEATURE_SET_SECURITY_EXPIRE=1\n"); + if (id.dlf & (1<<3)) + printf("ID_ATA_FEATURE_SET_SECURITY_FROZEN=1\n"); + if (id.dlf & (1<<2)) + printf("ID_ATA_FEATURE_SET_SECURITY_LOCKED=1\n"); + } + if (id.command_set_1 & (1<<0)) { + printf("ID_ATA_FEATURE_SET_SMART=1\n"); + printf("ID_ATA_FEATURE_SET_SMART_ENABLED=%d\n", (id.cfs_enable_1 & (1<<0)) ? 1 : 0); + } + if (id.command_set_2 & (1<<9)) { + printf("ID_ATA_FEATURE_SET_AAM=1\n"); + printf("ID_ATA_FEATURE_SET_AAM_ENABLED=%d\n", (id.cfs_enable_2 & (1<<9)) ? 1 : 0); + printf("ID_ATA_FEATURE_SET_AAM_VENDOR_RECOMMENDED_VALUE=%d\n", id.acoustic >> 8); + printf("ID_ATA_FEATURE_SET_AAM_CURRENT_VALUE=%d\n", id.acoustic & 0xff); + } + if (id.command_set_2 & (1<<5)) { + printf("ID_ATA_FEATURE_SET_PUIS=1\n"); + printf("ID_ATA_FEATURE_SET_PUIS_ENABLED=%d\n", (id.cfs_enable_2 & (1<<5)) ? 1 : 0); + } + if (id.command_set_2 & (1<<3)) { + printf("ID_ATA_FEATURE_SET_APM=1\n"); + printf("ID_ATA_FEATURE_SET_APM_ENABLED=%d\n", (id.cfs_enable_2 & (1<<3)) ? 1 : 0); + if ((id.cfs_enable_2 & (1<<3))) + printf("ID_ATA_FEATURE_SET_APM_CURRENT_VALUE=%d\n", id.CurAPMvalues & 0xff); + } + if (id.command_set_2 & (1<<0)) + printf("ID_ATA_DOWNLOAD_MICROCODE=1\n"); + + /* + * Word 76 indicates the capabilities of a SATA device. A PATA device shall set + * word 76 to 0000h or FFFFh. If word 76 is set to 0000h or FFFFh, then + * the device does not claim compliance with the Serial ATA specification and words + * 76 through 79 are not valid and shall be ignored. + */ + word = *((uint16_t *) identify + 76); + if (word != 0x0000 && word != 0xffff) { + printf("ID_ATA_SATA=1\n"); + /* + * If bit 2 of word 76 is set to one, then the device supports the Gen2 + * signaling rate of 3.0 Gb/s (see SATA 2.6). + * + * If bit 1 of word 76 is set to one, then the device supports the Gen1 + * signaling rate of 1.5 Gb/s (see SATA 2.6). + */ + if (word & (1<<2)) + printf("ID_ATA_SATA_SIGNAL_RATE_GEN2=1\n"); + if (word & (1<<1)) + printf("ID_ATA_SATA_SIGNAL_RATE_GEN1=1\n"); + } + + /* Word 217 indicates the nominal media rotation rate of the device */ + word = *((uint16_t *) identify + 217); + if (word != 0x0000) { + if (word == 0x0001) { + printf ("ID_ATA_ROTATION_RATE_RPM=0\n"); /* non-rotating e.g. SSD */ + } else if (word >= 0x0401 && word <= 0xfffe) { + printf ("ID_ATA_ROTATION_RATE_RPM=%d\n", word); + } + } + + /* + * Words 108-111 contain a mandatory World Wide Name (WWN) in the NAA IEEE Registered identifier + * format. Word 108 bits (15:12) shall contain 5h, indicating that the naming authority is IEEE. + * All other values are reserved. + */ + word = *((uint16_t *) identify + 108); + if ((word & 0xf000) == 0x5000) { + uint64_t wwwn; + + wwwn = *((uint16_t *) identify + 108); + wwwn <<= 16; + wwwn |= *((uint16_t *) identify + 109); + wwwn <<= 16; + wwwn |= *((uint16_t *) identify + 110); + wwwn <<= 16; + wwwn |= *((uint16_t *) identify + 111); + printf("ID_WWN=0x%llx\n", (unsigned long long int) wwwn); + /* ATA devices have no vendor extension */ + printf("ID_WWN_WITH_EXTENSION=0x%llx\n", (unsigned long long int) wwwn); + } + + /* from Linux's include/linux/ata.h */ + if (identify_words[0] == 0x848a || identify_words[0] == 0x844a) { + printf("ID_ATA_CFA=1\n"); + } else { + if ((identify_words[83] & 0xc004) == 0x4004) { + printf("ID_ATA_CFA=1\n"); + } + } + } else { + if (serial[0] != '\0') + printf("%s_%s\n", model, serial); + else + printf("%s\n", model); + } +close: + close(fd); +exit: + udev_unref(udev); + log_close(); + return rc; +} diff --git a/src/udev/cdrom_id/cdrom_id.c b/src/udev/cdrom_id/cdrom_id.c new file mode 100644 index 000000000..1056536b7 --- /dev/null +++ b/src/udev/cdrom_id/cdrom_id.c @@ -0,0 +1,1099 @@ +/* + * cdrom_id - optical drive and media information prober + * + * Copyright (C) 2008-2010 Kay Sievers + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE 1 +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "libudev.h" +#include "libudev-private.h" + +static bool debug; + +static void log_fn(struct udev *udev, int priority, + const char *file, int line, const char *fn, + const char *format, va_list args) +{ + if (debug) { + fprintf(stderr, "%s: ", fn); + vfprintf(stderr, format, args); + } else { + vsyslog(priority, format, args); + } +} + +/* device info */ +static unsigned int cd_cd_rom; +static unsigned int cd_cd_r; +static unsigned int cd_cd_rw; +static unsigned int cd_dvd_rom; +static unsigned int cd_dvd_r; +static unsigned int cd_dvd_rw; +static unsigned int cd_dvd_ram; +static unsigned int cd_dvd_plus_r; +static unsigned int cd_dvd_plus_rw; +static unsigned int cd_dvd_plus_r_dl; +static unsigned int cd_dvd_plus_rw_dl; +static unsigned int cd_bd; +static unsigned int cd_bd_r; +static unsigned int cd_bd_re; +static unsigned int cd_hddvd; +static unsigned int cd_hddvd_r; +static unsigned int cd_hddvd_rw; +static unsigned int cd_mo; +static unsigned int cd_mrw; +static unsigned int cd_mrw_w; + +/* media info */ +static unsigned int cd_media; +static unsigned int cd_media_cd_rom; +static unsigned int cd_media_cd_r; +static unsigned int cd_media_cd_rw; +static unsigned int cd_media_dvd_rom; +static unsigned int cd_media_dvd_r; +static unsigned int cd_media_dvd_rw; +static unsigned int cd_media_dvd_rw_ro; /* restricted overwrite mode */ +static unsigned int cd_media_dvd_rw_seq; /* sequential mode */ +static unsigned int cd_media_dvd_ram; +static unsigned int cd_media_dvd_plus_r; +static unsigned int cd_media_dvd_plus_rw; +static unsigned int cd_media_dvd_plus_r_dl; +static unsigned int cd_media_dvd_plus_rw_dl; +static unsigned int cd_media_bd; +static unsigned int cd_media_bd_r; +static unsigned int cd_media_bd_re; +static unsigned int cd_media_hddvd; +static unsigned int cd_media_hddvd_r; +static unsigned int cd_media_hddvd_rw; +static unsigned int cd_media_mo; +static unsigned int cd_media_mrw; +static unsigned int cd_media_mrw_w; + +static const char *cd_media_state = NULL; +static unsigned int cd_media_session_next; +static unsigned int cd_media_session_count; +static unsigned int cd_media_track_count; +static unsigned int cd_media_track_count_data; +static unsigned int cd_media_track_count_audio; +static unsigned long long int cd_media_session_last_offset; + +#define ERRCODE(s) ((((s)[2] & 0x0F) << 16) | ((s)[12] << 8) | ((s)[13])) +#define SK(errcode) (((errcode) >> 16) & 0xF) +#define ASC(errcode) (((errcode) >> 8) & 0xFF) +#define ASCQ(errcode) ((errcode) & 0xFF) + +static bool is_mounted(const char *device) +{ + struct stat statbuf; + FILE *fp; + int maj, min; + bool mounted = false; + + if (stat(device, &statbuf) < 0) + return -ENODEV; + + fp = fopen("/proc/self/mountinfo", "re"); + if (fp == NULL) + return -ENOSYS; + while (fscanf(fp, "%*s %*s %i:%i %*[^\n]", &maj, &min) == 2) { + if (makedev(maj, min) == statbuf.st_rdev) { + mounted = true; + break; + } + } + fclose(fp); + return mounted; +} + +static void info_scsi_cmd_err(struct udev *udev, const char *cmd, int err) +{ + if (err == -1) { + log_debug("%s failed\n", cmd); + return; + } + log_debug("%s failed with SK=%Xh/ASC=%02Xh/ACQ=%02Xh\n", cmd, SK(err), ASC(err), ASCQ(err)); +} + +struct scsi_cmd { + struct cdrom_generic_command cgc; + union { + struct request_sense s; + unsigned char u[18]; + } _sense; + struct sg_io_hdr sg_io; +}; + +static void scsi_cmd_init(struct udev *udev, struct scsi_cmd *cmd) +{ + memset(cmd, 0x00, sizeof(struct scsi_cmd)); + cmd->cgc.quiet = 1; + cmd->cgc.sense = &cmd->_sense.s; + cmd->sg_io.interface_id = 'S'; + cmd->sg_io.mx_sb_len = sizeof(cmd->_sense); + cmd->sg_io.cmdp = cmd->cgc.cmd; + cmd->sg_io.sbp = cmd->_sense.u; + cmd->sg_io.flags = SG_FLAG_LUN_INHIBIT | SG_FLAG_DIRECT_IO; +} + +static void scsi_cmd_set(struct udev *udev, struct scsi_cmd *cmd, size_t i, unsigned char arg) +{ + cmd->sg_io.cmd_len = i + 1; + cmd->cgc.cmd[i] = arg; +} + +#define CHECK_CONDITION 0x01 + +static int scsi_cmd_run(struct udev *udev, struct scsi_cmd *cmd, int fd, unsigned char *buf, size_t bufsize) +{ + int ret = 0; + + if (bufsize > 0) { + cmd->sg_io.dxferp = buf; + cmd->sg_io.dxfer_len = bufsize; + cmd->sg_io.dxfer_direction = SG_DXFER_FROM_DEV; + } else { + cmd->sg_io.dxfer_direction = SG_DXFER_NONE; + } + if (ioctl(fd, SG_IO, &cmd->sg_io)) + return -1; + + if ((cmd->sg_io.info & SG_INFO_OK_MASK) != SG_INFO_OK) { + errno = EIO; + ret = -1; + if (cmd->sg_io.masked_status & CHECK_CONDITION) { + ret = ERRCODE(cmd->_sense.u); + if (ret == 0) + ret = -1; + } + } + return ret; +} + +static int media_lock(struct udev *udev, int fd, bool lock) +{ + int err; + + /* disable the kernel's lock logic */ + err = ioctl(fd, CDROM_CLEAR_OPTIONS, CDO_LOCK); + if (err < 0) + log_debug("CDROM_CLEAR_OPTIONS, CDO_LOCK failed\n"); + + err = ioctl(fd, CDROM_LOCKDOOR, lock ? 1 : 0); + if (err < 0) + log_debug("CDROM_LOCKDOOR failed\n"); + + return err; +} + +static int media_eject(struct udev *udev, int fd) +{ + struct scsi_cmd sc; + int err; + + scsi_cmd_init(udev, &sc); + scsi_cmd_set(udev, &sc, 0, 0x1b); + scsi_cmd_set(udev, &sc, 4, 0x02); + scsi_cmd_set(udev, &sc, 5, 0); + err = scsi_cmd_run(udev, &sc, fd, NULL, 0); + if ((err != 0)) { + info_scsi_cmd_err(udev, "START_STOP_UNIT", err); + return -1; + } + return 0; +} + +static int cd_capability_compat(struct udev *udev, int fd) +{ + int capability; + + capability = ioctl(fd, CDROM_GET_CAPABILITY, NULL); + if (capability < 0) { + log_debug("CDROM_GET_CAPABILITY failed\n"); + return -1; + } + + if (capability & CDC_CD_R) + cd_cd_r = 1; + if (capability & CDC_CD_RW) + cd_cd_rw = 1; + if (capability & CDC_DVD) + cd_dvd_rom = 1; + if (capability & CDC_DVD_R) + cd_dvd_r = 1; + if (capability & CDC_DVD_RAM) + cd_dvd_ram = 1; + if (capability & CDC_MRW) + cd_mrw = 1; + if (capability & CDC_MRW_W) + cd_mrw_w = 1; + return 0; +} + +static int cd_media_compat(struct udev *udev, int fd) +{ + if (ioctl(fd, CDROM_DRIVE_STATUS, CDSL_CURRENT) != CDS_DISC_OK) { + log_debug("CDROM_DRIVE_STATUS != CDS_DISC_OK\n"); + return -1; + } + cd_media = 1; + return 0; +} + +static int cd_inquiry(struct udev *udev, int fd) +{ + struct scsi_cmd sc; + unsigned char inq[128]; + int err; + + scsi_cmd_init(udev, &sc); + scsi_cmd_set(udev, &sc, 0, 0x12); + scsi_cmd_set(udev, &sc, 4, 36); + scsi_cmd_set(udev, &sc, 5, 0); + err = scsi_cmd_run(udev, &sc, fd, inq, 36); + if ((err != 0)) { + info_scsi_cmd_err(udev, "INQUIRY", err); + return -1; + } + + if ((inq[0] & 0x1F) != 5) { + log_debug("not an MMC unit\n"); + return -1; + } + + log_debug("INQUIRY: [%.8s][%.16s][%.4s]\n", inq + 8, inq + 16, inq + 32); + return 0; +} + +static void feature_profile_media(struct udev *udev, int cur_profile) +{ + switch (cur_profile) { + case 0x03: + case 0x04: + case 0x05: + log_debug("profile 0x%02x \n", cur_profile); + cd_media = 1; + cd_media_mo = 1; + break; + case 0x08: + log_debug("profile 0x%02x media_cd_rom\n", cur_profile); + cd_media = 1; + cd_media_cd_rom = 1; + break; + case 0x09: + log_debug("profile 0x%02x media_cd_r\n", cur_profile); + cd_media = 1; + cd_media_cd_r = 1; + break; + case 0x0a: + log_debug("profile 0x%02x media_cd_rw\n", cur_profile); + cd_media = 1; + cd_media_cd_rw = 1; + break; + case 0x10: + log_debug("profile 0x%02x media_dvd_ro\n", cur_profile); + cd_media = 1; + cd_media_dvd_rom = 1; + break; + case 0x11: + log_debug("profile 0x%02x media_dvd_r\n", cur_profile); + cd_media = 1; + cd_media_dvd_r = 1; + break; + case 0x12: + log_debug("profile 0x%02x media_dvd_ram\n", cur_profile); + cd_media = 1; + cd_media_dvd_ram = 1; + break; + case 0x13: + log_debug("profile 0x%02x media_dvd_rw_ro\n", cur_profile); + cd_media = 1; + cd_media_dvd_rw = 1; + cd_media_dvd_rw_ro = 1; + break; + case 0x14: + log_debug("profile 0x%02x media_dvd_rw_seq\n", cur_profile); + cd_media = 1; + cd_media_dvd_rw = 1; + cd_media_dvd_rw_seq = 1; + break; + case 0x1B: + log_debug("profile 0x%02x media_dvd_plus_r\n", cur_profile); + cd_media = 1; + cd_media_dvd_plus_r = 1; + break; + case 0x1A: + log_debug("profile 0x%02x media_dvd_plus_rw\n", cur_profile); + cd_media = 1; + cd_media_dvd_plus_rw = 1; + break; + case 0x2A: + log_debug("profile 0x%02x media_dvd_plus_rw_dl\n", cur_profile); + cd_media = 1; + cd_media_dvd_plus_rw_dl = 1; + break; + case 0x2B: + log_debug("profile 0x%02x media_dvd_plus_r_dl\n", cur_profile); + cd_media = 1; + cd_media_dvd_plus_r_dl = 1; + break; + case 0x40: + log_debug("profile 0x%02x media_bd\n", cur_profile); + cd_media = 1; + cd_media_bd = 1; + break; + case 0x41: + case 0x42: + log_debug("profile 0x%02x media_bd_r\n", cur_profile); + cd_media = 1; + cd_media_bd_r = 1; + break; + case 0x43: + log_debug("profile 0x%02x media_bd_re\n", cur_profile); + cd_media = 1; + cd_media_bd_re = 1; + break; + case 0x50: + log_debug("profile 0x%02x media_hddvd\n", cur_profile); + cd_media = 1; + cd_media_hddvd = 1; + break; + case 0x51: + log_debug("profile 0x%02x media_hddvd_r\n", cur_profile); + cd_media = 1; + cd_media_hddvd_r = 1; + break; + case 0x52: + log_debug("profile 0x%02x media_hddvd_rw\n", cur_profile); + cd_media = 1; + cd_media_hddvd_rw = 1; + break; + default: + log_debug("profile 0x%02x \n", cur_profile); + break; + } +} + +static int feature_profiles(struct udev *udev, const unsigned char *profiles, size_t size) +{ + unsigned int i; + + for (i = 0; i+4 <= size; i += 4) { + int profile; + + profile = profiles[i] << 8 | profiles[i+1]; + switch (profile) { + case 0x03: + case 0x04: + case 0x05: + log_debug("profile 0x%02x mo\n", profile); + cd_mo = 1; + break; + case 0x08: + log_debug("profile 0x%02x cd_rom\n", profile); + cd_cd_rom = 1; + break; + case 0x09: + log_debug("profile 0x%02x cd_r\n", profile); + cd_cd_r = 1; + break; + case 0x0A: + log_debug("profile 0x%02x cd_rw\n", profile); + cd_cd_rw = 1; + break; + case 0x10: + log_debug("profile 0x%02x dvd_rom\n", profile); + cd_dvd_rom = 1; + break; + case 0x12: + log_debug("profile 0x%02x dvd_ram\n", profile); + cd_dvd_ram = 1; + break; + case 0x13: + case 0x14: + log_debug("profile 0x%02x dvd_rw\n", profile); + cd_dvd_rw = 1; + break; + case 0x1B: + log_debug("profile 0x%02x dvd_plus_r\n", profile); + cd_dvd_plus_r = 1; + break; + case 0x1A: + log_debug("profile 0x%02x dvd_plus_rw\n", profile); + cd_dvd_plus_rw = 1; + break; + case 0x2A: + log_debug("profile 0x%02x dvd_plus_rw_dl\n", profile); + cd_dvd_plus_rw_dl = 1; + break; + case 0x2B: + log_debug("profile 0x%02x dvd_plus_r_dl\n", profile); + cd_dvd_plus_r_dl = 1; + break; + case 0x40: + cd_bd = 1; + log_debug("profile 0x%02x bd\n", profile); + break; + case 0x41: + case 0x42: + cd_bd_r = 1; + log_debug("profile 0x%02x bd_r\n", profile); + break; + case 0x43: + cd_bd_re = 1; + log_debug("profile 0x%02x bd_re\n", profile); + break; + case 0x50: + cd_hddvd = 1; + log_debug("profile 0x%02x hddvd\n", profile); + break; + case 0x51: + cd_hddvd_r = 1; + log_debug("profile 0x%02x hddvd_r\n", profile); + break; + case 0x52: + cd_hddvd_rw = 1; + log_debug("profile 0x%02x hddvd_rw\n", profile); + break; + default: + log_debug("profile 0x%02x \n", profile); + break; + } + } + return 0; +} + +/* returns 0 if media was detected */ +static int cd_profiles_old_mmc(struct udev *udev, int fd) +{ + struct scsi_cmd sc; + int err; + + unsigned char header[32]; + + scsi_cmd_init(udev, &sc); + scsi_cmd_set(udev, &sc, 0, 0x51); + scsi_cmd_set(udev, &sc, 8, sizeof(header)); + scsi_cmd_set(udev, &sc, 9, 0); + err = scsi_cmd_run(udev, &sc, fd, header, sizeof(header)); + if ((err != 0)) { + info_scsi_cmd_err(udev, "READ DISC INFORMATION", err); + if (cd_media == 1) { + log_debug("no current profile, but disc is present; assuming CD-ROM\n"); + cd_media_cd_rom = 1; + return 0; + } else { + log_debug("no current profile, assuming no media\n"); + return -1; + } + }; + + cd_media = 1; + + if (header[2] & 16) { + cd_media_cd_rw = 1; + log_debug("profile 0x0a media_cd_rw\n"); + } else if ((header[2] & 3) < 2 && cd_cd_r) { + cd_media_cd_r = 1; + log_debug("profile 0x09 media_cd_r\n"); + } else { + cd_media_cd_rom = 1; + log_debug("profile 0x08 media_cd_rom\n"); + } + return 0; +} + +/* returns 0 if media was detected */ +static int cd_profiles(struct udev *udev, int fd) +{ + struct scsi_cmd sc; + unsigned char features[65530]; + unsigned int cur_profile = 0; + unsigned int len; + unsigned int i; + int err; + int ret; + + ret = -1; + + /* First query the current profile */ + scsi_cmd_init(udev, &sc); + scsi_cmd_set(udev, &sc, 0, 0x46); + scsi_cmd_set(udev, &sc, 8, 8); + scsi_cmd_set(udev, &sc, 9, 0); + err = scsi_cmd_run(udev, &sc, fd, features, 8); + if ((err != 0)) { + info_scsi_cmd_err(udev, "GET CONFIGURATION", err); + /* handle pre-MMC2 drives which do not support GET CONFIGURATION */ + if (SK(err) == 0x5 && ASC(err) == 0x20) { + log_debug("drive is pre-MMC2 and does not support 46h get configuration command\n"); + log_debug("trying to work around the problem\n"); + ret = cd_profiles_old_mmc(udev, fd); + } + goto out; + } + + cur_profile = features[6] << 8 | features[7]; + if (cur_profile > 0) { + log_debug("current profile 0x%02x\n", cur_profile); + feature_profile_media (udev, cur_profile); + ret = 0; /* we have media */ + } else { + log_debug("no current profile, assuming no media\n"); + } + + len = features[0] << 24 | features[1] << 16 | features[2] << 8 | features[3]; + log_debug("GET CONFIGURATION: size of features buffer 0x%04x\n", len); + + if (len > sizeof(features)) { + log_debug("can not get features in a single query, truncating\n"); + len = sizeof(features); + } else if (len <= 8) { + len = sizeof(features); + } + + /* Now get the full feature buffer */ + scsi_cmd_init(udev, &sc); + scsi_cmd_set(udev, &sc, 0, 0x46); + scsi_cmd_set(udev, &sc, 7, ( len >> 8 ) & 0xff); + scsi_cmd_set(udev, &sc, 8, len & 0xff); + scsi_cmd_set(udev, &sc, 9, 0); + err = scsi_cmd_run(udev, &sc, fd, features, len); + if ((err != 0)) { + info_scsi_cmd_err(udev, "GET CONFIGURATION", err); + return -1; + } + + /* parse the length once more, in case the drive decided to have other features suddenly :) */ + len = features[0] << 24 | features[1] << 16 | features[2] << 8 | features[3]; + log_debug("GET CONFIGURATION: size of features buffer 0x%04x\n", len); + + if (len > sizeof(features)) { + log_debug("can not get features in a single query, truncating\n"); + len = sizeof(features); + } + + /* device features */ + for (i = 8; i+4 < len; i += (4 + features[i+3])) { + unsigned int feature; + + feature = features[i] << 8 | features[i+1]; + + switch (feature) { + case 0x00: + log_debug("GET CONFIGURATION: feature 'profiles', with %i entries\n", features[i+3] / 4); + feature_profiles(udev, &features[i]+4, features[i+3]); + break; + default: + log_debug("GET CONFIGURATION: feature 0x%04x , with 0x%02x bytes\n", feature, features[i+3]); + break; + } + } +out: + return ret; +} + +static int cd_media_info(struct udev *udev, int fd) +{ + struct scsi_cmd sc; + unsigned char header[32]; + static const char *media_status[] = { + "blank", + "appendable", + "complete", + "other" + }; + int err; + + scsi_cmd_init(udev, &sc); + scsi_cmd_set(udev, &sc, 0, 0x51); + scsi_cmd_set(udev, &sc, 8, sizeof(header) & 0xff); + scsi_cmd_set(udev, &sc, 9, 0); + err = scsi_cmd_run(udev, &sc, fd, header, sizeof(header)); + if ((err != 0)) { + info_scsi_cmd_err(udev, "READ DISC INFORMATION", err); + return -1; + }; + + cd_media = 1; + log_debug("disk type %02x\n", header[8]); + log_debug("hardware reported media status: %s\n", media_status[header[2] & 3]); + + /* exclude plain CDROM, some fake cdroms return 0 for "blank" media here */ + if (!cd_media_cd_rom) + cd_media_state = media_status[header[2] & 3]; + + /* fresh DVD-RW in restricted overwite mode reports itself as + * "appendable"; change it to "blank" to make it consistent with what + * gets reported after blanking, and what userspace expects */ + if (cd_media_dvd_rw_ro && (header[2] & 3) == 1) + cd_media_state = media_status[0]; + + /* DVD+RW discs (and DVD-RW in restricted mode) once formatted are + * always "complete", DVD-RAM are "other" or "complete" if the disc is + * write protected; we need to check the contents if it is blank */ + if ((cd_media_dvd_rw_ro || cd_media_dvd_plus_rw || cd_media_dvd_plus_rw_dl || cd_media_dvd_ram) && (header[2] & 3) > 1) { + unsigned char buffer[32 * 2048]; + unsigned char result, len; + int block, offset; + + if (cd_media_dvd_ram) { + /* a write protected dvd-ram may report "complete" status */ + + unsigned char dvdstruct[8]; + unsigned char format[12]; + + scsi_cmd_init(udev, &sc); + scsi_cmd_set(udev, &sc, 0, 0xAD); + scsi_cmd_set(udev, &sc, 7, 0xC0); + scsi_cmd_set(udev, &sc, 9, sizeof(dvdstruct)); + scsi_cmd_set(udev, &sc, 11, 0); + err = scsi_cmd_run(udev, &sc, fd, dvdstruct, sizeof(dvdstruct)); + if ((err != 0)) { + info_scsi_cmd_err(udev, "READ DVD STRUCTURE", err); + return -1; + } + if (dvdstruct[4] & 0x02) { + cd_media_state = media_status[2]; + log_debug("write-protected DVD-RAM media inserted\n"); + goto determined; + } + + /* let's make sure we don't try to read unformatted media */ + scsi_cmd_init(udev, &sc); + scsi_cmd_set(udev, &sc, 0, 0x23); + scsi_cmd_set(udev, &sc, 8, sizeof(format)); + scsi_cmd_set(udev, &sc, 9, 0); + err = scsi_cmd_run(udev, &sc, fd, format, sizeof(format)); + if ((err != 0)) { + info_scsi_cmd_err(udev, "READ DVD FORMAT CAPACITIES", err); + return -1; + } + + len = format[3]; + if (len & 7 || len < 16) { + log_debug("invalid format capacities length\n"); + return -1; + } + + switch(format[8] & 3) { + case 1: + log_debug("unformatted DVD-RAM media inserted\n"); + /* This means that last format was interrupted + * or failed, blank dvd-ram discs are factory + * formatted. Take no action here as it takes + * quite a while to reformat a dvd-ram and it's + * not automatically started */ + goto determined; + + case 2: + log_debug("formatted DVD-RAM media inserted\n"); + break; + + case 3: + cd_media = 0; //return no media + log_debug("format capacities returned no media\n"); + return -1; + } + } + + /* Take a closer look at formatted media (unformatted DVD+RW + * has "blank" status", DVD-RAM was examined earlier) and check + * for ISO and UDF PVDs or a fs superblock presence and do it + * in one ioctl (we need just sectors 0 and 16) */ + scsi_cmd_init(udev, &sc); + scsi_cmd_set(udev, &sc, 0, 0x28); + scsi_cmd_set(udev, &sc, 5, 0); + scsi_cmd_set(udev, &sc, 8, 32); + scsi_cmd_set(udev, &sc, 9, 0); + err = scsi_cmd_run(udev, &sc, fd, buffer, sizeof(buffer)); + if ((err != 0)) { + cd_media = 0; + info_scsi_cmd_err(udev, "READ FIRST 32 BLOCKS", err); + return -1; + } + + /* if any non-zero data is found in sector 16 (iso and udf) or + * eventually 0 (fat32 boot sector, ext2 superblock, etc), disc + * is assumed non-blank */ + result = 0; + + for (block = 32768; block >= 0 && !result; block -= 32768) { + offset = block; + while (offset < (block + 2048) && !result) { + result = buffer [offset]; + offset++; + } + } + + if (!result) { + cd_media_state = media_status[0]; + log_debug("no data in blocks 0 or 16, assuming blank\n"); + } else { + log_debug("data in blocks 0 or 16, assuming complete\n"); + } + } + +determined: + /* "other" is e. g. DVD-RAM, can't append sessions there; DVDs in + * restricted overwrite mode can never append, only in sequential mode */ + if ((header[2] & 3) < 2 && !cd_media_dvd_rw_ro) + cd_media_session_next = header[10] << 8 | header[5]; + cd_media_session_count = header[9] << 8 | header[4]; + cd_media_track_count = header[11] << 8 | header[6]; + + return 0; +} + +static int cd_media_toc(struct udev *udev, int fd) +{ + struct scsi_cmd sc; + unsigned char header[12]; + unsigned char toc[65536]; + unsigned int len, i, num_tracks; + unsigned char *p; + int err; + + scsi_cmd_init(udev, &sc); + scsi_cmd_set(udev, &sc, 0, 0x43); + scsi_cmd_set(udev, &sc, 6, 1); + scsi_cmd_set(udev, &sc, 8, sizeof(header) & 0xff); + scsi_cmd_set(udev, &sc, 9, 0); + err = scsi_cmd_run(udev, &sc, fd, header, sizeof(header)); + if ((err != 0)) { + info_scsi_cmd_err(udev, "READ TOC", err); + return -1; + } + + len = (header[0] << 8 | header[1]) + 2; + log_debug("READ TOC: len: %d, start track: %d, end track: %d\n", len, header[2], header[3]); + if (len > sizeof(toc)) + return -1; + if (len < 2) + return -1; + /* 2: first track, 3: last track */ + num_tracks = header[3] - header[2] + 1; + + /* empty media has no tracks */ + if (len < 8) + return 0; + + scsi_cmd_init(udev, &sc); + scsi_cmd_set(udev, &sc, 0, 0x43); + scsi_cmd_set(udev, &sc, 6, header[2]); /* First Track/Session Number */ + scsi_cmd_set(udev, &sc, 7, (len >> 8) & 0xff); + scsi_cmd_set(udev, &sc, 8, len & 0xff); + scsi_cmd_set(udev, &sc, 9, 0); + err = scsi_cmd_run(udev, &sc, fd, toc, len); + if ((err != 0)) { + info_scsi_cmd_err(udev, "READ TOC (tracks)", err); + return -1; + } + + /* Take care to not iterate beyond the last valid track as specified in + * the TOC, but also avoid going beyond the TOC length, just in case + * the last track number is invalidly large */ + for (p = toc+4, i = 4; i < len-8 && num_tracks > 0; i += 8, p += 8, --num_tracks) { + unsigned int block; + unsigned int is_data_track; + + is_data_track = (p[1] & 0x04) != 0; + + block = p[4] << 24 | p[5] << 16 | p[6] << 8 | p[7]; + log_debug("track=%u info=0x%x(%s) start_block=%u\n", + p[2], p[1] & 0x0f, is_data_track ? "data":"audio", block); + + if (is_data_track) + cd_media_track_count_data++; + else + cd_media_track_count_audio++; + } + + scsi_cmd_init(udev, &sc); + scsi_cmd_set(udev, &sc, 0, 0x43); + scsi_cmd_set(udev, &sc, 2, 1); /* Session Info */ + scsi_cmd_set(udev, &sc, 8, sizeof(header)); + scsi_cmd_set(udev, &sc, 9, 0); + err = scsi_cmd_run(udev, &sc, fd, header, sizeof(header)); + if ((err != 0)) { + info_scsi_cmd_err(udev, "READ TOC (multi session)", err); + return -1; + } + len = header[4+4] << 24 | header[4+5] << 16 | header[4+6] << 8 | header[4+7]; + log_debug("last track %u starts at block %u\n", header[4+2], len); + cd_media_session_last_offset = (unsigned long long int)len * 2048; + return 0; +} + +int main(int argc, char *argv[]) +{ + struct udev *udev; + static const struct option options[] = { + { "lock-media", no_argument, NULL, 'l' }, + { "unlock-media", no_argument, NULL, 'u' }, + { "eject-media", no_argument, NULL, 'e' }, + { "debug", no_argument, NULL, 'd' }, + { "help", no_argument, NULL, 'h' }, + {} + }; + bool eject = false; + bool lock = false; + bool unlock = false; + const char *node = NULL; + int fd = -1; + int cnt; + int rc = 0; + + udev = udev_new(); + if (udev == NULL) + goto exit; + + log_open(); + udev_set_log_fn(udev, log_fn); + + while (1) { + int option; + + option = getopt_long(argc, argv, "deluh", options, NULL); + if (option == -1) + break; + + switch (option) { + case 'l': + lock = true; + break; + case 'u': + unlock = true; + break; + case 'e': + eject = true; + break; + case 'd': + debug = true; + log_set_max_level(LOG_DEBUG); + udev_set_log_priority(udev, LOG_DEBUG); + break; + case 'h': + printf("Usage: cdrom_id [options] \n" + " --lock-media lock the media (to enable eject request events)\n" + " --unlock-media unlock the media\n" + " --eject-media eject the media\n" + " --debug debug to stderr\n" + " --help print this help text\n\n"); + goto exit; + default: + rc = 1; + goto exit; + } + } + + node = argv[optind]; + if (!node) { + log_error("no device\n"); + fprintf(stderr, "no device\n"); + rc = 1; + goto exit; + } + + srand((unsigned int)getpid()); + for (cnt = 20; cnt > 0; cnt--) { + struct timespec duration; + + fd = open(node, O_RDONLY|O_NONBLOCK|(is_mounted(node) ? 0 : O_EXCL)); + if (fd >= 0 || errno != EBUSY) + break; + duration.tv_sec = 0; + duration.tv_nsec = (100 * 1000 * 1000) + (rand() % 100 * 1000 * 1000); + nanosleep(&duration, NULL); + } + if (fd < 0) { + log_debug("unable to open '%s'\n", node); + fprintf(stderr, "unable to open '%s'\n", node); + rc = 1; + goto exit; + } + log_debug("probing: '%s'\n", node); + + /* same data as original cdrom_id */ + if (cd_capability_compat(udev, fd) < 0) { + rc = 1; + goto exit; + } + + /* check for media - don't bail if there's no media as we still need to + * to read profiles */ + cd_media_compat(udev, fd); + + /* check if drive talks MMC */ + if (cd_inquiry(udev, fd) < 0) + goto work; + + /* read drive and possibly current profile */ + if (cd_profiles(udev, fd) != 0) + goto work; + + /* at this point we are guaranteed to have media in the drive - find out more about it */ + + /* get session/track info */ + cd_media_toc(udev, fd); + + /* get writable media state */ + cd_media_info(udev, fd); + +work: + /* lock the media, so we enable eject button events */ + if (lock && cd_media) { + log_debug("PREVENT_ALLOW_MEDIUM_REMOVAL (lock)\n"); + media_lock(udev, fd, true); + } + + if (unlock && cd_media) { + log_debug("PREVENT_ALLOW_MEDIUM_REMOVAL (unlock)\n"); + media_lock(udev, fd, false); + } + + if (eject) { + log_debug("PREVENT_ALLOW_MEDIUM_REMOVAL (unlock)\n"); + media_lock(udev, fd, false); + log_debug("START_STOP_UNIT (eject)\n"); + media_eject(udev, fd); + } + + printf("ID_CDROM=1\n"); + if (cd_cd_rom) + printf("ID_CDROM_CD=1\n"); + if (cd_cd_r) + printf("ID_CDROM_CD_R=1\n"); + if (cd_cd_rw) + printf("ID_CDROM_CD_RW=1\n"); + if (cd_dvd_rom) + printf("ID_CDROM_DVD=1\n"); + if (cd_dvd_r) + printf("ID_CDROM_DVD_R=1\n"); + if (cd_dvd_rw) + printf("ID_CDROM_DVD_RW=1\n"); + if (cd_dvd_ram) + printf("ID_CDROM_DVD_RAM=1\n"); + if (cd_dvd_plus_r) + printf("ID_CDROM_DVD_PLUS_R=1\n"); + if (cd_dvd_plus_rw) + printf("ID_CDROM_DVD_PLUS_RW=1\n"); + if (cd_dvd_plus_r_dl) + printf("ID_CDROM_DVD_PLUS_R_DL=1\n"); + if (cd_dvd_plus_rw_dl) + printf("ID_CDROM_DVD_PLUS_RW_DL=1\n"); + if (cd_bd) + printf("ID_CDROM_BD=1\n"); + if (cd_bd_r) + printf("ID_CDROM_BD_R=1\n"); + if (cd_bd_re) + printf("ID_CDROM_BD_RE=1\n"); + if (cd_hddvd) + printf("ID_CDROM_HDDVD=1\n"); + if (cd_hddvd_r) + printf("ID_CDROM_HDDVD_R=1\n"); + if (cd_hddvd_rw) + printf("ID_CDROM_HDDVD_RW=1\n"); + if (cd_mo) + printf("ID_CDROM_MO=1\n"); + if (cd_mrw) + printf("ID_CDROM_MRW=1\n"); + if (cd_mrw_w) + printf("ID_CDROM_MRW_W=1\n"); + + if (cd_media) + printf("ID_CDROM_MEDIA=1\n"); + if (cd_media_mo) + printf("ID_CDROM_MEDIA_MO=1\n"); + if (cd_media_mrw) + printf("ID_CDROM_MEDIA_MRW=1\n"); + if (cd_media_mrw_w) + printf("ID_CDROM_MEDIA_MRW_W=1\n"); + if (cd_media_cd_rom) + printf("ID_CDROM_MEDIA_CD=1\n"); + if (cd_media_cd_r) + printf("ID_CDROM_MEDIA_CD_R=1\n"); + if (cd_media_cd_rw) + printf("ID_CDROM_MEDIA_CD_RW=1\n"); + if (cd_media_dvd_rom) + printf("ID_CDROM_MEDIA_DVD=1\n"); + if (cd_media_dvd_r) + printf("ID_CDROM_MEDIA_DVD_R=1\n"); + if (cd_media_dvd_ram) + printf("ID_CDROM_MEDIA_DVD_RAM=1\n"); + if (cd_media_dvd_rw) + printf("ID_CDROM_MEDIA_DVD_RW=1\n"); + if (cd_media_dvd_plus_r) + printf("ID_CDROM_MEDIA_DVD_PLUS_R=1\n"); + if (cd_media_dvd_plus_rw) + printf("ID_CDROM_MEDIA_DVD_PLUS_RW=1\n"); + if (cd_media_dvd_plus_rw_dl) + printf("ID_CDROM_MEDIA_DVD_PLUS_RW_DL=1\n"); + if (cd_media_dvd_plus_r_dl) + printf("ID_CDROM_MEDIA_DVD_PLUS_R_DL=1\n"); + if (cd_media_bd) + printf("ID_CDROM_MEDIA_BD=1\n"); + if (cd_media_bd_r) + printf("ID_CDROM_MEDIA_BD_R=1\n"); + if (cd_media_bd_re) + printf("ID_CDROM_MEDIA_BD_RE=1\n"); + if (cd_media_hddvd) + printf("ID_CDROM_MEDIA_HDDVD=1\n"); + if (cd_media_hddvd_r) + printf("ID_CDROM_MEDIA_HDDVD_R=1\n"); + if (cd_media_hddvd_rw) + printf("ID_CDROM_MEDIA_HDDVD_RW=1\n"); + + if (cd_media_state != NULL) + printf("ID_CDROM_MEDIA_STATE=%s\n", cd_media_state); + if (cd_media_session_next > 0) + printf("ID_CDROM_MEDIA_SESSION_NEXT=%d\n", cd_media_session_next); + if (cd_media_session_count > 0) + printf("ID_CDROM_MEDIA_SESSION_COUNT=%d\n", cd_media_session_count); + if (cd_media_session_count > 1 && cd_media_session_last_offset > 0) + printf("ID_CDROM_MEDIA_SESSION_LAST_OFFSET=%llu\n", cd_media_session_last_offset); + if (cd_media_track_count > 0) + printf("ID_CDROM_MEDIA_TRACK_COUNT=%d\n", cd_media_track_count); + if (cd_media_track_count_audio > 0) + printf("ID_CDROM_MEDIA_TRACK_COUNT_AUDIO=%d\n", cd_media_track_count_audio); + if (cd_media_track_count_data > 0) + printf("ID_CDROM_MEDIA_TRACK_COUNT_DATA=%d\n", cd_media_track_count_data); +exit: + if (fd >= 0) + close(fd); + udev_unref(udev); + log_close(); + return rc; +} diff --git a/src/udev/collect/collect.c b/src/udev/collect/collect.c new file mode 100644 index 000000000..3c46e40de --- /dev/null +++ b/src/udev/collect/collect.c @@ -0,0 +1,492 @@ +/* + * Collect variables across events. + * + * usage: collect [--add|--remove] + * + * Adds ID to the list governed by . + * must be part of the ID list . + * If all IDs given by are listed (ie collect has been + * invoked for each ID in ) collect returns 0, the + * number of missing IDs otherwise. + * A negative number is returned on error. + * + * Copyright(C) 2007, Hannes Reinecke + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "libudev.h" +#include "libudev-private.h" +#include "macro.h" + +#define BUFSIZE 16 +#define UDEV_ALARM_TIMEOUT 180 + +enum collect_state { + STATE_NONE, + STATE_OLD, + STATE_CONFIRMED, +}; + +struct _mate { + struct udev_list_node node; + char *name; + enum collect_state state; +}; + +static struct udev_list_node bunch; +static int debug; + +/* This can increase dynamically */ +static size_t bufsize = BUFSIZE; + +static inline struct _mate *node_to_mate(struct udev_list_node *node) +{ + return container_of(node, struct _mate, node); +} + +_noreturn_ static void sig_alrm(int signo) +{ + exit(4); +} + +static void usage(void) +{ + printf("usage: collect [--add|--remove] [--debug] \n" + "\n" + " Adds ID to the list governed by .\n" + " must be part of the list .\n" + " If all IDs given by are listed (ie collect has been\n" + " invoked for each ID in ) collect returns 0, the\n" + " number of missing IDs otherwise.\n" + " On error a negative number is returned.\n" + "\n"); +} + +/* + * prepare + * + * Prepares the database file + */ +static int prepare(char *dir, char *filename) +{ + struct stat statbuf; + char buf[512]; + int fd; + + if (stat(dir, &statbuf) < 0) + mkdir(dir, 0700); + + snprintf(buf, sizeof(buf), "%s/%s", dir, filename); + + fd = open(buf,O_RDWR|O_CREAT, S_IRUSR|S_IWUSR); + if (fd < 0) + fprintf(stderr, "Cannot open %s: %s\n", buf, strerror(errno)); + + if (lockf(fd,F_TLOCK,0) < 0) { + if (debug) + fprintf(stderr, "Lock taken, wait for %d seconds\n", UDEV_ALARM_TIMEOUT); + if (errno == EAGAIN || errno == EACCES) { + alarm(UDEV_ALARM_TIMEOUT); + lockf(fd, F_LOCK, 0); + if (debug) + fprintf(stderr, "Acquired lock on %s\n", buf); + } else { + if (debug) + fprintf(stderr, "Could not get lock on %s: %s\n", buf, strerror(errno)); + } + } + + return fd; +} + +/* + * Read checkpoint file + * + * Tricky reading this. We allocate a buffer twice as large + * as we're going to read. Then we read into the upper half + * of that buffer and start parsing. + * Once we do _not_ find end-of-work terminator (whitespace + * character) we move the upper half to the lower half, + * adjust the read pointer and read the next bit. + * Quite clever methinks :-) + * I should become a programmer ... + * + * Yes, one could have used fgets() for this. But then we'd + * have to use freopen etc which I found quite tedious. + */ +static int checkout(int fd) +{ + int len; + char *buf, *ptr, *word = NULL; + struct _mate *him; + + restart: + len = bufsize >> 1; + buf = calloc(1,bufsize + 1); + if (!buf) { + fprintf(stderr, "Out of memory.\n"); + return log_oom(); + } + memset(buf, ' ', bufsize); + ptr = buf + len; + while ((read(fd, buf + len, len)) > 0) { + while (ptr && *ptr) { + word = ptr; + ptr = strpbrk(word," \n\t\r"); + if (!ptr && word < (buf + len)) { + bufsize = bufsize << 1; + if (debug) + fprintf(stderr, "ID overflow, restarting with size %zi\n", bufsize); + free(buf); + lseek(fd, 0, SEEK_SET); + goto restart; + } + if (ptr) { + *ptr = '\0'; + ptr++; + if (!strlen(word)) + continue; + + if (debug) + fprintf(stderr, "Found word %s\n", word); + him = malloc(sizeof (struct _mate)); + if (!him) { + free(buf); + return log_oom(); + } + him->name = strdup(word); + if (!him->name) { + free(buf); + free(him); + return log_oom(); + } + him->state = STATE_OLD; + udev_list_node_append(&him->node, &bunch); + word = NULL; + } + } + memcpy(buf, buf + len, len); + memset(buf + len, ' ', len); + + if (!ptr) + ptr = word; + if (!ptr) + break; + ptr -= len; + } + + free(buf); + return 0; +} + +/* + * invite + * + * Adds a new ID 'us' to the internal list, + * marks it as confirmed. + */ +static void invite(char *us) +{ + struct udev_list_node *him_node; + struct _mate *who = NULL; + + if (debug) + fprintf(stderr, "Adding ID '%s'\n", us); + + udev_list_node_foreach(him_node, &bunch) { + struct _mate *him = node_to_mate(him_node); + + if (!strcmp(him->name, us)) { + him->state = STATE_CONFIRMED; + who = him; + } + } + if (debug && !who) + fprintf(stderr, "ID '%s' not in database\n", us); + +} + +/* + * reject + * + * Marks the ID 'us' as invalid, + * causing it to be removed when the + * list is written out. + */ +static void reject(char *us) +{ + struct udev_list_node *him_node; + struct _mate *who = NULL; + + if (debug) + fprintf(stderr, "Removing ID '%s'\n", us); + + udev_list_node_foreach(him_node, &bunch) { + struct _mate *him = node_to_mate(him_node); + + if (!strcmp(him->name, us)) { + him->state = STATE_NONE; + who = him; + } + } + if (debug && !who) + fprintf(stderr, "ID '%s' not in database\n", us); +} + +/* + * kickout + * + * Remove all IDs in the internal list which are not part + * of the list passed via the commandline. + */ +static void kickout(void) +{ + struct udev_list_node *him_node; + struct udev_list_node *tmp; + + udev_list_node_foreach_safe(him_node, tmp, &bunch) { + struct _mate *him = node_to_mate(him_node); + + if (him->state == STATE_OLD) { + udev_list_node_remove(&him->node); + free(him->name); + free(him); + } + } +} + +/* + * missing + * + * Counts all missing IDs in the internal list. + */ +static int missing(int fd) +{ + char *buf; + int ret = 0; + struct udev_list_node *him_node; + + buf = malloc(bufsize); + if (!buf) + return log_oom(); + + udev_list_node_foreach(him_node, &bunch) { + struct _mate *him = node_to_mate(him_node); + + if (him->state == STATE_NONE) { + ret++; + } else { + while (strlen(him->name)+1 >= bufsize) { + char *tmpbuf; + + bufsize = bufsize << 1; + tmpbuf = realloc(buf, bufsize); + if (!tmpbuf) { + free(buf); + return log_oom(); + } + buf = tmpbuf; + } + snprintf(buf, strlen(him->name)+2, "%s ", him->name); + if (write(fd, buf, strlen(buf)) < 0) { + free(buf); + return -1; + } + } + } + + free(buf); + return ret; +} + +/* + * everybody + * + * Prints out the status of the internal list. + */ +static void everybody(void) +{ + struct udev_list_node *him_node; + const char *state = ""; + + udev_list_node_foreach(him_node, &bunch) { + struct _mate *him = node_to_mate(him_node); + + switch (him->state) { + case STATE_NONE: + state = "none"; + break; + case STATE_OLD: + state = "old"; + break; + case STATE_CONFIRMED: + state = "confirmed"; + break; + } + fprintf(stderr, "ID: %s=%s\n", him->name, state); + } +} + +int main(int argc, char **argv) +{ + struct udev *udev; + static const struct option options[] = { + { "add", no_argument, NULL, 'a' }, + { "remove", no_argument, NULL, 'r' }, + { "debug", no_argument, NULL, 'd' }, + { "help", no_argument, NULL, 'h' }, + {} + }; + int argi; + char *checkpoint, *us; + int fd; + int i; + int ret = EXIT_SUCCESS; + int prune = 0; + char tmpdir[UTIL_PATH_SIZE]; + + udev = udev_new(); + if (udev == NULL) { + ret = EXIT_FAILURE; + goto exit; + } + + while (1) { + int option; + + option = getopt_long(argc, argv, "ardh", options, NULL); + if (option == -1) + break; + + switch (option) { + case 'a': + prune = 0; + break; + case 'r': + prune = 1; + break; + case 'd': + debug = 1; + break; + case 'h': + usage(); + goto exit; + default: + ret = 1; + goto exit; + } + } + + argi = optind; + if (argi + 2 > argc) { + printf("Missing parameter(s)\n"); + ret = 1; + goto exit; + } + checkpoint = argv[argi++]; + us = argv[argi++]; + + if (signal(SIGALRM, sig_alrm) == SIG_ERR) { + fprintf(stderr, "Cannot set SIGALRM: %s\n", strerror(errno)); + ret = 2; + goto exit; + } + + udev_list_node_init(&bunch); + + if (debug) + fprintf(stderr, "Using checkpoint '%s'\n", checkpoint); + + util_strscpyl(tmpdir, sizeof(tmpdir), "/run/udev/collect", NULL); + fd = prepare(tmpdir, checkpoint); + if (fd < 0) { + ret = 3; + goto out; + } + + if (checkout(fd) < 0) { + ret = 2; + goto out; + } + + for (i = argi; i < argc; i++) { + struct udev_list_node *him_node; + struct _mate *who; + + who = NULL; + udev_list_node_foreach(him_node, &bunch) { + struct _mate *him = node_to_mate(him_node); + + if (!strcmp(him->name, argv[i])) + who = him; + } + if (!who) { + struct _mate *him; + + if (debug) + fprintf(stderr, "ID %s: not in database\n", argv[i]); + him = malloc(sizeof (struct _mate)); + if (!him) { + ret = ENOMEM; + goto out; + } + + him->name = malloc(strlen(argv[i]) + 1); + if (!him->name) { + ret = ENOMEM; + goto out; + } + + strcpy(him->name, argv[i]); + him->state = STATE_NONE; + udev_list_node_append(&him->node, &bunch); + } else { + if (debug) + fprintf(stderr, "ID %s: found in database\n", argv[i]); + who->state = STATE_CONFIRMED; + } + } + + if (prune) + reject(us); + else + invite(us); + + if (debug) { + everybody(); + fprintf(stderr, "Prune lists\n"); + } + kickout(); + + lseek(fd, 0, SEEK_SET); + ftruncate(fd, 0); + ret = missing(fd); + + lockf(fd, F_ULOCK, 0); + close(fd); +out: + if (debug) + everybody(); + if (ret >= 0) + printf("COLLECT_%s=%d\n", checkpoint, ret); +exit: + udev_unref(udev); + return ret; +} diff --git a/src/udev/keymap/.gitignore b/src/udev/keymap/.gitignore new file mode 100644 index 000000000..4567584f4 --- /dev/null +++ b/src/udev/keymap/.gitignore @@ -0,0 +1,5 @@ +keyboard-force-release.sh +keys-from-name.gperf +keys-from-name.h +keys-to-name.h +keys.txt diff --git a/src/udev/keymap/95-keyboard-force-release.rules b/src/udev/keymap/95-keyboard-force-release.rules new file mode 100644 index 000000000..f97a022d8 --- /dev/null +++ b/src/udev/keymap/95-keyboard-force-release.rules @@ -0,0 +1,57 @@ +# Set model specific atkbd force_release quirk +# +# Several laptops have hotkeys which don't generate release events, +# which can cause problems with software key repeat. +# The atkbd driver has a quirk handler for generating synthetic +# release events, which can be configured via sysfs since 2.6.32. +# Simply add a file with a list of scancodes for your laptop model +# in /usr/lib/udev/keymaps, and add a rule here. +# If the hotkeys also need a keymap assignment you can copy the +# scancodes from the keymap file, otherwise you can run +# /usr/lib/udev/keymap -i /dev/input/eventX +# on a Linux vt to find out. + +ACTION=="remove", GOTO="force_release_end" +SUBSYSTEM!="serio", GOTO="force_release_end" +KERNEL!="serio*", GOTO="force_release_end" +DRIVER!="atkbd", GOTO="force_release_end" + +ENV{DMI_VENDOR}="$attr{[dmi/id]sys_vendor}" + +ENV{DMI_VENDOR}=="[sS][aA][mM][sS][uU][nN][gG]*", RUN+="keyboard-force-release.sh $devpath samsung-other" +ENV{DMI_VENDOR}=="[sS][aA][mM][sS][uU][nN][gG]*", ATTR{[dmi/id]product_name}=="*90X3A*|*900X3*|*900X4*", RUN+="keyboard-force-release.sh $devpath samsung-series-9" + +ENV{DMI_VENDOR}=="Dell Inc.", ATTR{[dmi/id]product_name}=="Studio 1557|Studio 1558", RUN+="keyboard-force-release.sh $devpath common-volume-keys" +ENV{DMI_VENDOR}=="Dell Inc.", ATTR{[dmi/id]product_name}=="Latitude E*|Latitude *U|Precision M*", RUN+="keyboard-force-release.sh $devpath dell-touchpad" +ENV{DMI_VENDOR}=="Dell Inc.", ATTR{[dmi/id]product_name}=="XPS*", RUN+="keyboard-force-release.sh $devpath dell-xps" + +ENV{DMI_VENDOR}=="FUJITSU SIEMENS", ATTR{[dmi/id]product_name}=="AMILO*", RUN+="keyboard-force-release.sh $devpath common-volume-keys" + +ENV{DMI_VENDOR}=="FOXCONN", ATTR{[dmi/id]product_name}=="QBOOK", RUN+="keyboard-force-release.sh $devpath common-volume-keys" + +ENV{DMI_VENDOR}=="MTC", ATTR{[dmi/id]product_version}=="A0", RUN+="keyboard-force-release.sh $devpath common-volume-keys" + +ENV{DMI_VENDOR}=="Mio Technology", ATTR{[dmi/id]product_name}=="N890", RUN+="keyboard-force-release.sh $devpath common-volume-keys" + +ENV{DMI_VENDOR}=="PEGATRON CORP.", ATTR{[dmi/id]product_name}=="Spring Peak", RUN+="keyboard-force-release.sh $devpath common-volume-keys" + +ENV{DMI_VENDOR}=="TOSHIBA", ATTR{[dmi/id]product_name}=="Satellite [uU]300*|Satellite Pro [uU]300*|Satellite [uU]305*|SATELLITE [uU]500*", RUN+="keyboard-force-release.sh $devpath common-volume-keys" + +ENV{DMI_VENDOR}=="Viooo Corporation", ATTR{[dmi/id]product_name}=="PT17", RUN+="keyboard-force-release.sh $devpath common-volume-keys" + +# These are all the HP laptops that setup a touchpad toggle key +ENV{DMI_VENDOR}=="Hewlett-Packard*", ATTR{[dmi/id]product_name}=="*[pP][aA][vV][iI][lL][iI][oO][nN]*", RUN+="keyboard-force-release.sh $devpath hp-other" +ENV{DMI_VENDOR}=="Hewlett-Packard*", ATTR{[dmi/id]product_name}=="*[tT][xX]2*", RUN+="keyboard-force-release.sh $devpath hp-other" +ENV{DMI_VENDOR}=="Hewlett-Packard*", ATTR{[dmi/id]product_name}=="*2510p*|*2530p*|HP G60 Notebook PC", RUN+="keyboard-force-release.sh $devpath hp-other" + +ENV{DMI_VENDOR}=="Zepto", ATTR{[dmi/id]product_name}=="Znote 6615WD", RUN+="keyboard-force-release.sh $devpath common-volume-keys" + +ENV{DMI_VENDOR}=="Zepto", ATTR{[dmi/id]product_name}=="Znote", ATTR{[dmi/id]product_version}=="6625WD", RUN+="keyboard-force-release.sh $devpath common-volume-keys" + +ENV{DMI_VENDOR}=="HANNspree", ATTR{[dmi/id]product_name}=="SN10E100", RUN+="keyboard-force-release.sh $devpath common-volume-keys" + +ENV{DMI_VENDOR}=="GIGABYTE", ATTR{[dmi/id]product_name}=="i1520M", RUN+="keyboard-force-release.sh $devpath common-volume-keys" + +ENV{DMI_VENDOR}=="BenQ", ATTR{[dmi/id]product_name}=="*nScreen*", RUN+="keyboard-force-release.sh $devpath common-volume-keys" + +LABEL="force_release_end" diff --git a/src/udev/keymap/95-keymap.rules b/src/udev/keymap/95-keymap.rules new file mode 100644 index 000000000..347b5a1dd --- /dev/null +++ b/src/udev/keymap/95-keymap.rules @@ -0,0 +1,176 @@ +# Set model specific hotkey keycodes. +# +# Key map overrides can be specified by either giving scancode/keyname pairs +# directly as keymap arguments (if there are just one or two to change), or as +# a file name (in /usr/lib/udev/keymaps), which has to contain scancode/keyname +# pairs. + +ACTION=="remove", GOTO="keyboard_end" +KERNEL!="event*", GOTO="keyboard_end" +ENV{ID_INPUT_KEY}=="", GOTO="keyboard_end" +SUBSYSTEMS=="bluetooth", GOTO="keyboard_end" + +SUBSYSTEMS=="usb", IMPORT{builtin}="usb_id" +SUBSYSTEMS=="usb", GOTO="keyboard_usbcheck" +GOTO="keyboard_modulecheck" + +# +# The following are external USB keyboards +# + +LABEL="keyboard_usbcheck" + +ENV{ID_VENDOR}=="Genius", ENV{ID_MODEL_ID}=="0708", ENV{ID_USB_INTERFACE_NUM}=="01", RUN+="keymap $name genius-slimstar-320" +ENV{ID_VENDOR}=="Logitech*", ATTRS{name}=="Logitech USB Multimedia Keyboard", RUN+="keymap $name logitech-wave" +ENV{ID_VENDOR}=="Logitech*", ATTRS{name}=="Logitech USB Receiver", RUN+="keymap $name logitech-wave-cordless" +# Logitech Cordless Wave Pro looks slightly weird; some hotkeys are coming through the mouse interface +ENV{ID_VENDOR_ID}=="046d", ENV{ID_MODEL_ID}=="c52[9b]", ATTRS{name}=="Logitech USB Receiver", RUN+="keymap $name logitech-wave-pro-cordless" + +ENV{ID_VENDOR}=="Lite-On_Technology_Corp*", ATTRS{name}=="Lite-On Technology Corp. ThinkPad USB Keyboard with TrackPoint", RUN+="keymap $name lenovo-thinkpad-usb-keyboard-trackpoint" +ENV{ID_VENDOR_ID}=="04b3", ENV{ID_MODEL_ID}=="301[89]", RUN+="keymap $name ibm-thinkpad-usb-keyboard-trackpoint" + +ENV{ID_VENDOR}=="Microsoft", ENV{ID_MODEL_ID}=="00db", RUN+="keymap $name 0xc022d zoomin 0xc022e zoomout" + +GOTO="keyboard_end" + +# +# The following are exposed as separate input devices with low key codes, thus +# we need to check their input device product name +# + +LABEL="keyboard_modulecheck" + +ENV{DMI_VENDOR}="$attr{[dmi/id]sys_vendor}" +ENV{DMI_VENDOR}=="", GOTO="keyboard_end" + +ENV{DMI_VENDOR}=="LENOVO*", KERNELS=="input*", ATTRS{name}=="ThinkPad Extra Buttons", RUN+="keymap $name module-lenovo" +ENV{DMI_VENDOR}=="LENOVO*", KERNELS=="input*", ATTRS{name}=="Lenovo ThinkPad SL Series extra buttons", RUN+="keymap $name 0x0E bluetooth" +ENV{DMI_VENDOR}=="LENOVO*", KERNELS=="input*", ATTRS{name}=="Ideapad extra buttons", RUN+="keymap $name 0x42 f23 0x43 f22" + +ENV{DMI_VENDOR}=="ASUS*", KERNELS=="input*", ATTRS{name}=="Asus Extra Buttons", ATTR{[dmi/id]product_name}=="W3J", RUN+="keymap $name module-asus-w3j" +ENV{DMI_VENDOR}=="ASUS*", KERNELS=="input*", ATTRS{name}=="Eee PC WMI hotkeys|Asus Laptop Support|Asus*WMI*", RUN+="keymap $name 0x6B f21" +ENV{DMI_VENDOR}=="ASUS*", KERNELS=="input*", ATTRS{name}=="Eee PC Hotkey Driver", RUN+="keymap $name 0x37 f21" + +ENV{DMI_VENDOR}=="IBM*", KERNELS=="input*", ATTRS{name}=="ThinkPad Extra Buttons", RUN+="keymap $name module-ibm" +ENV{DMI_VENDOR}=="Sony*", KERNELS=="input*", ATTRS{name}=="Sony Vaio Keys", RUN+="keymap $name module-sony" +ENV{DMI_VENDOR}=="Acer*", KERNELS=="input*", ATTRS{name}=="Acer WMI hotkeys", RUN+="keymap $name 0x82 f21" +ENV{DMI_VENDOR}=="MICRO-STAR*|Micro-Star*", KERNELS=="input*", ATTRS{name}=="MSI Laptop hotkeys", RUN+="keymap $name 0x213 f22 0x214 f23" + +# Older Vaios have some different keys +ENV{DMI_VENDOR}=="Sony*", ATTR{[dmi/id]product_name}=="*PCG-C1*|*PCG-K25*|*PCG-F1*|*PCG-F2*|*PCG-F3*|*PCG-F4*|*PCG-F5*|*PCG-F6*|*PCG-FX*|*PCG-FRV*|*PCG-GR*|*PCG-TR*|*PCG-NV*|*PCG-Z*|*VGN-S360*", ATTRS{name}=="Sony Vaio Keys", RUN+="keymap $name module-sony-old" + +# Some Sony VGN/VPC models have yet another one +ENV{DMI_VENDOR}=="Sony*", ATTR{[dmi/id]product_name}=="VGN-AR71*|VGN-FW*|VGN-Z21*", ATTRS{name}=="Sony Vaio Keys", RUN+="keymap $name module-sony-vgn" +ENV{DMI_VENDOR}=="Sony*", ATTR{[dmi/id]product_name}=="VPC*", ATTRS{name}=="Sony Vaio Keys", RUN+="keymap $name module-sony-vpc" + + +# +# The following rules belong to standard i8042 AT keyboard with high key codes. +# + +DRIVERS=="atkbd", GOTO="keyboard_vendorcheck" +GOTO="keyboard_end" + +LABEL="keyboard_vendorcheck" + +ENV{DMI_VENDOR}=="Dell*", RUN+="keymap $name dell" +ENV{DMI_VENDOR}=="Dell*", ATTR{[dmi/id]product_name}=="Inspiron 910|Inspiron 1010|Inspiron 1011|Inspiron 1012|Inspiron 1110|Inspiron 1210", RUN+="keymap $name 0x84 wlan" +ENV{DMI_VENDOR}=="Dell*", ATTR{[dmi/id]product_name}=="Latitude XT2", RUN+="keymap $name dell-latitude-xt2" + +ENV{DMI_VENDOR}=="Compaq*", ATTR{[dmi/id]product_name}=="*E500*|*Evo N*", RUN+="keymap $name compaq-e_evo" + +ENV{DMI_VENDOR}=="LENOVO*", ATTR{[dmi/id]product_version}=="*3000*", RUN+="keymap $name lenovo-3000" +ENV{DMI_VENDOR}=="LENOVO*", ATTR{[dmi/id]product_version}=="ThinkPad X6*", ATTR{[dmi/id]product_version}=="* Tablet", RUN+="keymap $name lenovo-thinkpad_x6_tablet" +ENV{DMI_VENDOR}=="LENOVO*", ATTR{[dmi/id]product_version}=="ThinkPad X2* Tablet*", ATTR{[dmi/id]product_version}=="* Tablet", RUN+="keymap $name lenovo-thinkpad_x200_tablet" +ENV{DMI_VENDOR}=="LENOVO*", ATTR{[dmi/id]product_version}=="*IdeaPad*", RUN+="keymap $name lenovo-ideapad" +ENV{DMI_VENDOR}=="LENOVO*", ATTR{[dmi/id]product_name}=="S10-*", RUN+="keymap $name lenovo-ideapad" +ENV{DMI_VENDOR}=="LENOVO", ATTR{[dmi/id]product_version}=="*IdeaPad Y550*", RUN+="keymap $name 0x95 media 0xA3 play" +ENV{DMI_VENDOR}=="LENOVO", ATTR{[dmi/id]product_version}=="*Lenovo V480*", RUN+="keymap $name 0xf1 f21" + +ENV{DMI_VENDOR}=="Hewlett-Packard*", RUN+="keymap $name hewlett-packard" +ENV{DMI_VENDOR}=="Hewlett-Packard*", ATTR{[dmi/id]product_name}=="*[tT][aA][bB][lL][eE][tT]*", RUN+="keymap $name hewlett-packard-tablet" +ENV{DMI_VENDOR}=="Hewlett-Packard*", ATTR{[dmi/id]product_name}=="*[pP][aA][vV][iI][lL][iI][oO][nN]*", RUN+="keymap $name hewlett-packard-pavilion" +ENV{DMI_VENDOR}=="Hewlett-Packard*", ATTR{[dmi/id]product_name}=="*Compaq*|*EliteBook*|*2230s*", RUN+="keymap $name hewlett-packard-compaq_elitebook" +ENV{DMI_VENDOR}=="Hewlett-Packard*", ATTR{[dmi/id]product_name}=="*Presario*CQ*", RUN+="keymap $name 0xD8 f21 0xD9 f21" +ENV{DMI_VENDOR}=="Hewlett-Packard*", ATTR{[dmi/id]product_name}=="*2510p*|*2530p*|HP G60 Notebook PC", RUN+="keymap $name hewlett-packard-2510p_2530p" +ENV{DMI_VENDOR}=="Hewlett-Packard*", ATTR{[dmi/id]product_name}=="*[tT][xX]2*", RUN+="keymap $name hewlett-packard-tx2" +ENV{DMI_VENDOR}=="Hewlett-Packard", ATTR{[dmi/id]product_name}=="Presario 2100*", RUN+="keymap $name hewlett-packard-presario-2100" +ENV{DMI_VENDOR}=="Hewlett-Packard", ATTR{[dmi/id]product_name}=="HP G62 Notebook PC", RUN+="keymap $name 0xB2 www" +ENV{DMI_VENDOR}=="Hewlett-Packard", ATTR{[dmi/id]product_name}=="HP ProBook*", RUN+="keymap $name 0xF8 rfkill" +ENV{DMI_VENDOR}=="Hewlett-Packard", ATTR{[dmi/id]product_name}=="HP EliteBook 8440p", RUN+="keymap $name hewlett-packard_elitebook-8440p" +# HP Pavillion dv6315ea has empty DMI_VENDOR +ATTR{[dmi/id]board_vendor}=="Quanta", ATTR{[dmi/id]board_name}=="30B7", ATTR{[dmi/id]board_version}=="65.2B", RUN+="keymap $name 0x88 media" # "quick play + +# Gateway clone of Acer Aspire One AOA110/AOA150 +ENV{DMI_VENDOR}=="Gateway*", ATTR{[dmi/id]product_name}=="*AOA1*", RUN+="keymap $name acer" + +ENV{DMI_VENDOR}=="Acer*", RUN+="keymap $name acer" +ENV{DMI_VENDOR}=="Acer*", ATTR{[dmi/id]product_name}=="Extensa*", ATTR{[dmi/id]product_name}=="*5210*|*5220*|*5610*|*5620*|*5720*", RUN+="keymap $name 0xEE screenlock" +ENV{DMI_VENDOR}=="Acer*", ATTR{[dmi/id]product_name}=="TravelMate*C3[01]0*", RUN+="keymap $name acer-travelmate_c300" +ENV{DMI_VENDOR}=="Acer*", ATTR{[dmi/id]product_name}=="TravelMate*6292*|TravelMate*8471*|TravelMate*4720*|TravelMate*7720*|Aspire 1810T*|AO751h|AO531h", RUN+="keymap $name 0xD9 bluetooth" +ENV{DMI_VENDOR}=="Acer*", ATTR{[dmi/id]product_name}=="TravelMate*4720*", RUN+="keymap $name 0xB2 www 0xEE screenlock" +ENV{DMI_VENDOR}=="Acer*", ATTR{[dmi/id]product_name}=="TravelMate 6593|Aspire 1640", RUN+="keymap $name 0xB2 www 0xEE screenlock" +ENV{DMI_VENDOR}=="Acer*", ATTR{[dmi/id]product_name}=="Aspire 6920", RUN+="keymap $name acer-aspire_6920" +ENV{DMI_VENDOR}=="Acer*", ATTR{[dmi/id]product_name}=="Aspire 5920G", RUN+="keymap $name acer-aspire_5920g" +ENV{DMI_VENDOR}=="Acer*", ATTR{[dmi/id]product_name}=="Aspire 5720*", RUN+="keymap $name acer-aspire_5720" +ENV{DMI_VENDOR}=="Acer*", ATTR{[dmi/id]product_name}=="Aspire 8930", RUN+="keymap $name acer-aspire_8930" +ENV{DMI_VENDOR}=="Acer*", ATTR{[dmi/id]product_serial}=="ZG8*", RUN+="keymap $name acer-aspire_5720" + +ENV{DMI_VENDOR}=="*BenQ*", ATTR{[dmi/id]product_name}=="*Joybook R22*", RUN+="keymap $name 0x6E wlan" + +ENV{DMI_VENDOR}=="FUJITSU*", ATTR{[dmi/id]product_name}=="*AMILO Pro V3205*", RUN+="keymap $name fujitsu-amilo_pro_v3205" +ENV{DMI_VENDOR}=="FUJITSU*", ATTR{[dmi/id]product_name}=="*AMILO Pa 2548*", RUN+="keymap $name fujitsu-amilo_pa_2548" +ENV{DMI_VENDOR}=="FUJITSU*", ATTR{[dmi/id]product_name}=="*ESPRIMO Mobile V5*", RUN+="keymap $name fujitsu-esprimo_mobile_v5" +ENV{DMI_VENDOR}=="FUJITSU*", ATTR{[dmi/id]product_name}=="*ESPRIMO Mobile V6*", RUN+="keymap $name fujitsu-esprimo_mobile_v6" +ENV{DMI_VENDOR}=="FUJITSU*", ATTR{[dmi/id]product_name}=="*AMILO Pro Edition V3505*", RUN+="keymap $name fujitsu-amilo_pro_edition_v3505" +ENV{DMI_VENDOR}=="FUJITSU*", ATTR{[dmi/id]product_name}=="*Amilo Si 1520*", RUN+="keymap $name fujitsu-amilo_si_1520" +ENV{DMI_VENDOR}=="FUJITSU*", ATTR{[dmi/id]product_name}=="AMILO*M*", RUN+="keymap $name 0x97 prog2 0x9F prog1" +ENV{DMI_VENDOR}=="FUJITSU*", ATTR{[dmi/id]product_name}=="Amilo Li 1718", RUN+="keymap $name 0xD6 wlan" +ENV{DMI_VENDOR}=="FUJITSU*", ATTR{[dmi/id]product_name}=="AMILO Li 2732", RUN+="keymap $name fujitsu-amilo_li_2732" + +ENV{DMI_VENDOR}=="LG*", ATTR{[dmi/id]product_name}=="*X110*", RUN+="keymap $name lg-x110" + +ENV{DMI_VENDOR}=="MEDION*", ATTR{[dmi/id]product_name}=="*FID2060*", RUN+="keymap $name medion-fid2060" +ENV{DMI_VENDOR}=="MEDIONNB", ATTR{[dmi/id]product_name}=="A555*", RUN+="keymap $name medionnb-a555" + +ENV{DMI_VENDOR}=="MICRO-STAR*|Micro-Star*", RUN+="keymap $name micro-star" + +# some MSI models generate ACPI/input events on the LNXVIDEO input devices, +# plus some extra synthesized ones on atkbd as an echo of actually changing the +# brightness; so ignore those atkbd ones, to avoid loops +ENV{DMI_VENDOR}=="MICRO-STAR*", ATTR{[dmi/id]product_name}=="*U-100*|*U100*|*N033", RUN+="keymap $name 0xF7 reserved 0xF8 reserved" + +ENV{DMI_VENDOR}=="INVENTEC", ATTR{[dmi/id]product_name}=="SYMPHONY 6.0/7.0", RUN+="keymap $name inventec-symphony_6.0_7.0" + +ENV{DMI_VENDOR}=="MAXDATA", ATTR{[dmi/id]product_name}=="Pro 7000*", RUN+="keymap $name maxdata-pro_7000" + +ENV{DMI_VENDOR}=="[sS][aA][mM][sS][uU][nN][gG]*", RUN+="keymap $name samsung-other" +ENV{DMI_VENDOR}=="[sS][aA][mM][sS][uU][nN][gG]*", ATTR{[dmi/id]product_name}=="*SX20S*", RUN+="keymap $name samsung-sx20s" +ENV{DMI_VENDOR}=="[sS][aA][mM][sS][uU][nN][gG]*", ATTR{[dmi/id]product_name}=="SQ1US", RUN+="keymap $name samsung-sq1us" +ENV{DMI_VENDOR}=="[sS][aA][mM][sS][uU][nN][gG]*", ATTR{[dmi/id]product_name}=="*700Z*", RUN+="keymap $name 0xBA ejectcd 0x96 keyboardbrightnessup 0x97 keyboardbrightnessdown" +ENV{DMI_VENDOR}=="[sS][aA][mM][sS][uU][nN][gG]*", ATTR{[dmi/id]product_name}=="*700T*", RUN+="keymap $name 0xAD leftmeta" +ENV{DMI_VENDOR}=="[sS][aA][mM][sS][uU][nN][gG]*", ATTR{[dmi/id]product_name}=="*90X3A*|*900X3*|*900X4*", RUN+="keymap $name samsung-series-9" + +ENV{DMI_VENDOR}=="TOSHIBA", ATTR{[dmi/id]product_name}=="SATELLITE A100", RUN+="keymap $name toshiba-satellite_a100" +ENV{DMI_VENDOR}=="TOSHIBA", ATTR{[dmi/id]product_name}=="Satellite A110", RUN+="keymap $name toshiba-satellite_a110" +ENV{DMI_VENDOR}=="TOSHIBA", ATTR{[dmi/id]product_name}=="Satellite M30X", RUN+="keymap $name toshiba-satellite_m30x" + +ENV{DMI_VENDOR}=="OQO Inc.*", ATTR{[dmi/id]product_name}=="OQO Model 2*", RUN+="keymap $name oqo-model2" + +ENV{DMI_VENDOR}=="ONKYO CORPORATION", ATTR{[dmi/id]product_name}=="ONKYOPC", RUN+="keymap $name onkyo" + +ENV{DMI_VENDOR}=="ASUS", RUN+="keymap $name asus" + +ENV{DMI_VENDOR}=="VIA", ATTR{[dmi/id]product_name}=="K8N800", ATTR{[dmi/id]product_version}=="VT8204B", RUN+="keymap $name 0x81 prog1" + +ENV{DMI_VENDOR}=="Zepto", ATTR{[dmi/id]product_name}=="Znote", ATTR{[dmi/id]product_version}=="62*|63*", RUN+="keymap $name zepto-znote" + +ENV{DMI_VENDOR}=="Everex", ATTR{[dmi/id]product_name}=="XT5000*", RUN+="keymap $name everex-xt5000" + +ENV{DMI_VENDOR}=="COMPAL", ATTR{[dmi/id]product_name}=="HEL80I", RUN+="keymap $name 0x84 wlan" + +ENV{DMI_VENDOR}=="OLPC", ATTR{[dmi/id]product_name}=="XO", RUN+="keymap $name olpc-xo" + +ENV{DMI_VENDOR}=="Alienware*", ATTR{[dmi/id]product_name}=="M14xR1", RUN+="keymap $name 0x8A ejectcd" + +LABEL="keyboard_end" diff --git a/src/udev/keymap/README.keymap.txt b/src/udev/keymap/README.keymap.txt new file mode 100644 index 000000000..2cf2a4e88 --- /dev/null +++ b/src/udev/keymap/README.keymap.txt @@ -0,0 +1,97 @@ += The udev keymap tool = + +== Introduction == + +This udev extension configures computer model specific key mappings. This is +particularly necessary for the non-standard extra keys found on many laptops, +such as "brightness up", "next song", "www browser", or "suspend". Often these +are accessed with the Fn key. + +Every key produces a "scan code", which is highly vendor/model specific for the +nonstandard keys. This tool maintains mappings for these scan codes to standard +"key codes", which denote the "meaning" of the key. The key codes are defined +in /usr/include/linux/input.h. + +If some of your keys on your keyboard are not working at all, or produce the +wrong effect, then a very likely cause of this is that the scan code -> key +code mapping is incorrect on your computer. + +== Structure == + +udev-keymap consists of the following parts: + + keymaps/*:: mappings of scan codes to key code names + + 95-keymap.rules:: udev rules for mapping system vendor/product names and + input module names to one of the keymaps above + + keymap:: manipulate an evdev input device: + * write a key map file into a device (used by udev rules) + * dump current scan → key code mapping + * interactively display scan and key codes of pressed keys + + findkeyboards:: display evdev input devices which belong to actual keyboards, + i. e. those suitable for the keymap program + +== Fixing broken keys == + +In order to make a broken key work on your system and send it back to upstream +for inclusion you need to do the following steps: + + 1. Find the keyboard device. + + Run /usr/lib/udev/findkeyboards. This should always give you an "AT + keyboard" and possibly a "module". Some laptops (notably Thinkpads, Sonys, and + Acers) have multimedia/function keys on a separate input device instead of the + primary keyboard. The keyboard device should have a name like "input/event3". + In the following commands, the name will be written as "input/eventX" (replace + X with the appropriate number). + + 2. Find broken scan codes: + + sudo /usr/lib/udev/keymap -i input/eventX + + Press all multimedia/function keys and check if the key name that gets printed + out is plausible. If it is unknown or wrong, write down the scan code (looks + like "0x1E") and the intended functionality of this key. Look in + /usr/include/linux/input.h for an available KEY_XXXXX constant which most + closely approximates this functionality and write it down as the new key code. + + For example, you might press a key labeled "web browser" which currently + produces "unknown". Note down this: + + 0x1E www # Fn+F2 web browser + + Repeat that for all other keys. Write the resulting list into a file. Look at + /usr/lib/udev/keymaps/ for existing key map files and make sure that you use the + same structure. + + If the key only ever works once and then your keyboard (or the entire desktop) + gets stuck for a long time, then it is likely that the BIOS fails to send a + corresponding "key release" event after the key press event. Please note down + this case as well, as it can be worked around in + /usr/lib/udev/keymaps/95-keyboard-force-release.rules . + + 3. Find out your system vendor and product: + + cat /sys/class/dmi/id/sys_vendor + cat /sys/class/dmi/id/product_name + + 4. Generate a device dump with "udevadm info --export-db > /tmp/udev-db.txt". + + 6. Send the system vendor/product names, the key mapping from step 2, + and /tmp/udev-db.txt from step 4 to the linux-hotplug@vger.kernel.org mailing + list, so that they can be included in the next release. + +For local testing, copy your map file to /usr/lib/udev/keymaps/ with an appropriate +name, and add an appropriate udev rule to /usr/lib/udev/rules.d/95-keymap.rules: + + * If you selected an "AT keyboard", add the rule to the section after + 'LABEL="keyboard_vendorcheck"'. + + * If you selected a "module", add the rule to the top section where the + "ThinkPad Extra Buttons" are. + +== Author == + +keymap is written and maintained by Martin Pitt . diff --git a/src/udev/keymap/check-keymaps.sh b/src/udev/keymap/check-keymaps.sh new file mode 100755 index 000000000..c4572745e --- /dev/null +++ b/src/udev/keymap/check-keymaps.sh @@ -0,0 +1,38 @@ +#!/bin/bash + +# check that all key names in keymaps/* are known in +# and that all key maps listed in the rules are valid and present in +# Makefile.am +SRCDIR=${1:-.} +KEYLIST=${2:-src/udev/keymap/keys.txt} +KEYMAPS_DIR=$SRCDIR/keymaps +RULES=$SRCDIR/src/udev/keymap/95-keymap.rules + +[ -e "$KEYLIST" ] || { + echo "need $KEYLIST please build first" >&2 + exit 1 +} + +missing=$(join -v 2 <(awk '{print tolower(substr($1,5))}' $KEYLIST | sort -u) \ + <(grep -hv '^#' ${KEYMAPS_DIR}/*| awk '{print $2}' | sort -u)) +[ -z "$missing" ] || { + echo "ERROR: unknown key names in keymaps/*:" >&2 + echo "$missing" >&2 + exit 1 +} + +# check that all maps referred to in $RULES exist +maps=$(sed -rn '/keymap \$name/ { s/^.*\$name ([^"[:space:]]+).*$/\1/; p }' $RULES) +for m in $maps; do + # ignore inline mappings + [ "$m" = "${m#0x}" ] || continue + + [ -e ${KEYMAPS_DIR}/$m ] || { + echo "ERROR: unknown map name in $RULES: $m" >&2 + exit 1 + } + grep -q "keymaps/$m\>" $SRCDIR/Makefile.am || { + echo "ERROR: map file $m is not added to Makefile.am" >&2 + exit 1 + } +done diff --git a/src/udev/keymap/findkeyboards b/src/udev/keymap/findkeyboards new file mode 100755 index 000000000..9ce27429b --- /dev/null +++ b/src/udev/keymap/findkeyboards @@ -0,0 +1,68 @@ +#!/bin/sh -e +# Find "real" keyboard devices and print their device path. +# Author: Martin Pitt +# +# Copyright (C) 2009, Canonical Ltd. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. + +# returns OK if $1 contains $2 +strstr() { + [ "${1#*$2*}" != "$1" ] +} + +# returns OK if $1 contains $2 at the beginning +str_starts() { + [ "${1#$2*}" != "$1" ] +} + +str_line_starts() { + while read a; do str_starts "$a" "$1" && return 0;done + return 1; +} + +# print a list of input devices which are keyboard-like +keyboard_devices() { + # standard AT keyboard + for dev in `udevadm trigger --dry-run --verbose --property-match=ID_INPUT_KEYBOARD=1`; do + walk=`udevadm info --attribute-walk --path=$dev` + env=`udevadm info --query=env --path=$dev` + # filter out non-event devices, such as the parent input devices which have no devnode + if ! echo "$env" | str_line_starts 'DEVNAME='; then + continue + fi + if strstr "$walk" 'DRIVERS=="atkbd"'; then + echo -n 'AT keyboard: ' + elif echo "$env" | str_line_starts 'ID_USB_DRIVER=usbhid'; then + echo -n 'USB keyboard: ' + else + echo -n 'Unknown type: ' + fi + udevadm info --query=name --path=$dev + done + + # modules + module=$(udevadm trigger --verbose --dry-run --subsystem-match=input --attr-match=name='*Extra Buttons') + module="$module + $(udevadm trigger --verbose --dry-run --subsystem-match=input --attr-match=name='*extra buttons')" + module="$module + $(udevadm trigger --verbose --dry-run --subsystem-match=input --attr-match=name='Sony Vaio Keys')" + for m in $module; do + for evdev in $m/event*/dev; do + if [ -e "$evdev" ]; then + echo -n 'module: ' + udevadm info --query=name --path=${evdev%%/dev} + fi + done + done +} + +keyboard_devices diff --git a/src/udev/keymap/keyboard-force-release.sh.in b/src/udev/keymap/keyboard-force-release.sh.in new file mode 100755 index 000000000..b82674840 --- /dev/null +++ b/src/udev/keymap/keyboard-force-release.sh.in @@ -0,0 +1,22 @@ +#!/bin/sh -e +# read list of scancodes, convert hex to decimal and +# append to the atkbd force_release sysfs attribute +# $1 sysfs devpath for serioX +# $2 file with scancode list (hex or dec) + +case "$2" in + /*) scf="$2" ;; + *) scf="@udevlibexecdir@/keymaps/force-release/$2" ;; +esac + +read attr <"/sys/$1/force_release" +while read scancode dummy; do + case "$scancode" in + \#*) ;; + *) + scancode=$(($scancode)) + attr="$attr${attr:+,}$scancode" + ;; + esac +done <"$scf" +echo "$attr" >"/sys/$1/force_release" diff --git a/src/udev/keymap/keymap.c b/src/udev/keymap/keymap.c new file mode 100644 index 000000000..27aaf6b67 --- /dev/null +++ b/src/udev/keymap/keymap.c @@ -0,0 +1,453 @@ +/* + * keymap - dump keymap of an evdev device or set a new keymap from a file + * + * Based on keyfuzz by Lennart Poettering + * Adapted for udev-extras by Martin Pitt + * + * Copyright (C) 2006, Lennart Poettering + * Copyright (C) 2009, Canonical Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +const struct key* lookup_key (const char *str, unsigned int len); + +#include "keys-from-name.h" +#include "keys-to-name.h" +#include "macro.h" +#include "util.h" + +#define MAX_SCANCODES 1024 + +static int evdev_open(const char *dev) +{ + int fd; + char fn[PATH_MAX]; + + if (!startswith(dev, "/dev")) { + snprintf(fn, sizeof(fn), "/dev/%s", dev); + dev = fn; + } + + if ((fd = open(dev, O_RDWR)) < 0) { + fprintf(stderr, "error open('%s'): %m\n", dev); + return -1; + } + return fd; +} + +static int evdev_get_keycode(int fd, unsigned scancode, int e) +{ + unsigned codes[2]; + + codes[0] = scancode; + if (ioctl(fd, EVIOCGKEYCODE, codes) < 0) { + if (e && errno == EINVAL) { + return -2; + } else { + fprintf(stderr, "EVIOCGKEYCODE for scan code 0x%x: %m\n", scancode); + return -1; + } + } + return codes[1]; +} + +static int evdev_set_keycode(int fd, unsigned scancode, int keycode) +{ + unsigned codes[2]; + + codes[0] = scancode; + codes[1] = (unsigned) keycode; + + if (ioctl(fd, EVIOCSKEYCODE, codes) < 0) { + fprintf(stderr, "EVIOCSKEYCODE: %m\n"); + return -1; + } + return 0; +} + +static int evdev_driver_version(int fd, char *v, size_t l) +{ + int version; + + if (ioctl(fd, EVIOCGVERSION, &version)) { + fprintf(stderr, "EVIOCGVERSION: %m\n"); + return -1; + } + + snprintf(v, l, "%i.%i.%i.", version >> 16, (version >> 8) & 0xff, version & 0xff); + return 0; +} + +static int evdev_device_name(int fd, char *n, size_t l) +{ + if (ioctl(fd, EVIOCGNAME(l), n) < 0) { + fprintf(stderr, "EVIOCGNAME: %m\n"); + return -1; + } + return 0; +} + +/* Return a lower-case string with KEY_ prefix removed */ +static const char* format_keyname(const char* key) { + static char result[101]; + const char* s; + int len; + + for (s = key+4, len = 0; *s && len < 100; ++len, ++s) + result[len] = tolower(*s); + result[len] = '\0'; + return result; +} + +static int dump_table(int fd) { + char version[256], name[256]; + unsigned scancode; + int r = -1; + + if (evdev_driver_version(fd, version, sizeof(version)) < 0) + goto fail; + + if (evdev_device_name(fd, name, sizeof(name)) < 0) + goto fail; + + printf("### evdev %s, driver '%s'\n", version, name); + + r = 0; + for (scancode = 0; scancode < MAX_SCANCODES; scancode++) { + int keycode; + + if ((keycode = evdev_get_keycode(fd, scancode, 1)) < 0) { + if (keycode == -2) + continue; + r = -1; + break; + } + + if (keycode < KEY_MAX && key_names[keycode]) + printf("0x%03x %s\n", scancode, format_keyname(key_names[keycode])); + else + printf("0x%03x 0x%03x\n", scancode, keycode); + } +fail: + return r; +} + +static void set_key(int fd, const char* scancode_str, const char* keyname) +{ + unsigned scancode; + char *endptr; + char t[105] = "KEY_UNKNOWN"; + const struct key *k; + + scancode = (unsigned) strtol(scancode_str, &endptr, 0); + if (*endptr != '\0') { + fprintf(stderr, "ERROR: Invalid scancode\n"); + exit(1); + } + + snprintf(t, sizeof(t), "KEY_%s", keyname); + + if (!(k = lookup_key(t, strlen(t)))) { + fprintf(stderr, "ERROR: Unknown key name '%s'\n", keyname); + exit(1); + } + + if (evdev_set_keycode(fd, scancode, k->id) < 0) + fprintf(stderr, "setting scancode 0x%2X to key code %i failed\n", + scancode, k->id); + else + printf("setting scancode 0x%2X to key code %i\n", + scancode, k->id); +} + +static int merge_table(int fd, FILE *f) { + int r = 0; + int line = 0; + + while (!feof(f)) { + char s[256], *p; + unsigned scancode; + int new_keycode, old_keycode; + + if (!fgets(s, sizeof(s), f)) + break; + + line++; + p = s+strspn(s, "\t "); + if (*p == '#' || *p == '\n') + continue; + + if (sscanf(p, "%i %i", &scancode, &new_keycode) != 2) { + char t[105] = "KEY_UNKNOWN"; + const struct key *k; + + if (sscanf(p, "%i %100s", &scancode, t+4) != 2) { + fprintf(stderr, "WARNING: Parse failure at line %i, ignoring.\n", line); + r = -1; + continue; + } + + if (!(k = lookup_key(t, strlen(t)))) { + fprintf(stderr, "WARNING: Unknown key '%s' at line %i, ignoring.\n", t, line); + r = -1; + continue; + } + + new_keycode = k->id; + } + + + if ((old_keycode = evdev_get_keycode(fd, scancode, 0)) < 0) { + r = -1; + continue; + } + + if (evdev_set_keycode(fd, scancode, new_keycode) < 0) { + r = -1; + continue; + } + + if (new_keycode != old_keycode) + fprintf(stderr, "Remapped scancode 0x%02x to 0x%02x (prior: 0x%02x)\n", + scancode, new_keycode, old_keycode); + } + + fclose(f); + return r; +} + + +/* read one event; return 1 if valid */ +static int read_event(int fd, struct input_event* ev) +{ + int ret; + ret = read(fd, ev, sizeof(struct input_event)); + + if (ret < 0) { + perror("read"); + return 0; + } + if (ret != sizeof(struct input_event)) { + fprintf(stderr, "did not get enough data for event struct, aborting\n"); + return 0; + } + + return 1; +} + +static void print_key(unsigned scancode, uint16_t keycode, int has_scan, int has_key) +{ + const char *keyname; + + /* ignore key release events */ + if (has_key == 1) + return; + + if (has_key == 0 && has_scan != 0) { + fprintf(stderr, "got scan code event 0x%02X without a key code event\n", + scancode); + return; + } + + if (has_scan != 0) + printf("scan code: 0x%02X ", scancode); + else + printf("(no scan code received) "); + + keyname = key_names[keycode]; + if (keyname != NULL) + printf("key code: %s\n", format_keyname(keyname)); + else + printf("key code: %03X\n", keycode); +} + +static void interactive(int fd) +{ + struct input_event ev; + unsigned last_scan = 0; + uint16_t last_key = 0; + int has_scan; /* boolean */ + int has_key; /* 0: none, 1: release, 2: press */ + + /* grab input device */ + ioctl(fd, EVIOCGRAB, 1); + puts("Press ESC to finish, or Control-C if this device is not your primary keyboard"); + + has_scan = has_key = 0; + while (read_event(fd, &ev)) { + /* Drivers usually send the scan code first, then the key code, + * then a SYN. Some drivers (like thinkpad_acpi) send the key + * code first, and some drivers might not send SYN events, so + * keep a robust state machine which can deal with any of those + */ + + if (ev.type == EV_MSC && ev.code == MSC_SCAN) { + if (has_scan) { + fputs("driver did not send SYN event in between key events; previous event:\n", + stderr); + print_key(last_scan, last_key, has_scan, has_key); + has_key = 0; + } + + last_scan = ev.value; + has_scan = 1; + /*printf("--- got scan %u; has scan %i key %i\n", last_scan, has_scan, has_key); */ + } + else if (ev.type == EV_KEY) { + if (has_key) { + fputs("driver did not send SYN event in between key events; previous event:\n", + stderr); + print_key(last_scan, last_key, has_scan, has_key); + has_scan = 0; + } + + last_key = ev.code; + has_key = 1 + ev.value; + /*printf("--- got key %hu; has scan %i key %i\n", last_key, has_scan, has_key);*/ + + /* Stop on ESC */ + if (ev.code == KEY_ESC && ev.value == 0) + break; + } + else if (ev.type == EV_SYN) { + /*printf("--- got SYN; has scan %i key %i\n", has_scan, has_key);*/ + print_key(last_scan, last_key, has_scan, has_key); + + has_scan = has_key = 0; + } + + } + + /* release input device */ + ioctl(fd, EVIOCGRAB, 0); +} + +_noreturn_ static void help(int error) +{ + const char* h = "Usage: keymap []\n" + " keymap scancode keyname [...]\n" + " keymap -i \n"; + if (error) { + fputs(h, stderr); + exit(2); + } else { + fputs(h, stdout); + exit(0); + } +} + +int main(int argc, char **argv) +{ + static const struct option options[] = { + { "help", no_argument, NULL, 'h' }, + { "interactive", no_argument, NULL, 'i' }, + {} + }; + int fd = -1; + int opt_interactive = 0; + int i; + + while (1) { + int option; + + option = getopt_long(argc, argv, "hi", options, NULL); + if (option == -1) + break; + + switch (option) { + case 'h': + help(0); + + case 'i': + opt_interactive = 1; + break; + default: + return 1; + } + } + + if (argc < optind+1) + help (1); + + if ((fd = evdev_open(argv[optind])) < 0) + return 3; + + /* one argument (device): dump or interactive */ + if (argc == optind+1) { + if (opt_interactive) + interactive(fd); + else + dump_table(fd); + return 0; + } + + /* two arguments (device, mapfile): set map file */ + if (argc == optind+2) { + const char *filearg = argv[optind+1]; + if (strchr(filearg, '/')) { + /* Keymap file argument is a path */ + FILE *f = fopen(filearg, "re"); + if (f) + merge_table(fd, f); + else + perror(filearg); + } else { + /* Keymap file argument is a filename */ + /* Open override file if present, otherwise default file */ + char keymap_path[PATH_MAX]; + FILE *f; + + snprintf(keymap_path, sizeof(keymap_path), "/etc/udev/keymaps/%s", filearg); + f = fopen(keymap_path, "re"); + if (f) { + merge_table(fd, f); + } else { + snprintf(keymap_path, sizeof(keymap_path), UDEVLIBEXECDIR "/keymaps/%s", filearg); + f = fopen(keymap_path, "re"); + if (f) + merge_table(fd, f); + else + perror(keymap_path); + } + } + return 0; + } + + /* more arguments (device, scancode/keyname pairs): set keys directly */ + if ((argc - optind - 1) % 2 == 0) { + for (i = optind+1; i < argc; i += 2) + set_key(fd, argv[i], argv[i+1]); + return 0; + } + + /* invalid number of arguments */ + help(1); + return 1; /* not reached */ +} diff --git a/src/udev/mtd_probe/mtd_probe.c b/src/udev/mtd_probe/mtd_probe.c new file mode 100644 index 000000000..70c04db40 --- /dev/null +++ b/src/udev/mtd_probe/mtd_probe.c @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2010 - Maxim Levitsky + * + * mtd_probe is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * mtd_probe is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with mtd_probe; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301 USA + */ +#include "mtd_probe.h" +#include +#include +#include +#include +#include +#include +#include +#include + +int main(int argc, char** argv) +{ + int mtd_fd; + int error; + mtd_info_t mtd_info; + + if (argc != 2) { + printf("usage: mtd_probe /dev/mtd[n]\n"); + return 1; + } + + mtd_fd = open(argv[1], O_RDONLY); + if (mtd_fd == -1) { + perror("open"); + exit(-1); + } + + error = ioctl(mtd_fd, MEMGETINFO, &mtd_info); + if (error == -1) { + perror("ioctl"); + exit(-1); + } + + probe_smart_media(mtd_fd, &mtd_info); + return -1; +} diff --git a/src/udev/mtd_probe/mtd_probe.h b/src/udev/mtd_probe/mtd_probe.h new file mode 100644 index 000000000..2a37ede57 --- /dev/null +++ b/src/udev/mtd_probe/mtd_probe.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2010 - Maxim Levitsky + * + * mtd_probe is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * mtd_probe is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with mtd_probe; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include + +/* Full oob structure as written on the flash */ +struct sm_oob { + uint32_t reserved; + uint8_t data_status; + uint8_t block_status; + uint8_t lba_copy1[2]; + uint8_t ecc2[3]; + uint8_t lba_copy2[2]; + uint8_t ecc1[3]; +} __attribute__((packed)); + + +/* one sector is always 512 bytes, but it can consist of two nand pages */ +#define SM_SECTOR_SIZE 512 + +/* oob area is also 16 bytes, but might be from two pages */ +#define SM_OOB_SIZE 16 + +/* This is maximum zone size, and all devices that have more that one zone + have this size */ +#define SM_MAX_ZONE_SIZE 1024 + +/* support for small page nand */ +#define SM_SMALL_PAGE 256 +#define SM_SMALL_OOB_SIZE 8 + + +void probe_smart_media(int mtd_fd, mtd_info_t *info); diff --git a/src/udev/mtd_probe/probe_smartmedia.c b/src/udev/mtd_probe/probe_smartmedia.c new file mode 100644 index 000000000..feadb5076 --- /dev/null +++ b/src/udev/mtd_probe/probe_smartmedia.c @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2010 - Maxim Levitsky + * + * mtd_probe is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * mtd_probe is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with mtd_probe; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "mtd_probe.h" + +static const uint8_t cis_signature[] = { + 0x01, 0x03, 0xD9, 0x01, 0xFF, 0x18, 0x02, 0xDF, 0x01, 0x20 +}; + + +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); + int offset; + int cis_found = 0; + + if (!cis_buffer) + return; + + if (info->type != MTD_NANDFLASH) + goto exit; + + sector_size = info->writesize; + block_size = info->erasesize; + size_in_megs = info->size / (1024 * 1024); + + if (sector_size != SM_SECTOR_SIZE && sector_size != SM_SMALL_PAGE) + goto exit; + + switch(size_in_megs) { + case 1: + case 2: + spare_count = 6; + break; + case 4: + spare_count = 12; + break; + default: + spare_count = 24; + break; + } + + for (offset = 0 ; offset < block_size * spare_count ; + offset += sector_size) { + lseek(mtd_fd, SEEK_SET, offset); + if (read(mtd_fd, cis_buffer, SM_SECTOR_SIZE) == SM_SECTOR_SIZE){ + cis_found = 1; + break; + } + } + + if (!cis_found) + goto exit; + + if (memcmp(cis_buffer, cis_signature, sizeof(cis_signature)) != 0 && + (memcmp(cis_buffer + SM_SMALL_PAGE, cis_signature, + sizeof(cis_signature)) != 0)) + goto exit; + + printf("MTD_FTL=smartmedia\n"); + free(cis_buffer); + exit(0); +exit: + free(cis_buffer); + return; +} diff --git a/src/udev/scsi_id/.gitignore b/src/udev/scsi_id/.gitignore new file mode 100644 index 000000000..6aebddd80 --- /dev/null +++ b/src/udev/scsi_id/.gitignore @@ -0,0 +1 @@ +scsi_id_version.h diff --git a/src/udev/scsi_id/README b/src/udev/scsi_id/README new file mode 100644 index 000000000..9cfe73991 --- /dev/null +++ b/src/udev/scsi_id/README @@ -0,0 +1,4 @@ +scsi_id - generate a SCSI unique identifier for a given SCSI device + +Please send questions, comments or patches to or +. diff --git a/src/udev/scsi_id/scsi.h b/src/udev/scsi_id/scsi.h new file mode 100644 index 000000000..c423cac57 --- /dev/null +++ b/src/udev/scsi_id/scsi.h @@ -0,0 +1,97 @@ +/* + * scsi.h + * + * General scsi and linux scsi specific defines and structs. + * + * Copyright (C) IBM Corp. 2003 + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation version 2 of the License. + */ + +#include + +struct scsi_ioctl_command { + unsigned int inlen; /* excluding scsi command length */ + unsigned int outlen; + unsigned char data[1]; + /* on input, scsi command starts here then opt. data */ +}; + +/* + * Default 5 second timeout + */ +#define DEF_TIMEOUT 5000 + +#define SENSE_BUFF_LEN 32 + +/* + * The request buffer size passed to the SCSI INQUIRY commands, use 254, + * as this is a nice value for some devices, especially some of the usb + * mass storage devices. + */ +#define SCSI_INQ_BUFF_LEN 254 + +/* + * SCSI INQUIRY vendor and model (really product) lengths. + */ +#define VENDOR_LENGTH 8 +#define MODEL_LENGTH 16 + +#define INQUIRY_CMD 0x12 +#define INQUIRY_CMDLEN 6 + +/* + * INQUIRY VPD page 0x83 identifier descriptor related values. Reference the + * SCSI Primary Commands specification for details. + */ + +/* + * id type values of id descriptors. These are assumed to fit in 4 bits. + */ +#define SCSI_ID_VENDOR_SPECIFIC 0 +#define SCSI_ID_T10_VENDOR 1 +#define SCSI_ID_EUI_64 2 +#define SCSI_ID_NAA 3 +#define SCSI_ID_RELPORT 4 +#define SCSI_ID_TGTGROUP 5 +#define SCSI_ID_LUNGROUP 6 +#define SCSI_ID_MD5 7 +#define SCSI_ID_NAME 8 + +/* + * Supported NAA values. These fit in 4 bits, so the "don't care" value + * cannot conflict with real values. + */ +#define SCSI_ID_NAA_DONT_CARE 0xff +#define SCSI_ID_NAA_IEEE_REG 5 +#define SCSI_ID_NAA_IEEE_REG_EXTENDED 6 + +/* + * Supported Code Set values. + */ +#define SCSI_ID_BINARY 1 +#define SCSI_ID_ASCII 2 + +struct scsi_id_search_values { + u_char id_type; + u_char naa_type; + u_char code_set; +}; + +/* + * Following are the "true" SCSI status codes. Linux has traditionally + * used a 1 bit right and masked version of these. So now CHECK_CONDITION + * and friends (in ) are deprecated. + */ +#define SCSI_CHECK_CONDITION 0x2 +#define SCSI_CONDITION_MET 0x4 +#define SCSI_BUSY 0x8 +#define SCSI_IMMEDIATE 0x10 +#define SCSI_IMMEDIATE_CONDITION_MET 0x14 +#define SCSI_RESERVATION_CONFLICT 0x18 +#define SCSI_COMMAND_TERMINATED 0x22 +#define SCSI_TASK_SET_FULL 0x28 +#define SCSI_ACA_ACTIVE 0x30 +#define SCSI_TASK_ABORTED 0x40 diff --git a/src/udev/scsi_id/scsi_id.c b/src/udev/scsi_id/scsi_id.c new file mode 100644 index 000000000..c90b6aa58 --- /dev/null +++ b/src/udev/scsi_id/scsi_id.c @@ -0,0 +1,634 @@ +/* + * Copyright (C) IBM Corp. 2003 + * Copyright (C) SUSE Linux Products GmbH, 2006 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "libudev.h" +#include "libudev-private.h" +#include "scsi_id.h" + +static const struct option options[] = { + { "device", required_argument, NULL, 'd' }, + { "config", required_argument, NULL, 'f' }, + { "page", required_argument, NULL, 'p' }, + { "blacklisted", no_argument, NULL, 'b' }, + { "whitelisted", no_argument, NULL, 'g' }, + { "replace-whitespace", no_argument, NULL, 'u' }, + { "sg-version", required_argument, NULL, 's' }, + { "verbose", no_argument, NULL, 'v' }, + { "version", no_argument, NULL, 'V' }, + { "export", no_argument, NULL, 'x' }, + { "help", no_argument, NULL, 'h' }, + {} +}; + +static const char short_options[] = "d:f:ghip:uvVx"; +static const char dev_short_options[] = "bgp:"; + +static int all_good; +static int dev_specified; +static char config_file[MAX_PATH_LEN] = "/etc/scsi_id.config"; +static enum page_code default_page_code; +static int sg_version = 4; +static int use_stderr; +static int debug; +static int reformat_serial; +static int export; +static char vendor_str[64]; +static char model_str[64]; +static char vendor_enc_str[256]; +static char model_enc_str[256]; +static char revision_str[16]; +static char type_str[16]; + +static void log_fn(struct udev *udev, int priority, + const char *file, int line, const char *fn, + const char *format, va_list args) +{ + vsyslog(priority, format, args); +} + +static void set_type(const char *from, char *to, size_t len) +{ + int type_num; + char *eptr; + const char *type = "generic"; + + type_num = strtoul(from, &eptr, 0); + if (eptr != from) { + switch (type_num) { + case 0: + type = "disk"; + break; + case 1: + type = "tape"; + break; + case 4: + type = "optical"; + break; + case 5: + type = "cd"; + break; + case 7: + type = "optical"; + break; + case 0xe: + type = "disk"; + break; + case 0xf: + type = "optical"; + break; + default: + break; + } + } + util_strscpy(to, len, type); +} + +/* + * get_value: + * + * buf points to an '=' followed by a quoted string ("foo") or a string ending + * with a space or ','. + * + * Return a pointer to the NUL terminated string, returns NULL if no + * matches. + */ +static char *get_value(char **buffer) +{ + static const char *quote_string = "\"\n"; + static const char *comma_string = ",\n"; + char *val; + const char *end; + + if (**buffer == '"') { + /* + * skip leading quote, terminate when quote seen + */ + (*buffer)++; + end = quote_string; + } else { + end = comma_string; + } + val = strsep(buffer, end); + if (val && end == quote_string) + /* + * skip trailing quote + */ + (*buffer)++; + + while (isspace(**buffer)) + (*buffer)++; + + return val; +} + +static int argc_count(char *opts) +{ + int i = 0; + while (*opts != '\0') + if (*opts++ == ' ') + i++; + return i; +} + +/* + * get_file_options: + * + * If vendor == NULL, find a line in the config file with only "OPTIONS="; + * if vendor and model are set find the first OPTIONS line in the config + * file that matches. Set argc and argv to match the OPTIONS string. + * + * vendor and model can end in '\n'. + */ +static int get_file_options(struct udev *udev, + const char *vendor, const char *model, + int *argc, char ***newargv) +{ + char *buffer; + FILE *fd; + char *buf; + char *str1; + char *vendor_in, *model_in, *options_in; /* read in from file */ + int lineno; + int c; + int retval = 0; + + fd = fopen(config_file, "re"); + if (fd == NULL) { + if (errno == ENOENT) { + return 1; + } else { + log_error("can't open %s: %s\n", config_file, strerror(errno)); + return -1; + } + } + + /* + * Allocate a buffer rather than put it on the stack so we can + * keep it around to parse any options (any allocated newargv + * points into this buffer for its strings). + */ + buffer = malloc(MAX_BUFFER_LEN); + if (!buffer) { + fclose(fd); + return log_oom(); + } + + *newargv = NULL; + lineno = 0; + while (1) { + vendor_in = model_in = options_in = NULL; + + buf = fgets(buffer, MAX_BUFFER_LEN, fd); + if (buf == NULL) + break; + lineno++; + if (buf[strlen(buffer) - 1] != '\n') { + log_error("Config file line %d too long\n", lineno); + break; + } + + while (isspace(*buf)) + buf++; + + /* blank or all whitespace line */ + if (*buf == '\0') + continue; + + /* comment line */ + if (*buf == '#') + continue; + + str1 = strsep(&buf, "="); + if (str1 && strcasecmp(str1, "VENDOR") == 0) { + str1 = get_value(&buf); + if (!str1) { + retval = log_oom(); + break; + } + vendor_in = str1; + + str1 = strsep(&buf, "="); + if (str1 && strcasecmp(str1, "MODEL") == 0) { + str1 = get_value(&buf); + if (!str1) { + retval = log_oom(); + break; + } + model_in = str1; + str1 = strsep(&buf, "="); + } + } + + if (str1 && strcasecmp(str1, "OPTIONS") == 0) { + str1 = get_value(&buf); + if (!str1) { + retval = log_oom(); + break; + } + options_in = str1; + } + + /* + * Only allow: [vendor=foo[,model=bar]]options=stuff + */ + if (!options_in || (!vendor_in && model_in)) { + log_error("Error parsing config file line %d '%s'\n", lineno, buffer); + retval = -1; + break; + } + if (vendor == NULL) { + if (vendor_in == NULL) + break; + } else if ((vendor_in && strncmp(vendor, vendor_in, + strlen(vendor_in)) == 0) && + (!model_in || (strncmp(model, model_in, + strlen(model_in)) == 0))) { + /* + * Matched vendor and optionally model. + * + * Note: a short vendor_in or model_in can + * give a partial match (that is FOO + * matches FOOBAR). + */ + break; + } + } + + if (retval == 0) { + if (vendor_in != NULL || model_in != NULL || + options_in != NULL) { + /* + * Something matched. Allocate newargv, and store + * values found in options_in. + */ + strcpy(buffer, options_in); + c = argc_count(buffer) + 2; + *newargv = calloc(c, sizeof(**newargv)); + if (!*newargv) { + retval = log_oom(); + } else { + *argc = c; + c = 0; + /* + * argv[0] at 0 is skipped by getopt, but + * store the buffer address there for + * later freeing + */ + (*newargv)[c] = buffer; + for (c = 1; c < *argc; c++) + (*newargv)[c] = strsep(&buffer, " \t"); + } + } else { + /* No matches */ + retval = 1; + } + } + if (retval != 0) + free(buffer); + fclose(fd); + return retval; +} + +static int set_options(struct udev *udev, + int argc, char **argv, const char *short_opts, + char *maj_min_dev) +{ + int option; + + /* + * optind is a global extern used by getopt. Since we can call + * set_options twice (once for command line, and once for config + * file) we have to reset this back to 1. + */ + optind = 1; + while (1) { + option = getopt_long(argc, argv, short_opts, options, NULL); + if (option == -1) + break; + + switch (option) { + case 'b': + all_good = 0; + break; + + case 'd': + dev_specified = 1; + util_strscpy(maj_min_dev, MAX_PATH_LEN, optarg); + break; + + case 'e': + use_stderr = 1; + break; + + case 'f': + util_strscpy(config_file, MAX_PATH_LEN, optarg); + break; + + case 'g': + all_good = 1; + break; + + case 'h': + printf("Usage: scsi_id OPTIONS \n" + " --device= device node for SG_IO commands\n" + " --config= location of config file\n" + " --page=0x80|0x83|pre-spc3-83 SCSI page (0x80, 0x83, pre-spc3-83)\n" + " --sg-version=3|4 use SGv3 or SGv4\n" + " --blacklisted threat device as blacklisted\n" + " --whitelisted threat device as whitelisted\n" + " --replace-whitespace replace all whitespaces by underscores\n" + " --verbose verbose logging\n" + " --version print version\n" + " --export print values as environment keys\n" + " --help print this help text\n\n"); + exit(0); + + case 'p': + if (strcmp(optarg, "0x80") == 0) { + default_page_code = PAGE_80; + } else if (strcmp(optarg, "0x83") == 0) { + default_page_code = PAGE_83; + } else if (strcmp(optarg, "pre-spc3-83") == 0) { + default_page_code = PAGE_83_PRE_SPC3; + } else { + log_error("Unknown page code '%s'\n", optarg); + return -1; + } + break; + + case 's': + sg_version = atoi(optarg); + if (sg_version < 3 || sg_version > 4) { + log_error("Unknown SG version '%s'\n", optarg); + return -1; + } + break; + + case 'u': + reformat_serial = 1; + break; + + case 'x': + export = 1; + break; + + case 'v': + debug++; + break; + + case 'V': + printf("%s\n", VERSION); + exit(0); + break; + + default: + exit(1); + } + } + if (optind < argc && !dev_specified) { + dev_specified = 1; + util_strscpy(maj_min_dev, MAX_PATH_LEN, argv[optind]); + } + return 0; +} + +static int per_dev_options(struct udev *udev, + struct scsi_id_device *dev_scsi, int *good_bad, int *page_code) +{ + int retval; + int newargc; + char **newargv = NULL; + int option; + + *good_bad = all_good; + *page_code = default_page_code; + + retval = get_file_options(udev, vendor_str, model_str, &newargc, &newargv); + + optind = 1; /* reset this global extern */ + while (retval == 0) { + option = getopt_long(newargc, newargv, dev_short_options, options, NULL); + if (option == -1) + break; + + switch (option) { + case 'b': + *good_bad = 0; + break; + + case 'g': + *good_bad = 1; + break; + + case 'p': + if (strcmp(optarg, "0x80") == 0) { + *page_code = PAGE_80; + } else if (strcmp(optarg, "0x83") == 0) { + *page_code = PAGE_83; + } else if (strcmp(optarg, "pre-spc3-83") == 0) { + *page_code = PAGE_83_PRE_SPC3; + } else { + log_error("Unknown page code '%s'\n", optarg); + retval = -1; + } + break; + + default: + log_error("Unknown or bad option '%c' (0x%x)\n", option, option); + retval = -1; + break; + } + } + + if (newargv) { + free(newargv[0]); + free(newargv); + } + return retval; +} + +static int set_inq_values(struct udev *udev, struct scsi_id_device *dev_scsi, const char *path) +{ + int retval; + + dev_scsi->use_sg = sg_version; + + retval = scsi_std_inquiry(udev, dev_scsi, path); + if (retval) + return retval; + + udev_util_encode_string(dev_scsi->vendor, vendor_enc_str, sizeof(vendor_enc_str)); + udev_util_encode_string(dev_scsi->model, model_enc_str, sizeof(model_enc_str)); + + util_replace_whitespace(dev_scsi->vendor, vendor_str, sizeof(vendor_str)); + util_replace_chars(vendor_str, NULL); + util_replace_whitespace(dev_scsi->model, model_str, sizeof(model_str)); + util_replace_chars(model_str, NULL); + set_type(dev_scsi->type, type_str, sizeof(type_str)); + util_replace_whitespace(dev_scsi->revision, revision_str, sizeof(revision_str)); + util_replace_chars(revision_str, NULL); + return 0; +} + +/* + * scsi_id: try to get an id, if one is found, printf it to stdout. + * returns a value passed to exit() - 0 if printed an id, else 1. + */ +static int scsi_id(struct udev *udev, char *maj_min_dev) +{ + struct scsi_id_device dev_scsi; + int good_dev; + int page_code; + int retval = 0; + + memset(&dev_scsi, 0x00, sizeof(struct scsi_id_device)); + + if (set_inq_values(udev, &dev_scsi, maj_min_dev) < 0) { + retval = 1; + goto out; + } + + /* get per device (vendor + model) options from the config file */ + per_dev_options(udev, &dev_scsi, &good_dev, &page_code); + if (!good_dev) { + retval = 1; + goto out; + } + + /* read serial number from mode pages (no values for optical drives) */ + scsi_get_serial(udev, &dev_scsi, maj_min_dev, page_code, MAX_SERIAL_LEN); + + if (export) { + char serial_str[MAX_SERIAL_LEN]; + + printf("ID_SCSI=1\n"); + printf("ID_VENDOR=%s\n", vendor_str); + printf("ID_VENDOR_ENC=%s\n", vendor_enc_str); + printf("ID_MODEL=%s\n", model_str); + printf("ID_MODEL_ENC=%s\n", model_enc_str); + printf("ID_REVISION=%s\n", revision_str); + printf("ID_TYPE=%s\n", type_str); + if (dev_scsi.serial[0] != '\0') { + util_replace_whitespace(dev_scsi.serial, serial_str, sizeof(serial_str)); + util_replace_chars(serial_str, NULL); + printf("ID_SERIAL=%s\n", serial_str); + util_replace_whitespace(dev_scsi.serial_short, serial_str, sizeof(serial_str)); + util_replace_chars(serial_str, NULL); + printf("ID_SERIAL_SHORT=%s\n", serial_str); + } + if (dev_scsi.wwn[0] != '\0') { + printf("ID_WWN=0x%s\n", dev_scsi.wwn); + if (dev_scsi.wwn_vendor_extension[0] != '\0') { + printf("ID_WWN_VENDOR_EXTENSION=0x%s\n", dev_scsi.wwn_vendor_extension); + printf("ID_WWN_WITH_EXTENSION=0x%s%s\n", dev_scsi.wwn, dev_scsi.wwn_vendor_extension); + } else { + printf("ID_WWN_WITH_EXTENSION=0x%s\n", dev_scsi.wwn); + } + } + if (dev_scsi.tgpt_group[0] != '\0') { + printf("ID_TARGET_PORT=%s\n", dev_scsi.tgpt_group); + } + if (dev_scsi.unit_serial_number[0] != '\0') { + printf("ID_SCSI_SERIAL=%s\n", dev_scsi.unit_serial_number); + } + goto out; + } + + if (dev_scsi.serial[0] == '\0') { + retval = 1; + goto out; + } + + if (reformat_serial) { + char serial_str[MAX_SERIAL_LEN]; + + util_replace_whitespace(dev_scsi.serial, serial_str, sizeof(serial_str)); + util_replace_chars(serial_str, NULL); + printf("%s\n", serial_str); + goto out; + } + + printf("%s\n", dev_scsi.serial); +out: + return retval; +} + +int main(int argc, char **argv) +{ + struct udev *udev; + int retval = 0; + char maj_min_dev[MAX_PATH_LEN]; + int newargc; + char **newargv; + + udev = udev_new(); + if (udev == NULL) + goto exit; + + log_open(); + udev_set_log_fn(udev, log_fn); + + /* + * Get config file options. + */ + newargv = NULL; + retval = get_file_options(udev, NULL, NULL, &newargc, &newargv); + if (retval < 0) { + retval = 1; + goto exit; + } + if (newargv && (retval == 0)) { + if (set_options(udev, newargc, newargv, short_options, maj_min_dev) < 0) { + retval = 2; + goto exit; + } + free(newargv); + } + + /* + * Get command line options (overriding any config file settings). + */ + if (set_options(udev, argc, argv, short_options, maj_min_dev) < 0) + exit(1); + + if (!dev_specified) { + log_error("no device specified\n"); + retval = 1; + goto exit; + } + + retval = scsi_id(udev, maj_min_dev); + +exit: + udev_unref(udev); + log_close(); + return retval; +} diff --git a/src/udev/scsi_id/scsi_id.h b/src/udev/scsi_id/scsi_id.h new file mode 100644 index 000000000..828a98305 --- /dev/null +++ b/src/udev/scsi_id/scsi_id.h @@ -0,0 +1,73 @@ +/* + * Copyright (C) IBM Corp. 2003 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#define MAX_PATH_LEN 512 + +/* + * MAX_ATTR_LEN: maximum length of the result of reading a sysfs + * attribute. + */ +#define MAX_ATTR_LEN 256 + +/* + * MAX_SERIAL_LEN: the maximum length of the serial number, including + * added prefixes such as vendor and product (model) strings. + */ +#define MAX_SERIAL_LEN 256 + +/* + * MAX_BUFFER_LEN: maximum buffer size and line length used while reading + * the config file. + */ +#define MAX_BUFFER_LEN 256 + +struct scsi_id_device { + char vendor[9]; + char model[17]; + char revision[5]; + char type[33]; + char kernel[64]; + char serial[MAX_SERIAL_LEN]; + char serial_short[MAX_SERIAL_LEN]; + int use_sg; + + /* Always from page 0x80 e.g. 'B3G1P8500RWT' - may not be unique */ + char unit_serial_number[MAX_SERIAL_LEN]; + + /* NULs if not set - otherwise hex encoding using lower-case e.g. '50014ee0016eb572' */ + char wwn[17]; + + /* NULs if not set - otherwise hex encoding using lower-case e.g. '0xe00000d80000' */ + char wwn_vendor_extension[17]; + + /* NULs if not set - otherwise decimal number */ + char tgpt_group[8]; +}; + +extern int scsi_std_inquiry(struct udev *udev, struct scsi_id_device *dev_scsi, const char *devname); +extern int scsi_get_serial (struct udev *udev, struct scsi_id_device *dev_scsi, const char *devname, + int page_code, int len); + +/* + * Page code values. + */ +enum page_code { + PAGE_83_PRE_SPC3 = -0x83, + PAGE_UNSPECIFIED = 0x00, + PAGE_80 = 0x80, + PAGE_83 = 0x83, +}; diff --git a/src/udev/scsi_id/scsi_serial.c b/src/udev/scsi_id/scsi_serial.c new file mode 100644 index 000000000..3c52dee62 --- /dev/null +++ b/src/udev/scsi_id/scsi_serial.c @@ -0,0 +1,968 @@ +/* + * Copyright (C) IBM Corp. 2003 + * + * Author: Patrick Mansfield + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "libudev.h" +#include "libudev-private.h" +#include "scsi.h" +#include "scsi_id.h" + +/* + * A priority based list of id, naa, and binary/ascii for the identifier + * descriptor in VPD page 0x83. + * + * Brute force search for a match starting with the first value in the + * following id_search_list. This is not a performance issue, since there + * is normally one or some small number of descriptors. + */ +static const struct scsi_id_search_values id_search_list[] = { + { SCSI_ID_TGTGROUP, SCSI_ID_NAA_DONT_CARE, SCSI_ID_BINARY }, + { SCSI_ID_NAA, SCSI_ID_NAA_IEEE_REG_EXTENDED, SCSI_ID_BINARY }, + { SCSI_ID_NAA, SCSI_ID_NAA_IEEE_REG_EXTENDED, SCSI_ID_ASCII }, + { SCSI_ID_NAA, SCSI_ID_NAA_IEEE_REG, SCSI_ID_BINARY }, + { SCSI_ID_NAA, SCSI_ID_NAA_IEEE_REG, SCSI_ID_ASCII }, + /* + * Devices already exist using NAA values that are now marked + * reserved. These should not conflict with other values, or it is + * a bug in the device. As long as we find the IEEE extended one + * first, we really don't care what other ones are used. Using + * don't care here means that a device that returns multiple + * non-IEEE descriptors in a random order will get different + * names. + */ + { SCSI_ID_NAA, SCSI_ID_NAA_DONT_CARE, SCSI_ID_BINARY }, + { SCSI_ID_NAA, SCSI_ID_NAA_DONT_CARE, SCSI_ID_ASCII }, + { SCSI_ID_EUI_64, SCSI_ID_NAA_DONT_CARE, SCSI_ID_BINARY }, + { SCSI_ID_EUI_64, SCSI_ID_NAA_DONT_CARE, SCSI_ID_ASCII }, + { SCSI_ID_T10_VENDOR, SCSI_ID_NAA_DONT_CARE, SCSI_ID_BINARY }, + { SCSI_ID_T10_VENDOR, SCSI_ID_NAA_DONT_CARE, SCSI_ID_ASCII }, + { SCSI_ID_VENDOR_SPECIFIC, SCSI_ID_NAA_DONT_CARE, SCSI_ID_BINARY }, + { SCSI_ID_VENDOR_SPECIFIC, SCSI_ID_NAA_DONT_CARE, SCSI_ID_ASCII }, +}; + +static const char hex_str[]="0123456789abcdef"; + +/* + * Values returned in the result/status, only the ones used by the code + * are used here. + */ + +#define DID_NO_CONNECT 0x01 /* Unable to connect before timeout */ +#define DID_BUS_BUSY 0x02 /* Bus remain busy until timeout */ +#define DID_TIME_OUT 0x03 /* Timed out for some other reason */ +#define DRIVER_TIMEOUT 0x06 +#define DRIVER_SENSE 0x08 /* Sense_buffer has been set */ + +/* The following "category" function returns one of the following */ +#define SG_ERR_CAT_CLEAN 0 /* No errors or other information */ +#define SG_ERR_CAT_MEDIA_CHANGED 1 /* interpreted from sense buffer */ +#define SG_ERR_CAT_RESET 2 /* interpreted from sense buffer */ +#define SG_ERR_CAT_TIMEOUT 3 +#define SG_ERR_CAT_RECOVERED 4 /* Successful command after recovered err */ +#define SG_ERR_CAT_NOTSUPPORTED 5 /* Illegal / unsupported command */ +#define SG_ERR_CAT_SENSE 98 /* Something else in the sense buffer */ +#define SG_ERR_CAT_OTHER 99 /* Some other error/warning */ + +static int do_scsi_page80_inquiry(struct udev *udev, + struct scsi_id_device *dev_scsi, int fd, + char *serial, char *serial_short, int max_len); + +static int sg_err_category_new(struct udev *udev, + int scsi_status, int msg_status, int + host_status, int driver_status, const + unsigned char *sense_buffer, int sb_len) +{ + scsi_status &= 0x7e; + + /* + * XXX change to return only two values - failed or OK. + */ + + if (!scsi_status && !host_status && !driver_status) + return SG_ERR_CAT_CLEAN; + + if ((scsi_status == SCSI_CHECK_CONDITION) || + (scsi_status == SCSI_COMMAND_TERMINATED) || + ((driver_status & 0xf) == DRIVER_SENSE)) { + if (sense_buffer && (sb_len > 2)) { + int sense_key; + unsigned char asc; + + if (sense_buffer[0] & 0x2) { + sense_key = sense_buffer[1] & 0xf; + asc = sense_buffer[2]; + } else { + sense_key = sense_buffer[2] & 0xf; + asc = (sb_len > 12) ? sense_buffer[12] : 0; + } + + if (sense_key == RECOVERED_ERROR) + return SG_ERR_CAT_RECOVERED; + else if (sense_key == UNIT_ATTENTION) { + if (0x28 == asc) + return SG_ERR_CAT_MEDIA_CHANGED; + if (0x29 == asc) + return SG_ERR_CAT_RESET; + } else if (sense_key == ILLEGAL_REQUEST) { + return SG_ERR_CAT_NOTSUPPORTED; + } + } + return SG_ERR_CAT_SENSE; + } + if (host_status) { + if ((host_status == DID_NO_CONNECT) || + (host_status == DID_BUS_BUSY) || + (host_status == DID_TIME_OUT)) + return SG_ERR_CAT_TIMEOUT; + } + if (driver_status) { + if (driver_status == DRIVER_TIMEOUT) + return SG_ERR_CAT_TIMEOUT; + } + return SG_ERR_CAT_OTHER; +} + +static int sg_err_category3(struct udev *udev, struct sg_io_hdr *hp) +{ + return sg_err_category_new(udev, + hp->status, hp->msg_status, + hp->host_status, hp->driver_status, + hp->sbp, hp->sb_len_wr); +} + +static int sg_err_category4(struct udev *udev, struct sg_io_v4 *hp) +{ + return sg_err_category_new(udev, hp->device_status, 0, + hp->transport_status, hp->driver_status, + (unsigned char *)(uintptr_t)hp->response, + hp->response_len); +} + +static int scsi_dump_sense(struct udev *udev, + struct scsi_id_device *dev_scsi, + unsigned char *sense_buffer, int sb_len) +{ + int s; + int code; + int sense_class; + int sense_key; + int asc, ascq; +#ifdef DUMP_SENSE + char out_buffer[256]; + int i, j; +#endif + + /* + * Figure out and print the sense key, asc and ascq. + * + * If you want to suppress these for a particular drive model, add + * a black list entry in the scsi_id config file. + * + * XXX We probably need to: lookup the sense/asc/ascq in a retry + * table, and if found return 1 (after dumping the sense, asc, and + * ascq). So, if/when we get something like a power on/reset, + * we'll retry the command. + */ + + if (sb_len < 1) { + log_debug("%s: sense buffer empty\n", dev_scsi->kernel); + return -1; + } + + sense_class = (sense_buffer[0] >> 4) & 0x07; + code = sense_buffer[0] & 0xf; + + if (sense_class == 7) { + /* + * extended sense data. + */ + s = sense_buffer[7] + 8; + if (sb_len < s) { + log_debug("%s: sense buffer too small %d bytes, %d bytes too short\n", + dev_scsi->kernel, sb_len, s - sb_len); + return -1; + } + if ((code == 0x0) || (code == 0x1)) { + sense_key = sense_buffer[2] & 0xf; + if (s < 14) { + /* + * Possible? + */ + log_debug("%s: sense result too" " small %d bytes\n", + dev_scsi->kernel, s); + return -1; + } + asc = sense_buffer[12]; + ascq = sense_buffer[13]; + } else if ((code == 0x2) || (code == 0x3)) { + sense_key = sense_buffer[1] & 0xf; + asc = sense_buffer[2]; + ascq = sense_buffer[3]; + } else { + log_debug("%s: invalid sense code 0x%x\n", + dev_scsi->kernel, code); + return -1; + } + log_debug("%s: sense key 0x%x ASC 0x%x ASCQ 0x%x\n", + dev_scsi->kernel, sense_key, asc, ascq); + } else { + if (sb_len < 4) { + log_debug("%s: sense buffer too small %d bytes, %d bytes too short\n", + dev_scsi->kernel, sb_len, 4 - sb_len); + return -1; + } + + if (sense_buffer[0] < 15) + log_debug("%s: old sense key: 0x%x\n", dev_scsi->kernel, sense_buffer[0] & 0x0f); + else + log_debug("%s: sense = %2x %2x\n", + dev_scsi->kernel, sense_buffer[0], sense_buffer[2]); + log_debug("%s: non-extended sense class %d code 0x%0x\n", + dev_scsi->kernel, sense_class, code); + + } + +#ifdef DUMP_SENSE + for (i = 0, j = 0; (i < s) && (j < 254); i++) { + out_buffer[j++] = hex_str[(sense_buffer[i] & 0xf0) >> 4]; + out_buffer[j++] = hex_str[sense_buffer[i] & 0x0f]; + out_buffer[j++] = ' '; + } + out_buffer[j] = '\0'; + log_debug("%s: sense dump:\n", dev_scsi->kernel); + log_debug("%s: %s\n", dev_scsi->kernel, out_buffer); + +#endif + return -1; +} + +static int scsi_dump(struct udev *udev, + struct scsi_id_device *dev_scsi, struct sg_io_hdr *io) +{ + if (!io->status && !io->host_status && !io->msg_status && + !io->driver_status) { + /* + * Impossible, should not be called. + */ + log_debug("%s: called with no error\n", __FUNCTION__); + return -1; + } + + log_debug("%s: sg_io failed status 0x%x 0x%x 0x%x 0x%x\n", + dev_scsi->kernel, io->driver_status, io->host_status, io->msg_status, io->status); + if (io->status == SCSI_CHECK_CONDITION) + return scsi_dump_sense(udev, dev_scsi, io->sbp, io->sb_len_wr); + else + return -1; +} + +static int scsi_dump_v4(struct udev *udev, + struct scsi_id_device *dev_scsi, struct sg_io_v4 *io) +{ + if (!io->device_status && !io->transport_status && + !io->driver_status) { + /* + * Impossible, should not be called. + */ + log_debug("%s: called with no error\n", __FUNCTION__); + return -1; + } + + log_debug("%s: sg_io failed status 0x%x 0x%x 0x%x\n", + dev_scsi->kernel, io->driver_status, io->transport_status, + io->device_status); + if (io->device_status == SCSI_CHECK_CONDITION) + return scsi_dump_sense(udev, dev_scsi, (unsigned char *)(uintptr_t)io->response, + io->response_len); + else + return -1; +} + +static int scsi_inquiry(struct udev *udev, + struct scsi_id_device *dev_scsi, int fd, + unsigned char evpd, unsigned char page, + unsigned char *buf, unsigned int buflen) +{ + unsigned char inq_cmd[INQUIRY_CMDLEN] = + { INQUIRY_CMD, evpd, page, 0, buflen, 0 }; + unsigned char sense[SENSE_BUFF_LEN]; + void *io_buf; + struct sg_io_v4 io_v4; + struct sg_io_hdr io_hdr; + int retry = 3; /* rather random */ + int retval; + + if (buflen > SCSI_INQ_BUFF_LEN) { + log_debug("buflen %d too long\n", buflen); + return -1; + } + +resend: + if (dev_scsi->use_sg == 4) { + memset(&io_v4, 0, sizeof(struct sg_io_v4)); + io_v4.guard = 'Q'; + io_v4.protocol = BSG_PROTOCOL_SCSI; + io_v4.subprotocol = BSG_SUB_PROTOCOL_SCSI_CMD; + io_v4.request_len = sizeof(inq_cmd); + io_v4.request = (uintptr_t)inq_cmd; + io_v4.max_response_len = sizeof(sense); + io_v4.response = (uintptr_t)sense; + io_v4.din_xfer_len = buflen; + io_v4.din_xferp = (uintptr_t)buf; + io_buf = (void *)&io_v4; + } else { + memset(&io_hdr, 0, sizeof(struct sg_io_hdr)); + io_hdr.interface_id = 'S'; + io_hdr.cmd_len = sizeof(inq_cmd); + io_hdr.mx_sb_len = sizeof(sense); + io_hdr.dxfer_direction = SG_DXFER_FROM_DEV; + io_hdr.dxfer_len = buflen; + io_hdr.dxferp = buf; + io_hdr.cmdp = inq_cmd; + io_hdr.sbp = sense; + io_hdr.timeout = DEF_TIMEOUT; + io_buf = (void *)&io_hdr; + } + + retval = ioctl(fd, SG_IO, io_buf); + if (retval < 0) { + if ((errno == EINVAL || errno == ENOSYS) && dev_scsi->use_sg == 4) { + dev_scsi->use_sg = 3; + goto resend; + } + log_debug("%s: ioctl failed: %s\n", dev_scsi->kernel, strerror(errno)); + goto error; + } + + if (dev_scsi->use_sg == 4) + retval = sg_err_category4(udev, io_buf); + else + retval = sg_err_category3(udev, io_buf); + + switch (retval) { + case SG_ERR_CAT_NOTSUPPORTED: + buf[1] = 0; + /* Fallthrough */ + case SG_ERR_CAT_CLEAN: + case SG_ERR_CAT_RECOVERED: + retval = 0; + break; + + default: + if (dev_scsi->use_sg == 4) + retval = scsi_dump_v4(udev, dev_scsi, io_buf); + else + retval = scsi_dump(udev, dev_scsi, io_buf); + } + + if (!retval) { + retval = buflen; + } else if (retval > 0) { + if (--retry > 0) + goto resend; + retval = -1; + } + +error: + if (retval < 0) + log_debug("%s: Unable to get INQUIRY vpd %d page 0x%x.\n", + dev_scsi->kernel, evpd, page); + + return retval; +} + +/* Get list of supported EVPD pages */ +static int do_scsi_page0_inquiry(struct udev *udev, + struct scsi_id_device *dev_scsi, int fd, + unsigned char *buffer, unsigned int len) +{ + int retval; + + memset(buffer, 0, len); + retval = scsi_inquiry(udev, dev_scsi, fd, 1, 0x0, buffer, len); + if (retval < 0) + return 1; + + if (buffer[1] != 0) { + log_debug("%s: page 0 not available.\n", dev_scsi->kernel); + return 1; + } + if (buffer[3] > len) { + log_debug("%s: page 0 buffer too long %d\n", dev_scsi->kernel, buffer[3]); + return 1; + } + + /* + * Following check is based on code once included in the 2.5.x + * kernel. + * + * Some ill behaved devices return the standard inquiry here + * rather than the evpd data, snoop the data to verify. + */ + if (buffer[3] > MODEL_LENGTH) { + /* + * If the vendor id appears in the page assume the page is + * invalid. + */ + if (!strncmp((char *)&buffer[VENDOR_LENGTH], dev_scsi->vendor, VENDOR_LENGTH)) { + log_debug("%s: invalid page0 data\n", dev_scsi->kernel); + return 1; + } + } + return 0; +} + +/* + * The caller checks that serial is long enough to include the vendor + + * model. + */ +static int prepend_vendor_model(struct udev *udev, + struct scsi_id_device *dev_scsi, char *serial) +{ + int ind; + + strncpy(serial, dev_scsi->vendor, VENDOR_LENGTH); + strncat(serial, dev_scsi->model, MODEL_LENGTH); + ind = strlen(serial); + + /* + * This is not a complete check, since we are using strncat/cpy + * above, ind will never be too large. + */ + if (ind != (VENDOR_LENGTH + MODEL_LENGTH)) { + log_debug("%s: expected length %d, got length %d\n", + dev_scsi->kernel, (VENDOR_LENGTH + MODEL_LENGTH), ind); + return -1; + } + return ind; +} + +/* + * check_fill_0x83_id - check the page 0x83 id, if OK allocate and fill + * serial number. + */ +static int check_fill_0x83_id(struct udev *udev, + struct scsi_id_device *dev_scsi, + unsigned char *page_83, + const struct scsi_id_search_values + *id_search, char *serial, char *serial_short, + int max_len, char *wwn, + char *wwn_vendor_extension, char *tgpt_group) +{ + int i, j, s, len; + + /* + * ASSOCIATION must be with the device (value 0) + * or with the target port for SCSI_ID_TGTPORT + */ + if ((page_83[1] & 0x30) == 0x10) { + if (id_search->id_type != SCSI_ID_TGTGROUP) + return 1; + } else if ((page_83[1] & 0x30) != 0) { + return 1; + } + + if ((page_83[1] & 0x0f) != id_search->id_type) + return 1; + + /* + * Possibly check NAA sub-type. + */ + if ((id_search->naa_type != SCSI_ID_NAA_DONT_CARE) && + (id_search->naa_type != (page_83[4] & 0xf0) >> 4)) + return 1; + + /* + * Check for matching code set - ASCII or BINARY. + */ + if ((page_83[0] & 0x0f) != id_search->code_set) + return 1; + + /* + * page_83[3]: identifier length + */ + len = page_83[3]; + if ((page_83[0] & 0x0f) != SCSI_ID_ASCII) + /* + * If not ASCII, use two bytes for each binary value. + */ + len *= 2; + + /* + * Add one byte for the NUL termination, and one for the id_type. + */ + len += 2; + if (id_search->id_type == SCSI_ID_VENDOR_SPECIFIC) + len += VENDOR_LENGTH + MODEL_LENGTH; + + if (max_len < len) { + log_debug("%s: length %d too short - need %d\n", + dev_scsi->kernel, max_len, len); + return 1; + } + + if (id_search->id_type == SCSI_ID_TGTGROUP && tgpt_group != NULL) { + unsigned int group; + + group = ((unsigned int)page_83[6] << 8) | page_83[7]; + sprintf(tgpt_group,"%x", group); + return 1; + } + + serial[0] = hex_str[id_search->id_type]; + + /* + * For SCSI_ID_VENDOR_SPECIFIC prepend the vendor and model before + * the id since it is not unique across all vendors and models, + * this differs from SCSI_ID_T10_VENDOR, where the vendor is + * included in the identifier. + */ + if (id_search->id_type == SCSI_ID_VENDOR_SPECIFIC) + if (prepend_vendor_model(udev, dev_scsi, &serial[1]) < 0) + return 1; + + i = 4; /* offset to the start of the identifier */ + s = j = strlen(serial); + if ((page_83[0] & 0x0f) == SCSI_ID_ASCII) { + /* + * ASCII descriptor. + */ + while (i < (4 + page_83[3])) + serial[j++] = page_83[i++]; + } else { + /* + * Binary descriptor, convert to ASCII, using two bytes of + * ASCII for each byte in the page_83. + */ + while (i < (4 + page_83[3])) { + serial[j++] = hex_str[(page_83[i] & 0xf0) >> 4]; + serial[j++] = hex_str[page_83[i] & 0x0f]; + i++; + } + } + + strcpy(serial_short, &serial[s]); + + if (id_search->id_type == SCSI_ID_NAA && wwn != NULL) { + strncpy(wwn, &serial[s], 16); + if (wwn_vendor_extension != NULL) { + strncpy(wwn_vendor_extension, &serial[s + 16], 16); + } + } + + return 0; +} + +/* Extract the raw binary from VPD 0x83 pre-SPC devices */ +static int check_fill_0x83_prespc3(struct udev *udev, + struct scsi_id_device *dev_scsi, + unsigned char *page_83, + const struct scsi_id_search_values + *id_search, char *serial, char *serial_short, int max_len) +{ + int i, j; + + serial[0] = hex_str[id_search->id_type]; + /* serial has been memset to zero before */ + j = strlen(serial); /* j = 1; */ + + for (i = 0; (i < page_83[3]) && (j < max_len-3); ++i) { + serial[j++] = hex_str[(page_83[4+i] & 0xf0) >> 4]; + serial[j++] = hex_str[ page_83[4+i] & 0x0f]; + } + serial[max_len-1] = 0; + strncpy(serial_short, serial, max_len-1); + return 0; +} + + +/* Get device identification VPD page */ +static int do_scsi_page83_inquiry(struct udev *udev, + struct scsi_id_device *dev_scsi, int fd, + char *serial, char *serial_short, int len, + char *unit_serial_number, char *wwn, + char *wwn_vendor_extension, char *tgpt_group) +{ + int retval; + unsigned int id_ind, j; + unsigned char page_83[SCSI_INQ_BUFF_LEN]; + + /* also pick up the page 80 serial number */ + do_scsi_page80_inquiry(udev, dev_scsi, fd, NULL, unit_serial_number, MAX_SERIAL_LEN); + + memset(page_83, 0, SCSI_INQ_BUFF_LEN); + retval = scsi_inquiry(udev, dev_scsi, fd, 1, PAGE_83, page_83, + SCSI_INQ_BUFF_LEN); + if (retval < 0) + return 1; + + if (page_83[1] != PAGE_83) { + log_debug("%s: Invalid page 0x83\n", dev_scsi->kernel); + return 1; + } + + /* + * XXX Some devices (IBM 3542) return all spaces for an identifier if + * the LUN is not actually configured. This leads to identifiers of + * the form: "1 ". + */ + + /* + * Model 4, 5, and (some) model 6 EMC Symmetrix devices return + * a page 83 reply according to SCSI-2 format instead of SPC-2/3. + * + * The SCSI-2 page 83 format returns an IEEE WWN in binary + * encoded hexi-decimal in the 16 bytes following the initial + * 4-byte page 83 reply header. + * + * Both the SPC-2 and SPC-3 formats return an IEEE WWN as part + * of an Identification descriptor. The 3rd byte of the first + * Identification descriptor is a reserved (BSZ) byte field. + * + * Reference the 7th byte of the page 83 reply to determine + * whether the reply is compliant with SCSI-2 or SPC-2/3 + * specifications. A zero value in the 7th byte indicates + * an SPC-2/3 conformant reply, (i.e., the reserved field of the + * first Identification descriptor). This byte will be non-zero + * for a SCSI-2 conformant page 83 reply from these EMC + * Symmetrix models since the 7th byte of the reply corresponds + * to the 4th and 5th nibbles of the 6-byte OUI for EMC, that is, + * 0x006048. + */ + + if (page_83[6] != 0) + return check_fill_0x83_prespc3(udev, + dev_scsi, page_83, id_search_list, + serial, serial_short, len); + + /* + * Search for a match in the prioritized id_search_list - since WWN ids + * come first we can pick up the WWN in check_fill_0x83_id(). + */ + for (id_ind = 0; + id_ind < sizeof(id_search_list)/sizeof(id_search_list[0]); + id_ind++) { + /* + * Examine each descriptor returned. There is normally only + * one or a small number of descriptors. + */ + for (j = 4; j <= (unsigned int)page_83[3] + 3; j += page_83[j + 3] + 4) { + retval = check_fill_0x83_id(udev, + dev_scsi, &page_83[j], + &id_search_list[id_ind], + serial, serial_short, len, + wwn, wwn_vendor_extension, + tgpt_group); + if (!retval) + return retval; + else if (retval < 0) + return retval; + } + } + return 1; +} + +/* + * Get device identification VPD page for older SCSI-2 device which is not + * compliant with either SPC-2 or SPC-3 format. + * + * Return the hard coded error code value 2 if the page 83 reply is not + * conformant to the SCSI-2 format. + */ +static int do_scsi_page83_prespc3_inquiry(struct udev *udev, + struct scsi_id_device *dev_scsi, int fd, + char *serial, char *serial_short, int len) +{ + int retval; + int i, j; + unsigned char page_83[SCSI_INQ_BUFF_LEN]; + + memset(page_83, 0, SCSI_INQ_BUFF_LEN); + retval = scsi_inquiry(udev, dev_scsi, fd, 1, PAGE_83, page_83, SCSI_INQ_BUFF_LEN); + if (retval < 0) + return 1; + + if (page_83[1] != PAGE_83) { + log_debug("%s: Invalid page 0x83\n", dev_scsi->kernel); + return 1; + } + /* + * Model 4, 5, and (some) model 6 EMC Symmetrix devices return + * a page 83 reply according to SCSI-2 format instead of SPC-2/3. + * + * The SCSI-2 page 83 format returns an IEEE WWN in binary + * encoded hexi-decimal in the 16 bytes following the initial + * 4-byte page 83 reply header. + * + * Both the SPC-2 and SPC-3 formats return an IEEE WWN as part + * of an Identification descriptor. The 3rd byte of the first + * Identification descriptor is a reserved (BSZ) byte field. + * + * Reference the 7th byte of the page 83 reply to determine + * whether the reply is compliant with SCSI-2 or SPC-2/3 + * specifications. A zero value in the 7th byte indicates + * an SPC-2/3 conformant reply, (i.e., the reserved field of the + * first Identification descriptor). This byte will be non-zero + * for a SCSI-2 conformant page 83 reply from these EMC + * Symmetrix models since the 7th byte of the reply corresponds + * to the 4th and 5th nibbles of the 6-byte OUI for EMC, that is, + * 0x006048. + */ + if (page_83[6] == 0) + return 2; + + serial[0] = hex_str[id_search_list[0].id_type]; + /* + * The first four bytes contain data, not a descriptor. + */ + i = 4; + j = strlen(serial); + /* + * Binary descriptor, convert to ASCII, + * using two bytes of ASCII for each byte + * in the page_83. + */ + while (i < (page_83[3]+4)) { + serial[j++] = hex_str[(page_83[i] & 0xf0) >> 4]; + serial[j++] = hex_str[page_83[i] & 0x0f]; + i++; + } + return 0; +} + +/* Get unit serial number VPD page */ +static int do_scsi_page80_inquiry(struct udev *udev, + struct scsi_id_device *dev_scsi, int fd, + char *serial, char *serial_short, int max_len) +{ + int retval; + int ser_ind; + int i; + int len; + unsigned char buf[SCSI_INQ_BUFF_LEN]; + + memset(buf, 0, SCSI_INQ_BUFF_LEN); + retval = scsi_inquiry(udev, dev_scsi, fd, 1, PAGE_80, buf, SCSI_INQ_BUFF_LEN); + if (retval < 0) + return retval; + + if (buf[1] != PAGE_80) { + log_debug("%s: Invalid page 0x80\n", dev_scsi->kernel); + return 1; + } + + len = 1 + VENDOR_LENGTH + MODEL_LENGTH + buf[3]; + if (max_len < len) { + log_debug("%s: length %d too short - need %d\n", + dev_scsi->kernel, max_len, len); + return 1; + } + /* + * Prepend 'S' to avoid unlikely collision with page 0x83 vendor + * specific type where we prepend '0' + vendor + model. + */ + len = buf[3]; + if (serial != NULL) { + serial[0] = 'S'; + ser_ind = prepend_vendor_model(udev, dev_scsi, &serial[1]); + if (ser_ind < 0) + return 1; + ser_ind++; /* for the leading 'S' */ + for (i = 4; i < len + 4; i++, ser_ind++) + serial[ser_ind] = buf[i]; + } + if (serial_short != NULL) { + memcpy(serial_short, &buf[4], len); + serial_short[len] = '\0'; + } + return 0; +} + +int scsi_std_inquiry(struct udev *udev, + struct scsi_id_device *dev_scsi, const char *devname) +{ + int fd; + unsigned char buf[SCSI_INQ_BUFF_LEN]; + struct stat statbuf; + int err = 0; + + fd = open(devname, O_RDONLY | O_NONBLOCK); + if (fd < 0) { + log_debug("scsi_id: cannot open %s: %s\n", + devname, strerror(errno)); + return 1; + } + + if (fstat(fd, &statbuf) < 0) { + log_debug("scsi_id: cannot stat %s: %s\n", + devname, strerror(errno)); + err = 2; + goto out; + } + sprintf(dev_scsi->kernel,"%d:%d", major(statbuf.st_rdev), + minor(statbuf.st_rdev)); + + memset(buf, 0, SCSI_INQ_BUFF_LEN); + err = scsi_inquiry(udev, dev_scsi, fd, 0, 0, buf, SCSI_INQ_BUFF_LEN); + if (err < 0) + goto out; + + err = 0; + memcpy(dev_scsi->vendor, buf + 8, 8); + dev_scsi->vendor[8] = '\0'; + memcpy(dev_scsi->model, buf + 16, 16); + dev_scsi->model[16] = '\0'; + memcpy(dev_scsi->revision, buf + 32, 4); + dev_scsi->revision[4] = '\0'; + sprintf(dev_scsi->type,"%x", buf[0] & 0x1f); + +out: + close(fd); + return err; +} + +int scsi_get_serial(struct udev *udev, + struct scsi_id_device *dev_scsi, const char *devname, + int page_code, int len) +{ + unsigned char page0[SCSI_INQ_BUFF_LEN]; + int fd = -1; + int cnt; + int ind; + int retval; + + memset(dev_scsi->serial, 0, len); + srand((unsigned int)getpid()); + for (cnt = 20; cnt > 0; cnt--) { + struct timespec duration; + + fd = open(devname, O_RDONLY | O_NONBLOCK); + if (fd >= 0 || errno != EBUSY) + break; + duration.tv_sec = 0; + duration.tv_nsec = (200 * 1000 * 1000) + (rand() % 100 * 1000 * 1000); + nanosleep(&duration, NULL); + } + if (fd < 0) + return 1; + + if (page_code == PAGE_80) { + if (do_scsi_page80_inquiry(udev, dev_scsi, fd, dev_scsi->serial, dev_scsi->serial_short, len)) { + retval = 1; + goto completed; + } else { + retval = 0; + goto completed; + } + } else if (page_code == PAGE_83) { + if (do_scsi_page83_inquiry(udev, dev_scsi, fd, dev_scsi->serial, dev_scsi->serial_short, len, dev_scsi->unit_serial_number, dev_scsi->wwn, dev_scsi->wwn_vendor_extension, dev_scsi->tgpt_group)) { + retval = 1; + goto completed; + } else { + retval = 0; + goto completed; + } + } else if (page_code == PAGE_83_PRE_SPC3) { + retval = do_scsi_page83_prespc3_inquiry(udev, dev_scsi, fd, dev_scsi->serial, dev_scsi->serial_short, len); + if (retval) { + /* + * Fallback to servicing a SPC-2/3 compliant page 83 + * inquiry if the page 83 reply format does not + * conform to pre-SPC3 expectations. + */ + if (retval == 2) { + if (do_scsi_page83_inquiry(udev, dev_scsi, fd, dev_scsi->serial, dev_scsi->serial_short, len, dev_scsi->unit_serial_number, dev_scsi->wwn, dev_scsi->wwn_vendor_extension, dev_scsi->tgpt_group)) { + retval = 1; + goto completed; + } else { + retval = 0; + goto completed; + } + } + else { + retval = 1; + goto completed; + } + } else { + retval = 0; + goto completed; + } + } else if (page_code != 0x00) { + log_debug("%s: unsupported page code 0x%d\n", dev_scsi->kernel, page_code); + retval = 1; + goto completed; + } + + /* + * Get page 0, the page of the pages. By default, try from best to + * worst of supported pages: 0x83 then 0x80. + */ + if (do_scsi_page0_inquiry(udev, dev_scsi, fd, page0, SCSI_INQ_BUFF_LEN)) { + /* + * Don't try anything else. Black list if a specific page + * should be used for this vendor+model, or maybe have an + * optional fall-back to page 0x80 or page 0x83. + */ + retval = 1; + goto completed; + } + + for (ind = 4; ind <= page0[3] + 3; ind++) + if (page0[ind] == PAGE_83) + if (!do_scsi_page83_inquiry(udev, dev_scsi, fd, + dev_scsi->serial, dev_scsi->serial_short, len, dev_scsi->unit_serial_number, dev_scsi->wwn, dev_scsi->wwn_vendor_extension, dev_scsi->tgpt_group)) { + /* + * Success + */ + retval = 0; + goto completed; + } + + for (ind = 4; ind <= page0[3] + 3; ind++) + if (page0[ind] == PAGE_80) + if (!do_scsi_page80_inquiry(udev, dev_scsi, fd, + dev_scsi->serial, dev_scsi->serial_short, len)) { + /* + * Success + */ + retval = 0; + goto completed; + } + retval = 1; + +completed: + close(fd); + return retval; +} diff --git a/src/udev/udev-builtin-blkid.c b/src/udev/udev-builtin-blkid.c new file mode 100644 index 000000000..429310304 --- /dev/null +++ b/src/udev/udev-builtin-blkid.c @@ -0,0 +1,204 @@ +/* + * probe disks for filesystems and partitions + * + * Copyright (C) 2011 Kay Sievers + * Copyright (C) 2011 Karel Zak + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "udev.h" + +static void print_property(struct udev_device *dev, bool test, const char *name, const char *value) +{ + char s[265]; + + s[0] = '\0'; + + if (streq(name, "TYPE")) { + udev_builtin_add_property(dev, test, "ID_FS_TYPE", value); + + } else if (streq(name, "USAGE")) { + udev_builtin_add_property(dev, test, "ID_FS_USAGE", value); + + } else if (streq(name, "VERSION")) { + udev_builtin_add_property(dev, test, "ID_FS_VERSION", value); + + } else if (streq(name, "UUID")) { + blkid_safe_string(value, s, sizeof(s)); + udev_builtin_add_property(dev, test, "ID_FS_UUID", s); + blkid_encode_string(value, s, sizeof(s)); + udev_builtin_add_property(dev, test, "ID_FS_UUID_ENC", s); + + } else if (streq(name, "UUID_SUB")) { + blkid_safe_string(value, s, sizeof(s)); + udev_builtin_add_property(dev, test, "ID_FS_UUID_SUB", s); + blkid_encode_string(value, s, sizeof(s)); + udev_builtin_add_property(dev, test, "ID_FS_UUID_SUB_ENC", s); + + } else if (streq(name, "LABEL")) { + blkid_safe_string(value, s, sizeof(s)); + udev_builtin_add_property(dev, test, "ID_FS_LABEL", s); + blkid_encode_string(value, s, sizeof(s)); + udev_builtin_add_property(dev, test, "ID_FS_LABEL_ENC", s); + + } else if (streq(name, "PTTYPE")) { + udev_builtin_add_property(dev, test, "ID_PART_TABLE_TYPE", value); + + } else if (streq(name, "PART_ENTRY_NAME")) { + blkid_encode_string(value, s, sizeof(s)); + udev_builtin_add_property(dev, test, "ID_PART_ENTRY_NAME", s); + + } else if (streq(name, "PART_ENTRY_TYPE")) { + blkid_encode_string(value, s, sizeof(s)); + udev_builtin_add_property(dev, test, "ID_PART_ENTRY_TYPE", s); + + } else if (startswith(name, "PART_ENTRY_")) { + util_strscpyl(s, sizeof(s), "ID_", name, NULL); + udev_builtin_add_property(dev, test, s, value); + } +} + +static int probe_superblocks(blkid_probe pr) +{ + struct stat st; + int rc; + + if (fstat(blkid_probe_get_fd(pr), &st)) + return -1; + + blkid_probe_enable_partitions(pr, 1); + + if (!S_ISCHR(st.st_mode) && blkid_probe_get_size(pr) <= 1024 * 1440 && + blkid_probe_is_wholedisk(pr)) { + /* + * check if the small disk is partitioned, if yes then + * don't probe for filesystems. + */ + blkid_probe_enable_superblocks(pr, 0); + + rc = blkid_do_fullprobe(pr); + if (rc < 0) + return rc; /* -1 = error, 1 = nothing, 0 = succes */ + + if (blkid_probe_lookup_value(pr, "PTTYPE", NULL, NULL) == 0) + return 0; /* partition table detected */ + } + + blkid_probe_set_partitions_flags(pr, BLKID_PARTS_ENTRY_DETAILS); + blkid_probe_enable_superblocks(pr, 1); + + return blkid_do_safeprobe(pr); +} + +static int builtin_blkid(struct udev_device *dev, int argc, char *argv[], bool test) +{ + int64_t offset = 0; + bool noraid = false; + int fd = -1; + blkid_probe pr; + const char *data; + const char *name; + int nvals; + int i; + size_t len; + int err = 0; + + static const struct option options[] = { + { "offset", optional_argument, NULL, 'o' }, + { "noraid", no_argument, NULL, 'R' }, + {} + }; + + for (;;) { + int option; + + option = getopt_long(argc, argv, "oR", options, NULL); + if (option == -1) + break; + + switch (option) { + case 'o': + offset = strtoull(optarg, NULL, 0); + break; + case 'R': + noraid = true; + break; + } + } + + pr = blkid_new_probe(); + if (!pr) + return EXIT_FAILURE; + + blkid_probe_set_superblocks_flags(pr, + BLKID_SUBLKS_LABEL | BLKID_SUBLKS_UUID | + BLKID_SUBLKS_TYPE | BLKID_SUBLKS_SECTYPE | + BLKID_SUBLKS_USAGE | BLKID_SUBLKS_VERSION); + + if (noraid) + blkid_probe_filter_superblocks_usage(pr, BLKID_FLTR_NOTIN, BLKID_USAGE_RAID); + + fd = open(udev_device_get_devnode(dev), O_RDONLY|O_CLOEXEC); + if (fd < 0) { + fprintf(stderr, "error: %s: %m\n", udev_device_get_devnode(dev)); + goto out; + } + + err = blkid_probe_set_device(pr, fd, offset, 0); + if (err < 0) + goto out; + + log_debug("probe %s %sraid offset=%llu\n", + udev_device_get_devnode(dev), + noraid ? "no" : "", (unsigned long long) offset); + + err = probe_superblocks(pr); + if (err < 0) + goto out; + + nvals = blkid_probe_numof_values(pr); + for (i = 0; i < nvals; i++) { + if (blkid_probe_get_value(pr, i, &name, &data, &len)) + continue; + len = strnlen((char *) data, len); + print_property(dev, test, name, (char *) data); + } + + blkid_free_probe(pr); +out: + if (fd > 0) + close(fd); + if (err < 0) + return EXIT_FAILURE; + return EXIT_SUCCESS; +} + +const struct udev_builtin udev_builtin_blkid = { + .name = "blkid", + .cmd = builtin_blkid, + .help = "filesystem and partition probing", + .run_once = true, +}; diff --git a/src/udev/udev-builtin-btrfs.c b/src/udev/udev-builtin-btrfs.c new file mode 100644 index 000000000..dfb05525a --- /dev/null +++ b/src/udev/udev-builtin-btrfs.c @@ -0,0 +1,65 @@ +/*** + This file is part of systemd. + + Copyright 2012 Kay Sievers + + 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include + +#include "udev.h" + +#define BTRFS_PATH_NAME_MAX 4087 +struct btrfs_ioctl_vol_args { + int64_t fd; + char name[BTRFS_PATH_NAME_MAX + 1]; +}; +#define BTRFS_IOCTL_MAGIC 0x94 +#define BTRFS_IOC_DEVICES_READY _IOR(BTRFS_IOCTL_MAGIC, 39, struct btrfs_ioctl_vol_args) + +static int builtin_btrfs(struct udev_device *dev, int argc, char *argv[], bool test) +{ + struct btrfs_ioctl_vol_args args; + int fd; + int err; + + if (argc != 3 || !streq(argv[1], "ready")) + return EXIT_FAILURE; + + fd = open("/dev/btrfs-control", O_RDWR); + if (fd < 0) + return EXIT_FAILURE; + + util_strscpy(args.name, sizeof(args.name), argv[2]); + err = ioctl(fd, BTRFS_IOC_DEVICES_READY, &args); + close(fd); + if (err < 0) + return EXIT_FAILURE; + + udev_builtin_add_property(dev, test, "ID_BTRFS_READY", err == 0 ? "1" : "0"); + return EXIT_SUCCESS; +} + +const struct udev_builtin udev_builtin_btrfs = { + .name = "btrfs", + .cmd = builtin_btrfs, + .help = "btrfs volume management", +}; diff --git a/src/udev/udev-builtin-firmware.c b/src/udev/udev-builtin-firmware.c new file mode 100644 index 000000000..4a91d3357 --- /dev/null +++ b/src/udev/udev-builtin-firmware.c @@ -0,0 +1,175 @@ +/* + * firmware - Kernel firmware loader + * + * Copyright (C) 2009 Piter Punk + * Copyright (C) 2009-2011 Kay Sievers + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details:* + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "udev.h" + +static bool set_loading(struct udev *udev, char *loadpath, const char *state) +{ + FILE *ldfile; + + ldfile = fopen(loadpath, "we"); + if (ldfile == NULL) { + log_error("error: can not open '%s'\n", loadpath); + return false; + }; + fprintf(ldfile, "%s\n", state); + fclose(ldfile); + return true; +} + +static bool copy_firmware(struct udev *udev, const char *source, const char *target, size_t size) +{ + char *buf; + FILE *fsource = NULL, *ftarget = NULL; + bool ret = false; + + buf = malloc(size); + if (buf == NULL) { + log_error("No memory available to load firmware file"); + return false; + } + + log_debug("writing '%s' (%zi) to '%s'\n", source, size, target); + + fsource = fopen(source, "re"); + if (fsource == NULL) + goto exit; + ftarget = fopen(target, "we"); + if (ftarget == NULL) + goto exit; + if (fread(buf, size, 1, fsource) != 1) + goto exit; + if (fwrite(buf, size, 1, ftarget) == 1) + ret = true; +exit: + if (ftarget != NULL) + fclose(ftarget); + if (fsource != NULL) + fclose(fsource); + free(buf); + return ret; +} + +static int builtin_firmware(struct udev_device *dev, int argc, char *argv[], bool test) +{ + struct udev *udev = udev_device_get_udev(dev); + static const char *searchpath[] = { FIRMWARE_PATH }; + char fwencpath[UTIL_PATH_SIZE]; + char misspath[UTIL_PATH_SIZE]; + char loadpath[UTIL_PATH_SIZE]; + char datapath[UTIL_PATH_SIZE]; + char fwpath[UTIL_PATH_SIZE]; + const char *firmware; + FILE *fwfile = NULL; + struct utsname kernel; + struct stat statbuf; + unsigned int i; + int rc = EXIT_SUCCESS; + + firmware = udev_device_get_property_value(dev, "FIRMWARE"); + if (firmware == NULL) { + log_error("firmware parameter missing\n\n"); + rc = EXIT_FAILURE; + goto exit; + } + + /* lookup firmware file */ + uname(&kernel); + for (i = 0; i < ELEMENTSOF(searchpath); i++) { + util_strscpyl(fwpath, sizeof(fwpath), searchpath[i], kernel.release, "/", firmware, NULL); + fwfile = fopen(fwpath, "re"); + if (fwfile != NULL) + break; + + util_strscpyl(fwpath, sizeof(fwpath), searchpath[i], firmware, NULL); + fwfile = fopen(fwpath, "re"); + if (fwfile != NULL) + break; + } + + util_path_encode(firmware, fwencpath, sizeof(fwencpath)); + util_strscpyl(misspath, sizeof(misspath), "/run/udev/firmware-missing/", fwencpath, NULL); + util_strscpyl(loadpath, sizeof(loadpath), udev_device_get_syspath(dev), "/loading", NULL); + + if (fwfile == NULL) { + int err; + + /* This link indicates the missing firmware file and the associated device */ + log_debug("did not find firmware file '%s'\n", firmware); + do { + err = mkdir_parents(misspath, 0755); + if (err != 0 && err != -ENOENT) + break; + err = symlink(udev_device_get_devpath(dev), misspath); + if (err != 0) + err = -errno; + } while (err == -ENOENT); + rc = EXIT_FAILURE; + /* + * Do not cancel the request in the initrd, the real root might have + * the firmware file and the 'coldplug' run in the real root will find + * this pending request and fulfill or cancel it. + * */ + if (!in_initrd()) + set_loading(udev, loadpath, "-1"); + goto exit; + } + + if (stat(fwpath, &statbuf) < 0 || statbuf.st_size == 0) { + if (!in_initrd()) + set_loading(udev, loadpath, "-1"); + rc = EXIT_FAILURE; + goto exit; + } + + if (unlink(misspath) == 0) + util_delete_path(udev, misspath); + + if (!set_loading(udev, loadpath, "1")) + goto exit; + + util_strscpyl(datapath, sizeof(datapath), udev_device_get_syspath(dev), "/data", NULL); + if (!copy_firmware(udev, fwpath, datapath, statbuf.st_size)) { + log_error("error sending firmware '%s' to device\n", firmware); + set_loading(udev, loadpath, "-1"); + rc = EXIT_FAILURE; + goto exit; + }; + + set_loading(udev, loadpath, "0"); +exit: + if (fwfile) + fclose(fwfile); + return rc; +} + +const struct udev_builtin udev_builtin_firmware = { + .name = "firmware", + .cmd = builtin_firmware, + .help = "kernel firmware loader", + .run_once = true, +}; diff --git a/src/udev/udev-builtin-hwdb.c b/src/udev/udev-builtin-hwdb.c new file mode 100644 index 000000000..0b35d799f --- /dev/null +++ b/src/udev/udev-builtin-hwdb.c @@ -0,0 +1,162 @@ +/*** + This file is part of systemd. + + Copyright 2012 Kay Sievers + + 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include + +#include "udev.h" + +static struct udev_hwdb *hwdb; + +int udev_builtin_hwdb_lookup(struct udev_device *dev, const char *modalias, bool test) { + struct udev_list_entry *entry; + int n = 0; + + if (!hwdb) + return -ENOENT; + + udev_list_entry_foreach(entry, udev_hwdb_get_properties_list_entry(hwdb, modalias, 0)) { + if (udev_builtin_add_property(dev, test, + udev_list_entry_get_name(entry), + udev_list_entry_get_value(entry)) < 0) + return -ENOMEM; + n++; + } + return n; +} + +static const char *modalias_usb(struct udev_device *dev, char *s, size_t size) { + const char *v, *p; + int vn, pn; + + v = udev_device_get_sysattr_value(dev, "idVendor"); + if (!v) + return NULL; + p = udev_device_get_sysattr_value(dev, "idProduct"); + if (!p) + return NULL; + vn = strtol(v, NULL, 16); + if (vn <= 0) + return NULL; + pn = strtol(p, NULL, 16); + if (pn <= 0) + return NULL; + snprintf(s, size, "usb:v%04Xp%04X*", vn, pn); + return s; +} + +static int udev_builtin_hwdb_search(struct udev_device *dev, const char *subsystem, bool test) { + struct udev_device *d; + char s[16]; + int n = 0; + + for (d = dev; d; d = udev_device_get_parent(d)) { + const char *dsubsys; + const char *modalias = NULL; + + dsubsys = udev_device_get_subsystem(d); + if (!dsubsys) + continue; + + /* look only at devices of a specific subsystem */ + if (subsystem && !streq(dsubsys, subsystem)) + continue; + + /* the usb_device does not have a modalias, compose one */ + if (streq(dsubsys, "usb")) + modalias = modalias_usb(dev, s, sizeof(s)); + + if (!modalias) + modalias = udev_device_get_property_value(d, "MODALIAS"); + + if (!modalias) + continue; + n = udev_builtin_hwdb_lookup(dev, modalias, test); + if (n > 0) + break; + } + + return n; +} + +static int builtin_hwdb(struct udev_device *dev, int argc, char *argv[], bool test) { + static const struct option options[] = { + { "subsystem", required_argument, NULL, 's' }, + {} + }; + const char *subsystem = NULL; + + if (!hwdb) + return EXIT_FAILURE; + + for (;;) { + int option; + + option = getopt_long(argc, argv, "s", options, NULL); + if (option == -1) + break; + + switch (option) { + case 's': + subsystem = optarg; + break; + } + } + + if (udev_builtin_hwdb_search(dev, subsystem, test) < 0) + return EXIT_FAILURE; + return EXIT_SUCCESS; +} + +/* called at udev startup and reload */ +static int builtin_hwdb_init(struct udev *udev) +{ + if (hwdb) + return 0; + hwdb = udev_hwdb_new(udev); + if (!hwdb) + return -ENOMEM; + return 0; +} + +/* called on udev shutdown and reload request */ +static void builtin_hwdb_exit(struct udev *udev) +{ + hwdb = udev_hwdb_unref(hwdb); +} + +/* called every couple of seconds during event activity; 'true' if config has changed */ +static bool builtin_hwdb_validate(struct udev *udev) +{ + return udev_hwdb_validate(hwdb); +} + +const struct udev_builtin udev_builtin_hwdb = { + .name = "hwdb", + .cmd = builtin_hwdb, + .init = builtin_hwdb_init, + .exit = builtin_hwdb_exit, + .validate = builtin_hwdb_validate, + .help = "hardware database", +}; diff --git a/src/udev/udev-builtin-input_id.c b/src/udev/udev-builtin-input_id.c new file mode 100644 index 000000000..445b602f9 --- /dev/null +++ b/src/udev/udev-builtin-input_id.c @@ -0,0 +1,219 @@ +/* + * compose persistent device path + * + * Copyright (C) 2009 Martin Pitt + * Portions Copyright (C) 2004 David Zeuthen, + * Copyright (C) 2011 Kay Sievers + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "udev.h" + +/* we must use this kernel-compatible implementation */ +#define BITS_PER_LONG (sizeof(unsigned long) * 8) +#define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1) +#define OFF(x) ((x)%BITS_PER_LONG) +#define BIT(x) (1UL<> OFF(bit)) & 1) + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wformat-nonliteral" +/* + * Read a capability attribute and return bitmask. + * @param dev udev_device + * @param attr sysfs attribute name (e. g. "capabilities/key") + * @param bitmask: Output array which has a sizeof of bitmask_size + */ +static void get_cap_mask(struct udev_device *dev, + struct udev_device *pdev, const char* attr, + unsigned long *bitmask, size_t bitmask_size, + bool test) +{ + char text[4096]; + unsigned i; + char* word; + unsigned long val; + + snprintf(text, sizeof(text), "%s", udev_device_get_sysattr_value(pdev, attr)); + log_debug("%s raw kernel attribute: %s\n", attr, text); + + memset (bitmask, 0, bitmask_size); + i = 0; + while ((word = strrchr(text, ' ')) != NULL) { + val = strtoul (word+1, NULL, 16); + if (i < bitmask_size/sizeof(unsigned long)) + bitmask[i] = val; + else + log_debug("ignoring %s block %lX which is larger than maximum size\n", attr, val); + *word = '\0'; + ++i; + } + val = strtoul (text, NULL, 16); + if (i < bitmask_size / sizeof(unsigned long)) + bitmask[i] = val; + else + log_debug("ignoring %s block %lX which is larger than maximum size\n", attr, val); + + if (test) { + /* printf pattern with the right unsigned long number of hex chars */ + snprintf(text, sizeof(text), " bit %%4u: %%0%zilX\n", 2 * sizeof(unsigned long)); + log_debug("%s decoded bit map:\n", attr); + val = bitmask_size / sizeof (unsigned long); + /* skip over leading zeros */ + while (bitmask[val-1] == 0 && val > 0) + --val; + for (i = 0; i < val; ++i) + log_debug(text, i * BITS_PER_LONG, bitmask[i]); + } +} +#pragma GCC diagnostic pop + +/* pointer devices */ +static void test_pointers (struct udev_device *dev, + const unsigned long* bitmask_ev, + const unsigned long* bitmask_abs, + const unsigned long* bitmask_key, + const unsigned long* bitmask_rel, + bool test) +{ + int is_mouse = 0; + int is_touchpad = 0; + + if (!test_bit (EV_KEY, bitmask_ev)) { + if (test_bit (EV_ABS, bitmask_ev) && + test_bit (ABS_X, bitmask_abs) && + test_bit (ABS_Y, bitmask_abs) && + test_bit (ABS_Z, bitmask_abs)) + udev_builtin_add_property(dev, test, "ID_INPUT_ACCELEROMETER", "1"); + return; + } + + if (test_bit (EV_ABS, bitmask_ev) && + test_bit (ABS_X, bitmask_abs) && test_bit (ABS_Y, bitmask_abs)) { + if (test_bit (BTN_STYLUS, bitmask_key) || test_bit (BTN_TOOL_PEN, bitmask_key)) + udev_builtin_add_property(dev, test, "ID_INPUT_TABLET", "1"); + else if (test_bit (BTN_TOOL_FINGER, bitmask_key) && !test_bit (BTN_TOOL_PEN, bitmask_key)) + is_touchpad = 1; + else if (test_bit (BTN_TRIGGER, bitmask_key) || + test_bit (BTN_A, bitmask_key) || + test_bit (BTN_1, bitmask_key)) + udev_builtin_add_property(dev, test, "ID_INPUT_JOYSTICK", "1"); + else if (test_bit (BTN_MOUSE, bitmask_key)) + /* This path is taken by VMware's USB mouse, which has + * absolute axes, but no touch/pressure button. */ + is_mouse = 1; + else if (test_bit (BTN_TOUCH, bitmask_key)) + udev_builtin_add_property(dev, test, "ID_INPUT_TOUCHSCREEN", "1"); + } + + if (test_bit (EV_REL, bitmask_ev) && + test_bit (REL_X, bitmask_rel) && test_bit (REL_Y, bitmask_rel) && + test_bit (BTN_MOUSE, bitmask_key)) + is_mouse = 1; + + if (is_mouse) + udev_builtin_add_property(dev, test, "ID_INPUT_MOUSE", "1"); + if (is_touchpad) + udev_builtin_add_property(dev, test, "ID_INPUT_TOUCHPAD", "1"); +} + +/* key like devices */ +static void test_key (struct udev_device *dev, + const unsigned long* bitmask_ev, + const unsigned long* bitmask_key, + bool test) +{ + unsigned i; + unsigned long found; + unsigned long mask; + + /* do we have any KEY_* capability? */ + if (!test_bit (EV_KEY, bitmask_ev)) { + log_debug("test_key: no EV_KEY capability\n"); + return; + } + + /* only consider KEY_* here, not BTN_* */ + found = 0; + for (i = 0; i < BTN_MISC/BITS_PER_LONG; ++i) { + found |= bitmask_key[i]; + log_debug("test_key: checking bit block %lu for any keys; found=%i\n", (unsigned long)i*BITS_PER_LONG, found > 0); + } + /* If there are no keys in the lower block, check the higher block */ + if (!found) { + for (i = KEY_OK; i < BTN_TRIGGER_HAPPY; ++i) { + if (test_bit (i, bitmask_key)) { + log_debug("test_key: Found key %x in high block\n", i); + found = 1; + break; + } + } + } + + if (found > 0) + udev_builtin_add_property(dev, test, "ID_INPUT_KEY", "1"); + + /* the first 32 bits are ESC, numbers, and Q to D; if we have all of + * those, consider it a full keyboard; do not test KEY_RESERVED, though */ + mask = 0xFFFFFFFE; + if ((bitmask_key[0] & mask) == mask) + udev_builtin_add_property(dev, test, "ID_INPUT_KEYBOARD", "1"); +} + +static int builtin_input_id(struct udev_device *dev, int argc, char *argv[], bool test) +{ + struct udev_device *pdev; + unsigned long bitmask_ev[NBITS(EV_MAX)]; + unsigned long bitmask_abs[NBITS(ABS_MAX)]; + unsigned long bitmask_key[NBITS(KEY_MAX)]; + unsigned long bitmask_rel[NBITS(REL_MAX)]; + + /* walk up the parental chain until we find the real input device; the + * argument is very likely a subdevice of this, like eventN */ + pdev = dev; + while (pdev != NULL && udev_device_get_sysattr_value(pdev, "capabilities/ev") == NULL) + pdev = udev_device_get_parent_with_subsystem_devtype(pdev, "input", NULL); + + /* not an "input" class device */ + if (pdev == NULL) + return EXIT_SUCCESS; + + /* Use this as a flag that input devices were detected, so that this + * program doesn't need to be called more than once per device */ + udev_builtin_add_property(dev, test, "ID_INPUT", "1"); + get_cap_mask(dev, pdev, "capabilities/ev", bitmask_ev, sizeof(bitmask_ev), test); + get_cap_mask(dev, pdev, "capabilities/abs", bitmask_abs, sizeof(bitmask_abs), test); + get_cap_mask(dev, pdev, "capabilities/rel", bitmask_rel, sizeof(bitmask_rel), test); + get_cap_mask(dev, pdev, "capabilities/key", bitmask_key, sizeof(bitmask_key), test); + test_pointers(dev, bitmask_ev, bitmask_abs, bitmask_key, bitmask_rel, test); + test_key(dev, bitmask_ev, bitmask_key, test); + return EXIT_SUCCESS; +} + +const struct udev_builtin udev_builtin_input_id = { + .name = "input_id", + .cmd = builtin_input_id, + .help = "input device properties", +}; diff --git a/src/udev/udev-builtin-kmod.c b/src/udev/udev-builtin-kmod.c new file mode 100644 index 000000000..17aca2944 --- /dev/null +++ b/src/udev/udev-builtin-kmod.c @@ -0,0 +1,134 @@ +/* + * load kernel modules + * + * Copyright (C) 2011-2012 Kay Sievers + * Copyright (C) 2011 ProFUSION embedded systems + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "udev.h" + +static struct kmod_ctx *ctx; + +static int load_module(struct udev *udev, const char *alias) +{ + struct kmod_list *list = NULL; + struct kmod_list *l; + int err; + + err = kmod_module_new_from_lookup(ctx, alias, &list); + if (err < 0) + return err; + + if (list == NULL) + log_debug("no module matches '%s'\n", alias); + + kmod_list_foreach(l, list) { + struct kmod_module *mod = kmod_module_get_module(l); + + err = kmod_module_probe_insert_module(mod, KMOD_PROBE_APPLY_BLACKLIST, NULL, NULL, NULL, NULL); + if (err == KMOD_PROBE_APPLY_BLACKLIST) + log_debug("module '%s' is blacklisted\n", kmod_module_get_name(mod)); + else if (err == 0) + log_debug("inserted '%s'\n", kmod_module_get_name(mod)); + else + log_debug("failed to insert '%s'\n", kmod_module_get_name(mod)); + + kmod_module_unref(mod); + } + + kmod_module_unref_list(list); + return err; +} + +static void udev_kmod_log(void *data, int priority, const char *file, int line, + const char *fn, const char *format, va_list args) +{ + udev_main_log(data, priority, file, line, fn, format, args); +} + +static int builtin_kmod(struct udev_device *dev, int argc, char *argv[], bool test) +{ + struct udev *udev = udev_device_get_udev(dev); + int i; + + if (!ctx) + return 0; + + if (argc < 3 || strcmp(argv[1], "load")) { + log_error("expect: %s load \n", argv[0]); + return EXIT_FAILURE; + } + + for (i = 2; argv[i]; i++) { + log_debug("execute '%s' '%s'\n", argv[1], argv[i]); + load_module(udev, argv[i]); + } + + return EXIT_SUCCESS; +} + +/* called at udev startup and reload */ +static int builtin_kmod_init(struct udev *udev) +{ + if (ctx) + return 0; + + ctx = kmod_new(NULL, NULL); + if (!ctx) + return -ENOMEM; + + log_debug("load module index\n"); + kmod_set_log_fn(ctx, udev_kmod_log, udev); + kmod_load_resources(ctx); + return 0; +} + +/* called on udev shutdown and reload request */ +static void builtin_kmod_exit(struct udev *udev) +{ + log_debug("unload module index\n"); + ctx = kmod_unref(ctx); +} + +/* called every couple of seconds during event activity; 'true' if config has changed */ +static bool builtin_kmod_validate(struct udev *udev) +{ + log_debug("validate module index\n"); + if (!ctx) + return false; + return (kmod_validate_resources(ctx) != KMOD_RESOURCES_OK); +} + +const struct udev_builtin udev_builtin_kmod = { + .name = "kmod", + .cmd = builtin_kmod, + .init = builtin_kmod_init, + .exit = builtin_kmod_exit, + .validate = builtin_kmod_validate, + .help = "kernel module loader", + .run_once = false, +}; diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c new file mode 100644 index 000000000..d5db762e8 --- /dev/null +++ b/src/udev/udev-builtin-net_id.c @@ -0,0 +1,452 @@ +/*** + This file is part of systemd. + + Copyright 2012 Kay Sievers + + 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 . +***/ + +/* + * Predictable network interface device names based on: + * - firmware/bios-provided index numbers for on-board devices + * - firmware-provided pci-express hotplug slot index number + * - physical/geographical location of the hardware + * - the interface's MAC address + * + * Two character prefixes based on the type of interface: + * en -- ethernet + * wl -- wlan + * ww -- wwan + * + * Type of names: + * o -- on-board device index number + * s[f][d] -- hotplug slot index number + * x -- MAC address + * ps[f][d] -- PCI geographical location + * ps[f][u][..][c][i] + * -- USB port number chain + * + * All multi-function PCI devices will carry the [f] number in the + * device name, including the function 0 device. + * + * For USB devices the full chain of port numbers of hubs is composed. If the + * name gets longer than the maximum number of 15 characters, the name is not + * exported. + * The usual USB configuration == 1 and interface == 0 values are suppressed. + * + * PCI ethernet card with firmware index "1": + * ID_NET_NAME_ONBOARD=eno1 + * ID_NET_NAME_ONBOARD_LABEL=Ethernet Port 1 + * + * PCI ethernet card in hotplug slot with firmware index number: + * /sys/devices/pci0000:00/0000:00:1c.3/0000:05:00.0/net/ens1 + * ID_NET_NAME_MAC=enx000000000466 + * ID_NET_NAME_PATH=enp5s0 + * ID_NET_NAME_SLOT=ens1 + * + * PCI ethernet multi-function card with 2 ports: + * /sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/net/enp2s0f0 + * ID_NET_NAME_MAC=enx78e7d1ea46da + * ID_NET_NAME_PATH=enp2s0f0 + * /sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.1/net/enp2s0f1 + * ID_NET_NAME_MAC=enx78e7d1ea46dc + * ID_NET_NAME_PATH=enp2s0f1 + * + * PCI wlan card: + * /sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlp3s0 + * ID_NET_NAME_MAC=wlx0024d7e31130 + * ID_NET_NAME_PATH=wlp3s0 + * + * USB built-in 3G modem: + * /sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.4/2-1.4:1.6/net/wwp0s29u1u4i6 + * ID_NET_NAME_MAC=wwx028037ec0200 + * ID_NET_NAME_PATH=wwp0s29u1u4i6 + * + * USB Android phone: + * /sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0/net/enp0s29u1u2 + * ID_NET_NAME_MAC=enxd626b3450fb5 + * ID_NET_NAME_PATH=enp0s29u1u2 + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "udev.h" + +enum netname_type{ + NET_UNDEF, + NET_PCI, + NET_USB, +}; + +struct netnames { + enum netname_type type; + + uint8_t mac[6]; + bool mac_valid; + + struct udev_device *pcidev; + char pci_slot[IFNAMSIZ]; + char pci_path[IFNAMSIZ]; + char pci_onboard[IFNAMSIZ]; + const char *pci_onboard_label; + + struct udev_device *usbdev; + char usb_ports[IFNAMSIZ]; +}; + +/* retrieve on-board index number and label from firmware */ +static int dev_pci_onboard(struct udev_device *dev, struct netnames *names) { + const char *index; + int idx; + + /* ACPI _DSM -- device specific method for naming a PCI or PCI Express device */ + index = udev_device_get_sysattr_value(names->pcidev, "acpi_index"); + /* SMBIOS type 41 -- Onboard Devices Extended Information */ + if (!index) + index = udev_device_get_sysattr_value(names->pcidev, "index"); + if (!index) + return -ENOENT; + idx = strtoul(index, NULL, 0); + if (idx <= 0) + return -EINVAL; + snprintf(names->pci_onboard, sizeof(names->pci_onboard), "o%d", idx); + + names->pci_onboard_label = udev_device_get_sysattr_value(names->pcidev, "label"); + return 0; +} + +/* read the 256 bytes PCI configuration space to check the multi-function bit */ +static bool is_pci_multifunction(struct udev_device *dev) { + char filename[256]; + FILE *f; + char config[64]; + bool multi = false; + + snprintf(filename, sizeof(filename), "%s/config", udev_device_get_syspath(dev)); + f = fopen(filename, "re"); + if (!f) + goto out; + if (fread(&config, sizeof(config), 1, f) != 1) + goto out; + + /* bit 0-6 header type, bit 7 multi/single function device */ + if ((config[PCI_HEADER_TYPE] & 0x80) != 0) + multi = true; +out: + fclose(f); + return multi; +} + +static int dev_pci_slot(struct udev_device *dev, struct netnames *names) { + struct udev *udev = udev_device_get_udev(names->pcidev); + unsigned int bus; + unsigned int slot; + unsigned int func; + unsigned int dev_id = 0; + size_t l; + char *s; + const char *attr; + struct udev_device *pci = NULL; + char slots[256]; + DIR *dir; + struct dirent *dent; + char str[256]; + int hotplug_slot = 0; + int err = 0; + + if (sscanf(udev_device_get_sysname(names->pcidev), "0000:%x:%x.%d", &bus, &slot, &func) != 3) + return -ENOENT; + + /* kernel provided multi-device index */ + attr = udev_device_get_sysattr_value(dev, "dev_id"); + if (attr) + dev_id = strtol(attr, NULL, 16); + + /* compose a name based on the raw kernel's PCI bus, slot numbers */ + s = names->pci_path; + l = util_strpcpyf(&s, sizeof(names->pci_path), "p%ds%d", bus, slot); + if (func > 0 || is_pci_multifunction(names->pcidev)) + l = util_strpcpyf(&s, l, "f%d", func); + if (dev_id > 0) + l = util_strpcpyf(&s, l, "d%d", dev_id); + if (l == 0) + names->pci_path[0] = '\0'; + + /* ACPI _SUN -- slot user number */ + pci = udev_device_new_from_subsystem_sysname(udev, "subsystem", "pci"); + if (!pci) { + err = -ENOENT; + goto out; + } + snprintf(slots, sizeof(slots), "%s/slots", udev_device_get_syspath(pci)); + dir = opendir(slots); + if (!dir) { + err = -errno; + goto out; + } + + for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) { + int i; + char *rest; + char *address; + + if (dent->d_name[0] == '.') + continue; + i = strtol(dent->d_name, &rest, 10); + if (rest[0] != '\0') + continue; + if (i < 1) + continue; + snprintf(str, sizeof(str), "%s/%s/address", slots, dent->d_name); + if (read_one_line_file(str, &address) >= 0) { + /* match slot address with device by stripping the function */ + if (strncmp(address, udev_device_get_sysname(names->pcidev), strlen(address)) == 0) + hotplug_slot = i; + free(address); + } + + if (hotplug_slot > 0) + break; + } + closedir(dir); + + if (hotplug_slot > 0) { + s = names->pci_slot; + l = util_strpcpyf(&s, sizeof(names->pci_slot), "s%d", hotplug_slot); + if (func > 0 || is_pci_multifunction(names->pcidev)) + l = util_strpcpyf(&s, l, "f%d", func); + if (dev_id > 0) + l = util_strpcpyf(&s, l, "d%d", dev_id); + if (l == 0) + names->pci_path[0] = '\0'; + } +out: + udev_device_unref(pci); + return err; +} + +static int names_pci(struct udev_device *dev, struct netnames *names) { + struct udev_device *parent; + + parent = udev_device_get_parent(dev); + if (!parent) + return -ENOENT; + /* check if our direct parent is a PCI device with no other bus in-between */ + if (streq("pci", udev_device_get_subsystem(parent))) { + names->type = NET_PCI; + names->pcidev = parent; + } else { + names->pcidev = udev_device_get_parent_with_subsystem_devtype(dev, "pci", NULL); + if (!names->pcidev) + return -ENOENT; + } + dev_pci_onboard(dev, names); + dev_pci_slot(dev, names); + return 0; +} + +static int names_usb(struct udev_device *dev, struct netnames *names) { + char name[256]; + char *ports; + char *config; + char *interf; + size_t l; + char *s; + + names->usbdev = udev_device_get_parent_with_subsystem_devtype(dev, "usb", "usb_interface"); + if (!names->usbdev) + return -ENOENT; + + /* get USB port number chain, configuration, interface */ + util_strscpy(name, sizeof(name), udev_device_get_sysname(names->usbdev)); + s = strchr(name, '-'); + if (!s) + return -EINVAL; + ports = s+1; + + s = strchr(ports, ':'); + if (!s) + return -EINVAL; + s[0] = '\0'; + config = s+1; + + s = strchr(config, '.'); + if (!s) + return -EINVAL; + s[0] = '\0'; + interf = s+1; + + /* prefix every port number in the chain with "u"*/ + s = ports; + while ((s = strchr(s, '.'))) + s[0] = 'u'; + s = names->usb_ports; + l = util_strpcpyl(&s, sizeof(names->usb_ports), "u", ports, NULL); + + /* append USB config number, suppress the common config == 1 */ + if (!streq(config, "1")) + l = util_strpcpyl(&s, sizeof(names->usb_ports), "c", config, NULL); + + /* append USB interface number, suppress the interface == 0 */ + if (!streq(interf, "0")) + l = util_strpcpyl(&s, sizeof(names->usb_ports), "i", interf, NULL); + if (l == 0) + return -ENAMETOOLONG; + + names->type = NET_USB; + return 0; +} + +static int names_mac(struct udev_device *dev, struct netnames *names) { + const char *s; + unsigned int i; + unsigned int a1, a2, a3, a4, a5, a6; + + /* check for NET_ADDR_PERM, skip random MAC addresses */ + s = udev_device_get_sysattr_value(dev, "addr_assign_type"); + if (!s) + return EXIT_FAILURE; + i = strtoul(s, NULL, 0); + if (i != 0) + return 0; + + s = udev_device_get_sysattr_value(dev, "address"); + if (!s) + return -ENOENT; + if (sscanf(s, "%x:%x:%x:%x:%x:%x", &a1, &a2, &a3, &a4, &a5, &a6) != 6) + return -EINVAL; + + /* skip empty MAC addresses */ + if (a1 + a2 + a3 + a4 + a5 + a6 == 0) + return -EINVAL; + + names->mac[0] = a1; + names->mac[1] = a2; + names->mac[2] = a3; + names->mac[3] = a4; + names->mac[4] = a5; + names->mac[5] = a6; + names->mac_valid = true; + return 0; +} + +/* IEEE Organizationally Unique Identifier vendor string */ +static int ieee_oui(struct udev_device *dev, struct netnames *names, bool test) { + char str[32]; + + if (!names->mac_valid) + return -ENOENT; + /* skip commonly misused 00:00:00 (Xerox) prefix */ + if (memcmp(names->mac, "\0\0\0", 3) == 0) + return -EINVAL; + snprintf(str, sizeof(str), "OUI:%02X%02X%02X%02X%02X%02X", + names->mac[0], names->mac[1], names->mac[2], + names->mac[3], names->mac[4], names->mac[5]); + udev_builtin_hwdb_lookup(dev, str, test); + return 0; +} + +static int builtin_net_id(struct udev_device *dev, int argc, char *argv[], bool test) { + const char *s; + unsigned int i; + const char *devtype; + const char *prefix = "en"; + struct netnames names; + int err; + + /* handle only ARPHRD_ETHER devices */ + s = udev_device_get_sysattr_value(dev, "type"); + if (!s) + return EXIT_FAILURE; + i = strtoul(s, NULL, 0); + if (i != 1) + return 0; + + devtype = udev_device_get_devtype(dev); + if (devtype) { + if (streq("wlan", devtype)) + prefix = "wl"; + else if (streq("wwan", devtype)) + prefix = "ww"; + } + + zero(names); + err = names_mac(dev, &names); + if (err >= 0 && names.mac_valid) { + char str[IFNAMSIZ]; + + snprintf(str, sizeof(str), "%sx%02x%02x%02x%02x%02x%02x", prefix, + names.mac[0], names.mac[1], names.mac[2], + names.mac[3], names.mac[4], names.mac[5]); + udev_builtin_add_property(dev, test, "ID_NET_NAME_MAC", str); + + ieee_oui(dev, &names, test); + } + + /* get PCI based path names, we compose only PCI based paths */ + err = names_pci(dev, &names); + if (err < 0) + goto out; + + /* plain PCI device */ + if (names.type == NET_PCI) { + char str[IFNAMSIZ]; + + if (names.pci_onboard[0]) + if (snprintf(str, sizeof(str), "%s%s", prefix, names.pci_onboard) < (int)sizeof(str)) + udev_builtin_add_property(dev, test, "ID_NET_NAME_ONBOARD", str); + + if (names.pci_onboard_label) + if (snprintf(str, sizeof(str), "%s%s", prefix, names.pci_onboard_label) < (int)sizeof(str)) + udev_builtin_add_property(dev, test, "ID_NET_LABEL_ONBOARD", str); + + if (names.pci_path[0]) + if (snprintf(str, sizeof(str), "%s%s", prefix, names.pci_path) < (int)sizeof(str)) + udev_builtin_add_property(dev, test, "ID_NET_NAME_PATH", str); + + if (names.pci_slot[0]) + if (snprintf(str, sizeof(str), "%s%s", prefix, names.pci_slot) < (int)sizeof(str)) + udev_builtin_add_property(dev, test, "ID_NET_NAME_SLOT", str); + goto out; + } + + /* USB device */ + err = names_usb(dev, &names); + if (err >= 0 && names.type == NET_USB) { + char str[IFNAMSIZ]; + + if (names.pci_path[0]) + if (snprintf(str, sizeof(str), "%s%s%s", prefix, names.pci_path, names.usb_ports) < (int)sizeof(str)) + udev_builtin_add_property(dev, test, "ID_NET_NAME_PATH", str); + + if (names.pci_slot[0]) + if (snprintf(str, sizeof(str), "%s%s%s", prefix, names.pci_slot, names.usb_ports) < (int)sizeof(str)) + udev_builtin_add_property(dev, test, "ID_NET_NAME_SLOT", str); + } +out: + return EXIT_SUCCESS; +} + +const struct udev_builtin udev_builtin_net_id = { + .name = "net_id", + .cmd = builtin_net_id, + .help = "network device properties", +}; diff --git a/src/udev/udev-builtin-path_id.c b/src/udev/udev-builtin-path_id.c new file mode 100644 index 000000000..c2c9161c9 --- /dev/null +++ b/src/udev/udev-builtin-path_id.c @@ -0,0 +1,590 @@ +/* + * compose persistent device path + * + * Copyright (C) 2009-2011 Kay Sievers + * + * Logic based on Hannes Reinecke's shell script. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "udev.h" + +static int path_prepend(char **path, const char *fmt, ...) +{ + va_list va; + char *pre; + int err = 0; + + va_start(va, fmt); + err = vasprintf(&pre, fmt, va); + va_end(va); + if (err < 0) + goto out; + + if (*path != NULL) { + char *new; + + err = asprintf(&new, "%s-%s", pre, *path); + free(pre); + if (err < 0) + goto out; + free(*path); + *path = new; + } else { + *path = pre; + } +out: + return err; +} + +/* +** Linux only supports 32 bit luns. +** See drivers/scsi/scsi_scan.c::scsilun_to_int() for more details. +*/ +static int format_lun_number(struct udev_device *dev, char **path) +{ + unsigned long lun = strtoul(udev_device_get_sysnum(dev), NULL, 10); + + /* address method 0, peripheral device addressing with bus id of zero */ + if (lun < 256) + return path_prepend(path, "lun-%d", lun); + /* handle all other lun addressing methods by using a variant of the original lun format */ + return path_prepend(path, "lun-0x%04x%04x00000000", (lun & 0xffff), (lun >> 16) & 0xffff); +} + +static struct udev_device *skip_subsystem(struct udev_device *dev, const char *subsys) +{ + struct udev_device *parent = dev; + + while (parent != NULL) { + const char *subsystem; + + subsystem = udev_device_get_subsystem(parent); + if (subsystem == NULL || strcmp(subsystem, subsys) != 0) + break; + dev = parent; + parent = udev_device_get_parent(parent); + } + return dev; +} + +static struct udev_device *handle_scsi_fibre_channel(struct udev_device *parent, char **path) +{ + struct udev *udev = udev_device_get_udev(parent); + struct udev_device *targetdev; + struct udev_device *fcdev = NULL; + const char *port; + char *lun = NULL; + + targetdev = udev_device_get_parent_with_subsystem_devtype(parent, "scsi", "scsi_target"); + if (targetdev == NULL) + return NULL; + + fcdev = udev_device_new_from_subsystem_sysname(udev, "fc_transport", udev_device_get_sysname(targetdev)); + if (fcdev == NULL) + return NULL; + port = udev_device_get_sysattr_value(fcdev, "port_name"); + if (port == NULL) { + parent = NULL; + goto out; + } + + format_lun_number(parent, &lun); + path_prepend(path, "fc-%s-%s", port, lun); + if (lun) + free(lun); +out: + udev_device_unref(fcdev); + return parent; +} + +static struct udev_device *handle_scsi_sas(struct udev_device *parent, char **path) +{ + struct udev *udev = udev_device_get_udev(parent); + struct udev_device *targetdev; + struct udev_device *target_parent; + struct udev_device *sasdev; + const char *sas_address; + char *lun = NULL; + + targetdev = udev_device_get_parent_with_subsystem_devtype(parent, "scsi", "scsi_target"); + if (targetdev == NULL) + return NULL; + + target_parent = udev_device_get_parent(targetdev); + if (target_parent == NULL) + return NULL; + + sasdev = udev_device_new_from_subsystem_sysname(udev, "sas_device", + udev_device_get_sysname(target_parent)); + if (sasdev == NULL) + return NULL; + + sas_address = udev_device_get_sysattr_value(sasdev, "sas_address"); + if (sas_address == NULL) { + parent = NULL; + goto out; + } + + format_lun_number(parent, &lun); + path_prepend(path, "sas-%s-%s", sas_address, lun); + if (lun) + free(lun); +out: + udev_device_unref(sasdev); + return parent; +} + +static struct udev_device *handle_scsi_iscsi(struct udev_device *parent, char **path) +{ + struct udev *udev = udev_device_get_udev(parent); + struct udev_device *transportdev; + struct udev_device *sessiondev = NULL; + const char *target; + char *connname; + struct udev_device *conndev = NULL; + const char *addr; + const char *port; + char *lun = NULL; + + /* find iscsi session */ + transportdev = parent; + for (;;) { + transportdev = udev_device_get_parent(transportdev); + if (transportdev == NULL) + return NULL; + if (startswith(udev_device_get_sysname(transportdev), "session")) + break; + } + + /* find iscsi session device */ + sessiondev = udev_device_new_from_subsystem_sysname(udev, "iscsi_session", udev_device_get_sysname(transportdev)); + if (sessiondev == NULL) + return NULL; + target = udev_device_get_sysattr_value(sessiondev, "targetname"); + if (target == NULL) { + parent = NULL; + goto out; + } + + if (asprintf(&connname, "connection%s:0", udev_device_get_sysnum(transportdev)) < 0) { + parent = NULL; + goto out; + } + conndev = udev_device_new_from_subsystem_sysname(udev, "iscsi_connection", connname); + free(connname); + if (conndev == NULL) { + parent = NULL; + goto out; + } + addr = udev_device_get_sysattr_value(conndev, "persistent_address"); + port = udev_device_get_sysattr_value(conndev, "persistent_port"); + if (addr == NULL || port == NULL) { + parent = NULL; + goto out; + } + + format_lun_number(parent, &lun); + path_prepend(path, "ip-%s:%s-iscsi-%s-%s", addr, port, target, lun); + if (lun) + free(lun); +out: + udev_device_unref(sessiondev); + udev_device_unref(conndev); + return parent; +} + +static struct udev_device *handle_scsi_default(struct udev_device *parent, char **path) +{ + struct udev_device *hostdev; + int host, bus, target, lun; + const char *name; + char *base; + char *pos; + DIR *dir; + struct dirent *dent; + int basenum; + + hostdev = udev_device_get_parent_with_subsystem_devtype(parent, "scsi", "scsi_host"); + if (hostdev == NULL) + return NULL; + + name = udev_device_get_sysname(parent); + if (sscanf(name, "%d:%d:%d:%d", &host, &bus, &target, &lun) != 4) + return NULL; + + /* + * Rebase host offset to get the local relative number + * + * Note: This is by definition racy, unreliable and too simple. + * Please do not copy this model anywhere. It's just a left-over + * from the time we had no idea how things should look like in + * the end. + * + * Making assumptions about a global in-kernel counter and use + * that to calculate a local offset is a very broken concept. It + * can only work as long as things are in strict order. + * + * The kernel needs to export the instance/port number of a + * controller directly, without the need for rebase magic like + * this. Manual driver unbind/bind, parallel hotplug/unplug will + * get into the way of this "I hope it works" logic. + */ + basenum = -1; + base = strdup(udev_device_get_syspath(hostdev)); + if (base == NULL) + return NULL; + pos = strrchr(base, '/'); + if (pos == NULL) { + parent = NULL; + goto out; + } + pos[0] = '\0'; + dir = opendir(base); + if (dir == NULL) { + parent = NULL; + goto out; + } + for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) { + char *rest; + int i; + + if (dent->d_name[0] == '.') + continue; + if (dent->d_type != DT_DIR && dent->d_type != DT_LNK) + continue; + if (!startswith(dent->d_name, "host")) + continue; + i = strtoul(&dent->d_name[4], &rest, 10); + if (rest[0] != '\0') + continue; + /* + * find the smallest number; the host really needs to export its + * own instance number per parent device; relying on the global host + * enumeration and plainly rebasing the numbers sounds unreliable + */ + if (basenum == -1 || i < basenum) + basenum = i; + } + closedir(dir); + if (basenum == -1) { + parent = NULL; + goto out; + } + host -= basenum; + + path_prepend(path, "scsi-%u:%u:%u:%u", host, bus, target, lun); +out: + free(base); + return hostdev; +} + +static struct udev_device *handle_scsi_hyperv(struct udev_device *parent, char **path) { + struct udev_device *hostdev; + struct udev_device *vmbusdev; + const char *guid_str; + char *lun = NULL; + char guid[38]; + size_t i, k; + + hostdev = udev_device_get_parent_with_subsystem_devtype(parent, "scsi", "scsi_host"); + if (!hostdev) + return NULL; + + vmbusdev = udev_device_get_parent(hostdev); + if (!vmbusdev) + return NULL; + + guid_str = udev_device_get_sysattr_value(vmbusdev, "device_id"); + if (!guid_str) + return NULL; + + if (strlen(guid_str) < 37 || guid_str[0] != '{' || guid_str[36] != '}') + return NULL; + + for (i = 1, k = 0; i < 36; i++) { + if (guid_str[i] == '-') + continue; + guid[k++] = guid_str[i]; + } + guid[k] = '\0'; + + format_lun_number(parent, &lun); + path_prepend(path, "vmbus-%s-%s", guid, lun); + free(lun); + return parent; +} + +static struct udev_device *handle_scsi(struct udev_device *parent, char **path) +{ + const char *devtype; + const char *name; + const char *id; + + devtype = udev_device_get_devtype(parent); + if (devtype == NULL || strcmp(devtype, "scsi_device") != 0) + return parent; + + /* firewire */ + id = udev_device_get_sysattr_value(parent, "ieee1394_id"); + if (id != NULL) { + parent = skip_subsystem(parent, "scsi"); + path_prepend(path, "ieee1394-0x%s", id); + goto out; + } + + /* lousy scsi sysfs does not have a "subsystem" for the transport */ + name = udev_device_get_syspath(parent); + + if (strstr(name, "/rport-") != NULL) { + parent = handle_scsi_fibre_channel(parent, path); + goto out; + } + + if (strstr(name, "/end_device-") != NULL) { + parent = handle_scsi_sas(parent, path); + goto out; + } + + if (strstr(name, "/session") != NULL) { + parent = handle_scsi_iscsi(parent, path); + goto out; + } + + /* + * We do not support the ATA transport class, it creates duplicated link + * names as the fake SCSI host adapters are all separated, they are all + * re-based as host == 0. ATA should just stop faking two duplicated + * hierarchies for a single topology and leave the SCSI stuff alone; + * until that happens, there are no by-path/ links for ATA devices behind + * an ATA transport class. + */ + if (strstr(name, "/ata") != NULL) { + parent = NULL; + goto out; + } + + if (strstr(name, "/vmbus_") != NULL) { + parent = handle_scsi_hyperv(parent, path); + goto out; + } + + parent = handle_scsi_default(parent, path); +out: + return parent; +} + +static struct udev_device *handle_cciss(struct udev_device *parent, char **path) +{ + const char *str; + unsigned int controller, disk; + + str = udev_device_get_sysname(parent); + if (sscanf(str, "c%ud%u%*s", &controller, &disk) != 2) + return NULL; + + path_prepend(path, "cciss-disk%u", disk); + parent = skip_subsystem(parent, "cciss"); + return parent; +} + +static void handle_scsi_tape(struct udev_device *dev, char **path) +{ + const char *name; + + /* must be the last device in the syspath */ + if (*path != NULL) + return; + + name = udev_device_get_sysname(dev); + if (startswith(name, "nst") && strchr("lma", name[3]) != NULL) + path_prepend(path, "nst%c", name[3]); + else if (startswith(name, "st") && strchr("lma", name[2]) != NULL) + path_prepend(path, "st%c", name[2]); +} + +static struct udev_device *handle_usb(struct udev_device *parent, char **path) +{ + const char *devtype; + const char *str; + const char *port; + + devtype = udev_device_get_devtype(parent); + if (devtype == NULL) + return parent; + if (strcmp(devtype, "usb_interface") != 0 && strcmp(devtype, "usb_device") != 0) + return parent; + + str = udev_device_get_sysname(parent); + port = strchr(str, '-'); + if (port == NULL) + return parent; + port++; + + parent = skip_subsystem(parent, "usb"); + path_prepend(path, "usb-0:%s", port); + return parent; +} + +static struct udev_device *handle_ccw(struct udev_device *parent, struct udev_device *dev, char **path) +{ + struct udev_device *scsi_dev; + + scsi_dev = udev_device_get_parent_with_subsystem_devtype(dev, "scsi", "scsi_device"); + if (scsi_dev != NULL) { + const char *wwpn; + const char *lun; + const char *hba_id; + + hba_id = udev_device_get_sysattr_value(scsi_dev, "hba_id"); + wwpn = udev_device_get_sysattr_value(scsi_dev, "wwpn"); + lun = udev_device_get_sysattr_value(scsi_dev, "fcp_lun"); + if (hba_id != NULL && lun != NULL && wwpn != NULL) { + path_prepend(path, "ccw-%s-zfcp-%s:%s", hba_id, wwpn, lun); + goto out; + } + } + + path_prepend(path, "ccw-%s", udev_device_get_sysname(parent)); +out: + parent = skip_subsystem(parent, "ccw"); + return parent; +} + +static int builtin_path_id(struct udev_device *dev, int argc, char *argv[], bool test) +{ + struct udev_device *parent; + char *path = NULL; + bool some_transport = false; + + /* S390 ccw bus */ + parent = udev_device_get_parent_with_subsystem_devtype(dev, "ccw", NULL); + if (parent != NULL) { + handle_ccw(parent, dev, &path); + goto out; + } + + /* walk up the chain of devices and compose path */ + parent = dev; + while (parent != NULL) { + const char *subsys; + + subsys = udev_device_get_subsystem(parent); + if (subsys == NULL) { + ; + } else if (strcmp(subsys, "scsi_tape") == 0) { + handle_scsi_tape(parent, &path); + } else if (strcmp(subsys, "scsi") == 0) { + parent = handle_scsi(parent, &path); + some_transport = true; + } else if (strcmp(subsys, "cciss") == 0) { + parent = handle_cciss(parent, &path); + some_transport = true; + } else if (strcmp(subsys, "usb") == 0) { + parent = handle_usb(parent, &path); + some_transport = true; + } else if (strcmp(subsys, "serio") == 0) { + path_prepend(&path, "serio-%s", udev_device_get_sysnum(parent)); + parent = skip_subsystem(parent, "serio"); + } else if (strcmp(subsys, "pci") == 0) { + path_prepend(&path, "pci-%s", udev_device_get_sysname(parent)); + parent = skip_subsystem(parent, "pci"); + } else if (strcmp(subsys, "platform") == 0) { + path_prepend(&path, "platform-%s", udev_device_get_sysname(parent)); + parent = skip_subsystem(parent, "platform"); + some_transport = true; + } else if (strcmp(subsys, "acpi") == 0) { + path_prepend(&path, "acpi-%s", udev_device_get_sysname(parent)); + parent = skip_subsystem(parent, "acpi"); + } else if (strcmp(subsys, "xen") == 0) { + path_prepend(&path, "xen-%s", udev_device_get_sysname(parent)); + parent = skip_subsystem(parent, "xen"); + } else if (strcmp(subsys, "virtio") == 0) { + path_prepend(&path, "virtio-pci-%s", udev_device_get_sysname(parent)); + parent = skip_subsystem(parent, "virtio"); + } else if (strcmp(subsys, "scm") == 0) { + path_prepend(&path, "scm-%s", udev_device_get_sysname(parent)); + parent = skip_subsystem(parent, "scm"); + } + + parent = udev_device_get_parent(parent); + } + + /* + * Do not return a single-parent-device-only for block + * devices, they might have entire buses behind it which + * do not get unique IDs only by using the parent device. + */ + if (!some_transport && streq(udev_device_get_subsystem(dev), "block")) { + free(path); + path = NULL; + } + +out: + if (path != NULL) { + char tag[UTIL_NAME_SIZE]; + size_t i; + const char *p; + + /* compose valid udev tag name */ + for (p = path, i = 0; *p; p++) { + if ((*p >= '0' && *p <= '9') || + (*p >= 'A' && *p <= 'Z') || + (*p >= 'a' && *p <= 'z') || + *p == '-') { + tag[i++] = *p; + continue; + } + + /* skip all leading '_' */ + if (i == 0) + continue; + + /* avoid second '_' */ + if (tag[i-1] == '_') + continue; + + tag[i++] = '_'; + } + /* strip trailing '_' */ + while (i > 0 && tag[i-1] == '_') + i--; + tag[i] = '\0'; + + udev_builtin_add_property(dev, test, "ID_PATH", path); + udev_builtin_add_property(dev, test, "ID_PATH_TAG", tag); + free(path); + return EXIT_SUCCESS; + } + return EXIT_FAILURE; +} + +const struct udev_builtin udev_builtin_path_id = { + .name = "path_id", + .cmd = builtin_path_id, + .help = "compose persistent device path", + .run_once = true, +}; diff --git a/src/udev/udev-builtin-uaccess.c b/src/udev/udev-builtin-uaccess.c new file mode 100644 index 000000000..662bac9e0 --- /dev/null +++ b/src/udev/udev-builtin-uaccess.c @@ -0,0 +1,99 @@ +/* + * manage device node user ACL + * + * Copyright 2010-2012 Kay Sievers + * Copyright 2010 Lennart Poettering + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include "logind-acl.h" +#include "udev.h" +#include "util.h" + +static int builtin_uaccess(struct udev_device *dev, int argc, char *argv[], bool test) +{ + int r; + const char *path = NULL, *seat; + bool changed_acl = false; + uid_t uid; + + log_set_target(LOG_TARGET_AUTO); + log_parse_environment(); + log_open(); + + umask(0022); + + /* don't muck around with ACLs when the system is not running systemd */ + if (!sd_booted()) + return 0; + + path = udev_device_get_devnode(dev); + seat = udev_device_get_property_value(dev, "ID_SEAT"); + if (!seat) + seat = "seat0"; + + r = sd_seat_get_active(seat, NULL, &uid); + if (r == -ENOENT) { + /* No active session on this seat */ + r = 0; + goto finish; + } else if (r < 0) { + log_error("Failed to determine active user on seat %s.", seat); + goto finish; + } + + r = devnode_acl(path, true, false, 0, true, uid); + if (r < 0) { + log_error("Failed to apply ACL on %s: %s", path, strerror(-r)); + goto finish; + } + + changed_acl = true; + r = 0; + +finish: + if (path && !changed_acl) { + int k; + + /* Better be safe than sorry and reset ACL */ + k = devnode_acl(path, true, false, 0, false, 0); + if (k < 0) { + log_error("Failed to apply ACL on %s: %s", path, strerror(-k)); + if (r >= 0) + r = k; + } + } + + return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; +} + +const struct udev_builtin udev_builtin_uaccess = { + .name = "uaccess", + .cmd = builtin_uaccess, + .help = "manage device node user ACL", +}; diff --git a/src/udev/udev-builtin-usb_id.c b/src/udev/udev-builtin-usb_id.c new file mode 100644 index 000000000..13d122639 --- /dev/null +++ b/src/udev/udev-builtin-usb_id.c @@ -0,0 +1,477 @@ +/* + * USB device properties and persistent device path + * + * Copyright (c) 2005 SUSE Linux Products GmbH, Germany + * Author: Hannes Reinecke + * + * Copyright (C) 2005-2011 Kay Sievers + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "udev.h" + +static void set_usb_iftype(char *to, int if_class_num, size_t len) +{ + const char *type = "generic"; + + switch (if_class_num) { + case 1: + type = "audio"; + break; + case 2: /* CDC-Control */ + break; + case 3: + type = "hid"; + break; + case 5: /* Physical */ + break; + case 6: + type = "media"; + break; + case 7: + type = "printer"; + break; + case 8: + type = "storage"; + break; + case 9: + type = "hub"; + break; + case 0x0a: /* CDC-Data */ + break; + case 0x0b: /* Chip/Smart Card */ + break; + case 0x0d: /* Content Security */ + break; + case 0x0e: + type = "video"; + break; + case 0xdc: /* Diagnostic Device */ + break; + case 0xe0: /* Wireless Controller */ + break; + case 0xfe: /* Application-specific */ + break; + case 0xff: /* Vendor-specific */ + break; + default: + break; + } + strncpy(to, type, len); + to[len-1] = '\0'; +} + +static int set_usb_mass_storage_ifsubtype(char *to, const char *from, size_t len) +{ + int type_num = 0; + char *eptr; + const char *type = "generic"; + + type_num = strtoul(from, &eptr, 0); + if (eptr != from) { + switch (type_num) { + case 2: + type = "atapi"; + break; + case 3: + type = "tape"; + break; + case 4: /* UFI */ + case 5: /* SFF-8070i */ + type = "floppy"; + break; + case 1: /* RBC devices */ + type = "rbc"; + break; + case 6: /* Transparent SPC-2 devices */ + type = "scsi"; + break; + default: + break; + } + } + util_strscpy(to, len, type); + return type_num; +} + +static void set_scsi_type(char *to, const char *from, size_t len) +{ + int type_num; + char *eptr; + const char *type = "generic"; + + type_num = strtoul(from, &eptr, 0); + if (eptr != from) { + switch (type_num) { + case 0: + case 0xe: + type = "disk"; + break; + case 1: + type = "tape"; + break; + case 4: + case 7: + case 0xf: + type = "optical"; + break; + case 5: + type = "cd"; + break; + default: + break; + } + } + util_strscpy(to, len, type); +} + +#define USB_DT_DEVICE 0x01 +#define USB_DT_INTERFACE 0x04 + +static int dev_if_packed_info(struct udev_device *dev, char *ifs_str, size_t len) +{ + char *filename = NULL; + int fd; + ssize_t size; + unsigned char buf[18 + 65535]; + unsigned int pos, strpos; + struct usb_interface_descriptor { + u_int8_t bLength; + u_int8_t bDescriptorType; + u_int8_t bInterfaceNumber; + u_int8_t bAlternateSetting; + u_int8_t bNumEndpoints; + u_int8_t bInterfaceClass; + u_int8_t bInterfaceSubClass; + u_int8_t bInterfaceProtocol; + u_int8_t iInterface; + } __attribute__((packed)); + int err = 0; + + if (asprintf(&filename, "%s/descriptors", udev_device_get_syspath(dev)) < 0) { + err = -1; + goto out; + } + fd = open(filename, O_RDONLY|O_CLOEXEC); + if (fd < 0) { + fprintf(stderr, "error opening USB device 'descriptors' file\n"); + err = -1; + goto out; + } + size = read(fd, buf, sizeof(buf)); + close(fd); + if (size < 18 || size == sizeof(buf)) { + err = -1; + goto out; + } + + pos = 0; + strpos = 0; + ifs_str[0] = '\0'; + while (pos < sizeof(buf) && strpos+7 < len-2) { + struct usb_interface_descriptor *desc; + char if_str[8]; + + desc = (struct usb_interface_descriptor *) &buf[pos]; + if (desc->bLength < 3) + break; + pos += desc->bLength; + + if (desc->bDescriptorType != USB_DT_INTERFACE) + continue; + + if (snprintf(if_str, 8, ":%02x%02x%02x", + desc->bInterfaceClass, + desc->bInterfaceSubClass, + desc->bInterfaceProtocol) != 7) + continue; + + if (strstr(ifs_str, if_str) != NULL) + continue; + + memcpy(&ifs_str[strpos], if_str, 8), + strpos += 7; + } + if (strpos > 0) { + ifs_str[strpos++] = ':'; + ifs_str[strpos++] = '\0'; + } +out: + free(filename); + return err; +} + +/* + * A unique USB identification is generated like this: + * + * 1.) Get the USB device type from InterfaceClass and InterfaceSubClass + * 2.) If the device type is 'Mass-Storage/SPC-2' or 'Mass-Storage/RBC' + * use the SCSI vendor and model as USB-Vendor and USB-model. + * 3.) Otherwise use the USB manufacturer and product as + * USB-Vendor and USB-model. Any non-printable characters + * in those strings will be skipped; a slash '/' will be converted + * into a full stop '.'. + * 4.) If that fails, too, we will use idVendor and idProduct + * as USB-Vendor and USB-model. + * 5.) The USB identification is the USB-vendor and USB-model + * string concatenated with an underscore '_'. + * 6.) If the device supplies a serial number, this number + * is concatenated with the identification with an underscore '_'. + */ +static int builtin_usb_id(struct udev_device *dev, int argc, char *argv[], bool test) +{ + char vendor_str[64]; + char vendor_str_enc[256]; + const char *vendor_id; + char model_str[64]; + char model_str_enc[256]; + const char *product_id; + char serial_str[UTIL_NAME_SIZE]; + char packed_if_str[UTIL_NAME_SIZE]; + char revision_str[64]; + char type_str[64]; + char instance_str[64]; + const char *ifnum = NULL; + const char *driver = NULL; + char serial[256]; + + struct udev_device *dev_interface = NULL; + struct udev_device *dev_usb = NULL; + const char *if_class, *if_subclass; + int if_class_num; + int protocol = 0; + size_t l; + char *s; + + vendor_str[0] = '\0'; + model_str[0] = '\0'; + serial_str[0] = '\0'; + packed_if_str[0] = '\0'; + revision_str[0] = '\0'; + type_str[0] = '\0'; + instance_str[0] = '\0'; + + /* shortcut, if we are called directly for a "usb_device" type */ + if (udev_device_get_devtype(dev) != NULL && strcmp(udev_device_get_devtype(dev), "usb_device") == 0) { + dev_if_packed_info(dev, packed_if_str, sizeof(packed_if_str)); + dev_usb = dev; + goto fallback; + } + + /* usb interface directory */ + dev_interface = udev_device_get_parent_with_subsystem_devtype(dev, "usb", "usb_interface"); + if (dev_interface == NULL) { + log_debug("unable to access usb_interface device of '%s'\n", + udev_device_get_syspath(dev)); + return EXIT_FAILURE; + } + + ifnum = udev_device_get_sysattr_value(dev_interface, "bInterfaceNumber"); + driver = udev_device_get_sysattr_value(dev_interface, "driver"); + + if_class = udev_device_get_sysattr_value(dev_interface, "bInterfaceClass"); + if (!if_class) { + log_debug("%s: cannot get bInterfaceClass attribute\n", + udev_device_get_sysname(dev)); + return EXIT_FAILURE; + } + + if_class_num = strtoul(if_class, NULL, 16); + if (if_class_num == 8) { + /* mass storage */ + if_subclass = udev_device_get_sysattr_value(dev_interface, "bInterfaceSubClass"); + if (if_subclass != NULL) + protocol = set_usb_mass_storage_ifsubtype(type_str, if_subclass, sizeof(type_str)-1); + } else { + set_usb_iftype(type_str, if_class_num, sizeof(type_str)-1); + } + + log_debug("%s: if_class %d protocol %d\n", + udev_device_get_syspath(dev_interface), if_class_num, protocol); + + /* usb device directory */ + dev_usb = udev_device_get_parent_with_subsystem_devtype(dev_interface, "usb", "usb_device"); + if (!dev_usb) { + log_debug("unable to find parent 'usb' device of '%s'\n", + udev_device_get_syspath(dev)); + return EXIT_FAILURE; + } + + /* all interfaces of the device in a single string */ + dev_if_packed_info(dev_usb, packed_if_str, sizeof(packed_if_str)); + + /* mass storage : SCSI or ATAPI */ + if ((protocol == 6 || protocol == 2)) { + struct udev_device *dev_scsi; + const char *scsi_model, *scsi_vendor, *scsi_type, *scsi_rev; + int host, bus, target, lun; + + /* get scsi device */ + dev_scsi = udev_device_get_parent_with_subsystem_devtype(dev, "scsi", "scsi_device"); + if (dev_scsi == NULL) { + log_debug("unable to find parent 'scsi' device of '%s'\n", + udev_device_get_syspath(dev)); + goto fallback; + } + if (sscanf(udev_device_get_sysname(dev_scsi), "%d:%d:%d:%d", &host, &bus, &target, &lun) != 4) { + log_debug("invalid scsi device '%s'\n", udev_device_get_sysname(dev_scsi)); + goto fallback; + } + + /* Generic SPC-2 device */ + scsi_vendor = udev_device_get_sysattr_value(dev_scsi, "vendor"); + if (!scsi_vendor) { + log_debug("%s: cannot get SCSI vendor attribute\n", + udev_device_get_sysname(dev_scsi)); + goto fallback; + } + udev_util_encode_string(scsi_vendor, vendor_str_enc, sizeof(vendor_str_enc)); + util_replace_whitespace(scsi_vendor, vendor_str, sizeof(vendor_str)-1); + util_replace_chars(vendor_str, NULL); + + scsi_model = udev_device_get_sysattr_value(dev_scsi, "model"); + if (!scsi_model) { + log_debug("%s: cannot get SCSI model attribute\n", + udev_device_get_sysname(dev_scsi)); + goto fallback; + } + udev_util_encode_string(scsi_model, model_str_enc, sizeof(model_str_enc)); + util_replace_whitespace(scsi_model, model_str, sizeof(model_str)-1); + util_replace_chars(model_str, NULL); + + scsi_type = udev_device_get_sysattr_value(dev_scsi, "type"); + if (!scsi_type) { + log_debug("%s: cannot get SCSI type attribute\n", + udev_device_get_sysname(dev_scsi)); + goto fallback; + } + set_scsi_type(type_str, scsi_type, sizeof(type_str)-1); + + scsi_rev = udev_device_get_sysattr_value(dev_scsi, "rev"); + if (!scsi_rev) { + log_debug("%s: cannot get SCSI revision attribute\n", + udev_device_get_sysname(dev_scsi)); + goto fallback; + } + util_replace_whitespace(scsi_rev, revision_str, sizeof(revision_str)-1); + util_replace_chars(revision_str, NULL); + + /* + * some broken devices have the same identifiers + * for all luns, export the target:lun number + */ + sprintf(instance_str, "%d:%d", target, lun); + } + +fallback: + vendor_id = udev_device_get_sysattr_value(dev_usb, "idVendor"); + product_id = udev_device_get_sysattr_value(dev_usb, "idProduct"); + + /* fallback to USB vendor & device */ + if (vendor_str[0] == '\0') { + const char *usb_vendor = NULL; + + usb_vendor = udev_device_get_sysattr_value(dev_usb, "manufacturer"); + if (!usb_vendor) + usb_vendor = vendor_id; + if (!usb_vendor) { + log_debug("No USB vendor information available\n"); + return EXIT_FAILURE; + } + udev_util_encode_string(usb_vendor, vendor_str_enc, sizeof(vendor_str_enc)); + util_replace_whitespace(usb_vendor, vendor_str, sizeof(vendor_str)-1); + util_replace_chars(vendor_str, NULL); + } + + if (model_str[0] == '\0') { + const char *usb_model = NULL; + + usb_model = udev_device_get_sysattr_value(dev_usb, "product"); + if (!usb_model) + usb_model = product_id; + if (!usb_model) + return EXIT_FAILURE; + udev_util_encode_string(usb_model, model_str_enc, sizeof(model_str_enc)); + util_replace_whitespace(usb_model, model_str, sizeof(model_str)-1); + util_replace_chars(model_str, NULL); + } + + if (revision_str[0] == '\0') { + const char *usb_rev; + + usb_rev = udev_device_get_sysattr_value(dev_usb, "bcdDevice"); + if (usb_rev) { + util_replace_whitespace(usb_rev, revision_str, sizeof(revision_str)-1); + util_replace_chars(revision_str, NULL); + } + } + + if (serial_str[0] == '\0') { + const char *usb_serial; + + usb_serial = udev_device_get_sysattr_value(dev_usb, "serial"); + if (usb_serial) { + util_replace_whitespace(usb_serial, serial_str, sizeof(serial_str)-1); + util_replace_chars(serial_str, NULL); + } + } + + s = serial; + l = util_strpcpyl(&s, sizeof(serial), vendor_str, "_", model_str, NULL); + if (serial_str[0] != '\0') + l = util_strpcpyl(&s, l, "_", serial_str, NULL); + + if (instance_str[0] != '\0') + util_strpcpyl(&s, l, "-", instance_str, NULL); + + udev_builtin_add_property(dev, test, "ID_VENDOR", vendor_str); + udev_builtin_add_property(dev, test, "ID_VENDOR_ENC", vendor_str_enc); + udev_builtin_add_property(dev, test, "ID_VENDOR_ID", vendor_id); + udev_builtin_add_property(dev, test, "ID_MODEL", model_str); + udev_builtin_add_property(dev, test, "ID_MODEL_ENC", model_str_enc); + udev_builtin_add_property(dev, test, "ID_MODEL_ID", product_id); + udev_builtin_add_property(dev, test, "ID_REVISION", revision_str); + udev_builtin_add_property(dev, test, "ID_SERIAL", serial); + if (serial_str[0] != '\0') + udev_builtin_add_property(dev, test, "ID_SERIAL_SHORT", serial_str); + if (type_str[0] != '\0') + udev_builtin_add_property(dev, test, "ID_TYPE", type_str); + if (instance_str[0] != '\0') + udev_builtin_add_property(dev, test, "ID_INSTANCE", instance_str); + udev_builtin_add_property(dev, test, "ID_BUS", "usb"); + if (packed_if_str[0] != '\0') + udev_builtin_add_property(dev, test, "ID_USB_INTERFACES", packed_if_str); + if (ifnum != NULL) + udev_builtin_add_property(dev, test, "ID_USB_INTERFACE_NUM", ifnum); + if (driver != NULL) + udev_builtin_add_property(dev, test, "ID_USB_DRIVER", driver); + return EXIT_SUCCESS; +} + +const struct udev_builtin udev_builtin_usb_id = { + .name = "usb_id", + .cmd = builtin_usb_id, + .help = "usb device properties", + .run_once = true, +}; diff --git a/src/udev/udev-builtin.c b/src/udev/udev-builtin.c new file mode 100644 index 000000000..32e6e1e90 --- /dev/null +++ b/src/udev/udev-builtin.c @@ -0,0 +1,148 @@ +/*** + This file is part of systemd. + + Copyright 2007-2012 Kay Sievers + + 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include + +#include "udev.h" + +static bool initialized; + +static const struct udev_builtin *builtins[] = { +#ifdef HAVE_BLKID + [UDEV_BUILTIN_BLKID] = &udev_builtin_blkid, +#endif + [UDEV_BUILTIN_BTRFS] = &udev_builtin_btrfs, + [UDEV_BUILTIN_FIRMWARE] = &udev_builtin_firmware, + [UDEV_BUILTIN_HWDB] = &udev_builtin_hwdb, + [UDEV_BUILTIN_INPUT_ID] = &udev_builtin_input_id, +#ifdef HAVE_KMOD + [UDEV_BUILTIN_KMOD] = &udev_builtin_kmod, +#endif + [UDEV_BUILTIN_NET_ID] = &udev_builtin_net_id, + [UDEV_BUILTIN_PATH_ID] = &udev_builtin_path_id, + [UDEV_BUILTIN_USB_ID] = &udev_builtin_usb_id, +#ifdef HAVE_ACL + [UDEV_BUILTIN_UACCESS] = &udev_builtin_uaccess, +#endif +}; + +void udev_builtin_init(struct udev *udev) +{ + unsigned int i; + + if (initialized) + return; + + for (i = 0; i < ELEMENTSOF(builtins); i++) + if (builtins[i]->init) + builtins[i]->init(udev); + + initialized = true; +} + +void udev_builtin_exit(struct udev *udev) +{ + unsigned int i; + + if (!initialized) + return; + + for (i = 0; i < ELEMENTSOF(builtins); i++) + if (builtins[i]->exit) + builtins[i]->exit(udev); + + initialized = false; +} + +bool udev_builtin_validate(struct udev *udev) +{ + unsigned int i; + + for (i = 0; i < ELEMENTSOF(builtins); i++) + if (builtins[i]->validate && builtins[i]->validate(udev)) + return true; + return false; +} + +void udev_builtin_list(struct udev *udev) +{ + unsigned int i; + + for (i = 0; i < ELEMENTSOF(builtins); i++) + fprintf(stderr, " %-12s %s\n", builtins[i]->name, builtins[i]->help); +} + +const char *udev_builtin_name(enum udev_builtin_cmd cmd) +{ + return builtins[cmd]->name; +} + +bool udev_builtin_run_once(enum udev_builtin_cmd cmd) +{ + return builtins[cmd]->run_once; +} + +enum udev_builtin_cmd udev_builtin_lookup(const char *command) +{ + char name[UTIL_PATH_SIZE]; + enum udev_builtin_cmd i; + char *pos; + + util_strscpy(name, sizeof(name), command); + pos = strchr(name, ' '); + if (pos) + pos[0] = '\0'; + for (i = 0; i < ELEMENTSOF(builtins); i++) + if (strcmp(builtins[i]->name, name) == 0) + return i; + return UDEV_BUILTIN_MAX; +} + +int udev_builtin_run(struct udev_device *dev, enum udev_builtin_cmd cmd, const char *command, bool test) +{ + char arg[UTIL_PATH_SIZE]; + int argc; + char *argv[128]; + + /* we need '0' here to reset the internal state */ + optind = 0; + util_strscpy(arg, sizeof(arg), command); + udev_build_argv(udev_device_get_udev(dev), arg, &argc, argv); + return builtins[cmd]->cmd(dev, argc, argv, test); +} + +int udev_builtin_add_property(struct udev_device *dev, bool test, const char *key, const char *val) +{ + struct udev_list_entry *entry; + + entry = udev_device_add_property(dev, key, val); + /* store in db, skip private keys */ + if (key[0] != '.') + udev_list_entry_set_num(entry, true); + + if (test) + printf("%s=%s\n", key, val); + return 0; +} diff --git a/src/udev/udev-ctrl.c b/src/udev/udev-ctrl.c new file mode 100644 index 000000000..a235912ff --- /dev/null +++ b/src/udev/udev-ctrl.c @@ -0,0 +1,490 @@ +/* + * libudev - interface to udev device information + * + * Copyright (C) 2008 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "udev.h" + +/* wire protocol magic must match */ +#define UDEV_CTRL_MAGIC 0xdead1dea + +enum udev_ctrl_msg_type { + UDEV_CTRL_UNKNOWN, + UDEV_CTRL_SET_LOG_LEVEL, + UDEV_CTRL_STOP_EXEC_QUEUE, + UDEV_CTRL_START_EXEC_QUEUE, + UDEV_CTRL_RELOAD, + UDEV_CTRL_SET_ENV, + UDEV_CTRL_SET_CHILDREN_MAX, + UDEV_CTRL_PING, + UDEV_CTRL_EXIT, +}; + +struct udev_ctrl_msg_wire { + char version[16]; + unsigned int magic; + enum udev_ctrl_msg_type type; + union { + int intval; + char buf[256]; + }; +}; + +struct udev_ctrl_msg { + int refcount; + struct udev_ctrl_connection *conn; + struct udev_ctrl_msg_wire ctrl_msg_wire; +}; + +struct udev_ctrl { + int refcount; + struct udev *udev; + int sock; + struct sockaddr_un saddr; + socklen_t addrlen; + bool bound; + bool cleanup_socket; + bool connected; +}; + +struct udev_ctrl_connection { + int refcount; + struct udev_ctrl *uctrl; + int sock; +}; + +struct udev_ctrl *udev_ctrl_new_from_fd(struct udev *udev, int fd) +{ + struct udev_ctrl *uctrl; + + uctrl = calloc(1, sizeof(struct udev_ctrl)); + if (uctrl == NULL) + return NULL; + uctrl->refcount = 1; + uctrl->udev = udev; + + if (fd < 0) { + uctrl->sock = socket(AF_LOCAL, SOCK_SEQPACKET|SOCK_NONBLOCK|SOCK_CLOEXEC, 0); + if (uctrl->sock < 0) { + log_error("error getting socket: %m\n"); + udev_ctrl_unref(uctrl); + return NULL; + } + } else { + uctrl->bound = true; + uctrl->sock = fd; + } + + uctrl->saddr.sun_family = AF_LOCAL; + util_strscpy(uctrl->saddr.sun_path, sizeof(uctrl->saddr.sun_path), "/run/udev/control"); + uctrl->addrlen = offsetof(struct sockaddr_un, sun_path) + strlen(uctrl->saddr.sun_path); + return uctrl; +} + +struct udev_ctrl *udev_ctrl_new(struct udev *udev) +{ + return udev_ctrl_new_from_fd(udev, -1); +} + +int udev_ctrl_enable_receiving(struct udev_ctrl *uctrl) +{ + int err; + + if (!uctrl->bound) { + err = bind(uctrl->sock, (struct sockaddr *)&uctrl->saddr, uctrl->addrlen); + if (err < 0 && errno == EADDRINUSE) { + unlink(uctrl->saddr.sun_path); + err = bind(uctrl->sock, (struct sockaddr *)&uctrl->saddr, uctrl->addrlen); + } + + if (err < 0) { + err = -errno; + log_error("bind failed: %m\n"); + return err; + } + + err = listen(uctrl->sock, 0); + if (err < 0) { + err = -errno; + log_error("listen failed: %m\n"); + return err; + } + + uctrl->bound = true; + uctrl->cleanup_socket = true; + } + return 0; +} + +struct udev *udev_ctrl_get_udev(struct udev_ctrl *uctrl) +{ + return uctrl->udev; +} + +struct udev_ctrl *udev_ctrl_ref(struct udev_ctrl *uctrl) +{ + if (uctrl == NULL) + return NULL; + uctrl->refcount++; + return uctrl; +} + +struct udev_ctrl *udev_ctrl_unref(struct udev_ctrl *uctrl) +{ + if (uctrl == NULL) + return NULL; + uctrl->refcount--; + if (uctrl->refcount > 0) + return uctrl; + if (uctrl->sock >= 0) + close(uctrl->sock); + free(uctrl); + return NULL; +} + +int udev_ctrl_cleanup(struct udev_ctrl *uctrl) +{ + if (uctrl == NULL) + return 0; + if (uctrl->cleanup_socket) + unlink(uctrl->saddr.sun_path); + return 0; +} + +int udev_ctrl_get_fd(struct udev_ctrl *uctrl) +{ + if (uctrl == NULL) + return -EINVAL; + return uctrl->sock; +} + +struct udev_ctrl_connection *udev_ctrl_get_connection(struct udev_ctrl *uctrl) +{ + struct udev_ctrl_connection *conn; + struct ucred ucred; + socklen_t slen; + const int on = 1; + + conn = calloc(1, sizeof(struct udev_ctrl_connection)); + if (conn == NULL) + return NULL; + conn->refcount = 1; + conn->uctrl = uctrl; + + conn->sock = accept4(uctrl->sock, NULL, NULL, SOCK_CLOEXEC|SOCK_NONBLOCK); + if (conn->sock < 0) { + if (errno != EINTR) + log_error("unable to receive ctrl connection: %m\n"); + goto err; + } + + /* check peer credential of connection */ + slen = sizeof(ucred); + if (getsockopt(conn->sock, SOL_SOCKET, SO_PEERCRED, &ucred, &slen) < 0) { + log_error("unable to receive credentials of ctrl connection: %m\n"); + goto err; + } + if (ucred.uid > 0) { + log_error("sender uid=%i, message ignored\n", ucred.uid); + goto err; + } + + /* enable receiving of the sender credentials in the messages */ + setsockopt(conn->sock, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on)); + udev_ctrl_ref(uctrl); + return conn; +err: + if (conn->sock >= 0) + close(conn->sock); + free(conn); + return NULL; +} + +struct udev_ctrl_connection *udev_ctrl_connection_ref(struct udev_ctrl_connection *conn) +{ + if (conn == NULL) + return NULL; + conn->refcount++; + return conn; +} + +struct udev_ctrl_connection *udev_ctrl_connection_unref(struct udev_ctrl_connection *conn) +{ + if (conn == NULL) + return NULL; + conn->refcount--; + if (conn->refcount > 0) + return conn; + if (conn->sock >= 0) + close(conn->sock); + udev_ctrl_unref(conn->uctrl); + free(conn); + return NULL; +} + +static int ctrl_send(struct udev_ctrl *uctrl, enum udev_ctrl_msg_type type, int intval, const char *buf, int timeout) +{ + struct udev_ctrl_msg_wire ctrl_msg_wire; + int err = 0; + + memset(&ctrl_msg_wire, 0x00, sizeof(struct udev_ctrl_msg_wire)); + strcpy(ctrl_msg_wire.version, "udev-" VERSION); + ctrl_msg_wire.magic = UDEV_CTRL_MAGIC; + ctrl_msg_wire.type = type; + + if (buf != NULL) + util_strscpy(ctrl_msg_wire.buf, sizeof(ctrl_msg_wire.buf), buf); + else + ctrl_msg_wire.intval = intval; + + if (!uctrl->connected) { + if (connect(uctrl->sock, (struct sockaddr *)&uctrl->saddr, uctrl->addrlen) < 0) { + err = -errno; + goto out; + } + uctrl->connected = true; + } + if (send(uctrl->sock, &ctrl_msg_wire, sizeof(ctrl_msg_wire), 0) < 0) { + err = -errno; + goto out; + } + + /* wait for peer message handling or disconnect */ + for (;;) { + struct pollfd pfd[1]; + int r; + + pfd[0].fd = uctrl->sock; + pfd[0].events = POLLIN; + r = poll(pfd, 1, timeout * 1000); + if (r < 0) { + if (errno == EINTR) + continue; + err = -errno; + break; + } + + if (r > 0 && pfd[0].revents & POLLERR) { + err = -EIO; + break; + } + + if (r == 0) + err = -ETIMEDOUT; + break; + } +out: + return err; +} + +int udev_ctrl_send_set_log_level(struct udev_ctrl *uctrl, int priority, int timeout) +{ + return ctrl_send(uctrl, UDEV_CTRL_SET_LOG_LEVEL, priority, NULL, timeout); +} + +int udev_ctrl_send_stop_exec_queue(struct udev_ctrl *uctrl, int timeout) +{ + return ctrl_send(uctrl, UDEV_CTRL_STOP_EXEC_QUEUE, 0, NULL, timeout); +} + +int udev_ctrl_send_start_exec_queue(struct udev_ctrl *uctrl, int timeout) +{ + return ctrl_send(uctrl, UDEV_CTRL_START_EXEC_QUEUE, 0, NULL, timeout); +} + +int udev_ctrl_send_reload(struct udev_ctrl *uctrl, int timeout) +{ + return ctrl_send(uctrl, UDEV_CTRL_RELOAD, 0, NULL, timeout); +} + +int udev_ctrl_send_set_env(struct udev_ctrl *uctrl, const char *key, int timeout) +{ + return ctrl_send(uctrl, UDEV_CTRL_SET_ENV, 0, key, timeout); +} + +int udev_ctrl_send_set_children_max(struct udev_ctrl *uctrl, int count, int timeout) +{ + return ctrl_send(uctrl, UDEV_CTRL_SET_CHILDREN_MAX, count, NULL, timeout); +} + +int udev_ctrl_send_ping(struct udev_ctrl *uctrl, int timeout) +{ + return ctrl_send(uctrl, UDEV_CTRL_PING, 0, NULL, timeout); +} + +int udev_ctrl_send_exit(struct udev_ctrl *uctrl, int timeout) +{ + return ctrl_send(uctrl, UDEV_CTRL_EXIT, 0, NULL, timeout); +} + +struct udev_ctrl_msg *udev_ctrl_receive_msg(struct udev_ctrl_connection *conn) +{ + struct udev_ctrl_msg *uctrl_msg; + ssize_t size; + struct msghdr smsg; + struct cmsghdr *cmsg; + struct iovec iov; + struct ucred *cred; + char cred_msg[CMSG_SPACE(sizeof(struct ucred))]; + + uctrl_msg = calloc(1, sizeof(struct udev_ctrl_msg)); + if (uctrl_msg == NULL) + return NULL; + uctrl_msg->refcount = 1; + uctrl_msg->conn = conn; + udev_ctrl_connection_ref(conn); + + /* wait for the incoming message */ + for(;;) { + struct pollfd pfd[1]; + int r; + + pfd[0].fd = conn->sock; + pfd[0].events = POLLIN; + + r = poll(pfd, 1, 10000); + if (r < 0) { + if (errno == EINTR) + continue; + goto err; + } else if (r == 0) { + log_error("timeout waiting for ctrl message\n"); + goto err; + } else { + if (!(pfd[0].revents & POLLIN)) { + log_error("ctrl connection error: %m\n"); + goto err; + } + } + + break; + } + + iov.iov_base = &uctrl_msg->ctrl_msg_wire; + iov.iov_len = sizeof(struct udev_ctrl_msg_wire); + memset(&smsg, 0x00, sizeof(struct msghdr)); + smsg.msg_iov = &iov; + smsg.msg_iovlen = 1; + smsg.msg_control = cred_msg; + smsg.msg_controllen = sizeof(cred_msg); + size = recvmsg(conn->sock, &smsg, 0); + if (size < 0) { + log_error("unable to receive ctrl message: %m\n"); + goto err; + } + cmsg = CMSG_FIRSTHDR(&smsg); + cred = (struct ucred *) CMSG_DATA(cmsg); + + if (cmsg == NULL || cmsg->cmsg_type != SCM_CREDENTIALS) { + log_error("no sender credentials received, message ignored\n"); + goto err; + } + + if (cred->uid != 0) { + log_error("sender uid=%i, message ignored\n", cred->uid); + goto err; + } + + if (uctrl_msg->ctrl_msg_wire.magic != UDEV_CTRL_MAGIC) { + log_error("message magic 0x%08x doesn't match, ignore it\n", uctrl_msg->ctrl_msg_wire.magic); + goto err; + } + + return uctrl_msg; +err: + udev_ctrl_msg_unref(uctrl_msg); + return NULL; +} + +struct udev_ctrl_msg *udev_ctrl_msg_ref(struct udev_ctrl_msg *ctrl_msg) +{ + if (ctrl_msg == NULL) + return NULL; + ctrl_msg->refcount++; + return ctrl_msg; +} + +struct udev_ctrl_msg *udev_ctrl_msg_unref(struct udev_ctrl_msg *ctrl_msg) +{ + if (ctrl_msg == NULL) + return NULL; + ctrl_msg->refcount--; + if (ctrl_msg->refcount > 0) + return ctrl_msg; + udev_ctrl_connection_unref(ctrl_msg->conn); + free(ctrl_msg); + return NULL; +} + +int udev_ctrl_get_set_log_level(struct udev_ctrl_msg *ctrl_msg) +{ + if (ctrl_msg->ctrl_msg_wire.type == UDEV_CTRL_SET_LOG_LEVEL) + return ctrl_msg->ctrl_msg_wire.intval; + return -1; +} + +int udev_ctrl_get_stop_exec_queue(struct udev_ctrl_msg *ctrl_msg) +{ + if (ctrl_msg->ctrl_msg_wire.type == UDEV_CTRL_STOP_EXEC_QUEUE) + return 1; + return -1; +} + +int udev_ctrl_get_start_exec_queue(struct udev_ctrl_msg *ctrl_msg) +{ + if (ctrl_msg->ctrl_msg_wire.type == UDEV_CTRL_START_EXEC_QUEUE) + return 1; + return -1; +} + +int udev_ctrl_get_reload(struct udev_ctrl_msg *ctrl_msg) +{ + if (ctrl_msg->ctrl_msg_wire.type == UDEV_CTRL_RELOAD) + return 1; + return -1; +} + +const char *udev_ctrl_get_set_env(struct udev_ctrl_msg *ctrl_msg) +{ + if (ctrl_msg->ctrl_msg_wire.type == UDEV_CTRL_SET_ENV) + return ctrl_msg->ctrl_msg_wire.buf; + return NULL; +} + +int udev_ctrl_get_set_children_max(struct udev_ctrl_msg *ctrl_msg) +{ + if (ctrl_msg->ctrl_msg_wire.type == UDEV_CTRL_SET_CHILDREN_MAX) + return ctrl_msg->ctrl_msg_wire.intval; + return -1; +} + +int udev_ctrl_get_ping(struct udev_ctrl_msg *ctrl_msg) +{ + if (ctrl_msg->ctrl_msg_wire.type == UDEV_CTRL_PING) + return 1; + return -1; +} + +int udev_ctrl_get_exit(struct udev_ctrl_msg *ctrl_msg) +{ + if (ctrl_msg->ctrl_msg_wire.type == UDEV_CTRL_EXIT) + return 1; + return -1; +} diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c new file mode 100644 index 000000000..5eedf4f0d --- /dev/null +++ b/src/udev/udev-event.c @@ -0,0 +1,911 @@ +/* + * Copyright (C) 2003-2010 Kay Sievers + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "udev.h" + +struct udev_event *udev_event_new(struct udev_device *dev) +{ + struct udev *udev = udev_device_get_udev(dev); + struct udev_event *event; + + event = calloc(1, sizeof(struct udev_event)); + if (event == NULL) + return NULL; + event->dev = dev; + event->udev = udev; + udev_list_init(udev, &event->run_list, false); + event->fd_signal = -1; + event->birth_usec = now(CLOCK_MONOTONIC); + event->timeout_usec = 30 * 1000 * 1000; + return event; +} + +void udev_event_unref(struct udev_event *event) +{ + if (event == NULL) + return; + udev_list_cleanup(&event->run_list); + free(event->program_result); + free(event->name); + free(event); +} + +size_t udev_event_apply_format(struct udev_event *event, const char *src, char *dest, size_t size) +{ + struct udev_device *dev = event->dev; + enum subst_type { + SUBST_UNKNOWN, + SUBST_DEVNODE, + SUBST_ATTR, + SUBST_ENV, + SUBST_KERNEL, + SUBST_KERNEL_NUMBER, + SUBST_DRIVER, + SUBST_DEVPATH, + SUBST_ID, + SUBST_MAJOR, + SUBST_MINOR, + SUBST_RESULT, + SUBST_PARENT, + SUBST_NAME, + SUBST_LINKS, + SUBST_ROOT, + SUBST_SYS, + }; + static const struct subst_map { + const char *name; + const char fmt; + enum subst_type type; + } map[] = { + { .name = "devnode", .fmt = 'N', .type = SUBST_DEVNODE }, + { .name = "tempnode", .fmt = 'N', .type = SUBST_DEVNODE }, + { .name = "attr", .fmt = 's', .type = SUBST_ATTR }, + { .name = "sysfs", .fmt = 's', .type = SUBST_ATTR }, + { .name = "env", .fmt = 'E', .type = SUBST_ENV }, + { .name = "kernel", .fmt = 'k', .type = SUBST_KERNEL }, + { .name = "number", .fmt = 'n', .type = SUBST_KERNEL_NUMBER }, + { .name = "driver", .fmt = 'd', .type = SUBST_DRIVER }, + { .name = "devpath", .fmt = 'p', .type = SUBST_DEVPATH }, + { .name = "id", .fmt = 'b', .type = SUBST_ID }, + { .name = "major", .fmt = 'M', .type = SUBST_MAJOR }, + { .name = "minor", .fmt = 'm', .type = SUBST_MINOR }, + { .name = "result", .fmt = 'c', .type = SUBST_RESULT }, + { .name = "parent", .fmt = 'P', .type = SUBST_PARENT }, + { .name = "name", .fmt = 'D', .type = SUBST_NAME }, + { .name = "links", .fmt = 'L', .type = SUBST_LINKS }, + { .name = "root", .fmt = 'r', .type = SUBST_ROOT }, + { .name = "sys", .fmt = 'S', .type = SUBST_SYS }, + }; + const char *from; + char *s; + size_t l; + + from = src; + s = dest; + l = size; + + for (;;) { + enum subst_type type = SUBST_UNKNOWN; + char attrbuf[UTIL_PATH_SIZE]; + char *attr = NULL; + + while (from[0] != '\0') { + if (from[0] == '$') { + /* substitute named variable */ + unsigned int i; + + if (from[1] == '$') { + from++; + goto copy; + } + + for (i = 0; i < ELEMENTSOF(map); i++) { + if (startswith(&from[1], map[i].name)) { + type = map[i].type; + from += strlen(map[i].name)+1; + goto subst; + } + } + } else if (from[0] == '%') { + /* substitute format char */ + unsigned int i; + + if (from[1] == '%') { + from++; + goto copy; + } + + for (i = 0; i < ELEMENTSOF(map); i++) { + if (from[1] == map[i].fmt) { + type = map[i].type; + from += 2; + goto subst; + } + } + } +copy: + /* copy char */ + if (l == 0) + goto out; + s[0] = from[0]; + from++; + s++; + l--; + } + + goto out; +subst: + /* extract possible $format{attr} */ + if (from[0] == '{') { + unsigned int i; + + from++; + for (i = 0; from[i] != '}'; i++) { + if (from[i] == '\0') { + log_error("missing closing brace for format '%s'\n", src); + goto out; + } + } + if (i >= sizeof(attrbuf)) + goto out; + memcpy(attrbuf, from, i); + attrbuf[i] = '\0'; + from += i+1; + attr = attrbuf; + } else { + attr = NULL; + } + + switch (type) { + case SUBST_DEVPATH: + l = util_strpcpy(&s, l, udev_device_get_devpath(dev)); + break; + case SUBST_KERNEL: + l = util_strpcpy(&s, l, udev_device_get_sysname(dev)); + break; + case SUBST_KERNEL_NUMBER: + if (udev_device_get_sysnum(dev) == NULL) + break; + l = util_strpcpy(&s, l, udev_device_get_sysnum(dev)); + break; + case SUBST_ID: + if (event->dev_parent == NULL) + break; + l = util_strpcpy(&s, l, udev_device_get_sysname(event->dev_parent)); + break; + case SUBST_DRIVER: { + const char *driver; + + if (event->dev_parent == NULL) + break; + + driver = udev_device_get_driver(event->dev_parent); + if (driver == NULL) + break; + l = util_strpcpy(&s, l, driver); + break; + } + case SUBST_MAJOR: { + char num[UTIL_PATH_SIZE]; + + sprintf(num, "%d", major(udev_device_get_devnum(dev))); + l = util_strpcpy(&s, l, num); + break; + } + case SUBST_MINOR: { + char num[UTIL_PATH_SIZE]; + + sprintf(num, "%d", minor(udev_device_get_devnum(dev))); + l = util_strpcpy(&s, l, num); + break; + } + case SUBST_RESULT: { + char *rest; + int i; + + if (event->program_result == NULL) + break; + /* get part part of the result string */ + i = 0; + if (attr != NULL) + i = strtoul(attr, &rest, 10); + if (i > 0) { + char result[UTIL_PATH_SIZE]; + char tmp[UTIL_PATH_SIZE]; + char *cpos; + + util_strscpy(result, sizeof(result), event->program_result); + cpos = result; + while (--i) { + while (cpos[0] != '\0' && !isspace(cpos[0])) + cpos++; + while (isspace(cpos[0])) + cpos++; + } + if (i > 0) { + log_error("requested part of result string not found\n"); + break; + } + util_strscpy(tmp, sizeof(tmp), cpos); + /* %{2+}c copies the whole string from the second part on */ + if (rest[0] != '+') { + cpos = strchr(tmp, ' '); + if (cpos) + cpos[0] = '\0'; + } + l = util_strpcpy(&s, l, tmp); + } else { + l = util_strpcpy(&s, l, event->program_result); + } + break; + } + case SUBST_ATTR: { + const char *value = NULL; + char vbuf[UTIL_NAME_SIZE]; + size_t len; + int count; + + if (attr == NULL) { + log_error("missing file parameter for attr\n"); + break; + } + + /* try to read the value specified by "[dmi/id]product_name" */ + if (util_resolve_subsys_kernel(event->udev, attr, vbuf, sizeof(vbuf), 1) == 0) + value = vbuf; + + /* try to read the attribute the device */ + if (value == NULL) + value = udev_device_get_sysattr_value(event->dev, attr); + + /* try to read the attribute of the parent device, other matches have selected */ + if (value == NULL && event->dev_parent != NULL && event->dev_parent != event->dev) + value = udev_device_get_sysattr_value(event->dev_parent, attr); + + if (value == NULL) + break; + + /* strip trailing whitespace, and replace unwanted characters */ + if (value != vbuf) + util_strscpy(vbuf, sizeof(vbuf), value); + len = strlen(vbuf); + while (len > 0 && isspace(vbuf[--len])) + vbuf[len] = '\0'; + count = util_replace_chars(vbuf, UDEV_ALLOWED_CHARS_INPUT); + if (count > 0) + log_debug("%i character(s) replaced\n" , count); + l = util_strpcpy(&s, l, vbuf); + break; + } + case SUBST_PARENT: { + struct udev_device *dev_parent; + const char *devnode; + + dev_parent = udev_device_get_parent(event->dev); + if (dev_parent == NULL) + break; + devnode = udev_device_get_devnode(dev_parent); + if (devnode != NULL) + l = util_strpcpy(&s, l, devnode + strlen("/dev/")); + break; + } + case SUBST_DEVNODE: + if (udev_device_get_devnode(dev) != NULL) + l = util_strpcpy(&s, l, udev_device_get_devnode(dev)); + break; + case SUBST_NAME: + if (event->name != NULL) + l = util_strpcpy(&s, l, event->name); + else if (udev_device_get_devnode(dev) != NULL) + l = util_strpcpy(&s, l, udev_device_get_devnode(dev) + strlen("/dev/")); + else + l = util_strpcpy(&s, l, udev_device_get_sysname(dev)); + break; + case SUBST_LINKS: { + struct udev_list_entry *list_entry; + + list_entry = udev_device_get_devlinks_list_entry(dev); + if (list_entry == NULL) + break; + l = util_strpcpy(&s, l, udev_list_entry_get_name(list_entry) + strlen("/dev/")); + udev_list_entry_foreach(list_entry, udev_list_entry_get_next(list_entry)) + l = util_strpcpyl(&s, l, " ", udev_list_entry_get_name(list_entry) + strlen("/dev/"), NULL); + break; + } + case SUBST_ROOT: + l = util_strpcpy(&s, l, "/dev"); + break; + case SUBST_SYS: + l = util_strpcpy(&s, l, "/sys"); + break; + case SUBST_ENV: + if (attr == NULL) { + break; + } else { + const char *value; + + value = udev_device_get_property_value(event->dev, attr); + if (value == NULL) + break; + l = util_strpcpy(&s, l, value); + break; + } + default: + log_error("unknown substitution type=%i\n", type); + break; + } + } + +out: + s[0] = '\0'; + return l; +} + +static int spawn_exec(struct udev_event *event, + const char *cmd, char *const argv[], char **envp, const sigset_t *sigmask, + int fd_stdout, int fd_stderr) +{ + int err; + int fd; + + /* discard child output or connect to pipe */ + fd = open("/dev/null", O_RDWR); + if (fd >= 0) { + dup2(fd, STDIN_FILENO); + if (fd_stdout < 0) + dup2(fd, STDOUT_FILENO); + if (fd_stderr < 0) + dup2(fd, STDERR_FILENO); + close(fd); + } else { + log_error("open /dev/null failed: %m\n"); + } + + /* connect pipes to std{out,err} */ + if (fd_stdout >= 0) { + dup2(fd_stdout, STDOUT_FILENO); + close(fd_stdout); + } + if (fd_stderr >= 0) { + dup2(fd_stderr, STDERR_FILENO); + close(fd_stderr); + } + + /* terminate child in case parent goes away */ + prctl(PR_SET_PDEATHSIG, SIGTERM); + + /* restore original udev sigmask before exec */ + if (sigmask) + sigprocmask(SIG_SETMASK, sigmask, NULL); + + execve(argv[0], argv, envp); + + /* exec failed */ + err = -errno; + log_error("failed to execute '%s' '%s': %m\n", argv[0], cmd); + return err; +} + +static void spawn_read(struct udev_event *event, + const char *cmd, + int fd_stdout, int fd_stderr, + char *result, size_t ressize) +{ + size_t respos = 0; + int fd_ep = -1; + struct epoll_event ep_outpipe, ep_errpipe; + + /* read from child if requested */ + if (fd_stdout < 0 && fd_stderr < 0) + return; + + fd_ep = epoll_create1(EPOLL_CLOEXEC); + if (fd_ep < 0) { + log_error("error creating epoll fd: %m\n"); + goto out; + } + + if (fd_stdout >= 0) { + memset(&ep_outpipe, 0, sizeof(struct epoll_event)); + ep_outpipe.events = EPOLLIN; + ep_outpipe.data.ptr = &fd_stdout; + if (epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_stdout, &ep_outpipe) < 0) { + log_error("fail to add fd to epoll: %m\n"); + goto out; + } + } + + if (fd_stderr >= 0) { + memset(&ep_errpipe, 0, sizeof(struct epoll_event)); + ep_errpipe.events = EPOLLIN; + ep_errpipe.data.ptr = &fd_stderr; + if (epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_stderr, &ep_errpipe) < 0) { + log_error("fail to add fd to epoll: %m\n"); + goto out; + } + } + + /* read child output */ + while (fd_stdout >= 0 || fd_stderr >= 0) { + int timeout; + int fdcount; + struct epoll_event ev[4]; + int i; + + if (event->timeout_usec > 0) { + usec_t age_usec; + + age_usec = now(CLOCK_MONOTONIC) - event->birth_usec; + if (age_usec >= event->timeout_usec) { + log_error("timeout '%s'\n", cmd); + goto out; + } + timeout = ((event->timeout_usec - age_usec) / 1000) + 1000; + } else { + timeout = -1; + } + + fdcount = epoll_wait(fd_ep, ev, ELEMENTSOF(ev), timeout); + if (fdcount < 0) { + if (errno == EINTR) + continue; + log_error("failed to poll: %m\n"); + goto out; + } + if (fdcount == 0) { + log_error("timeout '%s'\n", cmd); + goto out; + } + + for (i = 0; i < fdcount; i++) { + int *fd = (int *)ev[i].data.ptr; + + if (ev[i].events & EPOLLIN) { + ssize_t count; + char buf[4096]; + + count = read(*fd, buf, sizeof(buf)-1); + if (count <= 0) + continue; + buf[count] = '\0'; + + /* store stdout result */ + if (result != NULL && *fd == fd_stdout) { + if (respos + count < ressize) { + memcpy(&result[respos], buf, count); + respos += count; + } else { + log_error("'%s' ressize %zd too short\n", cmd, ressize); + } + } + + /* log debug output only if we watch stderr */ + if (fd_stderr >= 0) { + char *pos; + char *line; + + pos = buf; + while ((line = strsep(&pos, "\n"))) { + if (pos != NULL || line[0] != '\0') + log_debug("'%s'(%s) '%s'\n", cmd, *fd == fd_stdout ? "out" : "err" , line); + } + } + } else if (ev[i].events & EPOLLHUP) { + if (epoll_ctl(fd_ep, EPOLL_CTL_DEL, *fd, NULL) < 0) { + log_error("failed to remove fd from epoll: %m\n"); + goto out; + } + *fd = -1; + } + } + } + + /* return the child's stdout string */ + if (result != NULL) + result[respos] = '\0'; +out: + if (fd_ep >= 0) + close(fd_ep); +} + +static int spawn_wait(struct udev_event *event, const char *cmd, pid_t pid) +{ + struct pollfd pfd[1]; + int err = 0; + + pfd[0].events = POLLIN; + pfd[0].fd = event->fd_signal; + + while (pid > 0) { + int timeout; + int fdcount; + + if (event->timeout_usec > 0) { + usec_t age_usec; + + age_usec = now(CLOCK_MONOTONIC) - event->birth_usec; + if (age_usec >= event->timeout_usec) + timeout = 1000; + else + timeout = ((event->timeout_usec - age_usec) / 1000) + 1000; + } else { + timeout = -1; + } + + fdcount = poll(pfd, 1, timeout); + if (fdcount < 0) { + if (errno == EINTR) + continue; + err = -errno; + log_error("failed to poll: %m\n"); + goto out; + } + if (fdcount == 0) { + log_error("timeout: killing '%s' [%u]\n", cmd, pid); + kill(pid, SIGKILL); + } + + if (pfd[0].revents & POLLIN) { + struct signalfd_siginfo fdsi; + int status; + ssize_t size; + + size = read(event->fd_signal, &fdsi, sizeof(struct signalfd_siginfo)); + if (size != sizeof(struct signalfd_siginfo)) + continue; + + switch (fdsi.ssi_signo) { + case SIGTERM: + event->sigterm = true; + break; + case SIGCHLD: + if (waitpid(pid, &status, WNOHANG) < 0) + break; + if (WIFEXITED(status)) { + log_debug("'%s' [%u] exit with return code %i\n", cmd, pid, WEXITSTATUS(status)); + if (WEXITSTATUS(status) != 0) + err = -1; + } else if (WIFSIGNALED(status)) { + log_error("'%s' [%u] terminated by signal %i (%s)\n", cmd, pid, WTERMSIG(status), strsignal(WTERMSIG(status))); + err = -1; + } else if (WIFSTOPPED(status)) { + log_error("'%s' [%u] stopped\n", cmd, pid); + err = -1; + } else if (WIFCONTINUED(status)) { + log_error("'%s' [%u] continued\n", cmd, pid); + err = -1; + } else { + log_error("'%s' [%u] exit with status 0x%04x\n", cmd, pid, status); + err = -1; + } + pid = 0; + break; + } + } + } +out: + return err; +} + +int udev_build_argv(struct udev *udev, char *cmd, int *argc, char *argv[]) +{ + int i = 0; + char *pos; + + if (strchr(cmd, ' ') == NULL) { + argv[i++] = cmd; + goto out; + } + + pos = cmd; + while (pos != NULL && pos[0] != '\0') { + if (pos[0] == '\'') { + /* do not separate quotes */ + pos++; + argv[i] = strsep(&pos, "\'"); + if (pos != NULL) + while (pos[0] == ' ') + pos++; + } else { + argv[i] = strsep(&pos, " "); + if (pos != NULL) + while (pos[0] == ' ') + pos++; + } + i++; + } +out: + argv[i] = NULL; + if (argc) + *argc = i; + return 0; +} + +int udev_event_spawn(struct udev_event *event, + const char *cmd, char **envp, const sigset_t *sigmask, + char *result, size_t ressize) +{ + struct udev *udev = event->udev; + int outpipe[2] = {-1, -1}; + int errpipe[2] = {-1, -1}; + pid_t pid; + char arg[UTIL_PATH_SIZE]; + char *argv[128]; + char program[UTIL_PATH_SIZE]; + int err = 0; + + util_strscpy(arg, sizeof(arg), cmd); + udev_build_argv(event->udev, arg, NULL, argv); + + /* pipes from child to parent */ + if (result != NULL || udev_get_log_priority(udev) >= LOG_INFO) { + if (pipe2(outpipe, O_NONBLOCK) != 0) { + err = -errno; + log_error("pipe failed: %m\n"); + goto out; + } + } + if (udev_get_log_priority(udev) >= LOG_INFO) { + if (pipe2(errpipe, O_NONBLOCK) != 0) { + err = -errno; + log_error("pipe failed: %m\n"); + goto out; + } + } + + /* allow programs in /usr/lib/udev/ to be called without the path */ + if (argv[0][0] != '/') { + util_strscpyl(program, sizeof(program), UDEVLIBEXECDIR "/", argv[0], NULL); + argv[0] = program; + } + + pid = fork(); + switch(pid) { + case 0: + /* child closes parent's ends of pipes */ + if (outpipe[READ_END] >= 0) { + close(outpipe[READ_END]); + outpipe[READ_END] = -1; + } + if (errpipe[READ_END] >= 0) { + close(errpipe[READ_END]); + errpipe[READ_END] = -1; + } + + log_debug("starting '%s'\n", cmd); + + spawn_exec(event, cmd, argv, envp, sigmask, + outpipe[WRITE_END], errpipe[WRITE_END]); + + _exit(2 ); + case -1: + log_error("fork of '%s' failed: %m\n", cmd); + err = -1; + goto out; + default: + /* parent closed child's ends of pipes */ + if (outpipe[WRITE_END] >= 0) { + close(outpipe[WRITE_END]); + outpipe[WRITE_END] = -1; + } + if (errpipe[WRITE_END] >= 0) { + close(errpipe[WRITE_END]); + errpipe[WRITE_END] = -1; + } + + spawn_read(event, cmd, + outpipe[READ_END], errpipe[READ_END], + result, ressize); + + err = spawn_wait(event, cmd, pid); + } + +out: + if (outpipe[READ_END] >= 0) + close(outpipe[READ_END]); + if (outpipe[WRITE_END] >= 0) + close(outpipe[WRITE_END]); + if (errpipe[READ_END] >= 0) + close(errpipe[READ_END]); + if (errpipe[WRITE_END] >= 0) + close(errpipe[WRITE_END]); + return err; +} + +static int rename_netif(struct udev_event *event) +{ + struct udev_device *dev = event->dev; + int sk; + struct ifreq ifr; + int err; + + log_debug("changing net interface name from '%s' to '%s'\n", + udev_device_get_sysname(dev), event->name); + + sk = socket(PF_INET, SOCK_DGRAM, 0); + if (sk < 0) { + err = -errno; + log_error("error opening socket: %m\n"); + return err; + } + + memset(&ifr, 0x00, sizeof(struct ifreq)); + util_strscpy(ifr.ifr_name, IFNAMSIZ, udev_device_get_sysname(dev)); + util_strscpy(ifr.ifr_newname, IFNAMSIZ, event->name); + err = ioctl(sk, SIOCSIFNAME, &ifr); + if (err >= 0) { + print_kmsg("renamed network interface %s to %s\n", ifr.ifr_name, ifr.ifr_newname); + } else { + err = -errno; + log_error("error changing net interface name %s to %s: %m\n", ifr.ifr_name, ifr.ifr_newname); + } + close(sk); + return err; +} + +int udev_event_execute_rules(struct udev_event *event, struct udev_rules *rules, const sigset_t *sigmask) +{ + struct udev_device *dev = event->dev; + int err = 0; + + if (udev_device_get_subsystem(dev) == NULL) + return -1; + + if (strcmp(udev_device_get_action(dev), "remove") == 0) { + udev_device_read_db(dev, NULL); + udev_device_delete_db(dev); + udev_device_tag_index(dev, NULL, false); + + if (major(udev_device_get_devnum(dev)) != 0) + udev_watch_end(event->udev, dev); + + udev_rules_apply_to_event(rules, event, sigmask); + + if (major(udev_device_get_devnum(dev)) != 0) + udev_node_remove(dev); + } else { + event->dev_db = udev_device_new(event->udev); + if (event->dev_db != NULL) { + udev_device_set_syspath(event->dev_db, udev_device_get_syspath(dev)); + udev_device_set_subsystem(event->dev_db, udev_device_get_subsystem(dev)); + udev_device_read_db(event->dev_db, NULL); + udev_device_set_info_loaded(event->dev_db); + + /* disable watch during event processing */ + if (major(udev_device_get_devnum(dev)) != 0) + udev_watch_end(event->udev, event->dev_db); + } + + udev_rules_apply_to_event(rules, event, sigmask); + + /* rename a new network interface, if needed */ + if (udev_device_get_ifindex(dev) > 0 && strcmp(udev_device_get_action(dev), "add") == 0 && + event->name != NULL && strcmp(event->name, udev_device_get_sysname(dev)) != 0) { + char syspath[UTIL_PATH_SIZE]; + char *pos; + + err = rename_netif(event); + if (err == 0) { + log_debug("renamed netif to '%s'\n", event->name); + + /* remember old name */ + udev_device_add_property(dev, "INTERFACE_OLD", udev_device_get_sysname(dev)); + + /* now change the devpath, because the kernel device name has changed */ + util_strscpy(syspath, sizeof(syspath), udev_device_get_syspath(dev)); + pos = strrchr(syspath, '/'); + if (pos != NULL) { + pos++; + util_strscpy(pos, sizeof(syspath) - (pos - syspath), event->name); + udev_device_set_syspath(event->dev, syspath); + udev_device_add_property(dev, "INTERFACE", udev_device_get_sysname(dev)); + log_debug("changed devpath to '%s'\n", udev_device_get_devpath(dev)); + } + } + } + + if (major(udev_device_get_devnum(dev)) > 0) { + /* remove/update possible left-over symlinks from old database entry */ + if (event->dev_db != NULL) + udev_node_update_old_links(dev, event->dev_db); + + if (!event->owner_set) + event->uid = udev_device_get_devnode_uid(dev); + + if (!event->group_set) + event->gid = udev_device_get_devnode_gid(dev); + + if (!event->mode_set) { + if (udev_device_get_devnode_mode(dev) > 0) { + /* kernel supplied value */ + event->mode = udev_device_get_devnode_mode(dev); + } else if (event->gid > 0) { + /* default 0660 if a group is assigned */ + event->mode = 0660; + } else { + /* default 0600 */ + event->mode = 0600; + } + } + + udev_node_add(dev, event->mode, event->uid, event->gid); + } + + /* preserve old, or get new initialization timestamp */ + if (event->dev_db != NULL && udev_device_get_usec_initialized(event->dev_db) > 0) + udev_device_set_usec_initialized(event->dev, udev_device_get_usec_initialized(event->dev_db)); + else if (udev_device_get_usec_initialized(event->dev) == 0) + udev_device_set_usec_initialized(event->dev, now(CLOCK_MONOTONIC)); + + /* (re)write database file */ + udev_device_update_db(dev); + udev_device_tag_index(dev, event->dev_db, true); + udev_device_set_is_initialized(dev); + + udev_device_unref(event->dev_db); + event->dev_db = NULL; + } + return err; +} + +void udev_event_execute_run(struct udev_event *event, const sigset_t *sigmask) +{ + struct udev_list_entry *list_entry; + + udev_list_entry_foreach(list_entry, udev_list_get_entry(&event->run_list)) { + const char *cmd = udev_list_entry_get_name(list_entry); + enum udev_builtin_cmd builtin_cmd = udev_list_entry_get_num(list_entry); + + if (builtin_cmd < UDEV_BUILTIN_MAX) { + char command[UTIL_PATH_SIZE]; + + udev_event_apply_format(event, cmd, command, sizeof(command)); + udev_builtin_run(event->dev, builtin_cmd, command, false); + } else { + char program[UTIL_PATH_SIZE]; + char **envp; + + if (event->exec_delay > 0) { + log_debug("delay execution of '%s'\n", program); + sleep(event->exec_delay); + } + + udev_event_apply_format(event, cmd, program, sizeof(program)); + envp = udev_device_get_properties_envp(event->dev); + udev_event_spawn(event, program, envp, sigmask, NULL, 0); + } + } +} diff --git a/src/udev/udev-node.c b/src/udev/udev-node.c new file mode 100644 index 000000000..1e378adf2 --- /dev/null +++ b/src/udev/udev-node.c @@ -0,0 +1,343 @@ +/* + * Copyright (C) 2003-2010 Kay Sievers + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "udev.h" + +#define TMP_FILE_EXT ".udev-tmp" + +static int node_symlink(struct udev *udev, const char *node, const char *slink) +{ + struct stat stats; + char target[UTIL_PATH_SIZE]; + char *s; + size_t l; + char slink_tmp[UTIL_PATH_SIZE + sizeof(TMP_FILE_EXT)]; + int i = 0; + int tail = 0; + int err = 0; + + /* use relative link */ + target[0] = '\0'; + while (node[i] && (node[i] == slink[i])) { + if (node[i] == '/') + tail = i+1; + i++; + } + s = target; + l = sizeof(target); + while (slink[i] != '\0') { + if (slink[i] == '/') + l = util_strpcpy(&s, l, "../"); + i++; + } + l = util_strscpy(s, l, &node[tail]); + if (l == 0) { + err = -EINVAL; + goto exit; + } + + /* preserve link with correct target, do not replace node of other device */ + if (lstat(slink, &stats) == 0) { + if (S_ISBLK(stats.st_mode) || S_ISCHR(stats.st_mode)) { + log_error("conflicting device node '%s' found, link to '%s' will not be created\n", slink, node); + goto exit; + } else if (S_ISLNK(stats.st_mode)) { + char buf[UTIL_PATH_SIZE]; + int len; + + len = readlink(slink, buf, sizeof(buf)); + if (len > 0 && len < (int)sizeof(buf)) { + buf[len] = '\0'; + if (strcmp(target, buf) == 0) { + log_debug("preserve already existing symlink '%s' to '%s'\n", slink, target); + label_fix(slink, true, false); + utimensat(AT_FDCWD, slink, NULL, AT_SYMLINK_NOFOLLOW); + goto exit; + } + } + } + } else { + log_debug("creating symlink '%s' to '%s'\n", slink, target); + do { + err = mkdir_parents_label(slink, 0755); + if (err != 0 && err != -ENOENT) + break; + label_context_set(slink, S_IFLNK); + err = symlink(target, slink); + if (err != 0) + err = -errno; + label_context_clear(); + } while (err == -ENOENT); + if (err == 0) + goto exit; + } + + log_debug("atomically replace '%s'\n", slink); + util_strscpyl(slink_tmp, sizeof(slink_tmp), slink, TMP_FILE_EXT, NULL); + unlink(slink_tmp); + do { + err = mkdir_parents_label(slink_tmp, 0755); + if (err != 0 && err != -ENOENT) + break; + label_context_set(slink_tmp, S_IFLNK); + err = symlink(target, slink_tmp); + if (err != 0) + err = -errno; + label_context_clear(); + } while (err == -ENOENT); + if (err != 0) { + log_error("symlink '%s' '%s' failed: %m\n", target, slink_tmp); + goto exit; + } + err = rename(slink_tmp, slink); + if (err != 0) { + log_error("rename '%s' '%s' failed: %m\n", slink_tmp, slink); + unlink(slink_tmp); + } +exit: + return err; +} + +/* find device node of device with highest priority */ +static const char *link_find_prioritized(struct udev_device *dev, bool add, const char *stackdir, char *buf, size_t bufsize) +{ + struct udev *udev = udev_device_get_udev(dev); + DIR *dir; + int priority = 0; + const char *target = NULL; + + if (add) { + priority = udev_device_get_devlink_priority(dev); + util_strscpy(buf, bufsize, udev_device_get_devnode(dev)); + target = buf; + } + + dir = opendir(stackdir); + if (dir == NULL) + return target; + for (;;) { + struct udev_device *dev_db; + struct dirent *dent; + + dent = readdir(dir); + if (dent == NULL || dent->d_name[0] == '\0') + break; + if (dent->d_name[0] == '.') + continue; + + log_debug("found '%s' claiming '%s'\n", dent->d_name, stackdir); + + /* did we find ourself? */ + if (strcmp(dent->d_name, udev_device_get_id_filename(dev)) == 0) + continue; + + dev_db = udev_device_new_from_device_id(udev, dent->d_name); + if (dev_db != NULL) { + const char *devnode; + + devnode = udev_device_get_devnode(dev_db); + if (devnode != NULL) { + if (target == NULL || udev_device_get_devlink_priority(dev_db) > priority) { + log_debug("'%s' claims priority %i for '%s'\n", + udev_device_get_syspath(dev_db), udev_device_get_devlink_priority(dev_db), stackdir); + priority = udev_device_get_devlink_priority(dev_db); + util_strscpy(buf, bufsize, devnode); + target = buf; + } + } + udev_device_unref(dev_db); + } + } + closedir(dir); + return target; +} + +/* manage "stack of names" with possibly specified device priorities */ +static void link_update(struct udev_device *dev, const char *slink, bool add) +{ + struct udev *udev = udev_device_get_udev(dev); + char name_enc[UTIL_PATH_SIZE]; + char filename[UTIL_PATH_SIZE * 2]; + char dirname[UTIL_PATH_SIZE]; + const char *target; + char buf[UTIL_PATH_SIZE]; + + util_path_encode(slink + strlen("/dev"), name_enc, sizeof(name_enc)); + util_strscpyl(dirname, sizeof(dirname), "/run/udev/links/", name_enc, NULL); + util_strscpyl(filename, sizeof(filename), dirname, "/", udev_device_get_id_filename(dev), NULL); + + if (!add && unlink(filename) == 0) + rmdir(dirname); + + target = link_find_prioritized(dev, add, dirname, buf, sizeof(buf)); + if (target == NULL) { + log_debug("no reference left, remove '%s'\n", slink); + if (unlink(slink) == 0) + util_delete_path(udev, slink); + } else { + log_debug("creating link '%s' to '%s'\n", slink, target); + node_symlink(udev, target, slink); + } + + if (add) { + int err; + + do { + int fd; + + err = mkdir_parents(filename, 0755); + if (err != 0 && err != -ENOENT) + break; + fd = open(filename, O_WRONLY|O_CREAT|O_CLOEXEC|O_TRUNC|O_NOFOLLOW, 0444); + if (fd >= 0) + close(fd); + else + err = -errno; + } while (err == -ENOENT); + } +} + +void udev_node_update_old_links(struct udev_device *dev, struct udev_device *dev_old) +{ + struct udev_list_entry *list_entry; + + /* update possible left-over symlinks */ + udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(dev_old)) { + const char *name = udev_list_entry_get_name(list_entry); + struct udev_list_entry *list_entry_current; + int found; + + /* check if old link name still belongs to this device */ + found = 0; + udev_list_entry_foreach(list_entry_current, udev_device_get_devlinks_list_entry(dev)) { + const char *name_current = udev_list_entry_get_name(list_entry_current); + + if (strcmp(name, name_current) == 0) { + found = 1; + break; + } + } + if (found) + continue; + + log_debug("update old name, '%s' no longer belonging to '%s'\n", + name, udev_device_get_devpath(dev)); + link_update(dev, name, false); + } +} + +static int node_fixup(struct udev_device *dev, mode_t mode, uid_t uid, gid_t gid) +{ + const char *devnode = udev_device_get_devnode(dev); + dev_t devnum = udev_device_get_devnum(dev); + struct stat stats; + int err = 0; + + if (strcmp(udev_device_get_subsystem(dev), "block") == 0) + mode |= S_IFBLK; + else + mode |= S_IFCHR; + + if (lstat(devnode, &stats) != 0) { + err = -errno; + log_debug("can not stat() node '%s' (%m)\n", devnode); + goto out; + } + + if (((stats.st_mode & S_IFMT) != (mode & S_IFMT)) || (stats.st_rdev != devnum)) { + err = -EEXIST; + log_debug("found node '%s' with non-matching devnum %s, skip handling\n", + udev_device_get_devnode(dev), udev_device_get_id_filename(dev)); + goto out; + } + + /* + * Set permissions and selinux file context only on add events. We always + * set it on bootup (coldplug) with "trigger --action=add" for all devices + * and for any newly added devices (hotplug). We don't want to change it + * later, in case something else has applied custom settings in the meantime. + */ + if (strcmp(udev_device_get_action(dev), "add") == 0) { + if ((stats.st_mode & 0777) != (mode & 0777) || stats.st_uid != uid || stats.st_gid != gid) { + log_debug("set permissions %s, %#o, uid=%u, gid=%u\n", devnode, mode, uid, gid); + chmod(devnode, mode); + chown(devnode, uid, gid); + } else { + log_debug("preserve permissions %s, %#o, uid=%u, gid=%u\n", devnode, mode, uid, gid); + } + + label_fix(devnode, true, false); + } + + /* always update timestamp when we re-use the node, like on media change events */ + utimensat(AT_FDCWD, devnode, NULL, 0); +out: + return err; +} + +void udev_node_add(struct udev_device *dev, mode_t mode, uid_t uid, gid_t gid) +{ + struct udev *udev = udev_device_get_udev(dev); + char filename[UTIL_PATH_SIZE]; + struct udev_list_entry *list_entry; + + log_debug("handling device node '%s', devnum=%s, mode=%#o, uid=%d, gid=%d\n", + udev_device_get_devnode(dev), udev_device_get_id_filename(dev), mode, uid, gid); + + if (node_fixup(dev, mode, uid, gid) < 0) + return; + + /* always add /dev/{block,char}/$major:$minor */ + snprintf(filename, sizeof(filename), "/dev/%s/%u:%u", + strcmp(udev_device_get_subsystem(dev), "block") == 0 ? "block" : "char", + major(udev_device_get_devnum(dev)), minor(udev_device_get_devnum(dev))); + node_symlink(udev, udev_device_get_devnode(dev), filename); + + /* create/update symlinks, add symlinks to name index */ + udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(dev)) + link_update(dev, udev_list_entry_get_name(list_entry), true); +} + +void udev_node_remove(struct udev_device *dev) +{ + struct udev_list_entry *list_entry; + char filename[UTIL_PATH_SIZE]; + + /* remove/update symlinks, remove symlinks from name index */ + udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(dev)) + link_update(dev, udev_list_entry_get_name(list_entry), false); + + /* remove /dev/{block,char}/$major:$minor */ + snprintf(filename, sizeof(filename), "/dev/%s/%u:%u", + strcmp(udev_device_get_subsystem(dev), "block") == 0 ? "block" : "char", + major(udev_device_get_devnum(dev)), minor(udev_device_get_devnum(dev))); + unlink(filename); +} diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c new file mode 100644 index 000000000..9743243a3 --- /dev/null +++ b/src/udev/udev-rules.c @@ -0,0 +1,2577 @@ +/* + * Copyright (C) 2003-2012 Kay Sievers + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "udev.h" +#include "path-util.h" +#include "conf-files.h" +#include "strbuf.h" + +#define PREALLOC_TOKEN 2048 + +struct uid_gid { + unsigned int name_off; + union { + uid_t uid; + gid_t gid; + }; +}; + +struct udev_rules { + struct udev *udev; + char **dirs; + usec_t *dirs_ts_usec; + int resolve_names; + + /* every key in the rules file becomes a token */ + struct token *tokens; + unsigned int token_cur; + unsigned int token_max; + + /* all key strings are copied and de-duplicated in a single continous string buffer */ + struct strbuf *strbuf; + + /* during rule parsing, uid/gid lookup results are cached */ + struct uid_gid *uids; + unsigned int uids_cur; + unsigned int uids_max; + struct uid_gid *gids; + unsigned int gids_cur; + unsigned int gids_max; +}; + +static char *rules_str(struct udev_rules *rules, unsigned int off) { + return rules->strbuf->buf + off; +} + +static unsigned int rules_add_string(struct udev_rules *rules, const char *s) { + return strbuf_add_string(rules->strbuf, s, strlen(s)); +} + +/* KEY=="", KEY!="", KEY+="", KEY="", KEY:="" */ +enum operation_type { + OP_UNSET, + + OP_MATCH, + OP_NOMATCH, + OP_MATCH_MAX, + + OP_ADD, + OP_ASSIGN, + OP_ASSIGN_FINAL, +}; + +enum string_glob_type { + GL_UNSET, + GL_PLAIN, /* no special chars */ + GL_GLOB, /* shell globs ?,*,[] */ + GL_SPLIT, /* multi-value A|B */ + GL_SPLIT_GLOB, /* multi-value with glob A*|B* */ + GL_SOMETHING, /* commonly used "?*" */ +}; + +enum string_subst_type { + SB_UNSET, + SB_NONE, + SB_FORMAT, + SB_SUBSYS, +}; + +/* tokens of a rule are sorted/handled in this order */ +enum token_type { + TK_UNSET, + TK_RULE, + + TK_M_ACTION, /* val */ + TK_M_DEVPATH, /* val */ + TK_M_KERNEL, /* val */ + TK_M_DEVLINK, /* val */ + TK_M_NAME, /* val */ + TK_M_ENV, /* val, attr */ + TK_M_TAG, /* val */ + TK_M_SUBSYSTEM, /* val */ + TK_M_DRIVER, /* val */ + TK_M_WAITFOR, /* val */ + TK_M_ATTR, /* val, attr */ + + TK_M_PARENTS_MIN, + TK_M_KERNELS, /* val */ + TK_M_SUBSYSTEMS, /* val */ + TK_M_DRIVERS, /* val */ + TK_M_ATTRS, /* val, attr */ + TK_M_TAGS, /* val */ + TK_M_PARENTS_MAX, + + TK_M_TEST, /* val, mode_t */ + TK_M_EVENT_TIMEOUT, /* int */ + TK_M_PROGRAM, /* val */ + TK_M_IMPORT_FILE, /* val */ + TK_M_IMPORT_PROG, /* val */ + TK_M_IMPORT_BUILTIN, /* val */ + TK_M_IMPORT_DB, /* val */ + TK_M_IMPORT_CMDLINE, /* val */ + TK_M_IMPORT_PARENT, /* val */ + TK_M_RESULT, /* val */ + TK_M_MAX, + + TK_A_STRING_ESCAPE_NONE, + TK_A_STRING_ESCAPE_REPLACE, + TK_A_DB_PERSIST, + TK_A_INOTIFY_WATCH, /* int */ + TK_A_DEVLINK_PRIO, /* int */ + TK_A_OWNER, /* val */ + TK_A_GROUP, /* val */ + TK_A_MODE, /* val */ + TK_A_OWNER_ID, /* uid_t */ + TK_A_GROUP_ID, /* gid_t */ + TK_A_MODE_ID, /* mode_t */ + TK_A_STATIC_NODE, /* val */ + TK_A_ENV, /* val, attr */ + TK_A_TAG, /* val */ + TK_A_NAME, /* val */ + TK_A_DEVLINK, /* val */ + TK_A_ATTR, /* val, attr */ + TK_A_RUN_BUILTIN, /* val, bool */ + TK_A_RUN_PROGRAM, /* val, bool */ + TK_A_GOTO, /* size_t */ + + TK_END, +}; + +/* we try to pack stuff in a way that we take only 12 bytes per token */ +struct token { + union { + unsigned char type; /* same in rule and key */ + struct { + enum token_type type:8; + bool can_set_name:1; + bool has_static_node:1; + unsigned int unused:6; + unsigned short token_count; + unsigned int label_off; + unsigned short filename_off; + unsigned short filename_line; + } rule; + struct { + enum token_type type:8; + enum operation_type op:8; + enum string_glob_type glob:8; + enum string_subst_type subst:4; + enum string_subst_type attrsubst:4; + unsigned int value_off; + union { + unsigned int attr_off; + unsigned int rule_goto; + mode_t mode; + uid_t uid; + gid_t gid; + int devlink_prio; + int event_timeout; + int watch; + enum udev_builtin_cmd builtin_cmd; + }; + } key; + }; +}; + +#define MAX_TK 64 +struct rule_tmp { + struct udev_rules *rules; + struct token rule; + struct token token[MAX_TK]; + unsigned int token_cur; +}; + +#ifdef DEBUG +static const char *operation_str(enum operation_type type) +{ + static const char *operation_strs[] = { + [OP_UNSET] = "UNSET", + [OP_MATCH] = "match", + [OP_NOMATCH] = "nomatch", + [OP_MATCH_MAX] = "MATCH_MAX", + + [OP_ADD] = "add", + [OP_ASSIGN] = "assign", + [OP_ASSIGN_FINAL] = "assign-final", +} ; + + return operation_strs[type]; +} + +static const char *string_glob_str(enum string_glob_type type) +{ + static const char *string_glob_strs[] = { + [GL_UNSET] = "UNSET", + [GL_PLAIN] = "plain", + [GL_GLOB] = "glob", + [GL_SPLIT] = "split", + [GL_SPLIT_GLOB] = "split-glob", + [GL_SOMETHING] = "split-glob", + }; + + return string_glob_strs[type]; +} + +static const char *token_str(enum token_type type) +{ + static const char *token_strs[] = { + [TK_UNSET] = "UNSET", + [TK_RULE] = "RULE", + + [TK_M_ACTION] = "M ACTION", + [TK_M_DEVPATH] = "M DEVPATH", + [TK_M_KERNEL] = "M KERNEL", + [TK_M_DEVLINK] = "M DEVLINK", + [TK_M_NAME] = "M NAME", + [TK_M_ENV] = "M ENV", + [TK_M_TAG] = "M TAG", + [TK_M_SUBSYSTEM] = "M SUBSYSTEM", + [TK_M_DRIVER] = "M DRIVER", + [TK_M_WAITFOR] = "M WAITFOR", + [TK_M_ATTR] = "M ATTR", + + [TK_M_PARENTS_MIN] = "M PARENTS_MIN", + [TK_M_KERNELS] = "M KERNELS", + [TK_M_SUBSYSTEMS] = "M SUBSYSTEMS", + [TK_M_DRIVERS] = "M DRIVERS", + [TK_M_ATTRS] = "M ATTRS", + [TK_M_TAGS] = "M TAGS", + [TK_M_PARENTS_MAX] = "M PARENTS_MAX", + + [TK_M_TEST] = "M TEST", + [TK_M_EVENT_TIMEOUT] = "M EVENT_TIMEOUT", + [TK_M_PROGRAM] = "M PROGRAM", + [TK_M_IMPORT_FILE] = "M IMPORT_FILE", + [TK_M_IMPORT_PROG] = "M IMPORT_PROG", + [TK_M_IMPORT_BUILTIN] = "M IMPORT_BUILTIN", + [TK_M_IMPORT_DB] = "M IMPORT_DB", + [TK_M_IMPORT_CMDLINE] = "M IMPORT_CMDLINE", + [TK_M_IMPORT_PARENT] = "M IMPORT_PARENT", + [TK_M_RESULT] = "M RESULT", + [TK_M_MAX] = "M MAX", + + [TK_A_STRING_ESCAPE_NONE] = "A STRING_ESCAPE_NONE", + [TK_A_STRING_ESCAPE_REPLACE] = "A STRING_ESCAPE_REPLACE", + [TK_A_DB_PERSIST] = "A DB_PERSIST", + [TK_A_INOTIFY_WATCH] = "A INOTIFY_WATCH", + [TK_A_DEVLINK_PRIO] = "A DEVLINK_PRIO", + [TK_A_OWNER] = "A OWNER", + [TK_A_GROUP] = "A GROUP", + [TK_A_MODE] = "A MODE", + [TK_A_OWNER_ID] = "A OWNER_ID", + [TK_A_GROUP_ID] = "A GROUP_ID", + [TK_A_STATIC_NODE] = "A STATIC_NODE", + [TK_A_MODE_ID] = "A MODE_ID", + [TK_A_ENV] = "A ENV", + [TK_A_TAG] = "A ENV", + [TK_A_NAME] = "A NAME", + [TK_A_DEVLINK] = "A DEVLINK", + [TK_A_ATTR] = "A ATTR", + [TK_A_RUN_BUILTIN] = "A RUN_BUILTIN", + [TK_A_RUN_PROGRAM] = "A RUN_PROGRAM", + [TK_A_GOTO] = "A GOTO", + + [TK_END] = "END", + }; + + return token_strs[type]; +} + +static void dump_token(struct udev_rules *rules, struct token *token) +{ + enum token_type type = token->type; + enum operation_type op = token->key.op; + enum string_glob_type glob = token->key.glob; + const char *value = str(rules, token->key.value_off); + const char *attr = &rules->buf[token->key.attr_off]; + + switch (type) { + case TK_RULE: + { + const char *tks_ptr = (char *)rules->tokens; + const char *tk_ptr = (char *)token; + unsigned int idx = (tk_ptr - tks_ptr) / sizeof(struct token); + + log_debug("* RULE %s:%u, token: %u, count: %u, label: '%s'\n", + &rules->buf[token->rule.filename_off], token->rule.filename_line, + idx, token->rule.token_count, + &rules->buf[token->rule.label_off]); + break; + } + case TK_M_ACTION: + case TK_M_DEVPATH: + case TK_M_KERNEL: + case TK_M_SUBSYSTEM: + case TK_M_DRIVER: + case TK_M_WAITFOR: + case TK_M_DEVLINK: + case TK_M_NAME: + case TK_M_KERNELS: + case TK_M_SUBSYSTEMS: + case TK_M_DRIVERS: + case TK_M_TAGS: + case TK_M_PROGRAM: + case TK_M_IMPORT_FILE: + case TK_M_IMPORT_PROG: + case TK_M_IMPORT_DB: + case TK_M_IMPORT_CMDLINE: + case TK_M_IMPORT_PARENT: + case TK_M_RESULT: + case TK_A_NAME: + case TK_A_DEVLINK: + case TK_A_OWNER: + case TK_A_GROUP: + case TK_A_MODE: + case TK_A_RUN_BUILTIN: + case TK_A_RUN_PROGRAM: + log_debug("%s %s '%s'(%s)\n", + token_str(type), operation_str(op), value, string_glob_str(glob)); + break; + case TK_M_IMPORT_BUILTIN: + log_debug("%s %i '%s'\n", token_str(type), token->key.builtin_cmd, value); + break; + case TK_M_ATTR: + case TK_M_ATTRS: + case TK_M_ENV: + case TK_A_ATTR: + case TK_A_ENV: + log_debug("%s %s '%s' '%s'(%s)\n", + token_str(type), operation_str(op), attr, value, string_glob_str(glob)); + break; + case TK_M_TAG: + case TK_A_TAG: + log_debug("%s %s '%s'\n", token_str(type), operation_str(op), value); + break; + case TK_A_STRING_ESCAPE_NONE: + case TK_A_STRING_ESCAPE_REPLACE: + case TK_A_DB_PERSIST: + log_debug("%s\n", token_str(type)); + break; + case TK_M_TEST: + log_debug("%s %s '%s'(%s) %#o\n", + token_str(type), operation_str(op), value, string_glob_str(glob), token->key.mode); + break; + case TK_A_INOTIFY_WATCH: + log_debug("%s %u\n", token_str(type), token->key.watch); + break; + case TK_A_DEVLINK_PRIO: + log_debug("%s %u\n", token_str(type), token->key.devlink_prio); + break; + case TK_A_OWNER_ID: + log_debug("%s %s %u\n", token_str(type), operation_str(op), token->key.uid); + break; + case TK_A_GROUP_ID: + log_debug("%s %s %u\n", token_str(type), operation_str(op), token->key.gid); + break; + case TK_A_MODE_ID: + log_debug("%s %s %#o\n", token_str(type), operation_str(op), token->key.mode); + break; + case TK_A_STATIC_NODE: + log_debug("%s '%s'\n", token_str(type), value); + break; + case TK_M_EVENT_TIMEOUT: + log_debug("%s %u\n", token_str(type), token->key.event_timeout); + break; + case TK_A_GOTO: + log_debug("%s '%s' %u\n", token_str(type), value, token->key.rule_goto); + break; + case TK_END: + log_debug("* %s\n", token_str(type)); + break; + case TK_M_PARENTS_MIN: + case TK_M_PARENTS_MAX: + case TK_M_MAX: + case TK_UNSET: + log_debug("unknown type %u\n", type); + break; + } +} + +static void dump_rules(struct udev_rules *rules) +{ + unsigned int i; + + log_debug("dumping %u (%zu bytes) tokens, %u (%zu bytes) strings\n", + rules->token_cur, + rules->token_cur * sizeof(struct token), + rules->buf_count, + rules->buf_cur); + for(i = 0; i < rules->token_cur; i++) + dump_token(rules, &rules->tokens[i]); +} +#else +static inline const char *operation_str(enum operation_type type) { return NULL; } +static inline const char *token_str(enum token_type type) { return NULL; } +static inline void dump_token(struct udev_rules *rules, struct token *token) {} +static inline void dump_rules(struct udev_rules *rules) {} +#endif /* DEBUG */ + +static int add_token(struct udev_rules *rules, struct token *token) +{ + /* grow buffer if needed */ + if (rules->token_cur+1 >= rules->token_max) { + struct token *tokens; + unsigned int add; + + /* double the buffer size */ + add = rules->token_max; + if (add < 8) + add = 8; + + tokens = realloc(rules->tokens, (rules->token_max + add ) * sizeof(struct token)); + if (tokens == NULL) + return -1; + rules->tokens = tokens; + rules->token_max += add; + } + memcpy(&rules->tokens[rules->token_cur], token, sizeof(struct token)); + rules->token_cur++; + return 0; +} + +static uid_t add_uid(struct udev_rules *rules, const char *owner) +{ + unsigned int i; + uid_t uid; + unsigned int off; + + /* lookup, if we know it already */ + for (i = 0; i < rules->uids_cur; i++) { + off = rules->uids[i].name_off; + if (streq(rules_str(rules, off), owner)) { + uid = rules->uids[i].uid; + return uid; + } + } + uid = util_lookup_user(rules->udev, owner); + + /* grow buffer if needed */ + if (rules->uids_cur+1 >= rules->uids_max) { + struct uid_gid *uids; + unsigned int add; + + /* double the buffer size */ + add = rules->uids_max; + if (add < 1) + add = 8; + + uids = realloc(rules->uids, (rules->uids_max + add ) * sizeof(struct uid_gid)); + if (uids == NULL) + return uid; + rules->uids = uids; + rules->uids_max += add; + } + rules->uids[rules->uids_cur].uid = uid; + off = rules_add_string(rules, owner); + if (off <= 0) + return uid; + rules->uids[rules->uids_cur].name_off = off; + rules->uids_cur++; + return uid; +} + +static gid_t add_gid(struct udev_rules *rules, const char *group) +{ + unsigned int i; + gid_t gid; + unsigned int off; + + /* lookup, if we know it already */ + for (i = 0; i < rules->gids_cur; i++) { + off = rules->gids[i].name_off; + if (streq(rules_str(rules, off), group)) { + gid = rules->gids[i].gid; + return gid; + } + } + gid = util_lookup_group(rules->udev, group); + + /* grow buffer if needed */ + if (rules->gids_cur+1 >= rules->gids_max) { + struct uid_gid *gids; + unsigned int add; + + /* double the buffer size */ + add = rules->gids_max; + if (add < 1) + add = 8; + + gids = realloc(rules->gids, (rules->gids_max + add ) * sizeof(struct uid_gid)); + if (gids == NULL) + return gid; + rules->gids = gids; + rules->gids_max += add; + } + rules->gids[rules->gids_cur].gid = gid; + off = rules_add_string(rules, group); + if (off <= 0) + return gid; + rules->gids[rules->gids_cur].name_off = off; + rules->gids_cur++; + return gid; +} + +static int import_property_from_string(struct udev_device *dev, char *line) +{ + char *key; + char *val; + size_t len; + + /* find key */ + key = line; + while (isspace(key[0])) + key++; + + /* comment or empty line */ + if (key[0] == '#' || key[0] == '\0') + return -1; + + /* split key/value */ + val = strchr(key, '='); + if (val == NULL) + return -1; + val[0] = '\0'; + val++; + + /* find value */ + while (isspace(val[0])) + val++; + + /* terminate key */ + len = strlen(key); + if (len == 0) + return -1; + while (isspace(key[len-1])) + len--; + key[len] = '\0'; + + /* terminate value */ + len = strlen(val); + if (len == 0) + return -1; + while (isspace(val[len-1])) + len--; + val[len] = '\0'; + + if (len == 0) + return -1; + + /* unquote */ + if (val[0] == '"' || val[0] == '\'') { + if (val[len-1] != val[0]) { + log_debug("inconsistent quoting: '%s', skip\n", line); + return -1; + } + val[len-1] = '\0'; + val++; + } + + /* handle device, renamed by external tool, returning new path */ + if (streq(key, "DEVPATH")) { + char syspath[UTIL_PATH_SIZE]; + + log_debug("updating devpath from '%s' to '%s'\n", + udev_device_get_devpath(dev), val); + util_strscpyl(syspath, sizeof(syspath), "/sys", val, NULL); + udev_device_set_syspath(dev, syspath); + } else { + struct udev_list_entry *entry; + + entry = udev_device_add_property(dev, key, val); + /* store in db, skip private keys */ + if (key[0] != '.') + udev_list_entry_set_num(entry, true); + } + return 0; +} + +static int import_file_into_properties(struct udev_device *dev, const char *filename) +{ + FILE *f; + char line[UTIL_LINE_SIZE]; + + f = fopen(filename, "re"); + if (f == NULL) + return -1; + while (fgets(line, sizeof(line), f) != NULL) + import_property_from_string(dev, line); + fclose(f); + return 0; +} + +static int import_program_into_properties(struct udev_event *event, const char *program, const sigset_t *sigmask) +{ + struct udev_device *dev = event->dev; + char **envp; + char result[UTIL_LINE_SIZE]; + char *line; + int err; + + envp = udev_device_get_properties_envp(dev); + err = udev_event_spawn(event, program, envp, sigmask, result, sizeof(result)); + if (err < 0) + return err; + + line = result; + while (line != NULL) { + char *pos; + + pos = strchr(line, '\n'); + if (pos != NULL) { + pos[0] = '\0'; + pos = &pos[1]; + } + import_property_from_string(dev, line); + line = pos; + } + return 0; +} + +static int import_parent_into_properties(struct udev_device *dev, const char *filter) +{ + struct udev_device *dev_parent; + struct udev_list_entry *list_entry; + + dev_parent = udev_device_get_parent(dev); + if (dev_parent == NULL) + return -1; + + udev_list_entry_foreach(list_entry, udev_device_get_properties_list_entry(dev_parent)) { + const char *key = udev_list_entry_get_name(list_entry); + const char *val = udev_list_entry_get_value(list_entry); + + if (fnmatch(filter, key, 0) == 0) { + struct udev_list_entry *entry; + + entry = udev_device_add_property(dev, key, val); + /* store in db, skip private keys */ + if (key[0] != '.') + udev_list_entry_set_num(entry, true); + } + } + return 0; +} + +#define WAIT_LOOP_PER_SECOND 50 +static int wait_for_file(struct udev_device *dev, const char *file, int timeout) +{ + char filepath[UTIL_PATH_SIZE]; + char devicepath[UTIL_PATH_SIZE]; + struct stat stats; + int loop = timeout * WAIT_LOOP_PER_SECOND; + + /* a relative path is a device attribute */ + devicepath[0] = '\0'; + if (file[0] != '/') { + util_strscpyl(devicepath, sizeof(devicepath), udev_device_get_syspath(dev), NULL); + util_strscpyl(filepath, sizeof(filepath), devicepath, "/", file, NULL); + file = filepath; + } + + while (--loop) { + const struct timespec duration = { 0, 1000 * 1000 * 1000 / WAIT_LOOP_PER_SECOND }; + + /* lookup file */ + if (stat(file, &stats) == 0) { + log_debug("file '%s' appeared after %i loops\n", file, (timeout * WAIT_LOOP_PER_SECOND) - loop-1); + return 0; + } + /* make sure, the device did not disappear in the meantime */ + if (devicepath[0] != '\0' && stat(devicepath, &stats) != 0) { + log_debug("device disappeared while waiting for '%s'\n", file); + return -2; + } + log_debug("wait for '%s' for %i mseconds\n", file, 1000 / WAIT_LOOP_PER_SECOND); + nanosleep(&duration, NULL); + } + log_debug("waiting for '%s' failed\n", file); + return -1; +} + +static int attr_subst_subdir(char *attr, size_t len) +{ + bool found = false; + + if (strstr(attr, "/*/")) { + char *pos; + char dirname[UTIL_PATH_SIZE]; + const char *tail; + DIR *dir; + + util_strscpy(dirname, sizeof(dirname), attr); + pos = strstr(dirname, "/*/"); + if (pos == NULL) + return -1; + pos[0] = '\0'; + tail = &pos[2]; + dir = opendir(dirname); + if (dir != NULL) { + struct dirent *dent; + + for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) { + struct stat stats; + + if (dent->d_name[0] == '.') + continue; + util_strscpyl(attr, len, dirname, "/", dent->d_name, tail, NULL); + if (stat(attr, &stats) == 0) { + found = true; + break; + } + } + closedir(dir); + } + } + + return found; +} + +static int get_key(struct udev *udev, char **line, char **key, enum operation_type *op, char **value) +{ + char *linepos; + char *temp; + + linepos = *line; + if (linepos == NULL || linepos[0] == '\0') + return -1; + + /* skip whitespace */ + while (isspace(linepos[0]) || linepos[0] == ',') + linepos++; + + /* get the key */ + if (linepos[0] == '\0') + return -1; + *key = linepos; + + for (;;) { + linepos++; + if (linepos[0] == '\0') + return -1; + if (isspace(linepos[0])) + break; + if (linepos[0] == '=') + break; + if ((linepos[0] == '+') || (linepos[0] == '!') || (linepos[0] == ':')) + if (linepos[1] == '=') + break; + } + + /* remember end of key */ + temp = linepos; + + /* skip whitespace after key */ + while (isspace(linepos[0])) + linepos++; + if (linepos[0] == '\0') + return -1; + + /* get operation type */ + if (linepos[0] == '=' && linepos[1] == '=') { + *op = OP_MATCH; + linepos += 2; + } else if (linepos[0] == '!' && linepos[1] == '=') { + *op = OP_NOMATCH; + linepos += 2; + } else if (linepos[0] == '+' && linepos[1] == '=') { + *op = OP_ADD; + linepos += 2; + } else if (linepos[0] == '=') { + *op = OP_ASSIGN; + linepos++; + } else if (linepos[0] == ':' && linepos[1] == '=') { + *op = OP_ASSIGN_FINAL; + linepos += 2; + } else + return -1; + + /* terminate key */ + temp[0] = '\0'; + + /* skip whitespace after operator */ + while (isspace(linepos[0])) + linepos++; + if (linepos[0] == '\0') + return -1; + + /* get the value */ + if (linepos[0] == '"') + linepos++; + else + return -1; + *value = linepos; + + /* terminate */ + temp = strchr(linepos, '"'); + if (!temp) + return -1; + temp[0] = '\0'; + temp++; + + /* move line to next key */ + *line = temp; + return 0; +} + +/* extract possible KEY{attr} */ +static const char *get_key_attribute(struct udev *udev, char *str) +{ + char *pos; + char *attr; + + attr = strchr(str, '{'); + if (attr != NULL) { + attr++; + pos = strchr(attr, '}'); + if (pos == NULL) { + log_error("missing closing brace for format\n"); + return NULL; + } + pos[0] = '\0'; + return attr; + } + return NULL; +} + +static int rule_add_key(struct rule_tmp *rule_tmp, enum token_type type, + enum operation_type op, + const char *value, const void *data) +{ + struct token *token = &rule_tmp->token[rule_tmp->token_cur]; + const char *attr = NULL; + + memset(token, 0x00, sizeof(struct token)); + + switch (type) { + case TK_M_ACTION: + case TK_M_DEVPATH: + case TK_M_KERNEL: + case TK_M_SUBSYSTEM: + case TK_M_DRIVER: + case TK_M_WAITFOR: + case TK_M_DEVLINK: + case TK_M_NAME: + case TK_M_KERNELS: + case TK_M_SUBSYSTEMS: + case TK_M_DRIVERS: + case TK_M_TAGS: + case TK_M_PROGRAM: + case TK_M_IMPORT_FILE: + case TK_M_IMPORT_PROG: + case TK_M_IMPORT_DB: + case TK_M_IMPORT_CMDLINE: + case TK_M_IMPORT_PARENT: + case TK_M_RESULT: + case TK_A_OWNER: + case TK_A_GROUP: + case TK_A_MODE: + case TK_A_DEVLINK: + case TK_A_NAME: + case TK_A_GOTO: + case TK_M_TAG: + case TK_A_TAG: + token->key.value_off = rules_add_string(rule_tmp->rules, value); + break; + case TK_M_IMPORT_BUILTIN: + token->key.value_off = rules_add_string(rule_tmp->rules, value); + token->key.builtin_cmd = *(enum udev_builtin_cmd *)data; + break; + case TK_M_ENV: + case TK_M_ATTR: + case TK_M_ATTRS: + case TK_A_ATTR: + case TK_A_ENV: + attr = data; + token->key.value_off = rules_add_string(rule_tmp->rules, value); + token->key.attr_off = rules_add_string(rule_tmp->rules, attr); + break; + case TK_M_TEST: + token->key.value_off = rules_add_string(rule_tmp->rules, value); + if (data != NULL) + token->key.mode = *(mode_t *)data; + break; + case TK_A_STRING_ESCAPE_NONE: + case TK_A_STRING_ESCAPE_REPLACE: + case TK_A_DB_PERSIST: + break; + case TK_A_RUN_BUILTIN: + case TK_A_RUN_PROGRAM: + token->key.builtin_cmd = *(enum udev_builtin_cmd *)data; + token->key.value_off = rules_add_string(rule_tmp->rules, value); + break; + case TK_A_INOTIFY_WATCH: + case TK_A_DEVLINK_PRIO: + token->key.devlink_prio = *(int *)data; + break; + case TK_A_OWNER_ID: + token->key.uid = *(uid_t *)data; + break; + case TK_A_GROUP_ID: + token->key.gid = *(gid_t *)data; + break; + case TK_A_MODE_ID: + token->key.mode = *(mode_t *)data; + break; + case TK_A_STATIC_NODE: + token->key.value_off = rules_add_string(rule_tmp->rules, value); + break; + case TK_M_EVENT_TIMEOUT: + token->key.event_timeout = *(int *)data; + break; + case TK_RULE: + case TK_M_PARENTS_MIN: + case TK_M_PARENTS_MAX: + case TK_M_MAX: + case TK_END: + case TK_UNSET: + log_error("wrong type %u\n", type); + return -1; + } + + if (value != NULL && type < TK_M_MAX) { + /* check if we need to split or call fnmatch() while matching rules */ + enum string_glob_type glob; + int has_split; + int has_glob; + + has_split = (strchr(value, '|') != NULL); + has_glob = (strchr(value, '*') != NULL || strchr(value, '?') != NULL || strchr(value, '[') != NULL); + if (has_split && has_glob) { + glob = GL_SPLIT_GLOB; + } else if (has_split) { + glob = GL_SPLIT; + } else if (has_glob) { + if (streq(value, "?*")) + glob = GL_SOMETHING; + else + glob = GL_GLOB; + } else { + glob = GL_PLAIN; + } + token->key.glob = glob; + } + + if (value != NULL && type > TK_M_MAX) { + /* check if assigned value has substitution chars */ + if (value[0] == '[') + token->key.subst = SB_SUBSYS; + else if (strchr(value, '%') != NULL || strchr(value, '$') != NULL) + token->key.subst = SB_FORMAT; + else + token->key.subst = SB_NONE; + } + + if (attr != NULL) { + /* check if property/attribut name has substitution chars */ + if (attr[0] == '[') + token->key.attrsubst = SB_SUBSYS; + else if (strchr(attr, '%') != NULL || strchr(attr, '$') != NULL) + token->key.attrsubst = SB_FORMAT; + else + token->key.attrsubst = SB_NONE; + } + + token->key.type = type; + token->key.op = op; + rule_tmp->token_cur++; + if (rule_tmp->token_cur >= ELEMENTSOF(rule_tmp->token)) { + log_error("temporary rule array too small\n"); + return -1; + } + return 0; +} + +static int sort_token(struct udev_rules *rules, struct rule_tmp *rule_tmp) +{ + unsigned int i; + unsigned int start = 0; + unsigned int end = rule_tmp->token_cur; + + for (i = 0; i < rule_tmp->token_cur; i++) { + enum token_type next_val = TK_UNSET; + unsigned int next_idx = 0; + unsigned int j; + + /* find smallest value */ + for (j = start; j < end; j++) { + if (rule_tmp->token[j].type == TK_UNSET) + continue; + if (next_val == TK_UNSET || rule_tmp->token[j].type < next_val) { + next_val = rule_tmp->token[j].type; + next_idx = j; + } + } + + /* add token and mark done */ + if (add_token(rules, &rule_tmp->token[next_idx]) != 0) + return -1; + rule_tmp->token[next_idx].type = TK_UNSET; + + /* shrink range */ + if (next_idx == start) + start++; + if (next_idx+1 == end) + end--; + } + return 0; +} + +static int add_rule(struct udev_rules *rules, char *line, + const char *filename, unsigned int filename_off, unsigned int lineno) +{ + char *linepos; + const char *attr; + struct rule_tmp rule_tmp; + + memset(&rule_tmp, 0x00, sizeof(struct rule_tmp)); + rule_tmp.rules = rules; + rule_tmp.rule.type = TK_RULE; + /* the offset in the rule is limited to unsigned short */ + if (filename_off < USHRT_MAX) + rule_tmp.rule.rule.filename_off = filename_off; + rule_tmp.rule.rule.filename_line = lineno; + + linepos = line; + for (;;) { + char *key; + char *value; + enum operation_type op; + + if (get_key(rules->udev, &linepos, &key, &op, &value) != 0) + break; + + if (streq(key, "ACTION")) { + if (op > OP_MATCH_MAX) { + log_error("invalid ACTION operation\n"); + goto invalid; + } + rule_add_key(&rule_tmp, TK_M_ACTION, op, value, NULL); + continue; + } + + if (streq(key, "DEVPATH")) { + if (op > OP_MATCH_MAX) { + log_error("invalid DEVPATH operation\n"); + goto invalid; + } + rule_add_key(&rule_tmp, TK_M_DEVPATH, op, value, NULL); + continue; + } + + if (streq(key, "KERNEL")) { + if (op > OP_MATCH_MAX) { + log_error("invalid KERNEL operation\n"); + goto invalid; + } + rule_add_key(&rule_tmp, TK_M_KERNEL, op, value, NULL); + continue; + } + + if (streq(key, "SUBSYSTEM")) { + if (op > OP_MATCH_MAX) { + log_error("invalid SUBSYSTEM operation\n"); + goto invalid; + } + /* bus, class, subsystem events should all be the same */ + if (streq(value, "subsystem") || + streq(value, "bus") || + streq(value, "class")) { + if (streq(value, "bus") || streq(value, "class")) + log_error("'%s' must be specified as 'subsystem' \n" + "please fix it in %s:%u", value, filename, lineno); + rule_add_key(&rule_tmp, TK_M_SUBSYSTEM, op, "subsystem|class|bus", NULL); + } else + rule_add_key(&rule_tmp, TK_M_SUBSYSTEM, op, value, NULL); + continue; + } + + if (streq(key, "DRIVER")) { + if (op > OP_MATCH_MAX) { + log_error("invalid DRIVER operation\n"); + goto invalid; + } + rule_add_key(&rule_tmp, TK_M_DRIVER, op, value, NULL); + continue; + } + + if (startswith(key, "ATTR{")) { + attr = get_key_attribute(rules->udev, key + sizeof("ATTR")-1); + if (attr == NULL) { + log_error("error parsing ATTR attribute\n"); + goto invalid; + } + if (op < OP_MATCH_MAX) { + rule_add_key(&rule_tmp, TK_M_ATTR, op, value, attr); + } else { + rule_add_key(&rule_tmp, TK_A_ATTR, op, value, attr); + } + continue; + } + + if (streq(key, "KERNELS")) { + if (op > OP_MATCH_MAX) { + log_error("invalid KERNELS operation\n"); + goto invalid; + } + rule_add_key(&rule_tmp, TK_M_KERNELS, op, value, NULL); + continue; + } + + if (streq(key, "SUBSYSTEMS")) { + if (op > OP_MATCH_MAX) { + log_error("invalid SUBSYSTEMS operation\n"); + goto invalid; + } + rule_add_key(&rule_tmp, TK_M_SUBSYSTEMS, op, value, NULL); + continue; + } + + if (streq(key, "DRIVERS")) { + if (op > OP_MATCH_MAX) { + log_error("invalid DRIVERS operation\n"); + goto invalid; + } + rule_add_key(&rule_tmp, TK_M_DRIVERS, op, value, NULL); + continue; + } + + if (startswith(key, "ATTRS{")) { + if (op > OP_MATCH_MAX) { + log_error("invalid ATTRS operation\n"); + goto invalid; + } + attr = get_key_attribute(rules->udev, key + sizeof("ATTRS")-1); + if (attr == NULL) { + log_error("error parsing ATTRS attribute\n"); + goto invalid; + } + if (startswith(attr, "device/")) + log_error("the 'device' link may not be available in a future kernel, " + "please fix it in %s:%u", filename, lineno); + else if (strstr(attr, "../") != NULL) + log_error("do not reference parent sysfs directories directly, " + "it may break with a future kernel, please fix it in %s:%u", filename, lineno); + rule_add_key(&rule_tmp, TK_M_ATTRS, op, value, attr); + continue; + } + + if (streq(key, "TAGS")) { + if (op > OP_MATCH_MAX) { + log_error("invalid TAGS operation\n"); + goto invalid; + } + rule_add_key(&rule_tmp, TK_M_TAGS, op, value, NULL); + continue; + } + + if (startswith(key, "ENV{")) { + attr = get_key_attribute(rules->udev, key + sizeof("ENV")-1); + if (attr == NULL) { + log_error("error parsing ENV attribute\n"); + goto invalid; + } + if (op < OP_MATCH_MAX) { + if (rule_add_key(&rule_tmp, TK_M_ENV, op, value, attr) != 0) + goto invalid; + } else { + static const char *blacklist[] = { + "ACTION", + "SUBSYSTEM", + "DEVTYPE", + "MAJOR", + "MINOR", + "DRIVER", + "IFINDEX", + "DEVNAME", + "DEVLINKS", + "DEVPATH", + "TAGS", + }; + unsigned int i; + + for (i = 0; i < ELEMENTSOF(blacklist); i++) { + if (!streq(attr, blacklist[i])) + continue; + log_error("invalid ENV attribute, '%s' can not be set %s:%u\n", attr, filename, lineno); + goto invalid; + } + if (rule_add_key(&rule_tmp, TK_A_ENV, op, value, attr) != 0) + goto invalid; + } + continue; + } + + if (streq(key, "TAG")) { + if (op < OP_MATCH_MAX) + rule_add_key(&rule_tmp, TK_M_TAG, op, value, NULL); + else + rule_add_key(&rule_tmp, TK_A_TAG, op, value, NULL); + continue; + } + + if (streq(key, "PROGRAM")) { + rule_add_key(&rule_tmp, TK_M_PROGRAM, op, value, NULL); + continue; + } + + if (streq(key, "RESULT")) { + if (op > OP_MATCH_MAX) { + log_error("invalid RESULT operation\n"); + goto invalid; + } + rule_add_key(&rule_tmp, TK_M_RESULT, op, value, NULL); + continue; + } + + if (startswith(key, "IMPORT")) { + attr = get_key_attribute(rules->udev, key + sizeof("IMPORT")-1); + if (attr == NULL) { + log_error("IMPORT{} type missing, ignoring IMPORT %s:%u\n", filename, lineno); + continue; + } + if (streq(attr, "program")) { + /* find known built-in command */ + if (value[0] != '/') { + enum udev_builtin_cmd cmd; + + cmd = udev_builtin_lookup(value); + if (cmd < UDEV_BUILTIN_MAX) { + log_debug("IMPORT found builtin '%s', replacing %s:%u\n", + value, filename, lineno); + rule_add_key(&rule_tmp, TK_M_IMPORT_BUILTIN, op, value, &cmd); + continue; + } + } + rule_add_key(&rule_tmp, TK_M_IMPORT_PROG, op, value, NULL); + } else if (streq(attr, "builtin")) { + enum udev_builtin_cmd cmd = udev_builtin_lookup(value); + + if (cmd < UDEV_BUILTIN_MAX) + rule_add_key(&rule_tmp, TK_M_IMPORT_BUILTIN, op, value, &cmd); + else + log_error("IMPORT{builtin}: '%s' unknown %s:%u\n", value, filename, lineno); + } else if (streq(attr, "file")) { + rule_add_key(&rule_tmp, TK_M_IMPORT_FILE, op, value, NULL); + } else if (streq(attr, "db")) { + rule_add_key(&rule_tmp, TK_M_IMPORT_DB, op, value, NULL); + } else if (streq(attr, "cmdline")) { + rule_add_key(&rule_tmp, TK_M_IMPORT_CMDLINE, op, value, NULL); + } else if (streq(attr, "parent")) { + rule_add_key(&rule_tmp, TK_M_IMPORT_PARENT, op, value, NULL); + } else + log_error("IMPORT{} unknown type, ignoring IMPORT %s:%u\n", filename, lineno); + continue; + } + + if (startswith(key, "TEST")) { + mode_t mode = 0; + + if (op > OP_MATCH_MAX) { + log_error("invalid TEST operation\n"); + goto invalid; + } + attr = get_key_attribute(rules->udev, key + sizeof("TEST")-1); + if (attr != NULL) { + mode = strtol(attr, NULL, 8); + rule_add_key(&rule_tmp, TK_M_TEST, op, value, &mode); + } else { + rule_add_key(&rule_tmp, TK_M_TEST, op, value, NULL); + } + continue; + } + + if (startswith(key, "RUN")) { + attr = get_key_attribute(rules->udev, key + sizeof("RUN")-1); + if (attr == NULL) + attr = "program"; + + if (streq(attr, "builtin")) { + enum udev_builtin_cmd cmd = udev_builtin_lookup(value); + + if (cmd < UDEV_BUILTIN_MAX) + rule_add_key(&rule_tmp, TK_A_RUN_BUILTIN, op, value, &cmd); + else + log_error("IMPORT{builtin}: '%s' unknown %s:%u\n", value, filename, lineno); + } else if (streq(attr, "program")) { + enum udev_builtin_cmd cmd = UDEV_BUILTIN_MAX; + + rule_add_key(&rule_tmp, TK_A_RUN_PROGRAM, op, value, &cmd); + } else { + log_error("RUN{} unknown type, ignoring RUN %s:%u\n", filename, lineno); + } + + continue; + } + + if (streq(key, "WAIT_FOR") || streq(key, "WAIT_FOR_SYSFS")) { + rule_add_key(&rule_tmp, TK_M_WAITFOR, 0, value, NULL); + continue; + } + + if (streq(key, "LABEL")) { + rule_tmp.rule.rule.label_off = rules_add_string(rules, value); + continue; + } + + if (streq(key, "GOTO")) { + rule_add_key(&rule_tmp, TK_A_GOTO, 0, value, NULL); + continue; + } + + if (startswith(key, "NAME")) { + if (op < OP_MATCH_MAX) { + rule_add_key(&rule_tmp, TK_M_NAME, op, value, NULL); + } else { + if (streq(value, "%k")) { + log_error("NAME=\"%%k\" is ignored, because it breaks kernel supplied names, " + "please remove it from %s:%u\n", filename, lineno); + continue; + } + if (value[0] == '\0') { + log_debug("NAME=\"\" is ignored, because udev will not delete any device nodes, " + "please remove it from %s:%u\n", filename, lineno); + continue; + } + rule_add_key(&rule_tmp, TK_A_NAME, op, value, NULL); + } + rule_tmp.rule.rule.can_set_name = true; + continue; + } + + if (streq(key, "SYMLINK")) { + if (op < OP_MATCH_MAX) + rule_add_key(&rule_tmp, TK_M_DEVLINK, op, value, NULL); + else + rule_add_key(&rule_tmp, TK_A_DEVLINK, op, value, NULL); + rule_tmp.rule.rule.can_set_name = true; + continue; + } + + if (streq(key, "OWNER")) { + uid_t uid; + char *endptr; + + uid = strtoul(value, &endptr, 10); + if (endptr[0] == '\0') { + rule_add_key(&rule_tmp, TK_A_OWNER_ID, op, NULL, &uid); + } else if ((rules->resolve_names > 0) && strchr("$%", value[0]) == NULL) { + uid = add_uid(rules, value); + rule_add_key(&rule_tmp, TK_A_OWNER_ID, op, NULL, &uid); + } else if (rules->resolve_names >= 0) { + rule_add_key(&rule_tmp, TK_A_OWNER, op, value, NULL); + } + rule_tmp.rule.rule.can_set_name = true; + continue; + } + + if (streq(key, "GROUP")) { + gid_t gid; + char *endptr; + + gid = strtoul(value, &endptr, 10); + if (endptr[0] == '\0') { + rule_add_key(&rule_tmp, TK_A_GROUP_ID, op, NULL, &gid); + } else if ((rules->resolve_names > 0) && strchr("$%", value[0]) == NULL) { + gid = add_gid(rules, value); + rule_add_key(&rule_tmp, TK_A_GROUP_ID, op, NULL, &gid); + } else if (rules->resolve_names >= 0) { + rule_add_key(&rule_tmp, TK_A_GROUP, op, value, NULL); + } + rule_tmp.rule.rule.can_set_name = true; + continue; + } + + if (streq(key, "MODE")) { + mode_t mode; + char *endptr; + + mode = strtol(value, &endptr, 8); + if (endptr[0] == '\0') + rule_add_key(&rule_tmp, TK_A_MODE_ID, op, NULL, &mode); + else + rule_add_key(&rule_tmp, TK_A_MODE, op, value, NULL); + rule_tmp.rule.rule.can_set_name = true; + continue; + } + + if (streq(key, "OPTIONS")) { + const char *pos; + + pos = strstr(value, "link_priority="); + if (pos != NULL) { + int prio = atoi(&pos[strlen("link_priority=")]); + + rule_add_key(&rule_tmp, TK_A_DEVLINK_PRIO, op, NULL, &prio); + } + + pos = strstr(value, "event_timeout="); + if (pos != NULL) { + int tout = atoi(&pos[strlen("event_timeout=")]); + + rule_add_key(&rule_tmp, TK_M_EVENT_TIMEOUT, op, NULL, &tout); + } + + pos = strstr(value, "string_escape="); + if (pos != NULL) { + pos = &pos[strlen("string_escape=")]; + if (startswith(pos, "none")) + rule_add_key(&rule_tmp, TK_A_STRING_ESCAPE_NONE, op, NULL, NULL); + else if (startswith(pos, "replace")) + rule_add_key(&rule_tmp, TK_A_STRING_ESCAPE_REPLACE, op, NULL, NULL); + } + + pos = strstr(value, "db_persist"); + if (pos != NULL) + rule_add_key(&rule_tmp, TK_A_DB_PERSIST, op, NULL, NULL); + + pos = strstr(value, "nowatch"); + if (pos != NULL) { + const int off = 0; + + rule_add_key(&rule_tmp, TK_A_INOTIFY_WATCH, op, NULL, &off); + } else { + pos = strstr(value, "watch"); + if (pos != NULL) { + const int on = 1; + + rule_add_key(&rule_tmp, TK_A_INOTIFY_WATCH, op, NULL, &on); + } + } + + pos = strstr(value, "static_node="); + if (pos != NULL) { + rule_add_key(&rule_tmp, TK_A_STATIC_NODE, op, &pos[strlen("static_node=")], NULL); + rule_tmp.rule.rule.has_static_node = true; + } + + continue; + } + + log_error("unknown key '%s' in %s:%u\n", key, filename, lineno); + goto invalid; + } + + /* add rule token */ + rule_tmp.rule.rule.token_count = 1 + rule_tmp.token_cur; + if (add_token(rules, &rule_tmp.rule) != 0) + goto invalid; + + /* add tokens to list, sorted by type */ + if (sort_token(rules, &rule_tmp) != 0) + goto invalid; + + return 0; +invalid: + log_error("invalid rule '%s:%u'\n", filename, lineno); + return -1; +} + +static int parse_file(struct udev_rules *rules, const char *filename) +{ + FILE *f; + unsigned int first_token; + unsigned int filename_off; + char line[UTIL_LINE_SIZE]; + int line_nr = 0; + unsigned int i; + + if (null_or_empty_path(filename)) { + log_debug("skip empty file: %s\n", filename); + return 0; + } + log_debug("read rules file: %s\n", filename); + + f = fopen(filename, "re"); + if (f == NULL) + return -1; + + first_token = rules->token_cur; + filename_off = rules_add_string(rules, filename); + + while (fgets(line, sizeof(line), f) != NULL) { + char *key; + size_t len; + + /* skip whitespace */ + line_nr++; + key = line; + while (isspace(key[0])) + key++; + + /* comment */ + if (key[0] == '#') + continue; + + len = strlen(line); + if (len < 3) + continue; + + /* continue reading if backslash+newline is found */ + while (line[len-2] == '\\') { + if (fgets(&line[len-2], (sizeof(line)-len)+2, f) == NULL) + break; + if (strlen(&line[len-2]) < 2) + break; + line_nr++; + len = strlen(line); + } + + if (len+1 >= sizeof(line)) { + log_error("line too long '%s':%u, ignored\n", filename, line_nr); + continue; + } + add_rule(rules, key, filename, filename_off, line_nr); + } + fclose(f); + + /* link GOTOs to LABEL rules in this file to be able to fast-forward */ + for (i = first_token+1; i < rules->token_cur; i++) { + if (rules->tokens[i].type == TK_A_GOTO) { + char *label = rules_str(rules, rules->tokens[i].key.value_off); + unsigned int j; + + for (j = i+1; j < rules->token_cur; j++) { + if (rules->tokens[j].type != TK_RULE) + continue; + if (rules->tokens[j].rule.label_off == 0) + continue; + if (!streq(label, rules_str(rules, rules->tokens[j].rule.label_off))) + continue; + rules->tokens[i].key.rule_goto = j; + break; + } + if (rules->tokens[i].key.rule_goto == 0) + log_error("GOTO '%s' has no matching label in: '%s'\n", label, filename); + } + } + return 0; +} + +struct udev_rules *udev_rules_new(struct udev *udev, int resolve_names) +{ + struct udev_rules *rules; + struct udev_list file_list; + struct token end_token; + char **files, **f; + int r; + + rules = calloc(1, sizeof(struct udev_rules)); + if (rules == NULL) + return NULL; + rules->udev = udev; + rules->resolve_names = resolve_names; + udev_list_init(udev, &file_list, true); + + /* init token array and string buffer */ + rules->tokens = malloc(PREALLOC_TOKEN * sizeof(struct token)); + if (rules->tokens == NULL) + return udev_rules_unref(rules); + rules->token_max = PREALLOC_TOKEN; + + rules->strbuf = strbuf_new(); + if (!rules->strbuf) + return udev_rules_unref(rules); + + rules->dirs = strv_new("/etc/udev/rules.d", + "/run/udev/rules.d", + UDEVLIBEXECDIR "/rules.d", + NULL); + if (!rules->dirs) { + log_error("failed to build config directory array"); + return udev_rules_unref(rules); + } + if (!path_strv_canonicalize(rules->dirs)) { + log_error("failed to canonicalize config directories\n"); + return udev_rules_unref(rules); + } + strv_uniq(rules->dirs); + + rules->dirs_ts_usec = calloc(strv_length(rules->dirs), sizeof(long long)); + if(!rules->dirs_ts_usec) + return udev_rules_unref(rules); + udev_rules_check_timestamp(rules); + + r = conf_files_list_strv(&files, ".rules", (const char **)rules->dirs); + if (r < 0) { + log_error("failed to enumerate rules files: %s\n", strerror(-r)); + return udev_rules_unref(rules); + } + + /* + * The offset value in the rules strct is limited; add all + * rules file names to the beginning of the string buffer. + */ + STRV_FOREACH(f, files) + rules_add_string(rules, *f); + + STRV_FOREACH(f, files) + parse_file(rules, *f); + + strv_free(files); + + memset(&end_token, 0x00, sizeof(struct token)); + end_token.type = TK_END; + add_token(rules, &end_token); + log_debug("rules contain %zu bytes tokens (%u * %zu bytes), %zu bytes strings\n", + rules->token_max * sizeof(struct token), rules->token_max, sizeof(struct token), rules->strbuf->len); + + /* cleanup temporary strbuf data */ + log_debug("%zu strings (%zu bytes), %zu de-duplicated (%zu bytes), %zu trie nodes used\n", + rules->strbuf->in_count, rules->strbuf->in_len, + rules->strbuf->dedup_count, rules->strbuf->dedup_len, rules->strbuf->nodes_count); + strbuf_complete(rules->strbuf); + + /* cleanup uid/gid cache */ + free(rules->uids); + rules->uids = NULL; + rules->uids_cur = 0; + rules->uids_max = 0; + free(rules->gids); + rules->gids = NULL; + rules->gids_cur = 0; + rules->gids_max = 0; + + dump_rules(rules); + return rules; +} + +struct udev_rules *udev_rules_unref(struct udev_rules *rules) +{ + if (rules == NULL) + return NULL; + free(rules->tokens); + strbuf_cleanup(rules->strbuf); + free(rules->uids); + free(rules->gids); + strv_free(rules->dirs); + free(rules->dirs_ts_usec); + free(rules); + return NULL; +} + +bool udev_rules_check_timestamp(struct udev_rules *rules) +{ + unsigned int i; + bool changed = false; + + if (rules == NULL) + goto out; + + for (i = 0; rules->dirs[i]; i++) { + struct stat stats; + + if (stat(rules->dirs[i], &stats) < 0) + continue; + + if (rules->dirs_ts_usec[i] == timespec_load(&stats.st_mtim)) + continue; + + /* first check */ + if (rules->dirs_ts_usec[i] != 0) { + log_debug("reload - timestamp of '%s' changed\n", rules->dirs[i]); + changed = true; + } + + /* update timestamp */ + rules->dirs_ts_usec[i] = timespec_load(&stats.st_mtim); + } +out: + return changed; +} + +static int match_key(struct udev_rules *rules, struct token *token, const char *val) +{ + char *key_value = rules_str(rules, token->key.value_off); + char *pos; + bool match = false; + + if (val == NULL) + val = ""; + + switch (token->key.glob) { + case GL_PLAIN: + match = (streq(key_value, val)); + break; + case GL_GLOB: + match = (fnmatch(key_value, val, 0) == 0); + break; + case GL_SPLIT: + { + const char *s; + size_t len; + + s = rules_str(rules, token->key.value_off); + len = strlen(val); + for (;;) { + const char *next; + + next = strchr(s, '|'); + if (next != NULL) { + size_t matchlen = (size_t)(next - s); + + match = (matchlen == len && strncmp(s, val, matchlen) == 0); + if (match) + break; + } else { + match = (streq(s, val)); + break; + } + s = &next[1]; + } + break; + } + case GL_SPLIT_GLOB: + { + char value[UTIL_PATH_SIZE]; + + util_strscpy(value, sizeof(value), rules_str(rules, token->key.value_off)); + key_value = value; + while (key_value != NULL) { + pos = strchr(key_value, '|'); + if (pos != NULL) { + pos[0] = '\0'; + pos = &pos[1]; + } + match = (fnmatch(key_value, val, 0) == 0); + if (match) + break; + key_value = pos; + } + break; + } + case GL_SOMETHING: + match = (val[0] != '\0'); + break; + case GL_UNSET: + return -1; + } + + if (match && (token->key.op == OP_MATCH)) + return 0; + if (!match && (token->key.op == OP_NOMATCH)) + return 0; + return -1; +} + +static int match_attr(struct udev_rules *rules, struct udev_device *dev, struct udev_event *event, struct token *cur) +{ + const char *name; + char nbuf[UTIL_NAME_SIZE]; + const char *value; + char vbuf[UTIL_NAME_SIZE]; + size_t len; + + name = rules_str(rules, cur->key.attr_off); + switch (cur->key.attrsubst) { + case SB_FORMAT: + udev_event_apply_format(event, name, nbuf, sizeof(nbuf)); + name = nbuf; + /* fall through */ + case SB_NONE: + value = udev_device_get_sysattr_value(dev, name); + if (value == NULL) + return -1; + break; + case SB_SUBSYS: + if (util_resolve_subsys_kernel(event->udev, name, vbuf, sizeof(vbuf), 1) != 0) + return -1; + value = vbuf; + break; + default: + return -1; + } + + /* remove trailing whitespace, if not asked to match for it */ + len = strlen(value); + if (len > 0 && isspace(value[len-1])) { + const char *key_value; + size_t klen; + + key_value = rules_str(rules, cur->key.value_off); + klen = strlen(key_value); + if (klen > 0 && !isspace(key_value[klen-1])) { + if (value != vbuf) { + util_strscpy(vbuf, sizeof(vbuf), value); + value = vbuf; + } + while (len > 0 && isspace(vbuf[--len])) + vbuf[len] = '\0'; + } + } + + return match_key(rules, cur, value); +} + +enum escape_type { + ESCAPE_UNSET, + ESCAPE_NONE, + ESCAPE_REPLACE, +}; + +int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event, const sigset_t *sigmask) +{ + struct token *cur; + struct token *rule; + enum escape_type esc = ESCAPE_UNSET; + bool can_set_name; + + if (rules->tokens == NULL) + return -1; + + can_set_name = ((!streq(udev_device_get_action(event->dev), "remove")) && + (major(udev_device_get_devnum(event->dev)) > 0 || + udev_device_get_ifindex(event->dev) > 0)); + + /* loop through token list, match, run actions or forward to next rule */ + cur = &rules->tokens[0]; + rule = cur; + for (;;) { + dump_token(rules, cur); + switch (cur->type) { + case TK_RULE: + /* current rule */ + rule = cur; + /* possibly skip rules which want to set NAME, SYMLINK, OWNER, GROUP, MODE */ + if (!can_set_name && rule->rule.can_set_name) + goto nomatch; + esc = ESCAPE_UNSET; + break; + case TK_M_ACTION: + if (match_key(rules, cur, udev_device_get_action(event->dev)) != 0) + goto nomatch; + break; + case TK_M_DEVPATH: + if (match_key(rules, cur, udev_device_get_devpath(event->dev)) != 0) + goto nomatch; + break; + case TK_M_KERNEL: + if (match_key(rules, cur, udev_device_get_sysname(event->dev)) != 0) + goto nomatch; + break; + case TK_M_DEVLINK: { + struct udev_list_entry *list_entry; + bool match = false; + + udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(event->dev)) { + const char *devlink; + + devlink = udev_list_entry_get_name(list_entry) + strlen("/dev/"); + if (match_key(rules, cur, devlink) == 0) { + match = true; + break; + } + } + if (!match) + goto nomatch; + break; + } + case TK_M_NAME: + if (match_key(rules, cur, event->name) != 0) + goto nomatch; + break; + case TK_M_ENV: { + const char *key_name = rules_str(rules, cur->key.attr_off); + const char *value; + + value = udev_device_get_property_value(event->dev, key_name); + if (value == NULL) + value = ""; + if (match_key(rules, cur, value)) + goto nomatch; + break; + } + case TK_M_TAG: { + struct udev_list_entry *list_entry; + bool match = false; + + udev_list_entry_foreach(list_entry, udev_device_get_tags_list_entry(event->dev)) { + if (streq(rules_str(rules, cur->key.value_off), udev_list_entry_get_name(list_entry))) { + match = true; + break; + } + } + if (!match && (cur->key.op != OP_NOMATCH)) + goto nomatch; + break; + } + case TK_M_SUBSYSTEM: + if (match_key(rules, cur, udev_device_get_subsystem(event->dev)) != 0) + goto nomatch; + break; + case TK_M_DRIVER: + if (match_key(rules, cur, udev_device_get_driver(event->dev)) != 0) + goto nomatch; + break; + case TK_M_WAITFOR: { + char filename[UTIL_PATH_SIZE]; + int found; + + udev_event_apply_format(event, rules_str(rules, cur->key.value_off), filename, sizeof(filename)); + found = (wait_for_file(event->dev, filename, 10) == 0); + if (!found && (cur->key.op != OP_NOMATCH)) + goto nomatch; + break; + } + case TK_M_ATTR: + if (match_attr(rules, event->dev, event, cur) != 0) + goto nomatch; + break; + case TK_M_KERNELS: + case TK_M_SUBSYSTEMS: + case TK_M_DRIVERS: + case TK_M_ATTRS: + case TK_M_TAGS: { + struct token *next; + + /* get whole sequence of parent matches */ + next = cur; + while (next->type > TK_M_PARENTS_MIN && next->type < TK_M_PARENTS_MAX) + next++; + + /* loop over parents */ + event->dev_parent = event->dev; + for (;;) { + struct token *key; + + /* loop over sequence of parent match keys */ + for (key = cur; key < next; key++ ) { + dump_token(rules, key); + switch(key->type) { + case TK_M_KERNELS: + if (match_key(rules, key, udev_device_get_sysname(event->dev_parent)) != 0) + goto try_parent; + break; + case TK_M_SUBSYSTEMS: + if (match_key(rules, key, udev_device_get_subsystem(event->dev_parent)) != 0) + goto try_parent; + break; + case TK_M_DRIVERS: + if (match_key(rules, key, udev_device_get_driver(event->dev_parent)) != 0) + goto try_parent; + break; + case TK_M_ATTRS: + if (match_attr(rules, event->dev_parent, event, key) != 0) + goto try_parent; + break; + case TK_M_TAGS: { + bool match = udev_device_has_tag(event->dev_parent, rules_str(rules, cur->key.value_off)); + + if (match && key->key.op == OP_NOMATCH) + goto try_parent; + if (!match && key->key.op == OP_MATCH) + goto try_parent; + break; + } + default: + goto nomatch; + } + } + break; + + try_parent: + event->dev_parent = udev_device_get_parent(event->dev_parent); + if (event->dev_parent == NULL) + goto nomatch; + } + /* move behind our sequence of parent match keys */ + cur = next; + continue; + } + case TK_M_TEST: { + char filename[UTIL_PATH_SIZE]; + struct stat statbuf; + int match; + + udev_event_apply_format(event, rules_str(rules, cur->key.value_off), filename, sizeof(filename)); + if (util_resolve_subsys_kernel(event->udev, filename, filename, sizeof(filename), 0) != 0) { + if (filename[0] != '/') { + char tmp[UTIL_PATH_SIZE]; + + util_strscpy(tmp, sizeof(tmp), filename); + util_strscpyl(filename, sizeof(filename), + udev_device_get_syspath(event->dev), "/", tmp, NULL); + } + } + attr_subst_subdir(filename, sizeof(filename)); + + match = (stat(filename, &statbuf) == 0); + if (match && cur->key.mode > 0) + match = ((statbuf.st_mode & cur->key.mode) > 0); + if (match && cur->key.op == OP_NOMATCH) + goto nomatch; + if (!match && cur->key.op == OP_MATCH) + goto nomatch; + break; + } + case TK_M_EVENT_TIMEOUT: + log_debug("OPTIONS event_timeout=%u\n", cur->key.event_timeout); + event->timeout_usec = cur->key.event_timeout * 1000 * 1000; + break; + case TK_M_PROGRAM: { + char program[UTIL_PATH_SIZE]; + char **envp; + char result[UTIL_PATH_SIZE]; + + free(event->program_result); + event->program_result = NULL; + udev_event_apply_format(event, rules_str(rules, cur->key.value_off), program, sizeof(program)); + envp = udev_device_get_properties_envp(event->dev); + log_debug("PROGRAM '%s' %s:%u\n", + program, + rules_str(rules, rule->rule.filename_off), + rule->rule.filename_line); + + if (udev_event_spawn(event, program, envp, sigmask, result, sizeof(result)) < 0) { + if (cur->key.op != OP_NOMATCH) + goto nomatch; + } else { + int count; + + util_remove_trailing_chars(result, '\n'); + if (esc == ESCAPE_UNSET || esc == ESCAPE_REPLACE) { + count = util_replace_chars(result, UDEV_ALLOWED_CHARS_INPUT); + if (count > 0) + log_debug("%i character(s) replaced\n" , count); + } + event->program_result = strdup(result); + if (cur->key.op == OP_NOMATCH) + goto nomatch; + } + break; + } + case TK_M_IMPORT_FILE: { + char import[UTIL_PATH_SIZE]; + + udev_event_apply_format(event, rules_str(rules, cur->key.value_off), import, sizeof(import)); + if (import_file_into_properties(event->dev, import) != 0) + if (cur->key.op != OP_NOMATCH) + goto nomatch; + break; + } + case TK_M_IMPORT_PROG: { + char import[UTIL_PATH_SIZE]; + + udev_event_apply_format(event, rules_str(rules, cur->key.value_off), import, sizeof(import)); + log_debug("IMPORT '%s' %s:%u\n", + import, + rules_str(rules, rule->rule.filename_off), + rule->rule.filename_line); + + if (import_program_into_properties(event, import, sigmask) != 0) + if (cur->key.op != OP_NOMATCH) + goto nomatch; + break; + } + case TK_M_IMPORT_BUILTIN: { + char command[UTIL_PATH_SIZE]; + + if (udev_builtin_run_once(cur->key.builtin_cmd)) { + /* check if we ran already */ + if (event->builtin_run & (1 << cur->key.builtin_cmd)) { + log_debug("IMPORT builtin skip '%s' %s:%u\n", + udev_builtin_name(cur->key.builtin_cmd), + rules_str(rules, rule->rule.filename_off), + rule->rule.filename_line); + /* return the result from earlier run */ + if (event->builtin_ret & (1 << cur->key.builtin_cmd)) + if (cur->key.op != OP_NOMATCH) + goto nomatch; + break; + } + /* mark as ran */ + event->builtin_run |= (1 << cur->key.builtin_cmd); + } + + udev_event_apply_format(event, rules_str(rules, cur->key.value_off), command, sizeof(command)); + log_debug("IMPORT builtin '%s' %s:%u\n", + udev_builtin_name(cur->key.builtin_cmd), + rules_str(rules, rule->rule.filename_off), + rule->rule.filename_line); + + if (udev_builtin_run(event->dev, cur->key.builtin_cmd, command, false) != 0) { + /* remember failure */ + log_debug("IMPORT builtin '%s' returned non-zero\n", + udev_builtin_name(cur->key.builtin_cmd)); + event->builtin_ret |= (1 << cur->key.builtin_cmd); + if (cur->key.op != OP_NOMATCH) + goto nomatch; + } + break; + } + case TK_M_IMPORT_DB: { + const char *key = rules_str(rules, cur->key.value_off); + const char *value; + + value = udev_device_get_property_value(event->dev_db, key); + if (value != NULL) { + struct udev_list_entry *entry; + + entry = udev_device_add_property(event->dev, key, value); + udev_list_entry_set_num(entry, true); + } else { + if (cur->key.op != OP_NOMATCH) + goto nomatch; + } + break; + } + case TK_M_IMPORT_CMDLINE: { + FILE *f; + bool imported = false; + + f = fopen("/proc/cmdline", "re"); + if (f != NULL) { + char cmdline[4096]; + + if (fgets(cmdline, sizeof(cmdline), f) != NULL) { + const char *key = rules_str(rules, cur->key.value_off); + char *pos; + + pos = strstr(cmdline, key); + if (pos != NULL) { + struct udev_list_entry *entry; + + pos += strlen(key); + if (pos[0] == '\0' || isspace(pos[0])) { + /* we import simple flags as 'FLAG=1' */ + entry = udev_device_add_property(event->dev, key, "1"); + udev_list_entry_set_num(entry, true); + imported = true; + } else if (pos[0] == '=') { + const char *value; + + pos++; + value = pos; + while (pos[0] != '\0' && !isspace(pos[0])) + pos++; + pos[0] = '\0'; + entry = udev_device_add_property(event->dev, key, value); + udev_list_entry_set_num(entry, true); + imported = true; + } + } + } + fclose(f); + } + if (!imported && cur->key.op != OP_NOMATCH) + goto nomatch; + break; + } + case TK_M_IMPORT_PARENT: { + char import[UTIL_PATH_SIZE]; + + udev_event_apply_format(event, rules_str(rules, cur->key.value_off), import, sizeof(import)); + if (import_parent_into_properties(event->dev, import) != 0) + if (cur->key.op != OP_NOMATCH) + goto nomatch; + break; + } + case TK_M_RESULT: + if (match_key(rules, cur, event->program_result) != 0) + goto nomatch; + break; + case TK_A_STRING_ESCAPE_NONE: + esc = ESCAPE_NONE; + break; + case TK_A_STRING_ESCAPE_REPLACE: + esc = ESCAPE_REPLACE; + break; + case TK_A_DB_PERSIST: + udev_device_set_db_persist(event->dev); + break; + case TK_A_INOTIFY_WATCH: + if (event->inotify_watch_final) + break; + if (cur->key.op == OP_ASSIGN_FINAL) + event->inotify_watch_final = true; + event->inotify_watch = cur->key.watch; + break; + case TK_A_DEVLINK_PRIO: + udev_device_set_devlink_priority(event->dev, cur->key.devlink_prio); + break; + case TK_A_OWNER: { + char owner[UTIL_NAME_SIZE]; + + if (event->owner_final) + break; + if (cur->key.op == OP_ASSIGN_FINAL) + event->owner_final = true; + udev_event_apply_format(event, rules_str(rules, cur->key.value_off), owner, sizeof(owner)); + event->owner_set = true; + event->uid = util_lookup_user(event->udev, owner); + log_debug("OWNER %u %s:%u\n", + event->uid, + rules_str(rules, rule->rule.filename_off), + rule->rule.filename_line); + break; + } + case TK_A_GROUP: { + char group[UTIL_NAME_SIZE]; + + if (event->group_final) + break; + if (cur->key.op == OP_ASSIGN_FINAL) + event->group_final = true; + udev_event_apply_format(event, rules_str(rules, cur->key.value_off), group, sizeof(group)); + event->group_set = true; + event->gid = util_lookup_group(event->udev, group); + log_debug("GROUP %u %s:%u\n", + event->gid, + rules_str(rules, rule->rule.filename_off), + rule->rule.filename_line); + break; + } + case TK_A_MODE: { + char mode_str[UTIL_NAME_SIZE]; + mode_t mode; + char *endptr; + + if (event->mode_final) + break; + udev_event_apply_format(event, rules_str(rules, cur->key.value_off), mode_str, sizeof(mode_str)); + mode = strtol(mode_str, &endptr, 8); + if (endptr[0] != '\0') { + log_error("ignoring invalid mode '%s'\n", mode_str); + break; + } + if (cur->key.op == OP_ASSIGN_FINAL) + event->mode_final = true; + event->mode_set = true; + event->mode = mode; + log_debug("MODE %#o %s:%u\n", + event->mode, + rules_str(rules, rule->rule.filename_off), + rule->rule.filename_line); + break; + } + case TK_A_OWNER_ID: + if (event->owner_final) + break; + if (cur->key.op == OP_ASSIGN_FINAL) + event->owner_final = true; + event->owner_set = true; + event->uid = cur->key.uid; + log_debug("OWNER %u %s:%u\n", + event->uid, + rules_str(rules, rule->rule.filename_off), + rule->rule.filename_line); + break; + case TK_A_GROUP_ID: + if (event->group_final) + break; + if (cur->key.op == OP_ASSIGN_FINAL) + event->group_final = true; + event->group_set = true; + event->gid = cur->key.gid; + log_debug("GROUP %u %s:%u\n", + event->gid, + rules_str(rules, rule->rule.filename_off), + rule->rule.filename_line); + break; + case TK_A_MODE_ID: + if (event->mode_final) + break; + if (cur->key.op == OP_ASSIGN_FINAL) + event->mode_final = true; + event->mode_set = true; + event->mode = cur->key.mode; + log_debug("MODE %#o %s:%u\n", + event->mode, + rules_str(rules, rule->rule.filename_off), + rule->rule.filename_line); + break; + case TK_A_ENV: { + const char *name = rules_str(rules, cur->key.attr_off); + char *value = rules_str(rules, cur->key.value_off); + char value_new[UTIL_NAME_SIZE]; + const char *value_old = NULL; + struct udev_list_entry *entry; + + if (value[0] == '\0') { + if (cur->key.op == OP_ADD) + break; + udev_device_add_property(event->dev, name, NULL); + break; + } + + if (cur->key.op == OP_ADD) + value_old = udev_device_get_property_value(event->dev, name); + if (value_old) { + char temp[UTIL_NAME_SIZE]; + + /* append value separated by space */ + udev_event_apply_format(event, value, temp, sizeof(temp)); + util_strscpyl(value_new, sizeof(value_new), value_old, " ", temp, NULL); + } else + udev_event_apply_format(event, value, value_new, sizeof(value_new)); + + entry = udev_device_add_property(event->dev, name, value_new); + /* store in db, skip private keys */ + if (name[0] != '.') + udev_list_entry_set_num(entry, true); + break; + } + case TK_A_TAG: { + char tag[UTIL_PATH_SIZE]; + const char *p; + + udev_event_apply_format(event, rules_str(rules, cur->key.value_off), tag, sizeof(tag)); + if (cur->key.op == OP_ASSIGN || cur->key.op == OP_ASSIGN_FINAL) + udev_device_cleanup_tags_list(event->dev); + for (p = tag; *p != '\0'; p++) { + if ((*p >= 'a' && *p <= 'z') || + (*p >= 'A' && *p <= 'Z') || + (*p >= '0' && *p <= '9') || + *p == '-' || *p == '_') + continue; + log_error("ignoring invalid tag name '%s'\n", tag); + break; + } + udev_device_add_tag(event->dev, tag); + break; + } + case TK_A_NAME: { + const char *name = rules_str(rules, cur->key.value_off); + + char name_str[UTIL_PATH_SIZE]; + int count; + + if (event->name_final) + break; + if (cur->key.op == OP_ASSIGN_FINAL) + event->name_final = true; + udev_event_apply_format(event, name, name_str, sizeof(name_str)); + if (esc == ESCAPE_UNSET || esc == ESCAPE_REPLACE) { + count = util_replace_chars(name_str, "/"); + if (count > 0) + log_debug("%i character(s) replaced\n", count); + } + if (major(udev_device_get_devnum(event->dev)) && + (!streq(name_str, udev_device_get_devnode(event->dev) + strlen("/dev/")))) { + log_error("NAME=\"%s\" ignored, kernel device nodes " + "can not be renamed; please fix it in %s:%u\n", name, + rules_str(rules, rule->rule.filename_off), rule->rule.filename_line); + break; + } + free(event->name); + event->name = strdup(name_str); + log_debug("NAME '%s' %s:%u\n", + event->name, + rules_str(rules, rule->rule.filename_off), + rule->rule.filename_line); + break; + } + case TK_A_DEVLINK: { + char temp[UTIL_PATH_SIZE]; + char filename[UTIL_PATH_SIZE]; + char *pos, *next; + int count = 0; + + if (event->devlink_final) + break; + if (major(udev_device_get_devnum(event->dev)) == 0) + break; + if (cur->key.op == OP_ASSIGN_FINAL) + event->devlink_final = true; + if (cur->key.op == OP_ASSIGN || cur->key.op == OP_ASSIGN_FINAL) + udev_device_cleanup_devlinks_list(event->dev); + + /* allow multiple symlinks separated by spaces */ + udev_event_apply_format(event, rules_str(rules, cur->key.value_off), temp, sizeof(temp)); + if (esc == ESCAPE_UNSET) + count = util_replace_chars(temp, "/ "); + else if (esc == ESCAPE_REPLACE) + count = util_replace_chars(temp, "/"); + if (count > 0) + log_debug("%i character(s) replaced\n" , count); + pos = temp; + while (isspace(pos[0])) + pos++; + next = strchr(pos, ' '); + while (next != NULL) { + next[0] = '\0'; + log_debug("LINK '%s' %s:%u\n", pos, + rules_str(rules, rule->rule.filename_off), rule->rule.filename_line); + util_strscpyl(filename, sizeof(filename), "/dev/", pos, NULL); + udev_device_add_devlink(event->dev, filename); + while (isspace(next[1])) + next++; + pos = &next[1]; + next = strchr(pos, ' '); + } + if (pos[0] != '\0') { + log_debug("LINK '%s' %s:%u\n", pos, + rules_str(rules, rule->rule.filename_off), rule->rule.filename_line); + util_strscpyl(filename, sizeof(filename), "/dev/", pos, NULL); + udev_device_add_devlink(event->dev, filename); + } + break; + } + case TK_A_ATTR: { + const char *key_name = rules_str(rules, cur->key.attr_off); + char attr[UTIL_PATH_SIZE]; + char value[UTIL_NAME_SIZE]; + FILE *f; + + if (util_resolve_subsys_kernel(event->udev, key_name, attr, sizeof(attr), 0) != 0) + util_strscpyl(attr, sizeof(attr), udev_device_get_syspath(event->dev), "/", key_name, NULL); + attr_subst_subdir(attr, sizeof(attr)); + + udev_event_apply_format(event, rules_str(rules, cur->key.value_off), value, sizeof(value)); + log_debug("ATTR '%s' writing '%s' %s:%u\n", attr, value, + rules_str(rules, rule->rule.filename_off), + rule->rule.filename_line); + f = fopen(attr, "we"); + if (f != NULL) { + if (fprintf(f, "%s", value) <= 0) + log_error("error writing ATTR{%s}: %m\n", attr); + fclose(f); + } else { + log_error("error opening ATTR{%s} for writing: %m\n", attr); + } + break; + } + case TK_A_RUN_BUILTIN: + case TK_A_RUN_PROGRAM: { + struct udev_list_entry *entry; + + if (cur->key.op == OP_ASSIGN || cur->key.op == OP_ASSIGN_FINAL) + udev_list_cleanup(&event->run_list); + log_debug("RUN '%s' %s:%u\n", + rules_str(rules, cur->key.value_off), + rules_str(rules, rule->rule.filename_off), + rule->rule.filename_line); + entry = udev_list_entry_add(&event->run_list, rules_str(rules, cur->key.value_off), NULL); + udev_list_entry_set_num(entry, cur->key.builtin_cmd); + break; + } + case TK_A_GOTO: + if (cur->key.rule_goto == 0) + break; + cur = &rules->tokens[cur->key.rule_goto]; + continue; + case TK_END: + return 0; + + case TK_M_PARENTS_MIN: + case TK_M_PARENTS_MAX: + case TK_M_MAX: + case TK_UNSET: + log_error("wrong type %u\n", cur->type); + goto nomatch; + } + + cur++; + continue; + nomatch: + /* fast-forward to next rule */ + cur = rule + rule->rule.token_count; + } +} + +void udev_rules_apply_static_dev_perms(struct udev_rules *rules) +{ + struct token *cur; + struct token *rule; + uid_t uid = 0; + gid_t gid = 0; + mode_t mode = 0; + + if (rules->tokens == NULL) + return; + + cur = &rules->tokens[0]; + rule = cur; + for (;;) { + switch (cur->type) { + case TK_RULE: + /* current rule */ + rule = cur; + + /* skip rules without a static_node tag */ + if (!rule->rule.has_static_node) + goto next; + + uid = 0; + gid = 0; + mode = 0; + break; + case TK_A_OWNER_ID: + uid = cur->key.uid; + break; + case TK_A_GROUP_ID: + gid = cur->key.gid; + break; + case TK_A_MODE_ID: + mode = cur->key.mode; + break; + case TK_A_STATIC_NODE: { + char filename[UTIL_PATH_SIZE]; + struct stat stats; + + /* we assure, that the permissions tokens are sorted before the static token */ + if (mode == 0 && uid == 0 && gid == 0) + goto next; + util_strscpyl(filename, sizeof(filename), "/dev/", rules_str(rules, cur->key.value_off), NULL); + if (stat(filename, &stats) != 0) + goto next; + if (!S_ISBLK(stats.st_mode) && !S_ISCHR(stats.st_mode)) + goto next; + if (mode == 0) { + if (gid > 0) + mode = 0660; + else + mode = 0600; + } + if (mode != (stats.st_mode & 01777)) { + chmod(filename, mode); + log_debug("chmod '%s' %#o\n", filename, mode); + } + + if ((uid != 0 && uid != stats.st_uid) || (gid != 0 && gid != stats.st_gid)) { + chown(filename, uid, gid); + log_debug("chown '%s' %u %u\n", filename, uid, gid); + } + + utimensat(AT_FDCWD, filename, NULL, 0); + break; + } + case TK_END: + return; + } + + cur++; + continue; +next: + /* fast-forward to next rule */ + cur = rule + rule->rule.token_count; + continue; + } +} diff --git a/src/udev/udev-watch.c b/src/udev/udev-watch.c new file mode 100644 index 000000000..311f5bdf2 --- /dev/null +++ b/src/udev/udev-watch.c @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2004-2012 Kay Sievers + * Copyright (C) 2009 Canonical Ltd. + * Copyright (C) 2009 Scott James Remnant + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "udev.h" + +static int inotify_fd = -1; + +/* inotify descriptor, will be shared with rules directory; + * set to cloexec since we need our children to be able to add + * watches for us + */ +int udev_watch_init(struct udev *udev) +{ + inotify_fd = inotify_init1(IN_CLOEXEC); + if (inotify_fd < 0) + log_error("inotify_init failed: %m\n"); + return inotify_fd; +} + +/* move any old watches directory out of the way, and then restore + * the watches + */ +void udev_watch_restore(struct udev *udev) +{ + if (inotify_fd < 0) + return; + + if (rename("/run/udev/watch", "/run/udev/watch.old") == 0) { + DIR *dir; + struct dirent *ent; + + dir = opendir("/run/udev/watch.old"); + if (dir == NULL) { + log_error("unable to open old watches dir /run/udev/watch.old; old watches will not be restored: %m"); + return; + } + + for (ent = readdir(dir); ent != NULL; ent = readdir(dir)) { + char device[UTIL_PATH_SIZE]; + ssize_t len; + struct udev_device *dev; + + if (ent->d_name[0] == '.') + continue; + + len = readlinkat(dirfd(dir), ent->d_name, device, sizeof(device)); + if (len <= 0 || len == (ssize_t)sizeof(device)) + goto unlink; + device[len] = '\0'; + + dev = udev_device_new_from_device_id(udev, device); + if (dev == NULL) + goto unlink; + + log_debug("restoring old watch on '%s'\n", udev_device_get_devnode(dev)); + udev_watch_begin(udev, dev); + udev_device_unref(dev); +unlink: + unlinkat(dirfd(dir), ent->d_name, 0); + } + + closedir(dir); + rmdir("/run/udev/watch.old"); + + } else if (errno != ENOENT) { + log_error("unable to move watches dir /run/udev/watch; old watches will not be restored: %m"); + } +} + +void udev_watch_begin(struct udev *udev, struct udev_device *dev) +{ + char filename[UTIL_PATH_SIZE]; + int wd; + int r; + + if (inotify_fd < 0) + return; + + log_debug("adding watch on '%s'\n", udev_device_get_devnode(dev)); + wd = inotify_add_watch(inotify_fd, udev_device_get_devnode(dev), IN_CLOSE_WRITE); + if (wd < 0) { + log_error("inotify_add_watch(%d, %s, %o) failed: %m\n", + inotify_fd, udev_device_get_devnode(dev), IN_CLOSE_WRITE); + return; + } + + snprintf(filename, sizeof(filename), "/run/udev/watch/%d", wd); + mkdir_parents(filename, 0755); + unlink(filename); + r = symlink(udev_device_get_id_filename(dev), filename); + if (r < 0) + log_error("Failed to create symlink: %m"); + + udev_device_set_watch_handle(dev, wd); +} + +void udev_watch_end(struct udev *udev, struct udev_device *dev) +{ + int wd; + char filename[UTIL_PATH_SIZE]; + + if (inotify_fd < 0) + return; + + wd = udev_device_get_watch_handle(dev); + if (wd < 0) + return; + + log_debug("removing watch on '%s'\n", udev_device_get_devnode(dev)); + inotify_rm_watch(inotify_fd, wd); + + snprintf(filename, sizeof(filename), "/run/udev/watch/%d", wd); + unlink(filename); + + udev_device_set_watch_handle(dev, -1); +} + +struct udev_device *udev_watch_lookup(struct udev *udev, int wd) +{ + char filename[UTIL_PATH_SIZE]; + char device[UTIL_NAME_SIZE]; + ssize_t len; + + if (inotify_fd < 0 || wd < 0) + return NULL; + + snprintf(filename, sizeof(filename), "/run/udev/watch/%d", wd); + len = readlink(filename, device, sizeof(device)); + if (len <= 0 || (size_t)len == sizeof(device)) + return NULL; + device[len] = '\0'; + + return udev_device_new_from_device_id(udev, device); +} diff --git a/src/udev/udev.conf b/src/udev/udev.conf new file mode 100644 index 000000000..f39253eb6 --- /dev/null +++ b/src/udev/udev.conf @@ -0,0 +1,3 @@ +# see udev(7) for details + +#udev_log="info" diff --git a/src/udev/udev.h b/src/udev/udev.h new file mode 100644 index 000000000..72a7623e3 --- /dev/null +++ b/src/udev/udev.h @@ -0,0 +1,211 @@ +/* + * Copyright (C) 2003 Greg Kroah-Hartman + * Copyright (C) 2003-2010 Kay Sievers + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef _UDEV_H_ +#define _UDEV_H_ + +#include +#include +#include + +#include "libudev.h" +#include "libudev-private.h" +#include "util.h" +#include "label.h" +#include "strv.h" + +struct udev_event { + struct udev *udev; + struct udev_device *dev; + struct udev_device *dev_parent; + struct udev_device *dev_db; + char *name; + char *program_result; + mode_t mode; + uid_t uid; + gid_t gid; + struct udev_list run_list; + int exec_delay; + usec_t birth_usec; + usec_t timeout_usec; + int fd_signal; + unsigned int builtin_run; + unsigned int builtin_ret; + bool sigterm; + bool inotify_watch; + bool inotify_watch_final; + bool group_set; + bool group_final; + bool owner_set; + bool owner_final; + bool mode_set; + bool mode_final; + bool name_final; + bool devlink_final; + bool run_final; +}; + +struct udev_watch { + struct udev_list_node node; + int handle; + char *name; +}; + +/* udev-rules.c */ +struct udev_rules; +struct udev_rules *udev_rules_new(struct udev *udev, int resolve_names); +struct udev_rules *udev_rules_unref(struct udev_rules *rules); +bool udev_rules_check_timestamp(struct udev_rules *rules); +int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event, const sigset_t *sigmask); +void udev_rules_apply_static_dev_perms(struct udev_rules *rules); + +/* udev-event.c */ +struct udev_event *udev_event_new(struct udev_device *dev); +void udev_event_unref(struct udev_event *event); +size_t udev_event_apply_format(struct udev_event *event, const char *src, char *dest, size_t size); +int udev_event_apply_subsys_kernel(struct udev_event *event, const char *string, + char *result, size_t maxsize, int read_value); +int udev_event_spawn(struct udev_event *event, + const char *cmd, char **envp, const sigset_t *sigmask, + char *result, size_t ressize); +int udev_event_execute_rules(struct udev_event *event, struct udev_rules *rules, const sigset_t *sigset); +void udev_event_execute_run(struct udev_event *event, const sigset_t *sigset); +int udev_build_argv(struct udev *udev, char *cmd, int *argc, char *argv[]); + +/* udev-watch.c */ +int udev_watch_init(struct udev *udev); +void udev_watch_restore(struct udev *udev); +void udev_watch_begin(struct udev *udev, struct udev_device *dev); +void udev_watch_end(struct udev *udev, struct udev_device *dev); +struct udev_device *udev_watch_lookup(struct udev *udev, int wd); + +/* udev-node.c */ +void udev_node_add(struct udev_device *dev, mode_t mode, uid_t uid, gid_t gid); +void udev_node_remove(struct udev_device *dev); +void udev_node_update_old_links(struct udev_device *dev, struct udev_device *dev_old); + +/* udev-ctrl.c */ +struct udev_ctrl; +struct udev_ctrl *udev_ctrl_new(struct udev *udev); +struct udev_ctrl *udev_ctrl_new_from_fd(struct udev *udev, int fd); +int udev_ctrl_enable_receiving(struct udev_ctrl *uctrl); +struct udev_ctrl *udev_ctrl_ref(struct udev_ctrl *uctrl); +struct udev_ctrl *udev_ctrl_unref(struct udev_ctrl *uctrl); +int udev_ctrl_cleanup(struct udev_ctrl *uctrl); +struct udev *udev_ctrl_get_udev(struct udev_ctrl *uctrl); +int udev_ctrl_get_fd(struct udev_ctrl *uctrl); +int udev_ctrl_send_set_log_level(struct udev_ctrl *uctrl, int priority, int timeout); +int udev_ctrl_send_stop_exec_queue(struct udev_ctrl *uctrl, int timeout); +int udev_ctrl_send_start_exec_queue(struct udev_ctrl *uctrl, int timeout); +int udev_ctrl_send_reload(struct udev_ctrl *uctrl, int timeout); +int udev_ctrl_send_ping(struct udev_ctrl *uctrl, int timeout); +int udev_ctrl_send_exit(struct udev_ctrl *uctrl, int timeout); +int udev_ctrl_send_set_env(struct udev_ctrl *uctrl, const char *key, int timeout); +int udev_ctrl_send_set_children_max(struct udev_ctrl *uctrl, int count, int timeout); +struct udev_ctrl_connection; +struct udev_ctrl_connection *udev_ctrl_get_connection(struct udev_ctrl *uctrl); +struct udev_ctrl_connection *udev_ctrl_connection_ref(struct udev_ctrl_connection *conn); +struct udev_ctrl_connection *udev_ctrl_connection_unref(struct udev_ctrl_connection *conn); +struct udev_ctrl_msg; +struct udev_ctrl_msg *udev_ctrl_receive_msg(struct udev_ctrl_connection *conn); +struct udev_ctrl_msg *udev_ctrl_msg_ref(struct udev_ctrl_msg *ctrl_msg); +struct udev_ctrl_msg *udev_ctrl_msg_unref(struct udev_ctrl_msg *ctrl_msg); +int udev_ctrl_get_set_log_level(struct udev_ctrl_msg *ctrl_msg); +int udev_ctrl_get_stop_exec_queue(struct udev_ctrl_msg *ctrl_msg); +int udev_ctrl_get_start_exec_queue(struct udev_ctrl_msg *ctrl_msg); +int udev_ctrl_get_reload(struct udev_ctrl_msg *ctrl_msg); +int udev_ctrl_get_ping(struct udev_ctrl_msg *ctrl_msg); +int udev_ctrl_get_exit(struct udev_ctrl_msg *ctrl_msg); +const char *udev_ctrl_get_set_env(struct udev_ctrl_msg *ctrl_msg); +int udev_ctrl_get_set_children_max(struct udev_ctrl_msg *ctrl_msg); + +/* built-in commands */ +enum udev_builtin_cmd { +#ifdef HAVE_BLKID + UDEV_BUILTIN_BLKID, +#endif + UDEV_BUILTIN_BTRFS, + UDEV_BUILTIN_FIRMWARE, + UDEV_BUILTIN_HWDB, + UDEV_BUILTIN_INPUT_ID, +#ifdef HAVE_KMOD + UDEV_BUILTIN_KMOD, +#endif + UDEV_BUILTIN_NET_ID, + UDEV_BUILTIN_PATH_ID, + UDEV_BUILTIN_USB_ID, +#ifdef HAVE_ACL + UDEV_BUILTIN_UACCESS, +#endif + UDEV_BUILTIN_MAX +}; +struct udev_builtin { + const char *name; + int (*cmd)(struct udev_device *dev, int argc, char *argv[], bool test); + const char *help; + int (*init)(struct udev *udev); + void (*exit)(struct udev *udev); + bool (*validate)(struct udev *udev); + bool run_once; +}; +#ifdef HAVE_BLKID +extern const struct udev_builtin udev_builtin_blkid; +#endif +extern const struct udev_builtin udev_builtin_btrfs; +extern const struct udev_builtin udev_builtin_firmware; +extern const struct udev_builtin udev_builtin_hwdb; +extern const struct udev_builtin udev_builtin_input_id; +#ifdef HAVE_KMOD +extern const struct udev_builtin udev_builtin_kmod; +#endif +extern const struct udev_builtin udev_builtin_net_id; +extern const struct udev_builtin udev_builtin_path_id; +extern const struct udev_builtin udev_builtin_usb_id; +extern const struct udev_builtin udev_builtin_uaccess; +void udev_builtin_init(struct udev *udev); +void udev_builtin_exit(struct udev *udev); +enum udev_builtin_cmd udev_builtin_lookup(const char *command); +const char *udev_builtin_name(enum udev_builtin_cmd cmd); +bool udev_builtin_run_once(enum udev_builtin_cmd cmd); +int udev_builtin_run(struct udev_device *dev, enum udev_builtin_cmd cmd, const char *command, bool test); +void udev_builtin_list(struct udev *udev); +bool udev_builtin_validate(struct udev *udev); +int udev_builtin_add_property(struct udev_device *dev, bool test, const char *key, const char *val); +int udev_builtin_hwdb_lookup(struct udev_device *dev, const char *modalias, bool test); + +/* udev logging */ +void udev_main_log(struct udev *udev, int priority, + const char *file, int line, const char *fn, + const char *format, va_list args); + +/* udevadm commands */ +struct udevadm_cmd { + const char *name; + int (*cmd)(struct udev *udev, int argc, char *argv[]); + const char *help; + int debug; +}; +extern const struct udevadm_cmd udevadm_info; +extern const struct udevadm_cmd udevadm_trigger; +extern const struct udevadm_cmd udevadm_settle; +extern const struct udevadm_cmd udevadm_control; +extern const struct udevadm_cmd udevadm_monitor; +extern const struct udevadm_cmd udevadm_hwdb; +extern const struct udevadm_cmd udevadm_test; +extern const struct udevadm_cmd udevadm_test_builtin; +#endif diff --git a/src/udev/udev.pc.in b/src/udev/udev.pc.in new file mode 100644 index 000000000..a0c2e82d4 --- /dev/null +++ b/src/udev/udev.pc.in @@ -0,0 +1,5 @@ +Name: udev +Description: udev +Version: @VERSION@ + +udevdir=@udevlibexecdir@ diff --git a/src/udev/udevadm-control.c b/src/udev/udevadm-control.c new file mode 100644 index 000000000..c5a189257 --- /dev/null +++ b/src/udev/udevadm-control.c @@ -0,0 +1,175 @@ +/* + * Copyright (C) 2005-2011 Kay Sievers + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "udev.h" + +static void print_help(void) +{ + printf("Usage: udevadm control COMMAND\n" + " --exit instruct the daemon to cleanup and exit\n" + " --log-priority= set the udev log level for the daemon\n" + " --stop-exec-queue do not execute events, queue only\n" + " --start-exec-queue execute events, flush queue\n" + " --reload reload rules and databases\n" + " --property== set a global property for all events\n" + " --children-max= maximum number of children\n" + " --timeout= maximum time to block for a reply\n" + " --help print this help text\n\n"); +} + +static int adm_control(struct udev *udev, int argc, char *argv[]) +{ + struct udev_ctrl *uctrl = NULL; + int timeout = 60; + int rc = 1; + + static const struct option options[] = { + { "exit", no_argument, NULL, 'e' }, + { "log-priority", required_argument, NULL, 'l' }, + { "stop-exec-queue", no_argument, NULL, 's' }, + { "start-exec-queue", no_argument, NULL, 'S' }, + { "reload", no_argument, NULL, 'R' }, + { "reload-rules", no_argument, NULL, 'R' }, + { "property", required_argument, NULL, 'p' }, + { "env", required_argument, NULL, 'p' }, + { "children-max", required_argument, NULL, 'm' }, + { "timeout", required_argument, NULL, 't' }, + { "help", no_argument, NULL, 'h' }, + {} + }; + + if (getuid() != 0) { + fprintf(stderr, "root privileges required\n"); + return 1; + } + + uctrl = udev_ctrl_new(udev); + if (uctrl == NULL) + return 2; + + for (;;) { + int option; + + option = getopt_long(argc, argv, "el:sSRp:m:h", options, NULL); + if (option == -1) + break; + + switch (option) { + case 'e': + if (udev_ctrl_send_exit(uctrl, timeout) < 0) + rc = 2; + else + rc = 0; + break; + case 'l': { + int i; + + i = util_log_priority(optarg); + if (i < 0) { + fprintf(stderr, "invalid number '%s'\n", optarg); + goto out; + } + if (udev_ctrl_send_set_log_level(uctrl, util_log_priority(optarg), timeout) < 0) + rc = 2; + else + rc = 0; + break; + } + case 's': + if (udev_ctrl_send_stop_exec_queue(uctrl, timeout) < 0) + rc = 2; + else + rc = 0; + break; + case 'S': + if (udev_ctrl_send_start_exec_queue(uctrl, timeout) < 0) + rc = 2; + else + rc = 0; + break; + case 'R': + if (udev_ctrl_send_reload(uctrl, timeout) < 0) + rc = 2; + else + rc = 0; + break; + case 'p': + if (strchr(optarg, '=') == NULL) { + fprintf(stderr, "expect = instead of '%s'\n", optarg); + goto out; + } + if (udev_ctrl_send_set_env(uctrl, optarg, timeout) < 0) + rc = 2; + else + rc = 0; + break; + case 'm': { + char *endp; + int i; + + i = strtoul(optarg, &endp, 0); + if (endp[0] != '\0' || i < 1) { + fprintf(stderr, "invalid number '%s'\n", optarg); + goto out; + } + if (udev_ctrl_send_set_children_max(uctrl, i, timeout) < 0) + rc = 2; + else + rc = 0; + break; + } + case 't': { + int seconds; + + seconds = atoi(optarg); + if (seconds >= 0) + timeout = seconds; + else + fprintf(stderr, "invalid timeout value\n"); + break; + } + case 'h': + print_help(); + rc = 0; + break; + } + } + + if (argv[optind] != NULL) + fprintf(stderr, "unknown option\n"); + else if (optind == 1) + fprintf(stderr, "missing option\n"); +out: + udev_ctrl_unref(uctrl); + return rc; +} + +const struct udevadm_cmd udevadm_control = { + .name = "control", + .cmd = adm_control, + .help = "control the udev daemon", +}; diff --git a/src/udev/udevadm-hwdb.c b/src/udev/udevadm-hwdb.c new file mode 100644 index 000000000..00c0d3d4c --- /dev/null +++ b/src/udev/udevadm-hwdb.c @@ -0,0 +1,602 @@ +/*** + This file is part of systemd. + + Copyright 2012 Kay Sievers + + 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 . +***/ + +#include +#include +#include +#include + +#include "util.h" +#include "strbuf.h" +#include "conf-files.h" + +#include "udev.h" +#include "libudev-hwdb-def.h" + +/* + * Generic udev properties, key/value database based on modalias strings. + * Uses a Patricia/radix trie to index all matches for efficient lookup. + */ + +static const char * const conf_file_dirs[] = { + "/etc/udev/hwdb.d", + UDEVLIBEXECDIR "/hwdb.d", + NULL +}; + +/* in-memory trie objects */ +struct trie { + struct trie_node *root; + struct strbuf *strings; + + size_t nodes_count; + size_t children_count; + size_t values_count; +}; + +struct trie_node { + /* prefix, common part for all children of this node */ + size_t prefix_off; + + /* sorted array of pointers to children nodes */ + struct trie_child_entry *children; + uint8_t children_count; + + /* sorted array of key/value pairs */ + struct trie_value_entry *values; + size_t values_count; +}; + +/* children array item with char (0-255) index */ +struct trie_child_entry { + uint8_t c; + struct trie_node *child; +}; + +/* value array item with key/value pairs */ +struct trie_value_entry { + size_t key_off; + size_t value_off; +}; + +static int trie_children_cmp(const void *v1, const void *v2) { + const struct trie_child_entry *n1 = v1; + const struct trie_child_entry *n2 = v2; + + return n1->c - n2->c; +} + +static int node_add_child(struct trie *trie, struct trie_node *node, struct trie_node *node_child, uint8_t c) { + struct trie_child_entry *child; + int err = 0; + + /* extend array, add new entry, sort for bisection */ + child = realloc(node->children, (node->children_count + 1) * sizeof(struct trie_child_entry)); + if (!child) { + err = -ENOMEM; + goto out; + } + node->children = child; + trie->children_count++; + node->children[node->children_count].c = c; + node->children[node->children_count].child = node_child; + node->children_count++; + qsort(node->children, node->children_count, sizeof(struct trie_child_entry), trie_children_cmp); + trie->nodes_count++; +out: + return err; +} + +static struct trie_node *node_lookup(const struct trie_node *node, uint8_t c) { + struct trie_child_entry *child; + struct trie_child_entry search; + + search.c = c; + child = bsearch(&search, node->children, node->children_count, sizeof(struct trie_child_entry), trie_children_cmp); + if (child) + return child->child; + return NULL; +} + +static void trie_node_cleanup(struct trie_node *node) { + size_t i; + + for (i = 0; i < node->children_count; i++) + trie_node_cleanup(node->children[i].child); + free(node->children); + free(node->values); + free(node); +} + +static int trie_values_cmp(const void *v1, const void *v2, void *arg) { + const struct trie_value_entry *val1 = v1; + const struct trie_value_entry *val2 = v2; + struct trie *trie = arg; + + return strcmp(trie->strings->buf + val1->key_off, + trie->strings->buf + val2->key_off); +} + +static int trie_node_add_value(struct trie *trie, struct trie_node *node, + const char *key, const char *value) { + ssize_t k, v; + struct trie_value_entry *val; + + k = strbuf_add_string(trie->strings, key, strlen(key)); + if (k < 0) + return k; + v = strbuf_add_string(trie->strings, value, strlen(value)); + if (v < 0) + return v; + + if (node->values_count) { + struct trie_value_entry search = { + .key_off = k, + .value_off = v, + }; + + val = xbsearch_r(&search, node->values, node->values_count, sizeof(struct trie_value_entry), trie_values_cmp, trie); + if (val) { + /* replace existing earlier key with new value */ + val->value_off = v; + return 0; + } + } + + /* extend array, add new entry, sort for bisection */ + val = realloc(node->values, (node->values_count + 1) * sizeof(struct trie_value_entry)); + if (!val) + return -ENOMEM; + trie->values_count++; + node->values = val; + node->values[node->values_count].key_off = k; + node->values[node->values_count].value_off = v; + node->values_count++; + qsort_r(node->values, node->values_count, sizeof(struct trie_value_entry), trie_values_cmp, trie); + return 0; +} + +static int trie_insert(struct trie *trie, struct trie_node *node, const char *search, + const char *key, const char *value) { + size_t i = 0; + int err = 0; + + for (;;) { + size_t p; + uint8_t c; + struct trie_node *child; + + for (p = 0; (c = trie->strings->buf[node->prefix_off + p]); p++) { + char *s; + ssize_t off; + + if (c == search[i + p]) + continue; + + /* split node */ + child = calloc(sizeof(struct trie_node), 1); + if (!child) { + err = -ENOMEM; + goto out; + } + + /* move values from parent to child */ + child->prefix_off = node->prefix_off + p+1; + child->children = node->children; + child->children_count = node->children_count; + child->values = node->values; + child->values_count = node->values_count; + + /* update parent; use strdup() because the source gets realloc()d */ + s = strndup(trie->strings->buf + node->prefix_off, p); + if (!s) { + err = -ENOMEM; + goto out; + } + off = strbuf_add_string(trie->strings, s, p); + free(s); + if (off < 0) { + err = off; + goto out; + } + node->prefix_off = off; + node->children = NULL; + node->children_count = 0; + node->values = NULL; + node->values_count = 0; + err = node_add_child(trie, node, child, c); + if (err) + goto out; + break; + } + i += p; + + c = search[i]; + if (c == '\0') + return trie_node_add_value(trie, node, key, value); + + child = node_lookup(node, c); + if (!child) { + ssize_t off; + + /* new child */ + child = calloc(sizeof(struct trie_node), 1); + if (!child) { + err = -ENOMEM; + goto out; + } + off = strbuf_add_string(trie->strings, search + i+1, strlen(search + i+1)); + if (off < 0) { + err = off; + goto out; + } + child->prefix_off = off; + err = node_add_child(trie, node, child, c); + if (err) + goto out; + return trie_node_add_value(trie, child, key, value); + } + + node = child; + i++; + } +out: + return err; +} + +struct trie_f { + FILE *f; + struct trie *trie; + uint64_t strings_off; + + uint64_t nodes_count; + uint64_t children_count; + uint64_t values_count; +}; + +/* calculate the storage space for the nodes, children arrays, value arrays */ +static void trie_store_nodes_size(struct trie_f *trie, struct trie_node *node) { + uint64_t i; + + for (i = 0; i < node->children_count; i++) + trie_store_nodes_size(trie, node->children[i].child); + + trie->strings_off += sizeof(struct trie_node_f); + for (i = 0; i < node->children_count; i++) + trie->strings_off += sizeof(struct trie_child_entry_f); + for (i = 0; i < node->values_count; i++) + trie->strings_off += sizeof(struct trie_value_entry_f); +} + +static int64_t trie_store_nodes(struct trie_f *trie, struct trie_node *node) { + uint64_t i; + struct trie_node_f n = { + .prefix_off = htole64(trie->strings_off + node->prefix_off), + .children_count = node->children_count, + .values_count = htole64(node->values_count), + }; + struct trie_child_entry_f *children = NULL; + int64_t node_off; + + if (node->children_count) { + children = new0(struct trie_child_entry_f, node->children_count); + if (!children) + return -ENOMEM; + } + + /* post-order recursion */ + for (i = 0; i < node->children_count; i++) { + int64_t child_off; + + child_off = trie_store_nodes(trie, node->children[i].child); + if (child_off < 0) + return child_off; + children[i].c = node->children[i].c; + children[i].child_off = htole64(child_off); + } + + /* write node */ + node_off = ftello(trie->f); + fwrite(&n, sizeof(struct trie_node_f), 1, trie->f); + trie->nodes_count++; + + /* append children array */ + if (node->children_count) { + fwrite(children, sizeof(struct trie_child_entry_f), node->children_count, trie->f); + trie->children_count += node->children_count; + free(children); + } + + /* append values array */ + for (i = 0; i < node->values_count; i++) { + struct trie_value_entry_f v = { + .key_off = htole64(trie->strings_off + node->values[i].key_off), + .value_off = htole64(trie->strings_off + node->values[i].value_off), + }; + + fwrite(&v, sizeof(struct trie_value_entry_f), 1, trie->f); + trie->values_count++; + } + + return node_off; +} + +static int trie_store(struct trie *trie, const char *filename) { + struct trie_f t = { + .trie = trie, + }; + char *filename_tmp; + int64_t pos; + int64_t root_off; + int64_t size; + struct trie_header_f h = { + .signature = HWDB_SIG, + .tool_version = htole64(atoi(VERSION)), + .header_size = htole64(sizeof(struct trie_header_f)), + .node_size = htole64(sizeof(struct trie_node_f)), + .child_entry_size = htole64(sizeof(struct trie_child_entry_f)), + .value_entry_size = htole64(sizeof(struct trie_value_entry_f)), + }; + int err; + + /* calculate size of header, nodes, children entries, value entries */ + t.strings_off = sizeof(struct trie_header_f); + trie_store_nodes_size(&t, trie->root); + + err = fopen_temporary(filename , &t.f, &filename_tmp); + if (err < 0) + return err; + fchmod(fileno(t.f), 0444); + + /* write nodes */ + fseeko(t.f, sizeof(struct trie_header_f), SEEK_SET); + root_off = trie_store_nodes(&t, trie->root); + h.nodes_root_off = htole64(root_off); + pos = ftello(t.f); + h.nodes_len = htole64(pos - sizeof(struct trie_header_f)); + + /* write string buffer */ + fwrite(trie->strings->buf, trie->strings->len, 1, t.f); + h.strings_len = htole64(trie->strings->len); + + /* write header */ + size = ftello(t.f); + h.file_size = htole64(size); + fseeko(t.f, 0, SEEK_SET); + fwrite(&h, sizeof(struct trie_header_f), 1, t.f); + err = ferror(t.f); + if (err) + err = -errno; + fclose(t.f); + if (err < 0 || rename(filename_tmp, filename) < 0) { + unlink(filename_tmp); + goto out; + } + + log_debug("=== trie on-disk ===\n"); + log_debug("size: %8llu bytes\n", (unsigned long long)size); + log_debug("header: %8zu bytes\n", sizeof(struct trie_header_f)); + log_debug("nodes: %8llu bytes (%8llu)\n", + (unsigned long long)t.nodes_count * sizeof(struct trie_node_f), (unsigned long long)t.nodes_count); + log_debug("child pointers: %8llu bytes (%8llu)\n", + (unsigned long long)t.children_count * sizeof(struct trie_child_entry_f), (unsigned long long)t.children_count); + log_debug("value pointers: %8llu bytes (%8llu)\n", + (unsigned long long)t.values_count * sizeof(struct trie_value_entry_f), (unsigned long long)t.values_count); + log_debug("string store: %8llu bytes\n", (unsigned long long)trie->strings->len); + log_debug("strings start: %8llu\n", (unsigned long long) t.strings_off); +out: + free(filename_tmp); + return err; +} + +static int import_file(struct trie *trie, const char *filename) { + FILE *f; + char line[LINE_MAX]; + char match[LINE_MAX]; + char cond[LINE_MAX]; + + f = fopen(filename, "re"); + if (f == NULL) + return -errno; + + match[0] = '\0'; + cond[0] = '\0'; + while (fgets(line, sizeof(line), f)) { + size_t len; + + if (line[0] == '#') + continue; + + /* new line, new record */ + if (line[0] == '\n') { + match[0] = '\0'; + cond[0] = '\0'; + continue; + } + + /* remove newline */ + len = strlen(line); + if (len < 2) + continue; + line[len-1] = '\0'; + + /* start of new record */ + if (match[0] == '\0') { + strcpy(match, line); + cond[0] = '\0'; + continue; + } + + if (line[0] == '+') { + strcpy(cond, line); + continue; + } + + /* TODO: support +; skip the entire record until we support it */ + if (cond[0] != '\0') + continue; + + /* value lines */ + if (line[0] == ' ') { + char *value; + + value = strchr(line, '='); + if (!value) + continue; + value[0] = '\0'; + value++; + trie_insert(trie, trie->root, match, line, value); + } + } + fclose(f); + return 0; +} + +static void help(void) { + printf("Usage: udevadm hwdb OPTIONS\n" + " --update update the hardware database\n" + " --test query database and print result\n" + " --help\n\n"); +} + +static int adm_hwdb(struct udev *udev, int argc, char *argv[]) { + static const struct option options[] = { + { "update", no_argument, NULL, 'u' }, + { "test", required_argument, NULL, 't' }, + { "help", no_argument, NULL, 'h' }, + {} + }; + const char *test = NULL; + bool update = false; + struct trie *trie = NULL; + int err; + int rc = EXIT_SUCCESS; + + for (;;) { + int option; + + option = getopt_long(argc, argv, "ut:h", options, NULL); + if (option == -1) + break; + + switch (option) { + case 'u': + update = true; + break; + case 't': + test = optarg; + break; + case 'h': + help(); + return EXIT_SUCCESS; + } + } + + if (!update && !test) { + help(); + return EXIT_SUCCESS; + } + + if (update) { + char **files, **f; + + trie = calloc(sizeof(struct trie), 1); + if (!trie) { + rc = EXIT_FAILURE; + goto out; + } + + /* string store */ + trie->strings = strbuf_new(); + if (!trie->strings) { + rc = EXIT_FAILURE; + goto out; + } + + /* index */ + trie->root = calloc(sizeof(struct trie_node), 1); + if (!trie->root) { + rc = EXIT_FAILURE; + goto out; + } + trie->nodes_count++; + + err = conf_files_list_strv(&files, ".hwdb", (const char **)conf_file_dirs); + if (err < 0) { + log_error("failed to enumerate hwdb files: %s\n", strerror(-err)); + rc = EXIT_FAILURE; + goto out; + } + STRV_FOREACH(f, files) { + log_debug("reading file '%s'", *f); + import_file(trie, *f); + } + strv_free(files); + + strbuf_complete(trie->strings); + + log_debug("=== trie in-memory ===\n"); + log_debug("nodes: %8zu bytes (%8zu)\n", + trie->nodes_count * sizeof(struct trie_node), trie->nodes_count); + log_debug("children arrays: %8zu bytes (%8zu)\n", + trie->children_count * sizeof(struct trie_child_entry), trie->children_count); + log_debug("values arrays: %8zu bytes (%8zu)\n", + trie->values_count * sizeof(struct trie_value_entry), trie->values_count); + log_debug("strings: %8zu bytes\n", + trie->strings->len); + log_debug("strings incoming: %8zu bytes (%8zu)\n", + trie->strings->in_len, trie->strings->in_count); + log_debug("strings dedup'ed: %8zu bytes (%8zu)\n", + trie->strings->dedup_len, trie->strings->dedup_count); + + mkdir_parents(HWDB_BIN, 0755); + err = trie_store(trie, HWDB_BIN); + if (err < 0) { + log_error("Failure writing hardware database '%s': %s", + HWDB_BIN, strerror(-err)); + rc = EXIT_FAILURE; + } + } + + if (test) { + struct udev_hwdb *hwdb = udev_hwdb_new(udev); + + if (hwdb) { + struct udev_list_entry *entry; + + udev_list_entry_foreach(entry, udev_hwdb_get_properties_list_entry(hwdb, test, 0)) + printf("%s=%s\n", udev_list_entry_get_name(entry), udev_list_entry_get_value(entry)); + hwdb = udev_hwdb_unref(hwdb); + } + } +out: + if (trie) { + if (trie->root) + trie_node_cleanup(trie->root); + strbuf_cleanup(trie->strings); + free(trie); + } + return rc; +} + +const struct udevadm_cmd udevadm_hwdb = { + .name = "hwdb", + .cmd = adm_hwdb, + .help = "maintain the hardware database index", +}; diff --git a/src/udev/udevadm-info.c b/src/udev/udevadm-info.c new file mode 100644 index 000000000..95f077ca9 --- /dev/null +++ b/src/udev/udevadm-info.c @@ -0,0 +1,550 @@ +/* + * Copyright (C) 2004-2009 Kay Sievers + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "udev.h" + +static bool skip_attribute(const char *name) +{ + static const char const *skip[] = { + "uevent", + "dev", + "modalias", + "resource", + "driver", + "subsystem", + "module", + }; + unsigned int i; + + for (i = 0; i < ELEMENTSOF(skip); i++) + if (strcmp(name, skip[i]) == 0) + return true; + return false; +} + +static void print_all_attributes(struct udev_device *device, const char *key) +{ + struct udev_list_entry *sysattr; + + udev_list_entry_foreach(sysattr, udev_device_get_sysattr_list_entry(device)) { + const char *name; + const char *value; + size_t len; + + name = udev_list_entry_get_name(sysattr); + if (skip_attribute(name)) + continue; + + value = udev_device_get_sysattr_value(device, name); + if (value == NULL) + continue; + + /* skip any values that look like a path */ + if (value[0] == '/') + continue; + + /* skip nonprintable attributes */ + len = strlen(value); + while (len > 0 && isprint(value[len-1])) + len--; + if (len > 0) + continue; + + printf(" %s{%s}==\"%s\"\n", key, name, value); + } + printf("\n"); +} + +static int print_device_chain(struct udev_device *device) +{ + struct udev_device *device_parent; + const char *str; + + printf("\n" + "Udevadm info starts with the device specified by the devpath and then\n" + "walks up the chain of parent devices. It prints for every device\n" + "found, all possible attributes in the udev rules key format.\n" + "A rule to match, can be composed by the attributes of the device\n" + "and the attributes from one single parent device.\n" + "\n"); + + printf(" looking at device '%s':\n", udev_device_get_devpath(device)); + printf(" KERNEL==\"%s\"\n", udev_device_get_sysname(device)); + str = udev_device_get_subsystem(device); + if (str == NULL) + str = ""; + printf(" SUBSYSTEM==\"%s\"\n", str); + str = udev_device_get_driver(device); + if (str == NULL) + str = ""; + printf(" DRIVER==\"%s\"\n", str); + print_all_attributes(device, "ATTR"); + + device_parent = device; + do { + device_parent = udev_device_get_parent(device_parent); + if (device_parent == NULL) + break; + printf(" looking at parent device '%s':\n", udev_device_get_devpath(device_parent)); + printf(" KERNELS==\"%s\"\n", udev_device_get_sysname(device_parent)); + str = udev_device_get_subsystem(device_parent); + if (str == NULL) + str = ""; + printf(" SUBSYSTEMS==\"%s\"\n", str); + str = udev_device_get_driver(device_parent); + if (str == NULL) + str = ""; + printf(" DRIVERS==\"%s\"\n", str); + print_all_attributes(device_parent, "ATTRS"); + } while (device_parent != NULL); + + return 0; +} + +static void print_record(struct udev_device *device) +{ + const char *str; + int i; + struct udev_list_entry *list_entry; + + printf("P: %s\n", udev_device_get_devpath(device)); + + str = udev_device_get_devnode(device); + if (str != NULL) + printf("N: %s\n", str + strlen("/dev/")); + + i = udev_device_get_devlink_priority(device); + if (i != 0) + printf("L: %i\n", i); + + udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(device)) + printf("S: %s\n", udev_list_entry_get_name(list_entry) + strlen("/dev/")); + + udev_list_entry_foreach(list_entry, udev_device_get_properties_list_entry(device)) + printf("E: %s=%s\n", + udev_list_entry_get_name(list_entry), + udev_list_entry_get_value(list_entry)); + printf("\n"); +} + +static int stat_device(const char *name, bool export, const char *prefix) +{ + struct stat statbuf; + + if (stat(name, &statbuf) != 0) + return -1; + + if (export) { + if (prefix == NULL) + prefix = "INFO_"; + printf("%sMAJOR=%d\n" + "%sMINOR=%d\n", + prefix, major(statbuf.st_dev), + prefix, minor(statbuf.st_dev)); + } else + printf("%d:%d\n", major(statbuf.st_dev), minor(statbuf.st_dev)); + return 0; +} + +static int export_devices(struct udev *udev) +{ + struct udev_enumerate *udev_enumerate; + struct udev_list_entry *list_entry; + + udev_enumerate = udev_enumerate_new(udev); + if (udev_enumerate == NULL) + return -1; + udev_enumerate_scan_devices(udev_enumerate); + udev_list_entry_foreach(list_entry, udev_enumerate_get_list_entry(udev_enumerate)) { + struct udev_device *device; + + device = udev_device_new_from_syspath(udev, udev_list_entry_get_name(list_entry)); + if (device != NULL) { + print_record(device); + udev_device_unref(device); + } + } + udev_enumerate_unref(udev_enumerate); + return 0; +} + +static void cleanup_dir(DIR *dir, mode_t mask, int depth) +{ + struct dirent *dent; + + if (depth <= 0) + return; + + for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) { + struct stat stats; + + if (dent->d_name[0] == '.') + continue; + if (fstatat(dirfd(dir), dent->d_name, &stats, AT_SYMLINK_NOFOLLOW) != 0) + continue; + if ((stats.st_mode & mask) != 0) + continue; + if (S_ISDIR(stats.st_mode)) { + DIR *dir2; + + dir2 = fdopendir(openat(dirfd(dir), dent->d_name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC)); + if (dir2 != NULL) { + cleanup_dir(dir2, mask, depth-1); + closedir(dir2); + } + unlinkat(dirfd(dir), dent->d_name, AT_REMOVEDIR); + } else { + unlinkat(dirfd(dir), dent->d_name, 0); + } + } +} + +static void cleanup_db(struct udev *udev) +{ + DIR *dir; + + unlink("/run/udev/queue.bin"); + + dir = opendir("/run/udev/data"); + if (dir != NULL) { + cleanup_dir(dir, S_ISVTX, 1); + closedir(dir); + } + + dir = opendir("/run/udev/links"); + if (dir != NULL) { + cleanup_dir(dir, 0, 2); + closedir(dir); + } + + dir = opendir("/run/udev/tags"); + if (dir != NULL) { + cleanup_dir(dir, 0, 2); + closedir(dir); + } + + dir = opendir("/run/udev/watch"); + if (dir != NULL) { + cleanup_dir(dir, 0, 1); + closedir(dir); + } + + dir = opendir("/run/udev/firmware-missing"); + if (dir != NULL) { + cleanup_dir(dir, 0, 1); + closedir(dir); + } +} + +static struct udev_device *find_device(struct udev *udev, const char *id, const char *prefix) +{ + char name[UTIL_PATH_SIZE]; + + if (prefix && !startswith(id, prefix)) { + util_strscpyl(name, sizeof(name), prefix, id, NULL); + id = name; + } + + if (startswith(id, "/dev/")) { + struct stat statbuf; + char type; + + if (stat(id, &statbuf) < 0) + return NULL; + + if (S_ISBLK(statbuf.st_mode)) + type = 'b'; + else if (S_ISCHR(statbuf.st_mode)) + type = 'c'; + else + return NULL; + + return udev_device_new_from_devnum(udev, type, statbuf.st_rdev); + } else if (startswith(id, "/sys/")) + return udev_device_new_from_syspath(udev, id); + else + return NULL; +} + +static int uinfo(struct udev *udev, int argc, char *argv[]) +{ + struct udev_device *device = NULL; + bool root = 0; + bool export = 0; + const char *export_prefix = NULL; + char name[UTIL_PATH_SIZE]; + struct udev_list_entry *list_entry; + int rc = 0; + + static const struct option options[] = { + { "name", required_argument, NULL, 'n' }, + { "path", required_argument, NULL, 'p' }, + { "query", required_argument, NULL, 'q' }, + { "attribute-walk", no_argument, NULL, 'a' }, + { "cleanup-db", no_argument, NULL, 'c' }, + { "export-db", no_argument, NULL, 'e' }, + { "root", no_argument, NULL, 'r' }, + { "device-id-of-file", required_argument, NULL, 'd' }, + { "export", no_argument, NULL, 'x' }, + { "export-prefix", required_argument, NULL, 'P' }, + { "version", no_argument, NULL, 'V' }, + { "help", no_argument, NULL, 'h' }, + {} + }; + + static const char *usage = + "Usage: udevadm info OPTIONS\n" + " --query= query device information:\n" + " name name of device node\n" + " symlink pointing to node\n" + " path sys device path\n" + " property the device properties\n" + " all all values\n" + " --path= sys device path used for query or attribute walk\n" + " --name= node or symlink name used for query or attribute walk\n" + " --root prepend dev directory to path names\n" + " --attribute-walk print all key matches while walking along the chain\n" + " of parent devices\n" + " --device-id-of-file= print major:minor of device containing this file\n" + " --export export key/value pairs\n" + " --export-prefix export the key name with a prefix\n" + " --export-db export the content of the udev database\n" + " --cleanup-db cleanup the udev database\n" + " --help\n"; + + enum action_type { + ACTION_QUERY, + ACTION_ATTRIBUTE_WALK, + ACTION_DEVICE_ID_FILE, + } action = ACTION_QUERY; + + enum query_type { + QUERY_NAME, + QUERY_PATH, + QUERY_SYMLINK, + QUERY_PROPERTY, + QUERY_ALL, + } query = QUERY_ALL; + + for (;;) { + int option; + + option = getopt_long(argc, argv, "aced:n:p:q:rxP:RVh", options, NULL); + if (option == -1) + break; + + switch (option) { + case 'n': { + if (device != NULL) { + fprintf(stderr, "device already specified\n"); + rc = 2; + goto exit; + } + + device = find_device(udev, optarg, "/dev/"); + if (device == NULL) { + fprintf(stderr, "device node not found\n"); + rc = 2; + goto exit; + } + break; + } + case 'p': + if (device != NULL) { + fprintf(stderr, "device already specified\n"); + rc = 2; + goto exit; + } + + device = find_device(udev, optarg, "/sys"); + if (device == NULL) { + fprintf(stderr, "syspath not found\n"); + rc = 2; + goto exit; + } + break; + case 'q': + action = ACTION_QUERY; + if (strcmp(optarg, "property") == 0 || strcmp(optarg, "env") == 0) { + query = QUERY_PROPERTY; + } else if (strcmp(optarg, "name") == 0) { + query = QUERY_NAME; + } else if (strcmp(optarg, "symlink") == 0) { + query = QUERY_SYMLINK; + } else if (strcmp(optarg, "path") == 0) { + query = QUERY_PATH; + } else if (strcmp(optarg, "all") == 0) { + query = QUERY_ALL; + } else { + fprintf(stderr, "unknown query type\n"); + rc = 3; + goto exit; + } + break; + case 'r': + root = true; + break; + case 'd': + action = ACTION_DEVICE_ID_FILE; + util_strscpy(name, sizeof(name), optarg); + break; + case 'a': + action = ACTION_ATTRIBUTE_WALK; + break; + case 'e': + export_devices(udev); + goto exit; + case 'c': + cleanup_db(udev); + goto exit; + case 'x': + export = true; + break; + case 'P': + export_prefix = optarg; + break; + case 'V': + printf("%s\n", VERSION); + goto exit; + case 'h': + printf("%s\n", usage); + goto exit; + default: + rc = 1; + goto exit; + } + } + + switch (action) { + case ACTION_QUERY: + if (!device) { + if (!argv[optind]) { + fprintf(stderr, "%s\n", usage); + rc = 2; + goto exit; + } + device = find_device(udev, argv[optind], NULL); + if (!device) { + fprintf(stderr, "Unknown device, --name=, --path=, or absolute path in /dev/ or /sys expected.\n"); + rc = 4; + goto exit; + } + } + + switch(query) { + case QUERY_NAME: { + const char *node = udev_device_get_devnode(device); + + if (node == NULL) { + fprintf(stderr, "no device node found\n"); + rc = 5; + goto exit; + } + + if (root) + printf("%s\n", udev_device_get_devnode(device)); + else + printf("%s\n", udev_device_get_devnode(device) + strlen("/dev/")); + break; + } + case QUERY_SYMLINK: + list_entry = udev_device_get_devlinks_list_entry(device); + while (list_entry != NULL) { + if (root) + printf("%s", udev_list_entry_get_name(list_entry)); + else + printf("%s", udev_list_entry_get_name(list_entry) + strlen("/dev/")); + list_entry = udev_list_entry_get_next(list_entry); + if (list_entry != NULL) + printf(" "); + } + printf("\n"); + break; + case QUERY_PATH: + printf("%s\n", udev_device_get_devpath(device)); + goto exit; + case QUERY_PROPERTY: + list_entry = udev_device_get_properties_list_entry(device); + while (list_entry != NULL) { + if (export) { + const char *prefix = export_prefix; + + if (prefix == NULL) + prefix = ""; + printf("%s%s='%s'\n", prefix, + udev_list_entry_get_name(list_entry), + udev_list_entry_get_value(list_entry)); + } else { + printf("%s=%s\n", udev_list_entry_get_name(list_entry), udev_list_entry_get_value(list_entry)); + } + list_entry = udev_list_entry_get_next(list_entry); + } + break; + case QUERY_ALL: + print_record(device); + break; + default: + fprintf(stderr, "unknown query type\n"); + break; + } + break; + case ACTION_ATTRIBUTE_WALK: + if (!device && argv[optind]) { + device = find_device(udev, argv[optind], NULL); + if (!device) { + fprintf(stderr, "Unknown device, absolute path in /dev/ or /sys expected.\n"); + rc = 4; + goto exit; + } + } + if (!device) { + fprintf(stderr, "Unknown device, --name=, --path=, or absolute path in /dev/ or /sys expected.\n"); + rc = 4; + goto exit; + } + print_device_chain(device); + break; + case ACTION_DEVICE_ID_FILE: + if (stat_device(name, export, export_prefix) != 0) + rc = 1; + break; + } + +exit: + udev_device_unref(device); + return rc; +} + +const struct udevadm_cmd udevadm_info = { + .name = "info", + .cmd = uinfo, + .help = "query sysfs or the udev database", +}; diff --git a/src/udev/udevadm-monitor.c b/src/udev/udevadm-monitor.c new file mode 100644 index 000000000..ffa70d830 --- /dev/null +++ b/src/udev/udevadm-monitor.c @@ -0,0 +1,297 @@ +/* + * Copyright (C) 2004-2010 Kay Sievers + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "udev.h" + +static bool udev_exit; + +static void sig_handler(int signum) +{ + if (signum == SIGINT || signum == SIGTERM) + udev_exit = true; +} + +static void print_device(struct udev_device *device, const char *source, int prop) +{ + struct timespec ts; + + clock_gettime(CLOCK_MONOTONIC, &ts); + printf("%-6s[%llu.%06u] %-8s %s (%s)\n", + source, + (unsigned long long) ts.tv_sec, (unsigned int) ts.tv_nsec/1000, + udev_device_get_action(device), + udev_device_get_devpath(device), + udev_device_get_subsystem(device)); + if (prop) { + struct udev_list_entry *list_entry; + + udev_list_entry_foreach(list_entry, udev_device_get_properties_list_entry(device)) + printf("%s=%s\n", + udev_list_entry_get_name(list_entry), + udev_list_entry_get_value(list_entry)); + printf("\n"); + } +} + +static int adm_monitor(struct udev *udev, int argc, char *argv[]) +{ + struct sigaction act; + sigset_t mask; + int option; + bool prop = false; + bool print_kernel = false; + bool print_udev = false; + struct udev_list subsystem_match_list; + struct udev_list tag_match_list; + struct udev_monitor *udev_monitor = NULL; + struct udev_monitor *kernel_monitor = NULL; + int fd_ep = -1; + int fd_kernel = -1, fd_udev = -1; + struct epoll_event ep_kernel, ep_udev; + int rc = 0; + + static const struct option options[] = { + { "property", no_argument, NULL, 'p' }, + { "environment", no_argument, NULL, 'e' }, + { "kernel", no_argument, NULL, 'k' }, + { "udev", no_argument, NULL, 'u' }, + { "subsystem-match", required_argument, NULL, 's' }, + { "tag-match", required_argument, NULL, 't' }, + { "help", no_argument, NULL, 'h' }, + {} + }; + + udev_list_init(udev, &subsystem_match_list, true); + udev_list_init(udev, &tag_match_list, true); + + for (;;) { + option = getopt_long(argc, argv, "pekus:t:h", options, NULL); + if (option == -1) + break; + + switch (option) { + case 'p': + case 'e': + prop = true; + break; + case 'k': + print_kernel = true; + break; + case 'u': + print_udev = true; + break; + case 's': + { + char subsys[UTIL_NAME_SIZE]; + char *devtype; + + util_strscpy(subsys, sizeof(subsys), optarg); + devtype = strchr(subsys, '/'); + if (devtype != NULL) { + devtype[0] = '\0'; + devtype++; + } + udev_list_entry_add(&subsystem_match_list, subsys, devtype); + break; + } + case 't': + udev_list_entry_add(&tag_match_list, optarg, NULL); + break; + case 'h': + printf("Usage: udevadm monitor [--property] [--kernel] [--udev] [--help]\n" + " --property print the event properties\n" + " --kernel print kernel uevents\n" + " --udev print udev events\n" + " --subsystem-match= filter events by subsystem\n" + " --tag-match= filter events by tag\n" + " --help\n\n"); + goto out; + default: + rc = 1; + goto out; + } + } + + if (!print_kernel && !print_udev) { + print_kernel = true; + print_udev = true; + } + + /* set signal handlers */ + memset(&act, 0x00, sizeof(struct sigaction)); + act.sa_handler = sig_handler; + sigemptyset(&act.sa_mask); + act.sa_flags = SA_RESTART; + sigaction(SIGINT, &act, NULL); + sigaction(SIGTERM, &act, NULL); + sigemptyset(&mask); + sigaddset(&mask, SIGINT); + sigaddset(&mask, SIGTERM); + sigprocmask(SIG_UNBLOCK, &mask, NULL); + + fd_ep = epoll_create1(EPOLL_CLOEXEC); + if (fd_ep < 0) { + log_error("error creating epoll fd: %m\n"); + goto out; + } + + printf("monitor will print the received events for:\n"); + if (print_udev) { + struct udev_list_entry *entry; + + udev_monitor = udev_monitor_new_from_netlink(udev, "udev"); + if (udev_monitor == NULL) { + fprintf(stderr, "error: unable to create netlink socket\n"); + rc = 1; + goto out; + } + udev_monitor_set_receive_buffer_size(udev_monitor, 128*1024*1024); + fd_udev = udev_monitor_get_fd(udev_monitor); + + udev_list_entry_foreach(entry, udev_list_get_entry(&subsystem_match_list)) { + const char *subsys = udev_list_entry_get_name(entry); + const char *devtype = udev_list_entry_get_value(entry); + + if (udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, subsys, devtype) < 0) + fprintf(stderr, "error: unable to apply subsystem filter '%s'\n", subsys); + } + + udev_list_entry_foreach(entry, udev_list_get_entry(&tag_match_list)) { + const char *tag = udev_list_entry_get_name(entry); + + if (udev_monitor_filter_add_match_tag(udev_monitor, tag) < 0) + fprintf(stderr, "error: unable to apply tag filter '%s'\n", tag); + } + + if (udev_monitor_enable_receiving(udev_monitor) < 0) { + fprintf(stderr, "error: unable to subscribe to udev events\n"); + rc = 2; + goto out; + } + + memset(&ep_udev, 0, sizeof(struct epoll_event)); + ep_udev.events = EPOLLIN; + ep_udev.data.fd = fd_udev; + if (epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_udev, &ep_udev) < 0) { + log_error("fail to add fd to epoll: %m\n"); + goto out; + } + + printf("UDEV - the event which udev sends out after rule processing\n"); + } + + if (print_kernel) { + struct udev_list_entry *entry; + + kernel_monitor = udev_monitor_new_from_netlink(udev, "kernel"); + if (kernel_monitor == NULL) { + fprintf(stderr, "error: unable to create netlink socket\n"); + rc = 3; + goto out; + } + udev_monitor_set_receive_buffer_size(kernel_monitor, 128*1024*1024); + fd_kernel = udev_monitor_get_fd(kernel_monitor); + + udev_list_entry_foreach(entry, udev_list_get_entry(&subsystem_match_list)) { + const char *subsys = udev_list_entry_get_name(entry); + + if (udev_monitor_filter_add_match_subsystem_devtype(kernel_monitor, subsys, NULL) < 0) + fprintf(stderr, "error: unable to apply subsystem filter '%s'\n", subsys); + } + + if (udev_monitor_enable_receiving(kernel_monitor) < 0) { + fprintf(stderr, "error: unable to subscribe to kernel events\n"); + rc = 4; + goto out; + } + + memset(&ep_kernel, 0, sizeof(struct epoll_event)); + ep_kernel.events = EPOLLIN; + ep_kernel.data.fd = fd_kernel; + if (epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_kernel, &ep_kernel) < 0) { + log_error("fail to add fd to epoll: %m\n"); + goto out; + } + + printf("KERNEL - the kernel uevent\n"); + } + printf("\n"); + + while (!udev_exit) { + int fdcount; + struct epoll_event ev[4]; + int i; + + fdcount = epoll_wait(fd_ep, ev, ELEMENTSOF(ev), -1); + if (fdcount < 0) { + if (errno != EINTR) + fprintf(stderr, "error receiving uevent message: %m\n"); + continue; + } + + for (i = 0; i < fdcount; i++) { + if (ev[i].data.fd == fd_kernel && ev[i].events & EPOLLIN) { + struct udev_device *device; + + device = udev_monitor_receive_device(kernel_monitor); + if (device == NULL) + continue; + print_device(device, "KERNEL", prop); + udev_device_unref(device); + } else if (ev[i].data.fd == fd_udev && ev[i].events & EPOLLIN) { + struct udev_device *device; + + device = udev_monitor_receive_device(udev_monitor); + if (device == NULL) + continue; + print_device(device, "UDEV", prop); + udev_device_unref(device); + } + } + } +out: + if (fd_ep >= 0) + close(fd_ep); + udev_monitor_unref(udev_monitor); + udev_monitor_unref(kernel_monitor); + udev_list_cleanup(&subsystem_match_list); + udev_list_cleanup(&tag_match_list); + return rc; +} + +const struct udevadm_cmd udevadm_monitor = { + .name = "monitor", + .cmd = adm_monitor, + .help = "listen to kernel and udev events", +}; diff --git a/src/udev/udevadm-settle.c b/src/udev/udevadm-settle.c new file mode 100644 index 000000000..c4fc4ee4e --- /dev/null +++ b/src/udev/udevadm-settle.c @@ -0,0 +1,232 @@ +/* + * Copyright (C) 2006-2009 Kay Sievers + * Copyright (C) 2009 Canonical Ltd. + * Copyright (C) 2009 Scott James Remnant + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "udev.h" + +static int adm_settle(struct udev *udev, int argc, char *argv[]) +{ + static const struct option options[] = { + { "seq-start", required_argument, NULL, 's' }, + { "seq-end", required_argument, NULL, 'e' }, + { "timeout", required_argument, NULL, 't' }, + { "exit-if-exists", required_argument, NULL, 'E' }, + { "quiet", no_argument, NULL, 'q' }, + { "help", no_argument, NULL, 'h' }, + {} + }; + usec_t start_usec = now(CLOCK_MONOTONIC); + usec_t start = 0; + usec_t end = 0; + int quiet = 0; + const char *exists = NULL; + unsigned int timeout = 120; + struct pollfd pfd[1] = { {.fd = -1}, }; + struct udev_queue *udev_queue = NULL; + int rc = EXIT_FAILURE; + + for (;;) { + int option; + int seconds; + + option = getopt_long(argc, argv, "s:e:t:E:qh", options, NULL); + if (option == -1) + break; + + switch (option) { + case 's': + start = strtoull(optarg, NULL, 0); + break; + case 'e': + end = strtoull(optarg, NULL, 0); + break; + case 't': + seconds = atoi(optarg); + if (seconds >= 0) + timeout = seconds; + else + fprintf(stderr, "invalid timeout value\n"); + break; + case 'q': + quiet = 1; + break; + case 'E': + exists = optarg; + break; + case 'h': + printf("Usage: udevadm settle OPTIONS\n" + " --timeout= maximum time to wait for events\n" + " --seq-start= first seqnum to wait for\n" + " --seq-end= last seqnum to wait for\n" + " --exit-if-exists= stop waiting if file exists\n" + " --quiet do not print list after timeout\n" + " --help\n\n"); + exit(EXIT_SUCCESS); + default: + exit(EXIT_FAILURE); + } + } + + udev_queue = udev_queue_new(udev); + if (udev_queue == NULL) + exit(2); + + if (start > 0) { + unsigned long long kernel_seq; + + kernel_seq = udev_queue_get_kernel_seqnum(udev_queue); + + /* unless specified, the last event is the current kernel seqnum */ + if (end == 0) + end = udev_queue_get_kernel_seqnum(udev_queue); + + if (start > end) { + log_error("seq-start larger than seq-end, ignoring\n"); + start = 0; + end = 0; + } + + if (start > kernel_seq || end > kernel_seq) { + log_error("seq-start or seq-end larger than current kernel value, ignoring\n"); + start = 0; + end = 0; + } + log_debug("start=%llu end=%llu current=%llu\n", (unsigned long long)start, (unsigned long long)end, kernel_seq); + } else { + if (end > 0) { + log_error("seq-end needs seq-start parameter, ignoring\n"); + end = 0; + } + } + + /* guarantee that the udev daemon isn't pre-processing */ + if (getuid() == 0) { + struct udev_ctrl *uctrl; + + uctrl = udev_ctrl_new(udev); + if (uctrl != NULL) { + if (udev_ctrl_send_ping(uctrl, timeout) < 0) { + log_debug("no connection to daemon\n"); + udev_ctrl_unref(uctrl); + rc = EXIT_SUCCESS; + goto out; + } + udev_ctrl_unref(uctrl); + } + } + + pfd[0].events = POLLIN; + pfd[0].fd = inotify_init1(IN_CLOEXEC); + if (pfd[0].fd < 0) { + log_error("inotify_init failed: %m\n"); + } else { + if (inotify_add_watch(pfd[0].fd, "/run/udev" , IN_MOVED_TO) < 0) { + log_error("watching /run/udev failed\n"); + close(pfd[0].fd); + pfd[0].fd = -1; + } + } + + for (;;) { + struct stat statbuf; + + if (exists != NULL && stat(exists, &statbuf) == 0) { + rc = EXIT_SUCCESS; + break; + } + + if (start > 0) { + /* if asked for, wait for a specific sequence of events */ + if (udev_queue_get_seqnum_sequence_is_finished(udev_queue, start, end) == 1) { + rc = EXIT_SUCCESS; + break; + } + } else { + /* exit if queue is empty */ + if (udev_queue_get_queue_is_empty(udev_queue)) { + rc = EXIT_SUCCESS; + break; + } + } + + if (pfd[0].fd >= 0) { + int delay; + + if (exists != NULL || start > 0) + delay = 100; + else + delay = 1000; + /* wake up after delay, or immediately after the queue is rebuilt */ + if (poll(pfd, 1, delay) > 0 && pfd[0].revents & POLLIN) { + char buf[sizeof(struct inotify_event) + PATH_MAX]; + + read(pfd[0].fd, buf, sizeof(buf)); + } + } else { + sleep(1); + } + + if (timeout > 0) { + usec_t age_usec; + + age_usec = now(CLOCK_MONOTONIC) - start_usec; + if (age_usec / (1000 * 1000) >= timeout) { + struct udev_list_entry *list_entry; + + if (!quiet && udev_queue_get_queued_list_entry(udev_queue) != NULL) { + log_debug("timeout waiting for udev queue\n"); + printf("\nudevadm settle - timeout of %i seconds reached, the event queue contains:\n", timeout); + udev_list_entry_foreach(list_entry, udev_queue_get_queued_list_entry(udev_queue)) + printf(" %s (%s)\n", + udev_list_entry_get_name(list_entry), + udev_list_entry_get_value(list_entry)); + } + + break; + } + } + } +out: + if (pfd[0].fd >= 0) + close(pfd[0].fd); + udev_queue_unref(udev_queue); + return rc; +} + +const struct udevadm_cmd udevadm_settle = { + .name = "settle", + .cmd = adm_settle, + .help = "wait for the event queue to finish", +}; diff --git a/src/udev/udevadm-test-builtin.c b/src/udev/udevadm-test-builtin.c new file mode 100644 index 000000000..9853d83b4 --- /dev/null +++ b/src/udev/udevadm-test-builtin.c @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2011 Kay Sievers + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "udev.h" + +static void help(struct udev *udev) +{ + fprintf(stderr, "\n"); + fprintf(stderr, "Usage: udevadm builtin [--help] \n"); + udev_builtin_list(udev); + fprintf(stderr, "\n"); +} + +static int adm_builtin(struct udev *udev, int argc, char *argv[]) +{ + static const struct option options[] = { + { "help", no_argument, NULL, 'h' }, + {} + }; + char *command = NULL; + char *syspath = NULL; + char filename[UTIL_PATH_SIZE]; + struct udev_device *dev = NULL; + enum udev_builtin_cmd cmd; + int rc = EXIT_SUCCESS; + + for (;;) { + int option; + + option = getopt_long(argc, argv, "h", options, NULL); + if (option == -1) + break; + + switch (option) { + case 'h': + help(udev); + goto out; + } + } + + command = argv[optind++]; + if (command == NULL) { + fprintf(stderr, "command missing\n"); + help(udev); + rc = 2; + goto out; + } + + syspath = argv[optind++]; + if (syspath == NULL) { + fprintf(stderr, "syspath missing\n\n"); + rc = 3; + goto out; + } + + udev_builtin_init(udev); + + cmd = udev_builtin_lookup(command); + if (cmd >= UDEV_BUILTIN_MAX) { + fprintf(stderr, "unknown command '%s'\n", command); + help(udev); + rc = 5; + goto out; + } + + /* add /sys if needed */ + if (!startswith(syspath, "/sys")) + util_strscpyl(filename, sizeof(filename), "/sys", syspath, NULL); + else + util_strscpy(filename, sizeof(filename), syspath); + util_remove_trailing_chars(filename, '/'); + + dev = udev_device_new_from_syspath(udev, filename); + if (dev == NULL) { + fprintf(stderr, "unable to open device '%s'\n\n", filename); + rc = 4; + goto out; + } + + rc = udev_builtin_run(dev, cmd, command, true); + if (rc < 0) { + fprintf(stderr, "error executing '%s', exit code %i\n\n", command, rc); + rc = 6; + } +out: + udev_device_unref(dev); + udev_builtin_exit(udev); + return rc; +} + +const struct udevadm_cmd udevadm_test_builtin = { + .name = "test-builtin", + .cmd = adm_builtin, + .help = "test a built-in command", + .debug = true, +}; diff --git a/src/udev/udevadm-test.c b/src/udev/udevadm-test.c new file mode 100644 index 000000000..2d8aa7913 --- /dev/null +++ b/src/udev/udevadm-test.c @@ -0,0 +1,172 @@ +/* + * Copyright (C) 2003-2004 Greg Kroah-Hartman + * Copyright (C) 2004-2008 Kay Sievers + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "udev.h" + +static int adm_test(struct udev *udev, int argc, char *argv[]) +{ + int resolve_names = 1; + char filename[UTIL_PATH_SIZE]; + const char *action = "add"; + const char *syspath = NULL; + struct udev_event *event = NULL; + struct udev_device *dev = NULL; + struct udev_rules *rules = NULL; + struct udev_list_entry *entry; + sigset_t mask, sigmask_orig; + int err; + int rc = 0; + + static const struct option options[] = { + { "action", required_argument, NULL, 'a' }, + { "resolve-names", required_argument, NULL, 'N' }, + { "help", no_argument, NULL, 'h' }, + {} + }; + + log_debug("version %s\n", VERSION); + + for (;;) { + int option; + + option = getopt_long(argc, argv, "a:s:N:fh", options, NULL); + if (option == -1) + break; + + switch (option) { + case 'a': + action = optarg; + break; + case 'N': + if (strcmp (optarg, "early") == 0) { + resolve_names = 1; + } else if (strcmp (optarg, "late") == 0) { + resolve_names = 0; + } else if (strcmp (optarg, "never") == 0) { + resolve_names = -1; + } else { + fprintf(stderr, "resolve-names must be early, late or never\n"); + log_error("resolve-names must be early, late or never\n"); + exit(EXIT_FAILURE); + } + break; + case 'h': + printf("Usage: udevadm test OPTIONS \n" + " --action= set action string\n" + " --help\n\n"); + exit(EXIT_SUCCESS); + default: + exit(EXIT_FAILURE); + } + } + syspath = argv[optind]; + + if (syspath == NULL) { + fprintf(stderr, "syspath parameter missing\n"); + rc = 2; + goto out; + } + + printf("This program is for debugging only, it does not run any program\n" + "specified by a RUN key. It may show incorrect results, because\n" + "some values may be different, or not available at a simulation run.\n" + "\n"); + + sigprocmask(SIG_SETMASK, NULL, &sigmask_orig); + + udev_builtin_init(udev); + + rules = udev_rules_new(udev, resolve_names); + if (rules == NULL) { + fprintf(stderr, "error reading rules\n"); + rc = 3; + goto out; + } + + /* add /sys if needed */ + if (!startswith(syspath, "/sys")) + util_strscpyl(filename, sizeof(filename), "/sys", syspath, NULL); + else + util_strscpy(filename, sizeof(filename), syspath); + util_remove_trailing_chars(filename, '/'); + + dev = udev_device_new_from_syspath(udev, filename); + if (dev == NULL) { + fprintf(stderr, "unable to open device '%s'\n", filename); + rc = 4; + goto out; + } + + /* skip reading of db, but read kernel parameters */ + udev_device_set_info_loaded(dev); + udev_device_read_uevent_file(dev); + + udev_device_set_action(dev, action); + event = udev_event_new(dev); + + sigfillset(&mask); + sigprocmask(SIG_SETMASK, &mask, &sigmask_orig); + event->fd_signal = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC); + if (event->fd_signal < 0) { + fprintf(stderr, "error creating signalfd\n"); + rc = 5; + goto out; + } + + err = udev_event_execute_rules(event, rules, &sigmask_orig); + + udev_list_entry_foreach(entry, udev_device_get_properties_list_entry(dev)) + printf("%s=%s\n", udev_list_entry_get_name(entry), udev_list_entry_get_value(entry)); + + if (err == 0) { + udev_list_entry_foreach(entry, udev_list_get_entry(&event->run_list)) { + char program[UTIL_PATH_SIZE]; + + udev_event_apply_format(event, udev_list_entry_get_name(entry), program, sizeof(program)); + printf("run: '%s'\n", program); + } + } +out: + if (event != NULL && event->fd_signal >= 0) + close(event->fd_signal); + udev_event_unref(event); + udev_device_unref(dev); + udev_rules_unref(rules); + udev_builtin_exit(udev); + return rc; +} + +const struct udevadm_cmd udevadm_test = { + .name = "test", + .cmd = adm_test, + .help = "test an event run", + .debug = true, +}; diff --git a/src/udev/udevadm-trigger.c b/src/udev/udevadm-trigger.c new file mode 100644 index 000000000..d52ae461f --- /dev/null +++ b/src/udev/udevadm-trigger.c @@ -0,0 +1,228 @@ +/* + * Copyright (C) 2008-2009 Kay Sievers + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "udev.h" + +static int verbose; +static int dry_run; + +static void exec_list(struct udev_enumerate *udev_enumerate, const char *action) +{ + struct udev_list_entry *entry; + + udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(udev_enumerate)) { + char filename[UTIL_PATH_SIZE]; + int fd; + + if (verbose) + printf("%s\n", udev_list_entry_get_name(entry)); + if (dry_run) + continue; + util_strscpyl(filename, sizeof(filename), udev_list_entry_get_name(entry), "/uevent", NULL); + fd = open(filename, O_WRONLY); + if (fd < 0) + continue; + if (write(fd, action, strlen(action)) < 0) + log_debug("error writing '%s' to '%s': %m\n", action, filename); + close(fd); + } +} + +static const char *keyval(const char *str, const char **val, char *buf, size_t size) +{ + char *pos; + + util_strscpy(buf, size,str); + pos = strchr(buf, '='); + if (pos != NULL) { + pos[0] = 0; + pos++; + } + *val = pos; + return buf; +} + +static int adm_trigger(struct udev *udev, int argc, char *argv[]) +{ + static const struct option options[] = { + { "verbose", no_argument, NULL, 'v' }, + { "dry-run", no_argument, NULL, 'n' }, + { "type", required_argument, NULL, 't' }, + { "action", required_argument, NULL, 'c' }, + { "subsystem-match", required_argument, NULL, 's' }, + { "subsystem-nomatch", required_argument, NULL, 'S' }, + { "attr-match", required_argument, NULL, 'a' }, + { "attr-nomatch", required_argument, NULL, 'A' }, + { "property-match", required_argument, NULL, 'p' }, + { "tag-match", required_argument, NULL, 'g' }, + { "sysname-match", required_argument, NULL, 'y' }, + { "parent-match", required_argument, NULL, 'b' }, + { "help", no_argument, NULL, 'h' }, + {} + }; + enum { + TYPE_DEVICES, + TYPE_SUBSYSTEMS, + } device_type = TYPE_DEVICES; + const char *action = "change"; + struct udev_enumerate *udev_enumerate; + int rc = 0; + + udev_enumerate = udev_enumerate_new(udev); + if (udev_enumerate == NULL) { + rc = 1; + goto exit; + } + + for (;;) { + int option; + const char *key; + const char *val; + char buf[UTIL_PATH_SIZE]; + + option = getopt_long(argc, argv, "vng:o:t:hc:p:s:S:a:A:y:b:", options, NULL); + if (option == -1) + break; + + switch (option) { + case 'v': + verbose = 1; + break; + case 'n': + dry_run = 1; + break; + case 't': + if (strcmp(optarg, "devices") == 0) { + device_type = TYPE_DEVICES; + } else if (strcmp(optarg, "subsystems") == 0) { + device_type = TYPE_SUBSYSTEMS; + } else { + log_error("unknown type --type=%s\n", optarg); + rc = 2; + goto exit; + } + break; + case 'c': + action = optarg; + break; + case 's': + udev_enumerate_add_match_subsystem(udev_enumerate, optarg); + break; + case 'S': + udev_enumerate_add_nomatch_subsystem(udev_enumerate, optarg); + break; + case 'a': + key = keyval(optarg, &val, buf, sizeof(buf)); + udev_enumerate_add_match_sysattr(udev_enumerate, key, val); + break; + case 'A': + key = keyval(optarg, &val, buf, sizeof(buf)); + udev_enumerate_add_nomatch_sysattr(udev_enumerate, key, val); + break; + case 'p': + key = keyval(optarg, &val, buf, sizeof(buf)); + udev_enumerate_add_match_property(udev_enumerate, key, val); + break; + case 'g': + udev_enumerate_add_match_tag(udev_enumerate, optarg); + break; + case 'y': + udev_enumerate_add_match_sysname(udev_enumerate, optarg); + break; + case 'b': { + char path[UTIL_PATH_SIZE]; + struct udev_device *dev; + + /* add sys dir if needed */ + if (!startswith(optarg, "/sys")) + util_strscpyl(path, sizeof(path), "/sys", optarg, NULL); + else + util_strscpy(path, sizeof(path), optarg); + util_remove_trailing_chars(path, '/'); + dev = udev_device_new_from_syspath(udev, path); + if (dev == NULL) { + log_error("unable to open the device '%s'\n", optarg); + rc = 2; + goto exit; + } + udev_enumerate_add_match_parent(udev_enumerate, dev); + /* drop reference immediately, enumerate pins the device as long as needed */ + udev_device_unref(dev); + break; + } + case 'h': + printf("Usage: udevadm trigger OPTIONS\n" + " --verbose print the list of devices while running\n" + " --dry-run do not actually trigger the events\n" + " --type= type of events to trigger\n" + " devices sys devices (default)\n" + " subsystems sys subsystems and drivers\n" + " --action= event action value, default is \"change\"\n" + " --subsystem-match= trigger devices from a matching subsystem\n" + " --subsystem-nomatch= exclude devices from a matching subsystem\n" + " --attr-match=]> trigger devices with a matching attribute\n" + " --attr-nomatch=]> exclude devices with a matching attribute\n" + " --property-match== trigger devices with a matching property\n" + " --tag-match== trigger devices with a matching property\n" + " --sysname-match= trigger devices with a matching name\n" + " --parent-match= trigger devices with that parent device\n" + " --help\n\n"); + goto exit; + default: + rc = 1; + goto exit; + } + } + + switch (device_type) { + case TYPE_SUBSYSTEMS: + udev_enumerate_scan_subsystems(udev_enumerate); + exec_list(udev_enumerate, action); + goto exit; + case TYPE_DEVICES: + udev_enumerate_scan_devices(udev_enumerate); + exec_list(udev_enumerate, action); + goto exit; + default: + goto exit; + } +exit: + udev_enumerate_unref(udev_enumerate); + return rc; +} + +const struct udevadm_cmd udevadm_trigger = { + .name = "trigger", + .cmd = adm_trigger, + .help = "request events from the kernel", +}; diff --git a/src/udev/udevadm.c b/src/udev/udevadm.c new file mode 100644 index 000000000..53419ffa6 --- /dev/null +++ b/src/udev/udevadm.c @@ -0,0 +1,152 @@ +/* + * Copyright (C) 2007-2012 Kay Sievers + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "udev.h" + +void udev_main_log(struct udev *udev, int priority, + const char *file, int line, const char *fn, + const char *format, va_list args) +{ + log_metav(priority, file, line, fn, format, args); +} + +static int adm_version(struct udev *udev, int argc, char *argv[]) +{ + printf("%s\n", VERSION); + return 0; +} + +static const struct udevadm_cmd udevadm_version = { + .name = "version", + .cmd = adm_version, +}; + +static int adm_help(struct udev *udev, int argc, char *argv[]); + +static const struct udevadm_cmd udevadm_help = { + .name = "help", + .cmd = adm_help, +}; + +static const struct udevadm_cmd *udevadm_cmds[] = { + &udevadm_info, + &udevadm_trigger, + &udevadm_settle, + &udevadm_control, + &udevadm_monitor, + &udevadm_hwdb, + &udevadm_test, + &udevadm_test_builtin, + &udevadm_version, + &udevadm_help, +}; + +static int adm_help(struct udev *udev, int argc, char *argv[]) +{ + unsigned int i; + + fprintf(stderr, "Usage: udevadm [--help] [--version] [--debug] COMMAND [COMMAND OPTIONS]\n"); + for (i = 0; i < ELEMENTSOF(udevadm_cmds); i++) + if (udevadm_cmds[i]->help != NULL) + printf(" %-12s %s\n", udevadm_cmds[i]->name, udevadm_cmds[i]->help); + fprintf(stderr, "\n"); + return 0; +} + +static int run_command(struct udev *udev, const struct udevadm_cmd *cmd, int argc, char *argv[]) +{ + if (cmd->debug) + log_set_max_level(LOG_DEBUG); + log_debug("calling: %s\n", cmd->name); + return cmd->cmd(udev, argc, argv); +} + +int main(int argc, char *argv[]) +{ + struct udev *udev; + static const struct option options[] = { + { "debug", no_argument, NULL, 'd' }, + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, 'V' }, + {} + }; + const char *command; + unsigned int i; + int rc = 1; + + udev = udev_new(); + if (udev == NULL) + goto out; + + log_parse_environment(); + log_open(); + udev_set_log_fn(udev, udev_main_log); + label_init("/dev"); + + for (;;) { + int option; + + option = getopt_long(argc, argv, "+dhV", options, NULL); + if (option == -1) + break; + + switch (option) { + case 'd': + log_set_max_level(LOG_DEBUG); + udev_set_log_priority(udev, LOG_DEBUG); + break; + case 'h': + rc = adm_help(udev, argc, argv); + goto out; + case 'V': + rc = adm_version(udev, argc, argv); + goto out; + default: + goto out; + } + } + command = argv[optind]; + + if (command != NULL) + for (i = 0; i < ELEMENTSOF(udevadm_cmds); i++) { + if (strcmp(udevadm_cmds[i]->name, command) == 0) { + argc -= optind; + argv += optind; + /* we need '0' here to reset the internal state */ + optind = 0; + rc = run_command(udev, udevadm_cmds[i], argc, argv); + goto out; + } + } + + fprintf(stderr, "missing or unknown command\n\n"); + adm_help(udev, argc, argv); + rc = 2; +out: + label_finish(); + udev_unref(udev); + log_close(); + return rc; +} diff --git a/src/udev/udevd.c b/src/udev/udevd.c new file mode 100644 index 000000000..ffc48a03b --- /dev/null +++ b/src/udev/udevd.c @@ -0,0 +1,1578 @@ +/* + * Copyright (C) 2004-2012 Kay Sievers + * Copyright (C) 2004 Chris Friesen + * Copyright (C) 2009 Canonical Ltd. + * Copyright (C) 2009 Scott James Remnant + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "udev.h" +#include "sd-daemon.h" +#include "cgroup-util.h" +#include "dev-setup.h" + +static bool debug; + +void udev_main_log(struct udev *udev, int priority, + const char *file, int line, const char *fn, + const char *format, va_list args) +{ + log_metav(priority, file, line, fn, format, args); +} + +static struct udev_rules *rules; +static struct udev_queue_export *udev_queue_export; +static struct udev_ctrl *udev_ctrl; +static struct udev_monitor *monitor; +static int worker_watch[2] = { -1, -1 }; +static int fd_signal = -1; +static int fd_ep = -1; +static int fd_inotify = -1; +static bool stop_exec_queue; +static bool reload; +static int children; +static int children_max; +static int exec_delay; +static sigset_t sigmask_orig; +static UDEV_LIST(event_list); +static UDEV_LIST(worker_list); +char *udev_cgroup; +static bool udev_exit; + +enum event_state { + EVENT_UNDEF, + EVENT_QUEUED, + EVENT_RUNNING, +}; + +struct event { + struct udev_list_node node; + struct udev *udev; + struct udev_device *dev; + enum event_state state; + int exitcode; + unsigned long long int delaying_seqnum; + unsigned long long int seqnum; + const char *devpath; + size_t devpath_len; + const char *devpath_old; + dev_t devnum; + int ifindex; + bool is_block; + bool nodelay; +}; + +static inline struct event *node_to_event(struct udev_list_node *node) +{ + return container_of(node, struct event, node); +} + +static void event_queue_cleanup(struct udev *udev, enum event_state type); + +enum worker_state { + WORKER_UNDEF, + WORKER_RUNNING, + WORKER_IDLE, + WORKER_KILLED, +}; + +struct worker { + struct udev_list_node node; + struct udev *udev; + int refcount; + pid_t pid; + struct udev_monitor *monitor; + enum worker_state state; + struct event *event; + usec_t event_start_usec; +}; + +/* passed from worker to main process */ +struct worker_message { + pid_t pid; + int exitcode; +}; + +static inline struct worker *node_to_worker(struct udev_list_node *node) +{ + return container_of(node, struct worker, node); +} + +static void event_queue_delete(struct event *event, bool export) +{ + udev_list_node_remove(&event->node); + + if (export) { + udev_queue_export_device_finished(udev_queue_export, event->dev); + log_debug("seq %llu done with %i\n", udev_device_get_seqnum(event->dev), event->exitcode); + } + udev_device_unref(event->dev); + free(event); +} + +static struct worker *worker_ref(struct worker *worker) +{ + worker->refcount++; + return worker; +} + +static void worker_cleanup(struct worker *worker) +{ + udev_list_node_remove(&worker->node); + udev_monitor_unref(worker->monitor); + children--; + free(worker); +} + +static void worker_unref(struct worker *worker) +{ + worker->refcount--; + if (worker->refcount > 0) + return; + log_debug("worker [%u] cleaned up\n", worker->pid); + worker_cleanup(worker); +} + +static void worker_list_cleanup(struct udev *udev) +{ + struct udev_list_node *loop, *tmp; + + udev_list_node_foreach_safe(loop, tmp, &worker_list) { + struct worker *worker = node_to_worker(loop); + + worker_cleanup(worker); + } +} + +static void worker_new(struct event *event) +{ + struct udev *udev = event->udev; + struct worker *worker; + struct udev_monitor *worker_monitor; + pid_t pid; + + /* listen for new events */ + worker_monitor = udev_monitor_new_from_netlink(udev, NULL); + if (worker_monitor == NULL) + return; + /* allow the main daemon netlink address to send devices to the worker */ + udev_monitor_allow_unicast_sender(worker_monitor, monitor); + udev_monitor_enable_receiving(worker_monitor); + + worker = calloc(1, sizeof(struct worker)); + if (worker == NULL) { + udev_monitor_unref(worker_monitor); + return; + } + /* worker + event reference */ + worker->refcount = 2; + worker->udev = udev; + + pid = fork(); + switch (pid) { + case 0: { + struct udev_device *dev = NULL; + int fd_monitor; + struct epoll_event ep_signal, ep_monitor; + sigset_t mask; + int rc = EXIT_SUCCESS; + + /* take initial device from queue */ + dev = event->dev; + event->dev = NULL; + + free(worker); + worker_list_cleanup(udev); + event_queue_cleanup(udev, EVENT_UNDEF); + udev_queue_export_unref(udev_queue_export); + udev_monitor_unref(monitor); + udev_ctrl_unref(udev_ctrl); + close(fd_signal); + close(fd_ep); + close(worker_watch[READ_END]); + + sigfillset(&mask); + fd_signal = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC); + if (fd_signal < 0) { + log_error("error creating signalfd %m\n"); + rc = 2; + goto out; + } + + fd_ep = epoll_create1(EPOLL_CLOEXEC); + if (fd_ep < 0) { + log_error("error creating epoll fd: %m\n"); + rc = 3; + goto out; + } + + memset(&ep_signal, 0, sizeof(struct epoll_event)); + ep_signal.events = EPOLLIN; + ep_signal.data.fd = fd_signal; + + fd_monitor = udev_monitor_get_fd(worker_monitor); + memset(&ep_monitor, 0, sizeof(struct epoll_event)); + ep_monitor.events = EPOLLIN; + ep_monitor.data.fd = fd_monitor; + + if (epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_signal, &ep_signal) < 0 || + epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_monitor, &ep_monitor) < 0) { + log_error("fail to add fds to epoll: %m\n"); + rc = 4; + goto out; + } + + /* request TERM signal if parent exits */ + prctl(PR_SET_PDEATHSIG, SIGTERM); + + /* reset OOM score, we only protect the main daemon */ + write_one_line_file("/proc/self/oom_score_adj", "0"); + + for (;;) { + struct udev_event *udev_event; + struct worker_message msg; + int err; + + log_debug("seq %llu running\n", udev_device_get_seqnum(dev)); + udev_event = udev_event_new(dev); + if (udev_event == NULL) { + rc = 5; + goto out; + } + + /* needed for SIGCHLD/SIGTERM in spawn() */ + udev_event->fd_signal = fd_signal; + + if (exec_delay > 0) + udev_event->exec_delay = exec_delay; + + /* apply rules, create node, symlinks */ + err = udev_event_execute_rules(udev_event, rules, &sigmask_orig); + + if (err == 0) + udev_event_execute_run(udev_event, &sigmask_orig); + + /* apply/restore inotify watch */ + if (err == 0 && udev_event->inotify_watch) { + udev_watch_begin(udev, dev); + udev_device_update_db(dev); + } + + /* send processed event back to libudev listeners */ + udev_monitor_send_device(worker_monitor, NULL, dev); + + /* send udevd the result of the event execution */ + memset(&msg, 0, sizeof(struct worker_message)); + if (err != 0) + msg.exitcode = err; + msg.pid = getpid(); + send(worker_watch[WRITE_END], &msg, sizeof(struct worker_message), 0); + + log_debug("seq %llu processed with %i\n", udev_device_get_seqnum(dev), err); + + udev_device_unref(dev); + dev = NULL; + + if (udev_event->sigterm) { + udev_event_unref(udev_event); + goto out; + } + + udev_event_unref(udev_event); + + /* wait for more device messages from main udevd, or term signal */ + while (dev == NULL) { + struct epoll_event ev[4]; + int fdcount; + int i; + + fdcount = epoll_wait(fd_ep, ev, ELEMENTSOF(ev), -1); + if (fdcount < 0) { + if (errno == EINTR) + continue; + log_error("failed to poll: %m\n"); + goto out; + } + + for (i = 0; i < fdcount; i++) { + if (ev[i].data.fd == fd_monitor && ev[i].events & EPOLLIN) { + dev = udev_monitor_receive_device(worker_monitor); + break; + } else if (ev[i].data.fd == fd_signal && ev[i].events & EPOLLIN) { + struct signalfd_siginfo fdsi; + ssize_t size; + + size = read(fd_signal, &fdsi, sizeof(struct signalfd_siginfo)); + if (size != sizeof(struct signalfd_siginfo)) + continue; + switch (fdsi.ssi_signo) { + case SIGTERM: + goto out; + } + } + } + } + } +out: + udev_device_unref(dev); + if (fd_signal >= 0) + close(fd_signal); + if (fd_ep >= 0) + close(fd_ep); + close(fd_inotify); + close(worker_watch[WRITE_END]); + udev_rules_unref(rules); + udev_builtin_exit(udev); + udev_monitor_unref(worker_monitor); + udev_unref(udev); + log_close(); + exit(rc); + } + case -1: + udev_monitor_unref(worker_monitor); + event->state = EVENT_QUEUED; + free(worker); + log_error("fork of child failed: %m\n"); + break; + default: + /* close monitor, but keep address around */ + udev_monitor_disconnect(worker_monitor); + worker->monitor = worker_monitor; + worker->pid = pid; + worker->state = WORKER_RUNNING; + worker->event_start_usec = now(CLOCK_MONOTONIC); + worker->event = event; + event->state = EVENT_RUNNING; + udev_list_node_append(&worker->node, &worker_list); + children++; + log_debug("seq %llu forked new worker [%u]\n", udev_device_get_seqnum(event->dev), pid); + break; + } +} + +static void event_run(struct event *event) +{ + struct udev_list_node *loop; + + udev_list_node_foreach(loop, &worker_list) { + struct worker *worker = node_to_worker(loop); + ssize_t count; + + if (worker->state != WORKER_IDLE) + continue; + + count = udev_monitor_send_device(monitor, worker->monitor, event->dev); + if (count < 0) { + log_error("worker [%u] did not accept message %zi (%m), kill it\n", worker->pid, count); + kill(worker->pid, SIGKILL); + worker->state = WORKER_KILLED; + continue; + } + worker_ref(worker); + worker->event = event; + worker->state = WORKER_RUNNING; + worker->event_start_usec = now(CLOCK_MONOTONIC); + event->state = EVENT_RUNNING; + return; + } + + if (children >= children_max) { + if (children_max > 1) + log_debug("maximum number (%i) of children reached\n", children); + return; + } + + /* start new worker and pass initial device */ + worker_new(event); +} + +static int event_queue_insert(struct udev_device *dev) +{ + struct event *event; + + event = calloc(1, sizeof(struct event)); + if (event == NULL) + return -1; + + event->udev = udev_device_get_udev(dev); + event->dev = dev; + event->seqnum = udev_device_get_seqnum(dev); + event->devpath = udev_device_get_devpath(dev); + event->devpath_len = strlen(event->devpath); + event->devpath_old = udev_device_get_devpath_old(dev); + event->devnum = udev_device_get_devnum(dev); + event->is_block = streq("block", udev_device_get_subsystem(dev)); + event->ifindex = udev_device_get_ifindex(dev); + if (streq(udev_device_get_subsystem(dev), "firmware")) + event->nodelay = true; + + udev_queue_export_device_queued(udev_queue_export, dev); + log_debug("seq %llu queued, '%s' '%s'\n", udev_device_get_seqnum(dev), + udev_device_get_action(dev), udev_device_get_subsystem(dev)); + + event->state = EVENT_QUEUED; + udev_list_node_append(&event->node, &event_list); + return 0; +} + +static void worker_kill(struct udev *udev) +{ + struct udev_list_node *loop; + + udev_list_node_foreach(loop, &worker_list) { + struct worker *worker = node_to_worker(loop); + + if (worker->state == WORKER_KILLED) + continue; + + worker->state = WORKER_KILLED; + kill(worker->pid, SIGTERM); + } +} + +/* lookup event for identical, parent, child device */ +static bool is_devpath_busy(struct event *event) +{ + struct udev_list_node *loop; + size_t common; + + /* check if queue contains events we depend on */ + udev_list_node_foreach(loop, &event_list) { + struct event *loop_event = node_to_event(loop); + + /* we already found a later event, earlier can not block us, no need to check again */ + if (loop_event->seqnum < event->delaying_seqnum) + continue; + + /* event we checked earlier still exists, no need to check again */ + if (loop_event->seqnum == event->delaying_seqnum) + return true; + + /* found ourself, no later event can block us */ + if (loop_event->seqnum >= event->seqnum) + break; + + /* check major/minor */ + if (major(event->devnum) != 0 && event->devnum == loop_event->devnum && event->is_block == loop_event->is_block) + return true; + + /* check network device ifindex */ + if (event->ifindex != 0 && event->ifindex == loop_event->ifindex) + return true; + + /* check our old name */ + if (event->devpath_old != NULL && strcmp(loop_event->devpath, event->devpath_old) == 0) { + event->delaying_seqnum = loop_event->seqnum; + return true; + } + + /* compare devpath */ + common = MIN(loop_event->devpath_len, event->devpath_len); + + /* one devpath is contained in the other? */ + if (memcmp(loop_event->devpath, event->devpath, common) != 0) + continue; + + /* identical device event found */ + if (loop_event->devpath_len == event->devpath_len) { + /* devices names might have changed/swapped in the meantime */ + if (major(event->devnum) != 0 && (event->devnum != loop_event->devnum || event->is_block != loop_event->is_block)) + continue; + if (event->ifindex != 0 && event->ifindex != loop_event->ifindex) + continue; + event->delaying_seqnum = loop_event->seqnum; + return true; + } + + /* allow to bypass the dependency tracking */ + if (event->nodelay) + continue; + + /* parent device event found */ + if (event->devpath[common] == '/') { + event->delaying_seqnum = loop_event->seqnum; + return true; + } + + /* child device event found */ + if (loop_event->devpath[common] == '/') { + event->delaying_seqnum = loop_event->seqnum; + return true; + } + + /* no matching device */ + continue; + } + + return false; +} + +static void event_queue_start(struct udev *udev) +{ + struct udev_list_node *loop; + + udev_list_node_foreach(loop, &event_list) { + struct event *event = node_to_event(loop); + + if (event->state != EVENT_QUEUED) + continue; + + /* do not start event if parent or child event is still running */ + if (is_devpath_busy(event)) + continue; + + event_run(event); + } +} + +static void event_queue_cleanup(struct udev *udev, enum event_state match_type) +{ + struct udev_list_node *loop, *tmp; + + udev_list_node_foreach_safe(loop, tmp, &event_list) { + struct event *event = node_to_event(loop); + + if (match_type != EVENT_UNDEF && match_type != event->state) + continue; + + event_queue_delete(event, false); + } +} + +static void worker_returned(int fd_worker) +{ + for (;;) { + struct worker_message msg; + ssize_t size; + struct udev_list_node *loop; + + size = recv(fd_worker, &msg, sizeof(struct worker_message), MSG_DONTWAIT); + if (size != sizeof(struct worker_message)) + break; + + /* lookup worker who sent the signal */ + udev_list_node_foreach(loop, &worker_list) { + struct worker *worker = node_to_worker(loop); + + if (worker->pid != msg.pid) + continue; + + /* worker returned */ + if (worker->event) { + worker->event->exitcode = msg.exitcode; + event_queue_delete(worker->event, true); + worker->event = NULL; + } + if (worker->state != WORKER_KILLED) + worker->state = WORKER_IDLE; + worker_unref(worker); + break; + } + } +} + +/* receive the udevd message from userspace */ +static struct udev_ctrl_connection *handle_ctrl_msg(struct udev_ctrl *uctrl) +{ + struct udev *udev = udev_ctrl_get_udev(uctrl); + struct udev_ctrl_connection *ctrl_conn; + struct udev_ctrl_msg *ctrl_msg = NULL; + const char *str; + int i; + + ctrl_conn = udev_ctrl_get_connection(uctrl); + if (ctrl_conn == NULL) + goto out; + + ctrl_msg = udev_ctrl_receive_msg(ctrl_conn); + if (ctrl_msg == NULL) + goto out; + + i = udev_ctrl_get_set_log_level(ctrl_msg); + if (i >= 0) { + log_debug("udevd message (SET_LOG_PRIORITY) received, log_priority=%i\n", i); + log_set_max_level(i); + udev_set_log_priority(udev, i); + worker_kill(udev); + } + + if (udev_ctrl_get_stop_exec_queue(ctrl_msg) > 0) { + log_debug("udevd message (STOP_EXEC_QUEUE) received\n"); + stop_exec_queue = true; + } + + if (udev_ctrl_get_start_exec_queue(ctrl_msg) > 0) { + log_debug("udevd message (START_EXEC_QUEUE) received\n"); + stop_exec_queue = false; + } + + if (udev_ctrl_get_reload(ctrl_msg) > 0) { + log_debug("udevd message (RELOAD) received\n"); + reload = true; + } + + str = udev_ctrl_get_set_env(ctrl_msg); + if (str != NULL) { + char *key; + + key = strdup(str); + if (key != NULL) { + char *val; + + val = strchr(key, '='); + if (val != NULL) { + val[0] = '\0'; + val = &val[1]; + if (val[0] == '\0') { + log_debug("udevd message (ENV) received, unset '%s'\n", key); + udev_add_property(udev, key, NULL); + } else { + log_debug("udevd message (ENV) received, set '%s=%s'\n", key, val); + udev_add_property(udev, key, val); + } + } else { + log_error("wrong key format '%s'\n", key); + } + free(key); + } + worker_kill(udev); + } + + i = udev_ctrl_get_set_children_max(ctrl_msg); + if (i >= 0) { + log_debug("udevd message (SET_MAX_CHILDREN) received, children_max=%i\n", i); + children_max = i; + } + + if (udev_ctrl_get_ping(ctrl_msg) > 0) + log_debug("udevd message (SYNC) received\n"); + + if (udev_ctrl_get_exit(ctrl_msg) > 0) { + log_debug("udevd message (EXIT) received\n"); + udev_exit = true; + /* keep reference to block the client until we exit */ + udev_ctrl_connection_ref(ctrl_conn); + } +out: + udev_ctrl_msg_unref(ctrl_msg); + return udev_ctrl_connection_unref(ctrl_conn); +} + +/* read inotify messages */ +static int handle_inotify(struct udev *udev) +{ + int nbytes, pos; + char *buf; + struct inotify_event *ev; + + if ((ioctl(fd_inotify, FIONREAD, &nbytes) < 0) || (nbytes <= 0)) + return 0; + + buf = malloc(nbytes); + if (buf == NULL) { + log_error("error getting buffer for inotify\n"); + return -1; + } + + nbytes = read(fd_inotify, buf, nbytes); + + for (pos = 0; pos < nbytes; pos += sizeof(struct inotify_event) + ev->len) { + struct udev_device *dev; + + ev = (struct inotify_event *)(buf + pos); + dev = udev_watch_lookup(udev, ev->wd); + if (dev != NULL) { + log_debug("inotify event: %x for %s\n", ev->mask, udev_device_get_devnode(dev)); + if (ev->mask & IN_CLOSE_WRITE) { + char filename[UTIL_PATH_SIZE]; + int fd; + + log_debug("device %s closed, synthesising 'change'\n", udev_device_get_devnode(dev)); + util_strscpyl(filename, sizeof(filename), udev_device_get_syspath(dev), "/uevent", NULL); + fd = open(filename, O_WRONLY); + if (fd >= 0) { + if (write(fd, "change", 6) < 0) + log_debug("error writing uevent: %m\n"); + close(fd); + } + } + if (ev->mask & IN_IGNORED) + udev_watch_end(udev, dev); + + udev_device_unref(dev); + } + + } + + free(buf); + return 0; +} + +static void handle_signal(struct udev *udev, int signo) +{ + switch (signo) { + case SIGINT: + case SIGTERM: + udev_exit = true; + break; + case SIGCHLD: + for (;;) { + pid_t pid; + int status; + struct udev_list_node *loop, *tmp; + + pid = waitpid(-1, &status, WNOHANG); + if (pid <= 0) + break; + + udev_list_node_foreach_safe(loop, tmp, &worker_list) { + struct worker *worker = node_to_worker(loop); + + if (worker->pid != pid) + continue; + log_debug("worker [%u] exit\n", pid); + + if (WIFEXITED(status)) { + if (WEXITSTATUS(status) != 0) + log_error("worker [%u] exit with return code %i\n", pid, WEXITSTATUS(status)); + } else if (WIFSIGNALED(status)) { + log_error("worker [%u] terminated by signal %i (%s)\n", + pid, WTERMSIG(status), strsignal(WTERMSIG(status))); + } else if (WIFSTOPPED(status)) { + log_error("worker [%u] stopped\n", pid); + } else if (WIFCONTINUED(status)) { + log_error("worker [%u] continued\n", pid); + } else { + log_error("worker [%u] exit with status 0x%04x\n", pid, status); + } + + if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { + if (worker->event) { + log_error("worker [%u] failed while handling '%s'\n", + pid, worker->event->devpath); + worker->event->exitcode = -32; + event_queue_delete(worker->event, true); + /* drop reference taken for state 'running' */ + worker_unref(worker); + } + } + worker_unref(worker); + break; + } + } + break; + case SIGHUP: + reload = true; + break; + } +} + +static void static_dev_create_from_modules(struct udev *udev) +{ + struct utsname kernel; + char modules[UTIL_PATH_SIZE]; + char buf[4096]; + FILE *f; + + uname(&kernel); + util_strscpyl(modules, sizeof(modules), ROOTPREFIX "/lib/modules/", kernel.release, "/modules.devname", NULL); + f = fopen(modules, "re"); + if (f == NULL) + return; + + while (fgets(buf, sizeof(buf), f) != NULL) { + char *s; + const char *modname; + const char *devname; + const char *devno; + int maj, min; + char type; + mode_t mode; + char filename[UTIL_PATH_SIZE]; + + if (buf[0] == '#') + continue; + + modname = buf; + s = strchr(modname, ' '); + if (s == NULL) + continue; + s[0] = '\0'; + + devname = &s[1]; + s = strchr(devname, ' '); + if (s == NULL) + continue; + s[0] = '\0'; + + devno = &s[1]; + s = strchr(devno, ' '); + if (s == NULL) + s = strchr(devno, '\n'); + if (s != NULL) + s[0] = '\0'; + if (sscanf(devno, "%c%u:%u", &type, &maj, &min) != 3) + continue; + + mode = 0600; + if (type == 'c') + mode |= S_IFCHR; + else if (type == 'b') + mode |= S_IFBLK; + else + continue; + + util_strscpyl(filename, sizeof(filename), "/dev/", devname, NULL); + mkdir_parents_label(filename, 0755); + label_context_set(filename, mode); + log_debug("mknod '%s' %c%u:%u\n", filename, type, maj, min); + if (mknod(filename, mode, makedev(maj, min)) < 0 && errno == EEXIST) + utimensat(AT_FDCWD, filename, NULL, 0); + label_context_clear(); + } + + fclose(f); +} + +static int mem_size_mb(void) +{ + FILE *f; + char buf[4096]; + long int memsize = -1; + + f = fopen("/proc/meminfo", "re"); + if (f == NULL) + return -1; + + while (fgets(buf, sizeof(buf), f) != NULL) { + long int value; + + if (sscanf(buf, "MemTotal: %ld kB", &value) == 1) { + memsize = value / 1024; + break; + } + } + + fclose(f); + return memsize; +} + +static int convert_db(struct udev *udev) +{ + char filename[UTIL_PATH_SIZE]; + struct udev_enumerate *udev_enumerate; + struct udev_list_entry *list_entry; + + /* current database */ + if (access("/run/udev/data", F_OK) >= 0) + return 0; + + /* make sure we do not get here again */ + mkdir_p("/run/udev/data", 0755); + + /* old database */ + util_strscpyl(filename, sizeof(filename), "/dev/.udev/db", NULL); + if (access(filename, F_OK) < 0) + return 0; + + print_kmsg("converting old udev database\n"); + + udev_enumerate = udev_enumerate_new(udev); + if (udev_enumerate == NULL) + return -1; + udev_enumerate_scan_devices(udev_enumerate); + udev_list_entry_foreach(list_entry, udev_enumerate_get_list_entry(udev_enumerate)) { + struct udev_device *device; + + device = udev_device_new_from_syspath(udev, udev_list_entry_get_name(list_entry)); + if (device == NULL) + continue; + + /* try to find the old database for devices without a current one */ + if (udev_device_read_db(device, NULL) < 0) { + bool have_db; + const char *id; + struct stat stats; + char devpath[UTIL_PATH_SIZE]; + char from[UTIL_PATH_SIZE]; + + have_db = false; + + /* find database in old location */ + id = udev_device_get_id_filename(device); + util_strscpyl(from, sizeof(from), "/dev/.udev/db/", id, NULL); + if (lstat(from, &stats) == 0) { + if (!have_db) { + udev_device_read_db(device, from); + have_db = true; + } + unlink(from); + } + + /* find old database with $subsys:$sysname name */ + util_strscpyl(from, sizeof(from), "/dev/.udev/db/", + udev_device_get_subsystem(device), ":", udev_device_get_sysname(device), NULL); + if (lstat(from, &stats) == 0) { + if (!have_db) { + udev_device_read_db(device, from); + have_db = true; + } + unlink(from); + } + + /* find old database with the encoded devpath name */ + util_path_encode(udev_device_get_devpath(device), devpath, sizeof(devpath)); + util_strscpyl(from, sizeof(from), "/dev/.udev/db/", devpath, NULL); + if (lstat(from, &stats) == 0) { + if (!have_db) { + udev_device_read_db(device, from); + have_db = true; + } + unlink(from); + } + + /* write out new database */ + if (have_db) + udev_device_update_db(device); + } + udev_device_unref(device); + } + udev_enumerate_unref(udev_enumerate); + return 0; +} + +static int systemd_fds(struct udev *udev, int *rctrl, int *rnetlink) +{ + int ctrl = -1, netlink = -1; + int fd, n; + + n = sd_listen_fds(true); + if (n <= 0) + return -1; + + for (fd = SD_LISTEN_FDS_START; fd < n + SD_LISTEN_FDS_START; fd++) { + if (sd_is_socket(fd, AF_LOCAL, SOCK_SEQPACKET, -1)) { + if (ctrl >= 0) + return -1; + ctrl = fd; + continue; + } + + if (sd_is_socket(fd, AF_NETLINK, SOCK_RAW, -1)) { + if (netlink >= 0) + return -1; + netlink = fd; + continue; + } + + return -1; + } + + if (ctrl < 0 || netlink < 0) + return -1; + + log_debug("ctrl=%i netlink=%i\n", ctrl, netlink); + *rctrl = ctrl; + *rnetlink = netlink; + return 0; +} + +/* + * read the kernel commandline, in case we need to get into debug mode + * udev.log-priority= syslog priority + * udev.children-max= events are fully serialized if set to 1 + * udev.exec-delay= delay execution of every executed program + */ +static void kernel_cmdline_options(struct udev *udev) +{ + char *line, *w, *state; + size_t l; + + if (read_one_line_file("/proc/cmdline", &line) < 0) + return; + + FOREACH_WORD_QUOTED(w, l, line, state) { + char *s, *opt; + + s = strndup(w, l); + if (!s) + break; + + /* accept the same options for the initrd, prefixed with "rd." */ + if (in_initrd() && startswith(s, "rd.")) + opt = s + 3; + else + opt = s; + + if (startswith(opt, "udev.log-priority=")) { + int prio; + + prio = util_log_priority(opt + 18); + log_set_max_level(prio); + udev_set_log_priority(udev, prio); + } else if (startswith(opt, "udev.children-max=")) { + children_max = strtoul(opt + 18, NULL, 0); + } else if (startswith(opt, "udev.exec-delay=")) { + exec_delay = strtoul(opt + 16, NULL, 0); + } + + free(s); + } + + free(line); +} + +int main(int argc, char *argv[]) +{ + struct udev *udev; + sigset_t mask; + int daemonize = false; + int resolve_names = 1; + static const struct option options[] = { + { "daemon", no_argument, NULL, 'd' }, + { "debug", no_argument, NULL, 'D' }, + { "children-max", required_argument, NULL, 'c' }, + { "exec-delay", required_argument, NULL, 'e' }, + { "resolve-names", required_argument, NULL, 'N' }, + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, 'V' }, + {} + }; + int fd_ctrl = -1; + int fd_netlink = -1; + int fd_worker = -1; + struct epoll_event ep_ctrl, ep_inotify, ep_signal, ep_netlink, ep_worker; + struct udev_ctrl_connection *ctrl_conn = NULL; + int rc = 1; + + udev = udev_new(); + if (udev == NULL) + goto exit; + + log_set_target(LOG_TARGET_AUTO); + log_parse_environment(); + log_open(); + udev_set_log_fn(udev, udev_main_log); + log_debug("version %s\n", VERSION); + label_init("/dev"); + + for (;;) { + int option; + + option = getopt_long(argc, argv, "c:de:DtN:hV", options, NULL); + if (option == -1) + break; + + switch (option) { + case 'd': + daemonize = true; + break; + case 'c': + children_max = strtoul(optarg, NULL, 0); + break; + case 'e': + exec_delay = strtoul(optarg, NULL, 0); + break; + case 'D': + debug = true; + log_set_max_level(LOG_DEBUG); + udev_set_log_priority(udev, LOG_DEBUG); + break; + case 'N': + if (strcmp (optarg, "early") == 0) { + resolve_names = 1; + } else if (strcmp (optarg, "late") == 0) { + resolve_names = 0; + } else if (strcmp (optarg, "never") == 0) { + resolve_names = -1; + } else { + fprintf(stderr, "resolve-names must be early, late or never\n"); + log_error("resolve-names must be early, late or never\n"); + goto exit; + } + break; + case 'h': + printf("Usage: udevd OPTIONS\n" + " --daemon\n" + " --debug\n" + " --children-max=\n" + " --exec-delay=\n" + " --resolve-names=early|late|never\n" + " --version\n" + " --help\n" + "\n"); + goto exit; + case 'V': + printf("%s\n", VERSION); + goto exit; + default: + goto exit; + } + } + + kernel_cmdline_options(udev); + + if (getuid() != 0) { + fprintf(stderr, "root privileges required\n"); + log_error("root privileges required\n"); + goto exit; + } + + /* set umask before creating any file/directory */ + chdir("/"); + umask(022); + + mkdir("/run/udev", 0755); + + dev_setup(NULL); + static_dev_create_from_modules(udev); + + /* before opening new files, make sure std{in,out,err} fds are in a sane state */ + if (daemonize) { + int fd; + + fd = open("/dev/null", O_RDWR); + if (fd >= 0) { + if (write(STDOUT_FILENO, 0, 0) < 0) + dup2(fd, STDOUT_FILENO); + if (write(STDERR_FILENO, 0, 0) < 0) + dup2(fd, STDERR_FILENO); + if (fd > STDERR_FILENO) + close(fd); + } else { + fprintf(stderr, "cannot open /dev/null\n"); + log_error("cannot open /dev/null\n"); + } + } + + if (systemd_fds(udev, &fd_ctrl, &fd_netlink) >= 0) { + /* get control and netlink socket from systemd */ + udev_ctrl = udev_ctrl_new_from_fd(udev, fd_ctrl); + if (udev_ctrl == NULL) { + log_error("error taking over udev control socket"); + rc = 1; + goto exit; + } + + monitor = udev_monitor_new_from_netlink_fd(udev, "kernel", fd_netlink); + if (monitor == NULL) { + log_error("error taking over netlink socket\n"); + rc = 3; + goto exit; + } + + /* get our own cgroup, we regularly kill everything udev has left behind */ + if (cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, 0, &udev_cgroup) < 0) + udev_cgroup = NULL; + } else { + /* open control and netlink socket */ + udev_ctrl = udev_ctrl_new(udev); + if (udev_ctrl == NULL) { + fprintf(stderr, "error initializing udev control socket"); + log_error("error initializing udev control socket"); + rc = 1; + goto exit; + } + fd_ctrl = udev_ctrl_get_fd(udev_ctrl); + + monitor = udev_monitor_new_from_netlink(udev, "kernel"); + if (monitor == NULL) { + fprintf(stderr, "error initializing netlink socket\n"); + log_error("error initializing netlink socket\n"); + rc = 3; + goto exit; + } + fd_netlink = udev_monitor_get_fd(monitor); + } + + if (udev_monitor_enable_receiving(monitor) < 0) { + fprintf(stderr, "error binding netlink socket\n"); + log_error("error binding netlink socket\n"); + rc = 3; + goto exit; + } + + if (udev_ctrl_enable_receiving(udev_ctrl) < 0) { + fprintf(stderr, "error binding udev control socket\n"); + log_error("error binding udev control socket\n"); + rc = 1; + goto exit; + } + + udev_monitor_set_receive_buffer_size(monitor, 128*1024*1024); + + /* create queue file before signalling 'ready', to make sure we block 'settle' */ + udev_queue_export = udev_queue_export_new(udev); + if (udev_queue_export == NULL) { + log_error("error creating queue file\n"); + goto exit; + } + + if (daemonize) { + pid_t pid; + + pid = fork(); + switch (pid) { + case 0: + break; + case -1: + log_error("fork of daemon failed: %m\n"); + rc = 4; + goto exit; + default: + rc = EXIT_SUCCESS; + goto exit_daemonize; + } + + setsid(); + + write_one_line_file("/proc/self/oom_score_adj", "-1000"); + } else { + sd_notify(1, "READY=1"); + } + + print_kmsg("starting version " VERSION "\n"); + + if (!debug) { + int fd; + + fd = open("/dev/null", O_RDWR); + if (fd >= 0) { + dup2(fd, STDIN_FILENO); + dup2(fd, STDOUT_FILENO); + dup2(fd, STDERR_FILENO); + close(fd); + } + } + + fd_inotify = udev_watch_init(udev); + if (fd_inotify < 0) { + fprintf(stderr, "error initializing inotify\n"); + log_error("error initializing inotify\n"); + rc = 4; + goto exit; + } + udev_watch_restore(udev); + + /* block and listen to all signals on signalfd */ + sigfillset(&mask); + sigprocmask(SIG_SETMASK, &mask, &sigmask_orig); + fd_signal = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC); + if (fd_signal < 0) { + fprintf(stderr, "error creating signalfd\n"); + log_error("error creating signalfd\n"); + rc = 5; + goto exit; + } + + /* unnamed socket from workers to the main daemon */ + if (socketpair(AF_LOCAL, SOCK_DGRAM|SOCK_CLOEXEC, 0, worker_watch) < 0) { + fprintf(stderr, "error creating socketpair\n"); + log_error("error creating socketpair\n"); + rc = 6; + goto exit; + } + fd_worker = worker_watch[READ_END]; + + udev_builtin_init(udev); + + rules = udev_rules_new(udev, resolve_names); + if (rules == NULL) { + log_error("error reading rules\n"); + goto exit; + } + + memset(&ep_ctrl, 0, sizeof(struct epoll_event)); + ep_ctrl.events = EPOLLIN; + ep_ctrl.data.fd = fd_ctrl; + + memset(&ep_inotify, 0, sizeof(struct epoll_event)); + ep_inotify.events = EPOLLIN; + ep_inotify.data.fd = fd_inotify; + + memset(&ep_signal, 0, sizeof(struct epoll_event)); + ep_signal.events = EPOLLIN; + ep_signal.data.fd = fd_signal; + + memset(&ep_netlink, 0, sizeof(struct epoll_event)); + ep_netlink.events = EPOLLIN; + ep_netlink.data.fd = fd_netlink; + + memset(&ep_worker, 0, sizeof(struct epoll_event)); + ep_worker.events = EPOLLIN; + ep_worker.data.fd = fd_worker; + + fd_ep = epoll_create1(EPOLL_CLOEXEC); + if (fd_ep < 0) { + log_error("error creating epoll fd: %m\n"); + goto exit; + } + if (epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_ctrl, &ep_ctrl) < 0 || + epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_inotify, &ep_inotify) < 0 || + epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_signal, &ep_signal) < 0 || + epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_netlink, &ep_netlink) < 0 || + epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_worker, &ep_worker) < 0) { + log_error("fail to add fds to epoll: %m\n"); + goto exit; + } + + /* if needed, convert old database from earlier udev version */ + convert_db(udev); + + if (children_max <= 0) { + int memsize = mem_size_mb(); + + /* set value depending on the amount of RAM */ + if (memsize > 0) + children_max = 16 + (memsize / 8); + else + children_max = 16; + } + log_debug("set children_max to %u\n", children_max); + + udev_rules_apply_static_dev_perms(rules); + + udev_list_node_init(&event_list); + udev_list_node_init(&worker_list); + + for (;;) { + static usec_t last_usec; + struct epoll_event ev[8]; + int fdcount; + int timeout; + bool is_worker, is_signal, is_inotify, is_netlink, is_ctrl; + int i; + + if (udev_exit) { + /* close sources of new events and discard buffered events */ + if (fd_ctrl >= 0) { + epoll_ctl(fd_ep, EPOLL_CTL_DEL, fd_ctrl, NULL); + fd_ctrl = -1; + } + if (monitor != NULL) { + epoll_ctl(fd_ep, EPOLL_CTL_DEL, fd_netlink, NULL); + udev_monitor_unref(monitor); + monitor = NULL; + } + if (fd_inotify >= 0) { + epoll_ctl(fd_ep, EPOLL_CTL_DEL, fd_inotify, NULL); + close(fd_inotify); + fd_inotify = -1; + } + + /* discard queued events and kill workers */ + event_queue_cleanup(udev, EVENT_QUEUED); + worker_kill(udev); + + /* exit after all has cleaned up */ + if (udev_list_node_is_empty(&event_list) && udev_list_node_is_empty(&worker_list)) + break; + + /* timeout at exit for workers to finish */ + timeout = 30 * 1000; + } else if (udev_list_node_is_empty(&event_list) && !children) { + /* we are idle */ + timeout = -1; + + /* cleanup possible left-over processes in our cgroup */ + if (udev_cgroup) + cg_kill(SYSTEMD_CGROUP_CONTROLLER, udev_cgroup, SIGKILL, false, true, NULL); + } else { + /* kill idle or hanging workers */ + timeout = 3 * 1000; + } + fdcount = epoll_wait(fd_ep, ev, ELEMENTSOF(ev), timeout); + if (fdcount < 0) + continue; + + if (fdcount == 0) { + struct udev_list_node *loop; + + /* timeout */ + if (udev_exit) { + log_error("timeout, giving up waiting for workers to finish\n"); + break; + } + + /* kill idle workers */ + if (udev_list_node_is_empty(&event_list)) { + log_debug("cleanup idle workers\n"); + worker_kill(udev); + } + + /* check for hanging events */ + udev_list_node_foreach(loop, &worker_list) { + struct worker *worker = node_to_worker(loop); + + if (worker->state != WORKER_RUNNING) + continue; + + if ((now(CLOCK_MONOTONIC) - worker->event_start_usec) > 30 * 1000 * 1000) { + log_error("worker [%u] %s timeout; kill it\n", worker->pid, + worker->event ? worker->event->devpath : ""); + kill(worker->pid, SIGKILL); + worker->state = WORKER_KILLED; + /* drop reference taken for state 'running' */ + worker_unref(worker); + if (worker->event) { + log_error("seq %llu '%s' killed\n", + udev_device_get_seqnum(worker->event->dev), worker->event->devpath); + worker->event->exitcode = -64; + event_queue_delete(worker->event, true); + worker->event = NULL; + } + } + } + + } + + is_worker = is_signal = is_inotify = is_netlink = is_ctrl = false; + for (i = 0; i < fdcount; i++) { + if (ev[i].data.fd == fd_worker && ev[i].events & EPOLLIN) + is_worker = true; + else if (ev[i].data.fd == fd_netlink && ev[i].events & EPOLLIN) + is_netlink = true; + else if (ev[i].data.fd == fd_signal && ev[i].events & EPOLLIN) + is_signal = true; + else if (ev[i].data.fd == fd_inotify && ev[i].events & EPOLLIN) + is_inotify = true; + else if (ev[i].data.fd == fd_ctrl && ev[i].events & EPOLLIN) + is_ctrl = true; + } + + /* check for changed config, every 3 seconds at most */ + if ((now(CLOCK_MONOTONIC) - last_usec) > 3 * 1000 * 1000) { + if (udev_rules_check_timestamp(rules)) + reload = true; + if (udev_builtin_validate(udev)) + reload = true; + + last_usec = now(CLOCK_MONOTONIC); + } + + /* reload requested, HUP signal received, rules changed, builtin changed */ + if (reload) { + worker_kill(udev); + rules = udev_rules_unref(rules); + udev_builtin_exit(udev); + reload = false; + } + + /* event has finished */ + if (is_worker) + worker_returned(fd_worker); + + if (is_netlink) { + struct udev_device *dev; + + dev = udev_monitor_receive_device(monitor); + if (dev != NULL) { + udev_device_set_usec_initialized(dev, now(CLOCK_MONOTONIC)); + if (event_queue_insert(dev) < 0) + udev_device_unref(dev); + } + } + + /* start new events */ + if (!udev_list_node_is_empty(&event_list) && !udev_exit && !stop_exec_queue) { + udev_builtin_init(udev); + if (rules == NULL) + rules = udev_rules_new(udev, resolve_names); + if (rules != NULL) + event_queue_start(udev); + } + + if (is_signal) { + struct signalfd_siginfo fdsi; + ssize_t size; + + size = read(fd_signal, &fdsi, sizeof(struct signalfd_siginfo)); + if (size == sizeof(struct signalfd_siginfo)) + handle_signal(udev, fdsi.ssi_signo); + } + + /* we are shutting down, the events below are not handled anymore */ + if (udev_exit) + continue; + + /* device node watch */ + if (is_inotify) + handle_inotify(udev); + + /* + * This needs to be after the inotify handling, to make sure, + * that the ping is send back after the possibly generated + * "change" events by the inotify device node watch. + * + * A single time we may receive a client connection which we need to + * keep open to block the client. It will be closed right before we + * exit. + */ + if (is_ctrl) + ctrl_conn = handle_ctrl_msg(udev_ctrl); + } + + rc = EXIT_SUCCESS; +exit: + udev_queue_export_cleanup(udev_queue_export); + udev_ctrl_cleanup(udev_ctrl); +exit_daemonize: + if (fd_ep >= 0) + close(fd_ep); + worker_list_cleanup(udev); + event_queue_cleanup(udev, EVENT_UNDEF); + udev_rules_unref(rules); + udev_builtin_exit(udev); + if (fd_signal >= 0) + close(fd_signal); + if (worker_watch[READ_END] >= 0) + close(worker_watch[READ_END]); + if (worker_watch[WRITE_END] >= 0) + close(worker_watch[WRITE_END]); + udev_monitor_unref(monitor); + udev_queue_export_unref(udev_queue_export); + udev_ctrl_connection_unref(ctrl_conn); + udev_ctrl_unref(udev_ctrl); + label_finish(); + udev_unref(udev); + log_close(); + return rc; +} diff --git a/src/udev/v4l_id/v4l_id.c b/src/udev/v4l_id/v4l_id.c new file mode 100644 index 000000000..8dcb645ed --- /dev/null +++ b/src/udev/v4l_id/v4l_id.c @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2009 Kay Sievers + * Copyright (c) 2009 Filippo Argiolas + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details: + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int main (int argc, char *argv[]) +{ + static const struct option options[] = { + { "help", no_argument, NULL, 'h' }, + {} + }; + int fd; + char *device; + struct v4l2_capability v2cap; + + while (1) { + int option; + + option = getopt_long(argc, argv, "h", options, NULL); + if (option == -1) + break; + + switch (option) { + case 'h': + printf("Usage: v4l_id [--help] \n\n"); + return 0; + default: + return 1; + } + } + device = argv[optind]; + + if (device == NULL) + return 2; + fd = open (device, O_RDONLY); + if (fd < 0) + return 3; + + if (ioctl (fd, VIDIOC_QUERYCAP, &v2cap) == 0) { + printf("ID_V4L_VERSION=2\n"); + printf("ID_V4L_PRODUCT=%s\n", v2cap.card); + printf("ID_V4L_CAPABILITIES=:"); + if ((v2cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) > 0) + printf("capture:"); + if ((v2cap.capabilities & V4L2_CAP_VIDEO_OUTPUT) > 0) + printf("video_output:"); + if ((v2cap.capabilities & V4L2_CAP_VIDEO_OVERLAY) > 0) + printf("video_overlay:"); + if ((v2cap.capabilities & V4L2_CAP_AUDIO) > 0) + printf("audio:"); + if ((v2cap.capabilities & V4L2_CAP_TUNER) > 0) + printf("tuner:"); + if ((v2cap.capabilities & V4L2_CAP_RADIO) > 0) + printf("radio:"); + printf("\n"); + } + + close (fd); + return 0; +} diff --git a/src/update-utmp/Makefile b/src/update-utmp/Makefile new file mode 120000 index 000000000..d0b0e8e00 --- /dev/null +++ b/src/update-utmp/Makefile @@ -0,0 +1 @@ +../Makefile \ No newline at end of file diff --git a/src/update-utmp/update-utmp.c b/src/update-utmp/update-utmp.c new file mode 100644 index 000000000..a311280c2 --- /dev/null +++ b/src/update-utmp/update-utmp.c @@ -0,0 +1,386 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include +#include +#include +#include +#include + +#include + +#ifdef HAVE_AUDIT +#include +#endif + +#include "log.h" +#include "macro.h" +#include "util.h" +#include "special.h" +#include "utmp-wtmp.h" +#include "dbus-common.h" + +typedef struct Context { + DBusConnection *bus; +#ifdef HAVE_AUDIT + int audit_fd; +#endif +} Context; + +static usec_t get_startup_time(Context *c) { + const char + *interface = "org.freedesktop.systemd1.Manager", + *property = "UserspaceTimestamp"; + + usec_t t = 0; + DBusMessage *reply = NULL; + DBusMessageIter iter, sub; + + assert(c); + + if (bus_method_call_with_reply ( + c->bus, + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.DBus.Properties", + "Get", + &reply, + NULL, + DBUS_TYPE_STRING, &interface, + DBUS_TYPE_STRING, &property, + DBUS_TYPE_INVALID)) + goto finish; + + if (!dbus_message_iter_init(reply, &iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT) { + log_error("Failed to parse reply."); + goto finish; + } + + dbus_message_iter_recurse(&iter, &sub); + + if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_UINT64) { + log_error("Failed to parse reply."); + goto finish; + } + + dbus_message_iter_get_basic(&sub, &t); + +finish: + if (reply) + dbus_message_unref(reply); + return t; +} + +static int get_current_runlevel(Context *c) { + static const struct { + const int runlevel; + const char *special; + } table[] = { + /* The first target of this list that is active or has + * a job scheduled wins. We prefer runlevels 5 and 3 + * here over the others, since these are the main + * runlevels used on Fedora. It might make sense to + * change the order on some distributions. */ + { '5', SPECIAL_RUNLEVEL5_TARGET }, + { '3', SPECIAL_RUNLEVEL3_TARGET }, + { '4', SPECIAL_RUNLEVEL4_TARGET }, + { '2', SPECIAL_RUNLEVEL2_TARGET }, + { 'S', SPECIAL_RESCUE_TARGET }, + }; + const char + *interface = "org.freedesktop.systemd1.Unit", + *property = "ActiveState"; + + DBusMessage *reply = NULL; + int r = 0; + unsigned i; + DBusError error; + + assert(c); + + dbus_error_init(&error); + + for (i = 0; i < ELEMENTSOF(table); i++) { + const char *path = NULL, *state; + DBusMessageIter iter, sub; + + r = bus_method_call_with_reply ( + c->bus, + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "GetUnit", + &reply, + NULL, + DBUS_TYPE_STRING, &table[i].special, + DBUS_TYPE_INVALID); + if (r == -ENOMEM) + goto finish; + if (r) + continue; + + if (!dbus_message_get_args(reply, &error, + DBUS_TYPE_OBJECT_PATH, &path, + DBUS_TYPE_INVALID)) { + log_error("Failed to parse reply: %s", bus_error_message(&error)); + r = -EIO; + goto finish; + } + + dbus_message_unref(reply); + r = bus_method_call_with_reply ( + c->bus, + "org.freedesktop.systemd1", + path, + "org.freedesktop.DBus.Properties", + "Get", + &reply, + NULL, + DBUS_TYPE_STRING, &interface, + DBUS_TYPE_STRING, &property, + DBUS_TYPE_INVALID); + if (r) + goto finish; + + if (!dbus_message_iter_init(reply, &iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_recurse(&iter, &sub); + + if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_get_basic(&sub, &state); + + if (streq(state, "active") || streq(state, "reloading")) + r = table[i].runlevel; + + dbus_message_unref(reply); + reply = NULL; + + if (r) + break; + } + +finish: + if (reply) + dbus_message_unref(reply); + + dbus_error_free(&error); + + return r; +} + +static int on_reboot(Context *c) { + int r = 0, q; + usec_t t; + + assert(c); + + /* We finished start-up, so let's write the utmp + * record and send the audit msg */ + +#ifdef HAVE_AUDIT + if (c->audit_fd >= 0) + if (audit_log_user_message(c->audit_fd, AUDIT_SYSTEM_BOOT, "init", NULL, NULL, NULL, 1) < 0 && + errno != EPERM) { + log_error("Failed to send audit message: %m"); + r = -errno; + } +#endif + + /* If this call fails it will return 0, which + * utmp_put_reboot() will then fix to the current time */ + t = get_startup_time(c); + + if ((q = utmp_put_reboot(t)) < 0) { + log_error("Failed to write utmp record: %s", strerror(-q)); + r = q; + } + + return r; +} + +static int on_shutdown(Context *c) { + int r = 0, q; + + assert(c); + + /* We started shut-down, so let's write the utmp + * record and send the audit msg */ + +#ifdef HAVE_AUDIT + if (c->audit_fd >= 0) + if (audit_log_user_message(c->audit_fd, AUDIT_SYSTEM_SHUTDOWN, "init", NULL, NULL, NULL, 1) < 0 && + errno != EPERM) { + log_error("Failed to send audit message: %m"); + r = -errno; + } +#endif + + if ((q = utmp_put_shutdown()) < 0) { + log_error("Failed to write utmp record: %s", strerror(-q)); + r = q; + } + + return r; +} + +static int on_runlevel(Context *c) { + int r = 0, q, previous, runlevel; + + assert(c); + + /* We finished changing runlevel, so let's write the + * utmp record and send the audit msg */ + + /* First, get last runlevel */ + if ((q = utmp_get_runlevel(&previous, NULL)) < 0) { + + if (q != -ESRCH && q != -ENOENT) { + log_error("Failed to get current runlevel: %s", strerror(-q)); + return q; + } + + /* Hmm, we didn't find any runlevel, that means we + * have been rebooted */ + r = on_reboot(c); + previous = 0; + } + + /* Secondly, get new runlevel */ + if ((runlevel = get_current_runlevel(c)) < 0) + return runlevel; + + if (previous == runlevel) + return 0; + +#ifdef HAVE_AUDIT + if (c->audit_fd >= 0) { + char *s = NULL; + + if (asprintf(&s, "old-level=%c new-level=%c", + previous > 0 ? previous : 'N', + runlevel > 0 ? runlevel : 'N') < 0) + return -ENOMEM; + + if (audit_log_user_message(c->audit_fd, AUDIT_SYSTEM_RUNLEVEL, s, NULL, NULL, NULL, 1) < 0 && + errno != EPERM) { + log_error("Failed to send audit message: %m"); + r = -errno; + } + + free(s); + } +#endif + + if ((q = utmp_put_runlevel(runlevel, previous)) < 0) { + if (q != -ESRCH && q != -ENOENT) { + log_error("Failed to write utmp record: %s", strerror(-q)); + r = q; + } + } + + return r; +} + +int main(int argc, char *argv[]) { + int r; + DBusError error; + Context c; + + dbus_error_init(&error); + + zero(c); +#ifdef HAVE_AUDIT + c.audit_fd = -1; +#endif + + if (getppid() != 1) { + log_error("This program should be invoked by init only."); + return EXIT_FAILURE; + } + + if (argc != 2) { + log_error("This program requires one argument."); + return EXIT_FAILURE; + } + + log_set_target(LOG_TARGET_AUTO); + log_parse_environment(); + log_open(); + + umask(0022); + +#ifdef HAVE_AUDIT + if ((c.audit_fd = audit_open()) < 0 && + /* If the kernel lacks netlink or audit support, + * don't worry about it. */ + errno != EAFNOSUPPORT && errno != EPROTONOSUPPORT) + log_error("Failed to connect to audit log: %m"); +#endif + + if (bus_connect(DBUS_BUS_SYSTEM, &c.bus, NULL, &error) < 0) { + log_error("Failed to get D-Bus connection: %s", bus_error_message(&error)); + r = -EIO; + goto finish; + } + + log_debug("systemd-update-utmp running as pid %lu", (unsigned long) getpid()); + + if (streq(argv[1], "reboot")) + r = on_reboot(&c); + else if (streq(argv[1], "shutdown")) + r = on_shutdown(&c); + else if (streq(argv[1], "runlevel")) + r = on_runlevel(&c); + else { + log_error("Unknown command %s", argv[1]); + r = -EINVAL; + } + + log_debug("systemd-update-utmp stopped as pid %lu", (unsigned long) getpid()); + +finish: +#ifdef HAVE_AUDIT + if (c.audit_fd >= 0) + audit_close(c.audit_fd); +#endif + + if (c.bus) { + dbus_connection_flush(c.bus); + dbus_connection_close(c.bus); + dbus_connection_unref(c.bus); + } + + dbus_error_free(&error); + dbus_shutdown(); + + return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/src/vconsole/Makefile b/src/vconsole/Makefile new file mode 120000 index 000000000..d0b0e8e00 --- /dev/null +++ b/src/vconsole/Makefile @@ -0,0 +1 @@ +../Makefile \ No newline at end of file diff --git a/src/vconsole/vconsole-setup.c b/src/vconsole/vconsole-setup.c new file mode 100644 index 000000000..b9d8681a8 --- /dev/null +++ b/src/vconsole/vconsole-setup.c @@ -0,0 +1,257 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Kay Sievers + + 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 . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "util.h" +#include "log.h" +#include "macro.h" +#include "virt.h" + +static bool is_vconsole(int fd) { + unsigned char data[1]; + + data[0] = TIOCL_GETFGCONSOLE; + return ioctl(fd, TIOCLINUX, data) >= 0; +} + +static int disable_utf8(int fd) { + int r = 0, k; + + if (ioctl(fd, KDSKBMODE, K_XLATE) < 0) + r = -errno; + + if (loop_write(fd, "\033%@", 3, false) < 0) + r = -errno; + + k = write_one_line_file("/sys/module/vt/parameters/default_utf8", "0"); + if (k < 0) + r = k; + + if (r < 0) + log_warning("Failed to disable UTF-8: %s", strerror(-r)); + + return r; +} + +static int enable_utf8(int fd) { + int r = 0, k; + + if (ioctl(fd, KDSKBMODE, K_UNICODE) < 0) + r = -errno; + + if (loop_write(fd, "\033%G", 3, false) < 0) + r = -errno; + + k = write_one_line_file("/sys/module/vt/parameters/default_utf8", "1"); + if (k < 0) + r = k; + + if (r < 0) + log_warning("Failed to enable UTF-8: %s", strerror(-r)); + + return r; +} + +static int load_keymap(const char *vc, const char *map, const char *map_toggle, bool utf8, pid_t *_pid) { + const char *args[8]; + int i = 0; + pid_t pid; + + if (isempty(map)) { + /* An empty map means kernel map */ + *_pid = 0; + return 0; + } + + args[i++] = KBD_LOADKEYS; + args[i++] = "-q"; + args[i++] = "-C"; + args[i++] = vc; + if (utf8) + args[i++] = "-u"; + args[i++] = map; + if (map_toggle) + args[i++] = map_toggle; + args[i++] = NULL; + + pid = fork(); + if (pid < 0) { + log_error("Failed to fork: %m"); + return -errno; + } else if (pid == 0) { + execv(args[0], (char **) args); + _exit(EXIT_FAILURE); + } + + *_pid = pid; + return 0; +} + +static int load_font(const char *vc, const char *font, const char *map, const char *unimap, pid_t *_pid) { + const char *args[9]; + int i = 0; + pid_t pid; + + if (isempty(font)) { + /* An empty font means kernel font */ + *_pid = 0; + return 0; + } + + args[i++] = KBD_SETFONT; + args[i++] = "-C"; + args[i++] = vc; + args[i++] = font; + if (map) { + args[i++] = "-m"; + args[i++] = map; + } + if (unimap) { + args[i++] = "-u"; + args[i++] = unimap; + } + args[i++] = NULL; + + pid = fork(); + if (pid < 0) { + log_error("Failed to fork: %m"); + return -errno; + } else if (pid == 0) { + execv(args[0], (char **) args); + _exit(EXIT_FAILURE); + } + + *_pid = pid; + return 0; +} + +int main(int argc, char **argv) { + const char *vc; + char *vc_keymap = NULL; + char *vc_keymap_toggle = NULL; + char *vc_font = NULL; + char *vc_font_map = NULL; + char *vc_font_unimap = NULL; + int fd = -1; + bool utf8; + int r = EXIT_FAILURE; + pid_t font_pid = 0, keymap_pid = 0; + + log_set_target(LOG_TARGET_AUTO); + log_parse_environment(); + log_open(); + + umask(0022); + + if (argv[1]) + vc = argv[1]; + else + vc = "/dev/tty0"; + + fd = open_terminal(vc, O_RDWR|O_CLOEXEC); + if (fd < 0) { + log_error("Failed to open %s: %m", vc); + goto finish; + } + + if (!is_vconsole(fd)) { + log_error("Device %s is not a virtual console.", vc); + goto finish; + } + + utf8 = is_locale_utf8(); + + r = 0; + + if (detect_container(NULL) <= 0) { + r = parse_env_file("/proc/cmdline", WHITESPACE, + "vconsole.keymap", &vc_keymap, + "vconsole.keymap.toggle", &vc_keymap_toggle, + "vconsole.font", &vc_font, + "vconsole.font.map", &vc_font_map, + "vconsole.font.unimap", &vc_font_unimap, + NULL); + + if (r < 0 && r != -ENOENT) + log_warning("Failed to read /proc/cmdline: %s", strerror(-r)); + } + + /* Hmm, nothing set on the kernel cmd line? Then let's + * try /etc/vconsole.conf */ + if (r <= 0) { + r = parse_env_file("/etc/vconsole.conf", NEWLINE, + "KEYMAP", &vc_keymap, + "KEYMAP_TOGGLE", &vc_keymap_toggle, + "FONT", &vc_font, + "FONT_MAP", &vc_font_map, + "FONT_UNIMAP", &vc_font_unimap, + NULL); + + if (r < 0 && r != -ENOENT) + log_warning("Failed to read /etc/vconsole.conf: %s", strerror(-r)); + } + + if (r <= 0) { + } + + r = EXIT_FAILURE; + + if (utf8) + enable_utf8(fd); + else + disable_utf8(fd); + + + if (load_keymap(vc, vc_keymap, vc_keymap_toggle, utf8, &keymap_pid) >= 0 && + load_font(vc, vc_font, vc_font_map, vc_font_unimap, &font_pid) >= 0) + r = EXIT_SUCCESS; + +finish: + if (keymap_pid > 0) + wait_for_terminate_and_warn(KBD_LOADKEYS, keymap_pid); + + if (font_pid > 0) + wait_for_terminate_and_warn(KBD_SETFONT, font_pid); + + free(vc_keymap); + free(vc_font); + free(vc_font_map); + free(vc_font_unimap); + + if (fd >= 0) + close_nointr_nofail(fd); + + return r; +} diff --git a/sysctl.d/.gitignore b/sysctl.d/.gitignore new file mode 100644 index 000000000..7563539ab --- /dev/null +++ b/sysctl.d/.gitignore @@ -0,0 +1 @@ +/coredump.conf diff --git a/sysctl.d/Makefile b/sysctl.d/Makefile new file mode 120000 index 000000000..bd1047548 --- /dev/null +++ b/sysctl.d/Makefile @@ -0,0 +1 @@ +../src/Makefile \ No newline at end of file diff --git a/sysctl.d/coredump.conf.in b/sysctl.d/coredump.conf.in new file mode 100644 index 000000000..5c791b791 --- /dev/null +++ b/sysctl.d/coredump.conf.in @@ -0,0 +1,10 @@ +# This file is part of systemd. +# +# 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. + +# See sysctl.d(5) for details + +kernel.core_pattern=|@rootlibexecdir@/systemd-coredump %p %u %g %s %t %e diff --git a/test/.gitignore b/test/.gitignore new file mode 100644 index 000000000..93c1f950f --- /dev/null +++ b/test/.gitignore @@ -0,0 +1,3 @@ +.testdir +test.log +/sys diff --git a/test/Makefile b/test/Makefile new file mode 100644 index 000000000..987a32548 --- /dev/null +++ b/test/Makefile @@ -0,0 +1,20 @@ +# Just a little hook script to easy building when in this directory +.PHONY: all check clean + +all: + $(MAKE) -C .. + +clean: + @for i in TEST-[0-9]*; do \ + [ -d $$i ] || continue ; \ + [ -f $$i/Makefile ] || continue ; \ + make -C $$i clean ; \ + done + +check: + $(MAKE) -C .. all + @for i in TEST-[0-9]*; do \ + [ -d $$i ] || continue ; \ + [ -f $$i/Makefile ] || continue ; \ + make -C $$i all ; \ + done diff --git a/test/README.testsuite b/test/README.testsuite new file mode 100644 index 000000000..0f96b984a --- /dev/null +++ b/test/README.testsuite @@ -0,0 +1,35 @@ +The extended testsuite only works with uid=0. It contains of several +subdirectories named "test/TEST-??-*", which are run one by one. + +To run the extended testsuite do the following: + +$ make all +$ cd test +$ sudo make clean check +... +make[1]: Entering directory `/mnt/data/harald/git/systemd/test/TEST-01-BASIC' +Making all in . +Making all in po +Making all in docs/libudev +Making all in docs/gudev +TEST: Basic systemd setup [OK] +make[1]: Leaving directory `/mnt/data/harald/git/systemd/test/TEST-01-BASIC' +... + +If one of the tests fails, then $subdir/test.log contains the log file of +the test. + +To debug a special testcase of the testsuite do: + +$ make all +$ cd test/TEST-01-BASIC +$ sudo make clean setup run + +If you want to log in the testsuite virtual machine, you can specify +additional kernel command line parameter with $DEBUGFAIL. + +$ sudo sh -c 'DEBUGFAIL="systemd.unit=multi-user.target" make clean setup run' + +you can even skip the "clean" and "setup" if you want to run the machine again. + +$ sudo sh -c 'DEBUGFAIL="systemd.unit=multi-user.target" make run' diff --git a/test/TEST-01-BASIC/Makefile b/test/TEST-01-BASIC/Makefile new file mode 100644 index 000000000..5e89a29ef --- /dev/null +++ b/test/TEST-01-BASIC/Makefile @@ -0,0 +1,10 @@ +all: + @make -s --no-print-directory -C ../.. all + @basedir=../.. TEST_BASE_DIR=../ ./test.sh --all +setup: + @make --no-print-directory -C ../.. all + @basedir=../.. TEST_BASE_DIR=../ ./test.sh --setup +clean: + @basedir=../.. TEST_BASE_DIR=../ ./test.sh --clean +run: + @basedir=../.. TEST_BASE_DIR=../ ./test.sh --run diff --git a/test/TEST-01-BASIC/test.sh b/test/TEST-01-BASIC/test.sh new file mode 100755 index 000000000..eb6a80a07 --- /dev/null +++ b/test/TEST-01-BASIC/test.sh @@ -0,0 +1,252 @@ +#!/bin/bash +# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*- +# ex: ts=8 sw=4 sts=4 et filetype=sh +TEST_DESCRIPTION="Basic systemd setup" + +KVERSION=${KVERSION-$(uname -r)} +KERNEL_VER=$(uname -r) + +# Uncomment this to debug failures +#DEBUGFAIL="systemd.unit=multi-user.target" +DEBUGTOOLS="df free ls stty cat ps ln ip route dmesg dhclient mkdir cp ping dhclient strace less grep id tty touch du sort" + +run_qemu() { + # TODO: qemu wrapper script: http://www.spinics.net/lists/kvm/msg72389.html + qemu-kvm \ + -hda $TESTDIR/rootdisk.img \ + -m 512M -nographic \ + -net none -kernel /boot/vmlinuz-$KERNEL_VER \ + -append "root=/dev/sda1 systemd.log_level=debug raid=noautodetect loglevel=2 init=/usr/lib/systemd/systemd ro console=ttyS0,115200n81 selinux=0 $DEBUGFAIL" || return 1 + + ret=1 + mkdir -p $TESTDIR/root + mount ${LOOPDEV}p1 $TESTDIR/root + [[ -e $TESTDIR/root/testok ]] && ret=0 + cp -a $TESTDIR/root/failed $TESTDIR + cp -a $TESTDIR/root/var/log/journal $TESTDIR + umount $TESTDIR/root + cat $TESTDIR/failed + ls -l $TESTDIR/journal/*/*.journal + test -s $TESTDIR/failed && ret=$(($ret+1)) + return $ret +} + + +run_nspawn() { + systemd-nspawn -b -D $TESTDIR/nspawn-root --capability=CAP_AUDIT_CONTROL,CAP_AUDIT_WRITE /usr/lib/systemd/systemd + ret=1 + [[ -e $TESTDIR/nspawn-root/testok ]] && ret=0 + cp -a $TESTDIR/nspawn-root/failed $TESTDIR + cp -a $TESTDIR/nspawn-root/var/log/journal $TESTDIR + cat $TESTDIR/failed + ls -l $TESTDIR/journal/*/*.journal + test -s $TESTDIR/failed && ret=$(($ret+1)) + return $ret +} + + +test_run() { + if check_qemu ; then + run_qemu || return 1 + else + dwarn "can't run qemu-kvm, skipping" + fi + if check_nspawn; then + run_nspawn || return 1 + else + dwarn "can't run systemd-nspawn, skipping" + fi + return 0 +} + +test_setup() { + rm -f $TESTDIR/rootdisk.img + # Create the blank file to use as a root filesystem + dd if=/dev/null of=$TESTDIR/rootdisk.img bs=1M seek=200 + LOOPDEV=$(losetup --show -P -f $TESTDIR/rootdisk.img) + [ -b $LOOPDEV ] || return 1 + echo "LOOPDEV=$LOOPDEV" >> $STATEFILE + sfdisk -C 6400 -H 2 -S 32 -L $LOOPDEV <$TESTDIR/keyfile + mkdir -p $TESTDIR/root + mount ${LOOPDEV}p1 $TESTDIR/root + mkdir -p $TESTDIR/root/run + + # Create what will eventually be our root filesystem onto an overlay + ( + LOG_LEVEL=5 + initdir=$TESTDIR/root + + # create the basic filesystem layout + setup_basic_dirs + + # install compiled files + (cd ../..; make DESTDIR=$initdir install) + + # remove unneeded documentation + rm -fr $initdir/usr/share/{man,doc,gtk-doc} + + # install possible missing libraries + for i in $initdir/{sbin,bin}/* $initdir/lib/systemd/*; do + inst_libs $i + done + + # make a journal directory + mkdir -p $initdir/var/log/journal + + # install some basic config files + inst /etc/sysconfig/init + inst /etc/passwd + inst /etc/shadow + inst /etc/group + inst /etc/shells + inst /etc/nsswitch.conf + inst /etc/pam.conf + inst /etc/securetty + inst /etc/os-release + inst /etc/localtime + # we want an empty environment + > $initdir/etc/environment + > $initdir/etc/machine-id + + # set the hostname + echo systemd-testsuite > $initdir/etc/hostname + + eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) + + cat >$initdir/etc/fstab <$initdir/etc/systemd/system/testsuite.target <$initdir/etc/systemd/system/testsuite.service < /failed ; echo OK > /testok; while : ;do echo "testsuite service waiting for journal to move to /var/log/journal" > /dev/console ; for i in /var/log/journal/*;do [ -d "\$i" ] && echo "\$i" && break 2; done; sleep 1; done; sleep 1; exit 0;' +ExecStopPost=/usr/bin/systemctl poweroff +Type=oneshot +EOF + mkdir -p $initdir/etc/systemd/system/testsuite.target.wants + ln -fs ../testsuite.service $initdir/etc/systemd/system/testsuite.target.wants/testsuite.service + + # make the testsuite the default target + ln -fs testsuite.target $initdir/etc/systemd/system/default.target + mkdir -p $initdir/etc/rc.d + cat >$initdir/etc/rc.d/rc.local </dev/null + [[ $LOOPDEV ]] && losetup -d $LOOPDEV + return 0 +} + +. $TEST_BASE_DIR/test-functions +do_test "$@" diff --git a/test/TEST-02-CRYPTSETUP/Makefile b/test/TEST-02-CRYPTSETUP/Makefile new file mode 120000 index 000000000..e9f93b110 --- /dev/null +++ b/test/TEST-02-CRYPTSETUP/Makefile @@ -0,0 +1 @@ +../TEST-01-BASIC/Makefile \ No newline at end of file diff --git a/test/TEST-02-CRYPTSETUP/test.sh b/test/TEST-02-CRYPTSETUP/test.sh new file mode 100755 index 000000000..790dc3074 --- /dev/null +++ b/test/TEST-02-CRYPTSETUP/test.sh @@ -0,0 +1,264 @@ +#!/bin/bash +# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*- +# ex: ts=8 sw=4 sts=4 et filetype=sh +TEST_DESCRIPTION="cryptsetup systemd setup" + +KVERSION=${KVERSION-$(uname -r)} +KERNEL_VER=$(uname -r) + +# Uncomment this to debug failures +#DEBUGFAIL="systemd.unit=multi-user.target" +DEBUGTOOLS="df free ls stty cat ps ln ip route dmesg dhclient mkdir cp ping dhclient strace less grep id tty touch du sort" + +run_qemu() { + # TODO: qemu wrapper script: http://www.spinics.net/lists/kvm/msg72389.html + qemu-kvm \ + -hda $TESTDIR/rootdisk.img \ + -m 512M -nographic \ + -net none -kernel /boot/vmlinuz-$KERNEL_VER \ + -append "root=/dev/sda1 systemd.log_level=debug raid=noautodetect loglevel=2 init=/usr/lib/systemd/systemd ro console=ttyS0,115200n81 selinux=0 $DEBUGFAIL" || return 1 + + ret=1 + mkdir -p $TESTDIR/root + mount ${LOOPDEV}p1 $TESTDIR/root + [[ -e $TESTDIR/root/testok ]] && ret=0 + cp -a $TESTDIR/root/failed $TESTDIR + cryptsetup luksOpen ${LOOPDEV}p2 varcrypt <$TESTDIR/keyfile + mount /dev/mapper/varcrypt $TESTDIR/root/var + cp -a $TESTDIR/root/var/log/journal $TESTDIR + umount $TESTDIR/root/var + umount $TESTDIR/root + cryptsetup luksClose /dev/mapper/varcrypt + cat $TESTDIR/failed + ls -l $TESTDIR/journal/*/*.journal + test -s $TESTDIR/failed && ret=$(($ret+1)) + return $ret +} + + +test_run() { + if check_qemu ; then + run_qemu || return 1 + else + dwarn "can't run qemu-kvm, skipping" + fi + return 0 +} + +test_setup() { + rm -f $TESTDIR/rootdisk.img + # Create the blank file to use as a root filesystem + dd if=/dev/null of=$TESTDIR/rootdisk.img bs=1M seek=200 + LOOPDEV=$(losetup --show -P -f $TESTDIR/rootdisk.img) + [ -b $LOOPDEV ] || return 1 + echo "LOOPDEV=$LOOPDEV" >> $STATEFILE + sfdisk -C 6400 -H 2 -S 32 -L $LOOPDEV <$TESTDIR/keyfile + cryptsetup -q luksFormat ${LOOPDEV}p2 $TESTDIR/keyfile + cryptsetup luksOpen ${LOOPDEV}p2 varcrypt <$TESTDIR/keyfile + mkfs.ext3 -L var /dev/mapper/varcrypt + mkdir -p $TESTDIR/root + mount ${LOOPDEV}p1 $TESTDIR/root + mkdir -p $TESTDIR/root/run + mkdir -p $TESTDIR/root/var + mount /dev/mapper/varcrypt $TESTDIR/root/var + + # Create what will eventually be our root filesystem onto an overlay + ( + LOG_LEVEL=5 + initdir=$TESTDIR/root + + # create the basic filesystem layout + setup_basic_dirs + + # install compiled files + (cd ../..; make DESTDIR=$initdir install) + + # remove unneeded documentation + rm -fr $initdir/usr/share/{man,doc,gtk-doc} + + # install possible missing libraries + for i in $initdir/{sbin,bin}/* $initdir/lib/systemd/*; do + inst_libs $i + done + + # make a journal directory + mkdir -p $initdir/var/log/journal + + # install some basic config files + inst /etc/sysconfig/init + inst /etc/passwd + inst /etc/shadow + inst /etc/group + inst /etc/shells + inst /etc/nsswitch.conf + inst /etc/pam.conf + inst /etc/securetty + inst /etc/os-release + inst /etc/localtime + # we want an empty environment + > $initdir/etc/environment + > $initdir/etc/machine-id + + # set the hostname + echo systemd-testsuite > $initdir/etc/hostname + + eval $(udevadm info --export --query=env --name=/dev/mapper/varcrypt) + eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) + + cat >$initdir/etc/crypttab < $initdir/etc/varkey + cat $initdir/etc/crypttab | ddebug + + cat >$initdir/etc/fstab <$initdir/etc/systemd/system/testsuite.target <$initdir/etc/systemd/system/testsuite.service < /failed ; echo OK > /testok; while : ;do systemd-cat echo "testsuite service waiting for /var/log/journal" ; echo "testsuite service waiting for journal to move to /var/log/journal" > /dev/console ; for i in /var/log/journal/*;do [ -d "\$i" ] && echo "\$i" && break 2; done; sleep 1; done; sleep 1; exit 0;' +ExecStopPost=/usr/bin/systemctl poweroff +Type=oneshot +EOF + mkdir -p $initdir/etc/systemd/system/testsuite.target.wants + ln -fs ../testsuite.service $initdir/etc/systemd/system/testsuite.target.wants/testsuite.service + + # make the testsuite the default target + ln -fs testsuite.target $initdir/etc/systemd/system/default.target + mkdir -p $initdir/etc/rc.d + cat >$initdir/etc/rc.d/rc.local </dev/null && dracut_install dmeventd + + inst_libdir_file "libdevmapper-event.so*" + + inst_rules 10-dm.rules 13-dm-disk.rules 95-dm-notify.rules + + # install libnss_files for login + inst_libdir_file "libnss_files*" + + # install dbus and pam + find \ + /etc/dbus-1 \ + /etc/pam.d \ + /etc/security \ + /lib64/security \ + /lib/security -xtype f \ + | while read file; do + inst $file + done + + # install dbus socket and service file + inst /usr/lib/systemd/system/dbus.socket + inst /usr/lib/systemd/system/dbus.service + + # install basic keyboard maps and fonts + for i in \ + /usr/lib/kbd/consolefonts/latarcyrheb-sun16* \ + /usr/lib/kbd/keymaps/include/* \ + /usr/lib/kbd/keymaps/i386/include/* \ + /usr/lib/kbd/keymaps/i386/qwerty/us.*; do + [[ -f $i ]] || continue + inst $i + done + + # some basic terminfo files + for _terminfodir in /lib/terminfo /etc/terminfo /usr/share/terminfo; do + [ -f ${_terminfodir}/l/linux ] && break + done + dracut_install -o ${_terminfodir}/l/linux + + # softlink mtab + ln -fs /proc/self/mounts $initdir/etc/mtab + + # install any Exec's from the service files + egrep -ho '^Exec[^ ]*=[^ ]+' $initdir/lib/systemd/system/*.service \ + | while read i; do + i=${i##Exec*=}; i=${i##-} + inst $i + done + + # install plymouth, if found... else remove plymouth service files + # if [ -x /usr/libexec/plymouth/plymouth-populate-initrd ]; then + # PLYMOUTH_POPULATE_SOURCE_FUNCTIONS="$TEST_BASE_DIR/test-functions" \ + # /usr/libexec/plymouth/plymouth-populate-initrd -t $initdir + # dracut_install plymouth plymouthd + # else + rm -f $initdir/{usr/lib,etc}/systemd/system/plymouth* $initdir/{usr/lib,etc}/systemd/system/*/plymouth* + # fi + + # some helper tools for debugging + [[ $DEBUGTOOLS ]] && dracut_install $DEBUGTOOLS + + # install ld.so.conf* and run ldconfig + cp -a /etc/ld.so.conf* $initdir/etc + ldconfig -r "$initdir" + ddebug "Strip binaeries" + find "$initdir" -perm +111 -type f | xargs strip --strip-unneeded | ddebug + + # copy depmod files + inst /lib/modules/$KERNEL_VER/modules.order + inst /lib/modules/$KERNEL_VER/modules.builtin + # generate module dependencies + if [[ -d $initdir/lib/modules/$KERNEL_VER ]] && \ + ! depmod -a -b "$initdir" $KERNEL_VER; then + dfatal "\"depmod -a $KERNEL_VER\" failed." + exit 1 + fi + ) + rm -fr $TESTDIR/nspawn-root + ddebug "cp -ar $TESTDIR/root $TESTDIR/nspawn-root" + cp -ar $TESTDIR/root $TESTDIR/nspawn-root + # we don't mount in the nspawn root + rm -fr $TESTDIR/nspawn-root/etc/fstab + + ddebug "umount $TESTDIR/root/var" + umount $TESTDIR/root/var + cryptsetup luksClose /dev/mapper/varcrypt + ddebug "umount $TESTDIR/root" + umount $TESTDIR/root +} + +test_cleanup() { + umount $TESTDIR/root/var 2>/dev/null + [[ -b /dev/mapper/varcrypt ]] && cryptsetup luksClose /dev/mapper/varcrypt + umount $TESTDIR/root 2>/dev/null + [[ $LOOPDEV ]] && losetup -d $LOOPDEV + return 0 +} + +. $TEST_BASE_DIR/test-functions +do_test "$@" diff --git a/test/a.service b/test/a.service new file mode 100644 index 000000000..4168d2d05 --- /dev/null +++ b/test/a.service @@ -0,0 +1,7 @@ +[Unit] +Description=A +Requires=b.service +Before=b.service + +[Service] +ExecStart=/bin/true diff --git a/test/b.service b/test/b.service new file mode 100644 index 000000000..e03bae36b --- /dev/null +++ b/test/b.service @@ -0,0 +1,6 @@ +[Unit] +Description=B +Wants=f.service + +[Service] +ExecStart=/bin/true diff --git a/test/c.service b/test/c.service new file mode 100644 index 000000000..e2f60a8fb --- /dev/null +++ b/test/c.service @@ -0,0 +1,6 @@ +[Unit] +Description=C +Requires=a.service + +[Service] +ExecStart=/bin/true diff --git a/test/d.service b/test/d.service new file mode 100644 index 000000000..921fd2ee1 --- /dev/null +++ b/test/d.service @@ -0,0 +1,8 @@ +[Unit] +Description=D:Cyclic +After=b.service +Before=a.service +Requires=a.service + +[Service] +ExecStart=/bin/true diff --git a/test/e.service b/test/e.service new file mode 100644 index 000000000..5ba98c7c4 --- /dev/null +++ b/test/e.service @@ -0,0 +1,8 @@ +[Unit] +Description=E:Cyclic +After=b.service +Before=a.service +Wants=a.service + +[Service] +ExecStart=/bin/true diff --git a/test/f.service b/test/f.service new file mode 100644 index 000000000..7dde681c1 --- /dev/null +++ b/test/f.service @@ -0,0 +1,5 @@ +[Unit] +Description=F + +[Service] +ExecStart=/bin/true diff --git a/test/g.service b/test/g.service new file mode 100644 index 000000000..cbfa82a45 --- /dev/null +++ b/test/g.service @@ -0,0 +1,6 @@ +[Unit] +Description=G +Conflicts=e.service + +[Service] +ExecStart=/bin/true diff --git a/test/h.service b/test/h.service new file mode 100644 index 000000000..74a7751ca --- /dev/null +++ b/test/h.service @@ -0,0 +1,6 @@ +[Unit] +Description=H +Wants=g.service + +[Service] +ExecStart=/bin/true diff --git a/test/rule-syntax-check.py b/test/rule-syntax-check.py new file mode 100755 index 000000000..b18f8780c --- /dev/null +++ b/test/rule-syntax-check.py @@ -0,0 +1,64 @@ +#!/usr/bin/python +# Simple udev rules syntax checker +# +# (C) 2010 Canonical Ltd. +# Author: Martin Pitt +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +import re +import sys + +if len(sys.argv) < 2: + print >> sys.stderr, 'Usage: %s [...]' % sys.argv[0] + sys.exit(2) + +no_args_tests = re.compile('(ACTION|DEVPATH|KERNELS?|NAME|SYMLINK|SUBSYSTEMS?|DRIVERS?|TAG|RESULT|TEST)\s*(?:=|!)=\s*"([^"]*)"$') +args_tests = re.compile('(ATTRS?|ENV|TEST){([a-zA-Z0-9/_.*%-]+)}\s*(?:=|!)=\s*"([^"]*)"$') +no_args_assign = re.compile('(NAME|SYMLINK|OWNER|GROUP|MODE|TAG|PROGRAM|RUN|LABEL|GOTO|WAIT_FOR|OPTIONS|IMPORT)\s*(?:\+=|:=|=)\s*"([^"]*)"$') +args_assign = re.compile('(ATTR|ENV|IMPORT|RUN){([a-zA-Z0-9/_.*%-]+)}\s*(=|\+=)\s*"([^"]*)"$') + +result = 0 +buffer = '' +for path in sys.argv[1:]: + lineno = 0 + for line in open(path): + lineno += 1 + + # handle line continuation + if line.endswith('\\\n'): + buffer += line[:-2] + continue + else: + line = buffer + line + buffer = '' + + # filter out comments and empty lines + line = line.strip() + if not line or line.startswith('#'): + continue + + for clause in line.split(','): + clause = clause.strip() + if not (no_args_tests.match(clause) or args_tests.match(clause) or + no_args_assign.match(clause) or args_assign.match(clause)): + + print('Invalid line %s:%i: %s' % (path, lineno, line)) + print(' clause:', clause) + print() + result = 1 + break + +sys.exit(result) diff --git a/test/rules-test.sh b/test/rules-test.sh new file mode 100755 index 000000000..1e224ff8b --- /dev/null +++ b/test/rules-test.sh @@ -0,0 +1,15 @@ +#!/bin/sh +# Call the udev rule syntax checker on all rules that we ship +# +# (C) 2010 Canonical Ltd. +# Author: Martin Pitt + +[ -n "$srcdir" ] || srcdir=`dirname $0`/.. + +# skip if we don't have python +type python >/dev/null 2>&1 || { + echo "$0: No python installed, skipping udev rule syntax check" + exit 0 +} + +$srcdir/test/rule-syntax-check.py `find $srcdir/rules -name '*.rules'` diff --git a/test/sched_idle_bad.service b/test/sched_idle_bad.service new file mode 100644 index 000000000..589a87ccf --- /dev/null +++ b/test/sched_idle_bad.service @@ -0,0 +1,6 @@ +[Unit] +Description=Bad sched priority for Idle + +[Service] +ExecStart=/bin/true +CPUSchedulingPriority=1 diff --git a/test/sched_idle_ok.service b/test/sched_idle_ok.service new file mode 100644 index 000000000..262ef3e31 --- /dev/null +++ b/test/sched_idle_ok.service @@ -0,0 +1,6 @@ +[Unit] +Description=Sched idle with prio 0 + +[Service] +ExecStart=/bin/true +CPUSchedulingPriority=0 diff --git a/test/sched_rr_bad.service b/test/sched_rr_bad.service new file mode 100644 index 000000000..0be534a54 --- /dev/null +++ b/test/sched_rr_bad.service @@ -0,0 +1,8 @@ +[Unit] +Description=Bad sched priority for RR + +[Service] +ExecStart=/bin/true +CPUSchedulingPolicy=rr +CPUSchedulingPriority=0 +CPUSchedulingPriority=100 diff --git a/test/sched_rr_change.service b/test/sched_rr_change.service new file mode 100644 index 000000000..b3e3a000f --- /dev/null +++ b/test/sched_rr_change.service @@ -0,0 +1,9 @@ +[Unit] +Description=Change prio + +[Service] +ExecStart=/bin/true +CPUSchedulingPolicy=rr +CPUSchedulingPriority=1 +CPUSchedulingPriority=2 +CPUSchedulingPriority=99 diff --git a/test/sched_rr_ok.service b/test/sched_rr_ok.service new file mode 100644 index 000000000..b88adc543 --- /dev/null +++ b/test/sched_rr_ok.service @@ -0,0 +1,6 @@ +[Unit] +Description=Default prio for RR + +[Service] +ExecStart=/bin/true +CPUSchedulingPolicy=rr diff --git a/test/sys.tar.xz b/test/sys.tar.xz new file mode 100644 index 000000000..49ee8027b Binary files /dev/null and b/test/sys.tar.xz differ diff --git a/test/test-functions b/test/test-functions new file mode 100644 index 000000000..0587cd4fe --- /dev/null +++ b/test/test-functions @@ -0,0 +1,864 @@ +#!/bin/bash +# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*- +# ex: ts=8 sw=4 sts=4 et filetype=sh +PATH=/sbin:/bin:/usr/sbin:/usr/bin +export PATH + +KERNEL_VER=${KERNEL_VER-$(uname -r)} +KERNEL_MODS="/lib/modules/$KERNEL_VER/" + +setup_basic_dirs() { + for d in usr/bin usr/sbin bin etc lib "$libdir" sbin tmp usr var var/log dev proc sys sysroot root run run/lock run/initramfs; do + if [ -L "/$d" ]; then + inst_symlink "/$d" + else + inst_dir "/$d" + fi + done + + ln -sfn /run "$initdir/var/run" + ln -sfn /run/lock "$initdir/var/lock" +} + +inst_libs() { + local _bin=$1 + local _so_regex='([^ ]*/lib[^/]*/[^ ]*\.so[^ ]*)' + local _file _line + + LC_ALL=C ldd "$_bin" 2>/dev/null | while read _line; do + [[ $_line = 'not a dynamic executable' ]] && break + + if [[ $_line =~ $_so_regex ]]; then + _file=${BASH_REMATCH[1]} + [[ -e ${initdir}/$_file ]] && continue + inst_library "$_file" + continue + fi + + if [[ $_line =~ not\ found ]]; then + dfatal "Missing a shared library required by $_bin." + dfatal "Run \"ldd $_bin\" to find out what it is." + dfatal "$_line" + dfatal "dracut cannot create an initrd." + exit 1 + fi + done +} + +import_testdir() { + STATEFILE=".testdir" + [[ -e $STATEFILE ]] && . $STATEFILE + if [[ -z "$TESTDIR" ]] || [[ ! -d "$TESTDIR" ]]; then + TESTDIR=$(mktemp --tmpdir=/var/tmp -d -t systemd-test.XXXXXX) + echo "TESTDIR=\"$TESTDIR\"" > $STATEFILE + export TESTDIR + fi +} + +## @brief Converts numeric logging level to the first letter of level name. +# +# @param lvl Numeric logging level in range from 1 to 6. +# @retval 1 if @a lvl is out of range. +# @retval 0 if @a lvl is correct. +# @result Echoes first letter of level name. +_lvl2char() { + case "$1" in + 1) echo F;; + 2) echo E;; + 3) echo W;; + 4) echo I;; + 5) echo D;; + 6) echo T;; + *) return 1;; + esac +} + +## @brief Internal helper function for _do_dlog() +# +# @param lvl Numeric logging level. +# @param msg Message. +# @retval 0 It's always returned, even if logging failed. +# +# @note This function is not supposed to be called manually. Please use +# dtrace(), ddebug(), or others instead which wrap this one. +# +# This function calls _do_dlog() either with parameter msg, or if +# none is given, it will read standard input and will use every line as +# a message. +# +# This enables: +# dwarn "This is a warning" +# echo "This is a warning" | dwarn +LOG_LEVEL=4 + +dlog() { + [ -z "$LOG_LEVEL" ] && return 0 + [ $1 -le $LOG_LEVEL ] || return 0 + local lvl="$1"; shift + local lvlc=$(_lvl2char "$lvl") || return 0 + + if [ $# -ge 1 ]; then + echo "$lvlc: $*" + else + while read line; do + echo "$lvlc: " "$line" + done + fi +} + +## @brief Logs message at TRACE level (6) +# +# @param msg Message. +# @retval 0 It's always returned, even if logging failed. +dtrace() { + set +x + dlog 6 "$@" + [ -n "$debug" ] && set -x || : +} + +## @brief Logs message at DEBUG level (5) +# +# @param msg Message. +# @retval 0 It's always returned, even if logging failed. +ddebug() { +# set +x + dlog 5 "$@" +# [ -n "$debug" ] && set -x || : +} + +## @brief Logs message at INFO level (4) +# +# @param msg Message. +# @retval 0 It's always returned, even if logging failed. +dinfo() { + set +x + dlog 4 "$@" + [ -n "$debug" ] && set -x || : +} + +## @brief Logs message at WARN level (3) +# +# @param msg Message. +# @retval 0 It's always returned, even if logging failed. +dwarn() { + set +x + dlog 3 "$@" + [ -n "$debug" ] && set -x || : +} + +## @brief Logs message at ERROR level (2) +# +# @param msg Message. +# @retval 0 It's always returned, even if logging failed. +derror() { +# set +x + dlog 2 "$@" +# [ -n "$debug" ] && set -x || : +} + +## @brief Logs message at FATAL level (1) +# +# @param msg Message. +# @retval 0 It's always returned, even if logging failed. +dfatal() { + set +x + dlog 1 "$@" + [ -n "$debug" ] && set -x || : +} + + +# Generic substring function. If $2 is in $1, return 0. +strstr() { [ "${1#*$2*}" != "$1" ]; } + +# normalize_path +# Prints the normalized path, where it removes any duplicated +# and trailing slashes. +# Example: +# $ normalize_path ///test/test// +# /test/test +normalize_path() { + shopt -q -s extglob + set -- "${1//+(\/)//}" + shopt -q -u extglob + echo "${1%/}" +} + +# convert_abs_rel +# Prints the relative path, when creating a symlink to from . +# Example: +# $ convert_abs_rel /usr/bin/test /bin/test-2 +# ../../bin/test-2 +# $ ln -s $(convert_abs_rel /usr/bin/test /bin/test-2) /usr/bin/test +convert_abs_rel() { + local __current __absolute __abssize __cursize __newpath + local -i __i __level + + set -- "$(normalize_path "$1")" "$(normalize_path "$2")" + + # corner case #1 - self looping link + [[ "$1" == "$2" ]] && { echo "${1##*/}"; return; } + + # corner case #2 - own dir link + [[ "${1%/*}" == "$2" ]] && { echo "."; return; } + + IFS="/" __current=($1) + IFS="/" __absolute=($2) + + __abssize=${#__absolute[@]} + __cursize=${#__current[@]} + + while [[ ${__absolute[__level]} == ${__current[__level]} ]] + do + (( __level++ )) + if (( __level > __abssize || __level > __cursize )) + then + break + fi + done + + for ((__i = __level; __i < __cursize-1; __i++)) + do + if ((__i > __level)) + then + __newpath=$__newpath"/" + fi + __newpath=$__newpath".." + done + + for ((__i = __level; __i < __abssize; __i++)) + do + if [[ -n $__newpath ]] + then + __newpath=$__newpath"/" + fi + __newpath=$__newpath${__absolute[__i]} + done + + echo "$__newpath" +} + + +# Install a directory, keeping symlinks as on the original system. +# Example: if /lib points to /lib64 on the host, "inst_dir /lib/file" +# will create ${initdir}/lib64, ${initdir}/lib64/file, +# and a symlink ${initdir}/lib -> lib64. +inst_dir() { + [[ -e ${initdir}/"$1" ]] && return 0 # already there + + local _dir="$1" _part="${1%/*}" _file + while [[ "$_part" != "${_part%/*}" ]] && ! [[ -e "${initdir}/${_part}" ]]; do + _dir="$_part $_dir" + _part=${_part%/*} + done + + # iterate over parent directories + for _file in $_dir; do + [[ -e "${initdir}/$_file" ]] && continue + if [[ -L $_file ]]; then + inst_symlink "$_file" + else + # create directory + mkdir -m 0755 -p "${initdir}/$_file" || return 1 + [[ -e "$_file" ]] && chmod --reference="$_file" "${initdir}/$_file" + chmod u+w "${initdir}/$_file" + fi + done +} + +# $1 = file to copy to ramdisk +# $2 (optional) Name for the file on the ramdisk +# Location of the image dir is assumed to be $initdir +# We never overwrite the target if it exists. +inst_simple() { + [[ -f "$1" ]] || return 1 + strstr "$1" "/" || return 1 + + local _src=$1 target="${2:-$1}" + if ! [[ -d ${initdir}/$target ]]; then + [[ -e ${initdir}/$target ]] && return 0 + [[ -L ${initdir}/$target ]] && return 0 + [[ -d "${initdir}/${target%/*}" ]] || inst_dir "${target%/*}" + fi + # install checksum files also + if [[ -e "${_src%/*}/.${_src##*/}.hmac" ]]; then + inst "${_src%/*}/.${_src##*/}.hmac" "${target%/*}/.${target##*/}.hmac" + fi + ddebug "Installing $_src" + cp --sparse=always -pfL "$_src" "${initdir}/$target" +} + +# find symlinks linked to given library file +# $1 = library file +# Function searches for symlinks by stripping version numbers appended to +# library filename, checks if it points to the same target and finally +# prints the list of symlinks to stdout. +# +# Example: +# rev_lib_symlinks libfoo.so.8.1 +# output: libfoo.so.8 libfoo.so +# (Only if libfoo.so.8 and libfoo.so exists on host system.) +rev_lib_symlinks() { + [[ ! $1 ]] && return 0 + + local fn="$1" orig="$(readlink -f "$1")" links='' + + [[ ${fn} =~ .*\.so\..* ]] || return 1 + + until [[ ${fn##*.} == so ]]; do + fn="${fn%.*}" + [[ -L ${fn} && $(readlink -f "${fn}") == ${orig} ]] && links+=" ${fn}" + done + + echo "${links}" +} + +# Same as above, but specialized to handle dynamic libraries. +# It handles making symlinks according to how the original library +# is referenced. +inst_library() { + local _src="$1" _dest=${2:-$1} _lib _reallib _symlink + strstr "$1" "/" || return 1 + [[ -e $initdir/$_dest ]] && return 0 + if [[ -L $_src ]]; then + # install checksum files also + if [[ -e "${_src%/*}/.${_src##*/}.hmac" ]]; then + inst "${_src%/*}/.${_src##*/}.hmac" "${_dest%/*}/.${_dest##*/}.hmac" + fi + _reallib=$(readlink -f "$_src") + inst_simple "$_reallib" "$_reallib" + inst_dir "${_dest%/*}" + [[ -d "${_dest%/*}" ]] && _dest=$(readlink -f "${_dest%/*}")/${_dest##*/} + ln -sfn $(convert_abs_rel "${_dest}" "${_reallib}") "${initdir}/${_dest}" + else + inst_simple "$_src" "$_dest" + fi + + # Create additional symlinks. See rev_symlinks description. + for _symlink in $(rev_lib_symlinks $_src) $(rev_lib_symlinks $_reallib); do + [[ ! -e $initdir/$_symlink ]] && { + ddebug "Creating extra symlink: $_symlink" + inst_symlink $_symlink + } + done +} + +# find a binary. If we were not passed the full path directly, +# search in the usual places to find the binary. +find_binary() { + if [[ -z ${1##/*} ]]; then + if [[ -x $1 ]] || { strstr "$1" ".so" && ldd $1 &>/dev/null; }; then + echo $1 + return 0 + fi + fi + + type -P $1 +} + +# Same as above, but specialized to install binary executables. +# Install binary executable, and all shared library dependencies, if any. +inst_binary() { + local _bin _target + _bin=$(find_binary "$1") || return 1 + _target=${2:-$_bin} + [[ -e $initdir/$_target ]] && return 0 + [[ -L $_bin ]] && inst_symlink $_bin $_target && return 0 + local _file _line + local _so_regex='([^ ]*/lib[^/]*/[^ ]*\.so[^ ]*)' + # I love bash! + LC_ALL=C ldd "$_bin" 2>/dev/null | while read _line; do + [[ $_line = 'not a dynamic executable' ]] && break + + if [[ $_line =~ $_so_regex ]]; then + _file=${BASH_REMATCH[1]} + [[ -e ${initdir}/$_file ]] && continue + inst_library "$_file" + continue + fi + + if [[ $_line =~ not\ found ]]; then + dfatal "Missing a shared library required by $_bin." + dfatal "Run \"ldd $_bin\" to find out what it is." + dfatal "$_line" + dfatal "dracut cannot create an initrd." + exit 1 + fi + done + inst_simple "$_bin" "$_target" +} + +# same as above, except for shell scripts. +# If your shell script does not start with shebang, it is not a shell script. +inst_script() { + local _bin + _bin=$(find_binary "$1") || return 1 + shift + local _line _shebang_regex + read -r -n 80 _line <"$_bin" + # If debug is set, clean unprintable chars to prevent messing up the term + [[ $debug ]] && _line=$(echo -n "$_line" | tr -c -d '[:print:][:space:]') + _shebang_regex='(#! *)(/[^ ]+).*' + [[ $_line =~ $_shebang_regex ]] || return 1 + inst "${BASH_REMATCH[2]}" && inst_simple "$_bin" "$@" +} + +# same as above, but specialized for symlinks +inst_symlink() { + local _src=$1 _target=${2:-$1} _realsrc + strstr "$1" "/" || return 1 + [[ -L $1 ]] || return 1 + [[ -L $initdir/$_target ]] && return 0 + _realsrc=$(readlink -f "$_src") + if ! [[ -e $initdir/$_realsrc ]]; then + if [[ -d $_realsrc ]]; then + inst_dir "$_realsrc" + else + inst "$_realsrc" + fi + fi + [[ ! -e $initdir/${_target%/*} ]] && inst_dir "${_target%/*}" + [[ -d ${_target%/*} ]] && _target=$(readlink -f ${_target%/*})/${_target##*/} + ln -sfn $(convert_abs_rel "${_target}" "${_realsrc}") "$initdir/$_target" +} + +# attempt to install any programs specified in a udev rule +inst_rule_programs() { + local _prog _bin + + if grep -qE 'PROGRAM==?"[^ "]+' "$1"; then + for _prog in $(grep -E 'PROGRAM==?"[^ "]+' "$1" | sed -r 's/.*PROGRAM==?"([^ "]+).*/\1/'); do + if [ -x /lib/udev/$_prog ]; then + _bin=/lib/udev/$_prog + else + _bin=$(find_binary "$_prog") || { + dinfo "Skipping program $_prog using in udev rule $(basename $1) as it cannot be found" + continue; + } + fi + + #dinfo "Installing $_bin due to it's use in the udev rule $(basename $1)" + dracut_install "$_bin" + done + fi +} + +# udev rules always get installed in the same place, so +# create a function to install them to make life simpler. +inst_rules() { + local _target=/etc/udev/rules.d _rule _found + + inst_dir "/lib/udev/rules.d" + inst_dir "$_target" + for _rule in "$@"; do + if [ "${rule#/}" = "$rule" ]; then + for r in /lib/udev/rules.d /etc/udev/rules.d; do + if [[ -f $r/$_rule ]]; then + _found="$r/$_rule" + inst_simple "$_found" + inst_rule_programs "$_found" + fi + done + fi + for r in '' ./ $dracutbasedir/rules.d/; do + if [[ -f ${r}$_rule ]]; then + _found="${r}$_rule" + inst_simple "$_found" "$_target/${_found##*/}" + inst_rule_programs "$_found" + fi + done + [[ $_found ]] || dinfo "Skipping udev rule: $_rule" + done +} + +# general purpose installation function +# Same args as above. +inst() { + local _x + + case $# in + 1) ;; + 2) [[ ! $initdir && -d $2 ]] && export initdir=$2 + [[ $initdir = $2 ]] && set $1;; + 3) [[ -z $initdir ]] && export initdir=$2 + set $1 $3;; + *) dfatal "inst only takes 1 or 2 or 3 arguments" + exit 1;; + esac + for _x in inst_symlink inst_script inst_binary inst_simple; do + $_x "$@" && return 0 + done + return 1 +} + +# install any of listed files +# +# If first argument is '-d' and second some destination path, first accessible +# source is installed into this path, otherwise it will installed in the same +# path as source. If none of listed files was installed, function return 1. +# On first successful installation it returns with 0 status. +# +# Example: +# +# inst_any -d /bin/foo /bin/bar /bin/baz +# +# Lets assume that /bin/baz exists, so it will be installed as /bin/foo in +# initramfs. +inst_any() { + local to f + + [[ $1 = '-d' ]] && to="$2" && shift 2 + + for f in "$@"; do + if [[ -e $f ]]; then + [[ $to ]] && inst "$f" "$to" && return 0 + inst "$f" && return 0 + fi + done + + return 1 +} + +# dracut_install [-o ] [ ... ] +# Install to the initramfs image +# -o optionally install the and don't fail, if it is not there +dracut_install() { + local _optional=no + if [[ $1 = '-o' ]]; then + _optional=yes + shift + fi + while (($# > 0)); do + if ! inst "$1" ; then + if [[ $_optional = yes ]]; then + dinfo "Skipping program $1 as it cannot be found and is" \ + "flagged to be optional" + else + dfatal "Failed to install $1" + exit 1 + fi + fi + shift + done +} + +# Install a single kernel module along with any firmware it may require. +# $1 = full path to kernel module to install +install_kmod_with_fw() { + # no need to go further if the module is already installed + + [[ -e "${initdir}/lib/modules/$KERNEL_VER/${1##*/lib/modules/$KERNEL_VER/}" ]] \ + && return 0 + + [[ -e "$initdir/.kernelmodseen/${1##*/}" ]] && return 0 + + if [[ $omit_drivers ]]; then + local _kmod=${1##*/} + _kmod=${_kmod%.ko} + _kmod=${_kmod/-/_} + if [[ "$_kmod" =~ $omit_drivers ]]; then + dinfo "Omitting driver $_kmod" + return 1 + fi + if [[ "${1##*/lib/modules/$KERNEL_VER/}" =~ $omit_drivers ]]; then + dinfo "Omitting driver $_kmod" + return 1 + fi + fi + + [ -d "$initdir/.kernelmodseen" ] && \ + > "$initdir/.kernelmodseen/${1##*/}" + + inst_simple "$1" "/lib/modules/$KERNEL_VER/${1##*/lib/modules/$KERNEL_VER/}" \ + || return $? + + local _modname=${1##*/} _fwdir _found _fw + _modname=${_modname%.ko*} + for _fw in $(modinfo -k $KERNEL_VER -F firmware $1 2>/dev/null); do + _found='' + for _fwdir in $fw_dir; do + if [[ -d $_fwdir && -f $_fwdir/$_fw ]]; then + inst_simple "$_fwdir/$_fw" "/lib/firmware/$_fw" + _found=yes + fi + done + if [[ $_found != yes ]]; then + if ! grep -qe "\<${_modname//-/_}\>" /proc/modules; then + dinfo "Possible missing firmware \"${_fw}\" for kernel module" \ + "\"${_modname}.ko\"" + else + dwarn "Possible missing firmware \"${_fw}\" for kernel module" \ + "\"${_modname}.ko\"" + fi + fi + done + return 0 +} + +# Do something with all the dependencies of a kernel module. +# Note that kernel modules depend on themselves using the technique we use +# $1 = function to call for each dependency we find +# It will be passed the full path to the found kernel module +# $2 = module to get dependencies for +# rest of args = arguments to modprobe +# _fderr specifies FD passed from surrounding scope +for_each_kmod_dep() { + local _func=$1 _kmod=$2 _cmd _modpath _options _found=0 + shift 2 + modprobe "$@" --ignore-install --show-depends $_kmod 2>&${_fderr} | ( + while read _cmd _modpath _options; do + [[ $_cmd = insmod ]] || continue + $_func ${_modpath} || exit $? + _found=1 + done + [[ $_found -eq 0 ]] && exit 1 + exit 0 + ) +} + +# filter kernel modules to install certain modules that meet specific +# requirements. +# $1 = search only in subdirectory of /kernel/$1 +# $2 = function to call with module name to filter. +# This function will be passed the full path to the module to test. +# The behavior of this function can vary depending on whether $hostonly is set. +# If it is, we will only look at modules that are already in memory. +# If it is not, we will look at all kernel modules +# This function returns the full filenames of modules that match $1 +filter_kernel_modules_by_path () ( + local _modname _filtercmd + if ! [[ $hostonly ]]; then + _filtercmd='find "$KERNEL_MODS/kernel/$1" "$KERNEL_MODS/extra"' + _filtercmd+=' "$KERNEL_MODS/weak-updates" -name "*.ko" -o -name "*.ko.gz"' + _filtercmd+=' -o -name "*.ko.xz"' + _filtercmd+=' 2>/dev/null' + else + _filtercmd='cut -d " " -f 1 $initdir/$$.ko + $2 $initdir/$$.ko && echo "$_modname" + rm -f $initdir/$$.ko + ;; + *.ko.xz) xz -dc "$_modname" > $initdir/$$.ko + $2 $initdir/$$.ko && echo "$_modname" + rm -f $initdir/$$.ko + ;; + esac + done +) +find_kernel_modules_by_path () ( + if ! [[ $hostonly ]]; then + find "$KERNEL_MODS/kernel/$1" "$KERNEL_MODS/extra" "$KERNEL_MODS/weak-updates" \ + -name "*.ko" -o -name "*.ko.gz" -o -name "*.ko.xz" 2>/dev/null + else + cut -d " " -f 1 /dev/null + fi +) + +filter_kernel_modules () { + filter_kernel_modules_by_path drivers "$1" +} + +find_kernel_modules () { + find_kernel_modules_by_path drivers +} + +# instmods [-c] [ ... ] +# instmods [-c] +# install kernel modules along with all their dependencies. +# can be e.g. "=block" or "=drivers/usb/storage" +instmods() { + [[ $no_kernel = yes ]] && return + # called [sub]functions inherit _fderr + local _fderr=9 + local _check=no + if [[ $1 = '-c' ]]; then + _check=yes + shift + fi + + function inst1mod() { + local _ret=0 _mod="$1" + case $_mod in + =*) + if [ -f $KERNEL_MODS/modules.${_mod#=} ]; then + ( [[ "$_mpargs" ]] && echo $_mpargs + cat "${KERNEL_MODS}/modules.${_mod#=}" ) \ + | instmods + else + ( [[ "$_mpargs" ]] && echo $_mpargs + find "$KERNEL_MODS" -path "*/${_mod#=}/*" -printf '%f\n' ) \ + | instmods + fi + ;; + --*) _mpargs+=" $_mod" ;; + i2o_scsi) return ;; # Do not load this diagnostic-only module + *) + _mod=${_mod##*/} + # if we are already installed, skip this module and go on + # to the next one. + [[ -f "$initdir/.kernelmodseen/${_mod%.ko}.ko" ]] && return + + if [[ $omit_drivers ]] && [[ "$1" =~ $omit_drivers ]]; then + dinfo "Omitting driver ${_mod##$KERNEL_MODS}" + return + fi + # If we are building a host-specific initramfs and this + # module is not already loaded, move on to the next one. + [[ $hostonly ]] && ! grep -qe "\<${_mod//-/_}\>" /proc/modules \ + && ! echo $add_drivers | grep -qe "\<${_mod}\>" \ + && return + + # We use '-d' option in modprobe only if modules prefix path + # differs from default '/'. This allows us to use Dracut with + # old version of modprobe which doesn't have '-d' option. + local _moddirname=${KERNEL_MODS%%/lib/modules/*} + [[ -n ${_moddirname} ]] && _moddirname="-d ${_moddirname}/" + + # ok, load the module, all its dependencies, and any firmware + # it may require + for_each_kmod_dep install_kmod_with_fw $_mod \ + --set-version $KERNEL_VER ${_moddirname} $_mpargs + ((_ret+=$?)) + ;; + esac + return $_ret + } + + function instmods_1() { + local _mod _mpargs + if (($# == 0)); then # filenames from stdin + while read _mod; do + inst1mod "${_mod%.ko*}" || { + if [ "$_check" = "yes" ]; then + dfatal "Failed to install $_mod" + return 1 + fi + } + done + fi + while (($# > 0)); do # filenames as arguments + inst1mod ${1%.ko*} || { + if [ "$_check" = "yes" ]; then + dfatal "Failed to install $1" + return 1 + fi + } + shift + done + return 0 + } + + local _ret _filter_not_found='FATAL: Module .* not found.' + set -o pipefail + # Capture all stderr from modprobe to _fderr. We could use {var}>... + # redirections, but that would make dracut require bash4 at least. + eval "( instmods_1 \"\$@\" ) ${_fderr}>&1" \ + | while read line; do [[ "$line" =~ $_filter_not_found ]] && echo $line || echo $line >&2 ;done | derror + _ret=$? + set +o pipefail + return $_ret +} + +# inst_libdir_file [-n ] [...] +# Install a located on a lib directory to the initramfs image +# -n install non-matching files +inst_libdir_file() { + if [[ "$1" == "-n" ]]; then + local _pattern=$1 + shift 2 + for _dir in $libdirs; do + for _i in "$@"; do + for _f in "$_dir"/$_i; do + [[ "$_i" =~ $_pattern ]] || continue + [[ -e "$_i" ]] && dracut_install "$_i" + done + done + done + else + for _dir in $libdirs; do + for _i in "$@"; do + for _f in "$_dir"/$_i; do + [[ -e "$_f" ]] && dracut_install "$_f" + done + done + done + fi +} + +check_qemu() { + command -v qemu-kvm &>/dev/null && [[ -c /dev/kvm ]] +} + +check_nspawn() { + [[ -d /sys/fs/cgroup/systemd ]] +} + + +do_test() { + if [[ $UID != "0" ]]; then + echo "TEST: $TEST_DESCRIPTION [SKIPPED]: not root" >&2 + exit 0 + fi + +# Detect lib paths + [[ $libdir ]] || for libdir in /lib64 /lib; do + [[ -d $libdir ]] && libdirs+=" $libdir" && break + done + + [[ $usrlibdir ]] || for usrlibdir in /usr/lib64 /usr/lib; do + [[ -d $usrlibdir ]] && libdirs+=" $usrlibdir" && break + done + + import_testdir + + while (($# > 0)); do + case $1 in + --run) + echo "TEST RUN: $TEST_DESCRIPTION" + test_run + ret=$? + if [ $ret -eq 0 ]; then + echo "TEST RUN: $TEST_DESCRIPTION [OK]" + else + echo "TEST RUN: $TEST_DESCRIPTION [FAILED]" + fi + exit $ret;; + --setup) + echo "TEST SETUP: $TEST_DESCRIPTION" + test_setup + exit $?;; + --clean) + echo "TEST CLEANUP: $TEST_DESCRIPTION" + test_cleanup + rm -fr "$TESTDIR" + rm -f .testdir + exit $?;; + --all) + echo -n "TEST: $TEST_DESCRIPTION "; + ( + test_setup && test_run + ret=$? + test_cleanup + rm -fr "$TESTDIR" + rm -f .testdir + exit $ret + ) test.log 2>&1 + ret=$? + if [ $ret -eq 0 ]; then + rm test.log + echo "[OK]" + else + echo "[FAILED]" + echo "see $(pwd)/test.log" + fi + exit $ret;; + *) break ;; + esac + shift + done +} diff --git a/test/udev-test.pl b/test/udev-test.pl new file mode 100755 index 000000000..a9f5db03c --- /dev/null +++ b/test/udev-test.pl @@ -0,0 +1,1530 @@ +#!/usr/bin/perl + +# udev test +# +# Provides automated testing of the udev binary. +# The whole test is self contained in this file, except the matching sysfs tree. +# Simply extend the @tests array, to add a new test variant. +# +# Every test is driven by its own temporary config file. +# This program prepares the environment, creates the config and calls udev. +# +# udev parses the rules, looks at the provided sysfs and +# first creates and then removes the device node. +# After creation and removal the result is checked against the +# expected value and the result is printed. +# +# Copyright (C) 2004-2012 Kay Sievers +# Copyright (C) 2004 Leann Ogasawara + +use warnings; +use strict; + +my $udev_bin = "./test-udev"; +my $valgrind = 0; +my $udev_bin_valgrind = "valgrind --tool=memcheck --leak-check=yes --quiet $udev_bin"; +my $udev_dev = "test/dev"; +my $udev_run = "test/run"; +my $udev_rules_dir = "$udev_run/udev/rules.d"; +my $udev_rules = "$udev_rules_dir/udev-test.rules"; + +my @tests = ( + { + desc => "no rules", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_name => "sda" , + exp_rem_error => "yes", + rules => < "label test of scsi disc", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_name => "boot_disk" , + rules => < "label test of scsi disc", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_name => "boot_disk" , + rules => < "label test of scsi disc", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_name => "boot_disk" , + rules => < "label test of scsi partition", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", + exp_name => "boot_disk1" , + rules => < "label test of pattern match", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", + exp_name => "boot_disk1" , + rules => < "label test of multiple sysfs files", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", + exp_name => "boot_disk1" , + rules => < "label test of max sysfs files (skip invalid rule)", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", + exp_name => "boot_disk1" , + rules => < "catch device by *", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", + exp_name => "modem/0" , + rules => < "catch device by * - take 2", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", + exp_name => "modem/0" , + rules => < "catch device by ?", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", + exp_name => "modem/0" , + rules => < "catch device by character class", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", + exp_name => "modem/0" , + rules => < "replace kernel name", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", + exp_name => "modem" , + rules => < "Handle comment lines in config file (and replace kernel name)", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", + exp_name => "modem" , + rules => < "Handle comment lines in config file with whitespace (and replace kernel name)", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", + exp_name => "modem" , + rules => < "Handle whitespace only lines (and replace kernel name)", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", + exp_name => "whitespace" , + rules => < "Handle empty lines in config file (and replace kernel name)", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", + exp_name => "modem" , + rules => < "Handle backslashed multi lines in config file (and replace kernel name)", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", + exp_name => "modem" , + rules => < "preserve backslashes, if they are not for a newline", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", + exp_name => "aaa", + rules => < "Handle stupid backslashed multi lines in config file (and replace kernel name)", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", + exp_name => "modem" , + rules => < "subdirectory handling", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", + exp_name => "sub/direct/ory/modem" , + rules => < "parent device name match of scsi partition", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", + exp_name => "first_disk5" , + rules => < "test substitution chars", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", + exp_name => "Major:8:minor:5:kernelnumber:5:id:0:0:0:0" , + rules => < "import of shell-value returned from program", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_name => "node12345678", + rules => < "sustitution of sysfs value (%s{file})", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_name => "disk-ATA-sda" , + rules => < "program result substitution", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", + exp_name => "special-device-5" , + not_exp_name => "not" , + rules => < "program result substitution (newline removal)", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", + exp_name => "newline_removed" , + rules => < "program result substitution", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", + exp_name => "test-0:0:0:0" , + rules => < "program with lots of arguments", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", + exp_name => "foo9" , + rules => < "program with subshell", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", + exp_name => "bar9" , + rules => < "program arguments combined with apostrophes", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", + exp_name => "foo7" , + rules => < "characters before the %c{N} substitution", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", + exp_name => "my-foo9" , + rules => < "substitute the second to last argument", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", + exp_name => "my-foo8" , + rules => < "test substitution by variable name", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", + exp_name => "Major:8-minor:5-kernelnumber:5-id:0:0:0:0", + rules => < "test substitution by variable name 2", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", + exp_name => "Major:8-minor:5-kernelnumber:5-id:0:0:0:0", + rules => < "test substitution by variable name 3", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", + exp_name => "850:0:0:05" , + rules => < "test substitution by variable name 4", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", + exp_name => "855" , + rules => < "test substitution by variable name 5", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", + exp_name => "8550:0:0:0" , + rules => < "non matching SUBSYSTEMS for device with no parent", + devpath => "/devices/virtual/tty/console", + exp_name => "TTY", + rules => < "non matching SUBSYSTEMS", + devpath => "/devices/virtual/tty/console", + exp_name => "TTY" , + rules => < "ATTRS match", + devpath => "/devices/virtual/tty/console", + exp_name => "foo" , + rules => < "ATTR (empty file)", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_name => "empty" , + rules => < "ATTR (non-existent file)", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_name => "non-existent" , + rules => < "program and bus type match", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_name => "scsi-0:0:0:0" , + rules => < "sysfs parent hierarchy", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", + exp_name => "modem" , + rules => < "name test with ! in the name", + devpath => "/devices/virtual/block/fake!blockdev0", + exp_name => "is/a/fake/blockdev0" , + rules => < "name test with ! in the name, but no matching rule", + devpath => "/devices/virtual/block/fake!blockdev0", + exp_name => "fake/blockdev0" , + exp_rem_error => "yes", + rules => < "KERNELS rule", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_name => "scsi-0:0:0:0", + rules => < "KERNELS wildcard all", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_name => "scsi-0:0:0:0", + rules => < "KERNELS wildcard partial", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_name => "scsi-0:0:0:0", + rules => < "KERNELS wildcard partial 2", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_name => "scsi-0:0:0:0", + rules => < "substitute attr with link target value (first match)", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_name => "driver-is-sd", + rules => < "substitute attr with link target value (currently selected device)", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_name => "driver-is-ahci", + rules => < "ignore ATTRS attribute whitespace", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_name => "ignored", + rules => < "do not ignore ATTRS attribute whitespace", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_name => "matched-with-space", + rules => < "permissions USER=bad GROUP=name", + devpath => "/devices/virtual/tty/tty33", + exp_name => "tty33", + exp_perms => "0:0:0600", + rules => < "permissions OWNER=5000", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_name => "node", + exp_perms => "5000::0600", + rules => < "permissions GROUP=100", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_name => "node", + exp_perms => ":100:0660", + rules => < "textual user id", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_name => "node", + exp_perms => "nobody::0600", + rules => < "textual group id", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_name => "node", + exp_perms => ":daemon:0660", + rules => < "textual user/group id", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_name => "node", + exp_perms => "root:mail:0660", + rules => < "permissions MODE=0777", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_name => "node", + exp_perms => "::0777", + rules => < "permissions OWNER=5000 GROUP=100 MODE=0777", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_name => "node", + exp_perms => "5000:100:0777", + rules => < "permissions OWNER to 5000", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", + exp_name => "ttyACM0", + exp_perms => "5000::", + rules => < "permissions GROUP to 100", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", + exp_name => "ttyACM0", + exp_perms => ":100:0660", + rules => < "permissions MODE to 0060", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", + exp_name => "ttyACM0", + exp_perms => "::0060", + rules => < "permissions OWNER, GROUP, MODE", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", + exp_name => "ttyACM0", + exp_perms => "5000:100:0777", + rules => < "permissions only rule", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", + exp_name => "ttyACM0", + exp_perms => "5000:100:0777", + rules => < "multiple permissions only rule", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", + exp_name => "ttyACM0", + exp_perms => "3000:4000:0777", + rules => < "permissions only rule with override at SYMLINK+ rule", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", + exp_name => "ttyACM0", + exp_perms => "3000:8000:0777", + rules => < "major/minor number test", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_name => "node", + exp_majorminor => "8:0", + rules => < "big major number test", + devpath => "/devices/virtual/misc/misc-fake1", + exp_name => "node", + exp_majorminor => "4095:1", + rules => < "big major and big minor number test", + devpath => "/devices/virtual/misc/misc-fake89999", + exp_name => "node", + exp_majorminor => "4095:89999", + rules => < "multiple symlinks with format char", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", + exp_name => "symlink2-ttyACM0", + rules => < "multiple symlinks with a lot of s p a c e s", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", + exp_name => "one", + not_exp_name => " ", + rules => < "symlink creation (same directory)", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", + exp_name => "modem0", + rules => < "multiple symlinks", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", + exp_name => "second-0" , + rules => < "symlink name '.'", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_name => ".", + exp_add_error => "yes", + exp_rem_error => "yes", + rules => < "symlink node to itself", + devpath => "/devices/virtual/tty/tty0", + exp_name => "link", + exp_add_error => "yes", + exp_rem_error => "yes", + option => "clean", + rules => < "symlink %n substitution", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", + exp_name => "symlink0", + rules => < "symlink %k substitution", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", + exp_name => "symlink-ttyACM0", + rules => < "symlink %M:%m substitution", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", + exp_name => "major-166:0", + rules => < "symlink %b substitution", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_name => "symlink-0:0:0:0", + rules => < "symlink %c substitution", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", + exp_name => "test", + rules => < "symlink %c{N} substitution", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", + exp_name => "test", + rules => < "symlink %c{N+} substitution", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", + exp_name => "this", + rules => < "symlink only rule with %c{N+}", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_name => "test", + rules => < "symlink %s{filename} substitution", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", + exp_name => "166:0", + rules => < "program result substitution (numbered part of)", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", + exp_name => "link1", + rules => < "program result substitution (numbered part of+)", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", + exp_name => "link4", + rules => < "SUBSYSTEM match test", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_name => "node", + rules => < "DRIVERS match test", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_name => "node", + rules => < "devnode substitution test", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_name => "node", + rules => < "parent node name substitution test", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", + exp_name => "sda-part-1", + rules => < "udev_root substitution", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", + exp_name => "start-/dev-end", + rules => < "last_rule option", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", + exp_name => "last", + rules => < "negation KERNEL!=", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", + exp_name => "match", + rules => < "negation SUBSYSTEM!=", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", + exp_name => "not-anything", + rules => < "negation PROGRAM!= exit code", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", + exp_name => "nonzero-program", + rules => < "ENV{} test", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", + exp_name => "true", + rules => < "ENV{} test", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", + exp_name => "true", + rules => < "ENV{} test (assign)", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", + exp_name => "true", + rules => < "ENV{} test (assign 2 times)", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", + exp_name => "true", + rules => < "ENV{} test (assign2)", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", + exp_name => "part", + rules => < "untrusted string sanitize", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", + exp_name => "sane", + rules => < "untrusted string sanitize (don't replace utf8)", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", + exp_name => "uber", + rules => < "untrusted string sanitize (replace invalid utf8)", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", + exp_name => "replaced", + rules => < "read sysfs value from parent device", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", + exp_name => "serial-354172020305000", + rules => < "match against empty key string", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_name => "ok", + rules => < "check ACTION value", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_name => "ok", + rules => < "final assignment", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_name => "ok", + exp_perms => "root:tty:0640", + rules => < "final assignment 2", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_name => "ok", + exp_perms => "root:tty:0640", + rules => < "env substitution", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_name => "node-add-me", + rules => < "reset list to current value", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", + exp_name => "three", + not_exp_name => "two", + rules => < "test empty SYMLINK+ (empty override)", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", + exp_name => "right", + not_exp_name => "wrong", + rules => < "test multi matches", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", + exp_name => "right", + rules => < "test multi matches 2", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", + exp_name => "right", + rules => < "test multi matches 3", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", + exp_name => "right", + rules => < "test multi matches 4", + devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0", + exp_name => "right", + rules => < "IMPORT parent test sequence 1/2 (keep)", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_name => "parent", + option => "keep", + rules => < "IMPORT parent test sequence 2/2 (keep)", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", + exp_name => "parentenv-parent_right", + option => "clean", + rules => < "GOTO test", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", + exp_name => "right", + rules => < "GOTO label does not exist", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", + exp_name => "right", + rules => < "SYMLINK+ compare test", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", + exp_name => "right", + not_exp_name => "wrong", + rules => < "invalid key operation", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", + exp_name => "yes", + rules => < "operator chars in attribute", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_name => "yes", + rules => < "overlong comment line", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1", + exp_name => "yes", + rules => < "magic subsys/kernel lookup", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_name => "00:16:41:e2:8d:ff", + rules => < "TEST absolute path", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_name => "there", + rules => < "TEST subsys/kernel lookup", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_name => "yes", + rules => < "TEST relative path", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_name => "relative", + rules => < "TEST wildcard substitution (find queue/nr_requests)", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_name => "found-subdir", + rules => < "TEST MODE=0000", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_name => "sda", + exp_perms => "0:0:0000", + exp_rem_error => "yes", + rules => < "TEST PROGRAM feeds OWNER, GROUP, MODE", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_name => "sda", + exp_perms => "5000:100:0400", + exp_rem_error => "yes", + rules => < "TEST PROGRAM feeds MODE with overflow", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_name => "sda", + exp_perms => "0:0:0440", + exp_rem_error => "yes", + rules => < "magic [subsys/sysname] attribute substitution", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_name => "sda-8741C4G-end", + exp_perms => "0:0:0600", + rules => < "builtin path_id", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_name => "disk/by-path/pci-0000:00:1f.2-scsi-0:0:0:0", + rules => <$udev_rules" || die "unable to create rules file: $udev_rules"; + print CONF $$rules; + close CONF; + + if ($valgrind > 0) { + system("$udev_bin_valgrind $action $devpath"); + } else { + system("$udev_bin", "$action", "$devpath"); + } +} + +my $error = 0; + +sub permissions_test { + my($rules, $uid, $gid, $mode) = @_; + + my $wrong = 0; + my $userid; + my $groupid; + + $rules->{exp_perms} =~ m/^(.*):(.*):(.*)$/; + if ($1 ne "") { + if (defined(getpwnam($1))) { + $userid = int(getpwnam($1)); + } else { + $userid = $1; + } + if ($uid != $userid) { $wrong = 1; } + } + if ($2 ne "") { + if (defined(getgrnam($2))) { + $groupid = int(getgrnam($2)); + } else { + $groupid = $2; + } + if ($gid != $groupid) { $wrong = 1; } + } + if ($3 ne "") { + if (($mode & 07777) != oct($3)) { $wrong = 1; }; + } + if ($wrong == 0) { + print "permissions: ok\n"; + } else { + printf " expected permissions are: %s:%s:%#o\n", $1, $2, oct($3); + printf " created permissions are : %i:%i:%#o\n", $uid, $gid, $mode & 07777; + print "permissions: error\n"; + $error++; + sleep(1); + } +} + +sub major_minor_test { + my($rules, $rdev) = @_; + + my $major = ($rdev >> 8) & 0xfff; + my $minor = ($rdev & 0xff) | (($rdev >> 12) & 0xfff00); + my $wrong = 0; + + $rules->{exp_majorminor} =~ m/^(.*):(.*)$/; + if ($1 ne "") { + if ($major != $1) { $wrong = 1; }; + } + if ($2 ne "") { + if ($minor != $2) { $wrong = 1; }; + } + if ($wrong == 0) { + print "major:minor: ok\n"; + } else { + printf " expected major:minor is: %i:%i\n", $1, $2; + printf " created major:minor is : %i:%i\n", $major, $minor; + print "major:minor: error\n"; + $error++; + sleep(1); + } +} + +sub udev_setup { + system("rm", "-rf", "$udev_dev"); + mkdir($udev_dev) || die "unable to create udev_dev: $udev_dev\n"; + # setting group and mode of udev_dev ensures the tests work + # even if the parent directory has setgid bit enabled. + chown (0, 0, $udev_dev) || die "unable to chown $udev_dev\n"; + chmod (0755, $udev_dev) || die "unable to chmod $udev_dev\n"; + + system("rm", "-rf", "$udev_run"); +} + +sub run_test { + my ($rules, $number) = @_; + + print "TEST $number: $rules->{desc}\n"; + print "device \'$rules->{devpath}\' expecting node/link \'$rules->{exp_name}\'\n"; + + udev("add", $rules->{devpath}, \$rules->{rules}); + if (defined($rules->{not_exp_name})) { + if ((-e "$udev_dev/$rules->{not_exp_name}") || + (-l "$udev_dev/$rules->{not_exp_name}")) { + print "nonexistent: error \'$rules->{not_exp_name}\' not expected to be there\n"; + $error++; + sleep(1); + } + } + + if ((-e "$udev_dev/$rules->{exp_name}") || + (-l "$udev_dev/$rules->{exp_name}")) { + + my ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, + $atime, $mtime, $ctime, $blksize, $blocks) = stat("$udev_dev/$rules->{exp_name}"); + + if (defined($rules->{exp_perms})) { + permissions_test($rules, $uid, $gid, $mode); + } + if (defined($rules->{exp_majorminor})) { + major_minor_test($rules, $rdev); + } + print "add: ok\n"; + } else { + print "add: error"; + if ($rules->{exp_add_error}) { + print " as expected\n"; + } else { + print "\n"; + system("tree", "$udev_dev"); + print "\n"; + $error++; + sleep(1); + } + } + + if (defined($rules->{option}) && $rules->{option} eq "keep") { + print "\n\n"; + return; + } + + udev("remove", $rules->{devpath}, \$rules->{rules}); + if ((-e "$udev_dev/$rules->{exp_name}") || + (-l "$udev_dev/$rules->{exp_name}")) { + print "remove: error"; + if ($rules->{exp_rem_error}) { + print " as expected\n"; + } else { + print "\n"; + system("tree", "$udev_dev"); + print "\n"; + $error++; + sleep(1); + } + } else { + print "remove: ok\n"; + } + + print "\n"; + + if (defined($rules->{option}) && $rules->{option} eq "clean") { + udev_setup(); + } + +} + +# only run if we have root permissions +# due to mknod restrictions +if (!($<==0)) { + print "Must have root permissions to run properly.\n"; + exit; +} + +udev_setup(); + +my $test_num = 1; +my @list; + +foreach my $arg (@ARGV) { + if ($arg =~ m/--valgrind/) { + $valgrind = 1; + printf("using valgrind\n"); + } else { + push(@list, $arg); + } +} + +if ($list[0]) { + foreach my $arg (@list) { + if (defined($tests[$arg-1]->{desc})) { + print "udev-test will run test number $arg:\n\n"; + run_test($tests[$arg-1], $arg); + } else { + print "test does not exist.\n"; + } + } +} else { + # test all + print "\nudev-test will run ".($#tests + 1)." tests:\n\n"; + + foreach my $rules (@tests) { + run_test($rules, $test_num); + $test_num++; + } +} + +print "$error errors occured\n\n"; + +# cleanup +system("rm", "-rf", "$udev_dev"); +system("rm", "-rf", "$udev_run"); + +if ($error > 0) { + exit(1); +} +exit(0); diff --git a/tmpfiles.d/Makefile b/tmpfiles.d/Makefile new file mode 120000 index 000000000..bd1047548 --- /dev/null +++ b/tmpfiles.d/Makefile @@ -0,0 +1 @@ +../src/Makefile \ No newline at end of file diff --git a/tmpfiles.d/legacy.conf b/tmpfiles.d/legacy.conf new file mode 100644 index 000000000..92bd71b98 --- /dev/null +++ b/tmpfiles.d/legacy.conf @@ -0,0 +1,22 @@ +# This file is part of systemd. +# +# 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. + +# See tmpfiles.d(5) for details + +# These files are considered legacy and are unnecessary on legacy-free +# systems. /run/lock/subsys is used for serializing SysV service +# execution, and hence without use on SysV-less systems. +# +# /run/lock/lockdev is used to serialize access to tty devices via +# LCK..xxx style lock files, For more information see: +# http://lists.freedesktop.org/archives/systemd-devel/2011-March/001823.html +# On modern systems a BSD file lock is a better choice if +# serialization is needed on those devices. + +d /run/lock 0755 root root - +d /run/lock/subsys 0755 root root - +d /run/lock/lockdev 0775 root lock - diff --git a/tmpfiles.d/systemd.conf b/tmpfiles.d/systemd.conf new file mode 100644 index 000000000..965c6fc32 --- /dev/null +++ b/tmpfiles.d/systemd.conf @@ -0,0 +1,28 @@ +# This file is part of systemd. +# +# 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. + +# See tmpfiles.d(5) for details + +d /run/user 0755 root root ~10d +F /run/utmp 0664 root utmp - + +f /var/log/wtmp 0664 root utmp - +f /var/log/btmp 0600 root utmp - + +d /var/cache/man - - - 30d + +r /forcefsck +r /forcequotacheck +r /fastboot + +d /run/systemd/ask-password 0755 root root - +d /run/systemd/seats 0755 root root - +d /run/systemd/sessions 0755 root root - +d /run/systemd/users 0755 root root - +d /run/systemd/shutdown 0755 root root - + +F /run/nologin 0755 - - - "System is booting up." diff --git a/tmpfiles.d/tmp.conf b/tmpfiles.d/tmp.conf new file mode 100644 index 000000000..1284fc470 --- /dev/null +++ b/tmpfiles.d/tmp.conf @@ -0,0 +1,12 @@ +# This file is part of systemd. +# +# 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. + +# See tmpfiles.d(5) for details + +# Clear tmp directories separately, to make them easier to override +d /tmp 1777 root root 10d +d /var/tmp 1777 root root 30d diff --git a/tmpfiles.d/x11.conf b/tmpfiles.d/x11.conf new file mode 100644 index 000000000..ece6a5ce9 --- /dev/null +++ b/tmpfiles.d/x11.conf @@ -0,0 +1,18 @@ +# This file is part of systemd. +# +# 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. + +# See tmpfiles.d(5) for details + +# Make sure these are created by default so that nobody else can +d /tmp/.X11-unix 1777 root root 10d +d /tmp/.ICE-unix 1777 root root 10d +d /tmp/.XIM-unix 1777 root root 10d +d /tmp/.font-unix 1777 root root 10d +d /tmp/.Test-unix 1777 root root 10d + +# Unlink the X11 lock files +r /tmp/.X[0-9]*-lock diff --git a/units/.gitignore b/units/.gitignore new file mode 100644 index 000000000..5e86d3011 --- /dev/null +++ b/units/.gitignore @@ -0,0 +1,51 @@ +/halt-local.service +/rc-local.service +/systemd-hybrid-sleep.service +/systemd-journal-gatewayd.service +/systemd-journal-flush.service +/systemd-hibernate.service +/systemd-suspend.service +/console-getty.service +/systemd-journald.service +/user@.service +/systemd-logind.service +/systemd-localed.service +/systemd-timedated.service +/systemd-hostnamed.service +/console-shell.service +/systemd-sysctl.service +/systemd-ask-password-console.service +/rescue.service +/systemd-ask-password-wall.service +/systemd-quotacheck.service +/quotaon.service +/systemd-fsck@.service +/systemd-fsck-root.service +/systemd-tmpfiles-clean.service +/systemd-tmpfiles-setup.service +/systemd-halt.service +/systemd-poweroff.service +/systemd-reboot.service +/systemd-kexec.service +/systemd-user-sessions.service +/systemd-readahead-done.service +/systemd-tmpfiles.service +/systemd-readahead-collect.service +/systemd-readahead-replay.service +/serial-getty@.service +/systemd-modules-load.service +/systemd-remount-fs.service +/systemd-vconsole-setup.service +/systemd-shutdownd.service +/systemd-random-seed-load.service +/systemd-random-seed-save.service +/systemd-initctl.service +/getty@.service +/systemd-update-utmp-runlevel.service +/systemd-update-utmp-shutdown.service +/systemd-binfmt.service +/emergency.service +/systemd-udev-settle.service +/systemd-udev-trigger.service +/systemd-udevd.service +/debug-shell.service diff --git a/units/Makefile b/units/Makefile new file mode 120000 index 000000000..bd1047548 --- /dev/null +++ b/units/Makefile @@ -0,0 +1 @@ +../src/Makefile \ No newline at end of file diff --git a/units/basic.target b/units/basic.target new file mode 100644 index 000000000..f9d03fa16 --- /dev/null +++ b/units/basic.target @@ -0,0 +1,13 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Basic System +Documentation=man:systemd.special(7) +Requires=sysinit.target sockets.target +After=sysinit.target sockets.target +RefuseManualStart=yes diff --git a/units/bluetooth.target b/units/bluetooth.target new file mode 100644 index 000000000..dd4ae14cf --- /dev/null +++ b/units/bluetooth.target @@ -0,0 +1,11 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Bluetooth +Documentation=man:systemd.special(7) +StopWhenUnneeded=yes diff --git a/units/console-getty.service.m4.in b/units/console-getty.service.m4.in new file mode 100644 index 000000000..0426050ee --- /dev/null +++ b/units/console-getty.service.m4.in @@ -0,0 +1,34 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Console Getty +Documentation=man:agetty(8) +After=systemd-user-sessions.service plymouth-quit-wait.service +m4_ifdef(`HAVE_SYSV_COMPAT', +After=rc-local.service +)m4_dnl +Before=getty.target + +[Service] +ExecStart=-/sbin/agetty --noclear -s console 115200,38400,9600 +Type=idle +Restart=always +RestartSec=0 +UtmpIdentifier=cons +TTYPath=/dev/console +TTYReset=yes +TTYVHangup=yes +KillMode=process +IgnoreSIGPIPE=no + +# Bash ignores SIGTERM, so we send SIGHUP instead, to ensure that bash +# terminates cleanly. +KillSignal=SIGHUP + +[Install] +WantedBy=getty.target diff --git a/units/console-shell.service.m4.in b/units/console-shell.service.m4.in new file mode 100644 index 000000000..dac2ac212 --- /dev/null +++ b/units/console-shell.service.m4.in @@ -0,0 +1,34 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Console Shell +Documentation=man:sulogin(8) +After=systemd-user-sessions.service plymouth-quit-wait.service +m4_ifdef(`HAVE_SYSV_COMPAT', +After=rc-local.service +)m4_dnl +Before=getty.target + +[Service] +Environment=HOME=/root +WorkingDirectory=/root +ExecStart=-/sbin/sulogin +ExecStopPost=-@SYSTEMCTL@ poweroff +Type=idle +StandardInput=tty-force +StandardOutput=inherit +StandardError=inherit +KillMode=process +IgnoreSIGPIPE=no + +# Bash ignores SIGTERM, so we send SIGHUP instead, to ensure that bash +# terminates cleanly. +KillSignal=SIGHUP + +[Install] +WantedBy=getty.target diff --git a/units/cryptsetup.target b/units/cryptsetup.target new file mode 100644 index 000000000..25d3e33f6 --- /dev/null +++ b/units/cryptsetup.target @@ -0,0 +1,10 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Encrypted Volumes +Documentation=man:systemd.special(7) diff --git a/units/debug-shell.service.in b/units/debug-shell.service.in new file mode 100644 index 000000000..2aa98d3cc --- /dev/null +++ b/units/debug-shell.service.in @@ -0,0 +1,33 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Early root shell on tty9 FOR DEBUGGING ONLY +Documentation=man:sushell(8) +DefaultDependencies=no +IgnoreOnIsolate=yes + +[Service] +Environment=TERM=linux +ExecStart=@sushell@ +Restart=always +RestartSec=0 +StandardInput=tty +TTYPath=/dev/tty9 +TTYReset=yes +TTYVHangup=yes +KillMode=process +IgnoreSIGPIPE=no +# bash ignores SIGTERM +KillSignal=SIGHUP + +# Unset locale for the console getty since the console has problems +# displaying some internationalized messages. +Environment=LANG= LANGUAGE= LC_CTYPE= LC_NUMERIC= LC_TIME= LC_COLLATE= LC_MONETARY= LC_MESSAGES= LC_PAPER= LC_NAME= LC_ADDRESS= LC_TELEPHONE= LC_MEASUREMENT= LC_IDENTIFICATION= + +[Install] +WantedBy=sysinit.target diff --git a/units/dev-hugepages.mount b/units/dev-hugepages.mount new file mode 100644 index 000000000..9381167c8 --- /dev/null +++ b/units/dev-hugepages.mount @@ -0,0 +1,18 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Huge Pages File System +Documentation=https://www.kernel.org/doc/Documentation/vm/hugetlbpage.txt +DefaultDependencies=no +Before=sysinit.target +ConditionPathExists=/sys/kernel/mm/hugepages + +[Mount] +What=hugetlbfs +Where=/dev/hugepages +Type=hugetlbfs diff --git a/units/dev-mqueue.mount b/units/dev-mqueue.mount new file mode 100644 index 000000000..5786bb151 --- /dev/null +++ b/units/dev-mqueue.mount @@ -0,0 +1,18 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=POSIX Message Queue File System +Documentation=man:mq_overview(7) +DefaultDependencies=no +Before=sysinit.target +ConditionPathExists=/proc/sys/fs/mqueue + +[Mount] +What=mqueue +Where=/dev/mqueue +Type=mqueue diff --git a/units/emergency.service.in b/units/emergency.service.in new file mode 100644 index 000000000..442f0e0ee --- /dev/null +++ b/units/emergency.service.in @@ -0,0 +1,31 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Emergency Shell +Documentation=man:sulogin(8) +DefaultDependencies=no +Conflicts=shutdown.target +Before=shutdown.target + +[Service] +Environment=HOME=/root +WorkingDirectory=/root +ExecStartPre=-/bin/plymouth quit +ExecStartPre=-/bin/echo -e 'Welcome to emergency mode! After logging in, type "journalctl -xb" to view\\nsystem logs, "systemctl reboot" to reboot, "systemctl default" to try again\\nto boot into default mode.' +ExecStart=-/sbin/sulogin +ExecStopPost=@SYSTEMCTL@ --fail --no-block default +Type=idle +StandardInput=tty-force +StandardOutput=inherit +StandardError=inherit +KillMode=process +IgnoreSIGPIPE=no + +# Bash ignores SIGTERM, so we send SIGHUP instead, to ensure that bash +# terminates cleanly. +KillSignal=SIGHUP diff --git a/units/emergency.target b/units/emergency.target new file mode 100644 index 000000000..0760d66f9 --- /dev/null +++ b/units/emergency.target @@ -0,0 +1,13 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Emergency Mode +Documentation=man:systemd.special(7) +Requires=emergency.service +After=emergency.service +AllowIsolate=yes diff --git a/units/final.target b/units/final.target new file mode 100644 index 000000000..42819105c --- /dev/null +++ b/units/final.target @@ -0,0 +1,13 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Final Step +Documentation=man:systemd.special(7) +DefaultDependencies=no +RefuseManualStart=yes +After=shutdown.target umount.target diff --git a/units/getty.target b/units/getty.target new file mode 100644 index 000000000..c33d44657 --- /dev/null +++ b/units/getty.target @@ -0,0 +1,11 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Login Prompts +Documentation=man:systemd.special(7) man:systemd-getty-generator(8) +Documentation=http://0pointer.de/blog/projects/serial-console.html diff --git a/units/getty@.service.m4 b/units/getty@.service.m4 new file mode 100644 index 000000000..083eb9705 --- /dev/null +++ b/units/getty@.service.m4 @@ -0,0 +1,51 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Getty on %I +Documentation=man:agetty(8) man:systemd-getty-generator(8) +Documentation=http://0pointer.de/blog/projects/serial-console.html +After=systemd-user-sessions.service plymouth-quit-wait.service +m4_ifdef(`HAVE_SYSV_COMPAT', +After=rc-local.service +)m4_dnl + +# If additional gettys are spawned during boot then we should make +# sure that this is synchronized before getty.target, even though +# getty.target didn't actually pull it in. +Before=getty.target +IgnoreOnIsolate=yes + +# On systems without virtual consoles, don't start any getty. (Note +# that serial gettys are covered by serial-getty@.service, not this +# unit +ConditionPathExists=/dev/tty0 + +[Service] +# the VT is cleared by TTYVTDisallocate +ExecStart=-/sbin/agetty --noclear %I 38400 linux +Type=idle +Restart=always +RestartSec=0 +UtmpIdentifier=%I +TTYPath=/dev/%I +TTYReset=yes +TTYVHangup=yes +TTYVTDisallocate=yes +KillMode=process +IgnoreSIGPIPE=no + +# Unset locale for the console getty since the console has problems +# displaying some internationalized messages. +Environment=LANG= LANGUAGE= LC_CTYPE= LC_NUMERIC= LC_TIME= LC_COLLATE= LC_MONETARY= LC_MESSAGES= LC_PAPER= LC_NAME= LC_ADDRESS= LC_TELEPHONE= LC_MEASUREMENT= LC_IDENTIFICATION= + +# Some login implementations ignore SIGTERM, so we send SIGHUP +# instead, to ensure that login terminates cleanly. +KillSignal=SIGHUP + +[Install] +Alias=getty.target.wants/getty@tty1.service diff --git a/units/graphical.target b/units/graphical.target new file mode 100644 index 000000000..65f2521d9 --- /dev/null +++ b/units/graphical.target @@ -0,0 +1,18 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Graphical Interface +Documentation=man:systemd.special(7) +Requires=multi-user.target +After=multi-user.target +Conflicts=rescue.target +Wants=display-manager.service +AllowIsolate=yes + +[Install] +Alias=default.target diff --git a/units/halt-local.service.in b/units/halt-local.service.in new file mode 100644 index 000000000..c8be8965a --- /dev/null +++ b/units/halt-local.service.in @@ -0,0 +1,20 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=@RC_LOCAL_SCRIPT_PATH_STOP@ Compatibility +ConditionFileIsExecutable=@RC_LOCAL_SCRIPT_PATH_STOP@ +DefaultDependencies=no +After=shutdown.target +Before=final.target + +[Service] +Type=oneshot +ExecStart=@RC_LOCAL_SCRIPT_PATH_STOP@ +TimeoutSec=0 +StandardOutput=tty +RemainAfterExit=yes diff --git a/units/halt.target b/units/halt.target new file mode 100644 index 000000000..a21d984b2 --- /dev/null +++ b/units/halt.target @@ -0,0 +1,17 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Halt +Documentation=man:systemd.special(7) +DefaultDependencies=no +Requires=systemd-halt.service +After=systemd-halt.service +AllowIsolate=yes + +[Install] +Alias=ctrl-alt-del.target diff --git a/units/hibernate.target b/units/hibernate.target new file mode 100644 index 000000000..143eb5923 --- /dev/null +++ b/units/hibernate.target @@ -0,0 +1,13 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Hibernate +Documentation=man:systemd.special(7) +DefaultDependencies=no +BindsTo=systemd-hibernate.service +After=systemd-hibernate.service diff --git a/units/hybrid-sleep.target b/units/hybrid-sleep.target new file mode 100644 index 000000000..d2d340922 --- /dev/null +++ b/units/hybrid-sleep.target @@ -0,0 +1,13 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Hybrid Suspend+Hibernate +Documentation=man:systemd.special(7) +DefaultDependencies=no +BindsTo=systemd-hybrid-sleep.service +After=systemd-hybrid-sleep.service diff --git a/units/kexec.target b/units/kexec.target new file mode 100644 index 000000000..90795d0c5 --- /dev/null +++ b/units/kexec.target @@ -0,0 +1,17 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Reboot via kexec +Documentation=man:systemd.special(7) +DefaultDependencies=no +Requires=systemd-kexec.service +After=systemd-kexec.service +AllowIsolate=yes + +[Install] +Alias=ctrl-alt-del.target diff --git a/units/local-fs-pre.target b/units/local-fs-pre.target new file mode 100644 index 000000000..f8760ec9d --- /dev/null +++ b/units/local-fs-pre.target @@ -0,0 +1,10 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Local File Systems (Pre) +Documentation=man:systemd.special(7) diff --git a/units/local-fs.target b/units/local-fs.target new file mode 100644 index 000000000..dd92b17b6 --- /dev/null +++ b/units/local-fs.target @@ -0,0 +1,12 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Local File Systems +Documentation=man:systemd.special(7) +OnFailure=emergency.target +OnFailureIsolate=yes diff --git a/units/mail-transfer-agent.target b/units/mail-transfer-agent.target new file mode 100644 index 000000000..d2f24d15b --- /dev/null +++ b/units/mail-transfer-agent.target @@ -0,0 +1,13 @@ +# This file is part of systemd. +# +# 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. + +# This exists mostly for compatibility with SysV/LSB units, and +# implementations lacking socket/bus activation. + +[Unit] +Description=Mail Transfer Agent +Documentation=man:systemd.special(7) diff --git a/units/multi-user.target b/units/multi-user.target new file mode 100644 index 000000000..6e3f0b4f7 --- /dev/null +++ b/units/multi-user.target @@ -0,0 +1,17 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Multi-User +Documentation=man:systemd.special(7) +Requires=basic.target +Conflicts=rescue.service rescue.target +After=basic.target rescue.service rescue.target +AllowIsolate=yes + +[Install] +Alias=default.target diff --git a/units/network.target b/units/network.target new file mode 100644 index 000000000..5406f4e5d --- /dev/null +++ b/units/network.target @@ -0,0 +1,10 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Network +Documentation=man:systemd.special(7) diff --git a/units/nss-lookup.target b/units/nss-lookup.target new file mode 100644 index 000000000..eea905a71 --- /dev/null +++ b/units/nss-lookup.target @@ -0,0 +1,14 @@ +# This file is part of systemd. +# +# 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. + +# This exists mostly for compatibility with SysV/LSB units, and +# implementations lacking socket/bus activation. + +[Unit] +Description=Host and Network Name Lookups +Documentation=man:systemd.special(7) +After=network.target diff --git a/units/nss-user-lookup.target b/units/nss-user-lookup.target new file mode 100644 index 000000000..3e0fced10 --- /dev/null +++ b/units/nss-user-lookup.target @@ -0,0 +1,14 @@ +# This file is part of systemd. +# +# 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. + +# This exists mostly for implementations lacking socket/bus +# activation. + +[Unit] +Description=User and Group Name Lookups +Documentation=man:systemd.special(7) +After=network.target diff --git a/units/poweroff.target b/units/poweroff.target new file mode 100644 index 000000000..71871033a --- /dev/null +++ b/units/poweroff.target @@ -0,0 +1,17 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Power-Off +Documentation=man:systemd.special(7) +DefaultDependencies=no +Requires=systemd-poweroff.service +After=systemd-poweroff.service +AllowIsolate=yes + +[Install] +Alias=ctrl-alt-del.target diff --git a/units/printer.target b/units/printer.target new file mode 100644 index 000000000..a6b86caa8 --- /dev/null +++ b/units/printer.target @@ -0,0 +1,11 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Printer +Documentation=man:systemd.special(7) +StopWhenUnneeded=yes diff --git a/units/proc-sys-fs-binfmt_misc.automount b/units/proc-sys-fs-binfmt_misc.automount new file mode 100644 index 000000000..7fd5afe3c --- /dev/null +++ b/units/proc-sys-fs-binfmt_misc.automount @@ -0,0 +1,17 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Arbitrary Executable File Formats File System Automount Point +Documentation=https://www.kernel.org/doc/Documentation/binfmt_misc.txt +DefaultDependencies=no +Before=sysinit.target +ConditionPathExists=/proc/sys/fs/binfmt_misc/ +ConditionPathIsReadWrite=/proc/sys/ + +[Automount] +Where=/proc/sys/fs/binfmt_misc diff --git a/units/proc-sys-fs-binfmt_misc.mount b/units/proc-sys-fs-binfmt_misc.mount new file mode 100644 index 000000000..c64c84951 --- /dev/null +++ b/units/proc-sys-fs-binfmt_misc.mount @@ -0,0 +1,16 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Arbitrary Executable File Formats File System +Documentation=https://www.kernel.org/doc/Documentation/binfmt_misc.txt +DefaultDependencies=no + +[Mount] +What=binfmt_misc +Where=/proc/sys/fs/binfmt_misc +Type=binfmt_misc diff --git a/units/quotaon.service.in b/units/quotaon.service.in new file mode 100644 index 000000000..49a50a7fe --- /dev/null +++ b/units/quotaon.service.in @@ -0,0 +1,19 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Enable File System Quotas +Documentation=man:quotaon(8) +DefaultDependencies=no +After=systemd-readahead-collect.service systemd-readahead-replay.service systemd-quotacheck.service +Before=local-fs.target shutdown.target +ConditionPathExists=@QUOTAON@ + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=@QUOTAON@ -aug diff --git a/units/rc-local.service.in b/units/rc-local.service.in new file mode 100644 index 000000000..97d44a7a2 --- /dev/null +++ b/units/rc-local.service.in @@ -0,0 +1,20 @@ +# This file is part of systemd. +# +# 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. + +# This unit gets pulled automatically into multi-user.target by +# systemd-rc-local-generator if @RC_LOCAL_SCRIPT_PATH_START@ is executable. +[Unit] +Description=@RC_LOCAL_SCRIPT_PATH_START@ Compatibility +ConditionFileIsExecutable=@RC_LOCAL_SCRIPT_PATH_START@ +After=network.target + +[Service] +Type=forking +ExecStart=@RC_LOCAL_SCRIPT_PATH_START@ start +TimeoutSec=0 +RemainAfterExit=yes +SysVStartPriority=99 diff --git a/units/reboot.target b/units/reboot.target new file mode 100644 index 000000000..dec8f5679 --- /dev/null +++ b/units/reboot.target @@ -0,0 +1,17 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Reboot +Documentation=man:systemd.special(7) +DefaultDependencies=no +Requires=systemd-reboot.service +After=systemd-reboot.service +AllowIsolate=yes + +[Install] +Alias=ctrl-alt-del.target diff --git a/units/remote-fs-pre.target b/units/remote-fs-pre.target new file mode 100644 index 000000000..2169533bd --- /dev/null +++ b/units/remote-fs-pre.target @@ -0,0 +1,11 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Remote File Systems (Pre) +Documentation=man:systemd.special(7) +After=network.target nss-lookup.target diff --git a/units/remote-fs.target b/units/remote-fs.target new file mode 100644 index 000000000..9e68878ad --- /dev/null +++ b/units/remote-fs.target @@ -0,0 +1,13 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Remote File Systems +Documentation=man:systemd.special(7) + +[Install] +WantedBy=multi-user.target diff --git a/units/rescue.service.m4.in b/units/rescue.service.m4.in new file mode 100644 index 000000000..269797a12 --- /dev/null +++ b/units/rescue.service.m4.in @@ -0,0 +1,31 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Rescue Shell +Documentation=man:sulogin(8) +DefaultDependencies=no +Conflicts=shutdown.target +After=sysinit.target plymouth-start.service +Before=shutdown.target + +[Service] +Environment=HOME=/root +WorkingDirectory=/root +ExecStartPre=-/bin/plymouth quit +ExecStartPre=-/bin/echo -e 'Welcome to rescue mode! Type "systemctl default" or ^D to enter default mode.\\nType "journalctl -xb" to view system logs. Type "systemctl reboot" to reboot.' +ExecStart=-/sbin/sulogin +ExecStopPost=-@SYSTEMCTL@ --fail --no-block default +Type=idle +StandardInput=tty-force +StandardOutput=inherit +StandardError=inherit +KillMode=process + +# Bash ignores SIGTERM, so we send SIGHUP instead, to ensure that bash +# terminates cleanly. +KillSignal=SIGHUP diff --git a/units/rescue.target b/units/rescue.target new file mode 100644 index 000000000..3f59b1433 --- /dev/null +++ b/units/rescue.target @@ -0,0 +1,16 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Rescue Mode +Documentation=man:systemd.special(7) +Requires=sysinit.target rescue.service +After=sysinit.target rescue.service +AllowIsolate=yes + +[Install] +Alias=kbrequest.target diff --git a/units/rpcbind.target b/units/rpcbind.target new file mode 100644 index 000000000..eb06a6db2 --- /dev/null +++ b/units/rpcbind.target @@ -0,0 +1,13 @@ +# This file is part of systemd. +# +# 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. + +# This exists mostly for compatibility with SysV/LSB units, and +# implementations lacking socket/bus activation. + +[Unit] +Description=RPC Port Mapper +Documentation=man:systemd.special(7) diff --git a/units/serial-getty@.service.m4 b/units/serial-getty@.service.m4 new file mode 100644 index 000000000..60d7737b7 --- /dev/null +++ b/units/serial-getty@.service.m4 @@ -0,0 +1,38 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Serial Getty on %I +Documentation=man:agetty(8) man:systemd-getty-generator(8) +Documentation=http://0pointer.de/blog/projects/serial-console.html +BindsTo=dev-%i.device +After=dev-%i.device systemd-user-sessions.service plymouth-quit-wait.service +m4_ifdef(`HAVE_SYSV_COMPAT', +After=rc-local.service +)m4_dnl + +# If additional gettys are spawned during boot then we should make +# sure that this is synchronized before getty.target, even though +# getty.target didn't actually pull it in. +Before=getty.target +IgnoreOnIsolate=yes + +[Service] +ExecStart=-/sbin/agetty -s %I 115200,38400,9600 vt102 +Type=idle +Restart=always +RestartSec=0 +UtmpIdentifier=%I +TTYPath=/dev/%I +TTYReset=yes +TTYVHangup=yes +KillMode=process +IgnoreSIGPIPE=no + +# Some login implementations ignore SIGTERM, so we send SIGHUP +# instead, to ensure that login terminates cleanly. +KillSignal=SIGHUP diff --git a/units/shutdown.target b/units/shutdown.target new file mode 100644 index 000000000..73e302b8b --- /dev/null +++ b/units/shutdown.target @@ -0,0 +1,12 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Shutdown +Documentation=man:systemd.special(7) +DefaultDependencies=no +RefuseManualStart=yes diff --git a/units/sigpwr.target b/units/sigpwr.target new file mode 100644 index 000000000..a52e7cffc --- /dev/null +++ b/units/sigpwr.target @@ -0,0 +1,10 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Power Failure +Documentation=man:systemd.special(7) diff --git a/units/sleep.target b/units/sleep.target new file mode 100644 index 000000000..10c7c8d59 --- /dev/null +++ b/units/sleep.target @@ -0,0 +1,13 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Sleep +Documentation=man:systemd.special(7) +DefaultDependencies=no +RefuseManualStart=yes +StopWhenUnneeded=yes diff --git a/units/smartcard.target b/units/smartcard.target new file mode 100644 index 000000000..5fefe8470 --- /dev/null +++ b/units/smartcard.target @@ -0,0 +1,11 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Smart Card +Documentation=man:systemd.special(7) +StopWhenUnneeded=yes diff --git a/units/sockets.target b/units/sockets.target new file mode 100644 index 000000000..26ab065d0 --- /dev/null +++ b/units/sockets.target @@ -0,0 +1,10 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Sockets +Documentation=man:systemd.special(7) diff --git a/units/sound.target b/units/sound.target new file mode 100644 index 000000000..6699adece --- /dev/null +++ b/units/sound.target @@ -0,0 +1,11 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Sound Card +Documentation=man:systemd.special(7) +StopWhenUnneeded=yes diff --git a/units/suspend.target b/units/suspend.target new file mode 100644 index 000000000..f50cb2264 --- /dev/null +++ b/units/suspend.target @@ -0,0 +1,13 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Suspend +Documentation=man:systemd.special(7) +DefaultDependencies=no +BindsTo=systemd-suspend.service +After=systemd-suspend.service diff --git a/units/swap.target b/units/swap.target new file mode 100644 index 000000000..23a7d0dc9 --- /dev/null +++ b/units/swap.target @@ -0,0 +1,10 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Swap +Documentation=man:systemd.special(7) diff --git a/units/sys-fs-fuse-connections.mount b/units/sys-fs-fuse-connections.mount new file mode 100644 index 000000000..9269ea427 --- /dev/null +++ b/units/sys-fs-fuse-connections.mount @@ -0,0 +1,19 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=FUSE Control File System +Documentation=https://www.kernel.org/doc/Documentation/filesystems/fuse.txt +DefaultDependencies=no +ConditionPathExists=/sys/fs/fuse/connections +After=systemd-modules-load.service +Before=sysinit.target + +[Mount] +What=fusectl +Where=/sys/fs/fuse/connections +Type=fusectl diff --git a/units/sys-kernel-config.mount b/units/sys-kernel-config.mount new file mode 100644 index 000000000..e7cd4909c --- /dev/null +++ b/units/sys-kernel-config.mount @@ -0,0 +1,19 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Configuration File System +Documentation=https://www.kernel.org/doc/Documentation/filesystems/configfs/configfs.txt +DefaultDependencies=no +ConditionPathExists=/sys/kernel/config +After=systemd-modules-load.service +Before=sysinit.target + +[Mount] +What=configfs +Where=/sys/kernel/config +Type=configfs diff --git a/units/sys-kernel-debug.mount b/units/sys-kernel-debug.mount new file mode 100644 index 000000000..8b1e33e7f --- /dev/null +++ b/units/sys-kernel-debug.mount @@ -0,0 +1,18 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Debug File System +Documentation=https://www.kernel.org/doc/Documentation/filesystems/debugfs.txt +DefaultDependencies=no +ConditionPathExists=/sys/kernel/debug +Before=sysinit.target + +[Mount] +What=debugfs +Where=/sys/kernel/debug +Type=debugfs diff --git a/units/sysinit.target b/units/sysinit.target new file mode 100644 index 000000000..8f4fb8f5c --- /dev/null +++ b/units/sysinit.target @@ -0,0 +1,14 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=System Initialization +Documentation=man:systemd.special(7) +Conflicts=emergency.service emergency.target +Wants=local-fs.target swap.target +After=local-fs.target swap.target emergency.service emergency.target +RefuseManualStart=yes diff --git a/units/syslog.socket b/units/syslog.socket new file mode 100644 index 000000000..c78435762 --- /dev/null +++ b/units/syslog.socket @@ -0,0 +1,43 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Syslog Socket +Documentation=man:systemd.special(7) +Documentation=http://www.freedesktop.org/wiki/Software/systemd/syslog +DefaultDependencies=no +Before=sockets.target syslog.target shutdown.target + +# Don't allow logging until the very end +Conflicts=shutdown.target + +# Pull in syslog.target to tell people that /dev/log is now accessible +Wants=syslog.target + +[Socket] +ListenDatagram=/run/systemd/journal/syslog +SocketMode=0666 +PassCredentials=yes +PassSecurity=yes +ReceiveBuffer=8M + +# The default syslog implementation should make syslog.service a +# symlink to itself, so that this socket activates the right actual +# syslog service. +# +# Examples: +# +# /etc/systemd/system/syslog.service -> /lib/systemd/system/rsyslog.service +# /etc/systemd/system/syslog.service -> /lib/systemd/system/syslog-ng.service +# +# Best way to achieve that is by adding this to your unit file +# (i.e. to rsyslog.service or syslog-ng.service): +# +# [Install] +# Alias=syslog.service +# +# See http://www.freedesktop.org/wiki/Software/systemd/syslog for details. diff --git a/units/syslog.target b/units/syslog.target new file mode 100644 index 000000000..423fef30a --- /dev/null +++ b/units/syslog.target @@ -0,0 +1,19 @@ +# This file is part of systemd. +# +# 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. + +# This exists mostly for compatibility with SysV/LSB units, and +# implementations lacking socket/bus activation. + +[Unit] +Description=Syslog +Documentation=man:systemd.special(7) +Documentation=http://www.freedesktop.org/wiki/Software/systemd/syslog + +# Avoid that we conflict with shutdown.target, so that we can stay +# until the very end and do not cancel shutdown.target if we should +# happen to be activated very late. +DefaultDependencies=no diff --git a/units/system-update.target b/units/system-update.target new file mode 100644 index 000000000..d0f847f95 --- /dev/null +++ b/units/system-update.target @@ -0,0 +1,16 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=System Update +Documentation=http://freedesktop.org/wiki/Software/systemd/SystemUpdates +Documentation=man:systemd.special(7) man:systemd-system-update-generator(8) +Requires=sysinit.target +Conflicts=shutdown.target systemd-readahead-collect.service systemd-readahead-replay.service +After=sysinit.target +Before=shutdown.target +AllowIsolate=yes diff --git a/units/systemd-ask-password-console.path b/units/systemd-ask-password-console.path new file mode 100644 index 000000000..80f6cc4c1 --- /dev/null +++ b/units/systemd-ask-password-console.path @@ -0,0 +1,19 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Dispatch Password Requests to Console Directory Watch +Documentation=man:systemd-ask-password-console.service(8) +DefaultDependencies=no +Conflicts=shutdown.target +After=plymouth-start.service +Before=basic.target shutdown.target +ConditionPathExists=!/run/plymouth/pid + +[Path] +DirectoryNotEmpty=/run/systemd/ask-password +MakeDirectory=yes diff --git a/units/systemd-ask-password-console.service.in b/units/systemd-ask-password-console.service.in new file mode 100644 index 000000000..4bcb30be0 --- /dev/null +++ b/units/systemd-ask-password-console.service.in @@ -0,0 +1,18 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Dispatch Password Requests to Console +Documentation=man:systemd-ask-password-console.service(8) +DefaultDependencies=no +Conflicts=shutdown.target +After=plymouth-start.service +Before=shutdown.target +ConditionPathExists=!/run/plymouth/pid + +[Service] +ExecStart=@rootbindir@/systemd-tty-ask-password-agent --watch --console diff --git a/units/systemd-ask-password-wall.path b/units/systemd-ask-password-wall.path new file mode 100644 index 000000000..62dee8055 --- /dev/null +++ b/units/systemd-ask-password-wall.path @@ -0,0 +1,17 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Forward Password Requests to Wall Directory Watch +Documentation=man:systemd-ask-password-console.service(8) +DefaultDependencies=no +Conflicts=shutdown.target +Before=basic.target shutdown.target + +[Path] +DirectoryNotEmpty=/run/systemd/ask-password +MakeDirectory=yes diff --git a/units/systemd-ask-password-wall.service.in b/units/systemd-ask-password-wall.service.in new file mode 100644 index 000000000..0eaa27479 --- /dev/null +++ b/units/systemd-ask-password-wall.service.in @@ -0,0 +1,15 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Forward Password Requests to Wall +Documentation=man:systemd-ask-password-console.service(8) +After=systemd-user-sessions.service + +[Service] +ExecStartPre=-@SYSTEMCTL@ stop systemd-ask-password-console.path systemd-ask-password-console.service systemd-ask-password-plymouth.path systemd-ask-password-plymouth.service +ExecStart=@rootbindir@/systemd-tty-ask-password-agent --wall diff --git a/units/systemd-binfmt.service.in b/units/systemd-binfmt.service.in new file mode 100644 index 000000000..02dfe774d --- /dev/null +++ b/units/systemd-binfmt.service.in @@ -0,0 +1,26 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Set Up Additional Binary Formats +Documentation=man:systemd-binfmt.service(8) man:binfmt.d(5) +Documentation=https://www.kernel.org/doc/Documentation/binfmt_misc.txt +DefaultDependencies=no +Conflicts=shutdown.target +After=systemd-readahead-collect.service systemd-readahead-replay.service proc-sys-fs-binfmt_misc.automount +Before=sysinit.target shutdown.target +ConditionPathIsReadWrite=/proc/sys/ +ConditionDirectoryNotEmpty=|/lib/binfmt.d +ConditionDirectoryNotEmpty=|/usr/lib/binfmt.d +ConditionDirectoryNotEmpty=|/usr/local/lib/binfmt.d +ConditionDirectoryNotEmpty=|/etc/binfmt.d +ConditionDirectoryNotEmpty=|/run/binfmt.d + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=@rootlibexecdir@/systemd-binfmt diff --git a/units/systemd-fsck-root.service.in b/units/systemd-fsck-root.service.in new file mode 100644 index 000000000..ef5123feb --- /dev/null +++ b/units/systemd-fsck-root.service.in @@ -0,0 +1,25 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=File System Check on Root Device +Documentation=man:systemd-fsck@.service(8) +DefaultDependencies=no +After=systemd-readahead-collect.service systemd-readahead-replay.service +Before=local-fs.target shutdown.target + +# Dracut informs us with this flag file if the root fsck was already run +ConditionPathExists=!/run/initramfs/root-fsck +ConditionPathIsReadWrite=!/ + +[Service] +Type=oneshot +RemainAfterExit=no +ExecStart=@rootlibexecdir@/systemd-fsck +StandardOutput=journal+console +FsckPassNo=1 +TimeoutSec=0 diff --git a/units/systemd-fsck@.service.in b/units/systemd-fsck@.service.in new file mode 100644 index 000000000..b3c71eb25 --- /dev/null +++ b/units/systemd-fsck@.service.in @@ -0,0 +1,21 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=File System Check on %f +Documentation=man:systemd-fsck@.service(8) +DefaultDependencies=no +BindsTo=%i.device +After=systemd-readahead-collect.service systemd-readahead-replay.service %i.device +Before=shutdown.target + +[Service] +Type=oneshot +RemainAfterExit=no +ExecStart=@rootlibexecdir@/systemd-fsck %f +StandardOutput=journal+console +TimeoutSec=0 diff --git a/units/systemd-halt.service.in b/units/systemd-halt.service.in new file mode 100644 index 000000000..d55d622c1 --- /dev/null +++ b/units/systemd-halt.service.in @@ -0,0 +1,17 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Halt +Documentation=man:systemd-halt.service(8) +DefaultDependencies=no +Requires=shutdown.target umount.target final.target +After=shutdown.target umount.target final.target + +[Service] +Type=oneshot +ExecStart=@SYSTEMCTL@ --force halt diff --git a/units/systemd-hibernate.service.in b/units/systemd-hibernate.service.in new file mode 100644 index 000000000..29d9b696a --- /dev/null +++ b/units/systemd-hibernate.service.in @@ -0,0 +1,17 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Hibernate +Documentation=man:systemd-suspend.service(8) +DefaultDependencies=no +Requires=sleep.target +After=sleep.target + +[Service] +Type=oneshot +ExecStart=@rootlibexecdir@/systemd-sleep hibernate diff --git a/units/systemd-hostnamed.service.in b/units/systemd-hostnamed.service.in new file mode 100644 index 000000000..874f6c274 --- /dev/null +++ b/units/systemd-hostnamed.service.in @@ -0,0 +1,16 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Hostname Service +Documentation=man:systemd-hostnamed.service(8) man:hostname(5) man:machine-info(5) +Documentation=http://www.freedesktop.org/wiki/Software/systemd/hostnamed + +[Service] +ExecStart=@rootlibexecdir@/systemd-hostnamed +BusName=org.freedesktop.hostname1 +CapabilityBoundingSet=CAP_SYS_ADMIN CAP_DAC_OVERRIDE CAP_SYS_PTRACE diff --git a/units/systemd-hybrid-sleep.service.in b/units/systemd-hybrid-sleep.service.in new file mode 100644 index 000000000..914b686c3 --- /dev/null +++ b/units/systemd-hybrid-sleep.service.in @@ -0,0 +1,17 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Hybrid Suspend+Hibernate +Documentation=man:systemd-suspend.service(8) +DefaultDependencies=no +Requires=sleep.target +After=sleep.target + +[Service] +Type=oneshot +ExecStart=@rootlibexecdir@/systemd-sleep hybrid-sleep diff --git a/units/systemd-initctl.service.in b/units/systemd-initctl.service.in new file mode 100644 index 000000000..27e663c8d --- /dev/null +++ b/units/systemd-initctl.service.in @@ -0,0 +1,15 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=/dev/initctl Compatibility Daemon +Documentation=man:systemd-initctl.service(8) +DefaultDependencies=no + +[Service] +ExecStart=@rootlibexecdir@/systemd-initctl +NotifyAccess=all diff --git a/units/systemd-initctl.socket b/units/systemd-initctl.socket new file mode 100644 index 000000000..b98d5ca6e --- /dev/null +++ b/units/systemd-initctl.socket @@ -0,0 +1,16 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=/dev/initctl Compatibility Named Pipe +Documentation=man:systemd-initctl.service(8) +DefaultDependencies=no +Before=sockets.target + +[Socket] +ListenFIFO=/dev/initctl +SocketMode=0600 diff --git a/units/systemd-journal-flush.service.in b/units/systemd-journal-flush.service.in new file mode 100644 index 000000000..503e8a63b --- /dev/null +++ b/units/systemd-journal-flush.service.in @@ -0,0 +1,18 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Trigger Flushing of Journal to Persistent Storage +Documentation=man:systemd-journald.service(8) man:journald.conf(5) +DefaultDependencies=no +Requires=systemd-journald.service +After=systemd-journald.service local-fs.target remote-fs.target +Before=systemd-user-sessions.service + +[Service] +ExecStart=@rootbindir@/systemctl kill --kill-who=main --signal=SIGUSR1 systemd-journald.service +Type=oneshot diff --git a/units/systemd-journal-gatewayd.service.in b/units/systemd-journal-gatewayd.service.in new file mode 100644 index 000000000..c3b5c725b --- /dev/null +++ b/units/systemd-journal-gatewayd.service.in @@ -0,0 +1,16 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Journal Gateway Service +Requires=systemd-journal-gatewayd.socket + +[Service] +ExecStart=@rootlibexecdir@/systemd-journal-gatewayd + +[Install] +Also=systemd-journal-gatewayd.socket diff --git a/units/systemd-journal-gatewayd.socket b/units/systemd-journal-gatewayd.socket new file mode 100644 index 000000000..fd11058ab --- /dev/null +++ b/units/systemd-journal-gatewayd.socket @@ -0,0 +1,15 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Journal Gateway Service Socket + +[Socket] +ListenStream=19531 + +[Install] +WantedBy=sockets.target diff --git a/units/systemd-journald.service.in b/units/systemd-journald.service.in new file mode 100644 index 000000000..ab2e50c22 --- /dev/null +++ b/units/systemd-journald.service.in @@ -0,0 +1,26 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Journal Service +Documentation=man:systemd-journald.service(8) man:journald.conf(5) +DefaultDependencies=no +Requires=systemd-journald.socket +After=systemd-journald.socket syslog.socket +Before=sysinit.target + +[Service] +ExecStart=@rootlibexecdir@/systemd-journald +Restart=always +RestartSec=0 +NotifyAccess=all +StandardOutput=null +CapabilityBoundingSet=CAP_SYS_ADMIN CAP_DAC_OVERRIDE CAP_SYS_PTRACE CAP_SYSLOG CAP_AUDIT_CONTROL CAP_CHOWN CAP_DAC_READ_SEARCH CAP_FOWNER CAP_SETUID CAP_SETGID + +# Increase the default a bit in order to allow many simultaneous +# services being run since we keep one fd open per service. +LimitNOFILE=16384 diff --git a/units/systemd-journald.socket b/units/systemd-journald.socket new file mode 100644 index 000000000..dbe8882c0 --- /dev/null +++ b/units/systemd-journald.socket @@ -0,0 +1,26 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Journal Socket +Documentation=man:systemd-journald.service(8) man:journald.conf(5) +DefaultDependencies=no +Before=sockets.target syslog.target + +# Mount and swap units need this. If this socket unit is removed by an +# isolate request the mount and and swap units would be removed too, +# hence let's exclude this from isolate requests. +IgnoreOnIsolate=yes + +[Socket] +ListenStream=/run/systemd/journal/stdout +ListenDatagram=/run/systemd/journal/socket +ListenDatagram=/dev/log +SocketMode=0666 +PassCredentials=yes +PassSecurity=yes +ReceiveBuffer=8M diff --git a/units/systemd-kexec.service.in b/units/systemd-kexec.service.in new file mode 100644 index 000000000..61303f917 --- /dev/null +++ b/units/systemd-kexec.service.in @@ -0,0 +1,17 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Reboot via kexec +Documentation=man:systemd-halt.service(8) +DefaultDependencies=no +Requires=shutdown.target umount.target final.target +After=shutdown.target umount.target final.target + +[Service] +Type=oneshot +ExecStart=@SYSTEMCTL@ --force kexec diff --git a/units/systemd-localed.service.in b/units/systemd-localed.service.in new file mode 100644 index 000000000..6818a4c5c --- /dev/null +++ b/units/systemd-localed.service.in @@ -0,0 +1,16 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Locale Service +Documentation=man:systemd-localed.service(8) man:locale.conf(5) man:vconsole.conf(5) +Documentation=http://www.freedesktop.org/wiki/Software/systemd/localed + +[Service] +ExecStart=@rootlibexecdir@/systemd-localed +BusName=org.freedesktop.locale1 +CapabilityBoundingSet= diff --git a/units/systemd-logind.service.in b/units/systemd-logind.service.in new file mode 100644 index 000000000..cf3c430b7 --- /dev/null +++ b/units/systemd-logind.service.in @@ -0,0 +1,23 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Login Service +Documentation=man:systemd-logind.service(8) man:logind.conf(5) +Documentation=http://www.freedesktop.org/wiki/Software/systemd/multiseat +After=nss-user-lookup.target + +[Service] +ExecStart=@rootlibexecdir@/systemd-logind +Restart=always +RestartSec=0 +BusName=org.freedesktop.login1 +CapabilityBoundingSet=CAP_AUDIT_CONTROL CAP_CHOWN CAP_KILL CAP_DAC_READ_SEARCH CAP_DAC_OVERRIDE CAP_FOWNER CAP_SYS_TTY_CONFIG + +# Increase the default a bit in order to allow many simultaneous +# logins since we keep one fd open per session. +LimitNOFILE=16384 diff --git a/units/systemd-modules-load.service.in b/units/systemd-modules-load.service.in new file mode 100644 index 000000000..32deb52e2 --- /dev/null +++ b/units/systemd-modules-load.service.in @@ -0,0 +1,27 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Load Kernel Modules +Documentation=man:systemd-modules-load.service(8) man:modules-load.d(5) +DefaultDependencies=no +Conflicts=shutdown.target +After=systemd-readahead-collect.service systemd-readahead-replay.service +Before=sysinit.target shutdown.target +ConditionCapability=CAP_SYS_MODULE +ConditionDirectoryNotEmpty=|/lib/modules-load.d +ConditionDirectoryNotEmpty=|/usr/lib/modules-load.d +ConditionDirectoryNotEmpty=|/usr/local/lib/modules-load.d +ConditionDirectoryNotEmpty=|/etc/modules-load.d +ConditionDirectoryNotEmpty=|/run/modules-load.d +ConditionKernelCommandLine=|modules-load +ConditionKernelCommandLine=|rd.modules-load + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=@rootlibexecdir@/systemd-modules-load diff --git a/units/systemd-poweroff.service.in b/units/systemd-poweroff.service.in new file mode 100644 index 000000000..363071973 --- /dev/null +++ b/units/systemd-poweroff.service.in @@ -0,0 +1,17 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Power-Off +Documentation=man:systemd-halt.service(8) +DefaultDependencies=no +Requires=shutdown.target umount.target final.target +After=shutdown.target umount.target final.target + +[Service] +Type=oneshot +ExecStart=@SYSTEMCTL@ --force poweroff diff --git a/units/systemd-quotacheck.service.in b/units/systemd-quotacheck.service.in new file mode 100644 index 000000000..f726ea1bc --- /dev/null +++ b/units/systemd-quotacheck.service.in @@ -0,0 +1,20 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=File System Quota Check +Documentation=man:systemd-quotacheck.service(8) +DefaultDependencies=no +After=systemd-readahead-collect.service systemd-readahead-replay.service systemd-remount-fs.service +Before=local-fs.target shutdown.target +ConditionPathExists=@QUOTACHECK@ + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=@rootlibexecdir@/systemd-quotacheck +TimeoutSec=0 diff --git a/units/systemd-random-seed-load.service.in b/units/systemd-random-seed-load.service.in new file mode 100644 index 000000000..e9156ef08 --- /dev/null +++ b/units/systemd-random-seed-load.service.in @@ -0,0 +1,18 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Load Random Seed +Documentation=man:systemd-random-seed-load.service(8) man:random(4) +DefaultDependencies=no +RequiresMountsFor=@RANDOM_SEED@ +After=systemd-readahead-collect.service systemd-readahead-replay.service systemd-remount-fs.service +Before=sysinit.target final.target + +[Service] +Type=oneshot +ExecStart=@rootlibexecdir@/systemd-random-seed load diff --git a/units/systemd-random-seed-save.service.in b/units/systemd-random-seed-save.service.in new file mode 100644 index 000000000..3444d4ce7 --- /dev/null +++ b/units/systemd-random-seed-save.service.in @@ -0,0 +1,18 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Save Random Seed +Documentation=man:systemd-random-seed-load.service(8) man:random(4) +DefaultDependencies=no +RequiresMountsFor=@RANDOM_SEED@ +After=systemd-remount-fs.service systemd-random-seed-load.service +Before=final.target + +[Service] +Type=oneshot +ExecStart=@rootlibexecdir@/systemd-random-seed save diff --git a/units/systemd-readahead-collect.service.in b/units/systemd-readahead-collect.service.in new file mode 100644 index 000000000..d4b8e6793 --- /dev/null +++ b/units/systemd-readahead-collect.service.in @@ -0,0 +1,28 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Collect Read-Ahead Data +Documentation=man:systemd-readahead-replay.service(8) +DefaultDependencies=no +Wants=systemd-readahead-done.timer +Conflicts=shutdown.target +Before=sysinit.target shutdown.target +ConditionPathExists=!/run/systemd/readahead/cancel +ConditionPathExists=!/run/systemd/readahead/done +ConditionVirtualization=no + +[Service] +Type=notify +ExecStart=@rootlibexecdir@/systemd-readahead collect +RemainAfterExit=yes +StandardOutput=null +OOMScoreAdjust=1000 + +[Install] +WantedBy=default.target +Also=systemd-readahead-drop.service diff --git a/units/systemd-readahead-done.service.in b/units/systemd-readahead-done.service.in new file mode 100644 index 000000000..c3b2ac506 --- /dev/null +++ b/units/systemd-readahead-done.service.in @@ -0,0 +1,21 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Stop Read-Ahead Data Collection +Documentation=man:systemd-readahead-replay.service(8) +DefaultDependencies=no +Conflicts=shutdown.target +After=default.target +Before=shutdown.target + +[Service] +Type=oneshot +ExecStart=@SYSTEMD_NOTIFY@ --readahead=done + +[Install] +Also=systemd-readahead-collect.service diff --git a/units/systemd-readahead-done.timer b/units/systemd-readahead-done.timer new file mode 100644 index 000000000..2828d198a --- /dev/null +++ b/units/systemd-readahead-done.timer @@ -0,0 +1,20 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Stop Read-Ahead Data Collection 10s After Completed Startup +Documentation=man:systemd-readahead-replay.service(8) +DefaultDependencies=no +Conflicts=shutdown.target +After=default.target +Before=shutdown.target + +[Timer] +OnActiveSec=10s + +[Install] +Also=systemd-readahead-collect.service diff --git a/units/systemd-readahead-drop.service b/units/systemd-readahead-drop.service new file mode 100644 index 000000000..d9d12bc53 --- /dev/null +++ b/units/systemd-readahead-drop.service @@ -0,0 +1,19 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Drop Read-Ahead Data +Documentation=man:systemd-readahead-replay.service(8) +ConditionPathExists=/.readahead + +[Service] +Type=oneshot +ExecStart=/bin/rm -f /.readahead + +[Install] +WantedBy=system-update.target +Also=systemd-readahead-collect.service diff --git a/units/systemd-readahead-replay.service.in b/units/systemd-readahead-replay.service.in new file mode 100644 index 000000000..c64a533e4 --- /dev/null +++ b/units/systemd-readahead-replay.service.in @@ -0,0 +1,26 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Replay Read-Ahead Data +Documentation=man:systemd-readahead-replay.service(8) +DefaultDependencies=no +Conflicts=shutdown.target +Before=sysinit.target shutdown.target +ConditionPathExists=!/run/systemd/readahead/noreplay +ConditionPathExists=/.readahead +ConditionVirtualization=no + +[Service] +Type=notify +ExecStart=@rootlibexecdir@/systemd-readahead replay +RemainAfterExit=yes +StandardOutput=null +OOMScoreAdjust=1000 + +[Install] +WantedBy=default.target diff --git a/units/systemd-reboot.service.in b/units/systemd-reboot.service.in new file mode 100644 index 000000000..d99bd3e70 --- /dev/null +++ b/units/systemd-reboot.service.in @@ -0,0 +1,17 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Reboot +Documentation=man:systemd-halt.service(8) +DefaultDependencies=no +Requires=shutdown.target umount.target final.target +After=shutdown.target umount.target final.target + +[Service] +Type=oneshot +ExecStart=@SYSTEMCTL@ --force reboot diff --git a/units/systemd-remount-fs.service.in b/units/systemd-remount-fs.service.in new file mode 100644 index 000000000..cddb0a1fb --- /dev/null +++ b/units/systemd-remount-fs.service.in @@ -0,0 +1,21 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Remount Root and Kernel File Systems +Documentation=man:systemd-remount-fs.service(8) +DefaultDependencies=no +Conflicts=shutdown.target +After=systemd-readahead-collect.service systemd-readahead-replay.service systemd-fsck-root.service +Before=local-fs-pre.target local-fs.target shutdown.target +Wants=local-fs-pre.target +ConditionPathExists=/etc/fstab + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=@rootlibexecdir@/systemd-remount-fs diff --git a/units/systemd-shutdownd.service.in b/units/systemd-shutdownd.service.in new file mode 100644 index 000000000..d95174250 --- /dev/null +++ b/units/systemd-shutdownd.service.in @@ -0,0 +1,15 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Delayed Shutdown Service +Documentation=man:systemd-shutdownd.service(8) +DefaultDependencies=no + +[Service] +ExecStart=@rootlibexecdir@/systemd-shutdownd +NotifyAccess=all diff --git a/units/systemd-shutdownd.socket b/units/systemd-shutdownd.socket new file mode 100644 index 000000000..9421ce8ad --- /dev/null +++ b/units/systemd-shutdownd.socket @@ -0,0 +1,18 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Delayed Shutdown Socket +Documentation=man:systemd-shutdownd.service(8) +DefaultDependencies=no +Before=sockets.target + +[Socket] +ListenDatagram=/run/systemd/shutdownd +SocketMode=0600 +PassCredentials=yes +PassSecurity=yes diff --git a/units/systemd-suspend.service.in b/units/systemd-suspend.service.in new file mode 100644 index 000000000..3a702d2e2 --- /dev/null +++ b/units/systemd-suspend.service.in @@ -0,0 +1,17 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Suspend +Documentation=man:systemd-suspend.service(8) +DefaultDependencies=no +Requires=sleep.target +After=sleep.target + +[Service] +Type=oneshot +ExecStart=@rootlibexecdir@/systemd-sleep suspend diff --git a/units/systemd-sysctl.service.in b/units/systemd-sysctl.service.in new file mode 100644 index 000000000..45e1ceb25 --- /dev/null +++ b/units/systemd-sysctl.service.in @@ -0,0 +1,26 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Apply Kernel Variables +Documentation=man:systemd-sysctl.service(8) man:sysctl.d(5) +DefaultDependencies=no +Conflicts=shutdown.target +After=systemd-readahead-collect.service systemd-readahead-replay.service +Before=sysinit.target shutdown.target +ConditionPathIsReadWrite=/proc/sys/ +ConditionPathExists=|/etc/sysctl.conf +ConditionDirectoryNotEmpty=|/lib/sysctl.d +ConditionDirectoryNotEmpty=|/usr/lib/sysctl.d +ConditionDirectoryNotEmpty=|/usr/local/lib/sysctl.d +ConditionDirectoryNotEmpty=|/etc/sysctl.d +ConditionDirectoryNotEmpty=|/run/sysctl.d + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=@rootlibexecdir@/systemd-sysctl diff --git a/units/systemd-timedated.service.in b/units/systemd-timedated.service.in new file mode 100644 index 000000000..dd3eb1b33 --- /dev/null +++ b/units/systemd-timedated.service.in @@ -0,0 +1,16 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Time & Date Service +Documentation=man:systemd-timedated.service(8) man:localtime(5) +Documentation=http://www.freedesktop.org/wiki/Software/systemd/timedated + +[Service] +ExecStart=@rootlibexecdir@/systemd-timedated +BusName=org.freedesktop.timedate1 +CapabilityBoundingSet=CAP_SYS_TIME diff --git a/units/systemd-tmpfiles-clean.service.in b/units/systemd-tmpfiles-clean.service.in new file mode 100644 index 000000000..a288232e1 --- /dev/null +++ b/units/systemd-tmpfiles-clean.service.in @@ -0,0 +1,23 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Cleanup of Temporary Directories +Documentation=man:tmpfiles.d(5) +DefaultDependencies=no +Wants=local-fs.target +After=systemd-readahead-collect.service systemd-readahead-replay.service local-fs.target +Before=sysinit.target shutdown.target +ConditionDirectoryNotEmpty=|/usr/lib/tmpfiles.d +ConditionDirectoryNotEmpty=|/usr/local/lib/tmpfiles.d +ConditionDirectoryNotEmpty=|/etc/tmpfiles.d +ConditionDirectoryNotEmpty=|/run/tmpfiles.d + +[Service] +Type=oneshot +ExecStart=@rootbindir@/systemd-tmpfiles --clean +IOSchedulingClass=idle diff --git a/units/systemd-tmpfiles-clean.timer b/units/systemd-tmpfiles-clean.timer new file mode 100644 index 000000000..fac4ee3da --- /dev/null +++ b/units/systemd-tmpfiles-clean.timer @@ -0,0 +1,14 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Daily Cleanup of Temporary Directories +Documentation=man:tmpfiles.d(5) + +[Timer] +OnBootSec=15min +OnUnitActiveSec=1d diff --git a/units/systemd-tmpfiles-setup.service.in b/units/systemd-tmpfiles-setup.service.in new file mode 100644 index 000000000..dbd6bfb6d --- /dev/null +++ b/units/systemd-tmpfiles-setup.service.in @@ -0,0 +1,23 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Recreate Volatile Files and Directories +Documentation=man:tmpfiles.d(5) +DefaultDependencies=no +Wants=local-fs.target +After=systemd-readahead-collect.service systemd-readahead-replay.service local-fs.target +Before=sysinit.target shutdown.target +ConditionDirectoryNotEmpty=|/usr/lib/tmpfiles.d +ConditionDirectoryNotEmpty=|/usr/local/lib/tmpfiles.d +ConditionDirectoryNotEmpty=|/etc/tmpfiles.d +ConditionDirectoryNotEmpty=|/run/tmpfiles.d + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=@rootbindir@/systemd-tmpfiles --create --remove diff --git a/units/systemd-udev-settle.service.in b/units/systemd-udev-settle.service.in new file mode 100644 index 000000000..b63194964 --- /dev/null +++ b/units/systemd-udev-settle.service.in @@ -0,0 +1,30 @@ +# This file is part of systemd. +# +# 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. + +# This service is usually not enabled by default. If enabled, it +# acts as a barrier for basic.target -- so all later services will +# wait for udev completely finishing its coldplug run. +# +# If needed, to work around broken or non-hotplug-aware services, +# it might be enabled unconditionally, or pulled-in on-demand by +# the services that assume a fully populated /dev at startup. It +# should not be used or pulled-in ever on systems without such +# legacy services running. + +[Unit] +Description=udev Wait for Complete Device Initialization +Documentation=man:udev(7) man:systemd-udevd.service(8) +DefaultDependencies=no +Wants=systemd-udevd.service +After=systemd-udev-trigger.service +ConditionCapability=CAP_MKNOD + +[Service] +Type=oneshot +TimeoutSec=180 +RemainAfterExit=yes +ExecStart=@bindir@/udevadm settle diff --git a/units/systemd-udev-trigger.service.in b/units/systemd-udev-trigger.service.in new file mode 100644 index 000000000..391f99693 --- /dev/null +++ b/units/systemd-udev-trigger.service.in @@ -0,0 +1,19 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=udev Coldplug all Devices +Documentation=man:udev(7) man:systemd-udevd.service(8) +Wants=systemd-udevd.service +After=systemd-udevd-kernel.socket systemd-udevd-control.socket +DefaultDependencies=no +ConditionCapability=CAP_MKNOD + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=@bindir@/udevadm trigger --type=subsystems --action=add ; @bindir@/udevadm trigger --type=devices --action=add diff --git a/units/systemd-udevd-control.socket b/units/systemd-udevd-control.socket new file mode 100644 index 000000000..9065ea2c6 --- /dev/null +++ b/units/systemd-udevd-control.socket @@ -0,0 +1,18 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=udev Control Socket +Documentation=man:systemd-udevd.service(8) man:udev(7) +DefaultDependencies=no +ConditionCapability=CAP_MKNOD + +[Socket] +Service=systemd-udevd.service +ListenSequentialPacket=/run/udev/control +SocketMode=0600 +PassCredentials=yes diff --git a/units/systemd-udevd-kernel.socket b/units/systemd-udevd-kernel.socket new file mode 100644 index 000000000..54a005b7a --- /dev/null +++ b/units/systemd-udevd-kernel.socket @@ -0,0 +1,18 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=udev Kernel Socket +Documentation=man:systemd-udevd.service(8) man:udev(7) +DefaultDependencies=no +ConditionCapability=CAP_MKNOD + +[Socket] +Service=systemd-udevd.service +ReceiveBuffer=134217728 +ListenNetlink=kobject-uevent 1 +PassCredentials=yes diff --git a/units/systemd-udevd.service.in b/units/systemd-udevd.service.in new file mode 100644 index 000000000..2fe7822fe --- /dev/null +++ b/units/systemd-udevd.service.in @@ -0,0 +1,23 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=udev Kernel Device Manager +Documentation=man:systemd-udevd.service(8) man:udev(7) +Wants=systemd-udevd-control.socket systemd-udevd-kernel.socket +After=systemd-udevd-control.socket systemd-udevd-kernel.socket +Before=basic.target +DefaultDependencies=no +ConditionCapability=CAP_MKNOD + +[Service] +Type=notify +OOMScoreAdjust=-1000 +Sockets=systemd-udevd-control.socket systemd-udevd-kernel.socket +Restart=always +RestartSec=0 +ExecStart=@rootlibexecdir@/systemd-udevd diff --git a/units/systemd-update-utmp-runlevel.service.in b/units/systemd-update-utmp-runlevel.service.in new file mode 100644 index 000000000..27fae2cd0 --- /dev/null +++ b/units/systemd-update-utmp-runlevel.service.in @@ -0,0 +1,19 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Update UTMP about System Runlevel Changes +Documentation=man:systemd-update-utmp-runlevel.service(8) man:utmp(5) +DefaultDependencies=no +RequiresMountsFor=/var/log/wtmp +After=systemd-remount-fs.service systemd-tmpfiles-setup.service auditd.service +After=runlevel1.target runlevel2.target runlevel3.target runlevel4.target runlevel5.target +Before=final.target + +[Service] +Type=oneshot +ExecStart=@rootlibexecdir@/systemd-update-utmp runlevel diff --git a/units/systemd-update-utmp-shutdown.service.in b/units/systemd-update-utmp-shutdown.service.in new file mode 100644 index 000000000..aa93562f0 --- /dev/null +++ b/units/systemd-update-utmp-shutdown.service.in @@ -0,0 +1,19 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Update UTMP about System Shutdown +Documentation=man:systemd-update-utmp-runlevel.service(8) man:utmp(5) +DefaultDependencies=no +RequiresMountsFor=/var/log/wtmp +After=systemd-remount-fs.service systemd-tmpfiles-setup.service auditd.service +After=systemd-update-utmp-runlevel.service +Before=final.target + +[Service] +Type=oneshot +ExecStart=@rootlibexecdir@/systemd-update-utmp shutdown diff --git a/units/systemd-user-sessions.service.in b/units/systemd-user-sessions.service.in new file mode 100644 index 000000000..0869e7399 --- /dev/null +++ b/units/systemd-user-sessions.service.in @@ -0,0 +1,17 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Permit User Sessions +Documentation=man:systemd-user-sessions.service(8) +After=remote-fs.target + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=@rootlibexecdir@/systemd-user-sessions start +ExecStop=@rootlibexecdir@/systemd-user-sessions stop diff --git a/units/systemd-vconsole-setup.service.in b/units/systemd-vconsole-setup.service.in new file mode 100644 index 000000000..18faa63f2 --- /dev/null +++ b/units/systemd-vconsole-setup.service.in @@ -0,0 +1,20 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Setup Virtual Console +Documentation=man:systemd-vconsole-setup.service(8) man:vconsole.conf(5) +DefaultDependencies=no +Conflicts=shutdown.target +After=systemd-readahead-collect.service systemd-readahead-replay.service +Before=sysinit.target shutdown.target +ConditionPathExists=/dev/tty0 + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=@rootlibexecdir@/systemd-vconsole-setup diff --git a/units/time-sync.target b/units/time-sync.target new file mode 100644 index 000000000..ec00ecbbf --- /dev/null +++ b/units/time-sync.target @@ -0,0 +1,13 @@ +# This file is part of systemd. +# +# 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. + +# This exists mostly for compatibility with SysV/LSB units, and +# implementations lacking socket/bus activation. + +[Unit] +Description=System Time Synchronized +Documentation=man:systemd.special(7) diff --git a/units/tmp.mount b/units/tmp.mount new file mode 100644 index 000000000..94c41c29b --- /dev/null +++ b/units/tmp.mount @@ -0,0 +1,19 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Temporary Directory +Documentation=man:hier(7) +DefaultDependencies=no +Conflicts=umount.target +Before=local-fs.target umount.target + +[Mount] +What=tmpfs +Where=/tmp +Type=tmpfs +Options=mode=1777,strictatime diff --git a/units/umount.target b/units/umount.target new file mode 100644 index 000000000..39668d85d --- /dev/null +++ b/units/umount.target @@ -0,0 +1,12 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Unmount All Filesystems +Documentation=man:systemd.special(7) +DefaultDependencies=no +RefuseManualStart=yes diff --git a/units/user/.gitignore b/units/user/.gitignore new file mode 100644 index 000000000..41a74f546 --- /dev/null +++ b/units/user/.gitignore @@ -0,0 +1 @@ +/systemd-exit.service diff --git a/units/user/Makefile b/units/user/Makefile new file mode 120000 index 000000000..50be21181 --- /dev/null +++ b/units/user/Makefile @@ -0,0 +1 @@ +../../src/Makefile \ No newline at end of file diff --git a/units/user/default.target b/units/user/default.target new file mode 100644 index 000000000..56cf4dcb9 --- /dev/null +++ b/units/user/default.target @@ -0,0 +1,10 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Default +Documentation=man:systemd.special(7) diff --git a/units/user/exit.target b/units/user/exit.target new file mode 100644 index 000000000..b0ad24c48 --- /dev/null +++ b/units/user/exit.target @@ -0,0 +1,17 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Exit the Session +Documentation=man:systemd.special(7) +DefaultDependencies=no +Requires=systemd-exit.service +After=systemd-exit.service +AllowIsolate=yes + +[Install] +Alias=ctrl-alt-del.target diff --git a/units/user/systemd-exit.service.in b/units/user/systemd-exit.service.in new file mode 100644 index 000000000..987fab812 --- /dev/null +++ b/units/user/systemd-exit.service.in @@ -0,0 +1,17 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=Exit the Session +Documentation=man:systemd.special(7) +DefaultDependencies=no +Requires=shutdown.target +After=shutdown.target + +[Service] +Type=oneshot +ExecStart=@KILL@ -s 58 $MANAGERPID diff --git a/units/user@.service.in b/units/user@.service.in new file mode 100644 index 000000000..2c154953b --- /dev/null +++ b/units/user@.service.in @@ -0,0 +1,19 @@ +# This file is part of systemd. +# +# 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. + +[Unit] +Description=User Manager for %I +After=systemd-user-sessions.service + +[Service] +User=%I +PAMName=systemd-shared +ControlGroup=%R/user/%I/shared cpu:/ +ControlGroupModify=yes +Type=notify +ExecStart=-@rootlibexecdir@/systemd --user +Environment=DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/%I/dbus/user_bus_socket